diff --git a/common/platform/api/quiche_default_proof_providers.h b/common/platform/api/quiche_default_proof_providers.h
deleted file mode 100644
index 54eabab..0000000
--- a/common/platform/api/quiche_default_proof_providers.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
-#define QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
-
-#include <memory>
-
-#include "quiche_platform_impl/quiche_default_proof_providers_impl.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/proof_verifier.h"
-
-namespace quiche {
-
-// Provides a default proof verifier that can verify a cert chain for |host|.
-// The verifier has to do a good faith attempt at verifying the certificate
-// against a reasonable root store, and not just always return success.
-inline std::unique_ptr<quic::ProofVerifier> CreateDefaultProofVerifier(
-    const std::string& host) {
-  return CreateDefaultProofVerifierImpl(host);
-}
-
-// Provides a default proof source for CLI-based tools.  The actual certificates
-// used in the proof source should be confifgurable via command-line flags.
-inline std::unique_ptr<quic::ProofSource> CreateDefaultProofSource() {
-  return CreateDefaultProofSourceImpl();
-}
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/common/platform/api/quiche_file_utils.cc b/common/platform/api/quiche_file_utils.cc
deleted file mode 100644
index fc0c189..0000000
--- a/common/platform/api/quiche_file_utils.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "common/platform/api/quiche_file_utils.h"
-
-#include "quiche_platform_impl/quiche_file_utils_impl.h"
-
-namespace quiche {
-
-std::string JoinPath(absl::string_view a, absl::string_view b) {
-  return JoinPathImpl(a, b);
-}
-
-absl::optional<std::string> ReadFileContents(absl::string_view file) {
-  return ReadFileContentsImpl(file);
-}
-
-bool EnumerateDirectory(absl::string_view path,
-                        std::vector<std::string>& directories,
-                        std::vector<std::string>& files) {
-  return EnumerateDirectoryImpl(path, directories, files);
-}
-
-bool EnumerateDirectoryRecursivelyInner(absl::string_view path,
-                                        int recursion_limit,
-                                        std::vector<std::string>& files) {
-  if (recursion_limit < 0) {
-    return false;
-  }
-
-  std::vector<std::string> local_files;
-  std::vector<std::string> directories;
-  if (!EnumerateDirectory(path, directories, local_files)) {
-    return false;
-  }
-  for (const std::string& directory : directories) {
-    if (!EnumerateDirectoryRecursivelyInner(JoinPath(path, directory),
-                                            recursion_limit - 1, files)) {
-      return false;
-    }
-  }
-  for (const std::string& file : local_files) {
-    files.push_back(JoinPath(path, file));
-  }
-  return true;
-}
-
-bool EnumerateDirectoryRecursively(absl::string_view path,
-                                   std::vector<std::string>& files) {
-  constexpr int kRecursionLimit = 20;
-  return EnumerateDirectoryRecursivelyInner(path, kRecursionLimit, files);
-}
-
-}  // namespace quiche
diff --git a/common/platform/api/quiche_file_utils_test.cc b/common/platform/api/quiche_file_utils_test.cc
deleted file mode 100644
index ddf1a40..0000000
--- a/common/platform/api/quiche_file_utils_test.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "common/platform/api/quiche_file_utils.h"
-
-#include <vector>
-
-#include "absl/algorithm/container.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/strip.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-using testing::UnorderedElementsAre;
-using testing::UnorderedElementsAreArray;
-
-TEST(QuicheFileUtilsTest, ReadFileContents) {
-  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
-                                  "/platform/api/testdir/testfile");
-  absl::optional<std::string> contents = ReadFileContents(path);
-  ASSERT_TRUE(contents.has_value());
-  EXPECT_EQ(*contents, "This is a test file.");
-}
-
-TEST(QuicheFileUtilsTest, ReadFileContentsFileNotFound) {
-  std::string path =
-      absl::StrCat(QuicheGetCommonSourcePath(),
-                   "/platform/api/testdir/file-that-does-not-exist");
-  absl::optional<std::string> contents = ReadFileContents(path);
-  EXPECT_FALSE(contents.has_value());
-}
-
-TEST(QuicheFileUtilsTest, EnumerateDirectory) {
-  std::string path =
-      absl::StrCat(QuicheGetCommonSourcePath(), "/platform/api/testdir");
-  std::vector<std::string> dirs;
-  std::vector<std::string> files;
-  bool success = EnumerateDirectory(path, dirs, files);
-  EXPECT_TRUE(success);
-  EXPECT_THAT(files, UnorderedElementsAre("testfile", "README.md"));
-  EXPECT_THAT(dirs, UnorderedElementsAre("a"));
-}
-
-TEST(QuicheFileUtilsTest, EnumerateDirectoryNoSuchDirectory) {
-  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
-                                  "/platform/api/testdir/no-such-directory");
-  std::vector<std::string> dirs;
-  std::vector<std::string> files;
-  bool success = EnumerateDirectory(path, dirs, files);
-  EXPECT_FALSE(success);
-}
-
-TEST(QuicheFileUtilsTest, EnumerateDirectoryNotADirectory) {
-  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
-                                  "/platform/api/testdir/testfile");
-  std::vector<std::string> dirs;
-  std::vector<std::string> files;
-  bool success = EnumerateDirectory(path, dirs, files);
-  EXPECT_FALSE(success);
-}
-
-TEST(QuicheFileUtilsTest, EnumerateDirectoryRecursively) {
-  std::vector<std::string> expected_paths = {"a/b/c/d/e", "a/subdir/testfile",
-                                             "a/z", "testfile", "README.md"};
-
-  std::string root_path =
-      absl::StrCat(QuicheGetCommonSourcePath(), "/platform/api/testdir");
-  for (std::string& path : expected_paths) {
-    // For Windows, use Windows path separators.
-    if (JoinPath("a", "b") == "a\\b") {
-      absl::c_replace(path, '/', '\\');
-    }
-
-    path = JoinPath(root_path, path);
-  }
-
-  std::vector<std::string> files;
-  bool success = EnumerateDirectoryRecursively(root_path, files);
-  EXPECT_TRUE(success);
-  EXPECT_THAT(files, UnorderedElementsAreArray(expected_paths));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/platform/api/quiche_hostname_utils.cc b/common/platform/api/quiche_hostname_utils.cc
deleted file mode 100644
index 0513cb9..0000000
--- a/common/platform/api/quiche_hostname_utils.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_hostname_utils.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "url/url_canon.h"
-#include "url/url_canon_stdstring.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-
-// TODO(vasilvv): the functions below are forked from Chromium's
-// net/base/url_util.h; those should be moved to googleurl.
-namespace {
-
-std::string CanonicalizeHost(absl::string_view host,
-                             url::CanonHostInfo* host_info) {
-  // Try to canonicalize the host.
-  const url::Component raw_host_component(0, static_cast<int>(host.length()));
-  std::string canon_host;
-  url::StdStringCanonOutput canon_host_output(&canon_host);
-  url::CanonicalizeHostVerbose(host.data(), raw_host_component,
-                               &canon_host_output, host_info);
-
-  if (host_info->out_host.is_nonempty() &&
-      host_info->family != url::CanonHostInfo::BROKEN) {
-    // Success!  Assert that there's no extra garbage.
-    canon_host_output.Complete();
-    QUICHE_DCHECK_EQ(host_info->out_host.len,
-                     static_cast<int>(canon_host.length()));
-  } else {
-    // Empty host, or canonicalization failed.  We'll return empty.
-    canon_host.clear();
-  }
-
-  return canon_host;
-}
-
-bool IsHostCharAlphanumeric(char c) {
-  // We can just check lowercase because uppercase characters have already been
-  // normalized.
-  return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
-}
-
-bool IsCanonicalizedHostCompliant(const std::string& host) {
-  if (host.empty()) {
-    return false;
-  }
-
-  bool in_component = false;
-  bool most_recent_component_started_alphanumeric = false;
-
-  for (char c : host) {
-    if (!in_component) {
-      most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c);
-      if (!most_recent_component_started_alphanumeric && (c != '-') &&
-          (c != '_')) {
-        return false;
-      }
-      in_component = true;
-    } else if (c == '.') {
-      in_component = false;
-    } else if (!IsHostCharAlphanumeric(c) && (c != '-') && (c != '_')) {
-      return false;
-    }
-  }
-
-  return most_recent_component_started_alphanumeric;
-}
-
-}  // namespace
-
-// static
-bool QuicheHostnameUtils::IsValidSNI(absl::string_view sni) {
-  // TODO(rtenneti): Support RFC2396 hostname.
-  // NOTE: Microsoft does NOT enforce this spec, so if we throw away hostnames
-  // based on the above spec, we may be losing some hostnames that windows
-  // would consider valid. By far the most common hostname character NOT
-  // accepted by the above spec is '_'.
-  url::CanonHostInfo host_info;
-  std::string canonicalized_host = CanonicalizeHost(sni, &host_info);
-  return !host_info.IsIPAddress() &&
-         IsCanonicalizedHostCompliant(canonicalized_host);
-}
-
-// static
-std::string QuicheHostnameUtils::NormalizeHostname(absl::string_view hostname) {
-  url::CanonHostInfo host_info;
-  std::string host = CanonicalizeHost(hostname, &host_info);
-
-  // Walk backwards over the string, stopping at the first trailing dot.
-  size_t host_end = host.length();
-  while (host_end != 0 && host[host_end - 1] == '.') {
-    host_end--;
-  }
-
-  // Erase the trailing dots.
-  if (host_end != host.length()) {
-    host.erase(host_end, host.length() - host_end);
-  }
-
-  return host;
-}
-
-}  // namespace quiche
diff --git a/common/platform/api/quiche_hostname_utils.h b/common/platform/api/quiche_hostname_utils.h
deleted file mode 100644
index b9e0fb9..0000000
--- a/common/platform/api/quiche_hostname_utils.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
-#define QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-class QUICHE_EXPORT_PRIVATE QuicheHostnameUtils {
- public:
-  QuicheHostnameUtils() = delete;
-
-  // Returns true if the sni is valid, false otherwise.
-  //  (1) disallow IP addresses;
-  //  (2) check that the hostname contains valid characters only; and
-  //  (3) contains at least one dot.
-  static bool IsValidSNI(absl::string_view sni);
-
-  // Canonicalizes the specified hostname.  This involves a wide variety of
-  // transformations, including lowercasing, removing trailing dots and IDNA
-  // conversion.
-  static std::string NormalizeHostname(absl::string_view hostname);
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
diff --git a/common/platform/api/quiche_hostname_utils_test.cc b/common/platform/api/quiche_hostname_utils_test.cc
deleted file mode 100644
index 3a48b9b..0000000
--- a/common/platform/api/quiche_hostname_utils_test.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_hostname_utils.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-class QuicheHostnameUtilsTest : public QuicheTest {};
-
-TEST_F(QuicheHostnameUtilsTest, IsValidSNI) {
-  // IP as SNI.
-  EXPECT_FALSE(QuicheHostnameUtils::IsValidSNI("192.168.0.1"));
-  // SNI without any dot.
-  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("somedomain"));
-  // Invalid by RFC2396 but unfortunately domains of this form exist.
-  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("some_domain.com"));
-  // An empty string must be invalid otherwise the QUIC client will try sending
-  // it.
-  EXPECT_FALSE(QuicheHostnameUtils::IsValidSNI(""));
-
-  // Valid SNI
-  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("test.google.com"));
-}
-
-TEST_F(QuicheHostnameUtilsTest, NormalizeHostname) {
-  // clang-format off
-  struct {
-    const char *input, *expected;
-  } tests[] = {
-      {
-          "www.google.com",
-          "www.google.com",
-      },
-      {
-          "WWW.GOOGLE.COM",
-          "www.google.com",
-      },
-      {
-          "www.google.com.",
-          "www.google.com",
-      },
-      {
-          "www.google.COM.",
-          "www.google.com",
-      },
-      {
-          "www.google.com..",
-          "www.google.com",
-      },
-      {
-          "www.google.com........",
-          "www.google.com",
-      },
-      {
-          "",
-          "",
-      },
-      {
-          ".",
-          "",
-      },
-      {
-          "........",
-          "",
-      },
-      {
-          "\xe5\x85\x89.google.com",
-          "xn--54q.google.com",
-      },
-  };
-  // clang-format on
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); ++i) {
-    EXPECT_EQ(std::string(tests[i].expected),
-              QuicheHostnameUtils::NormalizeHostname(tests[i].input));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/platform/api/quiche_mem_slice.h b/common/platform/api/quiche_mem_slice.h
deleted file mode 100644
index ce59c75..0000000
--- a/common/platform/api/quiche_mem_slice.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
-#define QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
-
-#include <memory>
-
-#include "quiche_platform_impl/quiche_mem_slice_impl.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quiche {
-
-// QuicheMemSlice is a wrapper around a platform-specific I/O buffer type. It
-// may be reference counted, though QUICHE itself does not rely on that.
-class QUICHE_EXPORT_PRIVATE QuicheMemSlice {
- public:
-  // Constructs a empty QuicheMemSlice with no underlying data.
-  QuicheMemSlice() = default;
-
-  // Constructs a QuicheMemSlice that takes ownership of |buffer|.  The length
-  // of the |buffer| must not be zero.  To construct an empty QuicheMemSlice,
-  // use the zero-argument constructor instead.
-  explicit QuicheMemSlice(QuicheBuffer buffer) : impl_(std::move(buffer)) {}
-
-  // Constructs a QuicheMemSlice that takes ownership of |buffer| allocated on
-  // heap.  |length| must not be zero.
-  QuicheMemSlice(std::unique_ptr<char[]> buffer, size_t length)
-      : impl_(std::move(buffer), length) {}
-
-  // Constructs QuicheMemSlice from |impl|. It takes the reference away from
-  // |impl|.
-  explicit QuicheMemSlice(QuicheMemSliceImpl impl) : impl_(std::move(impl)) {}
-
-  QuicheMemSlice(const QuicheMemSlice& other) = delete;
-  QuicheMemSlice& operator=(const QuicheMemSlice& other) = delete;
-
-  // Move constructors. |other| will not hold a reference to the data buffer
-  // after this call completes.
-  QuicheMemSlice(QuicheMemSlice&& other) = default;
-  QuicheMemSlice& operator=(QuicheMemSlice&& other) = default;
-
-  ~QuicheMemSlice() = default;
-
-  // Release the underlying reference. Further access the memory will result in
-  // undefined behavior.
-  void Reset() { impl_.Reset(); }
-
-  // Returns a const char pointer to underlying data buffer.
-  const char* data() const { return impl_.data(); }
-  // Returns the length of underlying data buffer.
-  size_t length() const { return impl_.length(); }
-  // Returns the representation of the underlying data as a string view.
-  absl::string_view AsStringView() const {
-    return absl::string_view(data(), length());
-  }
-
-  bool empty() const { return impl_.empty(); }
-
-  QuicheMemSliceImpl* impl() { return &impl_; }
-
- private:
-  QuicheMemSliceImpl impl_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
diff --git a/common/platform/api/quiche_mem_slice_test.cc b/common/platform/api/quiche_mem_slice_test.cc
deleted file mode 100644
index e110f90..0000000
--- a/common/platform/api/quiche_mem_slice_test.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_mem_slice.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_buffer_allocator.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-class QuicheMemSliceTest : public QuicheTest {
- public:
-  QuicheMemSliceTest() {
-    size_t length = 1024;
-    slice_ = QuicheMemSlice(QuicheBuffer(&allocator_, length));
-    orig_data_ = slice_.data();
-    orig_length_ = slice_.length();
-  }
-
-  SimpleBufferAllocator allocator_;
-  QuicheMemSlice slice_;
-  const char* orig_data_;
-  size_t orig_length_;
-};
-
-TEST_F(QuicheMemSliceTest, MoveConstruct) {
-  QuicheMemSlice moved(std::move(slice_));
-  EXPECT_EQ(moved.data(), orig_data_);
-  EXPECT_EQ(moved.length(), orig_length_);
-  EXPECT_EQ(nullptr, slice_.data());
-  EXPECT_EQ(0u, slice_.length());
-  EXPECT_TRUE(slice_.empty());
-}
-
-TEST_F(QuicheMemSliceTest, MoveAssign) {
-  QuicheMemSlice moved;
-  moved = std::move(slice_);
-  EXPECT_EQ(moved.data(), orig_data_);
-  EXPECT_EQ(moved.length(), orig_length_);
-  EXPECT_EQ(nullptr, slice_.data());
-  EXPECT_EQ(0u, slice_.length());
-  EXPECT_TRUE(slice_.empty());
-}
-
-TEST_F(QuicheMemSliceTest, SliceAllocatedOnHeap) {
-  auto buffer = std::make_unique<char[]>(128);
-  char* orig_data = buffer.get();
-  size_t used_length = 105;
-  QuicheMemSlice slice = QuicheMemSlice(std::move(buffer), used_length);
-  QuicheMemSlice moved = std::move(slice);
-  EXPECT_EQ(moved.data(), orig_data);
-  EXPECT_EQ(moved.length(), used_length);
-}
-
-TEST_F(QuicheMemSliceTest, SliceFromBuffer) {
-  const absl::string_view kTestString =
-      "RFC 9000 Release Celebration Memorial Test String";
-  auto buffer = QuicheBuffer::Copy(&allocator_, kTestString);
-  QuicheMemSlice slice(std::move(buffer));
-
-  EXPECT_EQ(buffer.data(), nullptr);  // NOLINT(bugprone-use-after-move)
-  EXPECT_EQ(buffer.size(), 0u);
-  EXPECT_EQ(slice.AsStringView(), kTestString);
-  EXPECT_EQ(slice.length(), kTestString.length());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/platform/api/quiche_mutex.cc b/common/platform/api/quiche_mutex.cc
deleted file mode 100644
index 31c5951..0000000
--- a/common/platform/api/quiche_mutex.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_mutex.h"
-
-namespace quiche {
-
-void QuicheMutex::WriterLock() { impl_.WriterLock(); }
-
-void QuicheMutex::WriterUnlock() { impl_.WriterUnlock(); }
-
-void QuicheMutex::ReaderLock() { impl_.ReaderLock(); }
-
-void QuicheMutex::ReaderUnlock() { impl_.ReaderUnlock(); }
-
-void QuicheMutex::AssertReaderHeld() const { impl_.AssertReaderHeld(); }
-
-QuicheReaderMutexLock::QuicheReaderMutexLock(QuicheMutex* lock) : lock_(lock) {
-  lock->ReaderLock();
-}
-
-QuicheReaderMutexLock::~QuicheReaderMutexLock() { lock_->ReaderUnlock(); }
-
-QuicheWriterMutexLock::QuicheWriterMutexLock(QuicheMutex* lock) : lock_(lock) {
-  lock->WriterLock();
-}
-
-QuicheWriterMutexLock::~QuicheWriterMutexLock() { lock_->WriterUnlock(); }
-
-}  // namespace quiche
diff --git a/common/platform/api/quiche_reference_counted.h b/common/platform/api/quiche_reference_counted.h
deleted file mode 100644
index 6585a30..0000000
--- a/common/platform/api/quiche_reference_counted.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
-
-#include "quiche_platform_impl/quiche_reference_counted_impl.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-// Base class for explicitly reference-counted objects in QUIC.
-class QUICHE_EXPORT_PRIVATE QuicheReferenceCounted
-    : public QuicheReferenceCountedImpl {
- public:
-  QuicheReferenceCounted() {}
-
- protected:
-  ~QuicheReferenceCounted() override {}
-};
-
-// A class representing a reference counted pointer in QUIC.
-//
-// Construct or initialize QuicheReferenceCountedPointer from raw pointer. Here
-// raw pointer MUST be a newly created object. Reference count of a newly
-// created object is undefined, but that will be 1 after being added to
-// QuicheReferenceCountedPointer.
-// QuicheReferenceCountedPointer is used as a local variable.
-// QuicheReferenceCountedPointer<T> r_ptr(new T());
-// or, equivalently:
-// QuicheReferenceCountedPointer<T> r_ptr;
-// T* p = new T();
-// r_ptr = T;
-//
-// QuicheReferenceCountedPointer is used as a member variable:
-// MyClass::MyClass() : r_ptr(new T()) {}
-//
-// This is WRONG, since *p is not guaranteed to be newly created:
-// MyClass::MyClass(T* p) : r_ptr(p) {}
-//
-// Given an existing QuicheReferenceCountedPointer, create a duplicate that has
-// its own reference on the object:
-// QuicheReferenceCountedPointer<T> r_ptr_b(r_ptr_a);
-// or, equivalently:
-// QuicheReferenceCountedPointer<T> r_ptr_b = r_ptr_a;
-//
-// Given an existing QuicheReferenceCountedPointer, create a
-// QuicheReferenceCountedPointer that adopts the reference:
-// QuicheReferenceCountedPointer<T> r_ptr_b(std::move(r_ptr_a));
-// or, equivalently:
-// QuicheReferenceCountedPointer<T> r_ptr_b = std::move(r_ptr_a);
-
-template <class T>
-class QUICHE_NO_EXPORT QuicheReferenceCountedPointer {
- public:
-  QuicheReferenceCountedPointer() = default;
-
-  // Constructor from raw pointer |p|. This guarantees that the reference count
-  // of *p is 1. This should be only called when a new object is created.
-  // Calling this on an already existent object does not increase its reference
-  // count.
-  explicit QuicheReferenceCountedPointer(T* p) : impl_(p) {}
-
-  // Allows implicit conversion from nullptr.
-  QuicheReferenceCountedPointer(std::nullptr_t) : impl_(nullptr) {}  // NOLINT
-
-  // Copy and copy conversion constructors. It does not take the reference away
-  // from |other| and they each end up with their own reference.
-  template <typename U>
-  QuicheReferenceCountedPointer(  // NOLINT
-      const QuicheReferenceCountedPointer<U>& other)
-      : impl_(other.impl()) {}
-  QuicheReferenceCountedPointer(const QuicheReferenceCountedPointer& other)
-      : impl_(other.impl()) {}
-
-  // Move constructors. After move, it adopts the reference from |other|.
-  template <typename U>
-  QuicheReferenceCountedPointer(
-      QuicheReferenceCountedPointer<U>&& other)  // NOLINT
-      : impl_(std::move(other.impl())) {}
-  QuicheReferenceCountedPointer(QuicheReferenceCountedPointer&& other)
-      : impl_(std::move(other.impl())) {}
-
-  ~QuicheReferenceCountedPointer() = default;
-
-  // Copy assignments.
-  QuicheReferenceCountedPointer& operator=(
-      const QuicheReferenceCountedPointer& other) {
-    impl_ = other.impl();
-    return *this;
-  }
-  template <typename U>
-  QuicheReferenceCountedPointer<T>& operator=(
-      const QuicheReferenceCountedPointer<U>& other) {
-    impl_ = other.impl();
-    return *this;
-  }
-
-  // Move assignments.
-  QuicheReferenceCountedPointer& operator=(
-      QuicheReferenceCountedPointer&& other) {
-    impl_ = std::move(other.impl());
-    return *this;
-  }
-  template <typename U>
-  QuicheReferenceCountedPointer<T>& operator=(
-      QuicheReferenceCountedPointer<U>&& other) {
-    impl_ = std::move(other.impl());
-    return *this;
-  }
-
-  // Accessors for the referenced object.
-  // operator*() and operator->() will assert() if there is no current object.
-  T& operator*() const { return *impl_; }
-  T* operator->() const { return impl_.get(); }
-
-  explicit operator bool() const { return static_cast<bool>(impl_); }
-
-  // Assignment operator on raw pointer. Drops a reference to current pointee,
-  // if any, and replaces it with |p|. This guarantees that the reference count
-  // of *p is 1. This should only be used when a new object is created.  Calling
-  // this on an already existent object is undefined behavior.
-  QuicheReferenceCountedPointer<T>& operator=(T* p) {
-    impl_ = p;
-    return *this;
-  }
-
-  // Returns the raw pointer with no change in reference count.
-  T* get() const { return impl_.get(); }
-
-  QuicheReferenceCountedPointerImpl<T>& impl() { return impl_; }
-  const QuicheReferenceCountedPointerImpl<T>& impl() const { return impl_; }
-
-  // Comparisons against same type.
-  friend bool operator==(const QuicheReferenceCountedPointer& a,
-                         const QuicheReferenceCountedPointer& b) {
-    return a.get() == b.get();
-  }
-  friend bool operator!=(const QuicheReferenceCountedPointer& a,
-                         const QuicheReferenceCountedPointer& b) {
-    return a.get() != b.get();
-  }
-
-  // Comparisons against nullptr.
-  friend bool operator==(const QuicheReferenceCountedPointer& a,
-                         std::nullptr_t) {
-    return a.get() == nullptr;
-  }
-  friend bool operator==(std::nullptr_t,
-                         const QuicheReferenceCountedPointer& b) {
-    return nullptr == b.get();
-  }
-  friend bool operator!=(const QuicheReferenceCountedPointer& a,
-                         std::nullptr_t) {
-    return a.get() != nullptr;
-  }
-  friend bool operator!=(std::nullptr_t,
-                         const QuicheReferenceCountedPointer& b) {
-    return nullptr != b.get();
-  }
-
- private:
-  QuicheReferenceCountedPointerImpl<T> impl_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
diff --git a/common/platform/api/quiche_reference_counted_test.cc b/common/platform/api/quiche_reference_counted_test.cc
deleted file mode 100644
index 5248e4e..0000000
--- a/common/platform/api/quiche_reference_counted_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_reference_counted.h"
-
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-class Base : public QuicheReferenceCounted {
- public:
-  explicit Base(bool* destroyed) : destroyed_(destroyed) {
-    *destroyed_ = false;
-  }
-
- protected:
-  ~Base() override { *destroyed_ = true; }
-
- private:
-  bool* destroyed_;
-};
-
-class Derived : public Base {
- public:
-  explicit Derived(bool* destroyed) : Base(destroyed) {}
-
- private:
-  ~Derived() override {}
-};
-
-class QuicheReferenceCountedTest : public QuicheTest {};
-
-TEST_F(QuicheReferenceCountedTest, DefaultConstructor) {
-  QuicheReferenceCountedPointer<Base> a;
-  EXPECT_EQ(nullptr, a);
-  EXPECT_EQ(nullptr, a.get());
-  EXPECT_FALSE(a);
-}
-
-TEST_F(QuicheReferenceCountedTest, ConstructFromRawPointer) {
-  bool destroyed = false;
-  {
-    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
-    EXPECT_FALSE(destroyed);
-  }
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, RawPointerAssignment) {
-  bool destroyed = false;
-  {
-    QuicheReferenceCountedPointer<Base> a;
-    Base* rct = new Base(&destroyed);
-    a = rct;
-    EXPECT_FALSE(destroyed);
-  }
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerCopy) {
-  bool destroyed = false;
-  {
-    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
-    {
-      QuicheReferenceCountedPointer<Base> b(a);
-      EXPECT_EQ(a, b);
-      EXPECT_FALSE(destroyed);
-    }
-    EXPECT_FALSE(destroyed);
-  }
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerCopyAssignment) {
-  bool destroyed = false;
-  {
-    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
-    {
-      QuicheReferenceCountedPointer<Base> b = a;
-      EXPECT_EQ(a, b);
-      EXPECT_FALSE(destroyed);
-    }
-    EXPECT_FALSE(destroyed);
-  }
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerCopyFromOtherType) {
-  bool destroyed = false;
-  {
-    QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
-    {
-      QuicheReferenceCountedPointer<Base> b(a);
-      EXPECT_EQ(a.get(), b.get());
-      EXPECT_FALSE(destroyed);
-    }
-    EXPECT_FALSE(destroyed);
-  }
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerCopyAssignmentFromOtherType) {
-  bool destroyed = false;
-  {
-    QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
-    {
-      QuicheReferenceCountedPointer<Base> b = a;
-      EXPECT_EQ(a.get(), b.get());
-      EXPECT_FALSE(destroyed);
-    }
-    EXPECT_FALSE(destroyed);
-  }
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerMove) {
-  bool destroyed = false;
-  QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
-  EXPECT_FALSE(destroyed);
-  QuicheReferenceCountedPointer<Base> b(std::move(a));
-  EXPECT_FALSE(destroyed);
-  EXPECT_NE(nullptr, b);
-  EXPECT_EQ(nullptr, a);  // NOLINT
-
-  b = nullptr;
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerMoveAssignment) {
-  bool destroyed = false;
-  QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
-  EXPECT_FALSE(destroyed);
-  QuicheReferenceCountedPointer<Base> b = std::move(a);
-  EXPECT_FALSE(destroyed);
-  EXPECT_NE(nullptr, b);
-  EXPECT_EQ(nullptr, a);  // NOLINT
-
-  b = nullptr;
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerMoveFromOtherType) {
-  bool destroyed = false;
-  QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
-  EXPECT_FALSE(destroyed);
-  QuicheReferenceCountedPointer<Base> b(std::move(a));
-  EXPECT_FALSE(destroyed);
-  EXPECT_NE(nullptr, b);
-  EXPECT_EQ(nullptr, a);  // NOLINT
-
-  b = nullptr;
-  EXPECT_TRUE(destroyed);
-}
-
-TEST_F(QuicheReferenceCountedTest, PointerMoveAssignmentFromOtherType) {
-  bool destroyed = false;
-  QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
-  EXPECT_FALSE(destroyed);
-  QuicheReferenceCountedPointer<Base> b = std::move(a);
-  EXPECT_FALSE(destroyed);
-  EXPECT_NE(nullptr, b);
-  EXPECT_EQ(nullptr, a);  // NOLINT
-
-  b = nullptr;
-  EXPECT_TRUE(destroyed);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/platform/api/quiche_test_loopback.cc b/common/platform/api/quiche_test_loopback.cc
deleted file mode 100644
index a2f6908..0000000
--- a/common/platform/api/quiche_test_loopback.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_test_loopback.h"
-
-namespace quiche {
-
-quic::IpAddressFamily AddressFamilyUnderTest() {
-  return AddressFamilyUnderTestImpl();
-}
-
-quic::QuicIpAddress TestLoopback4() { return TestLoopback4Impl(); }
-
-quic::QuicIpAddress TestLoopback6() { return TestLoopback6Impl(); }
-
-quic::QuicIpAddress TestLoopback() { return TestLoopbackImpl(); }
-
-quic::QuicIpAddress TestLoopback(int index) { return TestLoopbackImpl(index); }
-
-}  // namespace quiche
diff --git a/common/platform/api/quiche_test_loopback.h b/common/platform/api/quiche_test_loopback.h
deleted file mode 100644
index 9d36b09..0000000
--- a/common/platform/api/quiche_test_loopback.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
-#define QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
-
-#include "quiche_platform_impl/quiche_test_loopback_impl.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quiche {
-
-// Returns the address family (IPv4 or IPv6) used to run test under.
-quic::IpAddressFamily AddressFamilyUnderTest();
-
-// Returns an IPv4 loopback address.
-quic::QuicIpAddress TestLoopback4();
-
-// Returns the only IPv6 loopback address.
-quic::QuicIpAddress TestLoopback6();
-
-// Returns an appropriate IPv4/Ipv6 loopback address based upon whether the
-// test's environment.
-quic::QuicIpAddress TestLoopback();
-
-// If address family under test is IPv4, returns an indexed IPv4 loopback
-// address. If address family under test is IPv6, the address returned is
-// platform-dependent.
-quic::QuicIpAddress TestLoopback(int index);
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
diff --git a/common/platform/api/quiche_thread.h b/common/platform/api/quiche_thread.h
deleted file mode 100644
index 919ccdc..0000000
--- a/common/platform/api/quiche_thread.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
-#define QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
-
-#include <string>
-
-#include "quiche_platform_impl/quiche_thread_impl.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-// A class representing a thread of execution in QUIC.
-class QUICHE_EXPORT_PRIVATE QuicheThread : public QuicheThreadImpl {
- public:
-  QuicheThread(const std::string& string) : QuicheThreadImpl(string) {}
-  QuicheThread(const QuicheThread&) = delete;
-  QuicheThread& operator=(const QuicheThread&) = delete;
-
-  // Impl defines a virtual void Run() method which subclasses
-  // must implement.
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
diff --git a/common/platform/api/quiche_time_utils_test.cc b/common/platform/api/quiche_time_utils_test.cc
deleted file mode 100644
index 1992b84..0000000
--- a/common/platform/api/quiche_time_utils_test.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_time_utils.h"
-
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace {
-
-TEST(QuicheTimeUtilsTest, Basic) {
-  EXPECT_EQ(1, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 0, 1));
-  EXPECT_EQ(365 * 86400, QuicheUtcDateTimeToUnixSeconds(1971, 1, 1, 0, 0, 0));
-  // Some arbitrary timestamps closer to the present, compared to the output of
-  // "Date(...).getTime()" from the JavaScript console.
-  EXPECT_EQ(1152966896,
-            QuicheUtcDateTimeToUnixSeconds(2006, 7, 15, 12, 34, 56));
-  EXPECT_EQ(1591130001, QuicheUtcDateTimeToUnixSeconds(2020, 6, 2, 20, 33, 21));
-
-  EXPECT_EQ(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1970, 2, 29, 0, 0, 1));
-  EXPECT_NE(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1972, 2, 29, 0, 0, 1));
-}
-
-TEST(QuicheTimeUtilsTest, Bounds) {
-  EXPECT_EQ(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1970, 1, 32, 0, 0, 1));
-  EXPECT_EQ(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1970, 4, 31, 0, 0, 1));
-  EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1));
-  EXPECT_EQ(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1970, 13, 1, 0, 0, 1));
-  EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1));
-  EXPECT_EQ(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 24, 0, 0));
-  EXPECT_EQ(absl::nullopt,
-            QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 60, 0));
-}
-
-TEST(QuicheTimeUtilsTest, LeapSecond) {
-  EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 23, 59, 60),
-            QuicheUtcDateTimeToUnixSeconds(2015, 7, 1, 0, 0, 0));
-  EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 25, 59, 60),
-            absl::nullopt);
-}
-
-}  // namespace
-}  // namespace quiche
diff --git a/common/platform/api/quiche_url_utils_test.cc b/common/platform/api/quiche_url_utils_test.cc
deleted file mode 100644
index 1a59d74..0000000
--- a/common/platform/api/quiche_url_utils_test.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_url_utils.h"
-
-#include <set>
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace {
-
-void ValidateExpansion(
-    const std::string& uri_template,
-    const absl::flat_hash_map<std::string, std::string>& parameters,
-    const std::string& expected_expansion,
-    const absl::flat_hash_set<std::string>& expected_vars_found) {
-  absl::flat_hash_set<std::string> vars_found;
-  std::string target;
-  ASSERT_TRUE(
-      ExpandURITemplate(uri_template, parameters, &target, &vars_found));
-  EXPECT_EQ(expected_expansion, target);
-  EXPECT_EQ(vars_found, expected_vars_found);
-}
-
-TEST(QuicheUrlUtilsTest, Basic) {
-  ValidateExpansion("/{foo}/{bar}/", {{"foo", "123"}, {"bar", "456"}},
-                    "/123/456/", {"foo", "bar"});
-}
-
-TEST(QuicheUrlUtilsTest, ExtraParameter) {
-  ValidateExpansion("/{foo}/{bar}/{baz}/", {{"foo", "123"}, {"bar", "456"}},
-                    "/123/456//", {"foo", "bar"});
-}
-
-TEST(QuicheUrlUtilsTest, MissingParameter) {
-  ValidateExpansion("/{foo}/{baz}/", {{"foo", "123"}, {"bar", "456"}}, "/123//",
-                    {"foo"});
-}
-
-TEST(QuicheUrlUtilsTest, RepeatedParameter) {
-  ValidateExpansion("/{foo}/{bar}/{foo}/", {{"foo", "123"}, {"bar", "456"}},
-                    "/123/456/123/", {"foo", "bar"});
-}
-
-TEST(QuicheUrlUtilsTest, URLEncoding) {
-  ValidateExpansion("/{foo}/{bar}/", {{"foo", "123"}, {"bar", ":"}},
-                    "/123/%3A/", {"foo", "bar"});
-}
-
-void ValidateUrlDecode(const std::string& input,
-                       const absl::optional<std::string>& expected_output) {
-  absl::optional<std::string> decode_result = AsciiUrlDecode(input);
-  if (!expected_output.has_value()) {
-    EXPECT_FALSE(decode_result.has_value());
-    return;
-  }
-  ASSERT_TRUE(decode_result.has_value());
-  EXPECT_EQ(decode_result.value(), expected_output);
-}
-
-TEST(QuicheUrlUtilsTest, DecodeNoChange) {
-  ValidateUrlDecode("foobar", "foobar");
-}
-
-TEST(QuicheUrlUtilsTest, DecodeReplace) {
-  ValidateUrlDecode("%7Bfoobar%7D", "{foobar}");
-}
-
-TEST(QuicheUrlUtilsTest, DecodeFail) {
-  ValidateUrlDecode("%FF", absl::nullopt);
-}
-
-}  // namespace
-}  // namespace quiche
diff --git a/common/platform/default/quiche_platform_impl/quic_flags_impl.cc b/common/platform/default/quiche_platform_impl/quic_flags_impl.cc
deleted file mode 100644
index 81b1d8f..0000000
--- a/common/platform/default/quiche_platform_impl/quic_flags_impl.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quiche_platform_impl/quic_flags_impl.h"
-
-#define DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE(type, flag, value, doc) \
-  type FLAGS_##flag = value;
-
-#define DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES(type, flag, internal_value, \
-                                             external_value, doc)        \
-  type FLAGS_##flag = external_value;
-
-// Preprocessor macros can only have one definition.
-// Select the right macro based on the number of arguments.
-#define GET_6TH_ARG(arg1, arg2, arg3, arg4, arg5, arg6, ...) arg6
-#define QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(...)                    \
-  GET_6TH_ARG(__VA_ARGS__, DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES, \
-              DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE)
-#define QUIC_PROTOCOL_FLAG(...) \
-  QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
-
-#include "quic/core/quic_protocol_flags_list.h"
-
-#undef QUIC_PROTOCOL_FLAG
-#undef QUIC_PROTOCOL_FLAG_MACRO_CHOOSER
-#undef GET_6TH_ARG
-#undef DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES
-#undef DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE
diff --git a/common/platform/default/quiche_platform_impl/quic_flags_impl.h b/common/platform/default/quiche_platform_impl/quic_flags_impl.h
deleted file mode 100644
index b58d24d..0000000
--- a/common/platform/default/quiche_platform_impl/quic_flags_impl.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
-
-#include <string>
-
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_flags.h"
-
-#define QUIC_PROTOCOL_FLAG(type, flag, ...) \
-  QUICHE_EXPORT_PRIVATE extern type FLAGS_##flag;
-#include "quic/core/quic_protocol_flags_list.h"
-#undef QUIC_PROTOCOL_FLAG
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h b/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h
deleted file mode 100644
index de164aa..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
-
-#include "common/platform/api/quiche_logging.h"
-
-#define QUICHE_BUG_IMPL(b) QUICHE_LOG(DFATAL)
-#define QUICHE_BUG_IF_IMPL(b, condition) QUICHE_LOG_IF(DFATAL, condition)
-#define QUICHE_PEER_BUG_IMPL(b) QUICHE_LOG(DFATAL)
-#define QUICHE_PEER_BUG_IF_IMPL(b, condition) QUICHE_LOG_IF(DFATAL, condition)
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_export_impl.h b/common/platform/default/quiche_platform_impl/quiche_export_impl.h
deleted file mode 100644
index 1001b81..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_export_impl.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
-
-// These macros are documented in: quic/platform/api/quic_export.h
-
-#define QUICHE_EXPORT_IMPL
-#define QUICHE_EXPORT_PRIVATE_IMPL
-#define QUICHE_NO_EXPORT_IMPL
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc b/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
deleted file mode 100644
index b68f93d..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quiche_platform_impl/quiche_flags_impl.h"
-
-#define QUIC_FLAG(flag, value) bool flag = value;
-#include "quic/core/quic_flags_list.h"
-#undef QUIC_FLAG
diff --git a/common/platform/default/quiche_platform_impl/quiche_flags_impl.h b/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
deleted file mode 100644
index 8d655ed..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "common/platform/api/quiche_export.h"
-
-#define QUIC_FLAG(flag, value) QUICHE_EXPORT_PRIVATE extern bool flag;
-#include "quic/core/quic_flags_list.h"
-#undef QUIC_FLAG
-
-inline bool GetQuicheFlagImpl(bool flag) { return flag; }
-inline int32_t GetQuicheFlagImpl(int32_t flag) { return flag; }
-inline int64_t GetQuicheFlagImpl(int64_t flag) { return flag; }
-inline uint64_t GetQuicheFlagImpl(uint64_t flag) { return flag; }
-inline double GetQuicheFlagImpl(double flag) { return flag; }
-inline std::string GetQuicheFlagImpl(const std::string& flag) { return flag; }
-#define SetQuicheFlagImpl(flag, value) ((flag) = (value))
-
-// ------------------------------------------------------------------------
-// QUIC feature flags implementation.
-// ------------------------------------------------------------------------
-#define QUICHE_RELOADABLE_FLAG(flag) FLAGS_quic_reloadable_flag_##flag
-#define QUICHE_RESTART_FLAG(flag) FLAGS_quic_restart_flag_##flag
-#define GetQuicheReloadableFlagImpl(module, flag) \
-  GetQuicheFlag(QUICHE_RELOADABLE_FLAG(flag))
-#define SetQuicheReloadableFlagImpl(module, flag, value) \
-  SetQuicheFlag(QUICHE_RELOADABLE_FLAG(flag), value)
-#define GetQuicheRestartFlagImpl(module, flag) \
-  GetQuicheFlag(QUICHE_RESTART_FLAG(flag))
-#define SetQuicheRestartFlagImpl(module, flag, value) \
-  SetQuicheFlag(QUICHE_RESTART_FLAG(flag), value)
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h b/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
deleted file mode 100644
index 175d49d..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
-
-#include "common/platform/api/quiche_export.h"
-
-#if defined(_WIN32)
-
-// See <https://pubs.opengroup.org/onlinepubs/009604599/basedefs/sys/uio.h.html>
-struct QUICHE_EXPORT_PRIVAATE iovec {
-  void* iov_base;
-  size_t iov_len;
-};
-
-#else
-
-#include <sys/uio.h>  // IWYU pragma: export
-
-#endif  // defined(_WIN32)
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h b/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
deleted file mode 100644
index 2db6c44..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
-
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_buffer_allocator.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quiche {
-
-class QUICHE_EXPORT_PRIVATE QuicheMemSliceImpl {
- public:
-  QuicheMemSliceImpl() = default;
-
-  explicit QuicheMemSliceImpl(QuicheBuffer buffer)
-      : buffer_(std::move(buffer)) {}
-
-  QuicheMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length)
-      : buffer_(
-            QuicheBuffer(QuicheUniqueBufferPtr(
-                             buffer.release(),
-                             QuicheBufferDeleter(SimpleBufferAllocator::Get())),
-                         length)) {}
-
-  QuicheMemSliceImpl(const QuicheMemSliceImpl& other) = delete;
-  QuicheMemSliceImpl& operator=(const QuicheMemSliceImpl& other) = delete;
-
-  // Move constructors. |other| will not hold a reference to the data buffer
-  // after this call completes.
-  QuicheMemSliceImpl(QuicheMemSliceImpl&& other) = default;
-  QuicheMemSliceImpl& operator=(QuicheMemSliceImpl&& other) = default;
-
-  ~QuicheMemSliceImpl() = default;
-
-  void Reset() { buffer_ = QuicheBuffer(); }
-
-  const char* data() const { return buffer_.data(); }
-  size_t length() const { return buffer_.size(); }
-  bool empty() const { return buffer_.empty(); }
-
- private:
-  QuicheBuffer buffer_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h b/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
deleted file mode 100644
index 369e649..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
-
-#include "absl/synchronization/mutex.h"
-#include "absl/synchronization/notification.h"
-#include "common/platform/api/quiche_export.h"
-
-#define QUICHE_EXCLUSIVE_LOCKS_REQUIRED_IMPL ABSL_EXCLUSIVE_LOCKS_REQUIRED
-#define QUICHE_GUARDED_BY_IMPL ABSL_GUARDED_BY
-#define QUICHE_LOCKABLE_IMPL ABSL_LOCKABLE
-#define QUICHE_LOCKS_EXCLUDED_IMPL ABSL_LOCKS_EXCLUDED
-#define QUICHE_SHARED_LOCKS_REQUIRED_IMPL ABSL_SHARED_LOCKS_REQUIRED
-#define QUICHE_EXCLUSIVE_LOCK_FUNCTION_IMPL ABSL_EXCLUSIVE_LOCK_FUNCTION
-#define QUICHE_UNLOCK_FUNCTION_IMPL ABSL_UNLOCK_FUNCTION
-#define QUICHE_SHARED_LOCK_FUNCTION_IMPL ABSL_SHARED_LOCK_FUNCTION
-#define QUICHE_SCOPED_LOCKABLE_IMPL ABSL_SCOPED_LOCKABLE
-#define QUICHE_ASSERT_SHARED_LOCK_IMPL ABSL_ASSERT_SHARED_LOCK
-
-namespace quiche {
-
-// A class wrapping a non-reentrant mutex.
-class ABSL_LOCKABLE QUICHE_EXPORT_PRIVATE QuicheLockImpl {
- public:
-  QuicheLockImpl() = default;
-  QuicheLockImpl(const QuicheLockImpl&) = delete;
-  QuicheLockImpl& operator=(const QuicheLockImpl&) = delete;
-
-  // Block until mu_ is free, then acquire it exclusively.
-  void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION();
-
-  // Release mu_. Caller must hold it exclusively.
-  void WriterUnlock() ABSL_UNLOCK_FUNCTION();
-
-  // Block until mu_ is free or shared, then acquire a share of it.
-  void ReaderLock() ABSL_SHARED_LOCK_FUNCTION();
-
-  // Release mu_. Caller could hold it in shared mode.
-  void ReaderUnlock() ABSL_UNLOCK_FUNCTION();
-
-  // Returns immediately if current thread holds mu_ in at least shared
-  // mode.  Otherwise, reports an error by crashing with a diagnostic.
-  void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK();
-
- private:
-  absl::Mutex mu_;
-};
-
-// A Notification allows threads to receive notification of a single occurrence
-// of a single event.
-class QUICHE_EXPORT_PRIVATE QuicheNotificationImpl {
- public:
-  QuicheNotificationImpl() = default;
-  QuicheNotificationImpl(const QuicheNotificationImpl&) = delete;
-  QuicheNotificationImpl& operator=(const QuicheNotificationImpl&) = delete;
-
-  bool HasBeenNotified() { return notification_.HasBeenNotified(); }
-
-  void Notify() { notification_.Notify(); }
-
-  void WaitForNotification() { notification_.WaitForNotification(); }
-
- private:
-  absl::Notification notification_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h b/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h
deleted file mode 100644
index 1447b54..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
-
-#include <atomic>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-
-class QUICHE_EXPORT_PRIVATE QuicheReferenceCountedImpl {
- public:
-  virtual ~QuicheReferenceCountedImpl() { QUICHE_DCHECK_EQ(ref_count_, 0); }
-
-  void AddReference() { ref_count_.fetch_add(1, std::memory_order_relaxed); }
-
-  // Returns true if the objects needs to be deleted.
-  ABSL_MUST_USE_RESULT bool RemoveReference() {
-    int new_count = ref_count_.fetch_sub(1, std::memory_order_acq_rel) - 1;
-    QUICHE_DCHECK_GE(new_count, 0);
-    return new_count == 0;
-  }
-
-  bool HasUniqueReference() const {
-    return ref_count_.load(std::memory_order_acquire) == 1;
-  }
-
- private:
-  std::atomic<int> ref_count_ = 1;
-};
-
-template <class T>
-class QUICHE_NO_EXPORT QuicheReferenceCountedPointerImpl {
- public:
-  QuicheReferenceCountedPointerImpl() = default;
-  ~QuicheReferenceCountedPointerImpl() { RemoveReference(); }
-
-  // Constructor from raw pointer |p|. This guarantees that the reference count
-  // of *p is 1. This should be only called when a new object is created.
-  explicit QuicheReferenceCountedPointerImpl(T* p) : object_(p) {
-    if (p != nullptr) {
-      QUICHE_DCHECK(p->HasUniqueReference());
-    }
-  }
-
-  explicit QuicheReferenceCountedPointerImpl(std::nullptr_t)
-      : object_(nullptr) {}
-
-  // Copy and copy conversion constructors.
-  QuicheReferenceCountedPointerImpl(
-      const QuicheReferenceCountedPointerImpl& other) {
-    AssignObject(other.get());
-    AddReference();
-  }
-  template <typename U>
-  QuicheReferenceCountedPointerImpl(  // NOLINT
-      const QuicheReferenceCountedPointerImpl<U>& other) {
-    AssignObject(other.get());
-    AddReference();
-  }
-
-  // Move constructors.
-  QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl&& other) {
-    object_ = other.object_;
-    other.object_ = nullptr;
-  }
-  template <typename U>
-  QuicheReferenceCountedPointerImpl(
-      QuicheReferenceCountedPointerImpl<U>&& other) {  // NOLINT
-    // We can't access other.object_ since other has different T and object_ is
-    // private.
-    object_ = other.get();
-    AddReference();
-    other = nullptr;
-  }
-
-  // Copy assignments.
-  QuicheReferenceCountedPointerImpl& operator=(
-      const QuicheReferenceCountedPointerImpl& other) {
-    AssignObject(other.object_);
-    AddReference();
-    return *this;
-  }
-  template <typename U>
-  QuicheReferenceCountedPointerImpl<T>& operator=(
-      const QuicheReferenceCountedPointerImpl<U>& other) {
-    AssignObject(other.object_);
-    AddReference();
-    return *this;
-  }
-
-  // Move assignments.
-  QuicheReferenceCountedPointerImpl& operator=(
-      QuicheReferenceCountedPointerImpl&& other) {
-    AssignObject(other.object_);
-    other.object_ = nullptr;
-    return *this;
-  }
-  template <typename U>
-  QuicheReferenceCountedPointerImpl<T>& operator=(
-      QuicheReferenceCountedPointerImpl<U>&& other) {
-    AssignObject(other.get());
-    AddReference();
-    other = nullptr;
-    return *this;
-  }
-
-  T& operator*() const { return *object_; }
-  T* operator->() const { return object_; }
-
-  explicit operator bool() const { return object_ != nullptr; }
-
-  // Assignment operator on raw pointer.  Behaves similar to the raw pointer
-  // constructor.
-  QuicheReferenceCountedPointerImpl<T>& operator=(T* p) {
-    AssignObject(p);
-    if (p != nullptr) {
-      QUICHE_DCHECK(p->HasUniqueReference());
-    }
-    return *this;
-  }
-
-  // Returns the raw pointer with no change in reference count.
-  T* get() const { return object_; }
-
-  // Comparisons against same type.
-  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
-                         const QuicheReferenceCountedPointerImpl& b) {
-    return a.get() == b.get();
-  }
-  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
-                         const QuicheReferenceCountedPointerImpl& b) {
-    return a.get() != b.get();
-  }
-
-  // Comparisons against nullptr.
-  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
-                         std::nullptr_t) {
-    return a.get() == nullptr;
-  }
-  friend bool operator==(std::nullptr_t,
-                         const QuicheReferenceCountedPointerImpl& b) {
-    return nullptr == b.get();
-  }
-  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
-                         std::nullptr_t) {
-    return a.get() != nullptr;
-  }
-  friend bool operator!=(std::nullptr_t,
-                         const QuicheReferenceCountedPointerImpl& b) {
-    return nullptr != b.get();
-  }
-
- private:
-  void AddReference() {
-    if (object_ == nullptr) {
-      return;
-    }
-    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
-    implicitly_cast_object->AddReference();
-  }
-
-  void RemoveReference() {
-    if (object_ == nullptr) {
-      return;
-    }
-    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
-    if (implicitly_cast_object->RemoveReference()) {
-      delete implicitly_cast_object;
-    }
-    object_ = nullptr;
-  }
-
-  void AssignObject(T* new_object) {
-    RemoveReference();
-    object_ = new_object;
-  }
-
-  T* object_ = nullptr;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h b/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
deleted file mode 100644
index 1cc80e5..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
-
-#include "common/simple_buffer_allocator.h"
-
-namespace quiche {
-
-using QuicheStreamBufferAllocatorImpl = quiche::SimpleBufferAllocator;
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h b/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h
deleted file mode 100644
index 8ba419e..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
-
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-
-inline void QuicheRunSystemEventLoopIterationImpl() {}
-
-class QUICHE_EXPORT_PRIVATE QuicheSystemEventLoopImpl {
- public:
-  QuicheSystemEventLoopImpl(std::string context_name) {
-    QUICHE_LOG(INFO) << "Starting event loop for " << context_name;
-  }
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h b/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h
deleted file mode 100644
index 3bcf3b0..0000000
--- a/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
-#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
-
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-// Produces concrete URLs in |target| from templated ones in |uri_template|.
-// Parameters are URL-encoded. Collects the names of any expanded variables in
-// |vars_found|. Supports level 1 templates as specified in RFC 6570. Returns
-// true if the template was parseable, false if it was malformed.
-QUICHE_EXPORT_PRIVATE bool ExpandURITemplateImpl(
-    const std::string& uri_template,
-    const absl::flat_hash_map<std::string, std::string>& parameters,
-    std::string* target,
-    absl::flat_hash_set<std::string>* vars_found = nullptr);
-
-// Decodes a URL-encoded string and converts it to ASCII. If the decoded input
-// contains non-ASCII characters, decoding fails and absl::nullopt is returned.
-QUICHE_EXPORT_PRIVATE absl::optional<std::string> AsciiUrlDecodeImpl(
-    absl::string_view input);
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
diff --git a/common/print_elements.h b/common/print_elements.h
deleted file mode 100644
index 7a0997f..0000000
--- a/common/print_elements.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_PRINT_ELEMENTS_H_
-#define QUICHE_COMMON_PRINT_ELEMENTS_H_
-
-#include <ostream>
-#include <sstream>
-#include <string>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-// Print elements of any iterable container that has cbegin() and cend() methods
-// and the elements have operator<<(ostream) override.
-template <typename T>
-QUICHE_EXPORT_PRIVATE inline std::string PrintElements(const T& container) {
-  std::stringstream debug_string;
-  debug_string << "{";
-  auto it = container.cbegin();
-  if (it != container.cend()) {
-    debug_string << *it;
-    ++it;
-    while (it != container.cend()) {
-      debug_string << ", " << *it;
-      ++it;
-    }
-  }
-  debug_string << "}";
-  return debug_string.str();
-}
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_PRINT_ELEMENTS_H_
diff --git a/common/print_elements_test.cc b/common/print_elements_test.cc
deleted file mode 100644
index 8be4d92..0000000
--- a/common/print_elements_test.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/print_elements.h"
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_error_codes.h"
-#include "common/platform/api/quiche_test.h"
-
-using quic::QuicIetfTransportErrorCodes;
-
-namespace quiche {
-namespace test {
-namespace {
-
-TEST(PrintElementsTest, Empty) {
-  std::vector<std::string> empty{};
-  EXPECT_EQ("{}", PrintElements(empty));
-}
-
-TEST(PrintElementsTest, StdContainers) {
-  std::vector<std::string> one{"foo"};
-  EXPECT_EQ("{foo}", PrintElements(one));
-
-  std::list<std::string> two{"foo", "bar"};
-  EXPECT_EQ("{foo, bar}", PrintElements(two));
-
-  std::deque<absl::string_view> three{"foo", "bar", "baz"};
-  EXPECT_EQ("{foo, bar, baz}", PrintElements(three));
-}
-
-// QuicIetfTransportErrorCodes has a custom operator<<() override.
-TEST(PrintElementsTest, CustomPrinter) {
-  std::vector<QuicIetfTransportErrorCodes> empty{};
-  EXPECT_EQ("{}", PrintElements(empty));
-
-  std::list<QuicIetfTransportErrorCodes> one{
-      QuicIetfTransportErrorCodes::NO_IETF_QUIC_ERROR};
-  EXPECT_EQ("{NO_IETF_QUIC_ERROR}", PrintElements(one));
-
-  std::vector<QuicIetfTransportErrorCodes> two{
-      QuicIetfTransportErrorCodes::FLOW_CONTROL_ERROR,
-      QuicIetfTransportErrorCodes::STREAM_LIMIT_ERROR};
-  EXPECT_EQ("{FLOW_CONTROL_ERROR, STREAM_LIMIT_ERROR}", PrintElements(two));
-
-  std::list<QuicIetfTransportErrorCodes> three{
-      QuicIetfTransportErrorCodes::CONNECTION_ID_LIMIT_ERROR,
-      QuicIetfTransportErrorCodes::PROTOCOL_VIOLATION,
-      QuicIetfTransportErrorCodes::INVALID_TOKEN};
-  EXPECT_EQ("{CONNECTION_ID_LIMIT_ERROR, PROTOCOL_VIOLATION, INVALID_TOKEN}",
-            PrintElements(three));
-}
-
-}  // anonymous namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/quiche_buffer_allocator.cc b/common/quiche_buffer_allocator.cc
deleted file mode 100644
index 0801173..0000000
--- a/common/quiche_buffer_allocator.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_buffer_allocator.h"
-
-#include <cstring>
-
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_prefetch.h"
-
-namespace quiche {
-
-QuicheBuffer QuicheBuffer::CopyFromIovec(QuicheBufferAllocator* allocator,
-                                         const struct iovec* iov, int iov_count,
-                                         size_t iov_offset,
-                                         size_t buffer_length) {
-  if (buffer_length == 0) {
-    return {};
-  }
-
-  int iovnum = 0;
-  while (iovnum < iov_count && iov_offset >= iov[iovnum].iov_len) {
-    iov_offset -= iov[iovnum].iov_len;
-    ++iovnum;
-  }
-  QUICHE_DCHECK_LE(iovnum, iov_count);
-  if (iovnum >= iov_count) {
-    QUICHE_BUG(quiche_bug_10839_1)
-        << "iov_offset larger than iovec total size.";
-    return {};
-  }
-  QUICHE_DCHECK_LE(iov_offset, iov[iovnum].iov_len);
-
-  // Unroll the first iteration that handles iov_offset.
-  const size_t iov_available = iov[iovnum].iov_len - iov_offset;
-  size_t copy_len = std::min(buffer_length, iov_available);
-
-  // Try to prefetch the next iov if there is at least one more after the
-  // current. Otherwise, it looks like an irregular access that the hardware
-  // prefetcher won't speculatively prefetch. Only prefetch one iov because
-  // generally, the iov_offset is not 0, input iov consists of 2K buffers and
-  // the output buffer is ~1.4K.
-  if (copy_len == iov_available && iovnum + 1 < iov_count) {
-    char* next_base = static_cast<char*>(iov[iovnum + 1].iov_base);
-    // Prefetch 2 cachelines worth of data to get the prefetcher started; leave
-    // it to the hardware prefetcher after that.
-    quiche::QuichePrefetchT0(next_base);
-    if (iov[iovnum + 1].iov_len >= 64) {
-      quiche::QuichePrefetchT0(next_base + ABSL_CACHELINE_SIZE);
-    }
-  }
-
-  QuicheBuffer buffer(allocator, buffer_length);
-
-  const char* src = static_cast<char*>(iov[iovnum].iov_base) + iov_offset;
-  char* dst = buffer.data();
-  while (true) {
-    memcpy(dst, src, copy_len);
-    buffer_length -= copy_len;
-    dst += copy_len;
-    if (buffer_length == 0 || ++iovnum >= iov_count) {
-      break;
-    }
-    src = static_cast<char*>(iov[iovnum].iov_base);
-    copy_len = std::min(buffer_length, iov[iovnum].iov_len);
-  }
-
-  QUICHE_BUG_IF(quiche_bug_10839_2, buffer_length > 0)
-      << "iov_offset + buffer_length larger than iovec total size.";
-
-  return buffer;
-}
-
-}  // namespace quiche
diff --git a/common/quiche_buffer_allocator.h b/common/quiche_buffer_allocator.h
deleted file mode 100644
index a30a675..0000000
--- a/common/quiche_buffer_allocator.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
-#define QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_iovec.h"
-
-namespace quiche {
-
-// Abstract base class for classes which allocate and delete buffers.
-class QUICHE_EXPORT_PRIVATE QuicheBufferAllocator {
- public:
-  virtual ~QuicheBufferAllocator() = default;
-
-  // Returns or allocates a new buffer of |size|. Never returns null.
-  virtual char* New(size_t size) = 0;
-
-  // Returns or allocates a new buffer of |size| if |flag_enable| is true.
-  // Otherwise, returns a buffer that is compatible with this class directly
-  // with operator new. Never returns null.
-  virtual char* New(size_t size, bool flag_enable) = 0;
-
-  // Releases a buffer.
-  virtual void Delete(char* buffer) = 0;
-
-  // Marks the allocator as being idle. Serves as a hint to notify the allocator
-  // that it should release any resources it's still holding on to.
-  virtual void MarkAllocatorIdle() {}
-};
-
-// A deleter that can be used to manage ownership of buffers allocated via
-// QuicheBufferAllocator through std::unique_ptr.
-class QUICHE_EXPORT_PRIVATE QuicheBufferDeleter {
- public:
-  explicit QuicheBufferDeleter(QuicheBufferAllocator* allocator)
-      : allocator_(allocator) {}
-
-  QuicheBufferAllocator* allocator() { return allocator_; }
-  void operator()(char* buffer) { allocator_->Delete(buffer); }
-
- private:
-  QuicheBufferAllocator* allocator_;
-};
-
-using QuicheUniqueBufferPtr = std::unique_ptr<char[], QuicheBufferDeleter>;
-
-inline QuicheUniqueBufferPtr MakeUniqueBuffer(QuicheBufferAllocator* allocator,
-                                              size_t size) {
-  return QuicheUniqueBufferPtr(allocator->New(size),
-                               QuicheBufferDeleter(allocator));
-}
-
-// QuicheUniqueBufferPtr with a length attached to it.  Similar to
-// QuicheMemSlice, except unlike QuicheMemSlice, QuicheBuffer is mutable and is
-// not platform-specific.  Also unlike QuicheMemSlice, QuicheBuffer can be
-// empty.
-class QUICHE_EXPORT_PRIVATE QuicheBuffer {
- public:
-  QuicheBuffer() : buffer_(nullptr, QuicheBufferDeleter(nullptr)), size_(0) {}
-  QuicheBuffer(QuicheBufferAllocator* allocator, size_t size)
-      : buffer_(MakeUniqueBuffer(allocator, size)), size_(size) {}
-
-  QuicheBuffer(QuicheUniqueBufferPtr buffer, size_t size)
-      : buffer_(std::move(buffer)), size_(size) {}
-
-  // Make sure the move constructor zeroes out the size field.
-  QuicheBuffer(QuicheBuffer&& other)
-      : buffer_(std::move(other.buffer_)), size_(other.size_) {
-    other.buffer_ = nullptr;
-    other.size_ = 0;
-  }
-  QuicheBuffer& operator=(QuicheBuffer&& other) {
-    buffer_ = std::move(other.buffer_);
-    size_ = other.size_;
-
-    other.buffer_ = nullptr;
-    other.size_ = 0;
-    return *this;
-  }
-
-  // Factory method to create a QuicheBuffer that holds a copy of `data`.
-  static QuicheBuffer Copy(QuicheBufferAllocator* allocator,
-                           absl::string_view data) {
-    QuicheBuffer buffer(allocator, data.size());
-    memcpy(buffer.data(), data.data(), data.size());
-    return buffer;
-  }
-
-  // Factory method to create a QuicheBuffer of length `buffer_length` that
-  // holds a copy of `buffer_length` bytes from `iov` starting at offset
-  // `iov_offset`.  `iov` must be at least `iov_offset + buffer_length` total
-  // length.
-  static QuicheBuffer CopyFromIovec(QuicheBufferAllocator* allocator,
-                                    const struct iovec* iov, int iov_count,
-                                    size_t iov_offset, size_t buffer_length);
-
-  const char* data() const { return buffer_.get(); }
-  char* data() { return buffer_.get(); }
-  size_t size() const { return size_; }
-  bool empty() const { return size_ == 0; }
-  absl::string_view AsStringView() const {
-    return absl::string_view(data(), size());
-  }
-
-  // Releases the ownership of the underlying buffer.
-  QuicheUniqueBufferPtr Release() {
-    size_ = 0;
-    return std::move(buffer_);
-  }
-
- private:
-  QuicheUniqueBufferPtr buffer_;
-  size_t size_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
diff --git a/common/quiche_buffer_allocator_test.cc b/common/quiche_buffer_allocator_test.cc
deleted file mode 100644
index 7d08cf1..0000000
--- a/common/quiche_buffer_allocator_test.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_buffer_allocator.h"
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-#include "common/simple_buffer_allocator.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-TEST(QuicheBuffer, CopyFromEmpty) {
-  SimpleBufferAllocator allocator;
-  QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "");
-  EXPECT_TRUE(buffer.empty());
-}
-
-TEST(QuicheBuffer, Copy) {
-  SimpleBufferAllocator allocator;
-  QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "foobar");
-  EXPECT_EQ("foobar", buffer.AsStringView());
-}
-
-TEST(QuicheBuffer, CopyFromIovecZeroBytes) {
-  const int buffer_length = 0;
-
-  SimpleBufferAllocator allocator;
-  QuicheBuffer buffer = QuicheBuffer::CopyFromIovec(
-      &allocator, nullptr,
-      /* iov_count = */ 0, /* iov_offset = */ 0, buffer_length);
-  EXPECT_TRUE(buffer.empty());
-
-  constexpr absl::string_view kData("foobar");
-  iovec iov = MakeIOVector(kData);
-
-  buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov,
-                                       /* iov_count = */ 1,
-                                       /* iov_offset = */ 0, buffer_length);
-  EXPECT_TRUE(buffer.empty());
-
-  buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov,
-                                       /* iov_count = */ 1,
-                                       /* iov_offset = */ 3, buffer_length);
-  EXPECT_TRUE(buffer.empty());
-}
-
-TEST(QuicheBuffer, CopyFromIovecSimple) {
-  constexpr absl::string_view kData("foobar");
-  iovec iov = MakeIOVector(kData);
-
-  SimpleBufferAllocator allocator;
-  QuicheBuffer buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov,
-                                  /* iov_count = */ 1, /* iov_offset = */ 0,
-                                  /* buffer_length = */ 6);
-  EXPECT_EQ("foobar", buffer.AsStringView());
-
-  buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov,
-                                  /* iov_count = */ 1, /* iov_offset = */ 0,
-                                  /* buffer_length = */ 3);
-  EXPECT_EQ("foo", buffer.AsStringView());
-
-  buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov,
-                                  /* iov_count = */ 1, /* iov_offset = */ 3,
-                                  /* buffer_length = */ 3);
-  EXPECT_EQ("bar", buffer.AsStringView());
-
-  buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov,
-                                  /* iov_count = */ 1, /* iov_offset = */ 1,
-                                  /* buffer_length = */ 4);
-  EXPECT_EQ("ooba", buffer.AsStringView());
-}
-
-TEST(QuicheBuffer, CopyFromIovecMultiple) {
-  constexpr absl::string_view kData1("foo");
-  constexpr absl::string_view kData2("bar");
-  iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
-
-  SimpleBufferAllocator allocator;
-  QuicheBuffer buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
-                                  /* iov_count = */ 2, /* iov_offset = */ 0,
-                                  /* buffer_length = */ 6);
-  EXPECT_EQ("foobar", buffer.AsStringView());
-
-  buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
-                                  /* iov_count = */ 2, /* iov_offset = */ 0,
-                                  /* buffer_length = */ 3);
-  EXPECT_EQ("foo", buffer.AsStringView());
-
-  buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
-                                  /* iov_count = */ 2, /* iov_offset = */ 3,
-                                  /* buffer_length = */ 3);
-  EXPECT_EQ("bar", buffer.AsStringView());
-
-  buffer =
-      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
-                                  /* iov_count = */ 2, /* iov_offset = */ 1,
-                                  /* buffer_length = */ 4);
-  EXPECT_EQ("ooba", buffer.AsStringView());
-}
-
-TEST(QuicheBuffer, CopyFromIovecOffsetTooLarge) {
-  constexpr absl::string_view kData1("foo");
-  constexpr absl::string_view kData2("bar");
-  iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
-
-  SimpleBufferAllocator allocator;
-  EXPECT_QUICHE_BUG(
-      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
-                                  /* iov_count = */ 2, /* iov_offset = */ 10,
-                                  /* buffer_length = */ 6),
-      "iov_offset larger than iovec total size");
-}
-
-TEST(QuicheBuffer, CopyFromIovecTooManyBytesRequested) {
-  constexpr absl::string_view kData1("foo");
-  constexpr absl::string_view kData2("bar");
-  iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
-
-  SimpleBufferAllocator allocator;
-  EXPECT_QUICHE_BUG(
-      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
-                                  /* iov_count = */ 2, /* iov_offset = */ 2,
-                                  /* buffer_length = */ 10),
-      "iov_offset [+] buffer_length larger than iovec total size");
-}
-
-}  // anonymous namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/quiche_circular_deque.h b/common/quiche_circular_deque.h
deleted file mode 100644
index 42b2232..0000000
--- a/common/quiche_circular_deque.h
+++ /dev/null
@@ -1,759 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_CIRCULAR_DEQUE_H_
-#define QUICHE_COMMON_QUICHE_CIRCULAR_DEQUE_H_
-
-#include <algorithm>
-#include <cstddef>
-#include <cstring>
-#include <iterator>
-#include <memory>
-#include <ostream>
-#include <type_traits>
-
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-
-// QuicheCircularDeque is a STL-style container that is similar to std::deque in
-// API and std::vector in capacity management. The goal is to optimize a common
-// QUIC use case where we keep adding new elements to the end and removing old
-// elements from the beginning, under such scenarios, if the container's size()
-// remain relatively stable, QuicheCircularDeque requires little to no memory
-// allocations or deallocations.
-//
-// The implementation, as the name suggests, uses a flat circular buffer to hold
-// all elements. At any point in time, either
-// a) All elements are placed in a contiguous portion of this buffer, like a
-//    c-array, or
-// b) Elements are phycially divided into two parts: the first part occupies the
-//    end of the buffer and the second part occupies the beginning of the
-//    buffer.
-//
-// Currently, elements can only be pushed or poped from either ends, it can't be
-// inserted or erased in the middle.
-//
-// TODO(wub): Make memory grow/shrink strategies customizable.
-template <typename T,
-          size_t MinCapacityIncrement = 3,
-          typename Allocator = std::allocator<T>>
-class QUICHE_NO_EXPORT QuicheCircularDeque {
-  using AllocatorTraits = std::allocator_traits<Allocator>;
-
-  // Pointee is either T or const T.
-  template <typename Pointee>
-  class QUICHE_NO_EXPORT basic_iterator {
-    using size_type = typename AllocatorTraits::size_type;
-
-   public:
-    using iterator_category = std::random_access_iterator_tag;
-    using value_type = typename AllocatorTraits::value_type;
-    using difference_type = typename AllocatorTraits::difference_type;
-    using pointer = Pointee*;
-    using reference = Pointee&;
-
-    basic_iterator() = default;
-
-    // A copy constructor if Pointee is T.
-    // A conversion from iterator to const_iterator if Pointee is const T.
-    basic_iterator(
-        const basic_iterator<value_type>& it)  // NOLINT(runtime/explicit)
-        : deque_(it.deque_), index_(it.index_) {}
-
-    // A copy assignment if Pointee is T.
-    // A assignment from iterator to const_iterator if Pointee is const T.
-    basic_iterator& operator=(const basic_iterator<value_type>& it) {
-      if (this != &it) {
-        deque_ = it.deque_;
-        index_ = it.index_;
-      }
-      return *this;
-    }
-
-    reference operator*() const { return *deque_->index_to_address(index_); }
-    pointer operator->() const { return deque_->index_to_address(index_); }
-    reference operator[](difference_type i) { return *(*this + i); }
-
-    basic_iterator& operator++() {
-      Increment();
-      return *this;
-    }
-
-    basic_iterator operator++(int) {
-      basic_iterator result = *this;
-      Increment();
-      return result;
-    }
-
-    basic_iterator operator--() {
-      Decrement();
-      return *this;
-    }
-
-    basic_iterator operator--(int) {
-      basic_iterator result = *this;
-      Decrement();
-      return result;
-    }
-
-    friend basic_iterator operator+(const basic_iterator& it,
-                                    difference_type delta) {
-      basic_iterator result = it;
-      result.IncrementBy(delta);
-      return result;
-    }
-
-    basic_iterator& operator+=(difference_type delta) {
-      IncrementBy(delta);
-      return *this;
-    }
-
-    friend basic_iterator operator-(const basic_iterator& it,
-                                    difference_type delta) {
-      basic_iterator result = it;
-      result.IncrementBy(-delta);
-      return result;
-    }
-
-    basic_iterator& operator-=(difference_type delta) {
-      IncrementBy(-delta);
-      return *this;
-    }
-
-    friend difference_type operator-(const basic_iterator& lhs,
-                                     const basic_iterator& rhs) {
-      return lhs.ExternalPosition() - rhs.ExternalPosition();
-    }
-
-    friend bool operator==(const basic_iterator& lhs,
-                           const basic_iterator& rhs) {
-      return lhs.index_ == rhs.index_;
-    }
-
-    friend bool operator!=(const basic_iterator& lhs,
-                           const basic_iterator& rhs) {
-      return !(lhs == rhs);
-    }
-
-    friend bool operator<(const basic_iterator& lhs,
-                          const basic_iterator& rhs) {
-      return lhs.ExternalPosition() < rhs.ExternalPosition();
-    }
-
-    friend bool operator<=(const basic_iterator& lhs,
-                           const basic_iterator& rhs) {
-      return !(lhs > rhs);
-    }
-
-    friend bool operator>(const basic_iterator& lhs,
-                          const basic_iterator& rhs) {
-      return lhs.ExternalPosition() > rhs.ExternalPosition();
-    }
-
-    friend bool operator>=(const basic_iterator& lhs,
-                           const basic_iterator& rhs) {
-      return !(lhs < rhs);
-    }
-
-   private:
-    basic_iterator(const QuicheCircularDeque* deque, size_type index)
-        : deque_(deque), index_(index) {}
-
-    void Increment() {
-      QUICHE_DCHECK_LE(ExternalPosition() + 1, deque_->size());
-      index_ = deque_->index_next(index_);
-    }
-
-    void Decrement() {
-      QUICHE_DCHECK_GE(ExternalPosition(), 1u);
-      index_ = deque_->index_prev(index_);
-    }
-
-    void IncrementBy(difference_type delta) {
-      if (delta >= 0) {
-        // After increment we are before or at end().
-        QUICHE_DCHECK_LE(static_cast<size_type>(ExternalPosition() + delta),
-                         deque_->size());
-      } else {
-        // After decrement we are after or at begin().
-        QUICHE_DCHECK_GE(ExternalPosition(), static_cast<size_type>(-delta));
-      }
-      index_ = deque_->index_increment_by(index_, delta);
-    }
-
-    size_type ExternalPosition() const {
-      if (index_ >= deque_->begin_) {
-        return index_ - deque_->begin_;
-      }
-      return index_ + deque_->data_capacity() - deque_->begin_;
-    }
-
-    friend class QuicheCircularDeque;
-    const QuicheCircularDeque* deque_ = nullptr;
-    size_type index_ = 0;
-  };
-
- public:
-  using allocator_type = typename AllocatorTraits::allocator_type;
-  using value_type = typename AllocatorTraits::value_type;
-  using size_type = typename AllocatorTraits::size_type;
-  using difference_type = typename AllocatorTraits::difference_type;
-  using reference = value_type&;
-  using const_reference = const value_type&;
-  using pointer = typename AllocatorTraits::pointer;
-  using const_pointer = typename AllocatorTraits::const_pointer;
-  using iterator = basic_iterator<T>;
-  using const_iterator = basic_iterator<const T>;
-  using reverse_iterator = std::reverse_iterator<iterator>;
-  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
-  QuicheCircularDeque() : QuicheCircularDeque(allocator_type()) {}
-  explicit QuicheCircularDeque(const allocator_type& alloc)
-      : allocator_and_data_(alloc) {}
-
-  QuicheCircularDeque(size_type count,
-                      const T& value,
-                      const Allocator& alloc = allocator_type())
-      : allocator_and_data_(alloc) {
-    resize(count, value);
-  }
-
-  explicit QuicheCircularDeque(size_type count,
-                               const Allocator& alloc = allocator_type())
-      : allocator_and_data_(alloc) {
-    resize(count);
-  }
-
-  template <
-      class InputIt,
-      typename = std::enable_if_t<std::is_base_of<
-          std::input_iterator_tag,
-          typename std::iterator_traits<InputIt>::iterator_category>::value>>
-  QuicheCircularDeque(InputIt first,
-                      InputIt last,
-                      const Allocator& alloc = allocator_type())
-      : allocator_and_data_(alloc) {
-    AssignRange(first, last);
-  }
-
-  QuicheCircularDeque(const QuicheCircularDeque& other)
-      : QuicheCircularDeque(
-            other,
-            AllocatorTraits::select_on_container_copy_construction(
-                other.allocator_and_data_.allocator())) {}
-
-  QuicheCircularDeque(const QuicheCircularDeque& other,
-                      const allocator_type& alloc)
-      : allocator_and_data_(alloc) {
-    assign(other.begin(), other.end());
-  }
-
-  QuicheCircularDeque(QuicheCircularDeque&& other)
-      : begin_(other.begin_),
-        end_(other.end_),
-        allocator_and_data_(std::move(other.allocator_and_data_)) {
-    other.begin_ = other.end_ = 0;
-    other.allocator_and_data_.data = nullptr;
-    other.allocator_and_data_.data_capacity = 0;
-  }
-
-  QuicheCircularDeque(QuicheCircularDeque&& other, const allocator_type& alloc)
-      : allocator_and_data_(alloc) {
-    MoveRetainAllocator(std::move(other));
-  }
-
-  QuicheCircularDeque(std::initializer_list<T> init,
-                      const allocator_type& alloc = allocator_type())
-      : QuicheCircularDeque(init.begin(), init.end(), alloc) {}
-
-  QuicheCircularDeque& operator=(const QuicheCircularDeque& other) {
-    if (this == &other) {
-      return *this;
-    }
-    if (AllocatorTraits::propagate_on_container_copy_assignment::value &&
-        (allocator_and_data_.allocator() !=
-         other.allocator_and_data_.allocator())) {
-      // Destroy all current elements and blocks with the current allocator,
-      // before switching this to use the allocator propagated from "other".
-      DestroyAndDeallocateAll();
-      begin_ = end_ = 0;
-      allocator_and_data_ =
-          AllocatorAndData(other.allocator_and_data_.allocator());
-    }
-    assign(other.begin(), other.end());
-    return *this;
-  }
-
-  QuicheCircularDeque& operator=(QuicheCircularDeque&& other) {
-    if (this == &other) {
-      return *this;
-    }
-    if (AllocatorTraits::propagate_on_container_move_assignment::value) {
-      // Take over the storage of "other", along with its allocator.
-      this->~QuicheCircularDeque();
-      new (this) QuicheCircularDeque(std::move(other));
-    } else {
-      MoveRetainAllocator(std::move(other));
-    }
-    return *this;
-  }
-
-  ~QuicheCircularDeque() { DestroyAndDeallocateAll(); }
-
-  void assign(size_type count, const T& value) {
-    ClearRetainCapacity();
-    reserve(count);
-    for (size_t i = 0; i < count; ++i) {
-      emplace_back(value);
-    }
-  }
-
-  template <
-      class InputIt,
-      typename = std::enable_if_t<std::is_base_of<
-          std::input_iterator_tag,
-          typename std::iterator_traits<InputIt>::iterator_category>::value>>
-  void assign(InputIt first, InputIt last) {
-    AssignRange(first, last);
-  }
-
-  void assign(std::initializer_list<T> ilist) {
-    assign(ilist.begin(), ilist.end());
-  }
-
-  reference at(size_type pos) {
-    QUICHE_DCHECK(pos < size()) << "pos:" << pos << ", size():" << size();
-    size_type index = begin_ + pos;
-    if (index < data_capacity()) {
-      return *index_to_address(index);
-    }
-    return *index_to_address(index - data_capacity());
-  }
-
-  const_reference at(size_type pos) const {
-    return const_cast<QuicheCircularDeque*>(this)->at(pos);
-  }
-
-  reference operator[](size_type pos) { return at(pos); }
-
-  const_reference operator[](size_type pos) const { return at(pos); }
-
-  reference front() {
-    QUICHE_DCHECK(!empty());
-    return *index_to_address(begin_);
-  }
-
-  const_reference front() const {
-    return const_cast<QuicheCircularDeque*>(this)->front();
-  }
-
-  reference back() {
-    QUICHE_DCHECK(!empty());
-    return *(index_to_address(end_ == 0 ? data_capacity() - 1 : end_ - 1));
-  }
-
-  const_reference back() const {
-    return const_cast<QuicheCircularDeque*>(this)->back();
-  }
-
-  iterator begin() { return iterator(this, begin_); }
-  const_iterator begin() const { return const_iterator(this, begin_); }
-  const_iterator cbegin() const { return const_iterator(this, begin_); }
-
-  iterator end() { return iterator(this, end_); }
-  const_iterator end() const { return const_iterator(this, end_); }
-  const_iterator cend() const { return const_iterator(this, end_); }
-
-  reverse_iterator rbegin() { return reverse_iterator(end()); }
-  const_reverse_iterator rbegin() const {
-    return const_reverse_iterator(end());
-  }
-  const_reverse_iterator crbegin() const { return rbegin(); }
-
-  reverse_iterator rend() { return reverse_iterator(begin()); }
-  const_reverse_iterator rend() const {
-    return const_reverse_iterator(begin());
-  }
-  const_reverse_iterator crend() const { return rend(); }
-
-  size_type capacity() const {
-    return data_capacity() == 0 ? 0 : data_capacity() - 1;
-  }
-
-  void reserve(size_type new_cap) {
-    if (new_cap > capacity()) {
-      Relocate(new_cap);
-    }
-  }
-
-  // Remove all elements. Leave capacity unchanged.
-  void clear() { ClearRetainCapacity(); }
-
-  bool empty() const { return begin_ == end_; }
-
-  size_type size() const {
-    if (begin_ <= end_) {
-      return end_ - begin_;
-    }
-    return data_capacity() + end_ - begin_;
-  }
-
-  void resize(size_type count) { ResizeInternal(count); }
-
-  void resize(size_type count, const value_type& value) {
-    ResizeInternal(count, value);
-  }
-
-  void push_front(const T& value) { emplace_front(value); }
-  void push_front(T&& value) { emplace_front(std::move(value)); }
-
-  template <class... Args>
-  reference emplace_front(Args&&... args) {
-    MaybeExpandCapacity(1);
-    begin_ = index_prev(begin_);
-    new (index_to_address(begin_)) T(std::forward<Args>(args)...);
-    return front();
-  }
-
-  void push_back(const T& value) { emplace_back(value); }
-  void push_back(T&& value) { emplace_back(std::move(value)); }
-
-  template <class... Args>
-  reference emplace_back(Args&&... args) {
-    MaybeExpandCapacity(1);
-    new (index_to_address(end_)) T(std::forward<Args>(args)...);
-    end_ = index_next(end_);
-    return back();
-  }
-
-  void pop_front() {
-    QUICHE_DCHECK(!empty());
-    DestroyByIndex(begin_);
-    begin_ = index_next(begin_);
-    MaybeShrinkCapacity();
-  }
-
-  size_type pop_front_n(size_type count) {
-    size_type num_elements_to_pop = std::min(count, size());
-    size_type new_begin = index_increment_by(begin_, num_elements_to_pop);
-    DestroyRange(begin_, new_begin);
-    begin_ = new_begin;
-    MaybeShrinkCapacity();
-    return num_elements_to_pop;
-  }
-
-  void pop_back() {
-    QUICHE_DCHECK(!empty());
-    end_ = index_prev(end_);
-    DestroyByIndex(end_);
-    MaybeShrinkCapacity();
-  }
-
-  size_type pop_back_n(size_type count) {
-    size_type num_elements_to_pop = std::min(count, size());
-    size_type new_end = index_increment_by(end_, -num_elements_to_pop);
-    DestroyRange(new_end, end_);
-    end_ = new_end;
-    MaybeShrinkCapacity();
-    return num_elements_to_pop;
-  }
-
-  void swap(QuicheCircularDeque& other) {
-    using std::swap;
-    swap(begin_, other.begin_);
-    swap(end_, other.end_);
-
-    if (AllocatorTraits::propagate_on_container_swap::value) {
-      swap(allocator_and_data_, other.allocator_and_data_);
-    } else {
-      // When propagate_on_container_swap is false, it is undefined behavior, by
-      // c++ standard, to swap between two AllocatorAwareContainer(s) with
-      // unequal allocators.
-      QUICHE_DCHECK(get_allocator() == other.get_allocator())
-          << "Undefined swap behavior";
-      swap(allocator_and_data_.data, other.allocator_and_data_.data);
-      swap(allocator_and_data_.data_capacity,
-           other.allocator_and_data_.data_capacity);
-    }
-  }
-
-  friend void swap(QuicheCircularDeque& lhs, QuicheCircularDeque& rhs) {
-    lhs.swap(rhs);
-  }
-
-  allocator_type get_allocator() const {
-    return allocator_and_data_.allocator();
-  }
-
-  friend bool operator==(const QuicheCircularDeque& lhs,
-                         const QuicheCircularDeque& rhs) {
-    return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
-  }
-
-  friend bool operator!=(const QuicheCircularDeque& lhs,
-                         const QuicheCircularDeque& rhs) {
-    return !(lhs == rhs);
-  }
-
-  friend QUICHE_NO_EXPORT std::ostream& operator<<(
-      std::ostream& os,
-      const QuicheCircularDeque& dq) {
-    os << "{";
-    for (size_type pos = 0; pos != dq.size(); ++pos) {
-      if (pos != 0) {
-        os << ",";
-      }
-      os << " " << dq[pos];
-    }
-    os << " }";
-    return os;
-  }
-
- private:
-  void MoveRetainAllocator(QuicheCircularDeque&& other) {
-    if (get_allocator() == other.get_allocator()) {
-      // Take over the storage of "other", with which we share an allocator.
-      DestroyAndDeallocateAll();
-
-      begin_ = other.begin_;
-      end_ = other.end_;
-      allocator_and_data_.data = other.allocator_and_data_.data;
-      allocator_and_data_.data_capacity =
-          other.allocator_and_data_.data_capacity;
-
-      other.begin_ = other.end_ = 0;
-      other.allocator_and_data_.data = nullptr;
-      other.allocator_and_data_.data_capacity = 0;
-    } else {
-      // We cannot take over of the storage from "other", since it has a
-      // different allocator; we're stuck move-assigning elements individually.
-      ClearRetainCapacity();
-      for (auto& elem : other) {
-        push_back(std::move(elem));
-      }
-      other.clear();
-    }
-  }
-
-  template <
-      typename InputIt,
-      typename = std::enable_if_t<std::is_base_of<
-          std::input_iterator_tag,
-          typename std::iterator_traits<InputIt>::iterator_category>::value>>
-  void AssignRange(InputIt first, InputIt last) {
-    ClearRetainCapacity();
-    if (std::is_base_of<
-            std::random_access_iterator_tag,
-            typename std::iterator_traits<InputIt>::iterator_category>::value) {
-      reserve(std::distance(first, last));
-    }
-    for (; first != last; ++first) {
-      emplace_back(*first);
-    }
-  }
-
-  // WARNING: begin_, end_ and allocator_and_data_ are not modified.
-  void DestroyAndDeallocateAll() {
-    DestroyRange(begin_, end_);
-
-    if (data_capacity() > 0) {
-      QUICHE_DCHECK_NE(nullptr, allocator_and_data_.data);
-      AllocatorTraits::deallocate(allocator_and_data_.allocator(),
-                                  allocator_and_data_.data, data_capacity());
-    }
-  }
-
-  void ClearRetainCapacity() {
-    DestroyRange(begin_, end_);
-    begin_ = end_ = 0;
-  }
-
-  void MaybeShrinkCapacity() {
-    // TODO(wub): Implement a storage policy that actually shrinks.
-  }
-
-  void MaybeExpandCapacity(size_t num_additional_elements) {
-    size_t new_size = size() + num_additional_elements;
-    if (capacity() >= new_size) {
-      return;
-    }
-
-    // The minimum amount of additional capacity to grow.
-    size_t min_additional_capacity =
-        std::max(MinCapacityIncrement, capacity() / 4);
-    size_t new_capacity =
-        std::max(new_size, capacity() + min_additional_capacity);
-
-    Relocate(new_capacity);
-  }
-
-  void Relocate(size_t new_capacity) {
-    const size_t num_elements = size();
-    QUICHE_DCHECK_GT(new_capacity, num_elements)
-        << "new_capacity:" << new_capacity << ", num_elements:" << num_elements;
-
-    size_t new_data_capacity = new_capacity + 1;
-    pointer new_data = AllocatorTraits::allocate(
-        allocator_and_data_.allocator(), new_data_capacity);
-
-    if (begin_ < end_) {
-      // Not wrapped.
-      RelocateUnwrappedRange(begin_, end_, new_data);
-    } else if (begin_ > end_) {
-      // Wrapped.
-      const size_t num_elements_before_wrap = data_capacity() - begin_;
-      RelocateUnwrappedRange(begin_, data_capacity(), new_data);
-      RelocateUnwrappedRange(0, end_, new_data + num_elements_before_wrap);
-    }
-
-    if (data_capacity()) {
-      AllocatorTraits::deallocate(allocator_and_data_.allocator(),
-                                  allocator_and_data_.data, data_capacity());
-    }
-
-    allocator_and_data_.data = new_data;
-    allocator_and_data_.data_capacity = new_data_capacity;
-    begin_ = 0;
-    end_ = num_elements;
-  }
-
-  template <typename T_ = T>
-  typename std::enable_if<std::is_trivially_copyable<T_>::value, void>::type
-  RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const {
-    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
-    pointer src = index_to_address(begin);
-    QUICHE_DCHECK_NE(src, nullptr);
-    memcpy(dest, src, sizeof(T) * (end - begin));
-    DestroyRange(begin, end);
-  }
-
-  template <typename T_ = T>
-  typename std::enable_if<!std::is_trivially_copyable<T_>::value &&
-                              std::is_move_constructible<T_>::value,
-                          void>::type
-  RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const {
-    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
-    pointer src = index_to_address(begin);
-    pointer src_end = index_to_address(end);
-    while (src != src_end) {
-      new (dest) T(std::move(*src));
-      DestroyByAddress(src);
-      ++dest;
-      ++src;
-    }
-  }
-
-  template <typename T_ = T>
-  typename std::enable_if<!std::is_trivially_copyable<T_>::value &&
-                              !std::is_move_constructible<T_>::value,
-                          void>::type
-  RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const {
-    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
-    pointer src = index_to_address(begin);
-    pointer src_end = index_to_address(end);
-    while (src != src_end) {
-      new (dest) T(*src);
-      DestroyByAddress(src);
-      ++dest;
-      ++src;
-    }
-  }
-
-  template <class... U>
-  void ResizeInternal(size_type count, U&&... u) {
-    if (count > size()) {
-      // Expanding.
-      MaybeExpandCapacity(count - size());
-      while (size() < count) {
-        emplace_back(std::forward<U>(u)...);
-      }
-    } else {
-      // Most likely shrinking. No-op if count == size().
-      size_type new_end = (begin_ + count) % data_capacity();
-      DestroyRange(new_end, end_);
-      end_ = new_end;
-
-      MaybeShrinkCapacity();
-    }
-  }
-
-  void DestroyRange(size_type begin, size_type end) const {
-    if (std::is_trivially_destructible<T>::value) {
-      return;
-    }
-    if (end >= begin) {
-      DestroyUnwrappedRange(begin, end);
-    } else {
-      DestroyUnwrappedRange(begin, data_capacity());
-      DestroyUnwrappedRange(0, end);
-    }
-  }
-
-  // Should only be called from DestroyRange.
-  void DestroyUnwrappedRange(size_type begin, size_type end) const {
-    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
-    for (; begin != end; ++begin) {
-      DestroyByIndex(begin);
-    }
-  }
-
-  void DestroyByIndex(size_type index) const {
-    DestroyByAddress(index_to_address(index));
-  }
-
-  void DestroyByAddress(pointer address) const {
-    if (std::is_trivially_destructible<T>::value) {
-      return;
-    }
-    address->~T();
-  }
-
-  size_type data_capacity() const { return allocator_and_data_.data_capacity; }
-
-  pointer index_to_address(size_type index) const {
-    return allocator_and_data_.data + index;
-  }
-
-  size_type index_prev(size_type index) const {
-    return index == 0 ? data_capacity() - 1 : index - 1;
-  }
-
-  size_type index_next(size_type index) const {
-    return index == data_capacity() - 1 ? 0 : index + 1;
-  }
-
-  size_type index_increment_by(size_type index, difference_type delta) const {
-    if (delta == 0) {
-      return index;
-    }
-
-    QUICHE_DCHECK_LT(static_cast<size_type>(std::abs(delta)), data_capacity());
-    return (index + data_capacity() + delta) % data_capacity();
-  }
-
-  // Empty base-class optimization: bundle storage for our allocator together
-  // with the fields we had to store anyway, via inheriting from the allocator,
-  // so this allocator instance doesn't consume any storage when its type has no
-  // data members.
-  struct AllocatorAndData : private allocator_type {
-    explicit AllocatorAndData(const allocator_type& alloc)
-        : allocator_type(alloc) {}
-
-    const allocator_type& allocator() const { return *this; }
-    allocator_type& allocator() { return *this; }
-
-    pointer data = nullptr;
-    size_type data_capacity = 0;
-  };
-
-  size_type begin_ = 0;
-  size_type end_ = 0;
-  AllocatorAndData allocator_and_data_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_CIRCULAR_DEQUE_H_
diff --git a/common/quiche_circular_deque_test.cc b/common/quiche_circular_deque_test.cc
deleted file mode 100644
index c15d904..0000000
--- a/common/quiche_circular_deque_test.cc
+++ /dev/null
@@ -1,801 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_circular_deque.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <memory>
-#include <type_traits>
-
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-using testing::ElementsAre;
-
-namespace quiche {
-namespace test {
-namespace {
-
-template <typename T, template <typename> class BaseAllocator = std::allocator>
-class CountingAllocator : public BaseAllocator<T> {
-  using BaseType = BaseAllocator<T>;
-
- public:
-  using propagate_on_container_copy_assignment = std::true_type;
-  using propagate_on_container_move_assignment = std::true_type;
-  using propagate_on_container_swap = std::true_type;
-
-  T* allocate(std::size_t n) {
-    ++shared_counts_->allocate_count;
-    return BaseType::allocate(n);
-  }
-
-  void deallocate(T* ptr, std::size_t n) {
-    ++shared_counts_->deallocate_count;
-    return BaseType::deallocate(ptr, n);
-  }
-
-  size_t allocate_count() const { return shared_counts_->allocate_count; }
-
-  size_t deallocate_count() const { return shared_counts_->deallocate_count; }
-
-  friend bool operator==(const CountingAllocator& lhs,
-                         const CountingAllocator& rhs) {
-    return lhs.shared_counts_ == rhs.shared_counts_;
-  }
-
-  friend bool operator!=(const CountingAllocator& lhs,
-                         const CountingAllocator& rhs) {
-    return !(lhs == rhs);
-  }
-
- private:
-  struct Counts {
-    size_t allocate_count = 0;
-    size_t deallocate_count = 0;
-  };
-
-  std::shared_ptr<Counts> shared_counts_ = std::make_shared<Counts>();
-};
-
-template <typename T,
-          typename propagate_on_copy_assignment,
-          typename propagate_on_move_assignment,
-          typename propagate_on_swap,
-          bool equality_result,
-          template <typename> class BaseAllocator = std::allocator>
-struct ConfigurableAllocator : public BaseAllocator<T> {
-  using propagate_on_container_copy_assignment = propagate_on_copy_assignment;
-  using propagate_on_container_move_assignment = propagate_on_move_assignment;
-  using propagate_on_container_swap = propagate_on_swap;
-
-  friend bool operator==(const ConfigurableAllocator& /*lhs*/,
-                         const ConfigurableAllocator& /*rhs*/) {
-    return equality_result;
-  }
-
-  friend bool operator!=(const ConfigurableAllocator& lhs,
-                         const ConfigurableAllocator& rhs) {
-    return !(lhs == rhs);
-  }
-};
-
-// [1, 2, 3, 4] ==> [4, 1, 2, 3]
-template <typename Deque>
-void ShiftRight(Deque* dq, bool emplace) {
-  auto back = *(&dq->back());
-  dq->pop_back();
-  if (emplace) {
-    dq->emplace_front(back);
-  } else {
-    dq->push_front(back);
-  }
-}
-
-// [1, 2, 3, 4] ==> [2, 3, 4, 1]
-template <typename Deque>
-void ShiftLeft(Deque* dq, bool emplace) {
-  auto front = *(&dq->front());
-  dq->pop_front();
-  if (emplace) {
-    dq->emplace_back(front);
-  } else {
-    dq->push_back(front);
-  }
-}
-
-class QuicheCircularDequeTest : public QuicheTest {};
-
-TEST_F(QuicheCircularDequeTest, Empty) {
-  QuicheCircularDeque<int> dq;
-  EXPECT_TRUE(dq.empty());
-  EXPECT_EQ(0u, dq.size());
-  dq.clear();
-  dq.push_back(10);
-  EXPECT_FALSE(dq.empty());
-  EXPECT_EQ(1u, dq.size());
-  EXPECT_EQ(10, dq.front());
-  EXPECT_EQ(10, dq.back());
-  dq.pop_front();
-  EXPECT_TRUE(dq.empty());
-  EXPECT_EQ(0u, dq.size());
-
-  EXPECT_QUICHE_DEBUG_DEATH(dq.front(), "");
-  EXPECT_QUICHE_DEBUG_DEATH(dq.back(), "");
-  EXPECT_QUICHE_DEBUG_DEATH(dq.at(0), "");
-  EXPECT_QUICHE_DEBUG_DEATH(dq[0], "");
-}
-
-TEST_F(QuicheCircularDequeTest, Constructor) {
-  QuicheCircularDeque<int> dq;
-  EXPECT_TRUE(dq.empty());
-
-  std::allocator<int> alloc;
-  QuicheCircularDeque<int> dq1(alloc);
-  EXPECT_TRUE(dq1.empty());
-
-  QuicheCircularDeque<int> dq2(8, 100, alloc);
-  EXPECT_THAT(dq2, ElementsAre(100, 100, 100, 100, 100, 100, 100, 100));
-
-  QuicheCircularDeque<int> dq3(5, alloc);
-  EXPECT_THAT(dq3, ElementsAre(0, 0, 0, 0, 0));
-
-  QuicheCircularDeque<int> dq4_rand_iter(dq3.begin(), dq3.end(), alloc);
-  EXPECT_THAT(dq4_rand_iter, ElementsAre(0, 0, 0, 0, 0));
-  EXPECT_EQ(dq4_rand_iter, dq3);
-
-  std::list<int> dq4_src = {4, 4, 4, 4};
-  QuicheCircularDeque<int> dq4_bidi_iter(dq4_src.begin(), dq4_src.end());
-  EXPECT_THAT(dq4_bidi_iter, ElementsAre(4, 4, 4, 4));
-
-  QuicheCircularDeque<int> dq5(dq4_bidi_iter);
-  EXPECT_THAT(dq5, ElementsAre(4, 4, 4, 4));
-  EXPECT_EQ(dq5, dq4_bidi_iter);
-
-  QuicheCircularDeque<int> dq6(dq5, alloc);
-  EXPECT_THAT(dq6, ElementsAre(4, 4, 4, 4));
-  EXPECT_EQ(dq6, dq5);
-
-  QuicheCircularDeque<int> dq7(std::move(*&dq6));
-  EXPECT_THAT(dq7, ElementsAre(4, 4, 4, 4));
-  EXPECT_TRUE(dq6.empty());
-
-  QuicheCircularDeque<int> dq8_equal_allocator(std::move(*&dq7), alloc);
-  EXPECT_THAT(dq8_equal_allocator, ElementsAre(4, 4, 4, 4));
-  EXPECT_TRUE(dq7.empty());
-
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq8_temp = {5, 6, 7, 8,
-                                                                  9};
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq8_unequal_allocator(
-      std::move(*&dq8_temp), CountingAllocator<int>());
-  EXPECT_THAT(dq8_unequal_allocator, ElementsAre(5, 6, 7, 8, 9));
-  EXPECT_TRUE(dq8_temp.empty());
-
-  QuicheCircularDeque<int> dq9({3, 4, 5, 6, 7}, alloc);
-  EXPECT_THAT(dq9, ElementsAre(3, 4, 5, 6, 7));
-}
-
-TEST_F(QuicheCircularDequeTest, Assign) {
-  // assign()
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq;
-  dq.assign(7, 1);
-  EXPECT_THAT(dq, ElementsAre(1, 1, 1, 1, 1, 1, 1));
-  EXPECT_EQ(1u, dq.get_allocator().allocate_count());
-
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq2;
-  dq2.assign(dq.begin(), dq.end());
-  EXPECT_THAT(dq2, ElementsAre(1, 1, 1, 1, 1, 1, 1));
-  EXPECT_EQ(1u, dq2.get_allocator().allocate_count());
-  EXPECT_TRUE(std::equal(dq.begin(), dq.end(), dq2.begin(), dq2.end()));
-
-  dq2.assign({2, 2, 2, 2, 2, 2});
-  EXPECT_THAT(dq2, ElementsAre(2, 2, 2, 2, 2, 2));
-
-  // Assign from a non random access iterator.
-  std::list<int> dq3_src = {3, 3, 3, 3, 3};
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq3;
-  dq3.assign(dq3_src.begin(), dq3_src.end());
-  EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3));
-  EXPECT_LT(1u, dq3.get_allocator().allocate_count());
-
-  // Copy assignment
-  dq3 = *&dq3;
-  EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3));
-
-  QuicheCircularDeque<
-      int, 3,
-      ConfigurableAllocator<int,
-                            /*propagate_on_copy_assignment=*/std::true_type,
-                            /*propagate_on_move_assignment=*/std::true_type,
-                            /*propagate_on_swap=*/std::true_type,
-                            /*equality_result=*/false>>
-      dq4, dq5;
-  dq4.assign(dq3.begin(), dq3.end());
-  dq5 = dq4;
-  EXPECT_THAT(dq5, ElementsAre(3, 3, 3, 3, 3));
-
-  QuicheCircularDeque<
-      int, 3,
-      ConfigurableAllocator<int,
-                            /*propagate_on_copy_assignment=*/std::false_type,
-                            /*propagate_on_move_assignment=*/std::true_type,
-                            /*propagate_on_swap=*/std::true_type,
-                            /*equality_result=*/true>>
-      dq6, dq7;
-  dq6.assign(dq3.begin(), dq3.end());
-  dq7 = dq6;
-  EXPECT_THAT(dq7, ElementsAre(3, 3, 3, 3, 3));
-
-  // Move assignment
-  dq3 = std::move(*&dq3);
-  EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3));
-
-  ASSERT_TRUE(decltype(
-      dq3.get_allocator())::propagate_on_container_move_assignment::value);
-  decltype(dq3) dq8;
-  dq8 = std::move(*&dq3);
-  EXPECT_THAT(dq8, ElementsAre(3, 3, 3, 3, 3));
-  EXPECT_TRUE(dq3.empty());
-
-  QuicheCircularDeque<
-      int, 3,
-      ConfigurableAllocator<int,
-                            /*propagate_on_copy_assignment=*/std::true_type,
-                            /*propagate_on_move_assignment=*/std::false_type,
-                            /*propagate_on_swap=*/std::true_type,
-                            /*equality_result=*/true>>
-      dq9, dq10;
-  dq9.assign(dq8.begin(), dq8.end());
-  dq10.assign(dq2.begin(), dq2.end());
-  dq9 = std::move(*&dq10);
-  EXPECT_THAT(dq9, ElementsAre(2, 2, 2, 2, 2, 2));
-  EXPECT_TRUE(dq10.empty());
-
-  QuicheCircularDeque<
-      int, 3,
-      ConfigurableAllocator<int,
-                            /*propagate_on_copy_assignment=*/std::true_type,
-                            /*propagate_on_move_assignment=*/std::false_type,
-                            /*propagate_on_swap=*/std::true_type,
-                            /*equality_result=*/false>>
-      dq11, dq12;
-  dq11.assign(dq8.begin(), dq8.end());
-  dq12.assign(dq2.begin(), dq2.end());
-  dq11 = std::move(*&dq12);
-  EXPECT_THAT(dq11, ElementsAre(2, 2, 2, 2, 2, 2));
-  EXPECT_TRUE(dq12.empty());
-}
-
-TEST_F(QuicheCircularDequeTest, Access) {
-  // at()
-  // operator[]
-  // front()
-  // back()
-
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq;
-  dq.push_back(10);
-  EXPECT_EQ(dq.front(), 10);
-  EXPECT_EQ(dq.back(), 10);
-  EXPECT_EQ(dq.at(0), 10);
-  EXPECT_EQ(dq[0], 10);
-  dq.front() = 12;
-  EXPECT_EQ(dq.front(), 12);
-  EXPECT_EQ(dq.back(), 12);
-  EXPECT_EQ(dq.at(0), 12);
-  EXPECT_EQ(dq[0], 12);
-
-  const auto& dqref = dq;
-  EXPECT_EQ(dqref.front(), 12);
-  EXPECT_EQ(dqref.back(), 12);
-  EXPECT_EQ(dqref.at(0), 12);
-  EXPECT_EQ(dqref[0], 12);
-
-  dq.pop_front();
-  EXPECT_TRUE(dqref.empty());
-
-  // Push to capacity.
-  dq.push_back(15);
-  dq.push_front(5);
-  dq.push_back(25);
-  EXPECT_EQ(dq.size(), dq.capacity());
-  EXPECT_THAT(dq, ElementsAre(5, 15, 25));
-  EXPECT_LT(&dq.front(), &dq.back());
-  EXPECT_EQ(dq.front(), 5);
-  EXPECT_EQ(dq.back(), 25);
-  EXPECT_EQ(dq.at(0), 5);
-  EXPECT_EQ(dq.at(1), 15);
-  EXPECT_EQ(dq.at(2), 25);
-  EXPECT_EQ(dq[0], 5);
-  EXPECT_EQ(dq[1], 15);
-  EXPECT_EQ(dq[2], 25);
-
-  // Shift right such that begin=1 and end=0. Data is still not wrapped.
-  dq.pop_front();
-  dq.push_back(35);
-  EXPECT_THAT(dq, ElementsAre(15, 25, 35));
-  EXPECT_LT(&dq.front(), &dq.back());
-  EXPECT_EQ(dq.front(), 15);
-  EXPECT_EQ(dq.back(), 35);
-  EXPECT_EQ(dq.at(0), 15);
-  EXPECT_EQ(dq.at(1), 25);
-  EXPECT_EQ(dq.at(2), 35);
-  EXPECT_EQ(dq[0], 15);
-  EXPECT_EQ(dq[1], 25);
-  EXPECT_EQ(dq[2], 35);
-
-  // Shift right such that data is wrapped.
-  dq.pop_front();
-  dq.push_back(45);
-  EXPECT_THAT(dq, ElementsAre(25, 35, 45));
-  EXPECT_GT(&dq.front(), &dq.back());
-  EXPECT_EQ(dq.front(), 25);
-  EXPECT_EQ(dq.back(), 45);
-  EXPECT_EQ(dq.at(0), 25);
-  EXPECT_EQ(dq.at(1), 35);
-  EXPECT_EQ(dq.at(2), 45);
-  EXPECT_EQ(dq[0], 25);
-  EXPECT_EQ(dq[1], 35);
-  EXPECT_EQ(dq[2], 45);
-
-  // Shift right again, data is still wrapped.
-  dq.pop_front();
-  dq.push_back(55);
-  EXPECT_THAT(dq, ElementsAre(35, 45, 55));
-  EXPECT_GT(&dq.front(), &dq.back());
-  EXPECT_EQ(dq.front(), 35);
-  EXPECT_EQ(dq.back(), 55);
-  EXPECT_EQ(dq.at(0), 35);
-  EXPECT_EQ(dq.at(1), 45);
-  EXPECT_EQ(dq.at(2), 55);
-  EXPECT_EQ(dq[0], 35);
-  EXPECT_EQ(dq[1], 45);
-  EXPECT_EQ(dq[2], 55);
-
-  // Shift right one last time. begin returns to 0. Data is no longer wrapped.
-  dq.pop_front();
-  dq.push_back(65);
-  EXPECT_THAT(dq, ElementsAre(45, 55, 65));
-  EXPECT_LT(&dq.front(), &dq.back());
-  EXPECT_EQ(dq.front(), 45);
-  EXPECT_EQ(dq.back(), 65);
-  EXPECT_EQ(dq.at(0), 45);
-  EXPECT_EQ(dq.at(1), 55);
-  EXPECT_EQ(dq.at(2), 65);
-  EXPECT_EQ(dq[0], 45);
-  EXPECT_EQ(dq[1], 55);
-  EXPECT_EQ(dq[2], 65);
-
-  EXPECT_EQ(1u, dq.get_allocator().allocate_count());
-}
-
-TEST_F(QuicheCircularDequeTest, Iterate) {
-  QuicheCircularDeque<int> dq;
-  EXPECT_EQ(dq.begin(), dq.end());
-  EXPECT_EQ(dq.cbegin(), dq.cend());
-  EXPECT_EQ(dq.rbegin(), dq.rend());
-  EXPECT_EQ(dq.crbegin(), dq.crend());
-
-  dq.emplace_back(2);
-  QuicheCircularDeque<int>::const_iterator citer = dq.begin();
-  EXPECT_NE(citer, dq.end());
-  EXPECT_EQ(*citer, 2);
-  ++citer;
-  EXPECT_EQ(citer, dq.end());
-
-  EXPECT_EQ(*dq.begin(), 2);
-  EXPECT_EQ(*dq.cbegin(), 2);
-  EXPECT_EQ(*dq.rbegin(), 2);
-  EXPECT_EQ(*dq.crbegin(), 2);
-
-  dq.emplace_front(1);
-  QuicheCircularDeque<int>::const_reverse_iterator criter = dq.rbegin();
-  EXPECT_NE(criter, dq.rend());
-  EXPECT_EQ(*criter, 2);
-  ++criter;
-  EXPECT_NE(criter, dq.rend());
-  EXPECT_EQ(*criter, 1);
-  ++criter;
-  EXPECT_EQ(criter, dq.rend());
-
-  EXPECT_EQ(*dq.begin(), 1);
-  EXPECT_EQ(*dq.cbegin(), 1);
-  EXPECT_EQ(*dq.rbegin(), 2);
-  EXPECT_EQ(*dq.crbegin(), 2);
-
-  dq.push_back(3);
-
-  // Forward iterate.
-  int expected_value = 1;
-  for (QuicheCircularDeque<int>::iterator it = dq.begin(); it != dq.end();
-       ++it) {
-    EXPECT_EQ(expected_value++, *it);
-  }
-
-  expected_value = 1;
-  for (QuicheCircularDeque<int>::const_iterator it = dq.cbegin();
-       it != dq.cend(); ++it) {
-    EXPECT_EQ(expected_value++, *it);
-  }
-
-  // Reverse iterate.
-  expected_value = 3;
-  for (QuicheCircularDeque<int>::reverse_iterator it = dq.rbegin();
-       it != dq.rend(); ++it) {
-    EXPECT_EQ(expected_value--, *it);
-  }
-
-  expected_value = 3;
-  for (QuicheCircularDeque<int>::const_reverse_iterator it = dq.crbegin();
-       it != dq.crend(); ++it) {
-    EXPECT_EQ(expected_value--, *it);
-  }
-}
-
-TEST_F(QuicheCircularDequeTest, Iterator) {
-  // Default constructed iterators of the same type compare equal.
-  EXPECT_EQ(QuicheCircularDeque<int>::iterator(),
-            QuicheCircularDeque<int>::iterator());
-  EXPECT_EQ(QuicheCircularDeque<int>::const_iterator(),
-            QuicheCircularDeque<int>::const_iterator());
-  EXPECT_EQ(QuicheCircularDeque<int>::reverse_iterator(),
-            QuicheCircularDeque<int>::reverse_iterator());
-  EXPECT_EQ(QuicheCircularDeque<int>::const_reverse_iterator(),
-            QuicheCircularDeque<int>::const_reverse_iterator());
-
-  QuicheCircularDeque<QuicheCircularDeque<int>, 3> dqdq = {
-      {1, 2}, {10, 20, 30}, {100, 200, 300, 400}};
-
-  // iter points to {1, 2}
-  decltype(dqdq)::iterator iter = dqdq.begin();
-  EXPECT_EQ(iter->size(), 2u);
-  EXPECT_THAT(*iter, ElementsAre(1, 2));
-
-  // citer points to {10, 20, 30}
-  decltype(dqdq)::const_iterator citer = dqdq.cbegin() + 1;
-  EXPECT_NE(*iter, *citer);
-  EXPECT_EQ(citer->size(), 3u);
-  int x = 10;
-  for (auto it = citer->begin(); it != citer->end(); ++it) {
-    EXPECT_EQ(*it, x);
-    x += 10;
-  }
-
-  EXPECT_LT(iter, citer);
-  EXPECT_LE(iter, iter);
-  EXPECT_GT(citer, iter);
-  EXPECT_GE(citer, citer);
-
-  // iter points to {100, 200, 300, 400}
-  iter += 2;
-  EXPECT_NE(*iter, *citer);
-  EXPECT_EQ(iter->size(), 4u);
-  for (int i = 1; i <= 4; ++i) {
-    EXPECT_EQ(iter->begin()[i - 1], i * 100);
-  }
-
-  EXPECT_LT(citer, iter);
-  EXPECT_LE(iter, iter);
-  EXPECT_GT(iter, citer);
-  EXPECT_GE(citer, citer);
-
-  // iter points to {10, 20, 30}. (same as citer)
-  iter -= 1;
-  EXPECT_EQ(*iter, *citer);
-  EXPECT_EQ(iter->size(), 3u);
-  x = 10;
-  for (auto it = iter->begin(); it != iter->end();) {
-    EXPECT_EQ(*(it++), x);
-    x += 10;
-  }
-  x = 30;
-  for (auto it = iter->begin() + 2; it != iter->begin();) {
-    EXPECT_EQ(*(it--), x);
-    x -= 10;
-  }
-}
-
-TEST_F(QuicheCircularDequeTest, Resize) {
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq;
-  dq.resize(8);
-  EXPECT_THAT(dq, ElementsAre(0, 0, 0, 0, 0, 0, 0, 0));
-  EXPECT_EQ(1u, dq.get_allocator().allocate_count());
-
-  dq.resize(10, 5);
-  EXPECT_THAT(dq, ElementsAre(0, 0, 0, 0, 0, 0, 0, 0, 5, 5));
-
-  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq2 = dq;
-
-  for (size_t new_size = dq.size(); new_size != 0; --new_size) {
-    dq.resize(new_size);
-    EXPECT_TRUE(
-        std::equal(dq.begin(), dq.end(), dq2.begin(), dq2.begin() + new_size));
-  }
-
-  dq.resize(0);
-  EXPECT_TRUE(dq.empty());
-
-  // Resize when data is wrapped.
-  ASSERT_EQ(dq2.size(), dq2.capacity());
-  while (dq2.size() < dq2.capacity()) {
-    dq2.push_back(5);
-  }
-
-  // Shift left once such that data is wrapped.
-  ASSERT_LT(&dq2.front(), &dq2.back());
-  dq2.pop_back();
-  dq2.push_front(-5);
-  ASSERT_GT(&dq2.front(), &dq2.back());
-
-  EXPECT_EQ(-5, dq2.front());
-  EXPECT_EQ(5, dq2.back());
-  dq2.resize(dq2.size() + 1, 10);
-
-  // Data should be unwrapped after the resize.
-  ASSERT_LT(&dq2.front(), &dq2.back());
-  EXPECT_EQ(-5, dq2.front());
-  EXPECT_EQ(10, dq2.back());
-  EXPECT_EQ(5, *(dq2.rbegin() + 1));
-}
-
-namespace {
-class Foo {
- public:
-  Foo() : Foo(0xF00) {}
-
-  explicit Foo(int i) : i_(new int(i)) {}
-
-  ~Foo() {
-    if (i_ != nullptr) {
-      delete i_;
-      // Do not set i_ to nullptr such that if the container calls destructor
-      // multiple times, asan can detect it.
-    }
-  }
-
-  Foo(const Foo& other) : i_(new int(*other.i_)) {}
-
-  Foo(Foo&& other) = delete;
-
-  void Set(int i) { *i_ = i; }
-
-  int i() const { return *i_; }
-
-  friend bool operator==(const Foo& lhs, const Foo& rhs) {
-    return lhs.i() == rhs.i();
-  }
-
-  friend std::ostream& operator<<(std::ostream& os, const Foo& foo) {
-    return os << "Foo(" << foo.i() << ")";
-  }
-
- private:
-  // By pointing i_ to a dynamically allocated integer, a memory leak will be
-  // reported if the container forget to properly destruct this object.
-  int* i_ = nullptr;
-};
-}  // namespace
-
-TEST_F(QuicheCircularDequeTest, RelocateNonTriviallyCopyable) {
-  // When relocating non-trivially-copyable objects:
-  // - Move constructor is preferred, if available.
-  // - Copy constructor is used otherwise.
-
-  {
-    // Move construct in Relocate.
-    using MoveConstructible = std::unique_ptr<Foo>;
-    ASSERT_FALSE(std::is_trivially_copyable<MoveConstructible>::value);
-    ASSERT_TRUE(std::is_move_constructible<MoveConstructible>::value);
-    QuicheCircularDeque<MoveConstructible, 3,
-                        CountingAllocator<MoveConstructible>>
-        dq1;
-    dq1.resize(3);
-    EXPECT_EQ(dq1.size(), dq1.capacity());
-    EXPECT_EQ(1u, dq1.get_allocator().allocate_count());
-
-    dq1.emplace_back(new Foo(0xF1));  // Cause existing elements to relocate.
-    EXPECT_EQ(4u, dq1.size());
-    EXPECT_EQ(2u, dq1.get_allocator().allocate_count());
-    EXPECT_EQ(dq1[0], nullptr);
-    EXPECT_EQ(dq1[1], nullptr);
-    EXPECT_EQ(dq1[2], nullptr);
-    EXPECT_EQ(dq1[3]->i(), 0xF1);
-  }
-
-  {
-    // Copy construct in Relocate.
-    using NonMoveConstructible = Foo;
-    ASSERT_FALSE(std::is_trivially_copyable<NonMoveConstructible>::value);
-    ASSERT_FALSE(std::is_move_constructible<NonMoveConstructible>::value);
-    QuicheCircularDeque<NonMoveConstructible, 3,
-                        CountingAllocator<NonMoveConstructible>>
-        dq2;
-    dq2.resize(3);
-    EXPECT_EQ(dq2.size(), dq2.capacity());
-    EXPECT_EQ(1u, dq2.get_allocator().allocate_count());
-
-    dq2.emplace_back(0xF1);  // Cause existing elements to relocate.
-    EXPECT_EQ(4u, dq2.size());
-    EXPECT_EQ(2u, dq2.get_allocator().allocate_count());
-    EXPECT_EQ(dq2[0].i(), 0xF00);
-    EXPECT_EQ(dq2[1].i(), 0xF00);
-    EXPECT_EQ(dq2[2].i(), 0xF00);
-    EXPECT_EQ(dq2[3].i(), 0xF1);
-  }
-}
-
-TEST_F(QuicheCircularDequeTest, PushPop) {
-  // (push|pop|emplace)_(back|front)
-
-  {
-    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq(4);
-    for (size_t i = 0; i < dq.size(); ++i) {
-      dq[i].Set(i + 1);
-    }
-    QUICHE_LOG(INFO) << "dq initialized to " << dq;
-    EXPECT_THAT(dq, ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4)));
-
-    ShiftLeft(&dq, false);
-    QUICHE_LOG(INFO) << "shift left once : " << dq;
-    EXPECT_THAT(dq, ElementsAre(Foo(2), Foo(3), Foo(4), Foo(1)));
-
-    ShiftLeft(&dq, true);
-    QUICHE_LOG(INFO) << "shift left twice: " << dq;
-    EXPECT_THAT(dq, ElementsAre(Foo(3), Foo(4), Foo(1), Foo(2)));
-    ASSERT_GT(&dq.front(), &dq.back());
-    // dq destructs with wrapped data.
-  }
-
-  {
-    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq1(4);
-    for (size_t i = 0; i < dq1.size(); ++i) {
-      dq1[i].Set(i + 1);
-    }
-    QUICHE_LOG(INFO) << "dq1 initialized to " << dq1;
-    EXPECT_THAT(dq1, ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4)));
-
-    ShiftRight(&dq1, false);
-    QUICHE_LOG(INFO) << "shift right once : " << dq1;
-    EXPECT_THAT(dq1, ElementsAre(Foo(4), Foo(1), Foo(2), Foo(3)));
-
-    ShiftRight(&dq1, true);
-    QUICHE_LOG(INFO) << "shift right twice: " << dq1;
-    EXPECT_THAT(dq1, ElementsAre(Foo(3), Foo(4), Foo(1), Foo(2)));
-    ASSERT_GT(&dq1.front(), &dq1.back());
-    // dq1 destructs with wrapped data.
-  }
-
-  {  // Pop n elements from front.
-    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq2(5);
-    for (size_t i = 0; i < dq2.size(); ++i) {
-      dq2[i].Set(i + 1);
-    }
-    EXPECT_THAT(dq2, ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)));
-
-    EXPECT_EQ(2u, dq2.pop_front_n(2));
-    EXPECT_THAT(dq2, ElementsAre(Foo(3), Foo(4), Foo(5)));
-
-    EXPECT_EQ(3u, dq2.pop_front_n(100));
-    EXPECT_TRUE(dq2.empty());
-  }
-
-  {  // Pop n elements from back.
-    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq3(6);
-    for (size_t i = 0; i < dq3.size(); ++i) {
-      dq3[i].Set(i + 1);
-    }
-    EXPECT_THAT(dq3,
-                ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4), Foo(5), Foo(6)));
-
-    ShiftRight(&dq3, true);
-    ShiftRight(&dq3, true);
-    ShiftRight(&dq3, true);
-    EXPECT_THAT(dq3,
-                ElementsAre(Foo(4), Foo(5), Foo(6), Foo(1), Foo(2), Foo(3)));
-
-    EXPECT_EQ(2u, dq3.pop_back_n(2));
-    EXPECT_THAT(dq3, ElementsAre(Foo(4), Foo(5), Foo(6), Foo(1)));
-
-    EXPECT_EQ(2u, dq3.pop_back_n(2));
-    EXPECT_THAT(dq3, ElementsAre(Foo(4), Foo(5)));
-  }
-}
-
-TEST_F(QuicheCircularDequeTest, Allocation) {
-  CountingAllocator<int> alloc;
-
-  {
-    QuicheCircularDeque<int, 3, CountingAllocator<int>> dq(alloc);
-    EXPECT_EQ(alloc, dq.get_allocator());
-    EXPECT_EQ(0u, dq.size());
-    EXPECT_EQ(0u, dq.capacity());
-    EXPECT_EQ(0u, alloc.allocate_count());
-    EXPECT_EQ(0u, alloc.deallocate_count());
-
-    for (int i = 1; i <= 18; ++i) {
-      SCOPED_TRACE(testing::Message()
-                   << "i=" << i << ", capacity_b4_push=" << dq.capacity());
-      dq.push_back(i);
-      EXPECT_EQ(i, static_cast<int>(dq.size()));
-
-      const size_t capacity = 3 + (i - 1) / 3 * 3;
-      EXPECT_EQ(capacity, dq.capacity());
-      EXPECT_EQ(capacity / 3, alloc.allocate_count());
-      EXPECT_EQ(capacity / 3 - 1, alloc.deallocate_count());
-    }
-
-    dq.push_back(19);
-    EXPECT_EQ(22u, dq.capacity());  // 18 + 18 / 4
-    EXPECT_EQ(7u, alloc.allocate_count());
-    EXPECT_EQ(6u, alloc.deallocate_count());
-  }
-
-  EXPECT_EQ(7u, alloc.deallocate_count());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
-
-// Use a non-quiche namespace to make sure swap can be used via ADL.
-namespace {
-
-template <typename T>
-using SwappableAllocator = quiche::test::ConfigurableAllocator<
-    T,
-    /*propagate_on_copy_assignment=*/std::true_type,
-    /*propagate_on_move_assignment=*/std::true_type,
-    /*propagate_on_swap=*/std::true_type,
-    /*equality_result=*/true>;
-
-template <typename T>
-using UnswappableEqualAllocator = quiche::test::ConfigurableAllocator<
-    T,
-    /*propagate_on_copy_assignment=*/std::true_type,
-    /*propagate_on_move_assignment=*/std::true_type,
-    /*propagate_on_swap=*/std::false_type,
-    /*equality_result=*/true>;
-
-template <typename T>
-using UnswappableUnequalAllocator = quiche::test::ConfigurableAllocator<
-    T,
-    /*propagate_on_copy_assignment=*/std::true_type,
-    /*propagate_on_move_assignment=*/std::true_type,
-    /*propagate_on_swap=*/std::false_type,
-    /*equality_result=*/false>;
-
-using quiche::test::QuicheCircularDequeTest;
-
-TEST_F(QuicheCircularDequeTest, Swap) {
-  using std::swap;
-
-  quiche::QuicheCircularDeque<int64_t, 3, SwappableAllocator<int64_t>> dq1, dq2;
-  dq1.push_back(10);
-  dq1.push_back(11);
-  dq2.push_back(20);
-  swap(dq1, dq2);
-  EXPECT_THAT(dq1, ElementsAre(20));
-  EXPECT_THAT(dq2, ElementsAre(10, 11));
-
-  quiche::QuicheCircularDeque<char, 3, UnswappableEqualAllocator<char>> dq3,
-      dq4;
-  dq3 = {1, 2, 3, 4, 5};
-  dq4 = {6, 7, 8, 9, 0};
-  swap(dq3, dq4);
-  EXPECT_THAT(dq3, ElementsAre(6, 7, 8, 9, 0));
-  EXPECT_THAT(dq4, ElementsAre(1, 2, 3, 4, 5));
-
-  quiche::QuicheCircularDeque<int, 3, UnswappableUnequalAllocator<int>> dq5,
-      dq6;
-  dq6.push_front(4);
-
-  // Using UnswappableUnequalAllocator is ok as long as swap is not called.
-  dq5.assign(dq6.begin(), dq6.end());
-  EXPECT_THAT(dq5, ElementsAre(4));
-
-  // Undefined behavior to swap between two containers with unequal allocators.
-  EXPECT_QUICHE_DEBUG_DEATH(swap(dq5, dq6), "Undefined swap behavior");
-}
-}  // namespace
diff --git a/common/quiche_data_reader.cc b/common/quiche_data_reader.cc
deleted file mode 100644
index 1f948f1..0000000
--- a/common/quiche_data_reader.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_data_reader.h"
-
-#include <cstring>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quiche {
-
-QuicheDataReader::QuicheDataReader(absl::string_view data)
-    : QuicheDataReader(data.data(), data.length(), quiche::NETWORK_BYTE_ORDER) {
-}
-
-QuicheDataReader::QuicheDataReader(const char* data, const size_t len)
-    : QuicheDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
-
-QuicheDataReader::QuicheDataReader(const char* data,
-                                   const size_t len,
-                                   quiche::Endianness endianness)
-    : data_(data), len_(len), pos_(0), endianness_(endianness) {}
-
-bool QuicheDataReader::ReadUInt8(uint8_t* result) {
-  return ReadBytes(result, sizeof(*result));
-}
-
-bool QuicheDataReader::ReadUInt16(uint16_t* result) {
-  if (!ReadBytes(result, sizeof(*result))) {
-    return false;
-  }
-  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
-    *result = quiche::QuicheEndian::NetToHost16(*result);
-  }
-  return true;
-}
-
-bool QuicheDataReader::ReadUInt24(uint32_t* result) {
-  if (endianness_ != quiche::NETWORK_BYTE_ORDER) {
-    // TODO(b/214573190): Implement and test HOST_BYTE_ORDER case.
-    QUICHE_BUG(QuicheDataReader_ReadUInt24_NotImplemented);
-    return false;
-  }
-
-  *result = 0;
-  if (!ReadBytes(reinterpret_cast<char*>(result) + 1, 3u)) {
-    return false;
-  }
-  *result = quiche::QuicheEndian::NetToHost32(*result);
-  return true;
-}
-
-bool QuicheDataReader::ReadUInt32(uint32_t* result) {
-  if (!ReadBytes(result, sizeof(*result))) {
-    return false;
-  }
-  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
-    *result = quiche::QuicheEndian::NetToHost32(*result);
-  }
-  return true;
-}
-
-bool QuicheDataReader::ReadUInt64(uint64_t* result) {
-  if (!ReadBytes(result, sizeof(*result))) {
-    return false;
-  }
-  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
-    *result = quiche::QuicheEndian::NetToHost64(*result);
-  }
-  return true;
-}
-
-bool QuicheDataReader::ReadBytesToUInt64(size_t num_bytes, uint64_t* result) {
-  *result = 0u;
-  if (num_bytes > sizeof(*result)) {
-    return false;
-  }
-  if (endianness_ == quiche::HOST_BYTE_ORDER) {
-    return ReadBytes(result, num_bytes);
-  }
-
-  if (!ReadBytes(reinterpret_cast<char*>(result) + sizeof(*result) - num_bytes,
-                 num_bytes)) {
-    return false;
-  }
-  *result = quiche::QuicheEndian::NetToHost64(*result);
-  return true;
-}
-
-bool QuicheDataReader::ReadStringPiece16(absl::string_view* result) {
-  // Read resultant length.
-  uint16_t result_len;
-  if (!ReadUInt16(&result_len)) {
-    // OnFailure() already called.
-    return false;
-  }
-
-  return ReadStringPiece(result, result_len);
-}
-
-bool QuicheDataReader::ReadStringPiece8(absl::string_view* result) {
-  // Read resultant length.
-  uint8_t result_len;
-  if (!ReadUInt8(&result_len)) {
-    // OnFailure() already called.
-    return false;
-  }
-
-  return ReadStringPiece(result, result_len);
-}
-
-bool QuicheDataReader::ReadStringPiece(absl::string_view* result, size_t size) {
-  // Make sure that we have enough data to read.
-  if (!CanRead(size)) {
-    OnFailure();
-    return false;
-  }
-
-  // Set result.
-  *result = absl::string_view(data_ + pos_, size);
-
-  // Iterate.
-  pos_ += size;
-
-  return true;
-}
-
-bool QuicheDataReader::ReadTag(uint32_t* tag) {
-  return ReadBytes(tag, sizeof(*tag));
-}
-
-bool QuicheDataReader::ReadDecimal64(size_t num_digits, uint64_t* result) {
-  absl::string_view digits;
-  if (!ReadStringPiece(&digits, num_digits)) {
-    return false;
-  }
-
-  return absl::SimpleAtoi(digits, result);
-}
-
-absl::string_view QuicheDataReader::ReadRemainingPayload() {
-  absl::string_view payload = PeekRemainingPayload();
-  pos_ = len_;
-  return payload;
-}
-
-absl::string_view QuicheDataReader::PeekRemainingPayload() const {
-  return absl::string_view(data_ + pos_, len_ - pos_);
-}
-
-absl::string_view QuicheDataReader::FullPayload() const {
-  return absl::string_view(data_, len_);
-}
-
-absl::string_view QuicheDataReader::PreviouslyReadPayload() const {
-  return absl::string_view(data_, pos_);
-}
-
-bool QuicheDataReader::ReadBytes(void* result, size_t size) {
-  // Make sure that we have enough data to read.
-  if (!CanRead(size)) {
-    OnFailure();
-    return false;
-  }
-
-  // Read into result.
-  memcpy(result, data_ + pos_, size);
-
-  // Iterate.
-  pos_ += size;
-
-  return true;
-}
-
-bool QuicheDataReader::Seek(size_t size) {
-  if (!CanRead(size)) {
-    OnFailure();
-    return false;
-  }
-  pos_ += size;
-  return true;
-}
-
-bool QuicheDataReader::IsDoneReading() const {
-  return len_ == pos_;
-}
-
-size_t QuicheDataReader::BytesRemaining() const {
-  return len_ - pos_;
-}
-
-bool QuicheDataReader::TruncateRemaining(size_t truncation_length) {
-  if (truncation_length > BytesRemaining()) {
-    return false;
-  }
-  len_ = pos_ + truncation_length;
-  return true;
-}
-
-bool QuicheDataReader::CanRead(size_t bytes) const {
-  return bytes <= (len_ - pos_);
-}
-
-void QuicheDataReader::OnFailure() {
-  // Set our iterator to the end of the buffer so that further reads fail
-  // immediately.
-  pos_ = len_;
-}
-
-uint8_t QuicheDataReader::PeekByte() const {
-  if (pos_ >= len_) {
-    QUICHE_LOG(FATAL)
-        << "Reading is done, cannot peek next byte. Tried to read pos = "
-        << pos_ << " buffer length = " << len_;
-    return 0;
-  }
-  return data_[pos_];
-}
-
-std::string QuicheDataReader::DebugString() const {
-  return absl::StrCat(" { length: ", len_, ", position: ", pos_, " }");
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quiche
diff --git a/common/quiche_data_reader.h b/common/quiche_data_reader.h
deleted file mode 100644
index ae8bbcf..0000000
--- a/common/quiche_data_reader.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_DATA_READER_H_
-#define QUICHE_COMMON_QUICHE_DATA_READER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quiche {
-
-// To use, simply construct a QuicheDataReader using the underlying buffer that
-// you'd like to read fields from, then call one of the Read*() methods to
-// actually do some reading.
-//
-// This class keeps an internal iterator to keep track of what's already been
-// read and each successive Read*() call automatically increments said iterator
-// on success. On failure, internal state of the QuicheDataReader should not be
-// trusted and it is up to the caller to throw away the failed instance and
-// handle the error as appropriate. None of the Read*() methods should ever be
-// called after failure, as they will also fail immediately.
-class QUICHE_EXPORT_PRIVATE QuicheDataReader {
- public:
-  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
-  // Caller must provide an underlying buffer to work on.
-  explicit QuicheDataReader(absl::string_view data);
-  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
-  // Caller must provide an underlying buffer to work on.
-  QuicheDataReader(const char* data, const size_t len);
-  // Constructs a reader using the specified endianness.
-  // Caller must provide an underlying buffer to work on.
-  QuicheDataReader(const char* data,
-                   const size_t len,
-                   quiche::Endianness endianness);
-  QuicheDataReader(const QuicheDataReader&) = delete;
-  QuicheDataReader& operator=(const QuicheDataReader&) = delete;
-
-  // Empty destructor.
-  ~QuicheDataReader() {}
-
-  // Reads an 8/16/24/32/64-bit unsigned integer into the given output
-  // parameter. Forwards the internal iterator on success. Returns true on
-  // success, false otherwise.
-  bool ReadUInt8(uint8_t* result);
-  bool ReadUInt16(uint16_t* result);
-  bool ReadUInt24(uint32_t* result);
-  bool ReadUInt32(uint32_t* result);
-  bool ReadUInt64(uint64_t* result);
-
-  // Set |result| to 0, then read |num_bytes| bytes in the correct byte order
-  // into least significant bytes of |result|.
-  bool ReadBytesToUInt64(size_t num_bytes, uint64_t* result);
-
-  // Reads a string prefixed with 16-bit length into the given output parameter.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadStringPiece16(absl::string_view* result);
-
-  // Reads a string prefixed with 8-bit length into the given output parameter.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadStringPiece8(absl::string_view* result);
-
-  // Reads a given number of bytes into the given buffer. The buffer
-  // must be of adequate size.
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadStringPiece(absl::string_view* result, size_t size);
-
-  // Reads tag represented as 32-bit unsigned integer into given output
-  // parameter. Tags are in big endian on the wire (e.g., CHLO is
-  // 'C','H','L','O') and are read in byte order, so tags in memory are in big
-  // endian.
-  bool ReadTag(uint32_t* tag);
-
-  // Reads a sequence of a fixed number of decimal digits, parses them as an
-  // unsigned integer and returns them as a uint64_t.  Forwards internal
-  // iterator on success, may forward it even in case of failure.
-  bool ReadDecimal64(size_t num_digits, uint64_t* result);
-
-  // Returns the remaining payload as a absl::string_view.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // Forwards the internal iterator.
-  absl::string_view ReadRemainingPayload();
-
-  // Returns the remaining payload as a absl::string_view.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // DOES NOT forward the internal iterator.
-  absl::string_view PeekRemainingPayload() const;
-
-  // Returns the entire payload as a absl::string_view.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // DOES NOT forward the internal iterator.
-  absl::string_view FullPayload() const;
-
-  // Returns the part of the payload that has been already read as a
-  // absl::string_view.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // DOES NOT forward the internal iterator.
-  absl::string_view PreviouslyReadPayload() const;
-
-  // Reads a given number of bytes into the given buffer. The buffer
-  // must be of adequate size.
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadBytes(void* result, size_t size);
-
-  // Skips over |size| bytes from the buffer and forwards the internal iterator.
-  // Returns true if there are at least |size| bytes remaining to read, false
-  // otherwise.
-  bool Seek(size_t size);
-
-  // Returns true if the entirety of the underlying buffer has been read via
-  // Read*() calls.
-  bool IsDoneReading() const;
-
-  // Returns the number of bytes remaining to be read.
-  size_t BytesRemaining() const;
-
-  // Truncates the reader down by reducing its internal length.
-  // If called immediately after calling this, BytesRemaining will
-  // return |truncation_length|. If truncation_length is less than the
-  // current value of BytesRemaining, this does nothing and returns false.
-  bool TruncateRemaining(size_t truncation_length);
-
-  // Returns the next byte that to be read. Must not be called when there are no
-  // bytes to be read.
-  //
-  // DOES NOT forward the internal iterator.
-  uint8_t PeekByte() const;
-
-  std::string DebugString() const;
-
- protected:
-  // Returns true if the underlying buffer has enough room to read the given
-  // amount of bytes.
-  bool CanRead(size_t bytes) const;
-
-  // To be called when a read fails for any reason.
-  void OnFailure();
-
-  const char* data() const { return data_; }
-
-  size_t pos() const { return pos_; }
-
-  void AdvancePos(size_t amount) {
-    QUICHE_DCHECK_LE(pos_, std::numeric_limits<size_t>::max() - amount);
-    QUICHE_DCHECK_LE(pos_, len_ - amount);
-    pos_ += amount;
-  }
-
-  quiche::Endianness endianness() const { return endianness_; }
-
- private:
-  // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
-  // char. The data buffer that we're reading from.
-  const char* data_;
-
-  // The length of the data buffer that we're reading from.
-  size_t len_;
-
-  // The location of the next read from our data buffer.
-  size_t pos_;
-
-  // The endianness to read integers and floating numbers.
-  quiche::Endianness endianness_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_DATA_READER_H_
diff --git a/common/quiche_data_reader_test.cc b/common/quiche_data_reader_test.cc
deleted file mode 100644
index 52ed292..0000000
--- a/common/quiche_data_reader_test.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_data_reader.h"
-
-#include <cstdint>
-
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_endian.h"
-
-namespace quiche {
-
-// TODO(b/214573190): Test Endianness::HOST_BYTE_ORDER.
-// TODO(b/214573190): Test ReadUInt8, ReadUInt24, ReadUInt64, ReadBytesToUInt64,
-// ReadStringPiece8, ReadStringPiece, ReadTag, etc.
-
-TEST(QuicheDataReaderTest, ReadUInt16) {
-  // Data in network byte order.
-  const uint16_t kData[] = {
-      QuicheEndian::HostToNet16(1),
-      QuicheEndian::HostToNet16(1 << 15),
-  };
-
-  QuicheDataReader reader(reinterpret_cast<const char*>(kData), sizeof(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  uint16_t uint16_val;
-  EXPECT_TRUE(reader.ReadUInt16(&uint16_val));
-  EXPECT_FALSE(reader.IsDoneReading());
-  EXPECT_EQ(1, uint16_val);
-
-  EXPECT_TRUE(reader.ReadUInt16(&uint16_val));
-  EXPECT_TRUE(reader.IsDoneReading());
-  EXPECT_EQ(1 << 15, uint16_val);
-}
-
-TEST(QuicheDataReaderTest, ReadUInt32) {
-  // Data in network byte order.
-  const uint32_t kData[] = {
-      QuicheEndian::HostToNet32(1),
-      QuicheEndian::HostToNet32(0x80000000),
-  };
-
-  QuicheDataReader reader(reinterpret_cast<const char*>(kData),
-                          ABSL_ARRAYSIZE(kData) * sizeof(uint32_t));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  uint32_t uint32_val;
-  EXPECT_TRUE(reader.ReadUInt32(&uint32_val));
-  EXPECT_FALSE(reader.IsDoneReading());
-  EXPECT_EQ(1u, uint32_val);
-
-  EXPECT_TRUE(reader.ReadUInt32(&uint32_val));
-  EXPECT_TRUE(reader.IsDoneReading());
-  EXPECT_EQ(1u << 31, uint32_val);
-}
-
-TEST(QuicheDataReaderTest, ReadStringPiece16) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x00, 0x02,  // uint16_t(2)
-      0x48, 0x69,  // "Hi"
-      0x00, 0x10,  // uint16_t(16)
-      0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2c,
-      0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33,  // "Testing, 1, 2, 3"
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  absl::string_view stringpiece_val;
-  EXPECT_TRUE(reader.ReadStringPiece16(&stringpiece_val));
-  EXPECT_FALSE(reader.IsDoneReading());
-  EXPECT_EQ(0, stringpiece_val.compare("Hi"));
-
-  EXPECT_TRUE(reader.ReadStringPiece16(&stringpiece_val));
-  EXPECT_TRUE(reader.IsDoneReading());
-  EXPECT_EQ(0, stringpiece_val.compare("Testing, 1, 2, 3"));
-}
-
-TEST(QuicheDataReaderTest, ReadUInt16WithBufferTooSmall) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x00,  // part of a uint16_t
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  uint16_t uint16_val;
-  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
-}
-
-TEST(QuicheDataReaderTest, ReadUInt32WithBufferTooSmall) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x00, 0x00, 0x00,  // part of a uint32_t
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  uint32_t uint32_val;
-  EXPECT_FALSE(reader.ReadUInt32(&uint32_val));
-
-  // Also make sure that trying to read a uint16_t, which technically could
-  // work, fails immediately due to previously encountered failed read.
-  uint16_t uint16_val;
-  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
-}
-
-// Tests ReadStringPiece16() with a buffer too small to fit the entire string.
-TEST(QuicheDataReaderTest, ReadStringPiece16WithBufferTooSmall) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x00, 0x03,  // uint16_t(3)
-      0x48, 0x69,  // "Hi"
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  absl::string_view stringpiece_val;
-  EXPECT_FALSE(reader.ReadStringPiece16(&stringpiece_val));
-
-  // Also make sure that trying to read a uint16_t, which technically could
-  // work, fails immediately due to previously encountered failed read.
-  uint16_t uint16_val;
-  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
-}
-
-// Tests ReadStringPiece16() with a buffer too small even to fit the length.
-TEST(QuicheDataReaderTest, ReadStringPiece16WithBufferWayTooSmall) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x00,  // part of a uint16_t
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  absl::string_view stringpiece_val;
-  EXPECT_FALSE(reader.ReadStringPiece16(&stringpiece_val));
-
-  // Also make sure that trying to read a uint16_t, which technically could
-  // work, fails immediately due to previously encountered failed read.
-  uint16_t uint16_val;
-  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
-}
-
-TEST(QuicheDataReaderTest, ReadBytes) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x66, 0x6f, 0x6f,  // "foo"
-      0x48, 0x69,        // "Hi"
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  char dest1[3] = {};
-  EXPECT_TRUE(reader.ReadBytes(&dest1, ABSL_ARRAYSIZE(dest1)));
-  EXPECT_FALSE(reader.IsDoneReading());
-  EXPECT_EQ("foo", absl::string_view(dest1, ABSL_ARRAYSIZE(dest1)));
-
-  char dest2[2] = {};
-  EXPECT_TRUE(reader.ReadBytes(&dest2, ABSL_ARRAYSIZE(dest2)));
-  EXPECT_TRUE(reader.IsDoneReading());
-  EXPECT_EQ("Hi", absl::string_view(dest2, ABSL_ARRAYSIZE(dest2)));
-}
-
-TEST(QuicheDataReaderTest, ReadBytesWithBufferTooSmall) {
-  // Data in network byte order.
-  const char kData[] = {
-      0x01,
-  };
-
-  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
-  EXPECT_FALSE(reader.IsDoneReading());
-
-  char dest[ABSL_ARRAYSIZE(kData) + 2] = {};
-  EXPECT_FALSE(reader.ReadBytes(&dest, ABSL_ARRAYSIZE(kData) + 1));
-  EXPECT_STREQ("", dest);
-}
-
-}  // namespace quiche
diff --git a/common/quiche_data_writer.cc b/common/quiche_data_writer.cc
deleted file mode 100644
index 4416d84..0000000
--- a/common/quiche_data_writer.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_data_writer.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "common/quiche_endian.h"
-
-namespace quiche {
-
-QuicheDataWriter::QuicheDataWriter(size_t size, char* buffer)
-    : QuicheDataWriter(size, buffer, quiche::NETWORK_BYTE_ORDER) {}
-
-QuicheDataWriter::QuicheDataWriter(size_t size,
-                                   char* buffer,
-                                   quiche::Endianness endianness)
-    : buffer_(buffer), capacity_(size), length_(0), endianness_(endianness) {}
-
-QuicheDataWriter::~QuicheDataWriter() {}
-
-char* QuicheDataWriter::data() {
-  return buffer_;
-}
-
-bool QuicheDataWriter::WriteUInt8(uint8_t value) {
-  return WriteBytes(&value, sizeof(value));
-}
-
-bool QuicheDataWriter::WriteUInt16(uint16_t value) {
-  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
-    value = quiche::QuicheEndian::HostToNet16(value);
-  }
-  return WriteBytes(&value, sizeof(value));
-}
-
-bool QuicheDataWriter::WriteUInt32(uint32_t value) {
-  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
-    value = quiche::QuicheEndian::HostToNet32(value);
-  }
-  return WriteBytes(&value, sizeof(value));
-}
-
-bool QuicheDataWriter::WriteUInt64(uint64_t value) {
-  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
-    value = quiche::QuicheEndian::HostToNet64(value);
-  }
-  return WriteBytes(&value, sizeof(value));
-}
-
-bool QuicheDataWriter::WriteBytesToUInt64(size_t num_bytes, uint64_t value) {
-  if (num_bytes > sizeof(value)) {
-    return false;
-  }
-  if (endianness_ == quiche::HOST_BYTE_ORDER) {
-    return WriteBytes(&value, num_bytes);
-  }
-
-  value = quiche::QuicheEndian::HostToNet64(value);
-  return WriteBytes(reinterpret_cast<char*>(&value) + sizeof(value) - num_bytes,
-                    num_bytes);
-}
-
-bool QuicheDataWriter::WriteStringPiece16(absl::string_view val) {
-  if (val.size() > std::numeric_limits<uint16_t>::max()) {
-    return false;
-  }
-  if (!WriteUInt16(static_cast<uint16_t>(val.size()))) {
-    return false;
-  }
-  return WriteBytes(val.data(), val.size());
-}
-
-bool QuicheDataWriter::WriteStringPiece(absl::string_view val) {
-  return WriteBytes(val.data(), val.size());
-}
-
-char* QuicheDataWriter::BeginWrite(size_t length) {
-  if (length_ > capacity_) {
-    return nullptr;
-  }
-
-  if (capacity_ - length_ < length) {
-    return nullptr;
-  }
-
-#ifdef ARCH_CPU_64_BITS
-  QUICHE_DCHECK_LE(length, std::numeric_limits<uint32_t>::max());
-#endif
-
-  return buffer_ + length_;
-}
-
-bool QuicheDataWriter::WriteBytes(const void* data, size_t data_len) {
-  char* dest = BeginWrite(data_len);
-  if (!dest) {
-    return false;
-  }
-
-  memcpy(dest, data, data_len);
-
-  length_ += data_len;
-  return true;
-}
-
-bool QuicheDataWriter::WriteRepeatedByte(uint8_t byte, size_t count) {
-  char* dest = BeginWrite(count);
-  if (!dest) {
-    return false;
-  }
-
-  memset(dest, byte, count);
-
-  length_ += count;
-  return true;
-}
-
-void QuicheDataWriter::WritePadding() {
-  QUICHE_DCHECK_LE(length_, capacity_);
-  if (length_ > capacity_) {
-    return;
-  }
-  memset(buffer_ + length_, 0x00, capacity_ - length_);
-  length_ = capacity_;
-}
-
-bool QuicheDataWriter::WritePaddingBytes(size_t count) {
-  return WriteRepeatedByte(0x00, count);
-}
-
-bool QuicheDataWriter::WriteTag(uint32_t tag) {
-  return WriteBytes(&tag, sizeof(tag));
-}
-
-bool QuicheDataWriter::Seek(size_t length) {
-  if (!BeginWrite(length)) {
-    return false;
-  }
-  length_ += length;
-  return true;
-}
-
-std::string QuicheDataWriter::DebugString() const {
-  return absl::StrCat(" { capacity: ", capacity_, ", length: ", length_, " }");
-}
-
-}  // namespace quiche
diff --git a/common/quiche_data_writer.h b/common/quiche_data_writer.h
deleted file mode 100644
index d85f631..0000000
--- a/common/quiche_data_writer.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_DATA_WRITER_H_
-#define QUICHE_COMMON_QUICHE_DATA_WRITER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quiche {
-
-// This class provides facilities for packing binary data.
-//
-// The QuicheDataWriter supports appending primitive values (int, string, etc)
-// to a frame instance.  The internal memory buffer is exposed as the "data"
-// of the QuicheDataWriter.
-class QUICHE_EXPORT_PRIVATE QuicheDataWriter {
- public:
-  // Creates a QuicheDataWriter where |buffer| is not owned
-  // using NETWORK_BYTE_ORDER endianness.
-  QuicheDataWriter(size_t size, char* buffer);
-  // Creates a QuicheDataWriter where |buffer| is not owned
-  // using the specified endianness.
-  QuicheDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
-  QuicheDataWriter(const QuicheDataWriter&) = delete;
-  QuicheDataWriter& operator=(const QuicheDataWriter&) = delete;
-
-  ~QuicheDataWriter();
-
-  // Returns the size of the QuicheDataWriter's data.
-  size_t length() const { return length_; }
-
-  // Retrieves the buffer from the QuicheDataWriter without changing ownership.
-  char* data();
-
-  // Methods for adding to the payload.  These values are appended to the end
-  // of the QuicheDataWriter payload.
-
-  // Writes 8/16/32/64-bit unsigned integers.
-  bool WriteUInt8(uint8_t value);
-  bool WriteUInt16(uint16_t value);
-  bool WriteUInt32(uint32_t value);
-  bool WriteUInt64(uint64_t value);
-
-  // Writes least significant |num_bytes| of a 64-bit unsigned integer in the
-  // correct byte order.
-  bool WriteBytesToUInt64(size_t num_bytes, uint64_t value);
-
-  bool WriteStringPiece(absl::string_view val);
-  bool WriteStringPiece16(absl::string_view val);
-  bool WriteBytes(const void* data, size_t data_len);
-  bool WriteRepeatedByte(uint8_t byte, size_t count);
-  // Fills the remaining buffer with null characters.
-  void WritePadding();
-  // Write padding of |count| bytes.
-  bool WritePaddingBytes(size_t count);
-
-  // Write tag as a 32-bit unsigned integer to the payload. As tags are already
-  // converted to big endian (e.g., CHLO is 'C','H','L','O') in memory by TAG or
-  // MakeQuicTag and tags are written in byte order, so tags on the wire are
-  // in big endian.
-  bool WriteTag(uint32_t tag);
-
-  // Advance the writer's position for writing by |length| bytes without writing
-  // anything. This method only makes sense to be used on a buffer that has
-  // already been written to (and is having certain parts rewritten).
-  bool Seek(size_t length);
-
-  size_t capacity() const { return capacity_; }
-
-  size_t remaining() const { return capacity_ - length_; }
-
-  std::string DebugString() const;
-
- protected:
-  // Returns the location that the data should be written at, or nullptr if
-  // there is not enough room. Call EndWrite with the returned offset and the
-  // given length to pad out for the next write.
-  char* BeginWrite(size_t length);
-
-  quiche::Endianness endianness() const { return endianness_; }
-
-  char* buffer() const { return buffer_; }
-
-  void IncreaseLength(size_t delta) {
-    QUICHE_DCHECK_LE(length_, std::numeric_limits<size_t>::max() - delta);
-    QUICHE_DCHECK_LE(length_, capacity_ - delta);
-    length_ += delta;
-  }
-
- private:
-  // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
-  // char.
-  char* buffer_;
-  size_t capacity_;  // Allocation size of payload (or -1 if buffer is const).
-  size_t length_;    // Current length of the buffer.
-
-  // The endianness to write integers and floating numbers.
-  quiche::Endianness endianness_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_DATA_WRITER_H_
diff --git a/common/quiche_data_writer_test.cc b/common/quiche_data_writer_test.cc
deleted file mode 100644
index 290a27e..0000000
--- a/common/quiche_data_writer_test.cc
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_data_writer.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_data_reader.h"
-#include "common/quiche_endian.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-char* AsChars(unsigned char* data) {
-  return reinterpret_cast<char*>(data);
-}
-
-struct TestParams {
-  explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
-
-  quiche::Endianness endianness;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
-      "ByteOrder");
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (quiche::Endianness endianness :
-       {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
-    params.push_back(TestParams(endianness));
-  }
-  return params;
-}
-
-class QuicheDataWriterTest : public QuicheTestWithParam<TestParams> {};
-
-INSTANTIATE_TEST_SUITE_P(QuicheDataWriterTests,
-                         QuicheDataWriterTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicheDataWriterTest, Write16BitUnsignedIntegers) {
-  char little_endian16[] = {0x22, 0x11};
-  char big_endian16[] = {0x11, 0x22};
-  char buffer16[2];
-  {
-    uint16_t in_memory16 = 0x1122;
-    QuicheDataWriter writer(2, buffer16, GetParam().endianness);
-    writer.WriteUInt16(in_memory16);
-    test::CompareCharArraysWithHexError(
-        "uint16_t", buffer16, 2,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
-                                                            : little_endian16,
-        2);
-
-    uint16_t read_number16;
-    QuicheDataReader reader(buffer16, 2, GetParam().endianness);
-    reader.ReadUInt16(&read_number16);
-    EXPECT_EQ(in_memory16, read_number16);
-  }
-
-  {
-    uint64_t in_memory16 = 0x0000000000001122;
-    QuicheDataWriter writer(2, buffer16, GetParam().endianness);
-    writer.WriteBytesToUInt64(2, in_memory16);
-    test::CompareCharArraysWithHexError(
-        "uint16_t", buffer16, 2,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
-                                                            : little_endian16,
-        2);
-
-    uint64_t read_number16;
-    QuicheDataReader reader(buffer16, 2, GetParam().endianness);
-    reader.ReadBytesToUInt64(2, &read_number16);
-    EXPECT_EQ(in_memory16, read_number16);
-  }
-}
-
-TEST_P(QuicheDataWriterTest, Write24BitUnsignedIntegers) {
-  char little_endian24[] = {0x33, 0x22, 0x11};
-  char big_endian24[] = {0x11, 0x22, 0x33};
-  char buffer24[3];
-  uint64_t in_memory24 = 0x0000000000112233;
-  QuicheDataWriter writer(3, buffer24, GetParam().endianness);
-  writer.WriteBytesToUInt64(3, in_memory24);
-  test::CompareCharArraysWithHexError(
-      "uint24", buffer24, 3,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
-                                                          : little_endian24,
-      3);
-
-  uint64_t read_number24;
-  QuicheDataReader reader(buffer24, 3, GetParam().endianness);
-  reader.ReadBytesToUInt64(3, &read_number24);
-  EXPECT_EQ(in_memory24, read_number24);
-}
-
-TEST_P(QuicheDataWriterTest, Write32BitUnsignedIntegers) {
-  char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
-  char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
-  char buffer32[4];
-  {
-    uint32_t in_memory32 = 0x11223344;
-    QuicheDataWriter writer(4, buffer32, GetParam().endianness);
-    writer.WriteUInt32(in_memory32);
-    test::CompareCharArraysWithHexError(
-        "uint32_t", buffer32, 4,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
-                                                            : little_endian32,
-        4);
-
-    uint32_t read_number32;
-    QuicheDataReader reader(buffer32, 4, GetParam().endianness);
-    reader.ReadUInt32(&read_number32);
-    EXPECT_EQ(in_memory32, read_number32);
-  }
-
-  {
-    uint64_t in_memory32 = 0x11223344;
-    QuicheDataWriter writer(4, buffer32, GetParam().endianness);
-    writer.WriteBytesToUInt64(4, in_memory32);
-    test::CompareCharArraysWithHexError(
-        "uint32_t", buffer32, 4,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
-                                                            : little_endian32,
-        4);
-
-    uint64_t read_number32;
-    QuicheDataReader reader(buffer32, 4, GetParam().endianness);
-    reader.ReadBytesToUInt64(4, &read_number32);
-    EXPECT_EQ(in_memory32, read_number32);
-  }
-}
-
-TEST_P(QuicheDataWriterTest, Write40BitUnsignedIntegers) {
-  uint64_t in_memory40 = 0x0000001122334455;
-  char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
-  char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
-  char buffer40[5];
-  QuicheDataWriter writer(5, buffer40, GetParam().endianness);
-  writer.WriteBytesToUInt64(5, in_memory40);
-  test::CompareCharArraysWithHexError(
-      "uint40", buffer40, 5,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
-                                                          : little_endian40,
-      5);
-
-  uint64_t read_number40;
-  QuicheDataReader reader(buffer40, 5, GetParam().endianness);
-  reader.ReadBytesToUInt64(5, &read_number40);
-  EXPECT_EQ(in_memory40, read_number40);
-}
-
-TEST_P(QuicheDataWriterTest, Write48BitUnsignedIntegers) {
-  uint64_t in_memory48 = 0x0000112233445566;
-  char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
-  char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
-  char buffer48[6];
-  QuicheDataWriter writer(6, buffer48, GetParam().endianness);
-  writer.WriteBytesToUInt64(6, in_memory48);
-  test::CompareCharArraysWithHexError(
-      "uint48", buffer48, 6,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
-                                                          : little_endian48,
-      6);
-
-  uint64_t read_number48;
-  QuicheDataReader reader(buffer48, 6, GetParam().endianness);
-  reader.ReadBytesToUInt64(6., &read_number48);
-  EXPECT_EQ(in_memory48, read_number48);
-}
-
-TEST_P(QuicheDataWriterTest, Write56BitUnsignedIntegers) {
-  uint64_t in_memory56 = 0x0011223344556677;
-  char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
-  char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
-  char buffer56[7];
-  QuicheDataWriter writer(7, buffer56, GetParam().endianness);
-  writer.WriteBytesToUInt64(7, in_memory56);
-  test::CompareCharArraysWithHexError(
-      "uint56", buffer56, 7,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
-                                                          : little_endian56,
-      7);
-
-  uint64_t read_number56;
-  QuicheDataReader reader(buffer56, 7, GetParam().endianness);
-  reader.ReadBytesToUInt64(7, &read_number56);
-  EXPECT_EQ(in_memory56, read_number56);
-}
-
-TEST_P(QuicheDataWriterTest, Write64BitUnsignedIntegers) {
-  uint64_t in_memory64 = 0x1122334455667788;
-  unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
-                                     0x44, 0x33, 0x22, 0x11};
-  unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
-                                  0x55, 0x66, 0x77, 0x88};
-  char buffer64[8];
-  QuicheDataWriter writer(8, buffer64, GetParam().endianness);
-  writer.WriteBytesToUInt64(8, in_memory64);
-  test::CompareCharArraysWithHexError(
-      "uint64_t", buffer64, 8,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
-          ? AsChars(big_endian64)
-          : AsChars(little_endian64),
-      8);
-
-  uint64_t read_number64;
-  QuicheDataReader reader(buffer64, 8, GetParam().endianness);
-  reader.ReadBytesToUInt64(8, &read_number64);
-  EXPECT_EQ(in_memory64, read_number64);
-
-  QuicheDataWriter writer2(8, buffer64, GetParam().endianness);
-  writer2.WriteUInt64(in_memory64);
-  test::CompareCharArraysWithHexError(
-      "uint64_t", buffer64, 8,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
-          ? AsChars(big_endian64)
-          : AsChars(little_endian64),
-      8);
-  read_number64 = 0u;
-  QuicheDataReader reader2(buffer64, 8, GetParam().endianness);
-  reader2.ReadUInt64(&read_number64);
-  EXPECT_EQ(in_memory64, read_number64);
-}
-
-TEST_P(QuicheDataWriterTest, WriteIntegers) {
-  char buf[43];
-  uint8_t i8 = 0x01;
-  uint16_t i16 = 0x0123;
-  uint32_t i32 = 0x01234567;
-  uint64_t i64 = 0x0123456789ABCDEF;
-  QuicheDataWriter writer(46, buf, GetParam().endianness);
-  for (size_t i = 0; i < 10; ++i) {
-    switch (i) {
-      case 0u:
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 1u:
-        EXPECT_TRUE(writer.WriteUInt8(i8));
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 2u:
-        EXPECT_TRUE(writer.WriteUInt16(i16));
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 3u:
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 4u:
-        EXPECT_TRUE(writer.WriteUInt32(i32));
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 5u:
-      case 6u:
-      case 7u:
-      case 8u:
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      default:
-        EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
-    }
-  }
-
-  QuicheDataReader reader(buf, 46, GetParam().endianness);
-  for (size_t i = 0; i < 10; ++i) {
-    uint8_t read8;
-    uint16_t read16;
-    uint32_t read32;
-    uint64_t read64;
-    switch (i) {
-      case 0u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0u, read64);
-        break;
-      case 1u:
-        EXPECT_TRUE(reader.ReadUInt8(&read8));
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(i8, read8);
-        EXPECT_EQ(0xEFu, read64);
-        break;
-      case 2u:
-        EXPECT_TRUE(reader.ReadUInt16(&read16));
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(i16, read16);
-        EXPECT_EQ(0xCDEFu, read64);
-        break;
-      case 3u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0xABCDEFu, read64);
-        break;
-      case 4u:
-        EXPECT_TRUE(reader.ReadUInt32(&read32));
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(i32, read32);
-        EXPECT_EQ(0x89ABCDEFu, read64);
-        break;
-      case 5u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x6789ABCDEFu, read64);
-        break;
-      case 6u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x456789ABCDEFu, read64);
-        break;
-      case 7u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x23456789ABCDEFu, read64);
-        break;
-      case 8u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x0123456789ABCDEFu, read64);
-        break;
-      default:
-        EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
-    }
-  }
-}
-
-TEST_P(QuicheDataWriterTest, WriteBytes) {
-  char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
-  char buf[ABSL_ARRAYSIZE(bytes)];
-  QuicheDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
-  EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
-  for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
-    EXPECT_EQ(bytes[i], buf[i]);
-  }
-}
-
-TEST_P(QuicheDataWriterTest, Seek) {
-  char buffer[3] = {};
-  QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                          GetParam().endianness);
-  EXPECT_TRUE(writer.WriteUInt8(42));
-  EXPECT_TRUE(writer.Seek(1));
-  EXPECT_TRUE(writer.WriteUInt8(3));
-
-  char expected[] = {42, 0, 3};
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
-    EXPECT_EQ(buffer[i], expected[i]);
-  }
-}
-
-TEST_P(QuicheDataWriterTest, SeekTooFarFails) {
-  char buffer[20];
-
-  // Check that one can seek to the end of the writer, but not past.
-  {
-    QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                            GetParam().endianness);
-    EXPECT_TRUE(writer.Seek(20));
-    EXPECT_FALSE(writer.Seek(1));
-  }
-
-  // Seeking several bytes past the end fails.
-  {
-    QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                            GetParam().endianness);
-    EXPECT_FALSE(writer.Seek(100));
-  }
-
-  // Seeking so far that arithmetic overflow could occur also fails.
-  {
-    QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                            GetParam().endianness);
-    EXPECT_TRUE(writer.Seek(10));
-    EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
-  }
-}
-
-TEST_P(QuicheDataWriterTest, PayloadReads) {
-  char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-  char expected_first_read[4] = {1, 2, 3, 4};
-  char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-  QuicheDataReader reader(buffer, sizeof(buffer));
-  absl::string_view previously_read_payload1 = reader.PreviouslyReadPayload();
-  EXPECT_TRUE(previously_read_payload1.empty());
-  char first_read_buffer[4] = {};
-  EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
-  test::CompareCharArraysWithHexError(
-      "first read", first_read_buffer, sizeof(first_read_buffer),
-      expected_first_read, sizeof(expected_first_read));
-  absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
-  test::CompareCharArraysWithHexError(
-      "peeked_remaining_payload", peeked_remaining_payload.data(),
-      peeked_remaining_payload.length(), expected_remaining,
-      sizeof(expected_remaining));
-  absl::string_view full_payload = reader.FullPayload();
-  test::CompareCharArraysWithHexError("full_payload", full_payload.data(),
-                                      full_payload.length(), buffer,
-                                      sizeof(buffer));
-  absl::string_view previously_read_payload2 = reader.PreviouslyReadPayload();
-  test::CompareCharArraysWithHexError(
-      "previously_read_payload2", previously_read_payload2.data(),
-      previously_read_payload2.length(), first_read_buffer,
-      sizeof(first_read_buffer));
-  absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
-  test::CompareCharArraysWithHexError(
-      "read_remaining_payload", read_remaining_payload.data(),
-      read_remaining_payload.length(), expected_remaining,
-      sizeof(expected_remaining));
-  EXPECT_TRUE(reader.IsDoneReading());
-  absl::string_view full_payload2 = reader.FullPayload();
-  test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(),
-                                      full_payload2.length(), buffer,
-                                      sizeof(buffer));
-  absl::string_view previously_read_payload3 = reader.PreviouslyReadPayload();
-  test::CompareCharArraysWithHexError(
-      "previously_read_payload3", previously_read_payload3.data(),
-      previously_read_payload3.length(), buffer, sizeof(buffer));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/quiche_endian.h b/common/quiche_endian.h
deleted file mode 100644
index 032e2da..0000000
--- a/common/quiche_endian.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_ENDIAN_H_
-#define QUICHE_COMMON_QUICHE_ENDIAN_H_
-
-#include <algorithm>
-#include <cstdint>
-#include <type_traits>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-enum Endianness {
-  NETWORK_BYTE_ORDER,  // big endian
-  HOST_BYTE_ORDER      // little endian
-};
-
-// Provide utility functions that convert from/to network order (big endian)
-// to/from host order (little endian).
-class QUICHE_EXPORT_PRIVATE QuicheEndian {
- public:
-  // Convert |x| from host order (little endian) to network order (big endian).
-#if defined(__clang__) || \
-    (defined(__GNUC__) && \
-     ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
-  static uint16_t HostToNet16(uint16_t x) { return __builtin_bswap16(x); }
-  static uint32_t HostToNet32(uint32_t x) { return __builtin_bswap32(x); }
-  static uint64_t HostToNet64(uint64_t x) { return __builtin_bswap64(x); }
-#else
-  static uint16_t HostToNet16(uint16_t x) { return PortableByteSwap(x); }
-  static uint32_t HostToNet32(uint32_t x) { return PortableByteSwap(x); }
-  static uint64_t HostToNet64(uint64_t x) { return PortableByteSwap(x); }
-#endif
-
-  // Convert |x| from network order (big endian) to host order (little endian).
-  static uint16_t NetToHost16(uint16_t x) { return HostToNet16(x); }
-  static uint32_t NetToHost32(uint32_t x) { return HostToNet32(x); }
-  static uint64_t NetToHost64(uint64_t x) { return HostToNet64(x); }
-
-  // Left public for tests.
-  template <typename T>
-  static T PortableByteSwap(T input) {
-    static_assert(std::is_unsigned<T>::value, "T has to be uintNN_t");
-    union {
-      T number;
-      char bytes[sizeof(T)];
-    } value;
-    value.number = input;
-    std::reverse(std::begin(value.bytes), std::end(value.bytes));
-    return value.number;
-  }
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_ENDIAN_H_
diff --git a/common/quiche_endian_test.cc b/common/quiche_endian_test.cc
deleted file mode 100644
index 6f6bc82..0000000
--- a/common/quiche_endian_test.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_endian.h"
-
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-const uint16_t k16BitTestData = 0xaabb;
-const uint16_t k16BitSwappedTestData = 0xbbaa;
-const uint32_t k32BitTestData = 0xaabbccdd;
-const uint32_t k32BitSwappedTestData = 0xddccbbaa;
-const uint64_t k64BitTestData = 0xaabbccdd44332211;
-const uint64_t k64BitSwappedTestData = 0x11223344ddccbbaa;
-
-class QuicheEndianTest : public QuicheTest {};
-
-// Test portable version.  Since we normally compile with either GCC or Clang,
-// it will very rarely used otherwise.
-TEST_F(QuicheEndianTest, Portable) {
-  EXPECT_EQ(k16BitSwappedTestData,
-            QuicheEndian::PortableByteSwap(k16BitTestData));
-  EXPECT_EQ(k32BitSwappedTestData,
-            QuicheEndian::PortableByteSwap(k32BitTestData));
-  EXPECT_EQ(k64BitSwappedTestData,
-            QuicheEndian::PortableByteSwap(k64BitTestData));
-}
-
-TEST_F(QuicheEndianTest, HostToNet) {
-  EXPECT_EQ(k16BitSwappedTestData,
-            quiche::QuicheEndian::HostToNet16(k16BitTestData));
-  EXPECT_EQ(k32BitSwappedTestData,
-            quiche::QuicheEndian::HostToNet32(k32BitTestData));
-  EXPECT_EQ(k64BitSwappedTestData,
-            quiche::QuicheEndian::HostToNet64(k64BitTestData));
-}
-
-TEST_F(QuicheEndianTest, NetToHost) {
-  EXPECT_EQ(k16BitTestData,
-            quiche::QuicheEndian::NetToHost16(k16BitSwappedTestData));
-  EXPECT_EQ(k32BitTestData,
-            quiche::QuicheEndian::NetToHost32(k32BitSwappedTestData));
-  EXPECT_EQ(k64BitTestData,
-            quiche::QuicheEndian::NetToHost64(k64BitSwappedTestData));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/quiche_linked_hash_map.h b/common/quiche_linked_hash_map.h
deleted file mode 100644
index e8aafc4..0000000
--- a/common/quiche_linked_hash_map.h
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a simplistic insertion-ordered map.  It behaves similarly to an STL
-// map, but only implements a small subset of the map's methods.  Internally, we
-// just keep a map and a list going in parallel.
-//
-// This class provides no thread safety guarantees, beyond what you would
-// normally see with std::list.
-//
-// Iterators point into the list and should be stable in the face of
-// mutations, except for an iterator pointing to an element that was just
-// deleted.
-
-#ifndef QUICHE_COMMON_QUICHE_LINKED_HASH_MAP_H_
-#define QUICHE_COMMON_QUICHE_LINKED_HASH_MAP_H_
-
-#include <functional>
-#include <list>
-#include <tuple>
-#include <type_traits>
-#include <utility>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/hash/hash.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-
-// This holds a list of pair<Key, Value> items.  This list is what gets
-// traversed, and it's iterators from this list that we return from
-// begin/end/find.
-//
-// We also keep a set<list::iterator> for find.  Since std::list is a
-// doubly-linked list, the iterators should remain stable.
-
-// QUICHE_NO_EXPORT comments suppress erroneous presubmit failures.
-template <class Key,                      // QUICHE_NO_EXPORT
-          class Value,                    // QUICHE_NO_EXPORT
-          class Hash = absl::Hash<Key>,   // QUICHE_NO_EXPORT
-          class Eq = std::equal_to<Key>>  // QUICHE_NO_EXPORT
-class QuicheLinkedHashMap {               // QUICHE_NO_EXPORT
- private:
-  typedef std::list<std::pair<Key, Value>> ListType;
-  typedef absl::flat_hash_map<Key, typename ListType::iterator, Hash, Eq>
-      MapType;
-
- public:
-  typedef typename ListType::iterator iterator;
-  typedef typename ListType::reverse_iterator reverse_iterator;
-  typedef typename ListType::const_iterator const_iterator;
-  typedef typename ListType::const_reverse_iterator const_reverse_iterator;
-  typedef typename MapType::key_type key_type;
-  typedef typename ListType::value_type value_type;
-  typedef typename ListType::size_type size_type;
-
-  QuicheLinkedHashMap() = default;
-  explicit QuicheLinkedHashMap(size_type bucket_count) : map_(bucket_count) {}
-
-  QuicheLinkedHashMap(const QuicheLinkedHashMap& other) = delete;
-  QuicheLinkedHashMap& operator=(const QuicheLinkedHashMap& other) = delete;
-  QuicheLinkedHashMap(QuicheLinkedHashMap&& other) = default;
-  QuicheLinkedHashMap& operator=(QuicheLinkedHashMap&& other) = default;
-
-  // Returns an iterator to the first (insertion-ordered) element.  Like a map,
-  // this can be dereferenced to a pair<Key, Value>.
-  iterator begin() { return list_.begin(); }
-  const_iterator begin() const { return list_.begin(); }
-
-  // Returns an iterator beyond the last element.
-  iterator end() { return list_.end(); }
-  const_iterator end() const { return list_.end(); }
-
-  // Returns an iterator to the last (insertion-ordered) element.  Like a map,
-  // this can be dereferenced to a pair<Key, Value>.
-  reverse_iterator rbegin() { return list_.rbegin(); }
-  const_reverse_iterator rbegin() const { return list_.rbegin(); }
-
-  // Returns an iterator beyond the first element.
-  reverse_iterator rend() { return list_.rend(); }
-  const_reverse_iterator rend() const { return list_.rend(); }
-
-  // Front and back accessors common to many stl containers.
-
-  // Returns the earliest-inserted element
-  const value_type& front() const { return list_.front(); }
-
-  // Returns the earliest-inserted element.
-  value_type& front() { return list_.front(); }
-
-  // Returns the most-recently-inserted element.
-  const value_type& back() const { return list_.back(); }
-
-  // Returns the most-recently-inserted element.
-  value_type& back() { return list_.back(); }
-
-  // Clears the map of all values.
-  void clear() {
-    map_.clear();
-    list_.clear();
-  }
-
-  // Returns true iff the map is empty.
-  bool empty() const { return list_.empty(); }
-
-  // Removes the first element from the list.
-  void pop_front() { erase(begin()); }
-
-  // Erases values with the provided key.  Returns the number of elements
-  // erased.  In this implementation, this will be 0 or 1.
-  size_type erase(const Key& key) {
-    typename MapType::iterator found = map_.find(key);
-    if (found == map_.end()) {
-      return 0;
-    }
-
-    list_.erase(found->second);
-    map_.erase(found);
-
-    return 1;
-  }
-
-  // Erases the item that 'position' points to. Returns an iterator that points
-  // to the item that comes immediately after the deleted item in the list, or
-  // end().
-  // If the provided iterator is invalid or there is inconsistency between the
-  // map and list, a QUICHE_CHECK() error will occur.
-  iterator erase(iterator position) {
-    typename MapType::iterator found = map_.find(position->first);
-    QUICHE_CHECK(found->second == position)
-        << "Inconsistent iterator for map and list, or the iterator is "
-           "invalid.";
-
-    map_.erase(found);
-    return list_.erase(position);
-  }
-
-  // Erases all the items in the range [first, last).  Returns an iterator that
-  // points to the item that comes immediately after the last deleted item in
-  // the list, or end().
-  iterator erase(iterator first, iterator last) {
-    while (first != last && first != end()) {
-      first = erase(first);
-    }
-    return first;
-  }
-
-  // Finds the element with the given key.  Returns an iterator to the
-  // value found, or to end() if the value was not found.  Like a map, this
-  // iterator points to a pair<Key, Value>.
-  iterator find(const Key& key) {
-    typename MapType::iterator found = map_.find(key);
-    if (found == map_.end()) {
-      return end();
-    }
-    return found->second;
-  }
-
-  const_iterator find(const Key& key) const {
-    typename MapType::const_iterator found = map_.find(key);
-    if (found == map_.end()) {
-      return end();
-    }
-    return found->second;
-  }
-
-  bool contains(const Key& key) const { return find(key) != end(); }
-
-  // Returns the value mapped to key, or an inserted iterator to that position
-  // in the map.
-  Value& operator[](const key_type& key) {
-    return (*((this->insert(std::make_pair(key, Value()))).first)).second;
-  }
-
-  // Inserts an element into the map
-  std::pair<iterator, bool> insert(const std::pair<Key, Value>& pair) {
-    return InsertInternal(pair);
-  }
-
-  // Inserts an element into the map
-  std::pair<iterator, bool> insert(std::pair<Key, Value>&& pair) {
-    return InsertInternal(std::move(pair));
-  }
-
-  // Derive size_ from map_, as list::size might be O(N).
-  size_type size() const { return map_.size(); }
-
-  template <typename... Args>
-  std::pair<iterator, bool> emplace(Args&&... args) {
-    ListType node_donor;
-    auto node_pos =
-        node_donor.emplace(node_donor.end(), std::forward<Args>(args)...);
-    const auto& k = node_pos->first;
-    auto ins = map_.insert({k, node_pos});
-    if (!ins.second) {
-      return {ins.first->second, false};
-    }
-    list_.splice(list_.end(), node_donor, node_pos);
-    return {ins.first->second, true};
-  }
-
-  void swap(QuicheLinkedHashMap& other) {
-    map_.swap(other.map_);
-    list_.swap(other.list_);
-  }
-
- private:
-  template <typename U>
-  std::pair<iterator, bool> InsertInternal(U&& pair) {
-    auto insert_result = map_.try_emplace(pair.first);
-    auto map_iter = insert_result.first;
-
-    // If the map already contains this key, return a pair with an iterator to
-    // it, and false indicating that we didn't insert anything.
-    if (!insert_result.second) {
-      return {map_iter->second, false};
-    }
-
-    // Otherwise, insert into the list, and set value in map.
-    auto list_iter = list_.insert(list_.end(), std::forward<U>(pair));
-    map_iter->second = list_iter;
-
-    return {list_iter, true};
-  }
-
-  // The map component, used for speedy lookups
-  MapType map_;
-
-  // The list component, used for maintaining insertion order
-  ListType list_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_LINKED_HASH_MAP_H_
diff --git a/common/quiche_linked_hash_map_test.cc b/common/quiche_linked_hash_map_test.cc
deleted file mode 100644
index dab6085..0000000
--- a/common/quiche_linked_hash_map_test.cc
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Tests QuicheLinkedHashMap.
-
-#include "common/quiche_linked_hash_map.h"
-
-#include <memory>
-#include <utility>
-
-#include "common/platform/api/quiche_test.h"
-
-using testing::Pair;
-using testing::Pointee;
-using testing::UnorderedElementsAre;
-
-namespace quiche {
-namespace test {
-
-// Tests that move constructor works.
-TEST(LinkedHashMapTest, Move) {
-  // Use unique_ptr as an example of a non-copyable type.
-  QuicheLinkedHashMap<int, std::unique_ptr<int>> m;
-  m[2] = std::make_unique<int>(12);
-  m[3] = std::make_unique<int>(13);
-  QuicheLinkedHashMap<int, std::unique_ptr<int>> n = std::move(m);
-  EXPECT_THAT(n,
-              UnorderedElementsAre(Pair(2, Pointee(12)), Pair(3, Pointee(13))));
-}
-
-TEST(LinkedHashMapTest, CanEmplaceMoveOnly) {
-  QuicheLinkedHashMap<int, std::unique_ptr<int>> m;
-  struct Data {
-    int k, v;
-  };
-  const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
-  for (const auto& kv : data) {
-    m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
-              std::make_tuple(new int{kv.v}));
-  }
-  EXPECT_TRUE(m.contains(2));
-  auto found = m.find(2);
-  ASSERT_TRUE(found != m.end());
-  EXPECT_EQ(234, *found->second);
-}
-
-struct NoCopy {
-  explicit NoCopy(int x) : x(x) {}
-  NoCopy(const NoCopy&) = delete;
-  NoCopy& operator=(const NoCopy&) = delete;
-  NoCopy(NoCopy&&) = delete;
-  NoCopy& operator=(NoCopy&&) = delete;
-  int x;
-};
-
-TEST(LinkedHashMapTest, CanEmplaceNoMoveNoCopy) {
-  QuicheLinkedHashMap<int, NoCopy> m;
-  struct Data {
-    int k, v;
-  };
-  const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
-  for (const auto& kv : data) {
-    m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
-              std::make_tuple(kv.v));
-  }
-  EXPECT_TRUE(m.contains(2));
-  auto found = m.find(2);
-  ASSERT_TRUE(found != m.end());
-  EXPECT_EQ(234, found->second.x);
-}
-
-TEST(LinkedHashMapTest, ConstKeys) {
-  QuicheLinkedHashMap<int, int> m;
-  m.insert(std::make_pair(1, 2));
-  // Test that keys are const in iteration.
-  std::pair<int, int>& p = *m.begin();
-  EXPECT_EQ(1, p.first);
-}
-
-// Tests that iteration from begin() to end() works
-TEST(LinkedHashMapTest, Iteration) {
-  QuicheLinkedHashMap<int, int> m;
-  EXPECT_TRUE(m.begin() == m.end());
-
-  m.insert(std::make_pair(2, 12));
-  m.insert(std::make_pair(1, 11));
-  m.insert(std::make_pair(3, 13));
-
-  QuicheLinkedHashMap<int, int>::iterator i = m.begin();
-  ASSERT_TRUE(m.begin() == i);
-  ASSERT_TRUE(m.end() != i);
-  EXPECT_EQ(2, i->first);
-  EXPECT_EQ(12, i->second);
-
-  ++i;
-  ASSERT_TRUE(m.end() != i);
-  EXPECT_EQ(1, i->first);
-  EXPECT_EQ(11, i->second);
-
-  ++i;
-  ASSERT_TRUE(m.end() != i);
-  EXPECT_EQ(3, i->first);
-  EXPECT_EQ(13, i->second);
-
-  ++i;  // Should be the end of the line.
-  ASSERT_TRUE(m.end() == i);
-}
-
-// Tests that reverse iteration from rbegin() to rend() works
-TEST(LinkedHashMapTest, ReverseIteration) {
-  QuicheLinkedHashMap<int, int> m;
-  EXPECT_TRUE(m.rbegin() == m.rend());
-
-  m.insert(std::make_pair(2, 12));
-  m.insert(std::make_pair(1, 11));
-  m.insert(std::make_pair(3, 13));
-
-  QuicheLinkedHashMap<int, int>::reverse_iterator i = m.rbegin();
-  ASSERT_TRUE(m.rbegin() == i);
-  ASSERT_TRUE(m.rend() != i);
-  EXPECT_EQ(3, i->first);
-  EXPECT_EQ(13, i->second);
-
-  ++i;
-  ASSERT_TRUE(m.rend() != i);
-  EXPECT_EQ(1, i->first);
-  EXPECT_EQ(11, i->second);
-
-  ++i;
-  ASSERT_TRUE(m.rend() != i);
-  EXPECT_EQ(2, i->first);
-  EXPECT_EQ(12, i->second);
-
-  ++i;  // Should be the end of the line.
-  ASSERT_TRUE(m.rend() == i);
-}
-
-// Tests that clear() works
-TEST(LinkedHashMapTest, Clear) {
-  QuicheLinkedHashMap<int, int> m;
-  m.insert(std::make_pair(2, 12));
-  m.insert(std::make_pair(1, 11));
-  m.insert(std::make_pair(3, 13));
-
-  ASSERT_EQ(3u, m.size());
-
-  m.clear();
-
-  EXPECT_EQ(0u, m.size());
-
-  m.clear();  // Make sure we can call it on an empty map.
-
-  EXPECT_EQ(0u, m.size());
-}
-
-// Tests that size() works.
-TEST(LinkedHashMapTest, Size) {
-  QuicheLinkedHashMap<int, int> m;
-  EXPECT_EQ(0u, m.size());
-  m.insert(std::make_pair(2, 12));
-  EXPECT_EQ(1u, m.size());
-  m.insert(std::make_pair(1, 11));
-  EXPECT_EQ(2u, m.size());
-  m.insert(std::make_pair(3, 13));
-  EXPECT_EQ(3u, m.size());
-  m.clear();
-  EXPECT_EQ(0u, m.size());
-}
-
-// Tests empty()
-TEST(LinkedHashMapTest, Empty) {
-  QuicheLinkedHashMap<int, int> m;
-  ASSERT_TRUE(m.empty());
-  m.insert(std::make_pair(2, 12));
-  ASSERT_FALSE(m.empty());
-  m.clear();
-  ASSERT_TRUE(m.empty());
-}
-
-TEST(LinkedHashMapTest, Erase) {
-  QuicheLinkedHashMap<int, int> m;
-  ASSERT_EQ(0u, m.size());
-  EXPECT_EQ(0u, m.erase(2));  // Nothing to erase yet
-
-  m.insert(std::make_pair(2, 12));
-  ASSERT_EQ(1u, m.size());
-  EXPECT_EQ(1u, m.erase(2));
-  EXPECT_EQ(0u, m.size());
-
-  EXPECT_EQ(0u, m.erase(2));  // Make sure nothing bad happens if we repeat.
-  EXPECT_EQ(0u, m.size());
-}
-
-TEST(LinkedHashMapTest, Erase2) {
-  QuicheLinkedHashMap<int, int> m;
-  ASSERT_EQ(0u, m.size());
-  EXPECT_EQ(0u, m.erase(2));  // Nothing to erase yet
-
-  m.insert(std::make_pair(2, 12));
-  m.insert(std::make_pair(1, 11));
-  m.insert(std::make_pair(3, 13));
-  m.insert(std::make_pair(4, 14));
-  ASSERT_EQ(4u, m.size());
-
-  // Erase middle two
-  EXPECT_EQ(1u, m.erase(1));
-  EXPECT_EQ(1u, m.erase(3));
-
-  EXPECT_EQ(2u, m.size());
-
-  // Make sure we can still iterate over everything that's left.
-  QuicheLinkedHashMap<int, int>::iterator it = m.begin();
-  ASSERT_TRUE(it != m.end());
-  EXPECT_EQ(12, it->second);
-  ++it;
-  ASSERT_TRUE(it != m.end());
-  EXPECT_EQ(14, it->second);
-  ++it;
-  ASSERT_TRUE(it == m.end());
-
-  EXPECT_EQ(0u, m.erase(1));  // Make sure nothing bad happens if we repeat.
-  ASSERT_EQ(2u, m.size());
-
-  EXPECT_EQ(1u, m.erase(2));
-  EXPECT_EQ(1u, m.erase(4));
-  ASSERT_EQ(0u, m.size());
-
-  EXPECT_EQ(0u, m.erase(1));  // Make sure nothing bad happens if we repeat.
-  ASSERT_EQ(0u, m.size());
-}
-
-// Test that erase(iter,iter) and erase(iter) compile and work.
-TEST(LinkedHashMapTest, Erase3) {
-  QuicheLinkedHashMap<int, int> m;
-
-  m.insert(std::make_pair(1, 11));
-  m.insert(std::make_pair(2, 12));
-  m.insert(std::make_pair(3, 13));
-  m.insert(std::make_pair(4, 14));
-
-  // Erase middle two
-  QuicheLinkedHashMap<int, int>::iterator it2 = m.find(2);
-  QuicheLinkedHashMap<int, int>::iterator it4 = m.find(4);
-  EXPECT_EQ(m.erase(it2, it4), m.find(4));
-  EXPECT_EQ(2u, m.size());
-
-  // Make sure we can still iterate over everything that's left.
-  QuicheLinkedHashMap<int, int>::iterator it = m.begin();
-  ASSERT_TRUE(it != m.end());
-  EXPECT_EQ(11, it->second);
-  ++it;
-  ASSERT_TRUE(it != m.end());
-  EXPECT_EQ(14, it->second);
-  ++it;
-  ASSERT_TRUE(it == m.end());
-
-  // Erase first one using an iterator.
-  EXPECT_EQ(m.erase(m.begin()), m.find(4));
-
-  // Only the last element should be left.
-  it = m.begin();
-  ASSERT_TRUE(it != m.end());
-  EXPECT_EQ(14, it->second);
-  ++it;
-  ASSERT_TRUE(it == m.end());
-}
-
-TEST(LinkedHashMapTest, Insertion) {
-  QuicheLinkedHashMap<int, int> m;
-  ASSERT_EQ(0u, m.size());
-  std::pair<QuicheLinkedHashMap<int, int>::iterator, bool> result;
-
-  result = m.insert(std::make_pair(2, 12));
-  ASSERT_EQ(1u, m.size());
-  EXPECT_TRUE(result.second);
-  EXPECT_EQ(2, result.first->first);
-  EXPECT_EQ(12, result.first->second);
-
-  result = m.insert(std::make_pair(1, 11));
-  ASSERT_EQ(2u, m.size());
-  EXPECT_TRUE(result.second);
-  EXPECT_EQ(1, result.first->first);
-  EXPECT_EQ(11, result.first->second);
-
-  result = m.insert(std::make_pair(3, 13));
-  QuicheLinkedHashMap<int, int>::iterator result_iterator = result.first;
-  ASSERT_EQ(3u, m.size());
-  EXPECT_TRUE(result.second);
-  EXPECT_EQ(3, result.first->first);
-  EXPECT_EQ(13, result.first->second);
-
-  result = m.insert(std::make_pair(3, 13));
-  EXPECT_EQ(3u, m.size());
-  EXPECT_FALSE(result.second) << "No insertion should have occurred.";
-  EXPECT_TRUE(result_iterator == result.first)
-      << "Duplicate insertion should have given us the original iterator.";
-}
-
-static std::pair<int, int> Pair(int i, int j) {
-  return {i, j};
-}
-
-// Test front accessors.
-TEST(LinkedHashMapTest, Front) {
-  QuicheLinkedHashMap<int, int> m;
-
-  m.insert(std::make_pair(2, 12));
-  m.insert(std::make_pair(1, 11));
-  m.insert(std::make_pair(3, 13));
-
-  EXPECT_EQ(3u, m.size());
-  EXPECT_EQ(Pair(2, 12), m.front());
-  m.pop_front();
-  EXPECT_EQ(2u, m.size());
-  EXPECT_EQ(Pair(1, 11), m.front());
-  m.pop_front();
-  EXPECT_EQ(1u, m.size());
-  EXPECT_EQ(Pair(3, 13), m.front());
-  m.pop_front();
-  EXPECT_TRUE(m.empty());
-}
-
-TEST(LinkedHashMapTest, Find) {
-  QuicheLinkedHashMap<int, int> m;
-
-  EXPECT_TRUE(m.end() == m.find(1))
-      << "We shouldn't find anything in an empty map.";
-
-  m.insert(std::make_pair(2, 12));
-  EXPECT_TRUE(m.end() == m.find(1))
-      << "We shouldn't find an element that doesn't exist in the map.";
-
-  std::pair<QuicheLinkedHashMap<int, int>::iterator, bool> result =
-      m.insert(std::make_pair(1, 11));
-  ASSERT_TRUE(result.second);
-  ASSERT_TRUE(m.end() != result.first);
-  EXPECT_TRUE(result.first == m.find(1))
-      << "We should have found an element we know exists in the map.";
-  EXPECT_EQ(11, result.first->second);
-
-  // Check that a follow-up insertion doesn't affect our original
-  m.insert(std::make_pair(3, 13));
-  QuicheLinkedHashMap<int, int>::iterator it = m.find(1);
-  ASSERT_TRUE(m.end() != it);
-  EXPECT_EQ(11, it->second);
-
-  m.clear();
-  EXPECT_TRUE(m.end() == m.find(1))
-      << "We shouldn't find anything in a map that we've cleared.";
-}
-
-TEST(LinkedHashMapTest, Contains) {
-  QuicheLinkedHashMap<int, int> m;
-
-  EXPECT_FALSE(m.contains(1)) << "An empty map shouldn't contain anything.";
-
-  m.insert(std::make_pair(2, 12));
-  EXPECT_FALSE(m.contains(1))
-      << "The map shouldn't contain an element that doesn't exist.";
-
-  m.insert(std::make_pair(1, 11));
-  EXPECT_TRUE(m.contains(1))
-      << "The map should contain an element that we know exists.";
-
-  m.clear();
-  EXPECT_FALSE(m.contains(1))
-      << "A map that we've cleared shouldn't contain anything.";
-}
-
-TEST(LinkedHashMapTest, Swap) {
-  QuicheLinkedHashMap<int, int> m1;
-  QuicheLinkedHashMap<int, int> m2;
-  m1.insert(std::make_pair(1, 1));
-  m1.insert(std::make_pair(2, 2));
-  m2.insert(std::make_pair(3, 3));
-  ASSERT_EQ(2u, m1.size());
-  ASSERT_EQ(1u, m2.size());
-  m1.swap(m2);
-  ASSERT_EQ(1u, m1.size());
-  ASSERT_EQ(2u, m2.size());
-}
-
-TEST(LinkedHashMapTest, CustomHashAndEquality) {
-  struct CustomIntHash {
-    size_t operator()(int x) const { return x; }
-  };
-  QuicheLinkedHashMap<int, int, CustomIntHash> m;
-  m.insert(std::make_pair(1, 1));
-  EXPECT_TRUE(m.contains(1));
-  EXPECT_EQ(1, m[1]);
-}
-
-}  // namespace test
-}  // namespace quiche
diff --git a/common/quiche_mem_slice_storage.cc b/common/quiche_mem_slice_storage.cc
deleted file mode 100644
index d57cf76..0000000
--- a/common/quiche_mem_slice_storage.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_mem_slice_storage.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quiche {
-
-QuicheMemSliceStorage::QuicheMemSliceStorage(
-    const struct iovec* iov, int iov_count, QuicheBufferAllocator* allocator,
-    const quic::QuicByteCount max_slice_len) {
-  if (iov == nullptr) {
-    return;
-  }
-  quic::QuicByteCount write_len = 0;
-  for (int i = 0; i < iov_count; ++i) {
-    write_len += iov[i].iov_len;
-  }
-  QUICHE_DCHECK_LT(0u, write_len);
-
-  size_t io_offset = 0;
-  while (write_len > 0) {
-    size_t slice_len = std::min(write_len, max_slice_len);
-    QuicheBuffer buffer = QuicheBuffer::CopyFromIovec(allocator, iov, iov_count,
-                                                      io_offset, slice_len);
-    storage_.push_back(QuicheMemSlice(std::move(buffer)));
-    write_len -= slice_len;
-    io_offset += slice_len;
-  }
-}
-
-}  // namespace quiche
diff --git a/common/quiche_mem_slice_storage.h b/common/quiche_mem_slice_storage.h
deleted file mode 100644
index f30750d..0000000
--- a/common/quiche_mem_slice_storage.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_MEM_SLICE_STORAGE_H_
-#define QUICHE_COMMON_QUICHE_MEM_SLICE_STORAGE_H_
-
-#include <vector>
-
-#include "absl/types/span.h"
-#include "quic/core/quic_types.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_iovec.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quiche {
-
-// QuicheMemSliceStorage is a container class that store QuicheMemSlices for
-// further use cases such as turning into QuicheMemSliceSpan.
-class QUICHE_EXPORT_PRIVATE QuicheMemSliceStorage {
- public:
-  QuicheMemSliceStorage(const struct iovec* iov, int iov_count,
-                        QuicheBufferAllocator* allocator,
-                        const quic::QuicByteCount max_slice_len);
-
-  QuicheMemSliceStorage(const QuicheMemSliceStorage& other) = default;
-  QuicheMemSliceStorage& operator=(const QuicheMemSliceStorage& other) =
-      default;
-  QuicheMemSliceStorage(QuicheMemSliceStorage&& other) = default;
-  QuicheMemSliceStorage& operator=(QuicheMemSliceStorage&& other) = default;
-
-  ~QuicheMemSliceStorage() = default;
-
-  // Return a QuicheMemSliceSpan form of the storage.
-  absl::Span<QuicheMemSlice> ToSpan() { return absl::MakeSpan(storage_); }
-
- private:
-  std::vector<QuicheMemSlice> storage_;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_MEM_SLICE_STORAGE_H_
diff --git a/common/quiche_mem_slice_storage_test.cc b/common/quiche_mem_slice_storage_test.cc
deleted file mode 100644
index 15d8294..0000000
--- a/common/quiche_mem_slice_storage_test.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_mem_slice_storage.h"
-
-#include "common/platform/api/quiche_test.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quiche {
-namespace test {
-namespace {
-
-class QuicheMemSliceStorageImplTest : public QuicheTest {
- public:
-  QuicheMemSliceStorageImplTest() = default;
-};
-
-TEST_F(QuicheMemSliceStorageImplTest, EmptyIov) {
-  QuicheMemSliceStorage storage(nullptr, 0, nullptr, 1024);
-  EXPECT_TRUE(storage.ToSpan().empty());
-}
-
-TEST_F(QuicheMemSliceStorageImplTest, SingleIov) {
-  SimpleBufferAllocator allocator;
-  std::string body(3, 'c');
-  struct iovec iov = {const_cast<char*>(body.data()), body.length()};
-  QuicheMemSliceStorage storage(&iov, 1, &allocator, 1024);
-  auto span = storage.ToSpan();
-  EXPECT_EQ("ccc", span[0].AsStringView());
-  EXPECT_NE(static_cast<const void*>(span[0].data()), body.data());
-}
-
-TEST_F(QuicheMemSliceStorageImplTest, MultipleIovInSingleSlice) {
-  SimpleBufferAllocator allocator;
-  std::string body1(3, 'a');
-  std::string body2(4, 'b');
-  struct iovec iov[] = {{const_cast<char*>(body1.data()), body1.length()},
-                        {const_cast<char*>(body2.data()), body2.length()}};
-
-  QuicheMemSliceStorage storage(iov, 2, &allocator, 1024);
-  auto span = storage.ToSpan();
-  EXPECT_EQ("aaabbbb", span[0].AsStringView());
-}
-
-TEST_F(QuicheMemSliceStorageImplTest, MultipleIovInMultipleSlice) {
-  SimpleBufferAllocator allocator;
-  std::string body1(4, 'a');
-  std::string body2(4, 'b');
-  struct iovec iov[] = {{const_cast<char*>(body1.data()), body1.length()},
-                        {const_cast<char*>(body2.data()), body2.length()}};
-
-  QuicheMemSliceStorage storage(iov, 2, &allocator, 4);
-  auto span = storage.ToSpan();
-  EXPECT_EQ("aaaa", span[0].AsStringView());
-  EXPECT_EQ("bbbb", span[1].AsStringView());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quiche
diff --git a/common/quiche_text_utils.cc b/common/quiche_text_utils.cc
deleted file mode 100644
index 263c97e..0000000
--- a/common/quiche_text_utils.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_text_utils.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-
-namespace quiche {
-
-// static
-void QuicheTextUtils::Base64Encode(const uint8_t* data,
-                                   size_t data_len,
-                                   std::string* output) {
-  absl::Base64Escape(std::string(reinterpret_cast<const char*>(data), data_len),
-                     output);
-  // Remove padding.
-  size_t len = output->size();
-  if (len >= 2) {
-    if ((*output)[len - 1] == '=') {
-      len--;
-      if ((*output)[len - 1] == '=') {
-        len--;
-      }
-      output->resize(len);
-    }
-  }
-}
-
-// static
-absl::optional<std::string> QuicheTextUtils::Base64Decode(
-    absl::string_view input) {
-  std::string output;
-  if (!absl::Base64Unescape(input, &output)) {
-    return absl::nullopt;
-  }
-  return output;
-}
-
-// static
-std::string QuicheTextUtils::HexDump(absl::string_view binary_data) {
-  const int kBytesPerLine = 16;  // Maximum bytes dumped per line.
-  int offset = 0;
-  const char* p = binary_data.data();
-  int bytes_remaining = binary_data.size();
-  std::string output;
-  while (bytes_remaining > 0) {
-    const int line_bytes = std::min(bytes_remaining, kBytesPerLine);
-    absl::StrAppendFormat(&output, "0x%04x:  ", offset);
-    for (int i = 0; i < kBytesPerLine; ++i) {
-      if (i < line_bytes) {
-        absl::StrAppendFormat(&output, "%02x",
-                              static_cast<unsigned char>(p[i]));
-      } else {
-        absl::StrAppend(&output, "  ");
-      }
-      if (i % 2) {
-        absl::StrAppend(&output, " ");
-      }
-    }
-    absl::StrAppend(&output, " ");
-    for (int i = 0; i < line_bytes; ++i) {
-      // Replace non-printable characters and 0x20 (space) with '.'
-      output += absl::ascii_isgraph(p[i]) ? p[i] : '.';
-    }
-
-    bytes_remaining -= line_bytes;
-    offset += line_bytes;
-    p += line_bytes;
-    absl::StrAppend(&output, "\n");
-  }
-  return output;
-}
-
-}  // namespace quiche
diff --git a/common/quiche_text_utils.h b/common/quiche_text_utils.h
deleted file mode 100644
index 3909f65..0000000
--- a/common/quiche_text_utils.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_TEXT_UTILS_H_
-#define QUICHE_COMMON_QUICHE_TEXT_UTILS_H_
-
-#include <string>
-
-#include "absl/hash/hash.h"
-#include "absl/strings/ascii.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace quiche {
-
-struct QUICHE_EXPORT_PRIVATE StringPieceCaseHash {
-  size_t operator()(absl::string_view data) const {
-    std::string lower = absl::AsciiStrToLower(data);
-    absl::Hash<absl::string_view> hasher;
-    return hasher(lower);
-  }
-};
-
-struct QUICHE_EXPORT_PRIVATE StringPieceCaseEqual {
-  bool operator()(absl::string_view piece1, absl::string_view piece2) const {
-    return absl::EqualsIgnoreCase(piece1, piece2);
-  }
-};
-
-// Various utilities for manipulating text.
-class QUICHE_EXPORT_PRIVATE QuicheTextUtils {
- public:
-  // Returns a new string in which |data| has been converted to lower case.
-  static std::string ToLower(absl::string_view data) {
-    return absl::AsciiStrToLower(data);
-  }
-
-  // Removes leading and trailing whitespace from |data|.
-  static void RemoveLeadingAndTrailingWhitespace(absl::string_view* data) {
-    *data = absl::StripAsciiWhitespace(*data);
-  }
-
-  // Base64 encodes with no padding |data_len| bytes of |data| into |output|.
-  static void Base64Encode(const uint8_t* data,
-                           size_t data_len,
-                           std::string* output);
-
-  // Decodes a base64-encoded |input|.  Returns nullopt when the input is
-  // invalid.
-  static absl::optional<std::string> Base64Decode(absl::string_view input);
-
-  // Returns a string containing hex and ASCII representations of |binary|,
-  // side-by-side in the style of hexdump. Non-printable characters will be
-  // printed as '.' in the ASCII output.
-  // For example, given the input "Hello, QUIC!\01\02\03\04", returns:
-  // "0x0000:  4865 6c6c 6f2c 2051 5549 4321 0102 0304  Hello,.QUIC!...."
-  static std::string HexDump(absl::string_view binary_data);
-
-  // Returns true if |data| contains any uppercase characters.
-  static bool ContainsUpperCase(absl::string_view data) {
-    return std::any_of(data.begin(), data.end(), absl::ascii_isupper);
-  }
-
-  // Returns true if |data| contains only decimal digits.
-  static bool IsAllDigits(absl::string_view data) {
-    return std::all_of(data.begin(), data.end(), absl::ascii_isdigit);
-  }
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_TEXT_UTILS_H_
diff --git a/common/quiche_text_utils_test.cc b/common/quiche_text_utils_test.cc
deleted file mode 100644
index 5c10cbf..0000000
--- a/common/quiche_text_utils_test.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/quiche_text_utils.h"
-
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace test {
-
-TEST(QuicheTextUtilsTest, ToLower) {
-  EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("LOWER"));
-  EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("lower"));
-  EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("lOwEr"));
-  EXPECT_EQ("123", quiche::QuicheTextUtils::ToLower("123"));
-  EXPECT_EQ("", quiche::QuicheTextUtils::ToLower(""));
-}
-
-TEST(QuicheTextUtilsTest, RemoveLeadingAndTrailingWhitespace) {
-  std::string input;
-
-  for (auto* input : {"text", " text", "  text", "text ", "text  ", " text ",
-                      "  text  ", "\r\n\ttext", "text\n\r\t"}) {
-    absl::string_view piece(input);
-    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&piece);
-    EXPECT_EQ("text", piece);
-  }
-}
-
-TEST(QuicheTextUtilsTest, HexDump) {
-  // Verify output for empty input.
-  EXPECT_EQ("", quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("")));
-  // Verify output of the HexDump method is as expected.
-  char packet[] = {
-      0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x51, 0x55, 0x49, 0x43, 0x21,
-      0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
-      0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x6c,
-      0x6f, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74,
-      0x6f, 0x20, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69,
-      0x70, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x6f, 0x66,
-      0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x01, 0x02, 0x03, 0x00,
-  };
-  EXPECT_EQ(
-      quiche::QuicheTextUtils::HexDump(packet),
-      "0x0000:  4865 6c6c 6f2c 2051 5549 4321 2054 6869  Hello,.QUIC!.Thi\n"
-      "0x0010:  7320 7374 7269 6e67 2073 686f 756c 6420  s.string.should.\n"
-      "0x0020:  6265 206c 6f6e 6720 656e 6f75 6768 2074  be.long.enough.t\n"
-      "0x0030:  6f20 7370 616e 206d 756c 7469 706c 6520  o.span.multiple.\n"
-      "0x0040:  6c69 6e65 7320 6f66 206f 7574 7075 742e  lines.of.output.\n"
-      "0x0050:  0102 03                                  ...\n");
-  // Verify that 0x21 and 0x7e are printable, 0x20 and 0x7f are not.
-  EXPECT_EQ(
-      "0x0000:  2021 7e7f                                .!~.\n",
-      quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("20217e7f")));
-  // Verify that values above numeric_limits<unsigned char>::max() are formatted
-  // properly on platforms where char is unsigned.
-  EXPECT_EQ("0x0000:  90aa ff                                  ...\n",
-            quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("90aaff")));
-}
-
-TEST(QuicheTextUtilsTest, Base64Encode) {
-  std::string output;
-  std::string input = "Hello";
-  quiche::QuicheTextUtils::Base64Encode(
-      reinterpret_cast<const uint8_t*>(input.data()), input.length(), &output);
-  EXPECT_EQ("SGVsbG8", output);
-
-  input =
-      "Hello, QUIC! This string should be long enough to span"
-      "multiple lines of output\n";
-  quiche::QuicheTextUtils::Base64Encode(
-      reinterpret_cast<const uint8_t*>(input.data()), input.length(), &output);
-  EXPECT_EQ(
-      "SGVsbG8sIFFVSUMhIFRoaXMgc3RyaW5nIHNob3VsZCBiZSBsb25n"
-      "IGVub3VnaCB0byBzcGFubXVsdGlwbGUgbGluZXMgb2Ygb3V0cHV0Cg",
-      output);
-}
-
-TEST(QuicheTextUtilsTest, ContainsUpperCase) {
-  EXPECT_FALSE(quiche::QuicheTextUtils::ContainsUpperCase("abc"));
-  EXPECT_FALSE(quiche::QuicheTextUtils::ContainsUpperCase(""));
-  EXPECT_FALSE(quiche::QuicheTextUtils::ContainsUpperCase("123"));
-  EXPECT_TRUE(quiche::QuicheTextUtils::ContainsUpperCase("ABC"));
-  EXPECT_TRUE(quiche::QuicheTextUtils::ContainsUpperCase("aBc"));
-}
-
-}  // namespace test
-}  // namespace quiche
diff --git a/common/simple_buffer_allocator.cc b/common/simple_buffer_allocator.cc
deleted file mode 100644
index 64501a1..0000000
--- a/common/simple_buffer_allocator.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/simple_buffer_allocator.h"
-
-namespace quiche {
-
-char* SimpleBufferAllocator::New(size_t size) {
-  return new char[size];
-}
-
-char* SimpleBufferAllocator::New(size_t size, bool /* flag_enable */) {
-  return New(size);
-}
-
-void SimpleBufferAllocator::Delete(char* buffer) {
-  delete[] buffer;
-}
-
-}  // namespace quiche
diff --git a/common/simple_buffer_allocator.h b/common/simple_buffer_allocator.h
deleted file mode 100644
index 586c0f3..0000000
--- a/common/simple_buffer_allocator.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_SIMPLE_BUFFER_ALLOCATOR_H_
-#define QUICHE_COMMON_QUICHE_SIMPLE_BUFFER_ALLOCATOR_H_
-
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quiche {
-
-// Provides buffer allocation using operators new[] and delete[] on char arrays.
-// Note that some of the QUICHE code relies on this being the case for deleting
-// new[]-allocated arrays from elsewhere.
-class QUICHE_EXPORT_PRIVATE SimpleBufferAllocator
-    : public QuicheBufferAllocator {
- public:
-  static SimpleBufferAllocator* Get() {
-    static SimpleBufferAllocator* singleton = new SimpleBufferAllocator();
-    return singleton;
-  }
-
-  char* New(size_t size) override;
-  char* New(size_t size, bool flag_enable) override;
-  void Delete(char* buffer) override;
-};
-
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_SIMPLE_BUFFER_ALLOCATOR_H_
diff --git a/common/simple_buffer_allocator_test.cc b/common/simple_buffer_allocator_test.cc
deleted file mode 100644
index e768bbb..0000000
--- a/common/simple_buffer_allocator_test.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/simple_buffer_allocator.h"
-
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace {
-
-TEST(SimpleBufferAllocatorTest, NewDelete) {
-  SimpleBufferAllocator alloc;
-  char* buf = alloc.New(4);
-  EXPECT_NE(nullptr, buf);
-  alloc.Delete(buf);
-}
-
-TEST(SimpleBufferAllocatorTest, DeleteNull) {
-  SimpleBufferAllocator alloc;
-  alloc.Delete(nullptr);
-}
-
-TEST(SimpleBufferAllocatorTest, MoveBuffersConstructor) {
-  SimpleBufferAllocator alloc;
-  QuicheBuffer buffer1(&alloc, 16);
-
-  EXPECT_NE(buffer1.data(), nullptr);
-  EXPECT_EQ(buffer1.size(), 16u);
-
-  QuicheBuffer buffer2(std::move(buffer1));
-  EXPECT_EQ(buffer1.data(), nullptr);  // NOLINT(bugprone-use-after-move)
-  EXPECT_EQ(buffer1.size(), 0u);
-  EXPECT_NE(buffer2.data(), nullptr);
-  EXPECT_EQ(buffer2.size(), 16u);
-}
-
-TEST(SimpleBufferAllocatorTest, MoveBuffersAssignment) {
-  SimpleBufferAllocator alloc;
-  QuicheBuffer buffer1(&alloc, 16);
-  QuicheBuffer buffer2;
-
-  EXPECT_NE(buffer1.data(), nullptr);
-  EXPECT_EQ(buffer1.size(), 16u);
-  EXPECT_EQ(buffer2.data(), nullptr);
-  EXPECT_EQ(buffer2.size(), 0u);
-
-  buffer2 = std::move(buffer1);
-  EXPECT_EQ(buffer1.data(), nullptr);  // NOLINT(bugprone-use-after-move)
-  EXPECT_EQ(buffer1.size(), 0u);
-  EXPECT_NE(buffer2.data(), nullptr);
-  EXPECT_EQ(buffer2.size(), 16u);
-}
-
-TEST(SimpleBufferAllocatorTest, CopyBuffer) {
-  SimpleBufferAllocator alloc;
-  const absl::string_view original = "Test string";
-  QuicheBuffer copy = QuicheBuffer::Copy(&alloc, original);
-  EXPECT_EQ(copy.AsStringView(), original);
-}
-
-}  // namespace
-}  // namespace quiche
diff --git a/common/structured_headers.cc b/common/structured_headers.cc
deleted file mode 100644
index aead6a3..0000000
--- a/common/structured_headers.cc
+++ /dev/null
@@ -1,909 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/structured_headers.h"
-
-#include <cmath>
-#include <string>
-#include <utility>
-
-#include "absl/algorithm/container.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/ascii.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-namespace structured_headers {
-
-namespace {
-
-#define DIGIT "0123456789"
-#define LCALPHA "abcdefghijklmnopqrstuvwxyz"
-#define UCALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-#define TCHAR DIGIT LCALPHA UCALPHA "!#$%&'*+-.^_`|~"
-// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.9
-constexpr char kTokenChars09[] = DIGIT UCALPHA LCALPHA "_-.:%*/";
-// https://www.rfc-editor.org/rfc/rfc8941.html#section-3.3.4
-constexpr char kTokenChars[] = TCHAR ":/";
-// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.1
-constexpr char kKeyChars09[] = DIGIT LCALPHA "_-";
-// https://www.rfc-editor.org/rfc/rfc8941.html#section-3.1.2
-constexpr char kKeyChars[] = DIGIT LCALPHA "_-.*";
-constexpr char kSP[] = " ";
-constexpr char kOWS[] = " \t";
-#undef DIGIT
-#undef LCALPHA
-#undef UCALPHA
-
-// https://www.rfc-editor.org/rfc/rfc8941.html#section-3.3.1
-constexpr int64_t kMaxInteger = 999'999'999'999'999L;
-constexpr int64_t kMinInteger = -999'999'999'999'999L;
-
-// Smallest value which is too large for an sh-decimal. This is the smallest
-// double which will round up to 1e12 when serialized, which exceeds the range
-// for sh-decimal. Any float less than this should round down. This behaviour is
-// verified by unit tests.
-constexpr double kTooLargeDecimal = 1e12 - 0.0005;
-
-// Removes characters in remove from the beginning of s.
-void StripLeft(absl::string_view& s, absl::string_view remove) {
-  size_t i = 0;
-  while (i < s.size() && memchr(remove.data(), s[i], remove.size())) {
-    ++i;
-  }
-  if (i > 0) s.remove_prefix(i);
-}
-
-// Parser for (a subset of) Structured Headers for HTTP defined in [SH09] and
-// [RFC8941]. [SH09] compatibility is retained for use by Web Packaging, and can
-// be removed once that spec is updated, and users have migrated to new headers.
-// [SH09] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09
-// [RFC8941] https://www.rfc-editor.org/rfc/rfc8941.html
-class StructuredHeaderParser {
- public:
-  enum DraftVersion {
-    kDraft09,
-    kFinal,
-  };
-  explicit StructuredHeaderParser(absl::string_view str, DraftVersion version)
-      : input_(str), version_(version) {
-    // [SH09] 4.2 Step 1.
-    // Discard any leading OWS from input_string.
-    // [RFC8941] 4.2 Step 2.
-    // Discard any leading SP characters from input_string.
-    SkipWhitespaces();
-  }
-  StructuredHeaderParser(const StructuredHeaderParser&) = delete;
-  StructuredHeaderParser& operator=(const StructuredHeaderParser&) = delete;
-
-  // Callers should call this after ReadSomething(), to check if parser has
-  // consumed all the input successfully.
-  bool FinishParsing() {
-    // [SH09] 4.2 Step 7.
-    // Discard any leading OWS from input_string.
-    // [RFC8941] 4.2 Step 6.
-    // Discard any leading SP characters from input_string.
-    SkipWhitespaces();
-    // [SH09] 4.2 Step 8. [RFC8941] 4.2 Step 7.
-    // If input_string is not empty, fail parsing.
-    return input_.empty();
-  }
-
-  // Parses a List of Lists ([SH09] 4.2.4).
-  absl::optional<ListOfLists> ReadListOfLists() {
-    QUICHE_CHECK_EQ(version_, kDraft09);
-    ListOfLists result;
-    while (true) {
-      std::vector<Item> inner_list;
-      while (true) {
-        absl::optional<Item> item(ReadBareItem());
-        if (!item) return absl::nullopt;
-        inner_list.push_back(std::move(*item));
-        SkipWhitespaces();
-        if (!ConsumeChar(';')) break;
-        SkipWhitespaces();
-      }
-      result.push_back(std::move(inner_list));
-      SkipWhitespaces();
-      if (!ConsumeChar(',')) break;
-      SkipWhitespaces();
-    }
-    return result;
-  }
-
-  // Parses a List ([RFC8941] 4.2.1).
-  absl::optional<List> ReadList() {
-    QUICHE_CHECK_EQ(version_, kFinal);
-    List members;
-    while (!input_.empty()) {
-      absl::optional<ParameterizedMember> member(ReadItemOrInnerList());
-      if (!member) return absl::nullopt;
-      members.push_back(std::move(*member));
-      SkipOWS();
-      if (input_.empty()) break;
-      if (!ConsumeChar(',')) return absl::nullopt;
-      SkipOWS();
-      if (input_.empty()) return absl::nullopt;
-    }
-    return members;
-  }
-
-  // Parses an Item ([RFC8941] 4.2.3).
-  absl::optional<ParameterizedItem> ReadItem() {
-    absl::optional<Item> item = ReadBareItem();
-    if (!item) return absl::nullopt;
-    absl::optional<Parameters> parameters = ReadParameters();
-    if (!parameters) return absl::nullopt;
-    return ParameterizedItem(std::move(*item), std::move(*parameters));
-  }
-
-  // Parses a bare Item ([RFC8941] 4.2.3.1, though this is also the algorithm
-  // for parsing an Item from [SH09] 4.2.7).
-  absl::optional<Item> ReadBareItem() {
-    if (input_.empty()) {
-      DVLOG(1) << "ReadBareItem: unexpected EOF";
-      return absl::nullopt;
-    }
-    switch (input_.front()) {
-      case '"':
-        return ReadString();
-      case '*':
-        if (version_ == kDraft09) return ReadByteSequence();
-        return ReadToken();
-      case ':':
-        if (version_ == kFinal) return ReadByteSequence();
-        return absl::nullopt;
-      case '?':
-        return ReadBoolean();
-      default:
-        if (input_.front() == '-' || absl::ascii_isdigit(input_.front()))
-          return ReadNumber();
-        if (absl::ascii_isalpha(input_.front())) return ReadToken();
-        return absl::nullopt;
-    }
-  }
-
-  // Parses a Dictionary ([RFC8941] 4.2.2).
-  absl::optional<Dictionary> ReadDictionary() {
-    QUICHE_CHECK_EQ(version_, kFinal);
-    Dictionary members;
-    while (!input_.empty()) {
-      absl::optional<std::string> key(ReadKey());
-      if (!key) return absl::nullopt;
-      absl::optional<ParameterizedMember> member;
-      if (ConsumeChar('=')) {
-        member = ReadItemOrInnerList();
-        if (!member) return absl::nullopt;
-      } else {
-        absl::optional<Parameters> parameters;
-        parameters = ReadParameters();
-        if (!parameters) return absl::nullopt;
-        member = ParameterizedMember{Item(true), std::move(*parameters)};
-      }
-      members[*key] = std::move(*member);
-      SkipOWS();
-      if (input_.empty()) break;
-      if (!ConsumeChar(',')) return absl::nullopt;
-      SkipOWS();
-      if (input_.empty()) return absl::nullopt;
-    }
-    return members;
-  }
-
-  // Parses a Parameterised List ([SH09] 4.2.5).
-  absl::optional<ParameterisedList> ReadParameterisedList() {
-    QUICHE_CHECK_EQ(version_, kDraft09);
-    ParameterisedList items;
-    while (true) {
-      absl::optional<ParameterisedIdentifier> item =
-          ReadParameterisedIdentifier();
-      if (!item) return absl::nullopt;
-      items.push_back(std::move(*item));
-      SkipWhitespaces();
-      if (!ConsumeChar(',')) return items;
-      SkipWhitespaces();
-    }
-  }
-
- private:
-  // Parses a Parameterised Identifier ([SH09] 4.2.6).
-  absl::optional<ParameterisedIdentifier> ReadParameterisedIdentifier() {
-    QUICHE_CHECK_EQ(version_, kDraft09);
-    absl::optional<Item> primary_identifier = ReadToken();
-    if (!primary_identifier) return absl::nullopt;
-
-    ParameterisedIdentifier::Parameters parameters;
-
-    SkipWhitespaces();
-    while (ConsumeChar(';')) {
-      SkipWhitespaces();
-
-      absl::optional<std::string> name = ReadKey();
-      if (!name) return absl::nullopt;
-
-      Item value;
-      if (ConsumeChar('=')) {
-        auto item = ReadBareItem();
-        if (!item) return absl::nullopt;
-        value = std::move(*item);
-      }
-      if (!parameters.emplace(*name, value).second) {
-        DVLOG(1) << "ReadParameterisedIdentifier: duplicated parameter: "
-                 << *name;
-        return absl::nullopt;
-      }
-      SkipWhitespaces();
-    }
-    return ParameterisedIdentifier(std::move(*primary_identifier),
-                                   std::move(parameters));
-  }
-
-  // Parses an Item or Inner List ([RFC8941] 4.2.1.1).
-  absl::optional<ParameterizedMember> ReadItemOrInnerList() {
-    QUICHE_CHECK_EQ(version_, kFinal);
-    std::vector<Item> member;
-    bool member_is_inner_list = (!input_.empty() && input_.front() == '(');
-    if (member_is_inner_list) {
-      return ReadInnerList();
-    } else {
-      auto item = ReadItem();
-      if (!item) return absl::nullopt;
-      return ParameterizedMember(std::move(item->item),
-                                 std::move(item->params));
-    }
-  }
-
-  // Parses Parameters ([RFC8941] 4.2.3.2)
-  absl::optional<Parameters> ReadParameters() {
-    Parameters parameters;
-    absl::flat_hash_set<std::string> keys;
-
-    while (ConsumeChar(';')) {
-      SkipWhitespaces();
-
-      absl::optional<std::string> name = ReadKey();
-      if (!name) return absl::nullopt;
-      bool is_duplicate_key = !keys.insert(*name).second;
-
-      Item value{true};
-      if (ConsumeChar('=')) {
-        auto item = ReadBareItem();
-        if (!item) return absl::nullopt;
-        value = std::move(*item);
-      }
-      if (is_duplicate_key) {
-        for (auto& param : parameters) {
-          if (param.first == name) {
-            param.second = std::move(value);
-            break;
-          }
-        }
-      } else {
-        parameters.emplace_back(std::move(*name), std::move(value));
-      }
-    }
-    return parameters;
-  }
-
-  // Parses an Inner List ([RFC8941] 4.2.1.2).
-  absl::optional<ParameterizedMember> ReadInnerList() {
-    QUICHE_CHECK_EQ(version_, kFinal);
-    if (!ConsumeChar('(')) return absl::nullopt;
-    std::vector<ParameterizedItem> inner_list;
-    while (true) {
-      SkipWhitespaces();
-      if (ConsumeChar(')')) {
-        absl::optional<Parameters> parameters;
-        parameters = ReadParameters();
-        if (!parameters) return absl::nullopt;
-        return ParameterizedMember(std::move(inner_list), true,
-                                   std::move(*parameters));
-      }
-      auto item = ReadItem();
-      if (!item) return absl::nullopt;
-      inner_list.push_back(std::move(*item));
-      if (input_.empty() || (input_.front() != ' ' && input_.front() != ')'))
-        return absl::nullopt;
-    }
-    QUICHE_NOTREACHED();
-    return absl::nullopt;
-  }
-
-  // Parses a Key ([SH09] 4.2.2, [RFC8941] 4.2.3.3).
-  absl::optional<std::string> ReadKey() {
-    if (version_ == kDraft09) {
-      if (input_.empty() || !absl::ascii_islower(input_.front())) {
-        LogParseError("ReadKey", "lcalpha");
-        return absl::nullopt;
-      }
-    } else {
-      if (input_.empty() ||
-          (!absl::ascii_islower(input_.front()) && input_.front() != '*')) {
-        LogParseError("ReadKey", "lcalpha | *");
-        return absl::nullopt;
-      }
-    }
-    const char* allowed_chars =
-        (version_ == kDraft09 ? kKeyChars09 : kKeyChars);
-    size_t len = input_.find_first_not_of(allowed_chars);
-    if (len == absl::string_view::npos) len = input_.size();
-    std::string key(input_.substr(0, len));
-    input_.remove_prefix(len);
-    return key;
-  }
-
-  // Parses a Token ([SH09] 4.2.10, [RFC8941] 4.2.6).
-  absl::optional<Item> ReadToken() {
-    if (input_.empty() ||
-        !(absl::ascii_isalpha(input_.front()) || input_.front() == '*')) {
-      LogParseError("ReadToken", "ALPHA");
-      return absl::nullopt;
-    }
-    size_t len = input_.find_first_not_of(version_ == kDraft09 ? kTokenChars09
-                                                               : kTokenChars);
-    if (len == absl::string_view::npos) len = input_.size();
-    std::string token(input_.substr(0, len));
-    input_.remove_prefix(len);
-    return Item(std::move(token), Item::kTokenType);
-  }
-
-  // Parses a Number ([SH09] 4.2.8, [RFC8941] 4.2.4).
-  absl::optional<Item> ReadNumber() {
-    bool is_negative = ConsumeChar('-');
-    bool is_decimal = false;
-    size_t decimal_position = 0;
-    size_t i = 0;
-    for (; i < input_.size(); ++i) {
-      if (i > 0 && input_[i] == '.' && !is_decimal) {
-        is_decimal = true;
-        decimal_position = i;
-        continue;
-      }
-      if (!absl::ascii_isdigit(input_[i])) break;
-    }
-    if (i == 0) {
-      LogParseError("ReadNumber", "DIGIT");
-      return absl::nullopt;
-    }
-    if (!is_decimal) {
-      // [RFC8941] restricts the range of integers further.
-      if (version_ == kFinal && i > 15) {
-        LogParseError("ReadNumber", "integer too long");
-        return absl::nullopt;
-      }
-    } else {
-      if (version_ != kFinal && i > 16) {
-        LogParseError("ReadNumber", "float too long");
-        return absl::nullopt;
-      }
-      if (version_ == kFinal && decimal_position > 12) {
-        LogParseError("ReadNumber", "decimal too long");
-        return absl::nullopt;
-      }
-      if (i - decimal_position > (version_ == kFinal ? 4 : 7)) {
-        LogParseError("ReadNumber", "too many digits after decimal");
-        return absl::nullopt;
-      }
-      if (i == decimal_position) {
-        LogParseError("ReadNumber", "no digits after decimal");
-        return absl::nullopt;
-      }
-    }
-    std::string output_number_string(input_.substr(0, i));
-    input_.remove_prefix(i);
-
-    if (is_decimal) {
-      // Convert to a 64-bit double, and return if the conversion is
-      // successful.
-      double f;
-      if (!absl::SimpleAtod(output_number_string, &f)) return absl::nullopt;
-      return Item(is_negative ? -f : f);
-    } else {
-      // Convert to a 64-bit signed integer, and return if the conversion is
-      // successful.
-      int64_t n;
-      if (!absl::SimpleAtoi(output_number_string, &n)) return absl::nullopt;
-      QUICHE_CHECK(version_ != kFinal ||
-                   (n <= kMaxInteger && n >= kMinInteger));
-      return Item(is_negative ? -n : n);
-    }
-  }
-
-  // Parses a String ([SH09] 4.2.9, [RFC8941] 4.2.5).
-  absl::optional<Item> ReadString() {
-    std::string s;
-    if (!ConsumeChar('"')) {
-      LogParseError("ReadString", "'\"'");
-      return absl::nullopt;
-    }
-    while (!ConsumeChar('"')) {
-      size_t i = 0;
-      for (; i < input_.size(); ++i) {
-        if (!absl::ascii_isprint(input_[i])) {
-          DVLOG(1) << "ReadString: non printable-ASCII character";
-          return absl::nullopt;
-        }
-        if (input_[i] == '"' || input_[i] == '\\') break;
-      }
-      if (i == input_.size()) {
-        DVLOG(1) << "ReadString: missing closing '\"'";
-        return absl::nullopt;
-      }
-      s.append(std::string(input_.substr(0, i)));
-      input_.remove_prefix(i);
-      if (ConsumeChar('\\')) {
-        if (input_.empty()) {
-          DVLOG(1) << "ReadString: backslash at string end";
-          return absl::nullopt;
-        }
-        if (input_[0] != '"' && input_[0] != '\\') {
-          DVLOG(1) << "ReadString: invalid escape";
-          return absl::nullopt;
-        }
-        s.push_back(input_.front());
-        input_.remove_prefix(1);
-      }
-    }
-    return s;
-  }
-
-  // Parses a Byte Sequence ([SH09] 4.2.11, [RFC8941] 4.2.7).
-  absl::optional<Item> ReadByteSequence() {
-    char delimiter = (version_ == kDraft09 ? '*' : ':');
-    if (!ConsumeChar(delimiter)) {
-      LogParseError("ReadByteSequence", "delimiter");
-      return absl::nullopt;
-    }
-    size_t len = input_.find(delimiter);
-    if (len == absl::string_view::npos) {
-      DVLOG(1) << "ReadByteSequence: missing closing delimiter";
-      return absl::nullopt;
-    }
-    std::string base64(input_.substr(0, len));
-    // Append the necessary padding characters.
-    base64.resize((base64.size() + 3) / 4 * 4, '=');
-
-    std::string binary;
-    if (!absl::Base64Unescape(base64, &binary)) {
-      DVLOG(1) << "ReadByteSequence: failed to decode base64: " << base64;
-      return absl::nullopt;
-    }
-    input_.remove_prefix(len);
-    ConsumeChar(delimiter);
-    return Item(std::move(binary), Item::kByteSequenceType);
-  }
-
-  // Parses a Boolean ([RFC8941] 4.2.8).
-  // Note that this only parses ?0 and ?1 forms from SH version 10+, not the
-  // previous ?F and ?T, which were not needed by any consumers of SH version 9.
-  absl::optional<Item> ReadBoolean() {
-    if (!ConsumeChar('?')) {
-      LogParseError("ReadBoolean", "'?'");
-      return absl::nullopt;
-    }
-    if (ConsumeChar('1')) {
-      return Item(true);
-    }
-    if (ConsumeChar('0')) {
-      return Item(false);
-    }
-    return absl::nullopt;
-  }
-
-  // There are several points in the specs where the handling of whitespace
-  // differs between Draft 9 and the final RFC. In those cases, Draft 9 allows
-  // any OWS character, while the RFC allows only a U+0020 SPACE.
-  void SkipWhitespaces() {
-    if (version_ == kDraft09) {
-      StripLeft(input_, kOWS);
-    } else {
-      StripLeft(input_, kSP);
-    }
-  }
-
-  void SkipOWS() { StripLeft(input_, kOWS); }
-
-  bool ConsumeChar(char expected) {
-    if (!input_.empty() && input_.front() == expected) {
-      input_.remove_prefix(1);
-      return true;
-    }
-    return false;
-  }
-
-  void LogParseError(const char* func, const char* expected) {
-    DVLOG(1) << func << ": " << expected << " expected, got "
-             << (input_.empty() ? "EOS"
-                                : "'" + std::string(input_.substr(0, 1)) + "'");
-  }
-
-  absl::string_view input_;
-  DraftVersion version_;
-};
-
-// Serializer for (a subset of) Structured Field Values for HTTP defined in
-// [RFC8941]. Note that this serializer does not attempt to support [SH09].
-class StructuredHeaderSerializer {
- public:
-  StructuredHeaderSerializer() = default;
-  ~StructuredHeaderSerializer() = default;
-  StructuredHeaderSerializer(const StructuredHeaderSerializer&) = delete;
-  StructuredHeaderSerializer& operator=(const StructuredHeaderSerializer&) =
-      delete;
-
-  std::string Output() { return output_.str(); }
-
-  // Serializes a List ([RFC8941] 4.1.1).
-  bool WriteList(const List& value) {
-    bool first = true;
-    for (const auto& member : value) {
-      if (!first) output_ << ", ";
-      if (!WriteParameterizedMember(member)) return false;
-      first = false;
-    }
-    return true;
-  }
-
-  // Serializes an Item ([RFC8941] 4.1.3).
-  bool WriteItem(const ParameterizedItem& value) {
-    if (!WriteBareItem(value.item)) return false;
-    return WriteParameters(value.params);
-  }
-
-  // Serializes an Item ([RFC8941] 4.1.3).
-  bool WriteBareItem(const Item& value) {
-    if (value.is_string()) {
-      // Serializes a String ([RFC8941] 4.1.6).
-      output_ << "\"";
-      for (const char& c : value.GetString()) {
-        if (!absl::ascii_isprint(c)) return false;
-        if (c == '\\' || c == '\"') output_ << "\\";
-        output_ << c;
-      }
-      output_ << "\"";
-      return true;
-    }
-    if (value.is_token()) {
-      // Serializes a Token ([RFC8941] 4.1.7).
-      if (value.GetString().empty() ||
-          !(absl::ascii_isalpha(value.GetString().front()) ||
-            value.GetString().front() == '*'))
-        return false;
-      if (value.GetString().find_first_not_of(kTokenChars) != std::string::npos)
-        return false;
-      output_ << value.GetString();
-      return true;
-    }
-    if (value.is_byte_sequence()) {
-      // Serializes a Byte Sequence ([RFC8941] 4.1.8).
-      output_ << ":";
-      output_ << absl::Base64Escape(value.GetString());
-      output_ << ":";
-      return true;
-    }
-    if (value.is_integer()) {
-      // Serializes an Integer ([RFC8941] 4.1.4).
-      if (value.GetInteger() > kMaxInteger || value.GetInteger() < kMinInteger)
-        return false;
-      output_ << value.GetInteger();
-      return true;
-    }
-    if (value.is_decimal()) {
-      // Serializes a Decimal ([RFC8941] 4.1.5).
-      double decimal_value = value.GetDecimal();
-      if (!std::isfinite(decimal_value) ||
-          fabs(decimal_value) >= kTooLargeDecimal)
-        return false;
-
-      // Handle sign separately to simplify the rest of the formatting.
-      if (decimal_value < 0) output_ << "-";
-      // Unconditionally take absolute value to ensure that -0 is serialized as
-      // "0.0", with no negative sign, as required by spec. (4.1.5, step 2).
-      decimal_value = fabs(decimal_value);
-      double remainder = fmod(decimal_value, 0.002);
-      if (remainder == 0.0005) {
-        // Value ended in exactly 0.0005, 0.0025, 0.0045, etc. Round down.
-        decimal_value -= 0.0005;
-      } else if (remainder == 0.0015) {
-        // Value ended in exactly 0.0015, 0.0035, 0,0055, etc. Round up.
-        decimal_value += 0.0005;
-      } else {
-        // Standard rounding will work in all other cases.
-        decimal_value = round(decimal_value * 1000.0) / 1000.0;
-      }
-
-      // Use standard library functions to write the decimal, and then truncate
-      // if necessary to conform to spec.
-
-      // Maximum is 12 integer digits, one decimal point, three fractional
-      // digits, and a null terminator.
-      char buffer[17];
-      absl::SNPrintF(buffer, std::size(buffer), "%#.3f", decimal_value);
-
-      // Strip any trailing 0s after the decimal point, but leave at least one
-      // digit after it in all cases. (So 1.230 becomes 1.23, but 1.000 becomes
-      // 1.0.)
-      absl::string_view formatted_number(buffer);
-      auto truncate_index = formatted_number.find_last_not_of('0');
-      if (formatted_number[truncate_index] == '.') truncate_index++;
-      output_ << formatted_number.substr(0, truncate_index + 1);
-      return true;
-    }
-    if (value.is_boolean()) {
-      // Serializes a Boolean ([RFC8941] 4.1.9).
-      output_ << (value.GetBoolean() ? "?1" : "?0");
-      return true;
-    }
-    return false;
-  }
-
-  // Serializes a Dictionary ([RFC8941] 4.1.2).
-  bool WriteDictionary(const Dictionary& value) {
-    bool first = true;
-    for (const auto& [dict_key, dict_value] : value) {
-      if (!first) output_ << ", ";
-      if (!WriteKey(dict_key)) return false;
-      first = false;
-      if (!dict_value.member_is_inner_list && !dict_value.member.empty() &&
-          dict_value.member.front().item.is_boolean() &&
-          dict_value.member.front().item.GetBoolean()) {
-        if (!WriteParameters(dict_value.params)) return false;
-      } else {
-        output_ << "=";
-        if (!WriteParameterizedMember(dict_value)) return false;
-      }
-    }
-    return true;
-  }
-
- private:
-  bool WriteParameterizedMember(const ParameterizedMember& value) {
-    // Serializes a parameterized member ([RFC8941] 4.1.1).
-    if (value.member_is_inner_list) {
-      if (!WriteInnerList(value.member)) return false;
-    } else {
-      QUICHE_CHECK_EQ(value.member.size(), 1UL);
-      if (!WriteItem(value.member[0])) return false;
-    }
-    return WriteParameters(value.params);
-  }
-
-  bool WriteInnerList(const std::vector<ParameterizedItem>& value) {
-    // Serializes an inner list ([RFC8941] 4.1.1.1).
-    output_ << "(";
-    bool first = true;
-    for (const ParameterizedItem& member : value) {
-      if (!first) output_ << " ";
-      if (!WriteItem(member)) return false;
-      first = false;
-    }
-    output_ << ")";
-    return true;
-  }
-
-  bool WriteParameters(const Parameters& value) {
-    // Serializes a parameter list ([RFC8941] 4.1.1.2).
-    for (const auto& param_name_and_value : value) {
-      const std::string& param_name = param_name_and_value.first;
-      const Item& param_value = param_name_and_value.second;
-      output_ << ";";
-      if (!WriteKey(param_name)) return false;
-      if (!param_value.is_null()) {
-        if (param_value.is_boolean() && param_value.GetBoolean()) continue;
-        output_ << "=";
-        if (!WriteBareItem(param_value)) return false;
-      }
-    }
-    return true;
-  }
-
-  bool WriteKey(const std::string& value) {
-    // Serializes a Key ([RFC8941] 4.1.1.3).
-    if (value.empty()) return false;
-    if (value.find_first_not_of(kKeyChars) != std::string::npos) return false;
-    if (!absl::ascii_islower(value[0]) && value[0] != '*') return false;
-    output_ << value;
-    return true;
-  }
-
-  std::ostringstream output_;
-};
-
-}  // namespace
-
-Item::Item() {}
-Item::Item(const std::string& value, Item::ItemType type)
-    : type_(type), string_value_(value) {}
-Item::Item(std::string&& value, Item::ItemType type)
-    : type_(type), string_value_(std::move(value)) {
-  QUICHE_CHECK(type_ == kStringType || type_ == kTokenType ||
-               type_ == kByteSequenceType);
-}
-Item::Item(const char* value, Item::ItemType type)
-    : Item(std::string(value), type) {}
-Item::Item(int64_t value) : type_(kIntegerType), integer_value_(value) {}
-Item::Item(double value) : type_(kDecimalType), decimal_value_(value) {}
-Item::Item(bool value) : type_(kBooleanType), boolean_value_(value) {}
-
-bool operator==(const Item& lhs, const Item& rhs) {
-  if (lhs.type_ != rhs.type_) return false;
-  switch (lhs.type_) {
-    case Item::kNullType:
-      return true;
-    case Item::kStringType:
-    case Item::kTokenType:
-    case Item::kByteSequenceType:
-      return lhs.string_value_ == rhs.string_value_;
-    case Item::kIntegerType:
-      return lhs.integer_value_ == rhs.integer_value_;
-    case Item::kDecimalType:
-      return lhs.decimal_value_ == rhs.decimal_value_;
-    case Item::kBooleanType:
-      return lhs.boolean_value_ == rhs.boolean_value_;
-  }
-  QUICHE_NOTREACHED();
-  return false;
-}
-
-ParameterizedItem::ParameterizedItem(const ParameterizedItem&) = default;
-ParameterizedItem& ParameterizedItem::operator=(const ParameterizedItem&) =
-    default;
-ParameterizedItem::ParameterizedItem(Item id, const Parameters& ps)
-    : item(std::move(id)), params(ps) {}
-ParameterizedItem::~ParameterizedItem() = default;
-
-ParameterizedMember::ParameterizedMember() = default;
-ParameterizedMember::ParameterizedMember(const ParameterizedMember&) = default;
-ParameterizedMember& ParameterizedMember::operator=(
-    const ParameterizedMember&) = default;
-ParameterizedMember::ParameterizedMember(std::vector<ParameterizedItem> id,
-                                         bool member_is_inner_list,
-                                         const Parameters& ps)
-    : member(std::move(id)),
-      member_is_inner_list(member_is_inner_list),
-      params(ps) {}
-ParameterizedMember::ParameterizedMember(std::vector<ParameterizedItem> id,
-                                         const Parameters& ps)
-    : member(std::move(id)), member_is_inner_list(true), params(ps) {}
-ParameterizedMember::ParameterizedMember(Item id, const Parameters& ps)
-    : member({{std::move(id), {}}}), member_is_inner_list(false), params(ps) {}
-ParameterizedMember::~ParameterizedMember() = default;
-
-ParameterisedIdentifier::ParameterisedIdentifier(
-    const ParameterisedIdentifier&) = default;
-ParameterisedIdentifier& ParameterisedIdentifier::operator=(
-    const ParameterisedIdentifier&) = default;
-ParameterisedIdentifier::ParameterisedIdentifier(Item id, const Parameters& ps)
-    : identifier(std::move(id)), params(ps) {}
-ParameterisedIdentifier::~ParameterisedIdentifier() = default;
-
-Dictionary::Dictionary() = default;
-Dictionary::Dictionary(const Dictionary&) = default;
-Dictionary::Dictionary(std::vector<DictionaryMember> members)
-    : members_(std::move(members)) {}
-Dictionary::~Dictionary() = default;
-std::vector<DictionaryMember>::iterator Dictionary::begin() {
-  return members_.begin();
-}
-std::vector<DictionaryMember>::const_iterator Dictionary::begin() const {
-  return members_.begin();
-}
-std::vector<DictionaryMember>::iterator Dictionary::end() {
-  return members_.end();
-}
-std::vector<DictionaryMember>::const_iterator Dictionary::end() const {
-  return members_.end();
-}
-ParameterizedMember& Dictionary::operator[](std::size_t idx) {
-  return members_[idx].second;
-}
-const ParameterizedMember& Dictionary::operator[](std::size_t idx) const {
-  return members_[idx].second;
-}
-ParameterizedMember& Dictionary::at(std::size_t idx) { return (*this)[idx]; }
-const ParameterizedMember& Dictionary::at(std::size_t idx) const {
-  return (*this)[idx];
-}
-ParameterizedMember& Dictionary::operator[](absl::string_view key) {
-  auto it = absl::c_find_if(
-      members_, [key](const auto& member) { return member.first == key; });
-  if (it != members_.end()) return it->second;
-  members_.push_back({std::string(key), ParameterizedMember()});
-  return members_.back().second;
-}
-ParameterizedMember& Dictionary::at(absl::string_view key) {
-  auto it = absl::c_find_if(
-      members_, [key](const auto& member) { return member.first == key; });
-  QUICHE_CHECK(it != members_.end()) << "Provided key not found in dictionary";
-  return it->second;
-}
-const ParameterizedMember& Dictionary::at(absl::string_view key) const {
-  auto it = absl::c_find_if(
-      members_, [key](const auto& member) { return member.first == key; });
-  QUICHE_CHECK(it != members_.end()) << "Provided key not found in dictionary";
-  return it->second;
-}
-bool Dictionary::empty() const { return members_.empty(); }
-std::size_t Dictionary::size() const { return members_.size(); }
-bool Dictionary::contains(absl::string_view key) const {
-  for (auto& member : members_) {
-    if (member.first == key) return true;
-  }
-  return false;
-}
-
-absl::optional<ParameterizedItem> ParseItem(absl::string_view str) {
-  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
-  absl::optional<ParameterizedItem> item = parser.ReadItem();
-  if (item && parser.FinishParsing()) return item;
-  return absl::nullopt;
-}
-
-absl::optional<Item> ParseBareItem(absl::string_view str) {
-  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
-  absl::optional<Item> item = parser.ReadBareItem();
-  if (item && parser.FinishParsing()) return item;
-  return absl::nullopt;
-}
-
-absl::optional<ParameterisedList> ParseParameterisedList(
-    absl::string_view str) {
-  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
-  absl::optional<ParameterisedList> param_list = parser.ReadParameterisedList();
-  if (param_list && parser.FinishParsing()) return param_list;
-  return absl::nullopt;
-}
-
-absl::optional<ListOfLists> ParseListOfLists(absl::string_view str) {
-  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
-  absl::optional<ListOfLists> list_of_lists = parser.ReadListOfLists();
-  if (list_of_lists && parser.FinishParsing()) return list_of_lists;
-  return absl::nullopt;
-}
-
-absl::optional<List> ParseList(absl::string_view str) {
-  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
-  absl::optional<List> list = parser.ReadList();
-  if (list && parser.FinishParsing()) return list;
-  return absl::nullopt;
-}
-
-absl::optional<Dictionary> ParseDictionary(const absl::string_view& str) {
-  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
-  absl::optional<Dictionary> dictionary = parser.ReadDictionary();
-  if (dictionary && parser.FinishParsing()) return dictionary;
-  return absl::nullopt;
-}
-
-absl::optional<std::string> SerializeItem(const Item& value) {
-  StructuredHeaderSerializer s;
-  if (s.WriteItem(ParameterizedItem(value, {}))) return s.Output();
-  return absl::nullopt;
-}
-
-absl::optional<std::string> SerializeItem(const ParameterizedItem& value) {
-  StructuredHeaderSerializer s;
-  if (s.WriteItem(value)) return s.Output();
-  return absl::nullopt;
-}
-
-absl::optional<std::string> SerializeList(const List& value) {
-  StructuredHeaderSerializer s;
-  if (s.WriteList(value)) return s.Output();
-  return absl::nullopt;
-}
-
-absl::optional<std::string> SerializeDictionary(const Dictionary& value) {
-  StructuredHeaderSerializer s;
-  if (s.WriteDictionary(value)) return s.Output();
-  return absl::nullopt;
-}
-
-}  // namespace structured_headers
-}  // namespace quiche
diff --git a/common/structured_headers.h b/common/structured_headers.h
deleted file mode 100644
index b5525db..0000000
--- a/common/structured_headers.h
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_STRUCTURED_HEADERS_H_
-#define QUICHE_COMMON_STRUCTURED_HEADERS_H_
-
-#include <algorithm>
-#include <map>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quiche {
-namespace structured_headers {
-
-// This file implements parsing of HTTP structured headers, as defined in
-// RFC8941 (https://www.rfc-editor.org/rfc/rfc8941.html). For compatibility with
-// the shipped implementation of Web Packaging, this file also supports a
-// previous revision of the standard, referred to here as "Draft 9".
-// (https://datatracker.ietf.org/doc/draft-ietf-httpbis-header-structure/09/)
-//
-// The major difference between the two revisions is in the various list
-// formats: Draft 9 describes "parameterised lists" and "lists-of-lists", while
-// the final RFC uses a single "list" syntax, whose members may be inner lists.
-// There should be no ambiguity, however, as the code which calls this parser
-// should be expecting only a single type for a given header.
-//
-// References within the code are tagged with either [SH09] or [RFC8941],
-// depending on which revision they refer to.
-//
-// Currently supported data types are:
-//  Item:
-//   integer: 123
-//   string: "abc"
-//   token: abc
-//   byte sequence: *YWJj*
-//  Parameterised list: abc_123;a=1;b=2; cdef_456, ghi;q="9";r="w"
-//  List-of-lists: "foo";"bar", "baz", "bat"; "one"
-//  List: "foo", "bar", "It was the best of times."
-//        ("foo" "bar"), ("baz"), ("bat" "one"), ()
-//        abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w
-//  Dictionary: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?0
-//
-// Functions are provided to parse each of these, which are intended to be
-// called with the complete value of an HTTP header (that is, any
-// sub-structure will be handled internally by the parser; the exported
-// functions are not intended to be called on partial header strings.) Input
-// values should be ASCII byte strings (non-ASCII characters should not be
-// present in Structured Header values, and will cause the entire header to fail
-// to parse.)
-
-class QUICHE_EXPORT_PRIVATE Item {
- public:
-  enum ItemType {
-    kNullType,
-    kIntegerType,
-    kDecimalType,
-    kStringType,
-    kTokenType,
-    kByteSequenceType,
-    kBooleanType
-  };
-  Item();
-  explicit Item(int64_t value);
-  explicit Item(double value);
-  explicit Item(bool value);
-
-  // Constructors for string-like items: Strings, Tokens and Byte Sequences.
-  Item(const char* value, Item::ItemType type = kStringType);
-  Item(const std::string& value, Item::ItemType type = kStringType);
-  Item(std::string&& value, Item::ItemType type = kStringType);
-
-  QUICHE_EXPORT_PRIVATE friend bool operator==(const Item& lhs,
-                                               const Item& rhs);
-  inline friend bool operator!=(const Item& lhs, const Item& rhs) {
-    return !(lhs == rhs);
-  }
-
-  bool is_null() const { return type_ == kNullType; }
-  bool is_integer() const { return type_ == kIntegerType; }
-  bool is_decimal() const { return type_ == kDecimalType; }
-  bool is_string() const { return type_ == kStringType; }
-  bool is_token() const { return type_ == kTokenType; }
-  bool is_byte_sequence() const { return type_ == kByteSequenceType; }
-  bool is_boolean() const { return type_ == kBooleanType; }
-
-  int64_t GetInteger() const {
-    QUICHE_CHECK_EQ(type_, kIntegerType);
-    return integer_value_;
-  }
-  double GetDecimal() const {
-    QUICHE_CHECK_EQ(type_, kDecimalType);
-    return decimal_value_;
-  }
-  bool GetBoolean() const {
-    QUICHE_CHECK_EQ(type_, kBooleanType);
-    return boolean_value_;
-  }
-  // TODO(iclelland): Split up accessors for String, Token and Byte Sequence.
-  const std::string& GetString() const {
-    QUICHE_CHECK(type_ == kStringType || type_ == kTokenType ||
-                 type_ == kByteSequenceType);
-    return string_value_;
-  }
-
-  ItemType Type() const { return type_; }
-
- private:
-  ItemType type_ = kNullType;
-  // TODO(iclelland): Make this class more memory-efficient, replacing the
-  // values here with a union or std::variant (when available).
-  int64_t integer_value_ = 0;
-  std::string string_value_;
-  double decimal_value_;
-  bool boolean_value_;
-};
-
-// Holds a ParameterizedIdentifier (draft 9 only). The contained Item must be a
-// Token, and there may be any number of parameters. Parameter ordering is not
-// significant.
-struct QUICHE_EXPORT_PRIVATE ParameterisedIdentifier {
-  using Parameters = std::map<std::string, Item>;
-
-  Item identifier;
-  Parameters params;
-
-  ParameterisedIdentifier(const ParameterisedIdentifier&);
-  ParameterisedIdentifier& operator=(const ParameterisedIdentifier&);
-  ParameterisedIdentifier(Item, const Parameters&);
-  ~ParameterisedIdentifier();
-};
-
-inline bool operator==(const ParameterisedIdentifier& lhs,
-                       const ParameterisedIdentifier& rhs) {
-  return std::tie(lhs.identifier, lhs.params) ==
-         std::tie(rhs.identifier, rhs.params);
-}
-
-using Parameters = std::vector<std::pair<std::string, Item>>;
-
-struct QUICHE_EXPORT_PRIVATE ParameterizedItem {
-  Item item;
-  Parameters params;
-
-  ParameterizedItem(const ParameterizedItem&);
-  ParameterizedItem& operator=(const ParameterizedItem&);
-  ParameterizedItem(Item, const Parameters&);
-  ~ParameterizedItem();
-};
-
-inline bool operator==(const ParameterizedItem& lhs,
-                       const ParameterizedItem& rhs) {
-  return std::tie(lhs.item, lhs.params) == std::tie(rhs.item, rhs.params);
-}
-
-inline bool operator!=(const ParameterizedItem& lhs,
-                       const ParameterizedItem& rhs) {
-  return !(lhs == rhs);
-}
-
-// Holds a ParameterizedMember, which may be either an single Item, or an Inner
-// List of ParameterizedItems, along with any number of parameters. Parameter
-// ordering is significant.
-struct QUICHE_EXPORT_PRIVATE ParameterizedMember {
-  std::vector<ParameterizedItem> member;
-  // If false, then |member| should only hold one Item.
-  bool member_is_inner_list = false;
-
-  Parameters params;
-
-  ParameterizedMember();
-  ParameterizedMember(const ParameterizedMember&);
-  ParameterizedMember& operator=(const ParameterizedMember&);
-  ParameterizedMember(std::vector<ParameterizedItem>, bool member_is_inner_list,
-                      const Parameters&);
-  // Shorthand constructor for a member which is an inner list.
-  ParameterizedMember(std::vector<ParameterizedItem>, const Parameters&);
-  // Shorthand constructor for a member which is a single Item.
-  ParameterizedMember(Item, const Parameters&);
-  ~ParameterizedMember();
-};
-
-inline bool operator==(const ParameterizedMember& lhs,
-                       const ParameterizedMember& rhs) {
-  return std::tie(lhs.member, lhs.member_is_inner_list, lhs.params) ==
-         std::tie(rhs.member, rhs.member_is_inner_list, rhs.params);
-}
-
-using DictionaryMember = std::pair<std::string, ParameterizedMember>;
-
-// Structured Headers RFC8941 Dictionary.
-class QUICHE_EXPORT_PRIVATE Dictionary {
- public:
-  using iterator = std::vector<DictionaryMember>::iterator;
-  using const_iterator = std::vector<DictionaryMember>::const_iterator;
-
-  Dictionary();
-  Dictionary(const Dictionary&);
-  explicit Dictionary(std::vector<DictionaryMember> members);
-  ~Dictionary();
-  Dictionary& operator=(const Dictionary&) = default;
-  iterator begin();
-  const_iterator begin() const;
-  iterator end();
-  const_iterator end() const;
-
-  // operator[](size_t) and at(size_t) will both abort the program in case of
-  // out of bounds access.
-  ParameterizedMember& operator[](std::size_t idx);
-  const ParameterizedMember& operator[](std::size_t idx) const;
-  ParameterizedMember& at(std::size_t idx);
-  const ParameterizedMember& at(std::size_t idx) const;
-
-  // Consistent with std::map, if |key| does not exist in the Dictionary, then
-  // operator[](absl::string_view) will create an entry for it, but at() will
-  // abort the entire program.
-  ParameterizedMember& operator[](absl::string_view key);
-  ParameterizedMember& at(absl::string_view key);
-  const ParameterizedMember& at(absl::string_view key) const;
-
-  bool empty() const;
-  std::size_t size() const;
-  bool contains(absl::string_view key) const;
-  friend bool operator==(const Dictionary& lhs, const Dictionary& rhs);
-  friend bool operator!=(const Dictionary& lhs, const Dictionary& rhs);
-
- private:
-  // Uses a vector to hold pairs of key and dictionary member. This makes
-  // look up by index and serialization much easier.
-  std::vector<DictionaryMember> members_;
-};
-
-inline bool operator==(const Dictionary& lhs, const Dictionary& rhs) {
-  return lhs.members_ == rhs.members_;
-}
-
-inline bool operator!=(const Dictionary& lhs, const Dictionary& rhs) {
-  return !(lhs == rhs);
-}
-
-// Structured Headers Draft 09 Parameterised List.
-using ParameterisedList = std::vector<ParameterisedIdentifier>;
-// Structured Headers Draft 09 List of Lists.
-using ListOfLists = std::vector<std::vector<Item>>;
-// Structured Headers RFC8941 List.
-using List = std::vector<ParameterizedMember>;
-
-// Returns the result of parsing the header value as an Item, if it can be
-// parsed as one, or nullopt if it cannot. Note that this uses the Draft 15
-// parsing rules, and so applies tighter range limits to integers.
-QUICHE_EXPORT_PRIVATE absl::optional<ParameterizedItem> ParseItem(
-    absl::string_view str);
-
-// Returns the result of parsing the header value as an Item with no parameters,
-// or nullopt if it cannot. Note that this uses the Draft 15 parsing rules, and
-// so applies tighter range limits to integers.
-QUICHE_EXPORT_PRIVATE absl::optional<Item> ParseBareItem(absl::string_view str);
-
-// Returns the result of parsing the header value as a Parameterised List, if it
-// can be parsed as one, or nullopt if it cannot. Note that parameter keys will
-// be returned as strings, which are guaranteed to be ASCII-encoded. List items,
-// as well as parameter values, will be returned as Items. This method uses the
-// Draft 09 parsing rules for Items, so integers have the 64-bit int range.
-// Structured-Headers Draft 09 only.
-QUICHE_EXPORT_PRIVATE absl::optional<ParameterisedList> ParseParameterisedList(
-    absl::string_view str);
-
-// Returns the result of parsing the header value as a List of Lists, if it can
-// be parsed as one, or nullopt if it cannot. Inner list items will be returned
-// as Items. This method uses the Draft 09 parsing rules for Items, so integers
-// have the 64-bit int range.
-// Structured-Headers Draft 09 only.
-QUICHE_EXPORT_PRIVATE absl::optional<ListOfLists> ParseListOfLists(
-    absl::string_view str);
-
-// Returns the result of parsing the header value as a general List, if it can
-// be parsed as one, or nullopt if it cannot.
-// Structured-Headers Draft 15 only.
-QUICHE_EXPORT_PRIVATE absl::optional<List> ParseList(absl::string_view str);
-
-// Returns the result of parsing the header value as a general Dictionary, if it
-// can be parsed as one, or nullopt if it cannot. Structured-Headers Draft 15
-// only.
-QUICHE_EXPORT_PRIVATE absl::optional<Dictionary> ParseDictionary(
-    const absl::string_view& str);
-
-// Serialization is implemented for Structured-Headers Draft 15 only.
-QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeItem(
-    const Item& value);
-QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeItem(
-    const ParameterizedItem& value);
-QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeList(
-    const List& value);
-QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeDictionary(
-    const Dictionary& value);
-
-}  // namespace structured_headers
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_STRUCTURED_HEADERS_H_
diff --git a/common/structured_headers_fuzzer.cc b/common/structured_headers_fuzzer.cc
deleted file mode 100644
index 2201881..0000000
--- a/common/structured_headers_fuzzer.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "absl/strings/string_view.h"
-#include "common/structured_headers.h"
-
-namespace quiche {
-namespace structured_headers {
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  absl::string_view input(reinterpret_cast<const char*>(data), size);
-  ParseItem(input);
-  ParseListOfLists(input);
-  ParseList(input);
-  ParseDictionary(input);
-  ParseParameterisedList(input);
-  return 0;
-}
-
-}  // namespace structured_headers
-}  // namespace quiche
diff --git a/common/structured_headers_generated_test.cc b/common/structured_headers_generated_test.cc
deleted file mode 100644
index f2f40b8..0000000
--- a/common/structured_headers_generated_test.cc
+++ /dev/null
@@ -1,3944 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/platform/api/quiche_test.h"
-#include "common/structured_headers.h"
-
-// This file contains tests cases for the Structured Header parser and
-// serializer, taken from the public test case repository at
-// https://github.com/httpwg/structured-field-tests. All of the tests are named,
-// so a given test case can be found in the JSON files in that repository by
-// searching for the test name. This file is generated, with the test cases
-// being automatically translated from the JSON source to C++ unit tests. Please
-// do not modify, as the contents will be overwritten when this is re-generated.
-
-// Generated on 2022-03-15 from structured-field-tests.git @
-// faed1f92942abd4fb5d61b1f9f0dc359f499f1d7.
-
-namespace quiche {
-namespace structured_headers {
-namespace {
-
-// Helpers to make test cases clearer
-
-Item Integer(int64_t value) { return Item(value); }
-
-std::pair<std::string, Item> BooleanParam(std::string key, bool value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> DoubleParam(std::string key, double value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> Param(std::string key, int64_t value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> Param(std::string key, std::string value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> TokenParam(std::string key, std::string value) {
-  return std::make_pair(key, Item(value, Item::kTokenType));
-}
-
-const struct ParameterizedItemTestCase {
-  const char* name;
-  const char* raw;
-  size_t raw_len;
-  const absl::optional<ParameterizedItem>
-      expected;           // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} parameterized_item_test_cases[] = {
-    // binary.json
-    {"basic binary",
-     ":aGVsbG8=:",
-     10,
-     {{Item("hello", Item::kByteSequenceType), {}}},
-     nullptr},
-    {"empty binary",
-     "::",
-     2,
-     {{Item("", Item::kByteSequenceType), {}}},
-     nullptr},
-    {"bad paddding",
-     ":aGVsbG8:",
-     9,
-     {{Item("hello", Item::kByteSequenceType), {}}},
-     ":aGVsbG8=:"},
-    {"bad end delimiter", ":aGVsbG8=", 9, absl::nullopt, nullptr},
-    {"extra whitespace", ":aGVsb G8=:", 11, absl::nullopt, nullptr},
-    {"extra chars", ":aGVsbG!8=:", 11, absl::nullopt, nullptr},
-    {"suffix chars", ":aGVsbG8=!:", 11, absl::nullopt, nullptr},
-    {"non-zero pad bits",
-     ":iZ==:",
-     6,
-     {{Item("\211", Item::kByteSequenceType), {}}},
-     ":iQ==:"},
-    {"non-ASCII binary",
-     ":/+Ah:",
-     6,
-     {{Item("\377\340!", Item::kByteSequenceType), {}}},
-     nullptr},
-    {"base64url binary", ":_-Ah:", 6, absl::nullopt, nullptr},
-    // boolean.json
-    {"basic true boolean", "?1", 2, {{Item(true), {}}}, nullptr},
-    {"basic false boolean", "?0", 2, {{Item(false), {}}}, nullptr},
-    {"unknown boolean", "?Q", 2, absl::nullopt, nullptr},
-    {"whitespace boolean", "? 1", 3, absl::nullopt, nullptr},
-    {"negative zero boolean", "?-0", 3, absl::nullopt, nullptr},
-    {"T boolean", "?T", 2, absl::nullopt, nullptr},
-    {"F boolean", "?F", 2, absl::nullopt, nullptr},
-    {"t boolean", "?t", 2, absl::nullopt, nullptr},
-    {"f boolean", "?f", 2, absl::nullopt, nullptr},
-    {"spelled-out True boolean", "?True", 5, absl::nullopt, nullptr},
-    {"spelled-out False boolean", "?False", 6, absl::nullopt, nullptr},
-    // examples.json
-    {"Foo-Example",
-     "2; foourl=\"https://foo.example.com/\"",
-     36,
-     {{Integer(2), {Param("foourl", "https://foo.example.com/")}}},
-     "2;foourl=\"https://foo.example.com/\""},
-    {"Example-IntHeader",
-     "1; a; b=?0",
-     10,
-     {{Integer(1), {BooleanParam("a", true), BooleanParam("b", false)}}},
-     "1;a;b=?0"},
-    {"Example-IntItemHeader", "5", 1, {{Integer(5), {}}}, nullptr},
-    {"Example-IntItemHeader (params)",
-     "5; foo=bar",
-     10,
-     {{Integer(5), {TokenParam("foo", "bar")}}},
-     "5;foo=bar"},
-    {"Example-IntegerHeader", "42", 2, {{Integer(42), {}}}, nullptr},
-    {"Example-FloatHeader", "4.5", 3, {{Item(4.500000), {}}}, nullptr},
-    {"Example-StringHeader",
-     "\"hello world\"",
-     13,
-     {{Item("hello world"), {}}},
-     nullptr},
-    {"Example-BinaryHdr",
-     ":cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==:",
-     46,
-     {{Item("pretend this is binary content.", Item::kByteSequenceType), {}}},
-     nullptr},
-    {"Example-BoolHdr", "?1", 2, {{Item(true), {}}}, nullptr},
-    // item.json
-    {"empty item", "", 0, absl::nullopt, nullptr},
-    {"leading space", " \t 1", 4, absl::nullopt, nullptr},
-    {"trailing space", "1 \t ", 4, absl::nullopt, nullptr},
-    {"leading and trailing space", "  1  ", 5, {{Integer(1), {}}}, "1"},
-    {"leading and trailing whitespace", "     1  ", 8, {{Integer(1), {}}}, "1"},
-    // number-generated.json
-    {"1 digits of zero", "0", 1, {{Integer(0), {}}}, "0"},
-    {"1 digit small integer", "1", 1, {{Integer(1), {}}}, nullptr},
-    {"1 digit large integer", "9", 1, {{Integer(9), {}}}, nullptr},
-    {"2 digits of zero", "00", 2, {{Integer(0), {}}}, "0"},
-    {"2 digit small integer", "11", 2, {{Integer(11), {}}}, nullptr},
-    {"2 digit large integer", "99", 2, {{Integer(99), {}}}, nullptr},
-    {"3 digits of zero", "000", 3, {{Integer(0), {}}}, "0"},
-    {"3 digit small integer", "111", 3, {{Integer(111), {}}}, nullptr},
-    {"3 digit large integer", "999", 3, {{Integer(999), {}}}, nullptr},
-    {"4 digits of zero", "0000", 4, {{Integer(0), {}}}, "0"},
-    {"4 digit small integer", "1111", 4, {{Integer(1111), {}}}, nullptr},
-    {"4 digit large integer", "9999", 4, {{Integer(9999), {}}}, nullptr},
-    {"5 digits of zero", "00000", 5, {{Integer(0), {}}}, "0"},
-    {"5 digit small integer", "11111", 5, {{Integer(11111), {}}}, nullptr},
-    {"5 digit large integer", "99999", 5, {{Integer(99999), {}}}, nullptr},
-    {"6 digits of zero", "000000", 6, {{Integer(0), {}}}, "0"},
-    {"6 digit small integer", "111111", 6, {{Integer(111111), {}}}, nullptr},
-    {"6 digit large integer", "999999", 6, {{Integer(999999), {}}}, nullptr},
-    {"7 digits of zero", "0000000", 7, {{Integer(0), {}}}, "0"},
-    {"7 digit small integer", "1111111", 7, {{Integer(1111111), {}}}, nullptr},
-    {"7 digit large integer", "9999999", 7, {{Integer(9999999), {}}}, nullptr},
-    {"8 digits of zero", "00000000", 8, {{Integer(0), {}}}, "0"},
-    {"8 digit small integer",
-     "11111111",
-     8,
-     {{Integer(11111111), {}}},
-     nullptr},
-    {"8 digit large integer",
-     "99999999",
-     8,
-     {{Integer(99999999), {}}},
-     nullptr},
-    {"9 digits of zero", "000000000", 9, {{Integer(0), {}}}, "0"},
-    {"9 digit small integer",
-     "111111111",
-     9,
-     {{Integer(111111111), {}}},
-     nullptr},
-    {"9 digit large integer",
-     "999999999",
-     9,
-     {{Integer(999999999), {}}},
-     nullptr},
-    {"10 digits of zero", "0000000000", 10, {{Integer(0), {}}}, "0"},
-    {"10 digit small integer",
-     "1111111111",
-     10,
-     {{Integer(1111111111), {}}},
-     nullptr},
-    {"10 digit large integer",
-     "9999999999",
-     10,
-     {{Integer(9999999999), {}}},
-     nullptr},
-    {"11 digits of zero", "00000000000", 11, {{Integer(0), {}}}, "0"},
-    {"11 digit small integer",
-     "11111111111",
-     11,
-     {{Integer(11111111111), {}}},
-     nullptr},
-    {"11 digit large integer",
-     "99999999999",
-     11,
-     {{Integer(99999999999), {}}},
-     nullptr},
-    {"12 digits of zero", "000000000000", 12, {{Integer(0), {}}}, "0"},
-    {"12 digit small integer",
-     "111111111111",
-     12,
-     {{Integer(111111111111), {}}},
-     nullptr},
-    {"12 digit large integer",
-     "999999999999",
-     12,
-     {{Integer(999999999999), {}}},
-     nullptr},
-    {"13 digits of zero", "0000000000000", 13, {{Integer(0), {}}}, "0"},
-    {"13 digit small integer",
-     "1111111111111",
-     13,
-     {{Integer(1111111111111), {}}},
-     nullptr},
-    {"13 digit large integer",
-     "9999999999999",
-     13,
-     {{Integer(9999999999999), {}}},
-     nullptr},
-    {"14 digits of zero", "00000000000000", 14, {{Integer(0), {}}}, "0"},
-    {"14 digit small integer",
-     "11111111111111",
-     14,
-     {{Integer(11111111111111), {}}},
-     nullptr},
-    {"14 digit large integer",
-     "99999999999999",
-     14,
-     {{Integer(99999999999999), {}}},
-     nullptr},
-    {"15 digits of zero", "000000000000000", 15, {{Integer(0), {}}}, "0"},
-    {"15 digit small integer",
-     "111111111111111",
-     15,
-     {{Integer(111111111111111), {}}},
-     nullptr},
-    {"15 digit large integer",
-     "999999999999999",
-     15,
-     {{Integer(999999999999999), {}}},
-     nullptr},
-    {"2 digit 0, 1 fractional small decimal",
-     "0.1",
-     3,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"2 digit, 1 fractional 0 decimal",
-     "1.0",
-     3,
-     {{Item(1.000000), {}}},
-     "1.0"},
-    {"2 digit, 1 fractional small decimal",
-     "1.1",
-     3,
-     {{Item(1.100000), {}}},
-     nullptr},
-    {"2 digit, 1 fractional large decimal",
-     "9.9",
-     3,
-     {{Item(9.900000), {}}},
-     nullptr},
-    {"3 digit 0, 2 fractional small decimal",
-     "0.11",
-     4,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"3 digit, 2 fractional 0 decimal",
-     "1.00",
-     4,
-     {{Item(1.000000), {}}},
-     "1.0"},
-    {"3 digit, 2 fractional small decimal",
-     "1.11",
-     4,
-     {{Item(1.110000), {}}},
-     nullptr},
-    {"3 digit, 2 fractional large decimal",
-     "9.99",
-     4,
-     {{Item(9.990000), {}}},
-     nullptr},
-    {"4 digit 0, 3 fractional small decimal",
-     "0.111",
-     5,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"4 digit, 3 fractional 0 decimal",
-     "1.000",
-     5,
-     {{Item(1.000000), {}}},
-     "1.0"},
-    {"4 digit, 3 fractional small decimal",
-     "1.111",
-     5,
-     {{Item(1.111000), {}}},
-     nullptr},
-    {"4 digit, 3 fractional large decimal",
-     "9.999",
-     5,
-     {{Item(9.999000), {}}},
-     nullptr},
-    {"3 digit 0, 1 fractional small decimal",
-     "00.1",
-     4,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"3 digit, 1 fractional 0 decimal",
-     "11.0",
-     4,
-     {{Item(11.000000), {}}},
-     "11.0"},
-    {"3 digit, 1 fractional small decimal",
-     "11.1",
-     4,
-     {{Item(11.100000), {}}},
-     nullptr},
-    {"3 digit, 1 fractional large decimal",
-     "99.9",
-     4,
-     {{Item(99.900000), {}}},
-     nullptr},
-    {"4 digit 0, 2 fractional small decimal",
-     "00.11",
-     5,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"4 digit, 2 fractional 0 decimal",
-     "11.00",
-     5,
-     {{Item(11.000000), {}}},
-     "11.0"},
-    {"4 digit, 2 fractional small decimal",
-     "11.11",
-     5,
-     {{Item(11.110000), {}}},
-     nullptr},
-    {"4 digit, 2 fractional large decimal",
-     "99.99",
-     5,
-     {{Item(99.990000), {}}},
-     nullptr},
-    {"5 digit 0, 3 fractional small decimal",
-     "00.111",
-     6,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"5 digit, 3 fractional 0 decimal",
-     "11.000",
-     6,
-     {{Item(11.000000), {}}},
-     "11.0"},
-    {"5 digit, 3 fractional small decimal",
-     "11.111",
-     6,
-     {{Item(11.111000), {}}},
-     nullptr},
-    {"5 digit, 3 fractional large decimal",
-     "99.999",
-     6,
-     {{Item(99.999000), {}}},
-     nullptr},
-    {"4 digit 0, 1 fractional small decimal",
-     "000.1",
-     5,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"4 digit, 1 fractional 0 decimal",
-     "111.0",
-     5,
-     {{Item(111.000000), {}}},
-     "111.0"},
-    {"4 digit, 1 fractional small decimal",
-     "111.1",
-     5,
-     {{Item(111.100000), {}}},
-     nullptr},
-    {"4 digit, 1 fractional large decimal",
-     "999.9",
-     5,
-     {{Item(999.900000), {}}},
-     nullptr},
-    {"5 digit 0, 2 fractional small decimal",
-     "000.11",
-     6,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"5 digit, 2 fractional 0 decimal",
-     "111.00",
-     6,
-     {{Item(111.000000), {}}},
-     "111.0"},
-    {"5 digit, 2 fractional small decimal",
-     "111.11",
-     6,
-     {{Item(111.110000), {}}},
-     nullptr},
-    {"5 digit, 2 fractional large decimal",
-     "999.99",
-     6,
-     {{Item(999.990000), {}}},
-     nullptr},
-    {"6 digit 0, 3 fractional small decimal",
-     "000.111",
-     7,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"6 digit, 3 fractional 0 decimal",
-     "111.000",
-     7,
-     {{Item(111.000000), {}}},
-     "111.0"},
-    {"6 digit, 3 fractional small decimal",
-     "111.111",
-     7,
-     {{Item(111.111000), {}}},
-     nullptr},
-    {"6 digit, 3 fractional large decimal",
-     "999.999",
-     7,
-     {{Item(999.999000), {}}},
-     nullptr},
-    {"5 digit 0, 1 fractional small decimal",
-     "0000.1",
-     6,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"5 digit, 1 fractional 0 decimal",
-     "1111.0",
-     6,
-     {{Item(1111.000000), {}}},
-     "1111.0"},
-    {"5 digit, 1 fractional small decimal",
-     "1111.1",
-     6,
-     {{Item(1111.100000), {}}},
-     nullptr},
-    {"5 digit, 1 fractional large decimal",
-     "9999.9",
-     6,
-     {{Item(9999.900000), {}}},
-     nullptr},
-    {"6 digit 0, 2 fractional small decimal",
-     "0000.11",
-     7,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"6 digit, 2 fractional 0 decimal",
-     "1111.00",
-     7,
-     {{Item(1111.000000), {}}},
-     "1111.0"},
-    {"6 digit, 2 fractional small decimal",
-     "1111.11",
-     7,
-     {{Item(1111.110000), {}}},
-     nullptr},
-    {"6 digit, 2 fractional large decimal",
-     "9999.99",
-     7,
-     {{Item(9999.990000), {}}},
-     nullptr},
-    {"7 digit 0, 3 fractional small decimal",
-     "0000.111",
-     8,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"7 digit, 3 fractional 0 decimal",
-     "1111.000",
-     8,
-     {{Item(1111.000000), {}}},
-     "1111.0"},
-    {"7 digit, 3 fractional small decimal",
-     "1111.111",
-     8,
-     {{Item(1111.111000), {}}},
-     nullptr},
-    {"7 digit, 3 fractional large decimal",
-     "9999.999",
-     8,
-     {{Item(9999.999000), {}}},
-     nullptr},
-    {"6 digit 0, 1 fractional small decimal",
-     "00000.1",
-     7,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"6 digit, 1 fractional 0 decimal",
-     "11111.0",
-     7,
-     {{Item(11111.000000), {}}},
-     "11111.0"},
-    {"6 digit, 1 fractional small decimal",
-     "11111.1",
-     7,
-     {{Item(11111.100000), {}}},
-     nullptr},
-    {"6 digit, 1 fractional large decimal",
-     "99999.9",
-     7,
-     {{Item(99999.900000), {}}},
-     nullptr},
-    {"7 digit 0, 2 fractional small decimal",
-     "00000.11",
-     8,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"7 digit, 2 fractional 0 decimal",
-     "11111.00",
-     8,
-     {{Item(11111.000000), {}}},
-     "11111.0"},
-    {"7 digit, 2 fractional small decimal",
-     "11111.11",
-     8,
-     {{Item(11111.110000), {}}},
-     nullptr},
-    {"7 digit, 2 fractional large decimal",
-     "99999.99",
-     8,
-     {{Item(99999.990000), {}}},
-     nullptr},
-    {"8 digit 0, 3 fractional small decimal",
-     "00000.111",
-     9,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"8 digit, 3 fractional 0 decimal",
-     "11111.000",
-     9,
-     {{Item(11111.000000), {}}},
-     "11111.0"},
-    {"8 digit, 3 fractional small decimal",
-     "11111.111",
-     9,
-     {{Item(11111.111000), {}}},
-     nullptr},
-    {"8 digit, 3 fractional large decimal",
-     "99999.999",
-     9,
-     {{Item(99999.999000), {}}},
-     nullptr},
-    {"7 digit 0, 1 fractional small decimal",
-     "000000.1",
-     8,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"7 digit, 1 fractional 0 decimal",
-     "111111.0",
-     8,
-     {{Item(111111.000000), {}}},
-     "111111.0"},
-    {"7 digit, 1 fractional small decimal",
-     "111111.1",
-     8,
-     {{Item(111111.100000), {}}},
-     nullptr},
-    {"7 digit, 1 fractional large decimal",
-     "999999.9",
-     8,
-     {{Item(999999.900000), {}}},
-     nullptr},
-    {"8 digit 0, 2 fractional small decimal",
-     "000000.11",
-     9,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"8 digit, 2 fractional 0 decimal",
-     "111111.00",
-     9,
-     {{Item(111111.000000), {}}},
-     "111111.0"},
-    {"8 digit, 2 fractional small decimal",
-     "111111.11",
-     9,
-     {{Item(111111.110000), {}}},
-     nullptr},
-    {"8 digit, 2 fractional large decimal",
-     "999999.99",
-     9,
-     {{Item(999999.990000), {}}},
-     nullptr},
-    {"9 digit 0, 3 fractional small decimal",
-     "000000.111",
-     10,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"9 digit, 3 fractional 0 decimal",
-     "111111.000",
-     10,
-     {{Item(111111.000000), {}}},
-     "111111.0"},
-    {"9 digit, 3 fractional small decimal",
-     "111111.111",
-     10,
-     {{Item(111111.111000), {}}},
-     nullptr},
-    {"9 digit, 3 fractional large decimal",
-     "999999.999",
-     10,
-     {{Item(999999.999000), {}}},
-     nullptr},
-    {"8 digit 0, 1 fractional small decimal",
-     "0000000.1",
-     9,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"8 digit, 1 fractional 0 decimal",
-     "1111111.0",
-     9,
-     {{Item(1111111.000000), {}}},
-     "1111111.0"},
-    {"8 digit, 1 fractional small decimal",
-     "1111111.1",
-     9,
-     {{Item(1111111.100000), {}}},
-     nullptr},
-    {"8 digit, 1 fractional large decimal",
-     "9999999.9",
-     9,
-     {{Item(9999999.900000), {}}},
-     nullptr},
-    {"9 digit 0, 2 fractional small decimal",
-     "0000000.11",
-     10,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"9 digit, 2 fractional 0 decimal",
-     "1111111.00",
-     10,
-     {{Item(1111111.000000), {}}},
-     "1111111.0"},
-    {"9 digit, 2 fractional small decimal",
-     "1111111.11",
-     10,
-     {{Item(1111111.110000), {}}},
-     nullptr},
-    {"9 digit, 2 fractional large decimal",
-     "9999999.99",
-     10,
-     {{Item(9999999.990000), {}}},
-     nullptr},
-    {"10 digit 0, 3 fractional small decimal",
-     "0000000.111",
-     11,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"10 digit, 3 fractional 0 decimal",
-     "1111111.000",
-     11,
-     {{Item(1111111.000000), {}}},
-     "1111111.0"},
-    {"10 digit, 3 fractional small decimal",
-     "1111111.111",
-     11,
-     {{Item(1111111.111000), {}}},
-     nullptr},
-    {"10 digit, 3 fractional large decimal",
-     "9999999.999",
-     11,
-     {{Item(9999999.999000), {}}},
-     nullptr},
-    {"9 digit 0, 1 fractional small decimal",
-     "00000000.1",
-     10,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"9 digit, 1 fractional 0 decimal",
-     "11111111.0",
-     10,
-     {{Item(11111111.000000), {}}},
-     "11111111.0"},
-    {"9 digit, 1 fractional small decimal",
-     "11111111.1",
-     10,
-     {{Item(11111111.100000), {}}},
-     nullptr},
-    {"9 digit, 1 fractional large decimal",
-     "99999999.9",
-     10,
-     {{Item(99999999.900000), {}}},
-     nullptr},
-    {"10 digit 0, 2 fractional small decimal",
-     "00000000.11",
-     11,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"10 digit, 2 fractional 0 decimal",
-     "11111111.00",
-     11,
-     {{Item(11111111.000000), {}}},
-     "11111111.0"},
-    {"10 digit, 2 fractional small decimal",
-     "11111111.11",
-     11,
-     {{Item(11111111.110000), {}}},
-     nullptr},
-    {"10 digit, 2 fractional large decimal",
-     "99999999.99",
-     11,
-     {{Item(99999999.990000), {}}},
-     nullptr},
-    {"11 digit 0, 3 fractional small decimal",
-     "00000000.111",
-     12,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"11 digit, 3 fractional 0 decimal",
-     "11111111.000",
-     12,
-     {{Item(11111111.000000), {}}},
-     "11111111.0"},
-    {"11 digit, 3 fractional small decimal",
-     "11111111.111",
-     12,
-     {{Item(11111111.111000), {}}},
-     nullptr},
-    {"11 digit, 3 fractional large decimal",
-     "99999999.999",
-     12,
-     {{Item(99999999.999000), {}}},
-     nullptr},
-    {"10 digit 0, 1 fractional small decimal",
-     "000000000.1",
-     11,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"10 digit, 1 fractional 0 decimal",
-     "111111111.0",
-     11,
-     {{Item(111111111.000000), {}}},
-     "111111111.0"},
-    {"10 digit, 1 fractional small decimal",
-     "111111111.1",
-     11,
-     {{Item(111111111.100000), {}}},
-     nullptr},
-    {"10 digit, 1 fractional large decimal",
-     "999999999.9",
-     11,
-     {{Item(999999999.900000), {}}},
-     nullptr},
-    {"11 digit 0, 2 fractional small decimal",
-     "000000000.11",
-     12,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"11 digit, 2 fractional 0 decimal",
-     "111111111.00",
-     12,
-     {{Item(111111111.000000), {}}},
-     "111111111.0"},
-    {"11 digit, 2 fractional small decimal",
-     "111111111.11",
-     12,
-     {{Item(111111111.110000), {}}},
-     nullptr},
-    {"11 digit, 2 fractional large decimal",
-     "999999999.99",
-     12,
-     {{Item(999999999.990000), {}}},
-     nullptr},
-    {"12 digit 0, 3 fractional small decimal",
-     "000000000.111",
-     13,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"12 digit, 3 fractional 0 decimal",
-     "111111111.000",
-     13,
-     {{Item(111111111.000000), {}}},
-     "111111111.0"},
-    {"12 digit, 3 fractional small decimal",
-     "111111111.111",
-     13,
-     {{Item(111111111.111000), {}}},
-     nullptr},
-    {"12 digit, 3 fractional large decimal",
-     "999999999.999",
-     13,
-     {{Item(999999999.999000), {}}},
-     nullptr},
-    {"11 digit 0, 1 fractional small decimal",
-     "0000000000.1",
-     12,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"11 digit, 1 fractional 0 decimal",
-     "1111111111.0",
-     12,
-     {{Item(1111111111.000000), {}}},
-     "1111111111.0"},
-    {"11 digit, 1 fractional small decimal",
-     "1111111111.1",
-     12,
-     {{Item(1111111111.100000), {}}},
-     nullptr},
-    {"11 digit, 1 fractional large decimal",
-     "9999999999.9",
-     12,
-     {{Item(9999999999.900000), {}}},
-     nullptr},
-    {"12 digit 0, 2 fractional small decimal",
-     "0000000000.11",
-     13,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"12 digit, 2 fractional 0 decimal",
-     "1111111111.00",
-     13,
-     {{Item(1111111111.000000), {}}},
-     "1111111111.0"},
-    {"12 digit, 2 fractional small decimal",
-     "1111111111.11",
-     13,
-     {{Item(1111111111.110000), {}}},
-     nullptr},
-    {"12 digit, 2 fractional large decimal",
-     "9999999999.99",
-     13,
-     {{Item(9999999999.990000), {}}},
-     nullptr},
-    {"13 digit 0, 3 fractional small decimal",
-     "0000000000.111",
-     14,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"13 digit, 3 fractional 0 decimal",
-     "1111111111.000",
-     14,
-     {{Item(1111111111.000000), {}}},
-     "1111111111.0"},
-    {"13 digit, 3 fractional small decimal",
-     "1111111111.111",
-     14,
-     {{Item(1111111111.111000), {}}},
-     nullptr},
-    {"13 digit, 3 fractional large decimal",
-     "9999999999.999",
-     14,
-     {{Item(9999999999.999001), {}}},
-     nullptr},
-    {"12 digit 0, 1 fractional small decimal",
-     "00000000000.1",
-     13,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"12 digit, 1 fractional 0 decimal",
-     "11111111111.0",
-     13,
-     {{Item(11111111111.000000), {}}},
-     "11111111111.0"},
-    {"12 digit, 1 fractional small decimal",
-     "11111111111.1",
-     13,
-     {{Item(11111111111.100000), {}}},
-     nullptr},
-    {"12 digit, 1 fractional large decimal",
-     "99999999999.9",
-     13,
-     {{Item(99999999999.899994), {}}},
-     nullptr},
-    {"13 digit 0, 2 fractional small decimal",
-     "00000000000.11",
-     14,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"13 digit, 2 fractional 0 decimal",
-     "11111111111.00",
-     14,
-     {{Item(11111111111.000000), {}}},
-     "11111111111.0"},
-    {"13 digit, 2 fractional small decimal",
-     "11111111111.11",
-     14,
-     {{Item(11111111111.110001), {}}},
-     nullptr},
-    {"13 digit, 2 fractional large decimal",
-     "99999999999.99",
-     14,
-     {{Item(99999999999.990005), {}}},
-     nullptr},
-    {"14 digit 0, 3 fractional small decimal",
-     "00000000000.111",
-     15,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"14 digit, 3 fractional 0 decimal",
-     "11111111111.000",
-     15,
-     {{Item(11111111111.000000), {}}},
-     "11111111111.0"},
-    {"14 digit, 3 fractional small decimal",
-     "11111111111.111",
-     15,
-     {{Item(11111111111.111000), {}}},
-     nullptr},
-    {"14 digit, 3 fractional large decimal",
-     "99999999999.999",
-     15,
-     {{Item(99999999999.998993), {}}},
-     nullptr},
-    {"13 digit 0, 1 fractional small decimal",
-     "000000000000.1",
-     14,
-     {{Item(0.100000), {}}},
-     "0.1"},
-    {"13 digit, 1 fractional 0 decimal",
-     "111111111111.0",
-     14,
-     {{Item(111111111111.000000), {}}},
-     "111111111111.0"},
-    {"13 digit, 1 fractional small decimal",
-     "111111111111.1",
-     14,
-     {{Item(111111111111.100006), {}}},
-     nullptr},
-    {"13 digit, 1 fractional large decimal",
-     "999999999999.9",
-     14,
-     {{Item(999999999999.900024), {}}},
-     nullptr},
-    {"14 digit 0, 2 fractional small decimal",
-     "000000000000.11",
-     15,
-     {{Item(0.110000), {}}},
-     "0.11"},
-    {"14 digit, 2 fractional 0 decimal",
-     "111111111111.00",
-     15,
-     {{Item(111111111111.000000), {}}},
-     "111111111111.0"},
-    {"14 digit, 2 fractional small decimal",
-     "111111111111.11",
-     15,
-     {{Item(111111111111.110001), {}}},
-     nullptr},
-    {"14 digit, 2 fractional large decimal",
-     "999999999999.99",
-     15,
-     {{Item(999999999999.989990), {}}},
-     nullptr},
-    {"15 digit 0, 3 fractional small decimal",
-     "000000000000.111",
-     16,
-     {{Item(0.111000), {}}},
-     "0.111"},
-    {"15 digit, 3 fractional 0 decimal",
-     "111111111111.000",
-     16,
-     {{Item(111111111111.000000), {}}},
-     "111111111111.0"},
-    {"15 digit, 3 fractional small decimal",
-     "111111111111.111",
-     16,
-     {{Item(111111111111.110992), {}}},
-     nullptr},
-    {"15 digit, 3 fractional large decimal",
-     "999999999999.999",
-     16,
-     {{Item(999999999999.999023), {}}},
-     nullptr},
-    {"too many digit 0 decimal", "000000000000000.0", 17, absl::nullopt,
-     nullptr},
-    {"too many fractional digits 0 decimal", "000000000000.0000", 17,
-     absl::nullopt, nullptr},
-    {"too many digit 9 decimal", "999999999999999.9", 17, absl::nullopt,
-     nullptr},
-    {"too many fractional digits 9 decimal", "999999999999.9999", 17,
-     absl::nullopt, nullptr},
-    // number.json
-    {"basic integer", "42", 2, {{Integer(42), {}}}, nullptr},
-    {"zero integer", "0", 1, {{Integer(0), {}}}, nullptr},
-    {"negative zero", "-0", 2, {{Integer(0), {}}}, "0"},
-    {"double negative zero", "--0", 3, absl::nullopt, nullptr},
-    {"negative integer", "-42", 3, {{Integer(-42), {}}}, nullptr},
-    {"leading 0 integer", "042", 3, {{Integer(42), {}}}, "42"},
-    {"leading 0 negative integer", "-042", 4, {{Integer(-42), {}}}, "-42"},
-    {"leading 0 zero", "00", 2, {{Integer(0), {}}}, "0"},
-    {"comma", "2,3", 3, absl::nullopt, nullptr},
-    {"negative non-DIGIT first character", "-a23", 4, absl::nullopt, nullptr},
-    {"sign out of place", "4-2", 3, absl::nullopt, nullptr},
-    {"whitespace after sign", "- 42", 4, absl::nullopt, nullptr},
-    {"long integer",
-     "123456789012345",
-     15,
-     {{Integer(123456789012345), {}}},
-     nullptr},
-    {"long negative integer",
-     "-123456789012345",
-     16,
-     {{Integer(-123456789012345), {}}},
-     nullptr},
-    {"too long integer", "1234567890123456", 16, absl::nullopt, nullptr},
-    {"negative too long integer", "-1234567890123456", 17, absl::nullopt,
-     nullptr},
-    {"simple decimal", "1.23", 4, {{Item(1.230000), {}}}, nullptr},
-    {"negative decimal", "-1.23", 5, {{Item(-1.230000), {}}}, nullptr},
-    {"decimal, whitespace after decimal", "1. 23", 5, absl::nullopt, nullptr},
-    {"decimal, whitespace before decimal", "1 .23", 5, absl::nullopt, nullptr},
-    {"negative decimal, whitespace after sign", "- 1.23", 6, absl::nullopt,
-     nullptr},
-    {"tricky precision decimal",
-     "123456789012.1",
-     14,
-     {{Item(123456789012.100006), {}}},
-     nullptr},
-    {"double decimal decimal", "1.5.4", 5, absl::nullopt, nullptr},
-    {"adjacent double decimal decimal", "1..4", 4, absl::nullopt, nullptr},
-    {"decimal with three fractional digits",
-     "1.123",
-     5,
-     {{Item(1.123000), {}}},
-     nullptr},
-    {"negative decimal with three fractional digits",
-     "-1.123",
-     6,
-     {{Item(-1.123000), {}}},
-     nullptr},
-    {"decimal with four fractional digits", "1.1234", 6, absl::nullopt,
-     nullptr},
-    {"negative decimal with four fractional digits", "-1.1234", 7,
-     absl::nullopt, nullptr},
-    {"decimal with thirteen integer digits", "1234567890123.0", 15,
-     absl::nullopt, nullptr},
-    {"negative decimal with thirteen integer digits", "-1234567890123.0", 16,
-     absl::nullopt, nullptr},
-    // string-generated.json
-    {"0x00 in string", "\" \000 \"", 5, absl::nullopt, nullptr},
-    {"0x01 in string", "\" \001 \"", 5, absl::nullopt, nullptr},
-    {"0x02 in string", "\" \002 \"", 5, absl::nullopt, nullptr},
-    {"0x03 in string", "\" \003 \"", 5, absl::nullopt, nullptr},
-    {"0x04 in string", "\" \004 \"", 5, absl::nullopt, nullptr},
-    {"0x05 in string", "\" \005 \"", 5, absl::nullopt, nullptr},
-    {"0x06 in string", "\" \006 \"", 5, absl::nullopt, nullptr},
-    {"0x07 in string", "\" \a \"", 5, absl::nullopt, nullptr},
-    {"0x08 in string", "\" \b \"", 5, absl::nullopt, nullptr},
-    {"0x09 in string", "\" \t \"", 5, absl::nullopt, nullptr},
-    {"0x0a in string", "\" \n \"", 5, absl::nullopt, nullptr},
-    {"0x0b in string", "\" \v \"", 5, absl::nullopt, nullptr},
-    {"0x0c in string", "\" \f \"", 5, absl::nullopt, nullptr},
-    {"0x0d in string", "\" \r \"", 5, absl::nullopt, nullptr},
-    {"0x0e in string", "\" \016 \"", 5, absl::nullopt, nullptr},
-    {"0x0f in string", "\" \017 \"", 5, absl::nullopt, nullptr},
-    {"0x10 in string", "\" \020 \"", 5, absl::nullopt, nullptr},
-    {"0x11 in string", "\" \021 \"", 5, absl::nullopt, nullptr},
-    {"0x12 in string", "\" \022 \"", 5, absl::nullopt, nullptr},
-    {"0x13 in string", "\" \023 \"", 5, absl::nullopt, nullptr},
-    {"0x14 in string", "\" \024 \"", 5, absl::nullopt, nullptr},
-    {"0x15 in string", "\" \025 \"", 5, absl::nullopt, nullptr},
-    {"0x16 in string", "\" \026 \"", 5, absl::nullopt, nullptr},
-    {"0x17 in string", "\" \027 \"", 5, absl::nullopt, nullptr},
-    {"0x18 in string", "\" \030 \"", 5, absl::nullopt, nullptr},
-    {"0x19 in string", "\" \031 \"", 5, absl::nullopt, nullptr},
-    {"0x1a in string", "\" \032 \"", 5, absl::nullopt, nullptr},
-    {"0x1b in string", "\" \033 \"", 5, absl::nullopt, nullptr},
-    {"0x1c in string", "\" \034 \"", 5, absl::nullopt, nullptr},
-    {"0x1d in string", "\" \035 \"", 5, absl::nullopt, nullptr},
-    {"0x1e in string", "\" \036 \"", 5, absl::nullopt, nullptr},
-    {"0x1f in string", "\" \037 \"", 5, absl::nullopt, nullptr},
-    {"0x20 in string", "\"   \"", 5, {{Item("   "), {}}}, nullptr},
-    {"0x21 in string", "\" ! \"", 5, {{Item(" ! "), {}}}, nullptr},
-    {"0x22 in string", "\" \" \"", 5, absl::nullopt, nullptr},
-    {"0x23 in string", "\" # \"", 5, {{Item(" # "), {}}}, nullptr},
-    {"0x24 in string", "\" $ \"", 5, {{Item(" $ "), {}}}, nullptr},
-    {"0x25 in string", "\" % \"", 5, {{Item(" % "), {}}}, nullptr},
-    {"0x26 in string", "\" & \"", 5, {{Item(" & "), {}}}, nullptr},
-    {"0x27 in string", "\" ' \"", 5, {{Item(" ' "), {}}}, nullptr},
-    {"0x28 in string", "\" ( \"", 5, {{Item(" ( "), {}}}, nullptr},
-    {"0x29 in string", "\" ) \"", 5, {{Item(" ) "), {}}}, nullptr},
-    {"0x2a in string", "\" * \"", 5, {{Item(" * "), {}}}, nullptr},
-    {"0x2b in string", "\" + \"", 5, {{Item(" + "), {}}}, nullptr},
-    {"0x2c in string", "\" , \"", 5, {{Item(" , "), {}}}, nullptr},
-    {"0x2d in string", "\" - \"", 5, {{Item(" - "), {}}}, nullptr},
-    {"0x2e in string", "\" . \"", 5, {{Item(" . "), {}}}, nullptr},
-    {"0x2f in string", "\" / \"", 5, {{Item(" / "), {}}}, nullptr},
-    {"0x30 in string", "\" 0 \"", 5, {{Item(" 0 "), {}}}, nullptr},
-    {"0x31 in string", "\" 1 \"", 5, {{Item(" 1 "), {}}}, nullptr},
-    {"0x32 in string", "\" 2 \"", 5, {{Item(" 2 "), {}}}, nullptr},
-    {"0x33 in string", "\" 3 \"", 5, {{Item(" 3 "), {}}}, nullptr},
-    {"0x34 in string", "\" 4 \"", 5, {{Item(" 4 "), {}}}, nullptr},
-    {"0x35 in string", "\" 5 \"", 5, {{Item(" 5 "), {}}}, nullptr},
-    {"0x36 in string", "\" 6 \"", 5, {{Item(" 6 "), {}}}, nullptr},
-    {"0x37 in string", "\" 7 \"", 5, {{Item(" 7 "), {}}}, nullptr},
-    {"0x38 in string", "\" 8 \"", 5, {{Item(" 8 "), {}}}, nullptr},
-    {"0x39 in string", "\" 9 \"", 5, {{Item(" 9 "), {}}}, nullptr},
-    {"0x3a in string", "\" : \"", 5, {{Item(" : "), {}}}, nullptr},
-    {"0x3b in string", "\" ; \"", 5, {{Item(" ; "), {}}}, nullptr},
-    {"0x3c in string", "\" < \"", 5, {{Item(" < "), {}}}, nullptr},
-    {"0x3d in string", "\" = \"", 5, {{Item(" = "), {}}}, nullptr},
-    {"0x3e in string", "\" > \"", 5, {{Item(" > "), {}}}, nullptr},
-    {"0x3f in string", "\" ? \"", 5, {{Item(" ? "), {}}}, nullptr},
-    {"0x40 in string", "\" @ \"", 5, {{Item(" @ "), {}}}, nullptr},
-    {"0x41 in string", "\" A \"", 5, {{Item(" A "), {}}}, nullptr},
-    {"0x42 in string", "\" B \"", 5, {{Item(" B "), {}}}, nullptr},
-    {"0x43 in string", "\" C \"", 5, {{Item(" C "), {}}}, nullptr},
-    {"0x44 in string", "\" D \"", 5, {{Item(" D "), {}}}, nullptr},
-    {"0x45 in string", "\" E \"", 5, {{Item(" E "), {}}}, nullptr},
-    {"0x46 in string", "\" F \"", 5, {{Item(" F "), {}}}, nullptr},
-    {"0x47 in string", "\" G \"", 5, {{Item(" G "), {}}}, nullptr},
-    {"0x48 in string", "\" H \"", 5, {{Item(" H "), {}}}, nullptr},
-    {"0x49 in string", "\" I \"", 5, {{Item(" I "), {}}}, nullptr},
-    {"0x4a in string", "\" J \"", 5, {{Item(" J "), {}}}, nullptr},
-    {"0x4b in string", "\" K \"", 5, {{Item(" K "), {}}}, nullptr},
-    {"0x4c in string", "\" L \"", 5, {{Item(" L "), {}}}, nullptr},
-    {"0x4d in string", "\" M \"", 5, {{Item(" M "), {}}}, nullptr},
-    {"0x4e in string", "\" N \"", 5, {{Item(" N "), {}}}, nullptr},
-    {"0x4f in string", "\" O \"", 5, {{Item(" O "), {}}}, nullptr},
-    {"0x50 in string", "\" P \"", 5, {{Item(" P "), {}}}, nullptr},
-    {"0x51 in string", "\" Q \"", 5, {{Item(" Q "), {}}}, nullptr},
-    {"0x52 in string", "\" R \"", 5, {{Item(" R "), {}}}, nullptr},
-    {"0x53 in string", "\" S \"", 5, {{Item(" S "), {}}}, nullptr},
-    {"0x54 in string", "\" T \"", 5, {{Item(" T "), {}}}, nullptr},
-    {"0x55 in string", "\" U \"", 5, {{Item(" U "), {}}}, nullptr},
-    {"0x56 in string", "\" V \"", 5, {{Item(" V "), {}}}, nullptr},
-    {"0x57 in string", "\" W \"", 5, {{Item(" W "), {}}}, nullptr},
-    {"0x58 in string", "\" X \"", 5, {{Item(" X "), {}}}, nullptr},
-    {"0x59 in string", "\" Y \"", 5, {{Item(" Y "), {}}}, nullptr},
-    {"0x5a in string", "\" Z \"", 5, {{Item(" Z "), {}}}, nullptr},
-    {"0x5b in string", "\" [ \"", 5, {{Item(" [ "), {}}}, nullptr},
-    {"0x5c in string", "\" \\ \"", 5, absl::nullopt, nullptr},
-    {"0x5d in string", "\" ] \"", 5, {{Item(" ] "), {}}}, nullptr},
-    {"0x5e in string", "\" ^ \"", 5, {{Item(" ^ "), {}}}, nullptr},
-    {"0x5f in string", "\" _ \"", 5, {{Item(" _ "), {}}}, nullptr},
-    {"0x60 in string", "\" ` \"", 5, {{Item(" ` "), {}}}, nullptr},
-    {"0x61 in string", "\" a \"", 5, {{Item(" a "), {}}}, nullptr},
-    {"0x62 in string", "\" b \"", 5, {{Item(" b "), {}}}, nullptr},
-    {"0x63 in string", "\" c \"", 5, {{Item(" c "), {}}}, nullptr},
-    {"0x64 in string", "\" d \"", 5, {{Item(" d "), {}}}, nullptr},
-    {"0x65 in string", "\" e \"", 5, {{Item(" e "), {}}}, nullptr},
-    {"0x66 in string", "\" f \"", 5, {{Item(" f "), {}}}, nullptr},
-    {"0x67 in string", "\" g \"", 5, {{Item(" g "), {}}}, nullptr},
-    {"0x68 in string", "\" h \"", 5, {{Item(" h "), {}}}, nullptr},
-    {"0x69 in string", "\" i \"", 5, {{Item(" i "), {}}}, nullptr},
-    {"0x6a in string", "\" j \"", 5, {{Item(" j "), {}}}, nullptr},
-    {"0x6b in string", "\" k \"", 5, {{Item(" k "), {}}}, nullptr},
-    {"0x6c in string", "\" l \"", 5, {{Item(" l "), {}}}, nullptr},
-    {"0x6d in string", "\" m \"", 5, {{Item(" m "), {}}}, nullptr},
-    {"0x6e in string", "\" n \"", 5, {{Item(" n "), {}}}, nullptr},
-    {"0x6f in string", "\" o \"", 5, {{Item(" o "), {}}}, nullptr},
-    {"0x70 in string", "\" p \"", 5, {{Item(" p "), {}}}, nullptr},
-    {"0x71 in string", "\" q \"", 5, {{Item(" q "), {}}}, nullptr},
-    {"0x72 in string", "\" r \"", 5, {{Item(" r "), {}}}, nullptr},
-    {"0x73 in string", "\" s \"", 5, {{Item(" s "), {}}}, nullptr},
-    {"0x74 in string", "\" t \"", 5, {{Item(" t "), {}}}, nullptr},
-    {"0x75 in string", "\" u \"", 5, {{Item(" u "), {}}}, nullptr},
-    {"0x76 in string", "\" v \"", 5, {{Item(" v "), {}}}, nullptr},
-    {"0x77 in string", "\" w \"", 5, {{Item(" w "), {}}}, nullptr},
-    {"0x78 in string", "\" x \"", 5, {{Item(" x "), {}}}, nullptr},
-    {"0x79 in string", "\" y \"", 5, {{Item(" y "), {}}}, nullptr},
-    {"0x7a in string", "\" z \"", 5, {{Item(" z "), {}}}, nullptr},
-    {"0x7b in string", "\" { \"", 5, {{Item(" { "), {}}}, nullptr},
-    {"0x7c in string", "\" | \"", 5, {{Item(" | "), {}}}, nullptr},
-    {"0x7d in string", "\" } \"", 5, {{Item(" } "), {}}}, nullptr},
-    {"0x7e in string", "\" ~ \"", 5, {{Item(" ~ "), {}}}, nullptr},
-    {"0x7f in string", "\" \177 \"", 5, absl::nullopt, nullptr},
-    {"Escaped 0x00 in string", "\"\\\000\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x01 in string", "\"\\\001\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x02 in string", "\"\\\002\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x03 in string", "\"\\\003\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x04 in string", "\"\\\004\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x05 in string", "\"\\\005\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x06 in string", "\"\\\006\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x07 in string", "\"\\\a\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x08 in string", "\"\\\b\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x09 in string", "\"\\\t\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x0a in string", "\"\\\n\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x0b in string", "\"\\\v\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x0c in string", "\"\\\f\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x0d in string", "\"\\\r\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x0e in string", "\"\\\016\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x0f in string", "\"\\\017\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x10 in string", "\"\\\020\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x11 in string", "\"\\\021\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x12 in string", "\"\\\022\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x13 in string", "\"\\\023\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x14 in string", "\"\\\024\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x15 in string", "\"\\\025\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x16 in string", "\"\\\026\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x17 in string", "\"\\\027\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x18 in string", "\"\\\030\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x19 in string", "\"\\\031\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x1a in string", "\"\\\032\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x1b in string", "\"\\\033\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x1c in string", "\"\\\034\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x1d in string", "\"\\\035\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x1e in string", "\"\\\036\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x1f in string", "\"\\\037\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x20 in string", "\"\\ \"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x21 in string", "\"\\!\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x22 in string", "\"\\\"\"", 4, {{Item("\""), {}}}, nullptr},
-    {"Escaped 0x23 in string", "\"\\#\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x24 in string", "\"\\$\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x25 in string", "\"\\%\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x26 in string", "\"\\&\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x27 in string", "\"\\'\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x28 in string", "\"\\(\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x29 in string", "\"\\)\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x2a in string", "\"\\*\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x2b in string", "\"\\+\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x2c in string", "\"\\,\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x2d in string", "\"\\-\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x2e in string", "\"\\.\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x2f in string", "\"\\/\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x30 in string", "\"\\0\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x31 in string", "\"\\1\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x32 in string", "\"\\2\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x33 in string", "\"\\3\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x34 in string", "\"\\4\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x35 in string", "\"\\5\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x36 in string", "\"\\6\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x37 in string", "\"\\7\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x38 in string", "\"\\8\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x39 in string", "\"\\9\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x3a in string", "\"\\:\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x3b in string", "\"\\;\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x3c in string", "\"\\<\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x3d in string", "\"\\=\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x3e in string", "\"\\>\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x3f in string", "\"\\?\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x40 in string", "\"\\@\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x41 in string", "\"\\A\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x42 in string", "\"\\B\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x43 in string", "\"\\C\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x44 in string", "\"\\D\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x45 in string", "\"\\E\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x46 in string", "\"\\F\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x47 in string", "\"\\G\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x48 in string", "\"\\H\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x49 in string", "\"\\I\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x4a in string", "\"\\J\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x4b in string", "\"\\K\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x4c in string", "\"\\L\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x4d in string", "\"\\M\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x4e in string", "\"\\N\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x4f in string", "\"\\O\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x50 in string", "\"\\P\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x51 in string", "\"\\Q\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x52 in string", "\"\\R\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x53 in string", "\"\\S\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x54 in string", "\"\\T\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x55 in string", "\"\\U\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x56 in string", "\"\\V\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x57 in string", "\"\\W\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x58 in string", "\"\\X\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x59 in string", "\"\\Y\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x5a in string", "\"\\Z\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x5b in string", "\"\\[\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x5c in string", "\"\\\\\"", 4, {{Item("\\"), {}}}, nullptr},
-    {"Escaped 0x5d in string", "\"\\]\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x5e in string", "\"\\^\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x5f in string", "\"\\_\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x60 in string", "\"\\`\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x61 in string", "\"\\a\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x62 in string", "\"\\b\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x63 in string", "\"\\c\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x64 in string", "\"\\d\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x65 in string", "\"\\e\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x66 in string", "\"\\f\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x67 in string", "\"\\g\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x68 in string", "\"\\h\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x69 in string", "\"\\i\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x6a in string", "\"\\j\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x6b in string", "\"\\k\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x6c in string", "\"\\l\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x6d in string", "\"\\m\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x6e in string", "\"\\n\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x6f in string", "\"\\o\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x70 in string", "\"\\p\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x71 in string", "\"\\q\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x72 in string", "\"\\r\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x73 in string", "\"\\s\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x74 in string", "\"\\t\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x75 in string", "\"\\u\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x76 in string", "\"\\v\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x77 in string", "\"\\w\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x78 in string", "\"\\x\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x79 in string", "\"\\y\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x7a in string", "\"\\z\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x7b in string", "\"\\{\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x7c in string", "\"\\|\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x7d in string", "\"\\}\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x7e in string", "\"\\~\"", 4, absl::nullopt, nullptr},
-    {"Escaped 0x7f in string", "\"\\\177\"", 4, absl::nullopt, nullptr},
-    // string.json
-    {"basic string", "\"foo bar\"", 9, {{Item("foo bar"), {}}}, nullptr},
-    {"empty string", "\"\"", 2, {{Item(""), {}}}, nullptr},
-    {"long string",
-     "\"foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-     "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-     "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-     "foo foo foo foo foo foo foo foo foo foo foo foo \"",
-     262,
-     {{Item("foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-            "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-            "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-            "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
-            "foo "),
-       {}}},
-     nullptr},
-    {"whitespace string", "\"   \"", 5, {{Item("   "), {}}}, nullptr},
-    {"non-ascii string", "\"f\374\374\"", 5, absl::nullopt, nullptr},
-    {"tab in string", "\"\\t\"", 4, absl::nullopt, nullptr},
-    {"newline in string", "\" \\n \"", 6, absl::nullopt, nullptr},
-    {"single quoted string", "'foo'", 5, absl::nullopt, nullptr},
-    {"unbalanced string", "\"foo", 4, absl::nullopt, nullptr},
-    {"string quoting",
-     "\"foo \\\"bar\\\" \\\\ baz\"",
-     20,
-     {{Item("foo \"bar\" \\ baz"), {}}},
-     nullptr},
-    {"bad string quoting", "\"foo \\,\"", 8, absl::nullopt, nullptr},
-    {"ending string quote", "\"foo \\\"", 7, absl::nullopt, nullptr},
-    {"abruptly ending string quote", "\"foo \\", 6, absl::nullopt, nullptr},
-    // token-generated.json
-    {"0x00 in token", "a\000a", 3, absl::nullopt, nullptr},
-    {"0x01 in token", "a\001a", 3, absl::nullopt, nullptr},
-    {"0x02 in token", "a\002a", 3, absl::nullopt, nullptr},
-    {"0x03 in token", "a\003a", 3, absl::nullopt, nullptr},
-    {"0x04 in token", "a\004a", 3, absl::nullopt, nullptr},
-    {"0x05 in token", "a\005a", 3, absl::nullopt, nullptr},
-    {"0x06 in token", "a\006a", 3, absl::nullopt, nullptr},
-    {"0x07 in token", "a\aa", 3, absl::nullopt, nullptr},
-    {"0x08 in token", "a\ba", 3, absl::nullopt, nullptr},
-    {"0x09 in token", "a\ta", 3, absl::nullopt, nullptr},
-    {"0x0a in token", "a\na", 3, absl::nullopt, nullptr},
-    {"0x0b in token", "a\va", 3, absl::nullopt, nullptr},
-    {"0x0c in token", "a\fa", 3, absl::nullopt, nullptr},
-    {"0x0d in token", "a\ra", 3, absl::nullopt, nullptr},
-    {"0x0e in token", "a\016a", 3, absl::nullopt, nullptr},
-    {"0x0f in token", "a\017a", 3, absl::nullopt, nullptr},
-    {"0x10 in token", "a\020a", 3, absl::nullopt, nullptr},
-    {"0x11 in token", "a\021a", 3, absl::nullopt, nullptr},
-    {"0x12 in token", "a\022a", 3, absl::nullopt, nullptr},
-    {"0x13 in token", "a\023a", 3, absl::nullopt, nullptr},
-    {"0x14 in token", "a\024a", 3, absl::nullopt, nullptr},
-    {"0x15 in token", "a\025a", 3, absl::nullopt, nullptr},
-    {"0x16 in token", "a\026a", 3, absl::nullopt, nullptr},
-    {"0x17 in token", "a\027a", 3, absl::nullopt, nullptr},
-    {"0x18 in token", "a\030a", 3, absl::nullopt, nullptr},
-    {"0x19 in token", "a\031a", 3, absl::nullopt, nullptr},
-    {"0x1a in token", "a\032a", 3, absl::nullopt, nullptr},
-    {"0x1b in token", "a\033a", 3, absl::nullopt, nullptr},
-    {"0x1c in token", "a\034a", 3, absl::nullopt, nullptr},
-    {"0x1d in token", "a\035a", 3, absl::nullopt, nullptr},
-    {"0x1e in token", "a\036a", 3, absl::nullopt, nullptr},
-    {"0x1f in token", "a\037a", 3, absl::nullopt, nullptr},
-    {"0x20 in token", "a a", 3, absl::nullopt, nullptr},
-    {"0x21 in token", "a!a", 3, {{Item("a!a", Item::kTokenType), {}}}, nullptr},
-    {"0x22 in token", "a\"a", 3, absl::nullopt, nullptr},
-    {"0x23 in token", "a#a", 3, {{Item("a#a", Item::kTokenType), {}}}, nullptr},
-    {"0x24 in token", "a$a", 3, {{Item("a$a", Item::kTokenType), {}}}, nullptr},
-    {"0x25 in token", "a%a", 3, {{Item("a%a", Item::kTokenType), {}}}, nullptr},
-    {"0x26 in token", "a&a", 3, {{Item("a&a", Item::kTokenType), {}}}, nullptr},
-    {"0x27 in token", "a'a", 3, {{Item("a'a", Item::kTokenType), {}}}, nullptr},
-    {"0x28 in token", "a(a", 3, absl::nullopt, nullptr},
-    {"0x29 in token", "a)a", 3, absl::nullopt, nullptr},
-    {"0x2a in token", "a*a", 3, {{Item("a*a", Item::kTokenType), {}}}, nullptr},
-    {"0x2b in token", "a+a", 3, {{Item("a+a", Item::kTokenType), {}}}, nullptr},
-    {"0x2c in token", "a,a", 3, absl::nullopt, nullptr},
-    {"0x2d in token", "a-a", 3, {{Item("a-a", Item::kTokenType), {}}}, nullptr},
-    {"0x2e in token", "a.a", 3, {{Item("a.a", Item::kTokenType), {}}}, nullptr},
-    {"0x2f in token", "a/a", 3, {{Item("a/a", Item::kTokenType), {}}}, nullptr},
-    {"0x30 in token", "a0a", 3, {{Item("a0a", Item::kTokenType), {}}}, nullptr},
-    {"0x31 in token", "a1a", 3, {{Item("a1a", Item::kTokenType), {}}}, nullptr},
-    {"0x32 in token", "a2a", 3, {{Item("a2a", Item::kTokenType), {}}}, nullptr},
-    {"0x33 in token", "a3a", 3, {{Item("a3a", Item::kTokenType), {}}}, nullptr},
-    {"0x34 in token", "a4a", 3, {{Item("a4a", Item::kTokenType), {}}}, nullptr},
-    {"0x35 in token", "a5a", 3, {{Item("a5a", Item::kTokenType), {}}}, nullptr},
-    {"0x36 in token", "a6a", 3, {{Item("a6a", Item::kTokenType), {}}}, nullptr},
-    {"0x37 in token", "a7a", 3, {{Item("a7a", Item::kTokenType), {}}}, nullptr},
-    {"0x38 in token", "a8a", 3, {{Item("a8a", Item::kTokenType), {}}}, nullptr},
-    {"0x39 in token", "a9a", 3, {{Item("a9a", Item::kTokenType), {}}}, nullptr},
-    {"0x3a in token", "a:a", 3, {{Item("a:a", Item::kTokenType), {}}}, nullptr},
-    {"0x3b in token",
-     "a;a",
-     3,
-     {{Item("a", Item::kTokenType), {BooleanParam("a", true)}}},
-     nullptr},
-    {"0x3c in token", "a<a", 3, absl::nullopt, nullptr},
-    {"0x3d in token", "a=a", 3, absl::nullopt, nullptr},
-    {"0x3e in token", "a>a", 3, absl::nullopt, nullptr},
-    {"0x3f in token", "a?a", 3, absl::nullopt, nullptr},
-    {"0x40 in token", "a@a", 3, absl::nullopt, nullptr},
-    {"0x41 in token", "aAa", 3, {{Item("aAa", Item::kTokenType), {}}}, nullptr},
-    {"0x42 in token", "aBa", 3, {{Item("aBa", Item::kTokenType), {}}}, nullptr},
-    {"0x43 in token", "aCa", 3, {{Item("aCa", Item::kTokenType), {}}}, nullptr},
-    {"0x44 in token", "aDa", 3, {{Item("aDa", Item::kTokenType), {}}}, nullptr},
-    {"0x45 in token", "aEa", 3, {{Item("aEa", Item::kTokenType), {}}}, nullptr},
-    {"0x46 in token", "aFa", 3, {{Item("aFa", Item::kTokenType), {}}}, nullptr},
-    {"0x47 in token", "aGa", 3, {{Item("aGa", Item::kTokenType), {}}}, nullptr},
-    {"0x48 in token", "aHa", 3, {{Item("aHa", Item::kTokenType), {}}}, nullptr},
-    {"0x49 in token", "aIa", 3, {{Item("aIa", Item::kTokenType), {}}}, nullptr},
-    {"0x4a in token", "aJa", 3, {{Item("aJa", Item::kTokenType), {}}}, nullptr},
-    {"0x4b in token", "aKa", 3, {{Item("aKa", Item::kTokenType), {}}}, nullptr},
-    {"0x4c in token", "aLa", 3, {{Item("aLa", Item::kTokenType), {}}}, nullptr},
-    {"0x4d in token", "aMa", 3, {{Item("aMa", Item::kTokenType), {}}}, nullptr},
-    {"0x4e in token", "aNa", 3, {{Item("aNa", Item::kTokenType), {}}}, nullptr},
-    {"0x4f in token", "aOa", 3, {{Item("aOa", Item::kTokenType), {}}}, nullptr},
-    {"0x50 in token", "aPa", 3, {{Item("aPa", Item::kTokenType), {}}}, nullptr},
-    {"0x51 in token", "aQa", 3, {{Item("aQa", Item::kTokenType), {}}}, nullptr},
-    {"0x52 in token", "aRa", 3, {{Item("aRa", Item::kTokenType), {}}}, nullptr},
-    {"0x53 in token", "aSa", 3, {{Item("aSa", Item::kTokenType), {}}}, nullptr},
-    {"0x54 in token", "aTa", 3, {{Item("aTa", Item::kTokenType), {}}}, nullptr},
-    {"0x55 in token", "aUa", 3, {{Item("aUa", Item::kTokenType), {}}}, nullptr},
-    {"0x56 in token", "aVa", 3, {{Item("aVa", Item::kTokenType), {}}}, nullptr},
-    {"0x57 in token", "aWa", 3, {{Item("aWa", Item::kTokenType), {}}}, nullptr},
-    {"0x58 in token", "aXa", 3, {{Item("aXa", Item::kTokenType), {}}}, nullptr},
-    {"0x59 in token", "aYa", 3, {{Item("aYa", Item::kTokenType), {}}}, nullptr},
-    {"0x5a in token", "aZa", 3, {{Item("aZa", Item::kTokenType), {}}}, nullptr},
-    {"0x5b in token", "a[a", 3, absl::nullopt, nullptr},
-    {"0x5c in token", "a\\a", 3, absl::nullopt, nullptr},
-    {"0x5d in token", "a]a", 3, absl::nullopt, nullptr},
-    {"0x5e in token", "a^a", 3, {{Item("a^a", Item::kTokenType), {}}}, nullptr},
-    {"0x5f in token", "a_a", 3, {{Item("a_a", Item::kTokenType), {}}}, nullptr},
-    {"0x60 in token", "a`a", 3, {{Item("a`a", Item::kTokenType), {}}}, nullptr},
-    {"0x61 in token", "aaa", 3, {{Item("aaa", Item::kTokenType), {}}}, nullptr},
-    {"0x62 in token", "aba", 3, {{Item("aba", Item::kTokenType), {}}}, nullptr},
-    {"0x63 in token", "aca", 3, {{Item("aca", Item::kTokenType), {}}}, nullptr},
-    {"0x64 in token", "ada", 3, {{Item("ada", Item::kTokenType), {}}}, nullptr},
-    {"0x65 in token", "aea", 3, {{Item("aea", Item::kTokenType), {}}}, nullptr},
-    {"0x66 in token", "afa", 3, {{Item("afa", Item::kTokenType), {}}}, nullptr},
-    {"0x67 in token", "aga", 3, {{Item("aga", Item::kTokenType), {}}}, nullptr},
-    {"0x68 in token", "aha", 3, {{Item("aha", Item::kTokenType), {}}}, nullptr},
-    {"0x69 in token", "aia", 3, {{Item("aia", Item::kTokenType), {}}}, nullptr},
-    {"0x6a in token", "aja", 3, {{Item("aja", Item::kTokenType), {}}}, nullptr},
-    {"0x6b in token", "aka", 3, {{Item("aka", Item::kTokenType), {}}}, nullptr},
-    {"0x6c in token", "ala", 3, {{Item("ala", Item::kTokenType), {}}}, nullptr},
-    {"0x6d in token", "ama", 3, {{Item("ama", Item::kTokenType), {}}}, nullptr},
-    {"0x6e in token", "ana", 3, {{Item("ana", Item::kTokenType), {}}}, nullptr},
-    {"0x6f in token", "aoa", 3, {{Item("aoa", Item::kTokenType), {}}}, nullptr},
-    {"0x70 in token", "apa", 3, {{Item("apa", Item::kTokenType), {}}}, nullptr},
-    {"0x71 in token", "aqa", 3, {{Item("aqa", Item::kTokenType), {}}}, nullptr},
-    {"0x72 in token", "ara", 3, {{Item("ara", Item::kTokenType), {}}}, nullptr},
-    {"0x73 in token", "asa", 3, {{Item("asa", Item::kTokenType), {}}}, nullptr},
-    {"0x74 in token", "ata", 3, {{Item("ata", Item::kTokenType), {}}}, nullptr},
-    {"0x75 in token", "aua", 3, {{Item("aua", Item::kTokenType), {}}}, nullptr},
-    {"0x76 in token", "ava", 3, {{Item("ava", Item::kTokenType), {}}}, nullptr},
-    {"0x77 in token", "awa", 3, {{Item("awa", Item::kTokenType), {}}}, nullptr},
-    {"0x78 in token", "axa", 3, {{Item("axa", Item::kTokenType), {}}}, nullptr},
-    {"0x79 in token", "aya", 3, {{Item("aya", Item::kTokenType), {}}}, nullptr},
-    {"0x7a in token", "aza", 3, {{Item("aza", Item::kTokenType), {}}}, nullptr},
-    {"0x7b in token", "a{a", 3, absl::nullopt, nullptr},
-    {"0x7c in token", "a|a", 3, {{Item("a|a", Item::kTokenType), {}}}, nullptr},
-    {"0x7d in token", "a}a", 3, absl::nullopt, nullptr},
-    {"0x7e in token", "a~a", 3, {{Item("a~a", Item::kTokenType), {}}}, nullptr},
-    {"0x7f in token", "a\177a", 3, absl::nullopt, nullptr},
-    {"0x00 starting an token", "\000a", 2, absl::nullopt, nullptr},
-    {"0x01 starting an token", "\001a", 2, absl::nullopt, nullptr},
-    {"0x02 starting an token", "\002a", 2, absl::nullopt, nullptr},
-    {"0x03 starting an token", "\003a", 2, absl::nullopt, nullptr},
-    {"0x04 starting an token", "\004a", 2, absl::nullopt, nullptr},
-    {"0x05 starting an token", "\005a", 2, absl::nullopt, nullptr},
-    {"0x06 starting an token", "\006a", 2, absl::nullopt, nullptr},
-    {"0x07 starting an token", "\aa", 2, absl::nullopt, nullptr},
-    {"0x08 starting an token", "\ba", 2, absl::nullopt, nullptr},
-    {"0x09 starting an token", "\ta", 2, absl::nullopt, nullptr},
-    {"0x0a starting an token", "\na", 2, absl::nullopt, nullptr},
-    {"0x0b starting an token", "\va", 2, absl::nullopt, nullptr},
-    {"0x0c starting an token", "\fa", 2, absl::nullopt, nullptr},
-    {"0x0d starting an token", "\ra", 2, absl::nullopt, nullptr},
-    {"0x0e starting an token", "\016a", 2, absl::nullopt, nullptr},
-    {"0x0f starting an token", "\017a", 2, absl::nullopt, nullptr},
-    {"0x10 starting an token", "\020a", 2, absl::nullopt, nullptr},
-    {"0x11 starting an token", "\021a", 2, absl::nullopt, nullptr},
-    {"0x12 starting an token", "\022a", 2, absl::nullopt, nullptr},
-    {"0x13 starting an token", "\023a", 2, absl::nullopt, nullptr},
-    {"0x14 starting an token", "\024a", 2, absl::nullopt, nullptr},
-    {"0x15 starting an token", "\025a", 2, absl::nullopt, nullptr},
-    {"0x16 starting an token", "\026a", 2, absl::nullopt, nullptr},
-    {"0x17 starting an token", "\027a", 2, absl::nullopt, nullptr},
-    {"0x18 starting an token", "\030a", 2, absl::nullopt, nullptr},
-    {"0x19 starting an token", "\031a", 2, absl::nullopt, nullptr},
-    {"0x1a starting an token", "\032a", 2, absl::nullopt, nullptr},
-    {"0x1b starting an token", "\033a", 2, absl::nullopt, nullptr},
-    {"0x1c starting an token", "\034a", 2, absl::nullopt, nullptr},
-    {"0x1d starting an token", "\035a", 2, absl::nullopt, nullptr},
-    {"0x1e starting an token", "\036a", 2, absl::nullopt, nullptr},
-    {"0x1f starting an token", "\037a", 2, absl::nullopt, nullptr},
-    {"0x20 starting an token",
-     " a",
-     2,
-     {{Item("a", Item::kTokenType), {}}},
-     "a"},
-    {"0x21 starting an token", "!a", 2, absl::nullopt, nullptr},
-    {"0x22 starting an token", "\"a", 2, absl::nullopt, nullptr},
-    {"0x23 starting an token", "#a", 2, absl::nullopt, nullptr},
-    {"0x24 starting an token", "$a", 2, absl::nullopt, nullptr},
-    {"0x25 starting an token", "%a", 2, absl::nullopt, nullptr},
-    {"0x26 starting an token", "&a", 2, absl::nullopt, nullptr},
-    {"0x27 starting an token", "'a", 2, absl::nullopt, nullptr},
-    {"0x28 starting an token", "(a", 2, absl::nullopt, nullptr},
-    {"0x29 starting an token", ")a", 2, absl::nullopt, nullptr},
-    {"0x2a starting an token",
-     "*a",
-     2,
-     {{Item("*a", Item::kTokenType), {}}},
-     nullptr},
-    {"0x2b starting an token", "+a", 2, absl::nullopt, nullptr},
-    {"0x2c starting an token", ",a", 2, absl::nullopt, nullptr},
-    {"0x2d starting an token", "-a", 2, absl::nullopt, nullptr},
-    {"0x2e starting an token", ".a", 2, absl::nullopt, nullptr},
-    {"0x2f starting an token", "/a", 2, absl::nullopt, nullptr},
-    {"0x30 starting an token", "0a", 2, absl::nullopt, nullptr},
-    {"0x31 starting an token", "1a", 2, absl::nullopt, nullptr},
-    {"0x32 starting an token", "2a", 2, absl::nullopt, nullptr},
-    {"0x33 starting an token", "3a", 2, absl::nullopt, nullptr},
-    {"0x34 starting an token", "4a", 2, absl::nullopt, nullptr},
-    {"0x35 starting an token", "5a", 2, absl::nullopt, nullptr},
-    {"0x36 starting an token", "6a", 2, absl::nullopt, nullptr},
-    {"0x37 starting an token", "7a", 2, absl::nullopt, nullptr},
-    {"0x38 starting an token", "8a", 2, absl::nullopt, nullptr},
-    {"0x39 starting an token", "9a", 2, absl::nullopt, nullptr},
-    {"0x3a starting an token", ":a", 2, absl::nullopt, nullptr},
-    {"0x3b starting an token", ";a", 2, absl::nullopt, nullptr},
-    {"0x3c starting an token", "<a", 2, absl::nullopt, nullptr},
-    {"0x3d starting an token", "=a", 2, absl::nullopt, nullptr},
-    {"0x3e starting an token", ">a", 2, absl::nullopt, nullptr},
-    {"0x3f starting an token", "?a", 2, absl::nullopt, nullptr},
-    {"0x40 starting an token", "@a", 2, absl::nullopt, nullptr},
-    {"0x41 starting an token",
-     "Aa",
-     2,
-     {{Item("Aa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x42 starting an token",
-     "Ba",
-     2,
-     {{Item("Ba", Item::kTokenType), {}}},
-     nullptr},
-    {"0x43 starting an token",
-     "Ca",
-     2,
-     {{Item("Ca", Item::kTokenType), {}}},
-     nullptr},
-    {"0x44 starting an token",
-     "Da",
-     2,
-     {{Item("Da", Item::kTokenType), {}}},
-     nullptr},
-    {"0x45 starting an token",
-     "Ea",
-     2,
-     {{Item("Ea", Item::kTokenType), {}}},
-     nullptr},
-    {"0x46 starting an token",
-     "Fa",
-     2,
-     {{Item("Fa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x47 starting an token",
-     "Ga",
-     2,
-     {{Item("Ga", Item::kTokenType), {}}},
-     nullptr},
-    {"0x48 starting an token",
-     "Ha",
-     2,
-     {{Item("Ha", Item::kTokenType), {}}},
-     nullptr},
-    {"0x49 starting an token",
-     "Ia",
-     2,
-     {{Item("Ia", Item::kTokenType), {}}},
-     nullptr},
-    {"0x4a starting an token",
-     "Ja",
-     2,
-     {{Item("Ja", Item::kTokenType), {}}},
-     nullptr},
-    {"0x4b starting an token",
-     "Ka",
-     2,
-     {{Item("Ka", Item::kTokenType), {}}},
-     nullptr},
-    {"0x4c starting an token",
-     "La",
-     2,
-     {{Item("La", Item::kTokenType), {}}},
-     nullptr},
-    {"0x4d starting an token",
-     "Ma",
-     2,
-     {{Item("Ma", Item::kTokenType), {}}},
-     nullptr},
-    {"0x4e starting an token",
-     "Na",
-     2,
-     {{Item("Na", Item::kTokenType), {}}},
-     nullptr},
-    {"0x4f starting an token",
-     "Oa",
-     2,
-     {{Item("Oa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x50 starting an token",
-     "Pa",
-     2,
-     {{Item("Pa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x51 starting an token",
-     "Qa",
-     2,
-     {{Item("Qa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x52 starting an token",
-     "Ra",
-     2,
-     {{Item("Ra", Item::kTokenType), {}}},
-     nullptr},
-    {"0x53 starting an token",
-     "Sa",
-     2,
-     {{Item("Sa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x54 starting an token",
-     "Ta",
-     2,
-     {{Item("Ta", Item::kTokenType), {}}},
-     nullptr},
-    {"0x55 starting an token",
-     "Ua",
-     2,
-     {{Item("Ua", Item::kTokenType), {}}},
-     nullptr},
-    {"0x56 starting an token",
-     "Va",
-     2,
-     {{Item("Va", Item::kTokenType), {}}},
-     nullptr},
-    {"0x57 starting an token",
-     "Wa",
-     2,
-     {{Item("Wa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x58 starting an token",
-     "Xa",
-     2,
-     {{Item("Xa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x59 starting an token",
-     "Ya",
-     2,
-     {{Item("Ya", Item::kTokenType), {}}},
-     nullptr},
-    {"0x5a starting an token",
-     "Za",
-     2,
-     {{Item("Za", Item::kTokenType), {}}},
-     nullptr},
-    {"0x5b starting an token", "[a", 2, absl::nullopt, nullptr},
-    {"0x5c starting an token", "\\a", 2, absl::nullopt, nullptr},
-    {"0x5d starting an token", "]a", 2, absl::nullopt, nullptr},
-    {"0x5e starting an token", "^a", 2, absl::nullopt, nullptr},
-    {"0x5f starting an token", "_a", 2, absl::nullopt, nullptr},
-    {"0x60 starting an token", "`a", 2, absl::nullopt, nullptr},
-    {"0x61 starting an token",
-     "aa",
-     2,
-     {{Item("aa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x62 starting an token",
-     "ba",
-     2,
-     {{Item("ba", Item::kTokenType), {}}},
-     nullptr},
-    {"0x63 starting an token",
-     "ca",
-     2,
-     {{Item("ca", Item::kTokenType), {}}},
-     nullptr},
-    {"0x64 starting an token",
-     "da",
-     2,
-     {{Item("da", Item::kTokenType), {}}},
-     nullptr},
-    {"0x65 starting an token",
-     "ea",
-     2,
-     {{Item("ea", Item::kTokenType), {}}},
-     nullptr},
-    {"0x66 starting an token",
-     "fa",
-     2,
-     {{Item("fa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x67 starting an token",
-     "ga",
-     2,
-     {{Item("ga", Item::kTokenType), {}}},
-     nullptr},
-    {"0x68 starting an token",
-     "ha",
-     2,
-     {{Item("ha", Item::kTokenType), {}}},
-     nullptr},
-    {"0x69 starting an token",
-     "ia",
-     2,
-     {{Item("ia", Item::kTokenType), {}}},
-     nullptr},
-    {"0x6a starting an token",
-     "ja",
-     2,
-     {{Item("ja", Item::kTokenType), {}}},
-     nullptr},
-    {"0x6b starting an token",
-     "ka",
-     2,
-     {{Item("ka", Item::kTokenType), {}}},
-     nullptr},
-    {"0x6c starting an token",
-     "la",
-     2,
-     {{Item("la", Item::kTokenType), {}}},
-     nullptr},
-    {"0x6d starting an token",
-     "ma",
-     2,
-     {{Item("ma", Item::kTokenType), {}}},
-     nullptr},
-    {"0x6e starting an token",
-     "na",
-     2,
-     {{Item("na", Item::kTokenType), {}}},
-     nullptr},
-    {"0x6f starting an token",
-     "oa",
-     2,
-     {{Item("oa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x70 starting an token",
-     "pa",
-     2,
-     {{Item("pa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x71 starting an token",
-     "qa",
-     2,
-     {{Item("qa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x72 starting an token",
-     "ra",
-     2,
-     {{Item("ra", Item::kTokenType), {}}},
-     nullptr},
-    {"0x73 starting an token",
-     "sa",
-     2,
-     {{Item("sa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x74 starting an token",
-     "ta",
-     2,
-     {{Item("ta", Item::kTokenType), {}}},
-     nullptr},
-    {"0x75 starting an token",
-     "ua",
-     2,
-     {{Item("ua", Item::kTokenType), {}}},
-     nullptr},
-    {"0x76 starting an token",
-     "va",
-     2,
-     {{Item("va", Item::kTokenType), {}}},
-     nullptr},
-    {"0x77 starting an token",
-     "wa",
-     2,
-     {{Item("wa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x78 starting an token",
-     "xa",
-     2,
-     {{Item("xa", Item::kTokenType), {}}},
-     nullptr},
-    {"0x79 starting an token",
-     "ya",
-     2,
-     {{Item("ya", Item::kTokenType), {}}},
-     nullptr},
-    {"0x7a starting an token",
-     "za",
-     2,
-     {{Item("za", Item::kTokenType), {}}},
-     nullptr},
-    {"0x7b starting an token", "{a", 2, absl::nullopt, nullptr},
-    {"0x7c starting an token", "|a", 2, absl::nullopt, nullptr},
-    {"0x7d starting an token", "}a", 2, absl::nullopt, nullptr},
-    {"0x7e starting an token", "~a", 2, absl::nullopt, nullptr},
-    {"0x7f starting an token", "\177a", 2, absl::nullopt, nullptr},
-    // token.json
-    {"basic token - item",
-     "a_b-c.d3:f%00/*",
-     15,
-     {{Item("a_b-c.d3:f%00/*", Item::kTokenType), {}}},
-     nullptr},
-    {"token with capitals - item",
-     "fooBar",
-     6,
-     {{Item("fooBar", Item::kTokenType), {}}},
-     nullptr},
-    {"token starting with capitals - item",
-     "FooBar",
-     6,
-     {{Item("FooBar", Item::kTokenType), {}}},
-     nullptr},
-};
-
-const struct ListTestCase {
-  const char* name;
-  const char* raw;
-  size_t raw_len;
-  const absl::optional<List> expected;  // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} list_test_cases[] = {
-    // examples.json
-    {"Example-StrListHeader",
-     "\"foo\", \"bar\", \"It was the best of times.\"",
-     41,
-     {{{Item("foo"), {}},
-       {Item("bar"), {}},
-       {Item("It was the best of times."), {}}}},
-     nullptr},
-    {"Example-Hdr (list on one line)",
-     "foo, bar",
-     8,
-     {{{Item("foo", Item::kTokenType), {}},
-       {Item("bar", Item::kTokenType), {}}}},
-     nullptr},
-    {"Example-Hdr (list on two lines)",
-     "foo, bar",
-     8,
-     {{{Item("foo", Item::kTokenType), {}},
-       {Item("bar", Item::kTokenType), {}}}},
-     "foo, bar"},
-    {"Example-StrListListHeader",
-     "(\"foo\" \"bar\"), (\"baz\"), (\"bat\" \"one\"), ()",
-     41,
-     {{{{{Item("foo"), {}}, {Item("bar"), {}}}, {}},
-       {{{Item("baz"), {}}}, {}},
-       {{{Item("bat"), {}}, {Item("one"), {}}}, {}},
-       {std::vector<ParameterizedItem>(), {}}}},
-     nullptr},
-    {"Example-ListListParam",
-     "(\"foo\"; a=1;b=2);lvl=5, (\"bar\" \"baz\");lvl=1",
-     43,
-     {{{{{Item("foo"), {Param("a", 1), Param("b", 2)}}}, {Param("lvl", 5)}},
-       {{{Item("bar"), {}}, {Item("baz"), {}}}, {Param("lvl", 1)}}}},
-     "(\"foo\";a=1;b=2);lvl=5, (\"bar\" \"baz\");lvl=1"},
-    {"Example-ParamListHeader",
-     "abc;a=1;b=2; cde_456, (ghi;jk=4 l);q=\"9\";r=w",
-     44,
-     {{{Item("abc", Item::kTokenType),
-        {Param("a", 1), Param("b", 2), BooleanParam("cde_456", true)}},
-       {{{Item("ghi", Item::kTokenType), {Param("jk", 4)}},
-         {Item("l", Item::kTokenType), {}}},
-        {Param("q", "9"), TokenParam("r", "w")}}}},
-     "abc;a=1;b=2;cde_456, (ghi;jk=4 l);q=\"9\";r=w"},
-    // key-generated.json
-    {"0x00 in parameterised list key", "foo; a\000a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x01 in parameterised list key", "foo; a\001a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x02 in parameterised list key", "foo; a\002a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x03 in parameterised list key", "foo; a\003a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x04 in parameterised list key", "foo; a\004a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x05 in parameterised list key", "foo; a\005a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x06 in parameterised list key", "foo; a\006a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x07 in parameterised list key", "foo; a\aa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x08 in parameterised list key", "foo; a\ba=1", 10, absl::nullopt,
-     nullptr},
-    {"0x09 in parameterised list key", "foo; a\ta=1", 10, absl::nullopt,
-     nullptr},
-    {"0x0a in parameterised list key", "foo; a\na=1", 10, absl::nullopt,
-     nullptr},
-    {"0x0b in parameterised list key", "foo; a\va=1", 10, absl::nullopt,
-     nullptr},
-    {"0x0c in parameterised list key", "foo; a\fa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x0d in parameterised list key", "foo; a\ra=1", 10, absl::nullopt,
-     nullptr},
-    {"0x0e in parameterised list key", "foo; a\016a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x0f in parameterised list key", "foo; a\017a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x10 in parameterised list key", "foo; a\020a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x11 in parameterised list key", "foo; a\021a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x12 in parameterised list key", "foo; a\022a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x13 in parameterised list key", "foo; a\023a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x14 in parameterised list key", "foo; a\024a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x15 in parameterised list key", "foo; a\025a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x16 in parameterised list key", "foo; a\026a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x17 in parameterised list key", "foo; a\027a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x18 in parameterised list key", "foo; a\030a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x19 in parameterised list key", "foo; a\031a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x1a in parameterised list key", "foo; a\032a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x1b in parameterised list key", "foo; a\033a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x1c in parameterised list key", "foo; a\034a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x1d in parameterised list key", "foo; a\035a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x1e in parameterised list key", "foo; a\036a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x1f in parameterised list key", "foo; a\037a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x20 in parameterised list key", "foo; a a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x21 in parameterised list key", "foo; a!a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x22 in parameterised list key", "foo; a\"a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x23 in parameterised list key", "foo; a#a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x24 in parameterised list key", "foo; a$a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x25 in parameterised list key", "foo; a%a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x26 in parameterised list key", "foo; a&a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x27 in parameterised list key", "foo; a'a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x28 in parameterised list key", "foo; a(a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x29 in parameterised list key", "foo; a)a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x2a in parameterised list key",
-     "foo; a*a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a*a", 1)}}}},
-     "foo;a*a=1"},
-    {"0x2b in parameterised list key", "foo; a+a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x2c in parameterised list key", "foo; a,a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x2d in parameterised list key",
-     "foo; a-a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a-a", 1)}}}},
-     "foo;a-a=1"},
-    {"0x2e in parameterised list key",
-     "foo; a.a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a.a", 1)}}}},
-     "foo;a.a=1"},
-    {"0x2f in parameterised list key", "foo; a/a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x30 in parameterised list key",
-     "foo; a0a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a0a", 1)}}}},
-     "foo;a0a=1"},
-    {"0x31 in parameterised list key",
-     "foo; a1a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a1a", 1)}}}},
-     "foo;a1a=1"},
-    {"0x32 in parameterised list key",
-     "foo; a2a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a2a", 1)}}}},
-     "foo;a2a=1"},
-    {"0x33 in parameterised list key",
-     "foo; a3a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a3a", 1)}}}},
-     "foo;a3a=1"},
-    {"0x34 in parameterised list key",
-     "foo; a4a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a4a", 1)}}}},
-     "foo;a4a=1"},
-    {"0x35 in parameterised list key",
-     "foo; a5a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a5a", 1)}}}},
-     "foo;a5a=1"},
-    {"0x36 in parameterised list key",
-     "foo; a6a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a6a", 1)}}}},
-     "foo;a6a=1"},
-    {"0x37 in parameterised list key",
-     "foo; a7a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a7a", 1)}}}},
-     "foo;a7a=1"},
-    {"0x38 in parameterised list key",
-     "foo; a8a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a8a", 1)}}}},
-     "foo;a8a=1"},
-    {"0x39 in parameterised list key",
-     "foo; a9a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a9a", 1)}}}},
-     "foo;a9a=1"},
-    {"0x3a in parameterised list key", "foo; a:a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x3b in parameterised list key",
-     "foo; a;a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a", 1)}}}},
-     "foo;a=1"},
-    {"0x3c in parameterised list key", "foo; a<a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x3d in parameterised list key", "foo; a=a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x3e in parameterised list key", "foo; a>a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x3f in parameterised list key", "foo; a?a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x40 in parameterised list key", "foo; a@a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x41 in parameterised list key", "foo; aAa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x42 in parameterised list key", "foo; aBa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x43 in parameterised list key", "foo; aCa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x44 in parameterised list key", "foo; aDa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x45 in parameterised list key", "foo; aEa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x46 in parameterised list key", "foo; aFa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x47 in parameterised list key", "foo; aGa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x48 in parameterised list key", "foo; aHa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x49 in parameterised list key", "foo; aIa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x4a in parameterised list key", "foo; aJa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x4b in parameterised list key", "foo; aKa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x4c in parameterised list key", "foo; aLa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x4d in parameterised list key", "foo; aMa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x4e in parameterised list key", "foo; aNa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x4f in parameterised list key", "foo; aOa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x50 in parameterised list key", "foo; aPa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x51 in parameterised list key", "foo; aQa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x52 in parameterised list key", "foo; aRa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x53 in parameterised list key", "foo; aSa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x54 in parameterised list key", "foo; aTa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x55 in parameterised list key", "foo; aUa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x56 in parameterised list key", "foo; aVa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x57 in parameterised list key", "foo; aWa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x58 in parameterised list key", "foo; aXa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x59 in parameterised list key", "foo; aYa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x5a in parameterised list key", "foo; aZa=1", 10, absl::nullopt,
-     nullptr},
-    {"0x5b in parameterised list key", "foo; a[a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x5c in parameterised list key", "foo; a\\a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x5d in parameterised list key", "foo; a]a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x5e in parameterised list key", "foo; a^a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x5f in parameterised list key",
-     "foo; a_a=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("a_a", 1)}}}},
-     "foo;a_a=1"},
-    {"0x60 in parameterised list key", "foo; a`a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x61 in parameterised list key",
-     "foo; aaa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aaa", 1)}}}},
-     "foo;aaa=1"},
-    {"0x62 in parameterised list key",
-     "foo; aba=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aba", 1)}}}},
-     "foo;aba=1"},
-    {"0x63 in parameterised list key",
-     "foo; aca=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aca", 1)}}}},
-     "foo;aca=1"},
-    {"0x64 in parameterised list key",
-     "foo; ada=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ada", 1)}}}},
-     "foo;ada=1"},
-    {"0x65 in parameterised list key",
-     "foo; aea=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aea", 1)}}}},
-     "foo;aea=1"},
-    {"0x66 in parameterised list key",
-     "foo; afa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("afa", 1)}}}},
-     "foo;afa=1"},
-    {"0x67 in parameterised list key",
-     "foo; aga=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aga", 1)}}}},
-     "foo;aga=1"},
-    {"0x68 in parameterised list key",
-     "foo; aha=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aha", 1)}}}},
-     "foo;aha=1"},
-    {"0x69 in parameterised list key",
-     "foo; aia=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aia", 1)}}}},
-     "foo;aia=1"},
-    {"0x6a in parameterised list key",
-     "foo; aja=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aja", 1)}}}},
-     "foo;aja=1"},
-    {"0x6b in parameterised list key",
-     "foo; aka=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aka", 1)}}}},
-     "foo;aka=1"},
-    {"0x6c in parameterised list key",
-     "foo; ala=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ala", 1)}}}},
-     "foo;ala=1"},
-    {"0x6d in parameterised list key",
-     "foo; ama=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ama", 1)}}}},
-     "foo;ama=1"},
-    {"0x6e in parameterised list key",
-     "foo; ana=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ana", 1)}}}},
-     "foo;ana=1"},
-    {"0x6f in parameterised list key",
-     "foo; aoa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aoa", 1)}}}},
-     "foo;aoa=1"},
-    {"0x70 in parameterised list key",
-     "foo; apa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("apa", 1)}}}},
-     "foo;apa=1"},
-    {"0x71 in parameterised list key",
-     "foo; aqa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aqa", 1)}}}},
-     "foo;aqa=1"},
-    {"0x72 in parameterised list key",
-     "foo; ara=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ara", 1)}}}},
-     "foo;ara=1"},
-    {"0x73 in parameterised list key",
-     "foo; asa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("asa", 1)}}}},
-     "foo;asa=1"},
-    {"0x74 in parameterised list key",
-     "foo; ata=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ata", 1)}}}},
-     "foo;ata=1"},
-    {"0x75 in parameterised list key",
-     "foo; aua=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aua", 1)}}}},
-     "foo;aua=1"},
-    {"0x76 in parameterised list key",
-     "foo; ava=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("ava", 1)}}}},
-     "foo;ava=1"},
-    {"0x77 in parameterised list key",
-     "foo; awa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("awa", 1)}}}},
-     "foo;awa=1"},
-    {"0x78 in parameterised list key",
-     "foo; axa=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("axa", 1)}}}},
-     "foo;axa=1"},
-    {"0x79 in parameterised list key",
-     "foo; aya=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aya", 1)}}}},
-     "foo;aya=1"},
-    {"0x7a in parameterised list key",
-     "foo; aza=1",
-     10,
-     {{{Item("foo", Item::kTokenType), {Param("aza", 1)}}}},
-     "foo;aza=1"},
-    {"0x7b in parameterised list key", "foo; a{a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x7c in parameterised list key", "foo; a|a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x7d in parameterised list key", "foo; a}a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x7e in parameterised list key", "foo; a~a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x7f in parameterised list key", "foo; a\177a=1", 10, absl::nullopt,
-     nullptr},
-    {"0x00 starting a parameterised list key", "foo; \000a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x01 starting a parameterised list key", "foo; \001a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x02 starting a parameterised list key", "foo; \002a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x03 starting a parameterised list key", "foo; \003a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x04 starting a parameterised list key", "foo; \004a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x05 starting a parameterised list key", "foo; \005a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x06 starting a parameterised list key", "foo; \006a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x07 starting a parameterised list key", "foo; \aa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x08 starting a parameterised list key", "foo; \ba=1", 9, absl::nullopt,
-     nullptr},
-    {"0x09 starting a parameterised list key", "foo; \ta=1", 9, absl::nullopt,
-     nullptr},
-    {"0x0a starting a parameterised list key", "foo; \na=1", 9, absl::nullopt,
-     nullptr},
-    {"0x0b starting a parameterised list key", "foo; \va=1", 9, absl::nullopt,
-     nullptr},
-    {"0x0c starting a parameterised list key", "foo; \fa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x0d starting a parameterised list key", "foo; \ra=1", 9, absl::nullopt,
-     nullptr},
-    {"0x0e starting a parameterised list key", "foo; \016a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x0f starting a parameterised list key", "foo; \017a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x10 starting a parameterised list key", "foo; \020a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x11 starting a parameterised list key", "foo; \021a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x12 starting a parameterised list key", "foo; \022a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x13 starting a parameterised list key", "foo; \023a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x14 starting a parameterised list key", "foo; \024a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x15 starting a parameterised list key", "foo; \025a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x16 starting a parameterised list key", "foo; \026a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x17 starting a parameterised list key", "foo; \027a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x18 starting a parameterised list key", "foo; \030a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x19 starting a parameterised list key", "foo; \031a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x1a starting a parameterised list key", "foo; \032a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x1b starting a parameterised list key", "foo; \033a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x1c starting a parameterised list key", "foo; \034a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x1d starting a parameterised list key", "foo; \035a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x1e starting a parameterised list key", "foo; \036a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x1f starting a parameterised list key", "foo; \037a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x20 starting a parameterised list key",
-     "foo;  a=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("a", 1)}}}},
-     "foo;a=1"},
-    {"0x21 starting a parameterised list key", "foo; !a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x22 starting a parameterised list key", "foo; \"a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x23 starting a parameterised list key", "foo; #a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x24 starting a parameterised list key", "foo; $a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x25 starting a parameterised list key", "foo; %a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x26 starting a parameterised list key", "foo; &a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x27 starting a parameterised list key", "foo; 'a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x28 starting a parameterised list key", "foo; (a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x29 starting a parameterised list key", "foo; )a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x2a starting a parameterised list key",
-     "foo; *a=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("*a", 1)}}}},
-     "foo;*a=1"},
-    {"0x2b starting a parameterised list key", "foo; +a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x2c starting a parameterised list key", "foo; ,a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x2d starting a parameterised list key", "foo; -a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x2e starting a parameterised list key", "foo; .a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x2f starting a parameterised list key", "foo; /a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x30 starting a parameterised list key", "foo; 0a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x31 starting a parameterised list key", "foo; 1a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x32 starting a parameterised list key", "foo; 2a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x33 starting a parameterised list key", "foo; 3a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x34 starting a parameterised list key", "foo; 4a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x35 starting a parameterised list key", "foo; 5a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x36 starting a parameterised list key", "foo; 6a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x37 starting a parameterised list key", "foo; 7a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x38 starting a parameterised list key", "foo; 8a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x39 starting a parameterised list key", "foo; 9a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x3a starting a parameterised list key", "foo; :a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x3b starting a parameterised list key", "foo; ;a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x3c starting a parameterised list key", "foo; <a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x3d starting a parameterised list key", "foo; =a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x3e starting a parameterised list key", "foo; >a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x3f starting a parameterised list key", "foo; ?a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x40 starting a parameterised list key", "foo; @a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x41 starting a parameterised list key", "foo; Aa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x42 starting a parameterised list key", "foo; Ba=1", 9, absl::nullopt,
-     nullptr},
-    {"0x43 starting a parameterised list key", "foo; Ca=1", 9, absl::nullopt,
-     nullptr},
-    {"0x44 starting a parameterised list key", "foo; Da=1", 9, absl::nullopt,
-     nullptr},
-    {"0x45 starting a parameterised list key", "foo; Ea=1", 9, absl::nullopt,
-     nullptr},
-    {"0x46 starting a parameterised list key", "foo; Fa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x47 starting a parameterised list key", "foo; Ga=1", 9, absl::nullopt,
-     nullptr},
-    {"0x48 starting a parameterised list key", "foo; Ha=1", 9, absl::nullopt,
-     nullptr},
-    {"0x49 starting a parameterised list key", "foo; Ia=1", 9, absl::nullopt,
-     nullptr},
-    {"0x4a starting a parameterised list key", "foo; Ja=1", 9, absl::nullopt,
-     nullptr},
-    {"0x4b starting a parameterised list key", "foo; Ka=1", 9, absl::nullopt,
-     nullptr},
-    {"0x4c starting a parameterised list key", "foo; La=1", 9, absl::nullopt,
-     nullptr},
-    {"0x4d starting a parameterised list key", "foo; Ma=1", 9, absl::nullopt,
-     nullptr},
-    {"0x4e starting a parameterised list key", "foo; Na=1", 9, absl::nullopt,
-     nullptr},
-    {"0x4f starting a parameterised list key", "foo; Oa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x50 starting a parameterised list key", "foo; Pa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x51 starting a parameterised list key", "foo; Qa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x52 starting a parameterised list key", "foo; Ra=1", 9, absl::nullopt,
-     nullptr},
-    {"0x53 starting a parameterised list key", "foo; Sa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x54 starting a parameterised list key", "foo; Ta=1", 9, absl::nullopt,
-     nullptr},
-    {"0x55 starting a parameterised list key", "foo; Ua=1", 9, absl::nullopt,
-     nullptr},
-    {"0x56 starting a parameterised list key", "foo; Va=1", 9, absl::nullopt,
-     nullptr},
-    {"0x57 starting a parameterised list key", "foo; Wa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x58 starting a parameterised list key", "foo; Xa=1", 9, absl::nullopt,
-     nullptr},
-    {"0x59 starting a parameterised list key", "foo; Ya=1", 9, absl::nullopt,
-     nullptr},
-    {"0x5a starting a parameterised list key", "foo; Za=1", 9, absl::nullopt,
-     nullptr},
-    {"0x5b starting a parameterised list key", "foo; [a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x5c starting a parameterised list key", "foo; \\a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x5d starting a parameterised list key", "foo; ]a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x5e starting a parameterised list key", "foo; ^a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x5f starting a parameterised list key", "foo; _a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x60 starting a parameterised list key", "foo; `a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x61 starting a parameterised list key",
-     "foo; aa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("aa", 1)}}}},
-     "foo;aa=1"},
-    {"0x62 starting a parameterised list key",
-     "foo; ba=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ba", 1)}}}},
-     "foo;ba=1"},
-    {"0x63 starting a parameterised list key",
-     "foo; ca=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ca", 1)}}}},
-     "foo;ca=1"},
-    {"0x64 starting a parameterised list key",
-     "foo; da=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("da", 1)}}}},
-     "foo;da=1"},
-    {"0x65 starting a parameterised list key",
-     "foo; ea=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ea", 1)}}}},
-     "foo;ea=1"},
-    {"0x66 starting a parameterised list key",
-     "foo; fa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("fa", 1)}}}},
-     "foo;fa=1"},
-    {"0x67 starting a parameterised list key",
-     "foo; ga=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ga", 1)}}}},
-     "foo;ga=1"},
-    {"0x68 starting a parameterised list key",
-     "foo; ha=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ha", 1)}}}},
-     "foo;ha=1"},
-    {"0x69 starting a parameterised list key",
-     "foo; ia=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ia", 1)}}}},
-     "foo;ia=1"},
-    {"0x6a starting a parameterised list key",
-     "foo; ja=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ja", 1)}}}},
-     "foo;ja=1"},
-    {"0x6b starting a parameterised list key",
-     "foo; ka=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ka", 1)}}}},
-     "foo;ka=1"},
-    {"0x6c starting a parameterised list key",
-     "foo; la=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("la", 1)}}}},
-     "foo;la=1"},
-    {"0x6d starting a parameterised list key",
-     "foo; ma=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ma", 1)}}}},
-     "foo;ma=1"},
-    {"0x6e starting a parameterised list key",
-     "foo; na=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("na", 1)}}}},
-     "foo;na=1"},
-    {"0x6f starting a parameterised list key",
-     "foo; oa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("oa", 1)}}}},
-     "foo;oa=1"},
-    {"0x70 starting a parameterised list key",
-     "foo; pa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("pa", 1)}}}},
-     "foo;pa=1"},
-    {"0x71 starting a parameterised list key",
-     "foo; qa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("qa", 1)}}}},
-     "foo;qa=1"},
-    {"0x72 starting a parameterised list key",
-     "foo; ra=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ra", 1)}}}},
-     "foo;ra=1"},
-    {"0x73 starting a parameterised list key",
-     "foo; sa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("sa", 1)}}}},
-     "foo;sa=1"},
-    {"0x74 starting a parameterised list key",
-     "foo; ta=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ta", 1)}}}},
-     "foo;ta=1"},
-    {"0x75 starting a parameterised list key",
-     "foo; ua=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ua", 1)}}}},
-     "foo;ua=1"},
-    {"0x76 starting a parameterised list key",
-     "foo; va=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("va", 1)}}}},
-     "foo;va=1"},
-    {"0x77 starting a parameterised list key",
-     "foo; wa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("wa", 1)}}}},
-     "foo;wa=1"},
-    {"0x78 starting a parameterised list key",
-     "foo; xa=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("xa", 1)}}}},
-     "foo;xa=1"},
-    {"0x79 starting a parameterised list key",
-     "foo; ya=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("ya", 1)}}}},
-     "foo;ya=1"},
-    {"0x7a starting a parameterised list key",
-     "foo; za=1",
-     9,
-     {{{Item("foo", Item::kTokenType), {Param("za", 1)}}}},
-     "foo;za=1"},
-    {"0x7b starting a parameterised list key", "foo; {a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x7c starting a parameterised list key", "foo; |a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x7d starting a parameterised list key", "foo; }a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x7e starting a parameterised list key", "foo; ~a=1", 9, absl::nullopt,
-     nullptr},
-    {"0x7f starting a parameterised list key", "foo; \177a=1", 9, absl::nullopt,
-     nullptr},
-    // list.json
-    {"basic list",
-     "1, 42",
-     5,
-     {{{Integer(1), {}}, {Integer(42), {}}}},
-     nullptr},
-    {"empty list", "", 0, {List()}, nullptr},
-    {"leading SP list",
-     "  42, 43",
-     8,
-     {{{Integer(42), {}}, {Integer(43), {}}}},
-     "42, 43"},
-    {"single item list", "42", 2, {{{Integer(42), {}}}}, nullptr},
-    {"no whitespace list",
-     "1,42",
-     4,
-     {{{Integer(1), {}}, {Integer(42), {}}}},
-     "1, 42"},
-    {"extra whitespace list",
-     "1 , 42",
-     6,
-     {{{Integer(1), {}}, {Integer(42), {}}}},
-     "1, 42"},
-    {"tab separated list",
-     "1\t,\t42",
-     6,
-     {{{Integer(1), {}}, {Integer(42), {}}}},
-     "1, 42"},
-    {"two line list",
-     "1, 42",
-     5,
-     {{{Integer(1), {}}, {Integer(42), {}}}},
-     "1, 42"},
-    {"trailing comma list", "1, 42,", 6, absl::nullopt, nullptr},
-    {"empty item list", "1,,42", 5, absl::nullopt, nullptr},
-    {"empty item list (multiple field lines)", "1, , 42", 7, absl::nullopt,
-     nullptr},
-    // listlist.json
-    {"basic list of lists",
-     "(1 2), (42 43)",
-     14,
-     {{{{{Integer(1), {}}, {Integer(2), {}}}, {}},
-       {{{Integer(42), {}}, {Integer(43), {}}}, {}}}},
-     nullptr},
-    {"single item list of lists",
-     "(42)",
-     4,
-     {{{{{Integer(42), {}}}, {}}}},
-     nullptr},
-    {"empty item list of lists",
-     "()",
-     2,
-     {{{std::vector<ParameterizedItem>(), {}}}},
-     nullptr},
-    {"empty middle item list of lists",
-     "(1),(),(42)",
-     11,
-     {{{{{Integer(1), {}}}, {}},
-       {std::vector<ParameterizedItem>(), {}},
-       {{{Integer(42), {}}}, {}}}},
-     "(1), (), (42)"},
-    {"extra whitespace list of lists",
-     "(  1  42  )",
-     11,
-     {{{{{Integer(1), {}}, {Integer(42), {}}}, {}}}},
-     "(1 42)"},
-    {"wrong whitespace list of lists", "(1\t 42)", 7, absl::nullopt, nullptr},
-    {"no trailing parenthesis list of lists", "(1 42", 5, absl::nullopt,
-     nullptr},
-    {"no trailing parenthesis middle list of lists", "(1 2, (42 43)", 13,
-     absl::nullopt, nullptr},
-    {"no spaces in inner-list", "(abc\"def\"?0123*dXZ3*xyz)", 24, absl::nullopt,
-     nullptr},
-    {"no closing parenthesis", "(", 1, absl::nullopt, nullptr},
-    // param-list.json
-    {"basic parameterised list",
-     "abc_123;a=1;b=2; cdef_456, ghi;q=9;r=\"+w\"",
-     41,
-     {{{Item("abc_123", Item::kTokenType),
-        {Param("a", 1), Param("b", 2), BooleanParam("cdef_456", true)}},
-       {Item("ghi", Item::kTokenType), {Param("q", 9), Param("r", "+w")}}}},
-     "abc_123;a=1;b=2;cdef_456, ghi;q=9;r=\"+w\""},
-    {"single item parameterised list",
-     "text/html;q=1.0",
-     15,
-     {{{Item("text/html", Item::kTokenType), {DoubleParam("q", 1.000000)}}}},
-     nullptr},
-    {"missing parameter value parameterised list",
-     "text/html;a;q=1.0",
-     17,
-     {{{Item("text/html", Item::kTokenType),
-        {BooleanParam("a", true), DoubleParam("q", 1.000000)}}}},
-     nullptr},
-    {"missing terminal parameter value parameterised list",
-     "text/html;q=1.0;a",
-     17,
-     {{{Item("text/html", Item::kTokenType),
-        {DoubleParam("q", 1.000000), BooleanParam("a", true)}}}},
-     nullptr},
-    {"no whitespace parameterised list",
-     "text/html,text/plain;q=0.5",
-     26,
-     {{{Item("text/html", Item::kTokenType), {}},
-       {Item("text/plain", Item::kTokenType), {DoubleParam("q", 0.500000)}}}},
-     "text/html, text/plain;q=0.5"},
-    {"whitespace before = parameterised list", "text/html, text/plain;q =0.5",
-     28, absl::nullopt, nullptr},
-    {"whitespace after = parameterised list", "text/html, text/plain;q= 0.5",
-     28, absl::nullopt, nullptr},
-    {"whitespace before ; parameterised list", "text/html, text/plain ;q=0.5",
-     28, absl::nullopt, nullptr},
-    {"whitespace after ; parameterised list",
-     "text/html, text/plain; q=0.5",
-     28,
-     {{{Item("text/html", Item::kTokenType), {}},
-       {Item("text/plain", Item::kTokenType), {DoubleParam("q", 0.500000)}}}},
-     "text/html, text/plain;q=0.5"},
-    {"extra whitespace parameterised list",
-     "text/html  ,  text/plain;  q=0.5;  charset=utf-8",
-     48,
-     {{{Item("text/html", Item::kTokenType), {}},
-       {Item("text/plain", Item::kTokenType),
-        {DoubleParam("q", 0.500000), TokenParam("charset", "utf-8")}}}},
-     "text/html, text/plain;q=0.5;charset=utf-8"},
-    {"two lines parameterised list",
-     "text/html, text/plain;q=0.5",
-     27,
-     {{{Item("text/html", Item::kTokenType), {}},
-       {Item("text/plain", Item::kTokenType), {DoubleParam("q", 0.500000)}}}},
-     "text/html, text/plain;q=0.5"},
-    {"trailing comma parameterised list", "text/html,text/plain;q=0.5,", 27,
-     absl::nullopt, nullptr},
-    {"empty item parameterised list", "text/html,,text/plain;q=0.5,", 28,
-     absl::nullopt, nullptr},
-    // param-listlist.json
-    {"parameterised inner list",
-     "(abc_123);a=1;b=2, cdef_456",
-     27,
-     {{{{{Item("abc_123", Item::kTokenType), {}}},
-        {Param("a", 1), Param("b", 2)}},
-       {Item("cdef_456", Item::kTokenType), {}}}},
-     nullptr},
-    {"parameterised inner list item",
-     "(abc_123;a=1;b=2;cdef_456)",
-     26,
-     {{{{{Item("abc_123", Item::kTokenType),
-          {Param("a", 1), Param("b", 2), BooleanParam("cdef_456", true)}}},
-        {}}}},
-     nullptr},
-    {"parameterised inner list with parameterised item",
-     "(abc_123;a=1;b=2);cdef_456",
-     26,
-     {{{{{Item("abc_123", Item::kTokenType), {Param("a", 1), Param("b", 2)}}},
-        {BooleanParam("cdef_456", true)}}}},
-     nullptr},
-    // token.json
-    {"basic token - list",
-     "a_b-c3/*",
-     8,
-     {{{Item("a_b-c3/*", Item::kTokenType), {}}}},
-     nullptr},
-    {"token with capitals - list",
-     "fooBar",
-     6,
-     {{{Item("fooBar", Item::kTokenType), {}}}},
-     nullptr},
-    {"token starting with capitals - list",
-     "FooBar",
-     6,
-     {{{Item("FooBar", Item::kTokenType), {}}}},
-     nullptr},
-};
-
-const struct DictionaryTestCase {
-  const char* name;
-  const char* raw;
-  size_t raw_len;
-  const absl::optional<Dictionary>
-      expected;           // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} dictionary_test_cases[] = {
-    // dictionary.json
-    {"basic dictionary",
-     "en=\"Applepie\", da=:w4ZibGV0w6ZydGUK:",
-     36,
-     {Dictionary{
-         {{"en", {Item("Applepie"), {}}},
-          {"da",
-           {Item("\303\206blet\303\246rte\n", Item::kByteSequenceType), {}}}}}},
-     nullptr},
-    {"empty dictionary", "", 0, {Dictionary{{}}}, nullptr},
-    {"single item dictionary",
-     "a=1",
-     3,
-     {Dictionary{{{"a", {Integer(1), {}}}}}},
-     nullptr},
-    {"list item dictionary",
-     "a=(1 2)",
-     7,
-     {Dictionary{{{"a", {{{Integer(1), {}}, {Integer(2), {}}}, {}}}}}},
-     nullptr},
-    {"single list item dictionary",
-     "a=(1)",
-     5,
-     {Dictionary{{{"a", {{{Integer(1), {}}}, {}}}}}},
-     nullptr},
-    {"empty list item dictionary",
-     "a=()",
-     4,
-     {Dictionary{{{"a", {std::vector<ParameterizedItem>(), {}}}}}},
-     nullptr},
-    {"no whitespace dictionary",
-     "a=1,b=2",
-     7,
-     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
-     "a=1, b=2"},
-    {"extra whitespace dictionary",
-     "a=1 ,  b=2",
-     10,
-     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
-     "a=1, b=2"},
-    {"tab separated dictionary",
-     "a=1\t,\tb=2",
-     9,
-     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
-     "a=1, b=2"},
-    {"leading whitespace dictionary",
-     "     a=1 ,  b=2",
-     15,
-     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
-     "a=1, b=2"},
-    {"whitespace before = dictionary", "a =1, b=2", 9, absl::nullopt, nullptr},
-    {"whitespace after = dictionary", "a=1, b= 2", 9, absl::nullopt, nullptr},
-    {"two lines dictionary",
-     "a=1, b=2",
-     8,
-     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
-     "a=1, b=2"},
-    {"missing value dictionary",
-     "a=1, b, c=3",
-     11,
-     {Dictionary{{{"a", {Integer(1), {}}},
-                  {"b", {Item(true), {}}},
-                  {"c", {Integer(3), {}}}}}},
-     nullptr},
-    {"all missing value dictionary",
-     "a, b, c",
-     7,
-     {Dictionary{{{"a", {Item(true), {}}},
-                  {"b", {Item(true), {}}},
-                  {"c", {Item(true), {}}}}}},
-     nullptr},
-    {"start missing value dictionary",
-     "a, b=2",
-     6,
-     {Dictionary{{{"a", {Item(true), {}}}, {"b", {Integer(2), {}}}}}},
-     nullptr},
-    {"end missing value dictionary",
-     "a=1, b",
-     6,
-     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Item(true), {}}}}}},
-     nullptr},
-    {"missing value with params dictionary",
-     "a=1, b;foo=9, c=3",
-     17,
-     {Dictionary{{{"a", {Integer(1), {}}},
-                  {"b", {Item(true), {Param("foo", 9)}}},
-                  {"c", {Integer(3), {}}}}}},
-     nullptr},
-    {"explicit true value with params dictionary",
-     "a=1, b=?1;foo=9, c=3",
-     20,
-     {Dictionary{{{"a", {Integer(1), {}}},
-                  {"b", {Item(true), {Param("foo", 9)}}},
-                  {"c", {Integer(3), {}}}}}},
-     "a=1, b;foo=9, c=3"},
-    {"trailing comma dictionary", "a=1, b=2,", 9, absl::nullopt, nullptr},
-    {"empty item dictionary", "a=1,,b=2,", 9, absl::nullopt, nullptr},
-    {"duplicate key dictionary",
-     "a=1,b=2,a=3",
-     11,
-     {Dictionary{{{"a", {Integer(3), {}}}, {"b", {Integer(2), {}}}}}},
-     "a=3, b=2"},
-    {"numeric key dictionary", "a=1,1b=2,a=1", 12, absl::nullopt, nullptr},
-    {"uppercase key dictionary", "a=1,B=2,a=1", 11, absl::nullopt, nullptr},
-    {"bad key dictionary", "a=1,b!=2,a=1", 12, absl::nullopt, nullptr},
-    // examples.json
-    {"Example-DictHeader",
-     "en=\"Applepie\", da=:w4ZibGV0w6ZydGU=:",
-     36,
-     {Dictionary{
-         {{"en", {Item("Applepie"), {}}},
-          {"da",
-           {Item("\303\206blet\303\246rte", Item::kByteSequenceType), {}}}}}},
-     nullptr},
-    {"Example-DictHeader (boolean values)",
-     "a=?0, b, c; foo=bar",
-     19,
-     {Dictionary{{{"a", {Item(false), {}}},
-                  {"b", {Item(true), {}}},
-                  {"c", {Item(true), {TokenParam("foo", "bar")}}}}}},
-     "a=?0, b, c;foo=bar"},
-    {"Example-DictListHeader",
-     "rating=1.5, feelings=(joy sadness)",
-     34,
-     {Dictionary{{{"rating", {Item(1.500000), {}}},
-                  {"feelings",
-                   {{{Item("joy", Item::kTokenType), {}},
-                     {Item("sadness", Item::kTokenType), {}}},
-                    {}}}}}},
-     nullptr},
-    {"Example-MixDict",
-     "a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid",
-     38,
-     {Dictionary{{{"a", {{{Integer(1), {}}, {Integer(2), {}}}, {}}},
-                  {"b", {Integer(3), {}}},
-                  {"c", {Integer(4), {TokenParam("aa", "bb")}}},
-                  {"d",
-                   {{{Integer(5), {}}, {Integer(6), {}}},
-                    {BooleanParam("valid", true)}}}}}},
-     "a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid"},
-    {"Example-Hdr (dictionary on one line)",
-     "foo=1, bar=2",
-     12,
-     {Dictionary{{{"foo", {Integer(1), {}}}, {"bar", {Integer(2), {}}}}}},
-     nullptr},
-    {"Example-Hdr (dictionary on two lines)",
-     "foo=1, bar=2",
-     12,
-     {Dictionary{{{"foo", {Integer(1), {}}}, {"bar", {Integer(2), {}}}}}},
-     "foo=1, bar=2"},
-    // key-generated.json
-    {"0x00 as a single-character dictionary key", "\000=1", 3, absl::nullopt,
-     nullptr},
-    {"0x01 as a single-character dictionary key", "\001=1", 3, absl::nullopt,
-     nullptr},
-    {"0x02 as a single-character dictionary key", "\002=1", 3, absl::nullopt,
-     nullptr},
-    {"0x03 as a single-character dictionary key", "\003=1", 3, absl::nullopt,
-     nullptr},
-    {"0x04 as a single-character dictionary key", "\004=1", 3, absl::nullopt,
-     nullptr},
-    {"0x05 as a single-character dictionary key", "\005=1", 3, absl::nullopt,
-     nullptr},
-    {"0x06 as a single-character dictionary key", "\006=1", 3, absl::nullopt,
-     nullptr},
-    {"0x07 as a single-character dictionary key", "\a=1", 3, absl::nullopt,
-     nullptr},
-    {"0x08 as a single-character dictionary key", "\b=1", 3, absl::nullopt,
-     nullptr},
-    {"0x09 as a single-character dictionary key", "\t=1", 3, absl::nullopt,
-     nullptr},
-    {"0x0a as a single-character dictionary key", "\n=1", 3, absl::nullopt,
-     nullptr},
-    {"0x0b as a single-character dictionary key", "\v=1", 3, absl::nullopt,
-     nullptr},
-    {"0x0c as a single-character dictionary key", "\f=1", 3, absl::nullopt,
-     nullptr},
-    {"0x0d as a single-character dictionary key", "\r=1", 3, absl::nullopt,
-     nullptr},
-    {"0x0e as a single-character dictionary key", "\016=1", 3, absl::nullopt,
-     nullptr},
-    {"0x0f as a single-character dictionary key", "\017=1", 3, absl::nullopt,
-     nullptr},
-    {"0x10 as a single-character dictionary key", "\020=1", 3, absl::nullopt,
-     nullptr},
-    {"0x11 as a single-character dictionary key", "\021=1", 3, absl::nullopt,
-     nullptr},
-    {"0x12 as a single-character dictionary key", "\022=1", 3, absl::nullopt,
-     nullptr},
-    {"0x13 as a single-character dictionary key", "\023=1", 3, absl::nullopt,
-     nullptr},
-    {"0x14 as a single-character dictionary key", "\024=1", 3, absl::nullopt,
-     nullptr},
-    {"0x15 as a single-character dictionary key", "\025=1", 3, absl::nullopt,
-     nullptr},
-    {"0x16 as a single-character dictionary key", "\026=1", 3, absl::nullopt,
-     nullptr},
-    {"0x17 as a single-character dictionary key", "\027=1", 3, absl::nullopt,
-     nullptr},
-    {"0x18 as a single-character dictionary key", "\030=1", 3, absl::nullopt,
-     nullptr},
-    {"0x19 as a single-character dictionary key", "\031=1", 3, absl::nullopt,
-     nullptr},
-    {"0x1a as a single-character dictionary key", "\032=1", 3, absl::nullopt,
-     nullptr},
-    {"0x1b as a single-character dictionary key", "\033=1", 3, absl::nullopt,
-     nullptr},
-    {"0x1c as a single-character dictionary key", "\034=1", 3, absl::nullopt,
-     nullptr},
-    {"0x1d as a single-character dictionary key", "\035=1", 3, absl::nullopt,
-     nullptr},
-    {"0x1e as a single-character dictionary key", "\036=1", 3, absl::nullopt,
-     nullptr},
-    {"0x1f as a single-character dictionary key", "\037=1", 3, absl::nullopt,
-     nullptr},
-    {"0x20 as a single-character dictionary key", "=1", 2, absl::nullopt,
-     nullptr},
-    {"0x21 as a single-character dictionary key", "!=1", 3, absl::nullopt,
-     nullptr},
-    {"0x22 as a single-character dictionary key", "\"=1", 3, absl::nullopt,
-     nullptr},
-    {"0x23 as a single-character dictionary key", "#=1", 3, absl::nullopt,
-     nullptr},
-    {"0x24 as a single-character dictionary key", "$=1", 3, absl::nullopt,
-     nullptr},
-    {"0x25 as a single-character dictionary key", "%=1", 3, absl::nullopt,
-     nullptr},
-    {"0x26 as a single-character dictionary key", "&=1", 3, absl::nullopt,
-     nullptr},
-    {"0x27 as a single-character dictionary key", "'=1", 3, absl::nullopt,
-     nullptr},
-    {"0x28 as a single-character dictionary key", "(=1", 3, absl::nullopt,
-     nullptr},
-    {"0x29 as a single-character dictionary key", ")=1", 3, absl::nullopt,
-     nullptr},
-    {"0x2a as a single-character dictionary key",
-     "*=1",
-     3,
-     {Dictionary{{{"*", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x2b as a single-character dictionary key", "+=1", 3, absl::nullopt,
-     nullptr},
-    {"0x2c as a single-character dictionary key", ",=1", 3, absl::nullopt,
-     nullptr},
-    {"0x2d as a single-character dictionary key", "-=1", 3, absl::nullopt,
-     nullptr},
-    {"0x2e as a single-character dictionary key", ".=1", 3, absl::nullopt,
-     nullptr},
-    {"0x2f as a single-character dictionary key", "/=1", 3, absl::nullopt,
-     nullptr},
-    {"0x30 as a single-character dictionary key", "0=1", 3, absl::nullopt,
-     nullptr},
-    {"0x31 as a single-character dictionary key", "1=1", 3, absl::nullopt,
-     nullptr},
-    {"0x32 as a single-character dictionary key", "2=1", 3, absl::nullopt,
-     nullptr},
-    {"0x33 as a single-character dictionary key", "3=1", 3, absl::nullopt,
-     nullptr},
-    {"0x34 as a single-character dictionary key", "4=1", 3, absl::nullopt,
-     nullptr},
-    {"0x35 as a single-character dictionary key", "5=1", 3, absl::nullopt,
-     nullptr},
-    {"0x36 as a single-character dictionary key", "6=1", 3, absl::nullopt,
-     nullptr},
-    {"0x37 as a single-character dictionary key", "7=1", 3, absl::nullopt,
-     nullptr},
-    {"0x38 as a single-character dictionary key", "8=1", 3, absl::nullopt,
-     nullptr},
-    {"0x39 as a single-character dictionary key", "9=1", 3, absl::nullopt,
-     nullptr},
-    {"0x3a as a single-character dictionary key", ":=1", 3, absl::nullopt,
-     nullptr},
-    {"0x3b as a single-character dictionary key", ";=1", 3, absl::nullopt,
-     nullptr},
-    {"0x3c as a single-character dictionary key", "<=1", 3, absl::nullopt,
-     nullptr},
-    {"0x3d as a single-character dictionary key", "==1", 3, absl::nullopt,
-     nullptr},
-    {"0x3e as a single-character dictionary key", ">=1", 3, absl::nullopt,
-     nullptr},
-    {"0x3f as a single-character dictionary key", "?=1", 3, absl::nullopt,
-     nullptr},
-    {"0x40 as a single-character dictionary key", "@=1", 3, absl::nullopt,
-     nullptr},
-    {"0x41 as a single-character dictionary key", "A=1", 3, absl::nullopt,
-     nullptr},
-    {"0x42 as a single-character dictionary key", "B=1", 3, absl::nullopt,
-     nullptr},
-    {"0x43 as a single-character dictionary key", "C=1", 3, absl::nullopt,
-     nullptr},
-    {"0x44 as a single-character dictionary key", "D=1", 3, absl::nullopt,
-     nullptr},
-    {"0x45 as a single-character dictionary key", "E=1", 3, absl::nullopt,
-     nullptr},
-    {"0x46 as a single-character dictionary key", "F=1", 3, absl::nullopt,
-     nullptr},
-    {"0x47 as a single-character dictionary key", "G=1", 3, absl::nullopt,
-     nullptr},
-    {"0x48 as a single-character dictionary key", "H=1", 3, absl::nullopt,
-     nullptr},
-    {"0x49 as a single-character dictionary key", "I=1", 3, absl::nullopt,
-     nullptr},
-    {"0x4a as a single-character dictionary key", "J=1", 3, absl::nullopt,
-     nullptr},
-    {"0x4b as a single-character dictionary key", "K=1", 3, absl::nullopt,
-     nullptr},
-    {"0x4c as a single-character dictionary key", "L=1", 3, absl::nullopt,
-     nullptr},
-    {"0x4d as a single-character dictionary key", "M=1", 3, absl::nullopt,
-     nullptr},
-    {"0x4e as a single-character dictionary key", "N=1", 3, absl::nullopt,
-     nullptr},
-    {"0x4f as a single-character dictionary key", "O=1", 3, absl::nullopt,
-     nullptr},
-    {"0x50 as a single-character dictionary key", "P=1", 3, absl::nullopt,
-     nullptr},
-    {"0x51 as a single-character dictionary key", "Q=1", 3, absl::nullopt,
-     nullptr},
-    {"0x52 as a single-character dictionary key", "R=1", 3, absl::nullopt,
-     nullptr},
-    {"0x53 as a single-character dictionary key", "S=1", 3, absl::nullopt,
-     nullptr},
-    {"0x54 as a single-character dictionary key", "T=1", 3, absl::nullopt,
-     nullptr},
-    {"0x55 as a single-character dictionary key", "U=1", 3, absl::nullopt,
-     nullptr},
-    {"0x56 as a single-character dictionary key", "V=1", 3, absl::nullopt,
-     nullptr},
-    {"0x57 as a single-character dictionary key", "W=1", 3, absl::nullopt,
-     nullptr},
-    {"0x58 as a single-character dictionary key", "X=1", 3, absl::nullopt,
-     nullptr},
-    {"0x59 as a single-character dictionary key", "Y=1", 3, absl::nullopt,
-     nullptr},
-    {"0x5a as a single-character dictionary key", "Z=1", 3, absl::nullopt,
-     nullptr},
-    {"0x5b as a single-character dictionary key", "[=1", 3, absl::nullopt,
-     nullptr},
-    {"0x5c as a single-character dictionary key", "\\=1", 3, absl::nullopt,
-     nullptr},
-    {"0x5d as a single-character dictionary key", "]=1", 3, absl::nullopt,
-     nullptr},
-    {"0x5e as a single-character dictionary key", "^=1", 3, absl::nullopt,
-     nullptr},
-    {"0x5f as a single-character dictionary key", "_=1", 3, absl::nullopt,
-     nullptr},
-    {"0x60 as a single-character dictionary key", "`=1", 3, absl::nullopt,
-     nullptr},
-    {"0x61 as a single-character dictionary key",
-     "a=1",
-     3,
-     {Dictionary{{{"a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x62 as a single-character dictionary key",
-     "b=1",
-     3,
-     {Dictionary{{{"b", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x63 as a single-character dictionary key",
-     "c=1",
-     3,
-     {Dictionary{{{"c", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x64 as a single-character dictionary key",
-     "d=1",
-     3,
-     {Dictionary{{{"d", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x65 as a single-character dictionary key",
-     "e=1",
-     3,
-     {Dictionary{{{"e", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x66 as a single-character dictionary key",
-     "f=1",
-     3,
-     {Dictionary{{{"f", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x67 as a single-character dictionary key",
-     "g=1",
-     3,
-     {Dictionary{{{"g", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x68 as a single-character dictionary key",
-     "h=1",
-     3,
-     {Dictionary{{{"h", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x69 as a single-character dictionary key",
-     "i=1",
-     3,
-     {Dictionary{{{"i", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6a as a single-character dictionary key",
-     "j=1",
-     3,
-     {Dictionary{{{"j", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6b as a single-character dictionary key",
-     "k=1",
-     3,
-     {Dictionary{{{"k", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6c as a single-character dictionary key",
-     "l=1",
-     3,
-     {Dictionary{{{"l", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6d as a single-character dictionary key",
-     "m=1",
-     3,
-     {Dictionary{{{"m", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6e as a single-character dictionary key",
-     "n=1",
-     3,
-     {Dictionary{{{"n", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6f as a single-character dictionary key",
-     "o=1",
-     3,
-     {Dictionary{{{"o", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x70 as a single-character dictionary key",
-     "p=1",
-     3,
-     {Dictionary{{{"p", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x71 as a single-character dictionary key",
-     "q=1",
-     3,
-     {Dictionary{{{"q", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x72 as a single-character dictionary key",
-     "r=1",
-     3,
-     {Dictionary{{{"r", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x73 as a single-character dictionary key",
-     "s=1",
-     3,
-     {Dictionary{{{"s", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x74 as a single-character dictionary key",
-     "t=1",
-     3,
-     {Dictionary{{{"t", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x75 as a single-character dictionary key",
-     "u=1",
-     3,
-     {Dictionary{{{"u", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x76 as a single-character dictionary key",
-     "v=1",
-     3,
-     {Dictionary{{{"v", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x77 as a single-character dictionary key",
-     "w=1",
-     3,
-     {Dictionary{{{"w", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x78 as a single-character dictionary key",
-     "x=1",
-     3,
-     {Dictionary{{{"x", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x79 as a single-character dictionary key",
-     "y=1",
-     3,
-     {Dictionary{{{"y", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x7a as a single-character dictionary key",
-     "z=1",
-     3,
-     {Dictionary{{{"z", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x7b as a single-character dictionary key", "{=1", 3, absl::nullopt,
-     nullptr},
-    {"0x7c as a single-character dictionary key", "|=1", 3, absl::nullopt,
-     nullptr},
-    {"0x7d as a single-character dictionary key", "}=1", 3, absl::nullopt,
-     nullptr},
-    {"0x7e as a single-character dictionary key", "~=1", 3, absl::nullopt,
-     nullptr},
-    {"0x7f as a single-character dictionary key", "\177=1", 3, absl::nullopt,
-     nullptr},
-    {"0x00 in dictionary key", "a\000a=1", 5, absl::nullopt, nullptr},
-    {"0x01 in dictionary key", "a\001a=1", 5, absl::nullopt, nullptr},
-    {"0x02 in dictionary key", "a\002a=1", 5, absl::nullopt, nullptr},
-    {"0x03 in dictionary key", "a\003a=1", 5, absl::nullopt, nullptr},
-    {"0x04 in dictionary key", "a\004a=1", 5, absl::nullopt, nullptr},
-    {"0x05 in dictionary key", "a\005a=1", 5, absl::nullopt, nullptr},
-    {"0x06 in dictionary key", "a\006a=1", 5, absl::nullopt, nullptr},
-    {"0x07 in dictionary key", "a\aa=1", 5, absl::nullopt, nullptr},
-    {"0x08 in dictionary key", "a\ba=1", 5, absl::nullopt, nullptr},
-    {"0x09 in dictionary key", "a\ta=1", 5, absl::nullopt, nullptr},
-    {"0x0a in dictionary key", "a\na=1", 5, absl::nullopt, nullptr},
-    {"0x0b in dictionary key", "a\va=1", 5, absl::nullopt, nullptr},
-    {"0x0c in dictionary key", "a\fa=1", 5, absl::nullopt, nullptr},
-    {"0x0d in dictionary key", "a\ra=1", 5, absl::nullopt, nullptr},
-    {"0x0e in dictionary key", "a\016a=1", 5, absl::nullopt, nullptr},
-    {"0x0f in dictionary key", "a\017a=1", 5, absl::nullopt, nullptr},
-    {"0x10 in dictionary key", "a\020a=1", 5, absl::nullopt, nullptr},
-    {"0x11 in dictionary key", "a\021a=1", 5, absl::nullopt, nullptr},
-    {"0x12 in dictionary key", "a\022a=1", 5, absl::nullopt, nullptr},
-    {"0x13 in dictionary key", "a\023a=1", 5, absl::nullopt, nullptr},
-    {"0x14 in dictionary key", "a\024a=1", 5, absl::nullopt, nullptr},
-    {"0x15 in dictionary key", "a\025a=1", 5, absl::nullopt, nullptr},
-    {"0x16 in dictionary key", "a\026a=1", 5, absl::nullopt, nullptr},
-    {"0x17 in dictionary key", "a\027a=1", 5, absl::nullopt, nullptr},
-    {"0x18 in dictionary key", "a\030a=1", 5, absl::nullopt, nullptr},
-    {"0x19 in dictionary key", "a\031a=1", 5, absl::nullopt, nullptr},
-    {"0x1a in dictionary key", "a\032a=1", 5, absl::nullopt, nullptr},
-    {"0x1b in dictionary key", "a\033a=1", 5, absl::nullopt, nullptr},
-    {"0x1c in dictionary key", "a\034a=1", 5, absl::nullopt, nullptr},
-    {"0x1d in dictionary key", "a\035a=1", 5, absl::nullopt, nullptr},
-    {"0x1e in dictionary key", "a\036a=1", 5, absl::nullopt, nullptr},
-    {"0x1f in dictionary key", "a\037a=1", 5, absl::nullopt, nullptr},
-    {"0x20 in dictionary key", "a a=1", 5, absl::nullopt, nullptr},
-    {"0x21 in dictionary key", "a!a=1", 5, absl::nullopt, nullptr},
-    {"0x22 in dictionary key", "a\"a=1", 5, absl::nullopt, nullptr},
-    {"0x23 in dictionary key", "a#a=1", 5, absl::nullopt, nullptr},
-    {"0x24 in dictionary key", "a$a=1", 5, absl::nullopt, nullptr},
-    {"0x25 in dictionary key", "a%a=1", 5, absl::nullopt, nullptr},
-    {"0x26 in dictionary key", "a&a=1", 5, absl::nullopt, nullptr},
-    {"0x27 in dictionary key", "a'a=1", 5, absl::nullopt, nullptr},
-    {"0x28 in dictionary key", "a(a=1", 5, absl::nullopt, nullptr},
-    {"0x29 in dictionary key", "a)a=1", 5, absl::nullopt, nullptr},
-    {"0x2a in dictionary key",
-     "a*a=1",
-     5,
-     {Dictionary{{{"a*a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x2b in dictionary key", "a+a=1", 5, absl::nullopt, nullptr},
-    {"0x2c in dictionary key",
-     "a,a=1",
-     5,
-     {Dictionary{{{"a", {Integer(1), {}}}}}},
-     "a=1"},
-    {"0x2d in dictionary key",
-     "a-a=1",
-     5,
-     {Dictionary{{{"a-a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x2e in dictionary key",
-     "a.a=1",
-     5,
-     {Dictionary{{{"a.a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x2f in dictionary key", "a/a=1", 5, absl::nullopt, nullptr},
-    {"0x30 in dictionary key",
-     "a0a=1",
-     5,
-     {Dictionary{{{"a0a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x31 in dictionary key",
-     "a1a=1",
-     5,
-     {Dictionary{{{"a1a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x32 in dictionary key",
-     "a2a=1",
-     5,
-     {Dictionary{{{"a2a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x33 in dictionary key",
-     "a3a=1",
-     5,
-     {Dictionary{{{"a3a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x34 in dictionary key",
-     "a4a=1",
-     5,
-     {Dictionary{{{"a4a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x35 in dictionary key",
-     "a5a=1",
-     5,
-     {Dictionary{{{"a5a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x36 in dictionary key",
-     "a6a=1",
-     5,
-     {Dictionary{{{"a6a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x37 in dictionary key",
-     "a7a=1",
-     5,
-     {Dictionary{{{"a7a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x38 in dictionary key",
-     "a8a=1",
-     5,
-     {Dictionary{{{"a8a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x39 in dictionary key",
-     "a9a=1",
-     5,
-     {Dictionary{{{"a9a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x3a in dictionary key", "a:a=1", 5, absl::nullopt, nullptr},
-    {"0x3b in dictionary key",
-     "a;a=1",
-     5,
-     {Dictionary{{{"a", {Item(true), {Param("a", 1)}}}}}},
-     nullptr},
-    {"0x3c in dictionary key", "a<a=1", 5, absl::nullopt, nullptr},
-    {"0x3d in dictionary key", "a=a=1", 5, absl::nullopt, nullptr},
-    {"0x3e in dictionary key", "a>a=1", 5, absl::nullopt, nullptr},
-    {"0x3f in dictionary key", "a?a=1", 5, absl::nullopt, nullptr},
-    {"0x40 in dictionary key", "a@a=1", 5, absl::nullopt, nullptr},
-    {"0x41 in dictionary key", "aAa=1", 5, absl::nullopt, nullptr},
-    {"0x42 in dictionary key", "aBa=1", 5, absl::nullopt, nullptr},
-    {"0x43 in dictionary key", "aCa=1", 5, absl::nullopt, nullptr},
-    {"0x44 in dictionary key", "aDa=1", 5, absl::nullopt, nullptr},
-    {"0x45 in dictionary key", "aEa=1", 5, absl::nullopt, nullptr},
-    {"0x46 in dictionary key", "aFa=1", 5, absl::nullopt, nullptr},
-    {"0x47 in dictionary key", "aGa=1", 5, absl::nullopt, nullptr},
-    {"0x48 in dictionary key", "aHa=1", 5, absl::nullopt, nullptr},
-    {"0x49 in dictionary key", "aIa=1", 5, absl::nullopt, nullptr},
-    {"0x4a in dictionary key", "aJa=1", 5, absl::nullopt, nullptr},
-    {"0x4b in dictionary key", "aKa=1", 5, absl::nullopt, nullptr},
-    {"0x4c in dictionary key", "aLa=1", 5, absl::nullopt, nullptr},
-    {"0x4d in dictionary key", "aMa=1", 5, absl::nullopt, nullptr},
-    {"0x4e in dictionary key", "aNa=1", 5, absl::nullopt, nullptr},
-    {"0x4f in dictionary key", "aOa=1", 5, absl::nullopt, nullptr},
-    {"0x50 in dictionary key", "aPa=1", 5, absl::nullopt, nullptr},
-    {"0x51 in dictionary key", "aQa=1", 5, absl::nullopt, nullptr},
-    {"0x52 in dictionary key", "aRa=1", 5, absl::nullopt, nullptr},
-    {"0x53 in dictionary key", "aSa=1", 5, absl::nullopt, nullptr},
-    {"0x54 in dictionary key", "aTa=1", 5, absl::nullopt, nullptr},
-    {"0x55 in dictionary key", "aUa=1", 5, absl::nullopt, nullptr},
-    {"0x56 in dictionary key", "aVa=1", 5, absl::nullopt, nullptr},
-    {"0x57 in dictionary key", "aWa=1", 5, absl::nullopt, nullptr},
-    {"0x58 in dictionary key", "aXa=1", 5, absl::nullopt, nullptr},
-    {"0x59 in dictionary key", "aYa=1", 5, absl::nullopt, nullptr},
-    {"0x5a in dictionary key", "aZa=1", 5, absl::nullopt, nullptr},
-    {"0x5b in dictionary key", "a[a=1", 5, absl::nullopt, nullptr},
-    {"0x5c in dictionary key", "a\\a=1", 5, absl::nullopt, nullptr},
-    {"0x5d in dictionary key", "a]a=1", 5, absl::nullopt, nullptr},
-    {"0x5e in dictionary key", "a^a=1", 5, absl::nullopt, nullptr},
-    {"0x5f in dictionary key",
-     "a_a=1",
-     5,
-     {Dictionary{{{"a_a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x60 in dictionary key", "a`a=1", 5, absl::nullopt, nullptr},
-    {"0x61 in dictionary key",
-     "aaa=1",
-     5,
-     {Dictionary{{{"aaa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x62 in dictionary key",
-     "aba=1",
-     5,
-     {Dictionary{{{"aba", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x63 in dictionary key",
-     "aca=1",
-     5,
-     {Dictionary{{{"aca", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x64 in dictionary key",
-     "ada=1",
-     5,
-     {Dictionary{{{"ada", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x65 in dictionary key",
-     "aea=1",
-     5,
-     {Dictionary{{{"aea", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x66 in dictionary key",
-     "afa=1",
-     5,
-     {Dictionary{{{"afa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x67 in dictionary key",
-     "aga=1",
-     5,
-     {Dictionary{{{"aga", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x68 in dictionary key",
-     "aha=1",
-     5,
-     {Dictionary{{{"aha", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x69 in dictionary key",
-     "aia=1",
-     5,
-     {Dictionary{{{"aia", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6a in dictionary key",
-     "aja=1",
-     5,
-     {Dictionary{{{"aja", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6b in dictionary key",
-     "aka=1",
-     5,
-     {Dictionary{{{"aka", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6c in dictionary key",
-     "ala=1",
-     5,
-     {Dictionary{{{"ala", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6d in dictionary key",
-     "ama=1",
-     5,
-     {Dictionary{{{"ama", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6e in dictionary key",
-     "ana=1",
-     5,
-     {Dictionary{{{"ana", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6f in dictionary key",
-     "aoa=1",
-     5,
-     {Dictionary{{{"aoa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x70 in dictionary key",
-     "apa=1",
-     5,
-     {Dictionary{{{"apa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x71 in dictionary key",
-     "aqa=1",
-     5,
-     {Dictionary{{{"aqa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x72 in dictionary key",
-     "ara=1",
-     5,
-     {Dictionary{{{"ara", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x73 in dictionary key",
-     "asa=1",
-     5,
-     {Dictionary{{{"asa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x74 in dictionary key",
-     "ata=1",
-     5,
-     {Dictionary{{{"ata", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x75 in dictionary key",
-     "aua=1",
-     5,
-     {Dictionary{{{"aua", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x76 in dictionary key",
-     "ava=1",
-     5,
-     {Dictionary{{{"ava", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x77 in dictionary key",
-     "awa=1",
-     5,
-     {Dictionary{{{"awa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x78 in dictionary key",
-     "axa=1",
-     5,
-     {Dictionary{{{"axa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x79 in dictionary key",
-     "aya=1",
-     5,
-     {Dictionary{{{"aya", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x7a in dictionary key",
-     "aza=1",
-     5,
-     {Dictionary{{{"aza", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x7b in dictionary key", "a{a=1", 5, absl::nullopt, nullptr},
-    {"0x7c in dictionary key", "a|a=1", 5, absl::nullopt, nullptr},
-    {"0x7d in dictionary key", "a}a=1", 5, absl::nullopt, nullptr},
-    {"0x7e in dictionary key", "a~a=1", 5, absl::nullopt, nullptr},
-    {"0x7f in dictionary key", "a\177a=1", 5, absl::nullopt, nullptr},
-    {"0x00 starting an dictionary key", "\000a=1", 4, absl::nullopt, nullptr},
-    {"0x01 starting an dictionary key", "\001a=1", 4, absl::nullopt, nullptr},
-    {"0x02 starting an dictionary key", "\002a=1", 4, absl::nullopt, nullptr},
-    {"0x03 starting an dictionary key", "\003a=1", 4, absl::nullopt, nullptr},
-    {"0x04 starting an dictionary key", "\004a=1", 4, absl::nullopt, nullptr},
-    {"0x05 starting an dictionary key", "\005a=1", 4, absl::nullopt, nullptr},
-    {"0x06 starting an dictionary key", "\006a=1", 4, absl::nullopt, nullptr},
-    {"0x07 starting an dictionary key", "\aa=1", 4, absl::nullopt, nullptr},
-    {"0x08 starting an dictionary key", "\ba=1", 4, absl::nullopt, nullptr},
-    {"0x09 starting an dictionary key", "\ta=1", 4, absl::nullopt, nullptr},
-    {"0x0a starting an dictionary key", "\na=1", 4, absl::nullopt, nullptr},
-    {"0x0b starting an dictionary key", "\va=1", 4, absl::nullopt, nullptr},
-    {"0x0c starting an dictionary key", "\fa=1", 4, absl::nullopt, nullptr},
-    {"0x0d starting an dictionary key", "\ra=1", 4, absl::nullopt, nullptr},
-    {"0x0e starting an dictionary key", "\016a=1", 4, absl::nullopt, nullptr},
-    {"0x0f starting an dictionary key", "\017a=1", 4, absl::nullopt, nullptr},
-    {"0x10 starting an dictionary key", "\020a=1", 4, absl::nullopt, nullptr},
-    {"0x11 starting an dictionary key", "\021a=1", 4, absl::nullopt, nullptr},
-    {"0x12 starting an dictionary key", "\022a=1", 4, absl::nullopt, nullptr},
-    {"0x13 starting an dictionary key", "\023a=1", 4, absl::nullopt, nullptr},
-    {"0x14 starting an dictionary key", "\024a=1", 4, absl::nullopt, nullptr},
-    {"0x15 starting an dictionary key", "\025a=1", 4, absl::nullopt, nullptr},
-    {"0x16 starting an dictionary key", "\026a=1", 4, absl::nullopt, nullptr},
-    {"0x17 starting an dictionary key", "\027a=1", 4, absl::nullopt, nullptr},
-    {"0x18 starting an dictionary key", "\030a=1", 4, absl::nullopt, nullptr},
-    {"0x19 starting an dictionary key", "\031a=1", 4, absl::nullopt, nullptr},
-    {"0x1a starting an dictionary key", "\032a=1", 4, absl::nullopt, nullptr},
-    {"0x1b starting an dictionary key", "\033a=1", 4, absl::nullopt, nullptr},
-    {"0x1c starting an dictionary key", "\034a=1", 4, absl::nullopt, nullptr},
-    {"0x1d starting an dictionary key", "\035a=1", 4, absl::nullopt, nullptr},
-    {"0x1e starting an dictionary key", "\036a=1", 4, absl::nullopt, nullptr},
-    {"0x1f starting an dictionary key", "\037a=1", 4, absl::nullopt, nullptr},
-    {"0x20 starting an dictionary key",
-     " a=1",
-     4,
-     {Dictionary{{{"a", {Integer(1), {}}}}}},
-     "a=1"},
-    {"0x21 starting an dictionary key", "!a=1", 4, absl::nullopt, nullptr},
-    {"0x22 starting an dictionary key", "\"a=1", 4, absl::nullopt, nullptr},
-    {"0x23 starting an dictionary key", "#a=1", 4, absl::nullopt, nullptr},
-    {"0x24 starting an dictionary key", "$a=1", 4, absl::nullopt, nullptr},
-    {"0x25 starting an dictionary key", "%a=1", 4, absl::nullopt, nullptr},
-    {"0x26 starting an dictionary key", "&a=1", 4, absl::nullopt, nullptr},
-    {"0x27 starting an dictionary key", "'a=1", 4, absl::nullopt, nullptr},
-    {"0x28 starting an dictionary key", "(a=1", 4, absl::nullopt, nullptr},
-    {"0x29 starting an dictionary key", ")a=1", 4, absl::nullopt, nullptr},
-    {"0x2a starting an dictionary key",
-     "*a=1",
-     4,
-     {Dictionary{{{"*a", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x2b starting an dictionary key", "+a=1", 4, absl::nullopt, nullptr},
-    {"0x2c starting an dictionary key", ",a=1", 4, absl::nullopt, nullptr},
-    {"0x2d starting an dictionary key", "-a=1", 4, absl::nullopt, nullptr},
-    {"0x2e starting an dictionary key", ".a=1", 4, absl::nullopt, nullptr},
-    {"0x2f starting an dictionary key", "/a=1", 4, absl::nullopt, nullptr},
-    {"0x30 starting an dictionary key", "0a=1", 4, absl::nullopt, nullptr},
-    {"0x31 starting an dictionary key", "1a=1", 4, absl::nullopt, nullptr},
-    {"0x32 starting an dictionary key", "2a=1", 4, absl::nullopt, nullptr},
-    {"0x33 starting an dictionary key", "3a=1", 4, absl::nullopt, nullptr},
-    {"0x34 starting an dictionary key", "4a=1", 4, absl::nullopt, nullptr},
-    {"0x35 starting an dictionary key", "5a=1", 4, absl::nullopt, nullptr},
-    {"0x36 starting an dictionary key", "6a=1", 4, absl::nullopt, nullptr},
-    {"0x37 starting an dictionary key", "7a=1", 4, absl::nullopt, nullptr},
-    {"0x38 starting an dictionary key", "8a=1", 4, absl::nullopt, nullptr},
-    {"0x39 starting an dictionary key", "9a=1", 4, absl::nullopt, nullptr},
-    {"0x3a starting an dictionary key", ":a=1", 4, absl::nullopt, nullptr},
-    {"0x3b starting an dictionary key", ";a=1", 4, absl::nullopt, nullptr},
-    {"0x3c starting an dictionary key", "<a=1", 4, absl::nullopt, nullptr},
-    {"0x3d starting an dictionary key", "=a=1", 4, absl::nullopt, nullptr},
-    {"0x3e starting an dictionary key", ">a=1", 4, absl::nullopt, nullptr},
-    {"0x3f starting an dictionary key", "?a=1", 4, absl::nullopt, nullptr},
-    {"0x40 starting an dictionary key", "@a=1", 4, absl::nullopt, nullptr},
-    {"0x41 starting an dictionary key", "Aa=1", 4, absl::nullopt, nullptr},
-    {"0x42 starting an dictionary key", "Ba=1", 4, absl::nullopt, nullptr},
-    {"0x43 starting an dictionary key", "Ca=1", 4, absl::nullopt, nullptr},
-    {"0x44 starting an dictionary key", "Da=1", 4, absl::nullopt, nullptr},
-    {"0x45 starting an dictionary key", "Ea=1", 4, absl::nullopt, nullptr},
-    {"0x46 starting an dictionary key", "Fa=1", 4, absl::nullopt, nullptr},
-    {"0x47 starting an dictionary key", "Ga=1", 4, absl::nullopt, nullptr},
-    {"0x48 starting an dictionary key", "Ha=1", 4, absl::nullopt, nullptr},
-    {"0x49 starting an dictionary key", "Ia=1", 4, absl::nullopt, nullptr},
-    {"0x4a starting an dictionary key", "Ja=1", 4, absl::nullopt, nullptr},
-    {"0x4b starting an dictionary key", "Ka=1", 4, absl::nullopt, nullptr},
-    {"0x4c starting an dictionary key", "La=1", 4, absl::nullopt, nullptr},
-    {"0x4d starting an dictionary key", "Ma=1", 4, absl::nullopt, nullptr},
-    {"0x4e starting an dictionary key", "Na=1", 4, absl::nullopt, nullptr},
-    {"0x4f starting an dictionary key", "Oa=1", 4, absl::nullopt, nullptr},
-    {"0x50 starting an dictionary key", "Pa=1", 4, absl::nullopt, nullptr},
-    {"0x51 starting an dictionary key", "Qa=1", 4, absl::nullopt, nullptr},
-    {"0x52 starting an dictionary key", "Ra=1", 4, absl::nullopt, nullptr},
-    {"0x53 starting an dictionary key", "Sa=1", 4, absl::nullopt, nullptr},
-    {"0x54 starting an dictionary key", "Ta=1", 4, absl::nullopt, nullptr},
-    {"0x55 starting an dictionary key", "Ua=1", 4, absl::nullopt, nullptr},
-    {"0x56 starting an dictionary key", "Va=1", 4, absl::nullopt, nullptr},
-    {"0x57 starting an dictionary key", "Wa=1", 4, absl::nullopt, nullptr},
-    {"0x58 starting an dictionary key", "Xa=1", 4, absl::nullopt, nullptr},
-    {"0x59 starting an dictionary key", "Ya=1", 4, absl::nullopt, nullptr},
-    {"0x5a starting an dictionary key", "Za=1", 4, absl::nullopt, nullptr},
-    {"0x5b starting an dictionary key", "[a=1", 4, absl::nullopt, nullptr},
-    {"0x5c starting an dictionary key", "\\a=1", 4, absl::nullopt, nullptr},
-    {"0x5d starting an dictionary key", "]a=1", 4, absl::nullopt, nullptr},
-    {"0x5e starting an dictionary key", "^a=1", 4, absl::nullopt, nullptr},
-    {"0x5f starting an dictionary key", "_a=1", 4, absl::nullopt, nullptr},
-    {"0x60 starting an dictionary key", "`a=1", 4, absl::nullopt, nullptr},
-    {"0x61 starting an dictionary key",
-     "aa=1",
-     4,
-     {Dictionary{{{"aa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x62 starting an dictionary key",
-     "ba=1",
-     4,
-     {Dictionary{{{"ba", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x63 starting an dictionary key",
-     "ca=1",
-     4,
-     {Dictionary{{{"ca", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x64 starting an dictionary key",
-     "da=1",
-     4,
-     {Dictionary{{{"da", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x65 starting an dictionary key",
-     "ea=1",
-     4,
-     {Dictionary{{{"ea", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x66 starting an dictionary key",
-     "fa=1",
-     4,
-     {Dictionary{{{"fa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x67 starting an dictionary key",
-     "ga=1",
-     4,
-     {Dictionary{{{"ga", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x68 starting an dictionary key",
-     "ha=1",
-     4,
-     {Dictionary{{{"ha", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x69 starting an dictionary key",
-     "ia=1",
-     4,
-     {Dictionary{{{"ia", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6a starting an dictionary key",
-     "ja=1",
-     4,
-     {Dictionary{{{"ja", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6b starting an dictionary key",
-     "ka=1",
-     4,
-     {Dictionary{{{"ka", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6c starting an dictionary key",
-     "la=1",
-     4,
-     {Dictionary{{{"la", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6d starting an dictionary key",
-     "ma=1",
-     4,
-     {Dictionary{{{"ma", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6e starting an dictionary key",
-     "na=1",
-     4,
-     {Dictionary{{{"na", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x6f starting an dictionary key",
-     "oa=1",
-     4,
-     {Dictionary{{{"oa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x70 starting an dictionary key",
-     "pa=1",
-     4,
-     {Dictionary{{{"pa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x71 starting an dictionary key",
-     "qa=1",
-     4,
-     {Dictionary{{{"qa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x72 starting an dictionary key",
-     "ra=1",
-     4,
-     {Dictionary{{{"ra", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x73 starting an dictionary key",
-     "sa=1",
-     4,
-     {Dictionary{{{"sa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x74 starting an dictionary key",
-     "ta=1",
-     4,
-     {Dictionary{{{"ta", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x75 starting an dictionary key",
-     "ua=1",
-     4,
-     {Dictionary{{{"ua", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x76 starting an dictionary key",
-     "va=1",
-     4,
-     {Dictionary{{{"va", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x77 starting an dictionary key",
-     "wa=1",
-     4,
-     {Dictionary{{{"wa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x78 starting an dictionary key",
-     "xa=1",
-     4,
-     {Dictionary{{{"xa", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x79 starting an dictionary key",
-     "ya=1",
-     4,
-     {Dictionary{{{"ya", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x7a starting an dictionary key",
-     "za=1",
-     4,
-     {Dictionary{{{"za", {Integer(1), {}}}}}},
-     nullptr},
-    {"0x7b starting an dictionary key", "{a=1", 4, absl::nullopt, nullptr},
-    {"0x7c starting an dictionary key", "|a=1", 4, absl::nullopt, nullptr},
-    {"0x7d starting an dictionary key", "}a=1", 4, absl::nullopt, nullptr},
-    {"0x7e starting an dictionary key", "~a=1", 4, absl::nullopt, nullptr},
-    {"0x7f starting an dictionary key", "\177a=1", 4, absl::nullopt, nullptr},
-    // param-dict.json
-    {"basic parameterised dict",
-     "abc=123;a=1;b=2, def=456, ghi=789;q=9;r=\"+w\"",
-     44,
-     {Dictionary{{{"abc", {Integer(123), {Param("a", 1), Param("b", 2)}}},
-                  {"def", {Integer(456), {}}},
-                  {"ghi", {Integer(789), {Param("q", 9), Param("r", "+w")}}}}}},
-     nullptr},
-    {"single item parameterised dict",
-     "a=b; q=1.0",
-     10,
-     {Dictionary{
-         {{"a", {Item("b", Item::kTokenType), {DoubleParam("q", 1.000000)}}}}}},
-     "a=b;q=1.0"},
-    {"list item parameterised dictionary",
-     "a=(1 2); q=1.0",
-     14,
-     {Dictionary{{{"a",
-                   {{{Integer(1), {}}, {Integer(2), {}}},
-                    {DoubleParam("q", 1.000000)}}}}}},
-     "a=(1 2);q=1.0"},
-    {"missing parameter value parameterised dict",
-     "a=3;c;d=5",
-     9,
-     {Dictionary{
-         {{"a", {Integer(3), {BooleanParam("c", true), Param("d", 5)}}}}}},
-     nullptr},
-    {"terminal missing parameter value parameterised dict",
-     "a=3;c=5;d",
-     9,
-     {Dictionary{
-         {{"a", {Integer(3), {Param("c", 5), BooleanParam("d", true)}}}}}},
-     nullptr},
-    {"no whitespace parameterised dict",
-     "a=b;c=1,d=e;f=2",
-     15,
-     {Dictionary{{{"a", {Item("b", Item::kTokenType), {Param("c", 1)}}},
-                  {"d", {Item("e", Item::kTokenType), {Param("f", 2)}}}}}},
-     "a=b;c=1, d=e;f=2"},
-    {"whitespace before = parameterised dict", "a=b;q =0.5", 10, absl::nullopt,
-     nullptr},
-    {"whitespace after = parameterised dict", "a=b;q= 0.5", 10, absl::nullopt,
-     nullptr},
-    {"whitespace before ; parameterised dict", "a=b ;q=0.5", 10, absl::nullopt,
-     nullptr},
-    {"whitespace after ; parameterised dict",
-     "a=b; q=0.5",
-     10,
-     {Dictionary{
-         {{"a", {Item("b", Item::kTokenType), {DoubleParam("q", 0.500000)}}}}}},
-     "a=b;q=0.5"},
-    {"extra whitespace parameterised dict",
-     "a=b;  c=1  ,  d=e; f=2; g=3",
-     27,
-     {Dictionary{
-         {{"a", {Item("b", Item::kTokenType), {Param("c", 1)}}},
-          {"d",
-           {Item("e", Item::kTokenType), {Param("f", 2), Param("g", 3)}}}}}},
-     "a=b;c=1, d=e;f=2;g=3"},
-    {"two lines parameterised list",
-     "a=b;c=1, d=e;f=2",
-     16,
-     {Dictionary{{{"a", {Item("b", Item::kTokenType), {Param("c", 1)}}},
-                  {"d", {Item("e", Item::kTokenType), {Param("f", 2)}}}}}},
-     "a=b;c=1, d=e;f=2"},
-    {"trailing comma parameterised list", "a=b; q=1.0,", 11, absl::nullopt,
-     nullptr},
-    {"empty item parameterised list", "a=b; q=1.0,,c=d", 15, absl::nullopt,
-     nullptr},
-};
-
-}  // namespace
-
-TEST(StructuredHeaderGeneratedTest, ParseItem) {
-  for (const auto& c : parameterized_item_test_cases) {
-    if (c.raw) {
-      SCOPED_TRACE(c.name);
-      std::string raw{c.raw, c.raw_len};
-      absl::optional<ParameterizedItem> result = ParseItem(raw);
-      EXPECT_EQ(result, c.expected);
-    }
-  }
-}
-
-TEST(StructuredHeaderGeneratedTest, ParseList) {
-  for (const auto& c : list_test_cases) {
-    if (c.raw) {
-      SCOPED_TRACE(c.name);
-      std::string raw{c.raw, c.raw_len};
-      absl::optional<List> result = ParseList(raw);
-      EXPECT_EQ(result, c.expected);
-    }
-  }
-}
-
-TEST(StructuredHeaderGeneratedTest, ParseDictionary) {
-  for (const auto& c : dictionary_test_cases) {
-    if (c.raw) {
-      SCOPED_TRACE(c.name);
-      std::string raw{c.raw, c.raw_len};
-      absl::optional<Dictionary> result = ParseDictionary(raw);
-      EXPECT_EQ(result, c.expected);
-    }
-  }
-}
-
-TEST(StructuredHeaderGeneratedTest, SerializeItem) {
-  for (const auto& c : parameterized_item_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeItem(*c.expected);
-      if (c.raw || c.canonical) {
-        EXPECT_TRUE(result.has_value());
-        EXPECT_EQ(result.value(),
-                  std::string(c.canonical ? c.canonical : c.raw));
-      } else {
-        EXPECT_FALSE(result.has_value());
-      }
-    }
-  }
-}
-
-TEST(StructuredHeaderGeneratedTest, SerializeList) {
-  for (const auto& c : list_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeList(*c.expected);
-      if (c.raw || c.canonical) {
-        EXPECT_TRUE(result.has_value());
-        EXPECT_EQ(result.value(),
-                  std::string(c.canonical ? c.canonical : c.raw));
-      } else {
-        EXPECT_FALSE(result.has_value());
-      }
-    }
-  }
-}
-
-TEST(StructuredHeaderGeneratedTest, SerializeDictionary) {
-  for (const auto& c : dictionary_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeDictionary(*c.expected);
-      if (c.raw || c.canonical) {
-        EXPECT_TRUE(result.has_value());
-        EXPECT_EQ(result.value(),
-                  std::string(c.canonical ? c.canonical : c.raw));
-      } else {
-        EXPECT_FALSE(result.has_value());
-      }
-    }
-  }
-}
-
-}  // namespace structured_headers
-}  // namespace quiche
diff --git a/common/structured_headers_test.cc b/common/structured_headers_test.cc
deleted file mode 100644
index 87dacd8..0000000
--- a/common/structured_headers_test.cc
+++ /dev/null
@@ -1,762 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/structured_headers.h"
-
-#include <math.h>
-
-#include <limits>
-#include <string>
-
-#include "common/platform/api/quiche_test.h"
-
-namespace quiche {
-namespace structured_headers {
-namespace {
-
-// Helpers to make test cases clearer
-
-Item Token(std::string value) { return Item(value, Item::kTokenType); }
-
-Item Integer(int64_t value) { return Item(value); }
-
-// Parameter with null value, only used in Structured Headers Draft 09
-std::pair<std::string, Item> NullParam(std::string key) {
-  return std::make_pair(key, Item());
-}
-
-std::pair<std::string, Item> BooleanParam(std::string key, bool value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> DoubleParam(std::string key, double value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> Param(std::string key, int64_t value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> Param(std::string key, std::string value) {
-  return std::make_pair(key, Item(value));
-}
-
-std::pair<std::string, Item> ByteSequenceParam(std::string key,
-                                               std::string value) {
-  return std::make_pair(key, Item(value, Item::kByteSequenceType));
-}
-
-std::pair<std::string, Item> TokenParam(std::string key, std::string value) {
-  return std::make_pair(key, Token(value));
-}
-
-// Test cases taken from https://github.com/httpwg/structured-header-tests can
-// be found in structured_headers_generated_unittest.cc
-
-const struct ItemTestCase {
-  const char* name;
-  const char* raw;
-  const absl::optional<Item> expected;  // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} item_test_cases[] = {
-    // Token
-    {"bad token - item", "abc$@%!", absl::nullopt, nullptr},
-    {"leading whitespace", " foo", Token("foo"), "foo"},
-    {"trailing whitespace", "foo ", Token("foo"), "foo"},
-    {"leading asterisk", "*foo", Token("*foo"), nullptr},
-    // Number
-    {"long integer", "999999999999999", Integer(999999999999999L), nullptr},
-    {"long negative integer", "-999999999999999", Integer(-999999999999999L),
-     nullptr},
-    {"too long integer", "1000000000000000", absl::nullopt, nullptr},
-    {"negative too long integer", "-1000000000000000", absl::nullopt, nullptr},
-    {"integral decimal", "1.0", Item(1.0), nullptr},
-    // String
-    {"basic string", "\"foo\"", Item("foo"), nullptr},
-    {"non-ascii string", "\"f\xC3\xBC\xC3\xBC\"", absl::nullopt, nullptr},
-    // Additional tests
-    {"valid quoting containing \\n", "\"\\\\n\"", Item("\\n"), nullptr},
-    {"valid quoting containing \\t", "\"\\\\t\"", Item("\\t"), nullptr},
-    {"valid quoting containing \\x", "\"\\\\x61\"", Item("\\x61"), nullptr},
-    {"c-style hex escape in string", "\"\\x61\"", absl::nullopt, nullptr},
-    {"valid quoting containing \\u", "\"\\\\u0061\"", Item("\\u0061"), nullptr},
-    {"c-style unicode escape in string", "\"\\u0061\"", absl::nullopt, nullptr},
-};
-
-const ItemTestCase sh09_item_test_cases[] = {
-    // Integer
-    {"large integer", "9223372036854775807", Integer(9223372036854775807L),
-     nullptr},
-    {"large negative integer", "-9223372036854775807",
-     Integer(-9223372036854775807L), nullptr},
-    {"too large integer", "9223372036854775808", absl::nullopt, nullptr},
-    {"too large negative integer", "-9223372036854775808", absl::nullopt,
-     nullptr},
-    // Byte Sequence
-    {"basic binary", "*aGVsbG8=*", Item("hello", Item::kByteSequenceType),
-     nullptr},
-    {"empty binary", "**", Item("", Item::kByteSequenceType), nullptr},
-    {"bad paddding", "*aGVsbG8*", Item("hello", Item::kByteSequenceType),
-     "*aGVsbG8=*"},
-    {"bad end delimiter", "*aGVsbG8=", absl::nullopt, nullptr},
-    {"extra whitespace", "*aGVsb G8=*", absl::nullopt, nullptr},
-    {"extra chars", "*aGVsbG!8=*", absl::nullopt, nullptr},
-    {"suffix chars", "*aGVsbG8=!*", absl::nullopt, nullptr},
-    {"non-zero pad bits", "*iZ==*", Item("\x89", Item::kByteSequenceType),
-     "*iQ==*"},
-    {"non-ASCII binary", "*/+Ah*", Item("\xFF\xE0!", Item::kByteSequenceType),
-     nullptr},
-    {"base64url binary", "*_-Ah*", absl::nullopt, nullptr},
-    {"token with leading asterisk", "*foo", absl::nullopt, nullptr},
-};
-
-// For Structured Headers Draft 15
-const struct ParameterizedItemTestCase {
-  const char* name;
-  const char* raw;
-  const absl::optional<ParameterizedItem>
-      expected;           // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} parameterized_item_test_cases[] = {
-    {"single parameter item",
-     "text/html;q=1.0",
-     {{Token("text/html"), {DoubleParam("q", 1)}}},
-     nullptr},
-    {"missing parameter value item",
-     "text/html;a;q=1.0",
-     {{Token("text/html"), {BooleanParam("a", true), DoubleParam("q", 1)}}},
-     nullptr},
-    {"missing terminal parameter value item",
-     "text/html;q=1.0;a",
-     {{Token("text/html"), {DoubleParam("q", 1), BooleanParam("a", true)}}},
-     nullptr},
-    {"duplicate parameter keys with different value",
-     "text/html;a=1;b=2;a=3.0",
-     {{Token("text/html"), {DoubleParam("a", 3), Param("b", 2L)}}},
-     "text/html;a=3.0;b=2"},
-    {"multiple duplicate parameter keys at different position",
-     "text/html;c=1;a=2;b;b=3.0;a",
-     {{Token("text/html"),
-       {Param("c", 1L), BooleanParam("a", true), DoubleParam("b", 3)}}},
-     "text/html;c=1;a;b=3.0"},
-    {"duplicate parameter keys with missing value",
-     "text/html;a;a=1",
-     {{Token("text/html"), {Param("a", 1L)}}},
-     "text/html;a=1"},
-    {"whitespace before = parameterised item", "text/html, text/plain;q =0.5",
-     absl::nullopt, nullptr},
-    {"whitespace after = parameterised item", "text/html, text/plain;q= 0.5",
-     absl::nullopt, nullptr},
-    {"whitespace before ; parameterised item", "text/html, text/plain ;q=0.5",
-     absl::nullopt, nullptr},
-    {"whitespace after ; parameterised item",
-     "text/plain; q=0.5",
-     {{Token("text/plain"), {DoubleParam("q", 0.5)}}},
-     "text/plain;q=0.5"},
-    {"extra whitespace parameterised item",
-     "text/plain;  q=0.5;  charset=utf-8",
-     {{Token("text/plain"),
-       {DoubleParam("q", 0.5), TokenParam("charset", "utf-8")}}},
-     "text/plain;q=0.5;charset=utf-8"},
-};
-
-// For Structured Headers Draft 15
-const struct ListTestCase {
-  const char* name;
-  const char* raw;
-  const absl::optional<List> expected;  // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} list_test_cases[] = {
-    // Lists of lists
-    {"extra whitespace list of lists",
-     "(1  42)",
-     {{{{{Integer(1L), {}}, {Integer(42L), {}}}, {}}}},
-     "(1 42)"},
-    // Parameterized Lists
-    {"basic parameterised list",
-     "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"+w\"",
-     {{{Token("abc_123"),
-        {Param("a", 1), Param("b", 2), BooleanParam("cdef_456", true)}},
-       {Token("ghi"), {Param("q", "9"), Param("r", "+w")}}}},
-     "abc_123;a=1;b=2;cdef_456, ghi;q=\"9\";r=\"+w\""},
-    // Parameterized inner lists
-    {"parameterised basic list of lists",
-     "(1;a=1.0 2), (42 43)",
-     {{{{{Integer(1L), {DoubleParam("a", 1.0)}}, {Integer(2L), {}}}, {}},
-       {{{Integer(42L), {}}, {Integer(43L), {}}}, {}}}},
-     nullptr},
-    {"parameters on inner members",
-     "(1;a=1.0 2;b=c), (42;d=?0 43;e=:Zmdo:)",
-     {{{{{Integer(1L), {DoubleParam("a", 1.0)}},
-         {Integer(2L), {TokenParam("b", "c")}}},
-        {}},
-       {{{Integer(42L), {BooleanParam("d", false)}},
-         {Integer(43L), {ByteSequenceParam("e", "fgh")}}},
-        {}}}},
-     nullptr},
-    {"parameters on inner lists",
-     "(1 2);a=1.0, (42 43);b=?0",
-     {{{{{Integer(1L), {}}, {Integer(2L), {}}}, {DoubleParam("a", 1.0)}},
-       {{{Integer(42L), {}}, {Integer(43L), {}}}, {BooleanParam("b", false)}}}},
-     nullptr},
-    {"default true values for parameters on inner list members",
-     "(1;a 2), (42 43;b)",
-     {{{{{Integer(1L), {BooleanParam("a", true)}}, {Integer(2L), {}}}, {}},
-       {{{Integer(42L), {}}, {Integer(43L), {BooleanParam("b", true)}}}, {}}}},
-     nullptr},
-    {"default true values for parameters on inner lists",
-     "(1 2);a, (42 43);b",
-     {{{{{Integer(1L), {}}, {Integer(2L), {}}}, {BooleanParam("a", true)}},
-       {{{Integer(42L), {}}, {Integer(43L), {}}}, {BooleanParam("b", true)}}}},
-     nullptr},
-    {"extra whitespace before semicolon in parameters on inner list member",
-     "(a;b ;c b)", absl::nullopt, nullptr},
-    {"extra whitespace between parameters on inner list member",
-     "(a;b; c b)",
-     {{{{{Token("a"), {BooleanParam("b", true), BooleanParam("c", true)}},
-         {Token("b"), {}}},
-        {}}}},
-     "(a;b;c b)"},
-    {"extra whitespace before semicolon in parameters on inner list",
-     "(a b);c ;d, (e)", absl::nullopt, nullptr},
-    {"extra whitespace between parameters on inner list",
-     "(a b);c; d, (e)",
-     {{{{{Token("a"), {}}, {Token("b"), {}}},
-        {BooleanParam("c", true), BooleanParam("d", true)}},
-       {{{Token("e"), {}}}, {}}}},
-     "(a b);c;d, (e)"},
-};
-
-// For Structured Headers Draft 15
-const struct DictionaryTestCase {
-  const char* name;
-  const char* raw;
-  const absl::optional<Dictionary>
-      expected;           // nullopt if parse error is expected.
-  const char* canonical;  // nullptr if parse error is expected, or if canonical
-                          // format is identical to raw.
-} dictionary_test_cases[] = {
-    {"basic dictionary",
-     "en=\"Applepie\", da=:aGVsbG8=:",
-     {Dictionary{{{"en", {Item("Applepie"), {}}},
-                  {"da", {Item("hello", Item::kByteSequenceType), {}}}}}},
-     nullptr},
-    {"tab separated dictionary",
-     "a=1\t,\tb=2",
-     {Dictionary{{{"a", {Integer(1L), {}}}, {"b", {Integer(2L), {}}}}}},
-     "a=1, b=2"},
-    {"missing value with params dictionary",
-     "a=1, b;foo=9, c=3",
-     {Dictionary{{{"a", {Integer(1L), {}}},
-                  {"b", {Item(true), {Param("foo", 9)}}},
-                  {"c", {Integer(3L), {}}}}}},
-     nullptr},
-    // Parameterised dictionary tests
-    {"parameterised inner list member dict",
-     "a=(\"1\";b=1;c=?0 \"2\");d=\"e\"",
-     {Dictionary{{{"a",
-                   {{{Item("1"), {Param("b", 1), BooleanParam("c", false)}},
-                     {Item("2"), {}}},
-                    {Param("d", "e")}}}}}},
-     nullptr},
-    {"explicit true value with parameter",
-     "a=?1;b=1",
-     {Dictionary{{{"a", {Item(true), {Param("b", 1)}}}}}},
-     "a;b=1"},
-    {"implicit true value with parameter",
-     "a;b=1",
-     {Dictionary{{{"a", {Item(true), {Param("b", 1)}}}}}},
-     nullptr},
-    {"implicit true value with implicitly-valued parameter",
-     "a;b",
-     {Dictionary{{{"a", {Item(true), {BooleanParam("b", true)}}}}}},
-     nullptr},
-};
-}  // namespace
-
-TEST(StructuredHeaderTest, ParseBareItem) {
-  for (const auto& c : item_test_cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<Item> result = ParseBareItem(c.raw);
-    EXPECT_EQ(result, c.expected);
-  }
-}
-
-// For Structured Headers Draft 15, these tests include parameters on Items.
-TEST(StructuredHeaderTest, ParseItem) {
-  for (const auto& c : parameterized_item_test_cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<ParameterizedItem> result = ParseItem(c.raw);
-    EXPECT_EQ(result, c.expected);
-  }
-}
-
-// Structured Headers Draft 9 parsing rules are different than Draft 15, and
-// some strings which are considered invalid in SH15 should parse in SH09.
-// The SH09 Item parser is not directly exposed, but can be used indirectly by
-// calling the parser for SH09-specific lists.
-TEST(StructuredHeaderTest, ParseSH09Item) {
-  for (const auto& c : sh09_item_test_cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<ListOfLists> result = ParseListOfLists(c.raw);
-    if (c.expected.has_value()) {
-      EXPECT_TRUE(result.has_value());
-      EXPECT_EQ(result->size(), 1UL);
-      EXPECT_EQ((*result)[0].size(), 1UL);
-      EXPECT_EQ((*result)[0][0], c.expected);
-    } else {
-      EXPECT_FALSE(result.has_value());
-    }
-  }
-}
-
-// In Structured Headers Draft 9, floats can have more than three fractional
-// digits, and can be larger than 1e12. This behaviour is exposed in the parser
-// for SH09-specific lists, so test it through that interface.
-TEST(StructuredHeaderTest, SH09HighPrecisionFloats) {
-  // These values are exactly representable in binary floating point, so no
-  // accuracy issues are expected in this test.
-  absl::optional<ListOfLists> result =
-      ParseListOfLists("1.03125;-1.03125;12345678901234.5;-12345678901234.5");
-  ASSERT_TRUE(result.has_value());
-  EXPECT_EQ(*result,
-            (ListOfLists{{Item(1.03125), Item(-1.03125), Item(12345678901234.5),
-                          Item(-12345678901234.5)}}));
-
-  result = ParseListOfLists("123456789012345.0");
-  EXPECT_FALSE(result.has_value());
-
-  result = ParseListOfLists("-123456789012345.0");
-  EXPECT_FALSE(result.has_value());
-}
-
-// For Structured Headers Draft 9
-TEST(StructuredHeaderTest, ParseListOfLists) {
-  static const struct TestCase {
-    const char* name;
-    const char* raw;
-    ListOfLists expected;  // empty if parse error is expected
-  } cases[] = {
-      {"basic list of lists",
-       "1;2, 42;43",
-       {{Integer(1L), Integer(2L)}, {Integer(42L), Integer(43L)}}},
-      {"empty list of lists", "", {}},
-      {"single item list of lists", "42", {{Integer(42L)}}},
-      {"no whitespace list of lists", "1,42", {{Integer(1L)}, {Integer(42L)}}},
-      {"no inner whitespace list of lists",
-       "1;2, 42;43",
-       {{Integer(1L), Integer(2L)}, {Integer(42L), Integer(43L)}}},
-      {"extra whitespace list of lists",
-       "1 , 42",
-       {{Integer(1L)}, {Integer(42L)}}},
-      {"extra inner whitespace list of lists",
-       "1 ; 2,42 ; 43",
-       {{Integer(1L), Integer(2L)}, {Integer(42L), Integer(43L)}}},
-      {"trailing comma list of lists", "1;2, 42,", {}},
-      {"trailing semicolon list of lists", "1;2, 42;43;", {}},
-      {"leading comma list of lists", ",1;2, 42", {}},
-      {"leading semicolon list of lists", ";1;2, 42;43", {}},
-      {"empty item list of lists", "1,,42", {}},
-      {"empty inner item list of lists", "1;;2,42", {}},
-  };
-  for (const auto& c : cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<ListOfLists> result = ParseListOfLists(c.raw);
-    if (!c.expected.empty()) {
-      EXPECT_TRUE(result.has_value());
-      EXPECT_EQ(*result, c.expected);
-    } else {
-      EXPECT_FALSE(result.has_value());
-    }
-  }
-}
-
-// For Structured Headers Draft 9
-TEST(StructuredHeaderTest, ParseParameterisedList) {
-  static const struct TestCase {
-    const char* name;
-    const char* raw;
-    ParameterisedList expected;  // empty if parse error is expected
-  } cases[] = {
-      {"basic param-list",
-       "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"",
-       {
-           {Token("abc_123"),
-            {Param("a", 1), Param("b", 2), NullParam("cdef_456")}},
-           {Token("ghi"), {Param("q", "9"), Param("r", "w")}},
-       }},
-      {"empty param-list", "", {}},
-      {"single item param-list",
-       "text/html;q=1",
-       {{Token("text/html"), {Param("q", 1)}}}},
-      {"empty param-list", "", {}},
-      {"no whitespace param-list",
-       "text/html,text/plain;q=1",
-       {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}},
-      {"whitespace before = param-list", "text/html, text/plain;q =1", {}},
-      {"whitespace after = param-list", "text/html, text/plain;q= 1", {}},
-      {"extra whitespace param-list",
-       "text/html  ,  text/plain ;  q=1",
-       {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}},
-      {"duplicate key", "abc;a=1;b=2;a=1", {}},
-      {"numeric key", "abc;a=1;1b=2;c=1", {}},
-      {"uppercase key", "abc;a=1;B=2;c=1", {}},
-      {"bad key", "abc;a=1;b!=2;c=1", {}},
-      {"another bad key", "abc;a=1;b==2;c=1", {}},
-      {"empty key name", "abc;a=1;=2;c=1", {}},
-      {"empty parameter", "abc;a=1;;c=1", {}},
-      {"empty list item", "abc;a=1,,def;b=1", {}},
-      {"extra semicolon", "abc;a=1;b=1;", {}},
-      {"extra comma", "abc;a=1,def;b=1,", {}},
-      {"leading semicolon", ";abc;a=1", {}},
-      {"leading comma", ",abc;a=1", {}},
-  };
-  for (const auto& c : cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<ParameterisedList> result = ParseParameterisedList(c.raw);
-    if (c.expected.empty()) {
-      EXPECT_FALSE(result.has_value());
-      continue;
-    }
-    EXPECT_TRUE(result.has_value());
-    EXPECT_EQ(result->size(), c.expected.size());
-    if (result->size() == c.expected.size()) {
-      for (size_t i = 0; i < c.expected.size(); ++i) {
-        EXPECT_EQ((*result)[i], c.expected[i]);
-      }
-    }
-  }
-}
-
-// For Structured Headers Draft 15
-TEST(StructuredHeaderTest, ParseList) {
-  for (const auto& c : list_test_cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<List> result = ParseList(c.raw);
-    EXPECT_EQ(result, c.expected);
-  }
-}
-
-// For Structured Headers Draft 15
-TEST(StructuredHeaderTest, ParseDictionary) {
-  for (const auto& c : dictionary_test_cases) {
-    SCOPED_TRACE(c.name);
-    absl::optional<Dictionary> result = ParseDictionary(c.raw);
-    EXPECT_EQ(result, c.expected);
-  }
-}
-
-// Serializer tests are all exclusively for Structured Headers Draft 15
-
-TEST(StructuredHeaderTest, SerializeItem) {
-  for (const auto& c : item_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeItem(*c.expected);
-      EXPECT_TRUE(result.has_value());
-      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
-    }
-  }
-}
-
-TEST(StructuredHeaderTest, SerializeParameterizedItem) {
-  for (const auto& c : parameterized_item_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeItem(*c.expected);
-      EXPECT_TRUE(result.has_value());
-      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
-    }
-  }
-}
-
-TEST(StructuredHeaderTest, UnserializableItems) {
-  // Test that items with unknown type are not serialized.
-  EXPECT_FALSE(SerializeItem(Item()).has_value());
-}
-
-TEST(StructuredHeaderTest, UnserializableTokens) {
-  static const struct UnserializableString {
-    const char* name;
-    const char* value;
-  } bad_tokens[] = {
-      {"empty token", ""},
-      {"contains high ascii", "a\xff"},
-      {"contains nonprintable character", "a\x7f"},
-      {"contains C0", "a\x01"},
-      {"UTF-8 encoded", "a\xc3\xa9"},
-      {"contains TAB", "a\t"},
-      {"contains LF", "a\n"},
-      {"contains CR", "a\r"},
-      {"contains SP", "a "},
-      {"begins with digit", "9token"},
-      {"begins with hyphen", "-token"},
-      {"begins with LF", "\ntoken"},
-      {"begins with SP", " token"},
-      {"begins with colon", ":token"},
-      {"begins with percent", "%token"},
-      {"begins with period", ".token"},
-      {"begins with slash", "/token"},
-  };
-  for (const auto& bad_token : bad_tokens) {
-    SCOPED_TRACE(bad_token.name);
-    absl::optional<std::string> serialization =
-        SerializeItem(Token(bad_token.value));
-    EXPECT_FALSE(serialization.has_value()) << *serialization;
-  }
-}
-
-TEST(StructuredHeaderTest, UnserializableKeys) {
-  static const struct UnserializableString {
-    const char* name;
-    const char* value;
-  } bad_keys[] = {
-      {"empty key", ""},
-      {"contains high ascii", "a\xff"},
-      {"contains nonprintable character", "a\x7f"},
-      {"contains C0", "a\x01"},
-      {"UTF-8 encoded", "a\xc3\xa9"},
-      {"contains TAB", "a\t"},
-      {"contains LF", "a\n"},
-      {"contains CR", "a\r"},
-      {"contains SP", "a "},
-      {"begins with uppercase", "Atoken"},
-      {"begins with digit", "9token"},
-      {"begins with hyphen", "-token"},
-      {"begins with LF", "\ntoken"},
-      {"begins with SP", " token"},
-      {"begins with colon", ":token"},
-      {"begins with percent", "%token"},
-      {"begins with period", ".token"},
-      {"begins with slash", "/token"},
-  };
-  for (const auto& bad_key : bad_keys) {
-    SCOPED_TRACE(bad_key.name);
-    absl::optional<std::string> serialization =
-        SerializeItem(ParameterizedItem("a", {{bad_key.value, "a"}}));
-    EXPECT_FALSE(serialization.has_value()) << *serialization;
-  }
-}
-
-TEST(StructuredHeaderTest, UnserializableStrings) {
-  static const struct UnserializableString {
-    const char* name;
-    const char* value;
-  } bad_strings[] = {
-      {"contains high ascii", "a\xff"},
-      {"contains nonprintable character", "a\x7f"},
-      {"UTF-8 encoded", "a\xc3\xa9"},
-      {"contains TAB", "a\t"},
-      {"contains LF", "a\n"},
-      {"contains CR", "a\r"},
-      {"contains C0", "a\x01"},
-  };
-  for (const auto& bad_string : bad_strings) {
-    SCOPED_TRACE(bad_string.name);
-    absl::optional<std::string> serialization =
-        SerializeItem(Item(bad_string.value));
-    EXPECT_FALSE(serialization.has_value()) << *serialization;
-  }
-}
-
-TEST(StructuredHeaderTest, UnserializableIntegers) {
-  EXPECT_FALSE(SerializeItem(Integer(1e15L)).has_value());
-  EXPECT_FALSE(SerializeItem(Integer(-1e15L)).has_value());
-}
-
-TEST(StructuredHeaderTest, UnserializableDecimals) {
-  for (double value :
-       {std::numeric_limits<double>::quiet_NaN(),
-        std::numeric_limits<double>::infinity(),
-        -std::numeric_limits<double>::infinity(), 1e12, 1e12 - 0.0001,
-        1e12 - 0.0005, -1e12, -1e12 + 0.0001, -1e12 + 0.0005}) {
-    auto x = SerializeItem(Item(value));
-    EXPECT_FALSE(SerializeItem(Item(value)).has_value());
-  }
-}
-
-// These values cannot be directly parsed from headers, but are valid doubles
-// which can be serialized as sh-floats (though rounding is expected.)
-TEST(StructuredHeaderTest, SerializeUnparseableDecimals) {
-  struct UnparseableDecimal {
-    const char* name;
-    double value;
-    const char* canonical;
-  } float_test_cases[] = {
-      {"negative 0", -0.0, "0.0"},
-      {"0.0001", 0.0001, "0.0"},
-      {"0.0000001", 0.0000001, "0.0"},
-      {"1.0001", 1.0001, "1.0"},
-      {"1.0009", 1.0009, "1.001"},
-      {"round positive odd decimal", 0.0015, "0.002"},
-      {"round positive even decimal", 0.0025, "0.002"},
-      {"round negative odd decimal", -0.0015, "-0.002"},
-      {"round negative even decimal", -0.0025, "-0.002"},
-      {"round decimal up to integer part", 9.9995, "10.0"},
-      {"subnormal numbers", std::numeric_limits<double>::denorm_min(), "0.0"},
-      {"round up to 10 digits", 1e9 - 0.0000001, "1000000000.0"},
-      {"round up to 11 digits", 1e10 - 0.000001, "10000000000.0"},
-      {"round up to 12 digits", 1e11 - 0.00001, "100000000000.0"},
-      {"largest serializable float", nextafter(1e12 - 0.0005, 0),
-       "999999999999.999"},
-      {"largest serializable negative float", -nextafter(1e12 - 0.0005, 0),
-       "-999999999999.999"},
-      // This will fail if we simply truncate the fractional portion.
-      {"float rounds up to next int", 3.9999999, "4.0"},
-      // This will fail if we first round to >3 digits, and then round again to
-      // 3 digits.
-      {"don't double round", 3.99949, "3.999"},
-      // This will fail if we first round to 3 digits, and then round again to
-      // max_avail_digits.
-      {"don't double round", 123456789.99949, "123456789.999"},
-  };
-  for (const auto& test_case : float_test_cases) {
-    SCOPED_TRACE(test_case.name);
-    absl::optional<std::string> serialization =
-        SerializeItem(Item(test_case.value));
-    EXPECT_TRUE(serialization.has_value());
-    EXPECT_EQ(*serialization, test_case.canonical);
-  }
-}
-
-TEST(StructuredHeaderTest, SerializeList) {
-  for (const auto& c : list_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeList(*c.expected);
-      EXPECT_TRUE(result.has_value());
-      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
-    }
-  }
-}
-
-TEST(StructuredHeaderTest, UnserializableLists) {
-  static const struct UnserializableList {
-    const char* name;
-    const List value;
-  } bad_lists[] = {
-      {"Null item as member", {{Item(), {}}}},
-      {"Unserializable item as member", {{Token("\n"), {}}}},
-      {"Key is empty", {{Token("abc"), {Param("", 1)}}}},
-      {"Key containswhitespace", {{Token("abc"), {Param("a\n", 1)}}}},
-      {"Key contains UTF8", {{Token("abc"), {Param("a\xc3\xa9", 1)}}}},
-      {"Key contains unprintable characters",
-       {{Token("abc"), {Param("a\x7f", 1)}}}},
-      {"Key contains disallowed characters",
-       {{Token("abc"), {Param("a:", 1)}}}},
-      {"Param value is unserializable", {{Token("abc"), {{"a", Token("\n")}}}}},
-      {"Inner list contains unserializable item",
-       {{std::vector<ParameterizedItem>{{Token("\n"), {}}}, {}}}},
-  };
-  for (const auto& bad_list : bad_lists) {
-    SCOPED_TRACE(bad_list.name);
-    absl::optional<std::string> serialization = SerializeList(bad_list.value);
-    EXPECT_FALSE(serialization.has_value()) << *serialization;
-  }
-}
-
-TEST(StructuredHeaderTest, SerializeDictionary) {
-  for (const auto& c : dictionary_test_cases) {
-    SCOPED_TRACE(c.name);
-    if (c.expected) {
-      absl::optional<std::string> result = SerializeDictionary(*c.expected);
-      EXPECT_TRUE(result.has_value());
-      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
-    }
-  }
-}
-
-TEST(StructuredHeaderTest, DictionaryConstructors) {
-  const std::string key0 = "key0";
-  const std::string key1 = "key1";
-  const ParameterizedMember member0{Item("Applepie"), {}};
-  const ParameterizedMember member1{Item("hello", Item::kByteSequenceType), {}};
-
-  Dictionary dict;
-  EXPECT_TRUE(dict.empty());
-  EXPECT_EQ(0U, dict.size());
-  dict[key0] = member0;
-  EXPECT_FALSE(dict.empty());
-  EXPECT_EQ(1U, dict.size());
-
-  const Dictionary dict_copy = dict;
-  EXPECT_FALSE(dict_copy.empty());
-  EXPECT_EQ(1U, dict_copy.size());
-  EXPECT_EQ(dict, dict_copy);
-
-  const Dictionary dict_init{{{key0, member0}, {key1, member1}}};
-  EXPECT_FALSE(dict_init.empty());
-  EXPECT_EQ(2U, dict_init.size());
-  EXPECT_EQ(member0, dict_init.at(key0));
-  EXPECT_EQ(member1, dict_init.at(key1));
-}
-
-TEST(StructuredHeaderTest, DictionaryAccessors) {
-  const std::string key0 = "key0";
-  const std::string key1 = "key1";
-
-  const ParameterizedMember nonempty_member0{Item("Applepie"), {}};
-  const ParameterizedMember nonempty_member1{
-      Item("hello", Item::kByteSequenceType), {}};
-  const ParameterizedMember empty_member;
-
-  Dictionary dict{{{key0, nonempty_member0}}};
-  EXPECT_TRUE(dict.contains(key0));
-  EXPECT_EQ(nonempty_member0, dict[key0]);
-  EXPECT_EQ(&dict[key0], &dict.at(key0));
-  EXPECT_EQ(&dict[key0], &dict[0]);
-  EXPECT_EQ(&dict[key0], &dict.at(0));
-
-  // Even if the key does not yet exist in |dict|, operator[]() should
-  // automatically create an empty entry.
-  ASSERT_FALSE(dict.contains(key1));
-  ParameterizedMember& member1 = dict[key1];
-  EXPECT_TRUE(dict.contains(key1));
-  EXPECT_EQ(empty_member, member1);
-  EXPECT_EQ(&member1, &dict[key1]);
-  EXPECT_EQ(&member1, &dict.at(key1));
-  EXPECT_EQ(&member1, &dict[1]);
-  EXPECT_EQ(&member1, &dict.at(1));
-
-  member1 = nonempty_member1;
-  EXPECT_EQ(nonempty_member1, dict[key1]);
-  EXPECT_EQ(&dict[key1], &dict.at(key1));
-  EXPECT_EQ(&dict[key1], &dict[1]);
-  EXPECT_EQ(&dict[key1], &dict.at(1));
-
-  // at(StringPiece) and indexed accessors have const overloads.
-  const Dictionary& dict_ref = dict;
-  EXPECT_EQ(&member1, &dict_ref.at(key1));
-  EXPECT_EQ(&member1, &dict_ref[1]);
-  EXPECT_EQ(&member1, &dict_ref.at(1));
-}
-
-TEST(StructuredHeaderTest, UnserializableDictionary) {
-  static const struct UnserializableDictionary {
-    const char* name;
-    const Dictionary value;
-  } bad_dictionaries[] = {
-      {"Unserializable dict key", Dictionary{{{"ABC", {Token("abc"), {}}}}}},
-      {"Dictionary item is unserializable",
-       Dictionary{{{"abc", {Token("abc="), {}}}}}},
-      {"Param value is unserializable",
-       Dictionary{{{"abc", {Token("abc"), {{"a", Token("\n")}}}}}}},
-      {"Dictionary inner-list contains unserializable item",
-       Dictionary{
-           {{"abc",
-             {std::vector<ParameterizedItem>{{Token("abc="), {}}}, {}}}}}},
-  };
-  for (const auto& bad_dictionary : bad_dictionaries) {
-    SCOPED_TRACE(bad_dictionary.name);
-    absl::optional<std::string> serialization =
-        SerializeDictionary(bad_dictionary.value);
-    EXPECT_FALSE(serialization.has_value()) << *serialization;
-  }
-}
-
-}  // namespace structured_headers
-}  // namespace quiche
diff --git a/common/test_tools/quiche_test_utils.cc b/common/test_tools/quiche_test_utils.cc
deleted file mode 100644
index 5ebe527..0000000
--- a/common/test_tools/quiche_test_utils.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "common/test_tools/quiche_test_utils.h"
-
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-#include <string>
-
-namespace {
-
-std::string HexDumpWithMarks(const char* data,
-                             int length,
-                             const bool* marks,
-                             int mark_length) {
-  static const char kHexChars[] = "0123456789abcdef";
-  static const int kColumns = 4;
-
-  const int kSizeLimit = 1024;
-  if (length > kSizeLimit || mark_length > kSizeLimit) {
-    QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
-    length = std::min(length, kSizeLimit);
-    mark_length = std::min(mark_length, kSizeLimit);
-  }
-
-  std::string hex;
-  for (const char* row = data; length > 0;
-       row += kColumns, length -= kColumns) {
-    for (const char* p = row; p < row + 4; ++p) {
-      if (p < row + length) {
-        const bool mark =
-            (marks && (p - data) < mark_length && marks[p - data]);
-        hex += mark ? '*' : ' ';
-        hex += kHexChars[(*p & 0xf0) >> 4];
-        hex += kHexChars[*p & 0x0f];
-        hex += mark ? '*' : ' ';
-      } else {
-        hex += "    ";
-      }
-    }
-    hex = hex + "  ";
-
-    for (const char* p = row; p < row + 4 && p < row + length; ++p) {
-      hex += (*p >= 0x20 && *p < 0x7f) ? (*p) : '.';
-    }
-
-    hex = hex + '\n';
-  }
-  return hex;
-}
-
-}  // namespace
-
-namespace quiche {
-namespace test {
-
-void CompareCharArraysWithHexError(const std::string& description,
-                                   const char* actual,
-                                   const int actual_len,
-                                   const char* expected,
-                                   const int expected_len) {
-  EXPECT_EQ(actual_len, expected_len);
-  const int min_len = std::min(actual_len, expected_len);
-  const int max_len = std::max(actual_len, expected_len);
-  std::unique_ptr<bool[]> marks(new bool[max_len]);
-  bool identical = (actual_len == expected_len);
-  for (int i = 0; i < min_len; ++i) {
-    if (actual[i] != expected[i]) {
-      marks[i] = true;
-      identical = false;
-    } else {
-      marks[i] = false;
-    }
-  }
-  for (int i = min_len; i < max_len; ++i) {
-    marks[i] = true;
-  }
-  if (identical)
-    return;
-  ADD_FAILURE() << "Description:\n"
-                << description << "\n\nExpected:\n"
-                << HexDumpWithMarks(expected, expected_len, marks.get(),
-                                    max_len)
-                << "\nActual:\n"
-                << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
-}
-
-iovec MakeIOVector(absl::string_view str) {
-  return iovec{const_cast<char*>(str.data()), static_cast<size_t>(str.size())};
-}
-
-}  // namespace test
-}  // namespace quiche
diff --git a/common/test_tools/quiche_test_utils.h b/common/test_tools/quiche_test_utils.h
deleted file mode 100644
index adbaaa4..0000000
--- a/common/test_tools/quiche_test_utils.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_COMMON_QUICHE_TEST_UTILS_H_
-#define QUICHE_COMMON_QUICHE_TEST_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_iovec.h"
-
-namespace quiche {
-namespace test {
-
-void CompareCharArraysWithHexError(const std::string& description,
-                                   const char* actual,
-                                   const int actual_len,
-                                   const char* expected,
-                                   const int expected_len);
-
-// Create iovec that points to that data that `str` points to.
-iovec MakeIOVector(absl::string_view str);
-
-}  // namespace test
-}  // namespace quiche
-
-#endif  // QUICHE_COMMON_QUICHE_TEST_UTILS_H_
diff --git a/epoll_server/fake_simple_epoll_server.cc b/epoll_server/fake_simple_epoll_server.cc
deleted file mode 100644
index 1e8b0b1..0000000
--- a/epoll_server/fake_simple_epoll_server.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "epoll_server/fake_simple_epoll_server.h"
-
-namespace epoll_server {
-namespace test {
-
-FakeTimeSimpleEpollServer::FakeTimeSimpleEpollServer() : now_in_usec_(0) {}
-
-FakeTimeSimpleEpollServer::~FakeTimeSimpleEpollServer() = default;
-
-int64_t FakeTimeSimpleEpollServer::NowInUsec() const { return now_in_usec_; }
-
-FakeSimpleEpollServer::FakeSimpleEpollServer() : until_in_usec_(-1) {}
-
-FakeSimpleEpollServer::~FakeSimpleEpollServer() = default;
-
-int FakeSimpleEpollServer::epoll_wait_impl(int /*epfd*/,
-                                           struct epoll_event* events,
-                                           int max_events, int timeout_in_ms) {
-  int num_events = 0;
-  while (!event_queue_.empty() && num_events < max_events &&
-         event_queue_.begin()->first <= NowInUsec() &&
-         ((until_in_usec_ == -1) ||
-          (event_queue_.begin()->first < until_in_usec_))) {
-    int64_t event_time_in_usec = event_queue_.begin()->first;
-    events[num_events] = event_queue_.begin()->second;
-    if (event_time_in_usec > NowInUsec()) {
-      set_now_in_usec(event_time_in_usec);
-    }
-    event_queue_.erase(event_queue_.begin());
-    ++num_events;
-  }
-  if (num_events == 0) {       // then we'd have waited 'till the timeout.
-    if (until_in_usec_ < 0) {  // then we don't care what the final time is.
-      if (timeout_in_ms > 0) {
-        AdvanceBy(timeout_in_ms * 1000);
-      }
-    } else {  // except we assume that we don't wait for the timeout
-      // period if until_in_usec_ is a positive number.
-      set_now_in_usec(until_in_usec_);
-      // And reset until_in_usec_ to signal no waiting (as
-      // the AdvanceByExactly* stuff is meant to be one-shot,
-      // as are all similar net::EpollServer functions)
-      until_in_usec_ = -1;
-    }
-  }
-  if (until_in_usec_ >= 0) {
-    CHECK(until_in_usec_ >= NowInUsec());
-  }
-  return num_events;
-}
-
-}  // namespace test
-}  // namespace epoll_server
diff --git a/epoll_server/fake_simple_epoll_server.h b/epoll_server/fake_simple_epoll_server.h
deleted file mode 100644
index 3c67786..0000000
--- a/epoll_server/fake_simple_epoll_server.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
-#define QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-
-#include "epoll_server/platform/api/epoll_export.h"
-#include "epoll_server/simple_epoll_server.h"
-
-namespace epoll_server {
-namespace test {
-
-// Unlike the full FakeEpollServer, this only lies about the time but lets
-// fd events operate normally.  Usefully when interacting with real backends
-// but wanting to skip forward in time to trigger timeouts.
-class EPOLL_EXPORT_PRIVATE FakeTimeSimpleEpollServer
-    : public SimpleEpollServer {
- public:
-  FakeTimeSimpleEpollServer();
-  FakeTimeSimpleEpollServer(const FakeTimeSimpleEpollServer&) = delete;
-  FakeTimeSimpleEpollServer operator=(const FakeTimeSimpleEpollServer&) =
-      delete;
-
-  ~FakeTimeSimpleEpollServer() override;
-
-  // Replaces the net::EpollServer NowInUsec.
-  int64_t NowInUsec() const override;
-
-  void set_now_in_usec(int64_t nius) { now_in_usec_ = nius; }
-
-  // Advances the virtual 'now' by advancement_usec.
-  void AdvanceBy(int64_t advancement_usec) {
-    set_now_in_usec(NowInUsec() + advancement_usec);
-  }
-
-  // Advances the virtual 'now' by advancement_usec, and
-  // calls WaitForEventAndExecteCallbacks.
-  // Note that the WaitForEventsAndExecuteCallbacks invocation
-  // may cause NowInUs to advance beyond what was specified here.
-  // If that is not desired, use the AdvanceByExactly calls.
-  void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64_t advancement_usec) {
-    AdvanceBy(advancement_usec);
-    WaitForEventsAndExecuteCallbacks();
-  }
-
- private:
-  int64_t now_in_usec_;
-};
-
-class EPOLL_EXPORT_PRIVATE FakeSimpleEpollServer
-    : public FakeTimeSimpleEpollServer {
- public:  // type definitions
-  using EventQueue = std::multimap<int64_t, struct epoll_event>;
-
-  FakeSimpleEpollServer();
-  FakeSimpleEpollServer(const FakeSimpleEpollServer&) = delete;
-  FakeSimpleEpollServer operator=(const FakeSimpleEpollServer&) = delete;
-
-  ~FakeSimpleEpollServer() override;
-
-  // time_in_usec is the time at which the event specified
-  // by 'ee' will be delivered. Note that it -is- possible
-  // to add an event for a time which has already been passed..
-  // .. upon the next time that the callbacks are invoked,
-  // all events which are in the 'past' will be delivered.
-  void AddEvent(int64_t time_in_usec, const struct epoll_event& ee) {
-    event_queue_.insert(std::make_pair(time_in_usec, ee));
-  }
-
-  // Advances the virtual 'now' by advancement_usec,
-  // and ensure that the next invocation of
-  // WaitForEventsAndExecuteCallbacks goes no farther than
-  // advancement_usec from the current time.
-  void AdvanceByExactly(int64_t advancement_usec) {
-    until_in_usec_ = NowInUsec() + advancement_usec;
-    set_now_in_usec(NowInUsec() + advancement_usec);
-  }
-
-  // As above, except calls WaitForEventsAndExecuteCallbacks.
-  void AdvanceByExactlyAndCallCallbacks(int64_t advancement_usec) {
-    AdvanceByExactly(advancement_usec);
-    WaitForEventsAndExecuteCallbacks();
-  }
-
-  std::unordered_set<AlarmCB*>::size_type NumberOfAlarms() const {
-    return all_alarms_.size();
-  }
-
- protected:  // functions
-  // These functions do nothing here, as we're not actually
-  // using the epoll_* syscalls.
-  void DelFD(int /*fd*/) const override {}
-  void AddFD(int /*fd*/, int /*event_mask*/) const override {}
-  void ModFD(int /*fd*/, int /*event_mask*/) const override {}
-
-  // Replaces the epoll_server's epoll_wait_impl.
-  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
-                      int timeout_in_ms) override;
-  void SetNonblocking(int /*fd*/) override {}
-
- private:  // members
-  EventQueue event_queue_;
-  int64_t until_in_usec_;
-};
-
-}  // namespace test
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
diff --git a/epoll_server/simple_epoll_server.cc b/epoll_server/simple_epoll_server.cc
deleted file mode 100644
index 0092bb1..0000000
--- a/epoll_server/simple_epoll_server.cc
+++ /dev/null
@@ -1,813 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "epoll_server/simple_epoll_server.h"
-
-#include <errno.h>   // for errno
-#include <stdlib.h>  // for abort
-#include <string.h>  // for strerror_r
-#include <unistd.h>  // For read, pipe, close and write.
-
-#include <algorithm>
-#include <utility>
-
-#include "epoll_server/platform/api/epoll_bug.h"
-#include "epoll_server/platform/api/epoll_time.h"
-
-// Design notes: An efficient implementation of ready list has the following
-// desirable properties:
-//
-// A. O(1) insertion into/removal from the list in any location.
-// B. Once the callback is found by hash lookup using the fd, the lookup of
-//    corresponding entry in the list is O(1).
-// C. Safe insertion into/removal from the list during list iteration. (The
-//    ready list's purpose is to enable completely event driven I/O model.
-//    Thus, all the interesting bits happen in the callback. It is critical
-//    to not place any restriction on the API during list iteration.
-//
-// The current implementation achieves these goals with the following design:
-//
-// - The ready list is constructed as a doubly linked list to enable O(1)
-//   insertion/removal (see man 3 queue).
-// - The forward and backward links are directly embedded inside the
-//   CBAndEventMask struct. This enables O(1) lookup in the list for a given
-//   callback. (Techincally, we could've used std::list of hash_set::iterator,
-//   and keep a list::iterator in CBAndEventMask to achieve the same effect.
-//   However, iterators have two problems: no way to portably invalidate them,
-//   and no way to tell whether an iterator is singular or not. The only way to
-//   overcome these issues is to keep bools in both places, but that throws off
-//   memory alignment (up to 7 wasted bytes for each bool). The extra level of
-//   indirection will also likely be less cache friendly. Direct manipulation
-//   of link pointers makes it easier to retrieve the CBAndEventMask from the
-//   list, easier to check whether an CBAndEventMask is in the list, uses less
-//   memory (save 32 bytes/fd), and does not affect cache usage (we need to
-//   read in the struct to use the callback anyway).)
-// - Embed the fd directly into CBAndEventMask and switch to using hash_set.
-//   This removes the need to store hash_map::iterator in the list just so that
-//   we can get both the fd and the callback.
-// - The ready list is "one shot": each entry is removed before OnEvent is
-//   called. This removes the mutation-while-iterating problem.
-// - Use two lists to keep track of callbacks. The ready_list_ is the one used
-//   for registration. Before iteration, the ready_list_ is swapped into the
-//   tmp_list_. Once iteration is done, tmp_list_ will be empty, and
-//   ready_list_ will have all the new ready fds.
-
-// The size we use for buffers passed to strerror_r
-static const int kErrorBufferSize = 256;
-
-namespace epoll_server {
-
-template <typename T>
-class AutoReset {
- public:
-  AutoReset(T* scoped_variable, T new_value)
-      : scoped_variable_(scoped_variable),
-        original_value_(std::move(*scoped_variable)) {
-    *scoped_variable_ = std::move(new_value);
-  }
-  AutoReset(const AutoReset&) = delete;
-  AutoReset& operator=(const AutoReset&) = delete;
-
-  ~AutoReset() { *scoped_variable_ = std::move(original_value_); }
-
- private:
-  T* scoped_variable_;
-  T original_value_;
-};
-
-// Clears the pipe and returns.  Used for waking the epoll server up.
-class ReadPipeCallback : public EpollCallbackInterface {
- public:
-  void OnEvent(int fd, EpollEvent* event) override {
-    DCHECK(event->in_events == EPOLLIN);
-    int data;
-    int data_read = 1;
-    // Read until the pipe is empty.
-    while (data_read > 0) {
-      data_read = read(fd, &data, sizeof(data));
-    }
-  }
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-  void OnRegistration(SimpleEpollServer*, int, int) override {}
-  void OnModification(int, int) override {}     // COV_NF_LINE
-  void OnUnregistration(int, bool) override {}  // COV_NF_LINE
-  std::string Name() const override { return "ReadPipeCallback"; }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-SimpleEpollServer::SimpleEpollServer()
-    : epoll_fd_(epoll_create(1024)),
-      timeout_in_us_(0),
-      recorded_now_in_us_(0),
-      ready_list_size_(0),
-      wake_cb_(new ReadPipeCallback),
-      read_fd_(-1),
-      write_fd_(-1),
-      in_wait_for_events_and_execute_callbacks_(false),
-      in_shutdown_(false),
-      last_delay_in_usec_(0) {
-  // ensure that the epoll_fd_ is valid.
-  CHECK_NE(epoll_fd_, -1);
-  LIST_INIT(&ready_list_);
-  LIST_INIT(&tmp_list_);
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    // Unfortunately, it is impossible to test any such initialization in
-    // a constructor (as virtual methods do not yet work).
-    // This -could- be solved by moving initialization to an outside
-    // call...
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Error " << saved_errno << " in pipe(): "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-  read_fd_ = pipe_fds[0];
-  write_fd_ = pipe_fds[1];
-  RegisterFD(read_fd_, wake_cb_.get(), EPOLLIN);
-}
-
-void SimpleEpollServer::CleanupFDToCBMap() {
-  auto cb_iter = cb_map_.begin();
-  while (cb_iter != cb_map_.end()) {
-    int fd = cb_iter->fd;
-    CB* cb = cb_iter->cb;
-
-    cb_iter->in_use = true;
-    if (cb) {
-      cb->OnShutdown(this, fd);
-    }
-
-    cb_map_.erase(cb_iter);
-    cb_iter = cb_map_.begin();
-  }
-}
-
-void SimpleEpollServer::CleanupTimeToAlarmCBMap() {
-  TimeToAlarmCBMap::iterator erase_it;
-
-  // Call OnShutdown() on alarms. Note that the structure of the loop
-  // is similar to the structure of loop in the function HandleAlarms()
-  for (auto i = alarm_map_.begin(); i != alarm_map_.end();) {
-    // Note that OnShutdown() can call UnregisterAlarm() on
-    // other iterators. OnShutdown() should not call UnregisterAlarm()
-    // on self because by definition the iterator is not valid any more.
-    i->second->OnShutdown(this);
-    erase_it = i;
-    ++i;
-    alarm_map_.erase(erase_it);
-  }
-}
-
-SimpleEpollServer::~SimpleEpollServer() {
-  DCHECK_EQ(in_shutdown_, false);
-  in_shutdown_ = true;
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  EPOLL_LOG(INFO) << "\n" << event_recorder_;
-#endif
-  EPOLL_VLOG(2) << "Shutting down epoll server ";
-  CleanupFDToCBMap();
-
-  LIST_INIT(&ready_list_);
-  LIST_INIT(&tmp_list_);
-
-  CleanupTimeToAlarmCBMap();
-
-  close(read_fd_);
-  close(write_fd_);
-  close(epoll_fd_);
-}
-
-// Whether a CBAandEventMask is on the ready list is determined by a non-NULL
-// le_prev pointer (le_next being NULL indicates end of list).
-inline void SimpleEpollServer::AddToReadyList(CBAndEventMask* cb_and_mask) {
-  if (cb_and_mask->entry.le_prev == NULL) {
-    LIST_INSERT_HEAD(&ready_list_, cb_and_mask, entry);
-    ++ready_list_size_;
-  }
-}
-
-inline void SimpleEpollServer::RemoveFromReadyList(
-    const CBAndEventMask& cb_and_mask) {
-  if (cb_and_mask.entry.le_prev != NULL) {
-    LIST_REMOVE(&cb_and_mask, entry);
-    // Clean up all the ready list states. Don't bother with the other fields
-    // as they are initialized when the CBAandEventMask is added to the ready
-    // list. This saves a few cycles in the inner loop.
-    cb_and_mask.entry.le_prev = NULL;
-    --ready_list_size_;
-    if (ready_list_size_ == 0) {
-      DCHECK(ready_list_.lh_first == NULL);
-      DCHECK(tmp_list_.lh_first == NULL);
-    }
-  }
-}
-
-void SimpleEpollServer::RegisterFD(int fd, CB* cb, int event_mask) {
-  CHECK(cb);
-  EPOLL_VLOG(3) << "RegisterFD fd=" << fd << " event_mask=" << event_mask;
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() != fd_i) {
-    // do we just abort, or do we just unregister the other callback?
-    // for now, lets just unregister the other callback.
-
-    // unregister any callback that may already be registered for this FD.
-    CB* other_cb = fd_i->cb;
-    if (other_cb) {
-      // Must remove from the ready list before erasing.
-      RemoveFromReadyList(*fd_i);
-      other_cb->OnUnregistration(fd, true);
-      ModFD(fd, event_mask);
-    } else {
-      // already unregistered, so just recycle the node.
-      AddFD(fd, event_mask);
-    }
-    fd_i->cb = cb;
-    fd_i->event_mask = event_mask;
-    fd_i->events_to_fake = 0;
-  } else {
-    AddFD(fd, event_mask);
-    cb_map_.insert(CBAndEventMask(cb, event_mask, fd));
-  }
-
-  // set the FD to be non-blocking.
-  SetNonblocking(fd);
-
-  cb->OnRegistration(this, fd, event_mask);
-}
-
-void SimpleEpollServer::SetNonblocking(int fd) {
-  int flags = fcntl(fd, F_GETFL, 0);
-  if (flags == -1) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
-                     << ", F_GETFL, 0): "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-  if (!(flags & O_NONBLOCK)) {
-    int saved_flags = flags;
-    flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-    if (flags == -1) {
-      // bad.
-      int saved_errno = errno;
-      char buf[kErrorBufferSize];
-      EPOLL_LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
-                       << ", F_SETFL, " << saved_flags
-                       << "): " << strerror_r(saved_errno, buf, sizeof(buf));
-    }
-  }
-}
-
-int SimpleEpollServer::epoll_wait_impl(int epfd, struct epoll_event* events,
-                                       int max_events, int timeout_in_ms) {
-  return epoll_wait(epfd, events, max_events, timeout_in_ms);
-}
-
-void SimpleEpollServer::RegisterFDForWrite(int fd, CB* cb) {
-  RegisterFD(fd, cb, EPOLLOUT);
-}
-
-void SimpleEpollServer::RegisterFDForReadWrite(int fd, CB* cb) {
-  RegisterFD(fd, cb, EPOLLIN | EPOLLOUT);
-}
-
-void SimpleEpollServer::RegisterFDForRead(int fd, CB* cb) {
-  RegisterFD(fd, cb, EPOLLIN);
-}
-
-void SimpleEpollServer::UnregisterFD(int fd) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() == fd_i || fd_i->cb == NULL) {
-    // Doesn't exist in server, or has gone through UnregisterFD once and still
-    // inside the callchain of OnEvent.
-    return;
-  }
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordUnregistration(fd);
-#endif
-  CB* cb = fd_i->cb;
-  // Since the links are embedded within the struct, we must remove it from the
-  // list before erasing it from the hash_set.
-  RemoveFromReadyList(*fd_i);
-  DelFD(fd);
-  cb->OnUnregistration(fd, false);
-  // fd_i->cb is NULL if that fd is unregistered inside the callchain of
-  // OnEvent. Since the SimpleEpollServer needs a valid CBAndEventMask after
-  // OnEvent returns in order to add it to the ready list, we cannot have
-  // UnregisterFD erase the entry if it is in use. Thus, a NULL fd_i->cb is used
-  // as a condition that tells the SimpleEpollServer that this entry is unused
-  // at a later point.
-  if (!fd_i->in_use) {
-    cb_map_.erase(fd_i);
-  } else {
-    // Remove all trace of the registration, and just keep the node alive long
-    // enough so the code that calls OnEvent doesn't have to worry about
-    // figuring out whether the CBAndEventMask is valid or not.
-    fd_i->cb = NULL;
-    fd_i->event_mask = 0;
-    fd_i->events_to_fake = 0;
-  }
-}
-
-void SimpleEpollServer::ModifyCallback(int fd, int event_mask) {
-  ModifyFD(fd, ~0, event_mask);
-}
-
-void SimpleEpollServer::StopRead(int fd) { ModifyFD(fd, EPOLLIN, 0); }
-
-void SimpleEpollServer::StartRead(int fd) { ModifyFD(fd, 0, EPOLLIN); }
-
-void SimpleEpollServer::StopWrite(int fd) { ModifyFD(fd, EPOLLOUT, 0); }
-
-void SimpleEpollServer::StartWrite(int fd) { ModifyFD(fd, 0, EPOLLOUT); }
-
-void SimpleEpollServer::HandleEvent(int fd, int event_mask) {
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordEpollEvent(fd, event_mask);
-#endif
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (fd_i == cb_map_.end() || fd_i->cb == NULL) {
-    // Ignore the event.
-    // This could occur if epoll() returns a set of events, and
-    // while processing event A (earlier) we removed the callback
-    // for event B (and are now processing event B).
-    return;
-  }
-  fd_i->events_asserted = event_mask;
-  CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i);
-  AddToReadyList(cb_and_mask);
-}
-
-void SimpleEpollServer::WaitForEventsAndExecuteCallbacks() {
-  if (in_wait_for_events_and_execute_callbacks_) {
-    EPOLL_LOG(DFATAL) << "Attempting to call WaitForEventsAndExecuteCallbacks"
-                         " when an ancestor to the current function is already"
-                         " WaitForEventsAndExecuteCallbacks!";
-    // The line below is actually tested, but in coverage mode,
-    // we never see it.
-    return;  // COV_NF_LINE
-  }
-  AutoReset<bool> recursion_guard(&in_wait_for_events_and_execute_callbacks_,
-                                  true);
-  if (alarm_map_.empty()) {
-    // no alarms, this is business as usual.
-    WaitForEventsAndCallHandleEvents(timeout_in_us_, events_, events_size_);
-    recorded_now_in_us_ = 0;
-    return;
-  }
-
-  // store the 'now'. If we recomputed 'now' every iteration
-  // down below, then we might never exit that loop-- any
-  // long-running alarms might install other long-running
-  // alarms, etc. By storing it here now, we ensure that
-  // a more reasonable amount of work is done here.
-  int64_t now_in_us = NowInUsec();
-
-  // Get the first timeout from the alarm_map where it is
-  // stored in absolute time.
-  int64_t next_alarm_time_in_us = alarm_map_.begin()->first;
-  EPOLL_VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us
-                << " now             = " << now_in_us
-                << " timeout_in_us = " << timeout_in_us_;
-
-  int64_t wait_time_in_us;
-  int64_t alarm_timeout_in_us = next_alarm_time_in_us - now_in_us;
-
-  // If the next alarm is sooner than the default timeout, or if there is no
-  // timeout (timeout_in_us_ == -1), wake up when the alarm should fire.
-  // Otherwise use the default timeout.
-  if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) {
-    wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64_t>(0));
-  } else {
-    wait_time_in_us = timeout_in_us_;
-  }
-
-  EPOLL_VLOG(4) << "wait_time_in_us = " << wait_time_in_us;
-
-  // wait for events.
-
-  WaitForEventsAndCallHandleEvents(wait_time_in_us, events_, events_size_);
-  CallAndReregisterAlarmEvents();
-  recorded_now_in_us_ = 0;
-}
-
-void SimpleEpollServer::SetFDReady(int fd, int events_to_fake) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() != fd_i && fd_i->cb != NULL) {
-    // This const_cast is necessary for LIST_HEAD_INSERT to work. Declaring
-    // entry mutable is insufficient because LIST_HEAD_INSERT assigns the
-    // forward pointer of the list head to the current cb_and_mask, and the
-    // compiler complains that it can't assign a const T* to a T*.
-    CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i);
-    // Note that there is no clearly correct behavior here when
-    // cb_and_mask->events_to_fake != 0 and this function is called.
-    // Of the two operations:
-    //      cb_and_mask->events_to_fake = events_to_fake
-    //      cb_and_mask->events_to_fake |= events_to_fake
-    // the first was picked because it discourages users from calling
-    // SetFDReady repeatedly to build up the correct event set as it is more
-    // efficient to call SetFDReady once with the correct, final mask.
-    cb_and_mask->events_to_fake = events_to_fake;
-    AddToReadyList(cb_and_mask);
-  }
-}
-
-void SimpleEpollServer::SetFDNotReady(int fd) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() != fd_i) {
-    RemoveFromReadyList(*fd_i);
-  }
-}
-
-bool SimpleEpollServer::IsFDReady(int fd) const {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  return (cb_map_.end() != fd_i && fd_i->cb != NULL &&
-          fd_i->entry.le_prev != NULL);
-}
-
-void SimpleEpollServer::VerifyReadyList() const {
-  int count = 0;
-  CBAndEventMask* cur = ready_list_.lh_first;
-  for (; cur; cur = cur->entry.le_next) {
-    ++count;
-  }
-  for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) {
-    ++count;
-  }
-  CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count";
-}
-
-void SimpleEpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) {
-  EPOLL_VLOG(4) << "RegisteringAlarm " << ac << " at : " << timeout_time_in_us;
-  CHECK(ac);
-  if (all_alarms_.find(ac) != all_alarms_.end()) {
-    EPOLL_BUG(epoll_bug_1_1) << "Alarm already exists";
-  }
-
-  auto alarm_iter = alarm_map_.insert(std::make_pair(timeout_time_in_us, ac));
-
-  all_alarms_.insert(ac);
-  // Pass the iterator to the EpollAlarmCallbackInterface.
-  ac->OnRegistration(alarm_iter, this);
-}
-
-// Unregister a specific alarm callback: iterator_token must be a
-//  valid iterator. The caller must ensure the validity of the iterator.
-void SimpleEpollServer::UnregisterAlarm(const AlarmRegToken& iterator_token) {
-  AlarmCB* cb = iterator_token->second;
-  EPOLL_VLOG(4) << "UnregisteringAlarm " << cb;
-  alarm_map_.erase(iterator_token);
-  all_alarms_.erase(cb);
-  cb->OnUnregistration();
-}
-
-SimpleEpollServer::AlarmRegToken SimpleEpollServer::ReregisterAlarm(
-    SimpleEpollServer::AlarmRegToken iterator_token,
-    int64_t timeout_time_in_us) {
-  AlarmCB* cb = iterator_token->second;
-  alarm_map_.erase(iterator_token);
-  return alarm_map_.emplace(timeout_time_in_us, cb);
-}
-
-int SimpleEpollServer::NumFDsRegistered() const {
-  DCHECK_GE(cb_map_.size(), 1u);
-  // Omit the internal FD (read_fd_)
-  return cb_map_.size() - 1;
-}
-
-void SimpleEpollServer::Wake() {
-  char data = 'd';  // 'd' is for data.  It's good enough for me.
-  int rv = write(write_fd_, &data, 1);
-  DCHECK_EQ(rv, 1);
-}
-
-int64_t SimpleEpollServer::NowInUsec() const { return WallTimeNowInUsec(); }
-
-int64_t SimpleEpollServer::ApproximateNowInUsec() const {
-  if (recorded_now_in_us_ != 0) {
-    return recorded_now_in_us_;
-  }
-  return this->NowInUsec();
-}
-
-std::string SimpleEpollServer::EventMaskToString(int event_mask) {
-  std::string s;
-  if (event_mask & EPOLLIN) s += "EPOLLIN ";
-  if (event_mask & EPOLLPRI) s += "EPOLLPRI ";
-  if (event_mask & EPOLLOUT) s += "EPOLLOUT ";
-  if (event_mask & EPOLLRDNORM) s += "EPOLLRDNORM ";
-  if (event_mask & EPOLLRDBAND) s += "EPOLLRDBAND ";
-  if (event_mask & EPOLLWRNORM) s += "EPOLLWRNORM ";
-  if (event_mask & EPOLLWRBAND) s += "EPOLLWRBAND ";
-  if (event_mask & EPOLLMSG) s += "EPOLLMSG ";
-  if (event_mask & EPOLLERR) s += "EPOLLERR ";
-  if (event_mask & EPOLLHUP) s += "EPOLLHUP ";
-  if (event_mask & EPOLLONESHOT) s += "EPOLLONESHOT ";
-  if (event_mask & EPOLLET) s += "EPOLLET ";
-  return s;
-}
-
-void SimpleEpollServer::LogStateOnCrash() {
-  EPOLL_LOG(ERROR)
-      << "-------------------Epoll Server-------------------------";
-  EPOLL_LOG(ERROR) << "Epoll server " << this << " polling on fd " << epoll_fd_;
-  EPOLL_LOG(ERROR) << "timeout_in_us_: " << timeout_in_us_;
-
-  // Log sessions with alarms.
-  EPOLL_LOG(ERROR) << alarm_map_.size() << " alarms registered.";
-  for (auto it = alarm_map_.begin(); it != alarm_map_.end(); ++it) {
-    const bool skipped =
-        alarms_reregistered_and_should_be_skipped_.find(it->second) !=
-        alarms_reregistered_and_should_be_skipped_.end();
-    EPOLL_LOG(ERROR) << "Alarm " << it->second << " registered at time "
-                     << it->first << " and should be skipped = " << skipped;
-  }
-
-  EPOLL_LOG(ERROR) << cb_map_.size() << " fd callbacks registered.";
-  for (auto it = cb_map_.begin(); it != cb_map_.end(); ++it) {
-    EPOLL_LOG(ERROR) << "fd: " << it->fd << " with mask " << it->event_mask
-                     << " registered with cb: " << it->cb;
-  }
-  EPOLL_LOG(ERROR)
-      << "-------------------/Epoll Server------------------------";
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-void SimpleEpollServer::DelFD(int fd) const {
-  struct epoll_event ee;
-  memset(&ee, 0, sizeof(ee));
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordFDMaskEvent(fd, 0, "DelFD");
-#endif
-  if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee)) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Epoll set removal error for fd " << fd << ": "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-}
-
-////////////////////////////////////////
-
-void SimpleEpollServer::AddFD(int fd, int event_mask) const {
-  struct epoll_event ee;
-  memset(&ee, 0, sizeof(ee));
-  ee.events = event_mask | EPOLLERR | EPOLLHUP;
-  ee.data.fd = fd;
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordFDMaskEvent(fd, ee.events, "AddFD");
-#endif
-  if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ee)) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Epoll set insertion error for fd " << fd << ": "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-}
-
-////////////////////////////////////////
-
-void SimpleEpollServer::ModFD(int fd, int event_mask) const {
-  struct epoll_event ee;
-  memset(&ee, 0, sizeof(ee));
-  ee.events = event_mask | EPOLLERR | EPOLLHUP;
-  ee.data.fd = fd;
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordFDMaskEvent(fd, ee.events, "ModFD");
-#endif
-  EPOLL_VLOG(3) << "modifying fd= " << fd << " "
-                << EventMaskToString(ee.events);
-  if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ee)) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Epoll set modification error for fd " << fd << ": "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-}
-
-////////////////////////////////////////
-
-void SimpleEpollServer::ModifyFD(int fd, int remove_event, int add_event) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() == fd_i) {
-    EPOLL_VLOG(2) << "Didn't find the fd " << fd << "in internal structures";
-    return;
-  }
-
-  if (fd_i->cb != NULL) {
-    int& event_mask = fd_i->event_mask;
-    EPOLL_VLOG(3) << "fd= " << fd
-                  << " event_mask before: " << EventMaskToString(event_mask);
-    event_mask &= ~remove_event;
-    event_mask |= add_event;
-
-    EPOLL_VLOG(3) << " event_mask after: " << EventMaskToString(event_mask);
-
-    ModFD(fd, event_mask);
-
-    fd_i->cb->OnModification(fd, event_mask);
-  }
-}
-
-void SimpleEpollServer::WaitForEventsAndCallHandleEvents(
-    int64_t timeout_in_us, struct epoll_event events[], int events_size) {
-  if (timeout_in_us == 0 || ready_list_.lh_first != NULL) {
-    // If ready list is not empty, then don't sleep at all.
-    timeout_in_us = 0;
-  } else if (timeout_in_us < 0) {
-    EPOLL_LOG(INFO) << "Negative epoll timeout: " << timeout_in_us
-                    << "us; epoll will wait forever for events.";
-    // If timeout_in_us is < 0 we are supposed to Wait forever.  This means we
-    // should set timeout_in_us to -1000 so we will
-    // Wait(-1000/1000) == Wait(-1) == Wait forever.
-    timeout_in_us = -1000;
-  } else {
-    // If timeout is specified, and the ready list is empty.
-    if (timeout_in_us < 1000) {
-      timeout_in_us = 1000;
-    }
-  }
-  const int timeout_in_ms = timeout_in_us / 1000;
-  int64_t expected_wakeup_us = NowInUsec() + timeout_in_us;
-
-  int nfds = epoll_wait_impl(epoll_fd_, events, events_size, timeout_in_ms);
-  EPOLL_VLOG(3) << "nfds=" << nfds;
-
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordEpollWaitEvent(timeout_in_ms, nfds);
-#endif
-
-  // If you're wondering why the NowInUsec() is recorded here, the answer is
-  // simple: If we did it before the epoll_wait_impl, then the max error for
-  // the ApproximateNowInUs() call would be as large as the maximum length of
-  // epoll_wait, which can be arbitrarily long. Since this would make
-  // ApproximateNowInUs() worthless, we instead record the time -after- we've
-  // done epoll_wait, which guarantees that the maximum error is the amount of
-  // time it takes to process all the events generated by epoll_wait.
-  recorded_now_in_us_ = NowInUsec();
-
-  if (timeout_in_us > 0) {
-    int64_t delta = NowInUsec() - expected_wakeup_us;
-    last_delay_in_usec_ = delta > 0 ? delta : 0;
-  } else {
-    // timeout_in_us < 0 means we waited forever until an event;
-    // timeout_in_us == 0 means there was no kernel delay to track.
-    last_delay_in_usec_ = 0;
-  }
-
-  if (nfds > 0) {
-    for (int i = 0; i < nfds; ++i) {
-      int event_mask = events[i].events;
-      int fd = events[i].data.fd;
-      HandleEvent(fd, event_mask);
-    }
-  } else if (nfds < 0) {
-    // Catch interrupted syscall and just ignore it and move on.
-    if (errno != EINTR && errno != 0) {
-      int saved_errno = errno;
-      char buf[kErrorBufferSize];
-      EPOLL_LOG(FATAL) << "Error " << saved_errno << " in epoll_wait: "
-                       << strerror_r(saved_errno, buf, sizeof(buf));
-    }
-  }
-
-  // Now run through the ready list.
-  if (ready_list_.lh_first) {
-    CallReadyListCallbacks();
-  }
-}
-
-void SimpleEpollServer::CallReadyListCallbacks() {
-  // Check pre-conditions.
-  DCHECK(tmp_list_.lh_first == NULL);
-  // Swap out the ready_list_ into the tmp_list_ before traversing the list to
-  // enable SetFDReady() to just push new items into the ready_list_.
-  std::swap(ready_list_.lh_first, tmp_list_.lh_first);
-  if (tmp_list_.lh_first) {
-    tmp_list_.lh_first->entry.le_prev = &tmp_list_.lh_first;
-    EpollEvent event(0);
-    while (tmp_list_.lh_first != NULL) {
-      DCHECK_GT(ready_list_size_, 0);
-      CBAndEventMask* cb_and_mask = tmp_list_.lh_first;
-      RemoveFromReadyList(*cb_and_mask);
-
-      event.out_ready_mask = 0;
-      event.in_events =
-          cb_and_mask->events_asserted | cb_and_mask->events_to_fake;
-      // TODO(fenix): get rid of the two separate fields in cb_and_mask.
-      cb_and_mask->events_asserted = 0;
-      cb_and_mask->events_to_fake = 0;
-      {
-        // OnEvent() may call UnRegister, so we set in_use, here. Any
-        // UnRegister call will now simply set the cb to NULL instead of
-        // invalidating the cb_and_mask object (by deleting the object in the
-        // map to which cb_and_mask refers)
-        AutoReset<bool> in_use_guard(&(cb_and_mask->in_use), true);
-        cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event);
-      }
-
-      // Since OnEvent may have called UnregisterFD, we must check here that
-      // the callback is still valid. If it isn't, then UnregisterFD *was*
-      // called, and we should now get rid of the object.
-      if (cb_and_mask->cb == NULL) {
-        cb_map_.erase(*cb_and_mask);
-      } else if (event.out_ready_mask != 0) {
-        cb_and_mask->events_to_fake = event.out_ready_mask;
-        AddToReadyList(cb_and_mask);
-      }
-    }
-  }
-  DCHECK(tmp_list_.lh_first == NULL);
-}
-
-void SimpleEpollServer::CallAndReregisterAlarmEvents() {
-  int64_t now_in_us = recorded_now_in_us_;
-  DCHECK_NE(0, recorded_now_in_us_);
-
-  TimeToAlarmCBMap::iterator erase_it;
-
-  // execute alarms.
-  for (auto i = alarm_map_.begin(); i != alarm_map_.end();) {
-    if (i->first > now_in_us) {
-      break;
-    }
-    AlarmCB* cb = i->second;
-    // Execute the OnAlarm() only if we did not register
-    // it in this loop itself.
-    const bool added_in_this_round =
-        alarms_reregistered_and_should_be_skipped_.find(cb) !=
-        alarms_reregistered_and_should_be_skipped_.end();
-    if (added_in_this_round) {
-      ++i;
-      continue;
-    }
-    all_alarms_.erase(cb);
-    const int64_t new_timeout_time_in_us = cb->OnAlarm();
-
-    erase_it = i;
-    ++i;
-    alarm_map_.erase(erase_it);
-
-    if (new_timeout_time_in_us > 0) {
-      // We add to hash_set only if the new timeout is <= now_in_us.
-      // if timeout is > now_in_us then we have no fear that this alarm
-      // can be reexecuted in this loop, and hence we do not need to
-      // worry about a recursive loop.
-      EPOLL_DVLOG(3) << "Reregistering alarm "
-                     << " " << cb << " " << new_timeout_time_in_us << " "
-                     << now_in_us;
-      if (new_timeout_time_in_us <= now_in_us) {
-        alarms_reregistered_and_should_be_skipped_.insert(cb);
-      }
-      RegisterAlarm(new_timeout_time_in_us, cb);
-    }
-  }
-  alarms_reregistered_and_should_be_skipped_.clear();
-}
-
-EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) {}
-
-EpollAlarm::~EpollAlarm() { UnregisterIfRegistered(); }
-
-int64_t EpollAlarm::OnAlarm() {
-  registered_ = false;
-  return 0;
-}
-
-void EpollAlarm::OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                                SimpleEpollServer* eps) {
-  DCHECK_EQ(false, registered_);
-
-  token_ = token;
-  eps_ = eps;
-  registered_ = true;
-}
-
-void EpollAlarm::OnUnregistration() { registered_ = false; }
-
-void EpollAlarm::OnShutdown(SimpleEpollServer* /*eps*/) {
-  registered_ = false;
-  eps_ = NULL;
-}
-
-// If the alarm was registered, unregister it.
-void EpollAlarm::UnregisterIfRegistered() {
-  if (!registered_) {
-    return;
-  }
-
-  eps_->UnregisterAlarm(token_);
-}
-
-void EpollAlarm::ReregisterAlarm(int64_t timeout_time_in_us) {
-  DCHECK(registered_);
-  token_ = eps_->ReregisterAlarm(token_, timeout_time_in_us);
-}
-
-}  // namespace epoll_server
diff --git a/epoll_server/simple_epoll_server.h b/epoll_server/simple_epoll_server.h
deleted file mode 100644
index 85b3a08..0000000
--- a/epoll_server/simple_epoll_server.h
+++ /dev/null
@@ -1,1052 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_EPOLL_SERVER_H_
-#define QUICHE_EPOLL_SERVER_H_
-
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-// #define EPOLL_SERVER_EVENT_TRACING 1
-//
-// Defining EPOLL_SERVER_EVENT_TRACING
-// causes code to exist which didn't before.
-// This code tracks each event generated by the epollserver,
-// as well as providing a per-fd-registered summary of
-// events. Note that enabling this code vastly slows
-// down operations, and uses substantially more
-// memory. For these reasons, it should only be enabled by developers doing
-// development at their workstations.
-//
-// A structure called 'EventRecorder' will exist when
-// the macro is defined. See the EventRecorder class interface
-// within the SimpleEpollServer class for more details.
-#ifdef EPOLL_SERVER_EVENT_TRACING
-#include <ostream>
-#endif
-
-#include <sys/epoll.h>
-
-#include "epoll_server/platform/api/epoll_export.h"
-#include "epoll_server/platform/api/epoll_logging.h"
-
-namespace epoll_server {
-
-class SimpleEpollServer;
-class EpollAlarmCallbackInterface;
-class ReadPipeCallback;
-
-struct EpollEvent {
-  EpollEvent(int events) : in_events(events), out_ready_mask(0) {}
-
-  int in_events;       // incoming events
-  int out_ready_mask;  // the new event mask for ready list (0 means don't
-                       // get on the ready list). This field is always
-                       // initialized to 0 when the event is passed to
-                       // OnEvent.
-};
-
-// Callbacks which go into SimpleEpollServers are expected to derive from this
-// class.
-class EpollCallbackInterface {
- public:
-  // Summary:
-  //   Called when the callback is registered into a SimpleEpollServer.
-  // Args:
-  //   eps - the poll server into which this callback was registered
-  //   fd - the file descriptor which was registered
-  //   event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc)
-  //                which was registered (and will initially be used
-  //                in the epoll() calls)
-  virtual void OnRegistration(SimpleEpollServer* eps, int fd,
-                              int event_mask) = 0;
-
-  // Summary:
-  //   Called when the event_mask is modified (for a file-descriptor)
-  // Args:
-  //   fd - the file descriptor which was registered
-  //   event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc)
-  //                which was is now curren (and will be used
-  //                in subsequent epoll() calls)
-  virtual void OnModification(int fd, int event_mask) = 0;
-
-  // Summary:
-  //   Called whenever an event occurs on the file-descriptor.
-  //   This is where the bulk of processing is expected to occur.
-  // Args:
-  //   fd - the file descriptor which was registered
-  //   event - a struct that contains the event mask (composed of EPOLLIN,
-  //           EPOLLOUT, etc), a flag that indicates whether this is a true
-  //           epoll_wait event vs one from the ready list, and an output
-  //           parameter for OnEvent to inform the SimpleEpollServer whether to
-  //           put this fd on the ready list.
-  virtual void OnEvent(int fd, EpollEvent* event) = 0;
-
-  // Summary:
-  //   Called when the file-descriptor is unregistered from the poll-server.
-  // Args:
-  //   fd - the file descriptor which was registered, and of this call, is now
-  //        unregistered.
-  //   replaced - If true, this callback is being replaced by another, otherwise
-  //              it is simply being removed.
-  virtual void OnUnregistration(int fd, bool replaced) = 0;
-
-  // Summary:
-  //   Called when the epoll server is shutting down.  This is different from
-  //   OnUnregistration because the subclass may want to clean up memory.
-  //   This is called in leiu of OnUnregistration.
-  // Args:
-  //  fd - the file descriptor which was registered.
-  virtual void OnShutdown(SimpleEpollServer* eps, int fd) = 0;
-
-  // Summary:
-  //   Returns a name describing the class for use in debug/error reporting.
-  virtual std::string Name() const = 0;
-
-  virtual ~EpollCallbackInterface() {}
-
- protected:
-  EpollCallbackInterface() {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-class EPOLL_EXPORT_PRIVATE SimpleEpollServer {
- public:
-  typedef EpollAlarmCallbackInterface AlarmCB;
-  typedef EpollCallbackInterface CB;
-
-  typedef std::multimap<int64_t, AlarmCB*> TimeToAlarmCBMap;
-  typedef TimeToAlarmCBMap::iterator AlarmRegToken;
-
-  // Summary:
-  //   Constructor:
-  //    By default, we don't wait any amount of time for events, and
-  //    we suggest to the epoll-system that we're going to use on-the-order
-  //    of 1024 FDs.
-  SimpleEpollServer();
-
-  SimpleEpollServer(const SimpleEpollServer&) = delete;
-  SimpleEpollServer operator=(const SimpleEpollServer&) = delete;
-
-  ////////////////////////////////////////
-
-  // Destructor
-  virtual ~SimpleEpollServer();
-
-  ////////////////////////////////////////
-
-  // Summary
-  //   Register a callback to be called whenever an event contained
-  //   in the set of events included in event_mask occurs on the
-  //   file-descriptor 'fd'
-  //
-  //   Note that only one callback is allowed to be registered for
-  //   any specific file-decriptor.
-  //
-  //   If a callback is registered for a file-descriptor which has already
-  //   been registered, then the previous callback is unregistered with
-  //   the 'replaced' flag set to true. I.e. the previous callback's
-  //   OnUnregistration() function is called like so:
-  //      OnUnregistration(fd, true);
-  //
-  //  The epoll server does NOT take on ownership of the callback: the callback
-  //  creator is responsible for managing that memory.
-  //
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  //   event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating
-  //                the events for which the callback would like to be
-  //                called.
-  virtual void RegisterFD(int fd, CB* cb, int event_mask);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   A shortcut for RegisterFD which sets things up such that the
-  //   callback is called when 'fd' is available for writing.
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  virtual void RegisterFDForWrite(int fd, CB* cb);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   A shortcut for RegisterFD which sets things up such that the
-  //   callback is called when 'fd' is available for reading or writing.
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  virtual void RegisterFDForReadWrite(int fd, CB* cb);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   A shortcut for RegisterFD which sets things up such that the
-  //   callback is called when 'fd' is available for reading.
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  virtual void RegisterFDForRead(int fd, CB* cb);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Removes the FD and the associated callback from the pollserver.
-  //   If the callback is registered with other FDs, they will continue
-  //   to be processed using the callback without modification.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the file-descriptor which should no-longer be monitored.
-  virtual void UnregisterFD(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor, replacing
-  //   the old event_mask with the new one specified here.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  //   event_mask - the new event mask.
-  virtual void ModifyCallback(int fd, int event_mask);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   no longer request events when 'fd' is readable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StopRead(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   request events when 'fd' is readable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StartRead(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   no longer request events when 'fd' is writable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StopWrite(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   request events when 'fd' is writable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StartWrite(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Looks up the callback associated with the file-descriptor 'fd'.
-  //   If a callback is associated with this file-descriptor, then
-  //   it's OnEvent() method is called with the file-descriptor 'fd',
-  //   and event_mask 'event_mask'
-  //
-  //   If no callback is registered for this file-descriptor, nothing
-  //   will happen as a result of this call.
-  //
-  //   This function is used internally by the SimpleEpollServer, but is
-  //   available publicly so that events might be 'faked'. Calling
-  //   this function with an fd and event_mask is equivalent (as far
-  //   as the callback is concerned) to having a real event generated
-  //   by epoll (except, of course, that read(), etc won't necessarily
-  //   be able to read anything)
-  // Args:
-  //   fd - the file-descriptor on which an event has occurred.
-  //   event_mask - a bitmask representing the events which have occurred
-  //                on/for this fd. This bitmask is composed of
-  //                POLLIN, POLLOUT, etc.
-  //
-  void HandleEvent(int fd, int event_mask);
-
-  // Summary:
-  //   Call this when you want the pollserver to
-  //   wait for events and execute the callbacks associated with
-  //   the file-descriptors on which those events have occurred.
-  //   Depending on the value of timeout_in_us_, this may or may
-  //   not return immediately. Please reference the set_timeout()
-  //   function for the specific behaviour.
-  virtual void WaitForEventsAndExecuteCallbacks();
-
-  // Summary:
-  //   When an fd is registered to use edge trigger notification, the ready
-  //   list can be used to simulate level trigger semantics. Edge trigger
-  //   registration doesn't send an initial event, and only rising edge (going
-  //   from blocked to unblocked) events are sent. A callback can put itself on
-  //   the ready list by calling SetFDReady() after calling RegisterFD(). The
-  //   OnEvent method of all callbacks associated with the fds on the ready
-  //   list will be called immediately after processing the events returned by
-  //   epoll_wait(). The fd is removed from the ready list before the
-  //   callback's OnEvent() method is invoked. To stay on the ready list, the
-  //   OnEvent() (or some function in that call chain) must call SetFDReady
-  //   again. When a fd is unregistered using UnregisterFD(), the fd is
-  //   automatically removed from the ready list.
-  //
-  //   When the callback for a edge triggered fd hits the falling edge (about
-  //   to block, either because of it got an EAGAIN, or had a short read/write
-  //   operation), it should remove itself from the ready list using
-  //   SetFDNotReady() (since OnEvent cannot distinguish between invocation
-  //   from the ready list vs from a normal epoll event). All four ready list
-  //   methods are safe to be called  within the context of the callbacks.
-  //
-  //   Since the ready list invokes EpollCallbackInterface::OnEvent, only fds
-  //   that are registered with the SimpleEpollServer will be put on the ready
-  //   list. SetFDReady() and SetFDNotReady() will do nothing if the
-  //   SimpleEpollServer doesn't know about the fd passed in.
-  //
-  //   Since the ready list cannot reliably determine proper set of events
-  //   which should be sent to the callback, SetFDReady() requests the caller
-  //   to provide the ready list with the event mask, which will be used later
-  //   when OnEvent() is invoked by the ready list. Hence, the event_mask
-  //   passedto SetFDReady() does not affect the actual epoll registration of
-  //   the fd with the kernel. If a fd is already put on the ready list, and
-  //   SetFDReady() is called again for that fd with a different event_mask,
-  //   the event_mask will be updated.
-  virtual void SetFDReady(int fd, int events_to_fake);
-
-  virtual void SetFDNotReady(int fd);
-
-  // Summary:
-  //   IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as
-  //   debugging tools and for writing unit tests.
-  //   ISFDReady() returns whether a fd is in the ready list.
-  //   ReadyListSize() returns the number of fds on the ready list.
-  //   VerifyReadyList() checks the consistency of internal data structure. It
-  //   will CHECK if it finds an error.
-  virtual bool IsFDReady(int fd) const;
-
-  size_t ReadyListSize() const { return ready_list_size_; }
-
-  void VerifyReadyList() const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Registers an alarm 'ac' to go off at time 'timeout_time_in_us'.
-  //   If the callback returns a positive number from its OnAlarm() function,
-  //   then the callback will be re-registered at that time, else the alarm
-  //   owner is responsible for freeing up memory.
-  //
-  //   Important: A give AlarmCB* can not be registered again if it is already
-  //    registered. If a user wants to register a callback again it should first
-  //    unregister the previous callback before calling RegisterAlarm again.
-  // Args:
-  //   timeout_time_in_us - the absolute time at which the alarm should go off
-  //   ac - the alarm which will be called.
-  virtual void RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac);
-
-  // Summary:
-  //   Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() +
-  //   delta_in_us). While this is somewhat less accurate (see the description
-  //   for ApproximateNowInUs() to see how 'approximate'), the error is never
-  //   worse than the amount of time it takes to process all events in one
-  //   WaitForEvents.  As with 'RegisterAlarm()', if the callback returns a
-  //   positive number from its OnAlarm() function, then the callback will be
-  //   re-registered at that time, else the alarm owner is responsible for
-  //   freeing up memory.
-  //   Note that this function is purely a convienence. The
-  //   same thing may be accomplished by using RegisterAlarm with
-  //   ApproximateNowInUs() directly.
-  //
-  //   Important: A give AlarmCB* can not be registered again if it is already
-  //    registered. If a user wants to register a callback again it should first
-  //    unregister the previous callback before calling RegisterAlarm again.
-  // Args:
-  //   delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at
-  //                 which point the alarm should go off.
-  //   ac - the alarm which will be called.
-  void RegisterAlarmApproximateDelta(int64_t delta_in_us, AlarmCB* ac) {
-    RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac);
-  }
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Unregister  the alarm referred to by iterator_token; Callers should
-  //   be warned that a token may have become already invalid when OnAlarm()
-  //   is called, was unregistered, or OnShutdown was called on that alarm.
-  // Args:
-  //    iterator_token - iterator to the alarm callback to unregister.
-  virtual void UnregisterAlarm(
-      const SimpleEpollServer::AlarmRegToken& iterator_token);
-
-  virtual SimpleEpollServer::AlarmRegToken ReregisterAlarm(
-      SimpleEpollServer::AlarmRegToken iterator_token,
-      int64_t timeout_time_in_us);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   returns the number of file-descriptors registered in this
-  //   SimpleEpollServer.
-  // Returns:
-  //   number of FDs registered (discounting the internal pipe used for Wake)
-  virtual int NumFDsRegistered() const;
-
-  // Summary:
-  //   Force the epoll server to wake up (by writing to an internal pipe).
-  virtual void Wake();
-
-  // Summary:
-  //   Wrapper around WallTimer's NowInUsec.  We do this so that we can test
-  //   SimpleEpollServer without using the system clock (and can avoid the
-  //   flakiness that would ensue)
-  // Returns:
-  //   the current time as number of microseconds since the Unix epoch.
-  virtual int64_t NowInUsec() const;
-
-  // Summary:
-  //   Since calling NowInUsec() many thousands of times per
-  //   WaitForEventsAndExecuteCallbacks function call is, to say the least,
-  //   inefficient, we allow users to use an approximate time instead. The
-  //   time returned from this function is as accurate as NowInUsec() when
-  //   WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's
-  //   callstack.
-  //   However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then
-  //   this function returns the time at which the
-  //   WaitForEventsAndExecuteCallbacks function started to process events or
-  //   alarms.
-  //
-  //   Essentially, this function makes available a fast and mostly accurate
-  //   mechanism for getting the time for any function handling an event or
-  //   alarm. When functions which are not handling callbacks or alarms call
-  //   this function, they get the slow and "absolutely" accurate time.
-  //
-  //   Users should be encouraged to use this function.
-  // Returns:
-  //   the "approximate" current time as number of microseconds since the Unix
-  //   epoch.
-  virtual int64_t ApproximateNowInUsec() const;
-
-  static std::string EventMaskToString(int event_mask);
-
-  // Summary:
-  //   Logs the state of the epoll server with EPOLL_LOG(ERROR).
-  void LogStateOnCrash();
-
-  // Summary:
-  //   Set the timeout to the value specified.
-  //   If the timeout is set to a negative number,
-  //      WaitForEventsAndExecuteCallbacks() will only return when an event has
-  //      occurred
-  //   If the timeout is set to zero,
-  //      WaitForEventsAndExecuteCallbacks() will return immediately
-  //   If the timeout is set to a positive number,
-  //      WaitForEventsAndExecuteCallbacks() will return when an event has
-  //      occurred, or when timeout_in_us microseconds has elapsed, whichever
-  //      is first.
-  //  Args:
-  //    timeout_in_us - value specified depending on behaviour desired.
-  //                    See above.
-  void set_timeout_in_us(int64_t timeout_in_us) {
-    timeout_in_us_ = timeout_in_us;
-  }
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Accessor for the current value of timeout_in_us.
-  int timeout_in_us_for_test() const { return timeout_in_us_; }
-
-  // Summary:
-  // Returns true when the SimpleEpollServer() is being destroyed.
-  bool in_shutdown() const { return in_shutdown_; }
-  bool ShutdownCalled() const { return in_shutdown(); }
-
-  // Compatibility stub.
-  void Shutdown() {}
-
-  // Summary:
-  //   A function for implementing the ready list. It invokes OnEvent for each
-  //   of the fd in the ready list, and takes care of adding them back to the
-  //   ready list if the callback requests it (by checking that out_ready_mask
-  //   is non-zero).
-  void CallReadyListCallbacks();
-
-  int64_t LastDelayInUsec() const { return last_delay_in_usec_; }
-
- protected:
-  virtual void SetNonblocking(int fd);
-
-  // This exists here so that we can override this function in unittests
-  // in order to make effective mock SimpleEpollServer objects.
-  virtual int epoll_wait_impl(int epfd, struct epoll_event* events,
-                              int max_events, int timeout_in_ms);
-
-  // this struct is used internally, and is never used by anything external
-  // to this class. Some of its members are declared mutable to get around the
-  // restriction imposed by hash_set. Since hash_set knows nothing about the
-  // objects it stores, it has to assume that every bit of the object is used
-  // in the hash function and equal_to comparison. Thus hash_set::iterator is a
-  // const iterator. In this case, the only thing that must stay constant is
-  // fd. Everything else are just along for the ride and changing them doesn't
-  // compromise the hash_set integrity.
-  struct CBAndEventMask {
-    CBAndEventMask()
-        : cb(NULL),
-          fd(-1),
-          event_mask(0),
-          events_asserted(0),
-          events_to_fake(0),
-          in_use(false) {
-      entry.le_next = NULL;
-      entry.le_prev = NULL;
-    }
-
-    CBAndEventMask(EpollCallbackInterface* cb, int event_mask, int fd)
-        : cb(cb),
-          fd(fd),
-          event_mask(event_mask),
-          events_asserted(0),
-          events_to_fake(0),
-          in_use(false) {
-      entry.le_next = NULL;
-      entry.le_prev = NULL;
-    }
-
-    // Required operator for hash_set. Normally operator== should be a free
-    // standing function. However, since CBAndEventMask is a protected type and
-    // it will never be a base class, it makes no difference.
-    bool operator==(const CBAndEventMask& cb_and_mask) const {
-      return fd == cb_and_mask.fd;
-    }
-    // A callback. If the fd is unregistered inside the callchain of OnEvent,
-    // the cb will be set to NULL.
-    mutable EpollCallbackInterface* cb;
-
-    mutable LIST_ENTRY(CBAndEventMask) entry;
-    // file descriptor registered with the epoll server.
-    int fd;
-    // the current event_mask registered for this callback.
-    mutable int event_mask;
-    // the event_mask that was returned by epoll
-    mutable int events_asserted;
-    // the event_mask for the ready list to use to call OnEvent.
-    mutable int events_to_fake;
-    // toggle around calls to OnEvent to tell UnregisterFD to not erase the
-    // iterator because HandleEvent is using it.
-    mutable bool in_use;
-  };
-
-  // Custom hash function to be used by hash_set.
-  struct CBAndEventMaskHash {
-    size_t operator()(const CBAndEventMask& cb_and_eventmask) const {
-      return static_cast<size_t>(cb_and_eventmask.fd);
-    }
-  };
-
-  using FDToCBMap = std::unordered_set<CBAndEventMask, CBAndEventMaskHash>;
-
-  // the following four functions are OS-specific, and are likely
-  // to be changed in a subclass if the poll/select method is changed
-  // from epoll.
-
-  // Summary:
-  //   Deletes a file-descriptor from the set of FDs that should be
-  //   monitored with epoll.
-  //   Note that this only deals with modifying data relating -directly-
-  //   with the epoll call-- it does not modify any data within the
-  //   epoll_server.
-  // Args:
-  //   fd - the file descriptor to-be-removed from the monitoring set
-  virtual void DelFD(int fd) const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Adds a file-descriptor to the set of FDs that should be
-  //   monitored with epoll.
-  //   Note that this only deals with modifying data relating -directly-
-  //   with the epoll call.
-  // Args:
-  //   fd - the file descriptor to-be-added to the monitoring set
-  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
-  //                 OR'd together) which will be associated with this
-  //                 FD initially.
-  virtual void AddFD(int fd, int event_mask) const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies a file-descriptor in the set of FDs that should be
-  //   monitored with epoll.
-  //   Note that this only deals with modifying data relating -directly-
-  //   with the epoll call.
-  // Args:
-  //   fd - the file descriptor to-be-added to the monitoring set
-  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
-  //                 OR'd together) which will be associated with this
-  //                 FD after this call.
-  virtual void ModFD(int fd, int event_mask) const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modified the event mask associated with an FD in the set of
-  //   data needed by epoll.
-  //   Events are removed before they are added, thus, if ~0 is put
-  //   in 'remove_event', whatever is put in 'add_event' will be
-  //   the new event mask.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the file descriptor whose event mask is to be modified
-  //   remove_event - the events which are to be removed from the current
-  //                  event_mask
-  //   add_event - the events which are to be added to the current event_mask
-  //
-  //
-  virtual void ModifyFD(int fd, int remove_event, int add_event);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Waits for events, and calls HandleEvents() for each
-  //   fd, event pair discovered to possibly have an event.
-  //   Note that a callback (B) may get a spurious event if
-  //   another callback (A) has closed a file-descriptor N, and
-  //   the callback (B) has a newly opened file-descriptor, which
-  //   also happens to be N.
-  virtual void WaitForEventsAndCallHandleEvents(int64_t timeout_in_us,
-                                                struct epoll_event events[],
-                                                int events_size);
-
-  // Summary:
-  //   An internal function for implementing the ready list. It adds a fd's
-  //   CBAndEventMask to the ready list. If the fd is already on the ready
-  //   list, it is a no-op.
-  void AddToReadyList(CBAndEventMask* cb_and_mask);
-
-  // Summary:
-  //   An internal function for implementing the ready list. It remove a fd's
-  //   CBAndEventMask from the ready list. If the fd is not on the ready list,
-  //   it is a no-op.
-  void RemoveFromReadyList(const CBAndEventMask& cb_and_mask);
-
-  // Summary:
-  // Calls any pending alarms that should go off and reregisters them if they
-  // were recurring.
-  virtual void CallAndReregisterAlarmEvents();
-
-  // The file-descriptor created for epolling
-  int epoll_fd_;
-
-  // The mapping of file-descriptor to CBAndEventMasks
-  FDToCBMap cb_map_;
-
-  // Custom hash function to be used by hash_set.
-  struct AlarmCBHash {
-    size_t operator()(AlarmCB* const& p) const {
-      return reinterpret_cast<size_t>(p);
-    }
-  };
-
-  // TODO(sushantj): Having this hash_set is avoidable. We currently have it
-  // only so that we can enforce stringent checks that a caller can not register
-  // the same alarm twice. One option is to have an implementation in which
-  // this hash_set is used only in the debug mode.
-  using AlarmCBMap = std::unordered_set<AlarmCB*, AlarmCBHash>;
-  AlarmCBMap all_alarms_;
-
-  TimeToAlarmCBMap alarm_map_;
-
-  // The amount of time in microseconds that we'll wait before returning
-  // from the WaitForEventsAndExecuteCallbacks() function.
-  // If this is positive, wait that many microseconds.
-  // If this is negative, wait forever, or for the first event that occurs
-  // If this is zero, never wait for an event.
-  int64_t timeout_in_us_;
-
-  // This is nonzero only after the invocation of epoll_wait_impl within
-  // WaitForEventsAndCallHandleEvents and before the function
-  // WaitForEventsAndExecuteCallbacks returns.  At all other times, this is
-  // zero. This enables us to have relatively accurate time returned from the
-  // ApproximateNowInUs() function. See that function for more details.
-  int64_t recorded_now_in_us_;
-
-  // This is used to implement CallAndReregisterAlarmEvents. This stores
-  // all alarms that were reregistered because OnAlarm() returned a
-  // value > 0 and the time at which they should be executed is less that
-  // the current time.  By storing such alarms in this map we ensure
-  // that while calling CallAndReregisterAlarmEvents we do not call
-  // OnAlarm on any alarm in this set. This ensures that we do not
-  // go in an infinite loop.
-  AlarmCBMap alarms_reregistered_and_should_be_skipped_;
-
-  LIST_HEAD(ReadyList, CBAndEventMask) ready_list_;
-  LIST_HEAD(TmpList, CBAndEventMask) tmp_list_;
-  int ready_list_size_;
-  // TODO(alyssar): make this into something that scales up.
-  static const int events_size_ = 256;
-  struct epoll_event events_[256];
-
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  struct EventRecorder {
-   public:
-    EventRecorder() : num_records_(0), record_threshold_(10000) {}
-
-    ~EventRecorder() { Clear(); }
-
-    // When a number of events equals the record threshold,
-    // the collected data summary for all FDs will be written
-    // to EPOLL_LOG(INFO). Note that this does not include the
-    // individual events (if you'reinterested in those, you'll
-    // have to get at them programmatically).
-    // After any such flushing to EPOLL_LOG(INFO) all events will
-    // be cleared.
-    // Note that the definition of an 'event' is a bit 'hazy',
-    // as it includes the 'Unregistration' event, and perhaps
-    // others.
-    void set_record_threshold(int64_t new_threshold) {
-      record_threshold_ = new_threshold;
-    }
-
-    void Clear() {
-      for (int i = 0; i < debug_events_.size(); ++i) {
-        delete debug_events_[i];
-      }
-      debug_events_.clear();
-      unregistered_fds_.clear();
-      event_counts_.clear();
-    }
-
-    void MaybeRecordAndClear() {
-      ++num_records_;
-      if ((num_records_ > record_threshold_) && (record_threshold_ > 0)) {
-        EPOLL_LOG(INFO) << "\n" << *this;
-        num_records_ = 0;
-        Clear();
-      }
-    }
-
-    void RecordFDMaskEvent(int fd, int mask, const char* function) {
-      FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function);
-      debug_events_.push_back(fdmo);
-      MaybeRecordAndClear();
-    }
-
-    void RecordEpollWaitEvent(int timeout_in_ms, int num_events_generated) {
-      EpollWaitOutput* ewo =
-          new EpollWaitOutput(timeout_in_ms, num_events_generated);
-      debug_events_.push_back(ewo);
-      MaybeRecordAndClear();
-    }
-
-    void RecordEpollEvent(int fd, int event_mask) {
-      Events& events_for_fd = event_counts_[fd];
-      events_for_fd.AssignFromMask(event_mask);
-      MaybeRecordAndClear();
-    }
-
-    friend ostream& operator<<(ostream& os, const EventRecorder& er) {
-      for (int i = 0; i < er.unregistered_fds_.size(); ++i) {
-        os << "fd: " << er.unregistered_fds_[i] << "\n";
-        os << er.unregistered_fds_[i];
-      }
-      for (EventCountsMap::const_iterator i = er.event_counts_.begin();
-           i != er.event_counts_.end(); ++i) {
-        os << "fd: " << i->first << "\n";
-        os << i->second;
-      }
-      for (int i = 0; i < er.debug_events_.size(); ++i) {
-        os << *(er.debug_events_[i]) << "\n";
-      }
-      return os;
-    }
-
-    void RecordUnregistration(int fd) {
-      EventCountsMap::iterator i = event_counts_.find(fd);
-      if (i != event_counts_.end()) {
-        unregistered_fds_.push_back(i->second);
-        event_counts_.erase(i);
-      }
-      MaybeRecordAndClear();
-    }
-
-   protected:
-    class DebugOutput {
-     public:
-      friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) {
-        debug_output.OutputToStream(os);
-        return os;
-      }
-      virtual void OutputToStream(ostream* os) const = 0;
-      virtual ~DebugOutput() {}
-    };
-
-    class FDMaskOutput : public DebugOutput {
-     public:
-      FDMaskOutput(int fd, int mask, const char* function)
-          : fd_(fd), mask_(mask), function_(function) {}
-      virtual void OutputToStream(ostream* os) const {
-        (*os) << "func: " << function_ << "\tfd: " << fd_;
-        if (mask_ != 0) {
-          (*os) << "\tmask: " << EventMaskToString(mask_);
-        }
-      }
-      int fd_;
-      int mask_;
-      const char* function_;
-    };
-
-    class EpollWaitOutput : public DebugOutput {
-     public:
-      EpollWaitOutput(int timeout_in_ms, int num_events_generated)
-          : timeout_in_ms_(timeout_in_ms),
-            num_events_generated_(num_events_generated) {}
-      virtual void OutputToStream(ostream* os) const {
-        (*os) << "timeout_in_ms: " << timeout_in_ms_
-              << "\tnum_events_generated: " << num_events_generated_;
-      }
-
-     protected:
-      int timeout_in_ms_;
-      int num_events_generated_;
-    };
-
-    struct Events {
-      Events()
-          : epoll_in(0),
-            epoll_pri(0),
-            epoll_out(0),
-            epoll_rdnorm(0),
-            epoll_rdband(0),
-            epoll_wrnorm(0),
-            epoll_wrband(0),
-            epoll_msg(0),
-            epoll_err(0),
-            epoll_hup(0),
-            epoll_oneshot(0),
-            epoll_et(0) {}
-
-      void AssignFromMask(int event_mask) {
-        if (event_mask & EPOLLIN) ++epoll_in;
-        if (event_mask & EPOLLPRI) ++epoll_pri;
-        if (event_mask & EPOLLOUT) ++epoll_out;
-        if (event_mask & EPOLLRDNORM) ++epoll_rdnorm;
-        if (event_mask & EPOLLRDBAND) ++epoll_rdband;
-        if (event_mask & EPOLLWRNORM) ++epoll_wrnorm;
-        if (event_mask & EPOLLWRBAND) ++epoll_wrband;
-        if (event_mask & EPOLLMSG) ++epoll_msg;
-        if (event_mask & EPOLLERR) ++epoll_err;
-        if (event_mask & EPOLLHUP) ++epoll_hup;
-        if (event_mask & EPOLLONESHOT) ++epoll_oneshot;
-        if (event_mask & EPOLLET) ++epoll_et;
-      }
-
-      friend ostream& operator<<(ostream& os, const Events& ev) {
-        if (ev.epoll_in) {
-          os << "\t      EPOLLIN: " << ev.epoll_in << "\n";
-        }
-        if (ev.epoll_pri) {
-          os << "\t     EPOLLPRI: " << ev.epoll_pri << "\n";
-        }
-        if (ev.epoll_out) {
-          os << "\t     EPOLLOUT: " << ev.epoll_out << "\n";
-        }
-        if (ev.epoll_rdnorm) {
-          os << "\t  EPOLLRDNORM: " << ev.epoll_rdnorm << "\n";
-        }
-        if (ev.epoll_rdband) {
-          os << "\t  EPOLLRDBAND: " << ev.epoll_rdband << "\n";
-        }
-        if (ev.epoll_wrnorm) {
-          os << "\t  EPOLLWRNORM: " << ev.epoll_wrnorm << "\n";
-        }
-        if (ev.epoll_wrband) {
-          os << "\t  EPOLLWRBAND: " << ev.epoll_wrband << "\n";
-        }
-        if (ev.epoll_msg) {
-          os << "\t     EPOLLMSG: " << ev.epoll_msg << "\n";
-        }
-        if (ev.epoll_err) {
-          os << "\t     EPOLLERR: " << ev.epoll_err << "\n";
-        }
-        if (ev.epoll_hup) {
-          os << "\t     EPOLLHUP: " << ev.epoll_hup << "\n";
-        }
-        if (ev.epoll_oneshot) {
-          os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n";
-        }
-        if (ev.epoll_et) {
-          os << "\t      EPOLLET: " << ev.epoll_et << "\n";
-        }
-        return os;
-      }
-
-      unsigned int epoll_in;
-      unsigned int epoll_pri;
-      unsigned int epoll_out;
-      unsigned int epoll_rdnorm;
-      unsigned int epoll_rdband;
-      unsigned int epoll_wrnorm;
-      unsigned int epoll_wrband;
-      unsigned int epoll_msg;
-      unsigned int epoll_err;
-      unsigned int epoll_hup;
-      unsigned int epoll_oneshot;
-      unsigned int epoll_et;
-    };
-
-    std::vector<DebugOutput*> debug_events_;
-    std::vector<Events> unregistered_fds_;
-    using EventCountsMap = std::unordered_map<int, Events>;
-    EventCountsMap event_counts_;
-    int64_t num_records_;
-    int64_t record_threshold_;
-  };
-
-  void ClearEventRecords() { event_recorder_.Clear(); }
-  void WriteEventRecords(ostream* os) const { (*os) << event_recorder_; }
-
-  mutable EventRecorder event_recorder_;
-
-#endif
-
- private:
-  // Helper functions used in the destructor.
-  void CleanupFDToCBMap();
-  void CleanupTimeToAlarmCBMap();
-
-  // The callback registered to the fds below.  As the purpose of their
-  // registration is to wake the epoll server it just clears the pipe and
-  // returns.
-  std::unique_ptr<ReadPipeCallback> wake_cb_;
-
-  // A pipe owned by the epoll server.  The server will be registered to listen
-  // on read_fd_ and can be woken by Wake() which writes to write_fd_.
-  int read_fd_;
-  int write_fd_;
-
-  // This boolean is checked to see if it is false at the top of the
-  // WaitForEventsAndExecuteCallbacks function. If not, then it either returns
-  // without doing work, and logs to ERROR, or aborts the program (in
-  // DEBUG mode). If so, then it sets the bool to true, does work, and
-  // sets it back to false when done. This catches unwanted recursion.
-  bool in_wait_for_events_and_execute_callbacks_;
-
-  // Returns true when the SimpleEpollServer() is being destroyed.
-  bool in_shutdown_;
-  int64_t last_delay_in_usec_;
-};
-
-class EpollAlarmCallbackInterface {
- public:
-  // Summary:
-  //   Called when an alarm times out. Invalidates an AlarmRegToken.
-  //   WARNING: If a token was saved to refer to an alarm callback, OnAlarm must
-  //   delete it, as the reference is no longer valid.
-  // Returns:
-  //   the unix time (in microseconds) at which this alarm should be signaled
-  //   again, or 0 if the alarm should be removed.
-  virtual int64_t OnAlarm() = 0;
-
-  // Summary:
-  //   Called when the an alarm is registered. Invalidates an AlarmRegToken.
-  // Args:
-  //   token: the iterator to the alarm registered in the alarm map.
-  //   WARNING: this token becomes invalid when the alarm fires, is
-  //   unregistered, or OnShutdown is called on that alarm.
-  //   eps: the epoll server the alarm is registered with.
-  virtual void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                              SimpleEpollServer* eps) = 0;
-
-  // Summary:
-  //   Called when the an alarm is unregistered.
-  //   WARNING: It is not valid to unregister a callback and then use the token
-  //   that was saved to refer to the callback.
-  virtual void OnUnregistration() = 0;
-
-  // Summary:
-  //   Called when the epoll server is shutting down.
-  //   Invalidates the AlarmRegToken that was given when this alarm was
-  //   registered.
-  virtual void OnShutdown(SimpleEpollServer* eps) = 0;
-
-  virtual ~EpollAlarmCallbackInterface() {}
-
- protected:
-  EpollAlarmCallbackInterface() {}
-};
-
-// A simple alarm which unregisters itself on destruction.
-//
-// PLEASE NOTE:
-// Any classes overriding these functions must either call the implementation
-// of the parent class, or is must otherwise make sure that the 'registered_'
-// boolean and the token, 'token_', are updated appropriately.
-class EPOLL_EXPORT_PRIVATE EpollAlarm : public EpollAlarmCallbackInterface {
- public:
-  EpollAlarm();
-
-  ~EpollAlarm() override;
-
-  // Marks the alarm as unregistered and returns 0.  The return value may be
-  // safely ignored by subclasses.
-  int64_t OnAlarm() override;
-
-  // Marks the alarm as registered, and stores the token.
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* eps) override;
-
-  // Marks the alarm as unregistered.
-  void OnUnregistration() override;
-
-  // Marks the alarm as unregistered.
-  void OnShutdown(SimpleEpollServer* eps) override;
-
-  // If the alarm was registered, unregister it.
-  void UnregisterIfRegistered();
-
-  // Reregisters the alarm at specified time.
-  void ReregisterAlarm(int64_t timeout_time_in_us);
-
-  bool registered() const { return registered_; }
-
-  const SimpleEpollServer* eps() const { return eps_; }
-
- private:
-  SimpleEpollServer::AlarmRegToken token_;
-  SimpleEpollServer* eps_;
-  bool registered_;
-};
-
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_H_
diff --git a/epoll_server/simple_epoll_server_test.cc b/epoll_server/simple_epoll_server_test.cc
deleted file mode 100644
index efd4799..0000000
--- a/epoll_server/simple_epoll_server_test.cc
+++ /dev/null
@@ -1,2522 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Epoll tests which determine that the right things happen in the right order.
-// Also lots of testing of individual functions.
-
-#include "epoll_server/simple_epoll_server.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include "epoll_server/fake_simple_epoll_server.h"
-#include "epoll_server/platform/api/epoll_address_test_utils.h"
-#include "epoll_server/platform/api/epoll_expect_bug.h"
-#include "epoll_server/platform/api/epoll_ptr_util.h"
-#include "epoll_server/platform/api/epoll_test.h"
-#include "epoll_server/platform/api/epoll_thread.h"
-#include "epoll_server/platform/api/epoll_time.h"
-
-namespace epoll_server {
-
-namespace test {
-
-namespace {
-
-const int kPageSize = 4096;
-const int kMaxBufLen = 10000;
-
-// These are used to record what is happening.
-enum {
-  CREATION,
-  REGISTRATION,
-  MODIFICATION,
-  EVENT,
-  UNREGISTRATION,
-  SHUTDOWN,
-  DESTRUCTION
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-struct RecordEntry {
-  RecordEntry() : time(0), instance(nullptr), event_type(0), fd(0), data(0) {}
-
-  RecordEntry(int64_t time, void* instance, int event_type, int fd, int data)
-      : time(time),
-        instance(instance),
-        event_type(event_type),
-        fd(fd),
-        data(data) {}
-
-  int64_t time;
-  void* instance;
-  int event_type;
-  int fd;
-  int data;
-
-  bool IsEqual(const RecordEntry *entry) const {
-    bool retval = true;
-
-    if (instance  !=  entry->instance) {
-      retval = false;
-      EPOLL_LOG(INFO) << " instance (" << instance << ") != entry->instance("
-                      << entry->instance << ")";
-    }
-    if (event_type != entry->event_type) {
-      retval = false;
-      EPOLL_LOG(INFO) << " event_type (" << event_type
-                      << ") != entry->event_type(" << entry->event_type << ")";
-    }
-    if ( fd != entry->fd ) {
-      retval = false;
-      EPOLL_LOG(INFO) << " fd (" << fd << ") != entry->fd (" << entry->fd
-                      << ")";
-    }
-    if (data != entry->data) {
-      retval = false;
-      EPOLL_LOG(INFO) << " data (" << data << ") != entry->data(" << entry->data
-                      << ")";
-    }
-    return retval;
-  }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-class Recorder {
- public:
-  void Record(void* instance, int event_type, int fd, int data) {
-    records_.push_back(
-        RecordEntry(WallTimeNowInUsec(), instance, event_type, fd, data));
-  }
-
-  const std::vector<RecordEntry> *records() const { return &records_; }
-
-  bool IsEqual(const Recorder *recorder) const {
-    const std::vector<RecordEntry> *records = recorder->records();
-
-     if (records_.size() != records->size()) {
-       EPOLL_LOG(INFO) << "records_.size() (" << records_.size()
-                       << ") != records->size() (" << records->size() << ")";
-       return false;
-     }
-     for (size_t i = 0; i < std::min(records_.size(), records->size()); ++i) {
-       if (!records_[i].IsEqual(&(*records)[i])) {
-         EPOLL_LOG(INFO) << "entry in index: " << i
-                         << " differs from recorder.";
-         return false;
-       }
-     }
-    return true;
-  }
-
- private:
-  std::vector<RecordEntry> records_;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-class RecordingCB : public EpollCallbackInterface {
- public:
-  RecordingCB() : recorder_(new Recorder()) {
-    recorder_->Record(this, CREATION, 0, 0);
-  }
-
-  ~RecordingCB() override {
-    recorder_->Record(this, DESTRUCTION, 0, 0);
-    delete recorder_;
-  }
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int fd,
-                      int event_mask) override {
-    recorder_->Record(this, REGISTRATION, fd, event_mask);
-  }
-
-  void OnModification(int fd, int event_mask) override {
-    recorder_->Record(this, MODIFICATION, fd, event_mask);
-  }
-
-  void OnEvent(int fd, EpollEvent* event) override {
-    recorder_->Record(this, EVENT, fd, event->in_events);
-    if (event->in_events & EPOLLIN) {
-      const int kLength = 1024;
-      char buf[kLength];
-      int data_read;
-      do {
-        data_read = read(fd, &buf, kLength);
-      } while (data_read > 0);
-    }
-  }
-
-  void OnUnregistration(int fd, bool replaced) override {
-    recorder_->Record(this, UNREGISTRATION, fd, replaced);
-  }
-
-  void OnShutdown(SimpleEpollServer* eps, int fd) override {
-    if (fd >= 0) {
-      eps->UnregisterFD(fd);
-    }
-    recorder_->Record(this, SHUTDOWN, fd, 0);
-  }
-
-  std::string Name() const override { return "RecordingCB"; }
-
-  const Recorder* recorder() const { return recorder_; }
-
- protected:
-  Recorder* recorder_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-// A simple test server that adds some test functions to SimpleEpollServer as
-// well as allowing access to protected functions.
-class EpollTestServer : public SimpleEpollServer {
- public:
-  EpollTestServer() : SimpleEpollServer() {}
-
-  ~EpollTestServer() override {}
-
-  void CheckMapping(int fd, CB* cb) {
-    CBAndEventMask tmp;
-    tmp.fd = fd;
-    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
-    CHECK(fd_i != cb_map_.end());  // Chokes CHECK_NE.
-    CHECK(fd_i->cb == cb);
-  }
-
-  void CheckNotMapped(int fd) {
-    CBAndEventMask tmp;
-    tmp.fd = fd;
-    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
-    CHECK(fd_i == cb_map_.end());  // Chokes CHECK_EQ.
-  }
-
-  void CheckEventMask(int fd, int event_mask) {
-    CBAndEventMask tmp;
-    tmp.fd = fd;
-    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
-    CHECK(cb_map_.end() != fd_i);  // Chokes CHECK_NE.
-    CHECK_EQ(fd_i->event_mask, event_mask);
-  }
-
-  void CheckNotRegistered(int fd) {
-    struct epoll_event ee;
-    memset(&ee, 0, sizeof(ee));
-    // If the fd is registered, the epoll_ctl call would succeed (return 0) and
-    // the CHECK would fail.
-    CHECK(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee));
-  }
-
-  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }
-
-  bool ContainsAlarm(AlarmCB* ac) {
-    return all_alarms_.find(ac) != all_alarms_.end();
-  }
-
-  using SimpleEpollServer::WaitForEventsAndCallHandleEvents;
-};
-
-class EpollFunctionTest : public EpollTest {
- public:
-  EpollFunctionTest()
-      : fd_(-1), fd2_(-1), recorder_(nullptr), cb_(nullptr), ep_(nullptr) {
-  }
-
-  ~EpollFunctionTest() override {
-    delete ep_;
-    delete cb_;
-  }
-
-  void SetUp() override {
-    ep_ = new EpollTestServer();
-    cb_ = new RecordingCB();
-    // recorder_ is safe to use directly as we know it has the same scope as
-    // cb_
-    recorder_ = cb_->recorder();
-
-    int pipe_fds[2];
-    if (pipe(pipe_fds) < 0) {
-      EPOLL_PLOG(FATAL) << "pipe() failed";
-    }
-    fd_ = pipe_fds[0];
-    fd2_ = pipe_fds[1];
-  }
-
-  void TearDown() override {
-    close(fd_);
-    close(fd2_);
-  }
-
-  void DeleteSimpleEpollServer() {
-    delete ep_;
-    ep_ = nullptr;
-  }
-
-  int fd() { return fd_; }
-  int fd2() { return fd2_; }
-  EpollTestServer*  ep() { return ep_; }
-  EpollCallbackInterface* cb() { return cb_; }
-  const Recorder* recorder() { return recorder_; }
-
- private:
-  int fd_;
-  int fd2_;
-  const Recorder *recorder_;
-  RecordingCB* cb_;
-  EpollTestServer* ep_;
-};
-
-TEST_F(EpollFunctionTest, TestUnconnectedSocket) {
-  int fd = socket(AddressFamilyUnderTest(), SOCK_STREAM, IPPROTO_TCP);
-  ep()->RegisterFD(fd, cb(), EPOLLIN | EPOLLOUT);
-  ep()->WaitForEventsAndExecuteCallbacks();
-
-  Recorder tmp;
-  tmp.Record(cb(), CREATION, 0, 0);
-  tmp.Record(cb(), REGISTRATION, fd, EPOLLIN | EPOLLOUT);
-  tmp.Record(cb(), EVENT, fd, EPOLLOUT | EPOLLHUP);
-  EXPECT_TRUE(recorder()->IsEqual(&tmp));
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFD) {
-  // Check that the basic register works.
-  ep()->RegisterFD(fd(), cb(), EPOLLIN);
-
-  // Make sure that the fd-CB mapping is there.
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Now make sure that if we register again, we stomp the old callback.
-  // Also make sure we handle O_NONBLOCK correctly
-  RecordingCB cb2;
-  ep()->RegisterFD(fd(), &cb2, EPOLLOUT | O_NONBLOCK);
-  ep()->CheckMapping(fd(), &cb2);
-  ep()->CheckEventMask(fd(), EPOLLOUT | O_NONBLOCK);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFDForWrite) {
-  ep()->RegisterFDForWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFDForReadWrite) {
-  ep()->RegisterFDForReadWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFDForRead) {
-  ep()->RegisterFDForRead(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestUnregisterFD) {
-  ep()->RegisterFDForRead(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-    // Unregister and make sure that it's gone.
-  ep()->UnregisterFD(fd());
-  ep()->CheckNotMapped(fd());
-  ep()->CheckNotRegistered(fd());
-
-  // And make sure that unregistering something a second time doesn't cause
-  // crashes.
-  ep()->UnregisterFD(fd());
-  ep()->CheckNotMapped(fd());
-  ep()->CheckNotRegistered(fd());
-}
-
-TEST_F(EpollFunctionTest, TestModifyCallback) {
-  // Check that nothing terrible happens if we modify an unregistered fd.
-  ep()->ModifyCallback(fd(), EPOLLOUT);
-  ep()->CheckNotMapped(fd());
-  ep()->CheckNotRegistered(fd());
-
-  // Check that the basic register works.
-  ep()->RegisterFD(fd(), cb(), EPOLLIN);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Check that adding a signal swaps it out for the first.
-  ep()->ModifyCallback(fd(), EPOLLOUT);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Check that modifying from X to X works correctly.
-  ep()->ModifyCallback(fd(), EPOLLOUT);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Check that modifying from something to nothing works.
-  ep()->ModifyCallback(fd(), 0);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), 0);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStopRead) {
-  ep()->RegisterFDForReadWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Unregister and make sure you only lose the read event.
-  ep()->StopRead(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStartRead) {
-  ep()->RegisterFDForWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Make sure that StartRead adds EPOLLIN and doesn't remove other signals.
-  ep()->StartRead(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStopWrite) {
-  ep()->RegisterFDForReadWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Unregister write and make sure you only lose the write event.
-  ep()->StopWrite(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStartWrite) {
-  ep()->RegisterFDForRead(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Make sure that StartWrite adds EPOLLOUT and doesn't remove other
-  // signals.
-  ep()->StartWrite(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestSet_timeout_in_us) {
-  // Check that set works with various values.  There's a separate test below
-  // to make sure the values are used properly.
-  ep()->set_timeout_in_us(10);
-  EXPECT_EQ(10, ep()->timeout_in_us_for_test());
-
-  ep()->set_timeout_in_us(-1);
-  EXPECT_EQ(-1, ep()->timeout_in_us_for_test());
-}
-
-TEST_F(EpollFunctionTest, TestHandleEvent) {
-  const std::vector<RecordEntry> *records = recorder()->records();
-
-  // Test that nothing bad happens if the FD is not in the map.
-  ep()->HandleEvent(fd(), EPOLLOUT);
-  ep()->CallReadyListCallbacks();
-
-  ep()->RegisterFD(fd(), cb(), 0);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), 0);
-
-  // At this point we should have creation and registration recorded.
-  EXPECT_EQ(2u, records->size());
-
-  // Call handle event and make sure something was recorded.
-  ep()->HandleEvent(fd(), EPOLLOUT);
-  ep()->CallReadyListCallbacks();
-  EXPECT_EQ(3u, records->size());
-
-  // Call handle event and make sure something was recorded.
-  ep()->HandleEvent(fd(), EPOLLIN | O_NONBLOCK);
-  ep()->CallReadyListCallbacks();
-  EXPECT_EQ(4u, records->size());
-
-  Recorder tmp;
-  tmp.Record(cb(), CREATION, 0, 0);
-  tmp.Record(cb(), REGISTRATION, fd(), 0);
-  tmp.Record(cb(), EVENT, fd(), EPOLLOUT);
-  tmp.Record(cb(), EVENT, fd(), EPOLLIN | O_NONBLOCK);
-
-  EXPECT_TRUE(recorder()->IsEqual(&tmp));
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestNumFDsRegistered) {
-  EXPECT_EQ(0, ep()->NumFDsRegistered());
-
-  ep()->RegisterFD(fd(), cb(), 0);
-  EXPECT_EQ(1, ep()->NumFDsRegistered());
-
-  ep()->RegisterFD(fd2(), cb(), 0);
-  EXPECT_EQ(2, ep()->NumFDsRegistered());
-
-  ep()->RegisterFD(fd2(), cb(), 0);
-  EXPECT_EQ(2, ep()->NumFDsRegistered());
-
-  ep()->UnregisterFD(fd2());
-  EXPECT_EQ(1, ep()->NumFDsRegistered());
-
-  ep()->UnregisterFD(fd());
-  EXPECT_EQ(0, ep()->NumFDsRegistered());
-}
-
-// Check all of the individual signals and 1-2 combinations.
-TEST_F(EpollFunctionTest, TestEventMaskToString) {
-  std::string test;
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLIN);
-  EXPECT_EQ(test, "EPOLLIN ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLOUT);
-  EXPECT_EQ(test, "EPOLLOUT ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLPRI);
-  EXPECT_EQ(test, "EPOLLPRI ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLERR);
-  EXPECT_EQ(test, "EPOLLERR ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLHUP);
-  EXPECT_EQ(test, "EPOLLHUP ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLHUP | EPOLLIN);
-  EXPECT_EQ(test, "EPOLLIN EPOLLHUP ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLIN | EPOLLOUT);
-  EXPECT_EQ(test, "EPOLLIN EPOLLOUT ");
-}
-
-class TestAlarm : public EpollAlarmCallbackInterface {
- public:
-  TestAlarm()
-    : time_before_next_alarm_(-1),
-      was_called_(false),
-      num_called_(0),
-      absolute_time_(false),
-      onshutdown_called_(false),
-      has_token_(false),
-      eps_(nullptr) {
-  }
-  ~TestAlarm() override {
-  }
-  int64_t OnAlarm() override {
-    has_token_ = false;
-    was_called_ = true;
-    ++num_called_;
-    if (time_before_next_alarm_ < 0) {
-      return 0;
-    }
-    if (absolute_time_) {
-      return time_before_next_alarm_;
-    } else {
-      return WallTimeNowInUsec() + time_before_next_alarm_;
-    }
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/) override {
-    onshutdown_called_ = true;
-    has_token_ = false;
-  }
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* eps) override {
-    has_token_ = true;
-    last_token_ = token;
-    eps_ = eps;
-  }
-  void OnUnregistration() override {
-    has_token_ = false;
-  }
-
-  void UnregisterIfRegistered(SimpleEpollServer* eps) {
-    if (has_token_) {
-      eps->UnregisterAlarm(last_token_);
-    }
-  }
-
-  void ReregisterAlarm(int64_t timeout_in_us) {
-    CHECK(has_token_);
-    eps_->ReregisterAlarm(last_token_, timeout_in_us);
-  }
-
-  void Reset() {
-    time_before_next_alarm_ = -1;
-    was_called_ = false;
-    absolute_time_ = false;
-  }
-
-  bool was_called() const { return was_called_; }
-  int num_called() const { return num_called_; }
-
-  void set_time_before_next_alarm(int64_t time) {
-    time_before_next_alarm_ = time;
-  }
-  void set_absolute_time(bool absolute) {
-    absolute_time_ = absolute;
-  }
-  bool onshutdown_called() { return onshutdown_called_; }
-
- protected:
-  int64_t time_before_next_alarm_;
-  bool was_called_;
-  int num_called_;
-  // Is time_before_next_alarm relative to the current time or absolute?
-  bool absolute_time_;
-  bool onshutdown_called_;
-  bool has_token_;
-  SimpleEpollServer::AlarmRegToken last_token_;
-  SimpleEpollServer* eps_;
-};
-
-class TestChildAlarm;
-
-// This node unregister all other alarms when it receives
-// OnShutdown() from any one child.
-class TestParentAlarm {
- public:
-  void OnShutdown(TestChildAlarm* child, SimpleEpollServer* eps) {
-    // Unregister
-    for (ChildTokenMap::const_iterator it = child_tokens_.begin();
-         it != child_tokens_.end(); ++it) {
-      if (it->first != child) {
-        eps->UnregisterAlarm(it->second);
-      }
-    }
-    child_tokens_.clear();
-  }
-
-  void OnRegistration(TestChildAlarm* child,
-                      const SimpleEpollServer::AlarmRegToken& token) {
-    child_tokens_[child] = token;
-  }
-
- protected:
-  typedef std::unordered_map<TestChildAlarm*, SimpleEpollServer::AlarmRegToken>
-      ChildTokenMap;
-
-  ChildTokenMap child_tokens_;
-};
-
-class TestChildAlarm : public TestAlarm {
- public:
-  void set_parent(TestParentAlarm* tp) { parent_ = tp; }
-  void OnShutdown(SimpleEpollServer* eps) override {
-    onshutdown_called_ = true;
-    // Inform parent of shutdown
-    parent_->OnShutdown(this, eps);
-  }
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* /*eps*/) override {
-    parent_->OnRegistration(this, token);
-  }
-
- protected:
-  TestParentAlarm* parent_;
-};
-
-class TestAlarmThatRegistersAnotherAlarm : public TestAlarm {
- public:
-  TestAlarmThatRegistersAnotherAlarm()
-      : alarm_(nullptr),
-        reg_time_delta_usec_(0),
-        eps_to_register_(nullptr),
-        has_reg_alarm_(false) {}
-  void SetRegisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
-                        SimpleEpollServer* eps) {
-    alarm_ = alarm;
-    reg_time_delta_usec_ = time_delta_usec;
-    has_reg_alarm_ = true;
-    eps_to_register_ = eps;
-  }
-  int64_t OnAlarm() override {
-    if (has_reg_alarm_) {
-      eps_to_register_->RegisterAlarm(
-          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
-          alarm_);
-      has_reg_alarm_ = false;
-    }
-    return TestAlarm::OnAlarm();
-  }
-
- protected:
-  TestAlarm* alarm_;
-  int64_t reg_time_delta_usec_;
-  SimpleEpollServer* eps_to_register_;
-  bool has_reg_alarm_;
-};
-
-class TestAlarmThatRegistersAndReregistersAnotherAlarm : public TestAlarm {
- public:
-  TestAlarmThatRegistersAndReregistersAnotherAlarm()
-      : alarm_(nullptr),
-        reg_time_delta_usec_(0),
-        reregister_time_delta_usec_(0),
-        eps_to_register_(nullptr),
-        has_reg_alarm_(false) {}
-  void SetRegisterAndReregisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
-                                     int64_t reregister_delta_usec,
-                                     SimpleEpollServer* eps) {
-    alarm_ = alarm;
-    reg_time_delta_usec_ = time_delta_usec;
-    reregister_time_delta_usec_ = reregister_delta_usec;
-    has_reg_alarm_ = true;
-    eps_to_register_ = eps;
-  }
-  int64_t OnAlarm() override {
-    if (has_reg_alarm_) {
-      eps_to_register_->RegisterAlarm(
-          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
-          alarm_);
-      alarm_->ReregisterAlarm(eps_to_register_->ApproximateNowInUsec() +
-                              reregister_time_delta_usec_);
-      has_reg_alarm_ = false;
-    }
-    return TestAlarm::OnAlarm();
-  }
-
- protected:
-  TestAlarm* alarm_;
-  int64_t reg_time_delta_usec_;
-  int64_t reregister_time_delta_usec_;
-  SimpleEpollServer* eps_to_register_;
-  bool has_reg_alarm_;
-};
-
-class TestAlarmThatUnregistersAnotherAlarm : public TestAlarm {
- public:
-  TestAlarmThatUnregistersAnotherAlarm()
-      : alarm_(nullptr), eps_to_register_(nullptr), has_unreg_alarm_(false) {}
-  void SetUnregisterAlarm(TestAlarm* alarm, SimpleEpollServer* eps) {
-    alarm_ = alarm;
-    has_unreg_alarm_ = true;
-    eps_to_register_ = eps;
-  }
-  int64_t OnAlarm() override {
-    if (has_unreg_alarm_) {
-      has_unreg_alarm_ = false;
-      alarm_->UnregisterIfRegistered(eps_to_register_);
-    }
-    return TestAlarm::OnAlarm();
-  }
-
- protected:
-  TestAlarm* alarm_;
-  SimpleEpollServer* eps_to_register_;
-  bool has_unreg_alarm_;
-};
-
-class TestAlarmUnregister : public TestAlarm {
- public:
-  TestAlarmUnregister()
-      : onunregistration_called_(false),
-        iterator_token_(nullptr) {
-  }
-  ~TestAlarmUnregister() override {
-    delete iterator_token_;
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/) override {
-    onshutdown_called_ = true;
-  }
-
-  int64_t OnAlarm() override {
-    delete iterator_token_;
-    iterator_token_ = nullptr;
-
-    return TestAlarm::OnAlarm();
-  }
-
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* /*eps*/) override {
-    // Multiple iterator tokens are not maintained by this code,
-    // so we should have reset the iterator_token in OnAlarm or
-    // OnUnregistration.
-    CHECK(iterator_token_ == nullptr);
-    iterator_token_ = new SimpleEpollServer::AlarmRegToken(token);
-  }
-  void OnUnregistration() override {
-    delete iterator_token_;
-    iterator_token_ = nullptr;
-    // Make sure that this alarm was not already unregistered.
-    CHECK(onunregistration_called_ == false);
-    onunregistration_called_ = true;
-  }
-
-  bool onunregistration_called() { return onunregistration_called_; }
-  // Returns true if the token has been filled in with the saved iterator
-  // and false if it has not.
-  bool get_token(SimpleEpollServer::AlarmRegToken* token) {
-    if (iterator_token_ != nullptr) {
-      *token = *iterator_token_;
-      return true;
-    } else {
-      return false;
-    }
-  }
-
- protected:
-  bool onunregistration_called_;
-  SimpleEpollServer::AlarmRegToken* iterator_token_;
-};
-
-void WaitForAlarm(SimpleEpollServer* eps, const TestAlarm& alarm) {
-  for (int i = 0; i < 5; ++i) {
-    // Ideally we would only have to call this once but it could wake up a bit
-    // early and so not call the alarm.  If it wakes up early several times
-    // there is something wrong.
-    eps->WaitForEventsAndExecuteCallbacks();
-    if (alarm.was_called()) {
-      break;
-    }
-  }
-}
-
-// Check a couple of alarm times to make sure they're falling within a
-// reasonable range.
-TEST(SimpleEpollServerTest, TestAlarms) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 10;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-
-  // Test a different time just to be careful.
-  alarm_time = 20;
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-  alarm.Reset();
-}
-
-// Same as above, but using RegisterAlarmApproximateDelta.
-TEST(SimpleEpollServerTest, TestRegisterAlarmApproximateDelta) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 10;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-  int64_t first_now = ep.ApproximateNowInUsec();
-  EXPECT_LT(0u, first_now);
-
-  // Test a different time just to be careful.
-  alarm_time = 20;
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-  int64_t second_now = ep.ApproximateNowInUsec();
-
-  EXPECT_LT(first_now, second_now);
-
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-  alarm.Reset();
-}
-
-TEST(SimpleEpollServerTest, TestAlarmsWithInfiniteWait) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 10;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(-1);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// In this test we have an alarm that when fires gets re-registered
-// at almost the same time at which it fires. Here, we want to make
-// sure that when the alarm gets re-registered we do not call OnAlarm()
-// on the same Alarm object again, until we have called
-// WaitForEventsAndExecuteCallbacks(). A poor implementation of epoll
-// server alarm handling can potentially cause OnAlarm() to be called
-// multiple times. We make sure that the epoll server is not going in
-// an infinite loop by checking that OnAlarm() is called exactly once
-// on the alarm object that got registered again.
-TEST(SimpleEpollServerTest, TestAlarmsThatGetReRegisteredAreNotCalledTwice) {
-  // This alarm would get registered again
-  TestAlarm alarm;
-  TestAlarm alarm2;
-  EpollTestServer ep;
-  ep.set_timeout_in_us(-1);
-
-  int64_t alarm_time = 10;
-  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
-
-  // This will make the alarm re-register when OnAlarm is called.
-  alarm.set_absolute_time(true);
-  alarm.set_time_before_next_alarm(abs_time + 2);
-
-  // Register two alarms and make sure we wait long enough to hit it.
-  ep.RegisterAlarm(abs_time, &alarm);
-  ep.RegisterAlarm(abs_time, &alarm2);
-  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  // Make sure that alarm is called only once.
-  EXPECT_EQ(1, alarm.num_called());
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// Here we make sure that when one alarm unregisters another alarm
-// (that is supposed to be registered again because its OnAlarm
-// returned > 0), the alarm thats supposed to be unregistered does
-// actually gets unregistered.
-TEST(SimpleEpollServerTest, TestAlarmsOneOnAlarmUnRegistersAnotherAlarm) {
-  TestAlarm alarm;
-  TestAlarmThatUnregistersAnotherAlarm alarm2;
-  EpollTestServer ep;
-  ep.set_timeout_in_us(-1);
-
-  int64_t alarm_time = 1;
-  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
-
-  // This will make the alarm re-register when OnAlarm is called.
-  alarm.set_absolute_time(true);
-  alarm.set_time_before_next_alarm(abs_time + 2);
-
-
-  // Register two alarms and make sure we wait long enough to hit it.
-  ep.RegisterAlarm(abs_time, &alarm);
-  // This would cause us to unregister alarm when OnAlarm is called
-  // on alarm2.
-  alarm2.SetUnregisterAlarm(&alarm, &ep);
-  ep.RegisterAlarm(abs_time + 1, &alarm2);
-  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  // Make sure that alarm is called only once.
-  EXPECT_EQ(1, alarm.num_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// Check a couple of alarm times to make sure they're falling within a
-// reasonable range.
-TEST(SimpleEpollServerTest, TestRepeatAlarms) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 20;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  alarm.set_time_before_next_alarm(1000*alarm_time);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-  // When we wake up it should be because the Alarm has been called, and has
-  // registered itself to be called again.
-
-  // Make sure the first alarm was called properly.
-  EXPECT_TRUE(alarm.was_called());
-
-  // Resetting means that the alarm is no longer a recurring alarm.  It will be
-  // called once more and then stop.
-  alarm.Reset();
-
-  // Make sure the alarm is called one final time.
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-}
-
-// Verify that an alarm that repeats itself in the past works properly.
-TEST(SimpleEpollServerTest, TestRepeatAlarmInPast) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int64_t alarm_time = 20;
-  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
-
-  // Make the alarm re-register in the past when OnAlarm is called.
-  alarm.set_absolute_time(true);
-  alarm.set_time_before_next_alarm(abs_time - 1000);
-
-  // Register the alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarm(abs_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-  // When we wake up it should be because the Alarm has been called, and has
-  // registered itself to be called again.
-
-  // Make sure the first alarm was called properly.
-  EXPECT_TRUE(alarm.was_called());
-
-  // Resetting means that the alarm is no longer a recurring alarm.  It will be
-  // called once more and then stop.
-  alarm.Reset();
-
-  // Make sure the alarm is called one final time.
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-}
-
-class EpollTestAlarms : public SimpleEpollServer {
- public:
-  EpollTestAlarms() : SimpleEpollServer() {}
-
-  inline int64_t NowInUsec() const override { return time_; }
-
-  void CallAndReregisterAlarmEvents() override {
-    recorded_now_in_us_ = NowInUsec();
-    SimpleEpollServer::CallAndReregisterAlarmEvents();
-  }
-
-  void set_time(int64_t time) { time_ = time; }
-
-  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }
-
- private:
-  int64_t time_;
-};
-
-// Test multiple interleaving alarms to make sure they work right.
-// Pattern is roughly:
-// time:   15    20    30    40
-// alarm:   A     B     A'    C
-TEST(SimpleEpollServerTest, TestMultipleAlarms) {
-  EpollTestAlarms ep;
-  TestAlarm alarmA;
-  TestAlarm alarmB;
-  TestAlarm alarmC;
-
-  ep.set_timeout_in_us(50 * 1000 * 2);
-  alarmA.set_time_before_next_alarm(1000 * 30);
-  alarmA.set_absolute_time(true);
-  ep.RegisterAlarm(15 * 1000, &alarmA);
-  ep.RegisterAlarm(20 * 1000, &alarmB);
-  ep.RegisterAlarm(40 * 1000, &alarmC);
-
-  ep.set_time(15 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-  EXPECT_TRUE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-  alarmA.Reset();  // Unregister A in the future.
-
-  ep.set_time(20 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // B
-  EXPECT_FALSE(alarmA.was_called());
-  EXPECT_TRUE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-  alarmB.Reset();
-
-  ep.set_time(30 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-  EXPECT_TRUE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-  alarmA.Reset();
-
-  ep.set_time(40 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // C
-  EXPECT_FALSE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_TRUE(alarmC.was_called());
-  alarmC.Reset();
-
-  ep.CallAndReregisterAlarmEvents();  // None.
-  EXPECT_FALSE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-}
-
-TEST(SimpleEpollServerTest, TestAlarmOnShutdown) {
-  TestAlarm alarm1;
-  {
-    EpollTestServer ep;
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-  }
-
-  EXPECT_TRUE(alarm1.onshutdown_called());
-}
-
-// Tests that if we have multiple alarms
-// OnShutdown then we handle them properly.
-TEST(SimpleEpollServerTest, TestMultipleAlarmOnShutdown) {
-  TestAlarm alarm1;
-  TestAlarm alarm2;
-  TestAlarm alarm3;
-  {
-    EpollTestServer ep;
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-    ep.RegisterAlarm(now + 9000, &alarm2);
-    ep.RegisterAlarm(now + 9000, &alarm3);
-  }
-
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_TRUE(alarm2.onshutdown_called());
-  EXPECT_TRUE(alarm3.onshutdown_called());
-}
-TEST(SimpleEpollServerTest, TestMultipleAlarmUnregistrationOnShutdown) {
-  TestParentAlarm tp;
-  TestChildAlarm alarm1;
-  TestChildAlarm alarm2;
-  alarm1.set_parent(&tp);
-  alarm2.set_parent(&tp);
-  {
-    EpollTestServer ep;
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-    ep.RegisterAlarm(now + 9000, &alarm2);
-  }
-
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_FALSE(alarm2.onshutdown_called());
-}
-
-// Check an alarm set in the past runs right away.
-TEST(SimpleEpollServerTest, TestPastAlarm) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  // Register the alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(1000 * 2);
-  ep.RegisterAlarm(WallTimeNowInUsec() - 1000, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// Test Unregistering of Alarms
-TEST(SimpleEpollServerTest, TestUnregisterAlarm) {
-  EpollTestServer ep;
-  SimpleEpollServer::AlarmRegToken temptok;
-
-  TestAlarmUnregister alarm1;
-  TestAlarmUnregister alarm2;
-
-  ep.RegisterAlarm(WallTimeNowInUsec() + 5 * 1000, &alarm1);
-  ep.RegisterAlarm(WallTimeNowInUsec() + 13 * 1000, &alarm2);
-
-  // Unregister an alarm.
-  if (alarm2.get_token(&temptok)) {
-    ep.UnregisterAlarm(temptok);
-  }
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  EXPECT_TRUE(alarm2.onunregistration_called());
-
-  if (alarm1.get_token(&temptok)) {
-    ep.UnregisterAlarm(temptok);
-  }
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  EXPECT_TRUE(alarm1.onunregistration_called());
-}
-
-// Test Reregistering of Alarms
-TEST(SimpleEpollServerTest, TestReregisterAlarm) {
-  EpollTestAlarms ep;
-  SimpleEpollServer::AlarmRegToken token;
-
-  TestAlarmUnregister alarm;
-  ep.set_time(1000);
-  ep.RegisterAlarm(5000, &alarm);
-
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ASSERT_TRUE(alarm.get_token(&token));
-  ep.ReregisterAlarm(token, 6000);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  ep.set_time(5000);
-  ep.set_timeout_in_us(0);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_FALSE(alarm.was_called());
-
-  ep.set_time(6000);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_TRUE(alarm.was_called());
-}
-
-TEST(SimpleEpollServerTest, TestReregisterDeferredAlarm) {
-  EpollTestAlarms ep;
-  ep.set_timeout_in_us(0);
-
-  TestAlarm alarm;
-  TestAlarmThatRegistersAndReregistersAnotherAlarm register_alarm;
-  // Register the alarm in the past so it is added as a deferred alarm.
-  register_alarm.SetRegisterAndReregisterAlarm(&alarm, -500, 500, &ep);
-  ep.set_time(1000);
-  ep.RegisterAlarm(1000, &register_alarm);
-  // Call reregister twice, first to run register_alarm and second to run any
-  // scheduled deferred alarms.
-  ep.CallAndReregisterAlarmEvents();
-  ep.CallAndReregisterAlarmEvents();
-
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  EXPECT_FALSE(alarm.was_called());
-
-  ep.set_time(1500);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_TRUE(alarm.was_called());
-}
-
-// Check if an alarm fired and got reregistered, you are able to
-// unregister the second registration.
-TEST(SimpleEpollServerTest, TestFiredReregisteredAlarm) {
-  EpollTestAlarms ep;
-  TestAlarmUnregister alarmA;
-
-  SimpleEpollServer::AlarmRegToken first_token;
-  SimpleEpollServer::AlarmRegToken second_token;
-  bool found;
-
-  ep.set_timeout_in_us(50 * 1000 * 2);
-  alarmA.set_time_before_next_alarm(1000 * 30);
-  alarmA.set_absolute_time(true);
-
-// Alarm A first fires at 15, then 30
-  ep.RegisterAlarm(15 * 1000, &alarmA);
-
-  found = alarmA.get_token(&first_token);
-  EXPECT_TRUE(found);
-
-  ep.set_time(15 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-  EXPECT_TRUE(alarmA.was_called());
-
-  alarmA.Reset();
-
-  found = alarmA.get_token(&second_token);
-  EXPECT_TRUE(found);
-  if (found) {
-    ep.UnregisterAlarm(second_token);
-  }
-
-  ep.set_time(30 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-
-  alarmA.Reset();
-}
-
-// Here we make sure that one alarm can unregister another alarm
-// in OnShutdown().
-TEST(SimpleEpollServerTest, TestAlarmCanUnregistersAnotherAlarmOnShutdown) {
-  TestAlarmThatUnregistersAnotherAlarm alarm1;
-  TestAlarm alarm2;
-  {
-    EpollTestServer ep;
-    // Register two alarms and make alarm1 is placed in queue in front of alarm2
-    // so that when the queue is cleared, alarm1 is processed first.
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-    ep.RegisterAlarm(now + 9000, &alarm2);
-    alarm1.SetUnregisterAlarm(&alarm2, &ep);
-    EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
-  }
-}
-
-class TestAlarmRegisterAnotherAlarmShutdown : public TestAlarmUnregister {
- public:
-  TestAlarmRegisterAnotherAlarmShutdown(EpollAlarmCallbackInterface* alarm2,
-                                        int64_t when)
-      : alarm2_(alarm2), when_(when) {}
-  void OnShutdown(SimpleEpollServer* eps) override {
-    TestAlarmUnregister::OnShutdown(eps);
-    eps->RegisterAlarm(when_, alarm2_);
-  }
-
- private:
-  EpollAlarmCallbackInterface* alarm2_;
-  int64_t when_;
-};
-
-// This tests that alarm registers another alarm when shutting down.
-// The two cases are: new alarm comes before and after the alarm being
-// notified by OnShutdown()
-TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownBeforeSelf) {
-  TestAlarm alarm2;
-  int64_t alarm_time = WallTimeNowInUsec() + 5000;
-  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time - 1000);
-  {
-    EpollTestAlarms ep;
-    ep.RegisterAlarm(alarm_time, &alarm1);
-  }
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_FALSE(alarm2.onshutdown_called());
-}
-
-TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownAfterSelf) {
-  TestAlarm alarm2;
-  int64_t alarm_time = WallTimeNowInUsec() + 5000;
-  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time + 1000);
-  {
-    EpollTestAlarms ep;
-    ep.RegisterAlarm(alarm_time, &alarm1);
-  }
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_TRUE(alarm2.onshutdown_called());
-}
-
-TEST(SimpleEpollServerTest, TestWrite) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  char data[kPageSize] = {0};
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  RecordingCB recording_cb;
-  const Recorder* recorder = recording_cb.recorder();
-  const std::vector<RecordEntry> *records = recorder->records();
-
-  // Register to listen to write events.
-  ep.RegisterFD(write_fd, &recording_cb, EPOLLOUT | O_NONBLOCK);
-  // At this point the recorder should have the creation and registration
-  // events.
-  EXPECT_EQ(2u, records->size());
-
-  // Fill up the pipe.
-  int written = 1;
-  for (int i = 0; i < 17 && written > 0 ; ++i) {
-    written = write(write_fd, &data, kPageSize);
-  }
-  EXPECT_LT(written, 0);
-
-  // There should be no new events as the pipe is not available for writing.
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(2u, records->size());
-
-  // Now read data from the pipe to make it writable again.  This time the
-  // we should get an EPOLLOUT event.
-  int size = read(read_fd, &data, kPageSize);
-  EXPECT_EQ(kPageSize, size);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records->size());
-
-  // Now unsubscribe from writable events (which adds a modification record)
-  // and wait to verify that no event records are added.
-  ep.StopWrite(write_fd);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(4u, records->size());
-
-  // We had the right number of events all along. Make sure they were actually
-  // the right events.
-  Recorder tmp;
-  tmp.Record(&recording_cb, CREATION, 0, 0);
-  tmp.Record(&recording_cb, REGISTRATION, write_fd, EPOLLOUT | O_NONBLOCK);
-  tmp.Record(&recording_cb, EVENT, write_fd, EPOLLOUT);
-  tmp.Record(&recording_cb, MODIFICATION, write_fd, O_NONBLOCK);
-
-  EXPECT_TRUE(recorder->IsEqual(&tmp));
-  ep.UnregisterFD(write_fd);
-
-  close(read_fd);
-  close(write_fd);
-}
-
-TEST(SimpleEpollServerTest, TestReadWrite) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  char data[kPageSize] = {0};
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  RecordingCB recording_cb;
-  const Recorder* recorder = recording_cb.recorder();
-  const std::vector<RecordEntry> *records = recorder->records();
-
-  // Register to listen to read and write events.
-  ep.RegisterFDForReadWrite(read_fd, &recording_cb);
-  // At this point the recorder should have the creation and registration
-  // events.
-  EXPECT_EQ(2u, records->size());
-
-  int written = write(write_fd, &data, kPageSize);
-  EXPECT_EQ(kPageSize, written);
-
-  ep.WaitForEventsAndExecuteCallbacks();
-  ep.UnregisterFD(read_fd);
-
-  close(read_fd);
-  close(write_fd);
-}
-
-TEST(SimpleEpollServerTest, TestMultipleFDs) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  char data = 'x';
-
-  int pipe_one[2];
-  if (pipe(pipe_one) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int pipe_two[2];
-  if (pipe(pipe_two) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-
-  RecordingCB recording_cb_one;
-  const Recorder* recorder_one = recording_cb_one.recorder();
-  const std::vector<RecordEntry> *records_one = recorder_one->records();
-
-  RecordingCB recording_cb_two;
-  const Recorder* recorder_two = recording_cb_two.recorder();
-  const std::vector<RecordEntry> *records_two = recorder_two->records();
-
-  // Register to listen to read events for both pipes
-  ep.RegisterFDForRead(pipe_one[0], &recording_cb_one);
-  ep.RegisterFDForRead(pipe_two[0], &recording_cb_two);
-
-  EXPECT_EQ(2u, records_one->size());
-  EXPECT_EQ(2u, records_two->size());
-
-  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records_one->size());
-  EXPECT_EQ(2u, records_two->size());
-
-  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records_one->size());
-  EXPECT_EQ(3u, records_two->size());
-
-  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
-  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(4u, records_one->size());
-  EXPECT_EQ(4u, records_two->size());
-
-  ep.WaitForEventsAndExecuteCallbacks();
-  ep.UnregisterFD(pipe_one[0]);
-  ep.UnregisterFD(pipe_two[0]);
-  close(pipe_one[0]);
-  close(pipe_one[1]);
-  close(pipe_two[0]);
-  close(pipe_two[1]);
-}
-
-// Check that the SimpleEpollServer calls OnShutdown for any registered FDs.
-TEST(SimpleEpollServerTest, TestFDOnShutdown) {
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  RecordingCB recording_cb1;
-  RecordingCB recording_cb2;
-  const Recorder* recorder1 = recording_cb1.recorder();
-  const Recorder* recorder2 = recording_cb2.recorder();
-
-  {
-    SimpleEpollServer ep;
-    ep.set_timeout_in_us(1);
-
-    // Register to listen to write events.
-    ep.RegisterFD(write_fd, &recording_cb1, EPOLLOUT | O_NONBLOCK);
-    ep.RegisterFD(read_fd, &recording_cb2, EPOLLIN | O_NONBLOCK);
-  }
-
-  // Make sure OnShutdown was called for both callbacks.
-  Recorder write_recorder;
-  write_recorder.Record(&recording_cb1, CREATION, 0, 0);
-  write_recorder.Record(
-      &recording_cb1, REGISTRATION, write_fd, EPOLLOUT | O_NONBLOCK);
-  write_recorder.Record(&recording_cb1, UNREGISTRATION, write_fd, false);
-  write_recorder.Record(&recording_cb1, SHUTDOWN, write_fd, 0);
-  EXPECT_TRUE(recorder1->IsEqual(&write_recorder));
-
-  Recorder read_recorder;
-  read_recorder.Record(&recording_cb2, CREATION, 0, 0);
-  read_recorder.Record(
-      &recording_cb2, REGISTRATION, read_fd, EPOLLIN | O_NONBLOCK);
-  read_recorder.Record(&recording_cb2, UNREGISTRATION, read_fd, false);
-  read_recorder.Record(&recording_cb2, SHUTDOWN, read_fd, 0);
-  EXPECT_TRUE(recorder2->IsEqual(&read_recorder));
-
-  close(read_fd);
-  close(write_fd);
-}
-
-class UnregisterCB : public EpollCallbackInterface {
- public:
-  explicit UnregisterCB(int fd)
-    : eps_(nullptr), fd_(fd), onshutdown_called_(false) {
-  }
-
-  ~UnregisterCB() override {
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int fd) override {
-    eps_->UnregisterFD(fd_);
-    eps_->UnregisterFD(fd);
-    onshutdown_called_ = true;
-    eps_ = nullptr;
-  }
-
-  void set_epollserver(SimpleEpollServer* eps) { eps_ = eps; }
-  bool onshutdown_called() { return onshutdown_called_; }
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {}
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  std::string Name() const override { return "UnregisterCB"; }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-  bool onshutdown_called_;
-};
-
-// Check that unregistering fds in OnShutdown works cleanly.
-TEST(SimpleEpollServerTest, TestUnregisteringFDsOnShutdown) {
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  UnregisterCB unreg_cb1(read_fd);
-  UnregisterCB unreg_cb2(write_fd);
-
-  {
-    SimpleEpollServer ep;
-    ep.set_timeout_in_us(1);
-
-    unreg_cb1.set_epollserver(&ep);
-    unreg_cb2.set_epollserver(&ep);
-
-    // Register to listen to write events.
-    ep.RegisterFD(write_fd, &unreg_cb1, EPOLLOUT | O_NONBLOCK);
-    ep.RegisterFD(read_fd, &unreg_cb2, EPOLLIN | O_NONBLOCK);
-  }
-
-  // Make sure at least one onshutdown was called.
-  EXPECT_TRUE(unreg_cb1.onshutdown_called() ||
-              unreg_cb2.onshutdown_called());
-  // Make sure that both onshutdowns were not called.
-  EXPECT_TRUE(!(unreg_cb1.onshutdown_called() &&
-              unreg_cb2.onshutdown_called()));
-
-  close(read_fd);
-  close(write_fd);
-}
-
-TEST(SimpleEpollServerTest, TestFDsAndAlarms) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(5);
-  char data = 'x';
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-
-  RecordingCB recording_cb;
-  const Recorder* recorder = recording_cb.recorder();
-  const std::vector<RecordEntry> *records = recorder->records();
-
-  TestAlarm alarm;
-
-  ep.RegisterFDForRead(pipe_fds[0], &recording_cb);
-
-  EXPECT_EQ(2u, records->size());
-  EXPECT_FALSE(alarm.was_called());
-
-  // Write to the pipe and set a longish alarm so we get a read event followed
-  // by an alarm event.
-  int written = write(pipe_fds[1], &data, 1);
-  EXPECT_EQ(1, written);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records->size());
-  EXPECT_FALSE(alarm.was_called());
-  ep.RegisterAlarm(WallTimeNowInUsec() + 1000, &alarm);
-  WaitForAlarm(&ep, alarm);
-  EXPECT_EQ(3u, records->size());
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // Now set a short alarm so the alarm and the read event are called together.
-  ep.RegisterAlarm(WallTimeNowInUsec(), &alarm);
-  written = write(pipe_fds[1], &data, 1);
-  EXPECT_EQ(1, written);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(4u, records->size());
-
-  ep.UnregisterFD(pipe_fds[0]);
-
-  close(pipe_fds[0]);
-  close(pipe_fds[1]);
-}
-
-class EpollReader: public EpollCallbackInterface {
- public:
-  explicit EpollReader(int len)
-      : len_(0),
-        expected_len_(len),
-        done_reading_(false) {
-    memset(&buf_, 0, kMaxBufLen);
-  }
-
-  ~EpollReader() override {}
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-
-  void OnEvent(int fd, EpollEvent* event) override {
-    if (event->in_events & EPOLLIN) {
-      len_ += read(fd, &buf_ + len_, kMaxBufLen - len_);
-    }
-
-    // If we have finished reading...
-    if (event->in_events & EPOLLHUP) {
-      CHECK_EQ(len_, expected_len_);
-      done_reading_ = true;
-    }
-  }
-
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
-    // None of the current tests involve having active callbacks when the
-    // server shuts down.
-    EPOLL_LOG(FATAL);
-  }
-
-  std::string Name() const override { return "EpollReader"; }
-
-  // Returns true if the data in buf is the same as buf_, false otherwise.
-  bool CheckOutput(char* buf, int len) {
-    if (len != len_) {
-      return false;
-    }
-    return !memcmp(buf, buf_, len);
-  }
-
-  bool done_reading() { return done_reading_; }
-
- protected:
-  int len_;
-  int expected_len_;
-  char buf_[kMaxBufLen];
-  bool done_reading_;
-};
-
-void TestPipe(char *test_message, int len) {
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe failed()";
-  }
-  int reader_pipe = pipe_fds[0];
-  int writer_pipe = pipe_fds[1];
-  int child_pid;
-  memset(test_message, 'x', len);
-
-  switch (child_pid = fork()) {
-    case 0: {  // Child will send message.
-      const char *message = test_message;
-      int size;
-      close(reader_pipe);
-      while ((size = write(writer_pipe, message, len)) > 0) {
-        message += size;
-        len -= size;
-        if (len == 0) {
-          break;
-        }
-      }
-      if (len > 0) {
-        EPOLL_PLOG(FATAL) << "write() failed";
-      }
-      close(writer_pipe);
-
-      _exit(0);
-    }
-    case -1:
-      EPOLL_PLOG(FATAL) << "fork() failed";
-      break;
-    default: {  // Parent will receive message.
-      close(writer_pipe);
-      auto ep = EpollMakeUnique<SimpleEpollServer>();
-      ep->set_timeout_in_us(1);
-      EpollReader reader(len);
-      ep->RegisterFD(reader_pipe, &reader, EPOLLIN);
-
-      int64_t start_ms = WallTimeNowInUsec() / 1000;
-      // Loop until we're either done reading, or have waited ~10 us.
-      while (!reader.done_reading() &&
-             (WallTimeNowInUsec() / 1000 - start_ms) < 10000) {
-        ep->WaitForEventsAndExecuteCallbacks();
-      }
-      ep->UnregisterFD(reader_pipe);
-      CHECK(reader.CheckOutput(test_message, len));
-      break;
-    }
-  }
-
-  close(reader_pipe);
-  close(writer_pipe);
-}
-
-TEST(SimpleEpollServerTest, TestSmallPipe) {
-  char buf[kMaxBufLen];
-  TestPipe(buf, 10);
-}
-
-TEST(SimpleEpollServerTest, TestLargePipe) {
-  char buf[kMaxBufLen];
-  TestPipe(buf, kMaxBufLen);
-}
-
-// Tests RegisterFDForRead as well as StopRead.
-TEST(SimpleEpollServerTest, TestRead) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  int len = 1;
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  auto reader = EpollMakeUnique<EpollReader>(len);
-
-  // Check that registering a FD for read alerts us when there is data to be
-  // read.
-  ep.RegisterFDForRead(read_fd, reader.get());
-  char data = 'a';
-  int size = write(write_fd, &data, 1);
-  EXPECT_EQ(1, size);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(reader->CheckOutput(&data, len));
-
-  // Remove the callback for read events, write to the pipe and make sure that
-  // we did not read more data.
-  ep.StopRead(read_fd);
-  size = write(write_fd, &data, len);
-  EXPECT_EQ(1, size);
-  // The wait will return after timeout.
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(reader->CheckOutput(&data, len));
-  ep.UnregisterFD(read_fd);
-
-  close(read_fd);
-  close(write_fd);
-}
-
-class EdgeTriggerCB : public EpollCallbackInterface {
- public:
-  EdgeTriggerCB(int read_size, int write_size, char write_char, char peer_char)
-      : eps_(nullptr),
-        read_buf_(read_size),
-        write_buf_(write_size, write_char),
-        peer_char_(peer_char) {
-    Reset();
-  }
-
-  ~EdgeTriggerCB() override {}
-
-  void Reset() {
-    CHECK(eps_ == nullptr);
-    bytes_read_ = 0;
-    bytes_written_ = 0;
-    can_read_ = false;
-    will_read_ = false;
-    can_write_ = false;
-    will_write_ = false;
-    read_closed_ = false;
-    write_closed_ = false;
-  }
-
-  void ResetByteCounts() {
-    bytes_read_ = bytes_written_ = 0;
-  }
-
-  void set_will_read(bool will_read) { will_read_ = will_read; }
-
-  void set_will_write(bool will_write) { will_write_ = will_write; }
-
-  bool can_write() const { return can_write_; }
-
-  int bytes_read() const { return bytes_read_; }
-
-  int bytes_written() const { return bytes_written_; }
-
-  void OnRegistration(SimpleEpollServer* eps, int fd, int event_mask) override {
-    EXPECT_TRUE(eps_ == nullptr);
-    eps_ = eps;
-    Initialize(fd, event_mask);
-  }
-
-  void OnModification(int fd, int event_mask) override {
-    EXPECT_TRUE(eps_ != nullptr);
-    if (event_mask & EPOLLET) {
-      Initialize(fd, event_mask);
-    } else {
-      eps_->SetFDNotReady(fd);
-    }
-  }
-
-  void OnEvent(int fd, EpollEvent* event) override {
-    const int event_mask = event->in_events;
-    if (event_mask & (EPOLLHUP | EPOLLERR)) {
-      write_closed_ = true;
-      return;
-    }
-    if (will_read_ && event_mask & EPOLLIN) {
-      EXPECT_FALSE(read_closed_);
-      int read_size = read_buf_.size();
-      memset(&read_buf_[0], 0, read_size);
-      int len = recv(fd, &read_buf_[0], read_size, MSG_DONTWAIT);
-      // Update the readiness states
-      can_read_ = (len == read_size);
-
-      if (len > 0) {
-        bytes_read_ += len;
-        EPOLL_VLOG(1) << "fd: " << fd << ", read " << len
-                      << ", total: " << bytes_read_;
-        // Now check the bytes read
-        EXPECT_TRUE(CheckReadBuffer(len));
-      } else if (len < 0) {
-        EPOLL_VLOG(1) << "fd: " << fd << " read hit EAGAIN";
-        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
-        can_read_ = false;
-      } else {
-        read_closed_ = true;
-      }
-    }
-    if (will_write_ && event_mask & EPOLLOUT) {
-      // Write side close/full close can only detected by EPOLLHUP, which is
-      // caused by EPIPE.
-      EXPECT_FALSE(write_closed_);
-      int write_size = write_buf_.size();
-      int len = send(fd, &write_buf_[0], write_size, MSG_DONTWAIT);
-      can_write_ = (len == write_size);
-      if (len > 0) {
-        bytes_written_ += len;
-        EPOLL_VLOG(1) << "fd: " << fd << ", write " << len
-                      << ", total: " << bytes_written_;
-      } else {
-        EPOLL_VLOG(1) << "fd: " << fd << " write hit EAGAIN";
-        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
-        can_write_ = false;
-      }
-    }
-    // Since we can only get on the ready list once, wait till we confirm both
-    // read and write side continuation state and set the correct event mask
-    // for the ready list.
-    event->out_ready_mask = can_read_ ? static_cast<int>(EPOLLIN) : 0;
-    if (can_write_) {
-      event->out_ready_mask |= EPOLLOUT;
-    }
-  }
-
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {
-    EXPECT_TRUE(eps_ != nullptr);
-    eps_ = nullptr;
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
-    // None of the current tests involve having active callbacks when the
-    // server shuts down.
-    EPOLL_LOG(FATAL);
-  }
-
-  std::string Name() const override { return "EdgeTriggerCB"; }
-
- private:
-  SimpleEpollServer* eps_;
-  std::vector<char> read_buf_;
-  int bytes_read_;
-  std::vector<char> write_buf_;
-  int bytes_written_;
-  char peer_char_;   // The char we expected to read.
-  bool can_read_;
-  bool will_read_;
-  bool can_write_;
-  bool will_write_;
-  bool read_closed_;
-  bool write_closed_;
-
-  void Initialize(int fd, int event_mask) {
-    CHECK(eps_);
-    can_read_ = can_write_ = false;
-    if (event_mask & EPOLLET) {
-      int events = 0;
-      if (event_mask & EPOLLIN) {
-        events |= EPOLLIN;
-        can_read_ = true;
-      }
-      if (event_mask & EPOLLOUT) {
-        events |= EPOLLOUT;
-        can_write_ = true;
-      }
-      eps_->SetFDReady(fd, events);
-    }
-  }
-
-  bool CheckReadBuffer(int len) const {
-    for (int i = 0; i < len; ++i) {
-      if (peer_char_ != read_buf_[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-};
-
-// Test adding and removing from the ready list.
-TEST(SimpleEpollServerTest, TestReadyList) {
-  SimpleEpollServer ep;
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-
-  // Just use any CB will do, since we never wait on epoll events.
-  EdgeTriggerCB reader1(0, 0, 0, 0);
-  EdgeTriggerCB reader2(0, 0, 0, 0);
-
-  ep.RegisterFD(pipe_fds[0], &reader1, EPOLLIN);
-  ep.RegisterFD(pipe_fds[1], &reader2, EPOLLOUT);
-
-  // Adding fds that are registered with eps
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
-
-  ep.SetFDReady(pipe_fds[0], EPOLLIN);
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
-  EXPECT_EQ(1u, ep.ReadyListSize());
-  ep.SetFDReady(pipe_fds[1], EPOLLOUT);
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
-  EXPECT_EQ(2u, ep.ReadyListSize());
-
-  // Now check that SetFDNotReady doesn't affect other fds
-  ep.SetFDNotReady(pipe_fds[0]);
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
-  EXPECT_EQ(1u, ep.ReadyListSize());
-
-  ep.UnregisterFD(pipe_fds[0]);
-  ep.UnregisterFD(pipe_fds[1]);
-  EXPECT_EQ(0u, ep.ReadyListSize());
-
-  // Now try adding them when they are not registered, and it shouldn't work.
-  ep.SetFDReady(pipe_fds[0], EPOLLIN);
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_EQ(0u, ep.ReadyListSize());
-
-  close(pipe_fds[0]);
-  close(pipe_fds[1]);
-}
-
-class EPSWaitThread : public EpollThread {
- public:
-  explicit EPSWaitThread(SimpleEpollServer* eps)
-      : EpollThread("EPSWait"), eps_(eps), done_(false) {}
-
-  void Run() override {
-    eps_->WaitForEventsAndExecuteCallbacks();
-  }
-
-  bool done() { return done_; }
- private:
-  SimpleEpollServer* eps_;
-  bool done_;
-};
-
-TEST(EpollServerTest, TestWake) {
-  SimpleEpollServer eps;
-  eps.set_timeout_in_us(-1);
-  EPSWaitThread eps_thread(&eps);
-  eps_thread.Start();
-
-  EXPECT_FALSE(eps_thread.done());
-  eps.Wake();
-  eps_thread.Join();
-}
-
-class UnRegisterWhileProcessingCB: public EpollCallbackInterface {
- public:
-  explicit UnRegisterWhileProcessingCB(int fd) : eps_(nullptr), fd_(fd) {}
-
-  ~UnRegisterWhileProcessingCB() override {
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    // This should cause no problems.
-    eps_->UnregisterFD(fd_);
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override { return "UnRegisterWhileProcessingCB"; }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-};
-
-class RegisterWhileProcessingCB: public EpollCallbackInterface {
- public:
-  RegisterWhileProcessingCB(int fd, EpollCallbackInterface* cb)
-    : eps_(nullptr), fd_(fd), cb_(cb) {}
-
-  ~RegisterWhileProcessingCB() override {
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    // This should cause no problems.
-    eps_->RegisterFDForReadWrite(fd_, cb_);
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override { return "RegisterWhileProcessingCB"; }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-  EpollCallbackInterface* cb_;
-};
-
-// Nothing bad should happen when we do this. We're -only-
-// testing that nothing bad occurs in this test.
-TEST(SimpleEpollServerTest, NothingBadWhenUnRegisteringFDWhileProcessingIt) {
-  UnRegisterWhileProcessingCB cb(0);
-  {
-    FakeSimpleEpollServer epoll_server;
-    cb.set_epoll_server(&epoll_server);
-    epoll_server.RegisterFDForReadWrite(0, &cb);
-    epoll_event ee;
-    ee.data.fd = 0;
-    epoll_server.AddEvent(0, ee);
-    epoll_server.AdvanceBy(1);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-}
-
-//
-// testing that nothing bad occurs in this test.
-TEST(SimpleEpollServerTest,
-     NoEventsDeliveredForFdsOfUnregisteredCBsWithReRegdFD) {
-  // events: fd0, fd1, fd2
-  // fd0 -> unreg fd2
-  // fd1 -> reg fd2
-  // fd2 -> no event should be seen
-  RecordingCB recorder_cb;
-  UnRegisterWhileProcessingCB unreg_cb(-3);
-  RegisterWhileProcessingCB reg_other_cb(-3, &recorder_cb);
-  {
-    FakeSimpleEpollServer epoll_server;
-    unreg_cb.set_epoll_server(&epoll_server);
-    reg_other_cb.set_epoll_server(&epoll_server);
-    epoll_server.RegisterFDForReadWrite(-1, &unreg_cb);
-    epoll_server.RegisterFDForReadWrite(-2, &reg_other_cb);
-    epoll_server.RegisterFDForReadWrite(-3, &recorder_cb);
-
-    epoll_event ee;
-    ee.events = EPOLLIN;  // asserted for all events for this test.
-
-    // Note that these events are in 'backwards' order in terms of time.
-    // Currently, the SimpleEpollServer code invokes the CBs from last delivered
-    // to first delivered, so this is to be sure that we invoke the CB for -1
-    // before -2, before -3.
-    ee.data.fd = -1;
-    epoll_server.AddEvent(2, ee);
-    ee.data.fd = -2;
-    epoll_server.AddEvent(1, ee);
-    ee.data.fd = -3;
-    epoll_server.AddEvent(0, ee);
-
-    epoll_server.AdvanceBy(5);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-
-  Recorder correct_recorder;
-  correct_recorder.Record(&recorder_cb, CREATION, 0, 0);
-  correct_recorder.Record(&recorder_cb, REGISTRATION, -3,
-                          EPOLLIN | EPOLLOUT);
-  correct_recorder.Record(&recorder_cb, UNREGISTRATION, -3, 0);
-  correct_recorder.Record(&recorder_cb, REGISTRATION, -3,
-                          EPOLLIN | EPOLLOUT);
-  correct_recorder.Record(&recorder_cb, SHUTDOWN, -3, 0);
-
-  EXPECT_TRUE(correct_recorder.IsEqual(recorder_cb.recorder()));
-}
-
-class ReRegWhileReadyListOnEvent: public EpollCallbackInterface {
- public:
-  explicit ReRegWhileReadyListOnEvent(int /*fd*/) : eps_(nullptr) {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int fd, EpollEvent* /*event_mask*/) override {
-    // This should cause no problems.
-    eps_->UnregisterFD(fd);
-    eps_->RegisterFDForReadWrite(fd, this);
-    eps_->UnregisterFD(fd);
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override { return "ReRegWhileReadyListOnEvent"; }
-
- protected:
-  SimpleEpollServer* eps_;
-};
-
-// Nothing bad should happen when we do this. We're -only-
-// testing that nothing bad occurs in this test.
-TEST(SimpleEpollServerTest,
-     NothingBadWhenReRegisteringFDWhileProcessingFromReadyList) {
-  ReRegWhileReadyListOnEvent cb(0);
-  {
-    FakeSimpleEpollServer epoll_server;
-    cb.set_epoll_server(&epoll_server);
-    epoll_server.RegisterFDForReadWrite(0, &cb);
-    epoll_event ee;
-    ee.data.fd = 0;
-    epoll_server.AddEvent(0, ee);
-    epoll_server.AdvanceBy(1);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-}
-
-class UnRegEverythingReadyListOnEvent: public EpollCallbackInterface {
- public:
-  UnRegEverythingReadyListOnEvent() : eps_(nullptr), fd_(0), fd_range_(0) {}
-
-  void set_fd(int fd) { fd_ = fd; }
-  void set_fd_range(int fd_range) { fd_range_ = fd_range; }
-  void set_num_called(int* num_called) { num_called_ = num_called; }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* eps, int fd,
-                      int /*event_mask*/) override {
-    eps->SetFDReady(fd, EPOLLIN);
-  }
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    // This should cause no problems.
-    CHECK(num_called_ != nullptr);
-    ++(*num_called_);
-    // Note that we're iterating from -fd_range + 1 -> 0.
-    // We do this because there is an FD installed into the
-    // epollserver somewhere in the low numbers.
-    // Using negative FD numbers (which are guaranteed to not
-    // exist in the epoll-server) ensures that we will not
-    // come in conflict with the preexisting FD.
-    for (int i = -fd_range_ + 1; i <= 0; ++i) {
-      eps_->UnregisterFD(i);
-    }
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override {
-    return "UnRegEverythingReadyListOnEvent";
-  }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-  int fd_range_;
-  int* num_called_;
-};
-
-TEST(SimpleEpollServerTest,
-     NothingBadWhenUnRegisteredWhileProcessingFromReadyList) {
-  const size_t kNumCallbacks = 32u;
-  UnRegEverythingReadyListOnEvent callbacks[kNumCallbacks];
-  int num_called = 0;
-  {
-    FakeSimpleEpollServer epoll_server;
-    for (size_t i = 0; i < kNumCallbacks; ++i) {
-      callbacks[i].set_fd(-i);
-      callbacks[i].set_fd_range(kNumCallbacks);
-      callbacks[i].set_num_called(&num_called);
-      callbacks[i].set_epoll_server(&epoll_server);
-      epoll_server.RegisterFDForReadWrite(0, &callbacks[i]);
-      epoll_event ee;
-      ee.data.fd = -i;
-      epoll_server.AddEvent(0, ee);
-    }
-    epoll_server.AdvanceBy(1);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-  EXPECT_EQ(1, num_called);
-}
-
-TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithNothingInList) {
-  FakeSimpleEpollServer epoll_server;
-  epoll_server.VerifyReadyList();
-}
-
-TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithStuffInLists) {
-  FakeSimpleEpollServer epoll_server;
-  epoll_server.VerifyReadyList();
-}
-
-TEST(SimpleEpollServerTest,
-     ApproximateNowInUsAccurateOutideOfWaitForEventsAndExecuteCallbacks) {
-  FakeSimpleEpollServer epoll_server;
-  epoll_server.AdvanceBy(1232);
-  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
-  epoll_server.AdvanceBy(1111);
-  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
-}
-
-class ApproximateNowInUsecTestCB: public EpollCallbackInterface {
- public:
-  ApproximateNowInUsecTestCB() : feps_(nullptr), called_(false) {}
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    EXPECT_EQ(feps_->ApproximateNowInUsec(), feps_->NowInUsec());
-    feps_->AdvanceBy(1111);
-    EXPECT_EQ(1 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
-    feps_->AdvanceBy(1111);
-    EXPECT_EQ(2 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
-    called_ = true;
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-  std::string Name() const override { return "ApproximateNowInUsecTestCB"; }
-
-  void set_fakeepollserver(FakeSimpleEpollServer* feps) { feps_ = feps; }
-  bool called() const { return called_; }
-
- protected:
-  FakeSimpleEpollServer* feps_;
-  bool called_;
-};
-
-TEST(SimpleEpollServerTest,
-     ApproximateNowInUsApproximateInsideOfWaitForEventsAndExecuteCallbacks) {
-  int dummy_fd = 11111;
-  ApproximateNowInUsecTestCB aniutcb;
-  {
-    FakeSimpleEpollServer epoll_server;
-    aniutcb.set_fakeepollserver(&epoll_server);
-
-    epoll_server.RegisterFD(dummy_fd, &aniutcb, EPOLLIN);
-    epoll_event ee;
-    ee.data.fd = dummy_fd;
-    ee.events = EPOLLIN;
-    epoll_server.AddEvent(10242, ee);
-    epoll_server.set_timeout_in_us(-1);
-    epoll_server.AdvanceByAndWaitForEventsAndExecuteCallbacks(20000);
-    EXPECT_TRUE(aniutcb.called());
-  }
-}
-
-// A mock epoll server that also simulates kernel delay in scheduling epoll
-// events.
-class FakeEpollServerWithDelay : public FakeSimpleEpollServer {
- public:
-  FakeEpollServerWithDelay() : FakeSimpleEpollServer(), delay(0) {}
-
-  int delay;
-
- protected:
-  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
-                      int timeout_in_ms) override {
-    int out = FakeSimpleEpollServer::epoll_wait_impl(epfd, events, max_events,
-                                                     timeout_in_ms);
-    AdvanceBy(delay);
-    return out;
-  }
-};
-
-// A callback that records the epoll event's delay.
-class RecordDelayOnEvent: public EpollCallbackInterface {
- public:
-  RecordDelayOnEvent() : last_delay(-1), eps_(nullptr) {}
-
-  ~RecordDelayOnEvent() override {
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  std::string Name() const override { return "RecordDelayOnEvent"; }
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    last_delay = eps_->LastDelayInUsec();
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  int64_t last_delay;
-
- protected:
-  SimpleEpollServer* eps_;
-};
-
-// Tests that an epoll callback sees the correct delay for its event when it
-// calls LastDelayInUsec().
-TEST(EpollServerTest, TestLastDelay) {
-  RecordDelayOnEvent cb;
-  FakeEpollServerWithDelay epoll_server;
-
-  cb.set_epoll_server(&epoll_server);
-
-  epoll_server.RegisterFDForReadWrite(0, &cb);
-  epoll_event ee;
-  ee.data.fd = 0;
-
-  // Inject delay, and confirm that it's reported.
-  epoll_server.set_timeout_in_us(5000);
-  epoll_server.delay = 6000;
-  epoll_server.AddEvent(0, ee);
-  epoll_server.AdvanceBy(1);
-  epoll_server.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(cb.last_delay, 1000);
-
-  // Fire an event before the timeout ends, and confirm that reported delay
-  // isn't negative.
-  epoll_server.set_timeout_in_us(5000);
-  epoll_server.delay = 0;
-  epoll_server.AddEvent(0, ee);
-  epoll_server.AdvanceBy(1);
-  epoll_server.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(cb.last_delay, 0);
-
-  // Wait forever until an event fires, and confirm there's no reported delay.
-  epoll_server.set_timeout_in_us(-1);
-  epoll_server.delay = 6000;
-  epoll_server.AddEvent(0, ee);
-  epoll_server.AdvanceBy(1);
-  epoll_server.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(cb.last_delay, 0);
-}
-
-TEST(SimpleEpollServerAlarmTest, TestShutdown) {
-  std::unique_ptr<SimpleEpollServer> eps(new SimpleEpollServer);
-  EpollAlarm alarm1;
-  EpollAlarm alarm2;
-
-  eps->RegisterAlarmApproximateDelta(10000000, &alarm1);
-  eps->RegisterAlarmApproximateDelta(10000000, &alarm2);
-
-  alarm2.UnregisterIfRegistered();
-  EXPECT_FALSE(alarm2.registered());
-  eps = nullptr;
-
-  EXPECT_FALSE(alarm1.registered());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestUnregister) {
-  SimpleEpollServer eps;
-  EpollAlarm alarm;
-
-  eps.RegisterAlarmApproximateDelta(10000000, &alarm);
-  EXPECT_TRUE(alarm.registered());
-
-  alarm.UnregisterIfRegistered();
-  EXPECT_FALSE(alarm.registered());
-
-  alarm.UnregisterIfRegistered();
-  EXPECT_FALSE(alarm.registered());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestUnregisterOnDestruction) {
-  EpollTestServer eps;
-  std::unique_ptr<EpollAlarm> alarm(new EpollAlarm());
-  EpollAlarm* alarm_ptr = alarm.get();
-
-  eps.RegisterAlarmApproximateDelta(10000000, alarm.get());
-  EXPECT_TRUE(eps.ContainsAlarm(alarm_ptr));
-  alarm = nullptr;
-  EXPECT_EQ(0u, eps.GetNumPendingAlarmsForTest());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestUnregisterOnAlarm) {
-  EpollTestServer eps;
-  EpollAlarm alarm;
-
-  eps.RegisterAlarmApproximateDelta(1, &alarm);
-  EXPECT_TRUE(eps.ContainsAlarm(&alarm));
-
-  while (alarm.registered()) {
-    eps.WaitForEventsAndExecuteCallbacks();
-  }
-  EXPECT_FALSE(eps.ContainsAlarm(&alarm));
-}
-
-TEST(SimpleEpollServerAlarmTest, TestReregisterAlarm) {
-  EpollTestAlarms ep;
-
-  EpollAlarm alarm;
-  ep.set_time(1000);
-  ep.RegisterAlarm(5000, &alarm);
-
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  alarm.ReregisterAlarm(6000);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  ep.set_time(5000);
-  ep.set_timeout_in_us(0);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  ep.set_time(6000);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestThatSameAlarmCanNotBeRegisteredTwice) {
-  TestAlarm alarm;
-  SimpleEpollServer epoll_server;
-  epoll_server.RegisterAlarm(1, &alarm);
-  EXPECT_EPOLL_BUG(epoll_server.RegisterAlarm(1, &alarm),
-                   "Alarm already exists");
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace epoll_server
diff --git a/http2/adapter/adapter_impl_comparison_test.cc b/http2/adapter/adapter_impl_comparison_test.cc
deleted file mode 100644
index 11f03bb..0000000
--- a/http2/adapter/adapter_impl_comparison_test.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "http2/adapter/recording_http2_visitor.h"
-
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/nghttp2_adapter.h"
-#include "http2/adapter/oghttp2_adapter.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-TEST(AdapterImplComparisonTest, ClientHandlesFrames) {
-  RecordingHttp2Visitor nghttp2_visitor;
-  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
-      NgHttp2Adapter::CreateClientAdapter(nghttp2_visitor);
-
-  RecordingHttp2Visitor oghttp2_visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
-      OgHttp2Adapter::Create(oghttp2_visitor, options);
-
-  const std::string initial_frames = TestFrameSequence()
-                                         .ServerPreface()
-                                         .Ping(42)
-                                         .WindowUpdate(0, 1000)
-                                         .Serialize();
-
-  nghttp2_adapter->ProcessBytes(initial_frames);
-  oghttp2_adapter->ProcessBytes(initial_frames);
-
-  EXPECT_EQ(nghttp2_visitor.GetEventSequence(),
-            oghttp2_visitor.GetEventSequence());
-
-  // TODO(b/181586191): Consider consistent behavior for delivering events on
-  // non-existent streams between nghttp2_adapter and oghttp2_adapter.
-}
-
-TEST(AdapterImplComparisonTest, ServerHandlesFrames) {
-  RecordingHttp2Visitor nghttp2_visitor;
-  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
-      NgHttp2Adapter::CreateServerAdapter(nghttp2_visitor);
-
-  RecordingHttp2Visitor oghttp2_visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
-      OgHttp2Adapter::Create(oghttp2_visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Ping(42)
-                                 .WindowUpdate(0, 1000)
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-
-  nghttp2_adapter->ProcessBytes(frames);
-  oghttp2_adapter->ProcessBytes(frames);
-
-  EXPECT_EQ(nghttp2_visitor.GetEventSequence(),
-            oghttp2_visitor.GetEventSequence());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/callback_visitor.cc b/http2/adapter/callback_visitor.cc
deleted file mode 100644
index 4b88a45..0000000
--- a/http2/adapter/callback_visitor.cc
+++ /dev/null
@@ -1,465 +0,0 @@
-#include "http2/adapter/callback_visitor.h"
-
-#include "absl/strings/escaping.h"
-#include "http2/adapter/http2_util.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "common/quiche_endian.h"
-
-// This visitor implementation needs visibility into the
-// nghttp2_session_callbacks type. There's no public header, so we'll redefine
-// the struct here.
-struct nghttp2_session_callbacks {
-  nghttp2_send_callback send_callback;
-  nghttp2_recv_callback recv_callback;
-  nghttp2_on_frame_recv_callback on_frame_recv_callback;
-  nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
-  nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
-  nghttp2_before_frame_send_callback before_frame_send_callback;
-  nghttp2_on_frame_send_callback on_frame_send_callback;
-  nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
-  nghttp2_on_stream_close_callback on_stream_close_callback;
-  nghttp2_on_begin_headers_callback on_begin_headers_callback;
-  nghttp2_on_header_callback on_header_callback;
-  nghttp2_on_header_callback2 on_header_callback2;
-  nghttp2_on_invalid_header_callback on_invalid_header_callback;
-  nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
-  nghttp2_select_padding_callback select_padding_callback;
-  nghttp2_data_source_read_length_callback read_length_callback;
-  nghttp2_on_begin_frame_callback on_begin_frame_callback;
-  nghttp2_send_data_callback send_data_callback;
-  nghttp2_pack_extension_callback pack_extension_callback;
-  nghttp2_unpack_extension_callback unpack_extension_callback;
-  nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
-  nghttp2_error_callback error_callback;
-  nghttp2_error_callback2 error_callback2;
-};
-
-namespace http2 {
-namespace adapter {
-
-CallbackVisitor::CallbackVisitor(Perspective perspective,
-                                 const nghttp2_session_callbacks& callbacks,
-                                 void* user_data)
-    : perspective_(perspective),
-      callbacks_(MakeCallbacksPtr(nullptr)),
-      user_data_(user_data) {
-  nghttp2_session_callbacks* c;
-  nghttp2_session_callbacks_new(&c);
-  *c = callbacks;
-  callbacks_ = MakeCallbacksPtr(c);
-}
-
-int64_t CallbackVisitor::OnReadyToSend(absl::string_view serialized) {
-  if (!callbacks_->send_callback) {
-    return kSendError;
-  }
-  int64_t result = callbacks_->send_callback(
-      nullptr, ToUint8Ptr(serialized.data()), serialized.size(), 0, user_data_);
-  QUICHE_VLOG(1) << "CallbackVisitor::OnReadyToSend called with "
-                 << serialized.size() << " bytes, returning " << result;
-  QUICHE_VLOG(2) << (perspective_ == Perspective::kClient ? "Client" : "Server")
-                 << " sending: [" << absl::CEscape(serialized) << "]";
-  if (result > 0) {
-    return result;
-  } else if (result == NGHTTP2_ERR_WOULDBLOCK) {
-    return kSendBlocked;
-  } else {
-    return kSendError;
-  }
-}
-
-void CallbackVisitor::OnConnectionError(ConnectionError /*error*/) {
-  QUICHE_VLOG(1) << "OnConnectionError not implemented";
-}
-
-bool CallbackVisitor::OnFrameHeader(Http2StreamId stream_id, size_t length,
-                                    uint8_t type, uint8_t flags) {
-  QUICHE_VLOG(1) << "CallbackVisitor::OnFrameHeader(stream_id=" << stream_id
-                 << ", type=" << int(type) << ", length=" << length
-                 << ", flags=" << int(flags) << ")";
-  if (static_cast<FrameType>(type) == FrameType::CONTINUATION) {
-    // Treat CONTINUATION as HEADERS
-    QUICHE_DCHECK_EQ(current_frame_.hd.stream_id, stream_id);
-    current_frame_.hd.length += length;
-    current_frame_.hd.flags |= flags;
-    QUICHE_DLOG_IF(ERROR, length == 0) << "Empty CONTINUATION!";
-    // Still need to deliver the CONTINUATION to the begin frame callback.
-    nghttp2_frame_hd hd;
-    memset(&hd, 0, sizeof(hd));
-    hd.stream_id = stream_id;
-    hd.length = length;
-    hd.type = type;
-    hd.flags = flags;
-    if (callbacks_->on_begin_frame_callback) {
-      const int result =
-          callbacks_->on_begin_frame_callback(nullptr, &hd, user_data_);
-      return result == 0;
-    }
-    return true;
-  }
-  // The general strategy is to clear |current_frame_| at the start of a new
-  // frame, accumulate frame information from the various callback events, then
-  // invoke the on_frame_recv_callback() with the accumulated frame data.
-  memset(&current_frame_, 0, sizeof(current_frame_));
-  current_frame_.hd.stream_id = stream_id;
-  current_frame_.hd.length = length;
-  current_frame_.hd.type = type;
-  current_frame_.hd.flags = flags;
-  if (callbacks_->on_begin_frame_callback) {
-    const int result = callbacks_->on_begin_frame_callback(
-        nullptr, &current_frame_.hd, user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-void CallbackVisitor::OnSettingsStart() {}
-
-void CallbackVisitor::OnSetting(Http2Setting setting) {
-  settings_.push_back({setting.id, setting.value});
-}
-
-void CallbackVisitor::OnSettingsEnd() {
-  current_frame_.settings.niv = settings_.size();
-  current_frame_.settings.iv = settings_.data();
-  QUICHE_VLOG(1) << "OnSettingsEnd, received settings of size "
-                 << current_frame_.settings.niv;
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    QUICHE_DCHECK_EQ(0, result);
-  }
-  settings_.clear();
-}
-
-void CallbackVisitor::OnSettingsAck() {
-  // ACK is part of the flags, which were set in OnFrameHeader().
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    QUICHE_DCHECK_EQ(0, result);
-  }
-}
-
-bool CallbackVisitor::OnBeginHeadersForStream(Http2StreamId stream_id) {
-  auto it = GetStreamInfo(stream_id);
-  if (it->second.received_headers) {
-    // At least one headers frame has already been received.
-    QUICHE_VLOG(1)
-        << "Headers already received for stream " << stream_id
-        << ", these are trailers or headers following a 100 response";
-    current_frame_.headers.cat = NGHTTP2_HCAT_HEADERS;
-  } else {
-    switch (perspective_) {
-      case Perspective::kClient:
-        QUICHE_VLOG(1) << "First headers at the client for stream " << stream_id
-                       << "; these are response headers";
-        current_frame_.headers.cat = NGHTTP2_HCAT_RESPONSE;
-        break;
-      case Perspective::kServer:
-        QUICHE_VLOG(1) << "First headers at the server for stream " << stream_id
-                       << "; these are request headers";
-        current_frame_.headers.cat = NGHTTP2_HCAT_REQUEST;
-        break;
-    }
-  }
-  it->second.received_headers = true;
-  if (callbacks_->on_begin_headers_callback) {
-    const int result = callbacks_->on_begin_headers_callback(
-        nullptr, &current_frame_, user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-Http2VisitorInterface::OnHeaderResult CallbackVisitor::OnHeaderForStream(
-    Http2StreamId /*stream_id*/, absl::string_view name,
-    absl::string_view value) {
-  if (callbacks_->on_header_callback) {
-    const int result = callbacks_->on_header_callback(
-        nullptr, &current_frame_, ToUint8Ptr(name.data()), name.size(),
-        ToUint8Ptr(value.data()), value.size(), NGHTTP2_NV_FLAG_NONE,
-        user_data_);
-    if (result == 0) {
-      return HEADER_OK;
-    } else if (result == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-      return HEADER_RST_STREAM;
-    } else {
-      // Assume NGHTTP2_ERR_CALLBACK_FAILURE.
-      return HEADER_CONNECTION_ERROR;
-    }
-  }
-  return HEADER_OK;
-}
-
-bool CallbackVisitor::OnEndHeadersForStream(Http2StreamId /*stream_id*/) {
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-bool CallbackVisitor::OnDataPaddingLength(Http2StreamId /*stream_id*/,
-                                          size_t padding_length) {
-  QUICHE_DCHECK_GE(remaining_data_, padding_length);
-  current_frame_.data.padlen = padding_length;
-  remaining_data_ -= padding_length;
-  if (remaining_data_ == 0 && callbacks_->on_frame_recv_callback != nullptr) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-bool CallbackVisitor::OnBeginDataForStream(Http2StreamId /*stream_id*/,
-                                           size_t payload_length) {
-  remaining_data_ = payload_length;
-  if (remaining_data_ == 0 && callbacks_->on_frame_recv_callback != nullptr) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-bool CallbackVisitor::OnDataForStream(Http2StreamId stream_id,
-                                      absl::string_view data) {
-  int result = 0;
-  if (callbacks_->on_data_chunk_recv_callback) {
-    result = callbacks_->on_data_chunk_recv_callback(
-        nullptr, current_frame_.hd.flags, stream_id, ToUint8Ptr(data.data()),
-        data.size(), user_data_);
-  }
-  remaining_data_ -= data.size();
-  if (result == 0 && remaining_data_ == 0 &&
-      callbacks_->on_frame_recv_callback) {
-    result = callbacks_->on_frame_recv_callback(nullptr, &current_frame_,
-                                                user_data_);
-  }
-  return result == 0;
-}
-
-void CallbackVisitor::OnEndStream(Http2StreamId /*stream_id*/) {}
-
-void CallbackVisitor::OnRstStream(Http2StreamId /*stream_id*/,
-                                  Http2ErrorCode error_code) {
-  current_frame_.rst_stream.error_code = static_cast<uint32_t>(error_code);
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    QUICHE_DCHECK_EQ(0, result);
-  }
-}
-
-bool CallbackVisitor::OnCloseStream(Http2StreamId stream_id,
-                                    Http2ErrorCode error_code) {
-  int result = 0;
-  if (callbacks_->on_stream_close_callback) {
-    QUICHE_VLOG(1) << "OnCloseStream(stream_id: " << stream_id
-                   << ", error_code: " << int(error_code) << ")";
-    result = callbacks_->on_stream_close_callback(
-        nullptr, stream_id, static_cast<uint32_t>(error_code), user_data_);
-  }
-  stream_map_.erase(stream_id);
-  if (stream_close_listener_) {
-    stream_close_listener_(stream_id);
-  }
-  return result == 0;
-}
-
-void CallbackVisitor::OnPriorityForStream(Http2StreamId /*stream_id*/,
-                                          Http2StreamId parent_stream_id,
-                                          int weight, bool exclusive) {
-  current_frame_.priority.pri_spec.stream_id = parent_stream_id;
-  current_frame_.priority.pri_spec.weight = weight;
-  current_frame_.priority.pri_spec.exclusive = exclusive;
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    QUICHE_DCHECK_EQ(0, result);
-  }
-}
-
-void CallbackVisitor::OnPing(Http2PingId ping_id, bool /*is_ack*/) {
-  uint64_t network_order_opaque_data =
-      quiche::QuicheEndian::HostToNet64(ping_id);
-  std::memcpy(current_frame_.ping.opaque_data, &network_order_opaque_data,
-              sizeof(network_order_opaque_data));
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    QUICHE_DCHECK_EQ(0, result);
-  }
-}
-
-void CallbackVisitor::OnPushPromiseForStream(
-    Http2StreamId /*stream_id*/, Http2StreamId /*promised_stream_id*/) {
-  QUICHE_LOG(DFATAL) << "Not implemented";
-}
-
-bool CallbackVisitor::OnGoAway(Http2StreamId last_accepted_stream_id,
-                               Http2ErrorCode error_code,
-                               absl::string_view opaque_data) {
-  current_frame_.goaway.last_stream_id = last_accepted_stream_id;
-  current_frame_.goaway.error_code = static_cast<uint32_t>(error_code);
-  current_frame_.goaway.opaque_data = ToUint8Ptr(opaque_data.data());
-  current_frame_.goaway.opaque_data_len = opaque_data.size();
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-void CallbackVisitor::OnWindowUpdate(Http2StreamId /*stream_id*/,
-                                     int window_increment) {
-  current_frame_.window_update.window_size_increment = window_increment;
-  if (callbacks_->on_frame_recv_callback) {
-    const int result = callbacks_->on_frame_recv_callback(
-        nullptr, &current_frame_, user_data_);
-    QUICHE_DCHECK_EQ(0, result);
-  }
-}
-
-void CallbackVisitor::PopulateFrame(nghttp2_frame& frame, uint8_t frame_type,
-                                    Http2StreamId stream_id, size_t length,
-                                    uint8_t flags, uint32_t error_code,
-                                    bool sent_headers) {
-  frame.hd.type = frame_type;
-  frame.hd.stream_id = stream_id;
-  frame.hd.length = length;
-  frame.hd.flags = flags;
-  const FrameType frame_type_enum = static_cast<FrameType>(frame_type);
-  if (frame_type_enum == FrameType::HEADERS) {
-    if (sent_headers) {
-      frame.headers.cat = NGHTTP2_HCAT_HEADERS;
-    } else {
-      switch (perspective_) {
-        case Perspective::kClient:
-          QUICHE_VLOG(1) << "First headers sent by the client for stream "
-                         << stream_id << "; these are request headers";
-          frame.headers.cat = NGHTTP2_HCAT_REQUEST;
-          break;
-        case Perspective::kServer:
-          QUICHE_VLOG(1) << "First headers sent by the server for stream "
-                         << stream_id << "; these are response headers";
-          frame.headers.cat = NGHTTP2_HCAT_RESPONSE;
-          break;
-      }
-    }
-  } else if (frame_type_enum == FrameType::RST_STREAM) {
-    frame.rst_stream.error_code = error_code;
-  } else if (frame_type_enum == FrameType::GOAWAY) {
-    frame.goaway.error_code = error_code;
-  }
-}
-
-int CallbackVisitor::OnBeforeFrameSent(uint8_t frame_type,
-                                       Http2StreamId stream_id, size_t length,
-                                       uint8_t flags) {
-  if (callbacks_->before_frame_send_callback) {
-    QUICHE_VLOG(1) << "OnBeforeFrameSent(stream_id=" << stream_id
-                   << ", type=" << int(frame_type) << ", length=" << length
-                   << ", flags=" << int(flags) << ")";
-    nghttp2_frame frame;
-    auto it = GetStreamInfo(stream_id);
-    // The implementation of the before_frame_send_callback doesn't look at the
-    // error code, so for now it's populated with 0.
-    PopulateFrame(frame, frame_type, stream_id, length, flags, /*error_code=*/0,
-                  it->second.before_sent_headers);
-    it->second.before_sent_headers = true;
-    return callbacks_->before_frame_send_callback(nullptr, &frame, user_data_);
-  }
-  return 0;
-}
-
-int CallbackVisitor::OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
-                                 size_t length, uint8_t flags,
-                                 uint32_t error_code) {
-  if (callbacks_->on_frame_send_callback) {
-    QUICHE_VLOG(1) << "OnFrameSent(stream_id=" << stream_id
-                   << ", type=" << int(frame_type) << ", length=" << length
-                   << ", flags=" << int(flags) << ", error_code=" << error_code
-                   << ")";
-    nghttp2_frame frame;
-    auto it = GetStreamInfo(stream_id);
-    PopulateFrame(frame, frame_type, stream_id, length, flags, error_code,
-                  it->second.sent_headers);
-    it->second.sent_headers = true;
-    return callbacks_->on_frame_send_callback(nullptr, &frame, user_data_);
-  }
-  return 0;
-}
-
-bool CallbackVisitor::OnInvalidFrame(Http2StreamId stream_id,
-                                     InvalidFrameError error) {
-  QUICHE_VLOG(1) << "OnInvalidFrame(" << stream_id << ", "
-                 << InvalidFrameErrorToString(error) << ")";
-  QUICHE_DCHECK_EQ(stream_id, current_frame_.hd.stream_id);
-  if (callbacks_->on_invalid_frame_recv_callback) {
-    return 0 ==
-           callbacks_->on_invalid_frame_recv_callback(
-               nullptr, &current_frame_, ToNgHttp2ErrorCode(error), user_data_);
-  }
-  return true;
-}
-
-void CallbackVisitor::OnBeginMetadataForStream(Http2StreamId stream_id,
-                                               size_t payload_length) {
-  QUICHE_VLOG(1) << "OnBeginMetadataForStream(stream_id=" << stream_id
-                 << ", payload_length=" << payload_length << ")";
-}
-
-bool CallbackVisitor::OnMetadataForStream(Http2StreamId stream_id,
-                                          absl::string_view metadata) {
-  QUICHE_VLOG(1) << "OnMetadataForStream(stream_id=" << stream_id
-                 << ", len=" << metadata.size() << ")";
-  if (callbacks_->on_extension_chunk_recv_callback) {
-    int result = callbacks_->on_extension_chunk_recv_callback(
-        nullptr, &current_frame_.hd, ToUint8Ptr(metadata.data()),
-        metadata.size(), user_data_);
-    return result == 0;
-  }
-  return true;
-}
-
-bool CallbackVisitor::OnMetadataEndForStream(Http2StreamId stream_id) {
-  QUICHE_LOG_IF(DFATAL, current_frame_.hd.flags != kMetadataEndFlag);
-  QUICHE_VLOG(1) << "OnMetadataEndForStream(stream_id=" << stream_id << ")";
-  if (callbacks_->unpack_extension_callback) {
-    void* payload;
-    int result = callbacks_->unpack_extension_callback(
-        nullptr, &payload, &current_frame_.hd, user_data_);
-    if (result == 0 && callbacks_->on_frame_recv_callback) {
-      current_frame_.ext.payload = payload;
-      result = callbacks_->on_frame_recv_callback(nullptr, &current_frame_,
-                                                  user_data_);
-    }
-    return (result == 0);
-  }
-  return true;
-}
-
-void CallbackVisitor::OnErrorDebug(absl::string_view message) {
-  if (callbacks_->error_callback2) {
-    callbacks_->error_callback2(nullptr, -1, message.data(), message.size(),
-                                user_data_);
-  }
-}
-
-CallbackVisitor::StreamInfoMap::iterator CallbackVisitor::GetStreamInfo(
-    Http2StreamId stream_id) {
-  auto it = stream_map_.find(stream_id);
-  if (it == stream_map_.end()) {
-    auto p = stream_map_.insert({stream_id, {}});
-    it = p.first;
-  }
-  return it;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/callback_visitor.h b/http2/adapter/callback_visitor.h
deleted file mode 100644
index d68211d..0000000
--- a/http2/adapter/callback_visitor.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_
-#define QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_
-
-#include <cstdint>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/nghttp2.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-// This visitor implementation accepts a set of nghttp2 callbacks and a "user
-// data" pointer, and invokes the callbacks according to HTTP/2 events received.
-class QUICHE_EXPORT_PRIVATE CallbackVisitor : public Http2VisitorInterface {
- public:
-  // Called when the visitor receives a close event for `stream_id`.
-  using StreamCloseListener = std::function<void(Http2StreamId stream_id)>;
-
-  explicit CallbackVisitor(Perspective perspective,
-                           const nghttp2_session_callbacks& callbacks,
-                           void* user_data);
-
-  int64_t OnReadyToSend(absl::string_view serialized) override;
-  void OnConnectionError(ConnectionError error) override;
-  bool OnFrameHeader(Http2StreamId stream_id, size_t length, uint8_t type,
-                     uint8_t flags) override;
-  void OnSettingsStart() override;
-  void OnSetting(Http2Setting setting) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck() override;
-  bool OnBeginHeadersForStream(Http2StreamId stream_id) override;
-  OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
-                                   absl::string_view name,
-                                   absl::string_view value) override;
-  bool OnEndHeadersForStream(Http2StreamId stream_id) override;
-  bool OnDataPaddingLength(Http2StreamId stream_id,
-                           size_t padding_length) override;
-  bool OnBeginDataForStream(Http2StreamId stream_id,
-                            size_t payload_length) override;
-  bool OnDataForStream(Http2StreamId stream_id,
-                       absl::string_view data) override;
-  void OnEndStream(Http2StreamId stream_id) override;
-  void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
-  bool OnCloseStream(Http2StreamId stream_id,
-                     Http2ErrorCode error_code) override;
-  void OnPriorityForStream(Http2StreamId stream_id,
-                           Http2StreamId parent_stream_id,
-                           int weight,
-                           bool exclusive) override;
-  void OnPing(Http2PingId ping_id, bool is_ack) override;
-  void OnPushPromiseForStream(Http2StreamId stream_id,
-                              Http2StreamId promised_stream_id) override;
-  bool OnGoAway(Http2StreamId last_accepted_stream_id,
-                Http2ErrorCode error_code,
-                absl::string_view opaque_data) override;
-  void OnWindowUpdate(Http2StreamId stream_id, int window_increment) override;
-  int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
-                        size_t length, uint8_t flags) override;
-  int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length,
-                  uint8_t flags, uint32_t error_code) override;
-  bool OnInvalidFrame(Http2StreamId stream_id,
-                      InvalidFrameError error) override;
-  void OnBeginMetadataForStream(Http2StreamId stream_id,
-                                size_t payload_length) override;
-  bool OnMetadataForStream(Http2StreamId stream_id,
-                           absl::string_view metadata) override;
-  bool OnMetadataEndForStream(Http2StreamId stream_id) override;
-  void OnErrorDebug(absl::string_view message) override;
-
-  size_t stream_map_size() const { return stream_map_.size(); }
-
-  void set_stream_close_listener(StreamCloseListener stream_close_listener) {
-    stream_close_listener_ = std::move(stream_close_listener);
-  }
-
- private:
-  struct QUICHE_EXPORT_PRIVATE StreamInfo {
-    bool before_sent_headers = false;
-    bool sent_headers = false;
-    bool received_headers = false;
-  };
-
-  using StreamInfoMap = absl::flat_hash_map<Http2StreamId, StreamInfo>;
-
-  void PopulateFrame(nghttp2_frame& frame, uint8_t frame_type,
-                     Http2StreamId stream_id, size_t length, uint8_t flags,
-                     uint32_t error_code, bool sent_headers);
-
-  // Creates the StreamInfoMap entry if it doesn't exist.
-  StreamInfoMap::iterator GetStreamInfo(Http2StreamId stream_id);
-
-  StreamInfoMap stream_map_;
-
-  StreamCloseListener stream_close_listener_;
-
-  Perspective perspective_;
-  nghttp2_session_callbacks_unique_ptr callbacks_;
-  void* user_data_;
-
-  nghttp2_frame current_frame_;
-  std::vector<nghttp2_settings_entry> settings_;
-  size_t remaining_data_ = 0;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_
diff --git a/http2/adapter/callback_visitor_test.cc b/http2/adapter/callback_visitor_test.cc
deleted file mode 100644
index c6c19f8..0000000
--- a/http2/adapter/callback_visitor_test.cc
+++ /dev/null
@@ -1,434 +0,0 @@
-#include "http2/adapter/callback_visitor.h"
-
-#include "absl/container/flat_hash_map.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/mock_nghttp2_callbacks.h"
-#include "http2/adapter/nghttp2_test_utils.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::IsEmpty;
-using testing::Pair;
-using testing::UnorderedElementsAre;
-
-enum FrameType {
-  DATA,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-  CONTINUATION,
-};
-
-// Tests connection-level events.
-TEST(ClientCallbackVisitorUnitTest, ConnectionFrames) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kClient,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-
-  testing::InSequence seq;
-
-  // SETTINGS
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));
-  visitor.OnFrameHeader(0, 0, SETTINGS, 0);
-
-  visitor.OnSettingsStart();
-  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
-  visitor.OnSettingsEnd();
-
-  // PING
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, PING, _)));
-  visitor.OnFrameHeader(0, 8, PING, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsPing(42)));
-  visitor.OnPing(42, false);
-
-  // WINDOW_UPDATE
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, _)));
-  visitor.OnFrameHeader(0, 4, WINDOW_UPDATE, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsWindowUpdate(1000)));
-  visitor.OnWindowUpdate(0, 1000);
-
-  // PING ack
-  EXPECT_CALL(callbacks,
-              OnBeginFrame(HasFrameHeader(0, PING, NGHTTP2_FLAG_ACK)));
-  visitor.OnFrameHeader(0, 8, PING, 1);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsPingAck(247)));
-  visitor.OnPing(247, true);
-
-  // GOAWAY
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, GOAWAY, 0)));
-  visitor.OnFrameHeader(0, 19, GOAWAY, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsGoAway(5, NGHTTP2_ENHANCE_YOUR_CALM,
-                                              "calm down!!")));
-  visitor.OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!");
-
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-}
-
-TEST(ClientCallbackVisitorUnitTest, StreamFrames) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kClient,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-  absl::flat_hash_map<Http2StreamId, int> stream_close_counts;
-  visitor.set_stream_close_listener(
-      [&stream_close_counts](Http2StreamId stream_id) {
-        ++stream_close_counts[stream_id];
-      });
-
-  testing::InSequence seq;
-
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-
-  // HEADERS on stream 1
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
-  visitor.OnFrameHeader(1, 23, HEADERS, 4);
-
-  EXPECT_CALL(callbacks,
-              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
-  visitor.OnBeginHeadersForStream(1);
-
-  EXPECT_EQ(visitor.stream_map_size(), 1);
-
-  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
-  visitor.OnHeaderForStream(1, ":status", "200");
-
-  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
-  visitor.OnHeaderForStream(1, "server", "my-fake-server");
-
-  EXPECT_CALL(callbacks,
-              OnHeader(_, "date", "Tue, 6 Apr 2021 12:54:01 GMT", _));
-  visitor.OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT");
-
-  EXPECT_CALL(callbacks, OnHeader(_, "trailer", "x-server-status", _));
-  visitor.OnHeaderForStream(1, "trailer", "x-server-status");
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
-  visitor.OnEndHeadersForStream(1);
-
-  // DATA for stream 1
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, DATA, 0)));
-  visitor.OnFrameHeader(1, 26, DATA, 0);
-
-  visitor.OnBeginDataForStream(1, 26);
-  EXPECT_CALL(callbacks, OnDataChunkRecv(0, 1, "This is the response body."));
-  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, 0)));
-  visitor.OnDataForStream(1, "This is the response body.");
-
-  // Trailers for stream 1, with a different nghttp2 "category".
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
-  visitor.OnFrameHeader(1, 23, HEADERS, 4);
-
-  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_HEADERS)));
-  visitor.OnBeginHeadersForStream(1);
-
-  EXPECT_CALL(callbacks, OnHeader(_, "x-server-status", "OK", _));
-  visitor.OnHeaderForStream(1, "x-server-status", "OK");
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_HEADERS)));
-  visitor.OnEndHeadersForStream(1);
-
-  EXPECT_THAT(stream_close_counts, IsEmpty());
-
-  // RST_STREAM on stream 3
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, RST_STREAM, 0)));
-  visitor.OnFrameHeader(3, 4, RST_STREAM, 0);
-
-  // No change in stream map size.
-  EXPECT_EQ(visitor.stream_map_size(), 1);
-  EXPECT_THAT(stream_close_counts, IsEmpty());
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(3, NGHTTP2_INTERNAL_ERROR)));
-  visitor.OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR);
-
-  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_INTERNAL_ERROR));
-  visitor.OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR);
-
-  EXPECT_THAT(stream_close_counts, UnorderedElementsAre(Pair(3, 1)));
-
-  // More stream close events
-  EXPECT_CALL(callbacks,
-              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));
-  visitor.OnFrameHeader(1, 0, DATA, 1);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
-  visitor.OnBeginDataForStream(1, 0);
-  visitor.OnEndStream(1);
-
-  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
-  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
-
-  // Stream map is empty again after both streams were closed.
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-  EXPECT_THAT(stream_close_counts,
-              UnorderedElementsAre(Pair(3, 1), Pair(1, 1)));
-
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(5, RST_STREAM, _)));
-  visitor.OnFrameHeader(5, 4, RST_STREAM, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(5, NGHTTP2_REFUSED_STREAM)));
-  visitor.OnRstStream(5, Http2ErrorCode::REFUSED_STREAM);
-
-  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_REFUSED_STREAM));
-  visitor.OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM);
-
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-  EXPECT_THAT(stream_close_counts,
-              UnorderedElementsAre(Pair(3, 1), Pair(1, 1), Pair(5, 1)));
-}
-
-TEST(ClientCallbackVisitorUnitTest, HeadersWithContinuation) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kClient,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-
-  testing::InSequence seq;
-
-  // HEADERS on stream 1
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, 0x0)));
-  visitor.OnFrameHeader(1, 23, HEADERS, 0x0);
-
-  EXPECT_CALL(callbacks,
-              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
-  visitor.OnBeginHeadersForStream(1);
-
-  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
-  visitor.OnHeaderForStream(1, ":status", "200");
-
-  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
-  visitor.OnHeaderForStream(1, "server", "my-fake-server");
-
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, CONTINUATION, 0x4)));
-  visitor.OnFrameHeader(1, 23, CONTINUATION, 0x4);
-
-  EXPECT_CALL(callbacks,
-              OnHeader(_, "date", "Tue, 6 Apr 2021 12:54:01 GMT", _));
-  visitor.OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT");
-
-  EXPECT_CALL(callbacks, OnHeader(_, "trailer", "x-server-status", _));
-  visitor.OnHeaderForStream(1, "trailer", "x-server-status");
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
-  visitor.OnEndHeadersForStream(1);
-}
-
-TEST(ClientCallbackVisitorUnitTest, ResetAndGoaway) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kClient,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-
-  testing::InSequence seq;
-
-  // RST_STREAM on stream 1
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, RST_STREAM, 0x0)));
-  EXPECT_TRUE(visitor.OnFrameHeader(1, 13, RST_STREAM, 0x0));
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(1, NGHTTP2_INTERNAL_ERROR)));
-  visitor.OnRstStream(1, Http2ErrorCode::INTERNAL_ERROR);
-
-  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_INTERNAL_ERROR));
-  EXPECT_TRUE(visitor.OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
-
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, GOAWAY, 0x0)));
-  EXPECT_TRUE(visitor.OnFrameHeader(0, 13, GOAWAY, 0x0));
-
-  EXPECT_CALL(callbacks,
-              OnFrameRecv(IsGoAway(3, NGHTTP2_ENHANCE_YOUR_CALM, "calma te")));
-  EXPECT_TRUE(
-      visitor.OnGoAway(3, Http2ErrorCode::ENHANCE_YOUR_CALM, "calma te"));
-
-  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_STREAM_CLOSED))
-      .WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
-  EXPECT_FALSE(visitor.OnCloseStream(5, Http2ErrorCode::STREAM_CLOSED));
-}
-
-TEST(ServerCallbackVisitorUnitTest, ConnectionFrames) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kServer,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-
-  testing::InSequence seq;
-
-  // SETTINGS
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));
-  visitor.OnFrameHeader(0, 0, SETTINGS, 0);
-
-  visitor.OnSettingsStart();
-  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
-  visitor.OnSettingsEnd();
-
-  // PING
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, PING, _)));
-  visitor.OnFrameHeader(0, 8, PING, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsPing(42)));
-  visitor.OnPing(42, false);
-
-  // WINDOW_UPDATE
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, _)));
-  visitor.OnFrameHeader(0, 4, WINDOW_UPDATE, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsWindowUpdate(1000)));
-  visitor.OnWindowUpdate(0, 1000);
-
-  // PING ack
-  EXPECT_CALL(callbacks,
-              OnBeginFrame(HasFrameHeader(0, PING, NGHTTP2_FLAG_ACK)));
-  visitor.OnFrameHeader(0, 8, PING, 1);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsPingAck(247)));
-  visitor.OnPing(247, true);
-
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-}
-
-TEST(ServerCallbackVisitorUnitTest, StreamFrames) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kServer,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-
-  testing::InSequence seq;
-
-  // HEADERS on stream 1
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(
-                             1, HEADERS, NGHTTP2_FLAG_END_HEADERS)));
-  visitor.OnFrameHeader(1, 23, HEADERS, 4);
-
-  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
-                                                  NGHTTP2_HCAT_REQUEST)));
-  visitor.OnBeginHeadersForStream(1);
-
-  EXPECT_EQ(visitor.stream_map_size(), 1);
-
-  EXPECT_CALL(callbacks, OnHeader(_, ":method", "POST", _));
-  visitor.OnHeaderForStream(1, ":method", "POST");
-
-  EXPECT_CALL(callbacks, OnHeader(_, ":path", "/example/path", _));
-  visitor.OnHeaderForStream(1, ":path", "/example/path");
-
-  EXPECT_CALL(callbacks, OnHeader(_, ":scheme", "https", _));
-  visitor.OnHeaderForStream(1, ":scheme", "https");
-
-  EXPECT_CALL(callbacks, OnHeader(_, ":authority", "example.com", _));
-  visitor.OnHeaderForStream(1, ":authority", "example.com");
-
-  EXPECT_CALL(callbacks, OnHeader(_, "accept", "text/html", _));
-  visitor.OnHeaderForStream(1, "accept", "text/html");
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
-                                               NGHTTP2_HCAT_REQUEST)));
-  visitor.OnEndHeadersForStream(1);
-
-  // DATA on stream 1
-  EXPECT_CALL(callbacks,
-              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));
-  visitor.OnFrameHeader(1, 25, DATA, NGHTTP2_FLAG_END_STREAM);
-
-  visitor.OnBeginDataForStream(1, 25);
-  EXPECT_CALL(callbacks, OnDataChunkRecv(NGHTTP2_FLAG_END_STREAM, 1,
-                                         "This is the request body."));
-  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
-  visitor.OnDataForStream(1, "This is the request body.");
-  visitor.OnEndStream(1);
-
-  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
-  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
-
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-
-  // RST_STREAM on stream 3
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, RST_STREAM, 0)));
-  visitor.OnFrameHeader(3, 4, RST_STREAM, 0);
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(3, NGHTTP2_INTERNAL_ERROR)));
-  visitor.OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR);
-
-  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_INTERNAL_ERROR));
-  visitor.OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR);
-
-  EXPECT_EQ(visitor.stream_map_size(), 0);
-}
-
-TEST(ServerCallbackVisitorUnitTest, DataWithPadding) {
-  testing::StrictMock<MockNghttp2Callbacks> callbacks;
-  CallbackVisitor visitor(Perspective::kServer,
-                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
-
-  const size_t kPaddingLength = 39;
-  const uint8_t kFlags = NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_END_STREAM;
-
-  testing::InSequence seq;
-
-  // DATA on stream 1
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, DATA, kFlags)));
-  EXPECT_TRUE(visitor.OnFrameHeader(1, 25 + kPaddingLength, DATA, kFlags));
-
-  EXPECT_TRUE(visitor.OnBeginDataForStream(1, 25 + kPaddingLength));
-
-  // Padding before data.
-  EXPECT_TRUE(visitor.OnDataPaddingLength(1, kPaddingLength));
-
-  EXPECT_CALL(callbacks,
-              OnDataChunkRecv(kFlags, 1, "This is the request body."));
-  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, kFlags, kPaddingLength)));
-  EXPECT_TRUE(visitor.OnDataForStream(1, "This is the request body."));
-  visitor.OnEndStream(1);
-
-  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
-  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
-
-  // DATA on stream 3
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, DATA, kFlags)));
-  EXPECT_TRUE(visitor.OnFrameHeader(3, 25 + kPaddingLength, DATA, kFlags));
-
-  EXPECT_TRUE(visitor.OnBeginDataForStream(3, 25 + kPaddingLength));
-
-  // Data before padding.
-  EXPECT_CALL(callbacks,
-              OnDataChunkRecv(kFlags, 3, "This is the request body."));
-  EXPECT_TRUE(visitor.OnDataForStream(3, "This is the request body."));
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsData(3, _, kFlags, kPaddingLength)));
-  EXPECT_TRUE(visitor.OnDataPaddingLength(3, kPaddingLength));
-  visitor.OnEndStream(3);
-
-  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_NO_ERROR));
-  visitor.OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR);
-
-  // DATA on stream 5
-  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(5, DATA, kFlags)));
-  EXPECT_TRUE(visitor.OnFrameHeader(5, 25 + kPaddingLength, DATA, kFlags));
-
-  EXPECT_TRUE(visitor.OnBeginDataForStream(5, 25 + kPaddingLength));
-
-  // Error during padding.
-  EXPECT_CALL(callbacks,
-              OnDataChunkRecv(kFlags, 5, "This is the request body."));
-  EXPECT_TRUE(visitor.OnDataForStream(5, "This is the request body."));
-
-  EXPECT_CALL(callbacks, OnFrameRecv(IsData(5, _, kFlags, kPaddingLength)))
-      .WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
-  EXPECT_FALSE(visitor.OnDataPaddingLength(5, kPaddingLength));
-  visitor.OnEndStream(3);
-
-  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_NO_ERROR));
-  visitor.OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/data_source.h b/http2/adapter/data_source.h
deleted file mode 100644
index dd4601f..0000000
--- a/http2/adapter/data_source.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_DATA_SOURCE_H_
-#define QUICHE_HTTP2_ADAPTER_DATA_SOURCE_H_
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-// Represents a source of DATA frames for transmission to the peer.
-class QUICHE_EXPORT_PRIVATE DataFrameSource {
- public:
-  virtual ~DataFrameSource() {}
-
-  enum : int64_t { kBlocked = 0, kError = -1 };
-
-  // Returns the number of bytes to send in the next DATA frame, and whether
-  // this frame indicates the end of the data. Returns {kBlocked, false} if
-  // blocked, {kError, false} on error.
-  virtual std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) = 0;
-
-  // This method is called with a frame header and a payload length to send. The
-  // source should send or buffer the entire frame and return true, or return
-  // false without sending or buffering anything.
-  virtual bool Send(absl::string_view frame_header, size_t payload_length) = 0;
-
-  // If true, the end of this data source indicates the end of the stream.
-  // Otherwise, this data will be followed by trailers.
-  virtual bool send_fin() const = 0;
-};
-
-// Represents a source of metadata frames for transmission to the peer.
-class QUICHE_EXPORT_PRIVATE MetadataSource {
- public:
-  virtual ~MetadataSource() {}
-
-  // Returns the number of frames of at most |max_frame_size| required to
-  // serialize the metadata for this source. Only required by the nghttp2
-  // implementation.
-  virtual size_t NumFrames(size_t max_frame_size) const = 0;
-
-  // This method is called with a destination buffer and length. It should
-  // return the number of payload bytes copied to |dest|, or a negative integer
-  // to indicate an error, as well as a boolean indicating whether the metadata
-  // has been completely copied.
-  virtual std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) = 0;
-
-  // This method is called when transmission of the metadata for this source
-  // fails in a non-recoverable way.
-  virtual void OnFailure() = 0;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_DATA_SOURCE_H_
diff --git a/http2/adapter/event_forwarder.cc b/http2/adapter/event_forwarder.cc
deleted file mode 100644
index e4b1f3d..0000000
--- a/http2/adapter/event_forwarder.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-#include "http2/adapter/event_forwarder.h"
-
-namespace http2 {
-namespace adapter {
-
-EventForwarder::EventForwarder(ForwardPredicate can_forward,
-                               spdy::SpdyFramerVisitorInterface& receiver)
-    : can_forward_(std::move(can_forward)), receiver_(receiver) {}
-
-void EventForwarder::OnError(Http2DecoderAdapter::SpdyFramerError error,
-                             std::string detailed_error) {
-  if (can_forward_()) {
-    receiver_.OnError(error, std::move(detailed_error));
-  }
-}
-
-void EventForwarder::OnCommonHeader(spdy::SpdyStreamId stream_id, size_t length,
-                                    uint8_t type, uint8_t flags) {
-  if (can_forward_()) {
-    receiver_.OnCommonHeader(stream_id, length, type, flags);
-  }
-}
-
-void EventForwarder::OnDataFrameHeader(spdy::SpdyStreamId stream_id,
-                                       size_t length, bool fin) {
-  if (can_forward_()) {
-    receiver_.OnDataFrameHeader(stream_id, length, fin);
-  }
-}
-
-void EventForwarder::OnStreamFrameData(spdy::SpdyStreamId stream_id,
-                                       const char* data, size_t len) {
-  if (can_forward_()) {
-    receiver_.OnStreamFrameData(stream_id, data, len);
-  }
-}
-
-void EventForwarder::OnStreamEnd(spdy::SpdyStreamId stream_id) {
-  if (can_forward_()) {
-    receiver_.OnStreamEnd(stream_id);
-  }
-}
-
-void EventForwarder::OnStreamPadLength(spdy::SpdyStreamId stream_id,
-                                       size_t value) {
-  if (can_forward_()) {
-    receiver_.OnStreamPadLength(stream_id, value);
-  }
-}
-
-void EventForwarder::OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) {
-  if (can_forward_()) {
-    receiver_.OnStreamPadding(stream_id, len);
-  }
-}
-
-spdy::SpdyHeadersHandlerInterface* EventForwarder::OnHeaderFrameStart(
-    spdy::SpdyStreamId stream_id) {
-  return receiver_.OnHeaderFrameStart(stream_id);
-}
-
-void EventForwarder::OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) {
-  if (can_forward_()) {
-    receiver_.OnHeaderFrameEnd(stream_id);
-  }
-}
-
-void EventForwarder::OnRstStream(spdy::SpdyStreamId stream_id,
-                                 spdy::SpdyErrorCode error_code) {
-  if (can_forward_()) {
-    receiver_.OnRstStream(stream_id, error_code);
-  }
-}
-
-void EventForwarder::OnSettings() {
-  if (can_forward_()) {
-    receiver_.OnSettings();
-  }
-}
-
-void EventForwarder::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
-  if (can_forward_()) {
-    receiver_.OnSetting(id, value);
-  }
-}
-
-void EventForwarder::OnSettingsEnd() {
-  if (can_forward_()) {
-    receiver_.OnSettingsEnd();
-  }
-}
-
-void EventForwarder::OnSettingsAck() {
-  if (can_forward_()) {
-    receiver_.OnSettingsAck();
-  }
-}
-
-void EventForwarder::OnPing(spdy::SpdyPingId unique_id, bool is_ack) {
-  if (can_forward_()) {
-    receiver_.OnPing(unique_id, is_ack);
-  }
-}
-
-void EventForwarder::OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
-                              spdy::SpdyErrorCode error_code) {
-  if (can_forward_()) {
-    receiver_.OnGoAway(last_accepted_stream_id, error_code);
-  }
-}
-
-bool EventForwarder::OnGoAwayFrameData(const char* goaway_data, size_t len) {
-  if (can_forward_()) {
-    return receiver_.OnGoAwayFrameData(goaway_data, len);
-  }
-  return false;
-}
-
-void EventForwarder::OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
-                               int weight, spdy::SpdyStreamId parent_stream_id,
-                               bool exclusive, bool fin, bool end) {
-  if (can_forward_()) {
-    receiver_.OnHeaders(stream_id, has_priority, weight, parent_stream_id,
-                        exclusive, fin, end);
-  }
-}
-
-void EventForwarder::OnWindowUpdate(spdy::SpdyStreamId stream_id,
-                                    int delta_window_size) {
-  if (can_forward_()) {
-    receiver_.OnWindowUpdate(stream_id, delta_window_size);
-  }
-}
-
-void EventForwarder::OnPushPromise(spdy::SpdyStreamId stream_id,
-                                   spdy::SpdyStreamId promised_stream_id,
-                                   bool end) {
-  if (can_forward_()) {
-    receiver_.OnPushPromise(stream_id, promised_stream_id, end);
-  }
-}
-
-void EventForwarder::OnContinuation(spdy::SpdyStreamId stream_id, bool end) {
-  if (can_forward_()) {
-    receiver_.OnContinuation(stream_id, end);
-  }
-}
-
-void EventForwarder::OnAltSvc(
-    spdy::SpdyStreamId stream_id, absl::string_view origin,
-    const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
-  if (can_forward_()) {
-    receiver_.OnAltSvc(stream_id, origin, altsvc_vector);
-  }
-}
-
-void EventForwarder::OnPriority(spdy::SpdyStreamId stream_id,
-                                spdy::SpdyStreamId parent_stream_id, int weight,
-                                bool exclusive) {
-  if (can_forward_()) {
-    receiver_.OnPriority(stream_id, parent_stream_id, weight, exclusive);
-  }
-}
-
-void EventForwarder::OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
-                                      absl::string_view priority_field_value) {
-  if (can_forward_()) {
-    receiver_.OnPriorityUpdate(prioritized_stream_id, priority_field_value);
-  }
-}
-
-bool EventForwarder::OnUnknownFrame(spdy::SpdyStreamId stream_id,
-                                    uint8_t frame_type) {
-  if (can_forward_()) {
-    return receiver_.OnUnknownFrame(stream_id, frame_type);
-  }
-  return false;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/event_forwarder.h b/http2/adapter/event_forwarder.h
deleted file mode 100644
index d4dce1e..0000000
--- a/http2/adapter/event_forwarder.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_EVENT_FORWARDER_H_
-#define QUICHE_HTTP2_ADAPTER_EVENT_FORWARDER_H_
-
-#include <functional>
-
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-
-namespace http2 {
-namespace adapter {
-
-// Forwards events to a provided SpdyFramerVisitorInterface receiver if the
-// provided predicate succeeds. Currently, OnHeaderFrameStart() is always
-// forwarded regardless of the predicate.
-// TODO(diannahu): Add a NoOpHeadersHandler if needed.
-class QUICHE_EXPORT_PRIVATE EventForwarder
-    : public spdy::SpdyFramerVisitorInterface {
- public:
-  // Whether the forwarder can forward events to the receiver.
-  using ForwardPredicate = std::function<bool()>;
-
-  EventForwarder(ForwardPredicate can_forward,
-                 spdy::SpdyFramerVisitorInterface& receiver);
-
-  void OnError(Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error) override;
-  void OnCommonHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
-                      uint8_t flags) override;
-  void OnDataFrameHeader(spdy::SpdyStreamId stream_id, size_t length,
-                         bool fin) override;
-  void OnStreamFrameData(spdy::SpdyStreamId stream_id, const char* data,
-                         size_t len) override;
-  void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
-  void OnStreamPadLength(spdy::SpdyStreamId stream_id, size_t value) override;
-  void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
-  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      spdy::SpdyStreamId stream_id) override;
-  void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
-  void OnRstStream(spdy::SpdyStreamId stream_id,
-                   spdy::SpdyErrorCode error_code) override;
-  void OnSettings() override;
-  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck() override;
-  void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
-  void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
-                spdy::SpdyErrorCode error_code) override;
-  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
-  void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority, int weight,
-                 spdy::SpdyStreamId parent_stream_id, bool exclusive, bool fin,
-                 bool end) override;
-  void OnWindowUpdate(spdy::SpdyStreamId stream_id,
-                      int delta_window_size) override;
-  void OnPushPromise(spdy::SpdyStreamId stream_id,
-                     spdy::SpdyStreamId promised_stream_id, bool end) override;
-  void OnContinuation(spdy::SpdyStreamId stream_id, bool end) override;
-  void OnAltSvc(spdy::SpdyStreamId stream_id, absl::string_view origin,
-                const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
-                    altsvc_vector) override;
-  void OnPriority(spdy::SpdyStreamId stream_id,
-                  spdy::SpdyStreamId parent_stream_id, int weight,
-                  bool exclusive) override;
-  void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
-                        absl::string_view priority_field_value) override;
-  bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
-                      uint8_t frame_type) override;
-
- private:
-  ForwardPredicate can_forward_;
-  spdy::SpdyFramerVisitorInterface& receiver_;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_EVENT_FORWARDER_H_
diff --git a/http2/adapter/event_forwarder_test.cc b/http2/adapter/event_forwarder_test.cc
deleted file mode 100644
index 3374f5e..0000000
--- a/http2/adapter/event_forwarder_test.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-#include "http2/adapter/event_forwarder.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/mock_spdy_framer_visitor.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-constexpr absl::string_view some_data = "Here is some data for events";
-constexpr spdy::SpdyStreamId stream_id = 1;
-constexpr spdy::SpdyErrorCode error_code =
-    spdy::SpdyErrorCode::ERROR_CODE_ENHANCE_YOUR_CALM;
-constexpr size_t length = 42;
-
-TEST(EventForwarderTest, ForwardsEventsWithTruePredicate) {
-  spdy::test::MockSpdyFramerVisitor receiver;
-  receiver.DelegateHeaderHandling();
-  EventForwarder event_forwarder([]() { return true; }, receiver);
-
-  EXPECT_CALL(
-      receiver,
-      OnError(Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
-              std::string(some_data)));
-  event_forwarder.OnError(
-      Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
-      std::string(some_data));
-
-  EXPECT_CALL(receiver,
-              OnCommonHeader(stream_id, length, /*type=*/0x0, /*flags=*/0x1));
-  event_forwarder.OnCommonHeader(stream_id, length, /*type=*/0x0,
-                                 /*flags=*/0x1);
-
-  EXPECT_CALL(receiver, OnDataFrameHeader(stream_id, length, /*fin=*/true));
-  event_forwarder.OnDataFrameHeader(stream_id, length, /*fin=*/true);
-
-  EXPECT_CALL(receiver,
-              OnStreamFrameData(stream_id, some_data.data(), some_data.size()));
-  event_forwarder.OnStreamFrameData(stream_id, some_data.data(),
-                                    some_data.size());
-
-  EXPECT_CALL(receiver, OnStreamEnd(stream_id));
-  event_forwarder.OnStreamEnd(stream_id);
-
-  EXPECT_CALL(receiver, OnStreamPadLength(stream_id, length));
-  event_forwarder.OnStreamPadLength(stream_id, length);
-
-  EXPECT_CALL(receiver, OnStreamPadding(stream_id, length));
-  event_forwarder.OnStreamPadding(stream_id, length);
-
-  EXPECT_CALL(receiver, OnHeaderFrameStart(stream_id));
-  spdy::SpdyHeadersHandlerInterface* handler =
-      event_forwarder.OnHeaderFrameStart(stream_id);
-  EXPECT_EQ(handler, receiver.ReturnTestHeadersHandler(stream_id));
-
-  EXPECT_CALL(receiver, OnHeaderFrameEnd(stream_id));
-  event_forwarder.OnHeaderFrameEnd(stream_id);
-
-  EXPECT_CALL(receiver, OnRstStream(stream_id, error_code));
-  event_forwarder.OnRstStream(stream_id, error_code);
-
-  EXPECT_CALL(receiver, OnSettings());
-  event_forwarder.OnSettings();
-
-  EXPECT_CALL(
-      receiver,
-      OnSetting(spdy::SpdyKnownSettingsId::SETTINGS_MAX_CONCURRENT_STREAMS,
-                100));
-  event_forwarder.OnSetting(
-      spdy::SpdyKnownSettingsId::SETTINGS_MAX_CONCURRENT_STREAMS, 100);
-
-  EXPECT_CALL(receiver, OnSettingsEnd());
-  event_forwarder.OnSettingsEnd();
-
-  EXPECT_CALL(receiver, OnSettingsAck());
-  event_forwarder.OnSettingsAck();
-
-  EXPECT_CALL(receiver, OnPing(/*unique_id=*/42, /*is_ack=*/false));
-  event_forwarder.OnPing(/*unique_id=*/42, /*is_ack=*/false);
-
-  EXPECT_CALL(receiver, OnGoAway(stream_id, error_code));
-  event_forwarder.OnGoAway(stream_id, error_code);
-
-  EXPECT_CALL(receiver, OnGoAwayFrameData(some_data.data(), some_data.size()));
-  event_forwarder.OnGoAwayFrameData(some_data.data(), some_data.size());
-
-  EXPECT_CALL(
-      receiver,
-      OnHeaders(stream_id, /*has_priority=*/false, /*weight=*/42, stream_id + 2,
-                /*exclusive=*/false, /*fin=*/true, /*end=*/true));
-  event_forwarder.OnHeaders(stream_id, /*has_priority=*/false, /*weight=*/42,
-                            stream_id + 2, /*exclusive=*/false, /*fin=*/true,
-                            /*end=*/true);
-
-  EXPECT_CALL(receiver, OnWindowUpdate(stream_id, /*delta_window_size=*/42));
-  event_forwarder.OnWindowUpdate(stream_id, /*delta_window_size=*/42);
-
-  EXPECT_CALL(receiver, OnPushPromise(stream_id, stream_id + 1, /*end=*/true));
-  event_forwarder.OnPushPromise(stream_id, stream_id + 1, /*end=*/true);
-
-  EXPECT_CALL(receiver, OnContinuation(stream_id, /*end=*/true));
-  event_forwarder.OnContinuation(stream_id, /*end=*/true);
-
-  const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  EXPECT_CALL(receiver, OnAltSvc(stream_id, some_data, altsvc_vector));
-  event_forwarder.OnAltSvc(stream_id, some_data, altsvc_vector);
-
-  EXPECT_CALL(receiver, OnPriority(stream_id, stream_id + 2, /*weight=*/42,
-                                   /*exclusive=*/false));
-  event_forwarder.OnPriority(stream_id, stream_id + 2, /*weight=*/42,
-                             /*exclusive=*/false);
-
-  EXPECT_CALL(receiver, OnPriorityUpdate(stream_id, some_data));
-  event_forwarder.OnPriorityUpdate(stream_id, some_data);
-
-  EXPECT_CALL(receiver, OnUnknownFrame(stream_id, /*frame_type=*/0x4D));
-  event_forwarder.OnUnknownFrame(stream_id, /*frame_type=*/0x4D);
-}
-
-TEST(EventForwarderTest, DoesNotForwardEventsWithFalsePredicate) {
-  spdy::test::MockSpdyFramerVisitor receiver;
-  receiver.DelegateHeaderHandling();
-  EventForwarder event_forwarder([]() { return false; }, receiver);
-
-  EXPECT_CALL(receiver, OnError).Times(0);
-  event_forwarder.OnError(
-      Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
-      std::string(some_data));
-
-  EXPECT_CALL(receiver, OnCommonHeader).Times(0);
-  event_forwarder.OnCommonHeader(stream_id, length, /*type=*/0x0,
-                                 /*flags=*/0x1);
-
-  EXPECT_CALL(receiver, OnDataFrameHeader).Times(0);
-  event_forwarder.OnDataFrameHeader(stream_id, length, /*fin=*/true);
-
-  EXPECT_CALL(receiver, OnStreamFrameData).Times(0);
-  event_forwarder.OnStreamFrameData(stream_id, some_data.data(),
-                                    some_data.size());
-
-  EXPECT_CALL(receiver, OnStreamEnd).Times(0);
-  event_forwarder.OnStreamEnd(stream_id);
-
-  EXPECT_CALL(receiver, OnStreamPadLength).Times(0);
-  event_forwarder.OnStreamPadLength(stream_id, length);
-
-  EXPECT_CALL(receiver, OnStreamPadding).Times(0);
-  event_forwarder.OnStreamPadding(stream_id, length);
-
-  EXPECT_CALL(receiver, OnHeaderFrameStart(stream_id));
-  spdy::SpdyHeadersHandlerInterface* handler =
-      event_forwarder.OnHeaderFrameStart(stream_id);
-  EXPECT_EQ(handler, receiver.ReturnTestHeadersHandler(stream_id));
-
-  EXPECT_CALL(receiver, OnHeaderFrameEnd).Times(0);
-  event_forwarder.OnHeaderFrameEnd(stream_id);
-
-  EXPECT_CALL(receiver, OnRstStream).Times(0);
-  event_forwarder.OnRstStream(stream_id, error_code);
-
-  EXPECT_CALL(receiver, OnSettings).Times(0);
-  event_forwarder.OnSettings();
-
-  EXPECT_CALL(receiver, OnSetting).Times(0);
-  event_forwarder.OnSetting(
-      spdy::SpdyKnownSettingsId::SETTINGS_MAX_CONCURRENT_STREAMS, 100);
-
-  EXPECT_CALL(receiver, OnSettingsEnd).Times(0);
-  event_forwarder.OnSettingsEnd();
-
-  EXPECT_CALL(receiver, OnSettingsAck).Times(0);
-  event_forwarder.OnSettingsAck();
-
-  EXPECT_CALL(receiver, OnPing).Times(0);
-  event_forwarder.OnPing(/*unique_id=*/42, /*is_ack=*/false);
-
-  EXPECT_CALL(receiver, OnGoAway).Times(0);
-  event_forwarder.OnGoAway(stream_id, error_code);
-
-  EXPECT_CALL(receiver, OnGoAwayFrameData).Times(0);
-  event_forwarder.OnGoAwayFrameData(some_data.data(), some_data.size());
-
-  EXPECT_CALL(receiver, OnHeaders).Times(0);
-  event_forwarder.OnHeaders(stream_id, /*has_priority=*/false, /*weight=*/42,
-                            stream_id + 2, /*exclusive=*/false, /*fin=*/true,
-                            /*end=*/true);
-
-  EXPECT_CALL(receiver, OnWindowUpdate).Times(0);
-  event_forwarder.OnWindowUpdate(stream_id, /*delta_window_size=*/42);
-
-  EXPECT_CALL(receiver, OnPushPromise).Times(0);
-  event_forwarder.OnPushPromise(stream_id, stream_id + 1, /*end=*/true);
-
-  EXPECT_CALL(receiver, OnContinuation).Times(0);
-  event_forwarder.OnContinuation(stream_id, /*end=*/true);
-
-  EXPECT_CALL(receiver, OnAltSvc).Times(0);
-  const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  event_forwarder.OnAltSvc(stream_id, some_data, altsvc_vector);
-
-  EXPECT_CALL(receiver, OnPriority).Times(0);
-  event_forwarder.OnPriority(stream_id, stream_id + 2, /*weight=*/42,
-                             /*exclusive=*/false);
-
-  EXPECT_CALL(receiver, OnPriorityUpdate).Times(0);
-  event_forwarder.OnPriorityUpdate(stream_id, some_data);
-
-  EXPECT_CALL(receiver, OnUnknownFrame).Times(0);
-  event_forwarder.OnUnknownFrame(stream_id, /*frame_type=*/0x4D);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/header_validator.cc b/http2/adapter/header_validator.cc
deleted file mode 100644
index d269501..0000000
--- a/http2/adapter/header_validator.cc
+++ /dev/null
@@ -1,257 +0,0 @@
-#include "http2/adapter/header_validator.h"
-
-#include <array>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/numbers.h"
-#include "http2/http2_constants.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace http2 {
-namespace adapter {
-
-namespace {
-
-const absl::string_view kHttp2HeaderNameAllowedChars =
-    "!#$%&\'*+-.0123456789"
-    "^_`abcdefghijklmnopqrstuvwxyz|~";
-
-const absl::string_view kHttp2HeaderValueAllowedChars =
-    "\t "
-    "!\"#$%&'()*+,-./"
-    "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
-    "abcdefghijklmnopqrstuvwxyz{|}~";
-
-const absl::string_view kHttp2StatusValueAllowedChars = "0123456789";
-
-const absl::string_view kValidAuthorityChars =
-    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%!$&'()["
-    "]*+,;=:";
-
-using CharMap = std::array<bool, 256>;
-
-CharMap BuildValidCharMap(absl::string_view valid_chars) {
-  CharMap map;
-  map.fill(false);
-  for (char c : valid_chars) {
-    // Cast to uint8_t, guaranteed to have 8 bits. A char may have more, leading
-    // to possible indices above 256.
-    map[static_cast<uint8_t>(c)] = true;
-  }
-  return map;
-}
-
-bool AllCharsInMap(absl::string_view str, const CharMap& map) {
-  for (char c : str) {
-    if (!map[static_cast<uint8_t>(c)]) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool IsValidHeaderName(absl::string_view name) {
-  static const CharMap valid_chars =
-      BuildValidCharMap(kHttp2HeaderNameAllowedChars);
-  return AllCharsInMap(name, valid_chars);
-}
-
-bool IsValidHeaderValue(absl::string_view value) {
-  static const CharMap valid_chars =
-      BuildValidCharMap(kHttp2HeaderValueAllowedChars);
-  return AllCharsInMap(value, valid_chars);
-}
-
-bool IsValidStatus(absl::string_view status) {
-  static const CharMap valid_chars =
-      BuildValidCharMap(kHttp2StatusValueAllowedChars);
-  return AllCharsInMap(status, valid_chars);
-}
-
-bool ValidateRequestHeaders(const std::vector<std::string>& pseudo_headers,
-                            absl::string_view method, absl::string_view path,
-                            bool allow_connect) {
-  QUICHE_VLOG(2) << "Request pseudo-headers: ["
-                 << absl::StrJoin(pseudo_headers, ", ")
-                 << "], allow_connect: " << allow_connect
-                 << ", method: " << method << ", path: " << path;
-  if (allow_connect && method == "CONNECT") {
-    static const std::vector<std::string>* kConnectHeaders =
-        new std::vector<std::string>(
-            {":authority", ":method", ":path", ":protocol", ":scheme"});
-    return pseudo_headers == *kConnectHeaders;
-  }
-
-  if (path.empty()) {
-    return false;
-  }
-  if (path == "*") {
-    if (method != "OPTIONS") {
-      return false;
-    }
-  } else if (path[0] != '/') {
-    return false;
-  }
-
-  static const std::vector<std::string>* kRequiredHeaders =
-      new std::vector<std::string>(
-          {":authority", ":method", ":path", ":scheme"});
-  return pseudo_headers == *kRequiredHeaders;
-}
-
-bool ValidateRequestTrailers(const std::vector<std::string>& pseudo_headers) {
-  return pseudo_headers.empty();
-}
-
-bool ValidateResponseHeaders(const std::vector<std::string>& pseudo_headers) {
-  static const std::vector<std::string>* kRequiredHeaders =
-      new std::vector<std::string>({":status"});
-  return pseudo_headers == *kRequiredHeaders;
-}
-
-bool ValidateResponseTrailers(const std::vector<std::string>& pseudo_headers) {
-  return pseudo_headers.empty();
-}
-
-}  // namespace
-
-void HeaderValidator::StartHeaderBlock() {
-  pseudo_headers_.clear();
-  status_.clear();
-  method_.clear();
-  path_.clear();
-  authority_ = absl::nullopt;
-  content_length_.reset();
-}
-
-HeaderValidator::HeaderStatus HeaderValidator::ValidateSingleHeader(
-    absl::string_view key, absl::string_view value) {
-  if (key.empty()) {
-    return HEADER_FIELD_INVALID;
-  }
-  if (max_field_size_.has_value() &&
-      key.size() + value.size() > max_field_size_.value()) {
-    QUICHE_VLOG(2) << "Header field size is " << key.size() + value.size()
-                   << ", exceeds max size of " << max_field_size_.value();
-    return HEADER_FIELD_TOO_LONG;
-  }
-  const absl::string_view validated_key = key[0] == ':' ? key.substr(1) : key;
-  if (!IsValidHeaderName(validated_key)) {
-    QUICHE_VLOG(2) << "invalid chars in header name: ["
-                   << absl::CEscape(validated_key) << "]";
-    return HEADER_FIELD_INVALID;
-  }
-  if (!IsValidHeaderValue(value)) {
-    QUICHE_VLOG(2) << "invalid chars in header value: [" << absl::CEscape(value)
-                   << "]";
-    return HEADER_FIELD_INVALID;
-  }
-  if (key[0] == ':') {
-    if (key == ":status") {
-      if (value.size() != 3 || !IsValidStatus(value)) {
-        QUICHE_VLOG(2) << "malformed status value: [" << absl::CEscape(value)
-                       << "]";
-        return HEADER_FIELD_INVALID;
-      }
-      if (value == "101") {
-        // Switching protocols is not allowed on a HTTP/2 stream.
-        return HEADER_FIELD_INVALID;
-      }
-      status_ = std::string(value);
-    } else if (key == ":method") {
-      method_ = std::string(value);
-    } else if (key == ":authority" && !ValidateAndSetAuthority(value)) {
-      return HEADER_FIELD_INVALID;
-    } else if (key == ":path") {
-      if (value.empty()) {
-        // For now, reject an empty path regardless of scheme.
-        return HEADER_FIELD_INVALID;
-      }
-      path_ = std::string(value);
-    }
-    pseudo_headers_.push_back(std::string(key));
-  } else if (key == "host") {
-    if (!status_.empty()) {
-      // Response headers can contain "Host".
-    } else {
-      if (!authority_.has_value()) {
-        pseudo_headers_.push_back(std::string(":authority"));
-      }
-      if (!ValidateAndSetAuthority(value)) {
-        return HEADER_FIELD_INVALID;
-      }
-    }
-  } else if (key == "content-length") {
-    const bool success = HandleContentLength(value);
-    if (!success) {
-      return HEADER_FIELD_INVALID;
-    }
-  } else if (key == "te" && value != "trailers") {
-    return HEADER_FIELD_INVALID;
-  } else if (key == "upgrade" || GetInvalidHttp2HeaderSet().contains(key)) {
-    // TODO(b/78024822): Remove the "upgrade" here once it's added to
-    // GetInvalidHttp2HeaderSet().
-    return HEADER_FIELD_INVALID;
-  }
-  return HEADER_OK;
-}
-
-// Returns true if all required pseudoheaders and no extra pseudoheaders are
-// present for the given header type.
-bool HeaderValidator::FinishHeaderBlock(HeaderType type) {
-  std::sort(pseudo_headers_.begin(), pseudo_headers_.end());
-  switch (type) {
-    case HeaderType::REQUEST:
-      return ValidateRequestHeaders(pseudo_headers_, method_, path_,
-                                    allow_connect_);
-    case HeaderType::REQUEST_TRAILER:
-      return ValidateRequestTrailers(pseudo_headers_);
-    case HeaderType::RESPONSE_100:
-    case HeaderType::RESPONSE:
-      return ValidateResponseHeaders(pseudo_headers_);
-    case HeaderType::RESPONSE_TRAILER:
-      return ValidateResponseTrailers(pseudo_headers_);
-  }
-  return false;
-}
-
-bool HeaderValidator::HandleContentLength(absl::string_view value) {
-  if (value.empty()) {
-    return false;
-  }
-
-  if (status_ == "204" && value != "0") {
-    // There should be no body in a "204 No Content" response.
-    return false;
-  }
-  if (!status_.empty() && status_[0] == '1' && value != "0") {
-    // There should also be no body in a 1xx response.
-    return false;
-  }
-
-  size_t content_length = 0;
-  const bool valid = absl::SimpleAtoi(value, &content_length);
-  if (!valid) {
-    return false;
-  }
-
-  content_length_ = content_length;
-  return true;
-}
-
-// Returns whether `authority` contains only characters from the `host` ABNF
-// from RFC 3986 section 3.2.2.
-bool HeaderValidator::ValidateAndSetAuthority(absl::string_view authority) {
-  static const CharMap valid_chars = BuildValidCharMap(kValidAuthorityChars);
-  if (!AllCharsInMap(authority, valid_chars)) {
-    return false;
-  }
-  if (authority_.has_value() && authority != authority_.value()) {
-    return false;
-  }
-  authority_ = std::string(authority);
-  return true;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/header_validator.h b/http2/adapter/header_validator.h
deleted file mode 100644
index 8b8744e..0000000
--- a/http2/adapter/header_validator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_H_
-#define QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_H_
-
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-enum class HeaderType : uint8_t {
-  REQUEST,
-  REQUEST_TRAILER,
-  RESPONSE_100,
-  RESPONSE,
-  RESPONSE_TRAILER,
-};
-
-class QUICHE_EXPORT_PRIVATE HeaderValidator {
- public:
-  HeaderValidator() {}
-
-  void SetMaxFieldSize(uint32_t field_size) { max_field_size_ = field_size; }
-
-  // If called, this validator will allow the `:protocol` pseudo-header, as
-  // described in RFC 8441.
-  void AllowConnect() { allow_connect_ = true; }
-
-  void StartHeaderBlock();
-
-  enum HeaderStatus {
-    HEADER_OK,
-    HEADER_FIELD_INVALID,
-    HEADER_FIELD_TOO_LONG,
-  };
-  HeaderStatus ValidateSingleHeader(absl::string_view key,
-                                    absl::string_view value);
-
-  // Returns true if all required pseudoheaders and no extra pseudoheaders are
-  // present for the given header type.
-  bool FinishHeaderBlock(HeaderType type);
-
-  // For responses, returns the value of the ":status" header, if present.
-  absl::string_view status_header() const { return status_; }
-
-  absl::optional<size_t> content_length() const { return content_length_; }
-
- private:
-  bool HandleContentLength(absl::string_view value);
-  bool ValidateAndSetAuthority(absl::string_view authority);
-
-  std::vector<std::string> pseudo_headers_;
-  absl::optional<std::string> authority_ = absl::nullopt;
-  std::string status_;
-  std::string method_;
-  std::string path_;
-  absl::optional<size_t> max_field_size_;
-  absl::optional<size_t> content_length_;
-  bool allow_connect_ = false;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_H_
diff --git a/http2/adapter/header_validator_test.cc b/http2/adapter/header_validator_test.cc
deleted file mode 100644
index a6d0326..0000000
--- a/http2/adapter/header_validator_test.cc
+++ /dev/null
@@ -1,563 +0,0 @@
-#include "http2/adapter/header_validator.h"
-
-#include <utility>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "absl/types/optional.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-using ::testing::Optional;
-
-using Header = std::pair<absl::string_view, absl::string_view>;
-constexpr Header kSampleRequestPseudoheaders[] = {{":authority", "www.foo.com"},
-                                                  {":method", "GET"},
-                                                  {":path", "/foo"},
-                                                  {":scheme", "https"}};
-
-TEST(HeaderValidatorTest, HeaderNameEmpty) {
-  HeaderValidator v;
-  HeaderValidator::HeaderStatus status = v.ValidateSingleHeader("", "value");
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-}
-
-TEST(HeaderValidatorTest, HeaderValueEmpty) {
-  HeaderValidator v;
-  HeaderValidator::HeaderStatus status = v.ValidateSingleHeader("name", "");
-  EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-}
-
-TEST(HeaderValidatorTest, ExceedsMaxSize) {
-  HeaderValidator v;
-  v.SetMaxFieldSize(64u);
-  HeaderValidator::HeaderStatus status =
-      v.ValidateSingleHeader("name", "value");
-  EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-  status = v.ValidateSingleHeader(
-      "name2",
-      "Antidisestablishmentariansism is supercalifragilisticexpialodocious.");
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_TOO_LONG, status);
-}
-
-TEST(HeaderValidatorTest, NameHasInvalidChar) {
-  HeaderValidator v;
-  for (const bool is_pseudo_header : {true, false}) {
-    // These characters should be allowed. (Not exhaustive.)
-    for (const char* c : {"!", "3", "a", "_", "|", "~"}) {
-      const std::string name = is_pseudo_header ? absl::StrCat(":met", c, "hod")
-                                                : absl::StrCat("na", c, "me");
-      HeaderValidator::HeaderStatus status =
-          v.ValidateSingleHeader(name, "value");
-      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-    }
-    // These should not. (Not exhaustive.)
-    for (const char* c : {"\\", "<", ";", "[", "=", " ", "\r", "\n", ",", "\"",
-                          "\x1F", "\x91"}) {
-      const std::string name = is_pseudo_header ? absl::StrCat(":met", c, "hod")
-                                                : absl::StrCat("na", c, "me");
-      HeaderValidator::HeaderStatus status =
-          v.ValidateSingleHeader(name, "value");
-      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-    }
-    // Test nul separately.
-    {
-      const absl::string_view name = is_pseudo_header
-                                         ? absl::string_view(":met\0hod", 8)
-                                         : absl::string_view("na\0me", 5);
-      HeaderValidator::HeaderStatus status =
-          v.ValidateSingleHeader(name, "value");
-      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-    }
-    // Uppercase characters in header names should not be allowed.
-    const std::string uc_name = is_pseudo_header ? ":Method" : "Name";
-    HeaderValidator::HeaderStatus status =
-        v.ValidateSingleHeader(uc_name, "value");
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-  }
-}
-
-TEST(HeaderValidatorTest, ValueHasInvalidChar) {
-  HeaderValidator v;
-  // These characters should be allowed. (Not exhaustive.)
-  for (const char* c :
-       {"!", "3", "a", "_", "|", "~", "\\", "<", ";", "[", "=", "A", "\t"}) {
-    HeaderValidator::HeaderStatus status =
-        v.ValidateSingleHeader("name", absl::StrCat("val", c, "ue"));
-    EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-  }
-  // These should not.
-  for (const char* c : {"\r", "\n"}) {
-    HeaderValidator::HeaderStatus status =
-        v.ValidateSingleHeader("name", absl::StrCat("val", c, "ue"));
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-  }
-  // Test nul separately.
-  {
-    HeaderValidator::HeaderStatus status =
-        v.ValidateSingleHeader("name", absl::string_view("val\0ue", 6));
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-  }
-}
-
-TEST(HeaderValidatorTest, StatusHasInvalidChar) {
-  HeaderValidator v;
-
-  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
-    // When `:status` has a non-digit value, validation will fail.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-              v.ValidateSingleHeader(":status", "bar"));
-    EXPECT_FALSE(v.FinishHeaderBlock(type));
-
-    // When `:status` is too short, validation will fail.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-              v.ValidateSingleHeader(":status", "10"));
-    EXPECT_FALSE(v.FinishHeaderBlock(type));
-
-    // When `:status` is too long, validation will fail.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-              v.ValidateSingleHeader(":status", "9000"));
-    EXPECT_FALSE(v.FinishHeaderBlock(type));
-
-    // When `:status` is just right, validation will succeed.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(":status", "400"));
-    EXPECT_TRUE(v.FinishHeaderBlock(type));
-  }
-}
-
-TEST(HeaderValidatorTest, AuthorityHasInvalidChar) {
-  for (absl::string_view key : {":authority", "host"}) {
-    // These characters should be allowed. (Not exhaustive.)
-    for (const absl::string_view c : {"1", "-", "!", ":", "+", "=", ","}) {
-      HeaderValidator v;
-      v.StartHeaderBlock();
-      HeaderValidator::HeaderStatus status =
-          v.ValidateSingleHeader(key, absl::StrCat("ho", c, "st.example.com"));
-      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-    }
-    // These should not.
-    for (const absl::string_view c : {"\r", "\n", "|", "\\", "`"}) {
-      HeaderValidator v;
-      v.StartHeaderBlock();
-      HeaderValidator::HeaderStatus status =
-          v.ValidateSingleHeader(key, absl::StrCat("ho", c, "st.example.com"));
-      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
-    }
-
-    {
-      // IPv4 example
-      HeaderValidator v;
-      v.StartHeaderBlock();
-      HeaderValidator::HeaderStatus status =
-          v.ValidateSingleHeader(key, "123.45.67.89");
-      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-    }
-
-    {
-      // IPv6 examples
-      HeaderValidator v;
-      v.StartHeaderBlock();
-      HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(
-          key, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
-      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-      HeaderValidator v2;
-      v2.StartHeaderBlock();
-      status = v2.ValidateSingleHeader(key, "[::1]:80");
-      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-    }
-
-    {
-      // Empty field
-      HeaderValidator v;
-      v.StartHeaderBlock();
-      HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, "");
-      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
-    }
-  }
-}
-
-TEST(HeaderValidatorTest, RequestHostAndAuthority) {
-  HeaderValidator v;
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(to_add.first, to_add.second));
-  }
-  // If both "host" and ":authority" have the same value, validation succeeds.
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("host", "www.foo.com"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(to_add.first, to_add.second));
-  }
-  // If "host" and ":authority" have different values, validation fails.
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("host", "www.bar.com"));
-}
-
-TEST(HeaderValidatorTest, RequestPseudoHeaders) {
-  HeaderValidator v;
-  for (Header to_skip : kSampleRequestPseudoheaders) {
-    v.StartHeaderBlock();
-    for (Header to_add : kSampleRequestPseudoheaders) {
-      if (to_add != to_skip) {
-        EXPECT_EQ(HeaderValidator::HEADER_OK,
-                  v.ValidateSingleHeader(to_add.first, to_add.second));
-      }
-    }
-    // When any pseudo-header is missing, final validation will fail.
-    EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-  }
-
-  // When all pseudo-headers are present, final validation will succeed.
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(to_add.first, to_add.second));
-  }
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  // When an extra pseudo-header is present, final validation will fail.
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(to_add.first, to_add.second));
-  }
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":extra", "blah"));
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  // When a required pseudo-header is repeated, final validation will fail.
-  for (Header to_repeat : kSampleRequestPseudoheaders) {
-    v.StartHeaderBlock();
-    for (Header to_add : kSampleRequestPseudoheaders) {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, to_add.second));
-      if (to_add == to_repeat) {
-        EXPECT_EQ(HeaderValidator::HEADER_OK,
-                  v.ValidateSingleHeader(to_add.first, to_add.second));
-      }
-    }
-    EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-  }
-}
-
-TEST(HeaderValidatorTest, WebsocketPseudoHeaders) {
-  HeaderValidator v;
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(to_add.first, to_add.second));
-  }
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":protocol", "websocket"));
-  // At this point, `:protocol` is treated as an extra pseudo-header.
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  // Future header blocks may send the `:protocol` pseudo-header for CONNECT
-  // requests.
-  v.AllowConnect();
-
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(to_add.first, to_add.second));
-  }
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":protocol", "websocket"));
-  // The method is not "CONNECT", so `:protocol` is still treated as an extra
-  // pseudo-header.
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    if (to_add.first == ":method") {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, "CONNECT"));
-    } else {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, to_add.second));
-    }
-  }
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":protocol", "websocket"));
-  // After allowing the method, `:protocol` is acepted for CONNECT requests.
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
-}
-
-TEST(HeaderValidatorTest, AsteriskPathPseudoHeader) {
-  HeaderValidator v;
-
-  // An asterisk :path should not be allowed for non-OPTIONS requests.
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    if (to_add.first == ":path") {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, "*"));
-    } else {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, to_add.second));
-    }
-  }
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  // An asterisk :path should be allowed for OPTIONS requests.
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    if (to_add.first == ":path") {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, "*"));
-    } else if (to_add.first == ":method") {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, "OPTIONS"));
-    } else {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, to_add.second));
-    }
-  }
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
-}
-
-TEST(HeaderValidatorTest, InvalidPathPseudoHeader) {
-  HeaderValidator v;
-
-  // An empty path should fail on single header validation and finish.
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    if (to_add.first == ":path") {
-      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-                v.ValidateSingleHeader(to_add.first, ""));
-    } else {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, to_add.second));
-    }
-  }
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-
-  // A path that does not start with a slash should fail on finish.
-  v.StartHeaderBlock();
-  for (Header to_add : kSampleRequestPseudoheaders) {
-    if (to_add.first == ":path") {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, "shawarma"));
-    } else {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(to_add.first, to_add.second));
-    }
-  }
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
-}
-
-TEST(HeaderValidatorTest, ResponsePseudoHeaders) {
-  HeaderValidator v;
-
-  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
-    // When `:status` is missing, validation will fail.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
-    EXPECT_FALSE(v.FinishHeaderBlock(type));
-
-    // When all pseudo-headers are present, final validation will succeed.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(":status", "199"));
-    EXPECT_TRUE(v.FinishHeaderBlock(type));
-    EXPECT_EQ("199", v.status_header());
-
-    // When `:status` is repeated, validation will fail.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(":status", "199"));
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(":status", "299"));
-    EXPECT_FALSE(v.FinishHeaderBlock(type));
-
-    // When an extra pseudo-header is present, final validation will fail.
-    v.StartHeaderBlock();
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(":status", "199"));
-    EXPECT_EQ(HeaderValidator::HEADER_OK,
-              v.ValidateSingleHeader(":extra", "blorp"));
-    EXPECT_FALSE(v.FinishHeaderBlock(type));
-  }
-}
-
-TEST(HeaderValidatorTest, ResponseWithHost) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "200"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("host", "myserver.com"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
-}
-
-TEST(HeaderValidatorTest, Response204) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "204"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("x-content", "is not present"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
-}
-
-TEST(HeaderValidatorTest, Response204WithContentLengthZero) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "204"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("x-content", "is not present"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("content-length", "0"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
-}
-
-TEST(HeaderValidatorTest, Response204WithContentLength) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "204"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("x-content", "is not present"));
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("content-length", "1"));
-}
-
-TEST(HeaderValidatorTest, Response100) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "100"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("x-content", "is not present"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
-}
-
-TEST(HeaderValidatorTest, Response100WithContentLengthZero) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "100"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("x-content", "is not present"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("content-length", "0"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
-}
-
-TEST(HeaderValidatorTest, Response100WithContentLength) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "100"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("x-content", "is not present"));
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("content-length", "1"));
-}
-
-TEST(HeaderValidatorTest, ResponseTrailerPseudoHeaders) {
-  HeaderValidator v;
-
-  // When no pseudo-headers are present, validation will succeed.
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
-  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
-
-  // When any pseudo-header is present, final validation will fail.
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader(":status", "200"));
-  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
-  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
-}
-
-TEST(HeaderValidatorTest, ValidContentLength) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(v.content_length(), absl::nullopt);
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("content-length", "41"));
-  EXPECT_THAT(v.content_length(), Optional(41));
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(v.content_length(), absl::nullopt);
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("content-length", "42"));
-  EXPECT_THAT(v.content_length(), Optional(42));
-}
-
-TEST(HeaderValidatorTest, InvalidContentLength) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(v.content_length(), absl::nullopt);
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("content-length", ""));
-  EXPECT_EQ(v.content_length(), absl::nullopt);
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("content-length", "nan"));
-  EXPECT_EQ(v.content_length(), absl::nullopt);
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("content-length", "-42"));
-  EXPECT_EQ(v.content_length(), absl::nullopt);
-  // End on a positive note.
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("content-length", "42"));
-  EXPECT_THAT(v.content_length(), Optional(42));
-}
-
-TEST(HeaderValidatorTest, TeHeader) {
-  HeaderValidator v;
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_OK,
-            v.ValidateSingleHeader("te", "trailers"));
-
-  v.StartHeaderBlock();
-  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-            v.ValidateSingleHeader("te", "trailers, deflate"));
-}
-
-TEST(HeaderValidatorTest, ConnectionSpecificHeaders) {
-  const std::vector<Header> connection_headers = {
-      {"connection", "keep-alive"}, {"proxy-connection", "keep-alive"},
-      {"keep-alive", "timeout=42"}, {"transfer-encoding", "chunked"},
-      {"upgrade", "h2c"},
-  };
-  for (const auto& [connection_key, connection_value] : connection_headers) {
-    HeaderValidator v;
-    v.StartHeaderBlock();
-    for (const auto& [sample_key, sample_value] : kSampleRequestPseudoheaders) {
-      EXPECT_EQ(HeaderValidator::HEADER_OK,
-                v.ValidateSingleHeader(sample_key, sample_value));
-    }
-    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
-              v.ValidateSingleHeader(connection_key, connection_value));
-  }
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/http2_adapter.h b/http2/adapter/http2_adapter.h
deleted file mode 100644
index 8c231d1..0000000
--- a/http2/adapter/http2_adapter.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_
-#define QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-#include "http2/adapter/data_source.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_session.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-// Http2Adapter is an HTTP/2-processing class that exposes an interface similar
-// to the nghttp2 library for processing the HTTP/2 wire format. As nghttp2
-// parses HTTP/2 frames and invokes callbacks on Http2Adapter, Http2Adapter then
-// invokes corresponding callbacks on its passed-in Http2VisitorInterface.
-// Http2Adapter is a base class shared between client-side and server-side
-// implementations.
-class QUICHE_EXPORT_PRIVATE Http2Adapter {
- public:
-  Http2Adapter(const Http2Adapter&) = delete;
-  Http2Adapter& operator=(const Http2Adapter&) = delete;
-
-  virtual ~Http2Adapter() {}
-
-  virtual bool IsServerSession() const = 0;
-
-  virtual bool want_read() const = 0;
-  virtual bool want_write() const = 0;
-
-  // Processes the incoming |bytes| as HTTP/2 and invokes callbacks on the
-  // |visitor_| as appropriate.
-  virtual int64_t ProcessBytes(absl::string_view bytes) = 0;
-
-  // Submits the |settings| to be written to the peer, e.g., as part of the
-  // HTTP/2 connection preface.
-  virtual void SubmitSettings(absl::Span<const Http2Setting> settings) = 0;
-
-  // Submits a PRIORITY frame for the given stream.
-  virtual void SubmitPriorityForStream(Http2StreamId stream_id,
-                                       Http2StreamId parent_stream_id,
-                                       int weight,
-                                       bool exclusive) = 0;
-
-  // Submits a PING on the connection.
-  virtual void SubmitPing(Http2PingId ping_id) = 0;
-
-  // Starts a graceful shutdown. A no-op for clients.
-  virtual void SubmitShutdownNotice() = 0;
-
-  // Submits a GOAWAY on the connection. Note that |last_accepted_stream_id|
-  // refers to stream IDs initiated by the peer. For a server sending this
-  // frame, this last stream ID must be odd (or 0).
-  virtual void SubmitGoAway(Http2StreamId last_accepted_stream_id,
-                            Http2ErrorCode error_code,
-                            absl::string_view opaque_data) = 0;
-
-  // Submits a WINDOW_UPDATE for the given stream (a |stream_id| of 0 indicates
-  // a connection-level WINDOW_UPDATE).
-  virtual void SubmitWindowUpdate(Http2StreamId stream_id,
-                                  int window_increment) = 0;
-
-  // Submits a RST_STREAM for the given |stream_id| and |error_code|.
-  virtual void SubmitRst(Http2StreamId stream_id,
-                         Http2ErrorCode error_code) = 0;
-
-  // Submits a sequence of METADATA frames for the given stream. A |stream_id|
-  // of 0 indicates connection-level METADATA.
-  virtual void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
-                              std::unique_ptr<MetadataSource> source) = 0;
-
-  // Invokes the visitor's OnReadyToSend() method for serialized frame data.
-  // Returns 0 on success.
-  virtual int Send() = 0;
-
-  // Returns the connection-level flow control window advertised by the peer.
-  virtual int GetSendWindowSize() const = 0;
-
-  // Returns the stream-level flow control window advertised by the peer.
-  virtual int GetStreamSendWindowSize(Http2StreamId stream_id) const = 0;
-
-  // Returns the current upper bound on the flow control receive window for this
-  // stream. This value does not account for data received from the peer.
-  virtual int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const = 0;
-
-  // Returns the amount of data a peer could send on a given stream. This is
-  // the outstanding stream receive window.
-  virtual int GetStreamReceiveWindowSize(Http2StreamId stream_id) const = 0;
-
-  // Returns the total amount of data a peer could send on the connection. This
-  // is the outstanding connection receive window.
-  virtual int GetReceiveWindowSize() const = 0;
-
-  // Returns the size of the HPACK encoder's dynamic table, including the
-  // per-entry overhead from the specification.
-  virtual int GetHpackEncoderDynamicTableSize() const = 0;
-
-  // Returns the size of the HPACK decoder's dynamic table, including the
-  // per-entry overhead from the specification.
-  virtual int GetHpackDecoderDynamicTableSize() const = 0;
-
-  // Gets the highest stream ID value seen in a frame received by this endpoint.
-  // This method is only guaranteed to work for server endpoints.
-  virtual Http2StreamId GetHighestReceivedStreamId() const = 0;
-
-  // Marks the given amount of data as consumed for the given stream, which
-  // enables the implementation layer to send WINDOW_UPDATEs as appropriate.
-  virtual void MarkDataConsumedForStream(Http2StreamId stream_id,
-                                         size_t num_bytes) = 0;
-
-  // Returns the assigned stream ID if the operation succeeds. Otherwise,
-  // returns a negative integer indicating an error code. |data_source| may be
-  // nullptr if the request does not have a body.
-  virtual int32_t SubmitRequest(absl::Span<const Header> headers,
-                                std::unique_ptr<DataFrameSource> data_source,
-                                void* user_data) = 0;
-
-  // Returns 0 on success. |data_source| may be nullptr if the response does not
-  // have a body.
-  virtual int SubmitResponse(Http2StreamId stream_id,
-                             absl::Span<const Header> headers,
-                             std::unique_ptr<DataFrameSource> data_source) = 0;
-
-  // Queues trailers to be sent after any outstanding data on the stream with ID
-  // |stream_id|. Returns 0 on success.
-  virtual int SubmitTrailer(Http2StreamId stream_id,
-                            absl::Span<const Header> trailers) = 0;
-
-  // Sets a user data pointer for the given stream. Can be called after
-  // SubmitRequest/SubmitResponse, or after receiving any frame for a given
-  // stream.
-  virtual void SetStreamUserData(Http2StreamId stream_id, void* user_data) = 0;
-
-  // Returns nullptr if the stream does not exist, or if stream user data has
-  // not been set.
-  virtual void* GetStreamUserData(Http2StreamId stream_id) = 0;
-
-  // Resumes a stream that was previously blocked (for example, due to
-  // DataFrameSource::SelectPayloadLength() returning kBlocked). Returns true if
-  // the stream was successfully resumed.
-  virtual bool ResumeStream(Http2StreamId stream_id) = 0;
-
- protected:
-  // Subclasses should expose a public factory method for constructing and
-  // initializing (via Initialize()) adapter instances.
-  explicit Http2Adapter(Http2VisitorInterface& visitor) : visitor_(visitor) {}
-
-  // Accessors. Do not transfer ownership.
-  Http2VisitorInterface& visitor() { return visitor_; }
-
- private:
-  // Http2Adapter will invoke callbacks upon the |visitor_| while processing.
-  Http2VisitorInterface& visitor_;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_
diff --git a/http2/adapter/http2_protocol.cc b/http2/adapter/http2_protocol.cc
deleted file mode 100644
index 0f3c0d7..0000000
--- a/http2/adapter/http2_protocol.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "http2/adapter/http2_protocol.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-
-namespace http2 {
-namespace adapter {
-
-const char kHttp2MethodPseudoHeader[] = ":method";
-const char kHttp2SchemePseudoHeader[] = ":scheme";
-const char kHttp2AuthorityPseudoHeader[] = ":authority";
-const char kHttp2PathPseudoHeader[] = ":path";
-const char kHttp2StatusPseudoHeader[] = ":status";
-
-const uint8_t kMetadataFrameType = 0x4d;
-const uint8_t kMetadataEndFlag = 0x04;
-const uint16_t kMetadataExtensionId = 0x4d44;
-
-std::pair<absl::string_view, bool> GetStringView(const HeaderRep& rep) {
-  if (absl::holds_alternative<absl::string_view>(rep)) {
-    return std::make_pair(absl::get<absl::string_view>(rep), true);
-  } else {
-    absl::string_view view = absl::get<std::string>(rep);
-    return std::make_pair(view, false);
-  }
-}
-
-bool operator==(const Http2Setting& a, const Http2Setting& b) {
-  return a.id == b.id && a.value == b.value;
-}
-
-absl::string_view Http2SettingsIdToString(uint16_t id) {
-  switch (id) {
-    case Http2KnownSettingsId::HEADER_TABLE_SIZE:
-      return "SETTINGS_HEADER_TABLE_SIZE";
-    case Http2KnownSettingsId::ENABLE_PUSH:
-      return "SETTINGS_ENABLE_PUSH";
-    case Http2KnownSettingsId::MAX_CONCURRENT_STREAMS:
-      return "SETTINGS_MAX_CONCURRENT_STREAMS";
-    case Http2KnownSettingsId::INITIAL_WINDOW_SIZE:
-      return "SETTINGS_INITIAL_WINDOW_SIZE";
-    case Http2KnownSettingsId::MAX_FRAME_SIZE:
-      return "SETTINGS_MAX_FRAME_SIZE";
-    case Http2KnownSettingsId::MAX_HEADER_LIST_SIZE:
-      return "SETTINGS_MAX_HEADER_LIST_SIZE";
-  }
-  return "SETTINGS_UNKNOWN";
-}
-
-absl::string_view Http2ErrorCodeToString(Http2ErrorCode error_code) {
-  switch (error_code) {
-    case Http2ErrorCode::HTTP2_NO_ERROR:
-      return "HTTP2_NO_ERROR";
-    case Http2ErrorCode::PROTOCOL_ERROR:
-      return "PROTOCOL_ERROR";
-    case Http2ErrorCode::INTERNAL_ERROR:
-      return "INTERNAL_ERROR";
-    case Http2ErrorCode::FLOW_CONTROL_ERROR:
-      return "FLOW_CONTROL_ERROR";
-    case Http2ErrorCode::SETTINGS_TIMEOUT:
-      return "SETTINGS_TIMEOUT";
-    case Http2ErrorCode::STREAM_CLOSED:
-      return "STREAM_CLOSED";
-    case Http2ErrorCode::FRAME_SIZE_ERROR:
-      return "FRAME_SIZE_ERROR";
-    case Http2ErrorCode::REFUSED_STREAM:
-      return "REFUSED_STREAM";
-    case Http2ErrorCode::CANCEL:
-      return "CANCEL";
-    case Http2ErrorCode::COMPRESSION_ERROR:
-      return "COMPRESSION_ERROR";
-    case Http2ErrorCode::CONNECT_ERROR:
-      return "CONNECT_ERROR";
-    case Http2ErrorCode::ENHANCE_YOUR_CALM:
-      return "ENHANCE_YOUR_CALM";
-    case Http2ErrorCode::INADEQUATE_SECURITY:
-      return "INADEQUATE_SECURITY";
-    case Http2ErrorCode::HTTP_1_1_REQUIRED:
-      return "HTTP_1_1_REQUIRED";
-  }
-  return "UNKNOWN_ERROR";
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/http2_protocol.h b/http2/adapter/http2_protocol.h
deleted file mode 100644
index d48a9ab..0000000
--- a/http2/adapter/http2_protocol.h
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_PROTOCOL_H_
-#define QUICHE_HTTP2_ADAPTER_HTTP2_PROTOCOL_H_
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/variant.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-// Represents an HTTP/2 stream ID, consistent with nghttp2.
-using Http2StreamId = int32_t;
-
-// Represents an HTTP/2 SETTINGS parameter as specified in RFC 7540 Section 6.5.
-using Http2SettingsId = uint16_t;
-
-// Represents the payload of an HTTP/2 PING frame.
-using Http2PingId = uint64_t;
-
-// Represents a single header name or value.
-using HeaderRep = absl::variant<absl::string_view, std::string>;
-
-// Boolean return value is true if |rep| holds a string_view, which is assumed
-// to have an indefinite lifetime.
-std::pair<absl::string_view, bool> GetStringView(const HeaderRep& rep);
-
-// Represents an HTTP/2 header field. A header field is a key-value pair with
-// lowercase keys (as specified in RFC 7540 Section 8.1.2).
-using Header = std::pair<HeaderRep, HeaderRep>;
-
-// Represents an HTTP/2 SETTINGS key-value parameter.
-struct QUICHE_EXPORT_PRIVATE Http2Setting {
-  Http2SettingsId id;
-  uint32_t value;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2Setting& a,
-                                      const Http2Setting& b);
-
-// The maximum possible stream ID.
-const Http2StreamId kMaxStreamId = 0x7FFFFFFF;
-
-// The stream ID that represents the connection (e.g., for connection-level flow
-// control updates).
-const Http2StreamId kConnectionStreamId = 0;
-
-// The default value for the size of the largest frame payload, according to RFC
-// 7540 Section 6.5.2 (SETTINGS_MAX_FRAME_SIZE).
-const int kDefaultFramePayloadSizeLimit = 16 * 1024;
-
-// The default value for the initial stream and connection flow control window
-// size, according to RFC 7540 Section 6.9.2.
-const int kInitialFlowControlWindowSize = 64 * 1024 - 1;
-
-// The pseudo-header fields as specified in RFC 7540 Section 8.1.2.3 (request)
-// and Section 8.1.2.4 (response).
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
-    kHttp2MethodPseudoHeader[];
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
-    kHttp2SchemePseudoHeader[];
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
-    kHttp2AuthorityPseudoHeader[];
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
-    kHttp2PathPseudoHeader[];
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
-    kHttp2StatusPseudoHeader[];
-
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const uint8_t kMetadataFrameType;
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const uint8_t kMetadataEndFlag;
-ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const uint16_t
-    kMetadataExtensionId;
-
-enum class FrameType : uint8_t {
-  DATA = 0x0,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-  CONTINUATION,
-};
-
-// HTTP/2 error codes as specified in RFC 7540 Section 7.
-enum class Http2ErrorCode {
-  HTTP2_NO_ERROR = 0x0,
-  PROTOCOL_ERROR = 0x1,
-  INTERNAL_ERROR = 0x2,
-  FLOW_CONTROL_ERROR = 0x3,
-  SETTINGS_TIMEOUT = 0x4,
-  STREAM_CLOSED = 0x5,
-  FRAME_SIZE_ERROR = 0x6,
-  REFUSED_STREAM = 0x7,
-  CANCEL = 0x8,
-  COMPRESSION_ERROR = 0x9,
-  CONNECT_ERROR = 0xA,
-  ENHANCE_YOUR_CALM = 0xB,
-  INADEQUATE_SECURITY = 0xC,
-  HTTP_1_1_REQUIRED = 0xD,
-  MAX_ERROR_CODE = HTTP_1_1_REQUIRED,
-};
-
-// The SETTINGS parameters defined in RFC 7540 Section 6.5.2. Endpoints may send
-// SETTINGS parameters outside of these definitions as per RFC 7540 Section 5.5.
-// This is explicitly an enum instead of an enum class for ease of implicit
-// conversion to the underlying Http2SettingsId type and use with non-standard
-// extension SETTINGS parameters.
-enum Http2KnownSettingsId : Http2SettingsId {
-  HEADER_TABLE_SIZE = 0x1,
-  MIN_SETTING = HEADER_TABLE_SIZE,
-  ENABLE_PUSH = 0x2,
-  MAX_CONCURRENT_STREAMS = 0x3,
-  INITIAL_WINDOW_SIZE = 0x4,
-  MAX_FRAME_SIZE = 0x5,
-  MAX_HEADER_LIST_SIZE = 0x6,
-  ENABLE_CONNECT_PROTOCOL = 0x8,  // See RFC 8441
-  MAX_SETTING = ENABLE_CONNECT_PROTOCOL
-};
-
-// Returns a human-readable string representation of the given SETTINGS |id| for
-// logging/debugging. Returns "SETTINGS_UNKNOWN" for IDs outside of the RFC 7540
-// Section 6.5.2 definitions.
-absl::string_view Http2SettingsIdToString(uint16_t id);
-
-// Returns a human-readable string representation of the given |error_code| for
-// logging/debugging. Returns "UNKNOWN_ERROR" for errors outside of RFC 7540
-// Section 7 definitions.
-absl::string_view Http2ErrorCodeToString(Http2ErrorCode error_code);
-
-enum class Perspective {
-  kClient,
-  kServer,
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_PROTOCOL_H_
diff --git a/http2/adapter/http2_session.h b/http2/adapter/http2_session.h
deleted file mode 100644
index e88a555..0000000
--- a/http2/adapter/http2_session.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_SESSION_H_
-#define QUICHE_HTTP2_ADAPTER_HTTP2_SESSION_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "http2/adapter/http2_protocol.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-struct QUICHE_EXPORT_PRIVATE Http2SessionCallbacks {};
-
-// A class to represent the state of a single HTTP/2 connection.
-class QUICHE_EXPORT_PRIVATE Http2Session {
- public:
-  Http2Session() = default;
-  virtual ~Http2Session() {}
-
-  virtual int64_t ProcessBytes(absl::string_view bytes) = 0;
-
-  virtual int Consume(Http2StreamId stream_id, size_t num_bytes) = 0;
-
-  virtual bool want_read() const = 0;
-  virtual bool want_write() const = 0;
-  virtual int GetRemoteWindowSize() const = 0;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_SESSION_H_
diff --git a/http2/adapter/http2_util.cc b/http2/adapter/http2_util.cc
deleted file mode 100644
index fd21173..0000000
--- a/http2/adapter/http2_util.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "http2/adapter/http2_util.h"
-
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-namespace {
-
-using ConnectionError = Http2VisitorInterface::ConnectionError;
-using InvalidFrameError = Http2VisitorInterface::InvalidFrameError;
-
-}  // anonymous namespace
-
-spdy::SpdyErrorCode TranslateErrorCode(Http2ErrorCode code) {
-  switch (code) {
-    case Http2ErrorCode::HTTP2_NO_ERROR:
-      return spdy::ERROR_CODE_NO_ERROR;
-    case Http2ErrorCode::PROTOCOL_ERROR:
-      return spdy::ERROR_CODE_PROTOCOL_ERROR;
-    case Http2ErrorCode::INTERNAL_ERROR:
-      return spdy::ERROR_CODE_INTERNAL_ERROR;
-    case Http2ErrorCode::FLOW_CONTROL_ERROR:
-      return spdy::ERROR_CODE_FLOW_CONTROL_ERROR;
-    case Http2ErrorCode::SETTINGS_TIMEOUT:
-      return spdy::ERROR_CODE_SETTINGS_TIMEOUT;
-    case Http2ErrorCode::STREAM_CLOSED:
-      return spdy::ERROR_CODE_STREAM_CLOSED;
-    case Http2ErrorCode::FRAME_SIZE_ERROR:
-      return spdy::ERROR_CODE_FRAME_SIZE_ERROR;
-    case Http2ErrorCode::REFUSED_STREAM:
-      return spdy::ERROR_CODE_REFUSED_STREAM;
-    case Http2ErrorCode::CANCEL:
-      return spdy::ERROR_CODE_CANCEL;
-    case Http2ErrorCode::COMPRESSION_ERROR:
-      return spdy::ERROR_CODE_COMPRESSION_ERROR;
-    case Http2ErrorCode::CONNECT_ERROR:
-      return spdy::ERROR_CODE_CONNECT_ERROR;
-    case Http2ErrorCode::ENHANCE_YOUR_CALM:
-      return spdy::ERROR_CODE_ENHANCE_YOUR_CALM;
-    case Http2ErrorCode::INADEQUATE_SECURITY:
-      return spdy::ERROR_CODE_INADEQUATE_SECURITY;
-    case Http2ErrorCode::HTTP_1_1_REQUIRED:
-      return spdy::ERROR_CODE_HTTP_1_1_REQUIRED;
-  }
-  return spdy::ERROR_CODE_INTERNAL_ERROR;
-}
-
-Http2ErrorCode TranslateErrorCode(spdy::SpdyErrorCode code) {
-  switch (code) {
-    case spdy::ERROR_CODE_NO_ERROR:
-      return Http2ErrorCode::HTTP2_NO_ERROR;
-    case spdy::ERROR_CODE_PROTOCOL_ERROR:
-      return Http2ErrorCode::PROTOCOL_ERROR;
-    case spdy::ERROR_CODE_INTERNAL_ERROR:
-      return Http2ErrorCode::INTERNAL_ERROR;
-    case spdy::ERROR_CODE_FLOW_CONTROL_ERROR:
-      return Http2ErrorCode::FLOW_CONTROL_ERROR;
-    case spdy::ERROR_CODE_SETTINGS_TIMEOUT:
-      return Http2ErrorCode::SETTINGS_TIMEOUT;
-    case spdy::ERROR_CODE_STREAM_CLOSED:
-      return Http2ErrorCode::STREAM_CLOSED;
-    case spdy::ERROR_CODE_FRAME_SIZE_ERROR:
-      return Http2ErrorCode::FRAME_SIZE_ERROR;
-    case spdy::ERROR_CODE_REFUSED_STREAM:
-      return Http2ErrorCode::REFUSED_STREAM;
-    case spdy::ERROR_CODE_CANCEL:
-      return Http2ErrorCode::CANCEL;
-    case spdy::ERROR_CODE_COMPRESSION_ERROR:
-      return Http2ErrorCode::COMPRESSION_ERROR;
-    case spdy::ERROR_CODE_CONNECT_ERROR:
-      return Http2ErrorCode::CONNECT_ERROR;
-    case spdy::ERROR_CODE_ENHANCE_YOUR_CALM:
-      return Http2ErrorCode::ENHANCE_YOUR_CALM;
-    case spdy::ERROR_CODE_INADEQUATE_SECURITY:
-      return Http2ErrorCode::INADEQUATE_SECURITY;
-    case spdy::ERROR_CODE_HTTP_1_1_REQUIRED:
-      return Http2ErrorCode::HTTP_1_1_REQUIRED;
-  }
-  return Http2ErrorCode::INTERNAL_ERROR;
-}
-
-absl::string_view ConnectionErrorToString(ConnectionError error) {
-  switch (error) {
-    case ConnectionError::kInvalidConnectionPreface:
-      return "InvalidConnectionPreface";
-    case ConnectionError::kSendError:
-      return "SendError";
-    case ConnectionError::kParseError:
-      return "ParseError";
-    case ConnectionError::kHeaderError:
-      return "HeaderError";
-    case ConnectionError::kInvalidNewStreamId:
-      return "InvalidNewStreamId";
-    case ConnectionError::kWrongFrameSequence:
-      return "kWrongFrameSequence";
-    case ConnectionError::kInvalidPushPromise:
-      return "InvalidPushPromise";
-    case ConnectionError::kExceededMaxConcurrentStreams:
-      return "ExceededMaxConcurrentStreams";
-    case ConnectionError::kFlowControlError:
-      return "FlowControlError";
-  }
-  return "UnknownConnectionError";
-}
-
-absl::string_view InvalidFrameErrorToString(
-    Http2VisitorInterface::InvalidFrameError error) {
-  switch (error) {
-    case InvalidFrameError::kProtocol:
-      return "Protocol";
-    case InvalidFrameError::kRefusedStream:
-      return "RefusedStream";
-    case InvalidFrameError::kHttpHeader:
-      return "HttpHeader";
-    case InvalidFrameError::kHttpMessaging:
-      return "HttpMessaging";
-    case InvalidFrameError::kFlowControl:
-      return "FlowControl";
-    case InvalidFrameError::kStreamClosed:
-      return "StreamClosed";
-  }
-  return "UnknownInvalidFrameError";
-}
-
-bool DeltaAtLeastHalfLimit(int64_t limit, int64_t /*size*/, int64_t delta) {
-  return delta > 0 && delta >= limit / 2;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/http2_util.h b/http2/adapter/http2_util.h
deleted file mode 100644
index feea543..0000000
--- a/http2/adapter/http2_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_UTIL_H_
-#define QUICHE_HTTP2_ADAPTER_HTTP2_UTIL_H_
-
-#include <cstdint>
-
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-
-QUICHE_EXPORT_PRIVATE spdy::SpdyErrorCode TranslateErrorCode(
-    Http2ErrorCode code);
-QUICHE_EXPORT_PRIVATE Http2ErrorCode
-TranslateErrorCode(spdy::SpdyErrorCode code);
-
-QUICHE_EXPORT_PRIVATE absl::string_view ConnectionErrorToString(
-    Http2VisitorInterface::ConnectionError error);
-
-QUICHE_EXPORT_PRIVATE absl::string_view InvalidFrameErrorToString(
-    Http2VisitorInterface::InvalidFrameError error);
-
-// A WINDOW_UPDATE sending strategy that returns true if the `delta` to be sent
-// is positive and at least half of the window `limit`.
-QUICHE_EXPORT_PRIVATE bool DeltaAtLeastHalfLimit(int64_t limit,
-                                                 int64_t /*size*/,
-                                                 int64_t delta);
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_UTIL_H_
diff --git a/http2/adapter/http2_visitor_interface.h b/http2/adapter/http2_visitor_interface.h
deleted file mode 100644
index 9136db2..0000000
--- a/http2/adapter/http2_visitor_interface.h
+++ /dev/null
@@ -1,260 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
-#define QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
-
-#include <cstdint>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "http2/adapter/http2_protocol.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-// Http2VisitorInterface contains callbacks for receiving HTTP/2-level events. A
-// processor like NghttpAdapter parses HTTP/2 frames and invokes the callbacks
-// on an instance of this interface. Prefer a void return type for these
-// callbacks, instead setting output parameters as needed.
-//
-// Example sequences of calls/events:
-//   GET:
-//     - OnBeginHeadersForStream()
-//     - OnHeaderForStream()
-//     - OnEndHeadersForStream()
-//     - OnEndStream()
-//
-//   POST:
-//     - OnBeginHeadersForStream()
-//     - OnHeaderForStream()
-//     - OnEndHeadersForStream()
-//     - OnBeginDataForStream()
-//     - OnDataForStream()
-//     - OnEndStream()
-//
-//   Request canceled mid-stream, e.g, with error code CANCEL:
-//     - OnBeginHeadersForStream()
-//     - OnHeaderForStream()
-//     - OnEndHeadersForStream()
-//     - OnRstStream()
-//     - OnCloseStream()
-//
-//   Request closed mid-stream, e.g., with error code NO_ERROR:
-//     - OnBeginHeadersForStream()
-//     - OnHeaderForStream()
-//     - OnEndHeadersForStream()
-//     - OnRstStream()
-//     - OnCloseStream()
-//
-// More details are at RFC 7540 (go/http2spec).
-class QUICHE_EXPORT_PRIVATE Http2VisitorInterface {
- public:
-  Http2VisitorInterface(const Http2VisitorInterface&) = delete;
-  Http2VisitorInterface& operator=(const Http2VisitorInterface&) = delete;
-  virtual ~Http2VisitorInterface() = default;
-
-  enum : int64_t {
-    kSendBlocked = 0,
-    kSendError = -1,
-  };
-  // Called when there are serialized frames to send. Should return how many
-  // bytes were actually sent. May return kSendBlocked or kSendError.
-  virtual int64_t OnReadyToSend(absl::string_view serialized) = 0;
-
-  // Called when a connection-level error has occurred.
-  enum class ConnectionError {
-    // The peer sent an invalid connection preface.
-    kInvalidConnectionPreface,
-    // The visitor encountered an error sending bytes to the peer.
-    kSendError,
-    // There was an error reading and framing bytes from the peer.
-    kParseError,
-    // The visitor considered a received header to be a connection error.
-    kHeaderError,
-    // The peer attempted to open a stream with an invalid stream ID.
-    kInvalidNewStreamId,
-    // The peer sent a frame that is invalid on an idle stream (before HEADERS).
-    kWrongFrameSequence,
-    // The peer sent an invalid PUSH_PROMISE frame.
-    kInvalidPushPromise,
-    // The peer exceeded the max concurrent streams limit.
-    kExceededMaxConcurrentStreams,
-    // The peer caused a flow control error.
-    kFlowControlError,
-  };
-  virtual void OnConnectionError(ConnectionError error) = 0;
-
-  // Called when the header for a frame is received. Returns false if a fatal
-  // error has occurred.
-  virtual bool OnFrameHeader(Http2StreamId /*stream_id*/, size_t /*length*/,
-                             uint8_t /*type*/, uint8_t /*flags*/) {
-    return true;
-  }
-
-  // Called when a non-ack SETTINGS frame is received.
-  virtual void OnSettingsStart() = 0;
-
-  // Called for each SETTINGS id-value pair.
-  virtual void OnSetting(Http2Setting setting) = 0;
-
-  // Called at the end of a non-ack SETTINGS frame.
-  virtual void OnSettingsEnd() = 0;
-
-  // Called when a SETTINGS ack frame is received.
-  virtual void OnSettingsAck() = 0;
-
-  // Called when the connection receives the header block for a HEADERS frame on
-  // a stream but has not yet parsed individual headers. Returns false if a
-  // fatal error has occurred.
-  virtual bool OnBeginHeadersForStream(Http2StreamId stream_id) = 0;
-
-  // Called when the connection receives the header |key| and |value| for a
-  // stream. The HTTP/2 pseudo-headers defined in RFC 7540 Sections 8.1.2.3 and
-  // 8.1.2.4 are also conveyed in this callback. This method is called after
-  // OnBeginHeadersForStream(). May return HEADER_RST_STREAM to indicate the
-  // header block should be rejected. This will cause the library to queue a
-  // RST_STREAM frame, which will have a default error code of INTERNAL_ERROR.
-  // The visitor implementation may choose to queue a RST_STREAM with a
-  // different error code instead, which should be done before returning
-  // HEADER_RST_STREAM. Returning HEADER_CONNECTION_ERROR will lead to a
-  // non-recoverable error on the connection.
-  enum OnHeaderResult {
-    // The header was accepted.
-    HEADER_OK,
-    // The application considers the header a connection error.
-    HEADER_CONNECTION_ERROR,
-    // The application rejects the header and requests the stream be reset.
-    HEADER_RST_STREAM,
-    // The header field is invalid and will be reset with error code
-    // PROTOCOL_ERROR.
-    HEADER_FIELD_INVALID,
-    // The headers are a violation of HTTP messaging semantics and will be reset
-    // with error code PROTOCOL_ERROR.
-    HEADER_HTTP_MESSAGING,
-    // The headers caused a compression context error.
-    HEADER_COMPRESSION_ERROR,
-  };
-  virtual OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
-                                           absl::string_view key,
-                                           absl::string_view value) = 0;
-
-  // Called when the connection has received the complete header block for a
-  // logical HEADERS frame on a stream (which may contain CONTINUATION frames,
-  // transparent to the user). Returns false if a fatal error has occurred.
-  virtual bool OnEndHeadersForStream(Http2StreamId stream_id) = 0;
-
-  // Called when the connection receives the beginning of a DATA frame. The data
-  // payload will be provided via subsequent calls to OnDataForStream(). Returns
-  // false if a fatal error has occurred.
-  virtual bool OnBeginDataForStream(Http2StreamId stream_id,
-                                    size_t payload_length) = 0;
-
-  // Called when the optional padding length field is parsed as part of a DATA
-  // frame payload. `padding_length` represents the total amount of padding for
-  // this frame, including the length byte itself. Returns false if a fatal
-  // error has occurred.
-  virtual bool OnDataPaddingLength(Http2StreamId stream_id,
-                                   size_t padding_length) = 0;
-
-  // Called when the connection receives some |data| (as part of a DATA frame
-  // payload) for a stream. Returns false if a fatal error has occurred.
-  virtual bool OnDataForStream(Http2StreamId stream_id,
-                               absl::string_view data) = 0;
-
-  // Called when the peer sends the END_STREAM flag on a stream, indicating that
-  // the peer will not send additional headers or data for that stream.
-  virtual void OnEndStream(Http2StreamId stream_id) = 0;
-
-  // Called when the connection receives a RST_STREAM for a stream. This call
-  // will be followed by either OnCloseStream().
-  virtual void OnRstStream(Http2StreamId stream_id,
-                           Http2ErrorCode error_code) = 0;
-
-  // Called when a stream is closed. Returns false if a fatal error has
-  // occurred.
-  virtual bool OnCloseStream(Http2StreamId stream_id,
-                             Http2ErrorCode error_code) = 0;
-
-  // Called when the connection receives a PRIORITY frame.
-  virtual void OnPriorityForStream(Http2StreamId stream_id,
-                                   Http2StreamId parent_stream_id, int weight,
-                                   bool exclusive) = 0;
-
-  // Called when the connection receives a PING frame.
-  virtual void OnPing(Http2PingId ping_id, bool is_ack) = 0;
-
-  // Called when the connection receives a PUSH_PROMISE frame. The server push
-  // request headers follow in calls to OnHeaderForStream() with |stream_id|.
-  virtual void OnPushPromiseForStream(Http2StreamId stream_id,
-                                      Http2StreamId promised_stream_id) = 0;
-
-  // Called when the connection receives a GOAWAY frame. Returns false if a
-  // fatal error has occurred.
-  virtual bool OnGoAway(Http2StreamId last_accepted_stream_id,
-                        Http2ErrorCode error_code,
-                        absl::string_view opaque_data) = 0;
-
-  // Called when the connection receives a WINDOW_UPDATE frame. For
-  // connection-level window updates, the |stream_id| will be 0.
-  virtual void OnWindowUpdate(Http2StreamId stream_id,
-                              int window_increment) = 0;
-
-  // Called immediately before a frame of the given type is sent. Should return
-  // 0 on success.
-  virtual int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
-                                size_t length, uint8_t flags) = 0;
-
-  // Called immediately after a frame of the given type is sent. Should return 0
-  // on success. |error_code| is only populated for RST_STREAM and GOAWAY frame
-  // types.
-  virtual int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
-                          size_t length, uint8_t flags,
-                          uint32_t error_code) = 0;
-
-  // Called when the connection receives an invalid frame. A return value of
-  // false will result in the connection entering an error state, with no
-  // further frame processing possible.
-  enum class InvalidFrameError {
-    // The frame contains a general protocol error.
-    kProtocol,
-    // The frame would have caused a new (invalid) stream to be opened.
-    kRefusedStream,
-    // The frame contains an invalid header field.
-    kHttpHeader,
-    // The frame contains a violation in HTTP messaging rules.
-    kHttpMessaging,
-    // The frame causes a flow control error.
-    kFlowControl,
-    // The frame is on an already closed stream or has an invalid stream ID.
-    kStreamClosed,
-  };
-  virtual bool OnInvalidFrame(Http2StreamId stream_id,
-                              InvalidFrameError error) = 0;
-
-  // Called when the connection receives the beginning of a METADATA frame
-  // (which may itself be the middle of a logical metadata block). The metadata
-  // payload will be provided via subsequent calls to OnMetadataForStream().
-  // TODO(birenroy): Consider removing this unnecessary method.
-  virtual void OnBeginMetadataForStream(Http2StreamId stream_id,
-                                        size_t payload_length) = 0;
-
-  // Called when the connection receives |metadata| as part of a METADATA frame
-  // payload for a stream. Returns false if a fatal error has occurred.
-  virtual bool OnMetadataForStream(Http2StreamId stream_id,
-                                   absl::string_view metadata) = 0;
-
-  // Called when the connection has finished receiving a logical metadata block
-  // for a stream. Note that there may be multiple metadata blocks for a stream.
-  // Returns false if there was an error unpacking the metadata payload.
-  virtual bool OnMetadataEndForStream(Http2StreamId stream_id) = 0;
-
-  // Invoked with an error message from the application.
-  virtual void OnErrorDebug(absl::string_view message) = 0;
-
- protected:
-  Http2VisitorInterface() = default;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
diff --git a/http2/adapter/mock_http2_visitor.h b/http2/adapter/mock_http2_visitor.h
deleted file mode 100644
index 098ca84..0000000
--- a/http2/adapter/mock_http2_visitor.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_MOCK_HTTP2_VISITOR_INTERFACE_H_
-#define QUICHE_HTTP2_ADAPTER_MOCK_HTTP2_VISITOR_INTERFACE_H_
-
-#include <cstdint>
-
-#include "http2/adapter/http2_visitor_interface.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-// A mock visitor class, for use in tests.
-class QUICHE_NO_EXPORT MockHttp2Visitor : public Http2VisitorInterface {
- public:
-  MockHttp2Visitor() {
-    ON_CALL(*this, OnFrameHeader).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnBeginHeadersForStream)
-        .WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnHeaderForStream).WillByDefault(testing::Return(HEADER_OK));
-    ON_CALL(*this, OnEndHeadersForStream).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnDataPaddingLength).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnBeginDataForStream).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnDataForStream).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnCloseStream).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnGoAway).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnInvalidFrame).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnMetadataForStream).WillByDefault(testing::Return(true));
-    ON_CALL(*this, OnMetadataEndForStream).WillByDefault(testing::Return(true));
-  }
-
-  MOCK_METHOD(int64_t, OnReadyToSend, (absl::string_view serialized),
-              (override));
-  MOCK_METHOD(void, OnConnectionError, (ConnectionError error), (override));
-  MOCK_METHOD(bool, OnFrameHeader,
-              (Http2StreamId stream_id, size_t length, uint8_t type,
-               uint8_t flags),
-              (override));
-  MOCK_METHOD(void, OnSettingsStart, (), (override));
-  MOCK_METHOD(void, OnSetting, (Http2Setting setting), (override));
-  MOCK_METHOD(void, OnSettingsEnd, (), (override));
-  MOCK_METHOD(void, OnSettingsAck, (), (override));
-  MOCK_METHOD(bool, OnBeginHeadersForStream, (Http2StreamId stream_id),
-              (override));
-
-  MOCK_METHOD(OnHeaderResult, OnHeaderForStream,
-              (Http2StreamId stream_id, absl::string_view key,
-               absl::string_view value),
-              (override));
-
-  MOCK_METHOD(bool, OnEndHeadersForStream, (Http2StreamId stream_id),
-              (override));
-
-  MOCK_METHOD(bool, OnDataPaddingLength,
-              (Http2StreamId strema_id, size_t padding_length), (override));
-
-  MOCK_METHOD(bool, OnBeginDataForStream,
-              (Http2StreamId stream_id, size_t payload_length), (override));
-
-  MOCK_METHOD(bool, OnDataForStream,
-              (Http2StreamId stream_id, absl::string_view data), (override));
-
-  MOCK_METHOD(void, OnEndStream, (Http2StreamId stream_id), (override));
-
-  MOCK_METHOD(void,
-              OnRstStream,
-              (Http2StreamId stream_id, Http2ErrorCode error_code),
-              (override));
-
-  MOCK_METHOD(bool, OnCloseStream,
-              (Http2StreamId stream_id, Http2ErrorCode error_code), (override));
-
-  MOCK_METHOD(void,
-              OnPriorityForStream,
-              (Http2StreamId stream_id,
-               Http2StreamId parent_stream_id,
-               int weight,
-               bool exclusive),
-              (override));
-
-  MOCK_METHOD(void, OnPing, (Http2PingId ping_id, bool is_ack), (override));
-
-  MOCK_METHOD(void,
-              OnPushPromiseForStream,
-              (Http2StreamId stream_id, Http2StreamId promised_stream_id),
-              (override));
-
-  MOCK_METHOD(bool, OnGoAway,
-              (Http2StreamId last_accepted_stream_id, Http2ErrorCode error_code,
-               absl::string_view opaque_data),
-              (override));
-
-  MOCK_METHOD(void,
-              OnWindowUpdate,
-              (Http2StreamId stream_id, int window_increment),
-              (override));
-
-  MOCK_METHOD(int, OnBeforeFrameSent,
-              (uint8_t frame_type, Http2StreamId stream_id, size_t length,
-               uint8_t flags),
-              (override));
-
-  MOCK_METHOD(int, OnFrameSent,
-              (uint8_t frame_type, Http2StreamId stream_id, size_t length,
-               uint8_t flags, uint32_t error_code),
-              (override));
-
-  MOCK_METHOD(bool, OnInvalidFrame,
-              (Http2StreamId stream_id, InvalidFrameError error), (override));
-
-  MOCK_METHOD(void,
-              OnBeginMetadataForStream,
-              (Http2StreamId stream_id, size_t payload_length),
-              (override));
-
-  MOCK_METHOD(bool, OnMetadataForStream,
-              (Http2StreamId stream_id, absl::string_view metadata),
-              (override));
-
-  MOCK_METHOD(bool, OnMetadataEndForStream, (Http2StreamId stream_id),
-              (override));
-
-  MOCK_METHOD(void, OnErrorDebug, (absl::string_view message), (override));
-};
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_MOCK_HTTP2_VISITOR_INTERFACE_H_
diff --git a/http2/adapter/mock_nghttp2_callbacks.cc b/http2/adapter/mock_nghttp2_callbacks.cc
deleted file mode 100644
index 4243347..0000000
--- a/http2/adapter/mock_nghttp2_callbacks.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "http2/adapter/mock_nghttp2_callbacks.h"
-
-#include "http2/adapter/nghttp2_util.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-/* static */
-nghttp2_session_callbacks_unique_ptr MockNghttp2Callbacks::GetCallbacks() {
-  nghttp2_session_callbacks* callbacks;
-  nghttp2_session_callbacks_new(&callbacks);
-
-  // All of the callback implementations below just delegate to the mock methods
-  // of |user_data|, which is assumed to be a MockNghttp2Callbacks*.
-  nghttp2_session_callbacks_set_send_callback(
-      callbacks,
-      [](nghttp2_session*, const uint8_t* data, size_t length, int flags,
-         void* user_data) -> ssize_t {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->Send(data, length,
-                                                                   flags);
-      });
-
-  nghttp2_session_callbacks_set_send_data_callback(
-      callbacks,
-      [](nghttp2_session*, nghttp2_frame* frame, const uint8_t* framehd,
-         size_t length, nghttp2_data_source* source, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->SendData(
-            frame, framehd, length, source);
-      });
-
-  nghttp2_session_callbacks_set_on_begin_headers_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnBeginHeaders(
-            frame);
-      });
-
-  nghttp2_session_callbacks_set_on_header_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, const uint8_t* raw_name,
-         size_t name_length, const uint8_t* raw_value, size_t value_length,
-         uint8_t flags, void* user_data) -> int {
-        absl::string_view name = ToStringView(raw_name, name_length);
-        absl::string_view value = ToStringView(raw_value, value_length);
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnHeader(
-            frame, name, value, flags);
-      });
-
-  nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
-      callbacks,
-      [](nghttp2_session*, uint8_t flags, int32_t stream_id,
-         const uint8_t* data, size_t len, void* user_data) -> int {
-        absl::string_view chunk = ToStringView(data, len);
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnDataChunkRecv(
-            flags, stream_id, chunk);
-      });
-
-  nghttp2_session_callbacks_set_on_begin_frame_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame_hd* hd, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnBeginFrame(hd);
-      });
-
-  nghttp2_session_callbacks_set_on_frame_recv_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameRecv(
-            frame);
-      });
-
-  nghttp2_session_callbacks_set_on_stream_close_callback(
-      callbacks,
-      [](nghttp2_session*, int32_t stream_id, uint32_t error_code,
-         void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnStreamClose(
-            stream_id, error_code);
-      });
-
-  nghttp2_session_callbacks_set_on_frame_send_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameSend(
-            frame);
-      });
-
-  nghttp2_session_callbacks_set_before_frame_send_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->BeforeFrameSend(
-            frame);
-      });
-
-  nghttp2_session_callbacks_set_on_frame_not_send_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, int lib_error_code,
-         void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameNotSend(
-            frame, lib_error_code);
-      });
-
-  nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
-      callbacks,
-      [](nghttp2_session*, const nghttp2_frame* frame, int error_code,
-         void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)
-            ->OnInvalidFrameRecv(frame, error_code);
-      });
-
-  nghttp2_session_callbacks_set_error_callback2(
-      callbacks,
-      [](nghttp2_session* /*session*/, int lib_error_code, const char* msg,
-         size_t len, void* user_data) -> int {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnErrorCallback2(
-            lib_error_code, msg, len);
-      });
-
-  nghttp2_session_callbacks_set_pack_extension_callback(
-      callbacks,
-      [](nghttp2_session*, uint8_t* buf, size_t len, const nghttp2_frame* frame,
-         void* user_data) -> ssize_t {
-        return static_cast<MockNghttp2Callbacks*>(user_data)->OnPackExtension(
-            buf, len, frame);
-      });
-  return MakeCallbacksPtr(callbacks);
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/mock_nghttp2_callbacks.h b/http2/adapter/mock_nghttp2_callbacks.h
deleted file mode 100644
index 85bc6a9..0000000
--- a/http2/adapter/mock_nghttp2_callbacks.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_
-#define QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "http2/adapter/nghttp2.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-// This class provides a set of mock nghttp2 callbacks for use in unit test
-// expectations.
-class QUICHE_NO_EXPORT MockNghttp2Callbacks {
- public:
-  MockNghttp2Callbacks() = default;
-
-  // The caller takes ownership of the |nghttp2_session_callbacks|.
-  static nghttp2_session_callbacks_unique_ptr GetCallbacks();
-
-  MOCK_METHOD(ssize_t,
-              Send,
-              (const uint8_t* data, size_t length, int flags),
-              ());
-
-  MOCK_METHOD(int,
-              SendData,
-              (nghttp2_frame * frame,
-               const uint8_t* framehd,
-               size_t length,
-               nghttp2_data_source* source),
-              ());
-
-  MOCK_METHOD(int, OnBeginHeaders, (const nghttp2_frame* frame), ());
-
-  MOCK_METHOD(int,
-              OnHeader,
-              (const nghttp2_frame* frame,
-               absl::string_view name,
-               absl::string_view value,
-               uint8_t flags),
-              ());
-
-  MOCK_METHOD(int,
-              OnDataChunkRecv,
-              (uint8_t flags, int32_t stream_id, absl::string_view data),
-              ());
-
-  MOCK_METHOD(int, OnBeginFrame, (const nghttp2_frame_hd* hd), ());
-
-  MOCK_METHOD(int, OnFrameRecv, (const nghttp2_frame* frame), ());
-
-  MOCK_METHOD(int, OnStreamClose, (int32_t stream_id, uint32_t error_code), ());
-
-  MOCK_METHOD(int, BeforeFrameSend, (const nghttp2_frame* frame), ());
-
-  MOCK_METHOD(int, OnFrameSend, (const nghttp2_frame* frame), ());
-
-  MOCK_METHOD(int,
-              OnFrameNotSend,
-              (const nghttp2_frame* frame, int lib_error_code),
-              ());
-
-  MOCK_METHOD(int,
-              OnInvalidFrameRecv,
-              (const nghttp2_frame* frame, int error_code),
-              ());
-
-  MOCK_METHOD(int,
-              OnErrorCallback2,
-              (int lib_error_code, const char* msg, size_t len),
-              ());
-
-  MOCK_METHOD(ssize_t, OnPackExtension,
-              (uint8_t * buf, size_t len, const nghttp2_frame* frame), ());
-};
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_
diff --git a/http2/adapter/nghttp2_adapter.cc b/http2/adapter/nghttp2_adapter.cc
deleted file mode 100644
index c8dbc74..0000000
--- a/http2/adapter/nghttp2_adapter.cc
+++ /dev/null
@@ -1,308 +0,0 @@
-#include "http2/adapter/nghttp2_adapter.h"
-
-#include "absl/algorithm/container.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/nghttp2.h"
-#include "http2/adapter/nghttp2_callbacks.h"
-#include "http2/adapter/nghttp2_data_provider.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-
-namespace http2 {
-namespace adapter {
-
-namespace {
-
-using ConnectionError = Http2VisitorInterface::ConnectionError;
-
-// A metadata source that deletes itself upon completion.
-class SelfDeletingMetadataSource : public MetadataSource {
- public:
-  explicit SelfDeletingMetadataSource(std::unique_ptr<MetadataSource> source)
-      : source_(std::move(source)) {}
-
-  size_t NumFrames(size_t max_frame_size) const override {
-    return source_->NumFrames(max_frame_size);
-  }
-
-  std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override {
-    const auto result = source_->Pack(dest, dest_len);
-    if (result.first < 0 || result.second) {
-      delete this;
-    }
-    return result;
-  }
-
-  void OnFailure() override {
-    source_->OnFailure();
-    delete this;
-  }
-
- private:
-  std::unique_ptr<MetadataSource> source_;
-};
-
-}  // anonymous namespace
-
-/* static */
-std::unique_ptr<NgHttp2Adapter> NgHttp2Adapter::CreateClientAdapter(
-    Http2VisitorInterface& visitor, const nghttp2_option* options) {
-  auto adapter = new NgHttp2Adapter(visitor, Perspective::kClient, options);
-  adapter->Initialize();
-  return absl::WrapUnique(adapter);
-}
-
-/* static */
-std::unique_ptr<NgHttp2Adapter> NgHttp2Adapter::CreateServerAdapter(
-    Http2VisitorInterface& visitor, const nghttp2_option* options) {
-  auto adapter = new NgHttp2Adapter(visitor, Perspective::kServer, options);
-  adapter->Initialize();
-  return absl::WrapUnique(adapter);
-}
-
-bool NgHttp2Adapter::IsServerSession() const {
-  int result = nghttp2_session_check_server_session(session_->raw_ptr());
-  QUICHE_DCHECK_EQ(perspective_ == Perspective::kServer, result > 0);
-  return result > 0;
-}
-
-int64_t NgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
-  const int64_t processed_bytes = session_->ProcessBytes(bytes);
-  if (processed_bytes < 0) {
-    visitor_.OnConnectionError(ConnectionError::kParseError);
-  }
-  return processed_bytes;
-}
-
-void NgHttp2Adapter::SubmitSettings(absl::Span<const Http2Setting> settings) {
-  // Submit SETTINGS, converting each Http2Setting to an nghttp2_settings_entry.
-  std::vector<nghttp2_settings_entry> nghttp2_settings;
-  absl::c_transform(settings, std::back_inserter(nghttp2_settings),
-                    [](const Http2Setting& setting) {
-                      return nghttp2_settings_entry{setting.id, setting.value};
-                    });
-  nghttp2_submit_settings(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
-                          nghttp2_settings.data(), nghttp2_settings.size());
-}
-
-void NgHttp2Adapter::SubmitPriorityForStream(Http2StreamId stream_id,
-                                             Http2StreamId parent_stream_id,
-                                             int weight,
-                                             bool exclusive) {
-  nghttp2_priority_spec priority_spec;
-  nghttp2_priority_spec_init(&priority_spec, parent_stream_id, weight,
-                             static_cast<int>(exclusive));
-  nghttp2_submit_priority(session_->raw_ptr(), NGHTTP2_FLAG_NONE, stream_id,
-                          &priority_spec);
-}
-
-void NgHttp2Adapter::SubmitPing(Http2PingId ping_id) {
-  uint8_t opaque_data[8] = {};
-  Http2PingId ping_id_to_serialize = quiche::QuicheEndian::HostToNet64(ping_id);
-  std::memcpy(opaque_data, &ping_id_to_serialize, sizeof(Http2PingId));
-  nghttp2_submit_ping(session_->raw_ptr(), NGHTTP2_FLAG_NONE, opaque_data);
-}
-
-void NgHttp2Adapter::SubmitShutdownNotice() {
-  nghttp2_submit_shutdown_notice(session_->raw_ptr());
-}
-
-void NgHttp2Adapter::SubmitGoAway(Http2StreamId last_accepted_stream_id,
-                                  Http2ErrorCode error_code,
-                                  absl::string_view opaque_data) {
-  nghttp2_submit_goaway(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
-                        last_accepted_stream_id,
-                        static_cast<uint32_t>(error_code),
-                        ToUint8Ptr(opaque_data.data()), opaque_data.size());
-}
-
-void NgHttp2Adapter::SubmitWindowUpdate(Http2StreamId stream_id,
-                                        int window_increment) {
-  nghttp2_submit_window_update(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
-                               stream_id, window_increment);
-}
-
-void NgHttp2Adapter::SubmitMetadata(Http2StreamId stream_id,
-                                    size_t max_frame_size,
-                                    std::unique_ptr<MetadataSource> source) {
-  auto* wrapped_source = new SelfDeletingMetadataSource(std::move(source));
-  const size_t num_frames = wrapped_source->NumFrames(max_frame_size);
-  size_t num_successes = 0;
-  for (size_t i = 1; i <= num_frames; ++i) {
-    const int result = nghttp2_submit_extension(
-        session_->raw_ptr(), kMetadataFrameType,
-        i == num_frames ? kMetadataEndFlag : 0, stream_id, wrapped_source);
-    if (result != 0) {
-      QUICHE_LOG(DFATAL) << "Failed to submit extension frame " << i << " of "
-                         << num_frames;
-      break;
-    }
-    ++num_successes;
-  }
-  if (num_successes == 0) {
-    delete wrapped_source;
-  }
-}
-
-int NgHttp2Adapter::Send() {
-  const int result = nghttp2_session_send(session_->raw_ptr());
-  if (result != 0) {
-    QUICHE_VLOG(1) << "nghttp2_session_send returned " << result;
-    visitor_.OnConnectionError(ConnectionError::kSendError);
-  }
-  return result;
-}
-
-int NgHttp2Adapter::GetSendWindowSize() const {
-  return session_->GetRemoteWindowSize();
-}
-
-int NgHttp2Adapter::GetStreamSendWindowSize(Http2StreamId stream_id) const {
-  return nghttp2_session_get_stream_remote_window_size(session_->raw_ptr(),
-                                                       stream_id);
-}
-
-int NgHttp2Adapter::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
-  return nghttp2_session_get_stream_effective_local_window_size(
-      session_->raw_ptr(), stream_id);
-}
-
-int NgHttp2Adapter::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
-  return nghttp2_session_get_stream_local_window_size(session_->raw_ptr(),
-                                                      stream_id);
-}
-
-int NgHttp2Adapter::GetReceiveWindowSize() const {
-  return nghttp2_session_get_local_window_size(session_->raw_ptr());
-}
-
-int NgHttp2Adapter::GetHpackEncoderDynamicTableSize() const {
-  return nghttp2_session_get_hd_deflate_dynamic_table_size(session_->raw_ptr());
-}
-
-int NgHttp2Adapter::GetHpackDecoderDynamicTableSize() const {
-  return nghttp2_session_get_hd_inflate_dynamic_table_size(session_->raw_ptr());
-}
-
-Http2StreamId NgHttp2Adapter::GetHighestReceivedStreamId() const {
-  return nghttp2_session_get_last_proc_stream_id(session_->raw_ptr());
-}
-
-void NgHttp2Adapter::MarkDataConsumedForStream(Http2StreamId stream_id,
-                                               size_t num_bytes) {
-  int rc = session_->Consume(stream_id, num_bytes);
-  if (rc != 0) {
-    QUICHE_LOG(ERROR) << "Error " << rc << " marking " << num_bytes
-                      << " bytes consumed for stream " << stream_id;
-  }
-}
-
-void NgHttp2Adapter::SubmitRst(Http2StreamId stream_id,
-                               Http2ErrorCode error_code) {
-  int status =
-      nghttp2_submit_rst_stream(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
-                                stream_id, static_cast<uint32_t>(error_code));
-  if (status < 0) {
-    QUICHE_LOG(WARNING) << "Reset stream failed: " << stream_id
-                        << " with status code " << status;
-  }
-}
-
-int32_t NgHttp2Adapter::SubmitRequest(
-    absl::Span<const Header> headers,
-    std::unique_ptr<DataFrameSource> data_source, void* stream_user_data) {
-  auto nvs = GetNghttp2Nvs(headers);
-  std::unique_ptr<nghttp2_data_provider> provider =
-      MakeDataProvider(data_source.get());
-
-  int32_t stream_id =
-      nghttp2_submit_request(session_->raw_ptr(), nullptr, nvs.data(),
-                             nvs.size(), provider.get(), stream_user_data);
-  sources_.emplace(stream_id, std::move(data_source));
-  QUICHE_VLOG(1) << "Submitted request with " << nvs.size()
-                 << " request headers and user data " << stream_user_data
-                 << "; resulted in stream " << stream_id;
-  return stream_id;
-}
-
-int NgHttp2Adapter::SubmitResponse(
-    Http2StreamId stream_id, absl::Span<const Header> headers,
-    std::unique_ptr<DataFrameSource> data_source) {
-  auto nvs = GetNghttp2Nvs(headers);
-  std::unique_ptr<nghttp2_data_provider> provider =
-      MakeDataProvider(data_source.get());
-
-  sources_.emplace(stream_id, std::move(data_source));
-
-  int result = nghttp2_submit_response(session_->raw_ptr(), stream_id,
-                                       nvs.data(), nvs.size(), provider.get());
-  QUICHE_VLOG(1) << "Submitted response with " << nvs.size()
-                 << " response headers; result = " << result;
-  return result;
-}
-
-int NgHttp2Adapter::SubmitTrailer(Http2StreamId stream_id,
-                                  absl::Span<const Header> trailers) {
-  auto nvs = GetNghttp2Nvs(trailers);
-  int result = nghttp2_submit_trailer(session_->raw_ptr(), stream_id,
-                                      nvs.data(), nvs.size());
-  QUICHE_VLOG(1) << "Submitted trailers with " << nvs.size()
-                 << " response trailers; result = " << result;
-  return result;
-}
-
-void NgHttp2Adapter::SetStreamUserData(Http2StreamId stream_id,
-                                       void* stream_user_data) {
-  nghttp2_session_set_stream_user_data(session_->raw_ptr(), stream_id,
-                                       stream_user_data);
-}
-
-void* NgHttp2Adapter::GetStreamUserData(Http2StreamId stream_id) {
-  return nghttp2_session_get_stream_user_data(session_->raw_ptr(), stream_id);
-}
-
-bool NgHttp2Adapter::ResumeStream(Http2StreamId stream_id) {
-  return 0 == nghttp2_session_resume_data(session_->raw_ptr(), stream_id);
-}
-
-void NgHttp2Adapter::RemoveStream(Http2StreamId stream_id) {
-  sources_.erase(stream_id);
-}
-
-NgHttp2Adapter::NgHttp2Adapter(Http2VisitorInterface& visitor,
-                               Perspective perspective,
-                               const nghttp2_option* options)
-    : Http2Adapter(visitor),
-      visitor_(visitor),
-      options_(options),
-      perspective_(perspective) {}
-
-NgHttp2Adapter::~NgHttp2Adapter() {}
-
-void NgHttp2Adapter::Initialize() {
-  nghttp2_option* owned_options = nullptr;
-  if (options_ == nullptr) {
-    nghttp2_option_new(&owned_options);
-    // Set some common options for compatibility.
-    nghttp2_option_set_no_closed_streams(owned_options, 1);
-    nghttp2_option_set_no_auto_window_update(owned_options, 1);
-    nghttp2_option_set_max_send_header_block_length(owned_options, 0x2000000);
-    nghttp2_option_set_max_outbound_ack(owned_options, 10000);
-    nghttp2_option_set_user_recv_extension_type(owned_options,
-                                                kMetadataFrameType);
-    options_ = owned_options;
-  }
-
-  session_ = absl::make_unique<NgHttp2Session>(perspective_,
-                                               callbacks::Create(), options_,
-                                               static_cast<void*>(&visitor_));
-  if (owned_options != nullptr) {
-    nghttp2_option_del(owned_options);
-  }
-  options_ = nullptr;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_adapter.h b/http2/adapter/nghttp2_adapter.h
deleted file mode 100644
index 257f01a..0000000
--- a/http2/adapter/nghttp2_adapter.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
-#define QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
-
-#include <cstdint>
-
-#include "absl/container/flat_hash_map.h"
-#include "http2/adapter/http2_adapter.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/nghttp2_session.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-class QUICHE_EXPORT_PRIVATE NgHttp2Adapter : public Http2Adapter {
- public:
-  ~NgHttp2Adapter() override;
-
-  // Creates an adapter that functions as a client. Does not take ownership of
-  // |options|.
-  static std::unique_ptr<NgHttp2Adapter> CreateClientAdapter(
-      Http2VisitorInterface& visitor, const nghttp2_option* options = nullptr);
-
-  // Creates an adapter that functions as a server. Does not take ownership of
-  // |options|.
-  static std::unique_ptr<NgHttp2Adapter> CreateServerAdapter(
-      Http2VisitorInterface& visitor, const nghttp2_option* options = nullptr);
-
-  bool IsServerSession() const override;
-  bool want_read() const override { return session_->want_read(); }
-  bool want_write() const override { return session_->want_write(); }
-
-  int64_t ProcessBytes(absl::string_view bytes) override;
-  void SubmitSettings(absl::Span<const Http2Setting> settings) override;
-  void SubmitPriorityForStream(Http2StreamId stream_id,
-                               Http2StreamId parent_stream_id,
-                               int weight,
-                               bool exclusive) override;
-
-  // Submits a PING on the connection. Note that nghttp2 automatically submits
-  // PING acks upon receiving non-ack PINGs from the peer, so callers only use
-  // this method to originate PINGs. See nghttp2_option_set_no_auto_ping_ack().
-  void SubmitPing(Http2PingId ping_id) override;
-
-  void SubmitShutdownNotice() override;
-  void SubmitGoAway(Http2StreamId last_accepted_stream_id,
-                    Http2ErrorCode error_code,
-                    absl::string_view opaque_data) override;
-
-  void SubmitWindowUpdate(Http2StreamId stream_id,
-                          int window_increment) override;
-
-  void SubmitRst(Http2StreamId stream_id, Http2ErrorCode error_code) override;
-
-  void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
-                      std::unique_ptr<MetadataSource> source) override;
-
-  int Send() override;
-
-  int GetSendWindowSize() const override;
-  int GetStreamSendWindowSize(Http2StreamId stream_id) const override;
-
-  int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const override;
-  int GetStreamReceiveWindowSize(Http2StreamId stream_id) const override;
-  int GetReceiveWindowSize() const override;
-
-  int GetHpackEncoderDynamicTableSize() const override;
-  int GetHpackDecoderDynamicTableSize() const override;
-
-  Http2StreamId GetHighestReceivedStreamId() const override;
-
-  void MarkDataConsumedForStream(Http2StreamId stream_id,
-                                 size_t num_bytes) override;
-
-  int32_t SubmitRequest(absl::Span<const Header> headers,
-                        std::unique_ptr<DataFrameSource> data_source,
-                        void* user_data) override;
-
-  int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
-                     std::unique_ptr<DataFrameSource> data_source) override;
-
-  int SubmitTrailer(Http2StreamId stream_id,
-                    absl::Span<const Header> trailers) override;
-
-  void SetStreamUserData(Http2StreamId stream_id, void* user_data) override;
-  void* GetStreamUserData(Http2StreamId stream_id) override;
-
-  bool ResumeStream(Http2StreamId stream_id) override;
-
-  // Removes references to the `stream_id` from this adapter.
-  void RemoveStream(Http2StreamId stream_id);
-
-  // Accessor for testing.
-  size_t sources_size() const { return sources_.size(); }
-
- private:
-  NgHttp2Adapter(Http2VisitorInterface& visitor, Perspective perspective,
-                 const nghttp2_option* options);
-
-  // Performs any necessary initialization of the underlying HTTP/2 session,
-  // such as preparing initial SETTINGS.
-  void Initialize();
-
-  std::unique_ptr<NgHttp2Session> session_;
-  Http2VisitorInterface& visitor_;
-  const nghttp2_option* options_;
-  Perspective perspective_;
-
-  absl::flat_hash_map<int32_t, std::unique_ptr<DataFrameSource>> sources_;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
diff --git a/http2/adapter/nghttp2_adapter_test.cc b/http2/adapter/nghttp2_adapter_test.cc
deleted file mode 100644
index 4341a24..0000000
--- a/http2/adapter/nghttp2_adapter_test.cc
+++ /dev/null
@@ -1,6391 +0,0 @@
-#include "http2/adapter/nghttp2_adapter.h"
-
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/mock_http2_visitor.h"
-#include "http2/adapter/nghttp2.h"
-#include "http2/adapter/nghttp2_test_utils.h"
-#include "http2/adapter/oghttp2_util.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using ConnectionError = Http2VisitorInterface::ConnectionError;
-
-using spdy::SpdyFrameType;
-using testing::_;
-
-enum FrameType {
-  DATA,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-  CONTINUATION,
-};
-
-// This send callback assumes |source|'s pointer is a TestDataSource, and
-// |user_data| is a Http2VisitorInterface.
-int TestSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/,
-                     const uint8_t* framehd, size_t length,
-                     nghttp2_data_source* source, void* user_data) {
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  // Send the frame header via the visitor.
-  ssize_t result = visitor->OnReadyToSend(ToStringView(framehd, 9));
-  if (result == 0) {
-    return NGHTTP2_ERR_WOULDBLOCK;
-  }
-  auto* test_source = static_cast<TestDataSource*>(source->ptr);
-  absl::string_view payload = test_source->ReadNext(length);
-  // Send the frame payload via the visitor.
-  visitor->OnReadyToSend(payload);
-  return 0;
-}
-
-TEST(NgHttp2AdapterTest, ClientConstruction) {
-  testing::StrictMock<MockHttp2Visitor> visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  ASSERT_NE(nullptr, adapter);
-  EXPECT_TRUE(adapter->want_read());
-  EXPECT_FALSE(adapter->want_write());
-  EXPECT_FALSE(adapter->IsServerSession());
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesFrames) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
-  visitor.Clear();
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string initial_frames = TestFrameSequence()
-                                         .ServerPreface()
-                                         .Ping(42)
-                                         .WindowUpdate(0, 1000)
-                                         .Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_EQ(adapter->GetSendWindowSize(), kInitialFlowControlWindowSize + 1000);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
-
-  result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
-  visitor.Clear();
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  const std::vector<Header> headers3 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/three"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const char* kSentinel3 = "arbitrary pointer 3";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
-  ASSERT_GT(stream_id2, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id2;
-
-  const int32_t stream_id3 =
-      adapter->SubmitRequest(headers3, nullptr, const_cast<char*>(kSentinel3));
-  ASSERT_GT(stream_id3, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id3;
-
-  const char* kSentinel2 = "arbitrary pointer 2";
-  adapter->SetStreamUserData(stream_id2, const_cast<char*>(kSentinel2));
-  adapter->SetStreamUserData(stream_id3, nullptr);
-
-  EXPECT_EQ(adapter->sources_size(), 3);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id3, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id3, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  // All streams are active and have not yet received any data, so the receive
-  // window should be at the initial value.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(stream_id1));
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(stream_id2));
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(stream_id3));
-
-  // Upper bound on the flow control receive window should be the initial value.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowLimit(stream_id1));
-
-  // Connection has not yet received any data.
-  EXPECT_EQ(kInitialFlowControlWindowSize, adapter->GetReceiveWindowSize());
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(stream_id1));
-  EXPECT_EQ(kSentinel2, adapter->GetStreamUserData(stream_id2));
-  EXPECT_EQ(nullptr, adapter->GetStreamUserData(stream_id3));
-
-  EXPECT_EQ(0, adapter->GetHpackDecoderDynamicTableSize());
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
-          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR))
-      .WillOnce(
-          [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
-            adapter->RemoveStream(stream_id);
-            return true;
-          });
-  EXPECT_CALL(visitor, OnFrameHeader(0, 19, GOAWAY, 0));
-  EXPECT_CALL(visitor,
-              OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!"));
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  // First stream has received some data.
-  EXPECT_GT(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(stream_id1));
-  // Second stream was closed.
-  EXPECT_EQ(-1, adapter->GetStreamReceiveWindowSize(stream_id2));
-  // Third stream has not received any data.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(stream_id3));
-
-  // One stream was closed.
-  EXPECT_EQ(adapter->sources_size(), 2);
-
-  // Connection window should be the same as the first stream.
-  EXPECT_EQ(adapter->GetReceiveWindowSize(),
-            adapter->GetStreamReceiveWindowSize(stream_id1));
-
-  // Upper bound on the flow control receive window should still be the initial
-  // value.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowLimit(stream_id1));
-
-  EXPECT_GT(adapter->GetHpackDecoderDynamicTableSize(), 0);
-
-  // Should be 3, but this method only works for server adapters.
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  // Even though the client recieved a GOAWAY, streams 1 and 5 are still active.
-  EXPECT_TRUE(adapter->want_read());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 0, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 0));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR))
-      .WillOnce(
-          [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
-            adapter->RemoveStream(stream_id);
-            return true;
-          });
-  EXPECT_CALL(visitor, OnFrameHeader(5, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(5, Http2ErrorCode::REFUSED_STREAM));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM))
-      .WillOnce(
-          [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
-            adapter->RemoveStream(stream_id);
-            return true;
-          });
-  adapter->ProcessBytes(TestFrameSequence()
-                            .Data(1, "", true)
-                            .RstStream(5, Http2ErrorCode::REFUSED_STREAM)
-                            .Serialize());
-
-  // Should be 5, but this method only works for server adapters.
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  // After receiving END_STREAM for 1 and RST_STREAM for 5, the session no
-  // longer expects reads.
-  EXPECT_FALSE(adapter->want_read());
-  EXPECT_EQ(adapter->sources_size(), 0);
-
-  // Client will not have anything else to write.
-  EXPECT_FALSE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-}
-
-TEST(NgHttp2AdapterTest, QueuingWindowUpdateAffectsWindow) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  EXPECT_EQ(adapter->GetReceiveWindowSize(), kInitialFlowControlWindowSize);
-  adapter->SubmitWindowUpdate(0, 10000);
-  EXPECT_EQ(adapter->GetReceiveWindowSize(),
-            kInitialFlowControlWindowSize + 10000);
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
-            kInitialFlowControlWindowSize);
-  adapter->SubmitWindowUpdate(1, 20000);
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
-            kInitialFlowControlWindowSize + 20000);
-}
-
-TEST(NgHttp2AdapterTest, AckOfSettingInitialWindowSizeAffectsWindow) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id1 = adapter->SubmitRequest(headers, nullptr, nullptr);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  int64_t parse_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(parse_result));
-
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
-            kInitialFlowControlWindowSize);
-  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000u}});
-  // No update for the first stream, yet.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
-            kInitialFlowControlWindowSize);
-
-  // Ack of server's initial settings.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  // Outbound SETTINGS containing INITIAL_WINDOW_SIZE.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  // Still no update, as a SETTINGS ack has not yet been received.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
-            kInitialFlowControlWindowSize);
-
-  const std::string settings_ack =
-      TestFrameSequence().SettingsAck().Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  parse_result = adapter->ProcessBytes(settings_ack);
-  EXPECT_EQ(settings_ack.size(), static_cast<size_t>(parse_result));
-
-  // Stream window has been updated.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1), 80000);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-  const int32_t stream_id2 = adapter->SubmitRequest(headers, nullptr, nullptr);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id2), 80000);
-}
-
-TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithFin) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}}, /*fin=*/false)
-          .Headers(1, {{":status", "100"}}, /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithContent) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}},
-                   /*fin=*/false)
-          .Data(1, "We needed the final headers before data, whoops")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithContentLength) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}, {"content-length", "42"}},
-                   /*fin=*/false)
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [content-length], value: [42]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandles204WithContent) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
-  ASSERT_GT(stream_id2, stream_id1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "204"}, {"content-length", "2"}},
-                   /*fin=*/false)
-          .Data(1, "hi")
-          .Headers(3, {{":status", "204"}}, /*fin=*/false)
-          .Data(3, "hi")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "204"));
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [content-length], value: [2]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":status", "204"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(3, 2));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandles304WithContent) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
-                   /*fin=*/false)
-          .Data(1, "hi")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandles304WithContentLength) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesTrailers) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Headers(1, {{"final-status", "A-OK"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "final-status", "A-OK"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientSendsTrailers) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const std::string kBody = "This is an example request body.";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  // nghttp2 does not require that the data source indicate the end of data
-  // before trailers are enqueued.
-
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  visitor.Clear();
-
-  const std::vector<Header> trailers1 =
-      ToHeaders({{"extra-info", "Trailers are weird but good?"}});
-  adapter->SubmitTrailer(stream_id1, trailers1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  data = visitor.data();
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesMetadata) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Metadata(0, "Example connection metadata")
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(1, "Example stream metadata")
-          .Data(1, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesMetadataWithEmptyPayload) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(1, "")
-          .Data(1, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(3);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesMetadataWithError) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Metadata(0, "Example connection metadata")
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(1, "Example stream metadata")
-          .Data(1, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _))
-      .WillOnce(testing::Return(false));
-  // Remaining frames are not processed due to the error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  // The false return from OnMetadataForStream() results in a connection error.
-  EXPECT_EQ(stream_result, NGHTTP2_ERR_CALLBACK_FAILURE);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_TRUE(adapter->want_read());  // Even after an error. Why?
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesHpackHeaderTableSetting) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 = ToHeaders({
-      {":method", "GET"},
-      {":scheme", "http"},
-      {":authority", "example.com"},
-      {":path", "/this/is/request/one"},
-      {"x-i-do-not-like", "green eggs and ham"},
-      {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
-      {"x-like-them-in-a-house", "no"},
-      {"x-like-them-with-a-mouse", "no"},
-  });
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 100);
-
-  const std::string stream_frames =
-      TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 100u}}).Serialize();
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
-
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  EXPECT_LE(adapter->GetHpackEncoderDynamicTableSize(), 100);
-}
-
-TEST(NgHttp2AdapterTest, ClientHandlesInvalidTrailers) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Headers(1, {{":bad-status", "9000"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [:bad-status], value: [9000]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  // Bad status trailer will cause a PROTOCOL_ERROR. The header is never
-  // delivered in an OnHeaderForStream callback.
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id1, 4, 0x0, 1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientRstStreamWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
-      .WillOnce(testing::DoAll(
-          testing::InvokeWithoutArgs([&adapter]() {
-            adapter->SubmitRst(1, Http2ErrorCode::REFUSED_STREAM);
-          }),
-          testing::Return(Http2VisitorInterface::HEADER_RST_STREAM)));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, stream_id1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::REFUSED_STREAM));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
-      .WillOnce(
-          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
-  // Translation to nghttp2 treats this error as a general parsing error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(-902 /* NGHTTP2_ERR_CALLBACK_FAILURE */, stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeadersOnly) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
-      .WillOnce(
-          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
-  // Translation to nghttp2 treats this error as a general parsing error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(-902 /* NGHTTP2_ERR_CALLBACK_FAILURE */, stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientRejectsHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1))
-      .WillOnce(testing::Return(false));
-  // Rejecting headers leads to a connection error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientStartsShutdown) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  // No-op for a client implementation.
-  adapter->SubmitShutdownNotice();
-  EXPECT_FALSE(adapter->want_write());
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_EQ(visitor.data(), spdy::kHttp2ConnectionHeaderPrefix);
-}
-
-TEST(NgHttp2AdapterTest, ClientReceivesGoAway) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
-  ASSERT_GT(stream_id2, stream_id1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
-          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
-          .WindowUpdate(0, 42)
-          .WindowUpdate(1, 42)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
-  EXPECT_CALL(visitor,
-              OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion"));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 42));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  // Intriguingly, despite want_write() being true, the sent data is empty; the
-  // receipt of the GOAWAY prevents the SETTINGS ack from being written.
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-}
-
-TEST(NgHttp2AdapterTest, ClientFailsOnGoAway) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
-  EXPECT_CALL(visitor,
-              OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion"))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientRejects101Response) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"},
-                 {"upgrade", "new-protocol"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "101"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [:status], value: [101]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(static_cast<int64_t>(stream_frames.size()), stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                  static_cast<uint32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientSubmitRequest) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  EXPECT_THAT(visitor.data(),
-              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
-  EXPECT_FALSE(adapter->want_write());
-  const char* kSentinel = "";
-  const absl::string_view kBody = "This is an example request body.";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), const_cast<char*>(kSentinel));
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(stream_id));
-  EXPECT_EQ(kInitialFlowControlWindowSize, adapter->GetReceiveWindowSize());
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowLimit(stream_id));
-
-  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
-
-  // Some data was sent, so the remaining send window size should be less than
-  // the default.
-  EXPECT_LT(adapter->GetStreamSendWindowSize(stream_id),
-            kInitialFlowControlWindowSize);
-  EXPECT_GT(adapter->GetStreamSendWindowSize(stream_id), 0);
-  // Send window for a nonexistent stream is not available.
-  EXPECT_EQ(-1, adapter->GetStreamSendWindowSize(stream_id + 2));
-
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             nullptr, nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-  const char* kSentinel2 = "arbitrary pointer 2";
-  EXPECT_EQ(nullptr, adapter->GetStreamUserData(stream_id));
-  adapter->SetStreamUserData(stream_id, const_cast<char*>(kSentinel2));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-
-  EXPECT_EQ(kSentinel2, adapter->GetStreamUserData(stream_id));
-
-  // No data was sent (just HEADERS), so the remaining send window size should
-  // still be the default.
-  EXPECT_EQ(adapter->GetStreamSendWindowSize(stream_id),
-            kInitialFlowControlWindowSize);
-}
-
-// This is really a test of the MakeZeroCopyDataFrameSource adapter, but I
-// wasn't sure where else to put it.
-TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProvider) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  EXPECT_THAT(visitor.data(),
-              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_FALSE(adapter->want_write());
-  const absl::string_view kBody = "This is an example request body.";
-  // This test will use TestDataSource as the source of the body payload data.
-  TestDataSource body1{kBody};
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-  nghttp2_send_data_callback send_callback = &TestSendCallback;
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(frame_source), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-// This test verifies how nghttp2 behaves when a data source becomes
-// read-blocked.
-TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProviderAndReadBlock) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const absl::string_view kBody = "This is an example request body.";
-  // This test will use TestDataSource as the source of the body payload data.
-  TestDataSource body1{kBody};
-  body1.set_is_data_available(false);
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-  nghttp2_send_data_callback send_callback = &TestSendCallback;
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(frame_source), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  // Resume the deferred stream.
-  body1.set_is_data_available(true);
-  EXPECT_TRUE(adapter->ResumeStream(stream_id));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
-  EXPECT_FALSE(adapter->want_write());
-
-  // Stream data is done, so this stream cannot be resumed.
-  EXPECT_FALSE(adapter->ResumeStream(stream_id));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-// This test verifies how nghttp2 behaves when a data source is read block, then
-// ends with an empty DATA frame.
-TEST(NgHttp2AdapterTest, ClientSubmitRequestEmptyDataWithFin) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const absl::string_view kEmptyBody = "";
-  // This test will use TestDataSource as the source of the body payload data.
-  TestDataSource body1{kEmptyBody};
-  body1.set_is_data_available(false);
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-  nghttp2_send_data_callback send_callback = &TestSendCallback;
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(frame_source), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  // Resume the deferred stream.
-  body1.set_is_data_available(true);
-  EXPECT_TRUE(adapter->ResumeStream(stream_id));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 0, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
-  EXPECT_FALSE(adapter->want_write());
-
-  // Stream data is done, so this stream cannot be resumed.
-  EXPECT_FALSE(adapter->ResumeStream(stream_id));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-// This test verifies how nghttp2 behaves when a connection becomes
-// write-blocked.
-TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProviderAndWriteBlock) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const absl::string_view kBody = "This is an example request body.";
-  // This test will use TestDataSource as the source of the body payload data.
-  TestDataSource body1{kBody};
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-  nghttp2_send_data_callback send_callback = &TestSendCallback;
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(frame_source), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  visitor.set_is_write_blocked(true);
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  visitor.set_is_write_blocked(false);
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ClientReceivesDataOnClosedStream) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  EXPECT_THAT(visitor.data(),
-              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  // Client SETTINGS ack
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Let the client open a stream with a request.
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             nullptr, nullptr);
-  EXPECT_GT(stream_id, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  // Let the client RST_STREAM the stream it opened.
-  adapter->SubmitRst(stream_id, Http2ErrorCode::CANCEL);
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id, _, 0x0,
-                                   static_cast<int>(Http2ErrorCode::CANCEL)));
-  EXPECT_CALL(visitor, OnCloseStream(stream_id, Http2ErrorCode::CANCEL));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
-  visitor.Clear();
-
-  // Let the server send a response on the stream. (It might not have received
-  // the RST_STREAM yet.)
-  const std::string response_frames =
-      TestFrameSequence()
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(stream_id, "This is the response body.", /*fin=*/true)
-          .Serialize();
-
-  // The visitor gets notified about the HEADERS frame but not the DATA frame on
-  // the closed stream. No further processing for either frame occurs.
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, DATA, _)).Times(0);
-
-  const int64_t response_result = adapter->ProcessBytes(response_frames);
-  EXPECT_EQ(response_frames.size(), response_result);
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ClientQueuesRequests) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  adapter->SubmitSettings({});
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  adapter->Send();
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ServerPreface({{MAX_CONCURRENT_STREAMS, 2}})
-          .SettingsAck()
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{
-                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-
-  adapter->ProcessBytes(initial_frames);
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/example/request"}});
-  std::vector<int32_t> stream_ids;
-  // Start two, which hits the limit.
-  int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-  // Start two more, which must be queued.
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[0], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[0], _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[1], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[1], _, 0x5, 0));
-
-  adapter->Send();
-
-  const std::string update_streams =
-      TestFrameSequence().Settings({{MAX_CONCURRENT_STREAMS, 5}}).Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{
-                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  adapter->ProcessBytes(update_streams);
-
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[2], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[2], _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[3], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[3], _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[4], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[4], _, 0x5, 0));
-  // Header frames should all have been sent in order, regardless of any
-  // queuing.
-
-  adapter->Send();
-}
-
-TEST(NgHttp2AdapterTest, SubmitMetadata) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType)}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, SubmitMetadataMultipleFrames) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const auto kLargeValue = std::string(63 * 1024, 'a');
-  auto source = absl::make_unique<TestMetadataSource>(
-      ToHeaderBlock(ToHeaders({{"large-value", kLargeValue}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-  EXPECT_TRUE(adapter->want_write());
-
-  testing::InSequence seq;
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType),
-                            static_cast<SpdyFrameType>(kMetadataFrameType),
-                            static_cast<SpdyFrameType>(kMetadataFrameType),
-                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, SubmitConnectionMetadata) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(0, 16384u, std::move(source));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 0, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 0, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType)}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ClientObeysMaxConcurrentStreams) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  // Client preface does not appear to include the mandatory SETTINGS frame.
-  EXPECT_THAT(visitor.data(),
-              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ServerPreface({{.id = MAX_CONCURRENT_STREAMS, .value = 1}})
-          .Serialize();
-  testing::InSequence s;
-
-  // Server preface (SETTINGS with MAX_CONCURRENT_STREAMS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting);
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_FALSE(adapter->want_write());
-  const absl::string_view kBody = "This is an example request body.";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-  const int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  const int next_stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/two"}}),
-                             nullptr, nullptr);
-
-  // A new pending stream is created, but because of MAX_CONCURRENT_STREAMS, the
-  // session should not want to write it at the moment.
-  EXPECT_GT(next_stream_id, stream_id);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(stream_id, "This is the response body.", /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(stream_id, "server", "my-fake-server"));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
-                                         "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0x1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
-  EXPECT_CALL(visitor,
-              OnDataForStream(stream_id, "This is the response body."));
-  EXPECT_CALL(visitor, OnEndStream(stream_id));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  // The first stream should close, which should make the session want to write
-  // the next stream.
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, next_stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, next_stream_id, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ClientReceivesInitialWindowSetting) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .Settings({{INITIAL_WINDOW_SIZE, 80000u}})
-          .WindowUpdate(0, 65536)
-          .Serialize();
-  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int64_t result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  const std::string kLongBody = std::string(81000, 'c');
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kLongBody);
-  body1->EndData();
-  const int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  // The client can send more than 4 frames (65536 bytes) of data.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(4);
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14464, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA, SpdyFrameType::DATA}));
-}
-
-TEST(NgHttp2AdapterTest, ClientReceivesInitialWindowSettingAfterStreamStart) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().WindowUpdate(0, 65536).Serialize();
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int64_t result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string kLongBody = std::string(81000, 'c');
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kLongBody);
-  body1->EndData();
-  const int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  // The client can only send 65535 bytes of data, as the stream window has not
-  // yet been increased.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(3);
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16383, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA}));
-  visitor.Clear();
-
-  // Can't write any more due to flow control.
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string settings_frame =
-      TestFrameSequence().Settings({{INITIAL_WINDOW_SIZE, 80000u}}).Serialize();
-  // SETTINGS with INITIAL_STREAM_WINDOW
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t settings_result = adapter->ProcessBytes(settings_frame);
-  EXPECT_EQ(settings_frame.size(), static_cast<size_t>(settings_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  // The client can write more after receiving the INITIAL_WINDOW_SIZE setting.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14465, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::DATA}));
-}
-
-TEST(NgHttp2AdapterTest, InvalidInitialWindowSetting) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const uint32_t kTooLargeInitialWindow = 1u << 31;
-  const std::string initial_frames =
-      TestFrameSequence()
-          .Settings({{INITIAL_WINDOW_SIZE, kTooLargeInitialWindow}})
-          .Serialize();
-  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  0, Http2VisitorInterface::InvalidFrameError::kFlowControl));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a GOAWAY.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  int64_t result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::GOAWAY}));
-  visitor.Clear();
-}
-
-TEST(NgHttp2AdapterTest, InitialWindowSettingCausesOverflow) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-  int64_t write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const uint32_t kLargeInitialWindow = (1u << 31) - 1;
-  const std::string frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(stream_id, {{":status", "200"}}, /*fin=*/false)
-          .WindowUpdate(stream_id, 65536u)
-          .Settings({{INITIAL_WINDOW_SIZE, kLargeInitialWindow}})
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 4, WINDOW_UPDATE, 0x0));
-  EXPECT_CALL(visitor, OnWindowUpdate(stream_id, 65536));
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE,
-                                              kLargeInitialWindow}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  // The stream window update plus the SETTINGS frame with INITIAL_WINDOW_SIZE
-  // pushes the stream's flow control window outside of the acceptable range.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, 4, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(RST_STREAM, stream_id, 4, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id, Http2ErrorCode::FLOW_CONTROL_ERROR));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ClientForbidsPushPromise) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  adapter->SubmitSettings({{ENABLE_PUSH, 0}});
-
-  testing::InSequence s;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  int write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-
-  visitor.Clear();
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-  write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::vector<Header> push_headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/push"}});
-  const std::string frames = TestFrameSequence()
-                                 .ServerPreface()
-                                 .SettingsAck()
-                                 .PushPromise(stream_id, 2, push_headers)
-                                 .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // SETTINGS ack (to acknowledge PUSH_ENABLED=0)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  // The PUSH_PROMISE is now treated as an invalid frame.
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, PUSH_PROMISE, _));
-  EXPECT_CALL(visitor, OnInvalidFrame(stream_id, _));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), read_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-}
-
-TEST(NgHttp2AdapterTest, ClientForbidsPushStream) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-  adapter->SubmitSettings({{ENABLE_PUSH, 0}});
-
-  testing::InSequence s;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  int write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-
-  visitor.Clear();
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-  write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .SettingsAck()
-          .Headers(2,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // SETTINGS ack (to acknowledge PUSH_ENABLED=0)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  // The push HEADERS are invalid.
-  EXPECT_CALL(visitor, OnFrameHeader(2, _, HEADERS, _));
-  EXPECT_CALL(visitor, OnInvalidFrame(2, _));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), read_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-}
-
-TEST(NgHttp2AdapterTest, FailureSendingConnectionPreface) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  visitor.set_has_write_error();
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
-
-  int result = adapter->Send();
-  EXPECT_EQ(result, NGHTTP2_ERR_CALLBACK_FAILURE);
-}
-
-TEST(NgHttp2AdapterTest, MaxFrameSizeSettingNotAppliedBeforeAck) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
-  const int32_t stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
-                                        {":scheme", "https"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             /*data_source=*/nullptr, /*user_data=*/nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  testing::InSequence s;
-
-  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string server_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "200"}}, /*fin=*/false)
-          .Data(1, std::string(large_frame_size, 'a'))
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Response HEADERS. Because the SETTINGS with MAX_FRAME_SIZE was not
-  // acknowledged, the large DATA is treated as a connection error. Note that
-  // nghttp2 does not deliver any DATA or connection error events.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  const int64_t process_result = adapter->ProcessBytes(server_frames);
-  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::FRAME_SIZE_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, MaxFrameSizeSettingAppliedAfterAck) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
-
-  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
-  const int32_t stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
-                                        {":scheme", "https"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             /*data_source=*/nullptr, /*user_data=*/nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  testing::InSequence s;
-
-  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string server_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .SettingsAck()
-          .Headers(1, {{":status", "200"}}, /*fin=*/false)
-          .Data(1, std::string(large_frame_size, 'a'))
-          .Serialize();
-
-  // Server preface (empty SETTINGS) and ack of SETTINGS.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-
-  // Response HEADERS and DATA. Because the SETTINGS with MAX_FRAME_SIZE was
-  // acknowledged, the large DATA is accepted without any error.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, large_frame_size));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-
-  const int64_t process_result = adapter->ProcessBytes(server_frames);
-  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
-
-  // Client ack of SETTINGS.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ConnectionErrorOnControlFrameSent) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().Ping(42).Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // PING
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0))
-      .WillOnce(testing::Return(-902));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
-
-  int send_result = adapter->Send();
-  EXPECT_LT(send_result, 0);
-
-  // Apparently nghttp2 retries sending the frames that had failed before.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
-  send_result = adapter->Send();
-  EXPECT_EQ(send_result, 0);
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ConnectionErrorOnDataFrameSent) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body->AppendPayload("Here is some data, which will lead to a fatal error");
-  TestDataFrameSource* body_ptr = body.get();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}}), std::move(body));
-  ASSERT_EQ(0, submit_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  // Stream 1, with doomed DATA
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0))
-      .WillOnce(testing::Return(-902));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
-
-  int send_result = adapter->Send();
-  EXPECT_LT(send_result, 0);
-
-  // The test data source got a signal that the first chunk of data was sent
-  // successfully, so discarded that data internally. However, due to the send
-  // error, the next Send() from nghttp2 will try to send that exact same data
-  // again. Without this line appending the exact same data back to the data
-  // source, the test crashes. It is not clear how the data source would know to
-  // not discard the data, unless told by the session? This is not intuitive.
-  body_ptr->AppendPayload(
-      "Here is some data, which will lead to a fatal error");
-
-  // Apparently nghttp2 retries sending the frames that had failed before.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(send_result, 0);
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ServerConstruction) {
-  testing::StrictMock<MockHttp2Visitor> visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  ASSERT_NE(nullptr, adapter);
-  EXPECT_TRUE(adapter->want_read());
-  EXPECT_FALSE(adapter->want_write());
-  EXPECT_TRUE(adapter->IsServerSession());
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesFrames) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-  EXPECT_EQ(0, adapter->GetHpackDecoderDynamicTableSize());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Ping(42)
-                                 .WindowUpdate(0, 1000)
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
-      .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
-        adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
-        return true;
-      }));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "http"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/two"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(47, false));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
-
-  EXPECT_GT(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowSize(1));
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1),
-            adapter->GetReceiveWindowSize());
-  // Upper bound should still be the original value.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            adapter->GetStreamReceiveWindowLimit(1));
-
-  EXPECT_GT(adapter->GetHpackDecoderDynamicTableSize(), 0);
-
-  // Because stream 3 has already been closed, it's not possible to set user
-  // data.
-  const char* kSentinel3 = "another arbitrary pointer";
-  adapter->SetStreamUserData(3, const_cast<char*>(kSentinel3));
-  EXPECT_EQ(nullptr, adapter->GetStreamUserData(3));
-
-  EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_EQ(adapter->GetSendWindowSize(), kInitialFlowControlWindowSize + 1000);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack, two PING acks.
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING,
-                            SpdyFrameType::PING}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesDataWithPadding) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.",
-                                       /*fin=*/true, /*padding_length=*/39)
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25 + 39, DATA, 0x9));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25 + 39));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-  // Note: nghttp2 passes padding information after the actual data.
-  EXPECT_CALL(visitor, OnDataPaddingLength(1, 39));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesHostHeader) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":path", "/this/is/request/one"},
-                                           {"host", "example.com"}},
-                                          /*fin=*/true)
-                                 .Headers(3,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"host", "example.com"}},
-                                          /*fin=*/true)
-                                 .Headers(5,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "foo.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"host", "bar.com"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(5));
-  EXPECT_CALL(visitor, OnEndStream(5));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  visitor.Clear();
-}
-
-// Tests the case where the response body is in the progress of being sent while
-// trailers are queued.
-TEST(NgHttp2AdapterTest, ServerSubmitsTrailersWhileDataDeferred) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  visitor.Clear();
-
-  const absl::string_view kBody = "This is an example response body.";
-
-  // The body source must indicate that the end of the body is not the end of
-  // the stream.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  auto* body1_ptr = body1.get();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  int trailer_result =
-      adapter->SubmitTrailer(1, ToHeaders({{"final-status", "a-ok"}}));
-  ASSERT_EQ(trailer_result, 0);
-
-  // Even though the data source has not finished sending data, nghttp2 will
-  // write the trailers anyway.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  // Resuming the stream results in the library wanting to write again.
-  body1_ptr->AppendPayload(kBody);
-  body1_ptr->EndData();
-  adapter->ResumeStream(1);
-  EXPECT_TRUE(adapter->want_write());
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-
-  // But no data is written for the stream.
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControl) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 // 70000 bytes of data
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(4464, 'a'))
-                                 .Serialize();
-
-  testing::InSequence s;
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  // No further frame data or headers are delivered.
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // No SETTINGS ack is written.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControlWithOneDataFrame) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  // Allow the client to send a DATA frame that exceeds the connection flow
-  // control window.
-  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "POST"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  int64_t process_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Outbound SETTINGS containing MAX_FRAME_SIZE.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  // Ack of client's initial settings.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
-  // overflow the connection-level window. The result should be a GOAWAY.
-  const std::string overflow_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Data(1, std::string(window_overflow_bytes, 'a'))
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, window_overflow_bytes));
-  // No further frame data is delivered.
-
-  process_result = adapter->ProcessBytes(overflow_frames);
-  EXPECT_EQ(overflow_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControlAcrossReads) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  // Allow the client to send a DATA frame that exceeds the connection flow
-  // control window.
-  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "POST"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  int64_t process_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Outbound SETTINGS containing MAX_FRAME_SIZE.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  // Ack of client's initial settings.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
-  // overflow the connection-level window. The result should be a GOAWAY, but
-  // because the processing is split across several calls, nghttp2 instead
-  // delivers the data payloads (which the visitor then consumes). This is a bug
-  // in nghttp2, which should recognize the flow control error.
-  const std::string overflow_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Data(1, std::string(window_overflow_bytes, 'a'))
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, window_overflow_bytes));
-  // BUG: The visitor should not have received the data.
-  EXPECT_CALL(visitor, OnDataForStream(1, _))
-      .WillRepeatedly(
-          [&adapter](Http2StreamId stream_id, absl::string_view data) {
-            adapter->MarkDataConsumedForStream(stream_id, data.size());
-            return true;
-          });
-
-  const size_t chunk_length = 16384;
-  ASSERT_GE(overflow_frames.size(), chunk_length);
-  absl::string_view remaining = overflow_frames;
-  while (!remaining.empty()) {
-    absl::string_view chunk = remaining.substr(0, chunk_length);
-    process_result = adapter->ProcessBytes(chunk);
-    EXPECT_EQ(chunk.length(), static_cast<size_t>(process_result));
-
-    remaining.remove_prefix(chunk.length());
-  }
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::WINDOW_UPDATE,
-                                            SpdyFrameType::WINDOW_UPDATE}));
-}
-
-TEST(NgHttp2AdapterTest, ClientDisobeysStreamFlowControl) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  const std::string more_frames = TestFrameSequence()
-                                      // 70000 bytes of data
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(4464, 'a'))
-                                      .Serialize();
-
-  testing::InSequence s;
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  adapter->SubmitWindowUpdate(0, 20000);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::WINDOW_UPDATE}));
-  visitor.Clear();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  // No further frame data or headers for stream 1 are delivered.
-
-  result = adapter->ProcessBytes(more_frames);
-  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::FLOW_CONTROL_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerErrorWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
-      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
-  // DATA frame is not delivered to the visitor.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerErrorWhileHandlingHeadersDropsFrames) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .Metadata(1, "This is the request metadata.")
-                                 .RstStream(1, Http2ErrorCode::CANCEL)
-                                 .WindowUpdate(0, 2000)
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/false)
-                                 .Metadata(3, "This is the request metadata.",
-                                           /*multiple_frames=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
-      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
-  // For the RST_STREAM-marked stream, the control frames and METADATA frame but
-  // not the DATA frame are delivered to the visitor.
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 0));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(3, "This is the re"))
-      .WillOnce(testing::DoAll(testing::InvokeWithoutArgs([&adapter]() {
-                                 adapter->SubmitRst(
-                                     3, Http2ErrorCode::REFUSED_STREAM);
-                               }),
-                               testing::Return(true)));
-  // The rest of the metadata is still delivered to the visitor.
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(3, "quest metadata."));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(3));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerConnectionErrorWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"Accept", "uppercase, oh boy!"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnErrorDebug);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader))
-      .WillOnce(testing::Return(false));
-  // Translation to nghttp2 treats this error as a general parsing error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(result, NGHTTP2_ERR_CALLBACK_FAILURE);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack and RST_STREAM
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerErrorAfterHandlingHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(-902, result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-// Exercises the case when a visitor chooses to reject a frame based solely on
-// the frame header, which is a fatal error for the connection.
-TEST(NgHttp2AdapterTest, ServerRejectsFrameHeader) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Ping(64)
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(-902, result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerRejectsBeginningOfData) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack.
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerRejectsStreamData) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
-  EXPECT_CALL(visitor, OnDataForStream(1, _)).WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack.
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerReceivesTooLargeHeader) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  // nghttp2 will accept a maximum of 64kB of huffman encoded data per header
-  // field.
-  const std::string too_large_value = std::string(80 * 1024, 'q');
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"x-toobig", too_large_value}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  // Further header processing is skipped, as the header field is too large.
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Since nghttp2 opted not to process the header, it generates a GOAWAY with
-  // error code COMPRESSION_ERROR.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, 8, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, 8, 0x0,
-                          static_cast<int>(Http2ErrorCode::COMPRESSION_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // GOAWAY.
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerReceivesInvalidAuthority) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "ex|ample.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [:authority], value: [ex|ample.com]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0x0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerSubmitResponse) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
-      .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
-        adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
-        return true;
-      }));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
-
-  // Server will want to send a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
-
-  EXPECT_FALSE(adapter->want_write());
-  const absl::string_view kBody = "This is an example response body.";
-  // A data fin is not sent so that the stream remains open, and the flow
-  // control state can be verified.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  int submit_result = adapter->SubmitResponse(
-      1,
-      ToHeaders({{":status", "404"},
-                 {"x-comment", "I have no idea what you're talking about."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  // Stream user data should have been set successfully after receiving headers.
-  EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
-  adapter->SetStreamUserData(1, nullptr);
-  EXPECT_EQ(nullptr, adapter->GetStreamUserData(1));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  EXPECT_FALSE(adapter->want_write());
-
-  // Some data was sent, so the remaining send window size should be less than
-  // the default.
-  EXPECT_LT(adapter->GetStreamSendWindowSize(1), kInitialFlowControlWindowSize);
-  EXPECT_GT(adapter->GetStreamSendWindowSize(1), 0);
-  // Send window for a nonexistent stream is not available.
-  EXPECT_EQ(adapter->GetStreamSendWindowSize(3), -1);
-
-  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
-}
-
-// Should also test: client attempts shutdown, server attempts shutdown after an
-// explicit GOAWAY.
-TEST(NgHttp2AdapterTest, ServerSendsShutdown) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  adapter->SubmitShutdownNotice();
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerSendsTrailers) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  // Server will want to send a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_FALSE(adapter->want_write());
-  const absl::string_view kBody = "This is an example response body.";
-
-  // The body source must indicate that the end of the body is not the end of
-  // the stream.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  // The body source has been exhausted by the call to Send() above.
-  int trailer_result = adapter->SubmitTrailer(
-      1, ToHeaders({{"final-status", "a-ok"},
-                    {"x-comment", "trailers sure are cool"}}));
-  ASSERT_EQ(trailer_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-}
-
-TEST(NgHttp2AdapterTest, ClientSendsContinuation) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true,
-                                          /*add_continuation=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 1));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-}
-
-TEST(NgHttp2AdapterTest, ClientSendsMetadataWithContinuation) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Metadata(0, "Example connection metadata in multiple frames", true)
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false,
-                   /*add_continuation=*/true)
-          .Metadata(1,
-                    "Some stream metadata that's also sent in multiple frames",
-                    true)
-          .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Metadata on stream 0
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 0));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  // Metadata on stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 0));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-  EXPECT_EQ("Example connection metadata in multiple frames",
-            absl::StrJoin(visitor.GetMetadata(0), ""));
-  EXPECT_EQ("Some stream metadata that's also sent in multiple frames",
-            absl::StrJoin(visitor.GetMetadata(1), ""));
-}
-
-TEST(NgHttp2AdapterTest, RepeatedHeaderNames) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "text/plain"},
-                                           {"accept", "text/html"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/plain"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/html"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  const std::vector<Header> headers1 = ToHeaders(
-      {{":status", "200"}, {"content-length", "10"}, {"content-length", "10"}});
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload("perfection");
-  body1->EndData();
-
-  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
-  ASSERT_EQ(0, submit_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 10, 0x1, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::DATA}));
-}
-
-TEST(NgHttp2AdapterTest, ServerRespondsToRequestWithTrailers) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/one"}})
-          .Data(1, "Example data, woohoo.")
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  const std::vector<Header> headers1 = ToHeaders({{":status", "200"}});
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  TestDataFrameSource* body1_ptr = body1.get();
-
-  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
-  ASSERT_EQ(0, submit_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string more_frames =
-      TestFrameSequence()
-          .Headers(1, {{"extra-info", "Trailers are weird but good?"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "extra-info",
-                                         "Trailers are weird but good?"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  result = adapter->ProcessBytes(more_frames);
-  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
-
-  body1_ptr->EndData();
-  EXPECT_EQ(true, adapter->ResumeStream(1));
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
-}
-
-TEST(NgHttp2AdapterTest, ServerSubmitsResponseWithDataSourceError) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->SimulateError();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 2));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::RST_STREAM}));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  int trailer_result =
-      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
-  // The library does not object to the user queuing trailers, even through the
-  // stream has already been closed.
-  EXPECT_EQ(trailer_result, 0);
-}
-
-TEST(NgHttp2AdapterTest, CompleteRequestWithServerResponse) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.", /*fin=*/true)
-          .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  int submit_result =
-      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, IncompleteRequestWithServerResponse) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  int submit_result =
-      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  // BUG: Should send RST_STREAM NO_ERROR as well, but nghttp2 does not.
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ServerSendsInvalidTrailers) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  const absl::string_view kBody = "This is an example response body.";
-
-  // The body source must indicate that the end of the body is not the end of
-  // the stream.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  // The body source has been exhausted by the call to Send() above.
-  int trailer_result =
-      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
-  ASSERT_EQ(trailer_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerDropsNewStreamBelowWatermark) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(3,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(3, "This is the request body.")
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(3, 25));
-  EXPECT_CALL(visitor, OnDataForStream(3, "This is the request body."));
-
-  // It looks like nghttp2 delivers the under-watermark frame header but
-  // otherwise silently drops the rest of the frame without error.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnInvalidFrame).Times(0);
-  EXPECT_CALL(visitor, OnConnectionError).Times(0);
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterInteractionTest,
-     ClientServerInteractionRepeatedHeaderNames) {
-  DataSavingVisitor client_visitor;
-  auto client_adapter = NgHttp2Adapter::CreateClientAdapter(client_visitor);
-
-  client_adapter->SubmitSettings({});
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"},
-                 {"accept", "text/plain"},
-                 {"accept", "text/html"}});
-
-  const int32_t stream_id1 =
-      client_adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(client_visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(client_visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  int send_result = client_adapter->Send();
-  EXPECT_EQ(0, send_result);
-
-  DataSavingVisitor server_visitor;
-  auto server_adapter = NgHttp2Adapter::CreateServerAdapter(server_visitor);
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
-  EXPECT_CALL(server_visitor, OnSettingsStart());
-  EXPECT_CALL(server_visitor, OnSetting(_)).Times(testing::AnyNumber());
-  EXPECT_CALL(server_visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
-  EXPECT_CALL(server_visitor,
-              OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(server_visitor,
-              OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/plain"));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/html"));
-  EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(server_visitor, OnEndStream(1));
-
-  int64_t result = server_adapter->ProcessBytes(client_visitor.data());
-  EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
-}
-
-TEST(NgHttp2AdapterTest, ServerForbidsWindowUpdateOnIdleStream) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnInvalidFrame(1, _));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // The GOAWAY apparently causes the SETTINGS ack to be dropped.
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerForbidsDataOnIdleStream) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Data(1, "Sorry, out of order")
-                                 .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // In this case, nghttp2 goes straight to GOAWAY and does not invoke the
-  // invalid frame callback.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // The GOAWAY apparently causes the SETTINGS ack to be dropped.
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerForbidsRstStreamOnIdleStream) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnInvalidFrame(1, _));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // The GOAWAY apparently causes the SETTINGS ack to be dropped.
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerForbidsNewStreamAboveStreamLimit) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Let the client send a SETTINGS ack and then attempt to open more than the
-  // advertised number of streams. The overflow stream should be rejected.
-  const std::string stream_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":method", "GET"},
-                    {":scheme", "http"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kProtocol));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  // The server should send a GOAWAY for this error, even though
-  // OnInvalidFrame() returns true.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerRstStreamsNewStreamAboveStreamLimitBeforeAck) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Let the client avoid sending a SETTINGS ack and attempt to open more than
-  // the advertised number of streams. The server should still reject the
-  // overflow stream, albeit with RST_STREAM REFUSED_STREAM instead of GOAWAY.
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":method", "GET"},
-                    {":scheme", "http"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  3, Http2VisitorInterface::InvalidFrameError::kRefusedStream));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_result, stream_frames.size());
-
-  // The server sends a RST_STREAM for the offending stream.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, AutomaticSettingsAndPingAcks) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  const std::string frames =
-      TestFrameSequence().ClientPreface().Ping(42).Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // PING
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server preface does not appear to include the mandatory SETTINGS frame.
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  // PING ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
-}
-
-TEST(NgHttp2AdapterTest, AutomaticPingAcksDisabled) {
-  DataSavingVisitor visitor;
-  nghttp2_option* options;
-  nghttp2_option_new(&options);
-  nghttp2_option_set_no_auto_ping_ack(options, 1);
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor, options);
-  nghttp2_option_del(options);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().Ping(42).Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // PING
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server preface does not appear to include the mandatory SETTINGS frame.
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  // No PING ack expected because automatic PING acks are disabled.
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  // The client attempts to send a CONNECT request with the `:protocol`
-  // pseudoheader before receiving the server's SETTINGS frame.
-  const std::string stream1_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":method", "CONNECT"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"},
-                    {":protocol", "websocket"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [:protocol], value: [websocket]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  int64_t stream_result = adapter->ProcessBytes(stream1_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream1_frames.size());
-
-  // Server sends a SETTINGS ack and initial SETTINGS (with
-  // ENABLE_CONNECT_PROTOCOL).
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  // The server sends a RST_STREAM for the offending stream.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-  visitor.Clear();
-
-  // The client attempts to send a CONNECT request with the `:protocol`
-  // pseudoheader before acking the server's SETTINGS frame.
-  const std::string stream3_frames =
-      TestFrameSequence()
-          .Headers(3,
-                   {{":method", "CONNECT"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"},
-                    {":protocol", "websocket"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Surprisingly, nghttp2 is okay with this.
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  stream_result = adapter->ProcessBytes(stream3_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream3_frames.size());
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, ServerAllowsProtocolPseudoheaderAfterAck) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  // Server initial SETTINGS (with ENABLE_CONNECT_PROTOCOL) and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  visitor.Clear();
-
-  // The client attempts to send a CONNECT request with the `:protocol`
-  // pseudoheader after acking the server's SETTINGS frame.
-  const std::string stream_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Headers(1,
-                   {{":method", "CONNECT"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"},
-                    {":protocol", "websocket"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(NgHttp2AdapterTest, SkipsSendingFramesForRejectedStream) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "http"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body->AppendPayload("Here is some data, which will be completely ignored!");
-
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}}), std::move(body));
-  ASSERT_EQ(0, submit_result);
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-
-  adapter->SubmitWindowUpdate(1, 1024);
-  adapter->SubmitRst(1, Http2ErrorCode::INTERNAL_ERROR);
-
-  // Server initial SETTINGS and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  // nghttp2 apparently allows extension frames to be sent on reset streams.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
-
-  // The server sends a RST_STREAM for the offending stream.
-  // The response HEADERS, DATA and WINDOW_UPDATE are all ignored.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS,
-                            static_cast<SpdyFrameType>(kMetadataFrameType),
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerStartsShutdown) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  adapter->SubmitShutdownNotice();
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(NgHttp2AdapterTest, ServerStartsShutdownAfterGoaway) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  adapter->SubmitGoAway(1, Http2ErrorCode::HTTP2_NO_ERROR,
-                        "and don't come back!");
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-
-  // No-op, since a GOAWAY has previously been enqueued.
-  adapter->SubmitShutdownNotice();
-  EXPECT_FALSE(adapter->want_write());
-}
-
-// Verifies that a connection-level processing error results in repeatedly
-// returning a positive value for ProcessBytes() to mark all data as consumed.
-TEST(NgHttp2AdapterTest, ConnectionErrorWithBlackholeSinkingData) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnInvalidFrame(1, _));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  // Ask the connection to process more bytes. Because the option is enabled,
-  // the data should be marked as consumed.
-  const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
-  const int64_t next_result = adapter->ProcessBytes(next_frame);
-  EXPECT_EQ(static_cast<size_t>(next_result), next_frame.size());
-}
-
-TEST(NgHttp2AdapterTest, ServerDoesNotSendFramesAfterImmediateGoAway) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  // Submit a custom initial SETTINGS frame with one setting.
-  adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  // Submit a response for the stream.
-  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body->AppendPayload("This data is doomed to never be written.");
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}}), std::move(body));
-  ASSERT_EQ(0, submit_result);
-
-  // Submit a WINDOW_UPDATE frame.
-  adapter->SubmitWindowUpdate(kConnectionStreamId, 42);
-
-  // Submit another SETTINGS frame.
-  adapter->SubmitSettings({});
-
-  // Submit some metadata.
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Trigger a connection error. Only the response headers will be written.
-  const std::string connection_error_frames =
-      TestFrameSequence().WindowUpdate(3, 42).Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnInvalidFrame(3, _));
-
-  const int64_t result = adapter->ProcessBytes(connection_error_frames);
-  EXPECT_EQ(static_cast<size_t>(result), connection_error_frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // The GOAWAY apparently causes the other frames to be dropped except for the
-  // non-ack SETTINGS frames; nghttp2 sends non-ack SETTINGS frames because they
-  // could be the initial SETTINGS frame. However, nghttp2 still allows sending
-  // multiple non-ack SETTINGS, which feels non-ideal.
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::GOAWAY}));
-  visitor.Clear();
-
-  // Try to submit more frames for writing. They should not be written.
-  adapter->SubmitPing(42);
-  EXPECT_FALSE(adapter->want_write());
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesContentLength) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/one"},
-                       {"content-length", "2"}})
-          .Data(1, "hi", /*fin=*/true)
-          .Headers(3,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"},
-                    {"content-length", "nan"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Stream 1: content-length is correct
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
-  EXPECT_CALL(visitor, OnDataForStream(1, "hi"));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  // Stream 3: content-length is not a number
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 3, name: [content-length], value: [nan]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesContentLengthMismatch) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/two"},
-                       {"content-length", "2"}})
-          .Data(1, "h", /*fin=*/true)
-          .Headers(3, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/three"},
-                       {"content-length", "2"}})
-          .Data(3, "howdy", /*fin=*/true)
-          .Headers(5,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/four"},
-                    {"content-length", "2"}},
-                   /*fin=*/true)
-          .Headers(7,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/four"},
-                    {"content-length", "2"}},
-                   /*fin=*/false)
-          .Data(7, "h", /*fin=*/false)
-          .Headers(7, {{"extra-info", "Trailers with content-length mismatch"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Stream 1: content-length is larger than actual data
-  // All data is delivered to the visitor, but OnInvalidFrame() is not.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 1));
-  EXPECT_CALL(visitor, OnDataForStream(1, "h"));
-
-  // Stream 3: content-length is smaller than actual data
-  // The beginning of data is delivered to the visitor, but not the actual data,
-  // and neither is OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(3, 5));
-
-  // Stream 5: content-length is invalid and HEADERS ends the stream
-  // When the stream ends with HEADERS, nghttp2 invokes OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  5, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  // Stream 7: content-length is invalid and trailers end the stream
-  // When the stream ends with trailers, nghttp2 invokes OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
-  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(7));
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(7, 1));
-  EXPECT_CALL(visitor, OnDataForStream(7, "h"));
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
-  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _));
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  7, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 7, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesAsteriskPathForOptions) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::string stream_frames = TestFrameSequence()
-                                        .ClientPreface()
-                                        .Headers(1,
-                                                 {{":scheme", "https"},
-                                                  {":authority", "example.com"},
-                                                  {":path", "*"},
-                                                  {":method", "OPTIONS"}},
-                                                 /*fin=*/true)
-                                        .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesInvalidPath) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "*"},
-                    {":method", "GET"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "other/non/slash/starter"},
-                    {":method", "GET"}},
-                   /*fin=*/true)
-          .Headers(5,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", ""},
-                    {":method", "GET"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  3, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(2);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 5, name: [:path], value: []"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesTeHeader) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::string stream_frames = TestFrameSequence()
-                                        .ClientPreface()
-                                        .Headers(1,
-                                                 {{":scheme", "https"},
-                                                  {":authority", "example.com"},
-                                                  {":path", "/"},
-                                                  {":method", "GET"},
-                                                  {"te", "trailers"}},
-                                                 /*fin=*/true)
-                                        .Headers(3,
-                                                 {{":scheme", "https"},
-                                                  {":authority", "example.com"},
-                                                  {":path", "/"},
-                                                  {":method", "GET"},
-                                                  {"te", "trailers, deflate"}},
-                                                 /*fin=*/true)
-                                        .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Stream 1: TE: trailers should be allowed.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  // Stream 3: TE: <non-trailers> should be rejected.
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 3, name: [te], value: [trailers, deflate]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(NgHttp2AdapterTest, ServerHandlesConnectionSpecificHeaders) {
-  DataSavingVisitor visitor;
-  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"connection", "keep-alive"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"proxy-connection", "keep-alive"}},
-                   /*fin=*/true)
-          .Headers(5,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"keep-alive", "timeout=42"}},
-                   /*fin=*/true)
-          .Headers(7,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"transfer-encoding", "chunked"}},
-                   /*fin=*/true)
-          .Headers(9,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"upgrade", "h2c"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // All streams contain a connection-specific header and should be rejected.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 1, name: [connection], value: [keep-alive]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 3, name: [proxy-connection], value: [keep-alive]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 5, name: [keep-alive], value: [timeout=42]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
-  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 7, name: [transfer-encoding], value: [chunked]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(7, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
-  EXPECT_CALL(visitor, OnHeaderForStream(9, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
-                   "stream: 9, name: [upgrade], value: [h2c]"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(9, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 7, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 9, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 9, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(9, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_callbacks.cc b/http2/adapter/nghttp2_callbacks.cc
deleted file mode 100644
index b8489b7..0000000
--- a/http2/adapter/nghttp2_callbacks.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-#include "http2/adapter/nghttp2_callbacks.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/strings/string_view.h"
-#include "http2/adapter/data_source.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/nghttp2_data_provider.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-
-namespace http2 {
-namespace adapter {
-namespace callbacks {
-
-ssize_t OnReadyToSend(nghttp2_session* /* session */, const uint8_t* data,
-                      size_t length, int flags, void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const int64_t result = visitor->OnReadyToSend(ToStringView(data, length));
-  QUICHE_VLOG(1) << "OnReadyToSend(length=" << length << ", flags=" << flags
-                 << ") returning " << result;
-  if (result > 0) {
-    return result;
-  } else if (result == Http2VisitorInterface::kSendBlocked) {
-    return -504;  // NGHTTP2_ERR_WOULDBLOCK
-  } else {
-    return -902;  // NGHTTP2_ERR_CALLBACK_FAILURE
-  }
-}
-
-int OnBeginFrame(nghttp2_session* /* session */,
-                 const nghttp2_frame_hd* header,
-                 void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  bool result = visitor->OnFrameHeader(header->stream_id, header->length,
-                                       header->type, header->flags);
-  if (!result) {
-    return NGHTTP2_ERR_CALLBACK_FAILURE;
-  }
-  if (header->type == NGHTTP2_DATA) {
-    result = visitor->OnBeginDataForStream(header->stream_id, header->length);
-  } else if (header->type == kMetadataFrameType) {
-    visitor->OnBeginMetadataForStream(header->stream_id, header->length);
-  }
-  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
-}
-
-int OnFrameReceived(nghttp2_session* /* session */,
-                    const nghttp2_frame* frame,
-                    void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const Http2StreamId stream_id = frame->hd.stream_id;
-  switch (frame->hd.type) {
-    // The beginning of the DATA frame is handled in OnBeginFrame(), and the
-    // beginning of the header block is handled in client/server-specific
-    // callbacks. This callback handles the point at which the entire logical
-    // frame has been received and processed.
-    case NGHTTP2_DATA:
-      if ((frame->hd.flags & NGHTTP2_FLAG_PADDED) != 0) {
-        visitor->OnDataPaddingLength(stream_id, frame->data.padlen);
-      }
-      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
-        visitor->OnEndStream(stream_id);
-      }
-      break;
-    case NGHTTP2_HEADERS: {
-      if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS) {
-        const bool result = visitor->OnEndHeadersForStream(stream_id);
-        if (!result) {
-          return NGHTTP2_ERR_CALLBACK_FAILURE;
-        }
-      }
-      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
-        visitor->OnEndStream(stream_id);
-      }
-      break;
-    }
-    case NGHTTP2_PRIORITY: {
-      nghttp2_priority_spec priority_spec = frame->priority.pri_spec;
-      visitor->OnPriorityForStream(stream_id, priority_spec.stream_id,
-                                   priority_spec.weight,
-                                   priority_spec.exclusive != 0);
-      break;
-    }
-    case NGHTTP2_RST_STREAM: {
-      visitor->OnRstStream(stream_id,
-                           ToHttp2ErrorCode(frame->rst_stream.error_code));
-      break;
-    }
-    case NGHTTP2_SETTINGS:
-      if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
-        visitor->OnSettingsAck();
-      } else {
-        visitor->OnSettingsStart();
-        for (size_t i = 0; i < frame->settings.niv; ++i) {
-          nghttp2_settings_entry entry = frame->settings.iv[i];
-          // The nghttp2_settings_entry uses int32_t for the ID; we must cast.
-          visitor->OnSetting(Http2Setting{
-              static_cast<Http2SettingsId>(entry.settings_id), entry.value});
-        }
-        visitor->OnSettingsEnd();
-      }
-      break;
-    case NGHTTP2_PUSH_PROMISE:
-      // This case is handled by headers-related callbacks:
-      //   1. visitor->OnPushPromiseForStream() is invoked in the client-side
-      //      OnHeadersStart() adapter callback, as nghttp2 only allows clients
-      //      to receive PUSH_PROMISE frames.
-      //   2. visitor->OnHeaderForStream() is invoked for each server push
-      //      request header in the PUSH_PROMISE header block.
-      //   3. This switch statement is reached once all server push request
-      //      headers have been parsed.
-      break;
-    case NGHTTP2_PING: {
-      Http2PingId ping_id;
-      std::memcpy(&ping_id, frame->ping.opaque_data, sizeof(Http2PingId));
-      visitor->OnPing(quiche::QuicheEndian::NetToHost64(ping_id),
-                      (frame->hd.flags & NGHTTP2_FLAG_ACK) != 0);
-      break;
-    }
-    case NGHTTP2_GOAWAY: {
-      absl::string_view opaque_data(
-          reinterpret_cast<const char*>(frame->goaway.opaque_data),
-          frame->goaway.opaque_data_len);
-      const bool result = visitor->OnGoAway(
-          frame->goaway.last_stream_id,
-          ToHttp2ErrorCode(frame->goaway.error_code), opaque_data);
-      if (!result) {
-        return NGHTTP2_ERR_CALLBACK_FAILURE;
-      }
-      break;
-    }
-    case NGHTTP2_WINDOW_UPDATE: {
-      visitor->OnWindowUpdate(stream_id,
-                              frame->window_update.window_size_increment);
-      break;
-    }
-    case NGHTTP2_CONTINUATION:
-      // This frame type should not be passed to any callbacks, according to
-      // https://nghttp2.org/documentation/enums.html#c.NGHTTP2_CONTINUATION.
-      QUICHE_LOG(ERROR) << "Unexpected receipt of NGHTTP2_CONTINUATION type!";
-      break;
-    case NGHTTP2_ALTSVC:
-      break;
-    case NGHTTP2_ORIGIN:
-      break;
-  }
-
-  return 0;
-}
-
-int OnBeginHeaders(nghttp2_session* /* session */,
-                   const nghttp2_frame* frame,
-                   void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const bool result = visitor->OnBeginHeadersForStream(frame->hd.stream_id);
-  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
-}
-
-int OnHeader(nghttp2_session* /* session */, const nghttp2_frame* frame,
-             nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t /*flags*/,
-             void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const Http2VisitorInterface::OnHeaderResult result =
-      visitor->OnHeaderForStream(frame->hd.stream_id, ToStringView(name),
-                                 ToStringView(value));
-  switch (result) {
-    case Http2VisitorInterface::HEADER_OK:
-      return 0;
-    case Http2VisitorInterface::HEADER_CONNECTION_ERROR:
-    case Http2VisitorInterface::HEADER_COMPRESSION_ERROR:
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
-    case Http2VisitorInterface::HEADER_RST_STREAM:
-    case Http2VisitorInterface::HEADER_FIELD_INVALID:
-    case Http2VisitorInterface::HEADER_HTTP_MESSAGING:
-      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-  }
-  // Unexpected value.
-  return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-}
-
-int OnBeforeFrameSent(nghttp2_session* /* session */,
-                      const nghttp2_frame* frame, void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  LogBeforeSend(*frame);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  return visitor->OnBeforeFrameSent(frame->hd.type, frame->hd.stream_id,
-                                    frame->hd.length, frame->hd.flags);
-}
-
-int OnFrameSent(nghttp2_session* /* session */, const nghttp2_frame* frame,
-                void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  uint32_t error_code = 0;
-  if (frame->hd.type == NGHTTP2_RST_STREAM) {
-    error_code = frame->rst_stream.error_code;
-  } else if (frame->hd.type == NGHTTP2_GOAWAY) {
-    error_code = frame->goaway.error_code;
-  }
-  return visitor->OnFrameSent(frame->hd.type, frame->hd.stream_id,
-                              frame->hd.length, frame->hd.flags, error_code);
-}
-
-int OnFrameNotSent(nghttp2_session* /* session */, const nghttp2_frame* frame,
-                   int /* lib_error_code */, void* /* user_data */) {
-  if (frame->hd.type == kMetadataFrameType) {
-    auto* source = static_cast<MetadataSource*>(frame->ext.payload);
-    if (source == nullptr) {
-      QUICHE_BUG(not_sent_payload_is_nullptr)
-          << "Extension frame payload for stream " << frame->hd.stream_id
-          << " is null!";
-    } else {
-      source->OnFailure();
-    }
-  }
-  return 0;
-}
-
-int OnInvalidFrameReceived(nghttp2_session* /* session */,
-                           const nghttp2_frame* frame, int lib_error_code,
-                           void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const bool result = visitor->OnInvalidFrame(
-      frame->hd.stream_id, ToInvalidFrameError(lib_error_code));
-  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
-}
-
-int OnDataChunk(nghttp2_session* /* session */, uint8_t /*flags*/,
-                Http2StreamId stream_id, const uint8_t* data, size_t len,
-                void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const bool result = visitor->OnDataForStream(
-      stream_id, absl::string_view(reinterpret_cast<const char*>(data), len));
-  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
-}
-
-int OnStreamClosed(nghttp2_session* /* session */,
-                   Http2StreamId stream_id,
-                   uint32_t error_code,
-                   void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  const bool result =
-      visitor->OnCloseStream(stream_id, ToHttp2ErrorCode(error_code));
-  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
-}
-
-int OnExtensionChunkReceived(nghttp2_session* /*session*/,
-                             const nghttp2_frame_hd* hd, const uint8_t* data,
-                             size_t len, void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  if (hd->type != kMetadataFrameType) {
-    QUICHE_LOG(ERROR) << "Unexpected frame type: "
-                      << static_cast<int>(hd->type);
-    return NGHTTP2_ERR_CANCEL;
-  }
-  const bool result =
-      visitor->OnMetadataForStream(hd->stream_id, ToStringView(data, len));
-  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
-}
-
-int OnUnpackExtensionCallback(nghttp2_session* /*session*/, void** /*payload*/,
-                              const nghttp2_frame_hd* hd, void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  if (hd->flags == kMetadataEndFlag) {
-    const bool result = visitor->OnMetadataEndForStream(hd->stream_id);
-    if (!result) {
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
-    }
-  }
-  return 0;
-}
-
-ssize_t OnPackExtensionCallback(nghttp2_session* /*session*/, uint8_t* buf,
-                                size_t len, const nghttp2_frame* frame,
-                                void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* source = static_cast<MetadataSource*>(frame->ext.payload);
-  if (source == nullptr) {
-    QUICHE_BUG(payload_is_nullptr) << "Extension frame payload for stream "
-                                   << frame->hd.stream_id << " is null!";
-    return NGHTTP2_ERR_CALLBACK_FAILURE;
-  }
-  const std::pair<int64_t, bool> result = source->Pack(buf, len);
-  if (result.first < 0) {
-    return NGHTTP2_ERR_CALLBACK_FAILURE;
-  }
-  const bool end_metadata_flag = (frame->hd.flags & kMetadataEndFlag);
-  QUICHE_LOG_IF(DFATAL, result.second != end_metadata_flag)
-      << "Metadata ends: " << result.second
-      << " has kMetadataEndFlag: " << end_metadata_flag;
-  return result.first;
-}
-
-int OnError(nghttp2_session* /*session*/, int /*lib_error_code*/,
-            const char* msg, size_t len, void* user_data) {
-  QUICHE_CHECK_NE(user_data, nullptr);
-  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
-  visitor->OnErrorDebug(absl::string_view(msg, len));
-  return 0;
-}
-
-nghttp2_session_callbacks_unique_ptr Create() {
-  nghttp2_session_callbacks* callbacks;
-  nghttp2_session_callbacks_new(&callbacks);
-
-  nghttp2_session_callbacks_set_send_callback(callbacks, &OnReadyToSend);
-  nghttp2_session_callbacks_set_on_begin_frame_callback(callbacks,
-                                                        &OnBeginFrame);
-  nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
-                                                       &OnFrameReceived);
-  nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks,
-                                                          &OnBeginHeaders);
-  nghttp2_session_callbacks_set_on_header_callback2(callbacks, &OnHeader);
-  nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks,
-                                                            &OnDataChunk);
-  nghttp2_session_callbacks_set_on_stream_close_callback(callbacks,
-                                                         &OnStreamClosed);
-  nghttp2_session_callbacks_set_before_frame_send_callback(callbacks,
-                                                           &OnBeforeFrameSent);
-  nghttp2_session_callbacks_set_on_frame_send_callback(callbacks, &OnFrameSent);
-  nghttp2_session_callbacks_set_on_frame_not_send_callback(callbacks,
-                                                           &OnFrameNotSent);
-  nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
-      callbacks, &OnInvalidFrameReceived);
-  nghttp2_session_callbacks_set_error_callback2(callbacks, &OnError);
-  nghttp2_session_callbacks_set_send_data_callback(
-      callbacks, &DataFrameSourceSendCallback);
-  nghttp2_session_callbacks_set_pack_extension_callback(
-      callbacks, &OnPackExtensionCallback);
-  nghttp2_session_callbacks_set_unpack_extension_callback(
-      callbacks, &OnUnpackExtensionCallback);
-  nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
-      callbacks, &OnExtensionChunkReceived);
-  return MakeCallbacksPtr(callbacks);
-}
-
-}  // namespace callbacks
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_callbacks.h b/http2/adapter/nghttp2_callbacks.h
deleted file mode 100644
index 82b7cf1..0000000
--- a/http2/adapter/nghttp2_callbacks.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_CALLBACKS_H_
-#define QUICHE_HTTP2_ADAPTER_NGHTTP2_CALLBACKS_H_
-
-#include <cstdint>
-
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/nghttp2.h"
-#include "http2/adapter/nghttp2_util.h"
-
-namespace http2 {
-namespace adapter {
-namespace callbacks {
-
-// The following functions are nghttp2 callbacks that Nghttp2Adapter sets at the
-// beginning of its lifetime. It is expected that |user_data| holds an
-// Http2VisitorInterface.
-
-// Callback once the library is ready to send serialized frames.
-ssize_t OnReadyToSend(nghttp2_session* session,
-                      const uint8_t* data,
-                      size_t length,
-                      int flags,
-                      void* user_data);
-
-// Callback once a frame header has been received.
-int OnBeginFrame(nghttp2_session* session, const nghttp2_frame_hd* header,
-                 void* user_data);
-
-// Callback once a complete frame has been received.
-int OnFrameReceived(nghttp2_session* session, const nghttp2_frame* frame,
-                    void* user_data);
-
-// Callback at the start of a frame carrying headers.
-int OnBeginHeaders(nghttp2_session* session,
-                   const nghttp2_frame* frame,
-                   void* user_data);
-
-// Callback once a name-value header has been received.
-int OnHeader(nghttp2_session* session, const nghttp2_frame* frame,
-             nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t flags,
-             void* user_data);
-
-// Invoked immediately before sending a frame.
-int OnBeforeFrameSent(nghttp2_session* session, const nghttp2_frame* frame,
-                      void* user_data);
-
-// Invoked immediately after a frame is sent.
-int OnFrameSent(nghttp2_session* session, const nghttp2_frame* frame,
-                void* user_data);
-
-// Invoked when a non-DATA frame is not sent because of an error.
-int OnFrameNotSent(nghttp2_session* session, const nghttp2_frame* frame,
-                   int lib_error_code, void* user_data);
-
-// Invoked when an invalid frame is received.
-int OnInvalidFrameReceived(nghttp2_session* session, const nghttp2_frame* frame,
-                           int lib_error_code, void* user_data);
-
-// Invoked when a chunk of data (from a DATA frame payload) has been received.
-int OnDataChunk(nghttp2_session* session, uint8_t flags,
-                Http2StreamId stream_id, const uint8_t* data, size_t len,
-                void* user_data);
-
-// Callback once a stream has been closed.
-int OnStreamClosed(nghttp2_session* session, Http2StreamId stream_id,
-                   uint32_t error_code, void* user_data);
-
-// Invoked when nghttp2 has a chunk of extension frame data to pass to the
-// application.
-int OnExtensionChunkReceived(nghttp2_session* session,
-                             const nghttp2_frame_hd* hd, const uint8_t* data,
-                             size_t len, void* user_data);
-
-// Invoked when nghttp2 wants the application to unpack an extension payload.
-int OnUnpackExtensionCallback(nghttp2_session* session, void** payload,
-                              const nghttp2_frame_hd* hd, void* user_data);
-
-// Invoked when nghttp2 is ready to pack an extension payload. Returns the
-// number of bytes serialized to |buf|.
-ssize_t OnPackExtensionCallback(nghttp2_session* session, uint8_t* buf,
-                                size_t len, const nghttp2_frame* frame,
-                                void* user_data);
-
-// Invoked when the library has an error message to deliver.
-int OnError(nghttp2_session* session, int lib_error_code, const char* msg,
-            size_t len, void* user_data);
-
-nghttp2_session_callbacks_unique_ptr Create();
-
-}  // namespace callbacks
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_CALLBACKS_H_
diff --git a/http2/adapter/nghttp2_data_provider.cc b/http2/adapter/nghttp2_data_provider.cc
deleted file mode 100644
index 200aa67..0000000
--- a/http2/adapter/nghttp2_data_provider.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "http2/adapter/nghttp2_data_provider.h"
-
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/nghttp2_util.h"
-
-namespace http2 {
-namespace adapter {
-namespace callbacks {
-
-namespace {
-const size_t kFrameHeaderSize = 9;
-}
-
-ssize_t DataFrameSourceReadCallback(nghttp2_session* /* session */,
-                                    int32_t /* stream_id */,
-                                    uint8_t* /* buf */,
-                                    size_t length,
-                                    uint32_t* data_flags,
-                                    nghttp2_data_source* source,
-                                    void* /* user_data */) {
-  *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
-  auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
-  auto [result_length, done] = frame_source->SelectPayloadLength(length);
-  if (result_length == 0 && !done) {
-    return NGHTTP2_ERR_DEFERRED;
-  } else if (result_length == DataFrameSource::kError) {
-    return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-  }
-  if (done) {
-    *data_flags |= NGHTTP2_DATA_FLAG_EOF;
-  }
-  if (!frame_source->send_fin()) {
-    *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
-  }
-  return result_length;
-}
-
-int DataFrameSourceSendCallback(nghttp2_session* /* session */,
-                                nghttp2_frame* /* frame */,
-                                const uint8_t* framehd,
-                                size_t length,
-                                nghttp2_data_source* source,
-                                void* /* user_data */) {
-  auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
-  frame_source->Send(ToStringView(framehd, kFrameHeaderSize), length);
-  return 0;
-}
-
-}  // namespace callbacks
-
-std::unique_ptr<nghttp2_data_provider> MakeDataProvider(
-    DataFrameSource* source) {
-  if (source == nullptr) {
-    return nullptr;
-  }
-  auto provider = absl::make_unique<nghttp2_data_provider>();
-  provider->source.ptr = source;
-  provider->read_callback = &callbacks::DataFrameSourceReadCallback;
-  return provider;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_data_provider.h b/http2/adapter/nghttp2_data_provider.h
deleted file mode 100644
index 9e3601a..0000000
--- a/http2/adapter/nghttp2_data_provider.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_DATA_PROVIDER_H_
-#define QUICHE_HTTP2_ADAPTER_NGHTTP2_DATA_PROVIDER_H_
-
-#include <cstdint>
-#include <memory>
-
-#include "http2/adapter/data_source.h"
-#include "http2/adapter/nghttp2.h"
-
-namespace http2 {
-namespace adapter {
-namespace callbacks {
-
-// Assumes |source| is a DataFrameSource.
-ssize_t DataFrameSourceReadCallback(nghttp2_session* /*session */,
-                                    int32_t /* stream_id */,
-                                    uint8_t* /* buf */,
-                                    size_t length,
-                                    uint32_t* data_flags,
-                                    nghttp2_data_source* source,
-                                    void* /* user_data */);
-
-int DataFrameSourceSendCallback(nghttp2_session* /* session */,
-                                nghttp2_frame* /* frame */,
-                                const uint8_t* framehd,
-                                size_t length,
-                                nghttp2_data_source* source,
-                                void* /* user_data */);
-
-}  // namespace callbacks
-
-// Transforms a DataFrameSource into a nghttp2_data_provider. Does not take
-// ownership of |source|. Returns nullptr if |source| is nullptr.
-std::unique_ptr<nghttp2_data_provider> MakeDataProvider(
-    DataFrameSource* source);
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_DATA_PROVIDER_H_
diff --git a/http2/adapter/nghttp2_data_provider_test.cc b/http2/adapter/nghttp2_data_provider_test.cc
deleted file mode 100644
index af8d981..0000000
--- a/http2/adapter/nghttp2_data_provider_test.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-#include "http2/adapter/nghttp2_data_provider.h"
-
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-const size_t kFrameHeaderSize = 9;
-
-// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
-// correctly with nghttp2-style callbacks when the amount of data read is less
-// than what the source provides.
-TEST(DataProviderTest, ReadLessThanSourceProvides) {
-  DataSavingVisitor visitor;
-  TestDataFrameSource source(visitor, true);
-  source.AppendPayload("Example payload");
-  source.EndData();
-  auto provider = MakeDataProvider(&source);
-  uint32_t data_flags = 0;
-  const int32_t kStreamId = 1;
-  const size_t kReadLength = 10;
-  // Read callback selects a payload length given an upper bound.
-  ssize_t result =
-      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
-                              &data_flags, &provider->source, nullptr);
-  ASSERT_EQ(kReadLength, result);
-  EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY, data_flags);
-
-  const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
-  // Sends the frame header and some payload bytes.
-  int send_result = callbacks::DataFrameSourceSendCallback(
-      nullptr, nullptr, framehd, result, &provider->source, nullptr);
-  EXPECT_EQ(0, send_result);
-  // Data accepted by the visitor includes a frame header and kReadLength bytes
-  // of payload.
-  EXPECT_EQ(visitor.data().size(), kFrameHeaderSize + kReadLength);
-}
-
-// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
-// correctly with nghttp2-style callbacks when the amount of data read is more
-// than what the source provides.
-TEST(DataProviderTest, ReadMoreThanSourceProvides) {
-  DataSavingVisitor visitor;
-  const absl::string_view kPayload = "Example payload";
-  TestDataFrameSource source(visitor, true);
-  source.AppendPayload(kPayload);
-  source.EndData();
-  auto provider = MakeDataProvider(&source);
-  uint32_t data_flags = 0;
-  const int32_t kStreamId = 1;
-  const size_t kReadLength = 30;
-  // Read callback selects a payload length given an upper bound.
-  ssize_t result =
-      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
-                              &data_flags, &provider->source, nullptr);
-  ASSERT_EQ(kPayload.size(), result);
-  EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
-
-  const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
-  // Sends the frame header and some payload bytes.
-  int send_result = callbacks::DataFrameSourceSendCallback(
-      nullptr, nullptr, framehd, result, &provider->source, nullptr);
-  EXPECT_EQ(0, send_result);
-  // Data accepted by the visitor includes a frame header and the entire
-  // payload.
-  EXPECT_EQ(visitor.data().size(), kFrameHeaderSize + kPayload.size());
-}
-
-// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
-// correctly with nghttp2-style callbacks when the source is blocked.
-TEST(DataProviderTest, ReadFromBlockedSource) {
-  DataSavingVisitor visitor;
-  // Source has no payload, but also no fin, so it's blocked.
-  TestDataFrameSource source(visitor, false);
-  auto provider = MakeDataProvider(&source);
-  uint32_t data_flags = 0;
-  const int32_t kStreamId = 1;
-  const size_t kReadLength = 10;
-  ssize_t result =
-      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
-                              &data_flags, &provider->source, nullptr);
-  // Read operation is deferred, since the source is blocked.
-  EXPECT_EQ(NGHTTP2_ERR_DEFERRED, result);
-}
-
-// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
-// correctly with nghttp2-style callbacks when the source provides only fin and
-// no data.
-TEST(DataProviderTest, ReadFromZeroLengthSource) {
-  DataSavingVisitor visitor;
-  // Empty payload and fin=true indicates the source is done.
-  TestDataFrameSource source(visitor, true);
-  source.EndData();
-  auto provider = MakeDataProvider(&source);
-  uint32_t data_flags = 0;
-  const int32_t kStreamId = 1;
-  const size_t kReadLength = 10;
-  ssize_t result =
-      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
-                              &data_flags, &provider->source, nullptr);
-  ASSERT_EQ(0, result);
-  EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
-
-  const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
-  int send_result = callbacks::DataFrameSourceSendCallback(
-      nullptr, nullptr, framehd, result, &provider->source, nullptr);
-  EXPECT_EQ(0, send_result);
-  // Data accepted by the visitor includes a frame header with fin and zero
-  // bytes of payload.
-  EXPECT_EQ(visitor.data().size(), kFrameHeaderSize);
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_session.cc b/http2/adapter/nghttp2_session.cc
deleted file mode 100644
index 6db6e4a..0000000
--- a/http2/adapter/nghttp2_session.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "http2/adapter/nghttp2_session.h"
-
-#include "common/platform/api/quiche_logging.h"
-
-namespace http2 {
-namespace adapter {
-
-NgHttp2Session::NgHttp2Session(Perspective perspective,
-                               nghttp2_session_callbacks_unique_ptr callbacks,
-                               const nghttp2_option* options, void* userdata)
-    : session_(MakeSessionPtr(nullptr)), perspective_(perspective) {
-  nghttp2_session* session;
-  switch (perspective_) {
-    case Perspective::kClient:
-      nghttp2_session_client_new2(&session, callbacks.get(), userdata, options);
-      break;
-    case Perspective::kServer:
-      nghttp2_session_server_new2(&session, callbacks.get(), userdata, options);
-      break;
-  }
-  session_ = MakeSessionPtr(session);
-}
-
-NgHttp2Session::~NgHttp2Session() {
-  // Can't invoke want_read() or want_write(), as they are virtual methods.
-  const bool pending_reads = nghttp2_session_want_read(session_.get()) != 0;
-  const bool pending_writes = nghttp2_session_want_write(session_.get()) != 0;
-  if (pending_reads || pending_writes) {
-    QUICHE_VLOG(1) << "Shutting down connection with pending reads: "
-                   << pending_reads << " or pending writes: " << pending_writes;
-  }
-}
-
-int64_t NgHttp2Session::ProcessBytes(absl::string_view bytes) {
-  return nghttp2_session_mem_recv(
-      session_.get(), reinterpret_cast<const uint8_t*>(bytes.data()),
-      bytes.size());
-}
-
-int NgHttp2Session::Consume(Http2StreamId stream_id, size_t num_bytes) {
-  return nghttp2_session_consume(session_.get(), stream_id, num_bytes);
-}
-
-bool NgHttp2Session::want_read() const {
-  return nghttp2_session_want_read(session_.get()) != 0;
-}
-
-bool NgHttp2Session::want_write() const {
-  return nghttp2_session_want_write(session_.get()) != 0;
-}
-
-int NgHttp2Session::GetRemoteWindowSize() const {
-  return nghttp2_session_get_remote_window_size(session_.get());
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_session.h b/http2/adapter/nghttp2_session.h
deleted file mode 100644
index c5c1b73..0000000
--- a/http2/adapter/nghttp2_session.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_SESSION_H_
-#define QUICHE_HTTP2_ADAPTER_NGHTTP2_SESSION_H_
-
-#include <cstdint>
-
-#include "http2/adapter/http2_session.h"
-#include "http2/adapter/nghttp2.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-// A C++ wrapper around common nghttp2_session operations.
-class QUICHE_EXPORT_PRIVATE NgHttp2Session : public Http2Session {
- public:
-  // Does not take ownership of |options|.
-  NgHttp2Session(Perspective perspective,
-                 nghttp2_session_callbacks_unique_ptr callbacks,
-                 const nghttp2_option* options, void* userdata);
-  ~NgHttp2Session() override;
-
-  int64_t ProcessBytes(absl::string_view bytes) override;
-
-  int Consume(Http2StreamId stream_id, size_t num_bytes) override;
-
-  bool want_read() const override;
-  bool want_write() const override;
-  int GetRemoteWindowSize() const override;
-
-  nghttp2_session* raw_ptr() const { return session_.get(); }
-
- private:
-  nghttp2_session_unique_ptr session_;
-  Perspective perspective_;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_SESSION_H_
diff --git a/http2/adapter/nghttp2_session_test.cc b/http2/adapter/nghttp2_session_test.cc
deleted file mode 100644
index 036c1f2..0000000
--- a/http2/adapter/nghttp2_session_test.cc
+++ /dev/null
@@ -1,322 +0,0 @@
-#include "http2/adapter/nghttp2_session.h"
-
-#include "http2/adapter/mock_http2_visitor.h"
-#include "http2/adapter/nghttp2_callbacks.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using testing::_;
-
-enum FrameType {
-  DATA,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-};
-
-class NgHttp2SessionTest : public testing::Test {
- public:
-  void SetUp() override {
-    nghttp2_option_new(&options_);
-    nghttp2_option_set_no_auto_window_update(options_, 1);
-  }
-
-  void TearDown() override { nghttp2_option_del(options_); }
-
-  nghttp2_session_callbacks_unique_ptr CreateCallbacks() {
-    nghttp2_session_callbacks_unique_ptr callbacks = callbacks::Create();
-    return callbacks;
-  }
-
-  DataSavingVisitor visitor_;
-  nghttp2_option* options_ = nullptr;
-};
-
-TEST_F(NgHttp2SessionTest, ClientConstruction) {
-  NgHttp2Session session(Perspective::kClient, CreateCallbacks(), options_,
-                         &visitor_);
-  EXPECT_TRUE(session.want_read());
-  EXPECT_FALSE(session.want_write());
-  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
-  EXPECT_NE(session.raw_ptr(), nullptr);
-}
-
-TEST_F(NgHttp2SessionTest, ClientHandlesFrames) {
-  NgHttp2Session session(Perspective::kClient, CreateCallbacks(), options_,
-                         &visitor_);
-
-  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
-  ASSERT_GT(visitor_.data().size(), 0);
-
-  const std::string initial_frames = TestFrameSequence()
-                                         .ServerPreface()
-                                         .Ping(42)
-                                         .WindowUpdate(0, 1000)
-                                         .Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor_, OnSettingsStart());
-  EXPECT_CALL(visitor_, OnSettingsEnd());
-
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor_, OnPing(42, false));
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor_, OnWindowUpdate(0, 1000));
-
-  const int64_t initial_result = session.ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), initial_result);
-
-  EXPECT_EQ(session.GetRemoteWindowSize(),
-            kInitialFlowControlWindowSize + 1000);
-
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor_, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(PING, 0, 8, 0x1));
-  EXPECT_CALL(visitor_, OnFrameSent(PING, 0, 8, 0x1, 0));
-
-  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
-  // Some bytes should have been serialized.
-  absl::string_view serialized = visitor_.data();
-  ASSERT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({spdy::SpdyFrameType::SETTINGS,
-                                        spdy::SpdyFrameType::PING}));
-  visitor_.Clear();
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const auto nvs1 = GetNghttp2Nvs(headers1);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-  const auto nvs2 = GetNghttp2Nvs(headers2);
-
-  const std::vector<Header> headers3 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/three"}});
-  const auto nvs3 = GetNghttp2Nvs(headers3);
-
-  const int32_t stream_id1 = nghttp2_submit_request(
-      session.raw_ptr(), nullptr, nvs1.data(), nvs1.size(), nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  const int32_t stream_id2 = nghttp2_submit_request(
-      session.raw_ptr(), nullptr, nvs2.data(), nvs2.size(), nullptr, nullptr);
-  ASSERT_GT(stream_id2, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id2;
-
-  const int32_t stream_id3 = nghttp2_submit_request(
-      session.raw_ptr(), nullptr, nvs3.data(), nvs3.size(), nullptr, nullptr);
-  ASSERT_GT(stream_id3, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id3;
-
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor_, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(HEADERS, 3, _, 0x5));
-  EXPECT_CALL(visitor_, OnFrameSent(HEADERS, 3, _, 0x5, 0));
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(HEADERS, 5, _, 0x5));
-  EXPECT_CALL(visitor_, OnFrameSent(HEADERS, 5, _, 0x5, 0));
-
-  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
-  serialized = visitor_.data();
-  EXPECT_THAT(serialized, EqualsFrames({spdy::SpdyFrameType::HEADERS,
-                                        spdy::SpdyFrameType::HEADERS,
-                                        spdy::SpdyFrameType::HEADERS}));
-  visitor_.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
-          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
-          .Serialize();
-
-  EXPECT_CALL(visitor_, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor_, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor_,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor_, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor_, OnFrameHeader(1, 26, DATA, 0));
-  EXPECT_CALL(visitor_, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor_, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor_, OnFrameHeader(3, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor_, OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR));
-  EXPECT_CALL(visitor_, OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR));
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 19, GOAWAY, 0));
-  EXPECT_CALL(visitor_,
-              OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!"));
-  const int64_t stream_result = session.ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), stream_result);
-
-  // Even though the client recieved a GOAWAY, streams 1 and 5 are still active.
-  EXPECT_TRUE(session.want_read());
-
-  EXPECT_CALL(visitor_, OnFrameHeader(1, 0, DATA, 1));
-  EXPECT_CALL(visitor_, OnBeginDataForStream(1, 0));
-  EXPECT_CALL(visitor_, OnEndStream(1));
-  EXPECT_CALL(visitor_, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor_, OnFrameHeader(5, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor_, OnRstStream(5, Http2ErrorCode::REFUSED_STREAM));
-  EXPECT_CALL(visitor_, OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM));
-  session.ProcessBytes(TestFrameSequence()
-                           .Data(1, "", true)
-                           .RstStream(5, Http2ErrorCode::REFUSED_STREAM)
-                           .Serialize());
-  // After receiving END_STREAM for 1 and RST_STREAM for 5, the session no
-  // longer expects reads.
-  EXPECT_FALSE(session.want_read());
-
-  // Client will not have anything else to write.
-  EXPECT_FALSE(session.want_write());
-  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
-  serialized = visitor_.data();
-  EXPECT_EQ(serialized.size(), 0);
-}
-
-TEST_F(NgHttp2SessionTest, ServerConstruction) {
-  NgHttp2Session session(Perspective::kServer, CreateCallbacks(), options_,
-                         &visitor_);
-  EXPECT_TRUE(session.want_read());
-  EXPECT_FALSE(session.want_write());
-  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
-  EXPECT_NE(session.raw_ptr(), nullptr);
-}
-
-TEST_F(NgHttp2SessionTest, ServerHandlesFrames) {
-  NgHttp2Session session(Perspective::kServer, CreateCallbacks(), options_,
-                         &visitor_);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Ping(42)
-                                 .WindowUpdate(0, 1000)
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor_, OnSettingsStart());
-  EXPECT_CALL(visitor_, OnSettingsEnd());
-
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor_, OnPing(42, false));
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor_, OnWindowUpdate(0, 1000));
-  EXPECT_CALL(visitor_, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor_, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor_, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor_, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor_, OnWindowUpdate(1, 2000));
-  EXPECT_CALL(visitor_, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor_, OnBeginDataForStream(1, 25));
-  EXPECT_CALL(visitor_, OnDataForStream(1, "This is the request body."));
-  EXPECT_CALL(visitor_, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor_, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":method", "GET"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":scheme", "http"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":authority", "example.com"));
-  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":path", "/this/is/request/two"));
-  EXPECT_CALL(visitor_, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor_, OnEndStream(3));
-  EXPECT_CALL(visitor_, OnFrameHeader(3, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor_, OnRstStream(3, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor_, OnCloseStream(3, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor_, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor_, OnPing(47, false));
-
-  const int64_t result = session.ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), result);
-
-  EXPECT_EQ(session.GetRemoteWindowSize(),
-            kInitialFlowControlWindowSize + 1000);
-
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor_, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(PING, 0, 8, 0x1));
-  EXPECT_CALL(visitor_, OnFrameSent(PING, 0, 8, 0x1, 0));
-  EXPECT_CALL(visitor_, OnBeforeFrameSent(PING, 0, 8, 0x1));
-  EXPECT_CALL(visitor_, OnFrameSent(PING, 0, 8, 0x1, 0));
-
-  EXPECT_TRUE(session.want_write());
-  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
-  // Some bytes should have been serialized.
-  absl::string_view serialized = visitor_.data();
-  // SETTINGS ack, two PING acks.
-  EXPECT_THAT(serialized, EqualsFrames({spdy::SpdyFrameType::SETTINGS,
-                                        spdy::SpdyFrameType::PING,
-                                        spdy::SpdyFrameType::PING}));
-}
-
-// Verifies that a null payload is caught by the OnPackExtensionCallback
-// implementation.
-TEST_F(NgHttp2SessionTest, NullPayload) {
-  NgHttp2Session session(Perspective::kClient, CreateCallbacks(), options_,
-                         &visitor_);
-
-  void* payload = nullptr;
-  const int result = nghttp2_submit_extension(
-      session.raw_ptr(), kMetadataFrameType, 0, 1, payload);
-  ASSERT_EQ(0, result);
-  EXPECT_TRUE(session.want_write());
-  int send_result = -1;
-  EXPECT_QUICHE_BUG(send_result = nghttp2_session_send(session.raw_ptr()),
-                    "Extension frame payload for stream 1 is null!");
-  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, send_result);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_test.cc b/http2/adapter/nghttp2_test.cc
deleted file mode 100644
index a65a775..0000000
--- a/http2/adapter/nghttp2_test.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-#include "http2/adapter/nghttp2.h"
-
-#include "absl/strings/str_cat.h"
-#include "http2/adapter/mock_nghttp2_callbacks.h"
-#include "http2/adapter/nghttp2_test_utils.h"
-#include "http2/adapter/nghttp2_util.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using testing::_;
-
-enum FrameType {
-  DATA,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-};
-
-nghttp2_option* GetOptions() {
-  nghttp2_option* options;
-  nghttp2_option_new(&options);
-  // Set some common options for compatibility.
-  nghttp2_option_set_no_closed_streams(options, 1);
-  nghttp2_option_set_no_auto_window_update(options, 1);
-  nghttp2_option_set_max_send_header_block_length(options, 0x2000000);
-  nghttp2_option_set_max_outbound_ack(options, 10000);
-  return options;
-}
-
-class Nghttp2Test : public testing::Test {
- public:
-  Nghttp2Test() : session_(MakeSessionPtr(nullptr)) {}
-
-  void SetUp() override { InitializeSession(); }
-
-  virtual Perspective GetPerspective() = 0;
-
-  void InitializeSession() {
-    auto nghttp2_callbacks = MockNghttp2Callbacks::GetCallbacks();
-    nghttp2_option* options = GetOptions();
-    nghttp2_session* ptr;
-    if (GetPerspective() == Perspective::kClient) {
-      nghttp2_session_client_new2(&ptr, nghttp2_callbacks.get(),
-                                  &mock_callbacks_, options);
-    } else {
-      nghttp2_session_server_new2(&ptr, nghttp2_callbacks.get(),
-                                  &mock_callbacks_, options);
-    }
-    nghttp2_option_del(options);
-
-    // Sets up the Send() callback to append to |serialized_|.
-    EXPECT_CALL(mock_callbacks_, Send(_, _, _))
-        .WillRepeatedly(
-            [this](const uint8_t* data, size_t length, int /*flags*/) {
-              absl::StrAppend(&serialized_, ToStringView(data, length));
-              return length;
-            });
-    // Sets up the SendData() callback to fetch and append data from a
-    // TestDataSource.
-    EXPECT_CALL(mock_callbacks_, SendData(_, _, _, _))
-        .WillRepeatedly([this](nghttp2_frame* /*frame*/, const uint8_t* framehd,
-                               size_t length, nghttp2_data_source* source) {
-          QUICHE_LOG(INFO) << "Appending frame header and " << length
-                           << " bytes of data";
-          auto* s = static_cast<TestDataSource*>(source->ptr);
-          absl::StrAppend(&serialized_, ToStringView(framehd, 9),
-                          s->ReadNext(length));
-          return 0;
-        });
-    session_ = MakeSessionPtr(ptr);
-  }
-
-  testing::StrictMock<MockNghttp2Callbacks> mock_callbacks_;
-  nghttp2_session_unique_ptr session_;
-  std::string serialized_;
-};
-
-class Nghttp2ClientTest : public Nghttp2Test {
- public:
-  Perspective GetPerspective() override { return Perspective::kClient; }
-};
-
-// Verifies nghttp2 behavior when acting as a client.
-TEST_F(Nghttp2ClientTest, ClientReceivesUnexpectedHeaders) {
-  const std::string initial_frames = TestFrameSequence()
-                                         .ServerPreface()
-                                         .Ping(42)
-                                         .WindowUpdate(0, 1000)
-                                         .Serialize();
-
-  testing::InSequence seq;
-  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(0, SETTINGS, 0)));
-  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsSettings(testing::IsEmpty())));
-  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(0, PING, 0)));
-  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsPing(42)));
-  EXPECT_CALL(mock_callbacks_,
-              OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, 0)));
-  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsWindowUpdate(1000)));
-
-  ssize_t result = nghttp2_session_mem_recv(
-      session_.get(), ToUint8Ptr(initial_frames.data()), initial_frames.size());
-  ASSERT_EQ(result, initial_frames.size());
-
-  const std::string unexpected_stream_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
-          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
-          .Serialize();
-
-  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
-  EXPECT_CALL(mock_callbacks_, OnInvalidFrameRecv(IsHeaders(1, _, _), _));
-  // No events from the DATA, RST_STREAM or GOAWAY.
-
-  nghttp2_session_mem_recv(session_.get(),
-                           ToUint8Ptr(unexpected_stream_frames.data()),
-                           unexpected_stream_frames.size());
-}
-
-// Tests the request-sending behavior of nghttp2 when acting as a client.
-TEST_F(Nghttp2ClientTest, ClientSendsRequest) {
-  int result = nghttp2_session_send(session_.get());
-  ASSERT_EQ(result, 0);
-
-  EXPECT_THAT(serialized_, testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized_.clear();
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(0, SETTINGS, 0)));
-  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsSettings(testing::IsEmpty())));
-
-  ssize_t recv_result = nghttp2_session_mem_recv(
-      session_.get(), ToUint8Ptr(initial_frames.data()), initial_frames.size());
-  EXPECT_EQ(initial_frames.size(), recv_result);
-
-  // Client wants to send a SETTINGS ack.
-  EXPECT_CALL(mock_callbacks_, BeforeFrameSend(IsSettings(testing::IsEmpty())));
-  EXPECT_CALL(mock_callbacks_, OnFrameSend(IsSettings(testing::IsEmpty())));
-  EXPECT_TRUE(nghttp2_session_want_write(session_.get()));
-  result = nghttp2_session_send(session_.get());
-  EXPECT_THAT(serialized_, EqualsFrames({spdy::SpdyFrameType::SETTINGS}));
-  serialized_.clear();
-
-  EXPECT_FALSE(nghttp2_session_want_write(session_.get()));
-
-  // The following sets up the client request.
-  std::vector<std::pair<absl::string_view, absl::string_view>> headers = {
-      {":method", "POST"},
-      {":scheme", "http"},
-      {":authority", "example.com"},
-      {":path", "/this/is/request/one"}};
-  std::vector<nghttp2_nv> nvs;
-  for (const auto& h : headers) {
-    nvs.push_back({.name = ToUint8Ptr(h.first.data()),
-                   .value = ToUint8Ptr(h.second.data()),
-                   .namelen = h.first.size(),
-                   .valuelen = h.second.size()});
-  }
-  const absl::string_view kBody = "This is an example request body.";
-  TestDataSource source{kBody};
-  nghttp2_data_provider provider = source.MakeDataProvider();
-  // After submitting the request, the client will want to write.
-  int stream_id =
-      nghttp2_submit_request(session_.get(), nullptr /* pri_spec */, nvs.data(),
-                             nvs.size(), &provider, nullptr /* stream_data */);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(nghttp2_session_want_write(session_.get()));
-
-  // We expect that the client will want to write HEADERS, then DATA.
-  EXPECT_CALL(mock_callbacks_, BeforeFrameSend(IsHeaders(stream_id, _, _)));
-  EXPECT_CALL(mock_callbacks_, OnFrameSend(IsHeaders(stream_id, _, _)));
-  EXPECT_CALL(mock_callbacks_, OnFrameSend(IsData(stream_id, kBody.size(), _)));
-  nghttp2_session_send(session_.get());
-  EXPECT_THAT(serialized_, EqualsFrames({spdy::SpdyFrameType::HEADERS,
-                                         spdy::SpdyFrameType::DATA}));
-  EXPECT_THAT(serialized_, testing::HasSubstr(kBody));
-
-  // Once the request is flushed, the client no longer wants to write.
-  EXPECT_FALSE(nghttp2_session_want_write(session_.get()));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_test_utils.cc b/http2/adapter/nghttp2_test_utils.cc
deleted file mode 100644
index 6e4b5b2..0000000
--- a/http2/adapter/nghttp2_test_utils.cc
+++ /dev/null
@@ -1,463 +0,0 @@
-#include "http2/adapter/nghttp2_test_utils.h"
-
-#include "http2/adapter/nghttp2_util.h"
-#include "common/quiche_endian.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-namespace {
-
-// Custom gMock matcher, used to implement HasFrameHeader().
-class FrameHeaderMatcher {
- public:
-  FrameHeaderMatcher(int32_t streamid, uint8_t type,
-                     const testing::Matcher<int> flags)
-      : stream_id_(streamid), type_(type), flags_(flags) {}
-
-  bool Match(const nghttp2_frame_hd& frame,
-             testing::MatchResultListener* listener) const {
-    bool matched = true;
-    if (stream_id_ != frame.stream_id) {
-      *listener << "; expected stream " << stream_id_ << ", saw "
-                << frame.stream_id;
-      matched = false;
-    }
-    if (type_ != frame.type) {
-      *listener << "; expected frame type " << type_ << ", saw "
-                << static_cast<int>(frame.type);
-      matched = false;
-    }
-    if (!flags_.MatchAndExplain(frame.flags, listener)) {
-      matched = false;
-    }
-    return matched;
-  }
-
-  void DescribeTo(std::ostream* os) const {
-    *os << "contains a frame header with stream " << stream_id_ << ", type "
-        << type_ << ", ";
-    flags_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const {
-    *os << "does not contain a frame header with stream " << stream_id_
-        << ", type " << type_ << ", ";
-    flags_.DescribeNegationTo(os);
-  }
-
- private:
-  const int32_t stream_id_;
-  const int type_;
-  const testing::Matcher<int> flags_;
-};
-
-class PointerToFrameHeaderMatcher
-    : public FrameHeaderMatcher,
-      public testing::MatcherInterface<const nghttp2_frame_hd*> {
- public:
-  PointerToFrameHeaderMatcher(int32_t streamid, uint8_t type,
-                              const testing::Matcher<int> flags)
-      : FrameHeaderMatcher(streamid, type, flags) {}
-
-  bool MatchAndExplain(const nghttp2_frame_hd* frame,
-                       testing::MatchResultListener* listener) const override {
-    return FrameHeaderMatcher::Match(*frame, listener);
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    FrameHeaderMatcher::DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    FrameHeaderMatcher::DescribeNegationTo(os);
-  }
-};
-
-class ReferenceToFrameHeaderMatcher
-    : public FrameHeaderMatcher,
-      public testing::MatcherInterface<const nghttp2_frame_hd&> {
- public:
-  ReferenceToFrameHeaderMatcher(int32_t streamid, uint8_t type,
-                                const testing::Matcher<int> flags)
-      : FrameHeaderMatcher(streamid, type, flags) {}
-
-  bool MatchAndExplain(const nghttp2_frame_hd& frame,
-                       testing::MatchResultListener* listener) const override {
-    return FrameHeaderMatcher::Match(frame, listener);
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    FrameHeaderMatcher::DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    FrameHeaderMatcher::DescribeNegationTo(os);
-  }
-};
-
-class DataMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  DataMatcher(const testing::Matcher<uint32_t> stream_id,
-              const testing::Matcher<size_t> length,
-              const testing::Matcher<int> flags,
-              const testing::Matcher<size_t> padding)
-      : stream_id_(stream_id),
-        length_(length),
-        flags_(flags),
-        padding_(padding) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_DATA) {
-      *listener << "; expected DATA frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    bool matched = true;
-    if (!stream_id_.MatchAndExplain(frame->hd.stream_id, listener)) {
-      matched = false;
-    }
-    if (!length_.MatchAndExplain(frame->hd.length, listener)) {
-      matched = false;
-    }
-    if (!flags_.MatchAndExplain(frame->hd.flags, listener)) {
-      matched = false;
-    }
-    if (!padding_.MatchAndExplain(frame->data.padlen, listener)) {
-      matched = false;
-    }
-    return matched;
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a DATA frame, ";
-    stream_id_.DescribeTo(os);
-    length_.DescribeTo(os);
-    flags_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a DATA frame, ";
-    stream_id_.DescribeNegationTo(os);
-    length_.DescribeNegationTo(os);
-    flags_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<uint32_t> stream_id_;
-  const testing::Matcher<size_t> length_;
-  const testing::Matcher<int> flags_;
-  const testing::Matcher<size_t> padding_;
-};
-
-class HeadersMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  HeadersMatcher(const testing::Matcher<uint32_t> stream_id,
-                 const testing::Matcher<int> flags,
-                 const testing::Matcher<int> category)
-      : stream_id_(stream_id), flags_(flags), category_(category) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_HEADERS) {
-      *listener << "; expected HEADERS frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    bool matched = true;
-    if (!stream_id_.MatchAndExplain(frame->hd.stream_id, listener)) {
-      matched = false;
-    }
-    if (!flags_.MatchAndExplain(frame->hd.flags, listener)) {
-      matched = false;
-    }
-    if (!category_.MatchAndExplain(frame->headers.cat, listener)) {
-      matched = false;
-    }
-    return matched;
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a HEADERS frame, ";
-    stream_id_.DescribeTo(os);
-    flags_.DescribeTo(os);
-    category_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a HEADERS frame, ";
-    stream_id_.DescribeNegationTo(os);
-    flags_.DescribeNegationTo(os);
-    category_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<uint32_t> stream_id_;
-  const testing::Matcher<int> flags_;
-  const testing::Matcher<int> category_;
-};
-
-class RstStreamMatcher
-    : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  RstStreamMatcher(const testing::Matcher<uint32_t> stream_id,
-                   const testing::Matcher<uint32_t> error_code)
-      : stream_id_(stream_id), error_code_(error_code) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_RST_STREAM) {
-      *listener << "; expected RST_STREAM frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    bool matched = true;
-    if (!stream_id_.MatchAndExplain(frame->hd.stream_id, listener)) {
-      matched = false;
-    }
-    if (!error_code_.MatchAndExplain(frame->rst_stream.error_code, listener)) {
-      matched = false;
-    }
-    return matched;
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a RST_STREAM frame, ";
-    stream_id_.DescribeTo(os);
-    error_code_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a RST_STREAM frame, ";
-    stream_id_.DescribeNegationTo(os);
-    error_code_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<uint32_t> stream_id_;
-  const testing::Matcher<uint32_t> error_code_;
-};
-
-class SettingsMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  SettingsMatcher(const testing::Matcher<std::vector<Http2Setting>> values)
-      : values_(values) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_SETTINGS) {
-      *listener << "; expected SETTINGS frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    std::vector<Http2Setting> settings;
-    settings.reserve(frame->settings.niv);
-    for (size_t i = 0; i < frame->settings.niv; ++i) {
-      const auto& p = frame->settings.iv[i];
-      settings.push_back({static_cast<uint16_t>(p.settings_id), p.value});
-    }
-    return values_.MatchAndExplain(settings, listener);
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a SETTINGS frame, ";
-    values_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a SETTINGS frame, ";
-    values_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<std::vector<Http2Setting>> values_;
-};
-
-class PingMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  PingMatcher(const testing::Matcher<uint64_t> id, bool is_ack)
-      : id_(id), is_ack_(is_ack) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_PING) {
-      *listener << "; expected PING frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    bool matched = true;
-    bool frame_ack = frame->hd.flags & NGHTTP2_FLAG_ACK;
-    if (is_ack_ != frame_ack) {
-      *listener << "; expected is_ack=" << is_ack_ << ", saw " << frame_ack;
-      matched = false;
-    }
-    uint64_t data;
-    std::memcpy(&data, frame->ping.opaque_data, sizeof(data));
-    data = quiche::QuicheEndian::HostToNet64(data);
-    if (!id_.MatchAndExplain(data, listener)) {
-      matched = false;
-    }
-    return matched;
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a PING frame, ";
-    id_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a PING frame, ";
-    id_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<uint64_t> id_;
-  const bool is_ack_;
-};
-
-class GoAwayMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  GoAwayMatcher(const testing::Matcher<uint32_t> last_stream_id,
-                const testing::Matcher<uint32_t> error_code,
-                const testing::Matcher<absl::string_view> opaque_data)
-      : last_stream_id_(last_stream_id),
-        error_code_(error_code),
-        opaque_data_(opaque_data) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_GOAWAY) {
-      *listener << "; expected GOAWAY frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    bool matched = true;
-    if (!last_stream_id_.MatchAndExplain(frame->goaway.last_stream_id,
-                                         listener)) {
-      matched = false;
-    }
-    if (!error_code_.MatchAndExplain(frame->goaway.error_code, listener)) {
-      matched = false;
-    }
-    auto opaque_data =
-        ToStringView(frame->goaway.opaque_data, frame->goaway.opaque_data_len);
-    if (!opaque_data_.MatchAndExplain(opaque_data, listener)) {
-      matched = false;
-    }
-    return matched;
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a GOAWAY frame, ";
-    last_stream_id_.DescribeTo(os);
-    error_code_.DescribeTo(os);
-    opaque_data_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a GOAWAY frame, ";
-    last_stream_id_.DescribeNegationTo(os);
-    error_code_.DescribeNegationTo(os);
-    opaque_data_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<uint32_t> last_stream_id_;
-  const testing::Matcher<uint32_t> error_code_;
-  const testing::Matcher<absl::string_view> opaque_data_;
-};
-
-class WindowUpdateMatcher
-    : public testing::MatcherInterface<const nghttp2_frame*> {
- public:
-  WindowUpdateMatcher(const testing::Matcher<uint32_t> delta) : delta_(delta) {}
-
-  bool MatchAndExplain(const nghttp2_frame* frame,
-                       testing::MatchResultListener* listener) const override {
-    if (frame->hd.type != NGHTTP2_WINDOW_UPDATE) {
-      *listener << "; expected WINDOW_UPDATE frame, saw frame of type "
-                << static_cast<int>(frame->hd.type);
-      return false;
-    }
-    return delta_.MatchAndExplain(frame->window_update.window_size_increment,
-                                  listener);
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "contains a WINDOW_UPDATE frame, ";
-    delta_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "does not contain a WINDOW_UPDATE frame, ";
-    delta_.DescribeNegationTo(os);
-  }
-
- private:
-  const testing::Matcher<uint32_t> delta_;
-};
-
-}  // namespace
-
-testing::Matcher<const nghttp2_frame_hd*> HasFrameHeader(
-    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags) {
-  return MakeMatcher(new PointerToFrameHeaderMatcher(streamid, type, flags));
-}
-
-testing::Matcher<const nghttp2_frame_hd&> HasFrameHeaderRef(
-    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags) {
-  return MakeMatcher(new ReferenceToFrameHeaderMatcher(streamid, type, flags));
-}
-
-testing::Matcher<const nghttp2_frame*> IsData(
-    const testing::Matcher<uint32_t> stream_id,
-    const testing::Matcher<size_t> length, const testing::Matcher<int> flags,
-    const testing::Matcher<size_t> padding) {
-  return MakeMatcher(new DataMatcher(stream_id, length, flags, padding));
-}
-
-testing::Matcher<const nghttp2_frame*> IsHeaders(
-    const testing::Matcher<uint32_t> stream_id,
-    const testing::Matcher<int> flags, const testing::Matcher<int> category) {
-  return MakeMatcher(new HeadersMatcher(stream_id, flags, category));
-}
-
-testing::Matcher<const nghttp2_frame*> IsRstStream(
-    const testing::Matcher<uint32_t> stream_id,
-    const testing::Matcher<uint32_t> error_code) {
-  return MakeMatcher(new RstStreamMatcher(stream_id, error_code));
-}
-
-testing::Matcher<const nghttp2_frame*> IsSettings(
-    const testing::Matcher<std::vector<Http2Setting>> values) {
-  return MakeMatcher(new SettingsMatcher(values));
-}
-
-testing::Matcher<const nghttp2_frame*> IsPing(
-    const testing::Matcher<uint64_t> id) {
-  return MakeMatcher(new PingMatcher(id, false));
-}
-
-testing::Matcher<const nghttp2_frame*> IsPingAck(
-    const testing::Matcher<uint64_t> id) {
-  return MakeMatcher(new PingMatcher(id, true));
-}
-
-testing::Matcher<const nghttp2_frame*> IsGoAway(
-    const testing::Matcher<uint32_t> last_stream_id,
-    const testing::Matcher<uint32_t> error_code,
-    const testing::Matcher<absl::string_view> opaque_data) {
-  return MakeMatcher(
-      new GoAwayMatcher(last_stream_id, error_code, opaque_data));
-}
-
-testing::Matcher<const nghttp2_frame*> IsWindowUpdate(
-    const testing::Matcher<uint32_t> delta) {
-  return MakeMatcher(new WindowUpdateMatcher(delta));
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_test_utils.h b/http2/adapter/nghttp2_test_utils.h
deleted file mode 100644
index 24493d7..0000000
--- a/http2/adapter/nghttp2_test_utils.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
-#define QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
-
-#include <cstdint>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/nghttp2.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-// A simple class that can easily be adapted to act as a nghttp2_data_source.
-class QUICHE_NO_EXPORT TestDataSource {
- public:
-  explicit TestDataSource(absl::string_view data) : data_(std::string(data)) {}
-
-  absl::string_view ReadNext(size_t size) {
-    const size_t to_send = std::min(size, remaining_.size());
-    auto ret = remaining_.substr(0, to_send);
-    remaining_.remove_prefix(to_send);
-    return ret;
-  }
-
-  size_t SelectPayloadLength(size_t max_length) {
-    return std::min(max_length, remaining_.size());
-  }
-
-  nghttp2_data_provider MakeDataProvider() {
-    return nghttp2_data_provider{
-        .source = {.ptr = this},
-        .read_callback = [](nghttp2_session*, int32_t, uint8_t*, size_t length,
-                            uint32_t* data_flags, nghttp2_data_source* source,
-                            void*) -> ssize_t {
-          *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
-          auto* s = static_cast<TestDataSource*>(source->ptr);
-          if (!s->is_data_available()) {
-            return NGHTTP2_ERR_DEFERRED;
-          }
-          const ssize_t ret = s->SelectPayloadLength(length);
-          if (ret < static_cast<ssize_t>(length)) {
-            *data_flags |= NGHTTP2_DATA_FLAG_EOF;
-          }
-          return ret;
-        }};
-  }
-
-  bool is_data_available() const { return is_data_available_; }
-  void set_is_data_available(bool value) { is_data_available_ = value; }
-
- private:
-  const std::string data_;
-  absl::string_view remaining_ = data_;
-  bool is_data_available_ = true;
-};
-
-// Matchers for nghttp2 data types.
-testing::Matcher<const nghttp2_frame_hd*> HasFrameHeader(
-    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags);
-testing::Matcher<const nghttp2_frame_hd&> HasFrameHeaderRef(
-    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags);
-
-testing::Matcher<const nghttp2_frame*> IsData(
-    const testing::Matcher<uint32_t> stream_id,
-    const testing::Matcher<size_t> length, const testing::Matcher<int> flags,
-    const testing::Matcher<size_t> padding = testing::_);
-
-testing::Matcher<const nghttp2_frame*> IsHeaders(
-    const testing::Matcher<uint32_t> stream_id,
-    const testing::Matcher<int> flags, const testing::Matcher<int> category);
-
-testing::Matcher<const nghttp2_frame*> IsRstStream(
-    const testing::Matcher<uint32_t> stream_id,
-    const testing::Matcher<uint32_t> error_code);
-
-testing::Matcher<const nghttp2_frame*> IsSettings(
-    const testing::Matcher<std::vector<Http2Setting>> values);
-
-testing::Matcher<const nghttp2_frame*> IsPing(
-    const testing::Matcher<uint64_t> id);
-
-testing::Matcher<const nghttp2_frame*> IsPingAck(
-    const testing::Matcher<uint64_t> id);
-
-testing::Matcher<const nghttp2_frame*> IsGoAway(
-    const testing::Matcher<uint32_t> last_stream_id,
-    const testing::Matcher<uint32_t> error_code,
-    const testing::Matcher<absl::string_view> opaque_data);
-
-testing::Matcher<const nghttp2_frame*> IsWindowUpdate(
-    const testing::Matcher<uint32_t> delta);
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
diff --git a/http2/adapter/nghttp2_util.cc b/http2/adapter/nghttp2_util.cc
deleted file mode 100644
index f3923a7..0000000
--- a/http2/adapter/nghttp2_util.cc
+++ /dev/null
@@ -1,305 +0,0 @@
-#include "http2/adapter/nghttp2_util.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_join.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "http2/adapter/http2_protocol.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-
-namespace http2 {
-namespace adapter {
-
-namespace {
-
-using InvalidFrameError = Http2VisitorInterface::InvalidFrameError;
-
-void DeleteCallbacks(nghttp2_session_callbacks* callbacks) {
-  if (callbacks) {
-    nghttp2_session_callbacks_del(callbacks);
-  }
-}
-
-void DeleteSession(nghttp2_session* session) {
-  if (session) {
-    nghttp2_session_del(session);
-  }
-}
-
-}  // namespace
-
-nghttp2_session_callbacks_unique_ptr MakeCallbacksPtr(
-    nghttp2_session_callbacks* callbacks) {
-  return nghttp2_session_callbacks_unique_ptr(callbacks, &DeleteCallbacks);
-}
-
-nghttp2_session_unique_ptr MakeSessionPtr(nghttp2_session* session) {
-  return nghttp2_session_unique_ptr(session, &DeleteSession);
-}
-
-uint8_t* ToUint8Ptr(char* str) { return reinterpret_cast<uint8_t*>(str); }
-uint8_t* ToUint8Ptr(const char* str) {
-  return const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(str));
-}
-
-absl::string_view ToStringView(nghttp2_rcbuf* rc_buffer) {
-  nghttp2_vec buffer = nghttp2_rcbuf_get_buf(rc_buffer);
-  return absl::string_view(reinterpret_cast<const char*>(buffer.base),
-                           buffer.len);
-}
-
-absl::string_view ToStringView(uint8_t* pointer, size_t length) {
-  return absl::string_view(reinterpret_cast<const char*>(pointer), length);
-}
-
-absl::string_view ToStringView(const uint8_t* pointer, size_t length) {
-  return absl::string_view(reinterpret_cast<const char*>(pointer), length);
-}
-
-std::vector<nghttp2_nv> GetNghttp2Nvs(absl::Span<const Header> headers) {
-  const int num_headers = headers.size();
-  std::vector<nghttp2_nv> nghttp2_nvs;
-  nghttp2_nvs.reserve(num_headers);
-  for (int i = 0; i < num_headers; ++i) {
-    nghttp2_nv header;
-    uint8_t flags = NGHTTP2_NV_FLAG_NONE;
-
-    const auto [name, no_copy_name] = GetStringView(headers[i].first);
-    header.name = ToUint8Ptr(name.data());
-    header.namelen = name.size();
-    if (no_copy_name) {
-      flags |= NGHTTP2_NV_FLAG_NO_COPY_NAME;
-    }
-    const auto [value, no_copy_value] = GetStringView(headers[i].second);
-    header.value = ToUint8Ptr(value.data());
-    header.valuelen = value.size();
-    if (no_copy_value) {
-      flags |= NGHTTP2_NV_FLAG_NO_COPY_VALUE;
-    }
-    header.flags = flags;
-    nghttp2_nvs.push_back(std::move(header));
-  }
-
-  return nghttp2_nvs;
-}
-
-std::vector<nghttp2_nv> GetResponseNghttp2Nvs(
-    const spdy::Http2HeaderBlock& headers,
-    absl::string_view response_code) {
-  // Allocate enough for all headers and also the :status pseudoheader.
-  const int num_headers = headers.size();
-  std::vector<nghttp2_nv> nghttp2_nvs;
-  nghttp2_nvs.reserve(num_headers + 1);
-
-  // Add the :status pseudoheader first.
-  nghttp2_nv status;
-  status.name = ToUint8Ptr(kHttp2StatusPseudoHeader);
-  status.namelen = strlen(kHttp2StatusPseudoHeader);
-  status.value = ToUint8Ptr(response_code.data());
-  status.valuelen = response_code.size();
-  status.flags = NGHTTP2_FLAG_NONE;
-  nghttp2_nvs.push_back(std::move(status));
-
-  // Add the remaining headers.
-  for (const auto& header_pair : headers) {
-    nghttp2_nv header;
-    header.name = ToUint8Ptr(header_pair.first.data());
-    header.namelen = header_pair.first.size();
-    header.value = ToUint8Ptr(header_pair.second.data());
-    header.valuelen = header_pair.second.size();
-    header.flags = NGHTTP2_FLAG_NONE;
-    nghttp2_nvs.push_back(std::move(header));
-  }
-
-  return nghttp2_nvs;
-}
-
-Http2ErrorCode ToHttp2ErrorCode(uint32_t wire_error_code) {
-  if (wire_error_code > static_cast<int>(Http2ErrorCode::MAX_ERROR_CODE)) {
-    return Http2ErrorCode::INTERNAL_ERROR;
-  }
-  return static_cast<Http2ErrorCode>(wire_error_code);
-}
-
-int ToNgHttp2ErrorCode(InvalidFrameError error) {
-  switch (error) {
-    case InvalidFrameError::kProtocol:
-      return NGHTTP2_ERR_PROTO;
-    case InvalidFrameError::kRefusedStream:
-      return NGHTTP2_ERR_REFUSED_STREAM;
-    case InvalidFrameError::kHttpHeader:
-      return NGHTTP2_ERR_HTTP_HEADER;
-    case InvalidFrameError::kHttpMessaging:
-      return NGHTTP2_ERR_HTTP_MESSAGING;
-    case InvalidFrameError::kFlowControl:
-      return NGHTTP2_ERR_FLOW_CONTROL;
-    case InvalidFrameError::kStreamClosed:
-      return NGHTTP2_ERR_STREAM_CLOSED;
-  }
-  return NGHTTP2_ERR_PROTO;
-}
-
-InvalidFrameError ToInvalidFrameError(int error) {
-  switch (error) {
-    case NGHTTP2_ERR_PROTO:
-      return InvalidFrameError::kProtocol;
-    case NGHTTP2_ERR_REFUSED_STREAM:
-      return InvalidFrameError::kRefusedStream;
-    case NGHTTP2_ERR_HTTP_HEADER:
-      return InvalidFrameError::kHttpHeader;
-    case NGHTTP2_ERR_HTTP_MESSAGING:
-      return InvalidFrameError::kHttpMessaging;
-    case NGHTTP2_ERR_FLOW_CONTROL:
-      return InvalidFrameError::kFlowControl;
-    case NGHTTP2_ERR_STREAM_CLOSED:
-      return InvalidFrameError::kStreamClosed;
-  }
-  return InvalidFrameError::kProtocol;
-}
-
-class Nghttp2DataFrameSource : public DataFrameSource {
- public:
-  Nghttp2DataFrameSource(nghttp2_data_provider provider,
-                         nghttp2_send_data_callback send_data,
-                         void* user_data)
-      : provider_(std::move(provider)),
-        send_data_(std::move(send_data)),
-        user_data_(user_data) {}
-
-  std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) override {
-    const int32_t stream_id = 0;
-    uint32_t data_flags = 0;
-    int64_t result = provider_.read_callback(
-        nullptr /* session */, stream_id, nullptr /* buf */, max_length,
-        &data_flags, &provider_.source, nullptr /* user_data */);
-    if (result == NGHTTP2_ERR_DEFERRED) {
-      return {kBlocked, false};
-    } else if (result < 0) {
-      return {kError, false};
-    } else if ((data_flags & NGHTTP2_DATA_FLAG_NO_COPY) == 0) {
-      QUICHE_LOG(ERROR) << "Source did not use the zero-copy API!";
-      return {kError, false};
-    } else {
-      const bool eof = data_flags & NGHTTP2_DATA_FLAG_EOF;
-      if (eof && (data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM) == 0) {
-        send_fin_ = true;
-      }
-      return {result, eof};
-    }
-  }
-
-  bool Send(absl::string_view frame_header, size_t payload_length) override {
-    nghttp2_frame frame;
-    frame.hd.type = 0;
-    frame.hd.length = payload_length;
-    frame.hd.flags = 0;
-    frame.hd.stream_id = 0;
-    frame.data.padlen = 0;
-    const int result = send_data_(
-        nullptr /* session */, &frame, ToUint8Ptr(frame_header.data()),
-        payload_length, &provider_.source, user_data_);
-    QUICHE_LOG_IF(ERROR, result < 0 && result != NGHTTP2_ERR_WOULDBLOCK)
-        << "Unexpected error code from send: " << result;
-    return result == 0;
-  }
-
-  bool send_fin() const override { return send_fin_; }
-
- private:
-  nghttp2_data_provider provider_;
-  nghttp2_send_data_callback send_data_;
-  void* user_data_;
-  bool send_fin_ = false;
-};
-
-std::unique_ptr<DataFrameSource> MakeZeroCopyDataFrameSource(
-    nghttp2_data_provider provider,
-    void* user_data,
-    nghttp2_send_data_callback send_data) {
-  return absl::make_unique<Nghttp2DataFrameSource>(
-      std::move(provider), std::move(send_data), user_data);
-}
-
-absl::string_view ErrorString(uint32_t error_code) {
-  return Http2ErrorCodeToString(static_cast<Http2ErrorCode>(error_code));
-}
-
-size_t PaddingLength(uint8_t flags, size_t padlen) {
-  return (flags & 0x8 ? 1 : 0) + padlen;
-}
-
-struct NvFormatter {
-  void operator()(std::string* out, const nghttp2_nv& nv) {
-    absl::StrAppend(out, ToStringView(nv.name, nv.namelen), ": ",
-                    ToStringView(nv.value, nv.valuelen));
-  }
-};
-
-std::string NvsAsString(nghttp2_nv* nva, size_t nvlen) {
-  return absl::StrJoin(absl::MakeConstSpan(nva, nvlen), ", ", NvFormatter());
-}
-
-#define HTTP2_FRAME_SEND_LOG QUICHE_VLOG(1)
-
-void LogBeforeSend(const nghttp2_frame& frame) {
-  switch (static_cast<FrameType>(frame.hd.type)) {
-    case FrameType::DATA:
-      HTTP2_FRAME_SEND_LOG << "Sending DATA on stream " << frame.hd.stream_id
-                           << " with length "
-                           << frame.hd.length - PaddingLength(frame.hd.flags,
-                                                              frame.data.padlen)
-                           << " and padding "
-                           << PaddingLength(frame.hd.flags, frame.data.padlen);
-      break;
-    case FrameType::HEADERS:
-      HTTP2_FRAME_SEND_LOG << "Sending HEADERS on stream " << frame.hd.stream_id
-                           << " with headers ["
-                           << NvsAsString(frame.headers.nva,
-                                          frame.headers.nvlen)
-                           << "]";
-      break;
-    case FrameType::PRIORITY:
-      HTTP2_FRAME_SEND_LOG << "Sending PRIORITY";
-      break;
-    case FrameType::RST_STREAM:
-      HTTP2_FRAME_SEND_LOG << "Sending RST_STREAM on stream "
-                           << frame.hd.stream_id << " with error code "
-                           << ErrorString(frame.rst_stream.error_code);
-      break;
-    case FrameType::SETTINGS:
-      HTTP2_FRAME_SEND_LOG << "Sending SETTINGS with " << frame.settings.niv
-                           << " entries, is_ack: " << (frame.hd.flags & 0x01);
-      break;
-    case FrameType::PUSH_PROMISE:
-      HTTP2_FRAME_SEND_LOG << "Sending PUSH_PROMISE";
-      break;
-    case FrameType::PING: {
-      Http2PingId ping_id;
-      std::memcpy(&ping_id, frame.ping.opaque_data, sizeof(Http2PingId));
-      HTTP2_FRAME_SEND_LOG << "Sending PING with unique_id "
-                           << quiche::QuicheEndian::NetToHost64(ping_id)
-                           << ", is_ack: " << (frame.hd.flags & 0x01);
-      break;
-    }
-    case FrameType::GOAWAY:
-      HTTP2_FRAME_SEND_LOG << "Sending GOAWAY with last_stream: "
-                           << frame.goaway.last_stream_id << " and error "
-                           << ErrorString(frame.goaway.error_code);
-      break;
-    case FrameType::WINDOW_UPDATE:
-      HTTP2_FRAME_SEND_LOG << "Sending WINDOW_UPDATE on stream "
-                           << frame.hd.stream_id << " with update delta "
-                           << frame.window_update.window_size_increment;
-      break;
-    case FrameType::CONTINUATION:
-      HTTP2_FRAME_SEND_LOG << "Sending CONTINUATION, which is unexpected";
-      break;
-  }
-}
-
-#undef HTTP2_FRAME_SEND_LOG
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/nghttp2_util.h b/http2/adapter/nghttp2_util.h
deleted file mode 100644
index a24d98d..0000000
--- a/http2/adapter/nghttp2_util.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Various utility/conversion functions for compatibility with the nghttp2 API.
-
-#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_UTIL_H_
-#define QUICHE_HTTP2_ADAPTER_NGHTTP2_UTIL_H_
-
-#include <cstdint>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "http2/adapter/data_source.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/nghttp2.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace http2 {
-namespace adapter {
-
-// Return codes to represent various errors.
-inline constexpr int kStreamCallbackFailureStatus =
-    NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-inline constexpr int kCancelStatus = NGHTTP2_ERR_CANCEL;
-
-using CallbacksDeleter = void (*)(nghttp2_session_callbacks*);
-using SessionDeleter = void (*)(nghttp2_session*);
-
-using nghttp2_session_callbacks_unique_ptr =
-    std::unique_ptr<nghttp2_session_callbacks, CallbacksDeleter>;
-using nghttp2_session_unique_ptr =
-    std::unique_ptr<nghttp2_session, SessionDeleter>;
-
-nghttp2_session_callbacks_unique_ptr MakeCallbacksPtr(
-    nghttp2_session_callbacks* callbacks);
-nghttp2_session_unique_ptr MakeSessionPtr(nghttp2_session* session);
-
-uint8_t* ToUint8Ptr(char* str);
-uint8_t* ToUint8Ptr(const char* str);
-
-absl::string_view ToStringView(nghttp2_rcbuf* rc_buffer);
-absl::string_view ToStringView(uint8_t* pointer, size_t length);
-absl::string_view ToStringView(const uint8_t* pointer, size_t length);
-
-// Returns the nghttp2 header structure from the given |headers|, which
-// must have the correct pseudoheaders preceding other headers.
-std::vector<nghttp2_nv> GetNghttp2Nvs(absl::Span<const Header> headers);
-
-// Returns the nghttp2 header structure from the given response |headers|, with
-// the :status pseudoheader first based on the given |response_code|. The
-// |response_code| is passed in separately from |headers| for lifetime reasons.
-std::vector<nghttp2_nv> GetResponseNghttp2Nvs(
-    const spdy::Http2HeaderBlock& headers,
-    absl::string_view response_code);
-
-// Returns the HTTP/2 error code corresponding to the raw wire value, as defined
-// in RFC 7540 Section 7. Unrecognized error codes are treated as INTERNAL_ERROR
-// based on the RFC 7540 Section 7 suggestion.
-Http2ErrorCode ToHttp2ErrorCode(uint32_t wire_error_code);
-
-// Converts between the integer error code used by nghttp2 and the corresponding
-// InvalidFrameError value.
-int ToNgHttp2ErrorCode(Http2VisitorInterface::InvalidFrameError error);
-Http2VisitorInterface::InvalidFrameError ToInvalidFrameError(int error);
-
-// Transforms a nghttp2_data_provider into a DataFrameSource. Assumes that
-// |provider| uses the zero-copy nghttp2_data_source_read_callback API. Unsafe
-// otherwise.
-std::unique_ptr<DataFrameSource> MakeZeroCopyDataFrameSource(
-    nghttp2_data_provider provider,
-    void* user_data,
-    nghttp2_send_data_callback send_data);
-
-void LogBeforeSend(const nghttp2_frame& frame);
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_UTIL_H_
diff --git a/http2/adapter/nghttp2_util_test.cc b/http2/adapter/nghttp2_util_test.cc
deleted file mode 100644
index 1ec00ba..0000000
--- a/http2/adapter/nghttp2_util_test.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "http2/adapter/nghttp2_util.h"
-
-#include "http2/adapter/nghttp2_test_utils.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-// This send callback assumes |source|'s pointer is a TestDataSource, and
-// |user_data| is a std::string.
-int FakeSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/,
-                     const uint8_t* framehd, size_t length,
-                     nghttp2_data_source* source, void* user_data) {
-  auto* dest = static_cast<std::string*>(user_data);
-  // Appends the frame header to the string.
-  absl::StrAppend(dest, ToStringView(framehd, 9));
-  auto* test_source = static_cast<TestDataSource*>(source->ptr);
-  absl::string_view payload = test_source->ReadNext(length);
-  // Appends the frame payload to the string.
-  absl::StrAppend(dest, payload);
-  return 0;
-}
-
-TEST(MakeZeroCopyDataFrameSource, EmptyPayload) {
-  std::string result;
-
-  const absl::string_view kEmptyBody = "";
-  TestDataSource body1{kEmptyBody};
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
-  auto [length, eof] = frame_source->SelectPayloadLength(100);
-  EXPECT_EQ(length, 0);
-  EXPECT_TRUE(eof);
-  frame_source->Send("ninebytes", 0);
-  EXPECT_EQ(result, "ninebytes");
-}
-
-TEST(MakeZeroCopyDataFrameSource, ShortPayload) {
-  std::string result;
-
-  const absl::string_view kShortBody =
-      "<html><head><title>Example Page!</title></head>"
-      "<body><div><span><table><tr><th><blink>Wow!!"
-      "</blink></th></tr></table></span></div></body>"
-      "</html>";
-  TestDataSource body1{kShortBody};
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
-  auto [length, eof] = frame_source->SelectPayloadLength(200);
-  EXPECT_EQ(length, kShortBody.size());
-  EXPECT_TRUE(eof);
-  frame_source->Send("ninebytes", length);
-  EXPECT_EQ(result, absl::StrCat("ninebytes", kShortBody));
-}
-
-TEST(MakeZeroCopyDataFrameSource, MultiFramePayload) {
-  std::string result;
-
-  const absl::string_view kShortBody =
-      "<html><head><title>Example Page!</title></head>"
-      "<body><div><span><table><tr><th><blink>Wow!!"
-      "</blink></th></tr></table></span></div></body>"
-      "</html>";
-  TestDataSource body1{kShortBody};
-  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
-  nghttp2_data_provider provider = body1.MakeDataProvider();
-
-  // This call transforms it back into a DataFrameSource, which is compatible
-  // with the Http2Adapter API.
-  std::unique_ptr<DataFrameSource> frame_source =
-      MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
-  auto ret = frame_source->SelectPayloadLength(50);
-  EXPECT_EQ(ret.first, 50);
-  EXPECT_FALSE(ret.second);
-  frame_source->Send("ninebyte1", ret.first);
-
-  ret = frame_source->SelectPayloadLength(50);
-  EXPECT_EQ(ret.first, 50);
-  EXPECT_FALSE(ret.second);
-  frame_source->Send("ninebyte2", ret.first);
-
-  ret = frame_source->SelectPayloadLength(50);
-  EXPECT_EQ(ret.first, 44);
-  EXPECT_TRUE(ret.second);
-  frame_source->Send("ninebyte3", ret.first);
-
-  EXPECT_EQ(result,
-            "ninebyte1<html><head><title>Example Page!</title></head><bo"
-            "ninebyte2dy><div><span><table><tr><th><blink>Wow!!</blink><"
-            "ninebyte3/th></tr></table></span></div></body></html>");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/oghttp2_adapter.cc b/http2/adapter/oghttp2_adapter.cc
deleted file mode 100644
index 3847ef8..0000000
--- a/http2/adapter/oghttp2_adapter.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "http2/adapter/oghttp2_adapter.h"
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "http2/adapter/http2_util.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-
-namespace {
-
-using spdy::SpdyGoAwayIR;
-using spdy::SpdyPingIR;
-using spdy::SpdyPriorityIR;
-using spdy::SpdyWindowUpdateIR;
-
-}  // namespace
-
-/* static */
-std::unique_ptr<OgHttp2Adapter> OgHttp2Adapter::Create(
-    Http2VisitorInterface& visitor,
-    Options options) {
-  // Using `new` to access a non-public constructor.
-  return absl::WrapUnique(new OgHttp2Adapter(visitor, std::move(options)));
-}
-
-OgHttp2Adapter::~OgHttp2Adapter() {}
-
-bool OgHttp2Adapter::IsServerSession() const {
-  return session_->IsServerSession();
-}
-
-int64_t OgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
-  return session_->ProcessBytes(bytes);
-}
-
-void OgHttp2Adapter::SubmitSettings(absl::Span<const Http2Setting> settings) {
-  session_->SubmitSettings(settings);
-}
-
-void OgHttp2Adapter::SubmitPriorityForStream(Http2StreamId stream_id,
-                                             Http2StreamId parent_stream_id,
-                                             int weight,
-                                             bool exclusive) {
-  session_->EnqueueFrame(absl::make_unique<SpdyPriorityIR>(
-      stream_id, parent_stream_id, weight, exclusive));
-}
-
-void OgHttp2Adapter::SubmitPing(Http2PingId ping_id) {
-  session_->EnqueueFrame(absl::make_unique<SpdyPingIR>(ping_id));
-}
-
-void OgHttp2Adapter::SubmitShutdownNotice() {
-  session_->StartGracefulShutdown();
-}
-
-void OgHttp2Adapter::SubmitGoAway(Http2StreamId last_accepted_stream_id,
-                                  Http2ErrorCode error_code,
-                                  absl::string_view opaque_data) {
-  session_->EnqueueFrame(absl::make_unique<SpdyGoAwayIR>(
-      last_accepted_stream_id, TranslateErrorCode(error_code),
-      std::string(opaque_data)));
-}
-void OgHttp2Adapter::SubmitWindowUpdate(Http2StreamId stream_id,
-                                        int window_increment) {
-  session_->EnqueueFrame(
-      absl::make_unique<SpdyWindowUpdateIR>(stream_id, window_increment));
-}
-
-void OgHttp2Adapter::SubmitMetadata(Http2StreamId stream_id,
-                                    size_t /* max_frame_size */,
-                                    std::unique_ptr<MetadataSource> source) {
-  // Not necessary to pass max_frame_size along, since OgHttp2Session tracks the
-  // peer's advertised max frame size.
-  session_->SubmitMetadata(stream_id, std::move(source));
-}
-
-int OgHttp2Adapter::Send() { return session_->Send(); }
-
-int OgHttp2Adapter::GetSendWindowSize() const {
-  return session_->GetRemoteWindowSize();
-}
-
-int OgHttp2Adapter::GetStreamSendWindowSize(Http2StreamId stream_id) const {
-  return session_->GetStreamSendWindowSize(stream_id);
-}
-
-int OgHttp2Adapter::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
-  return session_->GetStreamReceiveWindowLimit(stream_id);
-}
-
-int OgHttp2Adapter::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
-  return session_->GetStreamReceiveWindowSize(stream_id);
-}
-
-int OgHttp2Adapter::GetReceiveWindowSize() const {
-  return session_->GetReceiveWindowSize();
-}
-
-int OgHttp2Adapter::GetHpackEncoderDynamicTableSize() const {
-  return session_->GetHpackEncoderDynamicTableSize();
-}
-
-int OgHttp2Adapter::GetHpackEncoderDynamicTableCapacity() const {
-  return session_->GetHpackEncoderDynamicTableCapacity();
-}
-
-int OgHttp2Adapter::GetHpackDecoderDynamicTableSize() const {
-  return session_->GetHpackDecoderDynamicTableSize();
-}
-
-int OgHttp2Adapter::GetHpackDecoderSizeLimit() const {
-  return session_->GetHpackDecoderSizeLimit();
-}
-
-Http2StreamId OgHttp2Adapter::GetHighestReceivedStreamId() const {
-  return session_->GetHighestReceivedStreamId();
-}
-
-void OgHttp2Adapter::MarkDataConsumedForStream(Http2StreamId stream_id,
-                                               size_t num_bytes) {
-  session_->Consume(stream_id, num_bytes);
-}
-
-void OgHttp2Adapter::SubmitRst(Http2StreamId stream_id,
-                               Http2ErrorCode error_code) {
-  session_->EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-      stream_id, TranslateErrorCode(error_code)));
-}
-
-int32_t OgHttp2Adapter::SubmitRequest(
-    absl::Span<const Header> headers,
-    std::unique_ptr<DataFrameSource> data_source, void* user_data) {
-  return session_->SubmitRequest(headers, std::move(data_source), user_data);
-}
-
-int OgHttp2Adapter::SubmitResponse(
-    Http2StreamId stream_id, absl::Span<const Header> headers,
-    std::unique_ptr<DataFrameSource> data_source) {
-  return session_->SubmitResponse(stream_id, headers, std::move(data_source));
-}
-
-int OgHttp2Adapter::SubmitTrailer(Http2StreamId stream_id,
-                                  absl::Span<const Header> trailers) {
-  return session_->SubmitTrailer(stream_id, trailers);
-}
-
-void OgHttp2Adapter::SetStreamUserData(Http2StreamId stream_id,
-                                       void* user_data) {
-  session_->SetStreamUserData(stream_id, user_data);
-}
-
-void* OgHttp2Adapter::GetStreamUserData(Http2StreamId stream_id) {
-  return session_->GetStreamUserData(stream_id);
-}
-
-bool OgHttp2Adapter::ResumeStream(Http2StreamId stream_id) {
-  return session_->ResumeStream(stream_id);
-}
-
-OgHttp2Adapter::OgHttp2Adapter(Http2VisitorInterface& visitor, Options options)
-    : Http2Adapter(visitor),
-      session_(absl::make_unique<OgHttp2Session>(visitor, std::move(options))) {
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/oghttp2_adapter.h b/http2/adapter/oghttp2_adapter.h
deleted file mode 100644
index d30ed19..0000000
--- a/http2/adapter/oghttp2_adapter.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_ADAPTER_H_
-#define QUICHE_HTTP2_ADAPTER_OGHTTP2_ADAPTER_H_
-
-#include <cstdint>
-#include <memory>
-
-#include "http2/adapter/http2_adapter.h"
-#include "http2/adapter/http2_session.h"
-#include "http2/adapter/oghttp2_session.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-class QUICHE_EXPORT_PRIVATE OgHttp2Adapter : public Http2Adapter {
- public:
-  using Options = OgHttp2Session::Options;
-  static std::unique_ptr<OgHttp2Adapter> Create(Http2VisitorInterface& visitor,
-                                                Options options);
-
-  ~OgHttp2Adapter() override;
-
-  // From Http2Adapter.
-  bool IsServerSession() const override;
-  bool want_read() const override { return session_->want_read(); }
-  bool want_write() const override { return session_->want_write(); }
-  int64_t ProcessBytes(absl::string_view bytes) override;
-  void SubmitSettings(absl::Span<const Http2Setting> settings) override;
-  void SubmitPriorityForStream(Http2StreamId stream_id,
-                               Http2StreamId parent_stream_id,
-                               int weight,
-                               bool exclusive) override;
-  void SubmitPing(Http2PingId ping_id) override;
-  void SubmitShutdownNotice() override;
-  void SubmitGoAway(Http2StreamId last_accepted_stream_id,
-                    Http2ErrorCode error_code,
-                    absl::string_view opaque_data) override;
-  void SubmitWindowUpdate(Http2StreamId stream_id,
-                          int window_increment) override;
-  void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
-                      std::unique_ptr<MetadataSource> source) override;
-  int Send() override;
-  int GetSendWindowSize() const override;
-  int GetStreamSendWindowSize(Http2StreamId stream_id) const override;
-  int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const override;
-  int GetStreamReceiveWindowSize(Http2StreamId stream_id) const override;
-  int GetReceiveWindowSize() const override;
-  int GetHpackEncoderDynamicTableSize() const override;
-  int GetHpackEncoderDynamicTableCapacity() const;
-  int GetHpackDecoderDynamicTableSize() const override;
-  int GetHpackDecoderSizeLimit() const;
-  Http2StreamId GetHighestReceivedStreamId() const override;
-  void MarkDataConsumedForStream(Http2StreamId stream_id,
-                                 size_t num_bytes) override;
-  void SubmitRst(Http2StreamId stream_id, Http2ErrorCode error_code) override;
-  int32_t SubmitRequest(absl::Span<const Header> headers,
-                        std::unique_ptr<DataFrameSource> data_source,
-                        void* user_data) override;
-  int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
-                     std::unique_ptr<DataFrameSource> data_source) override;
-
-  int SubmitTrailer(Http2StreamId stream_id,
-                    absl::Span<const Header> trailers) override;
-
-  void SetStreamUserData(Http2StreamId stream_id, void* user_data) override;
-  void* GetStreamUserData(Http2StreamId stream_id) override;
-  bool ResumeStream(Http2StreamId stream_id) override;
-
- private:
-  OgHttp2Adapter(Http2VisitorInterface& visitor, Options options);
-
-  std::unique_ptr<OgHttp2Session> session_;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_ADAPTER_H_
diff --git a/http2/adapter/oghttp2_adapter_test.cc b/http2/adapter/oghttp2_adapter_test.cc
deleted file mode 100644
index fd572d9..0000000
--- a/http2/adapter/oghttp2_adapter_test.cc
+++ /dev/null
@@ -1,6781 +0,0 @@
-#include "http2/adapter/oghttp2_adapter.h"
-
-#include <string>
-
-#include "absl/strings/str_join.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/mock_http2_visitor.h"
-#include "http2/adapter/oghttp2_util.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using ConnectionError = Http2VisitorInterface::ConnectionError;
-
-using spdy::SpdyFrameType;
-using testing::_;
-
-enum FrameType {
-  DATA,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-  CONTINUATION,
-};
-
-// TODO(birenroy): replace numeric flag values with named constants
-enum FrameFlag {
-  END_STREAM = 0x01,
-  ACK = END_STREAM,
-  END_HEADERS = 0x04,
-};
-
-TEST(OgHttp2AdapterTest, IsServerSession) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_TRUE(adapter->IsServerSession());
-}
-
-TEST(OgHttp2AdapterTest, ProcessBytes) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence seq;
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, 4, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, 6, 0));
-  EXPECT_CALL(visitor, OnPing(17, false));
-  adapter->ProcessBytes(
-      TestFrameSequence().ClientPreface().Ping(17).Serialize());
-}
-
-TEST(OgHttp2AdapterTest, InitialSettingsNoExtendedConnect) {
-  DataSavingVisitor client_visitor;
-  OgHttp2Adapter::Options client_options{.perspective = Perspective::kClient,
-                                         .max_header_list_bytes = 42,
-                                         .allow_extended_connect = false};
-  auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
-
-  DataSavingVisitor server_visitor;
-  OgHttp2Adapter::Options server_options{.perspective = Perspective::kServer,
-                                         .allow_extended_connect = false};
-  auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
-
-  testing::InSequence s;
-
-  // Client sends the connection preface, including the initial SETTINGS.
-  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, 12, 0x0));
-  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, 12, 0x0, 0));
-  {
-    int result = client_adapter->Send();
-    EXPECT_EQ(0, result);
-    absl::string_view data = client_visitor.data();
-    EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-    data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-  }
-
-  // Server sends the connection preface, including the initial SETTINGS.
-  EXPECT_CALL(server_visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
-  EXPECT_CALL(server_visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
-  {
-    int result = server_adapter->Send();
-    EXPECT_EQ(0, result);
-    absl::string_view data = server_visitor.data();
-    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-  }
-
-  // Client processes the server's initial bytes, including initial SETTINGS.
-  EXPECT_CALL(client_visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
-  EXPECT_CALL(client_visitor, OnSettingsStart());
-  EXPECT_CALL(client_visitor, OnSettingsEnd());
-  {
-    const int64_t result = client_adapter->ProcessBytes(server_visitor.data());
-    EXPECT_EQ(server_visitor.data().size(), static_cast<size_t>(result));
-  }
-
-  // Server processes the client's initial bytes, including initial SETTINGS.
-  EXPECT_CALL(server_visitor, OnFrameHeader(0, 12, SETTINGS, 0x0));
-  EXPECT_CALL(server_visitor, OnSettingsStart());
-  EXPECT_CALL(server_visitor,
-              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
-  EXPECT_CALL(
-      server_visitor,
-      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}));
-  EXPECT_CALL(server_visitor, OnSettingsEnd());
-  {
-    const int64_t result = server_adapter->ProcessBytes(client_visitor.data());
-    EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
-  }
-}
-
-TEST(OgHttp2AdapterTest, InitialSettings) {
-  DataSavingVisitor client_visitor;
-  OgHttp2Adapter::Options client_options{.perspective = Perspective::kClient,
-                                         .max_header_list_bytes = 42};
-  ASSERT_TRUE(client_options.allow_extended_connect);
-  auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
-
-  DataSavingVisitor server_visitor;
-  OgHttp2Adapter::Options server_options{.perspective = Perspective::kServer};
-  ASSERT_TRUE(server_options.allow_extended_connect);
-  auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
-
-  testing::InSequence s;
-
-  // Client sends the connection preface, including the initial SETTINGS.
-  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, 12, 0x0));
-  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, 12, 0x0, 0));
-  {
-    int result = client_adapter->Send();
-    EXPECT_EQ(0, result);
-    absl::string_view data = client_visitor.data();
-    EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-    data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-  }
-
-  // Server sends the connection preface, including the initial SETTINGS.
-  EXPECT_CALL(server_visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(server_visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  {
-    int result = server_adapter->Send();
-    EXPECT_EQ(0, result);
-    absl::string_view data = server_visitor.data();
-    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-  }
-
-  // Client processes the server's initial bytes, including initial SETTINGS.
-  EXPECT_CALL(client_visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
-  EXPECT_CALL(client_visitor, OnSettingsStart());
-  EXPECT_CALL(client_visitor,
-              OnSetting(Http2Setting{
-                  Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u}));
-  EXPECT_CALL(client_visitor, OnSettingsEnd());
-  {
-    const int64_t result = client_adapter->ProcessBytes(server_visitor.data());
-    EXPECT_EQ(server_visitor.data().size(), static_cast<size_t>(result));
-  }
-
-  // Server processes the client's initial bytes, including initial SETTINGS.
-  EXPECT_CALL(server_visitor, OnFrameHeader(0, 12, SETTINGS, 0x0));
-  EXPECT_CALL(server_visitor, OnSettingsStart());
-  EXPECT_CALL(server_visitor,
-              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
-  EXPECT_CALL(
-      server_visitor,
-      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}));
-  EXPECT_CALL(server_visitor, OnSettingsEnd());
-  {
-    const int64_t result = server_adapter->ProcessBytes(client_visitor.data());
-    EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
-  }
-}
-
-TEST(OgHttp2AdapterTest, AutomaticSettingsAndPingAcks) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().Ping(42).Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // PING
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  // PING ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::PING}));
-}
-
-TEST(OgHttp2AdapterTest, AutomaticPingAcksDisabled) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .auto_ping_ack = false};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().Ping(42).Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // PING
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  // No PING ack expected because automatic PING acks are disabled.
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandles100Headers) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}},
-                   /*fin=*/false)
-          .Ping(101)
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(101, false));
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
-}
-
-TEST(OgHttp2AdapterTest, QueuingWindowUpdateAffectsWindow) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_EQ(adapter->GetReceiveWindowSize(), kInitialFlowControlWindowSize);
-  adapter->SubmitWindowUpdate(0, 10000);
-  EXPECT_EQ(adapter->GetReceiveWindowSize(),
-            kInitialFlowControlWindowSize + 10000);
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
-            kInitialFlowControlWindowSize);
-  adapter->SubmitWindowUpdate(1, 20000);
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
-            kInitialFlowControlWindowSize + 20000);
-}
-
-TEST(OgHttp2AdapterTest, AckOfSettingInitialWindowSizeAffectsWindow) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id1 = adapter->SubmitRequest(headers, nullptr, nullptr);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .SettingsAck()  // Ack of the client's initial settings.
-          .Serialize();
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  int64_t parse_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(parse_result));
-
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
-            kInitialFlowControlWindowSize);
-  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000u}});
-  // No update for the first stream, yet.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
-            kInitialFlowControlWindowSize);
-
-  // Ack of server's initial settings.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  // Outbound SETTINGS containing INITIAL_WINDOW_SIZE.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  // Still no update, as a SETTINGS ack has not yet been received.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
-            kInitialFlowControlWindowSize);
-
-  const std::string settings_ack =
-      TestFrameSequence().SettingsAck().Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  parse_result = adapter->ProcessBytes(settings_ack);
-  EXPECT_EQ(settings_ack.size(), static_cast<size_t>(parse_result));
-
-  // Stream window has been updated.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1), 80000);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-  const int32_t stream_id2 = adapter->SubmitRequest(headers, nullptr, nullptr);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id2), 80000);
-}
-
-TEST(OgHttp2AdapterTest, ClientRejects100HeadersWithFin) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}}, /*fin=*/false)
-          .Headers(1, {{":status", "100"}}, /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientRejects100HeadersWithContent) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}},
-                   /*fin=*/false)
-          .Data(1, "We needed the final headers before data, whoops")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientRejects100HeadersWithContentLength) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "100"}, {"content-length", "42"}},
-                   /*fin=*/false)
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandles204WithContent) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
-  ASSERT_GT(stream_id2, stream_id1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "204"}, {"content-length", "2"}},
-                   /*fin=*/false)
-          .Data(1, "hi")
-          .Headers(3, {{":status", "204"}}, /*fin=*/false)
-          .Data(3, "hi")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "204"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":status", "204"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(3, 2));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandles304WithContent) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
-                   /*fin=*/false)
-          .Data(1, "hi")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandles304WithContentLength) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesTrailers) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Headers(1, {{"final-status", "A-OK"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "final-status", "A-OK"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientSendsTrailers) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const std::string kBody = "This is an example request body.";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::DATA}));
-  visitor.Clear();
-
-  const std::vector<Header> trailers1 =
-      ToHeaders({{"extra-info", "Trailers are weird but good?"}});
-  adapter->SubmitTrailer(stream_id1, trailers1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  data = visitor.data();
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesMetadata) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Metadata(0, "Example connection metadata")
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(1, "Example stream metadata")
-          .Data(1, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesMetadataWithEmptyPayload) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(1, "")
-          .Data(1, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(3);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesMetadataWithPayloadError) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Metadata(0, "Example connection metadata")
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(stream_id, "Example stream metadata")
-          .Data(stream_id, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, _, _)).Times(3);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(stream_id, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(stream_id, _))
-      .WillOnce(testing::Return(false));
-  // Remaining frames are not processed due to the error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  // Negative integer returned to indicate an error.
-  EXPECT_LT(stream_result, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  EXPECT_FALSE(adapter->want_read());
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesMetadataWithCompletionError) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Metadata(0, "Example connection metadata")
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Metadata(stream_id, "Example stream metadata")
-          .Data(stream_id, "This is the response body.", true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, _, _)).Times(3);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(stream_id, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(stream_id, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(stream_id))
-      .WillOnce(testing::Return(false));
-  // Remaining frames are not processed due to the error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  // Negative integer returned to indicate an error.
-  EXPECT_LT(stream_result, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  EXPECT_FALSE(adapter->want_read());
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientRstStreamWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
-      .WillOnce(testing::DoAll(
-          testing::InvokeWithoutArgs([&adapter]() {
-            adapter->SubmitRst(1, Http2ErrorCode::REFUSED_STREAM);
-          }),
-          testing::Return(Http2VisitorInterface::HEADER_RST_STREAM)));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, stream_id1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
-      .WillOnce(
-          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_LT(stream_result, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeadersOnly) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
-      .WillOnce(
-          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_LT(stream_result, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientRejectsHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1))
-      .WillOnce(testing::Return(false));
-  // Rejecting headers leads to a connection error.
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_LT(stream_result, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesSmallerHpackHeaderTableSetting) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 = ToHeaders({
-      {":method", "GET"},
-      {":scheme", "http"},
-      {":authority", "example.com"},
-      {":path", "/this/is/request/one"},
-      {"x-i-do-not-like", "green eggs and ham"},
-      {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
-      {"x-like-them-in-a-house", "no"},
-      {"x-like-them-with-a-mouse", "no"},
-  });
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 100);
-
-  const std::string stream_frames =
-      TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 100u}}).Serialize();
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 100);
-  EXPECT_LE(adapter->GetHpackEncoderDynamicTableSize(), 100);
-}
-
-TEST(OgHttp2AdapterTest, ClientHandlesLargerHpackHeaderTableSetting) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 4096);
-
-  const std::string stream_frames =
-      TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 40960u}}).Serialize();
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 40960u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  // The increased capacity will not be applied until a SETTINGS ack is
-  // serialized.
-  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 4096);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 40960);
-}
-
-TEST(OgHttp2AdapterTest, ClientSendsHpackHeaderTableSetting) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 = ToHeaders({
-      {":method", "GET"},
-      {":scheme", "http"},
-      {":authority", "example.com"},
-      {":path", "/this/is/request/one"},
-  });
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .SettingsAck()
-          .Headers(
-              1,
-              {{":status", "200"},
-               {"server", "my-fake-server"},
-               {"date", "Tue, 6 Apr 2021 12:54:01 GMT"},
-               {"x-i-do-not-like", "green eggs and ham"},
-               {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
-               {"x-like-them-in-a-house", "no"},
-               {"x-like-them-with-a-mouse", "no"}},
-              /*fin=*/true)
-          .Serialize();
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Server acks client's initial SETTINGS.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(7);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
-
-  // Submit settings, check decoder table size.
-  adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
-  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
-
-  // Server preface SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  // SETTINGS with the new header table size value
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  // Because the client has not yet seen an ack from the server for the SETTINGS
-  // with header table size, it has not applied the new value.
-  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::vector<Header> headers2 = ToHeaders({
-      {":method", "GET"},
-      {":scheme", "http"},
-      {":authority", "example.com"},
-      {":path", "/this/is/request/two"},
-  });
-
-  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
-  ASSERT_GT(stream_id2, stream_id1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string response_frames =
-      TestFrameSequence()
-          .Headers(stream_id2,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id2, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id2));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id2, _, _)).Times(3);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id2));
-  EXPECT_CALL(visitor, OnEndStream(stream_id2));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id2, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  const int64_t response_result = adapter->ProcessBytes(response_frames);
-  EXPECT_EQ(response_frames.size(), static_cast<size_t>(response_result));
-
-  // Still no ack for the outbound settings.
-  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
-
-  const std::string settings_ack =
-      TestFrameSequence().SettingsAck().Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-
-  const int64_t ack_result = adapter->ProcessBytes(settings_ack);
-  EXPECT_EQ(settings_ack.size(), static_cast<size_t>(ack_result));
-  // Ack has finally arrived.
-  EXPECT_EQ(adapter->GetHpackDecoderSizeLimit(), 100);
-}
-
-// TODO(birenroy): Validate headers and re-enable this test. The library should
-// invoke OnErrorDebug() with an error message for the invalid header. The
-// library should also invoke OnInvalidFrame() for the invalid HEADERS frame.
-TEST(OgHttp2AdapterTest, DISABLED_ClientHandlesInvalidTrailers) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.")
-          .Headers(1, {{":bad-status", "9000"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-
-  // Bad status trailer will cause a PROTOCOL_ERROR. The header is never
-  // delivered in an OnHeaderForStream callback.
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id1, 4, 0x0, 1));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientStartsShutdown) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  // No-op (except for logging) for a client implementation.
-  adapter->SubmitShutdownNotice();
-  EXPECT_FALSE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientReceivesGoAway) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
-  ASSERT_GT(stream_id2, stream_id1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
-          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
-          .WindowUpdate(0, 42)
-          .WindowUpdate(1, 42)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
-  // Currently, oghttp2 does not pass the opaque data to the visitor.
-  EXPECT_CALL(visitor, OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, ""));
-  // TODO(b/228093860): Close stream IDs above the GOAWAY's last_stream_id.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 42));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientFailsOnGoAway) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
-  ASSERT_GT(stream_id1, 0);
-  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
-          .Data(1, "This is the response body.")
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
-  // TODO(birenroy): Pass the GOAWAY opaque data through the oghttp2 stack.
-  EXPECT_CALL(visitor, OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, ""))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_LT(stream_result, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientRejects101Response) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"},
-                 {"upgrade", "new-protocol"}});
-
-  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1,
-                   {{":status", "101"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(static_cast<int64_t>(stream_frames.size()), stream_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                  static_cast<uint32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
-                                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ClientObeysMaxConcurrentStreams) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  // Even though the user has not queued any frames for the session, it should
-  // still send the connection preface.
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  // Initial SETTINGS.
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ServerPreface({{.id = MAX_CONCURRENT_STREAMS, .value = 1}})
-          .Serialize();
-  testing::InSequence s;
-
-  // Server preface (SETTINGS with MAX_CONCURRENT_STREAMS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting);
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  const std::string kBody = "This is an example request body.";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-  const int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  const int next_stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/two"}}),
-                             nullptr, nullptr);
-
-  // A new pending stream is created, but because of MAX_CONCURRENT_STREAMS, the
-  // session should not want to write it at the moment.
-  EXPECT_GT(next_stream_id, stream_id);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(stream_id, "This is the response body.", /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(stream_id, "server", "my-fake-server"));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
-                                         "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0x1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
-  EXPECT_CALL(visitor,
-              OnDataForStream(stream_id, "This is the response body."));
-  EXPECT_CALL(visitor, OnEndStream(stream_id));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  // The first stream should close, which should make the session want to write
-  // the next stream.
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, next_stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, next_stream_id, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, ClientReceivesInitialWindowSetting) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .Settings({{INITIAL_WINDOW_SIZE, 80000u}})
-          .WindowUpdate(0, 65536)
-          .Serialize();
-  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int64_t result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  const std::string kLongBody = std::string(81000, 'c');
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kLongBody);
-  body1->EndData();
-  const int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  // The client can send more than 4 frames (65536 bytes) of data.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(4);
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14464, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA, SpdyFrameType::DATA}));
-}
-
-TEST(OgHttp2AdapterTest, ClientReceivesInitialWindowSettingAfterStreamStart) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().WindowUpdate(0, 65536).Serialize();
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a SETTINGS ack.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int64_t result = adapter->Send();
-  EXPECT_EQ(0, result);
-  visitor.Clear();
-
-  const std::string kLongBody = std::string(81000, 'c');
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload(kLongBody);
-  body1->EndData();
-  const int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             std::move(body1), nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  // The client can only send 65535 bytes of data, as the stream window has not
-  // yet been increased.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(3);
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16383, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA, SpdyFrameType::DATA,
-                            SpdyFrameType::DATA}));
-  visitor.Clear();
-
-  // Can't write any more due to flow control.
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string settings_frame =
-      TestFrameSequence().Settings({{INITIAL_WINDOW_SIZE, 80000u}}).Serialize();
-  // SETTINGS with INITIAL_STREAM_WINDOW
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t settings_result = adapter->ProcessBytes(settings_frame);
-  EXPECT_EQ(settings_frame.size(), static_cast<size_t>(settings_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  // The client can write more after receiving the INITIAL_WINDOW_SIZE setting.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14465, 0x0, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::DATA}));
-}
-
-TEST(OgHttp2AdapterTest, InvalidInitialWindowSetting) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const uint32_t kTooLargeInitialWindow = 1u << 31;
-  const std::string initial_frames =
-      TestFrameSequence()
-          .Settings({{INITIAL_WINDOW_SIZE, kTooLargeInitialWindow}})
-          .Serialize();
-  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  0, Http2VisitorInterface::InvalidFrameError::kFlowControl));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a GOAWAY.
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  int64_t result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-  visitor.Clear();
-}
-
-TEST(OggHttp2AdapterClientTest, InitialWindowSettingCausesOverflow) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-  int64_t write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const uint32_t kLargeInitialWindow = (1u << 31) - 1;
-  const std::string frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(stream_id, {{":status", "200"}}, /*fin=*/false)
-          .WindowUpdate(stream_id, 65536u)
-          .Settings({{INITIAL_WINDOW_SIZE, kLargeInitialWindow}})
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 4, WINDOW_UPDATE, 0x0));
-  EXPECT_CALL(visitor, OnWindowUpdate(stream_id, 65536));
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE,
-                                              kLargeInitialWindow}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  // The stream window update plus the SETTINGS frame with INITIAL_WINDOW_SIZE
-  // pushes the stream's flow control window outside of the acceptable range.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, 4, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(RST_STREAM, stream_id, 4, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, FailureSendingConnectionPreface) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  visitor.set_has_write_error();
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
-
-  int result = adapter->Send();
-  EXPECT_LT(result, 0);
-}
-
-TEST(OgHttp2AdapterTest, MaxFrameSizeSettingNotAppliedBeforeAck) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
-  const int32_t stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
-                                        {":scheme", "https"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             /*data_source=*/nullptr, /*user_data=*/nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  testing::InSequence s;
-
-  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string server_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .Headers(1, {{":status", "200"}}, /*fin=*/false)
-          .Data(1, std::string(large_frame_size, 'a'))
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Response HEADERS. Because the SETTINGS with MAX_FRAME_SIZE was not
-  // acknowledged, the large DATA is treated as a connection error. Note that
-  // oghttp2 delivers the DATA frame header and connection error events.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t process_result = adapter->ProcessBytes(server_frames);
-  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::FRAME_SIZE_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, MaxFrameSizeSettingAppliedAfterAck) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
-  const int32_t stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
-                                        {":scheme", "https"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             /*data_source=*/nullptr, /*user_data=*/nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  testing::InSequence s;
-
-  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string server_frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .SettingsAck()
-          .Headers(1, {{":status", "200"}}, /*fin=*/false)
-          .Data(1, std::string(large_frame_size, 'a'))
-          .Serialize();
-
-  // Server preface (empty SETTINGS) and ack of SETTINGS.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-
-  // Response HEADERS and DATA. Because the SETTINGS with MAX_FRAME_SIZE was
-  // acknowledged, the large DATA is accepted without any error.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, large_frame_size));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-
-  const int64_t process_result = adapter->ProcessBytes(server_frames);
-  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
-
-  // Client ack of SETTINGS.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ClientForbidsPushPromise) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-
-  visitor.Clear();
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-  write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::vector<Header> push_headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/push"}});
-  const std::string frames = TestFrameSequence()
-                                 .ServerPreface()
-                                 .SettingsAck()
-                                 .PushPromise(stream_id, 2, push_headers)
-                                 .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // SETTINGS ack (to acknowledge PUSH_ENABLED=0, though this is not explicitly
-  // required for OgHttp2: should it be?)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  // The PUSH_PROMISE is treated as an invalid frame.
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, PUSH_PROMISE, _));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidPushPromise));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientForbidsPushStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-
-  visitor.Clear();
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  ASSERT_GT(stream_id, 0);
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-  write_result = adapter->Send();
-  EXPECT_EQ(0, write_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string frames =
-      TestFrameSequence()
-          .ServerPreface()
-          .SettingsAck()
-          .Headers(2,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // SETTINGS ack (to acknowledge PUSH_ENABLED=0, though this is not explicitly
-  // required for OgHttp2: should it be?)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck);
-
-  // The push HEADERS are invalid.
-  EXPECT_CALL(visitor, OnFrameHeader(2, _, HEADERS, _));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidNewStreamId));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientReceivesDataOnClosedStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view data = visitor.data();
-  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Client SETTINGS ack
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Let the client open a stream with a request.
-  int stream_id =
-      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
-                                        {":scheme", "http"},
-                                        {":authority", "example.com"},
-                                        {":path", "/this/is/request/one"}}),
-                             nullptr, nullptr);
-  EXPECT_GT(stream_id, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  // Let the client RST_STREAM the stream it opened.
-  adapter->SubmitRst(stream_id, Http2ErrorCode::CANCEL);
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id, _, 0x0,
-                                   static_cast<int>(Http2ErrorCode::CANCEL)));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
-  visitor.Clear();
-
-  // Let the server send a response on the stream. (It might not have received
-  // the RST_STREAM yet.)
-  const std::string response_frames =
-      TestFrameSequence()
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(stream_id, "This is the response body.", /*fin=*/true)
-          .Serialize();
-
-  // The visitor gets notified about the HEADERS frame and DATA frame for the
-  // closed stream with no further processing on either frame.
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, DATA, 0x1));
-
-  const int64_t response_result = adapter->ProcessBytes(response_frames);
-  EXPECT_EQ(response_frames.size(), static_cast<size_t>(response_result));
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, ClientEncountersFlowControlBlock) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const std::string kBody = std::string(100 * 1024, 'a');
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  auto body2 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body2->AppendPayload(kBody);
-  body2->EndData();
-
-  const int32_t stream_id2 =
-      adapter->SubmitRequest(headers2, std::move(body2), nullptr);
-  ASSERT_GT(stream_id2, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x4, 0));
-  // 4 DATA frames should saturate the default 64kB stream/connection flow
-  // control window.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0)).Times(4);
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_EQ(0, adapter->GetSendWindowSize());
-
-  const std::string stream_frames = TestFrameSequence()
-                                        .ServerPreface()
-                                        .WindowUpdate(0, 80000)
-                                        .WindowUpdate(stream_id1, 20000)
-                                        .Serialize();
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 80000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(1, 20000));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id2, _, 0x0, 0))
-      .Times(testing::AtLeast(1));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0))
-      .Times(testing::AtLeast(1));
-
-  EXPECT_TRUE(adapter->want_write());
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-}
-
-TEST(OgHttp2AdapterTest, ClientSendsTrailersAfterFlowControlBlock) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload("Really small body.");
-  body1->EndData();
-
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  const std::vector<Header> headers2 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/two"}});
-
-  const std::string kBody = std::string(100 * 1024, 'a');
-  auto body2 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body2->AppendPayload(kBody);
-  body2->EndData();
-
-  const int32_t stream_id2 =
-      adapter->SubmitRequest(headers2, std::move(body2), nullptr);
-  ASSERT_GT(stream_id2, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0)).Times(1);
-  // 4 DATA frames should saturate the default 64kB stream/connection flow
-  // control window.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id2, _, 0x0, 0)).Times(4);
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_FALSE(adapter->want_write());
-  EXPECT_EQ(0, adapter->GetSendWindowSize());
-
-  const std::vector<Header> trailers1 =
-      ToHeaders({{"extra-info", "Trailers are weird but good?"}});
-  adapter->SubmitTrailer(stream_id1, trailers1);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-}
-
-TEST(OgHttp2AdapterTest, ClientSendsMetadataAfterFlowControlBlock) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}});
-
-  const std::string kBody = std::string(100 * 1024, 'a');
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-
-  const int32_t stream_id1 =
-      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
-  // 4 DATA frames should saturate the default 64kB stream/connection flow
-  // control window.
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0)).Times(4);
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_FALSE(adapter->want_write());
-  EXPECT_EQ(0, adapter->GetSendWindowSize());
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
-
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-}
-
-TEST(OgHttp2AdapterTest, ClientQueuesRequests) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  adapter->Send();
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ServerPreface({{MAX_CONCURRENT_STREAMS, 2}})
-          .SettingsAck()
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{
-                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-
-  adapter->ProcessBytes(initial_frames);
-
-  const std::vector<Header> headers =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/example/request"}});
-  std::vector<int32_t> stream_ids;
-  // Start two, which hits the limit.
-  int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-  // Start two more, which must be queued.
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[0], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[0], _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[1], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[1], _, 0x5, 0));
-
-  adapter->Send();
-
-  const std::string update_streams =
-      TestFrameSequence().Settings({{MAX_CONCURRENT_STREAMS, 5}}).Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{
-                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}));
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  adapter->ProcessBytes(update_streams);
-  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
-  stream_ids.push_back(stream_id);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[2], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[2], _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[3], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[3], _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[4], _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[4], _, 0x5, 0));
-  // Header frames should all have been sent in order, regardless of any
-  // queuing.
-
-  adapter->Send();
-}
-
-TEST(OgHttp2AdapterTest, SubmitMetadata) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS,
-                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, SubmitMetadataMultipleFrames) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const auto kLargeValue = std::string(63 * 1024, 'a');
-  auto source = absl::make_unique<TestMetadataSource>(
-      ToHeaderBlock(ToHeaders({{"large-value", kLargeValue}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-  EXPECT_TRUE(adapter->want_write());
-
-  testing::InSequence seq;
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS,
-                            static_cast<SpdyFrameType>(kMetadataFrameType),
-                            static_cast<SpdyFrameType>(kMetadataFrameType),
-                            static_cast<SpdyFrameType>(kMetadataFrameType),
-                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, SubmitConnectionMetadata) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(0, 16384u, std::move(source));
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 0, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 0, _, 0x4, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS,
-                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, GetSendWindowSize) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const int peer_window = adapter->GetSendWindowSize();
-  EXPECT_EQ(peer_window, kInitialFlowControlWindowSize);
-}
-
-TEST(OgHttp2AdapterTest, MarkDataConsumedForNonexistentStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  // Send some data on stream 1 so the connection window manager doesn't
-  // underflow later.
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "Some data on stream 1")
-                                 .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-
-  adapter->ProcessBytes(frames);
-
-  // This should not cause a crash or QUICHE_BUG.
-  adapter->MarkDataConsumedForStream(3, 11);
-}
-
-TEST(OgHttp2AdapterTest, TestSerialize) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_TRUE(adapter->want_read());
-  EXPECT_FALSE(adapter->want_write());
-
-  adapter->SubmitSettings(
-      {{HEADER_TABLE_SIZE, 128}, {MAX_FRAME_SIZE, 128 << 10}});
-  EXPECT_TRUE(adapter->want_write());
-
-  const Http2StreamId accepted_stream = 3;
-  const Http2StreamId rejected_stream = 7;
-  adapter->SubmitPriorityForStream(accepted_stream, 1, 255, true);
-  adapter->SubmitRst(rejected_stream, Http2ErrorCode::CANCEL);
-  adapter->SubmitPing(42);
-  adapter->SubmitGoAway(13, Http2ErrorCode::HTTP2_NO_ERROR, "");
-  adapter->SubmitWindowUpdate(accepted_stream, 127);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PRIORITY, accepted_stream, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(PRIORITY, accepted_stream, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, rejected_stream, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, rejected_stream, _, 0x0, 0x8));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor,
-              OnBeforeFrameSent(WINDOW_UPDATE, accepted_stream, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, accepted_stream, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PRIORITY,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::PING,
-                    SpdyFrameType::GOAWAY, SpdyFrameType::WINDOW_UPDATE}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, TestPartialSerialize) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  adapter->SubmitSettings(
-      {{HEADER_TABLE_SIZE, 128}, {MAX_FRAME_SIZE, 128 << 10}});
-  adapter->SubmitGoAway(13, Http2ErrorCode::HTTP2_NO_ERROR,
-                        "And don't come back!");
-  adapter->SubmitPing(42);
-  EXPECT_TRUE(adapter->want_write());
-
-  visitor.set_send_limit(20);
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x0, 0));
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_FALSE(adapter->want_write());
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY,
-                            SpdyFrameType::PING}));
-}
-
-TEST(OgHttp2AdapterTest, TestStreamInitialWindowSizeUpdates) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000}});
-  EXPECT_TRUE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  // New stream window size has not yet been applied.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 65535);
-
-  // Server initial SETTINGS
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  // New stream window size has still not been applied.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 65535);
-
-  const std::string ack = TestFrameSequence().SettingsAck().Serialize();
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  adapter->ProcessBytes(ack);
-
-  // New stream window size has finally been applied upon SETTINGS ack.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 80000);
-
-  // Update the stream window size again.
-  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 90000}});
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  result = adapter->Send();
-  EXPECT_EQ(0, result);
-
-  // New stream window size has not yet been applied.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 80000);
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  adapter->ProcessBytes(ack);
-
-  // New stream window size is applied after the ack.
-  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 90000);
-}
-
-TEST(OgHttp2AdapterTest, ConnectionErrorOnControlFrameSent) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().Ping(42).Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // PING
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0))
-      .WillOnce(testing::Return(-902));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
-
-  int send_result = adapter->Send();
-  EXPECT_LT(send_result, 0);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  send_result = adapter->Send();
-  EXPECT_LT(send_result, 0);
-}
-
-TEST(OgHttp2AdapterTest, ConnectionErrorOnDataFrameSent) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body->AppendPayload("Here is some data, which will lead to a fatal error");
-  TestDataFrameSource* body_ptr = body.get();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}}), std::move(body));
-  ASSERT_EQ(0, submit_result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server preface (SETTINGS)
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  // SETTINGS ack
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  // Stream 1, with doomed DATA
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0))
-      .WillOnce(testing::Return(-902));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
-
-  int send_result = adapter->Send();
-  EXPECT_LT(send_result, 0);
-
-  body_ptr->AppendPayload("After the fatal error, data will be sent no more");
-
-  EXPECT_FALSE(adapter->want_write());
-
-  send_result = adapter->Send();
-  EXPECT_LT(send_result, 0);
-}
-
-TEST(OgHttp2AdapterTest, ClientSendsContinuation) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true,
-                                          /*add_continuation=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 1));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-}
-
-TEST(OgHttp2AdapterTest, ClientSendsMetadataWithContinuation) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Metadata(0, "Example connection metadata in multiple frames", true)
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false,
-                   /*add_continuation=*/true)
-          .Metadata(1,
-                    "Some stream metadata that's also sent in multiple frames",
-                    true)
-          .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Metadata on stream 0
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 0));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
-
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  // Metadata on stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 0));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
-  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-  EXPECT_EQ("Example connection metadata in multiple frames",
-            absl::StrJoin(visitor.GetMetadata(0), ""));
-  EXPECT_EQ("Some stream metadata that's also sent in multiple frames",
-            absl::StrJoin(visitor.GetMetadata(1), ""));
-}
-
-TEST(OgHttp2AdapterTest, RepeatedHeaderNames) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "text/plain"},
-                                           {"accept", "text/html"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/plain"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/html"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  const std::vector<Header> headers1 = ToHeaders(
-      {{":status", "200"}, {"content-length", "10"}, {"content-length", "10"}});
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload("perfection");
-  body1->EndData();
-
-  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
-  ASSERT_EQ(0, submit_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 10, 0x1, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-}
-
-TEST(OgHttp2AdapterTest, ServerRespondsToRequestWithTrailers) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/one"}})
-          .Data(1, "Example data, woohoo.")
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  const std::vector<Header> headers1 = ToHeaders({{":status", "200"}});
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  TestDataFrameSource* body1_ptr = body1.get();
-
-  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
-  ASSERT_EQ(0, submit_result);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::HEADERS}));
-  visitor.Clear();
-
-  const std::string more_frames =
-      TestFrameSequence()
-          .Headers(1, {{"extra-info", "Trailers are weird but good?"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "extra-info",
-                                         "Trailers are weird but good?"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  result = adapter->ProcessBytes(more_frames);
-  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
-
-  body1_ptr->EndData();
-  EXPECT_EQ(true, adapter->ResumeStream(1));
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
-}
-
-TEST(OgHttp2AdapterTest, ServerReceivesMoreHeaderBytesThanConfigured) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .max_header_list_bytes = 42};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"},
-                    {"from-douglas-de-fermat",
-                     "I have discovered a truly marvelous answer to the life, "
-                     "the universe, and everything that the header setting is "
-                     "too narrow to contain."}},
-                   /*fin=*/true)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::COMPRESSION_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerSubmitsResponseWithDataSourceError) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->SimulateError();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  // TODO(birenroy): Send RST_STREAM INTERNAL_ERROR to the client as well.
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::HEADERS}));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  // Since the stream has been closed, it is not possible to submit trailers for
-  // the stream.
-  int trailer_result =
-      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
-  ASSERT_LT(trailer_result, 0);
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, CompleteRequestWithServerResponse) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false)
-          .Data(1, "This is the response body.", /*fin=*/true)
-          .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  int submit_result =
-      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::HEADERS}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, IncompleteRequestWithServerResponse) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  int submit_result =
-      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  // RST_STREAM NO_ERROR option is disabled.
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::HEADERS}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, IncompleteRequestWithServerResponseRstStreamEnabled) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .rst_stream_no_error_when_incomplete = true};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  int submit_result =
-      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, 4, 0x0, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                    SpdyFrameType::HEADERS, SpdyFrameType::RST_STREAM}));
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, ServerSendsInvalidTrailers) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  EXPECT_FALSE(adapter->want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  const absl::string_view kBody = "This is an example response body.";
-
-  // The body source must indicate that the end of the body is not the end of
-  // the stream.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload(kBody);
-  body1->EndData();
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
-  visitor.Clear();
-  EXPECT_FALSE(adapter->want_write());
-
-  // The body source has been exhausted by the call to Send() above.
-  int trailer_result =
-      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
-  ASSERT_EQ(trailer_result, 0);
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesDataWithPadding) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.",
-                                       /*fin=*/true, /*padding_length=*/39)
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25 + 39, DATA, 0x9));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25 + 39));
-  // Note: oghttp2 passes padding information before the actual data.
-  EXPECT_CALL(visitor, OnDataPaddingLength(1, 39));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesHostHeader) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":path", "/this/is/request/one"},
-                                           {"host", "example.com"}},
-                                          /*fin=*/true)
-                                 .Headers(3,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"host", "example.com"}},
-                                          /*fin=*/true)
-                                 .Headers(5,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "foo.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"host", "bar.com"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  visitor.Clear();
-}
-
-// Tests the case where the response body is in the progress of being sent while
-// trailers are queued.
-TEST(OgHttp2AdapterTest, ServerSubmitsTrailersWhileDataDeferred) {
-  DataSavingVisitor visitor;
-  for (const bool queue_trailers : {true, false}) {
-    OgHttp2Adapter::Options options{
-        .perspective = Perspective::kServer,
-        .trailers_require_end_data = queue_trailers};
-    auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-    const std::string frames = TestFrameSequence()
-                                   .ClientPreface()
-                                   .Headers(1,
-                                            {{":method", "POST"},
-                                             {":scheme", "https"},
-                                             {":authority", "example.com"},
-                                             {":path", "/this/is/request/one"}},
-                                            /*fin=*/false)
-                                   .WindowUpdate(1, 2000)
-                                   .Data(1, "This is the request body.")
-                                   .WindowUpdate(0, 2000)
-                                   .Serialize();
-    testing::InSequence s;
-
-    // Client preface (empty SETTINGS)
-    EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-    EXPECT_CALL(visitor, OnSettingsStart());
-    EXPECT_CALL(visitor, OnSettingsEnd());
-
-    EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-    EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-    EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-    EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-    EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-    EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
-    EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-    EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-    EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-    EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-    EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
-
-    const int64_t result = adapter->ProcessBytes(frames);
-    EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-    EXPECT_TRUE(adapter->want_write());
-
-    EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-    EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-    EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-    EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-    int send_result = adapter->Send();
-    EXPECT_EQ(0, send_result);
-    visitor.Clear();
-
-    const absl::string_view kBody = "This is an example response body.";
-
-    // The body source must indicate that the end of the body is not the end of
-    // the stream.
-    auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-    body1->AppendPayload(kBody);
-    auto* body1_ptr = body1.get();
-    int submit_result = adapter->SubmitResponse(
-        1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-        std::move(body1));
-    EXPECT_EQ(submit_result, 0);
-    EXPECT_TRUE(adapter->want_write());
-
-    EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-    EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-    EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-    send_result = adapter->Send();
-    EXPECT_EQ(0, send_result);
-    visitor.Clear();
-    EXPECT_FALSE(adapter->want_write());
-
-    int trailer_result =
-        adapter->SubmitTrailer(1, ToHeaders({{"final-status", "a-ok"}}));
-    ASSERT_EQ(trailer_result, 0);
-    if (queue_trailers) {
-      // Even though there are new trailers to write, the data source has not
-      // finished writing data and is blocked.
-      EXPECT_FALSE(adapter->want_write());
-
-      body1_ptr->EndData();
-      adapter->ResumeStream(1);
-      EXPECT_TRUE(adapter->want_write());
-
-      EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-      EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-
-      send_result = adapter->Send();
-      EXPECT_EQ(0, send_result);
-    } else {
-      // Even though the data source has not finished sending data, the library
-      // will write the trailers anyway.
-      EXPECT_TRUE(adapter->want_write());
-
-      EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-      EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-
-      send_result = adapter->Send();
-      EXPECT_EQ(0, send_result);
-      EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-    }
-  }
-}
-
-TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControl) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 // 70000 bytes of data
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(16384, 'a'))
-                                 .Data(1, std::string(4464, 'a'))
-                                 .Serialize();
-
-  testing::InSequence s;
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
-  // No further frame data or headers are delivered.
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControlWithOneDataFrame) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  // Allow the client to send a DATA frame that exceeds the connection flow
-  // control window.
-  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "POST"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  int64_t process_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Outbound SETTINGS containing MAX_FRAME_SIZE.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  // Ack of client's initial settings.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
-  // overflow the connection-level window. The result should be a GOAWAY.
-  const std::string overflow_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Data(1, std::string(window_overflow_bytes, 'a'))
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
-  // No further frame data is delivered.
-
-  process_result = adapter->ProcessBytes(overflow_frames);
-  EXPECT_EQ(overflow_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControlAcrossReads) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  // Allow the client to send a DATA frame that exceeds the connection flow
-  // control window.
-  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
-  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "POST"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/false)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  int64_t process_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Outbound SETTINGS containing MAX_FRAME_SIZE.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  // Ack of client's initial settings.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
-  // overflow the connection-level window. The result should be a GOAWAY.
-  const std::string overflow_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Data(1, std::string(window_overflow_bytes, 'a'))
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
-
-  const size_t chunk_length = 16384;
-  ASSERT_GE(overflow_frames.size(), chunk_length);
-  process_result =
-      adapter->ProcessBytes(overflow_frames.substr(0, chunk_length));
-  EXPECT_EQ(chunk_length, static_cast<size_t>(process_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(GOAWAY, 0, _, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ClientDisobeysStreamFlowControl) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  const std::string more_frames = TestFrameSequence()
-                                      // 70000 bytes of data
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(16384, 'a'))
-                                      .Data(1, std::string(4464, 'a'))
-                                      .Serialize();
-
-  testing::InSequence s;
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-
-  int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  adapter->SubmitWindowUpdate(0, 20000);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::WINDOW_UPDATE}));
-  visitor.Clear();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
-  EXPECT_CALL(visitor, OnDataForStream(1, _));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
-  // No further frame data or headers are delivered.
-
-  result = adapter->ProcessBytes(more_frames);
-  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(
-      visitor,
-      OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerErrorWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
-      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
-  // Stream WINDOW_UPDATE and DATA frames are not delivered to the visitor.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerErrorWhileHandlingHeadersDropsFrames) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"accept", "some bogus value!"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .Metadata(1, "This is the request metadata.")
-                                 .RstStream(1, Http2ErrorCode::CANCEL)
-                                 .WindowUpdate(0, 2000)
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/false)
-                                 .Metadata(3, "This is the request metadata.",
-                                           /*multiple_frames=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
-      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
-  // Frames for the RST_STREAM-marked stream are not delivered to the visitor.
-  // Note: nghttp2 still delivers control frames and metadata for the stream.
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 0));
-  EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
-  EXPECT_CALL(visitor, OnMetadataForStream(3, "This is the re"))
-      .WillOnce(testing::DoAll(testing::InvokeWithoutArgs([&adapter]() {
-                                 adapter->SubmitRst(
-                                     3, Http2ErrorCode::REFUSED_STREAM);
-                               }),
-                               testing::Return(true)));
-  // The rest of the metadata is not delivered to the visitor.
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  // SETTINGS ack
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerConnectionErrorWhileHandlingHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"Accept", "uppercase, oh boy!"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_LT(result, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
-                            SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerErrorAfterHandlingHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_LT(result, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-// Exercises the case when a visitor chooses to reject a frame based solely on
-// the frame header, which is a fatal error for the connection.
-TEST(OgHttp2AdapterTest, ServerRejectsFrameHeader) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Ping(64)
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .WindowUpdate(0, 2000)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_LT(result, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerRejectsBeginningOfData) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_LT(result, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerReceivesTooLargeHeader) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .max_header_list_bytes = 64 * 1024,
-                                  .max_header_field_size = 64 * 1024};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  // Due to configuration, the library will accept a maximum of 64kB of huffman
-  // encoded data per header field.
-  const std::string too_large_value = std::string(80 * 1024, 'q');
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"},
-                                           {"x-toobig", too_large_value}},
-                                          /*fin=*/true)
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_STREAM));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 0)).Times(3);
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, END_HEADERS));
-  // Further header processing is skipped, as the header field is too large.
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, END_STREAM | END_HEADERS));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerReceivesInvalidAuthority) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "ex|ample.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0x0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0x0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, 4, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerRejectsStreamData) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
-  EXPECT_CALL(visitor, OnDataForStream(1, _)).WillOnce(testing::Return(false));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_LT(result, 0);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-// Exercises a naive mutually recursive test client and server. This test fails
-// without recursion guards in OgHttp2Session.
-TEST(OgHttp2AdapterInteractionTest, ClientServerInteractionTest) {
-  MockHttp2Visitor client_visitor;
-  auto client_adapter = OgHttp2Adapter::Create(
-      client_visitor, {.perspective = Perspective::kClient});
-  MockHttp2Visitor server_visitor;
-  auto server_adapter = OgHttp2Adapter::Create(
-      server_visitor, {.perspective = Perspective::kServer});
-
-  // Feeds bytes sent from the client into the server's ProcessBytes.
-  EXPECT_CALL(client_visitor, OnReadyToSend(_))
-      .WillRepeatedly(
-          testing::Invoke(server_adapter.get(), &OgHttp2Adapter::ProcessBytes));
-  // Feeds bytes sent from the server into the client's ProcessBytes.
-  EXPECT_CALL(server_visitor, OnReadyToSend(_))
-      .WillRepeatedly(
-          testing::Invoke(client_adapter.get(), &OgHttp2Adapter::ProcessBytes));
-  // Sets up the server to respond automatically to a request from a client.
-  EXPECT_CALL(server_visitor, OnEndHeadersForStream(_))
-      .WillRepeatedly([&server_adapter](Http2StreamId stream_id) {
-        server_adapter->SubmitResponse(
-            stream_id, ToHeaders({{":status", "200"}}), nullptr);
-        server_adapter->Send();
-        return true;
-      });
-  // Sets up the client to create a new stream automatically when receiving a
-  // response.
-  EXPECT_CALL(client_visitor, OnEndHeadersForStream(_))
-      .WillRepeatedly([&client_adapter,
-                       &client_visitor](Http2StreamId stream_id) {
-        if (stream_id < 10) {
-          const Http2StreamId new_stream_id = stream_id + 2;
-          auto body =
-              absl::make_unique<TestDataFrameSource>(client_visitor, true);
-          body->AppendPayload("This is an example request body.");
-          body->EndData();
-          const int created_stream_id = client_adapter->SubmitRequest(
-              ToHeaders({{":method", "GET"},
-                         {":scheme", "http"},
-                         {":authority", "example.com"},
-                         {":path",
-                          absl::StrCat("/this/is/request/", new_stream_id)}}),
-              std::move(body), nullptr);
-          EXPECT_EQ(new_stream_id, created_stream_id);
-          client_adapter->Send();
-        }
-        return true;
-      });
-
-  // Submit a request to ensure the first stream is created.
-  int stream_id = client_adapter->SubmitRequest(
-      ToHeaders({{":method", "POST"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"}}),
-      nullptr, nullptr);
-  EXPECT_EQ(stream_id, 1);
-
-  client_adapter->Send();
-}
-
-TEST(OgHttp2AdapterInteractionTest,
-     ClientServerInteractionRepeatedHeaderNames) {
-  DataSavingVisitor client_visitor;
-  OgHttp2Adapter::Options client_options{.perspective = Perspective::kClient};
-  auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
-
-  const std::vector<Header> headers1 =
-      ToHeaders({{":method", "GET"},
-                 {":scheme", "http"},
-                 {":authority", "example.com"},
-                 {":path", "/this/is/request/one"},
-                 {"accept", "text/plain"},
-                 {"accept", "text/html"}});
-
-  const int32_t stream_id1 =
-      client_adapter->SubmitRequest(headers1, nullptr, nullptr);
-  ASSERT_GT(stream_id1, 0);
-
-  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(client_visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
-  EXPECT_CALL(client_visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
-  int send_result = client_adapter->Send();
-  EXPECT_EQ(0, send_result);
-
-  DataSavingVisitor server_visitor;
-  OgHttp2Adapter::Options server_options{.perspective = Perspective::kServer};
-  auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
-  EXPECT_CALL(server_visitor, OnSettingsStart());
-  EXPECT_CALL(server_visitor, OnSetting).Times(testing::AnyNumber());
-  EXPECT_CALL(server_visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
-  EXPECT_CALL(server_visitor,
-              OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(server_visitor,
-              OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/plain"));
-  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/html"));
-  EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(server_visitor, OnEndStream(1));
-
-  int64_t result = server_adapter->ProcessBytes(client_visitor.data());
-  EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
-}
-
-TEST(OgHttp2AdapterTest, ServerForbidsNewStreamBelowWatermark) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(3,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(3, "This is the request body.")
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(3, 25));
-  EXPECT_CALL(visitor, OnDataForStream(3, "This is the request body."));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidNewStreamId));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerForbidsWindowUpdateOnIdleStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerForbidsDataOnIdleStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Data(1, "Sorry, out of order")
-                                 .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerForbidsRstStreamOnIdleStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
-
-  const std::string frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerForbidsNewStreamAboveStreamLimit) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Let the client send a SETTINGS ack and then attempt to open more than the
-  // advertised number of streams. The overflow stream should be rejected.
-  const std::string stream_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":method", "GET"},
-                    {":scheme", "http"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kProtocol));
-  // The oghttp2 stack also signals the error via OnConnectionError().
-  EXPECT_CALL(visitor, OnConnectionError(
-                           ConnectionError::kExceededMaxConcurrentStreams));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
-
-  // The server should send a GOAWAY for this error, even though
-  // OnInvalidFrame() returns true.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerRstStreamsNewStreamAboveStreamLimitBeforeAck) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // Let the client avoid sending a SETTINGS ack and attempt to open more than
-  // the advertised number of streams. The server should still reject the
-  // overflow stream, albeit with RST_STREAM REFUSED_STREAM instead of GOAWAY.
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":method", "GET"},
-                    {":scheme", "http"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  3, Http2VisitorInterface::InvalidFrameError::kRefusedStream));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
-
-  // The server sends a RST_STREAM for the offending stream.
-  EXPECT_TRUE(adapter->want_write());
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
-
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .allow_extended_connect = false};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  // The client attempts to send a CONNECT request with the `:protocol`
-  // pseudoheader before receiving the server's SETTINGS frame.
-  const std::string stream1_frames =
-      TestFrameSequence()
-          .Headers(1,
-                   {{":method", "CONNECT"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"},
-                    {":protocol", "websocket"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  int64_t stream_result = adapter->ProcessBytes(stream1_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream1_frames.size());
-
-  // Server initial SETTINGS and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  // The server sends a RST_STREAM for the offending stream.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  // Server settings with ENABLE_CONNECT_PROTOCOL.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-
-  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  // The client attempts to send a CONNECT request with the `:protocol`
-  // pseudoheader before acking the server's SETTINGS frame.
-  const std::string stream3_frames =
-      TestFrameSequence()
-          .Headers(3,
-                   {{":method", "CONNECT"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/two"},
-                    {":protocol", "websocket"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // After sending SETTINGS with `ENABLE_CONNECT_PROTOCOL`, oghttp2 matches
-  // nghttp2 in allowing this, even though the `allow_extended_connect` option
-  // is false.
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-
-  stream_result = adapter->ProcessBytes(stream3_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream3_frames.size());
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, ServerAllowsProtocolPseudoheaderAfterAck) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
-
-  const std::string initial_frames =
-      TestFrameSequence().ClientPreface().Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  // Server initial SETTINGS (with ENABLE_CONNECT_PROTOCOL) and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  visitor.Clear();
-
-  // The client attempts to send a CONNECT request with the `:protocol`
-  // pseudoheader after acking the server's SETTINGS frame.
-  const std::string stream_frames =
-      TestFrameSequence()
-          .SettingsAck()
-          .Headers(1,
-                   {{":method", "CONNECT"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"},
-                    {":protocol", "websocket"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, 0x1));
-  EXPECT_CALL(visitor, OnSettingsAck());
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
-
-  EXPECT_FALSE(adapter->want_write());
-}
-
-TEST(OgHttp2AdapterTest, SkipsSendingFramesForRejectedStream) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string initial_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":method", "GET"},
-                    {":scheme", "http"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/one"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
-  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
-
-  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body->AppendPayload("Here is some data, which will be completely ignored!");
-
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}}), std::move(body));
-  ASSERT_EQ(0, submit_result);
-
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-
-  adapter->SubmitWindowUpdate(1, 1024);
-  adapter->SubmitRst(1, Http2ErrorCode::INTERNAL_ERROR);
-
-  // Server initial SETTINGS and SETTINGS ack.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-
-  // The server sends a RST_STREAM for the offending stream.
-  // The response HEADERS, DATA and WINDOW_UPDATE are all ignored.
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttpAdapterServerTest, ServerStartsShutdown) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  adapter->SubmitShutdownNotice();
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-}
-
-TEST(OgHttp2AdapterTest, ServerStartsShutdownAfterGoaway) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  EXPECT_FALSE(adapter->want_write());
-
-  adapter->SubmitGoAway(1, Http2ErrorCode::HTTP2_NO_ERROR,
-                        "and don't come back!");
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
-
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-
-  // No-op, since a GOAWAY has previously been enqueued.
-  adapter->SubmitShutdownNotice();
-  EXPECT_FALSE(adapter->want_write());
-}
-
-// Verifies that a connection-level processing error results in repeatedly
-// returning a positive value for ProcessBytes() to mark all data as consumed
-// when the blackhole option is enabled.
-TEST(OgHttp2AdapterTest, ConnectionErrorWithBlackholingData) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .blackhole_data_on_connection_error = true};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(result), frames.size());
-
-  // Ask the connection to process more bytes. Because the option is enabled,
-  // the data should be marked as consumed.
-  const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
-  const int64_t next_result = adapter->ProcessBytes(next_frame);
-  EXPECT_EQ(static_cast<size_t>(next_result), next_frame.size());
-}
-
-// Verifies that a connection-level processing error results in returning a
-// negative value for ProcessBytes() when the blackhole option is disabled.
-TEST(OgHttp2AdapterTest, ConnectionErrorWithoutBlackholingData) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
-                                  .blackhole_data_on_connection_error = false};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames =
-      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
-
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_LT(result, 0);
-
-  // Ask the connection to process more bytes. Because the option is disabled,
-  // ProcessBytes() should continue to return an error.
-  const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
-  const int64_t next_result = adapter->ProcessBytes(next_frame);
-  EXPECT_LT(next_result, 0);
-}
-
-TEST(OgHttp2AdapterTest, ServerDoesNotSendFramesAfterImmediateGoAway) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  // Submit a custom initial SETTINGS frame with one setting.
-  adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t read_result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
-
-  // Submit a response for the stream.
-  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body->AppendPayload("This data is doomed to never be written.");
-  int submit_result = adapter->SubmitResponse(
-      1, ToHeaders({{":status", "200"}}), std::move(body));
-  ASSERT_EQ(0, submit_result);
-
-  // Submit a WINDOW_UPDATE frame.
-  adapter->SubmitWindowUpdate(kConnectionStreamId, 42);
-
-  // Submit another SETTINGS frame.
-  adapter->SubmitSettings({});
-
-  // Submit some metadata.
-  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
-      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
-  adapter->SubmitMetadata(1, 16384u, std::move(source));
-
-  EXPECT_TRUE(adapter->want_write());
-
-  // Trigger a connection error. Only the response headers will be written.
-  const std::string connection_error_frames =
-      TestFrameSequence().WindowUpdate(3, 42).Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
-
-  const int64_t result = adapter->ProcessBytes(connection_error_frames);
-  EXPECT_EQ(static_cast<size_t>(result), connection_error_frames.size());
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(GOAWAY, 0, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-
-  int send_result = adapter->Send();
-  // Some bytes should have been serialized.
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
-  visitor.Clear();
-
-  // Try to submit more frames for writing. They should not be written.
-  adapter->SubmitPing(42);
-  // TODO(diannahu): Enable the below expectation.
-  // EXPECT_FALSE(adapter->want_write());
-  send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesContentLength) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/one"},
-                       {"content-length", "2"}})
-          .Data(1, "hi", /*fin=*/true)
-          .Headers(3,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/three"},
-                    {"content-length", "nan"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Stream 1: content-length is correct
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
-  EXPECT_CALL(visitor, OnDataForStream(1, "hi"));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  // Stream 3: content-length is not a number
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesContentLengthMismatch) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/two"},
-                       {"content-length", "2"}})
-          .Data(1, "h", /*fin=*/true)
-          .Headers(3, {{":method", "GET"},
-                       {":scheme", "https"},
-                       {":authority", "example.com"},
-                       {":path", "/this/is/request/three"},
-                       {"content-length", "2"}})
-          .Data(3, "howdy", /*fin=*/true)
-          .Headers(5,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/four"},
-                    {"content-length", "2"}},
-                   /*fin=*/true)
-          .Headers(7,
-                   {{":method", "GET"},
-                    {":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/this/is/request/four"},
-                    {"content-length", "2"}},
-                   /*fin=*/false)
-          .Data(7, "h", /*fin=*/false)
-          .Headers(7, {{"extra-info", "Trailers with content-length mismatch"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Stream 1: content-length is larger than actual data
-  // All data is delivered to the visitor. Note that neither oghttp2 nor
-  // nghttp2 delivers OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 1));
-  EXPECT_CALL(visitor, OnDataForStream(1, "h"));
-
-  // Stream 3: content-length is smaller than actual data
-  // The beginning of data is delivered to the visitor, but not the actual data.
-  // Again, neither oghttp2 nor nghttp2 delivers OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(3, 5));
-
-  // Stream 5: content-length is invalid and HEADERS ends the stream
-  // Only oghttp2 invokes OnEndHeadersForStream(). Only nghttp2 invokes
-  // OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(5));
-
-  // Stream 7: content-length is invalid and trailers end the stream
-  // Only oghttp2 invokes OnEndHeadersForStream(). Only nghttp2 invokes
-  // OnInvalidFrame().
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
-  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(7));
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(7, 1));
-  EXPECT_CALL(visitor, OnDataForStream(7, "h"));
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
-  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(7));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 7, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesAsteriskPathForOptions) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::string stream_frames = TestFrameSequence()
-                                        .ClientPreface()
-                                        .Headers(1,
-                                                 {{":scheme", "https"},
-                                                  {":authority", "example.com"},
-                                                  {":path", "*"},
-                                                  {":method", "OPTIONS"}},
-                                                 /*fin=*/true)
-                                        .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesInvalidPath) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "*"},
-                    {":method", "GET"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "other/non/slash/starter"},
-                    {":method", "GET"}},
-                   /*fin=*/true)
-          .Headers(5,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", ""},
-                    {":method", "GET"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(visitor,
-              OnInvalidFrame(
-                  3, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
-
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(2);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesTeHeader) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::string stream_frames = TestFrameSequence()
-                                        .ClientPreface()
-                                        .Headers(1,
-                                                 {{":scheme", "https"},
-                                                  {":authority", "example.com"},
-                                                  {":path", "/"},
-                                                  {":method", "GET"},
-                                                  {"te", "trailers"}},
-                                                 /*fin=*/true)
-                                        .Headers(3,
-                                                 {{":scheme", "https"},
-                                                  {":authority", "example.com"},
-                                                  {":path", "/"},
-                                                  {":method", "GET"},
-                                                  {"te", "trailers, deflate"}},
-                                                 /*fin=*/true)
-                                        .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // Stream 1: TE: trailers should be allowed.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  // Stream 3: TE: <non-trailers> should be rejected.
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerHandlesConnectionSpecificHeaders) {
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  testing::InSequence s;
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .ClientPreface()
-          .Headers(1,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"connection", "keep-alive"}},
-                   /*fin=*/true)
-          .Headers(3,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"proxy-connection", "keep-alive"}},
-                   /*fin=*/true)
-          .Headers(5,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"keep-alive", "timeout=42"}},
-                   /*fin=*/true)
-          .Headers(7,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"transfer-encoding", "chunked"}},
-                   /*fin=*/true)
-          .Headers(9,
-                   {{":scheme", "https"},
-                    {":authority", "example.com"},
-                    {":path", "/"},
-                    {":method", "GET"},
-                    {"upgrade", "h2c"}},
-                   /*fin=*/true)
-          .Serialize();
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  // All streams contain a connection-specific header and should be rejected.
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
-  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
-  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(7, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-  EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
-  EXPECT_CALL(visitor, OnHeaderForStream(9, _, _)).Times(4);
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(9, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
-
-  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 1, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 3, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 5, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 7, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 9, _, 0x0));
-  EXPECT_CALL(visitor,
-              OnFrameSent(RST_STREAM, 9, _, 0x0,
-                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
-  EXPECT_CALL(visitor, OnCloseStream(9, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  EXPECT_TRUE(adapter->want_write());
-  int result = adapter->Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(
-      visitor.data(),
-      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
-                    SpdyFrameType::RST_STREAM}));
-}
-
-TEST(OgHttp2AdapterTest, ServerUsesCustomWindowUpdateStrategy) {
-  // Test the use of a custom WINDOW_UPDATE strategy.
-  DataSavingVisitor visitor;
-  OgHttp2Adapter::Options options{
-      .should_window_update_fn = [](int64_t /*limit*/, int64_t /*size*/,
-                                    int64_t /*delta*/) { return true; },
-      .perspective = Perspective::kServer};
-  auto adapter = OgHttp2Adapter::Create(visitor, options);
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .Data(1, "This is the request body.",
-                                       /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0x1));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = adapter->ProcessBytes(frames);
-  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
-
-  // Mark a small number of bytes for the stream as consumed. Because of the
-  // custom WINDOW_UPDATE strategy, the session should send WINDOW_UPDATEs.
-  adapter->MarkDataConsumedForStream(1, 5);
-
-  EXPECT_TRUE(adapter->want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
-
-  int send_result = adapter->Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
-                            SpdyFrameType::WINDOW_UPDATE,
-                            SpdyFrameType::WINDOW_UPDATE}));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/oghttp2_session.cc b/http2/adapter/oghttp2_session.cc
deleted file mode 100644
index 0381625..0000000
--- a/http2/adapter/oghttp2_session.cc
+++ /dev/null
@@ -1,1869 +0,0 @@
-#include "http2/adapter/oghttp2_session.h"
-
-#include <cstdint>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "http2/adapter/header_validator.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_util.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/oghttp2_util.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-
-namespace {
-
-using ConnectionError = Http2VisitorInterface::ConnectionError;
-using SpdyFramerError = Http2DecoderAdapter::SpdyFramerError;
-
-using ::spdy::SpdySettingsIR;
-
-// #define OGHTTP2_DEBUG_TRACE 1
-
-#ifdef OGHTTP2_DEBUG_TRACE
-const bool kTraceLoggingEnabled = true;
-#else
-const bool kTraceLoggingEnabled = false;
-#endif
-
-const uint32_t kMaxAllowedMetadataFrameSize = 65536u;
-const uint32_t kDefaultHpackTableCapacity = 4096u;
-const uint32_t kMaximumHpackTableCapacity = 65536u;
-
-// Corresponds to NGHTTP2_ERR_CALLBACK_FAILURE.
-const int kSendError = -902;
-
-// TODO(birenroy): Consider incorporating spdy::FlagsSerializionVisitor here.
-class FrameAttributeCollector : public spdy::SpdyFrameVisitor {
- public:
-  FrameAttributeCollector() = default;
-  void VisitData(const spdy::SpdyDataIR& data) override {
-    frame_type_ = static_cast<uint8_t>(data.frame_type());
-    stream_id_ = data.stream_id();
-    flags_ = (data.fin() ? 0x1 : 0) | (data.padded() ? 0x8 : 0);
-  }
-  void VisitHeaders(const spdy::SpdyHeadersIR& headers) override {
-    frame_type_ = static_cast<uint8_t>(headers.frame_type());
-    stream_id_ = headers.stream_id();
-    flags_ = 0x4 | (headers.fin() ? 0x1 : 0) | (headers.padded() ? 0x8 : 0) |
-             (headers.has_priority() ? 0x20 : 0);
-  }
-  void VisitPriority(const spdy::SpdyPriorityIR& priority) override {
-    frame_type_ = static_cast<uint8_t>(priority.frame_type());
-    frame_type_ = 2;
-    stream_id_ = priority.stream_id();
-  }
-  void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override {
-    frame_type_ = static_cast<uint8_t>(rst_stream.frame_type());
-    frame_type_ = 3;
-    stream_id_ = rst_stream.stream_id();
-    error_code_ = rst_stream.error_code();
-  }
-  void VisitSettings(const spdy::SpdySettingsIR& settings) override {
-    frame_type_ = static_cast<uint8_t>(settings.frame_type());
-    frame_type_ = 4;
-    flags_ = (settings.is_ack() ? 0x1 : 0);
-  }
-  void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override {
-    frame_type_ = static_cast<uint8_t>(push_promise.frame_type());
-    frame_type_ = 5;
-    stream_id_ = push_promise.stream_id();
-    flags_ = (push_promise.padded() ? 0x8 : 0);
-  }
-  void VisitPing(const spdy::SpdyPingIR& ping) override {
-    frame_type_ = static_cast<uint8_t>(ping.frame_type());
-    frame_type_ = 6;
-    flags_ = (ping.is_ack() ? 0x1 : 0);
-  }
-  void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override {
-    frame_type_ = static_cast<uint8_t>(goaway.frame_type());
-    frame_type_ = 7;
-    error_code_ = goaway.error_code();
-  }
-  void VisitWindowUpdate(
-      const spdy::SpdyWindowUpdateIR& window_update) override {
-    frame_type_ = static_cast<uint8_t>(window_update.frame_type());
-    frame_type_ = 8;
-    stream_id_ = window_update.stream_id();
-  }
-  void VisitContinuation(
-      const spdy::SpdyContinuationIR& continuation) override {
-    frame_type_ = static_cast<uint8_t>(continuation.frame_type());
-    stream_id_ = continuation.stream_id();
-    flags_ = continuation.end_headers() ? 0x4 : 0;
-  }
-  void VisitUnknown(const spdy::SpdyUnknownIR& unknown) override {
-    frame_type_ = static_cast<uint8_t>(unknown.frame_type());
-    stream_id_ = unknown.stream_id();
-    flags_ = unknown.flags();
-  }
-  void VisitAltSvc(const spdy::SpdyAltSvcIR& /*altsvc*/) override {}
-  void VisitPriorityUpdate(
-      const spdy::SpdyPriorityUpdateIR& /*priority_update*/) override {}
-  void VisitAcceptCh(const spdy::SpdyAcceptChIR& /*accept_ch*/) override {}
-
-  uint32_t stream_id() { return stream_id_; }
-  uint32_t error_code() { return error_code_; }
-  uint8_t frame_type() { return frame_type_; }
-  uint8_t flags() { return flags_; }
-
- private:
-  uint32_t stream_id_ = 0;
-  uint32_t error_code_ = 0;
-  uint8_t frame_type_ = 0;
-  uint8_t flags_ = 0;
-};
-
-absl::string_view TracePerspectiveAsString(Perspective p) {
-  switch (p) {
-    case Perspective::kClient:
-      return "OGHTTP2_CLIENT";
-    case Perspective::kServer:
-      return "OGHTTP2_SERVER";
-  }
-  return "OGHTTP2_SERVER";
-}
-
-class RunOnExit {
- public:
-  RunOnExit() = default;
-  explicit RunOnExit(std::function<void()> f) : f_(std::move(f)) {}
-
-  RunOnExit(const RunOnExit& other) = delete;
-  RunOnExit& operator=(const RunOnExit& other) = delete;
-  RunOnExit(RunOnExit&& other) = delete;
-  RunOnExit& operator=(RunOnExit&& other) = delete;
-
-  ~RunOnExit() {
-    if (f_) {
-      f_();
-    }
-    f_ = {};
-  }
-
-  void emplace(std::function<void()> f) { f_ = std::move(f); }
-
- private:
-  std::function<void()> f_;
-};
-
-Http2ErrorCode GetHttp2ErrorCode(SpdyFramerError error) {
-  switch (error) {
-    case SpdyFramerError::SPDY_NO_ERROR:
-      return Http2ErrorCode::HTTP2_NO_ERROR;
-    case SpdyFramerError::SPDY_INVALID_STREAM_ID:
-    case SpdyFramerError::SPDY_INVALID_CONTROL_FRAME:
-    case SpdyFramerError::SPDY_INVALID_PADDING:
-    case SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS:
-    case SpdyFramerError::SPDY_UNEXPECTED_FRAME:
-      return Http2ErrorCode::PROTOCOL_ERROR;
-    case SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE:
-    case SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE:
-    case SpdyFramerError::SPDY_OVERSIZED_PAYLOAD:
-      return Http2ErrorCode::FRAME_SIZE_ERROR;
-    case SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
-    case SpdyFramerError::SPDY_HPACK_INDEX_VARINT_ERROR:
-    case SpdyFramerError::SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
-    case SpdyFramerError::SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
-    case SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG:
-    case SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG:
-    case SpdyFramerError::SPDY_HPACK_NAME_HUFFMAN_ERROR:
-    case SpdyFramerError::SPDY_HPACK_VALUE_HUFFMAN_ERROR:
-    case SpdyFramerError::SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
-    case SpdyFramerError::SPDY_HPACK_INVALID_INDEX:
-    case SpdyFramerError::SPDY_HPACK_INVALID_NAME_INDEX:
-    case SpdyFramerError::SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
-    case SpdyFramerError::
-        SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
-    case SpdyFramerError::
-        SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
-    case SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK:
-    case SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG:
-    case SpdyFramerError::SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
-      return Http2ErrorCode::COMPRESSION_ERROR;
-    case SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR:
-    case SpdyFramerError::SPDY_STOP_PROCESSING:
-    case SpdyFramerError::LAST_ERROR:
-      return Http2ErrorCode::INTERNAL_ERROR;
-  }
-  return Http2ErrorCode::INTERNAL_ERROR;
-}
-
-bool IsResponse(HeaderType type) {
-  return type == HeaderType::RESPONSE_100 || type == HeaderType::RESPONSE;
-}
-
-bool StatusIs1xx(absl::string_view status) {
-  return status.size() == 3 && status[0] == '1';
-}
-
-// Returns the upper bound on HPACK encoder table capacity. If not specified in
-// the Options, a reasonable default upper bound is used.
-uint32_t HpackCapacityBound(const OgHttp2Session::Options& o) {
-  return o.max_hpack_encoding_table_capacity.value_or(
-      kMaximumHpackTableCapacity);
-}
-
-bool IsNonAckSettings(const spdy::SpdyFrameIR& frame) {
-  return frame.frame_type() == spdy::SpdyFrameType::SETTINGS &&
-         !reinterpret_cast<const SpdySettingsIR&>(frame).is_ack();
-}
-
-}  // namespace
-
-void OgHttp2Session::PassthroughHeadersHandler::OnHeaderBlockStart() {
-  result_ = Http2VisitorInterface::HEADER_OK;
-  const bool status = visitor_.OnBeginHeadersForStream(stream_id_);
-  if (!status) {
-    QUICHE_VLOG(1)
-        << "Visitor rejected header block, returning HEADER_CONNECTION_ERROR";
-    result_ = Http2VisitorInterface::HEADER_CONNECTION_ERROR;
-  }
-  validator_.StartHeaderBlock();
-}
-
-Http2VisitorInterface::OnHeaderResult InterpretHeaderStatus(
-    HeaderValidator::HeaderStatus status) {
-  switch (status) {
-    case HeaderValidator::HEADER_OK:
-      return Http2VisitorInterface::HEADER_OK;
-    case HeaderValidator::HEADER_FIELD_INVALID:
-      return Http2VisitorInterface::HEADER_FIELD_INVALID;
-    case HeaderValidator::HEADER_FIELD_TOO_LONG:
-      return Http2VisitorInterface::HEADER_RST_STREAM;
-  }
-  return Http2VisitorInterface::HEADER_CONNECTION_ERROR;
-}
-
-void OgHttp2Session::PassthroughHeadersHandler::OnHeader(
-    absl::string_view key,
-    absl::string_view value) {
-  if (result_ != Http2VisitorInterface::HEADER_OK) {
-    QUICHE_VLOG(2) << "Early return; status not HEADER_OK";
-    return;
-  }
-  const HeaderValidator::HeaderStatus validation_result =
-      validator_.ValidateSingleHeader(key, value);
-  if (validation_result != HeaderValidator::HEADER_OK) {
-    QUICHE_VLOG(2) << "Header validation failed with result "
-                   << static_cast<int>(validation_result);
-    result_ = InterpretHeaderStatus(validation_result);
-    return;
-  }
-  result_ = visitor_.OnHeaderForStream(stream_id_, key, value);
-}
-
-void OgHttp2Session::PassthroughHeadersHandler::OnHeaderBlockEnd(
-    size_t /* uncompressed_header_bytes */,
-    size_t /* compressed_header_bytes */) {
-  if (result_ == Http2VisitorInterface::HEADER_OK) {
-    if (!validator_.FinishHeaderBlock(type_)) {
-      QUICHE_VLOG(1) << "FinishHeaderBlock returned false; returning "
-                        "HEADER_HTTP_MESSAGING";
-      result_ = Http2VisitorInterface::HEADER_HTTP_MESSAGING;
-    }
-  }
-  if (frame_contains_fin_ && IsResponse(type_) &&
-      StatusIs1xx(status_header())) {
-    QUICHE_VLOG(1) << "Unexpected end of stream without final headers";
-    result_ = Http2VisitorInterface::HEADER_HTTP_MESSAGING;
-  }
-  if (result_ == Http2VisitorInterface::HEADER_OK) {
-    const bool result = visitor_.OnEndHeadersForStream(stream_id_);
-    if (!result) {
-      session_.fatal_visitor_callback_failure_ = true;
-      session_.decoder_.StopProcessing();
-    }
-  } else {
-    session_.OnHeaderStatus(stream_id_, result_);
-  }
-  frame_contains_fin_ = false;
-}
-
-// TODO(diannahu): Add checks for request methods.
-bool OgHttp2Session::PassthroughHeadersHandler::CanReceiveBody() const {
-  switch (header_type()) {
-    case HeaderType::REQUEST_TRAILER:
-    case HeaderType::RESPONSE_TRAILER:
-    case HeaderType::RESPONSE_100:
-      return false;
-    case HeaderType::RESPONSE:
-      // 304 responses should not have a body:
-      // https://httpwg.org/specs/rfc7230.html#rfc.section.3.3.2
-      // Neither should 204 responses:
-      // https://httpwg.org/specs/rfc7231.html#rfc.section.6.3.5
-      return status_header() != "304" && status_header() != "204";
-    case HeaderType::REQUEST:
-      return true;
-  }
-  return true;
-}
-
-// A visitor that extracts an int64_t from each type of a ProcessBytesResult.
-struct OgHttp2Session::ProcessBytesResultVisitor {
-  int64_t operator()(const int64_t bytes) const { return bytes; }
-
-  int64_t operator()(const ProcessBytesError error) const {
-    switch (error) {
-      case ProcessBytesError::kUnspecified:
-        return -1;
-      case ProcessBytesError::kInvalidConnectionPreface:
-        return -903;  // NGHTTP2_ERR_BAD_CLIENT_MAGIC
-      case ProcessBytesError::kVisitorCallbackFailed:
-        return -902;  // NGHTTP2_ERR_CALLBACK_FAILURE
-    }
-    return -1;
-  }
-};
-
-OgHttp2Session::OgHttp2Session(Http2VisitorInterface& visitor, Options options)
-    : visitor_(visitor),
-      event_forwarder_([this]() { return !latched_error_; }, *this),
-      receive_logger_(
-          &event_forwarder_, TracePerspectiveAsString(options.perspective),
-          []() { return kTraceLoggingEnabled; }, this),
-      send_logger_(
-          TracePerspectiveAsString(options.perspective),
-          []() { return kTraceLoggingEnabled; }, this),
-      headers_handler_(*this, visitor),
-      noop_headers_handler_(/*listener=*/nullptr),
-      connection_window_manager_(
-          kInitialFlowControlWindowSize,
-          [this](size_t window_update_delta) {
-            SendWindowUpdate(kConnectionStreamId, window_update_delta);
-          },
-          options.should_window_update_fn,
-          /*update_window_on_notify=*/false),
-      options_(options) {
-  decoder_.set_visitor(&receive_logger_);
-  decoder_.set_extension_visitor(this);
-  if (options_.max_header_list_bytes) {
-    // Limit buffering of encoded HPACK data to 2x the decoded limit.
-    decoder_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
-        2 * *options_.max_header_list_bytes);
-    // Limit the total bytes accepted for HPACK decoding to 4x the limit.
-    decoder_.GetHpackDecoder()->set_max_header_block_bytes(
-        4 * *options_.max_header_list_bytes);
-  }
-  if (IsServerSession()) {
-    remaining_preface_ = {spdy::kHttp2ConnectionHeaderPrefix,
-                          spdy::kHttp2ConnectionHeaderPrefixSize};
-  }
-  if (options_.max_header_field_size.has_value()) {
-    headers_handler_.SetMaxFieldSize(options_.max_header_field_size.value());
-  }
-}
-
-OgHttp2Session::~OgHttp2Session() {}
-
-void OgHttp2Session::SetStreamUserData(Http2StreamId stream_id,
-                                       void* user_data) {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    it->second.user_data = user_data;
-  }
-}
-
-void* OgHttp2Session::GetStreamUserData(Http2StreamId stream_id) {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    return it->second.user_data;
-  }
-  auto p = pending_streams_.find(stream_id);
-  if (p != pending_streams_.end()) {
-    return p->second.user_data;
-  }
-  return nullptr;
-}
-
-bool OgHttp2Session::ResumeStream(Http2StreamId stream_id) {
-  auto it = stream_map_.find(stream_id);
-  if (it == stream_map_.end() || it->second.outbound_body == nullptr ||
-      !write_scheduler_.StreamRegistered(stream_id)) {
-    return false;
-  }
-  it->second.data_deferred = false;
-  write_scheduler_.MarkStreamReady(stream_id, /*add_to_front=*/false);
-  return true;
-}
-
-int OgHttp2Session::GetStreamSendWindowSize(Http2StreamId stream_id) const {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    return it->second.send_window;
-  }
-  return -1;
-}
-
-int OgHttp2Session::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    return it->second.window_manager.WindowSizeLimit();
-  }
-  return -1;
-}
-
-int OgHttp2Session::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    return it->second.window_manager.CurrentWindowSize();
-  }
-  return -1;
-}
-
-int OgHttp2Session::GetReceiveWindowSize() const {
-  return connection_window_manager_.CurrentWindowSize();
-}
-
-int OgHttp2Session::GetHpackEncoderDynamicTableSize() const {
-  const spdy::HpackEncoder* encoder = framer_.GetHpackEncoder();
-  return encoder == nullptr ? 0 : encoder->GetDynamicTableSize();
-}
-
-int OgHttp2Session::GetHpackEncoderDynamicTableCapacity() const {
-  const spdy::HpackEncoder* encoder = framer_.GetHpackEncoder();
-  return encoder == nullptr ? kDefaultHpackTableCapacity
-                            : encoder->CurrentHeaderTableSizeSetting();
-}
-
-int OgHttp2Session::GetHpackDecoderDynamicTableSize() const {
-  const spdy::HpackDecoderAdapter* decoder = decoder_.GetHpackDecoder();
-  return decoder == nullptr ? 0 : decoder->GetDynamicTableSize();
-}
-
-int OgHttp2Session::GetHpackDecoderSizeLimit() const {
-  const spdy::HpackDecoderAdapter* decoder = decoder_.GetHpackDecoder();
-  return decoder == nullptr ? 0 : decoder->GetCurrentHeaderTableSizeSetting();
-}
-
-int64_t OgHttp2Session::ProcessBytes(absl::string_view bytes) {
-  QUICHE_VLOG(2) << TracePerspectiveAsString(options_.perspective)
-                 << " processing [" << absl::CEscape(bytes) << "]";
-  return absl::visit(ProcessBytesResultVisitor(), ProcessBytesImpl(bytes));
-}
-
-absl::variant<int64_t, OgHttp2Session::ProcessBytesError>
-OgHttp2Session::ProcessBytesImpl(absl::string_view bytes) {
-  if (processing_bytes_) {
-    QUICHE_VLOG(1) << "Returning early; already processing bytes.";
-    return 0;
-  }
-  processing_bytes_ = true;
-  RunOnExit r{[this]() { processing_bytes_ = false; }};
-
-  if (options_.blackhole_data_on_connection_error && latched_error_) {
-    return static_cast<int64_t>(bytes.size());
-  }
-
-  int64_t preface_consumed = 0;
-  if (!remaining_preface_.empty()) {
-    QUICHE_VLOG(2) << "Preface bytes remaining: " << remaining_preface_.size();
-    // decoder_ does not understand the client connection preface.
-    size_t min_size = std::min(remaining_preface_.size(), bytes.size());
-    if (!absl::StartsWith(remaining_preface_, bytes.substr(0, min_size))) {
-      // Preface doesn't match!
-      QUICHE_DLOG(INFO) << "Preface doesn't match! Expected: ["
-                        << absl::CEscape(remaining_preface_) << "], actual: ["
-                        << absl::CEscape(bytes) << "]";
-      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                          ConnectionError::kInvalidConnectionPreface);
-      return ProcessBytesError::kInvalidConnectionPreface;
-    }
-    remaining_preface_.remove_prefix(min_size);
-    bytes.remove_prefix(min_size);
-    if (!remaining_preface_.empty()) {
-      QUICHE_VLOG(2) << "Preface bytes remaining: "
-                     << remaining_preface_.size();
-      return static_cast<int64_t>(min_size);
-    }
-    preface_consumed = min_size;
-  }
-  int64_t result = decoder_.ProcessInput(bytes.data(), bytes.size());
-  QUICHE_VLOG(2) << "ProcessBytes result: " << result;
-  if (fatal_visitor_callback_failure_) {
-    QUICHE_DCHECK(latched_error_);
-    QUICHE_VLOG(2) << "Visitor callback failed while processing bytes.";
-    return ProcessBytesError::kVisitorCallbackFailed;
-  }
-  if (latched_error_ || result < 0) {
-    QUICHE_VLOG(2) << "ProcessBytes encountered an error.";
-    if (options_.blackhole_data_on_connection_error) {
-      return static_cast<int64_t>(bytes.size() + preface_consumed);
-    } else {
-      return ProcessBytesError::kUnspecified;
-    }
-  }
-  return result + preface_consumed;
-}
-
-int OgHttp2Session::Consume(Http2StreamId stream_id, size_t num_bytes) {
-  auto it = stream_map_.find(stream_id);
-  if (it == stream_map_.end()) {
-    QUICHE_LOG(ERROR) << "Stream " << stream_id << " not found when consuming "
-                      << num_bytes << " bytes";
-  } else {
-    it->second.window_manager.MarkDataFlushed(num_bytes);
-  }
-  connection_window_manager_.MarkDataFlushed(num_bytes);
-  return 0;  // Remove?
-}
-
-void OgHttp2Session::StartGracefulShutdown() {
-  if (IsServerSession()) {
-    if (!queued_goaway_) {
-      EnqueueFrame(absl::make_unique<spdy::SpdyGoAwayIR>(
-          std::numeric_limits<int32_t>::max(), spdy::ERROR_CODE_NO_ERROR,
-          "graceful_shutdown"));
-    }
-  } else {
-    QUICHE_LOG(ERROR) << "Graceful shutdown not needed for clients.";
-  }
-}
-
-void OgHttp2Session::EnqueueFrame(std::unique_ptr<spdy::SpdyFrameIR> frame) {
-  if (queued_immediate_goaway_) {
-    // Do not allow additional frames to be enqueued after the GOAWAY.
-    return;
-  }
-
-  const bool is_non_ack_settings = IsNonAckSettings(*frame);
-  MaybeSetupPreface(is_non_ack_settings);
-
-  if (frame->frame_type() == spdy::SpdyFrameType::GOAWAY) {
-    queued_goaway_ = true;
-    if (latched_error_) {
-      PrepareForImmediateGoAway();
-    }
-  } else if (frame->fin() ||
-             frame->frame_type() == spdy::SpdyFrameType::RST_STREAM) {
-    auto iter = stream_map_.find(frame->stream_id());
-    if (iter != stream_map_.end()) {
-      iter->second.half_closed_local = true;
-    }
-    if (frame->frame_type() == spdy::SpdyFrameType::RST_STREAM) {
-      // TODO(diannahu): Condition on existence in the stream map?
-      streams_reset_.insert(frame->stream_id());
-    }
-  } else if (frame->frame_type() == spdy::SpdyFrameType::WINDOW_UPDATE) {
-    UpdateReceiveWindow(
-        frame->stream_id(),
-        reinterpret_cast<spdy::SpdyWindowUpdateIR&>(*frame).delta());
-  } else if (is_non_ack_settings) {
-    HandleOutboundSettings(
-        *reinterpret_cast<spdy::SpdySettingsIR*>(frame.get()));
-  }
-  if (frame->stream_id() != 0) {
-    auto result = queued_frames_.insert({frame->stream_id(), 1});
-    if (!result.second) {
-      ++(result.first->second);
-    }
-  }
-  frames_.push_back(std::move(frame));
-}
-
-int OgHttp2Session::Send() {
-  if (sending_) {
-    QUICHE_VLOG(1) << TracePerspectiveAsString(options_.perspective)
-                   << " returning early; already sending.";
-    return 0;
-  }
-  sending_ = true;
-  RunOnExit r{[this]() { sending_ = false; }};
-
-  if (fatal_send_error_) {
-    return kSendError;
-  }
-
-  MaybeSetupPreface(/*sending_outbound_settings=*/false);
-
-  SendResult continue_writing = SendQueuedFrames();
-  if (queued_immediate_goaway_) {
-    // If an immediate GOAWAY was queued, then the above flush either sent the
-    // GOAWAY or buffered it to be sent on the next successful flush. In either
-    // case, return early here to avoid sending other frames.
-    return InterpretSendResult(continue_writing);
-  }
-  while (continue_writing == SendResult::SEND_OK &&
-         !connection_metadata_.empty()) {
-    continue_writing = SendMetadata(0, connection_metadata_);
-  }
-  // Wake streams for writes.
-  while (continue_writing == SendResult::SEND_OK && HasReadyStream()) {
-    const Http2StreamId stream_id = GetNextReadyStream();
-    // TODO(birenroy): Add a return value to indicate write blockage, so streams
-    // aren't woken unnecessarily.
-    QUICHE_VLOG(1) << "Waking stream " << stream_id << " for writes.";
-    continue_writing = WriteForStream(stream_id);
-  }
-  if (continue_writing == SendResult::SEND_OK) {
-    continue_writing = SendQueuedFrames();
-  }
-  return InterpretSendResult(continue_writing);
-}
-
-int OgHttp2Session::InterpretSendResult(SendResult result) {
-  if (result == SendResult::SEND_ERROR) {
-    fatal_send_error_ = true;
-    return kSendError;
-  } else {
-    return 0;
-  }
-}
-
-bool OgHttp2Session::HasReadyStream() const {
-  return !metadata_ready_.empty() || !trailers_ready_.empty() ||
-         (write_scheduler_.HasReadyStreams() && connection_send_window_ > 0);
-}
-
-Http2StreamId OgHttp2Session::GetNextReadyStream() {
-  QUICHE_DCHECK(HasReadyStream());
-  if (!metadata_ready_.empty()) {
-    const Http2StreamId stream_id = *metadata_ready_.begin();
-    // WriteForStream() will re-mark the stream as ready, if necessary.
-    write_scheduler_.MarkStreamNotReady(stream_id);
-    return stream_id;
-  }
-  if (!trailers_ready_.empty()) {
-    const Http2StreamId stream_id = *trailers_ready_.begin();
-    // WriteForStream() will re-mark the stream as ready, if necessary.
-    write_scheduler_.MarkStreamNotReady(stream_id);
-    return stream_id;
-  }
-  return write_scheduler_.PopNextReadyStream();
-}
-
-OgHttp2Session::SendResult OgHttp2Session::MaybeSendBufferedData() {
-  int64_t result = std::numeric_limits<int64_t>::max();
-  while (result > 0 && !buffered_data_.empty()) {
-    result = visitor_.OnReadyToSend(buffered_data_);
-    if (result > 0) {
-      buffered_data_.erase(0, result);
-    }
-  }
-  if (result < 0) {
-    LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
-                        ConnectionError::kSendError);
-    return SendResult::SEND_ERROR;
-  }
-  return buffered_data_.empty() ? SendResult::SEND_OK
-                                : SendResult::SEND_BLOCKED;
-}
-
-OgHttp2Session::SendResult OgHttp2Session::SendQueuedFrames() {
-  // Flush any serialized prefix.
-  const SendResult result = MaybeSendBufferedData();
-  if (result != SendResult::SEND_OK) {
-    return result;
-  }
-  // Serialize and send frames in the queue.
-  while (!frames_.empty()) {
-    const auto& frame_ptr = frames_.front();
-    FrameAttributeCollector c;
-    frame_ptr->Visit(&c);
-
-    // DATA frames should never be queued.
-    QUICHE_DCHECK_NE(c.frame_type(), 0);
-
-    const bool stream_reset =
-        c.stream_id() != 0 && streams_reset_.count(c.stream_id()) > 0;
-    if (stream_reset &&
-        c.frame_type() != static_cast<uint8_t>(FrameType::RST_STREAM)) {
-      // The stream has been reset, so any other remaining frames can be
-      // skipped.
-      // TODO(birenroy): inform the visitor of frames that are skipped.
-      DecrementQueuedFrameCount(c.stream_id(), c.frame_type());
-      frames_.pop_front();
-      continue;
-    }
-    // Frames can't accurately report their own length; the actual serialized
-    // length must be used instead.
-    spdy::SpdySerializedFrame frame = framer_.SerializeFrame(*frame_ptr);
-    const size_t frame_payload_length = frame.size() - spdy::kFrameHeaderSize;
-    frame_ptr->Visit(&send_logger_);
-    visitor_.OnBeforeFrameSent(c.frame_type(), c.stream_id(),
-                               frame_payload_length, c.flags());
-    const int64_t result = visitor_.OnReadyToSend(absl::string_view(frame));
-    if (result < 0) {
-      LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
-                          ConnectionError::kSendError);
-      return SendResult::SEND_ERROR;
-    } else if (result == 0) {
-      // Write blocked.
-      return SendResult::SEND_BLOCKED;
-    } else {
-      frames_.pop_front();
-
-      const bool ok =
-          AfterFrameSent(c.frame_type(), c.stream_id(), frame_payload_length,
-                         c.flags(), c.error_code());
-      if (!ok) {
-        LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
-                            ConnectionError::kSendError);
-        return SendResult::SEND_ERROR;
-      }
-      if (static_cast<size_t>(result) < frame.size()) {
-        // The frame was partially written, so the rest must be buffered.
-        buffered_data_.append(frame.data() + result, frame.size() - result);
-        return SendResult::SEND_BLOCKED;
-      }
-    }
-  }
-  return SendResult::SEND_OK;
-}
-
-bool OgHttp2Session::AfterFrameSent(uint8_t frame_type_int, uint32_t stream_id,
-                                    size_t payload_length, uint8_t flags,
-                                    uint32_t error_code) {
-  const FrameType frame_type = static_cast<FrameType>(frame_type_int);
-  int result = visitor_.OnFrameSent(frame_type_int, stream_id, payload_length,
-                                    flags, error_code);
-  if (result < 0) {
-    return false;
-  }
-  if (stream_id == 0) {
-    if (frame_type == FrameType::SETTINGS) {
-      const bool is_settings_ack = (flags & 0x01);
-      if (is_settings_ack && encoder_header_table_capacity_when_acking_) {
-        framer_.UpdateHeaderEncoderTableSize(
-            encoder_header_table_capacity_when_acking_.value());
-        encoder_header_table_capacity_when_acking_ = absl::nullopt;
-      } else if (!is_settings_ack) {
-        sent_non_ack_settings_ = true;
-      }
-    }
-    return true;
-  }
-
-  const bool contains_fin =
-      (frame_type == FrameType::DATA || frame_type == FrameType::HEADERS) &&
-      (flags & 0x01) == 0x01;
-  auto it = stream_map_.find(stream_id);
-  const bool still_open_remote =
-      it != stream_map_.end() && !it->second.half_closed_remote;
-  if (contains_fin && still_open_remote &&
-      options_.rst_stream_no_error_when_incomplete && IsServerSession()) {
-    // Since the peer has not yet ended the stream, this endpoint should
-    // send a RST_STREAM NO_ERROR. See RFC 7540 Section 8.1.
-    frames_.push_front(absl::make_unique<spdy::SpdyRstStreamIR>(
-        stream_id, spdy::SpdyErrorCode::ERROR_CODE_NO_ERROR));
-    auto queued_result = queued_frames_.insert({stream_id, 1});
-    if (!queued_result.second) {
-      ++(queued_result.first->second);
-    }
-    it->second.half_closed_remote = true;
-  }
-
-  DecrementQueuedFrameCount(stream_id, frame_type_int);
-  return true;
-}
-
-OgHttp2Session::SendResult OgHttp2Session::WriteForStream(
-    Http2StreamId stream_id) {
-  auto it = stream_map_.find(stream_id);
-  if (it == stream_map_.end()) {
-    QUICHE_LOG(ERROR) << "Can't find stream " << stream_id
-                      << " which is ready to write!";
-    return SendResult::SEND_OK;
-  }
-  StreamState& state = it->second;
-  auto reset_it = streams_reset_.find(stream_id);
-  if (reset_it != streams_reset_.end()) {
-    // The stream has been reset; there's no point in sending DATA or trailing
-    // HEADERS.
-    state.outbound_body = nullptr;
-    state.trailers = nullptr;
-    state.outbound_metadata.clear();
-    return SendResult::SEND_OK;
-  }
-  SendResult connection_can_write = SendResult::SEND_OK;
-  if (!state.outbound_metadata.empty()) {
-    connection_can_write = SendMetadata(stream_id, state.outbound_metadata);
-  }
-
-  if (state.outbound_body == nullptr ||
-      (!options_.trailers_require_end_data && state.data_deferred)) {
-    // No data to send, but there might be trailers.
-    if (state.trailers != nullptr) {
-      // Trailers will include END_STREAM, so the data source can be discarded.
-      // Since data_deferred is true, there is no data waiting to be flushed for
-      // this stream.
-      state.outbound_body = nullptr;
-      auto block_ptr = std::move(state.trailers);
-      if (state.half_closed_local) {
-        QUICHE_LOG(ERROR) << "Sent fin; can't send trailers.";
-      } else {
-        SendTrailers(stream_id, std::move(*block_ptr));
-      }
-    }
-    return SendResult::SEND_OK;
-  }
-  int32_t available_window =
-      std::min({connection_send_window_, state.send_window,
-                static_cast<int32_t>(max_frame_payload_)});
-  while (connection_can_write == SendResult::SEND_OK && available_window > 0 &&
-         state.outbound_body != nullptr && !state.data_deferred) {
-    auto [length, end_data] =
-        state.outbound_body->SelectPayloadLength(available_window);
-    QUICHE_VLOG(2) << "WriteForStream | length: " << length
-                   << " end_data: " << end_data
-                   << " trailers: " << state.trailers.get();
-    if (length == 0 && !end_data &&
-        (options_.trailers_require_end_data || state.trailers == nullptr)) {
-      // An unproductive call to SelectPayloadLength() results in this stream
-      // entering the "deferred" state only if either no trailers are available
-      // to send, or trailers require an explicit end_data before being sent.
-      state.data_deferred = true;
-      break;
-    } else if (length == DataFrameSource::kError) {
-      // TODO(birenroy): Consider queuing a RST_STREAM INTERNAL_ERROR instead.
-      CloseStream(stream_id, Http2ErrorCode::INTERNAL_ERROR);
-      // No more work on the stream; it has been closed.
-      break;
-    }
-    const bool fin = end_data ? state.outbound_body->send_fin() : false;
-    if (length > 0 || fin) {
-      spdy::SpdyDataIR data(stream_id);
-      data.set_fin(fin);
-      data.SetDataShallow(length);
-      spdy::SpdySerializedFrame header =
-          spdy::SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
-              data);
-      QUICHE_DCHECK(buffered_data_.empty() && frames_.empty());
-      const bool success =
-          state.outbound_body->Send(absl::string_view(header), length);
-      if (!success) {
-        connection_can_write = SendResult::SEND_BLOCKED;
-        break;
-      }
-      connection_send_window_ -= length;
-      state.send_window -= length;
-      available_window = std::min({connection_send_window_, state.send_window,
-                                   static_cast<int32_t>(max_frame_payload_)});
-      if (fin) {
-        state.half_closed_local = true;
-        MaybeFinWithRstStream(it);
-      }
-      const bool ok =
-          AfterFrameSent(/* DATA */ 0, stream_id, length, fin ? 0x1 : 0x0, 0);
-      if (!ok) {
-        LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
-                            ConnectionError::kSendError);
-        return SendResult::SEND_ERROR;
-      }
-      if (!stream_map_.contains(stream_id)) {
-        // Note: the stream may have been closed if `fin` is true.
-        break;
-      }
-    }
-    if (end_data || (length == 0 && state.trailers != nullptr &&
-                     !options_.trailers_require_end_data)) {
-      // If SelectPayloadLength() returned {0, false}, and there are trailers to
-      // send, and the safety feature is disabled, it's okay to send the
-      // trailers.
-      if (state.trailers != nullptr) {
-        auto block_ptr = std::move(state.trailers);
-        if (fin) {
-          QUICHE_LOG(ERROR) << "Sent fin; can't send trailers.";
-        } else {
-          SendTrailers(stream_id, std::move(*block_ptr));
-        }
-      }
-      state.outbound_body = nullptr;
-    }
-  }
-  // If the stream still exists and has data to send, it should be marked as
-  // ready in the write scheduler.
-  if (stream_map_.contains(stream_id) && !state.data_deferred &&
-      state.send_window > 0 && state.outbound_body != nullptr) {
-    write_scheduler_.MarkStreamReady(stream_id, false);
-  }
-  // Streams can continue writing as long as the connection is not write-blocked
-  // and there is additional flow control quota available.
-  if (connection_can_write != SendResult::SEND_OK) {
-    return connection_can_write;
-  }
-  return connection_send_window_ <= 0 ? SendResult::SEND_BLOCKED
-                                      : SendResult::SEND_OK;
-}
-
-OgHttp2Session::SendResult OgHttp2Session::SendMetadata(
-    Http2StreamId stream_id, OgHttp2Session::MetadataSequence& sequence) {
-  const uint32_t max_payload_size =
-      std::min(kMaxAllowedMetadataFrameSize, max_frame_payload_);
-  auto payload_buffer = absl::make_unique<uint8_t[]>(max_payload_size);
-  while (!sequence.empty()) {
-    MetadataSource& source = *sequence.front();
-
-    auto [written, end_metadata] =
-        source.Pack(payload_buffer.get(), max_payload_size);
-    if (written < 0) {
-      // Did not touch the connection, so perhaps writes are still possible.
-      return SendResult::SEND_OK;
-    }
-    QUICHE_DCHECK_LE(static_cast<size_t>(written), max_payload_size);
-    auto payload = absl::string_view(
-        reinterpret_cast<const char*>(payload_buffer.get()), written);
-    EnqueueFrame(absl::make_unique<spdy::SpdyUnknownIR>(
-        stream_id, kMetadataFrameType, end_metadata ? kMetadataEndFlag : 0u,
-        std::string(payload)));
-    if (end_metadata) {
-      sequence.erase(sequence.begin());
-      metadata_ready_.erase(stream_id);
-    }
-  }
-  return SendQueuedFrames();
-}
-
-int32_t OgHttp2Session::SubmitRequest(
-    absl::Span<const Header> headers,
-    std::unique_ptr<DataFrameSource> data_source, void* user_data) {
-  // TODO(birenroy): return an error for the incorrect perspective
-  const Http2StreamId stream_id = next_stream_id_;
-  next_stream_id_ += 2;
-  if (!pending_streams_.empty() || !CanCreateStream()) {
-    // TODO(diannahu): There should probably be a limit to the number of allowed
-    // pending streams.
-    pending_streams_.insert(
-        {stream_id, PendingStreamState{ToHeaderBlock(headers),
-                                       std::move(data_source), user_data}});
-    StartPendingStreams();
-  } else {
-    StartRequest(stream_id, ToHeaderBlock(headers), std::move(data_source),
-                 user_data);
-  }
-  return stream_id;
-}
-
-int OgHttp2Session::SubmitResponse(
-    Http2StreamId stream_id, absl::Span<const Header> headers,
-    std::unique_ptr<DataFrameSource> data_source) {
-  // TODO(birenroy): return an error for the incorrect perspective
-  auto iter = stream_map_.find(stream_id);
-  if (iter == stream_map_.end()) {
-    QUICHE_LOG(ERROR) << "Unable to find stream " << stream_id;
-    return -501;  // NGHTTP2_ERR_INVALID_ARGUMENT
-  }
-  const bool end_stream = data_source == nullptr;
-  if (!end_stream) {
-    // Add data source to stream state
-    iter->second.outbound_body = std::move(data_source);
-    write_scheduler_.MarkStreamReady(stream_id, false);
-  }
-  SendHeaders(stream_id, ToHeaderBlock(headers), end_stream);
-  return 0;
-}
-
-int OgHttp2Session::SubmitTrailer(Http2StreamId stream_id,
-                                  absl::Span<const Header> trailers) {
-  // TODO(birenroy): Reject trailers when acting as a client?
-  auto iter = stream_map_.find(stream_id);
-  if (iter == stream_map_.end()) {
-    QUICHE_LOG(ERROR) << "Unable to find stream " << stream_id;
-    return -501;  // NGHTTP2_ERR_INVALID_ARGUMENT
-  }
-  StreamState& state = iter->second;
-  if (state.half_closed_local) {
-    QUICHE_LOG(ERROR) << "Stream " << stream_id << " is half closed (local)";
-    return -514;  // NGHTTP2_ERR_INVALID_STREAM_STATE
-  }
-  if (state.trailers != nullptr) {
-    QUICHE_LOG(ERROR) << "Stream " << stream_id
-                      << " already has trailers queued";
-    return -514;  // NGHTTP2_ERR_INVALID_STREAM_STATE
-  }
-  if (state.outbound_body == nullptr) {
-    // Enqueue trailers immediately.
-    SendTrailers(stream_id, ToHeaderBlock(trailers));
-  } else {
-    QUICHE_LOG_IF(ERROR, state.outbound_body->send_fin())
-        << "DataFrameSource will send fin, preventing trailers!";
-    // Save trailers so they can be written once data is done.
-    state.trailers =
-        absl::make_unique<spdy::SpdyHeaderBlock>(ToHeaderBlock(trailers));
-    if (!options_.trailers_require_end_data || !iter->second.data_deferred) {
-      trailers_ready_.insert(stream_id);
-    }
-  }
-  return 0;
-}
-
-void OgHttp2Session::SubmitMetadata(Http2StreamId stream_id,
-                                    std::unique_ptr<MetadataSource> source) {
-  if (stream_id == 0) {
-    connection_metadata_.push_back(std::move(source));
-  } else {
-    auto iter = CreateStream(stream_id);
-    iter->second.outbound_metadata.push_back(std::move(source));
-    metadata_ready_.insert(stream_id);
-  }
-}
-
-void OgHttp2Session::SubmitSettings(absl::Span<const Http2Setting> settings) {
-  auto frame = PrepareSettingsFrame(settings);
-  EnqueueFrame(std::move(frame));
-}
-
-void OgHttp2Session::OnError(SpdyFramerError error,
-                             std::string detailed_error) {
-  QUICHE_VLOG(1) << "Error: "
-                 << http2::Http2DecoderAdapter::SpdyFramerErrorToString(error)
-                 << " details: " << detailed_error;
-  // TODO(diannahu): Consider propagating `detailed_error`.
-  LatchErrorAndNotify(GetHttp2ErrorCode(error), ConnectionError::kParseError);
-}
-
-void OgHttp2Session::OnCommonHeader(spdy::SpdyStreamId stream_id,
-                                    size_t length,
-                                    uint8_t type,
-                                    uint8_t flags) {
-  highest_received_stream_id_ = std::max(static_cast<Http2StreamId>(stream_id),
-                                         highest_received_stream_id_);
-  if (streams_reset_.contains(stream_id)) {
-    return;
-  }
-  const bool result = visitor_.OnFrameHeader(stream_id, length, type, flags);
-  if (!result) {
-    fatal_visitor_callback_failure_ = true;
-    decoder_.StopProcessing();
-  }
-}
-
-void OgHttp2Session::OnDataFrameHeader(spdy::SpdyStreamId stream_id,
-                                       size_t length, bool /*fin*/) {
-  auto iter = stream_map_.find(stream_id);
-  if (iter == stream_map_.end() || streams_reset_.contains(stream_id)) {
-    // The stream does not exist; it could be an error or a benign close, e.g.,
-    // getting data for a stream this connection recently closed.
-    if (static_cast<Http2StreamId>(stream_id) > highest_processed_stream_id_) {
-      // Receiving DATA before HEADERS is a connection error.
-      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                          ConnectionError::kWrongFrameSequence);
-    }
-    return;
-  }
-
-  if (static_cast<int64_t>(length) >
-      connection_window_manager_.CurrentWindowSize()) {
-    // Peer exceeded the connection flow control limit.
-    LatchErrorAndNotify(
-        Http2ErrorCode::FLOW_CONTROL_ERROR,
-        Http2VisitorInterface::ConnectionError::kFlowControlError);
-    return;
-  }
-
-  if (static_cast<int64_t>(length) >
-      iter->second.window_manager.CurrentWindowSize()) {
-    // Peer exceeded the stream flow control limit.
-    EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-        stream_id, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
-    return;
-  }
-
-  const bool result = visitor_.OnBeginDataForStream(stream_id, length);
-  if (!result) {
-    fatal_visitor_callback_failure_ = true;
-    decoder_.StopProcessing();
-  }
-
-  if (!iter->second.can_receive_body && length > 0) {
-    EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-        stream_id, spdy::ERROR_CODE_PROTOCOL_ERROR));
-    return;
-  }
-
-  // Validate against the content-length if it exists.
-  if (iter->second.remaining_content_length.has_value()) {
-    if (length > *iter->second.remaining_content_length) {
-      HandleContentLengthError(stream_id);
-      iter->second.remaining_content_length.reset();
-    } else {
-      *iter->second.remaining_content_length -= length;
-    }
-  }
-}
-
-void OgHttp2Session::OnStreamFrameData(spdy::SpdyStreamId stream_id,
-                                       const char* data,
-                                       size_t len) {
-  // Count the data against flow control, even if the stream is unknown.
-  MarkDataBuffered(stream_id, len);
-
-  if (!stream_map_.contains(stream_id) || streams_reset_.contains(stream_id)) {
-    // If the stream was unknown due to a protocol error, the visitor was
-    // informed in OnDataFrameHeader().
-    return;
-  }
-
-  const bool result =
-      visitor_.OnDataForStream(stream_id, absl::string_view(data, len));
-  if (!result) {
-    fatal_visitor_callback_failure_ = true;
-    decoder_.StopProcessing();
-  }
-}
-
-void OgHttp2Session::OnStreamEnd(spdy::SpdyStreamId stream_id) {
-  auto iter = stream_map_.find(stream_id);
-  if (iter != stream_map_.end()) {
-    iter->second.half_closed_remote = true;
-    if (streams_reset_.contains(stream_id)) {
-      return;
-    }
-
-    // Validate against the content-length if it exists.
-    if (iter->second.remaining_content_length.has_value() &&
-        *iter->second.remaining_content_length != 0) {
-      HandleContentLengthError(stream_id);
-      return;
-    }
-
-    visitor_.OnEndStream(stream_id);
-  }
-
-  auto queued_frames_iter = queued_frames_.find(stream_id);
-  const bool no_queued_frames = queued_frames_iter == queued_frames_.end() ||
-                                queued_frames_iter->second == 0;
-  if (iter != stream_map_.end() && iter->second.half_closed_local &&
-      !IsServerSession() && no_queued_frames) {
-    // From the client's perspective, the stream can be closed if it's already
-    // half_closed_local.
-    CloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR);
-  }
-}
-
-void OgHttp2Session::OnStreamPadLength(spdy::SpdyStreamId stream_id,
-                                       size_t value) {
-  bool result = visitor_.OnDataPaddingLength(stream_id, 1 + value);
-  if (!result) {
-    fatal_visitor_callback_failure_ = true;
-    decoder_.StopProcessing();
-  }
-  MarkDataBuffered(stream_id, 1 + value);
-}
-
-void OgHttp2Session::OnStreamPadding(spdy::SpdyStreamId /*stream_id*/, size_t
-                                     /*len*/) {
-  // Flow control was accounted for in OnStreamPadLength().
-  // TODO(181586191): Pass padding to the visitor?
-}
-
-spdy::SpdyHeadersHandlerInterface* OgHttp2Session::OnHeaderFrameStart(
-    spdy::SpdyStreamId stream_id) {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end() && !streams_reset_.contains(stream_id)) {
-    headers_handler_.set_stream_id(stream_id);
-    headers_handler_.set_header_type(
-        NextHeaderType(it->second.received_header_type));
-    return &headers_handler_;
-  } else {
-    return &noop_headers_handler_;
-  }
-}
-
-void OgHttp2Session::OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) {
-  auto it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    if (headers_handler_.header_type() == HeaderType::RESPONSE &&
-        !headers_handler_.status_header().empty() &&
-        headers_handler_.status_header()[0] == '1') {
-      // If response headers carried a 1xx response code, final response headers
-      // should still be forthcoming.
-      headers_handler_.set_header_type(HeaderType::RESPONSE_100);
-    }
-    it->second.received_header_type = headers_handler_.header_type();
-
-    // Track the content-length if the headers indicate that a body can follow.
-    it->second.can_receive_body = headers_handler_.CanReceiveBody();
-    if (it->second.can_receive_body) {
-      it->second.remaining_content_length = headers_handler_.content_length();
-    }
-
-    headers_handler_.set_stream_id(0);
-  }
-}
-
-void OgHttp2Session::OnRstStream(spdy::SpdyStreamId stream_id,
-                                 spdy::SpdyErrorCode error_code) {
-  auto iter = stream_map_.find(stream_id);
-  if (iter != stream_map_.end()) {
-    iter->second.half_closed_remote = true;
-    iter->second.outbound_body = nullptr;
-  } else if (static_cast<Http2StreamId>(stream_id) >
-             highest_processed_stream_id_) {
-    // Receiving RST_STREAM before HEADERS is a connection error.
-    LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                        ConnectionError::kWrongFrameSequence);
-    return;
-  }
-  if (streams_reset_.contains(stream_id)) {
-    return;
-  }
-  visitor_.OnRstStream(stream_id, TranslateErrorCode(error_code));
-  // TODO(birenroy): Consider whether there are outbound frames queued for the
-  // stream.
-  CloseStream(stream_id, TranslateErrorCode(error_code));
-}
-
-void OgHttp2Session::OnSettings() {
-  visitor_.OnSettingsStart();
-  auto settings = absl::make_unique<SpdySettingsIR>();
-  settings->set_is_ack(true);
-  EnqueueFrame(std::move(settings));
-}
-
-void OgHttp2Session::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
-  switch (id) {
-    case MAX_FRAME_SIZE:
-      max_frame_payload_ = value;
-      break;
-    case MAX_CONCURRENT_STREAMS:
-      max_outbound_concurrent_streams_ = value;
-      break;
-    case HEADER_TABLE_SIZE:
-      value = std::min(value, HpackCapacityBound(options_));
-      if (value < framer_.GetHpackEncoder()->CurrentHeaderTableSizeSetting()) {
-        // Safe to apply a smaller table capacity immediately.
-        QUICHE_VLOG(2) << TracePerspectiveAsString(options_.perspective)
-                       << " applying encoder table capacity " << value;
-        framer_.GetHpackEncoder()->ApplyHeaderTableSizeSetting(value);
-      } else {
-        QUICHE_VLOG(2)
-            << TracePerspectiveAsString(options_.perspective)
-            << " NOT applying encoder table capacity until writing ack: "
-            << value;
-        encoder_header_table_capacity_when_acking_ = value;
-      }
-      break;
-    case INITIAL_WINDOW_SIZE:
-      if (value > spdy::kSpdyMaximumWindowSize) {
-        visitor_.OnInvalidFrame(
-            0, Http2VisitorInterface::InvalidFrameError::kFlowControl);
-        // The specification says this is a connection-level flow control error.
-        LatchErrorAndNotify(
-            Http2ErrorCode::FLOW_CONTROL_ERROR,
-            Http2VisitorInterface::ConnectionError::kFlowControlError);
-        return;
-      } else {
-        UpdateStreamSendWindowSizes(value);
-      }
-      break;
-    default:
-      // TODO(bnc): See if C++17 inline constants are allowed in QUICHE.
-      if (id == kMetadataExtensionId) {
-        peer_supports_metadata_ = (value != 0);
-      } else {
-        QUICHE_VLOG(1) << "Unimplemented SETTING id: " << id;
-      }
-  }
-  visitor_.OnSetting({id, value});
-}
-
-void OgHttp2Session::OnSettingsEnd() {
-  visitor_.OnSettingsEnd();
-}
-
-void OgHttp2Session::OnSettingsAck() {
-  if (!settings_ack_callbacks_.empty()) {
-    SettingsAckCallback callback = std::move(settings_ack_callbacks_.front());
-    settings_ack_callbacks_.pop_front();
-    callback();
-  }
-
-  visitor_.OnSettingsAck();
-}
-
-void OgHttp2Session::OnPing(spdy::SpdyPingId unique_id, bool is_ack) {
-  visitor_.OnPing(unique_id, is_ack);
-  if (options_.auto_ping_ack && !is_ack) {
-    auto ping = absl::make_unique<spdy::SpdyPingIR>(unique_id);
-    ping->set_is_ack(true);
-    EnqueueFrame(std::move(ping));
-  }
-}
-
-void OgHttp2Session::OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
-                              spdy::SpdyErrorCode error_code) {
-  received_goaway_ = true;
-  const bool result = visitor_.OnGoAway(last_accepted_stream_id,
-                                        TranslateErrorCode(error_code), "");
-  if (!result) {
-    fatal_visitor_callback_failure_ = true;
-    decoder_.StopProcessing();
-  }
-}
-
-bool OgHttp2Session::OnGoAwayFrameData(const char* /*goaway_data*/, size_t
-                                       /*len*/) {
-  // Opaque data is currently ignored.
-  return true;
-}
-
-void OgHttp2Session::OnHeaders(spdy::SpdyStreamId stream_id,
-                               bool /*has_priority*/, int /*weight*/,
-                               spdy::SpdyStreamId /*parent_stream_id*/,
-                               bool /*exclusive*/, bool fin, bool /*end*/) {
-  if (stream_id % 2 == 0) {
-    // Server push is disabled; receiving push HEADERS is a connection error.
-    LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                        ConnectionError::kInvalidNewStreamId);
-    return;
-  }
-  if (fin) {
-    headers_handler_.set_frame_contains_fin();
-  }
-  if (IsServerSession()) {
-    const auto new_stream_id = static_cast<Http2StreamId>(stream_id);
-    if (stream_map_.find(new_stream_id) != stream_map_.end() && fin) {
-      // Not a new stream, must be trailers.
-      return;
-    }
-    if (new_stream_id <= highest_processed_stream_id_) {
-      // A new stream ID lower than the watermark is a connection error.
-      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                          ConnectionError::kInvalidNewStreamId);
-      return;
-    }
-
-    if (stream_map_.size() >= max_inbound_concurrent_streams_) {
-      // The new stream would exceed our advertised and acknowledged
-      // MAX_CONCURRENT_STREAMS. For parity with nghttp2, treat this error as a
-      // connection-level PROTOCOL_ERROR.
-      bool ok = visitor_.OnInvalidFrame(
-          stream_id, Http2VisitorInterface::InvalidFrameError::kProtocol);
-      if (!ok) {
-        fatal_visitor_callback_failure_ = true;
-      }
-      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                          ConnectionError::kExceededMaxConcurrentStreams);
-      return;
-    }
-    if (stream_map_.size() >= pending_max_inbound_concurrent_streams_) {
-      // The new stream would exceed our advertised but unacked
-      // MAX_CONCURRENT_STREAMS. Refuse the stream for parity with nghttp2.
-      EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-          stream_id, spdy::ERROR_CODE_REFUSED_STREAM));
-      const bool ok = visitor_.OnInvalidFrame(
-          stream_id, Http2VisitorInterface::InvalidFrameError::kRefusedStream);
-      if (!ok) {
-        fatal_visitor_callback_failure_ = true;
-        LatchErrorAndNotify(Http2ErrorCode::REFUSED_STREAM,
-                            ConnectionError::kExceededMaxConcurrentStreams);
-      }
-      return;
-    }
-
-    CreateStream(stream_id);
-  }
-}
-
-void OgHttp2Session::OnWindowUpdate(spdy::SpdyStreamId stream_id,
-                                    int delta_window_size) {
-  if (stream_id == 0) {
-    connection_send_window_ += delta_window_size;
-  } else {
-    auto it = stream_map_.find(stream_id);
-    if (it == stream_map_.end()) {
-      QUICHE_VLOG(1) << "Stream " << stream_id << " not found!";
-      if (static_cast<Http2StreamId>(stream_id) >
-          highest_processed_stream_id_) {
-        // Receiving WINDOW_UPDATE before HEADERS is a connection error.
-        LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                            ConnectionError::kWrongFrameSequence);
-      }
-      // Do not inform the visitor of a WINDOW_UPDATE for a non-existent stream.
-      return;
-    } else {
-      if (streams_reset_.contains(stream_id)) {
-        return;
-      }
-      if (it->second.send_window == 0) {
-        // The stream was blocked on flow control.
-        QUICHE_VLOG(1) << "Marking stream " << stream_id << " ready to write.";
-        write_scheduler_.MarkStreamReady(stream_id, false);
-      }
-      it->second.send_window += delta_window_size;
-    }
-  }
-  visitor_.OnWindowUpdate(stream_id, delta_window_size);
-}
-
-void OgHttp2Session::OnPushPromise(spdy::SpdyStreamId /*stream_id*/,
-                                   spdy::SpdyStreamId /*promised_stream_id*/,
-                                   bool /*end*/) {
-  // Server push is disabled; PUSH_PROMISE is an invalid frame.
-  LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
-                      ConnectionError::kInvalidPushPromise);
-}
-
-void OgHttp2Session::OnContinuation(spdy::SpdyStreamId /*stream_id*/, bool
-                                    /*end*/) {}
-
-void OgHttp2Session::OnAltSvc(spdy::SpdyStreamId /*stream_id*/,
-                              absl::string_view /*origin*/,
-                              const spdy::SpdyAltSvcWireFormat::
-                                  AlternativeServiceVector& /*altsvc_vector*/) {
-}
-
-void OgHttp2Session::OnPriority(spdy::SpdyStreamId /*stream_id*/,
-                                spdy::SpdyStreamId /*parent_stream_id*/,
-                                int /*weight*/, bool /*exclusive*/) {}
-
-void OgHttp2Session::OnPriorityUpdate(
-    spdy::SpdyStreamId /*prioritized_stream_id*/,
-    absl::string_view /*priority_field_value*/) {}
-
-bool OgHttp2Session::OnUnknownFrame(spdy::SpdyStreamId /*stream_id*/,
-                                    uint8_t /*frame_type*/) {
-  return true;
-}
-
-void OgHttp2Session::OnHeaderStatus(
-    Http2StreamId stream_id, Http2VisitorInterface::OnHeaderResult result) {
-  QUICHE_DCHECK_NE(result, Http2VisitorInterface::HEADER_OK);
-  QUICHE_VLOG(1) << "OnHeaderStatus(stream_id=" << stream_id
-                 << ", result=" << result << ")";
-  const bool should_reset_stream =
-      result == Http2VisitorInterface::HEADER_RST_STREAM ||
-      result == Http2VisitorInterface::HEADER_FIELD_INVALID ||
-      result == Http2VisitorInterface::HEADER_HTTP_MESSAGING;
-  if (should_reset_stream) {
-    const Http2ErrorCode error_code =
-        (result == Http2VisitorInterface::HEADER_RST_STREAM)
-            ? Http2ErrorCode::INTERNAL_ERROR
-            : Http2ErrorCode::PROTOCOL_ERROR;
-    const spdy::SpdyErrorCode spdy_error_code = TranslateErrorCode(error_code);
-    const Http2VisitorInterface::InvalidFrameError frame_error =
-        (result == Http2VisitorInterface::HEADER_RST_STREAM ||
-         result == Http2VisitorInterface::HEADER_FIELD_INVALID)
-            ? Http2VisitorInterface::InvalidFrameError::kHttpHeader
-            : Http2VisitorInterface::InvalidFrameError::kHttpMessaging;
-    auto it = streams_reset_.find(stream_id);
-    if (it == streams_reset_.end()) {
-      EnqueueFrame(
-          absl::make_unique<spdy::SpdyRstStreamIR>(stream_id, spdy_error_code));
-
-      if (result == Http2VisitorInterface::HEADER_FIELD_INVALID ||
-          result == Http2VisitorInterface::HEADER_HTTP_MESSAGING) {
-        const bool ok = visitor_.OnInvalidFrame(stream_id, frame_error);
-        if (!ok) {
-          fatal_visitor_callback_failure_ = true;
-          LatchErrorAndNotify(error_code, ConnectionError::kHeaderError);
-        }
-      }
-    }
-  } else if (result == Http2VisitorInterface::HEADER_CONNECTION_ERROR) {
-    fatal_visitor_callback_failure_ = true;
-    LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
-                        ConnectionError::kHeaderError);
-  } else if (result == Http2VisitorInterface::HEADER_COMPRESSION_ERROR) {
-    LatchErrorAndNotify(Http2ErrorCode::COMPRESSION_ERROR,
-                        ConnectionError::kHeaderError);
-  }
-}
-
-bool OgHttp2Session::OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length,
-                                   uint8_t type, uint8_t flags) {
-  if (streams_reset_.contains(stream_id)) {
-    return false;
-  }
-  if (type == kMetadataFrameType) {
-    QUICHE_DCHECK_EQ(metadata_length_, 0u);
-    visitor_.OnBeginMetadataForStream(stream_id, length);
-    metadata_stream_id_ = stream_id;
-    metadata_length_ = length;
-    end_metadata_ = flags & kMetadataEndFlag;
-
-    // Empty metadata payloads will not trigger OnFramePayload(), so handle
-    // that possibility here.
-    MaybeHandleMetadataEndForStream(metadata_stream_id_);
-
-    return true;
-  } else {
-    QUICHE_DLOG(INFO) << "Unexpected frame type " << static_cast<int>(type)
-                      << " received by the extension visitor.";
-    return false;
-  }
-}
-
-void OgHttp2Session::OnFramePayload(const char* data, size_t len) {
-  if (streams_reset_.contains(metadata_stream_id_)) {
-    return;
-  }
-  if (metadata_length_ > 0) {
-    QUICHE_DCHECK_LE(len, metadata_length_);
-    const bool payload_success = visitor_.OnMetadataForStream(
-        metadata_stream_id_, absl::string_view(data, len));
-    if (payload_success) {
-      metadata_length_ -= len;
-      MaybeHandleMetadataEndForStream(metadata_stream_id_);
-    } else {
-      fatal_visitor_callback_failure_ = true;
-      decoder_.StopProcessing();
-    }
-  } else {
-    QUICHE_DLOG(INFO) << "Unexpected metadata payload for stream "
-                      << metadata_stream_id_;
-  }
-}
-
-void OgHttp2Session::MaybeSetupPreface(bool sending_outbound_settings) {
-  if (!queued_preface_) {
-    queued_preface_ = true;
-    if (!IsServerSession()) {
-      buffered_data_.assign(spdy::kHttp2ConnectionHeaderPrefix,
-                            spdy::kHttp2ConnectionHeaderPrefixSize);
-    }
-    if (!sending_outbound_settings) {
-      QUICHE_DCHECK(frames_.empty());
-      // First frame must be a non-ack SETTINGS.
-      EnqueueFrame(PrepareSettingsFrame(GetInitialSettings()));
-    }
-  }
-}
-
-std::vector<Http2Setting> OgHttp2Session::GetInitialSettings() const {
-  std::vector<Http2Setting> settings;
-  if (!IsServerSession()) {
-    // Disable server push. Note that server push from clients is already
-    // disabled, so the server does not need to send this disabling setting.
-    // TODO(diannahu): Consider applying server push disabling on SETTINGS ack.
-    settings.push_back({Http2KnownSettingsId::ENABLE_PUSH, 0});
-  }
-  if (options_.max_header_list_bytes) {
-    settings.push_back({Http2KnownSettingsId::MAX_HEADER_LIST_SIZE,
-                        *options_.max_header_list_bytes});
-  }
-  if (options_.allow_extended_connect && IsServerSession()) {
-    settings.push_back({Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u});
-  }
-  return settings;
-}
-
-std::unique_ptr<SpdySettingsIR> OgHttp2Session::PrepareSettingsFrame(
-    absl::Span<const Http2Setting> settings) {
-  auto settings_ir = absl::make_unique<SpdySettingsIR>();
-  for (const Http2Setting& setting : settings) {
-    settings_ir->AddSetting(setting.id, setting.value);
-  }
-  return settings_ir;
-}
-
-void OgHttp2Session::HandleOutboundSettings(
-    const spdy::SpdySettingsIR& settings_frame) {
-  for (const auto& [id, value] : settings_frame.values()) {
-    switch (static_cast<Http2KnownSettingsId>(id)) {
-      case MAX_CONCURRENT_STREAMS:
-        pending_max_inbound_concurrent_streams_ = value;
-        break;
-      case ENABLE_CONNECT_PROTOCOL:
-        if (value == 1u && IsServerSession()) {
-          // Allow extended CONNECT semantics even before SETTINGS are acked, to
-          // make things easier for clients.
-          headers_handler_.AllowConnect();
-        }
-        break;
-      case HEADER_TABLE_SIZE:
-      case ENABLE_PUSH:
-      case INITIAL_WINDOW_SIZE:
-      case MAX_FRAME_SIZE:
-      case MAX_HEADER_LIST_SIZE:
-        QUICHE_VLOG(2)
-            << "Not adjusting internal state for outbound setting with id "
-            << id;
-        break;
-    }
-  }
-
-  // Copy the (small) map of settings we are about to send so that we can set
-  // values in the SETTINGS ack callback.
-  settings_ack_callbacks_.push_back(
-      [this, settings_map = settings_frame.values()]() {
-        for (const auto& [id, value] : settings_map) {
-          switch (static_cast<Http2KnownSettingsId>(id)) {
-            case MAX_CONCURRENT_STREAMS:
-              max_inbound_concurrent_streams_ = value;
-              break;
-            case HEADER_TABLE_SIZE:
-              decoder_.GetHpackDecoder()->ApplyHeaderTableSizeSetting(value);
-              break;
-            case INITIAL_WINDOW_SIZE:
-              UpdateStreamReceiveWindowSizes(value);
-              initial_stream_receive_window_ = value;
-              break;
-            case MAX_FRAME_SIZE:
-              decoder_.SetMaxFrameSize(value);
-              break;
-            case ENABLE_PUSH:
-            case MAX_HEADER_LIST_SIZE:
-            case ENABLE_CONNECT_PROTOCOL:
-              QUICHE_VLOG(2)
-                  << "No action required in ack for outbound setting with id "
-                  << id;
-              break;
-          }
-        }
-      });
-}
-
-void OgHttp2Session::SendWindowUpdate(Http2StreamId stream_id,
-                                      size_t update_delta) {
-  EnqueueFrame(
-      absl::make_unique<spdy::SpdyWindowUpdateIR>(stream_id, update_delta));
-}
-
-void OgHttp2Session::SendHeaders(Http2StreamId stream_id,
-                                 spdy::SpdyHeaderBlock headers,
-                                 bool end_stream) {
-  auto frame =
-      absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(headers));
-  frame->set_fin(end_stream);
-  EnqueueFrame(std::move(frame));
-}
-
-void OgHttp2Session::SendTrailers(Http2StreamId stream_id,
-                                  spdy::SpdyHeaderBlock trailers) {
-  auto frame =
-      absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(trailers));
-  frame->set_fin(true);
-  EnqueueFrame(std::move(frame));
-  trailers_ready_.erase(stream_id);
-}
-
-void OgHttp2Session::MaybeFinWithRstStream(StreamStateMap::iterator iter) {
-  QUICHE_DCHECK(iter != stream_map_.end() && iter->second.half_closed_local);
-
-  if (options_.rst_stream_no_error_when_incomplete && IsServerSession() &&
-      !iter->second.half_closed_remote) {
-    // Since the peer has not yet ended the stream, this endpoint should
-    // send a RST_STREAM NO_ERROR. See RFC 7540 Section 8.1.
-    EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-        iter->first, spdy::SpdyErrorCode::ERROR_CODE_NO_ERROR));
-    iter->second.half_closed_remote = true;
-  }
-}
-
-void OgHttp2Session::MarkDataBuffered(Http2StreamId stream_id, size_t bytes) {
-  connection_window_manager_.MarkDataBuffered(bytes);
-  if (auto it = stream_map_.find(stream_id); it != stream_map_.end()) {
-    it->second.window_manager.MarkDataBuffered(bytes);
-  }
-}
-
-OgHttp2Session::StreamStateMap::iterator OgHttp2Session::CreateStream(
-    Http2StreamId stream_id) {
-  WindowManager::WindowUpdateListener listener =
-      [this, stream_id](size_t window_update_delta) {
-        SendWindowUpdate(stream_id, window_update_delta);
-      };
-  auto [iter, inserted] = stream_map_.try_emplace(
-      stream_id,
-      StreamState(initial_stream_receive_window_, initial_stream_send_window_,
-                  std::move(listener), options_.should_window_update_fn));
-  if (inserted) {
-    // Add the stream to the write scheduler.
-    const WriteScheduler::StreamPrecedenceType precedence(3);
-    write_scheduler_.RegisterStream(stream_id, precedence);
-
-    highest_processed_stream_id_ =
-        std::max(highest_processed_stream_id_, stream_id);
-  }
-  return iter;
-}
-
-void OgHttp2Session::StartRequest(Http2StreamId stream_id,
-                                  spdy::SpdyHeaderBlock headers,
-                                  std::unique_ptr<DataFrameSource> data_source,
-                                  void* user_data) {
-  auto iter = CreateStream(stream_id);
-  const bool end_stream = data_source == nullptr;
-  if (!end_stream) {
-    iter->second.outbound_body = std::move(data_source);
-    write_scheduler_.MarkStreamReady(stream_id, false);
-  }
-  iter->second.user_data = user_data;
-  SendHeaders(stream_id, std::move(headers), end_stream);
-}
-
-void OgHttp2Session::StartPendingStreams() {
-  while (!pending_streams_.empty() && CanCreateStream()) {
-    auto& [stream_id, pending_stream] = pending_streams_.front();
-    StartRequest(stream_id, std::move(pending_stream.headers),
-                 std::move(pending_stream.data_source),
-                 pending_stream.user_data);
-    pending_streams_.pop_front();
-  }
-}
-
-void OgHttp2Session::CloseStream(Http2StreamId stream_id,
-                                 Http2ErrorCode error_code) {
-  const bool result = visitor_.OnCloseStream(stream_id, error_code);
-  if (!result) {
-    latched_error_ = true;
-    decoder_.StopProcessing();
-  }
-  stream_map_.erase(stream_id);
-  trailers_ready_.erase(stream_id);
-  metadata_ready_.erase(stream_id);
-  streams_reset_.erase(stream_id);
-  queued_frames_.erase(stream_id);
-  stream_map_.erase(stream_id);
-  if (write_scheduler_.StreamRegistered(stream_id)) {
-    write_scheduler_.UnregisterStream(stream_id);
-  }
-
-  StartPendingStreams();
-}
-
-bool OgHttp2Session::CanCreateStream() const {
-  return stream_map_.size() < max_outbound_concurrent_streams_;
-}
-
-HeaderType OgHttp2Session::NextHeaderType(
-    absl::optional<HeaderType> current_type) {
-  if (IsServerSession()) {
-    if (!current_type) {
-      return HeaderType::REQUEST;
-    } else {
-      QUICHE_DCHECK(current_type == HeaderType::REQUEST);
-      return HeaderType::REQUEST_TRAILER;
-    }
-  } else if (!current_type ||
-             current_type.value() == HeaderType::RESPONSE_100) {
-    return HeaderType::RESPONSE;
-  } else {
-    return HeaderType::RESPONSE_TRAILER;
-  }
-}
-
-void OgHttp2Session::LatchErrorAndNotify(Http2ErrorCode error_code,
-                                         ConnectionError error) {
-  if (latched_error_) {
-    // Do not kick a connection when it is down.
-    return;
-  }
-
-  latched_error_ = true;
-  visitor_.OnConnectionError(error);
-  decoder_.StopProcessing();
-  EnqueueFrame(absl::make_unique<spdy::SpdyGoAwayIR>(
-      highest_processed_stream_id_, TranslateErrorCode(error_code),
-      ConnectionErrorToString(error)));
-}
-
-void OgHttp2Session::CloseStreamIfReady(uint8_t frame_type,
-                                        uint32_t stream_id) {
-  auto iter = stream_map_.find(stream_id);
-  if (iter == stream_map_.end()) {
-    return;
-  }
-  const StreamState& state = iter->second;
-  if (static_cast<FrameType>(frame_type) == FrameType::RST_STREAM ||
-      (state.half_closed_local && state.half_closed_remote)) {
-    CloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR);
-  }
-}
-
-void OgHttp2Session::PrepareForImmediateGoAway() {
-  queued_immediate_goaway_ = true;
-
-  // Keep the initial SETTINGS frame if the session has SETTINGS at the front of
-  // the queue but has not sent SETTINGS yet. The session should send initial
-  // SETTINGS before GOAWAY.
-  std::unique_ptr<spdy::SpdyFrameIR> initial_settings;
-  if (!sent_non_ack_settings_ && !frames_.empty() &&
-      IsNonAckSettings(*frames_.front())) {
-    initial_settings = std::move(frames_.front());
-    frames_.pop_front();
-  }
-
-  // Remove all pending frames except for RST_STREAMs. It is important to send
-  // RST_STREAMs so the peer knows of errors below the GOAWAY last stream ID.
-  // TODO(diannahu): Consider informing the visitor of dropped frames. This may
-  // mean keeping the frames and invoking a frame-not-sent callback, similar to
-  // nghttp2. Could add a closure to each frame in the frames queue.
-  frames_.remove_if([](const auto& frame) {
-    return frame->frame_type() != spdy::SpdyFrameType::RST_STREAM;
-  });
-
-  if (initial_settings != nullptr) {
-    frames_.push_front(std::move(initial_settings));
-  }
-}
-
-void OgHttp2Session::MaybeHandleMetadataEndForStream(Http2StreamId stream_id) {
-  if (metadata_length_ == 0 && end_metadata_) {
-    const bool completion_success = visitor_.OnMetadataEndForStream(stream_id);
-    if (!completion_success) {
-      fatal_visitor_callback_failure_ = true;
-      decoder_.StopProcessing();
-    }
-    metadata_stream_id_ = 0;
-    end_metadata_ = false;
-  }
-}
-
-void OgHttp2Session::DecrementQueuedFrameCount(uint32_t stream_id,
-                                               uint8_t frame_type) {
-  auto iter = queued_frames_.find(stream_id);
-  if (iter == queued_frames_.end()) {
-    QUICHE_LOG(ERROR) << "Unable to find a queued frame count for stream "
-                      << stream_id;
-    return;
-  }
-  if (static_cast<FrameType>(frame_type) != FrameType::DATA) {
-    --iter->second;
-  }
-  if (iter->second == 0) {
-    // TODO(birenroy): Consider passing through `error_code` here.
-    CloseStreamIfReady(frame_type, stream_id);
-  }
-}
-
-void OgHttp2Session::HandleContentLengthError(Http2StreamId stream_id) {
-  EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-      stream_id, spdy::ERROR_CODE_PROTOCOL_ERROR));
-}
-
-void OgHttp2Session::UpdateReceiveWindow(Http2StreamId stream_id,
-                                         int32_t delta) {
-  if (stream_id == 0) {
-    connection_window_manager_.IncreaseWindow(delta);
-  } else {
-    auto iter = stream_map_.find(stream_id);
-    if (iter != stream_map_.end()) {
-      iter->second.window_manager.IncreaseWindow(delta);
-    }
-  }
-}
-
-void OgHttp2Session::UpdateStreamSendWindowSizes(uint32_t new_value) {
-  const int32_t delta =
-      static_cast<int32_t>(new_value) - initial_stream_send_window_;
-  initial_stream_send_window_ = new_value;
-  for (auto& [stream_id, stream_state] : stream_map_) {
-    const int64_t current_window_size = stream_state.send_window;
-    const int64_t new_window_size = current_window_size + delta;
-    if (new_window_size > spdy::kSpdyMaximumWindowSize) {
-      EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
-          stream_id, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
-    } else {
-      stream_state.send_window += delta;
-    }
-    if (current_window_size <= 0 && new_window_size > 0) {
-      write_scheduler_.MarkStreamReady(stream_id, false);
-    }
-  }
-}
-
-void OgHttp2Session::UpdateStreamReceiveWindowSizes(uint32_t new_value) {
-  for (auto& [stream_id, stream_state] : stream_map_) {
-    stream_state.window_manager.OnWindowSizeLimitChange(new_value);
-  }
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/oghttp2_session.h b/http2/adapter/oghttp2_session.h
deleted file mode 100644
index e3771f8..0000000
--- a/http2/adapter/oghttp2_session.h
+++ /dev/null
@@ -1,552 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
-#define QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
-
-#include <cstdint>
-#include <limits>
-#include <list>
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "absl/types/variant.h"
-#include "http2/adapter/data_source.h"
-#include "http2/adapter/event_forwarder.h"
-#include "http2/adapter/header_validator.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_session.h"
-#include "http2/adapter/http2_util.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/adapter/window_manager.h"
-#include "http2/core/http2_trace_logging.h"
-#include "http2/core/priority_write_scheduler.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_linked_hash_map.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/no_op_headers_handler.h"
-#include "spdy/core/spdy_framer.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-
-// This class manages state associated with a single multiplexed HTTP/2 session.
-class QUICHE_EXPORT_PRIVATE OgHttp2Session
-    : public Http2Session,
-      public spdy::SpdyFramerVisitorInterface,
-      public spdy::ExtensionVisitorInterface {
- public:
-  struct QUICHE_EXPORT_PRIVATE Options {
-    // Returns whether to send a WINDOW_UPDATE based on the window limit, window
-    // size, and delta that would be sent in the WINDOW_UPDATE.
-    WindowManager::ShouldWindowUpdateFn should_window_update_fn =
-        DeltaAtLeastHalfLimit;
-    // The perspective of this session.
-    Perspective perspective = Perspective::kClient;
-    // The maximum HPACK table size to use.
-    absl::optional<size_t> max_hpack_encoding_table_capacity = absl::nullopt;
-    // The maximum number of decoded header bytes that a stream can receive.
-    absl::optional<uint32_t> max_header_list_bytes = absl::nullopt;
-    // The maximum size of an individual header field, including name and value.
-    absl::optional<uint32_t> max_header_field_size = absl::nullopt;
-    // Whether to automatically send PING acks when receiving a PING.
-    bool auto_ping_ack = true;
-    // Whether (as server) to send a RST_STREAM NO_ERROR when sending a fin on
-    // an incomplete stream.
-    bool rst_stream_no_error_when_incomplete = false;
-    // Whether (as server) to queue trailers until after a stream's data source
-    // has indicated the end of data. If false, the server will assume that
-    // submitting trailers indicates the end of data.
-    bool trailers_require_end_data = false;
-    // Whether to mark all input data as consumed upon encountering a connection
-    // error while processing bytes. If true, subsequent processing will also
-    // mark all input data as consumed.
-    bool blackhole_data_on_connection_error = true;
-    // Whether to advertise support for the extended CONNECT semantics described
-    // in RFC 8441. If true, this endpoint will send the appropriate setting in
-    // initial SETTINGS.
-    bool allow_extended_connect = true;
-  };
-
-  OgHttp2Session(Http2VisitorInterface& visitor, Options options);
-  ~OgHttp2Session() override;
-
-  // Enqueues a frame for transmission to the peer.
-  void EnqueueFrame(std::unique_ptr<spdy::SpdyFrameIR> frame);
-
-  // Starts a graceful shutdown sequence. No-op if a GOAWAY has already been
-  // sent.
-  void StartGracefulShutdown();
-
-  // Invokes the visitor's OnReadyToSend() method for serialized frames and
-  // DataFrameSource::Send() for data frames.
-  int Send();
-
-  int32_t SubmitRequest(absl::Span<const Header> headers,
-                        std::unique_ptr<DataFrameSource> data_source,
-                        void* user_data);
-  int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
-                     std::unique_ptr<DataFrameSource> data_source);
-  int SubmitTrailer(Http2StreamId stream_id, absl::Span<const Header> trailers);
-  void SubmitMetadata(Http2StreamId stream_id,
-                      std::unique_ptr<MetadataSource> source);
-  void SubmitSettings(absl::Span<const Http2Setting> settings);
-
-  bool IsServerSession() const {
-    return options_.perspective == Perspective::kServer;
-  }
-  Http2StreamId GetHighestReceivedStreamId() const {
-    return highest_received_stream_id_;
-  }
-  void SetStreamUserData(Http2StreamId stream_id, void* user_data);
-  void* GetStreamUserData(Http2StreamId stream_id);
-
-  // Resumes a stream that was previously blocked. Returns true on success.
-  bool ResumeStream(Http2StreamId stream_id);
-
-  // Returns the peer's outstanding stream receive window for the given stream.
-  int GetStreamSendWindowSize(Http2StreamId stream_id) const;
-
-  // Returns the current upper bound on the flow control receive window for this
-  // stream.
-  int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const;
-
-  // Returns the outstanding stream receive window, or -1 if the stream does not
-  // exist.
-  int GetStreamReceiveWindowSize(Http2StreamId stream_id) const;
-
-  // Returns the outstanding connection receive window.
-  int GetReceiveWindowSize() const;
-
-  // Returns the size of the HPACK encoder's dynamic table, including the
-  // per-entry overhead from the specification.
-  int GetHpackEncoderDynamicTableSize() const;
-
-  // Returns the maximum capacity of the HPACK encoder's dynamic table.
-  int GetHpackEncoderDynamicTableCapacity() const;
-
-  // Returns the size of the HPACK decoder's dynamic table, including the
-  // per-entry overhead from the specification.
-  int GetHpackDecoderDynamicTableSize() const;
-
-  // Returns the size of the HPACK decoder's most recently applied size limit.
-  int GetHpackDecoderSizeLimit() const;
-
-  // From Http2Session.
-  int64_t ProcessBytes(absl::string_view bytes) override;
-  int Consume(Http2StreamId stream_id, size_t num_bytes) override;
-  bool want_read() const override {
-    return !received_goaway_ && !decoder_.HasError();
-  }
-  bool want_write() const override {
-    return !fatal_send_error_ &&
-           (!frames_.empty() || !buffered_data_.empty() ||
-            !connection_metadata_.empty() || HasReadyStream());
-  }
-  int GetRemoteWindowSize() const override { return connection_send_window_; }
-
-  // From SpdyFramerVisitorInterface
-  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error) override;
-  void OnCommonHeader(spdy::SpdyStreamId /*stream_id*/,
-                      size_t /*length*/,
-                      uint8_t /*type*/,
-                      uint8_t /*flags*/) override;
-  void OnDataFrameHeader(spdy::SpdyStreamId stream_id,
-                         size_t length,
-                         bool fin) override;
-  void OnStreamFrameData(spdy::SpdyStreamId stream_id,
-                         const char* data,
-                         size_t len) override;
-  void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
-  void OnStreamPadLength(spdy::SpdyStreamId /*stream_id*/,
-                         size_t /*value*/) override;
-  void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
-  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      spdy::SpdyStreamId stream_id) override;
-  void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
-  void OnRstStream(spdy::SpdyStreamId stream_id,
-                   spdy::SpdyErrorCode error_code) override;
-  void OnSettings() override;
-  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck() override;
-  void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
-  void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
-                spdy::SpdyErrorCode error_code) override;
-  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
-  void OnHeaders(spdy::SpdyStreamId stream_id,
-                 bool has_priority,
-                 int weight,
-                 spdy::SpdyStreamId parent_stream_id,
-                 bool exclusive,
-                 bool fin,
-                 bool end) override;
-  void OnWindowUpdate(spdy::SpdyStreamId stream_id,
-                      int delta_window_size) override;
-  void OnPushPromise(spdy::SpdyStreamId stream_id,
-                     spdy::SpdyStreamId promised_stream_id,
-                     bool end) override;
-  void OnContinuation(spdy::SpdyStreamId stream_id, bool end) override;
-  void OnAltSvc(spdy::SpdyStreamId /*stream_id*/, absl::string_view /*origin*/,
-                const spdy::SpdyAltSvcWireFormat::
-                    AlternativeServiceVector& /*altsvc_vector*/) override;
-  void OnPriority(spdy::SpdyStreamId stream_id,
-                  spdy::SpdyStreamId parent_stream_id,
-                  int weight,
-                  bool exclusive) override;
-  void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
-                        absl::string_view priority_field_value) override;
-  bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
-                      uint8_t frame_type) override;
-
-  // Invoked when header processing encounters an invalid or otherwise
-  // problematic header.
-  void OnHeaderStatus(Http2StreamId stream_id,
-                      Http2VisitorInterface::OnHeaderResult result);
-
-  // Returns true if a recognized extension frame is received.
-  bool OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
-                     uint8_t flags) override;
-
-  // Handles the payload for a recognized extension frame.
-  void OnFramePayload(const char* data, size_t len) override;
-
- private:
-  using MetadataSequence = std::vector<std::unique_ptr<MetadataSource>>;
-
-  struct QUICHE_EXPORT_PRIVATE StreamState {
-    StreamState(int32_t stream_receive_window, int32_t stream_send_window,
-                WindowManager::WindowUpdateListener listener,
-                WindowManager::ShouldWindowUpdateFn should_window_update_fn)
-        : window_manager(stream_receive_window, std::move(listener),
-                         std::move(should_window_update_fn),
-                         /*update_window_on_notify=*/false),
-          send_window(stream_send_window) {}
-
-    WindowManager window_manager;
-    std::unique_ptr<DataFrameSource> outbound_body;
-    MetadataSequence outbound_metadata;
-    std::unique_ptr<spdy::SpdyHeaderBlock> trailers;
-    void* user_data = nullptr;
-    int32_t send_window;
-    absl::optional<HeaderType> received_header_type;
-    absl::optional<size_t> remaining_content_length;
-    bool half_closed_local = false;
-    bool half_closed_remote = false;
-    // Indicates that `outbound_body` temporarily cannot produce data.
-    bool data_deferred = false;
-    bool can_receive_body = true;
-  };
-  using StreamStateMap = absl::flat_hash_map<Http2StreamId, StreamState>;
-
-  struct QUICHE_EXPORT_PRIVATE PendingStreamState {
-    spdy::SpdyHeaderBlock headers;
-    std::unique_ptr<DataFrameSource> data_source;
-    void* user_data = nullptr;
-  };
-
-  class QUICHE_EXPORT_PRIVATE PassthroughHeadersHandler
-      : public spdy::SpdyHeadersHandlerInterface {
-   public:
-    explicit PassthroughHeadersHandler(OgHttp2Session& session,
-                                       Http2VisitorInterface& visitor)
-        : session_(session), visitor_(visitor) {}
-
-    void set_stream_id(Http2StreamId stream_id) {
-      stream_id_ = stream_id;
-      result_ = Http2VisitorInterface::HEADER_OK;
-    }
-
-    void set_frame_contains_fin() { frame_contains_fin_ = true; }
-    void set_header_type(HeaderType type) { type_ = type; }
-    HeaderType header_type() const { return type_; }
-
-    void OnHeaderBlockStart() override;
-    void OnHeader(absl::string_view key, absl::string_view value) override;
-    void OnHeaderBlockEnd(size_t /* uncompressed_header_bytes */,
-                          size_t /* compressed_header_bytes */) override;
-    absl::string_view status_header() const {
-      QUICHE_DCHECK(type_ == HeaderType::RESPONSE ||
-                    type_ == HeaderType::RESPONSE_100);
-      return validator_.status_header();
-    }
-    absl::optional<size_t> content_length() const {
-      return validator_.content_length();
-    }
-    void AllowConnect() { validator_.AllowConnect(); }
-    void SetMaxFieldSize(uint32_t field_size) {
-      validator_.SetMaxFieldSize(field_size);
-    }
-    bool CanReceiveBody() const;
-
-   private:
-    OgHttp2Session& session_;
-    Http2VisitorInterface& visitor_;
-    Http2StreamId stream_id_ = 0;
-    Http2VisitorInterface::OnHeaderResult result_ =
-        Http2VisitorInterface::HEADER_OK;
-    // Validates header blocks according to the HTTP/2 specification.
-    HeaderValidator validator_;
-    HeaderType type_ = HeaderType::RESPONSE;
-    bool frame_contains_fin_ = false;
-  };
-
-  struct QUICHE_EXPORT_PRIVATE ProcessBytesResultVisitor;
-
-  // Queues the connection preface, if not already done. If not
-  // `sending_outbound_settings` and the preface has not yet been queued, this
-  // method will generate and enqueue initial SETTINGS.
-  void MaybeSetupPreface(bool sending_outbound_settings);
-
-  // Gets the settings to be sent in the initial SETTINGS frame sent as part of
-  // the connection preface.
-  std::vector<Http2Setting> GetInitialSettings() const;
-
-  // Prepares and returns a SETTINGS frame with the given `settings`.
-  std::unique_ptr<spdy::SpdySettingsIR> PrepareSettingsFrame(
-      absl::Span<const Http2Setting> settings);
-
-  // Updates internal state to match the SETTINGS advertised to the peer.
-  void HandleOutboundSettings(const spdy::SpdySettingsIR& settings_frame);
-
-  void SendWindowUpdate(Http2StreamId stream_id, size_t update_delta);
-
-  enum class SendResult {
-    // All data was flushed.
-    SEND_OK,
-    // Not all data was flushed (due to flow control or TCP back pressure).
-    SEND_BLOCKED,
-    // An error occurred while sending data.
-    SEND_ERROR,
-  };
-
-  // Returns the int corresponding to the `result`, updating state as needed.
-  int InterpretSendResult(SendResult result);
-
-  enum class ProcessBytesError {
-    // A general, unspecified error.
-    kUnspecified,
-    // The (server-side) session received an invalid client connection preface.
-    kInvalidConnectionPreface,
-    // A user/visitor callback failed with a fatal error.
-    kVisitorCallbackFailed,
-  };
-  using ProcessBytesResult = absl::variant<int64_t, ProcessBytesError>;
-
-  // Attempts to process `bytes` and returns the number of bytes proccessed on
-  // success or the processing error on failure.
-  ProcessBytesResult ProcessBytesImpl(absl::string_view bytes);
-
-  // Returns true if at least one stream has data or control frames to write.
-  bool HasReadyStream() const;
-
-  // Returns the next stream that has something to write. If there are no such
-  // streams, returns zero.
-  Http2StreamId GetNextReadyStream();
-
-  // Sends the buffered connection preface or serialized frame data, if any.
-  SendResult MaybeSendBufferedData();
-
-  // Serializes and sends queued frames.
-  SendResult SendQueuedFrames();
-
-  // Returns false if a fatal connection error occurred.
-  bool AfterFrameSent(uint8_t frame_type_int, uint32_t stream_id,
-                      size_t payload_length, uint8_t flags,
-                      uint32_t error_code);
-
-  // Writes DATA frames for stream `stream_id`.
-  SendResult WriteForStream(Http2StreamId stream_id);
-
-  SendResult SendMetadata(Http2StreamId stream_id, MetadataSequence& sequence);
-
-  void SendHeaders(Http2StreamId stream_id, spdy::SpdyHeaderBlock headers,
-                   bool end_stream);
-
-  void SendTrailers(Http2StreamId stream_id, spdy::SpdyHeaderBlock trailers);
-
-  // Encapsulates the RST_STREAM NO_ERROR behavior described in RFC 7540
-  // Section 8.1.
-  void MaybeFinWithRstStream(StreamStateMap::iterator iter);
-
-  // Performs flow control accounting for data sent by the peer.
-  void MarkDataBuffered(Http2StreamId stream_id, size_t bytes);
-
-  // Creates a stream for `stream_id` if not already present and returns an
-  // iterator pointing to it.
-  StreamStateMap::iterator CreateStream(Http2StreamId stream_id);
-
-  // Creates a stream for `stream_id`, stores the `data_source` and `user_data`
-  // in the stream state, and sends the `headers`.
-  void StartRequest(Http2StreamId stream_id, spdy::SpdyHeaderBlock headers,
-                    std::unique_ptr<DataFrameSource> data_source,
-                    void* user_data);
-
-  // Sends headers for pending streams as long as the stream limit allows.
-  void StartPendingStreams();
-
-  // Closes the given `stream_id` with the given `error_code`.
-  void CloseStream(Http2StreamId stream_id, Http2ErrorCode error_code);
-
-  // Calculates the next expected header type for a stream in a given state.
-  HeaderType NextHeaderType(absl::optional<HeaderType> current_type);
-
-  // Returns true if the session can create a new stream.
-  bool CanCreateStream() const;
-
-  // Informs the visitor of the connection `error` and stops processing on the
-  // connection. If server-side, also sends a GOAWAY with `error_code`.
-  void LatchErrorAndNotify(Http2ErrorCode error_code,
-                           Http2VisitorInterface::ConnectionError error);
-
-  void CloseStreamIfReady(uint8_t frame_type, uint32_t stream_id);
-
-  // Updates internal state to prepare for sending an immediate GOAWAY.
-  void PrepareForImmediateGoAway();
-
-  // Handles the potential end of received metadata for the given `stream_id`.
-  void MaybeHandleMetadataEndForStream(Http2StreamId stream_id);
-
-  void DecrementQueuedFrameCount(uint32_t stream_id, uint8_t frame_type);
-
-  void HandleContentLengthError(Http2StreamId stream_id);
-
-  // Invoked when sending a flow control window update to the peer.
-  void UpdateReceiveWindow(Http2StreamId stream_id, int32_t delta);
-
-  // Updates stream send window accounting to respect the peer's advertised
-  // initial window setting.
-  void UpdateStreamSendWindowSizes(uint32_t new_value);
-
-  // Updates stream receive window managers to use the newly advertised stream
-  // initial window.
-  void UpdateStreamReceiveWindowSizes(uint32_t new_value);
-
-  // Receives events when inbound frames are parsed.
-  Http2VisitorInterface& visitor_;
-
-  // Forwards received events to the session if it can accept them.
-  EventForwarder event_forwarder_;
-
-  // Logs received frames when enabled.
-  Http2TraceLogger receive_logger_;
-  // Logs sent frames when enabled.
-  Http2FrameLogger send_logger_;
-
-  // Encodes outbound frames.
-  spdy::SpdyFramer framer_{spdy::SpdyFramer::ENABLE_COMPRESSION};
-
-  // Decodes inbound frames.
-  http2::Http2DecoderAdapter decoder_;
-
-  // Maintains the state of active streams known to this session.
-  StreamStateMap stream_map_;
-
-  // Maintains the state of pending streams known to this session. A pending
-  // stream is kept in this list until it can be created while complying with
-  // `max_outbound_concurrent_streams_`.
-  quiche::QuicheLinkedHashMap<Http2StreamId, PendingStreamState>
-      pending_streams_;
-
-  // The queue of outbound frames.
-  std::list<std::unique_ptr<spdy::SpdyFrameIR>> frames_;
-  // Buffered data (connection preface, serialized frames) that has not yet been
-  // sent.
-  std::string buffered_data_;
-
-  // Maintains the set of streams ready to write data to the peer.
-  using WriteScheduler = PriorityWriteScheduler<Http2StreamId>;
-  WriteScheduler write_scheduler_;
-
-  // Stores the queue of callbacks to invoke upon receiving SETTINGS acks. At
-  // most one callback is invoked for each SETTINGS ack.
-  using SettingsAckCallback = std::function<void()>;
-  std::list<SettingsAckCallback> settings_ack_callbacks_;
-
-  // Delivers header name-value pairs to the visitor.
-  PassthroughHeadersHandler headers_handler_;
-
-  // Ignores header data, e.g., for an unknown or rejected stream.
-  spdy::NoOpHeadersHandler noop_headers_handler_;
-
-  // Tracks the remaining client connection preface, in the case of a server
-  // session.
-  absl::string_view remaining_preface_;
-
-  WindowManager connection_window_manager_;
-
-  // Tracks the streams that have been marked for reset. A stream is removed
-  // from this set once it is closed.
-  absl::flat_hash_set<Http2StreamId> streams_reset_;
-
-  // The number of frames currently queued per stream.
-  absl::flat_hash_map<Http2StreamId, int> queued_frames_;
-  // Includes streams that are currently ready to write trailers.
-  absl::flat_hash_set<Http2StreamId> trailers_ready_;
-  // Includes streams that are currently ready to write metadata.
-  absl::flat_hash_set<Http2StreamId> metadata_ready_;
-
-  MetadataSequence connection_metadata_;
-
-  Http2StreamId next_stream_id_ = 1;
-  // The highest received stream ID is the highest stream ID in any frame read
-  // from the peer. The highest processed stream ID is the highest stream ID for
-  // which this endpoint created a stream in the stream map.
-  Http2StreamId highest_received_stream_id_ = 0;
-  Http2StreamId highest_processed_stream_id_ = 0;
-  Http2StreamId metadata_stream_id_ = 0;
-  size_t metadata_length_ = 0;
-  int32_t connection_send_window_ = kInitialFlowControlWindowSize;
-  // The initial flow control receive window size for any newly created streams.
-  int32_t initial_stream_receive_window_ = kInitialFlowControlWindowSize;
-  // The initial flow control send window size for any newly created streams.
-  int32_t initial_stream_send_window_ = kInitialFlowControlWindowSize;
-  uint32_t max_frame_payload_ = 16384u;
-  // The maximum number of concurrent streams that this connection can open to
-  // its peer and allow from its peer, respectively. Although the initial value
-  // is unlimited, the spec encourages a value of at least 100. We limit
-  // ourselves to opening 100 until told otherwise by the peer and allow an
-  // unlimited number from the peer until updated from SETTINGS we send.
-  uint32_t max_outbound_concurrent_streams_ = 100u;
-  uint32_t pending_max_inbound_concurrent_streams_ =
-      std::numeric_limits<uint32_t>::max();
-  uint32_t max_inbound_concurrent_streams_ =
-      std::numeric_limits<uint32_t>::max();
-  const Options options_;
-
-  // The HPACK encoder header table capacity that will be applied when
-  // acking SETTINGS from the peer. Only contains a value if the peer advertises
-  // a larger table capacity than currently used; a smaller value can safely be
-  // applied immediately upon receipt.
-  absl::optional<uint32_t> encoder_header_table_capacity_when_acking_;
-
-  bool received_goaway_ = false;
-  bool queued_preface_ = false;
-  bool peer_supports_metadata_ = false;
-  bool end_metadata_ = false;
-  bool sent_non_ack_settings_ = false;
-
-  // Recursion guard for ProcessBytes().
-  bool processing_bytes_ = false;
-  // Recursion guard for Send().
-  bool sending_ = false;
-
-  // Replace this with a stream ID, for multiple GOAWAY support.
-  bool queued_goaway_ = false;
-  bool queued_immediate_goaway_ = false;
-  bool latched_error_ = false;
-
-  // True if a fatal sending error has occurred.
-  bool fatal_send_error_ = false;
-
-  // True if a fatal processing visitor callback failed.
-  bool fatal_visitor_callback_failure_ = false;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
diff --git a/http2/adapter/oghttp2_session_test.cc b/http2/adapter/oghttp2_session_test.cc
deleted file mode 100644
index 83dd424..0000000
--- a/http2/adapter/oghttp2_session_test.cc
+++ /dev/null
@@ -1,920 +0,0 @@
-#include "http2/adapter/oghttp2_session.h"
-
-#include "http2/adapter/mock_http2_visitor.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "http2/adapter/test_utils.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using spdy::SpdyFrameType;
-using testing::_;
-
-enum FrameType {
-  DATA,
-  HEADERS,
-  PRIORITY,
-  RST_STREAM,
-  SETTINGS,
-  PUSH_PROMISE,
-  PING,
-  GOAWAY,
-  WINDOW_UPDATE,
-};
-
-}  // namespace
-
-TEST(OgHttp2SessionTest, ClientConstruction) {
-  testing::StrictMock<MockHttp2Visitor> visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_TRUE(session.want_read());
-  EXPECT_FALSE(session.want_write());
-  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
-  EXPECT_FALSE(session.IsServerSession());
-  EXPECT_EQ(0, session.GetHighestReceivedStreamId());
-}
-
-TEST(OgHttp2SessionTest, ClientHandlesFrames) {
-  testing::StrictMock<MockHttp2Visitor> visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-
-  const std::string initial_frames = TestFrameSequence()
-                                         .ServerPreface()
-                                         .Ping(42)
-                                         .WindowUpdate(0, 1000)
-                                         .Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
-
-  const int64_t initial_result = session.ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  EXPECT_EQ(session.GetRemoteWindowSize(),
-            kInitialFlowControlWindowSize + 1000);
-  EXPECT_EQ(0, session.GetHighestReceivedStreamId());
-
-  // Connection has not yet received any data.
-  EXPECT_EQ(kInitialFlowControlWindowSize, session.GetReceiveWindowSize());
-
-  EXPECT_EQ(0, session.GetHpackDecoderDynamicTableSize());
-
-  // Submit a request to ensure the first stream is created.
-  const char* kSentinel1 = "arbitrary pointer 1";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload("This is an example request body.");
-  body1->EndData();
-  int stream_id =
-      session.SubmitRequest(ToHeaders({{":method", "POST"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/one"}}),
-                            std::move(body1), const_cast<char*>(kSentinel1));
-  EXPECT_EQ(stream_id, 1);
-
-  // Submit another request to ensure the next stream is created.
-  int stream_id2 =
-      session.SubmitRequest(ToHeaders({{":method", "GET"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/two"}}),
-                            nullptr, nullptr);
-  EXPECT_EQ(stream_id2, 3);
-
-  const std::string stream_frames =
-      TestFrameSequence()
-          .Headers(stream_id,
-                   {{":status", "200"},
-                    {"server", "my-fake-server"},
-                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
-                   /*fin=*/false)
-          .Data(stream_id, "This is the response body.")
-          .RstStream(stream_id2, Http2ErrorCode::INTERNAL_ERROR)
-          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
-          .Serialize();
-
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
-  EXPECT_CALL(visitor,
-              OnHeaderForStream(stream_id, "server", "my-fake-server"));
-  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
-                                         "Tue, 6 Apr 2021 12:54:01 GMT"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
-  EXPECT_CALL(visitor,
-              OnDataForStream(stream_id, "This is the response body."));
-  EXPECT_CALL(visitor, OnFrameHeader(stream_id2, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(stream_id2, Http2ErrorCode::INTERNAL_ERROR));
-  EXPECT_CALL(visitor,
-              OnCloseStream(stream_id2, Http2ErrorCode::INTERNAL_ERROR));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 19, GOAWAY, 0));
-  EXPECT_CALL(visitor, OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, ""));
-  const int64_t stream_result = session.ProcessBytes(stream_frames);
-  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
-  EXPECT_EQ(stream_id2, session.GetHighestReceivedStreamId());
-
-  // The first stream is active and has received some data.
-  EXPECT_GT(kInitialFlowControlWindowSize,
-            session.GetStreamReceiveWindowSize(stream_id));
-  // Connection receive window is equivalent to the first stream's.
-  EXPECT_EQ(session.GetReceiveWindowSize(),
-            session.GetStreamReceiveWindowSize(stream_id));
-  // Receive window upper bound is still the initial value.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            session.GetStreamReceiveWindowLimit(stream_id));
-
-  EXPECT_GT(session.GetHpackDecoderDynamicTableSize(), 0);
-}
-
-// Verifies that a client session enqueues initial SETTINGS if Send() is called
-// before any frames are explicitly queued.
-TEST(OgHttp2SessionTest, ClientEnqueuesSettingsOnSend) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_FALSE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-// Verifies that a client session enqueues initial SETTINGS before whatever
-// frame type is passed to the first invocation of EnqueueFrame().
-TEST(OgHttp2SessionTest, ClientEnqueuesSettingsBeforeOtherFrame) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_FALSE(session.want_write());
-  session.EnqueueFrame(absl::make_unique<spdy::SpdyPingIR>(42));
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x0, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
-}
-
-// Verifies that if the first call to EnqueueFrame() passes a SETTINGS frame,
-// the client session will not enqueue an additional SETTINGS frame.
-TEST(OgHttp2SessionTest, ClientEnqueuesSettingsOnce) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_FALSE(session.want_write());
-  session.EnqueueFrame(absl::make_unique<spdy::SpdySettingsIR>());
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2SessionTest, ClientSubmitRequest) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-
-  EXPECT_FALSE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  // Even though the user has not queued any frames for the session, it should
-  // still send the connection preface.
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  // Initial SETTINGS.
-  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  const std::string initial_frames =
-      TestFrameSequence().ServerPreface().Serialize();
-  testing::InSequence s;
-
-  // Server preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  const int64_t initial_result = session.ProcessBytes(initial_frames);
-  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
-
-  // Session will want to write a SETTINGS ack.
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_EQ(0, session.GetHpackEncoderDynamicTableSize());
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload("This is an example request body.");
-  body1->EndData();
-  int stream_id =
-      session.SubmitRequest(ToHeaders({{":method", "POST"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/one"}}),
-                            std::move(body1), const_cast<char*>(kSentinel1));
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(session.want_write());
-  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({spdy::SpdyFrameType::HEADERS,
-                                            spdy::SpdyFrameType::DATA}));
-  visitor.Clear();
-  EXPECT_FALSE(session.want_write());
-
-  // Some data was sent, so the remaining send window size should be less than
-  // the default.
-  EXPECT_LT(session.GetStreamSendWindowSize(stream_id),
-            kInitialFlowControlWindowSize);
-  EXPECT_GT(session.GetStreamSendWindowSize(stream_id), 0);
-  // Send window for a nonexistent stream is not available.
-  EXPECT_EQ(-1, session.GetStreamSendWindowSize(stream_id + 2));
-
-  EXPECT_GT(session.GetHpackEncoderDynamicTableSize(), 0);
-
-  stream_id =
-      session.SubmitRequest(ToHeaders({{":method", "POST"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/two"}}),
-                            nullptr, nullptr);
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(session.want_write());
-  const char* kSentinel2 = "arbitrary pointer 2";
-  EXPECT_EQ(nullptr, session.GetStreamUserData(stream_id));
-  session.SetStreamUserData(stream_id, const_cast<char*>(kSentinel2));
-  EXPECT_EQ(kSentinel2, session.GetStreamUserData(stream_id));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
-
-  result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({spdy::SpdyFrameType::HEADERS}));
-
-  // No data was sent (just HEADERS), so the remaining send window size should
-  // still be the default.
-  EXPECT_EQ(session.GetStreamSendWindowSize(stream_id),
-            kInitialFlowControlWindowSize);
-}
-
-// This test exercises the case where the client request body source is read
-// blocked.
-TEST(OgHttp2SessionTest, ClientSubmitRequestWithReadBlock) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_FALSE(session.want_write());
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  TestDataFrameSource* body_ref = body1.get();
-  int stream_id =
-      session.SubmitRequest(ToHeaders({{":method", "POST"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/one"}}),
-                            std::move(body1), const_cast<char*>(kSentinel1));
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(session.want_write());
-  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  // No data frame, as body1 was read blocked.
-  visitor.Clear();
-  EXPECT_FALSE(session.want_write());
-
-  body_ref->AppendPayload("This is an example request body.");
-  body_ref->EndData();
-  EXPECT_TRUE(session.ResumeStream(stream_id));
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
-  EXPECT_FALSE(session.want_write());
-
-  // Stream data is done, so this stream cannot be resumed.
-  EXPECT_FALSE(session.ResumeStream(stream_id));
-  EXPECT_FALSE(session.want_write());
-}
-
-// This test exercises the case where the client request body source is read
-// blocked, then ends with an empty DATA frame.
-TEST(OgHttp2SessionTest, ClientSubmitRequestEmptyDataWithFin) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_FALSE(session.want_write());
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  TestDataFrameSource* body_ref = body1.get();
-  int stream_id =
-      session.SubmitRequest(ToHeaders({{":method", "POST"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/one"}}),
-                            std::move(body1), const_cast<char*>(kSentinel1));
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(session.want_write());
-  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
-  // No data frame, as body1 was read blocked.
-  visitor.Clear();
-  EXPECT_FALSE(session.want_write());
-
-  body_ref->EndData();
-  EXPECT_TRUE(session.ResumeStream(stream_id));
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 0, 0x1, 0));
-
-  result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
-  EXPECT_FALSE(session.want_write());
-
-  // Stream data is done, so this stream cannot be resumed.
-  EXPECT_FALSE(session.ResumeStream(stream_id));
-  EXPECT_FALSE(session.want_write());
-}
-
-// This test exercises the case where the connection to the peer is write
-// blocked.
-TEST(OgHttp2SessionTest, ClientSubmitRequestWithWriteBlock) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
-  EXPECT_FALSE(session.want_write());
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
-  body1->AppendPayload("This is an example request body.");
-  body1->EndData();
-  int stream_id =
-      session.SubmitRequest(ToHeaders({{":method", "POST"},
-                                       {":scheme", "http"},
-                                       {":authority", "example.com"},
-                                       {":path", "/this/is/request/one"}}),
-                            std::move(body1), const_cast<char*>(kSentinel1));
-  EXPECT_GT(stream_id, 0);
-  EXPECT_TRUE(session.want_write());
-  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
-  visitor.set_is_write_blocked(true);
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-
-  EXPECT_THAT(visitor.data(), testing::IsEmpty());
-  EXPECT_TRUE(session.want_write());
-  visitor.set_is_write_blocked(false);
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
-
-  result = session.Send();
-  EXPECT_EQ(0, result);
-
-  absl::string_view serialized = visitor.data();
-  EXPECT_THAT(serialized,
-              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
-  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
-  EXPECT_THAT(serialized,
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
-                            SpdyFrameType::DATA}));
-  EXPECT_FALSE(session.want_write());
-}
-
-TEST(OgHttp2SessionTest, ServerConstruction) {
-  testing::StrictMock<MockHttp2Visitor> visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-  EXPECT_TRUE(session.want_read());
-  EXPECT_FALSE(session.want_write());
-  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
-  EXPECT_TRUE(session.IsServerSession());
-  EXPECT_EQ(0, session.GetHighestReceivedStreamId());
-}
-
-TEST(OgHttp2SessionTest, ServerHandlesFrames) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-
-  EXPECT_EQ(0, session.GetHpackDecoderDynamicTableSize());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Ping(42)
-                                 .WindowUpdate(0, 1000)
-                                 .Headers(1,
-                                          {{":method", "POST"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/false)
-                                 .WindowUpdate(1, 2000)
-                                 .Data(1, "This is the request body.")
-                                 .Headers(3,
-                                          {{":method", "GET"},
-                                           {":scheme", "http"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/two"}},
-                                          /*fin=*/true)
-                                 .RstStream(3, Http2ErrorCode::CANCEL)
-                                 .Ping(47)
-                                 .Serialize();
-  testing::InSequence s;
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(42, false));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
-      .WillOnce(testing::InvokeWithoutArgs([&session, kSentinel1]() {
-        session.SetStreamUserData(1, const_cast<char*>(kSentinel1));
-        return true;
-      }));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
-  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
-  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
-  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
-  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
-  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "http"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/two"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
-  EXPECT_CALL(visitor, OnEndStream(3));
-  EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
-  EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::CANCEL));
-  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
-  EXPECT_CALL(visitor, OnPing(47, false));
-
-  const int64_t result = session.ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_EQ(kSentinel1, session.GetStreamUserData(1));
-
-  // The first stream is active and has received some data.
-  EXPECT_GT(kInitialFlowControlWindowSize,
-            session.GetStreamReceiveWindowSize(1));
-  // Connection receive window is equivalent to the first stream's.
-  EXPECT_EQ(session.GetReceiveWindowSize(),
-            session.GetStreamReceiveWindowSize(1));
-  // Receive window upper bound is still the initial value.
-  EXPECT_EQ(kInitialFlowControlWindowSize,
-            session.GetStreamReceiveWindowLimit(1));
-
-  EXPECT_GT(session.GetHpackDecoderDynamicTableSize(), 0);
-
-  // It should no longer be possible to set user data on a closed stream.
-  const char* kSentinel3 = "another arbitrary pointer";
-  session.SetStreamUserData(3, const_cast<char*>(kSentinel3));
-  EXPECT_EQ(nullptr, session.GetStreamUserData(3));
-
-  EXPECT_EQ(session.GetRemoteWindowSize(),
-            kInitialFlowControlWindowSize + 1000);
-  EXPECT_EQ(3, session.GetHighestReceivedStreamId());
-
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
-
-  // Some bytes should have been serialized.
-  int send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  // Initial SETTINGS, SETTINGS ack, and PING acks (for PING IDs 42 and 47).
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames(
-                  {spdy::SpdyFrameType::SETTINGS, spdy::SpdyFrameType::SETTINGS,
-                   spdy::SpdyFrameType::PING, spdy::SpdyFrameType::PING}));
-}
-
-// Verifies that a server session enqueues initial SETTINGS before whatever
-// frame type is passed to the first invocation of EnqueueFrame().
-TEST(OgHttp2SessionTest, ServerEnqueuesSettingsBeforeOtherFrame) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-  EXPECT_FALSE(session.want_write());
-  session.EnqueueFrame(absl::make_unique<spdy::SpdyPingIR>(42));
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x0, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
-}
-
-// Verifies that if the first call to EnqueueFrame() passes a SETTINGS frame,
-// the server session will not enqueue an additional SETTINGS frame.
-TEST(OgHttp2SessionTest, ServerEnqueuesSettingsOnce) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-  EXPECT_FALSE(session.want_write());
-  session.EnqueueFrame(absl::make_unique<spdy::SpdySettingsIR>());
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-
-  int result = session.Send();
-  EXPECT_EQ(0, result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
-}
-
-TEST(OgHttp2SessionTest, ServerSubmitResponse) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-
-  EXPECT_FALSE(session.want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  const char* kSentinel1 = "arbitrary pointer 1";
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
-      .WillOnce(testing::InvokeWithoutArgs([&session, kSentinel1]() {
-        session.SetStreamUserData(1, const_cast<char*>(kSentinel1));
-        return true;
-      }));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = session.ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  EXPECT_EQ(1, session.GetHighestReceivedStreamId());
-
-  EXPECT_EQ(0, session.GetHpackEncoderDynamicTableSize());
-
-  // Server will want to send initial SETTINGS, and a SETTINGS ack.
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_FALSE(session.want_write());
-  // A data fin is not sent so that the stream remains open, and the flow
-  // control state can be verified.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload("This is an example response body.");
-  int submit_result = session.SubmitResponse(
-      1,
-      ToHeaders({{":status", "404"},
-                 {"x-comment", "I have no idea what you're talking about."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(session.want_write());
-
-  // Stream user data should have been set successfully after receiving headers.
-  EXPECT_EQ(kSentinel1, session.GetStreamUserData(1));
-  session.SetStreamUserData(1, nullptr);
-  EXPECT_EQ(nullptr, session.GetStreamUserData(1));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  EXPECT_FALSE(session.want_write());
-
-  // Some data was sent, so the remaining send window size should be less than
-  // the default.
-  EXPECT_LT(session.GetStreamSendWindowSize(1), kInitialFlowControlWindowSize);
-  EXPECT_GT(session.GetStreamSendWindowSize(1), 0);
-  // Send window for a nonexistent stream is not available.
-  EXPECT_EQ(session.GetStreamSendWindowSize(3), -1);
-
-  EXPECT_GT(session.GetHpackEncoderDynamicTableSize(), 0);
-}
-
-// Tests the case where the server queues trailers after the data stream is
-// exhausted.
-TEST(OgHttp2SessionTest, ServerSendsTrailers) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-
-  EXPECT_FALSE(session.want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = session.ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  // Server will want to send initial SETTINGS, and a SETTINGS ack.
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_FALSE(session.want_write());
-
-  // The body source must indicate that the end of the body is not the end of
-  // the stream.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload("This is an example response body.");
-  body1->EndData();
-  int submit_result = session.SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
-  visitor.Clear();
-  EXPECT_FALSE(session.want_write());
-
-  // The body source has been exhausted by the call to Send() above.
-  int trailer_result = session.SubmitTrailer(
-      1, ToHeaders({{"final-status", "a-ok"},
-                    {"x-comment", "trailers sure are cool"}}));
-  ASSERT_EQ(trailer_result, 0);
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
-}
-
-// Tests the case where the server queues trailers immediately after headers and
-// data, and before any writes have taken place.
-TEST(OgHttp2SessionTest, ServerQueuesTrailersWithResponse) {
-  DataSavingVisitor visitor;
-  OgHttp2Session session(
-      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
-
-  EXPECT_FALSE(session.want_write());
-
-  const std::string frames = TestFrameSequence()
-                                 .ClientPreface()
-                                 .Headers(1,
-                                          {{":method", "GET"},
-                                           {":scheme", "https"},
-                                           {":authority", "example.com"},
-                                           {":path", "/this/is/request/one"}},
-                                          /*fin=*/true)
-                                 .Serialize();
-  testing::InSequence s;
-
-  // Client preface (empty SETTINGS)
-  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
-  EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor, OnSettingsEnd());
-  // Stream 1
-  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
-  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
-  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
-  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
-  EXPECT_CALL(visitor, OnEndStream(1));
-
-  const int64_t result = session.ProcessBytes(frames);
-  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
-
-  // Server will want to send initial SETTINGS, and a SETTINGS ack.
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
-  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
-  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
-
-  int send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
-  visitor.Clear();
-
-  EXPECT_FALSE(session.want_write());
-
-  // The body source must indicate that the end of the body is not the end of
-  // the stream.
-  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
-  body1->AppendPayload("This is an example response body.");
-  body1->EndData();
-  int submit_result = session.SubmitResponse(
-      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
-      std::move(body1));
-  EXPECT_EQ(submit_result, 0);
-  EXPECT_TRUE(session.want_write());
-  // There has not been a call to Send() yet, so neither headers nor body have
-  // been written.
-  int trailer_result = session.SubmitTrailer(
-      1, ToHeaders({{"final-status", "a-ok"},
-                    {"x-comment", "trailers sure are cool"}}));
-  ASSERT_EQ(trailer_result, 0);
-  EXPECT_TRUE(session.want_write());
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
-  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
-
-  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
-  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
-  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
-
-  send_result = session.Send();
-  EXPECT_EQ(0, send_result);
-  EXPECT_THAT(visitor.data(),
-              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
-                            SpdyFrameType::HEADERS}));
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/oghttp2_util.cc b/http2/adapter/oghttp2_util.cc
deleted file mode 100644
index ed0e6f6..0000000
--- a/http2/adapter/oghttp2_util.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "http2/adapter/oghttp2_util.h"
-
-namespace http2 {
-namespace adapter {
-
-spdy::SpdyHeaderBlock ToHeaderBlock(absl::Span<const Header> headers) {
-  spdy::SpdyHeaderBlock block;
-  for (const Header& header : headers) {
-    absl::string_view name = GetStringView(header.first).first;
-    absl::string_view value = GetStringView(header.second).first;
-    block.AppendValueOrAddHeader(name, value);
-  }
-  return block;
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/oghttp2_util.h b/http2/adapter/oghttp2_util.h
deleted file mode 100644
index 3134ff7..0000000
--- a/http2/adapter/oghttp2_util.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_UTIL_H_
-#define QUICHE_HTTP2_ADAPTER_OGHTTP2_UTIL_H_
-
-#include "absl/types/span.h"
-#include "http2/adapter/http2_protocol.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace http2 {
-namespace adapter {
-
-QUICHE_EXPORT_PRIVATE spdy::SpdyHeaderBlock ToHeaderBlock(
-    absl::Span<const Header> headers);
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_UTIL_H_
diff --git a/http2/adapter/oghttp2_util_test.cc b/http2/adapter/oghttp2_util_test.cc
deleted file mode 100644
index 6f29b26..0000000
--- a/http2/adapter/oghttp2_util_test.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "http2/adapter/oghttp2_util.h"
-
-#include <utility>
-#include <vector>
-
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/test_frame_sequence.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using HeaderPair = std::pair<absl::string_view, absl::string_view>;
-
-TEST(ToHeaderBlock, EmptySpan) {
-  spdy::SpdyHeaderBlock block = ToHeaderBlock({});
-  EXPECT_TRUE(block.empty());
-}
-
-TEST(ToHeaderBlock, ExampleRequestHeaders) {
-  const std::vector<HeaderPair> pairs = {{":authority", "example.com"},
-                                         {":method", "GET"},
-                                         {":path", "/example.html"},
-                                         {":scheme", "http"},
-                                         {"accept", "text/plain, text/html"}};
-  const std::vector<Header> headers = ToHeaders(pairs);
-  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
-  EXPECT_THAT(block, testing::ElementsAreArray(pairs));
-}
-
-TEST(ToHeaderBlock, ExampleResponseHeaders) {
-  const std::vector<HeaderPair> pairs = {
-      {":status", "403"},
-      {"content-length", "1023"},
-      {"x-extra-info", "humblest apologies"}};
-  const std::vector<Header> headers = ToHeaders(pairs);
-  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
-  EXPECT_THAT(block, testing::ElementsAreArray(pairs));
-}
-
-TEST(ToHeaderBlock, RepeatedRequestHeaderNames) {
-  const std::vector<HeaderPair> pairs = {
-      {":authority", "example.com"},     {":method", "GET"},
-      {":path", "/example.html"},        {":scheme", "http"},
-      {"cookie", "chocolate_chips=yes"}, {"accept", "text/plain, text/html"},
-      {"cookie", "raisins=no"}};
-  const std::vector<HeaderPair> expected = {
-      {":authority", "example.com"},
-      {":method", "GET"},
-      {":path", "/example.html"},
-      {":scheme", "http"},
-      {"cookie", "chocolate_chips=yes; raisins=no"},
-      {"accept", "text/plain, text/html"}};
-  const std::vector<Header> headers = ToHeaders(pairs);
-  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
-  EXPECT_THAT(block, testing::ElementsAreArray(expected));
-}
-
-TEST(ToHeaderBlock, RepeatedResponseHeaderNames) {
-  const std::vector<HeaderPair> pairs = {
-      {":status", "403"},          {"x-extra-info", "sorry"},
-      {"content-length", "1023"},  {"x-extra-info", "humblest apologies"},
-      {"content-length", "1024"},  {"set-cookie", "chocolate_chips=yes"},
-      {"set-cookie", "raisins=no"}};
-  const std::vector<HeaderPair> expected = {
-      {":status", "403"},
-      {"x-extra-info", absl::string_view("sorry\0humblest apologies", 24)},
-      {"content-length", absl::string_view("1023"
-                                           "\0"
-                                           "1024",
-                                           9)},
-      {"set-cookie", absl::string_view("chocolate_chips=yes\0raisins=no", 30)}};
-  const std::vector<Header> headers = ToHeaders(pairs);
-  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
-  EXPECT_THAT(block, testing::ElementsAreArray(expected));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/recording_http2_visitor.cc b/http2/adapter/recording_http2_visitor.cc
deleted file mode 100644
index f746259..0000000
--- a/http2/adapter/recording_http2_visitor.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-#include "http2/adapter/recording_http2_visitor.h"
-
-#include "absl/strings/str_format.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_util.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-int64_t RecordingHttp2Visitor::OnReadyToSend(absl::string_view serialized) {
-  events_.push_back(absl::StrFormat("OnReadyToSend %d", serialized.size()));
-  return serialized.size();
-}
-
-void RecordingHttp2Visitor::OnConnectionError(ConnectionError error) {
-  events_.push_back(
-      absl::StrFormat("OnConnectionError %s", ConnectionErrorToString(error)));
-}
-
-bool RecordingHttp2Visitor::OnFrameHeader(Http2StreamId stream_id,
-                                          size_t length, uint8_t type,
-                                          uint8_t flags) {
-  events_.push_back(absl::StrFormat("OnFrameHeader %d %d %d %d", stream_id,
-                                    length, type, flags));
-  return true;
-}
-
-void RecordingHttp2Visitor::OnSettingsStart() {
-  events_.push_back("OnSettingsStart");
-}
-
-void RecordingHttp2Visitor::OnSetting(Http2Setting setting) {
-  events_.push_back(absl::StrFormat(
-      "OnSetting %s %d", Http2SettingsIdToString(setting.id), setting.value));
-}
-
-void RecordingHttp2Visitor::OnSettingsEnd() {
-  events_.push_back("OnSettingsEnd");
-}
-
-void RecordingHttp2Visitor::OnSettingsAck() {
-  events_.push_back("OnSettingsAck");
-}
-
-bool RecordingHttp2Visitor::OnBeginHeadersForStream(Http2StreamId stream_id) {
-  events_.push_back(absl::StrFormat("OnBeginHeadersForStream %d", stream_id));
-  return true;
-}
-
-Http2VisitorInterface::OnHeaderResult RecordingHttp2Visitor::OnHeaderForStream(
-    Http2StreamId stream_id, absl::string_view name, absl::string_view value) {
-  events_.push_back(
-      absl::StrFormat("OnHeaderForStream %d %s %s", stream_id, name, value));
-  return HEADER_OK;
-}
-
-bool RecordingHttp2Visitor::OnEndHeadersForStream(Http2StreamId stream_id) {
-  events_.push_back(absl::StrFormat("OnEndHeadersForStream %d", stream_id));
-  return true;
-}
-
-bool RecordingHttp2Visitor::OnDataPaddingLength(Http2StreamId stream_id,
-                                                size_t padding_length) {
-  events_.push_back(
-      absl::StrFormat("OnDataPaddingLength %d %d", stream_id, padding_length));
-  return true;
-}
-
-bool RecordingHttp2Visitor::OnBeginDataForStream(Http2StreamId stream_id,
-                                                 size_t payload_length) {
-  events_.push_back(
-      absl::StrFormat("OnBeginDataForStream %d %d", stream_id, payload_length));
-  return true;
-}
-
-bool RecordingHttp2Visitor::OnDataForStream(Http2StreamId stream_id,
-                                            absl::string_view data) {
-  events_.push_back(absl::StrFormat("OnDataForStream %d %s", stream_id, data));
-  return true;
-}
-
-void RecordingHttp2Visitor::OnEndStream(Http2StreamId stream_id) {
-  events_.push_back(absl::StrFormat("OnEndStream %d", stream_id));
-}
-
-void RecordingHttp2Visitor::OnRstStream(Http2StreamId stream_id,
-                                        Http2ErrorCode error_code) {
-  events_.push_back(absl::StrFormat("OnRstStream %d %s", stream_id,
-                                    Http2ErrorCodeToString(error_code)));
-}
-
-bool RecordingHttp2Visitor::OnCloseStream(Http2StreamId stream_id,
-                                          Http2ErrorCode error_code) {
-  events_.push_back(absl::StrFormat("OnCloseStream %d %s", stream_id,
-                                    Http2ErrorCodeToString(error_code)));
-  return true;
-}
-
-void RecordingHttp2Visitor::OnPriorityForStream(Http2StreamId stream_id,
-                                                Http2StreamId parent_stream_id,
-                                                int weight,
-                                                bool exclusive) {
-  events_.push_back(absl::StrFormat("OnPriorityForStream %d %d %d %d",
-                                    stream_id, parent_stream_id, weight,
-                                    exclusive));
-}
-
-void RecordingHttp2Visitor::OnPing(Http2PingId ping_id, bool is_ack) {
-  events_.push_back(absl::StrFormat("OnPing %d %d", ping_id, is_ack));
-}
-
-void RecordingHttp2Visitor::OnPushPromiseForStream(
-    Http2StreamId stream_id,
-    Http2StreamId promised_stream_id) {
-  events_.push_back(absl::StrFormat("OnPushPromiseForStream %d %d", stream_id,
-                                    promised_stream_id));
-}
-
-bool RecordingHttp2Visitor::OnGoAway(Http2StreamId last_accepted_stream_id,
-                                     Http2ErrorCode error_code,
-                                     absl::string_view opaque_data) {
-  events_.push_back(
-      absl::StrFormat("OnGoAway %d %s %s", last_accepted_stream_id,
-                      Http2ErrorCodeToString(error_code), opaque_data));
-  return true;
-}
-
-void RecordingHttp2Visitor::OnWindowUpdate(Http2StreamId stream_id,
-                                           int window_increment) {
-  events_.push_back(
-      absl::StrFormat("OnWindowUpdate %d %d", stream_id, window_increment));
-}
-
-int RecordingHttp2Visitor::OnBeforeFrameSent(uint8_t frame_type,
-                                             Http2StreamId stream_id,
-                                             size_t length, uint8_t flags) {
-  events_.push_back(absl::StrFormat("OnBeforeFrameSent %d %d %d %d", frame_type,
-                                    stream_id, length, flags));
-  return 0;
-}
-
-int RecordingHttp2Visitor::OnFrameSent(uint8_t frame_type,
-                                       Http2StreamId stream_id, size_t length,
-                                       uint8_t flags, uint32_t error_code) {
-  events_.push_back(absl::StrFormat("OnFrameSent %d %d %d %d %d", frame_type,
-                                    stream_id, length, flags, error_code));
-  return 0;
-}
-
-bool RecordingHttp2Visitor::OnInvalidFrame(Http2StreamId stream_id,
-                                           InvalidFrameError error) {
-  events_.push_back(absl::StrFormat("OnInvalidFrame %d %s", stream_id,
-                                    InvalidFrameErrorToString(error)));
-  return true;
-}
-
-void RecordingHttp2Visitor::OnBeginMetadataForStream(Http2StreamId stream_id,
-                                                     size_t payload_length) {
-  events_.push_back(absl::StrFormat("OnBeginMetadataForStream %d %d", stream_id,
-                                    payload_length));
-}
-
-bool RecordingHttp2Visitor::OnMetadataForStream(Http2StreamId stream_id,
-                                                absl::string_view metadata) {
-  events_.push_back(
-      absl::StrFormat("OnMetadataForStream %d %s", stream_id, metadata));
-  return true;
-}
-
-bool RecordingHttp2Visitor::OnMetadataEndForStream(Http2StreamId stream_id) {
-  events_.push_back(absl::StrFormat("OnMetadataEndForStream %d", stream_id));
-  return true;
-}
-
-void RecordingHttp2Visitor::OnErrorDebug(absl::string_view message) {
-  events_.push_back(absl::StrFormat("OnErrorDebug %s", message));
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/recording_http2_visitor.h b/http2/adapter/recording_http2_visitor.h
deleted file mode 100644
index 144b5fb..0000000
--- a/http2/adapter/recording_http2_visitor.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_RECORDING_HTTP2_VISITOR_H_
-#define QUICHE_HTTP2_ADAPTER_RECORDING_HTTP2_VISITOR_H_
-
-#include <cstdint>
-#include <list>
-#include <string>
-
-#include "http2/adapter/http2_visitor_interface.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-// A visitor implementation that records the sequence of callbacks it receives.
-class QUICHE_NO_EXPORT RecordingHttp2Visitor : public Http2VisitorInterface {
- public:
-  using Event = std::string;
-  using EventSequence = std::list<Event>;
-
-  // From Http2VisitorInterface
-  int64_t OnReadyToSend(absl::string_view serialized) override;
-  void OnConnectionError(ConnectionError error) override;
-  bool OnFrameHeader(Http2StreamId stream_id, size_t length, uint8_t type,
-                     uint8_t flags) override;
-  void OnSettingsStart() override;
-  void OnSetting(Http2Setting setting) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck() override;
-  bool OnBeginHeadersForStream(Http2StreamId stream_id) override;
-  OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
-                                   absl::string_view name,
-                                   absl::string_view value) override;
-  bool OnEndHeadersForStream(Http2StreamId stream_id) override;
-  bool OnDataPaddingLength(Http2StreamId stream_id,
-                           size_t padding_length) override;
-  bool OnBeginDataForStream(Http2StreamId stream_id,
-                            size_t payload_length) override;
-  bool OnDataForStream(Http2StreamId stream_id,
-                       absl::string_view data) override;
-  void OnEndStream(Http2StreamId stream_id) override;
-  void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
-  bool OnCloseStream(Http2StreamId stream_id,
-                     Http2ErrorCode error_code) override;
-  void OnPriorityForStream(Http2StreamId stream_id,
-                           Http2StreamId parent_stream_id,
-                           int weight,
-                           bool exclusive) override;
-  void OnPing(Http2PingId ping_id, bool is_ack) override;
-  void OnPushPromiseForStream(Http2StreamId stream_id,
-                              Http2StreamId promised_stream_id) override;
-  bool OnGoAway(Http2StreamId last_accepted_stream_id,
-                Http2ErrorCode error_code,
-                absl::string_view opaque_data) override;
-  void OnWindowUpdate(Http2StreamId stream_id, int window_increment) override;
-  int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
-                        size_t length, uint8_t flags) override;
-  int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length,
-                  uint8_t flags, uint32_t error_code) override;
-  bool OnInvalidFrame(Http2StreamId stream_id,
-                      InvalidFrameError error) override;
-  void OnBeginMetadataForStream(Http2StreamId stream_id,
-                                size_t payload_length) override;
-  bool OnMetadataForStream(Http2StreamId stream_id,
-                           absl::string_view metadata) override;
-  bool OnMetadataEndForStream(Http2StreamId stream_id) override;
-  void OnErrorDebug(absl::string_view message) override;
-
-  const EventSequence& GetEventSequence() const { return events_; }
-  void Clear() { events_.clear(); }
-
- private:
-  EventSequence events_;
-};
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_RECORDING_HTTP2_VISITOR_H_
diff --git a/http2/adapter/recording_http2_visitor_test.cc b/http2/adapter/recording_http2_visitor_test.cc
deleted file mode 100644
index d8d3ea7..0000000
--- a/http2/adapter/recording_http2_visitor_test.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "http2/adapter/recording_http2_visitor.h"
-
-#include <list>
-
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using ::testing::IsEmpty;
-
-TEST(RecordingHttp2VisitorTest, EmptySequence) {
-  RecordingHttp2Visitor chocolate_visitor;
-  RecordingHttp2Visitor vanilla_visitor;
-
-  EXPECT_THAT(chocolate_visitor.GetEventSequence(), IsEmpty());
-  EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
-  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-
-  chocolate_visitor.OnSettingsStart();
-
-  EXPECT_THAT(chocolate_visitor.GetEventSequence(), testing::Not(IsEmpty()));
-  EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
-  EXPECT_NE(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-
-  chocolate_visitor.Clear();
-
-  EXPECT_THAT(chocolate_visitor.GetEventSequence(), IsEmpty());
-  EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
-  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-}
-
-TEST(RecordingHttp2VisitorTest, SameEventsProduceSameSequence) {
-  RecordingHttp2Visitor chocolate_visitor;
-  RecordingHttp2Visitor vanilla_visitor;
-
-  // Prepare some random values to deliver with the events.
-  http2::test::Http2Random random;
-  const Http2StreamId stream_id = random.Uniform(kMaxStreamId);
-  const Http2StreamId another_stream_id = random.Uniform(kMaxStreamId);
-  const size_t length = random.Rand16();
-  const uint8_t type = random.Rand8();
-  const uint8_t flags = random.Rand8();
-  const Http2ErrorCode error_code = static_cast<Http2ErrorCode>(
-      random.Uniform(static_cast<int>(Http2ErrorCode::MAX_ERROR_CODE)));
-  const Http2Setting setting = {.id = random.Rand16(),
-                                .value = random.Rand32()};
-  const absl::string_view alphabet = "abcdefghijklmnopqrstuvwxyz0123456789-";
-  const std::string some_string =
-      random.RandStringWithAlphabet(random.Rand8(), alphabet);
-  const std::string another_string =
-      random.RandStringWithAlphabet(random.Rand8(), alphabet);
-  const uint16_t some_int = random.Rand16();
-  const bool some_bool = random.OneIn(2);
-
-  // Send the same arbitrary sequence of events to both visitors.
-  std::list<RecordingHttp2Visitor*> visitors = {&chocolate_visitor,
-                                                &vanilla_visitor};
-  for (RecordingHttp2Visitor* visitor : visitors) {
-    visitor->OnConnectionError(
-        Http2VisitorInterface::ConnectionError::kSendError);
-    visitor->OnFrameHeader(stream_id, length, type, flags);
-    visitor->OnSettingsStart();
-    visitor->OnSetting(setting);
-    visitor->OnSettingsEnd();
-    visitor->OnSettingsAck();
-    visitor->OnBeginHeadersForStream(stream_id);
-    visitor->OnHeaderForStream(stream_id, some_string, another_string);
-    visitor->OnEndHeadersForStream(stream_id);
-    visitor->OnBeginDataForStream(stream_id, length);
-    visitor->OnDataForStream(stream_id, some_string);
-    visitor->OnDataForStream(stream_id, another_string);
-    visitor->OnEndStream(stream_id);
-    visitor->OnRstStream(stream_id, error_code);
-    visitor->OnCloseStream(stream_id, error_code);
-    visitor->OnPriorityForStream(stream_id, another_stream_id, some_int,
-                                 some_bool);
-    visitor->OnPing(some_int, some_bool);
-    visitor->OnPushPromiseForStream(stream_id, another_stream_id);
-    visitor->OnGoAway(stream_id, error_code, some_string);
-    visitor->OnWindowUpdate(stream_id, some_int);
-    visitor->OnBeginMetadataForStream(stream_id, length);
-    visitor->OnMetadataForStream(stream_id, some_string);
-    visitor->OnMetadataForStream(stream_id, another_string);
-    visitor->OnMetadataEndForStream(stream_id);
-  }
-
-  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-}
-
-TEST(RecordingHttp2VisitorTest, DifferentEventsProduceDifferentSequence) {
-  RecordingHttp2Visitor chocolate_visitor;
-  RecordingHttp2Visitor vanilla_visitor;
-  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-
-  const Http2StreamId stream_id = 1;
-  const size_t length = 42;
-
-  // Different events with the same method arguments should produce different
-  // event sequences.
-  chocolate_visitor.OnBeginDataForStream(stream_id, length);
-  vanilla_visitor.OnBeginMetadataForStream(stream_id, length);
-  EXPECT_NE(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-
-  chocolate_visitor.Clear();
-  vanilla_visitor.Clear();
-  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-
-  // The same events with different method arguments should produce different
-  // event sequences.
-  chocolate_visitor.OnBeginHeadersForStream(stream_id);
-  vanilla_visitor.OnBeginHeadersForStream(stream_id + 2);
-  EXPECT_NE(chocolate_visitor.GetEventSequence(),
-            vanilla_visitor.GetEventSequence());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/test_frame_sequence.cc b/http2/adapter/test_frame_sequence.cc
deleted file mode 100644
index ed9018a..0000000
--- a/http2/adapter/test_frame_sequence.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-#include "http2/adapter/test_frame_sequence.h"
-
-#include "http2/adapter/http2_util.h"
-#include "http2/adapter/oghttp2_util.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-std::vector<Header> ToHeaders(
-    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers) {
-  std::vector<Header> out;
-  for (auto [name, value] : headers) {
-    out.push_back(std::make_pair(HeaderRep(name), HeaderRep(value)));
-  }
-  return out;
-}
-
-TestFrameSequence& TestFrameSequence::ClientPreface(
-    absl::Span<const Http2Setting> settings) {
-  preface_ = spdy::kHttp2ConnectionHeaderPrefix;
-  return Settings(settings);
-}
-
-TestFrameSequence& TestFrameSequence::ServerPreface(
-    absl::Span<const Http2Setting> settings) {
-  return Settings(settings);
-}
-
-TestFrameSequence& TestFrameSequence::Data(Http2StreamId stream_id,
-                                           absl::string_view payload,
-                                           bool fin,
-                                           absl::optional<int> padding_length) {
-  auto data = absl::make_unique<spdy::SpdyDataIR>(stream_id, payload);
-  data->set_fin(fin);
-  if (padding_length) {
-    data->set_padding_len(padding_length.value());
-  }
-  frames_.push_back(std::move(data));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::RstStream(Http2StreamId stream_id,
-                                                Http2ErrorCode error) {
-  frames_.push_back(absl::make_unique<spdy::SpdyRstStreamIR>(
-      stream_id, TranslateErrorCode(error)));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::Settings(
-    absl::Span<const Http2Setting> settings) {
-  auto settings_frame = absl::make_unique<spdy::SpdySettingsIR>();
-  for (const Http2Setting& setting : settings) {
-    settings_frame->AddSetting(setting.id, setting.value);
-  }
-  frames_.push_back(std::move(settings_frame));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::SettingsAck() {
-  auto settings = absl::make_unique<spdy::SpdySettingsIR>();
-  settings->set_is_ack(true);
-  frames_.push_back(std::move(settings));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::PushPromise(
-    Http2StreamId stream_id, Http2StreamId promised_stream_id,
-    absl::Span<const Header> headers) {
-  frames_.push_back(absl::make_unique<spdy::SpdyPushPromiseIR>(
-      stream_id, promised_stream_id, ToHeaderBlock(headers)));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::Ping(Http2PingId id) {
-  frames_.push_back(absl::make_unique<spdy::SpdyPingIR>(id));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::PingAck(Http2PingId id) {
-  auto ping = absl::make_unique<spdy::SpdyPingIR>(id);
-  ping->set_is_ack(true);
-  frames_.push_back(std::move(ping));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::GoAway(Http2StreamId last_good_stream_id,
-                                             Http2ErrorCode error,
-                                             absl::string_view payload) {
-  frames_.push_back(absl::make_unique<spdy::SpdyGoAwayIR>(
-      last_good_stream_id, TranslateErrorCode(error), std::string(payload)));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::Headers(
-    Http2StreamId stream_id,
-    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers,
-    bool fin, bool add_continuation) {
-  return Headers(stream_id, ToHeaders(headers), fin, add_continuation);
-}
-
-TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
-                                              spdy::Http2HeaderBlock block,
-                                              bool fin, bool add_continuation) {
-  if (add_continuation) {
-    // The normal intermediate representations don't allow you to represent a
-    // nonterminal HEADERS frame explicitly, so we'll need to use
-    // SpdyUnknownIRs. For simplicity, and in order not to mess up HPACK state,
-    // the payload will be uncompressed.
-    spdy::HpackEncoder encoder;
-    encoder.DisableCompression();
-    std::string encoded_block = encoder.EncodeHeaderBlock(block);
-    const size_t pos = encoded_block.size() / 2;
-    const uint8_t flags = fin ? 0x1 : 0x0;
-    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
-        stream_id, static_cast<uint8_t>(spdy::SpdyFrameType::HEADERS), flags,
-        encoded_block.substr(0, pos)));
-
-    auto continuation = absl::make_unique<spdy::SpdyContinuationIR>(stream_id);
-    continuation->set_end_headers(true);
-    continuation->take_encoding(encoded_block.substr(pos));
-    frames_.push_back(std::move(continuation));
-  } else {
-    auto headers =
-        absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(block));
-    headers->set_fin(fin);
-    frames_.push_back(std::move(headers));
-  }
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
-                                              absl::Span<const Header> headers,
-                                              bool fin, bool add_continuation) {
-  return Headers(stream_id, ToHeaderBlock(headers), fin, add_continuation);
-}
-
-TestFrameSequence& TestFrameSequence::WindowUpdate(Http2StreamId stream_id,
-                                                   int32_t delta) {
-  frames_.push_back(
-      absl::make_unique<spdy::SpdyWindowUpdateIR>(stream_id, delta));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::Priority(Http2StreamId stream_id,
-                                               Http2StreamId parent_stream_id,
-                                               int weight,
-                                               bool exclusive) {
-  frames_.push_back(absl::make_unique<spdy::SpdyPriorityIR>(
-      stream_id, parent_stream_id, weight, exclusive));
-  return *this;
-}
-
-TestFrameSequence& TestFrameSequence::Metadata(Http2StreamId stream_id,
-                                               absl::string_view payload,
-                                               bool multiple_frames) {
-  if (multiple_frames) {
-    const size_t pos = payload.size() / 2;
-    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
-        stream_id, kMetadataFrameType, 0, std::string(payload.substr(0, pos))));
-    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
-        stream_id, kMetadataFrameType, kMetadataEndFlag,
-        std::string(payload.substr(pos))));
-  } else {
-    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
-        stream_id, kMetadataFrameType, kMetadataEndFlag, std::string(payload)));
-  }
-  return *this;
-}
-
-std::string TestFrameSequence::Serialize() {
-  std::string result;
-  if (!preface_.empty()) {
-    result = preface_;
-  }
-  spdy::SpdyFramer framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
-  for (const auto& frame : frames_) {
-    spdy::SpdySerializedFrame f = framer.SerializeFrame(*frame);
-    absl::StrAppend(&result, absl::string_view(f));
-  }
-  return result;
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/test_frame_sequence.h b/http2/adapter/test_frame_sequence.h
deleted file mode 100644
index 0eddf41..0000000
--- a/http2/adapter/test_frame_sequence.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_TEST_FRAME_SEQUENCE_H_
-#define QUICHE_HTTP2_ADAPTER_TEST_FRAME_SEQUENCE_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "http2/adapter/http2_protocol.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-std::vector<Header> QUICHE_NO_EXPORT ToHeaders(
-    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers);
-
-class QUICHE_NO_EXPORT TestFrameSequence {
- public:
-  TestFrameSequence() = default;
-
-  TestFrameSequence& ClientPreface(
-      absl::Span<const Http2Setting> settings = {});
-  TestFrameSequence& ServerPreface(
-      absl::Span<const Http2Setting> settings = {});
-  TestFrameSequence& Data(Http2StreamId stream_id,
-                          absl::string_view payload,
-                          bool fin = false,
-                          absl::optional<int> padding_length = absl::nullopt);
-  TestFrameSequence& RstStream(Http2StreamId stream_id, Http2ErrorCode error);
-  TestFrameSequence& Settings(absl::Span<const Http2Setting> settings);
-  TestFrameSequence& SettingsAck();
-  TestFrameSequence& PushPromise(Http2StreamId stream_id,
-                                 Http2StreamId promised_stream_id,
-                                 absl::Span<const Header> headers);
-  TestFrameSequence& Ping(Http2PingId id);
-  TestFrameSequence& PingAck(Http2PingId id);
-  TestFrameSequence& GoAway(Http2StreamId last_good_stream_id,
-                            Http2ErrorCode error,
-                            absl::string_view payload = "");
-  TestFrameSequence& Headers(
-      Http2StreamId stream_id,
-      absl::Span<const std::pair<absl::string_view, absl::string_view>> headers,
-      bool fin = false, bool add_continuation = false);
-  TestFrameSequence& Headers(Http2StreamId stream_id,
-                             spdy::Http2HeaderBlock block, bool fin = false,
-                             bool add_continuation = false);
-  TestFrameSequence& Headers(Http2StreamId stream_id,
-                             absl::Span<const Header> headers, bool fin = false,
-                             bool add_continuation = false);
-  TestFrameSequence& WindowUpdate(Http2StreamId stream_id, int32_t delta);
-  TestFrameSequence& Priority(Http2StreamId stream_id,
-                              Http2StreamId parent_stream_id,
-                              int weight,
-                              bool exclusive);
-  TestFrameSequence& Metadata(Http2StreamId stream_id,
-                              absl::string_view payload,
-                              bool multiple_frames = false);
-
-  std::string Serialize();
-
- private:
-  std::string preface_;
-  std::vector<std::unique_ptr<spdy::SpdyFrameIR>> frames_;
-};
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_TEST_FRAME_SEQUENCE_H_
diff --git a/http2/adapter/test_utils.cc b/http2/adapter/test_utils.cc
deleted file mode 100644
index d56acda..0000000
--- a/http2/adapter/test_utils.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-#include "http2/adapter/test_utils.h"
-
-#include <ostream>
-
-#include "absl/strings/str_format.h"
-#include "http2/adapter/http2_visitor_interface.h"
-#include "common/quiche_data_reader.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using ConnectionError = Http2VisitorInterface::ConnectionError;
-
-}  // anonymous namespace
-
-TestDataFrameSource::TestDataFrameSource(Http2VisitorInterface& visitor,
-                                         bool has_fin)
-    : visitor_(visitor), has_fin_(has_fin) {}
-
-void TestDataFrameSource::AppendPayload(absl::string_view payload) {
-  QUICHE_CHECK(!end_data_);
-  if (!payload.empty()) {
-    payload_fragments_.push_back(std::string(payload));
-    current_fragment_ = payload_fragments_.front();
-  }
-}
-
-void TestDataFrameSource::EndData() { end_data_ = true; }
-
-std::pair<int64_t, bool> TestDataFrameSource::SelectPayloadLength(
-    size_t max_length) {
-  if (return_error_) {
-    return {DataFrameSource::kError, false};
-  }
-  // The stream is done if there's no more data, or if |max_length| is at least
-  // as large as the remaining data.
-  const bool end_data = end_data_ && (current_fragment_.empty() ||
-                                      (payload_fragments_.size() == 1 &&
-                                       max_length >= current_fragment_.size()));
-  const int64_t length = std::min(max_length, current_fragment_.size());
-  return {length, end_data};
-}
-
-bool TestDataFrameSource::Send(absl::string_view frame_header,
-                               size_t payload_length) {
-  QUICHE_LOG_IF(DFATAL, payload_length > current_fragment_.size())
-      << "payload_length: " << payload_length
-      << " current_fragment_size: " << current_fragment_.size();
-  const std::string concatenated =
-      absl::StrCat(frame_header, current_fragment_.substr(0, payload_length));
-  const int64_t result = visitor_.OnReadyToSend(concatenated);
-  if (result < 0) {
-    // Write encountered error.
-    visitor_.OnConnectionError(ConnectionError::kSendError);
-    current_fragment_ = {};
-    payload_fragments_.clear();
-    return false;
-  } else if (result == 0) {
-    // Write blocked.
-    return false;
-  } else if (static_cast<const size_t>(result) < concatenated.size()) {
-    // Probably need to handle this better within this test class.
-    QUICHE_LOG(DFATAL)
-        << "DATA frame not fully flushed. Connection will be corrupt!";
-    visitor_.OnConnectionError(ConnectionError::kSendError);
-    current_fragment_ = {};
-    payload_fragments_.clear();
-    return false;
-  }
-  if (payload_length > 0) {
-    current_fragment_.remove_prefix(payload_length);
-  }
-  if (current_fragment_.empty() && !payload_fragments_.empty()) {
-    payload_fragments_.erase(payload_fragments_.begin());
-    if (!payload_fragments_.empty()) {
-      current_fragment_ = payload_fragments_.front();
-    }
-  }
-  return true;
-}
-
-std::string EncodeHeaders(const spdy::SpdyHeaderBlock& entries) {
-  spdy::HpackEncoder encoder;
-  encoder.DisableCompression();
-  return encoder.EncodeHeaderBlock(entries);
-}
-
-TestMetadataSource::TestMetadataSource(const spdy::SpdyHeaderBlock& entries)
-    : encoded_entries_(EncodeHeaders(entries)) {
-  remaining_ = encoded_entries_;
-}
-
-std::pair<int64_t, bool> TestMetadataSource::Pack(uint8_t* dest,
-                                                  size_t dest_len) {
-  const size_t copied = std::min(dest_len, remaining_.size());
-  std::memcpy(dest, remaining_.data(), copied);
-  remaining_.remove_prefix(copied);
-  return std::make_pair(copied, remaining_.empty());
-}
-
-namespace {
-
-using TypeAndOptionalLength =
-    std::pair<spdy::SpdyFrameType, absl::optional<size_t>>;
-
-std::ostream& operator<<(
-    std::ostream& os,
-    const std::vector<TypeAndOptionalLength>& types_and_lengths) {
-  for (const auto& type_and_length : types_and_lengths) {
-    os << "(" << spdy::FrameTypeToString(type_and_length.first) << ", "
-       << (type_and_length.second ? absl::StrCat(type_and_length.second.value())
-                                  : "<unspecified>")
-       << ") ";
-  }
-  return os;
-}
-
-std::string FrameTypeToString(uint8_t frame_type) {
-  if (spdy::IsDefinedFrameType(frame_type)) {
-    return spdy::FrameTypeToString(spdy::ParseFrameType(frame_type));
-  } else {
-    return absl::StrFormat("0x%x", static_cast<int>(frame_type));
-  }
-}
-
-// Custom gMock matcher, used to implement EqualsFrames().
-class SpdyControlFrameMatcher
-    : public testing::MatcherInterface<absl::string_view> {
- public:
-  explicit SpdyControlFrameMatcher(
-      std::vector<TypeAndOptionalLength> types_and_lengths)
-      : expected_types_and_lengths_(std::move(types_and_lengths)) {}
-
-  bool MatchAndExplain(absl::string_view s,
-                       testing::MatchResultListener* listener) const override {
-    quiche::QuicheDataReader reader(s.data(), s.size());
-
-    for (TypeAndOptionalLength expected : expected_types_and_lengths_) {
-      if (!MatchAndExplainOneFrame(expected.first, expected.second, &reader,
-                                   listener)) {
-        return false;
-      }
-    }
-    if (!reader.IsDoneReading()) {
-      *listener << "; " << reader.BytesRemaining() << " bytes left to read!";
-      return false;
-    }
-    return true;
-  }
-
-  bool MatchAndExplainOneFrame(spdy::SpdyFrameType expected_type,
-                               absl::optional<size_t> expected_length,
-                               quiche::QuicheDataReader* reader,
-                               testing::MatchResultListener* listener) const {
-    uint32_t payload_length;
-    if (!reader->ReadUInt24(&payload_length)) {
-      *listener << "; unable to read length field for expected_type "
-                << FrameTypeToString(expected_type) << ". data too short!";
-      return false;
-    }
-
-    if (expected_length && payload_length != expected_length.value()) {
-      *listener << "; actual length: " << payload_length
-                << " but expected length: " << expected_length.value();
-      return false;
-    }
-
-    uint8_t raw_type;
-    if (!reader->ReadUInt8(&raw_type)) {
-      *listener << "; unable to read type field for expected_type "
-                << FrameTypeToString(expected_type) << ". data too short!";
-      return false;
-    }
-
-    if (raw_type != static_cast<uint8_t>(expected_type)) {
-      *listener << "; actual type: " << FrameTypeToString(raw_type)
-                << " but expected type: " << FrameTypeToString(expected_type);
-      return false;
-    }
-
-    // Seek past flags (1B), stream ID (4B), and payload. Reach the next frame.
-    reader->Seek(5 + payload_length);
-    return true;
-  }
-
-  void DescribeTo(std::ostream* os) const override {
-    *os << "Data contains frames of types in sequence "
-        << expected_types_and_lengths_;
-  }
-
-  void DescribeNegationTo(std::ostream* os) const override {
-    *os << "Data does not contain frames of types in sequence "
-        << expected_types_and_lengths_;
-  }
-
- private:
-  const std::vector<TypeAndOptionalLength> expected_types_and_lengths_;
-};
-
-}  // namespace
-
-testing::Matcher<absl::string_view> EqualsFrames(
-    std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
-        types_and_lengths) {
-  return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
-}
-
-testing::Matcher<absl::string_view> EqualsFrames(
-    std::vector<spdy::SpdyFrameType> types) {
-  std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
-      types_and_lengths;
-  types_and_lengths.reserve(types.size());
-  for (spdy::SpdyFrameType type : types) {
-    types_and_lengths.push_back({type, absl::nullopt});
-  }
-  return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
-}
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/test_utils.h b/http2/adapter/test_utils.h
deleted file mode 100644
index be53ba8..0000000
--- a/http2/adapter/test_utils.h
+++ /dev/null
@@ -1,139 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
-#define QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "http2/adapter/data_source.h"
-#include "http2/adapter/http2_protocol.h"
-#include "http2/adapter/mock_http2_visitor.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-class QUICHE_NO_EXPORT DataSavingVisitor
-    : public testing::StrictMock<MockHttp2Visitor> {
- public:
-  int64_t OnReadyToSend(absl::string_view data) override {
-    if (has_write_error_) {
-      return kSendError;
-    }
-    if (is_write_blocked_) {
-      return kSendBlocked;
-    }
-    const size_t to_accept = std::min(send_limit_, data.size());
-    if (to_accept == 0) {
-      return kSendBlocked;
-    }
-    absl::StrAppend(&data_, data.substr(0, to_accept));
-    return to_accept;
-  }
-
-  bool OnMetadataForStream(Http2StreamId stream_id,
-                           absl::string_view metadata) override {
-    const bool ret = testing::StrictMock<MockHttp2Visitor>::OnMetadataForStream(
-        stream_id, metadata);
-    if (ret) {
-      auto result =
-          metadata_map_.try_emplace(stream_id, std::vector<std::string>());
-      result.first->second.push_back(std::string(metadata));
-    }
-    return ret;
-  }
-
-  const std::vector<std::string> GetMetadata(Http2StreamId stream_id) {
-    auto it = metadata_map_.find(stream_id);
-    if (it == metadata_map_.end()) {
-      return {};
-    } else {
-      return it->second;
-    }
-  }
-
-  const std::string& data() { return data_; }
-  void Clear() { data_.clear(); }
-
-  void set_send_limit(size_t limit) { send_limit_ = limit; }
-
-  bool is_write_blocked() const { return is_write_blocked_; }
-  void set_is_write_blocked(bool value) { is_write_blocked_ = value; }
-
-  void set_has_write_error() { has_write_error_ = true; }
-
- private:
-  std::string data_;
-  absl::flat_hash_map<Http2StreamId, std::vector<std::string>> metadata_map_;
-  size_t send_limit_ = std::numeric_limits<size_t>::max();
-  bool is_write_blocked_ = false;
-  bool has_write_error_ = false;
-};
-
-// A test DataFrameSource. Starts out in the empty, blocked state.
-class QUICHE_NO_EXPORT TestDataFrameSource : public DataFrameSource {
- public:
-  TestDataFrameSource(Http2VisitorInterface& visitor, bool has_fin);
-
-  void AppendPayload(absl::string_view payload);
-  void EndData();
-  void SimulateError() { return_error_ = true; }
-
-  std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) override;
-  bool Send(absl::string_view frame_header, size_t payload_length) override;
-  bool send_fin() const override { return has_fin_; }
-
- private:
-  Http2VisitorInterface& visitor_;
-  std::vector<std::string> payload_fragments_;
-  absl::string_view current_fragment_;
-  // Whether the stream should end with the final frame of data.
-  const bool has_fin_;
-  // Whether |payload_fragments_| contains the final segment of data.
-  bool end_data_ = false;
-  // Whether SelectPayloadLength() should return an error.
-  bool return_error_ = false;
-};
-
-class QUICHE_NO_EXPORT TestMetadataSource : public MetadataSource {
- public:
-  explicit TestMetadataSource(const spdy::SpdyHeaderBlock& entries);
-
-  size_t NumFrames(size_t max_frame_size) const override {
-    // Round up to the next frame.
-    return (encoded_entries_.size() + max_frame_size - 1) / max_frame_size;
-  }
-  std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override;
-  void OnFailure() override {}
-
- private:
-  const std::string encoded_entries_;
-  absl::string_view remaining_;
-};
-
-// These matchers check whether a string consists entirely of HTTP/2 frames of
-// the specified ordered sequence. This is useful in tests where we want to show
-// that one or more particular frame types are serialized for sending to the
-// peer. The match will fail if there are input bytes not consumed by the
-// matcher.
-
-// Requires that frames match both types and lengths.
-testing::Matcher<absl::string_view> EqualsFrames(
-    std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
-        types_and_lengths);
-
-// Requires that frames match the specified types.
-testing::Matcher<absl::string_view> EqualsFrames(
-    std::vector<spdy::SpdyFrameType> types);
-
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
diff --git a/http2/adapter/test_utils_test.cc b/http2/adapter/test_utils_test.cc
deleted file mode 100644
index 0de7b28..0000000
--- a/http2/adapter/test_utils_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-#include "http2/adapter/test_utils.h"
-
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-namespace {
-
-using spdy::SpdyFramer;
-
-TEST(EqualsFrames, Empty) {
-  EXPECT_THAT("", EqualsFrames(std::vector<spdy::SpdyFrameType>{}));
-}
-
-TEST(EqualsFrames, SingleFrameWithLength) {
-  SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
-
-  spdy::SpdyPingIR ping{511};
-  EXPECT_THAT(framer.SerializeFrame(ping),
-              EqualsFrames({{spdy::SpdyFrameType::PING, 8}}));
-
-  spdy::SpdyWindowUpdateIR window_update{1, 101};
-  EXPECT_THAT(framer.SerializeFrame(window_update),
-              EqualsFrames({{spdy::SpdyFrameType::WINDOW_UPDATE, 4}}));
-
-  spdy::SpdyDataIR data{3, "Some example data, ha ha!"};
-  EXPECT_THAT(framer.SerializeFrame(data),
-              EqualsFrames({{spdy::SpdyFrameType::DATA, 25}}));
-}
-
-TEST(EqualsFrames, SingleFrameWithoutLength) {
-  SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
-
-  spdy::SpdyRstStreamIR rst_stream{7, spdy::ERROR_CODE_REFUSED_STREAM};
-  EXPECT_THAT(framer.SerializeFrame(rst_stream),
-              EqualsFrames({{spdy::SpdyFrameType::RST_STREAM, absl::nullopt}}));
-
-  spdy::SpdyGoAwayIR goaway{13, spdy::ERROR_CODE_ENHANCE_YOUR_CALM,
-                            "Consider taking some deep breaths."};
-  EXPECT_THAT(framer.SerializeFrame(goaway),
-              EqualsFrames({{spdy::SpdyFrameType::GOAWAY, absl::nullopt}}));
-
-  spdy::Http2HeaderBlock block;
-  block[":method"] = "GET";
-  block[":path"] = "/example";
-  block[":authority"] = "example.com";
-  spdy::SpdyHeadersIR headers{17, std::move(block)};
-  EXPECT_THAT(framer.SerializeFrame(headers),
-              EqualsFrames({{spdy::SpdyFrameType::HEADERS, absl::nullopt}}));
-}
-
-TEST(EqualsFrames, MultipleFrames) {
-  SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
-
-  spdy::SpdyPingIR ping{511};
-  spdy::SpdyWindowUpdateIR window_update{1, 101};
-  spdy::SpdyDataIR data{3, "Some example data, ha ha!"};
-  spdy::SpdyRstStreamIR rst_stream{7, spdy::ERROR_CODE_REFUSED_STREAM};
-  spdy::SpdyGoAwayIR goaway{13, spdy::ERROR_CODE_ENHANCE_YOUR_CALM,
-                            "Consider taking some deep breaths."};
-  spdy::Http2HeaderBlock block;
-  block[":method"] = "GET";
-  block[":path"] = "/example";
-  block[":authority"] = "example.com";
-  spdy::SpdyHeadersIR headers{17, std::move(block)};
-
-  const std::string frame_sequence =
-      absl::StrCat(absl::string_view(framer.SerializeFrame(ping)),
-                   absl::string_view(framer.SerializeFrame(window_update)),
-                   absl::string_view(framer.SerializeFrame(data)),
-                   absl::string_view(framer.SerializeFrame(rst_stream)),
-                   absl::string_view(framer.SerializeFrame(goaway)),
-                   absl::string_view(framer.SerializeFrame(headers)));
-  absl::string_view frame_sequence_view = frame_sequence;
-  EXPECT_THAT(frame_sequence,
-              EqualsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
-                            {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
-                            {spdy::SpdyFrameType::DATA, 25},
-                            {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
-                            {spdy::SpdyFrameType::GOAWAY, 42},
-                            {spdy::SpdyFrameType::HEADERS, 19}}));
-  EXPECT_THAT(frame_sequence_view,
-              EqualsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
-                            {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
-                            {spdy::SpdyFrameType::DATA, 25},
-                            {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
-                            {spdy::SpdyFrameType::GOAWAY, 42},
-                            {spdy::SpdyFrameType::HEADERS, 19}}));
-  EXPECT_THAT(
-      frame_sequence,
-      EqualsFrames(
-          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
-           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
-           spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::HEADERS}));
-  EXPECT_THAT(
-      frame_sequence_view,
-      EqualsFrames(
-          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
-           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
-           spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::HEADERS}));
-
-  // If the final frame type is removed the expectation fails, as there are
-  // bytes left to read.
-  EXPECT_THAT(
-      frame_sequence,
-      testing::Not(EqualsFrames(
-          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
-           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
-           spdy::SpdyFrameType::GOAWAY})));
-  EXPECT_THAT(
-      frame_sequence_view,
-      testing::Not(EqualsFrames(
-          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
-           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
-           spdy::SpdyFrameType::GOAWAY})));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/window_manager.cc b/http2/adapter/window_manager.cc
deleted file mode 100644
index eca9031..0000000
--- a/http2/adapter/window_manager.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "http2/adapter/window_manager.h"
-
-#include <utility>
-
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace http2 {
-namespace adapter {
-
-bool DefaultShouldWindowUpdateFn(int64_t limit, int64_t window, int64_t delta) {
-  // For the sake of efficiency, we want to send window updates if less than
-  // half of the max quota is available to the peer at any point in time.
-  const int64_t kDesiredMinWindow = limit / 2;
-  const int64_t kDesiredMinDelta = limit / 3;
-  if (delta >= kDesiredMinDelta) {
-    // This particular window update was sent because the available delta
-    // exceeded the desired minimum.
-    return true;
-  } else if (window < kDesiredMinWindow) {
-    // This particular window update was sent because the quota available to the
-    // peer at this moment is less than the desired minimum.
-    return true;
-  }
-  return false;
-}
-
-WindowManager::WindowManager(int64_t window_size_limit,
-                             WindowUpdateListener listener,
-                             ShouldWindowUpdateFn should_window_update_fn,
-                             bool update_window_on_notify)
-    : limit_(window_size_limit),
-      window_(window_size_limit),
-      buffered_(0),
-      listener_(std::move(listener)),
-      should_window_update_fn_(std::move(should_window_update_fn)),
-      update_window_on_notify_(update_window_on_notify) {
-  if (!should_window_update_fn_) {
-    should_window_update_fn_ = DefaultShouldWindowUpdateFn;
-  }
-}
-
-void WindowManager::OnWindowSizeLimitChange(const int64_t new_limit) {
-  QUICHE_VLOG(2) << "WindowManager@" << this
-                 << " OnWindowSizeLimitChange from old limit of " << limit_
-                 << " to new limit of " << new_limit;
-  window_ += (new_limit - limit_);
-  limit_ = new_limit;
-}
-
-void WindowManager::SetWindowSizeLimit(int64_t new_limit) {
-  QUICHE_VLOG(2) << "WindowManager@" << this
-                 << " SetWindowSizeLimit from old limit of " << limit_
-                 << " to new limit of " << new_limit;
-  limit_ = new_limit;
-  MaybeNotifyListener();
-}
-
-bool WindowManager::MarkDataBuffered(int64_t bytes) {
-  QUICHE_VLOG(2) << "WindowManager@" << this << " window: " << window_
-                 << " bytes: " << bytes;
-  if (window_ < bytes) {
-    QUICHE_VLOG(2) << "WindowManager@" << this << " window underflow "
-                   << "window: " << window_ << " bytes: " << bytes;
-    window_ = 0;
-  } else {
-    window_ -= bytes;
-  }
-  buffered_ += bytes;
-  if (window_ == 0) {
-    // If data hasn't been flushed in a while there may be space available.
-    MaybeNotifyListener();
-  }
-  return window_ > 0;
-}
-
-void WindowManager::MarkDataFlushed(int64_t bytes) {
-  QUICHE_VLOG(2) << "WindowManager@" << this << " buffered: " << buffered_
-                 << " bytes: " << bytes;
-  if (buffered_ < bytes) {
-    QUICHE_BUG(bug_2816_1) << "WindowManager@" << this << " buffered underflow "
-                           << "buffered_: " << buffered_ << " bytes: " << bytes;
-    buffered_ = 0;
-  } else {
-    buffered_ -= bytes;
-  }
-  MaybeNotifyListener();
-}
-
-void WindowManager::MaybeNotifyListener() {
-  const int64_t delta = limit_ - (buffered_ + window_);
-  if (should_window_update_fn_(limit_, window_, delta) && delta > 0) {
-    QUICHE_VLOG(2) << "WindowManager@" << this
-                   << " Informing listener of delta: " << delta;
-    listener_(delta);
-    if (update_window_on_notify_) {
-      window_ += delta;
-    }
-  }
-}
-
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/adapter/window_manager.h b/http2/adapter/window_manager.h
deleted file mode 100644
index 48ec3d9..0000000
--- a/http2/adapter/window_manager.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_
-#define QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_
-
-#include <stddef.h>
-
-#include <functional>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace adapter {
-
-namespace test {
-class WindowManagerPeer;
-}
-
-// This class keeps track of a HTTP/2 flow control window, notifying a listener
-// when a window update needs to be sent. This class is not thread-safe.
-class QUICHE_EXPORT_PRIVATE WindowManager {
- public:
-  // A WindowUpdateListener is invoked when it is time to send a window update.
-  using WindowUpdateListener = std::function<void(int64_t)>;
-
-  // Invoked to determine whether to call the listener based on the window
-  // limit, window size, and delta that would be sent.
-  using ShouldWindowUpdateFn =
-      std::function<bool(int64_t limit, int64_t size, int64_t delta)>;
-
-  WindowManager(int64_t window_size_limit, WindowUpdateListener listener,
-                ShouldWindowUpdateFn should_window_update_fn = {},
-                bool update_window_on_notify = true);
-
-  int64_t CurrentWindowSize() const { return window_; }
-  int64_t WindowSizeLimit() const { return limit_; }
-
-  // Called when the window size limit is changed (typically via settings) but
-  // no window update should be sent.
-  void OnWindowSizeLimitChange(int64_t new_limit);
-
-  // Sets the window size limit to |new_limit| and notifies the listener to
-  // update as necessary.
-  void SetWindowSizeLimit(int64_t new_limit);
-
-  // Increments the running total of data bytes buffered. Returns true iff there
-  // is more window remaining.
-  bool MarkDataBuffered(int64_t bytes);
-
-  // Increments the running total of data bytes that have been flushed or
-  // dropped. Invokes the listener if the current window is smaller than some
-  // threshold and there is quota available to send.
-  void MarkDataFlushed(int64_t bytes);
-
-  // Convenience method, used when incoming data is immediately dropped or
-  // ignored.
-  void MarkWindowConsumed(int64_t bytes) {
-    MarkDataBuffered(bytes);
-    MarkDataFlushed(bytes);
-  }
-
-  // Increments the window size without affecting the limit. Useful if this end
-  // of a stream or connection issues a one-time WINDOW_UPDATE.
-  void IncreaseWindow(int64_t delta) { window_ += delta; }
-
- private:
-  friend class test::WindowManagerPeer;
-
-  void MaybeNotifyListener();
-
-  // The upper bound on the flow control window. The GFE attempts to maintain a
-  // window of this size at the peer as data is proxied through.
-  int64_t limit_;
-
-  // The current flow control window that has not been advertised to the peer
-  // and not yet consumed. The peer can send this many bytes before becoming
-  // blocked.
-  int64_t window_;
-
-  // The amount of data already buffered, which should count against the flow
-  // control window upper bound.
-  int64_t buffered_;
-
-  WindowUpdateListener listener_;
-
-  ShouldWindowUpdateFn should_window_update_fn_;
-
-  bool update_window_on_notify_;
-};
-
-}  // namespace adapter
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_
diff --git a/http2/adapter/window_manager_test.cc b/http2/adapter/window_manager_test.cc
deleted file mode 100644
index fd2327d..0000000
--- a/http2/adapter/window_manager_test.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-#include "http2/adapter/window_manager.h"
-
-#include <list>
-
-#include "absl/functional/bind_front.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-
-namespace http2 {
-namespace adapter {
-namespace test {
-
-// Use the peer to access private vars of WindowManager.
-class WindowManagerPeer {
- public:
-  explicit WindowManagerPeer(const WindowManager& wm) : wm_(wm) {}
-
-  int64_t buffered() { return wm_.buffered_; }
-
- private:
-  const WindowManager& wm_;
-};
-
-namespace {
-
-class WindowManagerTest : public ::testing::Test {
- protected:
-  WindowManagerTest()
-      : wm_(kDefaultLimit, absl::bind_front(&WindowManagerTest::OnCall, this)),
-        peer_(wm_) {}
-
-  void OnCall(int64_t s) { call_sequence_.push_back(s); }
-
-  const int64_t kDefaultLimit = 32 * 1024 * 3;
-  std::list<int64_t> call_sequence_;
-  WindowManager wm_;
-  WindowManagerPeer peer_;
-  ::http2::test::Http2Random random_;
-};
-
-// A few no-op calls.
-TEST_F(WindowManagerTest, NoOps) {
-  wm_.SetWindowSizeLimit(kDefaultLimit);
-  wm_.SetWindowSizeLimit(0);
-  wm_.SetWindowSizeLimit(kDefaultLimit);
-  wm_.MarkDataBuffered(0);
-  wm_.MarkDataFlushed(0);
-  EXPECT_TRUE(call_sequence_.empty());
-}
-
-// This test verifies that WindowManager does not notify its listener when data
-// is only buffered, and never flushed.
-TEST_F(WindowManagerTest, DataOnlyBuffered) {
-  int64_t total = 0;
-  while (total < kDefaultLimit) {
-    int64_t s = std::min<int64_t>(kDefaultLimit - total, random_.Uniform(1024));
-    total += s;
-    wm_.MarkDataBuffered(s);
-  }
-  EXPECT_THAT(call_sequence_, ::testing::IsEmpty());
-}
-
-// This test verifies that WindowManager does notify its listener when data is
-// buffered and subsequently flushed.
-TEST_F(WindowManagerTest, DataBufferedAndFlushed) {
-  int64_t total_buffered = 0;
-  int64_t total_flushed = 0;
-  while (call_sequence_.empty()) {
-    int64_t buffered = std::min<int64_t>(kDefaultLimit - total_buffered,
-                                         random_.Uniform(1024));
-    wm_.MarkDataBuffered(buffered);
-    total_buffered += buffered;
-    EXPECT_TRUE(call_sequence_.empty());
-    int64_t flushed = random_.Uniform(total_buffered - total_flushed);
-    wm_.MarkDataFlushed(flushed);
-    total_flushed += flushed;
-  }
-  // If WindowManager decided to send an update, at least one third of the
-  // window must have been consumed by buffered data.
-  EXPECT_GE(total_buffered, kDefaultLimit / 3);
-}
-
-// Window manager should avoid window underflow.
-TEST_F(WindowManagerTest, AvoidWindowUnderflow) {
-  EXPECT_EQ(wm_.CurrentWindowSize(), wm_.WindowSizeLimit());
-  // Don't buffer more than the total window!
-  wm_.MarkDataBuffered(wm_.WindowSizeLimit() + 1);
-  EXPECT_EQ(wm_.CurrentWindowSize(), 0u);
-}
-
-// Window manager should GFE_BUG and avoid buffered underflow.
-TEST_F(WindowManagerTest, AvoidBufferedUnderflow) {
-  EXPECT_EQ(peer_.buffered(), 0u);
-  // Don't flush more than has been buffered!
-  EXPECT_QUICHE_BUG(wm_.MarkDataFlushed(1), "buffered underflow");
-  EXPECT_EQ(peer_.buffered(), 0u);
-
-  wm_.MarkDataBuffered(42);
-  EXPECT_EQ(peer_.buffered(), 42u);
-  // Don't flush more than has been buffered!
-  EXPECT_QUICHE_BUG(wm_.MarkDataFlushed(43), "buffered underflow");
-  EXPECT_EQ(peer_.buffered(), 0u);
-}
-
-// This test verifies that WindowManager notifies its listener when window is
-// consumed (data is ignored or immediately dropped).
-TEST_F(WindowManagerTest, WindowConsumed) {
-  int64_t consumed = kDefaultLimit / 3 - 1;
-  wm_.MarkWindowConsumed(consumed);
-  EXPECT_TRUE(call_sequence_.empty());
-  const int64_t extra = 1;
-  wm_.MarkWindowConsumed(extra);
-  EXPECT_THAT(call_sequence_, testing::ElementsAre(consumed + extra));
-}
-
-// This test verifies that WindowManager notifies its listener when the window
-// size limit is increased.
-TEST_F(WindowManagerTest, ListenerCalledOnSizeUpdate) {
-  wm_.SetWindowSizeLimit(kDefaultLimit - 1024);
-  EXPECT_TRUE(call_sequence_.empty());
-  wm_.SetWindowSizeLimit(kDefaultLimit * 5);
-  // Because max(outstanding window, previous limit) is kDefaultLimit, it is
-  // only appropriate to increase the window by kDefaultLimit * 4.
-  EXPECT_THAT(call_sequence_, testing::ElementsAre(kDefaultLimit * 4));
-}
-
-// This test verifies that when data is buffered and then the limit is
-// decreased, WindowManager only notifies the listener once any outstanding
-// window has been consumed.
-TEST_F(WindowManagerTest, WindowUpdateAfterLimitDecreased) {
-  wm_.MarkDataBuffered(kDefaultLimit - 1024);
-  wm_.SetWindowSizeLimit(kDefaultLimit - 2048);
-
-  // Now there are 2048 bytes of window outstanding beyond the current limit,
-  // and we have 1024 bytes of data buffered beyond the current limit. This is
-  // intentional, to be sure that WindowManager works properly if the limit is
-  // decreased at runtime.
-
-  wm_.MarkDataFlushed(512);
-  EXPECT_TRUE(call_sequence_.empty());
-  wm_.MarkDataFlushed(512);
-  EXPECT_TRUE(call_sequence_.empty());
-  wm_.MarkDataFlushed(512);
-  EXPECT_TRUE(call_sequence_.empty());
-  wm_.MarkDataFlushed(1024);
-  EXPECT_THAT(call_sequence_, testing::ElementsAre(512));
-}
-
-// For normal behavior, we only call MaybeNotifyListener() when data is
-// flushed. But if window runs out entirely, we still need to call
-// MaybeNotifyListener() to avoid becoming artificially blocked when data isn't
-// being flushed.
-TEST_F(WindowManagerTest, ZeroWindowNotification) {
-  // Consume a byte of window, but not enough to trigger an update.
-  wm_.MarkWindowConsumed(1);
-
-  // Buffer the remaining window.
-  wm_.MarkDataBuffered(kDefaultLimit - 1);
-  // Listener is notified of the remaining byte of possible window.
-  EXPECT_THAT(call_sequence_, testing::ElementsAre(1));
-}
-
-TEST_F(WindowManagerTest, OnWindowSizeLimitChange) {
-  wm_.MarkDataBuffered(10000);
-  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 10000);
-  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);
-
-  wm_.OnWindowSizeLimitChange(kDefaultLimit + 1000);
-  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 9000);
-  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit + 1000);
-
-  wm_.OnWindowSizeLimitChange(kDefaultLimit - 1000);
-  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 11000);
-  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit - 1000);
-}
-
-TEST_F(WindowManagerTest, NegativeWindowSize) {
-  wm_.MarkDataBuffered(80000);
-  // 98304 window - 80000 buffered = 18304 available
-  EXPECT_EQ(wm_.CurrentWindowSize(), 18304);
-  wm_.OnWindowSizeLimitChange(65535);
-  // limit decreases by 98304 - 65535 = 32769, window becomes -14465
-  EXPECT_EQ(wm_.CurrentWindowSize(), -14465);
-  wm_.MarkDataFlushed(70000);
-  // Still 10000 bytes buffered, so window manager grants sufficient quota to
-  // reach a window of 65535 - 10000.
-  EXPECT_EQ(wm_.CurrentWindowSize(), 55535);
-  // Desired window minus existing window: 55535 - (-14465) = 70000
-  EXPECT_THAT(call_sequence_, testing::ElementsAre(70000));
-}
-
-TEST_F(WindowManagerTest, IncreaseWindow) {
-  wm_.MarkDataBuffered(1000);
-  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 1000);
-  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);
-
-  // Increasing the window beyond the limit is allowed.
-  wm_.IncreaseWindow(5000);
-  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit + 4000);
-  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);
-
-  // 80000 bytes are buffered, then flushed.
-  wm_.MarkWindowConsumed(80000);
-  // The window manager replenishes the consumed quota up to the limit.
-  EXPECT_THAT(call_sequence_, testing::ElementsAre(75000));
-  // The window is the limit, minus buffered data, as expected.
-  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 1000);
-}
-
-// This test verifies that when the constructor option is specified,
-// WindowManager does not update its internal accounting of the flow control
-// window when notifying the listener.
-TEST(WindowManagerNoUpdateTest, NoWindowUpdateOnListener) {
-  const int64_t kDefaultLimit = 65535;
-
-  std::list<int64_t> call_sequence1;
-  WindowManager wm1(
-      kDefaultLimit,
-      [&call_sequence1](int64_t delta) { call_sequence1.push_back(delta); },
-      /*should_notify_listener=*/{},
-      /*update_window_on_notify=*/true);  // default
-  std::list<int64_t> call_sequence2;
-  WindowManager wm2(
-      kDefaultLimit,
-      [&call_sequence2](int64_t delta) { call_sequence2.push_back(delta); },
-      /*should_notify_listener=*/{},
-      /*update_window_on_notify=*/false);
-
-  const int64_t consumed = kDefaultLimit / 3 - 1;
-
-  wm1.MarkWindowConsumed(consumed);
-  EXPECT_TRUE(call_sequence1.empty());
-  wm2.MarkWindowConsumed(consumed);
-  EXPECT_TRUE(call_sequence2.empty());
-
-  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit - consumed);
-  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit - consumed);
-
-  const int64_t extra = 1;
-  wm1.MarkWindowConsumed(extra);
-  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed + extra));
-  // Window size *is* updated after invoking the listener.
-  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit);
-  call_sequence1.clear();
-
-  wm2.MarkWindowConsumed(extra);
-  EXPECT_THAT(call_sequence2, testing::ElementsAre(consumed + extra));
-  // Window size is *not* updated after invoking the listener.
-  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit - (consumed + extra));
-  call_sequence2.clear();
-
-  // Manually increase the window by the listener notification amount.
-  wm2.IncreaseWindow(consumed + extra);
-  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit);
-
-  wm1.SetWindowSizeLimit(kDefaultLimit * 5);
-  EXPECT_THAT(call_sequence1, testing::ElementsAre(kDefaultLimit * 4));
-  // *Does* update the window size.
-  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit * 5);
-
-  wm2.SetWindowSizeLimit(kDefaultLimit * 5);
-  EXPECT_THAT(call_sequence2, testing::ElementsAre(kDefaultLimit * 4));
-  // Does *not* update the window size.
-  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit);
-}
-
-// This test verifies that when the constructor option is specified,
-// WindowManager uses the provided ShouldWindowUpdateFn to determine when to
-// notify the listener.
-TEST(WindowManagerShouldUpdateTest, CustomShouldWindowUpdateFn) {
-  const int64_t kDefaultLimit = 65535;
-
-  // This window manager should always notify.
-  std::list<int64_t> call_sequence1;
-  WindowManager wm1(
-      kDefaultLimit,
-      [&call_sequence1](int64_t delta) { call_sequence1.push_back(delta); },
-      [](int64_t /*limit*/, int64_t /*window*/, int64_t /*delta*/) {
-        return true;
-      });
-  // This window manager should never notify.
-  std::list<int64_t> call_sequence2;
-  WindowManager wm2(
-      kDefaultLimit,
-      [&call_sequence2](int64_t delta) { call_sequence2.push_back(delta); },
-      [](int64_t /*limit*/, int64_t /*window*/, int64_t /*delta*/) {
-        return false;
-      });
-  // This window manager should notify as long as no data is buffered.
-  std::list<int64_t> call_sequence3;
-  WindowManager wm3(
-      kDefaultLimit,
-      [&call_sequence3](int64_t delta) { call_sequence3.push_back(delta); },
-      [](int64_t limit, int64_t window, int64_t delta) {
-        return delta == limit - window;
-      });
-
-  const int64_t consumed = kDefaultLimit / 4;
-
-  wm1.MarkWindowConsumed(consumed);
-  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed));
-  wm2.MarkWindowConsumed(consumed);
-  EXPECT_TRUE(call_sequence2.empty());
-  wm3.MarkWindowConsumed(consumed);
-  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));
-
-  const int64_t buffered = 42;
-
-  wm1.MarkDataBuffered(buffered);
-  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed));
-  wm2.MarkDataBuffered(buffered);
-  EXPECT_TRUE(call_sequence2.empty());
-  wm3.MarkDataBuffered(buffered);
-  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));
-
-  wm1.MarkDataFlushed(buffered / 3);
-  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed, buffered / 3));
-  wm2.MarkDataFlushed(buffered / 3);
-  EXPECT_TRUE(call_sequence2.empty());
-  wm3.MarkDataFlushed(buffered / 3);
-  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));
-
-  wm1.MarkDataFlushed(2 * buffered / 3);
-  EXPECT_THAT(call_sequence1,
-              testing::ElementsAre(consumed, buffered / 3, 2 * buffered / 3));
-  wm2.MarkDataFlushed(2 * buffered / 3);
-  EXPECT_TRUE(call_sequence2.empty());
-  wm3.MarkDataFlushed(2 * buffered / 3);
-  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed, buffered));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace adapter
-}  // namespace http2
diff --git a/http2/core/http2_trace_logging.cc b/http2/core/http2_trace_logging.cc
deleted file mode 100644
index f8f54b6..0000000
--- a/http2/core/http2_trace_logging.cc
+++ /dev/null
@@ -1,459 +0,0 @@
-#include "http2/core/http2_trace_logging.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/spdy_protocol.h"
-
-// Convenience macros for printing function arguments in log lines in the
-// format arg_name=value.
-#define FORMAT_ARG(arg) " " #arg "=" << arg
-#define FORMAT_INT_ARG(arg) " " #arg "=" << static_cast<int>(arg)
-
-// Convenience macros for printing Spdy*IR attributes in log lines in the
-// format attrib_name=value.
-#define FORMAT_ATTR(ir, attrib) " " #attrib "=" << ir.attrib()
-#define FORMAT_INT_ATTR(ir, attrib) \
-  " " #attrib "=" << static_cast<int>(ir.attrib())
-
-namespace {
-
-// Logs a container, using a user-provided object to log each individual item.
-template <typename T, typename ItemLogger>
-struct ContainerLogger {
-  explicit ContainerLogger(const T& c, ItemLogger l)
-      : container(c), item_logger(l) {}
-
-  friend std::ostream& operator<<(std::ostream& out,
-                                  const ContainerLogger& logger) {
-    out << "[";
-    auto begin = logger.container.begin();
-    for (auto it = begin; it != logger.container.end(); ++it) {
-      if (it != begin) {
-        out << ", ";
-      }
-      logger.item_logger.Log(out, *it);
-    }
-    out << "]";
-    return out;
-  }
-  const T& container;
-  ItemLogger item_logger;
-};
-
-// Returns a ContainerLogger that will log |container| using |item_logger|.
-template <typename T, typename ItemLogger>
-auto LogContainer(const T& container, ItemLogger item_logger)
-    -> decltype(ContainerLogger<T, ItemLogger>(container, item_logger)) {
-  return ContainerLogger<T, ItemLogger>(container, item_logger);
-}
-
-}  // anonymous namespace
-
-#define FORMAT_HEADER_BLOCK(ir) \
-  " header_block=" << LogContainer(ir.header_block(), LogHeaderBlockEntry())
-
-namespace http2 {
-
-using spdy::SettingsMap;
-using spdy::SpdyAltSvcIR;
-using spdy::SpdyContinuationIR;
-using spdy::SpdyDataIR;
-using spdy::SpdyGoAwayIR;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyHeadersIR;
-using spdy::SpdyPingIR;
-using spdy::SpdyPriorityIR;
-using spdy::SpdyPushPromiseIR;
-using spdy::SpdyRstStreamIR;
-using spdy::SpdySettingsIR;
-using spdy::SpdyStreamId;
-using spdy::SpdyUnknownIR;
-using spdy::SpdyWindowUpdateIR;
-
-namespace {
-
-// Defines how elements of SpdyHeaderBlocks are logged.
-struct LogHeaderBlockEntry {
-  void Log(std::ostream& out,
-           const SpdyHeaderBlock::value_type& entry) const {  // NOLINT
-    out << "\"" << entry.first << "\": \"" << entry.second << "\"";
-  }
-};
-
-// Defines how elements of SettingsMap are logged.
-struct LogSettingsEntry {
-  void Log(std::ostream& out,
-           const SettingsMap::value_type& entry) const {  // NOLINT
-    out << spdy::SettingsIdToString(entry.first) << ": " << entry.second;
-  }
-};
-
-// Defines how elements of AlternativeServiceVector are logged.
-struct LogAlternativeService {
-  void Log(std::ostream& out,
-           const spdy::SpdyAltSvcWireFormat::AlternativeService& altsvc)
-      const {  // NOLINT
-    out << "{"
-        << "protocol_id=" << altsvc.protocol_id << " host=" << altsvc.host
-        << " port=" << altsvc.port
-        << " max_age_seconds=" << altsvc.max_age_seconds << " version=";
-    for (auto v : altsvc.version) {
-      out << v << ",";
-    }
-    out << "}";
-  }
-};
-
-}  // anonymous namespace
-
-Http2TraceLogger::Http2TraceLogger(SpdyFramerVisitorInterface* parent,
-                                   absl::string_view perspective,
-                                   std::function<bool()> is_enabled,
-                                   const void* connection_id)
-    : wrapped_(parent),
-      perspective_(perspective),
-      is_enabled_(std::move(is_enabled)),
-      connection_id_(connection_id) {}
-
-Http2TraceLogger::~Http2TraceLogger() {
-  if (recording_headers_handler_ != nullptr &&
-      !recording_headers_handler_->decoded_block().empty()) {
-    HTTP2_TRACE_LOG(perspective_, is_enabled_)
-        << "connection_id=" << connection_id_
-        << " Received headers that were never logged! keys/values:"
-        << recording_headers_handler_->decoded_block().DebugString();
-  }
-}
-
-void Http2TraceLogger::OnError(Http2DecoderAdapter::SpdyFramerError error,
-                               std::string detailed_error) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnError:" << FORMAT_ARG(connection_id_)
-      << ", error=" << Http2DecoderAdapter::SpdyFramerErrorToString(error);
-  wrapped_->OnError(error, detailed_error);
-}
-
-void Http2TraceLogger::OnCommonHeader(SpdyStreamId stream_id, size_t length,
-                                      uint8_t type, uint8_t flags) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnCommonHeader:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_INT_ARG(type)
-      << FORMAT_INT_ARG(flags);
-  wrapped_->OnCommonHeader(stream_id, length, type, flags);
-}
-
-void Http2TraceLogger::OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
-                                        bool fin) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnDataFrameHeader:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_ARG(fin);
-  wrapped_->OnDataFrameHeader(stream_id, length, fin);
-}
-
-void Http2TraceLogger::OnStreamFrameData(SpdyStreamId stream_id,
-                                        const char* data, size_t len) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnStreamFrameData:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
-  wrapped_->OnStreamFrameData(stream_id, data, len);
-}
-
-void Http2TraceLogger::OnStreamEnd(SpdyStreamId stream_id) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnStreamEnd:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id);
-  wrapped_->OnStreamEnd(stream_id);
-}
-
-void Http2TraceLogger::OnStreamPadLength(SpdyStreamId stream_id, size_t value) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnStreamPadLength:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(value);
-  wrapped_->OnStreamPadLength(stream_id, value);
-}
-
-void Http2TraceLogger::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnStreamPadding:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
-  wrapped_->OnStreamPadding(stream_id, len);
-}
-
-spdy::SpdyHeadersHandlerInterface* Http2TraceLogger::OnHeaderFrameStart(
-    SpdyStreamId stream_id) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnHeaderFrameStart:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id);
-  spdy::SpdyHeadersHandlerInterface* result =
-      wrapped_->OnHeaderFrameStart(stream_id);
-  if (is_enabled_()) {
-    recording_headers_handler_ =
-        absl::make_unique<spdy::RecordingHeadersHandler>(result);
-    result = recording_headers_handler_.get();
-  } else {
-    recording_headers_handler_ = nullptr;
-  }
-  return result;
-}
-
-void Http2TraceLogger::OnHeaderFrameEnd(SpdyStreamId stream_id) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnHeaderFrameEnd:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id);
-  LogReceivedHeaders();
-  wrapped_->OnHeaderFrameEnd(stream_id);
-  recording_headers_handler_ = nullptr;
-}
-
-void Http2TraceLogger::OnRstStream(SpdyStreamId stream_id,
-                                  SpdyErrorCode error_code) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnRstStream:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
-      << " error_code=" << spdy::ErrorCodeToString(error_code);
-  wrapped_->OnRstStream(stream_id, error_code);
-}
-
-void Http2TraceLogger::OnSettings() { wrapped_->OnSettings(); }
-
-void Http2TraceLogger::OnSetting(SpdySettingsId id, uint32_t value) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnSetting:" << FORMAT_ARG(connection_id_)
-      << " id=" << spdy::SettingsIdToString(id) << FORMAT_ARG(value);
-  wrapped_->OnSetting(id, value);
-}
-
-void Http2TraceLogger::OnSettingsEnd() {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnSettingsEnd:" << FORMAT_ARG(connection_id_);
-  wrapped_->OnSettingsEnd();
-}
-
-void Http2TraceLogger::OnSettingsAck() {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnSettingsAck:" << FORMAT_ARG(connection_id_);
-  wrapped_->OnSettingsAck();
-}
-
-void Http2TraceLogger::OnPing(SpdyPingId unique_id, bool is_ack) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnPing:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(unique_id)
-      << FORMAT_ARG(is_ack);
-  wrapped_->OnPing(unique_id, is_ack);
-}
-
-void Http2TraceLogger::OnGoAway(SpdyStreamId last_accepted_stream_id,
-                               SpdyErrorCode error_code) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnGoAway:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(last_accepted_stream_id)
-      << " error_code=" << spdy::ErrorCodeToString(error_code);
-  wrapped_->OnGoAway(last_accepted_stream_id, error_code);
-}
-
-bool Http2TraceLogger::OnGoAwayFrameData(const char* goaway_data, size_t len) {
-  return wrapped_->OnGoAwayFrameData(goaway_data, len);
-}
-
-void Http2TraceLogger::OnHeaders(SpdyStreamId stream_id, bool has_priority,
-                                int weight, SpdyStreamId parent_stream_id,
-                                bool exclusive, bool fin, bool end) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnHeaders:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
-      << FORMAT_ARG(has_priority) << FORMAT_INT_ARG(weight)
-      << FORMAT_ARG(parent_stream_id) << FORMAT_ARG(exclusive)
-      << FORMAT_ARG(fin) << FORMAT_ARG(end);
-  wrapped_->OnHeaders(stream_id, has_priority, weight, parent_stream_id,
-                      exclusive, fin, end);
-}
-
-void Http2TraceLogger::OnWindowUpdate(SpdyStreamId stream_id,
-                                     int delta_window_size) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnWindowUpdate:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(delta_window_size);
-  wrapped_->OnWindowUpdate(stream_id, delta_window_size);
-}
-
-void Http2TraceLogger::OnPushPromise(SpdyStreamId original_stream_id,
-                                    SpdyStreamId promised_stream_id, bool end) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnPushPromise:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(original_stream_id) << FORMAT_ARG(promised_stream_id)
-      << FORMAT_ARG(end);
-  wrapped_->OnPushPromise(original_stream_id, promised_stream_id, end);
-}
-
-void Http2TraceLogger::OnContinuation(SpdyStreamId stream_id, bool end) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnContinuation:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_ARG(end);
-  wrapped_->OnContinuation(stream_id, end);
-}
-
-void Http2TraceLogger::OnAltSvc(
-    SpdyStreamId stream_id, absl::string_view origin,
-    const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnAltSvc:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
-      << FORMAT_ARG(origin) << " altsvc_vector="
-      << LogContainer(altsvc_vector, LogAlternativeService());
-  wrapped_->OnAltSvc(stream_id, origin, altsvc_vector);
-}
-
-void Http2TraceLogger::OnPriority(SpdyStreamId stream_id,
-                                 SpdyStreamId parent_stream_id, int weight,
-                                 bool exclusive) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnPriority:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
-      << FORMAT_ARG(parent_stream_id) << FORMAT_INT_ARG(weight)
-      << FORMAT_ARG(exclusive);
-  wrapped_->OnPriority(stream_id, parent_stream_id, weight, exclusive);
-}
-
-void Http2TraceLogger::OnPriorityUpdate(
-    SpdyStreamId prioritized_stream_id,
-    absl::string_view priority_field_value) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnPriorityUpdate:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(prioritized_stream_id) << FORMAT_ARG(priority_field_value);
-  wrapped_->OnPriorityUpdate(prioritized_stream_id, priority_field_value);
-}
-
-bool Http2TraceLogger::OnUnknownFrame(SpdyStreamId stream_id,
-                                     uint8_t frame_type) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "OnUnknownFrame:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ARG(stream_id) << FORMAT_INT_ARG(frame_type);
-  return wrapped_->OnUnknownFrame(stream_id, frame_type);
-}
-
-void Http2TraceLogger::LogReceivedHeaders() const {
-  if (recording_headers_handler_ == nullptr) {
-    // Trace logging was not enabled when the start of the header block was
-    // received.
-    return;
-  }
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Received headers;" << FORMAT_ARG(connection_id_) << " keys/values:"
-      << recording_headers_handler_->decoded_block().DebugString()
-      << " compressed_bytes="
-      << recording_headers_handler_->compressed_header_bytes()
-      << " uncompressed_bytes="
-      << recording_headers_handler_->uncompressed_header_bytes();
-}
-
-void Http2FrameLogger::VisitRstStream(const SpdyRstStreamIR& rst_stream) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyRstStreamIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(rst_stream, stream_id)
-      << " error_code=" << spdy::ErrorCodeToString(rst_stream.error_code());
-}
-
-void Http2FrameLogger::VisitSettings(const SpdySettingsIR& settings) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdySettingsIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(settings, is_ack)
-      << " values=" << LogContainer(settings.values(), LogSettingsEntry());
-}
-
-void Http2FrameLogger::VisitPing(const SpdyPingIR& ping) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyPingIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(ping, id) << FORMAT_ATTR(ping, is_ack);
-}
-
-void Http2FrameLogger::VisitGoAway(const SpdyGoAwayIR& goaway) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyGoAwayIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(goaway, last_good_stream_id)
-      << " error_code=" << spdy::ErrorCodeToString(goaway.error_code())
-      << FORMAT_ATTR(goaway, description);
-}
-
-void Http2FrameLogger::VisitHeaders(const SpdyHeadersIR& headers) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyHeadersIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(headers, stream_id) << FORMAT_ATTR(headers, fin)
-      << FORMAT_ATTR(headers, has_priority) << FORMAT_INT_ATTR(headers, weight)
-      << FORMAT_ATTR(headers, parent_stream_id)
-      << FORMAT_ATTR(headers, exclusive) << FORMAT_ATTR(headers, padded)
-      << FORMAT_ATTR(headers, padding_payload_len)
-      << FORMAT_HEADER_BLOCK(headers);
-}
-
-void Http2FrameLogger::VisitWindowUpdate(
-    const SpdyWindowUpdateIR& window_update) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyWindowUpdateIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(window_update, stream_id)
-      << FORMAT_ATTR(window_update, delta);
-}
-
-void Http2FrameLogger::VisitPushPromise(const SpdyPushPromiseIR& push_promise) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyPushPromiseIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(push_promise, stream_id) << FORMAT_ATTR(push_promise, fin)
-      << FORMAT_ATTR(push_promise, promised_stream_id)
-      << FORMAT_ATTR(push_promise, padded)
-      << FORMAT_ATTR(push_promise, padding_payload_len)
-      << FORMAT_HEADER_BLOCK(push_promise);
-}
-
-void Http2FrameLogger::VisitContinuation(
-    const SpdyContinuationIR& continuation) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyContinuationIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(continuation, stream_id)
-      << FORMAT_ATTR(continuation, end_headers);
-}
-
-void Http2FrameLogger::VisitAltSvc(const SpdyAltSvcIR& altsvc) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyAltSvcIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(altsvc, stream_id) << FORMAT_ATTR(altsvc, origin)
-      << " altsvc_vector="
-      << LogContainer(altsvc.altsvc_vector(), LogAlternativeService());
-}
-
-void Http2FrameLogger::VisitPriority(const SpdyPriorityIR& priority) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyPriorityIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(priority, stream_id)
-      << FORMAT_ATTR(priority, parent_stream_id)
-      << FORMAT_INT_ATTR(priority, weight) << FORMAT_ATTR(priority, exclusive);
-}
-
-void Http2FrameLogger::VisitData(const SpdyDataIR& data) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyDataIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(data, stream_id) << FORMAT_ATTR(data, fin)
-      << " data_len=" << data.data_len() << FORMAT_ATTR(data, padded)
-      << FORMAT_ATTR(data, padding_payload_len);
-}
-
-void Http2FrameLogger::VisitPriorityUpdate(
-    const spdy::SpdyPriorityUpdateIR& priority_update) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyPriorityUpdateIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(priority_update, stream_id)
-      << FORMAT_ATTR(priority_update, prioritized_stream_id)
-      << FORMAT_ATTR(priority_update, priority_field_value);
-}
-
-void Http2FrameLogger::VisitAcceptCh(
-    const spdy::SpdyAcceptChIR& /*accept_ch*/) {
-  QUICHE_BUG(bug_2794_2)
-      << "Sending ACCEPT_CH frames is currently unimplemented.";
-}
-
-void Http2FrameLogger::VisitUnknown(const SpdyUnknownIR& ir) {
-  HTTP2_TRACE_LOG(perspective_, is_enabled_)
-      << "Wrote SpdyUnknownIR:" << FORMAT_ARG(connection_id_)
-      << FORMAT_ATTR(ir, stream_id) << FORMAT_INT_ATTR(ir, type)
-      << FORMAT_INT_ATTR(ir, flags) << FORMAT_ATTR(ir, length);
-}
-
-}  // namespace http2
diff --git a/http2/core/http2_trace_logging.h b/http2/core/http2_trace_logging.h
deleted file mode 100644
index e1185bf..0000000
--- a/http2/core/http2_trace_logging.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Classes and utilities for supporting HTTP/2 trace logging, which logs
-// information about all control and data frames sent and received over
-// HTTP/2 connections.
-
-#ifndef QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
-#define QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/recording_headers_handler.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-#include "spdy/core/spdy_protocol.h"
-
-// Logging macro to use for all HTTP/2 trace logging. Iff trace logging is
-// enabled, logs at level INFO with a common prefix prepended (to facilitate
-// post-hoc filtering of trace logging output).
-#define HTTP2_TRACE_LOG(perspective, is_enabled) \
-  QUICHE_LOG_IF(INFO, is_enabled()) << "[HTTP2_TRACE " << perspective << "] "
-
-namespace http2 {
-
-// Intercepts deframing events to provide detailed logs. Intended to be used for
-// manual debugging.
-//
-// Note any new methods in SpdyFramerVisitorInterface MUST be overridden here to
-// properly forward the event. This could be ensured by making every event in
-// SpdyFramerVisitorInterface a pure virtual.
-class QUICHE_EXPORT_PRIVATE Http2TraceLogger
-    : public spdy::SpdyFramerVisitorInterface {
- public:
-  typedef spdy::SpdyAltSvcWireFormat SpdyAltSvcWireFormat;
-  typedef spdy::SpdyErrorCode SpdyErrorCode;
-  typedef spdy::SpdyFramerVisitorInterface SpdyFramerVisitorInterface;
-  typedef spdy::SpdyPingId SpdyPingId;
-  typedef spdy::SpdyPriority SpdyPriority;
-  typedef spdy::SpdySettingsId SpdySettingsId;
-  typedef spdy::SpdyStreamId SpdyStreamId;
-
-  Http2TraceLogger(SpdyFramerVisitorInterface* parent,
-                   absl::string_view perspective,
-                   std::function<bool()> is_enabled, const void* connection_id);
-  ~Http2TraceLogger() override;
-
-  Http2TraceLogger(const Http2TraceLogger&) = delete;
-  Http2TraceLogger& operator=(const Http2TraceLogger&) = delete;
-
-  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error) override;
-  void OnCommonHeader(SpdyStreamId stream_id, size_t length, uint8_t type,
-                      uint8_t flags) override;
-  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      SpdyStreamId stream_id) override;
-  void OnHeaderFrameEnd(SpdyStreamId stream_id) override;
-  void OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
-                         bool fin) override;
-  void OnStreamFrameData(SpdyStreamId stream_id, const char* data,
-                         size_t len) override;
-  void OnStreamEnd(SpdyStreamId stream_id) override;
-  void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
-  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
-  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
-  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
-  void OnPing(SpdyPingId unique_id, bool is_ack) override;
-  void OnSettings() override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck() override;
-  void OnGoAway(SpdyStreamId last_accepted_stream_id,
-                SpdyErrorCode error_code) override;
-  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
-  void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
-                 SpdyStreamId parent_stream_id, bool exclusive, bool fin,
-                 bool end) override;
-  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
-  void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
-                     bool end) override;
-  void OnContinuation(SpdyStreamId stream_id, bool end) override;
-  void OnAltSvc(SpdyStreamId stream_id, absl::string_view origin,
-                const SpdyAltSvcWireFormat::AlternativeServiceVector&
-                    altsvc_vector) override;
-  void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id,
-                  int weight, bool exclusive) override;
-  void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
-                        absl::string_view priority_field_value) override;
-  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
-
- private:
-  void LogReceivedHeaders() const;
-
-  std::unique_ptr<spdy::RecordingHeadersHandler> recording_headers_handler_;
-
-  SpdyFramerVisitorInterface* wrapped_;
-  const absl::string_view perspective_;
-  const std::function<bool()> is_enabled_;
-  const void* connection_id_;
-};
-
-// Visitor to log control frames that have been written.
-class QUICHE_EXPORT_PRIVATE Http2FrameLogger : public spdy::SpdyFrameVisitor {
- public:
-  // This class will preface all of its log messages with the value of
-  // |connection_id| in hexadecimal.
-  Http2FrameLogger(absl::string_view perspective,
-                   std::function<bool()> is_enabled, const void* connection_id)
-      : perspective_(perspective),
-        is_enabled_(std::move(is_enabled)),
-        connection_id_(connection_id) {}
-
-  Http2FrameLogger(const Http2FrameLogger&) = delete;
-  Http2FrameLogger& operator=(const Http2FrameLogger&) = delete;
-
-  void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override;
-  void VisitSettings(const spdy::SpdySettingsIR& settings) override;
-  void VisitPing(const spdy::SpdyPingIR& ping) override;
-  void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override;
-  void VisitHeaders(const spdy::SpdyHeadersIR& headers) override;
-  void VisitWindowUpdate(
-      const spdy::SpdyWindowUpdateIR& window_update) override;
-  void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override;
-  void VisitContinuation(const spdy::SpdyContinuationIR& continuation) override;
-  void VisitAltSvc(const spdy::SpdyAltSvcIR& altsvc) override;
-  void VisitPriority(const spdy::SpdyPriorityIR& priority) override;
-  void VisitData(const spdy::SpdyDataIR& data) override;
-  void VisitPriorityUpdate(
-      const spdy::SpdyPriorityUpdateIR& priority_update) override;
-  void VisitAcceptCh(const spdy::SpdyAcceptChIR& accept_ch) override;
-  void VisitUnknown(const spdy::SpdyUnknownIR& ir) override;
-
- private:
-  const absl::string_view perspective_;
-  const std::function<bool()> is_enabled_;
-  const void* connection_id_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
diff --git a/http2/core/priority_write_scheduler.h b/http2/core/priority_write_scheduler.h
deleted file mode 100644
index cf1c77a..0000000
--- a/http2/core/priority_write_scheduler.h
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_CORE_PRIORITY_WRITE_SCHEDULER_H_
-#define QUICHE_HTTP2_CORE_PRIORITY_WRITE_SCHEDULER_H_
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "http2/core/write_scheduler.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-
-namespace test {
-template <typename StreamIdType>
-class PriorityWriteSchedulerPeer;
-}
-
-// WriteScheduler implementation that manages the order in which streams are
-// written using the SPDY priority scheme described at:
-// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
-//
-// Internally, PriorityWriteScheduler consists of 8 PriorityInfo objects, one
-// for each priority value.  Each PriorityInfo contains a list of streams of
-// that priority that are ready to write, as well as a timestamp of the last
-// I/O event that occurred for a stream of that priority.
-//
-template <typename StreamIdType>
-class QUICHE_EXPORT_PRIVATE PriorityWriteScheduler
-    : public WriteScheduler<StreamIdType> {
- public:
-  using typename WriteScheduler<StreamIdType>::StreamPrecedenceType;
-
-  // Creates scheduler with no streams.
-  PriorityWriteScheduler() : PriorityWriteScheduler(spdy::kHttp2RootStreamId) {}
-  explicit PriorityWriteScheduler(StreamIdType root_stream_id)
-      : root_stream_id_(root_stream_id) {}
-
-  void RegisterStream(StreamIdType stream_id,
-                      const StreamPrecedenceType& precedence) override {
-    // TODO(mpw): verify |precedence.is_spdy3_priority() == true| once
-    //   Http2PriorityWriteScheduler enabled for HTTP/2.
-
-    // parent_id not used here, but may as well validate it.  However,
-    // parent_id may legitimately not be registered yet--see b/15676312.
-    StreamIdType parent_id = precedence.parent_id();
-    QUICHE_DVLOG_IF(
-        1, parent_id != root_stream_id_ && !StreamRegistered(parent_id))
-        << "Parent stream " << parent_id << " not registered";
-
-    if (stream_id == root_stream_id_) {
-      QUICHE_BUG(spdy_bug_19_1)
-          << "Stream " << root_stream_id_ << " already registered";
-      return;
-    }
-    StreamInfo stream_info = {precedence.spdy3_priority(), stream_id, false};
-    bool inserted =
-        stream_infos_.insert(std::make_pair(stream_id, stream_info)).second;
-    QUICHE_BUG_IF(spdy_bug_19_2, !inserted)
-        << "Stream " << stream_id << " already registered";
-  }
-
-  void UnregisterStream(StreamIdType stream_id) override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_BUG(spdy_bug_19_3) << "Stream " << stream_id << " not registered";
-      return;
-    }
-    StreamInfo& stream_info = it->second;
-    if (stream_info.ready) {
-      bool erased =
-          Erase(&priority_infos_[stream_info.priority].ready_list, stream_info);
-      QUICHE_DCHECK(erased);
-    }
-    stream_infos_.erase(it);
-  }
-
-  bool StreamRegistered(StreamIdType stream_id) const override {
-    return stream_infos_.find(stream_id) != stream_infos_.end();
-  }
-
-  StreamPrecedenceType GetStreamPrecedence(
-      StreamIdType stream_id) const override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_DVLOG(1) << "Stream " << stream_id << " not registered";
-      return StreamPrecedenceType(spdy::kV3LowestPriority);
-    }
-    return StreamPrecedenceType(it->second.priority);
-  }
-
-  void UpdateStreamPrecedence(StreamIdType stream_id,
-                              const StreamPrecedenceType& precedence) override {
-    // TODO(mpw): verify |precedence.is_spdy3_priority() == true| once
-    //   Http2PriorityWriteScheduler enabled for HTTP/2.
-
-    // parent_id not used here, but may as well validate it.  However,
-    // parent_id may legitimately not be registered yet--see b/15676312.
-    StreamIdType parent_id = precedence.parent_id();
-    QUICHE_DVLOG_IF(
-        1, parent_id != root_stream_id_ && !StreamRegistered(parent_id))
-        << "Parent stream " << parent_id << " not registered";
-
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      // TODO(mpw): add to stream_infos_ on demand--see b/15676312.
-      QUICHE_DVLOG(1) << "Stream " << stream_id << " not registered";
-      return;
-    }
-    StreamInfo& stream_info = it->second;
-    spdy::SpdyPriority new_priority = precedence.spdy3_priority();
-    if (stream_info.priority == new_priority) {
-      return;
-    }
-    if (stream_info.ready) {
-      bool erased =
-          Erase(&priority_infos_[stream_info.priority].ready_list, stream_info);
-      QUICHE_DCHECK(erased);
-      priority_infos_[new_priority].ready_list.push_back(&stream_info);
-      ++num_ready_streams_;
-    }
-    stream_info.priority = new_priority;
-  }
-
-  std::vector<StreamIdType> GetStreamChildren(
-      StreamIdType /*stream_id*/) const override {
-    return std::vector<StreamIdType>();
-  }
-
-  void RecordStreamEventTime(StreamIdType stream_id,
-                             int64_t now_in_usec) override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_BUG(spdy_bug_19_4) << "Stream " << stream_id << " not registered";
-      return;
-    }
-    PriorityInfo& priority_info = priority_infos_[it->second.priority];
-    priority_info.last_event_time_usec =
-        std::max(priority_info.last_event_time_usec, now_in_usec);
-  }
-
-  int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_BUG(spdy_bug_19_5) << "Stream " << stream_id << " not registered";
-      return 0;
-    }
-    int64_t last_event_time_usec = 0;
-    const StreamInfo& stream_info = it->second;
-    for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
-         p < stream_info.priority; ++p) {
-      last_event_time_usec = std::max(last_event_time_usec,
-                                      priority_infos_[p].last_event_time_usec);
-    }
-    return last_event_time_usec;
-  }
-
-  StreamIdType PopNextReadyStream() override {
-    return std::get<0>(PopNextReadyStreamAndPrecedence());
-  }
-
-  // Returns the next ready stream and its precedence.
-  std::tuple<StreamIdType, StreamPrecedenceType>
-  PopNextReadyStreamAndPrecedence() override {
-    for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
-         p <= spdy::kV3LowestPriority; ++p) {
-      ReadyList& ready_list = priority_infos_[p].ready_list;
-      if (!ready_list.empty()) {
-        StreamInfo* info = ready_list.front();
-        ready_list.pop_front();
-        --num_ready_streams_;
-
-        QUICHE_DCHECK(stream_infos_.find(info->stream_id) !=
-                      stream_infos_.end());
-        info->ready = false;
-        return std::make_tuple(info->stream_id,
-                               StreamPrecedenceType(info->priority));
-      }
-    }
-    QUICHE_BUG(spdy_bug_19_6) << "No ready streams available";
-    return std::make_tuple(0, StreamPrecedenceType(spdy::kV3LowestPriority));
-  }
-
-  bool ShouldYield(StreamIdType stream_id) const override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_BUG(spdy_bug_19_7) << "Stream " << stream_id << " not registered";
-      return false;
-    }
-
-    // If there's a higher priority stream, this stream should yield.
-    const StreamInfo& stream_info = it->second;
-    for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
-         p < stream_info.priority; ++p) {
-      if (!priority_infos_[p].ready_list.empty()) {
-        return true;
-      }
-    }
-
-    // If this priority level is empty, or this stream is the next up, there's
-    // no need to yield.
-    const auto& ready_list = priority_infos_[it->second.priority].ready_list;
-    if (ready_list.empty() || ready_list.front()->stream_id == stream_id) {
-      return false;
-    }
-
-    // There are other streams in this priority level which take precedence.
-    // Yield.
-    return true;
-  }
-
-  void MarkStreamReady(StreamIdType stream_id, bool add_to_front) override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_BUG(spdy_bug_19_8) << "Stream " << stream_id << " not registered";
-      return;
-    }
-    StreamInfo& stream_info = it->second;
-    if (stream_info.ready) {
-      return;
-    }
-    ReadyList& ready_list = priority_infos_[stream_info.priority].ready_list;
-    if (add_to_front) {
-      ready_list.push_front(&stream_info);
-    } else {
-      ready_list.push_back(&stream_info);
-    }
-    ++num_ready_streams_;
-    stream_info.ready = true;
-  }
-
-  void MarkStreamNotReady(StreamIdType stream_id) override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_BUG(spdy_bug_19_9) << "Stream " << stream_id << " not registered";
-      return;
-    }
-    StreamInfo& stream_info = it->second;
-    if (!stream_info.ready) {
-      return;
-    }
-    bool erased =
-        Erase(&priority_infos_[stream_info.priority].ready_list, stream_info);
-    QUICHE_DCHECK(erased);
-    stream_info.ready = false;
-  }
-
-  // Returns true iff the number of ready streams is non-zero.
-  bool HasReadyStreams() const override { return num_ready_streams_ > 0; }
-
-  // Returns the number of ready streams.
-  size_t NumReadyStreams() const override { return num_ready_streams_; }
-
-  size_t NumRegisteredStreams() const override { return stream_infos_.size(); }
-
-  std::string DebugString() const override {
-    return absl::StrCat(
-        "PriorityWriteScheduler {num_streams=", stream_infos_.size(),
-        " num_ready_streams=", NumReadyStreams(), "}");
-  }
-
-  // Returns true if a stream is ready.
-  bool IsStreamReady(StreamIdType stream_id) const override {
-    auto it = stream_infos_.find(stream_id);
-    if (it == stream_infos_.end()) {
-      QUICHE_DLOG(INFO) << "Stream " << stream_id << " not registered";
-      return false;
-    }
-    return it->second.ready;
-  }
-
- private:
-  friend class test::PriorityWriteSchedulerPeer<StreamIdType>;
-
-  // State kept for all registered streams. All ready streams have ready = true
-  // and should be present in priority_infos_[priority].ready_list.
-  struct QUICHE_EXPORT_PRIVATE StreamInfo {
-    spdy::SpdyPriority priority;
-    StreamIdType stream_id;
-    bool ready;
-  };
-
-  // O(1) size lookup, O(1) insert at front or back (amortized).
-  using ReadyList = quiche::QuicheCircularDeque<StreamInfo*>;
-
-  // State kept for each priority level.
-  struct QUICHE_EXPORT_PRIVATE PriorityInfo {
-    // IDs of streams that are ready to write.
-    ReadyList ready_list;
-    // Time of latest write event for stream of this priority, in microseconds.
-    int64_t last_event_time_usec = 0;
-  };
-
-  typedef std::unordered_map<StreamIdType, StreamInfo> StreamInfoMap;
-
-  // Erases `info` from `ready_list`, returning true if found (and erased), or
-  // false otherwise. Decrements `num_ready_streams_` if an entry is erased.
-  bool Erase(ReadyList* ready_list, const StreamInfo& info) {
-    auto it = std::remove(ready_list->begin(), ready_list->end(), &info);
-    if (it == ready_list->end()) {
-      // `info` was not found.
-      return false;
-    }
-    ready_list->pop_back();
-    --num_ready_streams_;
-    return true;
-  }
-
-  // Number of ready streams.
-  size_t num_ready_streams_ = 0;
-  // Per-priority state, including ready lists.
-  PriorityInfo priority_infos_[spdy::kV3LowestPriority + 1];
-  // StreamInfos for all registered streams.
-  StreamInfoMap stream_infos_;
-  StreamIdType root_stream_id_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_CORE_PRIORITY_WRITE_SCHEDULER_H_
diff --git a/http2/core/priority_write_scheduler_test.cc b/http2/core/priority_write_scheduler_test.cc
deleted file mode 100644
index e4e6997..0000000
--- a/http2/core/priority_write_scheduler_test.cc
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/core/priority_write_scheduler.h"
-
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/spdy_test_utils.h"
-
-namespace http2 {
-namespace test {
-
-using ::spdy::kHttp2RootStreamId;
-using ::spdy::kV3LowestPriority;
-using ::spdy::SpdyPriority;
-using ::spdy::SpdyStreamId;
-using ::spdy::SpdyStreamPrecedence;
-
-template <typename StreamIdType>
-class PriorityWriteSchedulerPeer {
- public:
-  explicit PriorityWriteSchedulerPeer(
-      PriorityWriteScheduler<StreamIdType>* scheduler)
-      : scheduler_(scheduler) {}
-
-  size_t NumReadyStreams(SpdyPriority priority) const {
-    return scheduler_->priority_infos_[priority].ready_list.size();
-  }
-
- private:
-  PriorityWriteScheduler<StreamIdType>* scheduler_;
-};
-
-namespace {
-
-class PriorityWriteSchedulerTest : public QuicheTest {
- public:
-  PriorityWriteSchedulerTest() : peer_(&scheduler_) {}
-
-  PriorityWriteScheduler<SpdyStreamId> scheduler_;
-  PriorityWriteSchedulerPeer<SpdyStreamId> peer_;
-};
-
-TEST_F(PriorityWriteSchedulerTest, RegisterUnregisterStreams) {
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_FALSE(scheduler_.StreamRegistered(1));
-  EXPECT_EQ(0u, scheduler_.NumRegisteredStreams());
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(1));
-  EXPECT_TRUE(scheduler_.StreamRegistered(1));
-  EXPECT_EQ(1u, scheduler_.NumRegisteredStreams());
-
-  // Root stream counts as already registered.
-  EXPECT_QUICHE_BUG(
-      scheduler_.RegisterStream(kHttp2RootStreamId, SpdyStreamPrecedence(1)),
-      "Stream 0 already registered");
-
-  // Try redundant registrations.
-  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(1)),
-                    "Stream 1 already registered");
-  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(2)),
-                    "Stream 1 already registered");
-
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
-  EXPECT_EQ(2u, scheduler_.NumRegisteredStreams());
-
-  // Verify registration != ready.
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-
-  scheduler_.UnregisterStream(1);
-  EXPECT_EQ(1u, scheduler_.NumRegisteredStreams());
-  scheduler_.UnregisterStream(2);
-  EXPECT_EQ(0u, scheduler_.NumRegisteredStreams());
-
-  // Try redundant unregistration.
-  EXPECT_QUICHE_BUG(scheduler_.UnregisterStream(1), "Stream 1 not registered");
-  EXPECT_QUICHE_BUG(scheduler_.UnregisterStream(2), "Stream 2 not registered");
-}
-
-TEST_F(PriorityWriteSchedulerTest, RegisterStreamWithHttp2StreamDependency) {
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_FALSE(scheduler_.StreamRegistered(1));
-  scheduler_.RegisterStream(
-      1, SpdyStreamPrecedence(kHttp2RootStreamId, 123, false));
-  EXPECT_TRUE(scheduler_.StreamRegistered(1));
-  EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority());
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-
-  EXPECT_QUICHE_BUG(
-      scheduler_.RegisterStream(
-          1, SpdyStreamPrecedence(kHttp2RootStreamId, 256, false)),
-      "Stream 1 already registered");
-  EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority());
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  // Registering stream with a non-existent parent stream is permissible, per
-  // b/15676312, but parent stream will always be reset to 0.
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3, 123, false));
-  EXPECT_TRUE(scheduler_.StreamRegistered(2));
-  EXPECT_FALSE(scheduler_.StreamRegistered(3));
-  EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(2).parent_id());
-}
-
-TEST_F(PriorityWriteSchedulerTest, GetStreamPrecedence) {
-  // Unknown streams tolerated due to b/15676312. However, return lowest
-  // priority.
-  EXPECT_EQ(kV3LowestPriority,
-            scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
-  EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority());
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  // Redundant registration shouldn't change stream priority.
-  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(4)),
-                    "Stream 1 already registered");
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(5));
-  EXPECT_EQ(5, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  // Toggling ready state shouldn't change stream priority.
-  scheduler_.MarkStreamReady(1, true);
-  EXPECT_EQ(5, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  // Test changing priority of ready stream.
-  EXPECT_EQ(1u, peer_.NumReadyStreams(5));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(6));
-  EXPECT_EQ(6, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-  EXPECT_EQ(0u, peer_.NumReadyStreams(5));
-  EXPECT_EQ(1u, peer_.NumReadyStreams(6));
-
-  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(6, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-
-  scheduler_.UnregisterStream(1);
-  EXPECT_EQ(kV3LowestPriority,
-            scheduler_.GetStreamPrecedence(1).spdy3_priority());
-}
-
-TEST_F(PriorityWriteSchedulerTest, PopNextReadyStreamAndPrecedence) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(1, true);
-  EXPECT_EQ(std::make_tuple(1u, SpdyStreamPrecedence(3)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  scheduler_.UnregisterStream(1);
-}
-
-TEST_F(PriorityWriteSchedulerTest, UpdateStreamPrecedence) {
-  // For the moment, updating stream precedence on a non-registered stream
-  // should have no effect. In the future, it will lazily cause the stream to
-  // be registered (b/15676312).
-  EXPECT_EQ(kV3LowestPriority,
-            scheduler_.GetStreamPrecedence(3).spdy3_priority());
-  EXPECT_FALSE(scheduler_.StreamRegistered(3));
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(1));
-  EXPECT_FALSE(scheduler_.StreamRegistered(3));
-  EXPECT_EQ(kV3LowestPriority,
-            scheduler_.GetStreamPrecedence(3).spdy3_priority());
-
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1));
-  EXPECT_EQ(1, scheduler_.GetStreamPrecedence(3).spdy3_priority());
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(2));
-  EXPECT_EQ(2, scheduler_.GetStreamPrecedence(3).spdy3_priority());
-
-  // Updating priority of stream to current priority value is valid, but has no
-  // effect.
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(2));
-  EXPECT_EQ(2, scheduler_.GetStreamPrecedence(3).spdy3_priority());
-
-  // Even though stream 4 is marked ready after stream 5, it should be returned
-  // first by PopNextReadyStream() since it has higher priority.
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1));
-  scheduler_.MarkStreamReady(3, false);  // priority 2
-  EXPECT_TRUE(scheduler_.IsStreamReady(3));
-  scheduler_.MarkStreamReady(4, false);  // priority 1
-  EXPECT_TRUE(scheduler_.IsStreamReady(4));
-  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
-  EXPECT_FALSE(scheduler_.IsStreamReady(4));
-  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
-  EXPECT_FALSE(scheduler_.IsStreamReady(3));
-
-  // Verify that lowering priority of stream 4 causes it to be returned later
-  // by PopNextReadyStream().
-  scheduler_.MarkStreamReady(3, false);  // priority 2
-  scheduler_.MarkStreamReady(4, false);  // priority 1
-  scheduler_.UpdateStreamPrecedence(4, SpdyStreamPrecedence(3));
-  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
-
-  scheduler_.UnregisterStream(3);
-}
-
-TEST_F(PriorityWriteSchedulerTest,
-       UpdateStreamPrecedenceWithHttp2StreamDependency) {
-  // Unknown streams tolerated due to b/15676312, but should have no effect.
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false));
-  EXPECT_FALSE(scheduler_.StreamRegistered(3));
-
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false));
-  EXPECT_TRUE(scheduler_.GetStreamPrecedence(3).is_spdy3_priority());
-  EXPECT_EQ(4, scheduler_.GetStreamPrecedence(3).spdy3_priority());
-
-  scheduler_.UnregisterStream(3);
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false));
-  EXPECT_FALSE(scheduler_.StreamRegistered(3));
-}
-
-TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBack) {
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_QUICHE_BUG(scheduler_.MarkStreamReady(1, false),
-                    "Stream 1 not registered");
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-
-  // Add a bunch of ready streams to tail of per-priority lists.
-  // Expected order: (P2) 4, (P3) 1, 2, 3, (P5) 5.
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(1, false);
-  EXPECT_TRUE(scheduler_.HasReadyStreams());
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(2, false);
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(3, false);
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2));
-  scheduler_.MarkStreamReady(4, false);
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(5));
-  scheduler_.MarkStreamReady(5, false);
-
-  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-}
-
-TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyFront) {
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_QUICHE_BUG(scheduler_.MarkStreamReady(1, true),
-                    "Stream 1 not registered");
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-
-  // Add a bunch of ready streams to head of per-priority lists.
-  // Expected order: (P2) 4, (P3) 3, 2, 1, (P5) 5
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(1, true);
-  EXPECT_TRUE(scheduler_.HasReadyStreams());
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(2, true);
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
-  scheduler_.MarkStreamReady(3, true);
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2));
-  scheduler_.MarkStreamReady(4, true);
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(5));
-  scheduler_.MarkStreamReady(5, true);
-
-  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-}
-
-TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBackAndFront) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(4));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(3));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(4));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(1));
-
-  // Add a bunch of ready streams to per-priority lists, with variety of adding
-  // at head and tail.
-  // Expected order: (P1) 6, (P3) 4, 2, 3, (P4) 1, 5
-  scheduler_.MarkStreamReady(1, true);
-  scheduler_.MarkStreamReady(2, true);
-  scheduler_.MarkStreamReady(3, false);
-  scheduler_.MarkStreamReady(4, true);
-  scheduler_.MarkStreamReady(5, false);
-  scheduler_.MarkStreamReady(6, true);
-
-  EXPECT_EQ(6u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-}
-
-TEST_F(PriorityWriteSchedulerTest, MarkStreamNotReady) {
-  // Verify ready state reflected in NumReadyStreams().
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(1));
-  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
-  scheduler_.MarkStreamReady(1, false);
-  EXPECT_EQ(1u, scheduler_.NumReadyStreams());
-  scheduler_.MarkStreamNotReady(1);
-  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
-
-  // Empty pop should fail.
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-
-  // Tolerate redundant marking of a stream as not ready.
-  scheduler_.MarkStreamNotReady(1);
-  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
-
-  // Should only be able to mark registered streams.
-  EXPECT_QUICHE_BUG(scheduler_.MarkStreamNotReady(3),
-                    "Stream 3 not registered");
-}
-
-TEST_F(PriorityWriteSchedulerTest, UnregisterRemovesStream) {
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(4));
-  scheduler_.MarkStreamReady(3, false);
-  EXPECT_EQ(1u, scheduler_.NumReadyStreams());
-
-  // Unregistering a stream should remove it from set of ready streams.
-  scheduler_.UnregisterStream(3);
-  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
-                    "No ready streams available");
-}
-
-TEST_F(PriorityWriteSchedulerTest, ShouldYield) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(1));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(4));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(4));
-  scheduler_.RegisterStream(7, SpdyStreamPrecedence(7));
-
-  // Make sure we don't yield when the list is empty.
-  EXPECT_FALSE(scheduler_.ShouldYield(1));
-
-  // Add a low priority stream.
-  scheduler_.MarkStreamReady(4, false);
-  // 4 should not yield to itself.
-  EXPECT_FALSE(scheduler_.ShouldYield(4));
-  // 7 should yield as 4 is blocked and a higher priority.
-  EXPECT_TRUE(scheduler_.ShouldYield(7));
-  // 5 should yield to 4 as they are the same priority.
-  EXPECT_TRUE(scheduler_.ShouldYield(5));
-  // 1 should not yield as 1 is higher priority.
-  EXPECT_FALSE(scheduler_.ShouldYield(1));
-
-  // Add a second stream in that priority class.
-  scheduler_.MarkStreamReady(5, false);
-  // 4 and 5 are both blocked, but 4 is at the front so should not yield.
-  EXPECT_FALSE(scheduler_.ShouldYield(4));
-  EXPECT_TRUE(scheduler_.ShouldYield(5));
-}
-
-TEST_F(PriorityWriteSchedulerTest, GetLatestEventWithPrecedence) {
-  EXPECT_QUICHE_BUG(scheduler_.RecordStreamEventTime(3, 5),
-                    "Stream 3 not registered");
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(4)),
-                    "Stream 4 not registered");
-
-  for (int i = 1; i < 5; ++i) {
-    scheduler_.RegisterStream(i, SpdyStreamPrecedence(i));
-  }
-  for (int i = 1; i < 5; ++i) {
-    EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(i));
-  }
-  for (int i = 1; i < 5; ++i) {
-    scheduler_.RecordStreamEventTime(i, i * 100);
-  }
-  for (int i = 1; i < 5; ++i) {
-    EXPECT_EQ((i - 1) * 100, scheduler_.GetLatestEventWithPrecedence(i));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/core/write_scheduler.h b/http2/core/write_scheduler.h
deleted file mode 100644
index 3b58c4f..0000000
--- a/http2/core/write_scheduler.h
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
-#define QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
-
-#include <cstdint>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-
-// Abstract superclass for classes that decide which SPDY or HTTP/2 stream to
-// write next. Concrete subclasses implement various scheduling policies:
-//
-// PriorityWriteScheduler: implements SPDY priority-based stream scheduling,
-//     where (writable) higher-priority streams are always given precedence
-//     over lower-priority streams.
-//
-// The type used to represent stream IDs (StreamIdType) is templated in order
-// to allow for use by both SPDY and QUIC codebases. It must be a POD that
-// supports comparison (i.e., a numeric type).
-//
-// Each stream can be in one of two states: ready or not ready (for writing).
-// Ready state is changed by calling the MarkStreamReady() and
-// MarkStreamNotReady() methods. Only streams in the ready state can be
-// returned by PopNextReadyStream(); when returned by that method, the stream's
-// state changes to not ready.
-template <typename StreamIdType>
-class QUICHE_EXPORT_PRIVATE WriteScheduler {
- public:
-  typedef spdy::StreamPrecedence<StreamIdType> StreamPrecedenceType;
-
-  virtual ~WriteScheduler() {}
-
-  // Registers new stream |stream_id| with the scheduler, assigning it the
-  // given precedence. If the scheduler supports stream dependencies, the
-  // stream is inserted into the dependency tree under
-  // |precedence.parent_id()|.
-  //
-  // Preconditions: |stream_id| should be unregistered, and
-  // |precedence.parent_id()| should be registered or |kHttp2RootStreamId|.
-  virtual void RegisterStream(StreamIdType stream_id,
-                              const StreamPrecedenceType& precedence) = 0;
-
-  // Unregisters the given stream from the scheduler, which will no longer keep
-  // state for it.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual void UnregisterStream(StreamIdType stream_id) = 0;
-
-  // Returns true if the given stream is currently registered.
-  virtual bool StreamRegistered(StreamIdType stream_id) const = 0;
-
-  // Returns the precedence of the specified stream. If the scheduler supports
-  // stream dependencies, calling |parent_id()| on the return value returns the
-  // stream's parent, and calling |exclusive()| returns true iff the specified
-  // stream is an only child of the parent stream.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual StreamPrecedenceType GetStreamPrecedence(
-      StreamIdType stream_id) const = 0;
-
-  // Updates the precedence of the given stream. If the scheduler supports
-  // stream dependencies, |stream_id|'s parent will be updated to be
-  // |precedence.parent_id()| if it is not already.
-  //
-  // Preconditions: |stream_id| should be unregistered, and
-  // |precedence.parent_id()| should be registered or |kHttp2RootStreamId|.
-  virtual void UpdateStreamPrecedence(
-      StreamIdType stream_id,
-      const StreamPrecedenceType& precedence) = 0;
-
-  // Returns child streams of the given stream, if any. If the scheduler
-  // doesn't support stream dependencies, returns an empty vector.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual std::vector<StreamIdType> GetStreamChildren(
-      StreamIdType stream_id) const = 0;
-
-  // Records time (in microseconds) of a read/write event for the given
-  // stream.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual void RecordStreamEventTime(StreamIdType stream_id,
-                                     int64_t now_in_usec) = 0;
-
-  // Returns time (in microseconds) of the last read/write event for a stream
-  // with higher priority than the priority of the given stream, or 0 if there
-  // is no such event.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual int64_t GetLatestEventWithPrecedence(
-      StreamIdType stream_id) const = 0;
-
-  // If the scheduler has any ready streams, returns the next scheduled
-  // ready stream, in the process transitioning the stream from ready to not
-  // ready.
-  //
-  // Preconditions: |HasReadyStreams() == true|
-  virtual StreamIdType PopNextReadyStream() = 0;
-
-  // If the scheduler has any ready streams, returns the next scheduled
-  // ready stream and its priority, in the process transitioning the stream from
-  // ready to not ready.
-  //
-  // Preconditions: |HasReadyStreams() == true|
-  virtual std::tuple<StreamIdType, StreamPrecedenceType>
-  PopNextReadyStreamAndPrecedence() = 0;
-
-  // Returns true if there's another stream ahead of the given stream in the
-  // scheduling queue.  This function can be called to see if the given stream
-  // should yield work to another stream.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual bool ShouldYield(StreamIdType stream_id) const = 0;
-
-  // Marks the stream as ready to write. If the stream was already ready, does
-  // nothing. If add_to_front is true, the stream is scheduled ahead of other
-  // streams of the same priority/weight, otherwise it is scheduled behind them.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual void MarkStreamReady(StreamIdType stream_id, bool add_to_front) = 0;
-
-  // Marks the stream as not ready to write. If the stream is not registered or
-  // not ready, does nothing.
-  //
-  // Preconditions: |stream_id| should be registered.
-  virtual void MarkStreamNotReady(StreamIdType stream_id) = 0;
-
-  // Returns true iff the scheduler has any ready streams.
-  virtual bool HasReadyStreams() const = 0;
-
-  // Returns the number of streams currently marked ready.
-  virtual size_t NumReadyStreams() const = 0;
-
-  // Returns true if stream with |stream_id| is ready.
-  virtual bool IsStreamReady(StreamIdType stream_id) const = 0;
-
-  // Returns the number of registered streams.
-  virtual size_t NumRegisteredStreams() const = 0;
-
-  // Returns summary of internal state, for logging/debugging.
-  virtual std::string DebugString() const = 0;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
diff --git a/http2/decoder/decode_buffer.cc b/http2/decoder/decode_buffer.cc
deleted file mode 100644
index 2d1b6f7..0000000
--- a/http2/decoder/decode_buffer.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/decode_buffer.h"
-
-namespace http2 {
-
-uint8_t DecodeBuffer::DecodeUInt8() {
-  return static_cast<uint8_t>(DecodeChar());
-}
-
-uint16_t DecodeBuffer::DecodeUInt16() {
-  QUICHE_DCHECK_LE(2u, Remaining());
-  const uint8_t b1 = DecodeUInt8();
-  const uint8_t b2 = DecodeUInt8();
-  // Note that chars are automatically promoted to ints during arithmetic,
-  // so the b1 << 8 doesn't end up as zero before being or-ed with b2.
-  // And the left-shift operator has higher precedence than the or operator.
-  return b1 << 8 | b2;
-}
-
-uint32_t DecodeBuffer::DecodeUInt24() {
-  QUICHE_DCHECK_LE(3u, Remaining());
-  const uint8_t b1 = DecodeUInt8();
-  const uint8_t b2 = DecodeUInt8();
-  const uint8_t b3 = DecodeUInt8();
-  return b1 << 16 | b2 << 8 | b3;
-}
-
-uint32_t DecodeBuffer::DecodeUInt31() {
-  QUICHE_DCHECK_LE(4u, Remaining());
-  const uint8_t b1 = DecodeUInt8() & 0x7f;  // Mask out the high order bit.
-  const uint8_t b2 = DecodeUInt8();
-  const uint8_t b3 = DecodeUInt8();
-  const uint8_t b4 = DecodeUInt8();
-  return b1 << 24 | b2 << 16 | b3 << 8 | b4;
-}
-
-uint32_t DecodeBuffer::DecodeUInt32() {
-  QUICHE_DCHECK_LE(4u, Remaining());
-  const uint8_t b1 = DecodeUInt8();
-  const uint8_t b2 = DecodeUInt8();
-  const uint8_t b3 = DecodeUInt8();
-  const uint8_t b4 = DecodeUInt8();
-  return b1 << 24 | b2 << 16 | b3 << 8 | b4;
-}
-
-#ifndef NDEBUG
-void DecodeBuffer::set_subset_of_base(DecodeBuffer* base,
-                                      const DecodeBufferSubset* subset) {
-  QUICHE_DCHECK_EQ(this, subset);
-  base->set_subset(subset);
-}
-void DecodeBuffer::clear_subset_of_base(DecodeBuffer* base,
-                                        const DecodeBufferSubset* subset) {
-  QUICHE_DCHECK_EQ(this, subset);
-  base->clear_subset(subset);
-}
-void DecodeBuffer::set_subset(const DecodeBufferSubset* subset) {
-  QUICHE_DCHECK(subset != nullptr);
-  QUICHE_DCHECK_EQ(subset_, nullptr) << "There is already a subset";
-  subset_ = subset;
-}
-void DecodeBuffer::clear_subset(const DecodeBufferSubset* subset) {
-  QUICHE_DCHECK(subset != nullptr);
-  QUICHE_DCHECK_EQ(subset_, subset);
-  subset_ = nullptr;
-}
-void DecodeBufferSubset::DebugSetup() {
-  start_base_offset_ = base_buffer_->Offset();
-  max_base_offset_ = start_base_offset_ + FullSize();
-  QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());
-
-  // Ensure that there is only one DecodeBufferSubset at a time for a base.
-  set_subset_of_base(base_buffer_, this);
-}
-void DecodeBufferSubset::DebugTearDown() {
-  // Ensure that the base hasn't been modified.
-  QUICHE_DCHECK_EQ(start_base_offset_, base_buffer_->Offset())
-      << "The base buffer was modified";
-
-  // Ensure that we haven't gone beyond the maximum allowed offset.
-  size_t offset = Offset();
-  QUICHE_DCHECK_LE(offset, FullSize());
-  QUICHE_DCHECK_LE(start_base_offset_ + offset, max_base_offset_);
-  QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());
-
-  clear_subset_of_base(base_buffer_, this);
-}
-#endif
-
-}  // namespace http2
diff --git a/http2/decoder/decode_buffer.h b/http2/decoder/decode_buffer.h
deleted file mode 100644
index 3d0f5d5..0000000
--- a/http2/decoder/decode_buffer.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
-#define QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
-
-// DecodeBuffer provides primitives for decoding various integer types found in
-// HTTP/2 frames. It wraps a byte array from which we can read and decode
-// serialized HTTP/2 frames, or parts thereof. DecodeBuffer is intended only for
-// stack allocation, where the caller is typically going to use the DecodeBuffer
-// instance as part of decoding the entire buffer before returning to its own
-// caller.
-
-#include <stddef.h>
-
-#include <algorithm>
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-class DecodeBufferSubset;
-
-class QUICHE_EXPORT_PRIVATE DecodeBuffer {
- public:
-  // We assume the decode buffers will typically be modest in size (i.e. often a
-  // few KB, perhaps as high as 100KB). Let's make sure during testing that we
-  // don't go very high, with 32MB selected rather arbitrarily. This is exposed
-  // to support testing.
-  static constexpr size_t kMaxDecodeBufferLength = 1 << 25;
-
-  DecodeBuffer(const char* buffer, size_t len)
-      : buffer_(buffer), cursor_(buffer), beyond_(buffer + len) {
-    QUICHE_DCHECK(buffer != nullptr);
-    QUICHE_DCHECK_LE(len, kMaxDecodeBufferLength);
-  }
-  explicit DecodeBuffer(absl::string_view s)
-      : DecodeBuffer(s.data(), s.size()) {}
-  // Constructor for character arrays, typically in tests. For example:
-  //    const char input[] = { 0x11 };
-  //    DecodeBuffer b(input);
-  template <size_t N>
-  explicit DecodeBuffer(const char (&buf)[N]) : DecodeBuffer(buf, N) {}
-
-  DecodeBuffer(const DecodeBuffer&) = delete;
-  DecodeBuffer operator=(const DecodeBuffer&) = delete;
-
-  bool Empty() const { return cursor_ >= beyond_; }
-  bool HasData() const { return cursor_ < beyond_; }
-  size_t Remaining() const {
-    QUICHE_DCHECK_LE(cursor_, beyond_);
-    return beyond_ - cursor_;
-  }
-  size_t Offset() const { return cursor_ - buffer_; }
-  size_t FullSize() const { return beyond_ - buffer_; }
-
-  // Returns the minimum of the number of bytes remaining in this DecodeBuffer
-  // and |length|, in support of determining how much of some structure/payload
-  // is in this DecodeBuffer.
-  size_t MinLengthRemaining(size_t length) const {
-    return std::min(length, Remaining());
-  }
-
-  // For string decoding, returns a pointer to the next byte/char to be decoded.
-  const char* cursor() const { return cursor_; }
-  // Advances the cursor (pointer to the next byte/char to be decoded).
-  void AdvanceCursor(size_t amount) {
-    QUICHE_DCHECK_LE(amount,
-                     Remaining());  // Need at least that much remaining.
-    QUICHE_DCHECK_EQ(subset_, nullptr)
-        << "Access via subset only when present.";
-    cursor_ += amount;
-  }
-
-  // Only call methods starting "Decode" when there is enough input remaining.
-  char DecodeChar() {
-    QUICHE_DCHECK_LE(1u, Remaining());  // Need at least one byte remaining.
-    QUICHE_DCHECK_EQ(subset_, nullptr)
-        << "Access via subset only when present.";
-    return *cursor_++;
-  }
-
-  uint8_t DecodeUInt8();
-  uint16_t DecodeUInt16();
-  uint32_t DecodeUInt24();
-
-  // For 31-bit unsigned integers, where the 32nd bit is reserved for future
-  // use (i.e. the high-bit of the first byte of the encoding); examples:
-  // the Stream Id in a frame header or the Window Size Increment in a
-  // WINDOW_UPDATE frame.
-  uint32_t DecodeUInt31();
-
-  uint32_t DecodeUInt32();
-
- protected:
-#ifndef NDEBUG
-  // These are part of validating during tests that there is at most one
-  // DecodeBufferSubset instance at a time for any DecodeBuffer instance.
-  void set_subset_of_base(DecodeBuffer* base, const DecodeBufferSubset* subset);
-  void clear_subset_of_base(DecodeBuffer* base,
-                            const DecodeBufferSubset* subset);
-#endif
-
- private:
-#ifndef NDEBUG
-  void set_subset(const DecodeBufferSubset* subset);
-  void clear_subset(const DecodeBufferSubset* subset);
-#endif
-
-  // Prevent heap allocation of DecodeBuffer.
-  static void* operator new(size_t s);
-  static void* operator new[](size_t s);
-  static void operator delete(void* p);
-  static void operator delete[](void* p);
-
-  const char* const buffer_;
-  const char* cursor_;
-  const char* const beyond_;
-  const DecodeBufferSubset* subset_ = nullptr;  // Used for QUICHE_DCHECKs.
-};
-
-// DecodeBufferSubset is used when decoding a known sized chunk of data, which
-// starts at base->cursor(), and continues for subset_len, which may be
-// entirely in |base|, or may extend beyond it (hence the MinLengthRemaining
-// in the constructor).
-// There are two benefits to using DecodeBufferSubset: it ensures that the
-// cursor of |base| is advanced when the subset's destructor runs, and it
-// ensures that the consumer of the subset can't go beyond the subset which
-// it is intended to decode.
-// There must be only a single DecodeBufferSubset at a time for a base
-// DecodeBuffer, though they can be nested (i.e. a DecodeBufferSubset's
-// base may itself be a DecodeBufferSubset). This avoids the AdvanceCursor
-// being called erroneously.
-class QUICHE_EXPORT_PRIVATE DecodeBufferSubset : public DecodeBuffer {
- public:
-  DecodeBufferSubset(DecodeBuffer* base, size_t subset_len)
-      : DecodeBuffer(base->cursor(), base->MinLengthRemaining(subset_len)),
-        base_buffer_(base) {
-#ifndef NDEBUG
-    DebugSetup();
-#endif
-  }
-
-  DecodeBufferSubset(const DecodeBufferSubset&) = delete;
-  DecodeBufferSubset operator=(const DecodeBufferSubset&) = delete;
-
-  ~DecodeBufferSubset() {
-    size_t offset = Offset();
-#ifndef NDEBUG
-    DebugTearDown();
-#endif
-    base_buffer_->AdvanceCursor(offset);
-  }
-
- private:
-  DecodeBuffer* const base_buffer_;
-#ifndef NDEBUG
-  size_t start_base_offset_;  // Used for QUICHE_DCHECKs.
-  size_t max_base_offset_;    // Used for QUICHE_DCHECKs.
-
-  void DebugSetup();
-  void DebugTearDown();
-#endif
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
diff --git a/http2/decoder/decode_buffer_test.cc b/http2/decoder/decode_buffer_test.cc
deleted file mode 100644
index 54c0fea..0000000
--- a/http2/decoder/decode_buffer_test.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/decode_buffer.h"
-
-#include <functional>
-
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-enum class TestEnumClass32 {
-  kValue1 = 1,
-  kValue99 = 99,
-  kValue1M = 1000000,
-};
-
-enum class TestEnumClass8 {
-  kValue1 = 1,
-  kValue2 = 1,
-  kValue99 = 99,
-  kValue255 = 255,
-};
-
-enum TestEnum8 {
-  kMaskLo = 0x01,
-  kMaskHi = 0x80,
-};
-
-struct TestStruct {
-  uint8_t f1;
-  uint16_t f2;
-  uint32_t f3;  // Decoded as a uint24
-  uint32_t f4;
-  uint32_t f5;  // Decoded as if uint31
-  TestEnumClass32 f6;
-  TestEnumClass8 f7;
-  TestEnum8 f8;
-};
-
-class DecodeBufferTest : public QuicheTest {
- protected:
-  Http2Random random_;
-  uint32_t decode_offset_;
-};
-
-TEST_F(DecodeBufferTest, DecodesFixedInts) {
-  const char data[] = "\x01\x12\x23\x34\x45\x56\x67\x78\x89\x9a";
-  DecodeBuffer b1(data, strlen(data));
-  EXPECT_EQ(1, b1.DecodeUInt8());
-  EXPECT_EQ(0x1223u, b1.DecodeUInt16());
-  EXPECT_EQ(0x344556u, b1.DecodeUInt24());
-  EXPECT_EQ(0x6778899Au, b1.DecodeUInt32());
-}
-
-// Make sure that DecodeBuffer is not copying input, just pointing into
-// provided input buffer.
-TEST_F(DecodeBufferTest, HasNotCopiedInput) {
-  const char data[] = "ab";
-  DecodeBuffer b1(data, 2);
-
-  EXPECT_EQ(2u, b1.Remaining());
-  EXPECT_EQ(0u, b1.Offset());
-  EXPECT_FALSE(b1.Empty());
-  EXPECT_EQ(data, b1.cursor());  // cursor points to input buffer
-  EXPECT_TRUE(b1.HasData());
-
-  b1.AdvanceCursor(1);
-
-  EXPECT_EQ(1u, b1.Remaining());
-  EXPECT_EQ(1u, b1.Offset());
-  EXPECT_FALSE(b1.Empty());
-  EXPECT_EQ(&data[1], b1.cursor());
-  EXPECT_TRUE(b1.HasData());
-
-  b1.AdvanceCursor(1);
-
-  EXPECT_EQ(0u, b1.Remaining());
-  EXPECT_EQ(2u, b1.Offset());
-  EXPECT_TRUE(b1.Empty());
-  EXPECT_EQ(&data[2], b1.cursor());
-  EXPECT_FALSE(b1.HasData());
-
-  DecodeBuffer b2(data, 0);
-
-  EXPECT_EQ(0u, b2.Remaining());
-  EXPECT_EQ(0u, b2.Offset());
-  EXPECT_TRUE(b2.Empty());
-  EXPECT_EQ(data, b2.cursor());
-  EXPECT_FALSE(b2.HasData());
-}
-
-// DecodeBufferSubset can't go beyond the end of the base buffer.
-TEST_F(DecodeBufferTest, DecodeBufferSubsetLimited) {
-  const char data[] = "abc";
-  DecodeBuffer base(data, 3);
-  base.AdvanceCursor(1);
-  DecodeBufferSubset subset(&base, 100);
-  EXPECT_EQ(2u, subset.FullSize());
-}
-
-// DecodeBufferSubset advances the cursor of its base upon destruction.
-TEST_F(DecodeBufferTest, DecodeBufferSubsetAdvancesCursor) {
-  const char data[] = "abc";
-  const size_t size = sizeof(data) - 1;
-  EXPECT_EQ(3u, size);
-  DecodeBuffer base(data, size);
-  {
-    // First no change to the cursor.
-    DecodeBufferSubset subset(&base, size + 100);
-    EXPECT_EQ(size, subset.FullSize());
-    EXPECT_EQ(base.FullSize(), subset.FullSize());
-    EXPECT_EQ(0u, subset.Offset());
-  }
-  EXPECT_EQ(0u, base.Offset());
-  EXPECT_EQ(size, base.Remaining());
-}
-
-// Make sure that DecodeBuffer ctor complains about bad args.
-#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-TEST(DecodeBufferDeathTest, NonNullBufferRequired) {
-  EXPECT_DEBUG_DEATH({ DecodeBuffer b(nullptr, 3); }, "nullptr");
-}
-
-// Make sure that DecodeBuffer ctor complains about bad args.
-TEST(DecodeBufferDeathTest, ModestBufferSizeRequired) {
-  EXPECT_DEBUG_DEATH(
-      {
-        // This depends on being able to allocate a fairly large array on the
-        // stack. If that fails, we can instead do this:
-        //
-        //   std::string data(DecodeBuffer::kMaxDecodeBufferLength + 1, ' ');
-        //   DecodeBuffer b(data.data(), data.size());
-
-        const char data[DecodeBuffer::kMaxDecodeBufferLength + 1] = {};
-        DecodeBuffer b(data, sizeof data);
-      },
-      "Max.*Length");
-}
-
-// Make sure that DecodeBuffer detects advance beyond end, in debug mode.
-TEST(DecodeBufferDeathTest, LimitedAdvance) {
-  {
-    // Advance right up to end is OK.
-    const char data[] = "abc";
-    DecodeBuffer b(data, 3);
-    b.AdvanceCursor(3);  // OK
-    EXPECT_TRUE(b.Empty());
-  }
-  EXPECT_DEBUG_DEATH(
-      {
-        // Going beyond is not OK.
-        const char data[] = "abc";
-        DecodeBuffer b(data, 3);
-        b.AdvanceCursor(4);
-      },
-      "4 vs. 3");
-}
-
-// Make sure that DecodeBuffer detects decode beyond end, in debug mode.
-TEST(DecodeBufferDeathTest, DecodeUInt8PastEnd) {
-  const char data[] = {0x12, 0x23};
-  DecodeBuffer b(data, sizeof data);
-  EXPECT_EQ(2u, b.FullSize());
-  EXPECT_EQ(0x1223, b.DecodeUInt16());
-  EXPECT_DEBUG_DEATH({ b.DecodeUInt8(); }, "1 vs. 0");
-}
-
-// Make sure that DecodeBuffer detects decode beyond end, in debug mode.
-TEST(DecodeBufferDeathTest, DecodeUInt16OverEnd) {
-  const char data[] = {0x12, 0x23, 0x34};
-  DecodeBuffer b(data, sizeof data);
-  EXPECT_EQ(3u, b.FullSize());
-  EXPECT_EQ(0x1223, b.DecodeUInt16());
-  EXPECT_DEBUG_DEATH({ b.DecodeUInt16(); }, "2 vs. 1");
-}
-
-// Make sure that DecodeBuffer doesn't agree with having two subsets.
-TEST(DecodeBufferSubsetDeathTest, TwoSubsets) {
-  const char data[] = "abc";
-  DecodeBuffer base(data, 3);
-  DecodeBufferSubset subset1(&base, 1);
-  EXPECT_DEBUG_DEATH({ DecodeBufferSubset subset2(&base, 1); },
-                     "There is already a subset");
-}
-
-// Make sure that DecodeBufferSubset notices when the base's cursor has moved.
-TEST(DecodeBufferSubsetDeathTest, BaseCursorAdvanced) {
-  const char data[] = "abc";
-  DecodeBuffer base(data, 3);
-  base.AdvanceCursor(1);
-  EXPECT_DEBUG_DEATH(
-      {
-        DecodeBufferSubset subset1(&base, 2);
-        base.AdvanceCursor(1);
-      },
-      "Access via subset only when present");
-}
-#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/decode_http2_structures.cc b/http2/decoder/decode_http2_structures.cc
deleted file mode 100644
index a5582c2..0000000
--- a/http2/decoder/decode_http2_structures.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/decode_http2_structures.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-// Http2FrameHeader decoding:
-
-void DoDecode(Http2FrameHeader* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2FrameHeader::EncodedSize(), b->Remaining());
-  out->payload_length = b->DecodeUInt24();
-  out->type = static_cast<Http2FrameType>(b->DecodeUInt8());
-  out->flags = static_cast<Http2FrameFlag>(b->DecodeUInt8());
-  out->stream_id = b->DecodeUInt31();
-}
-
-// Http2PriorityFields decoding:
-
-void DoDecode(Http2PriorityFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2PriorityFields::EncodedSize(), b->Remaining());
-  uint32_t stream_id_and_flag = b->DecodeUInt32();
-  out->stream_dependency = stream_id_and_flag & StreamIdMask();
-  if (out->stream_dependency == stream_id_and_flag) {
-    out->is_exclusive = false;
-  } else {
-    out->is_exclusive = true;
-  }
-  // Note that chars are automatically promoted to ints during arithmetic,
-  // so 255 + 1 doesn't end up as zero.
-  out->weight = b->DecodeUInt8() + 1;
-}
-
-// Http2RstStreamFields decoding:
-
-void DoDecode(Http2RstStreamFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2RstStreamFields::EncodedSize(), b->Remaining());
-  out->error_code = static_cast<Http2ErrorCode>(b->DecodeUInt32());
-}
-
-// Http2SettingFields decoding:
-
-void DoDecode(Http2SettingFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2SettingFields::EncodedSize(), b->Remaining());
-  out->parameter = static_cast<Http2SettingsParameter>(b->DecodeUInt16());
-  out->value = b->DecodeUInt32();
-}
-
-// Http2PushPromiseFields decoding:
-
-void DoDecode(Http2PushPromiseFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2PushPromiseFields::EncodedSize(), b->Remaining());
-  out->promised_stream_id = b->DecodeUInt31();
-}
-
-// Http2PingFields decoding:
-
-void DoDecode(Http2PingFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2PingFields::EncodedSize(), b->Remaining());
-  memcpy(out->opaque_bytes, b->cursor(), Http2PingFields::EncodedSize());
-  b->AdvanceCursor(Http2PingFields::EncodedSize());
-}
-
-// Http2GoAwayFields decoding:
-
-void DoDecode(Http2GoAwayFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2GoAwayFields::EncodedSize(), b->Remaining());
-  out->last_stream_id = b->DecodeUInt31();
-  out->error_code = static_cast<Http2ErrorCode>(b->DecodeUInt32());
-}
-
-// Http2WindowUpdateFields decoding:
-
-void DoDecode(Http2WindowUpdateFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2WindowUpdateFields::EncodedSize(), b->Remaining());
-  out->window_size_increment = b->DecodeUInt31();
-}
-
-// Http2PriorityUpdateFields decoding:
-
-void DoDecode(Http2PriorityUpdateFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2PriorityUpdateFields::EncodedSize(), b->Remaining());
-  out->prioritized_stream_id = b->DecodeUInt31();
-}
-
-// Http2AltSvcFields decoding:
-
-void DoDecode(Http2AltSvcFields* out, DecodeBuffer* b) {
-  QUICHE_DCHECK_NE(nullptr, out);
-  QUICHE_DCHECK_NE(nullptr, b);
-  QUICHE_DCHECK_LE(Http2AltSvcFields::EncodedSize(), b->Remaining());
-  out->origin_length = b->DecodeUInt16();
-}
-
-}  // namespace http2
diff --git a/http2/decoder/decode_http2_structures.h b/http2/decoder/decode_http2_structures.h
deleted file mode 100644
index 9b26d33..0000000
--- a/http2/decoder/decode_http2_structures.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_DECODE_HTTP2_STRUCTURES_H_
-#define QUICHE_HTTP2_DECODER_DECODE_HTTP2_STRUCTURES_H_
-
-// Provides functions for decoding the fixed size structures in the HTTP/2 spec.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// DoDecode(STRUCTURE* out, DecodeBuffer* b) decodes the structure from start
-// to end, advancing the cursor by STRUCTURE::EncodedSize(). The decode buffer
-// must be large enough (i.e. b->Remaining() >= STRUCTURE::EncodedSize()).
-
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2FrameHeader* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2PriorityFields* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2RstStreamFields* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2SettingFields* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2PushPromiseFields* out,
-                                    DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2PingFields* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2GoAwayFields* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2WindowUpdateFields* out,
-                                    DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2AltSvcFields* out, DecodeBuffer* b);
-QUICHE_EXPORT_PRIVATE void DoDecode(Http2PriorityUpdateFields* out,
-                                    DecodeBuffer* b);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_DECODE_HTTP2_STRUCTURES_H_
diff --git a/http2/decoder/decode_http2_structures_test.cc b/http2/decoder/decode_http2_structures_test.cc
deleted file mode 100644
index 89833e5..0000000
--- a/http2/decoder/decode_http2_structures_test.cc
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/decode_http2_structures.h"
-
-// Tests decoding all of the fixed size HTTP/2 structures (i.e. those defined
-// in http2/http2_structures.h).
-
-#include <stddef.h>
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-template <typename T, size_t N>
-absl::string_view ToStringPiece(T (&data)[N]) {
-  return absl::string_view(reinterpret_cast<const char*>(data), N * sizeof(T));
-}
-
-template <class S>
-std::string SerializeStructure(const S& s) {
-  Http2FrameBuilder fb;
-  fb.Append(s);
-  EXPECT_EQ(S::EncodedSize(), fb.size());
-  return fb.buffer();
-}
-
-template <class S>
-class StructureDecoderTest : public QuicheTest {
- protected:
-  typedef S Structure;
-
-  StructureDecoderTest() : random_(), random_decode_count_(100) {}
-
-  // Set the fields of |*p| to random values.
-  void Randomize(S* p) { ::http2::test::Randomize(p, &random_); }
-
-  // Fully decodes the Structure at the start of data, and confirms it matches
-  // *expected (if provided).
-  void DecodeLeadingStructure(const S* expected, absl::string_view data) {
-    ASSERT_LE(S::EncodedSize(), data.size());
-    DecodeBuffer db(data);
-    Randomize(&structure_);
-    DoDecode(&structure_, &db);
-    EXPECT_EQ(db.Offset(), S::EncodedSize());
-    if (expected != nullptr) {
-      EXPECT_EQ(structure_, *expected);
-    }
-  }
-
-  template <size_t N>
-  void DecodeLeadingStructure(const char (&data)[N]) {
-    DecodeLeadingStructure(nullptr, absl::string_view(data, N));
-  }
-
-  // Encode the structure |in_s| into bytes, then decode the bytes
-  // and validate that the decoder produced the same field values.
-  void EncodeThenDecode(const S& in_s) {
-    std::string bytes = SerializeStructure(in_s);
-    EXPECT_EQ(S::EncodedSize(), bytes.size());
-    DecodeLeadingStructure(&in_s, bytes);
-  }
-
-  // Generate
-  void TestDecodingRandomizedStructures(size_t count) {
-    for (size_t i = 0; i < count && !HasFailure(); ++i) {
-      Structure input;
-      Randomize(&input);
-      EncodeThenDecode(input);
-    }
-  }
-
-  void TestDecodingRandomizedStructures() {
-    TestDecodingRandomizedStructures(random_decode_count_);
-  }
-
-  Http2Random random_;
-  const size_t random_decode_count_;
-  uint32_t decode_offset_ = 0;
-  S structure_;
-  size_t fast_decode_count_ = 0;
-  size_t slow_decode_count_ = 0;
-};
-
-class FrameHeaderDecoderTest : public StructureDecoderTest<Http2FrameHeader> {};
-
-TEST_F(FrameHeaderDecoderTest, DecodesLiteral) {
-  {
-    // Realistic input.
-    const char kData[] = {
-        '\x00', '\x00', '\x05',          // Payload length: 5
-        '\x01',                          // Frame type: HEADERS
-        '\x08',                          // Flags: PADDED
-        '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
-        '\x04',                          // Padding length: 4
-        '\x00', '\x00', '\x00', '\x00',  // Padding bytes
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(5u, structure_.payload_length);
-      EXPECT_EQ(Http2FrameType::HEADERS, structure_.type);
-      EXPECT_EQ(Http2FrameFlag::PADDED, structure_.flags);
-      EXPECT_EQ(1u, structure_.stream_id);
-    }
-  }
-  {
-    // Unlikely input.
-    const char kData[] = {
-        '\xff', '\xff', '\xff',          // Payload length: uint24 max
-        '\xff',                          // Frame type: Unknown
-        '\xff',                          // Flags: Unknown/All
-        '\xff', '\xff', '\xff', '\xff',  // Stream ID: uint31 max, plus R-bit
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ((1u << 24) - 1, structure_.payload_length);
-      EXPECT_EQ(static_cast<Http2FrameType>(255), structure_.type);
-      EXPECT_EQ(255, structure_.flags);
-      EXPECT_EQ(0x7FFFFFFFu, structure_.stream_id);
-    }
-  }
-}
-
-TEST_F(FrameHeaderDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class PriorityFieldsDecoderTest
-    : public StructureDecoderTest<Http2PriorityFields> {};
-
-TEST_F(PriorityFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x80', '\x00', '\x00', '\x05',  // Exclusive (yes) and Dependency (5)
-        '\xff',                          // Weight: 256 (after adding 1)
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(5u, structure_.stream_dependency);
-      EXPECT_EQ(256u, structure_.weight);
-      EXPECT_EQ(true, structure_.is_exclusive);
-    }
-  }
-  {
-    const char kData[] = {
-        '\x7f', '\xff',
-        '\xff', '\xff',  // Exclusive (no) and Dependency (0x7fffffff)
-        '\x00',          // Weight: 1 (after adding 1)
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(StreamIdMask(), structure_.stream_dependency);
-      EXPECT_EQ(1u, structure_.weight);
-      EXPECT_FALSE(structure_.is_exclusive);
-    }
-  }
-}
-
-TEST_F(PriorityFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class RstStreamFieldsDecoderTest
-    : public StructureDecoderTest<Http2RstStreamFields> {};
-
-TEST_F(RstStreamFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x00', '\x00', '\x00', '\x01',  // Error: PROTOCOL_ERROR
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_TRUE(structure_.IsSupportedErrorCode());
-      EXPECT_EQ(Http2ErrorCode::PROTOCOL_ERROR, structure_.error_code);
-    }
-  }
-  {
-    const char kData[] = {
-        '\xff', '\xff', '\xff',
-        '\xff',  // Error: max uint32 (Unknown error code)
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_FALSE(structure_.IsSupportedErrorCode());
-      EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_.error_code);
-    }
-  }
-}
-
-TEST_F(RstStreamFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class SettingFieldsDecoderTest
-    : public StructureDecoderTest<Http2SettingFields> {};
-
-TEST_F(SettingFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x00', '\x01',                  // Setting: HEADER_TABLE_SIZE
-        '\x00', '\x00', '\x40', '\x00',  // Value: 16K
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_TRUE(structure_.IsSupportedParameter());
-      EXPECT_EQ(Http2SettingsParameter::HEADER_TABLE_SIZE,
-                structure_.parameter);
-      EXPECT_EQ(1u << 14, structure_.value);
-    }
-  }
-  {
-    const char kData[] = {
-        '\x00', '\x00',                  // Setting: Unknown (0)
-        '\xff', '\xff', '\xff', '\xff',  // Value: max uint32
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_FALSE(structure_.IsSupportedParameter());
-      EXPECT_EQ(static_cast<Http2SettingsParameter>(0), structure_.parameter);
-    }
-  }
-}
-
-TEST_F(SettingFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class PushPromiseFieldsDecoderTest
-    : public StructureDecoderTest<Http2PushPromiseFields> {};
-
-TEST_F(PushPromiseFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x00', '\x01', '\x8a', '\x92',  // Promised Stream ID: 101010
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(101010u, structure_.promised_stream_id);
-    }
-  }
-  {
-    // Promised stream id has R-bit (reserved for future use) set, which
-    // should be cleared by the decoder.
-    const char kData[] = {
-        '\xff', '\xff', '\xff',
-        '\xff',  // Promised Stream ID: max uint31 and R-bit
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(StreamIdMask(), structure_.promised_stream_id);
-    }
-  }
-}
-
-TEST_F(PushPromiseFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class PingFieldsDecoderTest : public StructureDecoderTest<Http2PingFields> {};
-
-TEST_F(PingFieldsDecoderTest, DecodesLiteral) {
-  {
-    // Each byte is different, so can detect if order changed.
-    const char kData[] = {
-        '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(absl::string_view(kData, 8),
-                ToStringPiece(structure_.opaque_bytes));
-    }
-  }
-  {
-    // All zeros, detect problems handling NULs.
-    const char kData[] = {
-        '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(absl::string_view(kData, 8),
-                ToStringPiece(structure_.opaque_bytes));
-    }
-  }
-  {
-    const char kData[] = {
-        '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(absl::string_view(kData, 8),
-                ToStringPiece(structure_.opaque_bytes));
-    }
-  }
-}
-
-TEST_F(PingFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class GoAwayFieldsDecoderTest : public StructureDecoderTest<Http2GoAwayFields> {
-};
-
-TEST_F(GoAwayFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x00', '\x00', '\x00', '\x00',  // Last Stream ID: 0
-        '\x00', '\x00', '\x00', '\x00',  // Error: NO_ERROR (0)
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(0u, structure_.last_stream_id);
-      EXPECT_TRUE(structure_.IsSupportedErrorCode());
-      EXPECT_EQ(Http2ErrorCode::HTTP2_NO_ERROR, structure_.error_code);
-    }
-  }
-  {
-    const char kData[] = {
-        '\x00', '\x00', '\x00', '\x01',  // Last Stream ID: 1
-        '\x00', '\x00', '\x00', '\x0d',  // Error: HTTP_1_1_REQUIRED
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(1u, structure_.last_stream_id);
-      EXPECT_TRUE(structure_.IsSupportedErrorCode());
-      EXPECT_EQ(Http2ErrorCode::HTTP_1_1_REQUIRED, structure_.error_code);
-    }
-  }
-  {
-    const char kData[] = {
-        '\xff', '\xff',
-        '\xff', '\xff',  // Last Stream ID: max uint31 and R-bit
-        '\xff', '\xff',
-        '\xff', '\xff',  // Error: max uint32 (Unknown error code)
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(StreamIdMask(), structure_.last_stream_id);  // No high-bit.
-      EXPECT_FALSE(structure_.IsSupportedErrorCode());
-      EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_.error_code);
-    }
-  }
-}
-
-TEST_F(GoAwayFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class WindowUpdateFieldsDecoderTest
-    : public StructureDecoderTest<Http2WindowUpdateFields> {};
-
-TEST_F(WindowUpdateFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x00', '\x01', '\x00', '\x00',  // Window Size Increment: 2 ^ 16
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(1u << 16, structure_.window_size_increment);
-    }
-  }
-  {
-    // Increment must be non-zero, but we need to be able to decode the invalid
-    // zero to detect it.
-    const char kData[] = {
-        '\x00', '\x00', '\x00', '\x00',  // Window Size Increment: 0
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(0u, structure_.window_size_increment);
-    }
-  }
-  {
-    // Increment has R-bit (reserved for future use) set, which
-    // should be cleared by the decoder.
-    // clang-format off
-    const char kData[] = {
-        // Window Size Increment: max uint31 and R-bit
-        '\xff', '\xff', '\xff', '\xff',
-    };
-    // clang-format on
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(StreamIdMask(), structure_.window_size_increment);
-    }
-  }
-}
-
-TEST_F(WindowUpdateFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-//------------------------------------------------------------------------------
-
-class AltSvcFieldsDecoderTest : public StructureDecoderTest<Http2AltSvcFields> {
-};
-
-TEST_F(AltSvcFieldsDecoderTest, DecodesLiteral) {
-  {
-    const char kData[] = {
-        '\x00', '\x00',  // Origin Length: 0
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(0, structure_.origin_length);
-    }
-  }
-  {
-    const char kData[] = {
-        '\x00', '\x14',  // Origin Length: 20
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(20, structure_.origin_length);
-    }
-  }
-  {
-    const char kData[] = {
-        '\xff', '\xff',  // Origin Length: uint16 max
-    };
-    DecodeLeadingStructure(kData);
-    if (!HasFailure()) {
-      EXPECT_EQ(65535, structure_.origin_length);
-    }
-  }
-}
-
-TEST_F(AltSvcFieldsDecoderTest, DecodesRandomized) {
-  TestDecodingRandomizedStructures();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/decode_status.cc b/http2/decoder/decode_status.cc
deleted file mode 100644
index a5d2c6f..0000000
--- a/http2/decoder/decode_status.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/decode_status.h"
-
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out, DecodeStatus v) {
-  switch (v) {
-    case DecodeStatus::kDecodeDone:
-      return out << "DecodeDone";
-    case DecodeStatus::kDecodeInProgress:
-      return out << "DecodeInProgress";
-    case DecodeStatus::kDecodeError:
-      return out << "DecodeError";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_147_1) << "Unknown DecodeStatus " << unknown;
-  return out << "DecodeStatus(" << unknown << ")";
-}
-
-}  // namespace http2
diff --git a/http2/decoder/decode_status.h b/http2/decoder/decode_status.h
deleted file mode 100644
index e738ddf..0000000
--- a/http2/decoder/decode_status.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_DECODE_STATUS_H_
-#define QUICHE_HTTP2_DECODER_DECODE_STATUS_H_
-
-// Enum DecodeStatus is used to report the status of decoding of many
-// types of HTTP/2 and HPACK objects.
-
-#include <ostream>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-enum class DecodeStatus {
-  // Decoding is done.
-  kDecodeDone,
-
-  // Decoder needs more input to be able to make progress.
-  kDecodeInProgress,
-
-  // Decoding failed (e.g. HPACK variable length integer is too large, or
-  // an HTTP/2 frame has padding declared to be larger than the payload).
-  kDecodeError,
-};
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               DecodeStatus v);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_DECODE_STATUS_H_
diff --git a/http2/decoder/frame_decoder_state.cc b/http2/decoder/frame_decoder_state.cc
deleted file mode 100644
index ee53964..0000000
--- a/http2/decoder/frame_decoder_state.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/frame_decoder_state.h"
-
-namespace http2 {
-
-DecodeStatus FrameDecoderState::ReadPadLength(DecodeBuffer* db,
-                                              bool report_pad_length) {
-  HTTP2_DVLOG(2) << "ReadPadLength db->Remaining=" << db->Remaining()
-                 << "; payload_length=" << frame_header().payload_length;
-  QUICHE_DCHECK(IsPaddable());
-  QUICHE_DCHECK(frame_header().IsPadded());
-
-  // Pad Length is always at the start of the frame, so remaining_payload_
-  // should equal payload_length at this point.
-  const uint32_t total_payload = frame_header().payload_length;
-  QUICHE_DCHECK_EQ(total_payload, remaining_payload_);
-  QUICHE_DCHECK_EQ(0u, remaining_padding_);
-
-  if (db->HasData()) {
-    const uint32_t pad_length = db->DecodeUInt8();
-    const uint32_t total_padding = pad_length + 1;
-    if (total_padding <= total_payload) {
-      remaining_padding_ = pad_length;
-      remaining_payload_ = total_payload - total_padding;
-      if (report_pad_length) {
-        listener()->OnPadLength(pad_length);
-      }
-      return DecodeStatus::kDecodeDone;
-    }
-    const uint32_t missing_length = total_padding - total_payload;
-    // To allow for the possibility of recovery, record the number of
-    // remaining bytes of the frame's payload (invalid though it is)
-    // in remaining_payload_.
-    remaining_payload_ = total_payload - 1;  // 1 for sizeof(Pad Length).
-    remaining_padding_ = 0;
-    listener()->OnPaddingTooLong(frame_header(), missing_length);
-    return DecodeStatus::kDecodeError;
-  }
-
-  if (total_payload == 0) {
-    remaining_payload_ = 0;
-    remaining_padding_ = 0;
-    listener()->OnPaddingTooLong(frame_header(), 1);
-    return DecodeStatus::kDecodeError;
-  }
-  // Need to wait for another buffer.
-  return DecodeStatus::kDecodeInProgress;
-}
-
-bool FrameDecoderState::SkipPadding(DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "SkipPadding remaining_padding_=" << remaining_padding_
-                 << ", db->Remaining=" << db->Remaining()
-                 << ", header: " << frame_header();
-  QUICHE_DCHECK_EQ(remaining_payload_, 0u);
-  QUICHE_DCHECK(IsPaddable()) << "header: " << frame_header();
-  QUICHE_DCHECK(remaining_padding_ == 0 || frame_header().IsPadded())
-      << "remaining_padding_=" << remaining_padding_
-      << ", header: " << frame_header();
-  const size_t avail = AvailablePadding(db);
-  if (avail > 0) {
-    listener()->OnPadding(db->cursor(), avail);
-    db->AdvanceCursor(avail);
-    remaining_padding_ -= avail;
-  }
-  return remaining_padding_ == 0;
-}
-
-DecodeStatus FrameDecoderState::ReportFrameSizeError() {
-  HTTP2_DVLOG(2) << "FrameDecoderState::ReportFrameSizeError: "
-                 << " remaining_payload_=" << remaining_payload_
-                 << "; remaining_padding_=" << remaining_padding_
-                 << ", header: " << frame_header();
-  listener()->OnFrameSizeError(frame_header());
-  return DecodeStatus::kDecodeError;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/frame_decoder_state.h b/http2/decoder/frame_decoder_state.h
deleted file mode 100644
index f0c1357..0000000
--- a/http2/decoder/frame_decoder_state.h
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
-#define QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
-
-// FrameDecoderState provides state and behaviors in support of decoding
-// the common frame header and the payload of all frame types.
-// It is an input to all of the payload decoders.
-
-// TODO(jamessynge): Since FrameDecoderState has far more than state in it,
-// rename to FrameDecoderHelper, or similar.
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/http2_structure_decoder.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class FrameDecoderStatePeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE FrameDecoderState {
- public:
-  FrameDecoderState() {}
-
-  // Sets the listener which the decoders should call as they decode HTTP/2
-  // frames. The listener can be changed at any time, which allows for replacing
-  // it with a no-op listener when an error is detected, either by the payload
-  // decoder (OnPaddingTooLong or OnFrameSizeError) or by the "real" listener.
-  // That in turn allows us to define Http2FrameDecoderListener such that all
-  // methods have return type void, with no direct way to indicate whether the
-  // decoder should stop, and to eliminate from the decoder all checks of the
-  // return value. Instead the listener/caller can simply replace the current
-  // listener with a no-op listener implementation.
-  // TODO(jamessynge): Make set_listener private as only Http2FrameDecoder
-  // and tests need to set it, so it doesn't need to be public.
-  void set_listener(Http2FrameDecoderListener* listener) {
-    listener_ = listener;
-  }
-  Http2FrameDecoderListener* listener() const { return listener_; }
-
-  // The most recently decoded frame header.
-  const Http2FrameHeader& frame_header() const { return frame_header_; }
-
-  // Decode a structure in the payload, adjusting remaining_payload_ to account
-  // for the consumed portion of the payload. Returns kDecodeDone when fully
-  // decoded, kDecodeError if it ran out of payload before decoding completed,
-  // and kDecodeInProgress if the decode buffer didn't have enough of the
-  // remaining payload.
-  template <class S>
-  DecodeStatus StartDecodingStructureInPayload(S* out, DecodeBuffer* db) {
-    HTTP2_DVLOG(2) << __func__ << "\n\tdb->Remaining=" << db->Remaining()
-                   << "\n\tremaining_payload_=" << remaining_payload_
-                   << "\n\tneed=" << S::EncodedSize();
-    DecodeStatus status =
-        structure_decoder_.Start(out, db, &remaining_payload_);
-    if (status != DecodeStatus::kDecodeError) {
-      return status;
-    }
-    HTTP2_DVLOG(2)
-        << "StartDecodingStructureInPayload: detected frame size error";
-    return ReportFrameSizeError();
-  }
-
-  // Resume decoding of a structure that has been split across buffers,
-  // adjusting remaining_payload_ to account for the consumed portion of
-  // the payload. Returns values are as for StartDecodingStructureInPayload.
-  template <class S>
-  DecodeStatus ResumeDecodingStructureInPayload(S* out, DecodeBuffer* db) {
-    HTTP2_DVLOG(2) << __func__ << "\n\tdb->Remaining=" << db->Remaining()
-                   << "\n\tremaining_payload_=" << remaining_payload_;
-    if (structure_decoder_.Resume(out, db, &remaining_payload_)) {
-      return DecodeStatus::kDecodeDone;
-    } else if (remaining_payload_ > 0) {
-      return DecodeStatus::kDecodeInProgress;
-    } else {
-      HTTP2_DVLOG(2)
-          << "ResumeDecodingStructureInPayload: detected frame size error";
-      return ReportFrameSizeError();
-    }
-  }
-
-  // Initializes the two remaining* fields, which is needed if the frame's
-  // payload is split across buffers, or the decoder calls ReadPadLength or
-  // StartDecodingStructureInPayload, and of course the methods below which
-  // read those fields, as their names imply.
-  void InitializeRemainders() {
-    remaining_payload_ = frame_header().payload_length;
-    // Note that remaining_total_payload() relies on remaining_padding_ being
-    // zero for frames that have no padding.
-    remaining_padding_ = 0;
-  }
-
-  // Returns the number of bytes of the frame's payload that remain to be
-  // decoded, including any trailing padding. This method must only be called
-  // after the variables have been initialized, which in practice means once a
-  // payload decoder has called InitializeRemainders and/or ReadPadLength.
-  size_t remaining_total_payload() const {
-    QUICHE_DCHECK(IsPaddable() || remaining_padding_ == 0) << frame_header();
-    return remaining_payload_ + remaining_padding_;
-  }
-
-  // Returns the number of bytes of the frame's payload that remain to be
-  // decoded, excluding any trailing padding. This method must only be called
-  // after the variable has been initialized, which in practice means once a
-  // payload decoder has called InitializeRemainders; ReadPadLength will deduct
-  // the total number of padding bytes from remaining_payload_, including the
-  // size of the Pad Length field itself (1 byte).
-  size_t remaining_payload() const { return remaining_payload_; }
-
-  // Returns the number of bytes of the frame's payload that remain to be
-  // decoded, including any trailing padding. This method must only be called if
-  // the frame type allows padding, and after the variable has been initialized,
-  // which in practice means once a payload decoder has called
-  // InitializeRemainders and/or ReadPadLength.
-  size_t remaining_payload_and_padding() const {
-    QUICHE_DCHECK(IsPaddable()) << frame_header();
-    return remaining_payload_ + remaining_padding_;
-  }
-
-  // Returns the number of bytes of trailing padding after the payload that
-  // remain to be decoded. This method must only be called if the frame type
-  // allows padding, and after the variable has been initialized, which in
-  // practice means once a payload decoder has called InitializeRemainders,
-  // and isn't set to a non-zero value until ReadPadLength has been called.
-  uint32_t remaining_padding() const {
-    QUICHE_DCHECK(IsPaddable()) << frame_header();
-    return remaining_padding_;
-  }
-
-  // How many bytes of the remaining payload are in db?
-  size_t AvailablePayload(DecodeBuffer* db) const {
-    return db->MinLengthRemaining(remaining_payload_);
-  }
-
-  // How many bytes of the remaining payload and padding are in db?
-  // Call only for frames whose type is paddable.
-  size_t AvailablePayloadAndPadding(DecodeBuffer* db) const {
-    QUICHE_DCHECK(IsPaddable()) << frame_header();
-    return db->MinLengthRemaining(remaining_payload_ + remaining_padding_);
-  }
-
-  // How many bytes of the padding that have not yet been skipped are in db?
-  // Call only after remaining_padding_ has been set (for padded frames), or
-  // been cleared (for unpadded frames); and after all of the non-padding
-  // payload has been decoded.
-  size_t AvailablePadding(DecodeBuffer* db) const {
-    QUICHE_DCHECK(IsPaddable()) << frame_header();
-    QUICHE_DCHECK_EQ(remaining_payload_, 0u);
-    return db->MinLengthRemaining(remaining_padding_);
-  }
-
-  // Reduces remaining_payload_ by amount. To be called by a payload decoder
-  // after it has passed a variable length portion of the payload to the
-  // listener; remaining_payload_ will be automatically reduced when fixed
-  // size structures and padding, including the Pad Length field, are decoded.
-  void ConsumePayload(size_t amount) {
-    QUICHE_DCHECK_LE(amount, remaining_payload_);
-    remaining_payload_ -= amount;
-  }
-
-  // Reads the Pad Length field into remaining_padding_, and appropriately sets
-  // remaining_payload_. When present, the Pad Length field is always the first
-  // field in the payload, which this method relies on so that the caller need
-  // not set remaining_payload_ before calling this method.
-  // If report_pad_length is true, calls the listener's OnPadLength method when
-  // it decodes the Pad Length field.
-  // Returns kDecodeDone if the decode buffer was not empty (i.e. because the
-  // field is only a single byte long, it can always be decoded if the buffer is
-  // not empty).
-  // Returns kDecodeError if the buffer is empty because the frame has no
-  // payload (i.e. payload_length() == 0).
-  // Returns kDecodeInProgress if the buffer is empty but the frame has a
-  // payload.
-  DecodeStatus ReadPadLength(DecodeBuffer* db, bool report_pad_length);
-
-  // Skip the trailing padding bytes; only call once remaining_payload_==0.
-  // Returns true when the padding has been skipped.
-  // Does NOT check that the padding is all zeroes.
-  bool SkipPadding(DecodeBuffer* db);
-
-  // Calls the listener's OnFrameSizeError method and returns kDecodeError.
-  DecodeStatus ReportFrameSizeError();
-
- private:
-  friend class Http2FrameDecoder;
-  friend class test::FrameDecoderStatePeer;
-
-  // Starts the decoding of a common frame header. Returns true if completed the
-  // decoding, false if the decode buffer didn't have enough data in it, in
-  // which case the decode buffer will have been drained and the caller should
-  // call ResumeDecodingFrameHeader when more data is available. This is called
-  // from Http2FrameDecoder, a friend class.
-  bool StartDecodingFrameHeader(DecodeBuffer* db) {
-    return structure_decoder_.Start(&frame_header_, db);
-  }
-
-  // Resumes decoding the common frame header after the preceding call to
-  // StartDecodingFrameHeader returned false, as did any subsequent calls to
-  // ResumeDecodingFrameHeader. This is called from Http2FrameDecoder,
-  // a friend class.
-  bool ResumeDecodingFrameHeader(DecodeBuffer* db) {
-    return structure_decoder_.Resume(&frame_header_, db);
-  }
-
-  // Clear any of the flags in the frame header that aren't set in valid_flags.
-  void RetainFlags(uint8_t valid_flags) {
-    frame_header_.RetainFlags(valid_flags);
-  }
-
-  // Clear all of the flags in the frame header; for use with frame types that
-  // don't define any flags, such as WINDOW_UPDATE.
-  void ClearFlags() { frame_header_.flags = Http2FrameFlag(); }
-
-  // Returns true if the type of frame being decoded can have padding.
-  bool IsPaddable() const {
-    return frame_header().type == Http2FrameType::DATA ||
-           frame_header().type == Http2FrameType::HEADERS ||
-           frame_header().type == Http2FrameType::PUSH_PROMISE;
-  }
-
-  Http2FrameDecoderListener* listener_ = nullptr;
-  Http2FrameHeader frame_header_;
-
-  // Number of bytes remaining to be decoded, if set; does not include the
-  // trailing padding once the length of padding has been determined.
-  // See ReadPadLength.
-  uint32_t remaining_payload_;
-
-  // The amount of trailing padding after the payload that remains to be
-  // decoded. See ReadPadLength.
-  uint32_t remaining_padding_;
-
-  // Generic decoder of structures, which takes care of buffering the needed
-  // bytes if the encoded structure is split across decode buffers.
-  Http2StructureDecoder structure_decoder_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
diff --git a/http2/decoder/frame_decoder_state_test_util.cc b/http2/decoder/frame_decoder_state_test_util.cc
deleted file mode 100644
index e95f657..0000000
--- a/http2/decoder/frame_decoder_state_test_util.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/frame_decoder_state_test_util.h"
-
-#include "http2/decoder/http2_structure_decoder_test_util.h"
-#include "http2/http2_structures.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_decoder_test.h"
-
-namespace http2 {
-namespace test {
-
-// static
-void FrameDecoderStatePeer::Randomize(FrameDecoderState* p, Http2Random* rng) {
-  HTTP2_VLOG(1) << "FrameDecoderStatePeer::Randomize";
-  ::http2::test::Randomize(&p->frame_header_, rng);
-  p->remaining_payload_ = rng->Rand32();
-  p->remaining_padding_ = rng->Rand32();
-  Http2StructureDecoderPeer::Randomize(&p->structure_decoder_, rng);
-}
-
-// static
-void FrameDecoderStatePeer::set_frame_header(const Http2FrameHeader& header,
-                                             FrameDecoderState* p) {
-  HTTP2_VLOG(1) << "FrameDecoderStatePeer::set_frame_header " << header;
-  p->frame_header_ = header;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/frame_decoder_state_test_util.h b/http2/decoder/frame_decoder_state_test_util.h
deleted file mode 100644
index 8955cb7..0000000
--- a/http2/decoder/frame_decoder_state_test_util.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_TEST_UTIL_H_
-#define QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_TEST_UTIL_H_
-
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "http2/tools/random_decoder_test.h"
-
-namespace http2 {
-namespace test {
-
-class FrameDecoderStatePeer {
- public:
-  // Randomizes (i.e. corrupts) the fields of the FrameDecoderState.
-  // PayloadDecoderBaseTest::StartDecoding calls this before passing the first
-  // decode buffer to the payload decoder, which increases the likelihood of
-  // detecting any use of prior states of the decoder on the decoding of
-  // future payloads.
-  static void Randomize(FrameDecoderState* p, Http2Random* rng);
-
-  // Inject a frame header into the FrameDecoderState.
-  // PayloadDecoderBaseTest::StartDecoding calls this just after calling
-  // Randomize (above), to simulate a full frame decoder having just finished
-  // decoding the common frame header and then calling the appropriate payload
-  // decoder based on the frame type in that frame header.
-  static void set_frame_header(const Http2FrameHeader& header,
-                               FrameDecoderState* p);
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_TEST_UTIL_H_
diff --git a/http2/decoder/http2_frame_decoder.cc b/http2/decoder/http2_frame_decoder.cc
deleted file mode 100644
index ec2034b..0000000
--- a/http2/decoder/http2_frame_decoder.cc
+++ /dev/null
@@ -1,460 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_frame_decoder.h"
-
-#include "http2/decoder/decode_status.h"
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_flags.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out, Http2FrameDecoder::State v) {
-  switch (v) {
-    case Http2FrameDecoder::State::kStartDecodingHeader:
-      return out << "kStartDecodingHeader";
-    case Http2FrameDecoder::State::kResumeDecodingHeader:
-      return out << "kResumeDecodingHeader";
-    case Http2FrameDecoder::State::kResumeDecodingPayload:
-      return out << "kResumeDecodingPayload";
-    case Http2FrameDecoder::State::kDiscardPayload:
-      return out << "kDiscardPayload";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_155_1) << "Http2FrameDecoder::State " << unknown;
-  return out << "Http2FrameDecoder::State(" << unknown << ")";
-}
-
-Http2FrameDecoder::Http2FrameDecoder(Http2FrameDecoderListener* listener)
-    : state_(State::kStartDecodingHeader),
-      maximum_payload_size_(Http2SettingsInfo::DefaultMaxFrameSize()) {
-  set_listener(listener);
-}
-
-void Http2FrameDecoder::set_listener(Http2FrameDecoderListener* listener) {
-  if (listener == nullptr) {
-    listener = &no_op_listener_;
-  }
-  frame_decoder_state_.set_listener(listener);
-}
-
-Http2FrameDecoderListener* Http2FrameDecoder::listener() const {
-  return frame_decoder_state_.listener();
-}
-
-DecodeStatus Http2FrameDecoder::DecodeFrame(DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "Http2FrameDecoder::DecodeFrame state=" << state_;
-  switch (state_) {
-    case State::kStartDecodingHeader:
-      if (frame_decoder_state_.StartDecodingFrameHeader(db)) {
-        return StartDecodingPayload(db);
-      }
-      state_ = State::kResumeDecodingHeader;
-      return DecodeStatus::kDecodeInProgress;
-
-    case State::kResumeDecodingHeader:
-      if (frame_decoder_state_.ResumeDecodingFrameHeader(db)) {
-        return StartDecodingPayload(db);
-      }
-      return DecodeStatus::kDecodeInProgress;
-
-    case State::kResumeDecodingPayload:
-      return ResumeDecodingPayload(db);
-
-    case State::kDiscardPayload:
-      return DiscardPayload(db);
-  }
-
-  QUICHE_NOTREACHED();
-  return DecodeStatus::kDecodeError;
-}
-
-size_t Http2FrameDecoder::remaining_payload() const {
-  return frame_decoder_state_.remaining_payload();
-}
-
-uint32_t Http2FrameDecoder::remaining_padding() const {
-  return frame_decoder_state_.remaining_padding();
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingPayload(DecodeBuffer* db) {
-  const Http2FrameHeader& header = frame_header();
-
-  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
-  // SpdyFramer's exact states.
-  if (!listener()->OnFrameHeader(header)) {
-    HTTP2_DVLOG(2) << "OnFrameHeader rejected the frame, will discard; header: "
-                   << header;
-    state_ = State::kDiscardPayload;
-    frame_decoder_state_.InitializeRemainders();
-    return DecodeStatus::kDecodeError;
-  }
-
-  if (header.payload_length > maximum_payload_size_) {
-    HTTP2_DVLOG(2) << "Payload length is greater than allowed: "
-                   << header.payload_length << " > " << maximum_payload_size_
-                   << "\n   header: " << header;
-    state_ = State::kDiscardPayload;
-    frame_decoder_state_.InitializeRemainders();
-    listener()->OnFrameSizeError(header);
-    return DecodeStatus::kDecodeError;
-  }
-
-  // The decode buffer can extend across many frames. Make sure that the
-  // buffer we pass to the start method that is specific to the frame type
-  // does not exend beyond this frame.
-  DecodeBufferSubset subset(db, header.payload_length);
-  DecodeStatus status;
-  switch (header.type) {
-    case Http2FrameType::DATA:
-      status = StartDecodingDataPayload(&subset);
-      break;
-
-    case Http2FrameType::HEADERS:
-      status = StartDecodingHeadersPayload(&subset);
-      break;
-
-    case Http2FrameType::PRIORITY:
-      status = StartDecodingPriorityPayload(&subset);
-      break;
-
-    case Http2FrameType::RST_STREAM:
-      status = StartDecodingRstStreamPayload(&subset);
-      break;
-
-    case Http2FrameType::SETTINGS:
-      status = StartDecodingSettingsPayload(&subset);
-      break;
-
-    case Http2FrameType::PUSH_PROMISE:
-      status = StartDecodingPushPromisePayload(&subset);
-      break;
-
-    case Http2FrameType::PING:
-      status = StartDecodingPingPayload(&subset);
-      break;
-
-    case Http2FrameType::GOAWAY:
-      status = StartDecodingGoAwayPayload(&subset);
-      break;
-
-    case Http2FrameType::WINDOW_UPDATE:
-      status = StartDecodingWindowUpdatePayload(&subset);
-      break;
-
-    case Http2FrameType::CONTINUATION:
-      status = StartDecodingContinuationPayload(&subset);
-      break;
-
-    case Http2FrameType::ALTSVC:
-      status = StartDecodingAltSvcPayload(&subset);
-      break;
-
-    case Http2FrameType::PRIORITY_UPDATE:
-      status = StartDecodingPriorityUpdatePayload(&subset);
-      break;
-
-    default:
-      status = StartDecodingUnknownPayload(&subset);
-      break;
-  }
-
-  if (status == DecodeStatus::kDecodeDone) {
-    state_ = State::kStartDecodingHeader;
-    return status;
-  } else if (status == DecodeStatus::kDecodeInProgress) {
-    state_ = State::kResumeDecodingPayload;
-    return status;
-  } else {
-    state_ = State::kDiscardPayload;
-    return status;
-  }
-}
-
-DecodeStatus Http2FrameDecoder::ResumeDecodingPayload(DecodeBuffer* db) {
-  // The decode buffer can extend across many frames. Make sure that the
-  // buffer we pass to the start method that is specific to the frame type
-  // does not exend beyond this frame.
-  size_t remaining = frame_decoder_state_.remaining_total_payload();
-  QUICHE_DCHECK_LE(remaining, frame_header().payload_length);
-  DecodeBufferSubset subset(db, remaining);
-  DecodeStatus status;
-  switch (frame_header().type) {
-    case Http2FrameType::DATA:
-      status = ResumeDecodingDataPayload(&subset);
-      break;
-
-    case Http2FrameType::HEADERS:
-      status = ResumeDecodingHeadersPayload(&subset);
-      break;
-
-    case Http2FrameType::PRIORITY:
-      status = ResumeDecodingPriorityPayload(&subset);
-      break;
-
-    case Http2FrameType::RST_STREAM:
-      status = ResumeDecodingRstStreamPayload(&subset);
-      break;
-
-    case Http2FrameType::SETTINGS:
-      status = ResumeDecodingSettingsPayload(&subset);
-      break;
-
-    case Http2FrameType::PUSH_PROMISE:
-      status = ResumeDecodingPushPromisePayload(&subset);
-      break;
-
-    case Http2FrameType::PING:
-      status = ResumeDecodingPingPayload(&subset);
-      break;
-
-    case Http2FrameType::GOAWAY:
-      status = ResumeDecodingGoAwayPayload(&subset);
-      break;
-
-    case Http2FrameType::WINDOW_UPDATE:
-      status = ResumeDecodingWindowUpdatePayload(&subset);
-      break;
-
-    case Http2FrameType::CONTINUATION:
-      status = ResumeDecodingContinuationPayload(&subset);
-      break;
-
-    case Http2FrameType::ALTSVC:
-      status = ResumeDecodingAltSvcPayload(&subset);
-      break;
-
-    case Http2FrameType::PRIORITY_UPDATE:
-      status = ResumeDecodingPriorityUpdatePayload(&subset);
-      break;
-
-    default:
-      status = ResumeDecodingUnknownPayload(&subset);
-      break;
-  }
-
-  if (status == DecodeStatus::kDecodeDone) {
-    state_ = State::kStartDecodingHeader;
-    return status;
-  } else if (status == DecodeStatus::kDecodeInProgress) {
-    return status;
-  } else {
-    state_ = State::kDiscardPayload;
-    return status;
-  }
-}
-
-// Clear any of the flags in the frame header that aren't set in valid_flags.
-void Http2FrameDecoder::RetainFlags(uint8_t valid_flags) {
-  frame_decoder_state_.RetainFlags(valid_flags);
-}
-
-// Clear all of the flags in the frame header; for use with frame types that
-// don't define any flags, such as WINDOW_UPDATE.
-void Http2FrameDecoder::ClearFlags() {
-  frame_decoder_state_.ClearFlags();
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingAltSvcPayload(DecodeBuffer* db) {
-  ClearFlags();
-  return altsvc_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                      db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingAltSvcPayload(DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return altsvc_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
-                                                       db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingContinuationPayload(
-    DecodeBuffer* db) {
-  RetainFlags(Http2FrameFlag::END_HEADERS);
-  return continuation_payload_decoder_.StartDecodingPayload(
-      &frame_decoder_state_, db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingContinuationPayload(
-    DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return continuation_payload_decoder_.ResumeDecodingPayload(
-      &frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingDataPayload(DecodeBuffer* db) {
-  RetainFlags(Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED);
-  return data_payload_decoder_.StartDecodingPayload(&frame_decoder_state_, db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingDataPayload(DecodeBuffer* db) {
-  return data_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingGoAwayPayload(DecodeBuffer* db) {
-  ClearFlags();
-  return goaway_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                      db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingGoAwayPayload(DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return goaway_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
-                                                       db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingHeadersPayload(DecodeBuffer* db) {
-  RetainFlags(Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS |
-              Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY);
-  return headers_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                       db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingHeadersPayload(DecodeBuffer* db) {
-  QUICHE_DCHECK_LE(frame_decoder_state_.remaining_payload_and_padding(),
-                   frame_header().payload_length);
-  return headers_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
-                                                        db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingPingPayload(DecodeBuffer* db) {
-  RetainFlags(Http2FrameFlag::ACK);
-  return ping_payload_decoder_.StartDecodingPayload(&frame_decoder_state_, db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingPingPayload(DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return ping_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingPriorityPayload(DecodeBuffer* db) {
-  ClearFlags();
-  return priority_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                        db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingPriorityPayload(
-    DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return priority_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
-                                                         db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingPriorityUpdatePayload(
-    DecodeBuffer* db) {
-  ClearFlags();
-  return priority_payload_update_decoder_.StartDecodingPayload(
-      &frame_decoder_state_, db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingPriorityUpdatePayload(
-    DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return priority_payload_update_decoder_.ResumeDecodingPayload(
-      &frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingPushPromisePayload(
-    DecodeBuffer* db) {
-  RetainFlags(Http2FrameFlag::END_HEADERS | Http2FrameFlag::PADDED);
-  return push_promise_payload_decoder_.StartDecodingPayload(
-      &frame_decoder_state_, db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingPushPromisePayload(
-    DecodeBuffer* db) {
-  QUICHE_DCHECK_LE(frame_decoder_state_.remaining_payload_and_padding(),
-                   frame_header().payload_length);
-  return push_promise_payload_decoder_.ResumeDecodingPayload(
-      &frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingRstStreamPayload(
-    DecodeBuffer* db) {
-  ClearFlags();
-  return rst_stream_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                          db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingRstStreamPayload(
-    DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return rst_stream_payload_decoder_.ResumeDecodingPayload(
-      &frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingSettingsPayload(DecodeBuffer* db) {
-  RetainFlags(Http2FrameFlag::ACK);
-  return settings_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                        db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingSettingsPayload(
-    DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return settings_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
-                                                         db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingUnknownPayload(DecodeBuffer* db) {
-  // We don't known what type of frame this is, so we don't know which flags
-  // are valid, so we don't touch them.
-  return unknown_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
-                                                       db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingUnknownPayload(DecodeBuffer* db) {
-  // We don't known what type of frame this is, so we treat it as not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return unknown_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
-                                                        db);
-}
-
-DecodeStatus Http2FrameDecoder::StartDecodingWindowUpdatePayload(
-    DecodeBuffer* db) {
-  ClearFlags();
-  return window_update_payload_decoder_.StartDecodingPayload(
-      &frame_decoder_state_, db);
-}
-DecodeStatus Http2FrameDecoder::ResumeDecodingWindowUpdatePayload(
-    DecodeBuffer* db) {
-  // The frame is not paddable.
-  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
-                   frame_decoder_state_.remaining_payload());
-  return window_update_payload_decoder_.ResumeDecodingPayload(
-      &frame_decoder_state_, db);
-}
-
-DecodeStatus Http2FrameDecoder::DiscardPayload(DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "remaining_payload="
-                 << frame_decoder_state_.remaining_payload_
-                 << "; remaining_padding="
-                 << frame_decoder_state_.remaining_padding_;
-  frame_decoder_state_.remaining_payload_ +=
-      frame_decoder_state_.remaining_padding_;
-  frame_decoder_state_.remaining_padding_ = 0;
-  const size_t avail = frame_decoder_state_.AvailablePayload(db);
-  HTTP2_DVLOG(2) << "avail=" << avail;
-  if (avail > 0) {
-    frame_decoder_state_.ConsumePayload(avail);
-    db->AdvanceCursor(avail);
-  }
-  if (frame_decoder_state_.remaining_payload_ == 0) {
-    state_ = State::kStartDecodingHeader;
-    return DecodeStatus::kDecodeDone;
-  }
-  return DecodeStatus::kDecodeInProgress;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/http2_frame_decoder.h b/http2/decoder/http2_frame_decoder.h
deleted file mode 100644
index b758dc8..0000000
--- a/http2/decoder/http2_frame_decoder.h
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_H_
-#define QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_H_
-
-// Http2FrameDecoder decodes the available input until it reaches the end of
-// the input or it reaches the end of the first frame in the input.
-// Note that Http2FrameDecoder does only minimal validation; for example,
-// stream ids are not checked, nor is the sequence of frames such as
-// CONTINUATION frame placement.
-//
-// Http2FrameDecoder enters state kError once it has called the listener's
-// OnFrameSizeError or OnPaddingTooLong methods, and at this time has no
-// provision for leaving that state. While the HTTP/2 spec (RFC7540) allows
-// for some such errors to be considered as just stream errors in some cases,
-// this implementation treats them all as connection errors.
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/altsvc_payload_decoder.h"
-#include "http2/decoder/payload_decoders/continuation_payload_decoder.h"
-#include "http2/decoder/payload_decoders/data_payload_decoder.h"
-#include "http2/decoder/payload_decoders/goaway_payload_decoder.h"
-#include "http2/decoder/payload_decoders/headers_payload_decoder.h"
-#include "http2/decoder/payload_decoders/ping_payload_decoder.h"
-#include "http2/decoder/payload_decoders/priority_payload_decoder.h"
-#include "http2/decoder/payload_decoders/priority_update_payload_decoder.h"
-#include "http2/decoder/payload_decoders/push_promise_payload_decoder.h"
-#include "http2/decoder/payload_decoders/rst_stream_payload_decoder.h"
-#include "http2/decoder/payload_decoders/settings_payload_decoder.h"
-#include "http2/decoder/payload_decoders/unknown_payload_decoder.h"
-#include "http2/decoder/payload_decoders/window_update_payload_decoder.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class Http2FrameDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE Http2FrameDecoder {
- public:
-  explicit Http2FrameDecoder(Http2FrameDecoderListener* listener);
-
-  Http2FrameDecoder(const Http2FrameDecoder&) = delete;
-  Http2FrameDecoder& operator=(const Http2FrameDecoder&) = delete;
-
-  // The decoder will call the listener's methods as it decodes a frame.
-  void set_listener(Http2FrameDecoderListener* listener);
-  Http2FrameDecoderListener* listener() const;
-
-  // The decoder will reject frame's whose payload
-  // length field exceeds the maximum payload size.
-  void set_maximum_payload_size(size_t v) { maximum_payload_size_ = v; }
-  size_t maximum_payload_size() const { return maximum_payload_size_; }
-
-  // Decodes the input up to the next frame boundary (i.e. at most one frame).
-  //
-  // Returns kDecodeDone if it decodes the final byte of a frame, OR if there
-  // is no input and it is awaiting the start of a new frame (e.g. if this
-  // is the first call to DecodeFrame, or if the previous call returned
-  // kDecodeDone).
-  //
-  // Returns kDecodeInProgress if it decodes all of the decode buffer, but has
-  // not reached the end of the frame.
-  //
-  // Returns kDecodeError if the frame's padding or length wasn't valid (i.e. if
-  // the decoder called either the listener's OnPaddingTooLong or
-  // OnFrameSizeError method).
-  //
-  // If the decode buffer contains the entirety of a frame payload or field,
-  // then the corresponding Http2FrameDecoderListener::On*Payload(),
-  // OnHpackFragment(), OnGoAwayOpaqueData(), or OnAltSvcValueData() method is
-  // guaranteed to be called exactly once, with the entire payload or field in a
-  // single chunk.
-  DecodeStatus DecodeFrame(DecodeBuffer* db);
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Methods that support Http2FrameDecoderAdapter.
-
-  // Is the remainder of the frame's payload being discarded?
-  bool IsDiscardingPayload() const { return state_ == State::kDiscardPayload; }
-
-  // Returns the number of bytes of the frame's payload that remain to be
-  // decoded, excluding any trailing padding. This method must only be called
-  // after the frame header has been decoded AND DecodeFrame has returned
-  // kDecodeInProgress.
-  size_t remaining_payload() const;
-
-  // Returns the number of bytes of trailing padding after the payload that
-  // remain to be decoded. This method must only be called if the frame type
-  // allows padding, and after the frame header has been decoded AND
-  // DecodeFrame has returned. Will return 0 if the Pad Length field has not
-  // yet been decoded.
-  uint32_t remaining_padding() const;
-
- private:
-  enum class State {
-    // Ready to start decoding a new frame's header.
-    kStartDecodingHeader,
-    // Was in state kStartDecodingHeader, but unable to read the entire frame
-    // header, so needs more input to complete decoding the header.
-    kResumeDecodingHeader,
-
-    // Have decoded the frame header, and started decoding the available bytes
-    // of the frame's payload, but need more bytes to finish the job.
-    kResumeDecodingPayload,
-
-    // Decoding of the most recently started frame resulted in an error:
-    // OnPaddingTooLong or OnFrameSizeError was called to indicate that the
-    // decoder detected a problem, or OnFrameHeader returned false, indicating
-    // that the listener detected a problem. Regardless of which, the decoder
-    // will stay in state kDiscardPayload until it has been passed the rest
-    // of the bytes of the frame's payload that it hasn't yet seen, after
-    // which it will be ready to decode another frame.
-    kDiscardPayload,
-  };
-
-  friend class test::Http2FrameDecoderPeer;
-  QUICHE_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& out,
-                                                        State v);
-
-  DecodeStatus StartDecodingPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingPayload(DecodeBuffer* db);
-  DecodeStatus DiscardPayload(DecodeBuffer* db);
-
-  const Http2FrameHeader& frame_header() const {
-    return frame_decoder_state_.frame_header();
-  }
-
-  // Clear any of the flags in the frame header that aren't set in valid_flags.
-  void RetainFlags(uint8_t valid_flags);
-
-  // Clear all of the flags in the frame header; for use with frame types that
-  // don't define any flags, such as WINDOW_UPDATE.
-  void ClearFlags();
-
-  // These methods call the StartDecodingPayload() method of the frame type's
-  // payload decoder, after first clearing invalid flags in the header. The
-  // caller must ensure that the decode buffer does not extend beyond the
-  // end of the payload (handled by Http2FrameDecoder::StartDecodingPayload).
-  DecodeStatus StartDecodingAltSvcPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingContinuationPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingDataPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingGoAwayPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingHeadersPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingPingPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingPriorityPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingPriorityUpdatePayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingPushPromisePayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingRstStreamPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingSettingsPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingUnknownPayload(DecodeBuffer* db);
-  DecodeStatus StartDecodingWindowUpdatePayload(DecodeBuffer* db);
-
-  // These methods call the ResumeDecodingPayload() method of the frame type's
-  // payload decoder; they are called only if the preceding call to the
-  // corresponding Start method (above) returned kDecodeInProgress, as did any
-  // subsequent calls to the resume method.
-  // Unlike the Start methods, the decode buffer may extend beyond the
-  // end of the payload, so the method will create a DecodeBufferSubset
-  // before calling the ResumeDecodingPayload method of the frame type's
-  // payload decoder.
-  DecodeStatus ResumeDecodingAltSvcPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingContinuationPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingDataPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingGoAwayPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingHeadersPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingPingPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingPriorityPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingPriorityUpdatePayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingPushPromisePayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingRstStreamPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingSettingsPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingUnknownPayload(DecodeBuffer* db);
-  DecodeStatus ResumeDecodingWindowUpdatePayload(DecodeBuffer* db);
-
-  FrameDecoderState frame_decoder_state_;
-
-  // We only need one payload decoder at a time, so they share the same storage.
-  union {
-    AltSvcPayloadDecoder altsvc_payload_decoder_;
-    ContinuationPayloadDecoder continuation_payload_decoder_;
-    DataPayloadDecoder data_payload_decoder_;
-    GoAwayPayloadDecoder goaway_payload_decoder_;
-    HeadersPayloadDecoder headers_payload_decoder_;
-    PingPayloadDecoder ping_payload_decoder_;
-    PriorityPayloadDecoder priority_payload_decoder_;
-    PriorityUpdatePayloadDecoder priority_payload_update_decoder_;
-    PushPromisePayloadDecoder push_promise_payload_decoder_;
-    RstStreamPayloadDecoder rst_stream_payload_decoder_;
-    SettingsPayloadDecoder settings_payload_decoder_;
-    UnknownPayloadDecoder unknown_payload_decoder_;
-    WindowUpdatePayloadDecoder window_update_payload_decoder_;
-  };
-
-  State state_;
-  size_t maximum_payload_size_;
-
-  // Listener used whenever caller passes nullptr to set_listener.
-  Http2FrameDecoderNoOpListener no_op_listener_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_H_
diff --git a/http2/decoder/http2_frame_decoder_listener.cc b/http2/decoder/http2_frame_decoder_listener.cc
deleted file mode 100644
index 452f059..0000000
--- a/http2/decoder/http2_frame_decoder_listener.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-
-namespace http2 {
-
-bool Http2FrameDecoderNoOpListener::OnFrameHeader(
-    const Http2FrameHeader& /*header*/) {
-  return true;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/http2_frame_decoder_listener.h b/http2/decoder/http2_frame_decoder_listener.h
deleted file mode 100644
index 9bb1688..0000000
--- a/http2/decoder/http2_frame_decoder_listener.h
+++ /dev/null
@@ -1,384 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_
-#define QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_
-
-// Http2FrameDecoderListener is the interface which the HTTP/2 decoder uses
-// to report the decoded frames to a listener.
-//
-// The general design is to assume that the listener will copy the data it needs
-// (e.g. frame headers) and will keep track of the implicit state of the
-// decoding process (i.e. the decoder maintains just the information it needs in
-// order to perform the decoding). Therefore, the parameters are just those with
-// (potentially) new data, not previously provided info about the current frame.
-//
-// The calls are described as if they are made in quick succession, i.e. one
-// after another, but of course the decoder needs input to decode, and the
-// decoder will only call the listener once the necessary input has been
-// provided. For example: OnDataStart can only be called once the 9 bytes of
-// of an HTTP/2 common frame header have been received. The decoder will call
-// the listener methods as soon as possible to avoid almost all buffering.
-//
-// The listener interface is designed so that it is possible to exactly
-// reconstruct the serialized frames, with the exception of reserved bits,
-// including in the frame header's flags and stream_id fields, which will have
-// been cleared before the methods below are called.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <type_traits>
-
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-
-namespace http2 {
-
-// TODO(jamessynge): Consider sorting the methods by frequency of call, if that
-// helps at all.
-class Http2FrameDecoderListener {
- public:
-  Http2FrameDecoderListener() {}
-  virtual ~Http2FrameDecoderListener() {}
-
-  // Called once the common frame header has been decoded for any frame, and
-  // before any of the methods below, which will also be called. This method is
-  // included in this interface only for the purpose of supporting SpdyFramer
-  // semantics via an adapter. This is the only method that has a non-void
-  // return type, and this is just so that Http2FrameDecoderAdapter (called
-  // from SpdyFramer) can more readily pass existing tests that expect decoding
-  // to stop if the headers alone indicate an error. Return false to stop
-  // decoding just after decoding the header, else return true to continue
-  // decoding.
-  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
-  // SpdyFramer's exact states.
-  virtual bool OnFrameHeader(const Http2FrameHeader& header) = 0;
-
-  //////////////////////////////////////////////////////////////////////////////
-
-  // Called once the common frame header has been decoded for a DATA frame,
-  // before examining the frame's payload, after which:
-  //   OnPadLength will be called if header.IsPadded() is true, i.e. if the
-  //     PADDED flag is set;
-  //   OnDataPayload will be called as the non-padding portion of the payload
-  //     is available until all of it has been provided;
-  //   OnPadding will be called if the frame is padded AND the Pad Length field
-  //     is greater than zero;
-  //   OnDataEnd will be called last. If the frame is unpadded and has no
-  //     payload, then this will be called immediately after OnDataStart.
-  virtual void OnDataStart(const Http2FrameHeader& header) = 0;
-
-  // Called when the next non-padding portion of a DATA frame's payload is
-  // received.
-  // |data| The start of |len| bytes of data.
-  // |len| The length of the data buffer. Maybe zero in some cases, which does
-  //       not mean anything special.
-  virtual void OnDataPayload(const char* data, size_t len) = 0;
-
-  // Called after an entire DATA frame has been received.
-  // If header.IsEndStream() == true, this is the last data for the stream.
-  virtual void OnDataEnd() = 0;
-
-  // Called once the common frame header has been decoded for a HEADERS frame,
-  // before examining the frame's payload, after which:
-  //   OnPadLength will be called if header.IsPadded() is true, i.e. if the
-  //     PADDED flag is set;
-  //   OnHeadersPriority will be called if header.HasPriority() is true, i.e. if
-  //     the frame has the PRIORITY flag;
-  //   OnHpackFragment as the remainder of the non-padding payload is available
-  //     until all if has been provided;
-  //   OnPadding will be called if the frame is padded AND the Pad Length field
-  //     is greater than zero;
-  //   OnHeadersEnd will be called last; If the frame is unpadded and has no
-  //     payload, then this will be called immediately after OnHeadersStart;
-  //     OnHeadersEnd indicates the end of the HPACK block only if the frame
-  //     header had the END_HEADERS flag set, else the END_HEADERS should be
-  //     looked for on a subsequent CONTINUATION frame.
-  virtual void OnHeadersStart(const Http2FrameHeader& header) = 0;
-
-  // Called when a HEADERS frame is received with the PRIORITY flag set and
-  // the priority fields have been decoded.
-  virtual void OnHeadersPriority(
-      const Http2PriorityFields& priority_fields) = 0;
-
-  // Called when a fragment (i.e. some or all of an HPACK Block) is received;
-  // this may be part of a HEADERS, PUSH_PROMISE or CONTINUATION frame.
-  // |data| The start of |len| bytes of data.
-  // |len| The length of the data buffer. Maybe zero in some cases, which does
-  //       not mean anything special, except that it simplified the decoder.
-  virtual void OnHpackFragment(const char* data, size_t len) = 0;
-
-  // Called after an entire HEADERS frame has been received. The frame is the
-  // end of the HEADERS if the END_HEADERS flag is set; else there should be
-  // CONTINUATION frames after this frame.
-  virtual void OnHeadersEnd() = 0;
-
-  // Called when an entire PRIORITY frame has been decoded.
-  virtual void OnPriorityFrame(const Http2FrameHeader& header,
-                               const Http2PriorityFields& priority_fields) = 0;
-
-  // Called once the common frame header has been decoded for a CONTINUATION
-  // frame, before examining the frame's payload, after which:
-  //   OnHpackFragment as the frame's payload is available until all of it
-  //     has been provided;
-  //   OnContinuationEnd will be called last; If the frame has no payload,
-  //     then this will be called immediately after OnContinuationStart;
-  //     the HPACK block is at an end if and only if the frame header passed
-  //     to OnContinuationStart had the END_HEADERS flag set.
-  virtual void OnContinuationStart(const Http2FrameHeader& header) = 0;
-
-  // Called after an entire CONTINUATION frame has been received. The frame is
-  // the end of the HEADERS if the END_HEADERS flag is set.
-  virtual void OnContinuationEnd() = 0;
-
-  // Called when Pad Length field has been read. Applies to DATA and HEADERS
-  // frames. For PUSH_PROMISE frames, the Pad Length + 1 is provided in the
-  // OnPushPromiseStart call as total_padding_length.
-  virtual void OnPadLength(size_t pad_length) = 0;
-
-  // Called when padding is skipped over.
-  virtual void OnPadding(const char* padding, size_t skipped_length) = 0;
-
-  // Called when an entire RST_STREAM frame has been decoded.
-  // This is the only callback for RST_STREAM frames.
-  virtual void OnRstStream(const Http2FrameHeader& header,
-                           Http2ErrorCode error_code) = 0;
-
-  // Called once the common frame header has been decoded for a SETTINGS frame
-  // without the ACK flag, before examining the frame's payload, after which:
-  //   OnSetting will be called in turn for each pair of settings parameter and
-  //     value found in the payload;
-  //   OnSettingsEnd will be called last; If the frame has no payload,
-  //     then this will be called immediately after OnSettingsStart.
-  // The frame header is passed so that the caller can check the stream_id,
-  // which should be zero, but that hasn't been checked by the decoder.
-  virtual void OnSettingsStart(const Http2FrameHeader& header) = 0;
-
-  // Called for each setting parameter and value within a SETTINGS frame.
-  virtual void OnSetting(const Http2SettingFields& setting_fields) = 0;
-
-  // Called after parsing the complete payload of SETTINGS frame (non-ACK).
-  virtual void OnSettingsEnd() = 0;
-
-  // Called when an entire SETTINGS frame, with the ACK flag, has been decoded.
-  virtual void OnSettingsAck(const Http2FrameHeader& header) = 0;
-
-  // Called just before starting to process the HPACK block of a PUSH_PROMISE
-  // frame. The Pad Length field has already been decoded at this point, so
-  // OnPadLength will not be called; note that total_padding_length is Pad
-  // Length + 1. After OnPushPromiseStart:
-  //   OnHpackFragment as the remainder of the non-padding payload is available
-  //     until all if has been provided;
-  //   OnPadding will be called if the frame is padded AND the Pad Length field
-  //     is greater than zero (i.e. total_padding_length > 1);
-  //   OnPushPromiseEnd will be called last; If the frame is unpadded and has no
-  //     payload, then this will be called immediately after OnPushPromiseStart.
-  virtual void OnPushPromiseStart(const Http2FrameHeader& header,
-                                  const Http2PushPromiseFields& promise,
-                                  size_t total_padding_length) = 0;
-
-  // Called after all of the HPACK block fragment and padding of a PUSH_PROMISE
-  // has been decoded and delivered to the listener. This call indicates the end
-  // of the HPACK block if and only if the frame header had the END_HEADERS flag
-  // set (i.e. header.IsEndHeaders() is true); otherwise the next block must be
-  // a CONTINUATION frame with the same stream id (not the same promised stream
-  // id).
-  virtual void OnPushPromiseEnd() = 0;
-
-  // Called when an entire PING frame, without the ACK flag, has been decoded.
-  virtual void OnPing(const Http2FrameHeader& header,
-                      const Http2PingFields& ping) = 0;
-
-  // Called when an entire PING frame, with the ACK flag, has been decoded.
-  virtual void OnPingAck(const Http2FrameHeader& header,
-                         const Http2PingFields& ping) = 0;
-
-  // Called after parsing a GOAWAY frame's header and fixed size fields, after
-  // which:
-  //   OnGoAwayOpaqueData will be called as opaque data of the payload becomes
-  //     available to the decoder, until all of it has been provided to the
-  //     listener;
-  //   OnGoAwayEnd will be called last, after all the opaque data has been
-  //     provided to the listener; if there is no opaque data, then OnGoAwayEnd
-  //     will be called immediately after OnGoAwayStart.
-  virtual void OnGoAwayStart(const Http2FrameHeader& header,
-                             const Http2GoAwayFields& goaway) = 0;
-
-  // Called when the next portion of a GOAWAY frame's payload is received.
-  // |data| The start of |len| bytes of opaque data.
-  // |len| The length of the opaque data buffer. Maybe zero in some cases,
-  //       which does not mean anything special.
-  virtual void OnGoAwayOpaqueData(const char* data, size_t len) = 0;
-
-  // Called after finishing decoding all of a GOAWAY frame.
-  virtual void OnGoAwayEnd() = 0;
-
-  // Called when an entire WINDOW_UPDATE frame has been decoded. The
-  // window_size_increment is required to be non-zero, but that has not been
-  // checked. If header.stream_id==0, the connection's flow control window is
-  // being increased, else the specified stream's flow control is being
-  // increased.
-  virtual void OnWindowUpdate(const Http2FrameHeader& header,
-                              uint32_t window_size_increment) = 0;
-
-  // Called when an ALTSVC frame header and origin length have been parsed.
-  // Either or both lengths may be zero. After OnAltSvcStart:
-  //   OnAltSvcOriginData will be called until all of the (optional) Origin
-  //     has been provided;
-  //   OnAltSvcValueData will be called until all of the Alt-Svc-Field-Value
-  //     has been provided;
-  //   OnAltSvcEnd will called last, after all of the origin and
-  //     Alt-Svc-Field-Value have been delivered to the listener.
-  virtual void OnAltSvcStart(const Http2FrameHeader& header,
-                             size_t origin_length,
-                             size_t value_length) = 0;
-
-  // Called when decoding the (optional) origin of an ALTSVC;
-  // the field is uninterpreted.
-  virtual void OnAltSvcOriginData(const char* data, size_t len) = 0;
-
-  // Called when decoding the Alt-Svc-Field-Value of an ALTSVC;
-  // the field is uninterpreted.
-  virtual void OnAltSvcValueData(const char* data, size_t len) = 0;
-
-  // Called after decoding all of a ALTSVC frame and providing to the listener
-  // via the above methods.
-  virtual void OnAltSvcEnd() = 0;
-
-  // Called when an PRIORITY_UPDATE frame header and Prioritized Stream ID have
-  // been parsed.  Afterwards:
-  //   OnPriorityUpdatePayload will be called each time a portion of the
-  //     Priority Field Value field is available until all of it has been
-  //     provided;
-  //   OnPriorityUpdateEnd will be called last. If the frame has an empty
-  //     Priority Field Value, then this will be called immediately after
-  //     OnPriorityUpdateStart.
-  virtual void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) = 0;
-
-  // Called when the next portion of a PRIORITY_UPDATE frame's Priority Field
-  // Value field is received.
-  // |data| The start of |len| bytes of data.
-  // |len| The length of the data buffer. May be zero in some cases, which does
-  //     not mean anything special.
-  virtual void OnPriorityUpdatePayload(const char* data, size_t len) = 0;
-
-  // Called after an entire PRIORITY_UPDATE frame has been received.
-  virtual void OnPriorityUpdateEnd() = 0;
-
-  // Called when the common frame header has been decoded, but the frame type
-  // is unknown, after which:
-  //   OnUnknownPayload is called as the payload of the frame is provided to the
-  //     decoder, until all of the payload has been decoded;
-  //   OnUnknownEnd will called last, after the entire frame of the unknown type
-  //     has been decoded and provided to the listener.
-  virtual void OnUnknownStart(const Http2FrameHeader& header) = 0;
-
-  // Called when the payload of an unknown frame type is received.
-  // |data| A buffer containing the data received.
-  // |len| The length of the data buffer.
-  virtual void OnUnknownPayload(const char* data, size_t len) = 0;
-
-  // Called after decoding all of the payload of an unknown frame type.
-  virtual void OnUnknownEnd() = 0;
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Below here are events indicating a problem has been detected during
-  // decoding (i.e. the received frames are malformed in some way).
-
-  // Padding field (uint8) has a value that is too large (i.e. the amount of
-  // padding is greater than the remainder of the payload that isn't required).
-  // From RFC Section 6.1, DATA:
-  //     If the length of the padding is the length of the frame payload or
-  //     greater, the recipient MUST treat this as a connection error
-  //     (Section 5.4.1) of type PROTOCOL_ERROR.
-  // The same is true for HEADERS and PUSH_PROMISE.
-  virtual void OnPaddingTooLong(const Http2FrameHeader& header,
-                                size_t missing_length) = 0;
-
-  // Frame size error. Depending upon the effected frame, this may or may not
-  // require terminating the connection, though that is probably the best thing
-  // to do.
-  // From RFC Section 4.2, Frame Size:
-  //     An endpoint MUST send an error code of FRAME_SIZE_ERROR if a frame
-  //     exceeds the size defined in SETTINGS_MAX_FRAME_SIZE, exceeds any limit
-  //     defined for the frame type, or is too small to contain mandatory frame
-  //     data. A frame size error in a frame that could alter the state of the
-  //     the entire connection MUST be treated as a connection error
-  //     (Section 5.4.1); this includes any frame carrying a header block
-  //     (Section 4.3) (that is, HEADERS, PUSH_PROMISE, and CONTINUATION),
-  //     SETTINGS, and any frame with a stream identifier of 0.
-  virtual void OnFrameSizeError(const Http2FrameHeader& header) = 0;
-};
-
-// Do nothing for each call. Useful for ignoring a frame that is invalid.
-class Http2FrameDecoderNoOpListener : public Http2FrameDecoderListener {
- public:
-  Http2FrameDecoderNoOpListener() {}
-  ~Http2FrameDecoderNoOpListener() override {}
-
-  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
-  // SpdyFramer's exact states.
-  bool OnFrameHeader(const Http2FrameHeader& header) override;
-
-  void OnDataStart(const Http2FrameHeader& /*header*/) override {}
-  void OnDataPayload(const char* /*data*/, size_t /*len*/) override {}
-  void OnDataEnd() override {}
-  void OnHeadersStart(const Http2FrameHeader& /*header*/) override {}
-  void OnHeadersPriority(const Http2PriorityFields& /*priority*/) override {}
-  void OnHpackFragment(const char* /*data*/, size_t /*len*/) override {}
-  void OnHeadersEnd() override {}
-  void OnPriorityFrame(const Http2FrameHeader& /*header*/,
-                       const Http2PriorityFields& /*priority*/) override {}
-  void OnContinuationStart(const Http2FrameHeader& /*header*/) override {}
-  void OnContinuationEnd() override {}
-  void OnPadLength(size_t /*trailing_length*/) override {}
-  void OnPadding(const char* /*padding*/, size_t /*skipped_length*/) override {}
-  void OnRstStream(const Http2FrameHeader& /*header*/,
-                   Http2ErrorCode /*error_code*/) override {}
-  void OnSettingsStart(const Http2FrameHeader& /*header*/) override {}
-  void OnSetting(const Http2SettingFields& /*setting_fields*/) override {}
-  void OnSettingsEnd() override {}
-  void OnSettingsAck(const Http2FrameHeader& /*header*/) override {}
-  void OnPushPromiseStart(const Http2FrameHeader& /*header*/,
-                          const Http2PushPromiseFields& /*promise*/,
-                          size_t /*total_padding_length*/) override {}
-  void OnPushPromiseEnd() override {}
-  void OnPing(const Http2FrameHeader& /*header*/,
-              const Http2PingFields& /*ping*/) override {}
-  void OnPingAck(const Http2FrameHeader& /*header*/,
-                 const Http2PingFields& /*ping*/) override {}
-  void OnGoAwayStart(const Http2FrameHeader& /*header*/,
-                     const Http2GoAwayFields& /*goaway*/) override {}
-  void OnGoAwayOpaqueData(const char* /*data*/, size_t /*len*/) override {}
-  void OnGoAwayEnd() override {}
-  void OnWindowUpdate(const Http2FrameHeader& /*header*/,
-                      uint32_t /*increment*/) override {}
-  void OnAltSvcStart(const Http2FrameHeader& /*header*/,
-                     size_t /*origin_length*/,
-                     size_t /*value_length*/) override {}
-  void OnAltSvcOriginData(const char* /*data*/, size_t /*len*/) override {}
-  void OnAltSvcValueData(const char* /*data*/, size_t /*len*/) override {}
-  void OnAltSvcEnd() override {}
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& /*header*/,
-      const Http2PriorityUpdateFields& /*priority_update*/) override {}
-  void OnPriorityUpdatePayload(const char* /*data*/, size_t /*len*/) override {}
-  void OnPriorityUpdateEnd() override {}
-  void OnUnknownStart(const Http2FrameHeader& /*header*/) override {}
-  void OnUnknownPayload(const char* /*data*/, size_t /*len*/) override {}
-  void OnUnknownEnd() override {}
-  void OnPaddingTooLong(const Http2FrameHeader& /*header*/,
-                        size_t /*missing_length*/) override {}
-  void OnFrameSizeError(const Http2FrameHeader& /*header*/) override {}
-};
-
-static_assert(!std::is_abstract<Http2FrameDecoderNoOpListener>(),
-              "Http2FrameDecoderNoOpListener ought to be concrete.");
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_
diff --git a/http2/decoder/http2_frame_decoder_listener_test_util.cc b/http2/decoder/http2_frame_decoder_listener_test_util.cc
deleted file mode 100644
index ddd0064..0000000
--- a/http2/decoder/http2_frame_decoder_listener_test_util.cc
+++ /dev/null
@@ -1,530 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_frame_decoder_listener_test_util.h"
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-
-FailingHttp2FrameDecoderListener::FailingHttp2FrameDecoderListener() = default;
-FailingHttp2FrameDecoderListener::~FailingHttp2FrameDecoderListener() = default;
-
-bool FailingHttp2FrameDecoderListener::OnFrameHeader(
-    const Http2FrameHeader& header) {
-  ADD_FAILURE() << "OnFrameHeader: " << header;
-  return false;
-}
-
-void FailingHttp2FrameDecoderListener::OnDataStart(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnDataStart: " << header;
-}
-
-void FailingHttp2FrameDecoderListener::OnDataPayload(const char* /*data*/,
-                                                     size_t len) {
-  FAIL() << "OnDataPayload: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnDataEnd() {
-  FAIL() << "OnDataEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnHeadersStart(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnHeadersStart: " << header;
-}
-
-void FailingHttp2FrameDecoderListener::OnHeadersPriority(
-    const Http2PriorityFields& priority) {
-  FAIL() << "OnHeadersPriority: " << priority;
-}
-
-void FailingHttp2FrameDecoderListener::OnHpackFragment(const char* /*data*/,
-                                                       size_t len) {
-  FAIL() << "OnHpackFragment: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnHeadersEnd() {
-  FAIL() << "OnHeadersEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnPriorityFrame(
-    const Http2FrameHeader& header,
-    const Http2PriorityFields& priority) {
-  FAIL() << "OnPriorityFrame: " << header << "; priority: " << priority;
-}
-
-void FailingHttp2FrameDecoderListener::OnContinuationStart(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnContinuationStart: " << header;
-}
-
-void FailingHttp2FrameDecoderListener::OnContinuationEnd() {
-  FAIL() << "OnContinuationEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnPadLength(size_t trailing_length) {
-  FAIL() << "OnPadLength: trailing_length=" << trailing_length;
-}
-
-void FailingHttp2FrameDecoderListener::OnPadding(const char* /*padding*/,
-                                                 size_t skipped_length) {
-  FAIL() << "OnPadding: skipped_length=" << skipped_length;
-}
-
-void FailingHttp2FrameDecoderListener::OnRstStream(
-    const Http2FrameHeader& header,
-    Http2ErrorCode error_code) {
-  FAIL() << "OnRstStream: " << header << "; code=" << error_code;
-}
-
-void FailingHttp2FrameDecoderListener::OnSettingsStart(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnSettingsStart: " << header;
-}
-
-void FailingHttp2FrameDecoderListener::OnSetting(
-    const Http2SettingFields& setting_fields) {
-  FAIL() << "OnSetting: " << setting_fields;
-}
-
-void FailingHttp2FrameDecoderListener::OnSettingsEnd() {
-  FAIL() << "OnSettingsEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnSettingsAck(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnSettingsAck: " << header;
-}
-
-void FailingHttp2FrameDecoderListener::OnPushPromiseStart(
-    const Http2FrameHeader& header,
-    const Http2PushPromiseFields& promise,
-    size_t total_padding_length) {
-  FAIL() << "OnPushPromiseStart: " << header << "; promise: " << promise
-         << "; total_padding_length: " << total_padding_length;
-}
-
-void FailingHttp2FrameDecoderListener::OnPushPromiseEnd() {
-  FAIL() << "OnPushPromiseEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnPing(const Http2FrameHeader& header,
-                                              const Http2PingFields& ping) {
-  FAIL() << "OnPing: " << header << "; ping: " << ping;
-}
-
-void FailingHttp2FrameDecoderListener::OnPingAck(const Http2FrameHeader& header,
-                                                 const Http2PingFields& ping) {
-  FAIL() << "OnPingAck: " << header << "; ping: " << ping;
-}
-
-void FailingHttp2FrameDecoderListener::OnGoAwayStart(
-    const Http2FrameHeader& header,
-    const Http2GoAwayFields& goaway) {
-  FAIL() << "OnGoAwayStart: " << header << "; goaway: " << goaway;
-}
-
-void FailingHttp2FrameDecoderListener::OnGoAwayOpaqueData(const char* /*data*/,
-                                                          size_t len) {
-  FAIL() << "OnGoAwayOpaqueData: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnGoAwayEnd() {
-  FAIL() << "OnGoAwayEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnWindowUpdate(
-    const Http2FrameHeader& header,
-    uint32_t increment) {
-  FAIL() << "OnWindowUpdate: " << header << "; increment=" << increment;
-}
-
-void FailingHttp2FrameDecoderListener::OnAltSvcStart(
-    const Http2FrameHeader& header,
-    size_t origin_length,
-    size_t value_length) {
-  FAIL() << "OnAltSvcStart: " << header << "; origin_length: " << origin_length
-         << "; value_length: " << value_length;
-}
-
-void FailingHttp2FrameDecoderListener::OnAltSvcOriginData(const char* /*data*/,
-                                                          size_t len) {
-  FAIL() << "OnAltSvcOriginData: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnAltSvcValueData(const char* /*data*/,
-                                                         size_t len) {
-  FAIL() << "OnAltSvcValueData: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnAltSvcEnd() {
-  FAIL() << "OnAltSvcEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnPriorityUpdateStart(
-    const Http2FrameHeader& header,
-    const Http2PriorityUpdateFields& priority_update) {
-  FAIL() << "OnPriorityUpdateStart: " << header << "; prioritized_stream_id: "
-         << priority_update.prioritized_stream_id;
-}
-
-void FailingHttp2FrameDecoderListener::OnPriorityUpdatePayload(
-    const char* /*data*/,
-    size_t len) {
-  FAIL() << "OnPriorityUpdatePayload: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnPriorityUpdateEnd() {
-  FAIL() << "OnPriorityUpdateEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnUnknownStart(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnUnknownStart: " << header;
-}
-
-void FailingHttp2FrameDecoderListener::OnUnknownPayload(const char* /*data*/,
-                                                        size_t len) {
-  FAIL() << "OnUnknownPayload: len=" << len;
-}
-
-void FailingHttp2FrameDecoderListener::OnUnknownEnd() {
-  FAIL() << "OnUnknownEnd";
-}
-
-void FailingHttp2FrameDecoderListener::OnPaddingTooLong(
-    const Http2FrameHeader& header,
-    size_t missing_length) {
-  FAIL() << "OnPaddingTooLong: " << header
-         << "; missing_length: " << missing_length;
-}
-
-void FailingHttp2FrameDecoderListener::OnFrameSizeError(
-    const Http2FrameHeader& header) {
-  FAIL() << "OnFrameSizeError: " << header;
-}
-
-LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener()
-    : wrapped_(nullptr) {}
-LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener(
-    Http2FrameDecoderListener* wrapped)
-    : wrapped_(wrapped) {}
-LoggingHttp2FrameDecoderListener::~LoggingHttp2FrameDecoderListener() = default;
-
-bool LoggingHttp2FrameDecoderListener::OnFrameHeader(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnFrameHeader: " << header;
-  if (wrapped_ != nullptr) {
-    return wrapped_->OnFrameHeader(header);
-  }
-  return true;
-}
-
-void LoggingHttp2FrameDecoderListener::OnDataStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnDataStart: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnDataStart(header);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnDataPayload(const char* data,
-                                                     size_t len) {
-  HTTP2_VLOG(1) << "OnDataPayload: len=" << len;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnDataPayload(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnDataEnd() {
-  HTTP2_VLOG(1) << "OnDataEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnDataEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnHeadersStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHeadersStart(header);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnHeadersPriority(
-    const Http2PriorityFields& priority) {
-  HTTP2_VLOG(1) << "OnHeadersPriority: " << priority;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHeadersPriority(priority);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnHpackFragment(const char* data,
-                                                       size_t len) {
-  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHpackFragment(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnHeadersEnd() {
-  HTTP2_VLOG(1) << "OnHeadersEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHeadersEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPriorityFrame(
-    const Http2FrameHeader& header,
-    const Http2PriorityFields& priority) {
-  HTTP2_VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPriorityFrame(header, priority);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnContinuationStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnContinuationStart(header);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnContinuationEnd() {
-  HTTP2_VLOG(1) << "OnContinuationEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnContinuationEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPadLength(size_t trailing_length) {
-  HTTP2_VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPadLength(trailing_length);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPadding(const char* padding,
-                                                 size_t skipped_length) {
-  HTTP2_VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPadding(padding, skipped_length);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnRstStream(
-    const Http2FrameHeader& header,
-    Http2ErrorCode error_code) {
-  HTTP2_VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnRstStream(header, error_code);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnSettingsStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnSettingsStart(header);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnSetting(
-    const Http2SettingFields& setting_fields) {
-  HTTP2_VLOG(1) << "OnSetting: " << setting_fields;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnSetting(setting_fields);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnSettingsEnd() {
-  HTTP2_VLOG(1) << "OnSettingsEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnSettingsEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnSettingsAck(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnSettingsAck(header);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPushPromiseStart(
-    const Http2FrameHeader& header,
-    const Http2PushPromiseFields& promise,
-    size_t total_padding_length) {
-  HTTP2_VLOG(1) << "OnPushPromiseStart: " << header << "; promise: " << promise
-                << "; total_padding_length: " << total_padding_length;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPushPromiseStart(header, promise, total_padding_length);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPushPromiseEnd() {
-  HTTP2_VLOG(1) << "OnPushPromiseEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPushPromiseEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPing(const Http2FrameHeader& header,
-                                              const Http2PingFields& ping) {
-  HTTP2_VLOG(1) << "OnPing: " << header << "; ping: " << ping;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPing(header, ping);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPingAck(const Http2FrameHeader& header,
-                                                 const Http2PingFields& ping) {
-  HTTP2_VLOG(1) << "OnPingAck: " << header << "; ping: " << ping;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPingAck(header, ping);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnGoAwayStart(
-    const Http2FrameHeader& header,
-    const Http2GoAwayFields& goaway) {
-  HTTP2_VLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnGoAwayStart(header, goaway);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnGoAwayOpaqueData(const char* data,
-                                                          size_t len) {
-  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnGoAwayOpaqueData(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnGoAwayEnd() {
-  HTTP2_VLOG(1) << "OnGoAwayEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnGoAwayEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnWindowUpdate(
-    const Http2FrameHeader& header,
-    uint32_t increment) {
-  HTTP2_VLOG(1) << "OnWindowUpdate: " << header << "; increment=" << increment;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnWindowUpdate(header, increment);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnAltSvcStart(
-    const Http2FrameHeader& header,
-    size_t origin_length,
-    size_t value_length) {
-  HTTP2_VLOG(1) << "OnAltSvcStart: " << header
-                << "; origin_length: " << origin_length
-                << "; value_length: " << value_length;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnAltSvcStart(header, origin_length, value_length);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnAltSvcOriginData(const char* data,
-                                                          size_t len) {
-  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnAltSvcOriginData(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnAltSvcValueData(const char* data,
-                                                         size_t len) {
-  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnAltSvcValueData(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnAltSvcEnd() {
-  HTTP2_VLOG(1) << "OnAltSvcEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnAltSvcEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPriorityUpdateStart(
-    const Http2FrameHeader& header,
-    const Http2PriorityUpdateFields& priority_update) {
-  HTTP2_VLOG(1) << "OnPriorityUpdateStart";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPriorityUpdateStart(header, priority_update);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPriorityUpdatePayload(const char* data,
-                                                               size_t len) {
-  HTTP2_VLOG(1) << "OnPriorityUpdatePayload";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPriorityUpdatePayload(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPriorityUpdateEnd() {
-  HTTP2_VLOG(1) << "OnPriorityUpdateEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPriorityUpdateEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnUnknownStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnUnknownStart(header);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnUnknownPayload(const char* data,
-                                                        size_t len) {
-  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnUnknownPayload(data, len);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnUnknownEnd() {
-  HTTP2_VLOG(1) << "OnUnknownEnd";
-  if (wrapped_ != nullptr) {
-    wrapped_->OnUnknownEnd();
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnPaddingTooLong(
-    const Http2FrameHeader& header,
-    size_t missing_length) {
-  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
-                << "; missing_length: " << missing_length;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnPaddingTooLong(header, missing_length);
-  }
-}
-
-void LoggingHttp2FrameDecoderListener::OnFrameSizeError(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnFrameSizeError(header);
-  }
-}
-
-}  // namespace http2
diff --git a/http2/decoder/http2_frame_decoder_listener_test_util.h b/http2/decoder/http2_frame_decoder_listener_test_util.h
deleted file mode 100644
index e748327..0000000
--- a/http2/decoder/http2_frame_decoder_listener_test_util.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_TEST_UTIL_H_
-#define QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_TEST_UTIL_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-
-namespace http2 {
-
-// Fail if any of the methods are called. Allows a test to override only the
-// expected calls.
-class FailingHttp2FrameDecoderListener : public Http2FrameDecoderListener {
- public:
-  FailingHttp2FrameDecoderListener();
-  ~FailingHttp2FrameDecoderListener() override;
-
-  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
-  // SpdyFramer's exact states.
-  bool OnFrameHeader(const Http2FrameHeader& header) override;
-  void OnDataStart(const Http2FrameHeader& header) override;
-  void OnDataPayload(const char* data, size_t len) override;
-  void OnDataEnd() override;
-  void OnHeadersStart(const Http2FrameHeader& header) override;
-  void OnHeadersPriority(const Http2PriorityFields& priority) override;
-  void OnHpackFragment(const char* data, size_t len) override;
-  void OnHeadersEnd() override;
-  void OnPriorityFrame(const Http2FrameHeader& header,
-                       const Http2PriorityFields& priority) override;
-  void OnContinuationStart(const Http2FrameHeader& header) override;
-  void OnContinuationEnd() override;
-  void OnPadLength(size_t trailing_length) override;
-  void OnPadding(const char* padding, size_t skipped_length) override;
-  void OnRstStream(const Http2FrameHeader& header,
-                   Http2ErrorCode error_code) override;
-  void OnSettingsStart(const Http2FrameHeader& header) override;
-  void OnSetting(const Http2SettingFields& setting_fields) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck(const Http2FrameHeader& header) override;
-  void OnPushPromiseStart(const Http2FrameHeader& header,
-                          const Http2PushPromiseFields& promise,
-                          size_t total_padding_length) override;
-  void OnPushPromiseEnd() override;
-  void OnPing(const Http2FrameHeader& header,
-              const Http2PingFields& ping) override;
-  void OnPingAck(const Http2FrameHeader& header,
-                 const Http2PingFields& ping) override;
-  void OnGoAwayStart(const Http2FrameHeader& header,
-                     const Http2GoAwayFields& goaway) override;
-  void OnGoAwayOpaqueData(const char* data, size_t len) override;
-  void OnGoAwayEnd() override;
-  void OnWindowUpdate(const Http2FrameHeader& header,
-                      uint32_t increment) override;
-  void OnAltSvcStart(const Http2FrameHeader& header,
-                     size_t origin_length,
-                     size_t value_length) override;
-  void OnAltSvcOriginData(const char* data, size_t len) override;
-  void OnAltSvcValueData(const char* data, size_t len) override;
-  void OnAltSvcEnd() override;
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) override;
-  void OnPriorityUpdatePayload(const char* data, size_t len) override;
-  void OnPriorityUpdateEnd() override;
-  void OnUnknownStart(const Http2FrameHeader& header) override;
-  void OnUnknownPayload(const char* data, size_t len) override;
-  void OnUnknownEnd() override;
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override;
-  void OnFrameSizeError(const Http2FrameHeader& header) override;
-
- private:
-  void EnsureNotAbstract() { FailingHttp2FrameDecoderListener instance; }
-};
-
-// HTTP2_VLOG's all the calls it receives, and forwards those calls to an
-// optional listener.
-class LoggingHttp2FrameDecoderListener : public Http2FrameDecoderListener {
- public:
-  LoggingHttp2FrameDecoderListener();
-  explicit LoggingHttp2FrameDecoderListener(Http2FrameDecoderListener* wrapped);
-  ~LoggingHttp2FrameDecoderListener() override;
-
-  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
-  // SpdyFramer's exact states.
-  bool OnFrameHeader(const Http2FrameHeader& header) override;
-  void OnDataStart(const Http2FrameHeader& header) override;
-  void OnDataPayload(const char* data, size_t len) override;
-  void OnDataEnd() override;
-  void OnHeadersStart(const Http2FrameHeader& header) override;
-  void OnHeadersPriority(const Http2PriorityFields& priority) override;
-  void OnHpackFragment(const char* data, size_t len) override;
-  void OnHeadersEnd() override;
-  void OnPriorityFrame(const Http2FrameHeader& header,
-                       const Http2PriorityFields& priority) override;
-  void OnContinuationStart(const Http2FrameHeader& header) override;
-  void OnContinuationEnd() override;
-  void OnPadLength(size_t trailing_length) override;
-  void OnPadding(const char* padding, size_t skipped_length) override;
-  void OnRstStream(const Http2FrameHeader& header,
-                   Http2ErrorCode error_code) override;
-  void OnSettingsStart(const Http2FrameHeader& header) override;
-  void OnSetting(const Http2SettingFields& setting_fields) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck(const Http2FrameHeader& header) override;
-  void OnPushPromiseStart(const Http2FrameHeader& header,
-                          const Http2PushPromiseFields& promise,
-                          size_t total_padding_length) override;
-  void OnPushPromiseEnd() override;
-  void OnPing(const Http2FrameHeader& header,
-              const Http2PingFields& ping) override;
-  void OnPingAck(const Http2FrameHeader& header,
-                 const Http2PingFields& ping) override;
-  void OnGoAwayStart(const Http2FrameHeader& header,
-                     const Http2GoAwayFields& goaway) override;
-  void OnGoAwayOpaqueData(const char* data, size_t len) override;
-  void OnGoAwayEnd() override;
-  void OnWindowUpdate(const Http2FrameHeader& header,
-                      uint32_t increment) override;
-  void OnAltSvcStart(const Http2FrameHeader& header,
-                     size_t origin_length,
-                     size_t value_length) override;
-  void OnAltSvcOriginData(const char* data, size_t len) override;
-  void OnAltSvcValueData(const char* data, size_t len) override;
-  void OnAltSvcEnd() override;
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) override;
-  void OnPriorityUpdatePayload(const char* data, size_t len) override;
-  void OnPriorityUpdateEnd() override;
-  void OnUnknownStart(const Http2FrameHeader& header) override;
-  void OnUnknownPayload(const char* data, size_t len) override;
-  void OnUnknownEnd() override;
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override;
-  void OnFrameSizeError(const Http2FrameHeader& header) override;
-
- private:
-  void EnsureNotAbstract() { LoggingHttp2FrameDecoderListener instance; }
-
-  Http2FrameDecoderListener* wrapped_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_TEST_UTIL_H_
diff --git a/http2/decoder/http2_frame_decoder_test.cc b/http2/decoder/http2_frame_decoder_test.cc
deleted file mode 100644
index c628821..0000000
--- a/http2/decoder/http2_frame_decoder_test.cc
+++ /dev/null
@@ -1,924 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_frame_decoder.h"
-
-// Tests of Http2FrameDecoder.
-
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_flags.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector_listener.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_decoder_test.h"
-
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-class Http2FrameDecoderPeer {
- public:
-  static size_t remaining_total_payload(Http2FrameDecoder* decoder) {
-    return decoder->frame_decoder_state_.remaining_total_payload();
-  }
-};
-
-namespace {
-
-class Http2FrameDecoderTest : public RandomDecoderTest {
- protected:
-  DecodeStatus StartDecoding(DecodeBuffer* db) override {
-    HTTP2_DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining();
-    collector_.Reset();
-    PrepareDecoder();
-
-    DecodeStatus status = decoder_->DecodeFrame(db);
-    if (status != DecodeStatus::kDecodeInProgress) {
-      // Keep track of this so that a concrete test can verify that both fast
-      // and slow decoding paths have been tested.
-      ++fast_decode_count_;
-      if (status == DecodeStatus::kDecodeError) {
-        ConfirmDiscardsRemainingPayload();
-      }
-    }
-    return status;
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* db) override {
-    HTTP2_DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining();
-    DecodeStatus status = decoder_->DecodeFrame(db);
-    if (status != DecodeStatus::kDecodeInProgress) {
-      // Keep track of this so that a concrete test can verify that both fast
-      // and slow decoding paths have been tested.
-      ++slow_decode_count_;
-      if (status == DecodeStatus::kDecodeError) {
-        ConfirmDiscardsRemainingPayload();
-      }
-    }
-    return status;
-  }
-
-  // When an error is returned, the decoder is in state kDiscardPayload, and
-  // stays there until the remaining bytes of the frame's payload have been
-  // skipped over. There are no callbacks for this situation.
-  void ConfirmDiscardsRemainingPayload() {
-    ASSERT_TRUE(decoder_->IsDiscardingPayload());
-    size_t remaining =
-        Http2FrameDecoderPeer::remaining_total_payload(decoder_.get());
-    // The decoder will discard the remaining bytes, but not go beyond that,
-    // which these conditions verify.
-    size_t extra = 10;
-    std::string junk(remaining + extra, '0');
-    DecodeBuffer tmp(junk);
-    EXPECT_EQ(DecodeStatus::kDecodeDone, decoder_->DecodeFrame(&tmp));
-    EXPECT_EQ(remaining, tmp.Offset());
-    EXPECT_EQ(extra, tmp.Remaining());
-    EXPECT_FALSE(decoder_->IsDiscardingPayload());
-  }
-
-  void PrepareDecoder() {
-    decoder_ = std::make_unique<Http2FrameDecoder>(&collector_);
-    decoder_->set_maximum_payload_size(maximum_payload_size_);
-  }
-
-  void ResetDecodeSpeedCounters() {
-    fast_decode_count_ = 0;
-    slow_decode_count_ = 0;
-  }
-
-  AssertionResult VerifyCollected(const FrameParts& expected) {
-    VERIFY_FALSE(collector_.IsInProgress());
-    VERIFY_EQ(1u, collector_.size());
-    VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*collector_.frame(0)));
-  }
-
-  AssertionResult DecodePayloadAndValidateSeveralWays(absl::string_view payload,
-                                                      Validator validator) {
-    DecodeBuffer db(payload);
-    bool start_decoding_requires_non_empty = false;
-    return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty,
-                                        validator);
-  }
-
-  // Decode one frame's payload and confirm that the listener recorded the
-  // expected FrameParts instance, and only one FrameParts instance. The
-  // payload will be decoded several times with different partitionings
-  // of the payload, and after each the validator will be called.
-  AssertionResult DecodePayloadAndValidateSeveralWays(
-      absl::string_view payload,
-      const FrameParts& expected) {
-    auto validator = [&expected, this](const DecodeBuffer& /*input*/,
-                                       DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
-      VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
-    };
-    ResetDecodeSpeedCounters();
-    VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays(
-        payload, ValidateDoneAndEmpty(validator)));
-    VERIFY_GT(fast_decode_count_, 0u);
-    VERIFY_GT(slow_decode_count_, 0u);
-
-    // Repeat with more input; it should stop without reading that input.
-    std::string next_frame = Random().RandString(10);
-    std::string input(payload.data(), payload.size());
-    input += next_frame;
-
-    ResetDecodeSpeedCounters();
-    VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays(
-        payload, ValidateDoneAndOffset(payload.size(), validator)));
-    VERIFY_GT(fast_decode_count_, 0u);
-    VERIFY_GT(slow_decode_count_, 0u);
-
-    return AssertionSuccess();
-  }
-
-  template <size_t N>
-  AssertionResult DecodePayloadAndValidateSeveralWays(
-      const char (&buf)[N],
-      const FrameParts& expected) {
-    return DecodePayloadAndValidateSeveralWays(absl::string_view(buf, N),
-                                               expected);
-  }
-
-  template <size_t N>
-  AssertionResult DecodePayloadAndValidateSeveralWays(
-      const char (&buf)[N],
-      const Http2FrameHeader& header) {
-    return DecodePayloadAndValidateSeveralWays(absl::string_view(buf, N),
-                                               FrameParts(header));
-  }
-
-  template <size_t N>
-  AssertionResult DecodePayloadExpectingError(const char (&buf)[N],
-                                              const FrameParts& expected) {
-    auto validator = [&expected, this](const DecodeBuffer& /*input*/,
-                                       DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(status, DecodeStatus::kDecodeError);
-      VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
-    };
-    ResetDecodeSpeedCounters();
-    EXPECT_TRUE(
-        DecodePayloadAndValidateSeveralWays(ToStringPiece(buf), validator));
-    EXPECT_GT(fast_decode_count_, 0u);
-    EXPECT_GT(slow_decode_count_, 0u);
-    return AssertionSuccess();
-  }
-
-  template <size_t N>
-  AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N],
-                                                       FrameParts expected) {
-    expected.SetHasFrameSizeError(true);
-    VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected));
-  }
-
-  template <size_t N>
-  AssertionResult DecodePayloadExpectingFrameSizeError(
-      const char (&buf)[N],
-      const Http2FrameHeader& header) {
-    return DecodePayloadExpectingFrameSizeError(buf, FrameParts(header));
-  }
-
-  // Count of payloads that are fully decoded by StartDecodingPayload or for
-  // which an error was detected by StartDecodingPayload.
-  size_t fast_decode_count_ = 0;
-
-  // Count of payloads that required calling ResumeDecodingPayload in order to
-  // decode completely, or for which an error was detected by
-  // ResumeDecodingPayload.
-  size_t slow_decode_count_ = 0;
-
-  uint32_t maximum_payload_size_ = Http2SettingsInfo::DefaultMaxFrameSize();
-  FramePartsCollectorListener collector_;
-  std::unique_ptr<Http2FrameDecoder> decoder_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// Tests that pass the minimum allowed size for the frame type, which is often
-// empty. The tests are in order by frame type value (i.e. 0 for DATA frames).
-
-TEST_F(Http2FrameDecoderTest, DataEmpty) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',  // Payload length: 0
-      '\x00',                  // DATA
-      '\x00',                  // Flags: none
-      '\x00', '\x00', '\x00',
-      '\x00',  // Stream ID: 0 (invalid but unchecked here)
-  };
-  Http2FrameHeader header(0, Http2FrameType::DATA, 0, 0);
-  FrameParts expected(header, "");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeadersEmpty) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',          // Payload length: 0
-      '\x01',                          // HEADERS
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 0  (REQUIRES ID)
-  };
-  Http2FrameHeader header(0, Http2FrameType::HEADERS, 0, 1);
-  FrameParts expected(header, "");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, Priority) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x05',          // Length: 5
-      '\x02',                          //   Type: PRIORITY
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream: 2
-      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
-      '\x10',                          // Weight: 17
-  };
-  Http2FrameHeader header(5, Http2FrameType::PRIORITY, 0, 2);
-  FrameParts expected(header);
-  expected.SetOptPriority(Http2PriorityFields(1, 17, true));
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, RstStream) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x04',          // Length: 4
-      '\x03',                          //   Type: RST_STREAM
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
-      '\x00', '\x00', '\x00', '\x01',  //  Error: PROTOCOL_ERROR
-  };
-  Http2FrameHeader header(4, Http2FrameType::RST_STREAM, 0, 1);
-  FrameParts expected(header);
-  expected.SetOptRstStreamErrorCode(Http2ErrorCode::PROTOCOL_ERROR);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, SettingsEmpty) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',          // Length: 0
-      '\x04',                          //   Type: SETTINGS
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1 (invalid but unchecked here)
-  };
-  Http2FrameHeader header(0, Http2FrameType::SETTINGS, 0, 1);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, SettingsAck) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',          //   Length: 6
-      '\x04',                          //     Type: SETTINGS
-      '\x01',                          //    Flags: ACK
-      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
-  };
-  Http2FrameHeader header(0, Http2FrameType::SETTINGS, Http2FrameFlag::ACK, 0);
-  FrameParts expected(header);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, PushPromiseMinimal) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x04',  // Payload length: 4
-      '\x05',                  // PUSH_PROMISE
-      '\x04',                  // Flags: END_HEADERS
-      '\x00', '\x00', '\x00',
-      '\x02',  //   Stream: 2 (invalid but unchecked here)
-      '\x00', '\x00', '\x00',
-      '\x01',  // Promised: 1 (invalid but unchecked here)
-  };
-  Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
-                          Http2FrameFlag::END_HEADERS, 2);
-  FrameParts expected(header, "");
-  expected.SetOptPushPromise(Http2PushPromiseFields{1});
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, Ping) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x08',          //   Length: 8
-      '\x06',                          //     Type: PING
-      '\xfe',                          //    Flags: no valid flags
-      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
-      's',    'o',    'm',    'e',     // "some"
-      'd',    'a',    't',    'a',     // "data"
-  };
-  Http2FrameHeader header(8, Http2FrameType::PING, 0, 0);
-  FrameParts expected(header);
-  expected.SetOptPing(
-      Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, PingAck) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x08',          //   Length: 8
-      '\x06',                          //     Type: PING
-      '\xff',                          //    Flags: ACK (plus all invalid flags)
-      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
-      's',    'o',    'm',    'e',     // "some"
-      'd',    'a',    't',    'a',     // "data"
-  };
-  Http2FrameHeader header(8, Http2FrameType::PING, Http2FrameFlag::ACK, 0);
-  FrameParts expected(header);
-  expected.SetOptPing(
-      Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, GoAwayMinimal) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x08',          // Length: 8 (no opaque data)
-      '\x07',                          //   Type: GOAWAY
-      '\xff',                          //  Flags: 0xff (no valid flags)
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1 (invalid but unchecked here)
-      '\x80', '\x00', '\x00', '\xff',  //   Last: 255 (plus R bit)
-      '\x00', '\x00', '\x00', '\x09',  //  Error: COMPRESSION_ERROR
-  };
-  Http2FrameHeader header(8, Http2FrameType::GOAWAY, 0, 1);
-  FrameParts expected(header);
-  expected.SetOptGoaway(
-      Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR));
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, WindowUpdate) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x04',          // Length: 4
-      '\x08',                          //   Type: WINDOW_UPDATE
-      '\x0f',                          //  Flags: 0xff (no valid flags)
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
-      '\x80', '\x00', '\x04', '\x00',  //   Incr: 1024 (plus R bit)
-  };
-  Http2FrameHeader header(4, Http2FrameType::WINDOW_UPDATE, 0, 1);
-  FrameParts expected(header);
-  expected.SetOptWindowUpdateIncrement(1024);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, ContinuationEmpty) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',  // Payload length: 0
-      '\x09',                  // CONTINUATION
-      '\x00',                  // Flags: none
-      '\x00', '\x00', '\x00',
-      '\x00',  // Stream ID: 0 (invalid but unchecked here)
-  };
-  Http2FrameHeader header(0, Http2FrameType::CONTINUATION, 0, 0);
-  FrameParts expected(header);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, AltSvcMinimal) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x02',  // Payload length: 2
-      '\x0a',                  // ALTSVC
-      '\xff',                  // Flags: none (plus 0xff)
-      '\x00', '\x00', '\x00',
-      '\x00',          // Stream ID: 0 (invalid but unchecked here)
-      '\x00', '\x00',  // Origin Length: 0
-  };
-  Http2FrameHeader header(2, Http2FrameType::ALTSVC, 0, 0);
-  FrameParts expected(header);
-  expected.SetOptAltsvcOriginLength(0);
-  expected.SetOptAltsvcValueLength(0);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, UnknownEmpty) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',          // Payload length: 0
-      '\x20',                          // 32 (unknown)
-      '\xff',                          // Flags: all
-      '\x00', '\x00', '\x00', '\x00',  // Stream ID: 0
-  };
-  Http2FrameHeader header(0, static_cast<Http2FrameType>(32), 0xff, 0);
-  FrameParts expected(header);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Tests of longer payloads, for those frame types that allow longer payloads.
-
-TEST_F(Http2FrameDecoderTest, DataPayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x03',          // Payload length: 7
-      '\x00',                          // DATA
-      '\x80',                          // Flags: 0x80
-      '\x00', '\x00', '\x02', '\x02',  // Stream ID: 514
-      'a',    'b',    'c',             // Data
-  };
-  Http2FrameHeader header(3, Http2FrameType::DATA, 0, 514);
-  FrameParts expected(header, "abc");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeadersPayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x03',          // Payload length: 3
-      '\x01',                          // HEADERS
-      '\x05',                          // Flags: END_STREAM | END_HEADERS
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
-      'a',    'b',    'c',  // HPACK fragment (doesn't have to be valid)
-  };
-  Http2FrameHeader header(
-      3, Http2FrameType::HEADERS,
-      Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS, 2);
-  FrameParts expected(header, "abc");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeadersPriority) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x05',          // Payload length: 5
-      '\x01',                          // HEADERS
-      '\x20',                          // Flags: PRIORITY
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
-      '\x00', '\x00', '\x00', '\x01',  // Parent: 1 (Not Exclusive)
-      '\xff',                          // Weight: 256
-  };
-  Http2FrameHeader header(5, Http2FrameType::HEADERS, Http2FrameFlag::PRIORITY,
-                          2);
-  FrameParts expected(header);
-  expected.SetOptPriority(Http2PriorityFields(1, 256, false));
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, Settings) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x0c',          // Length: 12
-      '\x04',                          //   Type: SETTINGS
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x00',  // Stream: 0
-      '\x00', '\x04',                  //  Param: INITIAL_WINDOW_SIZE
-      '\x0a', '\x0b', '\x0c', '\x0d',  //  Value: 168496141
-      '\x00', '\x02',                  //  Param: ENABLE_PUSH
-      '\x00', '\x00', '\x00', '\x03',  //  Value: 3 (invalid but unchecked here)
-  };
-  Http2FrameHeader header(12, Http2FrameType::SETTINGS, 0, 0);
-  FrameParts expected(header);
-  expected.AppendSetting(Http2SettingFields(
-      Http2SettingsParameter::INITIAL_WINDOW_SIZE, 168496141));
-  expected.AppendSetting(
-      Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, PushPromisePayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', 7,               // Payload length: 7
-      '\x05',                          // PUSH_PROMISE
-      '\x04',                          // Flags: END_HEADERS
-      '\x00', '\x00', '\x00', '\xff',  // Stream ID: 255
-      '\x00', '\x00', '\x01', '\x00',  // Promised: 256
-      'a',    'b',    'c',  // HPACK fragment (doesn't have to be valid)
-  };
-  Http2FrameHeader header(7, Http2FrameType::PUSH_PROMISE,
-                          Http2FrameFlag::END_HEADERS, 255);
-  FrameParts expected(header, "abc");
-  expected.SetOptPushPromise(Http2PushPromiseFields{256});
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, GoAwayOpaqueData) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x0e',          // Length: 14
-      '\x07',                          //   Type: GOAWAY
-      '\xff',                          //  Flags: 0xff (no valid flags)
-      '\x80', '\x00', '\x00', '\x00',  // Stream: 0 (plus R bit)
-      '\x00', '\x00', '\x01', '\x00',  //   Last: 256
-      '\x00', '\x00', '\x00', '\x03',  //  Error: FLOW_CONTROL_ERROR
-      'o',    'p',    'a',    'q',    'u', 'e',
-  };
-  Http2FrameHeader header(14, Http2FrameType::GOAWAY, 0, 0);
-  FrameParts expected(header, "opaque");
-  expected.SetOptGoaway(
-      Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR));
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, ContinuationPayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x03',          // Payload length: 3
-      '\x09',                          // CONTINUATION
-      '\xff',                          // Flags: END_HEADERS | 0xfb
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
-      'a',    'b',    'c',             // Data
-  };
-  Http2FrameHeader header(3, Http2FrameType::CONTINUATION,
-                          Http2FrameFlag::END_HEADERS, 2);
-  FrameParts expected(header, "abc");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, AltSvcPayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x08',          // Payload length: 3
-      '\x0a',                          // ALTSVC
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
-      '\x00', '\x03',                  // Origin Length: 0
-      'a',    'b',    'c',             // Origin
-      'd',    'e',    'f',             // Value
-  };
-  Http2FrameHeader header(8, Http2FrameType::ALTSVC, 0, 2);
-  FrameParts expected(header);
-  expected.SetAltSvcExpected("abc", "def");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, PriorityUpdatePayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x07',          // Payload length: 7
-      '\x10',                          // PRIORITY_UPDATE
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x00',  // Stream ID: 0
-      '\x00', '\x00', '\x00', '\x05',  // Prioritized Stream ID: 5
-      'a',    'b',    'c',             // Priority Field Value
-  };
-  Http2FrameHeader header(7, Http2FrameType::PRIORITY_UPDATE, 0, 0);
-
-  FrameParts expected(header, "abc");
-  expected.SetOptPriorityUpdate(Http2PriorityUpdateFields{5});
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, UnknownPayload) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x03',          // Payload length: 3
-      '\x30',                          // 48 (unknown)
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
-      'a',    'b',    'c',             // Payload
-  };
-  Http2FrameHeader header(3, static_cast<Http2FrameType>(48), 0, 2);
-  FrameParts expected(header, "abc");
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Tests of padded payloads, for those frame types that allow padding.
-
-TEST_F(Http2FrameDecoderTest, DataPayloadAndPadding) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x07',          // Payload length: 7
-      '\x00',                          // DATA
-      '\x09',                          // Flags: END_STREAM | PADDED
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
-      '\x03',                          // Pad Len
-      'a',    'b',    'c',             // Data
-      '\x00', '\x00', '\x00',          // Padding
-  };
-  Http2FrameHeader header(7, Http2FrameType::DATA,
-                          Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED,
-                          2);
-  size_t total_pad_length = 4;  // Including the Pad Length field.
-  FrameParts expected(header, "abc", total_pad_length);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeadersPayloadAndPadding) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x07',          // Payload length: 7
-      '\x01',                          // HEADERS
-      '\x08',                          // Flags: PADDED
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
-      '\x03',                          // Pad Len
-      'a',    'b',    'c',     // HPACK fragment (doesn't have to be valid)
-      '\x00', '\x00', '\x00',  // Padding
-  };
-  Http2FrameHeader header(7, Http2FrameType::HEADERS, Http2FrameFlag::PADDED,
-                          2);
-  size_t total_pad_length = 4;  // Including the Pad Length field.
-  FrameParts expected(header, "abc", total_pad_length);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeadersPayloadPriorityAndPadding) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x0c',          // Payload length: 12
-      '\x01',                          // HEADERS
-      '\xff',                          // Flags: all, including undefined
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
-      '\x03',                          // Pad Len
-      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
-      '\x10',                          // Weight: 17
-      'a',    'b',    'c',     // HPACK fragment (doesn't have to be valid)
-      '\x00', '\x00', '\x00',  // Padding
-  };
-  Http2FrameHeader header(12, Http2FrameType::HEADERS,
-                          Http2FrameFlag::END_STREAM |
-                              Http2FrameFlag::END_HEADERS |
-                              Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY,
-                          2);
-  size_t total_pad_length = 4;  // Including the Pad Length field.
-  FrameParts expected(header, "abc", total_pad_length);
-  expected.SetOptPriority(Http2PriorityFields(1, 17, true));
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, PushPromisePayloadAndPadding) {
-  const char kFrameData[] = {
-      '\x00', '\x00', 11,              // Payload length: 11
-      '\x05',                          // PUSH_PROMISE
-      '\xff',                          // Flags: END_HEADERS | PADDED | 0xf3
-      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
-      '\x03',                          // Pad Len
-      '\x00', '\x00', '\x00', '\x02',  // Promised: 2
-      'a',    'b',    'c',     // HPACK fragment (doesn't have to be valid)
-      '\x00', '\x00', '\x00',  // Padding
-  };
-  Http2FrameHeader header(11, Http2FrameType::PUSH_PROMISE,
-                          Http2FrameFlag::END_HEADERS | Http2FrameFlag::PADDED,
-                          1);
-  size_t total_pad_length = 4;  // Including the Pad Length field.
-  FrameParts expected(header, "abc", total_pad_length);
-  expected.SetOptPushPromise(Http2PushPromiseFields{2});
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Payload too short errors.
-
-TEST_F(Http2FrameDecoderTest, DataMissingPadLengthField) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',          // Payload length: 0
-      '\x00',                          // DATA
-      '\x08',                          // Flags: PADDED
-      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
-  };
-  Http2FrameHeader header(0, Http2FrameType::DATA, Http2FrameFlag::PADDED, 1);
-  FrameParts expected(header);
-  expected.SetOptMissingLength(1);
-  EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeaderPaddingTooLong) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x02',          // Payload length: 0
-      '\x01',                          // HEADERS
-      '\x08',                          // Flags: PADDED
-      '\x00', '\x01', '\x00', '\x00',  // Stream ID: 65536
-      '\xff',                          // Pad Len: 255
-      '\x00',                          // Only one byte of padding
-  };
-  Http2FrameHeader header(2, Http2FrameType::HEADERS, Http2FrameFlag::PADDED,
-                          65536);
-  FrameParts expected(header);
-  expected.SetOptMissingLength(254);
-  EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, HeaderMissingPriority) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x04',          // Payload length: 0
-      '\x01',                          // HEADERS
-      '\x20',                          // Flags: PRIORITY
-      '\x00', '\x01', '\x00', '\x00',  // Stream ID: 65536
-      '\x00', '\x00', '\x00', '\x00',  // Priority (truncated)
-  };
-  Http2FrameHeader header(4, Http2FrameType::HEADERS, Http2FrameFlag::PRIORITY,
-                          65536);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, PriorityTooShort) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x04',          // Length: 5
-      '\x02',                          //   Type: PRIORITY
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream: 2
-      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
-  };
-  Http2FrameHeader header(4, Http2FrameType::PRIORITY, 0, 2);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, RstStreamTooShort) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x03',          // Length: 4
-      '\x03',                          //   Type: RST_STREAM
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
-      '\x00', '\x00', '\x00',          //  Truncated
-  };
-  Http2FrameHeader header(3, Http2FrameType::RST_STREAM, 0, 1);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-// SETTINGS frames must a multiple of 6 bytes long, so an 9 byte payload is
-// invalid.
-TEST_F(Http2FrameDecoderTest, SettingsWrongSize) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x09',          // Length: 2
-      '\x04',                          //   Type: SETTINGS
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x00',  // Stream: 0
-      '\x00', '\x02',                  //  Param: ENABLE_PUSH
-      '\x00', '\x00', '\x00', '\x03',  //  Value: 1
-      '\x00', '\x04',                  //  Param: INITIAL_WINDOW_SIZE
-      '\x00',                          //  Value: Truncated
-  };
-  Http2FrameHeader header(9, Http2FrameType::SETTINGS, 0, 0);
-  FrameParts expected(header);
-  expected.AppendSetting(
-      Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, expected));
-}
-
-TEST_F(Http2FrameDecoderTest, PushPromiseTooShort) {
-  const char kFrameData[] = {
-      '\x00', '\x00', 3,               // Payload length: 3
-      '\x05',                          // PUSH_PROMISE
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
-      '\x00', '\x00', '\x00',          // Truncated promise id
-  };
-  Http2FrameHeader header(3, Http2FrameType::PUSH_PROMISE, 0, 1);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, PushPromisePaddedTruncatedPromise) {
-  const char kFrameData[] = {
-      '\x00', '\x00', 4,               // Payload length: 4
-      '\x05',                          // PUSH_PROMISE
-      '\x08',                          // Flags: PADDED
-      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
-      '\x00',                          // Pad Len
-      '\x00', '\x00', '\x00',          // Truncated promise id
-  };
-  Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
-                          Http2FrameFlag::PADDED, 1);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, PingTooShort) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x07',          //   Length: 8
-      '\x06',                          //     Type: PING
-      '\xfe',                          //    Flags: no valid flags
-      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
-      's',    'o',    'm',    'e',     // "some"
-      'd',    'a',    't',             // Too little
-  };
-  Http2FrameHeader header(7, Http2FrameType::PING, 0, 0);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, GoAwayTooShort) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x00',          // Length: 0
-      '\x07',                          //   Type: GOAWAY
-      '\xff',                          //  Flags: 0xff (no valid flags)
-      '\x00', '\x00', '\x00', '\x00',  // Stream: 0
-  };
-  Http2FrameHeader header(0, Http2FrameType::GOAWAY, 0, 0);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, WindowUpdateTooShort) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x03',          // Length: 3
-      '\x08',                          //   Type: WINDOW_UPDATE
-      '\x0f',                          //  Flags: 0xff (no valid flags)
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
-      '\x80', '\x00', '\x04',          // Truncated
-  };
-  Http2FrameHeader header(3, Http2FrameType::WINDOW_UPDATE, 0, 1);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOriginLength) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x01',          // Payload length: 3
-      '\x0a',                          // ALTSVC
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
-      '\x00',                          // Origin Length: truncated
-  };
-  Http2FrameHeader header(1, Http2FrameType::ALTSVC, 0, 2);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOrigin) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x05',          // Payload length: 3
-      '\x0a',                          // ALTSVC
-      '\x00',                          // Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
-      '\x00', '\x04',                  // Origin Length: 4 (too long)
-      'a',    'b',    'c',             // Origin
-  };
-  Http2FrameHeader header(5, Http2FrameType::ALTSVC, 0, 2);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Payload too long errors.
-
-// The decoder calls the listener's OnFrameSizeError method if the frame's
-// payload is longer than the currently configured maximum payload size.
-TEST_F(Http2FrameDecoderTest, BeyondMaximum) {
-  maximum_payload_size_ = 2;
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x07',          // Payload length: 7
-      '\x00',                          // DATA
-      '\x09',                          // Flags: END_STREAM | PADDED
-      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
-      '\x03',                          // Pad Len
-      'a',    'b',    'c',             // Data
-      '\x00', '\x00', '\x00',          // Padding
-  };
-  Http2FrameHeader header(7, Http2FrameType::DATA,
-                          Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED,
-                          2);
-  FrameParts expected(header);
-  expected.SetHasFrameSizeError(true);
-  auto validator = [&expected, this](const DecodeBuffer& input,
-                                     DecodeStatus status) -> AssertionResult {
-    VERIFY_EQ(status, DecodeStatus::kDecodeError);
-    // The decoder detects this error after decoding the header, and without
-    // trying to decode the payload.
-    VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize());
-    VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
-  };
-  ResetDecodeSpeedCounters();
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(ToStringPiece(kFrameData),
-                                                  validator));
-  EXPECT_GT(fast_decode_count_, 0u);
-  EXPECT_GT(slow_decode_count_, 0u);
-}
-
-TEST_F(Http2FrameDecoderTest, PriorityTooLong) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x06',          // Length: 5
-      '\x02',                          //   Type: PRIORITY
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x02',  // Stream: 2
-      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
-      '\x10',                          // Weight: 17
-      '\x00',                          // Too much
-  };
-  Http2FrameHeader header(6, Http2FrameType::PRIORITY, 0, 2);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, RstStreamTooLong) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x05',          // Length: 4
-      '\x03',                          //   Type: RST_STREAM
-      '\x00',                          //  Flags: none
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
-      '\x00', '\x00', '\x00', '\x01',  //  Error: PROTOCOL_ERROR
-      '\x00',                          // Too much
-  };
-  Http2FrameHeader header(5, Http2FrameType::RST_STREAM, 0, 1);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, SettingsAckTooLong) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x06',          //   Length: 6
-      '\x04',                          //     Type: SETTINGS
-      '\x01',                          //    Flags: ACK
-      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
-      '\x00', '\x00',                  //   Extra
-      '\x00', '\x00', '\x00', '\x00',  //   Extra
-  };
-  Http2FrameHeader header(6, Http2FrameType::SETTINGS, Http2FrameFlag::ACK, 0);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, PingAckTooLong) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x09',          //   Length: 8
-      '\x06',                          //     Type: PING
-      '\xff',                          //    Flags: ACK | 0xfe
-      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
-      's',    'o',    'm',    'e',     // "some"
-      'd',    'a',    't',    'a',     // "data"
-      '\x00',                          // Too much
-  };
-  Http2FrameHeader header(9, Http2FrameType::PING, Http2FrameFlag::ACK, 0);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-TEST_F(Http2FrameDecoderTest, WindowUpdateTooLong) {
-  const char kFrameData[] = {
-      '\x00', '\x00', '\x05',          // Length: 5
-      '\x08',                          //   Type: WINDOW_UPDATE
-      '\x0f',                          //  Flags: 0xff (no valid flags)
-      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
-      '\x80', '\x00', '\x04', '\x00',  //   Incr: 1024 (plus R bit)
-      '\x00',                          // Too much
-  };
-  Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1);
-  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/http2_structure_decoder.cc b/http2/decoder/http2_structure_decoder.cc
deleted file mode 100644
index 43ade26..0000000
--- a/http2/decoder/http2_structure_decoder.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_structure_decoder.h"
-
-#include <algorithm>
-#include <cstring>
-
-#include "http2/platform/api/http2_bug_tracker.h"
-
-namespace http2 {
-
-// Below we have some defensive coding: if we somehow run off the end, don't
-// overwrite lots of memory. Note that most of this decoder is not defensive
-// against bugs in the decoder, only against malicious encoders, but since
-// we're copying memory into a buffer here, let's make sure we don't allow a
-// small mistake to grow larger. The decoder will get stuck if we hit the
-// HTTP2_BUG conditions, but shouldn't corrupt memory.
-
-uint32_t Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
-                                                uint32_t target_size) {
-  if (target_size > sizeof buffer_) {
-    HTTP2_BUG(http2_bug_154_1)
-        << "target_size too large for buffer: " << target_size;
-    return 0;
-  }
-  const uint32_t num_to_copy = db->MinLengthRemaining(target_size);
-  memcpy(buffer_, db->cursor(), num_to_copy);
-  offset_ = num_to_copy;
-  db->AdvanceCursor(num_to_copy);
-  return num_to_copy;
-}
-
-DecodeStatus Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
-                                                    uint32_t* remaining_payload,
-                                                    uint32_t target_size) {
-  HTTP2_DVLOG(1) << "IncompleteStart@" << this
-                 << ": *remaining_payload=" << *remaining_payload
-                 << "; target_size=" << target_size
-                 << "; db->Remaining=" << db->Remaining();
-  *remaining_payload -=
-      IncompleteStart(db, std::min(target_size, *remaining_payload));
-  if (*remaining_payload > 0 && db->Empty()) {
-    return DecodeStatus::kDecodeInProgress;
-  }
-  HTTP2_DVLOG(1) << "IncompleteStart: kDecodeError";
-  return DecodeStatus::kDecodeError;
-}
-
-bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
-                                                uint32_t target_size) {
-  HTTP2_DVLOG(2) << "ResumeFillingBuffer@" << this
-                 << ": target_size=" << target_size << "; offset_=" << offset_
-                 << "; db->Remaining=" << db->Remaining();
-  if (target_size < offset_) {
-    HTTP2_BUG(http2_bug_154_2)
-        << "Already filled buffer_! target_size=" << target_size
-        << "    offset_=" << offset_;
-    return false;
-  }
-  const uint32_t needed = target_size - offset_;
-  const uint32_t num_to_copy = db->MinLengthRemaining(needed);
-  HTTP2_DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
-  memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
-  db->AdvanceCursor(num_to_copy);
-  offset_ += num_to_copy;
-  return needed == num_to_copy;
-}
-
-bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
-                                                uint32_t* remaining_payload,
-                                                uint32_t target_size) {
-  HTTP2_DVLOG(2) << "ResumeFillingBuffer@" << this
-                 << ": target_size=" << target_size << "; offset_=" << offset_
-                 << "; *remaining_payload=" << *remaining_payload
-                 << "; db->Remaining=" << db->Remaining();
-  if (target_size < offset_) {
-    HTTP2_BUG(http2_bug_154_3)
-        << "Already filled buffer_! target_size=" << target_size
-        << "    offset_=" << offset_;
-    return false;
-  }
-  const uint32_t needed = target_size - offset_;
-  const uint32_t num_to_copy =
-      db->MinLengthRemaining(std::min(needed, *remaining_payload));
-  HTTP2_DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
-  memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
-  db->AdvanceCursor(num_to_copy);
-  offset_ += num_to_copy;
-  *remaining_payload -= num_to_copy;
-  return needed == num_to_copy;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/http2_structure_decoder.h b/http2/decoder/http2_structure_decoder.h
deleted file mode 100644
index 367e225..0000000
--- a/http2/decoder/http2_structure_decoder.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_H_
-#define QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_H_
-
-// Http2StructureDecoder is a class for decoding the fixed size structures in
-// the HTTP/2 spec, defined in http2/http2_structures.h. This class
-// is in aid of deciding whether to keep the SlowDecode methods which I
-// (jamessynge) now think may not be worth their complexity. In particular,
-// if most transport buffers are large, so it is rare that a structure is
-// split across buffer boundaries, than the cost of buffering upon
-// those rare occurrences is small, which then simplifies the callers.
-
-#include <cstdint>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_http2_structures.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class Http2StructureDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE Http2StructureDecoder {
- public:
-  // The caller needs to keep track of whether to call Start or Resume.
-  //
-  // Start has an optimization for the case where the DecodeBuffer holds the
-  // entire encoded structure; in that case it decodes into *out and returns
-  // true, and does NOT touch the data members of the Http2StructureDecoder
-  // instance because the caller won't be calling Resume later.
-  //
-  // However, if the DecodeBuffer is too small to hold the entire encoded
-  // structure, Start copies the available bytes into the Http2StructureDecoder
-  // instance, and returns false to indicate that it has not been able to
-  // complete the decoding.
-  //
-  template <class S>
-  bool Start(S* out, DecodeBuffer* db) {
-    static_assert(S::EncodedSize() <= sizeof buffer_, "buffer_ is too small");
-    HTTP2_DVLOG(2) << __func__ << "@" << this
-                   << ": db->Remaining=" << db->Remaining()
-                   << "; EncodedSize=" << S::EncodedSize();
-    if (db->Remaining() >= S::EncodedSize()) {
-      DoDecode(out, db);
-      return true;
-    }
-    IncompleteStart(db, S::EncodedSize());
-    return false;
-  }
-
-  template <class S>
-  bool Resume(S* out, DecodeBuffer* db) {
-    HTTP2_DVLOG(2) << __func__ << "@" << this << ": offset_=" << offset_
-                   << "; db->Remaining=" << db->Remaining();
-    if (ResumeFillingBuffer(db, S::EncodedSize())) {
-      // We have the whole thing now.
-      HTTP2_DVLOG(2) << __func__ << "@" << this << "    offset_=" << offset_
-                     << "    Ready to decode from buffer_.";
-      DecodeBuffer buffer_db(buffer_, S::EncodedSize());
-      DoDecode(out, &buffer_db);
-      return true;
-    }
-    QUICHE_DCHECK_LT(offset_, S::EncodedSize());
-    return false;
-  }
-
-  // A second pair of Start and Resume, where the caller has a variable,
-  // |remaining_payload| that is both tested for sufficiency and updated
-  // during decoding. Note that the decode buffer may extend beyond the
-  // remaining payload because the buffer may include padding.
-  template <class S>
-  DecodeStatus Start(S* out, DecodeBuffer* db, uint32_t* remaining_payload) {
-    static_assert(S::EncodedSize() <= sizeof buffer_, "buffer_ is too small");
-    HTTP2_DVLOG(2) << __func__ << "@" << this
-                   << ": *remaining_payload=" << *remaining_payload
-                   << "; db->Remaining=" << db->Remaining()
-                   << "; EncodedSize=" << S::EncodedSize();
-    if (db->MinLengthRemaining(*remaining_payload) >= S::EncodedSize()) {
-      DoDecode(out, db);
-      *remaining_payload -= S::EncodedSize();
-      return DecodeStatus::kDecodeDone;
-    }
-    return IncompleteStart(db, remaining_payload, S::EncodedSize());
-  }
-
-  template <class S>
-  bool Resume(S* out, DecodeBuffer* db, uint32_t* remaining_payload) {
-    HTTP2_DVLOG(3) << __func__ << "@" << this << ": offset_=" << offset_
-                   << "; *remaining_payload=" << *remaining_payload
-                   << "; db->Remaining=" << db->Remaining()
-                   << "; EncodedSize=" << S::EncodedSize();
-    if (ResumeFillingBuffer(db, remaining_payload, S::EncodedSize())) {
-      // We have the whole thing now.
-      HTTP2_DVLOG(2) << __func__ << "@" << this << ": offset_=" << offset_
-                     << "; Ready to decode from buffer_.";
-      DecodeBuffer buffer_db(buffer_, S::EncodedSize());
-      DoDecode(out, &buffer_db);
-      return true;
-    }
-    QUICHE_DCHECK_LT(offset_, S::EncodedSize());
-    return false;
-  }
-
-  uint32_t offset() const { return offset_; }
-
- private:
-  friend class test::Http2StructureDecoderPeer;
-
-  uint32_t IncompleteStart(DecodeBuffer* db, uint32_t target_size);
-  DecodeStatus IncompleteStart(DecodeBuffer* db,
-                               uint32_t* remaining_payload,
-                               uint32_t target_size);
-
-  bool ResumeFillingBuffer(DecodeBuffer* db, uint32_t target_size);
-  bool ResumeFillingBuffer(DecodeBuffer* db,
-                           uint32_t* remaining_payload,
-                           uint32_t target_size);
-
-  uint32_t offset_;
-  char buffer_[Http2FrameHeader::EncodedSize()];
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_H_
diff --git a/http2/decoder/http2_structure_decoder_test.cc b/http2/decoder/http2_structure_decoder_test.cc
deleted file mode 100644
index afec9d4..0000000
--- a/http2/decoder/http2_structure_decoder_test.cc
+++ /dev/null
@@ -1,537 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_structure_decoder.h"
-
-// Tests decoding all of the fixed size HTTP/2 structures (i.e. those defined in
-// http2/http2_structures.h) using Http2StructureDecoder, which
-// handles buffering of structures split across input buffer boundaries, and in
-// turn uses DoDecode when it has all of a structure in a contiguous buffer.
-
-// NOTE: This tests the first pair of Start and Resume, which don't take
-// a remaining_payload parameter. The other pair are well tested via the
-// payload decoder tests, though...
-// TODO(jamessynge): Create type parameterized tests for Http2StructureDecoder
-// where the type is the type of structure, and with testing of both pairs of
-// Start and Resume methods; note that it appears that the first pair will be
-// used only for Http2FrameHeader, and the other pair only for structures in the
-// frame payload.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-namespace {
-const bool kMayReturnZeroOnFirst = false;
-
-template <class S>
-class Http2StructureDecoderTest : public RandomDecoderTest {
- protected:
-  typedef S Structure;
-
-  Http2StructureDecoderTest() {
-    // IF the test adds more data after the encoded structure, stop as
-    // soon as the structure is decoded.
-    stop_decode_on_done_ = true;
-  }
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    // Overwrite the current contents of |structure_|, into which we'll
-    // decode the buffer, so that we can be confident that we really decoded
-    // the structure every time.
-    structure_ = std::make_unique<S>();
-    uint32_t old_remaining = b->Remaining();
-    if (structure_decoder_.Start(structure_.get(), b)) {
-      EXPECT_EQ(old_remaining - S::EncodedSize(), b->Remaining());
-      ++fast_decode_count_;
-      return DecodeStatus::kDecodeDone;
-    } else {
-      EXPECT_LT(structure_decoder_.offset(), S::EncodedSize());
-      EXPECT_EQ(0u, b->Remaining());
-      EXPECT_EQ(old_remaining - structure_decoder_.offset(), b->Remaining());
-      ++incomplete_start_count_;
-      return DecodeStatus::kDecodeInProgress;
-    }
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    uint32_t old_offset = structure_decoder_.offset();
-    EXPECT_LT(old_offset, S::EncodedSize());
-    uint32_t avail = b->Remaining();
-    if (structure_decoder_.Resume(structure_.get(), b)) {
-      EXPECT_LE(S::EncodedSize(), old_offset + avail);
-      EXPECT_EQ(b->Remaining(), avail - (S::EncodedSize() - old_offset));
-      ++slow_decode_count_;
-      return DecodeStatus::kDecodeDone;
-    } else {
-      EXPECT_LT(structure_decoder_.offset(), S::EncodedSize());
-      EXPECT_EQ(0u, b->Remaining());
-      EXPECT_GT(S::EncodedSize(), old_offset + avail);
-      ++incomplete_resume_count_;
-      return DecodeStatus::kDecodeInProgress;
-    }
-  }
-
-  // Fully decodes the Structure at the start of data, and confirms it matches
-  // *expected (if provided).
-  AssertionResult DecodeLeadingStructure(const S* expected,
-                                         absl::string_view data) {
-    VERIFY_LE(S::EncodedSize(), data.size());
-    DecodeBuffer original(data);
-
-    // The validator is called after each of the several times that the input
-    // DecodeBuffer is decoded, each with a different segmentation of the input.
-    // Validate that structure_ matches the expected value, if provided.
-    Validator validator;
-    if (expected != nullptr) {
-      validator = [expected, this](const DecodeBuffer& /*db*/,
-                                   DecodeStatus /*status*/) -> AssertionResult {
-        VERIFY_EQ(*expected, *structure_);
-        return AssertionSuccess();
-      };
-    }
-
-    // Before that, validate that decoding is done and that we've advanced
-    // the cursor the expected amount.
-    validator = ValidateDoneAndOffset(S::EncodedSize(), validator);
-
-    // Decode several times, with several segmentations of the input buffer.
-    fast_decode_count_ = 0;
-    slow_decode_count_ = 0;
-    incomplete_start_count_ = 0;
-    incomplete_resume_count_ = 0;
-    VERIFY_SUCCESS(DecodeAndValidateSeveralWays(
-        &original, kMayReturnZeroOnFirst, validator));
-    VERIFY_FALSE(HasFailure());
-    VERIFY_EQ(S::EncodedSize(), structure_decoder_.offset());
-    VERIFY_EQ(S::EncodedSize(), original.Offset());
-    VERIFY_LT(0u, fast_decode_count_);
-    VERIFY_LT(0u, slow_decode_count_);
-    VERIFY_LT(0u, incomplete_start_count_);
-
-    // If the structure is large enough so that SelectZeroOrOne will have
-    // caused Resume to return false, check that occurred.
-    if (S::EncodedSize() >= 2) {
-      VERIFY_LE(0u, incomplete_resume_count_);
-    } else {
-      VERIFY_EQ(0u, incomplete_resume_count_);
-    }
-    if (expected != nullptr) {
-      HTTP2_DVLOG(1) << "DecodeLeadingStructure expected: " << *expected;
-      HTTP2_DVLOG(1) << "DecodeLeadingStructure   actual: " << *structure_;
-      VERIFY_EQ(*expected, *structure_);
-    }
-    return AssertionSuccess();
-  }
-
-  template <size_t N>
-  AssertionResult DecodeLeadingStructure(const char (&data)[N]) {
-    VERIFY_AND_RETURN_SUCCESS(
-        DecodeLeadingStructure(nullptr, absl::string_view(data, N)));
-  }
-
-  template <size_t N>
-  AssertionResult DecodeLeadingStructure(const unsigned char (&data)[N]) {
-    VERIFY_AND_RETURN_SUCCESS(
-        DecodeLeadingStructure(nullptr, ToStringPiece(data)));
-  }
-
-  // Encode the structure |in_s| into bytes, then decode the bytes
-  // and validate that the decoder produced the same field values.
-  AssertionResult EncodeThenDecode(const S& in_s) {
-    std::string bytes = SerializeStructure(in_s);
-    VERIFY_EQ(S::EncodedSize(), bytes.size());
-    VERIFY_AND_RETURN_SUCCESS(DecodeLeadingStructure(&in_s, bytes));
-  }
-
-  // Repeatedly fill a structure with random but valid contents, encode it, then
-  // decode it, and finally validate that the decoded structure matches the
-  // random input. Lather-rinse-and-repeat.
-  AssertionResult TestDecodingRandomizedStructures(size_t count) {
-    for (size_t i = 0; i < count; ++i) {
-      Structure input;
-      Randomize(&input, RandomPtr());
-      VERIFY_SUCCESS(EncodeThenDecode(input));
-    }
-    return AssertionSuccess();
-  }
-
-  AssertionResult TestDecodingRandomizedStructures() {
-    VERIFY_SUCCESS(TestDecodingRandomizedStructures(100));
-    return AssertionSuccess();
-  }
-
-  uint32_t decode_offset_ = 0;
-  std::unique_ptr<S> structure_;
-  Http2StructureDecoder structure_decoder_;
-  size_t fast_decode_count_ = 0;
-  size_t slow_decode_count_ = 0;
-  size_t incomplete_start_count_ = 0;
-  size_t incomplete_resume_count_ = 0;
-};
-
-class Http2FrameHeaderDecoderTest
-    : public Http2StructureDecoderTest<Http2FrameHeader> {};
-
-TEST_F(Http2FrameHeaderDecoderTest, DecodesLiteral) {
-  {
-    // Realistic input.
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x00, 0x05,        // Payload length: 5
-        0x01,                    // Frame type: HEADERS
-        0x08,                    // Flags: PADDED
-        0x00, 0x00, 0x00, 0x01,  // Stream ID: 1
-        0x04,                    // Padding length: 4
-        0x00, 0x00, 0x00, 0x00,  // Padding bytes
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(5u, structure_->payload_length);
-    EXPECT_EQ(Http2FrameType::HEADERS, structure_->type);
-    EXPECT_EQ(Http2FrameFlag::PADDED, structure_->flags);
-    EXPECT_EQ(1u, structure_->stream_id);
-  }
-  {
-    // Unlikely input.
-    // clang-format off
-    const unsigned char kData[] = {
-        0xff, 0xff, 0xff,        // Payload length: uint24 max
-        0xff,                    // Frame type: Unknown
-        0xff,                    // Flags: Unknown/All
-        0xff, 0xff, 0xff, 0xff,  // Stream ID: uint31 max, plus R-bit
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ((1u << 24) - 1u, structure_->payload_length);
-    EXPECT_EQ(static_cast<Http2FrameType>(255), structure_->type);
-    EXPECT_EQ(255, structure_->flags);
-    EXPECT_EQ(0x7FFFFFFFu, structure_->stream_id);
-  }
-}
-
-TEST_F(Http2FrameHeaderDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2PriorityFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2PriorityFields> {};
-
-TEST_F(Http2PriorityFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0x80, 0x00, 0x00, 0x05,  // Exclusive (yes) and Dependency (5)
-        0xff,                    // Weight: 256 (after adding 1)
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(5u, structure_->stream_dependency);
-    EXPECT_EQ(256u, structure_->weight);
-    EXPECT_EQ(true, structure_->is_exclusive);
-  }
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0x7f, 0xff, 0xff, 0xff,  // Excl. (no) and Dependency (uint31 max)
-        0x00,                    // Weight: 1 (after adding 1)
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(StreamIdMask(), structure_->stream_dependency);
-    EXPECT_EQ(1u, structure_->weight);
-    EXPECT_FALSE(structure_->is_exclusive);
-  }
-}
-
-TEST_F(Http2PriorityFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2RstStreamFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2RstStreamFields> {};
-
-TEST_F(Http2RstStreamFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x00, 0x00, 0x01,  // Error: PROTOCOL_ERROR
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_TRUE(structure_->IsSupportedErrorCode());
-    EXPECT_EQ(Http2ErrorCode::PROTOCOL_ERROR, structure_->error_code);
-  }
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0xff, 0xff, 0xff, 0xff,  // Error: max uint32 (Unknown error code)
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_FALSE(structure_->IsSupportedErrorCode());
-    EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_->error_code);
-  }
-}
-
-TEST_F(Http2RstStreamFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2SettingFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2SettingFields> {};
-
-TEST_F(Http2SettingFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x01,              // Setting: HEADER_TABLE_SIZE
-        0x00, 0x00, 0x40, 0x00,  // Value: 16K
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_TRUE(structure_->IsSupportedParameter());
-    EXPECT_EQ(Http2SettingsParameter::HEADER_TABLE_SIZE, structure_->parameter);
-    EXPECT_EQ(1u << 14, structure_->value);
-  }
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0x00, 0x00,              // Setting: Unknown (0)
-        0xff, 0xff, 0xff, 0xff,  // Value: max uint32
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_FALSE(structure_->IsSupportedParameter());
-    EXPECT_EQ(static_cast<Http2SettingsParameter>(0), structure_->parameter);
-  }
-}
-
-TEST_F(Http2SettingFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2PushPromiseFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2PushPromiseFields> {};
-
-TEST_F(Http2PushPromiseFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0x00, 0x01, 0x8a, 0x92,  // Promised Stream ID: 101010
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(101010u, structure_->promised_stream_id);
-  }
-  {
-    // Promised stream id has R-bit (reserved for future use) set, which
-    // should be cleared by the decoder.
-    // clang-format off
-    const unsigned char kData[] = {
-        // Promised Stream ID: max uint31 and R-bit
-        0xff, 0xff, 0xff, 0xff,
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(StreamIdMask(), structure_->promised_stream_id);
-  }
-}
-
-TEST_F(Http2PushPromiseFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2PingFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2PingFields> {};
-
-TEST_F(Http2PingFieldsDecoderTest, DecodesLiteral) {
-  {
-    // Each byte is different, so can detect if order changed.
-    const char kData[] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    };
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(ToStringPiece(kData), ToStringPiece(structure_->opaque_bytes));
-  }
-  {
-    // All zeros, detect problems handling NULs.
-    const char kData[] = {
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    };
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(ToStringPiece(kData), ToStringPiece(structure_->opaque_bytes));
-  }
-  {
-    const unsigned char kData[] = {
-        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    };
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(ToStringPiece(kData), ToStringPiece(structure_->opaque_bytes));
-  }
-}
-
-TEST_F(Http2PingFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2GoAwayFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2GoAwayFields> {};
-
-TEST_F(Http2GoAwayFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x00, 0x00, 0x00,  // Last Stream ID: 0
-        0x00, 0x00, 0x00, 0x00,  // Error: NO_ERROR (0)
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(0u, structure_->last_stream_id);
-    EXPECT_TRUE(structure_->IsSupportedErrorCode());
-    EXPECT_EQ(Http2ErrorCode::HTTP2_NO_ERROR, structure_->error_code);
-  }
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x00, 0x00, 0x01,  // Last Stream ID: 1
-        0x00, 0x00, 0x00, 0x0d,  // Error: HTTP_1_1_REQUIRED
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(1u, structure_->last_stream_id);
-    EXPECT_TRUE(structure_->IsSupportedErrorCode());
-    EXPECT_EQ(Http2ErrorCode::HTTP_1_1_REQUIRED, structure_->error_code);
-  }
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0xff, 0xff, 0xff, 0xff,  // Last Stream ID: max uint31 and R-bit
-        0xff, 0xff, 0xff, 0xff,  // Error: max uint32 (Unknown error code)
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(StreamIdMask(), structure_->last_stream_id);  // No high-bit.
-    EXPECT_FALSE(structure_->IsSupportedErrorCode());
-    EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_->error_code);
-  }
-}
-
-TEST_F(Http2GoAwayFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2WindowUpdateFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2WindowUpdateFields> {};
-
-TEST_F(Http2WindowUpdateFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x01, 0x00, 0x00,  // Window Size Increment: 2 ^ 16
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(1u << 16, structure_->window_size_increment);
-  }
-  {
-    // Increment must be non-zero, but we need to be able to decode the invalid
-    // zero to detect it.
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x00, 0x00, 0x00,  // Window Size Increment: 0
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(0u, structure_->window_size_increment);
-  }
-  {
-    // Increment has R-bit (reserved for future use) set, which
-    // should be cleared by the decoder.
-    // clang-format off
-    const unsigned char kData[] = {
-        // Window Size Increment: max uint31 and R-bit
-        0xff, 0xff, 0xff, 0xff,
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(StreamIdMask(), structure_->window_size_increment);
-  }
-}
-
-TEST_F(Http2WindowUpdateFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-//------------------------------------------------------------------------------
-
-class Http2AltSvcFieldsDecoderTest
-    : public Http2StructureDecoderTest<Http2AltSvcFields> {};
-
-TEST_F(Http2AltSvcFieldsDecoderTest, DecodesLiteral) {
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x00,  // Origin Length: 0
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(0, structure_->origin_length);
-  }
-  {
-    // clang-format off
-    const char kData[] = {
-        0x00, 0x14,  // Origin Length: 20
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(20, structure_->origin_length);
-  }
-  {
-    // clang-format off
-    const unsigned char kData[] = {
-        0xff, 0xff,  // Origin Length: uint16 max
-    };
-    // clang-format on
-    ASSERT_TRUE(DecodeLeadingStructure(kData));
-    EXPECT_EQ(65535, structure_->origin_length);
-  }
-}
-
-TEST_F(Http2AltSvcFieldsDecoderTest, DecodesRandomized) {
-  EXPECT_TRUE(TestDecodingRandomizedStructures());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/http2_structure_decoder_test_util.cc b/http2/decoder/http2_structure_decoder_test_util.cc
deleted file mode 100644
index 7fc66f6..0000000
--- a/http2/decoder/http2_structure_decoder_test_util.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/http2_structure_decoder_test_util.h"
-
-#include <cstddef>
-
-namespace http2 {
-namespace test {
-
-// static
-void Http2StructureDecoderPeer::Randomize(Http2StructureDecoder* p,
-                                          Http2Random* rng) {
-  p->offset_ = rng->Rand32();
-  for (size_t i = 0; i < sizeof p->buffer_; ++i) {
-    p->buffer_[i] = rng->Rand8();
-  }
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/http2_structure_decoder_test_util.h b/http2/decoder/http2_structure_decoder_test_util.h
deleted file mode 100644
index 5403135..0000000
--- a/http2/decoder/http2_structure_decoder_test_util.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_TEST_UTIL_H_
-#define QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_TEST_UTIL_H_
-
-#include "http2/decoder/http2_structure_decoder.h"
-
-#include "http2/test_tools/http2_random.h"
-
-namespace http2 {
-namespace test {
-
-class Http2StructureDecoderPeer {
- public:
-  // Overwrite the Http2StructureDecoder instance with random values.
-  static void Randomize(Http2StructureDecoder* p, Http2Random* rng);
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_TEST_UTIL_H_
diff --git a/http2/decoder/payload_decoders/altsvc_payload_decoder.cc b/http2/decoder/payload_decoders/altsvc_payload_decoder.cc
deleted file mode 100644
index f95417c..0000000
--- a/http2/decoder/payload_decoders/altsvc_payload_decoder.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/altsvc_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         AltSvcPayloadDecoder::PayloadState v) {
-  switch (v) {
-    case AltSvcPayloadDecoder::PayloadState::kStartDecodingStruct:
-      return out << "kStartDecodingStruct";
-    case AltSvcPayloadDecoder::PayloadState::kMaybeDecodedStruct:
-      return out << "kMaybeDecodedStruct";
-    case AltSvcPayloadDecoder::PayloadState::kDecodingStrings:
-      return out << "kDecodingStrings";
-    case AltSvcPayloadDecoder::PayloadState::kResumeDecodingStruct:
-      return out << "kResumeDecodingStruct";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_163_1)
-      << "Invalid AltSvcPayloadDecoder::PayloadState: " << unknown;
-  return out << "AltSvcPayloadDecoder::PayloadState(" << unknown << ")";
-}
-
-DecodeStatus AltSvcPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "AltSvcPayloadDecoder::StartDecodingPayload: "
-                 << state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::ALTSVC, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
-
-  state->InitializeRemainders();
-  payload_state_ = PayloadState::kStartDecodingStruct;
-
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus AltSvcPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  HTTP2_DVLOG(2) << "AltSvcPayloadDecoder::ResumeDecodingPayload: "
-                 << frame_header;
-  QUICHE_DCHECK_EQ(Http2FrameType::ALTSVC, frame_header.type);
-  QUICHE_DCHECK_LE(state->remaining_payload(), frame_header.payload_length);
-  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
-  QUICHE_DCHECK_NE(PayloadState::kMaybeDecodedStruct, payload_state_);
-  // |status| has to be initialized to some value to avoid compiler error in
-  // case PayloadState::kMaybeDecodedStruct below, but value does not matter,
-  // see QUICHE_DCHECK_NE above.
-  DecodeStatus status = DecodeStatus::kDecodeError;
-  while (true) {
-    HTTP2_DVLOG(2)
-        << "AltSvcPayloadDecoder::ResumeDecodingPayload payload_state_="
-        << payload_state_;
-    switch (payload_state_) {
-      case PayloadState::kStartDecodingStruct:
-        status = state->StartDecodingStructureInPayload(&altsvc_fields_, db);
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kMaybeDecodedStruct:
-        if (status == DecodeStatus::kDecodeDone &&
-            altsvc_fields_.origin_length <= state->remaining_payload()) {
-          size_t origin_length = altsvc_fields_.origin_length;
-          size_t value_length = state->remaining_payload() - origin_length;
-          state->listener()->OnAltSvcStart(frame_header, origin_length,
-                                           value_length);
-        } else if (status != DecodeStatus::kDecodeDone) {
-          QUICHE_DCHECK(state->remaining_payload() > 0 ||
-                        status == DecodeStatus::kDecodeError)
-              << "\nremaining_payload: " << state->remaining_payload()
-              << "\nstatus: " << status << "\nheader: " << frame_header;
-          // Assume in progress.
-          payload_state_ = PayloadState::kResumeDecodingStruct;
-          return status;
-        } else {
-          // The origin's length is longer than the remaining payload.
-          QUICHE_DCHECK_GT(altsvc_fields_.origin_length,
-                           state->remaining_payload());
-          return state->ReportFrameSizeError();
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kDecodingStrings:
-        return DecodeStrings(state, db);
-
-      case PayloadState::kResumeDecodingStruct:
-        status = state->ResumeDecodingStructureInPayload(&altsvc_fields_, db);
-        payload_state_ = PayloadState::kMaybeDecodedStruct;
-        continue;
-    }
-    HTTP2_BUG(http2_bug_163_2) << "PayloadState: " << payload_state_;
-  }
-}
-
-DecodeStatus AltSvcPayloadDecoder::DecodeStrings(FrameDecoderState* state,
-                                                 DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "AltSvcPayloadDecoder::DecodeStrings remaining_payload="
-                 << state->remaining_payload()
-                 << ", db->Remaining=" << db->Remaining();
-  // Note that we don't explicitly keep track of exactly how far through the
-  // origin; instead we compute it from how much is left of the original
-  // payload length and the decoded total length of the origin.
-  size_t origin_length = altsvc_fields_.origin_length;
-  size_t value_length = state->frame_header().payload_length - origin_length -
-                        Http2AltSvcFields::EncodedSize();
-  if (state->remaining_payload() > value_length) {
-    size_t remaining_origin_length = state->remaining_payload() - value_length;
-    size_t avail = db->MinLengthRemaining(remaining_origin_length);
-    state->listener()->OnAltSvcOriginData(db->cursor(), avail);
-    db->AdvanceCursor(avail);
-    state->ConsumePayload(avail);
-    if (remaining_origin_length > avail) {
-      payload_state_ = PayloadState::kDecodingStrings;
-      return DecodeStatus::kDecodeInProgress;
-    }
-  }
-  // All that is left is the value string.
-  QUICHE_DCHECK_LE(state->remaining_payload(), value_length);
-  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
-  if (db->HasData()) {
-    size_t avail = db->Remaining();
-    state->listener()->OnAltSvcValueData(db->cursor(), avail);
-    db->AdvanceCursor(avail);
-    state->ConsumePayload(avail);
-  }
-  if (state->remaining_payload() == 0) {
-    state->listener()->OnAltSvcEnd();
-    return DecodeStatus::kDecodeDone;
-  }
-  payload_state_ = PayloadState::kDecodingStrings;
-  return DecodeStatus::kDecodeInProgress;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/altsvc_payload_decoder.h b/http2/decoder/payload_decoders/altsvc_payload_decoder.h
deleted file mode 100644
index 6a869c5..0000000
--- a/http2/decoder/payload_decoders/altsvc_payload_decoder.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_ALTSVC_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_ALTSVC_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a ALTSVC frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class AltSvcPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE AltSvcPayloadDecoder {
- public:
-  // States during decoding of a ALTSVC frame.
-  enum class PayloadState {
-    // Start decoding the fixed size structure at the start of an ALTSVC
-    // frame (Http2AltSvcFields).
-    kStartDecodingStruct,
-
-    // Handle the DecodeStatus returned from starting or resuming the
-    // decoding of Http2AltSvcFields. If complete, calls OnAltSvcStart.
-    kMaybeDecodedStruct,
-
-    // Reports the value of the strings (origin and value) of an ALTSVC frame
-    // to the listener.
-    kDecodingStrings,
-
-    // The initial decode buffer wasn't large enough for the Http2AltSvcFields,
-    // so this state resumes the decoding when ResumeDecodingPayload is called
-    // later with a new DecodeBuffer.
-    kResumeDecodingStruct,
-  };
-
-  // Starts the decoding of a ALTSVC frame's payload, and completes it if the
-  // entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a ALTSVC frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::AltSvcPayloadDecoderPeer;
-
-  // Implements state kDecodingStrings.
-  DecodeStatus DecodeStrings(FrameDecoderState* state, DecodeBuffer* db);
-
-  Http2AltSvcFields altsvc_fields_;
-  PayloadState payload_state_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_ALTSVC_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc b/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc
deleted file mode 100644
index cecd1f9..0000000
--- a/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/altsvc_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-// Provides friend access to an instance of the payload decoder, and also
-// provides info to aid in testing.
-class AltSvcPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() { return Http2FrameType::ALTSVC; }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnAltSvcStart(const Http2FrameHeader& header,
-                     size_t origin_length,
-                     size_t value_length) override {
-    HTTP2_VLOG(1) << "OnAltSvcStart header: " << header
-                  << "; origin_length=" << origin_length
-                  << "; value_length=" << value_length;
-    StartFrame(header)->OnAltSvcStart(header, origin_length, value_length);
-  }
-
-  void OnAltSvcOriginData(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
-    CurrentFrame()->OnAltSvcOriginData(data, len);
-  }
-
-  void OnAltSvcValueData(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
-    CurrentFrame()->OnAltSvcValueData(data, len);
-  }
-
-  void OnAltSvcEnd() override {
-    HTTP2_VLOG(1) << "OnAltSvcEnd";
-    EndFrame()->OnAltSvcEnd();
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class AltSvcPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<AltSvcPayloadDecoder,
-                                        AltSvcPayloadDecoderPeer,
-                                        Listener> {};
-
-// Confirm we get an error if the payload is not long enough to hold
-// Http2AltSvcFields and the indicated length of origin.
-TEST_F(AltSvcPayloadDecoderTest, Truncated) {
-  Http2FrameBuilder fb;
-  fb.Append(Http2AltSvcFields{0xffff});  // The longest possible origin length.
-  fb.Append("Too little origin!");
-  EXPECT_TRUE(
-      VerifyDetectsFrameSizeError(0, fb.buffer(), /*approve_size*/ nullptr));
-}
-
-class AltSvcPayloadLengthTests : public AltSvcPayloadDecoderTest,
-                                 public ::testing::WithParamInterface<
-                                     ::testing::tuple<uint16_t, uint32_t>> {
- protected:
-  AltSvcPayloadLengthTests()
-      : origin_length_(::testing::get<0>(GetParam())),
-        value_length_(::testing::get<1>(GetParam())) {
-    HTTP2_VLOG(1) << "################  origin_length_=" << origin_length_
-                  << "   value_length_=" << value_length_
-                  << "  ################";
-  }
-
-  const uint16_t origin_length_;
-  const uint32_t value_length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(VariousOriginAndValueLengths,
-                         AltSvcPayloadLengthTests,
-                         ::testing::Combine(::testing::Values(0, 1, 3, 65535),
-                                            ::testing::Values(0, 1, 3, 65537)));
-
-TEST_P(AltSvcPayloadLengthTests, ValidOriginAndValueLength) {
-  std::string origin = Random().RandString(origin_length_);
-  std::string value = Random().RandString(value_length_);
-  Http2FrameBuilder fb;
-  fb.Append(Http2AltSvcFields{origin_length_});
-  fb.Append(origin);
-  fb.Append(value);
-  Http2FrameHeader header(fb.size(), Http2FrameType::ALTSVC, RandFlags(),
-                          RandStreamId());
-  set_frame_header(header);
-  FrameParts expected(header);
-  expected.SetAltSvcExpected(origin, value);
-  ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/continuation_payload_decoder.cc b/http2/decoder/payload_decoders/continuation_payload_decoder.cc
deleted file mode 100644
index 10e9d95..0000000
--- a/http2/decoder/payload_decoders/continuation_payload_decoder.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/continuation_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus ContinuationPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "ContinuationPayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-  QUICHE_DCHECK_EQ(Http2FrameType::CONTINUATION, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::END_HEADERS));
-
-  state->InitializeRemainders();
-  state->listener()->OnContinuationStart(frame_header);
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus ContinuationPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "ContinuationPayloadDecoder::ResumeDecodingPayload"
-                 << "  remaining_payload=" << state->remaining_payload()
-                 << "  db->Remaining=" << db->Remaining();
-  QUICHE_DCHECK_EQ(Http2FrameType::CONTINUATION, state->frame_header().type);
-  QUICHE_DCHECK_LE(state->remaining_payload(),
-                   state->frame_header().payload_length);
-  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
-
-  size_t avail = db->Remaining();
-  QUICHE_DCHECK_LE(avail, state->remaining_payload());
-  if (avail > 0) {
-    state->listener()->OnHpackFragment(db->cursor(), avail);
-    db->AdvanceCursor(avail);
-    state->ConsumePayload(avail);
-  }
-  if (state->remaining_payload() == 0) {
-    state->listener()->OnContinuationEnd();
-    return DecodeStatus::kDecodeDone;
-  }
-  return DecodeStatus::kDecodeInProgress;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/continuation_payload_decoder.h b/http2/decoder/payload_decoders/continuation_payload_decoder.h
deleted file mode 100644
index d4ea98b..0000000
--- a/http2/decoder/payload_decoders/continuation_payload_decoder.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_CONTINUATION_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_CONTINUATION_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a CONTINUATION frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE ContinuationPayloadDecoder {
- public:
-  // Starts the decoding of a CONTINUATION frame's payload, and completes
-  // it if the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a CONTINUATION frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_CONTINUATION_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc b/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc
deleted file mode 100644
index ec88306..0000000
--- a/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/continuation_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-#include <type_traits>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-// Provides friend access to an instance of the payload decoder, and also
-// provides info to aid in testing.
-class ContinuationPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::CONTINUATION;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnContinuationStart(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnContinuationStart: " << header;
-    StartFrame(header)->OnContinuationStart(header);
-  }
-
-  void OnHpackFragment(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
-    CurrentFrame()->OnHpackFragment(data, len);
-  }
-
-  void OnContinuationEnd() override {
-    HTTP2_VLOG(1) << "OnContinuationEnd";
-    EndFrame()->OnContinuationEnd();
-  }
-};
-
-class ContinuationPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<ContinuationPayloadDecoder,
-                                        ContinuationPayloadDecoderPeer,
-                                        Listener>,
-      public ::testing::WithParamInterface<uint32_t> {
- protected:
-  ContinuationPayloadDecoderTest() : length_(GetParam()) {
-    HTTP2_VLOG(1) << "################  length_=" << length_
-                  << "  ################";
-  }
-
-  const uint32_t length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(VariousLengths,
-                         ContinuationPayloadDecoderTest,
-                         ::testing::Values(0, 1, 2, 3, 4, 5, 6));
-
-TEST_P(ContinuationPayloadDecoderTest, ValidLength) {
-  std::string hpack_payload = Random().RandString(length_);
-  Http2FrameHeader frame_header(length_, Http2FrameType::CONTINUATION,
-                                RandFlags(), RandStreamId());
-  set_frame_header(frame_header);
-  FrameParts expected(frame_header, hpack_payload);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(hpack_payload, expected));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/data_payload_decoder.cc b/http2/decoder/payload_decoders/data_payload_decoder.cc
deleted file mode 100644
index 523ead1..0000000
--- a/http2/decoder/payload_decoders/data_payload_decoder.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/data_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         DataPayloadDecoder::PayloadState v) {
-  switch (v) {
-    case DataPayloadDecoder::PayloadState::kReadPadLength:
-      return out << "kReadPadLength";
-    case DataPayloadDecoder::PayloadState::kReadPayload:
-      return out << "kReadPayload";
-    case DataPayloadDecoder::PayloadState::kSkipPadding:
-      return out << "kSkipPadding";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_174_1)
-      << "Invalid DataPayloadDecoder::PayloadState: " << unknown;
-  return out << "DataPayloadDecoder::PayloadState(" << unknown << ")";
-}
-
-DecodeStatus DataPayloadDecoder::StartDecodingPayload(FrameDecoderState* state,
-                                                      DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "DataPayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-  QUICHE_DCHECK_EQ(Http2FrameType::DATA, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::END_STREAM |
-                                             Http2FrameFlag::PADDED));
-
-  // Special case for the hoped for common case: unpadded and fits fully into
-  // the decode buffer. TO BE SEEN if that is true. It certainly requires that
-  // the transport buffers be large (e.g. >> 16KB typically).
-  // TODO(jamessynge) Add counters.
-  HTTP2_DVLOG(2) << "StartDecodingPayload total_length=" << total_length;
-  if (!frame_header.IsPadded()) {
-    HTTP2_DVLOG(2) << "StartDecodingPayload !IsPadded";
-    if (db->Remaining() == total_length) {
-      HTTP2_DVLOG(2) << "StartDecodingPayload all present";
-      // Note that we don't cache the listener field so that the callee can
-      // replace it if the frame is bad.
-      // If this case is common enough, consider combining the 3 callbacks
-      // into one.
-      state->listener()->OnDataStart(frame_header);
-      if (total_length > 0) {
-        state->listener()->OnDataPayload(db->cursor(), total_length);
-        db->AdvanceCursor(total_length);
-      }
-      state->listener()->OnDataEnd();
-      return DecodeStatus::kDecodeDone;
-    }
-    payload_state_ = PayloadState::kReadPayload;
-  } else {
-    payload_state_ = PayloadState::kReadPadLength;
-  }
-  state->InitializeRemainders();
-  state->listener()->OnDataStart(frame_header);
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus DataPayloadDecoder::ResumeDecodingPayload(FrameDecoderState* state,
-                                                       DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "DataPayloadDecoder::ResumeDecodingPayload payload_state_="
-                 << payload_state_;
-  const Http2FrameHeader& frame_header = state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::DATA, frame_header.type);
-  QUICHE_DCHECK_LE(state->remaining_payload_and_padding(),
-                   frame_header.payload_length);
-  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload_and_padding());
-  DecodeStatus status;
-  size_t avail;
-  switch (payload_state_) {
-    case PayloadState::kReadPadLength:
-      // ReadPadLength handles the OnPadLength callback, and updating the
-      // remaining_payload and remaining_padding fields. If the amount of
-      // padding is too large to fit in the frame's payload, ReadPadLength
-      // instead calls OnPaddingTooLong and returns kDecodeError.
-      status = state->ReadPadLength(db, /*report_pad_length*/ true);
-      if (status != DecodeStatus::kDecodeDone) {
-        return status;
-      }
-      ABSL_FALLTHROUGH_INTENDED;
-
-    case PayloadState::kReadPayload:
-      avail = state->AvailablePayload(db);
-      if (avail > 0) {
-        state->listener()->OnDataPayload(db->cursor(), avail);
-        db->AdvanceCursor(avail);
-        state->ConsumePayload(avail);
-      }
-      if (state->remaining_payload() > 0) {
-        payload_state_ = PayloadState::kReadPayload;
-        return DecodeStatus::kDecodeInProgress;
-      }
-      ABSL_FALLTHROUGH_INTENDED;
-
-    case PayloadState::kSkipPadding:
-      // SkipPadding handles the OnPadding callback.
-      if (state->SkipPadding(db)) {
-        state->listener()->OnDataEnd();
-        return DecodeStatus::kDecodeDone;
-      }
-      payload_state_ = PayloadState::kSkipPadding;
-      return DecodeStatus::kDecodeInProgress;
-  }
-  HTTP2_BUG(http2_bug_174_2) << "PayloadState: " << payload_state_;
-  return DecodeStatus::kDecodeError;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/data_payload_decoder.h b/http2/decoder/payload_decoders/data_payload_decoder.h
deleted file mode 100644
index 89fe417..0000000
--- a/http2/decoder/payload_decoders/data_payload_decoder.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_DATA_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_DATA_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a DATA frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class DataPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE DataPayloadDecoder {
- public:
-  // States during decoding of a DATA frame.
-  enum class PayloadState {
-    // The frame is padded and we need to read the PAD_LENGTH field (1 byte),
-    // and then call OnPadLength
-    kReadPadLength,
-
-    // Report the non-padding portion of the payload to the listener's
-    // OnDataPayload method.
-    kReadPayload,
-
-    // The decoder has finished with the non-padding portion of the payload,
-    // and is now ready to skip the trailing padding, if the frame has any.
-    kSkipPadding,
-  };
-
-  // Starts decoding a DATA frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a DATA frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::DataPayloadDecoderPeer;
-
-  PayloadState payload_state_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_DATA_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/data_payload_decoder_test.cc b/http2/decoder/payload_decoders/data_payload_decoder_test.cc
deleted file mode 100644
index aa7b5e8..0000000
--- a/http2/decoder/payload_decoders/data_payload_decoder_test.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/data_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-// Provides friend access to an instance of the payload decoder, and also
-// provides info to aid in testing.
-class DataPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() { return Http2FrameType::DATA; }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
-    return Http2FrameFlag::PADDED;
-  }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnDataStart(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnDataStart: " << header;
-    StartFrame(header)->OnDataStart(header);
-  }
-
-  void OnDataPayload(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnDataPayload: len=" << len;
-    CurrentFrame()->OnDataPayload(data, len);
-  }
-
-  void OnDataEnd() override {
-    HTTP2_VLOG(1) << "OnDataEnd";
-    EndFrame()->OnDataEnd();
-  }
-
-  void OnPadLength(size_t pad_length) override {
-    HTTP2_VLOG(1) << "OnPadLength: " << pad_length;
-    CurrentFrame()->OnPadLength(pad_length);
-  }
-
-  void OnPadding(const char* padding, size_t skipped_length) override {
-    HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
-    CurrentFrame()->OnPadding(padding, skipped_length);
-  }
-
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override {
-    HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
-                  << "    missing_length: " << missing_length;
-    EndFrame()->OnPaddingTooLong(header, missing_length);
-  }
-};
-
-class DataPayloadDecoderTest
-    : public AbstractPaddablePayloadDecoderTest<DataPayloadDecoder,
-                                                DataPayloadDecoderPeer,
-                                                Listener> {
- protected:
-  AssertionResult CreateAndDecodeDataOfSize(size_t data_size) {
-    Reset();
-    uint8_t flags = RandFlags();
-
-    std::string data_payload = Random().RandString(data_size);
-    frame_builder_.Append(data_payload);
-    MaybeAppendTrailingPadding();
-
-    Http2FrameHeader frame_header(frame_builder_.size(), Http2FrameType::DATA,
-                                  flags, RandStreamId());
-    set_frame_header(frame_header);
-    ScrubFlagsOfHeader(&frame_header);
-    FrameParts expected(frame_header, data_payload, total_pad_length_);
-    VERIFY_AND_RETURN_SUCCESS(
-        DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(), expected));
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(VariousPadLengths,
-                         DataPayloadDecoderTest,
-                         ::testing::Values(0, 1, 2, 3, 4, 254, 255, 256));
-
-TEST_P(DataPayloadDecoderTest, VariousDataPayloadSizes) {
-  for (size_t data_size : {0, 1, 2, 3, 255, 256, 1024}) {
-    EXPECT_TRUE(CreateAndDecodeDataOfSize(data_size));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/goaway_payload_decoder.cc b/http2/decoder/payload_decoders/goaway_payload_decoder.cc
deleted file mode 100644
index 3231feb..0000000
--- a/http2/decoder/payload_decoders/goaway_payload_decoder.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/goaway_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         GoAwayPayloadDecoder::PayloadState v) {
-  switch (v) {
-    case GoAwayPayloadDecoder::PayloadState::kStartDecodingFixedFields:
-      return out << "kStartDecodingFixedFields";
-    case GoAwayPayloadDecoder::PayloadState::kHandleFixedFieldsStatus:
-      return out << "kHandleFixedFieldsStatus";
-    case GoAwayPayloadDecoder::PayloadState::kReadOpaqueData:
-      return out << "kReadOpaqueData";
-    case GoAwayPayloadDecoder::PayloadState::kResumeDecodingFixedFields:
-      return out << "kResumeDecodingFixedFields";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_167_1)
-      << "Invalid GoAwayPayloadDecoder::PayloadState: " << unknown;
-  return out << "GoAwayPayloadDecoder::PayloadState(" << unknown << ")";
-}
-
-DecodeStatus GoAwayPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "GoAwayPayloadDecoder::StartDecodingPayload: "
-                 << state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::GOAWAY, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
-
-  state->InitializeRemainders();
-  payload_state_ = PayloadState::kStartDecodingFixedFields;
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus GoAwayPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2)
-      << "GoAwayPayloadDecoder::ResumeDecodingPayload: remaining_payload="
-      << state->remaining_payload() << ", db->Remaining=" << db->Remaining();
-
-  const Http2FrameHeader& frame_header = state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::GOAWAY, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
-  QUICHE_DCHECK_NE(PayloadState::kHandleFixedFieldsStatus, payload_state_);
-
-  // |status| has to be initialized to some value to avoid compiler error in
-  // case PayloadState::kHandleFixedFieldsStatus below, but value does not
-  // matter, see QUICHE_DCHECK_NE above.
-  DecodeStatus status = DecodeStatus::kDecodeError;
-  size_t avail;
-  while (true) {
-    HTTP2_DVLOG(2)
-        << "GoAwayPayloadDecoder::ResumeDecodingPayload payload_state_="
-        << payload_state_;
-    switch (payload_state_) {
-      case PayloadState::kStartDecodingFixedFields:
-        status = state->StartDecodingStructureInPayload(&goaway_fields_, db);
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kHandleFixedFieldsStatus:
-        if (status == DecodeStatus::kDecodeDone) {
-          state->listener()->OnGoAwayStart(frame_header, goaway_fields_);
-        } else {
-          // Not done decoding the structure. Either we've got more payload
-          // to decode, or we've run out because the payload is too short,
-          // in which case OnFrameSizeError will have already been called.
-          QUICHE_DCHECK((status == DecodeStatus::kDecodeInProgress &&
-                         state->remaining_payload() > 0) ||
-                        (status == DecodeStatus::kDecodeError &&
-                         state->remaining_payload() == 0))
-              << "\n status=" << status
-              << "; remaining_payload=" << state->remaining_payload();
-          payload_state_ = PayloadState::kResumeDecodingFixedFields;
-          return status;
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kReadOpaqueData:
-        // The opaque data is all the remains to be decoded, so anything left
-        // in the decode buffer is opaque data.
-        avail = db->Remaining();
-        if (avail > 0) {
-          state->listener()->OnGoAwayOpaqueData(db->cursor(), avail);
-          db->AdvanceCursor(avail);
-          state->ConsumePayload(avail);
-        }
-        if (state->remaining_payload() > 0) {
-          payload_state_ = PayloadState::kReadOpaqueData;
-          return DecodeStatus::kDecodeInProgress;
-        }
-        state->listener()->OnGoAwayEnd();
-        return DecodeStatus::kDecodeDone;
-
-      case PayloadState::kResumeDecodingFixedFields:
-        status = state->ResumeDecodingStructureInPayload(&goaway_fields_, db);
-        payload_state_ = PayloadState::kHandleFixedFieldsStatus;
-        continue;
-    }
-    HTTP2_BUG(http2_bug_167_2) << "PayloadState: " << payload_state_;
-  }
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/goaway_payload_decoder.h b/http2/decoder/payload_decoders/goaway_payload_decoder.h
deleted file mode 100644
index cbffa43..0000000
--- a/http2/decoder/payload_decoders/goaway_payload_decoder.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_GOAWAY_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_GOAWAY_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a GOAWAY frame.
-
-// TODO(jamessynge): Sweep through all payload decoders, changing the names of
-// the PayloadState enums so that they are really states, and not actions.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class GoAwayPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE GoAwayPayloadDecoder {
- public:
-  // States during decoding of a GOAWAY frame.
-  enum class PayloadState {
-    // At the start of the GOAWAY frame payload, ready to start decoding the
-    // fixed size fields into goaway_fields_.
-    kStartDecodingFixedFields,
-
-    // Handle the DecodeStatus returned from starting or resuming the
-    // decoding of Http2GoAwayFields into goaway_fields_. If complete,
-    // calls OnGoAwayStart.
-    kHandleFixedFieldsStatus,
-
-    // Report the Opaque Data portion of the payload to the listener's
-    // OnGoAwayOpaqueData method, and call OnGoAwayEnd when the end of the
-    // payload is reached.
-    kReadOpaqueData,
-
-    // The fixed size fields weren't all available when the decoder first
-    // tried to decode them (state kStartDecodingFixedFields); this state
-    // resumes the decoding when ResumeDecodingPayload is called later.
-    kResumeDecodingFixedFields,
-  };
-
-  // Starts the decoding of a GOAWAY frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a GOAWAY frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::GoAwayPayloadDecoderPeer;
-
-  Http2GoAwayFields goaway_fields_;
-  PayloadState payload_state_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_GOAWAY_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc b/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
deleted file mode 100644
index df64f20..0000000
--- a/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/goaway_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class GoAwayPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() { return Http2FrameType::GOAWAY; }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnGoAwayStart(const Http2FrameHeader& header,
-                     const Http2GoAwayFields& goaway) override {
-    HTTP2_VLOG(1) << "OnGoAwayStart header: " << header
-                  << "; goaway: " << goaway;
-    StartFrame(header)->OnGoAwayStart(header, goaway);
-  }
-
-  void OnGoAwayOpaqueData(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
-    CurrentFrame()->OnGoAwayOpaqueData(data, len);
-  }
-
-  void OnGoAwayEnd() override {
-    HTTP2_VLOG(1) << "OnGoAwayEnd";
-    EndFrame()->OnGoAwayEnd();
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class GoAwayPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<GoAwayPayloadDecoder,
-                                        GoAwayPayloadDecoderPeer,
-                                        Listener> {};
-
-// Confirm we get an error if the payload is not long enough to hold
-// Http2GoAwayFields.
-TEST_F(GoAwayPayloadDecoderTest, Truncated) {
-  auto approve_size = [](size_t size) {
-    return size != Http2GoAwayFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(Http2GoAwayFields(123, Http2ErrorCode::ENHANCE_YOUR_CALM));
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-class GoAwayOpaqueDataLengthTests
-    : public GoAwayPayloadDecoderTest,
-      public ::testing::WithParamInterface<uint32_t> {
- protected:
-  GoAwayOpaqueDataLengthTests() : length_(GetParam()) {
-    HTTP2_VLOG(1) << "################  length_=" << length_
-                  << "  ################";
-  }
-
-  const uint32_t length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(VariousLengths,
-                         GoAwayOpaqueDataLengthTests,
-                         ::testing::Values(0, 1, 2, 3, 4, 5, 6));
-
-TEST_P(GoAwayOpaqueDataLengthTests, ValidLength) {
-  Http2GoAwayFields goaway;
-  Randomize(&goaway, RandomPtr());
-  std::string opaque_data = Random().RandString(length_);
-  Http2FrameBuilder fb;
-  fb.Append(goaway);
-  fb.Append(opaque_data);
-  Http2FrameHeader header(fb.size(), Http2FrameType::GOAWAY, RandFlags(),
-                          RandStreamId());
-  set_frame_header(header);
-  FrameParts expected(header, opaque_data);
-  expected.SetOptGoaway(goaway);
-  ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/headers_payload_decoder.cc b/http2/decoder/payload_decoders/headers_payload_decoder.cc
deleted file mode 100644
index 5ae1f99..0000000
--- a/http2/decoder/payload_decoders/headers_payload_decoder.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/headers_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         HeadersPayloadDecoder::PayloadState v) {
-  switch (v) {
-    case HeadersPayloadDecoder::PayloadState::kReadPadLength:
-      return out << "kReadPadLength";
-    case HeadersPayloadDecoder::PayloadState::kStartDecodingPriorityFields:
-      return out << "kStartDecodingPriorityFields";
-    case HeadersPayloadDecoder::PayloadState::kResumeDecodingPriorityFields:
-      return out << "kResumeDecodingPriorityFields";
-    case HeadersPayloadDecoder::PayloadState::kReadPayload:
-      return out << "kReadPayload";
-    case HeadersPayloadDecoder::PayloadState::kSkipPadding:
-      return out << "kSkipPadding";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_189_1)
-      << "Invalid HeadersPayloadDecoder::PayloadState: " << unknown;
-  return out << "HeadersPayloadDecoder::PayloadState(" << unknown << ")";
-}
-
-DecodeStatus HeadersPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "HeadersPayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-
-  QUICHE_DCHECK_EQ(Http2FrameType::HEADERS, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-  QUICHE_DCHECK_EQ(
-      0, frame_header.flags &
-             ~(Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS |
-               Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY));
-
-  // Special case for HEADERS frames that contain only the HPACK block
-  // (fragment or whole) and that fit fully into the decode buffer.
-  // Why? Unencoded browser GET requests are typically under 1K and HPACK
-  // commonly shrinks request headers by 80%, so we can expect this to
-  // be common.
-  // TODO(jamessynge) Add counters here and to Spdy for determining how
-  // common this situation is. A possible approach is to create a
-  // Http2FrameDecoderListener that counts the callbacks and then forwards
-  // them on to another listener, which makes it easy to add and remove
-  // counting on a connection or even frame basis.
-
-  // PADDED and PRIORITY both extra steps to decode, but if neither flag is
-  // set then we can decode faster.
-  const auto payload_flags = Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY;
-  if (!frame_header.HasAnyFlags(payload_flags)) {
-    HTTP2_DVLOG(2) << "StartDecodingPayload !IsPadded && !HasPriority";
-    if (db->Remaining() == total_length) {
-      HTTP2_DVLOG(2) << "StartDecodingPayload all present";
-      // Note that we don't cache the listener field so that the callee can
-      // replace it if the frame is bad.
-      // If this case is common enough, consider combining the 3 callbacks
-      // into one, especially if END_HEADERS is also set.
-      state->listener()->OnHeadersStart(frame_header);
-      if (total_length > 0) {
-        state->listener()->OnHpackFragment(db->cursor(), total_length);
-        db->AdvanceCursor(total_length);
-      }
-      state->listener()->OnHeadersEnd();
-      return DecodeStatus::kDecodeDone;
-    }
-    payload_state_ = PayloadState::kReadPayload;
-  } else if (frame_header.IsPadded()) {
-    payload_state_ = PayloadState::kReadPadLength;
-  } else {
-    QUICHE_DCHECK(frame_header.HasPriority()) << frame_header;
-    payload_state_ = PayloadState::kStartDecodingPriorityFields;
-  }
-  state->InitializeRemainders();
-  state->listener()->OnHeadersStart(frame_header);
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus HeadersPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "HeadersPayloadDecoder::ResumeDecodingPayload "
-                 << "remaining_payload=" << state->remaining_payload()
-                 << "; db->Remaining=" << db->Remaining();
-
-  const Http2FrameHeader& frame_header = state->frame_header();
-
-  QUICHE_DCHECK_EQ(Http2FrameType::HEADERS, frame_header.type);
-  QUICHE_DCHECK_LE(state->remaining_payload_and_padding(),
-                   frame_header.payload_length);
-  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload_and_padding());
-  DecodeStatus status;
-  size_t avail;
-  while (true) {
-    HTTP2_DVLOG(2)
-        << "HeadersPayloadDecoder::ResumeDecodingPayload payload_state_="
-        << payload_state_;
-    switch (payload_state_) {
-      case PayloadState::kReadPadLength:
-        // ReadPadLength handles the OnPadLength callback, and updating the
-        // remaining_payload and remaining_padding fields. If the amount of
-        // padding is too large to fit in the frame's payload, ReadPadLength
-        // instead calls OnPaddingTooLong and returns kDecodeError.
-        status = state->ReadPadLength(db, /*report_pad_length*/ true);
-        if (status != DecodeStatus::kDecodeDone) {
-          return status;
-        }
-        if (!frame_header.HasPriority()) {
-          payload_state_ = PayloadState::kReadPayload;
-          continue;
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kStartDecodingPriorityFields:
-        status = state->StartDecodingStructureInPayload(&priority_fields_, db);
-        if (status != DecodeStatus::kDecodeDone) {
-          payload_state_ = PayloadState::kResumeDecodingPriorityFields;
-          return status;
-        }
-        state->listener()->OnHeadersPriority(priority_fields_);
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kReadPayload:
-        avail = state->AvailablePayload(db);
-        if (avail > 0) {
-          state->listener()->OnHpackFragment(db->cursor(), avail);
-          db->AdvanceCursor(avail);
-          state->ConsumePayload(avail);
-        }
-        if (state->remaining_payload() > 0) {
-          payload_state_ = PayloadState::kReadPayload;
-          return DecodeStatus::kDecodeInProgress;
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kSkipPadding:
-        // SkipPadding handles the OnPadding callback.
-        if (state->SkipPadding(db)) {
-          state->listener()->OnHeadersEnd();
-          return DecodeStatus::kDecodeDone;
-        }
-        payload_state_ = PayloadState::kSkipPadding;
-        return DecodeStatus::kDecodeInProgress;
-
-      case PayloadState::kResumeDecodingPriorityFields:
-        status = state->ResumeDecodingStructureInPayload(&priority_fields_, db);
-        if (status != DecodeStatus::kDecodeDone) {
-          return status;
-        }
-        state->listener()->OnHeadersPriority(priority_fields_);
-        payload_state_ = PayloadState::kReadPayload;
-        continue;
-    }
-    HTTP2_BUG(http2_bug_189_2) << "PayloadState: " << payload_state_;
-  }
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/headers_payload_decoder.h b/http2/decoder/payload_decoders/headers_payload_decoder.h
deleted file mode 100644
index c56417d..0000000
--- a/http2/decoder/payload_decoders/headers_payload_decoder.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_HEADERS_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_HEADERS_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a HEADERS frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class HeadersPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE HeadersPayloadDecoder {
- public:
-  // States during decoding of a HEADERS frame, unless the fast path kicks
-  // in, in which case the state machine will be bypassed.
-  enum class PayloadState {
-    // The PADDED flag is set, and we now need to read the Pad Length field
-    // (the first byte of the payload, after the common frame header).
-    kReadPadLength,
-
-    // The PRIORITY flag is set, and we now need to read the fixed size priority
-    // fields (E, Stream Dependency, Weight) into priority_fields_.  Calls on
-    // OnHeadersPriority if completely decodes those fields.
-    kStartDecodingPriorityFields,
-
-    // The decoder passes the non-padding portion of the remaining payload
-    // (i.e. the HPACK block fragment) to the listener's OnHpackFragment method.
-    kReadPayload,
-
-    // The decoder has finished with the HPACK block fragment, and is now
-    // ready to skip the trailing padding, if the frame has any.
-    kSkipPadding,
-
-    // The fixed size fields weren't all available when the decoder first tried
-    // to decode them (state kStartDecodingPriorityFields); this state resumes
-    // the decoding when ResumeDecodingPayload is called later.
-    kResumeDecodingPriorityFields,
-  };
-
-  // Starts the decoding of a HEADERS frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a HEADERS frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::HeadersPayloadDecoderPeer;
-
-  PayloadState payload_state_;
-  Http2PriorityFields priority_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_HEADERS_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/headers_payload_decoder_test.cc b/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
deleted file mode 100644
index a217233..0000000
--- a/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/headers_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class HeadersPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::HEADERS;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
-    return Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY;
-  }
-};
-
-namespace {
-
-// Listener handles all On* methods that are expected to be called. If any other
-// On* methods of Http2FrameDecoderListener is called then the test fails; this
-// is achieved by way of FailingHttp2FrameDecoderListener, the base class of
-// FramePartsCollector.
-// These On* methods make use of StartFrame, EndFrame, etc. of the base class
-// to create and access to FrameParts instance(s) that will record the details.
-// After decoding, the test validation code can access the FramePart instance(s)
-// via the public methods of FramePartsCollector.
-struct Listener : public FramePartsCollector {
-  void OnHeadersStart(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnHeadersStart: " << header;
-    StartFrame(header)->OnHeadersStart(header);
-  }
-
-  void OnHeadersPriority(const Http2PriorityFields& priority) override {
-    HTTP2_VLOG(1) << "OnHeadersPriority: " << priority;
-    CurrentFrame()->OnHeadersPriority(priority);
-  }
-
-  void OnHpackFragment(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
-    CurrentFrame()->OnHpackFragment(data, len);
-  }
-
-  void OnHeadersEnd() override {
-    HTTP2_VLOG(1) << "OnHeadersEnd";
-    EndFrame()->OnHeadersEnd();
-  }
-
-  void OnPadLength(size_t pad_length) override {
-    HTTP2_VLOG(1) << "OnPadLength: " << pad_length;
-    CurrentFrame()->OnPadLength(pad_length);
-  }
-
-  void OnPadding(const char* padding, size_t skipped_length) override {
-    HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
-    CurrentFrame()->OnPadding(padding, skipped_length);
-  }
-
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override {
-    HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
-                  << "; missing_length: " << missing_length;
-    FrameError(header)->OnPaddingTooLong(header, missing_length);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class HeadersPayloadDecoderTest
-    : public AbstractPaddablePayloadDecoderTest<HeadersPayloadDecoder,
-                                                HeadersPayloadDecoderPeer,
-                                                Listener> {};
-
-INSTANTIATE_TEST_SUITE_P(VariousPadLengths,
-                         HeadersPayloadDecoderTest,
-                         ::testing::Values(0, 1, 2, 3, 4, 254, 255, 256));
-
-// Decode various sizes of (fake) HPACK payload, both with and without the
-// PRIORITY flag set.
-TEST_P(HeadersPayloadDecoderTest, VariousHpackPayloadSizes) {
-  for (size_t hpack_size : {0, 1, 2, 3, 255, 256, 1024}) {
-    HTTP2_LOG(INFO) << "###########   hpack_size = " << hpack_size
-                    << "  ###########";
-    Http2PriorityFields priority(RandStreamId(), 1 + Random().Rand8(),
-                                 Random().OneIn(2));
-
-    for (bool has_priority : {false, true}) {
-      Reset();
-      ASSERT_EQ(IsPadded() ? 1u : 0u, frame_builder_.size());
-      uint8_t flags = RandFlags();
-      if (has_priority) {
-        flags |= Http2FrameFlag::PRIORITY;
-        frame_builder_.Append(priority);
-      }
-
-      std::string hpack_payload = Random().RandString(hpack_size);
-      frame_builder_.Append(hpack_payload);
-
-      MaybeAppendTrailingPadding();
-      Http2FrameHeader frame_header(frame_builder_.size(),
-                                    Http2FrameType::HEADERS, flags,
-                                    RandStreamId());
-      set_frame_header(frame_header);
-      ScrubFlagsOfHeader(&frame_header);
-      FrameParts expected(frame_header, hpack_payload, total_pad_length_);
-      if (has_priority) {
-        expected.SetOptPriority(priority);
-      }
-      EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(),
-                                                      expected));
-    }
-  }
-}
-
-// Confirm we get an error if the PRIORITY flag is set but the payload is
-// not long enough, regardless of the amount of (valid) padding.
-TEST_P(HeadersPayloadDecoderTest, Truncated) {
-  auto approve_size = [](size_t size) {
-    return size != Http2PriorityFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(Http2PriorityFields(RandStreamId(), 1 + Random().Rand8(),
-                                Random().OneIn(2)));
-  EXPECT_TRUE(VerifyDetectsMultipleFrameSizeErrors(
-      Http2FrameFlag::PRIORITY, fb.buffer(), approve_size, total_pad_length_));
-}
-
-// Confirm we get an error if the PADDED flag is set but the payload is not
-// long enough to hold even the Pad Length amount of padding.
-TEST_P(HeadersPayloadDecoderTest, PaddingTooLong) {
-  EXPECT_TRUE(VerifyDetectsPaddingTooLong());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc b/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc
deleted file mode 100644
index a393f4c..0000000
--- a/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-
-#include "http2/decoder/frame_decoder_state_test_util.h"
-#include "http2/http2_structures_test_util.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-PayloadDecoderBaseTest::PayloadDecoderBaseTest() {
-  // If the test adds more data after the frame payload,
-  // stop as soon as the payload is decoded.
-  stop_decode_on_done_ = true;
-  frame_header_is_set_ = false;
-  Randomize(&frame_header_, RandomPtr());
-}
-
-DecodeStatus PayloadDecoderBaseTest::StartDecoding(DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining();
-  // Make sure sub-class has set frame_header_ so that we can inject it
-  // into the payload decoder below.
-  if (!frame_header_is_set_) {
-    ADD_FAILURE() << "frame_header_ is not set";
-    return DecodeStatus::kDecodeError;
-  }
-  // The contract with the payload decoders is that they won't receive a
-  // decode buffer that extends beyond the end of the frame.
-  if (db->Remaining() > frame_header_.payload_length) {
-    ADD_FAILURE() << "DecodeBuffer has too much data: " << db->Remaining()
-                  << " > " << frame_header_.payload_length;
-    return DecodeStatus::kDecodeError;
-  }
-
-  // Prepare the payload decoder.
-  PreparePayloadDecoder();
-
-  // Reconstruct the FrameDecoderState, prepare the listener, and add it to
-  // the FrameDecoderState.
-  frame_decoder_state_ = std::make_unique<FrameDecoderState>();
-  frame_decoder_state_->set_listener(PrepareListener());
-
-  // Make sure that a listener was provided.
-  if (frame_decoder_state_->listener() == nullptr) {
-    ADD_FAILURE() << "PrepareListener must return a listener.";
-    return DecodeStatus::kDecodeError;
-  }
-
-  // Now that nothing in the payload decoder should be valid, inject the
-  // Http2FrameHeader whose payload we're about to decode. That header is the
-  // only state that a payload decoder should expect is valid when its Start
-  // method is called.
-  FrameDecoderStatePeer::set_frame_header(frame_header_,
-                                          frame_decoder_state_.get());
-  DecodeStatus status = StartDecodingPayload(db);
-  if (status != DecodeStatus::kDecodeInProgress) {
-    // Keep track of this so that a concrete test can verify that both fast
-    // and slow decoding paths have been tested.
-    ++fast_decode_count_;
-  }
-  return status;
-}
-
-DecodeStatus PayloadDecoderBaseTest::ResumeDecoding(DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining();
-  DecodeStatus status = ResumeDecodingPayload(db);
-  if (status != DecodeStatus::kDecodeInProgress) {
-    // Keep track of this so that a concrete test can verify that both fast
-    // and slow decoding paths have been tested.
-    ++slow_decode_count_;
-  }
-  return status;
-}
-
-::testing::AssertionResult
-PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
-    absl::string_view payload,
-    Validator validator) {
-  VERIFY_TRUE(frame_header_is_set_);
-  // Cap the payload to be decoded at the declared payload length. This is
-  // required by the decoders' preconditions; they are designed on the
-  // assumption that they're never passed more than they're permitted to
-  // consume.
-  // Note that it is OK if the payload is too short; the validator may be
-  // designed to check for that.
-  if (payload.size() > frame_header_.payload_length) {
-    payload = absl::string_view(payload.data(), frame_header_.payload_length);
-  }
-  DecodeBuffer db(payload);
-  ResetDecodeSpeedCounters();
-  const bool kMayReturnZeroOnFirst = false;
-  return DecodeAndValidateSeveralWays(&db, kMayReturnZeroOnFirst, validator);
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/payload_decoder_base_test_util.h b/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
deleted file mode 100644
index feea5e5..0000000
--- a/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
+++ /dev/null
@@ -1,449 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
-
-// Base class for testing concrete payload decoder classes.
-
-#include <stddef.h>
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_constants_test_util.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-
-namespace http2 {
-namespace test {
-
-// Base class for tests of payload decoders. Below this there is a templated
-// sub-class that adds a bunch of type specific features.
-class PayloadDecoderBaseTest : public RandomDecoderTest {
- protected:
-  PayloadDecoderBaseTest();
-
-  // Virtual functions to be implemented by the test classes for the individual
-  // payload decoders...
-
-  // Start decoding the payload.
-  virtual DecodeStatus StartDecodingPayload(DecodeBuffer* db) = 0;
-
-  // Resume decoding the payload.
-  virtual DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) = 0;
-
-  // In support of ensuring that we're really accessing and updating the
-  // decoder, prepare the decoder by, for example, overwriting the decoder.
-  virtual void PreparePayloadDecoder() = 0;
-
-  // Get the listener to be inserted into the FrameDecoderState, ready for
-  // listening (e.g. reset if it is a FramePartsCollector).
-  virtual Http2FrameDecoderListener* PrepareListener() = 0;
-
-  // Record a frame header for use on each call to StartDecoding.
-  void set_frame_header(const Http2FrameHeader& header) {
-    EXPECT_EQ(0, InvalidFlagMaskForFrameType(header.type) & header.flags);
-    if (!frame_header_is_set_ || frame_header_ != header) {
-      HTTP2_VLOG(2) << "set_frame_header: " << frame_header_;
-    }
-    frame_header_ = header;
-    frame_header_is_set_ = true;
-  }
-
-  FrameDecoderState* mutable_state() { return frame_decoder_state_.get(); }
-
-  // Randomize the payload decoder, sets the payload decoder's frame_header_,
-  // then start decoding the payload. Called by RandomDecoderTest. This method
-  // is final so that we can always perform certain actions when
-  // RandomDecoderTest starts the decoding of a payload, such as randomizing the
-  // the payload decoder, injecting the frame header and counting fast decoding
-  // cases. Sub-classes must implement StartDecodingPayload to perform their
-  // initial decoding of a frame's payload.
-  DecodeStatus StartDecoding(DecodeBuffer* db) final;
-
-  // Called by RandomDecoderTest. This method is final so that we can always
-  // perform certain actions when RandomDecoderTest calls it, such as counting
-  // slow decode cases. Sub-classes must implement ResumeDecodingPayload to
-  // continue decoding the frame's payload, which must not all be in one buffer.
-  DecodeStatus ResumeDecoding(DecodeBuffer* db) final;
-
-  // Given the specified payload (without the common frame header), decode
-  // it with several partitionings of the payload.
-  ::testing::AssertionResult DecodePayloadAndValidateSeveralWays(
-      absl::string_view payload,
-      Validator validator);
-
-  // TODO(jamessynge): Add helper method for verifying these are both non-zero,
-  // and call the new method from tests that expect successful decoding.
-  void ResetDecodeSpeedCounters() {
-    fast_decode_count_ = 0;
-    slow_decode_count_ = 0;
-  }
-
-  // Count of payloads that are full decoded by StartDecodingPayload, or that
-  // an error was detected by StartDecodingPayload.
-  size_t fast_decode_count_ = 0;
-
-  // Count of payloads that require calling ResumeDecodingPayload in order to
-  // decode them completely (or to detect an error during decoding).
-  size_t slow_decode_count_ = 0;
-
- private:
-  bool frame_header_is_set_ = false;
-  Http2FrameHeader frame_header_;
-  std::unique_ptr<FrameDecoderState> frame_decoder_state_;
-};
-
-// Base class for payload decoders of type Decoder, with corresponding test
-// peer of type DecoderPeer, and using class Listener as the implementation
-// of Http2FrameDecoderListenerInterface to be used during decoding.
-// Typically Listener is a sub-class of FramePartsCollector.
-// SupportedFrameType is set to false only for UnknownPayloadDecoder.
-template <class Decoder,
-          class DecoderPeer,
-          class Listener,
-          bool SupportedFrameType = true>
-class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest {
- protected:
-  // An ApproveSize function returns true to approve decoding the specified
-  // size of payload, else false to skip that size. Typically used for negative
-  // tests; for example, decoding a SETTINGS frame at all sizes except for
-  // multiples of 6.
-  typedef std::function<bool(size_t size)> ApproveSize;
-
-  AbstractPayloadDecoderTest() {}
-
-  // These tests are in setup rather than the constructor for two reasons:
-  // 1) Constructors are not allowed to fail, so gUnit documents that EXPECT_*
-  //    and ASSERT_* are not allowed in constructors, and should instead be in
-  //    SetUp if they are needed before the body of the test is executed.
-  // 2) To allow the sub-class constructor to make any desired modifications to
-  //    the DecoderPeer before these tests are executed; in particular,
-  //    UnknownPayloadDecoderPeer has not got a fixed frame type, but it is
-  //    instead set during the test's constructor.
-  void SetUp() override {
-    PayloadDecoderBaseTest::SetUp();
-
-    // Confirm that DecoderPeer et al returns sensible values. Using auto as the
-    // variable type so that no (narrowing) conversions take place that hide
-    // problems; i.e. if someone changes KnownFlagsMaskForFrameType so that it
-    // doesn't return a uint8, and has bits above the low-order 8 bits set, this
-    // bit of paranoia should detect the problem before we get too far.
-    auto frame_type = DecoderPeer::FrameType();
-    if (SupportedFrameType) {
-      EXPECT_TRUE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
-    } else {
-      EXPECT_FALSE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
-    }
-
-    auto known_flags = KnownFlagsMaskForFrameType(frame_type);
-    EXPECT_EQ(known_flags, known_flags & 0xff);
-
-    auto flags_to_avoid = DecoderPeer::FlagsAffectingPayloadDecoding();
-    EXPECT_EQ(flags_to_avoid, flags_to_avoid & known_flags);
-  }
-
-  void PreparePayloadDecoder() override {
-    payload_decoder_ = std::make_unique<Decoder>();
-  }
-
-  Http2FrameDecoderListener* PrepareListener() override {
-    listener_.Reset();
-    return &listener_;
-  }
-
-  // Returns random flags, but only those valid for the frame type, yet not
-  // those that the DecoderPeer says will affect the decoding of the payload
-  // (e.g. the PRIORTY flag on a HEADERS frame or PADDED on DATA frames).
-  uint8_t RandFlags() {
-    return Random().Rand8() &
-           KnownFlagsMaskForFrameType(DecoderPeer::FrameType()) &
-           ~DecoderPeer::FlagsAffectingPayloadDecoding();
-  }
-
-  // Start decoding the payload.
-  DecodeStatus StartDecodingPayload(DecodeBuffer* db) override {
-    HTTP2_DVLOG(2) << "StartDecodingPayload, db->Remaining=" << db->Remaining();
-    return payload_decoder_->StartDecodingPayload(mutable_state(), db);
-  }
-
-  // Resume decoding the payload.
-  DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) override {
-    HTTP2_DVLOG(2) << "ResumeDecodingPayload, db->Remaining="
-                   << db->Remaining();
-    return payload_decoder_->ResumeDecodingPayload(mutable_state(), db);
-  }
-
-  // Decode one frame's payload and confirm that the listener recorded the
-  // expected FrameParts instance, and only FrameParts instance. The payload
-  // will be decoded several times with different partitionings of the payload,
-  // and after each the validator will be called.
-  AssertionResult DecodePayloadAndValidateSeveralWays(
-      absl::string_view payload,
-      const FrameParts& expected) {
-    auto validator = [&expected, this]() -> AssertionResult {
-      VERIFY_FALSE(listener_.IsInProgress());
-      VERIFY_EQ(1u, listener_.size());
-      VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*listener_.frame(0)));
-    };
-    return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
-        payload, ValidateDoneAndEmpty(validator));
-  }
-
-  // Decode one frame's payload, expecting that the final status will be
-  // kDecodeError, and that OnFrameSizeError will have been called on the
-  // listener. The payload will be decoded several times with different
-  // partitionings of the payload. The type WrappedValidator is either
-  // RandomDecoderTest::Validator, RandomDecoderTest::NoArgValidator or
-  // std::nullptr_t (not extra validation).
-  template <typename WrappedValidator>
-  ::testing::AssertionResult VerifyDetectsFrameSizeError(
-      absl::string_view payload,
-      const Http2FrameHeader& header,
-      WrappedValidator wrapped_validator) {
-    set_frame_header(header);
-    // If wrapped_validator is not a RandomDecoderTest::Validator, make it so.
-    Validator validator = ToValidator(wrapped_validator);
-    // And wrap that validator in another which will check that we've reached
-    // the expected state of kDecodeError with OnFrameSizeError having been
-    // called by the payload decoder.
-    validator = [header, validator, this](
-                    const DecodeBuffer& input,
-                    DecodeStatus status) -> ::testing::AssertionResult {
-      HTTP2_DVLOG(2) << "VerifyDetectsFrameSizeError validator; status="
-                     << status << "; input.Remaining=" << input.Remaining();
-      VERIFY_EQ(DecodeStatus::kDecodeError, status);
-      VERIFY_FALSE(listener_.IsInProgress());
-      VERIFY_EQ(1u, listener_.size());
-      const FrameParts* frame = listener_.frame(0);
-      VERIFY_EQ(header, frame->GetFrameHeader());
-      VERIFY_TRUE(frame->GetHasFrameSizeError());
-      // Verify did not get OnPaddingTooLong, as we should only ever produce
-      // one of these two errors for a single frame.
-      VERIFY_FALSE(frame->GetOptMissingLength());
-      return validator(input, status);
-    };
-    VERIFY_AND_RETURN_SUCCESS(
-        PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(payload,
-                                                                    validator));
-  }
-
-  // Confirm that we get OnFrameSizeError when trying to decode unpadded_payload
-  // at all sizes from zero to unpadded_payload.size(), except those sizes not
-  // approved by approve_size.
-  // If total_pad_length is greater than zero, then that amount of padding
-  // is added to the payload (including the Pad Length field).
-  // The flags will be required_flags, PADDED if total_pad_length > 0, and some
-  // randomly selected flag bits not excluded by FlagsAffectingPayloadDecoding.
-  ::testing::AssertionResult VerifyDetectsMultipleFrameSizeErrors(
-      uint8_t required_flags,
-      absl::string_view unpadded_payload,
-      ApproveSize approve_size,
-      int total_pad_length) {
-    // required_flags should come from those that are defined for the frame
-    // type AND are those that affect the decoding of the payload (otherwise,
-    // the flag shouldn't be required).
-    Http2FrameType frame_type = DecoderPeer::FrameType();
-    VERIFY_EQ(required_flags,
-              required_flags & KnownFlagsMaskForFrameType(frame_type));
-    VERIFY_EQ(required_flags,
-              required_flags & DecoderPeer::FlagsAffectingPayloadDecoding());
-
-    if (0 !=
-        (Http2FrameFlag::PADDED & KnownFlagsMaskForFrameType(frame_type))) {
-      // Frame type supports padding.
-      if (total_pad_length == 0) {
-        required_flags &= ~Http2FrameFlag::PADDED;
-      } else {
-        required_flags |= Http2FrameFlag::PADDED;
-      }
-    } else {
-      VERIFY_EQ(0, total_pad_length);
-    }
-
-    bool validated = false;
-    for (size_t real_payload_size = 0;
-         real_payload_size <= unpadded_payload.size(); ++real_payload_size) {
-      if (approve_size != nullptr && !approve_size(real_payload_size)) {
-        continue;
-      }
-      HTTP2_VLOG(1) << "real_payload_size=" << real_payload_size;
-      uint8_t flags = required_flags | RandFlags();
-      Http2FrameBuilder fb;
-      if (total_pad_length > 0) {
-        // total_pad_length_ includes the size of the Pad Length field, and thus
-        // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
-        fb.AppendUInt8(total_pad_length - 1);
-      }
-      // Append a subset of the unpadded_payload, which the decoder should
-      // determine is not a valid amount.
-      fb.Append(unpadded_payload.substr(0, real_payload_size));
-      if (total_pad_length > 0) {
-        fb.AppendZeroes(total_pad_length - 1);
-      }
-      // We choose a random stream id because the payload decoders aren't
-      // checking stream ids.
-      uint32_t stream_id = RandStreamId();
-      Http2FrameHeader header(fb.size(), frame_type, flags, stream_id);
-      VERIFY_SUCCESS(VerifyDetectsFrameSizeError(fb.buffer(), header, nullptr));
-      validated = true;
-    }
-    VERIFY_TRUE(validated);
-    return ::testing::AssertionSuccess();
-  }
-
-  // As above, but for frames without padding.
-  ::testing::AssertionResult VerifyDetectsFrameSizeError(
-      uint8_t required_flags,
-      absl::string_view unpadded_payload,
-      const ApproveSize& approve_size) {
-    Http2FrameType frame_type = DecoderPeer::FrameType();
-    uint8_t known_flags = KnownFlagsMaskForFrameType(frame_type);
-    VERIFY_EQ(0, known_flags & Http2FrameFlag::PADDED);
-    VERIFY_EQ(0, required_flags & Http2FrameFlag::PADDED);
-    VERIFY_AND_RETURN_SUCCESS(VerifyDetectsMultipleFrameSizeErrors(
-        required_flags, unpadded_payload, approve_size, 0));
-  }
-
-  Listener listener_;
-  std::unique_ptr<Decoder> payload_decoder_;
-};
-
-// A base class for tests parameterized by the total number of bytes of
-// padding, including the Pad Length field (i.e. a total_pad_length of 0
-// means unpadded as there is then no room for the Pad Length field).
-// The frame type must support padding.
-template <class Decoder, class DecoderPeer, class Listener>
-class AbstractPaddablePayloadDecoderTest
-    : public AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener>,
-      public ::testing::WithParamInterface<int> {
-  typedef AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener> Base;
-
- protected:
-  using Base::listener_;
-  using Base::Random;
-  using Base::RandStreamId;
-  using Base::set_frame_header;
-  typedef typename Base::Validator Validator;
-
-  AbstractPaddablePayloadDecoderTest() : total_pad_length_(GetParam()) {
-    HTTP2_LOG(INFO) << "total_pad_length_ = " << total_pad_length_;
-  }
-
-  // Note that total_pad_length_ includes the size of the Pad Length field,
-  // and thus ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
-  bool IsPadded() const { return total_pad_length_ > 0; }
-
-  // Value of the Pad Length field. Only call if IsPadded.
-  size_t pad_length() const {
-    EXPECT_TRUE(IsPadded());
-    return total_pad_length_ - 1;
-  }
-
-  // Clear the frame builder and add the Pad Length field if appropriate.
-  void Reset() {
-    frame_builder_ = Http2FrameBuilder();
-    if (IsPadded()) {
-      frame_builder_.AppendUInt8(pad_length());
-    }
-  }
-
-  void MaybeAppendTrailingPadding() {
-    if (IsPadded()) {
-      frame_builder_.AppendZeroes(pad_length());
-    }
-  }
-
-  uint8_t RandFlags() {
-    uint8_t flags = Base::RandFlags();
-    if (IsPadded()) {
-      flags |= Http2FrameFlag::PADDED;
-    } else {
-      flags &= ~Http2FrameFlag::PADDED;
-    }
-    return flags;
-  }
-
-  // Verify that we get OnPaddingTooLong when decoding payload, and that the
-  // amount of missing padding is as specified. header.IsPadded must be true,
-  // and the payload must be empty or the PadLength field must be too large.
-  ::testing::AssertionResult VerifyDetectsPaddingTooLong(
-      absl::string_view payload,
-      const Http2FrameHeader& header,
-      size_t expected_missing_length) {
-    set_frame_header(header);
-    auto& listener = listener_;
-    Validator validator =
-        [header, expected_missing_length, &listener](
-            const DecodeBuffer&,
-            DecodeStatus status) -> ::testing::AssertionResult {
-      VERIFY_EQ(DecodeStatus::kDecodeError, status);
-      VERIFY_FALSE(listener.IsInProgress());
-      VERIFY_EQ(1u, listener.size());
-      const FrameParts* frame = listener.frame(0);
-      VERIFY_EQ(header, frame->GetFrameHeader());
-      VERIFY_TRUE(frame->GetOptMissingLength());
-      VERIFY_EQ(expected_missing_length, frame->GetOptMissingLength().value());
-      // Verify did not get OnFrameSizeError.
-      VERIFY_FALSE(frame->GetHasFrameSizeError());
-      return ::testing::AssertionSuccess();
-    };
-    VERIFY_AND_RETURN_SUCCESS(
-        PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(payload,
-                                                                    validator));
-  }
-
-  // Verifies that we get OnPaddingTooLong for a padded frame payload whose
-  // (randomly selected) payload length is less than total_pad_length_.
-  // Flags will be selected at random, except PADDED will be set and
-  // flags_to_avoid will not be set. The stream id is selected at random.
-  ::testing::AssertionResult VerifyDetectsPaddingTooLong() {
-    uint8_t flags = RandFlags() | Http2FrameFlag::PADDED;
-
-    // Create an all padding payload for total_pad_length_.
-    int payload_length = 0;
-    Http2FrameBuilder fb;
-    if (IsPadded()) {
-      fb.AppendUInt8(pad_length());
-      fb.AppendZeroes(pad_length());
-      HTTP2_VLOG(1) << "fb.size=" << fb.size();
-      // Pick a random length for the payload that is shorter than neccesary.
-      payload_length = Random().Uniform(fb.size());
-    }
-
-    HTTP2_VLOG(1) << "payload_length=" << payload_length;
-    std::string payload = fb.buffer().substr(0, payload_length);
-
-    // The missing length is the amount we cut off the end, unless
-    // payload_length is zero, in which case the decoder knows only that 1
-    // byte, the Pad Length field, is missing.
-    size_t missing_length =
-        payload_length == 0 ? 1 : fb.size() - payload_length;
-    HTTP2_VLOG(1) << "missing_length=" << missing_length;
-
-    const Http2FrameHeader header(payload_length, DecoderPeer::FrameType(),
-                                  flags, RandStreamId());
-    VERIFY_AND_RETURN_SUCCESS(
-        VerifyDetectsPaddingTooLong(payload, header, missing_length));
-  }
-
-  // total_pad_length_ includes the size of the Pad Length field, and thus
-  // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
-  const size_t total_pad_length_;
-  Http2FrameBuilder frame_builder_;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
diff --git a/http2/decoder/payload_decoders/ping_payload_decoder.cc b/http2/decoder/payload_decoders/ping_payload_decoder.cc
deleted file mode 100644
index 6c73cf7..0000000
--- a/http2/decoder/payload_decoders/ping_payload_decoder.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/ping_payload_decoder.h"
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-namespace {
-constexpr auto kOpaqueSize = Http2PingFields::EncodedSize();
-}
-
-DecodeStatus PingPayloadDecoder::StartDecodingPayload(FrameDecoderState* state,
-                                                      DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "PingPayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-  QUICHE_DCHECK_EQ(Http2FrameType::PING, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::ACK));
-
-  // Is the payload entirely in the decode buffer and is it the correct size?
-  // Given the size of the header and payload (17 bytes total), this is most
-  // likely the case the vast majority of the time.
-  if (db->Remaining() == kOpaqueSize && total_length == kOpaqueSize) {
-    // Special case this situation as it allows us to avoid any copying;
-    // the other path makes two copies, first into the buffer in
-    // Http2StructureDecoder as it accumulates the 8 bytes of opaque data,
-    // and a second copy into the Http2PingFields member of in this class.
-    // This supports the claim that this decoder is (mostly) non-buffering.
-    static_assert(sizeof(Http2PingFields) == kOpaqueSize,
-                  "If not, then can't enter this block!");
-    auto* ping = reinterpret_cast<const Http2PingFields*>(db->cursor());
-    if (frame_header.IsAck()) {
-      state->listener()->OnPingAck(frame_header, *ping);
-    } else {
-      state->listener()->OnPing(frame_header, *ping);
-    }
-    db->AdvanceCursor(kOpaqueSize);
-    return DecodeStatus::kDecodeDone;
-  }
-  state->InitializeRemainders();
-  return HandleStatus(
-      state, state->StartDecodingStructureInPayload(&ping_fields_, db));
-}
-
-DecodeStatus PingPayloadDecoder::ResumeDecodingPayload(FrameDecoderState* state,
-                                                       DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "ResumeDecodingPayload: remaining_payload="
-                 << state->remaining_payload();
-  QUICHE_DCHECK_EQ(Http2FrameType::PING, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  return HandleStatus(
-      state, state->ResumeDecodingStructureInPayload(&ping_fields_, db));
-}
-
-DecodeStatus PingPayloadDecoder::HandleStatus(FrameDecoderState* state,
-                                              DecodeStatus status) {
-  HTTP2_DVLOG(2) << "HandleStatus: status=" << status
-                 << "; remaining_payload=" << state->remaining_payload();
-  if (status == DecodeStatus::kDecodeDone) {
-    if (state->remaining_payload() == 0) {
-      const Http2FrameHeader& frame_header = state->frame_header();
-      if (frame_header.IsAck()) {
-        state->listener()->OnPingAck(frame_header, ping_fields_);
-      } else {
-        state->listener()->OnPing(frame_header, ping_fields_);
-      }
-      return DecodeStatus::kDecodeDone;
-    }
-    // Payload is too long.
-    return state->ReportFrameSizeError();
-  }
-  // Not done decoding the structure. Either we've got more payload to decode,
-  // or we've run out because the payload is too short.
-  QUICHE_DCHECK(
-      (status == DecodeStatus::kDecodeInProgress &&
-       state->remaining_payload() > 0) ||
-      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
-      << "\n status=" << status
-      << "; remaining_payload=" << state->remaining_payload();
-  return status;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/ping_payload_decoder.h b/http2/decoder/payload_decoders/ping_payload_decoder.h
deleted file mode 100644
index d6d2b7d..0000000
--- a/http2/decoder/payload_decoders/ping_payload_decoder.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PING_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PING_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a PING frame; for the RFC, see:
-//     http://httpwg.org/specs/rfc7540.html#PING
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class PingPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE PingPayloadDecoder {
- public:
-  // Starts the decoding of a PING frame's payload, and completes it if the
-  // entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a PING frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::PingPayloadDecoderPeer;
-
-  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
-
-  Http2PingFields ping_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PING_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/ping_payload_decoder_test.cc b/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
deleted file mode 100644
index 7f310a8..0000000
--- a/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/ping_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class PingPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() { return Http2FrameType::PING; }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnPing(const Http2FrameHeader& header,
-              const Http2PingFields& ping) override {
-    HTTP2_VLOG(1) << "OnPing: " << header << "; " << ping;
-    StartAndEndFrame(header)->OnPing(header, ping);
-  }
-
-  void OnPingAck(const Http2FrameHeader& header,
-                 const Http2PingFields& ping) override {
-    HTTP2_VLOG(1) << "OnPingAck: " << header << "; " << ping;
-    StartAndEndFrame(header)->OnPingAck(header, ping);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class PingPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<PingPayloadDecoder,
-                                        PingPayloadDecoderPeer,
-                                        Listener> {
- protected:
-  Http2PingFields RandPingFields() {
-    Http2PingFields fields;
-    test::Randomize(&fields, RandomPtr());
-    return fields;
-  }
-};
-
-// Confirm we get an error if the payload is not the correct size to hold
-// exactly one Http2PingFields.
-TEST_F(PingPayloadDecoderTest, WrongSize) {
-  auto approve_size = [](size_t size) {
-    return size != Http2PingFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(RandPingFields());
-  fb.Append(RandPingFields());
-  fb.Append(RandPingFields());
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-TEST_F(PingPayloadDecoderTest, Ping) {
-  for (int n = 0; n < 100; ++n) {
-    Http2PingFields fields = RandPingFields();
-    Http2FrameBuilder fb;
-    fb.Append(fields);
-    Http2FrameHeader header(fb.size(), Http2FrameType::PING,
-                            RandFlags() & ~Http2FrameFlag::ACK, RandStreamId());
-    set_frame_header(header);
-    FrameParts expected(header);
-    expected.SetOptPing(fields);
-    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-  }
-}
-
-TEST_F(PingPayloadDecoderTest, PingAck) {
-  for (int n = 0; n < 100; ++n) {
-    Http2PingFields fields;
-    Randomize(&fields, RandomPtr());
-    Http2FrameBuilder fb;
-    fb.Append(fields);
-    Http2FrameHeader header(fb.size(), Http2FrameType::PING,
-                            RandFlags() | Http2FrameFlag::ACK, RandStreamId());
-    set_frame_header(header);
-    FrameParts expected(header);
-    expected.SetOptPing(fields);
-    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/priority_payload_decoder.cc b/http2/decoder/payload_decoders/priority_payload_decoder.cc
deleted file mode 100644
index e68cbce..0000000
--- a/http2/decoder/payload_decoders/priority_payload_decoder.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/priority_payload_decoder.h"
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus PriorityPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "PriorityPayloadDecoder::StartDecodingPayload: "
-                 << state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  // PRIORITY frames have no flags.
-  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
-  state->InitializeRemainders();
-  return HandleStatus(
-      state, state->StartDecodingStructureInPayload(&priority_fields_, db));
-}
-
-DecodeStatus PriorityPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "PriorityPayloadDecoder::ResumeDecodingPayload"
-                 << "  remaining_payload=" << state->remaining_payload()
-                 << "  db->Remaining=" << db->Remaining();
-  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  return HandleStatus(
-      state, state->ResumeDecodingStructureInPayload(&priority_fields_, db));
-}
-
-DecodeStatus PriorityPayloadDecoder::HandleStatus(FrameDecoderState* state,
-                                                  DecodeStatus status) {
-  if (status == DecodeStatus::kDecodeDone) {
-    if (state->remaining_payload() == 0) {
-      state->listener()->OnPriorityFrame(state->frame_header(),
-                                         priority_fields_);
-      return DecodeStatus::kDecodeDone;
-    }
-    // Payload is too long.
-    return state->ReportFrameSizeError();
-  }
-  // Not done decoding the structure. Either we've got more payload to decode,
-  // or we've run out because the payload is too short, in which case
-  // OnFrameSizeError will have already been called.
-  QUICHE_DCHECK(
-      (status == DecodeStatus::kDecodeInProgress &&
-       state->remaining_payload() > 0) ||
-      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
-      << "\n status=" << status
-      << "; remaining_payload=" << state->remaining_payload();
-  return status;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/priority_payload_decoder.h b/http2/decoder/payload_decoders/priority_payload_decoder.h
deleted file mode 100644
index 7e6a9ee..0000000
--- a/http2/decoder/payload_decoders/priority_payload_decoder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a PRIORITY frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class PriorityPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE PriorityPayloadDecoder {
- public:
-  // Starts the decoding of a PRIORITY frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a PRIORITY frame that has been split across decode
-  // buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::PriorityPayloadDecoderPeer;
-
-  // Determines whether to report the PRIORITY to the listener, wait for more
-  // input, or to report a Frame Size Error.
-  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
-
-  Http2PriorityFields priority_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/priority_payload_decoder_test.cc b/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
deleted file mode 100644
index 08c9ec0..0000000
--- a/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/priority_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class PriorityPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::PRIORITY;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnPriorityFrame(const Http2FrameHeader& header,
-                       const Http2PriorityFields& priority_fields) override {
-    HTTP2_VLOG(1) << "OnPriority: " << header << "; " << priority_fields;
-    StartAndEndFrame(header)->OnPriorityFrame(header, priority_fields);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class PriorityPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<PriorityPayloadDecoder,
-                                        PriorityPayloadDecoderPeer,
-                                        Listener> {
- protected:
-  Http2PriorityFields RandPriorityFields() {
-    Http2PriorityFields fields;
-    test::Randomize(&fields, RandomPtr());
-    return fields;
-  }
-};
-
-// Confirm we get an error if the payload is not the correct size to hold
-// exactly one Http2PriorityFields.
-TEST_F(PriorityPayloadDecoderTest, WrongSize) {
-  auto approve_size = [](size_t size) {
-    return size != Http2PriorityFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(RandPriorityFields());
-  fb.Append(RandPriorityFields());
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-TEST_F(PriorityPayloadDecoderTest, VariousPayloads) {
-  for (int n = 0; n < 100; ++n) {
-    Http2PriorityFields fields = RandPriorityFields();
-    Http2FrameBuilder fb;
-    fb.Append(fields);
-    Http2FrameHeader header(fb.size(), Http2FrameType::PRIORITY, RandFlags(),
-                            RandStreamId());
-    set_frame_header(header);
-    FrameParts expected(header);
-    expected.SetOptPriority(fields);
-    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/priority_update_payload_decoder.cc b/http2/decoder/payload_decoders/priority_update_payload_decoder.cc
deleted file mode 100644
index ff6758c..0000000
--- a/http2/decoder/payload_decoders/priority_update_payload_decoder.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/priority_update_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         PriorityUpdatePayloadDecoder::PayloadState v) {
-  switch (v) {
-    case PriorityUpdatePayloadDecoder::PayloadState::kStartDecodingFixedFields:
-      return out << "kStartDecodingFixedFields";
-    case PriorityUpdatePayloadDecoder::PayloadState::kResumeDecodingFixedFields:
-      return out << "kResumeDecodingFixedFields";
-    case PriorityUpdatePayloadDecoder::PayloadState::kHandleFixedFieldsStatus:
-      return out << "kHandleFixedFieldsStatus";
-    case PriorityUpdatePayloadDecoder::PayloadState::kReadPriorityFieldValue:
-      return out << "kReadPriorityFieldValue";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_173_1)
-      << "Invalid PriorityUpdatePayloadDecoder::PayloadState: " << unknown;
-  return out << "PriorityUpdatePayloadDecoder::PayloadState(" << unknown << ")";
-}
-
-DecodeStatus PriorityUpdatePayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "PriorityUpdatePayloadDecoder::StartDecodingPayload: "
-                 << state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY_UPDATE, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
-
-  state->InitializeRemainders();
-  payload_state_ = PayloadState::kStartDecodingFixedFields;
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus PriorityUpdatePayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "PriorityUpdatePayloadDecoder::ResumeDecodingPayload: "
-                    "remaining_payload="
-                 << state->remaining_payload()
-                 << ", db->Remaining=" << db->Remaining();
-
-  const Http2FrameHeader& frame_header = state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY_UPDATE, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
-  QUICHE_DCHECK_NE(PayloadState::kHandleFixedFieldsStatus, payload_state_);
-
-  // |status| has to be initialized to some value to avoid compiler error in
-  // case PayloadState::kHandleFixedFieldsStatus below, but value does not
-  // matter, see QUICHE_DCHECK_NE above.
-  DecodeStatus status = DecodeStatus::kDecodeError;
-  size_t avail;
-  while (true) {
-    HTTP2_DVLOG(2)
-        << "PriorityUpdatePayloadDecoder::ResumeDecodingPayload payload_state_="
-        << payload_state_;
-    switch (payload_state_) {
-      case PayloadState::kStartDecodingFixedFields:
-        status = state->StartDecodingStructureInPayload(
-            &priority_update_fields_, db);
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kHandleFixedFieldsStatus:
-        if (status == DecodeStatus::kDecodeDone) {
-          state->listener()->OnPriorityUpdateStart(frame_header,
-                                                   priority_update_fields_);
-        } else {
-          // Not done decoding the structure. Either we've got more payload
-          // to decode, or we've run out because the payload is too short,
-          // in which case OnFrameSizeError will have already been called.
-          QUICHE_DCHECK((status == DecodeStatus::kDecodeInProgress &&
-                         state->remaining_payload() > 0) ||
-                        (status == DecodeStatus::kDecodeError &&
-                         state->remaining_payload() == 0))
-              << "\n status=" << status
-              << "; remaining_payload=" << state->remaining_payload();
-          payload_state_ = PayloadState::kResumeDecodingFixedFields;
-          return status;
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kReadPriorityFieldValue:
-        // Anything left in the decode buffer is the Priority Field Value.
-        avail = db->Remaining();
-        if (avail > 0) {
-          state->listener()->OnPriorityUpdatePayload(db->cursor(), avail);
-          db->AdvanceCursor(avail);
-          state->ConsumePayload(avail);
-        }
-        if (state->remaining_payload() > 0) {
-          payload_state_ = PayloadState::kReadPriorityFieldValue;
-          return DecodeStatus::kDecodeInProgress;
-        }
-        state->listener()->OnPriorityUpdateEnd();
-        return DecodeStatus::kDecodeDone;
-
-      case PayloadState::kResumeDecodingFixedFields:
-        status = state->ResumeDecodingStructureInPayload(
-            &priority_update_fields_, db);
-        payload_state_ = PayloadState::kHandleFixedFieldsStatus;
-        continue;
-    }
-    HTTP2_BUG(http2_bug_173_2) << "PayloadState: " << payload_state_;
-  }
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/priority_update_payload_decoder.h b/http2/decoder/payload_decoders/priority_update_payload_decoder.h
deleted file mode 100644
index f2557b2..0000000
--- a/http2/decoder/payload_decoders/priority_update_payload_decoder.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_UPDATE_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_UPDATE_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a PRIORITY_UPDATE frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class PriorityUpdatePayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE PriorityUpdatePayloadDecoder {
- public:
-  // States during decoding of a PRIORITY_UPDATE frame.
-  enum class PayloadState {
-    // At the start of the PRIORITY_UPDATE frame payload, ready to start
-    // decoding the fixed size fields into priority_update_fields_.
-    kStartDecodingFixedFields,
-
-    // The fixed size fields weren't all available when the decoder first
-    // tried to decode them; this state resumes the decoding when
-    // ResumeDecodingPayload is called later.
-    kResumeDecodingFixedFields,
-
-    // Handle the DecodeStatus returned from starting or resuming the decoding
-    // of Http2PriorityUpdateFields into priority_update_fields_. If complete,
-    // calls OnPriorityUpdateStart.
-    kHandleFixedFieldsStatus,
-
-    // Report the Priority Field Value portion of the payload to the listener's
-    // OnPriorityUpdatePayload method, and call OnPriorityUpdateEnd when the end
-    // of the payload is reached.
-    kReadPriorityFieldValue,
-  };
-
-  // Starts the decoding of a PRIORITY_UPDATE frame's payload, and completes it
-  // if the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a PRIORITY_UPDATE frame that has been split across decode
-  // buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::PriorityUpdatePayloadDecoderPeer;
-
-  Http2PriorityUpdateFields priority_update_fields_;
-  PayloadState payload_state_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_UPDATE_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc b/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc
deleted file mode 100644
index 41b7dc8..0000000
--- a/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/priority_update_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class PriorityUpdatePayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::PRIORITY_UPDATE;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) override {
-    HTTP2_VLOG(1) << "OnPriorityUpdateStart header: " << header
-                  << "; priority_update: " << priority_update;
-    StartFrame(header)->OnPriorityUpdateStart(header, priority_update);
-  }
-
-  void OnPriorityUpdatePayload(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
-    CurrentFrame()->OnPriorityUpdatePayload(data, len);
-  }
-
-  void OnPriorityUpdateEnd() override {
-    HTTP2_VLOG(1) << "OnPriorityUpdateEnd";
-    EndFrame()->OnPriorityUpdateEnd();
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class PriorityUpdatePayloadDecoderTest
-    : public AbstractPayloadDecoderTest<PriorityUpdatePayloadDecoder,
-                                        PriorityUpdatePayloadDecoderPeer,
-                                        Listener> {};
-
-// Confirm we get an error if the payload is not long enough to hold
-// Http2PriorityUpdateFields.
-TEST_F(PriorityUpdatePayloadDecoderTest, Truncated) {
-  auto approve_size = [](size_t size) {
-    return size != Http2PriorityUpdateFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(Http2PriorityUpdateFields(123));
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-class PriorityUpdatePayloadLengthTests
-    : public AbstractPayloadDecoderTest<PriorityUpdatePayloadDecoder,
-                                        PriorityUpdatePayloadDecoderPeer,
-                                        Listener>,
-      public ::testing::WithParamInterface<uint32_t> {
- protected:
-  PriorityUpdatePayloadLengthTests() : length_(GetParam()) {
-    HTTP2_VLOG(1) << "################  length_=" << length_
-                  << "  ################";
-  }
-
-  const uint32_t length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(VariousLengths,
-                         PriorityUpdatePayloadLengthTests,
-                         ::testing::Values(0, 1, 2, 3, 4, 5, 6));
-
-TEST_P(PriorityUpdatePayloadLengthTests, ValidLength) {
-  Http2PriorityUpdateFields priority_update;
-  Randomize(&priority_update, RandomPtr());
-  std::string priority_field_value = Random().RandString(length_);
-  Http2FrameBuilder fb;
-  fb.Append(priority_update);
-  fb.Append(priority_field_value);
-  Http2FrameHeader header(fb.size(), Http2FrameType::PRIORITY_UPDATE,
-                          RandFlags(), RandStreamId());
-  set_frame_header(header);
-  FrameParts expected(header, priority_field_value);
-  expected.SetOptPriorityUpdate(Http2PriorityUpdateFields{priority_update});
-  ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/push_promise_payload_decoder.cc b/http2/decoder/payload_decoders/push_promise_payload_decoder.cc
deleted file mode 100644
index 8dff0b9..0000000
--- a/http2/decoder/payload_decoders/push_promise_payload_decoder.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/push_promise_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         PushPromisePayloadDecoder::PayloadState v) {
-  switch (v) {
-    case PushPromisePayloadDecoder::PayloadState::kReadPadLength:
-      return out << "kReadPadLength";
-    case PushPromisePayloadDecoder::PayloadState::
-        kStartDecodingPushPromiseFields:
-      return out << "kStartDecodingPushPromiseFields";
-    case PushPromisePayloadDecoder::PayloadState::kReadPayload:
-      return out << "kReadPayload";
-    case PushPromisePayloadDecoder::PayloadState::kSkipPadding:
-      return out << "kSkipPadding";
-    case PushPromisePayloadDecoder::PayloadState::
-        kResumeDecodingPushPromiseFields:
-      return out << "kResumeDecodingPushPromiseFields";
-  }
-  return out << static_cast<int>(v);
-}
-
-DecodeStatus PushPromisePayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "PushPromisePayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-
-  QUICHE_DCHECK_EQ(Http2FrameType::PUSH_PROMISE, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::END_HEADERS |
-                                             Http2FrameFlag::PADDED));
-
-  if (!frame_header.IsPadded()) {
-    // If it turns out that PUSH_PROMISE frames without padding are sufficiently
-    // common, and that they are usually short enough that they fit entirely
-    // into one DecodeBuffer, we can detect that here and implement a special
-    // case, avoiding the state machine in ResumeDecodingPayload.
-    payload_state_ = PayloadState::kStartDecodingPushPromiseFields;
-  } else {
-    payload_state_ = PayloadState::kReadPadLength;
-  }
-  state->InitializeRemainders();
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus PushPromisePayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "UnknownPayloadDecoder::ResumeDecodingPayload"
-                 << "  remaining_payload=" << state->remaining_payload()
-                 << "  db->Remaining=" << db->Remaining();
-
-  const Http2FrameHeader& frame_header = state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::PUSH_PROMISE, frame_header.type);
-  QUICHE_DCHECK_LE(state->remaining_payload(), frame_header.payload_length);
-  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
-
-  DecodeStatus status;
-  while (true) {
-    HTTP2_DVLOG(2)
-        << "PushPromisePayloadDecoder::ResumeDecodingPayload payload_state_="
-        << payload_state_;
-    switch (payload_state_) {
-      case PayloadState::kReadPadLength:
-        QUICHE_DCHECK_EQ(state->remaining_payload(),
-                         frame_header.payload_length);
-        // ReadPadLength handles the OnPadLength callback, and updating the
-        // remaining_payload and remaining_padding fields. If the amount of
-        // padding is too large to fit in the frame's payload, ReadPadLength
-        // instead calls OnPaddingTooLong and returns kDecodeError.
-        // Suppress the call to OnPadLength because we haven't yet called
-        // OnPushPromiseStart, which needs to wait until we've decoded the
-        // Promised Stream ID.
-        status = state->ReadPadLength(db, /*report_pad_length*/ false);
-        if (status != DecodeStatus::kDecodeDone) {
-          payload_state_ = PayloadState::kReadPadLength;
-          return status;
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kStartDecodingPushPromiseFields:
-        status =
-            state->StartDecodingStructureInPayload(&push_promise_fields_, db);
-        if (status != DecodeStatus::kDecodeDone) {
-          payload_state_ = PayloadState::kResumeDecodingPushPromiseFields;
-          return status;
-        }
-        // Finished decoding the Promised Stream ID. Can now tell the listener
-        // that we're starting to decode a PUSH_PROMISE frame.
-        ReportPushPromise(state);
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kReadPayload:
-        QUICHE_DCHECK_LT(state->remaining_payload(),
-                         frame_header.payload_length);
-        QUICHE_DCHECK_LE(state->remaining_payload(),
-                         frame_header.payload_length -
-                             Http2PushPromiseFields::EncodedSize());
-        QUICHE_DCHECK_LE(
-            state->remaining_payload(),
-            frame_header.payload_length -
-                Http2PushPromiseFields::EncodedSize() -
-                (frame_header.IsPadded() ? (1 + state->remaining_padding())
-                                         : 0));
-        {
-          size_t avail = state->AvailablePayload(db);
-          state->listener()->OnHpackFragment(db->cursor(), avail);
-          db->AdvanceCursor(avail);
-          state->ConsumePayload(avail);
-        }
-        if (state->remaining_payload() > 0) {
-          payload_state_ = PayloadState::kReadPayload;
-          return DecodeStatus::kDecodeInProgress;
-        }
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case PayloadState::kSkipPadding:
-        // SkipPadding handles the OnPadding callback.
-        if (state->SkipPadding(db)) {
-          state->listener()->OnPushPromiseEnd();
-          return DecodeStatus::kDecodeDone;
-        }
-        payload_state_ = PayloadState::kSkipPadding;
-        return DecodeStatus::kDecodeInProgress;
-
-      case PayloadState::kResumeDecodingPushPromiseFields:
-        status =
-            state->ResumeDecodingStructureInPayload(&push_promise_fields_, db);
-        if (status == DecodeStatus::kDecodeDone) {
-          // Finished decoding the Promised Stream ID. Can now tell the listener
-          // that we're starting to decode a PUSH_PROMISE frame.
-          ReportPushPromise(state);
-          payload_state_ = PayloadState::kReadPayload;
-          continue;
-        }
-        payload_state_ = PayloadState::kResumeDecodingPushPromiseFields;
-        return status;
-    }
-    HTTP2_BUG(http2_bug_183_1) << "PayloadState: " << payload_state_;
-  }
-}
-
-void PushPromisePayloadDecoder::ReportPushPromise(FrameDecoderState* state) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  if (frame_header.IsPadded()) {
-    state->listener()->OnPushPromiseStart(frame_header, push_promise_fields_,
-                                          1 + state->remaining_padding());
-  } else {
-    state->listener()->OnPushPromiseStart(frame_header, push_promise_fields_,
-                                          0);
-  }
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/push_promise_payload_decoder.h b/http2/decoder/payload_decoders/push_promise_payload_decoder.h
deleted file mode 100644
index 7c5b6a2..0000000
--- a/http2/decoder/payload_decoders/push_promise_payload_decoder.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PUSH_PROMISE_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PUSH_PROMISE_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a PUSH_PROMISE frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class PushPromisePayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE PushPromisePayloadDecoder {
- public:
-  // States during decoding of a PUSH_PROMISE frame.
-  enum class PayloadState {
-    // The frame is padded and we need to read the PAD_LENGTH field (1 byte).
-    kReadPadLength,
-
-    // Ready to start decoding the fixed size fields of the PUSH_PROMISE
-    // frame into push_promise_fields_.
-    kStartDecodingPushPromiseFields,
-
-    // The decoder has already called OnPushPromiseStart, and is now reporting
-    // the HPACK block fragment to the listener's OnHpackFragment method.
-    kReadPayload,
-
-    // The decoder has finished with the HPACK block fragment, and is now
-    // ready to skip the trailing padding, if the frame has any.
-    kSkipPadding,
-
-    // The fixed size fields weren't all available when the decoder first tried
-    // to decode them (state kStartDecodingPushPromiseFields); this state
-    // resumes the decoding when ResumeDecodingPayload is called later.
-    kResumeDecodingPushPromiseFields,
-  };
-
-  // Starts the decoding of a PUSH_PROMISE frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a PUSH_PROMISE frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::PushPromisePayloadDecoderPeer;
-
-  void ReportPushPromise(FrameDecoderState* state);
-
-  PayloadState payload_state_;
-  Http2PushPromiseFields push_promise_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PUSH_PROMISE_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc b/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
deleted file mode 100644
index bd784ed..0000000
--- a/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/push_promise_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-// Provides friend access to an instance of the payload decoder, and also
-// provides info to aid in testing.
-class PushPromisePayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::PUSH_PROMISE;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
-    return Http2FrameFlag::PADDED;
-  }
-};
-
-namespace {
-
-// Listener listens for only those methods expected by the payload decoder
-// under test, and forwards them onto the FrameParts instance for the current
-// frame.
-struct Listener : public FramePartsCollector {
-  void OnPushPromiseStart(const Http2FrameHeader& header,
-                          const Http2PushPromiseFields& promise,
-                          size_t total_padding_length) override {
-    HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
-                  << "  promise: " << promise
-                  << "  total_padding_length: " << total_padding_length;
-    EXPECT_EQ(Http2FrameType::PUSH_PROMISE, header.type);
-    StartFrame(header)->OnPushPromiseStart(header, promise,
-                                           total_padding_length);
-  }
-
-  void OnHpackFragment(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
-    CurrentFrame()->OnHpackFragment(data, len);
-  }
-
-  void OnPushPromiseEnd() override {
-    HTTP2_VLOG(1) << "OnPushPromiseEnd";
-    EndFrame()->OnPushPromiseEnd();
-  }
-
-  void OnPadding(const char* padding, size_t skipped_length) override {
-    HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
-    CurrentFrame()->OnPadding(padding, skipped_length);
-  }
-
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override {
-    HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
-                  << "; missing_length: " << missing_length;
-    FrameError(header)->OnPaddingTooLong(header, missing_length);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class PushPromisePayloadDecoderTest
-    : public AbstractPaddablePayloadDecoderTest<PushPromisePayloadDecoder,
-                                                PushPromisePayloadDecoderPeer,
-                                                Listener> {};
-
-INSTANTIATE_TEST_SUITE_P(VariousPadLengths,
-                         PushPromisePayloadDecoderTest,
-                         ::testing::Values(0, 1, 2, 3, 4, 254, 255, 256));
-
-// Payload contains the required Http2PushPromiseFields, followed by some
-// (fake) HPACK payload.
-TEST_P(PushPromisePayloadDecoderTest, VariousHpackPayloadSizes) {
-  for (size_t hpack_size : {0, 1, 2, 3, 255, 256, 1024}) {
-    HTTP2_LOG(INFO) << "###########   hpack_size = " << hpack_size
-                    << "  ###########";
-    Reset();
-    std::string hpack_payload = Random().RandString(hpack_size);
-    Http2PushPromiseFields push_promise{RandStreamId()};
-    frame_builder_.Append(push_promise);
-    frame_builder_.Append(hpack_payload);
-    MaybeAppendTrailingPadding();
-    Http2FrameHeader frame_header(frame_builder_.size(),
-                                  Http2FrameType::PUSH_PROMISE, RandFlags(),
-                                  RandStreamId());
-    set_frame_header(frame_header);
-    FrameParts expected(frame_header, hpack_payload, total_pad_length_);
-    expected.SetOptPushPromise(push_promise);
-    EXPECT_TRUE(
-        DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(), expected));
-  }
-}
-
-// Confirm we get an error if the payload is not long enough for the required
-// portion of the payload, regardless of the amount of (valid) padding.
-TEST_P(PushPromisePayloadDecoderTest, Truncated) {
-  auto approve_size = [](size_t size) {
-    return size != Http2PushPromiseFields::EncodedSize();
-  };
-  Http2PushPromiseFields push_promise{RandStreamId()};
-  Http2FrameBuilder fb;
-  fb.Append(push_promise);
-  EXPECT_TRUE(VerifyDetectsMultipleFrameSizeErrors(0, fb.buffer(), approve_size,
-                                                   total_pad_length_));
-}
-
-// Confirm we get an error if the PADDED flag is set but the payload is not
-// long enough to hold even the Pad Length amount of padding.
-TEST_P(PushPromisePayloadDecoderTest, PaddingTooLong) {
-  EXPECT_TRUE(VerifyDetectsPaddingTooLong());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc b/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc
deleted file mode 100644
index b2afc40..0000000
--- a/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/rst_stream_payload_decoder.h"
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus RstStreamPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "RstStreamPayloadDecoder::StartDecodingPayload: "
-                 << state->frame_header();
-  QUICHE_DCHECK_EQ(Http2FrameType::RST_STREAM, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  // RST_STREAM has no flags.
-  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
-  state->InitializeRemainders();
-  return HandleStatus(
-      state, state->StartDecodingStructureInPayload(&rst_stream_fields_, db));
-}
-
-DecodeStatus RstStreamPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "RstStreamPayloadDecoder::ResumeDecodingPayload"
-                 << "  remaining_payload=" << state->remaining_payload()
-                 << "  db->Remaining=" << db->Remaining();
-  QUICHE_DCHECK_EQ(Http2FrameType::RST_STREAM, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  return HandleStatus(
-      state, state->ResumeDecodingStructureInPayload(&rst_stream_fields_, db));
-}
-
-DecodeStatus RstStreamPayloadDecoder::HandleStatus(FrameDecoderState* state,
-                                                   DecodeStatus status) {
-  HTTP2_DVLOG(2) << "HandleStatus: status=" << status
-                 << "; remaining_payload=" << state->remaining_payload();
-  if (status == DecodeStatus::kDecodeDone) {
-    if (state->remaining_payload() == 0) {
-      state->listener()->OnRstStream(state->frame_header(),
-                                     rst_stream_fields_.error_code);
-      return DecodeStatus::kDecodeDone;
-    }
-    // Payload is too long.
-    return state->ReportFrameSizeError();
-  }
-  // Not done decoding the structure. Either we've got more payload to decode,
-  // or we've run out because the payload is too short, in which case
-  // OnFrameSizeError will have already been called by the FrameDecoderState.
-  QUICHE_DCHECK(
-      (status == DecodeStatus::kDecodeInProgress &&
-       state->remaining_payload() > 0) ||
-      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
-      << "\n status=" << status
-      << "; remaining_payload=" << state->remaining_payload();
-  return status;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/rst_stream_payload_decoder.h b/http2/decoder/payload_decoders/rst_stream_payload_decoder.h
deleted file mode 100644
index 61035c1..0000000
--- a/http2/decoder/payload_decoders/rst_stream_payload_decoder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_RST_STREAM_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_RST_STREAM_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a RST_STREAM frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class RstStreamPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE RstStreamPayloadDecoder {
- public:
-  // Starts the decoding of a RST_STREAM frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a RST_STREAM frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::RstStreamPayloadDecoderPeer;
-
-  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
-
-  Http2RstStreamFields rst_stream_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_RST_STREAM_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc b/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
deleted file mode 100644
index 6299a2c..0000000
--- a/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/rst_stream_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_constants_test_util.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class RstStreamPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::RST_STREAM;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnRstStream(const Http2FrameHeader& header,
-                   Http2ErrorCode error_code) override {
-    HTTP2_VLOG(1) << "OnRstStream: " << header << "; error_code=" << error_code;
-    StartAndEndFrame(header)->OnRstStream(header, error_code);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class RstStreamPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<RstStreamPayloadDecoder,
-                                        RstStreamPayloadDecoderPeer,
-                                        Listener> {
- protected:
-  Http2RstStreamFields RandRstStreamFields() {
-    Http2RstStreamFields fields;
-    test::Randomize(&fields, RandomPtr());
-    return fields;
-  }
-};
-
-// Confirm we get an error if the payload is not the correct size to hold
-// exactly one Http2RstStreamFields.
-TEST_F(RstStreamPayloadDecoderTest, WrongSize) {
-  auto approve_size = [](size_t size) {
-    return size != Http2RstStreamFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(RandRstStreamFields());
-  fb.Append(RandRstStreamFields());
-  fb.Append(RandRstStreamFields());
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-TEST_F(RstStreamPayloadDecoderTest, AllErrors) {
-  for (auto error_code : AllHttp2ErrorCodes()) {
-    Http2RstStreamFields fields{error_code};
-    Http2FrameBuilder fb;
-    fb.Append(fields);
-    Http2FrameHeader header(fb.size(), Http2FrameType::RST_STREAM, RandFlags(),
-                            RandStreamId());
-    set_frame_header(header);
-    FrameParts expected(header);
-    expected.SetOptRstStreamErrorCode(error_code);
-    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/settings_payload_decoder.cc b/http2/decoder/payload_decoders/settings_payload_decoder.cc
deleted file mode 100644
index a041792..0000000
--- a/http2/decoder/payload_decoders/settings_payload_decoder.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/settings_payload_decoder.h"
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus SettingsPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "SettingsPayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-  QUICHE_DCHECK_EQ(Http2FrameType::SETTINGS, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::ACK));
-
-  if (frame_header.IsAck()) {
-    if (total_length == 0) {
-      state->listener()->OnSettingsAck(frame_header);
-      return DecodeStatus::kDecodeDone;
-    } else {
-      state->InitializeRemainders();
-      return state->ReportFrameSizeError();
-    }
-  } else {
-    state->InitializeRemainders();
-    state->listener()->OnSettingsStart(frame_header);
-    return StartDecodingSettings(state, db);
-  }
-}
-
-DecodeStatus SettingsPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "SettingsPayloadDecoder::ResumeDecodingPayload"
-                 << "  remaining_payload=" << state->remaining_payload()
-                 << "  db->Remaining=" << db->Remaining();
-  QUICHE_DCHECK_EQ(Http2FrameType::SETTINGS, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-
-  DecodeStatus status =
-      state->ResumeDecodingStructureInPayload(&setting_fields_, db);
-  if (status == DecodeStatus::kDecodeDone) {
-    state->listener()->OnSetting(setting_fields_);
-    return StartDecodingSettings(state, db);
-  }
-  return HandleNotDone(state, db, status);
-}
-
-DecodeStatus SettingsPayloadDecoder::StartDecodingSettings(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "SettingsPayloadDecoder::StartDecodingSettings"
-                 << "  remaining_payload=" << state->remaining_payload()
-                 << "  db->Remaining=" << db->Remaining();
-  while (state->remaining_payload() > 0) {
-    DecodeStatus status =
-        state->StartDecodingStructureInPayload(&setting_fields_, db);
-    if (status == DecodeStatus::kDecodeDone) {
-      state->listener()->OnSetting(setting_fields_);
-      continue;
-    }
-    return HandleNotDone(state, db, status);
-  }
-  HTTP2_DVLOG(2) << "LEAVING SettingsPayloadDecoder::StartDecodingSettings"
-                 << "\n\tdb->Remaining=" << db->Remaining()
-                 << "\n\t remaining_payload=" << state->remaining_payload();
-  state->listener()->OnSettingsEnd();
-  return DecodeStatus::kDecodeDone;
-}
-
-DecodeStatus SettingsPayloadDecoder::HandleNotDone(FrameDecoderState* state,
-                                                   DecodeBuffer* db,
-                                                   DecodeStatus status) {
-  // Not done decoding the structure. Either we've got more payload to decode,
-  // or we've run out because the payload is too short, in which case
-  // OnFrameSizeError will have already been called.
-  QUICHE_DCHECK(
-      (status == DecodeStatus::kDecodeInProgress &&
-       state->remaining_payload() > 0) ||
-      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
-      << "\n status=" << status
-      << "; remaining_payload=" << state->remaining_payload()
-      << "; db->Remaining=" << db->Remaining();
-  return status;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/settings_payload_decoder.h b/http2/decoder/payload_decoders/settings_payload_decoder.h
deleted file mode 100644
index 7462888..0000000
--- a/http2/decoder/payload_decoders/settings_payload_decoder.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_SETTINGS_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_SETTINGS_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a SETTINGS frame; for the RFC, see:
-//     http://httpwg.org/specs/rfc7540.html#SETTINGS
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class SettingsPayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE SettingsPayloadDecoder {
- public:
-  // Starts the decoding of a SETTINGS frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a SETTINGS frame that has been split across decode
-  // buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::SettingsPayloadDecoderPeer;
-
-  // Decodes as many settings as are available in the decode buffer, starting at
-  // the first byte of one setting; if a single setting is split across buffers,
-  // ResumeDecodingPayload will handle starting from where the previous call
-  // left off, and then will call StartDecodingSettings.
-  DecodeStatus StartDecodingSettings(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
-  // Decoding a single SETTING returned a status other than kDecodeDone; this
-  // method just brings together the QUICHE_DCHECKs to reduce duplication.
-  DecodeStatus HandleNotDone(FrameDecoderState* state,
-                             DecodeBuffer* db,
-                             DecodeStatus status);
-
-  Http2SettingFields setting_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_SETTINGS_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/settings_payload_decoder_test.cc b/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
deleted file mode 100644
index 0261ed3..0000000
--- a/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/settings_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <vector>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_constants_test_util.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class SettingsPayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::SETTINGS;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
-    return Http2FrameFlag::ACK;
-  }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnSettingsStart(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnSettingsStart: " << header;
-    EXPECT_EQ(Http2FrameType::SETTINGS, header.type) << header;
-    EXPECT_EQ(Http2FrameFlag(), header.flags) << header;
-    StartFrame(header)->OnSettingsStart(header);
-  }
-
-  void OnSetting(const Http2SettingFields& setting_fields) override {
-    HTTP2_VLOG(1) << "Http2SettingFields: setting_fields=" << setting_fields;
-    CurrentFrame()->OnSetting(setting_fields);
-  }
-
-  void OnSettingsEnd() override {
-    HTTP2_VLOG(1) << "OnSettingsEnd";
-    EndFrame()->OnSettingsEnd();
-  }
-
-  void OnSettingsAck(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnSettingsAck: " << header;
-    StartAndEndFrame(header)->OnSettingsAck(header);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class SettingsPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<SettingsPayloadDecoder,
-                                        SettingsPayloadDecoderPeer,
-                                        Listener> {
- protected:
-  Http2SettingFields RandSettingsFields() {
-    Http2SettingFields fields;
-    test::Randomize(&fields, RandomPtr());
-    return fields;
-  }
-};
-
-// Confirm we get an error if the SETTINGS payload is not the correct size
-// to hold exactly zero or more whole Http2SettingFields.
-TEST_F(SettingsPayloadDecoderTest, SettingsWrongSize) {
-  auto approve_size = [](size_t size) {
-    // Should get an error if size is not an integral multiple of the size
-    // of one setting.
-    return 0 != (size % Http2SettingFields::EncodedSize());
-  };
-  Http2FrameBuilder fb;
-  fb.Append(RandSettingsFields());
-  fb.Append(RandSettingsFields());
-  fb.Append(RandSettingsFields());
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-// Confirm we get an error if the SETTINGS ACK payload is not empty.
-TEST_F(SettingsPayloadDecoderTest, SettingsAkcWrongSize) {
-  auto approve_size = [](size_t size) { return size != 0; };
-  Http2FrameBuilder fb;
-  fb.Append(RandSettingsFields());
-  fb.Append(RandSettingsFields());
-  fb.Append(RandSettingsFields());
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(Http2FrameFlag::ACK, fb.buffer(),
-                                          approve_size));
-}
-
-// SETTINGS must have stream_id==0, but the payload decoder doesn't check that.
-TEST_F(SettingsPayloadDecoderTest, SettingsAck) {
-  for (int stream_id = 0; stream_id < 3; ++stream_id) {
-    Http2FrameHeader header(0, Http2FrameType::SETTINGS,
-                            RandFlags() | Http2FrameFlag::ACK, stream_id);
-    set_frame_header(header);
-    FrameParts expected(header);
-    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays("", expected));
-  }
-}
-
-// Try several values of each known SETTINGS parameter.
-TEST_F(SettingsPayloadDecoderTest, OneRealSetting) {
-  std::vector<uint32_t> values = {0, 1, 0xffffffff, Random().Rand32()};
-  for (auto param : AllHttp2SettingsParameters()) {
-    for (uint32_t value : values) {
-      Http2SettingFields fields(param, value);
-      Http2FrameBuilder fb;
-      fb.Append(fields);
-      Http2FrameHeader header(fb.size(), Http2FrameType::SETTINGS, RandFlags(),
-                              RandStreamId());
-      set_frame_header(header);
-      FrameParts expected(header);
-      expected.AppendSetting(fields);
-      EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-    }
-  }
-}
-
-// Decode a SETTINGS frame with lots of fields.
-TEST_F(SettingsPayloadDecoderTest, ManySettings) {
-  const size_t num_settings = 100;
-  const size_t size = Http2SettingFields::EncodedSize() * num_settings;
-  Http2FrameHeader header(size, Http2FrameType::SETTINGS,
-                          RandFlags(),  // & ~Http2FrameFlag::ACK,
-                          RandStreamId());
-  set_frame_header(header);
-  FrameParts expected(header);
-  Http2FrameBuilder fb;
-  for (size_t n = 0; n < num_settings; ++n) {
-    Http2SettingFields fields(static_cast<Http2SettingsParameter>(n),
-                              Random().Rand32());
-    fb.Append(fields);
-    expected.AppendSetting(fields);
-  }
-  ASSERT_EQ(size, fb.size());
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/unknown_payload_decoder.cc b/http2/decoder/payload_decoders/unknown_payload_decoder.cc
deleted file mode 100644
index a71ea78..0000000
--- a/http2/decoder/payload_decoders/unknown_payload_decoder.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/unknown_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus UnknownPayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-
-  HTTP2_DVLOG(2) << "UnknownPayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-  QUICHE_DCHECK(!IsSupportedHttp2FrameType(frame_header.type)) << frame_header;
-  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
-
-  state->InitializeRemainders();
-  state->listener()->OnUnknownStart(frame_header);
-  return ResumeDecodingPayload(state, db);
-}
-
-DecodeStatus UnknownPayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "UnknownPayloadDecoder::ResumeDecodingPayload "
-                 << "remaining_payload=" << state->remaining_payload()
-                 << "; db->Remaining=" << db->Remaining();
-  QUICHE_DCHECK(!IsSupportedHttp2FrameType(state->frame_header().type))
-      << state->frame_header();
-  QUICHE_DCHECK_LE(state->remaining_payload(),
-                   state->frame_header().payload_length);
-  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
-
-  size_t avail = db->Remaining();
-  if (avail > 0) {
-    state->listener()->OnUnknownPayload(db->cursor(), avail);
-    db->AdvanceCursor(avail);
-    state->ConsumePayload(avail);
-  }
-  if (state->remaining_payload() == 0) {
-    state->listener()->OnUnknownEnd();
-    return DecodeStatus::kDecodeDone;
-  }
-  return DecodeStatus::kDecodeInProgress;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/unknown_payload_decoder.h b/http2/decoder/payload_decoders/unknown_payload_decoder.h
deleted file mode 100644
index 7f89340..0000000
--- a/http2/decoder/payload_decoders/unknown_payload_decoder.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_UNKNOWN_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_UNKNOWN_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a frame whose type unknown.  According to the HTTP/2
-// specification (http://httpwg.org/specs/rfc7540.html#FrameHeader):
-//     Implementations MUST ignore and discard any frame that has
-//     a type that is unknown.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE UnknownPayloadDecoder {
- public:
-  // Starts decoding a payload of unknown type; just passes it to the listener.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a payload of unknown type that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_UNKNOWN_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc b/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc
deleted file mode 100644
index 722d109..0000000
--- a/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/unknown_payload_decoder.h"
-
-#include <stddef.h>
-
-#include <string>
-#include <type_traits>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-Http2FrameType g_unknown_frame_type;
-}  // namespace
-
-// Provides friend access to an instance of the payload decoder, and also
-// provides info to aid in testing.
-class UnknownPayloadDecoderPeer {
- public:
-  static Http2FrameType FrameType() { return g_unknown_frame_type; }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnUnknownStart(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnUnknownStart: " << header;
-    StartFrame(header)->OnUnknownStart(header);
-  }
-
-  void OnUnknownPayload(const char* data, size_t len) override {
-    HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
-    CurrentFrame()->OnUnknownPayload(data, len);
-  }
-
-  void OnUnknownEnd() override {
-    HTTP2_VLOG(1) << "OnUnknownEnd";
-    EndFrame()->OnUnknownEnd();
-  }
-};
-
-constexpr bool SupportedFrameType = false;
-
-class UnknownPayloadDecoderTest
-    : public AbstractPayloadDecoderTest<UnknownPayloadDecoder,
-                                        UnknownPayloadDecoderPeer,
-                                        Listener,
-                                        SupportedFrameType>,
-      public ::testing::WithParamInterface<uint32_t> {
- protected:
-  UnknownPayloadDecoderTest() : length_(GetParam()) {
-    HTTP2_VLOG(1) << "################  length_=" << length_
-                  << "  ################";
-
-    // Each test case will choose a random frame type that isn't supported.
-    do {
-      g_unknown_frame_type = static_cast<Http2FrameType>(Random().Rand8());
-    } while (IsSupportedHttp2FrameType(g_unknown_frame_type));
-  }
-
-  const uint32_t length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(VariousLengths,
-                         UnknownPayloadDecoderTest,
-                         ::testing::Values(0, 1, 2, 3, 255, 256));
-
-TEST_P(UnknownPayloadDecoderTest, ValidLength) {
-  std::string unknown_payload = Random().RandString(length_);
-  Http2FrameHeader frame_header(length_, g_unknown_frame_type, Random().Rand8(),
-                                RandStreamId());
-  set_frame_header(frame_header);
-  FrameParts expected(frame_header, unknown_payload);
-  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(unknown_payload, expected));
-  // TODO(jamessynge): Check here (and in other such tests) that the fast
-  // and slow decode counts are both non-zero. Perhaps also add some kind of
-  // test for the listener having been called. That could simply be a test
-  // that there is a single collected FrameParts instance, and that it matches
-  // expected.
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/window_update_payload_decoder.cc b/http2/decoder/payload_decoders/window_update_payload_decoder.cc
deleted file mode 100644
index d088e51..0000000
--- a/http2/decoder/payload_decoders/window_update_payload_decoder.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/window_update_payload_decoder.h"
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_http2_structures.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus WindowUpdatePayloadDecoder::StartDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  const Http2FrameHeader& frame_header = state->frame_header();
-  const uint32_t total_length = frame_header.payload_length;
-
-  HTTP2_DVLOG(2) << "WindowUpdatePayloadDecoder::StartDecodingPayload: "
-                 << frame_header;
-
-  QUICHE_DCHECK_EQ(Http2FrameType::WINDOW_UPDATE, frame_header.type);
-  QUICHE_DCHECK_LE(db->Remaining(), total_length);
-
-  // WINDOW_UPDATE frames have no flags.
-  QUICHE_DCHECK_EQ(0, frame_header.flags);
-
-  // Special case for when the payload is the correct size and entirely in
-  // the buffer.
-  if (db->Remaining() == Http2WindowUpdateFields::EncodedSize() &&
-      total_length == Http2WindowUpdateFields::EncodedSize()) {
-    DoDecode(&window_update_fields_, db);
-    state->listener()->OnWindowUpdate(
-        frame_header, window_update_fields_.window_size_increment);
-    return DecodeStatus::kDecodeDone;
-  }
-  state->InitializeRemainders();
-  return HandleStatus(state, state->StartDecodingStructureInPayload(
-                                 &window_update_fields_, db));
-}
-
-DecodeStatus WindowUpdatePayloadDecoder::ResumeDecodingPayload(
-    FrameDecoderState* state,
-    DecodeBuffer* db) {
-  HTTP2_DVLOG(2) << "ResumeDecodingPayload: remaining_payload="
-                 << state->remaining_payload()
-                 << "; db->Remaining=" << db->Remaining();
-  QUICHE_DCHECK_EQ(Http2FrameType::WINDOW_UPDATE, state->frame_header().type);
-  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
-  return HandleStatus(state, state->ResumeDecodingStructureInPayload(
-                                 &window_update_fields_, db));
-}
-
-DecodeStatus WindowUpdatePayloadDecoder::HandleStatus(FrameDecoderState* state,
-                                                      DecodeStatus status) {
-  HTTP2_DVLOG(2) << "HandleStatus: status=" << status
-                 << "; remaining_payload=" << state->remaining_payload();
-  if (status == DecodeStatus::kDecodeDone) {
-    if (state->remaining_payload() == 0) {
-      state->listener()->OnWindowUpdate(
-          state->frame_header(), window_update_fields_.window_size_increment);
-      return DecodeStatus::kDecodeDone;
-    }
-    // Payload is too long.
-    return state->ReportFrameSizeError();
-  }
-  // Not done decoding the structure. Either we've got more payload to decode,
-  // or we've run out because the payload is too short, in which case
-  // OnFrameSizeError will have already been called.
-  QUICHE_DCHECK(
-      (status == DecodeStatus::kDecodeInProgress &&
-       state->remaining_payload() > 0) ||
-      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
-      << "\n status=" << status
-      << "; remaining_payload=" << state->remaining_payload();
-  return status;
-}
-
-}  // namespace http2
diff --git a/http2/decoder/payload_decoders/window_update_payload_decoder.h b/http2/decoder/payload_decoders/window_update_payload_decoder.h
deleted file mode 100644
index 3e6db43..0000000
--- a/http2/decoder/payload_decoders/window_update_payload_decoder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_WINDOW_UPDATE_PAYLOAD_DECODER_H_
-#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_WINDOW_UPDATE_PAYLOAD_DECODER_H_
-
-// Decodes the payload of a WINDOW_UPDATE frame.
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/frame_decoder_state.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class WindowUpdatePayloadDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE WindowUpdatePayloadDecoder {
- public:
-  // Starts decoding a WINDOW_UPDATE frame's payload, and completes it if
-  // the entire payload is in the provided decode buffer.
-  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
-
-  // Resumes decoding a WINDOW_UPDATE frame's payload that has been split across
-  // decode buffers.
-  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
-                                     DecodeBuffer* db);
-
- private:
-  friend class test::WindowUpdatePayloadDecoderPeer;
-
-  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
-
-  Http2WindowUpdateFields window_update_fields_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_WINDOW_UPDATE_PAYLOAD_DECODER_H_
diff --git a/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc b/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
deleted file mode 100644
index 4e69e9b..0000000
--- a/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/decoder/payload_decoders/window_update_payload_decoder.h"
-
-#include <stddef.h>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/test_tools/frame_parts.h"
-#include "http2/test_tools/frame_parts_collector.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class WindowUpdatePayloadDecoderPeer {
- public:
-  static constexpr Http2FrameType FrameType() {
-    return Http2FrameType::WINDOW_UPDATE;
-  }
-
-  // Returns the mask of flags that affect the decoding of the payload (i.e.
-  // flags that that indicate the presence of certain fields or padding).
-  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
-};
-
-namespace {
-
-struct Listener : public FramePartsCollector {
-  void OnWindowUpdate(const Http2FrameHeader& header,
-                      uint32_t window_size_increment) override {
-    HTTP2_VLOG(1) << "OnWindowUpdate: " << header
-                  << "; window_size_increment=" << window_size_increment;
-    EXPECT_EQ(Http2FrameType::WINDOW_UPDATE, header.type);
-    StartAndEndFrame(header)->OnWindowUpdate(header, window_size_increment);
-  }
-
-  void OnFrameSizeError(const Http2FrameHeader& header) override {
-    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-    FrameError(header)->OnFrameSizeError(header);
-  }
-};
-
-class WindowUpdatePayloadDecoderTest
-    : public AbstractPayloadDecoderTest<WindowUpdatePayloadDecoder,
-                                        WindowUpdatePayloadDecoderPeer,
-                                        Listener> {
- protected:
-  Http2WindowUpdateFields RandWindowUpdateFields() {
-    Http2WindowUpdateFields fields;
-    test::Randomize(&fields, RandomPtr());
-    HTTP2_VLOG(3) << "RandWindowUpdateFields: " << fields;
-    return fields;
-  }
-};
-
-// Confirm we get an error if the payload is not the correct size to hold
-// exactly one Http2WindowUpdateFields.
-TEST_F(WindowUpdatePayloadDecoderTest, WrongSize) {
-  auto approve_size = [](size_t size) {
-    return size != Http2WindowUpdateFields::EncodedSize();
-  };
-  Http2FrameBuilder fb;
-  fb.Append(RandWindowUpdateFields());
-  fb.Append(RandWindowUpdateFields());
-  fb.Append(RandWindowUpdateFields());
-  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
-}
-
-TEST_F(WindowUpdatePayloadDecoderTest, VariousPayloads) {
-  for (int n = 0; n < 100; ++n) {
-    uint32_t stream_id = n == 0 ? 0 : RandStreamId();
-    Http2WindowUpdateFields fields = RandWindowUpdateFields();
-    Http2FrameBuilder fb;
-    fb.Append(fields);
-    Http2FrameHeader header(fb.size(), Http2FrameType::WINDOW_UPDATE,
-                            RandFlags(), stream_id);
-    set_frame_header(header);
-    FrameParts expected(header);
-    expected.SetOptWindowUpdateIncrement(fields.window_size_increment);
-    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_block_collector.cc b/http2/hpack/decoder/hpack_block_collector.cc
deleted file mode 100644
index 677f55a..0000000
--- a/http2/hpack/decoder/hpack_block_collector.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_block_collector.h"
-
-#include <algorithm>
-#include <memory>
-
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-
-HpackBlockCollector::HpackBlockCollector() = default;
-HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other)
-    : pending_entry_(other.pending_entry_), entries_(other.entries_) {}
-HpackBlockCollector::~HpackBlockCollector() = default;
-
-void HpackBlockCollector::OnIndexedHeader(size_t index) {
-  pending_entry_.OnIndexedHeader(index);
-  PushPendingEntry();
-}
-void HpackBlockCollector::OnDynamicTableSizeUpdate(size_t size) {
-  pending_entry_.OnDynamicTableSizeUpdate(size);
-  PushPendingEntry();
-}
-void HpackBlockCollector::OnStartLiteralHeader(HpackEntryType header_type,
-                                               size_t maybe_name_index) {
-  pending_entry_.OnStartLiteralHeader(header_type, maybe_name_index);
-}
-void HpackBlockCollector::OnNameStart(bool huffman_encoded, size_t len) {
-  pending_entry_.OnNameStart(huffman_encoded, len);
-}
-void HpackBlockCollector::OnNameData(const char* data, size_t len) {
-  pending_entry_.OnNameData(data, len);
-}
-void HpackBlockCollector::OnNameEnd() {
-  pending_entry_.OnNameEnd();
-}
-void HpackBlockCollector::OnValueStart(bool huffman_encoded, size_t len) {
-  pending_entry_.OnValueStart(huffman_encoded, len);
-}
-void HpackBlockCollector::OnValueData(const char* data, size_t len) {
-  pending_entry_.OnValueData(data, len);
-}
-void HpackBlockCollector::OnValueEnd() {
-  pending_entry_.OnValueEnd();
-  PushPendingEntry();
-}
-
-void HpackBlockCollector::PushPendingEntry() {
-  EXPECT_TRUE(pending_entry_.IsComplete());
-  HTTP2_DVLOG(2) << "PushPendingEntry: " << pending_entry_;
-  entries_.push_back(pending_entry_);
-  EXPECT_TRUE(entries_.back().IsComplete());
-  pending_entry_.Clear();
-}
-void HpackBlockCollector::Clear() {
-  pending_entry_.Clear();
-  entries_.clear();
-}
-
-void HpackBlockCollector::ExpectIndexedHeader(size_t index) {
-  entries_.push_back(
-      HpackEntryCollector(HpackEntryType::kIndexedHeader, index));
-}
-void HpackBlockCollector::ExpectDynamicTableSizeUpdate(size_t size) {
-  entries_.push_back(
-      HpackEntryCollector(HpackEntryType::kDynamicTableSizeUpdate, size));
-}
-void HpackBlockCollector::ExpectNameIndexAndLiteralValue(
-    HpackEntryType type,
-    size_t index,
-    bool value_huffman,
-    const std::string& value) {
-  entries_.push_back(HpackEntryCollector(type, index, value_huffman, value));
-}
-void HpackBlockCollector::ExpectLiteralNameAndValue(HpackEntryType type,
-                                                    bool name_huffman,
-                                                    const std::string& name,
-                                                    bool value_huffman,
-                                                    const std::string& value) {
-  entries_.push_back(
-      HpackEntryCollector(type, name_huffman, name, value_huffman, value));
-}
-
-void HpackBlockCollector::ShuffleEntries(Http2Random* rng) {
-  std::shuffle(entries_.begin(), entries_.end(), *rng);
-}
-
-void HpackBlockCollector::AppendToHpackBlockBuilder(
-    HpackBlockBuilder* hbb) const {
-  QUICHE_CHECK(IsNotPending());
-  for (const auto& entry : entries_) {
-    entry.AppendToHpackBlockBuilder(hbb);
-  }
-}
-
-AssertionResult HpackBlockCollector::ValidateSoleIndexedHeader(
-    size_t ndx) const {
-  VERIFY_TRUE(pending_entry_.IsClear());
-  VERIFY_EQ(1u, entries_.size());
-  VERIFY_TRUE(entries_.front().ValidateIndexedHeader(ndx));
-  return AssertionSuccess();
-}
-AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader(
-    HpackEntryType expected_type,
-    size_t expected_index,
-    bool expected_value_huffman,
-    absl::string_view expected_value) const {
-  VERIFY_TRUE(pending_entry_.IsClear());
-  VERIFY_EQ(1u, entries_.size());
-  VERIFY_TRUE(entries_.front().ValidateLiteralValueHeader(
-      expected_type, expected_index, expected_value_huffman, expected_value));
-  return AssertionSuccess();
-}
-AssertionResult HpackBlockCollector::ValidateSoleLiteralNameValueHeader(
-    HpackEntryType expected_type,
-    bool expected_name_huffman,
-    absl::string_view expected_name,
-    bool expected_value_huffman,
-    absl::string_view expected_value) const {
-  VERIFY_TRUE(pending_entry_.IsClear());
-  VERIFY_EQ(1u, entries_.size());
-  VERIFY_TRUE(entries_.front().ValidateLiteralNameValueHeader(
-      expected_type, expected_name_huffman, expected_name,
-      expected_value_huffman, expected_value));
-  return AssertionSuccess();
-}
-AssertionResult HpackBlockCollector::ValidateSoleDynamicTableSizeUpdate(
-    size_t size) const {
-  VERIFY_TRUE(pending_entry_.IsClear());
-  VERIFY_EQ(1u, entries_.size());
-  VERIFY_TRUE(entries_.front().ValidateDynamicTableSizeUpdate(size));
-  return AssertionSuccess();
-}
-
-AssertionResult HpackBlockCollector::VerifyEq(
-    const HpackBlockCollector& that) const {
-  VERIFY_EQ(pending_entry_, that.pending_entry_);
-  VERIFY_EQ(entries_, that.entries_);
-  return AssertionSuccess();
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_block_collector.h b/http2/hpack/decoder/hpack_block_collector.h
deleted file mode 100644
index 812c3db..0000000
--- a/http2/hpack/decoder/hpack_block_collector.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
-
-// HpackBlockCollector implements HpackEntryDecoderListener in order to record
-// the calls using HpackEntryCollector instances (one per HPACK entry). This
-// supports testing of HpackBlockDecoder, which decodes entire HPACK blocks.
-//
-// In addition to implementing the callback methods, HpackBlockCollector also
-// supports comparing two HpackBlockCollector instances (i.e. an expected and
-// an actual), or a sole HPACK entry against an expected value.
-
-#include <stddef.h>
-
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_entry_collector.h"
-#include "http2/hpack/decoder/hpack_entry_decoder_listener.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/test_tools/http2_random.h"
-
-namespace http2 {
-namespace test {
-
-class HpackBlockCollector : public HpackEntryDecoderListener {
- public:
-  HpackBlockCollector();
-  HpackBlockCollector(const HpackBlockCollector& other);
-  ~HpackBlockCollector() override;
-
-  // Implementations of HpackEntryDecoderListener, forwarding to pending_entry_,
-  // an HpackEntryCollector for the "in-progress" HPACK entry. OnIndexedHeader
-  // and OnDynamicTableSizeUpdate are pending only for that one call, while
-  // OnStartLiteralHeader is followed by many calls, ending with OnValueEnd.
-  // Once all the calls for one HPACK entry have been received, PushPendingEntry
-  // is used to append the pending_entry_ entry to the collected entries_.
-  void OnIndexedHeader(size_t index) override;
-  void OnDynamicTableSizeUpdate(size_t size) override;
-  void OnStartLiteralHeader(HpackEntryType header_type,
-                            size_t maybe_name_index) override;
-  void OnNameStart(bool huffman_encoded, size_t len) override;
-  void OnNameData(const char* data, size_t len) override;
-  void OnNameEnd() override;
-  void OnValueStart(bool huffman_encoded, size_t len) override;
-  void OnValueData(const char* data, size_t len) override;
-  void OnValueEnd() override;
-
-  // Methods for creating a set of expectations (i.e. HPACK entries to compare
-  // against those collected by another instance of HpackBlockCollector).
-
-  // Add an HPACK entry for an indexed header.
-  void ExpectIndexedHeader(size_t index);
-
-  // Add an HPACK entry for a dynamic table size update.
-  void ExpectDynamicTableSizeUpdate(size_t size);
-
-  // Add an HPACK entry for a header entry with an index for the name, and a
-  // literal value.
-  void ExpectNameIndexAndLiteralValue(HpackEntryType type,
-                                      size_t index,
-                                      bool value_huffman,
-                                      const std::string& value);
-
-  // Add an HPACK entry for a header entry with a literal name and value.
-  void ExpectLiteralNameAndValue(HpackEntryType type,
-                                 bool name_huffman,
-                                 const std::string& name,
-                                 bool value_huffman,
-                                 const std::string& value);
-
-  // Shuffle the entries, in support of generating an HPACK block of entries
-  // in some random order.
-  void ShuffleEntries(Http2Random* rng);
-
-  // Serialize entries_ to the HpackBlockBuilder.
-  void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const;
-
-  // Return AssertionSuccess if there is just one entry, and it is an
-  // Indexed Header with the specified index.
-  ::testing::AssertionResult ValidateSoleIndexedHeader(size_t ndx) const;
-
-  // Return AssertionSuccess if there is just one entry, and it is a
-  // Dynamic Table Size Update with the specified size.
-  ::testing::AssertionResult ValidateSoleDynamicTableSizeUpdate(
-      size_t size) const;
-
-  // Return AssertionSuccess if there is just one entry, and it is a Header
-  // entry with an index for the name and a literal value.
-  ::testing::AssertionResult ValidateSoleLiteralValueHeader(
-      HpackEntryType expected_type,
-      size_t expected_index,
-      bool expected_value_huffman,
-      absl::string_view expected_value) const;
-
-  // Return AssertionSuccess if there is just one entry, and it is a Header
-  // with a literal name and literal value.
-  ::testing::AssertionResult ValidateSoleLiteralNameValueHeader(
-      HpackEntryType expected_type,
-      bool expected_name_huffman,
-      absl::string_view expected_name,
-      bool expected_value_huffman,
-      absl::string_view expected_value) const;
-
-  bool IsNotPending() const { return pending_entry_.IsClear(); }
-  bool IsClear() const { return IsNotPending() && entries_.empty(); }
-  void Clear();
-
-  ::testing::AssertionResult VerifyEq(const HpackBlockCollector& that) const;
-
- private:
-  // Push the value of pending_entry_ onto entries_, and clear pending_entry_.
-  // The pending_entry_ must be complete.
-  void PushPendingEntry();
-
-  HpackEntryCollector pending_entry_;
-  std::vector<HpackEntryCollector> entries_;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
diff --git a/http2/hpack/decoder/hpack_block_decoder.cc b/http2/hpack/decoder/hpack_block_decoder.cc
deleted file mode 100644
index 0a4c71c..0000000
--- a/http2/hpack/decoder/hpack_block_decoder.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_block_decoder.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_cat.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_flags.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-DecodeStatus HpackBlockDecoder::Decode(DecodeBuffer* db) {
-  if (!before_entry_) {
-    HTTP2_DVLOG(2) << "HpackBlockDecoder::Decode resume entry, db->Remaining="
-                   << db->Remaining();
-    DecodeStatus status = entry_decoder_.Resume(db, listener_);
-    switch (status) {
-      case DecodeStatus::kDecodeDone:
-        before_entry_ = true;
-        break;
-      case DecodeStatus::kDecodeInProgress:
-        QUICHE_DCHECK_EQ(0u, db->Remaining());
-        return DecodeStatus::kDecodeInProgress;
-      case DecodeStatus::kDecodeError:
-        HTTP2_CODE_COUNT_N(decompress_failure_3, 1, 23);
-        return DecodeStatus::kDecodeError;
-    }
-  }
-  QUICHE_DCHECK(before_entry_);
-  while (db->HasData()) {
-    HTTP2_DVLOG(2) << "HpackBlockDecoder::Decode start entry, db->Remaining="
-                   << db->Remaining();
-    DecodeStatus status = entry_decoder_.Start(db, listener_);
-    switch (status) {
-      case DecodeStatus::kDecodeDone:
-        continue;
-      case DecodeStatus::kDecodeInProgress:
-        QUICHE_DCHECK_EQ(0u, db->Remaining());
-        before_entry_ = false;
-        return DecodeStatus::kDecodeInProgress;
-      case DecodeStatus::kDecodeError:
-        HTTP2_CODE_COUNT_N(decompress_failure_3, 2, 23);
-        return DecodeStatus::kDecodeError;
-    }
-    QUICHE_DCHECK(false);
-  }
-  QUICHE_DCHECK(before_entry_);
-  return DecodeStatus::kDecodeDone;
-}
-
-std::string HpackBlockDecoder::DebugString() const {
-  return absl::StrCat(
-      "HpackBlockDecoder(", entry_decoder_.DebugString(), ", listener@",
-      absl::Hex(reinterpret_cast<intptr_t>(listener_)),
-      (before_entry_ ? ", between entries)" : ", in an entry)"));
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackBlockDecoder& v) {
-  return out << v.DebugString();
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_block_decoder.h b/http2/hpack/decoder/hpack_block_decoder.h
deleted file mode 100644
index 3d956b1..0000000
--- a/http2/hpack/decoder/hpack_block_decoder.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_DECODER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_DECODER_H_
-
-// HpackBlockDecoder decodes an entire HPACK block (or the available portion
-// thereof in the DecodeBuffer) into entries, but doesn't include HPACK static
-// or dynamic table support, so table indices remain indices at this level.
-// Reports the entries to an HpackEntryDecoderListener.
-
-#include <string>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-#include "http2/hpack/decoder/hpack_entry_decoder.h"
-#include "http2/hpack/decoder/hpack_entry_decoder_listener.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackBlockDecoder {
- public:
-  explicit HpackBlockDecoder(HpackEntryDecoderListener* listener)
-      : listener_(listener) {
-    QUICHE_DCHECK_NE(listener_, nullptr);
-  }
-  ~HpackBlockDecoder() {}
-
-  HpackBlockDecoder(const HpackBlockDecoder&) = delete;
-  HpackBlockDecoder& operator=(const HpackBlockDecoder&) = delete;
-
-  // Prepares the decoder to start decoding a new HPACK block. Expected
-  // to be called from an implementation of Http2FrameDecoderListener's
-  // OnHeadersStart or OnPushPromiseStart methods.
-  void Reset() {
-    HTTP2_DVLOG(2) << "HpackBlockDecoder::Reset";
-    before_entry_ = true;
-  }
-
-  // Decode the fragment of the HPACK block contained in the decode buffer.
-  // Expected to be called from an implementation of Http2FrameDecoderListener's
-  // OnHpackFragment method.
-  DecodeStatus Decode(DecodeBuffer* db);
-
-  // Is the decoding process between entries (i.e. would the next byte be the
-  // first byte of a new HPACK entry)?
-  bool before_entry() const { return before_entry_; }
-
-  // Return error code after decoding error occurred in HpackEntryDecoder.
-  HpackDecodingError error() const { return entry_decoder_.error(); }
-
-  std::string DebugString() const;
-
- private:
-  HpackEntryDecoder entry_decoder_;
-  HpackEntryDecoderListener* const listener_;
-  bool before_entry_ = true;
-};
-
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const HpackBlockDecoder& v);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_DECODER_H_
diff --git a/http2/hpack/decoder/hpack_block_decoder_test.cc b/http2/hpack/decoder/hpack_block_decoder_test.cc
deleted file mode 100644
index 216eba4..0000000
--- a/http2/hpack/decoder/hpack_block_decoder_test.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_block_decoder.h"
-
-// Tests of HpackBlockDecoder.
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/hpack/decoder/hpack_block_collector.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/hpack/tools/hpack_example.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-class HpackBlockDecoderTest : public RandomDecoderTest {
- protected:
-  HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) {
-    stop_decode_on_done_ = false;
-    decoder_.Reset();
-    // Make sure logging doesn't crash. Not examining the result.
-    std::ostringstream strm;
-    strm << decoder_;
-  }
-
-  DecodeStatus StartDecoding(DecodeBuffer* db) override {
-    collector_.Clear();
-    decoder_.Reset();
-    return ResumeDecoding(db);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* db) override {
-    DecodeStatus status = decoder_.Decode(db);
-
-    // Make sure logging doesn't crash. Not examining the result.
-    std::ostringstream strm;
-    strm << decoder_;
-
-    return status;
-  }
-
-  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* db,
-                                               const Validator& validator) {
-    bool return_non_zero_on_first = false;
-    return RandomDecoderTest::DecodeAndValidateSeveralWays(
-        db, return_non_zero_on_first, validator);
-  }
-
-  AssertionResult DecodeAndValidateSeveralWays(const HpackBlockBuilder& hbb,
-                                               const Validator& validator) {
-    DecodeBuffer db(hbb.buffer());
-    return DecodeAndValidateSeveralWays(&db, validator);
-  }
-
-  AssertionResult DecodeHpackExampleAndValidateSeveralWays(
-      absl::string_view hpack_example,
-      Validator validator) {
-    std::string input = HpackExampleToStringOrDie(hpack_example);
-    DecodeBuffer db(input);
-    return DecodeAndValidateSeveralWays(&db, validator);
-  }
-
-  uint8_t Rand8() { return Random().Rand8(); }
-
-  std::string Rand8String() { return Random().RandString(Rand8()); }
-
-  HpackBlockCollector collector_;
-  HpackEntryDecoderVLoggingListener listener_;
-  HpackBlockDecoder decoder_;
-};
-
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1
-TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) {
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader(
-        HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false,
-        "custom-header"));
-  };
-  const char hpack_example[] = R"(
-      40                                      | == Literal indexed ==
-      0a                                      |   Literal name (len = 10)
-      6375 7374 6f6d 2d6b 6579                | custom-key
-      0d                                      |   Literal value (len = 13)
-      6375 7374 6f6d 2d68 6561 6465 72        | custom-header
-                                              | -> custom-key:
-                                              |   custom-header
-      )";
-  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
-      hpack_example, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2
-TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) {
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralValueHeader(
-        HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path"));
-  };
-  const char hpack_example[] = R"(
-      04                                      | == Literal not indexed ==
-                                              |   Indexed name (idx = 4)
-                                              |     :path
-      0c                                      |   Literal value (len = 12)
-      2f73 616d 706c 652f 7061 7468           | /sample/path
-                                              | -> :path: /sample/path
-      )";
-  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
-      hpack_example, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3
-TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) {
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader(
-        HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false,
-        "secret"));
-  };
-  const char hpack_example[] = R"(
-      10                                      | == Literal never indexed ==
-      08                                      |   Literal name (len = 8)
-      7061 7373 776f 7264                     | password
-      06                                      |   Literal value (len = 6)
-      7365 6372 6574                          | secret
-                                              | -> password: secret
-      )";
-  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
-      hpack_example, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4
-TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) {
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleIndexedHeader(2));
-  };
-  const char hpack_example[] = R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      )";
-  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
-      hpack_example, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1
-TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) {
-  std::string example = R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      86                                      | == Indexed - Add ==
-                                              |   idx = 6
-                                              | -> :scheme: http
-      84                                      | == Indexed - Add ==
-                                              |   idx = 4
-                                              | -> :path: /
-      41                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 1)
-                                              |     :authority
-      0f                                      |   Literal value (len = 15)
-      7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
-                                              | -> :authority:
-                                              |   www.example.com
-      )";
-  HpackBlockCollector expected;
-  expected.ExpectIndexedHeader(2);
-  expected.ExpectIndexedHeader(6);
-  expected.ExpectIndexedHeader(4);
-  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
-                                          1, false, "www.example.com");
-  NoArgValidator do_check = [expected, this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected));
-  };
-  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
-      example, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1
-TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) {
-  std::string example = R"(
-      48                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 8)
-                                              |     :status
-      03                                      |   Literal value (len = 3)
-      3330 32                                 | 302
-                                              | -> :status: 302
-      58                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 24)
-                                              |     cache-control
-      07                                      |   Literal value (len = 7)
-      7072 6976 6174 65                       | private
-                                              | -> cache-control: private
-      61                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 33)
-                                              |     date
-      1d                                      |   Literal value (len = 29)
-      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
-      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:21 GMT
-      6e                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 46)
-                                              |     location
-      17                                      |   Literal value (len = 23)
-      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
-      706c 652e 636f 6d                       | ple.com
-                                              | -> location:
-                                              |   https://www.example.com
-      )";
-  HpackBlockCollector expected;
-  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
-                                          8, false, "302");
-  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
-                                          24, false, "private");
-  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
-                                          33, false,
-                                          "Mon, 21 Oct 2013 20:13:21 GMT");
-  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
-                                          46, false, "https://www.example.com");
-  NoArgValidator do_check = [expected, this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected));
-  };
-  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
-      example, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-// Generate a bunch of HPACK block entries to expect, use those expectations
-// to generate an HPACK block, then decode it and confirm it matches those
-// expectations. Some of these are invalid (such as Indexed, with index=0),
-// but well-formed, and the decoder doesn't check for validity, just
-// well-formedness. That includes the validity of the strings not being checked,
-// such as lower-case ascii for the names, and valid Huffman encodings.
-TEST_F(HpackBlockDecoderTest, Computed) {
-  HpackBlockCollector expected;
-  expected.ExpectIndexedHeader(0);
-  expected.ExpectIndexedHeader(1);
-  expected.ExpectIndexedHeader(126);
-  expected.ExpectIndexedHeader(127);
-  expected.ExpectIndexedHeader(128);
-  expected.ExpectDynamicTableSizeUpdate(0);
-  expected.ExpectDynamicTableSizeUpdate(1);
-  expected.ExpectDynamicTableSizeUpdate(14);
-  expected.ExpectDynamicTableSizeUpdate(15);
-  expected.ExpectDynamicTableSizeUpdate(30);
-  expected.ExpectDynamicTableSizeUpdate(31);
-  expected.ExpectDynamicTableSizeUpdate(4095);
-  expected.ExpectDynamicTableSizeUpdate(4096);
-  expected.ExpectDynamicTableSizeUpdate(8192);
-  for (auto type : {HpackEntryType::kIndexedLiteralHeader,
-                    HpackEntryType::kUnindexedLiteralHeader,
-                    HpackEntryType::kNeverIndexedLiteralHeader}) {
-    for (bool value_huffman : {false, true}) {
-      // An entry with an index for the name. Ensure the name index
-      // is not zero by adding one to the Rand8() result.
-      expected.ExpectNameIndexAndLiteralValue(type, Rand8() + 1, value_huffman,
-                                              Rand8String());
-      // And two entries with literal names, one plain, one huffman encoded.
-      expected.ExpectLiteralNameAndValue(type, false, Rand8String(),
-                                         value_huffman, Rand8String());
-      expected.ExpectLiteralNameAndValue(type, true, Rand8String(),
-                                         value_huffman, Rand8String());
-    }
-  }
-  // Shuffle the entries and serialize them to produce an HPACK block.
-  expected.ShuffleEntries(RandomPtr());
-  HpackBlockBuilder hbb;
-  expected.AppendToHpackBlockBuilder(&hbb);
-
-  NoArgValidator do_check = [expected, this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected));
-  };
-  EXPECT_TRUE(
-      DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder.cc b/http2/hpack/decoder/hpack_decoder.cc
deleted file mode 100644
index 37933f1..0000000
--- a/http2/hpack/decoder/hpack_decoder.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder.h"
-
-#include "http2/decoder/decode_status.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_flags.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-HpackDecoder::HpackDecoder(HpackDecoderListener* listener,
-                           size_t max_string_size)
-    : decoder_state_(listener),
-      entry_buffer_(&decoder_state_, max_string_size),
-      block_decoder_(&entry_buffer_),
-      error_(HpackDecodingError::kOk) {}
-
-HpackDecoder::~HpackDecoder() = default;
-
-void HpackDecoder::set_max_string_size_bytes(size_t max_string_size_bytes) {
-  entry_buffer_.set_max_string_size_bytes(max_string_size_bytes);
-}
-
-void HpackDecoder::ApplyHeaderTableSizeSetting(uint32_t max_header_table_size) {
-  decoder_state_.ApplyHeaderTableSizeSetting(max_header_table_size);
-}
-
-bool HpackDecoder::StartDecodingBlock() {
-  HTTP2_DVLOG(3) << "HpackDecoder::StartDecodingBlock, error_detected="
-                 << (DetectError() ? "true" : "false");
-  if (DetectError()) {
-    return false;
-  }
-  // TODO(jamessynge): Eliminate Reset(), which shouldn't be necessary
-  // if there are no errors, and shouldn't be necessary with errors if
-  // we never resume decoding after an error has been detected.
-  block_decoder_.Reset();
-  decoder_state_.OnHeaderBlockStart();
-  return true;
-}
-
-bool HpackDecoder::DecodeFragment(DecodeBuffer* db) {
-  HTTP2_DVLOG(3) << "HpackDecoder::DecodeFragment, error_detected="
-                 << (DetectError() ? "true" : "false")
-                 << ", size=" << db->Remaining();
-  if (DetectError()) {
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 3, 23);
-    return false;
-  }
-  // Decode contents of db as an HPACK block fragment, forwards the decoded
-  // entries to entry_buffer_, which in turn forwards them to decode_state_,
-  // which finally forwards them to the HpackDecoderListener.
-  DecodeStatus status = block_decoder_.Decode(db);
-  if (status == DecodeStatus::kDecodeError) {
-    ReportError(block_decoder_.error(), "");
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 4, 23);
-    return false;
-  } else if (DetectError()) {
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 5, 23);
-    return false;
-  }
-  // Should be positioned between entries iff decoding is complete.
-  QUICHE_DCHECK_EQ(block_decoder_.before_entry(),
-                   status == DecodeStatus::kDecodeDone)
-      << status;
-  if (!block_decoder_.before_entry()) {
-    entry_buffer_.BufferStringsIfUnbuffered();
-  }
-  return true;
-}
-
-bool HpackDecoder::EndDecodingBlock() {
-  HTTP2_DVLOG(3) << "HpackDecoder::EndDecodingBlock, error_detected="
-                 << (DetectError() ? "true" : "false");
-  if (DetectError()) {
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 6, 23);
-    return false;
-  }
-  if (!block_decoder_.before_entry()) {
-    // The HPACK block ended in the middle of an entry.
-    ReportError(HpackDecodingError::kTruncatedBlock, "");
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 7, 23);
-    return false;
-  }
-  decoder_state_.OnHeaderBlockEnd();
-  if (DetectError()) {
-    // HpackDecoderState will have reported the error.
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 8, 23);
-    return false;
-  }
-  return true;
-}
-
-bool HpackDecoder::DetectError() {
-  if (error_ != HpackDecodingError::kOk) {
-    return true;
-  }
-
-  if (decoder_state_.error() != HpackDecodingError::kOk) {
-    HTTP2_DVLOG(2) << "Error detected in decoder_state_";
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 10, 23);
-    error_ = decoder_state_.error();
-    detailed_error_ = decoder_state_.detailed_error();
-  }
-
-  return error_ != HpackDecodingError::kOk;
-}
-
-void HpackDecoder::ReportError(HpackDecodingError error,
-                               std::string detailed_error) {
-  HTTP2_DVLOG(3) << "HpackDecoder::ReportError is new="
-                 << (error_ == HpackDecodingError::kOk ? "true" : "false")
-                 << ", error: " << HpackDecodingErrorToString(error);
-  if (error_ == HpackDecodingError::kOk) {
-    error_ = error;
-    detailed_error_ = detailed_error;
-    decoder_state_.listener()->OnHeaderErrorDetected(
-        HpackDecodingErrorToString(error));
-  }
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder.h b/http2/hpack/decoder/hpack_decoder.h
deleted file mode 100644
index 3ac5819..0000000
--- a/http2/hpack/decoder/hpack_decoder.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_H_
-
-// Decodes HPACK blocks, calls an HpackDecoderListener with the decoded header
-// entries. Also notifies the listener of errors and of the boundaries of the
-// HPACK blocks.
-
-// TODO(jamessynge): Add feature allowing an HpackEntryDecoderListener
-// sub-class (and possibly others) to be passed in for counting events,
-// so that deciding whether to count is not done by having lots of if
-// statements, but instead by inserting an indirection only when needed.
-
-// TODO(jamessynge): Consider whether to return false from methods below
-// when an error has been previously detected. It protects calling code
-// from its failure to pay attention to previous errors, but should we
-// spend time to do that?
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/hpack/decoder/hpack_block_decoder.h"
-#include "http2/hpack/decoder/hpack_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_decoder_state.h"
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-#include "http2/hpack/decoder/hpack_whole_entry_buffer.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class HpackDecoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE HpackDecoder {
- public:
-  HpackDecoder(HpackDecoderListener* listener, size_t max_string_size);
-  virtual ~HpackDecoder();
-
-  HpackDecoder(const HpackDecoder&) = delete;
-  HpackDecoder& operator=(const HpackDecoder&) = delete;
-
-  // max_string_size specifies the maximum size of an on-the-wire string (name
-  // or value, plain or Huffman encoded) that will be accepted. See sections
-  // 5.1 and 5.2 of RFC 7541. This is a defense against OOM attacks; HTTP/2
-  // allows a decoder to enforce any limit of the size of the header lists
-  // that it is willing to decode, including less than the MAX_HEADER_LIST_SIZE
-  // setting, a setting that is initially unlimited. For example, we might
-  // choose to send a MAX_HEADER_LIST_SIZE of 64KB, and to use that same value
-  // as the upper bound for individual strings.
-  void set_max_string_size_bytes(size_t max_string_size_bytes);
-
-  // ApplyHeaderTableSizeSetting notifies this object that this endpoint has
-  // received a SETTINGS ACK frame acknowledging an earlier SETTINGS frame from
-  // this endpoint specifying a new value for SETTINGS_HEADER_TABLE_SIZE (the
-  // maximum size of the dynamic table that this endpoint will use to decode
-  // HPACK blocks).
-  // Because a SETTINGS frame can contain SETTINGS_HEADER_TABLE_SIZE values,
-  // the caller must keep track of those multiple changes, and make
-  // corresponding calls to this method. In particular, a call must be made
-  // with the lowest value acknowledged by the peer, and a call must be made
-  // with the final value acknowledged, in that order; additional calls may
-  // be made if additional values were sent. These calls must be made between
-  // decoding the SETTINGS ACK, and before the next HPACK block is decoded.
-  void ApplyHeaderTableSizeSetting(uint32_t max_header_table_size);
-
-  // Returns the most recently applied value of SETTINGS_HEADER_TABLE_SIZE.
-  size_t GetCurrentHeaderTableSizeSetting() const {
-    return decoder_state_.GetCurrentHeaderTableSizeSetting();
-  }
-
-  // Prepares the decoder for decoding a new HPACK block, and announces this to
-  // its listener. Returns true if OK to continue with decoding, false if an
-  // error has been detected, which for StartDecodingBlock means the error was
-  // detected while decoding a previous HPACK block.
-  bool StartDecodingBlock();
-
-  // Decodes a fragment (some or all of the remainder) of an HPACK block,
-  // reporting header entries (name & value pairs) that it completely decodes
-  // in the process to the listener. Returns true successfully decoded, false if
-  // an error has been detected, either during decoding of the fragment, or
-  // prior to this call.
-  bool DecodeFragment(DecodeBuffer* db);
-
-  // Completes the process of decoding an HPACK block: if the HPACK block was
-  // properly terminated, announces the end of the header list to the listener
-  // and returns true; else returns false.
-  bool EndDecodingBlock();
-
-  // If no error has been detected so far, query |decoder_state_| for errors and
-  // set |error_| if necessary.  Returns true if an error has ever been
-  // detected.
-  bool DetectError();
-
-  size_t GetDynamicTableSize() const {
-    return decoder_state_.GetDynamicTableSize();
-  }
-
-  // Error code if an error has occurred, HpackDecodingError::kOk otherwise.
-  HpackDecodingError error() const { return error_; }
-
-  std::string detailed_error() const { return detailed_error_; }
-
- private:
-  friend class test::HpackDecoderPeer;
-
-  // Reports an error to the listener IF this is the first error detected.
-  void ReportError(HpackDecodingError error, std::string detailed_error);
-
-  // The decompressor state, as defined by HPACK (i.e. the static and dynamic
-  // tables).
-  HpackDecoderState decoder_state_;
-
-  // Assembles the various parts of a header entry into whole entries.
-  HpackWholeEntryBuffer entry_buffer_;
-
-  // The decoder of HPACK blocks into entry parts, passed to entry_buffer_.
-  HpackBlockDecoder block_decoder_;
-
-  // Error code if an error has occurred, HpackDecodingError::kOk otherwise.
-  HpackDecodingError error_;
-  std::string detailed_error_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_H_
diff --git a/http2/hpack/decoder/hpack_decoder_listener.cc b/http2/hpack/decoder/hpack_decoder_listener.cc
deleted file mode 100644
index d1dea19..0000000
--- a/http2/hpack/decoder/hpack_decoder_listener.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_listener.h"
-
-namespace http2 {
-
-HpackDecoderListener::HpackDecoderListener() = default;
-HpackDecoderListener::~HpackDecoderListener() = default;
-
-HpackDecoderNoOpListener::HpackDecoderNoOpListener() = default;
-HpackDecoderNoOpListener::~HpackDecoderNoOpListener() = default;
-
-void HpackDecoderNoOpListener::OnHeaderListStart() {}
-void HpackDecoderNoOpListener::OnHeader(const std::string& /*name*/,
-                                        const std::string& /*value*/) {}
-void HpackDecoderNoOpListener::OnHeaderListEnd() {}
-void HpackDecoderNoOpListener::OnHeaderErrorDetected(
-    absl::string_view /*error_message*/) {}
-
-// static
-HpackDecoderNoOpListener* HpackDecoderNoOpListener::NoOpListener() {
-  static HpackDecoderNoOpListener* static_instance =
-      new HpackDecoderNoOpListener();
-  return static_instance;
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_listener.h b/http2/hpack/decoder/hpack_decoder_listener.h
deleted file mode 100644
index d341025..0000000
--- a/http2/hpack/decoder/hpack_decoder_listener.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Defines HpackDecoderListener, the base class of listeners for HTTP header
-// lists decoded from an HPACK block.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackDecoderListener {
- public:
-  HpackDecoderListener();
-  virtual ~HpackDecoderListener();
-
-  // OnHeaderListStart is called at the start of decoding an HPACK block into
-  // an HTTP/2 header list. Will only be called once per block, even if it
-  // extends into CONTINUATION frames.
-  virtual void OnHeaderListStart() = 0;
-
-  // Called for each header name-value pair that is decoded, in the order they
-  // appear in the HPACK block. Multiple values for a given key will be emitted
-  // as multiple calls to OnHeader.
-  virtual void OnHeader(const std::string& name, const std::string& value) = 0;
-
-  // OnHeaderListEnd is called after successfully decoding an HPACK block into
-  // an HTTP/2 header list. Will only be called once per block, even if it
-  // extends into CONTINUATION frames.
-  virtual void OnHeaderListEnd() = 0;
-
-  // OnHeaderErrorDetected is called if an error is detected while decoding.
-  // error_message may be used in a GOAWAY frame as the Opaque Data.
-  virtual void OnHeaderErrorDetected(absl::string_view error_message) = 0;
-};
-
-// A no-op implementation of HpackDecoderListener, useful for ignoring
-// callbacks once an error is detected.
-class QUICHE_EXPORT_PRIVATE HpackDecoderNoOpListener
-    : public HpackDecoderListener {
- public:
-  HpackDecoderNoOpListener();
-  ~HpackDecoderNoOpListener() override;
-
-  void OnHeaderListStart() override;
-  void OnHeader(const std::string& name, const std::string& value) override;
-  void OnHeaderListEnd() override;
-  void OnHeaderErrorDetected(absl::string_view error_message) override;
-
-  // Returns a listener that ignores all the calls.
-  static HpackDecoderNoOpListener* NoOpListener();
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_
diff --git a/http2/hpack/decoder/hpack_decoder_state.cc b/http2/hpack/decoder/hpack_decoder_state.cc
deleted file mode 100644
index 92c7b25..0000000
--- a/http2/hpack/decoder/hpack_decoder_state.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_state.h"
-
-#include <utility>
-
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace http2 {
-namespace {
-
-std::string ExtractString(HpackDecoderStringBuffer* string_buffer) {
-  if (string_buffer->IsBuffered()) {
-    return string_buffer->ReleaseString();
-  } else {
-    auto result = std::string(string_buffer->str());
-    string_buffer->Reset();
-    return result;
-  }
-}
-
-}  // namespace
-
-HpackDecoderState::HpackDecoderState(HpackDecoderListener* listener)
-    : listener_(listener),
-      final_header_table_size_(Http2SettingsInfo::DefaultHeaderTableSize()),
-      lowest_header_table_size_(final_header_table_size_),
-      require_dynamic_table_size_update_(false),
-      allow_dynamic_table_size_update_(true),
-      saw_dynamic_table_size_update_(false),
-      error_(HpackDecodingError::kOk) {
-  QUICHE_CHECK(listener_);
-}
-
-HpackDecoderState::~HpackDecoderState() = default;
-
-void HpackDecoderState::ApplyHeaderTableSizeSetting(
-    uint32_t header_table_size) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::ApplyHeaderTableSizeSetting("
-                 << header_table_size << ")";
-  QUICHE_DCHECK_LE(lowest_header_table_size_, final_header_table_size_);
-  if (header_table_size < lowest_header_table_size_) {
-    lowest_header_table_size_ = header_table_size;
-  }
-  final_header_table_size_ = header_table_size;
-  HTTP2_DVLOG(2) << "low water mark: " << lowest_header_table_size_;
-  HTTP2_DVLOG(2) << "final limit: " << final_header_table_size_;
-}
-
-// Called to notify this object that we're starting to decode an HPACK block
-// (e.g. a HEADERS or PUSH_PROMISE frame's header has been decoded).
-void HpackDecoderState::OnHeaderBlockStart() {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnHeaderBlockStart";
-  // This instance can't be reused after an error has been detected, as we must
-  // assume that the encoder and decoder compression states are no longer
-  // synchronized.
-  QUICHE_DCHECK(error_ == HpackDecodingError::kOk)
-      << HpackDecodingErrorToString(error_);
-  QUICHE_DCHECK_LE(lowest_header_table_size_, final_header_table_size_);
-  allow_dynamic_table_size_update_ = true;
-  saw_dynamic_table_size_update_ = false;
-  // If the peer has acknowledged a HEADER_TABLE_SIZE smaller than that which
-  // its HPACK encoder has been using, then the next HPACK block it sends MUST
-  // start with a Dynamic Table Size Update entry that is at least as low as
-  // lowest_header_table_size_. That may be followed by another as great as
-  // final_header_table_size_, if those are different.
-  require_dynamic_table_size_update_ =
-      (lowest_header_table_size_ <
-           decoder_tables_.current_header_table_size() ||
-       final_header_table_size_ < decoder_tables_.header_table_size_limit());
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnHeaderListStart "
-                 << "require_dynamic_table_size_update_="
-                 << require_dynamic_table_size_update_;
-  listener_->OnHeaderListStart();
-}
-
-void HpackDecoderState::OnIndexedHeader(size_t index) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnIndexedHeader: " << index;
-  if (error_ != HpackDecodingError::kOk) {
-    return;
-  }
-  if (require_dynamic_table_size_update_) {
-    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
-    return;
-  }
-  allow_dynamic_table_size_update_ = false;
-  const HpackStringPair* entry = decoder_tables_.Lookup(index);
-  if (entry != nullptr) {
-    listener_->OnHeader(entry->name, entry->value);
-  } else {
-    ReportError(HpackDecodingError::kInvalidIndex, "");
-  }
-}
-
-void HpackDecoderState::OnNameIndexAndLiteralValue(
-    HpackEntryType entry_type,
-    size_t name_index,
-    HpackDecoderStringBuffer* value_buffer) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnNameIndexAndLiteralValue "
-                 << entry_type << ", " << name_index << ", "
-                 << value_buffer->str();
-  if (error_ != HpackDecodingError::kOk) {
-    return;
-  }
-  if (require_dynamic_table_size_update_) {
-    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
-    return;
-  }
-  allow_dynamic_table_size_update_ = false;
-  const HpackStringPair* entry = decoder_tables_.Lookup(name_index);
-  if (entry != nullptr) {
-    std::string value(ExtractString(value_buffer));
-    listener_->OnHeader(entry->name, value);
-    if (entry_type == HpackEntryType::kIndexedLiteralHeader) {
-      decoder_tables_.Insert(entry->name, std::move(value));
-    }
-  } else {
-    ReportError(HpackDecodingError::kInvalidNameIndex, "");
-  }
-}
-
-void HpackDecoderState::OnLiteralNameAndValue(
-    HpackEntryType entry_type,
-    HpackDecoderStringBuffer* name_buffer,
-    HpackDecoderStringBuffer* value_buffer) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnLiteralNameAndValue " << entry_type
-                 << ", " << name_buffer->str() << ", " << value_buffer->str();
-  if (error_ != HpackDecodingError::kOk) {
-    return;
-  }
-  if (require_dynamic_table_size_update_) {
-    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
-    return;
-  }
-  allow_dynamic_table_size_update_ = false;
-  std::string name(ExtractString(name_buffer));
-  std::string value(ExtractString(value_buffer));
-  listener_->OnHeader(name, value);
-  if (entry_type == HpackEntryType::kIndexedLiteralHeader) {
-    decoder_tables_.Insert(std::move(name), std::move(value));
-  }
-}
-
-void HpackDecoderState::OnDynamicTableSizeUpdate(size_t size_limit) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnDynamicTableSizeUpdate " << size_limit
-                 << ", required="
-                 << (require_dynamic_table_size_update_ ? "true" : "false")
-                 << ", allowed="
-                 << (allow_dynamic_table_size_update_ ? "true" : "false");
-  if (error_ != HpackDecodingError::kOk) {
-    return;
-  }
-  QUICHE_DCHECK_LE(lowest_header_table_size_, final_header_table_size_);
-  if (!allow_dynamic_table_size_update_) {
-    // At most two dynamic table size updates allowed at the start, and not
-    // after a header.
-    ReportError(HpackDecodingError::kDynamicTableSizeUpdateNotAllowed, "");
-    return;
-  }
-  if (require_dynamic_table_size_update_) {
-    // The new size must not be greater than the low water mark.
-    if (size_limit > lowest_header_table_size_) {
-      ReportError(
-          HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark,
-          "");
-      return;
-    }
-    require_dynamic_table_size_update_ = false;
-  } else if (size_limit > final_header_table_size_) {
-    // The new size must not be greater than the final max header table size
-    // that the peer acknowledged.
-    ReportError(
-        HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting,
-        "");
-    return;
-  }
-  decoder_tables_.DynamicTableSizeUpdate(size_limit);
-  if (saw_dynamic_table_size_update_) {
-    allow_dynamic_table_size_update_ = false;
-  } else {
-    saw_dynamic_table_size_update_ = true;
-  }
-  // We no longer need to keep an eye out for a lower header table size.
-  lowest_header_table_size_ = final_header_table_size_;
-}
-
-void HpackDecoderState::OnHpackDecodeError(HpackDecodingError error,
-                                           std::string detailed_error) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnHpackDecodeError "
-                 << HpackDecodingErrorToString(error);
-  if (error_ == HpackDecodingError::kOk) {
-    ReportError(error, detailed_error);
-  }
-}
-
-void HpackDecoderState::OnHeaderBlockEnd() {
-  HTTP2_DVLOG(2) << "HpackDecoderState::OnHeaderBlockEnd";
-  if (error_ != HpackDecodingError::kOk) {
-    return;
-  }
-  if (require_dynamic_table_size_update_) {
-    // Apparently the HPACK block was empty, but we needed it to contain at
-    // least 1 dynamic table size update.
-    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
-  } else {
-    listener_->OnHeaderListEnd();
-  }
-}
-
-void HpackDecoderState::ReportError(HpackDecodingError error,
-                                    std::string detailed_error) {
-  HTTP2_DVLOG(2) << "HpackDecoderState::ReportError is new="
-                 << (error_ == HpackDecodingError::kOk ? "true" : "false")
-                 << ", error: " << HpackDecodingErrorToString(error);
-  if (error_ == HpackDecodingError::kOk) {
-    listener_->OnHeaderErrorDetected(HpackDecodingErrorToString(error));
-    error_ = error;
-    detailed_error_ = detailed_error;
-  }
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_state.h b/http2/hpack/decoder/hpack_decoder_state.h
deleted file mode 100644
index 3040c18..0000000
--- a/http2/hpack/decoder/hpack_decoder_state.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// HpackDecoderState maintains the HPACK decompressor state; i.e. updates the
-// HPACK dynamic table according to RFC 7541 as the entries in an HPACK block
-// are decoded, and reads from the static and dynamic tables in order to build
-// complete header entries. Calls an HpackDecoderListener with the completely
-// decoded headers (i.e. after resolving table indices into names or values),
-// thus translating the decoded HPACK entries into HTTP/2 headers.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_decoder_string_buffer.h"
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-#include "http2/hpack/decoder/hpack_whole_entry_listener.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-class HpackDecoderStatePeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE HpackDecoderState : public HpackWholeEntryListener {
- public:
-  explicit HpackDecoderState(HpackDecoderListener* listener);
-  ~HpackDecoderState() override;
-
-  HpackDecoderState(const HpackDecoderState&) = delete;
-  HpackDecoderState& operator=(const HpackDecoderState&) = delete;
-
-  // Set the listener to be notified when a whole entry has been decoded,
-  // including resolving name or name and value references.
-  // The listener may be changed at any time.
-  HpackDecoderListener* listener() const { return listener_; }
-
-  // ApplyHeaderTableSizeSetting notifies this object that this endpoint has
-  // received a SETTINGS ACK frame acknowledging an earlier SETTINGS frame from
-  // this endpoint specifying a new value for SETTINGS_HEADER_TABLE_SIZE (the
-  // maximum size of the dynamic table that this endpoint will use to decode
-  // HPACK blocks).
-  // Because a SETTINGS frame can contain SETTINGS_HEADER_TABLE_SIZE values,
-  // the caller must keep track of those multiple changes, and make
-  // corresponding calls to this method. In particular, a call must be made
-  // with the lowest value acknowledged by the peer, and a call must be made
-  // with the final value acknowledged, in that order; additional calls may
-  // be made if additional values were sent. These calls must be made between
-  // decoding the SETTINGS ACK, and before the next HPACK block is decoded.
-  void ApplyHeaderTableSizeSetting(uint32_t max_header_table_size);
-
-  // Returns the most recently applied value of SETTINGS_HEADER_TABLE_SIZE.
-  size_t GetCurrentHeaderTableSizeSetting() const {
-    return final_header_table_size_;
-  }
-
-  // OnHeaderBlockStart notifies this object that we're starting to decode the
-  // HPACK payload of a HEADERS or PUSH_PROMISE frame.
-  void OnHeaderBlockStart();
-
-  // Implement the HpackWholeEntryListener methods, each of which notifies this
-  // object when an entire entry has been decoded.
-  void OnIndexedHeader(size_t index) override;
-  void OnNameIndexAndLiteralValue(
-      HpackEntryType entry_type,
-      size_t name_index,
-      HpackDecoderStringBuffer* value_buffer) override;
-  void OnLiteralNameAndValue(HpackEntryType entry_type,
-                             HpackDecoderStringBuffer* name_buffer,
-                             HpackDecoderStringBuffer* value_buffer) override;
-  void OnDynamicTableSizeUpdate(size_t size) override;
-  void OnHpackDecodeError(HpackDecodingError error,
-                          std::string detailed_error) override;
-
-  // OnHeaderBlockEnd notifies this object that an entire HPACK block has been
-  // decoded, which might have extended into CONTINUATION blocks.
-  void OnHeaderBlockEnd();
-
-  // Returns error code after an error has been detected and reported.
-  // No further callbacks will be made to the listener.
-  HpackDecodingError error() const { return error_; }
-
-  size_t GetDynamicTableSize() const {
-    return decoder_tables_.current_header_table_size();
-  }
-
-  const HpackDecoderTables& decoder_tables_for_test() const {
-    return decoder_tables_;
-  }
-
-  std::string detailed_error() const { return detailed_error_; }
-
- private:
-  friend class test::HpackDecoderStatePeer;
-
-  // Reports an error to the listener IF this is the first error detected.
-  void ReportError(HpackDecodingError error, std::string detailed_error);
-
-  // The static and dynamic HPACK tables.
-  HpackDecoderTables decoder_tables_;
-
-  // The listener to be notified of headers, the start and end of header
-  // lists, and of errors.
-  HpackDecoderListener* listener_;
-
-  // The most recent HEADER_TABLE_SIZE setting acknowledged by the peer.
-  uint32_t final_header_table_size_;
-
-  // The lowest HEADER_TABLE_SIZE setting acknowledged by the peer; valid until
-  // the next HPACK block is decoded.
-  // TODO(jamessynge): Test raising the HEADER_TABLE_SIZE.
-  uint32_t lowest_header_table_size_;
-
-  // Must the next (first) HPACK entry be a dynamic table size update?
-  bool require_dynamic_table_size_update_;
-
-  // May the next (first or second) HPACK entry be a dynamic table size update?
-  bool allow_dynamic_table_size_update_;
-
-  // Have we already seen a dynamic table size update in this HPACK block?
-  bool saw_dynamic_table_size_update_;
-
-  // Has an error already been detected and reported to the listener?
-  HpackDecodingError error_;
-  std::string detailed_error_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
diff --git a/http2/hpack/decoder/hpack_decoder_state_test.cc b/http2/hpack/decoder/hpack_decoder_state_test.cc
deleted file mode 100644
index 7e36a17..0000000
--- a/http2/hpack/decoder/hpack_decoder_state_test.cc
+++ /dev/null
@@ -1,549 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_state.h"
-
-// Tests of HpackDecoderState.
-
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::Eq;
-using ::testing::Mock;
-using ::testing::StrictMock;
-
-namespace http2 {
-namespace test {
-class HpackDecoderStatePeer {
- public:
-  static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) {
-    return &state->decoder_tables_;
-  }
-};
-
-namespace {
-
-class MockHpackDecoderListener : public HpackDecoderListener {
- public:
-  MOCK_METHOD(void, OnHeaderListStart, (), (override));
-  MOCK_METHOD(void,
-              OnHeader,
-              (const std::string& name, const std::string& value),
-              (override));
-  MOCK_METHOD(void, OnHeaderListEnd, (), (override));
-  MOCK_METHOD(void,
-              OnHeaderErrorDetected,
-              (absl::string_view error_message),
-              (override));
-};
-
-enum StringBacking { STATIC, UNBUFFERED, BUFFERED };
-
-class HpackDecoderStateTest : public QuicheTest {
- protected:
-  HpackDecoderStateTest() : decoder_state_(&listener_) {}
-
-  HpackDecoderTables* GetDecoderTables() {
-    return HpackDecoderStatePeer::GetDecoderTables(&decoder_state_);
-  }
-
-  const HpackStringPair* Lookup(size_t index) {
-    return GetDecoderTables()->Lookup(index);
-  }
-
-  size_t current_header_table_size() {
-    return GetDecoderTables()->current_header_table_size();
-  }
-
-  size_t header_table_size_limit() {
-    return GetDecoderTables()->header_table_size_limit();
-  }
-
-  void set_header_table_size_limit(size_t size) {
-    GetDecoderTables()->DynamicTableSizeUpdate(size);
-  }
-
-  void SetStringBuffer(const char* s,
-                       StringBacking backing,
-                       HpackDecoderStringBuffer* string_buffer) {
-    switch (backing) {
-      case STATIC:
-        string_buffer->Set(s, true);
-        break;
-      case UNBUFFERED:
-        string_buffer->Set(s, false);
-        break;
-      case BUFFERED:
-        string_buffer->Set(s, false);
-        string_buffer->BufferStringIfUnbuffered();
-        break;
-    }
-  }
-
-  void SetName(const char* s, StringBacking backing) {
-    SetStringBuffer(s, backing, &name_buffer_);
-  }
-
-  void SetValue(const char* s, StringBacking backing) {
-    SetStringBuffer(s, backing, &value_buffer_);
-  }
-
-  void SendStartAndVerifyCallback() {
-    EXPECT_CALL(listener_, OnHeaderListStart());
-    decoder_state_.OnHeaderBlockStart();
-    Mock::VerifyAndClearExpectations(&listener_);
-  }
-
-  void SendSizeUpdate(size_t size) {
-    decoder_state_.OnDynamicTableSizeUpdate(size);
-    Mock::VerifyAndClearExpectations(&listener_);
-  }
-
-  void SendIndexAndVerifyCallback(size_t index,
-                                  HpackEntryType /*expected_type*/,
-                                  const char* expected_name,
-                                  const char* expected_value) {
-    EXPECT_CALL(listener_, OnHeader(Eq(expected_name), Eq(expected_value)));
-    decoder_state_.OnIndexedHeader(index);
-    Mock::VerifyAndClearExpectations(&listener_);
-  }
-
-  void SendValueAndVerifyCallback(size_t name_index,
-                                  HpackEntryType entry_type,
-                                  const char* name,
-                                  const char* value,
-                                  StringBacking value_backing) {
-    SetValue(value, value_backing);
-    EXPECT_CALL(listener_, OnHeader(Eq(name), Eq(value)));
-    decoder_state_.OnNameIndexAndLiteralValue(entry_type, name_index,
-                                              &value_buffer_);
-    Mock::VerifyAndClearExpectations(&listener_);
-  }
-
-  void SendNameAndValueAndVerifyCallback(HpackEntryType entry_type,
-                                         const char* name,
-                                         StringBacking name_backing,
-                                         const char* value,
-                                         StringBacking value_backing) {
-    SetName(name, name_backing);
-    SetValue(value, value_backing);
-    EXPECT_CALL(listener_, OnHeader(Eq(name), Eq(value)));
-    decoder_state_.OnLiteralNameAndValue(entry_type, &name_buffer_,
-                                         &value_buffer_);
-    Mock::VerifyAndClearExpectations(&listener_);
-  }
-
-  void SendEndAndVerifyCallback() {
-    EXPECT_CALL(listener_, OnHeaderListEnd());
-    decoder_state_.OnHeaderBlockEnd();
-    Mock::VerifyAndClearExpectations(&listener_);
-  }
-
-  // dynamic_index is one-based, because that is the way RFC 7541 shows it.
-  AssertionResult VerifyEntry(size_t dynamic_index,
-                              const char* name,
-                              const char* value) {
-    const HpackStringPair* entry =
-        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
-    VERIFY_NE(entry, nullptr);
-    VERIFY_EQ(entry->name, name);
-    VERIFY_EQ(entry->value, value);
-    return AssertionSuccess();
-  }
-  AssertionResult VerifyNoEntry(size_t dynamic_index) {
-    const HpackStringPair* entry =
-        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
-    VERIFY_EQ(entry, nullptr);
-    return AssertionSuccess();
-  }
-  AssertionResult VerifyDynamicTableContents(
-      const std::vector<std::pair<const char*, const char*>>& entries) {
-    size_t index = 1;
-    for (const auto& entry : entries) {
-      VERIFY_SUCCESS(VerifyEntry(index, entry.first, entry.second));
-      ++index;
-    }
-    VERIFY_SUCCESS(VerifyNoEntry(index));
-    return AssertionSuccess();
-  }
-
-  StrictMock<MockHpackDecoderListener> listener_;
-  HpackDecoderState decoder_state_;
-  HpackDecoderStringBuffer name_buffer_, value_buffer_;
-};
-
-// Test based on RFC 7541, section C.3: Request Examples without Huffman Coding.
-// This section shows several consecutive header lists, corresponding to HTTP
-// requests, on the same connection.
-TEST_F(HpackDecoderStateTest, C3_RequestExamples) {
-  // C.3.1 First Request
-  //
-  // Header list to encode:
-  //
-  //   :method: GET
-  //   :scheme: http
-  //   :path: /
-  //   :authority: www.example.com
-
-  SendStartAndVerifyCallback();
-  SendIndexAndVerifyCallback(2, HpackEntryType::kIndexedHeader, ":method",
-                             "GET");
-  SendIndexAndVerifyCallback(6, HpackEntryType::kIndexedHeader, ":scheme",
-                             "http");
-  SendIndexAndVerifyCallback(4, HpackEntryType::kIndexedHeader, ":path", "/");
-  SendValueAndVerifyCallback(1, HpackEntryType::kIndexedLiteralHeader,
-                             ":authority", "www.example.com", UNBUFFERED);
-  SendEndAndVerifyCallback();
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  57) :authority: www.example.com
-  //         Table size:  57
-
-  ASSERT_TRUE(VerifyDynamicTableContents({{":authority", "www.example.com"}}));
-  ASSERT_EQ(57u, current_header_table_size());
-
-  // C.3.2 Second Request
-  //
-  // Header list to encode:
-  //
-  //   :method: GET
-  //   :scheme: http
-  //   :path: /
-  //   :authority: www.example.com
-  //   cache-control: no-cache
-
-  SendStartAndVerifyCallback();
-  SendIndexAndVerifyCallback(2, HpackEntryType::kIndexedHeader, ":method",
-                             "GET");
-  SendIndexAndVerifyCallback(6, HpackEntryType::kIndexedHeader, ":scheme",
-                             "http");
-  SendIndexAndVerifyCallback(4, HpackEntryType::kIndexedHeader, ":path", "/");
-  SendIndexAndVerifyCallback(62, HpackEntryType::kIndexedHeader, ":authority",
-                             "www.example.com");
-  SendValueAndVerifyCallback(24, HpackEntryType::kIndexedLiteralHeader,
-                             "cache-control", "no-cache", UNBUFFERED);
-  SendEndAndVerifyCallback();
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  53) cache-control: no-cache
-  //   [  2] (s =  57) :authority: www.example.com
-  //         Table size: 110
-
-  ASSERT_TRUE(VerifyDynamicTableContents(
-      {{"cache-control", "no-cache"}, {":authority", "www.example.com"}}));
-  ASSERT_EQ(110u, current_header_table_size());
-
-  // C.3.3 Third Request
-  //
-  // Header list to encode:
-  //
-  //   :method: GET
-  //   :scheme: https
-  //   :path: /index.html
-  //   :authority: www.example.com
-  //   custom-key: custom-value
-
-  SendStartAndVerifyCallback();
-  SendIndexAndVerifyCallback(2, HpackEntryType::kIndexedHeader, ":method",
-                             "GET");
-  SendIndexAndVerifyCallback(7, HpackEntryType::kIndexedHeader, ":scheme",
-                             "https");
-  SendIndexAndVerifyCallback(5, HpackEntryType::kIndexedHeader, ":path",
-                             "/index.html");
-  SendIndexAndVerifyCallback(63, HpackEntryType::kIndexedHeader, ":authority",
-                             "www.example.com");
-  SendNameAndValueAndVerifyCallback(HpackEntryType::kIndexedLiteralHeader,
-                                    "custom-key", UNBUFFERED, "custom-value",
-                                    UNBUFFERED);
-  SendEndAndVerifyCallback();
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  54) custom-key: custom-value
-  //   [  2] (s =  53) cache-control: no-cache
-  //   [  3] (s =  57) :authority: www.example.com
-  //         Table size: 164
-
-  ASSERT_TRUE(VerifyDynamicTableContents({{"custom-key", "custom-value"},
-                                          {"cache-control", "no-cache"},
-                                          {":authority", "www.example.com"}}));
-  ASSERT_EQ(164u, current_header_table_size());
-}
-
-// Test based on RFC 7541, section C.5: Response Examples without Huffman
-// Coding. This section shows several consecutive header lists, corresponding
-// to HTTP responses, on the same connection. The HTTP/2 setting parameter
-// SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing
-// some evictions to occur.
-TEST_F(HpackDecoderStateTest, C5_ResponseExamples) {
-  set_header_table_size_limit(256);
-
-  // C.5.1 First Response
-  //
-  // Header list to encode:
-  //
-  //   :status: 302
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   location: https://www.example.com
-
-  SendStartAndVerifyCallback();
-  SendValueAndVerifyCallback(8, HpackEntryType::kIndexedLiteralHeader,
-                             ":status", "302", BUFFERED);
-  SendValueAndVerifyCallback(24, HpackEntryType::kIndexedLiteralHeader,
-                             "cache-control", "private", UNBUFFERED);
-  SendValueAndVerifyCallback(33, HpackEntryType::kIndexedLiteralHeader, "date",
-                             "Mon, 21 Oct 2013 20:13:21 GMT", UNBUFFERED);
-  SendValueAndVerifyCallback(46, HpackEntryType::kIndexedLiteralHeader,
-                             "location", "https://www.example.com", UNBUFFERED);
-  SendEndAndVerifyCallback();
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  63) location: https://www.example.com
-  //   [  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   [  3] (s =  52) cache-control: private
-  //   [  4] (s =  42) :status: 302
-  //         Table size: 222
-
-  ASSERT_TRUE(
-      VerifyDynamicTableContents({{"location", "https://www.example.com"},
-                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                                  {"cache-control", "private"},
-                                  {":status", "302"}}));
-  ASSERT_EQ(222u, current_header_table_size());
-
-  // C.5.2 Second Response
-  //
-  // The (":status", "302") header field is evicted from the dynamic table to
-  // free space to allow adding the (":status", "307") header field.
-  //
-  // Header list to encode:
-  //
-  //   :status: 307
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   location: https://www.example.com
-
-  SendStartAndVerifyCallback();
-  SendValueAndVerifyCallback(8, HpackEntryType::kIndexedLiteralHeader,
-                             ":status", "307", BUFFERED);
-  SendIndexAndVerifyCallback(65, HpackEntryType::kIndexedHeader,
-                             "cache-control", "private");
-  SendIndexAndVerifyCallback(64, HpackEntryType::kIndexedHeader, "date",
-                             "Mon, 21 Oct 2013 20:13:21 GMT");
-  SendIndexAndVerifyCallback(63, HpackEntryType::kIndexedHeader, "location",
-                             "https://www.example.com");
-  SendEndAndVerifyCallback();
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  42) :status: 307
-  //   [  2] (s =  63) location: https://www.example.com
-  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   [  4] (s =  52) cache-control: private
-  //         Table size: 222
-
-  ASSERT_TRUE(
-      VerifyDynamicTableContents({{":status", "307"},
-                                  {"location", "https://www.example.com"},
-                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                                  {"cache-control", "private"}}));
-  ASSERT_EQ(222u, current_header_table_size());
-
-  // C.5.3 Third Response
-  //
-  // Several header fields are evicted from the dynamic table during the
-  // processing of this header list.
-  //
-  // Header list to encode:
-  //
-  //   :status: 200
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:22 GMT
-  //   location: https://www.example.com
-  //   content-encoding: gzip
-  //   set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1
-
-  SendStartAndVerifyCallback();
-  SendIndexAndVerifyCallback(8, HpackEntryType::kIndexedHeader, ":status",
-                             "200");
-  SendIndexAndVerifyCallback(65, HpackEntryType::kIndexedHeader,
-                             "cache-control", "private");
-  SendValueAndVerifyCallback(33, HpackEntryType::kIndexedLiteralHeader, "date",
-                             "Mon, 21 Oct 2013 20:13:22 GMT", BUFFERED);
-  SendIndexAndVerifyCallback(64, HpackEntryType::kIndexedHeader, "location",
-                             "https://www.example.com");
-  SendValueAndVerifyCallback(26, HpackEntryType::kIndexedLiteralHeader,
-                             "content-encoding", "gzip", UNBUFFERED);
-  SendValueAndVerifyCallback(
-      55, HpackEntryType::kIndexedLiteralHeader, "set-cookie",
-      "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", BUFFERED);
-  SendEndAndVerifyCallback();
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
-  //                    max-age=3600; version=1
-  //   [  2] (s =  52) content-encoding: gzip
-  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
-  //         Table size: 215
-
-  ASSERT_TRUE(VerifyDynamicTableContents(
-      {{"set-cookie",
-        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
-       {"content-encoding", "gzip"},
-       {"date", "Mon, 21 Oct 2013 20:13:22 GMT"}}));
-  ASSERT_EQ(215u, current_header_table_size());
-}
-
-// Confirm that the table size can be changed, but at most twice.
-TEST_F(HpackDecoderStateTest, OptionalTableSizeChanges) {
-  SendStartAndVerifyCallback();
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-  SendSizeUpdate(1024);
-  EXPECT_EQ(1024u, header_table_size_limit());
-  SendSizeUpdate(0);
-  EXPECT_EQ(0u, header_table_size_limit());
-
-  // Three updates aren't allowed.
-  EXPECT_CALL(listener_, OnHeaderErrorDetected(
-                             Eq("Dynamic table size update not allowed")));
-  SendSizeUpdate(0);
-}
-
-// Confirm that required size updates are indeed required before headers.
-TEST_F(HpackDecoderStateTest, RequiredTableSizeChangeBeforeHeader) {
-  EXPECT_EQ(4096u, decoder_state_.GetCurrentHeaderTableSizeSetting());
-  decoder_state_.ApplyHeaderTableSizeSetting(1024);
-  decoder_state_.ApplyHeaderTableSizeSetting(2048);
-  EXPECT_EQ(2048u, decoder_state_.GetCurrentHeaderTableSizeSetting());
-
-  // First provide the required update, and an allowed second update.
-  SendStartAndVerifyCallback();
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-  SendSizeUpdate(1024);
-  EXPECT_EQ(1024u, header_table_size_limit());
-  SendSizeUpdate(1500);
-  EXPECT_EQ(1500u, header_table_size_limit());
-  SendEndAndVerifyCallback();
-
-  // Another HPACK block, but this time missing the required size update.
-  decoder_state_.ApplyHeaderTableSizeSetting(1024);
-  EXPECT_EQ(1024u, decoder_state_.GetCurrentHeaderTableSizeSetting());
-  SendStartAndVerifyCallback();
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(Eq("Missing dynamic table size update")));
-  decoder_state_.OnIndexedHeader(1);
-
-  // Further decoded entries are ignored.
-  decoder_state_.OnIndexedHeader(1);
-  decoder_state_.OnDynamicTableSizeUpdate(1);
-  SetValue("value", UNBUFFERED);
-  decoder_state_.OnNameIndexAndLiteralValue(
-      HpackEntryType::kIndexedLiteralHeader, 4, &value_buffer_);
-  SetName("name", UNBUFFERED);
-  decoder_state_.OnLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader,
-                                       &name_buffer_, &value_buffer_);
-  decoder_state_.OnHeaderBlockEnd();
-  decoder_state_.OnHpackDecodeError(HpackDecodingError::kIndexVarintError, "");
-}
-
-// Confirm that required size updates are validated.
-TEST_F(HpackDecoderStateTest, InvalidRequiredSizeUpdate) {
-  // Require a size update, but provide one that isn't small enough.
-  decoder_state_.ApplyHeaderTableSizeSetting(1024);
-  SendStartAndVerifyCallback();
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-  EXPECT_CALL(
-      listener_,
-      OnHeaderErrorDetected(
-          Eq("Initial dynamic table size update is above low water mark")));
-  SendSizeUpdate(2048);
-}
-
-// Confirm that required size updates are indeed required before the end.
-TEST_F(HpackDecoderStateTest, RequiredTableSizeChangeBeforeEnd) {
-  decoder_state_.ApplyHeaderTableSizeSetting(1024);
-  SendStartAndVerifyCallback();
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(Eq("Missing dynamic table size update")));
-  decoder_state_.OnHeaderBlockEnd();
-}
-
-// Confirm that optional size updates are validated.
-TEST_F(HpackDecoderStateTest, InvalidOptionalSizeUpdate) {
-  // Require a size update, but provide one that isn't small enough.
-  SendStartAndVerifyCallback();
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(Eq(
-                  "Dynamic table size update is above acknowledged setting")));
-  SendSizeUpdate(Http2SettingsInfo::DefaultHeaderTableSize() + 1);
-}
-
-TEST_F(HpackDecoderStateTest, InvalidStaticIndex) {
-  SendStartAndVerifyCallback();
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(
-                  Eq("Invalid index in indexed header field representation")));
-  decoder_state_.OnIndexedHeader(0);
-}
-
-TEST_F(HpackDecoderStateTest, InvalidDynamicIndex) {
-  SendStartAndVerifyCallback();
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(
-                  Eq("Invalid index in indexed header field representation")));
-  decoder_state_.OnIndexedHeader(kFirstDynamicTableIndex);
-}
-
-TEST_F(HpackDecoderStateTest, InvalidNameIndex) {
-  SendStartAndVerifyCallback();
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(Eq("Invalid index in literal header field "
-                                       "with indexed name representation")));
-  SetValue("value", UNBUFFERED);
-  decoder_state_.OnNameIndexAndLiteralValue(
-      HpackEntryType::kIndexedLiteralHeader, kFirstDynamicTableIndex,
-      &value_buffer_);
-}
-
-TEST_F(HpackDecoderStateTest, ErrorsSuppressCallbacks) {
-  SendStartAndVerifyCallback();
-  EXPECT_CALL(listener_,
-              OnHeaderErrorDetected(Eq("Name Huffman encoding error")));
-  decoder_state_.OnHpackDecodeError(HpackDecodingError::kNameHuffmanError, "");
-
-  // Further decoded entries are ignored.
-  decoder_state_.OnIndexedHeader(1);
-  decoder_state_.OnDynamicTableSizeUpdate(1);
-  SetValue("value", UNBUFFERED);
-  decoder_state_.OnNameIndexAndLiteralValue(
-      HpackEntryType::kIndexedLiteralHeader, 4, &value_buffer_);
-  SetName("name", UNBUFFERED);
-  decoder_state_.OnLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader,
-                                       &name_buffer_, &value_buffer_);
-  decoder_state_.OnHeaderBlockEnd();
-  decoder_state_.OnHpackDecodeError(HpackDecodingError::kIndexVarintError, "");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/http2/hpack/decoder/hpack_decoder_string_buffer.cc
deleted file mode 100644
index d035903..0000000
--- a/http2/hpack/decoder/hpack_decoder_string_buffer.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_string_buffer.h"
-
-#include <utility>
-
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::ostream& operator<<(std::ostream& out,
-                         const HpackDecoderStringBuffer::State v) {
-  switch (v) {
-    case HpackDecoderStringBuffer::State::RESET:
-      return out << "RESET";
-    case HpackDecoderStringBuffer::State::COLLECTING:
-      return out << "COLLECTING";
-    case HpackDecoderStringBuffer::State::COMPLETE:
-      return out << "COMPLETE";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  int unknown = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_50_1)
-      << "Invalid HpackDecoderStringBuffer::State: " << unknown;
-  return out << "HpackDecoderStringBuffer::State(" << unknown << ")";
-}
-
-std::ostream& operator<<(std::ostream& out,
-                         const HpackDecoderStringBuffer::Backing v) {
-  switch (v) {
-    case HpackDecoderStringBuffer::Backing::RESET:
-      return out << "RESET";
-    case HpackDecoderStringBuffer::Backing::UNBUFFERED:
-      return out << "UNBUFFERED";
-    case HpackDecoderStringBuffer::Backing::BUFFERED:
-      return out << "BUFFERED";
-    case HpackDecoderStringBuffer::Backing::STATIC:
-      return out << "STATIC";
-  }
-  // Since the value doesn't come over the wire, only a programming bug should
-  // result in reaching this point.
-  auto v2 = static_cast<int>(v);
-  HTTP2_BUG(http2_bug_50_2)
-      << "Invalid HpackDecoderStringBuffer::Backing: " << v2;
-  return out << "HpackDecoderStringBuffer::Backing(" << v2 << ")";
-}
-
-HpackDecoderStringBuffer::HpackDecoderStringBuffer()
-    : remaining_len_(0),
-      is_huffman_encoded_(false),
-      state_(State::RESET),
-      backing_(Backing::RESET) {}
-HpackDecoderStringBuffer::~HpackDecoderStringBuffer() = default;
-
-void HpackDecoderStringBuffer::Reset() {
-  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::Reset";
-  state_ = State::RESET;
-}
-
-void HpackDecoderStringBuffer::Set(absl::string_view value, bool is_static) {
-  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::Set";
-  QUICHE_DCHECK_EQ(state_, State::RESET);
-  value_ = value;
-  state_ = State::COMPLETE;
-  backing_ = is_static ? Backing::STATIC : Backing::UNBUFFERED;
-  // TODO(jamessynge): Determine which of these two fields must be set.
-  remaining_len_ = 0;
-  is_huffman_encoded_ = false;
-}
-
-void HpackDecoderStringBuffer::OnStart(bool huffman_encoded, size_t len) {
-  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::OnStart";
-  QUICHE_DCHECK_EQ(state_, State::RESET);
-
-  remaining_len_ = len;
-  is_huffman_encoded_ = huffman_encoded;
-  state_ = State::COLLECTING;
-
-  if (huffman_encoded) {
-    // We don't set, clear or use value_ for buffered strings until OnEnd.
-    decoder_.Reset();
-    buffer_.clear();
-    backing_ = Backing::BUFFERED;
-
-    // Reserve space in buffer_ for the uncompressed string, assuming the
-    // maximum expansion. The shortest Huffman codes in the RFC are 5 bits long,
-    // which then expand to 8 bits during decoding (i.e. each code is for one
-    // plain text octet, aka byte), so the maximum size is 60% longer than the
-    // encoded size.
-    len = len * 8 / 5;
-    if (buffer_.capacity() < len) {
-      buffer_.reserve(len);
-    }
-  } else {
-    // Assume for now that we won't need to use buffer_, so don't reserve space
-    // in it.
-    backing_ = Backing::RESET;
-    // OnData is not called for empty (zero length) strings, so make sure that
-    // value_ is cleared.
-    value_ = absl::string_view();
-  }
-}
-
-bool HpackDecoderStringBuffer::OnData(const char* data, size_t len) {
-  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::OnData state=" << state_
-                 << ", backing=" << backing_;
-  QUICHE_DCHECK_EQ(state_, State::COLLECTING);
-  QUICHE_DCHECK_LE(len, remaining_len_);
-  remaining_len_ -= len;
-
-  if (is_huffman_encoded_) {
-    QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
-    return decoder_.Decode(absl::string_view(data, len), &buffer_);
-  }
-
-  if (backing_ == Backing::RESET) {
-    // This is the first call to OnData. If data contains the entire string,
-    // don't copy the string. If we later find that the HPACK entry is split
-    // across input buffers, then we'll copy the string into buffer_.
-    if (remaining_len_ == 0) {
-      value_ = absl::string_view(data, len);
-      backing_ = Backing::UNBUFFERED;
-      return true;
-    }
-
-    // We need to buffer the string because it is split across input buffers.
-    // Reserve space in buffer_ for the entire string.
-    backing_ = Backing::BUFFERED;
-    buffer_.reserve(remaining_len_ + len);
-    buffer_.assign(data, len);
-    return true;
-  }
-
-  // This is not the first call to OnData for this string, so it should be
-  // buffered.
-  QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
-
-  // Append to the current contents of the buffer.
-  buffer_.append(data, len);
-  return true;
-}
-
-bool HpackDecoderStringBuffer::OnEnd() {
-  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::OnEnd";
-  QUICHE_DCHECK_EQ(state_, State::COLLECTING);
-  QUICHE_DCHECK_EQ(0u, remaining_len_);
-
-  if (is_huffman_encoded_) {
-    QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
-    // Did the Huffman encoding of the string end properly?
-    if (!decoder_.InputProperlyTerminated()) {
-      return false;  // No, it didn't.
-    }
-    value_ = buffer_;
-  } else if (backing_ == Backing::BUFFERED) {
-    value_ = buffer_;
-  }
-  state_ = State::COMPLETE;
-  return true;
-}
-
-void HpackDecoderStringBuffer::BufferStringIfUnbuffered() {
-  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::BufferStringIfUnbuffered state="
-                 << state_ << ", backing=" << backing_;
-  if (state_ != State::RESET && backing_ == Backing::UNBUFFERED) {
-    HTTP2_DVLOG(2)
-        << "HpackDecoderStringBuffer buffering std::string of length "
-        << value_.size();
-    buffer_.assign(value_.data(), value_.size());
-    if (state_ == State::COMPLETE) {
-      value_ = buffer_;
-    }
-    backing_ = Backing::BUFFERED;
-  }
-}
-
-bool HpackDecoderStringBuffer::IsBuffered() const {
-  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::IsBuffered";
-  return state_ != State::RESET && backing_ == Backing::BUFFERED;
-}
-
-size_t HpackDecoderStringBuffer::BufferedLength() const {
-  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::BufferedLength";
-  return IsBuffered() ? buffer_.size() : 0;
-}
-
-absl::string_view HpackDecoderStringBuffer::str() const {
-  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::str";
-  QUICHE_DCHECK_EQ(state_, State::COMPLETE);
-  return value_;
-}
-
-absl::string_view HpackDecoderStringBuffer::GetStringIfComplete() const {
-  if (state_ != State::COMPLETE) {
-    return {};
-  }
-  return str();
-}
-
-std::string HpackDecoderStringBuffer::ReleaseString() {
-  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::ReleaseString";
-  QUICHE_DCHECK_EQ(state_, State::COMPLETE);
-  QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
-  if (state_ == State::COMPLETE) {
-    state_ = State::RESET;
-    if (backing_ == Backing::BUFFERED) {
-      return std::move(buffer_);
-    } else {
-      return std::string(value_);
-    }
-  }
-  return "";
-}
-
-void HpackDecoderStringBuffer::OutputDebugStringTo(std::ostream& out) const {
-  out << "{state=" << state_;
-  if (state_ != State::RESET) {
-    out << ", backing=" << backing_;
-    out << ", remaining_len=" << remaining_len_;
-    out << ", is_huffman_encoded=" << is_huffman_encoded_;
-    if (backing_ == Backing::BUFFERED) {
-      out << ", buffer: " << buffer_;
-    } else {
-      out << ", value: " << value_;
-    }
-  }
-  out << "}";
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackDecoderStringBuffer& v) {
-  v.OutputDebugStringTo(out);
-  return out;
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_string_buffer.h b/http2/hpack/decoder/hpack_decoder_string_buffer.h
deleted file mode 100644
index 83f59ed..0000000
--- a/http2/hpack/decoder/hpack_decoder_string_buffer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
-
-// HpackDecoderStringBuffer helps an HPACK decoder to avoid copies of a string
-// literal (name or value) except when necessary (e.g. when split across two
-// or more HPACK block fragments).
-
-#include <stddef.h>
-
-#include <ostream>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/huffman/hpack_huffman_decoder.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackDecoderStringBuffer {
- public:
-  enum class State : uint8_t { RESET, COLLECTING, COMPLETE };
-  enum class Backing : uint8_t { RESET, UNBUFFERED, BUFFERED, STATIC };
-
-  HpackDecoderStringBuffer();
-  ~HpackDecoderStringBuffer();
-
-  HpackDecoderStringBuffer(const HpackDecoderStringBuffer&) = delete;
-  HpackDecoderStringBuffer& operator=(const HpackDecoderStringBuffer&) = delete;
-
-  void Reset();
-  void Set(absl::string_view value, bool is_static);
-
-  // Note that for Huffman encoded strings the length of the string after
-  // decoding may be larger (expected), the same or even smaller; the latter
-  // are unlikely, but possible if the encoder makes odd choices.
-  void OnStart(bool huffman_encoded, size_t len);
-  bool OnData(const char* data, size_t len);
-  bool OnEnd();
-  void BufferStringIfUnbuffered();
-  bool IsBuffered() const;
-  size_t BufferedLength() const;
-
-  // Accessors for the completely collected string (i.e. Set or OnEnd has just
-  // been called, and no reset of the state has occurred).
-
-  // Returns a string_view pointing to the backing store for the string,
-  // either the internal buffer or the original transport buffer (e.g. for a
-  // literal value that wasn't Huffman encoded, and that wasn't split across
-  // transport buffers).
-  absl::string_view str() const;
-
-  // Same as str() if state_ is COMPLETE. Otherwise, returns empty string piece.
-  absl::string_view GetStringIfComplete() const;
-
-  // Returns the completely collected string by value, using std::move in an
-  // effort to avoid unnecessary copies. ReleaseString() must not be called
-  // unless the string has been buffered (to avoid forcing a potentially
-  // unnecessary copy). ReleaseString() also resets the instance so that it can
-  // be used to collect another string.
-  std::string ReleaseString();
-
-  State state_for_testing() const { return state_; }
-  Backing backing_for_testing() const { return backing_; }
-  void OutputDebugStringTo(std::ostream& out) const;
-
- private:
-  // Storage for the string being buffered, if buffering is necessary
-  // (e.g. if Huffman encoded, buffer_ is storage for the decoded string).
-  std::string buffer_;
-
-  // The string_view to be returned by HpackDecoderStringBuffer::str(). If
-  // a string has been collected, but not buffered, value_ points to that
-  // string.
-  absl::string_view value_;
-
-  // The decoder to use if the string is Huffman encoded.
-  HpackHuffmanDecoder decoder_;
-
-  // Count of bytes not yet passed to OnData.
-  size_t remaining_len_;
-
-  // Is the HPACK string Huffman encoded?
-  bool is_huffman_encoded_;
-
-  // State of the string decoding process.
-  State state_;
-
-  // Where is the string stored?
-  Backing backing_;
-};
-
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& out,
-    const HpackDecoderStringBuffer& v);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
diff --git a/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc b/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc
deleted file mode 100644
index 82244ef..0000000
--- a/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_string_buffer.h"
-
-// Tests of HpackDecoderStringBuffer.
-
-#include <initializer_list>
-
-#include "absl/strings/escaping.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::HasSubstr;
-
-namespace http2 {
-namespace test {
-namespace {
-
-class HpackDecoderStringBufferTest : public QuicheTest {
- protected:
-  typedef HpackDecoderStringBuffer::State State;
-  typedef HpackDecoderStringBuffer::Backing Backing;
-
-  State state() const { return buf_.state_for_testing(); }
-  Backing backing() const { return buf_.backing_for_testing(); }
-
-  // We want to know that HTTP2_LOG(x) << buf_ will work in production should
-  // that be needed, so we test that it outputs the expected values.
-  AssertionResult VerifyLogHasSubstrs(std::initializer_list<std::string> strs) {
-    HTTP2_VLOG(1) << buf_;
-    std::ostringstream ss;
-    buf_.OutputDebugStringTo(ss);
-    std::string dbg_str(ss.str());
-    for (const auto& expected : strs) {
-      VERIFY_THAT(dbg_str, HasSubstr(expected));
-    }
-    return AssertionSuccess();
-  }
-
-  HpackDecoderStringBuffer buf_;
-};
-
-TEST_F(HpackDecoderStringBufferTest, SetStatic) {
-  absl::string_view data("static string");
-
-  EXPECT_EQ(state(), State::RESET);
-  EXPECT_TRUE(VerifyLogHasSubstrs({"state=RESET"}));
-
-  buf_.Set(data, /*is_static*/ true);
-  HTTP2_LOG(INFO) << buf_;
-  EXPECT_EQ(state(), State::COMPLETE);
-  EXPECT_EQ(backing(), Backing::STATIC);
-  EXPECT_EQ(data, buf_.str());
-  EXPECT_EQ(data.data(), buf_.str().data());
-  EXPECT_TRUE(VerifyLogHasSubstrs(
-      {"state=COMPLETE", "backing=STATIC", "value: static string"}));
-
-  // The string is static, so BufferStringIfUnbuffered won't change anything.
-  buf_.BufferStringIfUnbuffered();
-  EXPECT_EQ(state(), State::COMPLETE);
-  EXPECT_EQ(backing(), Backing::STATIC);
-  EXPECT_EQ(data, buf_.str());
-  EXPECT_EQ(data.data(), buf_.str().data());
-  EXPECT_TRUE(VerifyLogHasSubstrs(
-      {"state=COMPLETE", "backing=STATIC", "value: static string"}));
-}
-
-TEST_F(HpackDecoderStringBufferTest, PlainWhole) {
-  absl::string_view data("some text.");
-
-  HTTP2_LOG(INFO) << buf_;
-  EXPECT_EQ(state(), State::RESET);
-
-  buf_.OnStart(/*huffman_encoded*/ false, data.size());
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::RESET);
-  HTTP2_LOG(INFO) << buf_;
-
-  EXPECT_TRUE(buf_.OnData(data.data(), data.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::UNBUFFERED);
-
-  EXPECT_TRUE(buf_.OnEnd());
-  EXPECT_EQ(state(), State::COMPLETE);
-  EXPECT_EQ(backing(), Backing::UNBUFFERED);
-  EXPECT_EQ(0u, buf_.BufferedLength());
-  EXPECT_TRUE(VerifyLogHasSubstrs(
-      {"state=COMPLETE", "backing=UNBUFFERED", "value: some text."}));
-
-  // We expect that the string buffer points to the passed in
-  // string_view's backing store.
-  EXPECT_EQ(data.data(), buf_.str().data());
-
-  // Now force it to buffer the string, after which it will still have the same
-  // string value, but the backing store will be different.
-  buf_.BufferStringIfUnbuffered();
-  HTTP2_LOG(INFO) << buf_;
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), data.size());
-  EXPECT_EQ(data, buf_.str());
-  EXPECT_NE(data.data(), buf_.str().data());
-  EXPECT_TRUE(VerifyLogHasSubstrs(
-      {"state=COMPLETE", "backing=BUFFERED", "buffer: some text."}));
-}
-
-TEST_F(HpackDecoderStringBufferTest, PlainSplit) {
-  absl::string_view data("some text.");
-  absl::string_view part1 = data.substr(0, 1);
-  absl::string_view part2 = data.substr(1);
-
-  EXPECT_EQ(state(), State::RESET);
-  buf_.OnStart(/*huffman_encoded*/ false, data.size());
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::RESET);
-
-  // OnData with only a part of the data, not the whole, so buf_ will buffer
-  // the data.
-  EXPECT_TRUE(buf_.OnData(part1.data(), part1.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), part1.size());
-  HTTP2_LOG(INFO) << buf_;
-
-  EXPECT_TRUE(buf_.OnData(part2.data(), part2.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), data.size());
-
-  EXPECT_TRUE(buf_.OnEnd());
-  EXPECT_EQ(state(), State::COMPLETE);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), data.size());
-  HTTP2_LOG(INFO) << buf_;
-
-  absl::string_view buffered = buf_.str();
-  EXPECT_EQ(data, buffered);
-  EXPECT_NE(data.data(), buffered.data());
-
-  // The string is already buffered, so BufferStringIfUnbuffered should not make
-  // any change.
-  buf_.BufferStringIfUnbuffered();
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), data.size());
-  EXPECT_EQ(buffered, buf_.str());
-  EXPECT_EQ(buffered.data(), buf_.str().data());
-}
-
-TEST_F(HpackDecoderStringBufferTest, HuffmanWhole) {
-  std::string encoded = absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff");
-  absl::string_view decoded("www.example.com");
-
-  EXPECT_EQ(state(), State::RESET);
-  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
-  EXPECT_EQ(state(), State::COLLECTING);
-
-  EXPECT_TRUE(buf_.OnData(encoded.data(), encoded.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-
-  EXPECT_TRUE(buf_.OnEnd());
-  EXPECT_EQ(state(), State::COMPLETE);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), decoded.size());
-  EXPECT_EQ(decoded, buf_.str());
-  EXPECT_TRUE(VerifyLogHasSubstrs(
-      {"{state=COMPLETE", "backing=BUFFERED", "buffer: www.example.com}"}));
-
-  std::string s = buf_.ReleaseString();
-  EXPECT_EQ(s, decoded);
-  EXPECT_EQ(state(), State::RESET);
-}
-
-TEST_F(HpackDecoderStringBufferTest, HuffmanSplit) {
-  std::string encoded = absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff");
-  std::string part1 = encoded.substr(0, 5);
-  std::string part2 = encoded.substr(5);
-  absl::string_view decoded("www.example.com");
-
-  EXPECT_EQ(state(), State::RESET);
-  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(0u, buf_.BufferedLength());
-  HTTP2_LOG(INFO) << buf_;
-
-  EXPECT_TRUE(buf_.OnData(part1.data(), part1.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_GT(buf_.BufferedLength(), 0u);
-  EXPECT_LT(buf_.BufferedLength(), decoded.size());
-  HTTP2_LOG(INFO) << buf_;
-
-  EXPECT_TRUE(buf_.OnData(part2.data(), part2.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), decoded.size());
-  HTTP2_LOG(INFO) << buf_;
-
-  EXPECT_TRUE(buf_.OnEnd());
-  EXPECT_EQ(state(), State::COMPLETE);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-  EXPECT_EQ(buf_.BufferedLength(), decoded.size());
-  EXPECT_EQ(decoded, buf_.str());
-  HTTP2_LOG(INFO) << buf_;
-
-  buf_.Reset();
-  EXPECT_EQ(state(), State::RESET);
-  HTTP2_LOG(INFO) << buf_;
-}
-
-TEST_F(HpackDecoderStringBufferTest, InvalidHuffmanOnData) {
-  // Explicitly encode the End-of-String symbol, a no-no.
-  std::string encoded = absl::HexStringToBytes("ffffffff");
-
-  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
-  EXPECT_EQ(state(), State::COLLECTING);
-
-  EXPECT_FALSE(buf_.OnData(encoded.data(), encoded.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-
-  HTTP2_LOG(INFO) << buf_;
-}
-
-TEST_F(HpackDecoderStringBufferTest, InvalidHuffmanOnEnd) {
-  // Last byte of string doesn't end with prefix of End-of-String symbol.
-  std::string encoded = absl::HexStringToBytes("00");
-
-  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
-  EXPECT_EQ(state(), State::COLLECTING);
-
-  EXPECT_TRUE(buf_.OnData(encoded.data(), encoded.size()));
-  EXPECT_EQ(state(), State::COLLECTING);
-  EXPECT_EQ(backing(), Backing::BUFFERED);
-
-  EXPECT_FALSE(buf_.OnEnd());
-  HTTP2_LOG(INFO) << buf_;
-}
-
-// TODO(jamessynge): Add tests for ReleaseString().
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_tables.cc b/http2/hpack/decoder/hpack_decoder_tables.cc
deleted file mode 100644
index 9f50ec7..0000000
--- a/http2/hpack/decoder/hpack_decoder_tables.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-
-#include "absl/strings/str_cat.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-namespace {
-
-std::vector<HpackStringPair>* MakeStaticTable() {
-  auto* ptr = new std::vector<HpackStringPair>();
-  ptr->reserve(kFirstDynamicTableIndex);
-  ptr->emplace_back("", "");
-
-#define STATIC_TABLE_ENTRY(name, value, index)               \
-  QUICHE_DCHECK_EQ(ptr->size(), static_cast<size_t>(index)); \
-  ptr->emplace_back(name, value)
-
-#include "http2/hpack/hpack_static_table_entries.inc"
-
-#undef STATIC_TABLE_ENTRY
-
-  return ptr;
-}
-
-const std::vector<HpackStringPair>* GetStaticTable() {
-  static const std::vector<HpackStringPair>* const g_static_table =
-      MakeStaticTable();
-  return g_static_table;
-}
-
-}  // namespace
-
-HpackStringPair::HpackStringPair(std::string name, std::string value)
-    : name(std::move(name)), value(std::move(value)) {
-  HTTP2_DVLOG(3) << DebugString() << " ctor";
-}
-
-HpackStringPair::~HpackStringPair() {
-  HTTP2_DVLOG(3) << DebugString() << " dtor";
-}
-
-std::string HpackStringPair::DebugString() const {
-  return absl::StrCat("HpackStringPair(name=", name, ", value=", value, ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const HpackStringPair& p) {
-  os << p.DebugString();
-  return os;
-}
-
-HpackDecoderStaticTable::HpackDecoderStaticTable(
-    const std::vector<HpackStringPair>* table)
-    : table_(table) {}
-
-HpackDecoderStaticTable::HpackDecoderStaticTable() : table_(GetStaticTable()) {}
-
-const HpackStringPair* HpackDecoderStaticTable::Lookup(size_t index) const {
-  if (0 < index && index < kFirstDynamicTableIndex) {
-    return &((*table_)[index]);
-  }
-  return nullptr;
-}
-
-HpackDecoderDynamicTable::HpackDecoderDynamicTable()
-    : insert_count_(kFirstDynamicTableIndex - 1) {}
-HpackDecoderDynamicTable::~HpackDecoderDynamicTable() = default;
-
-void HpackDecoderDynamicTable::DynamicTableSizeUpdate(size_t size_limit) {
-  HTTP2_DVLOG(3) << "HpackDecoderDynamicTable::DynamicTableSizeUpdate "
-                 << size_limit;
-  EnsureSizeNoMoreThan(size_limit);
-  QUICHE_DCHECK_LE(current_size_, size_limit);
-  size_limit_ = size_limit;
-}
-
-// TODO(jamessynge): Check somewhere before here that names received from the
-// peer are valid (e.g. are lower-case, no whitespace, etc.).
-void HpackDecoderDynamicTable::Insert(std::string name, std::string value) {
-  HpackStringPair entry(std::move(name), std::move(value));
-  size_t entry_size = entry.size();
-  HTTP2_DVLOG(2) << "InsertEntry of size=" << entry_size
-                 << "\n     name: " << entry.name
-                 << "\n    value: " << entry.value;
-  if (entry_size > size_limit_) {
-    HTTP2_DVLOG(2) << "InsertEntry: entry larger than table, removing "
-                   << table_.size() << " entries, of total size "
-                   << current_size_ << " bytes.";
-    table_.clear();
-    current_size_ = 0;
-    return;
-  }
-  ++insert_count_;
-  size_t insert_limit = size_limit_ - entry_size;
-  EnsureSizeNoMoreThan(insert_limit);
-  table_.push_front(entry);
-  current_size_ += entry_size;
-  HTTP2_DVLOG(2) << "InsertEntry: current_size_=" << current_size_;
-  QUICHE_DCHECK_GE(current_size_, entry_size);
-  QUICHE_DCHECK_LE(current_size_, size_limit_);
-}
-
-const HpackStringPair* HpackDecoderDynamicTable::Lookup(size_t index) const {
-  if (index < table_.size()) {
-    return &table_[index];
-  }
-  return nullptr;
-}
-
-void HpackDecoderDynamicTable::EnsureSizeNoMoreThan(size_t limit) {
-  HTTP2_DVLOG(2) << "EnsureSizeNoMoreThan limit=" << limit
-                 << ", current_size_=" << current_size_;
-  // Not the most efficient choice, but any easy way to start.
-  while (current_size_ > limit) {
-    RemoveLastEntry();
-  }
-  QUICHE_DCHECK_LE(current_size_, limit);
-}
-
-void HpackDecoderDynamicTable::RemoveLastEntry() {
-  QUICHE_DCHECK(!table_.empty());
-  if (!table_.empty()) {
-    HTTP2_DVLOG(2) << "RemoveLastEntry current_size_=" << current_size_
-                   << ", last entry size=" << table_.back().size();
-    QUICHE_DCHECK_GE(current_size_, table_.back().size());
-    current_size_ -= table_.back().size();
-    table_.pop_back();
-    // Empty IFF current_size_ == 0.
-    QUICHE_DCHECK_EQ(table_.empty(), current_size_ == 0);
-  }
-}
-
-HpackDecoderTables::HpackDecoderTables() = default;
-HpackDecoderTables::~HpackDecoderTables() = default;
-
-const HpackStringPair* HpackDecoderTables::Lookup(size_t index) const {
-  if (index < kFirstDynamicTableIndex) {
-    return static_table_.Lookup(index);
-  } else {
-    return dynamic_table_.Lookup(index - kFirstDynamicTableIndex);
-  }
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_tables.h b/http2/hpack/decoder/hpack_decoder_tables.h
deleted file mode 100644
index ef5b3d2..0000000
--- a/http2/hpack/decoder/hpack_decoder_tables.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
-
-// Static and dynamic tables for the HPACK decoder. See:
-// http://httpwg.org/specs/rfc7541.html#indexing.tables
-
-// Note that the Lookup methods return nullptr if the requested index was not
-// found. This should be treated as a COMPRESSION error according to the HTTP/2
-// spec, which is a connection level protocol error (i.e. the connection must
-// be terminated). See these sections in the two RFCs:
-// http://httpwg.org/specs/rfc7541.html#indexed.header.representation
-// http://httpwg.org/specs/rfc7541.html#index.address.space
-// http://httpwg.org/specs/rfc7540.html#HeaderBlock
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <iosfwd>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "http2/http2_constants.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_circular_deque.h"
-
-namespace http2 {
-namespace test {
-class HpackDecoderTablesPeer;
-}  // namespace test
-
-struct QUICHE_EXPORT_PRIVATE HpackStringPair {
-  HpackStringPair(std::string name, std::string value);
-  ~HpackStringPair();
-
-  // Returns the size of a header entry with this name and value, per the RFC:
-  // http://httpwg.org/specs/rfc7541.html#calculating.table.size
-  size_t size() const { return 32 + name.size() + value.size(); }
-
-  std::string DebugString() const;
-
-  const std::string name;
-  const std::string value;
-};
-
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                               const HpackStringPair& p);
-
-// See http://httpwg.org/specs/rfc7541.html#static.table.definition for the
-// contents, and http://httpwg.org/specs/rfc7541.html#index.address.space for
-// info about accessing the static table.
-class QUICHE_EXPORT_PRIVATE HpackDecoderStaticTable {
- public:
-  explicit HpackDecoderStaticTable(const std::vector<HpackStringPair>* table);
-  // Uses a global table shared by all threads.
-  HpackDecoderStaticTable();
-
-  // If index is valid, returns a pointer to the entry, otherwise returns
-  // nullptr.
-  const HpackStringPair* Lookup(size_t index) const;
-
- private:
-  friend class test::HpackDecoderTablesPeer;
-  const std::vector<HpackStringPair>* const table_;
-};
-
-// HpackDecoderDynamicTable implements HPACK compression feature "indexed
-// headers"; previously sent headers may be referenced later by their index
-// in the dynamic table. See these sections of the RFC:
-//   http://httpwg.org/specs/rfc7541.html#dynamic.table
-//   http://httpwg.org/specs/rfc7541.html#dynamic.table.management
-class QUICHE_EXPORT_PRIVATE HpackDecoderDynamicTable {
- public:
-  HpackDecoderDynamicTable();
-  ~HpackDecoderDynamicTable();
-
-  HpackDecoderDynamicTable(const HpackDecoderDynamicTable&) = delete;
-  HpackDecoderDynamicTable& operator=(const HpackDecoderDynamicTable&) = delete;
-
-  // Sets a new size limit, received from the peer; performs evictions if
-  // necessary to ensure that the current size does not exceed the new limit.
-  // The caller needs to have validated that size_limit does not
-  // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
-  void DynamicTableSizeUpdate(size_t size_limit);
-
-  // Insert entry if possible.
-  // If entry is too large to insert, then dynamic table will be empty.
-  void Insert(std::string name, std::string value);
-
-  // If index is valid, returns a pointer to the entry, otherwise returns
-  // nullptr.
-  const HpackStringPair* Lookup(size_t index) const;
-
-  size_t size_limit() const { return size_limit_; }
-  size_t current_size() const { return current_size_; }
-
- private:
-  friend class test::HpackDecoderTablesPeer;
-
-  // Drop older entries to ensure the size is not greater than limit.
-  void EnsureSizeNoMoreThan(size_t limit);
-
-  // Removes the oldest dynamic table entry.
-  void RemoveLastEntry();
-
-  quiche::QuicheCircularDeque<HpackStringPair> table_;
-
-  // The last received DynamicTableSizeUpdate value, initialized to
-  // SETTINGS_HEADER_TABLE_SIZE.
-  size_t size_limit_ = Http2SettingsInfo::DefaultHeaderTableSize();
-
-  size_t current_size_ = 0;
-
-  // insert_count_ and debug_listener_ are used by a QUIC experiment; remove
-  // when the experiment is done.
-  size_t insert_count_;
-};
-
-class QUICHE_EXPORT_PRIVATE HpackDecoderTables {
- public:
-  HpackDecoderTables();
-  ~HpackDecoderTables();
-
-  HpackDecoderTables(const HpackDecoderTables&) = delete;
-  HpackDecoderTables& operator=(const HpackDecoderTables&) = delete;
-
-  // Sets a new size limit, received from the peer; performs evictions if
-  // necessary to ensure that the current size does not exceed the new limit.
-  // The caller needs to have validated that size_limit does not
-  // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
-  void DynamicTableSizeUpdate(size_t size_limit) {
-    dynamic_table_.DynamicTableSizeUpdate(size_limit);
-  }
-
-  // Insert entry if possible.
-  // If entry is too large to insert, then dynamic table will be empty.
-  void Insert(std::string name, std::string value) {
-    dynamic_table_.Insert(std::move(name), std::move(value));
-  }
-
-  // If index is valid, returns a pointer to the entry, otherwise returns
-  // nullptr.
-  const HpackStringPair* Lookup(size_t index) const;
-
-  // The size limit that the peer (the HPACK encoder) has told the decoder it is
-  // currently operating with. Defaults to SETTINGS_HEADER_TABLE_SIZE, 4096.
-  size_t header_table_size_limit() const { return dynamic_table_.size_limit(); }
-
-  // Sum of the sizes of the dynamic table entries.
-  size_t current_header_table_size() const {
-    return dynamic_table_.current_size();
-  }
-
- private:
-  friend class test::HpackDecoderTablesPeer;
-  HpackDecoderStaticTable static_table_;
-  HpackDecoderDynamicTable dynamic_table_;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
diff --git a/http2/hpack/decoder/hpack_decoder_tables_test.cc b/http2/hpack/decoder/hpack_decoder_tables_test.cc
deleted file mode 100644
index b7ed527..0000000
--- a/http2/hpack/decoder/hpack_decoder_tables_test.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-
-#include <algorithm>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_util.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-class HpackDecoderTablesPeer {
- public:
-  static size_t num_dynamic_entries(const HpackDecoderTables& tables) {
-    return tables.dynamic_table_.table_.size();
-  }
-};
-
-namespace {
-struct StaticEntry {
-  const char* name;
-  const char* value;
-  size_t index;
-};
-
-std::vector<StaticEntry> MakeSpecStaticEntries() {
-  std::vector<StaticEntry> static_entries;
-
-#define STATIC_TABLE_ENTRY(name, value, index)                             \
-  QUICHE_DCHECK_EQ(static_entries.size() + 1, static_cast<size_t>(index)); \
-  static_entries.push_back({name, value, index});
-
-#include "http2/hpack/hpack_static_table_entries.inc"
-
-#undef STATIC_TABLE_ENTRY
-
-  return static_entries;
-}
-
-template <class C>
-void ShuffleCollection(C* collection, Http2Random* r) {
-  std::shuffle(collection->begin(), collection->end(), *r);
-}
-
-class HpackDecoderStaticTableTest : public QuicheTest {
- protected:
-  HpackDecoderStaticTableTest() = default;
-
-  std::vector<StaticEntry> shuffled_static_entries() {
-    std::vector<StaticEntry> entries = MakeSpecStaticEntries();
-    ShuffleCollection(&entries, &random_);
-    return entries;
-  }
-
-  // This test is in a function so that it can be applied to both the static
-  // table and the combined static+dynamic tables.
-  AssertionResult VerifyStaticTableContents() {
-    for (const auto& expected : shuffled_static_entries()) {
-      const HpackStringPair* found = Lookup(expected.index);
-      VERIFY_NE(found, nullptr);
-      VERIFY_EQ(expected.name, found->name) << expected.index;
-      VERIFY_EQ(expected.value, found->value) << expected.index;
-    }
-
-    // There should be no entry with index 0.
-    VERIFY_EQ(nullptr, Lookup(0));
-    return AssertionSuccess();
-  }
-
-  virtual const HpackStringPair* Lookup(size_t index) {
-    return static_table_.Lookup(index);
-  }
-
-  Http2Random* RandomPtr() { return &random_; }
-
-  Http2Random random_;
-
- private:
-  HpackDecoderStaticTable static_table_;
-};
-
-TEST_F(HpackDecoderStaticTableTest, StaticTableContents) {
-  EXPECT_TRUE(VerifyStaticTableContents());
-}
-
-size_t Size(const std::string& name, const std::string& value) {
-  return name.size() + value.size() + 32;
-}
-
-// To support tests with more than a few of hand crafted changes to the dynamic
-// table, we have another, exceedingly simple, implementation of the HPACK
-// dynamic table containing FakeHpackEntry instances. We can thus compare the
-// contents of the actual table with those in fake_dynamic_table_.
-
-typedef std::tuple<std::string, std::string, size_t> FakeHpackEntry;
-const std::string& Name(const FakeHpackEntry& entry) {
-  return std::get<0>(entry);
-}
-const std::string& Value(const FakeHpackEntry& entry) {
-  return std::get<1>(entry);
-}
-size_t Size(const FakeHpackEntry& entry) {
-  return std::get<2>(entry);
-}
-
-class HpackDecoderTablesTest : public HpackDecoderStaticTableTest {
- protected:
-  const HpackStringPair* Lookup(size_t index) override {
-    return tables_.Lookup(index);
-  }
-
-  size_t dynamic_size_limit() const {
-    return tables_.header_table_size_limit();
-  }
-  size_t current_dynamic_size() const {
-    return tables_.current_header_table_size();
-  }
-  size_t num_dynamic_entries() const {
-    return HpackDecoderTablesPeer::num_dynamic_entries(tables_);
-  }
-
-  // Insert the name and value into fake_dynamic_table_.
-  void FakeInsert(const std::string& name, const std::string& value) {
-    FakeHpackEntry entry(name, value, Size(name, value));
-    fake_dynamic_table_.insert(fake_dynamic_table_.begin(), entry);
-  }
-
-  // Add up the size of all entries in fake_dynamic_table_.
-  size_t FakeSize() {
-    size_t sz = 0;
-    for (const auto& entry : fake_dynamic_table_) {
-      sz += Size(entry);
-    }
-    return sz;
-  }
-
-  // If the total size of the fake_dynamic_table_ is greater than limit,
-  // keep the first N entries such that those N entries have a size not
-  // greater than limit, and such that keeping entry N+1 would have a size
-  // greater than limit. Returns the count of removed bytes.
-  size_t FakeTrim(size_t limit) {
-    size_t original_size = FakeSize();
-    size_t total_size = 0;
-    for (size_t ndx = 0; ndx < fake_dynamic_table_.size(); ++ndx) {
-      total_size += Size(fake_dynamic_table_[ndx]);
-      if (total_size > limit) {
-        // Need to get rid of ndx and all following entries.
-        fake_dynamic_table_.erase(fake_dynamic_table_.begin() + ndx,
-                                  fake_dynamic_table_.end());
-        return original_size - FakeSize();
-      }
-    }
-    return 0;
-  }
-
-  // Verify that the contents of the actual dynamic table match those in
-  // fake_dynamic_table_.
-  AssertionResult VerifyDynamicTableContents() {
-    VERIFY_EQ(current_dynamic_size(), FakeSize());
-    VERIFY_EQ(num_dynamic_entries(), fake_dynamic_table_.size());
-
-    for (size_t ndx = 0; ndx < fake_dynamic_table_.size(); ++ndx) {
-      const HpackStringPair* found = Lookup(ndx + kFirstDynamicTableIndex);
-      VERIFY_NE(found, nullptr);
-
-      const auto& expected = fake_dynamic_table_[ndx];
-      VERIFY_EQ(Name(expected), found->name);
-      VERIFY_EQ(Value(expected), found->value);
-    }
-
-    // Make sure there are no more entries.
-    VERIFY_EQ(nullptr,
-              Lookup(fake_dynamic_table_.size() + kFirstDynamicTableIndex));
-    return AssertionSuccess();
-  }
-
-  // Apply an update to the limit on the maximum size of the dynamic table.
-  AssertionResult DynamicTableSizeUpdate(size_t size_limit) {
-    VERIFY_EQ(current_dynamic_size(), FakeSize());
-    if (size_limit < current_dynamic_size()) {
-      // Will need to trim the dynamic table's oldest entries.
-      tables_.DynamicTableSizeUpdate(size_limit);
-      FakeTrim(size_limit);
-      return VerifyDynamicTableContents();
-    }
-    // Shouldn't change the size.
-    tables_.DynamicTableSizeUpdate(size_limit);
-    return VerifyDynamicTableContents();
-  }
-
-  // Insert an entry into the dynamic table, confirming that trimming of entries
-  // occurs if the total size is greater than the limit, and that older entries
-  // move up by 1 index.
-  AssertionResult Insert(const std::string& name, const std::string& value) {
-    size_t old_count = num_dynamic_entries();
-    tables_.Insert(name, value);
-    FakeInsert(name, value);
-    VERIFY_EQ(old_count + 1, fake_dynamic_table_.size());
-    FakeTrim(dynamic_size_limit());
-    VERIFY_EQ(current_dynamic_size(), FakeSize());
-    VERIFY_EQ(num_dynamic_entries(), fake_dynamic_table_.size());
-    return VerifyDynamicTableContents();
-  }
-
- private:
-  HpackDecoderTables tables_;
-
-  std::vector<FakeHpackEntry> fake_dynamic_table_;
-};
-
-TEST_F(HpackDecoderTablesTest, StaticTableContents) {
-  EXPECT_TRUE(VerifyStaticTableContents());
-}
-
-// Generate a bunch of random header entries, insert them, and confirm they
-// present, as required by the RFC, using VerifyDynamicTableContents above on
-// each Insert. Also apply various resizings of the dynamic table.
-TEST_F(HpackDecoderTablesTest, RandomDynamicTable) {
-  EXPECT_EQ(0u, current_dynamic_size());
-  EXPECT_TRUE(VerifyStaticTableContents());
-  EXPECT_TRUE(VerifyDynamicTableContents());
-
-  std::vector<size_t> table_sizes;
-  table_sizes.push_back(dynamic_size_limit());
-  table_sizes.push_back(0);
-  table_sizes.push_back(dynamic_size_limit() / 2);
-  table_sizes.push_back(dynamic_size_limit());
-  table_sizes.push_back(dynamic_size_limit() / 2);
-  table_sizes.push_back(0);
-  table_sizes.push_back(dynamic_size_limit());
-
-  for (size_t limit : table_sizes) {
-    ASSERT_TRUE(DynamicTableSizeUpdate(limit));
-    for (int insert_count = 0; insert_count < 100; ++insert_count) {
-      std::string name =
-          GenerateHttp2HeaderName(random_.UniformInRange(2, 40), RandomPtr());
-      std::string value =
-          GenerateWebSafeString(random_.UniformInRange(2, 600), RandomPtr());
-      ASSERT_TRUE(Insert(name, value));
-    }
-    EXPECT_TRUE(VerifyStaticTableContents());
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoder_test.cc b/http2/hpack/decoder/hpack_decoder_test.cc
deleted file mode 100644
index c1439f9..0000000
--- a/http2/hpack/decoder/hpack_decoder_test.cc
+++ /dev/null
@@ -1,1192 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoder.h"
-
-// Tests of HpackDecoder.
-
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/hpack/decoder/hpack_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_decoder_state.h"
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/hpack/tools/hpack_example.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_util.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::ElementsAreArray;
-using ::testing::Eq;
-
-namespace http2 {
-namespace test {
-class HpackDecoderStatePeer {
- public:
-  static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) {
-    return &state->decoder_tables_;
-  }
-  static void set_listener(HpackDecoderState* state,
-                           HpackDecoderListener* listener) {
-    state->listener_ = listener;
-  }
-};
-class HpackDecoderPeer {
- public:
-  static HpackDecoderState* GetDecoderState(HpackDecoder* decoder) {
-    return &decoder->decoder_state_;
-  }
-  static HpackDecoderTables* GetDecoderTables(HpackDecoder* decoder) {
-    return HpackDecoderStatePeer::GetDecoderTables(GetDecoderState(decoder));
-  }
-};
-
-namespace {
-
-typedef std::pair<std::string, std::string> HpackHeaderEntry;
-typedef std::vector<HpackHeaderEntry> HpackHeaderEntries;
-
-// TODO(jamessynge): Create a ...test_utils.h file with the mock listener
-// and with VerifyDynamicTableContents.
-class MockHpackDecoderListener : public HpackDecoderListener {
- public:
-  MOCK_METHOD(void, OnHeaderListStart, (), (override));
-  MOCK_METHOD(void,
-              OnHeader,
-              (const std::string& name, const std::string& value),
-              (override));
-  MOCK_METHOD(void, OnHeaderListEnd, (), (override));
-  MOCK_METHOD(void,
-              OnHeaderErrorDetected,
-              (absl::string_view error_message),
-              (override));
-};
-
-class HpackDecoderTest : public QuicheTestWithParam<bool>,
-                         public HpackDecoderListener {
- protected:
-  // Note that we initialize the random number generator with the same seed
-  // for each individual test, therefore the order in which the tests are
-  // executed does not effect the sequence produced by the RNG within any
-  // one test.
-  HpackDecoderTest() : decoder_(this, 4096) {
-    fragment_the_hpack_block_ = GetParam();
-  }
-  ~HpackDecoderTest() override = default;
-
-  void OnHeaderListStart() override {
-    ASSERT_FALSE(saw_start_);
-    ASSERT_FALSE(saw_end_);
-    saw_start_ = true;
-    header_entries_.clear();
-  }
-
-  // Called for each header name-value pair that is decoded, in the order they
-  // appear in the HPACK block. Multiple values for a given key will be emitted
-  // as multiple calls to OnHeader.
-  void OnHeader(const std::string& name, const std::string& value) override {
-    ASSERT_TRUE(saw_start_);
-    ASSERT_FALSE(saw_end_);
-    header_entries_.emplace_back(name, value);
-  }
-
-  // OnHeaderBlockEnd is called after successfully decoding an HPACK block. Will
-  // only be called once per block, even if it extends into CONTINUATION frames.
-  // A callback method which notifies when the parser finishes handling a
-  // header block (i.e. the containing frame has the END_STREAM flag set).
-  // Also indicates the total number of bytes in this block.
-  void OnHeaderListEnd() override {
-    ASSERT_TRUE(saw_start_);
-    ASSERT_FALSE(saw_end_);
-    ASSERT_TRUE(error_messages_.empty());
-    saw_end_ = true;
-  }
-
-  // OnHeaderErrorDetected is called if an error is detected while decoding.
-  // error_message may be used in a GOAWAY frame as the Opaque Data.
-  void OnHeaderErrorDetected(absl::string_view error_message) override {
-    ASSERT_TRUE(saw_start_);
-    error_messages_.push_back(std::string(error_message));
-    // No further callbacks should be made at this point, so replace 'this' as
-    // the listener with mock_listener_, which is a strict mock, so will
-    // generate an error for any calls.
-    HpackDecoderStatePeer::set_listener(
-        HpackDecoderPeer::GetDecoderState(&decoder_), &mock_listener_);
-  }
-
-  AssertionResult DecodeBlock(absl::string_view block) {
-    HTTP2_VLOG(1) << "HpackDecoderTest::DecodeBlock";
-
-    VERIFY_FALSE(decoder_.DetectError());
-    VERIFY_TRUE(error_messages_.empty());
-    VERIFY_FALSE(saw_start_);
-    VERIFY_FALSE(saw_end_);
-    header_entries_.clear();
-
-    VERIFY_FALSE(decoder_.DetectError());
-    VERIFY_TRUE(decoder_.StartDecodingBlock());
-    VERIFY_FALSE(decoder_.DetectError());
-
-    if (fragment_the_hpack_block_) {
-      // See note in ctor regarding RNG.
-      while (!block.empty()) {
-        size_t fragment_size = random_.RandomSizeSkewedLow(block.size());
-        DecodeBuffer db(block.substr(0, fragment_size));
-        VERIFY_TRUE(decoder_.DecodeFragment(&db));
-        VERIFY_EQ(0u, db.Remaining());
-        block.remove_prefix(fragment_size);
-      }
-    } else {
-      DecodeBuffer db(block);
-      VERIFY_TRUE(decoder_.DecodeFragment(&db));
-      VERIFY_EQ(0u, db.Remaining());
-    }
-    VERIFY_FALSE(decoder_.DetectError());
-
-    VERIFY_TRUE(decoder_.EndDecodingBlock());
-    if (saw_end_) {
-      VERIFY_FALSE(decoder_.DetectError());
-      VERIFY_TRUE(error_messages_.empty());
-    } else {
-      VERIFY_TRUE(decoder_.DetectError());
-      VERIFY_FALSE(error_messages_.empty());
-    }
-
-    saw_start_ = saw_end_ = false;
-    return AssertionSuccess();
-  }
-
-  const HpackDecoderTables& GetDecoderTables() {
-    return *HpackDecoderPeer::GetDecoderTables(&decoder_);
-  }
-  const HpackStringPair* Lookup(size_t index) {
-    return GetDecoderTables().Lookup(index);
-  }
-  size_t current_header_table_size() {
-    return GetDecoderTables().current_header_table_size();
-  }
-  size_t header_table_size_limit() {
-    return GetDecoderTables().header_table_size_limit();
-  }
-  void set_header_table_size_limit(size_t size) {
-    HpackDecoderPeer::GetDecoderTables(&decoder_)->DynamicTableSizeUpdate(size);
-  }
-
-  // dynamic_index is one-based, because that is the way RFC 7541 shows it.
-  AssertionResult VerifyEntry(size_t dynamic_index,
-                              const char* name,
-                              const char* value) {
-    const HpackStringPair* entry =
-        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
-    VERIFY_NE(entry, nullptr);
-    VERIFY_EQ(entry->name, name);
-    VERIFY_EQ(entry->value, value);
-    return AssertionSuccess();
-  }
-  AssertionResult VerifyNoEntry(size_t dynamic_index) {
-    const HpackStringPair* entry =
-        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
-    VERIFY_EQ(entry, nullptr);
-    return AssertionSuccess();
-  }
-  AssertionResult VerifyDynamicTableContents(
-      const std::vector<std::pair<const char*, const char*>>& entries) {
-    size_t index = 1;
-    for (const auto& entry : entries) {
-      VERIFY_SUCCESS(VerifyEntry(index, entry.first, entry.second));
-      ++index;
-    }
-    VERIFY_SUCCESS(VerifyNoEntry(index));
-    return AssertionSuccess();
-  }
-
-  Http2Random random_;
-  HpackDecoder decoder_;
-  testing::StrictMock<MockHpackDecoderListener> mock_listener_;
-  HpackHeaderEntries header_entries_;
-  std::vector<std::string> error_messages_;
-  bool fragment_the_hpack_block_;
-  bool saw_start_ = false;
-  bool saw_end_ = false;
-};
-INSTANTIATE_TEST_SUITE_P(AllWays, HpackDecoderTest, ::testing::Bool());
-
-// Test based on RFC 7541, section C.3: Request Examples without Huffman Coding.
-// This section shows several consecutive header lists, corresponding to HTTP
-// requests, on the same connection.
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3
-TEST_P(HpackDecoderTest, C3_RequestExamples) {
-  // C.3.1 First Request
-  std::string hpack_block = HpackExampleToStringOrDie(R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      86                                      | == Indexed - Add ==
-                                              |   idx = 6
-                                              | -> :scheme: http
-      84                                      | == Indexed - Add ==
-                                              |   idx = 4
-                                              | -> :path: /
-      41                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 1)
-                                              |     :authority
-      0f                                      |   Literal value (len = 15)
-      7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
-                                              | -> :authority:
-                                              |   www.example.com
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":method", "GET"},
-                  HpackHeaderEntry{":scheme", "http"},
-                  HpackHeaderEntry{":path", "/"},
-                  HpackHeaderEntry{":authority", "www.example.com"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  57) :authority: www.example.com
-  //         Table size:  57
-  ASSERT_TRUE(VerifyDynamicTableContents({{":authority", "www.example.com"}}));
-  ASSERT_EQ(57u, current_header_table_size());
-
-  // C.3.2 Second Request
-  hpack_block = HpackExampleToStringOrDie(R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      86                                      | == Indexed - Add ==
-                                              |   idx = 6
-                                              | -> :scheme: http
-      84                                      | == Indexed - Add ==
-                                              |   idx = 4
-                                              | -> :path: /
-      be                                      | == Indexed - Add ==
-                                              |   idx = 62
-                                              | -> :authority:
-                                              |   www.example.com
-      58                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 24)
-                                              |     cache-control
-      08                                      |   Literal value (len = 8)
-      6e6f 2d63 6163 6865                     | no-cache
-                                              | -> cache-control: no-cache
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":method", "GET"},
-                  HpackHeaderEntry{":scheme", "http"},
-                  HpackHeaderEntry{":path", "/"},
-                  HpackHeaderEntry{":authority", "www.example.com"},
-                  HpackHeaderEntry{"cache-control", "no-cache"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  53) cache-control: no-cache
-  //   [  2] (s =  57) :authority: www.example.com
-  //         Table size: 110
-  ASSERT_TRUE(VerifyDynamicTableContents(
-      {{"cache-control", "no-cache"}, {":authority", "www.example.com"}}));
-  ASSERT_EQ(110u, current_header_table_size());
-
-  // C.3.2 Third Request
-  hpack_block = HpackExampleToStringOrDie(R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      87                                      | == Indexed - Add ==
-                                              |   idx = 7
-                                              | -> :scheme: https
-      85                                      | == Indexed - Add ==
-                                              |   idx = 5
-                                              | -> :path: /index.html
-      bf                                      | == Indexed - Add ==
-                                              |   idx = 63
-                                              | -> :authority:
-                                              |   www.example.com
-      40                                      | == Literal indexed ==
-      0a                                      |   Literal name (len = 10)
-      6375 7374 6f6d 2d6b 6579                | custom-key
-      0c                                      |   Literal value (len = 12)
-      6375 7374 6f6d 2d76 616c 7565           | custom-value
-                                              | -> custom-key:
-                                              |   custom-value
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":method", "GET"},
-                  HpackHeaderEntry{":scheme", "https"},
-                  HpackHeaderEntry{":path", "/index.html"},
-                  HpackHeaderEntry{":authority", "www.example.com"},
-                  HpackHeaderEntry{"custom-key", "custom-value"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  54) custom-key: custom-value
-  //   [  2] (s =  53) cache-control: no-cache
-  //   [  3] (s =  57) :authority: www.example.com
-  //         Table size: 164
-  ASSERT_TRUE(VerifyDynamicTableContents({{"custom-key", "custom-value"},
-                                          {"cache-control", "no-cache"},
-                                          {":authority", "www.example.com"}}));
-  ASSERT_EQ(164u, current_header_table_size());
-}
-
-// Test based on RFC 7541, section C.4 Request Examples with Huffman Coding.
-// This section shows the same examples as the previous section but uses
-// Huffman encoding for the literal values.
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4
-TEST_P(HpackDecoderTest, C4_RequestExamplesWithHuffmanEncoding) {
-  // C.4.1 First Request
-  std::string hpack_block = HpackExampleToStringOrDie(R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      86                                      | == Indexed - Add ==
-                                              |   idx = 6
-                                              | -> :scheme: http
-      84                                      | == Indexed - Add ==
-                                              |   idx = 4
-                                              | -> :path: /
-      41                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 1)
-                                              |     :authority
-      8c                                      |   Literal value (len = 12)
-                                              |     Huffman encoded:
-      f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
-                                              |     Decoded:
-                                              | www.example.com
-                                              | -> :authority:
-                                              |   www.example.com
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":method", "GET"},
-                  HpackHeaderEntry{":scheme", "http"},
-                  HpackHeaderEntry{":path", "/"},
-                  HpackHeaderEntry{":authority", "www.example.com"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  57) :authority: www.example.com
-  //         Table size:  57
-  ASSERT_TRUE(VerifyDynamicTableContents({{":authority", "www.example.com"}}));
-  ASSERT_EQ(57u, current_header_table_size());
-
-  // C.4.2 Second Request
-  hpack_block = HpackExampleToStringOrDie(R"(
-      82                                      | == Indexed - Add ==
-                                              |   idx = 2
-                                              | -> :method: GET
-      86                                      | == Indexed - Add ==
-                                              |   idx = 6
-                                              | -> :scheme: http
-      84                                      | == Indexed - Add ==
-                                              |   idx = 4
-                                              | -> :path: /
-      be                                      | == Indexed - Add ==
-                                              |   idx = 62
-                                              | -> :authority:
-                                              |   www.example.com
-      58                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 24)
-                                              |     cache-control
-      86                                      |   Literal value (len = 6)
-                                              |     Huffman encoded:
-      a8eb 1064 9cbf                          | ...d..
-                                              |     Decoded:
-                                              | no-cache
-                                              | -> cache-control: no-cache
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":method", "GET"},
-                  HpackHeaderEntry{":scheme", "http"},
-                  HpackHeaderEntry{":path", "/"},
-                  HpackHeaderEntry{":authority", "www.example.com"},
-                  HpackHeaderEntry{"cache-control", "no-cache"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  53) cache-control: no-cache
-  //   [  2] (s =  57) :authority: www.example.com
-  //         Table size: 110
-  ASSERT_TRUE(VerifyDynamicTableContents(
-      {{"cache-control", "no-cache"}, {":authority", "www.example.com"}}));
-  ASSERT_EQ(110u, current_header_table_size());
-
-  // C.4.2 Third Request
-  hpack_block = HpackExampleToStringOrDie(R"(
-    82                                      | == Indexed - Add ==
-                                            |   idx = 2
-                                            | -> :method: GET
-    87                                      | == Indexed - Add ==
-                                            |   idx = 7
-                                            | -> :scheme: https
-    85                                      | == Indexed - Add ==
-                                            |   idx = 5
-                                            | -> :path: /index.html
-    bf                                      | == Indexed - Add ==
-                                            |   idx = 63
-                                            | -> :authority:
-                                            |   www.example.com
-    40                                      | == Literal indexed ==
-    88                                      |   Literal name (len = 8)
-                                            |     Huffman encoded:
-    25a8 49e9 5ba9 7d7f                     | %.I.[.}.
-                                            |     Decoded:
-                                            | custom-key
-    89                                      |   Literal value (len = 9)
-                                            |     Huffman encoded:
-    25a8 49e9 5bb8 e8b4 bf                  | %.I.[....
-                                            |     Decoded:
-                                            | custom-value
-                                            | -> custom-key:
-                                            |   custom-value
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":method", "GET"},
-                  HpackHeaderEntry{":scheme", "https"},
-                  HpackHeaderEntry{":path", "/index.html"},
-                  HpackHeaderEntry{":authority", "www.example.com"},
-                  HpackHeaderEntry{"custom-key", "custom-value"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  54) custom-key: custom-value
-  //   [  2] (s =  53) cache-control: no-cache
-  //   [  3] (s =  57) :authority: www.example.com
-  //         Table size: 164
-  ASSERT_TRUE(VerifyDynamicTableContents({{"custom-key", "custom-value"},
-                                          {"cache-control", "no-cache"},
-                                          {":authority", "www.example.com"}}));
-  ASSERT_EQ(164u, current_header_table_size());
-}
-
-// Test based on RFC 7541, section C.5: Response Examples without Huffman
-// Coding. This section shows several consecutive header lists, corresponding
-// to HTTP responses, on the same connection. The HTTP/2 setting parameter
-// SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing
-// some evictions to occur.
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.5
-TEST_P(HpackDecoderTest, C5_ResponseExamples) {
-  set_header_table_size_limit(256);
-
-  // C.5.1 First Response
-  //
-  // Header list to encode:
-  //
-  //   :status: 302
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   location: https://www.example.com
-
-  std::string hpack_block = HpackExampleToStringOrDie(R"(
-      48                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 8)
-                                              |     :status
-      03                                      |   Literal value (len = 3)
-      3330 32                                 | 302
-                                              | -> :status: 302
-      58                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 24)
-                                              |     cache-control
-      07                                      |   Literal value (len = 7)
-      7072 6976 6174 65                       | private
-                                              | -> cache-control: private
-      61                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 33)
-                                              |     date
-      1d                                      |   Literal value (len = 29)
-      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
-      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:21 GMT
-      6e                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 46)
-                                              |     location
-      17                                      |   Literal value (len = 23)
-      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
-      706c 652e 636f 6d                       | ple.com
-                                              | -> location:
-                                              |   https://www.example.com
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":status", "302"},
-                  HpackHeaderEntry{"cache-control", "private"},
-                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                  HpackHeaderEntry{"location", "https://www.example.com"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  63) location: https://www.example.com
-  //   [  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   [  3] (s =  52) cache-control: private
-  //   [  4] (s =  42) :status: 302
-  //         Table size: 222
-  ASSERT_TRUE(
-      VerifyDynamicTableContents({{"location", "https://www.example.com"},
-                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                                  {"cache-control", "private"},
-                                  {":status", "302"}}));
-  ASSERT_EQ(222u, current_header_table_size());
-
-  // C.5.2 Second Response
-  //
-  // The (":status", "302") header field is evicted from the dynamic table to
-  // free space to allow adding the (":status", "307") header field.
-  //
-  // Header list to encode:
-  //
-  //   :status: 307
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   location: https://www.example.com
-
-  hpack_block = HpackExampleToStringOrDie(R"(
-      48                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 8)
-                                              |     :status
-      03                                      |   Literal value (len = 3)
-      3330 37                                 | 307
-                                              | - evict: :status: 302
-                                              | -> :status: 307
-      c1                                      | == Indexed - Add ==
-                                              |   idx = 65
-                                              | -> cache-control: private
-      c0                                      | == Indexed - Add ==
-                                              |   idx = 64
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:21 GMT
-      bf                                      | == Indexed - Add ==
-                                              |   idx = 63
-                                              | -> location:
-                                              |   https://www.example.com
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":status", "307"},
-                  HpackHeaderEntry{"cache-control", "private"},
-                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                  HpackHeaderEntry{"location", "https://www.example.com"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  42) :status: 307
-  //   [  2] (s =  63) location: https://www.example.com
-  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   [  4] (s =  52) cache-control: private
-  //         Table size: 222
-
-  ASSERT_TRUE(
-      VerifyDynamicTableContents({{":status", "307"},
-                                  {"location", "https://www.example.com"},
-                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                                  {"cache-control", "private"}}));
-  ASSERT_EQ(222u, current_header_table_size());
-
-  // C.5.3 Third Response
-  //
-  // Several header fields are evicted from the dynamic table during the
-  // processing of this header list.
-  //
-  // Header list to encode:
-  //
-  //   :status: 200
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:22 GMT
-  //   location: https://www.example.com
-  //   content-encoding: gzip
-  //   set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1
-  hpack_block = HpackExampleToStringOrDie(R"(
-      88                                      | == Indexed - Add ==
-                                              |   idx = 8
-                                              | -> :status: 200
-      c1                                      | == Indexed - Add ==
-                                              |   idx = 65
-                                              | -> cache-control: private
-      61                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 33)
-                                              |     date
-      1d                                      |   Literal value (len = 29)
-      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
-      2032 303a 3133 3a32 3220 474d 54        |  20:13:22 GMT
-                                              | - evict: cache-control:
-                                              |   private
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:22 GMT
-      c0                                      | == Indexed - Add ==
-                                              |   idx = 64
-                                              | -> location:
-                                              |   https://www.example.com
-      5a                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 26)
-                                              |     content-encoding
-      04                                      |   Literal value (len = 4)
-      677a 6970                               | gzip
-                                              | - evict: date: Mon, 21 Oct
-                                              |    2013 20:13:21 GMT
-                                              | -> content-encoding: gzip
-      77                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 55)
-                                              |     set-cookie
-      38                                      |   Literal value (len = 56)
-      666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO
-      5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU;
-      206d 6178 2d61 6765 3d33 3630 303b 2076 |  max-age=3600; v
-      6572 7369 6f6e 3d31                     | ersion=1
-                                              | - evict: location:
-                                              |   https://www.example.com
-                                              | - evict: :status: 307
-                                              | -> set-cookie: foo=ASDJKHQ
-                                              |   KBZXOQWEOPIUAXQWEOIU; ma
-                                              |   x-age=3600; version=1
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(
-      header_entries_,
-      ElementsAreArray({
-          HpackHeaderEntry{":status", "200"},
-          HpackHeaderEntry{"cache-control", "private"},
-          HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:22 GMT"},
-          HpackHeaderEntry{"location", "https://www.example.com"},
-          HpackHeaderEntry{"content-encoding", "gzip"},
-          HpackHeaderEntry{
-              "set-cookie",
-              "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
-      }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
-  //                    max-age=3600; version=1
-  //   [  2] (s =  52) content-encoding: gzip
-  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
-  //         Table size: 215
-  ASSERT_TRUE(VerifyDynamicTableContents(
-      {{"set-cookie",
-        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
-       {"content-encoding", "gzip"},
-       {"date", "Mon, 21 Oct 2013 20:13:22 GMT"}}));
-  ASSERT_EQ(215u, current_header_table_size());
-}
-
-// Test based on RFC 7541, section C.6: Response Examples with Huffman Coding.
-// This section shows the same examples as the previous section but uses Huffman
-// encoding for the literal values. The HTTP/2 setting parameter
-// SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing some
-// evictions to occur. The eviction mechanism uses the length of the decoded
-// literal values, so the same evictions occur as in the previous section.
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6
-TEST_P(HpackDecoderTest, C6_ResponseExamplesWithHuffmanEncoding) {
-  set_header_table_size_limit(256);
-
-  // C.5.1 First Response
-  //
-  // Header list to encode:
-  //
-  //   :status: 302
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   location: https://www.example.com
-  std::string hpack_block = HpackExampleToStringOrDie(R"(
-      48                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 8)
-                                              |     :status
-      03                                      |   Literal value (len = 3)
-      3330 32                                 | 302
-                                              | -> :status: 302
-      58                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 24)
-                                              |     cache-control
-      07                                      |   Literal value (len = 7)
-      7072 6976 6174 65                       | private
-                                              | -> cache-control: private
-      61                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 33)
-                                              |     date
-      1d                                      |   Literal value (len = 29)
-      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
-      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:21 GMT
-      6e                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 46)
-                                              |     location
-      17                                      |   Literal value (len = 23)
-      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
-      706c 652e 636f 6d                       | ple.com
-                                              | -> location:
-                                              |   https://www.example.com
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":status", "302"},
-                  HpackHeaderEntry{"cache-control", "private"},
-                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                  HpackHeaderEntry{"location", "https://www.example.com"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  63) location: https://www.example.com
-  //   [  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   [  3] (s =  52) cache-control: private
-  //   [  4] (s =  42) :status: 302
-  //         Table size: 222
-  ASSERT_TRUE(
-      VerifyDynamicTableContents({{"location", "https://www.example.com"},
-                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                                  {"cache-control", "private"},
-                                  {":status", "302"}}));
-  ASSERT_EQ(222u, current_header_table_size());
-
-  // C.5.2 Second Response
-  //
-  // The (":status", "302") header field is evicted from the dynamic table to
-  // free space to allow adding the (":status", "307") header field.
-  //
-  // Header list to encode:
-  //
-  //   :status: 307
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   location: https://www.example.com
-  hpack_block = HpackExampleToStringOrDie(R"(
-      48                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 8)
-                                              |     :status
-      03                                      |   Literal value (len = 3)
-      3330 37                                 | 307
-                                              | - evict: :status: 302
-                                              | -> :status: 307
-      c1                                      | == Indexed - Add ==
-                                              |   idx = 65
-                                              | -> cache-control: private
-      c0                                      | == Indexed - Add ==
-                                              |   idx = 64
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:21 GMT
-      bf                                      | == Indexed - Add ==
-                                              |   idx = 63
-                                              | -> location:
-                                              |   https://www.example.com
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(header_entries_,
-              ElementsAreArray({
-                  HpackHeaderEntry{":status", "307"},
-                  HpackHeaderEntry{"cache-control", "private"},
-                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                  HpackHeaderEntry{"location", "https://www.example.com"},
-              }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  42) :status: 307
-  //   [  2] (s =  63) location: https://www.example.com
-  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
-  //   [  4] (s =  52) cache-control: private
-  //         Table size: 222
-  ASSERT_TRUE(
-      VerifyDynamicTableContents({{":status", "307"},
-                                  {"location", "https://www.example.com"},
-                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
-                                  {"cache-control", "private"}}));
-  ASSERT_EQ(222u, current_header_table_size());
-
-  // C.5.3 Third Response
-  //
-  // Several header fields are evicted from the dynamic table during the
-  // processing of this header list.
-  //
-  // Header list to encode:
-  //
-  //   :status: 200
-  //   cache-control: private
-  //   date: Mon, 21 Oct 2013 20:13:22 GMT
-  //   location: https://www.example.com
-  //   content-encoding: gzip
-  //   set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1
-  hpack_block = HpackExampleToStringOrDie(R"(
-      88                                      | == Indexed - Add ==
-                                              |   idx = 8
-                                              | -> :status: 200
-      c1                                      | == Indexed - Add ==
-                                              |   idx = 65
-                                              | -> cache-control: private
-      61                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 33)
-                                              |     date
-      1d                                      |   Literal value (len = 29)
-      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
-      2032 303a 3133 3a32 3220 474d 54        |  20:13:22 GMT
-                                              | - evict: cache-control:
-                                              |   private
-                                              | -> date: Mon, 21 Oct 2013
-                                              |   20:13:22 GMT
-      c0                                      | == Indexed - Add ==
-                                              |   idx = 64
-                                              | -> location:
-                                              |   https://www.example.com
-      5a                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 26)
-                                              |     content-encoding
-      04                                      |   Literal value (len = 4)
-      677a 6970                               | gzip
-                                              | - evict: date: Mon, 21 Oct
-                                              |    2013 20:13:21 GMT
-                                              | -> content-encoding: gzip
-      77                                      | == Literal indexed ==
-                                              |   Indexed name (idx = 55)
-                                              |     set-cookie
-      38                                      |   Literal value (len = 56)
-      666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO
-      5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU;
-      206d 6178 2d61 6765 3d33 3630 303b 2076 |  max-age=3600; v
-      6572 7369 6f6e 3d31                     | ersion=1
-                                              | - evict: location:
-                                              |   https://www.example.com
-                                              | - evict: :status: 307
-                                              | -> set-cookie: foo=ASDJKHQ
-                                              |   KBZXOQWEOPIUAXQWEOIU; ma
-                                              |   x-age=3600; version=1
-  )");
-  EXPECT_TRUE(DecodeBlock(hpack_block));
-  ASSERT_THAT(
-      header_entries_,
-      ElementsAreArray({
-          HpackHeaderEntry{":status", "200"},
-          HpackHeaderEntry{"cache-control", "private"},
-          HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:22 GMT"},
-          HpackHeaderEntry{"location", "https://www.example.com"},
-          HpackHeaderEntry{"content-encoding", "gzip"},
-          HpackHeaderEntry{
-              "set-cookie",
-              "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
-      }));
-
-  // Dynamic Table (after decoding):
-  //
-  //   [  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
-  //                    max-age=3600; version=1
-  //   [  2] (s =  52) content-encoding: gzip
-  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
-  //         Table size: 215
-  ASSERT_TRUE(VerifyDynamicTableContents(
-      {{"set-cookie",
-        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
-       {"content-encoding", "gzip"},
-       {"date", "Mon, 21 Oct 2013 20:13:22 GMT"}}));
-  ASSERT_EQ(215u, current_header_table_size());
-}
-
-// Confirm that the table size can be changed, but at most twice.
-TEST_P(HpackDecoderTest, ProcessesOptionalTableSizeUpdates) {
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-  // One update allowed.
-  {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(3000);
-    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-    EXPECT_EQ(3000u, header_table_size_limit());
-    EXPECT_EQ(0u, current_header_table_size());
-    EXPECT_TRUE(header_entries_.empty());
-  }
-  // Two updates allowed.
-  {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(2000);
-    hbb.AppendDynamicTableSizeUpdate(2500);
-    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-    EXPECT_EQ(2500u, header_table_size_limit());
-    EXPECT_EQ(0u, current_header_table_size());
-    EXPECT_TRUE(header_entries_.empty());
-  }
-  // A third update in the same HPACK block is rejected, so the final
-  // size is 1000, not 500.
-  {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(1500);
-    hbb.AppendDynamicTableSizeUpdate(1000);
-    hbb.AppendDynamicTableSizeUpdate(500);
-    EXPECT_FALSE(DecodeBlock(hbb.buffer()));
-    EXPECT_EQ(HpackDecodingError::kDynamicTableSizeUpdateNotAllowed,
-              decoder_.error());
-    EXPECT_EQ(1u, error_messages_.size());
-    EXPECT_THAT(error_messages_[0],
-                Eq("Dynamic table size update not allowed"));
-    EXPECT_EQ(1000u, header_table_size_limit());
-    EXPECT_EQ(0u, current_header_table_size());
-    EXPECT_TRUE(header_entries_.empty());
-  }
-  // An error has been detected, so calls to HpackDecoder::DecodeFragment
-  // should return immediately.
-  DecodeBuffer db("\x80");
-  EXPECT_FALSE(decoder_.DecodeFragment(&db));
-  EXPECT_EQ(0u, db.Offset());
-  EXPECT_EQ(1u, error_messages_.size());
-}
-
-// Confirm that the table size can be changed when required, but at most twice.
-TEST_P(HpackDecoderTest, ProcessesRequiredTableSizeUpdate) {
-  EXPECT_EQ(4096u, decoder_.GetCurrentHeaderTableSizeSetting());
-  // One update required, two allowed, one provided, followed by a header.
-  decoder_.ApplyHeaderTableSizeSetting(1024);
-  decoder_.ApplyHeaderTableSizeSetting(2048);
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-  EXPECT_EQ(2048u, decoder_.GetCurrentHeaderTableSizeSetting());
-  {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(1024);
-    hbb.AppendIndexedHeader(4);  // :path: /
-    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-    EXPECT_THAT(header_entries_,
-                ElementsAreArray({HpackHeaderEntry{":path", "/"}}));
-    EXPECT_EQ(1024u, header_table_size_limit());
-    EXPECT_EQ(0u, current_header_table_size());
-  }
-  // One update required, two allowed, two provided, followed by a header.
-  decoder_.ApplyHeaderTableSizeSetting(1000);
-  decoder_.ApplyHeaderTableSizeSetting(1500);
-  EXPECT_EQ(1500u, decoder_.GetCurrentHeaderTableSizeSetting());
-  {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(500);
-    hbb.AppendDynamicTableSizeUpdate(1250);
-    hbb.AppendIndexedHeader(5);  // :path: /index.html
-    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-    EXPECT_THAT(header_entries_,
-                ElementsAreArray({HpackHeaderEntry{":path", "/index.html"}}));
-    EXPECT_EQ(1250u, header_table_size_limit());
-    EXPECT_EQ(0u, current_header_table_size());
-  }
-  // One update required, two allowed, three provided, followed by a header.
-  // The third update is rejected, so the final size is 1000, not 500.
-  decoder_.ApplyHeaderTableSizeSetting(500);
-  decoder_.ApplyHeaderTableSizeSetting(1000);
-  EXPECT_EQ(1000u, decoder_.GetCurrentHeaderTableSizeSetting());
-  {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(200);
-    hbb.AppendDynamicTableSizeUpdate(700);
-    hbb.AppendDynamicTableSizeUpdate(900);
-    hbb.AppendIndexedHeader(5);  // Not decoded.
-    EXPECT_FALSE(DecodeBlock(hbb.buffer()));
-    EXPECT_FALSE(saw_end_);
-    EXPECT_EQ(HpackDecodingError::kDynamicTableSizeUpdateNotAllowed,
-              decoder_.error());
-    EXPECT_EQ(1u, error_messages_.size());
-    EXPECT_THAT(error_messages_[0],
-                Eq("Dynamic table size update not allowed"));
-    EXPECT_EQ(700u, header_table_size_limit());
-    EXPECT_EQ(0u, current_header_table_size());
-    EXPECT_TRUE(header_entries_.empty());
-  }
-  EXPECT_EQ(1000u, decoder_.GetCurrentHeaderTableSizeSetting());
-  // Now that an error has been detected, StartDecodingBlock should return
-  // false.
-  EXPECT_FALSE(decoder_.StartDecodingBlock());
-}
-
-// Confirm that required size updates are validated.
-TEST_P(HpackDecoderTest, InvalidRequiredSizeUpdate) {
-  // Require a size update, but provide one that isn't small enough (must be
-  // zero or one, in this case).
-  decoder_.ApplyHeaderTableSizeSetting(1);
-  decoder_.ApplyHeaderTableSizeSetting(1024);
-  HpackBlockBuilder hbb;
-  hbb.AppendDynamicTableSizeUpdate(2);
-  EXPECT_TRUE(decoder_.StartDecodingBlock());
-  DecodeBuffer db(hbb.buffer());
-  EXPECT_FALSE(decoder_.DecodeFragment(&db));
-  EXPECT_FALSE(saw_end_);
-  EXPECT_EQ(
-      HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark,
-      decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0],
-              Eq("Initial dynamic table size update is above low water mark"));
-  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
-            header_table_size_limit());
-}
-
-// Confirm that required size updates are indeed required before the end.
-TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeEnd) {
-  decoder_.ApplyHeaderTableSizeSetting(1024);
-  EXPECT_FALSE(DecodeBlock(""));
-  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
-            decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
-  EXPECT_FALSE(saw_end_);
-}
-
-// Confirm that required size updates are indeed required before an
-// indexed header.
-TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeIndexedHeader) {
-  decoder_.ApplyHeaderTableSizeSetting(1024);
-  HpackBlockBuilder hbb;
-  hbb.AppendIndexedHeader(1);
-  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
-  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
-            decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
-  EXPECT_FALSE(saw_end_);
-  EXPECT_TRUE(header_entries_.empty());
-}
-
-// Confirm that required size updates are indeed required before an indexed
-// header name.
-// TODO(jamessynge): Move some of these to hpack_decoder_state_test.cc.
-TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeIndexedHeaderName) {
-  decoder_.ApplyHeaderTableSizeSetting(1024);
-  HpackBlockBuilder hbb;
-  hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 2,
-                                     false, "PUT");
-  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
-  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
-            decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
-  EXPECT_FALSE(saw_end_);
-  EXPECT_TRUE(header_entries_.empty());
-}
-
-// Confirm that required size updates are indeed required before a literal
-// header name.
-TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeLiteralName) {
-  decoder_.ApplyHeaderTableSizeSetting(1024);
-  HpackBlockBuilder hbb;
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
-                                false, "name", false, "some data.");
-  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
-  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
-            decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
-  EXPECT_FALSE(saw_end_);
-  EXPECT_TRUE(header_entries_.empty());
-}
-
-// Confirm that an excessively long varint is detected, in this case an
-// index of 127, but with lots of additional high-order 0 bits provided,
-// too many to be allowed.
-TEST_P(HpackDecoderTest, InvalidIndexedHeaderVarint) {
-  EXPECT_TRUE(decoder_.StartDecodingBlock());
-  DecodeBuffer db("\xff\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00");
-  EXPECT_FALSE(decoder_.DecodeFragment(&db));
-  EXPECT_TRUE(decoder_.DetectError());
-  EXPECT_FALSE(saw_end_);
-  EXPECT_EQ(HpackDecodingError::kIndexVarintError, decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0],
-              Eq("Index varint beyond implementation limit"));
-  EXPECT_TRUE(header_entries_.empty());
-  // Now that an error has been detected, EndDecodingBlock should not succeed.
-  EXPECT_FALSE(decoder_.EndDecodingBlock());
-}
-
-// Confirm that an invalid index into the tables is detected, in this case an
-// index of 0.
-TEST_P(HpackDecoderTest, InvalidIndex) {
-  EXPECT_TRUE(decoder_.StartDecodingBlock());
-  DecodeBuffer db("\x80");
-  EXPECT_FALSE(decoder_.DecodeFragment(&db));
-  EXPECT_TRUE(decoder_.DetectError());
-  EXPECT_FALSE(saw_end_);
-  EXPECT_EQ(HpackDecodingError::kInvalidIndex, decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0],
-              Eq("Invalid index in indexed header field representation"));
-  EXPECT_TRUE(header_entries_.empty());
-  // Now that an error has been detected, EndDecodingBlock should not succeed.
-  EXPECT_FALSE(decoder_.EndDecodingBlock());
-}
-
-// Confirm that EndDecodingBlock detects a truncated HPACK block.
-TEST_P(HpackDecoderTest, TruncatedBlock) {
-  HpackBlockBuilder hbb;
-  hbb.AppendDynamicTableSizeUpdate(3000);
-  EXPECT_EQ(3u, hbb.size());
-  hbb.AppendDynamicTableSizeUpdate(4000);
-  EXPECT_EQ(6u, hbb.size());
-  // Decodes this block if the whole thing is provided.
-  EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-  EXPECT_EQ(4000u, header_table_size_limit());
-  // Multiple times even.
-  EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-  EXPECT_EQ(4000u, header_table_size_limit());
-  // But not if the block is truncated.
-  EXPECT_FALSE(DecodeBlock(hbb.buffer().substr(0, hbb.size() - 1)));
-  EXPECT_FALSE(saw_end_);
-  EXPECT_EQ(HpackDecodingError::kTruncatedBlock, decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0],
-              Eq("Block ends in the middle of an instruction"));
-  // The first update was decoded.
-  EXPECT_EQ(3000u, header_table_size_limit());
-  EXPECT_EQ(0u, current_header_table_size());
-  EXPECT_TRUE(header_entries_.empty());
-}
-
-// Confirm that an oversized string is detected, ending decoding.
-TEST_P(HpackDecoderTest, OversizeStringDetected) {
-  HpackBlockBuilder hbb;
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
-                                false, "name", false, "some data.");
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kUnindexedLiteralHeader, false,
-                                "name2", false, "longer data");
-
-  // Normally able to decode this block.
-  EXPECT_TRUE(DecodeBlock(hbb.buffer()));
-  EXPECT_THAT(header_entries_,
-              ElementsAreArray({HpackHeaderEntry{"name", "some data."},
-                                HpackHeaderEntry{"name2", "longer data"}}));
-
-  // But not if the maximum size of strings is less than the longest string.
-  decoder_.set_max_string_size_bytes(10);
-  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
-  EXPECT_THAT(header_entries_,
-              ElementsAreArray({HpackHeaderEntry{"name", "some data."}}));
-  EXPECT_FALSE(saw_end_);
-  EXPECT_EQ(HpackDecodingError::kValueTooLong, decoder_.error());
-  EXPECT_EQ(1u, error_messages_.size());
-  EXPECT_THAT(error_messages_[0], Eq("Value length exceeds buffer limit"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoding_error.cc b/http2/hpack/decoder/hpack_decoding_error.cc
deleted file mode 100644
index 24db30d..0000000
--- a/http2/hpack/decoder/hpack_decoding_error.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-
-namespace http2 {
-
-// static
-absl::string_view HpackDecodingErrorToString(HpackDecodingError error) {
-  switch (error) {
-    case HpackDecodingError::kOk:
-      return "No error detected";
-    case HpackDecodingError::kIndexVarintError:
-      return "Index varint beyond implementation limit";
-    case HpackDecodingError::kNameLengthVarintError:
-      return "Name length varint beyond implementation limit";
-    case HpackDecodingError::kValueLengthVarintError:
-      return "Value length varint beyond implementation limit";
-    case HpackDecodingError::kNameTooLong:
-      return "Name length exceeds buffer limit";
-    case HpackDecodingError::kValueTooLong:
-      return "Value length exceeds buffer limit";
-    case HpackDecodingError::kNameHuffmanError:
-      return "Name Huffman encoding error";
-    case HpackDecodingError::kValueHuffmanError:
-      return "Value Huffman encoding error";
-    case HpackDecodingError::kMissingDynamicTableSizeUpdate:
-      return "Missing dynamic table size update";
-    case HpackDecodingError::kInvalidIndex:
-      return "Invalid index in indexed header field representation";
-    case HpackDecodingError::kInvalidNameIndex:
-      return "Invalid index in literal header field with indexed name "
-             "representation";
-    case HpackDecodingError::kDynamicTableSizeUpdateNotAllowed:
-      return "Dynamic table size update not allowed";
-    case HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark:
-      return "Initial dynamic table size update is above low water mark";
-    case HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting:
-      return "Dynamic table size update is above acknowledged setting";
-    case HpackDecodingError::kTruncatedBlock:
-      return "Block ends in the middle of an instruction";
-    case HpackDecodingError::kFragmentTooLong:
-      return "Incoming data fragment exceeds buffer limit";
-    case HpackDecodingError::kCompressedHeaderSizeExceedsLimit:
-      return "Total compressed HPACK data size exceeds limit";
-  }
-  return "invalid HpackDecodingError value";
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_decoding_error.h b/http2/hpack/decoder/hpack_decoding_error.h
deleted file mode 100644
index 0b97087..0000000
--- a/http2/hpack/decoder/hpack_decoding_error.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-enum class HpackDecodingError {
-  // No error detected so far.
-  kOk,
-  // Varint beyond implementation limit.
-  kIndexVarintError,
-  kNameLengthVarintError,
-  kValueLengthVarintError,
-  // String literal length exceeds buffer limit.
-  kNameTooLong,
-  kValueTooLong,
-  // Error in Huffman encoding.
-  kNameHuffmanError,
-  kValueHuffmanError,
-  // Next instruction should have been a dynamic table size update.
-  kMissingDynamicTableSizeUpdate,
-  // Invalid index in indexed header field representation.
-  kInvalidIndex,
-  // Invalid index in literal header field with indexed name representation.
-  kInvalidNameIndex,
-  // Dynamic table size update not allowed.
-  kDynamicTableSizeUpdateNotAllowed,
-  // Initial dynamic table size update is above low water mark.
-  kInitialDynamicTableSizeUpdateIsAboveLowWaterMark,
-  // Dynamic table size update is above acknowledged setting.
-  kDynamicTableSizeUpdateIsAboveAcknowledgedSetting,
-  // HPACK block ends in the middle of an instruction.
-  kTruncatedBlock,
-  // Incoming data fragment exceeds buffer limit.
-  kFragmentTooLong,
-  // Total compressed HPACK data size exceeds limit.
-  kCompressedHeaderSizeExceedsLimit,
-};
-
-QUICHE_EXPORT_PRIVATE absl::string_view HpackDecodingErrorToString(
-    HpackDecodingError error);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_
diff --git a/http2/hpack/decoder/hpack_entry_collector.cc b/http2/hpack/decoder/hpack_entry_collector.cc
deleted file mode 100644
index de7d2e2..0000000
--- a/http2/hpack/decoder/hpack_entry_collector.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_entry_collector.h"
-
-#include "absl/strings/str_cat.h"
-#include "http2/hpack/decoder/hpack_string_collector.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-
-namespace http2 {
-namespace test {
-namespace {
-
-const HpackEntryType kInvalidHeaderType = static_cast<HpackEntryType>(99);
-const size_t kInvalidIndex = 99999999;
-
-}  // namespace
-
-HpackEntryCollector::HpackEntryCollector() {
-  Clear();
-}
-
-HpackEntryCollector::HpackEntryCollector(const HpackEntryCollector& other) =
-    default;
-
-HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
-                                         size_t index_or_size)
-    : header_type_(type), index_(index_or_size), started_(true), ended_(true) {}
-HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
-                                         size_t index,
-                                         bool value_huffman,
-                                         const std::string& value)
-    : header_type_(type),
-      index_(index),
-      value_(value, value_huffman),
-      started_(true),
-      ended_(true) {}
-HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
-                                         bool name_huffman,
-                                         const std::string& name,
-                                         bool value_huffman,
-                                         const std::string& value)
-    : header_type_(type),
-      index_(0),
-      name_(name, name_huffman),
-      value_(value, value_huffman),
-      started_(true),
-      ended_(true) {}
-
-HpackEntryCollector::~HpackEntryCollector() = default;
-
-void HpackEntryCollector::OnIndexedHeader(size_t index) {
-  ASSERT_FALSE(started_);
-  ASSERT_TRUE(IsClear()) << ToString();
-  Init(HpackEntryType::kIndexedHeader, index);
-  ended_ = true;
-}
-void HpackEntryCollector::OnStartLiteralHeader(HpackEntryType header_type,
-                                               size_t maybe_name_index) {
-  ASSERT_FALSE(started_);
-  ASSERT_TRUE(IsClear()) << ToString();
-  Init(header_type, maybe_name_index);
-}
-void HpackEntryCollector::OnNameStart(bool huffman_encoded, size_t len) {
-  ASSERT_TRUE(started_);
-  ASSERT_FALSE(ended_);
-  ASSERT_FALSE(IsClear());
-  ASSERT_TRUE(LiteralNameExpected()) << ToString();
-  name_.OnStringStart(huffman_encoded, len);
-}
-void HpackEntryCollector::OnNameData(const char* data, size_t len) {
-  ASSERT_TRUE(started_);
-  ASSERT_FALSE(ended_);
-  ASSERT_TRUE(LiteralNameExpected()) << ToString();
-  ASSERT_TRUE(name_.IsInProgress());
-  name_.OnStringData(data, len);
-}
-void HpackEntryCollector::OnNameEnd() {
-  ASSERT_TRUE(started_);
-  ASSERT_FALSE(ended_);
-  ASSERT_TRUE(LiteralNameExpected()) << ToString();
-  ASSERT_TRUE(name_.IsInProgress());
-  name_.OnStringEnd();
-}
-void HpackEntryCollector::OnValueStart(bool huffman_encoded, size_t len) {
-  ASSERT_TRUE(started_);
-  ASSERT_FALSE(ended_);
-  if (LiteralNameExpected()) {
-    ASSERT_TRUE(name_.HasEnded());
-  }
-  ASSERT_TRUE(LiteralValueExpected()) << ToString();
-  ASSERT_TRUE(value_.IsClear()) << value_.ToString();
-  value_.OnStringStart(huffman_encoded, len);
-}
-void HpackEntryCollector::OnValueData(const char* data, size_t len) {
-  ASSERT_TRUE(started_);
-  ASSERT_FALSE(ended_);
-  ASSERT_TRUE(LiteralValueExpected()) << ToString();
-  ASSERT_TRUE(value_.IsInProgress());
-  value_.OnStringData(data, len);
-}
-void HpackEntryCollector::OnValueEnd() {
-  ASSERT_TRUE(started_);
-  ASSERT_FALSE(ended_);
-  ASSERT_TRUE(LiteralValueExpected()) << ToString();
-  ASSERT_TRUE(value_.IsInProgress());
-  value_.OnStringEnd();
-  ended_ = true;
-}
-void HpackEntryCollector::OnDynamicTableSizeUpdate(size_t size) {
-  ASSERT_FALSE(started_);
-  ASSERT_TRUE(IsClear()) << ToString();
-  Init(HpackEntryType::kDynamicTableSizeUpdate, size);
-  ended_ = true;
-}
-
-void HpackEntryCollector::Clear() {
-  header_type_ = kInvalidHeaderType;
-  index_ = kInvalidIndex;
-  name_.Clear();
-  value_.Clear();
-  started_ = ended_ = false;
-}
-bool HpackEntryCollector::IsClear() const {
-  return header_type_ == kInvalidHeaderType && index_ == kInvalidIndex &&
-         name_.IsClear() && value_.IsClear() && !started_ && !ended_;
-}
-bool HpackEntryCollector::IsComplete() const {
-  return started_ && ended_;
-}
-bool HpackEntryCollector::LiteralNameExpected() const {
-  switch (header_type_) {
-    case HpackEntryType::kIndexedLiteralHeader:
-    case HpackEntryType::kUnindexedLiteralHeader:
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      return index_ == 0;
-    default:
-      return false;
-  }
-}
-bool HpackEntryCollector::LiteralValueExpected() const {
-  switch (header_type_) {
-    case HpackEntryType::kIndexedLiteralHeader:
-    case HpackEntryType::kUnindexedLiteralHeader:
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      return true;
-    default:
-      return false;
-  }
-}
-AssertionResult HpackEntryCollector::ValidateIndexedHeader(
-    size_t expected_index) const {
-  VERIFY_TRUE(started_);
-  VERIFY_TRUE(ended_);
-  VERIFY_EQ(HpackEntryType::kIndexedHeader, header_type_);
-  VERIFY_EQ(expected_index, index_);
-  return ::testing::AssertionSuccess();
-}
-AssertionResult HpackEntryCollector::ValidateLiteralValueHeader(
-    HpackEntryType expected_type,
-    size_t expected_index,
-    bool expected_value_huffman,
-    absl::string_view expected_value) const {
-  VERIFY_TRUE(started_);
-  VERIFY_TRUE(ended_);
-  VERIFY_EQ(expected_type, header_type_);
-  VERIFY_NE(0u, expected_index);
-  VERIFY_EQ(expected_index, index_);
-  VERIFY_TRUE(name_.IsClear());
-  VERIFY_SUCCESS(value_.Collected(expected_value, expected_value_huffman));
-  return ::testing::AssertionSuccess();
-}
-AssertionResult HpackEntryCollector::ValidateLiteralNameValueHeader(
-    HpackEntryType expected_type,
-    bool expected_name_huffman,
-    absl::string_view expected_name,
-    bool expected_value_huffman,
-    absl::string_view expected_value) const {
-  VERIFY_TRUE(started_);
-  VERIFY_TRUE(ended_);
-  VERIFY_EQ(expected_type, header_type_);
-  VERIFY_EQ(0u, index_);
-  VERIFY_SUCCESS(name_.Collected(expected_name, expected_name_huffman));
-  VERIFY_SUCCESS(value_.Collected(expected_value, expected_value_huffman));
-  return ::testing::AssertionSuccess();
-}
-AssertionResult HpackEntryCollector::ValidateDynamicTableSizeUpdate(
-    size_t size) const {
-  VERIFY_TRUE(started_);
-  VERIFY_TRUE(ended_);
-  VERIFY_EQ(HpackEntryType::kDynamicTableSizeUpdate, header_type_);
-  VERIFY_EQ(index_, size);
-  return ::testing::AssertionSuccess();
-}
-
-void HpackEntryCollector::AppendToHpackBlockBuilder(
-    HpackBlockBuilder* hbb) const {
-  ASSERT_TRUE(started_ && ended_) << *this;
-  switch (header_type_) {
-    case HpackEntryType::kIndexedHeader:
-      hbb->AppendIndexedHeader(index_);
-      return;
-
-    case HpackEntryType::kDynamicTableSizeUpdate:
-      hbb->AppendDynamicTableSizeUpdate(index_);
-      return;
-
-    case HpackEntryType::kIndexedLiteralHeader:
-    case HpackEntryType::kUnindexedLiteralHeader:
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      ASSERT_TRUE(value_.HasEnded()) << *this;
-      if (index_ != 0) {
-        QUICHE_CHECK(name_.IsClear());
-        hbb->AppendNameIndexAndLiteralValue(header_type_, index_,
-                                            value_.huffman_encoded, value_.s);
-      } else {
-        QUICHE_CHECK(name_.HasEnded()) << *this;
-        hbb->AppendLiteralNameAndValue(header_type_, name_.huffman_encoded,
-                                       name_.s, value_.huffman_encoded,
-                                       value_.s);
-      }
-      return;
-
-    default:
-      ADD_FAILURE() << *this;
-  }
-}
-
-std::string HpackEntryCollector::ToString() const {
-  std::string result("Type=");
-  switch (header_type_) {
-    case HpackEntryType::kIndexedHeader:
-      result += "IndexedHeader";
-      break;
-    case HpackEntryType::kDynamicTableSizeUpdate:
-      result += "DynamicTableSizeUpdate";
-      break;
-    case HpackEntryType::kIndexedLiteralHeader:
-      result += "IndexedLiteralHeader";
-      break;
-    case HpackEntryType::kUnindexedLiteralHeader:
-      result += "UnindexedLiteralHeader";
-      break;
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      result += "NeverIndexedLiteralHeader";
-      break;
-    default:
-      if (header_type_ == kInvalidHeaderType) {
-        result += "<unset>";
-      } else {
-        absl::StrAppend(&result, header_type_);
-      }
-  }
-  if (index_ != 0) {
-    absl::StrAppend(&result, " Index=", index_);
-  }
-  if (!name_.IsClear()) {
-    absl::StrAppend(&result, " Name", name_.ToString());
-  }
-  if (!value_.IsClear()) {
-    absl::StrAppend(&result, " Value", value_.ToString());
-  }
-  if (!started_) {
-    EXPECT_FALSE(ended_);
-    absl::StrAppend(&result, " !started");
-  } else if (!ended_) {
-    absl::StrAppend(&result, " !ended");
-  } else {
-    absl::StrAppend(&result, " Complete");
-  }
-  return result;
-}
-
-void HpackEntryCollector::Init(HpackEntryType type, size_t maybe_index) {
-  ASSERT_TRUE(IsClear()) << ToString();
-  header_type_ = type;
-  index_ = maybe_index;
-  started_ = true;
-}
-
-bool operator==(const HpackEntryCollector& a, const HpackEntryCollector& b) {
-  return a.name() == b.name() && a.value() == b.value() &&
-         a.index() == b.index() && a.header_type() == b.header_type() &&
-         a.started() == b.started() && a.ended() == b.ended();
-}
-bool operator!=(const HpackEntryCollector& a, const HpackEntryCollector& b) {
-  return !(a == b);
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackEntryCollector& v) {
-  return out << v.ToString();
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_entry_collector.h b/http2/hpack/decoder/hpack_entry_collector.h
deleted file mode 100644
index cbce8df..0000000
--- a/http2/hpack/decoder/hpack_entry_collector.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_COLLECTOR_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_COLLECTOR_H_
-
-// HpackEntryCollector records calls to HpackEntryDecoderListener in support
-// of tests of HpackEntryDecoder, or which use it. Can only record the callbacks
-// for the decoding of a single entry; call Clear() between decoding successive
-// entries or use a distinct HpackEntryCollector for each entry.
-
-#include <stddef.h>
-
-#include <iosfwd>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_entry_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_string_collector.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class HpackEntryCollector : public HpackEntryDecoderListener {
- public:
-  HpackEntryCollector();
-  HpackEntryCollector(const HpackEntryCollector& other);
-
-  // These next three constructors are intended for use in tests that create
-  // an HpackEntryCollector "manually", and then compare it against another
-  // that is populated via calls to the HpackEntryDecoderListener methods.
-  HpackEntryCollector(HpackEntryType type, size_t index_or_size);
-  HpackEntryCollector(HpackEntryType type,
-                      size_t index,
-                      bool value_huffman,
-                      const std::string& value);
-  HpackEntryCollector(HpackEntryType type,
-                      bool name_huffman,
-                      const std::string& name,
-                      bool value_huffman,
-                      const std::string& value);
-
-  ~HpackEntryCollector() override;
-
-  // Methods defined by HpackEntryDecoderListener.
-  void OnIndexedHeader(size_t index) override;
-  void OnStartLiteralHeader(HpackEntryType header_type,
-                            size_t maybe_name_index) override;
-  void OnNameStart(bool huffman_encoded, size_t len) override;
-  void OnNameData(const char* data, size_t len) override;
-  void OnNameEnd() override;
-  void OnValueStart(bool huffman_encoded, size_t len) override;
-  void OnValueData(const char* data, size_t len) override;
-  void OnValueEnd() override;
-  void OnDynamicTableSizeUpdate(size_t size) override;
-
-  // Clears the fields of the collector so that it is ready to start collecting
-  // another HPACK block entry.
-  void Clear();
-
-  // Is the collector ready to start collecting another HPACK block entry.
-  bool IsClear() const;
-
-  // Has a complete entry been collected?
-  bool IsComplete() const;
-
-  // Based on the HpackEntryType, is a literal name expected?
-  bool LiteralNameExpected() const;
-
-  // Based on the HpackEntryType, is a literal value expected?
-  bool LiteralValueExpected() const;
-
-  // Returns success if collected an Indexed Header (i.e. OnIndexedHeader was
-  // called).
-  ::testing::AssertionResult ValidateIndexedHeader(size_t expected_index) const;
-
-  // Returns success if collected a Header with an indexed name and literal
-  // value (i.e. OnStartLiteralHeader was called with a non-zero index for
-  // the name, which must match expected_index).
-  ::testing::AssertionResult ValidateLiteralValueHeader(
-      HpackEntryType expected_type,
-      size_t expected_index,
-      bool expected_value_huffman,
-      absl::string_view expected_value) const;
-
-  // Returns success if collected a Header with an literal name and literal
-  // value.
-  ::testing::AssertionResult ValidateLiteralNameValueHeader(
-      HpackEntryType expected_type,
-      bool expected_name_huffman,
-      absl::string_view expected_name,
-      bool expected_value_huffman,
-      absl::string_view expected_value) const;
-
-  // Returns success if collected a Dynamic Table Size Update,
-  // with the specified size.
-  ::testing::AssertionResult ValidateDynamicTableSizeUpdate(
-      size_t expected_size) const;
-
-  void set_header_type(HpackEntryType v) { header_type_ = v; }
-  HpackEntryType header_type() const { return header_type_; }
-
-  void set_index(size_t v) { index_ = v; }
-  size_t index() const { return index_; }
-
-  void set_name(const HpackStringCollector& v) { name_ = v; }
-  const HpackStringCollector& name() const { return name_; }
-
-  void set_value(const HpackStringCollector& v) { value_ = v; }
-  const HpackStringCollector& value() const { return value_; }
-
-  void set_started(bool v) { started_ = v; }
-  bool started() const { return started_; }
-
-  void set_ended(bool v) { ended_ = v; }
-  bool ended() const { return ended_; }
-
-  void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const;
-
-  // Returns a debug string.
-  std::string ToString() const;
-
- private:
-  void Init(HpackEntryType type, size_t maybe_index);
-
-  HpackEntryType header_type_;
-  size_t index_;
-
-  HpackStringCollector name_;
-  HpackStringCollector value_;
-
-  // True if has received a call to an HpackEntryDecoderListener method
-  // indicating the start of decoding an HPACK entry; for example,
-  // OnIndexedHeader set it true, but OnNameStart does not change it.
-  bool started_ = false;
-
-  // True if has received a call to an HpackEntryDecoderListener method
-  // indicating the end of decoding an HPACK entry; for example,
-  // OnIndexedHeader and OnValueEnd both set it true, but OnNameEnd does
-  // not change it.
-  bool ended_ = false;
-};
-
-bool operator==(const HpackEntryCollector& a, const HpackEntryCollector& b);
-bool operator!=(const HpackEntryCollector& a, const HpackEntryCollector& b);
-std::ostream& operator<<(std::ostream& out, const HpackEntryCollector& v);
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_COLLECTOR_H_
diff --git a/http2/hpack/decoder/hpack_entry_decoder.cc b/http2/hpack/decoder/hpack_entry_decoder.cc
deleted file mode 100644
index 1302248..0000000
--- a/http2/hpack/decoder/hpack_entry_decoder.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_entry_decoder.h"
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "absl/base/macros.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_flags.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-namespace {
-// Converts calls from HpackStringDecoder when decoding a header name into the
-// appropriate HpackEntryDecoderListener::OnName* calls.
-class NameDecoderListener {
- public:
-  explicit NameDecoderListener(HpackEntryDecoderListener* listener)
-      : listener_(listener) {}
-  bool OnStringStart(bool huffman_encoded, size_t len) {
-    listener_->OnNameStart(huffman_encoded, len);
-    return true;
-  }
-  void OnStringData(const char* data, size_t len) {
-    listener_->OnNameData(data, len);
-  }
-  void OnStringEnd() { listener_->OnNameEnd(); }
-
- private:
-  HpackEntryDecoderListener* listener_;
-};
-
-// Converts calls from HpackStringDecoder when decoding a header value into
-// the appropriate HpackEntryDecoderListener::OnValue* calls.
-class ValueDecoderListener {
- public:
-  explicit ValueDecoderListener(HpackEntryDecoderListener* listener)
-      : listener_(listener) {}
-  bool OnStringStart(bool huffman_encoded, size_t len) {
-    listener_->OnValueStart(huffman_encoded, len);
-    return true;
-  }
-  void OnStringData(const char* data, size_t len) {
-    listener_->OnValueData(data, len);
-  }
-  void OnStringEnd() { listener_->OnValueEnd(); }
-
- private:
-  HpackEntryDecoderListener* listener_;
-};
-}  // namespace
-
-DecodeStatus HpackEntryDecoder::Start(DecodeBuffer* db,
-                                      HpackEntryDecoderListener* listener) {
-  QUICHE_DCHECK(db != nullptr);
-  QUICHE_DCHECK(listener != nullptr);
-  QUICHE_DCHECK(db->HasData());
-  DecodeStatus status = entry_type_decoder_.Start(db);
-  switch (status) {
-    case DecodeStatus::kDecodeDone:
-      // The type of the entry and its varint fit into the current decode
-      // buffer.
-      if (entry_type_decoder_.entry_type() == HpackEntryType::kIndexedHeader) {
-        // The entry consists solely of the entry type and varint.
-        // This is by far the most common case in practice.
-        listener->OnIndexedHeader(entry_type_decoder_.varint());
-        return DecodeStatus::kDecodeDone;
-      }
-      state_ = EntryDecoderState::kDecodedType;
-      return Resume(db, listener);
-    case DecodeStatus::kDecodeInProgress:
-      // Hit the end of the decode buffer before fully decoding
-      // the entry type and varint.
-      QUICHE_DCHECK_EQ(0u, db->Remaining());
-      state_ = EntryDecoderState::kResumeDecodingType;
-      return status;
-    case DecodeStatus::kDecodeError:
-      HTTP2_CODE_COUNT_N(decompress_failure_3, 11, 23);
-      error_ = HpackDecodingError::kIndexVarintError;
-      // The varint must have been invalid (too long).
-      return status;
-  }
-
-  HTTP2_BUG(http2_bug_63_1) << "Unreachable";
-  return DecodeStatus::kDecodeError;
-}
-
-DecodeStatus HpackEntryDecoder::Resume(DecodeBuffer* db,
-                                       HpackEntryDecoderListener* listener) {
-  QUICHE_DCHECK(db != nullptr);
-  QUICHE_DCHECK(listener != nullptr);
-
-  DecodeStatus status;
-
-  do {
-    switch (state_) {
-      case EntryDecoderState::kResumeDecodingType:
-        // entry_type_decoder_ returned kDecodeInProgress when last called.
-        HTTP2_DVLOG(1) << "kResumeDecodingType: db->Remaining="
-                       << db->Remaining();
-        status = entry_type_decoder_.Resume(db);
-        if (status == DecodeStatus::kDecodeError) {
-          HTTP2_CODE_COUNT_N(decompress_failure_3, 12, 23);
-          error_ = HpackDecodingError::kIndexVarintError;
-        }
-        if (status != DecodeStatus::kDecodeDone) {
-          return status;
-        }
-        state_ = EntryDecoderState::kDecodedType;
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case EntryDecoderState::kDecodedType:
-        // entry_type_decoder_ returned kDecodeDone, now need to decide how
-        // to proceed.
-        HTTP2_DVLOG(1) << "kDecodedType: db->Remaining=" << db->Remaining();
-        if (DispatchOnType(listener)) {
-          // All done.
-          return DecodeStatus::kDecodeDone;
-        }
-        continue;
-
-      case EntryDecoderState::kStartDecodingName:
-        HTTP2_DVLOG(1) << "kStartDecodingName: db->Remaining="
-                       << db->Remaining();
-        {
-          NameDecoderListener ncb(listener);
-          status = string_decoder_.Start(db, &ncb);
-        }
-        if (status != DecodeStatus::kDecodeDone) {
-          // On the assumption that the status is kDecodeInProgress, set
-          // state_ accordingly; unnecessary if status is kDecodeError, but
-          // that will only happen if the varint encoding the name's length
-          // is too long.
-          state_ = EntryDecoderState::kResumeDecodingName;
-          if (status == DecodeStatus::kDecodeError) {
-            HTTP2_CODE_COUNT_N(decompress_failure_3, 13, 23);
-            error_ = HpackDecodingError::kNameLengthVarintError;
-          }
-          return status;
-        }
-        state_ = EntryDecoderState::kStartDecodingValue;
-        ABSL_FALLTHROUGH_INTENDED;
-
-      case EntryDecoderState::kStartDecodingValue:
-        HTTP2_DVLOG(1) << "kStartDecodingValue: db->Remaining="
-                       << db->Remaining();
-        {
-          ValueDecoderListener vcb(listener);
-          status = string_decoder_.Start(db, &vcb);
-        }
-        if (status == DecodeStatus::kDecodeError) {
-          HTTP2_CODE_COUNT_N(decompress_failure_3, 14, 23);
-          error_ = HpackDecodingError::kValueLengthVarintError;
-        }
-        if (status == DecodeStatus::kDecodeDone) {
-          // Done with decoding the literal value, so we've reached the
-          // end of the header entry.
-          return status;
-        }
-        // On the assumption that the status is kDecodeInProgress, set
-        // state_ accordingly; unnecessary if status is kDecodeError, but
-        // that will only happen if the varint encoding the value's length
-        // is too long.
-        state_ = EntryDecoderState::kResumeDecodingValue;
-        return status;
-
-      case EntryDecoderState::kResumeDecodingName:
-        // The literal name was split across decode buffers.
-        HTTP2_DVLOG(1) << "kResumeDecodingName: db->Remaining="
-                       << db->Remaining();
-        {
-          NameDecoderListener ncb(listener);
-          status = string_decoder_.Resume(db, &ncb);
-        }
-        if (status != DecodeStatus::kDecodeDone) {
-          // On the assumption that the status is kDecodeInProgress, set
-          // state_ accordingly; unnecessary if status is kDecodeError, but
-          // that will only happen if the varint encoding the name's length
-          // is too long.
-          state_ = EntryDecoderState::kResumeDecodingName;
-          if (status == DecodeStatus::kDecodeError) {
-            HTTP2_CODE_COUNT_N(decompress_failure_3, 15, 23);
-            error_ = HpackDecodingError::kNameLengthVarintError;
-          }
-          return status;
-        }
-        state_ = EntryDecoderState::kStartDecodingValue;
-        break;
-
-      case EntryDecoderState::kResumeDecodingValue:
-        // The literal value was split across decode buffers.
-        HTTP2_DVLOG(1) << "kResumeDecodingValue: db->Remaining="
-                       << db->Remaining();
-        {
-          ValueDecoderListener vcb(listener);
-          status = string_decoder_.Resume(db, &vcb);
-        }
-        if (status == DecodeStatus::kDecodeError) {
-          HTTP2_CODE_COUNT_N(decompress_failure_3, 16, 23);
-          error_ = HpackDecodingError::kValueLengthVarintError;
-        }
-        if (status == DecodeStatus::kDecodeDone) {
-          // Done with decoding the value, therefore the entry as a whole.
-          return status;
-        }
-        // On the assumption that the status is kDecodeInProgress, set
-        // state_ accordingly; unnecessary if status is kDecodeError, but
-        // that will only happen if the varint encoding the value's length
-        // is too long.
-        state_ = EntryDecoderState::kResumeDecodingValue;
-        return status;
-    }
-  } while (true);
-}
-
-bool HpackEntryDecoder::DispatchOnType(HpackEntryDecoderListener* listener) {
-  const HpackEntryType entry_type = entry_type_decoder_.entry_type();
-  const uint32_t varint = static_cast<uint32_t>(entry_type_decoder_.varint());
-  switch (entry_type) {
-    case HpackEntryType::kIndexedHeader:
-      // The entry consists solely of the entry type and varint. See:
-      // http://httpwg.org/specs/rfc7541.html#indexed.header.representation
-      listener->OnIndexedHeader(varint);
-      return true;
-
-    case HpackEntryType::kIndexedLiteralHeader:
-    case HpackEntryType::kUnindexedLiteralHeader:
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      // The entry has a literal value, and if the varint is zero also has a
-      // literal name preceding the value. See:
-      // http://httpwg.org/specs/rfc7541.html#literal.header.representation
-      listener->OnStartLiteralHeader(entry_type, varint);
-      if (varint == 0) {
-        state_ = EntryDecoderState::kStartDecodingName;
-      } else {
-        state_ = EntryDecoderState::kStartDecodingValue;
-      }
-      return false;
-
-    case HpackEntryType::kDynamicTableSizeUpdate:
-      // The entry consists solely of the entry type and varint. FWIW, I've
-      // never seen this type of entry in production (primarily browser
-      // traffic) so if you're designing an HPACK successor someday, consider
-      // dropping it or giving it a much longer prefix. See:
-      // http://httpwg.org/specs/rfc7541.html#encoding.context.update
-      listener->OnDynamicTableSizeUpdate(varint);
-      return true;
-  }
-
-  HTTP2_BUG(http2_bug_63_2) << "Unreachable, entry_type=" << entry_type;
-  return true;
-}
-
-void HpackEntryDecoder::OutputDebugString(std::ostream& out) const {
-  out << "HpackEntryDecoder(state=" << state_ << ", " << entry_type_decoder_
-      << ", " << string_decoder_ << ")";
-}
-
-std::string HpackEntryDecoder::DebugString() const {
-  std::stringstream s;
-  s << *this;
-  return s.str();
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackEntryDecoder& v) {
-  v.OutputDebugString(out);
-  return out;
-}
-
-std::ostream& operator<<(std::ostream& out,
-                         HpackEntryDecoder::EntryDecoderState state) {
-  typedef HpackEntryDecoder::EntryDecoderState EntryDecoderState;
-  switch (state) {
-    case EntryDecoderState::kResumeDecodingType:
-      return out << "kResumeDecodingType";
-    case EntryDecoderState::kDecodedType:
-      return out << "kDecodedType";
-    case EntryDecoderState::kStartDecodingName:
-      return out << "kStartDecodingName";
-    case EntryDecoderState::kResumeDecodingName:
-      return out << "kResumeDecodingName";
-    case EntryDecoderState::kStartDecodingValue:
-      return out << "kStartDecodingValue";
-    case EntryDecoderState::kResumeDecodingValue:
-      return out << "kResumeDecodingValue";
-  }
-  return out << static_cast<int>(state);
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_entry_decoder.h b/http2/hpack/decoder/hpack_entry_decoder.h
deleted file mode 100644
index 256e7c2..0000000
--- a/http2/hpack/decoder/hpack_entry_decoder.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
-
-// HpackEntryDecoder decodes a single HPACK entry (i.e. one header or one
-// dynamic table size update), in a resumable fashion. The first call, Start(),
-// must provide a non-empty decode buffer. Continue with calls to Resume() if
-// Start, and any subsequent calls to Resume, returns kDecodeInProgress.
-
-#include <string>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-#include "http2/hpack/decoder/hpack_entry_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_entry_type_decoder.h"
-#include "http2/hpack/decoder/hpack_string_decoder.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackEntryDecoder {
- public:
-  enum class EntryDecoderState {
-    // Have started decoding the type/varint, but didn't finish on the previous
-    // attempt.  Next state is kResumeDecodingType or kDecodedType.
-    kResumeDecodingType,
-
-    // Have just finished decoding the type/varint. Final state if the type is
-    // kIndexedHeader or kDynamicTableSizeUpdate. Otherwise, the next state is
-    // kStartDecodingName (if the varint is 0), else kStartDecodingValue.
-    kDecodedType,
-
-    // Ready to start decoding the literal name of a header entry. Next state
-    // is kResumeDecodingName (if the name is split across decode buffers),
-    // else kStartDecodingValue.
-    kStartDecodingName,
-
-    // Resume decoding the literal name of a header that is split across decode
-    // buffers.
-    kResumeDecodingName,
-
-    // Ready to start decoding the literal value of a header entry. Final state
-    // if the value string is entirely in the decode buffer, else the next state
-    // is kResumeDecodingValue.
-    kStartDecodingValue,
-
-    // Resume decoding the literal value of a header that is split across decode
-    // buffers.
-    kResumeDecodingValue,
-  };
-
-  // Only call when the decode buffer has data (i.e. HpackBlockDecoder must
-  // not call until there is data).
-  DecodeStatus Start(DecodeBuffer* db, HpackEntryDecoderListener* listener);
-
-  // Only call Resume if the previous call (Start or Resume) returned
-  // kDecodeInProgress; Resume is also called from Start when it has succeeded
-  // in decoding the entry type and its varint.
-  DecodeStatus Resume(DecodeBuffer* db, HpackEntryDecoderListener* listener);
-
-  // Return error code after decoding error occurred.
-  HpackDecodingError error() const { return error_; }
-
-  std::string DebugString() const;
-  void OutputDebugString(std::ostream& out) const;
-
- private:
-  // Implements handling state kDecodedType.
-  bool DispatchOnType(HpackEntryDecoderListener* listener);
-
-  HpackEntryTypeDecoder entry_type_decoder_;
-  HpackStringDecoder string_decoder_;
-  EntryDecoderState state_ = EntryDecoderState();
-  HpackDecodingError error_ = HpackDecodingError::kOk;
-};
-
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const HpackEntryDecoder& v);
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& out,
-    HpackEntryDecoder::EntryDecoderState state);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
diff --git a/http2/hpack/decoder/hpack_entry_decoder_listener.cc b/http2/hpack/decoder/hpack_entry_decoder_listener.cc
deleted file mode 100644
index 994ffb3..0000000
--- a/http2/hpack/decoder/hpack_entry_decoder_listener.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_entry_decoder_listener.h"
-
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-void HpackEntryDecoderVLoggingListener::OnIndexedHeader(size_t index) {
-  HTTP2_VLOG(1) << "OnIndexedHeader, index=" << index;
-  if (wrapped_) {
-    wrapped_->OnIndexedHeader(index);
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnStartLiteralHeader(
-    HpackEntryType entry_type,
-    size_t maybe_name_index) {
-  HTTP2_VLOG(1) << "OnStartLiteralHeader: entry_type=" << entry_type
-                << ", maybe_name_index=" << maybe_name_index;
-  if (wrapped_) {
-    wrapped_->OnStartLiteralHeader(entry_type, maybe_name_index);
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnNameStart(bool huffman_encoded,
-                                                    size_t len) {
-  HTTP2_VLOG(1) << "OnNameStart: H=" << huffman_encoded << ", len=" << len;
-  if (wrapped_) {
-    wrapped_->OnNameStart(huffman_encoded, len);
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnNameData(const char* data,
-                                                   size_t len) {
-  HTTP2_VLOG(1) << "OnNameData: len=" << len;
-  if (wrapped_) {
-    wrapped_->OnNameData(data, len);
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnNameEnd() {
-  HTTP2_VLOG(1) << "OnNameEnd";
-  if (wrapped_) {
-    wrapped_->OnNameEnd();
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnValueStart(bool huffman_encoded,
-                                                     size_t len) {
-  HTTP2_VLOG(1) << "OnValueStart: H=" << huffman_encoded << ", len=" << len;
-  if (wrapped_) {
-    wrapped_->OnValueStart(huffman_encoded, len);
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnValueData(const char* data,
-                                                    size_t len) {
-  HTTP2_VLOG(1) << "OnValueData: len=" << len;
-  if (wrapped_) {
-    wrapped_->OnValueData(data, len);
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnValueEnd() {
-  HTTP2_VLOG(1) << "OnValueEnd";
-  if (wrapped_) {
-    wrapped_->OnValueEnd();
-  }
-}
-
-void HpackEntryDecoderVLoggingListener::OnDynamicTableSizeUpdate(size_t size) {
-  HTTP2_VLOG(1) << "OnDynamicTableSizeUpdate: size=" << size;
-  if (wrapped_) {
-    wrapped_->OnDynamicTableSizeUpdate(size);
-  }
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_entry_decoder_listener.h b/http2/hpack/decoder/hpack_entry_decoder_listener.h
deleted file mode 100644
index 062a003..0000000
--- a/http2/hpack/decoder/hpack_entry_decoder_listener.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_LISTENER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_LISTENER_H_
-
-// Defines HpackEntryDecoderListener, the base class of listeners that
-// HpackEntryDecoder calls. Also defines HpackEntryDecoderVLoggingListener
-// which logs before calling another HpackEntryDecoderListener implementation.
-
-#include <stddef.h>
-
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackEntryDecoderListener {
- public:
-  virtual ~HpackEntryDecoderListener() {}
-
-  // Called when an indexed header (i.e. one in the static or dynamic table) has
-  // been decoded from an HPACK block. index is supposed to be non-zero, but
-  // that has not been checked by the caller.
-  virtual void OnIndexedHeader(size_t index) = 0;
-
-  // Called when the start of a header with a literal value, and maybe a literal
-  // name, has been decoded. maybe_name_index is zero if the header has a
-  // literal name, else it is a reference into the static or dynamic table, from
-  // which the name should be determined. When the name is literal, the next
-  // call will be to OnNameStart; else it will be to OnValueStart. entry_type
-  // indicates whether the peer has added the entry to its dynamic table, and
-  // whether a proxy is permitted to do so when forwarding the entry.
-  virtual void OnStartLiteralHeader(HpackEntryType entry_type,
-                                    size_t maybe_name_index) = 0;
-
-  // Called when the encoding (Huffman compressed or plain text) and the encoded
-  // length of a literal name has been decoded. OnNameData will be called next,
-  // and repeatedly until the sum of lengths passed to OnNameData is len.
-  virtual void OnNameStart(bool huffman_encoded, size_t len) = 0;
-
-  // Called when len bytes of an encoded header name have been decoded.
-  virtual void OnNameData(const char* data, size_t len) = 0;
-
-  // Called after the entire name has been passed to OnNameData.
-  // OnValueStart will be called next.
-  virtual void OnNameEnd() = 0;
-
-  // Called when the encoding (Huffman compressed or plain text) and the encoded
-  // length of a literal value has been decoded. OnValueData will be called
-  // next, and repeatedly until the sum of lengths passed to OnValueData is len.
-  virtual void OnValueStart(bool huffman_encoded, size_t len) = 0;
-
-  // Called when len bytes of an encoded header value have been decoded.
-  virtual void OnValueData(const char* data, size_t len) = 0;
-
-  // Called after the entire value has been passed to OnValueData, marking the
-  // end of a header entry with a literal value, and maybe a literal name.
-  virtual void OnValueEnd() = 0;
-
-  // Called when an update to the size of the peer's dynamic table has been
-  // decoded.
-  virtual void OnDynamicTableSizeUpdate(size_t size) = 0;
-};
-
-class QUICHE_EXPORT_PRIVATE HpackEntryDecoderVLoggingListener
-    : public HpackEntryDecoderListener {
- public:
-  HpackEntryDecoderVLoggingListener() : wrapped_(nullptr) {}
-  explicit HpackEntryDecoderVLoggingListener(HpackEntryDecoderListener* wrapped)
-      : wrapped_(wrapped) {}
-  ~HpackEntryDecoderVLoggingListener() override {}
-
-  void OnIndexedHeader(size_t index) override;
-  void OnStartLiteralHeader(HpackEntryType entry_type,
-                            size_t maybe_name_index) override;
-  void OnNameStart(bool huffman_encoded, size_t len) override;
-  void OnNameData(const char* data, size_t len) override;
-  void OnNameEnd() override;
-  void OnValueStart(bool huffman_encoded, size_t len) override;
-  void OnValueData(const char* data, size_t len) override;
-  void OnValueEnd() override;
-  void OnDynamicTableSizeUpdate(size_t size) override;
-
- private:
-  HpackEntryDecoderListener* const wrapped_;
-};
-
-// A no-op implementation of HpackEntryDecoderListener.
-class QUICHE_EXPORT_PRIVATE HpackEntryDecoderNoOpListener
-    : public HpackEntryDecoderListener {
- public:
-  ~HpackEntryDecoderNoOpListener() override {}
-
-  void OnIndexedHeader(size_t /*index*/) override {}
-  void OnStartLiteralHeader(HpackEntryType /*entry_type*/,
-                            size_t /*maybe_name_index*/) override {}
-  void OnNameStart(bool /*huffman_encoded*/, size_t /*len*/) override {}
-  void OnNameData(const char* /*data*/, size_t /*len*/) override {}
-  void OnNameEnd() override {}
-  void OnValueStart(bool /*huffman_encoded*/, size_t /*len*/) override {}
-  void OnValueData(const char* /*data*/, size_t /*len*/) override {}
-  void OnValueEnd() override {}
-  void OnDynamicTableSizeUpdate(size_t /*size*/) override {}
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_LISTENER_H_
diff --git a/http2/hpack/decoder/hpack_entry_decoder_test.cc b/http2/hpack/decoder/hpack_entry_decoder_test.cc
deleted file mode 100644
index 32eeaf4..0000000
--- a/http2/hpack/decoder/hpack_entry_decoder_test.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_entry_decoder.h"
-
-// Tests of HpackEntryDecoder.
-
-#include <cstdint>
-
-#include "http2/hpack/decoder/hpack_entry_collector.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-class HpackEntryDecoderTest : public RandomDecoderTest {
- protected:
-  HpackEntryDecoderTest() : listener_(&collector_) {}
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    collector_.Clear();
-    return decoder_.Start(b, &listener_);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    return decoder_.Resume(b, &listener_);
-  }
-
-  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* db,
-                                               const Validator& validator) {
-    // StartDecoding, above, requires the DecodeBuffer be non-empty so that it
-    // can call Start with the prefix byte.
-    bool return_non_zero_on_first = true;
-    return RandomDecoderTest::DecodeAndValidateSeveralWays(
-        db, return_non_zero_on_first, validator);
-  }
-
-  AssertionResult DecodeAndValidateSeveralWays(const HpackBlockBuilder& hbb,
-                                               const Validator& validator) {
-    DecodeBuffer db(hbb.buffer());
-    return DecodeAndValidateSeveralWays(&db, validator);
-  }
-
-  HpackEntryDecoder decoder_;
-  HpackEntryCollector collector_;
-  HpackEntryDecoderVLoggingListener listener_;
-};
-
-TEST_F(HpackEntryDecoderTest, IndexedHeader_Literals) {
-  {
-    const char input[] = {'\x82'};  // == Index 2 ==
-    DecodeBuffer b(input);
-    auto do_check = [this]() {
-      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(2));
-    };
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
-    EXPECT_TRUE(do_check());
-  }
-  collector_.Clear();
-  {
-    const char input[] = {'\xfe'};  // == Index 126 ==
-    DecodeBuffer b(input);
-    auto do_check = [this]() {
-      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(126));
-    };
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
-    EXPECT_TRUE(do_check());
-  }
-  collector_.Clear();
-  {
-    const char input[] = {'\xff', '\x00'};  // == Index 127 ==
-    DecodeBuffer b(input);
-    auto do_check = [this]() {
-      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(127));
-    };
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
-    EXPECT_TRUE(do_check());
-  }
-}
-
-TEST_F(HpackEntryDecoderTest, IndexedHeader_Various) {
-  // Indices chosen to hit encoding and table boundaries.
-  for (const uint32_t ndx : {1, 2, 61, 62, 63, 126, 127, 254, 255, 256}) {
-    HpackBlockBuilder hbb;
-    hbb.AppendIndexedHeader(ndx);
-
-    auto do_check = [this, ndx]() {
-      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(ndx));
-    };
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
-    EXPECT_TRUE(do_check());
-  }
-}
-
-TEST_F(HpackEntryDecoderTest, IndexedLiteralValue_Literal) {
-  const char input[] =
-      "\x7f"            // == Literal indexed, name index 0x40 ==
-      "\x01"            // 2nd byte of name index (0x01 + 0x3f == 0x40)
-      "\x0d"            // Value length (13)
-      "custom-header";  // Value
-  DecodeBuffer b(input, sizeof input - 1);
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralValueHeader(
-        HpackEntryType::kIndexedLiteralHeader, 0x40, false, "custom-header"));
-  };
-  EXPECT_TRUE(DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-TEST_F(HpackEntryDecoderTest, IndexedLiteralNameValue_Literal) {
-  const char input[] =
-      "\x40"            // == Literal indexed ==
-      "\x0a"            // Name length (10)
-      "custom-key"      // Name
-      "\x0d"            // Value length (13)
-      "custom-header";  // Value
-
-  DecodeBuffer b(input, sizeof input - 1);
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralNameValueHeader(
-        HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false,
-        "custom-header"));
-  };
-  EXPECT_TRUE(DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-TEST_F(HpackEntryDecoderTest, DynamicTableSizeUpdate_Literal) {
-  // Size update, length 31.
-  const char input[] = "\x3f\x00";
-  DecodeBuffer b(input, 2);
-  auto do_check = [this]() {
-    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateDynamicTableSizeUpdate(31));
-  };
-  EXPECT_TRUE(DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
-  EXPECT_TRUE(do_check());
-}
-
-class HpackLiteralEntryDecoderTest
-    : public HpackEntryDecoderTest,
-      public ::testing::WithParamInterface<HpackEntryType> {
- protected:
-  HpackLiteralEntryDecoderTest() : entry_type_(GetParam()) {}
-
-  const HpackEntryType entry_type_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    AllLiteralTypes, HpackLiteralEntryDecoderTest,
-    testing::Values(HpackEntryType::kIndexedLiteralHeader,
-                    HpackEntryType::kUnindexedLiteralHeader,
-                    HpackEntryType::kNeverIndexedLiteralHeader));
-
-TEST_P(HpackLiteralEntryDecoderTest, RandNameIndexAndLiteralValue) {
-  for (int n = 0; n < 10; n++) {
-    const uint32_t ndx = 1 + Random().Rand8();
-    const bool value_is_huffman_encoded = (n % 2) == 0;
-    const std::string value = Random().RandString(Random().Rand8());
-    HpackBlockBuilder hbb;
-    hbb.AppendNameIndexAndLiteralValue(entry_type_, ndx,
-                                       value_is_huffman_encoded, value);
-    auto do_check = [this, ndx, value_is_huffman_encoded,
-                     value]() -> AssertionResult {
-      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralValueHeader(
-          entry_type_, ndx, value_is_huffman_encoded, value));
-    };
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
-    EXPECT_TRUE(do_check());
-  }
-}
-
-TEST_P(HpackLiteralEntryDecoderTest, RandLiteralNameAndValue) {
-  for (int n = 0; n < 10; n++) {
-    const bool name_is_huffman_encoded = (n & 1) == 0;
-    const int name_len = 1 + Random().Rand8();
-    const std::string name = Random().RandString(name_len);
-    const bool value_is_huffman_encoded = (n & 2) == 0;
-    const int value_len = Random().Skewed(10);
-    const std::string value = Random().RandString(value_len);
-    HpackBlockBuilder hbb;
-    hbb.AppendLiteralNameAndValue(entry_type_, name_is_huffman_encoded, name,
-                                  value_is_huffman_encoded, value);
-    auto do_check = [this, name_is_huffman_encoded, name,
-                     value_is_huffman_encoded, value]() -> AssertionResult {
-      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralNameValueHeader(
-          entry_type_, name_is_huffman_encoded, name, value_is_huffman_encoded,
-          value));
-    };
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
-    EXPECT_TRUE(do_check());
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_entry_type_decoder.cc b/http2/hpack/decoder/hpack_entry_type_decoder.cc
deleted file mode 100644
index bdfaddc..0000000
--- a/http2/hpack/decoder/hpack_entry_type_decoder.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_entry_type_decoder.h"
-
-#include "absl/strings/str_cat.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_flags.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::string HpackEntryTypeDecoder::DebugString() const {
-  return absl::StrCat(
-      "HpackEntryTypeDecoder(varint_decoder=", varint_decoder_.DebugString(),
-      ", entry_type=", entry_type_, ")");
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackEntryTypeDecoder& v) {
-  return out << v.DebugString();
-}
-
-// This ridiculous looking function turned out to be the winner in benchmarking
-// of several very different alternative implementations. It would be even
-// faster (~7%) if inlined in the header file, but I'm not sure if that is
-// worth doing... yet.
-// TODO(jamessynge): Benchmark again at a higher level (e.g. at least at the
-// full HTTP/2 decoder level, but preferably still higher) to determine if the
-// alternatives that take less code/data space are preferable in that situation.
-DecodeStatus HpackEntryTypeDecoder::Start(DecodeBuffer* db) {
-  QUICHE_DCHECK(db != nullptr);
-  QUICHE_DCHECK(db->HasData());
-
-  // The high four bits (nibble) of first byte of the entry determine the type
-  // of the entry, and may also be the initial bits of the varint that
-  // represents an index or table size. Note the use of the word 'initial'
-  // rather than 'high'; the HPACK encoding of varints is not in network
-  // order (i.e. not big-endian, the high-order byte isn't first), nor in
-  // little-endian order. See:
-  // http://httpwg.org/specs/rfc7541.html#integer.representation
-  uint8_t byte = db->DecodeUInt8();
-  switch (byte) {
-    case 0b00000000:
-    case 0b00000001:
-    case 0b00000010:
-    case 0b00000011:
-    case 0b00000100:
-    case 0b00000101:
-    case 0b00000110:
-    case 0b00000111:
-    case 0b00001000:
-    case 0b00001001:
-    case 0b00001010:
-    case 0b00001011:
-    case 0b00001100:
-    case 0b00001101:
-    case 0b00001110:
-      // The low 4 bits of |byte| are the initial bits of the varint.
-      // One of those bits is 0, so the varint is only one byte long.
-      entry_type_ = HpackEntryType::kUnindexedLiteralHeader;
-      varint_decoder_.set_value(byte);
-      return DecodeStatus::kDecodeDone;
-
-    case 0b00001111:
-      // The low 4 bits of |byte| are the initial bits of the varint. All 4
-      // are 1, so the varint extends into another byte.
-      entry_type_ = HpackEntryType::kUnindexedLiteralHeader;
-      return varint_decoder_.StartExtended(4, db);
-
-    case 0b00010000:
-    case 0b00010001:
-    case 0b00010010:
-    case 0b00010011:
-    case 0b00010100:
-    case 0b00010101:
-    case 0b00010110:
-    case 0b00010111:
-    case 0b00011000:
-    case 0b00011001:
-    case 0b00011010:
-    case 0b00011011:
-    case 0b00011100:
-    case 0b00011101:
-    case 0b00011110:
-      // The low 4 bits of |byte| are the initial bits of the varint.
-      // One of those bits is 0, so the varint is only one byte long.
-      entry_type_ = HpackEntryType::kNeverIndexedLiteralHeader;
-      varint_decoder_.set_value(byte & 0x0f);
-      return DecodeStatus::kDecodeDone;
-
-    case 0b00011111:
-      // The low 4 bits of |byte| are the initial bits of the varint.
-      // All of those bits are 1, so the varint extends into another byte.
-      entry_type_ = HpackEntryType::kNeverIndexedLiteralHeader;
-      return varint_decoder_.StartExtended(4, db);
-
-    case 0b00100000:
-    case 0b00100001:
-    case 0b00100010:
-    case 0b00100011:
-    case 0b00100100:
-    case 0b00100101:
-    case 0b00100110:
-    case 0b00100111:
-    case 0b00101000:
-    case 0b00101001:
-    case 0b00101010:
-    case 0b00101011:
-    case 0b00101100:
-    case 0b00101101:
-    case 0b00101110:
-    case 0b00101111:
-    case 0b00110000:
-    case 0b00110001:
-    case 0b00110010:
-    case 0b00110011:
-    case 0b00110100:
-    case 0b00110101:
-    case 0b00110110:
-    case 0b00110111:
-    case 0b00111000:
-    case 0b00111001:
-    case 0b00111010:
-    case 0b00111011:
-    case 0b00111100:
-    case 0b00111101:
-    case 0b00111110:
-      entry_type_ = HpackEntryType::kDynamicTableSizeUpdate;
-      // The low 5 bits of |byte| are the initial bits of the varint.
-      // One of those bits is 0, so the varint is only one byte long.
-      varint_decoder_.set_value(byte & 0x01f);
-      return DecodeStatus::kDecodeDone;
-
-    case 0b00111111:
-      entry_type_ = HpackEntryType::kDynamicTableSizeUpdate;
-      // The low 5 bits of |byte| are the initial bits of the varint.
-      // All of those bits are 1, so the varint extends into another byte.
-      return varint_decoder_.StartExtended(5, db);
-
-    case 0b01000000:
-    case 0b01000001:
-    case 0b01000010:
-    case 0b01000011:
-    case 0b01000100:
-    case 0b01000101:
-    case 0b01000110:
-    case 0b01000111:
-    case 0b01001000:
-    case 0b01001001:
-    case 0b01001010:
-    case 0b01001011:
-    case 0b01001100:
-    case 0b01001101:
-    case 0b01001110:
-    case 0b01001111:
-    case 0b01010000:
-    case 0b01010001:
-    case 0b01010010:
-    case 0b01010011:
-    case 0b01010100:
-    case 0b01010101:
-    case 0b01010110:
-    case 0b01010111:
-    case 0b01011000:
-    case 0b01011001:
-    case 0b01011010:
-    case 0b01011011:
-    case 0b01011100:
-    case 0b01011101:
-    case 0b01011110:
-    case 0b01011111:
-    case 0b01100000:
-    case 0b01100001:
-    case 0b01100010:
-    case 0b01100011:
-    case 0b01100100:
-    case 0b01100101:
-    case 0b01100110:
-    case 0b01100111:
-    case 0b01101000:
-    case 0b01101001:
-    case 0b01101010:
-    case 0b01101011:
-    case 0b01101100:
-    case 0b01101101:
-    case 0b01101110:
-    case 0b01101111:
-    case 0b01110000:
-    case 0b01110001:
-    case 0b01110010:
-    case 0b01110011:
-    case 0b01110100:
-    case 0b01110101:
-    case 0b01110110:
-    case 0b01110111:
-    case 0b01111000:
-    case 0b01111001:
-    case 0b01111010:
-    case 0b01111011:
-    case 0b01111100:
-    case 0b01111101:
-    case 0b01111110:
-      entry_type_ = HpackEntryType::kIndexedLiteralHeader;
-      // The low 6 bits of |byte| are the initial bits of the varint.
-      // One of those bits is 0, so the varint is only one byte long.
-      varint_decoder_.set_value(byte & 0x03f);
-      return DecodeStatus::kDecodeDone;
-
-    case 0b01111111:
-      entry_type_ = HpackEntryType::kIndexedLiteralHeader;
-      // The low 6 bits of |byte| are the initial bits of the varint.
-      // All of those bits are 1, so the varint extends into another byte.
-      return varint_decoder_.StartExtended(6, db);
-
-    case 0b10000000:
-    case 0b10000001:
-    case 0b10000010:
-    case 0b10000011:
-    case 0b10000100:
-    case 0b10000101:
-    case 0b10000110:
-    case 0b10000111:
-    case 0b10001000:
-    case 0b10001001:
-    case 0b10001010:
-    case 0b10001011:
-    case 0b10001100:
-    case 0b10001101:
-    case 0b10001110:
-    case 0b10001111:
-    case 0b10010000:
-    case 0b10010001:
-    case 0b10010010:
-    case 0b10010011:
-    case 0b10010100:
-    case 0b10010101:
-    case 0b10010110:
-    case 0b10010111:
-    case 0b10011000:
-    case 0b10011001:
-    case 0b10011010:
-    case 0b10011011:
-    case 0b10011100:
-    case 0b10011101:
-    case 0b10011110:
-    case 0b10011111:
-    case 0b10100000:
-    case 0b10100001:
-    case 0b10100010:
-    case 0b10100011:
-    case 0b10100100:
-    case 0b10100101:
-    case 0b10100110:
-    case 0b10100111:
-    case 0b10101000:
-    case 0b10101001:
-    case 0b10101010:
-    case 0b10101011:
-    case 0b10101100:
-    case 0b10101101:
-    case 0b10101110:
-    case 0b10101111:
-    case 0b10110000:
-    case 0b10110001:
-    case 0b10110010:
-    case 0b10110011:
-    case 0b10110100:
-    case 0b10110101:
-    case 0b10110110:
-    case 0b10110111:
-    case 0b10111000:
-    case 0b10111001:
-    case 0b10111010:
-    case 0b10111011:
-    case 0b10111100:
-    case 0b10111101:
-    case 0b10111110:
-    case 0b10111111:
-    case 0b11000000:
-    case 0b11000001:
-    case 0b11000010:
-    case 0b11000011:
-    case 0b11000100:
-    case 0b11000101:
-    case 0b11000110:
-    case 0b11000111:
-    case 0b11001000:
-    case 0b11001001:
-    case 0b11001010:
-    case 0b11001011:
-    case 0b11001100:
-    case 0b11001101:
-    case 0b11001110:
-    case 0b11001111:
-    case 0b11010000:
-    case 0b11010001:
-    case 0b11010010:
-    case 0b11010011:
-    case 0b11010100:
-    case 0b11010101:
-    case 0b11010110:
-    case 0b11010111:
-    case 0b11011000:
-    case 0b11011001:
-    case 0b11011010:
-    case 0b11011011:
-    case 0b11011100:
-    case 0b11011101:
-    case 0b11011110:
-    case 0b11011111:
-    case 0b11100000:
-    case 0b11100001:
-    case 0b11100010:
-    case 0b11100011:
-    case 0b11100100:
-    case 0b11100101:
-    case 0b11100110:
-    case 0b11100111:
-    case 0b11101000:
-    case 0b11101001:
-    case 0b11101010:
-    case 0b11101011:
-    case 0b11101100:
-    case 0b11101101:
-    case 0b11101110:
-    case 0b11101111:
-    case 0b11110000:
-    case 0b11110001:
-    case 0b11110010:
-    case 0b11110011:
-    case 0b11110100:
-    case 0b11110101:
-    case 0b11110110:
-    case 0b11110111:
-    case 0b11111000:
-    case 0b11111001:
-    case 0b11111010:
-    case 0b11111011:
-    case 0b11111100:
-    case 0b11111101:
-    case 0b11111110:
-      entry_type_ = HpackEntryType::kIndexedHeader;
-      // The low 7 bits of |byte| are the initial bits of the varint.
-      // One of those bits is 0, so the varint is only one byte long.
-      varint_decoder_.set_value(byte & 0x07f);
-      return DecodeStatus::kDecodeDone;
-
-    case 0b11111111:
-      entry_type_ = HpackEntryType::kIndexedHeader;
-      // The low 7 bits of |byte| are the initial bits of the varint.
-      // All of those bits are 1, so the varint extends into another byte.
-      return varint_decoder_.StartExtended(7, db);
-  }
-  HTTP2_BUG(http2_bug_66_1)
-      << "Unreachable, byte=" << std::hex << static_cast<uint32_t>(byte);
-  HTTP2_CODE_COUNT_N(decompress_failure_3, 17, 23);
-  return DecodeStatus::kDecodeError;
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_entry_type_decoder.h b/http2/hpack/decoder/hpack_entry_type_decoder.h
deleted file mode 100644
index dac0823..0000000
--- a/http2/hpack/decoder/hpack_entry_type_decoder.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_TYPE_DECODER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_TYPE_DECODER_H_
-
-// Decodes the type of an HPACK entry, and the variable length integer whose
-// prefix is in the low-order bits of the same byte, "below" the type bits.
-// The integer represents an index into static or dynamic table, which may be
-// zero, or is the new size limit of the dynamic table.
-
-#include <cstdint>
-#include <string>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackEntryTypeDecoder {
- public:
-  // Only call when the decode buffer has data (i.e. HpackEntryDecoder must
-  // not call until there is data).
-  DecodeStatus Start(DecodeBuffer* db);
-
-  // Only call Resume if the previous call (Start or Resume) returned
-  // DecodeStatus::kDecodeInProgress.
-  DecodeStatus Resume(DecodeBuffer* db) { return varint_decoder_.Resume(db); }
-
-  // Returns the decoded entry type. Only call if the preceding call to Start
-  // or Resume returned kDecodeDone.
-  HpackEntryType entry_type() const { return entry_type_; }
-
-  // Returns the decoded variable length integer. Only call if the
-  // preceding call to Start or Resume returned kDecodeDone.
-  uint64_t varint() const { return varint_decoder_.value(); }
-
-  std::string DebugString() const;
-
- private:
-  HpackVarintDecoder varint_decoder_;
-
-  // This field is initialized just to keep ASAN happy about reading it
-  // from DebugString().
-  HpackEntryType entry_type_ = HpackEntryType::kIndexedHeader;
-};
-
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const HpackEntryTypeDecoder& v);
-
-}  // namespace http2
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_TYPE_DECODER_H_
diff --git a/http2/hpack/decoder/hpack_entry_type_decoder_test.cc b/http2/hpack/decoder/hpack_entry_type_decoder_test.cc
deleted file mode 100644
index 8babd80..0000000
--- a/http2/hpack/decoder/hpack_entry_type_decoder_test.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_entry_type_decoder.h"
-
-#include <vector>
-
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-namespace {
-const bool kReturnNonZeroOnFirst = true;
-
-class HpackEntryTypeDecoderTest : public RandomDecoderTest {
- protected:
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    QUICHE_CHECK_LT(0u, b->Remaining());
-    return decoder_.Start(b);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    return decoder_.Resume(b);
-  }
-
-  HpackEntryTypeDecoder decoder_;
-};
-
-TEST_F(HpackEntryTypeDecoderTest, DynamicTableSizeUpdate) {
-  for (uint32_t size = 0; size < 1000 * 1000; size += 256) {
-    HpackBlockBuilder bb;
-    bb.AppendDynamicTableSizeUpdate(size);
-    DecodeBuffer db(bb.buffer());
-    auto validator = [size, this]() -> AssertionResult {
-      VERIFY_EQ(HpackEntryType::kDynamicTableSizeUpdate, decoder_.entry_type());
-      VERIFY_EQ(size, decoder_.varint());
-      return AssertionSuccess();
-    };
-    EXPECT_TRUE(DecodeAndValidateSeveralWays(&db, kReturnNonZeroOnFirst,
-                                             ValidateDoneAndEmpty(validator)))
-        << "\nentry_type=kDynamicTableSizeUpdate, size=" << size;
-    // Run the validator again to make sure that DecodeAndValidateSeveralWays
-    // did the right thing.
-    EXPECT_TRUE(validator());
-  }
-}
-
-TEST_F(HpackEntryTypeDecoderTest, HeaderWithIndex) {
-  std::vector<HpackEntryType> entry_types = {
-      HpackEntryType::kIndexedHeader,
-      HpackEntryType::kIndexedLiteralHeader,
-      HpackEntryType::kUnindexedLiteralHeader,
-      HpackEntryType::kNeverIndexedLiteralHeader,
-  };
-  for (const HpackEntryType entry_type : entry_types) {
-    const uint32_t first = entry_type == HpackEntryType::kIndexedHeader ? 1 : 0;
-    for (uint32_t index = first; index < 1000; ++index) {
-      HpackBlockBuilder bb;
-      bb.AppendEntryTypeAndVarint(entry_type, index);
-      DecodeBuffer db(bb.buffer());
-      auto validator = [entry_type, index, this]() -> AssertionResult {
-        VERIFY_EQ(entry_type, decoder_.entry_type());
-        VERIFY_EQ(index, decoder_.varint());
-        return AssertionSuccess();
-      };
-      EXPECT_TRUE(DecodeAndValidateSeveralWays(&db, kReturnNonZeroOnFirst,
-                                               ValidateDoneAndEmpty(validator)))
-          << "\nentry_type=" << entry_type << ", index=" << index;
-      // Run the validator again to make sure that DecodeAndValidateSeveralWays
-      // did the right thing.
-      EXPECT_TRUE(validator());
-    }
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_string_collector.cc b/http2/hpack/decoder/hpack_string_collector.cc
deleted file mode 100644
index eeed643..0000000
--- a/http2/hpack/decoder/hpack_string_collector.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_string_collector.h"
-
-#include <stddef.h>
-
-#include <iosfwd>
-#include <ostream>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-std::ostream& operator<<(std::ostream& out,
-                         HpackStringCollector::CollectorState v) {
-  switch (v) {
-    case HpackStringCollector::CollectorState::kGenesis:
-      return out << "kGenesis";
-    case HpackStringCollector::CollectorState::kStarted:
-      return out << "kStarted";
-    case HpackStringCollector::CollectorState::kEnded:
-      return out << "kEnded";
-  }
-  return out << "UnknownCollectorState";
-}
-
-}  // namespace
-
-HpackStringCollector::HpackStringCollector() {
-  Clear();
-}
-
-HpackStringCollector::HpackStringCollector(const std::string& str, bool huffman)
-    : s(str), len(str.size()), huffman_encoded(huffman), state(kEnded) {}
-
-void HpackStringCollector::Clear() {
-  s = "";
-  len = 0;
-  huffman_encoded = false;
-  state = kGenesis;
-}
-
-bool HpackStringCollector::IsClear() const {
-  return s.empty() && len == 0 && huffman_encoded == false && state == kGenesis;
-}
-
-bool HpackStringCollector::IsInProgress() const {
-  return state == kStarted;
-}
-
-bool HpackStringCollector::HasEnded() const {
-  return state == kEnded;
-}
-
-void HpackStringCollector::OnStringStart(bool huffman, size_t length) {
-  EXPECT_TRUE(IsClear()) << ToString();
-  state = kStarted;
-  huffman_encoded = huffman;
-  len = length;
-}
-
-void HpackStringCollector::OnStringData(const char* data, size_t length) {
-  absl::string_view sp(data, length);
-  EXPECT_TRUE(IsInProgress()) << ToString();
-  EXPECT_LE(sp.size(), len) << ToString();
-  absl::StrAppend(&s, sp);
-  EXPECT_LE(s.size(), len) << ToString();
-}
-
-void HpackStringCollector::OnStringEnd() {
-  EXPECT_TRUE(IsInProgress()) << ToString();
-  EXPECT_EQ(s.size(), len) << ToString();
-  state = kEnded;
-}
-
-::testing::AssertionResult HpackStringCollector::Collected(
-    absl::string_view str,
-    bool is_huffman_encoded) const {
-  VERIFY_TRUE(HasEnded());
-  VERIFY_EQ(str.size(), len);
-  VERIFY_EQ(is_huffman_encoded, huffman_encoded);
-  VERIFY_EQ(str, s);
-  return ::testing::AssertionSuccess();
-}
-
-std::string HpackStringCollector::ToString() const {
-  std::stringstream ss;
-  ss << *this;
-  return ss.str();
-}
-
-bool operator==(const HpackStringCollector& a, const HpackStringCollector& b) {
-  return a.s == b.s && a.len == b.len &&
-         a.huffman_encoded == b.huffman_encoded && a.state == b.state;
-}
-
-bool operator!=(const HpackStringCollector& a, const HpackStringCollector& b) {
-  return !(a == b);
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackStringCollector& v) {
-  out << "HpackStringCollector(state=" << v.state;
-  if (v.state == HpackStringCollector::kGenesis) {
-    return out << ")";
-  }
-  if (v.huffman_encoded) {
-    out << ", Huffman Encoded";
-  }
-  out << ", Length=" << v.len;
-  if (!v.s.empty() && v.len != v.s.size()) {
-    out << " (" << v.s.size() << ")";
-  }
-  return out << ", String=\"" << absl::CHexEscape(v.s) << "\")";
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_string_collector.h b/http2/hpack/decoder/hpack_string_collector.h
deleted file mode 100644
index 3ec6560..0000000
--- a/http2/hpack/decoder/hpack_string_collector.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_COLLECTOR_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_COLLECTOR_H_
-
-// Supports tests of decoding HPACK strings.
-
-#include <stddef.h>
-
-#include <iosfwd>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_string_decoder_listener.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-// Records the callbacks associated with a decoding a string; must
-// call Clear() between decoding successive strings.
-struct HpackStringCollector : public HpackStringDecoderListener {
-  enum CollectorState {
-    kGenesis,
-    kStarted,
-    kEnded,
-  };
-
-  HpackStringCollector();
-  HpackStringCollector(const std::string& str, bool huffman);
-
-  void Clear();
-  bool IsClear() const;
-  bool IsInProgress() const;
-  bool HasEnded() const;
-
-  void OnStringStart(bool huffman, size_t length) override;
-  void OnStringData(const char* data, size_t length) override;
-  void OnStringEnd() override;
-
-  ::testing::AssertionResult Collected(absl::string_view str,
-                                       bool is_huffman_encoded) const;
-
-  std::string ToString() const;
-
-  std::string s;
-  size_t len;
-  bool huffman_encoded;
-  CollectorState state;
-};
-
-bool operator==(const HpackStringCollector& a, const HpackStringCollector& b);
-
-bool operator!=(const HpackStringCollector& a, const HpackStringCollector& b);
-
-std::ostream& operator<<(std::ostream& out, const HpackStringCollector& v);
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_COLLECTOR_H_
diff --git a/http2/hpack/decoder/hpack_string_decoder.cc b/http2/hpack/decoder/hpack_string_decoder.cc
deleted file mode 100644
index 90da300..0000000
--- a/http2/hpack/decoder/hpack_string_decoder.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_string_decoder.h"
-
-#include "absl/strings/str_cat.h"
-
-namespace http2 {
-
-std::string HpackStringDecoder::DebugString() const {
-  return absl::StrCat("HpackStringDecoder(state=", StateToString(state_),
-                      ", length=", length_decoder_.DebugString(),
-                      ", remaining=", remaining_,
-                      ", huffman=", huffman_encoded_ ? "true)" : "false)");
-}
-
-// static
-std::string HpackStringDecoder::StateToString(StringDecoderState v) {
-  switch (v) {
-    case kStartDecodingLength:
-      return "kStartDecodingLength";
-    case kDecodingString:
-      return "kDecodingString";
-    case kResumeDecodingLength:
-      return "kResumeDecodingLength";
-  }
-  return absl::StrCat("UNKNOWN_STATE(", static_cast<uint32_t>(v), ")");
-}
-
-std::ostream& operator<<(std::ostream& out, const HpackStringDecoder& v) {
-  return out << v.DebugString();
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_string_decoder.h b/http2/hpack/decoder/hpack_string_decoder.h
deleted file mode 100644
index 9cddc67..0000000
--- a/http2/hpack/decoder/hpack_string_decoder.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_H_
-
-// HpackStringDecoder decodes strings encoded per the HPACK spec; this does
-// not mean decompressing Huffman encoded strings, just identifying the length,
-// encoding and contents for a listener.
-
-#include <stddef.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// Decodes a single string in an HPACK header entry. The high order bit of
-// the first byte of the length is the H (Huffman) bit indicating whether
-// the value is Huffman encoded, and the remainder of the byte is the first
-// 7 bits of an HPACK varint.
-//
-// Call Start() to begin decoding; if it returns kDecodeInProgress, then call
-// Resume() when more input is available, repeating until kDecodeInProgress is
-// not returned. If kDecodeDone or kDecodeError is returned, then Resume() must
-// not be called until Start() has been called to start decoding a new string.
-class QUICHE_EXPORT_PRIVATE HpackStringDecoder {
- public:
-  enum StringDecoderState {
-    kStartDecodingLength,
-    kDecodingString,
-    kResumeDecodingLength,
-  };
-
-  template <class Listener>
-  DecodeStatus Start(DecodeBuffer* db, Listener* cb) {
-    // Fast decode path is used if the string is under 127 bytes and the
-    // entire length of the string is in the decode buffer. More than 83% of
-    // string lengths are encoded in just one byte.
-    if (db->HasData() && (*db->cursor() & 0x7f) != 0x7f) {
-      // The string is short.
-      uint8_t h_and_prefix = db->DecodeUInt8();
-      uint8_t length = h_and_prefix & 0x7f;
-      bool huffman_encoded = (h_and_prefix & 0x80) == 0x80;
-      cb->OnStringStart(huffman_encoded, length);
-      if (length <= db->Remaining()) {
-        // Yeah, we've got the whole thing in the decode buffer.
-        // Ideally this will be the common case. Note that we don't
-        // update any of the member variables in this path.
-        cb->OnStringData(db->cursor(), length);
-        db->AdvanceCursor(length);
-        cb->OnStringEnd();
-        return DecodeStatus::kDecodeDone;
-      }
-      // Not all in the buffer.
-      huffman_encoded_ = huffman_encoded;
-      remaining_ = length;
-      // Call Resume to decode the string body, which is only partially
-      // in the decode buffer (or not at all).
-      state_ = kDecodingString;
-      return Resume(db, cb);
-    }
-    // Call Resume to decode the string length, which is either not in
-    // the decode buffer, or spans multiple bytes.
-    state_ = kStartDecodingLength;
-    return Resume(db, cb);
-  }
-
-  template <class Listener>
-  DecodeStatus Resume(DecodeBuffer* db, Listener* cb) {
-    DecodeStatus status;
-    while (true) {
-      switch (state_) {
-        case kStartDecodingLength:
-          HTTP2_DVLOG(2) << "kStartDecodingLength: db->Remaining="
-                         << db->Remaining();
-          if (!StartDecodingLength(db, cb, &status)) {
-            // The length is split across decode buffers.
-            return status;
-          }
-          // We've finished decoding the length, which spanned one or more
-          // bytes. Approximately 17% of strings have a length that is greater
-          // than 126 bytes, and thus the length is encoded in more than one
-          // byte, and so doesn't get the benefit of the optimization in
-          // Start() for single byte lengths. But, we still expect that most
-          // of such strings will be contained entirely in a single decode
-          // buffer, and hence this fall through skips another trip through the
-          // switch above and more importantly skips setting the state_ variable
-          // again in those cases where we don't need it.
-          ABSL_FALLTHROUGH_INTENDED;
-
-        case kDecodingString:
-          HTTP2_DVLOG(2) << "kDecodingString: db->Remaining=" << db->Remaining()
-                         << "    remaining_=" << remaining_;
-          return DecodeString(db, cb);
-
-        case kResumeDecodingLength:
-          HTTP2_DVLOG(2) << "kResumeDecodingLength: db->Remaining="
-                         << db->Remaining();
-          if (!ResumeDecodingLength(db, cb, &status)) {
-            return status;
-          }
-      }
-    }
-  }
-
-  std::string DebugString() const;
-
- private:
-  static std::string StateToString(StringDecoderState v);
-
-  // Returns true if the length is fully decoded and the listener wants the
-  // decoding to continue, false otherwise; status is set to the status from
-  // the varint decoder.
-  // If the length is not fully decoded, case state_ is set appropriately
-  // for the next call to Resume.
-  template <class Listener>
-  bool StartDecodingLength(DecodeBuffer* db,
-                           Listener* cb,
-                           DecodeStatus* status) {
-    if (db->Empty()) {
-      *status = DecodeStatus::kDecodeInProgress;
-      state_ = kStartDecodingLength;
-      return false;
-    }
-    uint8_t h_and_prefix = db->DecodeUInt8();
-    huffman_encoded_ = (h_and_prefix & 0x80) == 0x80;
-    *status = length_decoder_.Start(h_and_prefix, 7, db);
-    if (*status == DecodeStatus::kDecodeDone) {
-      OnStringStart(cb, status);
-      return true;
-    }
-    // Set the state to cover the DecodeStatus::kDecodeInProgress case.
-    // Won't be needed if the status is kDecodeError.
-    state_ = kResumeDecodingLength;
-    return false;
-  }
-
-  // Returns true if the length is fully decoded and the listener wants the
-  // decoding to continue, false otherwise; status is set to the status from
-  // the varint decoder; state_ is updated when fully decoded.
-  // If the length is not fully decoded, case state_ is set appropriately
-  // for the next call to Resume.
-  template <class Listener>
-  bool ResumeDecodingLength(DecodeBuffer* db,
-                            Listener* cb,
-                            DecodeStatus* status) {
-    QUICHE_DCHECK_EQ(state_, kResumeDecodingLength);
-    *status = length_decoder_.Resume(db);
-    if (*status == DecodeStatus::kDecodeDone) {
-      state_ = kDecodingString;
-      OnStringStart(cb, status);
-      return true;
-    }
-    return false;
-  }
-
-  // Returns true if the listener wants the decoding to continue, and
-  // false otherwise, in which case status set.
-  template <class Listener>
-  void OnStringStart(Listener* cb, DecodeStatus* /*status*/) {
-    // TODO(vasilvv): fail explicitly in case of truncation.
-    remaining_ = static_cast<size_t>(length_decoder_.value());
-    // Make callback so consumer knows what is coming.
-    cb->OnStringStart(huffman_encoded_, remaining_);
-  }
-
-  // Passes the available portion of the string to the listener, and signals
-  // the end of the string when it is reached. Returns kDecodeDone or
-  // kDecodeInProgress as appropriate.
-  template <class Listener>
-  DecodeStatus DecodeString(DecodeBuffer* db, Listener* cb) {
-    size_t len = std::min(remaining_, db->Remaining());
-    if (len > 0) {
-      cb->OnStringData(db->cursor(), len);
-      db->AdvanceCursor(len);
-      remaining_ -= len;
-    }
-    if (remaining_ == 0) {
-      cb->OnStringEnd();
-      return DecodeStatus::kDecodeDone;
-    }
-    state_ = kDecodingString;
-    return DecodeStatus::kDecodeInProgress;
-  }
-
-  HpackVarintDecoder length_decoder_;
-
-  // These fields are initialized just to keep ASAN happy about reading
-  // them from DebugString().
-  size_t remaining_ = 0;
-  StringDecoderState state_ = kStartDecodingLength;
-  bool huffman_encoded_ = false;
-};
-
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const HpackStringDecoder& v);
-
-}  // namespace http2
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_H_
diff --git a/http2/hpack/decoder/hpack_string_decoder_listener.cc b/http2/hpack/decoder/hpack_string_decoder_listener.cc
deleted file mode 100644
index 73db24f..0000000
--- a/http2/hpack/decoder/hpack_string_decoder_listener.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_string_decoder_listener.h"
-
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-namespace test {
-
-void HpackStringDecoderVLoggingListener::OnStringStart(bool huffman_encoded,
-                                                       size_t len) {
-  HTTP2_VLOG(1) << "OnStringStart: H=" << huffman_encoded << ", len=" << len;
-  if (wrapped_) {
-    wrapped_->OnStringStart(huffman_encoded, len);
-  }
-}
-
-void HpackStringDecoderVLoggingListener::OnStringData(const char* data,
-                                                      size_t len) {
-  HTTP2_VLOG(1) << "OnStringData: len=" << len;
-  if (wrapped_) {
-    return wrapped_->OnStringData(data, len);
-  }
-}
-
-void HpackStringDecoderVLoggingListener::OnStringEnd() {
-  HTTP2_VLOG(1) << "OnStringEnd";
-  if (wrapped_) {
-    return wrapped_->OnStringEnd();
-  }
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_string_decoder_listener.h b/http2/hpack/decoder/hpack_string_decoder_listener.h
deleted file mode 100644
index 25b7eea..0000000
--- a/http2/hpack/decoder/hpack_string_decoder_listener.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_LISTENER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_LISTENER_H_
-
-// Defines HpackStringDecoderListener which defines the methods required by an
-// HpackStringDecoder. Also defines HpackStringDecoderVLoggingListener which
-// logs before calling another HpackStringDecoderListener implementation.
-// For now these are only used by tests, so placed in the test namespace.
-
-#include <stddef.h>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-namespace test {
-
-// HpackStringDecoder methods require a listener that implements the methods
-// below, but it is NOT necessary to extend this class because the methods
-// are templates.
-class QUICHE_EXPORT_PRIVATE HpackStringDecoderListener {
- public:
-  virtual ~HpackStringDecoderListener() {}
-
-  // Called at the start of decoding an HPACK string. The encoded length of the
-  // string is |len| bytes, which may be zero. The string is Huffman encoded
-  // if huffman_encoded is true, else it is plain text (i.e. the encoded length
-  // is then the plain text length).
-  virtual void OnStringStart(bool huffman_encoded, size_t len) = 0;
-
-  // Called when some data is available, or once when the string length is zero
-  // (to simplify the decoder, it doesn't have a special case for len==0).
-  virtual void OnStringData(const char* data, size_t len) = 0;
-
-  // Called after OnStringData has provided all of the encoded bytes of the
-  // string.
-  virtual void OnStringEnd() = 0;
-};
-
-class QUICHE_EXPORT_PRIVATE HpackStringDecoderVLoggingListener
-    : public HpackStringDecoderListener {
- public:
-  HpackStringDecoderVLoggingListener() : wrapped_(nullptr) {}
-  explicit HpackStringDecoderVLoggingListener(
-      HpackStringDecoderListener* wrapped)
-      : wrapped_(wrapped) {}
-  ~HpackStringDecoderVLoggingListener() override {}
-
-  void OnStringStart(bool huffman_encoded, size_t len) override;
-  void OnStringData(const char* data, size_t len) override;
-  void OnStringEnd() override;
-
- private:
-  HpackStringDecoderListener* const wrapped_;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_LISTENER_H_
diff --git a/http2/hpack/decoder/hpack_string_decoder_test.cc b/http2/hpack/decoder/hpack_string_decoder_test.cc
deleted file mode 100644
index 6ff332f..0000000
--- a/http2/hpack/decoder/hpack_string_decoder_test.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_string_decoder.h"
-
-// Tests of HpackStringDecoder.
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_string_collector.h"
-#include "http2/hpack/decoder/hpack_string_decoder_listener.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-const bool kMayReturnZeroOnFirst = false;
-const bool kCompressed = true;
-const bool kUncompressed = false;
-
-class HpackStringDecoderTest : public RandomDecoderTest {
- protected:
-  HpackStringDecoderTest() : listener_(&collector_) {}
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    ++start_decoding_calls_;
-    collector_.Clear();
-    return decoder_.Start(b, &listener_);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    // Provides coverage of DebugString and StateToString.
-    // Not validating output.
-    HTTP2_VLOG(1) << decoder_.DebugString();
-    HTTP2_VLOG(2) << collector_;
-    return decoder_.Resume(b, &listener_);
-  }
-
-  AssertionResult Collected(absl::string_view s, bool huffman_encoded) {
-    HTTP2_VLOG(1) << collector_;
-    return collector_.Collected(s, huffman_encoded);
-  }
-
-  // expected_str is a std::string rather than a const std::string& or
-  // absl::string_view so that the lambda makes a copy of the string, and thus
-  // the string to be passed to Collected outlives the call to MakeValidator.
-  Validator MakeValidator(const std::string& expected_str,
-                          bool expected_huffman) {
-    return
-        [expected_str, expected_huffman, this](
-            const DecodeBuffer& /*input*/,
-            DecodeStatus /*status*/) -> AssertionResult {
-          AssertionResult result = Collected(expected_str, expected_huffman);
-          if (result) {
-            VERIFY_EQ(collector_,
-                      HpackStringCollector(expected_str, expected_huffman));
-          } else {
-            VERIFY_NE(collector_,
-                      HpackStringCollector(expected_str, expected_huffman));
-          }
-          HTTP2_VLOG(2) << collector_.ToString();
-          collector_.Clear();
-          HTTP2_VLOG(2) << collector_;
-          return result;
-        };
-  }
-
-  HpackStringDecoder decoder_;
-  HpackStringCollector collector_;
-  HpackStringDecoderVLoggingListener listener_;
-  size_t start_decoding_calls_ = 0;
-};
-
-TEST_F(HpackStringDecoderTest, DecodeEmptyString) {
-  {
-    Validator validator = ValidateDoneAndEmpty(MakeValidator("", kCompressed));
-    const char kData[] = {'\x80'};
-    DecodeBuffer b(kData);
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
-  }
-  {
-    // Make sure it stops after decoding the empty string.
-    Validator validator =
-        ValidateDoneAndOffset(1, MakeValidator("", kUncompressed));
-    const char kData[] = {'\x00', '\xff'};
-    DecodeBuffer b(kData);
-    EXPECT_EQ(2u, b.Remaining());
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
-    EXPECT_EQ(1u, b.Remaining());
-  }
-}
-
-TEST_F(HpackStringDecoderTest, DecodeShortString) {
-  {
-    // Make sure it stops after decoding the non-empty string.
-    Validator validator =
-        ValidateDoneAndOffset(11, MakeValidator("start end.", kCompressed));
-    const char kData[] = "\x8astart end.Don't peek at this.";
-    DecodeBuffer b(kData);
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
-  }
-  {
-    Validator validator =
-        ValidateDoneAndOffset(11, MakeValidator("start end.", kUncompressed));
-    absl::string_view data("\x0astart end.");
-    DecodeBuffer b(data);
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
-  }
-}
-
-TEST_F(HpackStringDecoderTest, DecodeLongStrings) {
-  std::string name = Random().RandString(1024);
-  std::string value = Random().RandString(65536);
-  HpackBlockBuilder hbb;
-
-  hbb.AppendString(false, name);
-  uint32_t offset_after_name = hbb.size();
-  EXPECT_EQ(3 + name.size(), offset_after_name);
-
-  hbb.AppendString(true, value);
-  uint32_t offset_after_value = hbb.size();
-  EXPECT_EQ(3 + name.size() + 4 + value.size(), offset_after_value);
-
-  DecodeBuffer b(hbb.buffer());
-
-  // Decode the name...
-  EXPECT_TRUE(DecodeAndValidateSeveralWays(
-      &b, kMayReturnZeroOnFirst,
-      ValidateDoneAndOffset(offset_after_name,
-                            MakeValidator(name, kUncompressed))));
-  EXPECT_EQ(offset_after_name, b.Offset());
-  EXPECT_EQ(offset_after_value - offset_after_name, b.Remaining());
-
-  // Decode the value...
-  EXPECT_TRUE(DecodeAndValidateSeveralWays(
-      &b, kMayReturnZeroOnFirst,
-      ValidateDoneAndOffset(offset_after_value - offset_after_name,
-                            MakeValidator(value, kCompressed))));
-  EXPECT_EQ(offset_after_value, b.Offset());
-  EXPECT_EQ(0u, b.Remaining());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/http2/hpack/decoder/hpack_whole_entry_buffer.cc
deleted file mode 100644
index 1752ba5..0000000
--- a/http2/hpack/decoder/hpack_whole_entry_buffer.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_whole_entry_buffer.h"
-
-#include "absl/strings/str_cat.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_flags.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_text_utils.h"
-
-namespace http2 {
-
-HpackWholeEntryBuffer::HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
-                                             size_t max_string_size_bytes)
-    : max_string_size_bytes_(max_string_size_bytes) {
-  set_listener(listener);
-}
-HpackWholeEntryBuffer::~HpackWholeEntryBuffer() = default;
-
-void HpackWholeEntryBuffer::set_listener(HpackWholeEntryListener* listener) {
-  QUICHE_CHECK(listener);
-  listener_ = listener;
-}
-
-void HpackWholeEntryBuffer::set_max_string_size_bytes(
-    size_t max_string_size_bytes) {
-  max_string_size_bytes_ = max_string_size_bytes;
-}
-
-void HpackWholeEntryBuffer::BufferStringsIfUnbuffered() {
-  name_.BufferStringIfUnbuffered();
-  value_.BufferStringIfUnbuffered();
-}
-
-void HpackWholeEntryBuffer::OnIndexedHeader(size_t index) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnIndexedHeader: index=" << index;
-  listener_->OnIndexedHeader(index);
-}
-
-void HpackWholeEntryBuffer::OnStartLiteralHeader(HpackEntryType entry_type,
-                                                 size_t maybe_name_index) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnStartLiteralHeader: entry_type="
-                 << entry_type << ",  maybe_name_index=" << maybe_name_index;
-  entry_type_ = entry_type;
-  maybe_name_index_ = maybe_name_index;
-}
-
-void HpackWholeEntryBuffer::OnNameStart(bool huffman_encoded, size_t len) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameStart: huffman_encoded="
-                 << (huffman_encoded ? "true" : "false") << ",  len=" << len;
-  QUICHE_DCHECK_EQ(maybe_name_index_, 0u);
-  if (!error_detected_) {
-    if (len > max_string_size_bytes_) {
-      HTTP2_DVLOG(1) << "Name length (" << len << ") is longer than permitted ("
-                     << max_string_size_bytes_ << ")";
-      ReportError(HpackDecodingError::kNameTooLong, "");
-      HTTP2_CODE_COUNT_N(decompress_failure_3, 18, 23);
-      return;
-    }
-    name_.OnStart(huffman_encoded, len);
-  }
-}
-
-void HpackWholeEntryBuffer::OnNameData(const char* data, size_t len) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameData: len=" << len
-                 << " data:\n"
-                 << quiche::QuicheTextUtils::HexDump(
-                        absl::string_view(data, len));
-  QUICHE_DCHECK_EQ(maybe_name_index_, 0u);
-  if (!error_detected_ && !name_.OnData(data, len)) {
-    ReportError(HpackDecodingError::kNameHuffmanError, "");
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 19, 23);
-  }
-}
-
-void HpackWholeEntryBuffer::OnNameEnd() {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameEnd";
-  QUICHE_DCHECK_EQ(maybe_name_index_, 0u);
-  if (!error_detected_ && !name_.OnEnd()) {
-    ReportError(HpackDecodingError::kNameHuffmanError, "");
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 20, 23);
-  }
-}
-
-void HpackWholeEntryBuffer::OnValueStart(bool huffman_encoded, size_t len) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueStart: huffman_encoded="
-                 << (huffman_encoded ? "true" : "false") << ",  len=" << len;
-  if (!error_detected_) {
-    if (len > max_string_size_bytes_) {
-      std::string detailed_error = absl::StrCat(
-          "Value length (", len, ") of [", name_.GetStringIfComplete(),
-          "] is longer than permitted (", max_string_size_bytes_, ")");
-      HTTP2_DVLOG(1) << detailed_error;
-      ReportError(HpackDecodingError::kValueTooLong, detailed_error);
-      HTTP2_CODE_COUNT_N(decompress_failure_3, 21, 23);
-      return;
-    }
-    value_.OnStart(huffman_encoded, len);
-  }
-}
-
-void HpackWholeEntryBuffer::OnValueData(const char* data, size_t len) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueData: len=" << len
-                 << " data:\n"
-                 << quiche::QuicheTextUtils::HexDump(
-                        absl::string_view(data, len));
-  if (!error_detected_ && !value_.OnData(data, len)) {
-    ReportError(HpackDecodingError::kValueHuffmanError, "");
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 22, 23);
-  }
-}
-
-void HpackWholeEntryBuffer::OnValueEnd() {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueEnd";
-  if (error_detected_) {
-    return;
-  }
-  if (!value_.OnEnd()) {
-    ReportError(HpackDecodingError::kValueHuffmanError, "");
-    HTTP2_CODE_COUNT_N(decompress_failure_3, 23, 23);
-    return;
-  }
-  if (maybe_name_index_ == 0) {
-    listener_->OnLiteralNameAndValue(entry_type_, &name_, &value_);
-    name_.Reset();
-  } else {
-    listener_->OnNameIndexAndLiteralValue(entry_type_, maybe_name_index_,
-                                          &value_);
-  }
-  value_.Reset();
-}
-
-void HpackWholeEntryBuffer::OnDynamicTableSizeUpdate(size_t size) {
-  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnDynamicTableSizeUpdate: size="
-                 << size;
-  listener_->OnDynamicTableSizeUpdate(size);
-}
-
-void HpackWholeEntryBuffer::ReportError(HpackDecodingError error,
-                                        std::string detailed_error) {
-  if (!error_detected_) {
-    HTTP2_DVLOG(1) << "HpackWholeEntryBuffer::ReportError: "
-                   << HpackDecodingErrorToString(error);
-    error_detected_ = true;
-    listener_->OnHpackDecodeError(error, detailed_error);
-    listener_ = HpackWholeEntryNoOpListener::NoOpListener();
-  }
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_whole_entry_buffer.h b/http2/hpack/decoder/hpack_whole_entry_buffer.h
deleted file mode 100644
index 0cce0ba..0000000
--- a/http2/hpack/decoder/hpack_whole_entry_buffer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
-
-// HpackWholeEntryBuffer isolates a listener from the fact that an entry may
-// be split across multiple input buffers, providing one callback per entry.
-// HpackWholeEntryBuffer requires that the HpackEntryDecoderListener be made in
-// the correct order, which is tested by hpack_entry_decoder_test.cc.
-
-#include <stddef.h>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_decoder_string_buffer.h"
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-#include "http2/hpack/decoder/hpack_entry_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_whole_entry_listener.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// TODO(jamessynge): Consider renaming HpackEntryDecoderListener to
-// HpackEntryPartsListener or HpackEntryFragmentsListener.
-class QUICHE_EXPORT_PRIVATE HpackWholeEntryBuffer
-    : public HpackEntryDecoderListener {
- public:
-  // max_string_size specifies the maximum size of an on-the-wire string (name
-  // or value, plain or Huffman encoded) that will be accepted. See sections
-  // 5.1 and 5.2 of RFC 7541. This is a defense against OOM attacks; HTTP/2
-  // allows a decoder to enforce any limit of the size of the header lists
-  // that it is willing decode, including less than the MAX_HEADER_LIST_SIZE
-  // setting, a setting that is initially unlimited. For example, we might
-  // choose to send a MAX_HEADER_LIST_SIZE of 64KB, and to use that same value
-  // as the upper bound for individual strings.
-  HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
-                        size_t max_string_size);
-  ~HpackWholeEntryBuffer() override;
-
-  HpackWholeEntryBuffer(const HpackWholeEntryBuffer&) = delete;
-  HpackWholeEntryBuffer& operator=(const HpackWholeEntryBuffer&) = delete;
-
-  // Set the listener to be notified when a whole entry has been decoded.
-  // The listener may be changed at any time.
-  void set_listener(HpackWholeEntryListener* listener);
-
-  // Set how much encoded data this decoder is willing to buffer.
-  // TODO(jamessynge): Come up with consistent semantics for this protection
-  // across the various decoders; e.g. should it be for a single string or
-  // a single header entry?
-  void set_max_string_size_bytes(size_t max_string_size_bytes);
-
-  // Ensure that decoded strings pointed to by the HpackDecoderStringBuffer
-  // instances name_ and value_ are buffered, which allows any underlying
-  // transport buffer to be freed or reused without overwriting the decoded
-  // strings. This is needed only when an HPACK entry is split across transport
-  // buffers. See HpackDecoder::DecodeFragment.
-  void BufferStringsIfUnbuffered();
-
-  // Was an error detected? After an error has been detected and reported,
-  // no further callbacks will be made to the listener.
-  bool error_detected() const { return error_detected_; }
-
-  // Implement the HpackEntryDecoderListener methods.
-
-  void OnIndexedHeader(size_t index) override;
-  void OnStartLiteralHeader(HpackEntryType entry_type,
-                            size_t maybe_name_index) override;
-  void OnNameStart(bool huffman_encoded, size_t len) override;
-  void OnNameData(const char* data, size_t len) override;
-  void OnNameEnd() override;
-  void OnValueStart(bool huffman_encoded, size_t len) override;
-  void OnValueData(const char* data, size_t len) override;
-  void OnValueEnd() override;
-  void OnDynamicTableSizeUpdate(size_t size) override;
-
- private:
-  void ReportError(HpackDecodingError error, std::string detailed_error);
-
-  HpackWholeEntryListener* listener_;
-  HpackDecoderStringBuffer name_, value_;
-
-  // max_string_size_bytes_ specifies the maximum allowed size of an on-the-wire
-  // string. Larger strings will be reported as errors to the listener; the
-  // endpoint should treat these as COMPRESSION errors, which are CONNECTION
-  // level errors.
-  size_t max_string_size_bytes_;
-
-  // The name index (or zero) of the current header entry with a literal value.
-  size_t maybe_name_index_;
-
-  // The type of the current header entry (with literals) that is being decoded.
-  HpackEntryType entry_type_;
-
-  bool error_detected_ = false;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
diff --git a/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc b/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
deleted file mode 100644
index 6f41481..0000000
--- a/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_whole_entry_buffer.h"
-
-// Tests of HpackWholeEntryBuffer: does it buffer correctly, and does it
-// detect Huffman decoding errors and oversize string errors?
-
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::_;
-using ::testing::AllOf;
-using ::testing::InSequence;
-using ::testing::Property;
-using ::testing::StrictMock;
-
-namespace http2 {
-namespace test {
-namespace {
-
-constexpr size_t kMaxStringSize = 20;
-
-class MockHpackWholeEntryListener : public HpackWholeEntryListener {
- public:
-  ~MockHpackWholeEntryListener() override = default;
-
-  MOCK_METHOD(void, OnIndexedHeader, (size_t index), (override));
-  MOCK_METHOD(void,
-              OnNameIndexAndLiteralValue,
-              (HpackEntryType entry_type,
-               size_t name_index,
-               HpackDecoderStringBuffer* value_buffer),
-              (override));
-  MOCK_METHOD(void,
-              OnLiteralNameAndValue,
-              (HpackEntryType entry_type,
-               HpackDecoderStringBuffer* name_buffer,
-               HpackDecoderStringBuffer* value_buffer),
-              (override));
-  MOCK_METHOD(void, OnDynamicTableSizeUpdate, (size_t size), (override));
-  MOCK_METHOD(void,
-              OnHpackDecodeError,
-              (HpackDecodingError error, std::string detailed_error),
-              (override));
-};
-
-class HpackWholeEntryBufferTest : public QuicheTest {
- protected:
-  HpackWholeEntryBufferTest() : entry_buffer_(&listener_, kMaxStringSize) {}
-  ~HpackWholeEntryBufferTest() override = default;
-
-  StrictMock<MockHpackWholeEntryListener> listener_;
-  HpackWholeEntryBuffer entry_buffer_;
-};
-
-// OnIndexedHeader is an immediate pass through.
-TEST_F(HpackWholeEntryBufferTest, OnIndexedHeader) {
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnIndexedHeader(17));
-    entry_buffer_.OnIndexedHeader(17);
-  }
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnIndexedHeader(62));
-    entry_buffer_.OnIndexedHeader(62);
-  }
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnIndexedHeader(62));
-    entry_buffer_.OnIndexedHeader(62);
-  }
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnIndexedHeader(128));
-    entry_buffer_.OnIndexedHeader(128);
-  }
-  StrictMock<MockHpackWholeEntryListener> listener2;
-  entry_buffer_.set_listener(&listener2);
-  {
-    InSequence seq;
-    EXPECT_CALL(listener2, OnIndexedHeader(100));
-    entry_buffer_.OnIndexedHeader(100);
-  }
-}
-
-// OnDynamicTableSizeUpdate is an immediate pass through.
-TEST_F(HpackWholeEntryBufferTest, OnDynamicTableSizeUpdate) {
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(4096));
-    entry_buffer_.OnDynamicTableSizeUpdate(4096);
-  }
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(0));
-    entry_buffer_.OnDynamicTableSizeUpdate(0);
-  }
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(1024));
-    entry_buffer_.OnDynamicTableSizeUpdate(1024);
-  }
-  {
-    InSequence seq;
-    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(1024));
-    entry_buffer_.OnDynamicTableSizeUpdate(1024);
-  }
-  StrictMock<MockHpackWholeEntryListener> listener2;
-  entry_buffer_.set_listener(&listener2);
-  {
-    InSequence seq;
-    EXPECT_CALL(listener2, OnDynamicTableSizeUpdate(0));
-    entry_buffer_.OnDynamicTableSizeUpdate(0);
-  }
-}
-
-TEST_F(HpackWholeEntryBufferTest, OnNameIndexAndLiteralValue) {
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kNeverIndexedLiteralHeader,
-                                     123);
-  entry_buffer_.OnValueStart(false, 10);
-  entry_buffer_.OnValueData("some data.", 10);
-
-  // Force the value to be buffered.
-  entry_buffer_.BufferStringsIfUnbuffered();
-
-  EXPECT_CALL(
-      listener_,
-      OnNameIndexAndLiteralValue(
-          HpackEntryType::kNeverIndexedLiteralHeader, 123,
-          AllOf(Property(&HpackDecoderStringBuffer::str, "some data."),
-                Property(&HpackDecoderStringBuffer::BufferedLength, 10))));
-
-  entry_buffer_.OnValueEnd();
-}
-
-TEST_F(HpackWholeEntryBufferTest, OnLiteralNameAndValue) {
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
-  // Force the name to be buffered by delivering it in two pieces.
-  entry_buffer_.OnNameStart(false, 9);
-  entry_buffer_.OnNameData("some-", 5);
-  entry_buffer_.OnNameData("name", 4);
-  entry_buffer_.OnNameEnd();
-  entry_buffer_.OnValueStart(false, 12);
-  entry_buffer_.OnValueData("Header Value", 12);
-
-  EXPECT_CALL(
-      listener_,
-      OnLiteralNameAndValue(
-          HpackEntryType::kIndexedLiteralHeader,
-          AllOf(Property(&HpackDecoderStringBuffer::str, "some-name"),
-                Property(&HpackDecoderStringBuffer::BufferedLength, 9)),
-          AllOf(Property(&HpackDecoderStringBuffer::str, "Header Value"),
-                Property(&HpackDecoderStringBuffer::BufferedLength, 0))));
-
-  entry_buffer_.OnValueEnd();
-}
-
-// Verify that a name longer than the allowed size generates an error.
-TEST_F(HpackWholeEntryBufferTest, NameTooLong) {
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
-  EXPECT_CALL(listener_,
-              OnHpackDecodeError(HpackDecodingError::kNameTooLong, _));
-  entry_buffer_.OnNameStart(false, kMaxStringSize + 1);
-}
-
-// Verify that a value longer than the allowed size generates an error.
-TEST_F(HpackWholeEntryBufferTest, ValueTooLong) {
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
-  EXPECT_CALL(listener_,
-              OnHpackDecodeError(
-                  HpackDecodingError::kValueTooLong,
-                  "Value length (21) of [path] is longer than permitted (20)"));
-  entry_buffer_.OnNameStart(false, 4);
-  entry_buffer_.OnNameData("path", 4);
-  entry_buffer_.OnNameEnd();
-  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
-}
-
-// Regression test for b/162141899.
-TEST_F(HpackWholeEntryBufferTest, ValueTooLongWithoutName) {
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 1);
-  EXPECT_CALL(listener_,
-              OnHpackDecodeError(
-                  HpackDecodingError::kValueTooLong,
-                  "Value length (21) of [] is longer than permitted (20)"));
-  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
-}
-
-// Verify that a Huffman encoded name with an explicit EOS generates an error
-// for an explicit EOS.
-TEST_F(HpackWholeEntryBufferTest, NameHuffmanError) {
-  const char data[] = "\xff\xff\xff";
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kUnindexedLiteralHeader,
-                                     0);
-  entry_buffer_.OnNameStart(true, 4);
-  entry_buffer_.OnNameData(data, 3);
-
-  EXPECT_CALL(listener_,
-              OnHpackDecodeError(HpackDecodingError::kNameHuffmanError, _));
-
-  entry_buffer_.OnNameData(data, 1);
-
-  // After an error is reported, the listener is not called again.
-  EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(8096)).Times(0);
-  entry_buffer_.OnDynamicTableSizeUpdate(8096);
-}
-
-// Verify that a Huffman encoded value that isn't properly terminated with
-// a partial EOS symbol generates an error.
-TEST_F(HpackWholeEntryBufferTest, ValueHuffmanError) {
-  const char data[] = "\x00\x00\x00";
-  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kNeverIndexedLiteralHeader,
-                                     61);
-  entry_buffer_.OnValueStart(true, 3);
-  entry_buffer_.OnValueData(data, 3);
-
-  EXPECT_CALL(listener_,
-              OnHpackDecodeError(HpackDecodingError::kValueHuffmanError, _));
-
-  entry_buffer_.OnValueEnd();
-
-  // After an error is reported, the listener is not called again.
-  EXPECT_CALL(listener_, OnIndexedHeader(17)).Times(0);
-  entry_buffer_.OnIndexedHeader(17);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_whole_entry_listener.cc b/http2/hpack/decoder/hpack_whole_entry_listener.cc
deleted file mode 100644
index 5ef9c4f..0000000
--- a/http2/hpack/decoder/hpack_whole_entry_listener.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/decoder/hpack_whole_entry_listener.h"
-
-namespace http2 {
-
-HpackWholeEntryListener::~HpackWholeEntryListener() = default;
-
-HpackWholeEntryNoOpListener::~HpackWholeEntryNoOpListener() = default;
-
-void HpackWholeEntryNoOpListener::OnIndexedHeader(size_t /*index*/) {}
-void HpackWholeEntryNoOpListener::OnNameIndexAndLiteralValue(
-    HpackEntryType /*entry_type*/,
-    size_t /*name_index*/,
-    HpackDecoderStringBuffer* /*value_buffer*/) {}
-void HpackWholeEntryNoOpListener::OnLiteralNameAndValue(
-    HpackEntryType /*entry_type*/,
-    HpackDecoderStringBuffer* /*name_buffer*/,
-    HpackDecoderStringBuffer* /*value_buffer*/) {}
-void HpackWholeEntryNoOpListener::OnDynamicTableSizeUpdate(size_t /*size*/) {}
-void HpackWholeEntryNoOpListener::OnHpackDecodeError(
-    HpackDecodingError /*error*/,
-    std::string /*detailed_error*/) {}
-
-// static
-HpackWholeEntryNoOpListener* HpackWholeEntryNoOpListener::NoOpListener() {
-  static HpackWholeEntryNoOpListener* static_instance =
-      new HpackWholeEntryNoOpListener();
-  return static_instance;
-}
-
-}  // namespace http2
diff --git a/http2/hpack/decoder/hpack_whole_entry_listener.h b/http2/hpack/decoder/hpack_whole_entry_listener.h
deleted file mode 100644
index 3593af3..0000000
--- a/http2/hpack/decoder/hpack_whole_entry_listener.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Defines HpackWholeEntryListener, the base class of listeners for decoded
-// complete HPACK entries, as opposed to HpackEntryDecoderListener which
-// receives multiple callbacks for some single entries.
-
-#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_LISTENER_H_
-#define QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_LISTENER_H_
-
-#include <stddef.h>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_decoder_string_buffer.h"
-#include "http2/hpack/decoder/hpack_decoding_error.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-class QUICHE_EXPORT_PRIVATE HpackWholeEntryListener {
- public:
-  virtual ~HpackWholeEntryListener();
-
-  // Called when an indexed header (i.e. one in the static or dynamic table) has
-  // been decoded from an HPACK block. index is supposed to be non-zero, but
-  // that has not been checked by the caller.
-  virtual void OnIndexedHeader(size_t index) = 0;
-
-  // Called when a header entry with a name index and literal value has
-  // been fully decoded from an HPACK block. name_index is NOT zero.
-  // entry_type will be kIndexedLiteralHeader, kUnindexedLiteralHeader, or
-  // kNeverIndexedLiteralHeader.
-  virtual void OnNameIndexAndLiteralValue(
-      HpackEntryType entry_type,
-      size_t name_index,
-      HpackDecoderStringBuffer* value_buffer) = 0;
-
-  // Called when a header entry with a literal name and literal value
-  // has been fully decoded from an HPACK block. entry_type will be
-  // kIndexedLiteralHeader, kUnindexedLiteralHeader, or
-  // kNeverIndexedLiteralHeader.
-  virtual void OnLiteralNameAndValue(
-      HpackEntryType entry_type,
-      HpackDecoderStringBuffer* name_buffer,
-      HpackDecoderStringBuffer* value_buffer) = 0;
-
-  // Called when an update to the size of the peer's dynamic table has been
-  // decoded.
-  virtual void OnDynamicTableSizeUpdate(size_t size) = 0;
-
-  // OnHpackDecodeError is called if an error is detected while decoding.
-  virtual void OnHpackDecodeError(HpackDecodingError error,
-                                  std::string detailed_error) = 0;
-};
-
-// A no-op implementation of HpackWholeEntryDecoderListener, useful for ignoring
-// callbacks once an error is detected.
-class HpackWholeEntryNoOpListener : public HpackWholeEntryListener {
- public:
-  ~HpackWholeEntryNoOpListener() override;
-
-  void OnIndexedHeader(size_t index) override;
-  void OnNameIndexAndLiteralValue(
-      HpackEntryType entry_type,
-      size_t name_index,
-      HpackDecoderStringBuffer* value_buffer) override;
-  void OnLiteralNameAndValue(HpackEntryType entry_type,
-                             HpackDecoderStringBuffer* name_buffer,
-                             HpackDecoderStringBuffer* value_buffer) override;
-  void OnDynamicTableSizeUpdate(size_t size) override;
-  void OnHpackDecodeError(HpackDecodingError error,
-                          std::string detailed_error) override;
-
-  // Returns a listener that ignores all the calls.
-  static HpackWholeEntryNoOpListener* NoOpListener();
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_LISTENER_H_
diff --git a/http2/hpack/http2_hpack_constants.cc b/http2/hpack/http2_hpack_constants.cc
deleted file mode 100644
index e02ef9b..0000000
--- a/http2/hpack/http2_hpack_constants.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/http2_hpack_constants.h"
-
-#include "absl/strings/str_cat.h"
-
-namespace http2 {
-
-std::string HpackEntryTypeToString(HpackEntryType v) {
-  switch (v) {
-    case HpackEntryType::kIndexedHeader:
-      return "kIndexedHeader";
-    case HpackEntryType::kDynamicTableSizeUpdate:
-      return "kDynamicTableSizeUpdate";
-    case HpackEntryType::kIndexedLiteralHeader:
-      return "kIndexedLiteralHeader";
-    case HpackEntryType::kUnindexedLiteralHeader:
-      return "kUnindexedLiteralHeader";
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      return "kNeverIndexedLiteralHeader";
-  }
-  return absl::StrCat("UnknownHpackEntryType(", static_cast<int>(v), ")");
-}
-
-std::ostream& operator<<(std::ostream& out, HpackEntryType v) {
-  return out << HpackEntryTypeToString(v);
-}
-
-}  // namespace http2
diff --git a/http2/hpack/http2_hpack_constants.h b/http2/hpack/http2_hpack_constants.h
deleted file mode 100644
index ba83ba3..0000000
--- a/http2/hpack/http2_hpack_constants.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
-#define QUICHE_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
-
-// Enum HpackEntryType identifies the 5 basic types of HPACK Block Entries.
-//
-// See the spec for details:
-// https://http2.github.io/http2-spec/compression.html#rfc.section.6
-
-#include <ostream>
-#include <string>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-const size_t kFirstDynamicTableIndex = 62;
-
-enum class HpackEntryType {
-  // Entry is an index into the static or dynamic table. Decoding it has no
-  // effect on the dynamic table.
-  kIndexedHeader,
-
-  // The entry contains a literal value. The name may be either a literal or a
-  // reference to an entry in the static or dynamic table.
-  // The entry is added to the dynamic table after decoding.
-  kIndexedLiteralHeader,
-
-  // The entry contains a literal value. The name may be either a literal or a
-  // reference to an entry in the static or dynamic table.
-  // The entry is not added to the dynamic table after decoding, but a proxy
-  // may choose to insert the entry into its dynamic table when forwarding
-  // to another endpoint.
-  kUnindexedLiteralHeader,
-
-  // The entry contains a literal value. The name may be either a literal or a
-  // reference to an entry in the static or dynamic table.
-  // The entry is not added to the dynamic table after decoding, and a proxy
-  // must NOT insert the entry into its dynamic table when forwarding to another
-  // endpoint.
-  kNeverIndexedLiteralHeader,
-
-  // Entry conveys the size limit of the dynamic table of the encoder to
-  // the decoder. May be used to flush the table by sending a zero and then
-  // resetting the size back up to the maximum that the encoder will use
-  // (within the limits of SETTINGS_HEADER_TABLE_SIZE sent by the
-  // decoder to the encoder, with the default of 4096 assumed).
-  kDynamicTableSizeUpdate,
-};
-
-// Returns the name of the enum member.
-QUICHE_EXPORT_PRIVATE std::string HpackEntryTypeToString(HpackEntryType v);
-
-// Inserts the name of the enum member into |out|.
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               HpackEntryType v);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
diff --git a/http2/hpack/http2_hpack_constants_test.cc b/http2/hpack/http2_hpack_constants_test.cc
deleted file mode 100644
index 1c3dd10..0000000
--- a/http2/hpack/http2_hpack_constants_test.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/http2_hpack_constants.h"
-
-#include <sstream>
-
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-TEST(HpackEntryTypeTest, HpackEntryTypeToString) {
-  EXPECT_EQ("kIndexedHeader",
-            HpackEntryTypeToString(HpackEntryType::kIndexedHeader));
-  EXPECT_EQ("kDynamicTableSizeUpdate",
-            HpackEntryTypeToString(HpackEntryType::kDynamicTableSizeUpdate));
-  EXPECT_EQ("kIndexedLiteralHeader",
-            HpackEntryTypeToString(HpackEntryType::kIndexedLiteralHeader));
-  EXPECT_EQ("kUnindexedLiteralHeader",
-            HpackEntryTypeToString(HpackEntryType::kUnindexedLiteralHeader));
-  EXPECT_EQ("kNeverIndexedLiteralHeader",
-            HpackEntryTypeToString(HpackEntryType::kNeverIndexedLiteralHeader));
-  EXPECT_EQ("UnknownHpackEntryType(12321)",
-            HpackEntryTypeToString(static_cast<HpackEntryType>(12321)));
-}
-
-TEST(HpackEntryTypeTest, OutputHpackEntryType) {
-  {
-    std::stringstream log;
-    log << HpackEntryType::kIndexedHeader;
-    EXPECT_EQ("kIndexedHeader", log.str());
-  }
-  {
-    std::stringstream log;
-    log << HpackEntryType::kDynamicTableSizeUpdate;
-    EXPECT_EQ("kDynamicTableSizeUpdate", log.str());
-  }
-  {
-    std::stringstream log;
-    log << HpackEntryType::kIndexedLiteralHeader;
-    EXPECT_EQ("kIndexedLiteralHeader", log.str());
-  }
-  {
-    std::stringstream log;
-    log << HpackEntryType::kUnindexedLiteralHeader;
-    EXPECT_EQ("kUnindexedLiteralHeader", log.str());
-  }
-  {
-    std::stringstream log;
-    log << HpackEntryType::kNeverIndexedLiteralHeader;
-    EXPECT_EQ("kNeverIndexedLiteralHeader", log.str());
-  }
-  {
-    std::stringstream log;
-    log << static_cast<HpackEntryType>(1234321);
-    EXPECT_EQ("UnknownHpackEntryType(1234321)", log.str());
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/huffman/hpack_huffman_decoder.cc b/http2/hpack/huffman/hpack_huffman_decoder.cc
deleted file mode 100644
index 2f486c6..0000000
--- a/http2/hpack/huffman/hpack_huffman_decoder.cc
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/huffman/hpack_huffman_decoder.h"
-
-#include <bitset>
-#include <limits>
-
-#include "http2/platform/api/http2_logging.h"
-
-// Terminology:
-//
-// Symbol - a plain text (unencoded) character (uint8), or the End-of-String
-//          (EOS) symbol, 256.
-//
-// Code - the sequence of bits used to encode a symbol, varying in length from
-//        5 bits for the most common symbols (e.g. '0', '1', and 'a'), to
-//        30 bits for the least common (e.g. the EOS symbol).
-//        For those symbols whose codes have the same length, their code values
-//        are sorted such that the lower symbol value has a lower code value.
-//
-// Canonical - a symbol's cardinal value when sorted first by code length, and
-//             then by symbol value. For example, canonical 0 is for ASCII '0'
-//             (uint8 value 0x30), which is the first of the symbols whose code
-//             is 5 bits long, and the last canonical is EOS, which is the last
-//             of the symbols whose code is 30 bits long.
-
-namespace http2 {
-namespace {
-
-// HuffmanCode is used to store the codes associated with symbols (a pattern of
-// from 5 to 30 bits).
-typedef uint32_t HuffmanCode;
-
-// HuffmanCodeBitCount is used to store a count of bits in a code.
-typedef uint16_t HuffmanCodeBitCount;
-
-// HuffmanCodeBitSet is used for producing a string version of a code because
-// std::bitset logs nicely.
-typedef std::bitset<32> HuffmanCodeBitSet;
-typedef std::bitset<64> HuffmanAccumulatorBitSet;
-
-static constexpr HuffmanCodeBitCount kMinCodeBitCount = 5;
-static constexpr HuffmanCodeBitCount kMaxCodeBitCount = 30;
-static constexpr HuffmanCodeBitCount kHuffmanCodeBitCount =
-    std::numeric_limits<HuffmanCode>::digits;
-
-static_assert(std::numeric_limits<HuffmanCode>::digits >= kMaxCodeBitCount,
-              "HuffmanCode isn't big enough.");
-
-static_assert(std::numeric_limits<HuffmanAccumulator>::digits >=
-                  kMaxCodeBitCount,
-              "HuffmanAccumulator isn't big enough.");
-
-static constexpr HuffmanAccumulatorBitCount kHuffmanAccumulatorBitCount =
-    std::numeric_limits<HuffmanAccumulator>::digits;
-static constexpr HuffmanAccumulatorBitCount kExtraAccumulatorBitCount =
-    kHuffmanAccumulatorBitCount - kHuffmanCodeBitCount;
-
-// PrefixInfo holds info about a group of codes that are all of the same length.
-struct PrefixInfo {
-  // Given the leading bits (32 in this case) of the encoded string, and that
-  // they start with a code of length |code_length|, return the corresponding
-  // canonical for that leading code.
-  uint32_t DecodeToCanonical(HuffmanCode bits) const {
-    // What is the position of the canonical symbol being decoded within
-    // the canonical symbols of |length|?
-    HuffmanCode ordinal_in_length =
-        ((bits - first_code) >> (kHuffmanCodeBitCount - code_length));
-
-    // Combined with |canonical| to produce the position of the canonical symbol
-    // being decoded within all of the canonical symbols.
-    return first_canonical + ordinal_in_length;
-  }
-
-  const HuffmanCode first_code;  // First code of this length, left justified in
-                                 // the field (i.e. the first bit of the code is
-                                 // the high-order bit).
-  const uint16_t code_length;    // Length of the prefix code |base|.
-  const uint16_t first_canonical;  // First canonical symbol of this length.
-};
-
-inline std::ostream& operator<<(std::ostream& out, const PrefixInfo& v) {
-  return out << "{first_code: " << HuffmanCodeBitSet(v.first_code)
-             << ", code_length: " << v.code_length
-             << ", first_canonical: " << v.first_canonical << "}";
-}
-
-// Given |value|, a sequence of the leading bits remaining to be decoded,
-// figure out which group of canonicals (by code length) that value starts
-// with. This function was generated.
-PrefixInfo PrefixToInfo(HuffmanCode value) {
-  if (value < 0b10111000000000000000000000000000) {
-    if (value < 0b01010000000000000000000000000000) {
-      return {0b00000000000000000000000000000000, 5, 0};
-    } else {
-      return {0b01010000000000000000000000000000, 6, 10};
-    }
-  } else {
-    if (value < 0b11111110000000000000000000000000) {
-      if (value < 0b11111000000000000000000000000000) {
-        return {0b10111000000000000000000000000000, 7, 36};
-      } else {
-        return {0b11111000000000000000000000000000, 8, 68};
-      }
-    } else {
-      if (value < 0b11111111110000000000000000000000) {
-        if (value < 0b11111111101000000000000000000000) {
-          if (value < 0b11111111010000000000000000000000) {
-            return {0b11111110000000000000000000000000, 10, 74};
-          } else {
-            return {0b11111111010000000000000000000000, 11, 79};
-          }
-        } else {
-          return {0b11111111101000000000000000000000, 12, 82};
-        }
-      } else {
-        if (value < 0b11111111111111100000000000000000) {
-          if (value < 0b11111111111110000000000000000000) {
-            if (value < 0b11111111111100000000000000000000) {
-              return {0b11111111110000000000000000000000, 13, 84};
-            } else {
-              return {0b11111111111100000000000000000000, 14, 90};
-            }
-          } else {
-            return {0b11111111111110000000000000000000, 15, 92};
-          }
-        } else {
-          if (value < 0b11111111111111110100100000000000) {
-            if (value < 0b11111111111111101110000000000000) {
-              if (value < 0b11111111111111100110000000000000) {
-                return {0b11111111111111100000000000000000, 19, 95};
-              } else {
-                return {0b11111111111111100110000000000000, 20, 98};
-              }
-            } else {
-              return {0b11111111111111101110000000000000, 21, 106};
-            }
-          } else {
-            if (value < 0b11111111111111111110101000000000) {
-              if (value < 0b11111111111111111011000000000000) {
-                return {0b11111111111111110100100000000000, 22, 119};
-              } else {
-                return {0b11111111111111111011000000000000, 23, 145};
-              }
-            } else {
-              if (value < 0b11111111111111111111101111000000) {
-                if (value < 0b11111111111111111111100000000000) {
-                  if (value < 0b11111111111111111111011000000000) {
-                    return {0b11111111111111111110101000000000, 24, 174};
-                  } else {
-                    return {0b11111111111111111111011000000000, 25, 186};
-                  }
-                } else {
-                  return {0b11111111111111111111100000000000, 26, 190};
-                }
-              } else {
-                if (value < 0b11111111111111111111111111110000) {
-                  if (value < 0b11111111111111111111111000100000) {
-                    return {0b11111111111111111111101111000000, 27, 205};
-                  } else {
-                    return {0b11111111111111111111111000100000, 28, 224};
-                  }
-                } else {
-                  return {0b11111111111111111111111111110000, 30, 253};
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-// Mapping from canonical symbol (0 to 255) to actual symbol.
-// clang-format off
-constexpr unsigned char kCanonicalToSymbol[] = {
-    '0',  '1',  '2',  'a',  'c',  'e',  'i',  'o',
-    's',  't',  0x20, '%',  '-',  '.',  '/',  '3',
-    '4',  '5',  '6',  '7',  '8',  '9',  '=',  'A',
-    '_',  'b',  'd',  'f',  'g',  'h',  'l',  'm',
-    'n',  'p',  'r',  'u',  ':',  'B',  'C',  'D',
-    'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L',
-    'M',  'N',  'O',  'P',  'Q',  'R',  'S',  'T',
-    'U',  'V',  'W',  'Y',  'j',  'k',  'q',  'v',
-    'w',  'x',  'y',  'z',  '&',  '*',  ',',  ';',
-    'X',  'Z',  '!',  '\"', '(',  ')',  '?',  '\'',
-    '+',  '|',  '#',  '>',  0x00, '$',  '@',  '[',
-    ']',  '~',  '^',  '}',  '<',  '`',  '{',  '\\',
-    0xc3, 0xd0, 0x80, 0x82, 0x83, 0xa2, 0xb8, 0xc2,
-    0xe0, 0xe2, 0x99, 0xa1, 0xa7, 0xac, 0xb0, 0xb1,
-    0xb3, 0xd1, 0xd8, 0xd9, 0xe3, 0xe5, 0xe6, 0x81,
-    0x84, 0x85, 0x86, 0x88, 0x92, 0x9a, 0x9c, 0xa0,
-    0xa3, 0xa4, 0xa9, 0xaa, 0xad, 0xb2, 0xb5, 0xb9,
-    0xba, 0xbb, 0xbd, 0xbe, 0xc4, 0xc6, 0xe4, 0xe8,
-    0xe9, 0x01, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
-    0x8f, 0x93, 0x95, 0x96, 0x97, 0x98, 0x9b, 0x9d,
-    0x9e, 0xa5, 0xa6, 0xa8, 0xae, 0xaf, 0xb4, 0xb6,
-    0xb7, 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e,
-    0x90, 0x91, 0x94, 0x9f, 0xab, 0xce, 0xd7, 0xe1,
-    0xec, 0xed, 0xc7, 0xcf, 0xea, 0xeb, 0xc0, 0xc1,
-    0xc8, 0xc9, 0xca, 0xcd, 0xd2, 0xd5, 0xda, 0xdb,
-    0xee, 0xf0, 0xf2, 0xf3, 0xff, 0xcb, 0xcc, 0xd3,
-    0xd4, 0xd6, 0xdd, 0xde, 0xdf, 0xf1, 0xf4, 0xf5,
-    0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
-    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0b,
-    0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
-    0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
-    0x1e, 0x1f, 0x7f, 0xdc, 0xf9, 0x0a, 0x0d, 0x16,
-};
-// clang-format on
-
-constexpr size_t kShortCodeTableSize = 124;
-struct ShortCodeInfo {
-  uint8_t symbol;
-  uint8_t length;
-} kShortCodeTable[kShortCodeTableSize] = {
-    {0x30, 5},  // Match: 0b0000000, Symbol: 0
-    {0x30, 5},  // Match: 0b0000001, Symbol: 0
-    {0x30, 5},  // Match: 0b0000010, Symbol: 0
-    {0x30, 5},  // Match: 0b0000011, Symbol: 0
-    {0x31, 5},  // Match: 0b0000100, Symbol: 1
-    {0x31, 5},  // Match: 0b0000101, Symbol: 1
-    {0x31, 5},  // Match: 0b0000110, Symbol: 1
-    {0x31, 5},  // Match: 0b0000111, Symbol: 1
-    {0x32, 5},  // Match: 0b0001000, Symbol: 2
-    {0x32, 5},  // Match: 0b0001001, Symbol: 2
-    {0x32, 5},  // Match: 0b0001010, Symbol: 2
-    {0x32, 5},  // Match: 0b0001011, Symbol: 2
-    {0x61, 5},  // Match: 0b0001100, Symbol: a
-    {0x61, 5},  // Match: 0b0001101, Symbol: a
-    {0x61, 5},  // Match: 0b0001110, Symbol: a
-    {0x61, 5},  // Match: 0b0001111, Symbol: a
-    {0x63, 5},  // Match: 0b0010000, Symbol: c
-    {0x63, 5},  // Match: 0b0010001, Symbol: c
-    {0x63, 5},  // Match: 0b0010010, Symbol: c
-    {0x63, 5},  // Match: 0b0010011, Symbol: c
-    {0x65, 5},  // Match: 0b0010100, Symbol: e
-    {0x65, 5},  // Match: 0b0010101, Symbol: e
-    {0x65, 5},  // Match: 0b0010110, Symbol: e
-    {0x65, 5},  // Match: 0b0010111, Symbol: e
-    {0x69, 5},  // Match: 0b0011000, Symbol: i
-    {0x69, 5},  // Match: 0b0011001, Symbol: i
-    {0x69, 5},  // Match: 0b0011010, Symbol: i
-    {0x69, 5},  // Match: 0b0011011, Symbol: i
-    {0x6f, 5},  // Match: 0b0011100, Symbol: o
-    {0x6f, 5},  // Match: 0b0011101, Symbol: o
-    {0x6f, 5},  // Match: 0b0011110, Symbol: o
-    {0x6f, 5},  // Match: 0b0011111, Symbol: o
-    {0x73, 5},  // Match: 0b0100000, Symbol: s
-    {0x73, 5},  // Match: 0b0100001, Symbol: s
-    {0x73, 5},  // Match: 0b0100010, Symbol: s
-    {0x73, 5},  // Match: 0b0100011, Symbol: s
-    {0x74, 5},  // Match: 0b0100100, Symbol: t
-    {0x74, 5},  // Match: 0b0100101, Symbol: t
-    {0x74, 5},  // Match: 0b0100110, Symbol: t
-    {0x74, 5},  // Match: 0b0100111, Symbol: t
-    {0x20, 6},  // Match: 0b0101000, Symbol: (space)
-    {0x20, 6},  // Match: 0b0101001, Symbol: (space)
-    {0x25, 6},  // Match: 0b0101010, Symbol: %
-    {0x25, 6},  // Match: 0b0101011, Symbol: %
-    {0x2d, 6},  // Match: 0b0101100, Symbol: -
-    {0x2d, 6},  // Match: 0b0101101, Symbol: -
-    {0x2e, 6},  // Match: 0b0101110, Symbol: .
-    {0x2e, 6},  // Match: 0b0101111, Symbol: .
-    {0x2f, 6},  // Match: 0b0110000, Symbol: /
-    {0x2f, 6},  // Match: 0b0110001, Symbol: /
-    {0x33, 6},  // Match: 0b0110010, Symbol: 3
-    {0x33, 6},  // Match: 0b0110011, Symbol: 3
-    {0x34, 6},  // Match: 0b0110100, Symbol: 4
-    {0x34, 6},  // Match: 0b0110101, Symbol: 4
-    {0x35, 6},  // Match: 0b0110110, Symbol: 5
-    {0x35, 6},  // Match: 0b0110111, Symbol: 5
-    {0x36, 6},  // Match: 0b0111000, Symbol: 6
-    {0x36, 6},  // Match: 0b0111001, Symbol: 6
-    {0x37, 6},  // Match: 0b0111010, Symbol: 7
-    {0x37, 6},  // Match: 0b0111011, Symbol: 7
-    {0x38, 6},  // Match: 0b0111100, Symbol: 8
-    {0x38, 6},  // Match: 0b0111101, Symbol: 8
-    {0x39, 6},  // Match: 0b0111110, Symbol: 9
-    {0x39, 6},  // Match: 0b0111111, Symbol: 9
-    {0x3d, 6},  // Match: 0b1000000, Symbol: =
-    {0x3d, 6},  // Match: 0b1000001, Symbol: =
-    {0x41, 6},  // Match: 0b1000010, Symbol: A
-    {0x41, 6},  // Match: 0b1000011, Symbol: A
-    {0x5f, 6},  // Match: 0b1000100, Symbol: _
-    {0x5f, 6},  // Match: 0b1000101, Symbol: _
-    {0x62, 6},  // Match: 0b1000110, Symbol: b
-    {0x62, 6},  // Match: 0b1000111, Symbol: b
-    {0x64, 6},  // Match: 0b1001000, Symbol: d
-    {0x64, 6},  // Match: 0b1001001, Symbol: d
-    {0x66, 6},  // Match: 0b1001010, Symbol: f
-    {0x66, 6},  // Match: 0b1001011, Symbol: f
-    {0x67, 6},  // Match: 0b1001100, Symbol: g
-    {0x67, 6},  // Match: 0b1001101, Symbol: g
-    {0x68, 6},  // Match: 0b1001110, Symbol: h
-    {0x68, 6},  // Match: 0b1001111, Symbol: h
-    {0x6c, 6},  // Match: 0b1010000, Symbol: l
-    {0x6c, 6},  // Match: 0b1010001, Symbol: l
-    {0x6d, 6},  // Match: 0b1010010, Symbol: m
-    {0x6d, 6},  // Match: 0b1010011, Symbol: m
-    {0x6e, 6},  // Match: 0b1010100, Symbol: n
-    {0x6e, 6},  // Match: 0b1010101, Symbol: n
-    {0x70, 6},  // Match: 0b1010110, Symbol: p
-    {0x70, 6},  // Match: 0b1010111, Symbol: p
-    {0x72, 6},  // Match: 0b1011000, Symbol: r
-    {0x72, 6},  // Match: 0b1011001, Symbol: r
-    {0x75, 6},  // Match: 0b1011010, Symbol: u
-    {0x75, 6},  // Match: 0b1011011, Symbol: u
-    {0x3a, 7},  // Match: 0b1011100, Symbol: :
-    {0x42, 7},  // Match: 0b1011101, Symbol: B
-    {0x43, 7},  // Match: 0b1011110, Symbol: C
-    {0x44, 7},  // Match: 0b1011111, Symbol: D
-    {0x45, 7},  // Match: 0b1100000, Symbol: E
-    {0x46, 7},  // Match: 0b1100001, Symbol: F
-    {0x47, 7},  // Match: 0b1100010, Symbol: G
-    {0x48, 7},  // Match: 0b1100011, Symbol: H
-    {0x49, 7},  // Match: 0b1100100, Symbol: I
-    {0x4a, 7},  // Match: 0b1100101, Symbol: J
-    {0x4b, 7},  // Match: 0b1100110, Symbol: K
-    {0x4c, 7},  // Match: 0b1100111, Symbol: L
-    {0x4d, 7},  // Match: 0b1101000, Symbol: M
-    {0x4e, 7},  // Match: 0b1101001, Symbol: N
-    {0x4f, 7},  // Match: 0b1101010, Symbol: O
-    {0x50, 7},  // Match: 0b1101011, Symbol: P
-    {0x51, 7},  // Match: 0b1101100, Symbol: Q
-    {0x52, 7},  // Match: 0b1101101, Symbol: R
-    {0x53, 7},  // Match: 0b1101110, Symbol: S
-    {0x54, 7},  // Match: 0b1101111, Symbol: T
-    {0x55, 7},  // Match: 0b1110000, Symbol: U
-    {0x56, 7},  // Match: 0b1110001, Symbol: V
-    {0x57, 7},  // Match: 0b1110010, Symbol: W
-    {0x59, 7},  // Match: 0b1110011, Symbol: Y
-    {0x6a, 7},  // Match: 0b1110100, Symbol: j
-    {0x6b, 7},  // Match: 0b1110101, Symbol: k
-    {0x71, 7},  // Match: 0b1110110, Symbol: q
-    {0x76, 7},  // Match: 0b1110111, Symbol: v
-    {0x77, 7},  // Match: 0b1111000, Symbol: w
-    {0x78, 7},  // Match: 0b1111001, Symbol: x
-    {0x79, 7},  // Match: 0b1111010, Symbol: y
-    {0x7a, 7},  // Match: 0b1111011, Symbol: z
-};
-
-}  // namespace
-
-HuffmanBitBuffer::HuffmanBitBuffer() {
-  Reset();
-}
-
-void HuffmanBitBuffer::Reset() {
-  accumulator_ = 0;
-  count_ = 0;
-}
-
-size_t HuffmanBitBuffer::AppendBytes(absl::string_view input) {
-  HuffmanAccumulatorBitCount free_cnt = free_count();
-  size_t bytes_available = input.size();
-  if (free_cnt < 8 || bytes_available == 0) {
-    return 0;
-  }
-
-  // Top up |accumulator_| until there isn't room for a whole byte.
-  size_t bytes_used = 0;
-  auto* ptr = reinterpret_cast<const uint8_t*>(input.data());
-  do {
-    auto b = static_cast<HuffmanAccumulator>(*ptr++);
-    free_cnt -= 8;
-    accumulator_ |= (b << free_cnt);
-    ++bytes_used;
-  } while (free_cnt >= 8 && bytes_used < bytes_available);
-  count_ += (bytes_used * 8);
-  return bytes_used;
-}
-
-HuffmanAccumulatorBitCount HuffmanBitBuffer::free_count() const {
-  return kHuffmanAccumulatorBitCount - count_;
-}
-
-void HuffmanBitBuffer::ConsumeBits(HuffmanAccumulatorBitCount code_length) {
-  QUICHE_DCHECK_LE(code_length, count_);
-  accumulator_ <<= code_length;
-  count_ -= code_length;
-}
-
-bool HuffmanBitBuffer::InputProperlyTerminated() const {
-  auto cnt = count();
-  if (cnt < 8) {
-    if (cnt == 0) {
-      return true;
-    }
-    HuffmanAccumulator expected = ~(~HuffmanAccumulator() >> cnt);
-    // We expect all the bits below the high order |cnt| bits of accumulator_
-    // to be cleared as we perform left shift operations while decoding.
-    QUICHE_DCHECK_EQ(accumulator_ & ~expected, 0u)
-        << "\n  expected: " << HuffmanAccumulatorBitSet(expected) << "\n  "
-        << *this;
-    return accumulator_ == expected;
-  }
-  return false;
-}
-
-std::string HuffmanBitBuffer::DebugString() const {
-  std::stringstream ss;
-  ss << "{accumulator: " << HuffmanAccumulatorBitSet(accumulator_)
-     << "; count: " << count_ << "}";
-  return ss.str();
-}
-
-HpackHuffmanDecoder::HpackHuffmanDecoder() = default;
-
-HpackHuffmanDecoder::~HpackHuffmanDecoder() = default;
-
-bool HpackHuffmanDecoder::Decode(absl::string_view input, std::string* output) {
-  HTTP2_DVLOG(1) << "HpackHuffmanDecoder::Decode";
-
-  // Fill bit_buffer_ from input.
-  input.remove_prefix(bit_buffer_.AppendBytes(input));
-
-  while (true) {
-    HTTP2_DVLOG(3) << "Enter Decode Loop, bit_buffer_: " << bit_buffer_;
-    if (bit_buffer_.count() >= 7) {
-      // Get high 7 bits of the bit buffer, see if that contains a complete
-      // code of 5, 6 or 7 bits.
-      uint8_t short_code =
-          bit_buffer_.value() >> (kHuffmanAccumulatorBitCount - 7);
-      QUICHE_DCHECK_LT(short_code, 128);
-      if (short_code < kShortCodeTableSize) {
-        ShortCodeInfo info = kShortCodeTable[short_code];
-        bit_buffer_.ConsumeBits(info.length);
-        output->push_back(static_cast<char>(info.symbol));
-        continue;
-      }
-      // The code is more than 7 bits long. Use PrefixToInfo, etc. to decode
-      // longer codes.
-    } else {
-      // We may have (mostly) drained bit_buffer_. If we can top it up, try
-      // using the table decoder above.
-      size_t byte_count = bit_buffer_.AppendBytes(input);
-      if (byte_count > 0) {
-        input.remove_prefix(byte_count);
-        continue;
-      }
-    }
-
-    HuffmanCode code_prefix = bit_buffer_.value() >> kExtraAccumulatorBitCount;
-    HTTP2_DVLOG(3) << "code_prefix: " << HuffmanCodeBitSet(code_prefix);
-
-    PrefixInfo prefix_info = PrefixToInfo(code_prefix);
-    HTTP2_DVLOG(3) << "prefix_info: " << prefix_info;
-    QUICHE_DCHECK_LE(kMinCodeBitCount, prefix_info.code_length);
-    QUICHE_DCHECK_LE(prefix_info.code_length, kMaxCodeBitCount);
-
-    if (prefix_info.code_length <= bit_buffer_.count()) {
-      // We have enough bits for one code.
-      uint32_t canonical = prefix_info.DecodeToCanonical(code_prefix);
-      if (canonical < 256) {
-        // Valid code.
-        char c = kCanonicalToSymbol[canonical];
-        output->push_back(c);
-        bit_buffer_.ConsumeBits(prefix_info.code_length);
-        continue;
-      }
-      // Encoder is not supposed to explicity encode the EOS symbol.
-      HTTP2_DLOG(ERROR) << "EOS explicitly encoded!\n " << bit_buffer_ << "\n "
-                        << prefix_info;
-      return false;
-    }
-    // bit_buffer_ doesn't have enough bits in it to decode the next symbol.
-    // Append to it as many bytes as are available AND fit.
-    size_t byte_count = bit_buffer_.AppendBytes(input);
-    if (byte_count == 0) {
-      QUICHE_DCHECK_EQ(input.size(), 0u);
-      return true;
-    }
-    input.remove_prefix(byte_count);
-  }
-}
-
-std::string HpackHuffmanDecoder::DebugString() const {
-  return bit_buffer_.DebugString();
-}
-
-}  // namespace http2
diff --git a/http2/hpack/huffman/hpack_huffman_decoder.h b/http2/hpack/huffman/hpack_huffman_decoder.h
deleted file mode 100644
index 8679823..0000000
--- a/http2/hpack/huffman/hpack_huffman_decoder.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_DECODER_H_
-#define QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_DECODER_H_
-
-// HpackHuffmanDecoder is an incremental decoder of strings that have been
-// encoded using the Huffman table defined in the HPACK spec.
-// By incremental, we mean that the HpackHuffmanDecoder::Decode method does
-// not require the entire string to be provided, and can instead decode the
-// string as fragments of it become available (e.g. as HPACK block fragments
-// are received for decoding by HpackEntryDecoder).
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <iosfwd>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// HuffmanAccumulator is used to store bits during decoding, e.g. next N bits
-// that have not yet been decoded, but have been extracted from the encoded
-// string).  An advantage of using a uint64 for the accumulator
-// is that it has room for the bits of the longest code plus the bits of a full
-// byte; that means that when adding more bits to the accumulator, it can always
-// be done in whole bytes. For example, if we currently have 26 bits in the
-// accumulator, and need more to decode the current symbol, we can add a whole
-// byte to the accumulator, and not have to do juggling with adding 6 bits (to
-// reach 30), and then keep track of the last two bits we've not been able to
-// add to the accumulator.
-typedef uint64_t HuffmanAccumulator;
-typedef size_t HuffmanAccumulatorBitCount;
-
-// HuffmanBitBuffer stores the leading edge of bits to be decoded. The high
-// order bit of accumulator_ is the next bit to be decoded.
-class QUICHE_EXPORT_PRIVATE HuffmanBitBuffer {
- public:
-  HuffmanBitBuffer();
-
-  // Prepare for decoding a new Huffman encoded string.
-  void Reset();
-
-  // Add as many whole bytes to the accumulator (accumulator_) as possible,
-  // returning the number of bytes added.
-  size_t AppendBytes(absl::string_view input);
-
-  // Get the bits of the accumulator.
-  HuffmanAccumulator value() const { return accumulator_; }
-
-  // Number of bits of the encoded string that are in the accumulator
-  // (accumulator_).
-  HuffmanAccumulatorBitCount count() const { return count_; }
-
-  // Are there no bits in the accumulator?
-  bool IsEmpty() const { return count_ == 0; }
-
-  // Number of additional bits that can be added to the accumulator.
-  HuffmanAccumulatorBitCount free_count() const;
-
-  // Consume the leading |code_length| bits of the accumulator.
-  void ConsumeBits(HuffmanAccumulatorBitCount code_length);
-
-  // Are the contents valid for the end of a Huffman encoded string? The RFC
-  // states that EOS (end-of-string) symbol must not be explicitly encoded in
-  // the bit stream, but any unused bits in the final byte must be set to the
-  // prefix of the EOS symbol, which is all 1 bits. So there can be at most 7
-  // such bits.
-  // Returns true if the bit buffer is empty, or contains at most 7 bits, all
-  // of them 1. Otherwise returns false.
-  bool InputProperlyTerminated() const;
-
-  std::string DebugString() const;
-
- private:
-  HuffmanAccumulator accumulator_;
-  HuffmanAccumulatorBitCount count_;
-};
-
-inline std::ostream& operator<<(std::ostream& out, const HuffmanBitBuffer& v) {
-  return out << v.DebugString();
-}
-
-class QUICHE_EXPORT_PRIVATE HpackHuffmanDecoder {
- public:
-  HpackHuffmanDecoder();
-  ~HpackHuffmanDecoder();
-
-  // Prepare for decoding a new Huffman encoded string.
-  void Reset() { bit_buffer_.Reset(); }
-
-  // Decode the portion of a HPACK Huffman encoded string that is in |input|,
-  // appending the decoded symbols into |*output|, stopping when more bits are
-  // needed to determine the next symbol, which/ means that the input has been
-  // drained, and also that the bit_buffer_ is empty or that the bits that are
-  // in it are not a whole symbol.
-  // If |input| is the start of a string, the caller must first call Reset.
-  // If |input| includes the end of the encoded string, the caller must call
-  // InputProperlyTerminated after Decode has returned true in order to
-  // determine if the encoded string was properly terminated.
-  // Returns false if something went wrong (e.g. the encoding contains the code
-  // EOS symbol). Otherwise returns true, in which case input has been fully
-  // decoded or buffered; in particular, if the low-order bit of the final byte
-  // of the input is not the last bit of an encoded symbol, then bit_buffer_
-  // will contain the leading bits of the code for that symbol, but not the
-  // final bits of that code.
-  // Note that output should be empty, but that it is not cleared by Decode().
-  bool Decode(absl::string_view input, std::string* output);
-
-  // Is what remains in the bit_buffer_ valid at the end of an encoded string?
-  // Call after passing the the final portion of a Huffman string to Decode,
-  // and getting true as the result.
-  bool InputProperlyTerminated() const {
-    return bit_buffer_.InputProperlyTerminated();
-  }
-
-  std::string DebugString() const;
-
- private:
-  HuffmanBitBuffer bit_buffer_;
-};
-
-inline std::ostream& operator<<(std::ostream& out,
-                                const HpackHuffmanDecoder& v) {
-  return out << v.DebugString();
-}
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_DECODER_H_
diff --git a/http2/hpack/huffman/hpack_huffman_decoder_test.cc b/http2/hpack/huffman/hpack_huffman_decoder_test.cc
deleted file mode 100644
index 1e16086..0000000
--- a/http2/hpack/huffman/hpack_huffman_decoder_test.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/huffman/hpack_huffman_decoder.h"
-
-// Tests of HpackHuffmanDecoder and HuffmanBitBuffer.
-
-#include <iostream>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-TEST(HuffmanBitBufferTest, Reset) {
-  HuffmanBitBuffer bb;
-  EXPECT_TRUE(bb.IsEmpty());
-  EXPECT_TRUE(bb.InputProperlyTerminated());
-  EXPECT_EQ(bb.count(), 0u);
-  EXPECT_EQ(bb.free_count(), 64u);
-  EXPECT_EQ(bb.value(), 0u);
-}
-
-TEST(HuffmanBitBufferTest, AppendBytesAligned) {
-  std::string s;
-  s.push_back('\x11');
-  s.push_back('\x22');
-  s.push_back('\x33');
-  absl::string_view sp(s);
-
-  HuffmanBitBuffer bb;
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_TRUE(sp.empty());
-  EXPECT_FALSE(bb.IsEmpty()) << bb;
-  EXPECT_FALSE(bb.InputProperlyTerminated());
-  EXPECT_EQ(bb.count(), 24u) << bb;
-  EXPECT_EQ(bb.free_count(), 40u) << bb;
-  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 40) << bb;
-
-  s.clear();
-  s.push_back('\x44');
-  sp = s;
-
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_TRUE(sp.empty());
-  EXPECT_EQ(bb.count(), 32u) << bb;
-  EXPECT_EQ(bb.free_count(), 32u) << bb;
-  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x11223344) << 32) << bb;
-
-  s.clear();
-  s.push_back('\x55');
-  s.push_back('\x66');
-  s.push_back('\x77');
-  s.push_back('\x88');
-  s.push_back('\x99');
-  sp = s;
-
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_EQ(sp.size(), 1u);
-  EXPECT_EQ('\x99', sp[0]);
-  EXPECT_EQ(bb.count(), 64u) << bb;
-  EXPECT_EQ(bb.free_count(), 0u) << bb;
-  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
-
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_EQ(sp.size(), 1u);
-  EXPECT_EQ('\x99', sp[0]);
-  EXPECT_EQ(bb.count(), 64u) << bb;
-  EXPECT_EQ(bb.free_count(), 0u) << bb;
-  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
-}
-
-TEST(HuffmanBitBufferTest, ConsumeBits) {
-  std::string s;
-  s.push_back('\x11');
-  s.push_back('\x22');
-  s.push_back('\x33');
-  absl::string_view sp(s);
-
-  HuffmanBitBuffer bb;
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_TRUE(sp.empty());
-
-  bb.ConsumeBits(1);
-  EXPECT_EQ(bb.count(), 23u) << bb;
-  EXPECT_EQ(bb.free_count(), 41u) << bb;
-  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 41) << bb;
-
-  bb.ConsumeBits(20);
-  EXPECT_EQ(bb.count(), 3u) << bb;
-  EXPECT_EQ(bb.free_count(), 61u) << bb;
-  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x3) << 61) << bb;
-}
-
-TEST(HuffmanBitBufferTest, AppendBytesUnaligned) {
-  std::string s;
-  s.push_back('\x11');
-  s.push_back('\x22');
-  s.push_back('\x33');
-  s.push_back('\x44');
-  s.push_back('\x55');
-  s.push_back('\x66');
-  s.push_back('\x77');
-  s.push_back('\x88');
-  s.push_back('\x99');
-  s.push_back('\xaa');
-  s.push_back('\xbb');
-  s.push_back('\xcc');
-  s.push_back('\xdd');
-  absl::string_view sp(s);
-
-  HuffmanBitBuffer bb;
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_EQ(sp.size(), 5u);
-  EXPECT_FALSE(bb.InputProperlyTerminated());
-
-  bb.ConsumeBits(15);
-  EXPECT_EQ(bb.count(), 49u) << bb;
-  EXPECT_EQ(bb.free_count(), 15u) << bb;
-
-  HuffmanAccumulator expected(0x1122334455667788);
-  expected <<= 15;
-  EXPECT_EQ(bb.value(), expected);
-
-  sp.remove_prefix(bb.AppendBytes(sp));
-  EXPECT_EQ(sp.size(), 4u);
-  EXPECT_EQ(bb.count(), 57u) << bb;
-  EXPECT_EQ(bb.free_count(), 7u) << bb;
-
-  expected |= (HuffmanAccumulator(0x99) << 7);
-  EXPECT_EQ(bb.value(), expected)
-      << bb << std::hex << "\n   actual: " << bb.value()
-      << "\n expected: " << expected;
-}
-
-class HpackHuffmanDecoderTest : public RandomDecoderTest {
- protected:
-  HpackHuffmanDecoderTest() {
-    // The decoder may return true, and its accumulator may be empty, at
-    // many boundaries while decoding, and yet the whole string hasn't
-    // been decoded.
-    stop_decode_on_done_ = false;
-  }
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    input_bytes_seen_ = 0;
-    output_buffer_.clear();
-    decoder_.Reset();
-    return ResumeDecoding(b);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    input_bytes_seen_ += b->Remaining();
-    absl::string_view sp(b->cursor(), b->Remaining());
-    if (decoder_.Decode(sp, &output_buffer_)) {
-      b->AdvanceCursor(b->Remaining());
-      // Successfully decoded (or buffered) the bytes in absl::string_view.
-      EXPECT_LE(input_bytes_seen_, input_bytes_expected_);
-      // Have we reached the end of the encoded string?
-      if (input_bytes_expected_ == input_bytes_seen_) {
-        if (decoder_.InputProperlyTerminated()) {
-          return DecodeStatus::kDecodeDone;
-        } else {
-          return DecodeStatus::kDecodeError;
-        }
-      }
-      return DecodeStatus::kDecodeInProgress;
-    }
-    return DecodeStatus::kDecodeError;
-  }
-
-  HpackHuffmanDecoder decoder_;
-  std::string output_buffer_;
-  size_t input_bytes_seen_;
-  size_t input_bytes_expected_;
-};
-
-TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) {
-  HpackHuffmanDecoder decoder;
-  std::string test_table[] = {
-      absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff"),
-      "www.example.com",
-      absl::HexStringToBytes("a8eb10649cbf"),
-      "no-cache",
-      absl::HexStringToBytes("25a849e95ba97d7f"),
-      "custom-key",
-      absl::HexStringToBytes("25a849e95bb8e8b4bf"),
-      "custom-value",
-  };
-  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
-    const std::string& huffman_encoded(test_table[i]);
-    const std::string& plain_string(test_table[i + 1]);
-    std::string buffer;
-    decoder.Reset();
-    EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
-    EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
-    EXPECT_EQ(buffer, plain_string);
-  }
-}
-
-TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) {
-  HpackHuffmanDecoder decoder;
-  // clang-format off
-  std::string test_table[] = {
-    absl::HexStringToBytes("6402"),
-    "302",
-    absl::HexStringToBytes("aec3771a4b"),
-    "private",
-    absl::HexStringToBytes("d07abe941054d444a8200595040b8166"
-            "e082a62d1bff"),
-    "Mon, 21 Oct 2013 20:13:21 GMT",
-    absl::HexStringToBytes("9d29ad171863c78f0b97c8e9ae82ae43"
-            "d3"),
-    "https://www.example.com",
-    absl::HexStringToBytes("94e7821dd7f2e6c7b335dfdfcd5b3960"
-            "d5af27087f3672c1ab270fb5291f9587"
-            "316065c003ed4ee5b1063d5007"),
-    "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
-  };
-  // clang-format on
-  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
-    const std::string& huffman_encoded(test_table[i]);
-    const std::string& plain_string(test_table[i + 1]);
-    std::string buffer;
-    decoder.Reset();
-    EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
-    EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
-    EXPECT_EQ(buffer, plain_string);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/huffman/hpack_huffman_encoder.cc b/http2/hpack/huffman/hpack_huffman_encoder.cc
deleted file mode 100644
index daf85bc..0000000
--- a/http2/hpack/huffman/hpack_huffman_encoder.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-
-#include "http2/hpack/huffman/huffman_spec_tables.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-size_t HuffmanSize(absl::string_view plain) {
-  size_t bits = 0;
-  for (const uint8_t c : plain) {
-    bits += HuffmanSpecTables::kCodeLengths[c];
-  }
-  return (bits + 7) / 8;
-}
-
-void HuffmanEncode(absl::string_view plain,
-                   size_t encoded_size,
-                   std::string* huffman) {
-  QUICHE_DCHECK(huffman != nullptr);
-  huffman->reserve(huffman->size() + encoded_size);
-  uint64_t bit_buffer = 0;  // High-bit is next bit to output. Not clear if that
-                            // is more performant than having the low-bit be the
-                            // last to be output.
-  size_t bits_unused = 64;  // Number of bits available for the next code.
-  for (uint8_t c : plain) {
-    size_t code_length = HuffmanSpecTables::kCodeLengths[c];
-    if (bits_unused < code_length) {
-      // There isn't enough room in bit_buffer for the code of c.
-      // Flush until bits_unused > 56 (i.e. 64 - 8).
-      do {
-        char h = static_cast<char>(bit_buffer >> 56);
-        bit_buffer <<= 8;
-        bits_unused += 8;
-        // Perhaps would be more efficient if we populated an array of chars,
-        // so we don't have to call push_back each time. Reconsider if used
-        // for production.
-        huffman->push_back(h);
-      } while (bits_unused <= 56);
-    }
-    uint64_t code = HuffmanSpecTables::kRightCodes[c];
-    size_t shift_by = bits_unused - code_length;
-    bit_buffer |= (code << shift_by);
-    bits_unused -= code_length;
-  }
-  // bit_buffer contains (64-bits_unused) bits that still need to be flushed.
-  // Output whole bytes until we don't have any whole bytes left.
-  size_t bits_used = 64 - bits_unused;
-  while (bits_used >= 8) {
-    char h = static_cast<char>(bit_buffer >> 56);
-    bit_buffer <<= 8;
-    bits_used -= 8;
-    huffman->push_back(h);
-  }
-  if (bits_used > 0) {
-    // We have less than a byte left to output. The spec calls for padding out
-    // the final byte with the leading bits of the EOS symbol (30 1-bits).
-    constexpr uint64_t leading_eos_bits = 0b11111111;
-    bit_buffer |= (leading_eos_bits << (56 - bits_used));
-    char h = static_cast<char>(bit_buffer >> 56);
-    huffman->push_back(h);
-  }
-}
-
-void HuffmanEncodeFast(absl::string_view input,
-                       size_t encoded_size,
-                       std::string* output) {
-  const size_t original_size = output->size();
-  const size_t final_size = original_size + encoded_size;
-  // Reserve an extra four bytes to avoid accessing unallocated memory (even
-  // though it would only be OR'd with zeros and thus not modified).
-  output->resize(final_size + 4, 0);
-
-  // Pointer to first appended byte.
-  char* const first = &*output->begin() + original_size;
-  size_t bit_counter = 0;
-  for (uint8_t c : input) {
-    // Align the Huffman code to byte boundaries as it needs to be written.
-    // The longest Huffman code is 30 bits long, and it can be shifted by up to
-    // 7 bits, requiring 37 bits in total.  The most significant 25 bits and
-    // least significant 2 bits of |code| are always zero.
-    uint64_t code = static_cast<uint64_t>(HuffmanSpecTables::kLeftCodes[c])
-                    << (8 - (bit_counter % 8));
-    // The byte where the first bit of |code| needs to be written.
-    char* const current = first + (bit_counter / 8);
-
-    bit_counter += HuffmanSpecTables::kCodeLengths[c];
-
-    *current |= code >> 32;
-
-    // Do not check if this write is zero before executing it, because with
-    // uniformly random shifts and an ideal random input distribution
-    // corresponding to the Huffman tree it would only be zero in 29% of the
-    // cases.
-    *(current + 1) |= (code >> 24) & 0xff;
-
-    // Continue to next input character if there is nothing else to write.
-    // (If next byte is zero, then rest must also be zero.)
-    if ((code & 0xff0000) == 0) {
-      continue;
-    }
-    *(current + 2) |= (code >> 16) & 0xff;
-
-    // Continue to next input character if there is nothing else to write.
-    // (If next byte is zero, then rest must also be zero.)
-    if ((code & 0xff00) == 0) {
-      continue;
-    }
-    *(current + 3) |= (code >> 8) & 0xff;
-
-    // Do not check if this write is zero, because the check would probably be
-    // as expensive as the write.
-    *(current + 4) |= code & 0xff;
-  }
-
-  QUICHE_DCHECK_EQ(encoded_size, (bit_counter + 7) / 8);
-
-  // EOF
-  if (bit_counter % 8 != 0) {
-    *(first + encoded_size - 1) |= 0xff >> (bit_counter & 7);
-  }
-
-  output->resize(final_size);
-}
-
-}  // namespace http2
diff --git a/http2/hpack/huffman/hpack_huffman_encoder.h b/http2/hpack/huffman/hpack_huffman_encoder.h
deleted file mode 100644
index a0ed861..0000000
--- a/http2/hpack/huffman/hpack_huffman_encoder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_
-#define QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_
-
-// Functions supporting the encoding of strings using the HPACK-defined Huffman
-// table.
-
-#include <cstddef>  // For size_t
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// Returns the size of the Huffman encoding of |plain|, which may be greater
-// than plain.size().
-QUICHE_EXPORT_PRIVATE size_t HuffmanSize(absl::string_view plain);
-
-// Encode the plain text string |plain| with the Huffman encoding defined in the
-// HPACK RFC, 7541.  |encoded_size| is used to pre-allocate storage and it
-// should be the value returned by HuffmanSize().  Appends the result to
-// |*huffman|.
-QUICHE_EXPORT_PRIVATE void HuffmanEncode(absl::string_view plain,
-                                         size_t encoded_size,
-                                         std::string* huffman);
-
-// Encode |input| with the Huffman encoding defined RFC7541, used in HPACK and
-// QPACK.  |encoded_size| must be the value returned by HuffmanSize().
-// Appends the result to the end of |*output|.
-QUICHE_EXPORT_PRIVATE void HuffmanEncodeFast(absl::string_view input,
-                                             size_t encoded_size,
-                                             std::string* output);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_
diff --git a/http2/hpack/huffman/hpack_huffman_encoder_test.cc b/http2/hpack/huffman/hpack_huffman_encoder_test.cc
deleted file mode 100644
index 84439c1..0000000
--- a/http2/hpack/huffman/hpack_huffman_encoder_test.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace {
-
-class HuffmanEncoderTest : public ::testing::TestWithParam<bool> {
- protected:
-  HuffmanEncoderTest() : use_fast_encoder_(GetParam()) {}
-  virtual ~HuffmanEncoderTest() = default;
-
-  void Encode(absl::string_view input,
-              size_t encoded_size,
-              std::string* output) {
-    use_fast_encoder_ ? HuffmanEncodeFast(input, encoded_size, output)
-                      : HuffmanEncode(input, encoded_size, output);
-  }
-
-  const bool use_fast_encoder_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TwoEncoders, HuffmanEncoderTest, ::testing::Bool());
-
-TEST_P(HuffmanEncoderTest, Empty) {
-  std::string empty("");
-  size_t encoded_size = HuffmanSize(empty);
-  EXPECT_EQ(0u, encoded_size);
-
-  std::string buffer;
-  Encode(empty, encoded_size, &buffer);
-  EXPECT_EQ("", buffer);
-}
-
-TEST_P(HuffmanEncoderTest, SpecRequestExamples) {
-  std::string test_table[] = {
-      absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff"),
-      "www.example.com",
-      absl::HexStringToBytes("a8eb10649cbf"),
-      "no-cache",
-      absl::HexStringToBytes("25a849e95ba97d7f"),
-      "custom-key",
-      absl::HexStringToBytes("25a849e95bb8e8b4bf"),
-      "custom-value",
-  };
-  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
-    const std::string& huffman_encoded(test_table[i]);
-    const std::string& plain_string(test_table[i + 1]);
-    size_t encoded_size = HuffmanSize(plain_string);
-    EXPECT_EQ(huffman_encoded.size(), encoded_size);
-    std::string buffer;
-    buffer.reserve();
-    Encode(plain_string, encoded_size, &buffer);
-    EXPECT_EQ(buffer, huffman_encoded) << "Error encoding " << plain_string;
-  }
-}
-
-TEST_P(HuffmanEncoderTest, SpecResponseExamples) {
-  // clang-format off
-  std::string test_table[] = {
-    absl::HexStringToBytes("6402"),
-    "302",
-    absl::HexStringToBytes("aec3771a4b"),
-    "private",
-    absl::HexStringToBytes("d07abe941054d444a8200595040b8166"
-            "e082a62d1bff"),
-    "Mon, 21 Oct 2013 20:13:21 GMT",
-    absl::HexStringToBytes("9d29ad171863c78f0b97c8e9ae82ae43"
-            "d3"),
-    "https://www.example.com",
-    absl::HexStringToBytes("94e7821dd7f2e6c7b335dfdfcd5b3960"
-            "d5af27087f3672c1ab270fb5291f9587"
-            "316065c003ed4ee5b1063d5007"),
-    "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
-  };
-  // clang-format on
-  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
-    const std::string& huffman_encoded(test_table[i]);
-    const std::string& plain_string(test_table[i + 1]);
-    size_t encoded_size = HuffmanSize(plain_string);
-    EXPECT_EQ(huffman_encoded.size(), encoded_size);
-    std::string buffer;
-    Encode(plain_string, encoded_size, &buffer);
-    EXPECT_EQ(buffer, huffman_encoded) << "Error encoding " << plain_string;
-  }
-}
-
-TEST_P(HuffmanEncoderTest, EncodedSizeAgreesWithEncodeString) {
-  std::string test_table[] = {
-      "",
-      "Mon, 21 Oct 2013 20:13:21 GMT",
-      "https://www.example.com",
-      "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
-      std::string(1, '\0'),
-      std::string("foo\0bar", 7),
-      std::string(256, '\0'),
-  };
-  // Modify last |test_table| entry to cover all codes.
-  for (size_t i = 0; i != 256; ++i) {
-    test_table[ABSL_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i);
-  }
-
-  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); ++i) {
-    const std::string& plain_string = test_table[i];
-    size_t encoded_size = HuffmanSize(plain_string);
-    std::string huffman_encoded;
-    Encode(plain_string, encoded_size, &huffman_encoded);
-    EXPECT_EQ(encoded_size, huffman_encoded.size());
-  }
-}
-
-// Test that encoding appends to output without overwriting it.
-TEST_P(HuffmanEncoderTest, AppendToOutput) {
-  size_t encoded_size = HuffmanSize("foo");
-  std::string buffer;
-  Encode("foo", encoded_size, &buffer);
-  EXPECT_EQ(absl::HexStringToBytes("94e7"), buffer);
-
-  encoded_size = HuffmanSize("bar");
-  Encode("bar", encoded_size, &buffer);
-  EXPECT_EQ(absl::HexStringToBytes("94e78c767f"), buffer);
-}
-
-}  // namespace
-}  // namespace http2
diff --git a/http2/hpack/huffman/hpack_huffman_transcoder_test.cc b/http2/hpack/huffman/hpack_huffman_transcoder_test.cc
deleted file mode 100644
index 671eb4f..0000000
--- a/http2/hpack/huffman/hpack_huffman_transcoder_test.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A test of roundtrips through the encoder and decoder.
-
-#include <stddef.h>
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/hpack/huffman/hpack_huffman_decoder.h"
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_text_utils.h"
-
-using ::testing::AssertionSuccess;
-using ::testing::Combine;
-using ::testing::Range;
-using ::testing::Values;
-
-namespace http2 {
-namespace test {
-namespace {
-
-std::string GenAsciiNonControlSet() {
-  std::string s;
-  const char space = ' ';  // First character after the control characters: 0x20
-  const char del = 127;    // First character after the non-control characters.
-  for (char c = space; c < del; ++c) {
-    s.push_back(c);
-  }
-  return s;
-}
-
-class HpackHuffmanTranscoderTest : public RandomDecoderTest {
- protected:
-  HpackHuffmanTranscoderTest()
-      : ascii_non_control_set_(GenAsciiNonControlSet()) {
-    // The decoder may return true, and its accumulator may be empty, at
-    // many boundaries while decoding, and yet the whole string hasn't
-    // been decoded.
-    stop_decode_on_done_ = false;
-  }
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    input_bytes_seen_ = 0;
-    output_buffer_.clear();
-    decoder_.Reset();
-    return ResumeDecoding(b);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    input_bytes_seen_ += b->Remaining();
-    absl::string_view sp(b->cursor(), b->Remaining());
-    if (decoder_.Decode(sp, &output_buffer_)) {
-      b->AdvanceCursor(b->Remaining());
-      // Successfully decoded (or buffered) the bytes in absl::string_view.
-      EXPECT_LE(input_bytes_seen_, input_bytes_expected_);
-      // Have we reached the end of the encoded string?
-      if (input_bytes_expected_ == input_bytes_seen_) {
-        if (decoder_.InputProperlyTerminated()) {
-          return DecodeStatus::kDecodeDone;
-        } else {
-          return DecodeStatus::kDecodeError;
-        }
-      }
-      return DecodeStatus::kDecodeInProgress;
-    }
-    return DecodeStatus::kDecodeError;
-  }
-
-  AssertionResult TranscodeAndValidateSeveralWays(
-      absl::string_view plain,
-      absl::string_view expected_huffman) {
-    size_t encoded_size = HuffmanSize(plain);
-    std::string encoded;
-    HuffmanEncode(plain, encoded_size, &encoded);
-    VERIFY_EQ(encoded_size, encoded.size());
-    if (!expected_huffman.empty() || plain.empty()) {
-      VERIFY_EQ(encoded, expected_huffman);
-    }
-    input_bytes_expected_ = encoded.size();
-    auto validator = [plain, this]() -> AssertionResult {
-      VERIFY_EQ(output_buffer_.size(), plain.size());
-      VERIFY_EQ(output_buffer_, plain);
-      return AssertionSuccess();
-    };
-    DecodeBuffer db(encoded);
-    bool return_non_zero_on_first = false;
-    return DecodeAndValidateSeveralWays(&db, return_non_zero_on_first,
-                                        ValidateDoneAndEmpty(validator));
-  }
-
-  AssertionResult TranscodeAndValidateSeveralWays(absl::string_view plain) {
-    return TranscodeAndValidateSeveralWays(plain, "");
-  }
-
-  std::string RandomAsciiNonControlString(int length) {
-    return Random().RandStringWithAlphabet(length, ascii_non_control_set_);
-  }
-
-  std::string RandomBytes(int length) { return Random().RandString(length); }
-
-  const std::string ascii_non_control_set_;
-  HpackHuffmanDecoder decoder_;
-  std::string output_buffer_;
-  size_t input_bytes_seen_;
-  size_t input_bytes_expected_;
-};
-
-TEST_F(HpackHuffmanTranscoderTest, RoundTripRandomAsciiNonControlString) {
-  for (size_t length = 0; length != 20; length++) {
-    const std::string s = RandomAsciiNonControlString(length);
-    ASSERT_TRUE(TranscodeAndValidateSeveralWays(s))
-        << "Unable to decode:\n\n"
-        << quiche::QuicheTextUtils::HexDump(s) << "\n\noutput_buffer_:\n"
-        << quiche::QuicheTextUtils::HexDump(output_buffer_);
-  }
-}
-
-TEST_F(HpackHuffmanTranscoderTest, RoundTripRandomBytes) {
-  for (size_t length = 0; length != 20; length++) {
-    const std::string s = RandomBytes(length);
-    ASSERT_TRUE(TranscodeAndValidateSeveralWays(s))
-        << "Unable to decode:\n\n"
-        << quiche::QuicheTextUtils::HexDump(s) << "\n\noutput_buffer_:\n"
-        << quiche::QuicheTextUtils::HexDump(output_buffer_);
-  }
-}
-
-// Two parameters: decoder choice, and the character to round-trip.
-class HpackHuffmanTranscoderAdjacentCharTest
-    : public HpackHuffmanTranscoderTest,
-      public testing::WithParamInterface<int> {
- protected:
-  HpackHuffmanTranscoderAdjacentCharTest()
-      : c_(static_cast<char>(GetParam())) {}
-
-  const char c_;
-};
-
-INSTANTIATE_TEST_SUITE_P(HpackHuffmanTranscoderAdjacentCharTest,
-                         HpackHuffmanTranscoderAdjacentCharTest, Range(0, 256));
-
-// Test c_ adjacent to every other character, both before and after.
-TEST_P(HpackHuffmanTranscoderAdjacentCharTest, RoundTripAdjacentChar) {
-  std::string s;
-  for (int a = 0; a < 256; ++a) {
-    s.push_back(static_cast<char>(a));
-    s.push_back(c_);
-    s.push_back(static_cast<char>(a));
-  }
-  ASSERT_TRUE(TranscodeAndValidateSeveralWays(s));
-}
-
-// Two parameters: character to repeat, number of repeats.
-class HpackHuffmanTranscoderRepeatedCharTest
-    : public HpackHuffmanTranscoderTest,
-      public testing::WithParamInterface<std::tuple<int, int>> {
- protected:
-  HpackHuffmanTranscoderRepeatedCharTest()
-      : c_(static_cast<char>(std::get<0>(GetParam()))),
-        length_(std::get<1>(GetParam())) {}
-  std::string MakeString() { return std::string(length_, c_); }
-
- private:
-  const char c_;
-  const size_t length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(HpackHuffmanTranscoderRepeatedCharTest,
-                         HpackHuffmanTranscoderRepeatedCharTest,
-                         Combine(Range(0, 256), Values(1, 2, 3, 4, 8, 16, 32)));
-
-TEST_P(HpackHuffmanTranscoderRepeatedCharTest, RoundTripRepeatedChar) {
-  ASSERT_TRUE(TranscodeAndValidateSeveralWays(MakeString()));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/huffman/huffman_spec_tables.cc b/http2/hpack/huffman/huffman_spec_tables.cc
deleted file mode 100644
index a4e0d3c..0000000
--- a/http2/hpack/huffman/huffman_spec_tables.cc
+++ /dev/null
@@ -1,572 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/huffman/huffman_spec_tables.h"
-
-namespace http2 {
-
-// clang-format off
-// static
-const uint8_t HuffmanSpecTables::kCodeLengths[] = {
-    13, 23, 28, 28, 28, 28, 28, 28,  //   0 -   7
-    28, 24, 30, 28, 28, 30, 28, 28,  //   8 -  15
-    28, 28, 28, 28, 28, 28, 30, 28,  //  16 -  23
-    28, 28, 28, 28, 28, 28, 28, 28,  //  24 -  31
-     6, 10, 10, 12, 13,  6,  8, 11,  //  32 -  39
-    10, 10,  8, 11,  8,  6,  6,  6,  //  40 -  47
-     5,  5,  5,  6,  6,  6,  6,  6,  //  48 -  55
-     6,  6,  7,  8, 15,  6, 12, 10,  //  56 -  63
-    13,  6,  7,  7,  7,  7,  7,  7,  //  64 -  71
-     7,  7,  7,  7,  7,  7,  7,  7,  //  72 -  79
-     7,  7,  7,  7,  7,  7,  7,  7,  //  80 -  87
-     8,  7,  8, 13, 19, 13, 14,  6,  //  88 -  95
-    15,  5,  6,  5,  6,  5,  6,  6,  //  96 - 103
-     6,  5,  7,  7,  6,  6,  6,  5,  // 104 - 111
-     6,  7,  6,  5,  5,  6,  7,  7,  // 112 - 119
-     7,  7,  7, 15, 11, 14, 13, 28,  // 120 - 127
-    20, 22, 20, 20, 22, 22, 22, 23,  // 128 - 135
-    22, 23, 23, 23, 23, 23, 24, 23,  // 136 - 143
-    24, 24, 22, 23, 24, 23, 23, 23,  // 144 - 151
-    23, 21, 22, 23, 22, 23, 23, 24,  // 152 - 159
-    22, 21, 20, 22, 22, 23, 23, 21,  // 160 - 167
-    23, 22, 22, 24, 21, 22, 23, 23,  // 168 - 175
-    21, 21, 22, 21, 23, 22, 23, 23,  // 176 - 183
-    20, 22, 22, 22, 23, 22, 22, 23,  // 184 - 191
-    26, 26, 20, 19, 22, 23, 22, 25,  // 192 - 199
-    26, 26, 26, 27, 27, 26, 24, 25,  // 200 - 207
-    19, 21, 26, 27, 27, 26, 27, 24,  // 208 - 215
-    21, 21, 26, 26, 28, 27, 27, 27,  // 216 - 223
-    20, 24, 20, 21, 22, 21, 21, 23,  // 224 - 231
-    22, 22, 25, 25, 24, 24, 26, 23,  // 232 - 239
-    26, 27, 26, 26, 27, 27, 27, 27,  // 240 - 247
-    27, 28, 27, 27, 27, 27, 27, 26,  // 248 - 255
-    30,                              // 256
-};
-
-// The encoding of each symbol, left justified (as printed), which means that
-// the first bit of the encoding is the high-order bit of the uint32.
-// static
-const uint32_t HuffmanSpecTables::kLeftCodes[] = {
-    0b11111111110000000000000000000000,  // 0x00
-    0b11111111111111111011000000000000,  // 0x01
-    0b11111111111111111111111000100000,  // 0x02
-    0b11111111111111111111111000110000,  // 0x03
-    0b11111111111111111111111001000000,  // 0x04
-    0b11111111111111111111111001010000,  // 0x05
-    0b11111111111111111111111001100000,  // 0x06
-    0b11111111111111111111111001110000,  // 0x07
-    0b11111111111111111111111010000000,  // 0x08
-    0b11111111111111111110101000000000,  // 0x09
-    0b11111111111111111111111111110000,  // 0x0a
-    0b11111111111111111111111010010000,  // 0x0b
-    0b11111111111111111111111010100000,  // 0x0c
-    0b11111111111111111111111111110100,  // 0x0d
-    0b11111111111111111111111010110000,  // 0x0e
-    0b11111111111111111111111011000000,  // 0x0f
-    0b11111111111111111111111011010000,  // 0x10
-    0b11111111111111111111111011100000,  // 0x11
-    0b11111111111111111111111011110000,  // 0x12
-    0b11111111111111111111111100000000,  // 0x13
-    0b11111111111111111111111100010000,  // 0x14
-    0b11111111111111111111111100100000,  // 0x15
-    0b11111111111111111111111111111000,  // 0x16
-    0b11111111111111111111111100110000,  // 0x17
-    0b11111111111111111111111101000000,  // 0x18
-    0b11111111111111111111111101010000,  // 0x19
-    0b11111111111111111111111101100000,  // 0x1a
-    0b11111111111111111111111101110000,  // 0x1b
-    0b11111111111111111111111110000000,  // 0x1c
-    0b11111111111111111111111110010000,  // 0x1d
-    0b11111111111111111111111110100000,  // 0x1e
-    0b11111111111111111111111110110000,  // 0x1f
-    0b01010000000000000000000000000000,  // 0x20
-    0b11111110000000000000000000000000,  // '!'
-    0b11111110010000000000000000000000,  // '\"'
-    0b11111111101000000000000000000000,  // '#'
-    0b11111111110010000000000000000000,  // '$'
-    0b01010100000000000000000000000000,  // '%'
-    0b11111000000000000000000000000000,  // '&'
-    0b11111111010000000000000000000000,  // '\''
-    0b11111110100000000000000000000000,  // '('
-    0b11111110110000000000000000000000,  // ')'
-    0b11111001000000000000000000000000,  // '*'
-    0b11111111011000000000000000000000,  // '+'
-    0b11111010000000000000000000000000,  // ','
-    0b01011000000000000000000000000000,  // '-'
-    0b01011100000000000000000000000000,  // '.'
-    0b01100000000000000000000000000000,  // '/'
-    0b00000000000000000000000000000000,  // '0'
-    0b00001000000000000000000000000000,  // '1'
-    0b00010000000000000000000000000000,  // '2'
-    0b01100100000000000000000000000000,  // '3'
-    0b01101000000000000000000000000000,  // '4'
-    0b01101100000000000000000000000000,  // '5'
-    0b01110000000000000000000000000000,  // '6'
-    0b01110100000000000000000000000000,  // '7'
-    0b01111000000000000000000000000000,  // '8'
-    0b01111100000000000000000000000000,  // '9'
-    0b10111000000000000000000000000000,  // ':'
-    0b11111011000000000000000000000000,  // ';'
-    0b11111111111110000000000000000000,  // '<'
-    0b10000000000000000000000000000000,  // '='
-    0b11111111101100000000000000000000,  // '>'
-    0b11111111000000000000000000000000,  // '?'
-    0b11111111110100000000000000000000,  // '@'
-    0b10000100000000000000000000000000,  // 'A'
-    0b10111010000000000000000000000000,  // 'B'
-    0b10111100000000000000000000000000,  // 'C'
-    0b10111110000000000000000000000000,  // 'D'
-    0b11000000000000000000000000000000,  // 'E'
-    0b11000010000000000000000000000000,  // 'F'
-    0b11000100000000000000000000000000,  // 'G'
-    0b11000110000000000000000000000000,  // 'H'
-    0b11001000000000000000000000000000,  // 'I'
-    0b11001010000000000000000000000000,  // 'J'
-    0b11001100000000000000000000000000,  // 'K'
-    0b11001110000000000000000000000000,  // 'L'
-    0b11010000000000000000000000000000,  // 'M'
-    0b11010010000000000000000000000000,  // 'N'
-    0b11010100000000000000000000000000,  // 'O'
-    0b11010110000000000000000000000000,  // 'P'
-    0b11011000000000000000000000000000,  // 'Q'
-    0b11011010000000000000000000000000,  // 'R'
-    0b11011100000000000000000000000000,  // 'S'
-    0b11011110000000000000000000000000,  // 'T'
-    0b11100000000000000000000000000000,  // 'U'
-    0b11100010000000000000000000000000,  // 'V'
-    0b11100100000000000000000000000000,  // 'W'
-    0b11111100000000000000000000000000,  // 'X'
-    0b11100110000000000000000000000000,  // 'Y'
-    0b11111101000000000000000000000000,  // 'Z'
-    0b11111111110110000000000000000000,  // '['
-    0b11111111111111100000000000000000,  // '\\'
-    0b11111111111000000000000000000000,  // ']'
-    0b11111111111100000000000000000000,  // '^'
-    0b10001000000000000000000000000000,  // '_'
-    0b11111111111110100000000000000000,  // '`'
-    0b00011000000000000000000000000000,  // 'a'
-    0b10001100000000000000000000000000,  // 'b'
-    0b00100000000000000000000000000000,  // 'c'
-    0b10010000000000000000000000000000,  // 'd'
-    0b00101000000000000000000000000000,  // 'e'
-    0b10010100000000000000000000000000,  // 'f'
-    0b10011000000000000000000000000000,  // 'g'
-    0b10011100000000000000000000000000,  // 'h'
-    0b00110000000000000000000000000000,  // 'i'
-    0b11101000000000000000000000000000,  // 'j'
-    0b11101010000000000000000000000000,  // 'k'
-    0b10100000000000000000000000000000,  // 'l'
-    0b10100100000000000000000000000000,  // 'm'
-    0b10101000000000000000000000000000,  // 'n'
-    0b00111000000000000000000000000000,  // 'o'
-    0b10101100000000000000000000000000,  // 'p'
-    0b11101100000000000000000000000000,  // 'q'
-    0b10110000000000000000000000000000,  // 'r'
-    0b01000000000000000000000000000000,  // 's'
-    0b01001000000000000000000000000000,  // 't'
-    0b10110100000000000000000000000000,  // 'u'
-    0b11101110000000000000000000000000,  // 'v'
-    0b11110000000000000000000000000000,  // 'w'
-    0b11110010000000000000000000000000,  // 'x'
-    0b11110100000000000000000000000000,  // 'y'
-    0b11110110000000000000000000000000,  // 'z'
-    0b11111111111111000000000000000000,  // '{'
-    0b11111111100000000000000000000000,  // '|'
-    0b11111111111101000000000000000000,  // '}'
-    0b11111111111010000000000000000000,  // '~'
-    0b11111111111111111111111111000000,  // 0x7f
-    0b11111111111111100110000000000000,  // 0x80
-    0b11111111111111110100100000000000,  // 0x81
-    0b11111111111111100111000000000000,  // 0x82
-    0b11111111111111101000000000000000,  // 0x83
-    0b11111111111111110100110000000000,  // 0x84
-    0b11111111111111110101000000000000,  // 0x85
-    0b11111111111111110101010000000000,  // 0x86
-    0b11111111111111111011001000000000,  // 0x87
-    0b11111111111111110101100000000000,  // 0x88
-    0b11111111111111111011010000000000,  // 0x89
-    0b11111111111111111011011000000000,  // 0x8a
-    0b11111111111111111011100000000000,  // 0x8b
-    0b11111111111111111011101000000000,  // 0x8c
-    0b11111111111111111011110000000000,  // 0x8d
-    0b11111111111111111110101100000000,  // 0x8e
-    0b11111111111111111011111000000000,  // 0x8f
-    0b11111111111111111110110000000000,  // 0x90
-    0b11111111111111111110110100000000,  // 0x91
-    0b11111111111111110101110000000000,  // 0x92
-    0b11111111111111111100000000000000,  // 0x93
-    0b11111111111111111110111000000000,  // 0x94
-    0b11111111111111111100001000000000,  // 0x95
-    0b11111111111111111100010000000000,  // 0x96
-    0b11111111111111111100011000000000,  // 0x97
-    0b11111111111111111100100000000000,  // 0x98
-    0b11111111111111101110000000000000,  // 0x99
-    0b11111111111111110110000000000000,  // 0x9a
-    0b11111111111111111100101000000000,  // 0x9b
-    0b11111111111111110110010000000000,  // 0x9c
-    0b11111111111111111100110000000000,  // 0x9d
-    0b11111111111111111100111000000000,  // 0x9e
-    0b11111111111111111110111100000000,  // 0x9f
-    0b11111111111111110110100000000000,  // 0xa0
-    0b11111111111111101110100000000000,  // 0xa1
-    0b11111111111111101001000000000000,  // 0xa2
-    0b11111111111111110110110000000000,  // 0xa3
-    0b11111111111111110111000000000000,  // 0xa4
-    0b11111111111111111101000000000000,  // 0xa5
-    0b11111111111111111101001000000000,  // 0xa6
-    0b11111111111111101111000000000000,  // 0xa7
-    0b11111111111111111101010000000000,  // 0xa8
-    0b11111111111111110111010000000000,  // 0xa9
-    0b11111111111111110111100000000000,  // 0xaa
-    0b11111111111111111111000000000000,  // 0xab
-    0b11111111111111101111100000000000,  // 0xac
-    0b11111111111111110111110000000000,  // 0xad
-    0b11111111111111111101011000000000,  // 0xae
-    0b11111111111111111101100000000000,  // 0xaf
-    0b11111111111111110000000000000000,  // 0xb0
-    0b11111111111111110000100000000000,  // 0xb1
-    0b11111111111111111000000000000000,  // 0xb2
-    0b11111111111111110001000000000000,  // 0xb3
-    0b11111111111111111101101000000000,  // 0xb4
-    0b11111111111111111000010000000000,  // 0xb5
-    0b11111111111111111101110000000000,  // 0xb6
-    0b11111111111111111101111000000000,  // 0xb7
-    0b11111111111111101010000000000000,  // 0xb8
-    0b11111111111111111000100000000000,  // 0xb9
-    0b11111111111111111000110000000000,  // 0xba
-    0b11111111111111111001000000000000,  // 0xbb
-    0b11111111111111111110000000000000,  // 0xbc
-    0b11111111111111111001010000000000,  // 0xbd
-    0b11111111111111111001100000000000,  // 0xbe
-    0b11111111111111111110001000000000,  // 0xbf
-    0b11111111111111111111100000000000,  // 0xc0
-    0b11111111111111111111100001000000,  // 0xc1
-    0b11111111111111101011000000000000,  // 0xc2
-    0b11111111111111100010000000000000,  // 0xc3
-    0b11111111111111111001110000000000,  // 0xc4
-    0b11111111111111111110010000000000,  // 0xc5
-    0b11111111111111111010000000000000,  // 0xc6
-    0b11111111111111111111011000000000,  // 0xc7
-    0b11111111111111111111100010000000,  // 0xc8
-    0b11111111111111111111100011000000,  // 0xc9
-    0b11111111111111111111100100000000,  // 0xca
-    0b11111111111111111111101111000000,  // 0xcb
-    0b11111111111111111111101111100000,  // 0xcc
-    0b11111111111111111111100101000000,  // 0xcd
-    0b11111111111111111111000100000000,  // 0xce
-    0b11111111111111111111011010000000,  // 0xcf
-    0b11111111111111100100000000000000,  // 0xd0
-    0b11111111111111110001100000000000,  // 0xd1
-    0b11111111111111111111100110000000,  // 0xd2
-    0b11111111111111111111110000000000,  // 0xd3
-    0b11111111111111111111110000100000,  // 0xd4
-    0b11111111111111111111100111000000,  // 0xd5
-    0b11111111111111111111110001000000,  // 0xd6
-    0b11111111111111111111001000000000,  // 0xd7
-    0b11111111111111110010000000000000,  // 0xd8
-    0b11111111111111110010100000000000,  // 0xd9
-    0b11111111111111111111101000000000,  // 0xda
-    0b11111111111111111111101001000000,  // 0xdb
-    0b11111111111111111111111111010000,  // 0xdc
-    0b11111111111111111111110001100000,  // 0xdd
-    0b11111111111111111111110010000000,  // 0xde
-    0b11111111111111111111110010100000,  // 0xdf
-    0b11111111111111101100000000000000,  // 0xe0
-    0b11111111111111111111001100000000,  // 0xe1
-    0b11111111111111101101000000000000,  // 0xe2
-    0b11111111111111110011000000000000,  // 0xe3
-    0b11111111111111111010010000000000,  // 0xe4
-    0b11111111111111110011100000000000,  // 0xe5
-    0b11111111111111110100000000000000,  // 0xe6
-    0b11111111111111111110011000000000,  // 0xe7
-    0b11111111111111111010100000000000,  // 0xe8
-    0b11111111111111111010110000000000,  // 0xe9
-    0b11111111111111111111011100000000,  // 0xea
-    0b11111111111111111111011110000000,  // 0xeb
-    0b11111111111111111111010000000000,  // 0xec
-    0b11111111111111111111010100000000,  // 0xed
-    0b11111111111111111111101010000000,  // 0xee
-    0b11111111111111111110100000000000,  // 0xef
-    0b11111111111111111111101011000000,  // 0xf0
-    0b11111111111111111111110011000000,  // 0xf1
-    0b11111111111111111111101100000000,  // 0xf2
-    0b11111111111111111111101101000000,  // 0xf3
-    0b11111111111111111111110011100000,  // 0xf4
-    0b11111111111111111111110100000000,  // 0xf5
-    0b11111111111111111111110100100000,  // 0xf6
-    0b11111111111111111111110101000000,  // 0xf7
-    0b11111111111111111111110101100000,  // 0xf8
-    0b11111111111111111111111111100000,  // 0xf9
-    0b11111111111111111111110110000000,  // 0xfa
-    0b11111111111111111111110110100000,  // 0xfb
-    0b11111111111111111111110111000000,  // 0xfc
-    0b11111111111111111111110111100000,  // 0xfd
-    0b11111111111111111111111000000000,  // 0xfe
-    0b11111111111111111111101110000000,  // 0xff
-    0b11111111111111111111111111111100,  // 0x100
-};
-
-// static
-const uint32_t HuffmanSpecTables::kRightCodes[] = {
-    0b00000000000000000001111111111000,  // 0x00
-    0b00000000011111111111111111011000,  // 0x01
-    0b00001111111111111111111111100010,  // 0x02
-    0b00001111111111111111111111100011,  // 0x03
-    0b00001111111111111111111111100100,  // 0x04
-    0b00001111111111111111111111100101,  // 0x05
-    0b00001111111111111111111111100110,  // 0x06
-    0b00001111111111111111111111100111,  // 0x07
-    0b00001111111111111111111111101000,  // 0x08
-    0b00000000111111111111111111101010,  // 0x09
-    0b00111111111111111111111111111100,  // 0x0a
-    0b00001111111111111111111111101001,  // 0x0b
-    0b00001111111111111111111111101010,  // 0x0c
-    0b00111111111111111111111111111101,  // 0x0d
-    0b00001111111111111111111111101011,  // 0x0e
-    0b00001111111111111111111111101100,  // 0x0f
-    0b00001111111111111111111111101101,  // 0x10
-    0b00001111111111111111111111101110,  // 0x11
-    0b00001111111111111111111111101111,  // 0x12
-    0b00001111111111111111111111110000,  // 0x13
-    0b00001111111111111111111111110001,  // 0x14
-    0b00001111111111111111111111110010,  // 0x15
-    0b00111111111111111111111111111110,  // 0x16
-    0b00001111111111111111111111110011,  // 0x17
-    0b00001111111111111111111111110100,  // 0x18
-    0b00001111111111111111111111110101,  // 0x19
-    0b00001111111111111111111111110110,  // 0x1a
-    0b00001111111111111111111111110111,  // 0x1b
-    0b00001111111111111111111111111000,  // 0x1c
-    0b00001111111111111111111111111001,  // 0x1d
-    0b00001111111111111111111111111010,  // 0x1e
-    0b00001111111111111111111111111011,  // 0x1f
-    0b00000000000000000000000000010100,  // 0x20
-    0b00000000000000000000001111111000,  // '!'
-    0b00000000000000000000001111111001,  // '\"'
-    0b00000000000000000000111111111010,  // '#'
-    0b00000000000000000001111111111001,  // '$'
-    0b00000000000000000000000000010101,  // '%'
-    0b00000000000000000000000011111000,  // '&'
-    0b00000000000000000000011111111010,  // '\''
-    0b00000000000000000000001111111010,  // '('
-    0b00000000000000000000001111111011,  // ')'
-    0b00000000000000000000000011111001,  // '*'
-    0b00000000000000000000011111111011,  // '+'
-    0b00000000000000000000000011111010,  // ','
-    0b00000000000000000000000000010110,  // '-'
-    0b00000000000000000000000000010111,  // '.'
-    0b00000000000000000000000000011000,  // '/'
-    0b00000000000000000000000000000000,  // '0'
-    0b00000000000000000000000000000001,  // '1'
-    0b00000000000000000000000000000010,  // '2'
-    0b00000000000000000000000000011001,  // '3'
-    0b00000000000000000000000000011010,  // '4'
-    0b00000000000000000000000000011011,  // '5'
-    0b00000000000000000000000000011100,  // '6'
-    0b00000000000000000000000000011101,  // '7'
-    0b00000000000000000000000000011110,  // '8'
-    0b00000000000000000000000000011111,  // '9'
-    0b00000000000000000000000001011100,  // ':'
-    0b00000000000000000000000011111011,  // ';'
-    0b00000000000000000111111111111100,  // '<'
-    0b00000000000000000000000000100000,  // '='
-    0b00000000000000000000111111111011,  // '>'
-    0b00000000000000000000001111111100,  // '?'
-    0b00000000000000000001111111111010,  // '@'
-    0b00000000000000000000000000100001,  // 'A'
-    0b00000000000000000000000001011101,  // 'B'
-    0b00000000000000000000000001011110,  // 'C'
-    0b00000000000000000000000001011111,  // 'D'
-    0b00000000000000000000000001100000,  // 'E'
-    0b00000000000000000000000001100001,  // 'F'
-    0b00000000000000000000000001100010,  // 'G'
-    0b00000000000000000000000001100011,  // 'H'
-    0b00000000000000000000000001100100,  // 'I'
-    0b00000000000000000000000001100101,  // 'J'
-    0b00000000000000000000000001100110,  // 'K'
-    0b00000000000000000000000001100111,  // 'L'
-    0b00000000000000000000000001101000,  // 'M'
-    0b00000000000000000000000001101001,  // 'N'
-    0b00000000000000000000000001101010,  // 'O'
-    0b00000000000000000000000001101011,  // 'P'
-    0b00000000000000000000000001101100,  // 'Q'
-    0b00000000000000000000000001101101,  // 'R'
-    0b00000000000000000000000001101110,  // 'S'
-    0b00000000000000000000000001101111,  // 'T'
-    0b00000000000000000000000001110000,  // 'U'
-    0b00000000000000000000000001110001,  // 'V'
-    0b00000000000000000000000001110010,  // 'W'
-    0b00000000000000000000000011111100,  // 'X'
-    0b00000000000000000000000001110011,  // 'Y'
-    0b00000000000000000000000011111101,  // 'Z'
-    0b00000000000000000001111111111011,  // '['
-    0b00000000000001111111111111110000,  // '\\'
-    0b00000000000000000001111111111100,  // ']'
-    0b00000000000000000011111111111100,  // '^'
-    0b00000000000000000000000000100010,  // '_'
-    0b00000000000000000111111111111101,  // '`'
-    0b00000000000000000000000000000011,  // 'a'
-    0b00000000000000000000000000100011,  // 'b'
-    0b00000000000000000000000000000100,  // 'c'
-    0b00000000000000000000000000100100,  // 'd'
-    0b00000000000000000000000000000101,  // 'e'
-    0b00000000000000000000000000100101,  // 'f'
-    0b00000000000000000000000000100110,  // 'g'
-    0b00000000000000000000000000100111,  // 'h'
-    0b00000000000000000000000000000110,  // 'i'
-    0b00000000000000000000000001110100,  // 'j'
-    0b00000000000000000000000001110101,  // 'k'
-    0b00000000000000000000000000101000,  // 'l'
-    0b00000000000000000000000000101001,  // 'm'
-    0b00000000000000000000000000101010,  // 'n'
-    0b00000000000000000000000000000111,  // 'o'
-    0b00000000000000000000000000101011,  // 'p'
-    0b00000000000000000000000001110110,  // 'q'
-    0b00000000000000000000000000101100,  // 'r'
-    0b00000000000000000000000000001000,  // 's'
-    0b00000000000000000000000000001001,  // 't'
-    0b00000000000000000000000000101101,  // 'u'
-    0b00000000000000000000000001110111,  // 'v'
-    0b00000000000000000000000001111000,  // 'w'
-    0b00000000000000000000000001111001,  // 'x'
-    0b00000000000000000000000001111010,  // 'y'
-    0b00000000000000000000000001111011,  // 'z'
-    0b00000000000000000111111111111110,  // '{'
-    0b00000000000000000000011111111100,  // '|'
-    0b00000000000000000011111111111101,  // '}'
-    0b00000000000000000001111111111101,  // '~'
-    0b00001111111111111111111111111100,  // 0x7f
-    0b00000000000011111111111111100110,  // 0x80
-    0b00000000001111111111111111010010,  // 0x81
-    0b00000000000011111111111111100111,  // 0x82
-    0b00000000000011111111111111101000,  // 0x83
-    0b00000000001111111111111111010011,  // 0x84
-    0b00000000001111111111111111010100,  // 0x85
-    0b00000000001111111111111111010101,  // 0x86
-    0b00000000011111111111111111011001,  // 0x87
-    0b00000000001111111111111111010110,  // 0x88
-    0b00000000011111111111111111011010,  // 0x89
-    0b00000000011111111111111111011011,  // 0x8a
-    0b00000000011111111111111111011100,  // 0x8b
-    0b00000000011111111111111111011101,  // 0x8c
-    0b00000000011111111111111111011110,  // 0x8d
-    0b00000000111111111111111111101011,  // 0x8e
-    0b00000000011111111111111111011111,  // 0x8f
-    0b00000000111111111111111111101100,  // 0x90
-    0b00000000111111111111111111101101,  // 0x91
-    0b00000000001111111111111111010111,  // 0x92
-    0b00000000011111111111111111100000,  // 0x93
-    0b00000000111111111111111111101110,  // 0x94
-    0b00000000011111111111111111100001,  // 0x95
-    0b00000000011111111111111111100010,  // 0x96
-    0b00000000011111111111111111100011,  // 0x97
-    0b00000000011111111111111111100100,  // 0x98
-    0b00000000000111111111111111011100,  // 0x99
-    0b00000000001111111111111111011000,  // 0x9a
-    0b00000000011111111111111111100101,  // 0x9b
-    0b00000000001111111111111111011001,  // 0x9c
-    0b00000000011111111111111111100110,  // 0x9d
-    0b00000000011111111111111111100111,  // 0x9e
-    0b00000000111111111111111111101111,  // 0x9f
-    0b00000000001111111111111111011010,  // 0xa0
-    0b00000000000111111111111111011101,  // 0xa1
-    0b00000000000011111111111111101001,  // 0xa2
-    0b00000000001111111111111111011011,  // 0xa3
-    0b00000000001111111111111111011100,  // 0xa4
-    0b00000000011111111111111111101000,  // 0xa5
-    0b00000000011111111111111111101001,  // 0xa6
-    0b00000000000111111111111111011110,  // 0xa7
-    0b00000000011111111111111111101010,  // 0xa8
-    0b00000000001111111111111111011101,  // 0xa9
-    0b00000000001111111111111111011110,  // 0xaa
-    0b00000000111111111111111111110000,  // 0xab
-    0b00000000000111111111111111011111,  // 0xac
-    0b00000000001111111111111111011111,  // 0xad
-    0b00000000011111111111111111101011,  // 0xae
-    0b00000000011111111111111111101100,  // 0xaf
-    0b00000000000111111111111111100000,  // 0xb0
-    0b00000000000111111111111111100001,  // 0xb1
-    0b00000000001111111111111111100000,  // 0xb2
-    0b00000000000111111111111111100010,  // 0xb3
-    0b00000000011111111111111111101101,  // 0xb4
-    0b00000000001111111111111111100001,  // 0xb5
-    0b00000000011111111111111111101110,  // 0xb6
-    0b00000000011111111111111111101111,  // 0xb7
-    0b00000000000011111111111111101010,  // 0xb8
-    0b00000000001111111111111111100010,  // 0xb9
-    0b00000000001111111111111111100011,  // 0xba
-    0b00000000001111111111111111100100,  // 0xbb
-    0b00000000011111111111111111110000,  // 0xbc
-    0b00000000001111111111111111100101,  // 0xbd
-    0b00000000001111111111111111100110,  // 0xbe
-    0b00000000011111111111111111110001,  // 0xbf
-    0b00000011111111111111111111100000,  // 0xc0
-    0b00000011111111111111111111100001,  // 0xc1
-    0b00000000000011111111111111101011,  // 0xc2
-    0b00000000000001111111111111110001,  // 0xc3
-    0b00000000001111111111111111100111,  // 0xc4
-    0b00000000011111111111111111110010,  // 0xc5
-    0b00000000001111111111111111101000,  // 0xc6
-    0b00000001111111111111111111101100,  // 0xc7
-    0b00000011111111111111111111100010,  // 0xc8
-    0b00000011111111111111111111100011,  // 0xc9
-    0b00000011111111111111111111100100,  // 0xca
-    0b00000111111111111111111111011110,  // 0xcb
-    0b00000111111111111111111111011111,  // 0xcc
-    0b00000011111111111111111111100101,  // 0xcd
-    0b00000000111111111111111111110001,  // 0xce
-    0b00000001111111111111111111101101,  // 0xcf
-    0b00000000000001111111111111110010,  // 0xd0
-    0b00000000000111111111111111100011,  // 0xd1
-    0b00000011111111111111111111100110,  // 0xd2
-    0b00000111111111111111111111100000,  // 0xd3
-    0b00000111111111111111111111100001,  // 0xd4
-    0b00000011111111111111111111100111,  // 0xd5
-    0b00000111111111111111111111100010,  // 0xd6
-    0b00000000111111111111111111110010,  // 0xd7
-    0b00000000000111111111111111100100,  // 0xd8
-    0b00000000000111111111111111100101,  // 0xd9
-    0b00000011111111111111111111101000,  // 0xda
-    0b00000011111111111111111111101001,  // 0xdb
-    0b00001111111111111111111111111101,  // 0xdc
-    0b00000111111111111111111111100011,  // 0xdd
-    0b00000111111111111111111111100100,  // 0xde
-    0b00000111111111111111111111100101,  // 0xdf
-    0b00000000000011111111111111101100,  // 0xe0
-    0b00000000111111111111111111110011,  // 0xe1
-    0b00000000000011111111111111101101,  // 0xe2
-    0b00000000000111111111111111100110,  // 0xe3
-    0b00000000001111111111111111101001,  // 0xe4
-    0b00000000000111111111111111100111,  // 0xe5
-    0b00000000000111111111111111101000,  // 0xe6
-    0b00000000011111111111111111110011,  // 0xe7
-    0b00000000001111111111111111101010,  // 0xe8
-    0b00000000001111111111111111101011,  // 0xe9
-    0b00000001111111111111111111101110,  // 0xea
-    0b00000001111111111111111111101111,  // 0xeb
-    0b00000000111111111111111111110100,  // 0xec
-    0b00000000111111111111111111110101,  // 0xed
-    0b00000011111111111111111111101010,  // 0xee
-    0b00000000011111111111111111110100,  // 0xef
-    0b00000011111111111111111111101011,  // 0xf0
-    0b00000111111111111111111111100110,  // 0xf1
-    0b00000011111111111111111111101100,  // 0xf2
-    0b00000011111111111111111111101101,  // 0xf3
-    0b00000111111111111111111111100111,  // 0xf4
-    0b00000111111111111111111111101000,  // 0xf5
-    0b00000111111111111111111111101001,  // 0xf6
-    0b00000111111111111111111111101010,  // 0xf7
-    0b00000111111111111111111111101011,  // 0xf8
-    0b00001111111111111111111111111110,  // 0xf9
-    0b00000111111111111111111111101100,  // 0xfa
-    0b00000111111111111111111111101101,  // 0xfb
-    0b00000111111111111111111111101110,  // 0xfc
-    0b00000111111111111111111111101111,  // 0xfd
-    0b00000111111111111111111111110000,  // 0xfe
-    0b00000011111111111111111111101110,  // 0xff
-    0b00111111111111111111111111111111,  // 0x100
-};
-// clang-format off
-
-}  // namespace http2
diff --git a/http2/hpack/tools/hpack_block_builder.cc b/http2/hpack/tools/hpack_block_builder.cc
deleted file mode 100644
index 3dbda95..0000000
--- a/http2/hpack/tools/hpack_block_builder.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/tools/hpack_block_builder.h"
-
-#include "http2/hpack/varint/hpack_varint_encoder.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-void HpackBlockBuilder::AppendHighBitsAndVarint(uint8_t high_bits,
-                                                uint8_t prefix_length,
-                                                uint64_t varint) {
-  EXPECT_LE(3, prefix_length);
-  EXPECT_LE(prefix_length, 8);
-
-  HpackVarintEncoder::Encode(high_bits, prefix_length, varint, &buffer_);
-}
-
-void HpackBlockBuilder::AppendEntryTypeAndVarint(HpackEntryType entry_type,
-                                                 uint64_t varint) {
-  uint8_t high_bits;
-  uint8_t prefix_length;  // Bits of the varint prefix in the first byte.
-  switch (entry_type) {
-    case HpackEntryType::kIndexedHeader:
-      high_bits = 0x80;
-      prefix_length = 7;
-      break;
-    case HpackEntryType::kDynamicTableSizeUpdate:
-      high_bits = 0x20;
-      prefix_length = 5;
-      break;
-    case HpackEntryType::kIndexedLiteralHeader:
-      high_bits = 0x40;
-      prefix_length = 6;
-      break;
-    case HpackEntryType::kUnindexedLiteralHeader:
-      high_bits = 0x00;
-      prefix_length = 4;
-      break;
-    case HpackEntryType::kNeverIndexedLiteralHeader:
-      high_bits = 0x10;
-      prefix_length = 4;
-      break;
-    default:
-      HTTP2_BUG(http2_bug_110_1) << "Unreached, entry_type=" << entry_type;
-      high_bits = 0;
-      prefix_length = 0;
-      break;
-  }
-  AppendHighBitsAndVarint(high_bits, prefix_length, varint);
-}
-
-void HpackBlockBuilder::AppendString(bool is_huffman_encoded,
-                                     absl::string_view str) {
-  uint8_t high_bits = is_huffman_encoded ? 0x80 : 0;
-  uint8_t prefix_length = 7;
-  AppendHighBitsAndVarint(high_bits, prefix_length, str.size());
-  buffer_.append(str.data(), str.size());
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/tools/hpack_block_builder.h b/http2/hpack/tools/hpack_block_builder.h
deleted file mode 100644
index 079f823..0000000
--- a/http2/hpack/tools/hpack_block_builder.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
-#define QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
-
-// HpackBlockBuilder builds wire-format HPACK blocks (or fragments thereof)
-// from components.
-
-// Supports very large varints to enable tests to create HPACK blocks with
-// values that the decoder should reject. For now, this is only intended for
-// use in tests, and thus has EXPECT* in the code. If desired to use it in an
-// encoder, it will need optimization work, especially w.r.t memory mgmt, and
-// the EXPECT* will need to be removed or replaced with QUICHE_DCHECKs. And of
-// course the support for very large varints will not be needed in production
-// code.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class HpackBlockBuilder {
- public:
-  explicit HpackBlockBuilder(absl::string_view initial_contents)
-      : buffer_(initial_contents.data(), initial_contents.size()) {}
-  HpackBlockBuilder() {}
-  ~HpackBlockBuilder() {}
-
-  size_t size() const { return buffer_.size(); }
-  const std::string& buffer() const { return buffer_; }
-
-  //----------------------------------------------------------------------------
-  // Methods for appending a valid HPACK entry.
-
-  void AppendIndexedHeader(uint64_t index) {
-    AppendEntryTypeAndVarint(HpackEntryType::kIndexedHeader, index);
-  }
-
-  void AppendDynamicTableSizeUpdate(uint64_t size) {
-    AppendEntryTypeAndVarint(HpackEntryType::kDynamicTableSizeUpdate, size);
-  }
-
-  void AppendNameIndexAndLiteralValue(HpackEntryType entry_type,
-                                      uint64_t name_index,
-                                      bool value_is_huffman_encoded,
-                                      absl::string_view value) {
-    // name_index==0 would indicate that the entry includes a literal name.
-    // Call AppendLiteralNameAndValue in that case.
-    EXPECT_NE(0u, name_index);
-    AppendEntryTypeAndVarint(entry_type, name_index);
-    AppendString(value_is_huffman_encoded, value);
-  }
-
-  void AppendLiteralNameAndValue(HpackEntryType entry_type,
-                                 bool name_is_huffman_encoded,
-                                 absl::string_view name,
-                                 bool value_is_huffman_encoded,
-                                 absl::string_view value) {
-    AppendEntryTypeAndVarint(entry_type, 0);
-    AppendString(name_is_huffman_encoded, name);
-    AppendString(value_is_huffman_encoded, value);
-  }
-
-  //----------------------------------------------------------------------------
-  // Primitive methods that are not guaranteed to write a valid HPACK entry.
-
-  // Appends a varint, with the specified high_bits above the prefix of the
-  // varint.
-  void AppendHighBitsAndVarint(uint8_t high_bits,
-                               uint8_t prefix_length,
-                               uint64_t varint);
-
-  // Append the start of an HPACK entry for the specified type, with the
-  // specified varint.
-  void AppendEntryTypeAndVarint(HpackEntryType entry_type, uint64_t varint);
-
-  // Append a header string (i.e. a header name or value) in HPACK format.
-  // Does NOT perform Huffman encoding.
-  void AppendString(bool is_huffman_encoded, absl::string_view str);
-
- private:
-  std::string buffer_;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
diff --git a/http2/hpack/tools/hpack_block_builder_test.cc b/http2/hpack/tools/hpack_block_builder_test.cc
deleted file mode 100644
index b292c4b..0000000
--- a/http2/hpack/tools/hpack_block_builder_test.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/tools/hpack_block_builder.h"
-
-#include "absl/strings/escaping.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-const bool kUncompressed = false;
-const bool kCompressed = true;
-
-// TODO(jamessynge): Once static table code is checked in, switch to using
-// constants from there.
-const uint32_t kStaticTableMethodGET = 2;
-const uint32_t kStaticTablePathSlash = 4;
-const uint32_t kStaticTableSchemeHttp = 6;
-
-// Tests of encoding per the RFC. See:
-//   http://httpwg.org/specs/rfc7541.html#header.field.representation.examples
-// The expected values have been copied from the RFC.
-TEST(HpackBlockBuilderTest, ExamplesFromSpecC2) {
-  {
-    HpackBlockBuilder b;
-    b.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader,
-                                kUncompressed, "custom-key", kUncompressed,
-                                "custom-header");
-    EXPECT_EQ(26u, b.size());
-
-    const char kExpected[] =
-        "\x40"            // == Literal indexed ==
-        "\x0a"            // Name length (10)
-        "custom-key"      // Name
-        "\x0d"            // Value length (13)
-        "custom-header";  // Value
-    EXPECT_EQ(kExpected, b.buffer());
-  }
-  {
-    HpackBlockBuilder b;
-    b.AppendNameIndexAndLiteralValue(HpackEntryType::kUnindexedLiteralHeader, 4,
-                                     kUncompressed, "/sample/path");
-    EXPECT_EQ(14u, b.size());
-
-    const char kExpected[] =
-        "\x04"           // == Literal unindexed, name index 0x04 ==
-        "\x0c"           // Value length (12)
-        "/sample/path";  // Value
-    EXPECT_EQ(kExpected, b.buffer());
-  }
-  {
-    HpackBlockBuilder b;
-    b.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
-                                kUncompressed, "password", kUncompressed,
-                                "secret");
-    EXPECT_EQ(17u, b.size());
-
-    const char kExpected[] =
-        "\x10"      // == Literal never indexed ==
-        "\x08"      // Name length (8)
-        "password"  // Name
-        "\x06"      // Value length (6)
-        "secret";   // Value
-    EXPECT_EQ(kExpected, b.buffer());
-  }
-  {
-    HpackBlockBuilder b;
-    b.AppendIndexedHeader(2);
-    EXPECT_EQ(1u, b.size());
-
-    const char kExpected[] = "\x82";  // == Indexed (2) ==
-    EXPECT_EQ(kExpected, b.buffer());
-  }
-}
-
-// Tests of encoding per the RFC. See:
-//  http://httpwg.org/specs/rfc7541.html#request.examples.without.huffman.coding
-TEST(HpackBlockBuilderTest, ExamplesFromSpecC3) {
-  {
-    // Header block to encode:
-    //   :method: GET
-    //   :scheme: http
-    //   :path: /
-    //   :authority: www.example.com
-    HpackBlockBuilder b;
-    b.AppendIndexedHeader(2);  // :method: GET
-    b.AppendIndexedHeader(6);  // :scheme: http
-    b.AppendIndexedHeader(4);  // :path: /
-    b.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 1,
-                                     kUncompressed, "www.example.com");
-    EXPECT_EQ(20u, b.size());
-
-    // Hex dump of encoded data (copied from RFC):
-    // 0x0000:  8286 8441 0f77 7777 2e65 7861 6d70 6c65  ...A.www.example
-    // 0x0010:  2e63 6f6d                                .com
-
-    const std::string expected =
-        absl::HexStringToBytes("828684410f7777772e6578616d706c652e636f6d");
-    EXPECT_EQ(expected, b.buffer());
-  }
-}
-
-// Tests of encoding per the RFC. See:
-//   http://httpwg.org/specs/rfc7541.html#request.examples.with.huffman.coding
-TEST(HpackBlockBuilderTest, ExamplesFromSpecC4) {
-  {
-    // Header block to encode:
-    //   :method: GET
-    //   :scheme: http
-    //   :path: /
-    //   :authority: www.example.com  (Huffman encoded)
-    HpackBlockBuilder b;
-    b.AppendIndexedHeader(kStaticTableMethodGET);
-    b.AppendIndexedHeader(kStaticTableSchemeHttp);
-    b.AppendIndexedHeader(kStaticTablePathSlash);
-    const char kHuffmanWwwExampleCom[] = {'\xf1', '\xe3', '\xc2', '\xe5',
-                                          '\xf2', '\x3a', '\x6b', '\xa0',
-                                          '\xab', '\x90', '\xf4', '\xff'};
-    b.AppendNameIndexAndLiteralValue(
-        HpackEntryType::kIndexedLiteralHeader, 1, kCompressed,
-        absl::string_view(kHuffmanWwwExampleCom, sizeof kHuffmanWwwExampleCom));
-    EXPECT_EQ(17u, b.size());
-
-    // Hex dump of encoded data (copied from RFC):
-    // 0x0000:  8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4  ...A......:k....
-    // 0x0010:  ff                                       .
-
-    const std::string expected =
-        absl::HexStringToBytes("828684418cf1e3c2e5f23a6ba0ab90f4ff");
-    EXPECT_EQ(expected, b.buffer());
-  }
-}
-
-TEST(HpackBlockBuilderTest, DynamicTableSizeUpdate) {
-  {
-    HpackBlockBuilder b;
-    b.AppendDynamicTableSizeUpdate(0);
-    EXPECT_EQ(1u, b.size());
-
-    const char kData[] = {'\x20'};
-    absl::string_view expected(kData, sizeof kData);
-    EXPECT_EQ(expected, b.buffer());
-  }
-  {
-    HpackBlockBuilder b;
-    b.AppendDynamicTableSizeUpdate(4096);  // The default size.
-    EXPECT_EQ(3u, b.size());
-
-    const char kData[] = {'\x3f', '\xe1', '\x1f'};
-    absl::string_view expected(kData, sizeof kData);
-    EXPECT_EQ(expected, b.buffer());
-  }
-  {
-    HpackBlockBuilder b;
-    b.AppendDynamicTableSizeUpdate(1000000000000);  // A very large value.
-    EXPECT_EQ(7u, b.size());
-
-    const char kData[] = {'\x3f', '\xe1', '\x9f', '\x94',
-                          '\xa5', '\x8d', '\x1d'};
-    absl::string_view expected(kData, sizeof kData);
-    EXPECT_EQ(expected, b.buffer());
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/tools/hpack_example.cc b/http2/hpack/tools/hpack_example.cc
deleted file mode 100644
index 64255b1..0000000
--- a/http2/hpack/tools/hpack_example.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/tools/hpack_example.h"
-
-#include <ctype.h>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "http2/platform/api/http2_bug_tracker.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-void HpackExampleToStringOrDie(absl::string_view example, std::string* output) {
-  while (!example.empty()) {
-    const char c0 = example[0];
-    if (isxdigit(c0)) {
-      QUICHE_CHECK_GT(example.size(), 1u) << "Truncated hex byte?";
-      const char c1 = example[1];
-      QUICHE_CHECK(isxdigit(c1)) << "Found half a byte?";
-      *output += absl::HexStringToBytes(example.substr(0, 2));
-      example.remove_prefix(2);
-      continue;
-    }
-    if (isspace(c0)) {
-      example.remove_prefix(1);
-      continue;
-    }
-    if (!example.empty() && example[0] == '|') {
-      // Start of a comment. Skip to end of line or of input.
-      auto pos = example.find('\n');
-      if (pos == absl::string_view::npos) {
-        // End of input.
-        break;
-      }
-      example.remove_prefix(pos + 1);
-      continue;
-    }
-    HTTP2_BUG(http2_bug_107_1)
-        << "Can't parse byte " << static_cast<int>(c0)
-        << absl::StrCat(" (0x", absl::Hex(c0), ")") << "\nExample: " << example;
-  }
-  QUICHE_CHECK_LT(0u, output->size()) << "Example is empty.";
-}
-
-}  // namespace
-
-std::string HpackExampleToStringOrDie(absl::string_view example) {
-  std::string output;
-  HpackExampleToStringOrDie(example, &output);
-  return output;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/varint/hpack_varint_decoder.cc b/http2/hpack/varint/hpack_varint_decoder.cc
deleted file mode 100644
index a9e6e74..0000000
--- a/http2/hpack/varint/hpack_varint_decoder.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-
-#include "absl/strings/str_cat.h"
-
-namespace http2 {
-
-DecodeStatus HpackVarintDecoder::Start(uint8_t prefix_value,
-                                       uint8_t prefix_length,
-                                       DecodeBuffer* db) {
-  QUICHE_DCHECK_LE(3u, prefix_length);
-  QUICHE_DCHECK_LE(prefix_length, 8u);
-
-  // |prefix_mask| defines the sequence of low-order bits of the first byte
-  // that encode the prefix of the value. It is also the marker in those bits
-  // of the first byte indicating that at least one extension byte is needed.
-  const uint8_t prefix_mask = (1 << prefix_length) - 1;
-
-  // Ignore the bits that aren't a part of the prefix of the varint.
-  value_ = prefix_value & prefix_mask;
-
-  if (value_ < prefix_mask) {
-    MarkDone();
-    return DecodeStatus::kDecodeDone;
-  }
-
-  offset_ = 0;
-  return Resume(db);
-}
-
-DecodeStatus HpackVarintDecoder::StartExtended(uint8_t prefix_length,
-                                               DecodeBuffer* db) {
-  QUICHE_DCHECK_LE(3u, prefix_length);
-  QUICHE_DCHECK_LE(prefix_length, 8u);
-
-  value_ = (1 << prefix_length) - 1;
-  offset_ = 0;
-  return Resume(db);
-}
-
-DecodeStatus HpackVarintDecoder::Resume(DecodeBuffer* db) {
-  // There can be at most 10 continuation bytes.  Offset is zero for the
-  // first one and increases by 7 for each subsequent one.
-  const uint8_t kMaxOffset = 63;
-  CheckNotDone();
-
-  // Process most extension bytes without the need for overflow checking.
-  while (offset_ < kMaxOffset) {
-    if (db->Empty()) {
-      return DecodeStatus::kDecodeInProgress;
-    }
-
-    uint8_t byte = db->DecodeUInt8();
-    uint64_t summand = byte & 0x7f;
-
-    // Shifting a 7 bit value to the left by at most 56 places can never
-    // overflow on uint64_t.
-    QUICHE_DCHECK_LE(offset_, 56);
-    QUICHE_DCHECK_LE(summand, std::numeric_limits<uint64_t>::max() >> offset_);
-
-    summand <<= offset_;
-
-    // At this point,
-    // |value_| is at most (2^prefix_length - 1) + (2^49 - 1), and
-    // |summand| is at most 255 << 56 (which is smaller than 2^63),
-    // so adding them can never overflow on uint64_t.
-    QUICHE_DCHECK_LE(value_, std::numeric_limits<uint64_t>::max() - summand);
-
-    value_ += summand;
-
-    // Decoding ends if continuation flag is not set.
-    if ((byte & 0x80) == 0) {
-      MarkDone();
-      return DecodeStatus::kDecodeDone;
-    }
-
-    offset_ += 7;
-  }
-
-  if (db->Empty()) {
-    return DecodeStatus::kDecodeInProgress;
-  }
-
-  QUICHE_DCHECK_EQ(kMaxOffset, offset_);
-
-  uint8_t byte = db->DecodeUInt8();
-  // No more extension bytes are allowed after this.
-  if ((byte & 0x80) == 0) {
-    uint64_t summand = byte & 0x7f;
-    // Check for overflow in left shift.
-    if (summand <= std::numeric_limits<uint64_t>::max() >> offset_) {
-      summand <<= offset_;
-      // Check for overflow in addition.
-      if (value_ <= std::numeric_limits<uint64_t>::max() - summand) {
-        value_ += summand;
-        MarkDone();
-        return DecodeStatus::kDecodeDone;
-      }
-    }
-  }
-
-  // Signal error if value is too large or there are too many extension bytes.
-  HTTP2_DLOG(WARNING)
-      << "Variable length int encoding is too large or too long. "
-      << DebugString();
-  MarkDone();
-  return DecodeStatus::kDecodeError;
-}
-
-uint64_t HpackVarintDecoder::value() const {
-  CheckDone();
-  return value_;
-}
-
-void HpackVarintDecoder::set_value(uint64_t v) {
-  MarkDone();
-  value_ = v;
-}
-
-std::string HpackVarintDecoder::DebugString() const {
-  return absl::StrCat("HpackVarintDecoder(value=", value_, ", offset=", offset_,
-                      ")");
-}
-
-DecodeStatus HpackVarintDecoder::StartForTest(uint8_t prefix_value,
-                                              uint8_t prefix_length,
-                                              DecodeBuffer* db) {
-  return Start(prefix_value, prefix_length, db);
-}
-
-DecodeStatus HpackVarintDecoder::StartExtendedForTest(uint8_t prefix_length,
-                                                      DecodeBuffer* db) {
-  return StartExtended(prefix_length, db);
-}
-
-DecodeStatus HpackVarintDecoder::ResumeForTest(DecodeBuffer* db) {
-  return Resume(db);
-}
-
-}  // namespace http2
diff --git a/http2/hpack/varint/hpack_varint_decoder.h b/http2/hpack/varint/hpack_varint_decoder.h
deleted file mode 100644
index 7de72ba..0000000
--- a/http2/hpack/varint/hpack_varint_decoder.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// HpackVarintDecoder decodes HPACK variable length unsigned integers. In HPACK,
-// these integers are used to identify static or dynamic table index entries, to
-// specify string lengths, and to update the size limit of the dynamic table.
-// In QPACK, in addition to these uses, these integers also identify streams.
-//
-// The caller will need to validate that the decoded value is in an acceptable
-// range.
-//
-// For details of the encoding, see:
-//        http://httpwg.org/specs/rfc7541.html#integer.representation
-//
-// HpackVarintDecoder supports decoding any integer that can be represented on
-// uint64_t, thereby exceeding the requirements for QPACK: "QPACK
-// implementations MUST be able to decode integers up to 62 bits long."  See
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.1.1
-//
-// This decoder supports at most 10 extension bytes (bytes following the prefix,
-// also called continuation bytes).  An encoder is allowed to zero pad the
-// encoded integer on the left, thereby increasing the number of extension
-// bytes.  If an encoder uses so much padding that the number of extension bytes
-// exceeds the limit, then this decoder signals an error.
-
-#ifndef QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_DECODER_H_
-#define QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_DECODER_H_
-
-#include <cstdint>
-#include <limits>
-#include <string>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// Sentinel value for |HpackVarintDecoder::offset_| to signify that decoding is
-// completed.  Only used in debug builds.
-#ifndef NDEBUG
-const uint8_t kHpackVarintDecoderOffsetDone =
-    std::numeric_limits<uint8_t>::max();
-#endif
-
-// Decodes an HPACK variable length unsigned integer, in a resumable fashion
-// so it can handle running out of input in the DecodeBuffer. Call Start or
-// StartExtended the first time (when decoding the byte that contains the
-// prefix), then call Resume later if it is necessary to resume. When done,
-// call value() to retrieve the decoded value.
-//
-// No constructor or destructor. Holds no resources, so destruction isn't
-// needed. Start and StartExtended handles the initialization of member
-// variables. This is necessary in order for HpackVarintDecoder to be part
-// of a union.
-class QUICHE_EXPORT_PRIVATE HpackVarintDecoder {
- public:
-  // |prefix_value| is the first byte of the encoded varint.
-  // |prefix_length| is number of bits in the first byte that are used for
-  // encoding the integer.  |db| is the rest of the buffer,  that is, not
-  // including the first byte.
-  DecodeStatus Start(uint8_t prefix_value,
-                     uint8_t prefix_length,
-                     DecodeBuffer* db);
-
-  // The caller has already determined that the encoding requires multiple
-  // bytes, i.e. that the 3 to 8 low-order bits (the number determined by
-  // |prefix_length|) of the first byte are are all 1.  |db| is the rest of the
-  // buffer,  that is, not including the first byte.
-  DecodeStatus StartExtended(uint8_t prefix_length, DecodeBuffer* db);
-
-  // Resume decoding a variable length integer after an earlier
-  // call to Start or StartExtended returned kDecodeInProgress.
-  DecodeStatus Resume(DecodeBuffer* db);
-
-  uint64_t value() const;
-
-  // This supports optimizations for the case of a varint with zero extension
-  // bytes, where the handling of the prefix is done by the caller.
-  void set_value(uint64_t v);
-
-  // All the public methods below are for supporting assertions and tests.
-
-  std::string DebugString() const;
-
-  // For benchmarking, these methods ensure the decoder
-  // is NOT inlined into the caller.
-  DecodeStatus StartForTest(uint8_t prefix_value,
-                            uint8_t prefix_length,
-                            DecodeBuffer* db);
-  DecodeStatus StartExtendedForTest(uint8_t prefix_length, DecodeBuffer* db);
-  DecodeStatus ResumeForTest(DecodeBuffer* db);
-
- private:
-  // Protection in case Resume is called when it shouldn't be.
-  void MarkDone() {
-#ifndef NDEBUG
-    offset_ = kHpackVarintDecoderOffsetDone;
-#endif
-  }
-  void CheckNotDone() const {
-#ifndef NDEBUG
-    QUICHE_DCHECK_NE(kHpackVarintDecoderOffsetDone, offset_);
-#endif
-  }
-  void CheckDone() const {
-#ifndef NDEBUG
-    QUICHE_DCHECK_EQ(kHpackVarintDecoderOffsetDone, offset_);
-#endif
-  }
-
-  // These fields are initialized just to keep ASAN happy about reading
-  // them from DebugString().
-
-  // The encoded integer is being accumulated in |value_|.  When decoding is
-  // complete, |value_| holds the result.
-  uint64_t value_ = 0;
-
-  // Each extension byte encodes in its lowest 7 bits a segment of the integer.
-  // |offset_| is the number of places this segment has to be shifted to the
-  // left for decoding.  It is zero for the first extension byte, and increases
-  // by 7 for each subsequent extension byte.
-  uint8_t offset_ = 0;
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_DECODER_H_
diff --git a/http2/hpack/varint/hpack_varint_decoder_test.cc b/http2/hpack/varint/hpack_varint_decoder_test.cc
deleted file mode 100644
index d204b33..0000000
--- a/http2/hpack/varint/hpack_varint_decoder_test.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-
-// Test HpackVarintDecoder against hardcoded data.
-
-#include <stddef.h>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-namespace {
-
-class HpackVarintDecoderTest
-    : public RandomDecoderTest,
-      public ::testing::WithParamInterface<std::tuple<uint8_t, const char*>> {
- protected:
-  HpackVarintDecoderTest()
-      : high_bits_(std::get<0>(GetParam())),
-        suffix_(absl::HexStringToBytes(std::get<1>(GetParam()))),
-        prefix_length_(0) {}
-
-  void DecodeExpectSuccess(absl::string_view data,
-                           uint32_t prefix_length,
-                           uint64_t expected_value) {
-    Validator validator = [expected_value, this](
-                              const DecodeBuffer& /*db*/,
-                              DecodeStatus /*status*/) -> AssertionResult {
-      VERIFY_EQ(expected_value, decoder_.value())
-          << "Value doesn't match expected: " << decoder_.value()
-          << " != " << expected_value;
-      return AssertionSuccess();
-    };
-
-    // First validate that decoding is done and that we've advanced the cursor
-    // the expected amount.
-    validator = ValidateDoneAndOffset(/* offset = */ data.size(), validator);
-
-    EXPECT_TRUE(Decode(data, prefix_length, validator));
-
-    EXPECT_EQ(expected_value, decoder_.value());
-  }
-
-  void DecodeExpectError(absl::string_view data, uint32_t prefix_length) {
-    Validator validator = [](const DecodeBuffer& /*db*/,
-                             DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(DecodeStatus::kDecodeError, status);
-      return AssertionSuccess();
-    };
-
-    EXPECT_TRUE(Decode(data, prefix_length, validator));
-  }
-
- private:
-  AssertionResult Decode(absl::string_view data,
-                         uint32_t prefix_length,
-                         const Validator validator) {
-    prefix_length_ = prefix_length;
-
-    // Copy |data| so that it can be modified.
-    std::string data_copy(data);
-
-    // Bits of the first byte not part of the prefix should be ignored.
-    uint8_t high_bits_mask = 0b11111111 << prefix_length_;
-    data_copy[0] |= (high_bits_mask & high_bits_);
-
-    // Extra bytes appended to the input should be ignored.
-    data_copy.append(suffix_);
-
-    DecodeBuffer b(data_copy);
-
-    // StartDecoding, above, requires the DecodeBuffer be non-empty so that it
-    // can call Start with the prefix byte.
-    bool return_non_zero_on_first = true;
-
-    return DecodeAndValidateSeveralWays(&b, return_non_zero_on_first,
-                                        validator);
-  }
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    QUICHE_CHECK_LT(0u, b->Remaining());
-    uint8_t prefix = b->DecodeUInt8();
-    return decoder_.Start(prefix, prefix_length_, b);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    return decoder_.Resume(b);
-  }
-
-  // Bits of the first byte not part of the prefix.
-  const uint8_t high_bits_;
-  // Extra bytes appended to the input.
-  const std::string suffix_;
-
-  HpackVarintDecoder decoder_;
-  uint8_t prefix_length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    HpackVarintDecoderTest,
-    HpackVarintDecoderTest,
-    ::testing::Combine(
-        // Bits of the first byte not part of the prefix should be ignored.
-        ::testing::Values(0b00000000, 0b11111111, 0b10101010),
-        // Extra bytes appended to the input should be ignored.
-        ::testing::Values("", "00", "666f6f")));
-
-struct {
-  const char* data;
-  uint32_t prefix_length;
-  uint64_t expected_value;
-} kSuccessTestData[] = {
-    // Zero value with different prefix lengths.
-    {"00", 3, 0},
-    {"00", 4, 0},
-    {"00", 5, 0},
-    {"00", 6, 0},
-    {"00", 7, 0},
-    {"00", 8, 0},
-    // Small values that fit in the prefix.
-    {"06", 3, 6},
-    {"0d", 4, 13},
-    {"10", 5, 16},
-    {"29", 6, 41},
-    {"56", 7, 86},
-    {"bf", 8, 191},
-    // Values of 2^n-1, which have an all-zero extension byte.
-    {"0700", 3, 7},
-    {"0f00", 4, 15},
-    {"1f00", 5, 31},
-    {"3f00", 6, 63},
-    {"7f00", 7, 127},
-    {"ff00", 8, 255},
-    // Values of 2^n-1, plus one extra byte of padding.
-    {"078000", 3, 7},
-    {"0f8000", 4, 15},
-    {"1f8000", 5, 31},
-    {"3f8000", 6, 63},
-    {"7f8000", 7, 127},
-    {"ff8000", 8, 255},
-    // Values requiring one extension byte.
-    {"0760", 3, 103},
-    {"0f2a", 4, 57},
-    {"1f7f", 5, 158},
-    {"3f02", 6, 65},
-    {"7f49", 7, 200},
-    {"ff6f", 8, 366},
-    // Values requiring one extension byte, plus one byte of padding.
-    {"07e000", 3, 103},
-    {"0faa00", 4, 57},
-    {"1fff00", 5, 158},
-    {"3f8200", 6, 65},
-    {"7fc900", 7, 200},
-    {"ffef00", 8, 366},
-    // Values requiring one extension byte, plus two bytes of padding.
-    {"07e08000", 3, 103},
-    {"0faa8000", 4, 57},
-    {"1fff8000", 5, 158},
-    {"3f828000", 6, 65},
-    {"7fc98000", 7, 200},
-    {"ffef8000", 8, 366},
-    // Values requiring one extension byte, plus the maximum amount of padding.
-    {"07e0808080808080808000", 3, 103},
-    {"0faa808080808080808000", 4, 57},
-    {"1fff808080808080808000", 5, 158},
-    {"3f82808080808080808000", 6, 65},
-    {"7fc9808080808080808000", 7, 200},
-    {"ffef808080808080808000", 8, 366},
-    // Values requiring two extension bytes.
-    {"07b260", 3, 12345},
-    {"0f8a2a", 4, 5401},
-    {"1fa87f", 5, 16327},
-    {"3fd002", 6, 399},
-    {"7fff49", 7, 9598},
-    {"ffe32f", 8, 6370},
-    // Values requiring two extension bytes, plus one byte of padding.
-    {"07b2e000", 3, 12345},
-    {"0f8aaa00", 4, 5401},
-    {"1fa8ff00", 5, 16327},
-    {"3fd08200", 6, 399},
-    {"7fffc900", 7, 9598},
-    {"ffe3af00", 8, 6370},
-    // Values requiring two extension bytes, plus the maximum amount of padding.
-    {"07b2e080808080808000", 3, 12345},
-    {"0f8aaa80808080808000", 4, 5401},
-    {"1fa8ff80808080808000", 5, 16327},
-    {"3fd08280808080808000", 6, 399},
-    {"7fffc980808080808000", 7, 9598},
-    {"ffe3af80808080808000", 8, 6370},
-    // Values requiring three extension bytes.
-    {"078ab260", 3, 1579281},
-    {"0fc18a2a", 4, 689488},
-    {"1fada87f", 5, 2085964},
-    {"3fa0d002", 6, 43103},
-    {"7ffeff49", 7, 1212541},
-    {"ff93de23", 8, 585746},
-    // Values requiring three extension bytes, plus one byte of padding.
-    {"078ab2e000", 3, 1579281},
-    {"0fc18aaa00", 4, 689488},
-    {"1fada8ff00", 5, 2085964},
-    {"3fa0d08200", 6, 43103},
-    {"7ffeffc900", 7, 1212541},
-    {"ff93dea300", 8, 585746},
-    // Values requiring four extension bytes.
-    {"079f8ab260", 3, 202147110},
-    {"0fa2c18a2a", 4, 88252593},
-    {"1fd0ada87f", 5, 266999535},
-    {"3ff9a0d002", 6, 5509304},
-    {"7f9efeff49", 7, 155189149},
-    {"ffaa82f404", 8, 10289705},
-    // Values requiring four extension bytes, plus one byte of padding.
-    {"079f8ab2e000", 3, 202147110},
-    {"0fa2c18aaa00", 4, 88252593},
-    {"1fd0ada8ff00", 5, 266999535},
-    {"3ff9a0d08200", 6, 5509304},
-    {"7f9efeffc900", 7, 155189149},
-    {"ffaa82f48400", 8, 10289705},
-    // Values requiring six extension bytes.
-    {"0783aa9f8ab260", 3, 3311978140938},
-    {"0ff0b0a2c18a2a", 4, 1445930244223},
-    {"1fda84d0ada87f", 5, 4374519874169},
-    {"3fb5fbf9a0d002", 6, 90263420404},
-    {"7fcff19efeff49", 7, 2542616951118},
-    {"ff9fa486bbc327", 8, 1358138807070},
-    // Values requiring eight extension bytes.
-    {"07f19883aa9f8ab260", 3, 54263449861016696},
-    {"0f84fdf0b0a2c18a2a", 4, 23690121121119891},
-    {"1fa0dfda84d0ada87f", 5, 71672133617889215},
-    {"3f9ff0b5fbf9a0d002", 6, 1478875878881374},
-    {"7ffbc1cff19efeff49", 7, 41658236125045114},
-    {"ff91b6fb85af99c342", 8, 37450237664484368},
-    // Values requiring ten extension bytes.
-    {"0794f1f19883aa9f8ab201", 3, 12832019021693745307u},
-    {"0fa08f84fdf0b0a2c18a01", 4, 9980690937382242223u},
-    {"1fbfdda0dfda84d0ada801", 5, 12131360551794650846u},
-    {"3f9dc79ff0b5fbf9a0d001", 6, 15006530362736632796u},
-    {"7f8790fbc1cff19efeff01", 7, 18445754019193211014u},
-    {"fffba8c5b8d3fe9f8c8401", 8, 9518498503615141242u},
-    // Maximum value: 2^64-1.
-    {"07f8ffffffffffffffff01", 3, 18446744073709551615u},
-    {"0ff0ffffffffffffffff01", 4, 18446744073709551615u},
-    {"1fe0ffffffffffffffff01", 5, 18446744073709551615u},
-    {"3fc0ffffffffffffffff01", 6, 18446744073709551615u},
-    {"7f80ffffffffffffffff01", 7, 18446744073709551615u},
-    {"ff80feffffffffffffff01", 8, 18446744073709551615u},
-    // Examples from RFC7541 C.1.
-    {"0a", 5, 10},
-    {"1f9a0a", 5, 1337},
-};
-
-TEST_P(HpackVarintDecoderTest, Success) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kSuccessTestData); ++i) {
-    DecodeExpectSuccess(absl::HexStringToBytes(kSuccessTestData[i].data),
-                        kSuccessTestData[i].prefix_length,
-                        kSuccessTestData[i].expected_value);
-  }
-}
-
-struct {
-  const char* data;
-  uint32_t prefix_length;
-} kErrorTestData[] = {
-    // Too many extension bytes, all 0s (except for extension bit in each byte).
-    {"0780808080808080808080", 3},
-    {"0f80808080808080808080", 4},
-    {"1f80808080808080808080", 5},
-    {"3f80808080808080808080", 6},
-    {"7f80808080808080808080", 7},
-    {"ff80808080808080808080", 8},
-    // Too many extension bytes, all 1s.
-    {"07ffffffffffffffffffff", 3},
-    {"0fffffffffffffffffffff", 4},
-    {"1fffffffffffffffffffff", 5},
-    {"3fffffffffffffffffffff", 6},
-    {"7fffffffffffffffffffff", 7},
-    {"ffffffffffffffffffffff", 8},
-    // Value of 2^64, one higher than maximum of 2^64-1.
-    {"07f9ffffffffffffffff01", 3},
-    {"0ff1ffffffffffffffff01", 4},
-    {"1fe1ffffffffffffffff01", 5},
-    {"3fc1ffffffffffffffff01", 6},
-    {"7f81ffffffffffffffff01", 7},
-    {"ff81feffffffffffffff01", 8},
-    // Maximum value: 2^64-1, with one byte of padding.
-    {"07f8ffffffffffffffff8100", 3},
-    {"0ff0ffffffffffffffff8100", 4},
-    {"1fe0ffffffffffffffff8100", 5},
-    {"3fc0ffffffffffffffff8100", 6},
-    {"7f80ffffffffffffffff8100", 7},
-    {"ff80feffffffffffffff8100", 8}};
-
-TEST_P(HpackVarintDecoderTest, Error) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kErrorTestData); ++i) {
-    DecodeExpectError(absl::HexStringToBytes(kErrorTestData[i].data),
-                      kErrorTestData[i].prefix_length);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/varint/hpack_varint_encoder.cc b/http2/hpack/varint/hpack_varint_encoder.cc
deleted file mode 100644
index 87f4981..0000000
--- a/http2/hpack/varint/hpack_varint_encoder.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/varint/hpack_varint_encoder.h"
-
-#include <limits>
-
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-// static
-void HpackVarintEncoder::Encode(uint8_t high_bits,
-                                uint8_t prefix_length,
-                                uint64_t varint,
-                                std::string* output) {
-  QUICHE_DCHECK_LE(1u, prefix_length);
-  QUICHE_DCHECK_LE(prefix_length, 8u);
-
-  // prefix_mask defines the sequence of low-order bits of the first byte
-  // that encode the prefix of the value. It is also the marker in those bits
-  // of the first byte indicating that at least one extension byte is needed.
-  const uint8_t prefix_mask = (1 << prefix_length) - 1;
-  QUICHE_DCHECK_EQ(0, high_bits & prefix_mask);
-
-  if (varint < prefix_mask) {
-    // The integer fits into the prefix in its entirety.
-    unsigned char first_byte = high_bits | static_cast<unsigned char>(varint);
-    output->push_back(first_byte);
-    return;
-  }
-
-  // Extension bytes are needed.
-  unsigned char first_byte = high_bits | prefix_mask;
-  output->push_back(first_byte);
-
-  varint -= prefix_mask;
-  while (varint >= 128) {
-    // Encode the next seven bits, with continuation bit set to one.
-    output->push_back(0b10000000 | (varint % 128));
-    varint >>= 7;
-  }
-
-  // Encode final seven bits, with continuation bit set to zero.
-  output->push_back(varint);
-}
-
-}  // namespace http2
diff --git a/http2/hpack/varint/hpack_varint_encoder.h b/http2/hpack/varint/hpack_varint_encoder.h
deleted file mode 100644
index 91eaa43..0000000
--- a/http2/hpack/varint/hpack_varint_encoder.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_ENCODER_H_
-#define QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_ENCODER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-// HPACK integer encoder class with single static method implementing variable
-// length integer representation defined in RFC7541, Section 5.1:
-// https://httpwg.org/specs/rfc7541.html#integer.representation
-class QUICHE_EXPORT_PRIVATE HpackVarintEncoder {
- public:
-  // Encode |varint|, appending encoded data to |*output|.
-  // Appends between 1 and 11 bytes in total.
-  static void Encode(uint8_t high_bits,
-                     uint8_t prefix_length,
-                     uint64_t varint,
-                     std::string* output);
-};
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_ENCODER_H_
diff --git a/http2/hpack/varint/hpack_varint_encoder_test.cc b/http2/hpack/varint/hpack_varint_encoder_test.cc
deleted file mode 100644
index 5daf88b..0000000
--- a/http2/hpack/varint/hpack_varint_encoder_test.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/varint/hpack_varint_encoder.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-struct {
-  uint8_t high_bits;
-  uint8_t prefix_length;
-  uint64_t value;
-  uint8_t expected_encoding;
-} kShortTestData[] = {{0b10110010, 1, 0, 0b10110010},
-                      {0b10101100, 2, 2, 0b10101110},
-                      {0b10100000, 3, 6, 0b10100110},
-                      {0b10110000, 4, 13, 0b10111101},
-                      {0b10100000, 5, 8, 0b10101000},
-                      {0b11000000, 6, 48, 0b11110000},
-                      {0b10000000, 7, 99, 0b11100011},
-                      // Example from RFC7541 C.1.
-                      {0b00000000, 5, 10, 0b00001010}};
-
-// Encode integers that fit in the prefix.
-TEST(HpackVarintEncoderTest, Short) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kShortTestData); ++i) {
-    std::string output;
-    HpackVarintEncoder::Encode(kShortTestData[i].high_bits,
-                               kShortTestData[i].prefix_length,
-                               kShortTestData[i].value, &output);
-    ASSERT_EQ(1u, output.size());
-    EXPECT_EQ(kShortTestData[i].expected_encoding,
-              static_cast<uint8_t>(output[0]));
-  }
-}
-
-struct {
-  uint8_t high_bits;
-  uint8_t prefix_length;
-  uint64_t value;
-  const char* expected_encoding;
-} kLongTestData[] = {
-    // One extension byte.
-    {0b10011000, 3, 103, "9f60"},
-    {0b10010000, 4, 57, "9f2a"},
-    {0b11000000, 5, 158, "df7f"},
-    {0b01000000, 6, 65, "7f02"},
-    {0b00000000, 7, 200, "7f49"},
-    // Two extension bytes.
-    {0b10011000, 3, 12345, "9fb260"},
-    {0b10010000, 4, 5401, "9f8a2a"},
-    {0b11000000, 5, 16327, "dfa87f"},
-    {0b01000000, 6, 399, "7fd002"},
-    {0b00000000, 7, 9598, "7fff49"},
-    // Three extension bytes.
-    {0b10011000, 3, 1579281, "9f8ab260"},
-    {0b10010000, 4, 689488, "9fc18a2a"},
-    {0b11000000, 5, 2085964, "dfada87f"},
-    {0b01000000, 6, 43103, "7fa0d002"},
-    {0b00000000, 7, 1212541, "7ffeff49"},
-    // Four extension bytes.
-    {0b10011000, 3, 202147110, "9f9f8ab260"},
-    {0b10010000, 4, 88252593, "9fa2c18a2a"},
-    {0b11000000, 5, 266999535, "dfd0ada87f"},
-    {0b01000000, 6, 5509304, "7ff9a0d002"},
-    {0b00000000, 7, 155189149, "7f9efeff49"},
-    // Six extension bytes.
-    {0b10011000, 3, 3311978140938, "9f83aa9f8ab260"},
-    {0b10010000, 4, 1445930244223, "9ff0b0a2c18a2a"},
-    {0b11000000, 5, 4374519874169, "dfda84d0ada87f"},
-    {0b01000000, 6, 90263420404, "7fb5fbf9a0d002"},
-    {0b00000000, 7, 2542616951118, "7fcff19efeff49"},
-    // Eight extension bytes.
-    {0b10011000, 3, 54263449861016696, "9ff19883aa9f8ab260"},
-    {0b10010000, 4, 23690121121119891, "9f84fdf0b0a2c18a2a"},
-    {0b11000000, 5, 71672133617889215, "dfa0dfda84d0ada87f"},
-    {0b01000000, 6, 1478875878881374, "7f9ff0b5fbf9a0d002"},
-    {0b00000000, 7, 41658236125045114, "7ffbc1cff19efeff49"},
-    // Ten extension bytes.
-    {0b10011000, 3, 12832019021693745307u, "9f94f1f19883aa9f8ab201"},
-    {0b10010000, 4, 9980690937382242223u, "9fa08f84fdf0b0a2c18a01"},
-    {0b11000000, 5, 12131360551794650846u, "dfbfdda0dfda84d0ada801"},
-    {0b01000000, 6, 15006530362736632796u, "7f9dc79ff0b5fbf9a0d001"},
-    {0b00000000, 7, 18445754019193211014u, "7f8790fbc1cff19efeff01"},
-    // Maximum value: 2^64-1.
-    {0b10011000, 3, 18446744073709551615u, "9ff8ffffffffffffffff01"},
-    {0b10010000, 4, 18446744073709551615u, "9ff0ffffffffffffffff01"},
-    {0b11000000, 5, 18446744073709551615u, "dfe0ffffffffffffffff01"},
-    {0b01000000, 6, 18446744073709551615u, "7fc0ffffffffffffffff01"},
-    {0b00000000, 7, 18446744073709551615u, "7f80ffffffffffffffff01"},
-    // Example from RFC7541 C.1.
-    {0b00000000, 5, 1337, "1f9a0a"},
-};
-
-// Encode integers that do not fit in the prefix.
-TEST(HpackVarintEncoderTest, Long) {
-  // Test encoding byte by byte, also test encoding in
-  // a single ResumeEncoding() call.
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kLongTestData); ++i) {
-    std::string expected_encoding =
-        absl::HexStringToBytes(kLongTestData[i].expected_encoding);
-
-    std::string output;
-    HpackVarintEncoder::Encode(kLongTestData[i].high_bits,
-                               kLongTestData[i].prefix_length,
-                               kLongTestData[i].value, &output);
-
-    EXPECT_EQ(expected_encoding, output);
-  }
-}
-
-struct {
-  uint8_t high_bits;
-  uint8_t prefix_length;
-  uint64_t value;
-  uint8_t expected_encoding_first_byte;
-} kLastByteIsZeroTestData[] = {
-    {0b10110010, 1, 1, 0b10110011},   {0b10101100, 2, 3, 0b10101111},
-    {0b10101000, 3, 7, 0b10101111},   {0b10110000, 4, 15, 0b10111111},
-    {0b10100000, 5, 31, 0b10111111},  {0b11000000, 6, 63, 0b11111111},
-    {0b10000000, 7, 127, 0b11111111}, {0b00000000, 8, 255, 0b11111111}};
-
-// Make sure that the encoder outputs the last byte even when it is zero.  This
-// happens exactly when encoding  the value 2^prefix_length - 1.
-TEST(HpackVarintEncoderTest, LastByteIsZero) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kLastByteIsZeroTestData); ++i) {
-    std::string output;
-    HpackVarintEncoder::Encode(kLastByteIsZeroTestData[i].high_bits,
-                               kLastByteIsZeroTestData[i].prefix_length,
-                               kLastByteIsZeroTestData[i].value, &output);
-    ASSERT_EQ(2u, output.size());
-    EXPECT_EQ(kLastByteIsZeroTestData[i].expected_encoding_first_byte,
-              static_cast<uint8_t>(output[0]));
-    EXPECT_EQ(0b00000000, output[1]);
-  }
-}
-
-// Test that encoder appends correctly to non-empty string.
-TEST(HpackVarintEncoderTest, Append) {
-  std::string output("foo");
-  EXPECT_EQ(absl::HexStringToBytes("666f6f"), output);
-
-  HpackVarintEncoder::Encode(0b10011000, 3, 103, &output);
-  EXPECT_EQ(absl::HexStringToBytes("666f6f9f60"), output);
-
-  HpackVarintEncoder::Encode(0b10100000, 5, 8, &output);
-  EXPECT_EQ(absl::HexStringToBytes("666f6f9f60a8"), output);
-
-  HpackVarintEncoder::Encode(0b10011000, 3, 202147110, &output);
-  EXPECT_EQ(absl::HexStringToBytes("666f6f9f60a89f9f8ab260"), output);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/hpack/varint/hpack_varint_round_trip_test.cc b/http2/hpack/varint/hpack_varint_round_trip_test.cc
deleted file mode 100644
index 0c832d9..0000000
--- a/http2/hpack/varint/hpack_varint_round_trip_test.cc
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-
-// Test HpackVarintDecoder against data encoded via HpackBlockBuilder,
-// which uses HpackVarintEncoder under the hood.
-
-#include <stddef.h>
-
-#include <iterator>
-#include <set>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/tools/random_decoder_test.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_text_utils.h"
-
-using ::testing::AssertionFailure;
-using ::testing::AssertionSuccess;
-
-namespace http2 {
-namespace test {
-namespace {
-
-// Returns the highest value with the specified number of extension bytes
-// and the specified prefix length (bits).
-uint64_t HiValueOfExtensionBytes(uint32_t extension_bytes,
-                                 uint32_t prefix_length) {
-  return (1 << prefix_length) - 2 +
-         (extension_bytes == 0 ? 0 : (1LLU << (extension_bytes * 7)));
-}
-
-class HpackVarintRoundTripTest : public RandomDecoderTest {
- protected:
-  HpackVarintRoundTripTest() : prefix_length_(0) {}
-
-  DecodeStatus StartDecoding(DecodeBuffer* b) override {
-    QUICHE_CHECK_LT(0u, b->Remaining());
-    uint8_t prefix = b->DecodeUInt8();
-    return decoder_.Start(prefix, prefix_length_, b);
-  }
-
-  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
-    return decoder_.Resume(b);
-  }
-
-  void DecodeSeveralWays(uint64_t expected_value, uint32_t expected_offset) {
-    // The validator is called after each of the several times that the input
-    // DecodeBuffer is decoded, each with a different segmentation of the input.
-    // Validate that decoder_.value() matches the expected value.
-    Validator validator = [expected_value, this](
-                              const DecodeBuffer& /*db*/,
-                              DecodeStatus /*status*/) -> AssertionResult {
-      if (decoder_.value() != expected_value) {
-        return AssertionFailure()
-               << "Value doesn't match expected: " << decoder_.value()
-               << " != " << expected_value;
-      }
-      return AssertionSuccess();
-    };
-
-    // First validate that decoding is done and that we've advanced the cursor
-    // the expected amount.
-    validator = ValidateDoneAndOffset(expected_offset, validator);
-
-    // StartDecoding, above, requires the DecodeBuffer be non-empty so that it
-    // can call Start with the prefix byte.
-    bool return_non_zero_on_first = true;
-
-    DecodeBuffer b(buffer_);
-    EXPECT_TRUE(
-        DecodeAndValidateSeveralWays(&b, return_non_zero_on_first, validator));
-
-    EXPECT_EQ(expected_value, decoder_.value());
-    EXPECT_EQ(expected_offset, b.Offset());
-  }
-
-  void EncodeNoRandom(uint64_t value, uint8_t prefix_length) {
-    QUICHE_DCHECK_LE(3, prefix_length);
-    QUICHE_DCHECK_LE(prefix_length, 8);
-    prefix_length_ = prefix_length;
-
-    HpackBlockBuilder bb;
-    bb.AppendHighBitsAndVarint(0, prefix_length_, value);
-    buffer_ = bb.buffer();
-    ASSERT_LT(0u, buffer_.size());
-
-    const uint8_t prefix_mask = (1 << prefix_length_) - 1;
-    ASSERT_EQ(static_cast<uint8_t>(buffer_[0]),
-              static_cast<uint8_t>(buffer_[0]) & prefix_mask);
-  }
-
-  void Encode(uint64_t value, uint8_t prefix_length) {
-    EncodeNoRandom(value, prefix_length);
-    // Add some random bits to the prefix (the first byte) above the mask.
-    uint8_t prefix = buffer_[0];
-    buffer_[0] = prefix | (Random().Rand8() << prefix_length);
-    const uint8_t prefix_mask = (1 << prefix_length_) - 1;
-    ASSERT_EQ(prefix, buffer_[0] & prefix_mask);
-  }
-
-  // This is really a test of HpackBlockBuilder, making sure that the input to
-  // HpackVarintDecoder is as expected, which also acts as confirmation that
-  // my thinking about the encodings being used by the tests, i.e. cover the
-  // range desired.
-  void ValidateEncoding(uint64_t value,
-                        uint64_t minimum,
-                        uint64_t maximum,
-                        size_t expected_bytes) {
-    ASSERT_EQ(expected_bytes, buffer_.size());
-    if (expected_bytes > 1) {
-      const uint8_t prefix_mask = (1 << prefix_length_) - 1;
-      EXPECT_EQ(prefix_mask, buffer_[0] & prefix_mask);
-      size_t last = expected_bytes - 1;
-      for (size_t ndx = 1; ndx < last; ++ndx) {
-        // Before the last extension byte, we expect the high-bit set.
-        uint8_t byte = buffer_[ndx];
-        if (value == minimum) {
-          EXPECT_EQ(0x80, byte) << "ndx=" << ndx;
-        } else if (value == maximum) {
-          if (expected_bytes < 11) {
-            EXPECT_EQ(0xff, byte) << "ndx=" << ndx;
-          }
-        } else {
-          EXPECT_EQ(0x80, byte & 0x80) << "ndx=" << ndx;
-        }
-      }
-      // The last extension byte should not have the high-bit set.
-      uint8_t byte = buffer_[last];
-      if (value == minimum) {
-        if (expected_bytes == 2) {
-          EXPECT_EQ(0x00, byte);
-        } else {
-          EXPECT_EQ(0x01, byte);
-        }
-      } else if (value == maximum) {
-        if (expected_bytes < 11) {
-          EXPECT_EQ(0x7f, byte);
-        }
-      } else {
-        EXPECT_EQ(0x00, byte & 0x80);
-      }
-    } else {
-      const uint8_t prefix_mask = (1 << prefix_length_) - 1;
-      EXPECT_EQ(value, static_cast<uint32_t>(buffer_[0] & prefix_mask));
-      EXPECT_LT(value, prefix_mask);
-    }
-  }
-
-  void EncodeAndDecodeValues(const std::set<uint64_t>& values,
-                             uint8_t prefix_length,
-                             size_t expected_bytes) {
-    QUICHE_CHECK(!values.empty());
-    const uint64_t minimum = *values.begin();
-    const uint64_t maximum = *values.rbegin();
-    for (const uint64_t value : values) {
-      Encode(value, prefix_length);  // Sets buffer_.
-
-      std::string msg = absl::StrCat("value=", value, " (0x", absl::Hex(value),
-                                     "), prefix_length=", prefix_length,
-                                     ", expected_bytes=", expected_bytes, "\n",
-                                     quiche::QuicheTextUtils::HexDump(buffer_));
-
-      if (value == minimum) {
-        HTTP2_LOG(INFO) << "Checking minimum; " << msg;
-      } else if (value == maximum) {
-        HTTP2_LOG(INFO) << "Checking maximum; " << msg;
-      }
-
-      SCOPED_TRACE(msg);
-      ValidateEncoding(value, minimum, maximum, expected_bytes);
-      DecodeSeveralWays(value, expected_bytes);
-
-      // Append some random data to the end of buffer_ and repeat. That random
-      // data should be ignored.
-      buffer_.append(Random().RandString(1 + Random().Uniform(10)));
-      DecodeSeveralWays(value, expected_bytes);
-
-      // If possible, add extension bytes that don't change the value.
-      if (1 < expected_bytes) {
-        buffer_.resize(expected_bytes);
-        for (uint8_t total_bytes = expected_bytes + 1; total_bytes <= 6;
-             ++total_bytes) {
-          // Mark the current last byte as not being the last one.
-          EXPECT_EQ(0x00, 0x80 & buffer_.back());
-          buffer_.back() |= 0x80;
-          buffer_.push_back('\0');
-          DecodeSeveralWays(value, total_bytes);
-        }
-      }
-    }
-  }
-
-  // Encode values (all or some of it) in [start, start+range).  Check
-  // that |start| is the smallest value and |start+range-1| is the largest value
-  // corresponding to |expected_bytes|, except if |expected_bytes| is maximal.
-  void EncodeAndDecodeValuesInRange(uint64_t start,
-                                    uint64_t range,
-                                    uint8_t prefix_length,
-                                    size_t expected_bytes) {
-    const uint8_t prefix_mask = (1 << prefix_length) - 1;
-    const uint64_t beyond = start + range;
-
-    HTTP2_LOG(INFO)
-        << "############################################################";
-    HTTP2_LOG(INFO) << "prefix_length=" << static_cast<int>(prefix_length);
-    HTTP2_LOG(INFO) << "prefix_mask=" << std::hex
-                    << static_cast<int>(prefix_mask);
-    HTTP2_LOG(INFO) << "start=" << start << " (" << std::hex << start << ")";
-    HTTP2_LOG(INFO) << "range=" << range << " (" << std::hex << range << ")";
-    HTTP2_LOG(INFO) << "beyond=" << beyond << " (" << std::hex << beyond << ")";
-    HTTP2_LOG(INFO) << "expected_bytes=" << expected_bytes;
-
-    if (expected_bytes < 11) {
-      // Confirm the claim that beyond requires more bytes.
-      Encode(beyond, prefix_length);
-      EXPECT_EQ(expected_bytes + 1, buffer_.size())
-          << quiche::QuicheTextUtils::HexDump(buffer_);
-    }
-
-    std::set<uint64_t> values;
-    if (range < 200) {
-      // Select all values in the range.
-      for (uint64_t offset = 0; offset < range; ++offset) {
-        values.insert(start + offset);
-      }
-    } else {
-      // Select some values in this range, including the minimum and maximum
-      // values that require exactly |expected_bytes| extension bytes.
-      values.insert({start, start + 1, beyond - 2, beyond - 1});
-      while (values.size() < 100) {
-        values.insert(Random().UniformInRange(start, beyond - 1));
-      }
-    }
-
-    EncodeAndDecodeValues(values, prefix_length, expected_bytes);
-  }
-
-  HpackVarintDecoder decoder_;
-  std::string buffer_;
-  uint8_t prefix_length_;
-};
-
-// To help me and future debuggers of varint encodings, this HTTP2_LOGs out the
-// transition points where a new extension byte is added.
-TEST_F(HpackVarintRoundTripTest, Encode) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t a = HiValueOfExtensionBytes(0, prefix_length);
-    const uint64_t b = HiValueOfExtensionBytes(1, prefix_length);
-    const uint64_t c = HiValueOfExtensionBytes(2, prefix_length);
-    const uint64_t d = HiValueOfExtensionBytes(3, prefix_length);
-    const uint64_t e = HiValueOfExtensionBytes(4, prefix_length);
-    const uint64_t f = HiValueOfExtensionBytes(5, prefix_length);
-    const uint64_t g = HiValueOfExtensionBytes(6, prefix_length);
-    const uint64_t h = HiValueOfExtensionBytes(7, prefix_length);
-    const uint64_t i = HiValueOfExtensionBytes(8, prefix_length);
-    const uint64_t j = HiValueOfExtensionBytes(9, prefix_length);
-
-    HTTP2_LOG(INFO)
-        << "############################################################";
-    HTTP2_LOG(INFO) << "prefix_length=" << prefix_length << "   a=" << a
-                    << "   b=" << b << "   c=" << c << "   d=" << d
-                    << "   e=" << e << "   f=" << f << "   g=" << g
-                    << "   h=" << h << "   i=" << i << "   j=" << j;
-
-    std::vector<uint64_t> values = {
-        0,     1,                       // Force line break.
-        a - 1, a, a + 1, a + 2, a + 3,  // Force line break.
-        b - 1, b, b + 1, b + 2, b + 3,  // Force line break.
-        c - 1, c, c + 1, c + 2, c + 3,  // Force line break.
-        d - 1, d, d + 1, d + 2, d + 3,  // Force line break.
-        e - 1, e, e + 1, e + 2, e + 3,  // Force line break.
-        f - 1, f, f + 1, f + 2, f + 3,  // Force line break.
-        g - 1, g, g + 1, g + 2, g + 3,  // Force line break.
-        h - 1, h, h + 1, h + 2, h + 3,  // Force line break.
-        i - 1, i, i + 1, i + 2, i + 3,  // Force line break.
-        j - 1, j, j + 1, j + 2, j + 3,  // Force line break.
-    };
-
-    for (uint64_t value : values) {
-      EncodeNoRandom(value, prefix_length);
-      std::string dump = quiche::QuicheTextUtils::HexDump(buffer_);
-      HTTP2_LOG(INFO) << absl::StrFormat("%10llu %0#18x ", value, value)
-                      << quiche::QuicheTextUtils::HexDump(buffer_).substr(7);
-    }
-  }
-}
-
-TEST_F(HpackVarintRoundTripTest, FromSpec1337) {
-  DecodeBuffer b(absl::string_view("\x1f\x9a\x0a"));
-  uint32_t prefix_length = 5;
-  uint8_t p = b.DecodeUInt8();
-  EXPECT_EQ(1u, b.Offset());
-  EXPECT_EQ(DecodeStatus::kDecodeDone, decoder_.Start(p, prefix_length, &b));
-  EXPECT_EQ(3u, b.Offset());
-  EXPECT_EQ(1337u, decoder_.value());
-
-  EncodeNoRandom(1337, prefix_length);
-  EXPECT_EQ(3u, buffer_.size());
-  EXPECT_EQ('\x1f', buffer_[0]);
-  EXPECT_EQ('\x9a', buffer_[1]);
-  EXPECT_EQ('\x0a', buffer_[2]);
-}
-
-// Test all the values that fit into the prefix (one less than the mask).
-TEST_F(HpackVarintRoundTripTest, ValidatePrefixOnly) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint8_t prefix_mask = (1 << prefix_length) - 1;
-    EncodeAndDecodeValuesInRange(0, prefix_mask, prefix_length, 1);
-  }
-}
-
-// Test all values that require exactly 1 extension byte.
-TEST_F(HpackVarintRoundTripTest, ValidateOneExtensionByte) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(0, prefix_length) + 1;
-    EncodeAndDecodeValuesInRange(start, 128, prefix_length, 2);
-  }
-}
-
-// Test *some* values that require exactly 2 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateTwoExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(1, prefix_length) + 1;
-    const uint64_t range = 127 << 7;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 3);
-  }
-}
-
-// Test *some* values that require 3 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateThreeExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(2, prefix_length) + 1;
-    const uint64_t range = 127 << 14;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 4);
-  }
-}
-
-// Test *some* values that require 4 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateFourExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(3, prefix_length) + 1;
-    const uint64_t range = 127 << 21;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 5);
-  }
-}
-
-// Test *some* values that require 5 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateFiveExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(4, prefix_length) + 1;
-    const uint64_t range = 127llu << 28;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 6);
-  }
-}
-
-// Test *some* values that require 6 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateSixExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(5, prefix_length) + 1;
-    const uint64_t range = 127llu << 35;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 7);
-  }
-}
-
-// Test *some* values that require 7 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateSevenExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(6, prefix_length) + 1;
-    const uint64_t range = 127llu << 42;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 8);
-  }
-}
-
-// Test *some* values that require 8 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateEightExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(7, prefix_length) + 1;
-    const uint64_t range = 127llu << 49;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 9);
-  }
-}
-
-// Test *some* values that require 9 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateNineExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(8, prefix_length) + 1;
-    const uint64_t range = 127llu << 56;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 10);
-  }
-}
-
-// Test *some* values that require 10 extension bytes.
-TEST_F(HpackVarintRoundTripTest, ValidateTenExtensionBytes) {
-  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
-    const uint64_t start = HiValueOfExtensionBytes(9, prefix_length) + 1;
-    const uint64_t range = std::numeric_limits<uint64_t>::max() - start;
-
-    EncodeAndDecodeValuesInRange(start, range, prefix_length, 11);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/http2_constants.cc b/http2/http2_constants.cc
deleted file mode 100644
index 6feea19..0000000
--- a/http2/http2_constants.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/http2_constants.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "http2/platform/api/http2_flag_utils.h"
-#include "http2/platform/api/http2_logging.h"
-
-namespace http2 {
-
-std::string Http2FrameTypeToString(Http2FrameType v) {
-  switch (v) {
-    case Http2FrameType::DATA:
-      return "DATA";
-    case Http2FrameType::HEADERS:
-      return "HEADERS";
-    case Http2FrameType::PRIORITY:
-      return "PRIORITY";
-    case Http2FrameType::RST_STREAM:
-      return "RST_STREAM";
-    case Http2FrameType::SETTINGS:
-      return "SETTINGS";
-    case Http2FrameType::PUSH_PROMISE:
-      return "PUSH_PROMISE";
-    case Http2FrameType::PING:
-      return "PING";
-    case Http2FrameType::GOAWAY:
-      return "GOAWAY";
-    case Http2FrameType::WINDOW_UPDATE:
-      return "WINDOW_UPDATE";
-    case Http2FrameType::CONTINUATION:
-      return "CONTINUATION";
-    case Http2FrameType::ALTSVC:
-      return "ALTSVC";
-    case Http2FrameType::PRIORITY_UPDATE:
-      return "PRIORITY_UPDATE";
-  }
-  return absl::StrCat("UnknownFrameType(", static_cast<int>(v), ")");
-}
-
-std::string Http2FrameTypeToString(uint8_t v) {
-  return Http2FrameTypeToString(static_cast<Http2FrameType>(v));
-}
-
-std::string Http2FrameFlagsToString(Http2FrameType type, uint8_t flags) {
-  std::string s;
-  // Closure to append flag name |v| to the std::string |s|,
-  // and to clear |bit| from |flags|.
-  auto append_and_clear = [&s, &flags](absl::string_view v, uint8_t bit) {
-    if (!s.empty()) {
-      s.push_back('|');
-    }
-    absl::StrAppend(&s, v);
-    flags ^= bit;
-  };
-  if (flags & 0x01) {
-    if (type == Http2FrameType::DATA || type == Http2FrameType::HEADERS) {
-      append_and_clear("END_STREAM", Http2FrameFlag::END_STREAM);
-    } else if (type == Http2FrameType::SETTINGS ||
-               type == Http2FrameType::PING) {
-      append_and_clear("ACK", Http2FrameFlag::ACK);
-    }
-  }
-  if (flags & 0x04) {
-    if (type == Http2FrameType::HEADERS ||
-        type == Http2FrameType::PUSH_PROMISE ||
-        type == Http2FrameType::CONTINUATION) {
-      append_and_clear("END_HEADERS", Http2FrameFlag::END_HEADERS);
-    }
-  }
-  if (flags & 0x08) {
-    if (type == Http2FrameType::DATA || type == Http2FrameType::HEADERS ||
-        type == Http2FrameType::PUSH_PROMISE) {
-      append_and_clear("PADDED", Http2FrameFlag::PADDED);
-    }
-  }
-  if (flags & 0x20) {
-    if (type == Http2FrameType::HEADERS) {
-      append_and_clear("PRIORITY", Http2FrameFlag::PRIORITY);
-    }
-  }
-  if (flags != 0) {
-    append_and_clear(absl::StrFormat("0x%02x", flags), flags);
-  }
-  QUICHE_DCHECK_EQ(0, flags);
-  return s;
-}
-std::string Http2FrameFlagsToString(uint8_t type, uint8_t flags) {
-  return Http2FrameFlagsToString(static_cast<Http2FrameType>(type), flags);
-}
-
-std::string Http2ErrorCodeToString(uint32_t v) {
-  switch (v) {
-    case 0x0:
-      return "NO_ERROR";
-    case 0x1:
-      return "PROTOCOL_ERROR";
-    case 0x2:
-      return "INTERNAL_ERROR";
-    case 0x3:
-      return "FLOW_CONTROL_ERROR";
-    case 0x4:
-      return "SETTINGS_TIMEOUT";
-    case 0x5:
-      return "STREAM_CLOSED";
-    case 0x6:
-      return "FRAME_SIZE_ERROR";
-    case 0x7:
-      return "REFUSED_STREAM";
-    case 0x8:
-      return "CANCEL";
-    case 0x9:
-      return "COMPRESSION_ERROR";
-    case 0xa:
-      return "CONNECT_ERROR";
-    case 0xb:
-      return "ENHANCE_YOUR_CALM";
-    case 0xc:
-      return "INADEQUATE_SECURITY";
-    case 0xd:
-      return "HTTP_1_1_REQUIRED";
-  }
-  return absl::StrCat("UnknownErrorCode(0x", absl::Hex(v), ")");
-}
-std::string Http2ErrorCodeToString(Http2ErrorCode v) {
-  return Http2ErrorCodeToString(static_cast<uint32_t>(v));
-}
-
-std::string Http2SettingsParameterToString(uint32_t v) {
-  switch (v) {
-    case 0x1:
-      return "HEADER_TABLE_SIZE";
-    case 0x2:
-      return "ENABLE_PUSH";
-    case 0x3:
-      return "MAX_CONCURRENT_STREAMS";
-    case 0x4:
-      return "INITIAL_WINDOW_SIZE";
-    case 0x5:
-      return "MAX_FRAME_SIZE";
-    case 0x6:
-      return "MAX_HEADER_LIST_SIZE";
-  }
-  return absl::StrCat("UnknownSettingsParameter(0x", absl::Hex(v), ")");
-}
-std::string Http2SettingsParameterToString(Http2SettingsParameter v) {
-  return Http2SettingsParameterToString(static_cast<uint32_t>(v));
-}
-
-// Invalid HTTP/2 header names according to
-// https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2.
-// TODO(b/78024822): Consider adding "upgrade" to this set.
-constexpr char const* kHttp2InvalidHeaderNames[] = {
-    "connection",        "host", "keep-alive", "proxy-connection",
-    "transfer-encoding", "",
-};
-
-constexpr char const* kHttp2InvalidHeaderNamesOld[] = {
-    "connection", "host", "keep-alive", "proxy-connection", "transfer-encoding",
-};
-
-const InvalidHeaderSet& GetInvalidHttp2HeaderSet() {
-  if (!GetQuicheReloadableFlag(quic, quic_verify_request_headers_2)) {
-    static const auto* invalid_header_set_old =
-        new InvalidHeaderSet(std::begin(http2::kHttp2InvalidHeaderNamesOld),
-                             std::end(http2::kHttp2InvalidHeaderNamesOld));
-    return *invalid_header_set_old;
-  }
-  HTTP2_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 3, 3);
-  static const auto* invalid_header_set =
-      new InvalidHeaderSet(std::begin(http2::kHttp2InvalidHeaderNames),
-                           std::end(http2::kHttp2InvalidHeaderNames));
-  return *invalid_header_set;
-}
-
-}  // namespace http2
diff --git a/http2/http2_constants.h b/http2/http2_constants.h
deleted file mode 100644
index d47c3f1..0000000
--- a/http2/http2_constants.h
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HTTP2_CONSTANTS_H_
-#define QUICHE_HTTP2_HTTP2_CONSTANTS_H_
-
-// Constants from the HTTP/2 spec, RFC 7540, and associated helper functions.
-
-#include <cstdint>
-#include <iosfwd>
-#include <ostream>
-#include <string>
-
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "http2/platform/api/http2_flags.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_text_utils.h"
-
-namespace http2 {
-
-// TODO(jamessynge): create http2_simple_types for types similar to
-// SpdyStreamId, but not for structures like Http2FrameHeader. Then will be
-// able to move these stream id functions there.
-constexpr uint32_t UInt31Mask() { return 0x7fffffff; }
-constexpr uint32_t StreamIdMask() { return UInt31Mask(); }
-
-// The value used to identify types of frames. Upper case to match the RFC.
-// The comments indicate which flags are valid for that frame type.
-enum class Http2FrameType : uint8_t {
-  DATA = 0,           // END_STREAM | PADDED
-  HEADERS = 1,        // END_STREAM | END_HEADERS | PADDED | PRIORITY
-  PRIORITY = 2,       //
-  RST_STREAM = 3,     //
-  SETTINGS = 4,       // ACK
-  PUSH_PROMISE = 5,   // END_HEADERS | PADDED
-  PING = 6,           // ACK
-  GOAWAY = 7,         //
-  WINDOW_UPDATE = 8,  //
-  CONTINUATION = 9,   // END_HEADERS
-  // https://tools.ietf.org/html/rfc7838
-  ALTSVC = 10,  // no flags
-  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-02
-  PRIORITY_UPDATE = 16,  // no flags
-};
-
-// Is the frame type known/supported?
-inline bool IsSupportedHttp2FrameType(uint32_t v) {
-  return v <= static_cast<uint32_t>(Http2FrameType::ALTSVC) ||
-         v == static_cast<uint32_t>(Http2FrameType::PRIORITY_UPDATE);
-}
-inline bool IsSupportedHttp2FrameType(Http2FrameType v) {
-  return IsSupportedHttp2FrameType(static_cast<uint32_t>(v));
-}
-
-// The return type is 'std::string' so that they can generate a unique string
-// for each unsupported value. Since these are just used for debugging/error
-// messages, that isn't a cost to we need to worry about. The same applies to
-// the functions later in this file.
-QUICHE_EXPORT_PRIVATE std::string Http2FrameTypeToString(Http2FrameType v);
-QUICHE_EXPORT_PRIVATE std::string Http2FrameTypeToString(uint8_t v);
-QUICHE_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
-                                                      Http2FrameType v) {
-  return out << Http2FrameTypeToString(v);
-}
-
-// Flags that appear in supported frame types. These are treated as bit masks.
-// The comments indicate for which frame types the flag is valid.
-enum Http2FrameFlag : uint8_t {
-  END_STREAM = 0x01,   // DATA, HEADERS
-  ACK = 0x01,          // SETTINGS, PING
-  END_HEADERS = 0x04,  // HEADERS, PUSH_PROMISE, CONTINUATION
-  PADDED = 0x08,       // DATA, HEADERS, PUSH_PROMISE
-  PRIORITY = 0x20,     // HEADERS
-};
-
-// Formats zero or more flags for the specified type of frame. Returns an
-// empty string if flags==0.
-QUICHE_EXPORT_PRIVATE std::string Http2FrameFlagsToString(Http2FrameType type,
-                                                          uint8_t flags);
-QUICHE_EXPORT_PRIVATE std::string Http2FrameFlagsToString(uint8_t type,
-                                                          uint8_t flags);
-
-// Error codes for GOAWAY and RST_STREAM frames.
-enum class Http2ErrorCode : uint32_t {
-  // The associated condition is not a result of an error. For example, a GOAWAY
-  // might include this code to indicate graceful shutdown of a connection.
-  HTTP2_NO_ERROR = 0x0,
-
-  // The endpoint detected an unspecific protocol error. This error is for use
-  // when a more specific error code is not available.
-  PROTOCOL_ERROR = 0x1,
-
-  // The endpoint encountered an unexpected internal error.
-  INTERNAL_ERROR = 0x2,
-
-  // The endpoint detected that its peer violated the flow-control protocol.
-  FLOW_CONTROL_ERROR = 0x3,
-
-  // The endpoint sent a SETTINGS frame but did not receive a response in a
-  // timely manner. See Section 6.5.3 ("Settings Synchronization").
-  SETTINGS_TIMEOUT = 0x4,
-
-  // The endpoint received a frame after a stream was half-closed.
-  STREAM_CLOSED = 0x5,
-
-  // The endpoint received a frame with an invalid size.
-  FRAME_SIZE_ERROR = 0x6,
-
-  // The endpoint refused the stream prior to performing any application
-  // processing (see Section 8.1.4 for details).
-  REFUSED_STREAM = 0x7,
-
-  // Used by the endpoint to indicate that the stream is no longer needed.
-  CANCEL = 0x8,
-
-  // The endpoint is unable to maintain the header compression context
-  // for the connection.
-  COMPRESSION_ERROR = 0x9,
-
-  // The connection established in response to a CONNECT request (Section 8.3)
-  // was reset or abnormally closed.
-  CONNECT_ERROR = 0xa,
-
-  // The endpoint detected that its peer is exhibiting a behavior that might
-  // be generating excessive load.
-  ENHANCE_YOUR_CALM = 0xb,
-
-  // The underlying transport has properties that do not meet minimum
-  // security requirements (see Section 9.2).
-  INADEQUATE_SECURITY = 0xc,
-
-  // The endpoint requires that HTTP/1.1 be used instead of HTTP/2.
-  HTTP_1_1_REQUIRED = 0xd,
-};
-
-// Is the error code supported? (So far that means it is in RFC 7540.)
-inline bool IsSupportedHttp2ErrorCode(uint32_t v) {
-  return v <= static_cast<uint32_t>(Http2ErrorCode::HTTP_1_1_REQUIRED);
-}
-inline bool IsSupportedHttp2ErrorCode(Http2ErrorCode v) {
-  return IsSupportedHttp2ErrorCode(static_cast<uint32_t>(v));
-}
-
-// Format the specified error code.
-QUICHE_EXPORT_PRIVATE std::string Http2ErrorCodeToString(uint32_t v);
-QUICHE_EXPORT_PRIVATE std::string Http2ErrorCodeToString(Http2ErrorCode v);
-QUICHE_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
-                                                      Http2ErrorCode v) {
-  return out << Http2ErrorCodeToString(v);
-}
-
-// Supported parameters in SETTINGS frames; so far just those in RFC 7540.
-enum class Http2SettingsParameter : uint16_t {
-  // Allows the sender to inform the remote endpoint of the maximum size of the
-  // header compression table used to decode header blocks, in octets. The
-  // encoder can select any size equal to or less than this value by using
-  // signaling specific to the header compression format inside a header block
-  // (see [COMPRESSION]). The initial value is 4,096 octets.
-  HEADER_TABLE_SIZE = 0x1,
-
-  // This setting can be used to disable server push (Section 8.2). An endpoint
-  // MUST NOT send a PUSH_PROMISE frame if it receives this parameter set to a
-  // value of 0. An endpoint that has both set this parameter to 0 and had it
-  // acknowledged MUST treat the receipt of a PUSH_PROMISE frame as a connection
-  // error (Section 5.4.1) of type PROTOCOL_ERROR.
-  //
-  // The initial value is 1, which indicates that server push is permitted. Any
-  // value other than 0 or 1 MUST be treated as a connection error (Section
-  // 5.4.1) of type PROTOCOL_ERROR.
-  ENABLE_PUSH = 0x2,
-
-  // Indicates the maximum number of concurrent streams that the sender will
-  // allow. This limit is directional: it applies to the number of streams that
-  // the sender permits the receiver to create. Initially, there is no limit to
-  // this value. It is recommended that this value be no smaller than 100, so as
-  // to not unnecessarily limit parallelism.
-  //
-  // A value of 0 for MAX_CONCURRENT_STREAMS SHOULD NOT be treated as
-  // special by endpoints. A zero value does prevent the creation of new
-  // streams; however, this can also happen for any limit that is exhausted with
-  // active streams. Servers SHOULD only set a zero value for short durations;
-  // if a server does not wish to accept requests, closing the connection is
-  // more appropriate.
-  MAX_CONCURRENT_STREAMS = 0x3,
-
-  // Indicates the sender's initial window size (in octets) for stream-level
-  // flow control. The initial value is 2^16-1 (65,535) octets.
-  //
-  // This setting affects the window size of all streams (see Section 6.9.2).
-  //
-  // Values above the maximum flow-control window size of 2^31-1 MUST be treated
-  // as a connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR.
-  INITIAL_WINDOW_SIZE = 0x4,
-
-  // Indicates the size of the largest frame payload that the sender is willing
-  // to receive, in octets.
-  //
-  // The initial value is 2^14 (16,384) octets. The value advertised by an
-  // endpoint MUST be between this initial value and the maximum allowed frame
-  // size (2^24-1 or 16,777,215 octets), inclusive. Values outside this range
-  // MUST be treated as a connection error (Section 5.4.1) of type
-  // PROTOCOL_ERROR.
-  MAX_FRAME_SIZE = 0x5,
-
-  // This advisory setting informs a peer of the maximum size of header list
-  // that the sender is prepared to accept, in octets. The value is based on the
-  // uncompressed size of header fields, including the length of the name and
-  // value in octets plus an overhead of 32 octets for each header field.
-  //
-  // For any given request, a lower limit than what is advertised MAY be
-  // enforced. The initial value of this setting is unlimited.
-  MAX_HEADER_LIST_SIZE = 0x6,
-};
-
-// Is the settings parameter supported (so far that means it is in RFC 7540)?
-inline bool IsSupportedHttp2SettingsParameter(uint32_t v) {
-  return 0 < v && v <= static_cast<uint32_t>(
-                           Http2SettingsParameter::MAX_HEADER_LIST_SIZE);
-}
-inline bool IsSupportedHttp2SettingsParameter(Http2SettingsParameter v) {
-  return IsSupportedHttp2SettingsParameter(static_cast<uint32_t>(v));
-}
-
-// Format the specified settings parameter.
-QUICHE_EXPORT_PRIVATE std::string Http2SettingsParameterToString(uint32_t v);
-QUICHE_EXPORT_PRIVATE std::string Http2SettingsParameterToString(
-    Http2SettingsParameter v);
-inline std::ostream& operator<<(std::ostream& out, Http2SettingsParameter v) {
-  return out << Http2SettingsParameterToString(v);
-}
-
-// Information about the initial, minimum and maximum value of settings (not
-// applicable to all settings parameters).
-class QUICHE_EXPORT_PRIVATE Http2SettingsInfo {
- public:
-  // Default value for HEADER_TABLE_SIZE.
-  static constexpr uint32_t DefaultHeaderTableSize() { return 4096; }
-
-  // Default value for ENABLE_PUSH.
-  static constexpr bool DefaultEnablePush() { return true; }
-
-  // Default value for INITIAL_WINDOW_SIZE.
-  static constexpr uint32_t DefaultInitialWindowSize() { return 65535; }
-
-  // Maximum value for INITIAL_WINDOW_SIZE, and for the connection flow control
-  // window, and for each stream flow control window.
-  static constexpr uint32_t MaximumWindowSize() { return UInt31Mask(); }
-
-  // Default value for MAX_FRAME_SIZE.
-  static constexpr uint32_t DefaultMaxFrameSize() { return 16384; }
-
-  // Minimum value for MAX_FRAME_SIZE.
-  static constexpr uint32_t MinimumMaxFrameSize() { return 16384; }
-
-  // Maximum value for MAX_FRAME_SIZE.
-  static constexpr uint32_t MaximumMaxFrameSize() { return (1 << 24) - 1; }
-};
-
-// Http3 early fails upper case request headers, but Http2 still needs case
-// insensitive comparison.
-using InvalidHeaderSet =
-    absl::flat_hash_set<absl::string_view, quiche::StringPieceCaseHash,
-                        quiche::StringPieceCaseEqual>;
-
-// Returns all disallowed HTTP/2 headers.
-QUICHE_EXPORT_PRIVATE const InvalidHeaderSet& GetInvalidHttp2HeaderSet();
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HTTP2_CONSTANTS_H_
diff --git a/http2/http2_constants_test.cc b/http2/http2_constants_test.cc
deleted file mode 100644
index 4a48c36..0000000
--- a/http2/http2_constants_test.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/http2_constants.h"
-
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-class Http2ConstantsTest : public QuicheTest {};
-
-TEST(Http2ConstantsTest, Http2FrameType) {
-  EXPECT_EQ(Http2FrameType::DATA, static_cast<Http2FrameType>(0));
-  EXPECT_EQ(Http2FrameType::HEADERS, static_cast<Http2FrameType>(1));
-  EXPECT_EQ(Http2FrameType::PRIORITY, static_cast<Http2FrameType>(2));
-  EXPECT_EQ(Http2FrameType::RST_STREAM, static_cast<Http2FrameType>(3));
-  EXPECT_EQ(Http2FrameType::SETTINGS, static_cast<Http2FrameType>(4));
-  EXPECT_EQ(Http2FrameType::PUSH_PROMISE, static_cast<Http2FrameType>(5));
-  EXPECT_EQ(Http2FrameType::PING, static_cast<Http2FrameType>(6));
-  EXPECT_EQ(Http2FrameType::GOAWAY, static_cast<Http2FrameType>(7));
-  EXPECT_EQ(Http2FrameType::WINDOW_UPDATE, static_cast<Http2FrameType>(8));
-  EXPECT_EQ(Http2FrameType::CONTINUATION, static_cast<Http2FrameType>(9));
-  EXPECT_EQ(Http2FrameType::ALTSVC, static_cast<Http2FrameType>(10));
-}
-
-TEST(Http2ConstantsTest, Http2FrameTypeToString) {
-  EXPECT_EQ("DATA", Http2FrameTypeToString(Http2FrameType::DATA));
-  EXPECT_EQ("HEADERS", Http2FrameTypeToString(Http2FrameType::HEADERS));
-  EXPECT_EQ("PRIORITY", Http2FrameTypeToString(Http2FrameType::PRIORITY));
-  EXPECT_EQ("RST_STREAM", Http2FrameTypeToString(Http2FrameType::RST_STREAM));
-  EXPECT_EQ("SETTINGS", Http2FrameTypeToString(Http2FrameType::SETTINGS));
-  EXPECT_EQ("PUSH_PROMISE",
-            Http2FrameTypeToString(Http2FrameType::PUSH_PROMISE));
-  EXPECT_EQ("PING", Http2FrameTypeToString(Http2FrameType::PING));
-  EXPECT_EQ("GOAWAY", Http2FrameTypeToString(Http2FrameType::GOAWAY));
-  EXPECT_EQ("WINDOW_UPDATE",
-            Http2FrameTypeToString(Http2FrameType::WINDOW_UPDATE));
-  EXPECT_EQ("CONTINUATION",
-            Http2FrameTypeToString(Http2FrameType::CONTINUATION));
-  EXPECT_EQ("ALTSVC", Http2FrameTypeToString(Http2FrameType::ALTSVC));
-
-  EXPECT_EQ("DATA", Http2FrameTypeToString(0));
-  EXPECT_EQ("HEADERS", Http2FrameTypeToString(1));
-  EXPECT_EQ("PRIORITY", Http2FrameTypeToString(2));
-  EXPECT_EQ("RST_STREAM", Http2FrameTypeToString(3));
-  EXPECT_EQ("SETTINGS", Http2FrameTypeToString(4));
-  EXPECT_EQ("PUSH_PROMISE", Http2FrameTypeToString(5));
-  EXPECT_EQ("PING", Http2FrameTypeToString(6));
-  EXPECT_EQ("GOAWAY", Http2FrameTypeToString(7));
-  EXPECT_EQ("WINDOW_UPDATE", Http2FrameTypeToString(8));
-  EXPECT_EQ("CONTINUATION", Http2FrameTypeToString(9));
-  EXPECT_EQ("ALTSVC", Http2FrameTypeToString(10));
-
-  EXPECT_EQ("UnknownFrameType(99)", Http2FrameTypeToString(99));
-}
-
-TEST(Http2ConstantsTest, Http2FrameFlag) {
-  EXPECT_EQ(Http2FrameFlag::END_STREAM, static_cast<Http2FrameFlag>(0x01));
-  EXPECT_EQ(Http2FrameFlag::ACK, static_cast<Http2FrameFlag>(0x01));
-  EXPECT_EQ(Http2FrameFlag::END_HEADERS, static_cast<Http2FrameFlag>(0x04));
-  EXPECT_EQ(Http2FrameFlag::PADDED, static_cast<Http2FrameFlag>(0x08));
-  EXPECT_EQ(Http2FrameFlag::PRIORITY, static_cast<Http2FrameFlag>(0x20));
-
-  EXPECT_EQ(Http2FrameFlag::END_STREAM, 0x01);
-  EXPECT_EQ(Http2FrameFlag::ACK, 0x01);
-  EXPECT_EQ(Http2FrameFlag::END_HEADERS, 0x04);
-  EXPECT_EQ(Http2FrameFlag::PADDED, 0x08);
-  EXPECT_EQ(Http2FrameFlag::PRIORITY, 0x20);
-}
-
-TEST(Http2ConstantsTest, Http2FrameFlagsToString) {
-  // Single flags...
-
-  // 0b00000001
-  EXPECT_EQ("END_STREAM", Http2FrameFlagsToString(Http2FrameType::DATA,
-                                                  Http2FrameFlag::END_STREAM));
-  EXPECT_EQ("END_STREAM",
-            Http2FrameFlagsToString(Http2FrameType::HEADERS, 0x01));
-  EXPECT_EQ("ACK", Http2FrameFlagsToString(Http2FrameType::SETTINGS,
-                                           Http2FrameFlag::ACK));
-  EXPECT_EQ("ACK", Http2FrameFlagsToString(Http2FrameType::PING, 0x01));
-
-  // 0b00000010
-  EXPECT_EQ("0x02", Http2FrameFlagsToString(0xff, 0x02));
-
-  // 0b00000100
-  EXPECT_EQ("END_HEADERS",
-            Http2FrameFlagsToString(Http2FrameType::HEADERS,
-                                    Http2FrameFlag::END_HEADERS));
-  EXPECT_EQ("END_HEADERS",
-            Http2FrameFlagsToString(Http2FrameType::PUSH_PROMISE, 0x04));
-  EXPECT_EQ("END_HEADERS", Http2FrameFlagsToString(0x09, 0x04));
-  EXPECT_EQ("0x04", Http2FrameFlagsToString(0xff, 0x04));
-
-  // 0b00001000
-  EXPECT_EQ("PADDED", Http2FrameFlagsToString(Http2FrameType::DATA,
-                                              Http2FrameFlag::PADDED));
-  EXPECT_EQ("PADDED", Http2FrameFlagsToString(Http2FrameType::HEADERS, 0x08));
-  EXPECT_EQ("PADDED", Http2FrameFlagsToString(0x05, 0x08));
-  EXPECT_EQ("0x08", Http2FrameFlagsToString(0xff, Http2FrameFlag::PADDED));
-
-  // 0b00010000
-  EXPECT_EQ("0x10", Http2FrameFlagsToString(Http2FrameType::SETTINGS, 0x10));
-
-  // 0b00100000
-  EXPECT_EQ("PRIORITY", Http2FrameFlagsToString(Http2FrameType::HEADERS, 0x20));
-  EXPECT_EQ("0x20",
-            Http2FrameFlagsToString(Http2FrameType::PUSH_PROMISE, 0x20));
-
-  // 0b01000000
-  EXPECT_EQ("0x40", Http2FrameFlagsToString(0xff, 0x40));
-
-  // 0b10000000
-  EXPECT_EQ("0x80", Http2FrameFlagsToString(0xff, 0x80));
-
-  // Combined flags...
-
-  EXPECT_EQ("END_STREAM|PADDED|0xf6",
-            Http2FrameFlagsToString(Http2FrameType::DATA, 0xff));
-  EXPECT_EQ("END_STREAM|END_HEADERS|PADDED|PRIORITY|0xd2",
-            Http2FrameFlagsToString(Http2FrameType::HEADERS, 0xff));
-  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::PRIORITY, 0xff));
-  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::RST_STREAM, 0xff));
-  EXPECT_EQ("ACK|0xfe",
-            Http2FrameFlagsToString(Http2FrameType::SETTINGS, 0xff));
-  EXPECT_EQ("END_HEADERS|PADDED|0xf3",
-            Http2FrameFlagsToString(Http2FrameType::PUSH_PROMISE, 0xff));
-  EXPECT_EQ("ACK|0xfe", Http2FrameFlagsToString(Http2FrameType::PING, 0xff));
-  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::GOAWAY, 0xff));
-  EXPECT_EQ("0xff",
-            Http2FrameFlagsToString(Http2FrameType::WINDOW_UPDATE, 0xff));
-  EXPECT_EQ("END_HEADERS|0xfb",
-            Http2FrameFlagsToString(Http2FrameType::CONTINUATION, 0xff));
-  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::ALTSVC, 0xff));
-  EXPECT_EQ("0xff", Http2FrameFlagsToString(0xff, 0xff));
-}
-
-TEST(Http2ConstantsTest, Http2ErrorCode) {
-  EXPECT_EQ(Http2ErrorCode::HTTP2_NO_ERROR, static_cast<Http2ErrorCode>(0x0));
-  EXPECT_EQ(Http2ErrorCode::PROTOCOL_ERROR, static_cast<Http2ErrorCode>(0x1));
-  EXPECT_EQ(Http2ErrorCode::INTERNAL_ERROR, static_cast<Http2ErrorCode>(0x2));
-  EXPECT_EQ(Http2ErrorCode::FLOW_CONTROL_ERROR,
-            static_cast<Http2ErrorCode>(0x3));
-  EXPECT_EQ(Http2ErrorCode::SETTINGS_TIMEOUT, static_cast<Http2ErrorCode>(0x4));
-  EXPECT_EQ(Http2ErrorCode::STREAM_CLOSED, static_cast<Http2ErrorCode>(0x5));
-  EXPECT_EQ(Http2ErrorCode::FRAME_SIZE_ERROR, static_cast<Http2ErrorCode>(0x6));
-  EXPECT_EQ(Http2ErrorCode::REFUSED_STREAM, static_cast<Http2ErrorCode>(0x7));
-  EXPECT_EQ(Http2ErrorCode::CANCEL, static_cast<Http2ErrorCode>(0x8));
-  EXPECT_EQ(Http2ErrorCode::COMPRESSION_ERROR,
-            static_cast<Http2ErrorCode>(0x9));
-  EXPECT_EQ(Http2ErrorCode::CONNECT_ERROR, static_cast<Http2ErrorCode>(0xa));
-  EXPECT_EQ(Http2ErrorCode::ENHANCE_YOUR_CALM,
-            static_cast<Http2ErrorCode>(0xb));
-  EXPECT_EQ(Http2ErrorCode::INADEQUATE_SECURITY,
-            static_cast<Http2ErrorCode>(0xc));
-  EXPECT_EQ(Http2ErrorCode::HTTP_1_1_REQUIRED,
-            static_cast<Http2ErrorCode>(0xd));
-}
-
-TEST(Http2ConstantsTest, Http2ErrorCodeToString) {
-  EXPECT_EQ("NO_ERROR", Http2ErrorCodeToString(Http2ErrorCode::HTTP2_NO_ERROR));
-  EXPECT_EQ("NO_ERROR", Http2ErrorCodeToString(0x0));
-  EXPECT_EQ("PROTOCOL_ERROR",
-            Http2ErrorCodeToString(Http2ErrorCode::PROTOCOL_ERROR));
-  EXPECT_EQ("PROTOCOL_ERROR", Http2ErrorCodeToString(0x1));
-  EXPECT_EQ("INTERNAL_ERROR",
-            Http2ErrorCodeToString(Http2ErrorCode::INTERNAL_ERROR));
-  EXPECT_EQ("INTERNAL_ERROR", Http2ErrorCodeToString(0x2));
-  EXPECT_EQ("FLOW_CONTROL_ERROR",
-            Http2ErrorCodeToString(Http2ErrorCode::FLOW_CONTROL_ERROR));
-  EXPECT_EQ("FLOW_CONTROL_ERROR", Http2ErrorCodeToString(0x3));
-  EXPECT_EQ("SETTINGS_TIMEOUT",
-            Http2ErrorCodeToString(Http2ErrorCode::SETTINGS_TIMEOUT));
-  EXPECT_EQ("SETTINGS_TIMEOUT", Http2ErrorCodeToString(0x4));
-  EXPECT_EQ("STREAM_CLOSED",
-            Http2ErrorCodeToString(Http2ErrorCode::STREAM_CLOSED));
-  EXPECT_EQ("STREAM_CLOSED", Http2ErrorCodeToString(0x5));
-  EXPECT_EQ("FRAME_SIZE_ERROR",
-            Http2ErrorCodeToString(Http2ErrorCode::FRAME_SIZE_ERROR));
-  EXPECT_EQ("FRAME_SIZE_ERROR", Http2ErrorCodeToString(0x6));
-  EXPECT_EQ("REFUSED_STREAM",
-            Http2ErrorCodeToString(Http2ErrorCode::REFUSED_STREAM));
-  EXPECT_EQ("REFUSED_STREAM", Http2ErrorCodeToString(0x7));
-  EXPECT_EQ("CANCEL", Http2ErrorCodeToString(Http2ErrorCode::CANCEL));
-  EXPECT_EQ("CANCEL", Http2ErrorCodeToString(0x8));
-  EXPECT_EQ("COMPRESSION_ERROR",
-            Http2ErrorCodeToString(Http2ErrorCode::COMPRESSION_ERROR));
-  EXPECT_EQ("COMPRESSION_ERROR", Http2ErrorCodeToString(0x9));
-  EXPECT_EQ("CONNECT_ERROR",
-            Http2ErrorCodeToString(Http2ErrorCode::CONNECT_ERROR));
-  EXPECT_EQ("CONNECT_ERROR", Http2ErrorCodeToString(0xa));
-  EXPECT_EQ("ENHANCE_YOUR_CALM",
-            Http2ErrorCodeToString(Http2ErrorCode::ENHANCE_YOUR_CALM));
-  EXPECT_EQ("ENHANCE_YOUR_CALM", Http2ErrorCodeToString(0xb));
-  EXPECT_EQ("INADEQUATE_SECURITY",
-            Http2ErrorCodeToString(Http2ErrorCode::INADEQUATE_SECURITY));
-  EXPECT_EQ("INADEQUATE_SECURITY", Http2ErrorCodeToString(0xc));
-  EXPECT_EQ("HTTP_1_1_REQUIRED",
-            Http2ErrorCodeToString(Http2ErrorCode::HTTP_1_1_REQUIRED));
-  EXPECT_EQ("HTTP_1_1_REQUIRED", Http2ErrorCodeToString(0xd));
-
-  EXPECT_EQ("UnknownErrorCode(0x123)", Http2ErrorCodeToString(0x123));
-}
-
-TEST(Http2ConstantsTest, Http2SettingsParameter) {
-  EXPECT_EQ(Http2SettingsParameter::HEADER_TABLE_SIZE,
-            static_cast<Http2SettingsParameter>(0x1));
-  EXPECT_EQ(Http2SettingsParameter::ENABLE_PUSH,
-            static_cast<Http2SettingsParameter>(0x2));
-  EXPECT_EQ(Http2SettingsParameter::MAX_CONCURRENT_STREAMS,
-            static_cast<Http2SettingsParameter>(0x3));
-  EXPECT_EQ(Http2SettingsParameter::INITIAL_WINDOW_SIZE,
-            static_cast<Http2SettingsParameter>(0x4));
-  EXPECT_EQ(Http2SettingsParameter::MAX_FRAME_SIZE,
-            static_cast<Http2SettingsParameter>(0x5));
-  EXPECT_EQ(Http2SettingsParameter::MAX_HEADER_LIST_SIZE,
-            static_cast<Http2SettingsParameter>(0x6));
-
-  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
-      Http2SettingsParameter::HEADER_TABLE_SIZE));
-  EXPECT_TRUE(
-      IsSupportedHttp2SettingsParameter(Http2SettingsParameter::ENABLE_PUSH));
-  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
-      Http2SettingsParameter::MAX_CONCURRENT_STREAMS));
-  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
-      Http2SettingsParameter::INITIAL_WINDOW_SIZE));
-  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
-      Http2SettingsParameter::MAX_FRAME_SIZE));
-  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
-      Http2SettingsParameter::MAX_HEADER_LIST_SIZE));
-
-  EXPECT_FALSE(IsSupportedHttp2SettingsParameter(
-      static_cast<Http2SettingsParameter>(0)));
-  EXPECT_FALSE(IsSupportedHttp2SettingsParameter(
-      static_cast<Http2SettingsParameter>(7)));
-}
-
-TEST(Http2ConstantsTest, Http2SettingsParameterToString) {
-  EXPECT_EQ("HEADER_TABLE_SIZE",
-            Http2SettingsParameterToString(
-                Http2SettingsParameter::HEADER_TABLE_SIZE));
-  EXPECT_EQ("HEADER_TABLE_SIZE", Http2SettingsParameterToString(0x1));
-  EXPECT_EQ("ENABLE_PUSH", Http2SettingsParameterToString(
-                               Http2SettingsParameter::ENABLE_PUSH));
-  EXPECT_EQ("ENABLE_PUSH", Http2SettingsParameterToString(0x2));
-  EXPECT_EQ("MAX_CONCURRENT_STREAMS",
-            Http2SettingsParameterToString(
-                Http2SettingsParameter::MAX_CONCURRENT_STREAMS));
-  EXPECT_EQ("MAX_CONCURRENT_STREAMS", Http2SettingsParameterToString(0x3));
-  EXPECT_EQ("INITIAL_WINDOW_SIZE",
-            Http2SettingsParameterToString(
-                Http2SettingsParameter::INITIAL_WINDOW_SIZE));
-  EXPECT_EQ("INITIAL_WINDOW_SIZE", Http2SettingsParameterToString(0x4));
-  EXPECT_EQ("MAX_FRAME_SIZE", Http2SettingsParameterToString(
-                                  Http2SettingsParameter::MAX_FRAME_SIZE));
-  EXPECT_EQ("MAX_FRAME_SIZE", Http2SettingsParameterToString(0x5));
-  EXPECT_EQ("MAX_HEADER_LIST_SIZE",
-            Http2SettingsParameterToString(
-                Http2SettingsParameter::MAX_HEADER_LIST_SIZE));
-  EXPECT_EQ("MAX_HEADER_LIST_SIZE", Http2SettingsParameterToString(0x6));
-
-  EXPECT_EQ("UnknownSettingsParameter(0x123)",
-            Http2SettingsParameterToString(0x123));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/http2_constants_test_util.cc b/http2/http2_constants_test_util.cc
deleted file mode 100644
index 0734ffb..0000000
--- a/http2/http2_constants_test_util.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/http2_constants_test_util.h"
-
-namespace http2 {
-namespace test {
-
-std::vector<Http2ErrorCode> AllHttp2ErrorCodes() {
-  // clang-format off
-  return {
-      Http2ErrorCode::HTTP2_NO_ERROR,
-      Http2ErrorCode::PROTOCOL_ERROR,
-      Http2ErrorCode::INTERNAL_ERROR,
-      Http2ErrorCode::FLOW_CONTROL_ERROR,
-      Http2ErrorCode::SETTINGS_TIMEOUT,
-      Http2ErrorCode::STREAM_CLOSED,
-      Http2ErrorCode::FRAME_SIZE_ERROR,
-      Http2ErrorCode::REFUSED_STREAM,
-      Http2ErrorCode::CANCEL,
-      Http2ErrorCode::COMPRESSION_ERROR,
-      Http2ErrorCode::CONNECT_ERROR,
-      Http2ErrorCode::ENHANCE_YOUR_CALM,
-      Http2ErrorCode::INADEQUATE_SECURITY,
-      Http2ErrorCode::HTTP_1_1_REQUIRED,
-  };
-  // clang-format on
-}
-
-std::vector<Http2SettingsParameter> AllHttp2SettingsParameters() {
-  // clang-format off
-  return {
-      Http2SettingsParameter::HEADER_TABLE_SIZE,
-      Http2SettingsParameter::ENABLE_PUSH,
-      Http2SettingsParameter::MAX_CONCURRENT_STREAMS,
-      Http2SettingsParameter::INITIAL_WINDOW_SIZE,
-      Http2SettingsParameter::MAX_FRAME_SIZE,
-      Http2SettingsParameter::MAX_HEADER_LIST_SIZE,
-  };
-  // clang-format on
-}
-
-// Returns a mask of flags supported for the specified frame type. Returns
-// zero for unknown frame types.
-uint8_t KnownFlagsMaskForFrameType(Http2FrameType type) {
-  switch (type) {
-    case Http2FrameType::DATA:
-      return Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED;
-    case Http2FrameType::HEADERS:
-      return Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS |
-             Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY;
-    case Http2FrameType::PRIORITY:
-      return 0x00;
-    case Http2FrameType::RST_STREAM:
-      return 0x00;
-    case Http2FrameType::SETTINGS:
-      return Http2FrameFlag::ACK;
-    case Http2FrameType::PUSH_PROMISE:
-      return Http2FrameFlag::END_HEADERS | Http2FrameFlag::PADDED;
-    case Http2FrameType::PING:
-      return Http2FrameFlag::ACK;
-    case Http2FrameType::GOAWAY:
-      return 0x00;
-    case Http2FrameType::WINDOW_UPDATE:
-      return 0x00;
-    case Http2FrameType::CONTINUATION:
-      return Http2FrameFlag::END_HEADERS;
-    case Http2FrameType::ALTSVC:
-      return 0x00;
-    default:
-      return 0x00;
-  }
-}
-
-uint8_t InvalidFlagMaskForFrameType(Http2FrameType type) {
-  if (IsSupportedHttp2FrameType(type)) {
-    return ~KnownFlagsMaskForFrameType(type);
-  }
-  return 0x00;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/http2_constants_test_util.h b/http2/http2_constants_test_util.h
deleted file mode 100644
index 27529ae..0000000
--- a/http2/http2_constants_test_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HTTP2_CONSTANTS_TEST_UTIL_H_
-#define QUICHE_HTTP2_HTTP2_CONSTANTS_TEST_UTIL_H_
-
-#include <cstdint>
-#include <vector>
-
-#include "http2/http2_constants.h"
-
-namespace http2 {
-namespace test {
-
-// Returns a vector of all supported RST_STREAM and GOAWAY error codes.
-std::vector<Http2ErrorCode> AllHttp2ErrorCodes();
-
-// Returns a vector of all supported parameters in SETTINGS frames.
-std::vector<Http2SettingsParameter> AllHttp2SettingsParameters();
-
-// Returns a mask of flags supported for the specified frame type. Returns
-// zero for unknown frame types.
-uint8_t KnownFlagsMaskForFrameType(Http2FrameType type);
-
-// Returns a mask of flag bits known to be invalid for the frame type.
-// For unknown frame types, the mask is zero; i.e., we don't know that any
-// are invalid.
-uint8_t InvalidFlagMaskForFrameType(Http2FrameType type);
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HTTP2_CONSTANTS_TEST_UTIL_H_
diff --git a/http2/http2_structures.cc b/http2/http2_structures.cc
deleted file mode 100644
index f8a8fad..0000000
--- a/http2/http2_structures.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/http2_structures.h"
-
-#include <cstring>  // For std::memcmp
-#include <sstream>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-
-namespace http2 {
-
-// Http2FrameHeader:
-
-bool Http2FrameHeader::IsProbableHttpResponse() const {
-  return (payload_length == 0x485454 &&      // "HTT"
-          static_cast<char>(type) == 'P' &&  // "P"
-          flags == '/');                     // "/"
-}
-
-std::string Http2FrameHeader::ToString() const {
-  return absl::StrCat("length=", payload_length,
-                      ", type=", Http2FrameTypeToString(type),
-                      ", flags=", FlagsToString(), ", stream=", stream_id);
-}
-
-std::string Http2FrameHeader::FlagsToString() const {
-  return Http2FrameFlagsToString(type, flags);
-}
-
-bool operator==(const Http2FrameHeader& a, const Http2FrameHeader& b) {
-  return a.payload_length == b.payload_length && a.stream_id == b.stream_id &&
-         a.type == b.type && a.flags == b.flags;
-}
-
-std::ostream& operator<<(std::ostream& out, const Http2FrameHeader& v) {
-  return out << v.ToString();
-}
-
-// Http2PriorityFields:
-
-bool operator==(const Http2PriorityFields& a, const Http2PriorityFields& b) {
-  return a.stream_dependency == b.stream_dependency && a.weight == b.weight;
-}
-
-std::string Http2PriorityFields::ToString() const {
-  std::stringstream ss;
-  ss << "E=" << (is_exclusive ? "true" : "false")
-     << ", stream=" << stream_dependency
-     << ", weight=" << static_cast<uint32_t>(weight);
-  return ss.str();
-}
-
-std::ostream& operator<<(std::ostream& out, const Http2PriorityFields& v) {
-  return out << v.ToString();
-}
-
-// Http2RstStreamFields:
-
-bool operator==(const Http2RstStreamFields& a, const Http2RstStreamFields& b) {
-  return a.error_code == b.error_code;
-}
-
-std::ostream& operator<<(std::ostream& out, const Http2RstStreamFields& v) {
-  return out << "error_code=" << v.error_code;
-}
-
-// Http2SettingFields:
-
-bool operator==(const Http2SettingFields& a, const Http2SettingFields& b) {
-  return a.parameter == b.parameter && a.value == b.value;
-}
-std::ostream& operator<<(std::ostream& out, const Http2SettingFields& v) {
-  return out << "parameter=" << v.parameter << ", value=" << v.value;
-}
-
-// Http2PushPromiseFields:
-
-bool operator==(const Http2PushPromiseFields& a,
-                const Http2PushPromiseFields& b) {
-  return a.promised_stream_id == b.promised_stream_id;
-}
-
-std::ostream& operator<<(std::ostream& out, const Http2PushPromiseFields& v) {
-  return out << "promised_stream_id=" << v.promised_stream_id;
-}
-
-// Http2PingFields:
-
-bool operator==(const Http2PingFields& a, const Http2PingFields& b) {
-  static_assert((sizeof a.opaque_bytes) == Http2PingFields::EncodedSize(),
-                "Why not the same size?");
-  return 0 ==
-         std::memcmp(a.opaque_bytes, b.opaque_bytes, sizeof a.opaque_bytes);
-}
-
-std::ostream& operator<<(std::ostream& out, const Http2PingFields& v) {
-  return out << "opaque_bytes=0x"
-             << absl::BytesToHexString(absl::string_view(
-                    reinterpret_cast<const char*>(v.opaque_bytes),
-                    sizeof v.opaque_bytes));
-}
-
-// Http2GoAwayFields:
-
-bool operator==(const Http2GoAwayFields& a, const Http2GoAwayFields& b) {
-  return a.last_stream_id == b.last_stream_id && a.error_code == b.error_code;
-}
-std::ostream& operator<<(std::ostream& out, const Http2GoAwayFields& v) {
-  return out << "last_stream_id=" << v.last_stream_id
-             << ", error_code=" << v.error_code;
-}
-
-// Http2WindowUpdateFields:
-
-bool operator==(const Http2WindowUpdateFields& a,
-                const Http2WindowUpdateFields& b) {
-  return a.window_size_increment == b.window_size_increment;
-}
-std::ostream& operator<<(std::ostream& out, const Http2WindowUpdateFields& v) {
-  return out << "window_size_increment=" << v.window_size_increment;
-}
-
-// Http2AltSvcFields:
-
-bool operator==(const Http2AltSvcFields& a, const Http2AltSvcFields& b) {
-  return a.origin_length == b.origin_length;
-}
-std::ostream& operator<<(std::ostream& out, const Http2AltSvcFields& v) {
-  return out << "origin_length=" << v.origin_length;
-}
-
-// Http2PriorityUpdateFields:
-
-bool operator==(const Http2PriorityUpdateFields& a,
-                const Http2PriorityUpdateFields& b) {
-  return a.prioritized_stream_id == b.prioritized_stream_id;
-}
-
-std::string Http2PriorityUpdateFields::ToString() const {
-  std::stringstream ss;
-  ss << "prioritized_stream_id=" << prioritized_stream_id;
-  return ss.str();
-}
-
-std::ostream& operator<<(std::ostream& out,
-                         const Http2PriorityUpdateFields& v) {
-  return out << v.ToString();
-}
-
-}  // namespace http2
diff --git a/http2/http2_structures.h b/http2/http2_structures.h
deleted file mode 100644
index f1ea5b3..0000000
--- a/http2/http2_structures.h
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HTTP2_STRUCTURES_H_
-#define QUICHE_HTTP2_HTTP2_STRUCTURES_H_
-
-// Defines structs for various fixed sized structures in HTTP/2.
-//
-// Those structs with multiple fields have constructors that take arguments in
-// the same order as their encoding (which may be different from their order
-// in the struct). For single field structs, use aggregate initialization if
-// desired, e.g.:
-//
-//   Http2RstStreamFields var{Http2ErrorCode::ENHANCE_YOUR_CALM};
-// or:
-//   SomeFunc(Http2RstStreamFields{Http2ErrorCode::ENHANCE_YOUR_CALM});
-//
-// Each struct includes a static method EncodedSize which returns the number
-// of bytes of the encoding.
-//
-// With the exception of Http2FrameHeader, all the types are named
-// Http2<X>Fields, where X is the title-case form of the frame which always
-// includes the fields; the "always" is to cover the case of the PRIORITY frame;
-// its fields optionally appear in the HEADERS frame, but the struct is called
-// Http2PriorityFields.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace http2 {
-
-struct QUICHE_EXPORT_PRIVATE Http2FrameHeader {
-  Http2FrameHeader() {}
-  Http2FrameHeader(uint32_t payload_length, Http2FrameType type, uint8_t flags,
-                   uint32_t stream_id)
-      : payload_length(payload_length),
-        stream_id(stream_id),
-        type(type),
-        flags(flags) {
-    QUICHE_DCHECK_LT(payload_length, static_cast<uint32_t>(1 << 24))
-        << "Payload Length is only a 24 bit field\n"
-        << ToString();
-  }
-
-  static constexpr size_t EncodedSize() { return 9; }
-
-  // Keep the current value of those flags that are in
-  // valid_flags, and clear all the others.
-  void RetainFlags(uint8_t valid_flags) { flags = (flags & valid_flags); }
-
-  // Returns true if any of the flags in flag_mask are set,
-  // otherwise false.
-  bool HasAnyFlags(uint8_t flag_mask) const { return 0 != (flags & flag_mask); }
-
-  // Is the END_STREAM flag set?
-  bool IsEndStream() const {
-    QUICHE_DCHECK(type == Http2FrameType::DATA ||
-                  type == Http2FrameType::HEADERS)
-        << ToString();
-    return (flags & Http2FrameFlag::END_STREAM) != 0;
-  }
-
-  // Is the ACK flag set?
-  bool IsAck() const {
-    QUICHE_DCHECK(type == Http2FrameType::SETTINGS ||
-                  type == Http2FrameType::PING)
-        << ToString();
-    return (flags & Http2FrameFlag::ACK) != 0;
-  }
-
-  // Is the END_HEADERS flag set?
-  bool IsEndHeaders() const {
-    QUICHE_DCHECK(type == Http2FrameType::HEADERS ||
-                  type == Http2FrameType::PUSH_PROMISE ||
-                  type == Http2FrameType::CONTINUATION)
-        << ToString();
-    return (flags & Http2FrameFlag::END_HEADERS) != 0;
-  }
-
-  // Is the PADDED flag set?
-  bool IsPadded() const {
-    QUICHE_DCHECK(type == Http2FrameType::DATA ||
-                  type == Http2FrameType::HEADERS ||
-                  type == Http2FrameType::PUSH_PROMISE)
-        << ToString();
-    return (flags & Http2FrameFlag::PADDED) != 0;
-  }
-
-  // Is the PRIORITY flag set?
-  bool HasPriority() const {
-    QUICHE_DCHECK_EQ(type, Http2FrameType::HEADERS) << ToString();
-    return (flags & Http2FrameFlag::PRIORITY) != 0;
-  }
-
-  // Does the encoding of this header start with "HTTP/", indicating that it
-  // might be from a non-HTTP/2 server.
-  bool IsProbableHttpResponse() const;
-
-  // Produce strings useful for debugging/logging messages.
-  std::string ToString() const;
-  std::string FlagsToString() const;
-
-  // 24 bit length of the payload after the header, including any padding.
-  // First field in encoding.
-  uint32_t payload_length;  // 24 bits
-
-  // 31 bit stream id, with high bit (32nd bit) reserved (must be zero),
-  // and is cleared during decoding.
-  // Fourth field in encoding.
-  uint32_t stream_id;
-
-  // Type of the frame.
-  // Second field in encoding.
-  Http2FrameType type;
-
-  // Flag bits, with interpretations that depend upon the frame type.
-  // Flag bits not used by the frame type are cleared.
-  // Third field in encoding.
-  uint8_t flags;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2FrameHeader& a,
-                                      const Http2FrameHeader& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2FrameHeader& a,
-                                             const Http2FrameHeader& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2FrameHeader& v);
-
-// Http2PriorityFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2PriorityFields {
-  Http2PriorityFields() {}
-  Http2PriorityFields(uint32_t stream_dependency,
-                      uint32_t weight,
-                      bool is_exclusive)
-      : stream_dependency(stream_dependency),
-        weight(weight),
-        is_exclusive(is_exclusive) {
-    // Can't have the high-bit set in the stream id because we need to use
-    // that for the EXCLUSIVE flag bit.
-    QUICHE_DCHECK_EQ(stream_dependency, stream_dependency & StreamIdMask())
-        << "Stream Dependency is only a 31-bit field.\n"
-        << ToString();
-    QUICHE_DCHECK_LE(1u, weight) << "Weight is too small.";
-    QUICHE_DCHECK_LE(weight, 256u) << "Weight is too large.";
-  }
-  static constexpr size_t EncodedSize() { return 5; }
-
-  // Produce strings useful for debugging/logging messages.
-  std::string ToString() const;
-
-  // A 31-bit stream identifier for the stream that this stream depends on.
-  uint32_t stream_dependency;
-
-  // Weight (1 to 256) is encoded as a byte in the range 0 to 255, so we
-  // add one when decoding, and store it in a field larger than a byte.
-  uint32_t weight;
-
-  // A single-bit flag indicating that the stream dependency is exclusive;
-  // extracted from high bit of stream dependency field during decoding.
-  bool is_exclusive;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2PriorityFields& a,
-                                      const Http2PriorityFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2PriorityFields& a,
-                                             const Http2PriorityFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2PriorityFields& v);
-
-// Http2RstStreamFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2RstStreamFields {
-  static constexpr size_t EncodedSize() { return 4; }
-  bool IsSupportedErrorCode() const {
-    return IsSupportedHttp2ErrorCode(error_code);
-  }
-
-  Http2ErrorCode error_code;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2RstStreamFields& a,
-                                      const Http2RstStreamFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2RstStreamFields& a,
-                                             const Http2RstStreamFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2RstStreamFields& v);
-
-// Http2SettingFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2SettingFields {
-  Http2SettingFields() {}
-  Http2SettingFields(Http2SettingsParameter parameter, uint32_t value)
-      : parameter(parameter), value(value) {}
-  static constexpr size_t EncodedSize() { return 6; }
-  bool IsSupportedParameter() const {
-    return IsSupportedHttp2SettingsParameter(parameter);
-  }
-
-  Http2SettingsParameter parameter;
-  uint32_t value;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2SettingFields& a,
-                                      const Http2SettingFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2SettingFields& a,
-                                             const Http2SettingFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2SettingFields& v);
-
-// Http2PushPromiseFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2PushPromiseFields {
-  static constexpr size_t EncodedSize() { return 4; }
-
-  uint32_t promised_stream_id;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2PushPromiseFields& a,
-                                      const Http2PushPromiseFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2PushPromiseFields& a,
-                                             const Http2PushPromiseFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2PushPromiseFields& v);
-
-// Http2PingFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2PingFields {
-  static constexpr size_t EncodedSize() { return 8; }
-
-  uint8_t opaque_bytes[8];
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2PingFields& a,
-                                      const Http2PingFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2PingFields& a,
-                                             const Http2PingFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2PingFields& v);
-
-// Http2GoAwayFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2GoAwayFields {
-  Http2GoAwayFields() {}
-  Http2GoAwayFields(uint32_t last_stream_id, Http2ErrorCode error_code)
-      : last_stream_id(last_stream_id), error_code(error_code) {}
-  static constexpr size_t EncodedSize() { return 8; }
-  bool IsSupportedErrorCode() const {
-    return IsSupportedHttp2ErrorCode(error_code);
-  }
-
-  uint32_t last_stream_id;
-  Http2ErrorCode error_code;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2GoAwayFields& a,
-                                      const Http2GoAwayFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2GoAwayFields& a,
-                                             const Http2GoAwayFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2GoAwayFields& v);
-
-// Http2WindowUpdateFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2WindowUpdateFields {
-  static constexpr size_t EncodedSize() { return 4; }
-
-  // 31-bit, unsigned increase in the window size (only positive values are
-  // allowed). The high-bit is reserved for the future.
-  uint32_t window_size_increment;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2WindowUpdateFields& a,
-                                      const Http2WindowUpdateFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2WindowUpdateFields& a,
-                                             const Http2WindowUpdateFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& out,
-    const Http2WindowUpdateFields& v);
-
-// Http2AltSvcFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2AltSvcFields {
-  static constexpr size_t EncodedSize() { return 2; }
-
-  // This is the one fixed size portion of the ALTSVC payload.
-  uint16_t origin_length;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2AltSvcFields& a,
-                                      const Http2AltSvcFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2AltSvcFields& a,
-                                             const Http2AltSvcFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               const Http2AltSvcFields& v);
-
-// Http2PriorityUpdateFields:
-
-struct QUICHE_EXPORT_PRIVATE Http2PriorityUpdateFields {
-  Http2PriorityUpdateFields() {}
-  Http2PriorityUpdateFields(uint32_t prioritized_stream_id)
-      : prioritized_stream_id(prioritized_stream_id) {}
-  static constexpr size_t EncodedSize() { return 4; }
-
-  // Produce strings useful for debugging/logging messages.
-  std::string ToString() const;
-
-  // The 31-bit stream identifier of the stream whose priority is updated.
-  uint32_t prioritized_stream_id;
-};
-
-QUICHE_EXPORT_PRIVATE bool operator==(const Http2PriorityUpdateFields& a,
-                                      const Http2PriorityUpdateFields& b);
-QUICHE_EXPORT_PRIVATE inline bool operator!=(
-    const Http2PriorityUpdateFields& a,
-    const Http2PriorityUpdateFields& b) {
-  return !(a == b);
-}
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& out,
-    const Http2PriorityUpdateFields& v);
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HTTP2_STRUCTURES_H_
diff --git a/http2/http2_structures_test.cc b/http2/http2_structures_test.cc
deleted file mode 100644
index dfe3390..0000000
--- a/http2/http2_structures_test.cc
+++ /dev/null
@@ -1,560 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/http2_structures.h"
-
-// Tests are focused on Http2FrameHeader because it has by far the most
-// methods of any of the structures.
-// Note that EXPECT.*DEATH tests are slow (a fork is probably involved).
-
-// And in case you're wondering, yes, these are ridiculously thorough tests,
-// but believe it or not, I've found silly bugs this way.
-
-#include <memory>
-#include <ostream>
-#include <sstream>
-#include <string>
-#include <tuple>
-#include <type_traits>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::Combine;
-using ::testing::HasSubstr;
-using ::testing::MatchesRegex;
-using ::testing::Not;
-using ::testing::Values;
-using ::testing::ValuesIn;
-
-namespace http2 {
-namespace test {
-namespace {
-
-template <typename E>
-E IncrementEnum(E e) {
-  using I = typename std::underlying_type<E>::type;
-  return static_cast<E>(1 + static_cast<I>(e));
-}
-
-template <class T>
-AssertionResult VerifyRandomCalls() {
-  T t1;
-  // Initialize with a stable key, to avoid test flakiness.
-  Http2Random seq1(
-      "6d9a61ddf2bc1fc0b8245505a1f28e324559d8b5c9c3268f38b42b1af3287c47");
-  Randomize(&t1, &seq1);
-
-  T t2;
-  Http2Random seq2(seq1.Key());
-  Randomize(&t2, &seq2);
-
-  // The two Randomize calls should have made the same number of calls into
-  // the Http2Random implementations.
-  VERIFY_EQ(seq1.Rand64(), seq2.Rand64());
-
-  // And because Http2Random implementation is returning the same sequence, and
-  // Randomize should have been consistent in applying those results, the two
-  // Ts should have the same value.
-  VERIFY_EQ(t1, t2);
-
-  Randomize(&t2, &seq2);
-  VERIFY_NE(t1, t2);
-
-  Randomize(&t1, &seq1);
-  VERIFY_EQ(t1, t2);
-
-  VERIFY_EQ(seq1.Rand64(), seq2.Rand64());
-
-  return AssertionSuccess();
-}
-
-#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-std::vector<Http2FrameType> ValidFrameTypes() {
-  std::vector<Http2FrameType> valid_types{Http2FrameType::DATA};
-  while (valid_types.back() != Http2FrameType::ALTSVC) {
-    valid_types.push_back(IncrementEnum(valid_types.back()));
-  }
-  return valid_types;
-}
-#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-
-TEST(Http2FrameHeaderTest, Constructor) {
-  Http2Random random;
-  uint8_t frame_type = 0;
-  do {
-    // Only the payload length is QUICHE_DCHECK'd in the constructor, so we need
-    // to make sure it is a "uint24".
-    uint32_t payload_length = random.Rand32() & 0xffffff;
-    Http2FrameType type = static_cast<Http2FrameType>(frame_type);
-    uint8_t flags = random.Rand8();
-    uint32_t stream_id = random.Rand32();
-
-    Http2FrameHeader v(payload_length, type, flags, stream_id);
-
-    EXPECT_EQ(payload_length, v.payload_length);
-    EXPECT_EQ(type, v.type);
-    EXPECT_EQ(flags, v.flags);
-    EXPECT_EQ(stream_id, v.stream_id);
-  } while (frame_type++ != 255);
-
-#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-  EXPECT_DEBUG_DEATH(Http2FrameHeader(0x01000000, Http2FrameType::DATA, 0, 1),
-                     "payload_length");
-#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-}
-
-TEST(Http2FrameHeaderTest, Eq) {
-  Http2Random random;
-  uint32_t payload_length = random.Rand32() & 0xffffff;
-  Http2FrameType type = static_cast<Http2FrameType>(random.Rand8());
-
-  uint8_t flags = random.Rand8();
-  uint32_t stream_id = random.Rand32();
-
-  Http2FrameHeader v(payload_length, type, flags, stream_id);
-
-  EXPECT_EQ(payload_length, v.payload_length);
-  EXPECT_EQ(type, v.type);
-  EXPECT_EQ(flags, v.flags);
-  EXPECT_EQ(stream_id, v.stream_id);
-
-  Http2FrameHeader u(0, type, ~flags, stream_id);
-
-  EXPECT_NE(u, v);
-  EXPECT_NE(v, u);
-  EXPECT_FALSE(u == v);
-  EXPECT_FALSE(v == u);
-  EXPECT_TRUE(u != v);
-  EXPECT_TRUE(v != u);
-
-  u = v;
-
-  EXPECT_EQ(u, v);
-  EXPECT_EQ(v, u);
-  EXPECT_TRUE(u == v);
-  EXPECT_TRUE(v == u);
-  EXPECT_FALSE(u != v);
-  EXPECT_FALSE(v != u);
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2FrameHeader>());
-}
-
-#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-// The tests of the valid frame types include EXPECT_DEBUG_DEATH, which is
-// quite slow, so using value parameterized tests in order to allow sharding.
-class Http2FrameHeaderTypeAndFlagTest
-    : public QuicheTestWithParam<std::tuple<Http2FrameType, Http2FrameFlag>> {
- protected:
-  Http2FrameHeaderTypeAndFlagTest()
-      : type_(std::get<0>(GetParam())), flags_(std::get<1>(GetParam())) {
-    HTTP2_LOG(INFO) << "Frame type: " << type_;
-    HTTP2_LOG(INFO) << "Frame flags: "
-                    << Http2FrameFlagsToString(type_, flags_);
-  }
-
-  const Http2FrameType type_;
-  const Http2FrameFlag flags_;
-};
-
-class IsEndStreamTest : public Http2FrameHeaderTypeAndFlagTest {};
-INSTANTIATE_TEST_SUITE_P(IsEndStream,
-                         IsEndStreamTest,
-                         Combine(ValuesIn(ValidFrameTypes()),
-                                 Values(~Http2FrameFlag::END_STREAM, 0xff)));
-TEST_P(IsEndStreamTest, IsEndStream) {
-  const bool is_set =
-      (flags_ & Http2FrameFlag::END_STREAM) == Http2FrameFlag::END_STREAM;
-  std::string flags_string;
-  Http2FrameHeader v(0, type_, flags_, 0);
-  switch (type_) {
-    case Http2FrameType::DATA:
-    case Http2FrameType::HEADERS:
-      EXPECT_EQ(is_set, v.IsEndStream()) << v;
-      flags_string = v.FlagsToString();
-      if (is_set) {
-        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?END_STREAM\\|.*"));
-      } else {
-        EXPECT_THAT(flags_string, Not(HasSubstr("END_STREAM")));
-      }
-      v.RetainFlags(Http2FrameFlag::END_STREAM);
-      EXPECT_EQ(is_set, v.IsEndStream()) << v;
-      {
-        std::stringstream s;
-        s << v;
-        EXPECT_EQ(v.ToString(), s.str());
-        if (is_set) {
-          EXPECT_THAT(s.str(), HasSubstr("flags=END_STREAM,"));
-        } else {
-          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
-        }
-      }
-      break;
-    default:
-      EXPECT_DEBUG_DEATH(v.IsEndStream(), "DATA.*HEADERS") << v;
-  }
-}
-
-class IsACKTest : public Http2FrameHeaderTypeAndFlagTest {};
-INSTANTIATE_TEST_SUITE_P(IsAck,
-                         IsACKTest,
-                         Combine(ValuesIn(ValidFrameTypes()),
-                                 Values(~Http2FrameFlag::ACK, 0xff)));
-TEST_P(IsACKTest, IsAck) {
-  const bool is_set = (flags_ & Http2FrameFlag::ACK) == Http2FrameFlag::ACK;
-  std::string flags_string;
-  Http2FrameHeader v(0, type_, flags_, 0);
-  switch (type_) {
-    case Http2FrameType::SETTINGS:
-    case Http2FrameType::PING:
-      EXPECT_EQ(is_set, v.IsAck()) << v;
-      flags_string = v.FlagsToString();
-      if (is_set) {
-        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?ACK\\|.*"));
-      } else {
-        EXPECT_THAT(flags_string, Not(HasSubstr("ACK")));
-      }
-      v.RetainFlags(Http2FrameFlag::ACK);
-      EXPECT_EQ(is_set, v.IsAck()) << v;
-      {
-        std::stringstream s;
-        s << v;
-        EXPECT_EQ(v.ToString(), s.str());
-        if (is_set) {
-          EXPECT_THAT(s.str(), HasSubstr("flags=ACK,"));
-        } else {
-          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
-        }
-      }
-      break;
-    default:
-      EXPECT_DEBUG_DEATH(v.IsAck(), "SETTINGS.*PING") << v;
-  }
-}
-
-class IsEndHeadersTest : public Http2FrameHeaderTypeAndFlagTest {};
-INSTANTIATE_TEST_SUITE_P(IsEndHeaders,
-                         IsEndHeadersTest,
-                         Combine(ValuesIn(ValidFrameTypes()),
-                                 Values(~Http2FrameFlag::END_HEADERS, 0xff)));
-TEST_P(IsEndHeadersTest, IsEndHeaders) {
-  const bool is_set =
-      (flags_ & Http2FrameFlag::END_HEADERS) == Http2FrameFlag::END_HEADERS;
-  std::string flags_string;
-  Http2FrameHeader v(0, type_, flags_, 0);
-  switch (type_) {
-    case Http2FrameType::HEADERS:
-    case Http2FrameType::PUSH_PROMISE:
-    case Http2FrameType::CONTINUATION:
-      EXPECT_EQ(is_set, v.IsEndHeaders()) << v;
-      flags_string = v.FlagsToString();
-      if (is_set) {
-        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?END_HEADERS\\|.*"));
-      } else {
-        EXPECT_THAT(flags_string, Not(HasSubstr("END_HEADERS")));
-      }
-      v.RetainFlags(Http2FrameFlag::END_HEADERS);
-      EXPECT_EQ(is_set, v.IsEndHeaders()) << v;
-      {
-        std::stringstream s;
-        s << v;
-        EXPECT_EQ(v.ToString(), s.str());
-        if (is_set) {
-          EXPECT_THAT(s.str(), HasSubstr("flags=END_HEADERS,"));
-        } else {
-          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
-        }
-      }
-      break;
-    default:
-      EXPECT_DEBUG_DEATH(v.IsEndHeaders(),
-                         "HEADERS.*PUSH_PROMISE.*CONTINUATION")
-          << v;
-  }
-}
-
-class IsPaddedTest : public Http2FrameHeaderTypeAndFlagTest {};
-INSTANTIATE_TEST_SUITE_P(IsPadded,
-                         IsPaddedTest,
-                         Combine(ValuesIn(ValidFrameTypes()),
-                                 Values(~Http2FrameFlag::PADDED, 0xff)));
-TEST_P(IsPaddedTest, IsPadded) {
-  const bool is_set =
-      (flags_ & Http2FrameFlag::PADDED) == Http2FrameFlag::PADDED;
-  std::string flags_string;
-  Http2FrameHeader v(0, type_, flags_, 0);
-  switch (type_) {
-    case Http2FrameType::DATA:
-    case Http2FrameType::HEADERS:
-    case Http2FrameType::PUSH_PROMISE:
-      EXPECT_EQ(is_set, v.IsPadded()) << v;
-      flags_string = v.FlagsToString();
-      if (is_set) {
-        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?PADDED\\|.*"));
-      } else {
-        EXPECT_THAT(flags_string, Not(HasSubstr("PADDED")));
-      }
-      v.RetainFlags(Http2FrameFlag::PADDED);
-      EXPECT_EQ(is_set, v.IsPadded()) << v;
-      {
-        std::stringstream s;
-        s << v;
-        EXPECT_EQ(v.ToString(), s.str());
-        if (is_set) {
-          EXPECT_THAT(s.str(), HasSubstr("flags=PADDED,"));
-        } else {
-          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
-        }
-      }
-      break;
-    default:
-      EXPECT_DEBUG_DEATH(v.IsPadded(), "DATA.*HEADERS.*PUSH_PROMISE") << v;
-  }
-}
-
-class HasPriorityTest : public Http2FrameHeaderTypeAndFlagTest {};
-INSTANTIATE_TEST_SUITE_P(HasPriority,
-                         HasPriorityTest,
-                         Combine(ValuesIn(ValidFrameTypes()),
-                                 Values(~Http2FrameFlag::PRIORITY, 0xff)));
-TEST_P(HasPriorityTest, HasPriority) {
-  const bool is_set =
-      (flags_ & Http2FrameFlag::PRIORITY) == Http2FrameFlag::PRIORITY;
-  std::string flags_string;
-  Http2FrameHeader v(0, type_, flags_, 0);
-  switch (type_) {
-    case Http2FrameType::HEADERS:
-      EXPECT_EQ(is_set, v.HasPriority()) << v;
-      flags_string = v.FlagsToString();
-      if (is_set) {
-        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?PRIORITY\\|.*"));
-      } else {
-        EXPECT_THAT(flags_string, Not(HasSubstr("PRIORITY")));
-      }
-      v.RetainFlags(Http2FrameFlag::PRIORITY);
-      EXPECT_EQ(is_set, v.HasPriority()) << v;
-      {
-        std::stringstream s;
-        s << v;
-        EXPECT_EQ(v.ToString(), s.str());
-        if (is_set) {
-          EXPECT_THAT(s.str(), HasSubstr("flags=PRIORITY,"));
-        } else {
-          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
-        }
-      }
-      break;
-    default:
-      EXPECT_DEBUG_DEATH(v.HasPriority(), "HEADERS") << v;
-  }
-}
-
-TEST(Http2PriorityFieldsTest, Constructor) {
-  Http2Random random;
-  uint32_t stream_dependency = random.Rand32() & StreamIdMask();
-  uint32_t weight = 1 + random.Rand8();
-  bool is_exclusive = random.OneIn(2);
-
-  Http2PriorityFields v(stream_dependency, weight, is_exclusive);
-
-  EXPECT_EQ(stream_dependency, v.stream_dependency);
-  EXPECT_EQ(weight, v.weight);
-  EXPECT_EQ(is_exclusive, v.is_exclusive);
-
-  // The high-bit must not be set on the stream id.
-  EXPECT_DEBUG_DEATH(
-      Http2PriorityFields(stream_dependency | 0x80000000, weight, is_exclusive),
-      "31-bit");
-
-  // The weight must be in the range 1-256.
-  EXPECT_DEBUG_DEATH(Http2PriorityFields(stream_dependency, 0, is_exclusive),
-                     "too small");
-  EXPECT_DEBUG_DEATH(
-      Http2PriorityFields(stream_dependency, weight + 256, is_exclusive),
-      "too large");
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2PriorityFields>());
-}
-#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-
-TEST(Http2RstStreamFieldsTest, IsSupported) {
-  Http2RstStreamFields v{Http2ErrorCode::HTTP2_NO_ERROR};
-  EXPECT_TRUE(v.IsSupportedErrorCode()) << v;
-
-  Http2RstStreamFields u{static_cast<Http2ErrorCode>(~0)};
-  EXPECT_FALSE(u.IsSupportedErrorCode()) << v;
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2RstStreamFields>());
-}
-
-TEST(Http2SettingFieldsTest, Misc) {
-  Http2Random random;
-  Http2SettingsParameter parameter =
-      static_cast<Http2SettingsParameter>(random.Rand16());
-  uint32_t value = random.Rand32();
-
-  Http2SettingFields v(parameter, value);
-
-  EXPECT_EQ(v, v);
-  EXPECT_EQ(parameter, v.parameter);
-  EXPECT_EQ(value, v.value);
-
-  if (static_cast<uint16_t>(parameter) < 7) {
-    EXPECT_TRUE(v.IsSupportedParameter()) << v;
-  } else {
-    EXPECT_FALSE(v.IsSupportedParameter()) << v;
-  }
-
-  Http2SettingFields u(parameter, ~value);
-  EXPECT_NE(v, u);
-  EXPECT_EQ(v.parameter, u.parameter);
-  EXPECT_NE(v.value, u.value);
-
-  Http2SettingFields w(IncrementEnum(parameter), value);
-  EXPECT_NE(v, w);
-  EXPECT_NE(v.parameter, w.parameter);
-  EXPECT_EQ(v.value, w.value);
-
-  Http2SettingFields x(Http2SettingsParameter::MAX_FRAME_SIZE, 123);
-  std::stringstream s;
-  s << x;
-  EXPECT_EQ("parameter=MAX_FRAME_SIZE, value=123", s.str());
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2SettingFields>());
-}
-
-TEST(Http2PushPromiseTest, Misc) {
-  Http2Random random;
-  uint32_t promised_stream_id = random.Rand32() & StreamIdMask();
-
-  Http2PushPromiseFields v{promised_stream_id};
-  EXPECT_EQ(promised_stream_id, v.promised_stream_id);
-  EXPECT_EQ(v, v);
-
-  std::stringstream s;
-  s << v;
-  EXPECT_EQ(absl::StrCat("promised_stream_id=", promised_stream_id), s.str());
-
-  // High-bit is reserved, but not used, so we can set it.
-  promised_stream_id |= 0x80000000;
-  Http2PushPromiseFields w{promised_stream_id};
-  EXPECT_EQ(w, w);
-  EXPECT_NE(v, w);
-
-  v.promised_stream_id = promised_stream_id;
-  EXPECT_EQ(v, w);
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2PushPromiseFields>());
-}
-
-TEST(Http2PingFieldsTest, Misc) {
-  Http2PingFields v{{'8', ' ', 'b', 'y', 't', 'e', 's', '\0'}};
-  std::stringstream s;
-  s << v;
-  EXPECT_EQ("opaque_bytes=0x3820627974657300", s.str());
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2PingFields>());
-}
-
-TEST(Http2GoAwayFieldsTest, Misc) {
-  Http2Random random;
-  uint32_t last_stream_id = random.Rand32() & StreamIdMask();
-  Http2ErrorCode error_code = static_cast<Http2ErrorCode>(random.Rand32());
-
-  Http2GoAwayFields v(last_stream_id, error_code);
-  EXPECT_EQ(v, v);
-  EXPECT_EQ(last_stream_id, v.last_stream_id);
-  EXPECT_EQ(error_code, v.error_code);
-
-  if (static_cast<uint32_t>(error_code) < 14) {
-    EXPECT_TRUE(v.IsSupportedErrorCode()) << v;
-  } else {
-    EXPECT_FALSE(v.IsSupportedErrorCode()) << v;
-  }
-
-  Http2GoAwayFields u(~last_stream_id, error_code);
-  EXPECT_NE(v, u);
-  EXPECT_NE(v.last_stream_id, u.last_stream_id);
-  EXPECT_EQ(v.error_code, u.error_code);
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2GoAwayFields>());
-}
-
-TEST(Http2WindowUpdateTest, Misc) {
-  Http2Random random;
-  uint32_t window_size_increment = random.Rand32() & UInt31Mask();
-
-  Http2WindowUpdateFields v{window_size_increment};
-  EXPECT_EQ(window_size_increment, v.window_size_increment);
-  EXPECT_EQ(v, v);
-
-  std::stringstream s;
-  s << v;
-  EXPECT_EQ(absl::StrCat("window_size_increment=", window_size_increment),
-            s.str());
-
-  // High-bit is reserved, but not used, so we can set it.
-  window_size_increment |= 0x80000000;
-  Http2WindowUpdateFields w{window_size_increment};
-  EXPECT_EQ(w, w);
-  EXPECT_NE(v, w);
-
-  v.window_size_increment = window_size_increment;
-  EXPECT_EQ(v, w);
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2WindowUpdateFields>());
-}
-
-TEST(Http2AltSvcTest, Misc) {
-  Http2Random random;
-  uint16_t origin_length = random.Rand16();
-
-  Http2AltSvcFields v{origin_length};
-  EXPECT_EQ(origin_length, v.origin_length);
-  EXPECT_EQ(v, v);
-
-  std::stringstream s;
-  s << v;
-  EXPECT_EQ(absl::StrCat("origin_length=", origin_length), s.str());
-
-  Http2AltSvcFields w{++origin_length};
-  EXPECT_EQ(w, w);
-  EXPECT_NE(v, w);
-
-  v.origin_length = w.origin_length;
-  EXPECT_EQ(v, w);
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2AltSvcFields>());
-}
-
-TEST(Http2PriorityUpdateFieldsTest, Eq) {
-  Http2PriorityUpdateFields u(/* prioritized_stream_id = */ 1);
-  Http2PriorityUpdateFields v(/* prioritized_stream_id = */ 3);
-
-  EXPECT_NE(u, v);
-  EXPECT_FALSE(u == v);
-  EXPECT_TRUE(u != v);
-
-  u = v;
-  EXPECT_EQ(u, v);
-  EXPECT_TRUE(u == v);
-  EXPECT_FALSE(u != v);
-}
-
-TEST(Http2PriorityUpdateFieldsTest, Misc) {
-  Http2PriorityUpdateFields u(/* prioritized_stream_id = */ 1);
-  EXPECT_EQ("prioritized_stream_id=1", u.ToString());
-
-  EXPECT_TRUE(VerifyRandomCalls<Http2PriorityUpdateFields>());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/http2_structures_test_util.cc b/http2/http2_structures_test_util.cc
deleted file mode 100644
index 83b5a95..0000000
--- a/http2/http2_structures_test_util.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/http2_structures_test_util.h"
-
-#include <cstdint>
-
-#include "http2/http2_constants.h"
-#include "http2/http2_constants_test_util.h"
-#include "http2/http2_structures.h"
-#include "http2/test_tools/http2_random.h"
-
-namespace http2 {
-namespace test {
-
-void Randomize(Http2FrameHeader* out, Http2Random* rng) {
-  out->payload_length = rng->Rand32() & 0xffffff;
-  out->type = static_cast<Http2FrameType>(rng->Rand8());
-  out->flags = static_cast<Http2FrameFlag>(rng->Rand8());
-  out->stream_id = rng->Rand32() & StreamIdMask();
-}
-void Randomize(Http2PriorityFields* out, Http2Random* rng) {
-  out->stream_dependency = rng->Rand32() & StreamIdMask();
-  out->weight = rng->Rand8() + 1;
-  out->is_exclusive = rng->OneIn(2);
-}
-void Randomize(Http2RstStreamFields* out, Http2Random* rng) {
-  out->error_code = static_cast<Http2ErrorCode>(rng->Rand32());
-}
-void Randomize(Http2SettingFields* out, Http2Random* rng) {
-  out->parameter = static_cast<Http2SettingsParameter>(rng->Rand16());
-  out->value = rng->Rand32();
-}
-void Randomize(Http2PushPromiseFields* out, Http2Random* rng) {
-  out->promised_stream_id = rng->Rand32() & StreamIdMask();
-}
-void Randomize(Http2PingFields* out, Http2Random* rng) {
-  for (int ndx = 0; ndx < 8; ++ndx) {
-    out->opaque_bytes[ndx] = rng->Rand8();
-  }
-}
-void Randomize(Http2GoAwayFields* out, Http2Random* rng) {
-  out->last_stream_id = rng->Rand32() & StreamIdMask();
-  out->error_code = static_cast<Http2ErrorCode>(rng->Rand32());
-}
-void Randomize(Http2WindowUpdateFields* out, Http2Random* rng) {
-  out->window_size_increment = rng->Rand32() & 0x7fffffff;
-}
-void Randomize(Http2AltSvcFields* out, Http2Random* rng) {
-  out->origin_length = rng->Rand16();
-}
-void Randomize(Http2PriorityUpdateFields* out, Http2Random* rng) {
-  out->prioritized_stream_id = rng->Rand32() & StreamIdMask();
-}
-
-void ScrubFlagsOfHeader(Http2FrameHeader* header) {
-  uint8_t invalid_mask = InvalidFlagMaskForFrameType(header->type);
-  uint8_t keep_mask = ~invalid_mask;
-  header->RetainFlags(keep_mask);
-}
-
-bool FrameIsPadded(const Http2FrameHeader& header) {
-  switch (header.type) {
-    case Http2FrameType::DATA:
-    case Http2FrameType::HEADERS:
-    case Http2FrameType::PUSH_PROMISE:
-      return header.IsPadded();
-    default:
-      return false;
-  }
-}
-
-bool FrameHasPriority(const Http2FrameHeader& header) {
-  switch (header.type) {
-    case Http2FrameType::HEADERS:
-      return header.HasPriority();
-    case Http2FrameType::PRIORITY:
-      return true;
-    default:
-      return false;
-  }
-}
-
-bool FrameCanHavePayload(const Http2FrameHeader& header) {
-  switch (header.type) {
-    case Http2FrameType::DATA:
-    case Http2FrameType::HEADERS:
-    case Http2FrameType::PUSH_PROMISE:
-    case Http2FrameType::CONTINUATION:
-    case Http2FrameType::PING:
-    case Http2FrameType::GOAWAY:
-    case Http2FrameType::ALTSVC:
-      return true;
-    default:
-      return false;
-  }
-}
-
-bool FrameCanHaveHpackPayload(const Http2FrameHeader& header) {
-  switch (header.type) {
-    case Http2FrameType::HEADERS:
-    case Http2FrameType::PUSH_PROMISE:
-    case Http2FrameType::CONTINUATION:
-      return true;
-    default:
-      return false;
-  }
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/http2_structures_test_util.h b/http2/http2_structures_test_util.h
deleted file mode 100644
index 31c1f14..0000000
--- a/http2/http2_structures_test_util.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_HTTP2_STRUCTURES_TEST_UTIL_H_
-#define QUICHE_HTTP2_HTTP2_STRUCTURES_TEST_UTIL_H_
-
-#include <string>
-
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "http2/tools/http2_frame_builder.h"
-
-namespace http2 {
-namespace test {
-
-template <class S>
-std::string SerializeStructure(const S& s) {
-  Http2FrameBuilder fb;
-  fb.Append(s);
-  EXPECT_EQ(S::EncodedSize(), fb.size());
-  return fb.buffer();
-}
-
-// Randomize the members of out, in a manner that yields encodeable contents
-// (e.g. a "uint24" field has only the low 24 bits set).
-void Randomize(Http2FrameHeader* out, Http2Random* rng);
-void Randomize(Http2PriorityFields* out, Http2Random* rng);
-void Randomize(Http2RstStreamFields* out, Http2Random* rng);
-void Randomize(Http2SettingFields* out, Http2Random* rng);
-void Randomize(Http2PushPromiseFields* out, Http2Random* rng);
-void Randomize(Http2PingFields* out, Http2Random* rng);
-void Randomize(Http2GoAwayFields* out, Http2Random* rng);
-void Randomize(Http2WindowUpdateFields* out, Http2Random* rng);
-void Randomize(Http2AltSvcFields* out, Http2Random* rng);
-void Randomize(Http2PriorityUpdateFields* out, Http2Random* rng);
-
-// Clear bits of header->flags that are known to be invalid for the
-// type. For unknown frame types, no change is made.
-void ScrubFlagsOfHeader(Http2FrameHeader* header);
-
-// Is the frame with this header padded? Only true for known/supported frame
-// types.
-bool FrameIsPadded(const Http2FrameHeader& header);
-
-// Does the frame with this header have Http2PriorityFields?
-bool FrameHasPriority(const Http2FrameHeader& header);
-
-// Does the frame with this header have a variable length payload (including
-// empty) payload (e.g. DATA or HEADERS)? Really a test of the frame type.
-bool FrameCanHavePayload(const Http2FrameHeader& header);
-
-// Does the frame with this header have a variable length HPACK payload
-// (including empty) payload (e.g. HEADERS)? Really a test of the frame type.
-bool FrameCanHaveHpackPayload(const Http2FrameHeader& header);
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_HTTP2_STRUCTURES_TEST_UTIL_H_
diff --git a/http2/platform/api/http2_bug_tracker.h b/http2/platform/api/http2_bug_tracker.h
deleted file mode 100644
index 6f2fe51..0000000
--- a/http2/platform/api/http2_bug_tracker.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_BUG_TRACKER_H_
-#define QUICHE_HTTP2_PLATFORM_API_HTTP2_BUG_TRACKER_H_
-
-#include "common/platform/api/quiche_bug_tracker.h"
-
-#define HTTP2_BUG QUICHE_BUG
-#define HTTP2_BUG_IF QUICHE_BUG_IF
-
-// V2 macros are the same as all the HTTP2_BUG flavor above, but they take a
-// bug_id parameter.
-#define HTTP2_BUG_V2 QUICHE_BUG
-#define HTTP2_BUG_IF_V2 QUICHE_BUG_IF
-
-#define FLAGS_http2_always_log_bugs_for_tests \
-  FLAGS_http2_always_log_bugs_for_tests_IMPL
-
-#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_BUG_TRACKER_H_
diff --git a/http2/platform/api/http2_flag_utils.h b/http2/platform/api/http2_flag_utils.h
deleted file mode 100644
index 79609e6..0000000
--- a/http2/platform/api/http2_flag_utils.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAG_UTILS_H_
-#define QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAG_UTILS_H_
-
-#include "common/platform/api/quiche_flag_utils.h"
-
-#define HTTP2_RELOADABLE_FLAG_COUNT QUICHE_RELOADABLE_FLAG_COUNT
-#define HTTP2_RELOADABLE_FLAG_COUNT_N QUICHE_RELOADABLE_FLAG_COUNT_N
-
-#define HTTP2_RESTART_FLAG_COUNT QUICHE_RESTART_FLAG_COUNT
-#define HTTP2_RESTART_FLAG_COUNT_N QUICHE_RESTART_FLAG_COUNT_N
-
-#define HTTP2_CODE_COUNT QUICHE_CODE_COUNT
-#define HTTP2_CODE_COUNT_N QUICHE_CODE_COUNT_N
-
-#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAG_UTILS_H_
diff --git a/http2/platform/api/http2_flags.h b/http2/platform/api/http2_flags.h
deleted file mode 100644
index 7c87864..0000000
--- a/http2/platform/api/http2_flags.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_
-#define QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_
-
-#include "common/platform/api/quiche_flags.h"
-
-#define GetHttp2ReloadableFlag(flag) GetQuicheReloadableFlag(http2, flag)
-#define SetHttp2ReloadableFlag(flag, value) \
-  SetQuicheReloadableFlag(http2, flag, value)
-#define GetHttp2RestartFlag(flag) GetQuicheRestartFlag(http2, flag)
-#define SetHttp2RestartFlag(flag, value) \
-  SetQuicheRestartFlag(http2, flag, value)
-#define GetHttp2Flag(flag) GetQuicheFlag(flag)
-#define SetHttp2Flag(flag, value) SetQuicheFlag(flag, value)
-
-#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_
diff --git a/http2/platform/api/http2_logging.h b/http2/platform/api/http2_logging.h
deleted file mode 100644
index 80ced05..0000000
--- a/http2/platform/api/http2_logging.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_LOGGING_H_
-#define QUICHE_HTTP2_PLATFORM_API_HTTP2_LOGGING_H_
-
-#include "common/platform/api/quiche_logging.h"
-
-#define HTTP2_LOG(severity) QUICHE_LOG(severity)
-
-#define HTTP2_VLOG(verbose_level) QUICHE_VLOG(verbose_level)
-
-#define HTTP2_DLOG(severity) QUICHE_DLOG(severity)
-
-#define HTTP2_DLOG_IF(severity, condition) QUICHE_DLOG_IF(severity, condition)
-
-#define HTTP2_DVLOG(verbose_level) QUICHE_DVLOG(verbose_level)
-
-#define HTTP2_DVLOG_IF(verbose_level, condition) \
-  QUICHE_DVLOG_IF(verbose_level, condition)
-
-#define HTTP2_LOG_FIRST_N(severity, n) QUICHE_LOG_FIRST_N(severity, n)
-
-#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_LOGGING_H_
diff --git a/http2/platform/api/http2_test_helpers.h b/http2/platform/api/http2_test_helpers.h
deleted file mode 100644
index ae1a5ee..0000000
--- a/http2/platform/api/http2_test_helpers.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_TEST_HELPERS_H_
-#define QUICHE_HTTP2_PLATFORM_API_HTTP2_TEST_HELPERS_H_
-
-// Provides VERIFY_* macros, similar to EXPECT_* and ASSERT_*, but they return
-// an AssertionResult if the condition is not satisfied.
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-
-#define VERIFY_AND_RETURN_SUCCESS(expression) \
-  {                                           \
-    VERIFY_SUCCESS(expression);               \
-    return ::testing::AssertionSuccess();     \
-  }
-
-#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_TEST_HELPERS_H_
diff --git a/http2/test_tools/frame_parts.cc b/http2/test_tools/frame_parts.cc
deleted file mode 100644
index 4713523..0000000
--- a/http2/test_tools/frame_parts.cc
+++ /dev/null
@@ -1,557 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/test_tools/frame_parts.h"
-
-#include <type_traits>
-
-#include "absl/strings/escaping.h"
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionFailure;
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::ContainerEq;
-
-namespace http2 {
-namespace test {
-namespace {
-
-static_assert(std::is_base_of<Http2FrameDecoderListener, FrameParts>::value &&
-                  !std::is_abstract<FrameParts>::value,
-              "FrameParts needs to implement all of the methods of "
-              "Http2FrameDecoderListener");
-
-// Compare two optional variables of the same type.
-// TODO(jamessynge): Maybe create a ::testing::Matcher for this.
-template <class T>
-AssertionResult VerifyOptionalEq(const T& opt_a, const T& opt_b) {
-  if (opt_a) {
-    if (opt_b) {
-      VERIFY_EQ(opt_a.value(), opt_b.value());
-    } else {
-      return AssertionFailure()
-             << "opt_b is not set; opt_a.value()=" << opt_a.value();
-    }
-  } else if (opt_b) {
-    return AssertionFailure()
-           << "opt_a is not set; opt_b.value()=" << opt_b.value();
-  }
-  return AssertionSuccess();
-}
-
-}  // namespace
-
-FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header_(header) {
-  HTTP2_VLOG(1) << "FrameParts, header: " << frame_header_;
-}
-
-FrameParts::FrameParts(const Http2FrameHeader& header,
-                       absl::string_view payload)
-    : FrameParts(header) {
-  HTTP2_VLOG(1) << "FrameParts with payload.size() = " << payload.size();
-  this->payload_.append(payload.data(), payload.size());
-  opt_payload_length_ = payload.size();
-}
-FrameParts::FrameParts(const Http2FrameHeader& header,
-                       absl::string_view payload,
-                       size_t total_pad_length)
-    : FrameParts(header, payload) {
-  HTTP2_VLOG(1) << "FrameParts with total_pad_length=" << total_pad_length;
-  SetTotalPadLength(total_pad_length);
-}
-
-FrameParts::FrameParts(const FrameParts& header) = default;
-
-FrameParts::~FrameParts() = default;
-
-AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const {
-#define COMMON_MESSAGE "\n  this: " << *this << "\n  that: " << that
-
-  VERIFY_EQ(frame_header_, that.frame_header_) << COMMON_MESSAGE;
-  VERIFY_EQ(payload_, that.payload_) << COMMON_MESSAGE;
-  VERIFY_EQ(padding_, that.padding_) << COMMON_MESSAGE;
-  VERIFY_EQ(altsvc_origin_, that.altsvc_origin_) << COMMON_MESSAGE;
-  VERIFY_EQ(altsvc_value_, that.altsvc_value_) << COMMON_MESSAGE;
-  VERIFY_THAT(settings_, ContainerEq(that.settings_)) << COMMON_MESSAGE;
-
-#define VERIFY_OPTIONAL_FIELD(field_name) \
-  VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name))
-
-  VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_priority_update_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_goaway_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_missing_length_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_pad_length_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_ping_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_priority_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_push_promise_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code_) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_window_update_increment_) << COMMON_MESSAGE;
-
-#undef VERIFY_OPTIONAL_FIELD
-
-  return AssertionSuccess();
-}
-
-void FrameParts::SetTotalPadLength(size_t total_pad_length) {
-  opt_pad_length_.reset();
-  padding_.clear();
-  if (total_pad_length > 0) {
-    ASSERT_LE(total_pad_length, 256u);
-    ASSERT_TRUE(frame_header_.IsPadded());
-    opt_pad_length_ = total_pad_length - 1;
-    char zero = 0;
-    padding_.append(opt_pad_length_.value(), zero);
-  }
-
-  if (opt_pad_length_) {
-    HTTP2_VLOG(1) << "SetTotalPadLength: pad_length="
-                  << opt_pad_length_.value();
-  } else {
-    HTTP2_VLOG(1) << "SetTotalPadLength: has no pad length";
-  }
-}
-
-void FrameParts::SetAltSvcExpected(absl::string_view origin,
-                                   absl::string_view value) {
-  altsvc_origin_.append(origin.data(), origin.size());
-  altsvc_value_.append(value.data(), value.size());
-  opt_altsvc_origin_length_ = origin.size();
-  opt_altsvc_value_length_ = value.size();
-}
-
-bool FrameParts::OnFrameHeader(const Http2FrameHeader& /*header*/) {
-  ADD_FAILURE() << "OnFrameHeader: " << *this;
-  return true;
-}
-
-void FrameParts::OnDataStart(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnDataStart: " << header;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this;
-  opt_payload_length_ = header.payload_length;
-}
-
-void FrameParts::OnDataPayload(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnDataPayload: len=" << len
-                << "; frame_header_: " << frame_header_;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this;
-  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
-                           &opt_payload_length_));
-}
-
-void FrameParts::OnDataEnd() {
-  HTTP2_VLOG(1) << "OnDataEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this;
-}
-
-void FrameParts::OnHeadersStart(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this;
-  opt_payload_length_ = header.payload_length;
-}
-
-void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) {
-  HTTP2_VLOG(1) << "OnHeadersPriority: priority: " << priority
-                << "; frame_header_: " << frame_header_;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this;
-  ASSERT_FALSE(opt_priority_);
-  opt_priority_ = priority;
-  ASSERT_TRUE(opt_payload_length_);
-  opt_payload_length_ =
-      opt_payload_length_.value() - Http2PriorityFields::EncodedSize();
-}
-
-void FrameParts::OnHpackFragment(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len
-                << "; frame_header_: " << frame_header_;
-  ASSERT_TRUE(got_start_callback_);
-  ASSERT_FALSE(got_end_callback_);
-  ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header_)) << *this;
-  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
-                           &opt_payload_length_));
-}
-
-void FrameParts::OnHeadersEnd() {
-  HTTP2_VLOG(1) << "OnHeadersEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this;
-}
-
-void FrameParts::OnPriorityFrame(const Http2FrameHeader& header,
-                                 const Http2PriorityFields& priority) {
-  HTTP2_VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this;
-  ASSERT_FALSE(opt_priority_);
-  opt_priority_ = priority;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this;
-}
-
-void FrameParts::OnContinuationStart(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this;
-  opt_payload_length_ = header.payload_length;
-}
-
-void FrameParts::OnContinuationEnd() {
-  HTTP2_VLOG(1) << "OnContinuationEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this;
-}
-
-void FrameParts::OnPadLength(size_t trailing_length) {
-  HTTP2_VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
-  ASSERT_TRUE(InPaddedFrame()) << *this;
-  ASSERT_FALSE(opt_pad_length_);
-  ASSERT_TRUE(opt_payload_length_);
-  size_t total_padding_length = trailing_length + 1;
-  ASSERT_GE(opt_payload_length_.value(), total_padding_length);
-  opt_payload_length_ = opt_payload_length_.value() - total_padding_length;
-  opt_pad_length_ = trailing_length;
-}
-
-void FrameParts::OnPadding(const char* pad, size_t skipped_length) {
-  HTTP2_VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
-  ASSERT_TRUE(InPaddedFrame()) << *this;
-  ASSERT_TRUE(opt_pad_length_);
-  ASSERT_TRUE(AppendString(absl::string_view(pad, skipped_length), &padding_,
-                           &opt_pad_length_));
-}
-
-void FrameParts::OnRstStream(const Http2FrameHeader& header,
-                             Http2ErrorCode error_code) {
-  HTTP2_VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this;
-  ASSERT_FALSE(opt_rst_stream_error_code_);
-  opt_rst_stream_error_code_ = error_code;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this;
-}
-
-void FrameParts::OnSettingsStart(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
-  ASSERT_EQ(0u, settings_.size());
-  ASSERT_FALSE(header.IsAck()) << header;
-}
-
-void FrameParts::OnSetting(const Http2SettingFields& setting_fields) {
-  HTTP2_VLOG(1) << "OnSetting: " << setting_fields;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this;
-  settings_.push_back(setting_fields);
-}
-
-void FrameParts::OnSettingsEnd() {
-  HTTP2_VLOG(1) << "OnSettingsEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
-}
-
-void FrameParts::OnSettingsAck(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
-  ASSERT_EQ(0u, settings_.size());
-  ASSERT_TRUE(header.IsAck());
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
-}
-
-void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header,
-                                    const Http2PushPromiseFields& promise,
-                                    size_t total_padding_length) {
-  HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
-                << "; promise: " << promise
-                << "; total_padding_length: " << total_padding_length;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this;
-  ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize());
-  opt_payload_length_ =
-      header.payload_length - Http2PushPromiseFields::EncodedSize();
-  ASSERT_FALSE(opt_push_promise_);
-  opt_push_promise_ = promise;
-  if (total_padding_length > 0) {
-    ASSERT_GE(opt_payload_length_.value(), total_padding_length);
-    OnPadLength(total_padding_length - 1);
-  } else {
-    ASSERT_FALSE(header.IsPadded());
-  }
-}
-
-void FrameParts::OnPushPromiseEnd() {
-  HTTP2_VLOG(1) << "OnPushPromiseEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this;
-}
-
-void FrameParts::OnPing(const Http2FrameHeader& header,
-                        const Http2PingFields& ping) {
-  HTTP2_VLOG(1) << "OnPing header: " << header << "   ping: " << ping;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
-  ASSERT_FALSE(header.IsAck());
-  ASSERT_FALSE(opt_ping_);
-  opt_ping_ = ping;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
-}
-
-void FrameParts::OnPingAck(const Http2FrameHeader& header,
-                           const Http2PingFields& ping) {
-  HTTP2_VLOG(1) << "OnPingAck header: " << header << "   ping: " << ping;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
-  ASSERT_TRUE(header.IsAck());
-  ASSERT_FALSE(opt_ping_);
-  opt_ping_ = ping;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
-}
-
-void FrameParts::OnGoAwayStart(const Http2FrameHeader& header,
-                               const Http2GoAwayFields& goaway) {
-  HTTP2_VLOG(1) << "OnGoAwayStart: " << goaway;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this;
-  ASSERT_FALSE(opt_goaway_);
-  opt_goaway_ = goaway;
-  opt_payload_length_ =
-      header.payload_length - Http2GoAwayFields::EncodedSize();
-}
-
-void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this;
-  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
-                           &opt_payload_length_));
-}
-
-void FrameParts::OnGoAwayEnd() {
-  HTTP2_VLOG(1) << "OnGoAwayEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this;
-}
-
-void FrameParts::OnWindowUpdate(const Http2FrameHeader& header,
-                                uint32_t increment) {
-  HTTP2_VLOG(1) << "OnWindowUpdate header: " << header
-                << "     increment=" << increment;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this;
-  ASSERT_FALSE(opt_window_update_increment_);
-  opt_window_update_increment_ = increment;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this;
-}
-
-void FrameParts::OnAltSvcStart(const Http2FrameHeader& header,
-                               size_t origin_length,
-                               size_t value_length) {
-  HTTP2_VLOG(1) << "OnAltSvcStart: " << header
-                << "    origin_length: " << origin_length
-                << "    value_length: " << value_length;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this;
-  ASSERT_FALSE(opt_altsvc_origin_length_);
-  opt_altsvc_origin_length_ = origin_length;
-  ASSERT_FALSE(opt_altsvc_value_length_);
-  opt_altsvc_value_length_ = value_length;
-}
-
-void FrameParts::OnAltSvcOriginData(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
-  ASSERT_TRUE(AppendString(absl::string_view(data, len), &altsvc_origin_,
-                           &opt_altsvc_origin_length_));
-}
-
-void FrameParts::OnAltSvcValueData(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
-  ASSERT_TRUE(AppendString(absl::string_view(data, len), &altsvc_value_,
-                           &opt_altsvc_value_length_));
-}
-
-void FrameParts::OnAltSvcEnd() {
-  HTTP2_VLOG(1) << "OnAltSvcEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this;
-}
-
-void FrameParts::OnPriorityUpdateStart(
-    const Http2FrameHeader& header,
-    const Http2PriorityUpdateFields& priority_update) {
-  HTTP2_VLOG(1) << "OnPriorityUpdateStart: " << header
-                << "    prioritized_stream_id: "
-                << priority_update.prioritized_stream_id;
-  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY_UPDATE))
-      << *this;
-  ASSERT_FALSE(opt_priority_update_);
-  opt_priority_update_ = priority_update;
-  opt_payload_length_ =
-      header.payload_length - Http2PriorityUpdateFields::EncodedSize();
-}
-
-void FrameParts::OnPriorityUpdatePayload(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
-  ASSERT_TRUE(InFrameOfType(Http2FrameType::PRIORITY_UPDATE)) << *this;
-  payload_.append(data, len);
-}
-
-void FrameParts::OnPriorityUpdateEnd() {
-  HTTP2_VLOG(1) << "OnPriorityUpdateEnd; frame_header_: " << frame_header_;
-  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY_UPDATE)) << *this;
-}
-
-void FrameParts::OnUnknownStart(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
-  ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header;
-  ASSERT_FALSE(got_start_callback_);
-  ASSERT_EQ(frame_header_, header);
-  got_start_callback_ = true;
-  opt_payload_length_ = header.payload_length;
-}
-
-void FrameParts::OnUnknownPayload(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
-  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
-  ASSERT_TRUE(got_start_callback_);
-  ASSERT_FALSE(got_end_callback_);
-  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
-                           &opt_payload_length_));
-}
-
-void FrameParts::OnUnknownEnd() {
-  HTTP2_VLOG(1) << "OnUnknownEnd; frame_header_: " << frame_header_;
-  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
-  ASSERT_TRUE(got_start_callback_);
-  ASSERT_FALSE(got_end_callback_);
-  got_end_callback_ = true;
-}
-
-void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header,
-                                  size_t missing_length) {
-  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
-                << "; missing_length: " << missing_length;
-  ASSERT_EQ(frame_header_, header);
-  ASSERT_FALSE(got_end_callback_);
-  ASSERT_TRUE(FrameIsPadded(header));
-  ASSERT_FALSE(opt_pad_length_);
-  ASSERT_FALSE(opt_missing_length_);
-  opt_missing_length_ = missing_length;
-  got_start_callback_ = true;
-  got_end_callback_ = true;
-}
-
-void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-  ASSERT_EQ(frame_header_, header);
-  ASSERT_FALSE(got_end_callback_);
-  ASSERT_FALSE(has_frame_size_error_);
-  has_frame_size_error_ = true;
-  got_end_callback_ = true;
-}
-
-void FrameParts::OutputTo(std::ostream& out) const {
-  out << "FrameParts{\n  frame_header_: " << frame_header_ << "\n";
-  if (!payload_.empty()) {
-    out << "  payload_=\"" << absl::CHexEscape(payload_) << "\"\n";
-  }
-  if (!padding_.empty()) {
-    out << "  padding_=\"" << absl::CHexEscape(padding_) << "\"\n";
-  }
-  if (!altsvc_origin_.empty()) {
-    out << "  altsvc_origin_=\"" << absl::CHexEscape(altsvc_origin_) << "\"\n";
-  }
-  if (!altsvc_value_.empty()) {
-    out << "  altsvc_value_=\"" << absl::CHexEscape(altsvc_value_) << "\"\n";
-  }
-  if (opt_priority_) {
-    out << "  priority=" << opt_priority_.value() << "\n";
-  }
-  if (opt_rst_stream_error_code_) {
-    out << "  rst_stream=" << opt_rst_stream_error_code_.value() << "\n";
-  }
-  if (opt_push_promise_) {
-    out << "  push_promise=" << opt_push_promise_.value() << "\n";
-  }
-  if (opt_ping_) {
-    out << "  ping=" << opt_ping_.value() << "\n";
-  }
-  if (opt_goaway_) {
-    out << "  goaway=" << opt_goaway_.value() << "\n";
-  }
-  if (opt_window_update_increment_) {
-    out << "  window_update=" << opt_window_update_increment_.value() << "\n";
-  }
-  if (opt_payload_length_) {
-    out << "  payload_length=" << opt_payload_length_.value() << "\n";
-  }
-  if (opt_pad_length_) {
-    out << "  pad_length=" << opt_pad_length_.value() << "\n";
-  }
-  if (opt_missing_length_) {
-    out << "  missing_length=" << opt_missing_length_.value() << "\n";
-  }
-  if (opt_altsvc_origin_length_) {
-    out << "  origin_length=" << opt_altsvc_origin_length_.value() << "\n";
-  }
-  if (opt_altsvc_value_length_) {
-    out << "  value_length=" << opt_altsvc_value_length_.value() << "\n";
-  }
-  if (opt_priority_update_) {
-    out << "  prioritized_stream_id_=" << opt_priority_update_.value() << "\n";
-  }
-  if (has_frame_size_error_) {
-    out << "  has_frame_size_error\n";
-  }
-  if (got_start_callback_) {
-    out << "  got_start_callback\n";
-  }
-  if (got_end_callback_) {
-    out << "  got_end_callback\n";
-  }
-  for (size_t ndx = 0; ndx < settings_.size(); ++ndx) {
-    out << "  setting[" << ndx << "]=" << settings_[ndx];
-  }
-  out << "}";
-}
-
-AssertionResult FrameParts::StartFrameOfType(
-    const Http2FrameHeader& header,
-    Http2FrameType expected_frame_type) {
-  VERIFY_EQ(header.type, expected_frame_type);
-  VERIFY_FALSE(got_start_callback_);
-  VERIFY_FALSE(got_end_callback_);
-  VERIFY_EQ(frame_header_, header);
-  got_start_callback_ = true;
-  return AssertionSuccess();
-}
-
-AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) {
-  VERIFY_TRUE(got_start_callback_);
-  VERIFY_FALSE(got_end_callback_);
-  VERIFY_EQ(frame_header_.type, expected_frame_type);
-  return AssertionSuccess();
-}
-
-AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) {
-  VERIFY_SUCCESS(InFrameOfType(expected_frame_type));
-  got_end_callback_ = true;
-  return AssertionSuccess();
-}
-
-AssertionResult FrameParts::InPaddedFrame() {
-  VERIFY_TRUE(got_start_callback_);
-  VERIFY_FALSE(got_end_callback_);
-  VERIFY_TRUE(FrameIsPadded(frame_header_));
-  return AssertionSuccess();
-}
-
-AssertionResult FrameParts::AppendString(absl::string_view source,
-                                         std::string* target,
-                                         absl::optional<size_t>* opt_length) {
-  target->append(source.data(), source.size());
-  if (opt_length != nullptr) {
-    VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this;
-    VERIFY_LE(target->size(), opt_length->value())
-        << "String too large; source.size() = " << source.size() << "\n"
-        << *this;
-  }
-  return ::testing::AssertionSuccess();
-}
-
-std::ostream& operator<<(std::ostream& out, const FrameParts& v) {
-  v.OutputTo(out);
-  return out;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/test_tools/frame_parts.h b/http2/test_tools/frame_parts.h
deleted file mode 100644
index 1cc6928..0000000
--- a/http2/test_tools/frame_parts.h
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
-#define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
-
-// FrameParts implements Http2FrameDecoderListener, recording the callbacks
-// during the decoding of a single frame. It is also used for comparing the
-// info that a test expects to be recorded during the decoding of a frame
-// with the actual recorded value (i.e. by providing a comparator).
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-class FrameParts : public Http2FrameDecoderListener {
- public:
-  // The first callback for every type of frame includes the frame header; this
-  // is the only constructor used during decoding of a frame.
-  explicit FrameParts(const Http2FrameHeader& header);
-
-  // For use in tests where the expected frame has a variable size payload.
-  FrameParts(const Http2FrameHeader& header, absl::string_view payload);
-
-  // For use in tests where the expected frame has a variable size payload
-  // and may be padded.
-  FrameParts(const Http2FrameHeader& header,
-             absl::string_view payload,
-             size_t total_pad_length);
-
-  // Copy constructor.
-  FrameParts(const FrameParts& header);
-
-  ~FrameParts() override;
-
-  // Returns AssertionSuccess() if they're equal, else AssertionFailure()
-  // with info about the difference.
-  ::testing::AssertionResult VerifyEquals(const FrameParts& other) const;
-
-  // Format this FrameParts object.
-  void OutputTo(std::ostream& out) const;
-
-  // Set the total padding length (0 to 256).
-  void SetTotalPadLength(size_t total_pad_length);
-
-  // Set the origin and value expected in an ALTSVC frame.
-  void SetAltSvcExpected(absl::string_view origin, absl::string_view value);
-
-  // Http2FrameDecoderListener methods:
-  bool OnFrameHeader(const Http2FrameHeader& header) override;
-  void OnDataStart(const Http2FrameHeader& header) override;
-  void OnDataPayload(const char* data, size_t len) override;
-  void OnDataEnd() override;
-  void OnHeadersStart(const Http2FrameHeader& header) override;
-  void OnHeadersPriority(const Http2PriorityFields& priority) override;
-  void OnHpackFragment(const char* data, size_t len) override;
-  void OnHeadersEnd() override;
-  void OnPriorityFrame(const Http2FrameHeader& header,
-                       const Http2PriorityFields& priority) override;
-  void OnContinuationStart(const Http2FrameHeader& header) override;
-  void OnContinuationEnd() override;
-  void OnPadLength(size_t trailing_length) override;
-  void OnPadding(const char* pad, size_t skipped_length) override;
-  void OnRstStream(const Http2FrameHeader& header,
-                   Http2ErrorCode error_code) override;
-  void OnSettingsStart(const Http2FrameHeader& header) override;
-  void OnSetting(const Http2SettingFields& setting_fields) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck(const Http2FrameHeader& header) override;
-  void OnPushPromiseStart(const Http2FrameHeader& header,
-                          const Http2PushPromiseFields& promise,
-                          size_t total_padding_length) override;
-  void OnPushPromiseEnd() override;
-  void OnPing(const Http2FrameHeader& header,
-              const Http2PingFields& ping) override;
-  void OnPingAck(const Http2FrameHeader& header,
-                 const Http2PingFields& ping) override;
-  void OnGoAwayStart(const Http2FrameHeader& header,
-                     const Http2GoAwayFields& goaway) override;
-  void OnGoAwayOpaqueData(const char* data, size_t len) override;
-  void OnGoAwayEnd() override;
-  void OnWindowUpdate(const Http2FrameHeader& header,
-                      uint32_t increment) override;
-  void OnAltSvcStart(const Http2FrameHeader& header,
-                     size_t origin_length,
-                     size_t value_length) override;
-  void OnAltSvcOriginData(const char* data, size_t len) override;
-  void OnAltSvcValueData(const char* data, size_t len) override;
-  void OnAltSvcEnd() override;
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) override;
-  void OnPriorityUpdatePayload(const char* data, size_t len) override;
-  void OnPriorityUpdateEnd() override;
-  void OnUnknownStart(const Http2FrameHeader& header) override;
-  void OnUnknownPayload(const char* data, size_t len) override;
-  void OnUnknownEnd() override;
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override;
-  void OnFrameSizeError(const Http2FrameHeader& header) override;
-
-  void AppendSetting(const Http2SettingFields& setting_fields) {
-    settings_.push_back(setting_fields);
-  }
-
-  const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
-
-  absl::optional<Http2PriorityFields> GetOptPriority() const {
-    return opt_priority_;
-  }
-  absl::optional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
-    return opt_rst_stream_error_code_;
-  }
-  absl::optional<Http2PushPromiseFields> GetOptPushPromise() const {
-    return opt_push_promise_;
-  }
-  absl::optional<Http2PingFields> GetOptPing() const { return opt_ping_; }
-  absl::optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; }
-  absl::optional<size_t> GetOptPadLength() const { return opt_pad_length_; }
-  absl::optional<size_t> GetOptPayloadLength() const {
-    return opt_payload_length_;
-  }
-  absl::optional<size_t> GetOptMissingLength() const {
-    return opt_missing_length_;
-  }
-  absl::optional<size_t> GetOptAltsvcOriginLength() const {
-    return opt_altsvc_origin_length_;
-  }
-  absl::optional<size_t> GetOptAltsvcValueLength() const {
-    return opt_altsvc_value_length_;
-  }
-  absl::optional<size_t> GetOptWindowUpdateIncrement() const {
-    return opt_window_update_increment_;
-  }
-  bool GetHasFrameSizeError() const { return has_frame_size_error_; }
-
-  void SetOptPriority(absl::optional<Http2PriorityFields> opt_priority) {
-    opt_priority_ = opt_priority;
-  }
-  void SetOptRstStreamErrorCode(
-      absl::optional<Http2ErrorCode> opt_rst_stream_error_code) {
-    opt_rst_stream_error_code_ = opt_rst_stream_error_code;
-  }
-  void SetOptPushPromise(
-      absl::optional<Http2PushPromiseFields> opt_push_promise) {
-    opt_push_promise_ = opt_push_promise;
-  }
-  void SetOptPing(absl::optional<Http2PingFields> opt_ping) {
-    opt_ping_ = opt_ping;
-  }
-  void SetOptGoaway(absl::optional<Http2GoAwayFields> opt_goaway) {
-    opt_goaway_ = opt_goaway;
-  }
-  void SetOptPadLength(absl::optional<size_t> opt_pad_length) {
-    opt_pad_length_ = opt_pad_length;
-  }
-  void SetOptPayloadLength(absl::optional<size_t> opt_payload_length) {
-    opt_payload_length_ = opt_payload_length;
-  }
-  void SetOptMissingLength(absl::optional<size_t> opt_missing_length) {
-    opt_missing_length_ = opt_missing_length;
-  }
-  void SetOptAltsvcOriginLength(
-      absl::optional<size_t> opt_altsvc_origin_length) {
-    opt_altsvc_origin_length_ = opt_altsvc_origin_length;
-  }
-  void SetOptAltsvcValueLength(absl::optional<size_t> opt_altsvc_value_length) {
-    opt_altsvc_value_length_ = opt_altsvc_value_length;
-  }
-  void SetOptWindowUpdateIncrement(
-      absl::optional<size_t> opt_window_update_increment) {
-    opt_window_update_increment_ = opt_window_update_increment;
-  }
-  void SetOptPriorityUpdate(
-      absl::optional<Http2PriorityUpdateFields> priority_update) {
-    opt_priority_update_ = priority_update;
-  }
-
-  void SetHasFrameSizeError(bool has_frame_size_error) {
-    has_frame_size_error_ = has_frame_size_error;
-  }
-
- private:
-  // ASSERT during an On* method that we're handling a frame of type
-  // expected_frame_type, and have not already received other On* methods
-  // (i.e. got_start_callback is false).
-  ::testing::AssertionResult StartFrameOfType(
-      const Http2FrameHeader& header,
-      Http2FrameType expected_frame_type);
-
-  // ASSERT that StartFrameOfType has already been called with
-  // expected_frame_type (i.e. got_start_callback has been called), and that
-  // EndFrameOfType has not yet been called (i.e. got_end_callback is false).
-  ::testing::AssertionResult InFrameOfType(Http2FrameType expected_frame_type);
-
-  // ASSERT that we're InFrameOfType, and then sets got_end_callback=true.
-  ::testing::AssertionResult EndFrameOfType(Http2FrameType expected_frame_type);
-
-  // ASSERT that we're in the middle of processing a frame that is padded.
-  ::testing::AssertionResult InPaddedFrame();
-
-  // Append source to target. If opt_length is not nullptr, then verifies that
-  // the optional has a value (i.e. that the necessary On*Start method has been
-  // called), and that target is not longer than opt_length->value().
-  ::testing::AssertionResult AppendString(absl::string_view source,
-                                          std::string* target,
-                                          absl::optional<size_t>* opt_length);
-
-  const Http2FrameHeader frame_header_;
-
-  std::string payload_;
-  std::string padding_;
-  std::string altsvc_origin_;
-  std::string altsvc_value_;
-
-  absl::optional<Http2PriorityFields> opt_priority_;
-  absl::optional<Http2ErrorCode> opt_rst_stream_error_code_;
-  absl::optional<Http2PushPromiseFields> opt_push_promise_;
-  absl::optional<Http2PingFields> opt_ping_;
-  absl::optional<Http2GoAwayFields> opt_goaway_;
-  absl::optional<Http2PriorityUpdateFields> opt_priority_update_;
-
-  absl::optional<size_t> opt_pad_length_;
-  absl::optional<size_t> opt_payload_length_;
-  absl::optional<size_t> opt_missing_length_;
-  absl::optional<size_t> opt_altsvc_origin_length_;
-  absl::optional<size_t> opt_altsvc_value_length_;
-
-  absl::optional<size_t> opt_window_update_increment_;
-
-  bool has_frame_size_error_ = false;
-
-  std::vector<Http2SettingFields> settings_;
-
-  // These booleans are not checked by CompareCollectedFrames.
-  bool got_start_callback_ = false;
-  bool got_end_callback_ = false;
-};
-
-std::ostream& operator<<(std::ostream& out, const FrameParts& v);
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
diff --git a/http2/test_tools/frame_parts_collector.cc b/http2/test_tools/frame_parts_collector.cc
deleted file mode 100644
index 6f02eb6..0000000
--- a/http2/test_tools/frame_parts_collector.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/test_tools/frame_parts_collector.h"
-
-#include <utility>
-
-#include "http2/http2_structures_test_util.h"
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-FramePartsCollector::FramePartsCollector() = default;
-FramePartsCollector::~FramePartsCollector() = default;
-
-void FramePartsCollector::Reset() {
-  current_frame_.reset();
-  collected_frames_.clear();
-  expected_header_set_ = false;
-}
-
-const FrameParts* FramePartsCollector::frame(size_t n) const {
-  if (n < size()) {
-    return collected_frames_.at(n).get();
-  }
-  QUICHE_CHECK(n == size());
-  return current_frame();
-}
-
-void FramePartsCollector::ExpectFrameHeader(const Http2FrameHeader& header) {
-  EXPECT_FALSE(IsInProgress());
-  EXPECT_FALSE(expected_header_set_)
-      << "expected_header_: " << expected_header_;
-  expected_header_ = header;
-  expected_header_set_ = true;
-  // OnFrameHeader is called before the flags are scrubbed, but the other
-  // methods are called after, so scrub the invalid flags from expected_header_.
-  ScrubFlagsOfHeader(&expected_header_);
-}
-
-void FramePartsCollector::TestExpectedHeader(const Http2FrameHeader& header) {
-  if (expected_header_set_) {
-    EXPECT_EQ(header, expected_header_);
-    expected_header_set_ = false;
-  }
-}
-
-Http2FrameDecoderListener* FramePartsCollector::StartFrame(
-    const Http2FrameHeader& header) {
-  TestExpectedHeader(header);
-  EXPECT_FALSE(IsInProgress());
-  if (current_frame_ == nullptr) {
-    current_frame_ = std::make_unique<FrameParts>(header);
-  }
-  return current_frame();
-}
-
-Http2FrameDecoderListener* FramePartsCollector::StartAndEndFrame(
-    const Http2FrameHeader& header) {
-  TestExpectedHeader(header);
-  EXPECT_FALSE(IsInProgress());
-  if (current_frame_ == nullptr) {
-    current_frame_ = std::make_unique<FrameParts>(header);
-  }
-  Http2FrameDecoderListener* result = current_frame();
-  collected_frames_.push_back(std::move(current_frame_));
-  return result;
-}
-
-Http2FrameDecoderListener* FramePartsCollector::CurrentFrame() {
-  EXPECT_TRUE(IsInProgress());
-  if (current_frame_ == nullptr) {
-    return &failing_listener_;
-  }
-  return current_frame();
-}
-
-Http2FrameDecoderListener* FramePartsCollector::EndFrame() {
-  EXPECT_TRUE(IsInProgress());
-  if (current_frame_ == nullptr) {
-    return &failing_listener_;
-  }
-  Http2FrameDecoderListener* result = current_frame();
-  collected_frames_.push_back(std::move(current_frame_));
-  return result;
-}
-
-Http2FrameDecoderListener* FramePartsCollector::FrameError(
-    const Http2FrameHeader& header) {
-  TestExpectedHeader(header);
-  if (current_frame_ == nullptr) {
-    // The decoder may detect an error before making any calls to the listener
-    // regarding the frame, in which case current_frame_==nullptr and we need
-    // to create a FrameParts instance.
-    current_frame_ = std::make_unique<FrameParts>(header);
-  } else {
-    // Similarly, the decoder may have made calls to the listener regarding the
-    // frame before detecting the error; for example, the DATA payload decoder
-    // calls OnDataStart before it can detect padding errors, hence before it
-    // can call OnPaddingTooLong.
-    EXPECT_EQ(header, current_frame_->GetFrameHeader());
-  }
-  Http2FrameDecoderListener* result = current_frame();
-  collected_frames_.push_back(std::move(current_frame_));
-  return result;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/test_tools/frame_parts_collector.h b/http2/test_tools/frame_parts_collector.h
deleted file mode 100644
index 8f74a9f..0000000
--- a/http2/test_tools/frame_parts_collector.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_
-#define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_
-
-// FramePartsCollector is a base class for Http2FrameDecoderListener
-// implementations that create one FrameParts instance for each decoded frame.
-
-#include <stddef.h>
-
-#include <memory>
-#include <vector>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/decoder/http2_frame_decoder_listener_test_util.h"
-#include "http2/http2_structures.h"
-#include "http2/test_tools/frame_parts.h"
-
-namespace http2 {
-namespace test {
-
-class FramePartsCollector : public FailingHttp2FrameDecoderListener {
- public:
-  FramePartsCollector();
-  ~FramePartsCollector() override;
-
-  // Toss out the collected data.
-  void Reset();
-
-  // Returns true if has started recording the info for a frame and has not yet
-  // finished doing so.
-  bool IsInProgress() const { return current_frame_ != nullptr; }
-
-  // Returns the FrameParts instance into which we're currently recording
-  // callback info if IsInProgress, else nullptr.
-  const FrameParts* current_frame() const { return current_frame_.get(); }
-
-  // Returns the number of completely collected FrameParts instances.
-  size_t size() const { return collected_frames_.size(); }
-
-  // Returns the n'th frame, where 0 is the oldest of the collected frames,
-  // and n==size() is the frame currently being collected, if there is one.
-  // Returns nullptr if the requested index is not valid.
-  const FrameParts* frame(size_t n) const;
-
- protected:
-  // In support of OnFrameHeader, set the header that we expect to be used in
-  // the next call.
-  // TODO(jamessynge): Remove ExpectFrameHeader et al. once done with supporting
-  // SpdyFramer's exact states.
-  void ExpectFrameHeader(const Http2FrameHeader& header);
-
-  // For use in implementing On*Start methods of Http2FrameDecoderListener,
-  // returns a FrameParts instance, which will be newly created if
-  // IsInProgress==false (which the caller should ensure), else will be the
-  // current_frame(); never returns nullptr.
-  // If called when IsInProgress==true, a test failure will be recorded.
-  Http2FrameDecoderListener* StartFrame(const Http2FrameHeader& header);
-
-  // For use in implementing On* callbacks, such as OnPingAck, that are the only
-  // call expected for the frame being decoded; not for On*Start methods.
-  // Returns a FrameParts instance, which will be newly created if
-  // IsInProgress==false (which the caller should ensure), else will be the
-  // current_frame(); never returns nullptr.
-  // If called when IsInProgress==true, a test failure will be recorded.
-  Http2FrameDecoderListener* StartAndEndFrame(const Http2FrameHeader& header);
-
-  // If IsInProgress==true, returns the FrameParts into which the current
-  // frame is being recorded; else records a test failure and returns
-  // failing_listener_, which will record a test failure when any of its
-  // On* methods is called.
-  Http2FrameDecoderListener* CurrentFrame();
-
-  // For use in implementing On*End methods, pushes the current frame onto
-  // the vector of completed frames, and returns a pointer to it for recording
-  // the info in the final call. If IsInProgress==false, records a test failure
-  // and returns failing_listener_, which will record a test failure when any
-  // of its On* methods is called.
-  Http2FrameDecoderListener* EndFrame();
-
-  // For use in implementing OnPaddingTooLong and OnFrameSizeError, is
-  // equivalent to EndFrame() if IsInProgress==true, else equivalent to
-  // StartAndEndFrame().
-  Http2FrameDecoderListener* FrameError(const Http2FrameHeader& header);
-
- private:
-  // Returns the mutable FrameParts instance into which we're currently
-  // recording callback info if IsInProgress, else nullptr.
-  FrameParts* current_frame() { return current_frame_.get(); }
-
-  // If expected header is set, verify that it matches the header param.
-  // TODO(jamessynge): Remove TestExpectedHeader et al. once done
-  // with supporting SpdyFramer's exact states.
-  void TestExpectedHeader(const Http2FrameHeader& header);
-
-  std::unique_ptr<FrameParts> current_frame_;
-  std::vector<std::unique_ptr<FrameParts>> collected_frames_;
-  FailingHttp2FrameDecoderListener failing_listener_;
-
-  // TODO(jamessynge): Remove expected_header_ et al. once done with supporting
-  // SpdyFramer's exact states.
-  Http2FrameHeader expected_header_;
-  bool expected_header_set_ = false;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_
diff --git a/http2/test_tools/frame_parts_collector_listener.cc b/http2/test_tools/frame_parts_collector_listener.cc
deleted file mode 100644
index b185d8e..0000000
--- a/http2/test_tools/frame_parts_collector_listener.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/test_tools/frame_parts_collector_listener.h"
-
-#include "http2/platform/api/http2_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-bool FramePartsCollectorListener::OnFrameHeader(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnFrameHeader: " << header;
-  ExpectFrameHeader(header);
-  return true;
-}
-
-void FramePartsCollectorListener::OnDataStart(const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnDataStart: " << header;
-  StartFrame(header)->OnDataStart(header);
-}
-
-void FramePartsCollectorListener::OnDataPayload(const char* data, size_t len) {
-  HTTP2_VLOG(1) << "OnDataPayload: len=" << len;
-  CurrentFrame()->OnDataPayload(data, len);
-}
-
-void FramePartsCollectorListener::OnDataEnd() {
-  HTTP2_VLOG(1) << "OnDataEnd";
-  EndFrame()->OnDataEnd();
-}
-
-void FramePartsCollectorListener::OnHeadersStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
-  StartFrame(header)->OnHeadersStart(header);
-}
-
-void FramePartsCollectorListener::OnHeadersPriority(
-    const Http2PriorityFields& priority) {
-  HTTP2_VLOG(1) << "OnHeadersPriority: " << priority;
-  CurrentFrame()->OnHeadersPriority(priority);
-}
-
-void FramePartsCollectorListener::OnHpackFragment(const char* data,
-                                                  size_t len) {
-  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
-  CurrentFrame()->OnHpackFragment(data, len);
-}
-
-void FramePartsCollectorListener::OnHeadersEnd() {
-  HTTP2_VLOG(1) << "OnHeadersEnd";
-  EndFrame()->OnHeadersEnd();
-}
-
-void FramePartsCollectorListener::OnPriorityFrame(
-    const Http2FrameHeader& header,
-    const Http2PriorityFields& priority_fields) {
-  HTTP2_VLOG(1) << "OnPriority: " << header << "; " << priority_fields;
-  StartAndEndFrame(header)->OnPriorityFrame(header, priority_fields);
-}
-
-void FramePartsCollectorListener::OnContinuationStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
-  StartFrame(header)->OnContinuationStart(header);
-}
-
-void FramePartsCollectorListener::OnContinuationEnd() {
-  HTTP2_VLOG(1) << "OnContinuationEnd";
-  EndFrame()->OnContinuationEnd();
-}
-
-void FramePartsCollectorListener::OnPadLength(size_t pad_length) {
-  HTTP2_VLOG(1) << "OnPadLength: " << pad_length;
-  CurrentFrame()->OnPadLength(pad_length);
-}
-
-void FramePartsCollectorListener::OnPadding(const char* padding,
-                                            size_t skipped_length) {
-  HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
-  CurrentFrame()->OnPadding(padding, skipped_length);
-}
-
-void FramePartsCollectorListener::OnRstStream(const Http2FrameHeader& header,
-                                              Http2ErrorCode error_code) {
-  HTTP2_VLOG(1) << "OnRstStream: " << header << "; error_code=" << error_code;
-  StartAndEndFrame(header)->OnRstStream(header, error_code);
-}
-
-void FramePartsCollectorListener::OnSettingsStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
-  EXPECT_EQ(Http2FrameType::SETTINGS, header.type) << header;
-  EXPECT_EQ(Http2FrameFlag(), header.flags) << header;
-  StartFrame(header)->OnSettingsStart(header);
-}
-
-void FramePartsCollectorListener::OnSetting(
-    const Http2SettingFields& setting_fields) {
-  HTTP2_VLOG(1) << "Http2SettingFields: setting_fields=" << setting_fields;
-  CurrentFrame()->OnSetting(setting_fields);
-}
-
-void FramePartsCollectorListener::OnSettingsEnd() {
-  HTTP2_VLOG(1) << "OnSettingsEnd";
-  EndFrame()->OnSettingsEnd();
-}
-
-void FramePartsCollectorListener::OnSettingsAck(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
-  StartAndEndFrame(header)->OnSettingsAck(header);
-}
-
-void FramePartsCollectorListener::OnPushPromiseStart(
-    const Http2FrameHeader& header,
-    const Http2PushPromiseFields& promise,
-    size_t total_padding_length) {
-  HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
-                << "  promise: " << promise
-                << "  total_padding_length: " << total_padding_length;
-  EXPECT_EQ(Http2FrameType::PUSH_PROMISE, header.type);
-  StartFrame(header)->OnPushPromiseStart(header, promise, total_padding_length);
-}
-
-void FramePartsCollectorListener::OnPushPromiseEnd() {
-  HTTP2_VLOG(1) << "OnPushPromiseEnd";
-  EndFrame()->OnPushPromiseEnd();
-}
-
-void FramePartsCollectorListener::OnPing(const Http2FrameHeader& header,
-                                         const Http2PingFields& ping) {
-  HTTP2_VLOG(1) << "OnPing: " << header << "; " << ping;
-  StartAndEndFrame(header)->OnPing(header, ping);
-}
-
-void FramePartsCollectorListener::OnPingAck(const Http2FrameHeader& header,
-                                            const Http2PingFields& ping) {
-  HTTP2_VLOG(1) << "OnPingAck: " << header << "; " << ping;
-  StartAndEndFrame(header)->OnPingAck(header, ping);
-}
-
-void FramePartsCollectorListener::OnGoAwayStart(
-    const Http2FrameHeader& header,
-    const Http2GoAwayFields& goaway) {
-  HTTP2_VLOG(1) << "OnGoAwayStart header: " << header << "; goaway: " << goaway;
-  StartFrame(header)->OnGoAwayStart(header, goaway);
-}
-
-void FramePartsCollectorListener::OnGoAwayOpaqueData(const char* data,
-                                                     size_t len) {
-  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
-  CurrentFrame()->OnGoAwayOpaqueData(data, len);
-}
-
-void FramePartsCollectorListener::OnGoAwayEnd() {
-  HTTP2_VLOG(1) << "OnGoAwayEnd";
-  EndFrame()->OnGoAwayEnd();
-}
-
-void FramePartsCollectorListener::OnWindowUpdate(
-    const Http2FrameHeader& header,
-    uint32_t window_size_increment) {
-  HTTP2_VLOG(1) << "OnWindowUpdate: " << header
-                << "; window_size_increment=" << window_size_increment;
-  EXPECT_EQ(Http2FrameType::WINDOW_UPDATE, header.type);
-  StartAndEndFrame(header)->OnWindowUpdate(header, window_size_increment);
-}
-
-void FramePartsCollectorListener::OnAltSvcStart(const Http2FrameHeader& header,
-                                                size_t origin_length,
-                                                size_t value_length) {
-  HTTP2_VLOG(1) << "OnAltSvcStart header: " << header
-                << "; origin_length=" << origin_length
-                << "; value_length=" << value_length;
-  StartFrame(header)->OnAltSvcStart(header, origin_length, value_length);
-}
-
-void FramePartsCollectorListener::OnAltSvcOriginData(const char* data,
-                                                     size_t len) {
-  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
-  CurrentFrame()->OnAltSvcOriginData(data, len);
-}
-
-void FramePartsCollectorListener::OnAltSvcValueData(const char* data,
-                                                    size_t len) {
-  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
-  CurrentFrame()->OnAltSvcValueData(data, len);
-}
-
-void FramePartsCollectorListener::OnAltSvcEnd() {
-  HTTP2_VLOG(1) << "OnAltSvcEnd";
-  EndFrame()->OnAltSvcEnd();
-}
-
-void FramePartsCollectorListener::OnPriorityUpdateStart(
-    const Http2FrameHeader& header,
-    const Http2PriorityUpdateFields& priority_update) {
-  HTTP2_VLOG(1) << "OnPriorityUpdateStart header: " << header
-                << "; priority_update=" << priority_update;
-  StartFrame(header)->OnPriorityUpdateStart(header, priority_update);
-}
-
-void FramePartsCollectorListener::OnPriorityUpdatePayload(const char* data,
-                                                          size_t len) {
-  HTTP2_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
-  CurrentFrame()->OnPriorityUpdatePayload(data, len);
-}
-
-void FramePartsCollectorListener::OnPriorityUpdateEnd() {
-  HTTP2_VLOG(1) << "OnPriorityUpdateEnd";
-  EndFrame()->OnPriorityUpdateEnd();
-}
-
-void FramePartsCollectorListener::OnUnknownStart(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
-  StartFrame(header)->OnUnknownStart(header);
-}
-
-void FramePartsCollectorListener::OnUnknownPayload(const char* data,
-                                                   size_t len) {
-  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
-  CurrentFrame()->OnUnknownPayload(data, len);
-}
-
-void FramePartsCollectorListener::OnUnknownEnd() {
-  HTTP2_VLOG(1) << "OnUnknownEnd";
-  EndFrame()->OnUnknownEnd();
-}
-
-void FramePartsCollectorListener::OnPaddingTooLong(
-    const Http2FrameHeader& header,
-    size_t missing_length) {
-  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
-                << "    missing_length: " << missing_length;
-  EndFrame()->OnPaddingTooLong(header, missing_length);
-}
-
-void FramePartsCollectorListener::OnFrameSizeError(
-    const Http2FrameHeader& header) {
-  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
-  FrameError(header)->OnFrameSizeError(header);
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/test_tools/frame_parts_collector_listener.h b/http2/test_tools/frame_parts_collector_listener.h
deleted file mode 100644
index bb09bf8..0000000
--- a/http2/test_tools/frame_parts_collector_listener.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_LISTENER_H_
-#define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_LISTENER_H_
-
-// FramePartsCollectorListener extends FramePartsCollector with an
-// implementation of every method of Http2FrameDecoderListener; it is
-// essentially the union of all the Listener classes in the tests of the
-// payload decoders (i.e. in ./payload_decoders/*_test.cc files), with the
-// addition of the OnFrameHeader method.
-// FramePartsCollectorListener supports tests of Http2FrameDecoder.
-
-#include <stddef.h>
-
-#include <cstdint>
-
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "http2/test_tools/frame_parts_collector.h"
-
-namespace http2 {
-namespace test {
-
-class FramePartsCollectorListener : public FramePartsCollector {
- public:
-  FramePartsCollectorListener() {}
-  ~FramePartsCollectorListener() override {}
-
-  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
-  // SpdyFramer's exact states.
-  bool OnFrameHeader(const Http2FrameHeader& header) override;
-  void OnDataStart(const Http2FrameHeader& header) override;
-  void OnDataPayload(const char* data, size_t len) override;
-  void OnDataEnd() override;
-  void OnHeadersStart(const Http2FrameHeader& header) override;
-  void OnHeadersPriority(const Http2PriorityFields& priority) override;
-  void OnHpackFragment(const char* data, size_t len) override;
-  void OnHeadersEnd() override;
-  void OnPriorityFrame(const Http2FrameHeader& header,
-                       const Http2PriorityFields& priority_fields) override;
-  void OnContinuationStart(const Http2FrameHeader& header) override;
-  void OnContinuationEnd() override;
-  void OnPadLength(size_t pad_length) override;
-  void OnPadding(const char* padding, size_t skipped_length) override;
-  void OnRstStream(const Http2FrameHeader& header,
-                   Http2ErrorCode error_code) override;
-  void OnSettingsStart(const Http2FrameHeader& header) override;
-  void OnSetting(const Http2SettingFields& setting_fields) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck(const Http2FrameHeader& header) override;
-  void OnPushPromiseStart(const Http2FrameHeader& header,
-                          const Http2PushPromiseFields& promise,
-                          size_t total_padding_length) override;
-  void OnPushPromiseEnd() override;
-  void OnPing(const Http2FrameHeader& header,
-              const Http2PingFields& ping) override;
-  void OnPingAck(const Http2FrameHeader& header,
-                 const Http2PingFields& ping) override;
-  void OnGoAwayStart(const Http2FrameHeader& header,
-                     const Http2GoAwayFields& goaway) override;
-  void OnGoAwayOpaqueData(const char* data, size_t len) override;
-  void OnGoAwayEnd() override;
-  void OnWindowUpdate(const Http2FrameHeader& header,
-                      uint32_t window_size_increment) override;
-  void OnAltSvcStart(const Http2FrameHeader& header,
-                     size_t origin_length,
-                     size_t value_length) override;
-  void OnAltSvcOriginData(const char* data, size_t len) override;
-  void OnAltSvcValueData(const char* data, size_t len) override;
-  void OnAltSvcEnd() override;
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) override;
-  void OnPriorityUpdatePayload(const char* data, size_t len) override;
-  void OnPriorityUpdateEnd() override;
-  void OnUnknownStart(const Http2FrameHeader& header) override;
-  void OnUnknownPayload(const char* data, size_t len) override;
-  void OnUnknownEnd() override;
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override;
-  void OnFrameSizeError(const Http2FrameHeader& header) override;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_LISTENER_H_
diff --git a/http2/test_tools/http2_random.cc b/http2/test_tools/http2_random.cc
deleted file mode 100644
index 71c08b7..0000000
--- a/http2/test_tools/http2_random.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "http2/test_tools/http2_random.h"
-
-#include "absl/strings/escaping.h"
-#include "http2/platform/api/http2_logging.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "third_party/boringssl/src/include/openssl/rand.h"
-
-static const uint8_t kZeroNonce[12] = {0};
-
-namespace http2 {
-namespace test {
-
-Http2Random::Http2Random() {
-  RAND_bytes(key_, sizeof(key_));
-
-  HTTP2_LOG(INFO) << "Initialized test RNG with the following key: " << Key();
-}
-
-Http2Random::Http2Random(absl::string_view key) {
-  std::string decoded_key = absl::HexStringToBytes(key);
-  QUICHE_CHECK_EQ(sizeof(key_), decoded_key.size());
-  memcpy(key_, decoded_key.data(), sizeof(key_));
-}
-
-std::string Http2Random::Key() const {
-  return absl::BytesToHexString(
-      absl::string_view(reinterpret_cast<const char*>(key_), sizeof(key_)));
-}
-
-void Http2Random::FillRandom(void* buffer, size_t buffer_size) {
-  memset(buffer, 0, buffer_size);
-  uint8_t* buffer_u8 = reinterpret_cast<uint8_t*>(buffer);
-  CRYPTO_chacha_20(buffer_u8, buffer_u8, buffer_size, key_, kZeroNonce,
-                   counter_++);
-}
-
-std::string Http2Random::RandString(int length) {
-  std::string result;
-  result.resize(length);
-  FillRandom(&result[0], length);
-  return result;
-}
-
-uint64_t Http2Random::Rand64() {
-  union {
-    uint64_t number;
-    uint8_t bytes[sizeof(uint64_t)];
-  } result;
-  FillRandom(result.bytes, sizeof(result.bytes));
-  return result.number;
-}
-
-double Http2Random::RandDouble() {
-  union {
-    double f;
-    uint64_t i;
-  } value;
-  value.i = (1023ull << 52ull) | (Rand64() & 0xfffffffffffffu);
-  return value.f - 1.0;
-}
-
-std::string Http2Random::RandStringWithAlphabet(int length,
-                                                absl::string_view alphabet) {
-  std::string result;
-  result.resize(length);
-  for (int i = 0; i < length; i++) {
-    result[i] = alphabet[Uniform(alphabet.size())];
-  }
-  return result;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/test_tools/http2_random_test.cc b/http2/test_tools/http2_random_test.cc
deleted file mode 100644
index d6dfdb7..0000000
--- a/http2/test_tools/http2_random_test.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "http2/test_tools/http2_random.h"
-
-#include <set>
-
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-namespace {
-
-TEST(Http2RandomTest, ProducesDifferentNumbers) {
-  Http2Random random;
-  uint64_t value1 = random.Rand64();
-  uint64_t value2 = random.Rand64();
-  uint64_t value3 = random.Rand64();
-
-  EXPECT_NE(value1, value2);
-  EXPECT_NE(value2, value3);
-  EXPECT_NE(value3, value1);
-}
-
-TEST(Http2RandomTest, StartsWithDifferentKeys) {
-  Http2Random random1;
-  Http2Random random2;
-
-  EXPECT_NE(random1.Key(), random2.Key());
-  EXPECT_NE(random1.Rand64(), random2.Rand64());
-  EXPECT_NE(random1.Rand64(), random2.Rand64());
-  EXPECT_NE(random1.Rand64(), random2.Rand64());
-}
-
-TEST(Http2RandomTest, ReproducibleRandom) {
-  Http2Random random;
-  uint64_t value1 = random.Rand64();
-  uint64_t value2 = random.Rand64();
-
-  Http2Random clone_random(random.Key());
-  EXPECT_EQ(clone_random.Key(), random.Key());
-  EXPECT_EQ(value1, clone_random.Rand64());
-  EXPECT_EQ(value2, clone_random.Rand64());
-}
-
-TEST(Http2RandomTest, STLShuffle) {
-  Http2Random random;
-  const std::string original = "abcdefghijklmonpqrsuvwxyz";
-
-  std::string shuffled = original;
-  std::shuffle(shuffled.begin(), shuffled.end(), random);
-  EXPECT_NE(original, shuffled);
-}
-
-TEST(Http2RandomTest, RandFloat) {
-  Http2Random random;
-  for (int i = 0; i < 10000; i++) {
-    float value = random.RandFloat();
-    ASSERT_GE(value, 0.f);
-    ASSERT_LE(value, 1.f);
-  }
-}
-
-TEST(Http2RandomTest, RandStringWithAlphabet) {
-  Http2Random random;
-  std::string str = random.RandStringWithAlphabet(1000, "xyz");
-  EXPECT_EQ(1000u, str.size());
-
-  std::set<char> characters(str.begin(), str.end());
-  EXPECT_THAT(characters, testing::ElementsAre('x', 'y', 'z'));
-}
-
-TEST(Http2RandomTest, SkewedLow) {
-  Http2Random random;
-  constexpr size_t kMax = 1234;
-  for (int i = 0; i < 10000; i++) {
-    size_t value = random.RandomSizeSkewedLow(kMax);
-    ASSERT_GE(value, 0u);
-    ASSERT_LE(value, kMax);
-  }
-}
-
-// Checks that SkewedLow() generates full range.  This is required, since in
-// some unit tests would infinitely loop.
-TEST(Http2RandomTest, SkewedLowFullRange) {
-  Http2Random random;
-  std::set<size_t> values;
-  for (int i = 0; i < 1000; i++) {
-    values.insert(random.RandomSizeSkewedLow(3));
-  }
-  EXPECT_THAT(values, testing::ElementsAre(0, 1, 2, 3));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace http2
diff --git a/http2/tools/http2_frame_builder.cc b/http2/tools/http2_frame_builder.cc
deleted file mode 100644
index 1481594..0000000
--- a/http2/tools/http2_frame_builder.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/tools/http2_frame_builder.h"
-
-#ifdef WIN32
-#include <winsock2.h>  // for htonl() functions
-#else
-#include <arpa/inet.h>
-#include <netinet/in.h>  // for htonl, htons
-#endif
-
-#include "absl/strings/str_cat.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-Http2FrameBuilder::Http2FrameBuilder(Http2FrameType type,
-                                     uint8_t flags,
-                                     uint32_t stream_id) {
-  AppendUInt24(0);  // Frame payload length, unknown so far.
-  Append(type);
-  AppendUInt8(flags);
-  AppendUInt31(stream_id);
-}
-
-Http2FrameBuilder::Http2FrameBuilder(const Http2FrameHeader& v) {
-  Append(v);
-}
-
-void Http2FrameBuilder::Append(absl::string_view s) {
-  absl::StrAppend(&buffer_, s);
-}
-
-void Http2FrameBuilder::AppendBytes(const void* data, uint32_t num_bytes) {
-  Append(absl::string_view(static_cast<const char*>(data), num_bytes));
-}
-
-void Http2FrameBuilder::AppendZeroes(size_t num_zero_bytes) {
-  char zero = 0;
-  buffer_.append(num_zero_bytes, zero);
-}
-
-void Http2FrameBuilder::AppendUInt8(uint8_t value) {
-  AppendBytes(&value, 1);
-}
-
-void Http2FrameBuilder::AppendUInt16(uint16_t value) {
-  value = htons(value);
-  AppendBytes(&value, 2);
-}
-
-void Http2FrameBuilder::AppendUInt24(uint32_t value) {
-  // Doesn't make sense to try to append a larger value, as that doesn't
-  // simulate something an encoder could do (i.e. the other 8 bits simply aren't
-  // there to be occupied).
-  EXPECT_EQ(value, value & 0xffffff);
-  value = htonl(value);
-  AppendBytes(reinterpret_cast<char*>(&value) + 1, 3);
-}
-
-void Http2FrameBuilder::AppendUInt31(uint32_t value) {
-  // If you want to test the high-bit being set, call AppendUInt32 instead.
-  uint32_t tmp = value & StreamIdMask();
-  EXPECT_EQ(value, value & StreamIdMask())
-      << "High-bit of uint32_t should be clear.";
-  value = htonl(tmp);
-  AppendBytes(&value, 4);
-}
-
-void Http2FrameBuilder::AppendUInt32(uint32_t value) {
-  value = htonl(value);
-  AppendBytes(&value, sizeof(value));
-}
-
-void Http2FrameBuilder::Append(Http2ErrorCode error_code) {
-  AppendUInt32(static_cast<uint32_t>(error_code));
-}
-
-void Http2FrameBuilder::Append(Http2FrameType type) {
-  AppendUInt8(static_cast<uint8_t>(type));
-}
-
-void Http2FrameBuilder::Append(Http2SettingsParameter parameter) {
-  AppendUInt16(static_cast<uint16_t>(parameter));
-}
-
-void Http2FrameBuilder::Append(const Http2FrameHeader& v) {
-  AppendUInt24(v.payload_length);
-  Append(v.type);
-  AppendUInt8(v.flags);
-  AppendUInt31(v.stream_id);
-}
-
-void Http2FrameBuilder::Append(const Http2PriorityFields& v) {
-  // The EXCLUSIVE flag is the high-bit of the 32-bit stream dependency field.
-  uint32_t tmp = v.stream_dependency & StreamIdMask();
-  EXPECT_EQ(tmp, v.stream_dependency);
-  if (v.is_exclusive) {
-    tmp |= 0x80000000;
-  }
-  AppendUInt32(tmp);
-
-  // The PRIORITY frame's weight field is logically in the range [1, 256],
-  // but is encoded as a byte in the range [0, 255].
-  ASSERT_LE(1u, v.weight);
-  ASSERT_LE(v.weight, 256u);
-  AppendUInt8(v.weight - 1);
-}
-
-void Http2FrameBuilder::Append(const Http2RstStreamFields& v) {
-  Append(v.error_code);
-}
-
-void Http2FrameBuilder::Append(const Http2SettingFields& v) {
-  Append(v.parameter);
-  AppendUInt32(v.value);
-}
-
-void Http2FrameBuilder::Append(const Http2PushPromiseFields& v) {
-  AppendUInt31(v.promised_stream_id);
-}
-
-void Http2FrameBuilder::Append(const Http2PingFields& v) {
-  AppendBytes(v.opaque_bytes, sizeof Http2PingFields::opaque_bytes);
-}
-
-void Http2FrameBuilder::Append(const Http2GoAwayFields& v) {
-  AppendUInt31(v.last_stream_id);
-  Append(v.error_code);
-}
-
-void Http2FrameBuilder::Append(const Http2WindowUpdateFields& v) {
-  EXPECT_NE(0u, v.window_size_increment) << "Increment must be non-zero.";
-  AppendUInt31(v.window_size_increment);
-}
-
-void Http2FrameBuilder::Append(const Http2AltSvcFields& v) {
-  AppendUInt16(v.origin_length);
-}
-
-void Http2FrameBuilder::Append(const Http2PriorityUpdateFields& v) {
-  AppendUInt31(v.prioritized_stream_id);
-}
-
-// Methods for changing existing buffer contents.
-
-void Http2FrameBuilder::WriteAt(absl::string_view s, size_t offset) {
-  ASSERT_LE(offset, buffer_.size());
-  size_t len = offset + s.size();
-  if (len > buffer_.size()) {
-    buffer_.resize(len);
-  }
-  for (size_t ndx = 0; ndx < s.size(); ++ndx) {
-    buffer_[offset + ndx] = s[ndx];
-  }
-}
-
-void Http2FrameBuilder::WriteBytesAt(const void* data,
-                                     uint32_t num_bytes,
-                                     size_t offset) {
-  WriteAt(absl::string_view(static_cast<const char*>(data), num_bytes), offset);
-}
-
-void Http2FrameBuilder::WriteUInt24At(uint32_t value, size_t offset) {
-  ASSERT_LT(value, static_cast<uint32_t>(1 << 24));
-  value = htonl(value);
-  WriteBytesAt(reinterpret_cast<char*>(&value) + 1, sizeof(value) - 1, offset);
-}
-
-void Http2FrameBuilder::SetPayloadLength(uint32_t payload_length) {
-  WriteUInt24At(payload_length, 0);
-}
-
-size_t Http2FrameBuilder::SetPayloadLength() {
-  EXPECT_GE(size(), Http2FrameHeader::EncodedSize());
-  uint32_t payload_length = size() - Http2FrameHeader::EncodedSize();
-  SetPayloadLength(payload_length);
-  return payload_length;
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/tools/http2_frame_builder.h b/http2/tools/http2_frame_builder.h
deleted file mode 100644
index 52f6350..0000000
--- a/http2/tools/http2_frame_builder.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_TOOLS_HTTP2_FRAME_BUILDER_H_
-#define QUICHE_HTTP2_TOOLS_HTTP2_FRAME_BUILDER_H_
-
-// Http2FrameBuilder builds wire-format HTTP/2 frames (or fragments thereof)
-// from components.
-//
-// For now, this is only intended for use in tests, and thus has EXPECT* in the
-// code. If desired to use it in an encoder, it will need optimization work,
-// especially w.r.t memory mgmt, and the EXPECT* will need to be removed or
-// replaced with QUICHE_DCHECKs.
-
-#include <stddef.h>  // for size_t
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-
-namespace http2 {
-namespace test {
-
-class Http2FrameBuilder {
- public:
-  Http2FrameBuilder(Http2FrameType type, uint8_t flags, uint32_t stream_id);
-  explicit Http2FrameBuilder(const Http2FrameHeader& v);
-  Http2FrameBuilder() {}
-  ~Http2FrameBuilder() {}
-
-  size_t size() const { return buffer_.size(); }
-  const std::string& buffer() const { return buffer_; }
-
-  //----------------------------------------------------------------------------
-  // Methods for appending to the end of the buffer.
-
-  // Append a sequence of bytes from various sources.
-  void Append(absl::string_view s);
-  void AppendBytes(const void* data, uint32_t num_bytes);
-
-  // Append an array of type T[N] to the string. Intended for tests with arrays
-  // initialized from literals, such as:
-  //    const char kData[] = {0x12, 0x23, ...};
-  //    builder.AppendBytes(kData);
-  template <typename T, size_t N>
-  void AppendBytes(T (&buf)[N]) {
-    AppendBytes(buf, N * sizeof(buf[0]));
-  }
-
-  // Support for appending padding. Does not read or write the Pad Length field.
-  void AppendZeroes(size_t num_zero_bytes);
-
-  // Append various sizes of unsigned integers.
-  void AppendUInt8(uint8_t value);
-  void AppendUInt16(uint16_t value);
-  void AppendUInt24(uint32_t value);
-  void AppendUInt31(uint32_t value);
-  void AppendUInt32(uint32_t value);
-
-  // Append various enums.
-  void Append(Http2ErrorCode error_code);
-  void Append(Http2FrameType type);
-  void Append(Http2SettingsParameter parameter);
-
-  // Append various structures.
-  void Append(const Http2FrameHeader& v);
-  void Append(const Http2PriorityFields& v);
-  void Append(const Http2RstStreamFields& v);
-  void Append(const Http2SettingFields& v);
-  void Append(const Http2PushPromiseFields& v);
-  void Append(const Http2PingFields& v);
-  void Append(const Http2GoAwayFields& v);
-  void Append(const Http2WindowUpdateFields& v);
-  void Append(const Http2AltSvcFields& v);
-  void Append(const Http2PriorityUpdateFields& v);
-
-  // Methods for changing existing buffer contents (mostly focused on updating
-  // the payload length).
-
-  void WriteAt(absl::string_view s, size_t offset);
-  void WriteBytesAt(const void* data, uint32_t num_bytes, size_t offset);
-  void WriteUInt24At(uint32_t value, size_t offset);
-
-  // Set the payload length to the specified size.
-  void SetPayloadLength(uint32_t payload_length);
-
-  // Sets the payload length to the size of the buffer minus the size of
-  // the frame header.
-  size_t SetPayloadLength();
-
- private:
-  std::string buffer_;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_TOOLS_HTTP2_FRAME_BUILDER_H_
diff --git a/http2/tools/random_decoder_test.cc b/http2/tools/random_decoder_test.cc
deleted file mode 100644
index a49e97f..0000000
--- a/http2/tools/random_decoder_test.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/tools/random_decoder_test.h"
-
-#include <stddef.h>
-
-#include <algorithm>
-#include <memory>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/http2_constants.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_test.h"
-
-using ::testing::AssertionResult;
-
-namespace http2 {
-namespace test {
-
-RandomDecoderTest::RandomDecoderTest() = default;
-
-bool RandomDecoderTest::StopDecodeOnDone() {
-  return stop_decode_on_done_;
-}
-
-DecodeStatus RandomDecoderTest::DecodeSegments(DecodeBuffer* original,
-                                               const SelectSize& select_size) {
-  DecodeStatus status = DecodeStatus::kDecodeInProgress;
-  bool first = true;
-  HTTP2_VLOG(2) << "DecodeSegments: input size=" << original->Remaining();
-  while (first || original->HasData()) {
-    size_t remaining = original->Remaining();
-    size_t size =
-        std::min(remaining, select_size(first, original->Offset(), remaining));
-    DecodeBuffer db(original->cursor(), size);
-    HTTP2_VLOG(2) << "Decoding " << size << " bytes of " << remaining
-                  << " remaining";
-    if (first) {
-      first = false;
-      status = StartDecoding(&db);
-    } else {
-      status = ResumeDecoding(&db);
-    }
-    // A decoder MUST consume some input (if any is available), else we could
-    // get stuck in infinite loops.
-    if (db.Offset() == 0 && db.HasData() &&
-        status != DecodeStatus::kDecodeError) {
-      ADD_FAILURE() << "Decoder didn't make any progress; db.FullSize="
-                    << db.FullSize()
-                    << "   original.Offset=" << original->Offset();
-      return DecodeStatus::kDecodeError;
-    }
-    original->AdvanceCursor(db.Offset());
-    switch (status) {
-      case DecodeStatus::kDecodeDone:
-        if (original->Empty() || StopDecodeOnDone()) {
-          return DecodeStatus::kDecodeDone;
-        }
-        continue;
-      case DecodeStatus::kDecodeInProgress:
-        continue;
-      case DecodeStatus::kDecodeError:
-        return DecodeStatus::kDecodeError;
-    }
-  }
-  return status;
-}
-
-// Decode |original| multiple times, with different segmentations, validating
-// after each decode, returning on the first failure.
-AssertionResult RandomDecoderTest::DecodeAndValidateSeveralWays(
-    DecodeBuffer* original,
-    bool return_non_zero_on_first,
-    const Validator& validator) {
-  const uint32_t original_remaining = original->Remaining();
-  HTTP2_VLOG(1) << "DecodeAndValidateSeveralWays - Start, remaining = "
-                << original_remaining;
-  uint32_t first_consumed;
-  {
-    // Fast decode (no stopping unless decoder does so).
-    DecodeBuffer input(original->cursor(), original_remaining);
-    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectRemaining";
-    VERIFY_SUCCESS(
-        DecodeSegmentsAndValidate(&input, SelectRemaining(), validator))
-        << "\nFailed with SelectRemaining; input.Offset=" << input.Offset()
-        << "; input.Remaining=" << input.Remaining();
-    first_consumed = input.Offset();
-  }
-  if (original_remaining <= 30) {
-    // Decode again, one byte at a time.
-    DecodeBuffer input(original->cursor(), original_remaining);
-    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectOne";
-    VERIFY_SUCCESS(DecodeSegmentsAndValidate(&input, SelectOne(), validator))
-        << "\nFailed with SelectOne; input.Offset=" << input.Offset()
-        << "; input.Remaining=" << input.Remaining();
-    VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectOne";
-  }
-  if (original_remaining <= 20) {
-    // Decode again, one or zero bytes at a time.
-    DecodeBuffer input(original->cursor(), original_remaining);
-    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectZeroAndOne";
-    VERIFY_SUCCESS(DecodeSegmentsAndValidate(
-        &input, SelectZeroAndOne(return_non_zero_on_first), validator))
-        << "\nFailed with SelectZeroAndOne";
-    VERIFY_EQ(first_consumed, input.Offset())
-        << "\nFailed with SelectZeroAndOne; input.Offset=" << input.Offset()
-        << "; input.Remaining=" << input.Remaining();
-  }
-  {
-    // Decode again, with randomly selected segment sizes.
-    DecodeBuffer input(original->cursor(), original_remaining);
-    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectRandom";
-    VERIFY_SUCCESS(DecodeSegmentsAndValidate(
-        &input, SelectRandom(return_non_zero_on_first), validator))
-        << "\nFailed with SelectRandom; input.Offset=" << input.Offset()
-        << "; input.Remaining=" << input.Remaining();
-    VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectRandom";
-  }
-  VERIFY_EQ(original_remaining, original->Remaining());
-  original->AdvanceCursor(first_consumed);
-  HTTP2_VLOG(1) << "DecodeAndValidateSeveralWays - SUCCESS";
-  return ::testing::AssertionSuccess();
-}
-
-// static
-RandomDecoderTest::SelectSize RandomDecoderTest::SelectZeroAndOne(
-    bool return_non_zero_on_first) {
-  std::shared_ptr<bool> zero_next(new bool);
-  *zero_next = !return_non_zero_on_first;
-  return [zero_next](bool /*first*/, size_t /*offset*/,
-                     size_t /*remaining*/) -> size_t {
-    if (*zero_next) {
-      *zero_next = false;
-      return 0;
-    } else {
-      *zero_next = true;
-      return 1;
-    }
-  };
-}
-
-RandomDecoderTest::SelectSize RandomDecoderTest::SelectRandom(
-    bool return_non_zero_on_first) {
-  return [this, return_non_zero_on_first](bool first, size_t /*offset*/,
-                                          size_t remaining) -> size_t {
-    uint32_t r = random_.Rand32();
-    if (first && return_non_zero_on_first) {
-      QUICHE_CHECK_LT(0u, remaining);
-      if (remaining == 1) {
-        return 1;
-      }
-      return 1 + (r % remaining);  // size in range [1, remaining).
-    }
-    return r % (remaining + 1);  // size in range [0, remaining].
-  };
-}
-
-uint32_t RandomDecoderTest::RandStreamId() {
-  return random_.Rand32() & StreamIdMask();
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/tools/random_decoder_test.h b/http2/tools/random_decoder_test.h
deleted file mode 100644
index 50c2e9e..0000000
--- a/http2/tools/random_decoder_test.h
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
-#define QUICHE_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
-
-// RandomDecoderTest is a base class for tests of decoding various kinds
-// of HTTP/2 and HPACK encodings.
-
-// TODO(jamessynge): Move more methods into .cc file.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <functional>
-#include <memory>
-#include <type_traits>
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/platform/api/http2_logging.h"
-#include "http2/platform/api/http2_test_helpers.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace http2 {
-namespace test {
-
-// Some helpers.
-
-template <typename T, size_t N>
-absl::string_view ToStringPiece(T (&data)[N]) {
-  return absl::string_view(reinterpret_cast<const char*>(data), N * sizeof(T));
-}
-
-// Overwrite the enum with some random value, probably not a valid value for
-// the enum type, but which fits into its storage.
-template <typename T,
-          typename E = typename std::enable_if<std::is_enum<T>::value>::type>
-void CorruptEnum(T* out, Http2Random* rng) {
-  // Per cppreference.com, if the destination type of a static_cast is
-  // smaller than the source type (i.e. type of r and uint32 below), the
-  // resulting value is the smallest unsigned value equal to the source value
-  // modulo 2^n, where n is the number of bits used to represent the
-  // destination type unsigned U.
-  using underlying_type_T = typename std::underlying_type<T>::type;
-  using unsigned_underlying_type_T =
-      typename std::make_unsigned<underlying_type_T>::type;
-  auto r = static_cast<unsigned_underlying_type_T>(rng->Rand32());
-  *out = static_cast<T>(r);
-}
-
-// Base class for tests of the ability to decode a sequence of bytes with
-// various boundaries between the DecodeBuffers provided to the decoder.
-class RandomDecoderTest : public QuicheTest {
- public:
-  // SelectSize returns the size of the next DecodeBuffer to be passed to the
-  // decoder. Note that RandomDecoderTest allows that size to be zero, though
-  // some decoders can't deal with that on the first byte, hence the |first|
-  // parameter.
-  typedef std::function<size_t(bool first, size_t offset, size_t remaining)>
-      SelectSize;
-
-  // Validator returns an AssertionResult so test can do:
-  // EXPECT_THAT(DecodeAndValidate(..., validator));
-  typedef ::testing::AssertionResult AssertionResult;
-  typedef std::function<AssertionResult(const DecodeBuffer& input,
-                                        DecodeStatus status)>
-      Validator;
-  typedef std::function<AssertionResult()> NoArgValidator;
-
-  RandomDecoderTest();
-
- protected:
-  // TODO(jamessynge): Modify StartDecoding, etc. to (somehow) return
-  // AssertionResult so that the VERIFY_* methods exported from
-  // gunit_helpers.h can be widely used.
-
-  // Start decoding; call allows sub-class to Reset the decoder, or deal with
-  // the first byte if that is done in a unique fashion.  Might be called with
-  // a zero byte buffer.
-  virtual DecodeStatus StartDecoding(DecodeBuffer* db) = 0;
-
-  // Resume decoding of the input after a prior call to StartDecoding, and
-  // possibly many calls to ResumeDecoding.
-  virtual DecodeStatus ResumeDecoding(DecodeBuffer* db) = 0;
-
-  // Return true if a decode status of kDecodeDone indicates that
-  // decoding should stop.
-  virtual bool StopDecodeOnDone();
-
-  // Decode buffer |original| until we run out of input, or kDecodeDone is
-  // returned by the decoder AND StopDecodeOnDone() returns true. Segments
-  // (i.e. cuts up) the original DecodeBuffer into (potentially) smaller buffers
-  // by calling |select_size| to decide how large each buffer should be.
-  // We do this to test the ability to deal with arbitrary boundaries, as might
-  // happen in transport.
-  // Returns the final DecodeStatus.
-  DecodeStatus DecodeSegments(DecodeBuffer* original,
-                              const SelectSize& select_size);
-
-  // Decode buffer |original| until we run out of input, or kDecodeDone is
-  // returned by the decoder AND StopDecodeOnDone() returns true. Segments
-  // (i.e. cuts up) the original DecodeBuffer into (potentially) smaller buffers
-  // by calling |select_size| to decide how large each buffer should be.
-  // We do this to test the ability to deal with arbitrary boundaries, as might
-  // happen in transport.
-  // Invokes |validator| with the final decode status and the original decode
-  // buffer, with the cursor advanced as far as has been consumed by the decoder
-  // and returns validator's result.
-  ::testing::AssertionResult DecodeSegmentsAndValidate(
-      DecodeBuffer* original,
-      const SelectSize& select_size,
-      const Validator& validator) {
-    DecodeStatus status = DecodeSegments(original, select_size);
-    VERIFY_AND_RETURN_SUCCESS(validator(*original, status));
-  }
-
-  // Returns a SelectSize function for fast decoding, i.e. passing all that
-  // is available to the decoder.
-  static SelectSize SelectRemaining() {
-    return [](bool /*first*/, size_t /*offset*/, size_t remaining) -> size_t {
-      return remaining;
-    };
-  }
-
-  // Returns a SelectSize function for decoding a single byte at a time.
-  static SelectSize SelectOne() {
-    return [](bool /*first*/, size_t /*offset*/,
-              size_t /*remaining*/) -> size_t { return 1; };
-  }
-
-  // Returns a SelectSize function for decoding a single byte at a time, where
-  // zero byte buffers are also allowed. Alternates between zero and one.
-  static SelectSize SelectZeroAndOne(bool return_non_zero_on_first);
-
-  // Returns a SelectSize function for decoding random sized segments.
-  SelectSize SelectRandom(bool return_non_zero_on_first);
-
-  // Decode |original| multiple times, with different segmentations of the
-  // decode buffer, validating after each decode, and confirming that they
-  // each decode the same amount. Returns on the first failure, else returns
-  // success.
-  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* original,
-                                               bool return_non_zero_on_first,
-                                               const Validator& validator);
-
-  static Validator ToValidator(std::nullptr_t) {
-    return [](const DecodeBuffer& /*input*/, DecodeStatus /*status*/) {
-      return ::testing::AssertionSuccess();
-    };
-  }
-
-  static Validator ToValidator(const Validator& validator) {
-    if (validator == nullptr) {
-      return ToValidator(nullptr);
-    }
-    return validator;
-  }
-
-  static Validator ToValidator(const NoArgValidator& validator) {
-    if (validator == nullptr) {
-      return ToValidator(nullptr);
-    }
-    return [validator](const DecodeBuffer& /*input*/, DecodeStatus /*status*/) {
-      return validator();
-    };
-  }
-
-  // Wraps a validator with another validator
-  // that first checks that the DecodeStatus is kDecodeDone and
-  // that the DecodeBuffer is empty.
-  // TODO(jamessynge): Replace this overload with the next, as using this method
-  // usually means that the wrapped function doesn't need to be passed the
-  // DecodeBuffer nor the DecodeStatus.
-  static Validator ValidateDoneAndEmpty(const Validator& wrapped) {
-    return [wrapped](const DecodeBuffer& input,
-                     DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
-      VERIFY_EQ(0u, input.Remaining()) << "\nOffset=" << input.Offset();
-      if (wrapped) {
-        return wrapped(input, status);
-      }
-      return ::testing::AssertionSuccess();
-    };
-  }
-  static Validator ValidateDoneAndEmpty(NoArgValidator wrapped) {
-    return [wrapped](const DecodeBuffer& input,
-                     DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
-      VERIFY_EQ(0u, input.Remaining()) << "\nOffset=" << input.Offset();
-      if (wrapped) {
-        return wrapped();
-      }
-      return ::testing::AssertionSuccess();
-    };
-  }
-  static Validator ValidateDoneAndEmpty() {
-    NoArgValidator validator;
-    return ValidateDoneAndEmpty(validator);
-  }
-
-  // Wraps a validator with another validator
-  // that first checks that the DecodeStatus is kDecodeDone and
-  // that the DecodeBuffer has the expected offset.
-  // TODO(jamessynge): Replace this overload with the next, as using this method
-  // usually means that the wrapped function doesn't need to be passed the
-  // DecodeBuffer nor the DecodeStatus.
-  static Validator ValidateDoneAndOffset(uint32_t offset,
-                                         const Validator& wrapped) {
-    return [wrapped, offset](const DecodeBuffer& input,
-                             DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
-      VERIFY_EQ(offset, input.Offset()) << "\nRemaining=" << input.Remaining();
-      if (wrapped) {
-        return wrapped(input, status);
-      }
-      return ::testing::AssertionSuccess();
-    };
-  }
-  static Validator ValidateDoneAndOffset(uint32_t offset,
-                                         NoArgValidator wrapped) {
-    return [wrapped, offset](const DecodeBuffer& input,
-                             DecodeStatus status) -> AssertionResult {
-      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
-      VERIFY_EQ(offset, input.Offset()) << "\nRemaining=" << input.Remaining();
-      if (wrapped) {
-        return wrapped();
-      }
-      return ::testing::AssertionSuccess();
-    };
-  }
-  static Validator ValidateDoneAndOffset(uint32_t offset) {
-    NoArgValidator validator;
-    return ValidateDoneAndOffset(offset, validator);
-  }
-
-  // Expose |random_| as Http2Random so callers don't have to care about which
-  // sub-class of Http2Random is used, nor can they rely on the specific
-  // sub-class that RandomDecoderTest uses.
-  Http2Random& Random() { return random_; }
-  Http2Random* RandomPtr() { return &random_; }
-
-  uint32_t RandStreamId();
-
-  bool stop_decode_on_done_ = true;
-
- private:
-  Http2Random random_;
-};
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
diff --git a/http2/tools/random_util.cc b/http2/tools/random_util.cc
deleted file mode 100644
index e9d1633..0000000
--- a/http2/tools/random_util.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/tools/random_util.h"
-
-#include <cmath>
-
-namespace http2 {
-namespace test {
-
-// Here "word" means something that starts with a lower-case letter, and has
-// zero or more additional characters that are numbers or lower-case letters.
-std::string GenerateHttp2HeaderName(size_t len, Http2Random* rng) {
-  absl::string_view alpha_lc = "abcdefghijklmnopqrstuvwxyz";
-  // If the name is short, just make it one word.
-  if (len < 8) {
-    return rng->RandStringWithAlphabet(len, alpha_lc);
-  }
-  // If the name is longer, ensure it starts with a word, and after that may
-  // have any character in alphanumdash_lc. 4 is arbitrary, could be as low
-  // as 1.
-  absl::string_view alphanumdash_lc = "abcdefghijklmnopqrstuvwxyz0123456789-";
-  return rng->RandStringWithAlphabet(4, alpha_lc) +
-         rng->RandStringWithAlphabet(len - 4, alphanumdash_lc);
-}
-
-std::string GenerateWebSafeString(size_t len, Http2Random* rng) {
-  static const char* kWebsafe64 =
-      "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
-  return rng->RandStringWithAlphabet(len, kWebsafe64);
-}
-
-std::string GenerateWebSafeString(size_t lo, size_t hi, Http2Random* rng) {
-  return GenerateWebSafeString(rng->UniformInRange(lo, hi), rng);
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/tools/random_util.h b/http2/tools/random_util.h
deleted file mode 100644
index dbcc64c..0000000
--- a/http2/tools/random_util.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_TOOLS_RANDOM_UTIL_H_
-#define QUICHE_HTTP2_TOOLS_RANDOM_UTIL_H_
-
-#include <stddef.h>
-
-#include <string>
-
-#include "http2/test_tools/http2_random.h"
-
-namespace http2 {
-namespace test {
-
-// Generate a string with the allowed character set for HTTP/2 / HPACK header
-// names.
-std::string GenerateHttp2HeaderName(size_t len, Http2Random* rng);
-
-// Generate a string with the web-safe string character set of specified len.
-std::string GenerateWebSafeString(size_t len, Http2Random* rng);
-
-// Generate a string with the web-safe string character set of length [lo, hi).
-std::string GenerateWebSafeString(size_t lo, size_t hi, Http2Random* rng);
-
-}  // namespace test
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_TOOLS_RANDOM_UTIL_H_
diff --git a/quic/core/batch_writer/quic_batch_writer_base.cc b/quic/core/batch_writer/quic_batch_writer_base.cc
deleted file mode 100644
index 9cdff7e..0000000
--- a/quic/core/batch_writer/quic_batch_writer_base.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-namespace quic {
-
-QuicBatchWriterBase::QuicBatchWriterBase(
-    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer)
-    : write_blocked_(false), batch_buffer_(std::move(batch_buffer)) {}
-
-WriteResult QuicBatchWriterBase::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  const WriteResult result =
-      InternalWritePacket(buffer, buf_len, self_address, peer_address, options);
-
-  if (IsWriteBlockedStatus(result.status)) {
-    write_blocked_ = true;
-  }
-
-  return result;
-}
-
-WriteResult QuicBatchWriterBase::InternalWritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  if (buf_len > kMaxOutgoingPacketSize) {
-    return WriteResult(WRITE_STATUS_MSG_TOO_BIG, EMSGSIZE);
-  }
-
-  ReleaseTime release_time{0, QuicTime::Delta::Zero()};
-  if (SupportsReleaseTime()) {
-    release_time = GetReleaseTime(options);
-    if (release_time.release_time_offset >= QuicTime::Delta::Zero()) {
-      QUIC_SERVER_HISTOGRAM_TIMES(
-          "batch_writer_positive_release_time_offset",
-          release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
-          "Duration from ideal release time to actual "
-          "release time, in microseconds.");
-    } else {
-      QUIC_SERVER_HISTOGRAM_TIMES(
-          "batch_writer_negative_release_time_offset",
-          -release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
-          "Duration from actual release time to ideal "
-          "release time, in microseconds.");
-    }
-  }
-
-  const CanBatchResult can_batch_result =
-      CanBatch(buffer, buf_len, self_address, peer_address, options,
-               release_time.actual_release_time);
-
-  bool buffered = false;
-  bool flush = can_batch_result.must_flush;
-
-  if (can_batch_result.can_batch) {
-    QuicBatchWriterBuffer::PushResult push_result =
-        batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
-                                         peer_address, options,
-                                         release_time.actual_release_time);
-    if (push_result.succeeded) {
-      buffered = true;
-      // If there's no space left after the packet is buffered, force a flush.
-      flush = flush || (batch_buffer_->GetNextWriteLocation() == nullptr);
-    } else {
-      // If there's no space without this packet, force a flush.
-      flush = true;
-    }
-  }
-
-  if (!flush) {
-    WriteResult result(WRITE_STATUS_OK, 0);
-    result.send_time_offset = release_time.release_time_offset;
-    return result;
-  }
-
-  size_t num_buffered_packets = buffered_writes().size();
-  const FlushImplResult flush_result = CheckedFlush();
-  WriteResult result = flush_result.write_result;
-  QUIC_DVLOG(1) << "Internally flushed " << flush_result.num_packets_sent
-                << " out of " << num_buffered_packets
-                << " packets. WriteResult=" << result;
-
-  if (result.status != WRITE_STATUS_OK) {
-    if (IsWriteBlockedStatus(result.status)) {
-      return WriteResult(
-          buffered ? WRITE_STATUS_BLOCKED_DATA_BUFFERED : WRITE_STATUS_BLOCKED,
-          result.error_code);
-    }
-
-    // Drop all packets, including the one being written.
-    size_t dropped_packets =
-        buffered ? buffered_writes().size() : buffered_writes().size() + 1;
-
-    batch_buffer().Clear();
-    result.dropped_packets =
-        dropped_packets > std::numeric_limits<uint16_t>::max()
-            ? std::numeric_limits<uint16_t>::max()
-            : static_cast<uint16_t>(dropped_packets);
-    return result;
-  }
-
-  if (!buffered) {
-    QuicBatchWriterBuffer::PushResult push_result =
-        batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
-                                         peer_address, options,
-                                         release_time.actual_release_time);
-    buffered = push_result.succeeded;
-
-    // Since buffered_writes has been emptied, this write must have been
-    // buffered successfully.
-    QUIC_BUG_IF(quic_bug_10826_1, !buffered)
-        << "Failed to push to an empty batch buffer."
-        << "  self_addr:" << self_address.ToString()
-        << ", peer_addr:" << peer_address.ToString() << ", buf_len:" << buf_len;
-  }
-
-  result.send_time_offset = release_time.release_time_offset;
-  return result;
-}
-
-QuicBatchWriterBase::FlushImplResult QuicBatchWriterBase::CheckedFlush() {
-  if (buffered_writes().empty()) {
-    return FlushImplResult{WriteResult(WRITE_STATUS_OK, 0),
-                           /*num_packets_sent=*/0, /*bytes_written=*/0};
-  }
-
-  const FlushImplResult flush_result = FlushImpl();
-
-  // Either flush_result.write_result.status is not WRITE_STATUS_OK, or it is
-  // WRITE_STATUS_OK and batch_buffer is empty.
-  QUICHE_DCHECK(flush_result.write_result.status != WRITE_STATUS_OK ||
-                buffered_writes().empty());
-
-  // Flush should never return WRITE_STATUS_BLOCKED_DATA_BUFFERED.
-  QUICHE_DCHECK(flush_result.write_result.status !=
-                WRITE_STATUS_BLOCKED_DATA_BUFFERED);
-
-  return flush_result;
-}
-
-WriteResult QuicBatchWriterBase::Flush() {
-  size_t num_buffered_packets = buffered_writes().size();
-  FlushImplResult flush_result = CheckedFlush();
-  QUIC_DVLOG(1) << "Externally flushed " << flush_result.num_packets_sent
-                << " out of " << num_buffered_packets
-                << " packets. WriteResult=" << flush_result.write_result;
-
-  if (IsWriteError(flush_result.write_result.status)) {
-    if (buffered_writes().size() > std::numeric_limits<uint16_t>::max()) {
-      flush_result.write_result.dropped_packets =
-          std::numeric_limits<uint16_t>::max();
-    } else {
-      flush_result.write_result.dropped_packets =
-          static_cast<uint16_t>(buffered_writes().size());
-    }
-    // Treat all errors as non-retryable fatal errors. Drop all buffered packets
-    // to avoid sending them and getting the same error again.
-    batch_buffer().Clear();
-  }
-
-  if (flush_result.write_result.status == WRITE_STATUS_BLOCKED) {
-    write_blocked_ = true;
-  }
-  return flush_result.write_result;
-}
-
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_batch_writer_base.h b/quic/core/batch_writer/quic_batch_writer_base.h
deleted file mode 100644
index bca8646..0000000
--- a/quic/core/batch_writer/quic_batch_writer_base.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
-
-#include <cstdint>
-#include "quic/core/batch_writer/quic_batch_writer_buffer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// QuicBatchWriterBase implements logic common to all derived batch writers,
-// including maintaining write blockage state and a skeleton implemention of
-// WritePacket().
-// A derived batch writer must override the FlushImpl() function to send all
-// buffered writes in a batch. It must also override the CanBatch() function
-// to control whether/when a WritePacket() call should flush.
-class QUIC_EXPORT_PRIVATE QuicBatchWriterBase : public QuicPacketWriter {
- public:
-  explicit QuicBatchWriterBase(
-      std::unique_ptr<QuicBatchWriterBuffer> batch_buffer);
-
-  // ATTENTION: If this write triggered a flush, and the flush failed, all
-  // buffered packets will be dropped to allow the next write to work. The
-  // number of dropped packets can be found in WriteResult.dropped_packets.
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-
-  bool IsWriteBlocked() const final { return write_blocked_; }
-
-  void SetWritable() final { write_blocked_ = false; }
-
-  absl::optional<int> MessageTooBigErrorCode() const override {
-    return EMSGSIZE;
-  }
-
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& /*peer_address*/) const final {
-    return kMaxOutgoingPacketSize;
-  }
-
-  bool SupportsReleaseTime() const override { return false; }
-
-  bool IsBatchMode() const final { return true; }
-
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& /*self_address*/,
-      const QuicSocketAddress& /*peer_address*/) final {
-    // No need to explicitly delete QuicBatchWriterBuffer.
-    return {batch_buffer_->GetNextWriteLocation(), nullptr};
-  }
-
-  WriteResult Flush() override;
-
- protected:
-  const QuicBatchWriterBuffer& batch_buffer() const { return *batch_buffer_; }
-  QuicBatchWriterBuffer& batch_buffer() { return *batch_buffer_; }
-
-  const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
-    return batch_buffer_->buffered_writes();
-  }
-
-  // Given the release delay in |options| and the state of |batch_buffer_|, get
-  // the absolute release time.
-  struct QUIC_NO_EXPORT ReleaseTime {
-    // The actual (absolute) release time.
-    uint64_t actual_release_time = 0;
-    // The difference between |actual_release_time| and ideal release time,
-    // which is (now + |options->release_time_delay|).
-    QuicTime::Delta release_time_offset = QuicTime::Delta::Zero();
-  };
-  virtual ReleaseTime GetReleaseTime(
-      const PerPacketOptions* /*options*/) const {
-    QUICHE_DCHECK(false)
-        << "Should not be called since release time is unsupported.";
-    return ReleaseTime{0, QuicTime::Delta::Zero()};
-  }
-
-  struct QUIC_EXPORT_PRIVATE CanBatchResult {
-    CanBatchResult(bool can_batch, bool must_flush)
-        : can_batch(can_batch), must_flush(must_flush) {}
-    // Whether this write can be batched with existing buffered writes.
-    bool can_batch;
-    // If |can_batch|, whether the caller must flush after this packet is
-    // buffered.
-    // Always true if not |can_batch|.
-    bool must_flush;
-  };
-
-  // Given the existing buffered writes(in buffered_writes()), whether a new
-  // write(in the arguments) can be batched.
-  virtual CanBatchResult CanBatch(const char* buffer,
-                                  size_t buf_len,
-                                  const QuicIpAddress& self_address,
-                                  const QuicSocketAddress& peer_address,
-                                  const PerPacketOptions* options,
-                                  uint64_t release_time) const = 0;
-
-  struct QUIC_EXPORT_PRIVATE FlushImplResult {
-    // The return value of the Flush() interface, which is:
-    // - WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered writes
-    //   were sent successfully.
-    // - WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR, if the batch write is
-    //   blocked or returned an error while sending. If a portion of buffered
-    //   writes were sent successfully, |FlushImplResult.num_packets_sent| and
-    //   |FlushImplResult.bytes_written| contain the number of successfully sent
-    //   packets and their total bytes.
-    WriteResult write_result;
-    int num_packets_sent;
-    // If write_result.status == WRITE_STATUS_OK, |bytes_written| will be equal
-    // to write_result.bytes_written. Otherwise |bytes_written| will be the
-    // number of bytes written before WRITE_BLOCK or WRITE_ERROR happened.
-    int bytes_written;
-  };
-
-  // Send all buffered writes(in buffered_writes()) in a batch.
-  // buffered_writes() is guaranteed to be non-empty when this function is
-  // called.
-  virtual FlushImplResult FlushImpl() = 0;
-
- private:
-  WriteResult InternalWritePacket(const char* buffer,
-                                  size_t buf_len,
-                                  const QuicIpAddress& self_address,
-                                  const QuicSocketAddress& peer_address,
-                                  PerPacketOptions* options);
-
-  // Calls FlushImpl() and check its post condition.
-  FlushImplResult CheckedFlush();
-
-  bool write_blocked_;
-  std::unique_ptr<QuicBatchWriterBuffer> batch_buffer_;
-};
-
-// QuicUdpBatchWriter is a batch writer backed by a UDP socket.
-class QUIC_EXPORT_PRIVATE QuicUdpBatchWriter : public QuicBatchWriterBase {
- public:
-  QuicUdpBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
-                     int fd)
-      : QuicBatchWriterBase(std::move(batch_buffer)), fd_(fd) {}
-
-  int fd() const { return fd_; }
-
- private:
-  const int fd_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
diff --git a/quic/core/batch_writer/quic_batch_writer_buffer.cc b/quic/core/batch_writer/quic_batch_writer_buffer.cc
deleted file mode 100644
index 8a450d7..0000000
--- a/quic/core/batch_writer/quic_batch_writer_buffer.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_batch_writer_buffer.h"
-
-#include <sstream>
-
-namespace quic {
-
-QuicBatchWriterBuffer::QuicBatchWriterBuffer() {
-  memset(buffer_, 0, sizeof(buffer_));
-}
-
-void QuicBatchWriterBuffer::Clear() {
-  buffered_writes_.clear();
-}
-
-std::string QuicBatchWriterBuffer::DebugString() const {
-  std::ostringstream os;
-  os << "{ buffer: " << static_cast<const void*>(buffer_)
-     << " buffer_end: " << static_cast<const void*>(buffer_end())
-     << " buffered_writes_.size(): " << buffered_writes_.size()
-     << " next_write_loc: " << static_cast<const void*>(GetNextWriteLocation())
-     << " SizeInUse: " << SizeInUse() << " }";
-  return os.str();
-}
-
-bool QuicBatchWriterBuffer::Invariants() const {
-  // Buffers in buffered_writes_ should not overlap, and collectively they
-  // should cover a continuous prefix of buffer_.
-  const char* next_buffer = buffer_;
-  for (auto iter = buffered_writes_.begin(); iter != buffered_writes_.end();
-       ++iter) {
-    if ((iter->buffer != next_buffer) ||
-        (iter->buffer + iter->buf_len > buffer_end())) {
-      return false;
-    }
-    next_buffer += iter->buf_len;
-  }
-
-  return static_cast<size_t>(next_buffer - buffer_) == SizeInUse();
-}
-
-char* QuicBatchWriterBuffer::GetNextWriteLocation() const {
-  const char* next_loc =
-      buffered_writes_.empty()
-          ? buffer_
-          : buffered_writes_.back().buffer + buffered_writes_.back().buf_len;
-  if (static_cast<size_t>(buffer_end() - next_loc) < kMaxOutgoingPacketSize) {
-    return nullptr;
-  }
-  return const_cast<char*>(next_loc);
-}
-
-QuicBatchWriterBuffer::PushResult QuicBatchWriterBuffer::PushBufferedWrite(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    const PerPacketOptions* options,
-    uint64_t release_time) {
-  QUICHE_DCHECK(Invariants());
-  QUICHE_DCHECK_LE(buf_len, kMaxOutgoingPacketSize);
-
-  PushResult result = {/*succeeded=*/false, /*buffer_copied=*/false};
-  char* next_write_location = GetNextWriteLocation();
-  if (next_write_location == nullptr) {
-    return result;
-  }
-
-  if (buffer != next_write_location) {
-    if (IsExternalBuffer(buffer, buf_len)) {
-      memcpy(next_write_location, buffer, buf_len);
-    } else if (IsInternalBuffer(buffer, buf_len)) {
-      memmove(next_write_location, buffer, buf_len);
-    } else {
-      QUIC_BUG(quic_bug_10831_1)
-          << "Buffer[" << static_cast<const void*>(buffer) << ", "
-          << static_cast<const void*>(buffer + buf_len)
-          << ") overlaps with internal buffer["
-          << static_cast<const void*>(buffer_) << ", "
-          << static_cast<const void*>(buffer_end()) << ")";
-      return result;
-    }
-    result.buffer_copied = true;
-  } else {
-    // In place push, do nothing.
-  }
-  buffered_writes_.emplace_back(
-      next_write_location, buf_len, self_address, peer_address,
-      options ? options->Clone() : std::unique_ptr<PerPacketOptions>(),
-      release_time);
-
-  QUICHE_DCHECK(Invariants());
-
-  result.succeeded = true;
-  return result;
-}
-
-void QuicBatchWriterBuffer::UndoLastPush() {
-  if (!buffered_writes_.empty()) {
-    buffered_writes_.pop_back();
-  }
-}
-
-QuicBatchWriterBuffer::PopResult QuicBatchWriterBuffer::PopBufferedWrite(
-    int32_t num_buffered_writes) {
-  QUICHE_DCHECK(Invariants());
-  QUICHE_DCHECK_GE(num_buffered_writes, 0);
-  QUICHE_DCHECK_LE(static_cast<size_t>(num_buffered_writes),
-                   buffered_writes_.size());
-
-  PopResult result = {/*num_buffers_popped=*/0,
-                      /*moved_remaining_buffers=*/false};
-
-  result.num_buffers_popped = std::max<int32_t>(num_buffered_writes, 0);
-  result.num_buffers_popped =
-      std::min<int32_t>(result.num_buffers_popped, buffered_writes_.size());
-  buffered_writes_.pop_front_n(result.num_buffers_popped);
-
-  if (!buffered_writes_.empty()) {
-    // If not all buffered writes are erased, the remaining ones will not cover
-    // a continuous prefix of buffer_. We'll fix it by moving the remaining
-    // buffers to the beginning of buffer_ and adjust the buffer pointers in all
-    // remaining buffered writes.
-    // This should happen very rarely, about once per write block.
-    result.moved_remaining_buffers = true;
-    const char* buffer_before_move = buffered_writes_.front().buffer;
-    size_t buffer_len_to_move = buffered_writes_.back().buffer +
-                                buffered_writes_.back().buf_len -
-                                buffer_before_move;
-    memmove(buffer_, buffer_before_move, buffer_len_to_move);
-
-    size_t distance_to_move = buffer_before_move - buffer_;
-    for (BufferedWrite& buffered_write : buffered_writes_) {
-      buffered_write.buffer -= distance_to_move;
-    }
-
-    QUICHE_DCHECK_EQ(buffer_, buffered_writes_.front().buffer);
-  }
-  QUICHE_DCHECK(Invariants());
-
-  return result;
-}
-
-size_t QuicBatchWriterBuffer::SizeInUse() const {
-  if (buffered_writes_.empty()) {
-    return 0;
-  }
-
-  return buffered_writes_.back().buffer + buffered_writes_.back().buf_len -
-         buffer_;
-}
-
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_batch_writer_buffer.h b/quic/core/batch_writer/quic_batch_writer_buffer.h
deleted file mode 100644
index 4faa3cb..0000000
--- a/quic/core/batch_writer/quic_batch_writer_buffer.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
-
-#include "absl/base/optimization.h"
-#include "quic/core/quic_linux_socket_utils.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// QuicBatchWriterBuffer manages an internal buffer to hold data from multiple
-// packets. Packet data are placed continuously within the internal buffer such
-// that they can be sent by a QuicGsoBatchWriter.
-// This class can also be used by a QuicBatchWriter which uses sendmmsg,
-// although it is not optimized for that use case.
-class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer {
- public:
-  QuicBatchWriterBuffer();
-
-  // Clear all buffered writes, but leave the internal buffer intact.
-  void Clear();
-
-  char* GetNextWriteLocation() const;
-
-  // Push a buffered write to the back.
-  struct QUIC_EXPORT_PRIVATE PushResult {
-    bool succeeded;
-    // True in one of the following cases:
-    // 1) The packet buffer is external and copied to the internal buffer, or
-    // 2) The packet buffer is from the internal buffer and moved within it.
-    //    This only happens if PopBufferedWrite is called in the middle of a
-    //    in-place push.
-    // Only valid if |succeeded| is true.
-    bool buffer_copied;
-  };
-
-  PushResult PushBufferedWrite(const char* buffer,
-                               size_t buf_len,
-                               const QuicIpAddress& self_address,
-                               const QuicSocketAddress& peer_address,
-                               const PerPacketOptions* options,
-                               uint64_t release_time);
-
-  void UndoLastPush();
-
-  // Pop |num_buffered_writes| buffered writes from the front.
-  // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
-  // before it is used.
-  struct QUIC_EXPORT_PRIVATE PopResult {
-    int32_t num_buffers_popped;
-    // True if after |num_buffers_popped| buffers are popped from front, the
-    // remaining buffers are moved to the beginning of the internal buffer.
-    // This should normally be false.
-    bool moved_remaining_buffers;
-  };
-  PopResult PopBufferedWrite(int32_t num_buffered_writes);
-
-  const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
-    return buffered_writes_;
-  }
-
-  bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
-    return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
-  }
-  bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
-    return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
-  }
-
-  // Number of bytes used in |buffer_|.
-  // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
-  size_t SizeInUse() const;
-
-  // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
-  // size of a GSO packet.
-  static const size_t kBufferSize = 64 * 1024;
-
-  std::string DebugString() const;
-
- protected:
-  // Whether the invariants of the buffer are upheld. For debug & test only.
-  bool Invariants() const;
-  const char* buffer_end() const { return buffer_ + sizeof(buffer_); }
-  ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize];
-  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
diff --git a/quic/core/batch_writer/quic_batch_writer_buffer_test.cc b/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
deleted file mode 100644
index a234e5e..0000000
--- a/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_batch_writer_buffer.h"
-#include <memory>
-#include <string>
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QUIC_EXPORT_PRIVATE TestQuicBatchWriterBuffer
-    : public QuicBatchWriterBuffer {
- public:
-  using QuicBatchWriterBuffer::buffer_;
-  using QuicBatchWriterBuffer::buffered_writes_;
-};
-
-static const size_t kBatchBufferSize = QuicBatchWriterBuffer::kBufferSize;
-
-class QuicBatchWriterBufferTest : public QuicTest {
- public:
-  QuicBatchWriterBufferTest() { SwitchToNewBuffer(); }
-
-  void SwitchToNewBuffer() {
-    batch_buffer_ = std::make_unique<TestQuicBatchWriterBuffer>();
-  }
-
-  // Fill packet_buffer_ with kMaxOutgoingPacketSize bytes of |c|s.
-  char* FillPacketBuffer(char c) {
-    return FillPacketBuffer(c, packet_buffer_, kMaxOutgoingPacketSize);
-  }
-
-  // Fill |packet_buffer| with kMaxOutgoingPacketSize bytes of |c|s.
-  char* FillPacketBuffer(char c, char* packet_buffer) {
-    return FillPacketBuffer(c, packet_buffer, kMaxOutgoingPacketSize);
-  }
-
-  // Fill |packet_buffer| with |buf_len| bytes of |c|s.
-  char* FillPacketBuffer(char c, char* packet_buffer, size_t buf_len) {
-    memset(packet_buffer, c, buf_len);
-    return packet_buffer;
-  }
-
-  void CheckBufferedWriteContent(int buffered_write_index,
-                                 char buffer_content,
-                                 size_t buf_len,
-                                 const QuicIpAddress& self_addr,
-                                 const QuicSocketAddress& peer_addr,
-                                 const PerPacketOptions* options) {
-    const BufferedWrite& buffered_write =
-        batch_buffer_->buffered_writes()[buffered_write_index];
-    EXPECT_EQ(buf_len, buffered_write.buf_len);
-    for (size_t i = 0; i < buf_len; ++i) {
-      EXPECT_EQ(buffer_content, buffered_write.buffer[i]);
-      if (buffer_content != buffered_write.buffer[i]) {
-        break;
-      }
-    }
-    EXPECT_EQ(self_addr, buffered_write.self_address);
-    EXPECT_EQ(peer_addr, buffered_write.peer_address);
-    if (options == nullptr) {
-      EXPECT_EQ(nullptr, buffered_write.options);
-    } else {
-      EXPECT_EQ(options->release_time_delay,
-                buffered_write.options->release_time_delay);
-    }
-  }
-
- protected:
-  std::unique_ptr<TestQuicBatchWriterBuffer> batch_buffer_;
-  QuicIpAddress self_addr_;
-  QuicSocketAddress peer_addr_;
-  uint64_t release_time_ = 0;
-  char packet_buffer_[kMaxOutgoingPacketSize];
-};
-
-class BufferSizeSequence {
- public:
-  explicit BufferSizeSequence(
-      std::vector<std::pair<std::vector<size_t>, size_t>> stages)
-      : stages_(std::move(stages)),
-        total_buf_len_(0),
-        stage_index_(0),
-        sequence_index_(0) {}
-
-  size_t Next() {
-    const std::vector<size_t>& seq = stages_[stage_index_].first;
-    size_t buf_len = seq[sequence_index_++ % seq.size()];
-    total_buf_len_ += buf_len;
-    if (stages_[stage_index_].second <= total_buf_len_) {
-      stage_index_ = std::min(stage_index_ + 1, stages_.size() - 1);
-    }
-    return buf_len;
-  }
-
- private:
-  const std::vector<std::pair<std::vector<size_t>, size_t>> stages_;
-  size_t total_buf_len_;
-  size_t stage_index_;
-  size_t sequence_index_;
-};
-
-// Test in-place pushes. A in-place push is a push with a buffer address that is
-// equal to the result of GetNextWriteLocation().
-TEST_F(QuicBatchWriterBufferTest, InPlacePushes) {
-  std::vector<BufferSizeSequence> buffer_size_sequences = {
-      // Push large writes until the buffer is near full, then switch to 1-byte
-      // writes. This covers the edge cases when detecting insufficient buffer.
-      BufferSizeSequence({{{1350}, kBatchBufferSize - 3000}, {{1}, 1e6}}),
-      // A sequence that looks real.
-      BufferSizeSequence({{{1, 39, 97, 150, 1350, 1350, 1350, 1350}, 1e6}}),
-  };
-
-  for (auto& buffer_size_sequence : buffer_size_sequences) {
-    SwitchToNewBuffer();
-    int64_t num_push_failures = 0;
-
-    while (batch_buffer_->SizeInUse() < kBatchBufferSize) {
-      size_t buf_len = buffer_size_sequence.Next();
-      const bool has_enough_space =
-          (kBatchBufferSize - batch_buffer_->SizeInUse() >=
-           kMaxOutgoingPacketSize);
-
-      char* buffer = batch_buffer_->GetNextWriteLocation();
-
-      if (has_enough_space) {
-        EXPECT_EQ(batch_buffer_->buffer_ + batch_buffer_->SizeInUse(), buffer);
-      } else {
-        EXPECT_EQ(nullptr, buffer);
-      }
-
-      SCOPED_TRACE(testing::Message()
-                   << "Before Push: buf_len=" << buf_len
-                   << ", has_enough_space=" << has_enough_space
-                   << ", batch_buffer=" << batch_buffer_->DebugString());
-
-      auto push_result = batch_buffer_->PushBufferedWrite(
-          buffer, buf_len, self_addr_, peer_addr_, nullptr, release_time_);
-      if (!push_result.succeeded) {
-        ++num_push_failures;
-      }
-      EXPECT_EQ(has_enough_space, push_result.succeeded);
-      EXPECT_FALSE(push_result.buffer_copied);
-      if (!has_enough_space) {
-        break;
-      }
-    }
-    // Expect one and only one failure from the final push operation.
-    EXPECT_EQ(1, num_push_failures);
-  }
-}
-
-// Test some in-place pushes mixed with pushes with external buffers.
-TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
-  // First, a in-place push.
-  char* buffer = batch_buffer_->GetNextWriteLocation();
-  auto push_result = batch_buffer_->PushBufferedWrite(
-      FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
-      peer_addr_, nullptr, release_time_);
-  EXPECT_TRUE(push_result.succeeded);
-  EXPECT_FALSE(push_result.buffer_copied);
-  CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
-                            peer_addr_, nullptr);
-
-  // Then a push with external buffer.
-  push_result = batch_buffer_->PushBufferedWrite(
-      FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
-      nullptr, release_time_);
-  EXPECT_TRUE(push_result.succeeded);
-  EXPECT_TRUE(push_result.buffer_copied);
-  CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
-                            peer_addr_, nullptr);
-
-  // Then another in-place push.
-  buffer = batch_buffer_->GetNextWriteLocation();
-  push_result = batch_buffer_->PushBufferedWrite(
-      FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
-      peer_addr_, nullptr, release_time_);
-  EXPECT_TRUE(push_result.succeeded);
-  EXPECT_FALSE(push_result.buffer_copied);
-  CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
-                            peer_addr_, nullptr);
-
-  // Then another push with external buffer.
-  push_result = batch_buffer_->PushBufferedWrite(
-      FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
-      nullptr, release_time_);
-  EXPECT_TRUE(push_result.succeeded);
-  EXPECT_TRUE(push_result.buffer_copied);
-  CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
-                            peer_addr_, nullptr);
-}
-
-TEST_F(QuicBatchWriterBufferTest, PopAll) {
-  const int kNumBufferedWrites = 10;
-  for (int i = 0; i < kNumBufferedWrites; ++i) {
-    EXPECT_TRUE(batch_buffer_
-                    ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
-                                        self_addr_, peer_addr_, nullptr,
-                                        release_time_)
-                    .succeeded);
-  }
-  EXPECT_EQ(kNumBufferedWrites,
-            static_cast<int>(batch_buffer_->buffered_writes().size()));
-
-  auto pop_result = batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
-  EXPECT_EQ(0u, batch_buffer_->buffered_writes().size());
-  EXPECT_EQ(kNumBufferedWrites, pop_result.num_buffers_popped);
-  EXPECT_FALSE(pop_result.moved_remaining_buffers);
-}
-
-TEST_F(QuicBatchWriterBufferTest, PopPartial) {
-  const int kNumBufferedWrites = 10;
-  for (int i = 0; i < kNumBufferedWrites; ++i) {
-    EXPECT_TRUE(batch_buffer_
-                    ->PushBufferedWrite(FillPacketBuffer('A' + i),
-                                        kDefaultMaxPacketSize - i, self_addr_,
-                                        peer_addr_, nullptr, release_time_)
-                    .succeeded);
-  }
-
-  for (size_t i = 0;
-       i < kNumBufferedWrites && !batch_buffer_->buffered_writes().empty();
-       ++i) {
-    const size_t size_before_pop = batch_buffer_->buffered_writes().size();
-    const size_t expect_size_after_pop =
-        size_before_pop < i ? 0 : size_before_pop - i;
-    batch_buffer_->PopBufferedWrite(i);
-    ASSERT_EQ(expect_size_after_pop, batch_buffer_->buffered_writes().size());
-    const char first_write_content =
-        'A' + kNumBufferedWrites - expect_size_after_pop;
-    const size_t first_write_len =
-        kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
-    for (size_t j = 0; j < expect_size_after_pop; ++j) {
-      CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
-                                self_addr_, peer_addr_, nullptr);
-    }
-  }
-}
-
-TEST_F(QuicBatchWriterBufferTest, InPlacePushWithPops) {
-  // First, a in-place push.
-  char* buffer = batch_buffer_->GetNextWriteLocation();
-  const size_t first_packet_len = 2;
-  auto push_result = batch_buffer_->PushBufferedWrite(
-      FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
-      self_addr_, peer_addr_, nullptr, release_time_);
-  EXPECT_TRUE(push_result.succeeded);
-  EXPECT_FALSE(push_result.buffer_copied);
-  CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
-                            nullptr);
-
-  // Simulate the case where the writer wants to do another in-place push, but
-  // can't do so because it can't be batched with the first buffer.
-  buffer = batch_buffer_->GetNextWriteLocation();
-  const size_t second_packet_len = 1350;
-
-  // Flush the first buffer.
-  auto pop_result = batch_buffer_->PopBufferedWrite(1);
-  EXPECT_EQ(1, pop_result.num_buffers_popped);
-  EXPECT_FALSE(pop_result.moved_remaining_buffers);
-
-  // Now the second push.
-  push_result = batch_buffer_->PushBufferedWrite(
-      FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
-      self_addr_, peer_addr_, nullptr, release_time_);
-  EXPECT_TRUE(push_result.succeeded);
-  EXPECT_TRUE(push_result.buffer_copied);
-  CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
-                            nullptr);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_batch_writer_test.cc b/quic/core/batch_writer/quic_batch_writer_test.cc
deleted file mode 100644
index 5f0dc9b..0000000
--- a/quic/core/batch_writer/quic_batch_writer_test.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_batch_writer_test.h"
-#include "quic/core/batch_writer/quic_gso_batch_writer.h"
-#include "quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicGsoBatchWriterIOTestDelegate
-    : public QuicUdpBatchWriterIOTestDelegate {
- public:
-  bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& params) override {
-    QuicUdpSocketApi socket_api;
-    int fd =
-        socket_api.Create(params.address_family,
-                          /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
-                          /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
-    if (fd < 0) {
-      QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
-      return false;  // Let the test fail rather than skip it.
-    }
-    const bool gso_not_supported =
-        QuicLinuxSocketUtils::GetUDPSegmentSize(fd) < 0;
-    socket_api.Destroy(fd);
-
-    if (gso_not_supported) {
-      QUIC_LOG(WARNING) << "Test skipped since GSO is not supported.";
-      return true;
-    }
-
-    QUIC_LOG(WARNING) << "OK: GSO is supported.";
-    return false;
-  }
-
-  void ResetWriter(int fd) override {
-    writer_ = std::make_unique<QuicGsoBatchWriter>(fd);
-  }
-
-  QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
-
- private:
-  std::unique_ptr<QuicGsoBatchWriter> writer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    QuicGsoBatchWriterTest,
-    QuicUdpBatchWriterIOTest,
-    testing::ValuesIn(
-        MakeQuicBatchWriterTestParams<QuicGsoBatchWriterIOTestDelegate>()));
-
-class QuicSendmmsgBatchWriterIOTestDelegate
-    : public QuicUdpBatchWriterIOTestDelegate {
- public:
-  void ResetWriter(int fd) override {
-    writer_ = std::make_unique<QuicSendmmsgBatchWriter>(
-        std::make_unique<QuicBatchWriterBuffer>(), fd);
-  }
-
-  QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
-
- private:
-  std::unique_ptr<QuicSendmmsgBatchWriter> writer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    QuicSendmmsgBatchWriterTest,
-    QuicUdpBatchWriterIOTest,
-    testing::ValuesIn(MakeQuicBatchWriterTestParams<
-                      QuicSendmmsgBatchWriterIOTestDelegate>()));
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_batch_writer_test.h b/quic/core/batch_writer/quic_batch_writer_test.h
deleted file mode 100644
index e14040f..0000000
--- a/quic/core/batch_writer/quic_batch_writer_test.h
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
-
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <cstddef>
-#include <iostream>
-#include <utility>
-
-#include "absl/base/optimization.h"
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-static bool IsAddressFamilySupported(int address_family) {
-  static auto check_function = [](int address_family) {
-    int fd = socket(address_family, SOCK_STREAM, 0);
-    if (fd < 0) {
-      QUIC_LOG(ERROR) << "address_family not supported: " << address_family
-                      << ", error: " << strerror(errno);
-      EXPECT_EQ(EAFNOSUPPORT, errno);
-      return false;
-    }
-    close(fd);
-    return true;
-  };
-
-  if (address_family == AF_INET) {
-    static const bool ipv4_supported = check_function(AF_INET);
-    return ipv4_supported;
-  }
-
-  static const bool ipv6_supported = check_function(AF_INET6);
-  return ipv6_supported;
-}
-
-static bool CreateSocket(int family, QuicSocketAddress* address, int* fd) {
-  if (family == AF_INET) {
-    *address = QuicSocketAddress(QuicIpAddress::Loopback4(), 0);
-  } else {
-    QUICHE_DCHECK_EQ(family, AF_INET6);
-    *address = QuicSocketAddress(QuicIpAddress::Loopback6(), 0);
-  }
-
-  QuicUdpSocketApi socket_api;
-  *fd = socket_api.Create(family,
-                          /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
-                          /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
-  if (*fd < 0) {
-    QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
-    return false;
-  }
-  socket_api.EnableDroppedPacketCount(*fd);
-
-  if (!socket_api.Bind(*fd, *address)) {
-    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
-    return false;
-  }
-
-  if (address->FromSocket(*fd) != 0) {
-    QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
-                    << strerror(errno);
-    return false;
-  }
-  return true;
-}
-
-struct QuicUdpBatchWriterIOTestParams;
-class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestDelegate {
- public:
-  virtual ~QuicUdpBatchWriterIOTestDelegate() {}
-
-  virtual bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& /*params*/) {
-    return false;
-  }
-
-  virtual void ResetWriter(int fd) = 0;
-
-  virtual QuicUdpBatchWriter* GetWriter() = 0;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestParams {
-  // Use shared_ptr because gtest makes copies of test params.
-  std::shared_ptr<QuicUdpBatchWriterIOTestDelegate> delegate;
-  int address_family;
-  int data_size;
-  int packet_size;
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicUdpBatchWriterIOTestParams& p) {
-    os << "{ address_family: " << p.address_family
-       << " data_size: " << p.data_size << " packet_size: " << p.packet_size
-       << " }";
-    return os;
-  }
-};
-
-template <class QuicUdpBatchWriterIOTestDelegateT>
-static std::vector<QuicUdpBatchWriterIOTestParams>
-MakeQuicBatchWriterTestParams() {
-  static_assert(std::is_base_of<QuicUdpBatchWriterIOTestDelegate,
-                                QuicUdpBatchWriterIOTestDelegateT>::value,
-                "<QuicUdpBatchWriterIOTestDelegateT> needs to derive from "
-                "QuicUdpBatchWriterIOTestDelegate");
-
-  std::vector<QuicUdpBatchWriterIOTestParams> params;
-  for (int address_family : {AF_INET, AF_INET6}) {
-    for (int data_size : {1, 150, 1500, 15000, 64000, 512 * 1024}) {
-      for (int packet_size : {1, 50, 1350, 1452}) {
-        if (packet_size <= data_size && (data_size / packet_size < 2000)) {
-          params.push_back(
-              {std::make_unique<QuicUdpBatchWriterIOTestDelegateT>(),
-               address_family, data_size, packet_size});
-        }
-      }
-    }
-  }
-  return params;
-}
-
-// QuicUdpBatchWriterIOTest is a value parameterized test fixture that can be
-// used by tests of derived classes of QuicUdpBatchWriter, to verify basic
-// packet IO capabilities.
-class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTest
-    : public QuicTestWithParam<QuicUdpBatchWriterIOTestParams> {
- protected:
-  QuicUdpBatchWriterIOTest()
-      : address_family_(GetParam().address_family),
-        data_size_(GetParam().data_size),
-        packet_size_(GetParam().packet_size),
-        self_socket_(-1),
-        peer_socket_(-1) {
-    QUIC_LOG(INFO) << "QuicUdpBatchWriterIOTestParams: " << GetParam();
-    EXPECT_TRUE(address_family_ == AF_INET || address_family_ == AF_INET6);
-    EXPECT_LE(packet_size_, data_size_);
-    EXPECT_LE(packet_size_, sizeof(packet_buffer_));
-  }
-
-  ~QuicUdpBatchWriterIOTest() override {
-    if (self_socket_ > 0) {
-      close(self_socket_);
-    }
-    if (peer_socket_ > 0) {
-      close(peer_socket_);
-    }
-  }
-
-  // Whether this test should be skipped. A test is passed if skipped.
-  // A test can be skipped when e.g. it exercises a kernel feature that is not
-  // available on the system.
-  bool ShouldSkip() {
-    if (!IsAddressFamilySupported(address_family_)) {
-      QUIC_LOG(WARNING)
-          << "Test skipped since address_family is not supported.";
-      return true;
-    }
-
-    return GetParam().delegate->ShouldSkip(GetParam());
-  }
-
-  // Initialize a test.
-  // To fail the test in Initialize, use ASSERT_xx macros.
-  void Initialize() {
-    ASSERT_TRUE(CreateSocket(address_family_, &self_address_, &self_socket_));
-    ASSERT_TRUE(CreateSocket(address_family_, &peer_address_, &peer_socket_));
-
-    QUIC_DLOG(INFO) << "Self address: " << self_address_.ToString() << ", fd "
-                    << self_socket_;
-    QUIC_DLOG(INFO) << "Peer address: " << peer_address_.ToString() << ", fd "
-                    << peer_socket_;
-    GetParam().delegate->ResetWriter(self_socket_);
-  }
-
-  QuicUdpBatchWriter* GetWriter() { return GetParam().delegate->GetWriter(); }
-
-  void ValidateWrite() {
-    char this_packet_content = '\0';
-    int this_packet_size;
-    int num_writes = 0;
-    size_t bytes_flushed = 0;
-    WriteResult result;
-
-    for (size_t bytes_sent = 0; bytes_sent < data_size_;
-         bytes_sent += this_packet_size, ++this_packet_content) {
-      this_packet_size = std::min(packet_size_, data_size_ - bytes_sent);
-      memset(&packet_buffer_[0], this_packet_content, this_packet_size);
-
-      result = GetWriter()->WritePacket(&packet_buffer_[0], this_packet_size,
-                                        self_address_.host(), peer_address_,
-                                        nullptr);
-
-      ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
-      bytes_flushed += result.bytes_written;
-      ++num_writes;
-
-      QUIC_DVLOG(1) << "[write #" << num_writes
-                    << "] this_packet_size: " << this_packet_size
-                    << ", total_bytes_sent: " << bytes_sent + this_packet_size
-                    << ", bytes_flushed: " << bytes_flushed
-                    << ", pkt content:" << std::hex << int(this_packet_content);
-    }
-
-    result = GetWriter()->Flush();
-    ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
-    bytes_flushed += result.bytes_written;
-    ASSERT_EQ(data_size_, bytes_flushed);
-
-    QUIC_LOG(INFO) << "Sent " << data_size_ << " bytes in " << num_writes
-                   << " writes.";
-  }
-
-  void ValidateRead() {
-    char this_packet_content = '\0';
-    int this_packet_size;
-    int packets_received = 0;
-    for (size_t bytes_received = 0; bytes_received < data_size_;
-         bytes_received += this_packet_size, ++this_packet_content) {
-      this_packet_size = std::min(packet_size_, data_size_ - bytes_received);
-      SCOPED_TRACE(testing::Message()
-                   << "Before ReadPacket: bytes_received=" << bytes_received
-                   << ", this_packet_size=" << this_packet_size);
-
-      QuicUdpSocketApi::ReadPacketResult result;
-      result.packet_buffer = {&packet_buffer_[0], sizeof(packet_buffer_)};
-      result.control_buffer = {&control_buffer_[0], sizeof(control_buffer_)};
-      QuicUdpSocketApi().ReadPacket(
-          peer_socket_,
-          quic::BitMask64(QuicUdpPacketInfoBit::V4_SELF_IP,
-                          QuicUdpPacketInfoBit::V6_SELF_IP,
-                          QuicUdpPacketInfoBit::PEER_ADDRESS),
-          &result);
-      ASSERT_TRUE(result.ok);
-      ASSERT_TRUE(
-          result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
-      QuicSocketAddress read_peer_address = result.packet_info.peer_address();
-      QuicIpAddress read_self_address = read_peer_address.host().IsIPv6()
-                                            ? result.packet_info.self_v6_ip()
-                                            : result.packet_info.self_v4_ip();
-
-      EXPECT_EQ(read_self_address, peer_address_.host());
-      EXPECT_EQ(read_peer_address, self_address_);
-      for (int i = 0; i < this_packet_size; ++i) {
-        EXPECT_EQ(this_packet_content, packet_buffer_[i]);
-      }
-      packets_received += this_packet_size;
-    }
-
-    QUIC_LOG(INFO) << "Received " << data_size_ << " bytes in "
-                   << packets_received << " packets.";
-  }
-
-  QuicSocketAddress self_address_;
-  QuicSocketAddress peer_address_;
-  ABSL_CACHELINE_ALIGNED char packet_buffer_[1500];
-  ABSL_CACHELINE_ALIGNED char
-      control_buffer_[kDefaultUdpPacketControlBufferSize];
-  int address_family_;
-  const size_t data_size_;
-  const size_t packet_size_;
-  int self_socket_;
-  int peer_socket_;
-};
-
-TEST_P(QuicUdpBatchWriterIOTest, WriteAndRead) {
-  if (ShouldSkip()) {
-    return;
-  }
-
-  Initialize();
-
-  ValidateWrite();
-  ValidateRead();
-}
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
diff --git a/quic/core/batch_writer/quic_gso_batch_writer.cc b/quic/core/batch_writer/quic_gso_batch_writer.cc
deleted file mode 100644
index fa26516..0000000
--- a/quic/core/batch_writer/quic_gso_batch_writer.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_gso_batch_writer.h"
-
-#include <time.h>
-#include <ctime>
-
-#include "quic/core/quic_linux_socket_utils.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-namespace quic {
-
-// static
-std::unique_ptr<QuicBatchWriterBuffer>
-QuicGsoBatchWriter::CreateBatchWriterBuffer() {
-  return std::make_unique<QuicBatchWriterBuffer>();
-}
-
-QuicGsoBatchWriter::QuicGsoBatchWriter(int fd)
-    : QuicGsoBatchWriter(fd, CLOCK_MONOTONIC) {}
-
-QuicGsoBatchWriter::QuicGsoBatchWriter(int fd,
-                                       clockid_t clockid_for_release_time)
-    : QuicUdpBatchWriter(CreateBatchWriterBuffer(), fd),
-      clockid_for_release_time_(clockid_for_release_time),
-      supports_release_time_(
-          GetQuicRestartFlag(quic_support_release_time_for_gso) &&
-          QuicLinuxSocketUtils::EnableReleaseTime(fd,
-                                                  clockid_for_release_time)) {
-  if (supports_release_time_) {
-    QUIC_RESTART_FLAG_COUNT(quic_support_release_time_for_gso);
-    QUIC_LOG_FIRST_N(INFO, 5) << "Release time is enabled.";
-  } else {
-    QUIC_LOG_FIRST_N(INFO, 5) << "Release time is not enabled.";
-  }
-}
-
-QuicGsoBatchWriter::QuicGsoBatchWriter(
-    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
-    int fd,
-    clockid_t clockid_for_release_time,
-    ReleaseTimeForceEnabler /*enabler*/)
-    : QuicUdpBatchWriter(std::move(batch_buffer), fd),
-      clockid_for_release_time_(clockid_for_release_time),
-      supports_release_time_(true) {
-  QUIC_DLOG(INFO) << "Release time forcefully enabled.";
-}
-
-QuicGsoBatchWriter::CanBatchResult QuicGsoBatchWriter::CanBatch(
-    const char* /*buffer*/,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    const PerPacketOptions* options,
-    uint64_t release_time) const {
-  // If there is nothing buffered already, this write will be included in this
-  // batch.
-  if (buffered_writes().empty()) {
-    return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
-  }
-
-  // The new write can be batched if all of the following are true:
-  // [0] The total number of the GSO segments(one write=one segment, including
-  //     the new write) must not exceed |max_segments|.
-  // [1] It has the same source and destination addresses as already buffered
-  //     writes.
-  // [2] It won't cause this batch to exceed kMaxGsoPacketSize.
-  // [3] Already buffered writes all have the same length.
-  // [4] Length of already buffered writes must >= length of the new write.
-  // [5] The new packet can be released without delay, or it has the same
-  //     release time as buffered writes.
-  const BufferedWrite& first = buffered_writes().front();
-  const BufferedWrite& last = buffered_writes().back();
-  // Whether this packet can be sent without delay, regardless of release time.
-  const bool can_burst = !SupportsReleaseTime() || !options ||
-                         options->release_time_delay.IsZero() ||
-                         options->allow_burst;
-  size_t max_segments = MaxSegments(first.buf_len);
-  bool can_batch =
-      buffered_writes().size() < max_segments &&                    // [0]
-      last.self_address == self_address &&                          // [1]
-      last.peer_address == peer_address &&                          // [1]
-      batch_buffer().SizeInUse() + buf_len <= kMaxGsoPacketSize &&  // [2]
-      first.buf_len == last.buf_len &&                              // [3]
-      first.buf_len >= buf_len &&                                   // [4]
-      (can_burst || first.release_time == release_time);            // [5]
-
-  // A flush is required if any of the following is true:
-  // [a] The new write can't be batched.
-  // [b] Length of the new write is different from the length of already
-  //     buffered writes.
-  // [c] The total number of the GSO segments, including the new write, reaches
-  //     |max_segments|.
-  bool must_flush = (!can_batch) ||                                  // [a]
-                    (last.buf_len != buf_len) ||                     // [b]
-                    (buffered_writes().size() + 1 == max_segments);  // [c]
-  return CanBatchResult(can_batch, must_flush);
-}
-
-QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime(
-    const PerPacketOptions* options) const {
-  QUICHE_DCHECK(SupportsReleaseTime());
-
-  if (options == nullptr) {
-    return {0, QuicTime::Delta::Zero()};
-  }
-
-  const uint64_t now = NowInNanosForReleaseTime();
-  const uint64_t ideal_release_time =
-      now + options->release_time_delay.ToMicroseconds() * 1000;
-
-  if ((options->release_time_delay.IsZero() || options->allow_burst) &&
-      !buffered_writes().empty() &&
-      // If release time of buffered packets is in the past, flush buffered
-      // packets and buffer this packet at the ideal release time.
-      (buffered_writes().back().release_time >= now)) {
-    // Send as soon as possible, but no sooner than the last buffered packet.
-    const uint64_t actual_release_time = buffered_writes().back().release_time;
-
-    const int64_t offset_ns = actual_release_time - ideal_release_time;
-    ReleaseTime result{actual_release_time,
-                       QuicTime::Delta::FromMicroseconds(offset_ns / 1000)};
-
-    QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time
-                  << ", actual_release_time:" << actual_release_time
-                  << ", offset:" << result.release_time_offset;
-    return result;
-  }
-
-  // Send according to the release time delay.
-  return {ideal_release_time, QuicTime::Delta::Zero()};
-}
-
-uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const {
-  struct timespec ts;
-
-  if (clock_gettime(clockid_for_release_time_, &ts) != 0) {
-    return 0;
-  }
-
-  return ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
-}
-
-// static
-void QuicGsoBatchWriter::BuildCmsg(QuicMsgHdr* hdr,
-                                   const QuicIpAddress& self_address,
-                                   uint16_t gso_size,
-                                   uint64_t release_time) {
-  hdr->SetIpInNextCmsg(self_address);
-  if (gso_size > 0) {
-    *hdr->GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = gso_size;
-  }
-  if (release_time != 0) {
-    *hdr->GetNextCmsgData<uint64_t>(SOL_SOCKET, SO_TXTIME) = release_time;
-  }
-}
-
-QuicGsoBatchWriter::FlushImplResult QuicGsoBatchWriter::FlushImpl() {
-  return InternalFlushImpl<kCmsgSpace>(BuildCmsg);
-}
-
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_gso_batch_writer.h b/quic/core/batch_writer/quic_gso_batch_writer.h
deleted file mode 100644
index f87e9f8..0000000
--- a/quic/core/batch_writer/quic_gso_batch_writer.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
-
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-
-namespace quic {
-
-// QuicGsoBatchWriter sends QUIC packets in batches, using UDP socket's generic
-// segmentation offload(GSO) capability.
-class QUIC_EXPORT_PRIVATE QuicGsoBatchWriter : public QuicUdpBatchWriter {
- public:
-  explicit QuicGsoBatchWriter(int fd);
-
-  // |clockid_for_release_time|: FQ qdisc requires CLOCK_MONOTONIC, EDF requires
-  // CLOCK_TAI.
-  QuicGsoBatchWriter(int fd, clockid_t clockid_for_release_time);
-
-  bool SupportsReleaseTime() const final { return supports_release_time_; }
-
-  CanBatchResult CanBatch(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          const PerPacketOptions* options,
-                          uint64_t release_time) const override;
-
-  FlushImplResult FlushImpl() override;
-
- protected:
-  // Test only constructor to forcefully enable release time.
-  struct QUIC_EXPORT_PRIVATE ReleaseTimeForceEnabler {};
-  QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
-                     int fd,
-                     clockid_t clockid_for_release_time,
-                     ReleaseTimeForceEnabler enabler);
-
-  ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override;
-
-  // Get the current time in nanos from |clockid_for_release_time_|.
-  virtual uint64_t NowInNanosForReleaseTime() const;
-
-  static size_t MaxSegments(size_t gso_size) {
-    // Max segments should be the min of UDP_MAX_SEGMENTS(64) and
-    // (((64KB - sizeof(ip hdr) - sizeof(udp hdr)) / MSS) + 1), in the typical
-    // case of IPv6 packets with 1500-byte MTU, the result is
-    //         ((64KB - 40 - 8) / (1500 - 48)) + 1 = 46
-    // However, due a kernel bug, the limit is much lower for tiny gso_sizes.
-    return gso_size <= 2 ? 16 : 45;
-  }
-
-  static const int kCmsgSpace =
-      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize + kCmsgSpaceForTxTime;
-  static void BuildCmsg(QuicMsgHdr* hdr,
-                        const QuicIpAddress& self_address,
-                        uint16_t gso_size,
-                        uint64_t release_time);
-
-  template <size_t CmsgSpace, typename CmsgBuilderT>
-  FlushImplResult InternalFlushImpl(CmsgBuilderT cmsg_builder) {
-    QUICHE_DCHECK(!IsWriteBlocked());
-    QUICHE_DCHECK(!buffered_writes().empty());
-
-    FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
-                              /*num_packets_sent=*/0, /*bytes_written=*/0};
-    WriteResult& write_result = result.write_result;
-
-    int total_bytes = batch_buffer().SizeInUse();
-    const BufferedWrite& first = buffered_writes().front();
-    char cbuf[CmsgSpace];
-    QuicMsgHdr hdr(first.buffer, total_bytes, first.peer_address, cbuf,
-                   sizeof(cbuf));
-
-    uint16_t gso_size = buffered_writes().size() > 1 ? first.buf_len : 0;
-    cmsg_builder(&hdr, first.self_address, gso_size, first.release_time);
-
-    write_result = QuicLinuxSocketUtils::WritePacket(fd(), hdr);
-    QUIC_DVLOG(1) << "Write GSO packet result: " << write_result
-                  << ", fd: " << fd()
-                  << ", self_address: " << first.self_address.ToString()
-                  << ", peer_address: " << first.peer_address.ToString()
-                  << ", num_segments: " << buffered_writes().size()
-                  << ", total_bytes: " << total_bytes
-                  << ", gso_size: " << gso_size
-                  << ", release_time: " << first.release_time;
-
-    // All segments in a GSO packet share the same fate - if the write failed,
-    // none of them are sent, and it's not needed to call PopBufferedWrite().
-    if (write_result.status != WRITE_STATUS_OK) {
-      return result;
-    }
-
-    result.num_packets_sent = buffered_writes().size();
-
-    write_result.bytes_written = total_bytes;
-    result.bytes_written = total_bytes;
-
-    batch_buffer().PopBufferedWrite(buffered_writes().size());
-
-    QUIC_BUG_IF(quic_bug_12544_1, !buffered_writes().empty())
-        << "All packets should have been written on a successful return";
-    return result;
-  }
-
- private:
-  static std::unique_ptr<QuicBatchWriterBuffer> CreateBatchWriterBuffer();
-
-  const clockid_t clockid_for_release_time_;
-  const bool supports_release_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
diff --git a/quic/core/batch_writer/quic_gso_batch_writer_test.cc b/quic/core/batch_writer/quic_gso_batch_writer_test.cc
deleted file mode 100644
index 4aab198..0000000
--- a/quic/core/batch_writer/quic_gso_batch_writer_test.cc
+++ /dev/null
@@ -1,472 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_gso_batch_writer.h"
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <utility>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_mock_syscall_wrapper.h"
-
-using testing::_;
-using testing::Invoke;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-size_t PacketLength(const msghdr* msg) {
-  size_t length = 0;
-  for (size_t i = 0; i < msg->msg_iovlen; ++i) {
-    length += msg->msg_iov[i].iov_len;
-  }
-  return length;
-}
-
-uint64_t MillisToNanos(uint64_t milliseconds) {
-  return milliseconds * 1000000;
-}
-
-class QUIC_EXPORT_PRIVATE TestQuicGsoBatchWriter : public QuicGsoBatchWriter {
- public:
-  using QuicGsoBatchWriter::batch_buffer;
-  using QuicGsoBatchWriter::buffered_writes;
-  using QuicGsoBatchWriter::CanBatch;
-  using QuicGsoBatchWriter::CanBatchResult;
-  using QuicGsoBatchWriter::GetReleaseTime;
-  using QuicGsoBatchWriter::MaxSegments;
-  using QuicGsoBatchWriter::QuicGsoBatchWriter;
-  using QuicGsoBatchWriter::ReleaseTime;
-
-  static std::unique_ptr<TestQuicGsoBatchWriter>
-  NewInstanceWithReleaseTimeSupport() {
-    return std::unique_ptr<TestQuicGsoBatchWriter>(new TestQuicGsoBatchWriter(
-        std::make_unique<QuicBatchWriterBuffer>(),
-        /*fd=*/-1, CLOCK_MONOTONIC, ReleaseTimeForceEnabler()));
-  }
-
-  uint64_t NowInNanosForReleaseTime() const override {
-    return MillisToNanos(forced_release_time_ms_);
-  }
-
-  void ForceReleaseTimeMs(uint64_t forced_release_time_ms) {
-    forced_release_time_ms_ = forced_release_time_ms;
-  }
-
- private:
-  uint64_t forced_release_time_ms_ = 1;
-};
-
-struct QUIC_EXPORT_PRIVATE TestPerPacketOptions : public PerPacketOptions {
-  std::unique_ptr<quic::PerPacketOptions> Clone() const override {
-    return std::make_unique<TestPerPacketOptions>(*this);
-  }
-};
-
-// TestBufferedWrite is a copy-constructible BufferedWrite.
-struct QUIC_EXPORT_PRIVATE TestBufferedWrite : public BufferedWrite {
-  using BufferedWrite::BufferedWrite;
-  TestBufferedWrite(const TestBufferedWrite& other)
-      : BufferedWrite(other.buffer,
-                      other.buf_len,
-                      other.self_address,
-                      other.peer_address,
-                      other.options ? other.options->Clone()
-                                    : std::unique_ptr<PerPacketOptions>(),
-                      other.release_time) {}
-};
-
-// Pointed to by all instances of |BatchCriteriaTestData|. Content not used.
-static char unused_packet_buffer[kMaxOutgoingPacketSize];
-
-struct QUIC_EXPORT_PRIVATE BatchCriteriaTestData {
-  BatchCriteriaTestData(size_t buf_len,
-                        const QuicIpAddress& self_address,
-                        const QuicSocketAddress& peer_address,
-                        uint64_t release_time,
-                        bool can_batch,
-                        bool must_flush)
-      : buffered_write(unused_packet_buffer,
-                       buf_len,
-                       self_address,
-                       peer_address,
-                       std::unique_ptr<PerPacketOptions>(),
-                       release_time),
-        can_batch(can_batch),
-        must_flush(must_flush) {}
-
-  TestBufferedWrite buffered_write;
-  // Expected value of CanBatchResult.can_batch when batching |buffered_write|.
-  bool can_batch;
-  // Expected value of CanBatchResult.must_flush when batching |buffered_write|.
-  bool must_flush;
-};
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeDecrease() {
-  const QuicIpAddress self_addr;
-  const QuicSocketAddress peer_addr;
-  std::vector<BatchCriteriaTestData> test_data_table = {
-      // clang-format off
-  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {39,       self_addr,  peer_addr,  0,      true,           true},
-    {39,       self_addr,  peer_addr,  0,      false,          true},
-    {1350,     self_addr,  peer_addr,  0,      false,          true},
-      // clang-format on
-  };
-  return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeIncrease() {
-  const QuicIpAddress self_addr;
-  const QuicSocketAddress peer_addr;
-  std::vector<BatchCriteriaTestData> test_data_table = {
-      // clang-format off
-  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1351,     self_addr,  peer_addr,  0,      false,          true},
-      // clang-format on
-  };
-  return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_AddressChange() {
-  const QuicIpAddress self_addr1 = QuicIpAddress::Loopback4();
-  const QuicIpAddress self_addr2 = QuicIpAddress::Loopback6();
-  const QuicSocketAddress peer_addr1(self_addr1, 666);
-  const QuicSocketAddress peer_addr2(self_addr1, 777);
-  const QuicSocketAddress peer_addr3(self_addr2, 666);
-  const QuicSocketAddress peer_addr4(self_addr2, 777);
-  std::vector<BatchCriteriaTestData> test_data_table = {
-      // clang-format off
-  // buf_len   self_addr   peer_addr    t_rel  can_batch       must_flush
-    {1350,     self_addr1, peer_addr1,  0,     true,           false},
-    {1350,     self_addr1, peer_addr1,  0,     true,           false},
-    {1350,     self_addr1, peer_addr1,  0,     true,           false},
-    {1350,     self_addr2, peer_addr1,  0,     false,          true},
-    {1350,     self_addr1, peer_addr2,  0,     false,          true},
-    {1350,     self_addr1, peer_addr3,  0,     false,          true},
-    {1350,     self_addr1, peer_addr4,  0,     false,          true},
-    {1350,     self_addr1, peer_addr4,  0,     false,          true},
-      // clang-format on
-  };
-  return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime1() {
-  const QuicIpAddress self_addr;
-  const QuicSocketAddress peer_addr;
-  std::vector<BatchCriteriaTestData> test_data_table = {
-      // clang-format off
-  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
-    {1350,     self_addr,  peer_addr,  5,      true,           false},
-    {1350,     self_addr,  peer_addr,  5,      true,           false},
-    {1350,     self_addr,  peer_addr,  5,      true,           false},
-    {1350,     self_addr,  peer_addr,  9,      false,          true},
-      // clang-format on
-  };
-  return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime2() {
-  const QuicIpAddress self_addr;
-  const QuicSocketAddress peer_addr;
-  std::vector<BatchCriteriaTestData> test_data_table = {
-      // clang-format off
-  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  0,      true,           false},
-    {1350,     self_addr,  peer_addr,  9,      false,          true},
-      // clang-format on
-  };
-  return test_data_table;
-}
-
-std::vector<BatchCriteriaTestData> BatchCriteriaTestData_MaxSegments(
-    size_t gso_size) {
-  const QuicIpAddress self_addr;
-  const QuicSocketAddress peer_addr;
-  std::vector<BatchCriteriaTestData> test_data_table;
-  size_t max_segments = TestQuicGsoBatchWriter::MaxSegments(gso_size);
-  for (size_t i = 0; i < max_segments; ++i) {
-    bool is_last_in_batch = (i + 1 == max_segments);
-    test_data_table.push_back({gso_size, self_addr, peer_addr,
-                               /*release_time=*/0, true, is_last_in_batch});
-  }
-  test_data_table.push_back(
-      {gso_size, self_addr, peer_addr, /*release_time=*/0, false, true});
-  return test_data_table;
-}
-
-class QuicGsoBatchWriterTest : public QuicTest {
- protected:
-  WriteResult WritePacket(QuicGsoBatchWriter* writer, size_t packet_size) {
-    return writer->WritePacket(&packet_buffer_[0], packet_size, self_address_,
-                               peer_address_, nullptr);
-  }
-
-  WriteResult WritePacketWithOptions(QuicGsoBatchWriter* writer,
-                                     PerPacketOptions* options) {
-    return writer->WritePacket(&packet_buffer_[0], 1350, self_address_,
-                               peer_address_, options);
-  }
-
-  QuicIpAddress self_address_ = QuicIpAddress::Any4();
-  QuicSocketAddress peer_address_{QuicIpAddress::Any4(), 443};
-  char packet_buffer_[1500];
-  StrictMock<MockQuicSyscallWrapper> mock_syscalls_;
-  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
-};
-
-TEST_F(QuicGsoBatchWriterTest, BatchCriteria) {
-  std::unique_ptr<TestQuicGsoBatchWriter> writer;
-
-  std::vector<std::vector<BatchCriteriaTestData>> test_data_tables;
-  test_data_tables.emplace_back(BatchCriteriaTestData_SizeDecrease());
-  test_data_tables.emplace_back(BatchCriteriaTestData_SizeIncrease());
-  test_data_tables.emplace_back(BatchCriteriaTestData_AddressChange());
-  test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime1());
-  test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime2());
-  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1));
-  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(2));
-  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1350));
-
-  for (size_t i = 0; i < test_data_tables.size(); ++i) {
-    writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
-
-    const auto& test_data_table = test_data_tables[i];
-    for (size_t j = 0; j < test_data_table.size(); ++j) {
-      const BatchCriteriaTestData& test_data = test_data_table[j];
-      SCOPED_TRACE(testing::Message() << "i=" << i << ", j=" << j);
-      TestPerPacketOptions options;
-      options.release_time_delay = QuicTime::Delta::FromMicroseconds(
-          test_data.buffered_write.release_time);
-      TestQuicGsoBatchWriter::CanBatchResult result = writer->CanBatch(
-          test_data.buffered_write.buffer, test_data.buffered_write.buf_len,
-          test_data.buffered_write.self_address,
-          test_data.buffered_write.peer_address, &options,
-          test_data.buffered_write.release_time);
-
-      ASSERT_EQ(test_data.can_batch, result.can_batch);
-      ASSERT_EQ(test_data.must_flush, result.must_flush);
-
-      if (result.can_batch) {
-        ASSERT_TRUE(writer->batch_buffer()
-                        .PushBufferedWrite(
-                            test_data.buffered_write.buffer,
-                            test_data.buffered_write.buf_len,
-                            test_data.buffered_write.self_address,
-                            test_data.buffered_write.peer_address, &options,
-                            test_data.buffered_write.release_time)
-                        .succeeded);
-      }
-    }
-  }
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteSuccess) {
-  TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 1000));
-
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(1100u, PacketLength(msg));
-        return 1100;
-      }));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 1100), WritePacket(&writer, 100));
-  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
-  ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteBlockDataNotBuffered) {
-  TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(200u, PacketLength(msg));
-        errno = EWOULDBLOCK;
-        return -1;
-      }));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
-            WritePacket(&writer, 150));
-  ASSERT_EQ(200u, writer.batch_buffer().SizeInUse());
-  ASSERT_EQ(2u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteBlockDataBuffered) {
-  TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(250u, PacketLength(msg));
-        errno = EWOULDBLOCK;
-        return -1;
-      }));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED_DATA_BUFFERED, EWOULDBLOCK),
-            WritePacket(&writer, 50));
-
-  EXPECT_TRUE(writer.IsWriteBlocked());
-
-  ASSERT_EQ(250u, writer.batch_buffer().SizeInUse());
-  ASSERT_EQ(3u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteErrorWithoutDataBuffered) {
-  TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(200u, PacketLength(msg));
-        errno = EPERM;
-        return -1;
-      }));
-  WriteResult error_result = WritePacket(&writer, 150);
-  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
-
-  ASSERT_EQ(3u, error_result.dropped_packets);
-  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
-  ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, WriteErrorAfterDataBuffered) {
-  TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(250u, PacketLength(msg));
-        errno = EPERM;
-        return -1;
-      }));
-  WriteResult error_result = WritePacket(&writer, 50);
-  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
-
-  ASSERT_EQ(3u, error_result.dropped_packets);
-  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
-  ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, FlushError) {
-  TestQuicGsoBatchWriter writer(/*fd=*/-1);
-
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
-
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(200u, PacketLength(msg));
-        errno = EINVAL;
-        return -1;
-      }));
-  WriteResult error_result = writer.Flush();
-  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL), error_result);
-
-  ASSERT_EQ(2u, error_result.dropped_packets);
-  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
-  ASSERT_EQ(0u, writer.buffered_writes().size());
-}
-
-TEST_F(QuicGsoBatchWriterTest, ReleaseTimeNullOptions) {
-  auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
-  EXPECT_EQ(0u, writer->GetReleaseTime(nullptr).actual_release_time);
-}
-
-TEST_F(QuicGsoBatchWriterTest, ReleaseTime) {
-  const WriteResult write_buffered(WRITE_STATUS_OK, 0);
-
-  auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
-
-  TestPerPacketOptions options;
-  EXPECT_TRUE(options.release_time_delay.IsZero());
-  EXPECT_FALSE(options.allow_burst);
-  EXPECT_EQ(MillisToNanos(1),
-            writer->GetReleaseTime(&options).actual_release_time);
-
-  // The 1st packet has no delay.
-  WriteResult result = WritePacketWithOptions(writer.get(), &options);
-  ASSERT_EQ(write_buffered, result);
-  EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
-  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-
-  // The 2nd packet has some delay, but allows burst.
-  options.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
-  options.allow_burst = true;
-  result = WritePacketWithOptions(writer.get(), &options);
-  ASSERT_EQ(write_buffered, result);
-  EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
-  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::FromMilliseconds(-3));
-
-  // The 3rd packet has more delay and does not allow burst.
-  // The first 2 packets are flushed due to different release time.
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(2700u, PacketLength(msg));
-        errno = 0;
-        return 0;
-      }));
-  options.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
-  options.allow_burst = false;
-  result = WritePacketWithOptions(writer.get(), &options);
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 2700), result);
-  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
-  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-
-  // The 4th packet has same delay, but allows burst.
-  options.allow_burst = true;
-  result = WritePacketWithOptions(writer.get(), &options);
-  ASSERT_EQ(write_buffered, result);
-  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
-  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-
-  // The 5th packet has same delay, allows burst, but is shorter.
-  // Packets 3,4 and 5 are flushed.
-  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
-      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
-        EXPECT_EQ(3000u, PacketLength(msg));
-        errno = 0;
-        return 0;
-      }));
-  options.allow_burst = true;
-  EXPECT_EQ(MillisToNanos(6),
-            writer->GetReleaseTime(&options).actual_release_time);
-  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 3000),
-            writer->WritePacket(&packet_buffer_[0], 300, self_address_,
-                                peer_address_, &options));
-  EXPECT_TRUE(writer->buffered_writes().empty());
-
-  // Pretend 1ms has elapsed and the 6th packet has 1ms less delay. In other
-  // words, the release time should still be the same as packets 3-5.
-  writer->ForceReleaseTimeMs(2);
-  options.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
-  result = WritePacketWithOptions(writer.get(), &options);
-  ASSERT_EQ(write_buffered, result);
-  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
-  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc b/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
deleted file mode 100644
index d5c0329..0000000
--- a/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
-
-namespace quic {
-
-QuicSendmmsgBatchWriter::QuicSendmmsgBatchWriter(
-    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
-    int fd)
-    : QuicUdpBatchWriter(std::move(batch_buffer), fd) {}
-
-QuicSendmmsgBatchWriter::CanBatchResult QuicSendmmsgBatchWriter::CanBatch(
-    const char* /*buffer*/,
-    size_t /*buf_len*/,
-    const QuicIpAddress& /*self_address*/,
-    const QuicSocketAddress& /*peer_address*/,
-    const PerPacketOptions* /*options*/,
-    uint64_t /*release_time*/) const {
-  return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
-}
-
-QuicSendmmsgBatchWriter::FlushImplResult QuicSendmmsgBatchWriter::FlushImpl() {
-  return InternalFlushImpl(
-      kCmsgSpaceForIp,
-      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
-        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
-      });
-}
-
-QuicSendmmsgBatchWriter::FlushImplResult
-QuicSendmmsgBatchWriter::InternalFlushImpl(size_t cmsg_space,
-                                           const CmsgBuilder& cmsg_builder) {
-  QUICHE_DCHECK(!IsWriteBlocked());
-  QUICHE_DCHECK(!buffered_writes().empty());
-
-  FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
-                            /*num_packets_sent=*/0, /*bytes_written=*/0};
-  WriteResult& write_result = result.write_result;
-
-  auto first = buffered_writes().cbegin();
-  const auto last = buffered_writes().cend();
-  while (first != last) {
-    QuicMMsgHdr mhdr(first, last, cmsg_space, cmsg_builder);
-
-    int num_packets_sent;
-    write_result = QuicLinuxSocketUtils::WriteMultiplePackets(
-        fd(), &mhdr, &num_packets_sent);
-    QUIC_DVLOG(1) << "WriteMultiplePackets sent " << num_packets_sent
-                  << " out of " << mhdr.num_msgs()
-                  << " packets. WriteResult=" << write_result;
-
-    if (write_result.status != WRITE_STATUS_OK) {
-      QUICHE_DCHECK_EQ(0, num_packets_sent);
-      break;
-    } else if (num_packets_sent == 0) {
-      QUIC_BUG(quic_bug_10825_1)
-          << "WriteMultiplePackets returned OK, but no packets were sent.";
-      write_result = WriteResult(WRITE_STATUS_ERROR, EIO);
-      break;
-    }
-
-    first += num_packets_sent;
-
-    result.num_packets_sent += num_packets_sent;
-    result.bytes_written += write_result.bytes_written;
-  }
-
-  // Call PopBufferedWrite() even if write_result.status is not WRITE_STATUS_OK,
-  // to deal with partial writes.
-  batch_buffer().PopBufferedWrite(result.num_packets_sent);
-
-  if (write_result.status != WRITE_STATUS_OK) {
-    return result;
-  }
-
-  QUIC_BUG_IF(quic_bug_12537_1, !buffered_writes().empty())
-      << "All packets should have been written on a successful return";
-  write_result.bytes_written = result.bytes_written;
-  return result;
-}
-
-}  // namespace quic
diff --git a/quic/core/batch_writer/quic_sendmmsg_batch_writer.h b/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
deleted file mode 100644
index 5efcb1d..0000000
--- a/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
-
-#include "quic/core/batch_writer/quic_batch_writer_base.h"
-#include "quic/core/quic_linux_socket_utils.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicSendmmsgBatchWriter : public QuicUdpBatchWriter {
- public:
-  QuicSendmmsgBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
-                          int fd);
-
-  CanBatchResult CanBatch(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          const PerPacketOptions* options,
-                          uint64_t release_time) const override;
-
-  FlushImplResult FlushImpl() override;
-
- protected:
-  using CmsgBuilder = QuicMMsgHdr::ControlBufferInitializer;
-  FlushImplResult InternalFlushImpl(size_t cmsg_space,
-                                    const CmsgBuilder& cmsg_builder);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
diff --git a/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc b/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
deleted file mode 100644
index 1265fae..0000000
--- a/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Add tests here.
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/chlo_extractor.cc b/quic/core/chlo_extractor.cc
deleted file mode 100644
index 29a43a6..0000000
--- a/quic/core/chlo_extractor.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/chlo_extractor.h"
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-namespace {
-
-class ChloFramerVisitor : public QuicFramerVisitorInterface,
-                          public CryptoFramerVisitorInterface {
- public:
-  ChloFramerVisitor(QuicFramer* framer,
-                    const QuicTagVector& create_session_tag_indicators,
-                    ChloExtractor::Delegate* delegate);
-
-  ~ChloFramerVisitor() override = default;
-
-  // QuicFramerVisitorInterface implementation
-  void OnError(QuicFramer* /*framer*/) override {}
-  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
-  void OnPacket() override {}
-  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& /*packet*/) override {}
-  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
-                     QuicConnectionId /*new_connection_id*/,
-                     absl::string_view /*retry_token*/,
-                     absl::string_view /*retry_integrity_tag*/,
-                     absl::string_view /*retry_without_tag*/) override {}
-  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
-  void OnDecryptedPacket(size_t /*length*/,
-                         EncryptionLevel /*level*/) override {}
-  bool OnPacketHeader(const QuicPacketHeader& header) override;
-  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
-  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
-                             EncryptionLevel decryption_level,
-                             bool has_decryption_key) override;
-  bool OnStreamFrame(const QuicStreamFrame& frame) override;
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta ack_delay_time) override;
-  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
-  bool OnAckTimestamp(QuicPacketNumber packet_number,
-                      QuicTime timestamp) override;
-  bool OnAckFrameEnd(QuicPacketNumber start) override;
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
-  bool OnPingFrame(const QuicPingFrame& frame) override;
-  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
-  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
-  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) override;
-  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
-  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
-  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
-  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
-  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
-  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
-  bool OnMessageFrame(const QuicMessageFrame& frame) override;
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& farme) override;
-  void OnPacketComplete() override {}
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& token) const override;
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& /*packet*/) override {}
-  void OnKeyUpdate(KeyUpdateReason /*reason*/) override;
-  void OnDecryptedFirstPacketInKeyPhase() override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-
-  // CryptoFramerVisitorInterface implementation.
-  void OnError(CryptoFramer* framer) override;
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
-  // Shared implementation between OnStreamFrame and OnCryptoFrame.
-  bool OnHandshakeData(absl::string_view data);
-
-  bool found_chlo() { return found_chlo_; }
-  bool chlo_contains_tags() { return chlo_contains_tags_; }
-
- private:
-  QuicFramer* framer_;
-  const QuicTagVector& create_session_tag_indicators_;
-  ChloExtractor::Delegate* delegate_;
-  bool found_chlo_;
-  bool chlo_contains_tags_;
-  QuicConnectionId connection_id_;
-};
-
-ChloFramerVisitor::ChloFramerVisitor(
-    QuicFramer* framer,
-    const QuicTagVector& create_session_tag_indicators,
-    ChloExtractor::Delegate* delegate)
-    : framer_(framer),
-      create_session_tag_indicators_(create_session_tag_indicators),
-      delegate_(delegate),
-      found_chlo_(false),
-      chlo_contains_tags_(false),
-      connection_id_(EmptyQuicConnectionId()) {}
-
-bool ChloFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
-  if (!framer_->IsSupportedVersion(version)) {
-    return false;
-  }
-  framer_->set_version(version);
-  return true;
-}
-
-bool ChloFramerVisitor::OnUnauthenticatedPublicHeader(
-    const QuicPacketHeader& header) {
-  connection_id_ = header.destination_connection_id;
-  // QuicFramer creates a NullEncrypter and NullDecrypter at level
-  // ENCRYPTION_INITIAL. While those are the correct ones to use with some
-  // versions of QUIC, others use the IETF-style initial crypters, so those need
-  // to be created and installed.
-  framer_->SetInitialObfuscators(header.destination_connection_id);
-  return true;
-}
-bool ChloFramerVisitor::OnUnauthenticatedHeader(
-    const QuicPacketHeader& /*header*/) {
-  return true;
-}
-bool ChloFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
-  return true;
-}
-
-void ChloFramerVisitor::OnCoalescedPacket(
-    const QuicEncryptedPacket& /*packet*/) {}
-
-void ChloFramerVisitor::OnUndecryptablePacket(
-    const QuicEncryptedPacket& /*packet*/,
-    EncryptionLevel /*decryption_level*/,
-    bool /*has_decryption_key*/) {}
-
-bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
-  if (QuicVersionUsesCryptoFrames(framer_->transport_version())) {
-    // CHLO will be sent in CRYPTO frames in v47 and above.
-    return false;
-  }
-  absl::string_view data(frame.data_buffer, frame.data_length);
-  if (QuicUtils::IsCryptoStreamId(framer_->transport_version(),
-                                  frame.stream_id) &&
-      frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
-    return OnHandshakeData(data);
-  }
-  return true;
-}
-
-bool ChloFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  if (!QuicVersionUsesCryptoFrames(framer_->transport_version())) {
-    // CHLO will be in stream frames before v47.
-    return false;
-  }
-  absl::string_view data(frame.data_buffer, frame.data_length);
-  if (frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
-    return OnHandshakeData(data);
-  }
-  return true;
-}
-
-bool ChloFramerVisitor::OnHandshakeData(absl::string_view data) {
-  CryptoFramer crypto_framer;
-  crypto_framer.set_visitor(this);
-  if (!crypto_framer.ProcessInput(data)) {
-    return false;
-  }
-  // Interrogate the crypto framer and see if there are any
-  // intersecting tags between what we saw in the maybe-CHLO and the
-  // indicator set.
-  for (const QuicTag tag : create_session_tag_indicators_) {
-    if (crypto_framer.HasTag(tag)) {
-      chlo_contains_tags_ = true;
-    }
-  }
-  if (chlo_contains_tags_ && delegate_) {
-    // Unfortunately, because this is a partial CHLO,
-    // OnHandshakeMessage was never called, so the ALPN was never
-    // extracted. Fake it up a bit and send it to the delegate so that
-    // the correct dispatch can happen.
-    crypto_framer.ForceHandshake();
-  }
-
-  return true;
-}
-
-bool ChloFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
-                                        QuicTime::Delta /*ack_delay_time*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
-                                   QuicPacketNumber /*end*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
-                                       QuicTime /*timestamp*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnStopWaitingFrame(
-    const QuicStopWaitingFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnConnectionCloseFrame(
-    const QuicConnectionCloseFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnStopSendingFrame(
-    const QuicStopSendingFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnPathChallengeFrame(
-    const QuicPathChallengeFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnPathResponseFrame(
-    const QuicPathResponseFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnWindowUpdateFrame(
-    const QuicWindowUpdateFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnNewConnectionIdFrame(
-    const QuicNewConnectionIdFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnRetireConnectionIdFrame(
-    const QuicRetireConnectionIdFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnHandshakeDoneFrame(
-    const QuicHandshakeDoneFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnAckFrequencyFrame(
-    const QuicAckFrequencyFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::IsValidStatelessResetToken(
-    const StatelessResetToken& /*token*/) const {
-  return false;
-}
-
-bool ChloFramerVisitor::OnMaxStreamsFrame(
-    const QuicMaxStreamsFrame& /*frame*/) {
-  return true;
-}
-
-bool ChloFramerVisitor::OnStreamsBlockedFrame(
-    const QuicStreamsBlockedFrame& /*frame*/) {
-  return true;
-}
-
-void ChloFramerVisitor::OnKeyUpdate(KeyUpdateReason /*reason*/) {}
-
-void ChloFramerVisitor::OnDecryptedFirstPacketInKeyPhase() {}
-
-std::unique_ptr<QuicDecrypter>
-ChloFramerVisitor::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  return nullptr;
-}
-
-std::unique_ptr<QuicEncrypter>
-ChloFramerVisitor::CreateCurrentOneRttEncrypter() {
-  return nullptr;
-}
-
-void ChloFramerVisitor::OnError(CryptoFramer* /*framer*/) {}
-
-void ChloFramerVisitor::OnHandshakeMessage(
-    const CryptoHandshakeMessage& message) {
-  if (delegate_ != nullptr) {
-    delegate_->OnChlo(framer_->transport_version(), connection_id_, message);
-  }
-  found_chlo_ = true;
-}
-
-}  // namespace
-
-// static
-bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
-                            ParsedQuicVersion version,
-                            const QuicTagVector& create_session_tag_indicators,
-                            Delegate* delegate,
-                            uint8_t connection_id_length) {
-  QUIC_DVLOG(1) << "Extracting CHLO using version " << version;
-  QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_SERVER,
-                    connection_id_length);
-  ChloFramerVisitor visitor(&framer, create_session_tag_indicators, delegate);
-  framer.set_visitor(&visitor);
-  if (!framer.ProcessPacket(packet)) {
-    return false;
-  }
-  return visitor.found_chlo() || visitor.chlo_contains_tags();
-}
-
-}  // namespace quic
diff --git a/quic/core/chlo_extractor.h b/quic/core/chlo_extractor.h
deleted file mode 100644
index 4e5bbe1..0000000
--- a/quic/core/chlo_extractor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
-#define QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-// A utility for extracting QUIC Client Hello messages from packets,
-// without needs to spin up a full QuicSession.
-class QUIC_NO_EXPORT ChloExtractor {
- public:
-  class QUIC_NO_EXPORT Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // Called when a CHLO message is found in the packets.
-    virtual void OnChlo(QuicTransportVersion version,
-                        QuicConnectionId connection_id,
-                        const CryptoHandshakeMessage& chlo) = 0;
-  };
-
-  // Extracts a CHLO message from |packet| and invokes the OnChlo
-  // method of |delegate|. Return true if a CHLO message was found,
-  // and false otherwise. If non-empty,
-  // |create_session_tag_indicators| contains a list of QUIC tags that
-  // if found will result in the session being created early, to
-  // enable support for multi-packet CHLOs.
-  static bool Extract(const QuicEncryptedPacket& packet,
-                      ParsedQuicVersion version,
-                      const QuicTagVector& create_session_tag_indicators,
-                      Delegate* delegate,
-                      uint8_t connection_id_length);
-
-  ChloExtractor(const ChloExtractor&) = delete;
-  ChloExtractor operator=(const ChloExtractor&) = delete;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
diff --git a/quic/core/chlo_extractor_test.cc b/quic/core/chlo_extractor_test.cc
deleted file mode 100644
index 6900620..0000000
--- a/quic/core/chlo_extractor_test.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/chlo_extractor.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestDelegate : public ChloExtractor::Delegate {
- public:
-  TestDelegate() = default;
-  ~TestDelegate() override = default;
-
-  // ChloExtractor::Delegate implementation
-  void OnChlo(QuicTransportVersion version,
-              QuicConnectionId connection_id,
-              const CryptoHandshakeMessage& chlo) override {
-    version_ = version;
-    connection_id_ = connection_id;
-    chlo_ = chlo.DebugString();
-    absl::string_view alpn_value;
-    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
-      alpn_ = std::string(alpn_value);
-    }
-  }
-
-  QuicConnectionId connection_id() const { return connection_id_; }
-  QuicTransportVersion transport_version() const { return version_; }
-  const std::string& chlo() const { return chlo_; }
-  const std::string& alpn() const { return alpn_; }
-
- private:
-  QuicConnectionId connection_id_;
-  QuicTransportVersion version_;
-  std::string chlo_;
-  std::string alpn_;
-};
-
-class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  ChloExtractorTest() : version_(GetParam()) {}
-
-  void MakePacket(absl::string_view data,
-                  bool munge_offset,
-                  bool munge_stream_id) {
-    QuicPacketHeader header;
-    header.destination_connection_id = TestConnectionId();
-    header.destination_connection_id_included = CONNECTION_ID_PRESENT;
-    header.version_flag = true;
-    header.version = version_;
-    header.reset_flag = false;
-    header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
-    header.packet_number = QuicPacketNumber(1);
-    if (version_.HasLongHeaderLengths()) {
-      header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-      header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-    }
-    QuicFrames frames;
-    size_t offset = 0;
-    if (munge_offset) {
-      offset++;
-    }
-    QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
-                      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
-    framer.SetInitialObfuscators(TestConnectionId());
-    if (!version_.UsesCryptoFrames() || munge_stream_id) {
-      QuicStreamId stream_id =
-          QuicUtils::GetCryptoStreamId(version_.transport_version);
-      if (munge_stream_id) {
-        stream_id++;
-      }
-      frames.push_back(
-          QuicFrame(QuicStreamFrame(stream_id, false, offset, data)));
-    } else {
-      frames.push_back(
-          QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, offset, data)));
-    }
-    std::unique_ptr<QuicPacket> packet(
-        BuildUnsizedDataPacket(&framer, header, frames));
-    EXPECT_TRUE(packet != nullptr);
-    size_t encrypted_length =
-        framer.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *packet,
-                              buffer_, ABSL_ARRAYSIZE(buffer_));
-    ASSERT_NE(0u, encrypted_length);
-    packet_ = std::make_unique<QuicEncryptedPacket>(buffer_, encrypted_length);
-    EXPECT_TRUE(packet_ != nullptr);
-    DeleteFrames(&frames);
-  }
-
- protected:
-  ParsedQuicVersion version_;
-  TestDelegate delegate_;
-  std::unique_ptr<QuicEncryptedPacket> packet_;
-  char buffer_[kMaxOutgoingPacketSize];
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    ChloExtractorTests,
-    ChloExtractorTest,
-    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
-    ::testing::PrintToStringParamName());
-
-TEST_P(ChloExtractorTest, FindsValidChlo) {
-  CryptoHandshakeMessage client_hello;
-  client_hello.set_tag(kCHLO);
-
-  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
-
-  MakePacket(client_hello_str, /*munge_offset=*/false,
-             /*munge_stream_id=*/false);
-  EXPECT_TRUE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
-                                     kQuicDefaultConnectionIdLength));
-  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
-  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
-  EXPECT_EQ(client_hello.DebugString(), delegate_.chlo());
-}
-
-TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
-  if (version_.UsesCryptoFrames()) {
-    // When crypto frames are in use we do not use stream frames.
-    return;
-  }
-  CryptoHandshakeMessage client_hello;
-  client_hello.set_tag(kCHLO);
-
-  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
-  MakePacket(client_hello_str,
-             /*munge_offset=*/false, /*munge_stream_id=*/true);
-  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
-                                      kQuicDefaultConnectionIdLength));
-}
-
-TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
-  CryptoHandshakeMessage client_hello;
-  client_hello.set_tag(kCHLO);
-
-  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
-  MakePacket(client_hello_str, /*munge_offset=*/true,
-             /*munge_stream_id=*/false);
-  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
-                                      kQuicDefaultConnectionIdLength));
-}
-
-TEST_P(ChloExtractorTest, DoesNotFindInvalidChlo) {
-  MakePacket("foo", /*munge_offset=*/false,
-             /*munge_stream_id=*/false);
-  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
-                                      kQuicDefaultConnectionIdLength));
-}
-
-TEST_P(ChloExtractorTest, FirstFlight) {
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
-      GetFirstFlightOfPackets(version_);
-  ASSERT_EQ(packets.size(), 1u);
-  EXPECT_TRUE(ChloExtractor::Extract(*packets[0], version_, {}, &delegate_,
-                                     kQuicDefaultConnectionIdLength));
-  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
-  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
-  EXPECT_EQ(AlpnForVersion(version_), delegate_.alpn());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/bandwidth_sampler.cc b/quic/core/congestion_control/bandwidth_sampler.cc
deleted file mode 100644
index fd2cc8f..0000000
--- a/quic/core/congestion_control/bandwidth_sampler.cc
+++ /dev/null
@@ -1,589 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-
-#include <algorithm>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-std::ostream& operator<<(std::ostream& os, const SendTimeState& s) {
-  os << "{valid:" << s.is_valid << ", app_limited:" << s.is_app_limited
-     << ", total_sent:" << s.total_bytes_sent
-     << ", total_acked:" << s.total_bytes_acked
-     << ", total_lost:" << s.total_bytes_lost
-     << ", inflight:" << s.bytes_in_flight << "}";
-  return os;
-}
-
-QuicByteCount MaxAckHeightTracker::Update(
-    QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
-    QuicRoundTripCount round_trip_count,
-    QuicPacketNumber last_sent_packet_number,
-    QuicPacketNumber last_acked_packet_number, QuicTime ack_time,
-    QuicByteCount bytes_acked) {
-  bool force_new_epoch = false;
-
-  if (reduce_extra_acked_on_bandwidth_increase_ && is_new_max_bandwidth) {
-    // Save and clear existing entries.
-    ExtraAckedEvent best = max_ack_height_filter_.GetBest();
-    ExtraAckedEvent second_best = max_ack_height_filter_.GetSecondBest();
-    ExtraAckedEvent third_best = max_ack_height_filter_.GetThirdBest();
-    max_ack_height_filter_.Clear();
-
-    // Reinsert the heights into the filter after recalculating.
-    QuicByteCount expected_bytes_acked = bandwidth_estimate * best.time_delta;
-    if (expected_bytes_acked < best.bytes_acked) {
-      best.extra_acked = best.bytes_acked - expected_bytes_acked;
-      max_ack_height_filter_.Update(best, best.round);
-    }
-    expected_bytes_acked = bandwidth_estimate * second_best.time_delta;
-    if (expected_bytes_acked < second_best.bytes_acked) {
-      QUICHE_DCHECK_LE(best.round, second_best.round);
-      second_best.extra_acked = second_best.bytes_acked - expected_bytes_acked;
-      max_ack_height_filter_.Update(second_best, second_best.round);
-    }
-    expected_bytes_acked = bandwidth_estimate * third_best.time_delta;
-    if (expected_bytes_acked < third_best.bytes_acked) {
-      QUICHE_DCHECK_LE(second_best.round, third_best.round);
-      third_best.extra_acked = third_best.bytes_acked - expected_bytes_acked;
-      max_ack_height_filter_.Update(third_best, third_best.round);
-    }
-  }
-
-  // If any packet sent after the start of the epoch has been acked, start a new
-  // epoch.
-  if (start_new_aggregation_epoch_after_full_round_ &&
-      last_sent_packet_number_before_epoch_.IsInitialized() &&
-      last_acked_packet_number.IsInitialized() &&
-      last_acked_packet_number > last_sent_packet_number_before_epoch_) {
-    QUIC_DVLOG(3) << "Force starting a new aggregation epoch. "
-                     "last_sent_packet_number_before_epoch_:"
-                  << last_sent_packet_number_before_epoch_
-                  << ", last_acked_packet_number:" << last_acked_packet_number;
-    if (reduce_extra_acked_on_bandwidth_increase_) {
-      QUIC_BUG(quic_bwsampler_46)
-          << "A full round of aggregation should never "
-          << "pass with startup_include_extra_acked(B204) enabled.";
-    }
-    force_new_epoch = true;
-  }
-  if (aggregation_epoch_start_time_ == QuicTime::Zero() || force_new_epoch) {
-    aggregation_epoch_bytes_ = bytes_acked;
-    aggregation_epoch_start_time_ = ack_time;
-    last_sent_packet_number_before_epoch_ = last_sent_packet_number;
-    ++num_ack_aggregation_epochs_;
-    return 0;
-  }
-
-  // Compute how many bytes are expected to be delivered, assuming max bandwidth
-  // is correct.
-  QuicTime::Delta aggregation_delta = ack_time - aggregation_epoch_start_time_;
-  QuicByteCount expected_bytes_acked = bandwidth_estimate * aggregation_delta;
-  // Reset the current aggregation epoch as soon as the ack arrival rate is less
-  // than or equal to the max bandwidth.
-  if (aggregation_epoch_bytes_ <=
-      ack_aggregation_bandwidth_threshold_ * expected_bytes_acked) {
-    QUIC_DVLOG(3) << "Starting a new aggregation epoch because "
-                     "aggregation_epoch_bytes_ "
-                  << aggregation_epoch_bytes_
-                  << " is smaller than expected. "
-                     "ack_aggregation_bandwidth_threshold_:"
-                  << ack_aggregation_bandwidth_threshold_
-                  << ", expected_bytes_acked:" << expected_bytes_acked
-                  << ", bandwidth_estimate:" << bandwidth_estimate
-                  << ", aggregation_duration:" << aggregation_delta
-                  << ", new_aggregation_epoch:" << ack_time
-                  << ", new_aggregation_bytes_acked:" << bytes_acked;
-    // Reset to start measuring a new aggregation epoch.
-    aggregation_epoch_bytes_ = bytes_acked;
-    aggregation_epoch_start_time_ = ack_time;
-    last_sent_packet_number_before_epoch_ = last_sent_packet_number;
-    ++num_ack_aggregation_epochs_;
-    return 0;
-  }
-
-  aggregation_epoch_bytes_ += bytes_acked;
-
-  // Compute how many extra bytes were delivered vs max bandwidth.
-  QuicByteCount extra_bytes_acked =
-      aggregation_epoch_bytes_ - expected_bytes_acked;
-  QUIC_DVLOG(3) << "Updating MaxAckHeight. ack_time:" << ack_time
-                << ", last sent packet:" << last_sent_packet_number
-                << ", bandwidth_estimate:" << bandwidth_estimate
-                << ", bytes_acked:" << bytes_acked
-                << ", expected_bytes_acked:" << expected_bytes_acked
-                << ", aggregation_epoch_bytes_:" << aggregation_epoch_bytes_
-                << ", extra_bytes_acked:" << extra_bytes_acked;
-  ExtraAckedEvent new_event;
-  new_event.extra_acked = extra_bytes_acked;
-  new_event.bytes_acked = aggregation_epoch_bytes_;
-  new_event.time_delta = aggregation_delta;
-  max_ack_height_filter_.Update(new_event, round_trip_count);
-  return extra_bytes_acked;
-}
-
-BandwidthSampler::BandwidthSampler(
-    const QuicUnackedPacketMap* unacked_packet_map,
-    QuicRoundTripCount max_height_tracker_window_length)
-    : total_bytes_sent_(0),
-      total_bytes_acked_(0),
-      total_bytes_lost_(0),
-      total_bytes_neutered_(0),
-      total_bytes_sent_at_last_acked_packet_(0),
-      last_acked_packet_sent_time_(QuicTime::Zero()),
-      last_acked_packet_ack_time_(QuicTime::Zero()),
-      is_app_limited_(true),
-      connection_state_map_(),
-      max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
-      unacked_packet_map_(unacked_packet_map),
-      max_ack_height_tracker_(max_height_tracker_window_length),
-      total_bytes_acked_after_last_ack_event_(0),
-      overestimate_avoidance_(false),
-      limit_max_ack_height_tracker_by_send_rate_(false) {}
-
-BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
-    : total_bytes_sent_(other.total_bytes_sent_),
-      total_bytes_acked_(other.total_bytes_acked_),
-      total_bytes_lost_(other.total_bytes_lost_),
-      total_bytes_neutered_(other.total_bytes_neutered_),
-      total_bytes_sent_at_last_acked_packet_(
-          other.total_bytes_sent_at_last_acked_packet_),
-      last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
-      last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
-      last_sent_packet_(other.last_sent_packet_),
-      last_acked_packet_(other.last_acked_packet_),
-      is_app_limited_(other.is_app_limited_),
-      end_of_app_limited_phase_(other.end_of_app_limited_phase_),
-      connection_state_map_(other.connection_state_map_),
-      recent_ack_points_(other.recent_ack_points_),
-      a0_candidates_(other.a0_candidates_),
-      max_tracked_packets_(other.max_tracked_packets_),
-      unacked_packet_map_(other.unacked_packet_map_),
-      max_ack_height_tracker_(other.max_ack_height_tracker_),
-      total_bytes_acked_after_last_ack_event_(
-          other.total_bytes_acked_after_last_ack_event_),
-      overestimate_avoidance_(other.overestimate_avoidance_),
-      limit_max_ack_height_tracker_by_send_rate_(
-          other.limit_max_ack_height_tracker_by_send_rate_) {}
-
-void BandwidthSampler::EnableOverestimateAvoidance() {
-  if (overestimate_avoidance_) {
-    return;
-  }
-
-  overestimate_avoidance_ = true;
-  // TODO(wub): Change the default value of
-  // --quic_ack_aggregation_bandwidth_threshold to 2.0.
-  max_ack_height_tracker_.SetAckAggregationBandwidthThreshold(2.0);
-}
-
-BandwidthSampler::~BandwidthSampler() {}
-
-void BandwidthSampler::OnPacketSent(
-    QuicTime sent_time,
-    QuicPacketNumber packet_number,
-    QuicByteCount bytes,
-    QuicByteCount bytes_in_flight,
-    HasRetransmittableData has_retransmittable_data) {
-  last_sent_packet_ = packet_number;
-
-  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
-    return;
-  }
-
-  total_bytes_sent_ += bytes;
-
-  // If there are no packets in flight, the time at which the new transmission
-  // opens can be treated as the A_0 point for the purpose of bandwidth
-  // sampling. This underestimates bandwidth to some extent, and produces some
-  // artificially low samples for most packets in flight, but it provides with
-  // samples at important points where we would not have them otherwise, most
-  // importantly at the beginning of the connection.
-  if (bytes_in_flight == 0) {
-    last_acked_packet_ack_time_ = sent_time;
-    if (overestimate_avoidance_) {
-      recent_ack_points_.Clear();
-      recent_ack_points_.Update(sent_time, total_bytes_acked_);
-      a0_candidates_.clear();
-      a0_candidates_.push_back(recent_ack_points_.MostRecentPoint());
-    }
-    total_bytes_sent_at_last_acked_packet_ = total_bytes_sent_;
-
-    // In this situation ack compression is not a concern, set send rate to
-    // effectively infinite.
-    last_acked_packet_sent_time_ = sent_time;
-  }
-
-  if (!connection_state_map_.IsEmpty() &&
-      packet_number >
-          connection_state_map_.last_packet() + max_tracked_packets_) {
-    if (unacked_packet_map_ != nullptr && !unacked_packet_map_->empty()) {
-      QuicPacketNumber maybe_least_unacked =
-          unacked_packet_map_->GetLeastUnacked();
-      QUIC_BUG(quic_bug_10437_1)
-          << "BandwidthSampler in-flight packet map has exceeded maximum "
-             "number of tracked packets("
-          << max_tracked_packets_
-          << ").  First tracked: " << connection_state_map_.first_packet()
-          << "; last tracked: " << connection_state_map_.last_packet()
-          << "; entry_slots_used: " << connection_state_map_.entry_slots_used()
-          << "; number_of_present_entries: "
-          << connection_state_map_.number_of_present_entries()
-          << "; packet number: " << packet_number
-          << "; unacked_map: " << unacked_packet_map_->DebugString()
-          << "; total_bytes_sent: " << total_bytes_sent_
-          << "; total_bytes_acked: " << total_bytes_acked_
-          << "; total_bytes_lost: " << total_bytes_lost_
-          << "; total_bytes_neutered: " << total_bytes_neutered_
-          << "; last_acked_packet_sent_time: " << last_acked_packet_sent_time_
-          << "; total_bytes_sent_at_last_acked_packet: "
-          << total_bytes_sent_at_last_acked_packet_
-          << "; least_unacked_packet_info: "
-          << (unacked_packet_map_->IsUnacked(maybe_least_unacked)
-                  ? unacked_packet_map_
-                        ->GetTransmissionInfo(maybe_least_unacked)
-                        .DebugString()
-                  : "n/a");
-    } else {
-      QUIC_BUG(quic_bug_10437_2)
-          << "BandwidthSampler in-flight packet map has exceeded maximum "
-             "number of tracked packets.";
-    }
-  }
-
-  bool success = connection_state_map_.Emplace(packet_number, sent_time, bytes,
-                                               bytes_in_flight + bytes, *this);
-  QUIC_BUG_IF(quic_bug_10437_3, !success)
-      << "BandwidthSampler failed to insert the packet "
-         "into the map, most likely because it's already "
-         "in it.";
-}
-
-void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
-  connection_state_map_.Remove(
-      packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
-        QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
-        total_bytes_neutered_ += sent_packet.size;
-      });
-}
-
-BandwidthSamplerInterface::CongestionEventSample
-BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
-                                    const AckedPacketVector& acked_packets,
-                                    const LostPacketVector& lost_packets,
-                                    QuicBandwidth max_bandwidth,
-                                    QuicBandwidth est_bandwidth_upper_bound,
-                                    QuicRoundTripCount round_trip_count) {
-  CongestionEventSample event_sample;
-
-  SendTimeState last_lost_packet_send_state;
-
-  for (const LostPacket& packet : lost_packets) {
-    SendTimeState send_state =
-        OnPacketLost(packet.packet_number, packet.bytes_lost);
-    if (send_state.is_valid) {
-      last_lost_packet_send_state = send_state;
-    }
-  }
-
-  if (acked_packets.empty()) {
-    // Only populate send state for a loss-only event.
-    event_sample.last_packet_send_state = last_lost_packet_send_state;
-    return event_sample;
-  }
-
-  SendTimeState last_acked_packet_send_state;
-  QuicBandwidth max_send_rate = QuicBandwidth::Zero();
-  for (const auto& packet : acked_packets) {
-    BandwidthSample sample =
-        OnPacketAcknowledged(ack_time, packet.packet_number);
-    if (!sample.state_at_send.is_valid) {
-      continue;
-    }
-
-    last_acked_packet_send_state = sample.state_at_send;
-
-    if (!sample.rtt.IsZero()) {
-      event_sample.sample_rtt = std::min(event_sample.sample_rtt, sample.rtt);
-    }
-    if (sample.bandwidth > event_sample.sample_max_bandwidth) {
-      event_sample.sample_max_bandwidth = sample.bandwidth;
-      event_sample.sample_is_app_limited = sample.state_at_send.is_app_limited;
-    }
-    if (!sample.send_rate.IsInfinite()) {
-      max_send_rate = std::max(max_send_rate, sample.send_rate);
-    }
-    const QuicByteCount inflight_sample =
-        total_bytes_acked() - last_acked_packet_send_state.total_bytes_acked;
-    if (inflight_sample > event_sample.sample_max_inflight) {
-      event_sample.sample_max_inflight = inflight_sample;
-    }
-  }
-
-  if (!last_lost_packet_send_state.is_valid) {
-    event_sample.last_packet_send_state = last_acked_packet_send_state;
-  } else if (!last_acked_packet_send_state.is_valid) {
-    event_sample.last_packet_send_state = last_lost_packet_send_state;
-  } else {
-    // If two packets are inflight and an alarm is armed to lose a packet and it
-    // wakes up late, then the first of two in flight packets could have been
-    // acknowledged before the wakeup, which re-evaluates loss detection, and
-    // could declare the later of the two lost.
-    event_sample.last_packet_send_state =
-        lost_packets.back().packet_number > acked_packets.back().packet_number
-            ? last_lost_packet_send_state
-            : last_acked_packet_send_state;
-  }
-
-  bool is_new_max_bandwidth = event_sample.sample_max_bandwidth > max_bandwidth;
-  max_bandwidth = std::max(max_bandwidth, event_sample.sample_max_bandwidth);
-  if (limit_max_ack_height_tracker_by_send_rate_) {
-    max_bandwidth = std::max(max_bandwidth, max_send_rate);
-  }
-  // TODO(ianswett): Why is the min being passed in here?
-  event_sample.extra_acked =
-      OnAckEventEnd(std::min(est_bandwidth_upper_bound, max_bandwidth),
-                    is_new_max_bandwidth, round_trip_count);
-
-  return event_sample;
-}
-
-QuicByteCount BandwidthSampler::OnAckEventEnd(
-    QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
-    QuicRoundTripCount round_trip_count) {
-  const QuicByteCount newly_acked_bytes =
-      total_bytes_acked_ - total_bytes_acked_after_last_ack_event_;
-
-  if (newly_acked_bytes == 0) {
-    return 0;
-  }
-  total_bytes_acked_after_last_ack_event_ = total_bytes_acked_;
-  QuicByteCount extra_acked = max_ack_height_tracker_.Update(
-      bandwidth_estimate, is_new_max_bandwidth, round_trip_count,
-      last_sent_packet_, last_acked_packet_, last_acked_packet_ack_time_,
-      newly_acked_bytes);
-  // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack
-  // aggregation epoch, save LessRecentPoint, which is the last ack point of the
-  // previous epoch, as a A0 candidate.
-  if (overestimate_avoidance_ && extra_acked == 0) {
-    a0_candidates_.push_back(recent_ack_points_.LessRecentPoint());
-    QUIC_DVLOG(1) << "New a0_candidate:" << a0_candidates_.back();
-  }
-  return extra_acked;
-}
-
-BandwidthSample BandwidthSampler::OnPacketAcknowledged(
-    QuicTime ack_time,
-    QuicPacketNumber packet_number) {
-  last_acked_packet_ = packet_number;
-  ConnectionStateOnSentPacket* sent_packet_pointer =
-      connection_state_map_.GetEntry(packet_number);
-  if (sent_packet_pointer == nullptr) {
-    // See the TODO below.
-    return BandwidthSample();
-  }
-  BandwidthSample sample =
-      OnPacketAcknowledgedInner(ack_time, packet_number, *sent_packet_pointer);
-  return sample;
-}
-
-BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
-    QuicTime ack_time,
-    QuicPacketNumber packet_number,
-    const ConnectionStateOnSentPacket& sent_packet) {
-  total_bytes_acked_ += sent_packet.size;
-  total_bytes_sent_at_last_acked_packet_ =
-      sent_packet.send_time_state.total_bytes_sent;
-  last_acked_packet_sent_time_ = sent_packet.sent_time;
-  last_acked_packet_ack_time_ = ack_time;
-  if (overestimate_avoidance_) {
-    recent_ack_points_.Update(ack_time, total_bytes_acked_);
-  }
-
-  if (is_app_limited_) {
-    // Exit app-limited phase in two cases:
-    // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
-    // packets are sent while there are buffered packets or pending data.
-    // (2) The current acked packet is after the sent packet marked as the end
-    // of the app limit phase.
-    if (!end_of_app_limited_phase_.IsInitialized() ||
-        packet_number > end_of_app_limited_phase_) {
-      is_app_limited_ = false;
-    }
-  }
-
-  // There might have been no packets acknowledged at the moment when the
-  // current packet was sent. In that case, there is no bandwidth sample to
-  // make.
-  if (sent_packet.last_acked_packet_sent_time == QuicTime::Zero()) {
-    QUIC_BUG(quic_bug_10437_4)
-        << "sent_packet.last_acked_packet_sent_time is zero";
-    return BandwidthSample();
-  }
-
-  // Infinite rate indicates that the sampler is supposed to discard the
-  // current send rate sample and use only the ack rate.
-  QuicBandwidth send_rate = QuicBandwidth::Infinite();
-  if (sent_packet.sent_time > sent_packet.last_acked_packet_sent_time) {
-    send_rate = QuicBandwidth::FromBytesAndTimeDelta(
-        sent_packet.send_time_state.total_bytes_sent -
-            sent_packet.total_bytes_sent_at_last_acked_packet,
-        sent_packet.sent_time - sent_packet.last_acked_packet_sent_time);
-  }
-
-  AckPoint a0;
-  if (overestimate_avoidance_ &&
-      ChooseA0Point(sent_packet.send_time_state.total_bytes_acked, &a0)) {
-    QUIC_DVLOG(2) << "Using a0 point: " << a0;
-  } else {
-    a0.ack_time = sent_packet.last_acked_packet_ack_time,
-    a0.total_bytes_acked = sent_packet.send_time_state.total_bytes_acked;
-  }
-
-  // During the slope calculation, ensure that ack time of the current packet is
-  // always larger than the time of the previous packet, otherwise division by
-  // zero or integer underflow can occur.
-  if (ack_time <= a0.ack_time) {
-    // TODO(wub): Compare this code count before and after fixing clock jitter
-    // issue.
-    if (a0.ack_time == sent_packet.sent_time) {
-      // This is the 1st packet after quiescense.
-      QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 1, 2);
-    } else {
-      QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 2, 2);
-    }
-    QUIC_LOG_EVERY_N_SEC(ERROR, 60)
-        << "Time of the previously acked packet:"
-        << a0.ack_time.ToDebuggingValue()
-        << " is larger than the ack time of the current packet:"
-        << ack_time.ToDebuggingValue()
-        << ". acked packet number:" << packet_number
-        << ", total_bytes_acked_:" << total_bytes_acked_
-        << ", overestimate_avoidance_:" << overestimate_avoidance_
-        << ", sent_packet:" << sent_packet;
-    return BandwidthSample();
-  }
-  QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      total_bytes_acked_ - a0.total_bytes_acked, ack_time - a0.ack_time);
-
-  BandwidthSample sample;
-  sample.bandwidth = std::min(send_rate, ack_rate);
-  // Note: this sample does not account for delayed acknowledgement time.  This
-  // means that the RTT measurements here can be artificially high, especially
-  // on low bandwidth connections.
-  sample.rtt = ack_time - sent_packet.sent_time;
-  sample.send_rate = send_rate;
-  SentPacketToSendTimeState(sent_packet, &sample.state_at_send);
-
-  if (sample.bandwidth.IsZero()) {
-    QUIC_LOG_EVERY_N_SEC(ERROR, 60)
-        << "ack_rate: " << ack_rate << ", send_rate: " << send_rate
-        << ". acked packet number:" << packet_number
-        << ", overestimate_avoidance_:" << overestimate_avoidance_ << "a1:{"
-        << total_bytes_acked_ << "@" << ack_time << "}, a0:{"
-        << a0.total_bytes_acked << "@" << a0.ack_time
-        << "}, sent_packet:" << sent_packet;
-  }
-  return sample;
-}
-
-bool BandwidthSampler::ChooseA0Point(QuicByteCount total_bytes_acked,
-                                     AckPoint* a0) {
-  if (a0_candidates_.empty()) {
-    QUIC_BUG(quic_bug_10437_5)
-        << "No A0 point candicates. total_bytes_acked:" << total_bytes_acked;
-    return false;
-  }
-
-  if (a0_candidates_.size() == 1) {
-    *a0 = a0_candidates_.front();
-    return true;
-  }
-
-  for (size_t i = 1; i < a0_candidates_.size(); ++i) {
-    if (a0_candidates_[i].total_bytes_acked > total_bytes_acked) {
-      *a0 = a0_candidates_[i - 1];
-      if (i > 1) {
-        a0_candidates_.pop_front_n(i - 1);
-      }
-      return true;
-    }
-  }
-
-  // All candidates' total_bytes_acked is <= |total_bytes_acked|.
-  *a0 = a0_candidates_.back();
-  a0_candidates_.pop_front_n(a0_candidates_.size() - 1);
-  return true;
-}
-
-SendTimeState BandwidthSampler::OnPacketLost(QuicPacketNumber packet_number,
-                                             QuicPacketLength bytes_lost) {
-  // TODO(vasilvv): see the comment for the case of missing packets in
-  // BandwidthSampler::OnPacketAcknowledged on why this does not raise a
-  // QUIC_BUG when removal fails.
-  SendTimeState send_time_state;
-
-  total_bytes_lost_ += bytes_lost;
-  ConnectionStateOnSentPacket* sent_packet_pointer =
-      connection_state_map_.GetEntry(packet_number);
-  if (sent_packet_pointer != nullptr) {
-    SentPacketToSendTimeState(*sent_packet_pointer, &send_time_state);
-  }
-
-  return send_time_state;
-}
-
-void BandwidthSampler::SentPacketToSendTimeState(
-    const ConnectionStateOnSentPacket& sent_packet,
-    SendTimeState* send_time_state) const {
-  *send_time_state = sent_packet.send_time_state;
-  send_time_state->is_valid = true;
-}
-
-void BandwidthSampler::OnAppLimited() {
-  is_app_limited_ = true;
-  end_of_app_limited_phase_ = last_sent_packet_;
-}
-
-void BandwidthSampler::RemoveObsoletePackets(QuicPacketNumber least_unacked) {
-  // A packet can become obsolete when it is removed from QuicUnackedPacketMap's
-  // view of inflight before it is acked or marked as lost. For example, when
-  // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet,
-  // the packet is removed from QuicUnackedPacketMap's inflight, but is not
-  // marked as acked or lost in the BandwidthSampler.
-  connection_state_map_.RemoveUpTo(least_unacked);
-}
-
-QuicByteCount BandwidthSampler::total_bytes_sent() const {
-  return total_bytes_sent_;
-}
-
-QuicByteCount BandwidthSampler::total_bytes_acked() const {
-  return total_bytes_acked_;
-}
-
-QuicByteCount BandwidthSampler::total_bytes_lost() const {
-  return total_bytes_lost_;
-}
-
-QuicByteCount BandwidthSampler::total_bytes_neutered() const {
-  return total_bytes_neutered_;
-}
-
-bool BandwidthSampler::is_app_limited() const {
-  return is_app_limited_;
-}
-
-QuicPacketNumber BandwidthSampler::end_of_app_limited_phase() const {
-  return end_of_app_limited_phase_;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bandwidth_sampler.h b/quic/core/congestion_control/bandwidth_sampler.h
deleted file mode 100644
index 60e822a..0000000
--- a/quic/core/congestion_control/bandwidth_sampler.h
+++ /dev/null
@@ -1,627 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/packet_number_indexed_queue.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class BandwidthSamplerPeer;
-}  // namespace test
-
-// A subset of BandwidthSampler::ConnectionStateOnSentPacket which is returned
-// to the caller when the packet is acked or lost.
-struct QUIC_EXPORT_PRIVATE SendTimeState {
-  SendTimeState()
-      : is_valid(false),
-        is_app_limited(false),
-        total_bytes_sent(0),
-        total_bytes_acked(0),
-        total_bytes_lost(0),
-        bytes_in_flight(0) {}
-
-  SendTimeState(bool is_app_limited,
-                QuicByteCount total_bytes_sent,
-                QuicByteCount total_bytes_acked,
-                QuicByteCount total_bytes_lost,
-                QuicByteCount bytes_in_flight)
-      : is_valid(true),
-        is_app_limited(is_app_limited),
-        total_bytes_sent(total_bytes_sent),
-        total_bytes_acked(total_bytes_acked),
-        total_bytes_lost(total_bytes_lost),
-        bytes_in_flight(bytes_in_flight) {}
-
-  SendTimeState(const SendTimeState& other) = default;
-  SendTimeState& operator=(const SendTimeState& other) = default;
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                      const SendTimeState& s);
-
-  // Whether other states in this object is valid.
-  bool is_valid;
-
-  // Whether the sender is app limited at the time the packet was sent.
-  // App limited bandwidth sample might be artificially low because the sender
-  // did not have enough data to send in order to saturate the link.
-  bool is_app_limited;
-
-  // Total number of sent bytes at the time the packet was sent.
-  // Includes the packet itself.
-  QuicByteCount total_bytes_sent;
-
-  // Total number of acked bytes at the time the packet was sent.
-  QuicByteCount total_bytes_acked;
-
-  // Total number of lost bytes at the time the packet was sent.
-  QuicByteCount total_bytes_lost;
-
-  // Total number of inflight bytes at the time the packet was sent.
-  // Includes the packet itself.
-  // It should be equal to |total_bytes_sent| minus the sum of
-  // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes.
-  QuicByteCount bytes_in_flight;
-};
-
-struct QUIC_NO_EXPORT ExtraAckedEvent {
-  // The excess bytes acknowlwedged in the time delta for this event.
-  QuicByteCount extra_acked = 0;
-
-  // The bytes acknowledged and time delta from the event.
-  QuicByteCount bytes_acked = 0;
-  QuicTime::Delta time_delta = QuicTime::Delta::Zero();
-  // The round trip of the event.
-  QuicRoundTripCount round = 0;
-
-  bool operator>=(const ExtraAckedEvent& other) const {
-    return extra_acked >= other.extra_acked;
-  }
-  bool operator==(const ExtraAckedEvent& other) const {
-    return extra_acked == other.extra_acked;
-  }
-};
-
-struct QUIC_EXPORT_PRIVATE BandwidthSample {
-  // The bandwidth at that particular sample. Zero if no valid bandwidth sample
-  // is available.
-  QuicBandwidth bandwidth = QuicBandwidth::Zero();
-
-  // The RTT measurement at this particular sample.  Zero if no RTT sample is
-  // available.  Does not correct for delayed ack time.
-  QuicTime::Delta rtt = QuicTime::Delta::Zero();
-
-  // |send_rate| is computed from the current packet being acked('P') and an
-  // earlier packet that is acked before P was sent.
-  QuicBandwidth send_rate = QuicBandwidth::Infinite();
-
-  // States captured when the packet was sent.
-  SendTimeState state_at_send;
-};
-
-// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every
-// ack event to keep track the degree of ack aggregation(a.k.a "ack height").
-class QUIC_EXPORT_PRIVATE MaxAckHeightTracker {
- public:
-  explicit MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)
-      : max_ack_height_filter_(initial_filter_window, ExtraAckedEvent(), 0) {}
-
-  QuicByteCount Get() const {
-    return max_ack_height_filter_.GetBest().extra_acked;
-  }
-
-  QuicByteCount Update(QuicBandwidth bandwidth_estimate,
-                       bool is_new_max_bandwidth,
-                       QuicRoundTripCount round_trip_count,
-                       QuicPacketNumber last_sent_packet_number,
-                       QuicPacketNumber last_acked_packet_number,
-                       QuicTime ack_time, QuicByteCount bytes_acked);
-
-  void SetFilterWindowLength(QuicRoundTripCount length) {
-    max_ack_height_filter_.SetWindowLength(length);
-  }
-
-  void Reset(QuicByteCount new_height, QuicRoundTripCount new_time) {
-    ExtraAckedEvent new_event;
-    new_event.extra_acked = new_height;
-    new_event.round = new_time;
-    max_ack_height_filter_.Reset(new_event, new_time);
-  }
-
-  void SetAckAggregationBandwidthThreshold(double threshold) {
-    ack_aggregation_bandwidth_threshold_ = threshold;
-  }
-
-  void SetStartNewAggregationEpochAfterFullRound(bool value) {
-    start_new_aggregation_epoch_after_full_round_ = value;
-  }
-
-  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
-    reduce_extra_acked_on_bandwidth_increase_ = value;
-  }
-
-  double ack_aggregation_bandwidth_threshold() const {
-    return ack_aggregation_bandwidth_threshold_;
-  }
-
-  uint64_t num_ack_aggregation_epochs() const {
-    return num_ack_aggregation_epochs_;
-  }
-
- private:
-  // Tracks the maximum number of bytes acked faster than the estimated
-  // bandwidth.
-  using MaxAckHeightFilter =
-      WindowedFilter<ExtraAckedEvent, MaxFilter<ExtraAckedEvent>,
-                     QuicRoundTripCount, QuicRoundTripCount>;
-  MaxAckHeightFilter max_ack_height_filter_;
-
-  // The time this aggregation started and the number of bytes acked during it.
-  QuicTime aggregation_epoch_start_time_ = QuicTime::Zero();
-  QuicByteCount aggregation_epoch_bytes_ = 0;
-  // The last sent packet number before the current aggregation epoch started.
-  QuicPacketNumber last_sent_packet_number_before_epoch_;
-  // The number of ack aggregation epochs ever started, including the ongoing
-  // one. Stats only.
-  uint64_t num_ack_aggregation_epochs_ = 0;
-  double ack_aggregation_bandwidth_threshold_ =
-      GetQuicFlag(FLAGS_quic_ack_aggregation_bandwidth_threshold);
-  bool start_new_aggregation_epoch_after_full_round_ = false;
-  bool reduce_extra_acked_on_bandwidth_increase_ = false;
-};
-
-// An interface common to any class that can provide bandwidth samples from the
-// information per individual acknowledged packet.
-class QUIC_EXPORT_PRIVATE BandwidthSamplerInterface {
- public:
-  virtual ~BandwidthSamplerInterface() {}
-
-  // Inputs the sent packet information into the sampler. Assumes that all
-  // packets are sent in order. The information about the packet will not be
-  // released from the sampler until it the packet is either acknowledged or
-  // declared lost.
-  virtual void OnPacketSent(
-      QuicTime sent_time,
-      QuicPacketNumber packet_number,
-      QuicByteCount bytes,
-      QuicByteCount bytes_in_flight,
-      HasRetransmittableData has_retransmittable_data) = 0;
-
-  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
-
-  struct QUIC_NO_EXPORT CongestionEventSample {
-    // The maximum bandwidth sample from all acked packets.
-    // QuicBandwidth::Zero() if no samples are available.
-    QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
-    // Whether |sample_max_bandwidth| is from a app-limited sample.
-    bool sample_is_app_limited = false;
-    // The minimum rtt sample from all acked packets.
-    // QuicTime::Delta::Infinite() if no samples are available.
-    QuicTime::Delta sample_rtt = QuicTime::Delta::Infinite();
-    // For each packet p in acked packets, this is the max value of INFLIGHT(p),
-    // where INFLIGHT(p) is the number of bytes acked while p is inflight.
-    QuicByteCount sample_max_inflight = 0;
-    // The send state of the largest packet in acked_packets, unless it is
-    // empty. If acked_packets is empty, it's the send state of the largest
-    // packet in lost_packets.
-    SendTimeState last_packet_send_state;
-    // The number of extra bytes acked from this ack event, compared to what is
-    // expected from the flow's bandwidth. Larger value means more ack
-    // aggregation.
-    QuicByteCount extra_acked = 0;
-  };
-  // Notifies the sampler that at |ack_time|, all packets in |acked_packets|
-  // have been acked, and all packets in |lost_packets| have been lost.
-  // See the comments in CongestionEventSample for the return value.
-  // |max_bandwidth| is the windowed maximum observed bandwidth.
-  // |est_bandwidth_upper_bound| is an upper bound of estimated bandwidth used
-  // to calculate extra_acked.
-  virtual CongestionEventSample OnCongestionEvent(
-      QuicTime ack_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      QuicBandwidth max_bandwidth,
-      QuicBandwidth est_bandwidth_upper_bound,
-      QuicRoundTripCount round_trip_count) = 0;
-
-  // Informs the sampler that the connection is currently app-limited, causing
-  // the sampler to enter the app-limited phase.  The phase will expire by
-  // itself.
-  virtual void OnAppLimited() = 0;
-
-  // Remove all the packets lower than the specified packet number.
-  virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0;
-
-  // Total number of bytes sent/acked/lost/neutered in the connection.
-  virtual QuicByteCount total_bytes_sent() const = 0;
-  virtual QuicByteCount total_bytes_acked() const = 0;
-  virtual QuicByteCount total_bytes_lost() const = 0;
-  virtual QuicByteCount total_bytes_neutered() const = 0;
-
-  // Application-limited information exported for debugging.
-  virtual bool is_app_limited() const = 0;
-
-  virtual QuicPacketNumber end_of_app_limited_phase() const = 0;
-};
-
-// BandwidthSampler keeps track of sent and acknowledged packets and outputs a
-// bandwidth sample for every packet acknowledged. The samples are taken for
-// individual packets, and are not filtered; the consumer has to filter the
-// bandwidth samples itself. In certain cases, the sampler will locally severely
-// underestimate the bandwidth, hence a maximum filter with a size of at least
-// one RTT is recommended.
-//
-// This class bases its samples on the slope of two curves: the number of bytes
-// sent over time, and the number of bytes acknowledged as received over time.
-// It produces a sample of both slopes for every packet that gets acknowledged,
-// based on a slope between two points on each of the corresponding curves. Note
-// that due to the packet loss, the number of bytes on each curve might get
-// further and further away from each other, meaning that it is not feasible to
-// compare byte values coming from different curves with each other.
-//
-// The obvious points for measuring slope sample are the ones corresponding to
-// the packet that was just acknowledged. Let us denote them as S_1 (point at
-// which the current packet was sent) and A_1 (point at which the current packet
-// was acknowledged). However, taking a slope requires two points on each line,
-// so estimating bandwidth requires picking a packet in the past with respect to
-// which the slope is measured.
-//
-// For that purpose, BandwidthSampler always keeps track of the most recently
-// acknowledged packet, and records it together with every outgoing packet.
-// When a packet gets acknowledged (A_1), it has not only information about when
-// it itself was sent (S_1), but also the information about a previously
-// acknowledged packet before it was sent (S_0 and A_0).
-//
-// Based on that data, send and ack rate are estimated as:
-//   send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0))
-//   ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0))
-//
-// Here, the ack rate is intuitively the rate we want to treat as bandwidth.
-// However, in certain cases (e.g. ack compression) the ack rate at a point may
-// end up higher than the rate at which the data was originally sent, which is
-// not indicative of the real bandwidth. Hence, we use the send rate as an upper
-// bound, and the sample value is
-//   rate_sample = min(send_rate, ack_rate)
-//
-// An important edge case handled by the sampler is tracking the app-limited
-// samples. There are multiple meaning of "app-limited" used interchangeably,
-// hence it is important to understand and to be able to distinguish between
-// them.
-//
-// Meaning 1: connection state. The connection is said to be app-limited when
-// there is no outstanding data to send. This means that certain bandwidth
-// samples in the future would not be an accurate indication of the link
-// capacity, and it is important to inform consumer about that. Whenever
-// connection becomes app-limited, the sampler is notified via OnAppLimited()
-// method.
-//
-// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth
-// sampler becomes notified about the connection being app-limited, it enters
-// app-limited phase. In that phase, all *sent* packets are marked as
-// app-limited. Note that the connection itself does not have to be
-// app-limited during the app-limited phase, and in fact it will not be
-// (otherwise how would it send packets?). The boolean flag below indicates
-// whether the sampler is in that phase.
-//
-// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is
-// sent during the app-limited phase, the resulting sample related to the
-// packet will be marked as app-limited.
-//
-// With the terminology issue out of the way, let us consider the question of
-// what kind of situation it addresses.
-//
-// Consider a scenario where we first send packets 1 to 20 at a regular
-// bandwidth, and then immediately run out of data. After a few seconds, we send
-// packets 21 to 60, and only receive ack for 21 between sending packets 40 and
-// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0
-// we use to compute the slope is going to be packet 20, a few seconds apart
-// from the current packet, hence the resulting estimate would be extremely low
-// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21,
-// meaning that the bandwidth sample would exclude the quiescence.
-//
-// Based on the analysis of that scenario, we implement the following rule: once
-// OnAppLimited() is called, all sent packets will produce app-limited samples
-// up until an ack for a packet that was sent after OnAppLimited() was called.
-// Note that while the scenario above is not the only scenario when the
-// connection is app-limited, the approach works in other cases too.
-class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
- public:
-  BandwidthSampler(const QuicUnackedPacketMap* unacked_packet_map,
-                   QuicRoundTripCount max_height_tracker_window_length);
-
-  // Copy states from |other|. This is useful when changing send algorithms in
-  // the middle of a connection.
-  BandwidthSampler(const BandwidthSampler& other);
-  ~BandwidthSampler() override;
-
-  void OnPacketSent(QuicTime sent_time,
-                    QuicPacketNumber packet_number,
-                    QuicByteCount bytes,
-                    QuicByteCount bytes_in_flight,
-                    HasRetransmittableData has_retransmittable_data) override;
-  void OnPacketNeutered(QuicPacketNumber packet_number) override;
-
-  CongestionEventSample OnCongestionEvent(
-      QuicTime ack_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      QuicBandwidth max_bandwidth,
-      QuicBandwidth est_bandwidth_upper_bound,
-      QuicRoundTripCount round_trip_count) override;
-  QuicByteCount OnAckEventEnd(QuicBandwidth bandwidth_estimate,
-                              bool is_new_max_bandwidth,
-                              QuicRoundTripCount round_trip_count);
-
-  void OnAppLimited() override;
-
-  void RemoveObsoletePackets(QuicPacketNumber least_unacked) override;
-
-  QuicByteCount total_bytes_sent() const override;
-  QuicByteCount total_bytes_acked() const override;
-  QuicByteCount total_bytes_lost() const override;
-  QuicByteCount total_bytes_neutered() const override;
-
-  bool is_app_limited() const override;
-
-  QuicPacketNumber end_of_app_limited_phase() const override;
-
-  QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); }
-
-  uint64_t num_ack_aggregation_epochs() const {
-    return max_ack_height_tracker_.num_ack_aggregation_epochs();
-  }
-
-  void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) {
-    max_ack_height_tracker_.SetFilterWindowLength(length);
-  }
-
-  void ResetMaxAckHeightTracker(QuicByteCount new_height,
-                                QuicRoundTripCount new_time) {
-    max_ack_height_tracker_.Reset(new_height, new_time);
-  }
-
-  void SetStartNewAggregationEpochAfterFullRound(bool value) {
-    max_ack_height_tracker_.SetStartNewAggregationEpochAfterFullRound(value);
-  }
-
-  void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
-    limit_max_ack_height_tracker_by_send_rate_ = value;
-  }
-
-  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
-    max_ack_height_tracker_.SetReduceExtraAckedOnBandwidthIncrease(value);
-  }
-
-  // AckPoint represents a point on the ack line.
-  struct QUIC_NO_EXPORT AckPoint {
-    QuicTime ack_time = QuicTime::Zero();
-    QuicByteCount total_bytes_acked = 0;
-
-    friend QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
-                                                   const AckPoint& ack_point) {
-      return os << ack_point.ack_time << ":" << ack_point.total_bytes_acked;
-    }
-  };
-
-  // RecentAckPoints maintains the most recent 2 ack points at distinct times.
-  class QUIC_NO_EXPORT RecentAckPoints {
-   public:
-    void Update(QuicTime ack_time, QuicByteCount total_bytes_acked) {
-      QUICHE_DCHECK_GE(total_bytes_acked, ack_points_[1].total_bytes_acked);
-
-      if (ack_time < ack_points_[1].ack_time) {
-        // This can only happen when time goes backwards, we use the smaller
-        // timestamp for the most recent ack point in that case.
-        // TODO(wub): Add a QUIC_BUG if ack time stops going backwards.
-        ack_points_[1].ack_time = ack_time;
-      } else if (ack_time > ack_points_[1].ack_time) {
-        ack_points_[0] = ack_points_[1];
-        ack_points_[1].ack_time = ack_time;
-      }
-
-      ack_points_[1].total_bytes_acked = total_bytes_acked;
-    }
-
-    void Clear() { ack_points_[0] = ack_points_[1] = AckPoint(); }
-
-    const AckPoint& MostRecentPoint() const { return ack_points_[1]; }
-
-    const AckPoint& LessRecentPoint() const {
-      if (ack_points_[0].total_bytes_acked != 0) {
-        return ack_points_[0];
-      }
-
-      return ack_points_[1];
-    }
-
-   private:
-    AckPoint ack_points_[2];
-  };
-
-  void EnableOverestimateAvoidance();
-  bool IsOverestimateAvoidanceEnabled() const {
-    return overestimate_avoidance_;
-  }
-
- private:
-  friend class test::BandwidthSamplerPeer;
-
-  // ConnectionStateOnSentPacket represents the information about a sent packet
-  // and the state of the connection at the moment the packet was sent,
-  // specifically the information about the most recently acknowledged packet at
-  // that moment.
-  struct QUIC_EXPORT_PRIVATE ConnectionStateOnSentPacket {
-    // Time at which the packet is sent.
-    QuicTime sent_time;
-
-    // Size of the packet.
-    QuicByteCount size;
-
-    // The value of |total_bytes_sent_at_last_acked_packet_| at the time the
-    // packet was sent.
-    QuicByteCount total_bytes_sent_at_last_acked_packet;
-
-    // The value of |last_acked_packet_sent_time_| at the time the packet was
-    // sent.
-    QuicTime last_acked_packet_sent_time;
-
-    // The value of |last_acked_packet_ack_time_| at the time the packet was
-    // sent.
-    QuicTime last_acked_packet_ack_time;
-
-    // Send time states that are returned to the congestion controller when the
-    // packet is acked or lost.
-    SendTimeState send_time_state;
-
-    // Snapshot constructor. Records the current state of the bandwidth
-    // sampler.
-    // |bytes_in_flight| is the bytes in flight right after the packet is sent.
-    ConnectionStateOnSentPacket(QuicTime sent_time,
-                                QuicByteCount size,
-                                QuicByteCount bytes_in_flight,
-                                const BandwidthSampler& sampler)
-        : sent_time(sent_time),
-          size(size),
-          total_bytes_sent_at_last_acked_packet(
-              sampler.total_bytes_sent_at_last_acked_packet_),
-          last_acked_packet_sent_time(sampler.last_acked_packet_sent_time_),
-          last_acked_packet_ack_time(sampler.last_acked_packet_ack_time_),
-          send_time_state(sampler.is_app_limited_,
-                          sampler.total_bytes_sent_,
-                          sampler.total_bytes_acked_,
-                          sampler.total_bytes_lost_,
-                          bytes_in_flight) {}
-
-    // Default constructor.  Required to put this structure into
-    // PacketNumberIndexedQueue.
-    ConnectionStateOnSentPacket()
-        : sent_time(QuicTime::Zero()),
-          size(0),
-          total_bytes_sent_at_last_acked_packet(0),
-          last_acked_packet_sent_time(QuicTime::Zero()),
-          last_acked_packet_ack_time(QuicTime::Zero()) {}
-
-    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-        std::ostream& os,
-        const ConnectionStateOnSentPacket& p) {
-      os << "{sent_time:" << p.sent_time << ", size:" << p.size
-         << ", total_bytes_sent_at_last_acked_packet:"
-         << p.total_bytes_sent_at_last_acked_packet
-         << ", last_acked_packet_sent_time:" << p.last_acked_packet_sent_time
-         << ", last_acked_packet_ack_time:" << p.last_acked_packet_ack_time
-         << ", send_time_state:" << p.send_time_state << "}";
-      return os;
-    }
-  };
-
-  BandwidthSample OnPacketAcknowledged(QuicTime ack_time,
-                                       QuicPacketNumber packet_number);
-
-  SendTimeState OnPacketLost(QuicPacketNumber packet_number,
-                             QuicPacketLength bytes_lost);
-
-  // Copy a subset of the (private) ConnectionStateOnSentPacket to the (public)
-  // SendTimeState. Always set send_time_state->is_valid to true.
-  void SentPacketToSendTimeState(const ConnectionStateOnSentPacket& sent_packet,
-                                 SendTimeState* send_time_state) const;
-
-  // Choose the best a0 from |a0_candidates_| to calculate the ack rate.
-  // |total_bytes_acked| is the total bytes acked when the packet being acked is
-  // sent. The best a0 is chosen as follows:
-  // - If there's only one candidate, use it.
-  // - If there are multiple candidates, let a[n] be the nth candidate, and
-  //   a[n-1].total_bytes_acked <= |total_bytes_acked| < a[n].total_bytes_acked,
-  //   use a[n-1].
-  // - If all candidates's total_bytes_acked is > |total_bytes_acked|, use a[0].
-  //   This may happen when acks are received out of order, and ack[n] caused
-  //   some candidates of ack[n-x] to be removed.
-  // - If all candidates's total_bytes_acked is <= |total_bytes_acked|, use
-  //   a[a.size()-1].
-  bool ChooseA0Point(QuicByteCount total_bytes_acked, AckPoint* a0);
-
-  // The total number of congestion controlled bytes sent during the connection.
-  QuicByteCount total_bytes_sent_;
-
-  // The total number of congestion controlled bytes which were acknowledged.
-  QuicByteCount total_bytes_acked_;
-
-  // The total number of congestion controlled bytes which were lost.
-  QuicByteCount total_bytes_lost_;
-
-  // The total number of congestion controlled bytes which have been neutered.
-  QuicByteCount total_bytes_neutered_;
-
-  // The value of |total_bytes_sent_| at the time the last acknowledged packet
-  // was sent. Valid only when |last_acked_packet_sent_time_| is valid.
-  QuicByteCount total_bytes_sent_at_last_acked_packet_;
-
-  // The time at which the last acknowledged packet was sent. Set to
-  // QuicTime::Zero() if no valid timestamp is available.
-  QuicTime last_acked_packet_sent_time_;
-
-  // The time at which the most recent packet was acknowledged.
-  QuicTime last_acked_packet_ack_time_;
-
-  // The most recently sent packet.
-  QuicPacketNumber last_sent_packet_;
-
-  // The most recently acked packet.
-  QuicPacketNumber last_acked_packet_;
-
-  // Indicates whether the bandwidth sampler is currently in an app-limited
-  // phase.
-  bool is_app_limited_;
-
-  // The packet that will be acknowledged after this one will cause the sampler
-  // to exit the app-limited phase.
-  QuicPacketNumber end_of_app_limited_phase_;
-
-  // Record of the connection state at the point where each packet in flight was
-  // sent, indexed by the packet number.
-  PacketNumberIndexedQueue<ConnectionStateOnSentPacket> connection_state_map_;
-
-  RecentAckPoints recent_ack_points_;
-  quiche::QuicheCircularDeque<AckPoint> a0_candidates_;
-
-  // Maximum number of tracked packets.
-  const QuicPacketCount max_tracked_packets_;
-
-  // The main unacked packet map.  Used for outputting extra debugging details.
-  // May be null.
-  // TODO(vasilvv): remove this once it's no longer useful for debugging.
-  const QuicUnackedPacketMap* unacked_packet_map_;
-
-  // Handles the actual bandwidth calculations, whereas the outer method handles
-  // retrieving and removing |sent_packet|.
-  BandwidthSample OnPacketAcknowledgedInner(
-      QuicTime ack_time,
-      QuicPacketNumber packet_number,
-      const ConnectionStateOnSentPacket& sent_packet);
-
-  MaxAckHeightTracker max_ack_height_tracker_;
-  QuicByteCount total_bytes_acked_after_last_ack_event_;
-
-  // True if connection option 'BSAO' is set.
-  bool overestimate_avoidance_;
-
-  // True if connection option 'BBRB' is set.
-  bool limit_max_ack_height_tracker_by_send_rate_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
diff --git a/quic/core/congestion_control/bandwidth_sampler_test.cc b/quic/core/congestion_control/bandwidth_sampler_test.cc
deleted file mode 100644
index 7babb1f..0000000
--- a/quic/core/congestion_control/bandwidth_sampler_test.cc
+++ /dev/null
@@ -1,889 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include <cstdint>
-#include <set>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class BandwidthSamplerPeer {
- public:
-  static size_t GetNumberOfTrackedPackets(const BandwidthSampler& sampler) {
-    return sampler.connection_state_map_.number_of_present_entries();
-  }
-
-  static QuicByteCount GetPacketSize(const BandwidthSampler& sampler,
-                                     QuicPacketNumber packet_number) {
-    return sampler.connection_state_map_.GetEntry(packet_number)->size;
-  }
-};
-
-const QuicByteCount kRegularPacketSize = 1280;
-// Enforce divisibility for some of the tests.
-static_assert((kRegularPacketSize & 31) == 0,
-              "kRegularPacketSize has to be five times divisible by 2");
-
-struct TestParameters {
-  bool overestimate_avoidance;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParameters& p) {
-  return p.overestimate_avoidance ? "enable_overestimate_avoidance"
-                                  : "no_enable_overestimate_avoidance";
-}
-
-// A test fixture with utility methods for BandwidthSampler tests.
-class BandwidthSamplerTest : public QuicTestWithParam<TestParameters> {
- protected:
-  BandwidthSamplerTest()
-      : sampler_(nullptr, /*max_height_tracker_window_length=*/0),
-        sampler_app_limited_at_start_(sampler_.is_app_limited()),
-        bytes_in_flight_(0),
-        max_bandwidth_(QuicBandwidth::Zero()),
-        est_bandwidth_upper_bound_(QuicBandwidth::Infinite()),
-        round_trip_count_(0) {
-    // Ensure that the clock does not start at zero.
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    if (GetParam().overestimate_avoidance) {
-      sampler_.EnableOverestimateAvoidance();
-    }
-  }
-
-  MockClock clock_;
-  BandwidthSampler sampler_;
-  bool sampler_app_limited_at_start_;
-  QuicByteCount bytes_in_flight_;
-  QuicBandwidth max_bandwidth_;  // Max observed bandwidth from acks.
-  QuicBandwidth est_bandwidth_upper_bound_;
-  QuicRoundTripCount round_trip_count_;  // Needed to calculate extra_acked.
-
-  QuicByteCount PacketsToBytes(QuicPacketCount packet_count) {
-    return packet_count * kRegularPacketSize;
-  }
-
-  void SendPacketInner(uint64_t packet_number,
-                       QuicByteCount bytes,
-                       HasRetransmittableData has_retransmittable_data) {
-    sampler_.OnPacketSent(clock_.Now(), QuicPacketNumber(packet_number), bytes,
-                          bytes_in_flight_, has_retransmittable_data);
-    if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA) {
-      bytes_in_flight_ += bytes;
-    }
-  }
-
-  void SendPacket(uint64_t packet_number) {
-    SendPacketInner(packet_number, kRegularPacketSize,
-                    HAS_RETRANSMITTABLE_DATA);
-  }
-
-  BandwidthSample AckPacketInner(uint64_t packet_number) {
-    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
-        sampler_, QuicPacketNumber(packet_number));
-    bytes_in_flight_ -= size;
-    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
-        clock_.Now(), {MakeAckedPacket(packet_number)}, {}, max_bandwidth_,
-        est_bandwidth_upper_bound_, round_trip_count_);
-    max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
-    BandwidthSample bandwidth_sample;
-    bandwidth_sample.bandwidth = sample.sample_max_bandwidth;
-    bandwidth_sample.rtt = sample.sample_rtt;
-    bandwidth_sample.state_at_send = sample.last_packet_send_state;
-    EXPECT_TRUE(bandwidth_sample.state_at_send.is_valid);
-    return bandwidth_sample;
-  }
-
-  AckedPacket MakeAckedPacket(uint64_t packet_number) const {
-    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
-        sampler_, QuicPacketNumber(packet_number));
-    return AckedPacket(QuicPacketNumber(packet_number), size, clock_.Now());
-  }
-
-  LostPacket MakeLostPacket(uint64_t packet_number) const {
-    return LostPacket(QuicPacketNumber(packet_number),
-                      BandwidthSamplerPeer::GetPacketSize(
-                          sampler_, QuicPacketNumber(packet_number)));
-  }
-
-  // Acknowledge receipt of a packet and expect it to be not app-limited.
-  QuicBandwidth AckPacket(uint64_t packet_number) {
-    BandwidthSample sample = AckPacketInner(packet_number);
-    return sample.bandwidth;
-  }
-
-  BandwidthSampler::CongestionEventSample OnCongestionEvent(
-      std::set<uint64_t> acked_packet_numbers,
-      std::set<uint64_t> lost_packet_numbers) {
-    AckedPacketVector acked_packets;
-    for (auto it = acked_packet_numbers.begin();
-         it != acked_packet_numbers.end(); ++it) {
-      acked_packets.push_back(MakeAckedPacket(*it));
-      bytes_in_flight_ -= acked_packets.back().bytes_acked;
-    }
-
-    LostPacketVector lost_packets;
-    for (auto it = lost_packet_numbers.begin(); it != lost_packet_numbers.end();
-         ++it) {
-      lost_packets.push_back(MakeLostPacket(*it));
-      bytes_in_flight_ -= lost_packets.back().bytes_lost;
-    }
-
-    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
-        clock_.Now(), acked_packets, lost_packets, max_bandwidth_,
-        est_bandwidth_upper_bound_, round_trip_count_);
-    max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
-    return sample;
-  }
-
-  SendTimeState LosePacket(uint64_t packet_number) {
-    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
-        sampler_, QuicPacketNumber(packet_number));
-    bytes_in_flight_ -= size;
-    LostPacket lost_packet(QuicPacketNumber(packet_number), size);
-    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
-        clock_.Now(), {}, {lost_packet}, max_bandwidth_,
-        est_bandwidth_upper_bound_, round_trip_count_);
-    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
-    EXPECT_EQ(sample.sample_max_bandwidth, QuicBandwidth::Zero());
-    EXPECT_EQ(sample.sample_rtt, QuicTime::Delta::Infinite());
-    return sample.last_packet_send_state;
-  }
-
-  // Sends one packet and acks it.  Then, send 20 packets.  Finally, send
-  // another 20 packets while acknowledging previous 20.
-  void Send40PacketsAndAckFirst20(QuicTime::Delta time_between_packets) {
-    // Send 20 packets at a constant inter-packet time.
-    for (int i = 1; i <= 20; i++) {
-      SendPacket(i);
-      clock_.AdvanceTime(time_between_packets);
-    }
-
-    // Ack packets 1 to 20, while sending new packets at the same rate as
-    // before.
-    for (int i = 1; i <= 20; i++) {
-      AckPacket(i);
-      SendPacket(i + 20);
-      clock_.AdvanceTime(time_between_packets);
-    }
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    BandwidthSamplerTests,
-    BandwidthSamplerTest,
-    testing::Values(TestParameters{/*overestimate_avoidance=*/false},
-                    TestParameters{/*overestimate_avoidance=*/true}),
-    testing::PrintToStringParamName());
-
-// Test the sampler in a simple stop-and-wait sender setting.
-TEST_P(BandwidthSamplerTest, SendAndWait) {
-  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromBytesPerSecond(kRegularPacketSize * 100);
-
-  // Send packets at the constant bandwidth.
-  for (int i = 1; i < 20; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-    QuicBandwidth current_sample = AckPacket(i);
-    EXPECT_EQ(expected_bandwidth, current_sample);
-  }
-
-  // Send packets at the exponentially decreasing bandwidth.
-  for (int i = 20; i < 25; i++) {
-    time_between_packets = time_between_packets * 2;
-    expected_bandwidth = expected_bandwidth * 0.5;
-
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-    QuicBandwidth current_sample = AckPacket(i);
-    EXPECT_EQ(expected_bandwidth, current_sample);
-  }
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(25));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-TEST_P(BandwidthSamplerTest, SendTimeState) {
-  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
-
-  // Send packets 1-5.
-  for (int i = 1; i <= 5; i++) {
-    SendPacket(i);
-    EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack packet 1.
-  SendTimeState send_time_state = AckPacketInner(1).state_at_send;
-  EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_sent);
-  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
-  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
-  EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_acked());
-
-  // Lose packet 2.
-  send_time_state = LosePacket(2);
-  EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_sent);
-  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
-  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
-  EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_lost());
-
-  // Lose packet 3.
-  send_time_state = LosePacket(3);
-  EXPECT_EQ(PacketsToBytes(3), send_time_state.total_bytes_sent);
-  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
-  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
-  EXPECT_EQ(PacketsToBytes(2), sampler_.total_bytes_lost());
-
-  // Send packets 6-10.
-  for (int i = 6; i <= 10; i++) {
-    SendPacket(i);
-    EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack all inflight packets.
-  QuicPacketCount acked_packet_count = 1;
-  EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
-  for (int i = 4; i <= 10; i++) {
-    send_time_state = AckPacketInner(i).state_at_send;
-    ++acked_packet_count;
-    EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
-    EXPECT_EQ(PacketsToBytes(i), send_time_state.total_bytes_sent);
-    if (i <= 5) {
-      EXPECT_EQ(0u, send_time_state.total_bytes_acked);
-      EXPECT_EQ(0u, send_time_state.total_bytes_lost);
-    } else {
-      EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_acked);
-      EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_lost);
-    }
-
-    // This equation works because there is no neutered bytes.
-    EXPECT_EQ(send_time_state.total_bytes_sent -
-                  send_time_state.total_bytes_acked -
-                  send_time_state.total_bytes_lost,
-              send_time_state.bytes_in_flight);
-
-    clock_.AdvanceTime(time_between_packets);
-  }
-}
-
-// Test the sampler during regular windowed sender scenario with fixed
-// CWND of 20.
-TEST_P(BandwidthSamplerTest, SendPaced) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
-  Send40PacketsAndAckFirst20(time_between_packets);
-
-  // Ack the packets 21 to 40, arriving at the correct bandwidth.
-  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (int i = 21; i <= 40; i++) {
-    last_bandwidth = AckPacket(i);
-    EXPECT_EQ(expected_bandwidth, last_bandwidth) << "i is " << i;
-    clock_.AdvanceTime(time_between_packets);
-  }
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the sampler in a scenario where 50% of packets is consistently lost.
-TEST_P(BandwidthSamplerTest, SendWithLosses) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
-
-  // Send 20 packets, each 1 ms apart.
-  for (int i = 1; i <= 20; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack packets 1 to 20, losing every even-numbered packet, while sending new
-  // packets at the same rate as before.
-  for (int i = 1; i <= 20; i++) {
-    if (i % 2 == 0) {
-      AckPacket(i);
-    } else {
-      LosePacket(i);
-    }
-    SendPacket(i + 20);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack the packets 21 to 40 with the same loss pattern.
-  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (int i = 21; i <= 40; i++) {
-    if (i % 2 == 0) {
-      last_bandwidth = AckPacket(i);
-      EXPECT_EQ(expected_bandwidth, last_bandwidth);
-    } else {
-      LosePacket(i);
-    }
-    clock_.AdvanceTime(time_between_packets);
-  }
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the sampler in a scenario where the 50% of packets are not
-// congestion controlled (specifically, non-retransmittable data is not
-// congestion controlled).  Should be functionally consistent in behavior with
-// the SendWithLosses test.
-TEST_P(BandwidthSamplerTest, NotCongestionControlled) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
-
-  // Send 20 packets, each 1 ms apart. Every even packet is not congestion
-  // controlled.
-  for (int i = 1; i <= 20; i++) {
-    SendPacketInner(
-        i, kRegularPacketSize,
-        i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ensure only congestion controlled packets are tracked.
-  EXPECT_EQ(10u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-
-  // Ack packets 2 to 21, ignoring every even-numbered packet, while sending new
-  // packets at the same rate as before.
-  for (int i = 1; i <= 20; i++) {
-    if (i % 2 == 0) {
-      AckPacket(i);
-    }
-    SendPacketInner(
-        i + 20, kRegularPacketSize,
-        i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack the packets 22 to 41 with the same congestion controlled pattern.
-  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (int i = 21; i <= 40; i++) {
-    if (i % 2 == 0) {
-      last_bandwidth = AckPacket(i);
-      EXPECT_EQ(expected_bandwidth, last_bandwidth);
-    }
-    clock_.AdvanceTime(time_between_packets);
-  }
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
-  // Since only congestion controlled packets are entered into the map, it has
-  // to be empty at this point.
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Simulate a situation where ACKs arrive in burst and earlier than usual, thus
-// producing an ACK rate which is higher than the original send rate.
-TEST_P(BandwidthSamplerTest, CompressedAck) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
-  Send40PacketsAndAckFirst20(time_between_packets);
-
-  // Simulate an RTT somewhat lower than the one for 1-to-21 transmission.
-  clock_.AdvanceTime(time_between_packets * 15);
-
-  // Ack the packets 21 to 40 almost immediately at once.
-  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  QuicTime::Delta ridiculously_small_time_delta =
-      QuicTime::Delta::FromMicroseconds(20);
-  for (int i = 21; i <= 40; i++) {
-    last_bandwidth = AckPacket(i);
-    clock_.AdvanceTime(ridiculously_small_time_delta);
-  }
-  EXPECT_EQ(expected_bandwidth, last_bandwidth);
-
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Tests receiving ACK packets in the reverse order.
-TEST_P(BandwidthSamplerTest, ReorderedAck) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
-  Send40PacketsAndAckFirst20(time_between_packets);
-
-  // Ack the packets 21 to 40 in the reverse order, while sending packets 41 to
-  // 60.
-  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (int i = 0; i < 20; i++) {
-    last_bandwidth = AckPacket(40 - i);
-    EXPECT_EQ(expected_bandwidth, last_bandwidth);
-    SendPacket(41 + i);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack the packets 41 to 60, now in the regular order.
-  for (int i = 41; i <= 60; i++) {
-    last_bandwidth = AckPacket(i);
-    EXPECT_EQ(expected_bandwidth, last_bandwidth);
-    clock_.AdvanceTime(time_between_packets);
-  }
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(61));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the app-limited logic.
-TEST_P(BandwidthSamplerTest, AppLimited) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  QuicBandwidth expected_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
-
-  // Send 20 packets at a constant inter-packet time.
-  for (int i = 1; i <= 20; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack packets 1 to 20, while sending new packets at the same rate as
-  // before.
-  for (int i = 1; i <= 20; i++) {
-    BandwidthSample sample = AckPacketInner(i);
-    EXPECT_EQ(sample.state_at_send.is_app_limited,
-              sampler_app_limited_at_start_);
-    SendPacket(i + 20);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // We are now app-limited. Ack 21 to 40 as usual, but do not send anything for
-  // now.
-  sampler_.OnAppLimited();
-  for (int i = 21; i <= 40; i++) {
-    BandwidthSample sample = AckPacketInner(i);
-    EXPECT_FALSE(sample.state_at_send.is_app_limited);
-    EXPECT_EQ(expected_bandwidth, sample.bandwidth);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Enter quiescence.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
-  // Send packets 41 to 60, all of which would be marked as app-limited.
-  for (int i = 41; i <= 60; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Ack packets 41 to 60, while sending packets 61 to 80.  41 to 60 should be
-  // app-limited and underestimate the bandwidth due to that.
-  for (int i = 41; i <= 60; i++) {
-    BandwidthSample sample = AckPacketInner(i);
-    EXPECT_TRUE(sample.state_at_send.is_app_limited);
-    EXPECT_LT(sample.bandwidth, 0.7f * expected_bandwidth);
-
-    SendPacket(i + 20);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // Run out of packets, and then ack packet 61 to 80, all of which should have
-  // correct non-app-limited samples.
-  for (int i = 61; i <= 80; i++) {
-    BandwidthSample sample = AckPacketInner(i);
-    EXPECT_FALSE(sample.state_at_send.is_app_limited);
-    EXPECT_EQ(sample.bandwidth, expected_bandwidth);
-    clock_.AdvanceTime(time_between_packets);
-  }
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(81));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  EXPECT_EQ(0u, bytes_in_flight_);
-}
-
-// Test the samples taken at the first flight of packets sent.
-TEST_P(BandwidthSamplerTest, FirstRoundTrip) {
-  const QuicTime::Delta time_between_packets =
-      QuicTime::Delta::FromMilliseconds(1);
-  const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(800);
-  const int num_packets = 10;
-  const QuicByteCount num_bytes = kRegularPacketSize * num_packets;
-  const QuicBandwidth real_bandwidth =
-      QuicBandwidth::FromBytesAndTimeDelta(num_bytes, rtt);
-
-  for (int i = 1; i <= 10; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  clock_.AdvanceTime(rtt - num_packets * time_between_packets);
-
-  QuicBandwidth last_sample = QuicBandwidth::Zero();
-  for (int i = 1; i <= 10; i++) {
-    QuicBandwidth sample = AckPacket(i);
-    EXPECT_GT(sample, last_sample);
-    last_sample = sample;
-    clock_.AdvanceTime(time_between_packets);
-  }
-
-  // The final measured sample for the first flight of sample is expected to be
-  // smaller than the real bandwidth, yet it should not lose more than 10%. The
-  // specific value of the error depends on the difference between the RTT and
-  // the time it takes to exhaust the congestion window (i.e. in the limit when
-  // all packets are sent simultaneously, last sample would indicate the real
-  // bandwidth).
-  EXPECT_LT(last_sample, real_bandwidth);
-  EXPECT_GT(last_sample, 0.9f * real_bandwidth);
-}
-
-// Test sampler's ability to remove obsolete packets.
-TEST_P(BandwidthSamplerTest, RemoveObsoletePackets) {
-  SendPacket(1);
-  SendPacket(2);
-  SendPacket(3);
-  SendPacket(4);
-  SendPacket(5);
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-
-  EXPECT_EQ(5u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(4));
-  EXPECT_EQ(2u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  LosePacket(4);
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(5));
-
-  EXPECT_EQ(1u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  AckPacket(5);
-
-  sampler_.RemoveObsoletePackets(QuicPacketNumber(6));
-
-  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-}
-
-TEST_P(BandwidthSamplerTest, NeuterPacket) {
-  SendPacket(1);
-  EXPECT_EQ(0u, sampler_.total_bytes_neutered());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  sampler_.OnPacketNeutered(QuicPacketNumber(1));
-  EXPECT_LT(0u, sampler_.total_bytes_neutered());
-  EXPECT_EQ(0u, sampler_.total_bytes_acked());
-
-  // If packet 1 is acked it should not produce a bandwidth sample.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
-      clock_.Now(),
-      {AckedPacket(QuicPacketNumber(1), kRegularPacketSize, clock_.Now())}, {},
-      max_bandwidth_, est_bandwidth_upper_bound_, round_trip_count_);
-  EXPECT_EQ(0u, sampler_.total_bytes_acked());
-  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
-  EXPECT_FALSE(sample.sample_is_app_limited);
-  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
-  EXPECT_EQ(0u, sample.sample_max_inflight);
-  EXPECT_EQ(0u, sample.extra_acked);
-}
-
-TEST_P(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
-  // Make sure a default constructed CongestionEventSample has the correct
-  // initial values for BandwidthSampler::OnCongestionEvent() to work.
-  BandwidthSampler::CongestionEventSample sample;
-
-  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
-  EXPECT_FALSE(sample.sample_is_app_limited);
-  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
-  EXPECT_EQ(0u, sample.sample_max_inflight);
-  EXPECT_EQ(0u, sample.extra_acked);
-}
-
-// 1) Send 2 packets, 2) Ack both in 1 event, 3) Repeat.
-TEST_P(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
-  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
-  QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      kRegularPacketSize, time_between_packets);
-
-  for (uint64_t i = 1; i < 21; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-    if (i % 2 != 0) {
-      continue;
-    }
-
-    BandwidthSampler::CongestionEventSample sample =
-        OnCongestionEvent({i - 1, i}, {});
-    EXPECT_EQ(sending_rate, sample.sample_max_bandwidth);
-    EXPECT_EQ(time_between_packets, sample.sample_rtt);
-    EXPECT_EQ(2 * kRegularPacketSize, sample.sample_max_inflight);
-    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
-    EXPECT_EQ(2 * kRegularPacketSize,
-              sample.last_packet_send_state.bytes_in_flight);
-    EXPECT_EQ(i * kRegularPacketSize,
-              sample.last_packet_send_state.total_bytes_sent);
-    EXPECT_EQ((i - 2) * kRegularPacketSize,
-              sample.last_packet_send_state.total_bytes_acked);
-    EXPECT_EQ(0u, sample.last_packet_send_state.total_bytes_lost);
-    sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
-  }
-}
-
-TEST_P(BandwidthSamplerTest, LoseEveryOtherPacket) {
-  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
-  QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      kRegularPacketSize, time_between_packets);
-
-  for (uint64_t i = 1; i < 21; i++) {
-    SendPacket(i);
-    clock_.AdvanceTime(time_between_packets);
-    if (i % 2 != 0) {
-      continue;
-    }
-
-    // Ack packet i and lose i-1.
-    BandwidthSampler::CongestionEventSample sample =
-        OnCongestionEvent({i}, {i - 1});
-    // Losing 50% packets means sending rate is twice the bandwidth.
-    EXPECT_EQ(sending_rate, sample.sample_max_bandwidth * 2);
-    EXPECT_EQ(time_between_packets, sample.sample_rtt);
-    EXPECT_EQ(kRegularPacketSize, sample.sample_max_inflight);
-    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
-    EXPECT_EQ(2 * kRegularPacketSize,
-              sample.last_packet_send_state.bytes_in_flight);
-    EXPECT_EQ(i * kRegularPacketSize,
-              sample.last_packet_send_state.total_bytes_sent);
-    EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
-              sample.last_packet_send_state.total_bytes_acked);
-    EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
-              sample.last_packet_send_state.total_bytes_lost);
-    sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
-  }
-}
-
-TEST_P(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
-  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
-  QuicBandwidth first_packet_sending_rate =
-      QuicBandwidth::FromBytesAndTimeDelta(kRegularPacketSize,
-                                           time_between_packets);
-
-  // Send packets 1 to 4 and ack packet 1.
-  SendPacket(1);
-  clock_.AdvanceTime(time_between_packets);
-  SendPacket(2);
-  SendPacket(3);
-  SendPacket(4);
-  BandwidthSampler::CongestionEventSample sample = OnCongestionEvent({1}, {});
-  EXPECT_EQ(first_packet_sending_rate, sample.sample_max_bandwidth);
-  EXPECT_EQ(first_packet_sending_rate, max_bandwidth_);
-
-  // Ack packet 2, 3 and 4, all of which uses S(1) to calculate ack rate since
-  // there were no acks at the time they were sent.
-  round_trip_count_++;
-  est_bandwidth_upper_bound_ = first_packet_sending_rate * 0.3;
-  clock_.AdvanceTime(time_between_packets);
-  sample = OnCongestionEvent({2, 3, 4}, {});
-  EXPECT_EQ(first_packet_sending_rate * 2, sample.sample_max_bandwidth);
-  EXPECT_EQ(max_bandwidth_, sample.sample_max_bandwidth);
-
-  EXPECT_LT(2 * kRegularPacketSize, sample.extra_acked);
-}
-
-class MaxAckHeightTrackerTest : public QuicTest {
- protected:
-  MaxAckHeightTrackerTest() : tracker_(/*initial_filter_window=*/10) {
-    tracker_.SetAckAggregationBandwidthThreshold(1.8);
-    tracker_.SetStartNewAggregationEpochAfterFullRound(true);
-  }
-
-  // Run a full aggregation episode, which is one or more aggregated acks,
-  // followed by a quiet period in which no ack happens.
-  // After this function returns, the time is set to the earliest point at which
-  // any ack event will cause tracker_.Update() to start a new aggregation.
-  void AggregationEpisode(QuicBandwidth aggregation_bandwidth,
-                          QuicTime::Delta aggregation_duration,
-                          QuicByteCount bytes_per_ack,
-                          bool expect_new_aggregation_epoch) {
-    ASSERT_GE(aggregation_bandwidth, bandwidth_);
-    const QuicTime start_time = now_;
-
-    const QuicByteCount aggregation_bytes =
-        aggregation_bandwidth * aggregation_duration;
-
-    const int num_acks = aggregation_bytes / bytes_per_ack;
-    ASSERT_EQ(aggregation_bytes, num_acks * bytes_per_ack)
-        << "aggregation_bytes: " << aggregation_bytes << " ["
-        << aggregation_bandwidth << " in " << aggregation_duration
-        << "], bytes_per_ack: " << bytes_per_ack;
-
-    const QuicTime::Delta time_between_acks = QuicTime::Delta::FromMicroseconds(
-        aggregation_duration.ToMicroseconds() / num_acks);
-    ASSERT_EQ(aggregation_duration, num_acks * time_between_acks)
-        << "aggregation_bytes: " << aggregation_bytes
-        << ", num_acks: " << num_acks
-        << ", time_between_acks: " << time_between_acks;
-
-    // The total duration of aggregation time and quiet period.
-    const QuicTime::Delta total_duration = QuicTime::Delta::FromMicroseconds(
-        aggregation_bytes * 8 * 1000000 / bandwidth_.ToBitsPerSecond());
-    ASSERT_EQ(aggregation_bytes, total_duration * bandwidth_)
-        << "total_duration: " << total_duration
-        << ", bandwidth_: " << bandwidth_;
-
-    QuicByteCount last_extra_acked = 0;
-    for (QuicByteCount bytes = 0; bytes < aggregation_bytes;
-         bytes += bytes_per_ack) {
-      QuicByteCount extra_acked = tracker_.Update(
-          bandwidth_, true, RoundTripCount(), last_sent_packet_number_,
-          last_acked_packet_number_, now_, bytes_per_ack);
-      QUIC_VLOG(1) << "T" << now_ << ": Update after " << bytes_per_ack
-                   << " bytes acked, " << extra_acked << " extra bytes acked";
-      // |extra_acked| should be 0 if either
-      // [1] We are at the beginning of a aggregation epoch(bytes==0) and the
-      //     the current tracker implementation can identify it, or
-      // [2] We are not really aggregating acks.
-      if ((bytes == 0 && expect_new_aggregation_epoch) ||  // [1]
-          (aggregation_bandwidth == bandwidth_)) {         // [2]
-        EXPECT_EQ(0u, extra_acked);
-      } else {
-        EXPECT_LT(last_extra_acked, extra_acked);
-      }
-      now_ = now_ + time_between_acks;
-      last_extra_acked = extra_acked;
-    }
-
-    // Advance past the quiet period.
-    const QuicTime time_after_aggregation = now_;
-    now_ = start_time + total_duration;
-    QUIC_VLOG(1) << "Advanced time from " << time_after_aggregation << " to "
-                 << now_ << ". Aggregation time["
-                 << (time_after_aggregation - start_time) << "], Quiet time["
-                 << (now_ - time_after_aggregation) << "].";
-  }
-
-  QuicRoundTripCount RoundTripCount() const {
-    return (now_ - QuicTime::Zero()).ToMicroseconds() / rtt_.ToMicroseconds();
-  }
-
-  MaxAckHeightTracker tracker_;
-  QuicBandwidth bandwidth_ = QuicBandwidth::FromBytesPerSecond(10 * 1000);
-  QuicTime now_ = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
-  QuicTime::Delta rtt_ = QuicTime::Delta::FromMilliseconds(60);
-  QuicPacketNumber last_sent_packet_number_;
-  QuicPacketNumber last_acked_packet_number_;
-};
-
-TEST_F(MaxAckHeightTrackerTest, VeryAggregatedLargeAck) {
-  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
-                     1200, true);
-  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
-                     1200, true);
-  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
-  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
-    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
-                       1200, true);
-    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
-  } else {
-    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
-                       1200, false);
-    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
-  }
-}
-
-TEST_F(MaxAckHeightTrackerTest, VeryAggregatedSmallAcks) {
-  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
-                     true);
-  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
-                     true);
-  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
-  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
-    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
-                       300, true);
-    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
-  } else {
-    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
-                       300, false);
-    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
-  }
-}
-
-TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedLargeAck) {
-  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
-                     1000, true);
-  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
-                     1000, true);
-  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
-  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
-    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
-                       1000, true);
-    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
-  } else {
-    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
-                       1000, false);
-    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
-  }
-}
-
-TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedSmallAcks) {
-  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
-                     true);
-  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
-                     true);
-  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
-
-  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
-    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
-                       100, true);
-    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
-  } else {
-    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
-                       100, false);
-    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
-  }
-}
-
-TEST_F(MaxAckHeightTrackerTest, NotAggregated) {
-  AggregationEpisode(bandwidth_, QuicTime::Delta::FromMilliseconds(100), 100,
-                     true);
-  EXPECT_LT(2u, tracker_.num_ack_aggregation_epochs());
-}
-
-TEST_F(MaxAckHeightTrackerTest, StartNewEpochAfterAFullRound) {
-  last_sent_packet_number_ = QuicPacketNumber(10);
-  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
-                     true);
-
-  last_acked_packet_number_ = QuicPacketNumber(11);
-  // Update with a tiny bandwidth causes a very low expected bytes acked, which
-  // in turn causes the current epoch to continue if the |tracker_| doesn't
-  // check the packet numbers.
-  tracker_.Update(bandwidth_ * 0.1, true, RoundTripCount(),
-                  last_sent_packet_number_, last_acked_packet_number_, now_,
-                  100);
-
-  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_drain.cc b/quic/core/congestion_control/bbr2_drain.cc
deleted file mode 100644
index 69befb5..0000000
--- a/quic/core/congestion_control/bbr2_drain.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr2_drain.h"
-
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-Bbr2Mode Bbr2DrainMode::OnCongestionEvent(
-    QuicByteCount /*prior_in_flight*/,
-    QuicTime /*event_time*/,
-    const AckedPacketVector& /*acked_packets*/,
-    const LostPacketVector& /*lost_packets*/,
-    const Bbr2CongestionEvent& congestion_event) {
-  model_->set_pacing_gain(Params().drain_pacing_gain);
-
-  // Only STARTUP can transition to DRAIN, both of them use the same cwnd gain.
-  QUICHE_DCHECK_EQ(model_->cwnd_gain(), Params().drain_cwnd_gain);
-  model_->set_cwnd_gain(Params().drain_cwnd_gain);
-
-  QuicByteCount drain_target = DrainTarget();
-  if (congestion_event.bytes_in_flight <= drain_target) {
-    QUIC_DVLOG(3) << sender_ << " Exiting DRAIN. bytes_in_flight:"
-                  << congestion_event.bytes_in_flight
-                  << ", bdp:" << model_->BDP()
-                  << ", drain_target:" << drain_target << "  @ "
-                  << congestion_event.event_time;
-    return Bbr2Mode::PROBE_BW;
-  }
-
-  QUIC_DVLOG(3) << sender_ << " Staying in DRAIN. bytes_in_flight:"
-                << congestion_event.bytes_in_flight << ", bdp:" << model_->BDP()
-                << ", drain_target:" << drain_target << "  @ "
-                << congestion_event.event_time;
-  return Bbr2Mode::DRAIN;
-}
-
-QuicByteCount Bbr2DrainMode::DrainTarget() const {
-  QuicByteCount bdp = model_->BDP();
-  return std::max<QuicByteCount>(bdp, sender_->GetMinimumCongestionWindow());
-}
-
-Bbr2DrainMode::DebugState Bbr2DrainMode::ExportDebugState() const {
-  DebugState s;
-  s.drain_target = DrainTarget();
-  return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const Bbr2DrainMode::DebugState& state) {
-  os << "[DRAIN] drain_target: " << state.drain_target << "\n";
-  return os;
-}
-
-const Bbr2Params& Bbr2DrainMode::Params() const {
-  return sender_->Params();
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_drain.h b/quic/core/congestion_control/bbr2_drain.h
deleted file mode 100644
index 3026320..0000000
--- a/quic/core/congestion_control/bbr2_drain.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2DrainMode final : public Bbr2ModeBase {
- public:
-  using Bbr2ModeBase::Bbr2ModeBase;
-
-  void Enter(QuicTime /*now*/,
-             const Bbr2CongestionEvent* /*congestion_event*/) override {}
-  void Leave(QuicTime /*now*/,
-             const Bbr2CongestionEvent* /*congestion_event*/) override {}
-
-  Bbr2Mode OnCongestionEvent(
-      QuicByteCount prior_in_flight,
-      QuicTime event_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      const Bbr2CongestionEvent& congestion_event) override;
-
-  Limits<QuicByteCount> GetCwndLimits() const override {
-    return NoGreaterThan(model_->inflight_lo());
-  }
-
-  bool IsProbingForBandwidth() const override { return false; }
-
-  Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
-                            QuicTime /*quiescence_start_time*/) override {
-    return Bbr2Mode::DRAIN;
-  }
-
-  struct QUIC_EXPORT_PRIVATE DebugState {
-    QuicByteCount drain_target;
-  };
-
-  DebugState ExportDebugState() const;
-
- private:
-  const Bbr2Params& Params() const;
-
-  QuicByteCount DrainTarget() const;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const Bbr2DrainMode::DebugState& state);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
diff --git a/quic/core/congestion_control/bbr2_misc.cc b/quic/core/congestion_control/bbr2_misc.cc
deleted file mode 100644
index 8472890..0000000
--- a/quic/core/congestion_control/bbr2_misc.cc
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-RoundTripCounter::RoundTripCounter() : round_trip_count_(0) {}
-
-void RoundTripCounter::OnPacketSent(QuicPacketNumber packet_number) {
-  QUICHE_DCHECK(!last_sent_packet_.IsInitialized() ||
-                last_sent_packet_ < packet_number);
-  last_sent_packet_ = packet_number;
-}
-
-bool RoundTripCounter::OnPacketsAcked(QuicPacketNumber last_acked_packet) {
-  if (!end_of_round_trip_.IsInitialized() ||
-      last_acked_packet > end_of_round_trip_) {
-    round_trip_count_++;
-    end_of_round_trip_ = last_sent_packet_;
-    return true;
-  }
-  return false;
-}
-
-void RoundTripCounter::RestartRound() {
-  end_of_round_trip_ = last_sent_packet_;
-}
-
-MinRttFilter::MinRttFilter(QuicTime::Delta initial_min_rtt,
-                           QuicTime initial_min_rtt_timestamp)
-    : min_rtt_(initial_min_rtt),
-      min_rtt_timestamp_(initial_min_rtt_timestamp) {}
-
-void MinRttFilter::Update(QuicTime::Delta sample_rtt, QuicTime now) {
-  if (sample_rtt < min_rtt_ || min_rtt_timestamp_ == QuicTime::Zero()) {
-    min_rtt_ = sample_rtt;
-    min_rtt_timestamp_ = now;
-  }
-}
-
-void MinRttFilter::ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now) {
-  min_rtt_ = sample_rtt;
-  min_rtt_timestamp_ = now;
-}
-
-Bbr2NetworkModel::Bbr2NetworkModel(const Bbr2Params* params,
-                                   QuicTime::Delta initial_rtt,
-                                   QuicTime initial_rtt_timestamp,
-                                   float cwnd_gain,
-                                   float pacing_gain,
-                                   const BandwidthSampler* old_sampler)
-    : params_(params),
-      bandwidth_sampler_([](QuicRoundTripCount max_height_tracker_window_length,
-                            const BandwidthSampler* old_sampler) {
-        if (old_sampler != nullptr) {
-          return BandwidthSampler(*old_sampler);
-        }
-        return BandwidthSampler(/*unacked_packet_map=*/nullptr,
-                                max_height_tracker_window_length);
-      }(params->initial_max_ack_height_filter_window, old_sampler)),
-      min_rtt_filter_(initial_rtt, initial_rtt_timestamp),
-      cwnd_gain_(cwnd_gain),
-      pacing_gain_(pacing_gain) {}
-
-void Bbr2NetworkModel::OnPacketSent(QuicTime sent_time,
-                                    QuicByteCount bytes_in_flight,
-                                    QuicPacketNumber packet_number,
-                                    QuicByteCount bytes,
-                                    HasRetransmittableData is_retransmittable) {
-  round_trip_counter_.OnPacketSent(packet_number);
-
-  bandwidth_sampler_.OnPacketSent(sent_time, packet_number, bytes,
-                                  bytes_in_flight, is_retransmittable);
-}
-
-void Bbr2NetworkModel::OnCongestionEventStart(
-    QuicTime event_time,
-    const AckedPacketVector& acked_packets,
-    const LostPacketVector& lost_packets,
-    Bbr2CongestionEvent* congestion_event) {
-  const QuicByteCount prior_bytes_acked = total_bytes_acked();
-  const QuicByteCount prior_bytes_lost = total_bytes_lost();
-
-  congestion_event->event_time = event_time;
-  congestion_event->end_of_round_trip =
-      acked_packets.empty() ? false
-                            : round_trip_counter_.OnPacketsAcked(
-                                  acked_packets.rbegin()->packet_number);
-
-  BandwidthSamplerInterface::CongestionEventSample sample =
-      bandwidth_sampler_.OnCongestionEvent(event_time, acked_packets,
-                                           lost_packets, MaxBandwidth(),
-                                           bandwidth_lo(), RoundTripCount());
-
-  if (sample.extra_acked == 0) {
-    cwnd_limited_before_aggregation_epoch_ =
-        congestion_event->prior_bytes_in_flight >= congestion_event->prior_cwnd;
-  }
-
-  if (sample.last_packet_send_state.is_valid) {
-    congestion_event->last_packet_send_state = sample.last_packet_send_state;
-  }
-
-  // Avoid updating |max_bandwidth_filter_| if a) this is a loss-only event, or
-  // b) all packets in |acked_packets| did not generate valid samples. (e.g. ack
-  // of ack-only packets). In both cases, total_bytes_acked() will not change.
-  if (prior_bytes_acked != total_bytes_acked()) {
-    QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
-        << total_bytes_acked() - prior_bytes_acked << " bytes from "
-        << acked_packets.size()
-        << " packets have been acked, but sample_max_bandwidth is zero.";
-    congestion_event->sample_max_bandwidth = sample.sample_max_bandwidth;
-    if (!sample.sample_is_app_limited ||
-        sample.sample_max_bandwidth > MaxBandwidth()) {
-      max_bandwidth_filter_.Update(congestion_event->sample_max_bandwidth);
-    }
-  }
-
-  if (!sample.sample_rtt.IsInfinite()) {
-    congestion_event->sample_min_rtt = sample.sample_rtt;
-    min_rtt_filter_.Update(congestion_event->sample_min_rtt, event_time);
-  }
-
-  congestion_event->bytes_acked = total_bytes_acked() - prior_bytes_acked;
-  congestion_event->bytes_lost = total_bytes_lost() - prior_bytes_lost;
-
-  if (congestion_event->prior_bytes_in_flight >=
-      congestion_event->bytes_acked + congestion_event->bytes_lost) {
-    congestion_event->bytes_in_flight =
-        congestion_event->prior_bytes_in_flight -
-        congestion_event->bytes_acked - congestion_event->bytes_lost;
-  } else {
-    QUIC_LOG_FIRST_N(ERROR, 1)
-        << "prior_bytes_in_flight:" << congestion_event->prior_bytes_in_flight
-        << " is smaller than the sum of bytes_acked:"
-        << congestion_event->bytes_acked
-        << " and bytes_lost:" << congestion_event->bytes_lost;
-    congestion_event->bytes_in_flight = 0;
-  }
-
-  if (congestion_event->bytes_lost > 0) {
-    bytes_lost_in_round_ += congestion_event->bytes_lost;
-    loss_events_in_round_++;
-  }
-
-  if (congestion_event->bytes_acked > 0 &&
-      congestion_event->last_packet_send_state.is_valid &&
-      total_bytes_acked() >
-          congestion_event->last_packet_send_state.total_bytes_acked) {
-    QuicByteCount bytes_delivered =
-        total_bytes_acked() -
-        congestion_event->last_packet_send_state.total_bytes_acked;
-    max_bytes_delivered_in_round_ =
-        std::max(max_bytes_delivered_in_round_, bytes_delivered);
-    // TODO(ianswett) Consider treating any bytes lost as decreasing inflight,
-    // because it's a sign of overutilization, not underutilization.
-    if (min_bytes_in_flight_in_round_ == 0 ||
-        congestion_event->bytes_in_flight < min_bytes_in_flight_in_round_) {
-      min_bytes_in_flight_in_round_ = congestion_event->bytes_in_flight;
-    }
-  }
-
-  // |bandwidth_latest_| and |inflight_latest_| only increased within a round.
-  if (sample.sample_max_bandwidth > bandwidth_latest_) {
-    bandwidth_latest_ = sample.sample_max_bandwidth;
-  }
-
-  if (sample.sample_max_inflight > inflight_latest_) {
-    inflight_latest_ = sample.sample_max_inflight;
-  }
-
-  // Adapt lower bounds(bandwidth_lo and inflight_lo).
-  AdaptLowerBounds(*congestion_event);
-
-  if (!congestion_event->end_of_round_trip) {
-    return;
-  }
-
-  if (!sample.sample_max_bandwidth.IsZero()) {
-    bandwidth_latest_ = sample.sample_max_bandwidth;
-  }
-
-  if (sample.sample_max_inflight > 0) {
-    inflight_latest_ = sample.sample_max_inflight;
-  }
-}
-
-void Bbr2NetworkModel::AdaptLowerBounds(
-    const Bbr2CongestionEvent& congestion_event) {
-  if (Params().bw_lo_mode_ == Bbr2Params::DEFAULT) {
-    if (!congestion_event.end_of_round_trip ||
-        congestion_event.is_probing_for_bandwidth) {
-      return;
-    }
-
-    if (bytes_lost_in_round_ > 0) {
-      if (bandwidth_lo_.IsInfinite()) {
-        bandwidth_lo_ = MaxBandwidth();
-      }
-      bandwidth_lo_ =
-          std::max(bandwidth_latest_, bandwidth_lo_ * (1.0 - Params().beta));
-      QUIC_DVLOG(3) << "bandwidth_lo_ updated to " << bandwidth_lo_
-                    << ", bandwidth_latest_ is " << bandwidth_latest_;
-
-      if (Params().ignore_inflight_lo) {
-        return;
-      }
-      if (inflight_lo_ == inflight_lo_default()) {
-        inflight_lo_ = congestion_event.prior_cwnd;
-      }
-      inflight_lo_ = std::max<QuicByteCount>(
-          inflight_latest_, inflight_lo_ * (1.0 - Params().beta));
-    }
-    return;
-  }
-
-  // Params().bw_lo_mode_ != Bbr2Params::DEFAULT
-  if (congestion_event.bytes_lost == 0) {
-    return;
-  }
-  // Ignore losses from packets sent when probing for more bandwidth in
-  // STARTUP or PROBE_UP when they're lost in DRAIN or PROBE_DOWN.
-  if (pacing_gain_ < 1) {
-    return;
-  }
-  // Decrease bandwidth_lo whenever there is loss.
-  // Set bandwidth_lo_ if it is not yet set.
-  if (bandwidth_lo_.IsInfinite()) {
-    bandwidth_lo_ = MaxBandwidth();
-  }
-  // Save bandwidth_lo_ if it hasn't already been saved.
-  if (prior_bandwidth_lo_.IsZero()) {
-    prior_bandwidth_lo_ = bandwidth_lo_;
-  }
-  switch (Params().bw_lo_mode_) {
-    case Bbr2Params::MIN_RTT_REDUCTION:
-      bandwidth_lo_ =
-          bandwidth_lo_ - QuicBandwidth::FromBytesAndTimeDelta(
-                              congestion_event.bytes_lost, MinRtt());
-      break;
-    case Bbr2Params::INFLIGHT_REDUCTION: {
-      // Use a max of BDP and inflight to avoid starving app-limited flows.
-      const QuicByteCount effective_inflight =
-          std::max(BDP(), congestion_event.prior_bytes_in_flight);
-      // This could use bytes_lost_in_round if the bandwidth_lo_ was saved
-      // when entering 'recovery', but this BBRv2 implementation doesn't have
-      // recovery defined.
-      bandwidth_lo_ =
-          bandwidth_lo_ * ((effective_inflight - congestion_event.bytes_lost) /
-                           static_cast<double>(effective_inflight));
-      break;
-    }
-    case Bbr2Params::CWND_REDUCTION:
-      bandwidth_lo_ =
-          bandwidth_lo_ *
-          ((congestion_event.prior_cwnd - congestion_event.bytes_lost) /
-           static_cast<double>(congestion_event.prior_cwnd));
-      break;
-    case Bbr2Params::DEFAULT:
-      QUIC_BUG(quic_bug_10466_1) << "Unreachable case DEFAULT.";
-  }
-  QuicBandwidth last_bandwidth = bandwidth_latest_;
-  // sample_max_bandwidth will be Zero() if the loss is triggered by a timer
-  // expiring.  Ideally we'd use the most recent bandwidth sample,
-  // but bandwidth_latest is safer than Zero().
-  if (!congestion_event.sample_max_bandwidth.IsZero()) {
-    // bandwidth_latest_ is the max bandwidth for the round, but to allow
-    // fast, conservation style response to loss, use the last sample.
-    last_bandwidth = congestion_event.sample_max_bandwidth;
-  }
-  if (pacing_gain_ > Params().startup_full_bw_threshold) {
-    // In STARTUP, pacing_gain_ is applied to bandwidth_lo_ in
-    // UpdatePacingRate, so this backs that multiplication out to allow the
-    // pacing rate to decrease, but not below
-    // last_bandwidth * startup_full_bw_threshold.
-    // TODO(ianswett): Consider altering pacing_gain_ when in STARTUP instead.
-    bandwidth_lo_ = std::max(
-        bandwidth_lo_,
-        last_bandwidth * (Params().startup_full_bw_threshold / pacing_gain_));
-  } else {
-    // Ensure bandwidth_lo isn't lower than last_bandwidth.
-    bandwidth_lo_ = std::max(bandwidth_lo_, last_bandwidth);
-  }
-  // If it's the end of the round, ensure bandwidth_lo doesn't decrease more
-  // than beta.
-  if (congestion_event.end_of_round_trip) {
-    bandwidth_lo_ =
-        std::max(bandwidth_lo_, prior_bandwidth_lo_ * (1.0 - Params().beta));
-    prior_bandwidth_lo_ = QuicBandwidth::Zero();
-  }
-  // These modes ignore inflight_lo as well.
-}
-
-void Bbr2NetworkModel::OnCongestionEventFinish(
-    QuicPacketNumber least_unacked_packet,
-    const Bbr2CongestionEvent& congestion_event) {
-  if (congestion_event.end_of_round_trip) {
-    OnNewRound();
-  }
-
-  bandwidth_sampler_.RemoveObsoletePackets(least_unacked_packet);
-}
-
-void Bbr2NetworkModel::UpdateNetworkParameters(QuicTime::Delta rtt) {
-  if (!rtt.IsZero()) {
-    min_rtt_filter_.Update(rtt, MinRttTimestamp());
-  }
-}
-
-bool Bbr2NetworkModel::MaybeExpireMinRtt(
-    const Bbr2CongestionEvent& congestion_event) {
-  if (congestion_event.event_time <
-      (MinRttTimestamp() + Params().probe_rtt_period)) {
-    return false;
-  }
-  if (congestion_event.sample_min_rtt.IsInfinite()) {
-    return false;
-  }
-  QUIC_DVLOG(3) << "Replacing expired min rtt of " << min_rtt_filter_.Get()
-                << " by " << congestion_event.sample_min_rtt << "  @ "
-                << congestion_event.event_time;
-  min_rtt_filter_.ForceUpdate(congestion_event.sample_min_rtt,
-                              congestion_event.event_time);
-  return true;
-}
-
-bool Bbr2NetworkModel::IsInflightTooHigh(
-    const Bbr2CongestionEvent& congestion_event,
-    int64_t max_loss_events) const {
-  const SendTimeState& send_state = congestion_event.last_packet_send_state;
-  if (!send_state.is_valid) {
-    // Not enough information.
-    return false;
-  }
-
-  if (loss_events_in_round() < max_loss_events) {
-    return false;
-  }
-
-  const QuicByteCount inflight_at_send = BytesInFlight(send_state);
-  // TODO(wub): Consider total_bytes_lost() - send_state.total_bytes_lost, which
-  // is the total bytes lost when the largest numbered packet was inflight.
-  // bytes_lost_in_round_, OTOH, is the total bytes lost in the "current" round.
-  const QuicByteCount bytes_lost_in_round = bytes_lost_in_round_;
-
-  QUIC_DVLOG(3) << "IsInflightTooHigh: loss_events_in_round:"
-                << loss_events_in_round()
-
-                << " bytes_lost_in_round:" << bytes_lost_in_round
-                << ", lost_in_round_threshold:"
-                << inflight_at_send * Params().loss_threshold;
-
-  if (inflight_at_send > 0 && bytes_lost_in_round > 0) {
-    QuicByteCount lost_in_round_threshold =
-        inflight_at_send * Params().loss_threshold;
-    if (bytes_lost_in_round > lost_in_round_threshold) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-void Bbr2NetworkModel::RestartRoundEarly() {
-  OnNewRound();
-  round_trip_counter_.RestartRound();
-}
-
-void Bbr2NetworkModel::OnNewRound() {
-  bytes_lost_in_round_ = 0;
-  loss_events_in_round_ = 0;
-  max_bytes_delivered_in_round_ = 0;
-  min_bytes_in_flight_in_round_ = 0;
-}
-
-void Bbr2NetworkModel::cap_inflight_lo(QuicByteCount cap) {
-  if (Params().ignore_inflight_lo) {
-    return;
-  }
-  if (inflight_lo_ != inflight_lo_default() && inflight_lo_ > cap) {
-    inflight_lo_ = cap;
-  }
-}
-
-QuicByteCount Bbr2NetworkModel::inflight_hi_with_headroom() const {
-  QuicByteCount headroom = inflight_hi_ * Params().inflight_hi_headroom;
-
-  return inflight_hi_ > headroom ? inflight_hi_ - headroom : 0;
-}
-
-bool Bbr2NetworkModel::HasBandwidthGrowth(
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK(!full_bandwidth_reached_);
-  QUICHE_DCHECK(congestion_event.end_of_round_trip);
-
-  QuicBandwidth threshold =
-      full_bandwidth_baseline_ * Params().startup_full_bw_threshold;
-
-  if (MaxBandwidth() >= threshold) {
-    QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
-                  << MaxBandwidth() << ", threshold:" << threshold
-                  << " (Still growing)  @ " << congestion_event.event_time;
-    full_bandwidth_baseline_ = MaxBandwidth();
-    rounds_without_bandwidth_growth_ = 0;
-    return true;
-  }
-  ++rounds_without_bandwidth_growth_;
-
-  // full_bandwidth_reached is only set to true when not app-limited, except
-  // when exit_startup_on_persistent_queue is true.
-  if (rounds_without_bandwidth_growth_ >= Params().startup_full_bw_rounds &&
-      !congestion_event.last_packet_send_state.is_app_limited) {
-    full_bandwidth_reached_ = true;
-  }
-  QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
-                << MaxBandwidth() << ", threshold:" << threshold
-                << " rounds_without_growth:" << rounds_without_bandwidth_growth_
-                << " full_bw_reached:" << full_bandwidth_reached_ << "  @ "
-                << congestion_event.event_time;
-
-  return false;
-}
-
-bool Bbr2NetworkModel::CheckPersistentQueue(
-    const Bbr2CongestionEvent& congestion_event, float bdp_gain) {
-  QUICHE_DCHECK(congestion_event.end_of_round_trip);
-  QuicByteCount target = bdp_gain * BDP();
-  if (bdp_gain >= 2) {
-    // Use a more conservative threshold for STARTUP because CWND gain is 2.
-    if (target <= QueueingThresholdExtraBytes()) {
-      return false;
-    }
-    target -= QueueingThresholdExtraBytes();
-  } else {
-    target += QueueingThresholdExtraBytes();
-  }
-  if (min_bytes_in_flight_in_round_ > target) {
-    full_bandwidth_reached_ = true;
-    return true;
-  }
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
deleted file mode 100644
index 5716ce9..0000000
--- a/quic/core/congestion_control/bbr2_misc.h
+++ /dev/null
@@ -1,674 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
-
-#include <algorithm>
-#include <limits>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_EXPORT_PRIVATE Limits {
- public:
-  Limits(T min, T max) : min_(min), max_(max) {}
-
-  // If [min, max] is an empty range, i.e. min > max, this function returns max,
-  // because typically a value larger than max means "risky".
-  T ApplyLimits(T raw_value) const {
-    return std::min(max_, std::max(min_, raw_value));
-  }
-
-  T Min() const { return min_; }
-  T Max() const { return max_; }
-
- private:
-  T min_;
-  T max_;
-};
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> MinMax(T min, T max) {
-  return Limits<T>(min, max);
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> NoLessThan(T min) {
-  return Limits<T>(min, std::numeric_limits<T>::max());
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> NoGreaterThan(T max) {
-  return Limits<T>(std::numeric_limits<T>::min(), max);
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline Limits<T> Unlimited() {
-  return Limits<T>(std::numeric_limits<T>::min(),
-                   std::numeric_limits<T>::max());
-}
-
-template <typename T>
-QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
-                                                    const Limits<T>& limits) {
-  return os << "[" << limits.Min() << ", " << limits.Max() << "]";
-}
-
-// Bbr2Params contains all parameters of a Bbr2Sender.
-struct QUIC_EXPORT_PRIVATE Bbr2Params {
-  Bbr2Params(QuicByteCount cwnd_min, QuicByteCount cwnd_max)
-      : cwnd_limits(cwnd_min, cwnd_max) {}
-
-  /*
-   * STARTUP parameters.
-   */
-
-  // The gain for both CWND and PacingRate at startup.
-  float startup_cwnd_gain = 2.0;
-  // TODO(wub): Maybe change to the newly derived value of 2.773 (4 * ln(2)).
-  float startup_pacing_gain = 2.885;
-
-  // Full bandwidth is declared if the total bandwidth growth is less than
-  // |startup_full_bw_threshold| times in the last |startup_full_bw_rounds|
-  // round trips.
-  float startup_full_bw_threshold = 1.25;
-
-  QuicRoundTripCount startup_full_bw_rounds = 3;
-
-  // The minimum number of loss marking events to exit STARTUP.
-  int64_t startup_full_loss_count =
-      GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count);
-
-  // If true, always exit STARTUP on loss, even if bandwidth exceeds threshold.
-  // If false, exit STARTUP on loss only if bandwidth is below threshold.
-  bool always_exit_startup_on_excess_loss = false;
-
-  // If true, include extra acked during STARTUP and proactively reduce extra
-  // acked when bandwidth increases.
-  bool startup_include_extra_acked = false;
-
-  // If true, exit STARTUP if bytes in flight has not gone below 2 * BDP at
-  // any point in the last round.
-  bool exit_startup_on_persistent_queue = false;
-
-  /*
-   * DRAIN parameters.
-   */
-  float drain_cwnd_gain = 2.0;
-  float drain_pacing_gain = 1.0 / 2.885;
-
-  /*
-   * PROBE_BW parameters.
-   */
-  // Max amount of randomness to inject in round counting for Reno-coexistence.
-  QuicRoundTripCount probe_bw_max_probe_rand_rounds = 2;
-
-  // Max number of rounds before probing for Reno-coexistence.
-  uint32_t probe_bw_probe_max_rounds = 63;
-
-  // Multiplier to get Reno-style probe epoch duration as: k * BDP round trips.
-  // If zero, disables Reno-style BDP-scaled coexistence mechanism.
-  float probe_bw_probe_reno_gain = 1.0;
-
-  // Minimum duration for BBR-native probes.
-  QuicTime::Delta probe_bw_probe_base_duration =
-      QuicTime::Delta::FromMilliseconds(
-          GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_base_duration_ms));
-
-  // The upper bound of the random amount of BBR-native probes.
-  QuicTime::Delta probe_bw_probe_max_rand_duration =
-      QuicTime::Delta::FromMilliseconds(
-          GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_max_rand_duration_ms));
-
-  // The minimum number of loss marking events to exit the PROBE_UP phase.
-  int64_t probe_bw_full_loss_count =
-      GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_full_loss_count);
-
-  // Multiplier to get target inflight (as multiple of BDP) for PROBE_UP phase.
-  float probe_bw_probe_inflight_gain = 1.25;
-
-  // When attempting to grow inflight_hi in PROBE_UP, check whether we are cwnd
-  // limited before the current aggregation epoch, instead of before the current
-  // ack event.
-  bool probe_bw_check_cwnd_limited_before_aggregation_epoch = false;
-
-  // Pacing gains.
-  float probe_bw_probe_up_pacing_gain = 1.25;
-  float probe_bw_probe_down_pacing_gain = 0.75;
-  float probe_bw_default_pacing_gain = 1.0;
-
-  float probe_bw_cwnd_gain = 2.0;
-
-  /*
-   * PROBE_UP parameters.
-   */
-  bool probe_up_includes_acks_after_cwnd_limited = false;
-  bool probe_up_dont_exit_if_no_queue_ = false;
-  bool probe_up_ignore_inflight_hi = false;
-
-  /*
-   * PROBE_RTT parameters.
-   */
-  float probe_rtt_inflight_target_bdp_fraction = 0.5;
-  QuicTime::Delta probe_rtt_period = QuicTime::Delta::FromMilliseconds(
-      GetQuicFlag(FLAGS_quic_bbr2_default_probe_rtt_period_ms));
-  QuicTime::Delta probe_rtt_duration = QuicTime::Delta::FromMilliseconds(200);
-
-  /*
-   * Parameters used by multiple modes.
-   */
-
-  // The initial value of the max ack height filter's window length.
-  QuicRoundTripCount initial_max_ack_height_filter_window =
-      GetQuicFlag(FLAGS_quic_bbr2_default_initial_ack_height_filter_window);
-
-  // Fraction of unutilized headroom to try to leave in path upon high loss.
-  float inflight_hi_headroom =
-      GetQuicFlag(FLAGS_quic_bbr2_default_inflight_hi_headroom);
-
-  // Estimate startup/bw probing has gone too far if loss rate exceeds this.
-  float loss_threshold = GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold);
-
-  // A common factor for multiplicative decreases. Used for adjusting
-  // bandwidth_lo, inflight_lo and inflight_hi upon losses.
-  float beta = 0.3;
-
-  Limits<QuicByteCount> cwnd_limits;
-
-  /*
-   * Experimental flags from QuicConfig.
-   */
-
-  // Can be disabled by connection option 'B2NA'.
-  bool add_ack_height_to_queueing_threshold = true;
-
-  // Can be disabled by connection option 'B2RP'.
-  bool avoid_unnecessary_probe_rtt = true;
-
-  // Can be enabled by connection option 'B2LO'.
-  bool ignore_inflight_lo = false;
-
-  // Can be enabled by connection option 'B2H2'.
-  bool limit_inflight_hi_by_max_delivered = false;
-
-  // Can be disabled by connection option 'B2SL'.
-  bool startup_loss_exit_use_max_delivered_for_inflight_hi = true;
-
-  // Can be enabled by connection option 'B2DL'.
-  bool use_bytes_delivered_for_inflight_hi = false;
-
-  // Can be disabled by connection option 'B2RC'.
-  bool enable_reno_coexistence = true;
-
-  // For experimentation to improve fast convergence upon loss.
-  enum QuicBandwidthLoMode : uint8_t {
-    DEFAULT = 0,
-    MIN_RTT_REDUCTION = 1,   // 'BBQ7'
-    INFLIGHT_REDUCTION = 2,  // 'BBQ8'
-    CWND_REDUCTION = 3,      // 'BBQ9'
-  };
-
-  // Different modes change bandwidth_lo_ differently upon loss.
-  QuicBandwidthLoMode bw_lo_mode_ = QuicBandwidthLoMode::DEFAULT;
-
-  // Set the pacing gain to 25% larger than the recent BW increase in STARTUP.
-  bool decrease_startup_pacing_at_end_of_round = false;
-};
-
-class QUIC_EXPORT_PRIVATE RoundTripCounter {
- public:
-  RoundTripCounter();
-
-  QuicRoundTripCount Count() const { return round_trip_count_; }
-
-  QuicPacketNumber last_sent_packet() const { return last_sent_packet_; }
-
-  // Must be called in ascending packet number order.
-  void OnPacketSent(QuicPacketNumber packet_number);
-
-  // Return whether a round trip has just completed.
-  bool OnPacketsAcked(QuicPacketNumber last_acked_packet);
-
-  void RestartRound();
-
- private:
-  QuicRoundTripCount round_trip_count_;
-  QuicPacketNumber last_sent_packet_;
-  // The last sent packet number of the current round trip.
-  QuicPacketNumber end_of_round_trip_;
-};
-
-class QUIC_EXPORT_PRIVATE MinRttFilter {
- public:
-  MinRttFilter(QuicTime::Delta initial_min_rtt,
-               QuicTime initial_min_rtt_timestamp);
-
-  void Update(QuicTime::Delta sample_rtt, QuicTime now);
-
-  void ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now);
-
-  QuicTime::Delta Get() const { return min_rtt_; }
-
-  QuicTime GetTimestamp() const { return min_rtt_timestamp_; }
-
- private:
-  QuicTime::Delta min_rtt_;
-  // Time when the current value of |min_rtt_| was assigned.
-  QuicTime min_rtt_timestamp_;
-};
-
-class QUIC_EXPORT_PRIVATE Bbr2MaxBandwidthFilter {
- public:
-  void Update(QuicBandwidth sample) {
-    max_bandwidth_[1] = std::max(sample, max_bandwidth_[1]);
-  }
-
-  void Advance() {
-    if (max_bandwidth_[1].IsZero()) {
-      return;
-    }
-
-    max_bandwidth_[0] = max_bandwidth_[1];
-    max_bandwidth_[1] = QuicBandwidth::Zero();
-  }
-
-  QuicBandwidth Get() const {
-    return std::max(max_bandwidth_[0], max_bandwidth_[1]);
-  }
-
- private:
-  QuicBandwidth max_bandwidth_[2] = {QuicBandwidth::Zero(),
-                                     QuicBandwidth::Zero()};
-};
-
-// Information that are meaningful only when Bbr2Sender::OnCongestionEvent is
-// running.
-struct QUIC_EXPORT_PRIVATE Bbr2CongestionEvent {
-  QuicTime event_time = QuicTime::Zero();
-
-  // The congestion window prior to the processing of the ack/loss events.
-  QuicByteCount prior_cwnd;
-
-  // Total bytes inflight before the processing of the ack/loss events.
-  QuicByteCount prior_bytes_in_flight = 0;
-
-  // Total bytes inflight after the processing of the ack/loss events.
-  QuicByteCount bytes_in_flight = 0;
-
-  // Total bytes acked from acks in this event.
-  QuicByteCount bytes_acked = 0;
-
-  // Total bytes lost from losses in this event.
-  QuicByteCount bytes_lost = 0;
-
-  // Whether acked_packets indicates the end of a round trip.
-  bool end_of_round_trip = false;
-
-  // When the event happened, whether the sender is probing for bandwidth.
-  bool is_probing_for_bandwidth = false;
-
-  // Minimum rtt of all bandwidth samples from acked_packets.
-  // QuicTime::Delta::Infinite() if acked_packets is empty.
-  QuicTime::Delta sample_min_rtt = QuicTime::Delta::Infinite();
-
-  // Maximum bandwidth of all bandwidth samples from acked_packets.
-  // This sample may be app-limited, and will be Zero() if there are no newly
-  // acknowledged inflight packets.
-  QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
-
-  // The send state of the largest packet in acked_packets, unless it is empty.
-  // If acked_packets is empty, it's the send state of the largest packet in
-  // lost_packets.
-  SendTimeState last_packet_send_state;
-};
-
-// Bbr2NetworkModel takes low level congestion signals(packets sent/acked/lost)
-// as input and produces BBRv2 model parameters like inflight_(hi|lo),
-// bandwidth_(hi|lo), bandwidth and rtt estimates, etc.
-class QUIC_EXPORT_PRIVATE Bbr2NetworkModel {
- public:
-  Bbr2NetworkModel(const Bbr2Params* params,
-                   QuicTime::Delta initial_rtt,
-                   QuicTime initial_rtt_timestamp,
-                   float cwnd_gain,
-                   float pacing_gain,
-                   const BandwidthSampler* old_sampler);
-
-  void OnPacketSent(QuicTime sent_time,
-                    QuicByteCount bytes_in_flight,
-                    QuicPacketNumber packet_number,
-                    QuicByteCount bytes,
-                    HasRetransmittableData is_retransmittable);
-
-  void OnCongestionEventStart(QuicTime event_time,
-                              const AckedPacketVector& acked_packets,
-                              const LostPacketVector& lost_packets,
-                              Bbr2CongestionEvent* congestion_event);
-
-  void OnCongestionEventFinish(QuicPacketNumber least_unacked_packet,
-                               const Bbr2CongestionEvent& congestion_event);
-
-  // Update the model without a congestion event.
-  // Min rtt is updated if |rtt| is non-zero and smaller than existing min rtt.
-  void UpdateNetworkParameters(QuicTime::Delta rtt);
-
-  // Update inflight/bandwidth short-term lower bounds.
-  void AdaptLowerBounds(const Bbr2CongestionEvent& congestion_event);
-
-  // Restart the current round trip as if it is starting now.
-  void RestartRoundEarly();
-
-  void AdvanceMaxBandwidthFilter() { max_bandwidth_filter_.Advance(); }
-
-  void OnApplicationLimited() { bandwidth_sampler_.OnAppLimited(); }
-
-  // Calculates BDP using the current MaxBandwidth.
-  QuicByteCount BDP() const { return BDP(MaxBandwidth()); }
-
-  QuicByteCount BDP(QuicBandwidth bandwidth) const {
-    return bandwidth * MinRtt();
-  }
-
-  QuicByteCount BDP(QuicBandwidth bandwidth, float gain) const {
-    return bandwidth * MinRtt() * gain;
-  }
-
-  QuicTime::Delta MinRtt() const { return min_rtt_filter_.Get(); }
-
-  QuicTime MinRttTimestamp() const { return min_rtt_filter_.GetTimestamp(); }
-
-  // TODO(wub): If we do this too frequently, we can potentailly postpone
-  // PROBE_RTT indefinitely. Observe how it works in production and improve it.
-  void PostponeMinRttTimestamp(QuicTime::Delta duration) {
-    min_rtt_filter_.ForceUpdate(MinRtt(), MinRttTimestamp() + duration);
-  }
-
-  QuicBandwidth MaxBandwidth() const { return max_bandwidth_filter_.Get(); }
-
-  QuicByteCount MaxAckHeight() const {
-    return bandwidth_sampler_.max_ack_height();
-  }
-
-  // 2 packets.  Used to indicate the typical number of bytes ACKed at once.
-  QuicByteCount QueueingThresholdExtraBytes() const {
-    return 2 * kDefaultTCPMSS;
-  }
-
-  bool cwnd_limited_before_aggregation_epoch() const {
-    return cwnd_limited_before_aggregation_epoch_;
-  }
-
-  void EnableOverestimateAvoidance() {
-    bandwidth_sampler_.EnableOverestimateAvoidance();
-  }
-
-  bool IsBandwidthOverestimateAvoidanceEnabled() const {
-    return bandwidth_sampler_.IsOverestimateAvoidanceEnabled();
-  }
-
-  void OnPacketNeutered(QuicPacketNumber packet_number) {
-    bandwidth_sampler_.OnPacketNeutered(packet_number);
-  }
-
-  uint64_t num_ack_aggregation_epochs() const {
-    return bandwidth_sampler_.num_ack_aggregation_epochs();
-  }
-
-  void SetStartNewAggregationEpochAfterFullRound(bool value) {
-    bandwidth_sampler_.SetStartNewAggregationEpochAfterFullRound(value);
-  }
-
-  void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
-    bandwidth_sampler_.SetLimitMaxAckHeightTrackerBySendRate(value);
-  }
-
-  void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount value) {
-    bandwidth_sampler_.SetMaxAckHeightTrackerWindowLength(value);
-  }
-
-  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
-    bandwidth_sampler_.SetReduceExtraAckedOnBandwidthIncrease(value);
-  }
-
-  bool MaybeExpireMinRtt(const Bbr2CongestionEvent& congestion_event);
-
-  QuicBandwidth BandwidthEstimate() const {
-    return std::min(MaxBandwidth(), bandwidth_lo_);
-  }
-
-  QuicRoundTripCount RoundTripCount() const {
-    return round_trip_counter_.Count();
-  }
-
-  // Return true if the number of loss events exceeds max_loss_events and
-  // fraction of bytes lost exceed the loss threshold.
-  bool IsInflightTooHigh(const Bbr2CongestionEvent& congestion_event,
-                         int64_t max_loss_events) const;
-
-  // Check bandwidth growth in the past round. Must be called at the end of a
-  // round. Returns true if there was sufficient bandwidth growth and false
-  // otherwise.  If it's been too many rounds without growth, also sets
-  // |full_bandwidth_reached_| to true.
-  bool HasBandwidthGrowth(const Bbr2CongestionEvent& congestion_event);
-
-  // Returns true if the minimum bytes in flight during the round is greater
-  // than the BDP * |bdp_gain|.
-  bool CheckPersistentQueue(const Bbr2CongestionEvent& congestion_event,
-                            float bdp_gain);
-
-  QuicPacketNumber last_sent_packet() const {
-    return round_trip_counter_.last_sent_packet();
-  }
-
-  QuicByteCount total_bytes_acked() const {
-    return bandwidth_sampler_.total_bytes_acked();
-  }
-
-  QuicByteCount total_bytes_lost() const {
-    return bandwidth_sampler_.total_bytes_lost();
-  }
-
-  QuicByteCount total_bytes_sent() const {
-    return bandwidth_sampler_.total_bytes_sent();
-  }
-
-  int64_t loss_events_in_round() const { return loss_events_in_round_; }
-
-  QuicByteCount max_bytes_delivered_in_round() const {
-    return max_bytes_delivered_in_round_;
-  }
-
-  QuicByteCount min_bytes_in_flight_in_round() const {
-    return min_bytes_in_flight_in_round_;
-  }
-
-  QuicPacketNumber end_of_app_limited_phase() const {
-    return bandwidth_sampler_.end_of_app_limited_phase();
-  }
-
-  QuicBandwidth bandwidth_latest() const { return bandwidth_latest_; }
-  QuicBandwidth bandwidth_lo() const { return bandwidth_lo_; }
-  static QuicBandwidth bandwidth_lo_default() {
-    return QuicBandwidth::Infinite();
-  }
-  void clear_bandwidth_lo() { bandwidth_lo_ = bandwidth_lo_default(); }
-
-  QuicByteCount inflight_latest() const { return inflight_latest_; }
-  QuicByteCount inflight_lo() const { return inflight_lo_; }
-  static QuicByteCount inflight_lo_default() {
-    return std::numeric_limits<QuicByteCount>::max();
-  }
-  void clear_inflight_lo() { inflight_lo_ = inflight_lo_default(); }
-  void cap_inflight_lo(QuicByteCount cap);
-
-  QuicByteCount inflight_hi_with_headroom() const;
-  QuicByteCount inflight_hi() const { return inflight_hi_; }
-  static QuicByteCount inflight_hi_default() {
-    return std::numeric_limits<QuicByteCount>::max();
-  }
-  void set_inflight_hi(QuicByteCount inflight_hi) {
-    inflight_hi_ = inflight_hi;
-  }
-
-  float cwnd_gain() const { return cwnd_gain_; }
-  void set_cwnd_gain(float cwnd_gain) { cwnd_gain_ = cwnd_gain; }
-
-  float pacing_gain() const { return pacing_gain_; }
-  void set_pacing_gain(float pacing_gain) { pacing_gain_ = pacing_gain; }
-
-  bool full_bandwidth_reached() const { return full_bandwidth_reached_; }
-  void set_full_bandwidth_reached() { full_bandwidth_reached_ = true; }
-  QuicBandwidth full_bandwidth_baseline() const {
-    return full_bandwidth_baseline_;
-  }
-  QuicRoundTripCount rounds_without_bandwidth_growth() const {
-    return rounds_without_bandwidth_growth_;
-  }
-
- private:
-  // Called when a new round trip starts.
-  void OnNewRound();
-
-  const Bbr2Params& Params() const { return *params_; }
-  const Bbr2Params* const params_;
-  RoundTripCounter round_trip_counter_;
-
-  // Bandwidth sampler provides BBR with the bandwidth measurements at
-  // individual points.
-  BandwidthSampler bandwidth_sampler_;
-  // The filter that tracks the maximum bandwidth over multiple recent round
-  // trips.
-  Bbr2MaxBandwidthFilter max_bandwidth_filter_;
-  MinRttFilter min_rtt_filter_;
-
-  // Bytes lost in the current round. Updated once per congestion event.
-  QuicByteCount bytes_lost_in_round_ = 0;
-  // Number of loss marking events in the current round.
-  int64_t loss_events_in_round_ = 0;
-
-  // A max of bytes delivered among all congestion events in the current round.
-  // A congestions event's bytes delivered is the total bytes acked between time
-  // Ts and Ta, which is the time when the largest acked packet(within the
-  // congestion event) was sent and acked, respectively.
-  QuicByteCount max_bytes_delivered_in_round_ = 0;
-
-  // The minimum bytes in flight during this round.
-  QuicByteCount min_bytes_in_flight_in_round_ = 0;
-
-  // Max bandwidth in the current round. Updated once per congestion event.
-  QuicBandwidth bandwidth_latest_ = QuicBandwidth::Zero();
-  // Max bandwidth of recent rounds. Updated once per round.
-  QuicBandwidth bandwidth_lo_ = bandwidth_lo_default();
-  // bandwidth_lo_ at the beginning of a round with loss. Only used when the
-  // bw_lo_mode is non-default.
-  QuicBandwidth prior_bandwidth_lo_ = QuicBandwidth::Zero();
-
-  // Max inflight in the current round. Updated once per congestion event.
-  QuicByteCount inflight_latest_ = 0;
-  // Max inflight of recent rounds. Updated once per round.
-  QuicByteCount inflight_lo_ = inflight_lo_default();
-  QuicByteCount inflight_hi_ = inflight_hi_default();
-
-  float cwnd_gain_;
-  float pacing_gain_;
-
-  // Whether we are cwnd limited prior to the start of the current aggregation
-  // epoch.
-  bool cwnd_limited_before_aggregation_epoch_ = false;
-
-  // STARTUP-centric fields which experimentally used by PROBE_UP.
-  bool full_bandwidth_reached_ = false;
-  QuicBandwidth full_bandwidth_baseline_ = QuicBandwidth::Zero();
-  QuicRoundTripCount rounds_without_bandwidth_growth_ = 0;
-};
-
-enum class Bbr2Mode : uint8_t {
-  // Startup phase of the connection.
-  STARTUP,
-  // After achieving the highest possible bandwidth during the startup, lower
-  // the pacing rate in order to drain the queue.
-  DRAIN,
-  // Cruising mode.
-  PROBE_BW,
-  // Temporarily slow down sending in order to empty the buffer and measure
-  // the real minimum RTT.
-  PROBE_RTT,
-};
-
-QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
-                                                    const Bbr2Mode& mode) {
-  switch (mode) {
-    case Bbr2Mode::STARTUP:
-      return os << "STARTUP";
-    case Bbr2Mode::DRAIN:
-      return os << "DRAIN";
-    case Bbr2Mode::PROBE_BW:
-      return os << "PROBE_BW";
-    case Bbr2Mode::PROBE_RTT:
-      return os << "PROBE_RTT";
-  }
-  return os << "<Invalid Mode>";
-}
-
-// The base class for all BBRv2 modes. A Bbr2Sender is in one mode at a time,
-// this interface is used to implement mode-specific behaviors.
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2ModeBase {
- public:
-  Bbr2ModeBase(const Bbr2Sender* sender, Bbr2NetworkModel* model)
-      : sender_(sender), model_(model) {}
-
-  virtual ~Bbr2ModeBase() = default;
-
-  // Called when entering/leaving this mode.
-  // congestion_event != nullptr means BBRv2 is switching modes in the context
-  // of a ack and/or loss.
-  virtual void Enter(QuicTime now,
-                     const Bbr2CongestionEvent* congestion_event) = 0;
-  virtual void Leave(QuicTime now,
-                     const Bbr2CongestionEvent* congestion_event) = 0;
-
-  virtual Bbr2Mode OnCongestionEvent(
-      QuicByteCount prior_in_flight,
-      QuicTime event_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      const Bbr2CongestionEvent& congestion_event) = 0;
-
-  virtual Limits<QuicByteCount> GetCwndLimits() const = 0;
-
-  virtual bool IsProbingForBandwidth() const = 0;
-
-  virtual Bbr2Mode OnExitQuiescence(QuicTime now,
-                                    QuicTime quiescence_start_time) = 0;
-
- protected:
-  const Bbr2Sender* const sender_;
-  Bbr2NetworkModel* model_;
-};
-
-QUIC_EXPORT_PRIVATE inline QuicByteCount BytesInFlight(
-    const SendTimeState& send_state) {
-  QUICHE_DCHECK(send_state.is_valid);
-  if (send_state.bytes_in_flight != 0) {
-    return send_state.bytes_in_flight;
-  }
-  return send_state.total_bytes_sent - send_state.total_bytes_acked -
-         send_state.total_bytes_lost;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
diff --git a/quic/core/congestion_control/bbr2_probe_bw.cc b/quic/core/congestion_control/bbr2_probe_bw.cc
deleted file mode 100644
index 0f65eca..0000000
--- a/quic/core/congestion_control/bbr2_probe_bw.cc
+++ /dev/null
@@ -1,677 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr2_probe_bw.h"
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-void Bbr2ProbeBwMode::Enter(QuicTime now,
-                            const Bbr2CongestionEvent* /*congestion_event*/) {
-  if (cycle_.phase == CyclePhase::PROBE_NOT_STARTED) {
-    // First time entering PROBE_BW. Start a new probing cycle.
-    EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/false,
-                   now);
-  } else {
-    // Transitioning from PROBE_RTT to PROBE_BW. Re-enter the last phase before
-    // PROBE_RTT.
-    QUICHE_DCHECK(cycle_.phase == CyclePhase::PROBE_CRUISE ||
-                  cycle_.phase == CyclePhase::PROBE_REFILL);
-    cycle_.cycle_start_time = now;
-    if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
-      EnterProbeCruise(now);
-    } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
-      EnterProbeRefill(cycle_.probe_up_rounds, now);
-    }
-  }
-}
-
-Bbr2Mode Bbr2ProbeBwMode::OnCongestionEvent(
-    QuicByteCount prior_in_flight, QuicTime event_time,
-    const AckedPacketVector& /*acked_packets*/,
-    const LostPacketVector& /*lost_packets*/,
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK_NE(cycle_.phase, CyclePhase::PROBE_NOT_STARTED);
-
-  if (congestion_event.end_of_round_trip) {
-    if (cycle_.cycle_start_time != event_time) {
-      ++cycle_.rounds_since_probe;
-    }
-    if (cycle_.phase_start_time != event_time) {
-      ++cycle_.rounds_in_phase;
-    }
-  }
-
-  bool switch_to_probe_rtt = false;
-
-  if (cycle_.phase == CyclePhase::PROBE_UP) {
-    UpdateProbeUp(prior_in_flight, congestion_event);
-  } else if (cycle_.phase == CyclePhase::PROBE_DOWN) {
-    UpdateProbeDown(prior_in_flight, congestion_event);
-    // Maybe transition to PROBE_RTT at the end of this cycle.
-    if (cycle_.phase != CyclePhase::PROBE_DOWN &&
-        model_->MaybeExpireMinRtt(congestion_event)) {
-      switch_to_probe_rtt = true;
-    }
-  } else if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
-    UpdateProbeCruise(congestion_event);
-  } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
-    UpdateProbeRefill(congestion_event);
-  }
-
-  // Do not need to set the gains if switching to PROBE_RTT, they will be set
-  // when Bbr2ProbeRttMode::Enter is called.
-  if (!switch_to_probe_rtt) {
-    model_->set_pacing_gain(PacingGainForPhase(cycle_.phase));
-    model_->set_cwnd_gain(Params().probe_bw_cwnd_gain);
-  }
-
-  return switch_to_probe_rtt ? Bbr2Mode::PROBE_RTT : Bbr2Mode::PROBE_BW;
-}
-
-Limits<QuicByteCount> Bbr2ProbeBwMode::GetCwndLimits() const {
-  if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
-    return NoGreaterThan(
-        std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom()));
-  }
-  if (Params().probe_up_ignore_inflight_hi &&
-      cycle_.phase == CyclePhase::PROBE_UP) {
-    // Similar to STARTUP.
-    return NoGreaterThan(model_->inflight_lo());
-  }
-
-  return NoGreaterThan(std::min(model_->inflight_lo(), model_->inflight_hi()));
-}
-
-bool Bbr2ProbeBwMode::IsProbingForBandwidth() const {
-  return cycle_.phase == CyclePhase::PROBE_REFILL ||
-         cycle_.phase == CyclePhase::PROBE_UP;
-}
-
-Bbr2Mode Bbr2ProbeBwMode::OnExitQuiescence(QuicTime now,
-                                           QuicTime quiescence_start_time) {
-  QUIC_DVLOG(3) << sender_ << " Postponing min_rtt_timestamp("
-                << model_->MinRttTimestamp() << ") by "
-                << now - quiescence_start_time;
-  model_->PostponeMinRttTimestamp(now - quiescence_start_time);
-  return Bbr2Mode::PROBE_BW;
-}
-
-// TODO(ianswett): Remove prior_in_flight from UpdateProbeDown.
-void Bbr2ProbeBwMode::UpdateProbeDown(
-    QuicByteCount prior_in_flight,
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
-
-  if (cycle_.rounds_in_phase == 1 && congestion_event.end_of_round_trip) {
-    cycle_.is_sample_from_probing = false;
-
-    if (!congestion_event.last_packet_send_state.is_app_limited) {
-      QUIC_DVLOG(2)
-          << sender_
-          << " Advancing max bw filter after one round in PROBE_DOWN.";
-      model_->AdvanceMaxBandwidthFilter();
-      cycle_.has_advanced_max_bw = true;
-    }
-
-    if (last_cycle_stopped_risky_probe_ && !last_cycle_probed_too_high_) {
-      EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
-      return;
-    }
-  }
-
-  MaybeAdaptUpperBounds(congestion_event);
-
-  if (IsTimeToProbeBandwidth(congestion_event)) {
-    EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
-    return;
-  }
-
-  if (HasStayedLongEnoughInProbeDown(congestion_event)) {
-    QUIC_DVLOG(3) << sender_ << " Proportional time based PROBE_DOWN exit";
-    EnterProbeCruise(congestion_event.event_time);
-    return;
-  }
-
-  const QuicByteCount inflight_with_headroom =
-      model_->inflight_hi_with_headroom();
-  QUIC_DVLOG(3)
-      << sender_
-      << " Checking if have enough inflight headroom. prior_in_flight:"
-      << prior_in_flight << " congestion_event.bytes_in_flight:"
-      << congestion_event.bytes_in_flight
-      << ", inflight_with_headroom:" << inflight_with_headroom;
-  QuicByteCount bytes_in_flight = congestion_event.bytes_in_flight;
-
-  if (bytes_in_flight > inflight_with_headroom) {
-    // Stay in PROBE_DOWN.
-    return;
-  }
-
-  // Transition to PROBE_CRUISE iff we've drained to target.
-  QuicByteCount bdp = model_->BDP();
-  QUIC_DVLOG(3) << sender_ << " Checking if drained to target. bytes_in_flight:"
-                << bytes_in_flight << ", bdp:" << bdp;
-  if (bytes_in_flight < bdp) {
-    EnterProbeCruise(congestion_event.event_time);
-  }
-}
-
-Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds(
-    const Bbr2CongestionEvent& congestion_event) {
-  const SendTimeState& send_state = congestion_event.last_packet_send_state;
-  if (!send_state.is_valid) {
-    QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
-                  << ": NOT_ADAPTED_INVALID_SAMPLE";
-    return NOT_ADAPTED_INVALID_SAMPLE;
-  }
-
-  // TODO(ianswett): Rename to bytes_delivered if
-  // use_bytes_delivered_for_inflight_hi is default enabled.
-  QuicByteCount inflight_at_send = BytesInFlight(send_state);
-  if (Params().use_bytes_delivered_for_inflight_hi) {
-    if (congestion_event.last_packet_send_state.total_bytes_acked <=
-        model_->total_bytes_acked()) {
-      inflight_at_send =
-          model_->total_bytes_acked() -
-          congestion_event.last_packet_send_state.total_bytes_acked;
-    } else {
-      QUIC_BUG(quic_bug_10436_1)
-          << "Total_bytes_acked(" << model_->total_bytes_acked()
-          << ") < send_state.total_bytes_acked("
-          << congestion_event.last_packet_send_state.total_bytes_acked << ")";
-    }
-  }
-  // TODO(ianswett): Inflight too high is really checking for loss, not
-  // inflight.
-  if (model_->IsInflightTooHigh(congestion_event,
-                                Params().probe_bw_full_loss_count)) {
-    if (cycle_.is_sample_from_probing) {
-      cycle_.is_sample_from_probing = false;
-      if (!send_state.is_app_limited ||
-          Params().probe_up_dont_exit_if_no_queue_) {
-        if (send_state.is_app_limited) {
-          // If there's excess loss or a queue is building, exit even if the
-          // last sample was app limited.
-          QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue,
-                                       2, 2);
-        }
-        const QuicByteCount inflight_target =
-            sender_->GetTargetBytesInflight() * (1.0 - Params().beta);
-        if (inflight_at_send >= inflight_target) {
-          // The new code does not change behavior.
-          QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_noop);
-        } else {
-          // The new code actually cuts inflight_hi slower than before.
-          QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_in_effect);
-        }
-        if (Params().limit_inflight_hi_by_max_delivered) {
-          QuicByteCount new_inflight_hi =
-              std::max(inflight_at_send, inflight_target);
-          if (new_inflight_hi >= model_->max_bytes_delivered_in_round()) {
-            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_noop);
-          } else {
-            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_in_effect);
-            new_inflight_hi = model_->max_bytes_delivered_in_round();
-          }
-          QUIC_DVLOG(3) << sender_
-                        << " Setting inflight_hi due to loss. new_inflight_hi:"
-                        << new_inflight_hi
-                        << ", inflight_at_send:" << inflight_at_send
-                        << ", inflight_target:" << inflight_target
-                        << ", max_bytes_delivered_in_round:"
-                        << model_->max_bytes_delivered_in_round() << "  @ "
-                        << congestion_event.event_time;
-          model_->set_inflight_hi(new_inflight_hi);
-        } else {
-          model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
-        }
-      }
-
-      QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
-                    << ": ADAPTED_PROBED_TOO_HIGH";
-      return ADAPTED_PROBED_TOO_HIGH;
-    }
-    return ADAPTED_OK;
-  }
-
-  if (model_->inflight_hi() == model_->inflight_hi_default()) {
-    QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
-                  << ": NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET";
-    return NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET;
-  }
-
-  // Raise the upper bound for inflight.
-  if (inflight_at_send > model_->inflight_hi()) {
-    QUIC_DVLOG(3)
-        << sender_ << " " << cycle_.phase
-        << ": Adapting inflight_hi from inflight_at_send. inflight_at_send:"
-        << inflight_at_send << ", old inflight_hi:" << model_->inflight_hi();
-    model_->set_inflight_hi(inflight_at_send);
-  }
-
-  return ADAPTED_OK;
-}
-
-bool Bbr2ProbeBwMode::IsTimeToProbeBandwidth(
-    const Bbr2CongestionEvent& congestion_event) const {
-  if (HasCycleLasted(cycle_.probe_wait_time, congestion_event)) {
-    return true;
-  }
-
-  if (IsTimeToProbeForRenoCoexistence(1.0, congestion_event)) {
-    ++sender_->connection_stats_->bbr_num_short_cycles_for_reno_coexistence;
-    return true;
-  }
-  return false;
-}
-
-// QUIC only. Used to prevent a Bbr2 flow from staying in PROBE_DOWN for too
-// long, as seen in some multi-sender simulator tests.
-bool Bbr2ProbeBwMode::HasStayedLongEnoughInProbeDown(
-    const Bbr2CongestionEvent& congestion_event) const {
-  // Stay in PROBE_DOWN for at most the time of a min rtt, as it is done in
-  // BBRv1.
-  // TODO(wub): Consider exit after a full round instead, which typically
-  // indicates most(if not all) packets sent during PROBE_UP have been acked.
-  return HasPhaseLasted(model_->MinRtt(), congestion_event);
-}
-
-bool Bbr2ProbeBwMode::HasCycleLasted(
-    QuicTime::Delta duration,
-    const Bbr2CongestionEvent& congestion_event) const {
-  bool result =
-      (congestion_event.event_time - cycle_.cycle_start_time) > duration;
-  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
-                << ": HasCycleLasted=" << result << ". elapsed:"
-                << (congestion_event.event_time - cycle_.cycle_start_time)
-                << ", duration:" << duration;
-  return result;
-}
-
-bool Bbr2ProbeBwMode::HasPhaseLasted(
-    QuicTime::Delta duration,
-    const Bbr2CongestionEvent& congestion_event) const {
-  bool result =
-      (congestion_event.event_time - cycle_.phase_start_time) > duration;
-  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
-                << ": HasPhaseLasted=" << result << ". elapsed:"
-                << (congestion_event.event_time - cycle_.phase_start_time)
-                << ", duration:" << duration;
-  return result;
-}
-
-bool Bbr2ProbeBwMode::IsTimeToProbeForRenoCoexistence(
-    double probe_wait_fraction,
-    const Bbr2CongestionEvent& /*congestion_event*/) const {
-  if (!Params().enable_reno_coexistence) {
-    return false;
-  }
-
-  uint64_t rounds = Params().probe_bw_probe_max_rounds;
-  if (Params().probe_bw_probe_reno_gain > 0.0) {
-    QuicByteCount target_bytes_inflight = sender_->GetTargetBytesInflight();
-    uint64_t reno_rounds = Params().probe_bw_probe_reno_gain *
-                           target_bytes_inflight / kDefaultTCPMSS;
-    rounds = std::min(rounds, reno_rounds);
-  }
-  bool result = cycle_.rounds_since_probe >= (rounds * probe_wait_fraction);
-  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
-                << ": IsTimeToProbeForRenoCoexistence=" << result
-                << ". rounds_since_probe:" << cycle_.rounds_since_probe
-                << ", rounds:" << rounds
-                << ", probe_wait_fraction:" << probe_wait_fraction;
-  return result;
-}
-
-void Bbr2ProbeBwMode::RaiseInflightHighSlope() {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
-  uint64_t growth_this_round = 1 << cycle_.probe_up_rounds;
-  // The number 30 below means |growth_this_round| is capped at 1G and the lower
-  // bound of |probe_up_bytes| is (practically) 1 mss, at this speed inflight_hi
-  // grows by approximately 1 packet per packet acked.
-  cycle_.probe_up_rounds = std::min<uint64_t>(cycle_.probe_up_rounds + 1, 30);
-  uint64_t probe_up_bytes = sender_->GetCongestionWindow() / growth_this_round;
-  cycle_.probe_up_bytes =
-      std::max<QuicByteCount>(probe_up_bytes, kDefaultTCPMSS);
-  QUIC_DVLOG(3) << sender_ << " Rasing inflight_hi slope. probe_up_rounds:"
-                << cycle_.probe_up_rounds
-                << ", probe_up_bytes:" << cycle_.probe_up_bytes;
-}
-
-void Bbr2ProbeBwMode::ProbeInflightHighUpward(
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
-  if (Params().probe_up_ignore_inflight_hi) {
-    // When inflight_hi is disabled in PROBE_UP, it increases when
-    // the number of bytes delivered in a round is larger inflight_hi.
-    return;
-  }
-  if (Params().probe_bw_check_cwnd_limited_before_aggregation_epoch) {
-    if (!model_->cwnd_limited_before_aggregation_epoch()) {
-      QUIC_DVLOG(3) << sender_
-                    << " Raising inflight_hi early return: Not cwnd limited "
-                       "before aggregation epoch.";
-      // Not fully utilizing cwnd, so can't safely grow.
-      return;
-    }
-  } else if (Params().probe_up_includes_acks_after_cwnd_limited) {
-    QUIC_RELOADABLE_FLAG_COUNT(
-        quic_bbr2_add_bytes_acked_after_inflight_hi_limited);
-    // Don't continue adding bytes to probe_up_acked if the sender was not
-    // app-limited after being inflight_hi limited at least once.
-    if (!cycle_.probe_up_app_limited_since_inflight_hi_limited_ ||
-        congestion_event.last_packet_send_state.is_app_limited) {
-      cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
-      if (congestion_event.prior_bytes_in_flight <
-          congestion_event.prior_cwnd) {
-        QUIC_DVLOG(3) << sender_
-                      << " Raising inflight_hi early return: Not cwnd limited.";
-        // Not fully utilizing cwnd, so can't safely grow.
-        return;
-      }
-
-      if (congestion_event.prior_cwnd < model_->inflight_hi()) {
-        QUIC_DVLOG(3)
-            << sender_
-            << " Raising inflight_hi early return: inflight_hi not fully used.";
-        // Not fully using inflight_hi, so don't grow it.
-        return;
-      }
-    }
-    // Start a new period of adding bytes_acked, because inflight_hi limited.
-    cycle_.probe_up_app_limited_since_inflight_hi_limited_ = true;
-  } else {
-    if (congestion_event.prior_bytes_in_flight < congestion_event.prior_cwnd) {
-      QUIC_DVLOG(3) << sender_
-                    << " Raising inflight_hi early return: Not cwnd limited.";
-      // Not fully utilizing cwnd, so can't safely grow.
-      return;
-    }
-  }
-
-  if (congestion_event.prior_cwnd < model_->inflight_hi()) {
-    QUIC_DVLOG(3)
-        << sender_
-        << " Raising inflight_hi early return: inflight_hi not fully used.";
-    // Not fully using inflight_hi, so don't grow it.
-    return;
-  }
-
-  // Increase inflight_hi by the number of probe_up_bytes within probe_up_acked.
-  cycle_.probe_up_acked += congestion_event.bytes_acked;
-  if (cycle_.probe_up_acked >= cycle_.probe_up_bytes) {
-    uint64_t delta = cycle_.probe_up_acked / cycle_.probe_up_bytes;
-    cycle_.probe_up_acked -= delta * cycle_.probe_up_bytes;
-    QuicByteCount new_inflight_hi =
-        model_->inflight_hi() + delta * kDefaultTCPMSS;
-    if (new_inflight_hi > model_->inflight_hi()) {
-      QUIC_DVLOG(3) << sender_ << " Raising inflight_hi from "
-                    << model_->inflight_hi() << " to " << new_inflight_hi
-                    << ". probe_up_bytes:" << cycle_.probe_up_bytes
-                    << ", delta:" << delta
-                    << ", (new)probe_up_acked:" << cycle_.probe_up_acked;
-
-      model_->set_inflight_hi(new_inflight_hi);
-    } else {
-      QUIC_BUG(quic_bug_10436_2)
-          << "Not growing inflight_hi due to wrap around. Old value:"
-          << model_->inflight_hi() << ", new value:" << new_inflight_hi;
-    }
-  }
-
-  if (congestion_event.end_of_round_trip) {
-    RaiseInflightHighSlope();
-  }
-}
-
-void Bbr2ProbeBwMode::UpdateProbeCruise(
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_CRUISE);
-  MaybeAdaptUpperBounds(congestion_event);
-  QUICHE_DCHECK(!cycle_.is_sample_from_probing);
-
-  if (IsTimeToProbeBandwidth(congestion_event)) {
-    EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
-    return;
-  }
-}
-
-void Bbr2ProbeBwMode::UpdateProbeRefill(
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
-  MaybeAdaptUpperBounds(congestion_event);
-  QUICHE_DCHECK(!cycle_.is_sample_from_probing);
-
-  if (cycle_.rounds_in_phase > 0 && congestion_event.end_of_round_trip) {
-    EnterProbeUp(congestion_event.event_time);
-    return;
-  }
-}
-
-void Bbr2ProbeBwMode::UpdateProbeUp(
-    QuicByteCount prior_in_flight,
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
-  if (MaybeAdaptUpperBounds(congestion_event) == ADAPTED_PROBED_TOO_HIGH) {
-    EnterProbeDown(/*probed_too_high=*/true, /*stopped_risky_probe=*/false,
-                   congestion_event.event_time);
-    return;
-  }
-
-  // TODO(wub): Consider exit PROBE_UP after a certain number(e.g. 64) of RTTs.
-
-  ProbeInflightHighUpward(congestion_event);
-
-  bool is_risky = false;
-  bool is_queuing = false;
-  if (last_cycle_probed_too_high_ && prior_in_flight >= model_->inflight_hi()) {
-    is_risky = true;
-    QUIC_DVLOG(3) << sender_
-                  << " Probe is too risky. last_cycle_probed_too_high_:"
-                  << last_cycle_probed_too_high_
-                  << ", prior_in_flight:" << prior_in_flight
-                  << ", inflight_hi:" << model_->inflight_hi();
-    // TCP uses min_rtt instead of a full round:
-    //   HasPhaseLasted(model_->MinRtt(), congestion_event)
-  } else if (cycle_.rounds_in_phase > 0) {
-    if (Params().probe_up_dont_exit_if_no_queue_) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue, 1,
-                                   2);
-      is_queuing = congestion_event.end_of_round_trip &&
-                   model_->CheckPersistentQueue(
-                       congestion_event, Params().probe_bw_probe_inflight_gain);
-    } else {
-      QuicByteCount queuing_threshold_extra_bytes =
-          model_->QueueingThresholdExtraBytes();
-      if (Params().add_ack_height_to_queueing_threshold) {
-        queuing_threshold_extra_bytes += model_->MaxAckHeight();
-      }
-      QuicByteCount queuing_threshold =
-          (Params().probe_bw_probe_inflight_gain * model_->BDP()) +
-          queuing_threshold_extra_bytes;
-
-      is_queuing = congestion_event.bytes_in_flight >= queuing_threshold;
-
-      QUIC_DVLOG(3) << sender_
-                    << " Checking if building up a queue. prior_in_flight:"
-                    << prior_in_flight
-                    << ", post_in_flight:" << congestion_event.bytes_in_flight
-                    << ", threshold:" << queuing_threshold
-                    << ", is_queuing:" << is_queuing
-                    << ", max_bw:" << model_->MaxBandwidth()
-                    << ", min_rtt:" << model_->MinRtt();
-    }
-  }
-
-  if (is_risky || is_queuing) {
-    EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/is_risky,
-                   congestion_event.event_time);
-  }
-}
-
-void Bbr2ProbeBwMode::EnterProbeDown(bool probed_too_high,
-                                     bool stopped_risky_probe, QuicTime now) {
-  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
-                << CyclePhase::PROBE_DOWN << " after "
-                << now - cycle_.phase_start_time << ", or "
-                << cycle_.rounds_in_phase
-                << " rounds. probed_too_high:" << probed_too_high
-                << ", stopped_risky_probe:" << stopped_risky_probe << "  @ "
-                << now;
-  last_cycle_probed_too_high_ = probed_too_high;
-  last_cycle_stopped_risky_probe_ = stopped_risky_probe;
-
-  cycle_.cycle_start_time = now;
-  cycle_.phase = CyclePhase::PROBE_DOWN;
-  cycle_.rounds_in_phase = 0;
-  cycle_.phase_start_time = now;
-  ++sender_->connection_stats_->bbr_num_cycles;
-  if (Params().bw_lo_mode_ != Bbr2Params::QuicBandwidthLoMode::DEFAULT) {
-    // Clear bandwidth lo if it was set in PROBE_UP, because losses in PROBE_UP
-    // should not permanently change bandwidth_lo.
-    // It's possible for bandwidth_lo to be set during REFILL, but if that was
-    // a valid value, it'll quickly be rediscovered.
-    model_->clear_bandwidth_lo();
-  }
-
-  // Pick probe wait time.
-  cycle_.rounds_since_probe =
-      sender_->RandomUint64(Params().probe_bw_max_probe_rand_rounds);
-  cycle_.probe_wait_time =
-      Params().probe_bw_probe_base_duration +
-      QuicTime::Delta::FromMicroseconds(sender_->RandomUint64(
-          Params().probe_bw_probe_max_rand_duration.ToMicroseconds()));
-
-  cycle_.probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
-  cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
-  cycle_.has_advanced_max_bw = false;
-  model_->RestartRoundEarly();
-}
-
-void Bbr2ProbeBwMode::EnterProbeCruise(QuicTime now) {
-  if (cycle_.phase == CyclePhase::PROBE_DOWN) {
-    ExitProbeDown();
-  }
-  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
-                << CyclePhase::PROBE_CRUISE << " after "
-                << now - cycle_.phase_start_time << ", or "
-                << cycle_.rounds_in_phase << " rounds.  @ " << now;
-
-  model_->cap_inflight_lo(model_->inflight_hi());
-  cycle_.phase = CyclePhase::PROBE_CRUISE;
-  cycle_.rounds_in_phase = 0;
-  cycle_.phase_start_time = now;
-  cycle_.is_sample_from_probing = false;
-}
-
-void Bbr2ProbeBwMode::EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now) {
-  if (cycle_.phase == CyclePhase::PROBE_DOWN) {
-    ExitProbeDown();
-  }
-  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
-                << CyclePhase::PROBE_REFILL << " after "
-                << now - cycle_.phase_start_time << ", or "
-                << cycle_.rounds_in_phase
-                << " rounds. probe_up_rounds:" << probe_up_rounds << "  @ "
-                << now;
-  cycle_.phase = CyclePhase::PROBE_REFILL;
-  cycle_.rounds_in_phase = 0;
-  cycle_.phase_start_time = now;
-  cycle_.is_sample_from_probing = false;
-  last_cycle_stopped_risky_probe_ = false;
-
-  model_->clear_bandwidth_lo();
-  model_->clear_inflight_lo();
-  cycle_.probe_up_rounds = probe_up_rounds;
-  cycle_.probe_up_acked = 0;
-  model_->RestartRoundEarly();
-}
-
-void Bbr2ProbeBwMode::EnterProbeUp(QuicTime now) {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
-  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
-                << CyclePhase::PROBE_UP << " after "
-                << now - cycle_.phase_start_time << ", or "
-                << cycle_.rounds_in_phase << " rounds.  @ " << now;
-  cycle_.phase = CyclePhase::PROBE_UP;
-  cycle_.rounds_in_phase = 0;
-  cycle_.phase_start_time = now;
-  cycle_.is_sample_from_probing = true;
-  RaiseInflightHighSlope();
-
-  model_->RestartRoundEarly();
-}
-
-void Bbr2ProbeBwMode::ExitProbeDown() {
-  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
-  if (!cycle_.has_advanced_max_bw) {
-    QUIC_DVLOG(2) << sender_ << " Advancing max bw filter at end of cycle.";
-    model_->AdvanceMaxBandwidthFilter();
-    cycle_.has_advanced_max_bw = true;
-  }
-}
-
-// static
-const char* Bbr2ProbeBwMode::CyclePhaseToString(CyclePhase phase) {
-  switch (phase) {
-    case CyclePhase::PROBE_NOT_STARTED:
-      return "PROBE_NOT_STARTED";
-    case CyclePhase::PROBE_UP:
-      return "PROBE_UP";
-    case CyclePhase::PROBE_DOWN:
-      return "PROBE_DOWN";
-    case CyclePhase::PROBE_CRUISE:
-      return "PROBE_CRUISE";
-    case CyclePhase::PROBE_REFILL:
-      return "PROBE_REFILL";
-    default:
-      break;
-  }
-  return "<Invalid CyclePhase>";
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const Bbr2ProbeBwMode::CyclePhase phase) {
-  return os << Bbr2ProbeBwMode::CyclePhaseToString(phase);
-}
-
-Bbr2ProbeBwMode::DebugState Bbr2ProbeBwMode::ExportDebugState() const {
-  DebugState s;
-  s.phase = cycle_.phase;
-  s.cycle_start_time = cycle_.cycle_start_time;
-  s.phase_start_time = cycle_.phase_start_time;
-  return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const Bbr2ProbeBwMode::DebugState& state) {
-  os << "[PROBE_BW] phase: " << state.phase << "\n";
-  os << "[PROBE_BW] cycle_start_time: " << state.cycle_start_time << "\n";
-  os << "[PROBE_BW] phase_start_time: " << state.phase_start_time << "\n";
-  return os;
-}
-
-const Bbr2Params& Bbr2ProbeBwMode::Params() const { return sender_->Params(); }
-
-float Bbr2ProbeBwMode::PacingGainForPhase(
-    Bbr2ProbeBwMode::CyclePhase phase) const {
-  if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_UP) {
-    return Params().probe_bw_probe_up_pacing_gain;
-  }
-  if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_DOWN) {
-    return Params().probe_bw_probe_down_pacing_gain;
-  }
-  return Params().probe_bw_default_pacing_gain;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_probe_bw.h b/quic/core/congestion_control/bbr2_probe_bw.h
deleted file mode 100644
index 832dfa1..0000000
--- a/quic/core/congestion_control/bbr2_probe_bw.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
-
-#include <cstdint>
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2ProbeBwMode final : public Bbr2ModeBase {
- public:
-  using Bbr2ModeBase::Bbr2ModeBase;
-
-  void Enter(QuicTime now,
-             const Bbr2CongestionEvent* congestion_event) override;
-  void Leave(QuicTime /*now*/,
-             const Bbr2CongestionEvent* /*congestion_event*/) override {}
-
-  Bbr2Mode OnCongestionEvent(
-      QuicByteCount prior_in_flight,
-      QuicTime event_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      const Bbr2CongestionEvent& congestion_event) override;
-
-  Limits<QuicByteCount> GetCwndLimits() const override;
-
-  bool IsProbingForBandwidth() const override;
-
-  Bbr2Mode OnExitQuiescence(QuicTime now,
-                            QuicTime quiescence_start_time) override;
-
-  enum class CyclePhase : uint8_t {
-    PROBE_NOT_STARTED,
-    PROBE_UP,
-    PROBE_DOWN,
-    PROBE_CRUISE,
-    PROBE_REFILL,
-  };
-
-  static const char* CyclePhaseToString(CyclePhase phase);
-
-  struct QUIC_EXPORT_PRIVATE DebugState {
-    CyclePhase phase;
-    QuicTime cycle_start_time = QuicTime::Zero();
-    QuicTime phase_start_time = QuicTime::Zero();
-  };
-
-  DebugState ExportDebugState() const;
-
- private:
-  const Bbr2Params& Params() const;
-  float PacingGainForPhase(CyclePhase phase) const;
-
-  void UpdateProbeUp(QuicByteCount prior_in_flight,
-                     const Bbr2CongestionEvent& congestion_event);
-  void UpdateProbeDown(QuicByteCount prior_in_flight,
-                       const Bbr2CongestionEvent& congestion_event);
-  void UpdateProbeCruise(const Bbr2CongestionEvent& congestion_event);
-  void UpdateProbeRefill(const Bbr2CongestionEvent& congestion_event);
-
-  enum AdaptUpperBoundsResult : uint8_t {
-    ADAPTED_OK,
-    ADAPTED_PROBED_TOO_HIGH,
-    NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET,
-    NOT_ADAPTED_INVALID_SAMPLE,
-  };
-
-  // Return whether adapted inflight_hi. If inflight is too high, this function
-  // will not adapt inflight_hi and will return false.
-  AdaptUpperBoundsResult MaybeAdaptUpperBounds(
-      const Bbr2CongestionEvent& congestion_event);
-
-  void EnterProbeDown(bool probed_too_high,
-                      bool stopped_risky_probe,
-                      QuicTime now);
-  void EnterProbeCruise(QuicTime now);
-  void EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now);
-  void EnterProbeUp(QuicTime now);
-
-  // Call right before the exit of PROBE_DOWN.
-  void ExitProbeDown();
-
-  float PercentTimeElapsedToProbeBandwidth(
-      const Bbr2CongestionEvent& congestion_event) const;
-
-  bool IsTimeToProbeBandwidth(
-      const Bbr2CongestionEvent& congestion_event) const;
-  bool HasStayedLongEnoughInProbeDown(
-      const Bbr2CongestionEvent& congestion_event) const;
-  bool HasCycleLasted(QuicTime::Delta duration,
-                      const Bbr2CongestionEvent& congestion_event) const;
-  bool HasPhaseLasted(QuicTime::Delta duration,
-                      const Bbr2CongestionEvent& congestion_event) const;
-  bool IsTimeToProbeForRenoCoexistence(
-      double probe_wait_fraction,
-      const Bbr2CongestionEvent& congestion_event) const;
-
-  void RaiseInflightHighSlope();
-  void ProbeInflightHighUpward(const Bbr2CongestionEvent& congestion_event);
-
-  struct QUIC_EXPORT_PRIVATE Cycle {
-    QuicTime cycle_start_time = QuicTime::Zero();
-    CyclePhase phase = CyclePhase::PROBE_NOT_STARTED;
-    uint64_t rounds_in_phase = 0;
-    QuicTime phase_start_time = QuicTime::Zero();
-    QuicRoundTripCount rounds_since_probe = 0;
-    QuicTime::Delta probe_wait_time = QuicTime::Delta::Zero();
-    uint64_t probe_up_rounds = 0;
-    QuicByteCount probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
-    QuicByteCount probe_up_acked = 0;
-    bool probe_up_app_limited_since_inflight_hi_limited_ = false;
-    // Whether max bandwidth filter window has advanced in this cycle. It is
-    // advanced once per cycle.
-    bool has_advanced_max_bw = false;
-    bool is_sample_from_probing = false;
-  } cycle_;
-
-  bool last_cycle_probed_too_high_;
-  bool last_cycle_stopped_risky_probe_;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const Bbr2ProbeBwMode::DebugState& state);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const Bbr2ProbeBwMode::CyclePhase phase);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
diff --git a/quic/core/congestion_control/bbr2_probe_rtt.cc b/quic/core/congestion_control/bbr2_probe_rtt.cc
deleted file mode 100644
index d83e5e6..0000000
--- a/quic/core/congestion_control/bbr2_probe_rtt.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr2_probe_rtt.h"
-
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-void Bbr2ProbeRttMode::Enter(QuicTime /*now*/,
-                             const Bbr2CongestionEvent* /*congestion_event*/) {
-  model_->set_pacing_gain(1.0);
-  model_->set_cwnd_gain(1.0);
-  exit_time_ = QuicTime::Zero();
-}
-
-Bbr2Mode Bbr2ProbeRttMode::OnCongestionEvent(
-    QuicByteCount /*prior_in_flight*/,
-    QuicTime /*event_time*/,
-    const AckedPacketVector& /*acked_packets*/,
-    const LostPacketVector& /*lost_packets*/,
-    const Bbr2CongestionEvent& congestion_event) {
-  if (exit_time_ == QuicTime::Zero()) {
-    if (congestion_event.bytes_in_flight <= InflightTarget() ||
-        congestion_event.bytes_in_flight <=
-            sender_->GetMinimumCongestionWindow()) {
-      exit_time_ = congestion_event.event_time + Params().probe_rtt_duration;
-      QUIC_DVLOG(2) << sender_ << " PROBE_RTT exit time set to " << exit_time_
-                    << ". bytes_inflight:" << congestion_event.bytes_in_flight
-                    << ", inflight_target:" << InflightTarget()
-                    << ", min_congestion_window:"
-                    << sender_->GetMinimumCongestionWindow() << "  @ "
-                    << congestion_event.event_time;
-    }
-    return Bbr2Mode::PROBE_RTT;
-  }
-
-  return congestion_event.event_time > exit_time_ ? Bbr2Mode::PROBE_BW
-                                                  : Bbr2Mode::PROBE_RTT;
-}
-
-QuicByteCount Bbr2ProbeRttMode::InflightTarget() const {
-  return model_->BDP(model_->MaxBandwidth(),
-                     Params().probe_rtt_inflight_target_bdp_fraction);
-}
-
-Limits<QuicByteCount> Bbr2ProbeRttMode::GetCwndLimits() const {
-  QuicByteCount inflight_upper_bound =
-      std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom());
-  return NoGreaterThan(std::min(inflight_upper_bound, InflightTarget()));
-}
-
-Bbr2Mode Bbr2ProbeRttMode::OnExitQuiescence(
-    QuicTime now,
-    QuicTime /*quiescence_start_time*/) {
-  if (now > exit_time_) {
-    return Bbr2Mode::PROBE_BW;
-  }
-  return Bbr2Mode::PROBE_RTT;
-}
-
-Bbr2ProbeRttMode::DebugState Bbr2ProbeRttMode::ExportDebugState() const {
-  DebugState s;
-  s.inflight_target = InflightTarget();
-  s.exit_time = exit_time_;
-  return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const Bbr2ProbeRttMode::DebugState& state) {
-  os << "[PROBE_RTT] inflight_target: " << state.inflight_target << "\n";
-  os << "[PROBE_RTT] exit_time: " << state.exit_time << "\n";
-  return os;
-}
-
-const Bbr2Params& Bbr2ProbeRttMode::Params() const {
-  return sender_->Params();
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_probe_rtt.h b/quic/core/congestion_control/bbr2_probe_rtt.h
deleted file mode 100644
index 7d3873d..0000000
--- a/quic/core/congestion_control/bbr2_probe_rtt.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2ProbeRttMode final : public Bbr2ModeBase {
- public:
-  using Bbr2ModeBase::Bbr2ModeBase;
-
-  void Enter(QuicTime now,
-             const Bbr2CongestionEvent* congestion_event) override;
-  void Leave(QuicTime /*now*/,
-             const Bbr2CongestionEvent* /*congestion_event*/) override {}
-
-  Bbr2Mode OnCongestionEvent(
-      QuicByteCount prior_in_flight,
-      QuicTime event_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      const Bbr2CongestionEvent& congestion_event) override;
-
-  Limits<QuicByteCount> GetCwndLimits() const override;
-
-  bool IsProbingForBandwidth() const override { return false; }
-
-  Bbr2Mode OnExitQuiescence(QuicTime now,
-                            QuicTime quiescence_start_time) override;
-
-  struct QUIC_EXPORT_PRIVATE DebugState {
-    QuicByteCount inflight_target;
-    QuicTime exit_time = QuicTime::Zero();
-  };
-
-  DebugState ExportDebugState() const;
-
- private:
-  const Bbr2Params& Params() const;
-
-  QuicByteCount InflightTarget() const;
-
-  QuicTime exit_time_ = QuicTime::Zero();
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const Bbr2ProbeRttMode::DebugState& state);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
deleted file mode 100644
index e60f998..0000000
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ /dev/null
@@ -1,578 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr2_sender.h"
-
-#include <cstddef>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/bbr2_drain.h"
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/print_elements.h"
-
-namespace quic {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
-// Does not inflate the pacing rate.
-const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
-
-const float kInitialPacingGain = 2.885f;
-
-const int kMaxModeChangesPerCongestionEvent = 4;
-}  // namespace
-
-// Call |member_function_call| based on the current Bbr2Mode we are in. e.g.
-//
-//   auto result = BBR2_MODE_DISPATCH(Foo());
-//
-// is equivalent to:
-//
-//   Bbr2ModeBase& Bbr2Sender::GetCurrentMode() {
-//     if (mode_ == Bbr2Mode::STARTUP) { return startup_; }
-//     if (mode_ == Bbr2Mode::DRAIN) { return drain_; }
-//     ...
-//   }
-//   auto result = GetCurrentMode().Foo();
-//
-// Except that BBR2_MODE_DISPATCH guarantees the call to Foo() is non-virtual.
-//
-#define BBR2_MODE_DISPATCH(member_function_call)     \
-  (mode_ == Bbr2Mode::STARTUP                        \
-       ? (startup_.member_function_call)             \
-       : (mode_ == Bbr2Mode::PROBE_BW                \
-              ? (probe_bw_.member_function_call)     \
-              : (mode_ == Bbr2Mode::DRAIN            \
-                     ? (drain_.member_function_call) \
-                     : (probe_rtt_or_die().member_function_call))))
-
-Bbr2Sender::Bbr2Sender(QuicTime now,
-                       const RttStats* rtt_stats,
-                       const QuicUnackedPacketMap* unacked_packets,
-                       QuicPacketCount initial_cwnd_in_packets,
-                       QuicPacketCount max_cwnd_in_packets,
-                       QuicRandom* random,
-                       QuicConnectionStats* stats,
-                       BbrSender* old_sender)
-    : mode_(Bbr2Mode::STARTUP),
-      rtt_stats_(rtt_stats),
-      unacked_packets_(unacked_packets),
-      random_(random),
-      connection_stats_(stats),
-      params_(kDefaultMinimumCongestionWindow,
-              max_cwnd_in_packets * kDefaultTCPMSS),
-      model_(&params_,
-             rtt_stats->SmoothedOrInitialRtt(),
-             rtt_stats->last_update_time(),
-             /*cwnd_gain=*/1.0,
-             /*pacing_gain=*/kInitialPacingGain,
-             old_sender ? &old_sender->sampler_ : nullptr),
-      initial_cwnd_(cwnd_limits().ApplyLimits(
-          (old_sender) ? old_sender->GetCongestionWindow()
-                       : (initial_cwnd_in_packets * kDefaultTCPMSS))),
-      cwnd_(initial_cwnd_),
-      pacing_rate_(kInitialPacingGain * QuicBandwidth::FromBytesAndTimeDelta(
-                                            cwnd_,
-                                            rtt_stats->SmoothedOrInitialRtt())),
-      startup_(this, &model_, now),
-      drain_(this, &model_),
-      probe_bw_(this, &model_),
-      probe_rtt_(this, &model_),
-      last_sample_is_app_limited_(false) {
-  QUIC_DVLOG(2) << this << " Initializing Bbr2Sender. mode:" << mode_
-                << ", PacingRate:" << pacing_rate_ << ", Cwnd:" << cwnd_
-                << ", CwndLimits:" << cwnd_limits() << "  @ " << now;
-  QUICHE_DCHECK_EQ(mode_, Bbr2Mode::STARTUP);
-}
-
-void Bbr2Sender::SetFromConfig(const QuicConfig& config,
-                               Perspective perspective) {
-  if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
-    params_.add_ack_height_to_queueing_threshold = false;
-  }
-  if (config.HasClientRequestedIndependentOption(kB2RP, perspective)) {
-    params_.avoid_unnecessary_probe_rtt = false;
-  }
-  if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
-    params_.startup_full_bw_rounds = 1;
-  }
-  if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
-    params_.startup_full_bw_rounds = 2;
-  }
-  if (config.HasClientRequestedIndependentOption(kB2HR, perspective)) {
-    params_.inflight_hi_headroom = 0.15;
-  }
-  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
-    max_cwnd_when_network_parameters_adjusted_ = 100 * kDefaultTCPMSS;
-  }
-
-  ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
-}
-
-void Bbr2Sender::ApplyConnectionOptions(
-    const QuicTagVector& connection_options) {
-  if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
-      ContainsQuicTag(connection_options, kBBR4)) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 1, 2);
-    model_.SetMaxAckHeightTrackerWindowLength(20);
-  }
-  if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
-      ContainsQuicTag(connection_options, kBBR5)) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 2, 2);
-    model_.SetMaxAckHeightTrackerWindowLength(40);
-  }
-  if (ContainsQuicTag(connection_options, kBBQ2)) {
-    params_.startup_cwnd_gain = 2.885;
-    params_.drain_cwnd_gain = 2.885;
-    model_.set_cwnd_gain(params_.startup_cwnd_gain);
-  }
-  if (ContainsQuicTag(connection_options, kB2LO)) {
-    params_.ignore_inflight_lo = true;
-  }
-  if (ContainsQuicTag(connection_options, kB2NE)) {
-    params_.always_exit_startup_on_excess_loss = true;
-  }
-  if (ContainsQuicTag(connection_options, kB2SL)) {
-    params_.startup_loss_exit_use_max_delivered_for_inflight_hi = false;
-  }
-  if (ContainsQuicTag(connection_options, kB2H2)) {
-    params_.limit_inflight_hi_by_max_delivered = true;
-  }
-  if (ContainsQuicTag(connection_options, kB2DL)) {
-    params_.use_bytes_delivered_for_inflight_hi = true;
-  }
-  if (ContainsQuicTag(connection_options, kB2RC)) {
-    params_.enable_reno_coexistence = false;
-  }
-  if (ContainsQuicTag(connection_options, kBSAO)) {
-    model_.EnableOverestimateAvoidance();
-  }
-  if (ContainsQuicTag(connection_options, kBBQ6)) {
-    params_.decrease_startup_pacing_at_end_of_round = true;
-  }
-  if (ContainsQuicTag(connection_options, kBBQ7)) {
-    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::MIN_RTT_REDUCTION;
-  }
-  if (ContainsQuicTag(connection_options, kBBQ8)) {
-    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::INFLIGHT_REDUCTION;
-  }
-  if (ContainsQuicTag(connection_options, kBBQ9)) {
-    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::CWND_REDUCTION;
-  }
-  if (ContainsQuicTag(connection_options, kB201)) {
-    params_.probe_bw_check_cwnd_limited_before_aggregation_epoch = true;
-  }
-  if (GetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue) &&
-      ContainsQuicTag(connection_options, kB202)) {
-    params_.probe_up_dont_exit_if_no_queue_ = true;
-  }
-  if (GetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up) &&
-      ContainsQuicTag(connection_options, kB203)) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_ignore_inflight_hi_in_probe_up);
-    params_.probe_up_ignore_inflight_hi = true;
-  }
-  if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
-      ContainsQuicTag(connection_options, kB204)) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 1, 2);
-    model_.SetReduceExtraAckedOnBandwidthIncrease(true);
-  }
-  if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
-      ContainsQuicTag(connection_options, kB205)) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 2, 2);
-    params_.startup_include_extra_acked = true;
-  }
-  if (GetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2) &&
-      ContainsQuicTag(connection_options, kB207)) {
-    params_.exit_startup_on_persistent_queue = true;
-  }
-
-  if (ContainsQuicTag(connection_options, kBBRA)) {
-    model_.SetStartNewAggregationEpochAfterFullRound(true);
-  }
-  if (ContainsQuicTag(connection_options, kBBRB)) {
-    model_.SetLimitMaxAckHeightTrackerBySendRate(true);
-  }
-  if (GetQuicReloadableFlag(
-          quic_bbr2_add_bytes_acked_after_inflight_hi_limited) &&
-      ContainsQuicTag(connection_options, kBBQ0)) {
-    params_.probe_up_includes_acks_after_cwnd_limited = true;
-  }
-
-  if (GetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events) &&
-      ContainsQuicTag(connection_options, kB206)) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_startup_probe_up_loss_events);
-    params_.startup_full_loss_count = params_.probe_bw_full_loss_count;
-  }
-}
-
-Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
-  switch (mode_) {
-    case Bbr2Mode::STARTUP:
-      return startup_.GetCwndLimits();
-    case Bbr2Mode::PROBE_BW:
-      return probe_bw_.GetCwndLimits();
-    case Bbr2Mode::DRAIN:
-      return drain_.GetCwndLimits();
-    case Bbr2Mode::PROBE_RTT:
-      return probe_rtt_.GetCwndLimits();
-    default:
-      QUIC_NOTREACHED();
-      return Unlimited<QuicByteCount>();
-  }
-}
-
-const Limits<QuicByteCount>& Bbr2Sender::cwnd_limits() const {
-  return params().cwnd_limits;
-}
-
-void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) {
-  model_.UpdateNetworkParameters(params.rtt);
-
-  if (mode_ == Bbr2Mode::STARTUP) {
-    const QuicByteCount prior_cwnd = cwnd_;
-
-    QuicBandwidth effective_bandwidth =
-        std::max(params.bandwidth, model_.BandwidthEstimate());
-    connection_stats_->cwnd_bootstrapping_rtt_us =
-        model_.MinRtt().ToMicroseconds();
-
-    if (params.max_initial_congestion_window > 0) {
-      max_cwnd_when_network_parameters_adjusted_ =
-          params.max_initial_congestion_window * kDefaultTCPMSS;
-    }
-    cwnd_ = cwnd_limits().ApplyLimits(
-        std::min(max_cwnd_when_network_parameters_adjusted_,
-                 model_.BDP(effective_bandwidth)));
-
-    if (!params.allow_cwnd_to_decrease) {
-      cwnd_ = std::max(cwnd_, prior_cwnd);
-    }
-
-    pacing_rate_ = std::max(pacing_rate_, QuicBandwidth::FromBytesAndTimeDelta(
-                                              cwnd_, model_.MinRtt()));
-  }
-}
-
-void Bbr2Sender::SetInitialCongestionWindowInPackets(
-    QuicPacketCount congestion_window) {
-  if (mode_ == Bbr2Mode::STARTUP) {
-    // The cwnd limits is unchanged and still applies to the new cwnd.
-    cwnd_ = cwnd_limits().ApplyLimits(congestion_window * kDefaultTCPMSS);
-  }
-}
-
-void Bbr2Sender::OnCongestionEvent(bool /*rtt_updated*/,
-                                   QuicByteCount prior_in_flight,
-                                   QuicTime event_time,
-                                   const AckedPacketVector& acked_packets,
-                                   const LostPacketVector& lost_packets) {
-  QUIC_DVLOG(3) << this
-                << " OnCongestionEvent. prior_in_flight:" << prior_in_flight
-                << " prior_cwnd:" << cwnd_ << "  @ " << event_time;
-  Bbr2CongestionEvent congestion_event;
-  congestion_event.prior_cwnd = cwnd_;
-  congestion_event.prior_bytes_in_flight = prior_in_flight;
-  congestion_event.is_probing_for_bandwidth =
-      BBR2_MODE_DISPATCH(IsProbingForBandwidth());
-
-  model_.OnCongestionEventStart(event_time, acked_packets, lost_packets,
-                                &congestion_event);
-
-  if (InSlowStart()) {
-    if (!lost_packets.empty()) {
-      connection_stats_->slowstart_packets_lost += lost_packets.size();
-      connection_stats_->slowstart_bytes_lost += congestion_event.bytes_lost;
-    }
-    if (congestion_event.end_of_round_trip) {
-      ++connection_stats_->slowstart_num_rtts;
-    }
-  }
-
-  // Number of mode changes allowed for this congestion event.
-  int mode_changes_allowed = kMaxModeChangesPerCongestionEvent;
-  while (true) {
-    Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
-        OnCongestionEvent(prior_in_flight, event_time, acked_packets,
-                          lost_packets, congestion_event));
-
-    if (next_mode == mode_) {
-      break;
-    }
-
-    QUIC_DVLOG(2) << this << " Mode change:  " << mode_ << " ==> " << next_mode
-                  << "  @ " << event_time;
-    BBR2_MODE_DISPATCH(Leave(event_time, &congestion_event));
-    mode_ = next_mode;
-    BBR2_MODE_DISPATCH(Enter(event_time, &congestion_event));
-    --mode_changes_allowed;
-    if (mode_changes_allowed < 0) {
-      QUIC_BUG(quic_bug_10443_1)
-          << "Exceeded max number of mode changes per congestion event.";
-      break;
-    }
-  }
-
-  UpdatePacingRate(congestion_event.bytes_acked);
-  QUIC_BUG_IF(quic_bug_10443_2, pacing_rate_.IsZero())
-      << "Pacing rate must not be zero!";
-
-  UpdateCongestionWindow(congestion_event.bytes_acked);
-  QUIC_BUG_IF(quic_bug_10443_3, cwnd_ == 0u)
-      << "Congestion window must not be zero!";
-
-  model_.OnCongestionEventFinish(unacked_packets_->GetLeastUnacked(),
-                                 congestion_event);
-  last_sample_is_app_limited_ =
-      congestion_event.last_packet_send_state.is_app_limited;
-  if (!last_sample_is_app_limited_) {
-    has_non_app_limited_sample_ = true;
-  }
-  if (congestion_event.bytes_in_flight == 0 &&
-      params().avoid_unnecessary_probe_rtt) {
-    OnEnterQuiescence(event_time);
-  }
-
-  QUIC_DVLOG(3)
-      << this
-      << " END CongestionEvent(acked:" << quiche::PrintElements(acked_packets)
-      << ", lost:" << lost_packets.size() << ") "
-      << ", Mode:" << mode_ << ", RttCount:" << model_.RoundTripCount()
-      << ", BytesInFlight:" << congestion_event.bytes_in_flight
-      << ", PacingRate:" << PacingRate(0) << ", CWND:" << GetCongestionWindow()
-      << ", PacingGain:" << model_.pacing_gain()
-      << ", CwndGain:" << model_.cwnd_gain()
-      << ", BandwidthEstimate(kbps):" << BandwidthEstimate().ToKBitsPerSecond()
-      << ", MinRTT(us):" << model_.MinRtt().ToMicroseconds()
-      << ", BDP:" << model_.BDP(BandwidthEstimate())
-      << ", BandwidthLatest(kbps):"
-      << model_.bandwidth_latest().ToKBitsPerSecond()
-      << ", BandwidthLow(kbps):" << model_.bandwidth_lo().ToKBitsPerSecond()
-      << ", BandwidthHigh(kbps):" << model_.MaxBandwidth().ToKBitsPerSecond()
-      << ", InflightLatest:" << model_.inflight_latest()
-      << ", InflightLow:" << model_.inflight_lo()
-      << ", InflightHigh:" << model_.inflight_hi()
-      << ", TotalAcked:" << model_.total_bytes_acked()
-      << ", TotalLost:" << model_.total_bytes_lost()
-      << ", TotalSent:" << model_.total_bytes_sent() << "  @ " << event_time;
-}
-
-void Bbr2Sender::UpdatePacingRate(QuicByteCount bytes_acked) {
-  if (BandwidthEstimate().IsZero()) {
-    return;
-  }
-
-  if (model_.total_bytes_acked() == bytes_acked) {
-    // After the first ACK, cwnd_ is still the initial congestion window.
-    pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(cwnd_, model_.MinRtt());
-    return;
-  }
-
-  QuicBandwidth target_rate = model_.pacing_gain() * model_.BandwidthEstimate();
-  if (model_.full_bandwidth_reached()) {
-    pacing_rate_ = target_rate;
-    return;
-  }
-  if (params_.decrease_startup_pacing_at_end_of_round &&
-      model_.pacing_gain() < Params().startup_pacing_gain) {
-    pacing_rate_ = target_rate;
-    return;
-  }
-  if (params_.bw_lo_mode_ != Bbr2Params::DEFAULT &&
-      model_.loss_events_in_round() > 0) {
-    pacing_rate_ = target_rate;
-    return;
-  }
-
-  // By default, the pacing rate never decreases in STARTUP.
-  if (target_rate > pacing_rate_) {
-    pacing_rate_ = target_rate;
-  }
-}
-
-void Bbr2Sender::UpdateCongestionWindow(QuicByteCount bytes_acked) {
-  QuicByteCount target_cwnd = GetTargetCongestionWindow(model_.cwnd_gain());
-
-  const QuicByteCount prior_cwnd = cwnd_;
-  if (model_.full_bandwidth_reached() || Params().startup_include_extra_acked) {
-    target_cwnd += model_.MaxAckHeight();
-    cwnd_ = std::min(prior_cwnd + bytes_acked, target_cwnd);
-  } else if (prior_cwnd < target_cwnd || prior_cwnd < 2 * initial_cwnd_) {
-    cwnd_ = prior_cwnd + bytes_acked;
-  }
-  const QuicByteCount desired_cwnd = cwnd_;
-
-  cwnd_ = GetCwndLimitsByMode().ApplyLimits(cwnd_);
-  const QuicByteCount model_limited_cwnd = cwnd_;
-
-  cwnd_ = cwnd_limits().ApplyLimits(cwnd_);
-
-  QUIC_DVLOG(3) << this << " Updating CWND. target_cwnd:" << target_cwnd
-                << ", max_ack_height:" << model_.MaxAckHeight()
-                << ", full_bw:" << model_.full_bandwidth_reached()
-                << ", bytes_acked:" << bytes_acked
-                << ", inflight_lo:" << model_.inflight_lo()
-                << ", inflight_hi:" << model_.inflight_hi() << ". (prior_cwnd) "
-                << prior_cwnd << " => (desired_cwnd) " << desired_cwnd
-                << " => (model_limited_cwnd) " << model_limited_cwnd
-                << " => (final_cwnd) " << cwnd_;
-}
-
-QuicByteCount Bbr2Sender::GetTargetCongestionWindow(float gain) const {
-  return std::max(model_.BDP(model_.BandwidthEstimate(), gain),
-                  cwnd_limits().Min());
-}
-
-void Bbr2Sender::OnPacketSent(QuicTime sent_time,
-                              QuicByteCount bytes_in_flight,
-                              QuicPacketNumber packet_number,
-                              QuicByteCount bytes,
-                              HasRetransmittableData is_retransmittable) {
-  QUIC_DVLOG(3) << this << " OnPacketSent: pkn:" << packet_number
-                << ", bytes:" << bytes << ", cwnd:" << cwnd_
-                << ", inflight:" << bytes_in_flight + bytes
-                << ", total_sent:" << model_.total_bytes_sent() + bytes
-                << ", total_acked:" << model_.total_bytes_acked()
-                << ", total_lost:" << model_.total_bytes_lost() << "  @ "
-                << sent_time;
-  if (InSlowStart()) {
-    ++connection_stats_->slowstart_packets_sent;
-    connection_stats_->slowstart_bytes_sent += bytes;
-  }
-  if (bytes_in_flight == 0 && params().avoid_unnecessary_probe_rtt) {
-    OnExitQuiescence(sent_time);
-  }
-  model_.OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
-                      is_retransmittable);
-}
-
-void Bbr2Sender::OnPacketNeutered(QuicPacketNumber packet_number) {
-  model_.OnPacketNeutered(packet_number);
-}
-
-bool Bbr2Sender::CanSend(QuicByteCount bytes_in_flight) {
-  const bool result = bytes_in_flight < GetCongestionWindow();
-  return result;
-}
-
-QuicByteCount Bbr2Sender::GetCongestionWindow() const {
-  // TODO(wub): Implement Recovery?
-  return cwnd_;
-}
-
-QuicBandwidth Bbr2Sender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
-  return pacing_rate_;
-}
-
-void Bbr2Sender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
-  if (bytes_in_flight >= GetCongestionWindow()) {
-    return;
-  }
-
-  model_.OnApplicationLimited();
-  QUIC_DVLOG(2) << this << " Becoming application limited. Last sent packet: "
-                << model_.last_sent_packet()
-                << ", CWND: " << GetCongestionWindow();
-}
-
-QuicByteCount Bbr2Sender::GetTargetBytesInflight() const {
-  QuicByteCount bdp = model_.BDP(model_.BandwidthEstimate());
-  return std::min(bdp, GetCongestionWindow());
-}
-
-void Bbr2Sender::PopulateConnectionStats(QuicConnectionStats* stats) const {
-  stats->num_ack_aggregation_epochs = model_.num_ack_aggregation_epochs();
-}
-
-void Bbr2Sender::OnEnterQuiescence(QuicTime now) {
-  last_quiescence_start_ = now;
-}
-
-void Bbr2Sender::OnExitQuiescence(QuicTime now) {
-  if (last_quiescence_start_ != QuicTime::Zero()) {
-    Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
-        OnExitQuiescence(now, std::min(now, last_quiescence_start_)));
-    if (next_mode != mode_) {
-      BBR2_MODE_DISPATCH(Leave(now, nullptr));
-      mode_ = next_mode;
-      BBR2_MODE_DISPATCH(Enter(now, nullptr));
-    }
-    last_quiescence_start_ = QuicTime::Zero();
-  }
-}
-
-bool Bbr2Sender::ShouldSendProbingPacket() const {
-  // TODO(wub): Implement ShouldSendProbingPacket properly.
-  return BBR2_MODE_DISPATCH(IsProbingForBandwidth());
-}
-
-std::string Bbr2Sender::GetDebugState() const {
-  std::ostringstream stream;
-  stream << ExportDebugState();
-  return stream.str();
-}
-
-Bbr2Sender::DebugState Bbr2Sender::ExportDebugState() const {
-  DebugState s;
-  s.mode = mode_;
-  s.round_trip_count = model_.RoundTripCount();
-  s.bandwidth_hi = model_.MaxBandwidth();
-  s.bandwidth_lo = model_.bandwidth_lo();
-  s.bandwidth_est = BandwidthEstimate();
-  s.inflight_hi = model_.inflight_hi();
-  s.inflight_lo = model_.inflight_lo();
-  s.max_ack_height = model_.MaxAckHeight();
-  s.min_rtt = model_.MinRtt();
-  s.min_rtt_timestamp = model_.MinRttTimestamp();
-  s.congestion_window = cwnd_;
-  s.pacing_rate = pacing_rate_;
-  s.last_sample_is_app_limited = last_sample_is_app_limited_;
-  s.end_of_app_limited_phase = model_.end_of_app_limited_phase();
-
-  s.startup = startup_.ExportDebugState();
-  s.drain = drain_.ExportDebugState();
-  s.probe_bw = probe_bw_.ExportDebugState();
-  s.probe_rtt = probe_rtt_.ExportDebugState();
-
-  return s;
-}
-
-std::ostream& operator<<(std::ostream& os, const Bbr2Sender::DebugState& s) {
-  os << "mode: " << s.mode << "\n";
-  os << "round_trip_count: " << s.round_trip_count << "\n";
-  os << "bandwidth_hi ~ lo ~ est: " << s.bandwidth_hi << " ~ " << s.bandwidth_lo
-     << " ~ " << s.bandwidth_est << "\n";
-  os << "min_rtt: " << s.min_rtt << "\n";
-  os << "min_rtt_timestamp: " << s.min_rtt_timestamp << "\n";
-  os << "congestion_window: " << s.congestion_window << "\n";
-  os << "pacing_rate: " << s.pacing_rate << "\n";
-  os << "last_sample_is_app_limited: " << s.last_sample_is_app_limited << "\n";
-
-  if (s.mode == Bbr2Mode::STARTUP) {
-    os << s.startup;
-  }
-
-  if (s.mode == Bbr2Mode::DRAIN) {
-    os << s.drain;
-  }
-
-  if (s.mode == Bbr2Mode::PROBE_BW) {
-    os << s.probe_bw;
-  }
-
-  if (s.mode == Bbr2Mode::PROBE_RTT) {
-    os << s.probe_rtt;
-  }
-
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_sender.h b/quic/core/congestion_control/bbr2_sender.h
deleted file mode 100644
index 1a2f9d2..0000000
--- a/quic/core/congestion_control/bbr2_sender.h
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
-
-#include <cstdint>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/bbr2_drain.h"
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_probe_bw.h"
-#include "quic/core/congestion_control/bbr2_probe_rtt.h"
-#include "quic/core/congestion_control/bbr2_startup.h"
-#include "quic/core/congestion_control/bbr_sender.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface {
- public:
-  Bbr2Sender(QuicTime now,
-             const RttStats* rtt_stats,
-             const QuicUnackedPacketMap* unacked_packets,
-             QuicPacketCount initial_cwnd_in_packets,
-             QuicPacketCount max_cwnd_in_packets,
-             QuicRandom* random,
-             QuicConnectionStats* stats,
-             BbrSender* old_sender);
-
-  ~Bbr2Sender() override = default;
-
-  // Start implementation of SendAlgorithmInterface.
-  bool InSlowStart() const override { return mode_ == Bbr2Mode::STARTUP; }
-
-  bool InRecovery() const override {
-    // TODO(wub): Implement Recovery.
-    return false;
-  }
-
-  bool ShouldSendProbingPacket() const override;
-
-  void SetFromConfig(const QuicConfig& config,
-                     Perspective perspective) override;
-
-  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
-
-  void AdjustNetworkParameters(const NetworkParams& params) override;
-
-  void SetInitialCongestionWindowInPackets(
-      QuicPacketCount congestion_window) override;
-
-  void OnCongestionEvent(bool rtt_updated,
-                         QuicByteCount prior_in_flight,
-                         QuicTime event_time,
-                         const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets) override;
-
-  void OnPacketSent(QuicTime sent_time,
-                    QuicByteCount bytes_in_flight,
-                    QuicPacketNumber packet_number,
-                    QuicByteCount bytes,
-                    HasRetransmittableData is_retransmittable) override;
-
-  void OnPacketNeutered(QuicPacketNumber packet_number) override;
-
-  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
-
-  void OnConnectionMigration() override {}
-
-  bool CanSend(QuicByteCount bytes_in_flight) override;
-
-  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
-
-  QuicBandwidth BandwidthEstimate() const override {
-    return model_.BandwidthEstimate();
-  }
-
-  bool HasGoodBandwidthEstimateForResumption() const override {
-    return has_non_app_limited_sample_;
-  }
-
-  QuicByteCount GetCongestionWindow() const override;
-
-  QuicByteCount GetSlowStartThreshold() const override { return 0; }
-
-  CongestionControlType GetCongestionControlType() const override {
-    return kBBRv2;
-  }
-
-  std::string GetDebugState() const override;
-
-  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
-
-  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
-  // End implementation of SendAlgorithmInterface.
-
-  const Bbr2Params& Params() const { return params_; }
-
-  QuicByteCount GetMinimumCongestionWindow() const {
-    return cwnd_limits().Min();
-  }
-
-  // Returns the min of BDP and congestion window.
-  QuicByteCount GetTargetBytesInflight() const;
-
-  bool IsBandwidthOverestimateAvoidanceEnabled() const {
-    return model_.IsBandwidthOverestimateAvoidanceEnabled();
-  }
-
-  struct QUIC_EXPORT_PRIVATE DebugState {
-    Bbr2Mode mode;
-
-    // Shared states.
-    QuicRoundTripCount round_trip_count;
-    QuicBandwidth bandwidth_hi = QuicBandwidth::Zero();
-    QuicBandwidth bandwidth_lo = QuicBandwidth::Zero();
-    QuicBandwidth bandwidth_est = QuicBandwidth::Zero();
-    QuicByteCount inflight_hi;
-    QuicByteCount inflight_lo;
-    QuicByteCount max_ack_height;
-    QuicTime::Delta min_rtt = QuicTime::Delta::Zero();
-    QuicTime min_rtt_timestamp = QuicTime::Zero();
-    QuicByteCount congestion_window;
-    QuicBandwidth pacing_rate = QuicBandwidth::Zero();
-    bool last_sample_is_app_limited;
-    QuicPacketNumber end_of_app_limited_phase;
-
-    // Mode-specific debug states.
-    Bbr2StartupMode::DebugState startup;
-    Bbr2DrainMode::DebugState drain;
-    Bbr2ProbeBwMode::DebugState probe_bw;
-    Bbr2ProbeRttMode::DebugState probe_rtt;
-  };
-
-  DebugState ExportDebugState() const;
-
- private:
-  void UpdatePacingRate(QuicByteCount bytes_acked);
-  void UpdateCongestionWindow(QuicByteCount bytes_acked);
-  QuicByteCount GetTargetCongestionWindow(float gain) const;
-  void OnEnterQuiescence(QuicTime now);
-  void OnExitQuiescence(QuicTime now);
-
-  // Helper function for BBR2_MODE_DISPATCH.
-  Bbr2ProbeRttMode& probe_rtt_or_die() {
-    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
-    return probe_rtt_;
-  }
-
-  const Bbr2ProbeRttMode& probe_rtt_or_die() const {
-    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
-    return probe_rtt_;
-  }
-
-  uint64_t RandomUint64(uint64_t max) const {
-    return random_->RandUint64() % max;
-  }
-
-  // Cwnd limits imposed by the current Bbr2 mode.
-  Limits<QuicByteCount> GetCwndLimitsByMode() const;
-
-  // Cwnd limits imposed by caller.
-  const Limits<QuicByteCount>& cwnd_limits() const;
-
-  const Bbr2Params& params() const { return params_; }
-
-  Bbr2Mode mode_;
-
-  const RttStats* const rtt_stats_;
-  const QuicUnackedPacketMap* const unacked_packets_;
-  QuicRandom* random_;
-  QuicConnectionStats* connection_stats_;
-
-  // Don't use it directly outside of SetFromConfig and ApplyConnectionOptions.
-  // Instead, use params() to get read-only access.
-  Bbr2Params params_;
-
-  // Max congestion window when adjusting network parameters.
-  QuicByteCount max_cwnd_when_network_parameters_adjusted_ =
-      kMaxInitialCongestionWindow * kDefaultTCPMSS;
-
-  Bbr2NetworkModel model_;
-
-  const QuicByteCount initial_cwnd_;
-
-  // Current cwnd and pacing rate.
-  QuicByteCount cwnd_;
-  QuicBandwidth pacing_rate_;
-
-  QuicTime last_quiescence_start_ = QuicTime::Zero();
-
-  Bbr2StartupMode startup_;
-  Bbr2DrainMode drain_;
-  Bbr2ProbeBwMode probe_bw_;
-  Bbr2ProbeRttMode probe_rtt_;
-
-  bool has_non_app_limited_sample_ = false;
-
-  // Debug only.
-  bool last_sample_is_app_limited_;
-
-  friend class Bbr2StartupMode;
-  friend class Bbr2DrainMode;
-  friend class Bbr2ProbeBwMode;
-  friend class Bbr2ProbeRttMode;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const Bbr2Sender::DebugState& state);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
diff --git a/quic/core/congestion_control/bbr2_simulator_test.cc b/quic/core/congestion_control/bbr2_simulator_test.cc
deleted file mode 100644
index 0a3a7e7..0000000
--- a/quic/core/congestion_control/bbr2_simulator_test.cc
+++ /dev/null
@@ -1,2298 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <sstream>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/types/optional.h"
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/congestion_control/bbr_sender.h"
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/send_algorithm_test_result.pb.h"
-#include "quic/test_tools/send_algorithm_test_utils.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "quic/test_tools/simulator/traffic_policer.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-using testing::AllOf;
-using testing::Ge;
-using testing::Le;
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, quic_bbr2_test_regression_mode, "",
-    "One of a) 'record' to record test result (one file per test), or "
-    "b) 'regress' to regress against recorded results, or "
-    "c) <anything else> for non-regression mode.");
-
-namespace quic {
-
-using CyclePhase = Bbr2ProbeBwMode::CyclePhase;
-
-namespace test {
-
-// Use the initial CWND of 10, as 32 is too much for the test network.
-const uint32_t kDefaultInitialCwndPackets = 10;
-const uint32_t kDefaultInitialCwndBytes =
-    kDefaultInitialCwndPackets * kDefaultTCPMSS;
-
-struct LinkParams {
-  LinkParams(int64_t kilo_bits_per_sec, int64_t delay_us)
-      : bandwidth(QuicBandwidth::FromKBitsPerSecond(kilo_bits_per_sec)),
-        delay(QuicTime::Delta::FromMicroseconds(delay_us)) {}
-  QuicBandwidth bandwidth;
-  QuicTime::Delta delay;
-};
-
-struct TrafficPolicerParams {
-  std::string name = "policer";
-  QuicByteCount initial_burst_size;
-  QuicByteCount max_bucket_size;
-  QuicBandwidth target_bandwidth = QuicBandwidth::Zero();
-};
-
-// All Bbr2DefaultTopologyTests uses the default network topology:
-//
-//            Sender
-//               |
-//               |  <-- local_link
-//               |
-//        Network switch
-//               *  <-- the bottleneck queue in the direction
-//               |          of the receiver
-//               |
-//               |  <-- test_link
-//               |
-//               |
-//           Receiver
-class DefaultTopologyParams {
- public:
-  LinkParams local_link = {10000, 2000};
-  LinkParams test_link = {4000, 30000};
-
-  const simulator::SwitchPortNumber switch_port_count = 2;
-  // Network switch queue capacity, in number of BDPs.
-  float switch_queue_capacity_in_bdp = 2;
-
-  absl::optional<TrafficPolicerParams> sender_policer_params;
-
-  QuicBandwidth BottleneckBandwidth() const {
-    return std::min(local_link.bandwidth, test_link.bandwidth);
-  }
-
-  // Round trip time of a single full size packet.
-  QuicTime::Delta RTT() const {
-    return 2 * (local_link.delay + test_link.delay +
-                local_link.bandwidth.TransferTime(kMaxOutgoingPacketSize) +
-                test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
-  }
-
-  QuicByteCount BDP() const { return BottleneckBandwidth() * RTT(); }
-
-  QuicByteCount SwitchQueueCapacity() const {
-    return switch_queue_capacity_in_bdp * BDP();
-  }
-
-  std::string ToString() const {
-    std::ostringstream os;
-    os << "{ BottleneckBandwidth: " << BottleneckBandwidth()
-       << " RTT: " << RTT() << " BDP: " << BDP()
-       << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
-    return os.str();
-  }
-};
-
-class Bbr2SimulatorTest : public QuicTest {
- protected:
-  Bbr2SimulatorTest() : simulator_(&random_) {
-    // Prevent the server(receiver), which only sends acks, from closing
-    // connection due to too many outstanding packets.
-    SetQuicFlag(FLAGS_quic_max_tracked_packet_count, 1000000);
-  }
-
-  void SetUp() override {
-    if (GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode) == "regress") {
-      SendAlgorithmTestResult expected;
-      ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
-      random_seed_ = expected.random_seed();
-    } else {
-      random_seed_ = QuicRandom::GetInstance()->RandUint64();
-    }
-    random_.set_seed(random_seed_);
-    QUIC_LOG(INFO) << "Using random seed: " << random_seed_;
-  }
-
-  ~Bbr2SimulatorTest() override {
-    const std::string regression_mode =
-        GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode);
-    const QuicTime::Delta simulated_duration =
-        SimulatedNow() - QuicTime::Zero();
-    if (regression_mode == "record") {
-      RecordSendAlgorithmTestResult(random_seed_,
-                                    simulated_duration.ToMicroseconds());
-    } else if (regression_mode == "regress") {
-      CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
-    }
-  }
-
-  QuicTime SimulatedNow() const { return simulator_.GetClock()->Now(); }
-
-  uint64_t random_seed_;
-  SimpleRandom random_;
-  simulator::Simulator simulator_;
-};
-
-class Bbr2DefaultTopologyTest : public Bbr2SimulatorTest {
- protected:
-  Bbr2DefaultTopologyTest()
-      : sender_endpoint_(&simulator_,
-                         "Sender",
-                         "Receiver",
-                         Perspective::IS_CLIENT,
-                         TestConnectionId(42)),
-        receiver_endpoint_(&simulator_,
-                           "Receiver",
-                           "Sender",
-                           Perspective::IS_SERVER,
-                           TestConnectionId(42)) {
-    sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
-  }
-
-  ~Bbr2DefaultTopologyTest() {
-    const auto* test_info =
-        ::testing::UnitTest::GetInstance()->current_test_info();
-    const Bbr2Sender::DebugState& debug_state = sender_->ExportDebugState();
-    QUIC_LOG(INFO) << "Bbr2DefaultTopologyTest." << test_info->name()
-                   << " completed at simulated time: "
-                   << SimulatedNow().ToDebuggingValue() / 1e6
-                   << " sec. packet loss:"
-                   << sender_loss_rate_in_packets() * 100
-                   << "%, bw_hi:" << debug_state.bandwidth_hi;
-  }
-
-  QuicUnackedPacketMap* GetUnackedMap(QuicConnection* connection) {
-    return QuicSentPacketManagerPeer::GetUnackedPacketMap(
-        QuicConnectionPeer::GetSentPacketManager(connection));
-  }
-
-  Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint,
-                              BbrSender* old_sender) {
-    // Ownership of the sender will be overtaken by the endpoint.
-    Bbr2Sender* sender = new Bbr2Sender(
-        endpoint->connection()->clock()->Now(),
-        endpoint->connection()->sent_packet_manager().GetRttStats(),
-        GetUnackedMap(endpoint->connection()), kDefaultInitialCwndPackets,
-        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
-        QuicConnectionPeer::GetStats(endpoint->connection()), old_sender);
-    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
-    const int kTestMaxPacketSize = 1350;
-    endpoint->connection()->SetMaxPacketLength(kTestMaxPacketSize);
-    endpoint->RecordTrace();
-    return sender;
-  }
-
-  void CreateNetwork(const DefaultTopologyParams& params) {
-    QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
-    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
-                                                  params.switch_port_count,
-                                                  params.SwitchQueueCapacity());
-
-    // WARNING: The order to add links to network_links_ matters, because some
-    // tests adjusts the link bandwidth on the fly.
-
-    // Local link connects sender and port 1.
-    network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
-        &sender_endpoint_, switch_->port(1), params.local_link.bandwidth,
-        params.local_link.delay));
-
-    // Test link connects receiver and port 2.
-    if (params.sender_policer_params.has_value()) {
-      const TrafficPolicerParams& policer_params =
-          params.sender_policer_params.value();
-      sender_policer_ = std::make_unique<simulator::TrafficPolicer>(
-          &simulator_, policer_params.name, policer_params.initial_burst_size,
-          policer_params.max_bucket_size, policer_params.target_bandwidth,
-          switch_->port(2));
-      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
-          &receiver_endpoint_, sender_policer_.get(),
-          params.test_link.bandwidth, params.test_link.delay));
-    } else {
-      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
-          &receiver_endpoint_, switch_->port(2), params.test_link.bandwidth,
-          params.test_link.delay));
-    }
-  }
-
-  simulator::SymmetricLink* TestLink() { return network_links_[1].get(); }
-
-  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta timeout) {
-    sender_endpoint_.AddBytesToTransfer(transfer_size);
-    // TODO(wub): consider rewriting this to run until the receiver actually
-    // receives the intended amount of bytes.
-    bool simulator_result = simulator_.RunUntilOrTimeout(
-        [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-        timeout);
-    EXPECT_TRUE(simulator_result)
-        << "Simple transfer failed.  Bytes remaining: "
-        << sender_endpoint_.bytes_to_transfer();
-    QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
-  }
-
-  // Drive the simulator by sending enough data to enter PROBE_BW.
-  void DriveOutOfStartup(const DefaultTopologyParams& params) {
-    ASSERT_FALSE(sender_->ExportDebugState().startup.full_bandwidth_reached);
-    DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
-    EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
-    EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                     sender_->ExportDebugState().bandwidth_hi, 0.02f);
-  }
-
-  // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
-  // |wait_time| between each burst.
-  void SendBursts(const DefaultTopologyParams& params,
-                  size_t number_of_bursts,
-                  QuicByteCount bytes,
-                  QuicTime::Delta wait_time) {
-    ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
-    for (size_t i = 0; i < number_of_bursts; i++) {
-      sender_endpoint_.AddBytesToTransfer(bytes);
-
-      // Transfer data and wait for three seconds between each transfer.
-      simulator_.RunFor(wait_time);
-
-      // Ensure the connection did not time out.
-      ASSERT_TRUE(sender_endpoint_.connection()->connected());
-      ASSERT_TRUE(receiver_endpoint_.connection()->connected());
-    }
-
-    simulator_.RunFor(wait_time + params.RTT());
-    ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
-  }
-
-  template <class TerminationPredicate>
-  bool SendUntilOrTimeout(TerminationPredicate termination_predicate,
-                          QuicTime::Delta timeout) {
-    EXPECT_EQ(0u, sender_endpoint_.bytes_to_transfer());
-    const QuicTime deadline = SimulatedNow() + timeout;
-    do {
-      sender_endpoint_.AddBytesToTransfer(4 * kDefaultTCPMSS);
-      if (simulator_.RunUntilOrTimeout(
-              [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-              deadline - SimulatedNow()) &&
-          termination_predicate()) {
-        return true;
-      }
-    } while (SimulatedNow() < deadline);
-    return false;
-  }
-
-  void EnableAggregation(QuicByteCount aggregation_bytes,
-                         QuicTime::Delta aggregation_timeout) {
-    switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
-                                              aggregation_timeout);
-  }
-
-  void SetConnectionOption(QuicTag option) {
-    SetConnectionOption(std::move(option), sender_);
-  }
-
-  void SetConnectionOption(QuicTag option, Bbr2Sender* sender) {
-    QuicConfig config;
-    QuicTagVector options;
-    options.push_back(option);
-    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-    sender->SetFromConfig(config, Perspective::IS_SERVER);
-  }
-
-  bool Bbr2ModeIsOneOf(const std::vector<Bbr2Mode>& expected_modes) const {
-    const Bbr2Mode mode = sender_->ExportDebugState().mode;
-    for (Bbr2Mode expected_mode : expected_modes) {
-      if (mode == expected_mode) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  const RttStats* rtt_stats() {
-    return sender_endpoint_.connection()->sent_packet_manager().GetRttStats();
-  }
-
-  QuicConnection* sender_connection() { return sender_endpoint_.connection(); }
-
-  Bbr2Sender::DebugState sender_debug_state() const {
-    return sender_->ExportDebugState();
-  }
-
-  const QuicConnectionStats& sender_connection_stats() {
-    return sender_connection()->GetStats();
-  }
-
-  QuicUnackedPacketMap* sender_unacked_map() {
-    return GetUnackedMap(sender_connection());
-  }
-
-  float sender_loss_rate_in_packets() {
-    return static_cast<float>(sender_connection_stats().packets_lost) /
-           sender_connection_stats().packets_sent;
-  }
-
-  simulator::QuicEndpoint sender_endpoint_;
-  simulator::QuicEndpoint receiver_endpoint_;
-  Bbr2Sender* sender_;
-
-  std::unique_ptr<simulator::Switch> switch_;
-  std::unique_ptr<simulator::TrafficPolicer> sender_policer_;
-  std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
-};
-
-TEST_F(Bbr2DefaultTopologyTest, NormalStartup) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
-          max_bw = sender_->ExportDebugState().bandwidth_hi;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().startup.full_bandwidth_reached;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(
-      3u,
-      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
-  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207) {
-  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
-  SetConnectionOption(kB207);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
-          max_bw = sender_->ExportDebugState().bandwidth_hi;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().startup.full_bandwidth_reached;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(
-      1u,
-      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-}
-
-// Add extra_acked to CWND in STARTUP and exit STARTUP on a persistent queue.
-TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207andB205) {
-  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
-  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
-  SetConnectionOption(kB205);
-  SetConnectionOption(kB207);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
-          max_bw = sender_->ExportDebugState().bandwidth_hi;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().startup.full_bandwidth_reached;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(
-      2u,
-      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-}
-
-// Test a simple long data transfer in the default setup.
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // At startup make sure we are at the default.
-  EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  // And that window is un-affected.
-  EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
-
-  // Verify that Sender is in slow start.
-  EXPECT_TRUE(sender_->InSlowStart());
-
-  // Verify that pacing rate is based on the initial RTT.
-  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      2.885 * kDefaultInitialCwndBytes, rtt_stats()->initial_rtt());
-  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
-                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
-  ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
-
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  // The margin here is quite high, since there exists a possibility that the
-  // connection just exited high gain cycle.
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 1.0f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB2RC) {
-  SetConnectionOption(kB2RC);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB201) {
-  SetConnectionOption(kB201);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB206) {
-  SetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events, true);
-  SetConnectionOption(kB206);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB207) {
-  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
-  SetConnectionOption(kB207);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBRB) {
-  SetConnectionOption(kBBRB);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR4) {
-  SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
-  SetConnectionOption(kBBR4);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR5) {
-  SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
-  SetConnectionOption(kBBR5);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) {
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
-  EXPECT_GE(sender_connection_stats().packets_lost, 0u);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBufferB2H2) {
-  SetConnectionOption(kB2H2);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
-  EXPECT_GE(sender_connection_stats().packets_lost, 0u);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
-  SetConnectionOption(kBSAO);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
-    EXPECT_EQ(sender_loss_rate_in_packets(), 0);
-  } else {
-    EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  }
-  // The margin here is high, because both link level aggregation and ack
-  // decimation can greatly increase smoothed rtt.
-  EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytesB201) {
-  SetConnectionOption(kB201);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  // TODO(wub): Tighten the error bound once BSAO is default enabled.
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.5f);
-
-  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
-    EXPECT_LE(sender_loss_rate_in_packets(), 0.01);
-  } else {
-    EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-  }
-  // The margin here is high, because both link level aggregation and ack
-  // decimation can greatly increase smoothed rtt.
-  EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
-  SetConnectionOption(kBSAO);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.001);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(params.RTT() * 3, rtt_stats()->smoothed_rtt());
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.1f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth decrease during a transfer.
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthDecrease)) {
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
-
-  // We can transfer ~12MB in the first 10 seconds. The rest ~8MB needs about
-  // 640 seconds.
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(10));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth decreasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
-
-  // Now decrease the bottleneck bandwidth from 10Mbps to 100Kbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(800));
-  EXPECT_TRUE(simulator_result);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer.
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncrease)) {
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure the full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBBQ0)) {
-  SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
-                        true);
-  SetConnectionOption(kBBQ0);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure the full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
-       QUIC_SLOW_TEST(BandwidthIncreaseBBQ0Aggregation)) {
-  SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
-                        true);
-  SetConnectionOption(kBBQ0);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Reduce the payload to 2MB because 10MB takes too long.
-  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  // This is much farther off when aggregation is present,
-  // Ideally BSAO or another option would fix this.
-  // TODO(ianswett) Make these bound tighter once overestimation is reduced.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.6f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure at least 10% of full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.90f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB202)) {
-  SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
-  SetConnectionOption(kB202);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure the full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.1f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
-       QUIC_SLOW_TEST(BandwidthIncreaseB202Aggregation)) {
-  SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
-  SetConnectionOption(kB202);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Reduce the payload to 2MB because 10MB takes too long.
-  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  // This is much farther off when aggregation is present,
-  // Ideally BSAO or another option would fix this.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.6f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure at least 10% of full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.92f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB203)) {
-  SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
-  SetConnectionOption(kB203);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure the full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
-       QUIC_SLOW_TEST(BandwidthIncreaseB203Aggregation)) {
-  SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
-  SetConnectionOption(kB203);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Reduce the payload to 2MB because 10MB takes too long.
-  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  // This is much farther off when aggregation is present,
-  // Ideally BSAO or another option would fix this.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.60f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure at least 10% of full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.91f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB204)) {
-  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
-  SetConnectionOption(kB204);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.25);
-  EXPECT_LE(sender_->ExportDebugState().max_ack_height, 2000u);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure the full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
-       QUIC_SLOW_TEST(BandwidthIncreaseB204Aggregation)) {
-  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
-  SetConnectionOption(kB204);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Reduce the payload to 2MB because 10MB takes too long.
-  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  // This is much farther off when aggregation is present, and B204 actually
-  // is increasing overestimation, which is surprising.
-  // Ideally BSAO or another option would fix this.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.60f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
-  EXPECT_LE(sender_->ExportDebugState().max_ack_height, 10000u);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure at least 10% of full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.95f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
-TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB205)) {
-  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
-  SetConnectionOption(kB205);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.1f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.10);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure the full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.1f);
-}
-
-// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
-// in the presence of ACK aggregation.
-TEST_F(Bbr2DefaultTopologyTest,
-       QUIC_SLOW_TEST(BandwidthIncreaseB205Aggregation)) {
-  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
-  SetConnectionOption(kB205);
-  DefaultTopologyParams params;
-  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
-  CreateNetwork(params);
-
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * params.RTT());
-
-  // Reduce the payload to 2MB because 10MB takes too long.
-  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
-
-  // This is much farther off when aggregation is present,
-  // Ideally BSAO or another option would fix this.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_est, 0.45f);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.15);
-
-  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
-  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
-  TestLink()->set_bandwidth(params.test_link.bandwidth);
-
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
-      QuicTime::Delta::FromSeconds(50));
-  EXPECT_TRUE(simulator_result);
-  // Ensure at least 5% of full bandwidth is discovered.
-  EXPECT_APPROX_EQ(params.test_link.bandwidth,
-                   sender_->ExportDebugState().bandwidth_hi, 0.9f);
-}
-
-// Test the number of losses incurred by the startup phase in a situation when
-// the buffer is less than BDP.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossOnSmallBufferStartup) {
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  // Packet loss is smaller with a CWND gain of 2 than 2.889.
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
-}
-
-// Test the number of losses decreases with packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ6SmallBufferStartup) {
-  SetConnectionOption(kBBQ2);  // Increase CWND gain.
-  SetConnectionOption(kBBQ6);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.0575);
-  // bandwidth_lo is cleared exiting STARTUP.
-  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
-            QuicBandwidth::Infinite());
-}
-
-// Test the number of losses decreases with min_rtt packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ7SmallBufferStartup) {
-  SetConnectionOption(kBBQ2);  // Increase CWND gain.
-  SetConnectionOption(kBBQ7);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.06);
-  // bandwidth_lo is cleared exiting STARTUP.
-  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
-            QuicBandwidth::Infinite());
-}
-
-// Test the number of losses decreases with Inflight packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ8SmallBufferStartup) {
-  SetConnectionOption(kBBQ2);  // Increase CWND gain.
-  SetConnectionOption(kBBQ8);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
-  // bandwidth_lo is cleared exiting STARTUP.
-  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
-            QuicBandwidth::Infinite());
-}
-
-// Test the number of losses decreases with CWND packet-conservation pacing.
-TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ9SmallBufferStartup) {
-  SetConnectionOption(kBBQ2);  // Increase CWND gain.
-  SetConnectionOption(kBBQ9);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
-  // bandwidth_lo is cleared exiting STARTUP.
-  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
-            QuicBandwidth::Infinite());
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data after sending continuously for a while.
-TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBursts) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
-  DriveOutOfStartup(params);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
-
-  SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
-  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
-  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data and then starts sending continuously.
-TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBurstsWithoutPrior) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  SendBursts(params, 40, 512, QuicTime::Delta::FromSeconds(3));
-  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  DriveOutOfStartup(params);
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Verify that the DRAIN phase works correctly.
-TEST_F(Bbr2DefaultTopologyTest, Drain) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-  // Get the queue at the bottleneck, which is the outgoing queue at the port to
-  // which the receiver is connected.
-  const simulator::Queue* queue = switch_->port_queue(2);
-  bool simulator_result;
-
-  // We have no intention of ever finishing this transfer.
-  sender_endpoint_.AddBytesToTransfer(100 * 1024 * 1024);
-
-  // Run the startup, and verify that it fills up the queue.
-  ASSERT_EQ(Bbr2Mode::STARTUP, sender_->ExportDebugState().mode);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().mode != Bbr2Mode::STARTUP;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
-                   sender_->PacingRate(0), 0.01f);
-
-  // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer with
-  // approximately 1 BDP.  Here, we use 0.95 to give some margin for error.
-  EXPECT_GE(queue->bytes_queued(), 0.95 * params.BDP());
-
-  // Observe increased RTT due to bufferbloat.
-  const QuicTime::Delta queueing_delay =
-      params.test_link.bandwidth.TransferTime(queue->bytes_queued());
-  EXPECT_APPROX_EQ(params.RTT() + queueing_delay, rtt_stats()->latest_rtt(),
-                   0.1f);
-
-  // Transition to the drain phase and verify that it makes the queue
-  // have at most a BDP worth of packets.
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().mode != Bbr2Mode::DRAIN; },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_LE(queue->bytes_queued(), params.BDP());
-
-  // Wait for a few round trips and ensure we're in appropriate phase of gain
-  // cycling before taking an RTT measurement.
-  const QuicRoundTripCount start_round_trip =
-      sender_->ExportDebugState().round_trip_count;
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this, start_round_trip]() {
-        const auto& debug_state = sender_->ExportDebugState();
-        QuicRoundTripCount rounds_passed =
-            debug_state.round_trip_count - start_round_trip;
-        return rounds_passed >= 4 && debug_state.mode == Bbr2Mode::PROBE_BW &&
-               debug_state.probe_bw.phase == CyclePhase::PROBE_REFILL;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Observe the bufferbloat go away.
-  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 0.1f);
-}
-
-// Ensure that a connection that is app-limited and is at sufficiently low
-// bandwidth will not exit high gain phase, and similarly ensure that the
-// connection will exit low gain early if the number of bytes in flight is low.
-TEST_F(Bbr2DefaultTopologyTest, InFlightAwareGainCycling) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-  DriveOutOfStartup(params);
-
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result;
-
-  // Start a few cycles prior to the high gain one.
-  simulator_result = SendUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().probe_bw.phase ==
-               CyclePhase::PROBE_REFILL;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Send at 10% of available rate.  Run for 3 seconds, checking in the middle
-  // and at the end.  The pacing gain should be high throughout.
-  QuicBandwidth target_bandwidth = 0.1f * params.BottleneckBandwidth();
-  QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
-  for (int i = 0; i < 2; i++) {
-    SendBursts(params, 5, target_bandwidth * burst_interval, burst_interval);
-    EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
-    EXPECT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
-    EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
-                     sender_->ExportDebugState().bandwidth_hi, 0.02f);
-  }
-
-  // Now that in-flight is almost zero and the pacing gain is still above 1,
-  // send approximately 1.4 BDPs worth of data. This should cause the PROBE_BW
-  // mode to enter low gain cycle(PROBE_DOWN), and exit it earlier than one
-  // min_rtt due to running out of data to send.
-  sender_endpoint_.AddBytesToTransfer(1.4 * params.BDP());
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().probe_bw.phase ==
-               CyclePhase::PROBE_DOWN;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
-  EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_EQ(CyclePhase::PROBE_CRUISE,
-            sender_->ExportDebugState().probe_bw.phase);
-}
-
-// Test exiting STARTUP earlier upon loss due to loss.
-TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLoss) {
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
-          max_bw = sender_->ExportDebugState().bandwidth_hi;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().startup.full_bandwidth_reached;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(
-      1u,
-      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
-  EXPECT_NE(0u, sender_connection_stats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  EXPECT_GT(sender_->ExportDebugState().inflight_hi, 1.2f * params.BDP());
-}
-
-// Test exiting STARTUP earlier upon loss due to loss when connection option
-// B2SL is used.
-TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2SL) {
-  SetConnectionOption(kB2SL);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
-          max_bw = sender_->ExportDebugState().bandwidth_hi;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().startup.full_bandwidth_reached;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(
-      1u,
-      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
-  EXPECT_NE(0u, sender_connection_stats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  EXPECT_APPROX_EQ(sender_->ExportDebugState().inflight_hi, params.BDP(), 0.1f);
-}
-
-// Verifies that in STARTUP, if we exceed loss threshold in a round, we exit
-// STARTUP at the end of the round even if there's enough bandwidth growth.
-TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2NE) {
-  // Set up flags such that any loss will be considered "too high".
-  SetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count, 0);
-  SetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold, 0.0);
-
-  sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
-
-  SetConnectionOption(kB2NE);
-  DefaultTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.5;
-  CreateNetwork(params);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
-          max_bw = sender_->ExportDebugState().bandwidth_hi;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().startup.full_bandwidth_reached;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(sender_->ExportDebugState().round_trip_count, max_bw_round);
-  EXPECT_EQ(
-      0u,
-      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
-  EXPECT_NE(0u, sender_connection_stats().packets_lost);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SenderPoliced) {
-  DefaultTopologyParams params;
-  params.sender_policer_params = TrafficPolicerParams();
-  params.sender_policer_params->initial_burst_size = 1000 * 10;
-  params.sender_policer_params->max_bucket_size = 1000 * 100;
-  params.sender_policer_params->target_bandwidth =
-      params.BottleneckBandwidth() * 0.25;
-
-  CreateNetwork(params);
-
-  ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
-
-  DoSimpleTransfer(3 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
-  // TODO(wub): Fix (long-term) bandwidth overestimation in policer mode, then
-  // reduce the loss rate upper bound.
-  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
-}
-
-// TODO(wub): Add other slowstart stats to BBRv2.
-TEST_F(Bbr2DefaultTopologyTest, StartupStats) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  ASSERT_FALSE(sender_->InSlowStart());
-
-  const QuicConnectionStats& stats = sender_connection_stats();
-  // The test explicitly replaces the default-created send algorithm with the
-  // one created by the test. slowstart_count increaments every time a BBR
-  // sender is created.
-  EXPECT_GE(stats.slowstart_count, 1u);
-  EXPECT_FALSE(stats.slowstart_duration.IsRunning());
-  EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
-              AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
-                    Le(QuicTime::Delta::FromMilliseconds(1500))));
-  EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
-            QuicConnectionPeer::GetSentPacketManager(sender_connection())
-                ->GetSlowStartDuration());
-}
-
-TEST_F(Bbr2DefaultTopologyTest, ProbeUpAdaptInflightHiGradually) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-
-  AckedPacketVector acked_packets;
-  QuicPacketNumber acked_packet_number =
-      sender_unacked_map()->GetLeastUnacked();
-  for (auto& info : *sender_unacked_map()) {
-    acked_packets.emplace_back(acked_packet_number++, info.bytes_sent,
-                               SimulatedNow());
-  }
-
-  // Advance time significantly so the OnCongestionEvent enters PROBE_REFILL.
-  QuicTime now = SimulatedNow() + QuicTime::Delta::FromSeconds(5);
-  auto next_packet_number = sender_unacked_map()->largest_sent_packet() + 1;
-  sender_->OnCongestionEvent(
-      /*rtt_updated=*/true, sender_unacked_map()->bytes_in_flight(), now,
-      acked_packets, {});
-  ASSERT_EQ(CyclePhase::PROBE_REFILL,
-            sender_->ExportDebugState().probe_bw.phase);
-
-  // Send and Ack one packet to exit app limited and enter PROBE_UP.
-  sender_->OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
-                        kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
-  now = now + params.RTT();
-  sender_->OnCongestionEvent(
-      /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
-      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {});
-  ASSERT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
-
-  // Send 2 packets and lose the first one(50% loss) to exit PROBE_UP.
-  for (uint64_t i = 0; i < 2; ++i) {
-    sender_->OnPacketSent(now, /*bytes_in_flight=*/i * kDefaultMaxPacketSize,
-                          next_packet_number++, kDefaultMaxPacketSize,
-                          HAS_RETRANSMITTABLE_DATA);
-  }
-  now = now + params.RTT();
-  sender_->OnCongestionEvent(
-      /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
-      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)},
-      {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)});
-
-  QuicByteCount inflight_hi = sender_->ExportDebugState().inflight_hi;
-  EXPECT_LT(2 * kDefaultMaxPacketSize, inflight_hi);
-}
-
-// Ensures bandwidth estimate does not change after a loss only event.
-TEST_F(Bbr2DefaultTopologyTest, LossOnlyCongestionEvent) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  // Send some bursts, each burst increments round count by 1, since it only
-  // generates small, app-limited samples, the max_bandwidth_filter_ will not be
-  // updated.
-  SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
-
-  // Run until we have something in flight.
-  sender_endpoint_.AddBytesToTransfer(50 * 1024 * 1024);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [&]() { return sender_unacked_map()->bytes_in_flight() > 0; },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-
-  const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
-  EXPECT_APPROX_EQ(params.BottleneckBandwidth(), prior_bandwidth_estimate,
-                   0.01f);
-
-  // Lose the least unacked packet.
-  LostPacketVector lost_packets;
-  lost_packets.emplace_back(
-      sender_connection()->sent_packet_manager().GetLeastUnacked(),
-      kDefaultMaxPacketSize);
-
-  QuicTime now = simulator_.GetClock()->Now() + params.RTT() * 0.25;
-  sender_->OnCongestionEvent(false, sender_unacked_map()->bytes_in_flight(),
-                             now, {}, lost_packets);
-
-  // Bandwidth estimate should not change for the loss only event.
-  EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
-}
-
-// After quiescence, if the sender is in PROBE_RTT, it should transition to
-// PROBE_BW immediately on the first sent packet after quiescence.
-TEST_F(Bbr2DefaultTopologyTest, ProbeRttAfterQuiescenceImmediatelyExits) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(15);
-  bool simulator_result;
-
-  // Keep sending until reach PROBE_RTT.
-  simulator_result = SendUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Wait for entering a quiescence of 5 seconds.
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_unacked_map()->bytes_in_flight() == 0 &&
-               sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
-      },
-      timeout));
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(5));
-
-  // Send one packet to exit quiescence.
-  EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_RTT);
-  sender_->OnPacketSent(SimulatedNow(), /*bytes_in_flight=*/0,
-                        sender_unacked_map()->largest_sent_packet() + 1,
-                        kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
-
-  EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_BW);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, ProbeBwAfterQuiescencePostponeMinRttTimestamp) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  DriveOutOfStartup(params);
-
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result;
-
-  // Keep sending until reach PROBE_REFILL.
-  simulator_result = SendUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().probe_bw.phase ==
-               CyclePhase::PROBE_REFILL;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  const QuicTime min_rtt_timestamp_before_idle =
-      sender_->ExportDebugState().min_rtt_timestamp;
-
-  // Wait for entering a quiescence of 15 seconds.
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() { return sender_unacked_map()->bytes_in_flight() == 0; },
-      params.RTT() + timeout));
-
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
-
-  // Send some data to exit quiescence.
-  SendBursts(params, 1, kDefaultTCPMSS, QuicTime::Delta::Zero());
-  const QuicTime min_rtt_timestamp_after_idle =
-      sender_->ExportDebugState().min_rtt_timestamp;
-
-  EXPECT_LT(min_rtt_timestamp_before_idle + QuicTime::Delta::FromSeconds(14),
-            min_rtt_timestamp_after_idle);
-}
-
-TEST_F(Bbr2DefaultTopologyTest, SwitchToBbr2MidConnection) {
-  QuicTime now = QuicTime::Zero();
-  BbrSender old_sender(sender_connection()->clock()->Now(),
-                       sender_connection()->sent_packet_manager().GetRttStats(),
-                       GetUnackedMap(sender_connection()),
-                       kDefaultInitialCwndPackets + 1,
-                       GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
-                       QuicConnectionPeer::GetStats(sender_connection()));
-
-  QuicPacketNumber next_packet_number(1);
-
-  // Send packets 1-4.
-  while (next_packet_number < QuicPacketNumber(5)) {
-    now = now + QuicTime::Delta::FromMilliseconds(10);
-
-    old_sender.OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
-                            /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
-  }
-
-  // Switch from |old_sender| to |sender_|.
-  const QuicByteCount old_sender_cwnd = old_sender.GetCongestionWindow();
-  sender_ = SetupBbr2Sender(&sender_endpoint_, &old_sender);
-  EXPECT_EQ(old_sender_cwnd, sender_->GetCongestionWindow());
-
-  // Send packets 5-7.
-  now = now + QuicTime::Delta::FromMilliseconds(10);
-  sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
-                        /*bytes=*/23, NO_RETRANSMITTABLE_DATA);
-
-  now = now + QuicTime::Delta::FromMilliseconds(10);
-  sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
-                        /*bytes=*/767, HAS_RETRANSMITTABLE_DATA);
-
-  QuicByteCount bytes_in_flight = 767;
-  while (next_packet_number < QuicPacketNumber(30)) {
-    now = now + QuicTime::Delta::FromMilliseconds(10);
-    bytes_in_flight += 1350;
-    sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
-                          /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
-  }
-
-  // Ack 1 & 2.
-  AckedPacketVector acked = {
-      AckedPacket(QuicPacketNumber(1), /*bytes_acked=*/0, QuicTime::Zero()),
-      AckedPacket(QuicPacketNumber(2), /*bytes_acked=*/0, QuicTime::Zero()),
-  };
-  now = now + QuicTime::Delta::FromMilliseconds(2000);
-  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
-
-  // Send 30-41.
-  while (next_packet_number < QuicPacketNumber(42)) {
-    now = now + QuicTime::Delta::FromMilliseconds(10);
-    bytes_in_flight += 1350;
-    sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
-                          /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
-  }
-
-  // Ack 3.
-  acked = {
-      AckedPacket(QuicPacketNumber(3), /*bytes_acked=*/0, QuicTime::Zero()),
-  };
-  now = now + QuicTime::Delta::FromMilliseconds(2000);
-  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
-
-  // Send 42.
-  now = now + QuicTime::Delta::FromMilliseconds(10);
-  bytes_in_flight += 1350;
-  sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
-                        /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
-
-  // Ack 4-7.
-  acked = {
-      AckedPacket(QuicPacketNumber(4), /*bytes_acked=*/0, QuicTime::Zero()),
-      AckedPacket(QuicPacketNumber(5), /*bytes_acked=*/0, QuicTime::Zero()),
-      AckedPacket(QuicPacketNumber(6), /*bytes_acked=*/767, QuicTime::Zero()),
-      AckedPacket(QuicPacketNumber(7), /*bytes_acked=*/1350, QuicTime::Zero()),
-  };
-  now = now + QuicTime::Delta::FromMilliseconds(2000);
-  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
-  EXPECT_FALSE(sender_->BandwidthEstimate().IsZero());
-}
-
-TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  QUIC_LOG(INFO) << "Initial cwnd: " << sender_debug_state().congestion_window
-                 << "\nInitial pacing rate: " << sender_->PacingRate(0)
-                 << "\nInitial bandwidth estimate: "
-                 << sender_->BandwidthEstimate()
-                 << "\nInitial rtt: " << sender_debug_state().min_rtt;
-
-  sender_connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(params.BottleneckBandwidth(),
-                                            params.RTT(),
-                                            /*allow_cwnd_to_decrease=*/false));
-
-  EXPECT_EQ(params.BDP(), sender_->ExportDebugState().congestion_window);
-
-  EXPECT_EQ(params.BottleneckBandwidth(),
-            sender_->PacingRate(/*bytes_in_flight=*/0));
-  EXPECT_NE(params.BottleneckBandwidth(), sender_->BandwidthEstimate());
-
-  EXPECT_APPROX_EQ(params.RTT(), sender_->ExportDebugState().min_rtt, 0.01f);
-
-  DriveOutOfStartup(params);
-}
-
-TEST_F(Bbr2DefaultTopologyTest,
-       200InitialCongestionWindowWithNetworkParameterAdjusted) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
-
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  sender_connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
-                                            QuicTime::Delta::Zero(), false));
-
-  // Verify cwnd is capped at 200.
-  EXPECT_EQ(200 * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
-}
-
-TEST_F(Bbr2DefaultTopologyTest,
-       100InitialCongestionWindowFromNetworkParameter) {
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  SendAlgorithmInterface::NetworkParams network_params(
-      1024 * params.BottleneckBandwidth(), QuicTime::Delta::Zero(), false);
-  network_params.max_initial_congestion_window = 100;
-  sender_connection()->AdjustNetworkParameters(network_params);
-
-  // Verify cwnd is capped at 100.
-  EXPECT_EQ(100 * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
-}
-
-TEST_F(Bbr2DefaultTopologyTest,
-       100InitialCongestionWindowWithNetworkParameterAdjusted) {
-  SetConnectionOption(kICW1);
-  DefaultTopologyParams params;
-  CreateNetwork(params);
-
-  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  sender_connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
-                                            QuicTime::Delta::Zero(), false));
-
-  // Verify cwnd is capped at 100.
-  EXPECT_EQ(100 * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
-}
-
-// All Bbr2MultiSenderTests uses the following network topology:
-//
-//   Sender 0  (A Bbr2Sender)
-//       |
-//       | <-- local_links[0]
-//       |
-//       |  Sender N (1 <= N < kNumLocalLinks) (May or may not be a Bbr2Sender)
-//       |      |
-//       |      | <-- local_links[N]
-//       |      |
-//    Network switch
-//           *  <-- the bottleneck queue in the direction
-//           |          of the receiver
-//           |
-//           |  <-- test_link
-//           |
-//           |
-//       Receiver
-class MultiSenderTopologyParams {
- public:
-  static constexpr size_t kNumLocalLinks = 8;
-  std::array<LinkParams, kNumLocalLinks> local_links = {
-      LinkParams(10000, 1987), LinkParams(10000, 1993), LinkParams(10000, 1997),
-      LinkParams(10000, 1999), LinkParams(10000, 2003), LinkParams(10000, 2011),
-      LinkParams(10000, 2017), LinkParams(10000, 2027),
-  };
-
-  LinkParams test_link = LinkParams(4000, 30000);
-
-  const simulator::SwitchPortNumber switch_port_count = kNumLocalLinks + 1;
-
-  // Network switch queue capacity, in number of BDPs.
-  float switch_queue_capacity_in_bdp = 2;
-
-  QuicBandwidth BottleneckBandwidth() const {
-    // Make sure all local links have a higher bandwidth than the test link.
-    for (size_t i = 0; i < local_links.size(); ++i) {
-      QUICHE_CHECK_GT(local_links[i].bandwidth, test_link.bandwidth);
-    }
-    return test_link.bandwidth;
-  }
-
-  // Sender n's round trip time of a single full size packet.
-  QuicTime::Delta Rtt(size_t n) const {
-    return 2 * (local_links[n].delay + test_link.delay +
-                local_links[n].bandwidth.TransferTime(kMaxOutgoingPacketSize) +
-                test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
-  }
-
-  QuicByteCount Bdp(size_t n) const { return BottleneckBandwidth() * Rtt(n); }
-
-  QuicByteCount SwitchQueueCapacity() const {
-    return switch_queue_capacity_in_bdp * Bdp(1);
-  }
-
-  std::string ToString() const {
-    std::ostringstream os;
-    os << "{ BottleneckBandwidth: " << BottleneckBandwidth();
-    for (size_t i = 0; i < local_links.size(); ++i) {
-      os << " RTT_" << i << ": " << Rtt(i) << " BDP_" << i << ": " << Bdp(i);
-    }
-    os << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
-    return os.str();
-  }
-};
-
-class Bbr2MultiSenderTest : public Bbr2SimulatorTest {
- protected:
-  Bbr2MultiSenderTest() {
-    uint64_t first_connection_id = 42;
-    std::vector<simulator::QuicEndpointBase*> receiver_endpoint_pointers;
-    for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
-      std::string sender_name = absl::StrCat("Sender", i + 1);
-      std::string receiver_name = absl::StrCat("Receiver", i + 1);
-      sender_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
-          &simulator_, sender_name, receiver_name, Perspective::IS_CLIENT,
-          TestConnectionId(first_connection_id + i)));
-      receiver_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
-          &simulator_, receiver_name, sender_name, Perspective::IS_SERVER,
-          TestConnectionId(first_connection_id + i)));
-      receiver_endpoint_pointers.push_back(receiver_endpoints_.back().get());
-    }
-    receiver_multiplexer_ =
-        std::make_unique<simulator::QuicEndpointMultiplexer>(
-            "Receiver multiplexer", receiver_endpoint_pointers);
-    sender_0_ = SetupBbr2Sender(sender_endpoints_[0].get());
-  }
-
-  ~Bbr2MultiSenderTest() {
-    const auto* test_info =
-        ::testing::UnitTest::GetInstance()->current_test_info();
-    QUIC_LOG(INFO) << "Bbr2MultiSenderTest." << test_info->name()
-                   << " completed at simulated time: "
-                   << SimulatedNow().ToDebuggingValue() / 1e6
-                   << " sec. Per sender stats:";
-    for (size_t i = 0; i < sender_endpoints_.size(); ++i) {
-      QUIC_LOG(INFO) << "sender[" << i << "]: "
-                     << sender_connection(i)
-                            ->sent_packet_manager()
-                            .GetSendAlgorithm()
-                            ->GetCongestionControlType()
-                     << ", packet_loss:"
-                     << 100.0 * sender_loss_rate_in_packets(i) << "%";
-    }
-  }
-
-  Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint) {
-    // Ownership of the sender will be overtaken by the endpoint.
-    Bbr2Sender* sender = new Bbr2Sender(
-        endpoint->connection()->clock()->Now(),
-        endpoint->connection()->sent_packet_manager().GetRttStats(),
-        QuicSentPacketManagerPeer::GetUnackedPacketMap(
-            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
-        kDefaultInitialCwndPackets,
-        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
-        QuicConnectionPeer::GetStats(endpoint->connection()), nullptr);
-    // TODO(ianswett): Add dedicated tests for this option until it becomes
-    // the default behavior.
-    SetConnectionOption(sender, kBBRA);
-
-    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
-    endpoint->RecordTrace();
-    return sender;
-  }
-
-  BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
-    // Ownership of the sender will be overtaken by the endpoint.
-    BbrSender* sender = new BbrSender(
-        endpoint->connection()->clock()->Now(),
-        endpoint->connection()->sent_packet_manager().GetRttStats(),
-        QuicSentPacketManagerPeer::GetUnackedPacketMap(
-            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
-        kDefaultInitialCwndPackets,
-        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
-        QuicConnectionPeer::GetStats(endpoint->connection()));
-    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
-    endpoint->RecordTrace();
-    return sender;
-  }
-
-  // reno => Reno. !reno => Cubic.
-  TcpCubicSenderBytes* SetupTcpSender(simulator::QuicEndpoint* endpoint,
-                                      bool reno) {
-    // Ownership of the sender will be overtaken by the endpoint.
-    TcpCubicSenderBytes* sender = new TcpCubicSenderBytes(
-        endpoint->connection()->clock(),
-        endpoint->connection()->sent_packet_manager().GetRttStats(), reno,
-        kDefaultInitialCwndPackets,
-        GetQuicFlag(FLAGS_quic_max_congestion_window),
-        QuicConnectionPeer::GetStats(endpoint->connection()));
-    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
-    endpoint->RecordTrace();
-    return sender;
-  }
-
-  void SetConnectionOption(SendAlgorithmInterface* sender, QuicTag option) {
-    QuicConfig config;
-    QuicTagVector options;
-    options.push_back(option);
-    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-    sender->SetFromConfig(config, Perspective::IS_SERVER);
-  }
-
-  void CreateNetwork(const MultiSenderTopologyParams& params) {
-    QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
-    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
-                                                  params.switch_port_count,
-                                                  params.SwitchQueueCapacity());
-
-    network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
-        receiver_multiplexer_.get(), switch_->port(1),
-        params.test_link.bandwidth, params.test_link.delay));
-    for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
-      simulator::SwitchPortNumber port_number = i + 2;
-      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
-          sender_endpoints_[i].get(), switch_->port(port_number),
-          params.local_links[i].bandwidth, params.local_links[i].delay));
-    }
-  }
-
-  QuicConnection* sender_connection(size_t which) {
-    return sender_endpoints_[which]->connection();
-  }
-
-  const QuicConnectionStats& sender_connection_stats(size_t which) {
-    return sender_connection(which)->GetStats();
-  }
-
-  float sender_loss_rate_in_packets(size_t which) {
-    return static_cast<float>(sender_connection_stats(which).packets_lost) /
-           sender_connection_stats(which).packets_sent;
-  }
-
-  std::vector<std::unique_ptr<simulator::QuicEndpoint>> sender_endpoints_;
-  std::vector<std::unique_ptr<simulator::QuicEndpoint>> receiver_endpoints_;
-  std::unique_ptr<simulator::QuicEndpointMultiplexer> receiver_multiplexer_;
-  Bbr2Sender* sender_0_;
-
-  std::unique_ptr<simulator::Switch> switch_;
-  std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
-};
-
-TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2) {
-  SetupBbr2Sender(sender_endpoints_[1].get());
-
-  MultiSenderTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
-  // Transfer 10% of data in first transfer.
-  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
-      },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
-               receiver_endpoints_[1]->bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(MultipleBbr2s)) {
-  const int kTotalNumSenders = 6;
-  for (int i = 1; i < kTotalNumSenders; ++i) {
-    SetupBbr2Sender(sender_endpoints_[i].get());
-  }
-
-  MultiSenderTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time
-                 << ". Now: " << SimulatedNow();
-
-  // Start all transfers.
-  for (int i = 0; i < kTotalNumSenders; ++i) {
-    if (i != 0) {
-      const QuicTime sender_start_time =
-          SimulatedNow() + QuicTime::Delta::FromSeconds(2);
-      bool simulator_result = simulator_.RunUntilOrTimeout(
-          [&]() { return SimulatedNow() >= sender_start_time; }, transfer_time);
-      ASSERT_TRUE(simulator_result);
-    }
-
-    sender_endpoints_[i]->AddBytesToTransfer(transfer_size);
-  }
-
-  // Wait for all transfers to finish.
-  QuicTime::Delta expected_total_transfer_time_upper_bound =
-      QuicTime::Delta::FromMicroseconds(kTotalNumSenders *
-                                        transfer_time.ToMicroseconds() * 1.1);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        for (int i = 0; i < kTotalNumSenders; ++i) {
-          if (receiver_endpoints_[i]->bytes_received() < transfer_size) {
-            return false;
-          }
-        }
-        return true;
-      },
-      expected_total_transfer_time_upper_bound);
-  ASSERT_TRUE(simulator_result)
-      << "Expected upper bound: " << expected_total_transfer_time_upper_bound;
-}
-
-/* The first 11 packets are sent at the same time, but the duration between the
- * acks of the 1st and the 11th packet is 49 milliseconds, causing very low bw
- * samples. This happens for both large and small buffers.
- */
-/*
-TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2LargeRttTinyBuffer) {
-  SetupBbr2Sender(sender_endpoints_[1].get());
-
-  MultiSenderTopologyParams params;
-  params.switch_queue_capacity_in_bdp = 0.05;
-  params.test_link.delay = QuicTime::Delta::FromSeconds(1);
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
-  // Transfer 10% of data in first transfer.
-  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
-      },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
-               receiver_endpoints_[1]->bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-*/
-
-TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr1) {
-  SetupBbrSender(sender_endpoints_[1].get());
-
-  MultiSenderTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
-  // Transfer 10% of data in first transfer.
-  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
-      },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
-               receiver_endpoints_[1]->bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsReno)) {
-  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
-
-  MultiSenderTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
-  // Transfer 10% of data in first transfer.
-  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
-      },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
-               receiver_endpoints_[1]->bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsRenoB2RC)) {
-  SetConnectionOption(sender_0_, kB2RC);
-  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
-
-  MultiSenderTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
-  // Transfer 10% of data in first transfer.
-  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
-      },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
-               receiver_endpoints_[1]->bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-
-TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsCubic)) {
-  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/false);
-
-  MultiSenderTopologyParams params;
-  CreateNetwork(params);
-
-  const QuicByteCount transfer_size = 50 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      params.BottleneckBandwidth().TransferTime(transfer_size);
-  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
-
-  // Transfer 10% of data in first transfer.
-  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
-      },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
-               receiver_endpoints_[1]->bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_startup.cc b/quic/core/congestion_control/bbr2_startup.cc
deleted file mode 100644
index 690bdb2..0000000
--- a/quic/core/congestion_control/bbr2_startup.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr2_startup.h"
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-Bbr2StartupMode::Bbr2StartupMode(const Bbr2Sender* sender,
-                                 Bbr2NetworkModel* model,
-                                 QuicTime now)
-    : Bbr2ModeBase(sender, model) {
-  // Increment, instead of reset startup stats, so we don't lose data recorded
-  // before QuicConnection switched send algorithm to BBRv2.
-  ++sender_->connection_stats_->slowstart_count;
-  if (!sender_->connection_stats_->slowstart_duration.IsRunning()) {
-    sender_->connection_stats_->slowstart_duration.Start(now);
-  }
-  // Enter() is never called for Startup, so the gains needs to be set here.
-  model_->set_pacing_gain(Params().startup_pacing_gain);
-  model_->set_cwnd_gain(Params().startup_cwnd_gain);
-}
-
-void Bbr2StartupMode::Enter(QuicTime /*now*/,
-                            const Bbr2CongestionEvent* /*congestion_event*/) {
-  QUIC_BUG(quic_bug_10463_1) << "Bbr2StartupMode::Enter should not be called";
-}
-
-void Bbr2StartupMode::Leave(QuicTime now,
-                            const Bbr2CongestionEvent* /*congestion_event*/) {
-  sender_->connection_stats_->slowstart_duration.Stop(now);
-  // Clear bandwidth_lo if it's set during STARTUP.
-  model_->clear_bandwidth_lo();
-}
-
-Bbr2Mode Bbr2StartupMode::OnCongestionEvent(
-    QuicByteCount /*prior_in_flight*/,
-    QuicTime /*event_time*/,
-    const AckedPacketVector& /*acked_packets*/,
-    const LostPacketVector& /*lost_packets*/,
-    const Bbr2CongestionEvent& congestion_event) {
-  if (model_->full_bandwidth_reached()) {
-    QUIC_BUG() << "In STARTUP, but full_bandwidth_reached is true.";
-    return Bbr2Mode::DRAIN;
-  }
-  if (!congestion_event.end_of_round_trip) {
-    return Bbr2Mode::STARTUP;
-  }
-  bool has_bandwidth_growth = model_->HasBandwidthGrowth(congestion_event);
-  if (Params().exit_startup_on_persistent_queue && !has_bandwidth_growth) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_exit_startup_on_persistent_queue2);
-    model_->CheckPersistentQueue(congestion_event, Params().startup_cwnd_gain);
-  }
-  // TCP BBR always exits upon excessive losses. QUIC BBRv1 does not exit
-  // upon excessive losses, if enough bandwidth growth is observed or if the
-  // sample was app limited.
-  if (Params().always_exit_startup_on_excess_loss ||
-      (!congestion_event.last_packet_send_state.is_app_limited &&
-       !has_bandwidth_growth)) {
-    CheckExcessiveLosses(congestion_event);
-  }
-
-  if (Params().decrease_startup_pacing_at_end_of_round) {
-    QUICHE_DCHECK_GT(model_->pacing_gain(), 0);
-    if (!congestion_event.last_packet_send_state.is_app_limited) {
-      // Multiply by startup_pacing_gain, so if the bandwidth doubles,
-      // the pacing gain will be the full startup_pacing_gain.
-      if (max_bw_at_round_beginning_ > QuicBandwidth::Zero()) {
-        const float bandwidth_ratio =
-            std::max(1., model_->MaxBandwidth().ToBitsPerSecond() /
-                             static_cast<double>(
-                                 max_bw_at_round_beginning_.ToBitsPerSecond()));
-        // Even when bandwidth isn't increasing, use a gain large enough to
-        // cause a startup_full_bw_threshold increase.
-        const float new_gain =
-            ((bandwidth_ratio - 1) * (Params().startup_pacing_gain -
-                                      Params().startup_full_bw_threshold)) +
-            Params().startup_full_bw_threshold;
-        // Allow the pacing gain to decrease.
-        model_->set_pacing_gain(
-            std::min(Params().startup_pacing_gain, new_gain));
-        // Clear bandwidth_lo if it's less than the pacing rate.
-        // This avoids a constantly app-limited flow from having it's pacing
-        // gain effectively decreased below 1.25.
-        if (model_->bandwidth_lo() <
-            model_->MaxBandwidth() * model_->pacing_gain()) {
-          model_->clear_bandwidth_lo();
-        }
-      }
-      max_bw_at_round_beginning_ = model_->MaxBandwidth();
-    }
-  }
-
-  // TODO(wub): Maybe implement STARTUP => PROBE_RTT.
-  return model_->full_bandwidth_reached() ? Bbr2Mode::DRAIN : Bbr2Mode::STARTUP;
-}
-
-void Bbr2StartupMode::CheckExcessiveLosses(
-    const Bbr2CongestionEvent& congestion_event) {
-  QUICHE_DCHECK(congestion_event.end_of_round_trip);
-
-  if (model_->full_bandwidth_reached()) {
-    return;
-  }
-
-  // At the end of a round trip. Check if loss is too high in this round.
-  if (model_->IsInflightTooHigh(congestion_event,
-                                Params().startup_full_loss_count)) {
-    QuicByteCount new_inflight_hi = model_->BDP();
-    if (Params().startup_loss_exit_use_max_delivered_for_inflight_hi) {
-      if (new_inflight_hi < model_->max_bytes_delivered_in_round()) {
-        new_inflight_hi = model_->max_bytes_delivered_in_round();
-      }
-    }
-    QUIC_DVLOG(3) << sender_ << " Exiting STARTUP due to loss at round "
-                  << model_->RoundTripCount()
-                  << ". inflight_hi:" << new_inflight_hi;
-    // TODO(ianswett): Add a shared method to set inflight_hi in the model.
-    model_->set_inflight_hi(new_inflight_hi);
-    model_->set_full_bandwidth_reached();
-    sender_->connection_stats_->bbr_exit_startup_due_to_loss = true;
-  }
-}
-
-Bbr2StartupMode::DebugState Bbr2StartupMode::ExportDebugState() const {
-  DebugState s;
-  s.full_bandwidth_reached = model_->full_bandwidth_reached();
-  s.full_bandwidth_baseline = model_->full_bandwidth_baseline();
-  s.round_trips_without_bandwidth_growth =
-      model_->rounds_without_bandwidth_growth();
-  return s;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const Bbr2StartupMode::DebugState& state) {
-  os << "[STARTUP] full_bandwidth_reached: " << state.full_bandwidth_reached
-     << "\n";
-  os << "[STARTUP] full_bandwidth_baseline: " << state.full_bandwidth_baseline
-     << "\n";
-  os << "[STARTUP] round_trips_without_bandwidth_growth: "
-     << state.round_trips_without_bandwidth_growth << "\n";
-  return os;
-}
-
-const Bbr2Params& Bbr2StartupMode::Params() const {
-  return sender_->Params();
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr2_startup.h b/quic/core/congestion_control/bbr2_startup.h
deleted file mode 100644
index a05bac2..0000000
--- a/quic/core/congestion_control/bbr2_startup.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
-
-#include "quic/core/congestion_control/bbr2_misc.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class Bbr2Sender;
-class QUIC_EXPORT_PRIVATE Bbr2StartupMode final : public Bbr2ModeBase {
- public:
-  Bbr2StartupMode(const Bbr2Sender* sender,
-                  Bbr2NetworkModel* model,
-                  QuicTime now);
-
-  void Enter(QuicTime now,
-             const Bbr2CongestionEvent* congestion_event) override;
-  void Leave(QuicTime now,
-             const Bbr2CongestionEvent* congestion_event) override;
-
-  Bbr2Mode OnCongestionEvent(
-      QuicByteCount prior_in_flight,
-      QuicTime event_time,
-      const AckedPacketVector& acked_packets,
-      const LostPacketVector& lost_packets,
-      const Bbr2CongestionEvent& congestion_event) override;
-
-  Limits<QuicByteCount> GetCwndLimits() const override {
-    // Inflight_lo is never set in STARTUP.
-    QUICHE_DCHECK_EQ(Bbr2NetworkModel::inflight_lo_default(),
-                     model_->inflight_lo());
-    return NoGreaterThan(model_->inflight_lo());
-  }
-
-  bool IsProbingForBandwidth() const override { return true; }
-
-  Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
-                            QuicTime /*quiescence_start_time*/) override {
-    return Bbr2Mode::STARTUP;
-  }
-
-  struct QUIC_EXPORT_PRIVATE DebugState {
-    bool full_bandwidth_reached;
-    QuicBandwidth full_bandwidth_baseline = QuicBandwidth::Zero();
-    QuicRoundTripCount round_trips_without_bandwidth_growth;
-  };
-
-  DebugState ExportDebugState() const;
-
- private:
-  const Bbr2Params& Params() const;
-
-  void CheckExcessiveLosses(const Bbr2CongestionEvent& congestion_event);
-  // Used when the pacing gain can decrease in STARTUP.
-  QuicBandwidth max_bw_at_round_beginning_ = QuicBandwidth::Zero();
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const Bbr2StartupMode::DebugState& state);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
diff --git a/quic/core/congestion_control/bbr_sender.cc b/quic/core/congestion_control/bbr_sender.cc
deleted file mode 100644
index db41058..0000000
--- a/quic/core/congestion_control/bbr_sender.cc
+++ /dev/null
@@ -1,914 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr_sender.h"
-
-#include <algorithm>
-#include <sstream>
-#include <string>
-
-#include "absl/base/attributes.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
-// Does not inflate the pacing rate.
-const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
-
-// The gain used for the STARTUP, equal to 2/ln(2).
-const float kDefaultHighGain = 2.885f;
-// The newly derived gain for STARTUP, equal to 4 * ln(2)
-const float kDerivedHighGain = 2.773f;
-// The newly derived CWND gain for STARTUP, 2.
-const float kDerivedHighCWNDGain = 2.0f;
-// The cycle of gains used during the PROBE_BW stage.
-const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
-
-// The length of the gain cycle.
-const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]);
-// The size of the bandwidth filter window, in round-trips.
-const QuicRoundTripCount kBandwidthWindowSize = kGainCycleLength + 2;
-
-// The time after which the current min_rtt value expires.
-const QuicTime::Delta kMinRttExpiry = QuicTime::Delta::FromSeconds(10);
-// The minimum time the connection can spend in PROBE_RTT mode.
-const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200);
-// If the bandwidth does not increase by the factor of |kStartupGrowthTarget|
-// within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection
-// will exit the STARTUP mode.
-const float kStartupGrowthTarget = 1.25;
-const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3;
-}  // namespace
-
-BbrSender::DebugState::DebugState(const BbrSender& sender)
-    : mode(sender.mode_),
-      max_bandwidth(sender.max_bandwidth_.GetBest()),
-      round_trip_count(sender.round_trip_count_),
-      gain_cycle_index(sender.cycle_current_offset_),
-      congestion_window(sender.congestion_window_),
-      is_at_full_bandwidth(sender.is_at_full_bandwidth_),
-      bandwidth_at_last_round(sender.bandwidth_at_last_round_),
-      rounds_without_bandwidth_gain(sender.rounds_without_bandwidth_gain_),
-      min_rtt(sender.min_rtt_),
-      min_rtt_timestamp(sender.min_rtt_timestamp_),
-      recovery_state(sender.recovery_state_),
-      recovery_window(sender.recovery_window_),
-      last_sample_is_app_limited(sender.last_sample_is_app_limited_),
-      end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()) {}
-
-BbrSender::DebugState::DebugState(const DebugState& state) = default;
-
-BbrSender::BbrSender(QuicTime now,
-                     const RttStats* rtt_stats,
-                     const QuicUnackedPacketMap* unacked_packets,
-                     QuicPacketCount initial_tcp_congestion_window,
-                     QuicPacketCount max_tcp_congestion_window,
-                     QuicRandom* random,
-                     QuicConnectionStats* stats)
-    : rtt_stats_(rtt_stats),
-      unacked_packets_(unacked_packets),
-      random_(random),
-      stats_(stats),
-      mode_(STARTUP),
-      sampler_(unacked_packets, kBandwidthWindowSize),
-      round_trip_count_(0),
-      num_loss_events_in_round_(0),
-      bytes_lost_in_round_(0),
-      max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
-      min_rtt_(QuicTime::Delta::Zero()),
-      min_rtt_timestamp_(QuicTime::Zero()),
-      congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
-      initial_congestion_window_(initial_tcp_congestion_window *
-                                 kDefaultTCPMSS),
-      max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
-      min_congestion_window_(kDefaultMinimumCongestionWindow),
-      high_gain_(kDefaultHighGain),
-      high_cwnd_gain_(kDefaultHighGain),
-      drain_gain_(1.f / kDefaultHighGain),
-      pacing_rate_(QuicBandwidth::Zero()),
-      pacing_gain_(1),
-      congestion_window_gain_(1),
-      congestion_window_gain_constant_(
-          static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
-      num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
-      cycle_current_offset_(0),
-      last_cycle_start_(QuicTime::Zero()),
-      is_at_full_bandwidth_(false),
-      rounds_without_bandwidth_gain_(0),
-      bandwidth_at_last_round_(QuicBandwidth::Zero()),
-      exiting_quiescence_(false),
-      exit_probe_rtt_at_(QuicTime::Zero()),
-      probe_rtt_round_passed_(false),
-      last_sample_is_app_limited_(false),
-      has_non_app_limited_sample_(false),
-      recovery_state_(NOT_IN_RECOVERY),
-      recovery_window_(max_congestion_window_),
-      slower_startup_(false),
-      rate_based_startup_(false),
-      enable_ack_aggregation_during_startup_(false),
-      expire_ack_aggregation_in_startup_(false),
-      drain_to_target_(false),
-      detect_overshooting_(false),
-      bytes_lost_while_detecting_overshooting_(0),
-      bytes_lost_multiplier_while_detecting_overshooting_(2),
-      cwnd_to_calculate_min_pacing_rate_(initial_congestion_window_),
-      max_congestion_window_with_network_parameters_adjusted_(
-          kMaxInitialCongestionWindow * kDefaultTCPMSS) {
-  if (stats_) {
-    // Clear some startup stats if |stats_| has been used by another sender,
-    // which happens e.g. when QuicConnection switch send algorithms.
-    stats_->slowstart_count = 0;
-    stats_->slowstart_duration = QuicTimeAccumulator();
-  }
-  EnterStartupMode(now);
-  set_high_cwnd_gain(kDerivedHighCWNDGain);
-}
-
-BbrSender::~BbrSender() {}
-
-void BbrSender::SetInitialCongestionWindowInPackets(
-    QuicPacketCount congestion_window) {
-  if (mode_ == STARTUP) {
-    initial_congestion_window_ = congestion_window * kDefaultTCPMSS;
-    congestion_window_ = congestion_window * kDefaultTCPMSS;
-    cwnd_to_calculate_min_pacing_rate_ = std::min(
-        initial_congestion_window_, cwnd_to_calculate_min_pacing_rate_);
-  }
-}
-
-bool BbrSender::InSlowStart() const {
-  return mode_ == STARTUP;
-}
-
-void BbrSender::OnPacketSent(QuicTime sent_time,
-                             QuicByteCount bytes_in_flight,
-                             QuicPacketNumber packet_number,
-                             QuicByteCount bytes,
-                             HasRetransmittableData is_retransmittable) {
-  if (stats_ && InSlowStart()) {
-    ++stats_->slowstart_packets_sent;
-    stats_->slowstart_bytes_sent += bytes;
-  }
-
-  last_sent_packet_ = packet_number;
-
-  if (bytes_in_flight == 0 && sampler_.is_app_limited()) {
-    exiting_quiescence_ = true;
-  }
-
-  sampler_.OnPacketSent(sent_time, packet_number, bytes, bytes_in_flight,
-                        is_retransmittable);
-}
-
-void BbrSender::OnPacketNeutered(QuicPacketNumber packet_number) {
-  sampler_.OnPacketNeutered(packet_number);
-}
-
-bool BbrSender::CanSend(QuicByteCount bytes_in_flight) {
-  return bytes_in_flight < GetCongestionWindow();
-}
-
-QuicBandwidth BbrSender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
-  if (pacing_rate_.IsZero()) {
-    return high_gain_ * QuicBandwidth::FromBytesAndTimeDelta(
-                            initial_congestion_window_, GetMinRtt());
-  }
-  return pacing_rate_;
-}
-
-QuicBandwidth BbrSender::BandwidthEstimate() const {
-  return max_bandwidth_.GetBest();
-}
-
-QuicByteCount BbrSender::GetCongestionWindow() const {
-  if (mode_ == PROBE_RTT) {
-    return ProbeRttCongestionWindow();
-  }
-
-  if (InRecovery()) {
-    return std::min(congestion_window_, recovery_window_);
-  }
-
-  return congestion_window_;
-}
-
-QuicByteCount BbrSender::GetSlowStartThreshold() const {
-  return 0;
-}
-
-bool BbrSender::InRecovery() const {
-  return recovery_state_ != NOT_IN_RECOVERY;
-}
-
-bool BbrSender::ShouldSendProbingPacket() const {
-  if (pacing_gain_ <= 1) {
-    return false;
-  }
-
-  // TODO(b/77975811): If the pipe is highly under-utilized, consider not
-  // sending a probing transmission, because the extra bandwidth is not needed.
-  return true;
-}
-
-void BbrSender::SetFromConfig(const QuicConfig& config,
-                              Perspective perspective) {
-  if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
-    num_startup_rtts_ = 1;
-  }
-  if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
-    num_startup_rtts_ = 2;
-  }
-  if (config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
-    drain_to_target_ = true;
-  }
-  if (config.HasClientRequestedIndependentOption(kBWM3, perspective)) {
-    bytes_lost_multiplier_while_detecting_overshooting_ = 3;
-  }
-  if (config.HasClientRequestedIndependentOption(kBWM4, perspective)) {
-    bytes_lost_multiplier_while_detecting_overshooting_ = 4;
-  }
-  if (config.HasClientRequestedIndependentOption(kBBR4, perspective)) {
-    sampler_.SetMaxAckHeightTrackerWindowLength(2 * kBandwidthWindowSize);
-  }
-  if (config.HasClientRequestedIndependentOption(kBBR5, perspective)) {
-    sampler_.SetMaxAckHeightTrackerWindowLength(4 * kBandwidthWindowSize);
-  }
-  if (config.HasClientRequestedIndependentOption(kBBQ1, perspective)) {
-    set_high_gain(kDerivedHighGain);
-    set_high_cwnd_gain(kDerivedHighGain);
-    set_drain_gain(1.f / kDerivedHighGain);
-  }
-  if (config.HasClientRequestedIndependentOption(kBBQ3, perspective)) {
-    enable_ack_aggregation_during_startup_ = true;
-  }
-  if (config.HasClientRequestedIndependentOption(kBBQ5, perspective)) {
-    expire_ack_aggregation_in_startup_ = true;
-  }
-  if (config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
-    min_congestion_window_ = kMaxSegmentSize;
-  }
-  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
-    max_congestion_window_with_network_parameters_adjusted_ =
-        100 * kDefaultTCPMSS;
-  }
-  if (config.HasClientRequestedIndependentOption(kDTOS, perspective)) {
-    detect_overshooting_ = true;
-    // DTOS would allow pacing rate drop to IW 10 / min_rtt if overshooting is
-    // detected.
-    cwnd_to_calculate_min_pacing_rate_ =
-        std::min(initial_congestion_window_, 10 * kDefaultTCPMSS);
-  }
-
-  ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
-}
-
-void BbrSender::ApplyConnectionOptions(
-    const QuicTagVector& connection_options) {
-  if (ContainsQuicTag(connection_options, kBSAO)) {
-    sampler_.EnableOverestimateAvoidance();
-  }
-  if (ContainsQuicTag(connection_options, kBBRA)) {
-    sampler_.SetStartNewAggregationEpochAfterFullRound(true);
-  }
-  if (ContainsQuicTag(connection_options, kBBRB)) {
-    sampler_.SetLimitMaxAckHeightTrackerBySendRate(true);
-  }
-}
-
-void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
-  const QuicBandwidth& bandwidth = params.bandwidth;
-  const QuicTime::Delta& rtt = params.rtt;
-
-  if (!rtt.IsZero() && (min_rtt_ > rtt || min_rtt_.IsZero())) {
-    min_rtt_ = rtt;
-  }
-
-  if (mode_ == STARTUP) {
-    if (bandwidth.IsZero()) {
-      // Ignore bad bandwidth samples.
-      return;
-    }
-
-    auto cwnd_bootstrapping_rtt = GetMinRtt();
-    if (params.max_initial_congestion_window > 0) {
-      max_congestion_window_with_network_parameters_adjusted_ =
-          params.max_initial_congestion_window * kDefaultTCPMSS;
-    }
-    const QuicByteCount new_cwnd = std::max(
-        kMinInitialCongestionWindow * kDefaultTCPMSS,
-        std::min(max_congestion_window_with_network_parameters_adjusted_,
-                 bandwidth * cwnd_bootstrapping_rtt));
-
-    stats_->cwnd_bootstrapping_rtt_us = cwnd_bootstrapping_rtt.ToMicroseconds();
-    if (!rtt_stats_->smoothed_rtt().IsZero()) {
-      QUIC_CODE_COUNT(quic_smoothed_rtt_available);
-    } else if (rtt_stats_->initial_rtt() !=
-               QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
-      QUIC_CODE_COUNT(quic_client_initial_rtt_available);
-    } else {
-      QUIC_CODE_COUNT(quic_default_initial_rtt);
-    }
-    if (new_cwnd < congestion_window_ && !params.allow_cwnd_to_decrease) {
-      // Only decrease cwnd if allow_cwnd_to_decrease is true.
-      return;
-    }
-    if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
-      // Decreases cwnd gain and pacing gain. Please note, if pacing_rate_ has
-      // been calculated, it cannot decrease in STARTUP phase.
-      QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_cwnd_and_pacing_gains);
-      set_high_gain(kDerivedHighCWNDGain);
-      set_high_cwnd_gain(kDerivedHighCWNDGain);
-    }
-    congestion_window_ = new_cwnd;
-
-    // Pace at the rate of new_cwnd / RTT.
-    QuicBandwidth new_pacing_rate =
-        QuicBandwidth::FromBytesAndTimeDelta(congestion_window_, GetMinRtt());
-    pacing_rate_ = std::max(pacing_rate_, new_pacing_rate);
-    detect_overshooting_ = true;
-  }
-}
-
-void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
-                                  QuicByteCount prior_in_flight,
-                                  QuicTime event_time,
-                                  const AckedPacketVector& acked_packets,
-                                  const LostPacketVector& lost_packets) {
-  const QuicByteCount total_bytes_acked_before = sampler_.total_bytes_acked();
-  const QuicByteCount total_bytes_lost_before = sampler_.total_bytes_lost();
-
-  bool is_round_start = false;
-  bool min_rtt_expired = false;
-  QuicByteCount excess_acked = 0;
-  QuicByteCount bytes_lost = 0;
-
-  // The send state of the largest packet in acked_packets, unless it is
-  // empty. If acked_packets is empty, it's the send state of the largest
-  // packet in lost_packets.
-  SendTimeState last_packet_send_state;
-
-  if (!acked_packets.empty()) {
-    QuicPacketNumber last_acked_packet = acked_packets.rbegin()->packet_number;
-    is_round_start = UpdateRoundTripCounter(last_acked_packet);
-    UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
-                        is_round_start);
-  }
-
-  BandwidthSamplerInterface::CongestionEventSample sample =
-      sampler_.OnCongestionEvent(event_time, acked_packets, lost_packets,
-                                 max_bandwidth_.GetBest(),
-                                 QuicBandwidth::Infinite(), round_trip_count_);
-  if (sample.last_packet_send_state.is_valid) {
-    last_sample_is_app_limited_ = sample.last_packet_send_state.is_app_limited;
-    has_non_app_limited_sample_ |= !last_sample_is_app_limited_;
-    if (stats_) {
-      stats_->has_non_app_limited_sample = has_non_app_limited_sample_;
-    }
-  }
-  // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all
-  // packets in |acked_packets| did not generate valid samples. (e.g. ack of
-  // ack-only packets). In both cases, sampler_.total_bytes_acked() will not
-  // change.
-  if (total_bytes_acked_before != sampler_.total_bytes_acked()) {
-    QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
-        << sampler_.total_bytes_acked() - total_bytes_acked_before
-        << " bytes from " << acked_packets.size()
-        << " packets have been acked, but sample_max_bandwidth is zero.";
-    if (!sample.sample_is_app_limited ||
-        sample.sample_max_bandwidth > max_bandwidth_.GetBest()) {
-      max_bandwidth_.Update(sample.sample_max_bandwidth, round_trip_count_);
-    }
-  }
-
-  if (!sample.sample_rtt.IsInfinite()) {
-    min_rtt_expired = MaybeUpdateMinRtt(event_time, sample.sample_rtt);
-  }
-  bytes_lost = sampler_.total_bytes_lost() - total_bytes_lost_before;
-  if (mode_ == STARTUP) {
-    if (stats_) {
-      stats_->slowstart_packets_lost += lost_packets.size();
-      stats_->slowstart_bytes_lost += bytes_lost;
-    }
-  }
-  excess_acked = sample.extra_acked;
-  last_packet_send_state = sample.last_packet_send_state;
-
-  if (!lost_packets.empty()) {
-    ++num_loss_events_in_round_;
-    bytes_lost_in_round_ += bytes_lost;
-  }
-
-  // Handle logic specific to PROBE_BW mode.
-  if (mode_ == PROBE_BW) {
-    UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty());
-  }
-
-  // Handle logic specific to STARTUP and DRAIN modes.
-  if (is_round_start && !is_at_full_bandwidth_) {
-    CheckIfFullBandwidthReached(last_packet_send_state);
-  }
-  MaybeExitStartupOrDrain(event_time);
-
-  // Handle logic specific to PROBE_RTT.
-  MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired);
-
-  // Calculate number of packets acked and lost.
-  QuicByteCount bytes_acked =
-      sampler_.total_bytes_acked() - total_bytes_acked_before;
-
-  // After the model is updated, recalculate the pacing rate and congestion
-  // window.
-  CalculatePacingRate(bytes_lost);
-  CalculateCongestionWindow(bytes_acked, excess_acked);
-  CalculateRecoveryWindow(bytes_acked, bytes_lost);
-
-  // Cleanup internal state.
-  sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked());
-  if (is_round_start) {
-    num_loss_events_in_round_ = 0;
-    bytes_lost_in_round_ = 0;
-  }
-}
-
-CongestionControlType BbrSender::GetCongestionControlType() const {
-  return kBBR;
-}
-
-QuicTime::Delta BbrSender::GetMinRtt() const {
-  if (!min_rtt_.IsZero()) {
-    return min_rtt_;
-  }
-  // min_rtt could be available if the handshake packet gets neutered then
-  // gets acknowledged. This could only happen for QUIC crypto where we do not
-  // drop keys.
-  return rtt_stats_->MinOrInitialRtt();
-}
-
-QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
-  QuicByteCount bdp = GetMinRtt() * BandwidthEstimate();
-  QuicByteCount congestion_window = gain * bdp;
-
-  // BDP estimate will be zero if no bandwidth samples are available yet.
-  if (congestion_window == 0) {
-    congestion_window = gain * initial_congestion_window_;
-  }
-
-  return std::max(congestion_window, min_congestion_window_);
-}
-
-QuicByteCount BbrSender::ProbeRttCongestionWindow() const {
-  return min_congestion_window_;
-}
-
-void BbrSender::EnterStartupMode(QuicTime now) {
-  if (stats_) {
-    ++stats_->slowstart_count;
-    stats_->slowstart_duration.Start(now);
-  }
-  mode_ = STARTUP;
-  pacing_gain_ = high_gain_;
-  congestion_window_gain_ = high_cwnd_gain_;
-}
-
-void BbrSender::EnterProbeBandwidthMode(QuicTime now) {
-  mode_ = PROBE_BW;
-  congestion_window_gain_ = congestion_window_gain_constant_;
-
-  // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is
-  // excluded because in that case increased gain and decreased gain would not
-  // follow each other.
-  cycle_current_offset_ = random_->RandUint64() % (kGainCycleLength - 1);
-  if (cycle_current_offset_ >= 1) {
-    cycle_current_offset_ += 1;
-  }
-
-  last_cycle_start_ = now;
-  pacing_gain_ = kPacingGain[cycle_current_offset_];
-}
-
-bool BbrSender::UpdateRoundTripCounter(QuicPacketNumber last_acked_packet) {
-  if (!current_round_trip_end_.IsInitialized() ||
-      last_acked_packet > current_round_trip_end_) {
-    round_trip_count_++;
-    current_round_trip_end_ = last_sent_packet_;
-    if (stats_ && InSlowStart()) {
-      ++stats_->slowstart_num_rtts;
-    }
-    return true;
-  }
-
-  return false;
-}
-
-bool BbrSender::MaybeUpdateMinRtt(QuicTime now,
-                                  QuicTime::Delta sample_min_rtt) {
-  // Do not expire min_rtt if none was ever available.
-  bool min_rtt_expired =
-      !min_rtt_.IsZero() && (now > (min_rtt_timestamp_ + kMinRttExpiry));
-
-  if (min_rtt_expired || sample_min_rtt < min_rtt_ || min_rtt_.IsZero()) {
-    QUIC_DVLOG(2) << "Min RTT updated, old value: " << min_rtt_
-                  << ", new value: " << sample_min_rtt
-                  << ", current time: " << now.ToDebuggingValue();
-
-    min_rtt_ = sample_min_rtt;
-    min_rtt_timestamp_ = now;
-  }
-  QUICHE_DCHECK(!min_rtt_.IsZero());
-
-  return min_rtt_expired;
-}
-
-void BbrSender::UpdateGainCyclePhase(QuicTime now,
-                                     QuicByteCount prior_in_flight,
-                                     bool has_losses) {
-  const QuicByteCount bytes_in_flight = unacked_packets_->bytes_in_flight();
-  // In most cases, the cycle is advanced after an RTT passes.
-  bool should_advance_gain_cycling = now - last_cycle_start_ > GetMinRtt();
-
-  // If the pacing gain is above 1.0, the connection is trying to probe the
-  // bandwidth by increasing the number of bytes in flight to at least
-  // pacing_gain * BDP.  Make sure that it actually reaches the target, as long
-  // as there are no losses suggesting that the buffers are not able to hold
-  // that much.
-  if (pacing_gain_ > 1.0 && !has_losses &&
-      prior_in_flight < GetTargetCongestionWindow(pacing_gain_)) {
-    should_advance_gain_cycling = false;
-  }
-
-  // If pacing gain is below 1.0, the connection is trying to drain the extra
-  // queue which could have been incurred by probing prior to it.  If the number
-  // of bytes in flight falls down to the estimated BDP value earlier, conclude
-  // that the queue has been successfully drained and exit this cycle early.
-  if (pacing_gain_ < 1.0 && bytes_in_flight <= GetTargetCongestionWindow(1)) {
-    should_advance_gain_cycling = true;
-  }
-
-  if (should_advance_gain_cycling) {
-    cycle_current_offset_ = (cycle_current_offset_ + 1) % kGainCycleLength;
-    if (cycle_current_offset_ == 0) {
-      ++stats_->bbr_num_cycles;
-    }
-    last_cycle_start_ = now;
-    // Stay in low gain mode until the target BDP is hit.
-    // Low gain mode will be exited immediately when the target BDP is achieved.
-    if (drain_to_target_ && pacing_gain_ < 1 &&
-        kPacingGain[cycle_current_offset_] == 1 &&
-        bytes_in_flight > GetTargetCongestionWindow(1)) {
-      return;
-    }
-    pacing_gain_ = kPacingGain[cycle_current_offset_];
-  }
-}
-
-void BbrSender::CheckIfFullBandwidthReached(
-    const SendTimeState& last_packet_send_state) {
-  if (last_sample_is_app_limited_) {
-    return;
-  }
-
-  QuicBandwidth target = bandwidth_at_last_round_ * kStartupGrowthTarget;
-  if (BandwidthEstimate() >= target) {
-    bandwidth_at_last_round_ = BandwidthEstimate();
-    rounds_without_bandwidth_gain_ = 0;
-    if (expire_ack_aggregation_in_startup_) {
-      // Expire old excess delivery measurements now that bandwidth increased.
-      sampler_.ResetMaxAckHeightTracker(0, round_trip_count_);
-    }
-    return;
-  }
-
-  rounds_without_bandwidth_gain_++;
-  if ((rounds_without_bandwidth_gain_ >= num_startup_rtts_) ||
-      ShouldExitStartupDueToLoss(last_packet_send_state)) {
-    QUICHE_DCHECK(has_non_app_limited_sample_);
-    is_at_full_bandwidth_ = true;
-  }
-}
-
-void BbrSender::MaybeExitStartupOrDrain(QuicTime now) {
-  if (mode_ == STARTUP && is_at_full_bandwidth_) {
-    OnExitStartup(now);
-    mode_ = DRAIN;
-    pacing_gain_ = drain_gain_;
-    congestion_window_gain_ = high_cwnd_gain_;
-  }
-  if (mode_ == DRAIN &&
-      unacked_packets_->bytes_in_flight() <= GetTargetCongestionWindow(1)) {
-    EnterProbeBandwidthMode(now);
-  }
-}
-
-void BbrSender::OnExitStartup(QuicTime now) {
-  QUICHE_DCHECK_EQ(mode_, STARTUP);
-  if (stats_) {
-    stats_->slowstart_duration.Stop(now);
-  }
-}
-
-bool BbrSender::ShouldExitStartupDueToLoss(
-    const SendTimeState& last_packet_send_state) const {
-  if (num_loss_events_in_round_ <
-          GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count) ||
-      !last_packet_send_state.is_valid) {
-    return false;
-  }
-
-  const QuicByteCount inflight_at_send = last_packet_send_state.bytes_in_flight;
-
-  if (inflight_at_send > 0 && bytes_lost_in_round_ > 0) {
-    if (bytes_lost_in_round_ >
-        inflight_at_send *
-            GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold)) {
-      stats_->bbr_exit_startup_due_to_loss = true;
-      return true;
-    }
-    return false;
-  }
-
-  return false;
-}
-
-void BbrSender::MaybeEnterOrExitProbeRtt(QuicTime now,
-                                         bool is_round_start,
-                                         bool min_rtt_expired) {
-  if (min_rtt_expired && !exiting_quiescence_ && mode_ != PROBE_RTT) {
-    if (InSlowStart()) {
-      OnExitStartup(now);
-    }
-    mode_ = PROBE_RTT;
-    pacing_gain_ = 1;
-    // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight|
-    // is at the target small value.
-    exit_probe_rtt_at_ = QuicTime::Zero();
-  }
-
-  if (mode_ == PROBE_RTT) {
-    sampler_.OnAppLimited();
-
-    if (exit_probe_rtt_at_ == QuicTime::Zero()) {
-      // If the window has reached the appropriate size, schedule exiting
-      // PROBE_RTT.  The CWND during PROBE_RTT is kMinimumCongestionWindow, but
-      // we allow an extra packet since QUIC checks CWND before sending a
-      // packet.
-      if (unacked_packets_->bytes_in_flight() <
-          ProbeRttCongestionWindow() + kMaxOutgoingPacketSize) {
-        exit_probe_rtt_at_ = now + kProbeRttTime;
-        probe_rtt_round_passed_ = false;
-      }
-    } else {
-      if (is_round_start) {
-        probe_rtt_round_passed_ = true;
-      }
-      if (now >= exit_probe_rtt_at_ && probe_rtt_round_passed_) {
-        min_rtt_timestamp_ = now;
-        if (!is_at_full_bandwidth_) {
-          EnterStartupMode(now);
-        } else {
-          EnterProbeBandwidthMode(now);
-        }
-      }
-    }
-  }
-
-  exiting_quiescence_ = false;
-}
-
-void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet,
-                                    bool has_losses,
-                                    bool is_round_start) {
-  // Disable recovery in startup, if loss-based exit is enabled.
-  if (!is_at_full_bandwidth_) {
-    return;
-  }
-
-  // Exit recovery when there are no losses for a round.
-  if (has_losses) {
-    end_recovery_at_ = last_sent_packet_;
-  }
-
-  switch (recovery_state_) {
-    case NOT_IN_RECOVERY:
-      // Enter conservation on the first loss.
-      if (has_losses) {
-        recovery_state_ = CONSERVATION;
-        // This will cause the |recovery_window_| to be set to the correct
-        // value in CalculateRecoveryWindow().
-        recovery_window_ = 0;
-        // Since the conservation phase is meant to be lasting for a whole
-        // round, extend the current round as if it were started right now.
-        current_round_trip_end_ = last_sent_packet_;
-      }
-      break;
-
-    case CONSERVATION:
-      if (is_round_start) {
-        recovery_state_ = GROWTH;
-      }
-      ABSL_FALLTHROUGH_INTENDED;
-
-    case GROWTH:
-      // Exit recovery if appropriate.
-      if (!has_losses && last_acked_packet > end_recovery_at_) {
-        recovery_state_ = NOT_IN_RECOVERY;
-      }
-
-      break;
-  }
-}
-
-void BbrSender::CalculatePacingRate(QuicByteCount bytes_lost) {
-  if (BandwidthEstimate().IsZero()) {
-    return;
-  }
-
-  QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate();
-  if (is_at_full_bandwidth_) {
-    pacing_rate_ = target_rate;
-    return;
-  }
-
-  // Pace at the rate of initial_window / RTT as soon as RTT measurements are
-  // available.
-  if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) {
-    pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(
-        initial_congestion_window_, rtt_stats_->min_rtt());
-    return;
-  }
-
-  if (detect_overshooting_) {
-    bytes_lost_while_detecting_overshooting_ += bytes_lost;
-    // Check for overshooting with network parameters adjusted when pacing rate
-    // > target_rate and loss has been detected.
-    if (pacing_rate_ > target_rate &&
-        bytes_lost_while_detecting_overshooting_ > 0) {
-      if (has_non_app_limited_sample_ ||
-          bytes_lost_while_detecting_overshooting_ *
-                  bytes_lost_multiplier_while_detecting_overshooting_ >
-              initial_congestion_window_) {
-        // We are fairly sure overshoot happens if 1) there is at least one
-        // non app-limited bw sample or 2) half of IW gets lost. Slow pacing
-        // rate.
-        pacing_rate_ = std::max(
-            target_rate, QuicBandwidth::FromBytesAndTimeDelta(
-                             cwnd_to_calculate_min_pacing_rate_, GetMinRtt()));
-        if (stats_) {
-          stats_->overshooting_detected_with_network_parameters_adjusted = true;
-        }
-        bytes_lost_while_detecting_overshooting_ = 0;
-        detect_overshooting_ = false;
-      }
-    }
-  }
-
-  // Do not decrease the pacing rate during startup.
-  pacing_rate_ = std::max(pacing_rate_, target_rate);
-}
-
-void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked,
-                                          QuicByteCount excess_acked) {
-  if (mode_ == PROBE_RTT) {
-    return;
-  }
-
-  QuicByteCount target_window =
-      GetTargetCongestionWindow(congestion_window_gain_);
-  if (is_at_full_bandwidth_) {
-    // Add the max recently measured ack aggregation to CWND.
-    target_window += sampler_.max_ack_height();
-  } else if (enable_ack_aggregation_during_startup_) {
-    // Add the most recent excess acked.  Because CWND never decreases in
-    // STARTUP, this will automatically create a very localized max filter.
-    target_window += excess_acked;
-  }
-
-  // Instead of immediately setting the target CWND as the new one, BBR grows
-  // the CWND towards |target_window| by only increasing it |bytes_acked| at a
-  // time.
-  if (is_at_full_bandwidth_) {
-    congestion_window_ =
-        std::min(target_window, congestion_window_ + bytes_acked);
-  } else if (congestion_window_ < target_window ||
-             sampler_.total_bytes_acked() < initial_congestion_window_) {
-    // If the connection is not yet out of startup phase, do not decrease the
-    // window.
-    congestion_window_ = congestion_window_ + bytes_acked;
-  }
-
-  // Enforce the limits on the congestion window.
-  congestion_window_ = std::max(congestion_window_, min_congestion_window_);
-  congestion_window_ = std::min(congestion_window_, max_congestion_window_);
-}
-
-void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
-                                        QuicByteCount bytes_lost) {
-  if (recovery_state_ == NOT_IN_RECOVERY) {
-    return;
-  }
-
-  // Set up the initial recovery window.
-  if (recovery_window_ == 0) {
-    recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
-    recovery_window_ = std::max(min_congestion_window_, recovery_window_);
-    return;
-  }
-
-  // Remove losses from the recovery window, while accounting for a potential
-  // integer underflow.
-  recovery_window_ = recovery_window_ >= bytes_lost
-                         ? recovery_window_ - bytes_lost
-                         : kMaxSegmentSize;
-
-  // In CONSERVATION mode, just subtracting losses is sufficient.  In GROWTH,
-  // release additional |bytes_acked| to achieve a slow-start-like behavior.
-  if (recovery_state_ == GROWTH) {
-    recovery_window_ += bytes_acked;
-  }
-
-  // Always allow sending at least |bytes_acked| in response.
-  recovery_window_ = std::max(
-      recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
-  recovery_window_ = std::max(min_congestion_window_, recovery_window_);
-}
-
-std::string BbrSender::GetDebugState() const {
-  std::ostringstream stream;
-  stream << ExportDebugState();
-  return stream.str();
-}
-
-void BbrSender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
-  if (bytes_in_flight >= GetCongestionWindow()) {
-    return;
-  }
-
-  sampler_.OnAppLimited();
-  QUIC_DVLOG(2) << "Becoming application limited. Last sent packet: "
-                << last_sent_packet_ << ", CWND: " << GetCongestionWindow();
-}
-
-void BbrSender::PopulateConnectionStats(QuicConnectionStats* stats) const {
-  stats->num_ack_aggregation_epochs = sampler_.num_ack_aggregation_epochs();
-}
-
-BbrSender::DebugState BbrSender::ExportDebugState() const {
-  return DebugState(*this);
-}
-
-static std::string ModeToString(BbrSender::Mode mode) {
-  switch (mode) {
-    case BbrSender::STARTUP:
-      return "STARTUP";
-    case BbrSender::DRAIN:
-      return "DRAIN";
-    case BbrSender::PROBE_BW:
-      return "PROBE_BW";
-    case BbrSender::PROBE_RTT:
-      return "PROBE_RTT";
-  }
-  return "???";
-}
-
-std::ostream& operator<<(std::ostream& os, const BbrSender::Mode& mode) {
-  os << ModeToString(mode);
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const BbrSender::DebugState& state) {
-  os << "Mode: " << ModeToString(state.mode) << std::endl;
-  os << "Maximum bandwidth: " << state.max_bandwidth << std::endl;
-  os << "Round trip counter: " << state.round_trip_count << std::endl;
-  os << "Gain cycle index: " << static_cast<int>(state.gain_cycle_index)
-     << std::endl;
-  os << "Congestion window: " << state.congestion_window << " bytes"
-     << std::endl;
-
-  if (state.mode == BbrSender::STARTUP) {
-    os << "(startup) Bandwidth at last round: " << state.bandwidth_at_last_round
-       << std::endl;
-    os << "(startup) Rounds without gain: "
-       << state.rounds_without_bandwidth_gain << std::endl;
-  }
-
-  os << "Minimum RTT: " << state.min_rtt << std::endl;
-  os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
-     << std::endl;
-
-  os << "Last sample is app-limited: "
-     << (state.last_sample_is_app_limited ? "yes" : "no");
-
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/bbr_sender.h b/quic/core/congestion_control/bbr_sender.h
deleted file mode 100644
index 49b3a34..0000000
--- a/quic/core/congestion_control/bbr_sender.h
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// BBR (Bottleneck Bandwidth and RTT) congestion control algorithm.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-
-#include "quic/core/congestion_control/bandwidth_sampler.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/windowed_filter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class RttStats;
-
-// BbrSender implements BBR congestion control algorithm.  BBR aims to estimate
-// the current available Bottleneck Bandwidth and RTT (hence the name), and
-// regulates the pacing rate and the size of the congestion window based on
-// those signals.
-//
-// BBR relies on pacing in order to function properly.  Do not use BBR when
-// pacing is disabled.
-//
-// TODO(vasilvv): implement traffic policer (long-term sampling) mode.
-class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
- public:
-  enum Mode {
-    // Startup phase of the connection.
-    STARTUP,
-    // After achieving the highest possible bandwidth during the startup, lower
-    // the pacing rate in order to drain the queue.
-    DRAIN,
-    // Cruising mode.
-    PROBE_BW,
-    // Temporarily slow down sending in order to empty the buffer and measure
-    // the real minimum RTT.
-    PROBE_RTT,
-  };
-
-  // Indicates how the congestion control limits the amount of bytes in flight.
-  enum RecoveryState {
-    // Do not limit.
-    NOT_IN_RECOVERY,
-    // Allow an extra outstanding byte for each byte acknowledged.
-    CONSERVATION,
-    // Allow two extra outstanding bytes for each byte acknowledged (slow
-    // start).
-    GROWTH
-  };
-
-  // Debug state can be exported in order to troubleshoot potential congestion
-  // control issues.
-  struct QUIC_EXPORT_PRIVATE DebugState {
-    explicit DebugState(const BbrSender& sender);
-    DebugState(const DebugState& state);
-
-    Mode mode;
-    QuicBandwidth max_bandwidth;
-    QuicRoundTripCount round_trip_count;
-    int gain_cycle_index;
-    QuicByteCount congestion_window;
-
-    bool is_at_full_bandwidth;
-    QuicBandwidth bandwidth_at_last_round;
-    QuicRoundTripCount rounds_without_bandwidth_gain;
-
-    QuicTime::Delta min_rtt;
-    QuicTime min_rtt_timestamp;
-
-    RecoveryState recovery_state;
-    QuicByteCount recovery_window;
-
-    bool last_sample_is_app_limited;
-    QuicPacketNumber end_of_app_limited_phase;
-  };
-
-  BbrSender(QuicTime now,
-            const RttStats* rtt_stats,
-            const QuicUnackedPacketMap* unacked_packets,
-            QuicPacketCount initial_tcp_congestion_window,
-            QuicPacketCount max_tcp_congestion_window,
-            QuicRandom* random,
-            QuicConnectionStats* stats);
-  BbrSender(const BbrSender&) = delete;
-  BbrSender& operator=(const BbrSender&) = delete;
-  ~BbrSender() override;
-
-  // Start implementation of SendAlgorithmInterface.
-  bool InSlowStart() const override;
-  bool InRecovery() const override;
-  bool ShouldSendProbingPacket() const override;
-
-  void SetFromConfig(const QuicConfig& config,
-                     Perspective perspective) override;
-  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
-
-  void AdjustNetworkParameters(const NetworkParams& params) override;
-  void SetInitialCongestionWindowInPackets(
-      QuicPacketCount congestion_window) override;
-  void OnCongestionEvent(bool rtt_updated,
-                         QuicByteCount prior_in_flight,
-                         QuicTime event_time,
-                         const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets) override;
-  void OnPacketSent(QuicTime sent_time,
-                    QuicByteCount bytes_in_flight,
-                    QuicPacketNumber packet_number,
-                    QuicByteCount bytes,
-                    HasRetransmittableData is_retransmittable) override;
-  void OnPacketNeutered(QuicPacketNumber packet_number) override;
-  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
-  void OnConnectionMigration() override {}
-  bool CanSend(QuicByteCount bytes_in_flight) override;
-  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
-  QuicBandwidth BandwidthEstimate() const override;
-  bool HasGoodBandwidthEstimateForResumption() const override {
-    return has_non_app_limited_sample();
-  }
-  QuicByteCount GetCongestionWindow() const override;
-  QuicByteCount GetSlowStartThreshold() const override;
-  CongestionControlType GetCongestionControlType() const override;
-  std::string GetDebugState() const override;
-  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
-  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
-  // End implementation of SendAlgorithmInterface.
-
-  // Gets the number of RTTs BBR remains in STARTUP phase.
-  QuicRoundTripCount num_startup_rtts() const { return num_startup_rtts_; }
-  bool has_non_app_limited_sample() const {
-    return has_non_app_limited_sample_;
-  }
-
-  // Sets the pacing gain used in STARTUP.  Must be greater than 1.
-  void set_high_gain(float high_gain) {
-    QUICHE_DCHECK_LT(1.0f, high_gain);
-    high_gain_ = high_gain;
-    if (mode_ == STARTUP) {
-      pacing_gain_ = high_gain;
-    }
-  }
-
-  // Sets the CWND gain used in STARTUP.  Must be greater than 1.
-  void set_high_cwnd_gain(float high_cwnd_gain) {
-    QUICHE_DCHECK_LT(1.0f, high_cwnd_gain);
-    high_cwnd_gain_ = high_cwnd_gain;
-    if (mode_ == STARTUP) {
-      congestion_window_gain_ = high_cwnd_gain;
-    }
-  }
-
-  // Sets the gain used in DRAIN.  Must be less than 1.
-  void set_drain_gain(float drain_gain) {
-    QUICHE_DCHECK_GT(1.0f, drain_gain);
-    drain_gain_ = drain_gain;
-  }
-
-  // Returns the current estimate of the RTT of the connection.  Outside of the
-  // edge cases, this is minimum RTT.
-  QuicTime::Delta GetMinRtt() const;
-
-  DebugState ExportDebugState() const;
-
- private:
-  // For switching send algorithm mid connection.
-  friend class Bbr2Sender;
-
-  using MaxBandwidthFilter = WindowedFilter<QuicBandwidth,
-                                            MaxFilter<QuicBandwidth>,
-                                            QuicRoundTripCount,
-                                            QuicRoundTripCount>;
-
-  using MaxAckHeightFilter = WindowedFilter<QuicByteCount,
-                                            MaxFilter<QuicByteCount>,
-                                            QuicRoundTripCount,
-                                            QuicRoundTripCount>;
-
-  // Computes the target congestion window using the specified gain.
-  QuicByteCount GetTargetCongestionWindow(float gain) const;
-  // The target congestion window during PROBE_RTT.
-  QuicByteCount ProbeRttCongestionWindow() const;
-  bool MaybeUpdateMinRtt(QuicTime now, QuicTime::Delta sample_min_rtt);
-
-  // Enters the STARTUP mode.
-  void EnterStartupMode(QuicTime now);
-  // Enters the PROBE_BW mode.
-  void EnterProbeBandwidthMode(QuicTime now);
-
-  // Updates the round-trip counter if a round-trip has passed.  Returns true if
-  // the counter has been advanced.
-  bool UpdateRoundTripCounter(QuicPacketNumber last_acked_packet);
-
-  // Updates the current gain used in PROBE_BW mode.
-  void UpdateGainCyclePhase(QuicTime now,
-                            QuicByteCount prior_in_flight,
-                            bool has_losses);
-  // Tracks for how many round-trips the bandwidth has not increased
-  // significantly.
-  void CheckIfFullBandwidthReached(const SendTimeState& last_packet_send_state);
-  // Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if
-  // appropriate.
-  void MaybeExitStartupOrDrain(QuicTime now);
-  // Decides whether to enter or exit PROBE_RTT.
-  void MaybeEnterOrExitProbeRtt(QuicTime now,
-                                bool is_round_start,
-                                bool min_rtt_expired);
-  // Determines whether BBR needs to enter, exit or advance state of the
-  // recovery.
-  void UpdateRecoveryState(QuicPacketNumber last_acked_packet,
-                           bool has_losses,
-                           bool is_round_start);
-
-  // Updates the ack aggregation max filter in bytes.
-  // Returns the most recent addition to the filter, or |newly_acked_bytes| if
-  // nothing was fed in to the filter.
-  QuicByteCount UpdateAckAggregationBytes(QuicTime ack_time,
-                                          QuicByteCount newly_acked_bytes);
-
-  // Determines the appropriate pacing rate for the connection.
-  void CalculatePacingRate(QuicByteCount bytes_lost);
-  // Determines the appropriate congestion window for the connection.
-  void CalculateCongestionWindow(QuicByteCount bytes_acked,
-                                 QuicByteCount excess_acked);
-  // Determines the appropriate window that constrains the in-flight during
-  // recovery.
-  void CalculateRecoveryWindow(QuicByteCount bytes_acked,
-                               QuicByteCount bytes_lost);
-
-  // Called right before exiting STARTUP.
-  void OnExitStartup(QuicTime now);
-
-  // Return whether we should exit STARTUP due to excessive loss.
-  bool ShouldExitStartupDueToLoss(
-      const SendTimeState& last_packet_send_state) const;
-
-  const RttStats* rtt_stats_;
-  const QuicUnackedPacketMap* unacked_packets_;
-  QuicRandom* random_;
-  QuicConnectionStats* stats_;
-
-  Mode mode_;
-
-  // Bandwidth sampler provides BBR with the bandwidth measurements at
-  // individual points.
-  BandwidthSampler sampler_;
-
-  // The number of the round trips that have occurred during the connection.
-  QuicRoundTripCount round_trip_count_;
-
-  // The packet number of the most recently sent packet.
-  QuicPacketNumber last_sent_packet_;
-  // Acknowledgement of any packet after |current_round_trip_end_| will cause
-  // the round trip counter to advance.
-  QuicPacketNumber current_round_trip_end_;
-
-  // Number of congestion events with some losses, in the current round.
-  int64_t num_loss_events_in_round_;
-
-  // Number of total bytes lost in the current round.
-  QuicByteCount bytes_lost_in_round_;
-
-  // The filter that tracks the maximum bandwidth over the multiple recent
-  // round-trips.
-  MaxBandwidthFilter max_bandwidth_;
-
-  // Minimum RTT estimate.  Automatically expires within 10 seconds (and
-  // triggers PROBE_RTT mode) if no new value is sampled during that period.
-  QuicTime::Delta min_rtt_;
-  // The time at which the current value of |min_rtt_| was assigned.
-  QuicTime min_rtt_timestamp_;
-
-  // The maximum allowed number of bytes in flight.
-  QuicByteCount congestion_window_;
-
-  // The initial value of the |congestion_window_|.
-  QuicByteCount initial_congestion_window_;
-
-  // The largest value the |congestion_window_| can achieve.
-  QuicByteCount max_congestion_window_;
-
-  // The smallest value the |congestion_window_| can achieve.
-  QuicByteCount min_congestion_window_;
-
-  // The pacing gain applied during the STARTUP phase.
-  float high_gain_;
-
-  // The CWND gain applied during the STARTUP phase.
-  float high_cwnd_gain_;
-
-  // The pacing gain applied during the DRAIN phase.
-  float drain_gain_;
-
-  // The current pacing rate of the connection.
-  QuicBandwidth pacing_rate_;
-
-  // The gain currently applied to the pacing rate.
-  float pacing_gain_;
-  // The gain currently applied to the congestion window.
-  float congestion_window_gain_;
-
-  // The gain used for the congestion window during PROBE_BW.  Latched from
-  // quic_bbr_cwnd_gain flag.
-  const float congestion_window_gain_constant_;
-  // The number of RTTs to stay in STARTUP mode.  Defaults to 3.
-  QuicRoundTripCount num_startup_rtts_;
-
-  // Number of round-trips in PROBE_BW mode, used for determining the current
-  // pacing gain cycle.
-  int cycle_current_offset_;
-  // The time at which the last pacing gain cycle was started.
-  QuicTime last_cycle_start_;
-
-  // Indicates whether the connection has reached the full bandwidth mode.
-  bool is_at_full_bandwidth_;
-  // Number of rounds during which there was no significant bandwidth increase.
-  QuicRoundTripCount rounds_without_bandwidth_gain_;
-  // The bandwidth compared to which the increase is measured.
-  QuicBandwidth bandwidth_at_last_round_;
-
-  // Set to true upon exiting quiescence.
-  bool exiting_quiescence_;
-
-  // Time at which PROBE_RTT has to be exited.  Setting it to zero indicates
-  // that the time is yet unknown as the number of packets in flight has not
-  // reached the required value.
-  QuicTime exit_probe_rtt_at_;
-  // Indicates whether a round-trip has passed since PROBE_RTT became active.
-  bool probe_rtt_round_passed_;
-
-  // Indicates whether the most recent bandwidth sample was marked as
-  // app-limited.
-  bool last_sample_is_app_limited_;
-  // Indicates whether any non app-limited samples have been recorded.
-  bool has_non_app_limited_sample_;
-
-  // Current state of recovery.
-  RecoveryState recovery_state_;
-  // Receiving acknowledgement of a packet after |end_recovery_at_| will cause
-  // BBR to exit the recovery mode.  A value above zero indicates at least one
-  // loss has been detected, so it must not be set back to zero.
-  QuicPacketNumber end_recovery_at_;
-  // A window used to limit the number of bytes in flight during loss recovery.
-  QuicByteCount recovery_window_;
-  // If true, consider all samples in recovery app-limited.
-  bool is_app_limited_recovery_;
-
-  // When true, pace at 1.5x and disable packet conservation in STARTUP.
-  bool slower_startup_;
-  // When true, disables packet conservation in STARTUP.
-  bool rate_based_startup_;
-
-  // When true, add the most recent ack aggregation measurement during STARTUP.
-  bool enable_ack_aggregation_during_startup_;
-  // When true, expire the windowed ack aggregation values in STARTUP when
-  // bandwidth increases more than 25%.
-  bool expire_ack_aggregation_in_startup_;
-
-  // If true, will not exit low gain mode until bytes_in_flight drops below BDP
-  // or it's time for high gain mode.
-  bool drain_to_target_;
-
-  // If true, slow down pacing rate in STARTUP when overshooting is detected.
-  bool detect_overshooting_;
-  // Bytes lost while detect_overshooting_ is true.
-  QuicByteCount bytes_lost_while_detecting_overshooting_;
-  // Slow down pacing rate if
-  // bytes_lost_while_detecting_overshooting_ *
-  // bytes_lost_multiplier_while_detecting_overshooting_ > IW.
-  uint8_t bytes_lost_multiplier_while_detecting_overshooting_;
-  // When overshooting is detected, do not drop pacing_rate_ below this value /
-  // min_rtt.
-  QuicByteCount cwnd_to_calculate_min_pacing_rate_;
-
-  // Max congestion window when adjusting network parameters.
-  QuicByteCount max_congestion_window_with_network_parameters_adjusted_;
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const BbrSender::Mode& mode);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os,
-    const BbrSender::DebugState& state);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
diff --git a/quic/core/congestion_control/bbr_sender_test.cc b/quic/core/congestion_control/bbr_sender_test.cc
deleted file mode 100644
index 3746d9e..0000000
--- a/quic/core/congestion_control/bbr_sender_test.cc
+++ /dev/null
@@ -1,1334 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/bbr_sender.h"
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/send_algorithm_test_result.pb.h"
-#include "quic/test_tools/send_algorithm_test_utils.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-using testing::AllOf;
-using testing::Ge;
-using testing::Le;
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, quic_bbr_test_regression_mode, "",
-    "One of a) 'record' to record test result (one file per test), or "
-    "b) 'regress' to regress against recorded results, or "
-    "c) <anything else> for non-regression mode.");
-
-namespace quic {
-namespace test {
-
-// Use the initial CWND of 10, as 32 is too much for the test network.
-const uint32_t kInitialCongestionWindowPackets = 10;
-const uint32_t kDefaultWindowTCP =
-    kInitialCongestionWindowPackets * kDefaultTCPMSS;
-
-// Test network parameters.  Here, the topology of the network is:
-//
-//          BBR sender
-//               |
-//               |  <-- local link (10 Mbps, 2 ms delay)
-//               |
-//        Network switch
-//               *  <-- the bottleneck queue in the direction
-//               |          of the receiver
-//               |
-//               |  <-- test link (4 Mbps, 30 ms delay)
-//               |
-//               |
-//           Receiver
-//
-// The reason the bandwidths chosen are relatively low is the fact that the
-// connection simulator uses QuicTime for its internal clock, and as such has
-// the granularity of 1us, meaning that at bandwidth higher than 20 Mbps the
-// packets can start to land on the same timestamp.
-const QuicBandwidth kTestLinkBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(4000);
-const QuicBandwidth kLocalLinkBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(10000);
-const QuicTime::Delta kTestPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(30);
-const QuicTime::Delta kLocalPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(2);
-const QuicTime::Delta kTestTransferTime =
-    kTestLinkBandwidth.TransferTime(kMaxOutgoingPacketSize) +
-    kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
-const QuicTime::Delta kTestRtt =
-    (kTestPropagationDelay + kLocalPropagationDelay + kTestTransferTime) * 2;
-const QuicByteCount kTestBdp = kTestRtt * kTestLinkBandwidth;
-
-class BbrSenderTest : public QuicTest {
- protected:
-  BbrSenderTest()
-      : simulator_(&random_),
-        bbr_sender_(&simulator_,
-                    "BBR sender",
-                    "Receiver",
-                    Perspective::IS_CLIENT,
-                    /*connection_id=*/TestConnectionId(42)),
-        competing_sender_(&simulator_,
-                          "Competing sender",
-                          "Competing receiver",
-                          Perspective::IS_CLIENT,
-                          /*connection_id=*/TestConnectionId(43)),
-        receiver_(&simulator_,
-                  "Receiver",
-                  "BBR sender",
-                  Perspective::IS_SERVER,
-                  /*connection_id=*/TestConnectionId(42)),
-        competing_receiver_(&simulator_,
-                            "Competing receiver",
-                            "Competing sender",
-                            Perspective::IS_SERVER,
-                            /*connection_id=*/TestConnectionId(43)),
-        receiver_multiplexer_("Receiver multiplexer",
-                              {&receiver_, &competing_receiver_}) {
-    rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats();
-    const int kTestMaxPacketSize = 1350;
-    bbr_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
-    sender_ = SetupBbrSender(&bbr_sender_);
-    SetConnectionOption(kBBRA);
-    clock_ = simulator_.GetClock();
-  }
-
-  void SetUp() override {
-    if (GetQuicFlag(FLAGS_quic_bbr_test_regression_mode) == "regress") {
-      SendAlgorithmTestResult expected;
-      ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
-      random_seed_ = expected.random_seed();
-    } else {
-      random_seed_ = QuicRandom::GetInstance()->RandUint64();
-    }
-    random_.set_seed(random_seed_);
-    QUIC_LOG(INFO) << "BbrSenderTest simulator set up.  Seed: " << random_seed_;
-  }
-
-  ~BbrSenderTest() {
-    const std::string regression_mode =
-        GetQuicFlag(FLAGS_quic_bbr_test_regression_mode);
-    const QuicTime::Delta simulated_duration = clock_->Now() - QuicTime::Zero();
-    if (regression_mode == "record") {
-      RecordSendAlgorithmTestResult(random_seed_,
-                                    simulated_duration.ToMicroseconds());
-    } else if (regression_mode == "regress") {
-      CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
-    }
-  }
-
-  uint64_t random_seed_;
-  SimpleRandom random_;
-  simulator::Simulator simulator_;
-  simulator::QuicEndpoint bbr_sender_;
-  simulator::QuicEndpoint competing_sender_;
-  simulator::QuicEndpoint receiver_;
-  simulator::QuicEndpoint competing_receiver_;
-  simulator::QuicEndpointMultiplexer receiver_multiplexer_;
-  std::unique_ptr<simulator::Switch> switch_;
-  std::unique_ptr<simulator::SymmetricLink> bbr_sender_link_;
-  std::unique_ptr<simulator::SymmetricLink> competing_sender_link_;
-  std::unique_ptr<simulator::SymmetricLink> receiver_link_;
-
-  // Owned by different components of the connection.
-  const QuicClock* clock_;
-  const RttStats* rtt_stats_;
-  BbrSender* sender_;
-
-  // Enables BBR on |endpoint| and returns the associated BBR congestion
-  // controller.
-  BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
-    const RttStats* rtt_stats =
-        endpoint->connection()->sent_packet_manager().GetRttStats();
-    // Ownership of the sender will be overtaken by the endpoint.
-    BbrSender* sender = new BbrSender(
-        endpoint->connection()->clock()->Now(), rtt_stats,
-        QuicSentPacketManagerPeer::GetUnackedPacketMap(
-            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
-        kInitialCongestionWindowPackets,
-        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
-        QuicConnectionPeer::GetStats(endpoint->connection()));
-    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
-    endpoint->RecordTrace();
-    return sender;
-  }
-
-  // Creates a default setup, which is a network with a bottleneck between the
-  // receiver and the switch.  The switch has the buffers four times larger than
-  // the bottleneck BDP, which should guarantee a lack of losses.
-  void CreateDefaultSetup() {
-    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
-                                                  2 * kTestBdp);
-    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
-        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
-        kLocalPropagationDelay);
-    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
-        &receiver_, switch_->port(2), kTestLinkBandwidth,
-        kTestPropagationDelay);
-  }
-
-  // Same as the default setup, except the buffer now is half of the BDP.
-  void CreateSmallBufferSetup() {
-    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
-                                                  0.5 * kTestBdp);
-    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
-        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
-        kLocalPropagationDelay);
-    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
-        &receiver_, switch_->port(2), kTestLinkBandwidth,
-        kTestPropagationDelay);
-  }
-
-  // Creates the variation of the default setup in which there is another sender
-  // that competes for the same bottleneck link.
-  void CreateCompetitionSetup() {
-    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
-                                                  2 * kTestBdp);
-
-    // Add a small offset to the competing link in order to avoid
-    // synchronization effects.
-    const QuicTime::Delta small_offset = QuicTime::Delta::FromMicroseconds(3);
-    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
-        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
-        kLocalPropagationDelay);
-    competing_sender_link_ = std::make_unique<simulator::SymmetricLink>(
-        &competing_sender_, switch_->port(3), kLocalLinkBandwidth,
-        kLocalPropagationDelay + small_offset);
-    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
-        &receiver_multiplexer_, switch_->port(2), kTestLinkBandwidth,
-        kTestPropagationDelay);
-  }
-
-  // Creates a BBR vs BBR competition setup.
-  void CreateBbrVsBbrSetup() {
-    SetupBbrSender(&competing_sender_);
-    CreateCompetitionSetup();
-  }
-
-  void EnableAggregation(QuicByteCount aggregation_bytes,
-                         QuicTime::Delta aggregation_timeout) {
-    // Enable aggregation on the path from the receiver to the sender.
-    switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
-                                              aggregation_timeout);
-  }
-
-  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
-    bbr_sender_.AddBytesToTransfer(transfer_size);
-    // TODO(vasilvv): consider rewriting this to run until the receiver actually
-    // receives the intended amount of bytes.
-    bool simulator_result = simulator_.RunUntilOrTimeout(
-        [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, deadline);
-    EXPECT_TRUE(simulator_result)
-        << "Simple transfer failed.  Bytes remaining: "
-        << bbr_sender_.bytes_to_transfer();
-    QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
-  }
-
-  // Drive the simulator by sending enough data to enter PROBE_BW.
-  void DriveOutOfStartup() {
-    ASSERT_FALSE(sender_->ExportDebugState().is_at_full_bandwidth);
-    DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
-    EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-    EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                     sender_->ExportDebugState().max_bandwidth, 0.02f);
-  }
-
-  // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
-  // |wait_time| between each burst.
-  void SendBursts(size_t number_of_bursts,
-                  QuicByteCount bytes,
-                  QuicTime::Delta wait_time) {
-    ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
-    for (size_t i = 0; i < number_of_bursts; i++) {
-      bbr_sender_.AddBytesToTransfer(bytes);
-
-      // Transfer data and wait for three seconds between each transfer.
-      simulator_.RunFor(wait_time);
-
-      // Ensure the connection did not time out.
-      ASSERT_TRUE(bbr_sender_.connection()->connected());
-      ASSERT_TRUE(receiver_.connection()->connected());
-    }
-
-    simulator_.RunFor(wait_time + kTestRtt);
-    ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
-  }
-
-  void SetConnectionOption(QuicTag option) {
-    QuicConfig config;
-    QuicTagVector options;
-    options.push_back(option);
-    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-    sender_->SetFromConfig(config, Perspective::IS_SERVER);
-  }
-};
-
-TEST_F(BbrSenderTest, SetInitialCongestionWindow) {
-  EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-  sender_->SetInitialCongestionWindowInPackets(3);
-  EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-// Test a simple long data transfer in the default setup.
-TEST_F(BbrSenderTest, SimpleTransfer) {
-  CreateDefaultSetup();
-
-  // At startup make sure we are at the default.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  // And that window is un-affected.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
-  // Verify that Sender is in slow start.
-  EXPECT_TRUE(sender_->InSlowStart());
-
-  // Verify that pacing rate is based on the initial RTT.
-  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
-  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
-                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
-  ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
-
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  // The margin here is quite high, since there exists a possibility that the
-  // connection just exited high gain cycle.
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
-}
-
-TEST_F(BbrSenderTest, SimpleTransferBBRB) {
-  SetConnectionOption(kBBRB);
-  CreateDefaultSetup();
-
-  // At startup make sure we are at the default.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  // And that window is un-affected.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
-  // Verify that Sender is in slow start.
-  EXPECT_TRUE(sender_->InSlowStart());
-
-  // Verify that pacing rate is based on the initial RTT.
-  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
-  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
-                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
-  ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
-
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  // The margin here is quite high, since there exists a possibility that the
-  // connection just exited high gain cycle.
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
-}
-
-// Test a simple transfer in a situation when the buffer is less than BDP.
-TEST_F(BbrSenderTest, SimpleTransferSmallBuffer) {
-  CreateSmallBufferSetup();
-
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-  EXPECT_GE(bbr_sender_.connection()->GetStats().packets_lost, 0u);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  // The margin here is quite high, since there exists a possibility that the
-  // connection just exited high gain cycle.
-  EXPECT_APPROX_EQ(kTestRtt, sender_->GetMinRtt(), 0.2f);
-}
-
-TEST_F(BbrSenderTest, RemoveBytesLostInRecovery) {
-  CreateDefaultSetup();
-
-  DriveOutOfStartup();
-
-  // Drop a packet to enter recovery.
-  receiver_.DropNextIncomingPacket();
-  ASSERT_TRUE(
-      simulator_.RunUntilOrTimeout([this]() { return sender_->InRecovery(); },
-                                   QuicTime::Delta::FromSeconds(30)));
-
-  QuicUnackedPacketMap* unacked_packets =
-      QuicSentPacketManagerPeer::GetUnackedPacketMap(
-          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
-  QuicPacketNumber largest_sent =
-      bbr_sender_.connection()->sent_packet_manager().GetLargestSentPacket();
-  // least_inflight is the smallest inflight packet.
-  QuicPacketNumber least_inflight =
-      bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked();
-  while (!unacked_packets->GetTransmissionInfo(least_inflight).in_flight) {
-    ASSERT_LE(least_inflight, largest_sent);
-    least_inflight++;
-  }
-  QuicPacketLength least_inflight_packet_size =
-      unacked_packets->GetTransmissionInfo(least_inflight).bytes_sent;
-  QuicByteCount prior_recovery_window =
-      sender_->ExportDebugState().recovery_window;
-  QuicByteCount prior_inflight = unacked_packets->bytes_in_flight();
-  QUIC_LOG(INFO) << "Recovery window:" << prior_recovery_window
-                 << ", least_inflight_packet_size:"
-                 << least_inflight_packet_size
-                 << ", bytes_in_flight:" << prior_inflight;
-  ASSERT_GT(prior_recovery_window, least_inflight_packet_size);
-
-  // Lose the least inflight packet and expect the recovery window to drop.
-  unacked_packets->RemoveFromInFlight(least_inflight);
-  LostPacketVector lost_packets;
-  lost_packets.emplace_back(least_inflight, least_inflight_packet_size);
-  sender_->OnCongestionEvent(false, prior_inflight, clock_->Now(), {},
-                             lost_packets);
-  EXPECT_EQ(sender_->ExportDebugState().recovery_window,
-            prior_inflight - least_inflight_packet_size);
-  EXPECT_LT(sender_->ExportDebugState().recovery_window, prior_recovery_window);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
-  SetConnectionOption(kBSAO);
-  CreateDefaultSetup();
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * kTestRtt);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
-              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
-
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.5f);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
-  SetConnectionOption(kBSAO);
-  // Decrease the CWND gain so extra CWND is required with stretch acks.
-  SetQuicFlag(FLAGS_quic_bbr_cwnd_gain, 1.0);
-  sender_ = new BbrSender(
-      bbr_sender_.connection()->clock()->Now(), rtt_stats_,
-      QuicSentPacketManagerPeer::GetUnackedPacketMap(
-          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())),
-      kInitialCongestionWindowPackets,
-      GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
-      QuicConnectionPeer::GetStats(bbr_sender_.connection()));
-  QuicConnectionPeer::SetSendAlgorithm(bbr_sender_.connection(), sender_);
-  CreateDefaultSetup();
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-
-  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
-  // bandwidth higher than the link rate.
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(kTestRtt * 2, rtt_stats_->smoothed_rtt());
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.1f);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-// TODO(b/172302465) Re-enable this test.
-TEST_F(BbrSenderTest,
-       QUIC_TEST_DISABLED_IN_CHROME(
-           SimpleTransfer2RTTAggregationBytes20RTTWindow)) {
-  SetConnectionOption(kBSAO);
-  CreateDefaultSetup();
-  SetConnectionOption(kBBR4);
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * kTestRtt);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
-              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
-
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-
-  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
-  // bandwidth higher than the link rate.
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
-}
-
-// Test a simple long data transfer with 2 rtts of aggregation.
-TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
-  SetConnectionOption(kBSAO);
-  CreateDefaultSetup();
-  SetConnectionOption(kBBR5);
-  // 2 RTTs of aggregation, with a max of 10kb.
-  EnableAggregation(10 * 1024, 2 * kTestRtt);
-
-  // Transfer 12MB.
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
-  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
-              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
-
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-
-  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
-  // bandwidth higher than the link rate.
-  // The margin here is high, because the aggregation greatly increases
-  // smoothed rtt.
-  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
-}
-
-// Test the number of losses incurred by the startup phase in a situation when
-// the buffer is less than BDP.
-TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartup) {
-  CreateSmallBufferSetup();
-
-  DriveOutOfStartup();
-  float loss_rate =
-      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
-      bbr_sender_.connection()->GetStats().packets_sent;
-  EXPECT_LE(loss_rate, 0.31);
-}
-
-// Test the number of losses incurred by the startup phase in a situation when
-// the buffer is less than BDP, with a STARTUP CWND gain of 2.
-TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartupDerivedCWNDGain) {
-  CreateSmallBufferSetup();
-
-  SetConnectionOption(kBBQ2);
-  DriveOutOfStartup();
-  float loss_rate =
-      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
-      bbr_sender_.connection()->GetStats().packets_sent;
-  EXPECT_LE(loss_rate, 0.1);
-}
-
-// Ensures the code transitions loss recovery states correctly (NOT_IN_RECOVERY
-// -> CONSERVATION -> GROWTH -> NOT_IN_RECOVERY).
-TEST_F(BbrSenderTest, RecoveryStates) {
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-  bool simulator_result;
-  CreateSmallBufferSetup();
-
-  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-  ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
-            sender_->ExportDebugState().recovery_state);
-
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().recovery_state !=
-               BbrSender::NOT_IN_RECOVERY;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::CONSERVATION,
-            sender_->ExportDebugState().recovery_state);
-
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().recovery_state !=
-               BbrSender::CONSERVATION;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::GROWTH, sender_->ExportDebugState().recovery_state);
-
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().recovery_state != BbrSender::GROWTH;
-      },
-      timeout);
-
-  ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
-            sender_->ExportDebugState().recovery_state);
-  ASSERT_TRUE(simulator_result);
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data after sending continuously for a while.
-TEST_F(BbrSenderTest, ApplicationLimitedBursts) {
-  CreateDefaultSetup();
-  EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
-
-  DriveOutOfStartup();
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
-
-  SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
-  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
-  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-}
-
-// Verify the behavior of the algorithm in the case when the connection sends
-// small bursts of data and then starts sending continuously.
-TEST_F(BbrSenderTest, ApplicationLimitedBurstsWithoutPrior) {
-  CreateDefaultSetup();
-
-  SendBursts(40, 512, QuicTime::Delta::FromSeconds(3));
-  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  DriveOutOfStartup();
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Verify that the DRAIN phase works correctly.
-TEST_F(BbrSenderTest, Drain) {
-  CreateDefaultSetup();
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-  // Get the queue at the bottleneck, which is the outgoing queue at the port to
-  // which the receiver is connected.
-  const simulator::Queue* queue = switch_->port_queue(2);
-  bool simulator_result;
-
-  // We have no intention of ever finishing this transfer.
-  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
-  // Run the startup, and verify that it fills up the queue.
-  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
-                   sender_->PacingRate(0), 0.01f);
-
-  // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer
-  // with approximately 1 BDP.  Here, we use 0.8 to give some margin for
-  // error.
-  EXPECT_GE(queue->bytes_queued(), 0.8 * kTestBdp);
-
-  // Observe increased RTT due to bufferbloat.
-  const QuicTime::Delta queueing_delay =
-      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
-  EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
-
-  // Transition to the drain phase and verify that it makes the queue
-  // have at most a BDP worth of packets.
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_LE(queue->bytes_queued(), kTestBdp);
-
-  // Wait for a few round trips and ensure we're in appropriate phase of gain
-  // cycling before taking an RTT measurement.
-  const QuicRoundTripCount start_round_trip =
-      sender_->ExportDebugState().round_trip_count;
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this, start_round_trip]() {
-        QuicRoundTripCount rounds_passed =
-            sender_->ExportDebugState().round_trip_count - start_round_trip;
-        return rounds_passed >= 4 &&
-               sender_->ExportDebugState().gain_cycle_index == 7;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Observe the bufferbloat go away.
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
-}
-
-// TODO(wub): Re-enable this test once default drain_gain changed to 0.75.
-// Verify that the DRAIN phase works correctly.
-TEST_F(BbrSenderTest, DISABLED_ShallowDrain) {
-  CreateDefaultSetup();
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-  // Get the queue at the bottleneck, which is the outgoing queue at the port to
-  // which the receiver is connected.
-  const simulator::Queue* queue = switch_->port_queue(2);
-  bool simulator_result;
-
-  // We have no intention of ever finishing this transfer.
-  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
-  // Run the startup, and verify that it fills up the queue.
-  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(0.75 * sender_->BandwidthEstimate(), sender_->PacingRate(0));
-  // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer
-  // with approximately 1.88 BDPs.  Here, we use 1.5 to give some margin for
-  // error.
-  EXPECT_GE(queue->bytes_queued(), 1.5 * kTestBdp);
-
-  // Observe increased RTT due to bufferbloat.
-  const QuicTime::Delta queueing_delay =
-      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
-  EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
-
-  // Transition to the drain phase and verify that it makes the queue
-  // have at most a BDP worth of packets.
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_LE(queue->bytes_queued(), kTestBdp);
-
-  // Wait for a few round trips and ensure we're in appropriate phase of gain
-  // cycling before taking an RTT measurement.
-  const QuicRoundTripCount start_round_trip =
-      sender_->ExportDebugState().round_trip_count;
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this, start_round_trip]() {
-        QuicRoundTripCount rounds_passed =
-            sender_->ExportDebugState().round_trip_count - start_round_trip;
-        return rounds_passed >= 4 &&
-               sender_->ExportDebugState().gain_cycle_index == 7;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Observe the bufferbloat go away.
-  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
-}
-
-// Verify that the connection enters and exits PROBE_RTT correctly.
-TEST_F(BbrSenderTest, ProbeRtt) {
-  CreateDefaultSetup();
-  DriveOutOfStartup();
-
-  // We have no intention of ever finishing this transfer.
-  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
-  // Wait until the connection enters PROBE_RTT.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
-
-  // Exit PROBE_RTT.
-  const QuicTime probe_rtt_start = clock_->Now();
-  const QuicTime::Delta time_to_exit_probe_rtt =
-      kTestRtt + QuicTime::Delta::FromMilliseconds(200);
-  simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
-}
-
-// Ensure that a connection that is app-limited and is at sufficiently low
-// bandwidth will not exit high gain phase, and similarly ensure that the
-// connection will exit low gain early if the number of bytes in flight is low.
-// TODO(crbug.com/1145095): Re-enable this test.
-TEST_F(BbrSenderTest, QUIC_TEST_DISABLED_IN_CHROME(InFlightAwareGainCycling)) {
-  CreateDefaultSetup();
-  DriveOutOfStartup();
-
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  while (!(sender_->ExportDebugState().gain_cycle_index >= 4 &&
-           bbr_sender_.bytes_to_transfer() == 0)) {
-    bbr_sender_.AddBytesToTransfer(kTestLinkBandwidth.ToBytesPerSecond());
-    ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-        [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, timeout));
-  }
-
-  // Send at 10% of available rate.  Run for 3 seconds, checking in the middle
-  // and at the end.  The pacing gain should be high throughout.
-  QuicBandwidth target_bandwidth = 0.1f * kTestLinkBandwidth;
-  QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
-  for (int i = 0; i < 2; i++) {
-    SendBursts(5, target_bandwidth * burst_interval, burst_interval);
-    EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-    EXPECT_EQ(0, sender_->ExportDebugState().gain_cycle_index);
-    EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                     sender_->ExportDebugState().max_bandwidth, 0.02f);
-  }
-
-  // Now that in-flight is almost zero and the pacing gain is still above 1,
-  // send approximately 1.25 BDPs worth of data.  This should cause the
-  // PROBE_BW mode to enter low gain cycle, and exit it earlier than one min_rtt
-  // due to running out of data to send.
-  bbr_sender_.AddBytesToTransfer(1.3 * kTestBdp);
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().gain_cycle_index == 1; },
-      timeout));
-
-  simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_EQ(2, sender_->ExportDebugState().gain_cycle_index);
-}
-
-// Ensure that the pacing rate does not drop at startup.
-TEST_F(BbrSenderTest, NoBandwidthDropOnStartup) {
-  CreateDefaultSetup();
-
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result;
-
-  QuicBandwidth initial_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      kInitialCongestionWindowPackets * kDefaultTCPMSS,
-      rtt_stats_->initial_rtt());
-  EXPECT_GE(sender_->PacingRate(0), initial_rate);
-
-  // Send a packet.
-  bbr_sender_.AddBytesToTransfer(1000);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return receiver_.bytes_received() == 1000; }, timeout);
-  ASSERT_TRUE(simulator_result);
-  EXPECT_GE(sender_->PacingRate(0), initial_rate);
-
-  // Wait for a while.
-  simulator_.RunFor(QuicTime::Delta::FromSeconds(2));
-  EXPECT_GE(sender_->PacingRate(0), initial_rate);
-
-  // Send another packet.
-  bbr_sender_.AddBytesToTransfer(1000);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return receiver_.bytes_received() == 2000; }, timeout);
-  ASSERT_TRUE(simulator_result);
-  EXPECT_GE(sender_->PacingRate(0), initial_rate);
-}
-
-// Test exiting STARTUP earlier due to the 1RTT connection option.
-TEST_F(BbrSenderTest, SimpleTransfer1RTTStartup) {
-  CreateDefaultSetup();
-
-  SetConnectionOption(k1RTT);
-  EXPECT_EQ(1u, sender_->num_startup_rtts());
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
-          max_bw = sender_->ExportDebugState().max_bandwidth;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().is_at_full_bandwidth;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test exiting STARTUP earlier due to the 2RTT connection option.
-TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
-  CreateDefaultSetup();
-
-  SetConnectionOption(k2RTT);
-  EXPECT_EQ(2u, sender_->num_startup_rtts());
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
-          max_bw = sender_->ExportDebugState().max_bandwidth;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().is_at_full_bandwidth;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(2u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test exiting STARTUP earlier upon loss.
-TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLoss) {
-  CreateDefaultSetup();
-
-  EXPECT_EQ(3u, sender_->num_startup_rtts());
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
-          max_bw = sender_->ExportDebugState().max_bandwidth;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().is_at_full_bandwidth;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test exiting STARTUP earlier upon loss with a small buffer.
-TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLossSmallBuffer) {
-  CreateSmallBufferSetup();
-
-  EXPECT_EQ(3u, sender_->num_startup_rtts());
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  QuicRoundTripCount max_bw_round = 0;
-  QuicBandwidth max_bw(QuicBandwidth::Zero());
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this, &max_bw, &max_bw_round]() {
-        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
-          max_bw = sender_->ExportDebugState().max_bandwidth;
-          max_bw_round = sender_->ExportDebugState().round_trip_count;
-        }
-        return sender_->ExportDebugState().is_at_full_bandwidth;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
-  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  EXPECT_NE(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(BbrSenderTest, DerivedPacingGainStartup) {
-  CreateDefaultSetup();
-
-  SetConnectionOption(kBBQ1);
-  EXPECT_EQ(3u, sender_->num_startup_rtts());
-  // Verify that Sender is in slow start.
-  EXPECT_TRUE(sender_->InSlowStart());
-  // Verify that pacing rate is based on the initial RTT.
-  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      2.773 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
-  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
-                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-TEST_F(BbrSenderTest, DerivedCWNDGainStartup) {
-  CreateSmallBufferSetup();
-
-  EXPECT_EQ(3u, sender_->num_startup_rtts());
-  // Verify that Sender is in slow start.
-  EXPECT_TRUE(sender_->InSlowStart());
-  // Verify that pacing rate is based on the initial RTT.
-  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
-  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
-                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  if (!bbr_sender_.connection()->GetStats().bbr_exit_startup_due_to_loss) {
-    EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  }
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-  float loss_rate =
-      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
-      bbr_sender_.connection()->GetStats().packets_sent;
-  EXPECT_LT(loss_rate, 0.15f);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-  // Expect an SRTT less than 2.7 * Min RTT on exit from STARTUP.
-  EXPECT_GT(kTestRtt * 2.7, rtt_stats_->smoothed_rtt());
-}
-
-TEST_F(BbrSenderTest, AckAggregationInStartup) {
-  CreateDefaultSetup();
-
-  SetConnectionOption(kBBQ3);
-  EXPECT_EQ(3u, sender_->num_startup_rtts());
-  // Verify that Sender is in slow start.
-  EXPECT_TRUE(sender_->InSlowStart());
-  // Verify that pacing rate is based on the initial RTT.
-  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
-      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
-  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
-                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
-
-  // Run until the full bandwidth is reached and check how many rounds it was.
-  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
-  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
-  EXPECT_APPROX_EQ(kTestLinkBandwidth,
-                   sender_->ExportDebugState().max_bandwidth, 0.01f);
-  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-}
-
-// Test that two BBR flows started slightly apart from each other terminate.
-TEST_F(BbrSenderTest, SimpleCompetition) {
-  const QuicByteCount transfer_size = 10 * 1024 * 1024;
-  const QuicTime::Delta transfer_time =
-      kTestLinkBandwidth.TransferTime(transfer_size);
-  CreateBbrVsBbrSetup();
-
-  // Transfer 10% of data in first transfer.
-  bbr_sender_.AddBytesToTransfer(transfer_size);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return receiver_.bytes_received() >= 0.1 * transfer_size; },
-      transfer_time);
-  ASSERT_TRUE(simulator_result);
-
-  // Start the second transfer and wait until both finish.
-  competing_sender_.AddBytesToTransfer(transfer_size);
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return receiver_.bytes_received() == transfer_size &&
-               competing_receiver_.bytes_received() == transfer_size;
-      },
-      3 * transfer_time);
-  ASSERT_TRUE(simulator_result);
-}
-
-// Test that BBR can resume bandwidth from cached network parameters.
-TEST_F(BbrSenderTest, ResumeConnectionState) {
-  CreateDefaultSetup();
-
-  bbr_sender_.connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth, kTestRtt,
-                                            false));
-  EXPECT_EQ(kTestLinkBandwidth * kTestRtt,
-            sender_->ExportDebugState().congestion_window);
-
-  EXPECT_EQ(kTestLinkBandwidth, sender_->PacingRate(/*bytes_in_flight=*/0));
-
-  EXPECT_APPROX_EQ(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f);
-
-  DriveOutOfStartup();
-}
-
-// Test with a min CWND of 1 instead of 4 packets.
-TEST_F(BbrSenderTest, ProbeRTTMinCWND1) {
-  CreateDefaultSetup();
-  SetConnectionOption(kMIN1);
-  DriveOutOfStartup();
-
-  // We have no intention of ever finishing this transfer.
-  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
-
-  // Wait until the connection enters PROBE_RTT.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() {
-        return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
-  // The PROBE_RTT CWND should be 1 if the min CWND is 1.
-  EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
-
-  // Exit PROBE_RTT.
-  const QuicTime probe_rtt_start = clock_->Now();
-  const QuicTime::Delta time_to_exit_probe_rtt =
-      kTestRtt + QuicTime::Delta::FromMilliseconds(200);
-  simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
-  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
-  EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
-}
-
-TEST_F(BbrSenderTest, StartupStats) {
-  CreateDefaultSetup();
-
-  DriveOutOfStartup();
-  ASSERT_FALSE(sender_->InSlowStart());
-
-  const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
-  EXPECT_EQ(1u, stats.slowstart_count);
-  EXPECT_THAT(stats.slowstart_num_rtts, AllOf(Ge(5u), Le(15u)));
-  EXPECT_THAT(stats.slowstart_packets_sent, AllOf(Ge(100u), Le(1000u)));
-  EXPECT_THAT(stats.slowstart_bytes_sent, AllOf(Ge(100000u), Le(1000000u)));
-  EXPECT_LE(stats.slowstart_packets_lost, 10u);
-  EXPECT_LE(stats.slowstart_bytes_lost, 10000u);
-  EXPECT_FALSE(stats.slowstart_duration.IsRunning());
-  EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
-              AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
-                    Le(QuicTime::Delta::FromMilliseconds(1500))));
-  EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
-            QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())
-                ->GetSlowStartDuration());
-}
-
-// Regression test for b/143540157.
-TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange1RTT) {
-  CreateDefaultSetup();
-
-  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  const QuicByteCount previous_cwnd =
-      sender_->ExportDebugState().congestion_window;
-
-  // Bootstrap cwnd.
-  bbr_sender_.connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
-                                            QuicTime::Delta::Zero(), false));
-  EXPECT_LT(previous_cwnd, sender_->ExportDebugState().congestion_window);
-
-  // Verify pacing rate is re-calculated based on the new cwnd and min_rtt.
-  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
-                       sender_->ExportDebugState().congestion_window,
-                       sender_->ExportDebugState().min_rtt),
-                   sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
-}
-
-TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange0RTT) {
-  CreateDefaultSetup();
-  // Initial RTT is available.
-  const_cast<RttStats*>(rtt_stats_)->set_initial_rtt(kTestRtt);
-
-  // Bootstrap cwnd.
-  bbr_sender_.connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
-                                            QuicTime::Delta::Zero(), false));
-  EXPECT_LT(kInitialCongestionWindowPackets * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  // No Rtt sample is available.
-  EXPECT_TRUE(sender_->ExportDebugState().min_rtt.IsZero());
-
-  // Verify pacing rate is re-calculated based on the new cwnd and initial
-  // RTT.
-  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
-                       sender_->ExportDebugState().congestion_window,
-                       rtt_stats_->initial_rtt()),
-                   sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
-}
-
-TEST_F(BbrSenderTest, MitigateCwndBootstrappingOvershoot) {
-  CreateDefaultSetup();
-  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
-
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  bbr_sender_.connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(8 * kTestLinkBandwidth,
-                                            QuicTime::Delta::Zero(), false));
-  QuicBandwidth pacing_rate = sender_->PacingRate(0);
-  EXPECT_EQ(8 * kTestLinkBandwidth, pacing_rate);
-
-  // Wait until pacing_rate decreases.
-  simulator_result = simulator_.RunUntilOrTimeout(
-      [this, pacing_rate]() { return sender_->PacingRate(0) < pacing_rate; },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  EXPECT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
-  if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
-    EXPECT_APPROX_EQ(2.0f * sender_->BandwidthEstimate(),
-                     sender_->PacingRate(0), 0.01f);
-  } else {
-    EXPECT_APPROX_EQ(2.885f * sender_->BandwidthEstimate(),
-                     sender_->PacingRate(0), 0.01f);
-  }
-}
-
-TEST_F(BbrSenderTest, 200InitialCongestionWindowWithNetworkParameterAdjusted) {
-  CreateDefaultSetup();
-
-  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  bbr_sender_.connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
-                                            QuicTime::Delta::Zero(), false));
-  // Verify cwnd is capped at 200.
-  EXPECT_EQ(200 * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
-}
-
-TEST_F(BbrSenderTest, 100InitialCongestionWindowFromNetworkParameter) {
-  CreateDefaultSetup();
-
-  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  SendAlgorithmInterface::NetworkParams network_params(
-      1024 * kTestLinkBandwidth, QuicTime::Delta::Zero(), false);
-  network_params.max_initial_congestion_window = 100;
-  bbr_sender_.connection()->AdjustNetworkParameters(network_params);
-  // Verify cwnd is capped at 100.
-  EXPECT_EQ(100 * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
-}
-
-TEST_F(BbrSenderTest, 100InitialCongestionWindowWithNetworkParameterAdjusted) {
-  SetConnectionOption(kICW1);
-  CreateDefaultSetup();
-
-  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
-  // Wait until an ACK comes back.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Bootstrap cwnd by a overly large bandwidth sample.
-  bbr_sender_.connection()->AdjustNetworkParameters(
-      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
-                                            QuicTime::Delta::Zero(), false));
-  // Verify cwnd is capped at 100.
-  EXPECT_EQ(100 * kDefaultTCPMSS,
-            sender_->ExportDebugState().congestion_window);
-  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
-}
-
-// Ensures bandwidth estimate does not change after a loss only event.
-// Regression test for b/151239871.
-TEST_F(BbrSenderTest, LossOnlyCongestionEvent) {
-  CreateDefaultSetup();
-
-  DriveOutOfStartup();
-  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
-
-  // Send some bursts, each burst increments round count by 1, since it only
-  // generates small, app-limited samples, the max_bandwidth_ will not be
-  // updated. At the end of all bursts, all estimates in max_bandwidth_ will
-  // look very old such that any Update() will reset all estimates.
-  SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
-
-  QuicUnackedPacketMap* unacked_packets =
-      QuicSentPacketManagerPeer::GetUnackedPacketMap(
-          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
-  // Run until we have something in flight.
-  bbr_sender_.AddBytesToTransfer(50 * 1024 * 1024);
-  bool simulator_result = simulator_.RunUntilOrTimeout(
-      [&]() { return unacked_packets->bytes_in_flight() > 0; },
-      QuicTime::Delta::FromSeconds(5));
-  ASSERT_TRUE(simulator_result);
-
-  const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
-  EXPECT_APPROX_EQ(kTestLinkBandwidth, prior_bandwidth_estimate, 0.01f);
-
-  // Lose the least unacked packet.
-  LostPacketVector lost_packets;
-  lost_packets.emplace_back(
-      bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked(),
-      kDefaultMaxPacketSize);
-
-  QuicTime now = simulator_.GetClock()->Now() + kTestRtt * 0.25;
-  sender_->OnCongestionEvent(false, unacked_packets->bytes_in_flight(), now, {},
-                             lost_packets);
-
-  // Bandwidth estimate should not change for the loss only event.
-  EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
-}
-
-TEST_F(BbrSenderTest, EnableOvershootingDetection) {
-  SetConnectionOption(kDTOS);
-  CreateSmallBufferSetup();
-  // Set a overly large initial cwnd.
-  sender_->SetInitialCongestionWindowInPackets(200);
-  const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
-  EXPECT_FALSE(stats.overshooting_detected_with_network_parameters_adjusted);
-  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
-
-  // Verify overshooting is detected.
-  EXPECT_TRUE(stats.overshooting_detected_with_network_parameters_adjusted);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/cubic_bytes.cc b/quic/core/congestion_control/cubic_bytes.cc
deleted file mode 100644
index 854d6a7..0000000
--- a/quic/core/congestion_control/cubic_bytes.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/cubic_bytes.h"
-
-#include <algorithm>
-#include <cmath>
-#include <cstdint>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Constants based on TCP defaults.
-// The following constants are in 2^10 fractions of a second instead of ms to
-// allow a 10 shift right to divide.
-const int kCubeScale = 40;  // 1024*1024^3 (first 1024 is from 0.100^3)
-                            // where 0.100 is 100 ms which is the scaling
-                            // round trip time.
-const int kCubeCongestionWindowScale = 410;
-// The cube factor for packets in bytes.
-const uint64_t kCubeFactor =
-    (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale / kDefaultTCPMSS;
-
-const float kDefaultCubicBackoffFactor = 0.7f;  // Default Cubic backoff factor.
-// Additional backoff factor when loss occurs in the concave part of the Cubic
-// curve. This additional backoff factor is expected to give up bandwidth to
-// new concurrent flows and speed up convergence.
-const float kBetaLastMax = 0.85f;
-
-}  // namespace
-
-CubicBytes::CubicBytes(const QuicClock* clock)
-    : clock_(clock),
-      num_connections_(kDefaultNumConnections),
-      epoch_(QuicTime::Zero()) {
-  ResetCubicState();
-}
-
-void CubicBytes::SetNumConnections(int num_connections) {
-  num_connections_ = num_connections;
-}
-
-float CubicBytes::Alpha() const {
-  // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
-  // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
-  // We derive the equivalent alpha for an N-connection emulation as:
-  const float beta = Beta();
-  return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
-}
-
-float CubicBytes::Beta() const {
-  // kNConnectionBeta is the backoff factor after loss for our N-connection
-  // emulation, which emulates the effective backoff of an ensemble of N
-  // TCP-Reno connections on a single loss event. The effective multiplier is
-  // computed as:
-  return (num_connections_ - 1 + kDefaultCubicBackoffFactor) / num_connections_;
-}
-
-float CubicBytes::BetaLastMax() const {
-  // BetaLastMax is the additional backoff factor after loss for our
-  // N-connection emulation, which emulates the additional backoff of
-  // an ensemble of N TCP-Reno connections on a single loss event. The
-  // effective multiplier is computed as:
-  return (num_connections_ - 1 + kBetaLastMax) / num_connections_;
-}
-
-void CubicBytes::ResetCubicState() {
-  epoch_ = QuicTime::Zero();             // Reset time.
-  last_max_congestion_window_ = 0;
-  acked_bytes_count_ = 0;
-  estimated_tcp_congestion_window_ = 0;
-  origin_point_congestion_window_ = 0;
-  time_to_origin_point_ = 0;
-  last_target_congestion_window_ = 0;
-}
-
-void CubicBytes::OnApplicationLimited() {
-  // When sender is not using the available congestion window, the window does
-  // not grow. But to be RTT-independent, Cubic assumes that the sender has been
-  // using the entire window during the time since the beginning of the current
-  // "epoch" (the end of the last loss recovery period). Since
-  // application-limited periods break this assumption, we reset the epoch when
-  // in such a period. This reset effectively freezes congestion window growth
-  // through application-limited periods and allows Cubic growth to continue
-  // when the entire window is being used.
-  epoch_ = QuicTime::Zero();
-}
-
-QuicByteCount CubicBytes::CongestionWindowAfterPacketLoss(
-    QuicByteCount current_congestion_window) {
-  // Since bytes-mode Reno mode slightly under-estimates the cwnd, we
-  // may never reach precisely the last cwnd over the course of an
-  // RTT.  Do not interpret a slight under-estimation as competing traffic.
-  if (current_congestion_window + kDefaultTCPMSS <
-      last_max_congestion_window_) {
-    // We never reached the old max, so assume we are competing with
-    // another flow. Use our extra back off factor to allow the other
-    // flow to go up.
-    last_max_congestion_window_ =
-        static_cast<int>(BetaLastMax() * current_congestion_window);
-  } else {
-    last_max_congestion_window_ = current_congestion_window;
-  }
-  epoch_ = QuicTime::Zero();  // Reset time.
-  return static_cast<int>(current_congestion_window * Beta());
-}
-
-QuicByteCount CubicBytes::CongestionWindowAfterAck(
-    QuicByteCount acked_bytes,
-    QuicByteCount current_congestion_window,
-    QuicTime::Delta delay_min,
-    QuicTime event_time) {
-  acked_bytes_count_ += acked_bytes;
-
-  if (!epoch_.IsInitialized()) {
-    // First ACK after a loss event.
-    QUIC_DVLOG(1) << "Start of epoch";
-    epoch_ = event_time;               // Start of epoch.
-    acked_bytes_count_ = acked_bytes;  // Reset count.
-    // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
-    estimated_tcp_congestion_window_ = current_congestion_window;
-    if (last_max_congestion_window_ <= current_congestion_window) {
-      time_to_origin_point_ = 0;
-      origin_point_congestion_window_ = current_congestion_window;
-    } else {
-      time_to_origin_point_ = static_cast<uint32_t>(
-          cbrt(kCubeFactor *
-               (last_max_congestion_window_ - current_congestion_window)));
-      origin_point_congestion_window_ = last_max_congestion_window_;
-    }
-  }
-  // Change the time unit from microseconds to 2^10 fractions per second. Take
-  // the round trip time in account. This is done to allow us to use shift as a
-  // divide operator.
-  int64_t elapsed_time =
-      ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
-      kNumMicrosPerSecond;
-
-  // Right-shifts of negative, signed numbers have implementation-dependent
-  // behavior, so force the offset to be positive, as is done in the kernel.
-  uint64_t offset = std::abs(time_to_origin_point_ - elapsed_time);
-
-  QuicByteCount delta_congestion_window = (kCubeCongestionWindowScale * offset *
-                                           offset * offset * kDefaultTCPMSS) >>
-                                          kCubeScale;
-
-  const bool add_delta = elapsed_time > time_to_origin_point_;
-  QUICHE_DCHECK(add_delta ||
-                (origin_point_congestion_window_ > delta_congestion_window));
-  QuicByteCount target_congestion_window =
-      add_delta ? origin_point_congestion_window_ + delta_congestion_window
-                : origin_point_congestion_window_ - delta_congestion_window;
-  // Limit the CWND increase to half the acked bytes.
-  target_congestion_window =
-      std::min(target_congestion_window,
-               current_congestion_window + acked_bytes_count_ / 2);
-
-  QUICHE_DCHECK_LT(0u, estimated_tcp_congestion_window_);
-  // Increase the window by approximately Alpha * 1 MSS of bytes every
-  // time we ack an estimated tcp window of bytes.  For small
-  // congestion windows (less than 25), the formula below will
-  // increase slightly slower than linearly per estimated tcp window
-  // of bytes.
-  estimated_tcp_congestion_window_ += acked_bytes_count_ *
-                                      (Alpha() * kDefaultTCPMSS) /
-                                      estimated_tcp_congestion_window_;
-  acked_bytes_count_ = 0;
-
-  // We have a new cubic congestion window.
-  last_target_congestion_window_ = target_congestion_window;
-
-  // Compute target congestion_window based on cubic target and estimated TCP
-  // congestion_window, use highest (fastest).
-  if (target_congestion_window < estimated_tcp_congestion_window_) {
-    target_congestion_window = estimated_tcp_congestion_window_;
-  }
-
-  QUIC_DVLOG(1) << "Final target congestion_window: "
-                << target_congestion_window;
-  return target_congestion_window;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/cubic_bytes.h b/quic/core/congestion_control/cubic_bytes.h
deleted file mode 100644
index 75a3bcd..0000000
--- a/quic/core/congestion_control/cubic_bytes.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Cubic algorithm, helper class to TCP cubic.
-// For details see http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class CubicBytesTest;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE CubicBytes {
- public:
-  explicit CubicBytes(const QuicClock* clock);
-  CubicBytes(const CubicBytes&) = delete;
-  CubicBytes& operator=(const CubicBytes&) = delete;
-
-  void SetNumConnections(int num_connections);
-
-  // Call after a timeout to reset the cubic state.
-  void ResetCubicState();
-
-  // Compute a new congestion window to use after a loss event.
-  // Returns the new congestion window in packets. The new congestion window is
-  // a multiplicative decrease of our current window.
-  QuicByteCount CongestionWindowAfterPacketLoss(QuicPacketCount current);
-
-  // Compute a new congestion window to use after a received ACK.
-  // Returns the new congestion window in bytes. The new congestion window
-  // follows a cubic function that depends on the time passed since last packet
-  // loss.
-  QuicByteCount CongestionWindowAfterAck(QuicByteCount acked_bytes,
-                                         QuicByteCount current,
-                                         QuicTime::Delta delay_min,
-                                         QuicTime event_time);
-
-  // Call on ack arrival when sender is unable to use the available congestion
-  // window. Resets Cubic state during quiescence.
-  void OnApplicationLimited();
-
- private:
-  friend class test::CubicBytesTest;
-
-  static const QuicTime::Delta MaxCubicTimeInterval() {
-    return QuicTime::Delta::FromMilliseconds(30);
-  }
-
-  // Compute the TCP Cubic alpha, beta, and beta-last-max based on the
-  // current number of connections.
-  float Alpha() const;
-  float Beta() const;
-  float BetaLastMax() const;
-
-  QuicByteCount last_max_congestion_window() const {
-    return last_max_congestion_window_;
-  }
-
-  const QuicClock* clock_;
-
-  // Number of connections to simulate.
-  int num_connections_;
-
-  // Time when this cycle started, after last loss event.
-  QuicTime epoch_;
-
-  // Max congestion window used just before last loss event.
-  // Note: to improve fairness to other streams an additional back off is
-  // applied to this value if the new value is below our latest value.
-  QuicByteCount last_max_congestion_window_;
-
-  // Number of acked bytes since the cycle started (epoch).
-  QuicByteCount acked_bytes_count_;
-
-  // TCP Reno equivalent congestion window in packets.
-  QuicByteCount estimated_tcp_congestion_window_;
-
-  // Origin point of cubic function.
-  QuicByteCount origin_point_congestion_window_;
-
-  // Time to origin point of cubic function in 2^10 fractions of a second.
-  uint32_t time_to_origin_point_;
-
-  // Last congestion window in packets computed by cubic function.
-  QuicByteCount last_target_congestion_window_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
diff --git a/quic/core/congestion_control/cubic_bytes_test.cc b/quic/core/congestion_control/cubic_bytes_test.cc
deleted file mode 100644
index edbe18d..0000000
--- a/quic/core/congestion_control/cubic_bytes_test.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/cubic_bytes.h"
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const float kBeta = 0.7f;          // Default Cubic backoff factor.
-const float kBetaLastMax = 0.85f;  // Default Cubic backoff factor.
-const uint32_t kNumConnections = 2;
-const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
-const float kNConnectionBetaLastMax =
-    (kNumConnections - 1 + kBetaLastMax) / kNumConnections;
-const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
-                                (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
-
-}  // namespace
-
-class CubicBytesTest : public QuicTest {
- protected:
-  CubicBytesTest()
-      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
-        hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
-        cubic_(&clock_) {}
-
-  QuicByteCount RenoCwndInBytes(QuicByteCount current_cwnd) {
-    QuicByteCount reno_estimated_cwnd =
-        current_cwnd +
-        kDefaultTCPMSS * (kNConnectionAlpha * kDefaultTCPMSS) / current_cwnd;
-    return reno_estimated_cwnd;
-  }
-
-  QuicByteCount ConservativeCwndInBytes(QuicByteCount current_cwnd) {
-    QuicByteCount conservative_cwnd = current_cwnd + kDefaultTCPMSS / 2;
-    return conservative_cwnd;
-  }
-
-  QuicByteCount CubicConvexCwndInBytes(QuicByteCount initial_cwnd,
-                                       QuicTime::Delta rtt,
-                                       QuicTime::Delta elapsed_time) {
-    const int64_t offset =
-        ((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000;
-    const QuicByteCount delta_congestion_window =
-        ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40);
-    const QuicByteCount cubic_cwnd = initial_cwnd + delta_congestion_window;
-    return cubic_cwnd;
-  }
-
-  QuicByteCount LastMaxCongestionWindow() {
-    return cubic_.last_max_congestion_window();
-  }
-
-  QuicTime::Delta MaxCubicTimeInterval() {
-    return cubic_.MaxCubicTimeInterval();
-  }
-
-  const QuicTime::Delta one_ms_;
-  const QuicTime::Delta hundred_ms_;
-  MockClock clock_;
-  CubicBytes cubic_;
-};
-
-// TODO(jokulik): The original "AboveOrigin" test, below, is very
-// loose.  It's nearly impossible to make the test tighter without
-// deploying the fix for convex mode.  Once cubic convex is deployed,
-// replace "AboveOrigin" with this test.
-TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) {
-  // Convex growth.
-  const QuicTime::Delta rtt_min = hundred_ms_;
-  int64_t rtt_min_ms = rtt_min.ToMilliseconds();
-  float rtt_min_s = rtt_min_ms / 1000.0;
-  QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
-  const QuicByteCount initial_cwnd = current_cwnd;
-
-  clock_.AdvanceTime(one_ms_);
-  const QuicTime initial_time = clock_.ApproximateNow();
-  const QuicByteCount expected_first_cwnd = RenoCwndInBytes(current_cwnd);
-  current_cwnd = cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
-                                                 rtt_min, initial_time);
-  ASSERT_EQ(expected_first_cwnd, current_cwnd);
-
-  // Normal TCP phase.
-  // The maximum number of expected Reno RTTs is calculated by
-  // finding the point where the cubic curve and the reno curve meet.
-  const int max_reno_rtts =
-      std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
-      2;
-  for (int i = 0; i < max_reno_rtts; ++i) {
-    // Alternatively, we expect it to increase by one, every time we
-    // receive current_cwnd/Alpha acks back.  (This is another way of
-    // saying we expect cwnd to increase by approximately Alpha once
-    // we receive current_cwnd number ofacks back).
-    const uint64_t num_acks_this_epoch =
-        current_cwnd / kDefaultTCPMSS / kNConnectionAlpha;
-    const QuicByteCount initial_cwnd_this_epoch = current_cwnd;
-    for (QuicPacketCount n = 0; n < num_acks_this_epoch; ++n) {
-      // Call once per ACK.
-      const QuicByteCount expected_next_cwnd = RenoCwndInBytes(current_cwnd);
-      current_cwnd = cubic_.CongestionWindowAfterAck(
-          kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-      ASSERT_EQ(expected_next_cwnd, current_cwnd);
-    }
-    // Our byte-wise Reno implementation is an estimate.  We expect
-    // the cwnd to increase by approximately one MSS every
-    // cwnd/kDefaultTCPMSS/Alpha acks, but it may be off by as much as
-    // half a packet for smaller values of current_cwnd.
-    const QuicByteCount cwnd_change_this_epoch =
-        current_cwnd - initial_cwnd_this_epoch;
-    ASSERT_NEAR(kDefaultTCPMSS, cwnd_change_this_epoch, kDefaultTCPMSS / 2);
-    clock_.AdvanceTime(hundred_ms_);
-  }
-
-  for (int i = 0; i < 54; ++i) {
-    const uint64_t max_acks_this_epoch = current_cwnd / kDefaultTCPMSS;
-    const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
-        hundred_ms_.ToMicroseconds() / max_acks_this_epoch);
-    for (QuicPacketCount n = 0; n < max_acks_this_epoch; ++n) {
-      clock_.AdvanceTime(interval);
-      current_cwnd = cubic_.CongestionWindowAfterAck(
-          kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-      const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
-          initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
-      // If we allow per-ack updates, every update is a small cubic update.
-      ASSERT_EQ(expected_cwnd, current_cwnd);
-    }
-  }
-  const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
-      initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
-  current_cwnd = cubic_.CongestionWindowAfterAck(
-      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  ASSERT_EQ(expected_cwnd, current_cwnd);
-}
-
-// TODO(ianswett): This test was disabled when all fixes were enabled, but it
-// may be worth fixing.
-TEST_F(CubicBytesTest, DISABLED_AboveOrigin) {
-  // Convex growth.
-  const QuicTime::Delta rtt_min = hundred_ms_;
-  QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
-  // Without the signed-integer, cubic-convex fix, we start out in the
-  // wrong mode.
-  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
-  // Initialize the state.
-  clock_.AdvanceTime(one_ms_);
-  ASSERT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
-                                            rtt_min, clock_.ApproximateNow()));
-  current_cwnd = expected_cwnd;
-  const QuicPacketCount initial_cwnd = expected_cwnd;
-  // Normal TCP phase.
-  for (int i = 0; i < 48; ++i) {
-    for (QuicPacketCount n = 1;
-         n < current_cwnd / kDefaultTCPMSS / kNConnectionAlpha; ++n) {
-      // Call once per ACK.
-      ASSERT_NEAR(
-          current_cwnd,
-          cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
-                                          clock_.ApproximateNow()),
-          kDefaultTCPMSS);
-    }
-    clock_.AdvanceTime(hundred_ms_);
-    current_cwnd = cubic_.CongestionWindowAfterAck(
-        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-    // When we fix convex mode and the uint64 arithmetic, we
-    // increase the expected_cwnd only after after the first 100ms,
-    // rather than after the initial 1ms.
-    expected_cwnd += kDefaultTCPMSS;
-    ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
-  }
-  // Cubic phase.
-  for (int i = 0; i < 52; ++i) {
-    for (QuicPacketCount n = 1; n < current_cwnd / kDefaultTCPMSS; ++n) {
-      // Call once per ACK.
-      ASSERT_NEAR(
-          current_cwnd,
-          cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
-                                          clock_.ApproximateNow()),
-          kDefaultTCPMSS);
-    }
-    clock_.AdvanceTime(hundred_ms_);
-    current_cwnd = cubic_.CongestionWindowAfterAck(
-        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  }
-  // Total time elapsed so far; add min_rtt (0.1s) here as well.
-  float elapsed_time_s = 10.0f + 0.1f;
-  // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
-  expected_cwnd =
-      initial_cwnd / kDefaultTCPMSS +
-      (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
-  EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS);
-}
-
-// Constructs an artificial scenario to ensure that cubic-convex
-// increases are truly fine-grained:
-//
-// - After starting the epoch, this test advances the elapsed time
-// sufficiently far that cubic will do small increases at less than
-// MaxCubicTimeInterval() intervals.
-//
-// - Sets an artificially large initial cwnd to prevent Reno from the
-// convex increases on every ack.
-TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) {
-  // Start the test with an artificially large cwnd to prevent Reno
-  // from over-taking cubic.
-  QuicByteCount current_cwnd = 1000 * kDefaultTCPMSS;
-  const QuicByteCount initial_cwnd = current_cwnd;
-  const QuicTime::Delta rtt_min = hundred_ms_;
-  clock_.AdvanceTime(one_ms_);
-  QuicTime initial_time = clock_.ApproximateNow();
-
-  // Start the epoch and then artificially advance the time.
-  current_cwnd = cubic_.CongestionWindowAfterAck(
-      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(600));
-  current_cwnd = cubic_.CongestionWindowAfterAck(
-      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-
-  // We expect the algorithm to perform only non-zero, fine-grained cubic
-  // increases on every ack in this case.
-  for (int i = 0; i < 100; ++i) {
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-    const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
-        initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
-    const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
-        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-    // Make sure we are performing cubic increases.
-    ASSERT_EQ(expected_cwnd, next_cwnd);
-    // Make sure that these are non-zero, less-than-packet sized
-    // increases.
-    ASSERT_GT(next_cwnd, current_cwnd);
-    const QuicByteCount cwnd_delta = next_cwnd - current_cwnd;
-    ASSERT_GT(kDefaultTCPMSS * .1, cwnd_delta);
-
-    current_cwnd = next_cwnd;
-  }
-}
-
-// Constructs an artificial scenario to show what happens when we
-// allow per-ack updates, rather than limititing update freqency.  In
-// this scenario, the first two acks of the epoch produce the same
-// cwnd.  When we limit per-ack updates, this would cause the
-// cessation of cubic updates for 30ms.  When we allow per-ack
-// updates, the window continues to grow on every ack.
-TEST_F(CubicBytesTest, PerAckUpdates) {
-  // Start the test with a large cwnd and RTT, to force the first
-  // increase to be a cubic increase.
-  QuicPacketCount initial_cwnd_packets = 150;
-  QuicByteCount current_cwnd = initial_cwnd_packets * kDefaultTCPMSS;
-  const QuicTime::Delta rtt_min = 350 * one_ms_;
-
-  // Initialize the epoch
-  clock_.AdvanceTime(one_ms_);
-  // Keep track of the growth of the reno-equivalent cwnd.
-  QuicByteCount reno_cwnd = RenoCwndInBytes(current_cwnd);
-  current_cwnd = cubic_.CongestionWindowAfterAck(
-      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  const QuicByteCount initial_cwnd = current_cwnd;
-
-  // Simulate the return of cwnd packets in less than
-  // MaxCubicInterval() time.
-  const QuicPacketCount max_acks = initial_cwnd_packets / kNConnectionAlpha;
-  const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
-      MaxCubicTimeInterval().ToMicroseconds() / (max_acks + 1));
-
-  // In this scenario, the first increase is dictated by the cubic
-  // equation, but it is less than one byte, so the cwnd doesn't
-  // change.  Normally, without per-ack increases, any cwnd plateau
-  // will cause the cwnd to be pinned for MaxCubicTimeInterval().  If
-  // we enable per-ack updates, the cwnd will continue to grow,
-  // regardless of the temporary plateau.
-  clock_.AdvanceTime(interval);
-  reno_cwnd = RenoCwndInBytes(reno_cwnd);
-  ASSERT_EQ(current_cwnd,
-            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
-                                            rtt_min, clock_.ApproximateNow()));
-  for (QuicPacketCount i = 1; i < max_acks; ++i) {
-    clock_.AdvanceTime(interval);
-    const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
-        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-    reno_cwnd = RenoCwndInBytes(reno_cwnd);
-    // The window shoud increase on every ack.
-    ASSERT_LT(current_cwnd, next_cwnd);
-    ASSERT_EQ(reno_cwnd, next_cwnd);
-    current_cwnd = next_cwnd;
-  }
-
-  // After all the acks are returned from the epoch, we expect the
-  // cwnd to have increased by nearly one packet.  (Not exactly one
-  // packet, because our byte-wise Reno algorithm is always a slight
-  // under-estimation).  Without per-ack updates, the current_cwnd
-  // would otherwise be unchanged.
-  const QuicByteCount minimum_expected_increase = kDefaultTCPMSS * .9;
-  EXPECT_LT(minimum_expected_increase + initial_cwnd, current_cwnd);
-}
-
-TEST_F(CubicBytesTest, LossEvents) {
-  const QuicTime::Delta rtt_min = hundred_ms_;
-  QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
-  // Without the signed-integer, cubic-convex fix, we mistakenly
-  // increment cwnd after only one_ms_ and a single ack.
-  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
-  // Initialize the state.
-  clock_.AdvanceTime(one_ms_);
-  EXPECT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
-                                            rtt_min, clock_.ApproximateNow()));
-
-  // On the first loss, the last max congestion window is set to the
-  // congestion window before the loss.
-  QuicByteCount pre_loss_cwnd = current_cwnd;
-  ASSERT_EQ(0u, LastMaxCongestionWindow());
-  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
-  EXPECT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
-  ASSERT_EQ(pre_loss_cwnd, LastMaxCongestionWindow());
-  current_cwnd = expected_cwnd;
-
-  // On the second loss, the current congestion window has not yet
-  // reached the last max congestion window.  The last max congestion
-  // window will be reduced by an additional backoff factor to allow
-  // for competition.
-  pre_loss_cwnd = current_cwnd;
-  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
-  ASSERT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
-  current_cwnd = expected_cwnd;
-  EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow());
-  QuicByteCount expected_last_max =
-      static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax);
-  EXPECT_EQ(expected_last_max, LastMaxCongestionWindow());
-  EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
-  // Simulate an increase, and check that we are below the origin.
-  current_cwnd = cubic_.CongestionWindowAfterAck(
-      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
-
-  // On the final loss, simulate the condition where the congestion
-  // window had a chance to grow nearly to the last congestion window.
-  current_cwnd = LastMaxCongestionWindow() - 1;
-  pre_loss_cwnd = current_cwnd;
-  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
-  EXPECT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
-  expected_last_max = pre_loss_cwnd;
-  ASSERT_EQ(expected_last_max, LastMaxCongestionWindow());
-}
-
-TEST_F(CubicBytesTest, BelowOrigin) {
-  // Concave growth.
-  const QuicTime::Delta rtt_min = hundred_ms_;
-  QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
-  // Without the signed-integer, cubic-convex fix, we mistakenly
-  // increment cwnd after only one_ms_ and a single ack.
-  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
-  // Initialize the state.
-  clock_.AdvanceTime(one_ms_);
-  EXPECT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
-                                            rtt_min, clock_.ApproximateNow()));
-  expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
-  EXPECT_EQ(expected_cwnd,
-            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
-  current_cwnd = expected_cwnd;
-  // First update after loss to initialize the epoch.
-  current_cwnd = cubic_.CongestionWindowAfterAck(
-      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  // Cubic phase.
-  for (int i = 0; i < 40; ++i) {
-    clock_.AdvanceTime(hundred_ms_);
-    current_cwnd = cubic_.CongestionWindowAfterAck(
-        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
-  }
-  expected_cwnd = 553632;
-  EXPECT_EQ(expected_cwnd, current_cwnd);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/general_loss_algorithm.cc b/quic/core/congestion_control/general_loss_algorithm.cc
deleted file mode 100644
index f9b7ac4..0000000
--- a/quic/core/congestion_control/general_loss_algorithm.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-float DetectionResponseTime(QuicTime::Delta rtt,
-                            QuicTime send_time,
-                            QuicTime detection_time) {
-  if (detection_time <= send_time || rtt.IsZero()) {
-    // Time skewed, assume a very fast detection where |detection_time| is
-    // |send_time| + |rtt|.
-    return 1.0;
-  }
-  float send_to_detection_us = (detection_time - send_time).ToMicroseconds();
-  return send_to_detection_us / rtt.ToMicroseconds();
-}
-
-QuicTime::Delta GetMaxRtt(const RttStats& rtt_stats) {
-  return std::max(kAlarmGranularity,
-                  std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt()));
-}
-
-}  // namespace
-
-// Uses nack counts to decide when packets are lost.
-LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
-    const QuicUnackedPacketMap& unacked_packets,
-    QuicTime time,
-    const RttStats& rtt_stats,
-    QuicPacketNumber largest_newly_acked,
-    const AckedPacketVector& packets_acked,
-    LostPacketVector* packets_lost) {
-  DetectionStats detection_stats;
-
-  loss_detection_timeout_ = QuicTime::Zero();
-  if (!packets_acked.empty() && least_in_flight_.IsInitialized() &&
-      packets_acked.front().packet_number == least_in_flight_) {
-    if (packets_acked.back().packet_number == largest_newly_acked &&
-        least_in_flight_ + packets_acked.size() - 1 == largest_newly_acked) {
-      // Optimization for the case when no packet is missing. Please note,
-      // packets_acked can include packets of different packet number space, so
-      // do not use this optimization if largest_newly_acked is not the largest
-      // packet in packets_acked.
-      least_in_flight_ = largest_newly_acked + 1;
-      return detection_stats;
-    }
-    // There is hole in acked_packets, increment least_in_flight_ if possible.
-    for (const auto& acked : packets_acked) {
-      if (acked.packet_number != least_in_flight_) {
-        break;
-      }
-      ++least_in_flight_;
-    }
-  }
-
-  const QuicTime::Delta max_rtt = GetMaxRtt(rtt_stats);
-
-  QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
-  auto it = unacked_packets.begin();
-  if (least_in_flight_.IsInitialized() && least_in_flight_ >= packet_number) {
-    if (least_in_flight_ > unacked_packets.largest_sent_packet() + 1) {
-      QUIC_BUG(quic_bug_10430_1) << "least_in_flight: " << least_in_flight_
-                                 << " is greater than largest_sent_packet + 1: "
-                                 << unacked_packets.largest_sent_packet() + 1;
-    } else {
-      it += (least_in_flight_ - packet_number);
-      packet_number = least_in_flight_;
-    }
-  }
-  // Clear least_in_flight_.
-  least_in_flight_.Clear();
-  QUICHE_DCHECK_EQ(packet_number_space_,
-                   unacked_packets.GetPacketNumberSpace(largest_newly_acked));
-  for (; it != unacked_packets.end() && packet_number <= largest_newly_acked;
-       ++it, ++packet_number) {
-    if (unacked_packets.GetPacketNumberSpace(it->encryption_level) !=
-        packet_number_space_) {
-      // Skip packets of different packet number space.
-      continue;
-    }
-
-    if (!it->in_flight) {
-      continue;
-    }
-
-    if (parent_ != nullptr && largest_newly_acked != packet_number) {
-      parent_->OnReorderingDetected();
-    }
-
-    if (largest_newly_acked - packet_number >
-        detection_stats.sent_packets_max_sequence_reordering) {
-      detection_stats.sent_packets_max_sequence_reordering =
-          largest_newly_acked - packet_number;
-    }
-
-    // Packet threshold loss detection.
-    // Skip packet threshold loss detection if largest_newly_acked is a runt.
-    const bool skip_packet_threshold_detection =
-        !use_packet_threshold_for_runt_packets_ &&
-        it->bytes_sent >
-            unacked_packets.GetTransmissionInfo(largest_newly_acked).bytes_sent;
-    if (!skip_packet_threshold_detection &&
-        largest_newly_acked - packet_number >= reordering_threshold_) {
-      packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
-      detection_stats.total_loss_detection_response_time +=
-          DetectionResponseTime(max_rtt, it->sent_time, time);
-      continue;
-    }
-
-    // Time threshold loss detection.
-    const QuicTime::Delta loss_delay = max_rtt + (max_rtt >> reordering_shift_);
-    QuicTime when_lost = it->sent_time + loss_delay;
-    if (time < when_lost) {
-      if (time >=
-          it->sent_time + max_rtt + (max_rtt >> (reordering_shift_ + 1))) {
-        ++detection_stats.sent_packets_num_borderline_time_reorderings;
-      }
-      loss_detection_timeout_ = when_lost;
-      if (!least_in_flight_.IsInitialized()) {
-        // At this point, packet_number is in flight and not detected as lost.
-        least_in_flight_ = packet_number;
-      }
-      break;
-    }
-    packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
-    detection_stats.total_loss_detection_response_time +=
-        DetectionResponseTime(max_rtt, it->sent_time, time);
-  }
-  if (!least_in_flight_.IsInitialized()) {
-    // There is no in flight packet.
-    least_in_flight_ = largest_newly_acked + 1;
-  }
-
-  return detection_stats;
-}
-
-QuicTime GeneralLossAlgorithm::GetLossTimeout() const {
-  return loss_detection_timeout_;
-}
-
-void GeneralLossAlgorithm::SpuriousLossDetected(
-    const QuicUnackedPacketMap& unacked_packets,
-    const RttStats& rtt_stats,
-    QuicTime ack_receive_time,
-    QuicPacketNumber packet_number,
-    QuicPacketNumber previous_largest_acked) {
-  if (use_adaptive_time_threshold_ && reordering_shift_ > 0) {
-    // Increase reordering fraction such that the packet would not have been
-    // declared lost.
-    QuicTime::Delta time_needed =
-        ack_receive_time -
-        unacked_packets.GetTransmissionInfo(packet_number).sent_time;
-    QuicTime::Delta max_rtt =
-        std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt());
-    while (max_rtt + (max_rtt >> reordering_shift_) < time_needed &&
-           reordering_shift_ > 0) {
-      --reordering_shift_;
-    }
-  }
-
-  if (use_adaptive_reordering_threshold_) {
-    QUICHE_DCHECK_LT(packet_number, previous_largest_acked);
-    // Increase reordering_threshold_ such that packet_number would not have
-    // been declared lost.
-    reordering_threshold_ = std::max(
-        reordering_threshold_, previous_largest_acked - packet_number + 1);
-  }
-}
-
-void GeneralLossAlgorithm::Initialize(PacketNumberSpace packet_number_space,
-                                      LossDetectionInterface* parent) {
-  parent_ = parent;
-  if (packet_number_space_ < NUM_PACKET_NUMBER_SPACES) {
-    QUIC_BUG(quic_bug_10430_2) << "Cannot switch packet_number_space";
-    return;
-  }
-
-  packet_number_space_ = packet_number_space;
-}
-
-void GeneralLossAlgorithm::Reset() {
-  loss_detection_timeout_ = QuicTime::Zero();
-  least_in_flight_.Clear();
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/general_loss_algorithm.h b/quic/core/congestion_control/general_loss_algorithm.h
deleted file mode 100644
index 6a3c5dd..0000000
--- a/quic/core/congestion_control/general_loss_algorithm.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
-
-#include <algorithm>
-#include <map>
-
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Class which can be configured to implement's TCP's approach of detecting loss
-// when 3 nacks have been received for a packet or with a time threshold.
-// Also implements TCP's early retransmit(RFC5827).
-class QUIC_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
- public:
-  GeneralLossAlgorithm() = default;
-  GeneralLossAlgorithm(const GeneralLossAlgorithm&) = delete;
-  GeneralLossAlgorithm& operator=(const GeneralLossAlgorithm&) = delete;
-  ~GeneralLossAlgorithm() override {}
-
-  void SetFromConfig(const QuicConfig& /*config*/,
-                     Perspective /*perspective*/) override {}
-
-  // Uses |largest_acked| and time to decide when packets are lost.
-  DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
-                              QuicTime time,
-                              const RttStats& rtt_stats,
-                              QuicPacketNumber largest_newly_acked,
-                              const AckedPacketVector& packets_acked,
-                              LostPacketVector* packets_lost) override;
-
-  // Returns a non-zero value when the early retransmit timer is active.
-  QuicTime GetLossTimeout() const override;
-
-  // Called to increases time and/or packet threshold.
-  void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
-                            const RttStats& rtt_stats,
-                            QuicTime ack_receive_time,
-                            QuicPacketNumber packet_number,
-                            QuicPacketNumber previous_largest_acked) override;
-
-  void OnConfigNegotiated() override {
-    QUICHE_DCHECK(false)
-        << "Unexpected call to GeneralLossAlgorithm::OnConfigNegotiated";
-  }
-
-  void OnMinRttAvailable() override {
-    QUICHE_DCHECK(false)
-        << "Unexpected call to GeneralLossAlgorithm::OnMinRttAvailable";
-  }
-
-  void OnUserAgentIdKnown() override {
-    QUICHE_DCHECK(false)
-        << "Unexpected call to GeneralLossAlgorithm::OnUserAgentIdKnown";
-  }
-
-  void OnConnectionClosed() override {
-    QUICHE_DCHECK(false)
-        << "Unexpected call to GeneralLossAlgorithm::OnConnectionClosed";
-  }
-
-  void OnReorderingDetected() override {
-    QUICHE_DCHECK(false)
-        << "Unexpected call to GeneralLossAlgorithm::OnReorderingDetected";
-  }
-
-  void Initialize(PacketNumberSpace packet_number_space,
-                  LossDetectionInterface* parent);
-
-  void Reset();
-
-  QuicPacketCount reordering_threshold() const { return reordering_threshold_; }
-
-  int reordering_shift() const { return reordering_shift_; }
-
-  void set_reordering_shift(int reordering_shift) {
-    reordering_shift_ = reordering_shift;
-  }
-
-  void set_reordering_threshold(QuicPacketCount reordering_threshold) {
-    reordering_threshold_ = reordering_threshold;
-  }
-
-  bool use_adaptive_reordering_threshold() const {
-    return use_adaptive_reordering_threshold_;
-  }
-
-  void set_use_adaptive_reordering_threshold(bool value) {
-    use_adaptive_reordering_threshold_ = value;
-  }
-
-  bool use_adaptive_time_threshold() const {
-    return use_adaptive_time_threshold_;
-  }
-
-  void enable_adaptive_time_threshold() { use_adaptive_time_threshold_ = true; }
-
-  bool use_packet_threshold_for_runt_packets() const {
-    return use_packet_threshold_for_runt_packets_;
-  }
-
-  void disable_packet_threshold_for_runt_packets() {
-    use_packet_threshold_for_runt_packets_ = false;
-  }
-
- private:
-  LossDetectionInterface* parent_ = nullptr;
-  QuicTime loss_detection_timeout_ = QuicTime::Zero();
-  // Fraction of a max(SRTT, latest_rtt) to permit reordering before declaring
-  // loss.  Fraction calculated by shifting max(SRTT, latest_rtt) to the right
-  // by reordering_shift.
-  int reordering_shift_ = kDefaultLossDelayShift;
-  // Reordering threshold for loss detection.
-  QuicPacketCount reordering_threshold_ = kDefaultPacketReorderingThreshold;
-  // If true, uses adaptive reordering threshold for loss detection.
-  bool use_adaptive_reordering_threshold_ = true;
-  // If true, uses adaptive time threshold for time based loss detection.
-  bool use_adaptive_time_threshold_ = false;
-  // If true, uses packet threshold when largest acked is a runt packet.
-  bool use_packet_threshold_for_runt_packets_ = true;
-  // The least in flight packet. Loss detection should start from this. Please
-  // note, least_in_flight_ could be largest packet ever sent + 1.
-  QuicPacketNumber least_in_flight_{1};
-  PacketNumberSpace packet_number_space_ = NUM_PACKET_NUMBER_SPACES;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
diff --git a/quic/core/congestion_control/general_loss_algorithm_test.cc b/quic/core/congestion_control/general_loss_algorithm_test.cc
deleted file mode 100644
index b8cffab..0000000
--- a/quic/core/congestion_control/general_loss_algorithm_test.cc
+++ /dev/null
@@ -1,489 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-
-#include <algorithm>
-#include <cstdint>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-class GeneralLossAlgorithmTest : public QuicTest {
- protected:
-  GeneralLossAlgorithmTest() : unacked_packets_(Perspective::IS_CLIENT) {
-    rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                         QuicTime::Delta::Zero(), clock_.Now());
-    EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
-    loss_algorithm_.Initialize(HANDSHAKE_DATA, nullptr);
-  }
-
-  ~GeneralLossAlgorithmTest() override {}
-
-  void SendDataPacket(uint64_t packet_number,
-                      QuicPacketLength encrypted_length) {
-    QuicStreamFrame frame;
-    frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-        CurrentSupportedVersions()[0].transport_version,
-        Perspective::IS_CLIENT);
-    SerializedPacket packet(QuicPacketNumber(packet_number),
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr,
-                            encrypted_length, false, false);
-    packet.retransmittable_frames.push_back(QuicFrame(frame));
-    unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
-                                   true, true);
-  }
-
-  void SendDataPacket(uint64_t packet_number) {
-    SendDataPacket(packet_number, kDefaultLength);
-  }
-
-  void SendAckPacket(uint64_t packet_number) {
-    SerializedPacket packet(QuicPacketNumber(packet_number),
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            true, false);
-    unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
-                                   false, true);
-  }
-
-  void VerifyLosses(uint64_t largest_newly_acked,
-                    const AckedPacketVector& packets_acked,
-                    const std::vector<uint64_t>& losses_expected) {
-    return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
-                        absl::nullopt, absl::nullopt);
-  }
-
-  void VerifyLosses(
-      uint64_t largest_newly_acked,
-      const AckedPacketVector& packets_acked,
-      const std::vector<uint64_t>& losses_expected,
-      absl::optional<QuicPacketCount> max_sequence_reordering_expected,
-      absl::optional<QuicPacketCount>
-          num_borderline_time_reorderings_expected) {
-    unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
-        APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
-    LostPacketVector lost_packets;
-    LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
-        unacked_packets_, clock_.Now(), rtt_stats_,
-        QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
-    if (max_sequence_reordering_expected.has_value()) {
-      EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
-                max_sequence_reordering_expected.value());
-    }
-    if (num_borderline_time_reorderings_expected.has_value()) {
-      EXPECT_EQ(stats.sent_packets_num_borderline_time_reorderings,
-                num_borderline_time_reorderings_expected.value());
-    }
-    ASSERT_EQ(losses_expected.size(), lost_packets.size());
-    for (size_t i = 0; i < losses_expected.size(); ++i) {
-      EXPECT_EQ(lost_packets[i].packet_number,
-                QuicPacketNumber(losses_expected[i]));
-    }
-  }
-
-  QuicUnackedPacketMap unacked_packets_;
-  GeneralLossAlgorithm loss_algorithm_;
-  RttStats rtt_stats_;
-  MockClock clock_;
-};
-
-TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
-  const size_t kNumSentPackets = 5;
-  // Transmit 5 packets.
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-  AckedPacketVector packets_acked;
-  // No loss on one ack.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1, 0);
-  packets_acked.clear();
-  // No loss on two acks.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2, 0);
-  packets_acked.clear();
-  // Loss on three acks.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, {1}, 3, 0);
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-// A stretch ack is an ack that covers more than 1 packet of previously
-// unacknowledged data.
-TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
-  const size_t kNumSentPackets = 10;
-  // Transmit 10 packets.
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-  AckedPacketVector packets_acked;
-  // Nack the first packet 3 times in a single StretchAck.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, {1});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-// Ack a packet 3 packets ahead, causing a retransmit.
-TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
-  const size_t kNumSentPackets = 10;
-  // Transmit 10 packets.
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-  AckedPacketVector packets_acked;
-  // Nack the first packet 3 times in an AckFrame with three missing packets.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, {1});
-  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
-  const size_t kNumSentPackets = 2;
-  // Transmit 2 packets.
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-  AckedPacketVector packets_acked;
-  // Early retransmit when the final packet gets acked and the first is nacked.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-
-  clock_.AdvanceTime(1.13 * rtt_stats_.latest_rtt());
-  // If reordering_shift increases by one we should have detected a loss.
-  VerifyLosses(2, packets_acked, {}, /*max_sequence_reordering_expected=*/1,
-               /*num_borderline_time_reorderings_expected=*/1);
-
-  clock_.AdvanceTime(0.13 * rtt_stats_.latest_rtt());
-  VerifyLosses(2, packets_acked, {1});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
-  const size_t kNumSentPackets = 5;
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-    // Advance the time 1/4 RTT between 3 and 4.
-    if (i == 3) {
-      clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
-    }
-  }
-  AckedPacketVector packets_acked;
-  // Early retransmit when the final packet gets acked and 1.25 RTTs have
-  // elapsed since the packets were sent.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
-  packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
-                                      kMaxOutgoingPacketSize,
-                                      QuicTime::Zero()));
-  // This simulates a single ack following multiple missing packets with FACK.
-  VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
-  packets_acked.clear();
-  // The time has already advanced 1/4 an RTT, so ensure the timeout is set
-  // 1.25 RTTs after the earliest pending packet(3), not the last(4).
-  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-  VerifyLosses(kNumSentPackets, packets_acked, {3});
-  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-  clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
-  VerifyLosses(kNumSentPackets, packets_acked, {4});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
-  const size_t kNumSentPackets = 2;
-  // Transmit 2 packets.
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-  AckedPacketVector packets_acked;
-  // Neuter packet 1.
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-
-  // Early retransmit when the final packet gets acked and the first is nacked.
-  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) {
-  // Transmit 2 data packets and one ack.
-  SendDataPacket(1);
-  SendDataPacket(2);
-  SendAckPacket(3);
-  AckedPacketVector packets_acked;
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-
-  // Early retransmit when the final packet gets acked and the first is nacked.
-  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-
-  // The packet should be lost once the loss timeout is reached.
-  clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt());
-  VerifyLosses(2, packets_acked, {1});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
-  // Transmit 1 packet and then wait an rtt plus 1ms.
-  SendDataPacket(1);
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
-                     QuicTime::Delta::FromMilliseconds(1));
-
-  // Transmit 2 packets.
-  SendDataPacket(2);
-  SendDataPacket(3);
-  AckedPacketVector packets_acked;
-  // Wait another RTT and ack 2.
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, {1});
-}
-
-TEST_F(GeneralLossAlgorithmTest, IncreaseTimeThresholdUponSpuriousLoss) {
-  loss_algorithm_.enable_adaptive_time_threshold();
-  loss_algorithm_.set_reordering_shift(kDefaultLossDelayShift);
-  EXPECT_EQ(kDefaultLossDelayShift, loss_algorithm_.reordering_shift());
-  EXPECT_TRUE(loss_algorithm_.use_adaptive_time_threshold());
-  const size_t kNumSentPackets = 10;
-  // Transmit 2 packets at 1/10th an RTT interval.
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-    clock_.AdvanceTime(0.1 * rtt_stats_.smoothed_rtt());
-  }
-  EXPECT_EQ(QuicTime::Zero() + rtt_stats_.smoothed_rtt(), clock_.Now());
-  AckedPacketVector packets_acked;
-  // Expect the timer to not be set.
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-  // Packet 1 should not be lost until 1/4 RTTs pass.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  // Expect the timer to be set to 1/4 RTT's in the future.
-  EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 4),
-            loss_algorithm_.GetLossTimeout() - clock_.Now());
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
-  VerifyLosses(2, packets_acked, {1});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-  // Retransmit packet 1 as 11 and 2 as 12.
-  SendDataPacket(11);
-  SendDataPacket(12);
-
-  // Advance the time 1/4 RTT and indicate the loss was spurious.
-  // The new threshold should be 1/2 RTT.
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
-  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
-                                       clock_.Now(), QuicPacketNumber(1),
-                                       QuicPacketNumber(2));
-  EXPECT_EQ(1, loss_algorithm_.reordering_shift());
-}
-
-TEST_F(GeneralLossAlgorithmTest, IncreaseReorderingThresholdUponSpuriousLoss) {
-  loss_algorithm_.set_use_adaptive_reordering_threshold(true);
-  for (size_t i = 1; i <= 4; ++i) {
-    SendDataPacket(i);
-  }
-  // Acking 4 causes 1 detected lost.
-  AckedPacketVector packets_acked;
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, std::vector<uint64_t>{1});
-  packets_acked.clear();
-
-  // Retransmit 1 as 5.
-  SendDataPacket(5);
-
-  // Acking 1 such that it was detected lost spuriously.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(1), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
-                                       clock_.Now(), QuicPacketNumber(1),
-                                       QuicPacketNumber(4));
-  VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-
-  // Verify acking 5 does not cause 2 detected lost.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(5), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(5, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-
-  SendDataPacket(6);
-
-  // Acking 6 will causes 2 detected lost.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(6, packets_acked, std::vector<uint64_t>{2});
-  packets_acked.clear();
-
-  // Retransmit 2 as 7.
-  SendDataPacket(7);
-
-  // Acking 2 such that it was detected lost spuriously.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
-                                       clock_.Now(), QuicPacketNumber(2),
-                                       QuicPacketNumber(6));
-  VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-
-  // Acking 7 will not cause 3 as detected lost.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-}
-
-TEST_F(GeneralLossAlgorithmTest, DefaultIetfLossDetection) {
-  loss_algorithm_.set_reordering_shift(kDefaultIetfLossDelayShift);
-  for (size_t i = 1; i <= 6; ++i) {
-    SendDataPacket(i);
-  }
-  // Packet threshold loss detection.
-  AckedPacketVector packets_acked;
-  // No loss on one ack.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  // No loss on two acks.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  // Loss on three acks.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, {1});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-  packets_acked.clear();
-
-  SendDataPacket(7);
-
-  // Time threshold loss detection.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
-                (rtt_stats_.smoothed_rtt() >> 3),
-            loss_algorithm_.GetLossTimeout());
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
-                     (rtt_stats_.smoothed_rtt() >> 3));
-  VerifyLosses(6, packets_acked, {5});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, IetfLossDetectionWithOneFourthRttDelay) {
-  loss_algorithm_.set_reordering_shift(2);
-  SendDataPacket(1);
-  SendDataPacket(2);
-
-  AckedPacketVector packets_acked;
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
-  packets_acked.clear();
-  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
-                (rtt_stats_.smoothed_rtt() >> 2),
-            loss_algorithm_.GetLossTimeout());
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
-                     (rtt_stats_.smoothed_rtt() >> 2));
-  VerifyLosses(2, packets_acked, {1});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(GeneralLossAlgorithmTest, NoPacketThresholdForRuntPackets) {
-  loss_algorithm_.disable_packet_threshold_for_runt_packets();
-  for (size_t i = 1; i <= 6; ++i) {
-    SendDataPacket(i);
-  }
-  // Send a small packet.
-  SendDataPacket(7, /*encrypted_length=*/kDefaultLength / 2);
-  // No packet threshold for runt packet.
-  AckedPacketVector packets_acked;
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
-  packets_acked.push_back(AckedPacket(
-      QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
-  // Verify no packet is detected lost because packet 7 is a runt.
-  VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
-  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
-                (rtt_stats_.smoothed_rtt() >> 2),
-            loss_algorithm_.GetLossTimeout());
-  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
-                     (rtt_stats_.smoothed_rtt() >> 2));
-  // Verify packets are declared lost because time threshold has passed.
-  VerifyLosses(7, packets_acked, {1, 2, 3, 4, 5, 6});
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/hybrid_slow_start.cc b/quic/core/congestion_control/hybrid_slow_start.cc
deleted file mode 100644
index 1e567fa..0000000
--- a/quic/core/congestion_control/hybrid_slow_start.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/hybrid_slow_start.h"
-
-#include <algorithm>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// Note(pwestin): the magic clamping numbers come from the original code in
-// tcp_cubic.c.
-const int64_t kHybridStartLowWindow = 16;
-// Number of delay samples for detecting the increase of delay.
-const uint32_t kHybridStartMinSamples = 8;
-// Exit slow start if the min rtt has increased by more than 1/8th.
-const int kHybridStartDelayFactorExp = 3;  // 2^3 = 8
-// The original paper specifies 2 and 8ms, but those have changed over time.
-const int64_t kHybridStartDelayMinThresholdUs = 4000;
-const int64_t kHybridStartDelayMaxThresholdUs = 16000;
-
-HybridSlowStart::HybridSlowStart()
-    : started_(false),
-      hystart_found_(NOT_FOUND),
-      rtt_sample_count_(0),
-      current_min_rtt_(QuicTime::Delta::Zero()) {}
-
-void HybridSlowStart::OnPacketAcked(QuicPacketNumber acked_packet_number) {
-  // OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end
-  // the round when the final packet of the burst is received and start it on
-  // the next incoming ack.
-  if (IsEndOfRound(acked_packet_number)) {
-    started_ = false;
-  }
-}
-
-void HybridSlowStart::OnPacketSent(QuicPacketNumber packet_number) {
-  last_sent_packet_number_ = packet_number;
-}
-
-void HybridSlowStart::Restart() {
-  started_ = false;
-  hystart_found_ = NOT_FOUND;
-}
-
-void HybridSlowStart::StartReceiveRound(QuicPacketNumber last_sent) {
-  QUIC_DVLOG(1) << "Reset hybrid slow start @" << last_sent;
-  end_packet_number_ = last_sent;
-  current_min_rtt_ = QuicTime::Delta::Zero();
-  rtt_sample_count_ = 0;
-  started_ = true;
-}
-
-bool HybridSlowStart::IsEndOfRound(QuicPacketNumber ack) const {
-  return !end_packet_number_.IsInitialized() || end_packet_number_ <= ack;
-}
-
-bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
-                                          QuicTime::Delta min_rtt,
-                                          QuicPacketCount congestion_window) {
-  if (!started_) {
-    // Time to start the hybrid slow start.
-    StartReceiveRound(last_sent_packet_number_);
-  }
-  if (hystart_found_ != NOT_FOUND) {
-    return true;
-  }
-  // Second detection parameter - delay increase detection.
-  // Compare the minimum delay (current_min_rtt_) of the current
-  // burst of packets relative to the minimum delay during the session.
-  // Note: we only look at the first few(8) packets in each burst, since we
-  // only want to compare the lowest RTT of the burst relative to previous
-  // bursts.
-  rtt_sample_count_++;
-  if (rtt_sample_count_ <= kHybridStartMinSamples) {
-    if (current_min_rtt_.IsZero() || current_min_rtt_ > latest_rtt) {
-      current_min_rtt_ = latest_rtt;
-    }
-  }
-  // We only need to check this once per round.
-  if (rtt_sample_count_ == kHybridStartMinSamples) {
-    // Divide min_rtt by 8 to get a rtt increase threshold for exiting.
-    int64_t min_rtt_increase_threshold_us =
-        min_rtt.ToMicroseconds() >> kHybridStartDelayFactorExp;
-    // Ensure the rtt threshold is never less than 2ms or more than 16ms.
-    min_rtt_increase_threshold_us = std::min(min_rtt_increase_threshold_us,
-                                             kHybridStartDelayMaxThresholdUs);
-    QuicTime::Delta min_rtt_increase_threshold =
-        QuicTime::Delta::FromMicroseconds(std::max(
-            min_rtt_increase_threshold_us, kHybridStartDelayMinThresholdUs));
-
-    if (current_min_rtt_ > min_rtt + min_rtt_increase_threshold) {
-      hystart_found_ = DELAY;
-    }
-  }
-  // Exit from slow start if the cwnd is greater than 16 and
-  // increasing delay is found.
-  return congestion_window >= kHybridStartLowWindow &&
-         hystart_found_ != NOT_FOUND;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/hybrid_slow_start.h b/quic/core/congestion_control/hybrid_slow_start.h
deleted file mode 100644
index bd1292a..0000000
--- a/quic/core/congestion_control/hybrid_slow_start.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This class is a helper class to TcpCubicSender.
-// Slow start is the initial startup phase of TCP, it lasts until first packet
-// loss. This class implements hybrid slow start of the TCP cubic send side
-// congestion algorithm. The key feaure of hybrid slow start is that it tries to
-// avoid running into the wall too hard during the slow start phase, which
-// the traditional TCP implementation does.
-// This does not implement ack train detection because it interacts poorly with
-// pacing.
-// http://netsrv.csc.ncsu.edu/export/hybridstart_pfldnet08.pdf
-// http://research.csc.ncsu.edu/netsrv/sites/default/files/hystart_techreport_2008.pdf
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE HybridSlowStart {
- public:
-  HybridSlowStart();
-  HybridSlowStart(const HybridSlowStart&) = delete;
-  HybridSlowStart& operator=(const HybridSlowStart&) = delete;
-
-  void OnPacketAcked(QuicPacketNumber acked_packet_number);
-
-  void OnPacketSent(QuicPacketNumber packet_number);
-
-  // ShouldExitSlowStart should be called on every new ack frame, since a new
-  // RTT measurement can be made then.
-  // rtt: the RTT for this ack packet.
-  // min_rtt: is the lowest delay (RTT) we have seen during the session.
-  // congestion_window: the congestion window in packets.
-  bool ShouldExitSlowStart(QuicTime::Delta rtt,
-                           QuicTime::Delta min_rtt,
-                           QuicPacketCount congestion_window);
-
-  // Start a new slow start phase.
-  void Restart();
-
-  // TODO(ianswett): The following methods should be private, but that requires
-  // a follow up CL to update the unit test.
-  // Returns true if this ack the last packet number of our current slow start
-  // round.
-  // Call Reset if this returns true.
-  bool IsEndOfRound(QuicPacketNumber ack) const;
-
-  // Call for the start of each receive round (burst) in the slow start phase.
-  void StartReceiveRound(QuicPacketNumber last_sent);
-
-  // Whether slow start has started.
-  bool started() const { return started_; }
-
- private:
-  // Whether a condition for exiting slow start has been found.
-  enum HystartState {
-    NOT_FOUND,
-    DELAY,  // Too much increase in the round's min_rtt was observed.
-  };
-
-  // Whether the hybrid slow start has been started.
-  bool started_;
-  HystartState hystart_found_;
-  // Last packet number sent which was CWND limited.
-  QuicPacketNumber last_sent_packet_number_;
-
-  // Variables for tracking acks received during a slow start round.
-  QuicPacketNumber end_packet_number_;  // End of the receive round.
-  uint32_t rtt_sample_count_;  // Number of rtt samples in the current round.
-  QuicTime::Delta current_min_rtt_;  // The minimum rtt of current round.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
diff --git a/quic/core/congestion_control/hybrid_slow_start_test.cc b/quic/core/congestion_control/hybrid_slow_start_test.cc
deleted file mode 100644
index caa0781..0000000
--- a/quic/core/congestion_control/hybrid_slow_start_test.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/hybrid_slow_start.h"
-
-#include <memory>
-#include <utility>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class HybridSlowStartTest : public QuicTest {
- protected:
-  HybridSlowStartTest()
-      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
-        rtt_(QuicTime::Delta::FromMilliseconds(60)) {}
-  void SetUp() override { slow_start_ = std::make_unique<HybridSlowStart>(); }
-  const QuicTime::Delta one_ms_;
-  const QuicTime::Delta rtt_;
-  std::unique_ptr<HybridSlowStart> slow_start_;
-};
-
-TEST_F(HybridSlowStartTest, Simple) {
-  QuicPacketNumber packet_number(1);
-  QuicPacketNumber end_packet_number(3);
-  slow_start_->StartReceiveRound(end_packet_number);
-
-  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
-
-  // Test duplicates.
-  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number));
-
-  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
-  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
-
-  // Test without a new registered end_packet_number;
-  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
-
-  end_packet_number = QuicPacketNumber(20);
-  slow_start_->StartReceiveRound(end_packet_number);
-  while (packet_number < end_packet_number) {
-    EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
-  }
-  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
-}
-
-TEST_F(HybridSlowStartTest, Delay) {
-  // We expect to detect the increase at +1/8 of the RTT; hence at a typical
-  // RTT of 60ms the detection will happen at 67.5 ms.
-  const int kHybridStartMinSamples = 8;  // Number of acks required to trigger.
-
-  QuicPacketNumber end_packet_number(1);
-  slow_start_->StartReceiveRound(end_packet_number++);
-
-  // Will not trigger since our lowest RTT in our burst is the same as the long
-  // term RTT provided.
-  for (int n = 0; n < kHybridStartMinSamples; ++n) {
-    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
-        rtt_ + QuicTime::Delta::FromMilliseconds(n), rtt_, 100));
-  }
-  slow_start_->StartReceiveRound(end_packet_number++);
-  for (int n = 1; n < kHybridStartMinSamples; ++n) {
-    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
-        rtt_ + QuicTime::Delta::FromMilliseconds(n + 10), rtt_, 100));
-  }
-  // Expect to trigger since all packets in this burst was above the long term
-  // RTT provided.
-  EXPECT_TRUE(slow_start_->ShouldExitSlowStart(
-      rtt_ + QuicTime::Delta::FromMilliseconds(10), rtt_, 100));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/loss_detection_interface.h b/quic/core/congestion_control/loss_detection_interface.h
deleted file mode 100644
index 77c8913..0000000
--- a/quic/core/congestion_control/loss_detection_interface.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The pure virtual class for send side loss detection algorithm.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicUnackedPacketMap;
-class RttStats;
-
-class QUIC_EXPORT_PRIVATE LossDetectionInterface {
- public:
-  virtual ~LossDetectionInterface() {}
-
-  virtual void SetFromConfig(const QuicConfig& config,
-                             Perspective perspective) = 0;
-
-  struct QUIC_NO_EXPORT DetectionStats {
-    // Maximum sequence reordering observed in newly acked packets.
-    QuicPacketCount sent_packets_max_sequence_reordering = 0;
-    QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
-    // Total detection response time for lost packets from this detection.
-    // See QuicConnectionStats for the definition of detection response time.
-    float total_loss_detection_response_time = 0.0;
-  };
-
-  // Called when a new ack arrives or the loss alarm fires.
-  virtual DetectionStats DetectLosses(
-      const QuicUnackedPacketMap& unacked_packets,
-      QuicTime time,
-      const RttStats& rtt_stats,
-      QuicPacketNumber largest_newly_acked,
-      const AckedPacketVector& packets_acked,
-      LostPacketVector* packets_lost) = 0;
-
-  // Get the time the LossDetectionAlgorithm wants to re-evaluate losses.
-  // Returns QuicTime::Zero if no alarm needs to be set.
-  virtual QuicTime GetLossTimeout() const = 0;
-
-  // Called when |packet_number| was detected lost but gets acked later.
-  virtual void SpuriousLossDetected(
-      const QuicUnackedPacketMap& unacked_packets,
-      const RttStats& rtt_stats,
-      QuicTime ack_receive_time,
-      QuicPacketNumber packet_number,
-      QuicPacketNumber previous_largest_acked) = 0;
-
-  virtual void OnConfigNegotiated() = 0;
-
-  virtual void OnMinRttAvailable() = 0;
-
-  virtual void OnUserAgentIdKnown() = 0;
-
-  virtual void OnConnectionClosed() = 0;
-
-  // Called when a reordering is detected by the loss algorithm, but _before_
-  // the reordering_shift and reordering_threshold are consulted to see whether
-  // it is a loss.
-  virtual void OnReorderingDetected() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
diff --git a/quic/core/congestion_control/pacing_sender.cc b/quic/core/congestion_control/pacing_sender.cc
deleted file mode 100644
index e4b6534..0000000
--- a/quic/core/congestion_control/pacing_sender.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/pacing_sender.h"
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-
-// Configured maximum size of the burst coming out of quiescence.  The burst
-// is never larger than the current CWND in packets.
-static const uint32_t kInitialUnpacedBurst = 10;
-
-}  // namespace
-
-PacingSender::PacingSender()
-    : sender_(nullptr),
-      max_pacing_rate_(QuicBandwidth::Zero()),
-      burst_tokens_(kInitialUnpacedBurst),
-      ideal_next_packet_send_time_(QuicTime::Zero()),
-      initial_burst_size_(kInitialUnpacedBurst),
-      lumpy_tokens_(0),
-      alarm_granularity_(kAlarmGranularity),
-      pacing_limited_(false) {
-  if (GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_donot_reset_ideal_next_packet_send_time);
-  }
-}
-
-PacingSender::~PacingSender() {}
-
-void PacingSender::set_sender(SendAlgorithmInterface* sender) {
-  QUICHE_DCHECK(sender != nullptr);
-  sender_ = sender;
-}
-
-void PacingSender::OnCongestionEvent(bool rtt_updated,
-                                     QuicByteCount bytes_in_flight,
-                                     QuicTime event_time,
-                                     const AckedPacketVector& acked_packets,
-                                     const LostPacketVector& lost_packets) {
-  QUICHE_DCHECK(sender_ != nullptr);
-  if (!lost_packets.empty()) {
-    // Clear any burst tokens when entering recovery.
-    burst_tokens_ = 0;
-  }
-  sender_->OnCongestionEvent(rtt_updated, bytes_in_flight, event_time,
-                             acked_packets, lost_packets);
-}
-
-void PacingSender::OnPacketSent(
-    QuicTime sent_time,
-    QuicByteCount bytes_in_flight,
-    QuicPacketNumber packet_number,
-    QuicByteCount bytes,
-    HasRetransmittableData has_retransmittable_data) {
-  QUICHE_DCHECK(sender_ != nullptr);
-  sender_->OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
-                        has_retransmittable_data);
-  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
-    return;
-  }
-  // If in recovery, the connection is not coming out of quiescence.
-  if (bytes_in_flight == 0 && !sender_->InRecovery()) {
-    // Add more burst tokens anytime the connection is leaving quiescence, but
-    // limit it to the equivalent of a single bulk write, not exceeding the
-    // current CWND in packets.
-    burst_tokens_ = std::min(
-        initial_burst_size_,
-        static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
-  }
-  if (burst_tokens_ > 0) {
-    --burst_tokens_;
-    if (!GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
-      ideal_next_packet_send_time_ = QuicTime::Zero();
-    }
-    pacing_limited_ = false;
-    return;
-  }
-  // The next packet should be sent as soon as the current packet has been
-  // transferred.  PacingRate is based on bytes in flight including this packet.
-  QuicTime::Delta delay =
-      PacingRate(bytes_in_flight + bytes).TransferTime(bytes);
-  if (!pacing_limited_ || lumpy_tokens_ == 0) {
-    // Reset lumpy_tokens_ if either application or cwnd throttles sending or
-    // token runs out.
-    lumpy_tokens_ = std::max(
-        1u, std::min(static_cast<uint32_t>(
-                         GetQuicFlag(FLAGS_quic_lumpy_pacing_size)),
-                     static_cast<uint32_t>(
-                         (sender_->GetCongestionWindow() *
-                          GetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction)) /
-                         kDefaultTCPMSS)));
-    if (sender_->BandwidthEstimate() <
-        QuicBandwidth::FromKBitsPerSecond(
-            GetQuicFlag(FLAGS_quic_lumpy_pacing_min_bandwidth_kbps))) {
-      // Below 1.2Mbps, send 1 packet at once, because one full-sized packet
-      // is about 10ms of queueing.
-      lumpy_tokens_ = 1u;
-    }
-    if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts) &&
-        (bytes_in_flight + bytes) >= sender_->GetCongestionWindow()) {
-      QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pacing_sender_bursts);
-      // Don't add lumpy_tokens if the congestion controller is CWND limited.
-      lumpy_tokens_ = 1u;
-    }
-  }
-  --lumpy_tokens_;
-  if (pacing_limited_) {
-    // Make up for lost time since pacing throttles the sending.
-    ideal_next_packet_send_time_ = ideal_next_packet_send_time_ + delay;
-  } else {
-    ideal_next_packet_send_time_ =
-        std::max(ideal_next_packet_send_time_ + delay, sent_time + delay);
-  }
-  // Stop making up for lost time if underlying sender prevents sending.
-  pacing_limited_ = sender_->CanSend(bytes_in_flight + bytes);
-}
-
-void PacingSender::OnApplicationLimited() {
-  // The send is application limited, stop making up for lost time.
-  pacing_limited_ = false;
-}
-
-void PacingSender::SetBurstTokens(uint32_t burst_tokens) {
-  initial_burst_size_ = burst_tokens;
-  burst_tokens_ = std::min(
-      initial_burst_size_,
-      static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
-}
-
-QuicTime::Delta PacingSender::TimeUntilSend(
-    QuicTime now,
-    QuicByteCount bytes_in_flight) const {
-  QUICHE_DCHECK(sender_ != nullptr);
-
-  if (!sender_->CanSend(bytes_in_flight)) {
-    // The underlying sender prevents sending.
-    return QuicTime::Delta::Infinite();
-  }
-
-  if (burst_tokens_ > 0 || bytes_in_flight == 0 || lumpy_tokens_ > 0) {
-    // Don't pace if we have burst tokens available or leaving quiescence.
-    QUIC_DVLOG(1) << "Sending packet now. burst_tokens:" << burst_tokens_
-                  << ", bytes_in_flight:" << bytes_in_flight
-                  << ", lumpy_tokens:" << lumpy_tokens_;
-    return QuicTime::Delta::Zero();
-  }
-
-  // If the next send time is within the alarm granularity, send immediately.
-  if (ideal_next_packet_send_time_ > now + alarm_granularity_) {
-    QUIC_DVLOG(1) << "Delaying packet: "
-                  << (ideal_next_packet_send_time_ - now).ToMicroseconds();
-    return ideal_next_packet_send_time_ - now;
-  }
-
-  QUIC_DVLOG(1) << "Sending packet now. ideal_next_packet_send_time: "
-                << ideal_next_packet_send_time_ << ", now: " << now;
-  return QuicTime::Delta::Zero();
-}
-
-QuicBandwidth PacingSender::PacingRate(QuicByteCount bytes_in_flight) const {
-  QUICHE_DCHECK(sender_ != nullptr);
-  if (!max_pacing_rate_.IsZero()) {
-    return QuicBandwidth::FromBitsPerSecond(
-        std::min(max_pacing_rate_.ToBitsPerSecond(),
-                 sender_->PacingRate(bytes_in_flight).ToBitsPerSecond()));
-  }
-  return sender_->PacingRate(bytes_in_flight);
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/pacing_sender.h b/quic/core/congestion_control/pacing_sender.h
deleted file mode 100644
index b2401a2..0000000
--- a/quic/core/congestion_control/pacing_sender.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A send algorithm that adds pacing on top of an another send algorithm.
-// It uses the underlying sender's pacing rate to schedule packets.
-// It also takes into consideration the expected granularity of the underlying
-// alarm to ensure that alarms are not set too aggressively, and err towards
-// sending packets too early instead of too late.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicSentPacketManagerPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE PacingSender {
- public:
-  PacingSender();
-  PacingSender(const PacingSender&) = delete;
-  PacingSender& operator=(const PacingSender&) = delete;
-  ~PacingSender();
-
-  // Sets the underlying sender. Does not take ownership of |sender|. |sender|
-  // must not be null. This must be called before any of the
-  // SendAlgorithmInterface wrapper methods are called.
-  void set_sender(SendAlgorithmInterface* sender);
-
-  void set_max_pacing_rate(QuicBandwidth max_pacing_rate) {
-    max_pacing_rate_ = max_pacing_rate;
-  }
-
-  void set_alarm_granularity(QuicTime::Delta alarm_granularity) {
-    alarm_granularity_ = alarm_granularity;
-  }
-
-  QuicBandwidth max_pacing_rate() const { return max_pacing_rate_; }
-
-  void OnCongestionEvent(bool rtt_updated,
-                         QuicByteCount bytes_in_flight,
-                         QuicTime event_time,
-                         const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets);
-
-  void OnPacketSent(QuicTime sent_time,
-                    QuicByteCount bytes_in_flight,
-                    QuicPacketNumber packet_number,
-                    QuicByteCount bytes,
-                    HasRetransmittableData has_retransmittable_data);
-
-  // Called when application throttles the sending, so that pacing sender stops
-  // making up for lost time.
-  void OnApplicationLimited();
-
-  // Set burst_tokens_ and initial_burst_size_.
-  void SetBurstTokens(uint32_t burst_tokens);
-
-  QuicTime::Delta TimeUntilSend(QuicTime now,
-                                QuicByteCount bytes_in_flight) const;
-
-  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const;
-
-  NextReleaseTimeResult GetNextReleaseTime() const {
-    bool allow_burst = (burst_tokens_ > 0 || lumpy_tokens_ > 0);
-    return {ideal_next_packet_send_time_, allow_burst};
-  }
-
-  uint32_t initial_burst_size() const { return initial_burst_size_; }
-
- protected:
-  uint32_t lumpy_tokens() const { return lumpy_tokens_; }
-
- private:
-  friend class test::QuicSentPacketManagerPeer;
-
-  // Underlying sender. Not owned.
-  SendAlgorithmInterface* sender_;
-  // If not QuicBandidth::Zero, the maximum rate the PacingSender will use.
-  QuicBandwidth max_pacing_rate_;
-
-  // Number of unpaced packets to be sent before packets are delayed.
-  uint32_t burst_tokens_;
-  QuicTime ideal_next_packet_send_time_;  // When can the next packet be sent.
-  uint32_t initial_burst_size_;
-
-  // Number of unpaced packets to be sent before packets are delayed. This token
-  // is consumed after burst_tokens_ ran out.
-  uint32_t lumpy_tokens_;
-
-  // If the next send time is within alarm_granularity_, send immediately.
-  // TODO(fayang): Remove alarm_granularity_ when deprecating
-  // quic_offload_pacing_to_usps2 flag.
-  QuicTime::Delta alarm_granularity_;
-
-  // Indicates whether pacing throttles the sending. If true, make up for lost
-  // time.
-  bool pacing_limited_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
diff --git a/quic/core/congestion_control/pacing_sender_test.cc b/quic/core/congestion_control/pacing_sender_test.cc
deleted file mode 100644
index ec3119d..0000000
--- a/quic/core/congestion_control/pacing_sender_test.cc
+++ /dev/null
@@ -1,597 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/pacing_sender.h"
-
-#include <memory>
-#include <utility>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::AtMost;
-using testing::IsEmpty;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-const QuicByteCount kBytesInFlight = 1024;
-const int kInitialBurstPackets = 10;
-
-class TestPacingSender : public PacingSender {
- public:
-  using PacingSender::lumpy_tokens;
-  using PacingSender::PacingSender;
-
-  QuicTime ideal_next_packet_send_time() const {
-    return GetNextReleaseTime().release_time;
-  }
-};
-
-class PacingSenderTest : public QuicTest {
- protected:
-  PacingSenderTest()
-      : zero_time_(QuicTime::Delta::Zero()),
-        infinite_time_(QuicTime::Delta::Infinite()),
-        packet_number_(1),
-        mock_sender_(new StrictMock<MockSendAlgorithm>()),
-        pacing_sender_(new TestPacingSender) {
-    pacing_sender_->set_sender(mock_sender_.get());
-    // Pick arbitrary time.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(9));
-  }
-
-  ~PacingSenderTest() override {}
-
-  void InitPacingRate(QuicPacketCount burst_size, QuicBandwidth bandwidth) {
-    mock_sender_ = std::make_unique<StrictMock<MockSendAlgorithm>>();
-    pacing_sender_ = std::make_unique<TestPacingSender>();
-    pacing_sender_->set_sender(mock_sender_.get());
-    EXPECT_CALL(*mock_sender_, PacingRate(_)).WillRepeatedly(Return(bandwidth));
-    EXPECT_CALL(*mock_sender_, BandwidthEstimate())
-        .WillRepeatedly(Return(bandwidth));
-    if (burst_size == 0) {
-      EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _));
-      LostPacketVector lost_packets;
-      lost_packets.push_back(
-          LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
-      AckedPacketVector empty;
-      pacing_sender_->OnCongestionEvent(true, 1234, clock_.Now(), empty,
-                                        lost_packets);
-    } else if (burst_size != kInitialBurstPackets) {
-      QUIC_LOG(FATAL) << "Unsupported burst_size " << burst_size
-                      << " specificied, only 0 and " << kInitialBurstPackets
-                      << " are supported.";
-    }
-  }
-
-  void CheckPacketIsSentImmediately(HasRetransmittableData retransmittable_data,
-                                    QuicByteCount prior_in_flight,
-                                    bool in_recovery,
-                                    QuicPacketCount cwnd) {
-    // In order for the packet to be sendable, the underlying sender must
-    // permit it to be sent immediately.
-    for (int i = 0; i < 2; ++i) {
-      EXPECT_CALL(*mock_sender_, CanSend(prior_in_flight))
-          .WillOnce(Return(true));
-      // Verify that the packet can be sent immediately.
-      EXPECT_EQ(zero_time_,
-                pacing_sender_->TimeUntilSend(clock_.Now(), prior_in_flight));
-    }
-
-    // Actually send the packet.
-    if (prior_in_flight == 0) {
-      EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(in_recovery));
-    }
-    EXPECT_CALL(*mock_sender_,
-                OnPacketSent(clock_.Now(), prior_in_flight, packet_number_,
-                             kMaxOutgoingPacketSize, retransmittable_data));
-    EXPECT_CALL(*mock_sender_, GetCongestionWindow())
-        .WillRepeatedly(Return(cwnd * kDefaultTCPMSS));
-    EXPECT_CALL(*mock_sender_,
-                CanSend(prior_in_flight + kMaxOutgoingPacketSize))
-        .Times(AtMost(1))
-        .WillRepeatedly(Return((prior_in_flight + kMaxOutgoingPacketSize) <
-                               (cwnd * kDefaultTCPMSS)));
-    pacing_sender_->OnPacketSent(clock_.Now(), prior_in_flight,
-                                 packet_number_++, kMaxOutgoingPacketSize,
-                                 retransmittable_data);
-  }
-
-  void CheckPacketIsSentImmediately() {
-    CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight,
-                                 false, 10);
-  }
-
-  void CheckPacketIsDelayed(QuicTime::Delta delay) {
-    // In order for the packet to be sendable, the underlying sender must
-    // permit it to be sent immediately.
-    for (int i = 0; i < 2; ++i) {
-      EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight))
-          .WillOnce(Return(true));
-      // Verify that the packet is delayed.
-      EXPECT_EQ(delay.ToMicroseconds(),
-                pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight)
-                    .ToMicroseconds());
-    }
-  }
-
-  void UpdateRtt() {
-    EXPECT_CALL(*mock_sender_,
-                OnCongestionEvent(true, kBytesInFlight, _, _, _));
-    AckedPacketVector empty_acked;
-    LostPacketVector empty_lost;
-    pacing_sender_->OnCongestionEvent(true, kBytesInFlight, clock_.Now(),
-                                      empty_acked, empty_lost);
-  }
-
-  void OnApplicationLimited() { pacing_sender_->OnApplicationLimited(); }
-
-  const QuicTime::Delta zero_time_;
-  const QuicTime::Delta infinite_time_;
-  MockClock clock_;
-  QuicPacketNumber packet_number_;
-  std::unique_ptr<StrictMock<MockSendAlgorithm>> mock_sender_;
-  std::unique_ptr<TestPacingSender> pacing_sender_;
-};
-
-TEST_F(PacingSenderTest, NoSend) {
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(false));
-    EXPECT_EQ(infinite_time_,
-              pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
-  }
-}
-
-TEST_F(PacingSenderTest, SendNow) {
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(true));
-    EXPECT_EQ(zero_time_,
-              pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
-  }
-}
-
-TEST_F(PacingSenderTest, VariousSending) {
-  // Configure pacing rate of 1 packet per 1 ms, no initial burst.
-  InitPacingRate(
-      0, QuicBandwidth::FromBytesAndTimeDelta(
-             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
-  // Now update the RTT and verify that packets are actually paced.
-  UpdateRtt();
-
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-
-  // The first packet was a "make up", then we sent two packets "into the
-  // future", so the delay should be 2.
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  // Wake up on time.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  // Wake up late.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(4));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  // Wake up really late.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  // Wake up really late again, but application pause partway through.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  OnApplicationLimited();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-  // Wake up early, but after enough time has passed to permit a send.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  CheckPacketIsSentImmediately();
-}
-
-TEST_F(PacingSenderTest, InitialBurst) {
-  // Configure pacing rate of 1 packet per 1 ms.
-  InitPacingRate(
-      10, QuicBandwidth::FromBytesAndTimeDelta(
-              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
-  // Update the RTT and verify that the first 10 packets aren't paced.
-  UpdateRtt();
-
-  // Send 10 packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  // The first packet was a "make up", then we sent two packets "into the
-  // future", so the delay should be 2ms.
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  CheckPacketIsSentImmediately();
-
-  // Next time TimeUntilSend is called with no bytes in flight, pacing should
-  // allow a packet to be sent, and when it's sent, the tokens are refilled.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
-  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  // The first packet was a "make up", then we sent two packets "into the
-  // future", so the delay should be 2ms.
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) {
-  // Configure pacing rate of 1 packet per 1 ms.
-  InitPacingRate(
-      10, QuicBandwidth::FromBytesAndTimeDelta(
-              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
-  // Send 10 packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  // The first packet was a "make up", then we sent two packets "into the
-  // future", so the delay should be 2ms.
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  CheckPacketIsSentImmediately();
-
-  // Next time TimeUntilSend is called with no bytes in flight, the tokens
-  // should be refilled and there should be no delay.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
-  // Send 10 packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  // The first packet was a "make up", then we sent two packets "into the
-  // future", so the delay should be 2ms.
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, FastSending) {
-  // Ensure the pacing sender paces, even when the inter-packet spacing(0.5ms)
-  // is less than the pacing granularity(1ms).
-  InitPacingRate(10, QuicBandwidth::FromBytesAndTimeDelta(
-                         2 * kMaxOutgoingPacketSize,
-                         QuicTime::Delta::FromMilliseconds(1)));
-  // Update the RTT and verify that the first 10 packets aren't paced.
-  UpdateRtt();
-
-  // Send 10 packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  CheckPacketIsSentImmediately();  // Make up
-  CheckPacketIsSentImmediately();  // Lumpy token
-  CheckPacketIsSentImmediately();  // "In the future" but within granularity.
-  CheckPacketIsSentImmediately();  // Lumpy token
-  CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  CheckPacketIsSentImmediately();
-
-  // Next time TimeUntilSend is called with no bytes in flight, the tokens
-  // should be refilled and there should be no delay.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
-  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  // The first packet was a "make up", then we sent two packets "into the
-  // future", so the delay should be 1.5ms.
-  CheckPacketIsSentImmediately();  // Make up
-  CheckPacketIsSentImmediately();  // Lumpy token
-  CheckPacketIsSentImmediately();  // "In the future" but within granularity.
-  CheckPacketIsSentImmediately();  // Lumpy token
-  CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
-}
-
-TEST_F(PacingSenderTest, NoBurstEnteringRecovery) {
-  // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
-  InitPacingRate(
-      0, QuicBandwidth::FromBytesAndTimeDelta(
-             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-  // Sending a packet will set burst tokens.
-  CheckPacketIsSentImmediately();
-
-  // Losing a packet will set clear burst tokens.
-  LostPacketVector lost_packets;
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
-  AckedPacketVector empty_acked;
-  EXPECT_CALL(*mock_sender_,
-              OnCongestionEvent(true, kMaxOutgoingPacketSize, _, IsEmpty(), _));
-  pacing_sender_->OnCongestionEvent(true, kMaxOutgoingPacketSize, clock_.Now(),
-                                    empty_acked, lost_packets);
-  // One packet is sent immediately, because of 1ms pacing granularity.
-  CheckPacketIsSentImmediately();
-  // Ensure packets are immediately paced.
-  EXPECT_CALL(*mock_sender_, CanSend(kMaxOutgoingPacketSize))
-      .WillOnce(Return(true));
-  // Verify the next packet is paced and delayed 2ms due to granularity.
-  EXPECT_EQ(
-      QuicTime::Delta::FromMilliseconds(2),
-      pacing_sender_->TimeUntilSend(clock_.Now(), kMaxOutgoingPacketSize));
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, NoBurstInRecovery) {
-  // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
-  InitPacingRate(
-      0, QuicBandwidth::FromBytesAndTimeDelta(
-             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
-  UpdateRtt();
-
-  // Ensure only one packet is sent immediately and the rest are paced.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, true, 10);
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, CwndLimited) {
-  // Configure pacing rate of 1 packet per 1 ms, no initial burst.
-  InitPacingRate(
-      0, QuicBandwidth::FromBytesAndTimeDelta(
-             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-
-  UpdateRtt();
-
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  // Packet 3 will be delayed 2ms.
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-
-  // Wake up on time.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
-  // After sending packet 3, cwnd is limited.
-  // This test is slightly odd because bytes_in_flight is calculated using
-  // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
-  // which is 8 bytes larger, so 3 packets can be sent for a CWND of 2.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
-                               2 * kMaxOutgoingPacketSize, false, 2);
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  // Verify pacing sender stops making up for lost time after sending packet 3.
-  // Packet 6 will be delayed 2ms.
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, LumpyPacingWithInitialBurstToken) {
-  // Set lumpy size to be 3, and cwnd faction to 0.5
-  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
-  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
-  // Configure pacing rate of 1 packet per 1 ms.
-  InitPacingRate(
-      10, QuicBandwidth::FromBytesAndTimeDelta(
-              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
-  UpdateRtt();
-
-  // Send 10 packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  // Packet 14 will be delayed 3ms.
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
-
-  // Wake up on time.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  // Packet 17 will be delayed 3ms.
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
-
-  // Application throttles sending.
-  OnApplicationLimited();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  CheckPacketIsSentImmediately();
-  // Packet 20 will be delayed 3ms.
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
-
-  // Wake up on time.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
-  CheckPacketIsSentImmediately();
-  // After sending packet 21, cwnd is limited.
-  // This test is slightly odd because bytes_in_flight is calculated using
-  // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
-  // which is 8 bytes larger, so 21 packets can be sent for a CWND of 20.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
-                               20 * kMaxOutgoingPacketSize, false, 20);
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  // Suppose cwnd size is 5, so that lumpy size becomes 2.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight, false,
-                               5);
-  CheckPacketIsSentImmediately();
-  // Packet 24 will be delayed 2ms.
-  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(PacingSenderTest, NoLumpyPacingForLowBandwidthFlows) {
-  // Set lumpy size to be 3, and cwnd fraction to 0.5
-  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
-  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
-
-  // Configure pacing rate of 1 packet per 100 ms.
-  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(100);
-  InitPacingRate(kInitialBurstPackets,
-                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
-                                                      inter_packet_delay));
-  UpdateRtt();
-
-  // Send kInitialBurstPackets packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  // The first packet after burst token exhausted is also sent immediately,
-  // because ideal_next_packet_send_time has not been set yet.
-  CheckPacketIsSentImmediately();
-
-  for (int i = 0; i < 200; ++i) {
-    CheckPacketIsDelayed(inter_packet_delay);
-  }
-}
-
-// Regression test for b/184471302 to ensure that ACKs received back-to-back
-// don't cause bursts in sending.
-TEST_F(PacingSenderTest, NoBurstsForLumpyPacingWithAckAggregation) {
-  // Configure pacing rate of 1 packet per millisecond.
-  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
-  InitPacingRate(kInitialBurstPackets,
-                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
-                                                      inter_packet_delay));
-  UpdateRtt();
-
-  // Send kInitialBurstPackets packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-  // The last packet of the burst causes the sender to be CWND limited.
-  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
-                               10 * kMaxOutgoingPacketSize, false, 10);
-
-  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
-    // The last sent packet made the connection CWND limited, so no lumpy tokens
-    // should be available.
-    EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
-    CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
-                                 10 * kMaxOutgoingPacketSize, false, 10);
-    EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
-    CheckPacketIsDelayed(2 * inter_packet_delay);
-  } else {
-    EXPECT_EQ(1u, pacing_sender_->lumpy_tokens());
-    // Repeatedly send single packets to make the sender CWND limited and
-    // observe that there's no pacing without the fix.
-    for (int i = 0; i < 10; ++i) {
-      CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
-                                   10 * kMaxOutgoingPacketSize, false, 10);
-    }
-  }
-}
-
-TEST_F(PacingSenderTest, IdealNextPacketSendTimeWithLumpyPacing) {
-  // Set lumpy size to be 3, and cwnd faction to 0.5
-  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
-  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
-
-  // Configure pacing rate of 1 packet per millisecond.
-  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
-  InitPacingRate(kInitialBurstPackets,
-                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
-                                                      inter_packet_delay));
-
-  // Send kInitialBurstPackets packets, and verify that they are not paced.
-  for (int i = 0; i < kInitialBurstPackets; ++i) {
-    CheckPacketIsSentImmediately();
-  }
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + 2 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + 3 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
-
-  CheckPacketIsDelayed(3 * inter_packet_delay);
-
-  // Wake up on time.
-  clock_.AdvanceTime(3 * inter_packet_delay);
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + 2 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + 3 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
-
-  CheckPacketIsDelayed(3 * inter_packet_delay);
-
-  // Wake up late.
-  clock_.AdvanceTime(4.5 * inter_packet_delay);
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() - 0.5 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + 0.5 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
-
-  CheckPacketIsSentImmediately();
-  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
-            clock_.Now() + 1.5 * inter_packet_delay);
-  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
-
-  CheckPacketIsDelayed(1.5 * inter_packet_delay);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/prr_sender.cc b/quic/core/congestion_control/prr_sender.cc
deleted file mode 100644
index ed96953..0000000
--- a/quic/core/congestion_control/prr_sender.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/prr_sender.h"
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-PrrSender::PrrSender()
-    : bytes_sent_since_loss_(0),
-      bytes_delivered_since_loss_(0),
-      ack_count_since_loss_(0),
-      bytes_in_flight_before_loss_(0) {}
-
-void PrrSender::OnPacketSent(QuicByteCount sent_bytes) {
-  bytes_sent_since_loss_ += sent_bytes;
-}
-
-void PrrSender::OnPacketLost(QuicByteCount prior_in_flight) {
-  bytes_sent_since_loss_ = 0;
-  bytes_in_flight_before_loss_ = prior_in_flight;
-  bytes_delivered_since_loss_ = 0;
-  ack_count_since_loss_ = 0;
-}
-
-void PrrSender::OnPacketAcked(QuicByteCount acked_bytes) {
-  bytes_delivered_since_loss_ += acked_bytes;
-  ++ack_count_since_loss_;
-}
-
-bool PrrSender::CanSend(QuicByteCount congestion_window,
-                        QuicByteCount bytes_in_flight,
-                        QuicByteCount slowstart_threshold) const {
-  // Return QuicTime::Zero in order to ensure limited transmit always works.
-  if (bytes_sent_since_loss_ == 0 || bytes_in_flight < kMaxSegmentSize) {
-    return true;
-  }
-  if (congestion_window > bytes_in_flight) {
-    // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
-    // of sending the entire available window. This prevents burst retransmits
-    // when more packets are lost than the CWND reduction.
-    //   limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
-    if (bytes_delivered_since_loss_ + ack_count_since_loss_ * kMaxSegmentSize <=
-        bytes_sent_since_loss_) {
-      return false;
-    }
-    return true;
-  }
-  // Implement Proportional Rate Reduction (RFC6937).
-  // Checks a simplified version of the PRR formula that doesn't use division:
-  // AvailableSendWindow =
-  //   CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent
-  if (bytes_delivered_since_loss_ * slowstart_threshold >
-      bytes_sent_since_loss_ * bytes_in_flight_before_loss_) {
-    return true;
-  }
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/prr_sender.h b/quic/core/congestion_control/prr_sender.h
deleted file mode 100644
index a403dcf..0000000
--- a/quic/core/congestion_control/prr_sender.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implements Proportional Rate Reduction (PRR) per RFC 6937.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE PrrSender {
- public:
-  PrrSender();
-  // OnPacketLost should be called on the first loss that triggers a recovery
-  // period and all other methods in this class should only be called when in
-  // recovery.
-  void OnPacketLost(QuicByteCount prior_in_flight);
-  void OnPacketSent(QuicByteCount sent_bytes);
-  void OnPacketAcked(QuicByteCount acked_bytes);
-  bool CanSend(QuicByteCount congestion_window,
-               QuicByteCount bytes_in_flight,
-               QuicByteCount slowstart_threshold) const;
-
- private:
-  // Bytes sent and acked since the last loss event.
-  // |bytes_sent_since_loss_| is the same as "prr_out_" in RFC 6937,
-  // and |bytes_delivered_since_loss_| is the same as "prr_delivered_".
-  QuicByteCount bytes_sent_since_loss_;
-  QuicByteCount bytes_delivered_since_loss_;
-  size_t ack_count_since_loss_;
-
-  // The congestion window before the last loss event.
-  QuicByteCount bytes_in_flight_before_loss_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
diff --git a/quic/core/congestion_control/prr_sender_test.cc b/quic/core/congestion_control/prr_sender_test.cc
deleted file mode 100644
index 80e9b41..0000000
--- a/quic/core/congestion_control/prr_sender_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/prr_sender.h"
-
-#include <algorithm>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-// Constant based on TCP defaults.
-const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
-}  // namespace
-
-class PrrSenderTest : public QuicTest {};
-
-TEST_F(PrrSenderTest, SingleLossResultsInSendOnEveryOtherAck) {
-  PrrSender prr;
-  QuicPacketCount num_packets_in_flight = 50;
-  QuicByteCount bytes_in_flight = num_packets_in_flight * kMaxSegmentSize;
-  const QuicPacketCount ssthresh_after_loss = num_packets_in_flight / 2;
-  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
-
-  prr.OnPacketLost(bytes_in_flight);
-  // Ack a packet. PRR allows one packet to leave immediately.
-  prr.OnPacketAcked(kMaxSegmentSize);
-  bytes_in_flight -= kMaxSegmentSize;
-  EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
-                          ssthresh_after_loss * kMaxSegmentSize));
-  // Send retransmission.
-  prr.OnPacketSent(kMaxSegmentSize);
-  // PRR shouldn't allow sending any more packets.
-  EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
-                           ssthresh_after_loss * kMaxSegmentSize));
-
-  // One packet is lost, and one ack was consumed above. PRR now paces
-  // transmissions through the remaining 48 acks. PRR will alternatively
-  // disallow and allow a packet to be sent in response to an ack.
-  for (uint64_t i = 0; i < ssthresh_after_loss - 1; ++i) {
-    // Ack a packet. PRR shouldn't allow sending a packet in response.
-    prr.OnPacketAcked(kMaxSegmentSize);
-    bytes_in_flight -= kMaxSegmentSize;
-    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
-                             ssthresh_after_loss * kMaxSegmentSize));
-    // Ack another packet. PRR should now allow sending a packet in response.
-    prr.OnPacketAcked(kMaxSegmentSize);
-    bytes_in_flight -= kMaxSegmentSize;
-    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
-                            ssthresh_after_loss * kMaxSegmentSize));
-    // Send a packet in response.
-    prr.OnPacketSent(kMaxSegmentSize);
-    bytes_in_flight += kMaxSegmentSize;
-  }
-
-  // Since bytes_in_flight is now equal to congestion_window, PRR now maintains
-  // packet conservation, allowing one packet to be sent in response to an ack.
-  EXPECT_EQ(congestion_window, bytes_in_flight);
-  for (int i = 0; i < 10; ++i) {
-    // Ack a packet.
-    prr.OnPacketAcked(kMaxSegmentSize);
-    bytes_in_flight -= kMaxSegmentSize;
-    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
-                            ssthresh_after_loss * kMaxSegmentSize));
-    // Send a packet in response, since PRR allows it.
-    prr.OnPacketSent(kMaxSegmentSize);
-    bytes_in_flight += kMaxSegmentSize;
-
-    // Since bytes_in_flight is equal to the congestion_window,
-    // PRR disallows sending.
-    EXPECT_EQ(congestion_window, bytes_in_flight);
-    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
-                             ssthresh_after_loss * kMaxSegmentSize));
-  }
-}
-
-TEST_F(PrrSenderTest, BurstLossResultsInSlowStart) {
-  PrrSender prr;
-  QuicByteCount bytes_in_flight = 20 * kMaxSegmentSize;
-  const QuicPacketCount num_packets_lost = 13;
-  const QuicPacketCount ssthresh_after_loss = 10;
-  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
-
-  // Lose 13 packets.
-  bytes_in_flight -= num_packets_lost * kMaxSegmentSize;
-  prr.OnPacketLost(bytes_in_flight);
-
-  // PRR-SSRB will allow the following 3 acks to send up to 2 packets.
-  for (int i = 0; i < 3; ++i) {
-    prr.OnPacketAcked(kMaxSegmentSize);
-    bytes_in_flight -= kMaxSegmentSize;
-    // PRR-SSRB should allow two packets to be sent.
-    for (int j = 0; j < 2; ++j) {
-      EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
-                              ssthresh_after_loss * kMaxSegmentSize));
-      // Send a packet in response.
-      prr.OnPacketSent(kMaxSegmentSize);
-      bytes_in_flight += kMaxSegmentSize;
-    }
-    // PRR should allow no more than 2 packets in response to an ack.
-    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
-                             ssthresh_after_loss * kMaxSegmentSize));
-  }
-
-  // Out of SSRB mode, PRR allows one send in response to each ack.
-  for (int i = 0; i < 10; ++i) {
-    prr.OnPacketAcked(kMaxSegmentSize);
-    bytes_in_flight -= kMaxSegmentSize;
-    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
-                            ssthresh_after_loss * kMaxSegmentSize));
-    // Send a packet in response.
-    prr.OnPacketSent(kMaxSegmentSize);
-    bytes_in_flight += kMaxSegmentSize;
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/rtt_stats.cc b/quic/core/congestion_control/rtt_stats.cc
deleted file mode 100644
index e167dec..0000000
--- a/quic/core/congestion_control/rtt_stats.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/rtt_stats.h"
-
-#include <cstdlib>  // std::abs
-
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-const float kAlpha = 0.125f;
-const float kOneMinusAlpha = (1 - kAlpha);
-const float kBeta = 0.25f;
-const float kOneMinusBeta = (1 - kBeta);
-
-}  // namespace
-
-RttStats::RttStats()
-    : latest_rtt_(QuicTime::Delta::Zero()),
-      min_rtt_(QuicTime::Delta::Zero()),
-      smoothed_rtt_(QuicTime::Delta::Zero()),
-      previous_srtt_(QuicTime::Delta::Zero()),
-      mean_deviation_(QuicTime::Delta::Zero()),
-      calculate_standard_deviation_(false),
-      initial_rtt_(QuicTime::Delta::FromMilliseconds(kInitialRttMs)),
-      last_update_time_(QuicTime::Zero()) {}
-
-void RttStats::ExpireSmoothedMetrics() {
-  mean_deviation_ = std::max(
-      mean_deviation_, QuicTime::Delta::FromMicroseconds(std::abs(
-                           (smoothed_rtt_ - latest_rtt_).ToMicroseconds())));
-  smoothed_rtt_ = std::max(smoothed_rtt_, latest_rtt_);
-}
-
-// Updates the RTT based on a new sample.
-void RttStats::UpdateRtt(QuicTime::Delta send_delta,
-                         QuicTime::Delta ack_delay,
-                         QuicTime now) {
-  if (send_delta.IsInfinite() || send_delta <= QuicTime::Delta::Zero()) {
-    QUIC_LOG_FIRST_N(WARNING, 3)
-        << "Ignoring measured send_delta, because it's is "
-        << "either infinite, zero, or negative.  send_delta = "
-        << send_delta.ToMicroseconds();
-    return;
-  }
-
-  last_update_time_ = now;
-
-  // Update min_rtt_ first. min_rtt_ does not use an rtt_sample corrected for
-  // ack_delay but the raw observed send_delta, since poor clock granularity at
-  // the client may cause a high ack_delay to result in underestimation of the
-  // min_rtt_.
-  if (min_rtt_.IsZero() || min_rtt_ > send_delta) {
-    min_rtt_ = send_delta;
-  }
-
-  QuicTime::Delta rtt_sample(send_delta);
-  previous_srtt_ = smoothed_rtt_;
-  // Correct for ack_delay if information received from the peer results in a
-  // an RTT sample at least as large as min_rtt. Otherwise, only use the
-  // send_delta.
-  // TODO(fayang): consider to ignore rtt_sample if rtt_sample < ack_delay and
-  // ack_delay is relatively large.
-  if (rtt_sample > ack_delay) {
-    if (rtt_sample - min_rtt_ >= ack_delay) {
-      rtt_sample = rtt_sample - ack_delay;
-    } else {
-      QUIC_CODE_COUNT(quic_ack_delay_makes_rtt_sample_smaller_than_min_rtt);
-    }
-  } else {
-    QUIC_CODE_COUNT(quic_ack_delay_greater_than_rtt_sample);
-  }
-  latest_rtt_ = rtt_sample;
-  if (calculate_standard_deviation_) {
-    standard_deviation_calculator_.OnNewRttSample(rtt_sample, smoothed_rtt_);
-  }
-  // First time call.
-  if (smoothed_rtt_.IsZero()) {
-    smoothed_rtt_ = rtt_sample;
-    mean_deviation_ =
-        QuicTime::Delta::FromMicroseconds(rtt_sample.ToMicroseconds() / 2);
-  } else {
-    mean_deviation_ = QuicTime::Delta::FromMicroseconds(static_cast<int64_t>(
-        kOneMinusBeta * mean_deviation_.ToMicroseconds() +
-        kBeta * std::abs((smoothed_rtt_ - rtt_sample).ToMicroseconds())));
-    smoothed_rtt_ = kOneMinusAlpha * smoothed_rtt_ + kAlpha * rtt_sample;
-    QUIC_DVLOG(1) << " smoothed_rtt(us):" << smoothed_rtt_.ToMicroseconds()
-                  << " mean_deviation(us):" << mean_deviation_.ToMicroseconds();
-  }
-}
-
-void RttStats::OnConnectionMigration() {
-  latest_rtt_ = QuicTime::Delta::Zero();
-  min_rtt_ = QuicTime::Delta::Zero();
-  smoothed_rtt_ = QuicTime::Delta::Zero();
-  mean_deviation_ = QuicTime::Delta::Zero();
-  initial_rtt_ = QuicTime::Delta::FromMilliseconds(kInitialRttMs);
-}
-
-QuicTime::Delta RttStats::GetStandardOrMeanDeviation() const {
-  QUICHE_DCHECK(calculate_standard_deviation_);
-  if (!standard_deviation_calculator_.has_valid_standard_deviation) {
-    return mean_deviation_;
-  }
-  return standard_deviation_calculator_.CalculateStandardDeviation();
-}
-
-void RttStats::StandardDeviationCaculator::OnNewRttSample(
-    QuicTime::Delta rtt_sample,
-    QuicTime::Delta smoothed_rtt) {
-  double new_value = rtt_sample.ToMicroseconds();
-  if (smoothed_rtt.IsZero()) {
-    return;
-  }
-  has_valid_standard_deviation = true;
-  const double delta = new_value - smoothed_rtt.ToMicroseconds();
-  m2 = kOneMinusBeta * m2 + kBeta * pow(delta, 2);
-}
-
-QuicTime::Delta
-RttStats::StandardDeviationCaculator::CalculateStandardDeviation() const {
-  QUICHE_DCHECK(has_valid_standard_deviation);
-  return QuicTime::Delta::FromMicroseconds(sqrt(m2));
-}
-
-void RttStats::CloneFrom(const RttStats& stats) {
-  latest_rtt_ = stats.latest_rtt_;
-  min_rtt_ = stats.min_rtt_;
-  smoothed_rtt_ = stats.smoothed_rtt_;
-  previous_srtt_ = stats.previous_srtt_;
-  mean_deviation_ = stats.mean_deviation_;
-  standard_deviation_calculator_ = stats.standard_deviation_calculator_;
-  calculate_standard_deviation_ = stats.calculate_standard_deviation_;
-  initial_rtt_ = stats.initial_rtt_;
-  last_update_time_ = stats.last_update_time_;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/rtt_stats.h b/quic/core/congestion_control/rtt_stats.h
deleted file mode 100644
index cb591db..0000000
--- a/quic/core/congestion_control/rtt_stats.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A convenience class to store rtt samples and calculate smoothed rtt.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
-
-#include <algorithm>
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class RttStatsPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE RttStats {
- public:
-  // Calculates running standard-deviation using Welford's algorithm:
-  // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#
-  // Welford's_Online_algorithm.
-  struct QUIC_EXPORT_PRIVATE StandardDeviationCaculator {
-    StandardDeviationCaculator() {}
-
-    // Called when a new RTT sample is available.
-    void OnNewRttSample(QuicTime::Delta rtt_sample,
-                        QuicTime::Delta smoothed_rtt);
-    // Calculates the standard deviation.
-    QuicTime::Delta CalculateStandardDeviation() const;
-
-    bool has_valid_standard_deviation = false;
-
-   private:
-    double m2 = 0;
-  };
-
-  RttStats();
-  RttStats(const RttStats&) = delete;
-  RttStats& operator=(const RttStats&) = delete;
-
-  // Updates the RTT from an incoming ack which is received |send_delta| after
-  // the packet is sent and the peer reports the ack being delayed |ack_delay|.
-  void UpdateRtt(QuicTime::Delta send_delta,
-                 QuicTime::Delta ack_delay,
-                 QuicTime now);
-
-  // Causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt
-  // is larger. The mean deviation is increased to the most recent deviation if
-  // it's larger.
-  void ExpireSmoothedMetrics();
-
-  // Called when connection migrates and rtt measurement needs to be reset.
-  void OnConnectionMigration();
-
-  // Returns the EWMA smoothed RTT for the connection.
-  // May return Zero if no valid updates have occurred.
-  QuicTime::Delta smoothed_rtt() const { return smoothed_rtt_; }
-
-  // Returns the EWMA smoothed RTT prior to the most recent RTT sample.
-  QuicTime::Delta previous_srtt() const { return previous_srtt_; }
-
-  QuicTime::Delta initial_rtt() const { return initial_rtt_; }
-
-  QuicTime::Delta SmoothedOrInitialRtt() const {
-    return smoothed_rtt_.IsZero() ? initial_rtt_ : smoothed_rtt_;
-  }
-
-  QuicTime::Delta MinOrInitialRtt() const {
-    return min_rtt_.IsZero() ? initial_rtt_ : min_rtt_;
-  }
-
-  // Sets an initial RTT to be used for SmoothedRtt before any RTT updates.
-  void set_initial_rtt(QuicTime::Delta initial_rtt) {
-    if (initial_rtt.ToMicroseconds() <= 0) {
-      QUIC_BUG(quic_bug_10453_1) << "Attempt to set initial rtt to <= 0.";
-      return;
-    }
-    initial_rtt_ = initial_rtt;
-  }
-
-  // The most recent rtt measurement.
-  // May return Zero if no valid updates have occurred.
-  QuicTime::Delta latest_rtt() const { return latest_rtt_; }
-
-  // Returns the min_rtt for the entire connection.
-  // May return Zero if no valid updates have occurred.
-  QuicTime::Delta min_rtt() const { return min_rtt_; }
-
-  QuicTime::Delta mean_deviation() const { return mean_deviation_; }
-
-  // Returns standard deviation if there is a valid one. Otherwise, returns
-  // mean_deviation_.
-  QuicTime::Delta GetStandardOrMeanDeviation() const;
-
-  QuicTime last_update_time() const { return last_update_time_; }
-
-  void EnableStandardDeviationCalculation() {
-    calculate_standard_deviation_ = true;
-  }
-
-  void CloneFrom(const RttStats& stats);
-
- private:
-  friend class test::RttStatsPeer;
-
-  QuicTime::Delta latest_rtt_;
-  QuicTime::Delta min_rtt_;
-  QuicTime::Delta smoothed_rtt_;
-  QuicTime::Delta previous_srtt_;
-  // Mean RTT deviation during this session.
-  // Approximation of standard deviation, the error is roughly 1.25 times
-  // larger than the standard deviation, for a normally distributed signal.
-  QuicTime::Delta mean_deviation_;
-  // Standard deviation calculator. Only used calculate_standard_deviation_ is
-  // true.
-  StandardDeviationCaculator standard_deviation_calculator_;
-  bool calculate_standard_deviation_;
-  QuicTime::Delta initial_rtt_;
-  QuicTime last_update_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
diff --git a/quic/core/congestion_control/rtt_stats_test.cc b/quic/core/congestion_control/rtt_stats_test.cc
deleted file mode 100644
index 1df509f..0000000
--- a/quic/core/congestion_control/rtt_stats_test.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/rtt_stats.h"
-
-#include <cmath>
-
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mock_log.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/rtt_stats_peer.h"
-
-using testing::_;
-using testing::Message;
-
-namespace quic {
-namespace test {
-
-class RttStatsTest : public QuicTest {
- protected:
-  RttStats rtt_stats_;
-};
-
-TEST_F(RttStatsTest, DefaultsBeforeUpdate) {
-  EXPECT_LT(QuicTime::Delta::Zero(), rtt_stats_.initial_rtt());
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
-}
-
-TEST_F(RttStatsTest, SmoothedRtt) {
-  // Verify that ack_delay is ignored in the first measurement.
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
-                       QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
-  // Verify that a plausible ack delay increases the max ack delay.
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(400),
-                       QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
-  // Verify that Smoothed RTT includes max ack delay if it's reasonable.
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(350),
-                       QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
-  // Verify that large erroneous ack_delay does not change Smoothed RTT.
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
-                       QuicTime::Delta::FromMilliseconds(300),
-                       QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
-            rtt_stats_.smoothed_rtt());
-}
-
-// Ensure that the potential rounding artifacts in EWMA calculation do not cause
-// the SRTT to drift too far from the exact value.
-TEST_F(RttStatsTest, SmoothedRttStability) {
-  for (size_t time = 3; time < 20000; time++) {
-    RttStats stats;
-    for (size_t i = 0; i < 100; i++) {
-      stats.UpdateRtt(QuicTime::Delta::FromMicroseconds(time),
-                      QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
-      int64_t time_delta_us = stats.smoothed_rtt().ToMicroseconds() - time;
-      ASSERT_LE(std::abs(time_delta_us), 1);
-    }
-  }
-}
-
-TEST_F(RttStatsTest, PreviousSmoothedRtt) {
-  // Verify that ack_delay is corrected for in Smoothed RTT.
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
-                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.previous_srtt());
-  // Ensure the previous SRTT is 200ms after a 100ms sample.
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(187500).ToMicroseconds(),
-            rtt_stats_.smoothed_rtt().ToMicroseconds());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.previous_srtt());
-}
-
-TEST_F(RttStatsTest, MinRtt) {
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
-  rtt_stats_.UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(10), QuicTime::Delta::Zero(),
-      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
-  rtt_stats_.UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
-      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(20));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
-  rtt_stats_.UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
-      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(30));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
-  rtt_stats_.UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
-      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(40));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
-  // Verify that ack_delay does not go into recording of min_rtt_.
-  rtt_stats_.UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(7),
-      QuicTime::Delta::FromMilliseconds(2),
-      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(50));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.min_rtt());
-}
-
-TEST_F(RttStatsTest, ExpireSmoothedMetrics) {
-  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
-  rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
-  EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
-
-  EXPECT_EQ(0.5 * initial_rtt, rtt_stats_.mean_deviation());
-
-  // Update once with a 20ms RTT.
-  QuicTime::Delta doubled_rtt = 2 * initial_rtt;
-  rtt_stats_.UpdateRtt(doubled_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(1.125 * initial_rtt, rtt_stats_.smoothed_rtt());
-
-  // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
-  rtt_stats_.ExpireSmoothedMetrics();
-  EXPECT_EQ(doubled_rtt, rtt_stats_.smoothed_rtt());
-  EXPECT_EQ(0.875 * initial_rtt, rtt_stats_.mean_deviation());
-
-  // Now go back down to 5ms and expire the smoothed metrics, and ensure the
-  // mean deviation increases to 15ms.
-  QuicTime::Delta half_rtt = 0.5 * initial_rtt;
-  rtt_stats_.UpdateRtt(half_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_GT(doubled_rtt, rtt_stats_.smoothed_rtt());
-  EXPECT_LT(initial_rtt, rtt_stats_.mean_deviation());
-}
-
-TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
-  // Make sure we ignore bad RTTs.
-  CREATE_QUIC_MOCK_LOG(log);
-
-  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
-  rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
-  EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
-
-  std::vector<QuicTime::Delta> bad_send_deltas;
-  bad_send_deltas.push_back(QuicTime::Delta::Zero());
-  bad_send_deltas.push_back(QuicTime::Delta::Infinite());
-  bad_send_deltas.push_back(QuicTime::Delta::FromMicroseconds(-1000));
-  log.StartCapturingLogs();
-
-  for (QuicTime::Delta bad_send_delta : bad_send_deltas) {
-    SCOPED_TRACE(Message() << "bad_send_delta = "
-                           << bad_send_delta.ToMicroseconds());
-    if (QUIC_LOG_WARNING_IS_ON()) {
-      EXPECT_QUIC_LOG_CALL_CONTAINS(log, WARNING, "Ignoring");
-    }
-    rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
-                         QuicTime::Zero());
-    EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
-    EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
-  }
-}
-
-TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
-                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
-
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
-                       QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
-
-  // Reset rtt stats on connection migrations.
-  rtt_stats_.OnConnectionMigration();
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
-}
-
-TEST_F(RttStatsTest, StandardDeviationCaculatorTest1) {
-  // All samples are the same.
-  rtt_stats_.EnableStandardDeviationCalculation();
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(rtt_stats_.mean_deviation(),
-            rtt_stats_.GetStandardOrMeanDeviation());
-
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.GetStandardOrMeanDeviation());
-}
-
-TEST_F(RttStatsTest, StandardDeviationCaculatorTest2) {
-  // Small variance.
-  rtt_stats_.EnableStandardDeviationCalculation();
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(9),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(11),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_LT(QuicTime::Delta::FromMicroseconds(500),
-            rtt_stats_.GetStandardOrMeanDeviation());
-  EXPECT_GT(QuicTime::Delta::FromMilliseconds(1),
-            rtt_stats_.GetStandardOrMeanDeviation());
-}
-
-TEST_F(RttStatsTest, StandardDeviationCaculatorTest3) {
-  // Some variance.
-  rtt_stats_.EnableStandardDeviationCalculation();
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_APPROX_EQ(rtt_stats_.mean_deviation(),
-                   rtt_stats_.GetStandardOrMeanDeviation(), 0.25f);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/send_algorithm_interface.cc b/quic/core/congestion_control/send_algorithm_interface.cc
deleted file mode 100644
index 22f164c..0000000
--- a/quic/core/congestion_control/send_algorithm_interface.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-
-#include "absl/base/attributes.h"
-#include "quic/core/congestion_control/bbr2_sender.h"
-#include "quic/core/congestion_control/bbr_sender.h"
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class RttStats;
-
-// Factory for send side congestion control algorithm.
-SendAlgorithmInterface* SendAlgorithmInterface::Create(
-    const QuicClock* clock,
-    const RttStats* rtt_stats,
-    const QuicUnackedPacketMap* unacked_packets,
-    CongestionControlType congestion_control_type,
-    QuicRandom* random,
-    QuicConnectionStats* stats,
-    QuicPacketCount initial_congestion_window,
-    SendAlgorithmInterface* old_send_algorithm) {
-  QuicPacketCount max_congestion_window =
-      GetQuicFlag(FLAGS_quic_max_congestion_window);
-  switch (congestion_control_type) {
-    case kGoogCC:  // GoogCC is not supported by quic/core, fall back to BBR.
-    case kBBR:
-      return new BbrSender(clock->ApproximateNow(), rtt_stats, unacked_packets,
-                           initial_congestion_window, max_congestion_window,
-                           random, stats);
-    case kBBRv2:
-      return new Bbr2Sender(
-          clock->ApproximateNow(), rtt_stats, unacked_packets,
-          initial_congestion_window, max_congestion_window, random, stats,
-          old_send_algorithm &&
-                  old_send_algorithm->GetCongestionControlType() == kBBR
-              ? static_cast<BbrSender*>(old_send_algorithm)
-              : nullptr);
-    case kPCC:
-      // PCC is currently not supported, fall back to CUBIC instead.
-      ABSL_FALLTHROUGH_INTENDED;
-    case kCubicBytes:
-      return new TcpCubicSenderBytes(
-          clock, rtt_stats, false /* don't use Reno */,
-          initial_congestion_window, max_congestion_window, stats);
-    case kRenoBytes:
-      return new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
-                                     initial_congestion_window,
-                                     max_congestion_window, stats);
-  }
-  return nullptr;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/send_algorithm_interface.h b/quic/core/congestion_control/send_algorithm_interface.h
deleted file mode 100644
index e35b739..0000000
--- a/quic/core/congestion_control/send_algorithm_interface.h
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The pure virtual class for send side congestion control algorithm.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
-
-#include <algorithm>
-#include <map>
-#include <string>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-using QuicRoundTripCount = uint64_t;
-
-class CachedNetworkParameters;
-class RttStats;
-
-class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
- public:
-  // Network Params for AdjustNetworkParameters.
-  struct QUIC_NO_EXPORT NetworkParams {
-    NetworkParams() = default;
-    NetworkParams(const QuicBandwidth& bandwidth, const QuicTime::Delta& rtt,
-                  bool allow_cwnd_to_decrease)
-        : bandwidth(bandwidth),
-          rtt(rtt),
-          allow_cwnd_to_decrease(allow_cwnd_to_decrease) {}
-    explicit NetworkParams(int burst_token) : burst_token(burst_token) {}
-
-    bool operator==(const NetworkParams& other) const {
-      return bandwidth == other.bandwidth && rtt == other.rtt &&
-             max_initial_congestion_window ==
-                 other.max_initial_congestion_window &&
-             burst_token == other.burst_token &&
-             allow_cwnd_to_decrease == other.allow_cwnd_to_decrease &&
-             is_rtt_trusted == other.is_rtt_trusted;
-    }
-
-    QuicBandwidth bandwidth = QuicBandwidth::Zero();
-    QuicTime::Delta rtt = QuicTime::Delta::Zero();
-    int max_initial_congestion_window = 0;
-    int burst_token = 0;
-    bool allow_cwnd_to_decrease = false;
-    bool is_rtt_trusted = false;
-  };
-
-  static SendAlgorithmInterface* Create(
-      const QuicClock* clock,
-      const RttStats* rtt_stats,
-      const QuicUnackedPacketMap* unacked_packets,
-      CongestionControlType type,
-      QuicRandom* random,
-      QuicConnectionStats* stats,
-      QuicPacketCount initial_congestion_window,
-      SendAlgorithmInterface* old_send_algorithm);
-
-  virtual ~SendAlgorithmInterface() {}
-
-  virtual void SetFromConfig(const QuicConfig& config,
-                             Perspective perspective) = 0;
-
-  virtual void ApplyConnectionOptions(
-      const QuicTagVector& connection_options) = 0;
-
-  // Sets the initial congestion window in number of packets.  May be ignored
-  // if called after the initial congestion window is no longer relevant.
-  virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0;
-
-  // Indicates an update to the congestion state, caused either by an incoming
-  // ack or loss event timeout.  |rtt_updated| indicates whether a new
-  // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
-  // prior to the congestion event.  |acked_packets| and |lost_packets| are any
-  // packets considered acked or lost as a result of the congestion event.
-  virtual void OnCongestionEvent(bool rtt_updated,
-                                 QuicByteCount prior_in_flight,
-                                 QuicTime event_time,
-                                 const AckedPacketVector& acked_packets,
-                                 const LostPacketVector& lost_packets) = 0;
-
-  // Inform that we sent |bytes| to the wire, and if the packet is
-  // retransmittable.  |bytes_in_flight| is the number of bytes in flight before
-  // the packet was sent.
-  // Note: this function must be called for every packet sent to the wire.
-  virtual void OnPacketSent(QuicTime sent_time,
-                            QuicByteCount bytes_in_flight,
-                            QuicPacketNumber packet_number,
-                            QuicByteCount bytes,
-                            HasRetransmittableData is_retransmittable) = 0;
-
-  // Inform that |packet_number| has been neutered.
-  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
-
-  // Called when the retransmission timeout fires.  Neither OnPacketAbandoned
-  // nor OnPacketLost will be called for these packets.
-  virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
-
-  // Called when connection migrates and cwnd needs to be reset.
-  virtual void OnConnectionMigration() = 0;
-
-  // Make decision on whether the sender can send right now.  Note that even
-  // when this method returns true, the sending can be delayed due to pacing.
-  virtual bool CanSend(QuicByteCount bytes_in_flight) = 0;
-
-  // The pacing rate of the send algorithm.  May be zero if the rate is unknown.
-  virtual QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const = 0;
-
-  // What's the current estimated bandwidth in bytes per second.
-  // Returns 0 when it does not have an estimate.
-  virtual QuicBandwidth BandwidthEstimate() const = 0;
-
-  // Whether BandwidthEstimate returns a good measurement for resumption.
-  virtual bool HasGoodBandwidthEstimateForResumption() const = 0;
-
-  // Returns the size of the current congestion window in bytes.  Note, this is
-  // not the *available* window.  Some send algorithms may not use a congestion
-  // window and will return 0.
-  virtual QuicByteCount GetCongestionWindow() const = 0;
-
-  // Whether the send algorithm is currently in slow start.  When true, the
-  // BandwidthEstimate is expected to be too low.
-  virtual bool InSlowStart() const = 0;
-
-  // Whether the send algorithm is currently in recovery.
-  virtual bool InRecovery() const = 0;
-
-  // True when the congestion control is probing for more bandwidth and needs
-  // enough data to not be app-limited to do so.
-  // TODO(ianswett): In the future, this API may want to indicate the size of
-  // the probing packet.
-  virtual bool ShouldSendProbingPacket() const = 0;
-
-  // Returns the size of the slow start congestion window in bytes,
-  // aka ssthresh.  Only defined for Cubic and Reno, other algorithms return 0.
-  virtual QuicByteCount GetSlowStartThreshold() const = 0;
-
-  virtual CongestionControlType GetCongestionControlType() const = 0;
-
-  // Notifies the congestion control algorithm of an external network
-  // measurement or prediction.  Either |bandwidth| or |rtt| may be zero if no
-  // sample is available.
-  virtual void AdjustNetworkParameters(const NetworkParams& params) = 0;
-
-  // Retrieves debugging information about the current state of the
-  // send algorithm.
-  virtual std::string GetDebugState() const = 0;
-
-  // Called when the connection has no outstanding data to send. Specifically,
-  // this means that none of the data streams are write-blocked, there are no
-  // packets in the connection queue, and there are no pending retransmissins,
-  // i.e. the sender cannot send anything for reasons other than being blocked
-  // by congestion controller. This includes cases when the connection is
-  // blocked by the flow controller.
-  //
-  // The fact that this method is called does not necessarily imply that the
-  // connection would not be blocked by the congestion control if it actually
-  // tried to send data. If the congestion control algorithm needs to exclude
-  // such cases, it should use the internal state it uses for congestion control
-  // for that.
-  virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0;
-
-  // Called before connection close to collect stats.
-  virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
diff --git a/quic/core/congestion_control/send_algorithm_test.cc b/quic/core/congestion_control/send_algorithm_test.cc
deleted file mode 100644
index d4c6070..0000000
--- a/quic/core/congestion_control/send_algorithm_test.cc
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Use the initial CWND of 10, as 32 is too much for the test network.
-const uint32_t kInitialCongestionWindowPackets = 10;
-
-// Test network parameters.  Here, the topology of the network is:
-//
-//           QUIC Sender
-//               |
-//               |  <-- local link
-//               |
-//        Network switch
-//               *  <-- the bottleneck queue in the direction
-//               |          of the receiver
-//               |
-//               |  <-- test link
-//               |
-//               |
-//           Receiver
-//
-// When setting the bandwidth of the local link and test link, choose
-// a bandwidth lower than 20Mbps, as the clock-granularity of the
-// simulator can only handle a granularity of 1us.
-
-// Default settings between the switch and the sender.
-const QuicBandwidth kLocalLinkBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(10000);
-const QuicTime::Delta kLocalPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(2);
-
-// Wired network settings.  A typical desktop network setup, a
-// high-bandwidth, 30ms test link to the receiver.
-const QuicBandwidth kTestLinkWiredBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(4000);
-const QuicTime::Delta kTestLinkWiredPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(50);
-const QuicTime::Delta kTestWiredTransferTime =
-    kTestLinkWiredBandwidth.TransferTime(kMaxOutgoingPacketSize) +
-    kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
-const QuicTime::Delta kTestWiredRtt =
-    (kTestLinkWiredPropagationDelay + kLocalPropagationDelay +
-     kTestWiredTransferTime) *
-    2;
-const QuicByteCount kTestWiredBdp = kTestWiredRtt * kTestLinkWiredBandwidth;
-
-// Small BDP, Bandwidth-policed network settings.  In this scenario,
-// the receiver has a low-bandwidth, short propagation-delay link,
-// resulting in a small BDP.  We model the policer by setting the
-// queue size to only one packet.
-const QuicBandwidth kTestLinkLowBdpBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(200);
-const QuicTime::Delta kTestLinkLowBdpPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(50);
-const QuicByteCount kTestPolicerQueue = kMaxOutgoingPacketSize;
-
-// Satellite network settings.  In a satellite network, the bottleneck
-// buffer is typically sized for non-satellite links , but the
-// propagation delay of the test link to the receiver is as much as a
-// quarter second.
-const QuicTime::Delta kTestSatellitePropagationDelay =
-    QuicTime::Delta::FromMilliseconds(250);
-
-// Cellular scenarios.  In a cellular network, the bottleneck queue at
-// the edge of the network can be as great as 3MB.
-const QuicBandwidth kTestLink2GBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(100);
-const QuicBandwidth kTestLink3GBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(1500);
-const QuicByteCount kCellularQueue = 3 * 1024 * 1024;
-const QuicTime::Delta kTestCellularPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(40);
-
-// Small RTT scenario, below the per-ack-update threshold of 30ms.
-const QuicTime::Delta kTestLinkSmallRTTDelay =
-    QuicTime::Delta::FromMilliseconds(10);
-
-const char* CongestionControlTypeToString(CongestionControlType cc_type) {
-  switch (cc_type) {
-    case kCubicBytes:
-      return "CUBIC_BYTES";
-    case kRenoBytes:
-      return "RENO_BYTES";
-    case kBBR:
-      return "BBR";
-    case kPCC:
-      return "PCC";
-    default:
-      QUIC_DLOG(FATAL) << "Unexpected CongestionControlType";
-      return nullptr;
-  }
-}
-
-struct TestParams {
-  explicit TestParams(CongestionControlType congestion_control_type)
-      : congestion_control_type(congestion_control_type) {}
-
-  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
-    os << "{ congestion_control_type: "
-       << CongestionControlTypeToString(p.congestion_control_type);
-    os << " }";
-    return os;
-  }
-
-  const CongestionControlType congestion_control_type;
-};
-
-std::string TestParamToString(
-    const testing::TestParamInfo<TestParams>& params) {
-  return absl::StrCat(
-      CongestionControlTypeToString(params.param.congestion_control_type), "_");
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (const CongestionControlType congestion_control_type :
-       {kBBR, kCubicBytes, kRenoBytes, kPCC}) {
-    params.push_back(TestParams(congestion_control_type));
-  }
-  return params;
-}
-
-}  // namespace
-
-class SendAlgorithmTest : public QuicTestWithParam<TestParams> {
- protected:
-  SendAlgorithmTest()
-      : simulator_(),
-        quic_sender_(&simulator_,
-                     "QUIC sender",
-                     "Receiver",
-                     Perspective::IS_CLIENT,
-                     TestConnectionId()),
-        receiver_(&simulator_,
-                  "Receiver",
-                  "QUIC sender",
-                  Perspective::IS_SERVER,
-                  TestConnectionId()) {
-    rtt_stats_ = quic_sender_.connection()->sent_packet_manager().GetRttStats();
-    sender_ = SendAlgorithmInterface::Create(
-        simulator_.GetClock(), rtt_stats_,
-        QuicSentPacketManagerPeer::GetUnackedPacketMap(
-            QuicConnectionPeer::GetSentPacketManager(
-                quic_sender_.connection())),
-        GetParam().congestion_control_type, &random_, &stats_,
-        kInitialCongestionWindowPackets, nullptr);
-    quic_sender_.RecordTrace();
-
-    QuicConnectionPeer::SetSendAlgorithm(quic_sender_.connection(), sender_);
-    const int kTestMaxPacketSize = 1350;
-    quic_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
-    clock_ = simulator_.GetClock();
-    simulator_.set_random_generator(&random_);
-
-    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
-    random_.set_seed(seed);
-    QUIC_LOG(INFO) << "SendAlgorithmTest simulator set up.  Seed: " << seed;
-  }
-
-  // Creates a simulated network, with default settings between the
-  // sender and the switch and the given settings from the switch to
-  // the receiver.
-  void CreateSetup(const QuicBandwidth& test_bandwidth,
-                   const QuicTime::Delta& test_link_delay,
-                   QuicByteCount bottleneck_queue_length) {
-    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
-                                                  bottleneck_queue_length);
-    quic_sender_link_ = std::make_unique<simulator::SymmetricLink>(
-        &quic_sender_, switch_->port(1), kLocalLinkBandwidth,
-        kLocalPropagationDelay);
-    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
-        &receiver_, switch_->port(2), test_bandwidth, test_link_delay);
-  }
-
-  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
-    quic_sender_.AddBytesToTransfer(transfer_size);
-    bool simulator_result = simulator_.RunUntilOrTimeout(
-        [this]() { return quic_sender_.bytes_to_transfer() == 0; }, deadline);
-    EXPECT_TRUE(simulator_result)
-        << "Simple transfer failed.  Bytes remaining: "
-        << quic_sender_.bytes_to_transfer();
-  }
-
-  void SendBursts(size_t number_of_bursts,
-                  QuicByteCount bytes,
-                  QuicTime::Delta rtt,
-                  QuicTime::Delta wait_time) {
-    ASSERT_EQ(0u, quic_sender_.bytes_to_transfer());
-    for (size_t i = 0; i < number_of_bursts; i++) {
-      quic_sender_.AddBytesToTransfer(bytes);
-
-      // Transfer data and wait for three seconds between each transfer.
-      simulator_.RunFor(wait_time);
-
-      // Ensure the connection did not time out.
-      ASSERT_TRUE(quic_sender_.connection()->connected());
-      ASSERT_TRUE(receiver_.connection()->connected());
-    }
-
-    simulator_.RunFor(wait_time + rtt);
-    EXPECT_EQ(0u, quic_sender_.bytes_to_transfer());
-  }
-
-  // Estimates the elapsed time for a given transfer size, given the
-  // bottleneck bandwidth and link propagation delay.
-  QuicTime::Delta EstimatedElapsedTime(
-      QuicByteCount transfer_size_bytes,
-      QuicBandwidth test_link_bandwidth,
-      const QuicTime::Delta& test_link_delay) const {
-    return test_link_bandwidth.TransferTime(transfer_size_bytes) +
-           2 * test_link_delay;
-  }
-
-  QuicTime QuicSenderStartTime() {
-    return quic_sender_.connection()->GetStats().connection_creation_time;
-  }
-
-  void PrintTransferStats() {
-    const QuicConnectionStats& stats = quic_sender_.connection()->GetStats();
-    QUIC_LOG(INFO) << "Summary for scenario " << GetParam();
-    QUIC_LOG(INFO) << "Sender stats is " << stats;
-    const double rtx_rate =
-        static_cast<double>(stats.bytes_retransmitted) / stats.bytes_sent;
-    QUIC_LOG(INFO) << "Retransmit rate (num_rtx/num_total_sent): " << rtx_rate;
-    QUIC_LOG(INFO) << "Connection elapsed time: "
-                   << (clock_->Now() - QuicSenderStartTime()).ToMilliseconds()
-                   << " (ms)";
-  }
-
-  simulator::Simulator simulator_;
-  simulator::QuicEndpoint quic_sender_;
-  simulator::QuicEndpoint receiver_;
-  std::unique_ptr<simulator::Switch> switch_;
-  std::unique_ptr<simulator::SymmetricLink> quic_sender_link_;
-  std::unique_ptr<simulator::SymmetricLink> receiver_link_;
-  QuicConnectionStats stats_;
-
-  SimpleRandom random_;
-
-  // Owned by different components of the connection.
-  const QuicClock* clock_;
-  const RttStats* rtt_stats_;
-  SendAlgorithmInterface* sender_;
-};
-
-INSTANTIATE_TEST_SUITE_P(SendAlgorithmTests,
-                         SendAlgorithmTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         TestParamToString);
-
-// Test a simple long data transfer in the default setup.
-TEST_P(SendAlgorithmTest, SimpleWiredNetworkTransfer) {
-  CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
-              kTestWiredBdp);
-  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
-  const QuicTime::Delta maximum_elapsed_time =
-      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
-                           kTestLinkWiredPropagationDelay) *
-      1.2;
-  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
-  PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, LowBdpPolicedNetworkTransfer) {
-  CreateSetup(kTestLinkLowBdpBandwidth, kTestLinkLowBdpPropagationDelay,
-              kTestPolicerQueue);
-  const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
-  const QuicTime::Delta maximum_elapsed_time =
-      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkLowBdpBandwidth,
-                           kTestLinkLowBdpPropagationDelay) *
-      1.2;
-  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
-  PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, AppLimitedBurstsOverWiredNetwork) {
-  CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
-              kTestWiredBdp);
-  const QuicByteCount kBurstSizeBytes = 512;
-  const int kNumBursts = 20;
-  const QuicTime::Delta kWaitTime = QuicTime::Delta::FromSeconds(3);
-  SendBursts(kNumBursts, kBurstSizeBytes, kTestWiredRtt, kWaitTime);
-  PrintTransferStats();
-
-  const QuicTime::Delta estimated_burst_time =
-      EstimatedElapsedTime(kBurstSizeBytes, kTestLinkWiredBandwidth,
-                           kTestLinkWiredPropagationDelay) +
-      kWaitTime;
-  const QuicTime::Delta max_elapsed_time =
-      kNumBursts * estimated_burst_time + kWaitTime;
-  const QuicTime::Delta actual_elapsed_time =
-      clock_->Now() - QuicSenderStartTime();
-  EXPECT_GE(max_elapsed_time, actual_elapsed_time);
-}
-
-TEST_P(SendAlgorithmTest, SatelliteNetworkTransfer) {
-  CreateSetup(kTestLinkWiredBandwidth, kTestSatellitePropagationDelay,
-              kTestWiredBdp);
-  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
-  const QuicTime::Delta maximum_elapsed_time =
-      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
-                           kTestSatellitePropagationDelay) *
-      1.25;
-  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
-  PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, 2GNetworkTransfer) {
-  CreateSetup(kTestLink2GBandwidth, kTestCellularPropagationDelay,
-              kCellularQueue);
-  const QuicByteCount kTransferSizeBytes = 1024 * 1024;
-  const QuicTime::Delta maximum_elapsed_time =
-      EstimatedElapsedTime(kTransferSizeBytes, kTestLink2GBandwidth,
-                           kTestCellularPropagationDelay) *
-      1.2;
-  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
-  PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, 3GNetworkTransfer) {
-  CreateSetup(kTestLink3GBandwidth, kTestCellularPropagationDelay,
-              kCellularQueue);
-  const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
-  const QuicTime::Delta maximum_elapsed_time =
-      EstimatedElapsedTime(kTransferSizeBytes, kTestLink3GBandwidth,
-                           kTestCellularPropagationDelay) *
-      1.2;
-  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
-  PrintTransferStats();
-}
-
-TEST_P(SendAlgorithmTest, LowRTTTransfer) {
-  CreateSetup(kTestLinkWiredBandwidth, kTestLinkSmallRTTDelay, kCellularQueue);
-
-  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
-  const QuicTime::Delta maximum_elapsed_time =
-      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
-                           kTestLinkSmallRTTDelay) *
-      1.2;
-  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
-  PrintTransferStats();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
deleted file mode 100644
index 562da98..0000000
--- a/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ /dev/null
@@ -1,431 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <string>
-
-#include "quic/core/congestion_control/prr_sender.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-// Constants based on TCP defaults.
-const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f;  // Reno backoff factor.
-// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
-// fast retransmission.
-const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
-}  // namespace
-
-TcpCubicSenderBytes::TcpCubicSenderBytes(
-    const QuicClock* clock,
-    const RttStats* rtt_stats,
-    bool reno,
-    QuicPacketCount initial_tcp_congestion_window,
-    QuicPacketCount max_congestion_window,
-    QuicConnectionStats* stats)
-    : rtt_stats_(rtt_stats),
-      stats_(stats),
-      reno_(reno),
-      num_connections_(kDefaultNumConnections),
-      min4_mode_(false),
-      last_cutback_exited_slowstart_(false),
-      slow_start_large_reduction_(false),
-      no_prr_(false),
-      cubic_(clock),
-      num_acked_packets_(0),
-      congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
-      min_congestion_window_(kDefaultMinimumCongestionWindow),
-      max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
-      slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
-      initial_tcp_congestion_window_(initial_tcp_congestion_window *
-                                     kDefaultTCPMSS),
-      initial_max_tcp_congestion_window_(max_congestion_window *
-                                         kDefaultTCPMSS),
-      min_slow_start_exit_window_(min_congestion_window_) {}
-
-TcpCubicSenderBytes::~TcpCubicSenderBytes() {}
-
-void TcpCubicSenderBytes::SetFromConfig(const QuicConfig& config,
-                                        Perspective perspective) {
-  if (perspective == Perspective::IS_SERVER) {
-    if (!GetQuicReloadableFlag(quic_unified_iw_options)) {
-      if (config.HasReceivedConnectionOptions() &&
-          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
-        // Initial window experiment.
-        SetInitialCongestionWindowInPackets(3);
-      }
-      if (config.HasReceivedConnectionOptions() &&
-          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
-        // Initial window experiment.
-        SetInitialCongestionWindowInPackets(10);
-      }
-      if (config.HasReceivedConnectionOptions() &&
-          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
-        // Initial window experiment.
-        SetInitialCongestionWindowInPackets(20);
-      }
-      if (config.HasReceivedConnectionOptions() &&
-          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
-        // Initial window experiment.
-        SetInitialCongestionWindowInPackets(50);
-      }
-      if (config.HasReceivedConnectionOptions() &&
-          ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
-        // Min CWND experiment.
-        SetMinCongestionWindowInPackets(1);
-      }
-    }
-    if (config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
-      // Min CWND of 4 experiment.
-      min4_mode_ = true;
-      SetMinCongestionWindowInPackets(1);
-    }
-    if (config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
-      // Slow Start Fast Exit experiment.
-      slow_start_large_reduction_ = true;
-    }
-    if (config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) {
-      // Use unity pacing instead of PRR.
-      no_prr_ = true;
-    }
-  }
-}
-
-void TcpCubicSenderBytes::AdjustNetworkParameters(const NetworkParams& params) {
-  if (params.bandwidth.IsZero() || params.rtt.IsZero()) {
-    return;
-  }
-  SetCongestionWindowFromBandwidthAndRtt(params.bandwidth, params.rtt);
-}
-
-float TcpCubicSenderBytes::RenoBeta() const {
-  // kNConnectionBeta is the backoff factor after loss for our N-connection
-  // emulation, which emulates the effective backoff of an ensemble of N
-  // TCP-Reno connections on a single loss event. The effective multiplier is
-  // computed as:
-  return (num_connections_ - 1 + kRenoBeta) / num_connections_;
-}
-
-void TcpCubicSenderBytes::OnCongestionEvent(
-    bool rtt_updated,
-    QuicByteCount prior_in_flight,
-    QuicTime event_time,
-    const AckedPacketVector& acked_packets,
-    const LostPacketVector& lost_packets) {
-  if (rtt_updated && InSlowStart() &&
-      hybrid_slow_start_.ShouldExitSlowStart(
-          rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
-          GetCongestionWindow() / kDefaultTCPMSS)) {
-    ExitSlowstart();
-  }
-  for (const LostPacket& lost_packet : lost_packets) {
-    OnPacketLost(lost_packet.packet_number, lost_packet.bytes_lost,
-                 prior_in_flight);
-  }
-  for (const AckedPacket& acked_packet : acked_packets) {
-    OnPacketAcked(acked_packet.packet_number, acked_packet.bytes_acked,
-                  prior_in_flight, event_time);
-  }
-}
-
-void TcpCubicSenderBytes::OnPacketAcked(QuicPacketNumber acked_packet_number,
-                                        QuicByteCount acked_bytes,
-                                        QuicByteCount prior_in_flight,
-                                        QuicTime event_time) {
-  largest_acked_packet_number_.UpdateMax(acked_packet_number);
-  if (InRecovery()) {
-    if (!no_prr_) {
-      // PRR is used when in recovery.
-      prr_.OnPacketAcked(acked_bytes);
-    }
-    return;
-  }
-  MaybeIncreaseCwnd(acked_packet_number, acked_bytes, prior_in_flight,
-                    event_time);
-  if (InSlowStart()) {
-    hybrid_slow_start_.OnPacketAcked(acked_packet_number);
-  }
-}
-
-void TcpCubicSenderBytes::OnPacketSent(
-    QuicTime /*sent_time*/,
-    QuicByteCount /*bytes_in_flight*/,
-    QuicPacketNumber packet_number,
-    QuicByteCount bytes,
-    HasRetransmittableData is_retransmittable) {
-  if (InSlowStart()) {
-    ++(stats_->slowstart_packets_sent);
-  }
-
-  if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
-    return;
-  }
-  if (InRecovery()) {
-    // PRR is used when in recovery.
-    prr_.OnPacketSent(bytes);
-  }
-  QUICHE_DCHECK(!largest_sent_packet_number_.IsInitialized() ||
-                largest_sent_packet_number_ < packet_number);
-  largest_sent_packet_number_ = packet_number;
-  hybrid_slow_start_.OnPacketSent(packet_number);
-}
-
-bool TcpCubicSenderBytes::CanSend(QuicByteCount bytes_in_flight) {
-  if (!no_prr_ && InRecovery()) {
-    // PRR is used when in recovery.
-    return prr_.CanSend(GetCongestionWindow(), bytes_in_flight,
-                        GetSlowStartThreshold());
-  }
-  if (GetCongestionWindow() > bytes_in_flight) {
-    return true;
-  }
-  if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
-    return true;
-  }
-  return false;
-}
-
-QuicBandwidth TcpCubicSenderBytes::PacingRate(
-    QuicByteCount /* bytes_in_flight */) const {
-  // We pace at twice the rate of the underlying sender's bandwidth estimate
-  // during slow start and 1.25x during congestion avoidance to ensure pacing
-  // doesn't prevent us from filling the window.
-  QuicTime::Delta srtt = rtt_stats_->SmoothedOrInitialRtt();
-  const QuicBandwidth bandwidth =
-      QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
-  return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
-}
-
-QuicBandwidth TcpCubicSenderBytes::BandwidthEstimate() const {
-  QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
-  if (srtt.IsZero()) {
-    // If we haven't measured an rtt, the bandwidth estimate is unknown.
-    return QuicBandwidth::Zero();
-  }
-  return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
-}
-
-bool TcpCubicSenderBytes::InSlowStart() const {
-  return GetCongestionWindow() < GetSlowStartThreshold();
-}
-
-bool TcpCubicSenderBytes::IsCwndLimited(QuicByteCount bytes_in_flight) const {
-  const QuicByteCount congestion_window = GetCongestionWindow();
-  if (bytes_in_flight >= congestion_window) {
-    return true;
-  }
-  const QuicByteCount available_bytes = congestion_window - bytes_in_flight;
-  const bool slow_start_limited =
-      InSlowStart() && bytes_in_flight > congestion_window / 2;
-  return slow_start_limited || available_bytes <= kMaxBurstBytes;
-}
-
-bool TcpCubicSenderBytes::InRecovery() const {
-  return largest_acked_packet_number_.IsInitialized() &&
-         largest_sent_at_last_cutback_.IsInitialized() &&
-         largest_acked_packet_number_ <= largest_sent_at_last_cutback_;
-}
-
-bool TcpCubicSenderBytes::ShouldSendProbingPacket() const {
-  return false;
-}
-
-void TcpCubicSenderBytes::OnRetransmissionTimeout(bool packets_retransmitted) {
-  largest_sent_at_last_cutback_.Clear();
-  if (!packets_retransmitted) {
-    return;
-  }
-  hybrid_slow_start_.Restart();
-  HandleRetransmissionTimeout();
-}
-
-std::string TcpCubicSenderBytes::GetDebugState() const {
-  return "";
-}
-
-void TcpCubicSenderBytes::OnApplicationLimited(
-    QuicByteCount /*bytes_in_flight*/) {}
-
-void TcpCubicSenderBytes::SetCongestionWindowFromBandwidthAndRtt(
-    QuicBandwidth bandwidth,
-    QuicTime::Delta rtt) {
-  QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt);
-  // Limit new CWND if needed.
-  congestion_window_ =
-      std::max(min_congestion_window_,
-               std::min(new_congestion_window,
-                        kMaxResumptionCongestionWindow * kDefaultTCPMSS));
-}
-
-void TcpCubicSenderBytes::SetInitialCongestionWindowInPackets(
-    QuicPacketCount congestion_window) {
-  congestion_window_ = congestion_window * kDefaultTCPMSS;
-}
-
-void TcpCubicSenderBytes::SetMinCongestionWindowInPackets(
-    QuicPacketCount congestion_window) {
-  min_congestion_window_ = congestion_window * kDefaultTCPMSS;
-}
-
-void TcpCubicSenderBytes::SetNumEmulatedConnections(int num_connections) {
-  num_connections_ = std::max(1, num_connections);
-  cubic_.SetNumConnections(num_connections_);
-}
-
-void TcpCubicSenderBytes::ExitSlowstart() {
-  slowstart_threshold_ = congestion_window_;
-}
-
-void TcpCubicSenderBytes::OnPacketLost(QuicPacketNumber packet_number,
-                                       QuicByteCount lost_bytes,
-                                       QuicByteCount prior_in_flight) {
-  // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
-  // already sent should be treated as a single loss event, since it's expected.
-  if (largest_sent_at_last_cutback_.IsInitialized() &&
-      packet_number <= largest_sent_at_last_cutback_) {
-    if (last_cutback_exited_slowstart_) {
-      ++stats_->slowstart_packets_lost;
-      stats_->slowstart_bytes_lost += lost_bytes;
-      if (slow_start_large_reduction_) {
-        // Reduce congestion window by lost_bytes for every loss.
-        congestion_window_ = std::max(congestion_window_ - lost_bytes,
-                                      min_slow_start_exit_window_);
-        slowstart_threshold_ = congestion_window_;
-      }
-    }
-    QUIC_DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
-                  << " because it was sent prior to the last CWND cutback.";
-    return;
-  }
-  ++stats_->tcp_loss_events;
-  last_cutback_exited_slowstart_ = InSlowStart();
-  if (InSlowStart()) {
-    ++stats_->slowstart_packets_lost;
-  }
-
-  if (!no_prr_) {
-    prr_.OnPacketLost(prior_in_flight);
-  }
-
-  // TODO(b/77268641): Separate out all of slow start into a separate class.
-  if (slow_start_large_reduction_ && InSlowStart()) {
-    QUICHE_DCHECK_LT(kDefaultTCPMSS, congestion_window_);
-    if (congestion_window_ >= 2 * initial_tcp_congestion_window_) {
-      min_slow_start_exit_window_ = congestion_window_ / 2;
-    }
-    congestion_window_ = congestion_window_ - kDefaultTCPMSS;
-  } else if (reno_) {
-    congestion_window_ = congestion_window_ * RenoBeta();
-  } else {
-    congestion_window_ =
-        cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
-  }
-  if (congestion_window_ < min_congestion_window_) {
-    congestion_window_ = min_congestion_window_;
-  }
-  slowstart_threshold_ = congestion_window_;
-  largest_sent_at_last_cutback_ = largest_sent_packet_number_;
-  // Reset packet count from congestion avoidance mode. We start counting again
-  // when we're out of recovery.
-  num_acked_packets_ = 0;
-  QUIC_DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_
-                << " slowstart threshold: " << slowstart_threshold_;
-}
-
-QuicByteCount TcpCubicSenderBytes::GetCongestionWindow() const {
-  return congestion_window_;
-}
-
-QuicByteCount TcpCubicSenderBytes::GetSlowStartThreshold() const {
-  return slowstart_threshold_;
-}
-
-// Called when we receive an ack. Normal TCP tracks how many packets one ack
-// represents, but quic has a separate ack for each packet.
-void TcpCubicSenderBytes::MaybeIncreaseCwnd(
-    QuicPacketNumber /*acked_packet_number*/,
-    QuicByteCount acked_bytes,
-    QuicByteCount prior_in_flight,
-    QuicTime event_time) {
-  QUIC_BUG_IF(quic_bug_10439_1, InRecovery())
-      << "Never increase the CWND during recovery.";
-  // Do not increase the congestion window unless the sender is close to using
-  // the current window.
-  if (!IsCwndLimited(prior_in_flight)) {
-    cubic_.OnApplicationLimited();
-    return;
-  }
-  if (congestion_window_ >= max_congestion_window_) {
-    return;
-  }
-  if (InSlowStart()) {
-    // TCP slow start, exponential growth, increase by one for each ACK.
-    congestion_window_ += kDefaultTCPMSS;
-    QUIC_DVLOG(1) << "Slow start; congestion window: " << congestion_window_
-                  << " slowstart threshold: " << slowstart_threshold_;
-    return;
-  }
-  // Congestion avoidance.
-  if (reno_) {
-    // Classic Reno congestion avoidance.
-    ++num_acked_packets_;
-    // Divide by num_connections to smoothly increase the CWND at a faster rate
-    // than conventional Reno.
-    if (num_acked_packets_ * num_connections_ >=
-        congestion_window_ / kDefaultTCPMSS) {
-      congestion_window_ += kDefaultTCPMSS;
-      num_acked_packets_ = 0;
-    }
-
-    QUIC_DVLOG(1) << "Reno; congestion window: " << congestion_window_
-                  << " slowstart threshold: " << slowstart_threshold_
-                  << " congestion window count: " << num_acked_packets_;
-  } else {
-    congestion_window_ = std::min(
-        max_congestion_window_,
-        cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
-                                        rtt_stats_->min_rtt(), event_time));
-    QUIC_DVLOG(1) << "Cubic; congestion window: " << congestion_window_
-                  << " slowstart threshold: " << slowstart_threshold_;
-  }
-}
-
-void TcpCubicSenderBytes::HandleRetransmissionTimeout() {
-  cubic_.ResetCubicState();
-  slowstart_threshold_ = congestion_window_ / 2;
-  congestion_window_ = min_congestion_window_;
-}
-
-void TcpCubicSenderBytes::OnConnectionMigration() {
-  hybrid_slow_start_.Restart();
-  prr_ = PrrSender();
-  largest_sent_packet_number_.Clear();
-  largest_acked_packet_number_.Clear();
-  largest_sent_at_last_cutback_.Clear();
-  last_cutback_exited_slowstart_ = false;
-  cubic_.ResetCubicState();
-  num_acked_packets_ = 0;
-  congestion_window_ = initial_tcp_congestion_window_;
-  max_congestion_window_ = initial_max_tcp_congestion_window_;
-  slowstart_threshold_ = initial_max_tcp_congestion_window_;
-}
-
-CongestionControlType TcpCubicSenderBytes::GetCongestionControlType() const {
-  return reno_ ? kRenoBytes : kCubicBytes;
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
deleted file mode 100644
index 8f52a6a..0000000
--- a/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
-
-#include <cstdint>
-#include <string>
-
-#include "quic/core/congestion_control/cubic_bytes.h"
-#include "quic/core/congestion_control/hybrid_slow_start.h"
-#include "quic/core/congestion_control/prr_sender.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class RttStats;
-
-// Maximum window to allow when doing bandwidth resumption.
-const QuicPacketCount kMaxResumptionCongestionWindow = 200;
-
-namespace test {
-class TcpCubicSenderBytesPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
- public:
-  TcpCubicSenderBytes(const QuicClock* clock,
-                      const RttStats* rtt_stats,
-                      bool reno,
-                      QuicPacketCount initial_tcp_congestion_window,
-                      QuicPacketCount max_congestion_window,
-                      QuicConnectionStats* stats);
-  TcpCubicSenderBytes(const TcpCubicSenderBytes&) = delete;
-  TcpCubicSenderBytes& operator=(const TcpCubicSenderBytes&) = delete;
-  ~TcpCubicSenderBytes() override;
-
-  // Start implementation of SendAlgorithmInterface.
-  void SetFromConfig(const QuicConfig& config,
-                     Perspective perspective) override;
-  void ApplyConnectionOptions(
-      const QuicTagVector& /*connection_options*/) override {}
-  void AdjustNetworkParameters(const NetworkParams& params) override;
-  void SetNumEmulatedConnections(int num_connections);
-  void SetInitialCongestionWindowInPackets(
-      QuicPacketCount congestion_window) override;
-  void OnConnectionMigration() override;
-  void OnCongestionEvent(bool rtt_updated,
-                         QuicByteCount prior_in_flight,
-                         QuicTime event_time,
-                         const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets) override;
-  void OnPacketSent(QuicTime sent_time,
-                    QuicByteCount bytes_in_flight,
-                    QuicPacketNumber packet_number,
-                    QuicByteCount bytes,
-                    HasRetransmittableData is_retransmittable) override;
-  void OnPacketNeutered(QuicPacketNumber /*packet_number*/) override {}
-  void OnRetransmissionTimeout(bool packets_retransmitted) override;
-  bool CanSend(QuicByteCount bytes_in_flight) override;
-  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
-  QuicBandwidth BandwidthEstimate() const override;
-  bool HasGoodBandwidthEstimateForResumption() const override { return false; }
-  QuicByteCount GetCongestionWindow() const override;
-  QuicByteCount GetSlowStartThreshold() const override;
-  CongestionControlType GetCongestionControlType() const override;
-  bool InSlowStart() const override;
-  bool InRecovery() const override;
-  bool ShouldSendProbingPacket() const override;
-  std::string GetDebugState() const override;
-  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
-  void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
-  // End implementation of SendAlgorithmInterface.
-
-  QuicByteCount min_congestion_window() const { return min_congestion_window_; }
-
- protected:
-  // Compute the TCP Reno beta based on the current number of connections.
-  float RenoBeta() const;
-
-  bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
-
-  // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
-  void OnPacketAcked(QuicPacketNumber acked_packet_number,
-                     QuicByteCount acked_bytes,
-                     QuicByteCount prior_in_flight,
-                     QuicTime event_time);
-  void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
-                                              QuicTime::Delta rtt);
-  void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
-  void ExitSlowstart();
-  void OnPacketLost(QuicPacketNumber packet_number, QuicByteCount lost_bytes,
-                    QuicByteCount prior_in_flight);
-  void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
-                         QuicByteCount acked_bytes,
-                         QuicByteCount prior_in_flight,
-                         QuicTime event_time);
-  void HandleRetransmissionTimeout();
-
- private:
-  friend class test::TcpCubicSenderBytesPeer;
-
-  HybridSlowStart hybrid_slow_start_;
-  PrrSender prr_;
-  const RttStats* rtt_stats_;
-  QuicConnectionStats* stats_;
-
-  // If true, Reno congestion control is used instead of Cubic.
-  const bool reno_;
-
-  // Number of connections to simulate.
-  uint32_t num_connections_;
-
-  // Track the largest packet that has been sent.
-  QuicPacketNumber largest_sent_packet_number_;
-
-  // Track the largest packet that has been acked.
-  QuicPacketNumber largest_acked_packet_number_;
-
-  // Track the largest packet number outstanding when a CWND cutback occurs.
-  QuicPacketNumber largest_sent_at_last_cutback_;
-
-  // Whether to use 4 packets as the actual min, but pace lower.
-  bool min4_mode_;
-
-  // Whether the last loss event caused us to exit slowstart.
-  // Used for stats collection of slowstart_packets_lost
-  bool last_cutback_exited_slowstart_;
-
-  // When true, exit slow start with large cutback of congestion window.
-  bool slow_start_large_reduction_;
-
-  // When true, use unity pacing instead of PRR.
-  bool no_prr_;
-
-  CubicBytes cubic_;
-
-  // ACK counter for the Reno implementation.
-  uint64_t num_acked_packets_;
-
-  // Congestion window in bytes.
-  QuicByteCount congestion_window_;
-
-  // Minimum congestion window in bytes.
-  QuicByteCount min_congestion_window_;
-
-  // Maximum congestion window in bytes.
-  QuicByteCount max_congestion_window_;
-
-  // Slow start congestion window in bytes, aka ssthresh.
-  QuicByteCount slowstart_threshold_;
-
-  // Initial TCP congestion window in bytes. This variable can only be set when
-  // this algorithm is created.
-  const QuicByteCount initial_tcp_congestion_window_;
-
-  // Initial maximum TCP congestion window in bytes. This variable can only be
-  // set when this algorithm is created.
-  const QuicByteCount initial_max_tcp_congestion_window_;
-
-  // The minimum window when exiting slow start with large reduction.
-  QuicByteCount min_slow_start_exit_window_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
deleted file mode 100644
index 6ef746d..0000000
--- a/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ /dev/null
@@ -1,845 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/tcp_cubic_sender_bytes.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_config_peer.h"
-
-namespace quic {
-namespace test {
-
-// TODO(ianswett): A number of theses tests were written with the assumption of
-// an initial CWND of 10. They have carefully calculated values which should be
-// updated to be based on kInitialCongestionWindow.
-const uint32_t kInitialCongestionWindowPackets = 10;
-const uint32_t kMaxCongestionWindowPackets = 200;
-const uint32_t kDefaultWindowTCP =
-    kInitialCongestionWindowPackets * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f;  // Reno backoff factor.
-
-class TcpCubicSenderBytesPeer : public TcpCubicSenderBytes {
- public:
-  TcpCubicSenderBytesPeer(const QuicClock* clock, bool reno)
-      : TcpCubicSenderBytes(clock,
-                            &rtt_stats_,
-                            reno,
-                            kInitialCongestionWindowPackets,
-                            kMaxCongestionWindowPackets,
-                            &stats_) {}
-
-  const HybridSlowStart& hybrid_slow_start() const {
-    return hybrid_slow_start_;
-  }
-
-  float GetRenoBeta() const { return RenoBeta(); }
-
-  RttStats rtt_stats_;
-  QuicConnectionStats stats_;
-};
-
-class TcpCubicSenderBytesTest : public QuicTest {
- protected:
-  TcpCubicSenderBytesTest()
-      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
-        sender_(new TcpCubicSenderBytesPeer(&clock_, true)),
-        packet_number_(1),
-        acked_packet_number_(0),
-        bytes_in_flight_(0) {}
-
-  int SendAvailableSendWindow() {
-    return SendAvailableSendWindow(kDefaultTCPMSS);
-  }
-
-  int SendAvailableSendWindow(QuicPacketLength /*packet_length*/) {
-    // Send as long as TimeUntilSend returns Zero.
-    int packets_sent = 0;
-    bool can_send = sender_->CanSend(bytes_in_flight_);
-    while (can_send) {
-      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
-                            QuicPacketNumber(packet_number_++), kDefaultTCPMSS,
-                            HAS_RETRANSMITTABLE_DATA);
-      ++packets_sent;
-      bytes_in_flight_ += kDefaultTCPMSS;
-      can_send = sender_->CanSend(bytes_in_flight_);
-    }
-    return packets_sent;
-  }
-
-  // Normal is that TCP acks every other segment.
-  void AckNPackets(int n) {
-    sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
-                                  QuicTime::Delta::Zero(), clock_.Now());
-    AckedPacketVector acked_packets;
-    LostPacketVector lost_packets;
-    for (int i = 0; i < n; ++i) {
-      ++acked_packet_number_;
-      acked_packets.push_back(
-          AckedPacket(QuicPacketNumber(acked_packet_number_), kDefaultTCPMSS,
-                      QuicTime::Zero()));
-    }
-    sender_->OnCongestionEvent(true, bytes_in_flight_, clock_.Now(),
-                               acked_packets, lost_packets);
-    bytes_in_flight_ -= n * kDefaultTCPMSS;
-    clock_.AdvanceTime(one_ms_);
-  }
-
-  void LoseNPackets(int n) { LoseNPackets(n, kDefaultTCPMSS); }
-
-  void LoseNPackets(int n, QuicPacketLength packet_length) {
-    AckedPacketVector acked_packets;
-    LostPacketVector lost_packets;
-    for (int i = 0; i < n; ++i) {
-      ++acked_packet_number_;
-      lost_packets.push_back(
-          LostPacket(QuicPacketNumber(acked_packet_number_), packet_length));
-    }
-    sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
-                               acked_packets, lost_packets);
-    bytes_in_flight_ -= n * packet_length;
-  }
-
-  // Does not increment acked_packet_number_.
-  void LosePacket(uint64_t packet_number) {
-    AckedPacketVector acked_packets;
-    LostPacketVector lost_packets;
-    lost_packets.push_back(
-        LostPacket(QuicPacketNumber(packet_number), kDefaultTCPMSS));
-    sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
-                               acked_packets, lost_packets);
-    bytes_in_flight_ -= kDefaultTCPMSS;
-  }
-
-  const QuicTime::Delta one_ms_;
-  MockClock clock_;
-  std::unique_ptr<TcpCubicSenderBytesPeer> sender_;
-  uint64_t packet_number_;
-  uint64_t acked_packet_number_;
-  QuicByteCount bytes_in_flight_;
-};
-
-TEST_F(TcpCubicSenderBytesTest, SimpleSender) {
-  // At startup make sure we are at the default.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  // And that window is un-affected.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
-  // Fill the send window with data, then verify that we can't send.
-  SendAvailableSendWindow();
-  EXPECT_FALSE(sender_->CanSend(sender_->GetCongestionWindow()));
-}
-
-TEST_F(TcpCubicSenderBytesTest, ApplicationLimitedSlowStart) {
-  // Send exactly 10 packets and ensure the CWND ends at 14 packets.
-  const int kNumberOfAcks = 5;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-
-  SendAvailableSendWindow();
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    AckNPackets(2);
-  }
-  QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
-  // It's expected 2 acks will arrive when the bytes_in_flight are greater than
-  // half the CWND.
-  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
-}
-
-TEST_F(TcpCubicSenderBytesTest, ExponentialSlowStart) {
-  const int kNumberOfAcks = 20;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-  EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->CanSend(0));
-
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  const QuicByteCount cwnd = sender_->GetCongestionWindow();
-  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
-  EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
-                cwnd, sender_->rtt_stats_.smoothed_rtt()),
-            sender_->BandwidthEstimate());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLoss) {
-  sender_->SetNumEmulatedConnections(1);
-  const int kNumberOfAcks = 10;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose a packet to exit slow start.
-  LoseNPackets(1);
-  size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
-  // We should now have fallen out of slow start with a reduced window.
-  expected_send_window *= kRenoBeta;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Recovery phase. We need to ack every packet in the recovery window before
-  // we exit recovery.
-  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
-  QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
-  AckNPackets(packets_in_recovery_window);
-  SendAvailableSendWindow();
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // We need to ack an entire window before we increase CWND by 1.
-  AckNPackets(number_of_packets_in_window - 2);
-  SendAvailableSendWindow();
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Next ack should increase cwnd by 1.
-  AckNPackets(1);
-  expected_send_window += kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Now RTO and ensure slow start gets reset.
-  EXPECT_TRUE(sender_->hybrid_slow_start().started());
-  sender_->OnRetransmissionTimeout(true);
-  EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithLargeReduction) {
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kSSLR);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
-  sender_->SetNumEmulatedConnections(1);
-  const int kNumberOfAcks = (kDefaultWindowTCP / (2 * kDefaultTCPMSS)) - 1;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose a packet to exit slow start. We should now have fallen out of
-  // slow start with a window reduced by 1.
-  LoseNPackets(1);
-  expected_send_window -= kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose 5 packets in recovery and verify that congestion window is reduced
-  // further.
-  LoseNPackets(5);
-  expected_send_window -= 5 * kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  // Lose another 10 packets and ensure it reduces below half the peak CWND,
-  // because we never acked the full IW.
-  LoseNPackets(10);
-  expected_send_window -= 10 * kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
-
-  // Recovery phase. We need to ack every packet in the recovery window before
-  // we exit recovery.
-  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
-  QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
-  AckNPackets(packets_in_recovery_window);
-  SendAvailableSendWindow();
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // We need to ack an entire window before we increase CWND by 1.
-  AckNPackets(number_of_packets_in_window - 1);
-  SendAvailableSendWindow();
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Next ack should increase cwnd by 1.
-  AckNPackets(1);
-  expected_send_window += kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Now RTO and ensure slow start gets reset.
-  EXPECT_TRUE(sender_->hybrid_slow_start().started());
-  sender_->OnRetransmissionTimeout(true);
-  EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartHalfPacketLossWithLargeReduction) {
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kSSLR);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
-  sender_->SetNumEmulatedConnections(1);
-  const int kNumberOfAcks = 10;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window in half sized packets.
-    SendAvailableSendWindow(kDefaultTCPMSS / 2);
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow(kDefaultTCPMSS / 2);
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose a packet to exit slow start. We should now have fallen out of
-  // slow start with a window reduced by 1.
-  LoseNPackets(1);
-  expected_send_window -= kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose 10 packets in recovery and verify that congestion window is reduced
-  // by 5 packets.
-  LoseNPackets(10, kDefaultTCPMSS / 2);
-  expected_send_window -= 5 * kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithMaxHalfReduction) {
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kSSLR);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, Perspective::IS_SERVER);
-
-  sender_->SetNumEmulatedConnections(1);
-  const int kNumberOfAcks = kInitialCongestionWindowPackets / 2;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose a packet to exit slow start. We should now have fallen out of
-  // slow start with a window reduced by 1.
-  LoseNPackets(1);
-  expected_send_window -= kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose half the outstanding packets in recovery and verify the congestion
-  // window is only reduced by a max of half.
-  LoseNPackets(kNumberOfAcks * 2);
-  expected_send_window -= (kNumberOfAcks * 2 - 1) * kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  LoseNPackets(5);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, NoPRRWhenLessThanOnePacketInFlight) {
-  SendAvailableSendWindow();
-  LoseNPackets(kInitialCongestionWindowPackets - 1);
-  AckNPackets(1);
-  // PRR will allow 2 packets for every ack during recovery.
-  EXPECT_EQ(2, SendAvailableSendWindow());
-  // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
-  // PRR should now allow a packet to be sent, even though prr's state variables
-  // believe it has sent enough packets.
-  EXPECT_TRUE(sender_->CanSend(0));
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossPRR) {
-  sender_->SetNumEmulatedConnections(1);
-  // Test based on the first example in RFC6937.
-  // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
-  const int kNumberOfAcks = 5;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  LoseNPackets(1);
-
-  // We should now have fallen out of slow start with a reduced window.
-  size_t send_window_before_loss = expected_send_window;
-  expected_send_window *= kRenoBeta;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Testing TCP proportional rate reduction.
-  // We should send packets paced over the received acks for the remaining
-  // outstanding packets. The number of packets before we exit recovery is the
-  // original CWND minus the packet that has been lost and the one which
-  // triggered the loss.
-  size_t remaining_packets_in_recovery =
-      send_window_before_loss / kDefaultTCPMSS - 2;
-
-  for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
-    AckNPackets(1);
-    SendAvailableSendWindow();
-    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  }
-
-  // We need to ack another window before we increase CWND by 1.
-  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
-  for (size_t i = 0; i < number_of_packets_in_window; ++i) {
-    AckNPackets(1);
-    EXPECT_EQ(1, SendAvailableSendWindow());
-    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  }
-
-  AckNPackets(1);
-  expected_send_window += kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SlowStartBurstPacketLossPRR) {
-  sender_->SetNumEmulatedConnections(1);
-  // Test based on the second example in RFC6937, though we also implement
-  // forward acknowledgements, so the first two incoming acks will trigger
-  // PRR immediately.
-  // Ack 20 packets in 10 acks to raise the CWND to 30.
-  const int kNumberOfAcks = 10;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Lose one more than the congestion window reduction, so that after loss,
-  // bytes_in_flight is lesser than the congestion window.
-  size_t send_window_after_loss = kRenoBeta * expected_send_window;
-  size_t num_packets_to_lose =
-      (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
-  LoseNPackets(num_packets_to_lose);
-  // Immediately after the loss, ensure at least one packet can be sent.
-  // Losses without subsequent acks can occur with timer based loss detection.
-  EXPECT_TRUE(sender_->CanSend(bytes_in_flight_));
-  AckNPackets(1);
-
-  // We should now have fallen out of slow start with a reduced window.
-  expected_send_window *= kRenoBeta;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Only 2 packets should be allowed to be sent, per PRR-SSRB.
-  EXPECT_EQ(2, SendAvailableSendWindow());
-
-  // Ack the next packet, which triggers another loss.
-  LoseNPackets(1);
-  AckNPackets(1);
-
-  // Send 2 packets to simulate PRR-SSRB.
-  EXPECT_EQ(2, SendAvailableSendWindow());
-
-  // Ack the next packet, which triggers another loss.
-  LoseNPackets(1);
-  AckNPackets(1);
-
-  // Send 2 packets to simulate PRR-SSRB.
-  EXPECT_EQ(2, SendAvailableSendWindow());
-
-  // Exit recovery and return to sending at the new rate.
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    AckNPackets(1);
-    EXPECT_EQ(1, SendAvailableSendWindow());
-  }
-}
-
-TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindow) {
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  // Expect the window to decrease to the minimum once the RTO fires and slow
-  // start threshold to be set to 1/2 of the CWND.
-  sender_->OnRetransmissionTimeout(true);
-  EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
-  EXPECT_EQ(5u * kDefaultTCPMSS, sender_->GetSlowStartThreshold());
-}
-
-TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindowNoRetransmission) {
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
-  // Expect the window to remain unchanged if the RTO fires but no packets are
-  // retransmitted.
-  sender_->OnRetransmissionTimeout(false);
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, TcpCubicResetEpochOnQuiescence) {
-  const int kMaxCongestionWindow = 50;
-  const QuicByteCount kMaxCongestionWindowBytes =
-      kMaxCongestionWindow * kDefaultTCPMSS;
-  int num_sent = SendAvailableSendWindow();
-
-  // Make sure we fall out of slow start.
-  QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
-  LoseNPackets(1);
-  EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
-  // Ack the rest of the outstanding packets to get out of recovery.
-  for (int i = 1; i < num_sent; ++i) {
-    AckNPackets(1);
-  }
-  EXPECT_EQ(0u, bytes_in_flight_);
-
-  // Send a new window of data and ack all; cubic growth should occur.
-  saved_cwnd = sender_->GetCongestionWindow();
-  num_sent = SendAvailableSendWindow();
-  for (int i = 0; i < num_sent; ++i) {
-    AckNPackets(1);
-  }
-  EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
-  EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
-  EXPECT_EQ(0u, bytes_in_flight_);
-
-  // Quiescent time of 100 seconds
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
-
-  // Send new window of data and ack one packet. Cubic epoch should have
-  // been reset; ensure cwnd increase is not dramatic.
-  saved_cwnd = sender_->GetCongestionWindow();
-  SendAvailableSendWindow();
-  AckNPackets(1);
-  EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
-  EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, MultipleLossesInOneWindow) {
-  SendAvailableSendWindow();
-  const QuicByteCount initial_window = sender_->GetCongestionWindow();
-  LosePacket(acked_packet_number_ + 1);
-  const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
-  EXPECT_GT(initial_window, post_loss_window);
-  LosePacket(acked_packet_number_ + 3);
-  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
-  LosePacket(packet_number_ - 1);
-  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
-
-  // Lose a later packet and ensure the window decreases.
-  LosePacket(packet_number_);
-  EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, ConfigureMaxInitialWindow) {
-  SetQuicReloadableFlag(quic_unified_iw_options, false);
-  QuicConfig config;
-
-  // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
-  QuicTagVector options;
-  options.push_back(kIW10);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, Perspective::IS_SERVER);
-  EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, SetInitialCongestionWindow) {
-  EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-  sender_->SetInitialCongestionWindowInPackets(3);
-  EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
-  sender_->SetNumEmulatedConnections(2);
-  // Ack 10 packets in 5 acks to raise the CWND to 20.
-  const int kNumberOfAcks = 5;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  LoseNPackets(1);
-
-  // We should now have fallen out of slow start with a reduced window.
-  expected_send_window = expected_send_window * sender_->GetRenoBeta();
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // No congestion window growth should occur in recovery phase, i.e., until the
-  // currently outstanding 20 packets are acked.
-  for (int i = 0; i < 10; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    EXPECT_TRUE(sender_->InRecovery());
-    AckNPackets(2);
-    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  }
-  EXPECT_FALSE(sender_->InRecovery());
-
-  // Out of recovery now. Congestion window should not grow for half an RTT.
-  size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
-  SendAvailableSendWindow();
-  AckNPackets(packets_in_send_window / 2 - 2);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Next ack should increase congestion window by 1MSS.
-  SendAvailableSendWindow();
-  AckNPackets(2);
-  expected_send_window += kDefaultTCPMSS;
-  packets_in_send_window += 1;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Congestion window should remain steady again for half an RTT.
-  SendAvailableSendWindow();
-  AckNPackets(packets_in_send_window / 2 - 1);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Next ack should cause congestion window to grow by 1MSS.
-  SendAvailableSendWindow();
-  AckNPackets(2);
-  expected_send_window += kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
-  sender_->SetNumEmulatedConnections(1);
-  // Ack 10 packets in 5 acks to raise the CWND to 20.
-  const int kNumberOfAcks = 5;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  LoseNPackets(1);
-
-  // We should now have fallen out of slow start with a reduced window.
-  expected_send_window *= kRenoBeta;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // No congestion window growth should occur in recovery phase, i.e., until the
-  // currently outstanding 20 packets are acked.
-  for (int i = 0; i < 10; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    EXPECT_TRUE(sender_->InRecovery());
-    AckNPackets(2);
-    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  }
-  EXPECT_FALSE(sender_->InRecovery());
-
-  // Out of recovery now. Congestion window should not grow during RTT.
-  for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  }
-
-  // Next ack should cause congestion window to grow by 1MSS.
-  SendAvailableSendWindow();
-  AckNPackets(2);
-  expected_send_window += kDefaultTCPMSS;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, BandwidthResumption) {
-  // Test that when provided with CachedNetworkParameters and opted in to the
-  // bandwidth resumption experiment, that the TcpCubicSenderPackets sets
-  // initial CWND appropriately.
-
-  // Set some common values.
-  const QuicPacketCount kNumberOfPackets = 123;
-  const QuicBandwidth kBandwidthEstimate =
-      QuicBandwidth::FromBytesPerSecond(kNumberOfPackets * kDefaultTCPMSS);
-  const QuicTime::Delta kRttEstimate = QuicTime::Delta::FromSeconds(1);
-
-  SendAlgorithmInterface::NetworkParams network_param;
-  network_param.bandwidth = kBandwidthEstimate;
-  network_param.rtt = kRttEstimate;
-  sender_->AdjustNetworkParameters(network_param);
-  EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
-
-  // Resume with an illegal value of 0 and verify the server ignores it.
-  SendAlgorithmInterface::NetworkParams network_param_no_bandwidth;
-  network_param_no_bandwidth.bandwidth = QuicBandwidth::Zero();
-  network_param_no_bandwidth.rtt = kRttEstimate;
-  sender_->AdjustNetworkParameters(network_param_no_bandwidth);
-  EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
-
-  // Resumed CWND is limited to be in a sensible range.
-  const QuicBandwidth kUnreasonableBandwidth =
-      QuicBandwidth::FromBytesPerSecond((kMaxResumptionCongestionWindow + 1) *
-                                        kDefaultTCPMSS);
-  SendAlgorithmInterface::NetworkParams network_param_large_bandwidth;
-  network_param_large_bandwidth.bandwidth = kUnreasonableBandwidth;
-  network_param_large_bandwidth.rtt = QuicTime::Delta::FromSeconds(1);
-  sender_->AdjustNetworkParameters(network_param_large_bandwidth);
-  EXPECT_EQ(kMaxResumptionCongestionWindow * kDefaultTCPMSS,
-            sender_->GetCongestionWindow());
-}
-
-TEST_F(TcpCubicSenderBytesTest, PaceBelowCWND) {
-  QuicConfig config;
-
-  // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
-  // to 4 to be sent.
-  QuicTagVector options;
-  options.push_back(kMIN4);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, Perspective::IS_SERVER);
-  sender_->OnRetransmissionTimeout(true);
-  EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
-  EXPECT_TRUE(sender_->CanSend(kDefaultTCPMSS));
-  EXPECT_TRUE(sender_->CanSend(2 * kDefaultTCPMSS));
-  EXPECT_TRUE(sender_->CanSend(3 * kDefaultTCPMSS));
-  EXPECT_FALSE(sender_->CanSend(4 * kDefaultTCPMSS));
-}
-
-TEST_F(TcpCubicSenderBytesTest, NoPRR) {
-  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
-  sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  sender_->SetNumEmulatedConnections(1);
-  // Verify that kCOPT: kNPRR allows all packets to be sent, even if only one
-  // ack has been received.
-  QuicTagVector options;
-  options.push_back(kNPRR);
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, Perspective::IS_SERVER);
-  SendAvailableSendWindow();
-  LoseNPackets(9);
-  AckNPackets(1);
-
-  // We should now have fallen out of slow start with a reduced window.
-  EXPECT_EQ(kRenoBeta * kDefaultWindowTCP, sender_->GetCongestionWindow());
-  const QuicPacketCount window_in_packets =
-      kRenoBeta * kDefaultWindowTCP / kDefaultTCPMSS;
-  const QuicBandwidth expected_pacing_rate =
-      QuicBandwidth::FromBytesAndTimeDelta(kRenoBeta * kDefaultWindowTCP,
-                                           sender_->rtt_stats_.smoothed_rtt());
-  EXPECT_EQ(expected_pacing_rate, sender_->PacingRate(0));
-  EXPECT_EQ(window_in_packets,
-            static_cast<uint64_t>(SendAvailableSendWindow()));
-  EXPECT_EQ(expected_pacing_rate,
-            sender_->PacingRate(kRenoBeta * kDefaultWindowTCP));
-}
-
-TEST_F(TcpCubicSenderBytesTest, ResetAfterConnectionMigration) {
-  // Starts from slow start.
-  sender_->SetNumEmulatedConnections(1);
-  const int kNumberOfAcks = 10;
-  for (int i = 0; i < kNumberOfAcks; ++i) {
-    // Send our full send window.
-    SendAvailableSendWindow();
-    AckNPackets(2);
-  }
-  SendAvailableSendWindow();
-  QuicByteCount expected_send_window =
-      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-
-  // Loses a packet to exit slow start.
-  LoseNPackets(1);
-
-  // We should now have fallen out of slow start with a reduced window. Slow
-  // start threshold is also updated.
-  expected_send_window *= kRenoBeta;
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  EXPECT_EQ(expected_send_window, sender_->GetSlowStartThreshold());
-
-  // Resets cwnd and slow start threshold on connection migrations.
-  sender_->OnConnectionMigration();
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS,
-            sender_->GetSlowStartThreshold());
-  EXPECT_FALSE(sender_->hybrid_slow_start().started());
-}
-
-TEST_F(TcpCubicSenderBytesTest, DefaultMaxCwnd) {
-  RttStats rtt_stats;
-  QuicConnectionStats stats;
-  std::unique_ptr<SendAlgorithmInterface> sender(SendAlgorithmInterface::Create(
-      &clock_, &rtt_stats, /*unacked_packets=*/nullptr, kCubicBytes,
-      QuicRandom::GetInstance(), &stats, kInitialCongestionWindow, nullptr));
-
-  AckedPacketVector acked_packets;
-  LostPacketVector missing_packets;
-  QuicPacketCount max_congestion_window =
-      GetQuicFlag(FLAGS_quic_max_congestion_window);
-  for (uint64_t i = 1; i < max_congestion_window; ++i) {
-    acked_packets.clear();
-    acked_packets.push_back(
-        AckedPacket(QuicPacketNumber(i), 1350, QuicTime::Zero()));
-    sender->OnCongestionEvent(true, sender->GetCongestionWindow(), clock_.Now(),
-                              acked_packets, missing_packets);
-  }
-  EXPECT_EQ(max_congestion_window,
-            sender->GetCongestionWindow() / kDefaultTCPMSS);
-}
-
-TEST_F(TcpCubicSenderBytesTest, LimitCwndIncreaseInCongestionAvoidance) {
-  // Enable Cubic.
-  sender_ = std::make_unique<TcpCubicSenderBytesPeer>(&clock_, false);
-
-  int num_sent = SendAvailableSendWindow();
-
-  // Make sure we fall out of slow start.
-  QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
-  LoseNPackets(1);
-  EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
-
-  // Ack the rest of the outstanding packets to get out of recovery.
-  for (int i = 1; i < num_sent; ++i) {
-    AckNPackets(1);
-  }
-  EXPECT_EQ(0u, bytes_in_flight_);
-  // Send a new window of data and ack all; cubic growth should occur.
-  saved_cwnd = sender_->GetCongestionWindow();
-  num_sent = SendAvailableSendWindow();
-
-  // Ack packets until the CWND increases.
-  while (sender_->GetCongestionWindow() == saved_cwnd) {
-    AckNPackets(1);
-    SendAvailableSendWindow();
-  }
-  // Bytes in flight may be larger than the CWND if the CWND isn't an exact
-  // multiple of the packet sizes being sent.
-  EXPECT_GE(bytes_in_flight_, sender_->GetCongestionWindow());
-  saved_cwnd = sender_->GetCongestionWindow();
-
-  // Advance time 2 seconds waiting for an ack.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2000));
-
-  // Ack two packets.  The CWND should increase by only one packet.
-  AckNPackets(2);
-  EXPECT_EQ(saved_cwnd + kDefaultTCPMSS, sender_->GetCongestionWindow());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/uber_loss_algorithm.cc b/quic/core/congestion_control/uber_loss_algorithm.cc
deleted file mode 100644
index 2bf8d86..0000000
--- a/quic/core/congestion_control/uber_loss_algorithm.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/uber_loss_algorithm.h"
-
-#include <algorithm>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-UberLossAlgorithm::UberLossAlgorithm() {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].Initialize(static_cast<PacketNumberSpace>(i),
-                                           this);
-  }
-}
-
-void UberLossAlgorithm::SetFromConfig(const QuicConfig& config,
-                                      Perspective perspective) {
-  if (config.HasClientRequestedIndependentOption(kELDT, perspective) &&
-      tuner_ != nullptr) {
-    tuning_configured_ = true;
-    MaybeStartTuning();
-  }
-}
-
-LossDetectionInterface::DetectionStats UberLossAlgorithm::DetectLosses(
-    const QuicUnackedPacketMap& unacked_packets,
-    QuicTime time,
-    const RttStats& rtt_stats,
-    QuicPacketNumber /*largest_newly_acked*/,
-    const AckedPacketVector& packets_acked,
-    LostPacketVector* packets_lost) {
-  DetectionStats overall_stats;
-
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    const QuicPacketNumber largest_acked =
-        unacked_packets.GetLargestAckedOfPacketNumberSpace(
-            static_cast<PacketNumberSpace>(i));
-    if (!largest_acked.IsInitialized() ||
-        unacked_packets.GetLeastUnacked() > largest_acked) {
-      // Skip detecting losses if no packet has been received for this packet
-      // number space or the least_unacked is greater than largest_acked.
-      continue;
-    }
-
-    DetectionStats stats = general_loss_algorithms_[i].DetectLosses(
-        unacked_packets, time, rtt_stats, largest_acked, packets_acked,
-        packets_lost);
-
-    overall_stats.sent_packets_max_sequence_reordering =
-        std::max(overall_stats.sent_packets_max_sequence_reordering,
-                 stats.sent_packets_max_sequence_reordering);
-    overall_stats.sent_packets_num_borderline_time_reorderings +=
-        stats.sent_packets_num_borderline_time_reorderings;
-    overall_stats.total_loss_detection_response_time +=
-        stats.total_loss_detection_response_time;
-  }
-
-  return overall_stats;
-}
-
-QuicTime UberLossAlgorithm::GetLossTimeout() const {
-  QuicTime loss_timeout = QuicTime::Zero();
-  // Returns the earliest non-zero loss timeout.
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    const QuicTime timeout = general_loss_algorithms_[i].GetLossTimeout();
-    if (!loss_timeout.IsInitialized()) {
-      loss_timeout = timeout;
-      continue;
-    }
-    if (timeout.IsInitialized()) {
-      loss_timeout = std::min(loss_timeout, timeout);
-    }
-  }
-  return loss_timeout;
-}
-
-void UberLossAlgorithm::SpuriousLossDetected(
-    const QuicUnackedPacketMap& unacked_packets,
-    const RttStats& rtt_stats,
-    QuicTime ack_receive_time,
-    QuicPacketNumber packet_number,
-    QuicPacketNumber previous_largest_acked) {
-  general_loss_algorithms_[unacked_packets.GetPacketNumberSpace(packet_number)]
-      .SpuriousLossDetected(unacked_packets, rtt_stats, ack_receive_time,
-                            packet_number, previous_largest_acked);
-}
-
-void UberLossAlgorithm::SetLossDetectionTuner(
-    std::unique_ptr<LossDetectionTunerInterface> tuner) {
-  if (tuner_ != nullptr) {
-    QUIC_BUG(quic_bug_10469_1)
-        << "LossDetectionTuner can only be set once when session begins.";
-    return;
-  }
-  tuner_ = std::move(tuner);
-}
-
-void UberLossAlgorithm::MaybeStartTuning() {
-  if (tuner_started_ || !tuning_configured_ || !min_rtt_available_ ||
-      !user_agent_known_ || !reorder_happened_) {
-    return;
-  }
-
-  tuner_started_ = tuner_->Start(&tuned_parameters_);
-  if (!tuner_started_) {
-    return;
-  }
-
-  if (tuned_parameters_.reordering_shift.has_value() &&
-      tuned_parameters_.reordering_threshold.has_value()) {
-    QUIC_DLOG(INFO) << "Setting reordering shift to "
-                    << *tuned_parameters_.reordering_shift
-                    << ", and reordering threshold to "
-                    << *tuned_parameters_.reordering_threshold;
-    SetReorderingShift(*tuned_parameters_.reordering_shift);
-    SetReorderingThreshold(*tuned_parameters_.reordering_threshold);
-  } else {
-    QUIC_BUG(quic_bug_10469_2)
-        << "Tuner started but some parameters are missing";
-  }
-}
-
-void UberLossAlgorithm::OnConfigNegotiated() {}
-
-void UberLossAlgorithm::OnMinRttAvailable() {
-  min_rtt_available_ = true;
-  MaybeStartTuning();
-}
-
-void UberLossAlgorithm::OnUserAgentIdKnown() {
-  user_agent_known_ = true;
-  MaybeStartTuning();
-}
-
-void UberLossAlgorithm::OnConnectionClosed() {
-  if (tuner_ != nullptr && tuner_started_) {
-    tuner_->Finish(tuned_parameters_);
-  }
-}
-
-void UberLossAlgorithm::OnReorderingDetected() {
-  const bool tuner_started_before = tuner_started_;
-  const bool reorder_happened_before = reorder_happened_;
-
-  reorder_happened_ = true;
-  MaybeStartTuning();
-
-  if (!tuner_started_before && tuner_started_) {
-    if (reorder_happened_before) {
-      QUIC_CODE_COUNT(quic_loss_tuner_started_after_first_reorder);
-    } else {
-      QUIC_CODE_COUNT(quic_loss_tuner_started_on_first_reorder);
-    }
-  }
-}
-
-void UberLossAlgorithm::SetReorderingShift(int reordering_shift) {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].set_reordering_shift(reordering_shift);
-  }
-}
-
-void UberLossAlgorithm::SetReorderingThreshold(
-    QuicPacketCount reordering_threshold) {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].set_reordering_threshold(reordering_threshold);
-  }
-}
-
-void UberLossAlgorithm::EnableAdaptiveReorderingThreshold() {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(true);
-  }
-}
-
-void UberLossAlgorithm::DisableAdaptiveReorderingThreshold() {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(false);
-  }
-}
-
-void UberLossAlgorithm::EnableAdaptiveTimeThreshold() {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].enable_adaptive_time_threshold();
-  }
-}
-
-QuicPacketCount UberLossAlgorithm::GetPacketReorderingThreshold() const {
-  return general_loss_algorithms_[APPLICATION_DATA].reordering_threshold();
-}
-
-int UberLossAlgorithm::GetPacketReorderingShift() const {
-  return general_loss_algorithms_[APPLICATION_DATA].reordering_shift();
-}
-
-void UberLossAlgorithm::DisablePacketThresholdForRuntPackets() {
-  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    general_loss_algorithms_[i].disable_packet_threshold_for_runt_packets();
-  }
-}
-
-void UberLossAlgorithm::ResetLossDetection(PacketNumberSpace space) {
-  if (space >= NUM_PACKET_NUMBER_SPACES) {
-    QUIC_BUG(quic_bug_10469_3) << "Invalid packet number space: " << space;
-    return;
-  }
-  general_loss_algorithms_[space].Reset();
-}
-
-}  // namespace quic
diff --git a/quic/core/congestion_control/uber_loss_algorithm.h b/quic/core/congestion_control/uber_loss_algorithm.h
deleted file mode 100644
index 58cb53e..0000000
--- a/quic/core/congestion_control/uber_loss_algorithm.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
-
-#include "absl/types/optional.h"
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicSentPacketManagerPeer;
-
-}  // namespace test
-
-struct QUIC_EXPORT_PRIVATE LossDetectionParameters {
-  // See GeneralLossAlgorithm for the meaning of reordering_(shift|threshold).
-  absl::optional<int> reordering_shift;
-  absl::optional<QuicPacketCount> reordering_threshold;
-};
-
-class QUIC_EXPORT_PRIVATE LossDetectionTunerInterface {
- public:
-  virtual ~LossDetectionTunerInterface() {}
-
-  // Start the tuning by choosing parameters and saving them into |*params|.
-  // Called near the start of a QUIC session, see the .cc file for exactly
-  // where.
-  virtual bool Start(LossDetectionParameters* params) = 0;
-
-  // Finish tuning. The tuner is expected to use the actual loss detection
-  // performance(for its definition of performance) to improve the parameter
-  // selection for future QUIC sessions.
-  // Called when a QUIC session closes.
-  virtual void Finish(const LossDetectionParameters& params) = 0;
-};
-
-// This class comprises multiple loss algorithms, each per packet number space.
-class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
- public:
-  UberLossAlgorithm();
-  UberLossAlgorithm(const UberLossAlgorithm&) = delete;
-  UberLossAlgorithm& operator=(const UberLossAlgorithm&) = delete;
-  ~UberLossAlgorithm() override {}
-
-  void SetFromConfig(const QuicConfig& config,
-                     Perspective perspective) override;
-
-  // Detects lost packets.
-  DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
-                              QuicTime time,
-                              const RttStats& rtt_stats,
-                              QuicPacketNumber largest_newly_acked,
-                              const AckedPacketVector& packets_acked,
-                              LostPacketVector* packets_lost) override;
-
-  // Returns the earliest time the early retransmit timer should be active.
-  QuicTime GetLossTimeout() const override;
-
-  // Called to increases time or packet threshold.
-  void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
-                            const RttStats& rtt_stats,
-                            QuicTime ack_receive_time,
-                            QuicPacketNumber packet_number,
-                            QuicPacketNumber previous_largest_acked) override;
-
-  void SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface> tuner);
-  void OnConfigNegotiated() override;
-  void OnMinRttAvailable() override;
-  void OnUserAgentIdKnown() override;
-  void OnConnectionClosed() override;
-  void OnReorderingDetected() override;
-
-  // Sets reordering_shift for all packet number spaces.
-  void SetReorderingShift(int reordering_shift);
-
-  // Sets reordering_threshold for all packet number spaces.
-  void SetReorderingThreshold(QuicPacketCount reordering_threshold);
-
-  // Enable adaptive reordering threshold of all packet number spaces.
-  void EnableAdaptiveReorderingThreshold();
-
-  // Disable adaptive reordering threshold of all packet number spaces.
-  void DisableAdaptiveReorderingThreshold();
-
-  // Enable adaptive time threshold of all packet number spaces.
-  void EnableAdaptiveTimeThreshold();
-
-  // Get the packet reordering threshold from the APPLICATION_DATA PN space.
-  // Always 3 when adaptive reordering is not enabled.
-  QuicPacketCount GetPacketReorderingThreshold() const;
-
-  // Get the packet reordering shift from the APPLICATION_DATA PN space.
-  int GetPacketReorderingShift() const;
-
-  // Disable packet threshold loss detection for *runt* packets.
-  void DisablePacketThresholdForRuntPackets();
-
-  // Called to reset loss detection of |space|.
-  void ResetLossDetection(PacketNumberSpace space);
-
-  bool use_adaptive_reordering_threshold() const {
-    return general_loss_algorithms_[APPLICATION_DATA]
-        .use_adaptive_reordering_threshold();
-  }
-
-  bool use_adaptive_time_threshold() const {
-    return general_loss_algorithms_[APPLICATION_DATA]
-        .use_adaptive_time_threshold();
-  }
-
- private:
-  friend class test::QuicSentPacketManagerPeer;
-
-  void MaybeStartTuning();
-
-  // One loss algorithm per packet number space.
-  GeneralLossAlgorithm general_loss_algorithms_[NUM_PACKET_NUMBER_SPACES];
-
-  // Used to tune reordering_shift and reordering_threshold.
-  std::unique_ptr<LossDetectionTunerInterface> tuner_;
-  LossDetectionParameters tuned_parameters_;
-  bool tuner_started_ = false;
-  bool min_rtt_available_ = false;
-  // Whether user agent is known to the session.
-  bool user_agent_known_ = false;
-  // Whether tuning is configured in QuicConfig.
-  bool tuning_configured_ = false;
-  bool reorder_happened_ = false;  // Whether any reordered packet is observed.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
diff --git a/quic/core/congestion_control/uber_loss_algorithm_test.cc b/quic/core/congestion_control/uber_loss_algorithm_test.cc
deleted file mode 100644
index a24b444..0000000
--- a/quic/core/congestion_control/uber_loss_algorithm_test.cc
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/uber_loss_algorithm.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/types/optional.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-class UberLossAlgorithmTest : public QuicTest {
- protected:
-  UberLossAlgorithmTest() {
-    unacked_packets_ =
-        std::make_unique<QuicUnackedPacketMap>(Perspective::IS_CLIENT);
-    rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                         QuicTime::Delta::Zero(), clock_.Now());
-    EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
-  }
-
-  void SendPacket(uint64_t packet_number, EncryptionLevel encryption_level) {
-    QuicStreamFrame frame;
-    QuicTransportVersion version =
-        CurrentSupportedVersions()[0].transport_version;
-    frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-        version, Perspective::IS_CLIENT);
-    if (encryption_level == ENCRYPTION_INITIAL) {
-      if (QuicVersionUsesCryptoFrames(version)) {
-        frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-            version, Perspective::IS_CLIENT);
-      } else {
-        frame.stream_id = QuicUtils::GetCryptoStreamId(version);
-      }
-    }
-    SerializedPacket packet(QuicPacketNumber(packet_number),
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
-    packet.encryption_level = encryption_level;
-    packet.retransmittable_frames.push_back(QuicFrame(frame));
-    unacked_packets_->AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
-                                    true, true);
-  }
-
-  void AckPackets(const std::vector<uint64_t>& packets_acked) {
-    packets_acked_.clear();
-    for (uint64_t acked : packets_acked) {
-      unacked_packets_->RemoveFromInFlight(QuicPacketNumber(acked));
-      packets_acked_.push_back(AckedPacket(
-          QuicPacketNumber(acked), kMaxOutgoingPacketSize, QuicTime::Zero()));
-    }
-  }
-
-  void VerifyLosses(uint64_t largest_newly_acked,
-                    const AckedPacketVector& packets_acked,
-                    const std::vector<uint64_t>& losses_expected) {
-    return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
-                        absl::nullopt);
-  }
-
-  void VerifyLosses(
-      uint64_t largest_newly_acked,
-      const AckedPacketVector& packets_acked,
-      const std::vector<uint64_t>& losses_expected,
-      absl::optional<QuicPacketCount> max_sequence_reordering_expected) {
-    LostPacketVector lost_packets;
-    LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
-        *unacked_packets_, clock_.Now(), rtt_stats_,
-        QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
-    if (max_sequence_reordering_expected.has_value()) {
-      EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
-                max_sequence_reordering_expected.value());
-    }
-    ASSERT_EQ(losses_expected.size(), lost_packets.size());
-    for (size_t i = 0; i < losses_expected.size(); ++i) {
-      EXPECT_EQ(lost_packets[i].packet_number,
-                QuicPacketNumber(losses_expected[i]));
-    }
-  }
-
-  MockClock clock_;
-  std::unique_ptr<QuicUnackedPacketMap> unacked_packets_;
-  RttStats rtt_stats_;
-  UberLossAlgorithm loss_algorithm_;
-  AckedPacketVector packets_acked_;
-};
-
-TEST_F(UberLossAlgorithmTest, ScenarioA) {
-  // This test mimics a scenario: client sends 1-CHLO, 2-0RTT, 3-0RTT,
-  // timeout and retransmits 4-CHLO. Server acks packet 1 (ack gets lost).
-  // Server receives and buffers packets 2 and 3. Server receives packet 4 and
-  // processes handshake asynchronously, so server acks 4 and cannot process
-  // packets 2 and 3.
-  SendPacket(1, ENCRYPTION_INITIAL);
-  SendPacket(2, ENCRYPTION_ZERO_RTT);
-  SendPacket(3, ENCRYPTION_ZERO_RTT);
-  unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
-  SendPacket(4, ENCRYPTION_INITIAL);
-
-  AckPackets({1, 4});
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      HANDSHAKE_DATA, QuicPacketNumber(4));
-  // Verify no packet is detected lost.
-  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 0);
-  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
-}
-
-TEST_F(UberLossAlgorithmTest, ScenarioB) {
-  // This test mimics a scenario: client sends 3-0RTT, 4-0RTT, receives SHLO,
-  // sends 5-1RTT, 6-1RTT.
-  SendPacket(3, ENCRYPTION_ZERO_RTT);
-  SendPacket(4, ENCRYPTION_ZERO_RTT);
-  SendPacket(5, ENCRYPTION_FORWARD_SECURE);
-  SendPacket(6, ENCRYPTION_FORWARD_SECURE);
-
-  AckPackets({4});
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(4));
-  // No packet loss by acking 4.
-  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 1);
-  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-
-  // Acking 6 causes 3 to be detected loss.
-  AckPackets({6});
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(6));
-  VerifyLosses(6, packets_acked_, std::vector<uint64_t>{3}, 3);
-  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-  packets_acked_.clear();
-
-  clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
-  // Verify 5 will be early retransmitted.
-  VerifyLosses(6, packets_acked_, {5}, 1);
-}
-
-TEST_F(UberLossAlgorithmTest, ScenarioC) {
-  // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT, 4-1RTT
-  // and retransmit 4-SHLO. Client receives and buffers packet 4. Client
-  // receives packet 5 and processes 4.
-  QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
-                                           Perspective::IS_SERVER);
-  SendPacket(1, ENCRYPTION_ZERO_RTT);
-  SendPacket(2, ENCRYPTION_FORWARD_SECURE);
-  SendPacket(3, ENCRYPTION_FORWARD_SECURE);
-  SendPacket(4, ENCRYPTION_FORWARD_SECURE);
-  unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
-  SendPacket(5, ENCRYPTION_ZERO_RTT);
-
-  AckPackets({4, 5});
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(4));
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      HANDSHAKE_DATA, QuicPacketNumber(5));
-  // No packet loss by acking 5.
-  VerifyLosses(5, packets_acked_, std::vector<uint64_t>{}, 2);
-  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
-            loss_algorithm_.GetLossTimeout());
-  packets_acked_.clear();
-
-  clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
-  // Verify 2 and 3 will be early retransmitted.
-  VerifyLosses(5, packets_acked_, std::vector<uint64_t>{2, 3}, 2);
-}
-
-// Regression test for b/133771183.
-TEST_F(UberLossAlgorithmTest, PacketInLimbo) {
-  // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT,
-  // 4-retransmit SHLO. Client receives and ACKs packets 1, 3 and 4.
-  QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
-                                           Perspective::IS_SERVER);
-
-  SendPacket(1, ENCRYPTION_ZERO_RTT);
-  SendPacket(2, ENCRYPTION_FORWARD_SECURE);
-  SendPacket(3, ENCRYPTION_FORWARD_SECURE);
-  SendPacket(4, ENCRYPTION_ZERO_RTT);
-
-  SendPacket(5, ENCRYPTION_FORWARD_SECURE);
-  AckPackets({1, 3, 4});
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(3));
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      HANDSHAKE_DATA, QuicPacketNumber(4));
-  // No packet loss detected.
-  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{});
-
-  SendPacket(6, ENCRYPTION_FORWARD_SECURE);
-  AckPackets({5, 6});
-  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
-      APPLICATION_DATA, QuicPacketNumber(6));
-  // Verify packet 2 is detected lost.
-  VerifyLosses(6, packets_acked_, std::vector<uint64_t>{2});
-}
-
-class TestLossTuner : public LossDetectionTunerInterface {
- public:
-  TestLossTuner(bool forced_start_result,
-                LossDetectionParameters forced_parameters)
-      : forced_start_result_(forced_start_result),
-        forced_parameters_(std::move(forced_parameters)) {}
-
-  ~TestLossTuner() override = default;
-
-  bool Start(LossDetectionParameters* params) override {
-    start_called_ = true;
-    *params = forced_parameters_;
-    return forced_start_result_;
-  }
-
-  void Finish(const LossDetectionParameters& /*params*/) override {}
-
-  bool start_called() const { return start_called_; }
-
- private:
-  bool forced_start_result_;
-  LossDetectionParameters forced_parameters_;
-  bool start_called_ = false;
-};
-
-// Verify the parameters are changed if first call SetFromConfig(), then call
-// OnMinRttAvailable().
-TEST_F(UberLossAlgorithmTest, LossDetectionTuning_SetFromConfigFirst) {
-  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
-  const QuicPacketCount old_reordering_threshold =
-      loss_algorithm_.GetPacketReorderingThreshold();
-
-  loss_algorithm_.OnUserAgentIdKnown();
-
-  // Not owned.
-  TestLossTuner* test_tuner = new TestLossTuner(
-      /*forced_start_result=*/true,
-      LossDetectionParameters{
-          /*reordering_shift=*/old_reordering_shift + 1,
-          /*reordering_threshold=*/old_reordering_threshold * 2});
-  loss_algorithm_.SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
-
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kELDT);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
-
-  // MinRtt was not available when SetFromConfig was called.
-  EXPECT_FALSE(test_tuner->start_called());
-  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
-  EXPECT_EQ(old_reordering_threshold,
-            loss_algorithm_.GetPacketReorderingThreshold());
-
-  // MinRtt available. Tuner should not start yet because no reordering yet.
-  loss_algorithm_.OnMinRttAvailable();
-  EXPECT_FALSE(test_tuner->start_called());
-
-  // Reordering happened. Tuner should start now.
-  loss_algorithm_.OnReorderingDetected();
-  EXPECT_TRUE(test_tuner->start_called());
-  EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
-  EXPECT_NE(old_reordering_threshold,
-            loss_algorithm_.GetPacketReorderingThreshold());
-}
-
-// Verify the parameters are changed if first call OnMinRttAvailable(), then
-// call SetFromConfig().
-TEST_F(UberLossAlgorithmTest, LossDetectionTuning_OnMinRttAvailableFirst) {
-  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
-  const QuicPacketCount old_reordering_threshold =
-      loss_algorithm_.GetPacketReorderingThreshold();
-
-  loss_algorithm_.OnUserAgentIdKnown();
-
-  // Not owned.
-  TestLossTuner* test_tuner = new TestLossTuner(
-      /*forced_start_result=*/true,
-      LossDetectionParameters{
-          /*reordering_shift=*/old_reordering_shift + 1,
-          /*reordering_threshold=*/old_reordering_threshold * 2});
-  loss_algorithm_.SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
-
-  loss_algorithm_.OnMinRttAvailable();
-  EXPECT_FALSE(test_tuner->start_called());
-  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
-  EXPECT_EQ(old_reordering_threshold,
-            loss_algorithm_.GetPacketReorderingThreshold());
-
-  // Pretend a reodering has happened.
-  loss_algorithm_.OnReorderingDetected();
-  EXPECT_FALSE(test_tuner->start_called());
-
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kELDT);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  // Should start tuning since MinRtt is available.
-  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
-
-  EXPECT_TRUE(test_tuner->start_called());
-  EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
-  EXPECT_NE(old_reordering_threshold,
-            loss_algorithm_.GetPacketReorderingThreshold());
-}
-
-// Verify the parameters are not changed if Tuner.Start() returns false.
-TEST_F(UberLossAlgorithmTest, LossDetectionTuning_StartFailed) {
-  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
-  const QuicPacketCount old_reordering_threshold =
-      loss_algorithm_.GetPacketReorderingThreshold();
-
-  loss_algorithm_.OnUserAgentIdKnown();
-
-  // Not owned.
-  TestLossTuner* test_tuner = new TestLossTuner(
-      /*forced_start_result=*/false,
-      LossDetectionParameters{
-          /*reordering_shift=*/old_reordering_shift + 1,
-          /*reordering_threshold=*/old_reordering_threshold * 2});
-  loss_algorithm_.SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
-
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kELDT);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
-
-  // MinRtt was not available when SetFromConfig was called.
-  EXPECT_FALSE(test_tuner->start_called());
-  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
-  EXPECT_EQ(old_reordering_threshold,
-            loss_algorithm_.GetPacketReorderingThreshold());
-
-  // Pretend a reodering has happened.
-  loss_algorithm_.OnReorderingDetected();
-  EXPECT_FALSE(test_tuner->start_called());
-
-  // Parameters should not change since test_tuner->Start() returns false.
-  loss_algorithm_.OnMinRttAvailable();
-  EXPECT_TRUE(test_tuner->start_called());
-  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
-  EXPECT_EQ(old_reordering_threshold,
-            loss_algorithm_.GetPacketReorderingThreshold());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/congestion_control/windowed_filter.h b/quic/core/congestion_control/windowed_filter.h
deleted file mode 100644
index a777ac5..0000000
--- a/quic/core/congestion_control/windowed_filter.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
-#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
-
-// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum)
-// estimate of a stream of samples over some fixed time interval. (E.g.,
-// the minimum RTT over the past five minutes.) The algorithm keeps track of
-// the best, second best, and third best min (or max) estimates, maintaining an
-// invariant that the measurement time of the n'th best >= n-1'th best.
-
-// The algorithm works as follows. On a reset, all three estimates are set to
-// the same sample. The second best estimate is then recorded in the second
-// quarter of the window, and a third best estimate is recorded in the second
-// half of the window, bounding the worst case error when the true min is
-// monotonically increasing (or true max is monotonically decreasing) over the
-// window.
-//
-// A new best sample replaces all three estimates, since the new best is lower
-// (or higher) than everything else in the window and it is the most recent.
-// The window thus effectively gets reset on every new min. The same property
-// holds true for second best and third best estimates. Specifically, when a
-// sample arrives that is better than the second best but not better than the
-// best, it replaces the second and third best estimates but not the best
-// estimate. Similarly, a sample that is better than the third best estimate
-// but not the other estimates replaces only the third best estimate.
-//
-// Finally, when the best expires, it is replaced by the second best, which in
-// turn is replaced by the third best. The newest sample replaces the third
-// best.
-
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-// Compares two values and returns true if the first is less than or equal
-// to the second.
-template <class T>
-struct QUIC_EXPORT_PRIVATE MinFilter {
-  bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; }
-};
-
-// Compares two values and returns true if the first is greater than or equal
-// to the second.
-template <class T>
-struct QUIC_EXPORT_PRIVATE MaxFilter {
-  bool operator()(const T& lhs, const T& rhs) const { return lhs >= rhs; }
-};
-
-// Use the following to construct a windowed filter object of type T.
-// For example, a min filter using QuicTime as the time type:
-//   WindowedFilter<T, MinFilter<T>, QuicTime, QuicTime::Delta> ObjectName;
-// A max filter using 64-bit integers as the time type:
-//   WindowedFilter<T, MaxFilter<T>, uint64_t, int64_t> ObjectName;
-// Specifically, this template takes four arguments:
-// 1. T -- type of the measurement that is being filtered.
-// 2. Compare -- MinFilter<T> or MaxFilter<T>, depending on the type of filter
-//    desired.
-// 3. TimeT -- the type used to represent timestamps.
-// 4. TimeDeltaT -- the type used to represent continuous time intervals between
-//    two timestamps.  Has to be the type of (a - b) if both |a| and |b| are
-//    of type TimeT.
-template <class T, class Compare, typename TimeT, typename TimeDeltaT>
-class QUIC_EXPORT_PRIVATE WindowedFilter {
- public:
-  // |window_length| is the period after which a best estimate expires.
-  // |zero_value| is used as the uninitialized value for objects of T.
-  // Importantly, |zero_value| should be an invalid value for a true sample.
-  WindowedFilter(TimeDeltaT window_length, T zero_value, TimeT zero_time)
-      : window_length_(window_length),
-        zero_value_(zero_value),
-        zero_time_(zero_time),
-        estimates_{Sample(zero_value_, zero_time),
-                   Sample(zero_value_, zero_time),
-                   Sample(zero_value_, zero_time)} {}
-
-  // Changes the window length.  Does not update any current samples.
-  void SetWindowLength(TimeDeltaT window_length) {
-    window_length_ = window_length;
-  }
-
-  // Updates best estimates with |sample|, and expires and updates best
-  // estimates as necessary.
-  void Update(T new_sample, TimeT new_time) {
-    // Reset all estimates if they have not yet been initialized, if new sample
-    // is a new best, or if the newest recorded estimate is too old.
-    if (estimates_[0].sample == zero_value_ ||
-        Compare()(new_sample, estimates_[0].sample) ||
-        new_time - estimates_[2].time > window_length_) {
-      Reset(new_sample, new_time);
-      return;
-    }
-
-    if (Compare()(new_sample, estimates_[1].sample)) {
-      estimates_[1] = Sample(new_sample, new_time);
-      estimates_[2] = estimates_[1];
-    } else if (Compare()(new_sample, estimates_[2].sample)) {
-      estimates_[2] = Sample(new_sample, new_time);
-    }
-
-    // Expire and update estimates as necessary.
-    if (new_time - estimates_[0].time > window_length_) {
-      // The best estimate hasn't been updated for an entire window, so promote
-      // second and third best estimates.
-      estimates_[0] = estimates_[1];
-      estimates_[1] = estimates_[2];
-      estimates_[2] = Sample(new_sample, new_time);
-      // Need to iterate one more time. Check if the new best estimate is
-      // outside the window as well, since it may also have been recorded a
-      // long time ago. Don't need to iterate once more since we cover that
-      // case at the beginning of the method.
-      if (new_time - estimates_[0].time > window_length_) {
-        estimates_[0] = estimates_[1];
-        estimates_[1] = estimates_[2];
-      }
-      return;
-    }
-    if (estimates_[1].sample == estimates_[0].sample &&
-        new_time - estimates_[1].time > window_length_ >> 2) {
-      // A quarter of the window has passed without a better sample, so the
-      // second-best estimate is taken from the second quarter of the window.
-      estimates_[2] = estimates_[1] = Sample(new_sample, new_time);
-      return;
-    }
-
-    if (estimates_[2].sample == estimates_[1].sample &&
-        new_time - estimates_[2].time > window_length_ >> 1) {
-      // We've passed a half of the window without a better estimate, so take
-      // a third-best estimate from the second half of the window.
-      estimates_[2] = Sample(new_sample, new_time);
-    }
-  }
-
-  // Resets all estimates to new sample.
-  void Reset(T new_sample, TimeT new_time) {
-    estimates_[0] = estimates_[1] = estimates_[2] =
-        Sample(new_sample, new_time);
-  }
-
-  void Clear() { Reset(zero_value_, zero_time_); }
-
-  T GetBest() const { return estimates_[0].sample; }
-  T GetSecondBest() const { return estimates_[1].sample; }
-  T GetThirdBest() const { return estimates_[2].sample; }
-
- private:
-  struct QUIC_EXPORT_PRIVATE Sample {
-    T sample;
-    TimeT time;
-    Sample(T init_sample, TimeT init_time)
-        : sample(init_sample), time(init_time) {}
-  };
-
-  TimeDeltaT window_length_;  // Time length of window.
-  T zero_value_;              // Uninitialized value of T.
-  TimeT zero_time_;           // Uninitialized value of TimeT.
-  Sample estimates_[3];       // Best estimate is element 0.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
diff --git a/quic/core/congestion_control/windowed_filter_test.cc b/quic/core/congestion_control/windowed_filter_test.cc
deleted file mode 100644
index bb0e8fb..0000000
--- a/quic/core/congestion_control/windowed_filter_test.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/congestion_control/windowed_filter.h"
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class WindowedFilterTest : public QuicTest {
- public:
-  // Set the window to 99ms, so 25ms is more than a quarter rtt.
-  WindowedFilterTest()
-      : windowed_min_rtt_(QuicTime::Delta::FromMilliseconds(99),
-                          QuicTime::Delta::Zero(),
-                          QuicTime::Zero()),
-        windowed_max_bw_(QuicTime::Delta::FromMilliseconds(99),
-                         QuicBandwidth::Zero(),
-                         QuicTime::Zero()) {}
-
-  // Sets up windowed_min_rtt_ to have the following values:
-  // Best = 20ms, recorded at 25ms
-  // Second best = 40ms, recorded at 75ms
-  // Third best = 50ms, recorded at 100ms
-  void InitializeMinFilter() {
-    QuicTime now = QuicTime::Zero();
-    QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
-    for (int i = 0; i < 5; ++i) {
-      windowed_min_rtt_.Update(rtt_sample, now);
-      QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
-                   << " mins: "
-                   << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
-                   << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
-                   << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
-      now = now + QuicTime::Delta::FromMilliseconds(25);
-      rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
-    }
-    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
-              windowed_min_rtt_.GetBest());
-    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
-              windowed_min_rtt_.GetSecondBest());
-    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
-              windowed_min_rtt_.GetThirdBest());
-  }
-
-  // Sets up windowed_max_bw_ to have the following values:
-  // Best = 900 bps, recorded at 25ms
-  // Second best = 700 bps, recorded at 75ms
-  // Third best = 600 bps, recorded at 100ms
-  void InitializeMaxFilter() {
-    QuicTime now = QuicTime::Zero();
-    QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
-    for (int i = 0; i < 5; ++i) {
-      windowed_max_bw_.Update(bw_sample, now);
-      QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
-                   << " maxs: "
-                   << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
-                   << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
-                   << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
-      now = now + QuicTime::Delta::FromMilliseconds(25);
-      bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
-    }
-    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
-              windowed_max_bw_.GetBest());
-    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
-              windowed_max_bw_.GetSecondBest());
-    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(600),
-              windowed_max_bw_.GetThirdBest());
-  }
-
- protected:
-  WindowedFilter<QuicTime::Delta,
-                 MinFilter<QuicTime::Delta>,
-                 QuicTime,
-                 QuicTime::Delta>
-      windowed_min_rtt_;
-  WindowedFilter<QuicBandwidth,
-                 MaxFilter<QuicBandwidth>,
-                 QuicTime,
-                 QuicTime::Delta>
-      windowed_max_bw_;
-};
-
-namespace {
-// Test helper function: updates the filter with a lot of small values in order
-// to ensure that it is not susceptible to noise.
-void UpdateWithIrrelevantSamples(
-    WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t>* filter,
-    uint64_t max_value,
-    uint64_t time) {
-  for (uint64_t i = 0; i < 1000; i++) {
-    filter->Update(i % max_value, time);
-  }
-}
-}  // namespace
-
-TEST_F(WindowedFilterTest, UninitializedEstimates) {
-  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetBest());
-  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetBest());
-  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetThirdBest());
-}
-
-TEST_F(WindowedFilterTest, MonotonicallyIncreasingMin) {
-  QuicTime now = QuicTime::Zero();
-  QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), windowed_min_rtt_.GetBest());
-
-  // Gradually increase the rtt samples and ensure the windowed min rtt starts
-  // rising.
-  for (int i = 0; i < 6; ++i) {
-    now = now + QuicTime::Delta::FromMilliseconds(25);
-    rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
-    windowed_min_rtt_.Update(rtt_sample, now);
-    QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
-                 << " mins: "
-                 << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
-                 << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
-                 << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
-    if (i < 3) {
-      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-                windowed_min_rtt_.GetBest());
-    } else if (i == 3) {
-      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
-                windowed_min_rtt_.GetBest());
-    } else if (i < 6) {
-      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
-                windowed_min_rtt_.GetBest());
-    }
-  }
-}
-
-TEST_F(WindowedFilterTest, MonotonicallyDecreasingMax) {
-  QuicTime now = QuicTime::Zero();
-  QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000), windowed_max_bw_.GetBest());
-
-  // Gradually decrease the bw samples and ensure the windowed max bw starts
-  // decreasing.
-  for (int i = 0; i < 6; ++i) {
-    now = now + QuicTime::Delta::FromMilliseconds(25);
-    bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
-    windowed_max_bw_.Update(bw_sample, now);
-    QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
-                 << " maxs: "
-                 << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
-                 << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
-                 << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
-    if (i < 3) {
-      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000),
-                windowed_max_bw_.GetBest());
-    } else if (i == 3) {
-      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
-                windowed_max_bw_.GetBest());
-    } else if (i < 6) {
-      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
-                windowed_max_bw_.GetBest());
-    }
-  }
-}
-
-TEST_F(WindowedFilterTest, SampleChangesThirdBestMin) {
-  InitializeMinFilter();
-  // RTT sample lower than the third-choice min-rtt sets that, but nothing else.
-  QuicTime::Delta rtt_sample =
-      windowed_min_rtt_.GetThirdBest() - QuicTime::Delta::FromMilliseconds(5);
-  // This assert is necessary to avoid triggering -Wstrict-overflow
-  // See crbug/616957
-  ASSERT_GT(windowed_min_rtt_.GetThirdBest(),
-            QuicTime::Delta::FromMilliseconds(5));
-  // Latest sample was recorded at 100ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
-            windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesThirdBestMax) {
-  InitializeMaxFilter();
-  // BW sample higher than the third-choice max sets that, but nothing else.
-  QuicBandwidth bw_sample =
-      windowed_max_bw_.GetThirdBest() + QuicBandwidth::FromBitsPerSecond(50);
-  // Latest sample was recorded at 100ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
-            windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesSecondBestMin) {
-  InitializeMinFilter();
-  // RTT sample lower than the second-choice min sets that and also
-  // the third-choice min.
-  QuicTime::Delta rtt_sample =
-      windowed_min_rtt_.GetSecondBest() - QuicTime::Delta::FromMilliseconds(5);
-  // This assert is necessary to avoid triggering -Wstrict-overflow
-  // See crbug/616957
-  ASSERT_GT(windowed_min_rtt_.GetSecondBest(),
-            QuicTime::Delta::FromMilliseconds(5));
-  // Latest sample was recorded at 100ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesSecondBestMax) {
-  InitializeMaxFilter();
-  // BW sample higher than the second-choice max sets that and also
-  // the third-choice max.
-  QuicBandwidth bw_sample =
-      windowed_max_bw_.GetSecondBest() + QuicBandwidth::FromBitsPerSecond(50);
-  // Latest sample was recorded at 100ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesAllMins) {
-  InitializeMinFilter();
-  // RTT sample lower than the first-choice min-rtt sets that and also
-  // the second and third-choice mins.
-  QuicTime::Delta rtt_sample =
-      windowed_min_rtt_.GetBest() - QuicTime::Delta::FromMilliseconds(5);
-  // This assert is necessary to avoid triggering -Wstrict-overflow
-  // See crbug/616957
-  ASSERT_GT(windowed_min_rtt_.GetBest(), QuicTime::Delta::FromMilliseconds(5));
-  // Latest sample was recorded at 100ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, SampleChangesAllMaxs) {
-  InitializeMaxFilter();
-  // BW sample higher than the first-choice max sets that and also
-  // the second and third-choice maxs.
-  QuicBandwidth bw_sample =
-      windowed_max_bw_.GetBest() + QuicBandwidth::FromBitsPerSecond(50);
-  // Latest sample was recorded at 100ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireBestMin) {
-  InitializeMinFilter();
-  QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
-  QuicTime::Delta old_second_best = windowed_min_rtt_.GetSecondBest();
-  QuicTime::Delta rtt_sample =
-      old_third_best + QuicTime::Delta::FromMilliseconds(5);
-  // Best min sample was recorded at 25ms, so expiry time is 124ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(old_third_best, windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(old_second_best, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireBestMax) {
-  InitializeMaxFilter();
-  QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
-  QuicBandwidth old_second_best = windowed_max_bw_.GetSecondBest();
-  QuicBandwidth bw_sample =
-      old_third_best - QuicBandwidth::FromBitsPerSecond(50);
-  // Best max sample was recorded at 25ms, so expiry time is 124ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
-  EXPECT_EQ(old_third_best, windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(old_second_best, windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireSecondBestMin) {
-  InitializeMinFilter();
-  QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
-  QuicTime::Delta rtt_sample =
-      old_third_best + QuicTime::Delta::FromMilliseconds(5);
-  // Second best min sample was recorded at 75ms, so expiry time is 174ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(old_third_best, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireSecondBestMax) {
-  InitializeMaxFilter();
-  QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
-  QuicBandwidth bw_sample =
-      old_third_best - QuicBandwidth::FromBitsPerSecond(50);
-  // Second best max sample was recorded at 75ms, so expiry time is 174ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(old_third_best, windowed_max_bw_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireAllMins) {
-  InitializeMinFilter();
-  QuicTime::Delta rtt_sample =
-      windowed_min_rtt_.GetThirdBest() + QuicTime::Delta::FromMilliseconds(5);
-  // This assert is necessary to avoid triggering -Wstrict-overflow
-  // See crbug/616957
-  ASSERT_LT(windowed_min_rtt_.GetThirdBest(),
-            QuicTime::Delta::Infinite() - QuicTime::Delta::FromMilliseconds(5));
-  // Third best min sample was recorded at 100ms, so expiry time is 199ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
-  windowed_min_rtt_.Update(rtt_sample, now);
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
-  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
-}
-
-TEST_F(WindowedFilterTest, ExpireAllMaxs) {
-  InitializeMaxFilter();
-  QuicBandwidth bw_sample =
-      windowed_max_bw_.GetThirdBest() - QuicBandwidth::FromBitsPerSecond(50);
-  // Third best max sample was recorded at 100ms, so expiry time is 199ms.
-  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
-  windowed_max_bw_.Update(bw_sample, now);
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
-  EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
-}
-
-// Test the windowed filter where the time used is an exact counter instead of a
-// timestamp.  This is useful if, for example, the time is measured in round
-// trips.
-TEST_F(WindowedFilterTest, ExpireCounterBasedMax) {
-  // Create a window which starts at t = 0 and expires after two cycles.
-  WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t> max_filter(
-      2, 0, 0);
-
-  const uint64_t kBest = 50000;
-  // Insert 50000 at t = 1.
-  max_filter.Update(50000, 1);
-  EXPECT_EQ(kBest, max_filter.GetBest());
-  UpdateWithIrrelevantSamples(&max_filter, 20, 1);
-  EXPECT_EQ(kBest, max_filter.GetBest());
-
-  // Insert 40000 at t = 2.  Nothing is expected to expire.
-  max_filter.Update(40000, 2);
-  EXPECT_EQ(kBest, max_filter.GetBest());
-  UpdateWithIrrelevantSamples(&max_filter, 20, 2);
-  EXPECT_EQ(kBest, max_filter.GetBest());
-
-  // Insert 30000 at t = 3.  Nothing is expected to expire yet.
-  max_filter.Update(30000, 3);
-  EXPECT_EQ(kBest, max_filter.GetBest());
-  UpdateWithIrrelevantSamples(&max_filter, 20, 3);
-  EXPECT_EQ(kBest, max_filter.GetBest());
-  QUIC_VLOG(0) << max_filter.GetSecondBest();
-  QUIC_VLOG(0) << max_filter.GetThirdBest();
-
-  // Insert 20000 at t = 4.  50000 at t = 1 expires, so 40000 becomes the new
-  // maximum.
-  const uint64_t kNewBest = 40000;
-  max_filter.Update(20000, 4);
-  EXPECT_EQ(kNewBest, max_filter.GetBest());
-  UpdateWithIrrelevantSamples(&max_filter, 20, 4);
-  EXPECT_EQ(kNewBest, max_filter.GetBest());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aead_base_decrypter.cc b/quic/core/crypto/aead_base_decrypter.cc
deleted file mode 100644
index 69724ba..0000000
--- a/quic/core/crypto/aead_base_decrypter.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aead_base_decrypter.h"
-
-#include <cstdint>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/crypto.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Clear OpenSSL error stack.
-void ClearOpenSslErrors() {
-  while (ERR_get_error()) {
-  }
-}
-
-// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
-// stack.
-void DLogOpenSslErrors() {
-#ifdef NDEBUG
-  ClearOpenSslErrors();
-#else
-  while (uint32_t error = ERR_get_error()) {
-    char buf[120];
-    ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
-    QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
-  }
-#endif
-}
-
-const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
-  // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
-  // the static initializer is disabled.
-  CRYPTO_library_init();
-  return aead_getter();
-}
-
-}  // namespace
-
-AeadBaseDecrypter::AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
-                                     size_t key_size,
-                                     size_t auth_tag_size,
-                                     size_t nonce_size,
-                                     bool use_ietf_nonce_construction)
-    : aead_alg_(InitAndCall(aead_getter)),
-      key_size_(key_size),
-      auth_tag_size_(auth_tag_size),
-      nonce_size_(nonce_size),
-      use_ietf_nonce_construction_(use_ietf_nonce_construction),
-      have_preliminary_key_(false) {
-  QUICHE_DCHECK_GT(256u, key_size);
-  QUICHE_DCHECK_GT(256u, auth_tag_size);
-  QUICHE_DCHECK_GT(256u, nonce_size);
-  QUICHE_DCHECK_LE(key_size_, sizeof(key_));
-  QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
-}
-
-AeadBaseDecrypter::~AeadBaseDecrypter() {}
-
-bool AeadBaseDecrypter::SetKey(absl::string_view key) {
-  QUICHE_DCHECK_EQ(key.size(), key_size_);
-  if (key.size() != key_size_) {
-    return false;
-  }
-  memcpy(key_, key.data(), key.size());
-
-  EVP_AEAD_CTX_cleanup(ctx_.get());
-  if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
-                         nullptr)) {
-    DLogOpenSslErrors();
-    return false;
-  }
-
-  return true;
-}
-
-bool AeadBaseDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
-  if (use_ietf_nonce_construction_) {
-    QUIC_BUG(quic_bug_10709_1)
-        << "Attempted to set nonce prefix on IETF QUIC crypter";
-    return false;
-  }
-  QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
-  if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
-    return false;
-  }
-  memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
-  return true;
-}
-
-bool AeadBaseDecrypter::SetIV(absl::string_view iv) {
-  if (!use_ietf_nonce_construction_) {
-    QUIC_BUG(quic_bug_10709_2) << "Attempted to set IV on Google QUIC crypter";
-    return false;
-  }
-  QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
-  if (iv.size() != nonce_size_) {
-    return false;
-  }
-  memcpy(iv_, iv.data(), iv.size());
-  return true;
-}
-
-bool AeadBaseDecrypter::SetPreliminaryKey(absl::string_view key) {
-  QUICHE_DCHECK(!have_preliminary_key_);
-  SetKey(key);
-  have_preliminary_key_ = true;
-
-  return true;
-}
-
-bool AeadBaseDecrypter::SetDiversificationNonce(
-    const DiversificationNonce& nonce) {
-  if (!have_preliminary_key_) {
-    return true;
-  }
-
-  std::string key, nonce_prefix;
-  size_t prefix_size = nonce_size_;
-  if (!use_ietf_nonce_construction_) {
-    prefix_size -= sizeof(QuicPacketNumber);
-  }
-  DiversifyPreliminaryKey(
-      absl::string_view(reinterpret_cast<const char*>(key_), key_size_),
-      absl::string_view(reinterpret_cast<const char*>(iv_), prefix_size), nonce,
-      key_size_, prefix_size, &key, &nonce_prefix);
-
-  if (!SetKey(key) ||
-      (!use_ietf_nonce_construction_ && !SetNoncePrefix(nonce_prefix)) ||
-      (use_ietf_nonce_construction_ && !SetIV(nonce_prefix))) {
-    QUICHE_DCHECK(false);
-    return false;
-  }
-
-  have_preliminary_key_ = false;
-  return true;
-}
-
-bool AeadBaseDecrypter::DecryptPacket(uint64_t packet_number,
-                                      absl::string_view associated_data,
-                                      absl::string_view ciphertext,
-                                      char* output,
-                                      size_t* output_length,
-                                      size_t max_output_length) {
-  if (ciphertext.length() < auth_tag_size_) {
-    return false;
-  }
-
-  if (have_preliminary_key_) {
-    QUIC_BUG(quic_bug_10709_3)
-        << "Unable to decrypt while key diversification is pending";
-    return false;
-  }
-
-  uint8_t nonce[kMaxNonceSize];
-  memcpy(nonce, iv_, nonce_size_);
-  size_t prefix_len = nonce_size_ - sizeof(packet_number);
-  if (use_ietf_nonce_construction_) {
-    for (size_t i = 0; i < sizeof(packet_number); ++i) {
-      nonce[prefix_len + i] ^=
-          (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
-    }
-  } else {
-    memcpy(nonce + prefix_len, &packet_number, sizeof(packet_number));
-  }
-  if (!EVP_AEAD_CTX_open(
-          ctx_.get(), reinterpret_cast<uint8_t*>(output), output_length,
-          max_output_length, reinterpret_cast<const uint8_t*>(nonce),
-          nonce_size_, reinterpret_cast<const uint8_t*>(ciphertext.data()),
-          ciphertext.size(),
-          reinterpret_cast<const uint8_t*>(associated_data.data()),
-          associated_data.size())) {
-    // Because QuicFramer does trial decryption, decryption errors are expected
-    // when encryption level changes. So we don't log decryption errors.
-    ClearOpenSslErrors();
-    return false;
-  }
-  return true;
-}
-
-size_t AeadBaseDecrypter::GetKeySize() const {
-  return key_size_;
-}
-
-size_t AeadBaseDecrypter::GetNoncePrefixSize() const {
-  return nonce_size_ - sizeof(QuicPacketNumber);
-}
-
-size_t AeadBaseDecrypter::GetIVSize() const {
-  return nonce_size_;
-}
-
-absl::string_view AeadBaseDecrypter::GetKey() const {
-  return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
-}
-
-absl::string_view AeadBaseDecrypter::GetNoncePrefix() const {
-  return absl::string_view(reinterpret_cast<const char*>(iv_),
-                           nonce_size_ - sizeof(QuicPacketNumber));
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aead_base_decrypter.h b/quic/core/crypto/aead_base_decrypter.h
deleted file mode 100644
index 1d4598b..0000000
--- a/quic/core/crypto/aead_base_decrypter.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// AeadBaseDecrypter is the base class of AEAD QuicDecrypter subclasses.
-class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
- public:
-  // This takes the function pointer rather than the EVP_AEAD itself so
-  // subclasses do not need to call CRYPTO_library_init.
-  AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
-                    size_t key_size,
-                    size_t auth_tag_size,
-                    size_t nonce_size,
-                    bool use_ietf_nonce_construction);
-  AeadBaseDecrypter(const AeadBaseDecrypter&) = delete;
-  AeadBaseDecrypter& operator=(const AeadBaseDecrypter&) = delete;
-  ~AeadBaseDecrypter() override;
-
-  // QuicDecrypter implementation
-  bool SetKey(absl::string_view key) override;
-  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
-  bool SetIV(absl::string_view iv) override;
-  bool SetPreliminaryKey(absl::string_view key) override;
-  bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
-  bool DecryptPacket(uint64_t packet_number,
-                     absl::string_view associated_data,
-                     absl::string_view ciphertext,
-                     char* output,
-                     size_t* output_length,
-                     size_t max_output_length) override;
-  size_t GetKeySize() const override;
-  size_t GetNoncePrefixSize() const override;
-  size_t GetIVSize() const override;
-  absl::string_view GetKey() const override;
-  absl::string_view GetNoncePrefix() const override;
-
- protected:
-  // Make these constants available to the subclasses so that the subclasses
-  // can assert at compile time their key_size_ and nonce_size_ do not
-  // exceed the maximum.
-  static const size_t kMaxKeySize = 32;
-  static const size_t kMaxNonceSize = 12;
-
- private:
-  const EVP_AEAD* const aead_alg_;
-  const size_t key_size_;
-  const size_t auth_tag_size_;
-  const size_t nonce_size_;
-  const bool use_ietf_nonce_construction_;
-  bool have_preliminary_key_;
-
-  // The key.
-  unsigned char key_[kMaxKeySize];
-  // The IV used to construct the nonce.
-  unsigned char iv_[kMaxNonceSize];
-
-  bssl::ScopedEVP_AEAD_CTX ctx_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
diff --git a/quic/core/crypto/aead_base_encrypter.cc b/quic/core/crypto/aead_base_encrypter.cc
deleted file mode 100644
index f4878e5..0000000
--- a/quic/core/crypto/aead_base_encrypter.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aead_base_encrypter.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/crypto.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
-// stack.
-void DLogOpenSslErrors() {
-#ifdef NDEBUG
-  while (ERR_get_error()) {
-  }
-#else
-  while (unsigned long error = ERR_get_error()) {
-    char buf[120];
-    ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
-    QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
-  }
-#endif
-}
-
-const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
-  // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
-  // the static initializer is disabled.
-  CRYPTO_library_init();
-  return aead_getter();
-}
-
-}  // namespace
-
-AeadBaseEncrypter::AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
-                                     size_t key_size,
-                                     size_t auth_tag_size,
-                                     size_t nonce_size,
-                                     bool use_ietf_nonce_construction)
-    : aead_alg_(InitAndCall(aead_getter)),
-      key_size_(key_size),
-      auth_tag_size_(auth_tag_size),
-      nonce_size_(nonce_size),
-      use_ietf_nonce_construction_(use_ietf_nonce_construction) {
-  QUICHE_DCHECK_LE(key_size_, sizeof(key_));
-  QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
-  QUICHE_DCHECK_GE(kMaxNonceSize, nonce_size_);
-}
-
-AeadBaseEncrypter::~AeadBaseEncrypter() {}
-
-bool AeadBaseEncrypter::SetKey(absl::string_view key) {
-  QUICHE_DCHECK_EQ(key.size(), key_size_);
-  if (key.size() != key_size_) {
-    return false;
-  }
-  memcpy(key_, key.data(), key.size());
-
-  EVP_AEAD_CTX_cleanup(ctx_.get());
-
-  if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
-                         nullptr)) {
-    DLogOpenSslErrors();
-    return false;
-  }
-
-  return true;
-}
-
-bool AeadBaseEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
-  if (use_ietf_nonce_construction_) {
-    QUIC_BUG(quic_bug_10634_1)
-        << "Attempted to set nonce prefix on IETF QUIC crypter";
-    return false;
-  }
-  QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
-  if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
-    return false;
-  }
-  memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
-  return true;
-}
-
-bool AeadBaseEncrypter::SetIV(absl::string_view iv) {
-  if (!use_ietf_nonce_construction_) {
-    QUIC_BUG(quic_bug_10634_2) << "Attempted to set IV on Google QUIC crypter";
-    return false;
-  }
-  QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
-  if (iv.size() != nonce_size_) {
-    return false;
-  }
-  memcpy(iv_, iv.data(), iv.size());
-  return true;
-}
-
-bool AeadBaseEncrypter::Encrypt(absl::string_view nonce,
-                                absl::string_view associated_data,
-                                absl::string_view plaintext,
-                                unsigned char* output) {
-  QUICHE_DCHECK_EQ(nonce.size(), nonce_size_);
-
-  size_t ciphertext_len;
-  if (!EVP_AEAD_CTX_seal(
-          ctx_.get(), output, &ciphertext_len,
-          plaintext.size() + auth_tag_size_,
-          reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
-          reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
-          reinterpret_cast<const uint8_t*>(associated_data.data()),
-          associated_data.size())) {
-    DLogOpenSslErrors();
-    return false;
-  }
-
-  return true;
-}
-
-bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number,
-                                      absl::string_view associated_data,
-                                      absl::string_view plaintext,
-                                      char* output,
-                                      size_t* output_length,
-                                      size_t max_output_length) {
-  size_t ciphertext_size = GetCiphertextSize(plaintext.length());
-  if (max_output_length < ciphertext_size) {
-    return false;
-  }
-  // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
-  // same packet number twice.
-  alignas(4) char nonce_buffer[kMaxNonceSize];
-  memcpy(nonce_buffer, iv_, nonce_size_);
-  size_t prefix_len = nonce_size_ - sizeof(packet_number);
-  if (use_ietf_nonce_construction_) {
-    for (size_t i = 0; i < sizeof(packet_number); ++i) {
-      nonce_buffer[prefix_len + i] ^=
-          (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
-    }
-  } else {
-    memcpy(nonce_buffer + prefix_len, &packet_number, sizeof(packet_number));
-  }
-
-  if (!Encrypt(absl::string_view(nonce_buffer, nonce_size_), associated_data,
-               plaintext, reinterpret_cast<unsigned char*>(output))) {
-    return false;
-  }
-  *output_length = ciphertext_size;
-  return true;
-}
-
-size_t AeadBaseEncrypter::GetKeySize() const {
-  return key_size_;
-}
-
-size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
-  return nonce_size_ - sizeof(QuicPacketNumber);
-}
-
-size_t AeadBaseEncrypter::GetIVSize() const {
-  return nonce_size_;
-}
-
-size_t AeadBaseEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
-  return ciphertext_size - std::min(ciphertext_size, auth_tag_size_);
-}
-
-size_t AeadBaseEncrypter::GetCiphertextSize(size_t plaintext_size) const {
-  return plaintext_size + auth_tag_size_;
-}
-
-absl::string_view AeadBaseEncrypter::GetKey() const {
-  return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
-}
-
-absl::string_view AeadBaseEncrypter::GetNoncePrefix() const {
-  return absl::string_view(reinterpret_cast<const char*>(iv_),
-                           GetNoncePrefixSize());
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aead_base_encrypter.h b/quic/core/crypto/aead_base_encrypter.h
deleted file mode 100644
index 7571a65..0000000
--- a/quic/core/crypto/aead_base_encrypter.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// AeadBaseEncrypter is the base class of AEAD QuicEncrypter subclasses.
-class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
- public:
-  // This takes the function pointer rather than the EVP_AEAD itself so
-  // subclasses do not need to call CRYPTO_library_init.
-  AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
-                    size_t key_size,
-                    size_t auth_tag_size,
-                    size_t nonce_size,
-                    bool use_ietf_nonce_construction);
-  AeadBaseEncrypter(const AeadBaseEncrypter&) = delete;
-  AeadBaseEncrypter& operator=(const AeadBaseEncrypter&) = delete;
-  ~AeadBaseEncrypter() override;
-
-  // QuicEncrypter implementation
-  bool SetKey(absl::string_view key) override;
-  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
-  bool SetIV(absl::string_view iv) override;
-  bool EncryptPacket(uint64_t packet_number,
-                     absl::string_view associated_data,
-                     absl::string_view plaintext,
-                     char* output,
-                     size_t* output_length,
-                     size_t max_output_length) override;
-  size_t GetKeySize() const override;
-  size_t GetNoncePrefixSize() const override;
-  size_t GetIVSize() const override;
-  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
-  size_t GetCiphertextSize(size_t plaintext_size) const override;
-  absl::string_view GetKey() const override;
-  absl::string_view GetNoncePrefix() const override;
-
-  // Necessary so unit tests can explicitly specify a nonce, instead of an IV
-  // (or nonce prefix) and packet number.
-  bool Encrypt(absl::string_view nonce,
-               absl::string_view associated_data,
-               absl::string_view plaintext,
-               unsigned char* output);
-
- protected:
-  // Make these constants available to the subclasses so that the subclasses
-  // can assert at compile time their key_size_ and nonce_size_ do not
-  // exceed the maximum.
-  static const size_t kMaxKeySize = 32;
-  enum : size_t { kMaxNonceSize = 12 };
-
- private:
-  const EVP_AEAD* const aead_alg_;
-  const size_t key_size_;
-  const size_t auth_tag_size_;
-  const size_t nonce_size_;
-  const bool use_ietf_nonce_construction_;
-
-  // The key.
-  unsigned char key_[kMaxKeySize];
-  // The IV used to construct the nonce.
-  unsigned char iv_[kMaxNonceSize];
-
-  bssl::ScopedEVP_AEAD_CTX ctx_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
diff --git a/quic/core/crypto/aes_128_gcm_12_decrypter.cc b/quic/core/crypto/aes_128_gcm_12_decrypter.cc
deleted file mode 100644
index 579ff92..0000000
--- a/quic/core/crypto/aes_128_gcm_12_decrypter.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
-    : AesBaseDecrypter(EVP_aead_aes_128_gcm,
-                       kKeySize,
-                       kAuthTagSize,
-                       kNonceSize,
-                       /* use_ietf_nonce_construction */ false) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {}
-
-uint32_t Aes128Gcm12Decrypter::cipher_id() const {
-  return TLS1_CK_AES_128_GCM_SHA256;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_12_decrypter.h b/quic/core/crypto/aes_128_gcm_12_decrypter.h
deleted file mode 100644
index fbd8d51..0000000
--- a/quic/core/crypto/aes_128_gcm_12_decrypter.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128Gcm12Decrypter is a QuicDecrypter that implements the
-// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
-// calling QuicDecrypter::Create(kAESG).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
-// of the nonce is four bytes.
-class QUIC_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AesBaseDecrypter {
- public:
-  enum {
-    // Authentication tags are truncated to 96 bits.
-    kAuthTagSize = 12,
-  };
-
-  Aes128Gcm12Decrypter();
-  Aes128Gcm12Decrypter(const Aes128Gcm12Decrypter&) = delete;
-  Aes128Gcm12Decrypter& operator=(const Aes128Gcm12Decrypter&) = delete;
-  ~Aes128Gcm12Decrypter() override;
-
-  uint32_t cipher_id() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
diff --git a/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
deleted file mode 100644
index dccd7df..0000000
--- a/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmDecrypt128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = cf063a34d4a9a76c2c86787d3f96db71
-// IV = 113b9785971864c83b01c787
-// CT =
-// AAD =
-// Tag = 72ac8493e3a5228b5d130a69d2510e42
-// PT =
-//
-// Count = 1
-// Key = a49a5e26a2f8cb63d05546c2a62f5343
-// IV = 907763b19b9b4ab6bd4f0281
-// CT =
-// AAD =
-// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
-// FAIL
-//
-// ...
-//
-// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
-  size_t key_len;
-  size_t iv_len;
-  size_t pt_len;
-  size_t aad_len;
-  size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  // Input:
-  const char* key;
-  const char* iv;
-  const char* ct;
-  const char* aad;
-  const char* tag;
-
-  // Expected output:
-  const char* pt;  // An empty string "" means decryption succeeded and
-                   // the plaintext is zero-length. nullptr means decryption
-                   // failed.
-};
-
-const TestGroupInfo test_group_info[] = {
-    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
-    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
-    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
-     "72ac8493e3a5228b5d130a69d2510e42", ""},
-    {
-        "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
-        "a2be08210d8c470a8df6e8fbd79ec5cf",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
-    {
-        "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
-        "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
-        nullptr  // FAIL
-    },
-    {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
-     "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
-     ""},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
-    {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
-     "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
-     "28286a321293253c3e0aa2704a278032"},
-    {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
-     "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
-     "95695a5b12f2870b9cc5fdc8f218a97d"},
-    {
-        "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
-        "0216c899c88d6e32c958c7e553daa5bc", "",
-        "a145319896329c96df291f64efbe0e3a",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
-    {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
-     "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
-     "338b22f9bad09093276a331e9c79c7f4",
-     "41dc38988945fcb44faf2ef72d0061289ef8efd8",
-     "4f71e72bde0018f555c5adcce062e005",
-     "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
-     "5b2f69b041596e8817d0a3c16f8fadeb"},
-    {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
-     "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
-     "f401823e04b05817243d2142a3589878",
-     "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
-     "534d9234d2351cf30e565de47baece0b",
-     "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
-     "353a18017f5b36bfc00b1f6dcb7ed485"},
-    {
-        "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
-        "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
-        "32b992760b3a5f99e9a47838867000a9",
-        "93c4fc6a4135f54d640b0c976bf755a06a292c33",
-        "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
-    {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
-     "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
-     "f4ee16c761b3c9aeac3da03aa9889c88",
-     "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
-     "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
-     "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
-     "9e3ac938d3eb0cadd6f5c9e35d22ba38",
-     "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
-     "d65dbd1378b196ac270588dd0621f642"},
-    {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
-     "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
-     "b0f1420be29ea547d42c713bc6af66aa",
-     "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
-     "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
-     "34a6039312774cedebf4961f3978b14a26509f96",
-     "e192c23cb036f0b31592989119eed55d",
-     "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
-     "f0a34bc305b88b804c60b90add594a17"},
-    {
-        "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
-        "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
-        "43edfd365b90d5b325950df0ada058f9",
-        "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
-        "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
-        "72c2cb136c8fd091cc4539877a5d1e72d607f960",
-        "8b347853f11d75e81e8a95010be81f17",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
-    {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
-     "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
-     "48f5b426baca03064554cc2b30"},
-    {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
-     "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
-     "46a2e55c8e264df211bd112685"},
-    {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
-     "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
-     "3b95b981086ee73cc4d0cc1422"},
-    {
-        "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
-        "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
-    test_group_0, test_group_1, test_group_2,
-    test_group_3, test_group_4, test_group_5,
-};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view ciphertext) {
-  uint64_t packet_number;
-  absl::string_view nonce_prefix(nonce.data(),
-                                 nonce.size() - sizeof(packet_number));
-  decrypter->SetNoncePrefix(nonce_prefix);
-  memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
-         sizeof(packet_number));
-  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
-  size_t output_length = 0;
-  const bool success = decrypter->DecryptPacket(
-      packet_number, associated_data, ciphertext, output.get(), &output_length,
-      ciphertext.length());
-  if (!success) {
-    return nullptr;
-  }
-  return new QuicData(output.release(), output_length, true);
-}
-
-class Aes128Gcm12DecrypterTest : public QuicTest {};
-
-TEST_F(Aes128Gcm12DecrypterTest, Decrypt) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
-    SCOPED_TRACE(i);
-    const TestVector* test_vectors = test_group_array[i];
-    const TestGroupInfo& test_info = test_group_info[i];
-    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
-      // If not present then decryption is expected to fail.
-      bool has_pt = test_vectors[j].pt;
-
-      // Decode the test vector.
-      std::string key = absl::HexStringToBytes(test_vectors[j].key);
-      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
-      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
-      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
-      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-      std::string pt;
-      if (has_pt) {
-        pt = absl::HexStringToBytes(test_vectors[j].pt);
-      }
-
-      // The test vector's lengths should look sane. Note that the lengths
-      // in |test_info| are in bits.
-      EXPECT_EQ(test_info.key_len, key.length() * 8);
-      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
-      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
-      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
-      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-      if (has_pt) {
-        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
-      }
-
-      // The test vectors have 16 byte authenticators but this code only uses
-      // the first 12.
-      ASSERT_LE(static_cast<size_t>(Aes128Gcm12Decrypter::kAuthTagSize),
-                tag.length());
-      tag.resize(Aes128Gcm12Decrypter::kAuthTagSize);
-      std::string ciphertext = ct + tag;
-
-      Aes128Gcm12Decrypter decrypter;
-      ASSERT_TRUE(decrypter.SetKey(key));
-
-      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
-          &decrypter, iv,
-          // This deliberately tests that the decrypter can
-          // handle an AAD that is set to nullptr, as opposed
-          // to a zero-length, non-nullptr pointer.
-          aad.length() ? aad : absl::string_view(), ciphertext));
-      if (!decrypted) {
-        EXPECT_FALSE(has_pt);
-        continue;
-      }
-      EXPECT_TRUE(has_pt);
-
-      ASSERT_EQ(pt.length(), decrypted->length());
-      quiche::test::CompareCharArraysWithHexError(
-          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
-    }
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_12_encrypter.cc b/quic/core/crypto/aes_128_gcm_12_encrypter.cc
deleted file mode 100644
index 075a21b..0000000
--- a/quic/core/crypto/aes_128_gcm_12_encrypter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-Aes128Gcm12Encrypter::Aes128Gcm12Encrypter()
-    : AesBaseEncrypter(EVP_aead_aes_128_gcm,
-                       kKeySize,
-                       kAuthTagSize,
-                       kNonceSize,
-                       /* use_ietf_nonce_construction */ false) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_12_encrypter.h b/quic/core/crypto/aes_128_gcm_12_encrypter.h
deleted file mode 100644
index f457336..0000000
--- a/quic/core/crypto/aes_128_gcm_12_encrypter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128Gcm12Encrypter is a QuicEncrypter that implements the
-// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
-// calling QuicEncrypter::Create(kAESG).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
-// of the nonce is four bytes.
-class QUIC_EXPORT_PRIVATE Aes128Gcm12Encrypter : public AesBaseEncrypter {
- public:
-  enum {
-    // Authentication tags are truncated to 96 bits.
-    kAuthTagSize = 12,
-  };
-
-  Aes128Gcm12Encrypter();
-  Aes128Gcm12Encrypter(const Aes128Gcm12Encrypter&) = delete;
-  Aes128Gcm12Encrypter& operator=(const Aes128Gcm12Encrypter&) = delete;
-  ~Aes128Gcm12Encrypter() override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
diff --git a/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
deleted file mode 100644
index 67e35ed..0000000
--- a/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = 11754cd72aec309bf52f7687212e8957
-// IV = 3c819d9a9bed087615030b65
-// PT =
-// AAD =
-// CT =
-// Tag = 250327c674aaf477aef2675748cf6971
-//
-// Count = 1
-// Key = ca47248ac0b6f8372a97ac43508308ed
-// IV = ffd2b598feabc9019262d2be
-// PT =
-// AAD =
-// CT =
-// Tag = 60d20404af527d248d893ae495707d1a
-//
-// ...
-//
-// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
-  size_t key_len;
-  size_t iv_len;
-  size_t pt_len;
-  size_t aad_len;
-  size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  const char* key;
-  const char* iv;
-  const char* pt;
-  const char* aad;
-  const char* ct;
-  const char* tag;
-};
-
-const TestGroupInfo test_group_info[] = {
-    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
-    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
-    {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
-     "250327c674aaf477aef2675748cf6971"},
-    {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
-     "60d20404af527d248d893ae495707d1a"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
-    {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
-     "7a43ec1d9c0a5a78a0b16533a6213cab", "",
-     "209fcc8d3675ed938e9c7166709dd946"},
-    {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
-     "c94c410194c765e3dcc7964379758ed3", "",
-     "94dca8edfcf90bb74b153c8d48a17930"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
-    {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
-     "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
-     "b36d1df9b9d5e596f83e8b7f52971cb3"},
-    {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
-     "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
-     "2b4401346697138c7a4891ee59867d0c"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
-    {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
-     "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
-     "b840382c4bccaf3bafb4ca8429bea063",
-     "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
-     "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
-     "3ddbc5db8778371495da76d269e5db3e",
-     "291ef1982e4defedaa2249f898556b47"},
-    {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
-     "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
-     "b764b9611f6c0f8641843d5d58f3a242",
-     "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
-     "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
-     "5506fde6309ffc19e716eddf1a828c5a",
-     "890147971946b627c40016da1ecf3e77"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
-    {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
-     "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
-     "8b5615ba7c1220ff6510e259f06655d8",
-     "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
-     "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
-     "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
-     "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
-     "b6ad57af43e1895df9dca2a5344a62cc",
-     "57a3ee28136e94c74838997ae9823f3a"},
-    {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
-     "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
-     "c2c6f6166f4a59431e182663fcaea05a",
-     "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
-     "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
-     "15d2e51398344b16bee1ed7c499b353d6c597af8",
-     "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
-     "3c7891c2a91fbc48db29967ec9542b23",
-     "21b51ca862cb637cdd03b99a0f93b134"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
-    {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
-     "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
-     "43fd4727fe5cdb4b5b42818dea7ef8c9"},
-    {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
-     "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
-     "38e6bcd29962e5f2c13626b85a877101"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
-    test_group_0, test_group_1, test_group_2,
-    test_group_3, test_group_4, test_group_5,
-};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view plaintext) {
-  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
-  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
-  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
-                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
-    return nullptr;
-  }
-
-  return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class Aes128Gcm12EncrypterTest : public QuicTest {};
-
-TEST_F(Aes128Gcm12EncrypterTest, Encrypt) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
-    SCOPED_TRACE(i);
-    const TestVector* test_vectors = test_group_array[i];
-    const TestGroupInfo& test_info = test_group_info[i];
-    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
-      // Decode the test vector.
-      std::string key = absl::HexStringToBytes(test_vectors[j].key);
-      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
-      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
-      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
-      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
-      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-
-      // The test vector's lengths should look sane. Note that the lengths
-      // in |test_info| are in bits.
-      EXPECT_EQ(test_info.key_len, key.length() * 8);
-      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
-      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
-      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
-      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
-      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-
-      Aes128Gcm12Encrypter encrypter;
-      ASSERT_TRUE(encrypter.SetKey(key));
-      std::unique_ptr<QuicData> encrypted(
-          EncryptWithNonce(&encrypter, iv,
-                           // This deliberately tests that the encrypter can
-                           // handle an AAD that is set to nullptr, as opposed
-                           // to a zero-length, non-nullptr pointer.
-                           aad.length() ? aad : absl::string_view(), pt));
-      ASSERT_TRUE(encrypted.get());
-
-      // The test vectors have 16 byte authenticators but this code only uses
-      // the first 12.
-      ASSERT_LE(static_cast<size_t>(Aes128Gcm12Encrypter::kAuthTagSize),
-                tag.length());
-      tag.resize(Aes128Gcm12Encrypter::kAuthTagSize);
-
-      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
-      quiche::test::CompareCharArraysWithHexError(
-          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
-      quiche::test::CompareCharArraysWithHexError(
-          "authentication tag", encrypted->data() + ct.length(), tag.length(),
-          tag.data(), tag.length());
-    }
-  }
-}
-
-TEST_F(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) {
-  Aes128Gcm12Encrypter encrypter;
-  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
-  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
-  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
-  EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
-}
-
-TEST_F(Aes128Gcm12EncrypterTest, GetCiphertextSize) {
-  Aes128Gcm12Encrypter encrypter;
-  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
-  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
-  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_decrypter.cc b/quic/core/crypto/aes_128_gcm_decrypter.cc
deleted file mode 100644
index d1def92..0000000
--- a/quic/core/crypto/aes_128_gcm_decrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-Aes128GcmDecrypter::Aes128GcmDecrypter()
-    : AesBaseDecrypter(EVP_aead_aes_128_gcm,
-                       kKeySize,
-                       kAuthTagSize,
-                       kNonceSize,
-                       /* use_ietf_nonce_construction */ true) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128GcmDecrypter::~Aes128GcmDecrypter() {}
-
-uint32_t Aes128GcmDecrypter::cipher_id() const {
-  return TLS1_CK_AES_128_GCM_SHA256;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_decrypter.h b/quic/core/crypto/aes_128_gcm_decrypter.h
deleted file mode 100644
index b9b3c68..0000000
--- a/quic/core/crypto/aes_128_gcm_decrypter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128GcmDecrypter is a QuicDecrypter that implements the
-// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes128GcmDecrypter : public AesBaseDecrypter {
- public:
-  enum {
-    kAuthTagSize = 16,
-  };
-
-  Aes128GcmDecrypter();
-  Aes128GcmDecrypter(const Aes128GcmDecrypter&) = delete;
-  Aes128GcmDecrypter& operator=(const Aes128GcmDecrypter&) = delete;
-  ~Aes128GcmDecrypter() override;
-
-  uint32_t cipher_id() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
diff --git a/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/quic/core/crypto/aes_128_gcm_decrypter_test.cc
deleted file mode 100644
index 25abd71..0000000
--- a/quic/core/crypto/aes_128_gcm_decrypter_test.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmDecrypt128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = cf063a34d4a9a76c2c86787d3f96db71
-// IV = 113b9785971864c83b01c787
-// CT =
-// AAD =
-// Tag = 72ac8493e3a5228b5d130a69d2510e42
-// PT =
-//
-// Count = 1
-// Key = a49a5e26a2f8cb63d05546c2a62f5343
-// IV = 907763b19b9b4ab6bd4f0281
-// CT =
-// AAD =
-// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
-// FAIL
-//
-// ...
-//
-// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
-  size_t key_len;
-  size_t iv_len;
-  size_t pt_len;
-  size_t aad_len;
-  size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  // Input:
-  const char* key;
-  const char* iv;
-  const char* ct;
-  const char* aad;
-  const char* tag;
-
-  // Expected output:
-  const char* pt;  // An empty string "" means decryption succeeded and
-                   // the plaintext is zero-length. nullptr means decryption
-                   // failed.
-};
-
-const TestGroupInfo test_group_info[] = {
-    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
-    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
-    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
-     "72ac8493e3a5228b5d130a69d2510e42", ""},
-    {
-        "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
-        "a2be08210d8c470a8df6e8fbd79ec5cf",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
-    {
-        "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
-        "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
-        nullptr  // FAIL
-    },
-    {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
-     "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
-     ""},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
-    {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
-     "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
-     "28286a321293253c3e0aa2704a278032"},
-    {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
-     "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
-     "95695a5b12f2870b9cc5fdc8f218a97d"},
-    {
-        "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
-        "0216c899c88d6e32c958c7e553daa5bc", "",
-        "a145319896329c96df291f64efbe0e3a",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
-    {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
-     "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
-     "338b22f9bad09093276a331e9c79c7f4",
-     "41dc38988945fcb44faf2ef72d0061289ef8efd8",
-     "4f71e72bde0018f555c5adcce062e005",
-     "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
-     "5b2f69b041596e8817d0a3c16f8fadeb"},
-    {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
-     "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
-     "f401823e04b05817243d2142a3589878",
-     "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
-     "534d9234d2351cf30e565de47baece0b",
-     "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
-     "353a18017f5b36bfc00b1f6dcb7ed485"},
-    {
-        "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
-        "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
-        "32b992760b3a5f99e9a47838867000a9",
-        "93c4fc6a4135f54d640b0c976bf755a06a292c33",
-        "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
-    {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
-     "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
-     "f4ee16c761b3c9aeac3da03aa9889c88",
-     "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
-     "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
-     "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
-     "9e3ac938d3eb0cadd6f5c9e35d22ba38",
-     "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
-     "d65dbd1378b196ac270588dd0621f642"},
-    {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
-     "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
-     "b0f1420be29ea547d42c713bc6af66aa",
-     "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
-     "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
-     "34a6039312774cedebf4961f3978b14a26509f96",
-     "e192c23cb036f0b31592989119eed55d",
-     "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
-     "f0a34bc305b88b804c60b90add594a17"},
-    {
-        "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
-        "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
-        "43edfd365b90d5b325950df0ada058f9",
-        "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
-        "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
-        "72c2cb136c8fd091cc4539877a5d1e72d607f960",
-        "8b347853f11d75e81e8a95010be81f17",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
-    {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
-     "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
-     "48f5b426baca03064554cc2b30"},
-    {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
-     "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
-     "46a2e55c8e264df211bd112685"},
-    {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
-     "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
-     "3b95b981086ee73cc4d0cc1422"},
-    {
-        "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
-        "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
-    test_group_0, test_group_1, test_group_2,
-    test_group_3, test_group_4, test_group_5,
-};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view ciphertext) {
-  decrypter->SetIV(nonce);
-  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
-  size_t output_length = 0;
-  const bool success =
-      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
-                               &output_length, ciphertext.length());
-  if (!success) {
-    return nullptr;
-  }
-  return new QuicData(output.release(), output_length, true);
-}
-
-class Aes128GcmDecrypterTest : public QuicTest {};
-
-TEST_F(Aes128GcmDecrypterTest, Decrypt) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
-    SCOPED_TRACE(i);
-    const TestVector* test_vectors = test_group_array[i];
-    const TestGroupInfo& test_info = test_group_info[i];
-    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
-      // If not present then decryption is expected to fail.
-      bool has_pt = test_vectors[j].pt;
-
-      // Decode the test vector.
-      std::string key = absl::HexStringToBytes(test_vectors[j].key);
-      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
-      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
-      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
-      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-      std::string pt;
-      if (has_pt) {
-        pt = absl::HexStringToBytes(test_vectors[j].pt);
-      }
-
-      // The test vector's lengths should look sane. Note that the lengths
-      // in |test_info| are in bits.
-      EXPECT_EQ(test_info.key_len, key.length() * 8);
-      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
-      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
-      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
-      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-      if (has_pt) {
-        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
-      }
-      std::string ciphertext = ct + tag;
-
-      Aes128GcmDecrypter decrypter;
-      ASSERT_TRUE(decrypter.SetKey(key));
-
-      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
-          &decrypter, iv,
-          // This deliberately tests that the decrypter can
-          // handle an AAD that is set to nullptr, as opposed
-          // to a zero-length, non-nullptr pointer.
-          aad.length() ? aad : absl::string_view(), ciphertext));
-      if (!decrypted) {
-        EXPECT_FALSE(has_pt);
-        continue;
-      }
-      EXPECT_TRUE(has_pt);
-
-      ASSERT_EQ(pt.length(), decrypted->length());
-      quiche::test::CompareCharArraysWithHexError(
-          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
-    }
-  }
-}
-
-TEST_F(Aes128GcmDecrypterTest, GenerateHeaderProtectionMask) {
-  Aes128GcmDecrypter decrypter;
-  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
-  std::string sample =
-      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
-  QuicDataReader sample_reader(sample.data(), sample.size());
-  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
-  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
-  std::string expected_mask =
-      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
-  quiche::test::CompareCharArraysWithHexError(
-      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
-      expected_mask.size());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_encrypter.cc b/quic/core/crypto/aes_128_gcm_encrypter.cc
deleted file mode 100644
index 1cf2817..0000000
--- a/quic/core/crypto/aes_128_gcm_encrypter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 16;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-Aes128GcmEncrypter::Aes128GcmEncrypter()
-    : AesBaseEncrypter(EVP_aead_aes_128_gcm,
-                       kKeySize,
-                       kAuthTagSize,
-                       kNonceSize,
-                       /* use_ietf_nonce_construction */ true) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes128GcmEncrypter::~Aes128GcmEncrypter() {}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_128_gcm_encrypter.h b/quic/core/crypto/aes_128_gcm_encrypter.h
deleted file mode 100644
index c385de3..0000000
--- a/quic/core/crypto/aes_128_gcm_encrypter.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes128GcmEncrypter is a QuicEncrypter that implements the
-// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes128GcmEncrypter : public AesBaseEncrypter {
- public:
-  enum {
-    kAuthTagSize = 16,
-  };
-
-  Aes128GcmEncrypter();
-  Aes128GcmEncrypter(const Aes128GcmEncrypter&) = delete;
-  Aes128GcmEncrypter& operator=(const Aes128GcmEncrypter&) = delete;
-  ~Aes128GcmEncrypter() override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
diff --git a/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/quic/core/crypto/aes_128_gcm_encrypter_test.cc
deleted file mode 100644
index 7e5fb25..0000000
--- a/quic/core/crypto/aes_128_gcm_encrypter_test.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
-// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
-// 2013-02-01. The test vectors in that file look like this:
-//
-// [Keylen = 128]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = 11754cd72aec309bf52f7687212e8957
-// IV = 3c819d9a9bed087615030b65
-// PT =
-// AAD =
-// CT =
-// Tag = 250327c674aaf477aef2675748cf6971
-//
-// Count = 1
-// Key = ca47248ac0b6f8372a97ac43508308ed
-// IV = ffd2b598feabc9019262d2be
-// PT =
-// AAD =
-// CT =
-// Tag = 60d20404af527d248d893ae495707d1a
-//
-// ...
-//
-// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
-// few test vectors for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
-  size_t key_len;
-  size_t iv_len;
-  size_t pt_len;
-  size_t aad_len;
-  size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  const char* key;
-  const char* iv;
-  const char* pt;
-  const char* aad;
-  const char* ct;
-  const char* tag;
-};
-
-const TestGroupInfo test_group_info[] = {
-    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
-    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
-    {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
-     "250327c674aaf477aef2675748cf6971"},
-    {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
-     "60d20404af527d248d893ae495707d1a"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
-    {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
-     "7a43ec1d9c0a5a78a0b16533a6213cab", "",
-     "209fcc8d3675ed938e9c7166709dd946"},
-    {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
-     "c94c410194c765e3dcc7964379758ed3", "",
-     "94dca8edfcf90bb74b153c8d48a17930"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
-    {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
-     "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
-     "b36d1df9b9d5e596f83e8b7f52971cb3"},
-    {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
-     "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
-     "2b4401346697138c7a4891ee59867d0c"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
-    {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
-     "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
-     "b840382c4bccaf3bafb4ca8429bea063",
-     "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
-     "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
-     "3ddbc5db8778371495da76d269e5db3e",
-     "291ef1982e4defedaa2249f898556b47"},
-    {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
-     "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
-     "b764b9611f6c0f8641843d5d58f3a242",
-     "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
-     "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
-     "5506fde6309ffc19e716eddf1a828c5a",
-     "890147971946b627c40016da1ecf3e77"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
-    {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
-     "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
-     "8b5615ba7c1220ff6510e259f06655d8",
-     "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
-     "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
-     "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
-     "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
-     "b6ad57af43e1895df9dca2a5344a62cc",
-     "57a3ee28136e94c74838997ae9823f3a"},
-    {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
-     "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
-     "c2c6f6166f4a59431e182663fcaea05a",
-     "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
-     "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
-     "15d2e51398344b16bee1ed7c499b353d6c597af8",
-     "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
-     "3c7891c2a91fbc48db29967ec9542b23",
-     "21b51ca862cb637cdd03b99a0f93b134"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
-    {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
-     "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
-     "43fd4727fe5cdb4b5b42818dea7ef8c9"},
-    {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
-     "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
-     "38e6bcd29962e5f2c13626b85a877101"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
-    test_group_0, test_group_1, test_group_2,
-    test_group_3, test_group_4, test_group_5,
-};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view plaintext) {
-  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
-  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
-  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
-                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
-    return nullptr;
-  }
-
-  return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class Aes128GcmEncrypterTest : public QuicTest {};
-
-TEST_F(Aes128GcmEncrypterTest, Encrypt) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
-    SCOPED_TRACE(i);
-    const TestVector* test_vectors = test_group_array[i];
-    const TestGroupInfo& test_info = test_group_info[i];
-    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
-      // Decode the test vector.
-      std::string key = absl::HexStringToBytes(test_vectors[j].key);
-      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
-      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
-      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
-      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
-      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-
-      // The test vector's lengths should look sane. Note that the lengths
-      // in |test_info| are in bits.
-      EXPECT_EQ(test_info.key_len, key.length() * 8);
-      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
-      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
-      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
-      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
-      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-
-      Aes128GcmEncrypter encrypter;
-      ASSERT_TRUE(encrypter.SetKey(key));
-      std::unique_ptr<QuicData> encrypted(
-          EncryptWithNonce(&encrypter, iv,
-                           // This deliberately tests that the encrypter can
-                           // handle an AAD that is set to nullptr, as opposed
-                           // to a zero-length, non-nullptr pointer.
-                           aad.length() ? aad : absl::string_view(), pt));
-      ASSERT_TRUE(encrypted.get());
-
-      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
-      quiche::test::CompareCharArraysWithHexError(
-          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
-      quiche::test::CompareCharArraysWithHexError(
-          "authentication tag", encrypted->data() + ct.length(), tag.length(),
-          tag.data(), tag.length());
-    }
-  }
-}
-
-TEST_F(Aes128GcmEncrypterTest, EncryptPacket) {
-  std::string key = absl::HexStringToBytes("d95a145250826c25a77b6a84fd4d34fc");
-  std::string iv = absl::HexStringToBytes("50c4431ebb18283448e276e2");
-  uint64_t packet_num = 0x13278f44;
-  std::string aad =
-      absl::HexStringToBytes("875d49f64a70c9cbe713278f44ff000005");
-  std::string pt = absl::HexStringToBytes("aa0003a250bd000000000001");
-  std::string ct = absl::HexStringToBytes(
-      "7dd4708b989ee7d38a013e3656e9b37beefd05808fe1ab41e3b4f2c0");
-
-  std::vector<char> out(ct.size());
-  size_t out_size;
-
-  Aes128GcmEncrypter encrypter;
-  ASSERT_TRUE(encrypter.SetKey(key));
-  ASSERT_TRUE(encrypter.SetIV(iv));
-  ASSERT_TRUE(encrypter.EncryptPacket(packet_num, aad, pt, out.data(),
-                                      &out_size, out.size()));
-  EXPECT_EQ(out_size, out.size());
-  quiche::test::CompareCharArraysWithHexError("ciphertext", out.data(),
-                                              out.size(), ct.data(), ct.size());
-}
-
-TEST_F(Aes128GcmEncrypterTest, GetMaxPlaintextSize) {
-  Aes128GcmEncrypter encrypter;
-  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
-  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
-  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
-}
-
-TEST_F(Aes128GcmEncrypterTest, GetCiphertextSize) {
-  Aes128GcmEncrypter encrypter;
-  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
-  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
-  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
-}
-
-TEST_F(Aes128GcmEncrypterTest, GenerateHeaderProtectionMask) {
-  Aes128GcmEncrypter encrypter;
-  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
-  std::string sample =
-      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
-  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
-  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
-  std::string expected_mask =
-      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
-  quiche::test::CompareCharArraysWithHexError(
-      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
-      expected_mask.size());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aes_256_gcm_decrypter.cc b/quic/core/crypto/aes_256_gcm_decrypter.cc
deleted file mode 100644
index 50980b7..0000000
--- a/quic/core/crypto/aes_256_gcm_decrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-Aes256GcmDecrypter::Aes256GcmDecrypter()
-    : AesBaseDecrypter(EVP_aead_aes_256_gcm,
-                       kKeySize,
-                       kAuthTagSize,
-                       kNonceSize,
-                       /* use_ietf_nonce_construction */ true) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes256GcmDecrypter::~Aes256GcmDecrypter() {}
-
-uint32_t Aes256GcmDecrypter::cipher_id() const {
-  return TLS1_CK_AES_256_GCM_SHA384;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_256_gcm_decrypter.h b/quic/core/crypto/aes_256_gcm_decrypter.h
deleted file mode 100644
index 6cc451b..0000000
--- a/quic/core/crypto/aes_256_gcm_decrypter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes256GcmDecrypter is a QuicDecrypter that implements the
-// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes256GcmDecrypter : public AesBaseDecrypter {
- public:
-  enum {
-    kAuthTagSize = 16,
-  };
-
-  Aes256GcmDecrypter();
-  Aes256GcmDecrypter(const Aes256GcmDecrypter&) = delete;
-  Aes256GcmDecrypter& operator=(const Aes256GcmDecrypter&) = delete;
-  ~Aes256GcmDecrypter() override;
-
-  uint32_t cipher_id() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
diff --git a/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/quic/core/crypto/aes_256_gcm_decrypter_test.cc
deleted file mode 100644
index c63a589..0000000
--- a/quic/core/crypto/aes_256_gcm_decrypter_test.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmDecrypt256.rsp
-// downloaded from
-// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
-// on 2017-09-27. The test vectors in that file look like this:
-//
-// [Keylen = 256]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010
-// IV = 58d2240f580a31c1d24948e9
-// CT =
-// AAD =
-// Tag = 15e051a5e4a5f5da6cea92e2ebee5bac
-// PT =
-//
-// Count = 1
-// Key = e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831
-// IV = 51e43385bf533e168427e1ad
-// CT =
-// AAD =
-// Tag = 38fe845c66e66bdd884c2aecafd280e6
-// FAIL
-//
-// ...
-//
-// The gcmDecrypt256.rsp file is huge (3.0 MB), so a few test vectors were
-// selected for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
-  size_t key_len;
-  size_t iv_len;
-  size_t pt_len;
-  size_t aad_len;
-  size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  // Input:
-  const char* key;
-  const char* iv;
-  const char* ct;
-  const char* aad;
-  const char* tag;
-
-  // Expected output:
-  const char* pt;  // An empty string "" means decryption succeeded and
-                   // the plaintext is zero-length. nullptr means decryption
-                   // failed.
-};
-
-const TestGroupInfo test_group_info[] = {
-    {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
-    {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
-    {"f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010",
-     "58d2240f580a31c1d24948e9", "", "", "15e051a5e4a5f5da6cea92e2ebee5bac",
-     ""},
-    {
-        "e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831",
-        "51e43385bf533e168427e1ad", "", "", "38fe845c66e66bdd884c2aecafd280e6",
-        nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
-    {"6dfdafd6703c285c01f14fd10a6012862b2af950d4733abb403b2e745b26945d",
-     "3749d0b3d5bacb71be06ade6", "", "c0d249871992e70302ae008193d1e89f",
-     "4aa4cc69f84ee6ac16d9bfb4e05de500", ""},
-    {
-        "2c392a5eb1a9c705371beda3a901c7c61dca4d93b4291de1dd0dd15ec11ffc45",
-        "0723fb84a08f4ea09841f32a", "", "140be561b6171eab942c486a94d33d43",
-        "aa0e1c9b57975bfc91aa137231977d2c", nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
-    {"4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8",
-     "473360e0ad24889959858995", "d2c78110ac7e8f107c0df0570bd7c90c", "",
-     "c26a379b6d98ef2852ead8ce83a833a7", "7789b41cb3ee548814ca0b388c10b343"},
-    {"3934f363fd9f771352c4c7a060682ed03c2864223a1573b3af997e2ababd60ab",
-     "efe2656d878c586e41c539c4", "e0de64302ac2d04048d65a87d2ad09fe", "",
-     "33cbd8d2fb8a3a03e30c1eb1b53c1d99", "697aff2d6b77e5ed6232770e400c1ead"},
-    {
-        "c997768e2d14e3d38259667a6649079de77beb4543589771e5068e6cd7cd0b14",
-        "835090aed9552dbdd45277e2", "9f6607d68e22ccf21928db0986be126e", "",
-        "f32617f67c574fd9f44ef76ff880ab9f", nullptr  // FAIL
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
-    {
-        "e9d381a9c413bee66175d5586a189836e5c20f5583535ab4d3f3e612dc21700e",
-        "23e81571da1c7821c681c7ca",
-        "a25f3f580306cd5065d22a6b7e9660110af7204bb77d370f7f34bee547feeff7b32a59"
-        "6fce29c9040e68b1589aad48da881990",
-        "6f39c9ae7b8e8a58a95f0dd8ea6a9087cbccdfd6",
-        "5b6dcd70eefb0892fab1539298b92a4b",
-        nullptr  // FAIL
-    },
-    {"6450d4501b1e6cfbe172c4c8570363e96b496591b842661c28c2f6c908379cad",
-     "7e4262035e0bf3d60e91668a",
-     "5a99b336fd3cfd82f10fb08f7045012415f0d9a06bb92dcf59c6f0dbe62d433671aacb8a1"
-     "c52ce7bbf6aea372bf51e2ba79406",
-     "f1c522f026e4c5d43851da516a1b78768ab18171",
-     "fe93b01636f7bb0458041f213e98de65",
-     "17449e236ef5858f6d891412495ead4607bfae2a2d735182a2a0242f9d52fc5345ef912db"
-     "e16f3bb4576fe3bcafe336dee6085"},
-    {"90f2e71ccb1148979cb742efc8f921de95457d898c84ce28edeed701650d3a26",
-     "aba58ad60047ba553f6e4c98",
-     "3fc77a5fe9203d091c7916587c9763cf2e4d0d53ca20b078b851716f1dab4873fe342b7b3"
-     "01402f015d00263bf3f77c58a99d6",
-     "2abe465df6e5be47f05b92c9a93d76ae3611fac5",
-     "9cb3d04637048bc0bddef803ffbb56cf",
-     "1d21639640e11638a2769e3fab78778f84be3f4a8ce28dfd99cb2e75171e05ea8e94e30aa"
-     "78b54bb402b39d613616a8ed951dc"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
-    {
-        "e36aca93414b13f5313e76a7244588ee116551d1f34c32859166f2eb0ac1a9b7",
-        "e9e701b1ccef6bddd03391d8",
-        "5b059ac6733b6de0e8cf5b88b7301c02c993426f71bb12abf692e9deeacfac1ff1644c"
-        "87d4df130028f515f0feda636309a24d",
-        "6a08fe6e55a08f283cec4c4b37676e770f402af6102f548ad473ec6236da764f7076ff"
-        "d41bbd9611b439362d899682b7b0f839fc5a68d9df54afd1e2b3c4e7d072454ee27111"
-        "d52193d28b9c4f925d2a8b451675af39191a2cba",
-        "43c7c9c93cc265fc8e192000e0417b5b",
-        nullptr  // FAIL
-    },
-    {"5f72046245d3f4a0877e50a86554bfd57d1c5e073d1ed3b5451f6d0fc2a8507a",
-     "ea6f5b391e44b751b26bce6f",
-     "0e6e0b2114c40769c15958d965a14dcf50b680e0185a4409d77d894ca15b1e698dd83b353"
-     "6b18c05d8cd0873d1edce8150ecb5",
-     "9b3a68c941d42744673fb60fea49075eae77322e7e70e34502c115b6495ebfc796d629080"
-     "7653c6b53cd84281bd0311656d0013f44619d2748177e99e8f8347c989a7b59f9d8dcf00f"
-     "31db0684a4a83e037e8777bae55f799b0d",
-     "fdaaff86ceb937502cd9012d03585800",
-     "b0a881b751cc1eb0c912a4cf9bd971983707dbd2411725664503455c55db25cdb19bc669c"
-     "2654a3a8011de6bf7eff3f9f07834"},
-    {"ab639bae205547607506522bd3cdca7861369e2b42ef175ff135f6ba435d5a8e",
-     "5fbb63eb44bd59fee458d8f6",
-     "9a34c62bed0972285503a32812877187a54dedbd55d2317fed89282bf1af4ba0b6bb9f9e1"
-     "6dd86da3b441deb7841262bc6bd63",
-     "1ef2b1768b805587935ffaf754a11bd2a305076d6374f1f5098b1284444b78f55408a786d"
-     "a37e1b7f1401c330d3585ef56f3e4d35eaaac92e1381d636477dc4f4beaf559735e902d6b"
-     "e58723257d4ac1ed9bd213de387f35f3c4",
-     "e0299e079bff46fd12e36d1c60e41434",
-     "e5a3ce804a8516cdd12122c091256b789076576040dbf3c55e8be3c016025896b8a72532b"
-     "fd51196cc82efca47aa0fd8e2e0dc"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
-    {
-        "8b37c4b8cf634704920059866ad96c49e9da502c63fca4a3a7a4dcec74cb0610",
-        "cb59344d2b06c4ae57cd0ea4", "66ab935c93555e786b775637a3", "",
-        "d8733acbb564d8afaa99d7ca2e2f92a9", nullptr  // FAIL
-    },
-    {"a71dac1377a3bf5d7fb1b5e36bee70d2e01de2a84a1c1009ba7448f7f26131dc",
-     "c5b60dda3f333b1146e9da7c", "43af49ec1ae3738a20755034d6", "",
-     "6f80b6ef2d8830a55eb63680a8dff9e0", "5b87141335f2becac1a559e05f"},
-    {"dc1f64681014be221b00793bbcf5a5bc675b968eb7a3a3d5aa5978ef4fa45ecc",
-     "056ae9a1a69e38af603924fe", "33013a48d9ea0df2911d583271", "",
-     "5b8f9cc22303e979cd1524187e9f70fe", "2a7e05612191c8bce2f529dca9"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
-    test_group_0, test_group_1, test_group_2,
-    test_group_3, test_group_4, test_group_5,
-};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view ciphertext) {
-  decrypter->SetIV(nonce);
-  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
-  size_t output_length = 0;
-  const bool success =
-      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
-                               &output_length, ciphertext.length());
-  if (!success) {
-    return nullptr;
-  }
-  return new QuicData(output.release(), output_length, true);
-}
-
-class Aes256GcmDecrypterTest : public QuicTest {};
-
-TEST_F(Aes256GcmDecrypterTest, Decrypt) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
-    SCOPED_TRACE(i);
-    const TestVector* test_vectors = test_group_array[i];
-    const TestGroupInfo& test_info = test_group_info[i];
-    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
-      // If not present then decryption is expected to fail.
-      bool has_pt = test_vectors[j].pt;
-
-      // Decode the test vector.
-      std::string key = absl::HexStringToBytes(test_vectors[j].key);
-      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
-      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
-      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
-      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-      std::string pt;
-      if (has_pt) {
-        pt = absl::HexStringToBytes(test_vectors[j].pt);
-      }
-
-      // The test vector's lengths should look sane. Note that the lengths
-      // in |test_info| are in bits.
-      EXPECT_EQ(test_info.key_len, key.length() * 8);
-      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
-      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
-      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
-      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-      if (has_pt) {
-        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
-      }
-      std::string ciphertext = ct + tag;
-
-      Aes256GcmDecrypter decrypter;
-      ASSERT_TRUE(decrypter.SetKey(key));
-
-      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
-          &decrypter, iv,
-          // This deliberately tests that the decrypter can
-          // handle an AAD that is set to nullptr, as opposed
-          // to a zero-length, non-nullptr pointer.
-          aad.length() ? aad : absl::string_view(), ciphertext));
-      if (!decrypted) {
-        EXPECT_FALSE(has_pt);
-        continue;
-      }
-      EXPECT_TRUE(has_pt);
-
-      ASSERT_EQ(pt.length(), decrypted->length());
-      quiche::test::CompareCharArraysWithHexError(
-          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
-    }
-  }
-}
-
-TEST_F(Aes256GcmDecrypterTest, GenerateHeaderProtectionMask) {
-  Aes256GcmDecrypter decrypter;
-  std::string key = absl::HexStringToBytes(
-      "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
-  std::string sample =
-      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
-  QuicDataReader sample_reader(sample.data(), sample.size());
-  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
-  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
-  std::string expected_mask =
-      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
-  quiche::test::CompareCharArraysWithHexError(
-      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
-      expected_mask.size());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aes_256_gcm_encrypter.cc b/quic/core/crypto/aes_256_gcm_encrypter.cc
deleted file mode 100644
index 0632496..0000000
--- a/quic/core/crypto/aes_256_gcm_encrypter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-Aes256GcmEncrypter::Aes256GcmEncrypter()
-    : AesBaseEncrypter(EVP_aead_aes_256_gcm,
-                       kKeySize,
-                       kAuthTagSize,
-                       kNonceSize,
-                       /* use_ietf_nonce_construction */ true) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-Aes256GcmEncrypter::~Aes256GcmEncrypter() {}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_256_gcm_encrypter.h b/quic/core/crypto/aes_256_gcm_encrypter.h
deleted file mode 100644
index 7183fb7..0000000
--- a/quic/core/crypto/aes_256_gcm_encrypter.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An Aes256GcmEncrypter is a QuicEncrypter that implements the
-// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE Aes256GcmEncrypter : public AesBaseEncrypter {
- public:
-  enum {
-    kAuthTagSize = 16,
-  };
-
-  Aes256GcmEncrypter();
-  Aes256GcmEncrypter(const Aes256GcmEncrypter&) = delete;
-  Aes256GcmEncrypter& operator=(const Aes256GcmEncrypter&) = delete;
-  ~Aes256GcmEncrypter() override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
diff --git a/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/quic/core/crypto/aes_256_gcm_encrypter_test.cc
deleted file mode 100644
index a2f8066..0000000
--- a/quic/core/crypto/aes_256_gcm_encrypter_test.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_256_gcm_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The AES GCM test vectors come from the file gcmEncryptExtIV256.rsp
-// downloaded from
-// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
-// on 2017-09-27. The test vectors in that file look like this:
-//
-// [Keylen = 256]
-// [IVlen = 96]
-// [PTlen = 0]
-// [AADlen = 0]
-// [Taglen = 128]
-//
-// Count = 0
-// Key = b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4
-// IV = 516c33929df5a3284ff463d7
-// PT =
-// AAD =
-// CT =
-// Tag = bdc1ac884d332457a1d2664f168c76f0
-//
-// Count = 1
-// Key = 5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f
-// IV = 770ac1a5a3d476d5d96944a1
-// PT =
-// AAD =
-// CT =
-// Tag = 196d691e1047093ca4b3d2ef4baba216
-//
-// ...
-//
-// The gcmEncryptExtIV256.rsp file is huge (3.2 MB), so a few test vectors were
-// selected for this unit test.
-
-// Describes a group of test vectors that all have a given key length, IV
-// length, plaintext length, AAD length, and tag length.
-struct TestGroupInfo {
-  size_t key_len;
-  size_t iv_len;
-  size_t pt_len;
-  size_t aad_len;
-  size_t tag_len;
-};
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  const char* key;
-  const char* iv;
-  const char* pt;
-  const char* aad;
-  const char* ct;
-  const char* tag;
-};
-
-const TestGroupInfo test_group_info[] = {
-    {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
-    {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
-};
-
-const TestVector test_group_0[] = {
-    {"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4",
-     "516c33929df5a3284ff463d7", "", "", "",
-     "bdc1ac884d332457a1d2664f168c76f0"},
-    {"5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f",
-     "770ac1a5a3d476d5d96944a1", "", "", "",
-     "196d691e1047093ca4b3d2ef4baba216"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_1[] = {
-    {"78dc4e0aaf52d935c3c01eea57428f00ca1fd475f5da86a49c8dd73d68c8e223",
-     "d79cf22d504cc793c3fb6c8a", "", "b96baa8c1c75a671bfb2d08d06be5f36", "",
-     "3e5d486aa2e30b22e040b85723a06e76"},
-    {"4457ff33683cca6ca493878bdc00373893a9763412eef8cddb54f91318e0da88",
-     "699d1f29d7b8c55300bb1fd2", "", "6749daeea367d0e9809e2dc2f309e6e3", "",
-     "d60c74d2517fde4a74e0cd4709ed43a9"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_2[] = {
-    {"31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22",
-     "0d18e06c7c725ac9e362e1ce", "2db5168e932556f8089a0622981d017d", "",
-     "fa4362189661d163fcd6a56d8bf0405a", "d636ac1bbedd5cc3ee727dc2ab4a9489"},
-    {"460fc864972261c2560e1eb88761ff1c992b982497bd2ac36c04071cbb8e5d99",
-     "8a4a16b9e210eb68bcb6f58d", "99e4e926ffe927f691893fb79a96b067", "",
-     "133fc15751621b5f325c7ff71ce08324", "ec4e87e0cf74a13618d0b68636ba9fa7"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_3[] = {
-    {"24501ad384e473963d476edcfe08205237acfd49b5b8f33857f8114e863fec7f",
-     "9ff18563b978ec281b3f2794",
-     "27f348f9cdc0c5bd5e66b1ccb63ad920ff2219d14e8d631b3872265cf117ee86757accb15"
-     "8bd9abb3868fdc0d0b074b5f01b2c",
-     "adb5ec720ccf9898500028bf34afccbcaca126ef",
-     "eb7cb754c824e8d96f7c6d9b76c7d26fb874ffbf1d65c6f64a698d839b0b06145dae82057"
-     "ad55994cf59ad7f67c0fa5e85fab8",
-     "bc95c532fecc594c36d1550286a7a3f0"},
-    {"fb43f5ab4a1738a30c1e053d484a94254125d55dccee1ad67c368bc1a985d235",
-     "9fbb5f8252db0bca21f1c230",
-     "34b797bb82250e23c5e796db2c37e488b3b99d1b981cea5e5b0c61a0b39adb6bd6ef1f507"
-     "22e2e4f81115cfcf53f842e2a6c08",
-     "98f8ae1735c39f732e2cbee1156dabeb854ec7a2",
-     "871cd53d95a8b806bd4821e6c4456204d27fd704ba3d07ce25872dc604ea5c5ea13322186"
-     "b7489db4fa060c1fd4159692612c8",
-     "07b48e4a32fac47e115d7ac7445d8330"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_4[] = {
-    {"148579a3cbca86d5520d66c0ec71ca5f7e41ba78e56dc6eebd566fed547fe691",
-     "b08a5ea1927499c6ecbfd4e0",
-     "9d0b15fdf1bd595f91f8b3abc0f7dec927dfd4799935a1795d9ce00c9b879434420fe42c2"
-     "75a7cd7b39d638fb81ca52b49dc41",
-     "e4f963f015ffbb99ee3349bbaf7e8e8e6c2a71c230a48f9d59860a29091d2747e01a5ca57"
-     "2347e247d25f56ba7ae8e05cde2be3c97931292c02370208ecd097ef692687fecf2f419d3"
-     "200162a6480a57dad408a0dfeb492e2c5d",
-     "2097e372950a5e9383c675e89eea1c314f999159f5611344b298cda45e62843716f215f82"
-     "ee663919c64002a5c198d7878fd3f",
-     "adbecdb0d5c2224d804d2886ff9a5760"},
-    {"e49af19182faef0ebeeba9f2d3be044e77b1212358366e4ef59e008aebcd9788",
-     "e7f37d79a6a487a5a703edbb",
-     "461cd0caf7427a3d44408d825ed719237272ecd503b9094d1f62c97d63ed83a0b50bdc804"
-     "ffdd7991da7a5b6dcf48d4bcd2cbc",
-     "19a9a1cfc647346781bef51ed9070d05f99a0e0192a223c5cd2522dbdf97d9739dd39fb17"
-     "8ade3339e68774b058aa03e9a20a9a205bc05f32381df4d63396ef691fefd5a71b49a2ad8"
-     "2d5ea428778ca47ee1398792762413cff4",
-     "32ca3588e3e56eb4c8301b009d8b84b8a900b2b88ca3c21944205e9dd7311757b51394ae9"
-     "0d8bb3807b471677614f4198af909",
-     "3e403d035c71d88f1be1a256c89ba6ad"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector test_group_5[] = {
-    {"82c4f12eeec3b2d3d157b0f992d292b237478d2cecc1d5f161389b97f999057a",
-     "7b40b20f5f397177990ef2d1", "982a296ee1cd7086afad976945", "",
-     "ec8e05a0471d6b43a59ca5335f", "113ddeafc62373cac2f5951bb9165249"},
-    {"db4340af2f835a6c6d7ea0ca9d83ca81ba02c29b7410f221cb6071114e393240",
-     "40e438357dd80a85cac3349e", "8ddb3397bd42853193cb0f80c9", "",
-     "b694118c85c41abf69e229cb0f", "c07f1b8aafbd152f697eb67f2a85fe45"},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-const TestVector* const test_group_array[] = {
-    test_group_0, test_group_1, test_group_2,
-    test_group_3, test_group_4, test_group_5,
-};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view plaintext) {
-  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
-  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
-  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
-                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
-    return nullptr;
-  }
-
-  return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class Aes256GcmEncrypterTest : public QuicTest {};
-
-TEST_F(Aes256GcmEncrypterTest, Encrypt) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
-    SCOPED_TRACE(i);
-    const TestVector* test_vectors = test_group_array[i];
-    const TestGroupInfo& test_info = test_group_info[i];
-    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
-      // Decode the test vector.
-      std::string key = absl::HexStringToBytes(test_vectors[j].key);
-      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
-      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
-      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
-      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
-      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
-
-      // The test vector's lengths should look sane. Note that the lengths
-      // in |test_info| are in bits.
-      EXPECT_EQ(test_info.key_len, key.length() * 8);
-      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
-      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
-      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
-      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
-      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
-
-      Aes256GcmEncrypter encrypter;
-      ASSERT_TRUE(encrypter.SetKey(key));
-      std::unique_ptr<QuicData> encrypted(
-          EncryptWithNonce(&encrypter, iv,
-                           // This deliberately tests that the encrypter can
-                           // handle an AAD that is set to nullptr, as opposed
-                           // to a zero-length, non-nullptr pointer.
-                           aad.length() ? aad : absl::string_view(), pt));
-      ASSERT_TRUE(encrypted.get());
-
-      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
-      quiche::test::CompareCharArraysWithHexError(
-          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
-      quiche::test::CompareCharArraysWithHexError(
-          "authentication tag", encrypted->data() + ct.length(), tag.length(),
-          tag.data(), tag.length());
-    }
-  }
-}
-
-TEST_F(Aes256GcmEncrypterTest, GetMaxPlaintextSize) {
-  Aes256GcmEncrypter encrypter;
-  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
-  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
-  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
-}
-
-TEST_F(Aes256GcmEncrypterTest, GetCiphertextSize) {
-  Aes256GcmEncrypter encrypter;
-  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
-  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
-  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
-}
-
-TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) {
-  Aes256GcmEncrypter encrypter;
-  std::string key = absl::HexStringToBytes(
-      "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
-  std::string sample =
-      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
-  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
-  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
-  std::string expected_mask =
-      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
-  quiche::test::CompareCharArraysWithHexError(
-      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
-      expected_mask.size());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/aes_base_decrypter.cc b/quic/core/crypto/aes_base_decrypter.cc
deleted file mode 100644
index fd21c73..0000000
--- a/quic/core/crypto/aes_base_decrypter.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_base_decrypter.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-bool AesBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
-  if (key.size() != GetKeySize()) {
-    QUIC_BUG(quic_bug_10649_1) << "Invalid key size for header protection";
-    return false;
-  }
-  if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
-                          key.size() * 8, &pne_key_) != 0) {
-    QUIC_BUG(quic_bug_10649_2) << "Unexpected failure of AES_set_encrypt_key";
-    return false;
-  }
-  return true;
-}
-
-std::string AesBaseDecrypter::GenerateHeaderProtectionMask(
-    QuicDataReader* sample_reader) {
-  absl::string_view sample;
-  if (!sample_reader->ReadStringPiece(&sample, AES_BLOCK_SIZE)) {
-    return std::string();
-  }
-  std::string out(AES_BLOCK_SIZE, 0);
-  AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
-              reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
-              &pne_key_);
-  return out;
-}
-
-QuicPacketCount AesBaseDecrypter::GetIntegrityLimit() const {
-  // For AEAD_AES_128_GCM ... endpoints that do not attempt to remove
-  // protection from packets larger than 2^11 bytes can attempt to remove
-  // protection from at most 2^57 packets.
-  // For AEAD_AES_256_GCM [the limit] is substantially larger than the limit for
-  // AEAD_AES_128_GCM. However, this document recommends that the same limit be
-  // applied to both functions as either limit is acceptably large.
-  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-integrity-limit
-  static_assert(kMaxIncomingPacketSize <= 2048,
-                "This key limit requires limits on decryption payload sizes");
-  return 144115188075855872U;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_base_decrypter.h b/quic/core/crypto/aes_base_decrypter.h
deleted file mode 100644
index a826f41..0000000
--- a/quic/core/crypto/aes_base_decrypter.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/core/crypto/aead_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE AesBaseDecrypter : public AeadBaseDecrypter {
- public:
-  using AeadBaseDecrypter::AeadBaseDecrypter;
-
-  bool SetHeaderProtectionKey(absl::string_view key) override;
-  std::string GenerateHeaderProtectionMask(
-      QuicDataReader* sample_reader) override;
-  QuicPacketCount GetIntegrityLimit() const override;
-
- private:
-  // The key used for packet number encryption.
-  AES_KEY pne_key_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
diff --git a/quic/core/crypto/aes_base_encrypter.cc b/quic/core/crypto/aes_base_encrypter.cc
deleted file mode 100644
index fb25a33..0000000
--- a/quic/core/crypto/aes_base_encrypter.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/aes_base_encrypter.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-bool AesBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
-  if (key.size() != GetKeySize()) {
-    QUIC_BUG(quic_bug_10726_1)
-        << "Invalid key size for header protection: " << key.size();
-    return false;
-  }
-  if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
-                          key.size() * 8, &pne_key_) != 0) {
-    QUIC_BUG(quic_bug_10726_2) << "Unexpected failure of AES_set_encrypt_key";
-    return false;
-  }
-  return true;
-}
-
-std::string AesBaseEncrypter::GenerateHeaderProtectionMask(
-    absl::string_view sample) {
-  if (sample.size() != AES_BLOCK_SIZE) {
-    return std::string();
-  }
-  std::string out(AES_BLOCK_SIZE, 0);
-  AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
-              reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
-              &pne_key_);
-  return out;
-}
-
-QuicPacketCount AesBaseEncrypter::GetConfidentialityLimit() const {
-  // For AEAD_AES_128_GCM and AEAD_AES_256_GCM ... endpoints that do not send
-  // packets larger than 2^11 bytes cannot protect more than 2^28 packets.
-  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-confidentiality-limit
-  static_assert(kMaxOutgoingPacketSize <= 2048,
-                "This key limit requires limits on encryption payload sizes");
-  return 268435456U;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/aes_base_encrypter.h b/quic/core/crypto/aes_base_encrypter.h
deleted file mode 100644
index 8ea3787..0000000
--- a/quic/core/crypto/aes_base_encrypter.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/core/crypto/aead_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE AesBaseEncrypter : public AeadBaseEncrypter {
- public:
-  using AeadBaseEncrypter::AeadBaseEncrypter;
-
-  bool SetHeaderProtectionKey(absl::string_view key) override;
-  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
-  QuicPacketCount GetConfidentialityLimit() const override;
-
- private:
-  // The key used for packet number encryption.
-  AES_KEY pne_key_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
diff --git a/quic/core/crypto/boring_utils.h b/quic/core/crypto/boring_utils.h
deleted file mode 100644
index d623fa2..0000000
--- a/quic/core/crypto/boring_utils.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
-#define QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-inline QUIC_EXPORT_PRIVATE absl::string_view CbsToStringPiece(CBS cbs) {
-  return absl::string_view(reinterpret_cast<const char*>(CBS_data(&cbs)),
-                           CBS_len(&cbs));
-}
-
-inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) {
-  CBS result;
-  CBS_init(&result, reinterpret_cast<const uint8_t*>(piece.data()),
-           piece.size());
-  return result;
-}
-
-inline QUIC_EXPORT_PRIVATE bool AddStringToCbb(CBB* cbb,
-                                               absl::string_view piece) {
-  return 1 == CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(piece.data()),
-                            piece.size());
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
diff --git a/quic/core/crypto/cert_compressor.cc b/quic/core/crypto/cert_compressor.cc
deleted file mode 100644
index 9cb2a59..0000000
--- a/quic/core/crypto/cert_compressor.cc
+++ /dev/null
@@ -1,599 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/cert_compressor.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "third_party/zlib/zlib.h"
-
-namespace quic {
-
-namespace {
-
-// kCommonCertSubstrings contains ~1500 bytes of common certificate substrings
-// in order to help zlib. This was generated via a fairly dumb algorithm from
-// the Alexa Top 5000 set - we could probably do better.
-static const unsigned char kCommonCertSubstrings[] = {
-    0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
-    0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
-    0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
-    0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01,
-    0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07,
-    0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
-    0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-    0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34,
-    0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
-    0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
-    0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e,
-    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
-    0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
-    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65,
-    0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
-    0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63,
-    0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
-    0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06,
-    0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d,
-    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
-    0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55,
-    0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
-    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
-    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2,
-    0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e,
-    0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
-    0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
-    0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03,
-    0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09,
-    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
-    0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
-    0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08,
-    0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30,
-    0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74,
-    0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
-    0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79,
-    0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33,
-    0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74,
-    0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
-    0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
-    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
-    0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
-    0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
-    0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
-    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
-    0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55,
-    0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37,
-    0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
-    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c,
-    0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
-    0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
-    0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
-    0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
-    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
-    0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
-    0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
-    0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
-    0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
-    0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
-    0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08,
-    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
-    0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
-    0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
-    0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
-    0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
-    0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a,
-    0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01,
-    0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
-    0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
-    0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
-    0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17,
-    0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72,
-    0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
-    0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65,
-    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
-    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39,
-    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73,
-    0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68,
-    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
-    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
-    0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e,
-    0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11,
-    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11,
-    0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01,
-    0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
-    0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
-    0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50,
-    0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
-    0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30,
-    0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61,
-    0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56,
-    0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31,
-    0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65,
-    0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
-    0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
-    0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
-    0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
-    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72,
-    0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
-    0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a,
-    0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a,
-    0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72,
-    0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72,
-    0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e,
-    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
-    0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63,
-    0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
-    0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
-    0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
-    0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b,
-    0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
-    0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
-    0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06,
-    0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68,
-    0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
-    0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
-    0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
-    0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74,
-    0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72,
-    0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-    0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee,
-    0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27,
-    0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30,
-    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
-};
-
-// CertEntry represents a certificate in compressed form. Each entry is one of
-// the three types enumerated in |Type|.
-struct CertEntry {
- public:
-  enum Type {
-    // Type 0 is reserved to mean "end of list" in the wire format.
-
-    // COMPRESSED means that the certificate is included in the trailing zlib
-    // data.
-    COMPRESSED = 1,
-    // CACHED means that the certificate is already known to the peer and will
-    // be replaced by its 64-bit hash (in |hash|).
-    CACHED = 2,
-  };
-
-  Type type;
-  uint64_t hash;
-  uint64_t set_hash;
-  uint32_t index;
-};
-
-// MatchCerts returns a vector of CertEntries describing how to most
-// efficiently represent |certs| to a peer who has cached the certificates
-// with the 64-bit, FNV-1a hashes in |client_cached_cert_hashes|.
-std::vector<CertEntry> MatchCerts(const std::vector<std::string>& certs,
-                                  absl::string_view client_cached_cert_hashes) {
-  std::vector<CertEntry> entries;
-  entries.reserve(certs.size());
-
-  const bool cached_valid =
-      client_cached_cert_hashes.size() % sizeof(uint64_t) == 0 &&
-      !client_cached_cert_hashes.empty();
-
-  for (auto i = certs.begin(); i != certs.end(); ++i) {
-    CertEntry entry;
-
-    if (cached_valid) {
-      bool cached = false;
-
-      uint64_t hash = QuicUtils::FNV1a_64_Hash(*i);
-      // This assumes that the machine is little-endian.
-      for (size_t j = 0; j < client_cached_cert_hashes.size();
-           j += sizeof(uint64_t)) {
-        uint64_t cached_hash;
-        memcpy(&cached_hash, client_cached_cert_hashes.data() + j,
-               sizeof(uint64_t));
-        if (hash != cached_hash) {
-          continue;
-        }
-
-        entry.type = CertEntry::CACHED;
-        entry.hash = hash;
-        entries.push_back(entry);
-        cached = true;
-        break;
-      }
-
-      if (cached) {
-        continue;
-      }
-    }
-
-    entry.type = CertEntry::COMPRESSED;
-    entries.push_back(entry);
-  }
-
-  return entries;
-}
-
-// CertEntriesSize returns the size, in bytes, of the serialised form of
-// |entries|.
-size_t CertEntriesSize(const std::vector<CertEntry>& entries) {
-  size_t entries_size = 0;
-
-  for (auto i = entries.begin(); i != entries.end(); ++i) {
-    entries_size++;
-    switch (i->type) {
-      case CertEntry::COMPRESSED:
-        break;
-      case CertEntry::CACHED:
-        entries_size += sizeof(uint64_t);
-        break;
-    }
-  }
-
-  entries_size++;  // for end marker
-
-  return entries_size;
-}
-
-// SerializeCertEntries serialises |entries| to |out|, which must have enough
-// space to contain them.
-void SerializeCertEntries(uint8_t* out, const std::vector<CertEntry>& entries) {
-  for (auto i = entries.begin(); i != entries.end(); ++i) {
-    *out++ = static_cast<uint8_t>(i->type);
-    switch (i->type) {
-      case CertEntry::COMPRESSED:
-        break;
-      case CertEntry::CACHED:
-        memcpy(out, &i->hash, sizeof(i->hash));
-        out += sizeof(uint64_t);
-        break;
-    }
-  }
-
-  *out++ = 0;  // end marker
-}
-
-// ZlibDictForEntries returns a string that contains the zlib pre-shared
-// dictionary to use in order to decompress a zlib block following |entries|.
-// |certs| is one-to-one with |entries| and contains the certificates for those
-// entries that are CACHED.
-std::string ZlibDictForEntries(const std::vector<CertEntry>& entries,
-                               const std::vector<std::string>& certs) {
-  std::string zlib_dict;
-
-  // The dictionary starts with the cached certs in reverse order.
-  size_t zlib_dict_size = 0;
-  for (size_t i = certs.size() - 1; i < certs.size(); i--) {
-    if (entries[i].type != CertEntry::COMPRESSED) {
-      zlib_dict_size += certs[i].size();
-    }
-  }
-
-  // At the end of the dictionary is a block of common certificate substrings.
-  zlib_dict_size += sizeof(kCommonCertSubstrings);
-
-  zlib_dict.reserve(zlib_dict_size);
-
-  for (size_t i = certs.size() - 1; i < certs.size(); i--) {
-    if (entries[i].type != CertEntry::COMPRESSED) {
-      zlib_dict += certs[i];
-    }
-  }
-
-  zlib_dict += std::string(reinterpret_cast<const char*>(kCommonCertSubstrings),
-                           sizeof(kCommonCertSubstrings));
-
-  QUICHE_DCHECK_EQ(zlib_dict.size(), zlib_dict_size);
-
-  return zlib_dict;
-}
-
-// HashCerts returns the FNV-1a hashes of |certs|.
-std::vector<uint64_t> HashCerts(const std::vector<std::string>& certs) {
-  std::vector<uint64_t> ret;
-  ret.reserve(certs.size());
-
-  for (auto i = certs.begin(); i != certs.end(); ++i) {
-    ret.push_back(QuicUtils::FNV1a_64_Hash(*i));
-  }
-
-  return ret;
-}
-
-// ParseEntries parses the serialised form of a vector of CertEntries from
-// |in_out| and writes them to |out_entries|. CACHED entries are resolved using
-// |cached_certs| and written to |out_certs|. |in_out| is updated to contain
-// the trailing data.
-bool ParseEntries(absl::string_view* in_out,
-                  const std::vector<std::string>& cached_certs,
-                  std::vector<CertEntry>* out_entries,
-                  std::vector<std::string>* out_certs) {
-  absl::string_view in = *in_out;
-  std::vector<uint64_t> cached_hashes;
-
-  out_entries->clear();
-  out_certs->clear();
-
-  for (;;) {
-    if (in.empty()) {
-      return false;
-    }
-    CertEntry entry;
-    const uint8_t type_byte = in[0];
-    in.remove_prefix(1);
-
-    if (type_byte == 0) {
-      break;
-    }
-
-    entry.type = static_cast<CertEntry::Type>(type_byte);
-
-    switch (entry.type) {
-      case CertEntry::COMPRESSED:
-        out_certs->push_back(std::string());
-        break;
-      case CertEntry::CACHED: {
-        if (in.size() < sizeof(uint64_t)) {
-          return false;
-        }
-        memcpy(&entry.hash, in.data(), sizeof(uint64_t));
-        in.remove_prefix(sizeof(uint64_t));
-
-        if (cached_hashes.size() != cached_certs.size()) {
-          cached_hashes = HashCerts(cached_certs);
-        }
-        bool found = false;
-        for (size_t i = 0; i < cached_hashes.size(); i++) {
-          if (cached_hashes[i] == entry.hash) {
-            out_certs->push_back(cached_certs[i]);
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          return false;
-        }
-        break;
-      }
-
-      default:
-        return false;
-    }
-    out_entries->push_back(entry);
-  }
-
-  *in_out = in;
-  return true;
-}
-
-// ScopedZLib deals with the automatic destruction of a zlib context.
-class ScopedZLib {
- public:
-  enum Type {
-    INFLATE,
-    DEFLATE,
-  };
-
-  explicit ScopedZLib(Type type) : z_(nullptr), type_(type) {}
-
-  void reset(z_stream* z) {
-    Clear();
-    z_ = z;
-  }
-
-  ~ScopedZLib() { Clear(); }
-
- private:
-  void Clear() {
-    if (!z_) {
-      return;
-    }
-
-    if (type_ == DEFLATE) {
-      deflateEnd(z_);
-    } else {
-      inflateEnd(z_);
-    }
-    z_ = nullptr;
-  }
-
-  z_stream* z_;
-  const Type type_;
-};
-
-}  // anonymous namespace
-
-// static
-std::string CertCompressor::CompressChain(
-    const std::vector<std::string>& certs,
-    absl::string_view client_cached_cert_hashes) {
-  const std::vector<CertEntry> entries =
-      MatchCerts(certs, client_cached_cert_hashes);
-  QUICHE_DCHECK_EQ(entries.size(), certs.size());
-
-  size_t uncompressed_size = 0;
-  for (size_t i = 0; i < entries.size(); i++) {
-    if (entries[i].type == CertEntry::COMPRESSED) {
-      uncompressed_size += 4 /* uint32_t length */ + certs[i].size();
-    }
-  }
-
-  size_t compressed_size = 0;
-  z_stream z;
-  ScopedZLib scoped_z(ScopedZLib::DEFLATE);
-
-  if (uncompressed_size > 0) {
-    memset(&z, 0, sizeof(z));
-    int rv = deflateInit(&z, Z_DEFAULT_COMPRESSION);
-    QUICHE_DCHECK_EQ(Z_OK, rv);
-    if (rv != Z_OK) {
-      return "";
-    }
-    scoped_z.reset(&z);
-
-    std::string zlib_dict = ZlibDictForEntries(entries, certs);
-
-    rv = deflateSetDictionary(
-        &z, reinterpret_cast<const uint8_t*>(&zlib_dict[0]), zlib_dict.size());
-    QUICHE_DCHECK_EQ(Z_OK, rv);
-    if (rv != Z_OK) {
-      return "";
-    }
-
-    compressed_size = deflateBound(&z, uncompressed_size);
-  }
-
-  const size_t entries_size = CertEntriesSize(entries);
-
-  std::string result;
-  result.resize(entries_size + (uncompressed_size > 0 ? 4 : 0) +
-                compressed_size);
-
-  uint8_t* j = reinterpret_cast<uint8_t*>(&result[0]);
-  SerializeCertEntries(j, entries);
-  j += entries_size;
-
-  if (uncompressed_size == 0) {
-    return result;
-  }
-
-  uint32_t uncompressed_size_32 = uncompressed_size;
-  memcpy(j, &uncompressed_size_32, sizeof(uint32_t));
-  j += sizeof(uint32_t);
-
-  int rv;
-
-  z.next_out = j;
-  z.avail_out = compressed_size;
-
-  for (size_t i = 0; i < certs.size(); i++) {
-    if (entries[i].type != CertEntry::COMPRESSED) {
-      continue;
-    }
-
-    uint32_t length32 = certs[i].size();
-    z.next_in = reinterpret_cast<uint8_t*>(&length32);
-    z.avail_in = sizeof(length32);
-    rv = deflate(&z, Z_NO_FLUSH);
-    QUICHE_DCHECK_EQ(Z_OK, rv);
-    QUICHE_DCHECK_EQ(0u, z.avail_in);
-    if (rv != Z_OK || z.avail_in) {
-      return "";
-    }
-
-    z.next_in =
-        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(certs[i].data()));
-    z.avail_in = certs[i].size();
-    rv = deflate(&z, Z_NO_FLUSH);
-    QUICHE_DCHECK_EQ(Z_OK, rv);
-    QUICHE_DCHECK_EQ(0u, z.avail_in);
-    if (rv != Z_OK || z.avail_in) {
-      return "";
-    }
-  }
-
-  z.avail_in = 0;
-  rv = deflate(&z, Z_FINISH);
-  QUICHE_DCHECK_EQ(Z_STREAM_END, rv);
-  if (rv != Z_STREAM_END) {
-    return "";
-  }
-
-  result.resize(result.size() - z.avail_out);
-  return result;
-}
-
-// static
-bool CertCompressor::DecompressChain(
-    absl::string_view in,
-    const std::vector<std::string>& cached_certs,
-    std::vector<std::string>* out_certs) {
-  std::vector<CertEntry> entries;
-  if (!ParseEntries(&in, cached_certs, &entries, out_certs)) {
-    return false;
-  }
-  QUICHE_DCHECK_EQ(entries.size(), out_certs->size());
-
-  std::unique_ptr<uint8_t[]> uncompressed_data;
-  absl::string_view uncompressed;
-
-  if (!in.empty()) {
-    if (in.size() < sizeof(uint32_t)) {
-      return false;
-    }
-
-    uint32_t uncompressed_size;
-    memcpy(&uncompressed_size, in.data(), sizeof(uncompressed_size));
-    in.remove_prefix(sizeof(uint32_t));
-
-    if (uncompressed_size > 128 * 1024) {
-      return false;
-    }
-
-    uncompressed_data = std::make_unique<uint8_t[]>(uncompressed_size);
-    z_stream z;
-    ScopedZLib scoped_z(ScopedZLib::INFLATE);
-
-    memset(&z, 0, sizeof(z));
-    z.next_out = uncompressed_data.get();
-    z.avail_out = uncompressed_size;
-    z.next_in =
-        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(in.data()));
-    z.avail_in = in.size();
-
-    if (Z_OK != inflateInit(&z)) {
-      return false;
-    }
-    scoped_z.reset(&z);
-
-    int rv = inflate(&z, Z_FINISH);
-    if (rv == Z_NEED_DICT) {
-      std::string zlib_dict = ZlibDictForEntries(entries, *out_certs);
-      const uint8_t* dict = reinterpret_cast<const uint8_t*>(zlib_dict.data());
-      if (Z_OK != inflateSetDictionary(&z, dict, zlib_dict.size())) {
-        return false;
-      }
-      rv = inflate(&z, Z_FINISH);
-    }
-
-    if (Z_STREAM_END != rv || z.avail_out > 0 || z.avail_in > 0) {
-      return false;
-    }
-
-    uncompressed = absl::string_view(
-        reinterpret_cast<char*>(uncompressed_data.get()), uncompressed_size);
-  }
-
-  for (size_t i = 0; i < entries.size(); i++) {
-    switch (entries[i].type) {
-      case CertEntry::COMPRESSED:
-        if (uncompressed.size() < sizeof(uint32_t)) {
-          return false;
-        }
-        uint32_t cert_len;
-        memcpy(&cert_len, uncompressed.data(), sizeof(cert_len));
-        uncompressed.remove_prefix(sizeof(uint32_t));
-        if (uncompressed.size() < cert_len) {
-          return false;
-        }
-        (*out_certs)[i] = std::string(uncompressed.substr(0, cert_len));
-        uncompressed.remove_prefix(cert_len);
-        break;
-      case CertEntry::CACHED:
-        break;
-    }
-  }
-
-  if (!uncompressed.empty()) {
-    return false;
-  }
-
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/cert_compressor.h b/quic/core/crypto/cert_compressor.h
deleted file mode 100644
index 9b741ee..0000000
--- a/quic/core/crypto/cert_compressor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
-
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// CertCompressor provides functions for compressing and decompressing
-// certificate chains using two techniquies:
-//   1) The peer may provide a list of a 64-bit, FNV-1a hashes of certificates
-//      that they already have. In the event that one of them is to be
-//      compressed, it can be replaced with just the hash.
-//   2) Otherwise the certificates are compressed with zlib using a pre-shared
-//      dictionary that consists of the certificates handled with the above
-//      methods and a small chunk of common substrings.
-class QUIC_EXPORT_PRIVATE CertCompressor {
- public:
-  CertCompressor() = delete;
-
-  // CompressChain compresses the certificates in |certs| and returns a
-  // compressed representation. client_cached_cert_hashes| contains
-  // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
-  static std::string CompressChain(const std::vector<std::string>& certs,
-                                   absl::string_view client_cached_cert_hashes);
-
-  // DecompressChain decompresses the result of |CompressChain|, given in |in|,
-  // into a series of certificates that are written to |out_certs|.
-  // |cached_certs| contains certificates that the peer may have omitted.
-  static bool DecompressChain(absl::string_view in,
-                              const std::vector<std::string>& cached_certs,
-                              std::vector<std::string>* out_certs);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
diff --git a/quic/core/crypto/cert_compressor_test.cc b/quic/core/crypto/cert_compressor_test.cc
deleted file mode 100644
index 5c1e991..0000000
--- a/quic/core/crypto/cert_compressor_test.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/cert_compressor.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class CertCompressorTest : public QuicTest {};
-
-TEST_F(CertCompressorTest, EmptyChain) {
-  std::vector<std::string> chain;
-  const std::string compressed =
-      CertCompressor::CompressChain(chain, absl::string_view());
-  EXPECT_EQ("00", absl::BytesToHexString(compressed));
-
-  std::vector<std::string> chain2, cached_certs;
-  ASSERT_TRUE(
-      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
-  EXPECT_EQ(chain.size(), chain2.size());
-}
-
-TEST_F(CertCompressorTest, Compressed) {
-  std::vector<std::string> chain;
-  chain.push_back("testcert");
-  const std::string compressed =
-      CertCompressor::CompressChain(chain, absl::string_view());
-  ASSERT_GE(compressed.size(), 2u);
-  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
-
-  std::vector<std::string> chain2, cached_certs;
-  ASSERT_TRUE(
-      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
-  EXPECT_EQ(chain.size(), chain2.size());
-  EXPECT_EQ(chain[0], chain2[0]);
-}
-
-TEST_F(CertCompressorTest, Common) {
-  std::vector<std::string> chain;
-  chain.push_back("testcert");
-  static const uint64_t set_hash = 42;
-  const std::string compressed = CertCompressor::CompressChain(
-      chain, absl::string_view(reinterpret_cast<const char*>(&set_hash),
-                               sizeof(set_hash)));
-  ASSERT_GE(compressed.size(), 2u);
-  // 01 is the prefix for a zlib "compressed" cert not common or cached.
-  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
-
-  std::vector<std::string> chain2, cached_certs;
-  ASSERT_TRUE(
-      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
-  EXPECT_EQ(chain.size(), chain2.size());
-  EXPECT_EQ(chain[0], chain2[0]);
-}
-
-TEST_F(CertCompressorTest, Cached) {
-  std::vector<std::string> chain;
-  chain.push_back("testcert");
-  uint64_t hash = QuicUtils::FNV1a_64_Hash(chain[0]);
-  absl::string_view hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
-  const std::string compressed =
-      CertCompressor::CompressChain(chain, hash_bytes);
-
-  EXPECT_EQ("02" /* cached */ + absl::BytesToHexString(hash_bytes) +
-                "00" /* end of list */,
-            absl::BytesToHexString(compressed));
-
-  std::vector<std::string> cached_certs, chain2;
-  cached_certs.push_back(chain[0]);
-  ASSERT_TRUE(
-      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
-  EXPECT_EQ(chain.size(), chain2.size());
-  EXPECT_EQ(chain[0], chain2[0]);
-}
-
-TEST_F(CertCompressorTest, BadInputs) {
-  std::vector<std::string> cached_certs, chain;
-
-  EXPECT_FALSE(CertCompressor::DecompressChain(
-      absl::BytesToHexString("04") /* bad entry type */, cached_certs, &chain));
-
-  EXPECT_FALSE(CertCompressor::DecompressChain(
-      absl::BytesToHexString("01") /* no terminator */, cached_certs, &chain));
-
-  EXPECT_FALSE(CertCompressor::DecompressChain(
-      absl::BytesToHexString("0200") /* hash truncated */, cached_certs,
-      &chain));
-
-  EXPECT_FALSE(CertCompressor::DecompressChain(
-      absl::BytesToHexString("0300") /* hash and index truncated */,
-      cached_certs, &chain));
-
-  /* without a CommonCertSets */
-  EXPECT_FALSE(
-      CertCompressor::DecompressChain(absl::BytesToHexString("03"
-                                                             "0000000000000000"
-                                                             "00000000"),
-                                      cached_certs, &chain));
-
-  /* incorrect hash and index */
-  EXPECT_FALSE(
-      CertCompressor::DecompressChain(absl::BytesToHexString("03"
-                                                             "a200000000000000"
-                                                             "00000000"),
-                                      cached_certs, &chain));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/certificate_util.cc b/quic/core/crypto/certificate_util.cc
deleted file mode 100644
index 550adff..0000000
--- a/quic/core/crypto/certificate_util.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/certificate_util.h"
-
-#include "absl/strings/str_format.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bn.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/ec_key.h"
-#include "third_party/boringssl/src/include/openssl/mem.h"
-#include "third_party/boringssl/src/include/openssl/pkcs7.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-#include "third_party/boringssl/src/include/openssl/rsa.h"
-#include "third_party/boringssl/src/include/openssl/stack.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-bool AddEcdsa256SignatureAlgorithm(CBB* cbb) {
-  // See RFC 5758. This is the encoding of OID 1.2.840.10045.4.3.2.
-  static const uint8_t kEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
-                                             0x3d, 0x04, 0x03, 0x02};
-
-  // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
-  CBB sequence, oid;
-  if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
-      !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
-    return false;
-  }
-
-  if (!CBB_add_bytes(&oid, kEcdsaWithSha256, sizeof(kEcdsaWithSha256))) {
-    return false;
-  }
-
-  // RFC 5758, section 3.2: ecdsa-with-sha256 MUST omit the parameters field.
-  return CBB_flush(cbb);
-}
-
-// Adds an X.509 Name with the specified distinguished name to |cbb|.
-bool AddName(CBB* cbb, absl::string_view name) {
-  // See RFC 4519.
-  static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
-  static const uint8_t kCountryName[] = {0x55, 0x04, 0x06};
-  static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a};
-  static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b};
-
-  std::vector<std::string> attributes =
-      absl::StrSplit(name, ',', absl::SkipEmpty());
-
-  if (attributes.empty()) {
-    QUIC_LOG(ERROR) << "Missing DN or wrong format";
-    return false;
-  }
-
-  // See RFC 5280, section 4.1.2.4.
-  CBB rdns;
-  if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
-    return false;
-  }
-
-  for (const std::string& attribute : attributes) {
-    std::vector<std::string> parts =
-        absl::StrSplit(absl::StripAsciiWhitespace(attribute), '=');
-    if (parts.size() != 2) {
-      QUIC_LOG(ERROR) << "Wrong DN format at " + attribute;
-      return false;
-    }
-
-    const std::string& type_string = parts[0];
-    const std::string& value_string = parts[1];
-    absl::Span<const uint8_t> type_bytes;
-    if (type_string == "CN") {
-      type_bytes = kCommonName;
-    } else if (type_string == "C") {
-      type_bytes = kCountryName;
-    } else if (type_string == "O") {
-      type_bytes = kOrganizationName;
-    } else if (type_string == "OU") {
-      type_bytes = kOrganizationalUnitName;
-    } else {
-      QUIC_LOG(ERROR) << "Unrecognized type " + type_string;
-      return false;
-    }
-
-    CBB rdn, attr, type, value;
-    if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
-        !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
-        !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
-        !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) ||
-        !CBB_add_asn1(&attr, &value,
-                      type_string == "C" ? CBS_ASN1_PRINTABLESTRING
-                                         : CBS_ASN1_UTF8STRING) ||
-        !AddStringToCbb(&value, value_string) || !CBB_flush(&rdns)) {
-      return false;
-    }
-  }
-  if (!CBB_flush(cbb)) {
-    return false;
-  }
-  return true;
-}
-
-bool CBBAddTime(CBB* cbb, const CertificateTimestamp& timestamp) {
-  CBB child;
-  std::string formatted_time;
-
-  // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as
-  // UTCTime rather than GeneralizedTime.
-  const bool is_utc_time = (1950 <= timestamp.year && timestamp.year < 2050);
-  if (is_utc_time) {
-    uint16_t year = timestamp.year - 1900;
-    if (year >= 100) {
-      year -= 100;
-    }
-    formatted_time = absl::StrFormat("%02d", year);
-    if (!CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME)) {
-      return false;
-    }
-  } else {
-    formatted_time = absl::StrFormat("%04d", timestamp.year);
-    if (!CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME)) {
-      return false;
-    }
-  }
-
-  absl::StrAppendFormat(&formatted_time, "%02d%02d%02d%02d%02dZ",
-                        timestamp.month, timestamp.day, timestamp.hour,
-                        timestamp.minute, timestamp.second);
-
-  static const size_t kGeneralizedTimeLength = 15;
-  static const size_t kUTCTimeLength = 13;
-  QUICHE_DCHECK_EQ(formatted_time.size(),
-                   is_utc_time ? kUTCTimeLength : kGeneralizedTimeLength);
-
-  return AddStringToCbb(&child, formatted_time) && CBB_flush(cbb);
-}
-
-bool CBBAddExtension(CBB* extensions, absl::Span<const uint8_t> oid,
-                     bool critical, absl::Span<const uint8_t> contents) {
-  CBB extension, cbb_oid, cbb_contents;
-  if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) ||
-      !CBB_add_asn1(&extension, &cbb_oid, CBS_ASN1_OBJECT) ||
-      !CBB_add_bytes(&cbb_oid, oid.data(), oid.size()) ||
-      (critical && !CBB_add_asn1_bool(&extension, 1)) ||
-      !CBB_add_asn1(&extension, &cbb_contents, CBS_ASN1_OCTETSTRING) ||
-      !CBB_add_bytes(&cbb_contents, contents.data(), contents.size()) ||
-      !CBB_flush(extensions)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool IsEcdsa256Key(const EVP_PKEY& evp_key) {
-  if (EVP_PKEY_id(&evp_key) != EVP_PKEY_EC) {
-    return false;
-  }
-  const EC_KEY* key = EVP_PKEY_get0_EC_KEY(&evp_key);
-  if (key == nullptr) {
-    return false;
-  }
-  const EC_GROUP* group = EC_KEY_get0_group(key);
-  if (group == nullptr) {
-    return false;
-  }
-  return EC_GROUP_get_curve_name(group) == NID_X9_62_prime256v1;
-}
-
-}  // namespace
-
-bssl::UniquePtr<EVP_PKEY> MakeKeyPairForSelfSignedCertificate() {
-  bssl::UniquePtr<EVP_PKEY_CTX> context(
-      EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
-  if (!context) {
-    return nullptr;
-  }
-  if (EVP_PKEY_keygen_init(context.get()) != 1) {
-    return nullptr;
-  }
-  if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context.get(),
-                                             NID_X9_62_prime256v1) != 1) {
-    return nullptr;
-  }
-  EVP_PKEY* raw_key = nullptr;
-  if (EVP_PKEY_keygen(context.get(), &raw_key) != 1) {
-    return nullptr;
-  }
-  return bssl::UniquePtr<EVP_PKEY>(raw_key);
-}
-
-std::string CreateSelfSignedCertificate(EVP_PKEY& key,
-                                        const CertificateOptions& options) {
-  std::string error;
-  if (!IsEcdsa256Key(key)) {
-    QUIC_LOG(ERROR) << "CreateSelfSignedCert only accepts ECDSA P-256 keys";
-    return error;
-  }
-
-  // See RFC 5280, section 4.1. First, construct the TBSCertificate.
-  bssl::ScopedCBB cbb;
-  CBB tbs_cert, version, validity;
-  uint8_t* tbs_cert_bytes;
-  size_t tbs_cert_len;
-
-  if (!CBB_init(cbb.get(), 64) ||
-      !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
-      !CBB_add_asn1(&tbs_cert, &version,
-                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
-      !CBB_add_asn1_uint64(&version, 2) ||  // X.509 version 3
-      !CBB_add_asn1_uint64(&tbs_cert, options.serial_number) ||
-      !AddEcdsa256SignatureAlgorithm(&tbs_cert) ||  // signature algorithm
-      !AddName(&tbs_cert, options.subject) ||       // issuer
-      !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
-      !CBBAddTime(&validity, options.validity_start) ||
-      !CBBAddTime(&validity, options.validity_end) ||
-      !AddName(&tbs_cert, options.subject) ||      // subject
-      !EVP_marshal_public_key(&tbs_cert, &key)) {  // subjectPublicKeyInfo
-    return error;
-  }
-
-  CBB outer_extensions, extensions;
-  if (!CBB_add_asn1(&tbs_cert, &outer_extensions,
-                    3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
-      !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
-    return error;
-  }
-
-  // Key Usage
-  constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f};
-  constexpr uint8_t kKeyUsageContent[] = {
-      0x3,   // BIT STRING
-      0x2,   // Length
-      0x0,   // Unused bits
-      0x80,  // bit(0): digitalSignature
-  };
-  CBBAddExtension(&extensions, kKeyUsageOid, true, kKeyUsageContent);
-
-  // TODO(wub): Add more extensions here if needed.
-
-  if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
-    return error;
-  }
-
-  bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
-
-  // Sign the TBSCertificate and write the entire certificate.
-  CBB cert, signature;
-  bssl::ScopedEVP_MD_CTX ctx;
-  uint8_t* sig_out;
-  size_t sig_len;
-  uint8_t* cert_bytes;
-  size_t cert_len;
-  if (!CBB_init(cbb.get(), tbs_cert_len) ||
-      !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
-      !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
-      !AddEcdsa256SignatureAlgorithm(&cert) ||
-      !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
-      !CBB_add_u8(&signature, 0 /* no unused bits */) ||
-      !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, &key) ||
-      // Compute the maximum signature length.
-      !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
-                      tbs_cert_len) ||
-      !CBB_reserve(&signature, &sig_out, sig_len) ||
-      // Actually sign the TBSCertificate.
-      !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
-                      tbs_cert_len) ||
-      !CBB_did_write(&signature, sig_len) ||
-      !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
-    return error;
-  }
-  bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
-  return std::string(reinterpret_cast<char*>(cert_bytes), cert_len);
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/certificate_util.h b/quic/core/crypto/certificate_util.h
deleted file mode 100644
index ebc1cf4..0000000
--- a/quic/core/crypto/certificate_util.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_NO_EXPORT CertificateTimestamp {
-  uint16_t year;
-  uint8_t month;
-  uint8_t day;
-  uint8_t hour;
-  uint8_t minute;
-  uint8_t second;
-};
-
-struct QUIC_NO_EXPORT CertificateOptions {
-  absl::string_view subject;
-  uint64_t serial_number;
-  CertificateTimestamp validity_start;  // a.k.a not_valid_before
-  CertificateTimestamp validity_end;    // a.k.a not_valid_after
-};
-
-// Creates a ECDSA P-256 key pair.
-QUIC_EXPORT_PRIVATE bssl::UniquePtr<EVP_PKEY>
-MakeKeyPairForSelfSignedCertificate();
-
-// Creates a self-signed, DER-encoded X.509 certificate.
-// |key| must be a ECDSA P-256 key.
-// This is mostly stolen from Chromium's net/cert/x509_util.h, with
-// modifications to make it work in QUICHE.
-QUIC_EXPORT_PRIVATE std::string CreateSelfSignedCertificate(
-    EVP_PKEY& key, const CertificateOptions& options);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
diff --git a/quic/core/crypto/certificate_util_test.cc b/quic/core/crypto/certificate_util_test.cc
deleted file mode 100644
index 1ffe6f5..0000000
--- a/quic/core/crypto/certificate_util_test.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/certificate_util.h"
-
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_output.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(CertificateUtilTest, CreateSelfSignedCertificate) {
-  bssl::UniquePtr<EVP_PKEY> key = MakeKeyPairForSelfSignedCertificate();
-  ASSERT_NE(key, nullptr);
-
-  CertificatePrivateKey cert_key(std::move(key));
-
-  CertificateOptions options;
-  options.subject = "CN=subject";
-  options.serial_number = 0x12345678;
-  options.validity_start = {2020, 1, 1, 0, 0, 0};
-  options.validity_end = {2049, 12, 31, 0, 0, 0};
-  std::string der_cert =
-      CreateSelfSignedCertificate(*cert_key.private_key(), options);
-  ASSERT_FALSE(der_cert.empty());
-
-  QuicSaveTestOutput("CertificateUtilTest_CreateSelfSignedCert.crt", der_cert);
-
-  std::unique_ptr<CertificateView> cert_view =
-      CertificateView::ParseSingleCertificate(der_cert);
-  ASSERT_NE(cert_view, nullptr);
-  EXPECT_EQ(cert_view->public_key_type(), PublicKeyType::kP256);
-
-  absl::optional<std::string> subject = cert_view->GetHumanReadableSubject();
-  ASSERT_TRUE(subject.has_value());
-  EXPECT_EQ(*subject, options.subject);
-
-  EXPECT_TRUE(
-      cert_key.ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
-  EXPECT_TRUE(cert_key.MatchesPublicKey(*cert_view));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/certificate_view.cc b/quic/core/crypto/certificate_view.cc
deleted file mode 100644
index 1286667..0000000
--- a/quic/core/crypto/certificate_view.cc
+++ /dev/null
@@ -1,650 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/certificate_view.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ec_key.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "third_party/boringssl/src/include/openssl/nid.h"
-#include "third_party/boringssl/src/include/openssl/rsa.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_time_utils.h"
-#include "common/quiche_data_reader.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-using ::quiche::QuicheTextUtils;
-
-// The literals below were encoded using `ascii2der | xxd -i`.  The comments
-// above the literals are the contents in the der2ascii syntax.
-
-// X.509 version 3 (version numbering starts with zero).
-// INTEGER { 2 }
-constexpr uint8_t kX509Version[] = {0x02, 0x01, 0x02};
-
-// 2.5.29.17
-constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11};
-
-PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) {
-  switch (EVP_PKEY_id(public_key)) {
-    case EVP_PKEY_RSA:
-      return PublicKeyType::kRsa;
-    case EVP_PKEY_EC: {
-      const EC_KEY* key = EVP_PKEY_get0_EC_KEY(public_key);
-      if (key == nullptr) {
-        return PublicKeyType::kUnknown;
-      }
-      const EC_GROUP* group = EC_KEY_get0_group(key);
-      if (group == nullptr) {
-        return PublicKeyType::kUnknown;
-      }
-      const int curve_nid = EC_GROUP_get_curve_name(group);
-      switch (curve_nid) {
-        case NID_X9_62_prime256v1:
-          return PublicKeyType::kP256;
-        case NID_secp384r1:
-          return PublicKeyType::kP384;
-        default:
-          return PublicKeyType::kUnknown;
-      }
-    }
-    case EVP_PKEY_ED25519:
-      return PublicKeyType::kEd25519;
-    default:
-      return PublicKeyType::kUnknown;
-  }
-}
-
-PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
-    uint16_t signature_algorithm) {
-  switch (signature_algorithm) {
-    case SSL_SIGN_RSA_PSS_RSAE_SHA256:
-      return PublicKeyType::kRsa;
-    case SSL_SIGN_ECDSA_SECP256R1_SHA256:
-      return PublicKeyType::kP256;
-    case SSL_SIGN_ECDSA_SECP384R1_SHA384:
-      return PublicKeyType::kP384;
-    case SSL_SIGN_ED25519:
-      return PublicKeyType::kEd25519;
-    default:
-      return PublicKeyType::kUnknown;
-  }
-}
-
-std::string AttributeNameToString(const CBS& oid_cbs) {
-  absl::string_view oid = CbsToStringPiece(oid_cbs);
-
-  // We only handle OIDs of form 2.5.4.N, which have binary encoding of
-  // "55 04 0N".
-  if (oid.length() == 3 && absl::StartsWith(oid, "\x55\x04")) {
-    // clang-format off
-    switch (oid[2]) {
-      case '\x3': return "CN";
-      case '\x7': return "L";
-      case '\x8': return "ST";
-      case '\xa': return "O";
-      case '\xb': return "OU";
-      case '\x6': return "C";
-    }
-    // clang-format on
-  }
-
-  bssl::UniquePtr<char> oid_representation(CBS_asn1_oid_to_text(&oid_cbs));
-  if (oid_representation == nullptr) {
-    return absl::StrCat("(", absl::BytesToHexString(oid), ")");
-  }
-  return std::string(oid_representation.get());
-}
-
-}  // namespace
-
-absl::optional<std::string> X509NameAttributeToString(CBS input) {
-  CBS name, value;
-  unsigned value_tag;
-  if (!CBS_get_asn1(&input, &name, CBS_ASN1_OBJECT) ||
-      !CBS_get_any_asn1(&input, &value, &value_tag) || CBS_len(&input) != 0) {
-    return absl::nullopt;
-  }
-  // Note that this does not process encoding of |input| in any way.  This works
-  // fine for the most cases.
-  return absl::StrCat(AttributeNameToString(name), "=",
-                      absl::CHexEscape(CbsToStringPiece(value)));
-}
-
-namespace {
-
-template <unsigned inner_tag,
-          char separator,
-          absl::optional<std::string> (*parser)(CBS)>
-absl::optional<std::string> ParseAndJoin(CBS input) {
-  std::vector<std::string> pieces;
-  while (CBS_len(&input) != 0) {
-    CBS attribute;
-    if (!CBS_get_asn1(&input, &attribute, inner_tag)) {
-      return absl::nullopt;
-    }
-    absl::optional<std::string> formatted = parser(attribute);
-    if (!formatted.has_value()) {
-      return absl::nullopt;
-    }
-    pieces.push_back(*formatted);
-  }
-
-  return absl::StrJoin(pieces, std::string({separator}));
-}
-
-absl::optional<std::string> RelativeDistinguishedNameToString(CBS input) {
-  return ParseAndJoin<CBS_ASN1_SEQUENCE, '+', X509NameAttributeToString>(input);
-}
-
-absl::optional<std::string> DistinguishedNameToString(CBS input) {
-  return ParseAndJoin<CBS_ASN1_SET, ',', RelativeDistinguishedNameToString>(
-      input);
-}
-
-}  // namespace
-
-std::string PublicKeyTypeToString(PublicKeyType type) {
-  switch (type) {
-    case PublicKeyType::kRsa:
-      return "RSA";
-    case PublicKeyType::kP256:
-      return "ECDSA P-256";
-    case PublicKeyType::kP384:
-      return "ECDSA P-384";
-    case PublicKeyType::kEd25519:
-      return "Ed25519";
-    case PublicKeyType::kUnknown:
-      return "unknown";
-  }
-  return "";
-}
-
-absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag,
-                                                absl::string_view payload) {
-  if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) {
-    QUIC_DLOG(WARNING) << "Invalid tag supplied for a DER timestamp";
-    return absl::nullopt;
-  }
-
-  const size_t year_length = tag == CBS_ASN1_GENERALIZEDTIME ? 4 : 2;
-  uint64_t year, month, day, hour, minute, second;
-  quiche::QuicheDataReader reader(payload);
-  if (!reader.ReadDecimal64(year_length, &year) ||
-      !reader.ReadDecimal64(2, &month) || !reader.ReadDecimal64(2, &day) ||
-      !reader.ReadDecimal64(2, &hour) || !reader.ReadDecimal64(2, &minute) ||
-      !reader.ReadDecimal64(2, &second) ||
-      reader.ReadRemainingPayload() != "Z") {
-    QUIC_DLOG(WARNING) << "Failed to parse the DER timestamp";
-    return absl::nullopt;
-  }
-
-  if (tag == CBS_ASN1_UTCTIME) {
-    QUICHE_DCHECK_LE(year, 100u);
-    year += (year >= 50) ? 1900 : 2000;
-  }
-
-  const absl::optional<int64_t> unix_time =
-      quiche::QuicheUtcDateTimeToUnixSeconds(year, month, day, hour, minute,
-                                             second);
-  if (!unix_time.has_value() || *unix_time < 0) {
-    return absl::nullopt;
-  }
-  return QuicWallTime::FromUNIXSeconds(*unix_time);
-}
-
-PemReadResult ReadNextPemMessage(std::istream* input) {
-  constexpr absl::string_view kPemBegin = "-----BEGIN ";
-  constexpr absl::string_view kPemEnd = "-----END ";
-  constexpr absl::string_view kPemDashes = "-----";
-
-  std::string line_buffer, encoded_message_contents, expected_end;
-  bool pending_message = false;
-  PemReadResult result;
-  while (std::getline(*input, line_buffer)) {
-    absl::string_view line(line_buffer);
-    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line);
-
-    // Handle BEGIN lines.
-    if (!pending_message && absl::StartsWith(line, kPemBegin) &&
-        absl::EndsWith(line, kPemDashes)) {
-      result.type = std::string(
-          line.substr(kPemBegin.size(),
-                      line.size() - kPemDashes.size() - kPemBegin.size()));
-      expected_end = absl::StrCat(kPemEnd, result.type, kPemDashes);
-      pending_message = true;
-      continue;
-    }
-
-    // Handle END lines.
-    if (pending_message && line == expected_end) {
-      absl::optional<std::string> data =
-          QuicheTextUtils::Base64Decode(encoded_message_contents);
-      if (data.has_value()) {
-        result.status = PemReadResult::kOk;
-        result.contents = data.value();
-      } else {
-        result.status = PemReadResult::kError;
-      }
-      return result;
-    }
-
-    if (pending_message) {
-      encoded_message_contents.append(std::string(line));
-    }
-  }
-  bool eof_reached = input->eof() && !pending_message;
-  return PemReadResult{
-      (eof_reached ? PemReadResult::kEof : PemReadResult::kError), "", ""};
-}
-
-std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
-    absl::string_view certificate) {
-  std::unique_ptr<CertificateView> result(new CertificateView());
-  CBS top = StringPieceToCbs(certificate);
-
-  CBS top_certificate, tbs_certificate, signature_algorithm, signature;
-  if (!CBS_get_asn1(&top, &top_certificate, CBS_ASN1_SEQUENCE) ||
-      CBS_len(&top) != 0) {
-    return nullptr;
-  }
-
-  // Certificate  ::=  SEQUENCE  {
-  if (
-      //   tbsCertificate       TBSCertificate,
-      !CBS_get_asn1(&top_certificate, &tbs_certificate, CBS_ASN1_SEQUENCE) ||
-
-      //   signatureAlgorithm   AlgorithmIdentifier,
-      !CBS_get_asn1(&top_certificate, &signature_algorithm,
-                    CBS_ASN1_SEQUENCE) ||
-
-      //   signature            BIT STRING  }
-      !CBS_get_asn1(&top_certificate, &signature, CBS_ASN1_BITSTRING) ||
-      CBS_len(&top_certificate) != 0) {
-    return nullptr;
-  }
-
-  int has_version, has_extensions;
-  CBS version, serial, signature_algorithm_inner, issuer, validity, subject,
-      spki, issuer_id, subject_id, extensions_outer;
-  // TBSCertificate  ::=  SEQUENCE  {
-  if (
-      //   version         [0]  Version DEFAULT v1,
-      !CBS_get_optional_asn1(
-          &tbs_certificate, &version, &has_version,
-          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
-
-      //   serialNumber         CertificateSerialNumber,
-      !CBS_get_asn1(&tbs_certificate, &serial, CBS_ASN1_INTEGER) ||
-
-      //   signature            AlgorithmIdentifier,
-      !CBS_get_asn1(&tbs_certificate, &signature_algorithm_inner,
-                    CBS_ASN1_SEQUENCE) ||
-
-      //   issuer               Name,
-      !CBS_get_asn1(&tbs_certificate, &issuer, CBS_ASN1_SEQUENCE) ||
-
-      //   validity             Validity,
-      !CBS_get_asn1(&tbs_certificate, &validity, CBS_ASN1_SEQUENCE) ||
-
-      //   subject              Name,
-      !CBS_get_asn1(&tbs_certificate, &subject, CBS_ASN1_SEQUENCE) ||
-
-      //   subjectPublicKeyInfo SubjectPublicKeyInfo,
-      !CBS_get_asn1_element(&tbs_certificate, &spki, CBS_ASN1_SEQUENCE) ||
-
-      //   issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
-      //                        -- If present, version MUST be v2 or v3
-      !CBS_get_optional_asn1(&tbs_certificate, &issuer_id, nullptr,
-                             CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
-
-      //   subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
-      //                        -- If present, version MUST be v2 or v3
-      !CBS_get_optional_asn1(&tbs_certificate, &subject_id, nullptr,
-                             CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
-
-      //   extensions      [3]  Extensions OPTIONAL
-      //                        -- If present, version MUST be v3 --  }
-      !CBS_get_optional_asn1(
-          &tbs_certificate, &extensions_outer, &has_extensions,
-          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3) ||
-
-      CBS_len(&tbs_certificate) != 0) {
-    return nullptr;
-  }
-
-  result->subject_der_ = CbsToStringPiece(subject);
-
-  unsigned not_before_tag, not_after_tag;
-  CBS not_before, not_after;
-  if (!CBS_get_any_asn1(&validity, &not_before, &not_before_tag) ||
-      !CBS_get_any_asn1(&validity, &not_after, &not_after_tag) ||
-      CBS_len(&validity) != 0) {
-    QUIC_DLOG(WARNING) << "Failed to extract the validity dates";
-    return nullptr;
-  }
-  absl::optional<QuicWallTime> not_before_parsed =
-      ParseDerTime(not_before_tag, CbsToStringPiece(not_before));
-  absl::optional<QuicWallTime> not_after_parsed =
-      ParseDerTime(not_after_tag, CbsToStringPiece(not_after));
-  if (!not_before_parsed.has_value() || !not_after_parsed.has_value()) {
-    QUIC_DLOG(WARNING) << "Failed to parse validity dates";
-    return nullptr;
-  }
-  result->validity_start_ = *not_before_parsed;
-  result->validity_end_ = *not_after_parsed;
-
-  result->public_key_.reset(EVP_parse_public_key(&spki));
-  if (result->public_key_ == nullptr) {
-    QUIC_DLOG(WARNING) << "Failed to parse the public key";
-    return nullptr;
-  }
-  if (!result->ValidatePublicKeyParameters()) {
-    QUIC_DLOG(WARNING) << "Public key has invalid parameters";
-    return nullptr;
-  }
-
-  // Only support X.509v3.
-  if (!has_version ||
-      !CBS_mem_equal(&version, kX509Version, sizeof(kX509Version))) {
-    QUIC_DLOG(WARNING) << "Bad X.509 version";
-    return nullptr;
-  }
-
-  if (!has_extensions) {
-    return nullptr;
-  }
-
-  CBS extensions;
-  if (!CBS_get_asn1(&extensions_outer, &extensions, CBS_ASN1_SEQUENCE) ||
-      CBS_len(&extensions_outer) != 0) {
-    QUIC_DLOG(WARNING) << "Failed to extract the extension sequence";
-    return nullptr;
-  }
-  if (!result->ParseExtensions(extensions)) {
-    QUIC_DLOG(WARNING) << "Failed to parse extensions";
-    return nullptr;
-  }
-
-  return result;
-}
-
-bool CertificateView::ParseExtensions(CBS extensions) {
-  while (CBS_len(&extensions) != 0) {
-    CBS extension, oid, critical, payload;
-    if (
-        // Extension  ::=  SEQUENCE  {
-        !CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
-        //     extnID      OBJECT IDENTIFIER,
-        !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
-        //     critical    BOOLEAN DEFAULT FALSE,
-        !CBS_get_optional_asn1(&extension, &critical, nullptr,
-                               CBS_ASN1_BOOLEAN) ||
-        //     extnValue   OCTET STRING
-        //                 -- contains the DER encoding of an ASN.1 value
-        //                 -- corresponding to the extension type identified
-        //                 -- by extnID
-        !CBS_get_asn1(&extension, &payload, CBS_ASN1_OCTETSTRING) ||
-        CBS_len(&extension) != 0) {
-      QUIC_DLOG(WARNING) << "Bad extension entry";
-      return false;
-    }
-
-    if (CBS_mem_equal(&oid, kSubjectAltNameOid, sizeof(kSubjectAltNameOid))) {
-      CBS alt_names;
-      if (!CBS_get_asn1(&payload, &alt_names, CBS_ASN1_SEQUENCE) ||
-          CBS_len(&payload) != 0) {
-        QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
-        return false;
-      }
-      while (CBS_len(&alt_names) != 0) {
-        CBS alt_name_cbs;
-        unsigned int alt_name_tag;
-        if (!CBS_get_any_asn1(&alt_names, &alt_name_cbs, &alt_name_tag)) {
-          QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
-          return false;
-        }
-
-        absl::string_view alt_name = CbsToStringPiece(alt_name_cbs);
-        QuicIpAddress ip_address;
-        // GeneralName ::= CHOICE {
-        switch (alt_name_tag) {
-          // dNSName                   [2]  IA5String,
-          case CBS_ASN1_CONTEXT_SPECIFIC | 2:
-            subject_alt_name_domains_.push_back(alt_name);
-            break;
-
-          // iPAddress                 [7]  OCTET STRING,
-          case CBS_ASN1_CONTEXT_SPECIFIC | 7:
-            if (!ip_address.FromPackedString(alt_name.data(),
-                                             alt_name.size())) {
-              QUIC_DLOG(WARNING) << "Failed to parse subjectAltName IP address";
-              return false;
-            }
-            subject_alt_name_ips_.push_back(ip_address);
-            break;
-
-          default:
-            QUIC_DLOG(INFO) << "Unknown subjectAltName tag " << alt_name_tag;
-            continue;
-        }
-      }
-    }
-  }
-
-  return true;
-}
-
-std::vector<std::string> CertificateView::LoadPemFromStream(
-    std::istream* input) {
-  std::vector<std::string> result;
-  for (;;) {
-    PemReadResult read_result = ReadNextPemMessage(input);
-    if (read_result.status == PemReadResult::kEof) {
-      return result;
-    }
-    if (read_result.status != PemReadResult::kOk) {
-      return std::vector<std::string>();
-    }
-    if (read_result.type != "CERTIFICATE") {
-      continue;
-    }
-    result.emplace_back(std::move(read_result.contents));
-  }
-}
-
-PublicKeyType CertificateView::public_key_type() const {
-  return PublicKeyTypeFromKey(public_key_.get());
-}
-
-bool CertificateView::ValidatePublicKeyParameters() {
-  // The profile here affects what certificates can be used when QUIC is used as
-  // a server library without any custom certificate provider logic.
-  // The goal is to allow at minimum any certificate that would be allowed on a
-  // regular Web session over TLS 1.3 while ensuring we do not expose any
-  // algorithms we don't want to support long-term.
-  PublicKeyType key_type = PublicKeyTypeFromKey(public_key_.get());
-  switch (key_type) {
-    case PublicKeyType::kRsa:
-      return EVP_PKEY_bits(public_key_.get()) >= 2048;
-    case PublicKeyType::kP256:
-    case PublicKeyType::kP384:
-    case PublicKeyType::kEd25519:
-      return true;
-    default:
-      return false;
-  }
-}
-
-bool CertificateView::VerifySignature(absl::string_view data,
-                                      absl::string_view signature,
-                                      uint16_t signature_algorithm) const {
-  if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) !=
-      PublicKeyTypeFromKey(public_key_.get())) {
-    QUIC_BUG(quic_bug_10640_1)
-        << "Mismatch between the requested signature algorithm and the "
-           "type of the public key.";
-    return false;
-  }
-
-  bssl::ScopedEVP_MD_CTX md_ctx;
-  EVP_PKEY_CTX* pctx;
-  if (!EVP_DigestVerifyInit(
-          md_ctx.get(), &pctx,
-          SSL_get_signature_algorithm_digest(signature_algorithm), nullptr,
-          public_key_.get())) {
-    return false;
-  }
-  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
-    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
-        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
-      return false;
-    }
-  }
-  return EVP_DigestVerify(
-      md_ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
-      signature.size(), reinterpret_cast<const uint8_t*>(data.data()),
-      data.size());
-}
-
-absl::optional<std::string> CertificateView::GetHumanReadableSubject() const {
-  CBS input = StringPieceToCbs(subject_der_);
-  return DistinguishedNameToString(input);
-}
-
-std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadFromDer(
-    absl::string_view private_key) {
-  std::unique_ptr<CertificatePrivateKey> result(new CertificatePrivateKey());
-  CBS private_key_cbs = StringPieceToCbs(private_key);
-  result->private_key_.reset(EVP_parse_private_key(&private_key_cbs));
-  if (result->private_key_ == nullptr || CBS_len(&private_key_cbs) != 0) {
-    return nullptr;
-  }
-  return result;
-}
-
-std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadPemFromStream(
-    std::istream* input) {
-skip:
-  PemReadResult result = ReadNextPemMessage(input);
-  if (result.status != PemReadResult::kOk) {
-    return nullptr;
-  }
-  // RFC 5958 OneAsymmetricKey message.
-  if (result.type == "PRIVATE KEY") {
-    return LoadFromDer(result.contents);
-  }
-  // Legacy OpenSSL format: PKCS#1 (RFC 8017) RSAPrivateKey message.
-  if (result.type == "RSA PRIVATE KEY") {
-    CBS private_key_cbs = StringPieceToCbs(result.contents);
-    bssl::UniquePtr<RSA> rsa(RSA_parse_private_key(&private_key_cbs));
-    if (rsa == nullptr || CBS_len(&private_key_cbs) != 0) {
-      return nullptr;
-    }
-
-    std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
-    key->private_key_.reset(EVP_PKEY_new());
-    EVP_PKEY_assign_RSA(key->private_key_.get(), rsa.release());
-    return key;
-  }
-  // EC keys are sometimes generated with "openssl ecparam -genkey". If the user
-  // forgets -noout, OpenSSL will output a redundant copy of the EC parameters.
-  // Skip those.
-  if (result.type == "EC PARAMETERS") {
-    goto skip;
-  }
-  // Legacy OpenSSL format: RFC 5915 ECPrivateKey message.
-  if (result.type == "EC PRIVATE KEY") {
-    CBS private_key_cbs = StringPieceToCbs(result.contents);
-    bssl::UniquePtr<EC_KEY> ec_key(
-        EC_KEY_parse_private_key(&private_key_cbs, /*group=*/nullptr));
-    if (ec_key == nullptr || CBS_len(&private_key_cbs) != 0) {
-      return nullptr;
-    }
-
-    std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
-    key->private_key_.reset(EVP_PKEY_new());
-    EVP_PKEY_assign_EC_KEY(key->private_key_.get(), ec_key.release());
-    return key;
-  }
-  // Unknown format.
-  return nullptr;
-}
-
-std::string CertificatePrivateKey::Sign(absl::string_view input,
-                                        uint16_t signature_algorithm) const {
-  if (!ValidForSignatureAlgorithm(signature_algorithm)) {
-    QUIC_BUG(quic_bug_10640_2)
-        << "Mismatch between the requested signature algorithm and the "
-           "type of the private key.";
-    return "";
-  }
-
-  bssl::ScopedEVP_MD_CTX md_ctx;
-  EVP_PKEY_CTX* pctx;
-  if (!EVP_DigestSignInit(
-          md_ctx.get(), &pctx,
-          SSL_get_signature_algorithm_digest(signature_algorithm),
-          /*e=*/nullptr, private_key_.get())) {
-    return "";
-  }
-  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
-    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
-        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
-      return "";
-    }
-  }
-
-  std::string output;
-  size_t output_size;
-  if (!EVP_DigestSign(md_ctx.get(), /*out_sig=*/nullptr, &output_size,
-                      reinterpret_cast<const uint8_t*>(input.data()),
-                      input.size())) {
-    return "";
-  }
-  output.resize(output_size);
-  if (!EVP_DigestSign(
-          md_ctx.get(), reinterpret_cast<uint8_t*>(&output[0]), &output_size,
-          reinterpret_cast<const uint8_t*>(input.data()), input.size())) {
-    return "";
-  }
-  output.resize(output_size);
-  return output;
-}
-
-bool CertificatePrivateKey::MatchesPublicKey(
-    const CertificateView& view) const {
-  return EVP_PKEY_cmp(view.public_key(), private_key_.get()) == 1;
-}
-
-bool CertificatePrivateKey::ValidForSignatureAlgorithm(
-    uint16_t signature_algorithm) const {
-  return PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) ==
-         PublicKeyTypeFromKey(private_key_.get());
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/certificate_view.h b/quic/core/crypto/certificate_view.h
deleted file mode 100644
index 5b3c8c7..0000000
--- a/quic/core/crypto/certificate_view.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
-
-#include <istream>
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE PemReadResult {
-  enum Status { kOk, kEof, kError };
-  Status status;
-  std::string contents;
-  // The type of the PEM message (e.g., if the message starts with
-  // "-----BEGIN CERTIFICATE-----", the |type| would be "CERTIFICATE").
-  std::string type;
-};
-
-// Reads |input| line-by-line and returns the next available PEM message.
-QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input);
-
-// Cryptograhpic algorithms recognized in X.509.
-enum class PublicKeyType {
-  kRsa,
-  kP256,
-  kP384,
-  kEd25519,
-  kUnknown,
-};
-QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type);
-
-// CertificateView represents a parsed version of a single X.509 certificate. As
-// the word "view" implies, it does not take ownership of the underlying strings
-// and consists primarily of pointers into the certificate that is passed into
-// the parser.
-class QUIC_EXPORT_PRIVATE CertificateView {
- public:
-  // Parses a single DER-encoded X.509 certificate.  Returns nullptr on parse
-  // error.
-  static std::unique_ptr<CertificateView> ParseSingleCertificate(
-      absl::string_view certificate);
-
-  // Loads all PEM-encoded X.509 certificates found in the |input| stream
-  // without parsing them.  Returns an empty vector if any parsing error occurs.
-  static std::vector<std::string> LoadPemFromStream(std::istream* input);
-
-  QuicWallTime validity_start() const { return validity_start_; }
-  QuicWallTime validity_end() const { return validity_end_; }
-  const EVP_PKEY* public_key() const { return public_key_.get(); }
-
-  const std::vector<absl::string_view>& subject_alt_name_domains() const {
-    return subject_alt_name_domains_;
-  }
-  const std::vector<QuicIpAddress>& subject_alt_name_ips() const {
-    return subject_alt_name_ips_;
-  }
-
-  // Returns a human-readable representation of the Subject field.  The format
-  // is similar to RFC 2253, but does not match it exactly.
-  absl::optional<std::string> GetHumanReadableSubject() const;
-
-  // |signature_algorithm| is a TLS signature algorithm ID.
-  bool VerifySignature(absl::string_view data,
-                       absl::string_view signature,
-                       uint16_t signature_algorithm) const;
-
-  // Returns the type of the key used in the certificate's SPKI.
-  PublicKeyType public_key_type() const;
-
- private:
-  CertificateView() = default;
-
-  QuicWallTime validity_start_ = QuicWallTime::Zero();
-  QuicWallTime validity_end_ = QuicWallTime::Zero();
-  absl::string_view subject_der_;
-
-  // Public key parsed from SPKI.
-  bssl::UniquePtr<EVP_PKEY> public_key_;
-
-  // SubjectAltName, https://tools.ietf.org/html/rfc5280#section-4.2.1.6
-  std::vector<absl::string_view> subject_alt_name_domains_;
-  std::vector<QuicIpAddress> subject_alt_name_ips_;
-
-  // Called from ParseSingleCertificate().
-  bool ParseExtensions(CBS extensions);
-  bool ValidatePublicKeyParameters();
-};
-
-// CertificatePrivateKey represents a private key that can be used with an X.509
-// certificate.
-class QUIC_EXPORT_PRIVATE CertificatePrivateKey {
- public:
-  explicit CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY> private_key)
-      : private_key_(std::move(private_key)) {}
-
-  // Loads a DER-encoded PrivateKeyInfo structure (RFC 5958) as a private key.
-  static std::unique_ptr<CertificatePrivateKey> LoadFromDer(
-      absl::string_view private_key);
-
-  // Loads a private key from a PEM file formatted according to RFC 7468.  Also
-  // supports legacy OpenSSL RSA key format ("BEGIN RSA PRIVATE KEY").
-  static std::unique_ptr<CertificatePrivateKey> LoadPemFromStream(
-      std::istream* input);
-
-  // |signature_algorithm| is a TLS signature algorithm ID.
-  std::string Sign(absl::string_view input, uint16_t signature_algorithm) const;
-
-  // Verifies that the private key in question matches the public key of the
-  // certificate |view|.
-  bool MatchesPublicKey(const CertificateView& view) const;
-
-  // Verifies that the private key can be used with the specified TLS signature
-  // algorithm.
-  bool ValidForSignatureAlgorithm(uint16_t signature_algorithm) const;
-
-  EVP_PKEY* private_key() const { return private_key_.get(); }
-
- private:
-  CertificatePrivateKey() = default;
-
-  bssl::UniquePtr<EVP_PKEY> private_key_;
-};
-
-// Parses a DER-encoded X.509 NameAttribute.  Exposed primarily for testing.
-QUIC_EXPORT_PRIVATE absl::optional<std::string> X509NameAttributeToString(
-    CBS input);
-
-// Parses a DER time based on the specified ASN.1 tag.  Exposed primarily for
-// testing.
-QUIC_EXPORT_PRIVATE absl::optional<quic::QuicWallTime> ParseDerTime(
-    unsigned tag,
-    absl::string_view payload);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
diff --git a/quic/core/crypto/certificate_view_der_fuzzer.cc b/quic/core/crypto/certificate_view_der_fuzzer.cc
deleted file mode 100644
index da931a2..0000000
--- a/quic/core/crypto/certificate_view_der_fuzzer.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "quic/core/crypto/certificate_view.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  std::string input(reinterpret_cast<const char*>(data), size);
-
-  std::unique_ptr<quic::CertificateView> view =
-      quic::CertificateView::ParseSingleCertificate(input);
-  if (view != nullptr) {
-    view->GetHumanReadableSubject();
-  }
-  quic::CertificatePrivateKey::LoadFromDer(input);
-  return 0;
-}
diff --git a/quic/core/crypto/certificate_view_pem_fuzzer.cc b/quic/core/crypto/certificate_view_pem_fuzzer.cc
deleted file mode 100644
index b317bef..0000000
--- a/quic/core/crypto/certificate_view_pem_fuzzer.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <sstream>
-#include <string>
-
-#include "quic/core/crypto/certificate_view.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  std::string input(reinterpret_cast<const char*>(data), size);
-  std::stringstream stream(input);
-
-  quic::CertificateView::LoadPemFromStream(&stream);
-  stream.seekg(0);
-  quic::CertificatePrivateKey::LoadPemFromStream(&stream);
-  return 0;
-}
diff --git a/quic/core/crypto/certificate_view_test.cc b/quic/core/crypto/certificate_view_test.cc
deleted file mode 100644
index fbca915..0000000
--- a/quic/core/crypto/certificate_view_test.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/certificate_view.h"
-
-#include <memory>
-#include <sstream>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/boring_utils.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/test_certificates.h"
-#include "common/platform/api/quiche_time_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::HasSubstr;
-using ::testing::Optional;
-
-TEST(CertificateViewTest, PemParser) {
-  std::stringstream stream(kTestCertificatePem);
-  PemReadResult result = ReadNextPemMessage(&stream);
-  EXPECT_EQ(result.status, PemReadResult::kOk);
-  EXPECT_EQ(result.type, "CERTIFICATE");
-  EXPECT_EQ(result.contents, kTestCertificate);
-
-  result = ReadNextPemMessage(&stream);
-  EXPECT_EQ(result.status, PemReadResult::kEof);
-}
-
-TEST(CertificateViewTest, Parse) {
-  std::unique_ptr<CertificateView> view =
-      CertificateView::ParseSingleCertificate(kTestCertificate);
-  ASSERT_TRUE(view != nullptr);
-
-  EXPECT_THAT(view->subject_alt_name_domains(),
-              ElementsAre(absl::string_view("www.example.org"),
-                          absl::string_view("mail.example.org"),
-                          absl::string_view("mail.example.com")));
-  EXPECT_THAT(view->subject_alt_name_ips(),
-              ElementsAre(QuicIpAddress::Loopback4()));
-  EXPECT_EQ(EVP_PKEY_id(view->public_key()), EVP_PKEY_RSA);
-
-  const QuicWallTime validity_start = QuicWallTime::FromUNIXSeconds(
-      *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 1, 30, 18, 13, 59));
-  EXPECT_EQ(view->validity_start(), validity_start);
-  const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds(
-      *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59));
-  EXPECT_EQ(view->validity_end(), validity_end);
-  EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa);
-  EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA");
-
-  EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1",
-            view->GetHumanReadableSubject());
-}
-
-TEST(CertificateViewTest, ParseCertWithUnknownSanType) {
-  std::stringstream stream(kTestCertWithUnknownSanTypePem);
-  PemReadResult result = ReadNextPemMessage(&stream);
-  EXPECT_EQ(result.status, PemReadResult::kOk);
-  EXPECT_EQ(result.type, "CERTIFICATE");
-
-  std::unique_ptr<CertificateView> view =
-      CertificateView::ParseSingleCertificate(result.contents);
-  EXPECT_TRUE(view != nullptr);
-}
-
-TEST(CertificateViewTest, PemSingleCertificate) {
-  std::stringstream pem_stream(kTestCertificatePem);
-  std::vector<std::string> chain =
-      CertificateView::LoadPemFromStream(&pem_stream);
-  EXPECT_THAT(chain, ElementsAre(kTestCertificate));
-}
-
-TEST(CertificateViewTest, PemMultipleCertificates) {
-  std::stringstream pem_stream(kTestCertificateChainPem);
-  std::vector<std::string> chain =
-      CertificateView::LoadPemFromStream(&pem_stream);
-  EXPECT_THAT(chain,
-              ElementsAre(kTestCertificate, HasSubstr("QUIC Server Root CA")));
-}
-
-TEST(CertificateViewTest, PemNoCertificates) {
-  std::stringstream pem_stream("one\ntwo\nthree\n");
-  std::vector<std::string> chain =
-      CertificateView::LoadPemFromStream(&pem_stream);
-  EXPECT_TRUE(chain.empty());
-}
-
-TEST(CertificateViewTest, SignAndVerify) {
-  std::unique_ptr<CertificatePrivateKey> key =
-      CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
-  ASSERT_TRUE(key != nullptr);
-
-  std::string data = "A really important message";
-  std::string signature = key->Sign(data, SSL_SIGN_RSA_PSS_RSAE_SHA256);
-  ASSERT_FALSE(signature.empty());
-
-  std::unique_ptr<CertificateView> view =
-      CertificateView::ParseSingleCertificate(kTestCertificate);
-  ASSERT_TRUE(view != nullptr);
-  EXPECT_TRUE(key->MatchesPublicKey(*view));
-
-  EXPECT_TRUE(
-      view->VerifySignature(data, signature, SSL_SIGN_RSA_PSS_RSAE_SHA256));
-  EXPECT_FALSE(view->VerifySignature("An unimportant message", signature,
-                                     SSL_SIGN_RSA_PSS_RSAE_SHA256));
-  EXPECT_FALSE(view->VerifySignature(data, "Not a signature",
-                                     SSL_SIGN_RSA_PSS_RSAE_SHA256));
-}
-
-TEST(CertificateViewTest, PrivateKeyPem) {
-  std::unique_ptr<CertificateView> view =
-      CertificateView::ParseSingleCertificate(kTestCertificate);
-  ASSERT_TRUE(view != nullptr);
-
-  std::stringstream pem_stream(kTestCertificatePrivateKeyPem);
-  std::unique_ptr<CertificatePrivateKey> pem_key =
-      CertificatePrivateKey::LoadPemFromStream(&pem_stream);
-  ASSERT_TRUE(pem_key != nullptr);
-  EXPECT_TRUE(pem_key->MatchesPublicKey(*view));
-
-  std::stringstream legacy_stream(kTestCertificatePrivateKeyLegacyPem);
-  std::unique_ptr<CertificatePrivateKey> legacy_key =
-      CertificatePrivateKey::LoadPemFromStream(&legacy_stream);
-  ASSERT_TRUE(legacy_key != nullptr);
-  EXPECT_TRUE(legacy_key->MatchesPublicKey(*view));
-}
-
-TEST(CertificateViewTest, PrivateKeyEcdsaPem) {
-  std::stringstream pem_stream(kTestEcPrivateKeyLegacyPem);
-  std::unique_ptr<CertificatePrivateKey> key =
-      CertificatePrivateKey::LoadPemFromStream(&pem_stream);
-  ASSERT_TRUE(key != nullptr);
-  EXPECT_TRUE(key->ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
-}
-
-TEST(CertificateViewTest, DerTime) {
-  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Z"),
-              Optional(QuicWallTime::FromUNIXSeconds(24)));
-  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19710101000024Z"),
-              Optional(QuicWallTime::FromUNIXSeconds(365 * 86400 + 24)));
-  EXPECT_THAT(ParseDerTime(CBS_ASN1_UTCTIME, "700101000024Z"),
-              Optional(QuicWallTime::FromUNIXSeconds(24)));
-  EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "200101000024Z").has_value());
-
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, ""), absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.001Z"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Q"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024-0500"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "700101000024ZZ"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.00Z"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.Z"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "197O0101000024Z"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.0O1Z"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "-9700101000024Z"),
-            absl::nullopt);
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "1970-101000024Z"),
-            absl::nullopt);
-
-  EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "490101000024Z").has_value());
-  // This should parse as 1950, which predates UNIX epoch.
-  EXPECT_FALSE(ParseDerTime(CBS_ASN1_UTCTIME, "500101000024Z").has_value());
-
-  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101230000Z"),
-              Optional(QuicWallTime::FromUNIXSeconds(23 * 3600)));
-  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101240000Z"),
-            absl::nullopt);
-}
-
-TEST(CertificateViewTest, NameAttribute) {
-  // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.112411 }
-  // UTF8String { "Test" }
-  std::string unknown_oid =
-      absl::HexStringToBytes("060b2a864886f712040186ee1b0c0454657374");
-  EXPECT_EQ("1.2.840.113554.4.1.112411=Test",
-            X509NameAttributeToString(StringPieceToCbs(unknown_oid)));
-
-  // OBJECT_IDENTIFIER { 2.5.4.3 }
-  // UTF8String { "Bell: \x07" }
-  std::string non_printable =
-      absl::HexStringToBytes("06035504030c0742656c6c3a2007");
-  EXPECT_EQ(R"(CN=Bell: \x07)",
-            X509NameAttributeToString(StringPieceToCbs(non_printable)));
-
-  // OBJECT_IDENTIFIER { "\x55\x80" }
-  // UTF8String { "Test" }
-  std::string invalid_oid = absl::HexStringToBytes("060255800c0454657374");
-  EXPECT_EQ("(5580)=Test",
-            X509NameAttributeToString(StringPieceToCbs(invalid_oid)));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_decrypter.cc b/quic/core/crypto/chacha20_poly1305_decrypter.cc
deleted file mode 100644
index 8a4571b..0000000
--- a/quic/core/crypto/chacha20_poly1305_decrypter.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
-    : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
-                          kKeySize,
-                          kAuthTagSize,
-                          kNonceSize,
-                          /* use_ietf_nonce_construction */ false) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
-
-uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
-  return TLS1_CK_CHACHA20_POLY1305_SHA256;
-}
-
-QuicPacketCount ChaCha20Poly1305Decrypter::GetIntegrityLimit() const {
-  // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
-  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
-  static_assert(kMaxIncomingPacketSize < 16384,
-                "This key limit requires limits on decryption payload sizes");
-  return 68719476736U;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_decrypter.h b/quic/core/crypto/chacha20_poly1305_decrypter.h
deleted file mode 100644
index f6af33d..0000000
--- a/quic/core/crypto/chacha20_poly1305_decrypter.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/chacha_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305Decrypter is a QuicDecrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
-// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
-// by calling QuicDecrypter::Create(kCC20).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
-// nonce is four bytes.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Decrypter
-    : public ChaChaBaseDecrypter {
- public:
-  enum {
-    kAuthTagSize = 12,
-  };
-
-  ChaCha20Poly1305Decrypter();
-  ChaCha20Poly1305Decrypter(const ChaCha20Poly1305Decrypter&) = delete;
-  ChaCha20Poly1305Decrypter& operator=(const ChaCha20Poly1305Decrypter&) =
-      delete;
-  ~ChaCha20Poly1305Decrypter() override;
-
-  uint32_t cipher_id() const override;
-  QuicPacketCount GetIntegrityLimit() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
diff --git a/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
deleted file mode 100644
index 93e48d2..0000000
--- a/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  // Input:
-  const char* key;
-  const char* iv;
-  const char* fixed;
-  const char* aad;
-  const char* ct;
-
-  // Expected output:
-  const char* pt;  // An empty string "" means decryption succeeded and
-                   // the plaintext is zero-length. nullptr means decryption
-                   // failed.
-};
-
-const TestVector test_vectors[] = {
-    {"808182838485868788898a8b8c8d8e8f"
-     "909192939495969798999a9b9c9d9e9f",
-
-     "4041424344454647",
-
-     "07000000",
-
-     "50515253c0c1c2c3c4c5c6c7",
-
-     "d31a8d34648e60db7b86afbc53ef7ec2"
-     "a4aded51296e08fea9e2b5a736ee62d6"
-     "3dbea45e8ca9671282fafb69da92728b"
-     "1a71de0a9e060b2905d6a5b67ecd3b36"
-     "92ddbd7f2d778b8c9803aee328091b58"
-     "fab324e4fad675945585808b4831d7bc"
-     "3ff4def08e4b7a9de576d26586cec64b"
-     "6116"
-     "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
-
-     "4c616469657320616e642047656e746c"
-     "656d656e206f662074686520636c6173"
-     "73206f66202739393a20496620492063"
-     "6f756c64206f6666657220796f75206f"
-     "6e6c79206f6e652074697020666f7220"
-     "746865206675747572652c2073756e73"
-     "637265656e20776f756c642062652069"
-     "742e"},
-    // Modify the ciphertext (Poly1305 authenticator).
-    {"808182838485868788898a8b8c8d8e8f"
-     "909192939495969798999a9b9c9d9e9f",
-
-     "4041424344454647",
-
-     "07000000",
-
-     "50515253c0c1c2c3c4c5c6c7",
-
-     "d31a8d34648e60db7b86afbc53ef7ec2"
-     "a4aded51296e08fea9e2b5a736ee62d6"
-     "3dbea45e8ca9671282fafb69da92728b"
-     "1a71de0a9e060b2905d6a5b67ecd3b36"
-     "92ddbd7f2d778b8c9803aee328091b58"
-     "fab324e4fad675945585808b4831d7bc"
-     "3ff4def08e4b7a9de576d26586cec64b"
-     "6116"
-     "1ae10b594f09e26a7e902ecc",  // "d0600691" truncated
-
-     nullptr},
-    // Modify the associated data.
-    {"808182838485868788898a8b8c8d8e8f"
-     "909192939495969798999a9b9c9d9e9f",
-
-     "4041424344454647",
-
-     "07000000",
-
-     "60515253c0c1c2c3c4c5c6c7",
-
-     "d31a8d34648e60db7b86afbc53ef7ec2"
-     "a4aded51296e08fea9e2b5a736ee62d6"
-     "3dbea45e8ca9671282fafb69da92728b"
-     "1a71de0a9e060b2905d6a5b67ecd3b36"
-     "92ddbd7f2d778b8c9803aee328091b58"
-     "fab324e4fad675945585808b4831d7bc"
-     "3ff4def08e4b7a9de576d26586cec64b"
-     "6116"
-     "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
-
-     nullptr},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view ciphertext) {
-  uint64_t packet_number;
-  absl::string_view nonce_prefix(nonce.data(),
-                                 nonce.size() - sizeof(packet_number));
-  decrypter->SetNoncePrefix(nonce_prefix);
-  memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
-         sizeof(packet_number));
-  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
-  size_t output_length = 0;
-  const bool success = decrypter->DecryptPacket(
-      packet_number, associated_data, ciphertext, output.get(), &output_length,
-      ciphertext.length());
-  if (!success) {
-    return nullptr;
-  }
-  return new QuicData(output.release(), output_length, true);
-}
-
-class ChaCha20Poly1305DecrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) {
-  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
-    // If not present then decryption is expected to fail.
-    bool has_pt = test_vectors[i].pt;
-
-    // Decode the test vector.
-    std::string key = absl::HexStringToBytes(test_vectors[i].key);
-    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
-    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
-    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
-    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
-    std::string pt;
-    if (has_pt) {
-      pt = absl::HexStringToBytes(test_vectors[i].pt);
-    }
-
-    ChaCha20Poly1305Decrypter decrypter;
-    ASSERT_TRUE(decrypter.SetKey(key));
-    std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
-        &decrypter, fixed + iv,
-        // This deliberately tests that the decrypter can handle an AAD that
-        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
-        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
-        ct));
-    if (!decrypted) {
-      EXPECT_FALSE(has_pt);
-      continue;
-    }
-    EXPECT_TRUE(has_pt);
-
-    EXPECT_EQ(12u, ct.size() - decrypted->length());
-    ASSERT_EQ(pt.length(), decrypted->length());
-    quiche::test::CompareCharArraysWithHexError(
-        "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_encrypter.cc b/quic/core/crypto/chacha20_poly1305_encrypter.cc
deleted file mode 100644
index 09be04f..0000000
--- a/quic/core/crypto/chacha20_poly1305_encrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
-    : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
-                          kKeySize,
-                          kAuthTagSize,
-                          kNonceSize,
-                          /* use_ietf_nonce_construction */ false) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {}
-
-QuicPacketCount ChaCha20Poly1305Encrypter::GetConfidentialityLimit() const {
-  // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
-  // number of possible packets (2^62) and so can be disregarded.
-  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
-  return std::numeric_limits<QuicPacketCount>::max();
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_encrypter.h b/quic/core/crypto/chacha20_poly1305_encrypter.h
deleted file mode 100644
index 3f58b59..0000000
--- a/quic/core/crypto/chacha20_poly1305_encrypter.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
-
-#include "quic/core/crypto/chacha_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
-// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
-// by calling QuicEncrypter::Create(kCC20).
-//
-// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
-// nonce is four bytes.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Encrypter
-    : public ChaChaBaseEncrypter {
- public:
-  enum {
-    kAuthTagSize = 12,
-  };
-
-  ChaCha20Poly1305Encrypter();
-  ChaCha20Poly1305Encrypter(const ChaCha20Poly1305Encrypter&) = delete;
-  ChaCha20Poly1305Encrypter& operator=(const ChaCha20Poly1305Encrypter&) =
-      delete;
-  ~ChaCha20Poly1305Encrypter() override;
-
-  QuicPacketCount GetConfidentialityLimit() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
diff --git a/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
deleted file mode 100644
index 7fc3282..0000000
--- a/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of five strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  const char* key;
-  const char* pt;
-  const char* iv;
-  const char* fixed;
-  const char* aad;
-  const char* ct;
-};
-
-const TestVector test_vectors[] = {
-    {
-        "808182838485868788898a8b8c8d8e8f"
-        "909192939495969798999a9b9c9d9e9f",
-
-        "4c616469657320616e642047656e746c"
-        "656d656e206f662074686520636c6173"
-        "73206f66202739393a20496620492063"
-        "6f756c64206f6666657220796f75206f"
-        "6e6c79206f6e652074697020666f7220"
-        "746865206675747572652c2073756e73"
-        "637265656e20776f756c642062652069"
-        "742e",
-
-        "4041424344454647",
-
-        "07000000",
-
-        "50515253c0c1c2c3c4c5c6c7",
-
-        "d31a8d34648e60db7b86afbc53ef7ec2"
-        "a4aded51296e08fea9e2b5a736ee62d6"
-        "3dbea45e8ca9671282fafb69da92728b"
-        "1a71de0a9e060b2905d6a5b67ecd3b36"
-        "92ddbd7f2d778b8c9803aee328091b58"
-        "fab324e4fad675945585808b4831d7bc"
-        "3ff4def08e4b7a9de576d26586cec64b"
-        "6116"
-        "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view plaintext) {
-  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
-  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
-  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
-                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
-    return nullptr;
-  }
-
-  return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class ChaCha20Poly1305EncrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) {
-  ChaCha20Poly1305Encrypter encrypter;
-  ChaCha20Poly1305Decrypter decrypter;
-
-  std::string key = absl::HexStringToBytes(test_vectors[0].key);
-  ASSERT_TRUE(encrypter.SetKey(key));
-  ASSERT_TRUE(decrypter.SetKey(key));
-  ASSERT_TRUE(encrypter.SetNoncePrefix("abcd"));
-  ASSERT_TRUE(decrypter.SetNoncePrefix("abcd"));
-
-  uint64_t packet_number = UINT64_C(0x123456789ABC);
-  std::string associated_data = "associated_data";
-  std::string plaintext = "plaintext";
-  char encrypted[1024];
-  size_t len;
-  ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
-                                      encrypted, &len,
-                                      ABSL_ARRAYSIZE(encrypted)));
-  absl::string_view ciphertext(encrypted, len);
-  char decrypted[1024];
-  ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
-                                      ciphertext, decrypted, &len,
-                                      ABSL_ARRAYSIZE(decrypted)));
-}
-
-TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) {
-  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
-    // Decode the test vector.
-    std::string key = absl::HexStringToBytes(test_vectors[i].key);
-    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
-    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
-    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
-    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
-    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
-
-    ChaCha20Poly1305Encrypter encrypter;
-    ASSERT_TRUE(encrypter.SetKey(key));
-    std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
-        &encrypter, fixed + iv,
-        // This deliberately tests that the encrypter can handle an AAD that
-        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
-        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
-        pt));
-    ASSERT_TRUE(encrypted.get());
-    EXPECT_EQ(12u, ct.size() - pt.size());
-    EXPECT_EQ(12u, encrypted->length() - pt.size());
-
-    quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
-                                                encrypted->length(), ct.data(),
-                                                ct.length());
-  }
-}
-
-TEST_F(ChaCha20Poly1305EncrypterTest, GetMaxPlaintextSize) {
-  ChaCha20Poly1305Encrypter encrypter;
-  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
-  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
-  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
-}
-
-TEST_F(ChaCha20Poly1305EncrypterTest, GetCiphertextSize) {
-  ChaCha20Poly1305Encrypter encrypter;
-  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
-  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
-  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc b/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
deleted file mode 100644
index 92cb132..0000000
--- a/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-ChaCha20Poly1305TlsDecrypter::ChaCha20Poly1305TlsDecrypter()
-    : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
-                          kKeySize,
-                          kAuthTagSize,
-                          kNonceSize,
-                          /* use_ietf_nonce_construction */ true) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305TlsDecrypter::~ChaCha20Poly1305TlsDecrypter() {}
-
-uint32_t ChaCha20Poly1305TlsDecrypter::cipher_id() const {
-  return TLS1_CK_CHACHA20_POLY1305_SHA256;
-}
-
-QuicPacketCount ChaCha20Poly1305TlsDecrypter::GetIntegrityLimit() const {
-  // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
-  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
-  static_assert(kMaxIncomingPacketSize < 16384,
-                "This key limit requires limits on decryption payload sizes");
-  return 68719476736U;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_tls_decrypter.h b/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
deleted file mode 100644
index 69abd89..0000000
--- a/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
-
-#include <cstdint>
-
-#include "quic/core/crypto/chacha_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305TlsDecrypter is a QuicDecrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 bytes IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsDecrypter
-    : public ChaChaBaseDecrypter {
- public:
-  enum {
-    kAuthTagSize = 16,
-  };
-
-  ChaCha20Poly1305TlsDecrypter();
-  ChaCha20Poly1305TlsDecrypter(const ChaCha20Poly1305TlsDecrypter&) = delete;
-  ChaCha20Poly1305TlsDecrypter& operator=(const ChaCha20Poly1305TlsDecrypter&) =
-      delete;
-  ~ChaCha20Poly1305TlsDecrypter() override;
-
-  uint32_t cipher_id() const override;
-  QuicPacketCount GetIntegrityLimit() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
diff --git a/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
deleted file mode 100644
index b71bcf1..0000000
--- a/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of six strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  // Input:
-  const char* key;
-  const char* iv;
-  const char* fixed;
-  const char* aad;
-  const char* ct;
-
-  // Expected output:
-  const char* pt;  // An empty string "" means decryption succeeded and
-                   // the plaintext is zero-length. nullptr means decryption
-                   // failed.
-};
-
-const TestVector test_vectors[] = {
-    {"808182838485868788898a8b8c8d8e8f"
-     "909192939495969798999a9b9c9d9e9f",
-
-     "4041424344454647",
-
-     "07000000",
-
-     "50515253c0c1c2c3c4c5c6c7",
-
-     "d31a8d34648e60db7b86afbc53ef7ec2"
-     "a4aded51296e08fea9e2b5a736ee62d6"
-     "3dbea45e8ca9671282fafb69da92728b"
-     "1a71de0a9e060b2905d6a5b67ecd3b36"
-     "92ddbd7f2d778b8c9803aee328091b58"
-     "fab324e4fad675945585808b4831d7bc"
-     "3ff4def08e4b7a9de576d26586cec64b"
-     "6116"
-     "1ae10b594f09e26a7e902ecbd0600691",
-
-     "4c616469657320616e642047656e746c"
-     "656d656e206f662074686520636c6173"
-     "73206f66202739393a20496620492063"
-     "6f756c64206f6666657220796f75206f"
-     "6e6c79206f6e652074697020666f7220"
-     "746865206675747572652c2073756e73"
-     "637265656e20776f756c642062652069"
-     "742e"},
-    // Modify the ciphertext (Poly1305 authenticator).
-    {"808182838485868788898a8b8c8d8e8f"
-     "909192939495969798999a9b9c9d9e9f",
-
-     "4041424344454647",
-
-     "07000000",
-
-     "50515253c0c1c2c3c4c5c6c7",
-
-     "d31a8d34648e60db7b86afbc53ef7ec2"
-     "a4aded51296e08fea9e2b5a736ee62d6"
-     "3dbea45e8ca9671282fafb69da92728b"
-     "1a71de0a9e060b2905d6a5b67ecd3b36"
-     "92ddbd7f2d778b8c9803aee328091b58"
-     "fab324e4fad675945585808b4831d7bc"
-     "3ff4def08e4b7a9de576d26586cec64b"
-     "6116"
-     "1ae10b594f09e26a7e902eccd0600691",
-
-     nullptr},
-    // Modify the associated data.
-    {"808182838485868788898a8b8c8d8e8f"
-     "909192939495969798999a9b9c9d9e9f",
-
-     "4041424344454647",
-
-     "07000000",
-
-     "60515253c0c1c2c3c4c5c6c7",
-
-     "d31a8d34648e60db7b86afbc53ef7ec2"
-     "a4aded51296e08fea9e2b5a736ee62d6"
-     "3dbea45e8ca9671282fafb69da92728b"
-     "1a71de0a9e060b2905d6a5b67ecd3b36"
-     "92ddbd7f2d778b8c9803aee328091b58"
-     "fab324e4fad675945585808b4831d7bc"
-     "3ff4def08e4b7a9de576d26586cec64b"
-     "6116"
-     "1ae10b594f09e26a7e902ecbd0600691",
-
-     nullptr},
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the plaintext.
-QuicData* DecryptWithNonce(ChaCha20Poly1305TlsDecrypter* decrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view ciphertext) {
-  decrypter->SetIV(nonce);
-  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
-  size_t output_length = 0;
-  const bool success =
-      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
-                               &output_length, ciphertext.length());
-  if (!success) {
-    return nullptr;
-  }
-  return new QuicData(output.release(), output_length, true);
-}
-
-class ChaCha20Poly1305TlsDecrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) {
-  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
-    // If not present then decryption is expected to fail.
-    bool has_pt = test_vectors[i].pt;
-
-    // Decode the test vector.
-    std::string key = absl::HexStringToBytes(test_vectors[i].key);
-    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
-    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
-    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
-    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
-    std::string pt;
-    if (has_pt) {
-      pt = absl::HexStringToBytes(test_vectors[i].pt);
-    }
-
-    ChaCha20Poly1305TlsDecrypter decrypter;
-    ASSERT_TRUE(decrypter.SetKey(key));
-    std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
-        &decrypter, fixed + iv,
-        // This deliberately tests that the decrypter can handle an AAD that
-        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
-        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
-        ct));
-    if (!decrypted) {
-      EXPECT_FALSE(has_pt);
-      continue;
-    }
-    EXPECT_TRUE(has_pt);
-
-    EXPECT_EQ(16u, ct.size() - decrypted->length());
-    ASSERT_EQ(pt.length(), decrypted->length());
-    quiche::test::CompareCharArraysWithHexError(
-        "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
-  }
-}
-
-TEST_F(ChaCha20Poly1305TlsDecrypterTest, GenerateHeaderProtectionMask) {
-  ChaCha20Poly1305TlsDecrypter decrypter;
-  std::string key = absl::HexStringToBytes(
-      "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
-  std::string sample =
-      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
-  QuicDataReader sample_reader(sample.data(), sample.size());
-  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
-  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
-  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
-  quiche::test::CompareCharArraysWithHexError(
-      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
-      expected_mask.size());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc b/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
deleted file mode 100644
index bbcb332..0000000
--- a/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
-
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kKeySize = 32;
-const size_t kNonceSize = 12;
-
-}  // namespace
-
-ChaCha20Poly1305TlsEncrypter::ChaCha20Poly1305TlsEncrypter()
-    : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
-                          kKeySize,
-                          kAuthTagSize,
-                          kNonceSize,
-                          /* use_ietf_nonce_construction */ true) {
-  static_assert(kKeySize <= kMaxKeySize, "key size too big");
-  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
-}
-
-ChaCha20Poly1305TlsEncrypter::~ChaCha20Poly1305TlsEncrypter() {}
-
-QuicPacketCount ChaCha20Poly1305TlsEncrypter::GetConfidentialityLimit() const {
-  // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
-  // number of possible packets (2^62) and so can be disregarded.
-  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
-  return std::numeric_limits<QuicPacketCount>::max();
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/chacha20_poly1305_tls_encrypter.h b/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
deleted file mode 100644
index 81a750f..0000000
--- a/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
-
-#include "quic/core/crypto/chacha_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
-// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
-//
-// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
-// that is XOR'd with the packet number to compute the nonce.
-class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsEncrypter
-    : public ChaChaBaseEncrypter {
- public:
-  enum {
-    kAuthTagSize = 16,
-  };
-
-  ChaCha20Poly1305TlsEncrypter();
-  ChaCha20Poly1305TlsEncrypter(const ChaCha20Poly1305TlsEncrypter&) = delete;
-  ChaCha20Poly1305TlsEncrypter& operator=(const ChaCha20Poly1305TlsEncrypter&) =
-      delete;
-  ~ChaCha20Poly1305TlsEncrypter() override;
-
-  QuicPacketCount GetConfidentialityLimit() const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
diff --git a/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
deleted file mode 100644
index 61aaac7..0000000
--- a/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace {
-
-// The test vectors come from RFC 7539 Section 2.8.2.
-
-// Each test vector consists of five strings of lowercase hexadecimal digits.
-// The strings may be empty (zero length). A test vector with a nullptr |key|
-// marks the end of an array of test vectors.
-struct TestVector {
-  const char* key;
-  const char* pt;
-  const char* iv;
-  const char* fixed;
-  const char* aad;
-  const char* ct;
-};
-
-const TestVector test_vectors[] = {
-    {
-        "808182838485868788898a8b8c8d8e8f"
-        "909192939495969798999a9b9c9d9e9f",
-
-        "4c616469657320616e642047656e746c"
-        "656d656e206f662074686520636c6173"
-        "73206f66202739393a20496620492063"
-        "6f756c64206f6666657220796f75206f"
-        "6e6c79206f6e652074697020666f7220"
-        "746865206675747572652c2073756e73"
-        "637265656e20776f756c642062652069"
-        "742e",
-
-        "4041424344454647",
-
-        "07000000",
-
-        "50515253c0c1c2c3c4c5c6c7",
-
-        "d31a8d34648e60db7b86afbc53ef7ec2"
-        "a4aded51296e08fea9e2b5a736ee62d6"
-        "3dbea45e8ca9671282fafb69da92728b"
-        "1a71de0a9e060b2905d6a5b67ecd3b36"
-        "92ddbd7f2d778b8c9803aee328091b58"
-        "fab324e4fad675945585808b4831d7bc"
-        "3ff4def08e4b7a9de576d26586cec64b"
-        "6116"
-        "1ae10b594f09e26a7e902ecbd0600691",
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
-
-}  // namespace
-
-namespace quic {
-namespace test {
-
-// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
-// in an nonce and also to allocate the buffer needed for the ciphertext.
-QuicData* EncryptWithNonce(ChaCha20Poly1305TlsEncrypter* encrypter,
-                           absl::string_view nonce,
-                           absl::string_view associated_data,
-                           absl::string_view plaintext) {
-  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
-  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
-
-  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
-                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
-    return nullptr;
-  }
-
-  return new QuicData(ciphertext.release(), ciphertext_size, true);
-}
-
-class ChaCha20Poly1305TlsEncrypterTest : public QuicTest {};
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) {
-  ChaCha20Poly1305TlsEncrypter encrypter;
-  ChaCha20Poly1305TlsDecrypter decrypter;
-
-  std::string key = absl::HexStringToBytes(test_vectors[0].key);
-  ASSERT_TRUE(encrypter.SetKey(key));
-  ASSERT_TRUE(decrypter.SetKey(key));
-  ASSERT_TRUE(encrypter.SetIV("abcdefghijkl"));
-  ASSERT_TRUE(decrypter.SetIV("abcdefghijkl"));
-
-  uint64_t packet_number = UINT64_C(0x123456789ABC);
-  std::string associated_data = "associated_data";
-  std::string plaintext = "plaintext";
-  char encrypted[1024];
-  size_t len;
-  ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
-                                      encrypted, &len,
-                                      ABSL_ARRAYSIZE(encrypted)));
-  absl::string_view ciphertext(encrypted, len);
-  char decrypted[1024];
-  ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
-                                      ciphertext, decrypted, &len,
-                                      ABSL_ARRAYSIZE(decrypted)));
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) {
-  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
-    // Decode the test vector.
-    std::string key = absl::HexStringToBytes(test_vectors[i].key);
-    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
-    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
-    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
-    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
-    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
-
-    ChaCha20Poly1305TlsEncrypter encrypter;
-    ASSERT_TRUE(encrypter.SetKey(key));
-    std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
-        &encrypter, fixed + iv,
-        // This deliberately tests that the encrypter can handle an AAD that
-        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
-        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
-        pt));
-    ASSERT_TRUE(encrypted.get());
-    EXPECT_EQ(16u, ct.size() - pt.size());
-    EXPECT_EQ(16u, encrypted->length() - pt.size());
-
-    quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
-                                                encrypted->length(), ct.data(),
-                                                ct.length());
-  }
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetMaxPlaintextSize) {
-  ChaCha20Poly1305TlsEncrypter encrypter;
-  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
-  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
-  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetCiphertextSize) {
-  ChaCha20Poly1305TlsEncrypter encrypter;
-  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
-  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
-  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
-}
-
-TEST_F(ChaCha20Poly1305TlsEncrypterTest, GenerateHeaderProtectionMask) {
-  ChaCha20Poly1305TlsEncrypter encrypter;
-  std::string key = absl::HexStringToBytes(
-      "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
-  std::string sample =
-      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
-  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
-  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
-  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
-  quiche::test::CompareCharArraysWithHexError(
-      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
-      expected_mask.size());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/chacha_base_decrypter.cc b/quic/core/crypto/chacha_base_decrypter.cc
deleted file mode 100644
index b1be3d6..0000000
--- a/quic/core/crypto/chacha_base_decrypter.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha_base_decrypter.h"
-
-#include <cstdint>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-bool ChaChaBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
-  if (key.size() != GetKeySize()) {
-    QUIC_BUG(quic_bug_10620_1) << "Invalid key size for header protection";
-    return false;
-  }
-  memcpy(pne_key_, key.data(), key.size());
-  return true;
-}
-
-std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask(
-    QuicDataReader* sample_reader) {
-  absl::string_view sample;
-  if (!sample_reader->ReadStringPiece(&sample, 16)) {
-    return std::string();
-  }
-  const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
-  uint32_t counter;
-  QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
-      .ReadUInt32(&counter);
-  const uint8_t zeroes[] = {0, 0, 0, 0, 0};
-  std::string out(ABSL_ARRAYSIZE(zeroes), 0);
-  CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
-                   zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
-  return out;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/chacha_base_decrypter.h b/quic/core/crypto/chacha_base_decrypter.h
deleted file mode 100644
index 4348cac..0000000
--- a/quic/core/crypto/chacha_base_decrypter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/aead_base_decrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE ChaChaBaseDecrypter : public AeadBaseDecrypter {
- public:
-  using AeadBaseDecrypter::AeadBaseDecrypter;
-
-  bool SetHeaderProtectionKey(absl::string_view key) override;
-  std::string GenerateHeaderProtectionMask(
-      QuicDataReader* sample_reader) override;
-
- private:
-  // The key used for packet number encryption.
-  unsigned char pne_key_[kMaxKeySize];
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
diff --git a/quic/core/crypto/chacha_base_encrypter.cc b/quic/core/crypto/chacha_base_encrypter.cc
deleted file mode 100644
index 1dfe8e6..0000000
--- a/quic/core/crypto/chacha_base_encrypter.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/chacha_base_encrypter.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-bool ChaChaBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
-  if (key.size() != GetKeySize()) {
-    QUIC_BUG(quic_bug_10656_1) << "Invalid key size for header protection";
-    return false;
-  }
-  memcpy(pne_key_, key.data(), key.size());
-  return true;
-}
-
-std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask(
-    absl::string_view sample) {
-  if (sample.size() != 16) {
-    return std::string();
-  }
-  const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
-  uint32_t counter;
-  QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
-      .ReadUInt32(&counter);
-  const uint8_t zeroes[] = {0, 0, 0, 0, 0};
-  std::string out(ABSL_ARRAYSIZE(zeroes), 0);
-  CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
-                   zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
-  return out;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/chacha_base_encrypter.h b/quic/core/crypto/chacha_base_encrypter.h
deleted file mode 100644
index 4b48963..0000000
--- a/quic/core/crypto/chacha_base_encrypter.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/aead_base_encrypter.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE ChaChaBaseEncrypter : public AeadBaseEncrypter {
- public:
-  using AeadBaseEncrypter::AeadBaseEncrypter;
-
-  bool SetHeaderProtectionKey(absl::string_view key) override;
-  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
-
- private:
-  // The key used for packet number encryption.
-  unsigned char pne_key_[kMaxKeySize];
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
diff --git a/quic/core/crypto/channel_id.cc b/quic/core/crypto/channel_id.cc
deleted file mode 100644
index 2d6f825..0000000
--- a/quic/core/crypto/channel_id.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/channel_id.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bn.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ecdsa.h"
-#include "third_party/boringssl/src/include/openssl/nid.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-
-namespace quic {
-
-// static
-const char ChannelIDVerifier::kContextStr[] = "QUIC ChannelID";
-// static
-const char ChannelIDVerifier::kClientToServerStr[] = "client -> server";
-
-// static
-bool ChannelIDVerifier::Verify(absl::string_view key,
-                               absl::string_view signed_data,
-                               absl::string_view signature) {
-  return VerifyRaw(key, signed_data, signature, true);
-}
-
-// static
-bool ChannelIDVerifier::VerifyRaw(absl::string_view key,
-                                  absl::string_view signed_data,
-                                  absl::string_view signature,
-                                  bool is_channel_id_signature) {
-  if (key.size() != 32 * 2 || signature.size() != 32 * 2) {
-    return false;
-  }
-
-  bssl::UniquePtr<EC_GROUP> p256(
-      EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
-  if (p256.get() == nullptr) {
-    return false;
-  }
-
-  bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), r(BN_new()), s(BN_new());
-
-  ECDSA_SIG sig;
-  sig.r = r.get();
-  sig.s = s.get();
-
-  const uint8_t* key_bytes = reinterpret_cast<const uint8_t*>(key.data());
-  const uint8_t* signature_bytes =
-      reinterpret_cast<const uint8_t*>(signature.data());
-
-  if (BN_bin2bn(key_bytes + 0, 32, x.get()) == nullptr ||
-      BN_bin2bn(key_bytes + 32, 32, y.get()) == nullptr ||
-      BN_bin2bn(signature_bytes + 0, 32, sig.r) == nullptr ||
-      BN_bin2bn(signature_bytes + 32, 32, sig.s) == nullptr) {
-    return false;
-  }
-
-  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
-  if (point.get() == nullptr ||
-      !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
-                                           y.get(), nullptr)) {
-    return false;
-  }
-
-  bssl::UniquePtr<EC_KEY> ecdsa_key(EC_KEY_new());
-  if (ecdsa_key.get() == nullptr ||
-      !EC_KEY_set_group(ecdsa_key.get(), p256.get()) ||
-      !EC_KEY_set_public_key(ecdsa_key.get(), point.get())) {
-    return false;
-  }
-
-  SHA256_CTX sha256;
-  SHA256_Init(&sha256);
-  if (is_channel_id_signature) {
-    SHA256_Update(&sha256, kContextStr, strlen(kContextStr) + 1);
-    SHA256_Update(&sha256, kClientToServerStr, strlen(kClientToServerStr) + 1);
-  }
-  SHA256_Update(&sha256, signed_data.data(), signed_data.size());
-
-  unsigned char digest[SHA256_DIGEST_LENGTH];
-  SHA256_Final(digest, &sha256);
-
-  return ECDSA_do_verify(digest, sizeof(digest), &sig, ecdsa_key.get()) == 1;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/channel_id.h b/quic/core/crypto/channel_id.h
deleted file mode 100644
index 11759d2..0000000
--- a/quic/core/crypto/channel_id.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// ChannelIDVerifier verifies ChannelID signatures.
-class QUIC_EXPORT_PRIVATE ChannelIDVerifier {
- public:
-  ChannelIDVerifier() = delete;
-
-  // kContextStr is prepended to the data to be signed in order to ensure that
-  // a ChannelID signature cannot be used in a different context. (The
-  // terminating NUL byte is inclued.)
-  static const char kContextStr[];
-  // kClientToServerStr follows kContextStr to specify that the ChannelID is
-  // being used in the client to server direction. (The terminating NUL byte is
-  // included.)
-  static const char kClientToServerStr[];
-
-  // Verify returns true iff |signature| is a valid signature of |signed_data|
-  // by |key|.
-  static bool Verify(absl::string_view key,
-                     absl::string_view signed_data,
-                     absl::string_view signature);
-
-  // FOR TESTING ONLY: VerifyRaw returns true iff |signature| is a valid
-  // signature of |signed_data| by |key|. |is_channel_id_signature| indicates
-  // whether |signature| is a ChannelID signature (with kContextStr prepended
-  // to the data to be signed).
-  static bool VerifyRaw(absl::string_view key,
-                        absl::string_view signed_data,
-                        absl::string_view signature,
-                        bool is_channel_id_signature);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
diff --git a/quic/core/crypto/channel_id_test.cc b/quic/core/crypto/channel_id_test.cc
deleted file mode 100644
index cf89fe5..0000000
--- a/quic/core/crypto/channel_id_test.cc
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/channel_id.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-// The following ECDSA signature verification test vectors for P-256,SHA-256
-// come from the SigVer.rsp file in
-// http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
-// downloaded on 2013-06-11.
-struct TestVector {
-  // Input:
-  const char* msg;
-  const char* qx;
-  const char* qy;
-  const char* r;
-  const char* s;
-
-  // Expected output:
-  bool result;  // true means "P", false means "F"
-};
-
-const TestVector test_vector[] = {
-    {
-        "e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d"
-        "9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19"
-        "fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c"
-        "24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0",
-        "87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555",
-        "e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9",
-        "d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0",
-        "a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6",
-        false  // F (3 - S changed)
-    },
-    {
-        "069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d6"
-        "83877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae187300"
-        "4565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b"
-        "3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e",
-        "5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2",
-        "ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85",
-        "dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693",
-        "d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c",
-        false  // F (2 - R changed)
-    },
-    {
-        "df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d"
-        "8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af7149598"
-        "96858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd861"
-        "28cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de",
-        "2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb",
-        "5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64",
-        "9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8",
-        "9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc",
-        false  // F (4 - Q changed)
-    },
-    {
-        "e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45f"
-        "d75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217"
-        "ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce4"
-        "70a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3",
-        "e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c",
-        "970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927",
-        "bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f",
-        "17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c",
-        true  // P (0 )
-    },
-    {
-        "73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730f"
-        "b68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f226"
-        "63bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a"
-        "6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08",
-        "e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864",
-        "7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a",
-        "1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407",
-        "cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a",
-        true  // P (0 )
-    },
-    {
-        "666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2"
-        "b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a"
-        "282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9"
-        "c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548",
-        "a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86",
-        "bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471",
-        "25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6",
-        "9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537",
-        false  // F (2 - R changed)
-    },
-    {
-        "7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f89"
-        "4edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25"
-        "b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660ef"
-        "b57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd",
-        "3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df",
-        "f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb",
-        "548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a",
-        "e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75",
-        false  // F (4 - Q changed)
-    },
-    {
-        "1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce1"
-        "3e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f2"
-        "2d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c"
-        "438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169",
-        "69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214",
-        "d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f",
-        "288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790",
-        "247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979",
-        false  // F (1 - Message changed)
-    },
-    {
-        "3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076"
-        "115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788e"
-        "c6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576e"
-        "fc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970",
-        "bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682",
-        "069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03",
-        "f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad",
-        "049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d",
-        false  // F (3 - S changed)
-    },
-    {
-        "983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312"
-        "a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd"
-        "9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a891"
-        "29938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c",
-        "224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de",
-        "178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9",
-        "87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2",
-        "4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66",
-        false  // F (2 - R changed)
-    },
-    {
-        "4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac28733"
-        "9e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfd"
-        "b892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4"
-        "f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af",
-        "43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369",
-        "f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac",
-        "8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce",
-        "cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154",
-        false  // F (3 - S changed)
-    },
-    {
-        "0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0"
-        "718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0"
-        "bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87a"
-        "c8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216",
-        "9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596",
-        "972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405",
-        "dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb",
-        "8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2",
-        false  // F (1 - Message changed)
-    },
-    {
-        "785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc285"
-        "81dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c"
-        "60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c557749"
-        "28c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e",
-        "072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda",
-        "9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5",
-        "09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19",
-        "a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d",
-        false  // F (4 - Q changed)
-    },
-    {
-        "76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e722"
-        "9ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad"
-        "3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212d"
-        "d4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca",
-        "09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24",
-        "f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5",
-        "5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73",
-        "9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7",
-        false  // F (1 - Message changed)
-    },
-    {
-        "60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855"
-        "dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddb"
-        "d1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c0"
-        "03c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84",
-        "2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d",
-        "9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a",
-        "06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959",
-        "62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce",
-        true  // P (0 )
-    },
-    {nullptr, nullptr, nullptr, nullptr, nullptr, false}};
-
-// Returns true if |ch| is a lowercase hexadecimal digit.
-bool IsHexDigit(char ch) {
-  return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f');
-}
-
-// Converts a lowercase hexadecimal digit to its integer value.
-int HexDigitToInt(char ch) {
-  if ('0' <= ch && ch <= '9') {
-    return ch - '0';
-  }
-  return ch - 'a' + 10;
-}
-
-// |in| is a string consisting of lowercase hexadecimal digits, where
-// every two digits represent one byte. |out| is a buffer of size |max_len|.
-// Converts |in| to bytes and stores the bytes in the |out| buffer. The
-// number of bytes converted is returned in |*out_len|. Returns true on
-// success, false on failure.
-bool DecodeHexString(const char* in,
-                     char* out,
-                     size_t* out_len,
-                     size_t max_len) {
-  if (!in) {
-    *out_len = static_cast<size_t>(-1);
-    return true;
-  }
-  *out_len = 0;
-  while (*in != '\0') {
-    if (!IsHexDigit(*in) || !IsHexDigit(*(in + 1))) {
-      return false;
-    }
-    if (*out_len >= max_len) {
-      return false;
-    }
-    out[*out_len] = HexDigitToInt(*in) * 16 + HexDigitToInt(*(in + 1));
-    (*out_len)++;
-    in += 2;
-  }
-  return true;
-}
-
-}  // namespace
-
-class ChannelIDTest : public QuicTest {};
-
-// A known answer test for ChannelIDVerifier.
-TEST_F(ChannelIDTest, VerifyKnownAnswerTest) {
-  char msg[1024];
-  size_t msg_len;
-  char key[64];
-  size_t qx_len;
-  size_t qy_len;
-  char signature[64];
-  size_t r_len;
-  size_t s_len;
-
-  for (size_t i = 0; test_vector[i].msg != nullptr; i++) {
-    SCOPED_TRACE(i);
-    // Decode the test vector.
-    ASSERT_TRUE(
-        DecodeHexString(test_vector[i].msg, msg, &msg_len, sizeof(msg)));
-    ASSERT_TRUE(DecodeHexString(test_vector[i].qx, key, &qx_len, sizeof(key)));
-    ASSERT_TRUE(DecodeHexString(test_vector[i].qy, key + qx_len, &qy_len,
-                                sizeof(key) - qx_len));
-    ASSERT_TRUE(DecodeHexString(test_vector[i].r, signature, &r_len,
-                                sizeof(signature)));
-    ASSERT_TRUE(DecodeHexString(test_vector[i].s, signature + r_len, &s_len,
-                                sizeof(signature) - r_len));
-
-    // The test vector's lengths should look sane.
-    EXPECT_EQ(sizeof(key) / 2, qx_len);
-    EXPECT_EQ(sizeof(key) / 2, qy_len);
-    EXPECT_EQ(sizeof(signature) / 2, r_len);
-    EXPECT_EQ(sizeof(signature) / 2, s_len);
-
-    EXPECT_EQ(test_vector[i].result,
-              ChannelIDVerifier::VerifyRaw(
-                  absl::string_view(key, sizeof(key)),
-                  absl::string_view(msg, msg_len),
-                  absl::string_view(signature, sizeof(signature)), false));
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/client_proof_source.cc b/quic/core/crypto/client_proof_source.cc
deleted file mode 100644
index 7f2e1fd..0000000
--- a/quic/core/crypto/client_proof_source.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/client_proof_source.h"
-
-#include "absl/strings/match.h"
-
-namespace quic {
-
-bool DefaultClientProofSource::AddCertAndKey(
-    std::vector<std::string> server_hostnames,
-    quiche::QuicheReferenceCountedPointer<Chain> chain,
-    CertificatePrivateKey private_key) {
-  if (!ValidateCertAndKey(chain, private_key)) {
-    return false;
-  }
-
-  auto cert_and_key =
-      std::make_shared<CertAndKey>(std::move(chain), std::move(private_key));
-  for (const std::string& domain : server_hostnames) {
-    cert_and_keys_[domain] = cert_and_key;
-  }
-  return true;
-}
-
-const ClientProofSource::CertAndKey* DefaultClientProofSource::GetCertAndKey(
-    absl::string_view hostname) const {
-  const CertAndKey* result = LookupExact(hostname);
-  if (result != nullptr || hostname == "*") {
-    return result;
-  }
-
-  // Either a full or a wildcard domain lookup failed. In the former case,
-  // derive the wildcard domain and look it up.
-  if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) {
-    auto dot_pos = hostname.find('.');
-    if (dot_pos != std::string::npos) {
-      std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
-      const CertAndKey* result = LookupExact(wildcard);
-      if (result != nullptr) {
-        return result;
-      }
-    }
-  }
-
-  // Return default cert, if any.
-  return LookupExact("*");
-}
-
-const ClientProofSource::CertAndKey* DefaultClientProofSource::LookupExact(
-    absl::string_view map_key) const {
-  const auto it = cert_and_keys_.find(map_key);
-  QUIC_DVLOG(1) << "LookupExact(" << map_key
-                << ") found:" << (it != cert_and_keys_.end());
-  if (it != cert_and_keys_.end()) {
-    return it->second.get();
-  }
-  return nullptr;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/client_proof_source.h b/quic/core/crypto/client_proof_source.h
deleted file mode 100644
index 2db8205..0000000
--- a/quic/core/crypto/client_proof_source.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
-
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-
-// ClientProofSource is the interface for a QUIC client to provide client certs
-// and keys based on server hostname. It is only used by TLS handshakes.
-class QUIC_EXPORT_PRIVATE ClientProofSource {
- public:
-  using Chain = ProofSource::Chain;
-
-  virtual ~ClientProofSource() {}
-
-  struct QUIC_EXPORT_PRIVATE CertAndKey {
-    CertAndKey(quiche::QuicheReferenceCountedPointer<Chain> chain,
-               CertificatePrivateKey private_key)
-        : chain(std::move(chain)), private_key(std::move(private_key)) {}
-
-    quiche::QuicheReferenceCountedPointer<Chain> chain;
-    CertificatePrivateKey private_key;
-  };
-
-  // Get the client certificate to be sent to the server with |server_hostname|
-  // and its corresponding private key. It returns nullptr if the cert and key
-  // can not be found.
-  //
-  // |server_hostname| is typically a full domain name(www.foo.com), but it
-  // could also be a wildcard domain(*.foo.com), or a "*" which will return the
-  // default cert.
-  virtual const CertAndKey* GetCertAndKey(
-      absl::string_view server_hostname) const = 0;
-};
-
-// DefaultClientProofSource is an implementation that simply keeps an in memory
-// map of server hostnames to certs.
-class QUIC_EXPORT_PRIVATE DefaultClientProofSource : public ClientProofSource {
- public:
-  ~DefaultClientProofSource() override {}
-
-  // Associate all hostnames in |server_hostnames| with {|chain|,|private_key|}.
-  // Elements of |server_hostnames| can be full domain names(www.foo.com),
-  // wildcard domains(*.foo.com), or "*" which means the given cert chain is the
-  // default one.
-  // If any element of |server_hostnames| is already associated with a cert
-  // chain, it will be updated to be associated with the new cert chain.
-  bool AddCertAndKey(std::vector<std::string> server_hostnames,
-                     quiche::QuicheReferenceCountedPointer<Chain> chain,
-                     CertificatePrivateKey private_key);
-
-  // ClientProofSource implementation
-  const CertAndKey* GetCertAndKey(absl::string_view hostname) const override;
-
- private:
-  const CertAndKey* LookupExact(absl::string_view map_key) const;
-  absl::flat_hash_map<std::string, std::shared_ptr<CertAndKey>> cert_and_keys_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
diff --git a/quic/core/crypto/client_proof_source_test.cc b/quic/core/crypto/client_proof_source_test.cc
deleted file mode 100644
index d8192b8..0000000
--- a/quic/core/crypto/client_proof_source_test.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/client_proof_source.h"
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-
-quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
-TestCertChain() {
-  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
-      new ClientProofSource::Chain({std::string(kTestCertificate)}));
-}
-
-CertificatePrivateKey TestPrivateKey() {
-  CBS private_key_cbs;
-  CBS_init(&private_key_cbs,
-           reinterpret_cast<const uint8_t*>(kTestCertificatePrivateKey.data()),
-           kTestCertificatePrivateKey.size());
-
-  return CertificatePrivateKey(
-      bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&private_key_cbs)));
-}
-
-const ClientProofSource::CertAndKey* TestCertAndKey() {
-  static const ClientProofSource::CertAndKey cert_and_key(TestCertChain(),
-                                                          TestPrivateKey());
-  return &cert_and_key;
-}
-
-quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
-NullCertChain() {
-  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>();
-}
-
-quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
-EmptyCertChain() {
-  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
-      new ClientProofSource::Chain(std::vector<std::string>()));
-}
-
-quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain> BadCertChain() {
-  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
-      new ClientProofSource::Chain({"This is the content of a bad cert."}));
-}
-
-CertificatePrivateKey EmptyPrivateKey() {
-  return CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY>(EVP_PKEY_new()));
-}
-
-#define VERIFY_CERT_AND_KEY_MATCHES(lhs, rhs) \
-  do {                                        \
-    SCOPED_TRACE(testing::Message());         \
-    VerifyCertAndKeyMatches(lhs, rhs);        \
-  } while (0)
-
-void VerifyCertAndKeyMatches(const ClientProofSource::CertAndKey* lhs,
-                             const ClientProofSource::CertAndKey* rhs) {
-  if (lhs == rhs) {
-    return;
-  }
-
-  if (lhs == nullptr) {
-    ADD_FAILURE() << "lhs is nullptr, but rhs is not";
-    return;
-  }
-
-  if (rhs == nullptr) {
-    ADD_FAILURE() << "rhs is nullptr, but lhs is not";
-    return;
-  }
-
-  if (1 != EVP_PKEY_cmp(lhs->private_key.private_key(),
-                        rhs->private_key.private_key())) {
-    ADD_FAILURE() << "Private keys mismatch";
-    return;
-  }
-
-  const ClientProofSource::Chain* lhs_chain = lhs->chain.get();
-  const ClientProofSource::Chain* rhs_chain = rhs->chain.get();
-
-  if (lhs_chain == rhs_chain) {
-    return;
-  }
-
-  if (lhs_chain == nullptr) {
-    ADD_FAILURE() << "lhs->chain is nullptr, but rhs->chain is not";
-    return;
-  }
-
-  if (rhs_chain == nullptr) {
-    ADD_FAILURE() << "rhs->chain is nullptr, but lhs->chain is not";
-    return;
-  }
-
-  if (lhs_chain->certs.size() != rhs_chain->certs.size()) {
-    ADD_FAILURE() << "Cert chain length differ. lhs:" << lhs_chain->certs.size()
-                  << ", rhs:" << rhs_chain->certs.size();
-    return;
-  }
-
-  for (size_t i = 0; i < lhs_chain->certs.size(); ++i) {
-    if (lhs_chain->certs[i] != rhs_chain->certs[i]) {
-      ADD_FAILURE() << "The " << i << "-th certs differ.";
-      return;
-    }
-  }
-
-  // All good.
-}
-
-TEST(DefaultClientProofSource, FullDomain) {
-  DefaultClientProofSource proof_source;
-  ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com"}, TestCertChain(),
-                                         TestPrivateKey()));
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
-                              TestCertAndKey());
-  EXPECT_EQ(proof_source.GetCertAndKey("*.google.com"), nullptr);
-  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, WildcardDomain) {
-  DefaultClientProofSource proof_source;
-  ASSERT_TRUE(proof_source.AddCertAndKey({"*.google.com"}, TestCertChain(),
-                                         TestPrivateKey()));
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
-                              TestCertAndKey());
-  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, DefaultDomain) {
-  DefaultClientProofSource proof_source;
-  ASSERT_TRUE(
-      proof_source.AddCertAndKey({"*"}, TestCertChain(), TestPrivateKey()));
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
-                              TestCertAndKey());
-}
-
-TEST(DefaultClientProofSource, FullAndWildcard) {
-  DefaultClientProofSource proof_source;
-  ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com", "*.google.com"},
-                                         TestCertChain(), TestPrivateKey()));
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
-                              TestCertAndKey());
-  EXPECT_EQ(proof_source.GetCertAndKey("www.example.com"), nullptr);
-  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, FullWildcardAndDefault) {
-  DefaultClientProofSource proof_source;
-  ASSERT_TRUE(
-      proof_source.AddCertAndKey({"www.google.com", "*.google.com", "*"},
-                                 TestCertChain(), TestPrivateKey()));
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.example.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
-                              TestCertAndKey());
-  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
-                              TestCertAndKey());
-}
-
-TEST(DefaultClientProofSource, EmptyCerts) {
-  DefaultClientProofSource proof_source;
-  bool ok;
-  EXPECT_QUIC_BUG(
-      ok = proof_source.AddCertAndKey({"*"}, NullCertChain(), TestPrivateKey()),
-      "Certificate chain is empty");
-  ASSERT_FALSE(ok);
-
-  EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey({"*"}, EmptyCertChain(),
-                                                  TestPrivateKey()),
-                  "Certificate chain is empty");
-  ASSERT_FALSE(ok);
-  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, BadCerts) {
-  DefaultClientProofSource proof_source;
-  bool ok;
-  EXPECT_QUIC_BUG(
-      ok = proof_source.AddCertAndKey({"*"}, BadCertChain(), TestPrivateKey()),
-      "Unabled to parse leaf certificate");
-  ASSERT_FALSE(ok);
-  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-TEST(DefaultClientProofSource, KeyMismatch) {
-  DefaultClientProofSource proof_source;
-  bool ok;
-  EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey(
-                      {"www.google.com"}, TestCertChain(), EmptyPrivateKey()),
-                  "Private key does not match the leaf certificate");
-  ASSERT_FALSE(ok);
-  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_framer.cc b/quic/core/crypto/crypto_framer.cc
deleted file mode 100644
index cf6e123..0000000
--- a/quic/core/crypto/crypto_framer.cc
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_framer.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kQuicTagSize = sizeof(QuicTag);
-const size_t kCryptoEndOffsetSize = sizeof(uint32_t);
-const size_t kNumEntriesSize = sizeof(uint16_t);
-
-// OneShotVisitor is a framer visitor that records a single handshake message.
-class OneShotVisitor : public CryptoFramerVisitorInterface {
- public:
-  OneShotVisitor() : error_(false) {}
-
-  void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
-    out_ = std::make_unique<CryptoHandshakeMessage>(message);
-  }
-
-  bool error() const { return error_; }
-
-  std::unique_ptr<CryptoHandshakeMessage> release() { return std::move(out_); }
-
- private:
-  std::unique_ptr<CryptoHandshakeMessage> out_;
-  bool error_;
-};
-
-}  // namespace
-
-CryptoFramer::CryptoFramer()
-    : visitor_(nullptr),
-      error_detail_(""),
-      num_entries_(0),
-      values_len_(0),
-      process_truncated_messages_(false) {
-  Clear();
-}
-
-CryptoFramer::~CryptoFramer() {}
-
-// static
-std::unique_ptr<CryptoHandshakeMessage> CryptoFramer::ParseMessage(
-    absl::string_view in) {
-  OneShotVisitor visitor;
-  CryptoFramer framer;
-
-  framer.set_visitor(&visitor);
-  if (!framer.ProcessInput(in) || visitor.error() ||
-      framer.InputBytesRemaining()) {
-    return nullptr;
-  }
-
-  return visitor.release();
-}
-
-QuicErrorCode CryptoFramer::error() const {
-  return error_;
-}
-
-const std::string& CryptoFramer::error_detail() const {
-  return error_detail_;
-}
-
-bool CryptoFramer::ProcessInput(absl::string_view input,
-                                EncryptionLevel /*level*/) {
-  return ProcessInput(input);
-}
-
-bool CryptoFramer::ProcessInput(absl::string_view input) {
-  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
-  if (error_ != QUIC_NO_ERROR) {
-    return false;
-  }
-  error_ = Process(input);
-  if (error_ != QUIC_NO_ERROR) {
-    QUICHE_DCHECK(!error_detail_.empty());
-    visitor_->OnError(this);
-    return false;
-  }
-
-  return true;
-}
-
-size_t CryptoFramer::InputBytesRemaining() const {
-  return buffer_.length();
-}
-
-bool CryptoFramer::HasTag(QuicTag tag) const {
-  if (state_ != STATE_READING_VALUES) {
-    return false;
-  }
-  for (const auto& it : tags_and_lengths_) {
-    if (it.first == tag) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void CryptoFramer::ForceHandshake() {
-  QuicDataReader reader(buffer_.data(), buffer_.length(),
-                        quiche::HOST_BYTE_ORDER);
-  for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
-    absl::string_view value;
-    if (reader.BytesRemaining() < item.second) {
-      break;
-    }
-    reader.ReadStringPiece(&value, item.second);
-    message_.SetStringPiece(item.first, value);
-  }
-  visitor_->OnHandshakeMessage(message_);
-}
-
-// static
-std::unique_ptr<QuicData> CryptoFramer::ConstructHandshakeMessage(
-    const CryptoHandshakeMessage& message) {
-  size_t num_entries = message.tag_value_map().size();
-  size_t pad_length = 0;
-  bool need_pad_tag = false;
-  bool need_pad_value = false;
-
-  size_t len = message.size();
-  if (len < message.minimum_size()) {
-    need_pad_tag = true;
-    need_pad_value = true;
-    num_entries++;
-
-    size_t delta = message.minimum_size() - len;
-    const size_t overhead = kQuicTagSize + kCryptoEndOffsetSize;
-    if (delta > overhead) {
-      pad_length = delta - overhead;
-    }
-    len += overhead + pad_length;
-  }
-
-  if (num_entries > kMaxEntries) {
-    return nullptr;
-  }
-
-  std::unique_ptr<char[]> buffer(new char[len]);
-  QuicDataWriter writer(len, buffer.get(), quiche::HOST_BYTE_ORDER);
-  if (!writer.WriteTag(message.tag())) {
-    QUICHE_DCHECK(false) << "Failed to write message tag.";
-    return nullptr;
-  }
-  if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) {
-    QUICHE_DCHECK(false) << "Failed to write size.";
-    return nullptr;
-  }
-  if (!writer.WriteUInt16(0)) {
-    QUICHE_DCHECK(false) << "Failed to write padding.";
-    return nullptr;
-  }
-
-  uint32_t end_offset = 0;
-  // Tags and offsets
-  for (auto it = message.tag_value_map().begin();
-       it != message.tag_value_map().end(); ++it) {
-    if (it->first == kPAD && need_pad_tag) {
-      // Existing PAD tags are only checked when padding needs to be added
-      // because parts of the code may need to reserialize received messages
-      // and those messages may, legitimately include padding.
-      QUICHE_DCHECK(false)
-          << "Message needed padding but already contained a PAD tag";
-      return nullptr;
-    }
-
-    if (it->first > kPAD && need_pad_tag) {
-      need_pad_tag = false;
-      if (!WritePadTag(&writer, pad_length, &end_offset)) {
-        return nullptr;
-      }
-    }
-
-    if (!writer.WriteTag(it->first)) {
-      QUICHE_DCHECK(false) << "Failed to write tag.";
-      return nullptr;
-    }
-    end_offset += it->second.length();
-    if (!writer.WriteUInt32(end_offset)) {
-      QUICHE_DCHECK(false) << "Failed to write end offset.";
-      return nullptr;
-    }
-  }
-
-  if (need_pad_tag) {
-    if (!WritePadTag(&writer, pad_length, &end_offset)) {
-      return nullptr;
-    }
-  }
-
-  // Values
-  for (auto it = message.tag_value_map().begin();
-       it != message.tag_value_map().end(); ++it) {
-    if (it->first > kPAD && need_pad_value) {
-      need_pad_value = false;
-      if (!writer.WriteRepeatedByte('-', pad_length)) {
-        QUICHE_DCHECK(false) << "Failed to write padding.";
-        return nullptr;
-      }
-    }
-
-    if (!writer.WriteBytes(it->second.data(), it->second.length())) {
-      QUICHE_DCHECK(false) << "Failed to write value.";
-      return nullptr;
-    }
-  }
-
-  if (need_pad_value) {
-    if (!writer.WriteRepeatedByte('-', pad_length)) {
-      QUICHE_DCHECK(false) << "Failed to write padding.";
-      return nullptr;
-    }
-  }
-
-  return std::make_unique<QuicData>(buffer.release(), len, true);
-}
-
-void CryptoFramer::Clear() {
-  message_.Clear();
-  tags_and_lengths_.clear();
-  error_ = QUIC_NO_ERROR;
-  error_detail_ = "";
-  state_ = STATE_READING_TAG;
-}
-
-QuicErrorCode CryptoFramer::Process(absl::string_view input) {
-  // Add this data to the buffer.
-  buffer_.append(input.data(), input.length());
-  QuicDataReader reader(buffer_.data(), buffer_.length(),
-                        quiche::HOST_BYTE_ORDER);
-
-  switch (state_) {
-    case STATE_READING_TAG:
-      if (reader.BytesRemaining() < kQuicTagSize) {
-        break;
-      }
-      QuicTag message_tag;
-      reader.ReadTag(&message_tag);
-      message_.set_tag(message_tag);
-      state_ = STATE_READING_NUM_ENTRIES;
-      ABSL_FALLTHROUGH_INTENDED;
-    case STATE_READING_NUM_ENTRIES:
-      if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) {
-        break;
-      }
-      reader.ReadUInt16(&num_entries_);
-      if (num_entries_ > kMaxEntries) {
-        error_detail_ = absl::StrCat(num_entries_, " entries");
-        return QUIC_CRYPTO_TOO_MANY_ENTRIES;
-      }
-      uint16_t padding;
-      reader.ReadUInt16(&padding);
-
-      tags_and_lengths_.reserve(num_entries_);
-      state_ = STATE_READING_TAGS_AND_LENGTHS;
-      values_len_ = 0;
-      ABSL_FALLTHROUGH_INTENDED;
-    case STATE_READING_TAGS_AND_LENGTHS: {
-      if (reader.BytesRemaining() <
-          num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
-        break;
-      }
-
-      uint32_t last_end_offset = 0;
-      for (unsigned i = 0; i < num_entries_; ++i) {
-        QuicTag tag;
-        reader.ReadTag(&tag);
-        if (i > 0 && tag <= tags_and_lengths_[i - 1].first) {
-          if (tag == tags_and_lengths_[i - 1].first) {
-            error_detail_ = absl::StrCat("Duplicate tag:", tag);
-            return QUIC_CRYPTO_DUPLICATE_TAG;
-          }
-          error_detail_ = absl::StrCat("Tag ", tag, " out of order");
-          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
-        }
-
-        uint32_t end_offset;
-        reader.ReadUInt32(&end_offset);
-
-        if (end_offset < last_end_offset) {
-          error_detail_ =
-              absl::StrCat("End offset: ", end_offset, " vs ", last_end_offset);
-          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
-        }
-        tags_and_lengths_.push_back(std::make_pair(
-            tag, static_cast<size_t>(end_offset - last_end_offset)));
-        last_end_offset = end_offset;
-      }
-      values_len_ = last_end_offset;
-      state_ = STATE_READING_VALUES;
-      ABSL_FALLTHROUGH_INTENDED;
-    }
-    case STATE_READING_VALUES:
-      if (reader.BytesRemaining() < values_len_) {
-        if (!process_truncated_messages_) {
-          break;
-        }
-        QUIC_LOG(ERROR) << "Trunacted message. Missing "
-                        << values_len_ - reader.BytesRemaining() << " bytes.";
-      }
-      for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
-        absl::string_view value;
-        if (!reader.ReadStringPiece(&value, item.second)) {
-          QUICHE_DCHECK(process_truncated_messages_);
-          // Store an empty value.
-          message_.SetStringPiece(item.first, "");
-          continue;
-        }
-        message_.SetStringPiece(item.first, value);
-      }
-      visitor_->OnHandshakeMessage(message_);
-      Clear();
-      state_ = STATE_READING_TAG;
-      break;
-  }
-  // Save any remaining data.
-  buffer_ = std::string(reader.PeekRemainingPayload());
-  return QUIC_NO_ERROR;
-}
-
-// static
-bool CryptoFramer::WritePadTag(QuicDataWriter* writer,
-                               size_t pad_length,
-                               uint32_t* end_offset) {
-  if (!writer->WriteTag(kPAD)) {
-    QUICHE_DCHECK(false) << "Failed to write tag.";
-    return false;
-  }
-  *end_offset += pad_length;
-  if (!writer->WriteUInt32(*end_offset)) {
-    QUICHE_DCHECK(false) << "Failed to write end offset.";
-    return false;
-  }
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_framer.h b/quic/core/crypto/crypto_framer.h
deleted file mode 100644
index e3c6c63..0000000
--- a/quic/core/crypto/crypto_framer.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_message_parser.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CryptoFramer;
-class QuicData;
-class QuicDataWriter;
-
-class QUIC_EXPORT_PRIVATE CryptoFramerVisitorInterface {
- public:
-  virtual ~CryptoFramerVisitorInterface() {}
-
-  // Called if an error is detected.
-  virtual void OnError(CryptoFramer* framer) = 0;
-
-  // Called when a complete handshake message has been parsed.
-  virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
-};
-
-// A class for framing the crypto messages that are exchanged in a QUIC
-// session.
-class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
- public:
-  CryptoFramer();
-
-  ~CryptoFramer() override;
-
-  // ParseMessage parses exactly one message from the given
-  // absl::string_view. If there is an error, the message is truncated,
-  // or the message has trailing garbage then nullptr will be returned.
-  static std::unique_ptr<CryptoHandshakeMessage> ParseMessage(
-      absl::string_view in);
-
-  // Set callbacks to be called from the framer.  A visitor must be set, or
-  // else the framer will crash.  It is acceptable for the visitor to do
-  // nothing.  If this is called multiple times, only the last visitor
-  // will be used.  |visitor| will be owned by the framer.
-  void set_visitor(CryptoFramerVisitorInterface* visitor) {
-    visitor_ = visitor;
-  }
-
-  QuicErrorCode error() const override;
-  const std::string& error_detail() const override;
-
-  // Processes input data, which must be delivered in order. Returns
-  // false if there was an error, and true otherwise. ProcessInput optionally
-  // takes an EncryptionLevel, but it is ignored. The variant with the
-  // EncryptionLevel is provided to match the CryptoMessageParser interface.
-  bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
-  bool ProcessInput(absl::string_view input);
-
-  // Returns the number of bytes of buffered input data remaining to be
-  // parsed.
-  size_t InputBytesRemaining() const override;
-
-  // Checks if the specified tag has been seen. Returns |true| if it
-  // has, and |false| if it has not or a CHLO has not been seen.
-  bool HasTag(QuicTag tag) const;
-
-  // Even if the CHLO has not been fully received, force processing of
-  // the handshake message. This is dangerous and should not be used
-  // except as a mechanism of last resort.
-  void ForceHandshake();
-
-  // Returns a new QuicData owned by the caller that contains a serialized
-  // |message|, or nullptr if there was an error.
-  static std::unique_ptr<QuicData> ConstructHandshakeMessage(
-      const CryptoHandshakeMessage& message);
-
-  // Debug only method which permits processing truncated messages.
-  void set_process_truncated_messages(bool process_truncated_messages) {
-    process_truncated_messages_ = process_truncated_messages;
-  }
-
- private:
-  // Clears per-message state.  Does not clear the visitor.
-  void Clear();
-
-  // Process does does the work of |ProcessInput|, but returns an error code,
-  // doesn't set error_ and doesn't call |visitor_->OnError()|.
-  QuicErrorCode Process(absl::string_view input);
-
-  static bool WritePadTag(QuicDataWriter* writer,
-                          size_t pad_length,
-                          uint32_t* end_offset);
-
-  // Represents the current state of the parsing state machine.
-  enum CryptoFramerState {
-    STATE_READING_TAG,
-    STATE_READING_NUM_ENTRIES,
-    STATE_READING_TAGS_AND_LENGTHS,
-    STATE_READING_VALUES
-  };
-
-  // Visitor to invoke when messages are parsed.
-  CryptoFramerVisitorInterface* visitor_;
-  // Last error.
-  QuicErrorCode error_;
-  // Remaining unparsed data.
-  std::string buffer_;
-  // Current state of the parsing.
-  CryptoFramerState state_;
-  // The message currently being parsed.
-  CryptoHandshakeMessage message_;
-  // The issue which caused |error_|
-  std::string error_detail_;
-  // Number of entires in the message currently being parsed.
-  uint16_t num_entries_;
-  // tags_and_lengths_ contains the tags that are currently being parsed and
-  // their lengths.
-  std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
-  // Cumulative length of all values in the message currently being parsed.
-  size_t values_len_;
-  // Set to true to allow of processing of truncated messages for debugging.
-  bool process_truncated_messages_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
diff --git a/quic/core/crypto/crypto_framer_test.cc b/quic/core/crypto/crypto_framer_test.cc
deleted file mode 100644
index 656a00a..0000000
--- a/quic/core/crypto/crypto_framer_test.cc
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_framer.h"
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-char* AsChars(unsigned char* data) {
-  return reinterpret_cast<char*>(data);
-}
-
-class TestCryptoVisitor : public CryptoFramerVisitorInterface {
- public:
-  TestCryptoVisitor() : error_count_(0) {}
-
-  void OnError(CryptoFramer* framer) override {
-    QUIC_DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
-    ++error_count_;
-  }
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
-    messages_.push_back(message);
-  }
-
-  // Counters from the visitor callbacks.
-  int error_count_;
-
-  std::vector<CryptoHandshakeMessage> messages_;
-};
-
-TEST(CryptoFramerTest, ConstructHandshakeMessage) {
-  CryptoHandshakeMessage message;
-  message.set_tag(0xFFAA7733);
-  message.SetStringPiece(0x12345678, "abcdef");
-  message.SetStringPiece(0x12345679, "ghijk");
-  message.SetStringPiece(0x1234567A, "lmnopqr");
-
-  unsigned char packet[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x03, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x06, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x0b, 0x00, 0x00, 0x00,
-      // tag 3
-      0x7A, 0x56, 0x34, 0x12,
-      // end offset 3
-      0x12, 0x00, 0x00, 0x00,
-      // value 1
-      'a', 'b', 'c', 'd', 'e', 'f',
-      // value 2
-      'g', 'h', 'i', 'j', 'k',
-      // value 3
-      'l', 'm', 'n', 'o', 'p', 'q', 'r',
-  };
-
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
-  CryptoHandshakeMessage message;
-  message.set_tag(0xFFAA7733);
-  message.SetStringPiece(0x12345678, "abcdef");
-  message.SetStringPiece(0x12345679, "ghijk");
-
-  unsigned char packet[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x06, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x0b, 0x00, 0x00, 0x00,
-      // value 1
-      'a', 'b', 'c', 'd', 'e', 'f',
-      // value 2
-      'g', 'h', 'i', 'j', 'k',
-  };
-
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
-  CryptoHandshakeMessage message;
-  message.set_tag(0xFFAA7733);
-  message.SetStringPiece(0x12345678, "");
-
-  unsigned char packet[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x01, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x00, 0x00, 0x00, 0x00,
-  };
-
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
-  CryptoHandshakeMessage message;
-  message.set_tag(0xFFAA7733);
-  for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) {
-    message.SetStringPiece(key, "abcdef");
-  }
-
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  EXPECT_TRUE(data == nullptr);
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
-  CryptoHandshakeMessage message;
-  message.set_tag(0xFFAA7733);
-  message.SetStringPiece(0x01020304, "test");
-  message.set_minimum_size(64);
-
-  unsigned char packet[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      'P', 'A', 'D', 0,
-      // end offset 1
-      0x24, 0x00, 0x00, 0x00,
-      // tag 2
-      0x04, 0x03, 0x02, 0x01,
-      // end offset 2
-      0x28, 0x00, 0x00, 0x00,
-      // 36 bytes of padding.
-      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
-      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
-      '-', '-', '-', '-', '-', '-',
-      // value 2
-      't', 'e', 's', 't',
-  };
-
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
-  CryptoHandshakeMessage message;
-  message.set_tag(0xFFAA7733);
-  message.SetStringPiece(1, "");
-  message.set_minimum_size(64);
-
-  unsigned char packet[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x01, 0x00, 0x00, 0x00,
-      // end offset 1
-      0x00, 0x00, 0x00, 0x00,
-      // tag 2
-      'P', 'A', 'D', 0,
-      // end offset 2
-      0x28, 0x00, 0x00, 0x00,
-      // 40 bytes of padding.
-      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
-      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
-      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
-  };
-
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST(CryptoFramerTest, ProcessInput) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x06, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x0b, 0x00, 0x00, 0x00,
-      // value 1
-      'a', 'b', 'c', 'd', 'e', 'f',
-      // value 2
-      'g', 'h', 'i', 'j', 'k',
-  };
-
-  EXPECT_TRUE(framer.ProcessInput(
-      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
-  EXPECT_EQ(0u, framer.InputBytesRemaining());
-  EXPECT_EQ(0, visitor.error_count_);
-  ASSERT_EQ(1u, visitor.messages_.size());
-  const CryptoHandshakeMessage& message = visitor.messages_[0];
-  EXPECT_EQ(0xFFAA7733, message.tag());
-  EXPECT_EQ(2u, message.tag_value_map().size());
-  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
-  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
-}
-
-TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x03, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x06, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x0b, 0x00, 0x00, 0x00,
-      // tag 3
-      0x7A, 0x56, 0x34, 0x12,
-      // end offset 3
-      0x12, 0x00, 0x00, 0x00,
-      // value 1
-      'a', 'b', 'c', 'd', 'e', 'f',
-      // value 2
-      'g', 'h', 'i', 'j', 'k',
-      // value 3
-      'l', 'm', 'n', 'o', 'p', 'q', 'r',
-  };
-
-  EXPECT_TRUE(framer.ProcessInput(
-      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
-  EXPECT_EQ(0u, framer.InputBytesRemaining());
-  EXPECT_EQ(0, visitor.error_count_);
-  ASSERT_EQ(1u, visitor.messages_.size());
-  const CryptoHandshakeMessage& message = visitor.messages_[0];
-  EXPECT_EQ(0xFFAA7733, message.tag());
-  EXPECT_EQ(3u, message.tag_value_map().size());
-  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
-  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
-  EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A));
-}
-
-TEST(CryptoFramerTest, ProcessInputIncrementally) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x06, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x0b, 0x00, 0x00, 0x00,
-      // value 1
-      'a', 'b', 'c', 'd', 'e', 'f',
-      // value 2
-      'g', 'h', 'i', 'j', 'k',
-  };
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(input); i++) {
-    EXPECT_TRUE(framer.ProcessInput(absl::string_view(AsChars(input) + i, 1)));
-  }
-  EXPECT_EQ(0u, framer.InputBytesRemaining());
-  ASSERT_EQ(1u, visitor.messages_.size());
-  const CryptoHandshakeMessage& message = visitor.messages_[0];
-  EXPECT_EQ(0xFFAA7733, message.tag());
-  EXPECT_EQ(2u, message.tag_value_map().size());
-  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
-  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
-}
-
-TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x13,
-      // end offset 1
-      0x01, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x02, 0x00, 0x00, 0x00,
-  };
-
-  EXPECT_FALSE(framer.ProcessInput(
-      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
-  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
-  EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x01, 0x00, 0x00, 0x00,
-      // tag 2
-      0x78, 0x56, 0x34, 0x13,
-      // end offset 2
-      0x00, 0x00, 0x00, 0x00,
-  };
-
-  EXPECT_FALSE(framer.ProcessInput(
-      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
-  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
-  EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0xA0, 0x00,
-      // padding
-      0x00, 0x00,
-  };
-
-  EXPECT_FALSE(framer.ProcessInput(
-      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
-  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TOO_MANY_ENTRIES));
-  EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST(CryptoFramerTest, ProcessInputZeroLength) {
-  test::TestCryptoVisitor visitor;
-  CryptoFramer framer;
-  framer.set_visitor(&visitor);
-
-  unsigned char input[] = {
-      // tag
-      0x33, 0x77, 0xAA, 0xFF,
-      // num entries
-      0x02, 0x00,
-      // padding
-      0x00, 0x00,
-      // tag 1
-      0x78, 0x56, 0x34, 0x12,
-      // end offset 1
-      0x00, 0x00, 0x00, 0x00,
-      // tag 2
-      0x79, 0x56, 0x34, 0x12,
-      // end offset 2
-      0x05, 0x00, 0x00, 0x00,
-  };
-
-  EXPECT_TRUE(framer.ProcessInput(
-      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
-  EXPECT_EQ(0, visitor.error_count_);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_handshake.cc b/quic/core/crypto/crypto_handshake.cc
deleted file mode 100644
index e59d7d5..0000000
--- a/quic/core/crypto/crypto_handshake.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_handshake.h"
-
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-
-namespace quic {
-
-QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
-    : key_exchange(0),
-      aead(0),
-      token_binding_key_param(0),
-      sct_supported_by_client(false) {}
-
-QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
-
-CrypterPair::CrypterPair() {}
-
-CrypterPair::~CrypterPair() {}
-
-// static
-const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion";
-
-// static
-const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block";
-
-// static
-const char QuicCryptoConfig::kForwardSecureLabel[] =
-    "QUIC forward secure key expansion";
-
-QuicCryptoConfig::QuicCryptoConfig() = default;
-
-QuicCryptoConfig::~QuicCryptoConfig() = default;
-
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_handshake.h b/quic/core/crypto/crypto_handshake.h
deleted file mode 100644
index a7a5fb0..0000000
--- a/quic/core/crypto/crypto_handshake.h
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class SynchronousKeyExchange;
-class QuicDecrypter;
-class QuicEncrypter;
-
-// HandshakeFailureReason enum values are uploaded to UMA, they cannot be
-// changed.
-enum HandshakeFailureReason {
-  HANDSHAKE_OK = 0,
-
-  // Failure reasons for an invalid client nonce in CHLO.
-  //
-  // The default error value for nonce verification failures from strike
-  // register (covers old strike registers and unknown failures).
-  CLIENT_NONCE_UNKNOWN_FAILURE = 1,
-  // Client nonce had incorrect length.
-  CLIENT_NONCE_INVALID_FAILURE = 2,
-  // Client nonce is not unique.
-  CLIENT_NONCE_NOT_UNIQUE_FAILURE = 3,
-  // Client orbit is invalid or incorrect.
-  CLIENT_NONCE_INVALID_ORBIT_FAILURE = 4,
-  // Client nonce's timestamp is not in the strike register's valid time range.
-  CLIENT_NONCE_INVALID_TIME_FAILURE = 5,
-  // Strike register's RPC call timed out, client nonce couldn't be verified.
-  CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT = 6,
-  // Strike register is down, client nonce couldn't be verified.
-  CLIENT_NONCE_STRIKE_REGISTER_FAILURE = 7,
-
-  // Failure reasons for an invalid server nonce in CHLO.
-  //
-  // Unbox of server nonce failed.
-  SERVER_NONCE_DECRYPTION_FAILURE = 8,
-  // Decrypted server nonce had incorrect length.
-  SERVER_NONCE_INVALID_FAILURE = 9,
-  // Server nonce is not unique.
-  SERVER_NONCE_NOT_UNIQUE_FAILURE = 10,
-  // Server nonce's timestamp is not in the strike register's valid time range.
-  SERVER_NONCE_INVALID_TIME_FAILURE = 11,
-  // The server requires handshake confirmation.
-  SERVER_NONCE_REQUIRED_FAILURE = 20,
-
-  // Failure reasons for an invalid server config in CHLO.
-  //
-  // Missing Server config id (kSCID) tag.
-  SERVER_CONFIG_INCHOATE_HELLO_FAILURE = 12,
-  // Couldn't find the Server config id (kSCID).
-  SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE = 13,
-
-  // Failure reasons for an invalid source-address token.
-  //
-  // Missing Source-address token (kSourceAddressTokenTag) tag.
-  SOURCE_ADDRESS_TOKEN_INVALID_FAILURE = 14,
-  // Unbox of Source-address token failed.
-  SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE = 15,
-  // Couldn't parse the unbox'ed Source-address token.
-  SOURCE_ADDRESS_TOKEN_PARSE_FAILURE = 16,
-  // Source-address token is for a different IP address.
-  SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE = 17,
-  // The source-address token has a timestamp in the future.
-  SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE = 18,
-  // The source-address token has expired.
-  SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE = 19,
-
-  // The expected leaf certificate hash could not be validated.
-  INVALID_EXPECTED_LEAF_CERTIFICATE = 21,
-
-  MAX_FAILURE_REASON = 22,
-};
-
-// These errors will be packed into an uint32_t and we don't want to set the
-// most significant bit, which may be misinterpreted as the sign bit.
-static_assert(MAX_FAILURE_REASON <= 32, "failure reason out of sync");
-
-// A CrypterPair contains the encrypter and decrypter for an encryption level.
-struct QUIC_EXPORT_PRIVATE CrypterPair {
-  CrypterPair();
-  CrypterPair(CrypterPair&&) = default;
-  ~CrypterPair();
-
-  std::unique_ptr<QuicEncrypter> encrypter;
-  std::unique_ptr<QuicDecrypter> decrypter;
-};
-
-// Parameters negotiated by the crypto handshake.
-struct QUIC_EXPORT_PRIVATE QuicCryptoNegotiatedParameters
-    : public quiche::QuicheReferenceCounted {
-  // Initializes the members to 0 or empty values.
-  QuicCryptoNegotiatedParameters();
-
-  QuicTag key_exchange;
-  QuicTag aead;
-  std::string initial_premaster_secret;
-  std::string forward_secure_premaster_secret;
-  // initial_subkey_secret is used as the PRK input to the HKDF used when
-  // performing key extraction that needs to happen before forward-secure keys
-  // are available.
-  std::string initial_subkey_secret;
-  // subkey_secret is used as the PRK input to the HKDF used for key extraction.
-  std::string subkey_secret;
-  CrypterPair initial_crypters;
-  CrypterPair forward_secure_crypters;
-  // Normalized SNI: converted to lower case and trailing '.' removed.
-  std::string sni;
-  std::string client_nonce;
-  std::string server_nonce;
-  // hkdf_input_suffix contains the HKDF input following the label: the
-  // ConnectionId, client hello and server config. This is only populated in the
-  // client because only the client needs to derive the forward secure keys at a
-  // later time from the initial keys.
-  std::string hkdf_input_suffix;
-  // cached_certs contains the cached certificates that a client used when
-  // sending a client hello.
-  std::vector<std::string> cached_certs;
-  // client_key_exchange is used by clients to store the ephemeral KeyExchange
-  // for the connection.
-  std::unique_ptr<SynchronousKeyExchange> client_key_exchange;
-  // channel_id is set by servers to a ChannelID key when the client correctly
-  // proves possession of the corresponding private key. It consists of 32
-  // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
-  // are big-endian and the pair is a P-256 public key.
-  std::string channel_id;
-  QuicTag token_binding_key_param;
-
-  // Used when generating proof signature when sending server config updates.
-
-  // Used to generate cert chain when sending server config updates.
-  std::string client_cached_cert_hashes;
-
-  // Default to false; set to true if the client indicates that it supports sct
-  // by sending CSCT tag with an empty value in client hello.
-  bool sct_supported_by_client;
-
-  // Parameters only populated for TLS handshakes. These will be 0 for
-  // connections not using TLS, or if the TLS handshake is not finished yet.
-  uint16_t cipher_suite = 0;
-  uint16_t key_exchange_group = 0;
-  uint16_t peer_signature_algorithm = 0;
-
- protected:
-  ~QuicCryptoNegotiatedParameters() override;
-};
-
-// QuicCryptoConfig contains common configuration between clients and servers.
-class QUIC_EXPORT_PRIVATE QuicCryptoConfig {
- public:
-  // kInitialLabel is a constant that is used when deriving the initial
-  // (non-forward secure) keys for the connection in order to tie the resulting
-  // key to this protocol.
-  static const char kInitialLabel[];
-
-  // kCETVLabel is a constant that is used when deriving the keys for the
-  // encrypted tag/value block in the client hello.
-  static const char kCETVLabel[];
-
-  // kForwardSecureLabel is a constant that is used when deriving the forward
-  // secure keys for the connection in order to tie the resulting key to this
-  // protocol.
-  static const char kForwardSecureLabel[];
-
-  QuicCryptoConfig();
-  QuicCryptoConfig(const QuicCryptoConfig&) = delete;
-  QuicCryptoConfig& operator=(const QuicCryptoConfig&) = delete;
-  ~QuicCryptoConfig();
-
-  // Key exchange methods. The following two members' values correspond by
-  // index.
-  QuicTagVector kexs;
-  // Authenticated encryption with associated data (AEAD) algorithms.
-  QuicTagVector aead;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
diff --git a/quic/core/crypto/crypto_handshake_message.cc b/quic/core/crypto/crypto_handshake_message.cc
deleted file mode 100644
index b591bec..0000000
--- a/quic/core/crypto/crypto_handshake_message.cc
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_utils.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0), minimum_size_(0) {}
-
-CryptoHandshakeMessage::CryptoHandshakeMessage(
-    const CryptoHandshakeMessage& other)
-    : tag_(other.tag_),
-      tag_value_map_(other.tag_value_map_),
-      minimum_size_(other.minimum_size_) {
-  // Don't copy serialized_. unique_ptr doesn't have a copy constructor.
-  // The new object can lazily reconstruct serialized_.
-}
-
-CryptoHandshakeMessage::CryptoHandshakeMessage(CryptoHandshakeMessage&& other) =
-    default;
-
-CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
-
-CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
-    const CryptoHandshakeMessage& other) {
-  tag_ = other.tag_;
-  tag_value_map_ = other.tag_value_map_;
-  // Don't copy serialized_. unique_ptr doesn't have an assignment operator.
-  // However, invalidate serialized_.
-  serialized_.reset();
-  minimum_size_ = other.minimum_size_;
-  return *this;
-}
-
-CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
-    CryptoHandshakeMessage&& other) = default;
-
-bool CryptoHandshakeMessage::operator==(
-    const CryptoHandshakeMessage& rhs) const {
-  return tag_ == rhs.tag_ && tag_value_map_ == rhs.tag_value_map_ &&
-         minimum_size_ == rhs.minimum_size_;
-}
-
-bool CryptoHandshakeMessage::operator!=(
-    const CryptoHandshakeMessage& rhs) const {
-  return !(*this == rhs);
-}
-
-void CryptoHandshakeMessage::Clear() {
-  tag_ = 0;
-  tag_value_map_.clear();
-  minimum_size_ = 0;
-  serialized_.reset();
-}
-
-const QuicData& CryptoHandshakeMessage::GetSerialized() const {
-  if (!serialized_) {
-    serialized_ = CryptoFramer::ConstructHandshakeMessage(*this);
-  }
-  return *serialized_;
-}
-
-void CryptoHandshakeMessage::MarkDirty() {
-  serialized_.reset();
-}
-
-void CryptoHandshakeMessage::SetVersionVector(
-    QuicTag tag,
-    ParsedQuicVersionVector versions) {
-  QuicVersionLabelVector version_labels;
-  for (const ParsedQuicVersion& version : versions) {
-    version_labels.push_back(
-        quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
-  }
-  SetVector(tag, version_labels);
-}
-
-void CryptoHandshakeMessage::SetVersion(QuicTag tag,
-                                        ParsedQuicVersion version) {
-  SetValue(tag,
-           quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
-}
-
-void CryptoHandshakeMessage::SetStringPiece(QuicTag tag,
-                                            absl::string_view value) {
-  tag_value_map_[tag] = std::string(value);
-}
-
-void CryptoHandshakeMessage::Erase(QuicTag tag) {
-  tag_value_map_.erase(tag);
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetTaglist(
-    QuicTag tag,
-    QuicTagVector* out_tags) const {
-  auto it = tag_value_map_.find(tag);
-  QuicErrorCode ret = QUIC_NO_ERROR;
-
-  if (it == tag_value_map_.end()) {
-    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-  } else if (it->second.size() % sizeof(QuicTag) != 0) {
-    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  if (ret != QUIC_NO_ERROR) {
-    out_tags->clear();
-    return ret;
-  }
-
-  size_t num_tags = it->second.size() / sizeof(QuicTag);
-  out_tags->resize(num_tags);
-  for (size_t i = 0; i < num_tags; ++i) {
-    QuicTag tag;
-    memcpy(&tag, it->second.data() + i * sizeof(tag), sizeof(tag));
-    (*out_tags)[i] = tag;
-  }
-  return ret;
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList(
-    QuicTag tag,
-    QuicVersionLabelVector* out) const {
-  QuicErrorCode error = GetTaglist(tag, out);
-  if (error != QUIC_NO_ERROR) {
-    return error;
-  }
-
-  for (size_t i = 0; i < out->size(); ++i) {
-    (*out)[i] = quiche::QuicheEndian::HostToNet32((*out)[i]);
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetVersionLabel(
-    QuicTag tag,
-    QuicVersionLabel* out) const {
-  QuicErrorCode error = GetUint32(tag, out);
-  if (error != QUIC_NO_ERROR) {
-    return error;
-  }
-
-  *out = quiche::QuicheEndian::HostToNet32(*out);
-  return QUIC_NO_ERROR;
-}
-
-bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag,
-                                            absl::string_view* out) const {
-  auto it = tag_value_map_.find(tag);
-  if (it == tag_value_map_.end()) {
-    return false;
-  }
-  *out = it->second;
-  return true;
-}
-
-bool CryptoHandshakeMessage::HasStringPiece(QuicTag tag) const {
-  return tag_value_map_.find(tag) != tag_value_map_.end();
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetNthValue24(
-    QuicTag tag,
-    unsigned index,
-    absl::string_view* out) const {
-  absl::string_view value;
-  if (!GetStringPiece(tag, &value)) {
-    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-  }
-
-  for (unsigned i = 0;; i++) {
-    if (value.empty()) {
-      return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND;
-    }
-    if (value.size() < 3) {
-      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-    }
-
-    const unsigned char* data =
-        reinterpret_cast<const unsigned char*>(value.data());
-    size_t size = static_cast<size_t>(data[0]) |
-                  (static_cast<size_t>(data[1]) << 8) |
-                  (static_cast<size_t>(data[2]) << 16);
-    value.remove_prefix(3);
-
-    if (value.size() < size) {
-      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-    }
-
-    if (i == index) {
-      *out = absl::string_view(value.data(), size);
-      return QUIC_NO_ERROR;
-    }
-
-    value.remove_prefix(size);
-  }
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
-                                                uint32_t* out) const {
-  return GetPOD(tag, out, sizeof(uint32_t));
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
-                                                uint64_t* out) const {
-  return GetPOD(tag, out, sizeof(uint64_t));
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetStatelessResetToken(
-    QuicTag tag,
-    StatelessResetToken* out) const {
-  return GetPOD(tag, out, kStatelessResetTokenLength);
-}
-
-size_t CryptoHandshakeMessage::size() const {
-  size_t ret = sizeof(QuicTag) + sizeof(uint16_t) /* number of entries */ +
-               sizeof(uint16_t) /* padding */;
-  ret += (sizeof(QuicTag) + sizeof(uint32_t) /* end offset */) *
-         tag_value_map_.size();
-  for (auto i = tag_value_map_.begin(); i != tag_value_map_.end(); ++i) {
-    ret += i->second.size();
-  }
-
-  return ret;
-}
-
-void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
-  if (min_bytes == minimum_size_) {
-    return;
-  }
-  serialized_.reset();
-  minimum_size_ = min_bytes;
-}
-
-size_t CryptoHandshakeMessage::minimum_size() const {
-  return minimum_size_;
-}
-
-std::string CryptoHandshakeMessage::DebugString() const {
-  return DebugStringInternal(0);
-}
-
-QuicErrorCode CryptoHandshakeMessage::GetPOD(QuicTag tag,
-                                             void* out,
-                                             size_t len) const {
-  auto it = tag_value_map_.find(tag);
-  QuicErrorCode ret = QUIC_NO_ERROR;
-
-  if (it == tag_value_map_.end()) {
-    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-  } else if (it->second.size() != len) {
-    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  if (ret != QUIC_NO_ERROR) {
-    memset(out, 0, len);
-    return ret;
-  }
-
-  memcpy(out, it->second.data(), len);
-  return ret;
-}
-
-std::string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
-  std::string ret =
-      std::string(2 * indent, ' ') + QuicTagToString(tag_) + "<\n";
-  ++indent;
-  for (auto it = tag_value_map_.begin(); it != tag_value_map_.end(); ++it) {
-    ret += std::string(2 * indent, ' ') + QuicTagToString(it->first) + ": ";
-
-    bool done = false;
-    switch (it->first) {
-      case kICSL:
-      case kCFCW:
-      case kSFCW:
-      case kIRTT:
-      case kMIUS:
-      case kMIBS:
-      case kTCID:
-      case kMAD:
-        // uint32_t value
-        if (it->second.size() == 4) {
-          uint32_t value;
-          memcpy(&value, it->second.data(), sizeof(value));
-          absl::StrAppend(&ret, value);
-          done = true;
-        }
-        break;
-      case kKEXS:
-      case kAEAD:
-      case kCOPT:
-      case kPDMD:
-      case kVER:
-        // tag lists
-        if (it->second.size() % sizeof(QuicTag) == 0) {
-          for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) {
-            QuicTag tag;
-            memcpy(&tag, it->second.data() + j, sizeof(tag));
-            if (j > 0) {
-              ret += ",";
-            }
-            ret += "'" + QuicTagToString(tag) + "'";
-          }
-          done = true;
-        }
-        break;
-      case kRREJ:
-        // uint32_t lists
-        if (it->second.size() % sizeof(uint32_t) == 0) {
-          for (size_t j = 0; j < it->second.size(); j += sizeof(uint32_t)) {
-            uint32_t value;
-            memcpy(&value, it->second.data() + j, sizeof(value));
-            if (j > 0) {
-              ret += ",";
-            }
-            ret += CryptoUtils::HandshakeFailureReasonToString(
-                static_cast<HandshakeFailureReason>(value));
-          }
-          done = true;
-        }
-        break;
-      case kCADR:
-        // IP address and port
-        if (!it->second.empty()) {
-          QuicSocketAddressCoder decoder;
-          if (decoder.Decode(it->second.data(), it->second.size())) {
-            ret += QuicSocketAddress(decoder.ip(), decoder.port()).ToString();
-            done = true;
-          }
-        }
-        break;
-      case kSCFG:
-        // nested messages.
-        if (!it->second.empty()) {
-          std::unique_ptr<CryptoHandshakeMessage> msg(
-              CryptoFramer::ParseMessage(it->second));
-          if (msg) {
-            ret += "\n";
-            ret += msg->DebugStringInternal(indent + 1);
-
-            done = true;
-          }
-        }
-        break;
-      case kPAD:
-        ret += absl::StrFormat("(%d bytes of padding)", it->second.size());
-        done = true;
-        break;
-      case kSNI:
-      case kUAID:
-        ret += "\"" + it->second + "\"";
-        done = true;
-        break;
-    }
-
-    if (!done) {
-      // If there's no specific format for this tag, or the value is invalid,
-      // then just use hex.
-      ret += "0x" + absl::BytesToHexString(it->second);
-    }
-    ret += "\n";
-  }
-  --indent;
-  ret += std::string(2 * indent, ' ') + ">";
-  return ret;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_handshake_message.h b/quic/core/crypto/crypto_handshake_message.h
deleted file mode 100644
index 9550c15..0000000
--- a/quic/core/crypto/crypto_handshake_message.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An intermediate format of a handshake message that's convenient for a
-// CryptoFramer to serialize from or parse into.
-class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage {
- public:
-  CryptoHandshakeMessage();
-  CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
-  CryptoHandshakeMessage(CryptoHandshakeMessage&& other);
-  ~CryptoHandshakeMessage();
-
-  CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other);
-  CryptoHandshakeMessage& operator=(CryptoHandshakeMessage&& other);
-
-  bool operator==(const CryptoHandshakeMessage& rhs) const;
-  bool operator!=(const CryptoHandshakeMessage& rhs) const;
-
-  // Clears state.
-  void Clear();
-
-  // GetSerialized returns the serialized form of this message and caches the
-  // result. Subsequently altering the message does not invalidate the cache.
-  const QuicData& GetSerialized() const;
-
-  // MarkDirty invalidates the cache created by |GetSerialized|.
-  void MarkDirty();
-
-  // SetValue sets an element with the given tag to the raw, memory contents of
-  // |v|.
-  template <class T>
-  void SetValue(QuicTag tag, const T& v) {
-    tag_value_map_[tag] =
-        std::string(reinterpret_cast<const char*>(&v), sizeof(v));
-  }
-
-  // SetVector sets an element with the given tag to the raw contents of an
-  // array of elements in |v|.
-  template <class T>
-  void SetVector(QuicTag tag, const std::vector<T>& v) {
-    if (v.empty()) {
-      tag_value_map_[tag] = std::string();
-    } else {
-      tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]),
-                                        v.size() * sizeof(T));
-    }
-  }
-
-  // Sets an element with the given tag to the on-the-wire representation of
-  // |version|.
-  void SetVersion(QuicTag tag, ParsedQuicVersion version);
-
-  // Sets an element with the given tag to the on-the-wire representation of
-  // the elements in |versions|.
-  void SetVersionVector(QuicTag tag, ParsedQuicVersionVector versions);
-
-  // Returns the message tag.
-  QuicTag tag() const { return tag_; }
-  // Sets the message tag.
-  void set_tag(QuicTag tag) { tag_ = tag; }
-
-  const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
-
-  void SetStringPiece(QuicTag tag, absl::string_view value);
-
-  // Erase removes a tag/value, if present, from the message.
-  void Erase(QuicTag tag);
-
-  // GetTaglist finds an element with the given tag containing zero or more
-  // tags. If such a tag doesn't exist, it returns an error code. Otherwise it
-  // populates |out_tags| with the tags and returns QUIC_NO_ERROR.
-  QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const;
-
-  // GetVersionLabelList finds an element with the given tag containing zero or
-  // more version labels. If such a tag doesn't exist, it returns an error code.
-  // Otherwise it populates |out| with the labels and returns QUIC_NO_ERROR.
-  QuicErrorCode GetVersionLabelList(QuicTag tag,
-                                    QuicVersionLabelVector* out) const;
-
-  // GetVersionLabel finds an element with the given tag containing a single
-  // version label. If such a tag doesn't exist, it returns an error code.
-  // Otherwise it populates |out| with the label and returns QUIC_NO_ERROR.
-  QuicErrorCode GetVersionLabel(QuicTag tag, QuicVersionLabel* out) const;
-
-  bool GetStringPiece(QuicTag tag, absl::string_view* out) const;
-  bool HasStringPiece(QuicTag tag) const;
-
-  // GetNthValue24 interprets the value with the given tag to be a series of
-  // 24-bit, length prefixed values and it returns the subvalue with the given
-  // index.
-  QuicErrorCode GetNthValue24(QuicTag tag,
-                              unsigned index,
-                              absl::string_view* out) const;
-  QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
-  QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
-
-  QuicErrorCode GetStatelessResetToken(QuicTag tag,
-                                       StatelessResetToken* out) const;
-
-  // size returns 4 (message tag) + 2 (uint16_t, number of entries) +
-  // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
-  size_t size() const;
-
-  // set_minimum_size sets the minimum number of bytes that the message should
-  // consume. The CryptoFramer will add a PAD tag as needed when serializing in
-  // order to ensure this. Setting a value of 0 disables padding.
-  //
-  // Padding is useful in order to ensure that messages are a minimum size. A
-  // QUIC server can require a minimum size in order to reduce the
-  // amplification factor of any mirror DoS attack.
-  void set_minimum_size(size_t min_bytes);
-
-  size_t minimum_size() const;
-
-  // DebugString returns a multi-line, string representation of the message
-  // suitable for including in debug output.
-  std::string DebugString() const;
-
- private:
-  // GetPOD is a utility function for extracting a plain-old-data value. If
-  // |tag| exists in the message, and has a value of exactly |len| bytes then
-  // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
-  // are zeroed out.
-  //
-  // If used to copy integers then this assumes that the machine is
-  // little-endian.
-  QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
-
-  std::string DebugStringInternal(size_t indent) const;
-
-  QuicTag tag_;
-  QuicTagValueMap tag_value_map_;
-
-  size_t minimum_size_;
-
-  // The serialized form of the handshake message. This member is constructed
-  // lazily.
-  mutable std::unique_ptr<QuicData> serialized_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
diff --git a/quic/core/crypto/crypto_handshake_message_test.cc b/quic/core/crypto/crypto_handshake_message_test.cc
deleted file mode 100644
index 4ace2e3..0000000
--- a/quic/core/crypto/crypto_handshake_message_test.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(CryptoHandshakeMessageTest, DebugString) {
-  const char* str = "SHLO<\n>";
-
-  CryptoHandshakeMessage message;
-  message.set_tag(kSHLO);
-  EXPECT_EQ(str, message.DebugString());
-
-  // Test copy
-  CryptoHandshakeMessage message2(message);
-  EXPECT_EQ(str, message2.DebugString());
-
-  // Test move
-  CryptoHandshakeMessage message3(std::move(message));
-  EXPECT_EQ(str, message3.DebugString());
-
-  // Test assign
-  CryptoHandshakeMessage message4 = message3;
-  EXPECT_EQ(str, message4.DebugString());
-
-  // Test move-assign
-  CryptoHandshakeMessage message5 = std::move(message3);
-  EXPECT_EQ(str, message5.DebugString());
-}
-
-TEST(CryptoHandshakeMessageTest, DebugStringWithUintVector) {
-  const char* str =
-      "REJ <\n  RREJ: "
-      "SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,"
-      "CLIENT_NONCE_NOT_UNIQUE_FAILURE\n>";
-
-  CryptoHandshakeMessage message;
-  message.set_tag(kREJ);
-  std::vector<uint32_t> reasons = {
-      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
-      CLIENT_NONCE_NOT_UNIQUE_FAILURE};
-  message.SetVector(kRREJ, reasons);
-  EXPECT_EQ(str, message.DebugString());
-
-  // Test copy
-  CryptoHandshakeMessage message2(message);
-  EXPECT_EQ(str, message2.DebugString());
-
-  // Test move
-  CryptoHandshakeMessage message3(std::move(message));
-  EXPECT_EQ(str, message3.DebugString());
-
-  // Test assign
-  CryptoHandshakeMessage message4 = message3;
-  EXPECT_EQ(str, message4.DebugString());
-
-  // Test move-assign
-  CryptoHandshakeMessage message5 = std::move(message3);
-  EXPECT_EQ(str, message5.DebugString());
-}
-
-TEST(CryptoHandshakeMessageTest, DebugStringWithTagVector) {
-  const char* str = "CHLO<\n  COPT: 'TBBR','PAD ','BYTE'\n>";
-
-  CryptoHandshakeMessage message;
-  message.set_tag(kCHLO);
-  message.SetVector(kCOPT, QuicTagVector{kTBBR, kPAD, kBYTE});
-  EXPECT_EQ(str, message.DebugString());
-
-  // Test copy
-  CryptoHandshakeMessage message2(message);
-  EXPECT_EQ(str, message2.DebugString());
-
-  // Test move
-  CryptoHandshakeMessage message3(std::move(message));
-  EXPECT_EQ(str, message3.DebugString());
-
-  // Test assign
-  CryptoHandshakeMessage message4 = message3;
-  EXPECT_EQ(str, message4.DebugString());
-
-  // Test move-assign
-  CryptoHandshakeMessage message5 = std::move(message3);
-  EXPECT_EQ(str, message5.DebugString());
-}
-
-TEST(CryptoHandshakeMessageTest, HasStringPiece) {
-  CryptoHandshakeMessage message;
-  EXPECT_FALSE(message.HasStringPiece(kALPN));
-  message.SetStringPiece(kALPN, "foo");
-  EXPECT_TRUE(message.HasStringPiece(kALPN));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_message_parser.h b/quic/core/crypto/crypto_message_parser.h
deleted file mode 100644
index 5b29dbf..0000000
--- a/quic/core/crypto/crypto_message_parser.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE CryptoMessageParser {
- public:
-  virtual ~CryptoMessageParser() {}
-
-  virtual QuicErrorCode error() const = 0;
-  virtual const std::string& error_detail() const = 0;
-
-  // Processes input data, which must be delivered in order. The input data
-  // being processed was received at encryption level |level|. Returns
-  // false if there was an error, and true otherwise.
-  virtual bool ProcessInput(absl::string_view input, EncryptionLevel level) = 0;
-
-  // Returns the number of bytes of buffered input data remaining to be
-  // parsed.
-  virtual size_t InputBytesRemaining() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
diff --git a/quic/core/crypto/crypto_message_printer_bin.cc b/quic/core/crypto/crypto_message_printer_bin.cc
deleted file mode 100644
index 0159e30..0000000
--- a/quic/core/crypto/crypto_message_printer_bin.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Dumps the contents of a QUIC crypto handshake message in a human readable
-// format.
-//
-// Usage: crypto_message_printer_bin <hex of message>
-
-#include <iostream>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/quic_utils.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-using std::cerr;
-using std::cout;
-using std::endl;
-
-namespace quic {
-
-class CryptoMessagePrinter : public ::quic::CryptoFramerVisitorInterface {
- public:
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
-    cout << message.DebugString() << endl;
-  }
-
-  void OnError(CryptoFramer* framer) override {
-    cerr << "Error code: " << framer->error() << endl;
-    cerr << "Error details: " << framer->error_detail() << endl;
-  }
-};
-
-}  // namespace quic
-
-int main(int argc, char* argv[]) {
-  const char* usage = "Usage: crypto_message_printer <hex>";
-  std::vector<std::string> messages =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-  if (messages.size() != 1) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    exit(0);
-  }
-
-  quic::CryptoMessagePrinter printer;
-  quic::CryptoFramer framer;
-  framer.set_visitor(&printer);
-  framer.set_process_truncated_messages(true);
-  std::string input = absl::HexStringToBytes(messages[0]);
-  if (!framer.ProcessInput(input)) {
-    return 1;
-  }
-  if (framer.InputBytesRemaining() != 0) {
-    cerr << "Input partially consumed. " << framer.InputBytesRemaining()
-         << " bytes remaining." << endl;
-    return 2;
-  }
-  return 0;
-}
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
deleted file mode 100644
index ea05d35..0000000
--- a/quic/core/crypto/crypto_protocol.h
+++ /dev/null
@@ -1,512 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
-
-#include <cstddef>
-#include <string>
-
-#include "quic/core/quic_tag.h"
-
-// Version and Crypto tags are written to the wire with a big-endian
-// representation of the name of the tag.  For example
-// the client hello tag (CHLO) will be written as the
-// following 4 bytes: 'C' 'H' 'L' 'O'.  Since it is
-// stored in memory as a little endian uint32_t, we need
-// to reverse the order of the bytes.
-//
-// We use a macro to ensure that no static initialisers are created. Use the
-// MakeQuicTag function in normal code.
-#define TAG(a, b, c, d) \
-  static_cast<QuicTag>((d << 24) + (c << 16) + (b << 8) + a)
-
-namespace quic {
-
-using ServerConfigID = std::string;
-
-// The following tags have been deprecated and should not be reused:
-// "1CON", "BBQ4", "NCON", "RCID", "SREJ", "TBKP", "TB10", "SCLS", "SMHL",
-// "QNZR", "B2HI", "H2PR", "FIFO", "LIFO", "RRWS", "QNSP", "B2CL", "CHSP",
-// "BPTE", "ACKD", "AKD2", "AKD4", "MAD1", "MAD4", "MAD5", "ACD0", "ACKQ",
-// "TLPR", "CCS\0"
-
-// clang-format off
-const QuicTag kCHLO = TAG('C', 'H', 'L', 'O');   // Client hello
-const QuicTag kSHLO = TAG('S', 'H', 'L', 'O');   // Server hello
-const QuicTag kSCFG = TAG('S', 'C', 'F', 'G');   // Server config
-const QuicTag kREJ  = TAG('R', 'E', 'J', '\0');  // Reject
-const QuicTag kCETV = TAG('C', 'E', 'T', 'V');   // Client encrypted tag-value
-                                                 // pairs
-const QuicTag kPRST = TAG('P', 'R', 'S', 'T');   // Public reset
-const QuicTag kSCUP = TAG('S', 'C', 'U', 'P');   // Server config update
-const QuicTag kALPN = TAG('A', 'L', 'P', 'N');   // Application-layer protocol
-
-// Key exchange methods
-const QuicTag kP256 = TAG('P', '2', '5', '6');   // ECDH, Curve P-256
-const QuicTag kC255 = TAG('C', '2', '5', '5');   // ECDH, Curve25519
-
-// AEAD algorithms
-const QuicTag kAESG = TAG('A', 'E', 'S', 'G');   // AES128 + GCM-12
-const QuicTag kCC20 = TAG('C', 'C', '2', '0');   // ChaCha20 + Poly1305 RFC7539
-
-// Congestion control feedback types
-const QuicTag kQBIC = TAG('Q', 'B', 'I', 'C');   // TCP cubic
-
-// Connection options (COPT) values
-const QuicTag kAFCW = TAG('A', 'F', 'C', 'W');   // Auto-tune flow control
-                                                 // receive windows.
-const QuicTag kIFW5 = TAG('I', 'F', 'W', '5');   // Set initial size
-                                                 // of stream flow control
-                                                 // receive window to
-                                                 // 32KB. (2^5 KB).
-const QuicTag kIFW6 = TAG('I', 'F', 'W', '6');   // Set initial size
-                                                 // of stream flow control
-                                                 // receive window to
-                                                 // 64KB. (2^6 KB).
-const QuicTag kIFW7 = TAG('I', 'F', 'W', '7');   // Set initial size
-                                                 // of stream flow control
-                                                 // receive window to
-                                                 // 128KB. (2^7 KB).
-const QuicTag kIFW8 = TAG('I', 'F', 'W', '8');   // Set initial size
-                                                 // of stream flow control
-                                                 // receive window to
-                                                 // 256KB. (2^8 KB).
-const QuicTag kIFW9 = TAG('I', 'F', 'W', '9');   // Set initial size
-                                                 // of stream flow control
-                                                 // receive window to
-                                                 // 512KB. (2^9 KB).
-const QuicTag kIFWA = TAG('I', 'F', 'W', 'a');   // Set initial size
-                                                 // of stream flow control
-                                                 // receive window to
-                                                 // 1MB. (2^0xa KB).
-const QuicTag kTBBR = TAG('T', 'B', 'B', 'R');   // Reduced Buffer Bloat TCP
-const QuicTag k1RTT = TAG('1', 'R', 'T', 'T');   // STARTUP in BBR for 1 RTT
-const QuicTag k2RTT = TAG('2', 'R', 'T', 'T');   // STARTUP in BBR for 2 RTTs
-const QuicTag kLRTT = TAG('L', 'R', 'T', 'T');   // Exit STARTUP in BBR on loss
-const QuicTag kBBS1 = TAG('B', 'B', 'S', '1');   // DEPRECATED
-const QuicTag kBBS2 = TAG('B', 'B', 'S', '2');   // More aggressive packet
-                                                 // conservation in BBR STARTUP
-const QuicTag kBBS3 = TAG('B', 'B', 'S', '3');   // Slowstart packet
-                                                 // conservation in BBR STARTUP
-const QuicTag kBBS4 = TAG('B', 'B', 'S', '4');   // DEPRECATED
-const QuicTag kBBS5 = TAG('B', 'B', 'S', '5');   // DEPRECATED
-const QuicTag kBBRR = TAG('B', 'B', 'R', 'R');   // Rate-based recovery in BBR
-const QuicTag kBBR1 = TAG('B', 'B', 'R', '1');   // DEPRECATED
-const QuicTag kBBR2 = TAG('B', 'B', 'R', '2');   // DEPRECATED
-const QuicTag kBBR3 = TAG('B', 'B', 'R', '3');   // Fully drain the queue once
-                                                 // per cycle
-const QuicTag kBBR4 = TAG('B', 'B', 'R', '4');   // 20 RTT ack aggregation
-const QuicTag kBBR5 = TAG('B', 'B', 'R', '5');   // 40 RTT ack aggregation
-const QuicTag kBBR9 = TAG('B', 'B', 'R', '9');   // DEPRECATED
-const QuicTag kBBRA = TAG('B', 'B', 'R', 'A');   // Starts a new ack aggregation
-                                                 // epoch if a full round has
-                                                 // passed
-const QuicTag kBBRB = TAG('B', 'B', 'R', 'B');   // Use send rate in BBR's
-                                                 // MaxAckHeightTracker
-const QuicTag kBBRS = TAG('B', 'B', 'R', 'S');   // DEPRECATED
-const QuicTag kBBQ1 = TAG('B', 'B', 'Q', '1');   // BBR with lower 2.77 STARTUP
-                                                 // pacing and CWND gain.
-const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2');   // BBRv2 with 2.885 STARTUP and
-                                                 // DRAIN CWND gain.
-const QuicTag kBBQ3 = TAG('B', 'B', 'Q', '3');   // BBR with ack aggregation
-                                                 // compensation in STARTUP.
-const QuicTag kBBQ5 = TAG('B', 'B', 'Q', '5');   // Expire ack aggregation upon
-                                                 // bandwidth increase in
-                                                 // STARTUP.
-const QuicTag kBBQ6 = TAG('B', 'B', 'Q', '6');   // Reduce STARTUP gain to 25%
-                                                 // more than BW increase.
-const QuicTag kBBQ7 = TAG('B', 'B', 'Q', '7');   // Reduce bw_lo by
-                                                 // bytes_lost/min_rtt.
-const QuicTag kBBQ8 = TAG('B', 'B', 'Q', '8');   // Reduce bw_lo by
-                                                 // bw_lo * bytes_lost/inflight
-const QuicTag kBBQ9 = TAG('B', 'B', 'Q', '9');   // Reduce bw_lo by
-                                                 // bw_lo * bytes_lost/cwnd
-const QuicTag kBBQ0 = TAG('B', 'B', 'Q', '0');   // Increase bytes_acked in
-                                                 // PROBE_UP when app limited.
-const QuicTag kRENO = TAG('R', 'E', 'N', 'O');   // Reno Congestion Control
-const QuicTag kTPCC = TAG('P', 'C', 'C', '\0');  // Performance-Oriented
-                                                 // Congestion Control
-const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E');   // TCP cubic or reno in bytes
-const QuicTag kIW03 = TAG('I', 'W', '0', '3');   // Force ICWND to 3
-const QuicTag kIW10 = TAG('I', 'W', '1', '0');   // Force ICWND to 10
-const QuicTag kIW20 = TAG('I', 'W', '2', '0');   // Force ICWND to 20
-const QuicTag kIW50 = TAG('I', 'W', '5', '0');   // Force ICWND to 50
-const QuicTag kB2ON = TAG('B', '2', 'O', 'N');   // Enable BBRv2
-const QuicTag kB2NA = TAG('B', '2', 'N', 'A');   // For BBRv2, do not add ack
-                                                 // height to queueing threshold
-const QuicTag kB2NE = TAG('B', '2', 'N', 'E');   // For BBRv2, always exit
-                                                 // STARTUP on loss, even if
-                                                 // bandwidth growth exceeds
-                                                 // threshold.
-const QuicTag kB2RP = TAG('B', '2', 'R', 'P');   // For BBRv2, run PROBE_RTT on
-                                                 // the regular schedule
-const QuicTag kB2LO = TAG('B', '2', 'L', 'O');   // Ignore inflight_lo in BBR2
-const QuicTag kB2HR = TAG('B', '2', 'H', 'R');   // 15% inflight_hi headroom.
-const QuicTag kB2SL = TAG('B', '2', 'S', 'L');   // When exiting STARTUP due to
-                                                 // loss, set inflight_hi to the
-                                                 // max of bdp and max bytes
-                                                 // delivered in round.
-const QuicTag kB2H2 = TAG('B', '2', 'H', '2');   // When exiting PROBE_UP due to
-                                                 // loss, set inflight_hi to the
-                                                 // max of inflight@send and max
-                                                 // bytes delivered in round.
-const QuicTag kB2RC = TAG('B', '2', 'R', 'C');   // Disable Reno-coexistence for
-                                                 // BBR2.
-const QuicTag kBSAO = TAG('B', 'S', 'A', 'O');   // Avoid Overestimation in
-                                                 // Bandwidth Sampler with ack
-                                                 // aggregation
-const QuicTag kB2DL = TAG('B', '2', 'D', 'L');   // Increase inflight_hi based
-                                                 // on delievered, not inflight.
-const QuicTag kB201 = TAG('B', '2', '0', '1');   // In PROBE_UP, check if cwnd
-                                                 // limited before aggregation
-                                                 // epoch, instead of ack event.
-const QuicTag kB202 = TAG('B', '2', '0', '2');   // Do not exit PROBE_UP if
-                                                 // inflight dips below 1.25*BW.
-const QuicTag kB203 = TAG('B', '2', '0', '3');   // Ignore inflight_hi until
-                                                 // PROBE_UP is exited.
-const QuicTag kB204 = TAG('B', '2', '0', '4');   // Reduce extra acked when
-                                                 // MaxBW incrases.
-const QuicTag kB205 = TAG('B', '2', '0', '5');   // Add extra acked to CWND in
-                                                 // STARTUP.
-const QuicTag kB206 = TAG('B', '2', '0', '6');   // Exit STARTUP after 2 losses.
-const QuicTag kB207 = TAG('B', '2', '0', '7');   // Exit STARTUP on persistent
-                                                 // queue
-const QuicTag kNTLP = TAG('N', 'T', 'L', 'P');   // No tail loss probe
-const QuicTag k1TLP = TAG('1', 'T', 'L', 'P');   // 1 tail loss probe
-const QuicTag k1RTO = TAG('1', 'R', 'T', 'O');   // Send 1 packet upon RTO
-const QuicTag kNRTO = TAG('N', 'R', 'T', 'O');   // CWND reduction on loss
-const QuicTag kTIME = TAG('T', 'I', 'M', 'E');   // Time based loss detection
-const QuicTag kATIM = TAG('A', 'T', 'I', 'M');   // Adaptive time loss detection
-const QuicTag kMIN1 = TAG('M', 'I', 'N', '1');   // Min CWND of 1 packet
-const QuicTag kMIN4 = TAG('M', 'I', 'N', '4');   // Min CWND of 4 packets,
-                                                 // with a min rate of 1 BDP.
-const QuicTag kMAD0 = TAG('M', 'A', 'D', '0');   // Ignore ack delay
-const QuicTag kMAD2 = TAG('M', 'A', 'D', '2');   // No min TLP
-const QuicTag kMAD3 = TAG('M', 'A', 'D', '3');   // No min RTO
-const QuicTag k1ACK = TAG('1', 'A', 'C', 'K');   // 1 fast ack for reordering
-const QuicTag kAKD3 = TAG('A', 'K', 'D', '3');   // Ack decimation style acking
-                                                 // with 1/8 RTT acks.
-const QuicTag kAKDU = TAG('A', 'K', 'D', 'U');   // Unlimited number of packets
-                                                 // received before acking
-const QuicTag kAFFE = TAG('A', 'F', 'F', 'E');   // Enable client receiving
-                                                 // AckFrequencyFrame.
-const QuicTag kAFF1 = TAG('A', 'F', 'F', '1');   // Use SRTT in building
-                                                 // AckFrequencyFrame.
-const QuicTag kAFF2 = TAG('A', 'F', 'F', '2');   // Send AckFrequencyFrame upon
-                                                 // handshake completion.
-const QuicTag kSSLR = TAG('S', 'S', 'L', 'R');   // Slow Start Large Reduction.
-const QuicTag kNPRR = TAG('N', 'P', 'R', 'R');   // Pace at unity instead of PRR
-const QuicTag k2RTO = TAG('2', 'R', 'T', 'O');   // Close connection on 2 RTOs
-const QuicTag k3RTO = TAG('3', 'R', 'T', 'O');   // Close connection on 3 RTOs
-const QuicTag k4RTO = TAG('4', 'R', 'T', 'O');   // Close connection on 4 RTOs
-const QuicTag k5RTO = TAG('5', 'R', 'T', 'O');   // Close connection on 5 RTOs
-const QuicTag k6RTO = TAG('6', 'R', 'T', 'O');   // Close connection on 6 RTOs
-const QuicTag kCBHD = TAG('C', 'B', 'H', 'D');   // Client only blackhole
-                                                 // detection.
-const QuicTag kNBHD = TAG('N', 'B', 'H', 'D');   // No blackhole detection.
-const QuicTag kCONH = TAG('C', 'O', 'N', 'H');   // Conservative Handshake
-                                                 // Retransmissions.
-const QuicTag kLFAK = TAG('L', 'F', 'A', 'K');   // Don't invoke FACK on the
-                                                 // first ack.
-const QuicTag kSTMP = TAG('S', 'T', 'M', 'P');   // DEPRECATED
-const QuicTag kEACK = TAG('E', 'A', 'C', 'K');   // Bundle ack-eliciting frame
-                                                 // with an ACK after PTO/RTO
-
-const QuicTag kILD0 = TAG('I', 'L', 'D', '0');   // IETF style loss detection
-                                                 // (default with 1/8 RTT time
-                                                 // threshold)
-const QuicTag kILD1 = TAG('I', 'L', 'D', '1');   // IETF style loss detection
-                                                 // with 1/4 RTT time threshold
-const QuicTag kILD2 = TAG('I', 'L', 'D', '2');   // IETF style loss detection
-                                                 // with adaptive packet
-                                                 // threshold
-const QuicTag kILD3 = TAG('I', 'L', 'D', '3');   // IETF style loss detection
-                                                 // with 1/4 RTT time threshold
-                                                 // and adaptive packet
-                                                 // threshold
-const QuicTag kILD4 = TAG('I', 'L', 'D', '4');   // IETF style loss detection
-                                                 // with both adaptive time
-                                                 // threshold (default 1/4 RTT)
-                                                 // and adaptive packet
-                                                 // threshold
-const QuicTag kRUNT = TAG('R', 'U', 'N', 'T');   // No packet threshold loss
-                                                 // detection for "runt" packet.
-const QuicTag kNSTP = TAG('N', 'S', 'T', 'P');   // No stop waiting frames.
-const QuicTag kNRTT = TAG('N', 'R', 'T', 'T');   // Ignore initial RTT
-
-const QuicTag k1PTO = TAG('1', 'P', 'T', 'O');   // Send 1 packet upon PTO.
-const QuicTag k2PTO = TAG('2', 'P', 'T', 'O');   // Send 2 packets upon PTO.
-
-const QuicTag k6PTO = TAG('6', 'P', 'T', 'O');   // Closes connection on 6
-                                                 // consecutive PTOs.
-const QuicTag k7PTO = TAG('7', 'P', 'T', 'O');   // Closes connection on 7
-                                                 // consecutive PTOs.
-const QuicTag k8PTO = TAG('8', 'P', 'T', 'O');   // Closes connection on 8
-                                                 // consecutive PTOs.
-const QuicTag kPTOS = TAG('P', 'T', 'O', 'S');   // Skip packet number before
-                                                 // sending the last PTO.
-const QuicTag kPTOA = TAG('P', 'T', 'O', 'A');   // Do not add max ack delay
-                                                 // when computing PTO timeout
-                                                 // if an immediate ACK is
-                                                 // expected.
-const QuicTag kPEB1 = TAG('P', 'E', 'B', '1');   // Start exponential backoff
-                                                 // since 1st PTO.
-const QuicTag kPEB2 = TAG('P', 'E', 'B', '2');   // Start exponential backoff
-                                                 // since 2nd PTO.
-const QuicTag kPVS1 = TAG('P', 'V', 'S', '1');   // Use 2 * rttvar when
-                                                 // calculating PTO timeout.
-const QuicTag kPAG1 = TAG('P', 'A', 'G', '1');   // Make 1st PTO more aggressive
-const QuicTag kPAG2 = TAG('P', 'A', 'G', '2');   // Make first 2 PTOs more
-                                                 // aggressive
-const QuicTag kPSDA = TAG('P', 'S', 'D', 'A');   // Use standard deviation when
-                                                 // calculating PTO timeout.
-const QuicTag kPLE1 = TAG('P', 'L', 'E', '1');   // Arm the 1st PTO with
-                                                 // earliest in flight sent time
-                                                 // and at least 0.5*srtt from
-                                                 // last sent packet.
-const QuicTag kPLE2 = TAG('P', 'L', 'E', '2');   // Arm the 1st PTO with
-                                                 // earliest in flight sent time
-                                                 // and at least 1.5*srtt from
-                                                 // last sent packet.
-const QuicTag kAPTO = TAG('A', 'P', 'T', 'O');   // Use 1.5 * initial RTT before
-                                                 // any RTT sample is available.
-
-const QuicTag kELDT = TAG('E', 'L', 'D', 'T');   // Enable Loss Detection Tuning
-
-// TODO(haoyuewang) Remove RVCM option once
-// --quic_remove_connection_migration_connection_option is deprecated.
-const QuicTag kRVCM = TAG('R', 'V', 'C', 'M');   // Validate the new address
-                                                 // upon client address change.
-
-// Optional support of truncated Connection IDs.  If sent by a peer, the value
-// is the minimum number of bytes allowed for the connection ID sent to the
-// peer.
-const QuicTag kTCID = TAG('T', 'C', 'I', 'D');   // Connection ID truncation.
-
-// Multipath option.
-const QuicTag kMPTH = TAG('M', 'P', 'T', 'H');   // Enable multipath.
-
-const QuicTag kNCMR = TAG('N', 'C', 'M', 'R');   // Do not attempt connection
-                                                 // migration.
-
-// Allows disabling defer_send_in_response_to_packets in QuicConnection.
-const QuicTag kDFER = TAG('D', 'F', 'E', 'R');   // Do not defer sending.
-
-// Disable Pacing offload option.
-const QuicTag kNPCO = TAG('N', 'P', 'C', 'O');    // No pacing offload.
-
-// Enable bandwidth resumption experiment.
-const QuicTag kBWRE = TAG('B', 'W', 'R', 'E');  // Bandwidth resumption.
-const QuicTag kBWMX = TAG('B', 'W', 'M', 'X');  // Max bandwidth resumption.
-const QuicTag kBWRS = TAG('B', 'W', 'R', 'S');  // Server bandwidth resumption.
-const QuicTag kBWS2 = TAG('B', 'W', 'S', '2');  // Server bw resumption v2.
-const QuicTag kBWS3 = TAG('B', 'W', 'S', '3');  // QUIC Initial CWND - Control.
-const QuicTag kBWS4 = TAG('B', 'W', 'S', '4');  // QUIC Initial CWND - Enabled.
-const QuicTag kBWS5 = TAG('B', 'W', 'S', '5');  // QUIC Initial CWND up and down
-const QuicTag kBWS6 = TAG('B', 'W', 'S', '6');  // QUIC Initial CWND - Enabled
-                                                // with 0.5 * default
-                                                // multiplier.
-const QuicTag kBWP0 = TAG('B', 'W', 'P', '0');  // QUIC Initial CWND - SPDY
-                                                // priority 0.
-const QuicTag kBWP1 = TAG('B', 'W', 'P', '1');  // QUIC Initial CWND - SPDY
-                                                // priorities 0 and 1.
-const QuicTag kBWP2 = TAG('B', 'W', 'P', '2');  // QUIC Initial CWND - SPDY
-                                                // priorities 0, 1 and 2.
-const QuicTag kBWP3 = TAG('B', 'W', 'P', '3');  // QUIC Initial CWND - SPDY
-                                                // priorities 0, 1, 2 and 3.
-const QuicTag kBWP4 = TAG('B', 'W', 'P', '4');  // QUIC Initial CWND - SPDY
-                                                // priorities >= 0, 1, 2, 3 and
-                                                // 4.
-const QuicTag kBWG4 = TAG('B', 'W', 'G', '4');  // QUIC Initial CWND -
-                                                // Bandwidth model 1.
-const QuicTag kBWG7 = TAG('B', 'W', 'G', '7');  // QUIC Initial CWND -
-                                                // Bandwidth model 2.
-const QuicTag kBWG8 = TAG('B', 'W', 'G', '8');  // QUIC Initial CWND -
-                                                // Bandwidth model 3.
-const QuicTag kBWS7 = TAG('B', 'W', 'S', '7');  // QUIC Initial CWND - Enabled
-                                                // with 0.75 * default
-                                                // multiplier.
-const QuicTag kBWM3 = TAG('B', 'W', 'M', '3');  // Consider overshooting if
-                                                // bytes lost after bandwidth
-                                                // resumption * 3 > IW.
-const QuicTag kBWM4 = TAG('B', 'W', 'M', '4');  // Consider overshooting if
-                                                // bytes lost after bandwidth
-                                                // resumption * 4 > IW.
-const QuicTag kICW1 = TAG('I', 'C', 'W', '1');  // Max initial congestion window
-                                                // 100.
-const QuicTag kDTOS = TAG('D', 'T', 'O', 'S');  // Enable overshooting
-                                                // detection.
-
-const QuicTag kFIDT = TAG('F', 'I', 'D', 'T');  // Extend idle timer by PTO
-                                                // instead of the whole idle
-                                                // timeout.
-
-const QuicTag k3AFF = TAG('3', 'A', 'F', 'F');  // 3 anti amplification factor.
-const QuicTag k10AF = TAG('1', '0', 'A', 'F');  // 10 anti amplification factor.
-
-// Enable path MTU discovery experiment.
-const QuicTag kMTUH = TAG('M', 'T', 'U', 'H');  // High-target MTU discovery.
-const QuicTag kMTUL = TAG('M', 'T', 'U', 'L');  // Low-target MTU discovery.
-
-const QuicTag kNSLC = TAG('N', 'S', 'L', 'C');  // Always send connection close
-                                                // for idle timeout.
-const QuicTag kNCHP = TAG('N', 'C', 'H', 'P');  // No chaos protection.
-const QuicTag kNBPE = TAG('N', 'B', 'P', 'E');  // No BoringSSL Permutes
-                                                // TLS Extensions.
-
-// Proof types (i.e. certificate types)
-// NOTE: although it would be silly to do so, specifying both kX509 and kX59R
-// is allowed and is equivalent to specifying only kX509.
-const QuicTag kX509 = TAG('X', '5', '0', '9');   // X.509 certificate, all key
-                                                 // types
-const QuicTag kX59R = TAG('X', '5', '9', 'R');   // X.509 certificate, RSA keys
-                                                 // only
-const QuicTag kCHID = TAG('C', 'H', 'I', 'D');   // Channel ID.
-
-// Client hello tags
-const QuicTag kVER  = TAG('V', 'E', 'R', '\0');  // Version
-const QuicTag kNONC = TAG('N', 'O', 'N', 'C');   // The client's nonce
-const QuicTag kNONP = TAG('N', 'O', 'N', 'P');   // The client's proof nonce
-const QuicTag kKEXS = TAG('K', 'E', 'X', 'S');   // Key exchange methods
-const QuicTag kAEAD = TAG('A', 'E', 'A', 'D');   // Authenticated
-                                                 // encryption algorithms
-const QuicTag kCOPT = TAG('C', 'O', 'P', 'T');   // Connection options
-const QuicTag kCLOP = TAG('C', 'L', 'O', 'P');   // Client connection options
-const QuicTag kICSL = TAG('I', 'C', 'S', 'L');   // Idle network timeout
-const QuicTag kMIBS = TAG('M', 'I', 'D', 'S');   // Max incoming bidi streams
-const QuicTag kMIUS = TAG('M', 'I', 'U', 'S');   // Max incoming unidi streams
-const QuicTag kADE  = TAG('A', 'D', 'E', 0);     // Ack Delay Exponent (IETF
-                                                 // QUIC ACK Frame Only).
-const QuicTag kIRTT = TAG('I', 'R', 'T', 'T');   // Estimated initial RTT in us.
-const QuicTag kTRTT = TAG('T', 'R', 'T', 'T');   // If server receives an rtt
-                                                 // from an address token, set
-                                                 // it as the initial rtt.
-const QuicTag kSNI  = TAG('S', 'N', 'I', '\0');  // Server name
-                                                 // indication
-const QuicTag kPUBS = TAG('P', 'U', 'B', 'S');   // Public key values
-const QuicTag kSCID = TAG('S', 'C', 'I', 'D');   // Server config id
-const QuicTag kORBT = TAG('O', 'B', 'I', 'T');   // Server orbit.
-const QuicTag kPDMD = TAG('P', 'D', 'M', 'D');   // Proof demand.
-const QuicTag kPROF = TAG('P', 'R', 'O', 'F');   // Proof (signature).
-const QuicTag kCCRT = TAG('C', 'C', 'R', 'T');   // Cached certificate
-const QuicTag kEXPY = TAG('E', 'X', 'P', 'Y');   // Expiry
-const QuicTag kSTTL = TAG('S', 'T', 'T', 'L');   // Server Config TTL
-const QuicTag kSFCW = TAG('S', 'F', 'C', 'W');   // Initial stream flow control
-                                                 // receive window.
-const QuicTag kCFCW = TAG('C', 'F', 'C', 'W');   // Initial session/connection
-                                                 // flow control receive window.
-const QuicTag kUAID = TAG('U', 'A', 'I', 'D');   // Client's User Agent ID.
-const QuicTag kXLCT = TAG('X', 'L', 'C', 'T');   // Expected leaf certificate.
-const QuicTag kQLVE = TAG('Q', 'L', 'V', 'E');   // Legacy Version
-                                                 // Encapsulation.
-
-const QuicTag kPDP1 = TAG('P', 'D', 'P', '1');   // Path degrading triggered
-                                                 // at 1PTO.
-
-const QuicTag kPDP2 = TAG('P', 'D', 'P', '2');   // Path degrading triggered
-                                                 // at 2PTO.
-
-const QuicTag kPDP3 = TAG('P', 'D', 'P', '3');   // Path degrading triggered
-                                                 // at 3PTO.
-
-const QuicTag kPDP4 = TAG('P', 'D', 'P', '4');   // Path degrading triggered
-                                                 // at 4PTO.
-
-const QuicTag kPDP5 = TAG('P', 'D', 'P', '5');   // Path degrading triggered
-                                                 // at 5PTO.
-
-const QuicTag kQNZ2 = TAG('Q', 'N', 'Z', '2');   // Turn off QUIC crypto 0-RTT.
-
-const QuicTag kMAD  = TAG('M', 'A', 'D', 0);     // Max Ack Delay (IETF QUIC)
-
-const QuicTag kIGNP = TAG('I', 'G', 'N', 'P');   // Do not use PING only packet
-                                                 // for RTT measure or
-                                                 // congestion control.
-
-const QuicTag kSRWP = TAG('S', 'R', 'W', 'P');   // Enable retransmittable on
-                                                 // wire PING (ROWP) on the
-                                                 // server side.
-const QuicTag kGSR0 = TAG('G', 'S', 'R', '0');   // Selective Resumption
-
-const QuicTag kINVC = TAG('I', 'N', 'V', 'C');   // Send connection close for
-                                                 // INVALID_VERSION
-
-// Client Hints triggers.
-const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
-const QuicTag kYTCH = TAG('Y', 'T', 'C', 'H');
-const QuicTag kACH0 = TAG('A', 'C', 'H', '0');
-
-// Rejection tags
-const QuicTag kRREJ = TAG('R', 'R', 'E', 'J');   // Reasons for server sending
-
-// Server hello tags
-const QuicTag kCADR = TAG('C', 'A', 'D', 'R');   // Client IP address and port
-const QuicTag kASAD = TAG('A', 'S', 'A', 'D');   // Alternate Server IP address
-                                                 // and port.
-const QuicTag kSRST = TAG('S', 'R', 'S', 'T');   // Stateless reset token used
-                                                 // in IETF public reset packet
-
-// CETV tags
-const QuicTag kCIDK = TAG('C', 'I', 'D', 'K');   // ChannelID key
-const QuicTag kCIDS = TAG('C', 'I', 'D', 'S');   // ChannelID signature
-
-// Public reset tags
-const QuicTag kRNON = TAG('R', 'N', 'O', 'N');   // Public reset nonce proof
-const QuicTag kRSEQ = TAG('R', 'S', 'E', 'Q');   // Rejected packet number
-
-// Universal tags
-const QuicTag kPAD  = TAG('P', 'A', 'D', '\0');  // Padding
-
-// Stats collection tags
-const QuicTag kEPID = TAG('E', 'P', 'I', 'D');  // Endpoint identifier.
-
-// clang-format on
-
-// These tags have a special form so that they appear either at the beginning
-// or the end of a handshake message. Since handshake messages are sorted by
-// tag value, the tags with 0 at the end will sort first and those with 255 at
-// the end will sort last.
-//
-// The certificate chain should have a tag that will cause it to be sorted at
-// the end of any handshake messages because it's likely to be large and the
-// client might be able to get everything that it needs from the small values at
-// the beginning.
-//
-// Likewise tags with random values should be towards the beginning of the
-// message because the server mightn't hold state for a rejected client hello
-// and therefore the client may have issues reassembling the rejection message
-// in the event that it sent two client hellos.
-const QuicTag kServerNonceTag = TAG('S', 'N', 'O', 0);  // The server's nonce
-const QuicTag kSourceAddressTokenTag =
-    TAG('S', 'T', 'K', 0);  // Source-address token
-const QuicTag kCertificateTag = TAG('C', 'R', 'T', 255);  // Certificate chain
-const QuicTag kCertificateSCTTag =
-    TAG('C', 'S', 'C', 'T');  // Signed cert timestamp (RFC6962) of leaf cert.
-
-#undef TAG
-
-const size_t kMaxEntries = 128;  // Max number of entries in a message.
-
-const size_t kNonceSize = 32;  // Size in bytes of the connection nonce.
-
-const size_t kOrbitSize = 8;  // Number of bytes in an orbit value.
-
-// kProofSignatureLabel is prepended to the CHLO hash and server configs before
-// signing to avoid any cross-protocol attacks on the signature.
-const char kProofSignatureLabel[] = "QUIC CHLO and server config signature";
-
-// kClientHelloMinimumSize is the minimum size of a client hello. Client hellos
-// will have PAD tags added in order to ensure this minimum is met and client
-// hellos smaller than this will be an error. This minimum size reduces the
-// amplification factor of any mirror DoS attack.
-//
-// A client may pad an inchoate client hello to a size larger than
-// kClientHelloMinimumSize to make it more likely to receive a complete
-// rejection message.
-const size_t kClientHelloMinimumSize = 1024;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
diff --git a/quic/core/crypto/crypto_secret_boxer.cc b/quic/core/crypto/crypto_secret_boxer.cc
deleted file mode 100644
index a4a7a2a..0000000
--- a/quic/core/crypto/crypto_secret_boxer.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstdint>
-#include <string>
-
-#include "quic/core/crypto/crypto_secret_boxer.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// kSIVNonceSize contains the number of bytes of nonce in each AES-GCM-SIV box.
-// AES-GCM-SIV takes a 12-byte nonce and, since the messages are so small, each
-// key is good for more than 2^64 source-address tokens. See table 1 of
-// https://eprint.iacr.org/2017/168.pdf
-static const size_t kSIVNonceSize = 12;
-
-// AES-GCM-SIV comes in AES-128 and AES-256 flavours. The AES-256 version is
-// used here so that the key size matches the 256-bit XSalsa20 keys that we
-// used to use.
-static const size_t kBoxKeySize = 32;
-
-struct CryptoSecretBoxer::State {
-  // ctxs are the initialised AEAD contexts. These objects contain the
-  // scheduled AES state for each of the keys.
-  std::vector<bssl::UniquePtr<EVP_AEAD_CTX>> ctxs;
-};
-
-CryptoSecretBoxer::CryptoSecretBoxer() {}
-
-CryptoSecretBoxer::~CryptoSecretBoxer() {}
-
-// static
-size_t CryptoSecretBoxer::GetKeySize() {
-  return kBoxKeySize;
-}
-
-// kAEAD is the AEAD used for boxing: AES-256-GCM-SIV.
-static const EVP_AEAD* (*const kAEAD)() = EVP_aead_aes_256_gcm_siv;
-
-bool CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
-  if (keys.empty()) {
-    QUIC_LOG(DFATAL) << "No keys supplied!";
-    return false;
-  }
-  const EVP_AEAD* const aead = kAEAD();
-  std::unique_ptr<State> new_state(new State);
-
-  for (const std::string& key : keys) {
-    QUICHE_DCHECK_EQ(kBoxKeySize, key.size());
-    bssl::UniquePtr<EVP_AEAD_CTX> ctx(
-        EVP_AEAD_CTX_new(aead, reinterpret_cast<const uint8_t*>(key.data()),
-                         key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH));
-    if (!ctx) {
-      ERR_clear_error();
-      QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_init failed";
-      return false;
-    }
-
-    new_state->ctxs.push_back(std::move(ctx));
-  }
-
-  QuicWriterMutexLock l(&lock_);
-  state_ = std::move(new_state);
-  return true;
-}
-
-std::string CryptoSecretBoxer::Box(QuicRandom* rand,
-                                   absl::string_view plaintext) const {
-  // The box is formatted as:
-  //   12 bytes of random nonce
-  //   n bytes of ciphertext
-  //   16 bytes of authenticator
-  size_t out_len =
-      kSIVNonceSize + plaintext.size() + EVP_AEAD_max_overhead(kAEAD());
-
-  std::string ret;
-  ret.resize(out_len);
-  uint8_t* out = reinterpret_cast<uint8_t*>(const_cast<char*>(ret.data()));
-
-  // Write kSIVNonceSize bytes of random nonce to the beginning of the output
-  // buffer.
-  rand->RandBytes(out, kSIVNonceSize);
-  const uint8_t* const nonce = out;
-  out += kSIVNonceSize;
-  out_len -= kSIVNonceSize;
-
-  size_t bytes_written;
-  {
-    QuicReaderMutexLock l(&lock_);
-    if (!EVP_AEAD_CTX_seal(state_->ctxs[0].get(), out, &bytes_written, out_len,
-                           nonce, kSIVNonceSize,
-                           reinterpret_cast<const uint8_t*>(plaintext.data()),
-                           plaintext.size(), nullptr, 0)) {
-      ERR_clear_error();
-      QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_seal failed";
-      return "";
-    }
-  }
-
-  QUICHE_DCHECK_EQ(out_len, bytes_written);
-  return ret;
-}
-
-bool CryptoSecretBoxer::Unbox(absl::string_view in_ciphertext,
-                              std::string* out_storage,
-                              absl::string_view* out) const {
-  if (in_ciphertext.size() < kSIVNonceSize) {
-    return false;
-  }
-
-  const uint8_t* const nonce =
-      reinterpret_cast<const uint8_t*>(in_ciphertext.data());
-  const uint8_t* const ciphertext = nonce + kSIVNonceSize;
-  const size_t ciphertext_len = in_ciphertext.size() - kSIVNonceSize;
-
-  out_storage->resize(ciphertext_len);
-
-  bool ok = false;
-  {
-    QuicReaderMutexLock l(&lock_);
-    for (const bssl::UniquePtr<EVP_AEAD_CTX>& ctx : state_->ctxs) {
-      size_t bytes_written;
-      if (EVP_AEAD_CTX_open(ctx.get(),
-                            reinterpret_cast<uint8_t*>(
-                                const_cast<char*>(out_storage->data())),
-                            &bytes_written, ciphertext_len, nonce,
-                            kSIVNonceSize, ciphertext, ciphertext_len, nullptr,
-                            0)) {
-        ok = true;
-        *out = absl::string_view(out_storage->data(), bytes_written);
-        break;
-      }
-
-      ERR_clear_error();
-    }
-  }
-
-  return ok;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_secret_boxer.h b/quic/core/crypto/crypto_secret_boxer.h
deleted file mode 100644
index e2cd037..0000000
--- a/quic/core/crypto/crypto_secret_boxer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
-
-#include <cstddef>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_mutex.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// CryptoSecretBoxer encrypts small chunks of plaintext (called 'boxing') and
-// then, later, can authenticate+decrypt the resulting boxes. This object is
-// thread-safe.
-class QUIC_EXPORT_PRIVATE CryptoSecretBoxer {
- public:
-  CryptoSecretBoxer();
-  CryptoSecretBoxer(const CryptoSecretBoxer&) = delete;
-  CryptoSecretBoxer& operator=(const CryptoSecretBoxer&) = delete;
-  ~CryptoSecretBoxer();
-
-  // GetKeySize returns the number of bytes in a key.
-  static size_t GetKeySize();
-
-  // SetKeys sets a list of encryption keys. The first key in the list will be
-  // used by |Box|, but all supplied keys will be tried by |Unbox|, to handle
-  // key skew across the fleet. This must be called before |Box| or |Unbox|.
-  // Keys must be |GetKeySize()| bytes long. No change is made if any key is
-  // invalid, or if there are no keys supplied.
-  bool SetKeys(const std::vector<std::string>& keys);
-
-  // Box encrypts |plaintext| using a random nonce generated from |rand| and
-  // returns the resulting ciphertext. Since an authenticator and nonce are
-  // included, the result will be slightly larger than |plaintext|. The first
-  // key in the vector supplied to |SetKeys| will be used. |SetKeys| must be
-  // called before calling this method.
-  std::string Box(QuicRandom* rand, absl::string_view plaintext) const;
-
-  // Unbox takes the result of a previous call to |Box| in |ciphertext| and
-  // authenticates+decrypts it. If |ciphertext| cannot be decrypted with any of
-  // the supplied keys, the function returns false. Otherwise, |out_storage| is
-  // used to store the result and |out| is set to point into |out_storage| and
-  // contains the original plaintext.
-  bool Unbox(absl::string_view ciphertext,
-             std::string* out_storage,
-             absl::string_view* out) const;
-
- private:
-  struct State;
-
-  mutable QuicMutex lock_;
-
-  // state_ is an opaque pointer to whatever additional state the concrete
-  // implementation of CryptoSecretBoxer requires.
-  std::unique_ptr<State> state_ QUIC_GUARDED_BY(lock_);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
diff --git a/quic/core/crypto/crypto_secret_boxer_test.cc b/quic/core/crypto/crypto_secret_boxer_test.cc
deleted file mode 100644
index 7b07d96..0000000
--- a/quic/core/crypto/crypto_secret_boxer_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_secret_boxer.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class CryptoSecretBoxerTest : public QuicTest {};
-
-TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) {
-  absl::string_view message("hello world");
-
-  CryptoSecretBoxer boxer;
-  boxer.SetKeys({std::string(CryptoSecretBoxer::GetKeySize(), 0x11)});
-
-  const std::string box = boxer.Box(QuicRandom::GetInstance(), message);
-
-  std::string storage;
-  absl::string_view result;
-  EXPECT_TRUE(boxer.Unbox(box, &storage, &result));
-  EXPECT_EQ(result, message);
-
-  EXPECT_FALSE(boxer.Unbox(std::string(1, 'X') + box, &storage, &result));
-  EXPECT_FALSE(
-      boxer.Unbox(box.substr(1, std::string::npos), &storage, &result));
-  EXPECT_FALSE(boxer.Unbox(std::string(), &storage, &result));
-  EXPECT_FALSE(boxer.Unbox(
-      std::string(1, box[0] ^ 0x80) + box.substr(1, std::string::npos),
-      &storage, &result));
-}
-
-// Helper function to test whether one boxer can decode the output of another.
-static bool CanDecode(const CryptoSecretBoxer& decoder,
-                      const CryptoSecretBoxer& encoder) {
-  absl::string_view message("hello world");
-  const std::string boxed = encoder.Box(QuicRandom::GetInstance(), message);
-  std::string storage;
-  absl::string_view result;
-  bool ok = decoder.Unbox(boxed, &storage, &result);
-  if (ok) {
-    EXPECT_EQ(result, message);
-  }
-  return ok;
-}
-
-TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
-  std::string key_11(CryptoSecretBoxer::GetKeySize(), 0x11);
-  std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12);
-
-  CryptoSecretBoxer boxer_11, boxer_12, boxer;
-  EXPECT_TRUE(boxer_11.SetKeys({key_11}));
-  EXPECT_TRUE(boxer_12.SetKeys({key_12}));
-  EXPECT_TRUE(boxer.SetKeys({key_12, key_11}));
-
-  // Neither single-key boxer can decode the other's tokens.
-  EXPECT_FALSE(CanDecode(boxer_11, boxer_12));
-  EXPECT_FALSE(CanDecode(boxer_12, boxer_11));
-
-  // |boxer| encodes with the first key, which is key_12.
-  EXPECT_TRUE(CanDecode(boxer_12, boxer));
-  EXPECT_FALSE(CanDecode(boxer_11, boxer));
-
-  // The boxer with both keys can decode tokens from either single-key boxer.
-  EXPECT_TRUE(CanDecode(boxer, boxer_11));
-  EXPECT_TRUE(CanDecode(boxer, boxer_12));
-
-  // After we flush key_11 from |boxer|, it can no longer decode tokens from
-  // |boxer_11|.
-  EXPECT_TRUE(boxer.SetKeys({key_12}));
-  EXPECT_FALSE(CanDecode(boxer, boxer_11));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_server_test.cc b/quic/core/crypto/crypto_server_test.cc
deleted file mode 100644
index d6c5815..0000000
--- a/quic/core/crypto/crypto_server_test.cc
+++ /dev/null
@@ -1,1128 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/failing_proof_source.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-class DummyProofVerifierCallback : public ProofVerifierCallback {
- public:
-  DummyProofVerifierCallback() {}
-  ~DummyProofVerifierCallback() override {}
-
-  void Run(bool /*ok*/,
-           const std::string& /*error_details*/,
-           std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
-    QUICHE_DCHECK(false);
-  }
-};
-
-const char kOldConfigId[] = "old-config-id";
-
-}  // namespace
-
-struct TestParams {
-  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
-    os << "  versions: "
-       << ParsedQuicVersionVectorToString(p.supported_versions) << " }";
-    return os;
-  }
-
-  // Versions supported by client and server.
-  ParsedQuicVersionVector supported_versions;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  std::string rv = ParsedQuicVersionVectorToString(p.supported_versions);
-  std::replace(rv.begin(), rv.end(), ',', '_');
-  return rv;
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-
-  // Start with all versions, remove highest on each iteration.
-  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
-  while (!supported_versions.empty()) {
-    params.push_back({supported_versions});
-    supported_versions.erase(supported_versions.begin());
-  }
-
-  return params;
-}
-
-class CryptoServerTest : public QuicTestWithParam<TestParams> {
- public:
-  CryptoServerTest()
-      : rand_(QuicRandom::GetInstance()),
-        client_address_(QuicIpAddress::Loopback4(), 1234),
-        client_version_(UnsupportedQuicVersion()),
-        config_(QuicCryptoServerConfig::TESTING,
-                rand_,
-                crypto_test_utils::ProofSourceForTesting(),
-                KeyExchangeSource::Default()),
-        peer_(&config_),
-        compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
-        params_(new QuicCryptoNegotiatedParameters),
-        signed_config_(new QuicSignedServerConfig),
-        chlo_packet_size_(kDefaultMaxPacketSize) {
-    supported_versions_ = GetParam().supported_versions;
-    config_.set_enable_serving_sct(true);
-
-    client_version_ = supported_versions_.front();
-    client_version_label_ = CreateQuicVersionLabel(client_version_);
-    client_version_string_ =
-        std::string(reinterpret_cast<const char*>(&client_version_label_),
-                    sizeof(client_version_label_));
-  }
-
-  void SetUp() override {
-    QuicCryptoServerConfig::ConfigOptions old_config_options;
-    old_config_options.id = kOldConfigId;
-    config_.AddDefaultConfig(rand_, &clock_, old_config_options);
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
-    QuicServerConfigProtobuf primary_config =
-        config_.GenerateConfig(rand_, &clock_, config_options_);
-    primary_config.set_primary_time(clock_.WallNow().ToUNIXSeconds());
-    std::unique_ptr<CryptoHandshakeMessage> msg(
-        config_.AddConfig(primary_config, clock_.WallNow()));
-
-    absl::string_view orbit;
-    QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
-    QUICHE_CHECK_EQ(sizeof(orbit_), orbit.size());
-    memcpy(orbit_, orbit.data(), orbit.size());
-
-    char public_value[32];
-    memset(public_value, 42, sizeof(public_value));
-
-    nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce());
-    pub_hex_ = "#" + absl::BytesToHexString(
-                         absl::string_view(public_value, sizeof(public_value)));
-
-    CryptoHandshakeMessage client_hello =
-        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                       {"AEAD", "AESG"},
-                                       {"KEXS", "C255"},
-                                       {"PUBS", pub_hex_},
-                                       {"NONC", nonce_hex_},
-                                       {"CSCT", ""},
-                                       {"VER\0", client_version_string_}},
-                                      kClientHelloMinimumSize);
-    ShouldSucceed(client_hello);
-    // The message should be rejected because the source-address token is
-    // missing.
-    CheckRejectTag();
-    const HandshakeFailureReason kRejectReasons[] = {
-        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
-    absl::string_view srct;
-    ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
-    srct_hex_ = "#" + absl::BytesToHexString(srct);
-
-    absl::string_view scfg;
-    ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
-    server_config_ = CryptoFramer::ParseMessage(scfg);
-
-    absl::string_view scid;
-    ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
-    scid_hex_ = "#" + absl::BytesToHexString(scid);
-
-    signed_config_ =
-        quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>(
-            new QuicSignedServerConfig());
-    QUICHE_DCHECK(signed_config_->chain.get() == nullptr);
-  }
-
-  // Helper used to accept the result of ValidateClientHello and pass
-  // it on to ProcessClientHello.
-  class ValidateCallback : public ValidateClientHelloResultCallback {
-   public:
-    ValidateCallback(CryptoServerTest* test,
-                     bool should_succeed,
-                     const char* error_substr,
-                     bool* called)
-        : test_(test),
-          should_succeed_(should_succeed),
-          error_substr_(error_substr),
-          called_(called) {
-      *called_ = false;
-    }
-
-    void Run(quiche::QuicheReferenceCountedPointer<Result> result,
-             std::unique_ptr<ProofSource::Details> /* details */) override {
-      ASSERT_FALSE(*called_);
-      test_->ProcessValidationResult(std::move(result), should_succeed_,
-                                     error_substr_);
-      *called_ = true;
-    }
-
-   private:
-    CryptoServerTest* test_;
-    const bool should_succeed_;
-    const char* const error_substr_;
-    bool* called_;
-  };
-
-  void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
-    QuicVersionLabelVector versions;
-    server_hello.GetVersionLabelList(kVER, &versions);
-    ASSERT_EQ(supported_versions_.size(), versions.size());
-    for (size_t i = 0; i < versions.size(); ++i) {
-      EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[i]), versions[i]);
-    }
-
-    absl::string_view address;
-    ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address));
-    QuicSocketAddressCoder decoder;
-    ASSERT_TRUE(decoder.Decode(address.data(), address.size()));
-    EXPECT_EQ(client_address_.host(), decoder.ip());
-    EXPECT_EQ(client_address_.port(), decoder.port());
-  }
-
-  void ShouldSucceed(const CryptoHandshakeMessage& message) {
-    bool called = false;
-    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
-    config_.ValidateClientHello(
-        message, client_address_, server_address,
-        supported_versions_.front().transport_version, &clock_, signed_config_,
-        std::make_unique<ValidateCallback>(this, true, "", &called));
-    EXPECT_TRUE(called);
-  }
-
-  void ShouldFailMentioning(const char* error_substr,
-                            const CryptoHandshakeMessage& message) {
-    bool called = false;
-    ShouldFailMentioning(error_substr, message, &called);
-    EXPECT_TRUE(called);
-  }
-
-  void ShouldFailMentioning(const char* error_substr,
-                            const CryptoHandshakeMessage& message,
-                            bool* called) {
-    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
-    config_.ValidateClientHello(
-        message, client_address_, server_address,
-        supported_versions_.front().transport_version, &clock_, signed_config_,
-        std::make_unique<ValidateCallback>(this, false, error_substr, called));
-  }
-
-  class ProcessCallback : public ProcessClientHelloResultCallback {
-   public:
-    ProcessCallback(
-        quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
-        bool should_succeed, const char* error_substr, bool* called,
-        CryptoHandshakeMessage* out)
-        : result_(std::move(result)),
-          should_succeed_(should_succeed),
-          error_substr_(error_substr),
-          called_(called),
-          out_(out) {
-      *called_ = false;
-    }
-
-    void Run(QuicErrorCode error,
-             const std::string& error_details,
-             std::unique_ptr<CryptoHandshakeMessage> message,
-             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
-             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
-        override {
-      if (should_succeed_) {
-        ASSERT_EQ(error, QUIC_NO_ERROR)
-            << "Message failed with error " << error_details << ": "
-            << result_->client_hello.DebugString();
-      } else {
-        ASSERT_NE(error, QUIC_NO_ERROR)
-            << "Message didn't fail: " << result_->client_hello.DebugString();
-        EXPECT_TRUE(absl::StrContains(error_details, error_substr_))
-            << error_substr_ << " not in " << error_details;
-      }
-      if (message != nullptr) {
-        *out_ = *message;
-      }
-      *called_ = true;
-    }
-
-   private:
-    const quiche::QuicheReferenceCountedPointer<ValidateCallback::Result>
-        result_;
-    const bool should_succeed_;
-    const char* const error_substr_;
-    bool* called_;
-    CryptoHandshakeMessage* out_;
-  };
-
-  void ProcessValidationResult(
-      quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
-      bool should_succeed, const char* error_substr) {
-    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
-    bool called;
-    config_.ProcessClientHello(
-        result, /*reject_only=*/false,
-        /*connection_id=*/TestConnectionId(1), server_address, client_address_,
-        supported_versions_.front(), supported_versions_, &clock_, rand_,
-        &compressed_certs_cache_, params_, signed_config_,
-        /*total_framing_overhead=*/50, chlo_packet_size_,
-        std::make_unique<ProcessCallback>(result, should_succeed, error_substr,
-                                          &called, &out_));
-    EXPECT_TRUE(called);
-  }
-
-  std::string GenerateNonce() {
-    std::string nonce;
-    CryptoUtils::GenerateNonce(
-        clock_.WallNow(), rand_,
-        absl::string_view(reinterpret_cast<const char*>(orbit_),
-                          sizeof(orbit_)),
-        &nonce);
-    return nonce;
-  }
-
-  void CheckRejectReasons(
-      const HandshakeFailureReason* expected_handshake_failures,
-      size_t expected_count) {
-    QuicTagVector reject_reasons;
-    static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
-    QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons);
-    ASSERT_THAT(error_code, IsQuicNoError());
-
-    EXPECT_EQ(expected_count, reject_reasons.size());
-    for (size_t i = 0; i < reject_reasons.size(); ++i) {
-      EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
-                reject_reasons[i]);
-    }
-  }
-
-  void CheckRejectTag() {
-    ASSERT_EQ(kREJ, out_.tag()) << QuicTagToString(out_.tag());
-  }
-
-  std::string XlctHexString() {
-    uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
-    return "#" + absl::BytesToHexString(absl::string_view(
-                     reinterpret_cast<char*>(&xlct), sizeof(xlct)));
-  }
-
- protected:
-  QuicRandom* const rand_;
-  MockRandom rand_for_id_generation_;
-  MockClock clock_;
-  QuicSocketAddress client_address_;
-  ParsedQuicVersionVector supported_versions_;
-  ParsedQuicVersion client_version_;
-  QuicVersionLabel client_version_label_;
-  std::string client_version_string_;
-  QuicCryptoServerConfig config_;
-  QuicCryptoServerConfigPeer peer_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-  QuicCryptoServerConfig::ConfigOptions config_options_;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
-  CryptoHandshakeMessage out_;
-  uint8_t orbit_[kOrbitSize];
-  size_t chlo_packet_size_;
-
-  // These strings contain hex escaped values from the server suitable for using
-  // when constructing client hello messages.
-  std::string nonce_hex_, pub_hex_, srct_hex_, scid_hex_;
-  std::unique_ptr<CryptoHandshakeMessage> server_config_;
-};
-
-INSTANTIATE_TEST_SUITE_P(CryptoServerTests,
-                         CryptoServerTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(CryptoServerTest, BadSNI) {
-  // clang-format off
-  std::vector<std::string> badSNIs = {
-    "",
-    "#00",
-    "#ff00",
-    "127.0.0.1",
-    "ffee::1",
-  };
-  // clang-format on
-
-  for (const std::string& bad_sni : badSNIs) {
-    CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-        {{"PDMD", "X509"}, {"SNI", bad_sni}, {"VER\0", client_version_string_}},
-        kClientHelloMinimumSize);
-    ShouldFailMentioning("SNI", msg);
-    const HandshakeFailureReason kRejectReasons[] = {
-        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-  }
-
-  // Check that SNIs without dots are allowed
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"}, {"SNI", "foo"}, {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-  ShouldSucceed(msg);
-}
-
-TEST_P(CryptoServerTest, DefaultCert) {
-  // Check that the server replies with a default certificate when no SNI is
-  // specified. The CHLO is constructed to generate a REJ with certs, so must
-  // not contain a valid STK, and must include PDMD.
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"PDMD", "X509"},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  absl::string_view cert, proof, cert_sct;
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
-  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
-  EXPECT_NE(0u, cert.size());
-  EXPECT_NE(0u, proof.size());
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-  EXPECT_LT(0u, cert_sct.size());
-}
-
-TEST_P(CryptoServerTest, RejectTooLarge) {
-  // Check that the server replies with no certificate when a CHLO is
-  // constructed with a PDMD but no SKT when the REJ would be too large.
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"PDMD", "X509"},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
-  config_.set_chlo_multiplier(1);
-
-  ShouldSucceed(msg);
-  absl::string_view cert, proof, cert_sct;
-  EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
-  EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
-  EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, RejectNotTooLarge) {
-  // When the CHLO packet is large enough, ensure that a full REJ is sent.
-  chlo_packet_size_ *= 5;
-
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"PDMD", "X509"},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
-  config_.set_chlo_multiplier(1);
-
-  ShouldSucceed(msg);
-  absl::string_view cert, proof, cert_sct;
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
-  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
-  // Check that the server replies with no certificate when a CHLO is
-  // constructed with a PDMD but no SKT when the REJ would be too large.
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PDMD", "X509"},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
-  config_.set_chlo_multiplier(1);
-
-  ShouldSucceed(msg);
-  absl::string_view cert, proof, cert_sct;
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
-  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
-  EXPECT_NE(0u, cert.size());
-  EXPECT_NE(0u, proof.size());
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, BadSourceAddressToken) {
-  // Invalid source-address tokens should be ignored.
-  // clang-format off
-  static const char* const kBadSourceAddressTokens[] = {
-    "",
-    "foo",
-    "#0000",
-    "#0000000000000000000000000000000000000000",
-  };
-  // clang-format on
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSourceAddressTokens); i++) {
-    CryptoHandshakeMessage msg =
-        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                       {"STK", kBadSourceAddressTokens[i]},
-                                       {"VER\0", client_version_string_}},
-                                      kClientHelloMinimumSize);
-    ShouldSucceed(msg);
-    const HandshakeFailureReason kRejectReasons[] = {
-        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-  }
-}
-
-TEST_P(CryptoServerTest, BadClientNonce) {
-  // clang-format off
-  static const char* const kBadNonces[] = {
-    "",
-    "#0000",
-    "#0000000000000000000000000000000000000000",
-  };
-  // clang-format on
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadNonces); i++) {
-    // Invalid nonces should be ignored, in an inchoate CHLO.
-
-    CryptoHandshakeMessage msg =
-        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                       {"NONC", kBadNonces[i]},
-                                       {"VER\0", client_version_string_}},
-                                      kClientHelloMinimumSize);
-
-    ShouldSucceed(msg);
-    const HandshakeFailureReason kRejectReasons[] = {
-        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
-    // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE.
-    CryptoHandshakeMessage msg1 =
-        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                       {"AEAD", "AESG"},
-                                       {"KEXS", "C255"},
-                                       {"SCID", scid_hex_},
-                                       {"#004b5453", srct_hex_},
-                                       {"PUBS", pub_hex_},
-                                       {"NONC", kBadNonces[i]},
-                                       {"NONP", kBadNonces[i]},
-                                       {"XLCT", XlctHexString()},
-                                       {"VER\0", client_version_string_}},
-                                      kClientHelloMinimumSize);
-
-    ShouldSucceed(msg1);
-
-    CheckRejectTag();
-    const HandshakeFailureReason kRejectReasons1[] = {
-        CLIENT_NONCE_INVALID_FAILURE};
-    CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
-  }
-}
-
-TEST_P(CryptoServerTest, NoClientNonce) {
-  // No client nonces should result in INCHOATE_HELLO_FAILURE.
-
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
-  CryptoHandshakeMessage msg1 =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"XLCT", XlctHexString()},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  ShouldSucceed(msg1);
-  CheckRejectTag();
-  const HandshakeFailureReason kRejectReasons1[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
-}
-
-TEST_P(CryptoServerTest, DowngradeAttack) {
-  if (supported_versions_.size() == 1) {
-    // No downgrade attack is possible if the server only supports one version.
-    return;
-  }
-  // Set the client's preferred version to a supported version that
-  // is not the "current" version (supported_versions_.front()).
-  std::string bad_version =
-      ParsedQuicVersionToString(supported_versions_.back());
-
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"}, {"VER\0", bad_version}}, kClientHelloMinimumSize);
-
-  ShouldFailMentioning("Downgrade", msg);
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptServerConfig) {
-  // This tests corrupted server config.
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"SCID", (std::string(1, 'X') + scid_hex_)},
-       {"#004b5453", srct_hex_},
-       {"PUBS", pub_hex_},
-       {"NONC", nonce_hex_},
-       {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  CheckRejectTag();
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
-  // This tests corrupted source address token.
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"SCID", scid_hex_},
-       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
-       {"PUBS", pub_hex_},
-       {"NONC", nonce_hex_},
-       {"XLCT", XlctHexString()},
-       {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  CheckRejectTag();
-  const HandshakeFailureReason kRejectReasons[] = {
-      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) {
-  // This tests corrupted source address token.
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"SCID", scid_hex_},
-       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
-       {"PUBS", pub_hex_},
-       {"NONC", nonce_hex_},
-       {"XLCT", XlctHexString()},
-       {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  config_.set_validate_source_address_token(false);
-
-  ShouldSucceed(msg);
-  EXPECT_EQ(kSHLO, out_.tag());
-}
-
-TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
-  // This test corrupts client nonce and source address token.
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"SCID", scid_hex_},
-       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
-       {"PUBS", pub_hex_},
-       {"NONC", (std::string(1, 'X') + nonce_hex_)},
-       {"XLCT", XlctHexString()},
-       {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  CheckRejectTag();
-  const HandshakeFailureReason kRejectReasons[] = {
-      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, CorruptMultipleTags) {
-  // This test corrupts client nonce, server nonce and source address token.
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"SCID", scid_hex_},
-       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
-       {"PUBS", pub_hex_},
-       {"NONC", (std::string(1, 'X') + nonce_hex_)},
-       {"NONP", (std::string(1, 'X') + nonce_hex_)},
-       {"SNO\0", (std::string(1, 'X') + nonce_hex_)},
-       {"XLCT", XlctHexString()},
-       {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  CheckRejectTag();
-
-  const HandshakeFailureReason kRejectReasons[] = {
-      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, NoServerNonce) {
-  // When no server nonce is present and no strike register is configured,
-  // the CHLO should be rejected.
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"NONP", nonce_hex_},
-                                     {"XLCT", XlctHexString()},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-
-  // Even without a server nonce, this ClientHello should be accepted in
-  // version 33.
-  ASSERT_EQ(kSHLO, out_.tag());
-  CheckServerHello(out_);
-}
-
-TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
-  client_address_ = QuicSocketAddress(QuicIpAddress::Loopback6(), 1234);
-
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"PDMD", "X509"},
-                                     {"SCID", kOldConfigId},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"NONP", "123456789012345678901234567890"},
-                                     {"VER\0", client_version_string_},
-                                     {"XLCT", XlctHexString()}},
-                                    kClientHelloMinimumSize);
-
-  ShouldSucceed(msg);
-  // The message should be rejected because the source-address token is no
-  // longer valid.
-  CheckRejectTag();
-  const HandshakeFailureReason kRejectReasons[] = {
-      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-
-  absl::string_view cert, proof, scfg_str;
-  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
-  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
-  EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str));
-  std::unique_ptr<CryptoHandshakeMessage> scfg(
-      CryptoFramer::ParseMessage(scfg_str));
-  absl::string_view scid;
-  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
-  EXPECT_NE(scid, kOldConfigId);
-
-  // Get certs from compressed certs.
-  std::vector<std::string> cached_certs;
-
-  std::vector<std::string> certs;
-  ASSERT_TRUE(CertCompressor::DecompressChain(cert, cached_certs, &certs));
-
-  // Check that the proof in the REJ message is valid.
-  std::unique_ptr<ProofVerifier> proof_verifier(
-      crypto_test_utils::ProofVerifierForTesting());
-  std::unique_ptr<ProofVerifyContext> verify_context(
-      crypto_test_utils::ProofVerifyContextForTesting());
-  std::unique_ptr<ProofVerifyDetails> details;
-  std::string error_details;
-  std::unique_ptr<ProofVerifierCallback> callback(
-      new DummyProofVerifierCallback());
-  const std::string chlo_hash =
-      CryptoUtils::HashHandshakeMessage(msg, Perspective::IS_SERVER);
-  EXPECT_EQ(QUIC_SUCCESS,
-            proof_verifier->VerifyProof(
-                "test.example.com", 443, (std::string(scfg_str)),
-                client_version_.transport_version, chlo_hash, certs, "",
-                (std::string(proof)), verify_context.get(), &error_details,
-                &details, std::move(callback)));
-}
-
-TEST_P(CryptoServerTest, RejectInvalidXlct) {
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"VER\0", client_version_string_},
-                                     {"XLCT", "#0102030405060708"}},
-                                    kClientHelloMinimumSize);
-
-  // If replay protection isn't disabled, then
-  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
-  // and cause ProcessClientHello to exit early (and generate a REJ message).
-  config_.set_replay_protection(false);
-
-  ShouldSucceed(msg);
-
-  const HandshakeFailureReason kRejectReasons[] = {
-      INVALID_EXPECTED_LEAF_CERTIFICATE};
-
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-TEST_P(CryptoServerTest, ValidXlct) {
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"VER\0", client_version_string_},
-                                     {"XLCT", XlctHexString()}},
-                                    kClientHelloMinimumSize);
-
-  // If replay protection isn't disabled, then
-  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
-  // and cause ProcessClientHello to exit early (and generate a REJ message).
-  config_.set_replay_protection(false);
-
-  ShouldSucceed(msg);
-  EXPECT_EQ(kSHLO, out_.tag());
-}
-
-TEST_P(CryptoServerTest, NonceInSHLO) {
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"VER\0", client_version_string_},
-                                     {"XLCT", XlctHexString()}},
-                                    kClientHelloMinimumSize);
-
-  // If replay protection isn't disabled, then
-  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
-  // and cause ProcessClientHello to exit early (and generate a REJ message).
-  config_.set_replay_protection(false);
-
-  ShouldSucceed(msg);
-  EXPECT_EQ(kSHLO, out_.tag());
-
-  absl::string_view nonce;
-  EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce));
-}
-
-TEST_P(CryptoServerTest, ProofSourceFailure) {
-  // Install a ProofSource which will unconditionally fail
-  peer_.ResetProofSource(std::unique_ptr<ProofSource>(new FailingProofSource));
-
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"PDMD", "X509"},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  // Just ensure that we don't crash as occurred in b/33916924.
-  ShouldFailMentioning("", msg);
-}
-
-// Regression test for crbug.com/723604
-// For 2RTT, if the first CHLO from the client contains hashes of cached
-// certs (stored in CCRT tag) but the second CHLO does not, then the second REJ
-// from the server should not contain hashes of cached certs.
-TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) {
-  // Send inchoate CHLO to get cert chain from server. This CHLO is only for
-  // the purpose of getting the server's certs; it is not part of the 2RTT
-  // handshake.
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-  ShouldSucceed(msg);
-
-  // Decompress cert chain from server to individual certs.
-  absl::string_view certs_compressed;
-  ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
-  ASSERT_NE(0u, certs_compressed.size());
-  std::vector<std::string> certs;
-  ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
-                                              /*cached_certs=*/{}, &certs));
-
-  // Start 2-RTT. Client sends CHLO with bad source-address token and hashes of
-  // the certs, which tells the server that the client has cached those certs.
-  config_.set_chlo_multiplier(1);
-  const char kBadSourceAddressToken[] = "";
-  msg.SetStringPiece(kSourceAddressTokenTag, kBadSourceAddressToken);
-  std::vector<uint64_t> hashes(certs.size());
-  for (size_t i = 0; i < certs.size(); ++i) {
-    hashes[i] = QuicUtils::QuicUtils::FNV1a_64_Hash(certs[i]);
-  }
-  msg.SetVector(kCCRT, hashes);
-  ShouldSucceed(msg);
-
-  // Server responds with inchoate REJ containing valid source-address token.
-  absl::string_view srct;
-  ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
-
-  // Client now drops cached certs; sends CHLO with updated source-address
-  // token but no hashes of certs.
-  msg.SetStringPiece(kSourceAddressTokenTag, srct);
-  msg.Erase(kCCRT);
-  ShouldSucceed(msg);
-
-  // Server response's cert chain should not contain hashes of
-  // previously-cached certs.
-  ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
-  ASSERT_NE(0u, certs_compressed.size());
-  ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
-                                              /*cached_certs=*/{}, &certs));
-}
-
-class CryptoServerConfigGenerationTest : public QuicTest {};
-
-TEST_F(CryptoServerConfigGenerationTest, Determinism) {
-  // Test that using a deterministic PRNG causes the server-config to be
-  // deterministic.
-
-  MockRandom rand_a, rand_b;
-  const QuicCryptoServerConfig::ConfigOptions options;
-  MockClock clock;
-
-  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
-                           crypto_test_utils::ProofSourceForTesting(),
-                           KeyExchangeSource::Default());
-  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
-                           crypto_test_utils::ProofSourceForTesting(),
-                           KeyExchangeSource::Default());
-  std::unique_ptr<CryptoHandshakeMessage> scfg_a(
-      a.AddDefaultConfig(&rand_a, &clock, options));
-  std::unique_ptr<CryptoHandshakeMessage> scfg_b(
-      b.AddDefaultConfig(&rand_b, &clock, options));
-
-  ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString());
-}
-
-TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) {
-  // This test ensures that the server config ID varies for different server
-  // configs.
-
-  MockRandom rand_a, rand_b;
-  const QuicCryptoServerConfig::ConfigOptions options;
-  MockClock clock;
-
-  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
-                           crypto_test_utils::ProofSourceForTesting(),
-                           KeyExchangeSource::Default());
-  rand_b.ChangeValue();
-  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
-                           crypto_test_utils::ProofSourceForTesting(),
-                           KeyExchangeSource::Default());
-  std::unique_ptr<CryptoHandshakeMessage> scfg_a(
-      a.AddDefaultConfig(&rand_a, &clock, options));
-  std::unique_ptr<CryptoHandshakeMessage> scfg_b(
-      b.AddDefaultConfig(&rand_b, &clock, options));
-
-  absl::string_view scid_a, scid_b;
-  EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a));
-  EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b));
-
-  EXPECT_NE(scid_a, scid_b);
-}
-
-TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
-  MockRandom rand_a;
-  const QuicCryptoServerConfig::ConfigOptions options;
-  MockClock clock;
-
-  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
-                           crypto_test_utils::ProofSourceForTesting(),
-                           KeyExchangeSource::Default());
-  std::unique_ptr<CryptoHandshakeMessage> scfg(
-      a.AddDefaultConfig(&rand_a, &clock, options));
-
-  absl::string_view scid;
-  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
-  // Need to take a copy of |scid| has we're about to call |Erase|.
-  const std::string scid_str(scid);
-
-  scfg->Erase(kSCID);
-  scfg->MarkDirty();
-  const QuicData& serialized(scfg->GetSerialized());
-
-  uint8_t digest[SHA256_DIGEST_LENGTH];
-  SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
-         serialized.length(), digest);
-
-  // scid is a SHA-256 hash, truncated to 16 bytes.
-  ASSERT_EQ(scid.size(), 16u);
-  EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), scid.size()));
-}
-
-// Those tests were declared incorrectly and thus never ran in first place.
-// TODO(b/147891553): figure out if we should fix or delete those.
-#if 0
-
-class CryptoServerTestNoConfig : public CryptoServerTest {
- public:
-  void SetUp() override {
-    // Deliberately don't add a config so that we can test this situation.
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(CryptoServerTestsNoConfig,
-                         CryptoServerTestNoConfig,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(CryptoServerTestNoConfig, DontCrash) {
-  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
-      kClientHelloMinimumSize);
-
-  ShouldFailMentioning("No config", msg);
-
-  const HandshakeFailureReason kRejectReasons[] = {
-      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
-  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
-}
-
-class CryptoServerTestOldVersion : public CryptoServerTest {
- public:
-  void SetUp() override {
-    client_version_ = supported_versions_.back();
-    client_version_string_ = ParsedQuicVersionToString(client_version_);
-    CryptoServerTest::SetUp();
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(CryptoServerTestsOldVersion,
-                         CryptoServerTestOldVersion,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"VER\0", client_version_string_},
-                                     {"XLCT", "#0100000000000000"}},
-                                    kClientHelloMinimumSize);
-
-  // If replay protection isn't disabled, then
-  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
-  // and cause ProcessClientHello to exit early (and generate a REJ message).
-  config_.set_replay_protection(false);
-
-  ShouldSucceed(msg);
-  EXPECT_EQ(kSHLO, out_.tag());
-}
-
-TEST_P(CryptoServerTestOldVersion, XlctNotRequired) {
-  CryptoHandshakeMessage msg =
-      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
-                                     {"AEAD", "AESG"},
-                                     {"KEXS", "C255"},
-                                     {"SCID", scid_hex_},
-                                     {"#004b5453", srct_hex_},
-                                     {"PUBS", pub_hex_},
-                                     {"NONC", nonce_hex_},
-                                     {"VER\0", client_version_string_}},
-                                    kClientHelloMinimumSize);
-
-  // If replay protection isn't disabled, then
-  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
-  // and cause ProcessClientHello to exit early (and generate a REJ message).
-  config_.set_replay_protection(false);
-
-  ShouldSucceed(msg);
-  EXPECT_EQ(kSHLO, out_.tag());
-}
-
-#endif  // 0
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_utils.cc b/quic/core/crypto/crypto_utils.cc
deleted file mode 100644
index ad9bae9..0000000
--- a/quic/core/crypto/crypto_utils.cc
+++ /dev/null
@@ -1,790 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_utils.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bytestring.h"
-#include "third_party/boringssl/src/include/openssl/hkdf.h"
-#include "third_party/boringssl/src/include/openssl/mem.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_hkdf.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-// Implements the HKDF-Expand-Label function as defined in section 7.1 of RFC
-// 8446. The HKDF-Expand-Label function takes 4 explicit arguments (Secret,
-// Label, Context, and Length), as well as implicit PRF which is the hash
-// function negotiated by TLS. Its use in QUIC (as needed by the QUIC stack,
-// instead of as used internally by the TLS stack) is only for deriving initial
-// secrets for obfuscation, for calculating packet protection keys and IVs from
-// the corresponding packet protection secret and key update in the same quic
-// session. None of these uses need a Context (a zero-length context is
-// provided), so this argument is omitted here.
-//
-// The implicit PRF is explicitly passed into HkdfExpandLabel as |prf|; the
-// Secret, Label, and Length are passed in as |secret|, |label|, and
-// |out_len|, respectively. The resulting expanded secret is returned.
-std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
-                                     const std::vector<uint8_t>& secret,
-                                     const std::string& label, size_t out_len) {
-  bssl::ScopedCBB quic_hkdf_label;
-  CBB inner_label;
-  const char label_prefix[] = "tls13 ";
-  // 20 = size(u16) + size(u8) + len("tls13 ") +
-  //      max_len("client in", "server in", "quicv2 key", ... ) +
-  //      size(u8);
-  static const size_t max_quic_hkdf_label_length = 20;
-  if (!CBB_init(quic_hkdf_label.get(), max_quic_hkdf_label_length) ||
-      !CBB_add_u16(quic_hkdf_label.get(), out_len) ||
-      !CBB_add_u8_length_prefixed(quic_hkdf_label.get(), &inner_label) ||
-      !CBB_add_bytes(&inner_label,
-                     reinterpret_cast<const uint8_t*>(label_prefix),
-                     ABSL_ARRAYSIZE(label_prefix) - 1) ||
-      !CBB_add_bytes(&inner_label,
-                     reinterpret_cast<const uint8_t*>(label.data()),
-                     label.size()) ||
-      // Zero length |Context|.
-      !CBB_add_u8(quic_hkdf_label.get(), 0) ||
-      !CBB_flush(quic_hkdf_label.get())) {
-    QUIC_LOG(ERROR) << "Building HKDF label failed";
-    return std::vector<uint8_t>();
-  }
-  std::vector<uint8_t> out;
-  out.resize(out_len);
-  if (!HKDF_expand(out.data(), out_len, prf, secret.data(), secret.size(),
-                   CBB_data(quic_hkdf_label.get()),
-                   CBB_len(quic_hkdf_label.get()))) {
-    QUIC_LOG(ERROR) << "Running HKDF-Expand-Label failed";
-    return std::vector<uint8_t>();
-  }
-  return out;
-}
-
-}  // namespace
-
-const std::string getLabelForVersion(const ParsedQuicVersion& version,
-                                     const absl::string_view& predicate) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync with HKDF labels");
-  if (version == ParsedQuicVersion::V2Draft01()) {
-    return absl::StrCat("quicv2 ", predicate);
-  } else {
-    return absl::StrCat("quic ", predicate);
-  }
-}
-
-void CryptoUtils::InitializeCrypterSecrets(
-    const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
-    const ParsedQuicVersion& version, QuicCrypter* crypter) {
-  SetKeyAndIV(prf, pp_secret, version, crypter);
-  std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey(
-      prf, pp_secret, version, crypter->GetKeySize());
-  crypter->SetHeaderProtectionKey(
-      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
-                        header_protection_key.size()));
-}
-
-void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
-                              const std::vector<uint8_t>& pp_secret,
-                              const ParsedQuicVersion& version,
-                              QuicCrypter* crypter) {
-  std::vector<uint8_t> key =
-      HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"),
-                      crypter->GetKeySize());
-  std::vector<uint8_t> iv = HkdfExpandLabel(
-      prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize());
-  crypter->SetKey(
-      absl::string_view(reinterpret_cast<char*>(key.data()), key.size()));
-  crypter->SetIV(
-      absl::string_view(reinterpret_cast<char*>(iv.data()), iv.size()));
-}
-
-std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
-    const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
-    const ParsedQuicVersion& version, size_t out_len) {
-  return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
-                         out_len);
-}
-
-std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
-    const EVP_MD* prf, const ParsedQuicVersion& version,
-    const std::vector<uint8_t>& current_secret) {
-  return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"),
-                         current_secret.size());
-}
-
-namespace {
-
-// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
-const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
-                                       0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
-                                       0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
-const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
-                                     0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
-                                     0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
-const uint8_t kV2Draft01InitialSalt[] = {
-    0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
-    0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};
-
-// Salts used by deployed versions of QUIC. When introducing a new version,
-// generate a new salt by running `openssl rand -hex 20`.
-
-// Salt to use for initial obfuscators in version Q050.
-const uint8_t kQ050Salt[] = {0x50, 0x45, 0x74, 0xef, 0xd0, 0x66, 0xfe,
-                             0x2f, 0x9d, 0x94, 0x5c, 0xfc, 0xdb, 0xd3,
-                             0xa7, 0xf0, 0xd3, 0xb5, 0x6b, 0x45};
-// Salt to use for initial obfuscators in
-// ParsedQuicVersion::ReservedForNegotiation().
-const uint8_t kReservedForNegotiationSalt[] = {
-    0xf9, 0x64, 0xbf, 0x45, 0x3a, 0x1f, 0x1b, 0x80, 0xa5, 0xf8,
-    0x82, 0x03, 0x77, 0xd4, 0xaf, 0xca, 0x58, 0x0e, 0xe7, 0x43};
-
-const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
-                                     size_t* out_len) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync with initial encryption salts");
-  if (version == ParsedQuicVersion::V2Draft01()) {
-    *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt);
-    return kV2Draft01InitialSalt;
-  } else if (version == ParsedQuicVersion::RFCv1()) {
-    *out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt);
-    return kRFCv1InitialSalt;
-  } else if (version == ParsedQuicVersion::Draft29()) {
-    *out_len = ABSL_ARRAYSIZE(kDraft29InitialSalt);
-    return kDraft29InitialSalt;
-  } else if (version == ParsedQuicVersion::Q050()) {
-    *out_len = ABSL_ARRAYSIZE(kQ050Salt);
-    return kQ050Salt;
-  } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
-    *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
-    return kReservedForNegotiationSalt;
-  }
-  QUIC_BUG(quic_bug_10699_1)
-      << "No initial obfuscation salt for version " << version;
-  *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
-  return kReservedForNegotiationSalt;
-}
-
-const char kPreSharedKeyLabel[] = "QUIC PSK";
-
-// Retry Integrity Protection Keys and Nonces.
-// https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
-// When introducing a new Google version, generate a new key by running
-// `openssl rand -hex 16`.
-const uint8_t kDraft29RetryIntegrityKey[] = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a,
-                                             0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a,
-                                             0x6c, 0xb9, 0x6b, 0xe1};
-const uint8_t kDraft29RetryIntegrityNonce[] = {
-    0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c};
-const uint8_t kRFCv1RetryIntegrityKey[] = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66,
-                                           0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
-                                           0xe3, 0x68, 0xc8, 0x4e};
-const uint8_t kRFCv1RetryIntegrityNonce[] = {
-    0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb};
-const uint8_t kV2Draft01RetryIntegrityKey[] = {
-    0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb,
-    0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb};
-const uint8_t kV2Draft01RetryIntegrityNonce[] = {
-    0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f};
-// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation().
-const uint8_t kReservedForNegotiationRetryIntegrityKey[] = {
-    0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35,
-    0x03, 0xe6, 0x7c, 0x7b, 0xd2, 0x44, 0xca, 0xd9};
-// When introducing a new Google version, generate a new nonce by running
-// `openssl rand -hex 12`.
-// Retry integrity nonce used by ParsedQuicVersion::ReservedForNegotiation().
-const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = {
-    0x35, 0x9f, 0x16, 0xd1, 0xed, 0x80, 0x90, 0x8e, 0xec, 0x85, 0xc4, 0xd6};
-
-bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
-                                  absl::string_view* key,
-                                  absl::string_view* nonce) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync with retry integrity keys");
-  if (!version.UsesTls()) {
-    QUIC_BUG(quic_bug_10699_2)
-        << "Attempted to get retry integrity keys for invalid version "
-        << version;
-    return false;
-  } else if (version == ParsedQuicVersion::V2Draft01()) {
-    *key = absl::string_view(
-        reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey),
-        ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey));
-    *nonce = absl::string_view(
-        reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce),
-        ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce));
-    return true;
-  } else if (version == ParsedQuicVersion::RFCv1()) {
-    *key = absl::string_view(
-        reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey),
-        ABSL_ARRAYSIZE(kRFCv1RetryIntegrityKey));
-    *nonce = absl::string_view(
-        reinterpret_cast<const char*>(kRFCv1RetryIntegrityNonce),
-        ABSL_ARRAYSIZE(kRFCv1RetryIntegrityNonce));
-    return true;
-  } else if (version == ParsedQuicVersion::Draft29()) {
-    *key = absl::string_view(
-        reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
-        ABSL_ARRAYSIZE(kDraft29RetryIntegrityKey));
-    *nonce = absl::string_view(
-        reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
-        ABSL_ARRAYSIZE(kDraft29RetryIntegrityNonce));
-    return true;
-  } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
-    *key = absl::string_view(
-        reinterpret_cast<const char*>(kReservedForNegotiationRetryIntegrityKey),
-        ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityKey));
-    *nonce = absl::string_view(
-        reinterpret_cast<const char*>(
-            kReservedForNegotiationRetryIntegrityNonce),
-        ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityNonce));
-    return true;
-  }
-  QUIC_BUG(quic_bug_10699_3)
-      << "Attempted to get retry integrity keys for version " << version;
-  return false;
-}
-
-}  // namespace
-
-// static
-void CryptoUtils::CreateInitialObfuscators(Perspective perspective,
-                                           ParsedQuicVersion version,
-                                           QuicConnectionId connection_id,
-                                           CrypterPair* crypters) {
-  QUIC_DLOG(INFO) << "Creating "
-                  << (perspective == Perspective::IS_CLIENT ? "client"
-                                                            : "server")
-                  << " crypters for version " << version << " with CID "
-                  << connection_id;
-  if (!version.UsesInitialObfuscators()) {
-    crypters->encrypter = std::make_unique<NullEncrypter>(perspective);
-    crypters->decrypter = std::make_unique<NullDecrypter>(perspective);
-    return;
-  }
-  QUIC_BUG_IF(quic_bug_12871_1, !QuicUtils::IsConnectionIdValidForVersion(
-                                    connection_id, version.transport_version))
-      << "CreateTlsInitialCrypters: attempted to use connection ID "
-      << connection_id << " which is invalid with version " << version;
-  const EVP_MD* hash = EVP_sha256();
-
-  size_t salt_len;
-  const uint8_t* salt = InitialSaltForVersion(version, &salt_len);
-  std::vector<uint8_t> handshake_secret;
-  handshake_secret.resize(EVP_MAX_MD_SIZE);
-  size_t handshake_secret_len;
-  const bool hkdf_extract_success =
-      HKDF_extract(handshake_secret.data(), &handshake_secret_len, hash,
-                   reinterpret_cast<const uint8_t*>(connection_id.data()),
-                   connection_id.length(), salt, salt_len);
-  QUIC_BUG_IF(quic_bug_12871_2, !hkdf_extract_success)
-      << "HKDF_extract failed when creating initial crypters";
-  handshake_secret.resize(handshake_secret_len);
-
-  const std::string client_label = "client in";
-  const std::string server_label = "server in";
-  std::string encryption_label, decryption_label;
-  if (perspective == Perspective::IS_CLIENT) {
-    encryption_label = client_label;
-    decryption_label = server_label;
-  } else {
-    encryption_label = server_label;
-    decryption_label = client_label;
-  }
-  std::vector<uint8_t> encryption_secret = HkdfExpandLabel(
-      hash, handshake_secret, encryption_label, EVP_MD_size(hash));
-  crypters->encrypter = std::make_unique<Aes128GcmEncrypter>();
-  InitializeCrypterSecrets(hash, encryption_secret, version,
-                           crypters->encrypter.get());
-
-  std::vector<uint8_t> decryption_secret = HkdfExpandLabel(
-      hash, handshake_secret, decryption_label, EVP_MD_size(hash));
-  crypters->decrypter = std::make_unique<Aes128GcmDecrypter>();
-  InitializeCrypterSecrets(hash, decryption_secret, version,
-                           crypters->decrypter.get());
-}
-
-// static
-bool CryptoUtils::ValidateRetryIntegrityTag(
-    ParsedQuicVersion version, QuicConnectionId original_connection_id,
-    absl::string_view retry_without_tag, absl::string_view integrity_tag) {
-  unsigned char computed_integrity_tag[kRetryIntegrityTagLength];
-  if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) {
-    QUIC_BUG(quic_bug_10699_4)
-        << "Invalid retry integrity tag length " << integrity_tag.length();
-    return false;
-  }
-  char retry_pseudo_packet[kMaxIncomingPacketSize + 256];
-  QuicDataWriter writer(ABSL_ARRAYSIZE(retry_pseudo_packet),
-                        retry_pseudo_packet);
-  if (!writer.WriteLengthPrefixedConnectionId(original_connection_id)) {
-    QUIC_BUG(quic_bug_10699_5)
-        << "Failed to write original connection ID in retry pseudo packet";
-    return false;
-  }
-  if (!writer.WriteStringPiece(retry_without_tag)) {
-    QUIC_BUG(quic_bug_10699_6)
-        << "Failed to write retry without tag in retry pseudo packet";
-    return false;
-  }
-  absl::string_view key;
-  absl::string_view nonce;
-  if (!RetryIntegrityKeysForVersion(version, &key, &nonce)) {
-    // RetryIntegrityKeysForVersion already logs failures.
-    return false;
-  }
-  Aes128GcmEncrypter crypter;
-  crypter.SetKey(key);
-  absl::string_view associated_data(writer.data(), writer.length());
-  absl::string_view plaintext;  // Plaintext is empty.
-  if (!crypter.Encrypt(nonce, associated_data, plaintext,
-                       computed_integrity_tag)) {
-    QUIC_BUG(quic_bug_10699_7) << "Failed to compute retry integrity tag";
-    return false;
-  }
-  if (CRYPTO_memcmp(computed_integrity_tag, integrity_tag.data(),
-                    ABSL_ARRAYSIZE(computed_integrity_tag)) != 0) {
-    QUIC_DLOG(ERROR) << "Failed to validate retry integrity tag";
-    return false;
-  }
-  return true;
-}
-
-// static
-void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
-                                absl::string_view orbit, std::string* nonce) {
-  // a 4-byte timestamp + 28 random bytes.
-  nonce->reserve(kNonceSize);
-  nonce->resize(kNonceSize);
-
-  uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds());
-  // The time in the nonce must be encoded in big-endian because the
-  // strike-register depends on the nonces being ordered by time.
-  (*nonce)[0] = static_cast<char>(gmt_unix_time >> 24);
-  (*nonce)[1] = static_cast<char>(gmt_unix_time >> 16);
-  (*nonce)[2] = static_cast<char>(gmt_unix_time >> 8);
-  (*nonce)[3] = static_cast<char>(gmt_unix_time);
-  size_t bytes_written = 4;
-
-  if (orbit.size() == 8) {
-    memcpy(&(*nonce)[bytes_written], orbit.data(), orbit.size());
-    bytes_written += orbit.size();
-  }
-
-  random_generator->RandBytes(&(*nonce)[bytes_written],
-                              kNonceSize - bytes_written);
-}
-
-// static
-bool CryptoUtils::DeriveKeys(
-    const ParsedQuicVersion& version, absl::string_view premaster_secret,
-    QuicTag aead, absl::string_view client_nonce,
-    absl::string_view server_nonce, absl::string_view pre_shared_key,
-    const std::string& hkdf_input, Perspective perspective,
-    Diversification diversification, CrypterPair* crypters,
-    std::string* subkey_secret) {
-  // If the connection is using PSK, concatenate it with the pre-master secret.
-  std::unique_ptr<char[]> psk_premaster_secret;
-  if (!pre_shared_key.empty()) {
-    const absl::string_view label(kPreSharedKeyLabel);
-    const size_t psk_premaster_secret_size = label.size() + 1 +
-                                             pre_shared_key.size() + 8 +
-                                             premaster_secret.size() + 8;
-
-    psk_premaster_secret = std::make_unique<char[]>(psk_premaster_secret_size);
-    QuicDataWriter writer(psk_premaster_secret_size, psk_premaster_secret.get(),
-                          quiche::HOST_BYTE_ORDER);
-
-    if (!writer.WriteStringPiece(label) || !writer.WriteUInt8(0) ||
-        !writer.WriteStringPiece(pre_shared_key) ||
-        !writer.WriteUInt64(pre_shared_key.size()) ||
-        !writer.WriteStringPiece(premaster_secret) ||
-        !writer.WriteUInt64(premaster_secret.size()) ||
-        writer.remaining() != 0) {
-      return false;
-    }
-
-    premaster_secret = absl::string_view(psk_premaster_secret.get(),
-                                         psk_premaster_secret_size);
-  }
-
-  crypters->encrypter = QuicEncrypter::Create(version, aead);
-  crypters->decrypter = QuicDecrypter::Create(version, aead);
-
-  size_t key_bytes = crypters->encrypter->GetKeySize();
-  size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize();
-  if (version.UsesInitialObfuscators()) {
-    nonce_prefix_bytes = crypters->encrypter->GetIVSize();
-  }
-  size_t subkey_secret_bytes =
-      subkey_secret == nullptr ? 0 : premaster_secret.length();
-
-  absl::string_view nonce = client_nonce;
-  std::string nonce_storage;
-  if (!server_nonce.empty()) {
-    nonce_storage = std::string(client_nonce) + std::string(server_nonce);
-    nonce = nonce_storage;
-  }
-
-  QuicHKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
-                nonce_prefix_bytes, subkey_secret_bytes);
-
-  // Key derivation depends on the key diversification method being employed.
-  // both the client and the server support never doing key diversification.
-  // The server also supports immediate diversification, and the client
-  // supports pending diversification.
-  switch (diversification.mode()) {
-    case Diversification::NEVER: {
-      if (perspective == Perspective::IS_SERVER) {
-        if (!crypters->encrypter->SetKey(hkdf.server_write_key()) ||
-            !crypters->encrypter->SetNoncePrefixOrIV(version,
-                                                     hkdf.server_write_iv()) ||
-            !crypters->encrypter->SetHeaderProtectionKey(
-                hkdf.server_hp_key()) ||
-            !crypters->decrypter->SetKey(hkdf.client_write_key()) ||
-            !crypters->decrypter->SetNoncePrefixOrIV(version,
-                                                     hkdf.client_write_iv()) ||
-            !crypters->decrypter->SetHeaderProtectionKey(
-                hkdf.client_hp_key())) {
-          return false;
-        }
-      } else {
-        if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
-            !crypters->encrypter->SetNoncePrefixOrIV(version,
-                                                     hkdf.client_write_iv()) ||
-            !crypters->encrypter->SetHeaderProtectionKey(
-                hkdf.client_hp_key()) ||
-            !crypters->decrypter->SetKey(hkdf.server_write_key()) ||
-            !crypters->decrypter->SetNoncePrefixOrIV(version,
-                                                     hkdf.server_write_iv()) ||
-            !crypters->decrypter->SetHeaderProtectionKey(
-                hkdf.server_hp_key())) {
-          return false;
-        }
-      }
-      break;
-    }
-    case Diversification::PENDING: {
-      if (perspective == Perspective::IS_SERVER) {
-        QUIC_BUG(quic_bug_10699_8)
-            << "Pending diversification is only for clients.";
-        return false;
-      }
-
-      if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
-          !crypters->encrypter->SetNoncePrefixOrIV(version,
-                                                   hkdf.client_write_iv()) ||
-          !crypters->encrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
-          !crypters->decrypter->SetPreliminaryKey(hkdf.server_write_key()) ||
-          !crypters->decrypter->SetNoncePrefixOrIV(version,
-                                                   hkdf.server_write_iv()) ||
-          !crypters->decrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
-        return false;
-      }
-      break;
-    }
-    case Diversification::NOW: {
-      if (perspective == Perspective::IS_CLIENT) {
-        QUIC_BUG(quic_bug_10699_9)
-            << "Immediate diversification is only for servers.";
-        return false;
-      }
-
-      std::string key, nonce_prefix;
-      QuicDecrypter::DiversifyPreliminaryKey(
-          hkdf.server_write_key(), hkdf.server_write_iv(),
-          *diversification.nonce(), key_bytes, nonce_prefix_bytes, &key,
-          &nonce_prefix);
-      if (!crypters->decrypter->SetKey(hkdf.client_write_key()) ||
-          !crypters->decrypter->SetNoncePrefixOrIV(version,
-                                                   hkdf.client_write_iv()) ||
-          !crypters->decrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
-          !crypters->encrypter->SetKey(key) ||
-          !crypters->encrypter->SetNoncePrefixOrIV(version, nonce_prefix) ||
-          !crypters->encrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
-        return false;
-      }
-      break;
-    }
-    default:
-      QUICHE_DCHECK(false);
-  }
-
-  if (subkey_secret != nullptr) {
-    *subkey_secret = std::string(hkdf.subkey_secret());
-  }
-
-  return true;
-}
-
-// static
-uint64_t CryptoUtils::ComputeLeafCertHash(absl::string_view cert) {
-  return QuicUtils::FNV1a_64_Hash(cert);
-}
-
-QuicErrorCode CryptoUtils::ValidateServerHello(
-    const CryptoHandshakeMessage& server_hello,
-    const ParsedQuicVersionVector& negotiated_versions,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-
-  if (server_hello.tag() != kSHLO) {
-    *error_details = "Bad tag";
-    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
-  }
-
-  QuicVersionLabelVector supported_version_labels;
-  if (server_hello.GetVersionLabelList(kVER, &supported_version_labels) !=
-      QUIC_NO_ERROR) {
-    *error_details = "server hello missing version list";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  return ValidateServerHelloVersions(supported_version_labels,
-                                     negotiated_versions, error_details);
-}
-
-QuicErrorCode CryptoUtils::ValidateServerHelloVersions(
-    const QuicVersionLabelVector& server_versions,
-    const ParsedQuicVersionVector& negotiated_versions,
-    std::string* error_details) {
-  if (!negotiated_versions.empty()) {
-    bool mismatch = server_versions.size() != negotiated_versions.size();
-    for (size_t i = 0; i < server_versions.size() && !mismatch; ++i) {
-      mismatch =
-          server_versions[i] != CreateQuicVersionLabel(negotiated_versions[i]);
-    }
-    // The server sent a list of supported versions, and the connection
-    // reports that there was a version negotiation during the handshake.
-    // Ensure that these two lists are identical.
-    if (mismatch) {
-      *error_details = absl::StrCat(
-          "Downgrade attack detected: ServerVersions(", server_versions.size(),
-          ")[", QuicVersionLabelVectorToString(server_versions, ",", 30),
-          "] NegotiatedVersions(", negotiated_versions.size(), ")[",
-          ParsedQuicVersionVectorToString(negotiated_versions, ",", 30), "]");
-      return QUIC_VERSION_NEGOTIATION_MISMATCH;
-    }
-  }
-  return QUIC_NO_ERROR;
-}
-
-QuicErrorCode CryptoUtils::ValidateClientHello(
-    const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
-    const ParsedQuicVersionVector& supported_versions,
-    std::string* error_details) {
-  if (client_hello.tag() != kCHLO) {
-    *error_details = "Bad tag";
-    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
-  }
-
-  // If the client's preferred version is not the version we are currently
-  // speaking, then the client went through a version negotiation.  In this
-  // case, we need to make sure that we actually do not support this version
-  // and that it wasn't a downgrade attack.
-  QuicVersionLabel client_version_label;
-  if (client_hello.GetVersionLabel(kVER, &client_version_label) !=
-      QUIC_NO_ERROR) {
-    *error_details = "client hello missing version list";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-  return ValidateClientHelloVersion(client_version_label, version,
-                                    supported_versions, error_details);
-}
-
-QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
-    QuicVersionLabel client_version, ParsedQuicVersion connection_version,
-    const ParsedQuicVersionVector& supported_versions,
-    std::string* error_details) {
-  if (client_version != CreateQuicVersionLabel(connection_version)) {
-    // Check to see if |client_version| is actually on the supported versions
-    // list. If not, the server doesn't support that version and it's not a
-    // downgrade attack.
-    for (size_t i = 0; i < supported_versions.size(); ++i) {
-      if (client_version == CreateQuicVersionLabel(supported_versions[i])) {
-        *error_details = absl::StrCat(
-            "Downgrade attack detected: ClientVersion[",
-            QuicVersionLabelToString(client_version), "] ConnectionVersion[",
-            ParsedQuicVersionToString(connection_version),
-            "] SupportedVersions(", supported_versions.size(), ")[",
-            ParsedQuicVersionVectorToString(supported_versions, ",", 30), "]");
-        return QUIC_VERSION_NEGOTIATION_MISMATCH;
-      }
-    }
-  }
-  return QUIC_NO_ERROR;
-}
-
-// static
-bool CryptoUtils::ValidateChosenVersion(
-    const QuicVersionLabel& version_information_chosen_version,
-    const ParsedQuicVersion& session_version, std::string* error_details) {
-  if (version_information_chosen_version !=
-      CreateQuicVersionLabel(session_version)) {
-    *error_details = absl::StrCat(
-        "Detected version mismatch: version_information contained ",
-        QuicVersionLabelToString(version_information_chosen_version),
-        " instead of ", ParsedQuicVersionToString(session_version));
-    return false;
-  }
-  return true;
-}
-
-// static
-bool CryptoUtils::ValidateServerVersions(
-    const QuicVersionLabelVector& version_information_other_versions,
-    const ParsedQuicVersion& session_version,
-    const ParsedQuicVersionVector& client_original_supported_versions,
-    std::string* error_details) {
-  if (client_original_supported_versions.empty()) {
-    // We did not receive a version negotiation packet.
-    return true;
-  }
-  // Parse the server's other versions.
-  ParsedQuicVersionVector parsed_other_versions =
-      ParseQuicVersionLabelVector(version_information_other_versions);
-  // Find the first version that we originally supported that is listed in the
-  // server's other versions.
-  ParsedQuicVersion expected_version = ParsedQuicVersion::Unsupported();
-  for (const ParsedQuicVersion& client_version :
-       client_original_supported_versions) {
-    if (std::find(parsed_other_versions.begin(), parsed_other_versions.end(),
-                  client_version) != parsed_other_versions.end()) {
-      expected_version = client_version;
-      break;
-    }
-  }
-  if (expected_version != session_version) {
-    *error_details = absl::StrCat(
-        "Downgrade attack detected: used ",
-        ParsedQuicVersionToString(session_version), " but ServerVersions(",
-        version_information_other_versions.size(), ")[",
-        QuicVersionLabelVectorToString(version_information_other_versions, ",",
-                                       30),
-        "] ClientOriginalVersions(", client_original_supported_versions.size(),
-        ")[",
-        ParsedQuicVersionVectorToString(client_original_supported_versions, ",",
-                                        30),
-        "]");
-    return false;
-  }
-  return true;
-}
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x
-
-// Returns the name of the HandshakeFailureReason as a char*
-// static
-const char* CryptoUtils::HandshakeFailureReasonToString(
-    HandshakeFailureReason reason) {
-  switch (reason) {
-    RETURN_STRING_LITERAL(HANDSHAKE_OK);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_UNKNOWN_FAILURE);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_FAILURE);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_NOT_UNIQUE_FAILURE);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_ORBIT_FAILURE);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_TIME_FAILURE);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT);
-    RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_FAILURE);
-
-    RETURN_STRING_LITERAL(SERVER_NONCE_DECRYPTION_FAILURE);
-    RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_FAILURE);
-    RETURN_STRING_LITERAL(SERVER_NONCE_NOT_UNIQUE_FAILURE);
-    RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_TIME_FAILURE);
-    RETURN_STRING_LITERAL(SERVER_NONCE_REQUIRED_FAILURE);
-
-    RETURN_STRING_LITERAL(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
-    RETURN_STRING_LITERAL(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
-
-    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_INVALID_FAILURE);
-    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE);
-    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_PARSE_FAILURE);
-    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE);
-    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE);
-    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE);
-
-    RETURN_STRING_LITERAL(INVALID_EXPECTED_LEAF_CERTIFICATE);
-    RETURN_STRING_LITERAL(MAX_FAILURE_REASON);
-  }
-  // Return a default value so that we return this when |reason| doesn't match
-  // any HandshakeFailureReason.. This can happen when the message by the peer
-  // (attacker) has invalid reason.
-  return "INVALID_HANDSHAKE_FAILURE_REASON";
-}
-
-#undef RETURN_STRING_LITERAL  // undef for jumbo builds
-
-// static
-std::string CryptoUtils::EarlyDataReasonToString(
-    ssl_early_data_reason_t reason) {
-  const char* reason_string = SSL_early_data_reason_string(reason);
-  if (reason_string != nullptr) {
-    return std::string("ssl_early_data_") + reason_string;
-  }
-  QUIC_BUG_IF(quic_bug_12871_3,
-              reason < 0 || reason > ssl_early_data_reason_max_value)
-      << "Unknown ssl_early_data_reason_t " << reason;
-  return "unknown ssl_early_data_reason_t";
-}
-
-// static
-std::string CryptoUtils::HashHandshakeMessage(
-    const CryptoHandshakeMessage& message, Perspective /*perspective*/) {
-  std::string output;
-  const QuicData& serialized = message.GetSerialized();
-  uint8_t digest[SHA256_DIGEST_LENGTH];
-  SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
-         serialized.length(), digest);
-  output.assign(reinterpret_cast<const char*>(digest), sizeof(digest));
-  return output;
-}
-
-// static
-bool CryptoUtils::GetSSLCapabilities(const SSL* ssl,
-                                     bssl::UniquePtr<uint8_t>* capabilities,
-                                     size_t* capabilities_len) {
-  uint8_t* buffer;
-  CBB cbb;
-
-  if (!CBB_init(&cbb, 128) || !SSL_serialize_capabilities(ssl, &cbb) ||
-      !CBB_finish(&cbb, &buffer, capabilities_len)) {
-    return false;
-  }
-
-  *capabilities = bssl::UniquePtr<uint8_t>(buffer);
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/crypto_utils.h b/quic/core/crypto/crypto_utils.h
deleted file mode 100644
index fce6201..0000000
--- a/quic/core/crypto/crypto_utils.h
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Some helpers for quic crypto
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_crypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicRandom;
-
-class QUIC_EXPORT_PRIVATE CryptoUtils {
- public:
-  CryptoUtils() = delete;
-
-  // Diversification is a utility class that's used to act like a union type.
-  // Values can be created by calling the functions like |NoDiversification|,
-  // below.
-  class QUIC_EXPORT_PRIVATE Diversification {
-   public:
-    enum Mode {
-      NEVER,  // Key diversification will never be used. Forward secure
-              // crypters will always use this mode.
-
-      PENDING,  // Key diversification will happen when a nonce is later
-                // received. This should only be used by clients initial
-                // decrypters which are waiting on the divesification nonce
-                // from the server.
-
-      NOW,  // Key diversification will happen immediate based on the nonce.
-            // This should only be used by servers initial encrypters.
-    };
-
-    Diversification(const Diversification& diversification) = default;
-
-    static Diversification Never() { return Diversification(NEVER, nullptr); }
-    static Diversification Pending() {
-      return Diversification(PENDING, nullptr);
-    }
-    static Diversification Now(DiversificationNonce* nonce) {
-      return Diversification(NOW, nonce);
-    }
-
-    Mode mode() const { return mode_; }
-    DiversificationNonce* nonce() const {
-      QUICHE_DCHECK_EQ(mode_, NOW);
-      return nonce_;
-    }
-
-   private:
-    Diversification(Mode mode, DiversificationNonce* nonce)
-        : mode_(mode), nonce_(nonce) {}
-
-    Mode mode_;
-    DiversificationNonce* nonce_;
-  };
-
-  // InitializeCrypterSecrets derives the key and IV and header protection key
-  // from the given packet protection secret |pp_secret| and sets those fields
-  // on the given QuicCrypter |*crypter|.
-  // This follows the derivation described in section 7.3 of RFC 8446, except
-  // with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic "
-  // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as
-  // described in draft-ietf-quic-v2-01.
-  static void InitializeCrypterSecrets(const EVP_MD* prf,
-                                       const std::vector<uint8_t>& pp_secret,
-                                       const ParsedQuicVersion& version,
-                                       QuicCrypter* crypter);
-
-  // Derives the key and IV from the packet protection secret and sets those
-  // fields on the given QuicCrypter |*crypter|, but does not set the header
-  // protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be
-  // called before using |crypter|.
-  static void SetKeyAndIV(const EVP_MD* prf,
-                          const std::vector<uint8_t>& pp_secret,
-                          const ParsedQuicVersion& version,
-                          QuicCrypter* crypter);
-
-  // Derives the header protection key from the packet protection secret.
-  static std::vector<uint8_t> GenerateHeaderProtectionKey(
-      const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
-      const ParsedQuicVersion& version, size_t out_len);
-
-  // Given a secret for key phase n, return the secret for phase n+1.
-  static std::vector<uint8_t> GenerateNextKeyPhaseSecret(
-      const EVP_MD* prf, const ParsedQuicVersion& version,
-      const std::vector<uint8_t>& current_secret);
-
-  // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key
-  // (to prevent network observers that are not aware of that QUIC version from
-  // making decisions based on the TLS handshake). This packet protection secret
-  // is derived from the connection ID in the client's Initial packet.
-  //
-  // This function takes that |connection_id| and creates the encrypter and
-  // decrypter (put in |*crypters|) to use for this packet protection, as well
-  // as setting the key and IV on those crypters. For older versions of QUIC
-  // that do not use the new IETF style ENCRYPTION_INITIAL obfuscators, this
-  // function puts a NullEncrypter and NullDecrypter in |*crypters|.
-  static void CreateInitialObfuscators(Perspective perspective,
-                                       ParsedQuicVersion version,
-                                       QuicConnectionId connection_id,
-                                       CrypterPair* crypters);
-
-  // IETF QUIC Retry packets carry a retry integrity tag to detect packet
-  // corruption and make it harder for an attacker to spoof. This function
-  // checks whether a given retry packet is valid.
-  static bool ValidateRetryIntegrityTag(ParsedQuicVersion version,
-                                        QuicConnectionId original_connection_id,
-                                        absl::string_view retry_without_tag,
-                                        absl::string_view integrity_tag);
-
-  // Generates the connection nonce. The nonce is formed as:
-  //   <4 bytes> current time
-  //   <8 bytes> |orbit| (or random if |orbit| is empty)
-  //   <20 bytes> random
-  static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
-                            absl::string_view orbit, std::string* nonce);
-
-  // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and
-  // |subkey_secret| (optional -- may be null) given the contents of
-  // |premaster_secret|, |client_nonce|, |server_nonce| and |hkdf_input|. |aead|
-  // determines which cipher will be used. |perspective| controls whether the
-  // server's keys are assigned to |encrypter| or |decrypter|. |server_nonce| is
-  // optional and, if non-empty, is mixed into the key derivation.
-  // |subkey_secret| will have the same length as |premaster_secret|.
-  //
-  // If |pre_shared_key| is non-empty, it is incorporated into the key
-  // derivation parameters.  If it is empty, the key derivation is unaltered.
-  //
-  // If the mode of |diversification| is NEVER, the the crypters will be
-  // configured to never perform key diversification. If the mode is
-  // NOW (which is only for servers, then the encrypter will be keyed via a
-  // two-step process that uses the nonce from |diversification|.
-  // If the mode is PENDING (which is only for servres), then the
-  // decrypter will only be keyed to a preliminary state: a call to
-  // |SetDiversificationNonce| with a diversification nonce will be needed to
-  // complete keying.
-  static bool DeriveKeys(const ParsedQuicVersion& version,
-                         absl::string_view premaster_secret, QuicTag aead,
-                         absl::string_view client_nonce,
-                         absl::string_view server_nonce,
-                         absl::string_view pre_shared_key,
-                         const std::string& hkdf_input, Perspective perspective,
-                         Diversification diversification, CrypterPair* crypters,
-                         std::string* subkey_secret);
-
-  // Computes the FNV-1a hash of the provided DER-encoded cert for use in the
-  // XLCT tag.
-  static uint64_t ComputeLeafCertHash(absl::string_view cert);
-
-  // Validates that |server_hello| is actually an SHLO message and that it is
-  // not part of a downgrade attack.
-  //
-  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
-  // code and sets |error_details|.
-  static QuicErrorCode ValidateServerHello(
-      const CryptoHandshakeMessage& server_hello,
-      const ParsedQuicVersionVector& negotiated_versions,
-      std::string* error_details);
-
-  // Validates that the |server_versions| received do not indicate that the
-  // ServerHello is part of a downgrade attack. |negotiated_versions| must
-  // contain the list of versions received in the server's version negotiation
-  // packet (or be empty if no such packet was received).
-  //
-  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
-  // code and sets |error_details|.
-  static QuicErrorCode ValidateServerHelloVersions(
-      const QuicVersionLabelVector& server_versions,
-      const ParsedQuicVersionVector& negotiated_versions,
-      std::string* error_details);
-
-  // Validates that |client_hello| is actually a CHLO and that this is not part
-  // of a downgrade attack.
-  // This includes verifiying versions and detecting downgrade attacks.
-  //
-  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
-  // code and sets |error_details|.
-  static QuicErrorCode ValidateClientHello(
-      const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
-      const ParsedQuicVersionVector& supported_versions,
-      std::string* error_details);
-
-  // Validates that the |client_version| received does not indicate that a
-  // downgrade attack has occurred. |connection_version| is the version of the
-  // QuicConnection, and |supported_versions| is all versions that that
-  // QuicConnection supports.
-  //
-  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
-  // code and sets |error_details|.
-  static QuicErrorCode ValidateClientHelloVersion(
-      QuicVersionLabel client_version, ParsedQuicVersion connection_version,
-      const ParsedQuicVersionVector& supported_versions,
-      std::string* error_details);
-
-  // Validates that the chosen version from the version_information matches the
-  // version from the session. Returns true if they match, otherwise returns
-  // false and fills in |error_details|.
-  static bool ValidateChosenVersion(
-      const QuicVersionLabel& version_information_chosen_version,
-      const ParsedQuicVersion& session_version, std::string* error_details);
-
-  // Validates that there was no downgrade attack involving a version
-  // negotiation packet. This verifies that if the client was initially
-  // configured with |client_original_supported_versions| and it had received a
-  // version negotiation packet with |version_information_other_versions|, then
-  // it would have selected |session_version|. Returns true if they match (or if
-  // |client_original_supported_versions| is empty indicating no version
-  // negotiation packet was received), otherwise returns
-  // false and fills in |error_details|.
-  static bool ValidateServerVersions(
-      const QuicVersionLabelVector& version_information_other_versions,
-      const ParsedQuicVersion& session_version,
-      const ParsedQuicVersionVector& client_original_supported_versions,
-      std::string* error_details);
-
-  // Returns the name of the HandshakeFailureReason as a char*
-  static const char* HandshakeFailureReasonToString(
-      HandshakeFailureReason reason);
-
-  // Returns the name of an ssl_early_data_reason_t as a char*
-  static std::string EarlyDataReasonToString(ssl_early_data_reason_t reason);
-
-  // Returns a hash of the serialized |message|.
-  static std::string HashHandshakeMessage(const CryptoHandshakeMessage& message,
-                                          Perspective perspective);
-
-  // Wraps SSL_serialize_capabilities. Return nullptr if failed.
-  static bool GetSSLCapabilities(const SSL* ssl,
-                                 bssl::UniquePtr<uint8_t>* capabilities,
-                                 size_t* capabilities_len);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
diff --git a/quic/core/crypto/crypto_utils_test.cc b/quic/core/crypto/crypto_utils_test.cc
deleted file mode 100644
index f0d944b..0000000
--- a/quic/core/crypto/crypto_utils_test.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/crypto_utils.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class CryptoUtilsTest : public QuicTest {};
-
-TEST_F(CryptoUtilsTest, HandshakeFailureReasonToString) {
-  EXPECT_STREQ("HANDSHAKE_OK",
-               CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK));
-  EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_UNKNOWN_FAILURE));
-  EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_INVALID_FAILURE));
-  EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_NOT_UNIQUE_FAILURE));
-  EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_INVALID_ORBIT_FAILURE));
-  EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_INVALID_TIME_FAILURE));
-  EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT));
-  EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   CLIENT_NONCE_STRIKE_REGISTER_FAILURE));
-  EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_NONCE_DECRYPTION_FAILURE));
-  EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_NONCE_INVALID_FAILURE));
-  EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_NONCE_NOT_UNIQUE_FAILURE));
-  EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_NONCE_INVALID_TIME_FAILURE));
-  EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_NONCE_REQUIRED_FAILURE));
-  EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_CONFIG_INCHOATE_HELLO_FAILURE));
-  EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE));
-  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SOURCE_ADDRESS_TOKEN_INVALID_FAILURE));
-  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE));
-  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SOURCE_ADDRESS_TOKEN_PARSE_FAILURE));
-  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE));
-  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE));
-  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE));
-  EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE",
-               CryptoUtils::HandshakeFailureReasonToString(
-                   INVALID_EXPECTED_LEAF_CERTIFICATE));
-  EXPECT_STREQ("MAX_FAILURE_REASON",
-               CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON));
-  EXPECT_STREQ(
-      "INVALID_HANDSHAKE_FAILURE_REASON",
-      CryptoUtils::HandshakeFailureReasonToString(
-          static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1)));
-}
-
-TEST_F(CryptoUtilsTest, AuthTagLengths) {
-  for (const auto& version : AllSupportedVersions()) {
-    for (QuicTag algo : {kAESG, kCC20}) {
-      SCOPED_TRACE(version);
-      std::unique_ptr<QuicEncrypter> encrypter(
-          QuicEncrypter::Create(version, algo));
-      size_t auth_tag_size = 12;
-      if (version.UsesInitialObfuscators()) {
-        auth_tag_size = 16;
-      }
-      EXPECT_EQ(encrypter->GetCiphertextSize(0), auth_tag_size);
-    }
-  }
-}
-
-TEST_F(CryptoUtilsTest, ValidateChosenVersion) {
-  for (const ParsedQuicVersion& v1 : AllSupportedVersions()) {
-    for (const ParsedQuicVersion& v2 : AllSupportedVersions()) {
-      std::string error_details;
-      bool success = CryptoUtils::ValidateChosenVersion(
-          CreateQuicVersionLabel(v1), v2, &error_details);
-      EXPECT_EQ(success, v1 == v2);
-      EXPECT_EQ(success, error_details.empty());
-    }
-  }
-}
-
-TEST_F(CryptoUtilsTest, ValidateServerVersionsNoVersionNegotiation) {
-  QuicVersionLabelVector version_information_other_versions;
-  ParsedQuicVersionVector client_original_supported_versions;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    std::string error_details;
-    EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
-        version_information_other_versions, version,
-        client_original_supported_versions, &error_details));
-    EXPECT_TRUE(error_details.empty());
-  }
-}
-
-TEST_F(CryptoUtilsTest, ValidateServerVersionsWithVersionNegotiation) {
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    QuicVersionLabelVector version_information_other_versions{
-        CreateQuicVersionLabel(version)};
-    ParsedQuicVersionVector client_original_supported_versions{
-        ParsedQuicVersion::ReservedForNegotiation(), version};
-    std::string error_details;
-    EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
-        version_information_other_versions, version,
-        client_original_supported_versions, &error_details));
-    EXPECT_TRUE(error_details.empty());
-  }
-}
-
-TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) {
-  if (AllSupportedVersions().size() <= 1) {
-    // We are not vulnerable to downgrade if we only support one version.
-    return;
-  }
-  ParsedQuicVersion client_version = AllSupportedVersions().front();
-  ParsedQuicVersion server_version = AllSupportedVersions().back();
-  ASSERT_NE(client_version, server_version);
-  QuicVersionLabelVector version_information_other_versions{
-      CreateQuicVersionLabel(client_version)};
-  ParsedQuicVersionVector client_original_supported_versions{
-      ParsedQuicVersion::ReservedForNegotiation(), server_version};
-  std::string error_details;
-  EXPECT_FALSE(CryptoUtils::ValidateServerVersions(
-      version_information_other_versions, server_version,
-      client_original_supported_versions, &error_details));
-  EXPECT_FALSE(error_details.empty());
-}
-
-// Test that the library is using the correct labels for each version, and
-// therefore generating correct obfuscators, using the test vectors in appendix
-// A of each RFC or internet-draft.
-TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
-  // if the number of HTTP/3 QUIC versions has changed, we need to change the
-  // expected_keys hardcoded into this test. Regrettably, this is not a
-  // compile-time constant.
-  EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
-  const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
-                               0x14,
-                               static_cast<char>(0x9d),
-                               0x0b,
-                               0x16,
-                               0x62,
-                               static_cast<char>(0xab),
-                               static_cast<char>(0x87),
-                               0x1f,
-                               static_cast<char>(0xbe),
-                               0x63,
-                               static_cast<char>(0xc4),
-                               static_cast<char>(0x9b),
-                               0x5e,
-                               0x65,
-                               0x5a,
-                               0x5d};
-  const char v1_key[] = {// test vector from RFC 9001, A.1
-                         static_cast<char>(0xcf),
-                         0x3a,
-                         0x53,
-                         0x31,
-                         0x65,
-                         0x3c,
-                         0x36,
-                         0x4c,
-                         static_cast<char>(0x88),
-                         static_cast<char>(0xf0),
-                         static_cast<char>(0xf3),
-                         0x79,
-                         static_cast<char>(0xb6),
-                         0x06,
-                         0x7e,
-                         0x37};
-  const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01
-                            0x15,
-                            static_cast<char>(0xd5),
-                            static_cast<char>(0xb4),
-                            static_cast<char>(0xd9),
-                            static_cast<char>(0xa2),
-                            static_cast<char>(0xb8),
-                            static_cast<char>(0x91),
-                            0x6a,
-                            static_cast<char>(0xa3),
-                            static_cast<char>(0x9b),
-                            0x1b,
-                            static_cast<char>(0xfe),
-                            0x57,
-                            0x4d,
-                            0x2a,
-                            static_cast<char>(0xad)};
-  const char connection_id[] =  // test vector from both docs
-      {static_cast<char>(0x83),
-       static_cast<char>(0x94),
-       static_cast<char>(0xc8),
-       static_cast<char>(0xf0),
-       0x3e,
-       0x51,
-       0x57,
-       0x08};
-  const QuicConnectionId cid(connection_id, sizeof(connection_id));
-  const char* key_str;
-  size_t key_size;
-  for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
-    if (version == ParsedQuicVersion::Draft29()) {
-      key_str = draft_29_key;
-      key_size = sizeof(draft_29_key);
-    } else if (version == ParsedQuicVersion::RFCv1()) {
-      key_str = v1_key;
-      key_size = sizeof(v1_key);
-    } else {  // draft-ietf-quic-v2-01
-      key_str = v2_01_key;
-      key_size = sizeof(v2_01_key);
-    }
-    const absl::string_view expected_key{key_str, key_size};
-
-    CrypterPair crypters;
-    CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
-                                          &crypters);
-    EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/curve25519_key_exchange.cc b/quic/core/crypto/curve25519_key_exchange.cc
deleted file mode 100644
index bdf3a08..0000000
--- a/quic/core/crypto/curve25519_key_exchange.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/curve25519_key_exchange.h"
-
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/curve25519.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-Curve25519KeyExchange::Curve25519KeyExchange() {}
-
-Curve25519KeyExchange::~Curve25519KeyExchange() {}
-
-// static
-std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
-    QuicRandom* rand) {
-  std::unique_ptr<Curve25519KeyExchange> result =
-      New(Curve25519KeyExchange::NewPrivateKey(rand));
-  QUIC_BUG_IF(quic_bug_12891_1, result == nullptr);
-  return result;
-}
-
-// static
-std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
-    absl::string_view private_key) {
-  // We don't want to #include the BoringSSL headers in the public header file,
-  // so we use literals for the sizes of private_key_ and public_key_. Here we
-  // assert that those values are equal to the values from the BoringSSL
-  // header.
-  static_assert(
-      sizeof(Curve25519KeyExchange::private_key_) == X25519_PRIVATE_KEY_LEN,
-      "header out of sync");
-  static_assert(
-      sizeof(Curve25519KeyExchange::public_key_) == X25519_PUBLIC_VALUE_LEN,
-      "header out of sync");
-
-  if (private_key.size() != X25519_PRIVATE_KEY_LEN) {
-    return nullptr;
-  }
-
-  // Use absl::WrapUnique(new) instead of std::make_unique because
-  // Curve25519KeyExchange has a private constructor.
-  auto ka = absl::WrapUnique(new Curve25519KeyExchange);
-  memcpy(ka->private_key_, private_key.data(), X25519_PRIVATE_KEY_LEN);
-  X25519_public_from_private(ka->public_key_, ka->private_key_);
-  return ka;
-}
-
-// static
-std::string Curve25519KeyExchange::NewPrivateKey(QuicRandom* rand) {
-  uint8_t private_key[X25519_PRIVATE_KEY_LEN];
-  rand->RandBytes(private_key, sizeof(private_key));
-  return std::string(reinterpret_cast<char*>(private_key), sizeof(private_key));
-}
-
-bool Curve25519KeyExchange::CalculateSharedKeySync(
-    absl::string_view peer_public_value,
-    std::string* shared_key) const {
-  if (peer_public_value.size() != X25519_PUBLIC_VALUE_LEN) {
-    return false;
-  }
-
-  uint8_t result[X25519_PUBLIC_VALUE_LEN];
-  if (!X25519(result, private_key_,
-              reinterpret_cast<const uint8_t*>(peer_public_value.data()))) {
-    return false;
-  }
-
-  shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
-  return true;
-}
-
-absl::string_view Curve25519KeyExchange::public_value() const {
-  return absl::string_view(reinterpret_cast<const char*>(public_key_),
-                           sizeof(public_key_));
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/curve25519_key_exchange.h b/quic/core/crypto/curve25519_key_exchange.h
deleted file mode 100644
index b6a12b6..0000000
--- a/quic/core/crypto/curve25519_key_exchange.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// Curve25519KeyExchange implements a SynchronousKeyExchange using
-// elliptic-curve Diffie-Hellman on curve25519. See http://cr.yp.to/ecdh.html
-class QUIC_EXPORT_PRIVATE Curve25519KeyExchange
-    : public SynchronousKeyExchange {
- public:
-  ~Curve25519KeyExchange() override;
-
-  // New generates a private key and then creates new key-exchange object.
-  static std::unique_ptr<Curve25519KeyExchange> New(QuicRandom* rand);
-
-  // New creates a new key-exchange object from a private key. If |private_key|
-  // is invalid, nullptr is returned.
-  static std::unique_ptr<Curve25519KeyExchange> New(
-      absl::string_view private_key);
-
-  // NewPrivateKey returns a private key, generated from |rand|, suitable for
-  // passing to |New|.
-  static std::string NewPrivateKey(QuicRandom* rand);
-
-  // SynchronousKeyExchange interface.
-  bool CalculateSharedKeySync(absl::string_view peer_public_value,
-                              std::string* shared_key) const override;
-  absl::string_view public_value() const override;
-  QuicTag type() const override { return kC255; }
-
- private:
-  Curve25519KeyExchange();
-
-  uint8_t private_key_[32];
-  uint8_t public_key_[32];
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
diff --git a/quic/core/crypto/curve25519_key_exchange_test.cc b/quic/core/crypto/curve25519_key_exchange_test.cc
deleted file mode 100644
index 968b969..0000000
--- a/quic/core/crypto/curve25519_key_exchange_test.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/curve25519_key_exchange.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class Curve25519KeyExchangeTest : public QuicTest {
- public:
-  // Holds the result of a key exchange callback.
-  class TestCallbackResult {
-   public:
-    void set_ok(bool ok) { ok_ = ok; }
-    bool ok() { return ok_; }
-
-   private:
-    bool ok_ = false;
-  };
-
-  // Key exchange callback which sets the result into the specified
-  // TestCallbackResult.
-  class TestCallback : public AsynchronousKeyExchange::Callback {
-   public:
-    TestCallback(TestCallbackResult* result) : result_(result) {}
-    virtual ~TestCallback() = default;
-
-    void Run(bool ok) { result_->set_ok(ok); }
-
-   private:
-    TestCallbackResult* result_;
-  };
-};
-
-// SharedKey just tests that the basic key exchange identity holds: that both
-// parties end up with the same key.
-TEST_F(Curve25519KeyExchangeTest, SharedKey) {
-  QuicRandom* const rand = QuicRandom::GetInstance();
-
-  for (int i = 0; i < 5; i++) {
-    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
-    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
-
-    std::unique_ptr<Curve25519KeyExchange> alice(
-        Curve25519KeyExchange::New(alice_key));
-    std::unique_ptr<Curve25519KeyExchange> bob(
-        Curve25519KeyExchange::New(bob_key));
-
-    const absl::string_view alice_public(alice->public_value());
-    const absl::string_view bob_public(bob->public_value());
-
-    std::string alice_shared, bob_shared;
-    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
-    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
-    ASSERT_EQ(alice_shared, bob_shared);
-  }
-}
-
-// SharedKeyAsync just tests that the basic asynchronous key exchange identity
-// holds: that both parties end up with the same key.
-TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) {
-  QuicRandom* const rand = QuicRandom::GetInstance();
-
-  for (int i = 0; i < 5; i++) {
-    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
-    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
-
-    std::unique_ptr<Curve25519KeyExchange> alice(
-        Curve25519KeyExchange::New(alice_key));
-    std::unique_ptr<Curve25519KeyExchange> bob(
-        Curve25519KeyExchange::New(bob_key));
-
-    const absl::string_view alice_public(alice->public_value());
-    const absl::string_view bob_public(bob->public_value());
-
-    std::string alice_shared, bob_shared;
-    TestCallbackResult alice_result;
-    ASSERT_FALSE(alice_result.ok());
-    alice->CalculateSharedKeyAsync(
-        bob_public, &alice_shared,
-        std::make_unique<TestCallback>(&alice_result));
-    ASSERT_TRUE(alice_result.ok());
-    TestCallbackResult bob_result;
-    ASSERT_FALSE(bob_result.ok());
-    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
-                                 std::make_unique<TestCallback>(&bob_result));
-    ASSERT_TRUE(bob_result.ok());
-    ASSERT_EQ(alice_shared, bob_shared);
-    ASSERT_NE(0u, alice_shared.length());
-    ASSERT_NE(0u, bob_shared.length());
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/key_exchange.cc b/quic/core/crypto/key_exchange.cc
deleted file mode 100644
index c97d5dd..0000000
--- a/quic/core/crypto/key_exchange.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/key_exchange.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/curve25519_key_exchange.h"
-#include "quic/core/crypto/p256_key_exchange.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
-    QuicTag type,
-    absl::string_view private_key) {
-  switch (type) {
-    case kC255:
-      return Curve25519KeyExchange::New(private_key);
-    case kP256:
-      return P256KeyExchange::New(private_key);
-    default:
-      QUIC_BUG(quic_bug_10712_1)
-          << "Unknown key exchange method: " << QuicTagToString(type);
-      return nullptr;
-  }
-}
-
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
-    QuicTag type,
-    QuicRandom* rand) {
-  switch (type) {
-    case kC255:
-      return Curve25519KeyExchange::New(rand);
-    case kP256:
-      return P256KeyExchange::New();
-    default:
-      QUIC_BUG(quic_bug_10712_2)
-          << "Unknown key exchange method: " << QuicTagToString(type);
-      return nullptr;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/key_exchange.h b/quic/core/crypto/key_exchange.h
deleted file mode 100644
index 0937caa..0000000
--- a/quic/core/crypto/key_exchange.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// Interface for a Diffie-Hellman key exchange with an asynchronous interface.
-// This allows for implementations which hold the private key locally, as well
-// as ones which make an RPC to an external key-exchange service.
-class QUIC_EXPORT_PRIVATE AsynchronousKeyExchange {
- public:
-  virtual ~AsynchronousKeyExchange() = default;
-
-  // Callback base class for receiving the results of an async call to
-  // CalculateSharedKeys.
-  class QUIC_EXPORT_PRIVATE Callback {
-   public:
-    Callback() = default;
-    virtual ~Callback() = default;
-
-    // Invoked upon completion of CalculateSharedKeysAsync.
-    //
-    // |ok| indicates whether the operation completed successfully.  If false,
-    // then the value pointed to by |shared_key| passed in to
-    // CalculateSharedKeyAsync is undefined.
-    virtual void Run(bool ok) = 0;
-
-   private:
-    Callback(const Callback&) = delete;
-    Callback& operator=(const Callback&) = delete;
-  };
-
-  // CalculateSharedKey computes the shared key between a private key which is
-  // conceptually owned by this object (though it may not be physically located
-  // in this process) and a public value from the peer.  Callers should expect
-  // that |callback| might be invoked synchronously.  Results will be written
-  // into |*shared_key|.
-  virtual void CalculateSharedKeyAsync(
-      absl::string_view peer_public_value,
-      std::string* shared_key,
-      std::unique_ptr<Callback> callback) const = 0;
-
-  // Tag indicating the key-exchange algorithm this object will use.
-  virtual QuicTag type() const = 0;
-};
-
-// Interface for a Diffie-Hellman key exchange with both synchronous and
-// asynchronous interfaces.  Only implementations which hold the private key
-// locally should implement this interface.
-class QUIC_EXPORT_PRIVATE SynchronousKeyExchange
-    : public AsynchronousKeyExchange {
- public:
-  virtual ~SynchronousKeyExchange() = default;
-
-  // AyncKeyExchange API.  Note that this method is marked 'final.'  Subclasses
-  // should implement CalculateSharedKeySync only.
-  void CalculateSharedKeyAsync(absl::string_view peer_public_value,
-                               std::string* shared_key,
-                               std::unique_ptr<Callback> callback) const final {
-    const bool ok = CalculateSharedKeySync(peer_public_value, shared_key);
-    callback->Run(ok);
-  }
-
-  // CalculateSharedKey computes the shared key between a local private key and
-  // a public value from the peer.  Results will be written into |*shared_key|.
-  virtual bool CalculateSharedKeySync(absl::string_view peer_public_value,
-                                      std::string* shared_key) const = 0;
-
-  // public_value returns the local public key which can be sent to a peer in
-  // order to complete a key exchange. The returned absl::string_view is
-  // a reference to a member of this object and is only valid for as long as it
-  // exists.
-  virtual absl::string_view public_value() const = 0;
-};
-
-// Create a SynchronousKeyExchange object which will use a keypair generated
-// from |private_key|, and a key-exchange algorithm specified by |type|, which
-// must be one of {kC255, kC256}.  Returns nullptr if |private_key| or |type| is
-// invalid.
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
-    QuicTag type,
-    absl::string_view private_key);
-
-// Create a SynchronousKeyExchange object which will use a keypair generated
-// from |rand|, and a key-exchange algorithm specified by |type|, which must be
-// one of {kC255, kC256}.  Returns nullptr if |type| is invalid.
-std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
-    QuicTag type,
-    QuicRandom* rand);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
diff --git a/quic/core/crypto/null_decrypter.cc b/quic/core/crypto/null_decrypter.cc
deleted file mode 100644
index fd611bd..0000000
--- a/quic/core/crypto/null_decrypter.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_decrypter.h"
-
-#include <cstdint>
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-NullDecrypter::NullDecrypter(Perspective perspective)
-    : perspective_(perspective) {}
-
-bool NullDecrypter::SetKey(absl::string_view key) {
-  return key.empty();
-}
-
-bool NullDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
-  return nonce_prefix.empty();
-}
-
-bool NullDecrypter::SetIV(absl::string_view iv) {
-  return iv.empty();
-}
-
-bool NullDecrypter::SetHeaderProtectionKey(absl::string_view key) {
-  return key.empty();
-}
-
-bool NullDecrypter::SetPreliminaryKey(absl::string_view /*key*/) {
-  QUIC_BUG(quic_bug_10652_1) << "Should not be called";
-  return false;
-}
-
-bool NullDecrypter::SetDiversificationNonce(
-    const DiversificationNonce& /*nonce*/) {
-  QUIC_BUG(quic_bug_10652_2) << "Should not be called";
-  return true;
-}
-
-bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/,
-                                  absl::string_view associated_data,
-                                  absl::string_view ciphertext,
-                                  char* output,
-                                  size_t* output_length,
-                                  size_t max_output_length) {
-  QuicDataReader reader(ciphertext.data(), ciphertext.length(),
-                        quiche::HOST_BYTE_ORDER);
-  absl::uint128 hash;
-
-  if (!ReadHash(&reader, &hash)) {
-    return false;
-  }
-
-  absl::string_view plaintext = reader.ReadRemainingPayload();
-  if (plaintext.length() > max_output_length) {
-    QUIC_BUG(quic_bug_10652_3)
-        << "Output buffer must be larger than the plaintext.";
-    return false;
-  }
-  if (hash != ComputeHash(associated_data, plaintext)) {
-    return false;
-  }
-  // Copy the plaintext to output.
-  memcpy(output, plaintext.data(), plaintext.length());
-  *output_length = plaintext.length();
-  return true;
-}
-
-std::string NullDecrypter::GenerateHeaderProtectionMask(
-    QuicDataReader* /*sample_reader*/) {
-  return std::string(5, 0);
-}
-
-size_t NullDecrypter::GetKeySize() const {
-  return 0;
-}
-
-size_t NullDecrypter::GetNoncePrefixSize() const {
-  return 0;
-}
-
-size_t NullDecrypter::GetIVSize() const {
-  return 0;
-}
-
-absl::string_view NullDecrypter::GetKey() const {
-  return absl::string_view();
-}
-
-absl::string_view NullDecrypter::GetNoncePrefix() const {
-  return absl::string_view();
-}
-
-uint32_t NullDecrypter::cipher_id() const {
-  return 0;
-}
-
-QuicPacketCount NullDecrypter::GetIntegrityLimit() const {
-  return std::numeric_limits<QuicPacketCount>::max();
-}
-
-bool NullDecrypter::ReadHash(QuicDataReader* reader, absl::uint128* hash) {
-  uint64_t lo;
-  uint32_t hi;
-  if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
-    return false;
-  }
-  *hash = absl::MakeUint128(hi, lo);
-  return true;
-}
-
-absl::uint128 NullDecrypter::ComputeHash(const absl::string_view data1,
-                                         const absl::string_view data2) const {
-  absl::uint128 correct_hash;
-  if (perspective_ == Perspective::IS_CLIENT) {
-    // Peer is a server.
-    correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Server");
-  } else {
-    // Peer is a client.
-    correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Client");
-  }
-  absl::uint128 mask = absl::MakeUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
-  mask <<= 96;
-  correct_hash &= ~mask;
-  return correct_hash;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/null_decrypter.h b/quic/core/crypto/null_decrypter.h
deleted file mode 100644
index b36fa82..0000000
--- a/quic/core/crypto/null_decrypter.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicDataReader;
-
-// A NullDecrypter is a QuicDecrypter used before a crypto negotiation
-// has occurred.  It does not actually decrypt the payload, but does
-// verify a hash (fnv128) over both the payload and associated data.
-class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
- public:
-  explicit NullDecrypter(Perspective perspective);
-  NullDecrypter(const NullDecrypter&) = delete;
-  NullDecrypter& operator=(const NullDecrypter&) = delete;
-  ~NullDecrypter() override {}
-
-  // QuicDecrypter implementation
-  bool SetKey(absl::string_view key) override;
-  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
-  bool SetIV(absl::string_view iv) override;
-  bool SetHeaderProtectionKey(absl::string_view key) override;
-  bool SetPreliminaryKey(absl::string_view key) override;
-  bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
-  bool DecryptPacket(uint64_t packet_number,
-                     absl::string_view associated_data,
-                     absl::string_view ciphertext,
-                     char* output,
-                     size_t* output_length,
-                     size_t max_output_length) override;
-  std::string GenerateHeaderProtectionMask(
-      QuicDataReader* sample_reader) override;
-  size_t GetKeySize() const override;
-  size_t GetNoncePrefixSize() const override;
-  size_t GetIVSize() const override;
-  absl::string_view GetKey() const override;
-  absl::string_view GetNoncePrefix() const override;
-
-  uint32_t cipher_id() const override;
-  QuicPacketCount GetIntegrityLimit() const override;
-
- private:
-  bool ReadHash(QuicDataReader* reader, absl::uint128* hash);
-  absl::uint128 ComputeHash(absl::string_view data1,
-                            absl::string_view data2) const;
-
-  Perspective perspective_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
diff --git a/quic/core/crypto/null_decrypter_test.cc b/quic/core/crypto/null_decrypter_test.cc
deleted file mode 100644
index 394fcfb..0000000
--- a/quic/core/crypto/null_decrypter_test.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_decrypter.h"
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class NullDecrypterTest : public QuicTestWithParam<bool> {};
-
-TEST_F(NullDecrypterTest, DecryptClient) {
-  unsigned char expected[] = {
-      // fnv hash
-      0x97,
-      0xdc,
-      0x27,
-      0x2f,
-      0x18,
-      0xa8,
-      0x56,
-      0x73,
-      0xdf,
-      0x8d,
-      0x1d,
-      0xd0,
-      // payload
-      'g',
-      'o',
-      'o',
-      'd',
-      'b',
-      'y',
-      'e',
-      '!',
-  };
-  const char* data = reinterpret_cast<const char*>(expected);
-  size_t len = ABSL_ARRAYSIZE(expected);
-  NullDecrypter decrypter(Perspective::IS_SERVER);
-  char buffer[256];
-  size_t length = 0;
-  ASSERT_TRUE(decrypter.DecryptPacket(
-      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
-  EXPECT_LT(0u, length);
-  EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
-}
-
-TEST_F(NullDecrypterTest, DecryptServer) {
-  unsigned char expected[] = {
-      // fnv hash
-      0x63,
-      0x5e,
-      0x08,
-      0x03,
-      0x32,
-      0x80,
-      0x8f,
-      0x73,
-      0xdf,
-      0x8d,
-      0x1d,
-      0x1a,
-      // payload
-      'g',
-      'o',
-      'o',
-      'd',
-      'b',
-      'y',
-      'e',
-      '!',
-  };
-  const char* data = reinterpret_cast<const char*>(expected);
-  size_t len = ABSL_ARRAYSIZE(expected);
-  NullDecrypter decrypter(Perspective::IS_CLIENT);
-  char buffer[256];
-  size_t length = 0;
-  ASSERT_TRUE(decrypter.DecryptPacket(
-      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
-  EXPECT_LT(0u, length);
-  EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
-}
-
-TEST_F(NullDecrypterTest, BadHash) {
-  unsigned char expected[] = {
-      // fnv hash
-      0x46,
-      0x11,
-      0xea,
-      0x5f,
-      0xcf,
-      0x1d,
-      0x66,
-      0x5b,
-      0xba,
-      0xf0,
-      0xbc,
-      0xfd,
-      // payload
-      'g',
-      'o',
-      'o',
-      'd',
-      'b',
-      'y',
-      'e',
-      '!',
-  };
-  const char* data = reinterpret_cast<const char*>(expected);
-  size_t len = ABSL_ARRAYSIZE(expected);
-  NullDecrypter decrypter(Perspective::IS_CLIENT);
-  char buffer[256];
-  size_t length = 0;
-  ASSERT_FALSE(decrypter.DecryptPacket(
-      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
-}
-
-TEST_F(NullDecrypterTest, ShortInput) {
-  unsigned char expected[] = {
-      // fnv hash (truncated)
-      0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc,
-  };
-  const char* data = reinterpret_cast<const char*>(expected);
-  size_t len = ABSL_ARRAYSIZE(expected);
-  NullDecrypter decrypter(Perspective::IS_CLIENT);
-  char buffer[256];
-  size_t length = 0;
-  ASSERT_FALSE(decrypter.DecryptPacket(
-      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/null_encrypter.cc b/quic/core/crypto/null_encrypter.cc
deleted file mode 100644
index a385321..0000000
--- a/quic/core/crypto/null_encrypter.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_encrypter.h"
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-const size_t kHashSizeShort = 12;  // size of uint128 serialized short
-
-NullEncrypter::NullEncrypter(Perspective perspective)
-    : perspective_(perspective) {}
-
-bool NullEncrypter::SetKey(absl::string_view key) {
-  return key.empty();
-}
-
-bool NullEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
-  return nonce_prefix.empty();
-}
-
-bool NullEncrypter::SetIV(absl::string_view iv) {
-  return iv.empty();
-}
-
-bool NullEncrypter::SetHeaderProtectionKey(absl::string_view key) {
-  return key.empty();
-}
-
-bool NullEncrypter::EncryptPacket(uint64_t /*packet_number*/,
-                                  absl::string_view associated_data,
-                                  absl::string_view plaintext,
-                                  char* output,
-                                  size_t* output_length,
-                                  size_t max_output_length) {
-  const size_t len = plaintext.size() + GetHashLength();
-  if (max_output_length < len) {
-    return false;
-  }
-  absl::uint128 hash;
-  if (perspective_ == Perspective::IS_SERVER) {
-    hash =
-        QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Server");
-  } else {
-    hash =
-        QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Client");
-  }
-  // TODO(ianswett): memmove required for in place encryption.  Placing the
-  // hash at the end would allow use of memcpy, doing nothing for in place.
-  memmove(output + GetHashLength(), plaintext.data(), plaintext.length());
-  QuicUtils::SerializeUint128Short(hash,
-                                   reinterpret_cast<unsigned char*>(output));
-  *output_length = len;
-  return true;
-}
-
-std::string NullEncrypter::GenerateHeaderProtectionMask(
-    absl::string_view /*sample*/) {
-  return std::string(5, 0);
-}
-
-size_t NullEncrypter::GetKeySize() const {
-  return 0;
-}
-
-size_t NullEncrypter::GetNoncePrefixSize() const {
-  return 0;
-}
-
-size_t NullEncrypter::GetIVSize() const {
-  return 0;
-}
-
-size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
-  return ciphertext_size - std::min(ciphertext_size, GetHashLength());
-}
-
-size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const {
-  return plaintext_size + GetHashLength();
-}
-
-QuicPacketCount NullEncrypter::GetConfidentialityLimit() const {
-  return std::numeric_limits<QuicPacketCount>::max();
-}
-
-absl::string_view NullEncrypter::GetKey() const {
-  return absl::string_view();
-}
-
-absl::string_view NullEncrypter::GetNoncePrefix() const {
-  return absl::string_view();
-}
-
-size_t NullEncrypter::GetHashLength() const {
-  return kHashSizeShort;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/null_encrypter.h b/quic/core/crypto/null_encrypter.h
deleted file mode 100644
index 9df1906..0000000
--- a/quic/core/crypto/null_encrypter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
-
-#include <cstddef>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A NullEncrypter is a QuicEncrypter used before a crypto negotiation
-// has occurred.  It does not actually encrypt the payload, but does
-// generate a MAC (fnv128) over both the payload and associated data.
-class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
- public:
-  explicit NullEncrypter(Perspective perspective);
-  NullEncrypter(const NullEncrypter&) = delete;
-  NullEncrypter& operator=(const NullEncrypter&) = delete;
-  ~NullEncrypter() override {}
-
-  // QuicEncrypter implementation
-  bool SetKey(absl::string_view key) override;
-  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
-  bool SetIV(absl::string_view iv) override;
-  bool SetHeaderProtectionKey(absl::string_view key) override;
-  bool EncryptPacket(uint64_t packet_number,
-                     absl::string_view associated_data,
-                     absl::string_view plaintext,
-                     char* output,
-                     size_t* output_length,
-                     size_t max_output_length) override;
-  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
-  size_t GetKeySize() const override;
-  size_t GetNoncePrefixSize() const override;
-  size_t GetIVSize() const override;
-  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
-  size_t GetCiphertextSize(size_t plaintext_size) const override;
-  QuicPacketCount GetConfidentialityLimit() const override;
-  absl::string_view GetKey() const override;
-  absl::string_view GetNoncePrefix() const override;
-
- private:
-  size_t GetHashLength() const;
-
-  Perspective perspective_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
diff --git a/quic/core/crypto/null_encrypter_test.cc b/quic/core/crypto/null_encrypter_test.cc
deleted file mode 100644
index 6924f8a..0000000
--- a/quic/core/crypto/null_encrypter_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class NullEncrypterTest : public QuicTestWithParam<bool> {};
-
-TEST_F(NullEncrypterTest, EncryptClient) {
-  unsigned char expected[] = {
-      // fnv hash
-      0x97,
-      0xdc,
-      0x27,
-      0x2f,
-      0x18,
-      0xa8,
-      0x56,
-      0x73,
-      0xdf,
-      0x8d,
-      0x1d,
-      0xd0,
-      // payload
-      'g',
-      'o',
-      'o',
-      'd',
-      'b',
-      'y',
-      'e',
-      '!',
-  };
-  char encrypted[256];
-  size_t encrypted_len = 0;
-  NullEncrypter encrypter(Perspective::IS_CLIENT);
-  ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
-                                      &encrypted_len, 256));
-  quiche::test::CompareCharArraysWithHexError(
-      "encrypted data", encrypted, encrypted_len,
-      reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
-}
-
-TEST_F(NullEncrypterTest, EncryptServer) {
-  unsigned char expected[] = {
-      // fnv hash
-      0x63,
-      0x5e,
-      0x08,
-      0x03,
-      0x32,
-      0x80,
-      0x8f,
-      0x73,
-      0xdf,
-      0x8d,
-      0x1d,
-      0x1a,
-      // payload
-      'g',
-      'o',
-      'o',
-      'd',
-      'b',
-      'y',
-      'e',
-      '!',
-  };
-  char encrypted[256];
-  size_t encrypted_len = 0;
-  NullEncrypter encrypter(Perspective::IS_SERVER);
-  ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
-                                      &encrypted_len, 256));
-  quiche::test::CompareCharArraysWithHexError(
-      "encrypted data", encrypted, encrypted_len,
-      reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
-}
-
-TEST_F(NullEncrypterTest, GetMaxPlaintextSize) {
-  NullEncrypter encrypter(Perspective::IS_CLIENT);
-  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
-  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
-  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
-  EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
-}
-
-TEST_F(NullEncrypterTest, GetCiphertextSize) {
-  NullEncrypter encrypter(Perspective::IS_CLIENT);
-  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
-  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
-  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/p256_key_exchange.cc b/quic/core/crypto/p256_key_exchange.cc
deleted file mode 100644
index 2a13c2e..0000000
--- a/quic/core/crypto/p256_key_exchange.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/p256_key_exchange.h"
-
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ecdh.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-P256KeyExchange::P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
-                                 const uint8_t* public_key)
-    : private_key_(std::move(private_key)) {
-  memcpy(public_key_, public_key, sizeof(public_key_));
-}
-
-P256KeyExchange::~P256KeyExchange() {}
-
-// static
-std::unique_ptr<P256KeyExchange> P256KeyExchange::New() {
-  return New(P256KeyExchange::NewPrivateKey());
-}
-
-// static
-std::unique_ptr<P256KeyExchange> P256KeyExchange::New(absl::string_view key) {
-  if (key.empty()) {
-    QUIC_DLOG(INFO) << "Private key is empty";
-    return nullptr;
-  }
-
-  const uint8_t* keyp = reinterpret_cast<const uint8_t*>(key.data());
-  bssl::UniquePtr<EC_KEY> private_key(
-      d2i_ECPrivateKey(nullptr, &keyp, key.size()));
-  if (!private_key.get() || !EC_KEY_check_key(private_key.get())) {
-    QUIC_DLOG(INFO) << "Private key is invalid.";
-    return nullptr;
-  }
-
-  uint8_t public_key[kUncompressedP256PointBytes];
-  if (EC_POINT_point2oct(EC_KEY_get0_group(private_key.get()),
-                         EC_KEY_get0_public_key(private_key.get()),
-                         POINT_CONVERSION_UNCOMPRESSED, public_key,
-                         sizeof(public_key), nullptr) != sizeof(public_key)) {
-    QUIC_DLOG(INFO) << "Can't get public key.";
-    return nullptr;
-  }
-
-  return absl::WrapUnique(
-      new P256KeyExchange(std::move(private_key), public_key));
-}
-
-// static
-std::string P256KeyExchange::NewPrivateKey() {
-  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
-  if (!key.get() || !EC_KEY_generate_key(key.get())) {
-    QUIC_DLOG(INFO) << "Can't generate a new private key.";
-    return std::string();
-  }
-
-  int key_len = i2d_ECPrivateKey(key.get(), nullptr);
-  if (key_len <= 0) {
-    QUIC_DLOG(INFO) << "Can't convert private key to string";
-    return std::string();
-  }
-  std::unique_ptr<uint8_t[]> private_key(new uint8_t[key_len]);
-  uint8_t* keyp = private_key.get();
-  if (!i2d_ECPrivateKey(key.get(), &keyp)) {
-    QUIC_DLOG(INFO) << "Can't convert private key to string.";
-    return std::string();
-  }
-  return std::string(reinterpret_cast<char*>(private_key.get()), key_len);
-}
-
-bool P256KeyExchange::CalculateSharedKeySync(
-    absl::string_view peer_public_value,
-    std::string* shared_key) const {
-  if (peer_public_value.size() != kUncompressedP256PointBytes) {
-    QUIC_DLOG(INFO) << "Peer public value is invalid";
-    return false;
-  }
-
-  bssl::UniquePtr<EC_POINT> point(
-      EC_POINT_new(EC_KEY_get0_group(private_key_.get())));
-  if (!point.get() ||
-      !EC_POINT_oct2point(/* also test if point is on curve */
-                          EC_KEY_get0_group(private_key_.get()), point.get(),
-                          reinterpret_cast<const uint8_t*>(
-                              peer_public_value.data()),
-                          peer_public_value.size(), nullptr)) {
-    QUIC_DLOG(INFO) << "Can't convert peer public value to curve point.";
-    return false;
-  }
-
-  uint8_t result[kP256FieldBytes];
-  if (ECDH_compute_key(result, sizeof(result), point.get(), private_key_.get(),
-                       nullptr) != sizeof(result)) {
-    QUIC_DLOG(INFO) << "Can't compute ECDH shared key.";
-    return false;
-  }
-
-  shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
-  return true;
-}
-
-absl::string_view P256KeyExchange::public_value() const {
-  return absl::string_view(reinterpret_cast<const char*>(public_key_),
-                           sizeof(public_key_));
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/p256_key_exchange.h b/quic/core/crypto/p256_key_exchange.h
deleted file mode 100644
index 7c21255..0000000
--- a/quic/core/crypto/p256_key_exchange.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// P256KeyExchange implements a SynchronousKeyExchange using elliptic-curve
-// Diffie-Hellman on NIST P-256.
-class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange {
- public:
-  ~P256KeyExchange() override;
-
-  // New generates a private key and then creates new key-exchange object.
-  static std::unique_ptr<P256KeyExchange> New();
-
-  // New creates a new key-exchange object from a private key. If |private_key|
-  // is invalid, nullptr is returned.
-  static std::unique_ptr<P256KeyExchange> New(absl::string_view private_key);
-
-  // NewPrivateKey returns a private key, suitable for passing to |New|.
-  // If |NewPrivateKey| can't generate a private key, it returns an empty
-  // string.
-  static std::string NewPrivateKey();
-
-  // SynchronousKeyExchange interface.
-  bool CalculateSharedKeySync(absl::string_view peer_public_value,
-                              std::string* shared_key) const override;
-  absl::string_view public_value() const override;
-  QuicTag type() const override { return kP256; }
-
- private:
-  enum {
-    // A P-256 field element consists of 32 bytes.
-    kP256FieldBytes = 32,
-    // A P-256 point in uncompressed form consists of 0x04 (to denote
-    // that the point is uncompressed) followed by two, 32-byte field
-    // elements.
-    kUncompressedP256PointBytes = 1 + 2 * kP256FieldBytes,
-    // The first byte in an uncompressed P-256 point.
-    kUncompressedECPointForm = 0x04,
-  };
-
-  // P256KeyExchange wraps |private_key|, and expects |public_key| consists of
-  // |kUncompressedP256PointBytes| bytes.
-  P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
-                  const uint8_t* public_key);
-  P256KeyExchange(const P256KeyExchange&) = delete;
-  P256KeyExchange& operator=(const P256KeyExchange&) = delete;
-
-  bssl::UniquePtr<EC_KEY> private_key_;
-  // The public key stored as an uncompressed P-256 point.
-  uint8_t public_key_[kUncompressedP256PointBytes];
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
diff --git a/quic/core/crypto/p256_key_exchange_test.cc b/quic/core/crypto/p256_key_exchange_test.cc
deleted file mode 100644
index 4d18356..0000000
--- a/quic/core/crypto/p256_key_exchange_test.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/p256_key_exchange.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class P256KeyExchangeTest : public QuicTest {
- public:
-  // Holds the result of a key exchange callback.
-  class TestCallbackResult {
-   public:
-    void set_ok(bool ok) { ok_ = ok; }
-    bool ok() { return ok_; }
-
-   private:
-    bool ok_ = false;
-  };
-
-  // Key exchange callback which sets the result into the specified
-  // TestCallbackResult.
-  class TestCallback : public AsynchronousKeyExchange::Callback {
-   public:
-    TestCallback(TestCallbackResult* result) : result_(result) {}
-    virtual ~TestCallback() = default;
-
-    void Run(bool ok) { result_->set_ok(ok); }
-
-   private:
-    TestCallbackResult* result_;
-  };
-};
-
-// SharedKeyAsync just tests that the basic asynchronous key exchange identity
-// holds: that both parties end up with the same key.
-TEST_F(P256KeyExchangeTest, SharedKey) {
-  for (int i = 0; i < 5; i++) {
-    std::string alice_private(P256KeyExchange::NewPrivateKey());
-    std::string bob_private(P256KeyExchange::NewPrivateKey());
-
-    ASSERT_FALSE(alice_private.empty());
-    ASSERT_FALSE(bob_private.empty());
-    ASSERT_NE(alice_private, bob_private);
-
-    std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
-    std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
-
-    ASSERT_TRUE(alice != nullptr);
-    ASSERT_TRUE(bob != nullptr);
-
-    const absl::string_view alice_public(alice->public_value());
-    const absl::string_view bob_public(bob->public_value());
-
-    std::string alice_shared, bob_shared;
-    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
-    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
-    ASSERT_EQ(alice_shared, bob_shared);
-  }
-}
-
-// SharedKey just tests that the basic key exchange identity holds: that both
-// parties end up with the same key.
-TEST_F(P256KeyExchangeTest, AsyncSharedKey) {
-  for (int i = 0; i < 5; i++) {
-    std::string alice_private(P256KeyExchange::NewPrivateKey());
-    std::string bob_private(P256KeyExchange::NewPrivateKey());
-
-    ASSERT_FALSE(alice_private.empty());
-    ASSERT_FALSE(bob_private.empty());
-    ASSERT_NE(alice_private, bob_private);
-
-    std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
-    std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
-
-    ASSERT_TRUE(alice != nullptr);
-    ASSERT_TRUE(bob != nullptr);
-
-    const absl::string_view alice_public(alice->public_value());
-    const absl::string_view bob_public(bob->public_value());
-
-    std::string alice_shared, bob_shared;
-    TestCallbackResult alice_result;
-    ASSERT_FALSE(alice_result.ok());
-    alice->CalculateSharedKeyAsync(
-        bob_public, &alice_shared,
-        std::make_unique<TestCallback>(&alice_result));
-    ASSERT_TRUE(alice_result.ok());
-    TestCallbackResult bob_result;
-    ASSERT_FALSE(bob_result.ok());
-    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
-                                 std::make_unique<TestCallback>(&bob_result));
-    ASSERT_TRUE(bob_result.ok());
-    ASSERT_EQ(alice_shared, bob_shared);
-    ASSERT_NE(0u, alice_shared.length());
-    ASSERT_NE(0u, bob_shared.length());
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/proof_source.cc b/quic/core/crypto/proof_source.cc
deleted file mode 100644
index 1f25a3c..0000000
--- a/quic/core/crypto/proof_source.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/proof_source.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-CryptoBuffers::~CryptoBuffers() {
-  for (size_t i = 0; i < value.size(); i++) {
-    CRYPTO_BUFFER_free(value[i]);
-  }
-}
-
-ProofSource::Chain::Chain(const std::vector<std::string>& certs)
-    : certs(certs) {}
-
-ProofSource::Chain::~Chain() {}
-
-CryptoBuffers ProofSource::Chain::ToCryptoBuffers() const {
-  CryptoBuffers crypto_buffers;
-  crypto_buffers.value.reserve(certs.size());
-  for (size_t i = 0; i < certs.size(); i++) {
-    crypto_buffers.value.push_back(
-        CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(certs[i].data()),
-                          certs[i].length(), nullptr));
-  }
-  return crypto_buffers;
-}
-
-bool ValidateCertAndKey(
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const CertificatePrivateKey& key) {
-  if (chain.get() == nullptr || chain->certs.empty()) {
-    QUIC_BUG(quic_proof_source_empty_chain) << "Certificate chain is empty";
-    return false;
-  }
-
-  std::unique_ptr<CertificateView> leaf =
-      CertificateView::ParseSingleCertificate(chain->certs[0]);
-  if (leaf == nullptr) {
-    QUIC_BUG(quic_proof_source_unparsable_leaf_cert)
-        << "Unabled to parse leaf certificate";
-    return false;
-  }
-
-  if (!key.MatchesPublicKey(*leaf)) {
-    QUIC_BUG(quic_proof_source_key_mismatch)
-        << "Private key does not match the leaf certificate";
-    return false;
-  }
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/proof_source.h b/quic/core/crypto/proof_source.h
deleted file mode 100644
index 8a57df6..0000000
--- a/quic/core/crypto/proof_source.h
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/quic_crypto_proof.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_reference_counted.h"
-
-namespace quic {
-
-namespace test {
-class FakeProofSourceHandle;
-}  // namespace test
-
-// CryptoBuffers is a RAII class to own a std::vector<CRYPTO_BUFFER*> and the
-// buffers the elements point to.
-struct QUIC_EXPORT_PRIVATE CryptoBuffers {
-  CryptoBuffers() = default;
-  CryptoBuffers(const CryptoBuffers&) = delete;
-  CryptoBuffers(CryptoBuffers&&) = default;
-  ~CryptoBuffers();
-
-  std::vector<CRYPTO_BUFFER*> value;
-};
-
-// ProofSource is an interface by which a QUIC server can obtain certificate
-// chains and signatures that prove its identity.
-class QUIC_EXPORT_PRIVATE ProofSource {
- public:
-  // Chain is a reference-counted wrapper for a vector of stringified
-  // certificates.
-  struct QUIC_EXPORT_PRIVATE Chain : public quiche::QuicheReferenceCounted {
-    explicit Chain(const std::vector<std::string>& certs);
-    Chain(const Chain&) = delete;
-    Chain& operator=(const Chain&) = delete;
-
-    CryptoBuffers ToCryptoBuffers() const;
-
-    const std::vector<std::string> certs;
-
-   protected:
-    ~Chain() override;
-  };
-
-  // Details is an abstract class which acts as a container for any
-  // implementation-specific details that a ProofSource wants to return.
-  class QUIC_EXPORT_PRIVATE Details {
-   public:
-    virtual ~Details() {}
-  };
-
-  // Callback base class for receiving the results of an async call to GetProof.
-  class QUIC_EXPORT_PRIVATE Callback {
-   public:
-    Callback() {}
-    virtual ~Callback() {}
-
-    // Invoked upon completion of GetProof.
-    //
-    // |ok| indicates whether the operation completed successfully.  If false,
-    // the values of the remaining three arguments are undefined.
-    //
-    // |chain| is a reference-counted pointer to an object representing the
-    // certificate chain.
-    //
-    // |signature| contains the signature of the server config.
-    //
-    // |leaf_cert_sct| holds the signed timestamp (RFC6962) of the leaf cert.
-    //
-    // |details| holds a pointer to an object representing the statistics, if
-    // any, gathered during the operation of GetProof.  If no stats are
-    // available, this will be nullptr.
-    virtual void Run(bool ok,
-                     const quiche::QuicheReferenceCountedPointer<Chain>& chain,
-                     const QuicCryptoProof& proof,
-                     std::unique_ptr<Details> details) = 0;
-
-   private:
-    Callback(const Callback&) = delete;
-    Callback& operator=(const Callback&) = delete;
-  };
-
-  // Base class for signalling the completion of a call to ComputeTlsSignature.
-  class QUIC_EXPORT_PRIVATE SignatureCallback {
-   public:
-    SignatureCallback() {}
-    virtual ~SignatureCallback() = default;
-
-    // Invoked upon completion of ComputeTlsSignature.
-    //
-    // |ok| indicates whether the operation completed successfully.
-    //
-    // |signature| contains the signature of the data provided to
-    // ComputeTlsSignature. Its value is undefined if |ok| is false.
-    //
-    // |details| holds a pointer to an object representing the statistics, if
-    // any, gathered during the operation of ComputeTlsSignature.  If no stats
-    // are available, this will be nullptr.
-    virtual void Run(bool ok,
-                     std::string signature,
-                     std::unique_ptr<Details> details) = 0;
-
-   private:
-    SignatureCallback(const SignatureCallback&) = delete;
-    SignatureCallback& operator=(const SignatureCallback&) = delete;
-  };
-
-  virtual ~ProofSource() {}
-
-  // GetProof finds a certificate chain for |hostname| (in leaf-first order),
-  // and calculates a signature of |server_config| using that chain.
-  //
-  // The signature uses SHA-256 as the hash function and PSS padding when the
-  // key is RSA.
-  //
-  // The signature uses SHA-256 as the hash function when the key is ECDSA.
-  // The signature may use an ECDSA key.
-  //
-  // The signature depends on |chlo_hash| which means that the signature can not
-  // be cached.
-  //
-  // |hostname| may be empty to signify that a default certificate should be
-  // used.
-  //
-  // This function may be called concurrently.
-  //
-  // Callers should expect that |callback| might be invoked synchronously.
-  virtual void GetProof(const QuicSocketAddress& server_address,
-                        const QuicSocketAddress& client_address,
-                        const std::string& hostname,
-                        const std::string& server_config,
-                        QuicTransportVersion transport_version,
-                        absl::string_view chlo_hash,
-                        std::unique_ptr<Callback> callback) = 0;
-
-  // Returns the certificate chain for |hostname| in leaf-first order.
-  //
-  // Sets *cert_matched_sni to true if the certificate matched the given
-  // hostname, false if a default cert not matching the hostname was used.
-  virtual quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, const std::string& hostname,
-      bool* cert_matched_sni) = 0;
-
-  // Computes a signature using the private key of the certificate for
-  // |hostname|. The value in |in| is signed using the algorithm specified by
-  // |signature_algorithm|, which is an |SSL_SIGN_*| value (as defined in TLS
-  // 1.3). Implementations can only assume that |in| is valid during the call to
-  // ComputeTlsSignature - an implementation computing signatures asynchronously
-  // must copy it if the value to be signed is used outside of this function.
-  //
-  // Callers should expect that |callback| might be invoked synchronously.
-  virtual void ComputeTlsSignature(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      const std::string& hostname,
-      uint16_t signature_algorithm,
-      absl::string_view in,
-      std::unique_ptr<SignatureCallback> callback) = 0;
-
-  // Return the list of TLS signature algorithms that is acceptable by the
-  // ComputeTlsSignature method. If the entire BoringSSL's default list of
-  // supported signature algorithms are acceptable, return an empty list.
-  //
-  // If returns a non-empty list, ComputeTlsSignature will only be called with a
-  // algorithm in the list.
-  virtual absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
-      const = 0;
-
-  class QUIC_EXPORT_PRIVATE DecryptCallback {
-   public:
-    DecryptCallback() = default;
-    virtual ~DecryptCallback() = default;
-
-    virtual void Run(std::vector<uint8_t> plaintext) = 0;
-
-   private:
-    DecryptCallback(const Callback&) = delete;
-    DecryptCallback& operator=(const Callback&) = delete;
-  };
-
-  // TicketCrypter is an interface for managing encryption and decryption of TLS
-  // session tickets. A TicketCrypter gets used as an
-  // SSL_CTX_set_ticket_aead_method in BoringSSL, which has a synchronous
-  // Encrypt/Seal operation and a potentially asynchronous Decrypt/Open
-  // operation. This interface allows for ticket decryptions to be performed on
-  // a remote service.
-  class QUIC_EXPORT_PRIVATE TicketCrypter {
-   public:
-    TicketCrypter() = default;
-    virtual ~TicketCrypter() = default;
-
-    // MaxOverhead returns the maximum number of bytes of overhead that may get
-    // added when encrypting the ticket.
-    virtual size_t MaxOverhead() = 0;
-
-    // Encrypt takes a serialized TLS session ticket in |in|, encrypts it, and
-    // returns the encrypted ticket. The resulting value must not be larger than
-    // MaxOverhead bytes larger than |in|. If encryption fails, this method
-    // returns an empty vector.
-    //
-    // If |encryption_key| is nonempty, this method should use it for minting
-    // TLS resumption tickets.  If it is empty, this method may use an
-    // internally cached encryption key, if available.
-    virtual std::vector<uint8_t> Encrypt(absl::string_view in,
-                                         absl::string_view encryption_key) = 0;
-
-    // Decrypt takes an encrypted ticket |in|, decrypts it, and calls
-    // |callback->Run| with the decrypted ticket, which must not be larger than
-    // |in|. If decryption fails, the callback is invoked with an empty
-    // vector.
-    virtual void Decrypt(absl::string_view in,
-                         std::unique_ptr<DecryptCallback> callback) = 0;
-  };
-
-  // Returns the TicketCrypter used for encrypting and decrypting TLS
-  // session tickets, or nullptr if that functionality is not supported. The
-  // TicketCrypter returned (if not nullptr) must be valid for the lifetime of
-  // the ProofSource, and the caller does not take ownership of said
-  // TicketCrypter.
-  virtual TicketCrypter* GetTicketCrypter() = 0;
-};
-
-// ProofSourceHandleCallback is an interface that contains the callbacks when
-// the operations in ProofSourceHandle completes.
-// TODO(wub): Consider deprecating ProofSource by moving all functionalities of
-// ProofSource into ProofSourceHandle.
-class QUIC_EXPORT_PRIVATE ProofSourceHandleCallback {
- public:
-  virtual ~ProofSourceHandleCallback() = default;
-
-  // Called when a ProofSourceHandle::SelectCertificate operation completes.
-  // |ok| indicates whether the operation was successful.
-  // |is_sync| indicates whether the operation completed synchronously, i.e.
-  //      whether it is completed before ProofSourceHandle::SelectCertificate
-  //      returned.
-  // |chain| the certificate chain in leaf-first order.
-  // |handshake_hints| (optional) handshake hints that can be used by
-  //      SSL_set_handshake_hints.
-  // |ticket_encryption_key| (optional) encryption key to be used for minting
-  //      TLS resumption tickets.
-  // |cert_matched_sni| is true if the certificate matched the SNI hostname,
-  //      false if a non-matching default cert was used.
-  // |delayed_ssl_config| contains SSL configs to be applied on the SSL object.
-  //
-  // When called asynchronously(is_sync=false), this method will be responsible
-  // to continue the handshake from where it left off.
-  virtual void OnSelectCertificateDone(
-      bool ok, bool is_sync, const ProofSource::Chain* chain,
-      absl::string_view handshake_hints,
-      absl::string_view ticket_encryption_key, bool cert_matched_sni,
-      QuicDelayedSSLConfig delayed_ssl_config) = 0;
-
-  // Called when a ProofSourceHandle::ComputeSignature operation completes.
-  virtual void OnComputeSignatureDone(
-      bool ok,
-      bool is_sync,
-      std::string signature,
-      std::unique_ptr<ProofSource::Details> details) = 0;
-
-  // Return true iff ProofSourceHandle::ComputeSignature won't be called later.
-  // The handle can use this function to release resources promptly.
-  virtual bool WillNotCallComputeSignature() const = 0;
-};
-
-// ProofSourceHandle is an interface by which a TlsServerHandshaker can obtain
-// certificate chains and signatures that prove its identity.
-// The operations this interface supports are similar to those in ProofSource,
-// the main difference is that ProofSourceHandle is per-handshaker, so
-// an implementation can have states that are shared by multiple calls on the
-// same handle.
-//
-// A handle object is owned by a TlsServerHandshaker. Since there might be an
-// async operation pending when the handle destructs, an implementation must
-// ensure when such operations finish, their corresponding callback method won't
-// be invoked.
-//
-// A handle will have at most one async operation pending at a time.
-class QUIC_EXPORT_PRIVATE ProofSourceHandle {
- public:
-  virtual ~ProofSourceHandle() = default;
-
-  // Close the handle. Cancel the pending operation, if any.
-  // Once called, any completion method on |callback()| won't be invoked, and
-  // future SelectCertificate and ComputeSignature calls should return failure.
-  virtual void CloseHandle() = 0;
-
-  // Starts a select certificate operation. If the operation is not cancelled
-  // when it completes, callback()->OnSelectCertificateDone will be invoked.
-  //
-  // server_address and client_address should be normalized by the caller before
-  // sending down to this function.
-  //
-  // If the operation is handled synchronously:
-  // - QUIC_SUCCESS or QUIC_FAILURE will be returned.
-  // - callback()->OnSelectCertificateDone should be invoked before the function
-  //   returns.
-  //
-  // If the operation is handled asynchronously:
-  // - QUIC_PENDING will be returned.
-  // - When the operation is done, callback()->OnSelectCertificateDone should be
-  //   invoked.
-  virtual QuicAsyncStatus SelectCertificate(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      absl::string_view ssl_capabilities,
-      const std::string& hostname,
-      absl::string_view client_hello,
-      const std::string& alpn,
-      absl::optional<std::string> alps,
-      const std::vector<uint8_t>& quic_transport_params,
-      const absl::optional<std::vector<uint8_t>>& early_data_context,
-      const QuicSSLConfig& ssl_config) = 0;
-
-  // Starts a compute signature operation. If the operation is not cancelled
-  // when it completes, callback()->OnComputeSignatureDone will be invoked.
-  //
-  // See the comments of SelectCertificate for sync vs. async operations.
-  virtual QuicAsyncStatus ComputeSignature(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      const std::string& hostname,
-      uint16_t signature_algorithm,
-      absl::string_view in,
-      size_t max_signature_size) = 0;
-
- protected:
-  // Returns the object that will be notified when an operation completes.
-  virtual ProofSourceHandleCallback* callback() = 0;
-
- private:
-  friend class test::FakeProofSourceHandle;
-};
-
-// Returns true if |chain| contains a parsable DER-encoded X.509 leaf cert and
-// it matches with |key|.
-QUIC_EXPORT_PRIVATE bool ValidateCertAndKey(
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const CertificatePrivateKey& key);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
diff --git a/quic/core/crypto/proof_source_x509.cc b/quic/core/crypto/proof_source_x509.cc
deleted file mode 100644
index ec9b85e..0000000
--- a/quic/core/crypto/proof_source_x509.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/proof_source_x509.h"
-
-#include <memory>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-std::unique_ptr<ProofSourceX509> ProofSourceX509::Create(
-    quiche::QuicheReferenceCountedPointer<Chain> default_chain,
-    CertificatePrivateKey default_key) {
-  std::unique_ptr<ProofSourceX509> result(new ProofSourceX509());
-  if (!result->AddCertificateChain(default_chain, std::move(default_key))) {
-    return nullptr;
-  }
-  result->default_certificate_ = &result->certificates_.front();
-  return result;
-}
-
-void ProofSourceX509::GetProof(
-    const QuicSocketAddress& /*server_address*/,
-    const QuicSocketAddress& /*client_address*/,
-    const std::string& hostname,
-    const std::string& server_config,
-    QuicTransportVersion /*transport_version*/,
-    absl::string_view chlo_hash,
-    std::unique_ptr<ProofSource::Callback> callback) {
-  QuicCryptoProof proof;
-
-  size_t payload_size = sizeof(kProofSignatureLabel) + sizeof(uint32_t) +
-                        chlo_hash.size() + server_config.size();
-  auto payload = std::make_unique<char[]>(payload_size);
-  QuicDataWriter payload_writer(payload_size, payload.get(),
-                                quiche::Endianness::HOST_BYTE_ORDER);
-  bool success = payload_writer.WriteBytes(kProofSignatureLabel,
-                                           sizeof(kProofSignatureLabel)) &&
-                 payload_writer.WriteUInt32(chlo_hash.size()) &&
-                 payload_writer.WriteStringPiece(chlo_hash) &&
-                 payload_writer.WriteStringPiece(server_config);
-  if (!success) {
-    callback->Run(/*ok=*/false, nullptr, proof, nullptr);
-    return;
-  }
-
-  Certificate* certificate = GetCertificate(hostname, &proof.cert_matched_sni);
-  proof.signature =
-      certificate->key.Sign(absl::string_view(payload.get(), payload_size),
-                            SSL_SIGN_RSA_PSS_RSAE_SHA256);
-  callback->Run(/*ok=*/!proof.signature.empty(), certificate->chain, proof,
-                nullptr);
-}
-
-quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
-ProofSourceX509::GetCertChain(const QuicSocketAddress& /*server_address*/,
-                              const QuicSocketAddress& /*client_address*/,
-                              const std::string& hostname,
-                              bool* cert_matched_sni) {
-  return GetCertificate(hostname, cert_matched_sni)->chain;
-}
-
-void ProofSourceX509::ComputeTlsSignature(
-    const QuicSocketAddress& /*server_address*/,
-    const QuicSocketAddress& /*client_address*/,
-    const std::string& hostname,
-    uint16_t signature_algorithm,
-    absl::string_view in,
-    std::unique_ptr<ProofSource::SignatureCallback> callback) {
-  bool cert_matched_sni;
-  std::string signature = GetCertificate(hostname, &cert_matched_sni)
-                              ->key.Sign(in, signature_algorithm);
-  callback->Run(/*ok=*/!signature.empty(), signature, nullptr);
-}
-
-absl::InlinedVector<uint16_t, 8>
-ProofSourceX509::SupportedTlsSignatureAlgorithms() const {
-  // Let ComputeTlsSignature() report an error if a bad signature algorithm is
-  // requested.
-  return {};
-}
-
-ProofSource::TicketCrypter* ProofSourceX509::GetTicketCrypter() {
-  return nullptr;
-}
-
-bool ProofSourceX509::AddCertificateChain(
-    quiche::QuicheReferenceCountedPointer<Chain> chain,
-    CertificatePrivateKey key) {
-  if (chain->certs.empty()) {
-    QUIC_BUG(quic_bug_10644_1) << "Empty certificate chain supplied.";
-    return false;
-  }
-
-  std::unique_ptr<CertificateView> leaf =
-      CertificateView::ParseSingleCertificate(chain->certs[0]);
-  if (leaf == nullptr) {
-    QUIC_BUG(quic_bug_10644_2)
-        << "Unable to parse X.509 leaf certificate in the supplied chain.";
-    return false;
-  }
-  if (!key.MatchesPublicKey(*leaf)) {
-    QUIC_BUG(quic_bug_10644_3)
-        << "Private key does not match the leaf certificate.";
-    return false;
-  }
-
-  certificates_.push_front(Certificate{
-      chain,
-      std::move(key),
-  });
-  Certificate* certificate = &certificates_.front();
-
-  for (absl::string_view host : leaf->subject_alt_name_domains()) {
-    certificate_map_[std::string(host)] = certificate;
-  }
-  return true;
-}
-
-ProofSourceX509::Certificate* ProofSourceX509::GetCertificate(
-    const std::string& hostname, bool* cert_matched_sni) const {
-  auto it = certificate_map_.find(hostname);
-  if (it != certificate_map_.end()) {
-    *cert_matched_sni = true;
-    return it->second;
-  }
-  auto dot_pos = hostname.find('.');
-  if (dot_pos != std::string::npos) {
-    std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
-    it = certificate_map_.find(wildcard);
-    if (it != certificate_map_.end()) {
-      *cert_matched_sni = true;
-      return it->second;
-    }
-  }
-  *cert_matched_sni = false;
-  return default_certificate_;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/proof_source_x509.h b/quic/core/crypto/proof_source_x509.h
deleted file mode 100644
index 8c42f24..0000000
--- a/quic/core/crypto/proof_source_x509.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
-#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
-
-#include <forward_list>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/container/node_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-// ProofSourceX509 accepts X.509 certificates with private keys and picks a
-// certificate internally based on its SubjectAltName value.
-class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
- public:
-  // Creates a proof source that uses |default_chain| when no SubjectAltName
-  // value matches.  Returns nullptr if |default_chain| is invalid.
-  static std::unique_ptr<ProofSourceX509> Create(
-      quiche::QuicheReferenceCountedPointer<Chain> default_chain,
-      CertificatePrivateKey default_key);
-
-  // ProofSource implementation.
-  void GetProof(const QuicSocketAddress& server_address,
-                const QuicSocketAddress& client_address,
-                const std::string& hostname,
-                const std::string& server_config,
-                QuicTransportVersion transport_version,
-                absl::string_view chlo_hash,
-                std::unique_ptr<Callback> callback) override;
-  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, const std::string& hostname,
-      bool* cert_matched_sni) override;
-  void ComputeTlsSignature(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, const std::string& hostname,
-      uint16_t signature_algorithm, absl::string_view in,
-      std::unique_ptr<SignatureCallback> callback) override;
-  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
-      const override;
-  TicketCrypter* GetTicketCrypter() override;
-
-  // Adds a certificate chain to the verifier.  Returns false if the chain is
-  // not valid.  Newer certificates will override older certificates with the
-  // same SubjectAltName value.
-  ABSL_MUST_USE_RESULT bool AddCertificateChain(
-      quiche::QuicheReferenceCountedPointer<Chain> chain,
-      CertificatePrivateKey key);
-
- private:
-  ProofSourceX509() = default;
-
-  struct QUIC_EXPORT_PRIVATE Certificate {
-    quiche::QuicheReferenceCountedPointer<Chain> chain;
-    CertificatePrivateKey key;
-  };
-
-  // Looks up certficiate for hostname, returns the default if no certificate is
-  // found.
-  Certificate* GetCertificate(const std::string& hostname,
-                              bool* cert_matched_sni) const;
-
-  std::forward_list<Certificate> certificates_;
-  Certificate* default_certificate_;
-  absl::node_hash_map<std::string, Certificate*> certificate_map_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
diff --git a/quic/core/crypto/proof_source_x509_test.cc b/quic/core/crypto/proof_source_x509_test.cc
deleted file mode 100644
index 1eac3fd..0000000
--- a/quic/core/crypto/proof_source_x509_test.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/proof_source_x509.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/test_certificates.h"
-#include "common/platform/api/quiche_reference_counted.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-quiche::QuicheReferenceCountedPointer<ProofSource::Chain> MakeChain(
-    absl::string_view cert) {
-  return quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
-      new ProofSource::Chain(std::vector<std::string>{std::string(cert)}));
-}
-
-class ProofSourceX509Test : public QuicTest {
- public:
-  ProofSourceX509Test()
-      : test_chain_(MakeChain(kTestCertificate)),
-        wildcard_chain_(MakeChain(kWildcardCertificate)),
-        test_key_(
-            CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey)),
-        wildcard_key_(CertificatePrivateKey::LoadFromDer(
-            kWildcardCertificatePrivateKey)) {
-    QUICHE_CHECK(test_key_ != nullptr);
-    QUICHE_CHECK(wildcard_key_ != nullptr);
-  }
-
- protected:
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> test_chain_,
-      wildcard_chain_;
-  std::unique_ptr<CertificatePrivateKey> test_key_, wildcard_key_;
-};
-
-TEST_F(ProofSourceX509Test, AddCertificates) {
-  std::unique_ptr<ProofSourceX509> proof_source =
-      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
-  ASSERT_TRUE(proof_source != nullptr);
-  EXPECT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
-                                                std::move(*wildcard_key_)));
-}
-
-TEST_F(ProofSourceX509Test, AddCertificateKeyMismatch) {
-  std::unique_ptr<ProofSourceX509> proof_source =
-      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
-  ASSERT_TRUE(proof_source != nullptr);
-  test_key_ = CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
-  EXPECT_QUIC_BUG((void)proof_source->AddCertificateChain(
-                      wildcard_chain_, std::move(*test_key_)),
-                  "Private key does not match");
-}
-
-TEST_F(ProofSourceX509Test, CertificateSelection) {
-  std::unique_ptr<ProofSourceX509> proof_source =
-      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
-  ASSERT_TRUE(proof_source != nullptr);
-  ASSERT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
-                                                std::move(*wildcard_key_)));
-
-  // Default certificate.
-  bool cert_matched_sni;
-  EXPECT_EQ(proof_source
-                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
-                               "unknown.test", &cert_matched_sni)
-                ->certs[0],
-            kTestCertificate);
-  EXPECT_FALSE(cert_matched_sni);
-  // mail.example.org is explicitly a SubjectAltName in kTestCertificate.
-  EXPECT_EQ(proof_source
-                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
-                               "mail.example.org", &cert_matched_sni)
-                ->certs[0],
-            kTestCertificate);
-  EXPECT_TRUE(cert_matched_sni);
-  // www.foo.test is in kWildcardCertificate.
-  EXPECT_EQ(proof_source
-                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
-                               "www.foo.test", &cert_matched_sni)
-                ->certs[0],
-            kWildcardCertificate);
-  EXPECT_TRUE(cert_matched_sni);
-  // *.wildcard.test is in kWildcardCertificate.
-  EXPECT_EQ(proof_source
-                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
-                               "www.wildcard.test", &cert_matched_sni)
-                ->certs[0],
-            kWildcardCertificate);
-  EXPECT_TRUE(cert_matched_sni);
-  EXPECT_EQ(proof_source
-                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
-                               "etc.wildcard.test", &cert_matched_sni)
-                ->certs[0],
-            kWildcardCertificate);
-  EXPECT_TRUE(cert_matched_sni);
-  // wildcard.test itself is not in kWildcardCertificate.
-  EXPECT_EQ(proof_source
-                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
-                               "wildcard.test", &cert_matched_sni)
-                ->certs[0],
-            kTestCertificate);
-  EXPECT_FALSE(cert_matched_sni);
-}
-
-TEST_F(ProofSourceX509Test, TlsSignature) {
-  class Callback : public ProofSource::SignatureCallback {
-   public:
-    void Run(bool ok,
-             std::string signature,
-             std::unique_ptr<ProofSource::Details> /*details*/) override {
-      ASSERT_TRUE(ok);
-      std::unique_ptr<CertificateView> view =
-          CertificateView::ParseSingleCertificate(kTestCertificate);
-      EXPECT_TRUE(view->VerifySignature("Test data", signature,
-                                        SSL_SIGN_RSA_PSS_RSAE_SHA256));
-    }
-  };
-
-  std::unique_ptr<ProofSourceX509> proof_source =
-      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
-  ASSERT_TRUE(proof_source != nullptr);
-
-  proof_source->ComputeTlsSignature(QuicSocketAddress(), QuicSocketAddress(),
-                                    "example.com", SSL_SIGN_RSA_PSS_RSAE_SHA256,
-                                    "Test data", std::make_unique<Callback>());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/proof_verifier.h b/quic/core/crypto/proof_verifier.h
deleted file mode 100644
index a487fa5..0000000
--- a/quic/core/crypto/proof_verifier.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// ProofVerifyDetails is an abstract class that acts as a container for any
-// implementation specific details that a ProofVerifier wishes to return. These
-// details are saved in the CachedState for the origin in question.
-class QUIC_EXPORT_PRIVATE ProofVerifyDetails {
- public:
-  virtual ~ProofVerifyDetails() {}
-
-  // Returns an new ProofVerifyDetails object with the same contents
-  // as this one.
-  virtual ProofVerifyDetails* Clone() const = 0;
-};
-
-// ProofVerifyContext is an abstract class that acts as a container for any
-// implementation specific context that a ProofVerifier needs.
-class QUIC_EXPORT_PRIVATE ProofVerifyContext {
- public:
-  virtual ~ProofVerifyContext() {}
-};
-
-// ProofVerifierCallback provides a generic mechanism for a ProofVerifier to
-// call back after an asynchronous verification.
-class QUIC_EXPORT_PRIVATE ProofVerifierCallback {
- public:
-  virtual ~ProofVerifierCallback() {}
-
-  // Run is called on the original thread to mark the completion of an
-  // asynchonous verification. If |ok| is true then the certificate is valid
-  // and |error_details| is unused. Otherwise, |error_details| contains a
-  // description of the error. |details| contains implementation-specific
-  // details of the verification. |Run| may take ownership of |details| by
-  // calling |release| on it.
-  virtual void Run(bool ok,
-                   const std::string& error_details,
-                   std::unique_ptr<ProofVerifyDetails>* details) = 0;
-};
-
-// A ProofVerifier checks the signature on a server config, and the certificate
-// chain that backs the public key.
-class QUIC_EXPORT_PRIVATE ProofVerifier {
- public:
-  virtual ~ProofVerifier() {}
-
-  // VerifyProof checks that |signature| is a valid signature of
-  // |server_config| by the public key in the leaf certificate of |certs|, and
-  // that |certs| is a valid chain for |hostname|. On success, it returns
-  // QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and sets |*error_details|
-  // to a description of the problem. In either case it may set |*details|,
-  // which the caller takes ownership of.
-  //
-  // |context| specifies an implementation specific struct (which may be nullptr
-  // for some implementations) that provides useful information for the
-  // verifier, e.g. logging handles.
-  //
-  // This function may also return QUIC_PENDING, in which case the ProofVerifier
-  // will call back, on the original thread, via |callback| when complete.
-  //
-  // The signature uses SHA-256 as the hash function and PSS padding in the
-  // case of RSA.
-  virtual QuicAsyncStatus VerifyProof(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::string& server_config,
-      QuicTransportVersion transport_version,
-      absl::string_view chlo_hash,
-      const std::vector<std::string>& certs,
-      const std::string& cert_sct,
-      const std::string& signature,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      std::unique_ptr<ProofVerifierCallback> callback) = 0;
-
-  // VerifyCertChain checks that |certs| is a valid chain for |hostname|. On
-  // success, it returns QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and
-  // sets |*error_details| to a description of the problem. In either case it
-  // may set |*details|, which the caller takes ownership of.
-  //
-  // |context| specifies an implementation specific struct (which may be nullptr
-  // for some implementations) that provides useful information for the
-  // verifier, e.g. logging handles.
-  //
-  // If certificate verification fails, a TLS alert will be sent when closing
-  // the connection. This alert defaults to certificate_unknown. By setting
-  // |*out_alert|, a different alert can be sent to provide a more specific
-  // reason why verification failed.
-  //
-  // This function may also return QUIC_PENDING, in which case the ProofVerifier
-  // will call back, on the original thread, via |callback| when complete.
-  // In this case, the ProofVerifier will take ownership of |callback|.
-  virtual QuicAsyncStatus VerifyCertChain(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::vector<std::string>& certs,
-      const std::string& ocsp_response,
-      const std::string& cert_sct,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) = 0;
-
-  // Returns a ProofVerifyContext instance which can be use for subsequent
-  // verifications. Applications may chose create a different context and
-  // supply it for verifications instead.
-  virtual std::unique_ptr<ProofVerifyContext> CreateDefaultContext() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
diff --git a/quic/core/crypto/quic_client_session_cache.cc b/quic/core/crypto/quic_client_session_cache.cc
deleted file mode 100644
index 24b5588..0000000
--- a/quic/core/crypto/quic_client_session_cache.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_client_session_cache.h"
-
-#include "quic/core/quic_clock.h"
-
-namespace quic {
-
-namespace {
-
-const size_t kDefaultMaxEntries = 1024;
-// Returns false if the SSL |session| doesn't exist or it is expired at |now|.
-bool IsValid(SSL_SESSION* session, uint64_t now) {
-  if (!session) return false;
-
-  // now_u64 may be slightly behind because of differences in how
-  // time is calculated at this layer versus BoringSSL.
-  // Add a second of wiggle room to account for this.
-  return !(now + 1 < SSL_SESSION_get_time(session) ||
-           now >= SSL_SESSION_get_time(session) +
-                      SSL_SESSION_get_timeout(session));
-}
-
-bool DoApplicationStatesMatch(const ApplicationState* state,
-                              ApplicationState* other) {
-  if ((state && !other) || (!state && other)) return false;
-  if ((!state && !other) || *state == *other) return true;
-  return false;
-}
-
-}  // namespace
-
-QuicClientSessionCache::QuicClientSessionCache()
-    : QuicClientSessionCache(kDefaultMaxEntries) {}
-
-QuicClientSessionCache::QuicClientSessionCache(size_t max_entries)
-    : cache_(max_entries) {}
-
-QuicClientSessionCache::~QuicClientSessionCache() { Clear(); }
-
-void QuicClientSessionCache::Insert(const QuicServerId& server_id,
-                                    bssl::UniquePtr<SSL_SESSION> session,
-                                    const TransportParameters& params,
-                                    const ApplicationState* application_state) {
-  QUICHE_DCHECK(session) << "TLS session is not inserted into client cache.";
-  auto iter = cache_.Lookup(server_id);
-  if (iter == cache_.end()) {
-    CreateAndInsertEntry(server_id, std::move(session), params,
-                         application_state);
-    return;
-  }
-
-  QUICHE_DCHECK(iter->second->params);
-  // The states are both the same, so only need to insert sessions.
-  if (params == *iter->second->params &&
-      DoApplicationStatesMatch(application_state,
-                               iter->second->application_state.get())) {
-    iter->second->PushSession(std::move(session));
-    return;
-  }
-  // Erase the existing entry because this Insert call must come from a
-  // different QUIC session.
-  cache_.Erase(iter);
-  CreateAndInsertEntry(server_id, std::move(session), params,
-                       application_state);
-}
-
-std::unique_ptr<QuicResumptionState> QuicClientSessionCache::Lookup(
-    const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* /*ctx*/) {
-  auto iter = cache_.Lookup(server_id);
-  if (iter == cache_.end()) return nullptr;
-
-  if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
-    QUIC_DLOG(INFO) << "TLS Session expired for host:" << server_id.host();
-    cache_.Erase(iter);
-    return nullptr;
-  }
-  auto state = std::make_unique<QuicResumptionState>();
-  state->tls_session = iter->second->PopSession();
-  if (iter->second->params != nullptr) {
-    state->transport_params =
-        std::make_unique<TransportParameters>(*iter->second->params);
-  }
-  if (iter->second->application_state != nullptr) {
-    state->application_state =
-        std::make_unique<ApplicationState>(*iter->second->application_state);
-  }
-  if (!iter->second->token.empty()) {
-    state->token = iter->second->token;
-    // Clear token after use.
-    iter->second->token.clear();
-  }
-
-  return state;
-}
-
-void QuicClientSessionCache::ClearEarlyData(const QuicServerId& server_id) {
-  auto iter = cache_.Lookup(server_id);
-  if (iter == cache_.end()) return;
-  for (auto& session : iter->second->sessions) {
-    if (session) {
-      QUIC_DLOG(INFO) << "Clear early data for for host: " << server_id.host();
-      session.reset(SSL_SESSION_copy_without_early_data(session.get()));
-    }
-  }
-}
-
-void QuicClientSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
-                                                absl::string_view token) {
-  if (token.empty()) {
-    return;
-  }
-  auto iter = cache_.Lookup(server_id);
-  if (iter == cache_.end()) {
-    return;
-  }
-  iter->second->token = std::string(token);
-}
-
-void QuicClientSessionCache::RemoveExpiredEntries(QuicWallTime now) {
-  auto iter = cache_.begin();
-  while (iter != cache_.end()) {
-    if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
-      iter = cache_.Erase(iter);
-    } else {
-      ++iter;
-    }
-  }
-}
-
-void QuicClientSessionCache::Clear() { cache_.Clear(); }
-
-void QuicClientSessionCache::CreateAndInsertEntry(
-    const QuicServerId& server_id, bssl::UniquePtr<SSL_SESSION> session,
-    const TransportParameters& params,
-    const ApplicationState* application_state) {
-  auto entry = std::make_unique<Entry>();
-  entry->PushSession(std::move(session));
-  entry->params = std::make_unique<TransportParameters>(params);
-  if (application_state) {
-    entry->application_state =
-        std::make_unique<ApplicationState>(*application_state);
-  }
-  cache_.Insert(server_id, std::move(entry));
-}
-
-QuicClientSessionCache::Entry::Entry() = default;
-QuicClientSessionCache::Entry::Entry(Entry&&) = default;
-QuicClientSessionCache::Entry::~Entry() = default;
-
-void QuicClientSessionCache::Entry::PushSession(
-    bssl::UniquePtr<SSL_SESSION> session) {
-  if (sessions[0] != nullptr) {
-    sessions[1] = std::move(sessions[0]);
-  }
-  sessions[0] = std::move(session);
-}
-
-bssl::UniquePtr<SSL_SESSION> QuicClientSessionCache::Entry::PopSession() {
-  if (sessions[0] == nullptr) return nullptr;
-  bssl::UniquePtr<SSL_SESSION> session = std::move(sessions[0]);
-  sessions[0] = std::move(sessions[1]);
-  sessions[1] = nullptr;
-  return session;
-}
-
-SSL_SESSION* QuicClientSessionCache::Entry::PeekSession() {
-  return sessions[0].get();
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_client_session_cache.h b/quic/core/crypto/quic_client_session_cache.h
deleted file mode 100644
index 38678af..0000000
--- a/quic/core/crypto/quic_client_session_cache.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
-
-#include <memory>
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_lru_cache.h"
-#include "quic/core/quic_server_id.h"
-
-namespace quic {
-
-namespace test {
-class QuicClientSessionCachePeer;
-}  // namespace test
-
-// QuicClientSessionCache maps from QuicServerId to information used to resume
-// TLS sessions for that server.
-class QUIC_EXPORT_PRIVATE QuicClientSessionCache : public SessionCache {
- public:
-  QuicClientSessionCache();
-  explicit QuicClientSessionCache(size_t max_entries);
-  ~QuicClientSessionCache() override;
-
-  void Insert(const QuicServerId& server_id,
-              bssl::UniquePtr<SSL_SESSION> session,
-              const TransportParameters& params,
-              const ApplicationState* application_state) override;
-
-  std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
-                                              QuicWallTime now,
-                                              const SSL_CTX* ctx) override;
-
-  void ClearEarlyData(const QuicServerId& server_id) override;
-
-  void OnNewTokenReceived(const QuicServerId& server_id,
-                          absl::string_view token) override;
-
-  void RemoveExpiredEntries(QuicWallTime now) override;
-
-  void Clear() override;
-
-  size_t size() const { return cache_.Size(); }
-
- private:
-  friend class test::QuicClientSessionCachePeer;
-
-  struct QUIC_EXPORT_PRIVATE Entry {
-    Entry();
-    Entry(Entry&&);
-    ~Entry();
-
-    // Adds a new |session| onto sessions, dropping the oldest one if two are
-    // already stored.
-    void PushSession(bssl::UniquePtr<SSL_SESSION> session);
-
-    // Retrieves the latest session from the entry, meanwhile removing it.
-    bssl::UniquePtr<SSL_SESSION> PopSession();
-
-    SSL_SESSION* PeekSession();
-
-    bssl::UniquePtr<SSL_SESSION> sessions[2];
-    std::unique_ptr<TransportParameters> params;
-    std::unique_ptr<ApplicationState> application_state;
-    std::string token;  // An opaque string received in NEW_TOKEN frame.
-  };
-
-  // Creates a new entry and insert into |cache_|.
-  void CreateAndInsertEntry(const QuicServerId& server_id,
-                            bssl::UniquePtr<SSL_SESSION> session,
-                            const TransportParameters& params,
-                            const ApplicationState* application_state);
-
-  QuicLRUCache<QuicServerId, Entry, QuicServerIdHash> cache_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
diff --git a/quic/core/crypto/quic_client_session_cache_test.cc b/quic/core/crypto/quic_client_session_cache_test.cc
deleted file mode 100644
index 8fd6d25..0000000
--- a/quic/core/crypto/quic_client_session_cache_test.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_client_session_cache.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const QuicTime::Delta kTimeout = QuicTime::Delta::FromSeconds(1000);
-const QuicVersionLabel kFakeVersionLabel = 0x01234567;
-const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
-const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
-const uint8_t kFakeStatelessResetTokenData[16] = {
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
-const uint64_t kFakeMaxPacketSize = 9001;
-const uint64_t kFakeInitialMaxData = 101;
-const bool kFakeDisableMigration = true;
-const auto kCustomParameter1 =
-    static_cast<TransportParameters::TransportParameterId>(0xffcd);
-const char* kCustomParameter1Value = "foo";
-const auto kCustomParameter2 =
-    static_cast<TransportParameters::TransportParameterId>(0xff34);
-const char* kCustomParameter2Value = "bar";
-
-std::vector<uint8_t> CreateFakeStatelessResetToken() {
-  return std::vector<uint8_t>(
-      kFakeStatelessResetTokenData,
-      kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData));
-}
-
-TransportParameters::LegacyVersionInformation
-CreateFakeLegacyVersionInformation() {
-  TransportParameters::LegacyVersionInformation legacy_version_information;
-  legacy_version_information.version = kFakeVersionLabel;
-  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
-  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
-  return legacy_version_information;
-}
-
-TransportParameters::VersionInformation CreateFakeVersionInformation() {
-  TransportParameters::VersionInformation version_information;
-  version_information.chosen_version = kFakeVersionLabel;
-  version_information.other_versions.push_back(kFakeVersionLabel);
-  return version_information;
-}
-
-// Make a TransportParameters that has a few fields set to help test comparison.
-std::unique_ptr<TransportParameters> MakeFakeTransportParams() {
-  auto params = std::make_unique<TransportParameters>();
-  params->perspective = Perspective::IS_CLIENT;
-  params->legacy_version_information = CreateFakeLegacyVersionInformation();
-  params->version_information = CreateFakeVersionInformation();
-  params->max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-  params->stateless_reset_token = CreateFakeStatelessResetToken();
-  params->max_udp_payload_size.set_value(kFakeMaxPacketSize);
-  params->initial_max_data.set_value(kFakeInitialMaxData);
-  params->disable_active_migration = kFakeDisableMigration;
-  params->custom_parameters[kCustomParameter1] = kCustomParameter1Value;
-  params->custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-  return params;
-}
-
-// Generated by running TlsClientHandshakerTest.ZeroRttResumption and in
-// TlsClientHandshaker::InsertSession calling SSL_SESSION_to_bytes to serialize
-// the received 0-RTT capable ticket.
-static const char kCachedSession[] =
-    "30820ad7020101020203040402130104206594ce84e61a866b56163c4ba09079aebf1d4f"
-    "6cbcbd38dc9d7066a38a76c9cf0420ec9062063582a4cc0a44f9ff93256a195153ba6032"
-    "0cf3c9189990932d838adaa10602046196f7b9a205020302a300a382039f3082039b3082"
-    "0183a00302010202021001300d06092a864886f70d010105050030623111300f06035504"
-    "030c08426f677573204941310b300906035504080c024d41310b30090603550406130255"
-    "533121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d"
-    "3110300e060355040a0c07426f6775734941301e170d3231303132383136323030315a17"
-    "0d3331303132363136323030315a3069311d301b06035504030c14746573745f6563632e"
-    "6578616d706c652e636f6d310b300906035504080c024d41310b30090603550406130255"
-    "53311e301c06092a864886f70d010901160f626f67757340626f6775732e636f6d310e30"
-    "0c060355040a0c05426f6775733059301306072a8648ce3d020106082a8648ce3d030107"
-    "034200041ba5e2b6f24e64990b9f24ae6d23473d8c77fbcfb7f554f36559529a69a57170"
-    "a10a81b7fe4a36ebf37b0a8c5e467a8443d8b8c002892aa5c1194bd843f42c9aa31f301d"
-    "301b0603551d11041430128210746573742e6578616d706c652e636f6d300d06092a8648"
-    "86f70d0101050500038202010019921d54ac06948763d609215f64f5d6540e3da886c6c9"
-    "61bc737a437719b4621416ef1229f39282d7d3234e1a5d57535473066233bd246eec8e96"
-    "1e0633cf4fe014c800e62599981820ec33d92e74ded0fa2953db1d81e19cb6890b6305b6"
-    "3ede8d3e9fcf3c09f3f57283acf08aa57be4ee9a68d00bb3e2ded5920c619b5d83e5194a"
-    "adb77ae5d61ed3e0a5670f0ae61cc3197329f0e71e3364dcab0405e9e4a6646adef8f022"
-    "6415ec16c8046307b1769029fe780bd576114dde2fa9b4a32aa70bc436549a24ee4907a9"
-    "045f6457ce8dfd8d62cc65315afe798ae1a948eefd70b035d415e73569c48fb20085de1a"
-    "87de039e6b0b9a5fcb4069df27f3a7a1409e72d1ac739c72f29ef786134207e61c79855f"
-    "c22e3ee5f6ad59a7b1ff0f18d79776f1c95efaebbebe381664132a58a1e7ff689945b7e0"
-    "88634b0872feeefbf6be020884b994c6a7ff435f2b3f609077ff97cb509cfa17ff479b34"
-    "e633e4b5bc46b20c5f27c80a2e2943f795a928acd5a3fc43c3af8425ad600c048b41d87e"
-    "6361bc72fc4e5e44680a3d325674ba6ffa760d2fc7d9e4847a8e0dd9d35a543324e18b94"
-    "2d42af6391ed1dd54a39e3f4a4c6b32486eb4ba72815dbd89c56fc053743a0b0483ce676"
-    "15defce6800c629b99d0cbc56da162487f475b7c246099eaf1e6d10a022b2f49c6af1da3"
-    "e8ed66096f267c4a76976b9572db7456ef90278330a4020400aa81b60481b3494e534543"
-    "55524500f3439e548c21d2ad6e5634cc1cc0045730819702010102020304040213010400"
-    "0420ec9062063582a4cc0a44f9ff93256a195153ba60320cf3c9189990932d838adaa106"
-    "02046196f7b9a205020302a300a4020400b20302011db5060404130800cdb807020500ff"
-    "ffffffb9050203093a80ba0404026833bb030101ffbc23042100d27d985bfce04833f02d"
-    "38366b219f4def42bc4ba1b01844d1778db11731487dbd020400be020400b20302011db3"
-    "8205da308205d6308203bea00302010202021000300d06092a864886f70d010105050030"
-    "62310b3009060355040613025553310b300906035504080c024d413110300e060355040a"
-    "0c07426f67757343413111300f06035504030c08426f6775732043413121301f06092a86"
-    "4886f70d0109011612626f67757340626f6775732d63612e636f6d3020170d3231303132"
-    "383136313935385a180f32303730303531313136313935385a30623111300f0603550403"
-    "0c08426f677573204941310b300906035504080c024d41310b3009060355040613025553"
-    "3121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d31"
-    "10300e060355040a0c07426f677573494130820222300d06092a864886f70d0101010500"
-    "0382020f003082020a028202010096c03a0ffc61bcedcd5ec9bf6f848b8a066b43f08377"
-    "3af518a6a0044f22e666e24d2ae741954e344302c4be04612185bd53bcd848eb322bf900"
-    "724eb0848047d647033ffbddb00f01d1de7c1cdb684f83c9bf5fd18ff60afad5a53b0d7d"
-    "2c2a50abc38df019cd7f50194d05bc4597a1ef8570ea04069a2c36d74496af126573ca18"
-    "8e470009b56250fadf2a04e837ee3837b36b1f08b7a0cfe2533d05f26484ce4e30203d01"
-    "517fffd3da63d0341079ddce16e9ab4dbf9d4049e5cc52326031e645dd682fe6220d9e0e"
-    "95451f5a82f3e1720dc13e8499466426a0bdbea9f6a76b3c9228dd3c79ab4dcc4c145ef0"
-    "e78d1ee8bfd4650692d7e28a54bed809d8f7b37fe24c586be59cc46638531cb291c8c156"
-    "8f08d67e768e51563e95a639c1f138b275ffad6a6a2a042ba9e26ad63c2ce63b600013f0"
-    "a6f0703ee51c4f457f7bab0391c2fc4c5bb3213742c9cf9941bff68cc2e1cc96139d35ed"
-    "1885244ddde0bf658416c486701841b81f7b17503d08c59a4db08a2a80755e007aa3b6c7"
-    "eadcaa9e07c8325f3689f100de23970b12c9d9f6d0a8fb35ba0fd75c64410318db4a13ac"
-    "3972ad16cdf6408af37013c7bcd7c42f20d6d04c3e39436c7531e8dafa219dd04b784ef0"
-    "3c70ee5a4782b33cafa925aa3deca62a14aed704f179b932efabc2b0c5c15a8a99bfc9e6"
-    "189dce7da50ea303594b6af9c933dd54b6e9d17c472d0203010001a38193308190300f06"
-    "03551d130101ff040530030101ff301d0603551d0e041604141a98e80029a80992b7e5e0"
-    "068ab9b3486cd839d6301f0603551d23041830168014780beeefe2fa419c48a438bdb30b"
-    "e37ef0b7a94e300b0603551d0f0404030202a430130603551d25040c300a06082b060105"
-    "05070301301b0603551d11041430128207426f67757343418207426f6775734941300d06"
-    "092a864886f70d010105050003820201009e822ed8064b1aabaddf1340010ea147f68c06"
-    "5a5a599ea305349f1b0e545a00817d6e55c7bf85560fab429ca72186c4d520b52f5cc121"
-    "abd068b06f3111494431d2522efa54642f907059e7db80b73bb5ecf621377195b8700bba"
-    "df798cece8c67a9571548d0e6592e81ae5d934877cb170aef18d3b97f635600fe0890d98"
-    "f88b33fe3d1fd34c1c915beae4e5c0b133f476c40b21d220f16ce9cdd9e8f97a36a31723"
-    "68875f052c9271648d9cb54687c6fdc3ea96f2908003bc5e5e79de00a21da7b8429f8b08"
-    "af4c4d34641e386d72eabf5f01f106363f2ffd18969bf0bb9a4d17627c6427ff772c4308"
-    "83c276feef5fc6dba9582c22fdbe9df7e8dfca375695f028ed588df54f3c86462dbf4c07"
-    "91d80ca738988a1419c86bb4dd8d738b746921f01f39422e5ffd488b6f00195b996e6392"
-    "3a820a32cd78b5989f339c0fcf4f269103964a30a16347d0ffdc8df1f3653ddc1515fa09"
-    "22c7aef1af1fbcb23e93ae7622ab1ee11fcfa98319bad4c37c091cad46bd0337b3cc78b5"
-    "5b9f1ea7994acc1f89c49a0b4cb540d2137e266fd43e56a9b5b778217b6f77df530e1eaf"
-    "b3417262b5ddb86d3c6c5ac51e3f326c650dcc2434473973b7182c66220d1f3871bde7ee"
-    "47d3f359d3d4c5bdd61baa684c03db4c75f9d6690c9e6e3abe6eaf5fa2c33c4daf26b373"
-    "d85a1e8a7d671ac4a0a97b14e36e81280de4593bbb12da7695b5060404130800cdb60301"
-    "0100b70402020403b807020500ffffffffb9050203093a80ba0404026833bb030101ffbd"
-    "020400be020400";
-
-class QuicClientSessionCacheTest : public QuicTest {
- public:
-  QuicClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-
- protected:
-  bssl::UniquePtr<SSL_SESSION> NewSSLSession() {
-    std::string cached_session =
-        absl::HexStringToBytes(absl::string_view(kCachedSession));
-    SSL_SESSION* session = SSL_SESSION_from_bytes(
-        reinterpret_cast<const uint8_t*>(cached_session.data()),
-        cached_session.size(), ssl_ctx_.get());
-    QUICHE_DCHECK(session);
-    return bssl::UniquePtr<SSL_SESSION>(session);
-  }
-
-  bssl::UniquePtr<SSL_SESSION> MakeTestSession(
-      QuicTime::Delta timeout = kTimeout) {
-    bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
-    SSL_SESSION_set_time(session.get(), clock_.WallNow().ToUNIXSeconds());
-    SSL_SESSION_set_timeout(session.get(), timeout.ToSeconds());
-    return session;
-  }
-
-  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-  MockClock clock_;
-};
-
-// Tests that simple insertion and lookup work correctly.
-TEST_F(QuicClientSessionCacheTest, SingleSession) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-
-  auto params2 = MakeFakeTransportParams();
-  auto session2 = MakeTestSession();
-  SSL_SESSION* unowned2 = session2.get();
-  QuicServerId id2("b.com", 443);
-
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(0u, cache.size());
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  EXPECT_EQ(1u, cache.size());
-  EXPECT_EQ(
-      *params,
-      *(cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->transport_params));
-  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
-  // No session is available for id1, even though the entry exists.
-  EXPECT_EQ(1u, cache.size());
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-  // Lookup() will trigger a deletion of invalid entry.
-  EXPECT_EQ(0u, cache.size());
-
-  auto session3 = MakeTestSession();
-  SSL_SESSION* unowned3 = session3.get();
-  QuicServerId id3("c.com", 443);
-  cache.Insert(id3, std::move(session3), *params, nullptr);
-  cache.Insert(id2, std::move(session2), *params2, nullptr);
-  EXPECT_EQ(2u, cache.size());
-  EXPECT_EQ(
-      unowned2,
-      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-  EXPECT_EQ(
-      unowned3,
-      cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-
-  // Verify that the cache is cleared after Lookups.
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(nullptr, cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(0u, cache.size());
-}
-
-TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-  auto session2 = MakeTestSession();
-  SSL_SESSION* unowned2 = session2.get();
-  auto session3 = MakeTestSession();
-  SSL_SESSION* unowned3 = session3.get();
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  cache.Insert(id1, std::move(session2), *params, nullptr);
-  cache.Insert(id1, std::move(session3), *params, nullptr);
-  // The latest session is popped first.
-  EXPECT_EQ(
-      unowned3,
-      cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-  EXPECT_EQ(
-      unowned2,
-      cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-  // Only two sessions are cached.
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-// Test that when a different TransportParameter is inserted for
-// the same server id, the existing entry is removed.
-TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-  auto session2 = MakeTestSession();
-  auto session3 = MakeTestSession();
-  SSL_SESSION* unowned3 = session3.get();
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  cache.Insert(id1, std::move(session2), *params, nullptr);
-  // tweak the transport parameters a little bit.
-  params->perspective = Perspective::IS_SERVER;
-  cache.Insert(id1, std::move(session3), *params, nullptr);
-  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
-  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
-  EXPECT_EQ(*params.get(), *resumption_state->transport_params);
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-  auto session2 = MakeTestSession();
-  auto session3 = MakeTestSession();
-  SSL_SESSION* unowned3 = session3.get();
-  ApplicationState state;
-  state.push_back('a');
-
-  cache.Insert(id1, std::move(session), *params, &state);
-  cache.Insert(id1, std::move(session2), *params, &state);
-  cache.Insert(id1, std::move(session3), *params, nullptr);
-  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
-  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
-  EXPECT_EQ(nullptr, resumption_state->application_state);
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-  auto session2 = MakeTestSession();
-  auto session3 = MakeTestSession();
-  SSL_SESSION* unowned3 = session3.get();
-  ApplicationState state;
-  state.push_back('a');
-
-  cache.Insert(id1, std::move(session), *params, &state);
-  cache.Insert(id1, std::move(session2), *params, &state);
-  params->perspective = Perspective::IS_SERVER;
-  cache.Insert(id1, std::move(session3), *params, nullptr);
-  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
-  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
-  EXPECT_EQ(*params.get(), *resumption_state->transport_params);
-  EXPECT_EQ(nullptr, resumption_state->application_state);
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-// When the size limit is exceeded, the oldest entry should be erased.
-TEST_F(QuicClientSessionCacheTest, SizeLimit) {
-  QuicClientSessionCache cache(2);
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-
-  auto session2 = MakeTestSession();
-  SSL_SESSION* unowned2 = session2.get();
-  QuicServerId id2("b.com", 443);
-
-  auto session3 = MakeTestSession();
-  SSL_SESSION* unowned3 = session3.get();
-  QuicServerId id3("c.com", 443);
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  cache.Insert(id2, std::move(session2), *params, nullptr);
-  cache.Insert(id3, std::move(session3), *params, nullptr);
-
-  EXPECT_EQ(2u, cache.size());
-  EXPECT_EQ(
-      unowned2,
-      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-  EXPECT_EQ(
-      unowned3,
-      cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-TEST_F(QuicClientSessionCacheTest, ClearEarlyData) {
-  QuicClientSessionCache cache;
-  SSL_CTX_set_early_data_enabled(ssl_ctx_.get(), 1);
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-  auto session2 = MakeTestSession();
-
-  EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
-  EXPECT_TRUE(SSL_SESSION_early_data_capable(session2.get()));
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  cache.Insert(id1, std::move(session2), *params, nullptr);
-
-  cache.ClearEarlyData(id1);
-
-  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
-  EXPECT_FALSE(
-      SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
-  resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
-  EXPECT_FALSE(
-      SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-}
-
-// Expired session isn't considered valid and nullptr will be returned upon
-// Lookup.
-TEST_F(QuicClientSessionCacheTest, Expiration) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  QuicServerId id1("a.com", 443);
-
-  auto session2 = MakeTestSession(3 * kTimeout);
-  SSL_SESSION* unowned2 = session2.get();
-  QuicServerId id2("b.com", 443);
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  cache.Insert(id2, std::move(session2), *params, nullptr);
-
-  EXPECT_EQ(2u, cache.size());
-  // Expire the session.
-  clock_.AdvanceTime(kTimeout * 2);
-  // The entry has not been removed yet.
-  EXPECT_EQ(2u, cache.size());
-
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(1u, cache.size());
-  EXPECT_EQ(
-      unowned2,
-      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
-  EXPECT_EQ(1u, cache.size());
-}
-
-TEST_F(QuicClientSessionCacheTest, RemoveExpiredEntriesAndClear) {
-  QuicClientSessionCache cache;
-
-  auto params = MakeFakeTransportParams();
-  auto session = MakeTestSession();
-  quic::QuicServerId id1("a.com", 443);
-
-  auto session2 = MakeTestSession(3 * kTimeout);
-  quic::QuicServerId id2("b.com", 443);
-
-  cache.Insert(id1, std::move(session), *params, nullptr);
-  cache.Insert(id2, std::move(session2), *params, nullptr);
-
-  EXPECT_EQ(2u, cache.size());
-  // Expire the session.
-  clock_.AdvanceTime(kTimeout * 2);
-  // The entry has not been removed yet.
-  EXPECT_EQ(2u, cache.size());
-
-  // Flush expired sessions.
-  cache.RemoveExpiredEntries(clock_.WallNow());
-
-  // session is expired and should be flushed.
-  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
-  EXPECT_EQ(1u, cache.size());
-
-  cache.Clear();
-  EXPECT_EQ(0u, cache.size());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/quic_compressed_certs_cache.cc b/quic/core/crypto/quic_compressed_certs_cache.cc
deleted file mode 100644
index 3e011cc..0000000
--- a/quic/core/crypto/quic_compressed_certs_cache.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-
-namespace quic {
-
-namespace {
-
-// Inline helper function for extending a 64-bit |seed| in-place with a 64-bit
-// |value|. Based on Boost's hash_combine function.
-inline void hash_combine(uint64_t* seed, const uint64_t& val) {
-  (*seed) ^= val + 0x9e3779b9 + ((*seed) << 6) + ((*seed) >> 2);
-}
-
-}  // namespace
-
-const size_t QuicCompressedCertsCache::kQuicCompressedCertsCacheSize = 225;
-
-QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts()
-    : chain(nullptr),
-      client_cached_cert_hashes(nullptr) {}
-
-QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts(
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const std::string* client_cached_cert_hashes)
-    : chain(chain), client_cached_cert_hashes(client_cached_cert_hashes) {}
-
-QuicCompressedCertsCache::UncompressedCerts::~UncompressedCerts() {}
-
-QuicCompressedCertsCache::CachedCerts::CachedCerts() {}
-
-QuicCompressedCertsCache::CachedCerts::CachedCerts(
-    const UncompressedCerts& uncompressed_certs,
-    const std::string& compressed_cert)
-    : chain_(uncompressed_certs.chain),
-      client_cached_cert_hashes_(*uncompressed_certs.client_cached_cert_hashes),
-      compressed_cert_(compressed_cert) {}
-
-QuicCompressedCertsCache::CachedCerts::CachedCerts(const CachedCerts& other) =
-    default;
-
-QuicCompressedCertsCache::CachedCerts::~CachedCerts() {}
-
-bool QuicCompressedCertsCache::CachedCerts::MatchesUncompressedCerts(
-    const UncompressedCerts& uncompressed_certs) const {
-  return (client_cached_cert_hashes_ ==
-              *uncompressed_certs.client_cached_cert_hashes &&
-          chain_ == uncompressed_certs.chain);
-}
-
-const std::string* QuicCompressedCertsCache::CachedCerts::compressed_cert()
-    const {
-  return &compressed_cert_;
-}
-
-QuicCompressedCertsCache::QuicCompressedCertsCache(int64_t max_num_certs)
-    : certs_cache_(max_num_certs) {}
-
-QuicCompressedCertsCache::~QuicCompressedCertsCache() {
-  // Underlying cache must be cleared before destruction.
-  certs_cache_.Clear();
-}
-
-const std::string* QuicCompressedCertsCache::GetCompressedCert(
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const std::string& client_cached_cert_hashes) {
-  UncompressedCerts uncompressed_certs(chain, &client_cached_cert_hashes);
-
-  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
-
-  CachedCerts* cached_value = nullptr;
-  auto iter = certs_cache_.Lookup(key);
-  if (iter != certs_cache_.end()) {
-    cached_value = iter->second.get();
-  }
-  if (cached_value != nullptr &&
-      cached_value->MatchesUncompressedCerts(uncompressed_certs)) {
-    return cached_value->compressed_cert();
-  }
-  return nullptr;
-}
-
-void QuicCompressedCertsCache::Insert(
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const std::string& client_cached_cert_hashes,
-    const std::string& compressed_cert) {
-  UncompressedCerts uncompressed_certs(chain, &client_cached_cert_hashes);
-
-  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
-
-  // Insert one unit to the cache.
-  std::unique_ptr<CachedCerts> cached_certs(
-      new CachedCerts(uncompressed_certs, compressed_cert));
-  certs_cache_.Insert(key, std::move(cached_certs));
-}
-
-size_t QuicCompressedCertsCache::MaxSize() {
-  return certs_cache_.MaxSize();
-}
-
-size_t QuicCompressedCertsCache::Size() {
-  return certs_cache_.Size();
-}
-
-uint64_t QuicCompressedCertsCache::ComputeUncompressedCertsHash(
-    const UncompressedCerts& uncompressed_certs) {
-  uint64_t hash =
-      std::hash<std::string>()(*uncompressed_certs.client_cached_cert_hashes);
-
-  hash_combine(&hash,
-               reinterpret_cast<uint64_t>(uncompressed_certs.chain.get()));
-  return hash;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_compressed_certs_cache.h b/quic/core/crypto/quic_compressed_certs_cache.h
deleted file mode 100644
index ffaf56f..0000000
--- a/quic/core/crypto/quic_compressed_certs_cache.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
-
-#include <string>
-#include <vector>
-
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/quic_lru_cache.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicCompressedCertsCache is a cache to track most recently compressed certs.
-class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache {
- public:
-  explicit QuicCompressedCertsCache(int64_t max_num_certs);
-  ~QuicCompressedCertsCache();
-
-  // Returns the pointer to the cached compressed cert if
-  // |chain, client_cached_cert_hashes| hits cache.
-  // Otherwise, return nullptr.
-  // Returned pointer might become invalid on the next call to Insert().
-  const std::string* GetCompressedCert(
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const std::string& client_cached_cert_hashes);
-
-  // Inserts the specified
-  // |chain, client_cached_cert_hashes, compressed_cert| tuple to the cache.
-  // If the insertion causes the cache to become overfull, entries will
-  // be deleted in an LRU order to make room.
-  void Insert(
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const std::string& client_cached_cert_hashes,
-      const std::string& compressed_cert);
-
-  // Returns max number of cache entries the cache can carry.
-  size_t MaxSize();
-
-  // Returns current number of cache entries in the cache.
-  size_t Size();
-
-  // Default size of the QuicCompressedCertsCache per server side investigation.
-  static const size_t kQuicCompressedCertsCacheSize;
-
- private:
-  // A wrapper of the tuple:
-  //   |chain, client_cached_cert_hashes|
-  // to identify uncompressed representation of certs.
-  struct QUIC_EXPORT_PRIVATE UncompressedCerts {
-    UncompressedCerts();
-    UncompressedCerts(
-        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-        const std::string* client_cached_cert_hashes);
-    ~UncompressedCerts();
-
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
-    const std::string* client_cached_cert_hashes;
-  };
-
-  // Certs stored by QuicCompressedCertsCache where uncompressed certs data is
-  // used to identify the uncompressed representation of certs and
-  // |compressed_cert| is the cached compressed representation.
-  class QUIC_EXPORT_PRIVATE CachedCerts {
-   public:
-    CachedCerts();
-    CachedCerts(const UncompressedCerts& uncompressed_certs,
-                const std::string& compressed_cert);
-    CachedCerts(const CachedCerts& other);
-    ~CachedCerts();
-
-    // Returns true if the |uncompressed_certs| matches uncompressed
-    // representation of this cert.
-    bool MatchesUncompressedCerts(
-        const UncompressedCerts& uncompressed_certs) const;
-
-    const std::string* compressed_cert() const;
-
-   private:
-    // Uncompressed certs data.
-    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain_;
-    const std::string client_cached_cert_hashes_;
-
-    // Cached compressed representation derived from uncompressed certs.
-    const std::string compressed_cert_;
-  };
-
-  // Computes a uint64_t hash for |uncompressed_certs|.
-  uint64_t ComputeUncompressedCertsHash(
-      const UncompressedCerts& uncompressed_certs);
-
-  // Key is a unit64_t hash for UncompressedCerts. Stored associated value is
-  // CachedCerts which has both original uncompressed certs data and the
-  // compressed representation of the certs.
-  QuicLRUCache<uint64_t, CachedCerts> certs_cache_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
diff --git a/quic/core/crypto/quic_compressed_certs_cache_test.cc b/quic/core/crypto/quic_compressed_certs_cache_test.cc
deleted file mode 100644
index c76cd72..0000000
--- a/quic/core/crypto/quic_compressed_certs_cache_test.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-class QuicCompressedCertsCacheTest : public QuicTest {
- public:
-  QuicCompressedCertsCacheTest()
-      : certs_cache_(QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {}
-
- protected:
-  QuicCompressedCertsCache certs_cache_;
-};
-
-TEST_F(QuicCompressedCertsCacheTest, CacheHit) {
-  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
-                                    "root cert"};
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
-      new ProofSource::Chain(certs));
-  std::string cached_certs = "cached certs";
-  std::string compressed = "compressed cert";
-
-  certs_cache_.Insert(chain, cached_certs, compressed);
-
-  const std::string* cached_value =
-      certs_cache_.GetCompressedCert(chain, cached_certs);
-  ASSERT_NE(nullptr, cached_value);
-  EXPECT_EQ(*cached_value, compressed);
-}
-
-TEST_F(QuicCompressedCertsCacheTest, CacheMiss) {
-  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
-                                    "root cert"};
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
-      new ProofSource::Chain(certs));
-
-  std::string cached_certs = "cached certs";
-  std::string compressed = "compressed cert";
-
-  certs_cache_.Insert(chain, cached_certs, compressed);
-
-  EXPECT_EQ(nullptr,
-            certs_cache_.GetCompressedCert(chain, "mismatched cached certs"));
-
-  // A different chain though with equivalent certs should get a cache miss.
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
-      new ProofSource::Chain(certs));
-  EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain2, cached_certs));
-}
-
-TEST_F(QuicCompressedCertsCacheTest, CacheMissDueToEviction) {
-  // Test cache returns a miss when a queried uncompressed certs was cached but
-  // then evicted.
-  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
-                                    "root cert"};
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
-      new ProofSource::Chain(certs));
-
-  std::string cached_certs = "cached certs";
-  std::string compressed = "compressed cert";
-  certs_cache_.Insert(chain, cached_certs, compressed);
-
-  // Insert another kQuicCompressedCertsCacheSize certs to evict the first
-  // cached cert.
-  for (unsigned int i = 0;
-       i < QuicCompressedCertsCache::kQuicCompressedCertsCacheSize; i++) {
-    EXPECT_EQ(certs_cache_.Size(), i + 1);
-    certs_cache_.Insert(chain, absl::StrCat(i), absl::StrCat(i));
-  }
-  EXPECT_EQ(certs_cache_.MaxSize(), certs_cache_.Size());
-
-  EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain, cached_certs));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/quic_crypter.cc b/quic/core/crypto/quic_crypter.cc
deleted file mode 100644
index d41ce21..0000000
--- a/quic/core/crypto/quic_crypter.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypter.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-bool QuicCrypter::SetNoncePrefixOrIV(const ParsedQuicVersion& version,
-                                     absl::string_view nonce_prefix_or_iv) {
-  if (version.UsesInitialObfuscators()) {
-    return SetIV(nonce_prefix_or_iv);
-  }
-  return SetNoncePrefix(nonce_prefix_or_iv);
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_crypter.h b/quic/core/crypto/quic_crypter.h
deleted file mode 100644
index 001b6ec..0000000
--- a/quic/core/crypto/quic_crypter.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicCrypter is the parent class for QuicEncrypter and QuicDecrypter.
-// Its purpose is to provide an interface for using methods that are common to
-// both classes when operations are being done that apply to both encrypters and
-// decrypters.
-class QUIC_EXPORT_PRIVATE QuicCrypter {
- public:
-  virtual ~QuicCrypter() {}
-
-  // Sets the symmetric encryption/decryption key. Returns true on success,
-  // false on failure.
-  //
-  // NOTE: The key is the client_write_key or server_write_key derived from
-  // the master secret.
-  virtual bool SetKey(absl::string_view key) = 0;
-
-  // Sets the fixed initial bytes of the nonce. Returns true on success,
-  // false on failure. This method must only be used with Google QUIC crypters.
-  //
-  // NOTE: The nonce prefix is the client_write_iv or server_write_iv
-  // derived from the master secret. A 64-bit packet number will
-  // be appended to form the nonce.
-  //
-  //                          <------------ 64 bits ----------->
-  //   +---------------------+----------------------------------+
-  //   |    Fixed prefix     |      packet number      |
-  //   +---------------------+----------------------------------+
-  //                          Nonce format
-  //
-  // The security of the nonce format requires that QUIC never reuse a
-  // packet number, even when retransmitting a lost packet.
-  virtual bool SetNoncePrefix(absl::string_view nonce_prefix) = 0;
-
-  // Sets |iv| as the initialization vector to use when constructing the nonce.
-  // Returns true on success, false on failure. This method must only be used
-  // with IETF QUIC crypters.
-  //
-  // Google QUIC and IETF QUIC use different nonce constructions. This method
-  // must be used when using IETF QUIC; SetNoncePrefix must be used when using
-  // Google QUIC.
-  //
-  // The nonce is constructed as follows (draft-ietf-quic-tls-14 section 5.2):
-  //
-  //    <---------------- max(8, N_MIN) bytes ----------------->
-  //   +--------------------------------------------------------+
-  //   |                 packet protection IV                   |
-  //   +--------------------------------------------------------+
-  //                             XOR
-  //                          <------------ 64 bits ----------->
-  //   +---------------------+----------------------------------+
-  //   |        zeroes       |   reconstructed packet number    |
-  //   +---------------------+----------------------------------+
-  //
-  // The nonce is the packet protection IV (|iv|) XOR'd with the left-padded
-  // reconstructed packet number.
-  //
-  // The security of the nonce format requires that QUIC never reuse a
-  // packet number, even when retransmitting a lost packet.
-  virtual bool SetIV(absl::string_view iv) = 0;
-
-  // Calls SetNoncePrefix or SetIV depending on whether |version| uses the
-  // Google QUIC crypto or IETF QUIC nonce construction.
-  virtual bool SetNoncePrefixOrIV(const ParsedQuicVersion& version,
-                                  absl::string_view nonce_prefix_or_iv);
-
-  // Sets the key to use for header protection.
-  virtual bool SetHeaderProtectionKey(absl::string_view key) = 0;
-
-  // GetKeySize, GetIVSize, and GetNoncePrefixSize are used to know how many
-  // bytes of key material needs to be derived from the master secret.
-
-  // Returns the size in bytes of a key for the algorithm.
-  virtual size_t GetKeySize() const = 0;
-  // Returns the size in bytes of an IV to use with the algorithm.
-  virtual size_t GetIVSize() const = 0;
-  // Returns the size in bytes of the fixed initial part of the nonce.
-  virtual size_t GetNoncePrefixSize() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
diff --git a/quic/core/crypto/quic_crypto_client_config.cc b/quic/core/crypto/quic_crypto_client_config.cc
deleted file mode 100644
index 4ddfb1e..0000000
--- a/quic/core/crypto/quic_crypto_client_config.cc
+++ /dev/null
@@ -1,857 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/curve25519_key_exchange.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/p256_key_exchange.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/crypto/tls_client_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Tracks the reason (the state of the server config) for sending inchoate
-// ClientHello to the server.
-void RecordInchoateClientHelloReason(
-    QuicCryptoClientConfig::CachedState::ServerConfigState state) {
-  QUIC_CLIENT_HISTOGRAM_ENUM(
-      "QuicInchoateClientHelloReason", state,
-      QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
-}
-
-// Tracks the state of the QUIC server information loaded from the disk cache.
-void RecordDiskCacheServerConfigState(
-    QuicCryptoClientConfig::CachedState::ServerConfigState state) {
-  QUIC_CLIENT_HISTOGRAM_ENUM(
-      "QuicServerInfo.DiskCacheState", state,
-      QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
-}
-
-}  // namespace
-
-QuicCryptoClientConfig::QuicCryptoClientConfig(
-    std::unique_ptr<ProofVerifier> proof_verifier)
-    : QuicCryptoClientConfig(std::move(proof_verifier), nullptr) {}
-
-QuicCryptoClientConfig::QuicCryptoClientConfig(
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    std::unique_ptr<SessionCache> session_cache)
-    : proof_verifier_(std::move(proof_verifier)),
-      session_cache_(std::move(session_cache)),
-      ssl_ctx_(TlsClientConnection::CreateSslCtx(
-          !GetQuicFlag(FLAGS_quic_disable_client_tls_zero_rtt))) {
-  QUICHE_DCHECK(proof_verifier_.get());
-  SetDefaults();
-}
-
-QuicCryptoClientConfig::~QuicCryptoClientConfig() {}
-
-QuicCryptoClientConfig::CachedState::CachedState()
-    : server_config_valid_(false),
-      expiration_time_(QuicWallTime::Zero()),
-      generation_counter_(0) {}
-
-QuicCryptoClientConfig::CachedState::~CachedState() {}
-
-bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
-  if (server_config_.empty()) {
-    RecordInchoateClientHelloReason(SERVER_CONFIG_EMPTY);
-    return false;
-  }
-
-  if (!server_config_valid_) {
-    RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID);
-    return false;
-  }
-
-  const CryptoHandshakeMessage* scfg = GetServerConfig();
-  if (!scfg) {
-    // Should be impossible short of cache corruption.
-    RecordInchoateClientHelloReason(SERVER_CONFIG_CORRUPTED);
-    QUICHE_DCHECK(false);
-    return false;
-  }
-
-  if (now.IsBefore(expiration_time_)) {
-    return true;
-  }
-
-  QUIC_CLIENT_HISTOGRAM_TIMES(
-      "QuicClientHelloServerConfig.InvalidDuration",
-      QuicTime::Delta::FromSeconds(now.ToUNIXSeconds() -
-                                   expiration_time_.ToUNIXSeconds()),
-      QuicTime::Delta::FromSeconds(60),              // 1 min.
-      QuicTime::Delta::FromSeconds(20 * 24 * 3600),  // 20 days.
-      50, "");
-  RecordInchoateClientHelloReason(SERVER_CONFIG_EXPIRED);
-  return false;
-}
-
-bool QuicCryptoClientConfig::CachedState::IsEmpty() const {
-  return server_config_.empty();
-}
-
-const CryptoHandshakeMessage*
-QuicCryptoClientConfig::CachedState::GetServerConfig() const {
-  if (server_config_.empty()) {
-    return nullptr;
-  }
-
-  if (!scfg_) {
-    scfg_ = CryptoFramer::ParseMessage(server_config_);
-    QUICHE_DCHECK(scfg_.get());
-  }
-  return scfg_.get();
-}
-
-QuicCryptoClientConfig::CachedState::ServerConfigState
-QuicCryptoClientConfig::CachedState::SetServerConfig(
-    absl::string_view server_config,
-    QuicWallTime now,
-    QuicWallTime expiry_time,
-    std::string* error_details) {
-  const bool matches_existing = server_config == server_config_;
-
-  // Even if the new server config matches the existing one, we still wish to
-  // reject it if it has expired.
-  std::unique_ptr<CryptoHandshakeMessage> new_scfg_storage;
-  const CryptoHandshakeMessage* new_scfg;
-
-  if (!matches_existing) {
-    new_scfg_storage = CryptoFramer::ParseMessage(server_config);
-    new_scfg = new_scfg_storage.get();
-  } else {
-    new_scfg = GetServerConfig();
-  }
-
-  if (!new_scfg) {
-    *error_details = "SCFG invalid";
-    return SERVER_CONFIG_INVALID;
-  }
-
-  if (expiry_time.IsZero()) {
-    uint64_t expiry_seconds;
-    if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
-      *error_details = "SCFG missing EXPY";
-      return SERVER_CONFIG_INVALID_EXPIRY;
-    }
-    expiration_time_ = QuicWallTime::FromUNIXSeconds(expiry_seconds);
-  } else {
-    expiration_time_ = expiry_time;
-  }
-
-  if (now.IsAfter(expiration_time_)) {
-    *error_details = "SCFG has expired";
-    return SERVER_CONFIG_EXPIRED;
-  }
-
-  if (!matches_existing) {
-    server_config_ = std::string(server_config);
-    SetProofInvalid();
-    scfg_ = std::move(new_scfg_storage);
-  }
-  return SERVER_CONFIG_VALID;
-}
-
-void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
-  server_config_.clear();
-  scfg_.reset();
-  SetProofInvalid();
-}
-
-void QuicCryptoClientConfig::CachedState::SetProof(
-    const std::vector<std::string>& certs,
-    absl::string_view cert_sct,
-    absl::string_view chlo_hash,
-    absl::string_view signature) {
-  bool has_changed = signature != server_config_sig_ ||
-                     chlo_hash != chlo_hash_ || certs_.size() != certs.size();
-
-  if (!has_changed) {
-    for (size_t i = 0; i < certs_.size(); i++) {
-      if (certs_[i] != certs[i]) {
-        has_changed = true;
-        break;
-      }
-    }
-  }
-
-  if (!has_changed) {
-    return;
-  }
-
-  // If the proof has changed then it needs to be revalidated.
-  SetProofInvalid();
-  certs_ = certs;
-  cert_sct_ = std::string(cert_sct);
-  chlo_hash_ = std::string(chlo_hash);
-  server_config_sig_ = std::string(signature);
-}
-
-void QuicCryptoClientConfig::CachedState::Clear() {
-  server_config_.clear();
-  source_address_token_.clear();
-  certs_.clear();
-  cert_sct_.clear();
-  chlo_hash_.clear();
-  server_config_sig_.clear();
-  server_config_valid_ = false;
-  proof_verify_details_.reset();
-  scfg_.reset();
-  ++generation_counter_;
-}
-
-void QuicCryptoClientConfig::CachedState::ClearProof() {
-  SetProofInvalid();
-  certs_.clear();
-  cert_sct_.clear();
-  chlo_hash_.clear();
-  server_config_sig_.clear();
-}
-
-void QuicCryptoClientConfig::CachedState::SetProofValid() {
-  server_config_valid_ = true;
-}
-
-void QuicCryptoClientConfig::CachedState::SetProofInvalid() {
-  server_config_valid_ = false;
-  ++generation_counter_;
-}
-
-bool QuicCryptoClientConfig::CachedState::Initialize(
-    absl::string_view server_config,
-    absl::string_view source_address_token,
-    const std::vector<std::string>& certs,
-    const std::string& cert_sct,
-    absl::string_view chlo_hash,
-    absl::string_view signature,
-    QuicWallTime now,
-    QuicWallTime expiration_time) {
-  QUICHE_DCHECK(server_config_.empty());
-
-  if (server_config.empty()) {
-    RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY);
-    return false;
-  }
-
-  std::string error_details;
-  ServerConfigState state =
-      SetServerConfig(server_config, now, expiration_time, &error_details);
-  RecordDiskCacheServerConfigState(state);
-  if (state != SERVER_CONFIG_VALID) {
-    QUIC_DVLOG(1) << "SetServerConfig failed with " << error_details;
-    return false;
-  }
-
-  chlo_hash_.assign(chlo_hash.data(), chlo_hash.size());
-  server_config_sig_.assign(signature.data(), signature.size());
-  source_address_token_.assign(source_address_token.data(),
-                               source_address_token.size());
-  certs_ = certs;
-  cert_sct_ = cert_sct;
-  return true;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::server_config() const {
-  return server_config_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::source_address_token()
-    const {
-  return source_address_token_;
-}
-
-const std::vector<std::string>& QuicCryptoClientConfig::CachedState::certs()
-    const {
-  return certs_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::cert_sct() const {
-  return cert_sct_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::chlo_hash() const {
-  return chlo_hash_;
-}
-
-const std::string& QuicCryptoClientConfig::CachedState::signature() const {
-  return server_config_sig_;
-}
-
-bool QuicCryptoClientConfig::CachedState::proof_valid() const {
-  return server_config_valid_;
-}
-
-uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const {
-  return generation_counter_;
-}
-
-const ProofVerifyDetails*
-QuicCryptoClientConfig::CachedState::proof_verify_details() const {
-  return proof_verify_details_.get();
-}
-
-void QuicCryptoClientConfig::CachedState::set_source_address_token(
-    absl::string_view token) {
-  source_address_token_ = std::string(token);
-}
-
-void QuicCryptoClientConfig::CachedState::set_cert_sct(
-    absl::string_view cert_sct) {
-  cert_sct_ = std::string(cert_sct);
-}
-
-void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
-    ProofVerifyDetails* details) {
-  proof_verify_details_.reset(details);
-}
-
-void QuicCryptoClientConfig::CachedState::InitializeFrom(
-    const QuicCryptoClientConfig::CachedState& other) {
-  QUICHE_DCHECK(server_config_.empty());
-  QUICHE_DCHECK(!server_config_valid_);
-  server_config_ = other.server_config_;
-  source_address_token_ = other.source_address_token_;
-  certs_ = other.certs_;
-  cert_sct_ = other.cert_sct_;
-  chlo_hash_ = other.chlo_hash_;
-  server_config_sig_ = other.server_config_sig_;
-  server_config_valid_ = other.server_config_valid_;
-  expiration_time_ = other.expiration_time_;
-  if (other.proof_verify_details_ != nullptr) {
-    proof_verify_details_.reset(other.proof_verify_details_->Clone());
-  }
-  ++generation_counter_;
-}
-
-void QuicCryptoClientConfig::SetDefaults() {
-  // Key exchange methods.
-  kexs = {kC255, kP256};
-
-  // Authenticated encryption algorithms. Prefer AES-GCM if hardware-supported
-  // fast implementation is available.
-  if (EVP_has_aes_hardware() == 1) {
-    aead = {kAESG, kCC20};
-  } else {
-    aead = {kCC20, kAESG};
-  }
-}
-
-QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate(
-    const QuicServerId& server_id) {
-  auto it = cached_states_.find(server_id);
-  if (it != cached_states_.end()) {
-    return it->second.get();
-  }
-
-  CachedState* cached = new CachedState;
-  cached_states_.insert(std::make_pair(server_id, absl::WrapUnique(cached)));
-  bool cache_populated = PopulateFromCanonicalConfig(server_id, cached);
-  QUIC_CLIENT_HISTOGRAM_BOOL(
-      "QuicCryptoClientConfig.PopulatedFromCanonicalConfig", cache_populated,
-      "");
-  return cached;
-}
-
-void QuicCryptoClientConfig::ClearCachedStates(const ServerIdFilter& filter) {
-  for (auto it = cached_states_.begin(); it != cached_states_.end(); ++it) {
-    if (filter.Matches(it->first))
-      it->second->Clear();
-  }
-}
-
-void QuicCryptoClientConfig::FillInchoateClientHello(
-    const QuicServerId& server_id, const ParsedQuicVersion preferred_version,
-    const CachedState* cached, QuicRandom* rand, bool demand_x509_proof,
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        out_params,
-    CryptoHandshakeMessage* out) const {
-  out->set_tag(kCHLO);
-  out->set_minimum_size(1);
-
-  // Server name indication. We only send SNI if it's a valid domain name, as
-  // per the spec.
-  if (QuicHostnameUtils::IsValidSNI(server_id.host())) {
-    out->SetStringPiece(kSNI, server_id.host());
-  }
-  out->SetVersion(kVER, preferred_version);
-
-  if (!user_agent_id_.empty()) {
-    out->SetStringPiece(kUAID, user_agent_id_);
-  }
-
-  if (!alpn_.empty()) {
-    out->SetStringPiece(kALPN, alpn_);
-  }
-
-  // Even though this is an inchoate CHLO, send the SCID so that
-  // the STK can be validated by the server.
-  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
-  if (scfg != nullptr) {
-    absl::string_view scid;
-    if (scfg->GetStringPiece(kSCID, &scid)) {
-      out->SetStringPiece(kSCID, scid);
-    }
-  }
-
-  if (!cached->source_address_token().empty()) {
-    out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
-  }
-
-  if (!demand_x509_proof) {
-    return;
-  }
-
-  char proof_nonce[32];
-  rand->RandBytes(proof_nonce, ABSL_ARRAYSIZE(proof_nonce));
-  out->SetStringPiece(
-      kNONP, absl::string_view(proof_nonce, ABSL_ARRAYSIZE(proof_nonce)));
-
-  out->SetVector(kPDMD, QuicTagVector{kX509});
-
-  out->SetStringPiece(kCertificateSCTTag, "");
-
-  const std::vector<std::string>& certs = cached->certs();
-  // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
-  // client config is being used for multiple connections, another connection
-  // doesn't update the cached certificates and cause us to be unable to
-  // process the server's compressed certificate chain.
-  out_params->cached_certs = certs;
-  if (!certs.empty()) {
-    std::vector<uint64_t> hashes;
-    hashes.reserve(certs.size());
-    for (auto i = certs.begin(); i != certs.end(); ++i) {
-      hashes.push_back(QuicUtils::FNV1a_64_Hash(*i));
-    }
-    out->SetVector(kCCRT, hashes);
-  }
-}
-
-QuicErrorCode QuicCryptoClientConfig::FillClientHello(
-    const QuicServerId& server_id, QuicConnectionId connection_id,
-    const ParsedQuicVersion preferred_version,
-    const ParsedQuicVersion actual_version, const CachedState* cached,
-    QuicWallTime now, QuicRandom* rand,
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        out_params,
-    CryptoHandshakeMessage* out, std::string* error_details) const {
-  QUICHE_DCHECK(error_details != nullptr);
-  QUIC_BUG_IF(quic_bug_12943_2,
-              !QuicUtils::IsConnectionIdValidForVersion(
-                  connection_id, preferred_version.transport_version))
-      << "FillClientHello: attempted to use connection ID " << connection_id
-      << " which is invalid with version " << preferred_version;
-
-  FillInchoateClientHello(server_id, preferred_version, cached, rand,
-                          /* demand_x509_proof= */ true, out_params, out);
-
-  out->set_minimum_size(1);
-
-  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
-  if (!scfg) {
-    // This should never happen as our caller should have checked
-    // cached->IsComplete() before calling this function.
-    *error_details = "Handshake not ready";
-    return QUIC_CRYPTO_INTERNAL_ERROR;
-  }
-
-  absl::string_view scid;
-  if (!scfg->GetStringPiece(kSCID, &scid)) {
-    *error_details = "SCFG missing SCID";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-  out->SetStringPiece(kSCID, scid);
-
-  out->SetStringPiece(kCertificateSCTTag, "");
-
-  QuicTagVector their_aeads;
-  QuicTagVector their_key_exchanges;
-  if (scfg->GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR ||
-      scfg->GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR) {
-    *error_details = "Missing AEAD or KEXS";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  // AEAD: the work loads on the client and server are symmetric. Since the
-  // client is more likely to be CPU-constrained, break the tie by favoring
-  // the client's preference.
-  // Key exchange: the client does more work than the server, so favor the
-  // client's preference.
-  size_t key_exchange_index;
-  if (!FindMutualQuicTag(aead, their_aeads, &out_params->aead, nullptr) ||
-      !FindMutualQuicTag(kexs, their_key_exchanges, &out_params->key_exchange,
-                         &key_exchange_index)) {
-    *error_details = "Unsupported AEAD or KEXS";
-    return QUIC_CRYPTO_NO_SUPPORT;
-  }
-  out->SetVector(kAEAD, QuicTagVector{out_params->aead});
-  out->SetVector(kKEXS, QuicTagVector{out_params->key_exchange});
-
-  absl::string_view public_value;
-  if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) !=
-      QUIC_NO_ERROR) {
-    *error_details = "Missing public value";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  absl::string_view orbit;
-  if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) {
-    *error_details = "SCFG missing OBIT";
-    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-  }
-
-  CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce);
-  out->SetStringPiece(kNONC, out_params->client_nonce);
-  if (!out_params->server_nonce.empty()) {
-    out->SetStringPiece(kServerNonceTag, out_params->server_nonce);
-  }
-
-  switch (out_params->key_exchange) {
-    case kC255:
-      out_params->client_key_exchange = Curve25519KeyExchange::New(
-          Curve25519KeyExchange::NewPrivateKey(rand));
-      break;
-    case kP256:
-      out_params->client_key_exchange =
-          P256KeyExchange::New(P256KeyExchange::NewPrivateKey());
-      break;
-    default:
-      QUICHE_DCHECK(false);
-      *error_details = "Configured to support an unknown key exchange";
-      return QUIC_CRYPTO_INTERNAL_ERROR;
-  }
-
-  if (!out_params->client_key_exchange->CalculateSharedKeySync(
-          public_value, &out_params->initial_premaster_secret)) {
-    *error_details = "Key exchange failure";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-  out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
-
-  const std::vector<std::string>& certs = cached->certs();
-  if (certs.empty()) {
-    *error_details = "No certs to calculate XLCT";
-    return QUIC_CRYPTO_INTERNAL_ERROR;
-  }
-  out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0]));
-
-  // Derive the symmetric keys and set up the encrypters and decrypters.
-  // Set the following members of out_params:
-  //   out_params->hkdf_input_suffix
-  //   out_params->initial_crypters
-  out_params->hkdf_input_suffix.clear();
-  out_params->hkdf_input_suffix.append(connection_id.data(),
-                                       connection_id.length());
-  const QuicData& client_hello_serialized = out->GetSerialized();
-  out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
-                                       client_hello_serialized.length());
-  out_params->hkdf_input_suffix.append(cached->server_config());
-  if (certs.empty()) {
-    *error_details = "No certs found to include in KDF";
-    return QUIC_CRYPTO_INTERNAL_ERROR;
-  }
-  out_params->hkdf_input_suffix.append(certs[0]);
-
-  std::string hkdf_input;
-  const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
-  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
-  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
-  hkdf_input.append(out_params->hkdf_input_suffix);
-
-  std::string* subkey_secret = &out_params->initial_subkey_secret;
-
-  if (!CryptoUtils::DeriveKeys(
-          actual_version, out_params->initial_premaster_secret,
-          out_params->aead, out_params->client_nonce, out_params->server_nonce,
-          pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
-          CryptoUtils::Diversification::Pending(),
-          &out_params->initial_crypters, subkey_secret)) {
-    *error_details = "Symmetric key setup failed";
-    return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
-    const CryptoHandshakeMessage& message,
-    QuicWallTime now,
-    QuicTransportVersion /*version*/,
-    absl::string_view chlo_hash,
-    const std::vector<std::string>& cached_certs,
-    CachedState* cached,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-
-  absl::string_view scfg;
-  if (!message.GetStringPiece(kSCFG, &scfg)) {
-    *error_details = "Missing SCFG";
-    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-  }
-
-  QuicWallTime expiration_time = QuicWallTime::Zero();
-  uint64_t expiry_seconds;
-  if (message.GetUint64(kSTTL, &expiry_seconds) == QUIC_NO_ERROR) {
-    // Only cache configs for a maximum of 1 week.
-    expiration_time = now.Add(QuicTime::Delta::FromSeconds(
-        std::min(expiry_seconds, kNumSecondsPerWeek)));
-  }
-
-  CachedState::ServerConfigState state =
-      cached->SetServerConfig(scfg, now, expiration_time, error_details);
-  if (state == CachedState::SERVER_CONFIG_EXPIRED) {
-    return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
-  }
-  // TODO(rtenneti): Return more specific error code than returning
-  // QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER.
-  if (state != CachedState::SERVER_CONFIG_VALID) {
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  absl::string_view token;
-  if (message.GetStringPiece(kSourceAddressTokenTag, &token)) {
-    cached->set_source_address_token(token);
-  }
-
-  absl::string_view proof, cert_bytes, cert_sct;
-  bool has_proof = message.GetStringPiece(kPROF, &proof);
-  bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes);
-  if (has_proof && has_cert) {
-    std::vector<std::string> certs;
-    if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, &certs)) {
-      *error_details = "Certificate data invalid";
-      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-    }
-
-    message.GetStringPiece(kCertificateSCTTag, &cert_sct);
-    cached->SetProof(certs, cert_sct, chlo_hash, proof);
-  } else {
-    // Secure QUIC: clear existing proof as we have been sent a new SCFG
-    // without matching proof/certs.
-    cached->ClearProof();
-
-    if (has_proof && !has_cert) {
-      *error_details = "Certificate missing";
-      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-    }
-
-    if (!has_proof && has_cert) {
-      *error_details = "Proof missing";
-      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-    }
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
-    const CryptoHandshakeMessage& rej, QuicWallTime now,
-    const QuicTransportVersion version, absl::string_view chlo_hash,
-    CachedState* cached,
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        out_params,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-
-  if (rej.tag() != kREJ) {
-    *error_details = "Message is not REJ";
-    return QUIC_CRYPTO_INTERNAL_ERROR;
-  }
-
-  QuicErrorCode error =
-      CacheNewServerConfig(rej, now, version, chlo_hash,
-                           out_params->cached_certs, cached, error_details);
-  if (error != QUIC_NO_ERROR) {
-    return error;
-  }
-
-  absl::string_view nonce;
-  if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
-    out_params->server_nonce = std::string(nonce);
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
-    const CryptoHandshakeMessage& server_hello,
-    QuicConnectionId /*connection_id*/, ParsedQuicVersion version,
-    const ParsedQuicVersionVector& negotiated_versions, CachedState* cached,
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        out_params,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-
-  QuicErrorCode valid = CryptoUtils::ValidateServerHello(
-      server_hello, negotiated_versions, error_details);
-  if (valid != QUIC_NO_ERROR) {
-    return valid;
-  }
-
-  // Learn about updated source address tokens.
-  absl::string_view token;
-  if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) {
-    cached->set_source_address_token(token);
-  }
-
-  absl::string_view shlo_nonce;
-  if (!server_hello.GetStringPiece(kServerNonceTag, &shlo_nonce)) {
-    *error_details = "server hello missing server nonce";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  // TODO(agl):
-  //   learn about updated SCFGs.
-
-  absl::string_view public_value;
-  if (!server_hello.GetStringPiece(kPUBS, &public_value)) {
-    *error_details = "server hello missing forward secure public value";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  if (!out_params->client_key_exchange->CalculateSharedKeySync(
-          public_value, &out_params->forward_secure_premaster_secret)) {
-    *error_details = "Key exchange failure";
-    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
-  }
-
-  std::string hkdf_input;
-  const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
-  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
-  hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len);
-  hkdf_input.append(out_params->hkdf_input_suffix);
-
-  if (!CryptoUtils::DeriveKeys(
-          version, out_params->forward_secure_premaster_secret,
-          out_params->aead, out_params->client_nonce,
-          shlo_nonce.empty() ? out_params->server_nonce : shlo_nonce,
-          pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
-          CryptoUtils::Diversification::Never(),
-          &out_params->forward_secure_crypters, &out_params->subkey_secret)) {
-    *error_details = "Symmetric key setup failed";
-    return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate(
-    const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
-    const QuicTransportVersion version, absl::string_view chlo_hash,
-    CachedState* cached,
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        out_params,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-
-  if (server_config_update.tag() != kSCUP) {
-    *error_details = "ServerConfigUpdate must have kSCUP tag.";
-    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
-  }
-  return CacheNewServerConfig(server_config_update, now, version, chlo_hash,
-                              out_params->cached_certs, cached, error_details);
-}
-
-ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
-  return proof_verifier_.get();
-}
-
-SessionCache* QuicCryptoClientConfig::session_cache() const {
-  return session_cache_.get();
-}
-
-ClientProofSource* QuicCryptoClientConfig::proof_source() const {
-  return proof_source_.get();
-}
-
-void QuicCryptoClientConfig::set_proof_source(
-    std::unique_ptr<ClientProofSource> proof_source) {
-  proof_source_ = std::move(proof_source);
-}
-
-SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const {
-  return ssl_ctx_.get();
-}
-
-void QuicCryptoClientConfig::InitializeFrom(
-    const QuicServerId& server_id,
-    const QuicServerId& canonical_server_id,
-    QuicCryptoClientConfig* canonical_crypto_config) {
-  CachedState* canonical_cached =
-      canonical_crypto_config->LookupOrCreate(canonical_server_id);
-  if (!canonical_cached->proof_valid()) {
-    return;
-  }
-  CachedState* cached = LookupOrCreate(server_id);
-  cached->InitializeFrom(*canonical_cached);
-}
-
-void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) {
-  canonical_suffixes_.push_back(suffix);
-}
-
-bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
-    const QuicServerId& server_id, CachedState* cached) {
-  QUICHE_DCHECK(cached->IsEmpty());
-  size_t i = 0;
-  for (; i < canonical_suffixes_.size(); ++i) {
-    if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) {
-      break;
-    }
-  }
-  if (i == canonical_suffixes_.size()) {
-    return false;
-  }
-
-  QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
-                                server_id.privacy_mode_enabled());
-  auto it = canonical_server_map_.lower_bound(suffix_server_id);
-  if (it == canonical_server_map_.end() || it->first != suffix_server_id) {
-    // This is the first host we've seen which matches the suffix, so make it
-    // canonical.  Use |it| as position hint for faster insertion.
-    canonical_server_map_.insert(
-        it, std::make_pair(std::move(suffix_server_id), std::move(server_id)));
-    return false;
-  }
-
-  const QuicServerId& canonical_server_id = it->second;
-  CachedState* canonical_state = cached_states_[canonical_server_id].get();
-  if (!canonical_state->proof_valid()) {
-    return false;
-  }
-
-  // Update canonical version to point at the "most recent" entry.
-  it->second = server_id;
-
-  cached->InitializeFrom(*canonical_state);
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_crypto_client_config.h b/quic/core/crypto/quic_crypto_client_config.h
deleted file mode 100644
index 16e1475..0000000
--- a/quic/core/crypto/quic_crypto_client_config.h
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/client_proof_source.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_reference_counted.h"
-
-namespace quic {
-
-class CryptoHandshakeMessage;
-class ProofVerifier;
-class ProofVerifyDetails;
-class QuicRandom;
-
-// QuicResumptionState stores the state a client needs for performing connection
-// resumption.
-struct QUIC_EXPORT_PRIVATE QuicResumptionState {
-  // |tls_session| holds the cryptographic state necessary for a resumption. It
-  // includes the ALPN negotiated on the connection where the ticket was
-  // received.
-  bssl::UniquePtr<SSL_SESSION> tls_session;
-
-  // If the application using QUIC doesn't support 0-RTT handshakes or the
-  // client didn't receive a 0-RTT capable session ticket from the server,
-  // |transport_params| will be null. Otherwise, it will contain the transport
-  // parameters received from the server on the original connection.
-  std::unique_ptr<TransportParameters> transport_params = nullptr;
-
-  // If |transport_params| is null, then |application_state| is ignored and
-  // should be empty. |application_state| contains serialized state that the
-  // client received from the server at the application layer that the client
-  // needs to remember when performing a 0-RTT handshake.
-  std::unique_ptr<ApplicationState> application_state = nullptr;
-
-  // Opaque token received in NEW_TOKEN frame if any.
-  std::string token;
-};
-
-// SessionCache is an interface for managing storing and retrieving
-// QuicResumptionState structs.
-class QUIC_EXPORT_PRIVATE SessionCache {
- public:
-  virtual ~SessionCache() {}
-
-  // Inserts |session|, |params|, and |application_states| into the cache, keyed
-  // by |server_id|. Insert is first called after all three values are present.
-  // The ownership of |session| is transferred to the cache, while other two are
-  // copied. Multiple sessions might need to be inserted for a connection.
-  // SessionCache implementations should support storing
-  // multiple entries per server ID.
-  virtual void Insert(const QuicServerId& server_id,
-                      bssl::UniquePtr<SSL_SESSION> session,
-                      const TransportParameters& params,
-                      const ApplicationState* application_state) = 0;
-
-  // Lookup is called once at the beginning of each TLS handshake to potentially
-  // provide the saved state both for the TLS handshake and for sending 0-RTT
-  // data (if supported). Lookup may return a nullptr. Implementations should
-  // delete cache entries after returning them in Lookup so that session tickets
-  // are used only once.
-  virtual std::unique_ptr<QuicResumptionState> Lookup(
-      const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* ctx) = 0;
-
-  // Called when 0-RTT is rejected. Disables early data for all the TLS tickets
-  // associated with |server_id|.
-  virtual void ClearEarlyData(const QuicServerId& server_id) = 0;
-
-  // Called when NEW_TOKEN frame is received.
-  virtual void OnNewTokenReceived(const QuicServerId& server_id,
-                                  absl::string_view token) = 0;
-
-  // Called to remove expired entries.
-  virtual void RemoveExpiredEntries(QuicWallTime now) = 0;
-
-  // Clear the session cache.
-  virtual void Clear() = 0;
-};
-
-// QuicCryptoClientConfig contains crypto-related configuration settings for a
-// client. Note that this object isn't thread-safe. It's designed to be used on
-// a single thread at a time.
-class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
- public:
-  // A CachedState contains the information that the client needs in order to
-  // perform a 0-RTT handshake with a server. This information can be reused
-  // over several connections to the same server.
-  class QUIC_EXPORT_PRIVATE CachedState {
-   public:
-    // Enum to track if the server config is valid or not. If it is not valid,
-    // it specifies why it is invalid.
-    enum ServerConfigState {
-      // WARNING: Do not change the numerical values of any of server config
-      // state. Do not remove deprecated server config states - just comment
-      // them as deprecated.
-      SERVER_CONFIG_EMPTY = 0,
-      SERVER_CONFIG_INVALID = 1,
-      SERVER_CONFIG_CORRUPTED = 2,
-      SERVER_CONFIG_EXPIRED = 3,
-      SERVER_CONFIG_INVALID_EXPIRY = 4,
-      SERVER_CONFIG_VALID = 5,
-      // NOTE: Add new server config states only immediately above this line.
-      // Make sure to update the QuicServerConfigState enum in
-      // tools/metrics/histograms/histograms.xml accordingly.
-      SERVER_CONFIG_COUNT
-    };
-
-    CachedState();
-    CachedState(const CachedState&) = delete;
-    CachedState& operator=(const CachedState&) = delete;
-    ~CachedState();
-
-    // IsComplete returns true if this object contains enough information to
-    // perform a handshake with the server. |now| is used to judge whether any
-    // cached server config has expired.
-    bool IsComplete(QuicWallTime now) const;
-
-    // IsEmpty returns true if |server_config_| is empty.
-    bool IsEmpty() const;
-
-    // GetServerConfig returns the parsed contents of |server_config|, or
-    // nullptr if |server_config| is empty. The return value is owned by this
-    // object and is destroyed when this object is.
-    const CryptoHandshakeMessage* GetServerConfig() const;
-
-    // SetServerConfig checks that |server_config| parses correctly and stores
-    // it in |server_config_|. |now| is used to judge whether |server_config|
-    // has expired.
-    ServerConfigState SetServerConfig(absl::string_view server_config,
-                                      QuicWallTime now,
-                                      QuicWallTime expiry_time,
-                                      std::string* error_details);
-
-    // InvalidateServerConfig clears the cached server config (if any).
-    void InvalidateServerConfig();
-
-    // SetProof stores a cert chain, cert signed timestamp and signature.
-    void SetProof(const std::vector<std::string>& certs,
-                  absl::string_view cert_sct,
-                  absl::string_view chlo_hash,
-                  absl::string_view signature);
-
-    // Clears all the data.
-    void Clear();
-
-    // Clears the certificate chain and signature and invalidates the proof.
-    void ClearProof();
-
-    // SetProofValid records that the certificate chain and signature have been
-    // validated and that it's safe to assume that the server is legitimate.
-    // (Note: this does not check the chain or signature.)
-    void SetProofValid();
-
-    // If the server config or the proof has changed then it needs to be
-    // revalidated. Helper function to keep server_config_valid_ and
-    // generation_counter_ in sync.
-    void SetProofInvalid();
-
-    const std::string& server_config() const;
-    const std::string& source_address_token() const;
-    const std::vector<std::string>& certs() const;
-    const std::string& cert_sct() const;
-    const std::string& chlo_hash() const;
-    const std::string& signature() const;
-    bool proof_valid() const;
-    uint64_t generation_counter() const;
-    const ProofVerifyDetails* proof_verify_details() const;
-
-    void set_source_address_token(absl::string_view token);
-
-    void set_cert_sct(absl::string_view cert_sct);
-
-    // SetProofVerifyDetails takes ownership of |details|.
-    void SetProofVerifyDetails(ProofVerifyDetails* details);
-
-    // Copy the |server_config_|, |source_address_token_|, |certs_|,
-    // |expiration_time_|, |cert_sct_|, |chlo_hash_| and |server_config_sig_|
-    // from the |other|.  The remaining fields, |generation_counter_|,
-    // |proof_verify_details_|, and |scfg_| remain unchanged.
-    void InitializeFrom(const CachedState& other);
-
-    // Initializes this cached state based on the arguments provided.
-    // Returns false if there is a problem parsing the server config.
-    bool Initialize(absl::string_view server_config,
-                    absl::string_view source_address_token,
-                    const std::vector<std::string>& certs,
-                    const std::string& cert_sct,
-                    absl::string_view chlo_hash,
-                    absl::string_view signature,
-                    QuicWallTime now,
-                    QuicWallTime expiration_time);
-
-   private:
-    std::string server_config_;         // A serialized handshake message.
-    std::string source_address_token_;  // An opaque proof of IP ownership.
-    std::vector<std::string> certs_;    // A list of certificates in leaf-first
-                                        // order.
-    std::string cert_sct_;              // Signed timestamp of the leaf cert.
-    std::string chlo_hash_;             // Hash of the CHLO message.
-    std::string server_config_sig_;     // A signature of |server_config_|.
-    bool server_config_valid_;          // True if |server_config_| is correctly
-                                // signed and |certs_| has been validated.
-    QuicWallTime expiration_time_;  // Time when the config is no longer valid.
-    // Generation counter associated with the |server_config_|, |certs_| and
-    // |server_config_sig_| combination. It is incremented whenever we set
-    // server_config_valid_ to false.
-    uint64_t generation_counter_;
-
-    std::unique_ptr<ProofVerifyDetails> proof_verify_details_;
-
-    // scfg contains the cached, parsed value of |server_config|.
-    mutable std::unique_ptr<CryptoHandshakeMessage> scfg_;
-  };
-
-  // Used to filter server ids for partial config deletion.
-  class QUIC_EXPORT_PRIVATE ServerIdFilter {
-   public:
-    virtual ~ServerIdFilter() {}
-
-    // Returns true if |server_id| matches the filter.
-    virtual bool Matches(const QuicServerId& server_id) const = 0;
-  };
-
-  // DEPRECATED: Use the constructor below instead.
-  explicit QuicCryptoClientConfig(
-      std::unique_ptr<ProofVerifier> proof_verifier);
-  QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier,
-                         std::unique_ptr<SessionCache> session_cache);
-  QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete;
-  QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete;
-  ~QuicCryptoClientConfig();
-
-  // LookupOrCreate returns a CachedState for the given |server_id|. If no such
-  // CachedState currently exists, it will be created and cached.
-  CachedState* LookupOrCreate(const QuicServerId& server_id);
-
-  // Delete CachedState objects whose server ids match |filter| from
-  // cached_states.
-  void ClearCachedStates(const ServerIdFilter& filter);
-
-  // FillInchoateClientHello sets |out| to be a CHLO message that elicits a
-  // source-address token or SCFG from a server. If |cached| is non-nullptr, the
-  // source-address token will be taken from it. |out_params| is used in order
-  // to store the cached certs that were sent as hints to the server in
-  // |out_params->cached_certs|. |preferred_version| is the version of the
-  // QUIC protocol that this client chose to use initially. This allows the
-  // server to detect downgrade attacks.  If |demand_x509_proof| is true,
-  // then |out| will include an X509 proof demand, and the associated
-  // certificate related fields.
-  void FillInchoateClientHello(
-      const QuicServerId& server_id, const ParsedQuicVersion preferred_version,
-      const CachedState* cached, QuicRandom* rand, bool demand_x509_proof,
-      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-          out_params,
-      CryptoHandshakeMessage* out) const;
-
-  // FillClientHello sets |out| to be a CHLO message based on the configuration
-  // of this object. This object must have cached enough information about
-  // the server's hostname in order to perform a handshake. This can be checked
-  // with the |IsComplete| member of |CachedState|.
-  //
-  // |now| and |rand| are used to generate the nonce and |out_params| is
-  // filled with the results of the handshake that the server is expected to
-  // accept. |preferred_version| is the version of the QUIC protocol that this
-  // client chose to use initially. This allows the server to detect downgrade
-  // attacks.
-  //
-  // If |channel_id_key| is not null, it is used to sign a secret value derived
-  // from the client and server's keys, and the Channel ID public key and the
-  // signature are placed in the CETV value of the CHLO.
-  QuicErrorCode FillClientHello(
-      const QuicServerId& server_id, QuicConnectionId connection_id,
-      const ParsedQuicVersion preferred_version,
-      const ParsedQuicVersion actual_version, const CachedState* cached,
-      QuicWallTime now, QuicRandom* rand,
-      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-          out_params,
-      CryptoHandshakeMessage* out, std::string* error_details) const;
-
-  // ProcessRejection processes a REJ message from a server and updates the
-  // cached information about that server. After this, |IsComplete| may return
-  // true for that server's CachedState. If the rejection message contains state
-  // about a future handshake (i.e. an nonce value from the server), then it
-  // will be saved in |out_params|. |now| is used to judge whether the server
-  // config in the rejection message has expired.
-  QuicErrorCode ProcessRejection(
-      const CryptoHandshakeMessage& rej, QuicWallTime now,
-      QuicTransportVersion version, absl::string_view chlo_hash,
-      CachedState* cached,
-      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-          out_params,
-      std::string* error_details);
-
-  // ProcessServerHello processes the message in |server_hello|, updates the
-  // cached information about that server, writes the negotiated parameters to
-  // |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable
-  // then it puts an error message in |error_details| and returns an error
-  // code. |version| is the QUIC version for the current connection.
-  // |negotiated_versions| contains the list of version, if any, that were
-  // present in a version negotiation packet previously received from the
-  // server. The contents of this list will be compared against the list of
-  // versions provided in the VER tag of the server hello.
-  QuicErrorCode ProcessServerHello(
-      const CryptoHandshakeMessage& server_hello,
-      QuicConnectionId connection_id, ParsedQuicVersion version,
-      const ParsedQuicVersionVector& negotiated_versions, CachedState* cached,
-      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-          out_params,
-      std::string* error_details);
-
-  // Processes the message in |server_config_update|, updating the cached source
-  // address token, and server config.
-  // If |server_config_update| is invalid then |error_details| will contain an
-  // error message, and an error code will be returned. If all has gone well
-  // QUIC_NO_ERROR is returned.
-  QuicErrorCode ProcessServerConfigUpdate(
-      const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
-      const QuicTransportVersion version, absl::string_view chlo_hash,
-      CachedState* cached,
-      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-          out_params,
-      std::string* error_details);
-
-  ProofVerifier* proof_verifier() const;
-  SessionCache* session_cache() const;
-  ClientProofSource* proof_source() const;
-  void set_proof_source(std::unique_ptr<ClientProofSource> proof_source);
-  SSL_CTX* ssl_ctx() const;
-
-  // Initialize the CachedState from |canonical_crypto_config| for the
-  // |canonical_server_id| as the initial CachedState for |server_id|. We will
-  // copy config data only if |canonical_crypto_config| has valid proof.
-  void InitializeFrom(const QuicServerId& server_id,
-                      const QuicServerId& canonical_server_id,
-                      QuicCryptoClientConfig* canonical_crypto_config);
-
-  // Adds |suffix| as a domain suffix for which the server's crypto config
-  // is expected to be shared among servers with the domain suffix. If a server
-  // matches this suffix, then the server config from another server with the
-  // suffix will be used to initialize the cached state for this server.
-  void AddCanonicalSuffix(const std::string& suffix);
-
-  // Saves the |user_agent_id| that will be passed in QUIC's CHLO message.
-  void set_user_agent_id(const std::string& user_agent_id) {
-    user_agent_id_ = user_agent_id;
-  }
-
-  // Returns the user_agent_id that will be provided in the client hello
-  // handshake message.
-  const std::string& user_agent_id() const { return user_agent_id_; }
-
-  void set_tls_signature_algorithms(std::string signature_algorithms) {
-    tls_signature_algorithms_ = std::move(signature_algorithms);
-  }
-
-  const absl::optional<std::string>& tls_signature_algorithms() const {
-    return tls_signature_algorithms_;
-  }
-
-  // Saves the |alpn| that will be passed in QUIC's CHLO message.
-  void set_alpn(const std::string& alpn) { alpn_ = alpn; }
-
-  // Saves the pre-shared key used during the handshake.
-  void set_pre_shared_key(absl::string_view psk) {
-    pre_shared_key_ = std::string(psk);
-  }
-
-  // Returns the pre-shared key used during the handshake.
-  const std::string& pre_shared_key() const { return pre_shared_key_; }
-
-  bool pad_inchoate_hello() const { return pad_inchoate_hello_; }
-  void set_pad_inchoate_hello(bool new_value) {
-    pad_inchoate_hello_ = new_value;
-  }
-
-  bool pad_full_hello() const { return pad_full_hello_; }
-  void set_pad_full_hello(bool new_value) { pad_full_hello_ = new_value; }
-
-  SessionCache* mutable_session_cache() { return session_cache_.get(); }
-
- private:
-  // Sets the members to reasonable, default values.
-  void SetDefaults();
-
-  // CacheNewServerConfig checks for SCFG, STK, PROF, and CRT tags in |message|,
-  // verifies them, and stores them in the cached state if they validate.
-  // This is used on receipt of a REJ from a server, or when a server sends
-  // updated server config during a connection.
-  QuicErrorCode CacheNewServerConfig(
-      const CryptoHandshakeMessage& message,
-      QuicWallTime now,
-      QuicTransportVersion version,
-      absl::string_view chlo_hash,
-      const std::vector<std::string>& cached_certs,
-      CachedState* cached,
-      std::string* error_details);
-
-  // If the suffix of the hostname in |server_id| is in |canonical_suffixes_|,
-  // then populate |cached| with the canonical cached state from
-  // |canonical_server_map_| for that suffix. Returns true if |cached| is
-  // initialized with canonical cached state.
-  bool PopulateFromCanonicalConfig(const QuicServerId& server_id,
-                                   CachedState* cached);
-
-  // cached_states_ maps from the server_id to the cached information about
-  // that server.
-  std::map<QuicServerId, std::unique_ptr<CachedState>> cached_states_;
-
-  // Contains a map of servers which could share the same server config. Map
-  // from a canonical host suffix/port/scheme to a representative server with
-  // the canonical suffix, which has a plausible set of initial certificates
-  // (or at least server public key).
-  std::map<QuicServerId, QuicServerId> canonical_server_map_;
-
-  // Contains list of suffixes (for exmaple ".c.youtube.com",
-  // ".googlevideo.com") of canonical hostnames.
-  std::vector<std::string> canonical_suffixes_;
-
-  std::unique_ptr<ProofVerifier> proof_verifier_;
-  std::unique_ptr<SessionCache> session_cache_;
-  std::unique_ptr<ClientProofSource> proof_source_;
-
-  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-
-  // The |user_agent_id_| passed in QUIC's CHLO message.
-  std::string user_agent_id_;
-
-  // The |alpn_| passed in QUIC's CHLO message.
-  std::string alpn_;
-
-  // If non-empty, the client will operate in the pre-shared key mode by
-  // incorporating |pre_shared_key_| into the key schedule.
-  std::string pre_shared_key_;
-
-  // If set, configure the client to use the specified signature algorithms, via
-  // SSL_set1_sigalgs_list. TLS only.
-  absl::optional<std::string> tls_signature_algorithms_;
-
-  // In QUIC, technically, client hello should be fully padded.
-  // However, fully padding on slow network connection (e.g. 50kbps) can add
-  // 150ms latency to one roundtrip. Therefore, you can disable padding of
-  // individual messages. It is recommend to leave at least one message in
-  // each direction fully padded (e.g. full CHLO and SHLO), but if you know
-  // the lower-bound MTU, you don't need to pad all of them (keep in mind that
-  // it's not OK to do it according to the standard).
-  //
-  // Also, if you disable padding, you must disable (change) the
-  // anti-amplification protection. You should only do so if you have some
-  // other means of verifying the client.
-  bool pad_inchoate_hello_ = true;
-  bool pad_full_hello_ = true;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
diff --git a/quic/core/crypto/quic_crypto_client_config_test.cc b/quic/core/crypto/quic_crypto_client_config_test.cc
deleted file mode 100644
index a1f1562..0000000
--- a/quic/core/crypto/quic_crypto_client_config_test.cc
+++ /dev/null
@@ -1,550 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::StartsWith;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestProofVerifyDetails : public ProofVerifyDetails {
-  ~TestProofVerifyDetails() override {}
-
-  // ProofVerifyDetails implementation
-  ProofVerifyDetails* Clone() const override {
-    return new TestProofVerifyDetails;
-  }
-};
-
-class OneServerIdFilter : public QuicCryptoClientConfig::ServerIdFilter {
- public:
-  explicit OneServerIdFilter(const QuicServerId* server_id)
-      : server_id_(*server_id) {}
-
-  bool Matches(const QuicServerId& server_id) const override {
-    return server_id == server_id_;
-  }
-
- private:
-  const QuicServerId server_id_;
-};
-
-class AllServerIdsFilter : public QuicCryptoClientConfig::ServerIdFilter {
- public:
-  bool Matches(const QuicServerId& /*server_id*/) const override {
-    return true;
-  }
-};
-
-}  // namespace
-
-class QuicCryptoClientConfigTest : public QuicTest {};
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_IsEmpty) {
-  QuicCryptoClientConfig::CachedState state;
-  EXPECT_TRUE(state.IsEmpty());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_IsComplete) {
-  QuicCryptoClientConfig::CachedState state;
-  EXPECT_FALSE(state.IsComplete(QuicWallTime::FromUNIXSeconds(0)));
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_GenerationCounter) {
-  QuicCryptoClientConfig::CachedState state;
-  EXPECT_EQ(0u, state.generation_counter());
-  state.SetProofInvalid();
-  EXPECT_EQ(1u, state.generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) {
-  QuicCryptoClientConfig::CachedState state;
-  EXPECT_TRUE(state.proof_verify_details() == nullptr);
-  ProofVerifyDetails* details = new TestProofVerifyDetails;
-  state.SetProofVerifyDetails(details);
-  EXPECT_EQ(details, state.proof_verify_details());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
-  QuicCryptoClientConfig::CachedState state;
-  QuicCryptoClientConfig::CachedState other;
-  state.set_source_address_token("TOKEN");
-  // TODO(rch): Populate other fields of |state|.
-  other.InitializeFrom(state);
-  EXPECT_EQ(state.server_config(), other.server_config());
-  EXPECT_EQ(state.source_address_token(), other.source_address_token());
-  EXPECT_EQ(state.certs(), other.certs());
-  EXPECT_EQ(1u, other.generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
-  QuicCryptoClientConfig::CachedState state;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  config.set_user_agent_id("quic-tester");
-  config.set_alpn("hq");
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  CryptoHandshakeMessage msg;
-  QuicServerId server_id("www.google.com", 443, false);
-  MockRandom rand;
-  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
-                                 /* demand_x509_proof= */ true, params, &msg);
-
-  QuicVersionLabel cver;
-  EXPECT_THAT(msg.GetVersionLabel(kVER, &cver), IsQuicNoError());
-  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
-  absl::string_view proof_nonce;
-  EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce));
-  EXPECT_EQ(std::string(32, 'r'), proof_nonce);
-  absl::string_view user_agent_id;
-  EXPECT_TRUE(msg.GetStringPiece(kUAID, &user_agent_id));
-  EXPECT_EQ("quic-tester", user_agent_id);
-  absl::string_view alpn;
-  EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn));
-  EXPECT_EQ("hq", alpn);
-  EXPECT_EQ(msg.minimum_size(), 1u);
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloIsNotPadded) {
-  QuicCryptoClientConfig::CachedState state;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  config.set_pad_inchoate_hello(false);
-  config.set_user_agent_id("quic-tester");
-  config.set_alpn("hq");
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  CryptoHandshakeMessage msg;
-  QuicServerId server_id("www.google.com", 443, false);
-  MockRandom rand;
-  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
-                                 /* demand_x509_proof= */ true, params, &msg);
-
-  EXPECT_EQ(msg.minimum_size(), 1u);
-}
-
-// Make sure AES-GCM is the preferred encryption algorithm if it has hardware
-// acceleration.
-TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  if (EVP_has_aes_hardware() == 1) {
-    EXPECT_EQ(kAESG, config.aead[0]);
-  } else {
-    EXPECT_EQ(kCC20, config.aead[0]);
-  }
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) {
-  QuicCryptoClientConfig::CachedState state;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  CryptoHandshakeMessage msg;
-  QuicServerId server_id("www.google.com", 443, false);
-  MockRandom rand;
-  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
-                                 /* demand_x509_proof= */ true, params, &msg);
-
-  QuicTag pdmd;
-  EXPECT_THAT(msg.GetUint32(kPDMD, &pdmd), IsQuicNoError());
-  EXPECT_EQ(kX509, pdmd);
-  absl::string_view scid;
-  EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid));
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) {
-  // Test that a config with no EXPY is still valid when a non-zero
-  // expiry time is passed in.
-  QuicCryptoClientConfig::CachedState state;
-  CryptoHandshakeMessage scfg;
-  scfg.set_tag(kSCFG);
-  scfg.SetStringPiece(kSCID, "12345678");
-  std::string details;
-  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
-  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
-  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
-                        &details);
-  EXPECT_FALSE(state.IsEmpty());
-
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  CryptoHandshakeMessage msg;
-  QuicServerId server_id("www.google.com", 443, false);
-  MockRandom rand;
-  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
-                                 /* demand_x509_proof= */ true, params, &msg);
-
-  absl::string_view scid;
-  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
-  EXPECT_EQ("12345678", scid);
-}
-
-TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
-  QuicCryptoClientConfig::CachedState state;
-  CryptoHandshakeMessage scfg;
-  scfg.set_tag(kSCFG);
-  uint64_t future = 1;
-  scfg.SetValue(kEXPY, future);
-  scfg.SetStringPiece(kSCID, "12345678");
-  std::string details;
-  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(),
-                        QuicWallTime::FromUNIXSeconds(1),
-                        QuicWallTime::FromUNIXSeconds(0), &details);
-  EXPECT_FALSE(state.IsEmpty());
-
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  CryptoHandshakeMessage msg;
-  QuicServerId server_id("www.google.com", 443, false);
-  MockRandom rand;
-  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
-                                 /* demand_x509_proof= */ true, params, &msg);
-
-  absl::string_view scid;
-  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
-  EXPECT_EQ("12345678", scid);
-}
-
-TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
-  QuicCryptoClientConfig::CachedState state;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  QuicConnectionId kConnectionId = TestConnectionId(1234);
-  std::string error_details;
-  MockRandom rand;
-  CryptoHandshakeMessage chlo;
-  QuicServerId server_id("www.google.com", 443, false);
-  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
-                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
-                         params, &chlo, &error_details);
-
-  // Verify that the version label has been set correctly in the CHLO.
-  QuicVersionLabel cver;
-  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
-  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
-}
-
-TEST_F(QuicCryptoClientConfigTest, FillClientHelloNoPadding) {
-  QuicCryptoClientConfig::CachedState state;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  config.set_pad_full_hello(false);
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
-      new QuicCryptoNegotiatedParameters);
-  QuicConnectionId kConnectionId = TestConnectionId(1234);
-  std::string error_details;
-  MockRandom rand;
-  CryptoHandshakeMessage chlo;
-  QuicServerId server_id("www.google.com", 443, false);
-  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
-                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
-                         params, &chlo, &error_details);
-
-  // Verify that the version label has been set correctly in the CHLO.
-  QuicVersionLabel cver;
-  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
-  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
-  EXPECT_EQ(chlo.minimum_size(), 1u);
-}
-
-TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
-  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
-  if (supported_versions.size() == 1) {
-    // No downgrade attack is possible if the client only supports one version.
-    return;
-  }
-
-  ParsedQuicVersionVector supported_version_vector;
-  for (size_t i = supported_versions.size(); i > 0; --i) {
-    supported_version_vector.push_back(supported_versions[i - 1]);
-  }
-
-  CryptoHandshakeMessage msg;
-  msg.set_tag(kSHLO);
-  msg.SetVersionVector(kVER, supported_version_vector);
-
-  QuicCryptoClientConfig::CachedState cached;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      out_params(new QuicCryptoNegotiatedParameters);
-  std::string error;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  EXPECT_THAT(config.ProcessServerHello(
-                  msg, EmptyQuicConnectionId(), supported_versions.front(),
-                  supported_versions, &cached, out_params, &error),
-              IsError(QUIC_VERSION_NEGOTIATION_MISMATCH));
-  EXPECT_THAT(error, StartsWith("Downgrade attack detected: ServerVersions"));
-}
-
-TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  QuicServerId canonical_server_id("www.google.com", 443, false);
-  QuicCryptoClientConfig::CachedState* state =
-      config.LookupOrCreate(canonical_server_id);
-  // TODO(rch): Populate other fields of |state|.
-  state->set_source_address_token("TOKEN");
-  state->SetProofValid();
-
-  QuicServerId other_server_id("mail.google.com", 443, false);
-  config.InitializeFrom(other_server_id, canonical_server_id, &config);
-  QuicCryptoClientConfig::CachedState* other =
-      config.LookupOrCreate(other_server_id);
-
-  EXPECT_EQ(state->server_config(), other->server_config());
-  EXPECT_EQ(state->source_address_token(), other->source_address_token());
-  EXPECT_EQ(state->certs(), other->certs());
-  EXPECT_EQ(1u, other->generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, Canonical) {
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  config.AddCanonicalSuffix(".google.com");
-  QuicServerId canonical_id1("www.google.com", 443, false);
-  QuicServerId canonical_id2("mail.google.com", 443, false);
-  QuicCryptoClientConfig::CachedState* state =
-      config.LookupOrCreate(canonical_id1);
-  // TODO(rch): Populate other fields of |state|.
-  state->set_source_address_token("TOKEN");
-  state->SetProofValid();
-
-  QuicCryptoClientConfig::CachedState* other =
-      config.LookupOrCreate(canonical_id2);
-
-  EXPECT_TRUE(state->IsEmpty());
-  EXPECT_EQ(state->server_config(), other->server_config());
-  EXPECT_EQ(state->source_address_token(), other->source_address_token());
-  EXPECT_EQ(state->certs(), other->certs());
-  EXPECT_EQ(1u, other->generation_counter());
-
-  QuicServerId different_id("mail.google.org", 443, false);
-  EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  config.AddCanonicalSuffix(".google.com");
-  QuicServerId canonical_id1("www.google.com", 443, false);
-  QuicServerId canonical_id2("mail.google.com", 443, false);
-  QuicCryptoClientConfig::CachedState* state =
-      config.LookupOrCreate(canonical_id1);
-  // TODO(rch): Populate other fields of |state|.
-  state->set_source_address_token("TOKEN");
-
-  // Do not set the proof as valid, and check that it is not used
-  // as a canonical entry.
-  EXPECT_TRUE(config.LookupOrCreate(canonical_id2)->IsEmpty());
-}
-
-TEST_F(QuicCryptoClientConfigTest, ClearCachedStates) {
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-
-  // Create two states on different origins.
-  struct TestCase {
-    TestCase(const std::string& host, QuicCryptoClientConfig* config)
-        : server_id(host, 443, false),
-          state(config->LookupOrCreate(server_id)) {
-      // TODO(rch): Populate other fields of |state|.
-      CryptoHandshakeMessage scfg;
-      scfg.set_tag(kSCFG);
-      uint64_t future = 1;
-      scfg.SetValue(kEXPY, future);
-      scfg.SetStringPiece(kSCID, "12345678");
-      std::string details;
-      state->SetServerConfig(scfg.GetSerialized().AsStringPiece(),
-                             QuicWallTime::FromUNIXSeconds(0),
-                             QuicWallTime::FromUNIXSeconds(future), &details);
-
-      std::vector<std::string> certs(1);
-      certs[0] = "Hello Cert for " + host;
-      state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
-      state->set_source_address_token("TOKEN");
-      state->SetProofValid();
-
-      // The generation counter starts at 2, because proof has been once
-      // invalidated in SetServerConfig().
-      EXPECT_EQ(2u, state->generation_counter());
-    }
-
-    QuicServerId server_id;
-    QuicCryptoClientConfig::CachedState* state;
-  } test_cases[] = {TestCase("www.google.com", &config),
-                    TestCase("www.example.com", &config)};
-
-  // Verify LookupOrCreate returns the same data.
-  for (const TestCase& test_case : test_cases) {
-    QuicCryptoClientConfig::CachedState* other =
-        config.LookupOrCreate(test_case.server_id);
-    EXPECT_EQ(test_case.state, other);
-    EXPECT_EQ(2u, other->generation_counter());
-  }
-
-  // Clear the cached state for www.google.com.
-  OneServerIdFilter google_com_filter(&test_cases[0].server_id);
-  config.ClearCachedStates(google_com_filter);
-
-  // Verify LookupOrCreate doesn't have any data for google.com.
-  QuicCryptoClientConfig::CachedState* cleared_cache =
-      config.LookupOrCreate(test_cases[0].server_id);
-
-  EXPECT_EQ(test_cases[0].state, cleared_cache);
-  EXPECT_FALSE(cleared_cache->proof_valid());
-  EXPECT_TRUE(cleared_cache->server_config().empty());
-  EXPECT_TRUE(cleared_cache->certs().empty());
-  EXPECT_TRUE(cleared_cache->cert_sct().empty());
-  EXPECT_TRUE(cleared_cache->signature().empty());
-  EXPECT_EQ(3u, cleared_cache->generation_counter());
-
-  // But it still does for www.example.com.
-  QuicCryptoClientConfig::CachedState* existing_cache =
-      config.LookupOrCreate(test_cases[1].server_id);
-
-  EXPECT_EQ(test_cases[1].state, existing_cache);
-  EXPECT_TRUE(existing_cache->proof_valid());
-  EXPECT_FALSE(existing_cache->server_config().empty());
-  EXPECT_FALSE(existing_cache->certs().empty());
-  EXPECT_FALSE(existing_cache->cert_sct().empty());
-  EXPECT_FALSE(existing_cache->signature().empty());
-  EXPECT_EQ(2u, existing_cache->generation_counter());
-
-  // Clear all cached states.
-  AllServerIdsFilter all_server_ids;
-  config.ClearCachedStates(all_server_ids);
-
-  // The data for www.example.com should now be cleared as well.
-  cleared_cache = config.LookupOrCreate(test_cases[1].server_id);
-
-  EXPECT_EQ(test_cases[1].state, cleared_cache);
-  EXPECT_FALSE(cleared_cache->proof_valid());
-  EXPECT_TRUE(cleared_cache->server_config().empty());
-  EXPECT_TRUE(cleared_cache->certs().empty());
-  EXPECT_TRUE(cleared_cache->cert_sct().empty());
-  EXPECT_TRUE(cleared_cache->signature().empty());
-  EXPECT_EQ(3u, cleared_cache->generation_counter());
-}
-
-TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
-  CryptoHandshakeMessage rej;
-  crypto_test_utils::FillInDummyReject(&rej);
-
-  // Now process the rejection.
-  QuicCryptoClientConfig::CachedState cached;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      out_params(new QuicCryptoNegotiatedParameters);
-  std::string error;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  EXPECT_THAT(
-      config.ProcessRejection(
-          rej, QuicWallTime::FromUNIXSeconds(0),
-          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
-          &cached, out_params, &error),
-      IsQuicNoError());
-}
-
-TEST_F(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) {
-  CryptoHandshakeMessage rej;
-  crypto_test_utils::FillInDummyReject(&rej);
-  QuicTime::Delta one_week = QuicTime::Delta::FromSeconds(kNumSecondsPerWeek);
-  int64_t long_ttl = 3 * one_week.ToSeconds();
-  rej.SetValue(kSTTL, long_ttl);
-
-  // Now process the rejection.
-  QuicCryptoClientConfig::CachedState cached;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      out_params(new QuicCryptoNegotiatedParameters);
-  std::string error;
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  EXPECT_THAT(
-      config.ProcessRejection(
-          rej, QuicWallTime::FromUNIXSeconds(0),
-          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
-          &cached, out_params, &error),
-      IsQuicNoError());
-  cached.SetProofValid();
-  EXPECT_FALSE(cached.IsComplete(QuicWallTime::FromUNIXSeconds(long_ttl)));
-  EXPECT_FALSE(
-      cached.IsComplete(QuicWallTime::FromUNIXSeconds(one_week.ToSeconds())));
-  EXPECT_TRUE(cached.IsComplete(
-      QuicWallTime::FromUNIXSeconds(one_week.ToSeconds() - 1)));
-}
-
-TEST_F(QuicCryptoClientConfigTest, ServerNonceinSHLO) {
-  // Test that the server must include a nonce in the SHLO.
-  CryptoHandshakeMessage msg;
-  msg.set_tag(kSHLO);
-  // Choose the latest version.
-  ParsedQuicVersionVector supported_versions;
-  ParsedQuicVersion version = AllSupportedVersions().front();
-  supported_versions.push_back(version);
-  msg.SetVersionVector(kVER, supported_versions);
-
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  QuicCryptoClientConfig::CachedState cached;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      out_params(new QuicCryptoNegotiatedParameters);
-  std::string error_details;
-  EXPECT_THAT(config.ProcessServerHello(msg, EmptyQuicConnectionId(), version,
-                                        supported_versions, &cached, out_params,
-                                        &error_details),
-              IsError(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER));
-  EXPECT_EQ("server hello missing server nonce", error_details);
-}
-
-// Test that PopulateFromCanonicalConfig() handles the case of multiple entries
-// in |canonical_server_map_|.
-TEST_F(QuicCryptoClientConfigTest, MultipleCanonicalEntries) {
-  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
-  config.AddCanonicalSuffix(".google.com");
-  QuicServerId canonical_server_id1("www.google.com", 443, false);
-  QuicCryptoClientConfig::CachedState* state1 =
-      config.LookupOrCreate(canonical_server_id1);
-
-  CryptoHandshakeMessage scfg;
-  scfg.set_tag(kSCFG);
-  scfg.SetStringPiece(kSCID, "12345678");
-  std::string details;
-  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
-  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
-  state1->SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
-                          &details);
-  state1->set_source_address_token("TOKEN");
-  state1->SetProofValid();
-  EXPECT_FALSE(state1->IsEmpty());
-
-  // This will have the same |suffix_server_id| as |canonical_server_id1|,
-  // therefore |*state2| will be initialized from |*state1|.
-  QuicServerId canonical_server_id2("mail.google.com", 443, false);
-  QuicCryptoClientConfig::CachedState* state2 =
-      config.LookupOrCreate(canonical_server_id2);
-  EXPECT_FALSE(state2->IsEmpty());
-  const CryptoHandshakeMessage* const scfg2 = state2->GetServerConfig();
-  ASSERT_TRUE(scfg2);
-  EXPECT_EQ(kSCFG, scfg2->tag());
-
-  // With a different |suffix_server_id|, this will return an empty CachedState.
-  config.AddCanonicalSuffix(".example.com");
-  QuicServerId canonical_server_id3("www.example.com", 443, false);
-  QuicCryptoClientConfig::CachedState* state3 =
-      config.LookupOrCreate(canonical_server_id3);
-  EXPECT_TRUE(state3->IsEmpty());
-  const CryptoHandshakeMessage* const scfg3 = state3->GetServerConfig();
-  EXPECT_FALSE(scfg3);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/quic_crypto_proof.cc b/quic/core/crypto/quic_crypto_proof.cc
deleted file mode 100644
index 1e5f3c4..0000000
--- a/quic/core/crypto/quic_crypto_proof.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypto_proof.h"
-
-namespace quic {
-
-QuicCryptoProof::QuicCryptoProof()
-    : send_expect_ct_header(false), cert_matched_sni(false) {}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_crypto_proof.h b/quic/core/crypto/quic_crypto_proof.h
deleted file mode 100644
index 53e0961..0000000
--- a/quic/core/crypto/quic_crypto_proof.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
-
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Contains the crypto-related data provided by ProofSource
-struct QUIC_EXPORT_PRIVATE QuicCryptoProof {
-  QuicCryptoProof();
-
-  // Signature generated by ProofSource
-  std::string signature;
-  // SCTList (RFC6962) to be sent to the client, if it supports receiving it.
-  std::string leaf_cert_scts;
-  // Should the Expect-CT header be sent on the connection where the
-  // certificate is used.
-  bool send_expect_ct_header;
-  // Did the selected leaf certificate contain a SubjectAltName that included
-  // the requested SNI.
-  bool cert_matched_sni;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
diff --git a/quic/core/crypto/quic_crypto_server_config.cc b/quic/core/crypto/quic_crypto_server_config.cc
deleted file mode 100644
index b4335b9..0000000
--- a/quic/core/crypto/quic_crypto_server_config.cc
+++ /dev/null
@@ -1,1918 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypto_server_config.h"
-
-#include <algorithm>
-#include <cstdlib>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/channel_id.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/curve25519_key_exchange.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/p256_key_exchange.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_hkdf.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/crypto/tls_server_connection.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/proto/source_address_token_proto.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "common/platform/api/quiche_reference_counted.h"
-
-namespace quic {
-
-namespace {
-
-// kMultiplier is the multiple of the CHLO message size that a REJ message
-// must stay under when the client doesn't present a valid source-address
-// token. This is used to protect QUIC from amplification attacks.
-// TODO(rch): Reduce this to 2 again once b/25933682 is fixed.
-const size_t kMultiplier = 3;
-
-const int kMaxTokenAddresses = 4;
-
-std::string DeriveSourceAddressTokenKey(
-    absl::string_view source_address_token_secret) {
-  QuicHKDF hkdf(source_address_token_secret, absl::string_view() /* no salt */,
-                "QUIC source address token key",
-                CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */,
-                0 /* no subkey secret */);
-  return std::string(hkdf.server_write_key());
-}
-
-// Default source for creating KeyExchange objects.
-class DefaultKeyExchangeSource : public KeyExchangeSource {
- public:
-  DefaultKeyExchangeSource() = default;
-  ~DefaultKeyExchangeSource() override = default;
-
-  std::unique_ptr<AsynchronousKeyExchange> Create(
-      std::string /*server_config_id*/,
-      bool /* is_fallback */,
-      QuicTag type,
-      absl::string_view private_key) override {
-    if (private_key.empty()) {
-      QUIC_LOG(WARNING) << "Server config contains key exchange method without "
-                           "corresponding private key of type "
-                        << QuicTagToString(type);
-      return nullptr;
-    }
-
-    std::unique_ptr<SynchronousKeyExchange> ka =
-        CreateLocalSynchronousKeyExchange(type, private_key);
-    if (!ka) {
-      QUIC_LOG(WARNING) << "Failed to create key exchange method of type "
-                        << QuicTagToString(type);
-    }
-    return ka;
-  }
-};
-
-// Returns true if the PDMD field from the client hello demands an X509
-// certificate.
-bool ClientDemandsX509Proof(const CryptoHandshakeMessage& client_hello) {
-  QuicTagVector their_proof_demands;
-
-  if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) {
-    return false;
-  }
-
-  for (const QuicTag tag : their_proof_demands) {
-    if (tag == kX509) {
-      return true;
-    }
-  }
-  return false;
-}
-
-std::string FormatCryptoHandshakeMessageForTrace(
-    const CryptoHandshakeMessage* message) {
-  if (message == nullptr) {
-    return "<null message>";
-  }
-
-  std::string s = QuicTagToString(message->tag());
-
-  // Append the reasons for REJ.
-  if (const auto it = message->tag_value_map().find(kRREJ);
-      it != message->tag_value_map().end()) {
-    const std::string& value = it->second;
-    // The value is a vector of uint32_t(s).
-    if (value.size() % sizeof(uint32_t) == 0) {
-      absl::StrAppend(&s, " RREJ:[");
-      // Append comma-separated list of reasons to |s|.
-      for (size_t j = 0; j < value.size(); j += sizeof(uint32_t)) {
-        uint32_t reason;
-        memcpy(&reason, value.data() + j, sizeof(reason));
-        if (j > 0) {
-          absl::StrAppend(&s, ",");
-        }
-        absl::StrAppend(&s, CryptoUtils::HandshakeFailureReasonToString(
-                                static_cast<HandshakeFailureReason>(reason)));
-      }
-      absl::StrAppend(&s, "]");
-    } else {
-      absl::StrAppendFormat(&s, " RREJ:[unexpected length:%u]", value.size());
-    }
-  }
-
-  return s;
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<KeyExchangeSource> KeyExchangeSource::Default() {
-  return std::make_unique<DefaultKeyExchangeSource>();
-}
-
-class ValidateClientHelloHelper {
- public:
-  // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when
-  // ValidationComplete is called.
-  ValidateClientHelloHelper(
-      quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>
-          result,
-      std::unique_ptr<ValidateClientHelloResultCallback>* done_cb)
-      : result_(std::move(result)), done_cb_(done_cb) {}
-  ValidateClientHelloHelper(const ValidateClientHelloHelper&) = delete;
-  ValidateClientHelloHelper& operator=(const ValidateClientHelloHelper&) =
-      delete;
-
-  ~ValidateClientHelloHelper() {
-    QUIC_BUG_IF(quic_bug_12963_1, done_cb_ != nullptr)
-        << "Deleting ValidateClientHelloHelper with a pending callback.";
-  }
-
-  void ValidationComplete(
-      QuicErrorCode error_code,
-      const char* error_details,
-      std::unique_ptr<ProofSource::Details> proof_source_details) {
-    result_->error_code = error_code;
-    result_->error_details = error_details;
-    (*done_cb_)->Run(std::move(result_), std::move(proof_source_details));
-    DetachCallback();
-  }
-
-  void DetachCallback() {
-    QUIC_BUG_IF(quic_bug_10630_1, done_cb_ == nullptr)
-        << "Callback already detached.";
-    done_cb_ = nullptr;
-  }
-
- private:
-  quiche::QuicheReferenceCountedPointer<
-      ValidateClientHelloResultCallback::Result>
-      result_;
-  std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_;
-};
-
-// static
-const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
-
-ClientHelloInfo::ClientHelloInfo(const QuicIpAddress& in_client_ip,
-                                 QuicWallTime in_now)
-    : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
-
-ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default;
-
-ClientHelloInfo::~ClientHelloInfo() {}
-
-PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {}
-
-PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {}
-
-ValidateClientHelloResultCallback::Result::Result(
-    const CryptoHandshakeMessage& in_client_hello,
-    QuicIpAddress in_client_ip,
-    QuicWallTime in_now)
-    : client_hello(in_client_hello),
-      info(in_client_ip, in_now),
-      error_code(QUIC_NO_ERROR) {}
-
-ValidateClientHelloResultCallback::Result::~Result() {}
-
-ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {}
-
-ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {}
-
-ProcessClientHelloResultCallback::ProcessClientHelloResultCallback() {}
-
-ProcessClientHelloResultCallback::~ProcessClientHelloResultCallback() {}
-
-QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
-    : expiry_time(QuicWallTime::Zero()),
-      channel_id_enabled(false),
-      p256(false) {}
-
-QuicCryptoServerConfig::ConfigOptions::ConfigOptions(
-    const ConfigOptions& other) = default;
-
-QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {}
-
-QuicCryptoServerConfig::ProcessClientHelloContext::
-    ~ProcessClientHelloContext() {
-  if (done_cb_ != nullptr) {
-    QUIC_LOG(WARNING)
-        << "Deleting ProcessClientHelloContext with a pending callback.";
-  }
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloContext::Fail(
-    QuicErrorCode error,
-    const std::string& error_details) {
-  QUIC_TRACEPRINTF("ProcessClientHello failed: error=%s, details=%s",
-                   QuicErrorCodeToString(error), error_details);
-  done_cb_->Run(error, error_details, nullptr, nullptr, nullptr);
-  done_cb_ = nullptr;
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloContext::Succeed(
-    std::unique_ptr<CryptoHandshakeMessage> message,
-    std::unique_ptr<DiversificationNonce> diversification_nonce,
-    std::unique_ptr<ProofSource::Details> proof_source_details) {
-  QUIC_TRACEPRINTF("ProcessClientHello succeeded: %s",
-                   FormatCryptoHandshakeMessageForTrace(message.get()));
-
-  done_cb_->Run(QUIC_NO_ERROR, std::string(), std::move(message),
-                std::move(diversification_nonce),
-                std::move(proof_source_details));
-  done_cb_ = nullptr;
-}
-
-QuicCryptoServerConfig::QuicCryptoServerConfig(
-    absl::string_view source_address_token_secret,
-    QuicRandom* server_nonce_entropy,
-    std::unique_ptr<ProofSource> proof_source,
-    std::unique_ptr<KeyExchangeSource> key_exchange_source)
-    : replay_protection_(true),
-      chlo_multiplier_(kMultiplier),
-      configs_lock_(),
-      primary_config_(nullptr),
-      next_config_promotion_time_(QuicWallTime::Zero()),
-      proof_source_(std::move(proof_source)),
-      key_exchange_source_(std::move(key_exchange_source)),
-      ssl_ctx_(TlsServerConnection::CreateSslCtx(proof_source_.get())),
-      source_address_token_future_secs_(3600),
-      source_address_token_lifetime_secs_(86400),
-      enable_serving_sct_(false),
-      rejection_observer_(nullptr),
-      pad_rej_(true),
-      pad_shlo_(true),
-      validate_chlo_size_(true),
-      validate_source_address_token_(true) {
-  QUICHE_DCHECK(proof_source_.get());
-  source_address_token_boxer_.SetKeys(
-      {DeriveSourceAddressTokenKey(source_address_token_secret)});
-
-  // Generate a random key and orbit for server nonces.
-  server_nonce_entropy->RandBytes(server_nonce_orbit_,
-                                  sizeof(server_nonce_orbit_));
-  const size_t key_size = server_nonce_boxer_.GetKeySize();
-  std::unique_ptr<uint8_t[]> key_bytes(new uint8_t[key_size]);
-  server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
-
-  server_nonce_boxer_.SetKeys(
-      {std::string(reinterpret_cast<char*>(key_bytes.get()), key_size)});
-}
-
-QuicCryptoServerConfig::~QuicCryptoServerConfig() {}
-
-// static
-QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig(
-    QuicRandom* rand,
-    const QuicClock* clock,
-    const ConfigOptions& options) {
-  CryptoHandshakeMessage msg;
-
-  const std::string curve25519_private_key =
-      Curve25519KeyExchange::NewPrivateKey(rand);
-  std::unique_ptr<Curve25519KeyExchange> curve25519 =
-      Curve25519KeyExchange::New(curve25519_private_key);
-  absl::string_view curve25519_public_value = curve25519->public_value();
-
-  std::string encoded_public_values;
-  // First three bytes encode the length of the public value.
-  QUICHE_DCHECK_LT(curve25519_public_value.size(), (1U << 24));
-  encoded_public_values.push_back(
-      static_cast<char>(curve25519_public_value.size()));
-  encoded_public_values.push_back(
-      static_cast<char>(curve25519_public_value.size() >> 8));
-  encoded_public_values.push_back(
-      static_cast<char>(curve25519_public_value.size() >> 16));
-  encoded_public_values.append(curve25519_public_value.data(),
-                               curve25519_public_value.size());
-
-  std::string p256_private_key;
-  if (options.p256) {
-    p256_private_key = P256KeyExchange::NewPrivateKey();
-    std::unique_ptr<P256KeyExchange> p256(
-        P256KeyExchange::New(p256_private_key));
-    absl::string_view p256_public_value = p256->public_value();
-
-    QUICHE_DCHECK_LT(p256_public_value.size(), (1U << 24));
-    encoded_public_values.push_back(
-        static_cast<char>(p256_public_value.size()));
-    encoded_public_values.push_back(
-        static_cast<char>(p256_public_value.size() >> 8));
-    encoded_public_values.push_back(
-        static_cast<char>(p256_public_value.size() >> 16));
-    encoded_public_values.append(p256_public_value.data(),
-                                 p256_public_value.size());
-  }
-
-  msg.set_tag(kSCFG);
-  if (options.p256) {
-    msg.SetVector(kKEXS, QuicTagVector{kC255, kP256});
-  } else {
-    msg.SetVector(kKEXS, QuicTagVector{kC255});
-  }
-  msg.SetVector(kAEAD, QuicTagVector{kAESG, kCC20});
-  msg.SetStringPiece(kPUBS, encoded_public_values);
-
-  if (options.expiry_time.IsZero()) {
-    const QuicWallTime now = clock->WallNow();
-    const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds(
-        60 * 60 * 24 * 180 /* 180 days, ~six months */));
-    const uint64_t expiry_seconds = expiry.ToUNIXSeconds();
-    msg.SetValue(kEXPY, expiry_seconds);
-  } else {
-    msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds());
-  }
-
-  char orbit_bytes[kOrbitSize];
-  if (options.orbit.size() == sizeof(orbit_bytes)) {
-    memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes));
-  } else {
-    QUICHE_DCHECK(options.orbit.empty());
-    rand->RandBytes(orbit_bytes, sizeof(orbit_bytes));
-  }
-  msg.SetStringPiece(kORBT,
-                     absl::string_view(orbit_bytes, sizeof(orbit_bytes)));
-
-  if (options.channel_id_enabled) {
-    msg.SetVector(kPDMD, QuicTagVector{kCHID});
-  }
-
-  if (options.id.empty()) {
-    // We need to ensure that the SCID changes whenever the server config does
-    // thus we make it a hash of the rest of the server config.
-    std::unique_ptr<QuicData> serialized =
-        CryptoFramer::ConstructHandshakeMessage(msg);
-
-    uint8_t scid_bytes[SHA256_DIGEST_LENGTH];
-    SHA256(reinterpret_cast<const uint8_t*>(serialized->data()),
-           serialized->length(), scid_bytes);
-    // The SCID is a truncated SHA-256 digest.
-    static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high.");
-    msg.SetStringPiece(
-        kSCID,
-        absl::string_view(reinterpret_cast<const char*>(scid_bytes), 16));
-  } else {
-    msg.SetStringPiece(kSCID, options.id);
-  }
-  // Don't put new tags below this point. The SCID generation should hash over
-  // everything but itself and so extra tags should be added prior to the
-  // preceding if block.
-
-  std::unique_ptr<QuicData> serialized =
-      CryptoFramer::ConstructHandshakeMessage(msg);
-
-  QuicServerConfigProtobuf config;
-  config.set_config(std::string(serialized->AsStringPiece()));
-  QuicServerConfigProtobuf::PrivateKey* curve25519_key = config.add_key();
-  curve25519_key->set_tag(kC255);
-  curve25519_key->set_private_key(curve25519_private_key);
-
-  if (options.p256) {
-    QuicServerConfigProtobuf::PrivateKey* p256_key = config.add_key();
-    p256_key->set_tag(kP256);
-    p256_key->set_private_key(p256_private_key);
-  }
-
-  return config;
-}
-
-std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig(
-    const QuicServerConfigProtobuf& protobuf,
-    const QuicWallTime now) {
-  std::unique_ptr<CryptoHandshakeMessage> msg =
-      CryptoFramer::ParseMessage(protobuf.config());
-
-  if (!msg) {
-    QUIC_LOG(WARNING) << "Failed to parse server config message";
-    return nullptr;
-  }
-
-  quiche::QuicheReferenceCountedPointer<Config> config =
-      ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
-  if (!config) {
-    QUIC_LOG(WARNING) << "Failed to parse server config message";
-    return nullptr;
-  }
-
-  {
-    QuicWriterMutexLock locked(&configs_lock_);
-    if (configs_.find(config->id) != configs_.end()) {
-      QUIC_LOG(WARNING) << "Failed to add config because another with the same "
-                           "server config id already exists: "
-                        << absl::BytesToHexString(config->id);
-      return nullptr;
-    }
-
-    configs_[config->id] = config;
-    SelectNewPrimaryConfig(now);
-    QUICHE_DCHECK(primary_config_.get());
-    QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
-                     primary_config_.get());
-  }
-
-  return msg;
-}
-
-std::unique_ptr<CryptoHandshakeMessage>
-QuicCryptoServerConfig::AddDefaultConfig(QuicRandom* rand,
-                                         const QuicClock* clock,
-                                         const ConfigOptions& options) {
-  return AddConfig(GenerateConfig(rand, clock, options), clock->WallNow());
-}
-
-bool QuicCryptoServerConfig::SetConfigs(
-    const std::vector<QuicServerConfigProtobuf>& protobufs,
-    const QuicServerConfigProtobuf* fallback_protobuf,
-    const QuicWallTime now) {
-  std::vector<quiche::QuicheReferenceCountedPointer<Config>> parsed_configs;
-  for (auto& protobuf : protobufs) {
-    quiche::QuicheReferenceCountedPointer<Config> config =
-        ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
-    if (!config) {
-      QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
-      return false;
-    }
-
-    parsed_configs.push_back(config);
-  }
-
-  quiche::QuicheReferenceCountedPointer<Config> fallback_config;
-  if (fallback_protobuf != nullptr) {
-    fallback_config =
-        ParseConfigProtobuf(*fallback_protobuf, /* is_fallback = */ true);
-    if (!fallback_config) {
-      QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
-      return false;
-    }
-    QUIC_LOG(INFO) << "Fallback config has scid "
-                   << absl::BytesToHexString(fallback_config->id);
-    parsed_configs.push_back(fallback_config);
-  } else {
-    QUIC_LOG(INFO) << "No fallback config provided";
-  }
-
-  if (parsed_configs.empty()) {
-    QUIC_LOG(WARNING)
-        << "Rejecting QUIC configs because new config list is empty.";
-    return false;
-  }
-
-  QUIC_LOG(INFO) << "Updating configs:";
-
-  QuicWriterMutexLock locked(&configs_lock_);
-  ConfigMap new_configs;
-
-  for (const quiche::QuicheReferenceCountedPointer<Config>& config :
-       parsed_configs) {
-    auto it = configs_.find(config->id);
-    if (it != configs_.end()) {
-      QUIC_LOG(INFO) << "Keeping scid: " << absl::BytesToHexString(config->id)
-                     << " orbit: "
-                     << absl::BytesToHexString(absl::string_view(
-                            reinterpret_cast<const char*>(config->orbit),
-                            kOrbitSize))
-                     << " new primary_time "
-                     << config->primary_time.ToUNIXSeconds()
-                     << " old primary_time "
-                     << it->second->primary_time.ToUNIXSeconds()
-                     << " new priority " << config->priority << " old priority "
-                     << it->second->priority;
-      // Update primary_time and priority.
-      it->second->primary_time = config->primary_time;
-      it->second->priority = config->priority;
-      new_configs.insert(*it);
-    } else {
-      QUIC_LOG(INFO) << "Adding scid: " << absl::BytesToHexString(config->id)
-                     << " orbit: "
-                     << absl::BytesToHexString(absl::string_view(
-                            reinterpret_cast<const char*>(config->orbit),
-                            kOrbitSize))
-                     << " primary_time " << config->primary_time.ToUNIXSeconds()
-                     << " priority " << config->priority;
-      new_configs.emplace(config->id, config);
-    }
-  }
-
-  configs_ = std::move(new_configs);
-  fallback_config_ = fallback_config;
-  SelectNewPrimaryConfig(now);
-  QUICHE_DCHECK(primary_config_.get());
-  QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
-                   primary_config_.get());
-
-  return true;
-}
-
-void QuicCryptoServerConfig::SetSourceAddressTokenKeys(
-    const std::vector<std::string>& keys) {
-  // TODO(b/208866709)
-  source_address_token_boxer_.SetKeys(keys);
-}
-
-std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const {
-  QuicReaderMutexLock locked(&configs_lock_);
-  std::vector<std::string> scids;
-  for (auto it = configs_.begin(); it != configs_.end(); ++it) {
-    scids.push_back(it->first);
-  }
-  return scids;
-}
-
-void QuicCryptoServerConfig::ValidateClientHello(
-    const CryptoHandshakeMessage& client_hello,
-    const QuicSocketAddress& client_address,
-    const QuicSocketAddress& server_address, QuicTransportVersion version,
-    const QuicClock* clock,
-    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
-    std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
-  const QuicWallTime now(clock->WallNow());
-
-  quiche::QuicheReferenceCountedPointer<
-      ValidateClientHelloResultCallback::Result>
-      result(new ValidateClientHelloResultCallback::Result(
-          client_hello, client_address.host(), now));
-
-  absl::string_view requested_scid;
-  // We ignore here the return value from GetStringPiece. If there is no SCID
-  // tag, EvaluateClientHello will discover that because GetCurrentConfigs will
-  // not have found the requested config (i.e. because none of the configs will
-  // have an empty string as its id).
-  client_hello.GetStringPiece(kSCID, &requested_scid);
-  Configs configs;
-  if (!GetCurrentConfigs(now, requested_scid,
-                         /* old_primary_config = */ nullptr, &configs)) {
-    result->error_code = QUIC_CRYPTO_INTERNAL_ERROR;
-    result->error_details = "No configurations loaded";
-  }
-  signed_config->config = configs.primary;
-
-  if (result->error_code == QUIC_NO_ERROR) {
-    // QUIC requires a new proof for each CHLO so clear any existing proof.
-    signed_config->chain = nullptr;
-    signed_config->proof.signature = "";
-    signed_config->proof.leaf_cert_scts = "";
-    EvaluateClientHello(server_address, client_address, version, configs,
-                        result, std::move(done_cb));
-  } else {
-    done_cb->Run(result, /* details = */ nullptr);
-  }
-}
-
-class QuicCryptoServerConfig::ProcessClientHelloCallback
-    : public ProofSource::Callback {
- public:
-  ProcessClientHelloCallback(const QuicCryptoServerConfig* config,
-                             std::unique_ptr<ProcessClientHelloContext> context,
-                             const Configs& configs)
-      : config_(config), context_(std::move(context)), configs_(configs) {}
-
-  void Run(
-      bool ok,
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const QuicCryptoProof& proof,
-      std::unique_ptr<ProofSource::Details> details) override {
-    if (ok) {
-      context_->signed_config()->chain = chain;
-      context_->signed_config()->proof = proof;
-    }
-    config_->ProcessClientHelloAfterGetProof(!ok, std::move(details),
-                                             std::move(context_), configs_);
-  }
-
- private:
-  const QuicCryptoServerConfig* config_;
-  std::unique_ptr<ProcessClientHelloContext> context_;
-  const Configs configs_;
-};
-
-class QuicCryptoServerConfig::ProcessClientHelloAfterGetProofCallback
-    : public AsynchronousKeyExchange::Callback {
- public:
-  ProcessClientHelloAfterGetProofCallback(
-      const QuicCryptoServerConfig* config,
-      std::unique_ptr<ProofSource::Details> proof_source_details,
-      QuicTag key_exchange_type,
-      std::unique_ptr<CryptoHandshakeMessage> out,
-      absl::string_view public_value,
-      std::unique_ptr<ProcessClientHelloContext> context,
-      const Configs& configs)
-      : config_(config),
-        proof_source_details_(std::move(proof_source_details)),
-        key_exchange_type_(key_exchange_type),
-        out_(std::move(out)),
-        public_value_(public_value),
-        context_(std::move(context)),
-        configs_(configs) {}
-
-  void Run(bool ok) override {
-    config_->ProcessClientHelloAfterCalculateSharedKeys(
-        !ok, std::move(proof_source_details_), key_exchange_type_,
-        std::move(out_), public_value_, std::move(context_), configs_);
-  }
-
- private:
-  const QuicCryptoServerConfig* config_;
-  std::unique_ptr<ProofSource::Details> proof_source_details_;
-  const QuicTag key_exchange_type_;
-  std::unique_ptr<CryptoHandshakeMessage> out_;
-  const std::string public_value_;
-  std::unique_ptr<ProcessClientHelloContext> context_;
-  const Configs configs_;
-  std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
-};
-
-class QuicCryptoServerConfig::SendRejectWithFallbackConfigCallback
-    : public ProofSource::Callback {
- public:
-  SendRejectWithFallbackConfigCallback(
-      const QuicCryptoServerConfig* config,
-      std::unique_ptr<ProcessClientHelloContext> context,
-      quiche::QuicheReferenceCountedPointer<Config> fallback_config)
-      : config_(config),
-        context_(std::move(context)),
-        fallback_config_(fallback_config) {}
-
-  // Capture |chain| and |proof| into the signed config, and then invoke
-  // SendRejectWithFallbackConfigAfterGetProof.
-  void Run(
-      bool ok,
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const QuicCryptoProof& proof,
-      std::unique_ptr<ProofSource::Details> details) override {
-    if (ok) {
-      context_->signed_config()->chain = chain;
-      context_->signed_config()->proof = proof;
-    }
-    config_->SendRejectWithFallbackConfigAfterGetProof(
-        !ok, std::move(details), std::move(context_), fallback_config_);
-  }
-
- private:
-  const QuicCryptoServerConfig* config_;
-  std::unique_ptr<ProcessClientHelloContext> context_;
-  quiche::QuicheReferenceCountedPointer<Config> fallback_config_;
-};
-
-void QuicCryptoServerConfig::ProcessClientHello(
-    quiche::QuicheReferenceCountedPointer<
-        ValidateClientHelloResultCallback::Result>
-        validate_chlo_result,
-    bool reject_only, QuicConnectionId connection_id,
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address, ParsedQuicVersion version,
-    const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
-    QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        params,
-    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
-    QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
-    std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const {
-  QUICHE_DCHECK(done_cb);
-  auto context = std::make_unique<ProcessClientHelloContext>(
-      validate_chlo_result, reject_only, connection_id, server_address,
-      client_address, version, supported_versions, clock, rand,
-      compressed_certs_cache, params, signed_config, total_framing_overhead,
-      chlo_packet_size, std::move(done_cb));
-
-  // Verify that various parts of the CHLO are valid
-  std::string error_details;
-  QuicErrorCode valid = CryptoUtils::ValidateClientHello(
-      context->client_hello(), context->version(),
-      context->supported_versions(), &error_details);
-  if (valid != QUIC_NO_ERROR) {
-    context->Fail(valid, error_details);
-    return;
-  }
-
-  absl::string_view requested_scid;
-  context->client_hello().GetStringPiece(kSCID, &requested_scid);
-  Configs configs;
-  if (!GetCurrentConfigs(context->clock()->WallNow(), requested_scid,
-                         signed_config->config, &configs)) {
-    context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded");
-    return;
-  }
-
-  if (context->validate_chlo_result()->error_code != QUIC_NO_ERROR) {
-    context->Fail(context->validate_chlo_result()->error_code,
-                  context->validate_chlo_result()->error_details);
-    return;
-  }
-
-  if (!ClientDemandsX509Proof(context->client_hello())) {
-    context->Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD");
-    return;
-  }
-
-  // No need to get a new proof if one was already generated.
-  if (!context->signed_config()->chain) {
-    const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
-        context->client_hello(), Perspective::IS_SERVER);
-    const QuicSocketAddress server_address = context->server_address();
-    const std::string sni = std::string(context->info().sni);
-    const QuicTransportVersion transport_version = context->transport_version();
-
-    auto cb = std::make_unique<ProcessClientHelloCallback>(
-        this, std::move(context), configs);
-
-    QUICHE_DCHECK(proof_source_.get());
-    proof_source_->GetProof(server_address, client_address, sni,
-                            configs.primary->serialized, transport_version,
-                            chlo_hash, std::move(cb));
-    return;
-  }
-
-  ProcessClientHelloAfterGetProof(
-      /* found_error = */ false, /* proof_source_details = */ nullptr,
-      std::move(context), configs);
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
-    bool found_error,
-    std::unique_ptr<ProofSource::Details> proof_source_details,
-    std::unique_ptr<ProcessClientHelloContext> context,
-    const Configs& configs) const {
-  QUIC_BUG_IF(quic_bug_12963_2,
-              !QuicUtils::IsConnectionIdValidForVersion(
-                  context->connection_id(), context->transport_version()))
-      << "ProcessClientHelloAfterGetProof: attempted to use connection ID "
-      << context->connection_id() << " which is invalid with version "
-      << context->version();
-
-  if (context->info().reject_reasons.empty()) {
-    if (!context->signed_config() || !context->signed_config()->chain) {
-      // No chain.
-      context->validate_chlo_result()->info.reject_reasons.push_back(
-          SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
-    } else if (!ValidateExpectedLeafCertificate(
-                   context->client_hello(),
-                   context->signed_config()->chain->certs)) {
-      // Has chain but leaf is invalid.
-      context->validate_chlo_result()->info.reject_reasons.push_back(
-          INVALID_EXPECTED_LEAF_CERTIFICATE);
-    }
-  }
-
-  if (found_error) {
-    context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
-    return;
-  }
-
-  auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
-
-  absl::string_view cert_sct;
-  if (context->client_hello().GetStringPiece(kCertificateSCTTag, &cert_sct) &&
-      cert_sct.empty()) {
-    context->params()->sct_supported_by_client = true;
-  }
-
-  auto out = std::make_unique<CryptoHandshakeMessage>();
-  if (!context->info().reject_reasons.empty() || !configs.requested) {
-    BuildRejectionAndRecordStats(*context, *configs.primary,
-                                 context->info().reject_reasons, out.get());
-    context->Succeed(std::move(out), std::move(out_diversification_nonce),
-                     std::move(proof_source_details));
-    return;
-  }
-
-  if (context->reject_only()) {
-    context->Succeed(std::move(out), std::move(out_diversification_nonce),
-                     std::move(proof_source_details));
-    return;
-  }
-
-  QuicTagVector their_aeads;
-  QuicTagVector their_key_exchanges;
-  if (context->client_hello().GetTaglist(kAEAD, &their_aeads) !=
-          QUIC_NO_ERROR ||
-      context->client_hello().GetTaglist(kKEXS, &their_key_exchanges) !=
-          QUIC_NO_ERROR ||
-      their_aeads.size() != 1 || their_key_exchanges.size() != 1) {
-    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                  "Missing or invalid AEAD or KEXS");
-    return;
-  }
-
-  size_t key_exchange_index;
-  if (!FindMutualQuicTag(configs.requested->aead, their_aeads,
-                         &context->params()->aead, nullptr) ||
-      !FindMutualQuicTag(configs.requested->kexs, their_key_exchanges,
-                         &context->params()->key_exchange,
-                         &key_exchange_index)) {
-    context->Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS");
-    return;
-  }
-
-  absl::string_view public_value;
-  if (!context->client_hello().GetStringPiece(kPUBS, &public_value)) {
-    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                  "Missing public value");
-    return;
-  }
-
-  // Allow testing a specific adversarial case in which a client sends a public
-  // value of incorrect size.
-  AdjustTestValue("quic::QuicCryptoServerConfig::public_value_adjust",
-                  &public_value);
-
-  const AsynchronousKeyExchange* key_exchange =
-      configs.requested->key_exchanges[key_exchange_index].get();
-  std::string* initial_premaster_secret =
-      &context->params()->initial_premaster_secret;
-  auto cb = std::make_unique<ProcessClientHelloAfterGetProofCallback>(
-      this, std::move(proof_source_details), key_exchange->type(),
-      std::move(out), public_value, std::move(context), configs);
-  key_exchange->CalculateSharedKeyAsync(public_value, initial_premaster_secret,
-                                        std::move(cb));
-}
-
-void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys(
-    bool found_error,
-    std::unique_ptr<ProofSource::Details> proof_source_details,
-    QuicTag key_exchange_type,
-    std::unique_ptr<CryptoHandshakeMessage> out,
-    absl::string_view public_value,
-    std::unique_ptr<ProcessClientHelloContext> context,
-    const Configs& configs) const {
-  QUIC_BUG_IF(quic_bug_12963_3,
-              !QuicUtils::IsConnectionIdValidForVersion(
-                  context->connection_id(), context->transport_version()))
-      << "ProcessClientHelloAfterCalculateSharedKeys:"
-         " attempted to use connection ID "
-      << context->connection_id() << " which is invalid with version "
-      << context->version();
-
-  if (found_error) {
-    // If we are already using the fallback config, or there is no fallback
-    // config to use, just bail out of the handshake.
-    if (configs.fallback == nullptr ||
-        context->signed_config()->config == configs.fallback) {
-      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                    "Failed to calculate shared key");
-    } else {
-      SendRejectWithFallbackConfig(std::move(context), configs.fallback);
-    }
-    return;
-  }
-
-  if (!context->info().sni.empty()) {
-    context->params()->sni =
-        QuicHostnameUtils::NormalizeHostname(context->info().sni);
-  }
-
-  std::string hkdf_suffix;
-  const QuicData& client_hello_serialized =
-      context->client_hello().GetSerialized();
-  hkdf_suffix.reserve(context->connection_id().length() +
-                      client_hello_serialized.length() +
-                      configs.requested->serialized.size());
-  hkdf_suffix.append(context->connection_id().data(),
-                     context->connection_id().length());
-  hkdf_suffix.append(client_hello_serialized.data(),
-                     client_hello_serialized.length());
-  hkdf_suffix.append(configs.requested->serialized);
-  QUICHE_DCHECK(proof_source_.get());
-  if (context->signed_config()->chain->certs.empty()) {
-    context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs");
-    return;
-  }
-  hkdf_suffix.append(context->signed_config()->chain->certs.at(0));
-
-  absl::string_view cetv_ciphertext;
-  if (configs.requested->channel_id_enabled &&
-      context->client_hello().GetStringPiece(kCETV, &cetv_ciphertext)) {
-    CryptoHandshakeMessage client_hello_copy(context->client_hello());
-    client_hello_copy.Erase(kCETV);
-    client_hello_copy.Erase(kPAD);
-
-    const QuicData& client_hello_copy_serialized =
-        client_hello_copy.GetSerialized();
-    std::string hkdf_input;
-    hkdf_input.append(QuicCryptoConfig::kCETVLabel,
-                      strlen(QuicCryptoConfig::kCETVLabel) + 1);
-    hkdf_input.append(context->connection_id().data(),
-                      context->connection_id().length());
-    hkdf_input.append(client_hello_copy_serialized.data(),
-                      client_hello_copy_serialized.length());
-    hkdf_input.append(configs.requested->serialized);
-
-    CrypterPair crypters;
-    if (!CryptoUtils::DeriveKeys(
-            context->version(), context->params()->initial_premaster_secret,
-            context->params()->aead, context->info().client_nonce,
-            context->info().server_nonce, pre_shared_key_, hkdf_input,
-            Perspective::IS_SERVER, CryptoUtils::Diversification::Never(),
-            &crypters, nullptr /* subkey secret */)) {
-      context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
-                    "Symmetric key setup failed");
-      return;
-    }
-
-    char plaintext[kMaxOutgoingPacketSize];
-    size_t plaintext_length = 0;
-    const bool success = crypters.decrypter->DecryptPacket(
-        0 /* packet number */, absl::string_view() /* associated data */,
-        cetv_ciphertext, plaintext, &plaintext_length, kMaxOutgoingPacketSize);
-    if (!success) {
-      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                    "CETV decryption failure");
-      return;
-    }
-    std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage(
-        absl::string_view(plaintext, plaintext_length)));
-    if (!cetv) {
-      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error");
-      return;
-    }
-
-    absl::string_view key, signature;
-    if (cetv->GetStringPiece(kCIDK, &key) &&
-        cetv->GetStringPiece(kCIDS, &signature)) {
-      if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) {
-        context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                      "ChannelID signature failure");
-        return;
-      }
-
-      context->params()->channel_id = std::string(key);
-    }
-  }
-
-  std::string hkdf_input;
-  size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
-  hkdf_input.reserve(label_len + hkdf_suffix.size());
-  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
-  hkdf_input.append(hkdf_suffix);
-
-  auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
-  context->rand()->RandBytes(out_diversification_nonce->data(),
-                             out_diversification_nonce->size());
-  CryptoUtils::Diversification diversification =
-      CryptoUtils::Diversification::Now(out_diversification_nonce.get());
-  if (!CryptoUtils::DeriveKeys(
-          context->version(), context->params()->initial_premaster_secret,
-          context->params()->aead, context->info().client_nonce,
-          context->info().server_nonce, pre_shared_key_, hkdf_input,
-          Perspective::IS_SERVER, diversification,
-          &context->params()->initial_crypters,
-          &context->params()->initial_subkey_secret)) {
-    context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
-                  "Symmetric key setup failed");
-    return;
-  }
-
-  std::string forward_secure_public_value;
-  std::unique_ptr<SynchronousKeyExchange> forward_secure_key_exchange =
-      CreateLocalSynchronousKeyExchange(key_exchange_type, context->rand());
-  if (!forward_secure_key_exchange) {
-    QUIC_DLOG(WARNING) << "Failed to create keypair";
-    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                  "Failed to create keypair");
-    return;
-  }
-
-  forward_secure_public_value =
-      std::string(forward_secure_key_exchange->public_value());
-  if (!forward_secure_key_exchange->CalculateSharedKeySync(
-          public_value, &context->params()->forward_secure_premaster_secret)) {
-    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                  "Invalid public value");
-    return;
-  }
-
-  std::string forward_secure_hkdf_input;
-  label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
-  forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size());
-  forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel,
-                                   label_len);
-  forward_secure_hkdf_input.append(hkdf_suffix);
-
-  std::string shlo_nonce;
-  shlo_nonce = NewServerNonce(context->rand(), context->info().now);
-  out->SetStringPiece(kServerNonceTag, shlo_nonce);
-
-  if (!CryptoUtils::DeriveKeys(
-          context->version(),
-          context->params()->forward_secure_premaster_secret,
-          context->params()->aead, context->info().client_nonce,
-          shlo_nonce.empty() ? context->info().server_nonce : shlo_nonce,
-          pre_shared_key_, forward_secure_hkdf_input, Perspective::IS_SERVER,
-          CryptoUtils::Diversification::Never(),
-          &context->params()->forward_secure_crypters,
-          &context->params()->subkey_secret)) {
-    context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
-                  "Symmetric key setup failed");
-    return;
-  }
-
-  out->set_tag(kSHLO);
-  out->SetVersionVector(kVER, context->supported_versions());
-  out->SetStringPiece(
-      kSourceAddressTokenTag,
-      NewSourceAddressToken(*configs.requested->source_address_token_boxer,
-                            context->info().source_address_tokens,
-                            context->client_address().host(), context->rand(),
-                            context->info().now, nullptr));
-  QuicSocketAddressCoder address_coder(context->client_address());
-  out->SetStringPiece(kCADR, address_coder.Encode());
-  out->SetStringPiece(kPUBS, forward_secure_public_value);
-
-  context->Succeed(std::move(out), std::move(out_diversification_nonce),
-                   std::move(proof_source_details));
-}
-
-void QuicCryptoServerConfig::SendRejectWithFallbackConfig(
-    std::unique_ptr<ProcessClientHelloContext> context,
-    quiche::QuicheReferenceCountedPointer<Config> fallback_config) const {
-  // We failed to calculate a shared initial key, likely because we tried to use
-  // a remote key-exchange service which could not be reached.  We want to send
-  // a REJ which tells the client to use a different ServerConfig which
-  // corresponds to a local keypair.  To generate the REJ we need to request a
-  // new proof.
-  const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
-      context->client_hello(), Perspective::IS_SERVER);
-  const QuicSocketAddress server_address = context->server_address();
-  const std::string sni(context->info().sni);
-  const QuicTransportVersion transport_version = context->transport_version();
-
-  const QuicSocketAddress& client_address = context->client_address();
-  auto cb = std::make_unique<SendRejectWithFallbackConfigCallback>(
-      this, std::move(context), fallback_config);
-  proof_source_->GetProof(server_address, client_address, sni,
-                          fallback_config->serialized, transport_version,
-                          chlo_hash, std::move(cb));
-}
-
-void QuicCryptoServerConfig::SendRejectWithFallbackConfigAfterGetProof(
-    bool found_error,
-    std::unique_ptr<ProofSource::Details> proof_source_details,
-    std::unique_ptr<ProcessClientHelloContext> context,
-    quiche::QuicheReferenceCountedPointer<Config> fallback_config) const {
-  if (found_error) {
-    context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
-    return;
-  }
-
-  auto out = std::make_unique<CryptoHandshakeMessage>();
-  BuildRejectionAndRecordStats(*context, *fallback_config,
-                               {SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE},
-                               out.get());
-
-  context->Succeed(std::move(out), std::make_unique<DiversificationNonce>(),
-                   std::move(proof_source_details));
-}
-
-quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfig::GetConfigWithScid(
-    absl::string_view requested_scid) const {
-  configs_lock_.AssertReaderHeld();
-
-  if (!requested_scid.empty()) {
-    auto it = configs_.find((std::string(requested_scid)));
-    if (it != configs_.end()) {
-      // We'll use the config that the client requested in order to do
-      // key-agreement.
-      return quiche::QuicheReferenceCountedPointer<Config>(it->second);
-    }
-  }
-
-  return quiche::QuicheReferenceCountedPointer<Config>();
-}
-
-bool QuicCryptoServerConfig::GetCurrentConfigs(
-    const QuicWallTime& now, absl::string_view requested_scid,
-    quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
-    Configs* configs) const {
-  QuicReaderMutexLock locked(&configs_lock_);
-
-  if (!primary_config_) {
-    return false;
-  }
-
-  if (IsNextConfigReady(now)) {
-    configs_lock_.ReaderUnlock();
-    configs_lock_.WriterLock();
-    SelectNewPrimaryConfig(now);
-    QUICHE_DCHECK(primary_config_.get());
-    QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
-                     primary_config_.get());
-    configs_lock_.WriterUnlock();
-    configs_lock_.ReaderLock();
-  }
-
-  if (old_primary_config != nullptr) {
-    configs->primary = old_primary_config;
-  } else {
-    configs->primary = primary_config_;
-  }
-  configs->requested = GetConfigWithScid(requested_scid);
-  configs->fallback = fallback_config_;
-
-  return true;
-}
-
-// ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
-// Config's based on their primary_time.
-// static
-bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
-    const quiche::QuicheReferenceCountedPointer<Config>& a,
-    const quiche::QuicheReferenceCountedPointer<Config>& b) {
-  if (a->primary_time.IsBefore(b->primary_time) ||
-      b->primary_time.IsBefore(a->primary_time)) {
-    // Primary times differ.
-    return a->primary_time.IsBefore(b->primary_time);
-  } else if (a->priority != b->priority) {
-    // Primary times are equal, sort backwards by priority.
-    return a->priority < b->priority;
-  } else {
-    // Primary times and priorities are equal, sort by config id.
-    return a->id < b->id;
-  }
-}
-
-void QuicCryptoServerConfig::SelectNewPrimaryConfig(
-    const QuicWallTime now) const {
-  std::vector<quiche::QuicheReferenceCountedPointer<Config>> configs;
-  configs.reserve(configs_.size());
-
-  for (auto it = configs_.begin(); it != configs_.end(); ++it) {
-    // TODO(avd) Exclude expired configs?
-    configs.push_back(it->second);
-  }
-
-  if (configs.empty()) {
-    if (primary_config_ != nullptr) {
-      QUIC_BUG(quic_bug_10630_2)
-          << "No valid QUIC server config. Keeping the current config.";
-    } else {
-      QUIC_BUG(quic_bug_10630_3) << "No valid QUIC server config.";
-    }
-    return;
-  }
-
-  std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan);
-
-  quiche::QuicheReferenceCountedPointer<Config> best_candidate = configs[0];
-
-  for (size_t i = 0; i < configs.size(); ++i) {
-    const quiche::QuicheReferenceCountedPointer<Config> config(configs[i]);
-    if (!config->primary_time.IsAfter(now)) {
-      if (config->primary_time.IsAfter(best_candidate->primary_time)) {
-        best_candidate = config;
-      }
-      continue;
-    }
-
-    // This is the first config with a primary_time in the future. Thus the
-    // previous Config should be the primary and this one should determine the
-    // next_config_promotion_time_.
-    quiche::QuicheReferenceCountedPointer<Config> new_primary = best_candidate;
-    if (i == 0) {
-      // We need the primary_time of the next config.
-      if (configs.size() > 1) {
-        next_config_promotion_time_ = configs[1]->primary_time;
-      } else {
-        next_config_promotion_time_ = QuicWallTime::Zero();
-      }
-    } else {
-      next_config_promotion_time_ = config->primary_time;
-    }
-
-    if (primary_config_) {
-      primary_config_->is_primary = false;
-    }
-    primary_config_ = new_primary;
-    new_primary->is_primary = true;
-    QUIC_DLOG(INFO) << "New primary config.  orbit: "
-                    << absl::BytesToHexString(
-                           absl::string_view(reinterpret_cast<const char*>(
-                                                 primary_config_->orbit),
-                                             kOrbitSize));
-    if (primary_config_changed_cb_ != nullptr) {
-      primary_config_changed_cb_->Run(primary_config_->id);
-    }
-
-    return;
-  }
-
-  // All config's primary times are in the past. We should make the most recent
-  // and highest priority candidate primary.
-  quiche::QuicheReferenceCountedPointer<Config> new_primary = best_candidate;
-  if (primary_config_) {
-    primary_config_->is_primary = false;
-  }
-  primary_config_ = new_primary;
-  new_primary->is_primary = true;
-  QUIC_DLOG(INFO) << "New primary config.  orbit: "
-                  << absl::BytesToHexString(absl::string_view(
-                         reinterpret_cast<const char*>(primary_config_->orbit),
-                         kOrbitSize))
-                  << " scid: " << absl::BytesToHexString(primary_config_->id);
-  next_config_promotion_time_ = QuicWallTime::Zero();
-  if (primary_config_changed_cb_ != nullptr) {
-    primary_config_changed_cb_->Run(primary_config_->id);
-  }
-}
-
-void QuicCryptoServerConfig::EvaluateClientHello(
-    const QuicSocketAddress& /*server_address*/,
-    const QuicSocketAddress& /*client_address*/,
-    QuicTransportVersion /*version*/, const Configs& configs,
-    quiche::QuicheReferenceCountedPointer<
-        ValidateClientHelloResultCallback::Result>
-        client_hello_state,
-    std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
-  ValidateClientHelloHelper helper(client_hello_state, &done_cb);
-
-  const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello;
-  ClientHelloInfo* info = &(client_hello_state->info);
-
-  if (client_hello.GetStringPiece(kSNI, &info->sni) &&
-      !QuicHostnameUtils::IsValidSNI(info->sni)) {
-    helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
-                              "Invalid SNI name", nullptr);
-    return;
-  }
-
-  client_hello.GetStringPiece(kUAID, &info->user_agent_id);
-
-  HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON;
-  if (validate_source_address_token_) {
-    absl::string_view srct;
-    if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
-      Config& config =
-          configs.requested != nullptr ? *configs.requested : *configs.primary;
-      source_address_token_error =
-          ParseSourceAddressToken(*config.source_address_token_boxer, srct,
-                                  info->source_address_tokens);
-
-      if (source_address_token_error == HANDSHAKE_OK) {
-        source_address_token_error = ValidateSourceAddressTokens(
-            info->source_address_tokens, info->client_ip, info->now,
-            &client_hello_state->cached_network_params);
-      }
-      info->valid_source_address_token =
-          (source_address_token_error == HANDSHAKE_OK);
-    } else {
-      source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
-    }
-  } else {
-    source_address_token_error = HANDSHAKE_OK;
-    info->valid_source_address_token = true;
-  }
-
-  if (!configs.requested) {
-    absl::string_view requested_scid;
-    if (client_hello.GetStringPiece(kSCID, &requested_scid)) {
-      info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
-    } else {
-      info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
-    }
-    // No server config with the requested ID.
-    helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
-    return;
-  }
-
-  if (!client_hello.GetStringPiece(kNONC, &info->client_nonce)) {
-    info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
-    // Report no client nonce as INCHOATE_HELLO_FAILURE.
-    helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
-    return;
-  }
-
-  if (source_address_token_error != HANDSHAKE_OK) {
-    info->reject_reasons.push_back(source_address_token_error);
-    // No valid source address token.
-  }
-
-  if (info->client_nonce.size() != kNonceSize) {
-    info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
-    // Invalid client nonce.
-    QUIC_LOG_FIRST_N(ERROR, 2)
-        << "Invalid client nonce: " << client_hello.DebugString();
-    QUIC_DLOG(INFO) << "Invalid client nonce.";
-  }
-
-  // Server nonce is optional, and used for key derivation if present.
-  client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
-
-  // If the server nonce is empty and we're requiring handshake confirmation
-  // for DoS reasons then we must reject the CHLO.
-  if (GetQuicReloadableFlag(quic_require_handshake_confirmation) &&
-      info->server_nonce.empty()) {
-    info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
-  }
-  helper.ValidationComplete(QUIC_NO_ERROR, "",
-                            std::unique_ptr<ProofSource::Details>());
-}
-
-void QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
-    QuicTransportVersion version,
-    absl::string_view chlo_hash,
-    const SourceAddressTokens& previous_source_address_tokens,
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    const QuicClock* clock,
-    QuicRandom* rand,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    const QuicCryptoNegotiatedParameters& params,
-    const CachedNetworkParameters* cached_network_params,
-    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
-  std::string serialized;
-  std::string source_address_token;
-  {
-    QuicReaderMutexLock locked(&configs_lock_);
-    serialized = primary_config_->serialized;
-    source_address_token = NewSourceAddressToken(
-        *primary_config_->source_address_token_boxer,
-        previous_source_address_tokens, client_address.host(), rand,
-        clock->WallNow(), cached_network_params);
-  }
-
-  CryptoHandshakeMessage message;
-  message.set_tag(kSCUP);
-  message.SetStringPiece(kSCFG, serialized);
-  message.SetStringPiece(kSourceAddressTokenTag, source_address_token);
-
-  auto proof_source_cb =
-      std::make_unique<BuildServerConfigUpdateMessageProofSourceCallback>(
-          this, compressed_certs_cache, params, std::move(message),
-          std::move(cb));
-
-  proof_source_->GetProof(server_address, client_address, params.sni,
-                          serialized, version, chlo_hash,
-                          std::move(proof_source_cb));
-}
-
-QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
-    ~BuildServerConfigUpdateMessageProofSourceCallback() {}
-
-QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
-    BuildServerConfigUpdateMessageProofSourceCallback(
-        const QuicCryptoServerConfig* config,
-        QuicCompressedCertsCache* compressed_certs_cache,
-        const QuicCryptoNegotiatedParameters& params,
-        CryptoHandshakeMessage message,
-        std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb)
-    : config_(config),
-      compressed_certs_cache_(compressed_certs_cache),
-      client_cached_cert_hashes_(params.client_cached_cert_hashes),
-      sct_supported_by_client_(params.sct_supported_by_client),
-      sni_(params.sni),
-      message_(std::move(message)),
-      cb_(std::move(cb)) {}
-
-void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
-    Run(bool ok,
-        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-        const QuicCryptoProof& proof,
-        std::unique_ptr<ProofSource::Details> details) {
-  config_->FinishBuildServerConfigUpdateMessage(
-      compressed_certs_cache_, client_cached_cert_hashes_,
-      sct_supported_by_client_, sni_, ok, chain, proof.signature,
-      proof.leaf_cert_scts, std::move(details), std::move(message_),
-      std::move(cb_));
-}
-
-void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage(
-    QuicCompressedCertsCache* compressed_certs_cache,
-    const std::string& client_cached_cert_hashes, bool sct_supported_by_client,
-    const std::string& sni, bool ok,
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const std::string& signature, const std::string& leaf_cert_sct,
-    std::unique_ptr<ProofSource::Details> /*details*/,
-    CryptoHandshakeMessage message,
-    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
-  if (!ok) {
-    cb->Run(false, message);
-    return;
-  }
-
-  const std::string compressed =
-      CompressChain(compressed_certs_cache, chain, client_cached_cert_hashes);
-
-  message.SetStringPiece(kCertificateTag, compressed);
-  message.SetStringPiece(kPROF, signature);
-  if (sct_supported_by_client && enable_serving_sct_) {
-    if (leaf_cert_sct.empty()) {
-      QUIC_LOG_EVERY_N_SEC(WARNING, 60)
-          << "SCT is expected but it is empty. SNI: " << sni;
-    } else {
-      message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct);
-    }
-  }
-
-  cb->Run(true, message);
-}
-
-void QuicCryptoServerConfig::BuildRejectionAndRecordStats(
-    const ProcessClientHelloContext& context,
-    const Config& config,
-    const std::vector<uint32_t>& reject_reasons,
-    CryptoHandshakeMessage* out) const {
-  BuildRejection(context, config, reject_reasons, out);
-  if (rejection_observer_ != nullptr) {
-    rejection_observer_->OnRejectionBuilt(reject_reasons, out);
-  }
-}
-
-void QuicCryptoServerConfig::BuildRejection(
-    const ProcessClientHelloContext& context,
-    const Config& config,
-    const std::vector<uint32_t>& reject_reasons,
-    CryptoHandshakeMessage* out) const {
-  const QuicWallTime now = context.clock()->WallNow();
-
-  out->set_tag(kREJ);
-  out->SetStringPiece(kSCFG, config.serialized);
-  out->SetStringPiece(
-      kSourceAddressTokenTag,
-      NewSourceAddressToken(
-          *config.source_address_token_boxer,
-          context.info().source_address_tokens, context.info().client_ip,
-          context.rand(), context.info().now,
-          &context.validate_chlo_result()->cached_network_params));
-  out->SetValue(kSTTL, config.expiry_time.AbsoluteDifference(now).ToSeconds());
-  if (replay_protection_) {
-    out->SetStringPiece(kServerNonceTag,
-                        NewServerNonce(context.rand(), context.info().now));
-  }
-
-  // Send client the reject reason for debugging purposes.
-  QUICHE_DCHECK_LT(0u, reject_reasons.size());
-  out->SetVector(kRREJ, reject_reasons);
-
-  // The client may have requested a certificate chain.
-  if (!ClientDemandsX509Proof(context.client_hello())) {
-    QUIC_BUG(quic_bug_10630_4)
-        << "x509 certificates not supported in proof demand";
-    return;
-  }
-
-  absl::string_view client_cached_cert_hashes;
-  if (context.client_hello().GetStringPiece(kCCRT,
-                                            &client_cached_cert_hashes)) {
-    context.params()->client_cached_cert_hashes =
-        std::string(client_cached_cert_hashes);
-  } else {
-    context.params()->client_cached_cert_hashes.clear();
-  }
-
-  const std::string compressed = CompressChain(
-      context.compressed_certs_cache(), context.signed_config()->chain,
-      context.params()->client_cached_cert_hashes);
-
-  QUICHE_DCHECK_GT(context.chlo_packet_size(), context.client_hello().size());
-  // kREJOverheadBytes is a very rough estimate of how much of a REJ
-  // message is taken up by things other than the certificates.
-  // STK: 56 bytes
-  // SNO: 56 bytes
-  // SCFG
-  //   SCID: 16 bytes
-  //   PUBS: 38 bytes
-  const size_t kREJOverheadBytes = 166;
-  // max_unverified_size is the number of bytes that the certificate chain,
-  // signature, and (optionally) signed certificate timestamp can consume before
-  // we will demand a valid source-address token.
-  const size_t max_unverified_size =
-      chlo_multiplier_ *
-          (context.chlo_packet_size() - context.total_framing_overhead()) -
-      kREJOverheadBytes;
-  static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
-                "overhead calculation may underflow");
-  bool should_return_sct =
-      context.params()->sct_supported_by_client && enable_serving_sct_;
-  const std::string& cert_sct = context.signed_config()->proof.leaf_cert_scts;
-  const size_t sct_size = should_return_sct ? cert_sct.size() : 0;
-  const size_t total_size = context.signed_config()->proof.signature.size() +
-                            compressed.size() + sct_size;
-  if (context.info().valid_source_address_token ||
-      total_size < max_unverified_size) {
-    out->SetStringPiece(kCertificateTag, compressed);
-    out->SetStringPiece(kPROF, context.signed_config()->proof.signature);
-    if (should_return_sct) {
-      if (cert_sct.empty()) {
-        // Log SNI and subject name for the leaf cert if its SCT is empty.
-        // This is for debugging b/28342827.
-        const std::vector<std::string>& certs =
-            context.signed_config()->chain->certs;
-        std::string ca_subject;
-        if (!certs.empty()) {
-            std::unique_ptr<CertificateView> view =
-                CertificateView::ParseSingleCertificate(certs[0]);
-            if (view != nullptr) {
-              absl::optional<std::string> maybe_ca_subject =
-                  view->GetHumanReadableSubject();
-              if (maybe_ca_subject.has_value()) {
-                ca_subject = *maybe_ca_subject;
-              }
-            }
-        }
-        QUIC_LOG_EVERY_N_SEC(WARNING, 60)
-            << "SCT is expected but it is empty. sni: '"
-            << context.params()->sni << "' cert subject: '" << ca_subject
-            << "'";
-      } else {
-        out->SetStringPiece(kCertificateSCTTag, cert_sct);
-      }
-    }
-  } else {
-    QUIC_LOG_EVERY_N_SEC(WARNING, 60)
-        << "Sending inchoate REJ for hostname: " << context.info().sni
-        << " signature: " << context.signed_config()->proof.signature.size()
-        << " cert: " << compressed.size() << " sct:" << sct_size
-        << " total: " << total_size << " max: " << max_unverified_size;
-  }
-}
-
-std::string QuicCryptoServerConfig::CompressChain(
-    QuicCompressedCertsCache* compressed_certs_cache,
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const std::string& client_cached_cert_hashes) {
-  // Check whether the compressed certs is available in the cache.
-  QUICHE_DCHECK(compressed_certs_cache);
-  const std::string* cached_value = compressed_certs_cache->GetCompressedCert(
-      chain, client_cached_cert_hashes);
-  if (cached_value) {
-    return *cached_value;
-  }
-  std::string compressed =
-      CertCompressor::CompressChain(chain->certs, client_cached_cert_hashes);
-  // Insert the newly compressed cert to cache.
-  compressed_certs_cache->Insert(chain, client_cached_cert_hashes, compressed);
-  return compressed;
-}
-
-quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfig::ParseConfigProtobuf(
-    const QuicServerConfigProtobuf& protobuf, bool is_fallback) const {
-  std::unique_ptr<CryptoHandshakeMessage> msg =
-      CryptoFramer::ParseMessage(protobuf.config());
-
-  if (!msg) {
-    QUIC_LOG(WARNING) << "Failed to parse server config message";
-    return nullptr;
-  }
-
-  if (msg->tag() != kSCFG) {
-    QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag()
-                      << ", but expected " << kSCFG;
-    return nullptr;
-  }
-
-  quiche::QuicheReferenceCountedPointer<Config> config(new Config);
-  config->serialized = protobuf.config();
-  config->source_address_token_boxer = &source_address_token_boxer_;
-
-  if (protobuf.has_primary_time()) {
-    config->primary_time =
-        QuicWallTime::FromUNIXSeconds(protobuf.primary_time());
-  }
-
-  config->priority = protobuf.priority();
-
-  absl::string_view scid;
-  if (!msg->GetStringPiece(kSCID, &scid)) {
-    QUIC_LOG(WARNING) << "Server config message is missing SCID";
-    return nullptr;
-  }
-  QUICHE_DCHECK(!scid.empty());
-  config->id = std::string(scid);
-
-  if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
-    QUIC_LOG(WARNING) << "Server config message is missing AEAD";
-    return nullptr;
-  }
-
-  QuicTagVector kexs_tags;
-  if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) {
-    QUIC_LOG(WARNING) << "Server config message is missing KEXS";
-    return nullptr;
-  }
-
-  absl::string_view orbit;
-  if (!msg->GetStringPiece(kORBT, &orbit)) {
-    QUIC_LOG(WARNING) << "Server config message is missing ORBT";
-    return nullptr;
-  }
-
-  if (orbit.size() != kOrbitSize) {
-    QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length."
-                         " Got "
-                      << orbit.size() << " want " << kOrbitSize;
-    return nullptr;
-  }
-  static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size");
-  memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
-
-  QuicTagVector proof_demand_tags;
-  if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) {
-    for (QuicTag tag : proof_demand_tags) {
-      if (tag == kCHID) {
-        config->channel_id_enabled = true;
-        break;
-      }
-    }
-  }
-
-  for (size_t i = 0; i < kexs_tags.size(); i++) {
-    const QuicTag tag = kexs_tags[i];
-    std::string private_key;
-
-    config->kexs.push_back(tag);
-
-    for (int j = 0; j < protobuf.key_size(); j++) {
-      const QuicServerConfigProtobuf::PrivateKey& key = protobuf.key(i);
-      if (key.tag() == tag) {
-        private_key = key.private_key();
-        break;
-      }
-    }
-
-    std::unique_ptr<AsynchronousKeyExchange> ka =
-        key_exchange_source_->Create(config->id, is_fallback, tag, private_key);
-    if (!ka) {
-      return nullptr;
-    }
-    for (const auto& key_exchange : config->key_exchanges) {
-      if (key_exchange->type() == tag) {
-        QUIC_LOG(WARNING) << "Duplicate key exchange in config: " << tag;
-        return nullptr;
-      }
-    }
-
-    config->key_exchanges.push_back(std::move(ka));
-  }
-
-  uint64_t expiry_seconds;
-  if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
-    QUIC_LOG(WARNING) << "Server config message is missing EXPY";
-    return nullptr;
-  }
-  config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds);
-
-  return config;
-}
-
-void QuicCryptoServerConfig::set_replay_protection(bool on) {
-  replay_protection_ = on;
-}
-
-void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) {
-  chlo_multiplier_ = multiplier;
-}
-
-void QuicCryptoServerConfig::set_source_address_token_future_secs(
-    uint32_t future_secs) {
-  source_address_token_future_secs_ = future_secs;
-}
-
-void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
-    uint32_t lifetime_secs) {
-  source_address_token_lifetime_secs_ = lifetime_secs;
-}
-
-void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
-  enable_serving_sct_ = enable_serving_sct;
-}
-
-void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
-    std::unique_ptr<PrimaryConfigChangedCallback> cb) {
-  QuicWriterMutexLock locked(&configs_lock_);
-  primary_config_changed_cb_ = std::move(cb);
-}
-
-std::string QuicCryptoServerConfig::NewSourceAddressToken(
-    const CryptoSecretBoxer& crypto_secret_boxer,
-    const SourceAddressTokens& previous_tokens,
-    const QuicIpAddress& ip,
-    QuicRandom* rand,
-    QuicWallTime now,
-    const CachedNetworkParameters* cached_network_params) const {
-  SourceAddressTokens source_address_tokens;
-  SourceAddressToken* source_address_token = source_address_tokens.add_tokens();
-  source_address_token->set_ip(ip.DualStacked().ToPackedString());
-  source_address_token->set_timestamp(now.ToUNIXSeconds());
-  if (cached_network_params != nullptr) {
-    *(source_address_token->mutable_cached_network_parameters()) =
-        *cached_network_params;
-  }
-
-  // Append previous tokens.
-  for (const SourceAddressToken& token : previous_tokens.tokens()) {
-    if (source_address_tokens.tokens_size() > kMaxTokenAddresses) {
-      break;
-    }
-
-    if (token.ip() == source_address_token->ip()) {
-      // It's for the same IP address.
-      continue;
-    }
-
-    if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) {
-      continue;
-    }
-
-    *(source_address_tokens.add_tokens()) = token;
-  }
-
-  return crypto_secret_boxer.Box(rand,
-                                 source_address_tokens.SerializeAsString());
-}
-
-int QuicCryptoServerConfig::NumberOfConfigs() const {
-  QuicReaderMutexLock locked(&configs_lock_);
-  return configs_.size();
-}
-
-ProofSource* QuicCryptoServerConfig::proof_source() const {
-  return proof_source_.get();
-}
-
-SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const {
-  return ssl_ctx_.get();
-}
-
-HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
-    const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
-    SourceAddressTokens& tokens) const {
-  std::string storage;
-  absl::string_view plaintext;
-  if (!crypto_secret_boxer.Unbox(token, &storage, &plaintext)) {
-    return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
-  }
-
-  if (!tokens.ParseFromArray(plaintext.data(), plaintext.size())) {
-    // Some clients might still be using the old source token format so
-    // attempt to parse that format.
-    // TODO(rch): remove this code once the new format is ubiquitous.
-    SourceAddressToken token;
-    if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
-      return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
-    }
-    *tokens.add_tokens() = token;
-  }
-
-  return HANDSHAKE_OK;
-}
-
-HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
-    const SourceAddressTokens& source_address_tokens,
-    const QuicIpAddress& ip,
-    QuicWallTime now,
-    CachedNetworkParameters* cached_network_params) const {
-  HandshakeFailureReason reason =
-      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
-  for (const SourceAddressToken& token : source_address_tokens.tokens()) {
-    reason = ValidateSingleSourceAddressToken(token, ip, now);
-    if (reason == HANDSHAKE_OK) {
-      if (cached_network_params != nullptr &&
-          token.has_cached_network_parameters()) {
-        *cached_network_params = token.cached_network_parameters();
-      }
-      break;
-    }
-  }
-  return reason;
-}
-
-HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
-    const SourceAddressToken& source_address_token,
-    const QuicIpAddress& ip,
-    QuicWallTime now) const {
-  if (source_address_token.ip() != ip.DualStacked().ToPackedString()) {
-    // It's for a different IP address.
-    return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
-  }
-
-  return ValidateSourceAddressTokenTimestamp(source_address_token, now);
-}
-
-HandshakeFailureReason
-QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
-    const SourceAddressToken& source_address_token,
-    QuicWallTime now) const {
-  const QuicWallTime timestamp(
-      QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
-  const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
-
-  if (now.IsBefore(timestamp) &&
-      delta.ToSeconds() > source_address_token_future_secs_) {
-    return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
-  }
-
-  if (now.IsAfter(timestamp) &&
-      delta.ToSeconds() > source_address_token_lifetime_secs_) {
-    return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
-  }
-
-  return HANDSHAKE_OK;
-}
-
-// kServerNoncePlaintextSize is the number of bytes in an unencrypted server
-// nonce.
-static const size_t kServerNoncePlaintextSize =
-    4 /* timestamp */ + 20 /* random bytes */;
-
-std::string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
-                                                   QuicWallTime now) const {
-  const uint32_t timestamp = static_cast<uint32_t>(now.ToUNIXSeconds());
-
-  uint8_t server_nonce[kServerNoncePlaintextSize];
-  static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small");
-  server_nonce[0] = static_cast<uint8_t>(timestamp >> 24);
-  server_nonce[1] = static_cast<uint8_t>(timestamp >> 16);
-  server_nonce[2] = static_cast<uint8_t>(timestamp >> 8);
-  server_nonce[3] = static_cast<uint8_t>(timestamp);
-  rand->RandBytes(&server_nonce[sizeof(timestamp)],
-                  sizeof(server_nonce) - sizeof(timestamp));
-
-  return server_nonce_boxer_.Box(
-      rand, absl::string_view(reinterpret_cast<char*>(server_nonce),
-                              sizeof(server_nonce)));
-}
-
-bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
-    const CryptoHandshakeMessage& client_hello,
-    const std::vector<std::string>& certs) const {
-  if (certs.empty()) {
-    return false;
-  }
-
-  uint64_t hash_from_client;
-  if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
-    return false;
-  }
-  return CryptoUtils::ComputeLeafCertHash(certs.at(0)) == hash_from_client;
-}
-
-bool QuicCryptoServerConfig::IsNextConfigReady(QuicWallTime now) const {
-  return !next_config_promotion_time_.IsZero() &&
-         !next_config_promotion_time_.IsAfter(now);
-}
-
-QuicCryptoServerConfig::Config::Config()
-    : channel_id_enabled(false),
-      is_primary(false),
-      primary_time(QuicWallTime::Zero()),
-      expiry_time(QuicWallTime::Zero()),
-      priority(0),
-      source_address_token_boxer(nullptr) {}
-
-QuicCryptoServerConfig::Config::~Config() {}
-
-QuicSignedServerConfig::QuicSignedServerConfig() {}
-QuicSignedServerConfig::~QuicSignedServerConfig() {}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_crypto_server_config.h b/quic/core/crypto/quic_crypto_server_config.h
deleted file mode 100644
index 3e7acb2..0000000
--- a/quic/core/crypto/quic_crypto_server_config.h
+++ /dev/null
@@ -1,965 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_secret_boxer.h"
-#include "quic/core/crypto/key_exchange.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_crypto_proof.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/proto/source_address_token_proto.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_reference_counted.h"
-
-namespace quic {
-
-class CryptoHandshakeMessage;
-class ProofSource;
-class QuicClock;
-class QuicRandom;
-class QuicServerConfigProtobuf;
-struct QuicSignedServerConfig;
-
-// ClientHelloInfo contains information about a client hello message that is
-// only kept for as long as it's being processed.
-struct QUIC_EXPORT_PRIVATE ClientHelloInfo {
-  ClientHelloInfo(const QuicIpAddress& in_client_ip, QuicWallTime in_now);
-  ClientHelloInfo(const ClientHelloInfo& other);
-  ~ClientHelloInfo();
-
-  // Inputs to EvaluateClientHello.
-  const QuicIpAddress client_ip;
-  const QuicWallTime now;
-
-  // Outputs from EvaluateClientHello.
-  bool valid_source_address_token;
-  absl::string_view sni;
-  absl::string_view client_nonce;
-  absl::string_view server_nonce;
-  absl::string_view user_agent_id;
-  SourceAddressTokens source_address_tokens;
-
-  // Errors from EvaluateClientHello.
-  std::vector<uint32_t> reject_reasons;
-  static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
-};
-
-namespace test {
-class QuicCryptoServerConfigPeer;
-}  // namespace test
-
-// Hook that allows application code to subscribe to primary config changes.
-class QUIC_EXPORT_PRIVATE PrimaryConfigChangedCallback {
- public:
-  PrimaryConfigChangedCallback();
-  PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete;
-  PrimaryConfigChangedCallback& operator=(const PrimaryConfigChangedCallback&) =
-      delete;
-  virtual ~PrimaryConfigChangedCallback();
-  virtual void Run(const std::string& scid) = 0;
-};
-
-// Callback used to accept the result of the |client_hello| validation step.
-class QUIC_EXPORT_PRIVATE ValidateClientHelloResultCallback {
- public:
-  // Opaque token that holds information about the client_hello and
-  // its validity.  Can be interpreted by calling ProcessClientHello.
-  struct QUIC_EXPORT_PRIVATE Result : public quiche::QuicheReferenceCounted {
-    Result(const CryptoHandshakeMessage& in_client_hello,
-           QuicIpAddress in_client_ip,
-           QuicWallTime in_now);
-
-    CryptoHandshakeMessage client_hello;
-    ClientHelloInfo info;
-    QuicErrorCode error_code;
-    std::string error_details;
-
-    // Populated if the CHLO STK contained a CachedNetworkParameters proto.
-    CachedNetworkParameters cached_network_params;
-
-   protected:
-    ~Result() override;
-  };
-
-  ValidateClientHelloResultCallback();
-  ValidateClientHelloResultCallback(const ValidateClientHelloResultCallback&) =
-      delete;
-  ValidateClientHelloResultCallback& operator=(
-      const ValidateClientHelloResultCallback&) = delete;
-  virtual ~ValidateClientHelloResultCallback();
-  virtual void Run(quiche::QuicheReferenceCountedPointer<Result> result,
-                   std::unique_ptr<ProofSource::Details> details) = 0;
-};
-
-// Callback used to accept the result of the ProcessClientHello method.
-class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback {
- public:
-  ProcessClientHelloResultCallback();
-  ProcessClientHelloResultCallback(const ProcessClientHelloResultCallback&) =
-      delete;
-  ProcessClientHelloResultCallback& operator=(
-      const ProcessClientHelloResultCallback&) = delete;
-  virtual ~ProcessClientHelloResultCallback();
-  virtual void Run(QuicErrorCode error,
-                   const std::string& error_details,
-                   std::unique_ptr<CryptoHandshakeMessage> message,
-                   std::unique_ptr<DiversificationNonce> diversification_nonce,
-                   std::unique_ptr<ProofSource::Details> details) = 0;
-};
-
-// Callback used to receive the results of a call to
-// BuildServerConfigUpdateMessage.
-class QUIC_EXPORT_PRIVATE BuildServerConfigUpdateMessageResultCallback {
- public:
-  BuildServerConfigUpdateMessageResultCallback() = default;
-  virtual ~BuildServerConfigUpdateMessageResultCallback() {}
-  BuildServerConfigUpdateMessageResultCallback(
-      const BuildServerConfigUpdateMessageResultCallback&) = delete;
-  BuildServerConfigUpdateMessageResultCallback& operator=(
-      const BuildServerConfigUpdateMessageResultCallback&) = delete;
-  virtual void Run(bool ok, const CryptoHandshakeMessage& message) = 0;
-};
-
-// Object that is interested in built rejections (which include REJ, SREJ and
-// cheap SREJ).
-class QUIC_EXPORT_PRIVATE RejectionObserver {
- public:
-  RejectionObserver() = default;
-  virtual ~RejectionObserver() {}
-  RejectionObserver(const RejectionObserver&) = delete;
-  RejectionObserver& operator=(const RejectionObserver&) = delete;
-  // Called after a rejection is built.
-  virtual void OnRejectionBuilt(const std::vector<uint32_t>& reasons,
-                                CryptoHandshakeMessage* out) const = 0;
-};
-
-// Factory for creating KeyExchange objects.
-class QUIC_EXPORT_PRIVATE KeyExchangeSource {
- public:
-  virtual ~KeyExchangeSource() = default;
-
-  // Returns the default KeyExchangeSource.
-  static std::unique_ptr<KeyExchangeSource> Default();
-
-  // Create a new KeyExchange using the curve specified by |type| using the
-  // specified private key.  |private_key| may be empty for key-exchange
-  // mechanisms which do not hold the private key in-process.  If |is_fallback|
-  // is set, |private_key| is required to be set, and a local key-exchange
-  // object should be returned.
-  virtual std::unique_ptr<AsynchronousKeyExchange> Create(
-      std::string server_config_id,
-      bool is_fallback,
-      QuicTag type,
-      absl::string_view private_key) = 0;
-};
-
-// QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
-// Unlike a client, a QUIC server can have multiple configurations active in
-// order to support clients resuming with a previous configuration.
-// TODO(agl): when adding configurations at runtime is added, this object will
-// need to consider locking.
-class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
- public:
-  // ConfigOptions contains options for generating server configs.
-  struct QUIC_EXPORT_PRIVATE ConfigOptions {
-    ConfigOptions();
-    ConfigOptions(const ConfigOptions& other);
-    ~ConfigOptions();
-
-    // expiry_time is the time, in UNIX seconds, when the server config will
-    // expire. If unset, it defaults to the current time plus six months.
-    QuicWallTime expiry_time;
-    // channel_id_enabled controls whether the server config will indicate
-    // support for ChannelIDs.
-    bool channel_id_enabled;
-    // id contains the server config id for the resulting config. If empty, a
-    // random id is generated.
-    std::string id;
-    // orbit contains the kOrbitSize bytes of the orbit value for the server
-    // config. If |orbit| is empty then a random orbit is generated.
-    std::string orbit;
-    // p256 determines whether a P-256 public key will be included in the
-    // server config. Note that this breaks deterministic server-config
-    // generation since P-256 key generation doesn't use the QuicRandom given
-    // to GenerateConfig().
-    bool p256;
-  };
-
-  // |source_address_token_secret|: secret key material used for encrypting and
-  //     decrypting source address tokens. It can be of any length as it is fed
-  //     into a KDF before use. In tests, use TESTING.
-  // |server_nonce_entropy|: an entropy source used to generate the orbit and
-  //     key for server nonces, which are always local to a given instance of a
-  //     server. Not owned.
-  // |proof_source|: provides certificate chains and signatures.
-  // |key_exchange_source|: provides key-exchange functionality.
-  QuicCryptoServerConfig(
-      absl::string_view source_address_token_secret,
-      QuicRandom* server_nonce_entropy,
-      std::unique_ptr<ProofSource> proof_source,
-      std::unique_ptr<KeyExchangeSource> key_exchange_source);
-  QuicCryptoServerConfig(const QuicCryptoServerConfig&) = delete;
-  QuicCryptoServerConfig& operator=(const QuicCryptoServerConfig&) = delete;
-  ~QuicCryptoServerConfig();
-
-  // TESTING is a magic parameter for passing to the constructor in tests.
-  static const char TESTING[];
-
-  // Generates a QuicServerConfigProtobuf protobuf suitable for
-  // AddConfig and SetConfigs.
-  static QuicServerConfigProtobuf GenerateConfig(QuicRandom* rand,
-                                                 const QuicClock* clock,
-                                                 const ConfigOptions& options);
-
-  // AddConfig adds a QuicServerConfigProtobuf to the available configurations.
-  // It returns the SCFG message from the config if successful. |now| is used in
-  // conjunction with |protobuf->primary_time()| to determine whether the
-  // config should be made primary.
-  std::unique_ptr<CryptoHandshakeMessage> AddConfig(
-      const QuicServerConfigProtobuf& protobuf,
-      QuicWallTime now);
-
-  // AddDefaultConfig calls GenerateConfig to create a config and then calls
-  // AddConfig to add it. See the comment for |GenerateConfig| for details of
-  // the arguments.
-  std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig(
-      QuicRandom* rand,
-      const QuicClock* clock,
-      const ConfigOptions& options);
-
-  // SetConfigs takes a vector of config protobufs and the current time.
-  // Configs are assumed to be uniquely identified by their server config ID.
-  // Previously unknown configs are added and possibly made the primary config
-  // depending on their |primary_time| and the value of |now|. Configs that are
-  // known, but are missing from the protobufs are deleted, unless they are
-  // currently the primary config. SetConfigs returns false if any errors were
-  // encountered and no changes to the QuicCryptoServerConfig will occur.
-  bool SetConfigs(const std::vector<QuicServerConfigProtobuf>& protobufs,
-                  const QuicServerConfigProtobuf* fallback_protobuf,
-                  QuicWallTime now);
-
-  // SetSourceAddressTokenKeys sets the keys to be tried, in order, when
-  // decrypting a source address token.  Note that these keys are used *without*
-  // passing them through a KDF, in contradistinction to the
-  // |source_address_token_secret| argument to the constructor.
-  void SetSourceAddressTokenKeys(const std::vector<std::string>& keys);
-
-  // Get the server config ids for all known configs.
-  std::vector<std::string> GetConfigIds() const;
-
-  // Checks |client_hello| for gross errors and determines whether it can be
-  // shown to be fresh (i.e. not a replay).  The result of the validation step
-  // must be interpreted by calling QuicCryptoServerConfig::ProcessClientHello
-  // from the done_cb.
-  //
-  // ValidateClientHello may invoke the done_cb before unrolling the
-  // stack if it is able to assess the validity of the client_nonce
-  // without asynchronous operations.
-  //
-  // client_hello: the incoming client hello message.
-  // client_ip: the IP address of the client, which is used to generate and
-  //     validate source-address tokens.
-  // server_address: the IP address and port of the server. The IP address and
-  //     port may be used for certificate selection.
-  // version: protocol version used for this connection.
-  // clock: used to validate client nonces and ephemeral keys.
-  // signed_config: in/out parameter to which will be written the crypto proof
-  //     used in reply to a proof demand.  The pointed-to-object must live until
-  //     the callback is invoked.
-  // done_cb: single-use callback that accepts an opaque
-  //     ValidatedClientHelloMsg token that holds information about
-  //     the client hello.  The callback will always be called exactly
-  //     once, either under the current call stack, or after the
-  //     completion of an asynchronous operation.
-  void ValidateClientHello(
-      const CryptoHandshakeMessage& client_hello,
-      const QuicSocketAddress& client_address,
-      const QuicSocketAddress& server_address, QuicTransportVersion version,
-      const QuicClock* clock,
-      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-          signed_config,
-      std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
-
-  // ProcessClientHello processes |client_hello| and decides whether to accept
-  // or reject the connection. If the connection is to be accepted, |done_cb| is
-  // invoked with the contents of the ServerHello and QUIC_NO_ERROR. Otherwise
-  // |done_cb| is called with a REJ or SREJ message and QUIC_NO_ERROR.
-  //
-  // validate_chlo_result: Output from the asynchronous call to
-  //     ValidateClientHello.  Contains the client hello message and
-  //     information about it.
-  // reject_only: Only generate rejections, not server hello messages.
-  // connection_id: the ConnectionId for the connection, which is used in key
-  //     derivation.
-  // server_ip: the IP address of the server. The IP address may be used for
-  //     certificate selection.
-  // client_address: the IP address and port of the client. The IP address is
-  //     used to generate and validate source-address tokens.
-  // version: version of the QUIC protocol in use for this connection
-  // supported_versions: versions of the QUIC protocol that this server
-  //     supports.
-  // clock: used to validate client nonces and ephemeral keys.
-  // rand: an entropy source
-  // compressed_certs_cache: the cache that caches a set of most recently used
-  //     certs. Owned by QuicDispatcher.
-  // params: the state of the handshake. This may be updated with a server
-  //     nonce when we send a rejection.
-  // signed_config: output structure containing the crypto proof used in reply
-  //     to a proof demand.
-  // total_framing_overhead: the total per-packet overhead for a stream frame
-  // chlo_packet_size: the size, in bytes, of the CHLO packet
-  // done_cb: the callback invoked on completion
-  void ProcessClientHello(
-      quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>
-          validate_chlo_result,
-      bool reject_only, QuicConnectionId connection_id,
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, ParsedQuicVersion version,
-      const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
-      QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
-      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-          params,
-      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-          signed_config,
-      QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
-      std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const;
-
-  // BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing
-  // the current primary config, an up to date source-address token, and cert
-  // chain and proof in the case of secure QUIC. Passes true to |cb| if the
-  // message was generated successfully, and false otherwise.  This method
-  // assumes ownership of |cb|.
-  //
-  // |cached_network_params| is optional, and can be nullptr.
-  void BuildServerConfigUpdateMessage(
-      QuicTransportVersion version,
-      absl::string_view chlo_hash,
-      const SourceAddressTokens& previous_source_address_tokens,
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      const QuicClock* clock,
-      QuicRandom* rand,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      const QuicCryptoNegotiatedParameters& params,
-      const CachedNetworkParameters* cached_network_params,
-      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
-
-  // set_replay_protection controls whether replay protection is enabled. If
-  // replay protection is disabled then no strike registers are needed and
-  // frontends can share an orbit value without a shared strike-register.
-  // However, an attacker can duplicate a handshake and cause a client's
-  // request to be processed twice.
-  void set_replay_protection(bool on);
-
-  // set_chlo_multiplier specifies the multiple of the CHLO message size
-  // that a REJ message must stay under when the client doesn't present a
-  // valid source-address token.
-  void set_chlo_multiplier(size_t multiplier);
-
-  // When sender is allowed to not pad client hello (not standards compliant),
-  // we need to disable the client hello check.
-  void set_validate_chlo_size(bool new_value) {
-    validate_chlo_size_ = new_value;
-  }
-
-  // Returns whether the sender is allowed to not pad the client hello.
-  bool validate_chlo_size() const { return validate_chlo_size_; }
-
-  // When QUIC is tunneled through some other mechanism, source token validation
-  // may be disabled. Do not disable it if you are not providing other
-  // protection. (|true| protects against UDP amplification attack.).
-  void set_validate_source_address_token(bool new_value) {
-    validate_source_address_token_ = new_value;
-  }
-
-  // set_source_address_token_future_secs sets the number of seconds into the
-  // future that source-address tokens will be accepted from. Since
-  // source-address tokens are authenticated, this should only happen if
-  // another, valid server has clock-skew.
-  void set_source_address_token_future_secs(uint32_t future_secs);
-
-  // set_source_address_token_lifetime_secs sets the number of seconds that a
-  // source-address token will be valid for.
-  void set_source_address_token_lifetime_secs(uint32_t lifetime_secs);
-
-  // set_enable_serving_sct enables or disables serving signed cert timestamp
-  // (RFC6962) in server hello.
-  void set_enable_serving_sct(bool enable_serving_sct);
-
-  // Set and take ownership of the callback to invoke on primary config changes.
-  void AcquirePrimaryConfigChangedCb(
-      std::unique_ptr<PrimaryConfigChangedCallback> cb);
-
-  // Returns the number of configs this object owns.
-  int NumberOfConfigs() const;
-
-  // NewSourceAddressToken returns a fresh source address token for the given
-  // IP address. |previous_tokens| is the received tokens, and can be empty.
-  // |cached_network_params| is optional, and can be nullptr.
-  std::string NewSourceAddressToken(
-      const CryptoSecretBoxer& crypto_secret_boxer,
-      const SourceAddressTokens& previous_tokens,
-      const QuicIpAddress& ip,
-      QuicRandom* rand,
-      QuicWallTime now,
-      const CachedNetworkParameters* cached_network_params) const;
-
-  // ParseSourceAddressToken parses the source address tokens contained in
-  // the encrypted |token|, and populates |tokens| with the parsed tokens.
-  // Returns HANDSHAKE_OK if |token| could be parsed, or the reason for the
-  // failure.
-  HandshakeFailureReason ParseSourceAddressToken(
-      const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
-      SourceAddressTokens& tokens) const;
-
-  // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address
-  // tokens in |tokens| contain a valid and timely token for the IP address
-  // |ip| given that the current time is |now|. Otherwise it returns the
-  // reason for failure. |cached_network_params| is populated if the valid
-  // token contains a CachedNetworkParameters proto.
-  HandshakeFailureReason ValidateSourceAddressTokens(
-      const SourceAddressTokens& tokens,
-      const QuicIpAddress& ip,
-      QuicWallTime now,
-      CachedNetworkParameters* cached_network_params) const;
-
-  // Callers retain the ownership of |rejection_observer| which must outlive the
-  // config.
-  void set_rejection_observer(RejectionObserver* rejection_observer) {
-    rejection_observer_ = rejection_observer;
-  }
-
-  ProofSource* proof_source() const;
-
-  SSL_CTX* ssl_ctx() const;
-
-  // Pre-shared key used during the handshake.
-  const std::string& pre_shared_key() const { return pre_shared_key_; }
-  void set_pre_shared_key(absl::string_view psk) {
-    pre_shared_key_ = std::string(psk);
-  }
-
-  bool pad_rej() const { return pad_rej_; }
-  void set_pad_rej(bool new_value) { pad_rej_ = new_value; }
-
-  bool pad_shlo() const { return pad_shlo_; }
-  void set_pad_shlo(bool new_value) { pad_shlo_ = new_value; }
-
-  const CryptoSecretBoxer& source_address_token_boxer() const {
-    return source_address_token_boxer_;
-  }
-
- private:
-  friend class test::QuicCryptoServerConfigPeer;
-  friend struct QuicSignedServerConfig;
-
-  // Config represents a server config: a collection of preferences and
-  // Diffie-Hellman public values.
-  class QUIC_EXPORT_PRIVATE Config : public QuicCryptoConfig,
-                                     public quiche::QuicheReferenceCounted {
-   public:
-    Config();
-    Config(const Config&) = delete;
-    Config& operator=(const Config&) = delete;
-
-    // TODO(rtenneti): since this is a class, we should probably do
-    // getters/setters here.
-    // |serialized| contains the bytes of this server config, suitable for
-    // sending on the wire.
-    std::string serialized;
-    // id contains the SCID of this server config.
-    std::string id;
-    // orbit contains the orbit value for this config: an opaque identifier
-    // used to identify clusters of server frontends.
-    unsigned char orbit[kOrbitSize];
-
-    // key_exchanges contains key exchange objects. The values correspond,
-    // one-to-one, with the tags in |kexs| from the parent class.
-    std::vector<std::unique_ptr<AsynchronousKeyExchange>> key_exchanges;
-
-    // channel_id_enabled is true if the config in |serialized| specifies that
-    // ChannelIDs are supported.
-    bool channel_id_enabled;
-
-    // is_primary is true if this config is the one that we'll give out to
-    // clients as the current one.
-    bool is_primary;
-
-    // primary_time contains the timestamp when this config should become the
-    // primary config. A value of QuicWallTime::Zero() means that this config
-    // will not be promoted at a specific time.
-    QuicWallTime primary_time;
-
-    // expiry_time contains the timestamp when this config expires.
-    QuicWallTime expiry_time;
-
-    // Secondary sort key for use when selecting primary configs and
-    // there are multiple configs with the same primary time.
-    // Smaller numbers mean higher priority.
-    uint64_t priority;
-
-    // source_address_token_boxer_ is used to protect the
-    // source-address tokens that are given to clients.
-    // Points to either source_address_token_boxer_storage or the
-    // default boxer provided by QuicCryptoServerConfig.
-    const CryptoSecretBoxer* source_address_token_boxer;
-
-    // Holds the override source_address_token_boxer instance if the
-    // Config is not using the default source address token boxer
-    // instance provided by QuicCryptoServerConfig.
-    std::unique_ptr<CryptoSecretBoxer> source_address_token_boxer_storage;
-
-   private:
-    ~Config() override;
-  };
-
-  using ConfigMap =
-      std::map<ServerConfigID, quiche::QuicheReferenceCountedPointer<Config>>;
-
-  // Get a ref to the config with a given server config id.
-  quiche::QuicheReferenceCountedPointer<Config> GetConfigWithScid(
-      absl::string_view requested_scid) const
-      QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
-
-  // A snapshot of the configs associated with an in-progress handshake.
-  struct QUIC_EXPORT_PRIVATE Configs {
-    quiche::QuicheReferenceCountedPointer<Config> requested;
-    quiche::QuicheReferenceCountedPointer<Config> primary;
-    quiche::QuicheReferenceCountedPointer<Config> fallback;
-  };
-
-  // Get a snapshot of the current configs associated with a handshake.  If this
-  // method was called earlier in this handshake |old_primary_config| should be
-  // set to the primary config returned from that invocation, otherwise nullptr.
-  //
-  // Returns true if any configs are loaded.  If false is returned, |configs| is
-  // not modified.
-  bool GetCurrentConfigs(
-      const QuicWallTime& now, absl::string_view requested_scid,
-      quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
-      Configs* configs) const;
-
-  // ConfigPrimaryTimeLessThan returns true if a->primary_time <
-  // b->primary_time.
-  static bool ConfigPrimaryTimeLessThan(
-      const quiche::QuicheReferenceCountedPointer<Config>& a,
-      const quiche::QuicheReferenceCountedPointer<Config>& b);
-
-  // SelectNewPrimaryConfig reevaluates the primary config based on the
-  // "primary_time" deadlines contained in each.
-  void SelectNewPrimaryConfig(QuicWallTime now) const
-      QUIC_EXCLUSIVE_LOCKS_REQUIRED(configs_lock_);
-
-  // EvaluateClientHello checks |client_hello_state->client_hello| for gross
-  // errors and determines whether it is fresh (i.e. not a replay). The results
-  // are written to |client_hello_state->info|.
-  void EvaluateClientHello(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, QuicTransportVersion version,
-      const Configs& configs,
-      quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>
-          client_hello_state,
-      std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
-
-  // Convenience class which carries the arguments passed to
-  // |ProcessClientHellp| along.
-  class QUIC_EXPORT_PRIVATE ProcessClientHelloContext {
-   public:
-    ProcessClientHelloContext(
-        quiche::QuicheReferenceCountedPointer<
-            ValidateClientHelloResultCallback::Result>
-            validate_chlo_result,
-        bool reject_only, QuicConnectionId connection_id,
-        const QuicSocketAddress& server_address,
-        const QuicSocketAddress& client_address, ParsedQuicVersion version,
-        const ParsedQuicVersionVector& supported_versions,
-        const QuicClock* clock, QuicRandom* rand,
-        QuicCompressedCertsCache* compressed_certs_cache,
-        quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-            params,
-        quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-            signed_config,
-        QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
-        std::unique_ptr<ProcessClientHelloResultCallback> done_cb)
-        : validate_chlo_result_(validate_chlo_result),
-          reject_only_(reject_only),
-          connection_id_(connection_id),
-          server_address_(server_address),
-          client_address_(client_address),
-          version_(version),
-          supported_versions_(supported_versions),
-          clock_(clock),
-          rand_(rand),
-          compressed_certs_cache_(compressed_certs_cache),
-          params_(params),
-          signed_config_(signed_config),
-          total_framing_overhead_(total_framing_overhead),
-          chlo_packet_size_(chlo_packet_size),
-          done_cb_(std::move(done_cb)) {}
-
-    ~ProcessClientHelloContext();
-
-    // Invoke |done_cb_| with an error status
-    void Fail(QuicErrorCode error, const std::string& error_details);
-
-    // Invoke |done_cb_| with a success status
-    void Succeed(std::unique_ptr<CryptoHandshakeMessage> message,
-                 std::unique_ptr<DiversificationNonce> diversification_nonce,
-                 std::unique_ptr<ProofSource::Details> proof_source_details);
-
-    // Member accessors
-    quiche::QuicheReferenceCountedPointer<
-        ValidateClientHelloResultCallback::Result>
-    validate_chlo_result() const {
-      return validate_chlo_result_;
-    }
-    bool reject_only() const { return reject_only_; }
-    QuicConnectionId connection_id() const { return connection_id_; }
-    QuicSocketAddress server_address() const { return server_address_; }
-    QuicSocketAddress client_address() const { return client_address_; }
-    ParsedQuicVersion version() const { return version_; }
-    ParsedQuicVersionVector supported_versions() const {
-      return supported_versions_;
-    }
-    const QuicClock* clock() const { return clock_; }
-    QuicRandom* rand() const { return rand_; }  // NOLINT
-    QuicCompressedCertsCache* compressed_certs_cache() const {
-      return compressed_certs_cache_;
-    }
-    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-    params() const {
-      return params_;
-    }
-    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-    signed_config() const {
-      return signed_config_;
-    }
-    QuicByteCount total_framing_overhead() const {
-      return total_framing_overhead_;
-    }
-    QuicByteCount chlo_packet_size() const { return chlo_packet_size_; }
-
-    // Derived value accessors
-    const CryptoHandshakeMessage& client_hello() const {
-      return validate_chlo_result()->client_hello;
-    }
-    const ClientHelloInfo& info() const { return validate_chlo_result()->info; }
-    QuicTransportVersion transport_version() const {
-      return version().transport_version;
-    }
-
-   private:
-    const quiche::QuicheReferenceCountedPointer<
-        ValidateClientHelloResultCallback::Result>
-        validate_chlo_result_;
-    const bool reject_only_;
-    const QuicConnectionId connection_id_;
-    const QuicSocketAddress server_address_;
-    const QuicSocketAddress client_address_;
-    const ParsedQuicVersion version_;
-    const ParsedQuicVersionVector supported_versions_;
-    const QuicClock* const clock_;
-    QuicRandom* const rand_;
-    QuicCompressedCertsCache* const compressed_certs_cache_;
-    const quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-        params_;
-    const quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-        signed_config_;
-    const QuicByteCount total_framing_overhead_;
-    const QuicByteCount chlo_packet_size_;
-    std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
-  };
-
-  // Callback class for bridging between ProcessClientHello and
-  // ProcessClientHelloAfterGetProof.
-  class ProcessClientHelloCallback;
-  friend class ProcessClientHelloCallback;
-
-  // Portion of ProcessClientHello which executes after GetProof.
-  void ProcessClientHelloAfterGetProof(
-      bool found_error,
-      std::unique_ptr<ProofSource::Details> proof_source_details,
-      std::unique_ptr<ProcessClientHelloContext> context,
-      const Configs& configs) const;
-
-  // Callback class for bridging between ProcessClientHelloAfterGetProof and
-  // ProcessClientHelloAfterCalculateSharedKeys.
-  class ProcessClientHelloAfterGetProofCallback;
-  friend class ProcessClientHelloAfterGetProofCallback;
-
-  // Portion of ProcessClientHello which executes after CalculateSharedKeys.
-  void ProcessClientHelloAfterCalculateSharedKeys(
-      bool found_error,
-      std::unique_ptr<ProofSource::Details> proof_source_details,
-      QuicTag key_exchange_type,
-      std::unique_ptr<CryptoHandshakeMessage> out,
-      absl::string_view public_value,
-      std::unique_ptr<ProcessClientHelloContext> context,
-      const Configs& configs) const;
-
-  // Send a REJ which contains a different ServerConfig than the one the client
-  // originally used.  This is necessary in cases where we discover in the
-  // middle of the handshake that the private key for the ServerConfig the
-  // client used is not accessible.
-  void SendRejectWithFallbackConfig(
-      std::unique_ptr<ProcessClientHelloContext> context,
-      quiche::QuicheReferenceCountedPointer<Config> fallback_config) const;
-
-  // Callback class for bridging between SendRejectWithFallbackConfig and
-  // SendRejectWithFallbackConfigAfterGetProof.
-  class SendRejectWithFallbackConfigCallback;
-  friend class SendRejectWithFallbackConfigCallback;
-
-  // Portion of ProcessClientHello which executes after GetProof in the case
-  // where we have received a CHLO but need to reject it due to the ServerConfig
-  // private keys being inaccessible.
-  void SendRejectWithFallbackConfigAfterGetProof(
-      bool found_error,
-      std::unique_ptr<ProofSource::Details> proof_source_details,
-      std::unique_ptr<ProcessClientHelloContext> context,
-      quiche::QuicheReferenceCountedPointer<Config> fallback_config) const;
-
-  // BuildRejectionAndRecordStats calls |BuildRejection| below and also informs
-  // the RejectionObserver.
-  void BuildRejectionAndRecordStats(const ProcessClientHelloContext& context,
-                                    const Config& config,
-                                    const std::vector<uint32_t>& reject_reasons,
-                                    CryptoHandshakeMessage* out) const;
-
-  // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
-  void BuildRejection(const ProcessClientHelloContext& context,
-                      const Config& config,
-                      const std::vector<uint32_t>& reject_reasons,
-                      CryptoHandshakeMessage* out) const;
-
-  // CompressChain compresses the certificates in |chain->certs| and returns a
-  // compressed representation. |client_cached_cert_hashes| contains
-  // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
-  static std::string CompressChain(
-      QuicCompressedCertsCache* compressed_certs_cache,
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const std::string& client_cached_cert_hashes);
-
-  // ParseConfigProtobuf parses the given config protobuf and returns a
-  // quiche::QuicheReferenceCountedPointer<Config> if successful. The caller
-  // adopts the reference to the Config. On error, ParseConfigProtobuf returns
-  // nullptr.
-  quiche::QuicheReferenceCountedPointer<Config> ParseConfigProtobuf(
-      const QuicServerConfigProtobuf& protobuf, bool is_fallback) const;
-
-  // ValidateSingleSourceAddressToken returns HANDSHAKE_OK if the source
-  // address token in |token| is a timely token for the IP address |ip|
-  // given that the current time is |now|. Otherwise it returns the reason
-  // for failure.
-  HandshakeFailureReason ValidateSingleSourceAddressToken(
-      const SourceAddressToken& token,
-      const QuicIpAddress& ip,
-      QuicWallTime now) const;
-
-  // Returns HANDSHAKE_OK if the source address token in |token| is a timely
-  // token given that the current time is |now|. Otherwise it returns the
-  // reason for failure.
-  HandshakeFailureReason ValidateSourceAddressTokenTimestamp(
-      const SourceAddressToken& token,
-      QuicWallTime now) const;
-
-  // NewServerNonce generates and encrypts a random nonce.
-  std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
-
-  // ValidateExpectedLeafCertificate checks the |client_hello| to see if it has
-  // an XLCT tag, and if so, verifies that its value matches the hash of the
-  // server's leaf certificate. |certs| is used to compare against the XLCT
-  // value.  This method returns true if the XLCT tag is not present, or if the
-  // XLCT tag is present and valid. It returns false otherwise.
-  bool ValidateExpectedLeafCertificate(
-      const CryptoHandshakeMessage& client_hello,
-      const std::vector<std::string>& certs) const;
-
-  // Callback to receive the results of ProofSource::GetProof.  Note: this
-  // callback has no cancellation support, since the lifetime of the ProofSource
-  // is controlled by this object via unique ownership.  If that ownership
-  // stricture changes, this decision may need to be revisited.
-  class BuildServerConfigUpdateMessageProofSourceCallback
-      : public ProofSource::Callback {
-   public:
-    BuildServerConfigUpdateMessageProofSourceCallback(
-        const BuildServerConfigUpdateMessageProofSourceCallback&) = delete;
-    ~BuildServerConfigUpdateMessageProofSourceCallback() override;
-    void operator=(const BuildServerConfigUpdateMessageProofSourceCallback&) =
-        delete;
-    BuildServerConfigUpdateMessageProofSourceCallback(
-        const QuicCryptoServerConfig* config,
-        QuicCompressedCertsCache* compressed_certs_cache,
-        const QuicCryptoNegotiatedParameters& params,
-        CryptoHandshakeMessage message,
-        std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb);
-
-    void Run(
-        bool ok,
-        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-        const QuicCryptoProof& proof,
-        std::unique_ptr<ProofSource::Details> details) override;
-
-   private:
-    const QuicCryptoServerConfig* config_;
-    QuicCompressedCertsCache* compressed_certs_cache_;
-    const std::string client_cached_cert_hashes_;
-    const bool sct_supported_by_client_;
-    const std::string sni_;
-    CryptoHandshakeMessage message_;
-    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb_;
-  };
-
-  // Invoked by BuildServerConfigUpdateMessageProofSourceCallback::Run once
-  // the proof has been acquired.  Finishes building the server config update
-  // message and invokes |cb|.
-  void FinishBuildServerConfigUpdateMessage(
-      QuicCompressedCertsCache* compressed_certs_cache,
-      const std::string& client_cached_cert_hashes,
-      bool sct_supported_by_client, const std::string& sni, bool ok,
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const std::string& signature, const std::string& leaf_cert_sct,
-      std::unique_ptr<ProofSource::Details> details,
-      CryptoHandshakeMessage message,
-      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
-
-  // Returns true if the next config promotion should happen now.
-  bool IsNextConfigReady(QuicWallTime now) const
-      QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
-
-  // replay_protection_ controls whether the server enforces that handshakes
-  // aren't replays.
-  bool replay_protection_;
-
-  // The multiple of the CHLO message size that a REJ message must stay under
-  // when the client doesn't present a valid source-address token. This is
-  // used to protect QUIC from amplification attacks.
-  size_t chlo_multiplier_;
-
-  // configs_ satisfies the following invariants:
-  //   1) configs_.empty() <-> primary_config_ == nullptr
-  //   2) primary_config_ != nullptr -> primary_config_->is_primary
-  //   3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
-  mutable QuicMutex configs_lock_;
-
-  // configs_ contains all active server configs. It's expected that there are
-  // about half-a-dozen configs active at any one time.
-  ConfigMap configs_ QUIC_GUARDED_BY(configs_lock_);
-
-  // primary_config_ points to a Config (which is also in |configs_|) which is
-  // the primary config - i.e. the one that we'll give out to new clients.
-  mutable quiche::QuicheReferenceCountedPointer<Config> primary_config_
-      QUIC_GUARDED_BY(configs_lock_);
-
-  // fallback_config_ points to a Config (which is also in |configs_|) which is
-  // the fallback config, which will be used if the other configs are unuseable
-  // for some reason.
-  //
-  // TODO(b/112548056): This is currently always nullptr.
-  quiche::QuicheReferenceCountedPointer<Config> fallback_config_
-      QUIC_GUARDED_BY(configs_lock_);
-
-  // next_config_promotion_time_ contains the nearest, future time when an
-  // active config will be promoted to primary.
-  mutable QuicWallTime next_config_promotion_time_
-      QUIC_GUARDED_BY(configs_lock_);
-
-  // Callback to invoke when the primary config changes.
-  std::unique_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_
-      QUIC_GUARDED_BY(configs_lock_);
-
-  // Used to protect the source-address tokens that are given to clients.
-  CryptoSecretBoxer source_address_token_boxer_;
-
-  // server_nonce_boxer_ is used to encrypt and validate suggested server
-  // nonces.
-  CryptoSecretBoxer server_nonce_boxer_;
-
-  // server_nonce_orbit_ contains the random, per-server orbit values that this
-  // server will use to generate server nonces (the moral equivalent of a SYN
-  // cookies).
-  uint8_t server_nonce_orbit_[8];
-
-  // proof_source_ contains an object that can provide certificate chains and
-  // signatures.
-  std::unique_ptr<ProofSource> proof_source_;
-
-  // key_exchange_source_ contains an object that can provide key exchange
-  // objects.
-  std::unique_ptr<KeyExchangeSource> key_exchange_source_;
-
-  // ssl_ctx_ contains the server configuration for doing TLS handshakes.
-  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
-
-  // These fields store configuration values. See the comments for their
-  // respective setter functions.
-  uint32_t source_address_token_future_secs_;
-  uint32_t source_address_token_lifetime_secs_;
-
-  // Enable serving SCT or not.
-  bool enable_serving_sct_;
-
-  // Does not own this observer.
-  RejectionObserver* rejection_observer_;
-
-  // If non-empty, the server will operate in the pre-shared key mode by
-  // incorporating |pre_shared_key_| into the key schedule.
-  std::string pre_shared_key_;
-
-  // Whether REJ message should be padded to max packet size.
-  bool pad_rej_;
-
-  // Whether SHLO message should be padded to max packet size.
-  bool pad_shlo_;
-
-  // If client is allowed to send a small client hello (by disabling padding),
-  // server MUST not check for the client hello size.
-  // DO NOT disable this unless you have some other way of validating client.
-  // (e.g. in realtime scenarios, where quic is tunneled through ICE, ICE will
-  // do its own peer validation using STUN pings with ufrag/upass).
-  bool validate_chlo_size_;
-
-  // When source address is validated by some other means (e.g. when using ICE),
-  // source address token validation may be disabled.
-  bool validate_source_address_token_;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig
-    : public quiche::QuicheReferenceCounted {
-  QuicSignedServerConfig();
-
-  QuicCryptoProof proof;
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
-  // The server config that is used for this proof (and the rest of the
-  // request).
-  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config> config;
-  std::string primary_scid;
-
- protected:
-  ~QuicSignedServerConfig() override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
diff --git a/quic/core/crypto/quic_crypto_server_config_test.cc b/quic/core/crypto/quic_crypto_server_config_test.cc
deleted file mode 100644
index 720da63..0000000
--- a/quic/core/crypto/quic_crypto_server_config_test.cc
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_crypto_server_config.h"
-
-#include <stdarg.h>
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/cert_compressor.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_secret_boxer.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-using ::testing::Not;
-
-// NOTE: This matcher depends on the wire format of serialzied protocol buffers,
-// which may change in the future.
-// Switch to ::testing::EqualsProto once it is available in Chromium.
-MATCHER_P(SerializedProtoEquals, message, "") {
-  std::string expected_serialized, actual_serialized;
-  message.SerializeToString(&expected_serialized);
-  arg.SerializeToString(&actual_serialized);
-  return expected_serialized == actual_serialized;
-}
-
-class QuicCryptoServerConfigTest : public QuicTest {};
-
-TEST_F(QuicCryptoServerConfigTest, ServerConfig) {
-  QuicRandom* rand = QuicRandom::GetInstance();
-  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
-                                crypto_test_utils::ProofSourceForTesting(),
-                                KeyExchangeSource::Default());
-  MockClock clock;
-
-  std::unique_ptr<CryptoHandshakeMessage> message(server.AddDefaultConfig(
-      rand, &clock, QuicCryptoServerConfig::ConfigOptions()));
-
-  // The default configuration should have AES-GCM and at least one ChaCha20
-  // cipher.
-  QuicTagVector aead;
-  ASSERT_THAT(message->GetTaglist(kAEAD, &aead), IsQuicNoError());
-  EXPECT_THAT(aead, ::testing::Contains(kAESG));
-  EXPECT_LE(1u, aead.size());
-}
-
-TEST_F(QuicCryptoServerConfigTest, CompressCerts) {
-  QuicCompressedCertsCache compressed_certs_cache(
-      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-
-  QuicRandom* rand = QuicRandom::GetInstance();
-  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
-                                crypto_test_utils::ProofSourceForTesting(),
-                                KeyExchangeSource::Default());
-  QuicCryptoServerConfigPeer peer(&server);
-
-  std::vector<std::string> certs = {"testcert"};
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
-      new ProofSource::Chain(certs));
-
-  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
-      &compressed_certs_cache, chain, "");
-
-  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-}
-
-TEST_F(QuicCryptoServerConfigTest, CompressSameCertsTwice) {
-  QuicCompressedCertsCache compressed_certs_cache(
-      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-
-  QuicRandom* rand = QuicRandom::GetInstance();
-  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
-                                crypto_test_utils::ProofSourceForTesting(),
-                                KeyExchangeSource::Default());
-  QuicCryptoServerConfigPeer peer(&server);
-
-  // Compress the certs for the first time.
-  std::vector<std::string> certs = {"testcert"};
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
-      new ProofSource::Chain(certs));
-  std::string cached_certs = "";
-
-  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
-      &compressed_certs_cache, chain, cached_certs);
-  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-
-  // Compress the same certs, should use cache if available.
-  std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
-      &compressed_certs_cache, chain, cached_certs);
-  EXPECT_EQ(compressed, compressed2);
-  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-}
-
-TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) {
-  // This test compresses a set of similar but not identical certs. Cache if
-  // used should return cache miss and add all the compressed certs.
-  QuicCompressedCertsCache compressed_certs_cache(
-      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-
-  QuicRandom* rand = QuicRandom::GetInstance();
-  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
-                                crypto_test_utils::ProofSourceForTesting(),
-                                KeyExchangeSource::Default());
-  QuicCryptoServerConfigPeer peer(&server);
-
-  std::vector<std::string> certs = {"testcert"};
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
-      new ProofSource::Chain(certs));
-  std::string cached_certs = "";
-
-  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
-      &compressed_certs_cache, chain, cached_certs);
-  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
-
-  // Compress a similar certs which only differs in the chain.
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
-      new ProofSource::Chain(certs));
-
-  std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
-      &compressed_certs_cache, chain2, cached_certs);
-  EXPECT_EQ(compressed_certs_cache.Size(), 2u);
-}
-
-class SourceAddressTokenTest : public QuicTest {
- public:
-  SourceAddressTokenTest()
-      : ip4_(QuicIpAddress::Loopback4()),
-        ip4_dual_(ip4_.DualStacked()),
-        ip6_(QuicIpAddress::Loopback6()),
-        original_time_(QuicWallTime::Zero()),
-        rand_(QuicRandom::GetInstance()),
-        server_(QuicCryptoServerConfig::TESTING,
-                rand_,
-                crypto_test_utils::ProofSourceForTesting(),
-                KeyExchangeSource::Default()),
-        peer_(&server_) {
-    // Advance the clock to some non-zero time.
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
-    original_time_ = clock_.WallNow();
-
-    primary_config_ = server_.AddDefaultConfig(
-        rand_, &clock_, QuicCryptoServerConfig::ConfigOptions());
-  }
-
-  std::string NewSourceAddressToken(std::string config_id,
-                                    const QuicIpAddress& ip) {
-    return NewSourceAddressToken(config_id, ip, nullptr);
-  }
-
-  std::string NewSourceAddressToken(
-      std::string config_id,
-      const QuicIpAddress& ip,
-      const SourceAddressTokens& previous_tokens) {
-    return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
-                                       clock_.WallNow(), nullptr);
-  }
-
-  std::string NewSourceAddressToken(
-      std::string config_id,
-      const QuicIpAddress& ip,
-      CachedNetworkParameters* cached_network_params) {
-    SourceAddressTokens previous_tokens;
-    return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
-                                       clock_.WallNow(), cached_network_params);
-  }
-
-  HandshakeFailureReason ValidateSourceAddressTokens(std::string config_id,
-                                                     absl::string_view srct,
-                                                     const QuicIpAddress& ip) {
-    return ValidateSourceAddressTokens(config_id, srct, ip, nullptr);
-  }
-
-  HandshakeFailureReason ValidateSourceAddressTokens(
-      std::string config_id,
-      absl::string_view srct,
-      const QuicIpAddress& ip,
-      CachedNetworkParameters* cached_network_params) {
-    return peer_.ValidateSourceAddressTokens(
-        config_id, srct, ip, clock_.WallNow(), cached_network_params);
-  }
-
-  const std::string kPrimary = "<primary>";
-  const std::string kOverride = "Config with custom source address token key";
-
-  QuicIpAddress ip4_;
-  QuicIpAddress ip4_dual_;
-  QuicIpAddress ip6_;
-
-  MockClock clock_;
-  QuicWallTime original_time_;
-  QuicRandom* rand_ = QuicRandom::GetInstance();
-  QuicCryptoServerConfig server_;
-  QuicCryptoServerConfigPeer peer_;
-  // Stores the primary config.
-  std::unique_ptr<CryptoHandshakeMessage> primary_config_;
-  std::unique_ptr<QuicServerConfigProtobuf> override_config_protobuf_;
-};
-
-// Test basic behavior of source address tokens including being specific
-// to a single IP address and server config.
-TEST_F(SourceAddressTokenTest, SourceAddressToken) {
-  // Primary config generates configs that validate successfully.
-  const std::string token4 = NewSourceAddressToken(kPrimary, ip4_);
-  const std::string token4d = NewSourceAddressToken(kPrimary, ip4_dual_);
-  const std::string token6 = NewSourceAddressToken(kPrimary, ip6_);
-  EXPECT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4, ip4_));
-  ASSERT_EQ(HANDSHAKE_OK,
-            ValidateSourceAddressTokens(kPrimary, token4, ip4_dual_));
-  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
-            ValidateSourceAddressTokens(kPrimary, token4, ip6_));
-  ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4d, ip4_));
-  ASSERT_EQ(HANDSHAKE_OK,
-            ValidateSourceAddressTokens(kPrimary, token4d, ip4_dual_));
-  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
-            ValidateSourceAddressTokens(kPrimary, token4d, ip6_));
-  ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token6, ip6_));
-}
-
-TEST_F(SourceAddressTokenTest, SourceAddressTokenExpiration) {
-  const std::string token = NewSourceAddressToken(kPrimary, ip4_);
-
-  // Validation fails if the token is from the future.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(-3600 * 2));
-  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
-            ValidateSourceAddressTokens(kPrimary, token, ip4_));
-
-  // Validation fails after tokens expire.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400 * 7));
-  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
-            ValidateSourceAddressTokens(kPrimary, token, ip4_));
-}
-
-TEST_F(SourceAddressTokenTest, SourceAddressTokenWithNetworkParams) {
-  // Make sure that if the source address token contains CachedNetworkParameters
-  // that this gets written to ValidateSourceAddressToken output argument.
-  CachedNetworkParameters cached_network_params_input;
-  cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
-  const std::string token4_with_cached_network_params =
-      NewSourceAddressToken(kPrimary, ip4_, &cached_network_params_input);
-
-  CachedNetworkParameters cached_network_params_output;
-  EXPECT_THAT(cached_network_params_output,
-              Not(SerializedProtoEquals(cached_network_params_input)));
-  ValidateSourceAddressTokens(kPrimary, token4_with_cached_network_params, ip4_,
-                              &cached_network_params_output);
-  EXPECT_THAT(cached_network_params_output,
-              SerializedProtoEquals(cached_network_params_input));
-}
-
-// Test the ability for a source address token to be valid for multiple
-// addresses.
-TEST_F(SourceAddressTokenTest, SourceAddressTokenMultipleAddresses) {
-  QuicWallTime now = clock_.WallNow();
-
-  // Now create a token which is usable for both addresses.
-  SourceAddressToken previous_token;
-  previous_token.set_ip(ip6_.DualStacked().ToPackedString());
-  previous_token.set_timestamp(now.ToUNIXSeconds());
-  SourceAddressTokens previous_tokens;
-  (*previous_tokens.add_tokens()) = previous_token;
-  const std::string token4or6 =
-      NewSourceAddressToken(kPrimary, ip4_, previous_tokens);
-
-  EXPECT_EQ(HANDSHAKE_OK,
-            ValidateSourceAddressTokens(kPrimary, token4or6, ip4_));
-  ASSERT_EQ(HANDSHAKE_OK,
-            ValidateSourceAddressTokens(kPrimary, token4or6, ip6_));
-}
-
-class CryptoServerConfigsTest : public QuicTest {
- public:
-  CryptoServerConfigsTest()
-      : rand_(QuicRandom::GetInstance()),
-        config_(QuicCryptoServerConfig::TESTING,
-                rand_,
-                crypto_test_utils::ProofSourceForTesting(),
-                KeyExchangeSource::Default()),
-        test_peer_(&config_) {}
-
-  void SetUp() override {
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
-  }
-
-  // SetConfigs constructs suitable config protobufs and calls SetConfigs on
-  // |config_|.
-  // Each struct in the input vector contains 3 elements.
-  // The first is the server config ID of a Config. The second is
-  // the |primary_time| of that Config, given in epoch seconds. (Although note
-  // that, in these tests, time is set to 1000 seconds since the epoch.).
-  // The third is the priority.
-  //
-  // For example:
-  //   SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());  // calls
-  //   |config_.SetConfigs| with no protobufs.
-  //
-  //   // Calls |config_.SetConfigs| with two protobufs: one for a Config with
-  //   // a |primary_time| of 900 and priority 1, and another with
-  //   // a |primary_time| of 1000 and priority 2.
-
-  //   CheckConfigs(
-  //     {{"id1", 900,  1},
-  //      {"id2", 1000, 2}});
-  //
-  // If the server config id starts with "INVALID" then the generated protobuf
-  // will be invalid.
-  struct ServerConfigIDWithTimeAndPriority {
-    ServerConfigID server_config_id;
-    int primary_time;
-    int priority;
-  };
-  void SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority> configs) {
-    const char kOrbit[] = "12345678";
-
-    bool has_invalid = false;
-
-    std::vector<QuicServerConfigProtobuf> protobufs;
-    for (const auto& config : configs) {
-      const ServerConfigID& server_config_id = config.server_config_id;
-      const int primary_time = config.primary_time;
-      const int priority = config.priority;
-
-      QuicCryptoServerConfig::ConfigOptions options;
-      options.id = server_config_id;
-      options.orbit = kOrbit;
-      QuicServerConfigProtobuf protobuf =
-          QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options);
-      protobuf.set_primary_time(primary_time);
-      protobuf.set_priority(priority);
-      if (absl::StartsWith(std::string(server_config_id), "INVALID")) {
-        protobuf.clear_key();
-        has_invalid = true;
-      }
-      protobufs.push_back(std::move(protobuf));
-    }
-
-    ASSERT_EQ(!has_invalid && !configs.empty(),
-              config_.SetConfigs(protobufs, /* fallback_protobuf = */ nullptr,
-                                 clock_.WallNow()));
-  }
-
- protected:
-  QuicRandom* const rand_;
-  MockClock clock_;
-  QuicCryptoServerConfig config_;
-  QuicCryptoServerConfigPeer test_peer_;
-};
-
-TEST_F(CryptoServerConfigsTest, NoConfigs) {
-  test_peer_.CheckConfigs(std::vector<std::pair<std::string, bool>>());
-}
-
-TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
-  // Make sure that "b" is primary even though "a" comes first.
-  SetConfigs({{"a", 1100, 1}, {"b", 900, 1}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
-  // Make sure that a remains primary after b is added.
-  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, Delete) {
-  // Ensure that configs get deleted when removed.
-  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
-  SetConfigs({{"b", 900, 1}, {"c", 1100, 1}});
-  test_peer_.CheckConfigs({{"b", true}, {"c", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, DeletePrimary) {
-  // Ensure that deleting the primary config works.
-  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
-  SetConfigs({{"a", 800, 1}, {"c", 1100, 1}});
-  test_peer_.CheckConfigs({{"a", true}, {"c", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
-  // Ensure that configs get deleted when removed.
-  SetConfigs({{"a", 800, 1}, {"b", 900, 1}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-  SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());
-  // Config change is rejected, still using old configs.
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
-  // Check that updates to primary time get picked up.
-  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
-  test_peer_.SelectNewPrimaryConfig(500);
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-  SetConfigs({{"a", 1200, 1}, {"b", 800, 1}, {"c", 400, 1}});
-  test_peer_.SelectNewPrimaryConfig(500);
-  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
-  // Check that the most recent config is selected.
-  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
-  test_peer_.SelectNewPrimaryConfig(1500);
-  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
-  // Check that the first config is selected.
-  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
-  test_peer_.SelectNewPrimaryConfig(100);
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-}
-
-TEST_F(CryptoServerConfigsTest, SortByPriority) {
-  // Check that priority is used to decide on a primary config when
-  // configs have the same primary time.
-  SetConfigs({{"a", 900, 1}, {"b", 900, 2}, {"c", 900, 3}});
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-  test_peer_.SelectNewPrimaryConfig(800);
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-  test_peer_.SelectNewPrimaryConfig(1000);
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
-
-  // Change priorities and expect sort order to change.
-  SetConfigs({{"a", 900, 2}, {"b", 900, 1}, {"c", 900, 0}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-  test_peer_.SelectNewPrimaryConfig(800);
-  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-  test_peer_.SelectNewPrimaryConfig(1000);
-  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
-  // Check that a new primary config is enabled at the right time.
-  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
-  test_peer_.SelectNewPrimaryConfig(1000);
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
-  test_peer_.SelectNewPrimaryConfig(1101);
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-class ValidateCallback : public ValidateClientHelloResultCallback {
- public:
-  void Run(quiche::QuicheReferenceCountedPointer<Result> /*result*/,
-           std::unique_ptr<ProofSource::Details> /*details*/) override {}
-};
-
-TEST_F(CryptoServerConfigsTest, AdvancePrimaryViaValidate) {
-  // Check that a new primary config is enabled at the right time.
-  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
-  test_peer_.SelectNewPrimaryConfig(1000);
-  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
-  CryptoHandshakeMessage client_hello;
-  QuicSocketAddress client_address;
-  QuicSocketAddress server_address;
-  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-      transport_version = version.transport_version;
-      break;
-    }
-  }
-  ASSERT_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
-  MockClock clock;
-  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config(
-      new QuicSignedServerConfig);
-  std::unique_ptr<ValidateClientHelloResultCallback> done_cb(
-      new ValidateCallback);
-  clock.AdvanceTime(QuicTime::Delta::FromSeconds(1100));
-  config_.ValidateClientHello(client_hello, client_address, server_address,
-                              transport_version, &clock, signed_config,
-                              std::move(done_cb));
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
-}
-
-TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
-  // Ensure that invalid configs don't change anything.
-  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
-  SetConfigs({{"a", 800, 1}, {"c", 1100, 1}, {"INVALID1", 1000, 1}});
-  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/quic_decrypter.cc b/quic/core/crypto/quic_decrypter.cc
deleted file mode 100644
index bd3a0c3..0000000
--- a/quic/core/crypto/quic_decrypter.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_decrypter.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "quic/core/crypto/aes_128_gcm_decrypter.h"
-#include "quic/core/crypto/aes_256_gcm_decrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_decrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/quic_hkdf.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// static
-std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(
-    const ParsedQuicVersion& version,
-    QuicTag algorithm) {
-  switch (algorithm) {
-    case kAESG:
-      if (version.UsesInitialObfuscators()) {
-        return std::make_unique<Aes128GcmDecrypter>();
-      } else {
-        return std::make_unique<Aes128Gcm12Decrypter>();
-      }
-    case kCC20:
-      if (version.UsesInitialObfuscators()) {
-        return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
-      } else {
-        return std::make_unique<ChaCha20Poly1305Decrypter>();
-      }
-    default:
-      QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
-      return nullptr;
-  }
-}
-
-// static
-std::unique_ptr<QuicDecrypter> QuicDecrypter::CreateFromCipherSuite(
-    uint32_t cipher_suite) {
-  switch (cipher_suite) {
-    case TLS1_CK_AES_128_GCM_SHA256:
-      return std::make_unique<Aes128GcmDecrypter>();
-    case TLS1_CK_AES_256_GCM_SHA384:
-      return std::make_unique<Aes256GcmDecrypter>();
-    case TLS1_CK_CHACHA20_POLY1305_SHA256:
-      return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
-    default:
-      QUIC_BUG(quic_bug_10660_1) << "TLS cipher suite is unknown to QUIC";
-      return nullptr;
-  }
-}
-
-// static
-void QuicDecrypter::DiversifyPreliminaryKey(absl::string_view preliminary_key,
-                                            absl::string_view nonce_prefix,
-                                            const DiversificationNonce& nonce,
-                                            size_t key_size,
-                                            size_t nonce_prefix_size,
-                                            std::string* out_key,
-                                            std::string* out_nonce_prefix) {
-  QuicHKDF hkdf((std::string(preliminary_key)) + (std::string(nonce_prefix)),
-                absl::string_view(nonce.data(), nonce.size()),
-                "QUIC key diversification", 0, key_size, 0, nonce_prefix_size,
-                0);
-  *out_key = std::string(hkdf.server_write_key());
-  *out_nonce_prefix = std::string(hkdf.server_write_iv());
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_decrypter.h b/quic/core/crypto/quic_decrypter.h
deleted file mode 100644
index 73f84c9..0000000
--- a/quic/core/crypto/quic_decrypter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypter.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter {
- public:
-  virtual ~QuicDecrypter() {}
-
-  static std::unique_ptr<QuicDecrypter> Create(const ParsedQuicVersion& version,
-                                               QuicTag algorithm);
-
-  // Creates an IETF QuicDecrypter based on |cipher_suite| which must be an id
-  // returned by SSL_CIPHER_get_id. The caller is responsible for taking
-  // ownership of the new QuicDecrypter.
-  static std::unique_ptr<QuicDecrypter> CreateFromCipherSuite(
-      uint32_t cipher_suite);
-
-  // Sets the encryption key. Returns true on success, false on failure.
-  // |DecryptPacket| may not be called until |SetDiversificationNonce| is
-  // called and the preliminary keying material will be combined with that
-  // nonce in order to create the actual key and nonce-prefix.
-  //
-  // If this function is called, neither |SetKey| nor |SetNoncePrefix| may be
-  // called.
-  virtual bool SetPreliminaryKey(absl::string_view key) = 0;
-
-  // SetDiversificationNonce uses |nonce| to derive final keys based on the
-  // input keying material given by calling |SetPreliminaryKey|.
-  //
-  // Calling this function is a no-op if |SetPreliminaryKey| hasn't been
-  // called.
-  virtual bool SetDiversificationNonce(const DiversificationNonce& nonce) = 0;
-
-  // Populates |output| with the decrypted |ciphertext| and populates
-  // |output_length| with the length.  Returns 0 if there is an error.
-  // |output| size is specified by |max_output_length| and must be
-  // at least as large as the ciphertext.  |packet_number| is
-  // appended to the |nonce_prefix| value provided in SetNoncePrefix()
-  // to form the nonce.
-  // TODO(wtc): add a way for DecryptPacket to report decryption failure due
-  // to non-authentic inputs, as opposed to other reasons for failure.
-  virtual bool DecryptPacket(uint64_t packet_number,
-                             absl::string_view associated_data,
-                             absl::string_view ciphertext,
-                             char* output,
-                             size_t* output_length,
-                             size_t max_output_length) = 0;
-
-  // Reads a sample of ciphertext from |sample_reader| and uses the header
-  // protection key to generate a mask to use for header protection. If
-  // successful, this function returns this mask, which is at least 5 bytes
-  // long. Callers can detect failure by checking if the output string is empty.
-  virtual std::string GenerateHeaderProtectionMask(
-      QuicDataReader* sample_reader) = 0;
-
-  // The ID of the cipher. Return 0x03000000 ORed with the 'cryptographic suite
-  // selector'.
-  virtual uint32_t cipher_id() const = 0;
-
-  // Returns the maximum number of packets that can safely fail decryption with
-  // this decrypter.
-  virtual QuicPacketCount GetIntegrityLimit() const = 0;
-
-  // For use by unit tests only.
-  virtual absl::string_view GetKey() const = 0;
-  virtual absl::string_view GetNoncePrefix() const = 0;
-
-  static void DiversifyPreliminaryKey(absl::string_view preliminary_key,
-                                      absl::string_view nonce_prefix,
-                                      const DiversificationNonce& nonce,
-                                      size_t key_size,
-                                      size_t nonce_prefix_size,
-                                      std::string* out_key,
-                                      std::string* out_nonce_prefix);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
diff --git a/quic/core/crypto/quic_encrypter.cc b/quic/core/crypto/quic_encrypter.cc
deleted file mode 100644
index 70a9367..0000000
--- a/quic/core/crypto/quic_encrypter.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_encrypter.h"
-
-#include <utility>
-
-#include "third_party/boringssl/src/include/openssl/tls1.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/aes_128_gcm_encrypter.h"
-#include "quic/core/crypto/aes_256_gcm_encrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_encrypter.h"
-#include "quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// static
-std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(
-    const ParsedQuicVersion& version,
-    QuicTag algorithm) {
-  switch (algorithm) {
-    case kAESG:
-      if (version.UsesInitialObfuscators()) {
-        return std::make_unique<Aes128GcmEncrypter>();
-      } else {
-        return std::make_unique<Aes128Gcm12Encrypter>();
-      }
-    case kCC20:
-      if (version.UsesInitialObfuscators()) {
-        return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
-      } else {
-        return std::make_unique<ChaCha20Poly1305Encrypter>();
-      }
-    default:
-      QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
-      return nullptr;
-  }
-}
-
-// static
-std::unique_ptr<QuicEncrypter> QuicEncrypter::CreateFromCipherSuite(
-    uint32_t cipher_suite) {
-  switch (cipher_suite) {
-    case TLS1_CK_AES_128_GCM_SHA256:
-      return std::make_unique<Aes128GcmEncrypter>();
-    case TLS1_CK_AES_256_GCM_SHA384:
-      return std::make_unique<Aes256GcmEncrypter>();
-    case TLS1_CK_CHACHA20_POLY1305_SHA256:
-      return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
-    default:
-      QUIC_BUG(quic_bug_10711_1) << "TLS cipher suite is unknown to QUIC";
-      return nullptr;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_encrypter.h b/quic/core/crypto/quic_encrypter.h
deleted file mode 100644
index 5465e39..0000000
--- a/quic/core/crypto/quic_encrypter.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypter.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter {
- public:
-  virtual ~QuicEncrypter() {}
-
-  static std::unique_ptr<QuicEncrypter> Create(const ParsedQuicVersion& version,
-                                               QuicTag algorithm);
-
-  // Creates an IETF QuicEncrypter based on |cipher_suite| which must be an id
-  // returned by SSL_CIPHER_get_id. The caller is responsible for taking
-  // ownership of the new QuicEncrypter.
-  static std::unique_ptr<QuicEncrypter> CreateFromCipherSuite(
-      uint32_t cipher_suite);
-
-  // Writes encrypted |plaintext| and a MAC over |plaintext| and
-  // |associated_data| into output. Sets |output_length| to the number of
-  // bytes written. Returns true on success or false if there was an error.
-  // |packet_number| is appended to the |nonce_prefix| value provided in
-  // SetNoncePrefix() to form the nonce. |output| must not overlap with
-  // |associated_data|. If |output| overlaps with |plaintext| then
-  // |plaintext| must be <= |output|.
-  virtual bool EncryptPacket(uint64_t packet_number,
-                             absl::string_view associated_data,
-                             absl::string_view plaintext,
-                             char* output,
-                             size_t* output_length,
-                             size_t max_output_length) = 0;
-
-  // Takes a |sample| of ciphertext and uses the header protection key to
-  // generate a mask to use for header protection, and returns that mask. On
-  // success, the mask will be at least 5 bytes long; on failure the string will
-  // be empty.
-  virtual std::string GenerateHeaderProtectionMask(
-      absl::string_view sample) = 0;
-
-  // Returns the maximum length of plaintext that can be encrypted
-  // to ciphertext no larger than |ciphertext_size|.
-  virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const = 0;
-
-  // Returns the length of the ciphertext that would be generated by encrypting
-  // to plaintext of size |plaintext_size|.
-  virtual size_t GetCiphertextSize(size_t plaintext_size) const = 0;
-
-  // Returns the maximum number of packets that can be safely encrypted with
-  // this encrypter.
-  virtual QuicPacketCount GetConfidentialityLimit() const = 0;
-
-  // For use by unit tests only.
-  virtual absl::string_view GetKey() const = 0;
-  virtual absl::string_view GetNoncePrefix() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
diff --git a/quic/core/crypto/quic_hkdf.cc b/quic/core/crypto/quic_hkdf.cc
deleted file mode 100644
index 8dcf104..0000000
--- a/quic/core/crypto/quic_hkdf.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_hkdf.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/hkdf.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-const size_t kSHA256HashLength = 32;
-const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256;
-
-QuicHKDF::QuicHKDF(absl::string_view secret,
-                   absl::string_view salt,
-                   absl::string_view info,
-                   size_t key_bytes_to_generate,
-                   size_t iv_bytes_to_generate,
-                   size_t subkey_secret_bytes_to_generate)
-    : QuicHKDF(secret,
-               salt,
-               info,
-               key_bytes_to_generate,
-               key_bytes_to_generate,
-               iv_bytes_to_generate,
-               iv_bytes_to_generate,
-               subkey_secret_bytes_to_generate) {}
-
-QuicHKDF::QuicHKDF(absl::string_view secret,
-                   absl::string_view salt,
-                   absl::string_view info,
-                   size_t client_key_bytes_to_generate,
-                   size_t server_key_bytes_to_generate,
-                   size_t client_iv_bytes_to_generate,
-                   size_t server_iv_bytes_to_generate,
-                   size_t subkey_secret_bytes_to_generate) {
-  const size_t material_length =
-      2 * client_key_bytes_to_generate + client_iv_bytes_to_generate +
-      2 * server_key_bytes_to_generate + server_iv_bytes_to_generate +
-      subkey_secret_bytes_to_generate;
-  QUICHE_DCHECK_LT(material_length, kMaxKeyMaterialSize);
-
-  output_.resize(material_length);
-  // On Windows, when the size of output_ is zero, dereference of 0'th element
-  // results in a crash. C++11 solves this problem by adding a data() getter
-  // method to std::vector.
-  if (output_.empty()) {
-    return;
-  }
-
-  ::HKDF(&output_[0], output_.size(), ::EVP_sha256(),
-         reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
-         reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
-         reinterpret_cast<const uint8_t*>(info.data()), info.size());
-
-  size_t j = 0;
-  if (client_key_bytes_to_generate) {
-    client_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                          client_key_bytes_to_generate);
-    j += client_key_bytes_to_generate;
-  }
-
-  if (server_key_bytes_to_generate) {
-    server_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                          server_key_bytes_to_generate);
-    j += server_key_bytes_to_generate;
-  }
-
-  if (client_iv_bytes_to_generate) {
-    client_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                         client_iv_bytes_to_generate);
-    j += client_iv_bytes_to_generate;
-  }
-
-  if (server_iv_bytes_to_generate) {
-    server_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                         server_iv_bytes_to_generate);
-    j += server_iv_bytes_to_generate;
-  }
-
-  if (subkey_secret_bytes_to_generate) {
-    subkey_secret_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                       subkey_secret_bytes_to_generate);
-    j += subkey_secret_bytes_to_generate;
-  }
-  // Repeat client and server key bytes for header protection keys.
-  if (client_key_bytes_to_generate) {
-    client_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                       client_key_bytes_to_generate);
-    j += client_key_bytes_to_generate;
-  }
-
-  if (server_key_bytes_to_generate) {
-    server_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
-                                       server_key_bytes_to_generate);
-    j += server_key_bytes_to_generate;
-  }
-}
-
-QuicHKDF::~QuicHKDF() {}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_hkdf.h b/quic/core/crypto/quic_hkdf.h
deleted file mode 100644
index 9a14bc4..0000000
--- a/quic/core/crypto/quic_hkdf.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicHKDF implements the key derivation function specified in RFC 5869
-// (using SHA-256) and outputs key material, as needed by QUIC.
-// See https://tools.ietf.org/html/rfc5869 for details.
-class QUIC_EXPORT_PRIVATE QuicHKDF {
- public:
-  // |secret|: the input shared secret (or, from RFC 5869, the IKM).
-  // |salt|: an (optional) public salt / non-secret random value. While
-  // optional, callers are strongly recommended to provide a salt. There is no
-  // added security value in making this larger than the SHA-256 block size of
-  // 64 bytes.
-  // |info|: an (optional) label to distinguish different uses of HKDF. It is
-  // optional context and application specific information (can be a zero-length
-  // string).
-  // |key_bytes_to_generate|: the number of bytes of key material to generate
-  // for both client and server.
-  // |iv_bytes_to_generate|: the number of bytes of IV to generate for both
-  // client and server.
-  // |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to
-  // generate, shared between client and server.
-  QuicHKDF(absl::string_view secret,
-           absl::string_view salt,
-           absl::string_view info,
-           size_t key_bytes_to_generate,
-           size_t iv_bytes_to_generate,
-           size_t subkey_secret_bytes_to_generate);
-
-  // An alternative constructor that allows the client and server key/IV
-  // lengths to be different.
-  QuicHKDF(absl::string_view secret,
-           absl::string_view salt,
-           absl::string_view info,
-           size_t client_key_bytes_to_generate,
-           size_t server_key_bytes_to_generate,
-           size_t client_iv_bytes_to_generate,
-           size_t server_iv_bytes_to_generate,
-           size_t subkey_secret_bytes_to_generate);
-
-  ~QuicHKDF();
-
-  absl::string_view client_write_key() const { return client_write_key_; }
-  absl::string_view client_write_iv() const { return client_write_iv_; }
-  absl::string_view server_write_key() const { return server_write_key_; }
-  absl::string_view server_write_iv() const { return server_write_iv_; }
-  absl::string_view subkey_secret() const { return subkey_secret_; }
-  absl::string_view client_hp_key() const { return client_hp_key_; }
-  absl::string_view server_hp_key() const { return server_hp_key_; }
-
- private:
-  std::vector<uint8_t> output_;
-
-  absl::string_view client_write_key_;
-  absl::string_view server_write_key_;
-  absl::string_view client_write_iv_;
-  absl::string_view server_write_iv_;
-  absl::string_view subkey_secret_;
-  absl::string_view client_hp_key_;
-  absl::string_view server_hp_key_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
diff --git a/quic/core/crypto/quic_hkdf_test.cc b/quic/core/crypto/quic_hkdf_test.cc
deleted file mode 100644
index e23d3f2..0000000
--- a/quic/core/crypto/quic_hkdf_test.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_hkdf.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct HKDFInput {
-  const char* key_hex;
-  const char* salt_hex;
-  const char* info_hex;
-  const char* output_hex;
-};
-
-// These test cases are taken from
-// https://tools.ietf.org/html/rfc5869#appendix-A.
-static const HKDFInput kHKDFInputs[] = {
-    {
-        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
-        "000102030405060708090a0b0c",
-        "f0f1f2f3f4f5f6f7f8f9",
-        "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf340072"
-        "08d5"
-        "b887185865",
-    },
-    {
-        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122"
-        "2324"
-        "25262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647"
-        "4849"
-        "4a4b4c4d4e4f",
-        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182"
-        "8384"
-        "85868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7"
-        "a8a9"
-        "aaabacadaeaf",
-        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2"
-        "d3d4"
-        "d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7"
-        "f8f9"
-        "fafbfcfdfeff",
-        "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a"
-        "99ca"
-        "c7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87"
-        "c14c"
-        "01d5c1f3434f1d87",
-    },
-    {
-        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
-        "",
-        "",
-        "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d2013"
-        "95fa"
-        "a4b61a96c8",
-    },
-};
-
-class QuicHKDFTest : public QuicTest {};
-
-TEST_F(QuicHKDFTest, HKDF) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kHKDFInputs); i++) {
-    const HKDFInput& test(kHKDFInputs[i]);
-    SCOPED_TRACE(i);
-
-    const std::string key = absl::HexStringToBytes(test.key_hex);
-    const std::string salt = absl::HexStringToBytes(test.salt_hex);
-    const std::string info = absl::HexStringToBytes(test.info_hex);
-    const std::string expected = absl::HexStringToBytes(test.output_hex);
-
-    // We set the key_length to the length of the expected output and then take
-    // the result from the first key, which is the client write key.
-    QuicHKDF hkdf(key, salt, info, expected.size(), 0, 0);
-
-    ASSERT_EQ(expected.size(), hkdf.client_write_key().size());
-    EXPECT_EQ(0, memcmp(expected.data(), hkdf.client_write_key().data(),
-                        expected.size()));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/quic_random.cc b/quic/core/crypto/quic_random.cc
deleted file mode 100644
index d3190c6..0000000
--- a/quic/core/crypto/quic_random.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_random.h"
-#include <cstdint>
-#include <cstring>
-
-#include "third_party/boringssl/src/include/openssl/rand.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Insecure randomness in DefaultRandom uses an implementation of
-// xoshiro256++ 1.0 based on code in the public domain from
-// <http://prng.di.unimi.it/xoshiro256plusplus.c>.
-
-inline uint64_t Xoshiro256InitializeRngStateMember() {
-  uint64_t result;
-  RAND_bytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
-  return result;
-}
-
-inline uint64_t Xoshiro256PlusPlusRotLeft(uint64_t x, int k) {
-  return (x << k) | (x >> (64 - k));
-}
-
-uint64_t Xoshiro256PlusPlus() {
-  static thread_local uint64_t rng_state[4] = {
-      Xoshiro256InitializeRngStateMember(),
-      Xoshiro256InitializeRngStateMember(),
-      Xoshiro256InitializeRngStateMember(),
-      Xoshiro256InitializeRngStateMember()};
-  const uint64_t result =
-      Xoshiro256PlusPlusRotLeft(rng_state[0] + rng_state[3], 23) + rng_state[0];
-  const uint64_t t = rng_state[1] << 17;
-  rng_state[2] ^= rng_state[0];
-  rng_state[3] ^= rng_state[1];
-  rng_state[1] ^= rng_state[2];
-  rng_state[0] ^= rng_state[3];
-  rng_state[2] ^= t;
-  rng_state[3] = Xoshiro256PlusPlusRotLeft(rng_state[3], 45);
-  return result;
-}
-
-class DefaultRandom : public QuicRandom {
- public:
-  DefaultRandom() {}
-  DefaultRandom(const DefaultRandom&) = delete;
-  DefaultRandom& operator=(const DefaultRandom&) = delete;
-  ~DefaultRandom() override {}
-
-  // QuicRandom implementation
-  void RandBytes(void* data, size_t len) override;
-  uint64_t RandUint64() override;
-  void InsecureRandBytes(void* data, size_t len) override;
-  uint64_t InsecureRandUint64() override;
-};
-
-void DefaultRandom::RandBytes(void* data, size_t len) {
-  RAND_bytes(reinterpret_cast<uint8_t*>(data), len);
-}
-
-uint64_t DefaultRandom::RandUint64() {
-  uint64_t value;
-  RandBytes(&value, sizeof(value));
-  return value;
-}
-
-void DefaultRandom::InsecureRandBytes(void* data, size_t len) {
-  while (len >= sizeof(uint64_t)) {
-    uint64_t random_bytes64 = Xoshiro256PlusPlus();
-    memcpy(data, &random_bytes64, sizeof(uint64_t));
-    data = reinterpret_cast<char*>(data) + sizeof(uint64_t);
-    len -= sizeof(uint64_t);
-  }
-  if (len > 0) {
-    QUICHE_DCHECK_LT(len, sizeof(uint64_t));
-    uint64_t random_bytes64 = Xoshiro256PlusPlus();
-    memcpy(data, &random_bytes64, len);
-  }
-}
-
-uint64_t DefaultRandom::InsecureRandUint64() {
-  return Xoshiro256PlusPlus();
-}
-
-}  // namespace
-
-// static
-QuicRandom* QuicRandom::GetInstance() {
-  static DefaultRandom* random = new DefaultRandom();
-  return random;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/quic_random.h b/quic/core/crypto/quic_random.h
deleted file mode 100644
index 4d7bf94..0000000
--- a/quic/core/crypto/quic_random.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
-#define QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The interface for a random number generator.
-class QUIC_EXPORT_PRIVATE QuicRandom {
- public:
-  virtual ~QuicRandom() {}
-
-  // Returns the default random number generator, which is cryptographically
-  // secure and thread-safe.
-  static QuicRandom* GetInstance();
-
-  // Generates |len| random bytes in the |data| buffer.
-  virtual void RandBytes(void* data, size_t len) = 0;
-
-  // Returns a random number in the range [0, kuint64max].
-  virtual uint64_t RandUint64() = 0;
-
-  // Generates |len| random bytes in the |data| buffer. This MUST NOT be used
-  // for any application that requires cryptographically-secure randomness.
-  virtual void InsecureRandBytes(void* data, size_t len) = 0;
-
-  // Returns a random number in the range [0, kuint64max]. This MUST NOT be used
-  // for any application that requires cryptographically-secure randomness.
-  virtual uint64_t InsecureRandUint64() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
diff --git a/quic/core/crypto/quic_random_test.cc b/quic/core/crypto/quic_random_test.cc
deleted file mode 100644
index ab27918..0000000
--- a/quic/core/crypto/quic_random_test.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/quic_random.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicRandomTest : public QuicTest {};
-
-TEST_F(QuicRandomTest, RandBytes) {
-  unsigned char buf1[16];
-  unsigned char buf2[16];
-  memset(buf1, 0xaf, sizeof(buf1));
-  memset(buf2, 0xaf, sizeof(buf2));
-  ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
-
-  QuicRandom* rng = QuicRandom::GetInstance();
-  rng->RandBytes(buf1, sizeof(buf1));
-  EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
-}
-
-TEST_F(QuicRandomTest, RandUint64) {
-  QuicRandom* rng = QuicRandom::GetInstance();
-  uint64_t value1 = rng->RandUint64();
-  uint64_t value2 = rng->RandUint64();
-  EXPECT_NE(value1, value2);
-}
-
-TEST_F(QuicRandomTest, InsecureRandBytes) {
-  unsigned char buf1[16];
-  unsigned char buf2[16];
-  memset(buf1, 0xaf, sizeof(buf1));
-  memset(buf2, 0xaf, sizeof(buf2));
-  ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
-
-  QuicRandom* rng = QuicRandom::GetInstance();
-  rng->InsecureRandBytes(buf1, sizeof(buf1));
-  EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
-}
-
-TEST_F(QuicRandomTest, InsecureRandUint64) {
-  QuicRandom* rng = QuicRandom::GetInstance();
-  uint64_t value1 = rng->InsecureRandUint64();
-  uint64_t value2 = rng->InsecureRandUint64();
-  EXPECT_NE(value1, value2);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/tls_client_connection.cc b/quic/core/crypto/tls_client_connection.cc
deleted file mode 100644
index 8e31bba..0000000
--- a/quic/core/crypto/tls_client_connection.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/tls_client_connection.h"
-
-namespace quic {
-
-TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx,
-                                         Delegate* delegate,
-                                         QuicSSLConfig ssl_config)
-    : TlsConnection(ssl_ctx,
-                    delegate->ConnectionDelegate(),
-                    std::move(ssl_config)),
-      delegate_(delegate) {}
-
-// static
-bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx(
-    bool enable_early_data) {
-  bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
-  // Configure certificate verification.
-  SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback);
-  int reverify_on_resume_enabled = 1;
-  SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled);
-
-  // Configure session caching.
-  SSL_CTX_set_session_cache_mode(
-      ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
-  SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
-
-  // TODO(wub): Always enable early data on the SSL_CTX, but allow it to be
-  // overridden on the SSL object, via QuicSSLConfig.
-  SSL_CTX_set_early_data_enabled(ssl_ctx.get(), enable_early_data);
-  return ssl_ctx;
-}
-
-void TlsClientConnection::SetCertChain(
-    const std::vector<CRYPTO_BUFFER*>& cert_chain, EVP_PKEY* privkey) {
-  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), privkey,
-                        /*privkey_method=*/nullptr);
-}
-
-// static
-int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
-  static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl))
-      ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session));
-  return 1;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/tls_client_connection.h b/quic/core/crypto/tls_client_connection.h
deleted file mode 100644
index 574441e..0000000
--- a/quic/core/crypto/tls_client_connection.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
-
-#include "quic/core/crypto/tls_connection.h"
-
-namespace quic {
-
-// TlsClientConnection receives calls for client-specific BoringSSL callbacks
-// and calls its Delegate for the implementation of those callbacks.
-class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection {
- public:
-  // A TlsClientConnection::Delegate implements the client-specific methods that
-  // are set as callbacks for an SSL object.
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-   protected:
-    // Called when a NewSessionTicket is received from the server.
-    virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0;
-
-    // Provides the delegate for callbacks that are shared between client and
-    // server.
-    virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
-
-    friend class TlsClientConnection;
-  };
-
-  TlsClientConnection(SSL_CTX* ssl_ctx,
-                      Delegate* delegate,
-                      QuicSSLConfig ssl_config);
-
-  // Creates and configures an SSL_CTX that is appropriate for clients to use.
-  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data);
-
-  // Set the client cert and private key to be used on this connection, if
-  // requested by the server.
-  void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain,
-                    EVP_PKEY* privkey);
-
- private:
-  // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls
-  // Delegate::InsertSession.
-  static int NewSessionCallback(SSL* ssl, SSL_SESSION* session);
-
-  Delegate* delegate_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
diff --git a/quic/core/crypto/tls_connection.cc b/quic/core/crypto/tls_connection.cc
deleted file mode 100644
index e534f7d..0000000
--- a/quic/core/crypto/tls_connection.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/tls_connection.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-
-// BoringSSL allows storing extra data off of some of its data structures,
-// including the SSL struct. To allow for multiple callers to store data, each
-// caller can use a different index for setting and getting data. These indices
-// are globals handed out by calling SSL_get_ex_new_index.
-//
-// SslIndexSingleton calls SSL_get_ex_new_index on its construction, and then
-// provides this index to be used in calls to SSL_get_ex_data/SSL_set_ex_data.
-// This is used to store in the SSL struct a pointer to the TlsConnection which
-// owns it.
-class SslIndexSingleton {
- public:
-  static SslIndexSingleton* GetInstance() {
-    static SslIndexSingleton* instance = new SslIndexSingleton();
-    return instance;
-  }
-
-  int ssl_ex_data_index_connection() const {
-    return ssl_ex_data_index_connection_;
-  }
-
- private:
-  SslIndexSingleton() {
-    CRYPTO_library_init();
-    ssl_ex_data_index_connection_ =
-        SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
-    QUICHE_CHECK_LE(0, ssl_ex_data_index_connection_);
-  }
-
-  SslIndexSingleton(const SslIndexSingleton&) = delete;
-  SslIndexSingleton& operator=(const SslIndexSingleton&) = delete;
-
-  // The index to supply to SSL_get_ex_data/SSL_set_ex_data for getting/setting
-  // the TlsConnection pointer.
-  int ssl_ex_data_index_connection_;
-};
-
-}  // namespace
-
-// static
-EncryptionLevel TlsConnection::QuicEncryptionLevel(
-    enum ssl_encryption_level_t level) {
-  switch (level) {
-    case ssl_encryption_initial:
-      return ENCRYPTION_INITIAL;
-    case ssl_encryption_early_data:
-      return ENCRYPTION_ZERO_RTT;
-    case ssl_encryption_handshake:
-      return ENCRYPTION_HANDSHAKE;
-    case ssl_encryption_application:
-      return ENCRYPTION_FORWARD_SECURE;
-    default:
-      QUIC_BUG(quic_bug_10698_1)
-          << "Invalid ssl_encryption_level_t " << static_cast<int>(level);
-      return ENCRYPTION_INITIAL;
-  }
-}
-
-// static
-enum ssl_encryption_level_t TlsConnection::BoringEncryptionLevel(
-    EncryptionLevel level) {
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-      return ssl_encryption_initial;
-    case ENCRYPTION_HANDSHAKE:
-      return ssl_encryption_handshake;
-    case ENCRYPTION_ZERO_RTT:
-      return ssl_encryption_early_data;
-    case ENCRYPTION_FORWARD_SECURE:
-      return ssl_encryption_application;
-    default:
-      QUIC_BUG(quic_bug_10698_2)
-          << "Invalid encryption level " << static_cast<int>(level);
-      return ssl_encryption_initial;
-  }
-}
-
-TlsConnection::TlsConnection(SSL_CTX* ssl_ctx,
-                             TlsConnection::Delegate* delegate,
-                             QuicSSLConfig ssl_config)
-    : delegate_(delegate),
-      ssl_(SSL_new(ssl_ctx)),
-      ssl_config_(std::move(ssl_config)) {
-  SSL_set_ex_data(
-      ssl(), SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection(),
-      this);
-  if (ssl_config_.early_data_enabled.has_value()) {
-    const int early_data_enabled = *ssl_config_.early_data_enabled ? 1 : 0;
-    SSL_set_early_data_enabled(ssl(), early_data_enabled);
-  }
-  if (ssl_config_.signing_algorithm_prefs.has_value()) {
-    SSL_set_signing_algorithm_prefs(
-        ssl(), ssl_config_.signing_algorithm_prefs->data(),
-        ssl_config_.signing_algorithm_prefs->size());
-  }
-  if (ssl_config_.disable_ticket_support.has_value()) {
-    if (*ssl_config_.disable_ticket_support) {
-      SSL_set_options(ssl(), SSL_OP_NO_TICKET);
-    }
-  }
-}
-
-void TlsConnection::EnableInfoCallback() {
-  SSL_set_info_callback(
-      ssl(), +[](const SSL* ssl, int type, int value) {
-        ConnectionFromSsl(ssl)->delegate_->InfoCallback(type, value);
-      });
-}
-
-void TlsConnection::DisableTicketSupport() {
-  ssl_config_.disable_ticket_support = true;
-  SSL_set_options(ssl(), SSL_OP_NO_TICKET);
-}
-
-// static
-bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() {
-  CRYPTO_library_init();
-  bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
-  SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
-  SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
-  SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod);
-  return ssl_ctx;
-}
-
-// static
-TlsConnection* TlsConnection::ConnectionFromSsl(const SSL* ssl) {
-  return reinterpret_cast<TlsConnection*>(SSL_get_ex_data(
-      ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection()));
-}
-
-// static
-enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl,
-                                                       uint8_t* out_alert) {
-  return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert);
-}
-
-const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{
-    TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback,
-    TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback,
-    TlsConnection::SendAlertCallback};
-
-// static
-int TlsConnection::SetReadSecretCallback(SSL* ssl,
-                                         enum ssl_encryption_level_t level,
-                                         const SSL_CIPHER* cipher,
-                                         const uint8_t* secret,
-                                         size_t secret_length) {
-  // TODO(nharper): replace this vector with a span (which unfortunately doesn't
-  // yet exist in quic/platform/api).
-  std::vector<uint8_t> secret_vec(secret, secret + secret_length);
-  TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
-  if (!delegate->SetReadSecret(QuicEncryptionLevel(level), cipher,
-                               secret_vec)) {
-    return 0;
-  }
-  return 1;
-}
-
-// static
-int TlsConnection::SetWriteSecretCallback(SSL* ssl,
-                                          enum ssl_encryption_level_t level,
-                                          const SSL_CIPHER* cipher,
-                                          const uint8_t* secret,
-                                          size_t secret_length) {
-  // TODO(nharper): replace this vector with a span (which unfortunately doesn't
-  // yet exist in quic/platform/api).
-  std::vector<uint8_t> secret_vec(secret, secret + secret_length);
-  TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
-  delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher, secret_vec);
-  return 1;
-}
-
-// static
-int TlsConnection::WriteMessageCallback(SSL* ssl,
-                                        enum ssl_encryption_level_t level,
-                                        const uint8_t* data,
-                                        size_t len) {
-  ConnectionFromSsl(ssl)->delegate_->WriteMessage(
-      QuicEncryptionLevel(level),
-      absl::string_view(reinterpret_cast<const char*>(data), len));
-  return 1;
-}
-
-// static
-int TlsConnection::FlushFlightCallback(SSL* ssl) {
-  ConnectionFromSsl(ssl)->delegate_->FlushFlight();
-  return 1;
-}
-
-// static
-int TlsConnection::SendAlertCallback(SSL* ssl,
-                                     enum ssl_encryption_level_t level,
-                                     uint8_t desc) {
-  ConnectionFromSsl(ssl)->delegate_->SendAlert(QuicEncryptionLevel(level),
-                                               desc);
-  return 1;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/tls_connection.h b/quic/core/crypto/tls_connection.h
deleted file mode 100644
index 5e80185..0000000
--- a/quic/core/crypto/tls_connection.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// TlsConnection wraps BoringSSL's SSL object which represents a single TLS
-// connection. Callbacks set in BoringSSL which are called with an SSL* argument
-// will get dispatched to the TlsConnection object owning that SSL. In turn, the
-// TlsConnection will delegate the implementation of that callback to its
-// Delegate.
-//
-// The owner of the TlsConnection is responsible for driving the TLS handshake
-// (and other interactions with the SSL*). This class only handles mapping
-// callbacks to the correct instance.
-class QUIC_EXPORT_PRIVATE TlsConnection {
- public:
-  // A TlsConnection::Delegate implements the methods that are set as callbacks
-  // of TlsConnection.
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-   protected:
-    // Certificate management functions:
-
-    // Verifies the peer's certificate chain. It may use
-    // SSL_get0_peer_certificates to get the cert chain. This method returns
-    // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid,
-    // or ssl_verify_retry if verification is happening asynchronously.
-    virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0;
-
-    // QUIC-TLS interface functions:
-
-    // SetWriteSecret provides the encryption secret used to encrypt messages at
-    // encryption level |level|. The secret provided here is the one from the
-    // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
-    // traffic secrets and application traffic secrets. The provided write
-    // secret must be used with the provided cipher suite |cipher|.
-    virtual void SetWriteSecret(EncryptionLevel level,
-                                const SSL_CIPHER* cipher,
-                                const std::vector<uint8_t>& write_secret) = 0;
-
-    // SetReadSecret is similar to SetWriteSecret, except that it is used for
-    // decrypting messages. SetReadSecret at a particular level is always called
-    // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT,
-    // where the EncryptionLevel for SetWriteSecret is
-    // ENCRYPTION_FORWARD_SECURE.
-    virtual bool SetReadSecret(EncryptionLevel level,
-                               const SSL_CIPHER* cipher,
-                               const std::vector<uint8_t>& read_secret) = 0;
-
-    // WriteMessage is called when there is |data| from the TLS stack ready for
-    // the QUIC stack to write in a crypto frame. The data must be transmitted
-    // at encryption level |level|.
-    virtual void WriteMessage(EncryptionLevel level,
-                              absl::string_view data) = 0;
-
-    // FlushFlight is called to signal that the current flight of messages have
-    // all been written (via calls to WriteMessage) and can be flushed to the
-    // underlying transport.
-    virtual void FlushFlight() = 0;
-
-    // SendAlert causes this TlsConnection to close the QUIC connection with an
-    // error code corersponding to the TLS alert description |desc| sent at
-    // level |level|.
-    virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
-
-    // Informational callback from BoringSSL. This callback is disabled by
-    // default, but can be enabled by TlsConnection::EnableInfoCallback.
-    //
-    // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
-    virtual void InfoCallback(int type, int value) = 0;
-
-    friend class TlsConnection;
-  };
-
-  TlsConnection(const TlsConnection&) = delete;
-  TlsConnection& operator=(const TlsConnection&) = delete;
-
-  // Configure the SSL such that delegate_->InfoCallback will be called.
-  void EnableInfoCallback();
-
-  // Configure the SSL to disable session ticket support. Note that, this
-  // function simply sets the |SSL_OP_NO_TICKET| option on the SSL object, it
-  // does not check whether it is too late to do so.
-  void DisableTicketSupport();
-
-  // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
-  // QUIC's EncryptionLevel.
-  static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
-  static enum ssl_encryption_level_t BoringEncryptionLevel(
-      EncryptionLevel level);
-
-  SSL* ssl() const { return ssl_.get(); }
-
-  const QuicSSLConfig& ssl_config() const { return ssl_config_; }
-
- protected:
-  // TlsConnection does not take ownership of |ssl_ctx| or |delegate|; they must
-  // outlive the TlsConnection object.
-  TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate, QuicSSLConfig ssl_config);
-
-  // Creates an SSL_CTX and configures it with the options that are appropriate
-  // for both client and server. The caller is responsible for ownership of the
-  // newly created struct.
-  static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
-
-  // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
-  // belongs to. This helper method allows the callbacks set in BoringSSL to be
-  // dispatched to the correct TlsConnection from the SSL* passed into the
-  // callback.
-  static TlsConnection* ConnectionFromSsl(const SSL* ssl);
-
-  // Registered as the callback for SSL(_CTX)_set_custom_verify. The
-  // implementation is delegated to Delegate::VerifyCert.
-  static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
-
-  QuicSSLConfig& mutable_ssl_config() { return ssl_config_; }
-
- private:
-  // TlsConnection implements SSL_QUIC_METHOD, which provides the interface
-  // between BoringSSL's TLS stack and a QUIC implementation.
-  static const SSL_QUIC_METHOD kSslQuicMethod;
-
-  // The following static functions make up the members of kSslQuicMethod:
-  static int SetReadSecretCallback(SSL* ssl,
-                                   enum ssl_encryption_level_t level,
-                                   const SSL_CIPHER* cipher,
-                                   const uint8_t* secret,
-                                   size_t secret_len);
-  static int SetWriteSecretCallback(SSL* ssl,
-                                    enum ssl_encryption_level_t level,
-                                    const SSL_CIPHER* cipher,
-                                    const uint8_t* secret,
-                                    size_t secret_len);
-  static int WriteMessageCallback(SSL* ssl,
-                                  enum ssl_encryption_level_t level,
-                                  const uint8_t* data,
-                                  size_t len);
-  static int FlushFlightCallback(SSL* ssl);
-  static int SendAlertCallback(SSL* ssl,
-                               enum ssl_encryption_level_t level,
-                               uint8_t desc);
-
-  Delegate* delegate_;
-  bssl::UniquePtr<SSL> ssl_;
-  QuicSSLConfig ssl_config_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
diff --git a/quic/core/crypto/tls_server_connection.cc b/quic/core/crypto/tls_server_connection.cc
deleted file mode 100644
index 007bdbb..0000000
--- a/quic/core/crypto/tls_server_connection.cc
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/tls_server_connection.h"
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate,
-                                         QuicSSLConfig ssl_config)
-    : TlsConnection(ssl_ctx, delegate->ConnectionDelegate(),
-                    std::move(ssl_config)),
-      delegate_(delegate) {
-  // By default, cert verify callback is not installed on ssl(), so only need to
-  // UpdateCertVerifyCallback() if client_cert_mode is not kNone.
-  if (TlsConnection::ssl_config().client_cert_mode != ClientCertMode::kNone) {
-    UpdateCertVerifyCallback();
-  }
-}
-
-// static
-bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
-    ProofSource* proof_source) {
-  bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
-
-  // Server does not request/verify client certs by default. Individual server
-  // connections may call SSL_set_custom_verify on their SSL object to request
-  // client certs.
-
-  SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
-                                         &TlsExtServernameCallback);
-  SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
-  // We don't actually need the TicketCrypter here, but we need to know
-  // whether it's set.
-  if (proof_source->GetTicketCrypter()) {
-    QUIC_CODE_COUNT(quic_session_tickets_enabled);
-    SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
-                                   &TlsServerConnection::kSessionTicketMethod);
-  } else {
-    QUIC_CODE_COUNT(quic_session_tickets_disabled);
-  }
-
-  SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
-
-  SSL_CTX_set_select_certificate_cb(
-      ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
-  SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
-  return ssl_ctx;
-}
-
-void TlsServerConnection::SetCertChain(
-    const std::vector<CRYPTO_BUFFER*>& cert_chain) {
-  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
-                        &TlsServerConnection::kPrivateKeyMethod);
-}
-
-void TlsServerConnection::SetClientCertMode(ClientCertMode client_cert_mode) {
-  if (ssl_config().client_cert_mode == client_cert_mode) {
-    return;
-  }
-
-  mutable_ssl_config().client_cert_mode = client_cert_mode;
-  UpdateCertVerifyCallback();
-}
-
-void TlsServerConnection::UpdateCertVerifyCallback() {
-  const ClientCertMode client_cert_mode = ssl_config().client_cert_mode;
-  if (client_cert_mode == ClientCertMode::kNone) {
-    SSL_set_custom_verify(ssl(), SSL_VERIFY_NONE, nullptr);
-    return;
-  }
-
-  int mode = SSL_VERIFY_PEER;
-  if (client_cert_mode == ClientCertMode::kRequire) {
-    mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-  } else {
-    QUICHE_DCHECK_EQ(client_cert_mode, ClientCertMode::kRequest);
-  }
-  SSL_set_custom_verify(ssl(), mode, &VerifyCallback);
-}
-
-const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
-    &TlsServerConnection::PrivateKeySign,
-    nullptr,  // decrypt
-    &TlsServerConnection::PrivateKeyComplete,
-};
-
-// static
-TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
-  return static_cast<TlsServerConnection*>(
-      TlsConnection::ConnectionFromSsl(ssl));
-}
-
-// static
-ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
-    const SSL_CLIENT_HELLO* client_hello) {
-  return ConnectionFromSsl(client_hello->ssl)
-      ->delegate_->EarlySelectCertCallback(client_hello);
-}
-
-// static
-int TlsServerConnection::TlsExtServernameCallback(SSL* ssl,
-                                                  int* out_alert,
-                                                  void* /*arg*/) {
-  return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
-}
-
-// static
-int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
-                                            const uint8_t** out,
-                                            uint8_t* out_len,
-                                            const uint8_t* in,
-                                            unsigned in_len,
-                                            void* /*arg*/) {
-  return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
-                                                       in_len);
-}
-
-// static
-ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
-                                                             uint8_t* out,
-                                                             size_t* out_len,
-                                                             size_t max_out,
-                                                             uint16_t sig_alg,
-                                                             const uint8_t* in,
-                                                             size_t in_len) {
-  return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
-      out, out_len, max_out, sig_alg,
-      absl::string_view(reinterpret_cast<const char*>(in), in_len));
-}
-
-// static
-ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
-    SSL* ssl,
-    uint8_t* out,
-    size_t* out_len,
-    size_t max_out) {
-  return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
-                                                               max_out);
-}
-
-// static
-const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
-    TlsServerConnection::SessionTicketMaxOverhead,
-    TlsServerConnection::SessionTicketSeal,
-    TlsServerConnection::SessionTicketOpen,
-};
-
-// static
-size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
-  return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
-}
-
-// static
-int TlsServerConnection::SessionTicketSeal(SSL* ssl,
-                                           uint8_t* out,
-                                           size_t* out_len,
-                                           size_t max_out_len,
-                                           const uint8_t* in,
-                                           size_t in_len) {
-  return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
-      out, out_len, max_out_len,
-      absl::string_view(reinterpret_cast<const char*>(in), in_len));
-}
-
-// static
-enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
-    SSL* ssl,
-    uint8_t* out,
-    size_t* out_len,
-    size_t max_out_len,
-    const uint8_t* in,
-    size_t in_len) {
-  return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
-      out, out_len, max_out_len,
-      absl::string_view(reinterpret_cast<const char*>(in), in_len));
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/tls_server_connection.h b/quic/core/crypto/tls_server_connection.h
deleted file mode 100644
index 976620d..0000000
--- a/quic/core/crypto/tls_server_connection.h
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/tls_connection.h"
-
-namespace quic {
-
-// TlsServerConnection receives calls for client-specific BoringSSL callbacks
-// and calls its Delegate for the implementation of those callbacks.
-class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection {
- public:
-  // A TlsServerConnection::Delegate implement the server-specific methods that
-  // are set as callbacks for an SSL object.
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-   protected:
-    // Called from BoringSSL right after SNI is extracted, which is very early
-    // in the handshake process.
-    virtual ssl_select_cert_result_t EarlySelectCertCallback(
-        const SSL_CLIENT_HELLO* client_hello) = 0;
-
-    // Called after the ClientHello extensions have been successfully parsed.
-    // Returns an SSL_TLSEXT_ERR_* value (see
-    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_tlsext_servername_callback).
-    //
-    // On success, return SSL_TLSEXT_ERR_OK causes the server_name extension to
-    // be acknowledged in the ServerHello, or return SSL_TLSEXT_ERR_NOACK which
-    // causes it to be not acknowledged.
-    //
-    // If the function returns SSL_TLSEXT_ERR_ALERT_FATAL, then it puts in
-    // |*out_alert| the TLS alert value that the server will send.
-    //
-    virtual int TlsExtServernameCallback(int* out_alert) = 0;
-
-    // Selects which ALPN to use based on the list sent by the client.
-    virtual int SelectAlpn(const uint8_t** out,
-                           uint8_t* out_len,
-                           const uint8_t* in,
-                           unsigned in_len) = 0;
-
-    // Signs |in| using the signature algorithm specified by |sig_alg| (an
-    // SSL_SIGN_* value). If the signing operation cannot be completed
-    // synchronously, ssl_private_key_retry is returned. If there is an error
-    // signing, or if the signature is longer than |max_out|, then
-    // ssl_private_key_failure is returned. Otherwise, ssl_private_key_success
-    // is returned with the signature put in |*out| and the length in
-    // |*out_len|.
-    virtual ssl_private_key_result_t PrivateKeySign(uint8_t* out,
-                                                    size_t* out_len,
-                                                    size_t max_out,
-                                                    uint16_t sig_alg,
-                                                    absl::string_view in) = 0;
-
-    // When PrivateKeySign returns ssl_private_key_retry, PrivateKeyComplete
-    // will be called after the async sign operation has completed.
-    // PrivateKeyComplete puts the resulting signature in |*out| and length in
-    // |*out_len|. If the length is greater than |max_out| or if there was an
-    // error in signing, then ssl_private_key_failure is returned. Otherwise,
-    // ssl_private_key_success is returned.
-    virtual ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
-                                                        size_t* out_len,
-                                                        size_t max_out) = 0;
-
-    // The following functions are used to implement an SSL_TICKET_AEAD_METHOD.
-    // See
-    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#ssl_ticket_aead_result_t
-    // for details on the BoringSSL API.
-
-    // SessionTicketMaxOverhead returns the maximum number of bytes of overhead
-    // that SessionTicketSeal may add when encrypting a session ticket.
-    virtual size_t SessionTicketMaxOverhead() = 0;
-
-    // SessionTicketSeal encrypts the session ticket in |in|, putting the
-    // resulting encrypted ticket in |out|, writing the length of the bytes
-    // written to |*out_len|, which is no larger than |max_out_len|. It returns
-    // 1 on success and 0 on error.
-    virtual int SessionTicketSeal(uint8_t* out,
-                                  size_t* out_len,
-                                  size_t max_out_len,
-                                  absl::string_view in) = 0;
-
-    // SessionTicketOpen is called when BoringSSL has an encrypted session
-    // ticket |in| and wants the ticket decrypted. This decryption operation can
-    // happen synchronously or asynchronously.
-    //
-    // If the decrypted ticket is not available at the time of the function
-    // call, this function returns ssl_ticket_aead_retry. If this function
-    // returns ssl_ticket_aead_retry, then SSL_do_handshake will return
-    // SSL_ERROR_PENDING_TICKET. Once the pending ticket decryption has
-    // completed, SSL_do_handshake needs to be called again.
-    //
-    // When this function is called and the decrypted ticket is available
-    // (either the ticket was decrypted synchronously, or an asynchronous
-    // operation has completed and SSL_do_handshake has been called again), the
-    // decrypted ticket is put in |out|, and the length of that output is
-    // written to |*out_len|, not to exceed |max_out_len|, and
-    // ssl_ticket_aead_success is returned. If the ticket cannot be decrypted
-    // and should be ignored, this function returns
-    // ssl_ticket_aead_ignore_ticket and a full handshake will be performed
-    // instead. If a fatal error occurs, ssl_ticket_aead_error can be returned
-    // which will terminate the handshake.
-    virtual enum ssl_ticket_aead_result_t SessionTicketOpen(
-        uint8_t* out,
-        size_t* out_len,
-        size_t max_out_len,
-        absl::string_view in) = 0;
-
-    // Provides the delegate for callbacks that are shared between client and
-    // server.
-    virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
-
-    friend class TlsServerConnection;
-  };
-
-  TlsServerConnection(SSL_CTX* ssl_ctx,
-                      Delegate* delegate,
-                      QuicSSLConfig ssl_config);
-
-  // Creates and configures an SSL_CTX that is appropriate for servers to use.
-  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(ProofSource* proof_source);
-
-  void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain);
-
-  // Set the client cert mode to be used on this connection. This should be
-  // called right after cert selection at the latest, otherwise it is too late
-  // to has an effect.
-  void SetClientCertMode(ClientCertMode client_cert_mode);
-
- private:
-  // Specialization of TlsConnection::ConnectionFromSsl.
-  static TlsServerConnection* ConnectionFromSsl(SSL* ssl);
-
-  static ssl_select_cert_result_t EarlySelectCertCallback(
-      const SSL_CLIENT_HELLO* client_hello);
-
-  // These functions are registered as callbacks in BoringSSL and delegate their
-  // implementation to the matching methods in Delegate above.
-  static int TlsExtServernameCallback(SSL* ssl, int* out_alert, void* arg);
-  static int SelectAlpnCallback(SSL* ssl,
-                                const uint8_t** out,
-                                uint8_t* out_len,
-                                const uint8_t* in,
-                                unsigned in_len,
-                                void* arg);
-
-  // |kPrivateKeyMethod| is a vtable pointing to PrivateKeySign and
-  // PrivateKeyComplete used by the TLS stack to compute the signature for the
-  // CertificateVerify message (using the server's private key).
-  static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
-
-  // The following functions make up the contents of |kPrivateKeyMethod|.
-  static ssl_private_key_result_t PrivateKeySign(SSL* ssl,
-                                                 uint8_t* out,
-                                                 size_t* out_len,
-                                                 size_t max_out,
-                                                 uint16_t sig_alg,
-                                                 const uint8_t* in,
-                                                 size_t in_len);
-  static ssl_private_key_result_t PrivateKeyComplete(SSL* ssl,
-                                                     uint8_t* out,
-                                                     size_t* out_len,
-                                                     size_t max_out);
-
-  // Implementation of SSL_TICKET_AEAD_METHOD which delegates to corresponding
-  // methods in TlsServerConnection::Delegate (a.k.a. TlsServerHandshaker).
-  static const SSL_TICKET_AEAD_METHOD kSessionTicketMethod;
-
-  // The following functions make up the contents of |kSessionTicketMethod|.
-  static size_t SessionTicketMaxOverhead(SSL* ssl);
-  static int SessionTicketSeal(SSL* ssl,
-                               uint8_t* out,
-                               size_t* out_len,
-                               size_t max_out_len,
-                               const uint8_t* in,
-                               size_t in_len);
-  static enum ssl_ticket_aead_result_t SessionTicketOpen(SSL* ssl,
-                                                         uint8_t* out,
-                                                         size_t* out_len,
-                                                         size_t max_out_len,
-                                                         const uint8_t* in,
-                                                         size_t in_len);
-
-  // Install custom verify callback on ssl() if |ssl_config().client_cert_mode|
-  // is not ClientCertMode::kNone. Uninstall otherwise.
-  void UpdateCertVerifyCallback();
-
-  Delegate* delegate_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
diff --git a/quic/core/crypto/transport_parameters.cc b/quic/core/crypto/transport_parameters.cc
deleted file mode 100644
index 4417d23..0000000
--- a/quic/core/crypto/transport_parameters.cc
+++ /dev/null
@@ -1,1590 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/transport_parameters.h"
-
-#include <cstdint>
-#include <cstring>
-#include <forward_list>
-#include <memory>
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/digest.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// Values of the TransportParameterId enum as defined in the
-// "Transport Parameter Encoding" section of draft-ietf-quic-transport.
-// When parameters are encoded, one of these enum values is used to indicate
-// which parameter is encoded. The supported draft version is noted in
-// transport_parameters.h.
-enum TransportParameters::TransportParameterId : uint64_t {
-  kOriginalDestinationConnectionId = 0,
-  kMaxIdleTimeout = 1,
-  kStatelessResetToken = 2,
-  kMaxPacketSize = 3,
-  kInitialMaxData = 4,
-  kInitialMaxStreamDataBidiLocal = 5,
-  kInitialMaxStreamDataBidiRemote = 6,
-  kInitialMaxStreamDataUni = 7,
-  kInitialMaxStreamsBidi = 8,
-  kInitialMaxStreamsUni = 9,
-  kAckDelayExponent = 0xa,
-  kMaxAckDelay = 0xb,
-  kDisableActiveMigration = 0xc,
-  kPreferredAddress = 0xd,
-  kActiveConnectionIdLimit = 0xe,
-  kInitialSourceConnectionId = 0xf,
-  kRetrySourceConnectionId = 0x10,
-
-  kMaxDatagramFrameSize = 0x20,
-
-  kInitialRoundTripTime = 0x3127,
-  kGoogleConnectionOptions = 0x3128,
-  // 0x3129 was used to convey the user agent string.
-  // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
-  // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
-  // 0x4751 was used for non-standard Google-specific parameters encoded as a
-  // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
-  kGoogleQuicVersion =
-      0x4752,  // Used to transmit version and supported_versions.
-
-  kMinAckDelay = 0xDE1A,           // draft-iyengar-quic-delayed-ack.
-  kVersionInformation = 0xFF73DB,  // draft-ietf-quic-version-negotiation.
-};
-
-namespace {
-
-// The following constants define minimum and maximum allowed values for some of
-// the parameters. These come from the "Transport Parameter Definitions"
-// section of draft-ietf-quic-transport.
-constexpr uint64_t kMinMaxPacketSizeTransportParam = 1200;
-constexpr uint64_t kMaxAckDelayExponentTransportParam = 20;
-constexpr uint64_t kDefaultAckDelayExponentTransportParam = 3;
-constexpr uint64_t kMaxMaxAckDelayTransportParam = 16383;
-constexpr uint64_t kDefaultMaxAckDelayTransportParam = 25;
-constexpr uint64_t kMinActiveConnectionIdLimitTransportParam = 2;
-constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;
-
-std::string TransportParameterIdToString(
-    TransportParameters::TransportParameterId param_id) {
-  switch (param_id) {
-    case TransportParameters::kOriginalDestinationConnectionId:
-      return "original_destination_connection_id";
-    case TransportParameters::kMaxIdleTimeout:
-      return "max_idle_timeout";
-    case TransportParameters::kStatelessResetToken:
-      return "stateless_reset_token";
-    case TransportParameters::kMaxPacketSize:
-      return "max_udp_payload_size";
-    case TransportParameters::kInitialMaxData:
-      return "initial_max_data";
-    case TransportParameters::kInitialMaxStreamDataBidiLocal:
-      return "initial_max_stream_data_bidi_local";
-    case TransportParameters::kInitialMaxStreamDataBidiRemote:
-      return "initial_max_stream_data_bidi_remote";
-    case TransportParameters::kInitialMaxStreamDataUni:
-      return "initial_max_stream_data_uni";
-    case TransportParameters::kInitialMaxStreamsBidi:
-      return "initial_max_streams_bidi";
-    case TransportParameters::kInitialMaxStreamsUni:
-      return "initial_max_streams_uni";
-    case TransportParameters::kAckDelayExponent:
-      return "ack_delay_exponent";
-    case TransportParameters::kMaxAckDelay:
-      return "max_ack_delay";
-    case TransportParameters::kDisableActiveMigration:
-      return "disable_active_migration";
-    case TransportParameters::kPreferredAddress:
-      return "preferred_address";
-    case TransportParameters::kActiveConnectionIdLimit:
-      return "active_connection_id_limit";
-    case TransportParameters::kInitialSourceConnectionId:
-      return "initial_source_connection_id";
-    case TransportParameters::kRetrySourceConnectionId:
-      return "retry_source_connection_id";
-    case TransportParameters::kMaxDatagramFrameSize:
-      return "max_datagram_frame_size";
-    case TransportParameters::kInitialRoundTripTime:
-      return "initial_round_trip_time";
-    case TransportParameters::kGoogleConnectionOptions:
-      return "google_connection_options";
-    case TransportParameters::kGoogleQuicVersion:
-      return "google-version";
-    case TransportParameters::kMinAckDelay:
-      return "min_ack_delay_us";
-    case TransportParameters::kVersionInformation:
-      return "version_information";
-  }
-  return absl::StrCat("Unknown(", param_id, ")");
-}
-
-bool TransportParameterIdIsKnown(
-    TransportParameters::TransportParameterId param_id) {
-  switch (param_id) {
-    case TransportParameters::kOriginalDestinationConnectionId:
-    case TransportParameters::kMaxIdleTimeout:
-    case TransportParameters::kStatelessResetToken:
-    case TransportParameters::kMaxPacketSize:
-    case TransportParameters::kInitialMaxData:
-    case TransportParameters::kInitialMaxStreamDataBidiLocal:
-    case TransportParameters::kInitialMaxStreamDataBidiRemote:
-    case TransportParameters::kInitialMaxStreamDataUni:
-    case TransportParameters::kInitialMaxStreamsBidi:
-    case TransportParameters::kInitialMaxStreamsUni:
-    case TransportParameters::kAckDelayExponent:
-    case TransportParameters::kMaxAckDelay:
-    case TransportParameters::kDisableActiveMigration:
-    case TransportParameters::kPreferredAddress:
-    case TransportParameters::kActiveConnectionIdLimit:
-    case TransportParameters::kInitialSourceConnectionId:
-    case TransportParameters::kRetrySourceConnectionId:
-    case TransportParameters::kMaxDatagramFrameSize:
-    case TransportParameters::kInitialRoundTripTime:
-    case TransportParameters::kGoogleConnectionOptions:
-    case TransportParameters::kGoogleQuicVersion:
-    case TransportParameters::kMinAckDelay:
-    case TransportParameters::kVersionInformation:
-      return true;
-  }
-  return false;
-}
-
-}  // namespace
-
-TransportParameters::IntegerParameter::IntegerParameter(
-    TransportParameters::TransportParameterId param_id,
-    uint64_t default_value,
-    uint64_t min_value,
-    uint64_t max_value)
-    : param_id_(param_id),
-      value_(default_value),
-      default_value_(default_value),
-      min_value_(min_value),
-      max_value_(max_value),
-      has_been_read_(false) {
-  QUICHE_DCHECK_LE(min_value, default_value);
-  QUICHE_DCHECK_LE(default_value, max_value);
-  QUICHE_DCHECK_LE(max_value, kVarInt62MaxValue);
-}
-
-TransportParameters::IntegerParameter::IntegerParameter(
-    TransportParameters::TransportParameterId param_id)
-    : TransportParameters::IntegerParameter::IntegerParameter(
-          param_id,
-          0,
-          0,
-          kVarInt62MaxValue) {}
-
-void TransportParameters::IntegerParameter::set_value(uint64_t value) {
-  value_ = value;
-}
-
-uint64_t TransportParameters::IntegerParameter::value() const {
-  return value_;
-}
-
-bool TransportParameters::IntegerParameter::IsValid() const {
-  return min_value_ <= value_ && value_ <= max_value_;
-}
-
-bool TransportParameters::IntegerParameter::Write(
-    QuicDataWriter* writer) const {
-  QUICHE_DCHECK(IsValid());
-  if (value_ == default_value_) {
-    // Do not write if the value is default.
-    return true;
-  }
-  if (!writer->WriteVarInt62(param_id_)) {
-    QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
-    return false;
-  }
-  const QuicVariableLengthIntegerLength value_length =
-      QuicDataWriter::GetVarInt62Len(value_);
-  if (!writer->WriteVarInt62(value_length)) {
-    QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
-    return false;
-  }
-  if (!writer->WriteVarInt62(value_, value_length)) {
-    QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
-    return false;
-  }
-  return true;
-}
-
-bool TransportParameters::IntegerParameter::Read(QuicDataReader* reader,
-                                                 std::string* error_details) {
-  if (has_been_read_) {
-    *error_details =
-        "Received a second " + TransportParameterIdToString(param_id_);
-    return false;
-  }
-  has_been_read_ = true;
-
-  if (!reader->ReadVarInt62(&value_)) {
-    *error_details =
-        "Failed to parse value for " + TransportParameterIdToString(param_id_);
-    return false;
-  }
-  if (!reader->IsDoneReading()) {
-    *error_details =
-        absl::StrCat("Received unexpected ", reader->BytesRemaining(),
-                     " bytes after parsing ", this->ToString(false));
-    return false;
-  }
-  return true;
-}
-
-std::string TransportParameters::IntegerParameter::ToString(
-    bool for_use_in_list) const {
-  if (for_use_in_list && value_ == default_value_) {
-    return "";
-  }
-  std::string rv = for_use_in_list ? " " : "";
-  absl::StrAppend(&rv, TransportParameterIdToString(param_id_), " ", value_);
-  if (!IsValid()) {
-    rv += " (Invalid)";
-  }
-  return rv;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const TransportParameters::IntegerParameter& param) {
-  os << param.ToString(/*for_use_in_list=*/false);
-  return os;
-}
-
-TransportParameters::PreferredAddress::PreferredAddress()
-    : ipv4_socket_address(QuicIpAddress::Any4(), 0),
-      ipv6_socket_address(QuicIpAddress::Any6(), 0),
-      connection_id(EmptyQuicConnectionId()),
-      stateless_reset_token(kStatelessResetTokenLength, 0) {}
-
-TransportParameters::PreferredAddress::~PreferredAddress() {}
-
-bool TransportParameters::PreferredAddress::operator==(
-    const PreferredAddress& rhs) const {
-  return ipv4_socket_address == rhs.ipv4_socket_address &&
-         ipv6_socket_address == rhs.ipv6_socket_address &&
-         connection_id == rhs.connection_id &&
-         stateless_reset_token == rhs.stateless_reset_token;
-}
-
-bool TransportParameters::PreferredAddress::operator!=(
-    const PreferredAddress& rhs) const {
-  return !(*this == rhs);
-}
-
-std::ostream& operator<<(
-    std::ostream& os,
-    const TransportParameters::PreferredAddress& preferred_address) {
-  os << preferred_address.ToString();
-  return os;
-}
-
-std::string TransportParameters::PreferredAddress::ToString() const {
-  return "[" + ipv4_socket_address.ToString() + " " +
-         ipv6_socket_address.ToString() + " connection_id " +
-         connection_id.ToString() + " stateless_reset_token " +
-         absl::BytesToHexString(absl::string_view(
-             reinterpret_cast<const char*>(stateless_reset_token.data()),
-             stateless_reset_token.size())) +
-         "]";
-}
-
-TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
-    : version(0) {}
-
-bool TransportParameters::LegacyVersionInformation::operator==(
-    const LegacyVersionInformation& rhs) const {
-  return version == rhs.version && supported_versions == rhs.supported_versions;
-}
-
-bool TransportParameters::LegacyVersionInformation::operator!=(
-    const LegacyVersionInformation& rhs) const {
-  return !(*this == rhs);
-}
-
-std::string TransportParameters::LegacyVersionInformation::ToString() const {
-  std::string rv =
-      absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
-  if (!supported_versions.empty()) {
-    absl::StrAppend(&rv,
-                    " supported_versions " +
-                        QuicVersionLabelVectorToString(supported_versions));
-  }
-  absl::StrAppend(&rv, "]");
-  return rv;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const TransportParameters::LegacyVersionInformation&
-                             legacy_version_information) {
-  os << legacy_version_information.ToString();
-  return os;
-}
-
-TransportParameters::VersionInformation::VersionInformation()
-    : chosen_version(0) {}
-
-bool TransportParameters::VersionInformation::operator==(
-    const VersionInformation& rhs) const {
-  return chosen_version == rhs.chosen_version &&
-         other_versions == rhs.other_versions;
-}
-
-bool TransportParameters::VersionInformation::operator!=(
-    const VersionInformation& rhs) const {
-  return !(*this == rhs);
-}
-
-std::string TransportParameters::VersionInformation::ToString() const {
-  std::string rv = absl::StrCat("[chosen_version ",
-                                QuicVersionLabelToString(chosen_version));
-  if (!other_versions.empty()) {
-    absl::StrAppend(&rv, " other_versions " +
-                             QuicVersionLabelVectorToString(other_versions));
-  }
-  absl::StrAppend(&rv, "]");
-  return rv;
-}
-
-std::ostream& operator<<(
-    std::ostream& os,
-    const TransportParameters::VersionInformation& version_information) {
-  os << version_information.ToString();
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
-  os << params.ToString();
-  return os;
-}
-
-std::string TransportParameters::ToString() const {
-  std::string rv = "[";
-  if (perspective == Perspective::IS_SERVER) {
-    rv += "Server";
-  } else {
-    rv += "Client";
-  }
-  if (legacy_version_information.has_value()) {
-    rv += " " + legacy_version_information.value().ToString();
-  }
-  if (version_information.has_value()) {
-    rv += " " + version_information.value().ToString();
-  }
-  if (original_destination_connection_id.has_value()) {
-    rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
-          " " + original_destination_connection_id.value().ToString();
-  }
-  rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
-  if (!stateless_reset_token.empty()) {
-    rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
-          absl::BytesToHexString(absl::string_view(
-              reinterpret_cast<const char*>(stateless_reset_token.data()),
-              stateless_reset_token.size()));
-  }
-  rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
-  rv += initial_max_data.ToString(/*for_use_in_list=*/true);
-  rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
-  rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
-  rv += initial_max_stream_data_uni.ToString(/*for_use_in_list=*/true);
-  rv += initial_max_streams_bidi.ToString(/*for_use_in_list=*/true);
-  rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
-  rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
-  rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
-  rv += min_ack_delay_us.ToString(/*for_use_in_list=*/true);
-  if (disable_active_migration) {
-    rv += " " + TransportParameterIdToString(kDisableActiveMigration);
-  }
-  if (preferred_address) {
-    rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
-          preferred_address->ToString();
-  }
-  rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
-  if (initial_source_connection_id.has_value()) {
-    rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
-          initial_source_connection_id.value().ToString();
-  }
-  if (retry_source_connection_id.has_value()) {
-    rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
-          retry_source_connection_id.value().ToString();
-  }
-  rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
-  rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
-  if (google_connection_options.has_value()) {
-    rv += " " + TransportParameterIdToString(kGoogleConnectionOptions) + " ";
-    bool first = true;
-    for (const QuicTag& connection_option : google_connection_options.value()) {
-      if (first) {
-        first = false;
-      } else {
-        rv += ",";
-      }
-      rv += QuicTagToString(connection_option);
-    }
-  }
-  for (const auto& kv : custom_parameters) {
-    absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
-                    "=");
-    static constexpr size_t kMaxPrintableLength = 32;
-    if (kv.second.length() <= kMaxPrintableLength) {
-      rv += absl::BytesToHexString(kv.second);
-    } else {
-      absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
-      rv += absl::StrCat(absl::BytesToHexString(truncated), "...(length ",
-                         kv.second.length(), ")");
-    }
-  }
-  rv += "]";
-  return rv;
-}
-
-TransportParameters::TransportParameters()
-    : max_idle_timeout_ms(kMaxIdleTimeout),
-      max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
-                           kMinMaxPacketSizeTransportParam, kVarInt62MaxValue),
-      initial_max_data(kInitialMaxData),
-      initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
-      initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
-      initial_max_stream_data_uni(kInitialMaxStreamDataUni),
-      initial_max_streams_bidi(kInitialMaxStreamsBidi),
-      initial_max_streams_uni(kInitialMaxStreamsUni),
-      ack_delay_exponent(kAckDelayExponent,
-                         kDefaultAckDelayExponentTransportParam, 0,
-                         kMaxAckDelayExponentTransportParam),
-      max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
-                    kMaxMaxAckDelayTransportParam),
-      min_ack_delay_us(kMinAckDelay, 0, 0,
-                       kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
-      disable_active_migration(false),
-      active_connection_id_limit(kActiveConnectionIdLimit,
-                                 kDefaultActiveConnectionIdLimitTransportParam,
-                                 kMinActiveConnectionIdLimitTransportParam,
-                                 kVarInt62MaxValue),
-      max_datagram_frame_size(kMaxDatagramFrameSize),
-      initial_round_trip_time_us(kInitialRoundTripTime)
-// Important note: any new transport parameters must be added
-// to TransportParameters::AreValid, SerializeTransportParameters and
-// ParseTransportParameters, TransportParameters's custom copy constructor, the
-// operator==, and TransportParametersTest.Comparator.
-{}
-
-TransportParameters::TransportParameters(const TransportParameters& other)
-    : perspective(other.perspective),
-      legacy_version_information(other.legacy_version_information),
-      version_information(other.version_information),
-      original_destination_connection_id(
-          other.original_destination_connection_id),
-      max_idle_timeout_ms(other.max_idle_timeout_ms),
-      stateless_reset_token(other.stateless_reset_token),
-      max_udp_payload_size(other.max_udp_payload_size),
-      initial_max_data(other.initial_max_data),
-      initial_max_stream_data_bidi_local(
-          other.initial_max_stream_data_bidi_local),
-      initial_max_stream_data_bidi_remote(
-          other.initial_max_stream_data_bidi_remote),
-      initial_max_stream_data_uni(other.initial_max_stream_data_uni),
-      initial_max_streams_bidi(other.initial_max_streams_bidi),
-      initial_max_streams_uni(other.initial_max_streams_uni),
-      ack_delay_exponent(other.ack_delay_exponent),
-      max_ack_delay(other.max_ack_delay),
-      min_ack_delay_us(other.min_ack_delay_us),
-      disable_active_migration(other.disable_active_migration),
-      active_connection_id_limit(other.active_connection_id_limit),
-      initial_source_connection_id(other.initial_source_connection_id),
-      retry_source_connection_id(other.retry_source_connection_id),
-      max_datagram_frame_size(other.max_datagram_frame_size),
-      initial_round_trip_time_us(other.initial_round_trip_time_us),
-      google_connection_options(other.google_connection_options),
-      custom_parameters(other.custom_parameters) {
-  if (other.preferred_address) {
-    preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
-        *other.preferred_address);
-  }
-}
-
-bool TransportParameters::operator==(const TransportParameters& rhs) const {
-  if (!(perspective == rhs.perspective &&
-        legacy_version_information == rhs.legacy_version_information &&
-        version_information == rhs.version_information &&
-        original_destination_connection_id ==
-            rhs.original_destination_connection_id &&
-        max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
-        stateless_reset_token == rhs.stateless_reset_token &&
-        max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
-        initial_max_data.value() == rhs.initial_max_data.value() &&
-        initial_max_stream_data_bidi_local.value() ==
-            rhs.initial_max_stream_data_bidi_local.value() &&
-        initial_max_stream_data_bidi_remote.value() ==
-            rhs.initial_max_stream_data_bidi_remote.value() &&
-        initial_max_stream_data_uni.value() ==
-            rhs.initial_max_stream_data_uni.value() &&
-        initial_max_streams_bidi.value() ==
-            rhs.initial_max_streams_bidi.value() &&
-        initial_max_streams_uni.value() ==
-            rhs.initial_max_streams_uni.value() &&
-        ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
-        max_ack_delay.value() == rhs.max_ack_delay.value() &&
-        min_ack_delay_us.value() == rhs.min_ack_delay_us.value() &&
-        disable_active_migration == rhs.disable_active_migration &&
-        active_connection_id_limit.value() ==
-            rhs.active_connection_id_limit.value() &&
-        initial_source_connection_id == rhs.initial_source_connection_id &&
-        retry_source_connection_id == rhs.retry_source_connection_id &&
-        max_datagram_frame_size.value() ==
-            rhs.max_datagram_frame_size.value() &&
-        initial_round_trip_time_us.value() ==
-            rhs.initial_round_trip_time_us.value() &&
-        google_connection_options == rhs.google_connection_options &&
-        custom_parameters == rhs.custom_parameters)) {
-    return false;
-  }
-
-  if ((!preferred_address && rhs.preferred_address) ||
-      (preferred_address && !rhs.preferred_address)) {
-    return false;
-  }
-  if (preferred_address && rhs.preferred_address &&
-      *preferred_address != *rhs.preferred_address) {
-    return false;
-  }
-
-  return true;
-}
-
-bool TransportParameters::operator!=(const TransportParameters& rhs) const {
-  return !(*this == rhs);
-}
-
-bool TransportParameters::AreValid(std::string* error_details) const {
-  QUICHE_DCHECK(perspective == Perspective::IS_CLIENT ||
-                perspective == Perspective::IS_SERVER);
-  if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
-    *error_details = "Client cannot send stateless reset token";
-    return false;
-  }
-  if (perspective == Perspective::IS_CLIENT &&
-      original_destination_connection_id.has_value()) {
-    *error_details = "Client cannot send original_destination_connection_id";
-    return false;
-  }
-  if (!stateless_reset_token.empty() &&
-      stateless_reset_token.size() != kStatelessResetTokenLength) {
-    *error_details = absl::StrCat("Stateless reset token has bad length ",
-                                  stateless_reset_token.size());
-    return false;
-  }
-  if (perspective == Perspective::IS_CLIENT && preferred_address) {
-    *error_details = "Client cannot send preferred address";
-    return false;
-  }
-  if (preferred_address && preferred_address->stateless_reset_token.size() !=
-                               kStatelessResetTokenLength) {
-    *error_details =
-        absl::StrCat("Preferred address stateless reset token has bad length ",
-                     preferred_address->stateless_reset_token.size());
-    return false;
-  }
-  if (preferred_address &&
-      (!preferred_address->ipv4_socket_address.host().IsIPv4() ||
-       !preferred_address->ipv6_socket_address.host().IsIPv6())) {
-    QUIC_BUG(quic_bug_10743_4) << "Preferred address family failure";
-    *error_details = "Internal preferred address family failure";
-    return false;
-  }
-  if (perspective == Perspective::IS_CLIENT &&
-      retry_source_connection_id.has_value()) {
-    *error_details = "Client cannot send retry_source_connection_id";
-    return false;
-  }
-  for (const auto& kv : custom_parameters) {
-    if (TransportParameterIdIsKnown(kv.first)) {
-      *error_details = absl::StrCat("Using custom_parameters with known ID ",
-                                    TransportParameterIdToString(kv.first),
-                                    " is not allowed");
-      return false;
-    }
-  }
-  if (perspective == Perspective::IS_SERVER &&
-      initial_round_trip_time_us.value() > 0) {
-    *error_details = "Server cannot send initial round trip time";
-    return false;
-  }
-  if (version_information.has_value()) {
-    const QuicVersionLabel& chosen_version =
-        version_information.value().chosen_version;
-    const QuicVersionLabelVector& other_versions =
-        version_information.value().other_versions;
-    if (chosen_version == 0) {
-      *error_details = "Invalid chosen version";
-      return false;
-    }
-    if (perspective == Perspective::IS_CLIENT &&
-        std::find(other_versions.begin(), other_versions.end(),
-                  chosen_version) == other_versions.end()) {
-      // When sent by the client, chosen_version needs to be present in
-      // other_versions because other_versions lists the compatible versions and
-      // the chosen version is part of that list. When sent by the server,
-      // other_version contains the list of fully-deployed versions which is
-      // generally equal to the list of supported versions but can slightly
-      // differ during removal of versions across a server fleet. See
-      // draft-ietf-quic-version-negotiation for details.
-      *error_details = "Client chosen version not in other versions";
-      return false;
-    }
-  }
-  const bool ok =
-      max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
-      initial_max_data.IsValid() &&
-      initial_max_stream_data_bidi_local.IsValid() &&
-      initial_max_stream_data_bidi_remote.IsValid() &&
-      initial_max_stream_data_uni.IsValid() &&
-      initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() &&
-      ack_delay_exponent.IsValid() && max_ack_delay.IsValid() &&
-      min_ack_delay_us.IsValid() && active_connection_id_limit.IsValid() &&
-      max_datagram_frame_size.IsValid() && initial_round_trip_time_us.IsValid();
-  if (!ok) {
-    *error_details = "Invalid transport parameters " + this->ToString();
-  }
-  return ok;
-}
-
-TransportParameters::~TransportParameters() = default;
-
-bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
-                                  const TransportParameters& in,
-                                  std::vector<uint8_t>* out) {
-  std::string error_details;
-  if (!in.AreValid(&error_details)) {
-    QUIC_BUG(invalid transport parameters)
-        << "Not serializing invalid transport parameters: " << error_details;
-    return false;
-  }
-  if (!in.legacy_version_information.has_value() ||
-      in.legacy_version_information.value().version == 0 ||
-      (in.perspective == Perspective::IS_SERVER &&
-       in.legacy_version_information.value().supported_versions.empty())) {
-    QUIC_BUG(missing versions) << "Refusing to serialize without versions";
-    return false;
-  }
-  TransportParameters::ParameterMap custom_parameters = in.custom_parameters;
-  for (const auto& kv : custom_parameters) {
-    if (kv.first % 31 == 27) {
-      // See the "Reserved Transport Parameters" section of RFC 9000.
-      QUIC_BUG(custom_parameters with GREASE)
-          << "Serializing custom_parameters with GREASE ID " << kv.first
-          << " is not allowed";
-      return false;
-    }
-  }
-
-  // Maximum length of the GREASE transport parameter (see below).
-  static constexpr size_t kMaxGreaseLength = 16;
-
-  // Empirically transport parameters generally fit within 128 bytes, but we
-  // need to allocate the size up front. Integer transport parameters
-  // have a maximum encoded length of 24 bytes (3 variable length integers),
-  // other transport parameters have a length of 16 + the maximum value length.
-  static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
-  static constexpr size_t kIntegerParameterLength =
-      kTypeAndValueLength + sizeof(uint64_t);
-  static constexpr size_t kStatelessResetParameterLength =
-      kTypeAndValueLength + 16 /* stateless reset token length */;
-  static constexpr size_t kConnectionIdParameterLength =
-      kTypeAndValueLength + 255 /* maximum connection ID length */;
-  static constexpr size_t kPreferredAddressParameterLength =
-      kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
-      16 /* IPv6 address */ + 1 /* Connection ID length */ +
-      255 /* maximum connection ID length */ + 16 /* stateless reset token */;
-  static constexpr size_t kKnownTransportParamLength =
-      kConnectionIdParameterLength +      // original_destination_connection_id
-      kIntegerParameterLength +           // max_idle_timeout
-      kStatelessResetParameterLength +    // stateless_reset_token
-      kIntegerParameterLength +           // max_udp_payload_size
-      kIntegerParameterLength +           // initial_max_data
-      kIntegerParameterLength +           // initial_max_stream_data_bidi_local
-      kIntegerParameterLength +           // initial_max_stream_data_bidi_remote
-      kIntegerParameterLength +           // initial_max_stream_data_uni
-      kIntegerParameterLength +           // initial_max_streams_bidi
-      kIntegerParameterLength +           // initial_max_streams_uni
-      kIntegerParameterLength +           // ack_delay_exponent
-      kIntegerParameterLength +           // max_ack_delay
-      kIntegerParameterLength +           // min_ack_delay_us
-      kTypeAndValueLength +               // disable_active_migration
-      kPreferredAddressParameterLength +  // preferred_address
-      kIntegerParameterLength +           // active_connection_id_limit
-      kConnectionIdParameterLength +      // initial_source_connection_id
-      kConnectionIdParameterLength +      // retry_source_connection_id
-      kIntegerParameterLength +           // max_datagram_frame_size
-      kIntegerParameterLength +           // initial_round_trip_time_us
-      kTypeAndValueLength +               // google_connection_options
-      kTypeAndValueLength;                // google-version
-
-  std::vector<TransportParameters::TransportParameterId> parameter_ids = {
-      TransportParameters::kOriginalDestinationConnectionId,
-      TransportParameters::kMaxIdleTimeout,
-      TransportParameters::kStatelessResetToken,
-      TransportParameters::kMaxPacketSize,
-      TransportParameters::kInitialMaxData,
-      TransportParameters::kInitialMaxStreamDataBidiLocal,
-      TransportParameters::kInitialMaxStreamDataBidiRemote,
-      TransportParameters::kInitialMaxStreamDataUni,
-      TransportParameters::kInitialMaxStreamsBidi,
-      TransportParameters::kInitialMaxStreamsUni,
-      TransportParameters::kAckDelayExponent,
-      TransportParameters::kMaxAckDelay,
-      TransportParameters::kMinAckDelay,
-      TransportParameters::kActiveConnectionIdLimit,
-      TransportParameters::kMaxDatagramFrameSize,
-      TransportParameters::kInitialRoundTripTime,
-      TransportParameters::kDisableActiveMigration,
-      TransportParameters::kPreferredAddress,
-      TransportParameters::kInitialSourceConnectionId,
-      TransportParameters::kRetrySourceConnectionId,
-      TransportParameters::kGoogleConnectionOptions,
-      TransportParameters::kGoogleQuicVersion,
-      TransportParameters::kVersionInformation,
-  };
-
-  size_t max_transport_param_length = kKnownTransportParamLength;
-  // google_connection_options.
-  if (in.google_connection_options.has_value()) {
-    max_transport_param_length +=
-        in.google_connection_options.value().size() * sizeof(QuicTag);
-  }
-  // Google-specific version extension.
-  if (in.legacy_version_information.has_value()) {
-    max_transport_param_length +=
-        sizeof(in.legacy_version_information.value().version) +
-        1 /* versions length */ +
-        in.legacy_version_information.value().supported_versions.size() *
-            sizeof(QuicVersionLabel);
-  }
-  // version_information.
-  if (in.version_information.has_value()) {
-    max_transport_param_length +=
-        sizeof(in.version_information.value().chosen_version) +
-        // Add one for the added GREASE version.
-        (in.version_information.value().other_versions.size() + 1) *
-            sizeof(QuicVersionLabel);
-  }
-
-  // Add a random GREASE transport parameter, as defined in the
-  // "Reserved Transport Parameters" section of RFC 9000.
-  // This forces receivers to support unexpected input.
-  QuicRandom* random = QuicRandom::GetInstance();
-  // Transport parameter identifiers are 62 bits long so we need to
-  // ensure that the output of the computation below fits in 62 bits.
-  uint64_t grease_id64 = random->RandUint64() % ((1ULL << 62) - 31);
-  // Make sure grease_id % 31 == 27. Note that this is not uniformely
-  // distributed but is acceptable since no security depends on this
-  // randomness.
-  grease_id64 = (grease_id64 / 31) * 31 + 27;
-  TransportParameters::TransportParameterId grease_id =
-      static_cast<TransportParameters::TransportParameterId>(grease_id64);
-  const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
-  QUICHE_DCHECK_GE(kMaxGreaseLength, grease_length);
-  char grease_contents[kMaxGreaseLength];
-  random->RandBytes(grease_contents, grease_length);
-  custom_parameters[grease_id] = std::string(grease_contents, grease_length);
-
-  // Custom parameters.
-  for (const auto& kv : custom_parameters) {
-    max_transport_param_length += kTypeAndValueLength + kv.second.length();
-    parameter_ids.push_back(kv.first);
-  }
-
-  // Randomize order of sent transport parameters by walking the array
-  // backwards and swapping each element with a random earlier one.
-  for (size_t i = parameter_ids.size() - 1; i > 0; i--) {
-    std::swap(parameter_ids[i],
-              parameter_ids[random->InsecureRandUint64() % (i + 1)]);
-  }
-
-  out->resize(max_transport_param_length);
-  QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));
-
-  for (TransportParameters::TransportParameterId parameter_id : parameter_ids) {
-    switch (parameter_id) {
-      // original_destination_connection_id
-      case TransportParameters::kOriginalDestinationConnectionId: {
-        if (in.original_destination_connection_id.has_value()) {
-          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
-          QuicConnectionId original_destination_connection_id =
-              in.original_destination_connection_id.value();
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kOriginalDestinationConnectionId) ||
-              !writer.WriteStringPieceVarInt62(absl::string_view(
-                  original_destination_connection_id.data(),
-                  original_destination_connection_id.length()))) {
-            QUIC_BUG(Failed to write original_destination_connection_id)
-                << "Failed to write original_destination_connection_id "
-                << original_destination_connection_id << " for " << in;
-            return false;
-          }
-        }
-      } break;
-      // max_idle_timeout
-      case TransportParameters::kMaxIdleTimeout: {
-        if (!in.max_idle_timeout_ms.Write(&writer)) {
-          QUIC_BUG(Failed to write idle_timeout)
-              << "Failed to write idle_timeout for " << in;
-          return false;
-        }
-      } break;
-      // stateless_reset_token
-      case TransportParameters::kStatelessResetToken: {
-        if (!in.stateless_reset_token.empty()) {
-          QUICHE_DCHECK_EQ(kStatelessResetTokenLength,
-                           in.stateless_reset_token.size());
-          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kStatelessResetToken) ||
-              !writer.WriteStringPieceVarInt62(
-                  absl::string_view(reinterpret_cast<const char*>(
-                                        in.stateless_reset_token.data()),
-                                    in.stateless_reset_token.size()))) {
-            QUIC_BUG(Failed to write stateless_reset_token)
-                << "Failed to write stateless_reset_token of length "
-                << in.stateless_reset_token.size() << " for " << in;
-            return false;
-          }
-        }
-      } break;
-      // max_udp_payload_size
-      case TransportParameters::kMaxPacketSize: {
-        if (!in.max_udp_payload_size.Write(&writer)) {
-          QUIC_BUG(Failed to write max_udp_payload_size)
-              << "Failed to write max_udp_payload_size for " << in;
-          return false;
-        }
-      } break;
-      // initial_max_data
-      case TransportParameters::kInitialMaxData: {
-        if (!in.initial_max_data.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_max_data)
-              << "Failed to write initial_max_data for " << in;
-          return false;
-        }
-      } break;
-      // initial_max_stream_data_bidi_local
-      case TransportParameters::kInitialMaxStreamDataBidiLocal: {
-        if (!in.initial_max_stream_data_bidi_local.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_max_stream_data_bidi_local)
-              << "Failed to write initial_max_stream_data_bidi_local for "
-              << in;
-          return false;
-        }
-      } break;
-      // initial_max_stream_data_bidi_remote
-      case TransportParameters::kInitialMaxStreamDataBidiRemote: {
-        if (!in.initial_max_stream_data_bidi_remote.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_max_stream_data_bidi_remote)
-              << "Failed to write initial_max_stream_data_bidi_remote for "
-              << in;
-          return false;
-        }
-      } break;
-      // initial_max_stream_data_uni
-      case TransportParameters::kInitialMaxStreamDataUni: {
-        if (!in.initial_max_stream_data_uni.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_max_stream_data_uni)
-              << "Failed to write initial_max_stream_data_uni for " << in;
-          return false;
-        }
-      } break;
-      // initial_max_streams_bidi
-      case TransportParameters::kInitialMaxStreamsBidi: {
-        if (!in.initial_max_streams_bidi.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_max_streams_bidi)
-              << "Failed to write initial_max_streams_bidi for " << in;
-          return false;
-        }
-      } break;
-      // initial_max_streams_uni
-      case TransportParameters::kInitialMaxStreamsUni: {
-        if (!in.initial_max_streams_uni.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_max_streams_uni)
-              << "Failed to write initial_max_streams_uni for " << in;
-          return false;
-        }
-      } break;
-      // ack_delay_exponent
-      case TransportParameters::kAckDelayExponent: {
-        if (!in.ack_delay_exponent.Write(&writer)) {
-          QUIC_BUG(Failed to write ack_delay_exponent)
-              << "Failed to write ack_delay_exponent for " << in;
-          return false;
-        }
-      } break;
-      // max_ack_delay
-      case TransportParameters::kMaxAckDelay: {
-        if (!in.max_ack_delay.Write(&writer)) {
-          QUIC_BUG(Failed to write max_ack_delay)
-              << "Failed to write max_ack_delay for " << in;
-          return false;
-        }
-      } break;
-      // min_ack_delay_us
-      case TransportParameters::kMinAckDelay: {
-        if (!in.min_ack_delay_us.Write(&writer)) {
-          QUIC_BUG(Failed to write min_ack_delay_us)
-              << "Failed to write min_ack_delay_us for " << in;
-          return false;
-        }
-      } break;
-      // active_connection_id_limit
-      case TransportParameters::kActiveConnectionIdLimit: {
-        if (!in.active_connection_id_limit.Write(&writer)) {
-          QUIC_BUG(Failed to write active_connection_id_limit)
-              << "Failed to write active_connection_id_limit for " << in;
-          return false;
-        }
-      } break;
-      // max_datagram_frame_size
-      case TransportParameters::kMaxDatagramFrameSize: {
-        if (!in.max_datagram_frame_size.Write(&writer)) {
-          QUIC_BUG(Failed to write max_datagram_frame_size)
-              << "Failed to write max_datagram_frame_size for " << in;
-          return false;
-        }
-      } break;
-      // initial_round_trip_time_us
-      case TransportParameters::kInitialRoundTripTime: {
-        if (!in.initial_round_trip_time_us.Write(&writer)) {
-          QUIC_BUG(Failed to write initial_round_trip_time_us)
-              << "Failed to write initial_round_trip_time_us for " << in;
-          return false;
-        }
-      } break;
-      // disable_active_migration
-      case TransportParameters::kDisableActiveMigration: {
-        if (in.disable_active_migration) {
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kDisableActiveMigration) ||
-              !writer.WriteVarInt62(/* transport parameter length */ 0)) {
-            QUIC_BUG(Failed to write disable_active_migration)
-                << "Failed to write disable_active_migration for " << in;
-            return false;
-          }
-        }
-      } break;
-      // preferred_address
-      case TransportParameters::kPreferredAddress: {
-        if (in.preferred_address) {
-          std::string v4_address_bytes =
-              in.preferred_address->ipv4_socket_address.host().ToPackedString();
-          std::string v6_address_bytes =
-              in.preferred_address->ipv6_socket_address.host().ToPackedString();
-          if (v4_address_bytes.length() != 4 ||
-              v6_address_bytes.length() != 16 ||
-              in.preferred_address->stateless_reset_token.size() !=
-                  kStatelessResetTokenLength) {
-            QUIC_BUG(quic_bug_10743_12)
-                << "Bad lengths " << *in.preferred_address;
-            return false;
-          }
-          const uint64_t preferred_address_length =
-              v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
-              v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
-              /* connection ID length byte */ sizeof(uint8_t) +
-              in.preferred_address->connection_id.length() +
-              in.preferred_address->stateless_reset_token.size();
-          if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
-              !writer.WriteVarInt62(
-                  /* transport parameter length */ preferred_address_length) ||
-              !writer.WriteStringPiece(v4_address_bytes) ||
-              !writer.WriteUInt16(
-                  in.preferred_address->ipv4_socket_address.port()) ||
-              !writer.WriteStringPiece(v6_address_bytes) ||
-              !writer.WriteUInt16(
-                  in.preferred_address->ipv6_socket_address.port()) ||
-              !writer.WriteUInt8(
-                  in.preferred_address->connection_id.length()) ||
-              !writer.WriteBytes(
-                  in.preferred_address->connection_id.data(),
-                  in.preferred_address->connection_id.length()) ||
-              !writer.WriteBytes(
-                  in.preferred_address->stateless_reset_token.data(),
-                  in.preferred_address->stateless_reset_token.size())) {
-            QUIC_BUG(Failed to write preferred_address)
-                << "Failed to write preferred_address for " << in;
-            return false;
-          }
-        }
-      } break;
-      // initial_source_connection_id
-      case TransportParameters::kInitialSourceConnectionId: {
-        if (in.initial_source_connection_id.has_value()) {
-          QuicConnectionId initial_source_connection_id =
-              in.initial_source_connection_id.value();
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kInitialSourceConnectionId) ||
-              !writer.WriteStringPieceVarInt62(
-                  absl::string_view(initial_source_connection_id.data(),
-                                    initial_source_connection_id.length()))) {
-            QUIC_BUG(Failed to write initial_source_connection_id)
-                << "Failed to write initial_source_connection_id "
-                << initial_source_connection_id << " for " << in;
-            return false;
-          }
-        }
-      } break;
-      // retry_source_connection_id
-      case TransportParameters::kRetrySourceConnectionId: {
-        if (in.retry_source_connection_id.has_value()) {
-          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
-          QuicConnectionId retry_source_connection_id =
-              in.retry_source_connection_id.value();
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kRetrySourceConnectionId) ||
-              !writer.WriteStringPieceVarInt62(
-                  absl::string_view(retry_source_connection_id.data(),
-                                    retry_source_connection_id.length()))) {
-            QUIC_BUG(Failed to write retry_source_connection_id)
-                << "Failed to write retry_source_connection_id "
-                << retry_source_connection_id << " for " << in;
-            return false;
-          }
-        }
-      } break;
-      // Google-specific connection options.
-      case TransportParameters::kGoogleConnectionOptions: {
-        if (in.google_connection_options.has_value()) {
-          static_assert(
-              sizeof(in.google_connection_options.value().front()) == 4,
-              "bad size");
-          uint64_t connection_options_length =
-              in.google_connection_options.value().size() * 4;
-          if (!writer.WriteVarInt62(
-                  TransportParameters::kGoogleConnectionOptions) ||
-              !writer.WriteVarInt62(
-                  /* transport parameter length */ connection_options_length)) {
-            QUIC_BUG(Failed to write google_connection_options)
-                << "Failed to write google_connection_options of length "
-                << connection_options_length << " for " << in;
-            return false;
-          }
-          for (const QuicTag& connection_option :
-               in.google_connection_options.value()) {
-            if (!writer.WriteTag(connection_option)) {
-              QUIC_BUG(Failed to write google_connection_option)
-                  << "Failed to write google_connection_option "
-                  << QuicTagToString(connection_option) << " for " << in;
-              return false;
-            }
-          }
-        }
-      } break;
-      // Google-specific version extension.
-      case TransportParameters::kGoogleQuicVersion: {
-        if (!in.legacy_version_information.has_value()) {
-          break;
-        }
-        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
-                      "bad length");
-        uint64_t google_version_length =
-            sizeof(in.legacy_version_information.value().version);
-        if (in.perspective == Perspective::IS_SERVER) {
-          google_version_length +=
-              /* versions length */ sizeof(uint8_t) +
-              sizeof(QuicVersionLabel) * in.legacy_version_information.value()
-                                             .supported_versions.size();
-        }
-        if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
-            !writer.WriteVarInt62(
-                /* transport parameter length */ google_version_length) ||
-            !writer.WriteUInt32(
-                in.legacy_version_information.value().version)) {
-          QUIC_BUG(Failed to write Google version extension)
-              << "Failed to write Google version extension for " << in;
-          return false;
-        }
-        if (in.perspective == Perspective::IS_SERVER) {
-          if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
-                                 in.legacy_version_information.value()
-                                     .supported_versions.size())) {
-            QUIC_BUG(Failed to write versions length)
-                << "Failed to write versions length for " << in;
-            return false;
-          }
-          for (QuicVersionLabel version_label :
-               in.legacy_version_information.value().supported_versions) {
-            if (!writer.WriteUInt32(version_label)) {
-              QUIC_BUG(Failed to write supported version)
-                  << "Failed to write supported version for " << in;
-              return false;
-            }
-          }
-        }
-      } break;
-      // version_information.
-      case TransportParameters::kVersionInformation: {
-        if (!in.version_information.has_value()) {
-          break;
-        }
-        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
-                      "bad length");
-        QuicVersionLabelVector other_versions =
-            in.version_information.value().other_versions;
-        // Insert one GREASE version at a random index.
-        const size_t grease_index =
-            random->InsecureRandUint64() % (other_versions.size() + 1);
-        other_versions.insert(
-            other_versions.begin() + grease_index,
-            CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
-        const uint64_t version_information_length =
-            sizeof(in.version_information.value().chosen_version) +
-            sizeof(QuicVersionLabel) * other_versions.size();
-        if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
-            !writer.WriteVarInt62(
-                /* transport parameter length */ version_information_length) ||
-            !writer.WriteUInt32(
-                in.version_information.value().chosen_version)) {
-          QUIC_BUG(Failed to write chosen version)
-              << "Failed to write chosen version for " << in;
-          return false;
-        }
-        for (QuicVersionLabel version_label : other_versions) {
-          if (!writer.WriteUInt32(version_label)) {
-            QUIC_BUG(Failed to write other version)
-                << "Failed to write other version for " << in;
-            return false;
-          }
-        }
-      } break;
-      // Custom parameters and GREASE.
-      default: {
-        auto it = custom_parameters.find(parameter_id);
-        if (it == custom_parameters.end()) {
-          QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
-          return false;
-        }
-        if (!writer.WriteVarInt62(parameter_id) ||
-            !writer.WriteStringPieceVarInt62(it->second)) {
-          QUIC_BUG(Failed to write custom parameter)
-              << "Failed to write custom parameter " << parameter_id;
-          return false;
-        }
-      } break;
-    }
-  }
-
-  out->resize(writer.length());
-
-  QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
-                  << " bytes";
-
-  return true;
-}
-
-bool ParseTransportParameters(ParsedQuicVersion version,
-                              Perspective perspective,
-                              const uint8_t* in,
-                              size_t in_len,
-                              TransportParameters* out,
-                              std::string* error_details) {
-  out->perspective = perspective;
-  QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);
-
-  while (!reader.IsDoneReading()) {
-    uint64_t param_id64;
-    if (!reader.ReadVarInt62(&param_id64)) {
-      *error_details = "Failed to parse transport parameter ID";
-      return false;
-    }
-    TransportParameters::TransportParameterId param_id =
-        static_cast<TransportParameters::TransportParameterId>(param_id64);
-    absl::string_view value;
-    if (!reader.ReadStringPieceVarInt62(&value)) {
-      *error_details =
-          "Failed to read length and value of transport parameter " +
-          TransportParameterIdToString(param_id);
-      return false;
-    }
-    QuicDataReader value_reader(value);
-    bool parse_success = true;
-    switch (param_id) {
-      case TransportParameters::kOriginalDestinationConnectionId: {
-        if (out->original_destination_connection_id.has_value()) {
-          *error_details =
-              "Received a second original_destination_connection_id";
-          return false;
-        }
-        const size_t connection_id_length = value_reader.BytesRemaining();
-        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
-                connection_id_length, version.transport_version)) {
-          *error_details = absl::StrCat(
-              "Received original_destination_connection_id of invalid length ",
-              connection_id_length);
-          return false;
-        }
-        QuicConnectionId original_destination_connection_id;
-        if (!value_reader.ReadConnectionId(&original_destination_connection_id,
-                                           connection_id_length)) {
-          *error_details = "Failed to read original_destination_connection_id";
-          return false;
-        }
-        out->original_destination_connection_id =
-            original_destination_connection_id;
-      } break;
-      case TransportParameters::kMaxIdleTimeout:
-        parse_success =
-            out->max_idle_timeout_ms.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kStatelessResetToken: {
-        if (!out->stateless_reset_token.empty()) {
-          *error_details = "Received a second stateless_reset_token";
-          return false;
-        }
-        absl::string_view stateless_reset_token =
-            value_reader.ReadRemainingPayload();
-        if (stateless_reset_token.length() != kStatelessResetTokenLength) {
-          *error_details =
-              absl::StrCat("Received stateless_reset_token of invalid length ",
-                           stateless_reset_token.length());
-          return false;
-        }
-        out->stateless_reset_token.assign(
-            stateless_reset_token.data(),
-            stateless_reset_token.data() + stateless_reset_token.length());
-      } break;
-      case TransportParameters::kMaxPacketSize:
-        parse_success =
-            out->max_udp_payload_size.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kInitialMaxData:
-        parse_success =
-            out->initial_max_data.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kInitialMaxStreamDataBidiLocal:
-        parse_success = out->initial_max_stream_data_bidi_local.Read(
-            &value_reader, error_details);
-        break;
-      case TransportParameters::kInitialMaxStreamDataBidiRemote:
-        parse_success = out->initial_max_stream_data_bidi_remote.Read(
-            &value_reader, error_details);
-        break;
-      case TransportParameters::kInitialMaxStreamDataUni:
-        parse_success =
-            out->initial_max_stream_data_uni.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kInitialMaxStreamsBidi:
-        parse_success =
-            out->initial_max_streams_bidi.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kInitialMaxStreamsUni:
-        parse_success =
-            out->initial_max_streams_uni.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kAckDelayExponent:
-        parse_success =
-            out->ack_delay_exponent.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kMaxAckDelay:
-        parse_success = out->max_ack_delay.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kDisableActiveMigration:
-        if (out->disable_active_migration) {
-          *error_details = "Received a second disable_active_migration";
-          return false;
-        }
-        out->disable_active_migration = true;
-        break;
-      case TransportParameters::kPreferredAddress: {
-        TransportParameters::PreferredAddress preferred_address;
-        uint16_t ipv4_port, ipv6_port;
-        in_addr ipv4_address;
-        in6_addr ipv6_address;
-        preferred_address.stateless_reset_token.resize(
-            kStatelessResetTokenLength);
-        if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
-            !value_reader.ReadUInt16(&ipv4_port) ||
-            !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
-            !value_reader.ReadUInt16(&ipv6_port) ||
-            !value_reader.ReadLengthPrefixedConnectionId(
-                &preferred_address.connection_id) ||
-            !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
-                                    kStatelessResetTokenLength)) {
-          *error_details = "Failed to read preferred_address";
-          return false;
-        }
-        preferred_address.ipv4_socket_address =
-            QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
-        preferred_address.ipv6_socket_address =
-            QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
-        if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
-            !preferred_address.ipv6_socket_address.host().IsIPv6()) {
-          *error_details = "Received preferred_address of bad families " +
-                           preferred_address.ToString();
-          return false;
-        }
-        if (!QuicUtils::IsConnectionIdValidForVersion(
-                preferred_address.connection_id, version.transport_version)) {
-          *error_details = "Received invalid preferred_address connection ID " +
-                           preferred_address.ToString();
-          return false;
-        }
-        out->preferred_address =
-            std::make_unique<TransportParameters::PreferredAddress>(
-                preferred_address);
-      } break;
-      case TransportParameters::kActiveConnectionIdLimit:
-        parse_success =
-            out->active_connection_id_limit.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kInitialSourceConnectionId: {
-        if (out->initial_source_connection_id.has_value()) {
-          *error_details = "Received a second initial_source_connection_id";
-          return false;
-        }
-        const size_t connection_id_length = value_reader.BytesRemaining();
-        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
-                connection_id_length, version.transport_version)) {
-          *error_details = absl::StrCat(
-              "Received initial_source_connection_id of invalid length ",
-              connection_id_length);
-          return false;
-        }
-        QuicConnectionId initial_source_connection_id;
-        if (!value_reader.ReadConnectionId(&initial_source_connection_id,
-                                           connection_id_length)) {
-          *error_details = "Failed to read initial_source_connection_id";
-          return false;
-        }
-        out->initial_source_connection_id = initial_source_connection_id;
-      } break;
-      case TransportParameters::kRetrySourceConnectionId: {
-        if (out->retry_source_connection_id.has_value()) {
-          *error_details = "Received a second retry_source_connection_id";
-          return false;
-        }
-        const size_t connection_id_length = value_reader.BytesRemaining();
-        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
-                connection_id_length, version.transport_version)) {
-          *error_details = absl::StrCat(
-              "Received retry_source_connection_id of invalid length ",
-              connection_id_length);
-          return false;
-        }
-        QuicConnectionId retry_source_connection_id;
-        if (!value_reader.ReadConnectionId(&retry_source_connection_id,
-                                           connection_id_length)) {
-          *error_details = "Failed to read retry_source_connection_id";
-          return false;
-        }
-        out->retry_source_connection_id = retry_source_connection_id;
-      } break;
-      case TransportParameters::kMaxDatagramFrameSize:
-        parse_success =
-            out->max_datagram_frame_size.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kInitialRoundTripTime:
-        parse_success =
-            out->initial_round_trip_time_us.Read(&value_reader, error_details);
-        break;
-      case TransportParameters::kGoogleConnectionOptions: {
-        if (out->google_connection_options.has_value()) {
-          *error_details = "Received a second google_connection_options";
-          return false;
-        }
-        out->google_connection_options = QuicTagVector{};
-        while (!value_reader.IsDoneReading()) {
-          QuicTag connection_option;
-          if (!value_reader.ReadTag(&connection_option)) {
-            *error_details = "Failed to read a google_connection_options";
-            return false;
-          }
-          out->google_connection_options.value().push_back(connection_option);
-        }
-      } break;
-      case TransportParameters::kGoogleQuicVersion: {
-        if (!out->legacy_version_information.has_value()) {
-          out->legacy_version_information =
-              TransportParameters::LegacyVersionInformation();
-        }
-        if (!value_reader.ReadUInt32(
-                &out->legacy_version_information.value().version)) {
-          *error_details = "Failed to read Google version extension version";
-          return false;
-        }
-        if (perspective == Perspective::IS_SERVER) {
-          uint8_t versions_length;
-          if (!value_reader.ReadUInt8(&versions_length)) {
-            *error_details = "Failed to parse Google supported versions length";
-            return false;
-          }
-          const uint8_t num_versions = versions_length / sizeof(uint32_t);
-          for (uint8_t i = 0; i < num_versions; ++i) {
-            QuicVersionLabel version;
-            if (!value_reader.ReadUInt32(&version)) {
-              *error_details = "Failed to parse Google supported version";
-              return false;
-            }
-            out->legacy_version_information.value()
-                .supported_versions.push_back(version);
-          }
-        }
-      } break;
-      case TransportParameters::kVersionInformation: {
-        if (out->version_information.has_value()) {
-          *error_details = "Received a second version_information";
-          return false;
-        }
-        out->version_information = TransportParameters::VersionInformation();
-        if (!value_reader.ReadUInt32(
-                &out->version_information.value().chosen_version)) {
-          *error_details = "Failed to read chosen version";
-          return false;
-        }
-        while (!value_reader.IsDoneReading()) {
-          QuicVersionLabel other_version;
-          if (!value_reader.ReadUInt32(&other_version)) {
-            *error_details = "Failed to parse other version";
-            return false;
-          }
-          out->version_information.value().other_versions.push_back(
-              other_version);
-        }
-      } break;
-      case TransportParameters::kMinAckDelay:
-        parse_success =
-            out->min_ack_delay_us.Read(&value_reader, error_details);
-        break;
-      default:
-        if (out->custom_parameters.find(param_id) !=
-            out->custom_parameters.end()) {
-          *error_details = "Received a second unknown parameter" +
-                           TransportParameterIdToString(param_id);
-          return false;
-        }
-        out->custom_parameters[param_id] =
-            std::string(value_reader.ReadRemainingPayload());
-        break;
-    }
-    if (!parse_success) {
-      QUICHE_DCHECK(!error_details->empty());
-      return false;
-    }
-    if (!value_reader.IsDoneReading()) {
-      *error_details = absl::StrCat(
-          "Received unexpected ", value_reader.BytesRemaining(),
-          " bytes after parsing ", TransportParameterIdToString(param_id));
-      return false;
-    }
-  }
-
-  if (!out->AreValid(error_details)) {
-    QUICHE_DCHECK(!error_details->empty());
-    return false;
-  }
-
-  QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
-                  << in_len << " bytes";
-
-  return true;
-}
-
-namespace {
-
-bool DigestUpdateIntegerParam(
-    EVP_MD_CTX* hash_ctx,
-    const TransportParameters::IntegerParameter& param) {
-  uint64_t value = param.value();
-  return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
-}
-
-}  // namespace
-
-bool SerializeTransportParametersForTicket(
-    const TransportParameters& in,
-    const std::vector<uint8_t>& application_data,
-    std::vector<uint8_t>* out) {
-  std::string error_details;
-  if (!in.AreValid(&error_details)) {
-    QUIC_BUG(quic_bug_10743_26)
-        << "Not serializing invalid transport parameters: " << error_details;
-    return false;
-  }
-
-  out->resize(SHA256_DIGEST_LENGTH + 1);
-  const uint8_t serialization_version = 0;
-  (*out)[0] = serialization_version;
-
-  bssl::ScopedEVP_MD_CTX hash_ctx;
-  // Write application data:
-  uint64_t app_data_len = application_data.size();
-  const uint64_t parameter_version = 0;
-  // The format of the input to the hash function is as follows:
-  // - The application data, prefixed with a 64-bit length field.
-  // - Transport parameters:
-  //   - A 64-bit version field indicating which version of encoding is used
-  //     for transport parameters.
-  //   - A list of 64-bit integers representing the relevant parameters.
-  //
-  //   When changing which parameters are included, additional parameters can be
-  //   added to the end of the list without changing the version field. New
-  //   parameters that are variable length must be length prefixed. If
-  //   parameters are removed from the list, the version field must be
-  //   incremented.
-  //
-  // Integers happen to be written in host byte order, not network byte order.
-  if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
-      !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
-      !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
-                        application_data.size()) ||
-      !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
-                        sizeof(parameter_version))) {
-    QUIC_BUG(quic_bug_10743_27)
-        << "Unexpected failure of EVP_Digest functions when hashing "
-           "Transport Parameters for ticket";
-    return false;
-  }
-
-  // Write transport parameters specified by draft-ietf-quic-transport-28,
-  // section 7.4.1, that are remembered for 0-RTT.
-  if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
-      !DigestUpdateIntegerParam(hash_ctx.get(),
-                                in.initial_max_stream_data_bidi_local) ||
-      !DigestUpdateIntegerParam(hash_ctx.get(),
-                                in.initial_max_stream_data_bidi_remote) ||
-      !DigestUpdateIntegerParam(hash_ctx.get(),
-                                in.initial_max_stream_data_uni) ||
-      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
-      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
-      !DigestUpdateIntegerParam(hash_ctx.get(),
-                                in.active_connection_id_limit)) {
-    QUIC_BUG(quic_bug_10743_28)
-        << "Unexpected failure of EVP_Digest functions when hashing "
-           "Transport Parameters for ticket";
-    return false;
-  }
-  uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
-  if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
-                        sizeof(disable_active_migration)) ||
-      !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
-    QUIC_BUG(quic_bug_10743_29)
-        << "Unexpected failure of EVP_Digest functions when hashing "
-           "Transport Parameters for ticket";
-    return false;
-  }
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/transport_parameters.h b/quic/core/crypto/transport_parameters.h
deleted file mode 100644
index 1b6f516..0000000
--- a/quic/core/crypto/transport_parameters.h
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
-#define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
-
-#include <memory>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// TransportParameters contains parameters for QUIC's transport layer that are
-// exchanged during the TLS handshake. This struct is a mirror of the struct in
-// the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
-// This struct currently uses the values from draft 29.
-struct QUIC_EXPORT_PRIVATE TransportParameters {
-  // The identifier used to differentiate transport parameters.
-  enum TransportParameterId : uint64_t;
-  // A map used to specify custom parameters.
-  using ParameterMap = absl::flat_hash_map<TransportParameterId, std::string>;
-  // Represents an individual QUIC transport parameter that only encodes a
-  // variable length integer. Can only be created inside the constructor for
-  // TransportParameters.
-  class QUIC_EXPORT_PRIVATE IntegerParameter {
-   public:
-    // Forbid constructing and copying apart from TransportParameters.
-    IntegerParameter() = delete;
-    IntegerParameter& operator=(const IntegerParameter&) = delete;
-    // Sets the value of this transport parameter.
-    void set_value(uint64_t value);
-    // Gets the value of this transport parameter.
-    uint64_t value() const;
-    // Validates whether the current value is valid.
-    bool IsValid() const;
-    // Writes to a crypto byte buffer, used during serialization. Does not write
-    // anything if the value is equal to the parameter's default value.
-    // Returns whether the write was successful.
-    bool Write(QuicDataWriter* writer) const;
-    // Reads from a crypto byte string, used during parsing.
-    // Returns whether the read was successful.
-    // On failure, this method will write a human-readable error message to
-    // |error_details|.
-    bool Read(QuicDataReader* reader, std::string* error_details);
-    // operator<< allows easily logging integer transport parameters.
-    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-        std::ostream& os,
-        const IntegerParameter& param);
-
-   private:
-    friend struct TransportParameters;
-    // Constructors for initial setup used by TransportParameters only.
-    // This constructor sets |default_value| and |min_value| to 0, and
-    // |max_value| to kVarInt62MaxValue.
-    explicit IntegerParameter(TransportParameterId param_id);
-    IntegerParameter(TransportParameterId param_id,
-                     uint64_t default_value,
-                     uint64_t min_value,
-                     uint64_t max_value);
-    IntegerParameter(const IntegerParameter& other) = default;
-    IntegerParameter(IntegerParameter&& other) = default;
-    // Human-readable string representation.
-    std::string ToString(bool for_use_in_list) const;
-
-    // Number used to indicate this transport parameter.
-    TransportParameterId param_id_;
-    // Current value of the transport parameter.
-    uint64_t value_;
-    // Default value of this transport parameter, as per IETF specification.
-    const uint64_t default_value_;
-    // Minimum value of this transport parameter, as per IETF specification.
-    const uint64_t min_value_;
-    // Maximum value of this transport parameter, as per IETF specification.
-    const uint64_t max_value_;
-    // Ensures this parameter is not parsed twice in the same message.
-    bool has_been_read_;
-  };
-
-  // Represents the preferred_address transport parameter that a server can
-  // send to clients.
-  struct QUIC_EXPORT_PRIVATE PreferredAddress {
-    PreferredAddress();
-    PreferredAddress(const PreferredAddress& other) = default;
-    PreferredAddress(PreferredAddress&& other) = default;
-    ~PreferredAddress();
-    bool operator==(const PreferredAddress& rhs) const;
-    bool operator!=(const PreferredAddress& rhs) const;
-
-    QuicSocketAddress ipv4_socket_address;
-    QuicSocketAddress ipv6_socket_address;
-    QuicConnectionId connection_id;
-    std::vector<uint8_t> stateless_reset_token;
-
-    // Allows easily logging.
-    std::string ToString() const;
-    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-        std::ostream& os,
-        const TransportParameters& params);
-  };
-
-  // LegacyVersionInformation represents the Google QUIC downgrade prevention
-  // mechanism ported to QUIC+TLS. It is exchanged using transport parameter ID
-  // 0x4752 and will eventually be deprecated in favor of
-  // draft-ietf-quic-version-negotiation.
-  struct QUIC_EXPORT_PRIVATE LegacyVersionInformation {
-    LegacyVersionInformation();
-    LegacyVersionInformation(const LegacyVersionInformation& other) = default;
-    LegacyVersionInformation& operator=(const LegacyVersionInformation& other) =
-        default;
-    LegacyVersionInformation& operator=(LegacyVersionInformation&& other) =
-        default;
-    LegacyVersionInformation(LegacyVersionInformation&& other) = default;
-    ~LegacyVersionInformation() = default;
-    bool operator==(const LegacyVersionInformation& rhs) const;
-    bool operator!=(const LegacyVersionInformation& rhs) const;
-    // When sent by the client, |version| is the initial version offered by the
-    // client (before any version negotiation packets) for this connection. When
-    // sent by the server, |version| is the version that is in use.
-    QuicVersionLabel version;
-
-    // When sent by the server, |supported_versions| contains a list of all
-    // versions that the server would send in a version negotiation packet. When
-    // sent by the client, this is empty.
-    QuicVersionLabelVector supported_versions;
-
-    // Allows easily logging.
-    std::string ToString() const;
-    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-        std::ostream& os,
-        const LegacyVersionInformation& legacy_version_information);
-  };
-
-  // Version information used for version downgrade prevention and compatible
-  // version negotiation. See draft-ietf-quic-version-negotiation-05.
-  struct QUIC_EXPORT_PRIVATE VersionInformation {
-    VersionInformation();
-    VersionInformation(const VersionInformation& other) = default;
-    VersionInformation& operator=(const VersionInformation& other) = default;
-    VersionInformation& operator=(VersionInformation&& other) = default;
-    VersionInformation(VersionInformation&& other) = default;
-    ~VersionInformation() = default;
-    bool operator==(const VersionInformation& rhs) const;
-    bool operator!=(const VersionInformation& rhs) const;
-
-    // Version that the sender has chosen to use on this connection.
-    QuicVersionLabel chosen_version;
-
-    // When sent by the client, |other_versions| contains all the versions that
-    // this first flight is compatible with. When sent by the server,
-    // |other_versions| contains all of the versions supported by the server.
-    QuicVersionLabelVector other_versions;
-
-    // Allows easily logging.
-    std::string ToString() const;
-    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-        std::ostream& os, const VersionInformation& version_information);
-  };
-
-  TransportParameters();
-  TransportParameters(const TransportParameters& other);
-  ~TransportParameters();
-  bool operator==(const TransportParameters& rhs) const;
-  bool operator!=(const TransportParameters& rhs) const;
-
-  // Represents the sender of the transport parameters. When |perspective| is
-  // Perspective::IS_CLIENT, this struct is being used in the client_hello
-  // handshake message; when it is Perspective::IS_SERVER, it is being used in
-  // the encrypted_extensions handshake message.
-  Perspective perspective;
-
-  // Google QUIC downgrade prevention mechanism sent over QUIC+TLS.
-  absl::optional<LegacyVersionInformation> legacy_version_information;
-
-  // IETF downgrade prevention and compatible version negotiation, see
-  // draft-ietf-quic-version-negotiation.
-  absl::optional<VersionInformation> version_information;
-
-  // The value of the Destination Connection ID field from the first
-  // Initial packet sent by the client.
-  absl::optional<QuicConnectionId> original_destination_connection_id;
-
-  // Maximum idle timeout expressed in milliseconds.
-  IntegerParameter max_idle_timeout_ms;
-
-  // Stateless reset token used in verifying stateless resets.
-  std::vector<uint8_t> stateless_reset_token;
-
-  // Limits the size of packets that the endpoint is willing to receive.
-  // This indicates that packets larger than this limit will be dropped.
-  IntegerParameter max_udp_payload_size;
-
-  // Contains the initial value for the maximum amount of data that can
-  // be sent on the connection.
-  IntegerParameter initial_max_data;
-
-  // Initial flow control limit for locally-initiated bidirectional streams.
-  IntegerParameter initial_max_stream_data_bidi_local;
-
-  // Initial flow control limit for peer-initiated bidirectional streams.
-  IntegerParameter initial_max_stream_data_bidi_remote;
-
-  // Initial flow control limit for unidirectional streams.
-  IntegerParameter initial_max_stream_data_uni;
-
-  // Initial maximum number of bidirectional streams the peer may initiate.
-  IntegerParameter initial_max_streams_bidi;
-
-  // Initial maximum number of unidirectional streams the peer may initiate.
-  IntegerParameter initial_max_streams_uni;
-
-  // Exponent used to decode the ACK Delay field in ACK frames.
-  IntegerParameter ack_delay_exponent;
-
-  // Maximum amount of time in milliseconds by which the endpoint will
-  // delay sending acknowledgments.
-  IntegerParameter max_ack_delay;
-
-  // Minimum amount of time in microseconds by which the endpoint will
-  // delay sending acknowledgments. Used to enable sender control of ack delay.
-  IntegerParameter min_ack_delay_us;
-
-  // Indicates lack of support for connection migration.
-  bool disable_active_migration;
-
-  // Used to effect a change in server address at the end of the handshake.
-  std::unique_ptr<PreferredAddress> preferred_address;
-
-  // Maximum number of connection IDs from the peer that an endpoint is willing
-  // to store.
-  IntegerParameter active_connection_id_limit;
-
-  // The value that the endpoint included in the Source Connection ID field of
-  // the first Initial packet it sent.
-  absl::optional<QuicConnectionId> initial_source_connection_id;
-
-  // The value that the server included in the Source Connection ID field of a
-  // Retry packet it sent.
-  absl::optional<QuicConnectionId> retry_source_connection_id;
-
-  // Indicates support for the DATAGRAM frame and the maximum frame size that
-  // the sender accepts. See draft-ietf-quic-datagram.
-  IntegerParameter max_datagram_frame_size;
-
-  // Google-specific transport parameter that carries an estimate of the
-  // initial round-trip time in microseconds.
-  IntegerParameter initial_round_trip_time_us;
-
-  // Google-specific connection options.
-  absl::optional<QuicTagVector> google_connection_options;
-
-  // Validates whether transport parameters are valid according to
-  // the specification. If the transport parameters are not valid, this method
-  // will write a human-readable error message to |error_details|.
-  bool AreValid(std::string* error_details) const;
-
-  // Custom parameters that may be specific to application protocol.
-  ParameterMap custom_parameters;
-
-  // Allows easily logging transport parameters.
-  std::string ToString() const;
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const TransportParameters& params);
-};
-
-// Serializes a TransportParameters struct into the format for sending it in a
-// TLS extension. The serialized bytes are written to |*out|. Returns if the
-// parameters are valid and serialization succeeded.
-QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
-    ParsedQuicVersion version,
-    const TransportParameters& in,
-    std::vector<uint8_t>* out);
-
-// Parses bytes from the quic_transport_parameters TLS extension and writes the
-// parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
-// |perspective| indicates whether the input came from a client or a server.
-// This method returns true if the input was successfully parsed.
-// On failure, this method will write a human-readable error message to
-// |error_details|.
-QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
-                                                  Perspective perspective,
-                                                  const uint8_t* in,
-                                                  size_t in_len,
-                                                  TransportParameters* out,
-                                                  std::string* error_details);
-
-// Serializes |in| and |application_data| in a deterministic format so that
-// multiple calls to SerializeTransportParametersForTicket with the same inputs
-// will generate the same output, and if the inputs differ, then the output will
-// differ. The output of this function is used by the server in
-// SSL_set_quic_early_data_context to determine whether early data should be
-// accepted: Early data will only be accepted if the inputs to this function
-// match what they were on the connection that issued an early data capable
-// ticket.
-QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
-    const TransportParameters& in,
-    const std::vector<uint8_t>& application_data,
-    std::vector<uint8_t>* out);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
diff --git a/quic/core/crypto/transport_parameters_test.cc b/quic/core/crypto/transport_parameters_test.cc
deleted file mode 100644
index 0019774..0000000
--- a/quic/core/crypto/transport_parameters_test.cc
+++ /dev/null
@@ -1,1131 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/transport_parameters.h"
-
-#include <cstring>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const QuicVersionLabel kFakeVersionLabel = 0x01234567;
-const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
-const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
-const uint64_t kFakeInitialMaxData = 101;
-const uint64_t kFakeInitialMaxStreamDataBidiLocal = 2001;
-const uint64_t kFakeInitialMaxStreamDataBidiRemote = 2002;
-const uint64_t kFakeInitialMaxStreamDataUni = 3000;
-const uint64_t kFakeInitialMaxStreamsBidi = 21;
-const uint64_t kFakeInitialMaxStreamsUni = 22;
-const bool kFakeDisableMigration = true;
-const uint64_t kFakeInitialRoundTripTime = 53;
-const uint8_t kFakePreferredStatelessResetTokenData[16] = {
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
-
-const auto kCustomParameter1 =
-    static_cast<TransportParameters::TransportParameterId>(0xffcd);
-const char* kCustomParameter1Value = "foo";
-const auto kCustomParameter2 =
-    static_cast<TransportParameters::TransportParameterId>(0xff34);
-const char* kCustomParameter2Value = "bar";
-
-QuicConnectionId CreateFakeOriginalDestinationConnectionId() {
-  return TestConnectionId(0x1337);
-}
-
-QuicConnectionId CreateFakeInitialSourceConnectionId() {
-  return TestConnectionId(0x2345);
-}
-
-QuicConnectionId CreateFakeRetrySourceConnectionId() {
-  return TestConnectionId(0x9876);
-}
-
-QuicConnectionId CreateFakePreferredConnectionId() {
-  return TestConnectionId(0xBEEF);
-}
-
-std::vector<uint8_t> CreateFakePreferredStatelessResetToken() {
-  return std::vector<uint8_t>(
-      kFakePreferredStatelessResetTokenData,
-      kFakePreferredStatelessResetTokenData +
-          sizeof(kFakePreferredStatelessResetTokenData));
-}
-
-QuicSocketAddress CreateFakeV4SocketAddress() {
-  QuicIpAddress ipv4_address;
-  if (!ipv4_address.FromString("65.66.67.68")) {  // 0x41, 0x42, 0x43, 0x44
-    QUIC_LOG(FATAL) << "Failed to create IPv4 address";
-    return QuicSocketAddress();
-  }
-  return QuicSocketAddress(ipv4_address, 0x4884);
-}
-
-QuicSocketAddress CreateFakeV6SocketAddress() {
-  QuicIpAddress ipv6_address;
-  if (!ipv6_address.FromString("6061:6263:6465:6667:6869:6A6B:6C6D:6E6F")) {
-    QUIC_LOG(FATAL) << "Failed to create IPv6 address";
-    return QuicSocketAddress();
-  }
-  return QuicSocketAddress(ipv6_address, 0x6336);
-}
-
-std::unique_ptr<TransportParameters::PreferredAddress>
-CreateFakePreferredAddress() {
-  TransportParameters::PreferredAddress preferred_address;
-  preferred_address.ipv4_socket_address = CreateFakeV4SocketAddress();
-  preferred_address.ipv6_socket_address = CreateFakeV6SocketAddress();
-  preferred_address.connection_id = CreateFakePreferredConnectionId();
-  preferred_address.stateless_reset_token =
-      CreateFakePreferredStatelessResetToken();
-  return std::make_unique<TransportParameters::PreferredAddress>(
-      preferred_address);
-}
-
-TransportParameters::LegacyVersionInformation
-CreateFakeLegacyVersionInformationClient() {
-  TransportParameters::LegacyVersionInformation legacy_version_information;
-  legacy_version_information.version = kFakeVersionLabel;
-  return legacy_version_information;
-}
-
-TransportParameters::LegacyVersionInformation
-CreateFakeLegacyVersionInformationServer() {
-  TransportParameters::LegacyVersionInformation legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
-  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
-  return legacy_version_information;
-}
-
-TransportParameters::VersionInformation CreateFakeVersionInformation() {
-  TransportParameters::VersionInformation version_information;
-  version_information.chosen_version = kFakeVersionLabel;
-  version_information.other_versions.push_back(kFakeVersionLabel);
-  version_information.other_versions.push_back(kFakeVersionLabel2);
-  return version_information;
-}
-
-QuicTagVector CreateFakeGoogleConnectionOptions() {
-  return {kALPN, MakeQuicTag('E', 'F', 'G', 0x00),
-          MakeQuicTag('H', 'I', 'J', 0xff)};
-}
-
-void RemoveGreaseParameters(TransportParameters* params) {
-  std::vector<TransportParameters::TransportParameterId> grease_params;
-  for (const auto& kv : params->custom_parameters) {
-    if (kv.first % 31 == 27) {
-      grease_params.push_back(kv.first);
-    }
-  }
-  EXPECT_EQ(grease_params.size(), 1u);
-  for (TransportParameters::TransportParameterId param_id : grease_params) {
-    params->custom_parameters.erase(param_id);
-  }
-  // Remove all GREASE versions from version_information.other_versions.
-  if (params->version_information.has_value()) {
-    QuicVersionLabelVector& other_versions =
-        params->version_information.value().other_versions;
-    for (auto it = other_versions.begin(); it != other_versions.end();) {
-      if ((*it & 0x0f0f0f0f) == 0x0a0a0a0a) {
-        it = other_versions.erase(it);
-      } else {
-        ++it;
-      }
-    }
-  }
-}
-
-}  // namespace
-
-class TransportParametersTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  TransportParametersTest() : version_(GetParam()) {}
-
-  ParsedQuicVersion version_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TransportParametersTests,
-                         TransportParametersTest,
-                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(TransportParametersTest, Comparator) {
-  TransportParameters orig_params;
-  TransportParameters new_params;
-  // Test comparison on primitive members.
-  orig_params.perspective = Perspective::IS_CLIENT;
-  new_params.perspective = Perspective::IS_SERVER;
-  EXPECT_NE(orig_params, new_params);
-  EXPECT_FALSE(orig_params == new_params);
-  EXPECT_TRUE(orig_params != new_params);
-  new_params.perspective = Perspective::IS_CLIENT;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  new_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  orig_params.version_information = CreateFakeVersionInformation();
-  new_params.version_information = CreateFakeVersionInformation();
-  orig_params.disable_active_migration = true;
-  new_params.disable_active_migration = true;
-  EXPECT_EQ(orig_params, new_params);
-  EXPECT_TRUE(orig_params == new_params);
-  EXPECT_FALSE(orig_params != new_params);
-
-  // Test comparison on vectors.
-  orig_params.legacy_version_information.value().supported_versions.push_back(
-      kFakeVersionLabel);
-  new_params.legacy_version_information.value().supported_versions.push_back(
-      kFakeVersionLabel2);
-  EXPECT_NE(orig_params, new_params);
-  EXPECT_FALSE(orig_params == new_params);
-  EXPECT_TRUE(orig_params != new_params);
-  new_params.legacy_version_information.value().supported_versions.pop_back();
-  new_params.legacy_version_information.value().supported_versions.push_back(
-      kFakeVersionLabel);
-  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
-  new_params.stateless_reset_token = CreateStatelessResetTokenForTest();
-  EXPECT_EQ(orig_params, new_params);
-  EXPECT_TRUE(orig_params == new_params);
-  EXPECT_FALSE(orig_params != new_params);
-
-  // Test comparison on IntegerParameters.
-  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest + 1);
-  EXPECT_NE(orig_params, new_params);
-  EXPECT_FALSE(orig_params == new_params);
-  EXPECT_TRUE(orig_params != new_params);
-  new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  EXPECT_EQ(orig_params, new_params);
-  EXPECT_TRUE(orig_params == new_params);
-  EXPECT_FALSE(orig_params != new_params);
-
-  // Test comparison on PreferredAddress
-  orig_params.preferred_address = CreateFakePreferredAddress();
-  EXPECT_NE(orig_params, new_params);
-  EXPECT_FALSE(orig_params == new_params);
-  EXPECT_TRUE(orig_params != new_params);
-  new_params.preferred_address = CreateFakePreferredAddress();
-  EXPECT_EQ(orig_params, new_params);
-  EXPECT_TRUE(orig_params == new_params);
-  EXPECT_FALSE(orig_params != new_params);
-
-  // Test comparison on CustomMap
-  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
-  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
-  new_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-  new_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
-  EXPECT_EQ(orig_params, new_params);
-  EXPECT_TRUE(orig_params == new_params);
-  EXPECT_FALSE(orig_params != new_params);
-
-  // Test comparison on connection IDs.
-  orig_params.initial_source_connection_id =
-      CreateFakeInitialSourceConnectionId();
-  new_params.initial_source_connection_id = absl::nullopt;
-  EXPECT_NE(orig_params, new_params);
-  EXPECT_FALSE(orig_params == new_params);
-  EXPECT_TRUE(orig_params != new_params);
-  new_params.initial_source_connection_id = TestConnectionId(0xbadbad);
-  EXPECT_NE(orig_params, new_params);
-  EXPECT_FALSE(orig_params == new_params);
-  EXPECT_TRUE(orig_params != new_params);
-  new_params.initial_source_connection_id =
-      CreateFakeInitialSourceConnectionId();
-  EXPECT_EQ(orig_params, new_params);
-  EXPECT_TRUE(orig_params == new_params);
-  EXPECT_FALSE(orig_params != new_params);
-}
-
-TEST_P(TransportParametersTest, CopyConstructor) {
-  TransportParameters orig_params;
-  orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  orig_params.version_information = CreateFakeVersionInformation();
-  orig_params.original_destination_connection_id =
-      CreateFakeOriginalDestinationConnectionId();
-  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
-  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
-  orig_params.initial_max_stream_data_bidi_local.set_value(
-      kFakeInitialMaxStreamDataBidiLocal);
-  orig_params.initial_max_stream_data_bidi_remote.set_value(
-      kFakeInitialMaxStreamDataBidiRemote);
-  orig_params.initial_max_stream_data_uni.set_value(
-      kFakeInitialMaxStreamDataUni);
-  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
-  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
-  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
-  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
-  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
-  orig_params.disable_active_migration = kFakeDisableMigration;
-  orig_params.preferred_address = CreateFakePreferredAddress();
-  orig_params.active_connection_id_limit.set_value(
-      kActiveConnectionIdLimitForTest);
-  orig_params.initial_source_connection_id =
-      CreateFakeInitialSourceConnectionId();
-  orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
-  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
-  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
-  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
-  TransportParameters new_params(orig_params);
-  EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, RoundTripClient) {
-  TransportParameters orig_params;
-  orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  orig_params.version_information = CreateFakeVersionInformation();
-  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
-  orig_params.initial_max_stream_data_bidi_local.set_value(
-      kFakeInitialMaxStreamDataBidiLocal);
-  orig_params.initial_max_stream_data_bidi_remote.set_value(
-      kFakeInitialMaxStreamDataBidiRemote);
-  orig_params.initial_max_stream_data_uni.set_value(
-      kFakeInitialMaxStreamDataUni);
-  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
-  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
-  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
-  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
-  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
-  orig_params.disable_active_migration = kFakeDisableMigration;
-  orig_params.active_connection_id_limit.set_value(
-      kActiveConnectionIdLimitForTest);
-  orig_params.initial_source_connection_id =
-      CreateFakeInitialSourceConnectionId();
-  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
-  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
-  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
-
-  TransportParameters new_params;
-  std::string error_details;
-  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
-                                       serialized.data(), serialized.size(),
-                                       &new_params, &error_details))
-      << error_details;
-  EXPECT_TRUE(error_details.empty());
-  RemoveGreaseParameters(&new_params);
-  EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, RoundTripServer) {
-  TransportParameters orig_params;
-  orig_params.perspective = Perspective::IS_SERVER;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationServer();
-  orig_params.version_information = CreateFakeVersionInformation();
-  orig_params.original_destination_connection_id =
-      CreateFakeOriginalDestinationConnectionId();
-  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
-  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
-  orig_params.initial_max_stream_data_bidi_local.set_value(
-      kFakeInitialMaxStreamDataBidiLocal);
-  orig_params.initial_max_stream_data_bidi_remote.set_value(
-      kFakeInitialMaxStreamDataBidiRemote);
-  orig_params.initial_max_stream_data_uni.set_value(
-      kFakeInitialMaxStreamDataUni);
-  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
-  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
-  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
-  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
-  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
-  orig_params.disable_active_migration = kFakeDisableMigration;
-  orig_params.preferred_address = CreateFakePreferredAddress();
-  orig_params.active_connection_id_limit.set_value(
-      kActiveConnectionIdLimitForTest);
-  orig_params.initial_source_connection_id =
-      CreateFakeInitialSourceConnectionId();
-  orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
-  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
-
-  TransportParameters new_params;
-  std::string error_details;
-  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
-                                       serialized.data(), serialized.size(),
-                                       &new_params, &error_details))
-      << error_details;
-  EXPECT_TRUE(error_details.empty());
-  RemoveGreaseParameters(&new_params);
-  EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, AreValid) {
-  {
-    TransportParameters params;
-    std::string error_details;
-    params.perspective = Perspective::IS_CLIENT;
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-  }
-  {
-    TransportParameters params;
-    std::string error_details;
-    params.perspective = Perspective::IS_CLIENT;
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.max_idle_timeout_ms.set_value(601000);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-  }
-  {
-    TransportParameters params;
-    std::string error_details;
-    params.perspective = Perspective::IS_CLIENT;
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.max_udp_payload_size.set_value(1200);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.max_udp_payload_size.set_value(65535);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.max_udp_payload_size.set_value(9999999);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.max_udp_payload_size.set_value(0);
-    error_details = "";
-    EXPECT_FALSE(params.AreValid(&error_details));
-    EXPECT_EQ(error_details,
-              "Invalid transport parameters [Client max_udp_payload_size 0 "
-              "(Invalid)]");
-    params.max_udp_payload_size.set_value(1199);
-    error_details = "";
-    EXPECT_FALSE(params.AreValid(&error_details));
-    EXPECT_EQ(error_details,
-              "Invalid transport parameters [Client max_udp_payload_size 1199 "
-              "(Invalid)]");
-  }
-  {
-    TransportParameters params;
-    std::string error_details;
-    params.perspective = Perspective::IS_CLIENT;
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.ack_delay_exponent.set_value(0);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.ack_delay_exponent.set_value(20);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.ack_delay_exponent.set_value(21);
-    EXPECT_FALSE(params.AreValid(&error_details));
-    EXPECT_EQ(error_details,
-              "Invalid transport parameters [Client ack_delay_exponent 21 "
-              "(Invalid)]");
-  }
-  {
-    TransportParameters params;
-    std::string error_details;
-    params.perspective = Perspective::IS_CLIENT;
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.active_connection_id_limit.set_value(2);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.active_connection_id_limit.set_value(999999);
-    EXPECT_TRUE(params.AreValid(&error_details));
-    EXPECT_TRUE(error_details.empty());
-    params.active_connection_id_limit.set_value(1);
-    EXPECT_FALSE(params.AreValid(&error_details));
-    EXPECT_EQ(error_details,
-              "Invalid transport parameters [Client active_connection_id_limit"
-              " 1 (Invalid)]");
-    params.active_connection_id_limit.set_value(0);
-    EXPECT_FALSE(params.AreValid(&error_details));
-    EXPECT_EQ(error_details,
-              "Invalid transport parameters [Client active_connection_id_limit"
-              " 0 (Invalid)]");
-  }
-}
-
-TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
-  TransportParameters orig_params;
-  orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
-  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-
-  std::vector<uint8_t> out;
-  bool ok = true;
-  EXPECT_QUIC_BUG(
-      ok = SerializeTransportParameters(version_, orig_params, &out),
-      "Not serializing invalid transport parameters: Client cannot send "
-      "stateless reset token");
-  EXPECT_FALSE(ok);
-}
-
-TEST_P(TransportParametersTest, ParseClientParams) {
-  // clang-format off
-  const uint8_t kClientParams[] = {
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // max_udp_payload_size
-      0x03,  // parameter id
-      0x02,  // length
-      0x63, 0x29,  // value
-      // initial_max_data
-      0x04,  // parameter id
-      0x02,  // length
-      0x40, 0x65,  // value
-      // initial_max_stream_data_bidi_local
-      0x05,  // parameter id
-      0x02,  // length
-      0x47, 0xD1,  // value
-      // initial_max_stream_data_bidi_remote
-      0x06,  // parameter id
-      0x02,  // length
-      0x47, 0xD2,  // value
-      // initial_max_stream_data_uni
-      0x07,  // parameter id
-      0x02,  // length
-      0x4B, 0xB8,  // value
-      // initial_max_streams_bidi
-      0x08,  // parameter id
-      0x01,  // length
-      0x15,  // value
-      // initial_max_streams_uni
-      0x09,  // parameter id
-      0x01,  // length
-      0x16,  // value
-      // ack_delay_exponent
-      0x0a,  // parameter id
-      0x01,  // length
-      0x0a,  // value
-      // max_ack_delay
-      0x0b,  // parameter id
-      0x01,  // length
-      0x33,  // value
-      // min_ack_delay_us
-      0x80, 0x00, 0xde, 0x1a,  // parameter id
-      0x02,  // length
-      0x43, 0xe8,  // value
-      // disable_active_migration
-      0x0c,  // parameter id
-      0x00,  // length
-      // active_connection_id_limit
-      0x0e,  // parameter id
-      0x01,  // length
-      0x34,  // value
-      // initial_source_connection_id
-      0x0f,  // parameter id
-      0x08,  // length
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
-      // initial_round_trip_time_us
-      0x71, 0x27,  // parameter id
-      0x01,  // length
-      0x35,  // value
-      // google_connection_options
-      0x71, 0x28,  // parameter id
-      0x0c,  // length
-      'A', 'L', 'P', 'N',  // value
-      'E', 'F', 'G', 0x00,
-      'H', 'I', 'J', 0xff,
-      // Google version extension
-      0x80, 0x00, 0x47, 0x52,  // parameter id
-      0x04,  // length
-      0x01, 0x23, 0x45, 0x67,  // initial version
-      // version_information
-      0x80, 0xFF, 0x73, 0xDB,  // parameter id
-      0x0C,  // length
-      0x01, 0x23, 0x45, 0x67,  // chosen version
-      0x01, 0x23, 0x45, 0x67,  // other version 1
-      0x89, 0xab, 0xcd, 0xef,  // other version 2
-  };
-  // clang-format on
-  const uint8_t* client_params =
-      reinterpret_cast<const uint8_t*>(kClientParams);
-  size_t client_params_length = ABSL_ARRAYSIZE(kClientParams);
-  TransportParameters new_params;
-  std::string error_details;
-  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
-                                       client_params, client_params_length,
-                                       &new_params, &error_details))
-      << error_details;
-  EXPECT_TRUE(error_details.empty());
-  EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
-  ASSERT_TRUE(new_params.legacy_version_information.has_value());
-  EXPECT_EQ(kFakeVersionLabel,
-            new_params.legacy_version_information.value().version);
-  EXPECT_TRUE(
-      new_params.legacy_version_information.value().supported_versions.empty());
-  ASSERT_TRUE(new_params.version_information.has_value());
-  EXPECT_EQ(new_params.version_information.value(),
-            CreateFakeVersionInformation());
-  EXPECT_FALSE(new_params.original_destination_connection_id.has_value());
-  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
-            new_params.max_idle_timeout_ms.value());
-  EXPECT_TRUE(new_params.stateless_reset_token.empty());
-  EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
-  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
-  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
-            new_params.initial_max_stream_data_bidi_local.value());
-  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
-            new_params.initial_max_stream_data_bidi_remote.value());
-  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
-            new_params.initial_max_stream_data_uni.value());
-  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
-            new_params.initial_max_streams_bidi.value());
-  EXPECT_EQ(kFakeInitialMaxStreamsUni,
-            new_params.initial_max_streams_uni.value());
-  EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
-  EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
-  EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
-  EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
-  EXPECT_EQ(kActiveConnectionIdLimitForTest,
-            new_params.active_connection_id_limit.value());
-  ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
-  EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
-            new_params.initial_source_connection_id.value());
-  EXPECT_FALSE(new_params.retry_source_connection_id.has_value());
-  EXPECT_EQ(kFakeInitialRoundTripTime,
-            new_params.initial_round_trip_time_us.value());
-  ASSERT_TRUE(new_params.google_connection_options.has_value());
-  EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
-            new_params.google_connection_options.value());
-}
-
-TEST_P(TransportParametersTest,
-       ParseClientParamsFailsWithFullStatelessResetToken) {
-  // clang-format off
-  const uint8_t kClientParamsWithFullToken[] = {
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // stateless_reset_token
-      0x02,  // parameter id
-      0x10,  // length
-      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
-      // max_udp_payload_size
-      0x03,  // parameter id
-      0x02,  // length
-      0x63, 0x29,  // value
-      // initial_max_data
-      0x04,  // parameter id
-      0x02,  // length
-      0x40, 0x65,  // value
-  };
-  // clang-format on
-  const uint8_t* client_params =
-      reinterpret_cast<const uint8_t*>(kClientParamsWithFullToken);
-  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithFullToken);
-  TransportParameters out_params;
-  std::string error_details;
-  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
-                                        client_params, client_params_length,
-                                        &out_params, &error_details));
-  EXPECT_EQ(error_details, "Client cannot send stateless reset token");
-}
-
-TEST_P(TransportParametersTest,
-       ParseClientParamsFailsWithEmptyStatelessResetToken) {
-  // clang-format off
-  const uint8_t kClientParamsWithEmptyToken[] = {
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // stateless_reset_token
-      0x02,  // parameter id
-      0x00,  // length
-      // max_udp_payload_size
-      0x03,  // parameter id
-      0x02,  // length
-      0x63, 0x29,  // value
-      // initial_max_data
-      0x04,  // parameter id
-      0x02,  // length
-      0x40, 0x65,  // value
-  };
-  // clang-format on
-  const uint8_t* client_params =
-      reinterpret_cast<const uint8_t*>(kClientParamsWithEmptyToken);
-  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithEmptyToken);
-  TransportParameters out_params;
-  std::string error_details;
-  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
-                                        client_params, client_params_length,
-                                        &out_params, &error_details));
-  EXPECT_EQ(error_details,
-            "Received stateless_reset_token of invalid length 0");
-}
-
-TEST_P(TransportParametersTest, ParseClientParametersRepeated) {
-  // clang-format off
-  const uint8_t kClientParamsRepeated[] = {
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // max_udp_payload_size
-      0x03,  // parameter id
-      0x02,  // length
-      0x63, 0x29,  // value
-      // max_idle_timeout (repeated)
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-  };
-  // clang-format on
-  const uint8_t* client_params =
-      reinterpret_cast<const uint8_t*>(kClientParamsRepeated);
-  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsRepeated);
-  TransportParameters out_params;
-  std::string error_details;
-  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
-                                        client_params, client_params_length,
-                                        &out_params, &error_details));
-  EXPECT_EQ(error_details, "Received a second max_idle_timeout");
-}
-
-TEST_P(TransportParametersTest, ParseServerParams) {
-  // clang-format off
-  const uint8_t kServerParams[] = {
-      // original_destination_connection_id
-      0x00,  // parameter id
-      0x08,  // length
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // stateless_reset_token
-      0x02,  // parameter id
-      0x10,  // length
-      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
-      // max_udp_payload_size
-      0x03,  // parameter id
-      0x02,  // length
-      0x63, 0x29,  // value
-      // initial_max_data
-      0x04,  // parameter id
-      0x02,  // length
-      0x40, 0x65,  // value
-      // initial_max_stream_data_bidi_local
-      0x05,  // parameter id
-      0x02,  // length
-      0x47, 0xD1,  // value
-      // initial_max_stream_data_bidi_remote
-      0x06,  // parameter id
-      0x02,  // length
-      0x47, 0xD2,  // value
-      // initial_max_stream_data_uni
-      0x07,  // parameter id
-      0x02,  // length
-      0x4B, 0xB8,  // value
-      // initial_max_streams_bidi
-      0x08,  // parameter id
-      0x01,  // length
-      0x15,  // value
-      // initial_max_streams_uni
-      0x09,  // parameter id
-      0x01,  // length
-      0x16,  // value
-      // ack_delay_exponent
-      0x0a,  // parameter id
-      0x01,  // length
-      0x0a,  // value
-      // max_ack_delay
-      0x0b,  // parameter id
-      0x01,  // length
-      0x33,  // value
-      // min_ack_delay_us
-      0x80, 0x00, 0xde, 0x1a,  // parameter id
-      0x02,  // length
-      0x43, 0xe8,  // value
-      // disable_active_migration
-      0x0c,  // parameter id
-      0x00,  // length
-      // preferred_address
-      0x0d,  // parameter id
-      0x31,  // length
-      0x41, 0x42, 0x43, 0x44,  // IPv4 address
-      0x48, 0x84,  // IPv4 port
-      0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  // IPv6 address
-      0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
-      0x63, 0x36,  // IPv6 port
-      0x08,        // connection ID length
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF,  // connection ID
-      0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // stateless reset token
-      0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
-      // active_connection_id_limit
-      0x0e,  // parameter id
-      0x01,  // length
-      0x34,  // value
-      // initial_source_connection_id
-      0x0f,  // parameter id
-      0x08,  // length
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
-      // retry_source_connection_id
-      0x10,  // parameter id
-      0x08,  // length
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x76,
-      // google_connection_options
-      0x71, 0x28,  // parameter id
-      0x0c,  // length
-      'A', 'L', 'P', 'N',  // value
-      'E', 'F', 'G', 0x00,
-      'H', 'I', 'J', 0xff,
-      // Google version extension
-      0x80, 0x00, 0x47, 0x52,  // parameter id
-      0x0d,  // length
-      0x01, 0x23, 0x45, 0x67,  // negotiated_version
-      0x08,  // length of supported versions array
-      0x01, 0x23, 0x45, 0x67,
-      0x89, 0xab, 0xcd, 0xef,
-      // version_information
-      0x80, 0xFF, 0x73, 0xDB,  // parameter id
-      0x0C,  // length
-      0x01, 0x23, 0x45, 0x67,  // chosen version
-      0x01, 0x23, 0x45, 0x67,  // other version 1
-      0x89, 0xab, 0xcd, 0xef,  // other version 2
-  };
-  // clang-format on
-  const uint8_t* server_params =
-      reinterpret_cast<const uint8_t*>(kServerParams);
-  size_t server_params_length = ABSL_ARRAYSIZE(kServerParams);
-  TransportParameters new_params;
-  std::string error_details;
-  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
-                                       server_params, server_params_length,
-                                       &new_params, &error_details))
-      << error_details;
-  EXPECT_TRUE(error_details.empty());
-  EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
-  ASSERT_TRUE(new_params.legacy_version_information.has_value());
-  EXPECT_EQ(kFakeVersionLabel,
-            new_params.legacy_version_information.value().version);
-  ASSERT_EQ(
-      2u,
-      new_params.legacy_version_information.value().supported_versions.size());
-  EXPECT_EQ(
-      kFakeVersionLabel,
-      new_params.legacy_version_information.value().supported_versions[0]);
-  EXPECT_EQ(
-      kFakeVersionLabel2,
-      new_params.legacy_version_information.value().supported_versions[1]);
-  ASSERT_TRUE(new_params.version_information.has_value());
-  EXPECT_EQ(new_params.version_information.value(),
-            CreateFakeVersionInformation());
-  ASSERT_TRUE(new_params.original_destination_connection_id.has_value());
-  EXPECT_EQ(CreateFakeOriginalDestinationConnectionId(),
-            new_params.original_destination_connection_id.value());
-  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
-            new_params.max_idle_timeout_ms.value());
-  EXPECT_EQ(CreateStatelessResetTokenForTest(),
-            new_params.stateless_reset_token);
-  EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
-  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
-  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
-            new_params.initial_max_stream_data_bidi_local.value());
-  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
-            new_params.initial_max_stream_data_bidi_remote.value());
-  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
-            new_params.initial_max_stream_data_uni.value());
-  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
-            new_params.initial_max_streams_bidi.value());
-  EXPECT_EQ(kFakeInitialMaxStreamsUni,
-            new_params.initial_max_streams_uni.value());
-  EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
-  EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
-  EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
-  EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
-  ASSERT_NE(nullptr, new_params.preferred_address.get());
-  EXPECT_EQ(CreateFakeV4SocketAddress(),
-            new_params.preferred_address->ipv4_socket_address);
-  EXPECT_EQ(CreateFakeV6SocketAddress(),
-            new_params.preferred_address->ipv6_socket_address);
-  EXPECT_EQ(CreateFakePreferredConnectionId(),
-            new_params.preferred_address->connection_id);
-  EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
-            new_params.preferred_address->stateless_reset_token);
-  EXPECT_EQ(kActiveConnectionIdLimitForTest,
-            new_params.active_connection_id_limit.value());
-  ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
-  EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
-            new_params.initial_source_connection_id.value());
-  ASSERT_TRUE(new_params.retry_source_connection_id.has_value());
-  EXPECT_EQ(CreateFakeRetrySourceConnectionId(),
-            new_params.retry_source_connection_id.value());
-  ASSERT_TRUE(new_params.google_connection_options.has_value());
-  EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
-            new_params.google_connection_options.value());
-}
-
-TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
-  // clang-format off
-  const uint8_t kServerParamsRepeated[] = {
-      // original_destination_connection_id
-      0x00,  // parameter id
-      0x08,  // length
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // stateless_reset_token
-      0x02,  // parameter id
-      0x10,  // length
-      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-      0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-      // max_idle_timeout (repeated)
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-  };
-  // clang-format on
-  const uint8_t* server_params =
-      reinterpret_cast<const uint8_t*>(kServerParamsRepeated);
-  size_t server_params_length = ABSL_ARRAYSIZE(kServerParamsRepeated);
-  TransportParameters out_params;
-  std::string error_details;
-  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_SERVER,
-                                        server_params, server_params_length,
-                                        &out_params, &error_details));
-  EXPECT_EQ(error_details, "Received a second max_idle_timeout");
-}
-
-TEST_P(TransportParametersTest,
-       ParseServerParametersEmptyOriginalConnectionId) {
-  // clang-format off
-  const uint8_t kServerParamsEmptyOriginalConnectionId[] = {
-      // original_destination_connection_id
-      0x00,  // parameter id
-      0x00,  // length
-      // max_idle_timeout
-      0x01,  // parameter id
-      0x02,  // length
-      0x6e, 0xec,  // value
-      // stateless_reset_token
-      0x02,  // parameter id
-      0x10,  // length
-      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-      0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
-  };
-  // clang-format on
-  const uint8_t* server_params =
-      reinterpret_cast<const uint8_t*>(kServerParamsEmptyOriginalConnectionId);
-  size_t server_params_length =
-      ABSL_ARRAYSIZE(kServerParamsEmptyOriginalConnectionId);
-  TransportParameters out_params;
-  std::string error_details;
-  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
-                                       server_params, server_params_length,
-                                       &out_params, &error_details))
-      << error_details;
-  ASSERT_TRUE(out_params.original_destination_connection_id.has_value());
-  EXPECT_EQ(out_params.original_destination_connection_id.value(),
-            EmptyQuicConnectionId());
-}
-
-TEST_P(TransportParametersTest, VeryLongCustomParameter) {
-  // Ensure we can handle a 70KB custom parameter on both send and receive.
-  std::string custom_value(70000, '?');
-  TransportParameters orig_params;
-  orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  orig_params.custom_parameters[kCustomParameter1] = custom_value;
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
-
-  TransportParameters new_params;
-  std::string error_details;
-  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
-                                       serialized.data(), serialized.size(),
-                                       &new_params, &error_details))
-      << error_details;
-  EXPECT_TRUE(error_details.empty());
-  RemoveGreaseParameters(&new_params);
-  EXPECT_EQ(new_params, orig_params);
-}
-
-TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
-  TransportParameters orig_params;
-  orig_params.perspective = Perspective::IS_CLIENT;
-  orig_params.legacy_version_information =
-      CreateFakeLegacyVersionInformationClient();
-  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
-  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
-  orig_params.initial_max_stream_data_bidi_local.set_value(
-      kFakeInitialMaxStreamDataBidiLocal);
-  orig_params.initial_max_stream_data_bidi_remote.set_value(
-      kFakeInitialMaxStreamDataBidiRemote);
-  orig_params.initial_max_stream_data_uni.set_value(
-      kFakeInitialMaxStreamDataUni);
-  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
-  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
-  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
-  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
-  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
-  orig_params.disable_active_migration = kFakeDisableMigration;
-  orig_params.active_connection_id_limit.set_value(
-      kActiveConnectionIdLimitForTest);
-  orig_params.initial_source_connection_id =
-      CreateFakeInitialSourceConnectionId();
-  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
-  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
-  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
-  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
-
-  std::vector<uint8_t> first_serialized;
-  ASSERT_TRUE(
-      SerializeTransportParameters(version_, orig_params, &first_serialized));
-  // Test that a subsequent serialization is different from the first.
-  // Run in a loop to avoid a failure in the unlikely event that randomization
-  // produces the same result multiple times.
-  for (int i = 0; i < 1000; i++) {
-    std::vector<uint8_t> serialized;
-    ASSERT_TRUE(
-        SerializeTransportParameters(version_, orig_params, &serialized));
-    if (serialized != first_serialized) {
-      return;
-    }
-  }
-}
-
-class TransportParametersTicketSerializationTest : public QuicTest {
- protected:
-  void SetUp() override {
-    original_params_.perspective = Perspective::IS_SERVER;
-    original_params_.legacy_version_information =
-        CreateFakeLegacyVersionInformationServer();
-    original_params_.original_destination_connection_id =
-        CreateFakeOriginalDestinationConnectionId();
-    original_params_.max_idle_timeout_ms.set_value(
-        kFakeIdleTimeoutMilliseconds);
-    original_params_.stateless_reset_token = CreateStatelessResetTokenForTest();
-    original_params_.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-    original_params_.initial_max_data.set_value(kFakeInitialMaxData);
-    original_params_.initial_max_stream_data_bidi_local.set_value(
-        kFakeInitialMaxStreamDataBidiLocal);
-    original_params_.initial_max_stream_data_bidi_remote.set_value(
-        kFakeInitialMaxStreamDataBidiRemote);
-    original_params_.initial_max_stream_data_uni.set_value(
-        kFakeInitialMaxStreamDataUni);
-    original_params_.initial_max_streams_bidi.set_value(
-        kFakeInitialMaxStreamsBidi);
-    original_params_.initial_max_streams_uni.set_value(
-        kFakeInitialMaxStreamsUni);
-    original_params_.ack_delay_exponent.set_value(kAckDelayExponentForTest);
-    original_params_.max_ack_delay.set_value(kMaxAckDelayForTest);
-    original_params_.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
-    original_params_.disable_active_migration = kFakeDisableMigration;
-    original_params_.preferred_address = CreateFakePreferredAddress();
-    original_params_.active_connection_id_limit.set_value(
-        kActiveConnectionIdLimitForTest);
-    original_params_.initial_source_connection_id =
-        CreateFakeInitialSourceConnectionId();
-    original_params_.retry_source_connection_id =
-        CreateFakeRetrySourceConnectionId();
-    original_params_.google_connection_options =
-        CreateFakeGoogleConnectionOptions();
-
-    ASSERT_TRUE(SerializeTransportParametersForTicket(
-        original_params_, application_state_, &original_serialized_params_));
-  }
-
-  TransportParameters original_params_;
-  std::vector<uint8_t> application_state_ = {0, 1};
-  std::vector<uint8_t> original_serialized_params_;
-};
-
-TEST_F(TransportParametersTicketSerializationTest,
-       StatelessResetTokenDoesntChangeOutput) {
-  // Test that changing the stateless reset token doesn't change the ticket
-  // serialization.
-  TransportParameters new_params = original_params_;
-  new_params.stateless_reset_token = CreateFakePreferredStatelessResetToken();
-  EXPECT_NE(new_params, original_params_);
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParametersForTicket(
-      new_params, application_state_, &serialized));
-  EXPECT_EQ(original_serialized_params_, serialized);
-}
-
-TEST_F(TransportParametersTicketSerializationTest,
-       ConnectionIDDoesntChangeOutput) {
-  // Changing original destination CID doesn't change serialization.
-  TransportParameters new_params = original_params_;
-  new_params.original_destination_connection_id = TestConnectionId(0xCAFE);
-  EXPECT_NE(new_params, original_params_);
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParametersForTicket(
-      new_params, application_state_, &serialized));
-  EXPECT_EQ(original_serialized_params_, serialized);
-}
-
-TEST_F(TransportParametersTicketSerializationTest, StreamLimitChangesOutput) {
-  // Changing a stream limit does change the serialization.
-  TransportParameters new_params = original_params_;
-  new_params.initial_max_stream_data_bidi_local.set_value(
-      kFakeInitialMaxStreamDataBidiLocal + 1);
-  EXPECT_NE(new_params, original_params_);
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParametersForTicket(
-      new_params, application_state_, &serialized));
-  EXPECT_NE(original_serialized_params_, serialized);
-}
-
-TEST_F(TransportParametersTicketSerializationTest,
-       ApplicationStateChangesOutput) {
-  // Changing the application state changes the serialization.
-  std::vector<uint8_t> new_application_state = {0};
-  EXPECT_NE(new_application_state, application_state_);
-
-  std::vector<uint8_t> serialized;
-  ASSERT_TRUE(SerializeTransportParametersForTicket(
-      original_params_, new_application_state, &serialized));
-  EXPECT_NE(original_serialized_params_, serialized);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc b/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc
deleted file mode 100644
index 7b294da..0000000
--- a/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
-
-#include <cstdint>
-#include <memory>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_replace.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-constexpr size_t kFingerprintLength = SHA256_DIGEST_LENGTH * 3 - 1;
-
-// Assumes that the character is normalized to lowercase beforehand.
-bool IsNormalizedHexDigit(char c) {
-  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
-}
-
-void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
-  fingerprint.fingerprint =
-      quiche::QuicheTextUtils::ToLower(fingerprint.fingerprint);
-}
-
-}  // namespace
-
-constexpr char CertificateFingerprint::kSha256[];
-constexpr char WebTransportHash::kSha256[];
-
-ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
-    const {
-  return new Details(*this);
-}
-
-WebTransportFingerprintProofVerifier::WebTransportFingerprintProofVerifier(
-    const QuicClock* clock, int max_validity_days)
-    : clock_(clock),
-      max_validity_days_(max_validity_days),
-      // Add an extra second to max validity to accomodate various edge cases.
-      max_validity_(
-          QuicTime::Delta::FromSeconds(max_validity_days * 86400 + 1)) {}
-
-bool WebTransportFingerprintProofVerifier::AddFingerprint(
-    CertificateFingerprint fingerprint) {
-  NormalizeFingerprint(fingerprint);
-  if (fingerprint.algorithm != CertificateFingerprint::kSha256) {
-    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
-    return false;
-  }
-  if (fingerprint.fingerprint.size() != kFingerprintLength) {
-    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
-    return false;
-  }
-  for (size_t i = 0; i < fingerprint.fingerprint.size(); i++) {
-    char current = fingerprint.fingerprint[i];
-    if (i % 3 == 2) {
-      if (current != ':') {
-        QUIC_DLOG(WARNING)
-            << "Missing colon separator between the bytes of the hash";
-        return false;
-      }
-    } else {
-      if (!IsNormalizedHexDigit(current)) {
-        QUIC_DLOG(WARNING) << "Fingerprint must be in hexadecimal";
-        return false;
-      }
-    }
-  }
-
-  std::string normalized =
-      absl::StrReplaceAll(fingerprint.fingerprint, {{":", ""}});
-  hashes_.push_back(WebTransportHash{fingerprint.algorithm,
-                                     absl::HexStringToBytes(normalized)});
-  return true;
-}
-
-bool WebTransportFingerprintProofVerifier::AddFingerprint(
-    WebTransportHash hash) {
-  if (hash.algorithm != CertificateFingerprint::kSha256) {
-    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
-    return false;
-  }
-  if (hash.value.size() != SHA256_DIGEST_LENGTH) {
-    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
-    return false;
-  }
-  hashes_.push_back(std::move(hash));
-  return true;
-}
-
-QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyProof(
-    const std::string& /*hostname*/, const uint16_t /*port*/,
-    const std::string& /*server_config*/,
-    QuicTransportVersion /*transport_version*/, absl::string_view /*chlo_hash*/,
-    const std::vector<std::string>& /*certs*/, const std::string& /*cert_sct*/,
-    const std::string& /*signature*/, const ProofVerifyContext* /*context*/,
-    std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
-    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
-  *error_details =
-      "QUIC crypto certificate verification is not supported in "
-      "WebTransportFingerprintProofVerifier";
-  QUIC_BUG(quic_bug_10879_1) << *error_details;
-  *details = std::make_unique<Details>(Status::kInternalError);
-  return QUIC_FAILURE;
-}
-
-QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
-    const std::string& /*hostname*/, const uint16_t /*port*/,
-    const std::vector<std::string>& certs, const std::string& /*ocsp_response*/,
-    const std::string& /*cert_sct*/, const ProofVerifyContext* /*context*/,
-    std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
-    uint8_t* /*out_alert*/,
-    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
-  if (certs.empty()) {
-    *details = std::make_unique<Details>(Status::kInternalError);
-    *error_details = "No certificates provided";
-    return QUIC_FAILURE;
-  }
-
-  if (!HasKnownFingerprint(certs[0])) {
-    *details = std::make_unique<Details>(Status::kUnknownFingerprint);
-    *error_details = "Certificate does not match any fingerprint";
-    return QUIC_FAILURE;
-  }
-
-  std::unique_ptr<CertificateView> view =
-      CertificateView::ParseSingleCertificate(certs[0]);
-  if (view == nullptr) {
-    *details = std::make_unique<Details>(Status::kCertificateParseFailure);
-    *error_details = "Failed to parse the certificate";
-    return QUIC_FAILURE;
-  }
-
-  if (!HasValidExpiry(*view)) {
-    *details = std::make_unique<Details>(Status::kExpiryTooLong);
-    *error_details =
-        absl::StrCat("Certificate expiry exceeds the configured limit of ",
-                     max_validity_days_, " days");
-    return QUIC_FAILURE;
-  }
-
-  if (!IsWithinValidityPeriod(*view)) {
-    *details = std::make_unique<Details>(Status::kExpired);
-    *error_details =
-        "Certificate has expired or has validity listed in the future";
-    return QUIC_FAILURE;
-  }
-
-  if (!IsKeyTypeAllowedByPolicy(*view)) {
-    *details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm);
-    *error_details =
-        absl::StrCat("Certificate uses a disallowed public key type (",
-                     PublicKeyTypeToString(view->public_key_type()), ")");
-    return QUIC_FAILURE;
-  }
-
-  *details = std::make_unique<Details>(Status::kValidCertificate);
-  return QUIC_SUCCESS;
-}
-
-std::unique_ptr<ProofVerifyContext>
-WebTransportFingerprintProofVerifier::CreateDefaultContext() {
-  return nullptr;
-}
-
-bool WebTransportFingerprintProofVerifier::HasKnownFingerprint(
-    absl::string_view der_certificate) {
-  // https://w3c.github.io/webtransport/#verify-a-certificate-hash
-  const std::string hash = RawSha256(der_certificate);
-  for (const WebTransportHash& reference : hashes_) {
-    if (reference.algorithm != WebTransportHash::kSha256) {
-      QUIC_BUG(quic_bug_10879_2) << "Unexpected non-SHA-256 hash";
-      continue;
-    }
-    if (hash == reference.value) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool WebTransportFingerprintProofVerifier::HasValidExpiry(
-    const CertificateView& certificate) {
-  if (!certificate.validity_start().IsBefore(certificate.validity_end())) {
-    return false;
-  }
-
-  const QuicTime::Delta duration_seconds =
-      certificate.validity_end() - certificate.validity_start();
-  return duration_seconds <= max_validity_;
-}
-
-bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
-    const CertificateView& certificate) {
-  QuicWallTime now = clock_->WallNow();
-  return now.IsAfter(certificate.validity_start()) &&
-         now.IsBefore(certificate.validity_end());
-}
-
-bool WebTransportFingerprintProofVerifier::IsKeyTypeAllowedByPolicy(
-    const CertificateView& certificate) {
-  switch (certificate.public_key_type()) {
-    // https://github.com/w3c/webtransport/pull/375 defines P-256 as an MTI
-    // algorithm, and prohibits RSA.  We also allow P-384 and Ed25519.
-    case PublicKeyType::kP256:
-    case PublicKeyType::kP384:
-    case PublicKeyType::kEd25519:
-      return true;
-    case PublicKeyType::kRsa:
-      // TODO(b/213614428): this should be false by default.
-      return true;
-    default:
-      return false;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/crypto/web_transport_fingerprint_proof_verifier.h b/quic/core/crypto/web_transport_fingerprint_proof_verifier.h
deleted file mode 100644
index 9a03c66..0000000
--- a/quic/core/crypto/web_transport_fingerprint_proof_verifier.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/certificate_view.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/quic_clock.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Represents a fingerprint of an X.509 certificate in a format based on
-// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
-// TODO(vasilvv): remove this once all consumers of this API use
-// WebTransportHash.
-struct QUIC_EXPORT_PRIVATE CertificateFingerprint {
-  static constexpr char kSha256[] = "sha-256";
-
-  // An algorithm described by one of the names in
-  // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
-  std::string algorithm;
-  // Hex-encoded, colon-separated fingerprint of the certificate.  For example,
-  // "12:3d:5b:71:8c:54:df:85:7e:bd:e3:7c:66:da:f9:db:6a:94:8f:85:cb:6e:44:7f:09:3e:05:f2:dd:d4:f7:86"
-  std::string fingerprint;
-};
-
-// Represents a fingerprint of an X.509 certificate in a format based on
-// https://w3c.github.io/webtransport/#dictdef-webtransporthash.
-struct QUIC_EXPORT_PRIVATE WebTransportHash {
-  static constexpr char kSha256[] = "sha-256";
-
-  // An algorithm described by one of the names in
-  // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
-  std::string algorithm;
-  // Raw bytes of the hash.
-  std::string value;
-};
-
-// WebTransportFingerprintProofVerifier verifies the server leaf certificate
-// against a supplied list of certificate fingerprints following the procedure
-// described in the WebTransport specification.  The certificate is deemed
-// trusted if it matches a fingerprint in the list, has expiry dates that are
-// not too long and has not expired.  Only the leaf is checked, the rest of the
-// chain is ignored. Reference specification:
-// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
-class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
-    : public ProofVerifier {
- public:
-  // Note: the entries in this list may be logged into a UMA histogram, and thus
-  // should not be renumbered.
-  enum class Status {
-    kValidCertificate = 0,
-    kUnknownFingerprint = 1,
-    kCertificateParseFailure = 2,
-    kExpiryTooLong = 3,
-    kExpired = 4,
-    kInternalError = 5,
-    kDisallowedKeyAlgorithm = 6,
-
-    kMaxValue = kDisallowedKeyAlgorithm,
-  };
-
-  class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
-   public:
-    explicit Details(Status status) : status_(status) {}
-    Status status() const { return status_; }
-
-    ProofVerifyDetails* Clone() const override;
-
-   private:
-    const Status status_;
-  };
-
-  // |clock| is used to check if the certificate has expired.  It is not owned
-  // and must outlive the object.  |max_validity_days| is the maximum time for
-  // which the certificate is allowed to be valid.
-  WebTransportFingerprintProofVerifier(const QuicClock* clock,
-                                       int max_validity_days);
-
-  // Adds a certificate fingerprint to be trusted.  The fingerprints are
-  // case-insensitive and are validated internally; the function returns true if
-  // the validation passes.
-  bool AddFingerprint(CertificateFingerprint fingerprint);
-  bool AddFingerprint(WebTransportHash hash);
-
-  // ProofVerifier implementation.
-  QuicAsyncStatus VerifyProof(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::string& server_config,
-      QuicTransportVersion transport_version,
-      absl::string_view chlo_hash,
-      const std::vector<std::string>& certs,
-      const std::string& cert_sct,
-      const std::string& signature,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      std::unique_ptr<ProofVerifierCallback> callback) override;
-  QuicAsyncStatus VerifyCertChain(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::vector<std::string>& certs,
-      const std::string& ocsp_response,
-      const std::string& cert_sct,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) override;
-  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
-
- protected:
-  virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate);
-
- private:
-  bool HasKnownFingerprint(absl::string_view der_certificate);
-  bool HasValidExpiry(const CertificateView& certificate);
-  bool IsWithinValidityPeriod(const CertificateView& certificate);
-
-  const QuicClock* clock_;  // Unowned.
-  const int max_validity_days_;
-  const QuicTime::Delta max_validity_;
-  std::vector<WebTransportHash> hashes_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
diff --git a/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc b/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc
deleted file mode 100644
index 1a39f05..0000000
--- a/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
-
-#include <memory>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::HasSubstr;
-
-// 2020-02-01 12:35:56 UTC
-constexpr QuicTime::Delta kValidTime = QuicTime::Delta::FromSeconds(1580560556);
-
-struct VerifyResult {
-  QuicAsyncStatus status;
-  WebTransportFingerprintProofVerifier::Status detailed_status;
-  std::string error;
-};
-
-class WebTransportFingerprintProofVerifierTest : public QuicTest {
- public:
-  WebTransportFingerprintProofVerifierTest() {
-    clock_.AdvanceTime(kValidTime);
-    verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
-        &clock_, /*max_validity_days=*/365);
-    AddTestCertificate();
-  }
-
- protected:
-  VerifyResult Verify(absl::string_view certificate) {
-    VerifyResult result;
-    std::unique_ptr<ProofVerifyDetails> details;
-    uint8_t tls_alert;
-    result.status = verifier_->VerifyCertChain(
-        /*hostname=*/"", /*port=*/0,
-        std::vector<std::string>{std::string(certificate)},
-        /*ocsp_response=*/"",
-        /*cert_sct=*/"",
-        /*context=*/nullptr, &result.error, &details, &tls_alert,
-        /*callback=*/nullptr);
-    result.detailed_status =
-        static_cast<WebTransportFingerprintProofVerifier::Details*>(
-            details.get())
-            ->status();
-    return result;
-  }
-
-  void AddTestCertificate() {
-    EXPECT_TRUE(verifier_->AddFingerprint(WebTransportHash{
-        WebTransportHash::kSha256, RawSha256(kTestCertificate)}));
-  }
-
-  MockClock clock_;
-  std::unique_ptr<WebTransportFingerprintProofVerifier> verifier_;
-};
-
-TEST_F(WebTransportFingerprintProofVerifierTest, Sha256Fingerprint) {
-  // Computed using `openssl x509 -fingerprint -sha256`.
-  EXPECT_EQ(absl::BytesToHexString(RawSha256(kTestCertificate)),
-            "f2e5465e2bf7ecd6f63066a5a37511734aa0eb7c4701"
-            "0e86d6758ed4f4fa1b0f");
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, SimpleFingerprint) {
-  VerifyResult result = Verify(kTestCertificate);
-  EXPECT_EQ(result.status, QUIC_SUCCESS);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-
-  result = Verify(kWildcardCertificate);
-  EXPECT_EQ(result.status, QUIC_FAILURE);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kUnknownFingerprint);
-
-  result = Verify("Some random text");
-  EXPECT_EQ(result.status, QUIC_FAILURE);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, Validity) {
-  // Validity periods of kTestCertificate, according to `openssl x509 -text`:
-  //     Not Before: Jan 30 18:13:59 2020 GMT
-  //     Not After : Feb  2 18:13:59 2020 GMT
-
-  // 2020-01-29 19:00:00 UTC
-  constexpr QuicTime::Delta kStartTime =
-      QuicTime::Delta::FromSeconds(1580324400);
-  clock_.Reset();
-  clock_.AdvanceTime(kStartTime);
-
-  VerifyResult result = Verify(kTestCertificate);
-  EXPECT_EQ(result.status, QUIC_FAILURE);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kExpired);
-
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400));
-  result = Verify(kTestCertificate);
-  EXPECT_EQ(result.status, QUIC_SUCCESS);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(4 * 86400));
-  result = Verify(kTestCertificate);
-  EXPECT_EQ(result.status, QUIC_FAILURE);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kExpired);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, MaxValidity) {
-  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
-      &clock_, /*max_validity_days=*/2);
-  AddTestCertificate();
-  VerifyResult result = Verify(kTestCertificate);
-  EXPECT_EQ(result.status, QUIC_FAILURE);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kExpiryTooLong);
-  EXPECT_THAT(result.error, HasSubstr("limit of 2 days"));
-
-  // kTestCertificate is valid for exactly four days.
-  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
-      &clock_, /*max_validity_days=*/4);
-  AddTestCertificate();
-  result = Verify(kTestCertificate);
-  EXPECT_EQ(result.status, QUIC_SUCCESS);
-  EXPECT_EQ(result.detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) {
-  constexpr absl::string_view kInvalidCertificate = "Hello, world!";
-  ASSERT_TRUE(verifier_->AddFingerprint(WebTransportHash{
-      WebTransportHash::kSha256, RawSha256(kInvalidCertificate)}));
-
-  VerifyResult result = Verify(kInvalidCertificate);
-  EXPECT_EQ(result.status, QUIC_FAILURE);
-  EXPECT_EQ(
-      result.detailed_status,
-      WebTransportFingerprintProofVerifier::Status::kCertificateParseFailure);
-}
-
-TEST_F(WebTransportFingerprintProofVerifierTest, AddCertificate) {
-  // Accept all-uppercase fingerprints.
-  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
-      &clock_, /*max_validity_days=*/365);
-  EXPECT_TRUE(verifier_->AddFingerprint(CertificateFingerprint{
-      CertificateFingerprint::kSha256,
-      "F2:E5:46:5E:2B:F7:EC:D6:F6:30:66:A5:A3:75:11:73:4A:A0:EB:"
-      "7C:47:01:0E:86:D6:75:8E:D4:F4:FA:1B:0F"}));
-  EXPECT_EQ(Verify(kTestCertificate).detailed_status,
-            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
-
-  // Reject unknown hash algorithms.
-  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
-      "sha-1", "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"}));
-  // Reject invalid length.
-  EXPECT_FALSE(verifier_->AddFingerprint(
-      CertificateFingerprint{CertificateFingerprint::kSha256, "00:00:00:00"}));
-  // Reject missing colons.
-  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
-      CertificateFingerprint::kSha256,
-      "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00."
-      "00.00.00.00.00.00.00.00.00.00.00.00.00"}));
-  // Reject non-hex symbols.
-  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
-      CertificateFingerprint::kSha256,
-      "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:"
-      "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz"}));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/frames/quic_ack_frame.cc b/quic/core/frames/quic_ack_frame.cc
deleted file mode 100644
index 724833e..0000000
--- a/quic/core/frames/quic_ack_frame.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ack_frame.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-
-const QuicPacketCount kMaxPrintRange = 128;
-
-}  // namespace
-
-bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
-                      QuicPacketNumber packet_number,
-                      QuicPacketNumber peer_least_packet_awaiting_ack) {
-  QUICHE_DCHECK(packet_number.IsInitialized());
-  return (!peer_least_packet_awaiting_ack.IsInitialized() ||
-          packet_number >= peer_least_packet_awaiting_ack) &&
-         !ack_frame.packets.Contains(packet_number);
-}
-
-QuicAckFrame::QuicAckFrame() = default;
-
-QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
-
-QuicAckFrame::~QuicAckFrame() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) {
-  os << "{ largest_acked: " << LargestAcked(ack_frame)
-     << ", ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds()
-     << ", packets: [ " << ack_frame.packets << " ]"
-     << ", received_packets: [ ";
-  for (const std::pair<QuicPacketNumber, QuicTime>& p :
-       ack_frame.received_packet_times) {
-    os << p.first << " at " << p.second.ToDebuggingValue() << " ";
-  }
-  os << " ]";
-  os << ", ecn_counters_populated: " << ack_frame.ecn_counters_populated;
-  if (ack_frame.ecn_counters_populated) {
-    os << ", ect_0_count: " << ack_frame.ect_0_count
-       << ", ect_1_count: " << ack_frame.ect_1_count
-       << ", ecn_ce_count: " << ack_frame.ecn_ce_count;
-  }
-
-  os << " }\n";
-  return os;
-}
-
-void QuicAckFrame::Clear() {
-  largest_acked.Clear();
-  ack_delay_time = QuicTime::Delta::Infinite();
-  received_packet_times.clear();
-  packets.Clear();
-}
-
-PacketNumberQueue::PacketNumberQueue() {}
-PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
-PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
-PacketNumberQueue::~PacketNumberQueue() {}
-
-PacketNumberQueue& PacketNumberQueue::operator=(
-    const PacketNumberQueue& other) = default;
-PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) =
-    default;
-
-void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
-  if (!packet_number.IsInitialized()) {
-    return;
-  }
-  packet_number_intervals_.AddOptimizedForAppend(packet_number,
-                                                 packet_number + 1);
-}
-
-void PacketNumberQueue::AddRange(QuicPacketNumber lower,
-                                 QuicPacketNumber higher) {
-  if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) {
-    return;
-  }
-
-  packet_number_intervals_.AddOptimizedForAppend(lower, higher);
-}
-
-bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
-  if (!higher.IsInitialized() || Empty()) {
-    return false;
-  }
-  return packet_number_intervals_.TrimLessThan(higher);
-}
-
-void PacketNumberQueue::RemoveSmallestInterval() {
-  // TODO(wub): Move this QUIC_BUG to upper level.
-  QUIC_BUG_IF(quic_bug_12614_1, packet_number_intervals_.Size() < 2)
-      << (Empty() ? "No intervals to remove."
-                  : "Can't remove the last interval.");
-  packet_number_intervals_.PopFront();
-}
-
-void PacketNumberQueue::Clear() {
-  packet_number_intervals_.Clear();
-}
-
-bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
-  if (!packet_number.IsInitialized()) {
-    return false;
-  }
-  return packet_number_intervals_.Contains(packet_number);
-}
-
-bool PacketNumberQueue::Empty() const {
-  return packet_number_intervals_.Empty();
-}
-
-QuicPacketNumber PacketNumberQueue::Min() const {
-  QUICHE_DCHECK(!Empty());
-  return packet_number_intervals_.begin()->min();
-}
-
-QuicPacketNumber PacketNumberQueue::Max() const {
-  QUICHE_DCHECK(!Empty());
-  return packet_number_intervals_.rbegin()->max() - 1;
-}
-
-QuicPacketCount PacketNumberQueue::NumPacketsSlow() const {
-  QuicPacketCount n_packets = 0;
-  for (const auto& interval : packet_number_intervals_) {
-    n_packets += interval.Length();
-  }
-  return n_packets;
-}
-
-size_t PacketNumberQueue::NumIntervals() const {
-  return packet_number_intervals_.Size();
-}
-
-PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
-  return packet_number_intervals_.begin();
-}
-
-PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
-  return packet_number_intervals_.end();
-}
-
-PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const {
-  return packet_number_intervals_.rbegin();
-}
-
-PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const {
-  return packet_number_intervals_.rend();
-}
-
-QuicPacketCount PacketNumberQueue::LastIntervalLength() const {
-  QUICHE_DCHECK(!Empty());
-  return packet_number_intervals_.rbegin()->Length();
-}
-
-// Largest min...max range for packet numbers where we print the numbers
-// explicitly. If bigger than this, we print as a range  [a,d] rather
-// than [a b c d]
-
-std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) {
-  for (const QuicInterval<QuicPacketNumber>& interval : q) {
-    // Print as a range if there is a pathological condition.
-    if ((interval.min() >= interval.max()) ||
-        (interval.max() - interval.min() > kMaxPrintRange)) {
-      // If min>max, it's really a bug, so QUIC_BUG it to
-      // catch it in development.
-      QUIC_BUG_IF(quic_bug_12614_2, interval.min() >= interval.max())
-          << "Ack Range minimum (" << interval.min() << "Not less than max ("
-          << interval.max() << ")";
-      // print range as min...max rather than full list.
-      // in the event of a bug, the list could be very big.
-      os << interval.min() << "..." << (interval.max() - 1) << " ";
-    } else {
-      for (QuicPacketNumber packet_number = interval.min();
-           packet_number < interval.max(); ++packet_number) {
-        os << packet_number << " ";
-      }
-    }
-  }
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_ack_frame.h b/quic/core/frames/quic_ack_frame.h
deleted file mode 100644
index c9c46d4..0000000
--- a/quic/core/frames/quic_ack_frame.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-// A sequence of packet numbers where each number is unique. Intended to be used
-// in a sliding window fashion, where smaller old packet numbers are removed and
-// larger new packet numbers are added, with the occasional random access.
-class QUIC_EXPORT_PRIVATE PacketNumberQueue {
- public:
-  PacketNumberQueue();
-  PacketNumberQueue(const PacketNumberQueue& other);
-  PacketNumberQueue(PacketNumberQueue&& other);
-  ~PacketNumberQueue();
-
-  PacketNumberQueue& operator=(const PacketNumberQueue& other);
-  PacketNumberQueue& operator=(PacketNumberQueue&& other);
-
-  using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator;
-  using const_reverse_iterator =
-      QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator;
-
-  // Adds |packet_number| to the set of packets in the queue.
-  void Add(QuicPacketNumber packet_number);
-
-  // Adds packets between [lower, higher) to the set of packets in the queue.
-  // No-op if |higher| < |lower|.
-  // NOTE(wub): Only used in tests as of Nov 2019.
-  void AddRange(QuicPacketNumber lower, QuicPacketNumber higher);
-
-  // Removes packets with values less than |higher| from the set of packets in
-  // the queue. Returns true if packets were removed.
-  bool RemoveUpTo(QuicPacketNumber higher);
-
-  // Removes the smallest interval in the queue.
-  void RemoveSmallestInterval();
-
-  // Clear this packet number queue.
-  void Clear();
-
-  // Returns true if the queue contains |packet_number|.
-  bool Contains(QuicPacketNumber packet_number) const;
-
-  // Returns true if the queue is empty.
-  bool Empty() const;
-
-  // Returns the minimum packet number stored in the queue. It is undefined
-  // behavior to call this if the queue is empty.
-  QuicPacketNumber Min() const;
-
-  // Returns the maximum packet number stored in the queue. It is undefined
-  // behavior to call this if the queue is empty.
-  QuicPacketNumber Max() const;
-
-  // Returns the number of unique packets stored in the queue. Inefficient; only
-  // exposed for testing.
-  QuicPacketCount NumPacketsSlow() const;
-
-  // Returns the number of disjoint packet number intervals contained in the
-  // queue.
-  size_t NumIntervals() const;
-
-  // Returns the length of last interval.
-  QuicPacketCount LastIntervalLength() const;
-
-  // Returns iterators over the packet number intervals.
-  const_iterator begin() const;
-  const_iterator end() const;
-  const_reverse_iterator rbegin() const;
-  const_reverse_iterator rend() const;
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const PacketNumberQueue& q);
-
- private:
-  QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicAckFrame {
-  QuicAckFrame();
-  QuicAckFrame(const QuicAckFrame& other);
-  ~QuicAckFrame();
-
-  void Clear();
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicAckFrame& ack_frame);
-
-  // The highest packet number we've observed from the peer. When |packets| is
-  // not empty, it should always be equal to packets.Max(). The |LargestAcked|
-  // function ensures this invariant in debug mode.
-  QuicPacketNumber largest_acked;
-
-  // Time elapsed since largest_observed() was received until this Ack frame was
-  // sent.
-  QuicTime::Delta ack_delay_time = QuicTime::Delta::Infinite();
-
-  // Vector of <packet_number, time> for when packets arrived.
-  // For IETF versions, packet numbers and timestamps in this vector are both in
-  // ascending orders. Packets received out of order are not saved here.
-  PacketTimeVector received_packet_times;
-
-  // Set of packets.
-  PacketNumberQueue packets;
-
-  // ECN counters, used only in version 99's ACK frame and valid only when
-  // |ecn_counters_populated| is true.
-  bool ecn_counters_populated = false;
-  QuicPacketCount ect_0_count = 0;
-  QuicPacketCount ect_1_count = 0;
-  QuicPacketCount ecn_ce_count = 0;
-};
-
-// The highest acked packet number we've observed from the peer. If no packets
-// have been observed, return 0.
-inline QUIC_EXPORT_PRIVATE QuicPacketNumber
-LargestAcked(const QuicAckFrame& frame) {
-  QUICHE_DCHECK(frame.packets.Empty() ||
-                frame.packets.Max() == frame.largest_acked);
-  return frame.largest_acked;
-}
-
-// True if the packet number is greater than largest_observed or is listed
-// as missing.
-// Always returns false for packet numbers less than least_unacked.
-QUIC_EXPORT_PRIVATE bool IsAwaitingPacket(
-    const QuicAckFrame& ack_frame,
-    QuicPacketNumber packet_number,
-    QuicPacketNumber peer_least_packet_awaiting_ack);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
diff --git a/quic/core/frames/quic_ack_frequency_frame.cc b/quic/core/frames/quic_ack_frequency_frame.cc
deleted file mode 100644
index 4bbfa17..0000000
--- a/quic/core/frames/quic_ack_frequency_frame.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include <cstdint>
-#include <limits>
-
-namespace quic {
-
-QuicAckFrequencyFrame::QuicAckFrequencyFrame(
-    QuicControlFrameId control_frame_id,
-    uint64_t sequence_number,
-    uint64_t packet_tolerance,
-    QuicTime::Delta max_ack_delay)
-    : control_frame_id(control_frame_id),
-      sequence_number(sequence_number),
-      packet_tolerance(packet_tolerance),
-      max_ack_delay(max_ack_delay) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicAckFrequencyFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id
-     << ", sequence_number: " << frame.sequence_number
-     << ", packet_tolerance: " << frame.packet_tolerance
-     << ", max_ack_delay_ms: " << frame.max_ack_delay.ToMilliseconds()
-     << ", ignore_order: " << frame.ignore_order << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_ack_frequency_frame.h b/quic/core/frames/quic_ack_frequency_frame.h
deleted file mode 100644
index 68e08e4..0000000
--- a/quic/core/frames/quic_ack_frequency_frame.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
-
-#include <cstdint>
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A frame that allows sender control of acknowledgement delays.
-struct QUIC_EXPORT_PRIVATE QuicAckFrequencyFrame {
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicAckFrequencyFrame& ack_frequency_frame);
-
-  QuicAckFrequencyFrame() = default;
-  QuicAckFrequencyFrame(QuicControlFrameId control_frame_id,
-                        uint64_t sequence_number,
-                        uint64_t packet_tolerance,
-                        QuicTime::Delta max_ack_delay);
-
-  // A unique identifier of this control frame. 0 when this frame is
-  // received, and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  // If true, do not ack immediately upon observeation of packet reordering.
-  bool ignore_order = false;
-
-  // Sequence number assigned to the ACK_FREQUENCY frame by the sender to allow
-  // receivers to ignore obsolete frames.
-  uint64_t sequence_number = 0;
-
-  // The maximum number of ack-eliciting packets after which the receiver sends
-  // an acknowledgement. Invald if == 0.
-  uint64_t packet_tolerance = 2;
-
-  // The maximum time that ack packets can be delayed.
-  QuicTime::Delta max_ack_delay =
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
diff --git a/quic/core/frames/quic_blocked_frame.cc b/quic/core/frames/quic_blocked_frame.cc
deleted file mode 100644
index 7d71637..0000000
--- a/quic/core/frames/quic_blocked_frame.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_blocked_frame.h"
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-QuicBlockedFrame::QuicBlockedFrame() : QuicInlinedFrame(BLOCKED_FRAME) {}
-
-QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
-                                   QuicStreamId stream_id)
-    : QuicInlinedFrame(BLOCKED_FRAME),
-      control_frame_id(control_frame_id),
-      stream_id(stream_id),
-      offset(0) {}
-
-QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
-                                   QuicStreamId stream_id,
-                                   QuicStreamOffset offset)
-    : QuicInlinedFrame(BLOCKED_FRAME),
-      control_frame_id(control_frame_id),
-      stream_id(stream_id),
-      offset(offset) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicBlockedFrame& blocked_frame) {
-  os << "{ control_frame_id: " << blocked_frame.control_frame_id
-     << ", stream_id: " << blocked_frame.stream_id << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_blocked_frame.h b/quic/core/frames/quic_blocked_frame.h
deleted file mode 100644
index 63d1c96..0000000
--- a/quic/core/frames/quic_blocked_frame.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// The BLOCKED frame is used to indicate to the remote endpoint that this
-// endpoint believes itself to be flow-control blocked but otherwise ready to
-// send data. The BLOCKED frame is purely advisory and optional.
-// Based on SPDY's BLOCKED frame (undocumented as of 2014-01-28).
-struct QUIC_EXPORT_PRIVATE QuicBlockedFrame
-    : public QuicInlinedFrame<QuicBlockedFrame> {
-  QuicBlockedFrame();
-  QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id);
-  QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id,
-                   QuicStreamOffset offset);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicBlockedFrame& b);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  // 0 is a special case meaning the connection is blocked, rather than a
-  // stream.  So stream_id 0 corresponds to a BLOCKED frame and non-0
-  // corresponds to a STREAM_BLOCKED.
-  // TODO(fkastenholz): This should be converted to use
-  // QuicUtils::GetInvalidStreamId to get the correct invalid stream id value
-  // and not rely on 0.
-  QuicStreamId stream_id = 0;
-
-  // For Google QUIC, the offset is ignored.
-  QuicStreamOffset offset = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
diff --git a/quic/core/frames/quic_connection_close_frame.cc b/quic/core/frames/quic_connection_close_frame.cc
deleted file mode 100644
index e17c3e7..0000000
--- a/quic/core/frames/quic_connection_close_frame.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_connection_close_frame.h"
-
-#include <memory>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-QuicConnectionCloseFrame::QuicConnectionCloseFrame(
-    QuicTransportVersion transport_version,
-    QuicErrorCode error_code,
-    QuicIetfTransportErrorCodes ietf_error,
-    std::string error_phrase,
-    uint64_t frame_type)
-    : quic_error_code(error_code), error_details(error_phrase) {
-  if (!VersionHasIetfQuicFrames(transport_version)) {
-    close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
-    wire_error_code = error_code;
-    transport_close_frame_type = 0;
-    return;
-  }
-  QuicErrorCodeToIetfMapping mapping =
-      QuicErrorCodeToTransportErrorCode(error_code);
-  if (ietf_error != NO_IETF_QUIC_ERROR) {
-    wire_error_code = ietf_error;
-  } else {
-    wire_error_code = mapping.error_code;
-  }
-  if (mapping.is_transport_close) {
-    // Maps to a transport close
-    close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
-    transport_close_frame_type = frame_type;
-    return;
-  }
-  // Maps to an application close.
-  close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
-  transport_close_frame_type = 0;
-}
-
-std::ostream& operator<<(
-    std::ostream& os,
-    const QuicConnectionCloseFrame& connection_close_frame) {
-  os << "{ Close type: " << connection_close_frame.close_type;
-  switch (connection_close_frame.close_type) {
-    case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
-      os << ", wire_error_code: "
-         << static_cast<QuicIetfTransportErrorCodes>(
-                connection_close_frame.wire_error_code);
-      break;
-    case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
-      os << ", wire_error_code: " << connection_close_frame.wire_error_code;
-      break;
-    case GOOGLE_QUIC_CONNECTION_CLOSE:
-      // Do not log, value same as |quic_error_code|.
-      break;
-  }
-  os << ", quic_error_code: "
-     << QuicErrorCodeToString(connection_close_frame.quic_error_code)
-     << ", error_details: '" << connection_close_frame.error_details << "'";
-  if (connection_close_frame.close_type ==
-      IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
-    os << ", frame_type: "
-       << static_cast<QuicIetfFrameType>(
-              connection_close_frame.transport_close_frame_type);
-  }
-  os << "}\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_connection_close_frame.h b/quic/core/frames/quic_connection_close_frame.h
deleted file mode 100644
index 66a90ad..0000000
--- a/quic/core/frames/quic_connection_close_frame.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
-
-#include <ostream>
-#include <string>
-
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame {
-  QuicConnectionCloseFrame() = default;
-
-  // Builds a connection close frame based on the transport version
-  // and the mapping of error_code. THIS IS THE PREFERRED C'TOR
-  // TO USE IF YOU NEED TO CREATE A CONNECTION-CLOSE-FRAME AND
-  // HAVE IT BE CORRECT FOR THE VERSION AND CODE MAPPINGS.
-  // |ietf_error| may optionally be be used to directly specify the wire
-  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
-  // QuicErrorCodeToTransportErrorCode mapping of |error_code| will be used.
-  QuicConnectionCloseFrame(QuicTransportVersion transport_version,
-                           QuicErrorCode error_code,
-                           QuicIetfTransportErrorCodes ietf_error,
-                           std::string error_phrase,
-                           uint64_t transport_close_frame_type);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicConnectionCloseFrame& c);
-
-  // Indicates whether the the frame is a Google QUIC CONNECTION_CLOSE frame,
-  // an IETF QUIC CONNECTION_CLOSE frame with transport error code,
-  // or an IETF QUIC CONNECTION_CLOSE frame with application error code.
-  QuicConnectionCloseType close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
-
-  // The error code on the wire.  For Google QUIC frames, this has the same
-  // value as |quic_error_code|.
-  uint64_t wire_error_code = QUIC_NO_ERROR;
-
-  // The underlying error.  For Google QUIC frames, this has the same value as
-  // |wire_error_code|.  For sent IETF QUIC frames, this is the error that
-  // triggered the closure of the connection.  For received IETF QUIC frames,
-  // this is parsed from the Reason Phrase field of the CONNECTION_CLOSE frame,
-  // or QUIC_IETF_GQUIC_ERROR_MISSING.
-  QuicErrorCode quic_error_code = QUIC_NO_ERROR;
-
-  // String with additional error details. |quic_error_code| and a colon will be
-  // prepended to the error details when sending IETF QUIC frames, and parsed
-  // into |quic_error_code| upon receipt, when present.
-  std::string error_details;
-
-  // The frame type present in the IETF transport connection close frame.
-  // Not populated for the Google QUIC or application connection close frames.
-  // Contains the type of frame that triggered the connection close. Made a
-  // uint64, as opposed to the QuicIetfFrameType, to support possible
-  // extensions as well as reporting invalid frame types received from the peer.
-  uint64_t transport_close_frame_type = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
diff --git a/quic/core/frames/quic_crypto_frame.cc b/quic/core/frames/quic_crypto_frame.cc
deleted file mode 100644
index 7b72beb..0000000
--- a/quic/core/frames/quic_crypto_frame.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_crypto_frame.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
-                                 QuicStreamOffset offset,
-                                 QuicPacketLength data_length)
-    : QuicCryptoFrame(level, offset, nullptr, data_length) {}
-
-QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
-                                 QuicStreamOffset offset,
-                                 absl::string_view data)
-    : QuicCryptoFrame(level, offset, data.data(), data.length()) {}
-
-QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
-                                 QuicStreamOffset offset,
-                                 const char* data_buffer,
-                                 QuicPacketLength data_length)
-    : level(level),
-      data_length(data_length),
-      data_buffer(data_buffer),
-      offset(offset) {}
-
-QuicCryptoFrame::~QuicCryptoFrame() {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicCryptoFrame& stream_frame) {
-  os << "{ level: " << stream_frame.level << ", offset: " << stream_frame.offset
-     << ", length: " << stream_frame.data_length << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_crypto_frame.h b/quic/core/frames/quic_crypto_frame.h
deleted file mode 100644
index 6e15fbe..0000000
--- a/quic/core/frames/quic_crypto_frame.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicCryptoFrame {
-  QuicCryptoFrame() = default;
-  QuicCryptoFrame(EncryptionLevel level,
-                  QuicStreamOffset offset,
-                  QuicPacketLength data_length);
-  QuicCryptoFrame(EncryptionLevel level,
-                  QuicStreamOffset offset,
-                  absl::string_view data);
-  ~QuicCryptoFrame();
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                      const QuicCryptoFrame& s);
-
-  // When writing a crypto frame to a packet, the packet must be encrypted at
-  // |level|. When a crypto frame is read, the encryption level of the packet it
-  // was received in is put in |level|.
-  EncryptionLevel level = ENCRYPTION_INITIAL;
-  QuicPacketLength data_length = 0;
-  // When reading, |data_buffer| points to the data that was received in the
-  // frame. |data_buffer| is not used when writing.
-  const char* data_buffer = nullptr;
-  QuicStreamOffset offset = 0;  // Location of this data in the stream.
-
-  QuicCryptoFrame(EncryptionLevel level,
-                  QuicStreamOffset offset,
-                  const char* data_buffer,
-                  QuicPacketLength data_length);
-};
-static_assert(sizeof(QuicCryptoFrame) <= 64,
-              "Keep the QuicCryptoFrame size to a cacheline.");
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
diff --git a/quic/core/frames/quic_frame.cc b/quic/core/frames/quic_frame.cc
deleted file mode 100644
index 5d0a675..0000000
--- a/quic/core/frames/quic_frame.cc
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_frame.h"
-
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quic {
-
-QuicFrame::QuicFrame() {}
-
-QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
-    : padding_frame(padding_frame) {}
-
-QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
-    : stream_frame(stream_frame) {}
-
-QuicFrame::QuicFrame(QuicHandshakeDoneFrame handshake_done_frame)
-    : handshake_done_frame(handshake_done_frame) {}
-
-QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
-    : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}
-
-QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
-    : mtu_discovery_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
-    : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
-    : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
-    : type(GOAWAY_FRAME), goaway_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicWindowUpdateFrame frame)
-    : window_update_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicBlockedFrame frame) : blocked_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
-    : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
-    : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
-    : streams_blocked_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
-    : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
-    : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicStopSendingFrame frame) : stop_sending_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicMessageFrame* frame)
-    : type(MESSAGE_FRAME), message_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
-    : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}
-
-QuicFrame::QuicFrame(QuicAckFrequencyFrame* frame)
-    : type(ACK_FREQUENCY_FRAME), ack_frequency_frame(frame) {}
-
-void DeleteFrames(QuicFrames* frames) {
-  for (QuicFrame& frame : *frames) {
-    DeleteFrame(&frame);
-  }
-  frames->clear();
-}
-
-void DeleteFrame(QuicFrame* frame) {
-#if QUIC_FRAME_DEBUG
-  // If the frame is not inlined, check that it can be safely deleted.
-  if (frame->type != PADDING_FRAME && frame->type != MTU_DISCOVERY_FRAME &&
-      frame->type != PING_FRAME && frame->type != MAX_STREAMS_FRAME &&
-      frame->type != STOP_WAITING_FRAME &&
-      frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
-      frame->type != HANDSHAKE_DONE_FRAME &&
-      frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME &&
-      frame->type != STOP_SENDING_FRAME) {
-    QUICHE_CHECK(!frame->delete_forbidden) << *frame;
-  }
-#endif  // QUIC_FRAME_DEBUG
-  switch (frame->type) {
-    // Frames smaller than a pointer are inlined, so don't need to be deleted.
-    case PADDING_FRAME:
-    case MTU_DISCOVERY_FRAME:
-    case PING_FRAME:
-    case MAX_STREAMS_FRAME:
-    case STOP_WAITING_FRAME:
-    case STREAMS_BLOCKED_FRAME:
-    case STREAM_FRAME:
-    case HANDSHAKE_DONE_FRAME:
-    case WINDOW_UPDATE_FRAME:
-    case BLOCKED_FRAME:
-    case STOP_SENDING_FRAME:
-      break;
-    case ACK_FRAME:
-      delete frame->ack_frame;
-      break;
-    case RST_STREAM_FRAME:
-      delete frame->rst_stream_frame;
-      break;
-    case CONNECTION_CLOSE_FRAME:
-      delete frame->connection_close_frame;
-      break;
-    case GOAWAY_FRAME:
-      delete frame->goaway_frame;
-      break;
-    case PATH_CHALLENGE_FRAME:
-      delete frame->path_challenge_frame;
-      break;
-    case NEW_CONNECTION_ID_FRAME:
-      delete frame->new_connection_id_frame;
-      break;
-    case RETIRE_CONNECTION_ID_FRAME:
-      delete frame->retire_connection_id_frame;
-      break;
-    case PATH_RESPONSE_FRAME:
-      delete frame->path_response_frame;
-      break;
-    case MESSAGE_FRAME:
-      delete frame->message_frame;
-      break;
-    case CRYPTO_FRAME:
-      delete frame->crypto_frame;
-      break;
-    case NEW_TOKEN_FRAME:
-      delete frame->new_token_frame;
-      break;
-    case ACK_FREQUENCY_FRAME:
-      delete frame->ack_frequency_frame;
-      break;
-    case NUM_FRAME_TYPES:
-      QUICHE_DCHECK(false) << "Cannot delete type: " << frame->type;
-  }
-}
-
-void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
-  auto it = frames->begin();
-  while (it != frames->end()) {
-    if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
-      ++it;
-      continue;
-    }
-    it = frames->erase(it);
-  }
-}
-
-bool IsControlFrame(QuicFrameType type) {
-  switch (type) {
-    case RST_STREAM_FRAME:
-    case GOAWAY_FRAME:
-    case WINDOW_UPDATE_FRAME:
-    case BLOCKED_FRAME:
-    case STREAMS_BLOCKED_FRAME:
-    case MAX_STREAMS_FRAME:
-    case PING_FRAME:
-    case STOP_SENDING_FRAME:
-    case NEW_CONNECTION_ID_FRAME:
-    case RETIRE_CONNECTION_ID_FRAME:
-    case HANDSHAKE_DONE_FRAME:
-    case ACK_FREQUENCY_FRAME:
-    case NEW_TOKEN_FRAME:
-      return true;
-    default:
-      return false;
-  }
-}
-
-QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
-  switch (frame.type) {
-    case RST_STREAM_FRAME:
-      return frame.rst_stream_frame->control_frame_id;
-    case GOAWAY_FRAME:
-      return frame.goaway_frame->control_frame_id;
-    case WINDOW_UPDATE_FRAME:
-      return frame.window_update_frame.control_frame_id;
-    case BLOCKED_FRAME:
-      return frame.blocked_frame.control_frame_id;
-    case STREAMS_BLOCKED_FRAME:
-      return frame.streams_blocked_frame.control_frame_id;
-    case MAX_STREAMS_FRAME:
-      return frame.max_streams_frame.control_frame_id;
-    case PING_FRAME:
-      return frame.ping_frame.control_frame_id;
-    case STOP_SENDING_FRAME:
-      return frame.stop_sending_frame.control_frame_id;
-    case NEW_CONNECTION_ID_FRAME:
-      return frame.new_connection_id_frame->control_frame_id;
-    case RETIRE_CONNECTION_ID_FRAME:
-      return frame.retire_connection_id_frame->control_frame_id;
-    case HANDSHAKE_DONE_FRAME:
-      return frame.handshake_done_frame.control_frame_id;
-    case ACK_FREQUENCY_FRAME:
-      return frame.ack_frequency_frame->control_frame_id;
-    case NEW_TOKEN_FRAME:
-      return frame.new_token_frame->control_frame_id;
-    default:
-      return kInvalidControlFrameId;
-  }
-}
-
-void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
-  switch (frame->type) {
-    case RST_STREAM_FRAME:
-      frame->rst_stream_frame->control_frame_id = control_frame_id;
-      return;
-    case GOAWAY_FRAME:
-      frame->goaway_frame->control_frame_id = control_frame_id;
-      return;
-    case WINDOW_UPDATE_FRAME:
-      frame->window_update_frame.control_frame_id = control_frame_id;
-      return;
-    case BLOCKED_FRAME:
-      frame->blocked_frame.control_frame_id = control_frame_id;
-      return;
-    case PING_FRAME:
-      frame->ping_frame.control_frame_id = control_frame_id;
-      return;
-    case STREAMS_BLOCKED_FRAME:
-      frame->streams_blocked_frame.control_frame_id = control_frame_id;
-      return;
-    case MAX_STREAMS_FRAME:
-      frame->max_streams_frame.control_frame_id = control_frame_id;
-      return;
-    case STOP_SENDING_FRAME:
-      frame->stop_sending_frame.control_frame_id = control_frame_id;
-      return;
-    case NEW_CONNECTION_ID_FRAME:
-      frame->new_connection_id_frame->control_frame_id = control_frame_id;
-      return;
-    case RETIRE_CONNECTION_ID_FRAME:
-      frame->retire_connection_id_frame->control_frame_id = control_frame_id;
-      return;
-    case HANDSHAKE_DONE_FRAME:
-      frame->handshake_done_frame.control_frame_id = control_frame_id;
-      return;
-    case ACK_FREQUENCY_FRAME:
-      frame->ack_frequency_frame->control_frame_id = control_frame_id;
-      return;
-    case NEW_TOKEN_FRAME:
-      frame->new_token_frame->control_frame_id = control_frame_id;
-      return;
-    default:
-      QUIC_BUG(quic_bug_12594_1)
-          << "Try to set control frame id of a frame without control frame id";
-  }
-}
-
-QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
-  QuicFrame copy;
-  switch (frame.type) {
-    case RST_STREAM_FRAME:
-      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
-      break;
-    case GOAWAY_FRAME:
-      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
-      break;
-    case WINDOW_UPDATE_FRAME:
-      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
-      break;
-    case BLOCKED_FRAME:
-      copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
-      break;
-    case PING_FRAME:
-      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
-      break;
-    case STOP_SENDING_FRAME:
-      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
-      break;
-    case NEW_CONNECTION_ID_FRAME:
-      copy = QuicFrame(
-          new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
-      break;
-    case RETIRE_CONNECTION_ID_FRAME:
-      copy = QuicFrame(
-          new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
-      break;
-    case STREAMS_BLOCKED_FRAME:
-      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
-      break;
-    case MAX_STREAMS_FRAME:
-      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
-      break;
-    case HANDSHAKE_DONE_FRAME:
-      copy = QuicFrame(
-          QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
-      break;
-    case ACK_FREQUENCY_FRAME:
-      copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
-      break;
-    case NEW_TOKEN_FRAME:
-      copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
-      break;
-    default:
-      QUIC_BUG(quic_bug_10533_1)
-          << "Try to copy a non-retransmittable control frame: " << frame;
-      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
-      break;
-  }
-  return copy;
-}
-
-QuicFrame CopyQuicFrame(quiche::QuicheBufferAllocator* allocator,
-                        const QuicFrame& frame) {
-  QuicFrame copy;
-  switch (frame.type) {
-    case PADDING_FRAME:
-      copy = QuicFrame(QuicPaddingFrame(frame.padding_frame));
-      break;
-    case RST_STREAM_FRAME:
-      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
-      break;
-    case CONNECTION_CLOSE_FRAME:
-      copy = QuicFrame(
-          new QuicConnectionCloseFrame(*frame.connection_close_frame));
-      break;
-    case GOAWAY_FRAME:
-      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
-      break;
-    case WINDOW_UPDATE_FRAME:
-      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
-      break;
-    case BLOCKED_FRAME:
-      copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
-      break;
-    case STOP_WAITING_FRAME:
-      copy = QuicFrame(QuicStopWaitingFrame(frame.stop_waiting_frame));
-      break;
-    case PING_FRAME:
-      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
-      break;
-    case CRYPTO_FRAME:
-      copy = QuicFrame(new QuicCryptoFrame(*frame.crypto_frame));
-      break;
-    case STREAM_FRAME:
-      copy = QuicFrame(QuicStreamFrame(frame.stream_frame));
-      break;
-    case ACK_FRAME:
-      copy = QuicFrame(new QuicAckFrame(*frame.ack_frame));
-      break;
-    case MTU_DISCOVERY_FRAME:
-      copy = QuicFrame(QuicMtuDiscoveryFrame(frame.mtu_discovery_frame));
-      break;
-    case NEW_CONNECTION_ID_FRAME:
-      copy = QuicFrame(
-          new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
-      break;
-    case MAX_STREAMS_FRAME:
-      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
-      break;
-    case STREAMS_BLOCKED_FRAME:
-      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
-      break;
-    case PATH_RESPONSE_FRAME:
-      copy = QuicFrame(new QuicPathResponseFrame(*frame.path_response_frame));
-      break;
-    case PATH_CHALLENGE_FRAME:
-      copy = QuicFrame(new QuicPathChallengeFrame(*frame.path_challenge_frame));
-      break;
-    case STOP_SENDING_FRAME:
-      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
-      break;
-    case MESSAGE_FRAME:
-      copy = QuicFrame(new QuicMessageFrame(frame.message_frame->message_id));
-      copy.message_frame->data = frame.message_frame->data;
-      copy.message_frame->message_length = frame.message_frame->message_length;
-      for (const auto& slice : frame.message_frame->message_data) {
-        quiche::QuicheBuffer buffer =
-            quiche::QuicheBuffer::Copy(allocator, slice.AsStringView());
-        copy.message_frame->message_data.push_back(
-            quiche::QuicheMemSlice(std::move(buffer)));
-      }
-      break;
-    case NEW_TOKEN_FRAME:
-      copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
-      break;
-    case RETIRE_CONNECTION_ID_FRAME:
-      copy = QuicFrame(
-          new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
-      break;
-    case HANDSHAKE_DONE_FRAME:
-      copy = QuicFrame(
-          QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
-      break;
-    case ACK_FREQUENCY_FRAME:
-      copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
-      break;
-    default:
-      QUIC_BUG(quic_bug_10533_2) << "Cannot copy frame: " << frame;
-      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
-      break;
-  }
-  return copy;
-}
-
-QuicFrames CopyQuicFrames(quiche::QuicheBufferAllocator* allocator,
-                          const QuicFrames& frames) {
-  QuicFrames copy;
-  for (const auto& frame : frames) {
-    copy.push_back(CopyQuicFrame(allocator, frame));
-  }
-  return copy;
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
-  switch (frame.type) {
-    case PADDING_FRAME: {
-      os << "type { PADDING_FRAME } " << frame.padding_frame;
-      break;
-    }
-    case RST_STREAM_FRAME: {
-      os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
-      break;
-    }
-    case CONNECTION_CLOSE_FRAME: {
-      os << "type { CONNECTION_CLOSE_FRAME } "
-         << *(frame.connection_close_frame);
-      break;
-    }
-    case GOAWAY_FRAME: {
-      os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
-      break;
-    }
-    case WINDOW_UPDATE_FRAME: {
-      os << "type { WINDOW_UPDATE_FRAME } " << frame.window_update_frame;
-      break;
-    }
-    case BLOCKED_FRAME: {
-      os << "type { BLOCKED_FRAME } " << frame.blocked_frame;
-      break;
-    }
-    case STREAM_FRAME: {
-      os << "type { STREAM_FRAME } " << frame.stream_frame;
-      break;
-    }
-    case ACK_FRAME: {
-      os << "type { ACK_FRAME } " << *(frame.ack_frame);
-      break;
-    }
-    case STOP_WAITING_FRAME: {
-      os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
-      break;
-    }
-    case PING_FRAME: {
-      os << "type { PING_FRAME } " << frame.ping_frame;
-      break;
-    }
-    case CRYPTO_FRAME: {
-      os << "type { CRYPTO_FRAME } " << *(frame.crypto_frame);
-      break;
-    }
-    case MTU_DISCOVERY_FRAME: {
-      os << "type { MTU_DISCOVERY_FRAME } ";
-      break;
-    }
-    case NEW_CONNECTION_ID_FRAME:
-      os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
-      break;
-    case RETIRE_CONNECTION_ID_FRAME:
-      os << "type { RETIRE_CONNECTION_ID } "
-         << *(frame.retire_connection_id_frame);
-      break;
-    case MAX_STREAMS_FRAME:
-      os << "type { MAX_STREAMS } " << frame.max_streams_frame;
-      break;
-    case STREAMS_BLOCKED_FRAME:
-      os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
-      break;
-    case PATH_RESPONSE_FRAME:
-      os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
-      break;
-    case PATH_CHALLENGE_FRAME:
-      os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
-      break;
-    case STOP_SENDING_FRAME:
-      os << "type { STOP_SENDING } " << frame.stop_sending_frame;
-      break;
-    case MESSAGE_FRAME:
-      os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
-      break;
-    case NEW_TOKEN_FRAME:
-      os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
-      break;
-    case HANDSHAKE_DONE_FRAME:
-      os << "type { HANDSHAKE_DONE_FRAME } " << frame.handshake_done_frame;
-      break;
-    case ACK_FREQUENCY_FRAME:
-      os << "type { ACK_FREQUENCY_FRAME } " << *(frame.ack_frequency_frame);
-      break;
-    default: {
-      QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
-      break;
-    }
-  }
-  return os;
-}
-
-std::string QuicFramesToString(const QuicFrames& frames) {
-  std::ostringstream os;
-  for (const QuicFrame& frame : frames) {
-    os << frame;
-  }
-  return os.str();
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_frame.h b/quic/core/frames/quic_frame.h
deleted file mode 100644
index e776999..0000000
--- a/quic/core/frames/quic_frame.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
-
-#include <ostream>
-#include <type_traits>
-#include <vector>
-
-#include "absl/container/inlined_vector.h"
-#include "quic/core/frames/quic_ack_frame.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_blocked_frame.h"
-#include "quic/core/frames/quic_connection_close_frame.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/frames/quic_goaway_frame.h"
-#include "quic/core/frames/quic_handshake_done_frame.h"
-#include "quic/core/frames/quic_max_streams_frame.h"
-#include "quic/core/frames/quic_message_frame.h"
-#include "quic/core/frames/quic_mtu_discovery_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_new_token_frame.h"
-#include "quic/core/frames/quic_padding_frame.h"
-#include "quic/core/frames/quic_path_challenge_frame.h"
-#include "quic/core/frames/quic_path_response_frame.h"
-#include "quic/core/frames/quic_ping_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/frames/quic_stop_sending_frame.h"
-#include "quic/core/frames/quic_stop_waiting_frame.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/frames/quic_streams_blocked_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-
-#ifndef QUIC_FRAME_DEBUG
-#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define QUIC_FRAME_DEBUG 1
-#else  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define QUIC_FRAME_DEBUG 0
-#endif  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#endif  // QUIC_FRAME_DEBUG
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicFrame {
-  QuicFrame();
-  // Please keep the constructors in the same order as the union below.
-  explicit QuicFrame(QuicPaddingFrame padding_frame);
-  explicit QuicFrame(QuicMtuDiscoveryFrame frame);
-  explicit QuicFrame(QuicPingFrame frame);
-  explicit QuicFrame(QuicMaxStreamsFrame frame);
-  explicit QuicFrame(QuicStopWaitingFrame frame);
-  explicit QuicFrame(QuicStreamsBlockedFrame frame);
-  explicit QuicFrame(QuicStreamFrame stream_frame);
-  explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame);
-  explicit QuicFrame(QuicWindowUpdateFrame frame);
-  explicit QuicFrame(QuicBlockedFrame frame);
-  explicit QuicFrame(QuicStopSendingFrame frame);
-
-  explicit QuicFrame(QuicAckFrame* frame);
-  explicit QuicFrame(QuicRstStreamFrame* frame);
-  explicit QuicFrame(QuicConnectionCloseFrame* frame);
-  explicit QuicFrame(QuicGoAwayFrame* frame);
-  explicit QuicFrame(QuicNewConnectionIdFrame* frame);
-  explicit QuicFrame(QuicRetireConnectionIdFrame* frame);
-  explicit QuicFrame(QuicNewTokenFrame* frame);
-  explicit QuicFrame(QuicPathResponseFrame* frame);
-  explicit QuicFrame(QuicPathChallengeFrame* frame);
-  explicit QuicFrame(QuicMessageFrame* message_frame);
-  explicit QuicFrame(QuicCryptoFrame* crypto_frame);
-  explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
-                                                      const QuicFrame& frame);
-
-  union {
-    // Inlined frames.
-    // Overlapping inlined frames have a |type| field at the same 0 offset as
-    // QuicFrame does for out of line frames below, allowing use of the
-    // remaining 7 bytes after offset for frame-type specific fields.
-    QuicPaddingFrame padding_frame;
-    QuicMtuDiscoveryFrame mtu_discovery_frame;
-    QuicPingFrame ping_frame;
-    QuicMaxStreamsFrame max_streams_frame;
-    QuicStopWaitingFrame stop_waiting_frame;
-    QuicStreamsBlockedFrame streams_blocked_frame;
-    QuicStreamFrame stream_frame;
-    QuicHandshakeDoneFrame handshake_done_frame;
-    QuicWindowUpdateFrame window_update_frame;
-    QuicBlockedFrame blocked_frame;
-    QuicStopSendingFrame stop_sending_frame;
-
-    // Out of line frames.
-    struct {
-      QuicFrameType type;
-
-#if QUIC_FRAME_DEBUG
-      bool delete_forbidden = false;
-#endif  // QUIC_FRAME_DEBUG
-
-      // TODO(wub): These frames can also be inlined without increasing the size
-      // of QuicFrame:
-      // QuicPathResponseFrame, QuicPathChallengeFrame.
-      union {
-        QuicAckFrame* ack_frame;
-        QuicRstStreamFrame* rst_stream_frame;
-        QuicConnectionCloseFrame* connection_close_frame;
-        QuicGoAwayFrame* goaway_frame;
-        QuicNewConnectionIdFrame* new_connection_id_frame;
-        QuicRetireConnectionIdFrame* retire_connection_id_frame;
-        QuicPathResponseFrame* path_response_frame;
-        QuicPathChallengeFrame* path_challenge_frame;
-        QuicMessageFrame* message_frame;
-        QuicCryptoFrame* crypto_frame;
-        QuicAckFrequencyFrame* ack_frequency_frame;
-        QuicNewTokenFrame* new_token_frame;
-      };
-    };
-  };
-};
-
-static_assert(std::is_standard_layout<QuicFrame>::value,
-              "QuicFrame must have a standard layout");
-static_assert(sizeof(QuicFrame) <= 24,
-              "Frames larger than 24 bytes should be referenced by pointer.");
-static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type),
-              "Offset of |type| must match in QuicFrame and QuicStreamFrame");
-
-// A inline size of 1 is chosen to optimize the typical use case of
-// 1-stream-frame in QuicTransmissionInfo.retransmittable_frames.
-using QuicFrames = absl::InlinedVector<QuicFrame, 1>;
-
-// Deletes all the sub-frames contained in |frames|.
-QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames);
-
-// Delete the sub-frame contained in |frame|.
-QUIC_EXPORT_PRIVATE void DeleteFrame(QuicFrame* frame);
-
-// Deletes all the QuicStreamFrames for the specified |stream_id|.
-QUIC_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames,
-                                               QuicStreamId stream_id);
-
-// Returns true if |type| is a retransmittable control frame.
-QUIC_EXPORT_PRIVATE bool IsControlFrame(QuicFrameType type);
-
-// Returns control_frame_id of |frame|. Returns kInvalidControlFrameId if
-// |frame| does not have a valid control_frame_id.
-QUIC_EXPORT_PRIVATE QuicControlFrameId
-GetControlFrameId(const QuicFrame& frame);
-
-// Sets control_frame_id of |frame| to |control_frame_id|.
-QUIC_EXPORT_PRIVATE void SetControlFrameId(QuicControlFrameId control_frame_id,
-                                           QuicFrame* frame);
-
-// Returns a copy of |frame|.
-QUIC_EXPORT_PRIVATE QuicFrame
-CopyRetransmittableControlFrame(const QuicFrame& frame);
-
-// Returns a copy of |frame|.
-QUIC_EXPORT_PRIVATE QuicFrame
-CopyQuicFrame(quiche::QuicheBufferAllocator* allocator, const QuicFrame& frame);
-
-// Returns a copy of |frames|.
-QUIC_EXPORT_PRIVATE QuicFrames CopyQuicFrames(
-    quiche::QuicheBufferAllocator* allocator, const QuicFrames& frames);
-
-// Human-readable description suitable for logging.
-QUIC_EXPORT_PRIVATE std::string QuicFramesToString(const QuicFrames& frames);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
diff --git a/quic/core/frames/quic_frames_test.cc b/quic/core/frames/quic_frames_test.cc
deleted file mode 100644
index 2520964..0000000
--- a/quic/core/frames/quic_frames_test.cc
+++ /dev/null
@@ -1,832 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ack_frame.h"
-#include "quic/core/frames/quic_blocked_frame.h"
-#include "quic/core/frames/quic_connection_close_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_goaway_frame.h"
-#include "quic/core/frames/quic_mtu_discovery_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_padding_frame.h"
-#include "quic/core/frames/quic_ping_frame.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/frames/quic_stop_waiting_frame.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicFramesTest : public QuicTest {};
-
-TEST_F(QuicFramesTest, AckFrameToString) {
-  QuicAckFrame frame;
-  frame.largest_acked = QuicPacketNumber(5);
-  frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
-  frame.packets.Add(QuicPacketNumber(4));
-  frame.packets.Add(QuicPacketNumber(5));
-  frame.received_packet_times = {
-      {QuicPacketNumber(6),
-       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
-  std::ostringstream stream;
-  stream << frame;
-  EXPECT_EQ(
-      "{ largest_acked: 5, ack_delay_time: 3, packets: [ 4 5  ], "
-      "received_packets: [ 6 at 7  ], ecn_counters_populated: 0 }\n",
-      stream.str());
-  QuicFrame quic_frame(&frame);
-  EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, BigAckFrameToString) {
-  QuicAckFrame frame;
-  frame.largest_acked = QuicPacketNumber(500);
-  frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
-  frame.packets.AddRange(QuicPacketNumber(4), QuicPacketNumber(501));
-  frame.received_packet_times = {
-      {QuicPacketNumber(500),
-       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
-  std::ostringstream stream;
-  stream << frame;
-  EXPECT_EQ(
-      "{ largest_acked: 500, ack_delay_time: 3, packets: [ 4...500  ], "
-      "received_packets: [ 500 at 7  ], ecn_counters_populated: 0 }\n",
-      stream.str());
-  QuicFrame quic_frame(&frame);
-  EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, PaddingFrameToString) {
-  QuicPaddingFrame frame;
-  frame.num_padding_bytes = 1;
-  std::ostringstream stream;
-  stream << frame;
-  EXPECT_EQ("{ num_padding_bytes: 1 }\n", stream.str());
-  QuicFrame quic_frame(frame);
-  EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, RstStreamFrameToString) {
-  QuicRstStreamFrame rst_stream;
-  QuicFrame frame(&rst_stream);
-  SetControlFrameId(1, &frame);
-  EXPECT_EQ(1u, GetControlFrameId(frame));
-  rst_stream.stream_id = 1;
-  rst_stream.byte_offset = 3;
-  rst_stream.error_code = QUIC_STREAM_CANCELLED;
-  std::ostringstream stream;
-  stream << rst_stream;
-  EXPECT_EQ(
-      "{ control_frame_id: 1, stream_id: 1, byte_offset: 3, error_code: 6, "
-      "ietf_error_code: 0 }\n",
-      stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, StopSendingFrameToString) {
-  QuicFrame frame((QuicStopSendingFrame()));
-  SetControlFrameId(1, &frame);
-  EXPECT_EQ(1u, GetControlFrameId(frame));
-  frame.stop_sending_frame.stream_id = 321;
-  frame.stop_sending_frame.error_code = QUIC_STREAM_CANCELLED;
-  frame.stop_sending_frame.ietf_error_code =
-      static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
-  std::ostringstream stream;
-  stream << frame.stop_sending_frame;
-  EXPECT_EQ(
-      "{ control_frame_id: 1, stream_id: 321, error_code: 6, ietf_error_code: "
-      "268 }\n",
-      stream.str());
-}
-
-TEST_F(QuicFramesTest, NewConnectionIdFrameToString) {
-  QuicNewConnectionIdFrame new_connection_id_frame;
-  QuicFrame frame(&new_connection_id_frame);
-  SetControlFrameId(1, &frame);
-  QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
-  EXPECT_EQ(1u, GetControlFrameId(frame_copy));
-  new_connection_id_frame.connection_id = TestConnectionId(2);
-  new_connection_id_frame.sequence_number = 2u;
-  new_connection_id_frame.retire_prior_to = 1u;
-  new_connection_id_frame.stateless_reset_token =
-      StatelessResetToken{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-  std::ostringstream stream;
-  stream << new_connection_id_frame;
-  EXPECT_EQ(
-      "{ control_frame_id: 1, connection_id: 0000000000000002, "
-      "sequence_number: 2, retire_prior_to: 1 }\n",
-      stream.str());
-  EXPECT_TRUE(IsControlFrame(frame_copy.type));
-  DeleteFrame(&frame_copy);
-}
-
-TEST_F(QuicFramesTest, RetireConnectionIdFrameToString) {
-  QuicRetireConnectionIdFrame retire_connection_id_frame;
-  QuicFrame frame(&retire_connection_id_frame);
-  SetControlFrameId(1, &frame);
-  QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
-  EXPECT_EQ(1u, GetControlFrameId(frame_copy));
-  retire_connection_id_frame.sequence_number = 1u;
-  std::ostringstream stream;
-  stream << retire_connection_id_frame;
-  EXPECT_EQ("{ control_frame_id: 1, sequence_number: 1 }\n", stream.str());
-  EXPECT_TRUE(IsControlFrame(frame_copy.type));
-  DeleteFrame(&frame_copy);
-}
-
-TEST_F(QuicFramesTest, StreamsBlockedFrameToString) {
-  QuicStreamsBlockedFrame streams_blocked;
-  QuicFrame frame(streams_blocked);
-  SetControlFrameId(1, &frame);
-  EXPECT_EQ(1u, GetControlFrameId(frame));
-  // QuicStreamsBlocked is copied into a QuicFrame (as opposed to putting a
-  // pointer to it into QuicFrame) so need to work with the copy in |frame| and
-  // not the original one, streams_blocked.
-  frame.streams_blocked_frame.stream_count = 321;
-  frame.streams_blocked_frame.unidirectional = false;
-  std::ostringstream stream;
-  stream << frame.streams_blocked_frame;
-  EXPECT_EQ("{ control_frame_id: 1, stream count: 321, bidirectional }\n",
-            stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, MaxStreamsFrameToString) {
-  QuicMaxStreamsFrame max_streams;
-  QuicFrame frame(max_streams);
-  SetControlFrameId(1, &frame);
-  EXPECT_EQ(1u, GetControlFrameId(frame));
-  // QuicMaxStreams is copied into a QuicFrame (as opposed to putting a
-  // pointer to it into QuicFrame) so need to work with the copy in |frame| and
-  // not the original one, max_streams.
-  frame.max_streams_frame.stream_count = 321;
-  frame.max_streams_frame.unidirectional = true;
-  std::ostringstream stream;
-  stream << frame.max_streams_frame;
-  EXPECT_EQ("{ control_frame_id: 1, stream_count: 321, unidirectional }\n",
-            stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, ConnectionCloseFrameToString) {
-  QuicConnectionCloseFrame frame;
-  frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
-  frame.error_details = "No recent network activity.";
-  std::ostringstream stream;
-  stream << frame;
-  // Note that "extracted_error_code: 122" is QUIC_IETF_GQUIC_ERROR_MISSING,
-  // indicating that, in fact, no extended error code was available from the
-  // underlying frame.
-  EXPECT_EQ(
-      "{ Close type: GOOGLE_QUIC_CONNECTION_CLOSE, "
-      "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
-      "error_details: 'No recent network activity.'}\n",
-      stream.str());
-  QuicFrame quic_frame(&frame);
-  EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, TransportConnectionCloseFrameToString) {
-  QuicConnectionCloseFrame frame;
-  frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
-  frame.wire_error_code = FINAL_SIZE_ERROR;
-  frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
-  frame.error_details = "No recent network activity.";
-  frame.transport_close_frame_type = IETF_STREAM;
-  std::ostringstream stream;
-  stream << frame;
-  EXPECT_EQ(
-      "{ Close type: IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, "
-      "wire_error_code: FINAL_SIZE_ERROR, "
-      "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
-      "error_details: 'No recent "
-      "network activity.', "
-      "frame_type: IETF_STREAM"
-      "}\n",
-      stream.str());
-  QuicFrame quic_frame(&frame);
-  EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, GoAwayFrameToString) {
-  QuicGoAwayFrame goaway_frame;
-  QuicFrame frame(&goaway_frame);
-  SetControlFrameId(2, &frame);
-  EXPECT_EQ(2u, GetControlFrameId(frame));
-  goaway_frame.error_code = QUIC_NETWORK_IDLE_TIMEOUT;
-  goaway_frame.last_good_stream_id = 2;
-  goaway_frame.reason_phrase = "Reason";
-  std::ostringstream stream;
-  stream << goaway_frame;
-  EXPECT_EQ(
-      "{ control_frame_id: 2, error_code: 25, last_good_stream_id: 2, "
-      "reason_phrase: "
-      "'Reason' }\n",
-      stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, WindowUpdateFrameToString) {
-  QuicFrame frame((QuicWindowUpdateFrame()));
-  SetControlFrameId(3, &frame);
-  EXPECT_EQ(3u, GetControlFrameId(frame));
-  std::ostringstream stream;
-  frame.window_update_frame.stream_id = 1;
-  frame.window_update_frame.max_data = 2;
-  stream << frame.window_update_frame;
-  EXPECT_EQ("{ control_frame_id: 3, stream_id: 1, max_data: 2 }\n",
-            stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, BlockedFrameToString) {
-  QuicFrame frame((QuicBlockedFrame()));
-  SetControlFrameId(4, &frame);
-  EXPECT_EQ(4u, GetControlFrameId(frame));
-  frame.blocked_frame.stream_id = 1;
-  std::ostringstream stream;
-  stream << frame.blocked_frame;
-  EXPECT_EQ("{ control_frame_id: 4, stream_id: 1 }\n", stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, PingFrameToString) {
-  QuicPingFrame ping;
-  QuicFrame frame(ping);
-  SetControlFrameId(5, &frame);
-  EXPECT_EQ(5u, GetControlFrameId(frame));
-  std::ostringstream stream;
-  stream << frame.ping_frame;
-  EXPECT_EQ("{ control_frame_id: 5 }\n", stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, HandshakeDoneFrameToString) {
-  QuicHandshakeDoneFrame handshake_done;
-  QuicFrame frame(handshake_done);
-  SetControlFrameId(6, &frame);
-  EXPECT_EQ(6u, GetControlFrameId(frame));
-  std::ostringstream stream;
-  stream << frame.handshake_done_frame;
-  EXPECT_EQ("{ control_frame_id: 6 }\n", stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, QuicAckFreuqncyFrameToString) {
-  QuicAckFrequencyFrame ack_frequency_frame;
-  ack_frequency_frame.sequence_number = 1;
-  ack_frequency_frame.packet_tolerance = 2;
-  ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(25);
-  ack_frequency_frame.ignore_order = false;
-  QuicFrame frame(&ack_frequency_frame);
-  ASSERT_EQ(ACK_FREQUENCY_FRAME, frame.type);
-  SetControlFrameId(6, &frame);
-  EXPECT_EQ(6u, GetControlFrameId(frame));
-  std::ostringstream stream;
-  stream << *frame.ack_frequency_frame;
-  EXPECT_EQ(
-      "{ control_frame_id: 6, sequence_number: 1, packet_tolerance: 2, "
-      "max_ack_delay_ms: 25, ignore_order: 0 }\n",
-      stream.str());
-  EXPECT_TRUE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, StreamFrameToString) {
-  QuicStreamFrame frame;
-  frame.stream_id = 1;
-  frame.fin = false;
-  frame.offset = 2;
-  frame.data_length = 3;
-  std::ostringstream stream;
-  stream << frame;
-  EXPECT_EQ("{ stream_id: 1, fin: 0, offset: 2, length: 3 }\n", stream.str());
-  EXPECT_FALSE(IsControlFrame(frame.type));
-}
-
-TEST_F(QuicFramesTest, StopWaitingFrameToString) {
-  QuicStopWaitingFrame frame;
-  frame.least_unacked = QuicPacketNumber(2);
-  std::ostringstream stream;
-  stream << frame;
-  EXPECT_EQ("{ least_unacked: 2 }\n", stream.str());
-  QuicFrame quic_frame(frame);
-  EXPECT_FALSE(IsControlFrame(quic_frame.type));
-}
-
-TEST_F(QuicFramesTest, IsAwaitingPacket) {
-  QuicAckFrame ack_frame1;
-  ack_frame1.largest_acked = QuicPacketNumber(10u);
-  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(11));
-  EXPECT_TRUE(
-      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
-  EXPECT_FALSE(
-      IsAwaitingPacket(ack_frame1, QuicPacketNumber(1u), QuicPacketNumber()));
-
-  ack_frame1.packets.Add(QuicPacketNumber(12));
-  EXPECT_TRUE(
-      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
-
-  QuicAckFrame ack_frame2;
-  ack_frame2.largest_acked = QuicPacketNumber(100u);
-  ack_frame2.packets.AddRange(QuicPacketNumber(21), QuicPacketNumber(100));
-  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(11u),
-                                QuicPacketNumber(20u)));
-  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(80u),
-                                QuicPacketNumber(20u)));
-  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
-                               QuicPacketNumber(20u)));
-
-  ack_frame2.packets.AddRange(QuicPacketNumber(102), QuicPacketNumber(200));
-  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
-                               QuicPacketNumber(20u)));
-}
-
-TEST_F(QuicFramesTest, AddPacket) {
-  QuicAckFrame ack_frame1;
-  ack_frame1.packets.Add(QuicPacketNumber(1));
-  ack_frame1.packets.Add(QuicPacketNumber(99));
-
-  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
-  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(
-      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(99), QuicPacketNumber(100)));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  EXPECT_EQ(expected_intervals, actual_intervals);
-
-  ack_frame1.packets.Add(QuicPacketNumber(20));
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
-  expected_intervals2.emplace_back(
-      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(20), QuicPacketNumber(21)));
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(99), QuicPacketNumber(100)));
-
-  EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(expected_intervals2, actual_intervals2);
-
-  ack_frame1.packets.Add(QuicPacketNumber(19));
-  ack_frame1.packets.Add(QuicPacketNumber(21));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals3(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals3;
-  expected_intervals3.emplace_back(
-      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
-  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(19), QuicPacketNumber(22)));
-  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(99), QuicPacketNumber(100)));
-
-  EXPECT_EQ(expected_intervals3, actual_intervals3);
-
-  ack_frame1.packets.Add(QuicPacketNumber(20));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals4(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  EXPECT_EQ(expected_intervals3, actual_intervals4);
-
-  QuicAckFrame ack_frame2;
-  ack_frame2.packets.Add(QuicPacketNumber(20));
-  ack_frame2.packets.Add(QuicPacketNumber(40));
-  ack_frame2.packets.Add(QuicPacketNumber(60));
-  ack_frame2.packets.Add(QuicPacketNumber(10));
-  ack_frame2.packets.Add(QuicPacketNumber(80));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals5(
-      ack_frame2.packets.begin(), ack_frame2.packets.end());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals5;
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(10), QuicPacketNumber(11)));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(20), QuicPacketNumber(21)));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(40), QuicPacketNumber(41)));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(60), QuicPacketNumber(61)));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(80), QuicPacketNumber(81)));
-
-  EXPECT_EQ(expected_intervals5, actual_intervals5);
-}
-
-TEST_F(QuicFramesTest, AddInterval) {
-  QuicAckFrame ack_frame1;
-  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
-  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
-
-  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
-  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals{
-      {QuicPacketNumber(1), QuicPacketNumber(10)},
-      {QuicPacketNumber(50), QuicPacketNumber(100)},
-  };
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  EXPECT_EQ(expected_intervals, actual_intervals);
-
-  // Add a range in the middle.
-  ack_frame1.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2{
-      {QuicPacketNumber(1), QuicPacketNumber(10)},
-      {QuicPacketNumber(20), QuicPacketNumber(30)},
-      {QuicPacketNumber(50), QuicPacketNumber(100)},
-  };
-
-  EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(expected_intervals2, actual_intervals2);
-
-  // Add ranges at both ends.
-  QuicAckFrame ack_frame2;
-  ack_frame2.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(25));
-  ack_frame2.packets.AddRange(QuicPacketNumber(40), QuicPacketNumber(45));
-  ack_frame2.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(65));
-  ack_frame2.packets.AddRange(QuicPacketNumber(10), QuicPacketNumber(15));
-  ack_frame2.packets.AddRange(QuicPacketNumber(80), QuicPacketNumber(85));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals8(
-      ack_frame2.packets.begin(), ack_frame2.packets.end());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals8{
-      {QuicPacketNumber(10), QuicPacketNumber(15)},
-      {QuicPacketNumber(20), QuicPacketNumber(25)},
-      {QuicPacketNumber(40), QuicPacketNumber(45)},
-      {QuicPacketNumber(60), QuicPacketNumber(65)},
-      {QuicPacketNumber(80), QuicPacketNumber(85)},
-  };
-
-  EXPECT_EQ(expected_intervals8, actual_intervals8);
-}
-
-TEST_F(QuicFramesTest, AddAdjacentForward) {
-  QuicAckFrame ack_frame1;
-  ack_frame1.packets.Add(QuicPacketNumber(49));
-  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
-  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
-  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(49), QuicPacketNumber(100)));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  EXPECT_EQ(expected_intervals, actual_intervals);
-}
-
-TEST_F(QuicFramesTest, AddAdjacentReverse) {
-  QuicAckFrame ack_frame1;
-  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
-  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
-  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
-  ack_frame1.packets.Add(QuicPacketNumber(49));
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(49), QuicPacketNumber(100)));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
-      ack_frame1.packets.begin(), ack_frame1.packets.end());
-
-  EXPECT_EQ(expected_intervals, actual_intervals);
-}
-
-TEST_F(QuicFramesTest, RemoveSmallestInterval) {
-  QuicAckFrame ack_frame1;
-  ack_frame1.largest_acked = QuicPacketNumber(100u);
-  ack_frame1.packets.AddRange(QuicPacketNumber(51), QuicPacketNumber(60));
-  ack_frame1.packets.AddRange(QuicPacketNumber(71), QuicPacketNumber(80));
-  ack_frame1.packets.AddRange(QuicPacketNumber(91), QuicPacketNumber(100));
-  ack_frame1.packets.RemoveSmallestInterval();
-  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(QuicPacketNumber(71u), ack_frame1.packets.Min());
-  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-
-  ack_frame1.packets.RemoveSmallestInterval();
-  EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(QuicPacketNumber(91u), ack_frame1.packets.Min());
-  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
-}
-
-TEST_F(QuicFramesTest, CopyQuicFrames) {
-  QuicFrames frames;
-  QuicMessageFrame* message_frame =
-      new QuicMessageFrame(1, MemSliceFromString("message"));
-  // Construct a frame list.
-  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
-    switch (i) {
-      case PADDING_FRAME:
-        frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-        break;
-      case RST_STREAM_FRAME:
-        frames.push_back(QuicFrame(new QuicRstStreamFrame()));
-        break;
-      case CONNECTION_CLOSE_FRAME:
-        frames.push_back(QuicFrame(new QuicConnectionCloseFrame()));
-        break;
-      case GOAWAY_FRAME:
-        frames.push_back(QuicFrame(new QuicGoAwayFrame()));
-        break;
-      case WINDOW_UPDATE_FRAME:
-        frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
-        break;
-      case BLOCKED_FRAME:
-        frames.push_back(QuicFrame(QuicBlockedFrame()));
-        break;
-      case STOP_WAITING_FRAME:
-        frames.push_back(QuicFrame(QuicStopWaitingFrame()));
-        break;
-      case PING_FRAME:
-        frames.push_back(QuicFrame(QuicPingFrame()));
-        break;
-      case CRYPTO_FRAME:
-        frames.push_back(QuicFrame(new QuicCryptoFrame()));
-        break;
-      case STREAM_FRAME:
-        frames.push_back(QuicFrame(QuicStreamFrame()));
-        break;
-      case ACK_FRAME:
-        frames.push_back(QuicFrame(new QuicAckFrame()));
-        break;
-      case MTU_DISCOVERY_FRAME:
-        frames.push_back(QuicFrame(QuicMtuDiscoveryFrame()));
-        break;
-      case NEW_CONNECTION_ID_FRAME:
-        frames.push_back(QuicFrame(new QuicNewConnectionIdFrame()));
-        break;
-      case MAX_STREAMS_FRAME:
-        frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
-        break;
-      case STREAMS_BLOCKED_FRAME:
-        frames.push_back(QuicFrame(QuicStreamsBlockedFrame()));
-        break;
-      case PATH_RESPONSE_FRAME:
-        frames.push_back(QuicFrame(new QuicPathResponseFrame()));
-        break;
-      case PATH_CHALLENGE_FRAME:
-        frames.push_back(QuicFrame(new QuicPathChallengeFrame()));
-        break;
-      case STOP_SENDING_FRAME:
-        frames.push_back(QuicFrame(QuicStopSendingFrame()));
-        break;
-      case MESSAGE_FRAME:
-        frames.push_back(QuicFrame(message_frame));
-        break;
-      case NEW_TOKEN_FRAME:
-        frames.push_back(QuicFrame(new QuicNewTokenFrame()));
-        break;
-      case RETIRE_CONNECTION_ID_FRAME:
-        frames.push_back(QuicFrame(new QuicRetireConnectionIdFrame()));
-        break;
-      case HANDSHAKE_DONE_FRAME:
-        frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
-        break;
-      case ACK_FREQUENCY_FRAME:
-        frames.push_back(QuicFrame(new QuicAckFrequencyFrame()));
-        break;
-      default:
-        ASSERT_TRUE(false)
-            << "Please fix CopyQuicFrames if a new frame type is added.";
-        break;
-    }
-  }
-
-  QuicFrames copy =
-      CopyQuicFrames(quiche::SimpleBufferAllocator::Get(), frames);
-  ASSERT_EQ(NUM_FRAME_TYPES, copy.size());
-  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
-    EXPECT_EQ(i, copy[i].type);
-    if (i != MESSAGE_FRAME) {
-      continue;
-    }
-    // Verify message frame is correctly copied.
-    EXPECT_EQ(1u, copy[i].message_frame->message_id);
-    EXPECT_EQ(nullptr, copy[i].message_frame->data);
-    EXPECT_EQ(7u, copy[i].message_frame->message_length);
-    ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
-    EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
-                        frames[i].message_frame->message_data[0].data(), 7));
-  }
-  DeleteFrames(&frames);
-  DeleteFrames(&copy);
-}
-
-class PacketNumberQueueTest : public QuicTest {};
-
-// Tests that a queue contains the expected data after calls to Add().
-TEST_F(PacketNumberQueueTest, AddRange) {
-  PacketNumberQueue queue;
-  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(51));
-  queue.Add(QuicPacketNumber(53));
-
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
-  for (int i = 1; i < 51; ++i) {
-    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
-  }
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber(52)));
-  EXPECT_TRUE(queue.Contains(QuicPacketNumber(53)));
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber(54)));
-  EXPECT_EQ(51u, queue.NumPacketsSlow());
-  EXPECT_EQ(QuicPacketNumber(1u), queue.Min());
-  EXPECT_EQ(QuicPacketNumber(53u), queue.Max());
-
-  queue.Add(QuicPacketNumber(70));
-  EXPECT_EQ(QuicPacketNumber(70u), queue.Max());
-}
-
-// Tests Contains function
-TEST_F(PacketNumberQueueTest, Contains) {
-  PacketNumberQueue queue;
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
-  queue.AddRange(QuicPacketNumber(5), QuicPacketNumber(10));
-  queue.Add(QuicPacketNumber(20));
-
-  for (int i = 1; i < 5; ++i) {
-    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
-  }
-
-  for (int i = 5; i < 10; ++i) {
-    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
-  }
-  for (int i = 10; i < 20; ++i) {
-    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
-  }
-  EXPECT_TRUE(queue.Contains(QuicPacketNumber(20)));
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber(21)));
-
-  PacketNumberQueue queue2;
-  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(1)));
-  for (int i = 1; i < 51; ++i) {
-    queue2.Add(QuicPacketNumber(2 * i));
-  }
-  EXPECT_FALSE(queue2.Contains(QuicPacketNumber()));
-  for (int i = 1; i < 51; ++i) {
-    if (i % 2 == 0) {
-      EXPECT_TRUE(queue2.Contains(QuicPacketNumber(i)));
-    } else {
-      EXPECT_FALSE(queue2.Contains(QuicPacketNumber(i)));
-    }
-  }
-  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(101)));
-}
-
-// Tests that a queue contains the expected data after calls to RemoveUpTo().
-TEST_F(PacketNumberQueueTest, Removal) {
-  PacketNumberQueue queue;
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
-  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
-
-  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(51)));
-  EXPECT_FALSE(queue.RemoveUpTo(QuicPacketNumber(51)));
-
-  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
-  for (int i = 1; i < 51; ++i) {
-    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
-  }
-  for (int i = 51; i < 100; ++i) {
-    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
-  }
-  EXPECT_EQ(49u, queue.NumPacketsSlow());
-  EXPECT_EQ(QuicPacketNumber(51u), queue.Min());
-  EXPECT_EQ(QuicPacketNumber(99u), queue.Max());
-
-  PacketNumberQueue queue2;
-  queue2.AddRange(QuicPacketNumber(1), QuicPacketNumber(5));
-  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(3)));
-  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(50)));
-  EXPECT_TRUE(queue2.Empty());
-}
-
-// Tests that a queue is empty when all of its elements are removed.
-TEST_F(PacketNumberQueueTest, Empty) {
-  PacketNumberQueue queue;
-  EXPECT_TRUE(queue.Empty());
-  EXPECT_EQ(0u, queue.NumPacketsSlow());
-
-  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
-  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(100)));
-  EXPECT_TRUE(queue.Empty());
-  EXPECT_EQ(0u, queue.NumPacketsSlow());
-}
-
-// Tests that logging the state of a PacketNumberQueue does not crash.
-TEST_F(PacketNumberQueueTest, LogDoesNotCrash) {
-  std::ostringstream oss;
-  PacketNumberQueue queue;
-  oss << queue;
-
-  queue.Add(QuicPacketNumber(1));
-  queue.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
-  oss << queue;
-}
-
-// Tests that the iterators returned from a packet queue iterate over the queue.
-TEST_F(PacketNumberQueueTest, Iterators) {
-  PacketNumberQueue queue;
-  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
-      queue.begin(), queue.end());
-
-  PacketNumberQueue queue2;
-  for (int i = 1; i < 100; i++) {
-    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
-  }
-
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
-      queue2.begin(), queue2.end());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(1), QuicPacketNumber(100)));
-  EXPECT_EQ(expected_intervals, actual_intervals);
-  EXPECT_EQ(expected_intervals, actual_intervals2);
-  EXPECT_EQ(actual_intervals, actual_intervals2);
-}
-
-TEST_F(PacketNumberQueueTest, ReversedIterators) {
-  PacketNumberQueue queue;
-  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
-  PacketNumberQueue queue2;
-  for (int i = 1; i < 100; i++) {
-    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
-  }
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
-      queue.rbegin(), queue.rend());
-  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
-      queue2.rbegin(), queue2.rend());
-
-  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
-      QuicPacketNumber(1), QuicPacketNumber(100)));
-
-  EXPECT_EQ(expected_intervals, actual_intervals);
-  EXPECT_EQ(expected_intervals, actual_intervals2);
-  EXPECT_EQ(actual_intervals, actual_intervals2);
-
-  PacketNumberQueue queue3;
-  for (int i = 1; i < 20; i++) {
-    queue3.Add(QuicPacketNumber(2 * i));
-  }
-
-  auto begin = queue3.begin();
-  auto end = queue3.end();
-  --end;
-  auto rbegin = queue3.rbegin();
-  auto rend = queue3.rend();
-  --rend;
-
-  EXPECT_EQ(*begin, *rend);
-  EXPECT_EQ(*rbegin, *end);
-}
-
-TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
-  PacketNumberQueue queue;
-  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
-  queue.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
-  queue.AddRange(QuicPacketNumber(40), QuicPacketNumber(50));
-  EXPECT_EQ(3u, queue.NumIntervals());
-  EXPECT_EQ(10u, queue.LastIntervalLength());
-
-  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(25)));
-  EXPECT_EQ(2u, queue.NumIntervals());
-  EXPECT_EQ(10u, queue.LastIntervalLength());
-  EXPECT_EQ(QuicPacketNumber(25u), queue.Min());
-  EXPECT_EQ(QuicPacketNumber(49u), queue.Max());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/frames/quic_goaway_frame.cc b/quic/core/frames/quic_goaway_frame.cc
deleted file mode 100644
index c73e6cb..0000000
--- a/quic/core/frames/quic_goaway_frame.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "quic/core/frames/quic_goaway_frame.h"
-
-namespace quic {
-
-QuicGoAwayFrame::QuicGoAwayFrame(QuicControlFrameId control_frame_id,
-                                 QuicErrorCode error_code,
-                                 QuicStreamId last_good_stream_id,
-                                 const std::string& reason)
-    : control_frame_id(control_frame_id),
-      error_code(error_code),
-      last_good_stream_id(last_good_stream_id),
-      reason_phrase(reason) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicGoAwayFrame& goaway_frame) {
-  os << "{ control_frame_id: " << goaway_frame.control_frame_id
-     << ", error_code: " << goaway_frame.error_code
-     << ", last_good_stream_id: " << goaway_frame.last_good_stream_id
-     << ", reason_phrase: '" << goaway_frame.reason_phrase << "' }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_goaway_frame.h b/quic/core/frames/quic_goaway_frame.h
deleted file mode 100644
index 436c7a3..0000000
--- a/quic/core/frames/quic_goaway_frame.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
-
-#include <ostream>
-#include <string>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicGoAwayFrame {
-  QuicGoAwayFrame() = default;
-  QuicGoAwayFrame(QuicControlFrameId control_frame_id,
-                  QuicErrorCode error_code,
-                  QuicStreamId last_good_stream_id,
-                  const std::string& reason);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                      const QuicGoAwayFrame& g);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-  QuicErrorCode error_code = QUIC_NO_ERROR;
-  QuicStreamId last_good_stream_id = 0;
-  std::string reason_phrase;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
diff --git a/quic/core/frames/quic_handshake_done_frame.cc b/quic/core/frames/quic_handshake_done_frame.cc
deleted file mode 100644
index 9501ff8..0000000
--- a/quic/core/frames/quic_handshake_done_frame.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_handshake_done_frame.h"
-
-namespace quic {
-
-QuicHandshakeDoneFrame::QuicHandshakeDoneFrame()
-    : QuicInlinedFrame(HANDSHAKE_DONE_FRAME) {}
-
-QuicHandshakeDoneFrame::QuicHandshakeDoneFrame(
-    QuicControlFrameId control_frame_id)
-    : QuicInlinedFrame(HANDSHAKE_DONE_FRAME),
-      control_frame_id(control_frame_id) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicHandshakeDoneFrame& handshake_done_frame) {
-  os << "{ control_frame_id: " << handshake_done_frame.control_frame_id
-     << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_handshake_done_frame.h b/quic/core/frames/quic_handshake_done_frame.h
deleted file mode 100644
index 69fc68c..0000000
--- a/quic/core/frames/quic_handshake_done_frame.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A HANDSHAKE_DONE frame contains no payload, and it is retransmittable,
-// and ACK'd just like other normal frames.
-struct QUIC_EXPORT_PRIVATE QuicHandshakeDoneFrame
-    : public QuicInlinedFrame<QuicHandshakeDoneFrame> {
-  QuicHandshakeDoneFrame();
-  explicit QuicHandshakeDoneFrame(QuicControlFrameId control_frame_id);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicHandshakeDoneFrame& handshake_done_frame);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
diff --git a/quic/core/frames/quic_inlined_frame.h b/quic/core/frames/quic_inlined_frame.h
deleted file mode 100644
index 1ef1532..0000000
--- a/quic/core/frames/quic_inlined_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
-
-#include <type_traits>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicInlinedFrame is the base class of all frame types that is inlined in the
-// QuicFrame class. It gurantees all inlined frame types contain a 'type' field
-// at offset 0, such that QuicFrame.type can get the correct frame type for both
-// inline and out-of-line frame types.
-template <typename DerivedT>
-struct QUIC_EXPORT_PRIVATE QuicInlinedFrame {
-  QuicInlinedFrame(QuicFrameType type) {
-    static_cast<DerivedT*>(this)->type = type;
-    static_assert(std::is_standard_layout<DerivedT>::value,
-                  "Inlined frame must have a standard layout");
-    static_assert(offsetof(DerivedT, type) == 0,
-                  "type must be the first field.");
-    static_assert(sizeof(DerivedT) <= 24,
-                  "Frames larger than 24 bytes should not be inlined.");
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
diff --git a/quic/core/frames/quic_max_streams_frame.cc b/quic/core/frames/quic_max_streams_frame.cc
deleted file mode 100644
index b2574e8..0000000
--- a/quic/core/frames/quic_max_streams_frame.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_max_streams_frame.h"
-
-namespace quic {
-
-QuicMaxStreamsFrame::QuicMaxStreamsFrame()
-    : QuicInlinedFrame(MAX_STREAMS_FRAME) {}
-
-QuicMaxStreamsFrame::QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
-                                         QuicStreamCount stream_count,
-                                         bool unidirectional)
-    : QuicInlinedFrame(MAX_STREAMS_FRAME),
-      control_frame_id(control_frame_id),
-      stream_count(stream_count),
-      unidirectional(unidirectional) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicMaxStreamsFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id
-     << ", stream_count: " << frame.stream_count
-     << ((frame.unidirectional) ? ", unidirectional }\n"
-                                : ", bidirectional }\n");
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_max_streams_frame.h b/quic/core/frames/quic_max_streams_frame.h
deleted file mode 100644
index 8b0231e..0000000
--- a/quic/core/frames/quic_max_streams_frame.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// IETF format MAX_STREAMS frame.
-// This frame is used by the sender to inform the peer of the number of
-// streams that the peer may open and that the sender will accept.
-struct QUIC_EXPORT_PRIVATE QuicMaxStreamsFrame
-    : public QuicInlinedFrame<QuicMaxStreamsFrame> {
-  QuicMaxStreamsFrame();
-  QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
-                      QuicStreamCount stream_count,
-                      bool unidirectional);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicMaxStreamsFrame& frame);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  // The number of streams that may be opened.
-  QuicStreamCount stream_count = 0;
-  // Whether uni- or bi-directional streams
-  bool unidirectional = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
diff --git a/quic/core/frames/quic_message_frame.cc b/quic/core/frames/quic_message_frame.cc
deleted file mode 100644
index 429a3bf..0000000
--- a/quic/core/frames/quic_message_frame.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_message_frame.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-namespace quic {
-
-QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id)
-    : message_id(message_id), data(nullptr), message_length(0) {}
-
-QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
-                                   absl::Span<quiche::QuicheMemSlice> span)
-    : message_id(message_id), data(nullptr), message_length(0) {
-  for (quiche::QuicheMemSlice& slice : span) {
-    if (slice.empty()) {
-      continue;
-    }
-    message_length += slice.length();
-    message_data.push_back(std::move(slice));
-  }
-}
-QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
-                                   quiche::QuicheMemSlice slice)
-    : QuicMessageFrame(message_id, absl::MakeSpan(&slice, 1)) {}
-
-QuicMessageFrame::QuicMessageFrame(const char* data, QuicPacketLength length)
-    : message_id(0), data(data), message_length(length) {}
-
-QuicMessageFrame::~QuicMessageFrame() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicMessageFrame& s) {
-  os << " message_id: " << s.message_id
-     << ", message_length: " << s.message_length << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_message_frame.h b/quic/core/frames/quic_message_frame.h
deleted file mode 100644
index 008a7d9..0000000
--- a/quic/core/frames/quic_message_frame.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
-
-#include "absl/container/inlined_vector.h"
-#include "absl/types/span.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-namespace quic {
-
-using QuicMessageData = absl::InlinedVector<quiche::QuicheMemSlice, 1>;
-
-struct QUIC_EXPORT_PRIVATE QuicMessageFrame {
-  QuicMessageFrame() = default;
-  explicit QuicMessageFrame(QuicMessageId message_id);
-  QuicMessageFrame(QuicMessageId message_id,
-                   absl::Span<quiche::QuicheMemSlice> span);
-  QuicMessageFrame(QuicMessageId message_id, quiche::QuicheMemSlice slice);
-  QuicMessageFrame(const char* data, QuicPacketLength length);
-
-  QuicMessageFrame(const QuicMessageFrame& other) = delete;
-  QuicMessageFrame& operator=(const QuicMessageFrame& other) = delete;
-
-  QuicMessageFrame(QuicMessageFrame&& other) = default;
-  QuicMessageFrame& operator=(QuicMessageFrame&& other) = default;
-
-  ~QuicMessageFrame();
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicMessageFrame& s);
-
-  // message_id is only used on the sender side and does not get serialized on
-  // wire.
-  QuicMessageId message_id = 0;
-  // Not owned, only used on read path.
-  const char* data = nullptr;
-  // Total length of message_data, must be fit into one packet.
-  QuicPacketLength message_length = 0;
-
-  // The actual message data which is reference counted, used on write path.
-  QuicMessageData message_data;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
diff --git a/quic/core/frames/quic_mtu_discovery_frame.h b/quic/core/frames/quic_mtu_discovery_frame.h
deleted file mode 100644
index 014af3a..0000000
--- a/quic/core/frames/quic_mtu_discovery_frame.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A path MTU discovery frame contains no payload and is serialized as a ping
-// frame.
-struct QUIC_EXPORT_PRIVATE QuicMtuDiscoveryFrame
-    : public QuicInlinedFrame<QuicMtuDiscoveryFrame> {
-  QuicMtuDiscoveryFrame() : QuicInlinedFrame(MTU_DISCOVERY_FRAME) {}
-
-  QuicFrameType type;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
diff --git a/quic/core/frames/quic_new_connection_id_frame.cc b/quic/core/frames/quic_new_connection_id_frame.cc
deleted file mode 100644
index b4c68ff..0000000
--- a/quic/core/frames/quic_new_connection_id_frame.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-
-namespace quic {
-
-QuicNewConnectionIdFrame::QuicNewConnectionIdFrame(
-    QuicControlFrameId control_frame_id,
-    QuicConnectionId connection_id,
-    QuicConnectionIdSequenceNumber sequence_number,
-    StatelessResetToken stateless_reset_token,
-    uint64_t retire_prior_to)
-    : control_frame_id(control_frame_id),
-      connection_id(connection_id),
-      sequence_number(sequence_number),
-      stateless_reset_token(stateless_reset_token),
-      retire_prior_to(retire_prior_to) {
-  QUICHE_DCHECK(retire_prior_to <= sequence_number);
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicNewConnectionIdFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id
-     << ", connection_id: " << frame.connection_id
-     << ", sequence_number: " << frame.sequence_number
-     << ", retire_prior_to: " << frame.retire_prior_to << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_new_connection_id_frame.h b/quic/core/frames/quic_new_connection_id_frame.h
deleted file mode 100644
index 235d2af..0000000
--- a/quic/core/frames/quic_new_connection_id_frame.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicNewConnectionIdFrame {
-  QuicNewConnectionIdFrame() = default;
-  QuicNewConnectionIdFrame(QuicControlFrameId control_frame_id,
-                           QuicConnectionId connection_id,
-                           QuicConnectionIdSequenceNumber sequence_number,
-                           StatelessResetToken stateless_reset_token,
-                           uint64_t retire_prior_to);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicNewConnectionIdFrame& frame);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-  QuicConnectionId connection_id = EmptyQuicConnectionId();
-  QuicConnectionIdSequenceNumber sequence_number = 0;
-  StatelessResetToken stateless_reset_token;
-  uint64_t retire_prior_to = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
diff --git a/quic/core/frames/quic_new_token_frame.cc b/quic/core/frames/quic_new_token_frame.cc
deleted file mode 100644
index 8642fd9..0000000
--- a/quic/core/frames/quic_new_token_frame.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_new_token_frame.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id,
-                                     absl::string_view token)
-    : control_frame_id(control_frame_id),
-      token(std::string(token.data(), token.length())) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
-  os << "{ control_frame_id: " << s.control_frame_id
-     << ", token: " << absl::BytesToHexString(s.token) << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_new_token_frame.h b/quic/core/frames/quic_new_token_frame.h
deleted file mode 100644
index d0d7e8e..0000000
--- a/quic/core/frames/quic_new_token_frame.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicNewTokenFrame {
-  QuicNewTokenFrame() = default;
-  QuicNewTokenFrame(QuicControlFrameId control_frame_id,
-                    absl::string_view token);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicNewTokenFrame& s);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  std::string token;
-};
-static_assert(sizeof(QuicNewTokenFrame) <= 64,
-              "Keep the QuicNewTokenFrame size to a cacheline.");
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
diff --git a/quic/core/frames/quic_padding_frame.cc b/quic/core/frames/quic_padding_frame.cc
deleted file mode 100644
index 5679a2b..0000000
--- a/quic/core/frames/quic_padding_frame.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_padding_frame.h"
-
-namespace quic {
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicPaddingFrame& padding_frame) {
-  os << "{ num_padding_bytes: " << padding_frame.num_padding_bytes << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_padding_frame.h b/quic/core/frames/quic_padding_frame.h
deleted file mode 100644
index 146721e..0000000
--- a/quic/core/frames/quic_padding_frame.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
-
-#include <cstdint>
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A padding frame contains no payload.
-struct QUIC_EXPORT_PRIVATE QuicPaddingFrame
-    : public QuicInlinedFrame<QuicPaddingFrame> {
-  QuicPaddingFrame() : QuicInlinedFrame(PADDING_FRAME) {}
-  explicit QuicPaddingFrame(int num_padding_bytes)
-      : QuicInlinedFrame(PADDING_FRAME), num_padding_bytes(num_padding_bytes) {}
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPaddingFrame& padding_frame);
-
-  QuicFrameType type;
-
-  // -1: full padding to the end of a max-sized packet
-  // otherwise: only pad up to num_padding_bytes bytes
-  int num_padding_bytes = -1;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
diff --git a/quic/core/frames/quic_path_challenge_frame.cc b/quic/core/frames/quic_path_challenge_frame.cc
deleted file mode 100644
index 0f88bb8..0000000
--- a/quic/core/frames/quic_path_challenge_frame.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_path_challenge_frame.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicPathChallengeFrame::QuicPathChallengeFrame(
-    QuicControlFrameId control_frame_id,
-    const QuicPathFrameBuffer& data_buff)
-    : control_frame_id(control_frame_id) {
-  memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
-}
-
-QuicPathChallengeFrame::~QuicPathChallengeFrame() {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicPathChallengeFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
-     << absl::BytesToHexString(absl::string_view(
-            reinterpret_cast<const char*>(frame.data_buffer.data()),
-            frame.data_buffer.size()))
-     << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_path_challenge_frame.h b/quic/core/frames/quic_path_challenge_frame.h
deleted file mode 100644
index 6966775..0000000
--- a/quic/core/frames/quic_path_challenge_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame {
-  QuicPathChallengeFrame() = default;
-  QuicPathChallengeFrame(QuicControlFrameId control_frame_id,
-                         const QuicPathFrameBuffer& data_buff);
-  ~QuicPathChallengeFrame();
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPathChallengeFrame& frame);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  QuicPathFrameBuffer data_buffer{};
-};
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
diff --git a/quic/core/frames/quic_path_response_frame.cc b/quic/core/frames/quic_path_response_frame.cc
deleted file mode 100644
index f802b13..0000000
--- a/quic/core/frames/quic_path_response_frame.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_path_response_frame.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicPathResponseFrame::QuicPathResponseFrame(
-    QuicControlFrameId control_frame_id,
-    const QuicPathFrameBuffer& data_buff)
-    : control_frame_id(control_frame_id) {
-  memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
-}
-
-QuicPathResponseFrame::~QuicPathResponseFrame() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
-     << absl::BytesToHexString(absl::string_view(
-            reinterpret_cast<const char*>(frame.data_buffer.data()),
-            frame.data_buffer.size()))
-     << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_path_response_frame.h b/quic/core/frames/quic_path_response_frame.h
deleted file mode 100644
index a4a75be..0000000
--- a/quic/core/frames/quic_path_response_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame {
-  QuicPathResponseFrame() = default;
-  QuicPathResponseFrame(QuicControlFrameId control_frame_id,
-                        const QuicPathFrameBuffer& data_buff);
-  ~QuicPathResponseFrame();
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPathResponseFrame& frame);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  QuicPathFrameBuffer data_buffer{};
-};
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
diff --git a/quic/core/frames/quic_ping_frame.cc b/quic/core/frames/quic_ping_frame.cc
deleted file mode 100644
index d4e6daa..0000000
--- a/quic/core/frames/quic_ping_frame.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_ping_frame.h"
-
-namespace quic {
-
-QuicPingFrame::QuicPingFrame() : QuicInlinedFrame(PING_FRAME) {}
-
-QuicPingFrame::QuicPingFrame(QuicControlFrameId control_frame_id)
-    : QuicInlinedFrame(PING_FRAME), control_frame_id(control_frame_id) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicPingFrame& ping_frame) {
-  os << "{ control_frame_id: " << ping_frame.control_frame_id << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_ping_frame.h b/quic/core/frames/quic_ping_frame.h
deleted file mode 100644
index 012d73d..0000000
--- a/quic/core/frames/quic_ping_frame.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A ping frame contains no payload, though it is retransmittable,
-// and ACK'd just like other normal frames.
-struct QUIC_EXPORT_PRIVATE QuicPingFrame
-    : public QuicInlinedFrame<QuicPingFrame> {
-  QuicPingFrame();
-  explicit QuicPingFrame(QuicControlFrameId control_frame_id);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPingFrame& ping_frame);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
diff --git a/quic/core/frames/quic_retire_connection_id_frame.cc b/quic/core/frames/quic_retire_connection_id_frame.cc
deleted file mode 100644
index c3009f0..0000000
--- a/quic/core/frames/quic_retire_connection_id_frame.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-
-namespace quic {
-
-QuicRetireConnectionIdFrame::QuicRetireConnectionIdFrame(
-    QuicControlFrameId control_frame_id,
-    QuicConnectionIdSequenceNumber sequence_number)
-    : control_frame_id(control_frame_id), sequence_number(sequence_number) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicRetireConnectionIdFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id
-     << ", sequence_number: " << frame.sequence_number << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_retire_connection_id_frame.h b/quic/core/frames/quic_retire_connection_id_frame.h
deleted file mode 100644
index 3a8a4da..0000000
--- a/quic/core/frames/quic_retire_connection_id_frame.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicRetireConnectionIdFrame {
-  QuicRetireConnectionIdFrame() = default;
-  QuicRetireConnectionIdFrame(QuicControlFrameId control_frame_id,
-                              QuicConnectionIdSequenceNumber sequence_number);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicRetireConnectionIdFrame& frame);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-  QuicConnectionIdSequenceNumber sequence_number = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
diff --git a/quic/core/frames/quic_rst_stream_frame.cc b/quic/core/frames/quic_rst_stream_frame.cc
deleted file mode 100644
index 873868c..0000000
--- a/quic/core/frames/quic_rst_stream_frame.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_rst_stream_frame.h"
-
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
-                                       QuicStreamId stream_id,
-                                       QuicRstStreamErrorCode error_code,
-                                       QuicStreamOffset bytes_written)
-    : control_frame_id(control_frame_id),
-      stream_id(stream_id),
-      error_code(error_code),
-      ietf_error_code(RstStreamErrorCodeToIetfResetStreamErrorCode(error_code)),
-      byte_offset(bytes_written) {}
-
-QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
-                                       QuicStreamId stream_id,
-                                       QuicResetStreamError error,
-                                       QuicStreamOffset bytes_written)
-    : control_frame_id(control_frame_id),
-      stream_id(stream_id),
-      error_code(error.internal_code()),
-      ietf_error_code(error.ietf_application_code()),
-      byte_offset(bytes_written) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicRstStreamFrame& rst_frame) {
-  os << "{ control_frame_id: " << rst_frame.control_frame_id
-     << ", stream_id: " << rst_frame.stream_id
-     << ", byte_offset: " << rst_frame.byte_offset
-     << ", error_code: " << rst_frame.error_code
-     << ", ietf_error_code: " << rst_frame.ietf_error_code << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_rst_stream_frame.h b/quic/core/frames/quic_rst_stream_frame.h
deleted file mode 100644
index 744a227..0000000
--- a/quic/core/frames/quic_rst_stream_frame.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicRstStreamFrame {
-  QuicRstStreamFrame() = default;
-  QuicRstStreamFrame(QuicControlFrameId control_frame_id,
-                     QuicStreamId stream_id, QuicRstStreamErrorCode error_code,
-                     QuicStreamOffset bytes_written);
-  QuicRstStreamFrame(QuicControlFrameId control_frame_id,
-                     QuicStreamId stream_id, QuicResetStreamError error,
-                     QuicStreamOffset bytes_written);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os, const QuicRstStreamFrame& r);
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  QuicStreamId stream_id = 0;
-
-  // When using Google QUIC: the RST_STREAM error code on the wire.
-  // When using IETF QUIC: for an outgoing RESET_STREAM frame, the error code
-  // generated by the application that determines |ietf_error_code| to be sent
-  // on the wire; for an incoming RESET_STREAM frame, the error code inferred
-  // from the |ietf_error_code| received on the wire.
-  QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
-
-  // Application error code of RESET_STREAM frame.  Used for IETF QUIC only.
-  uint64_t ietf_error_code = 0;
-
-  // Used to update flow control windows. On termination of a stream, both
-  // endpoints must inform the peer of the number of bytes they have sent on
-  // that stream. This can be done through normal termination (data packet with
-  // FIN) or through a RST.
-  QuicStreamOffset byte_offset = 0;
-
-  // Returns a tuple of both |error_code| and |ietf_error_code|.
-  QuicResetStreamError error() const {
-    return QuicResetStreamError(error_code, ietf_error_code);
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
diff --git a/quic/core/frames/quic_stop_sending_frame.cc b/quic/core/frames/quic_stop_sending_frame.cc
deleted file mode 100644
index 7923d41..0000000
--- a/quic/core/frames/quic_stop_sending_frame.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_stop_sending_frame.h"
-
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-QuicStopSendingFrame::QuicStopSendingFrame()
-    : QuicInlinedFrame(STOP_SENDING_FRAME) {}
-
-QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
-                                           QuicStreamId stream_id,
-                                           QuicRstStreamErrorCode error_code)
-    : QuicStopSendingFrame(control_frame_id, stream_id,
-                           QuicResetStreamError::FromInternal(error_code)) {}
-
-QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
-                                           QuicStreamId stream_id,
-                                           QuicResetStreamError error)
-    : QuicInlinedFrame(STOP_SENDING_FRAME),
-      control_frame_id(control_frame_id),
-      stream_id(stream_id),
-      error_code(error.internal_code()),
-      ietf_error_code(error.ietf_application_code()) {}
-
-std::ostream& operator<<(std::ostream& os, const QuicStopSendingFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id
-     << ", stream_id: " << frame.stream_id
-     << ", error_code: " << frame.error_code
-     << ", ietf_error_code: " << frame.ietf_error_code << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_stop_sending_frame.h b/quic/core/frames/quic_stop_sending_frame.h
deleted file mode 100644
index d7c92f1..0000000
--- a/quic/core/frames/quic_stop_sending_frame.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame
-    : public QuicInlinedFrame<QuicStopSendingFrame> {
-  QuicStopSendingFrame();
-  QuicStopSendingFrame(QuicControlFrameId control_frame_id,
-                       QuicStreamId stream_id,
-                       QuicRstStreamErrorCode error_code);
-  QuicStopSendingFrame(QuicControlFrameId control_frame_id,
-                       QuicStreamId stream_id, QuicResetStreamError error);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicStopSendingFrame& frame);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-  QuicStreamId stream_id = 0;
-
-  // For an outgoing frame, the error code generated by the application that
-  // determines |ietf_error_code| to be sent on the wire; for an incoming frame,
-  // the error code inferred from |ietf_error_code| received on the wire.
-  QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
-
-  // On-the-wire application error code of the frame.
-  uint64_t ietf_error_code = 0;
-
-  // Returns a tuple of both |error_code| and |ietf_error_code|.
-  QuicResetStreamError error() const {
-    return QuicResetStreamError(error_code, ietf_error_code);
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
diff --git a/quic/core/frames/quic_stop_waiting_frame.cc b/quic/core/frames/quic_stop_waiting_frame.cc
deleted file mode 100644
index c5ce938..0000000
--- a/quic/core/frames/quic_stop_waiting_frame.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_stop_waiting_frame.h"
-
-#include "quic/core/quic_constants.h"
-
-namespace quic {
-
-QuicStopWaitingFrame::QuicStopWaitingFrame()
-    : QuicInlinedFrame(STOP_WAITING_FRAME) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicStopWaitingFrame& sent_info) {
-  os << "{ least_unacked: " << sent_info.least_unacked << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_stop_waiting_frame.h b/quic/core/frames/quic_stop_waiting_frame.h
deleted file mode 100644
index fda5c61..0000000
--- a/quic/core/frames/quic_stop_waiting_frame.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicStopWaitingFrame
-    : public QuicInlinedFrame<QuicStopWaitingFrame> {
-  QuicStopWaitingFrame();
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicStopWaitingFrame& s);
-
-  QuicFrameType type;
-
-  // The lowest packet we've sent which is unacked, and we expect an ack for.
-  QuicPacketNumber least_unacked;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
diff --git a/quic/core/frames/quic_stream_frame.cc b/quic/core/frames/quic_stream_frame.cc
deleted file mode 100644
index c383c8f..0000000
--- a/quic/core/frames/quic_stream_frame.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_stream_frame.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicStreamFrame::QuicStreamFrame() : QuicInlinedFrame(STREAM_FRAME) {}
-
-QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
-                                 bool fin,
-                                 QuicStreamOffset offset,
-                                 absl::string_view data)
-    : QuicStreamFrame(stream_id, fin, offset, data.data(), data.length()) {}
-
-QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
-                                 bool fin,
-                                 QuicStreamOffset offset,
-                                 QuicPacketLength data_length)
-    : QuicStreamFrame(stream_id, fin, offset, nullptr, data_length) {}
-
-QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
-                                 bool fin,
-                                 QuicStreamOffset offset,
-                                 const char* data_buffer,
-                                 QuicPacketLength data_length)
-    : QuicInlinedFrame(STREAM_FRAME),
-      fin(fin),
-      data_length(data_length),
-      stream_id(stream_id),
-      data_buffer(data_buffer),
-      offset(offset) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicStreamFrame& stream_frame) {
-  os << "{ stream_id: " << stream_frame.stream_id
-     << ", fin: " << stream_frame.fin << ", offset: " << stream_frame.offset
-     << ", length: " << stream_frame.data_length << " }\n";
-  return os;
-}
-
-bool QuicStreamFrame::operator==(const QuicStreamFrame& rhs) const {
-  return fin == rhs.fin && data_length == rhs.data_length &&
-         stream_id == rhs.stream_id && data_buffer == rhs.data_buffer &&
-         offset == rhs.offset;
-}
-
-bool QuicStreamFrame::operator!=(const QuicStreamFrame& rhs) const {
-  return !(*this == rhs);
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_stream_frame.h b/quic/core/frames/quic_stream_frame.h
deleted file mode 100644
index 2e2daba..0000000
--- a/quic/core/frames/quic_stream_frame.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
-
-#include <memory>
-#include <ostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-struct QUIC_EXPORT_PRIVATE QuicStreamFrame
-    : public QuicInlinedFrame<QuicStreamFrame> {
-  QuicStreamFrame();
-  QuicStreamFrame(QuicStreamId stream_id,
-                  bool fin,
-                  QuicStreamOffset offset,
-                  absl::string_view data);
-  QuicStreamFrame(QuicStreamId stream_id,
-                  bool fin,
-                  QuicStreamOffset offset,
-                  QuicPacketLength data_length);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                      const QuicStreamFrame& s);
-
-  bool operator==(const QuicStreamFrame& rhs) const;
-
-  bool operator!=(const QuicStreamFrame& rhs) const;
-
-  QuicFrameType type;
-  bool fin = false;
-  QuicPacketLength data_length = 0;
-  // TODO(wub): Change to a QuicUtils::GetInvalidStreamId when it is not version
-  // dependent.
-  QuicStreamId stream_id = -1;
-  const char* data_buffer = nullptr;  // Not owned.
-  QuicStreamOffset offset = 0;        // Location of this data in the stream.
-
-  QuicStreamFrame(QuicStreamId stream_id,
-                  bool fin,
-                  QuicStreamOffset offset,
-                  const char* data_buffer,
-                  QuicPacketLength data_length);
-};
-static_assert(sizeof(QuicStreamFrame) <= 64,
-              "Keep the QuicStreamFrame size to a cacheline.");
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
diff --git a/quic/core/frames/quic_streams_blocked_frame.cc b/quic/core/frames/quic_streams_blocked_frame.cc
deleted file mode 100644
index 4ec8caa..0000000
--- a/quic/core/frames/quic_streams_blocked_frame.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_streams_blocked_frame.h"
-
-namespace quic {
-
-QuicStreamsBlockedFrame::QuicStreamsBlockedFrame()
-    : QuicInlinedFrame(STREAMS_BLOCKED_FRAME) {}
-
-QuicStreamsBlockedFrame::QuicStreamsBlockedFrame(
-    QuicControlFrameId control_frame_id,
-    QuicStreamCount stream_count,
-    bool unidirectional)
-    : QuicInlinedFrame(STREAMS_BLOCKED_FRAME),
-      control_frame_id(control_frame_id),
-      stream_count(stream_count),
-      unidirectional(unidirectional) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicStreamsBlockedFrame& frame) {
-  os << "{ control_frame_id: " << frame.control_frame_id
-     << ", stream count: " << frame.stream_count
-     << ((frame.unidirectional) ? ", unidirectional }\n"
-                                : ", bidirectional }\n");
-
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_streams_blocked_frame.h b/quic/core/frames/quic_streams_blocked_frame.h
deleted file mode 100644
index 2d73890..0000000
--- a/quic/core/frames/quic_streams_blocked_frame.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// IETF format STREAMS_BLOCKED frame.
-// The sender uses this to inform the peer that the sender wished to
-// open a new stream, exceeding the limit on the number of streams.
-struct QUIC_EXPORT_PRIVATE QuicStreamsBlockedFrame
-    : public QuicInlinedFrame<QuicStreamsBlockedFrame> {
-  QuicStreamsBlockedFrame();
-  QuicStreamsBlockedFrame(QuicControlFrameId control_frame_id,
-                          QuicStreamCount stream_count,
-                          bool unidirectional);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicStreamsBlockedFrame& frame);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  // The number of streams that the sender wishes to exceed
-  QuicStreamCount stream_count = 0;
-
-  // Whether uni- or bi-directional streams
-  bool unidirectional = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
diff --git a/quic/core/frames/quic_window_update_frame.cc b/quic/core/frames/quic_window_update_frame.cc
deleted file mode 100644
index c8fef31..0000000
--- a/quic/core/frames/quic_window_update_frame.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/frames/quic_window_update_frame.h"
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-QuicWindowUpdateFrame::QuicWindowUpdateFrame()
-    : QuicInlinedFrame(WINDOW_UPDATE_FRAME) {}
-
-QuicWindowUpdateFrame::QuicWindowUpdateFrame(
-    QuicControlFrameId control_frame_id, QuicStreamId stream_id,
-    QuicByteCount max_data)
-    : QuicInlinedFrame(WINDOW_UPDATE_FRAME),
-      control_frame_id(control_frame_id),
-      stream_id(stream_id),
-      max_data(max_data) {}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicWindowUpdateFrame& window_update_frame) {
-  os << "{ control_frame_id: " << window_update_frame.control_frame_id
-     << ", stream_id: " << window_update_frame.stream_id
-     << ", max_data: " << window_update_frame.max_data << " }\n";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/frames/quic_window_update_frame.h b/quic/core/frames/quic_window_update_frame.h
deleted file mode 100644
index 3a8a1d7..0000000
--- a/quic/core/frames/quic_window_update_frame.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
-#define QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
-
-#include <ostream>
-
-#include "quic/core/frames/quic_inlined_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// Flow control updates per-stream and at the connection level.
-// Based on SPDY's WINDOW_UPDATE frame, but uses an absolute max data bytes
-// rather than a window delta.
-struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame
-    : public QuicInlinedFrame<QuicWindowUpdateFrame> {
-  QuicWindowUpdateFrame();
-  QuicWindowUpdateFrame(QuicControlFrameId control_frame_id,
-                        QuicStreamId stream_id, QuicByteCount max_data);
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os, const QuicWindowUpdateFrame& w);
-
-  QuicFrameType type;
-
-  // A unique identifier of this control frame. 0 when this frame is received,
-  // and non-zero when sent.
-  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
-
-  // The stream this frame applies to.  0 is a special case meaning the overall
-  // connection rather than a specific stream.
-  QuicStreamId stream_id = 0;
-
-  // Maximum data allowed in the stream or connection. The receiver of this
-  // frame must not send data which would exceedes this restriction.
-  QuicByteCount max_data = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
diff --git a/quic/core/handshaker_delegate_interface.h b/quic/core/handshaker_delegate_interface.h
deleted file mode 100644
index 7fbc5ae..0000000
--- a/quic/core/handshaker_delegate_interface.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
-#define QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
-
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-class QuicDecrypter;
-class QuicEncrypter;
-
-// Pure virtual class to get notified when particular handshake events occurred.
-class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
- public:
-  virtual ~HandshakerDelegateInterface() {}
-
-  // Called when new decryption key of |level| is available. Returns true if
-  // decrypter is set successfully, otherwise, returns false.
-  virtual bool OnNewDecryptionKeyAvailable(
-      EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
-      bool set_alternative_decrypter, bool latch_once_used) = 0;
-
-  // Called when new encryption key of |level| is available.
-  virtual void OnNewEncryptionKeyAvailable(
-      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) = 0;
-
-  // Called to set default encryption level to |level|. Only used in QUIC
-  // crypto.
-  virtual void SetDefaultEncryptionLevel(EncryptionLevel level) = 0;
-
-  // Called when both 1-RTT read and write keys are available. Only used in TLS
-  // handshake.
-  virtual void OnTlsHandshakeComplete() = 0;
-
-  // Called to discard old decryption keys to stop processing packets of
-  // encryption |level|.
-  virtual void DiscardOldDecryptionKey(EncryptionLevel level) = 0;
-
-  // Called to discard old encryption keys (and neuter obsolete data).
-  // TODO(fayang): consider to combine this with DiscardOldDecryptionKey.
-  virtual void DiscardOldEncryptionKey(EncryptionLevel level) = 0;
-
-  // Called to neuter ENCRYPTION_INITIAL data (without discarding initial keys).
-  virtual void NeuterUnencryptedData() = 0;
-
-  // Called to neuter data of HANDSHAKE_DATA packet number space. Only used in
-  // QUIC crypto. This is called 1) when a client switches to forward secure
-  // encryption level and 2) a server successfully processes a forward secure
-  // packet.
-  virtual void NeuterHandshakeData() = 0;
-
-  // Called when 0-RTT data is rejected by the server. This is only called in
-  // TLS handshakes and only called on clients.
-  virtual void OnZeroRttRejected(int reason) = 0;
-
-  // Fills in |params| with values from the delegate's QuicConfig.
-  // Returns whether the operation succeeded.
-  virtual bool FillTransportParameters(TransportParameters* params) = 0;
-
-  // Read |params| and apply the values to the delegate's QuicConfig.
-  // On failure, returns a QuicErrorCode and saves a detailed error in
-  // |error_details|.
-  virtual QuicErrorCode ProcessTransportParameters(
-      const TransportParameters& params, bool is_resumption,
-      std::string* error_details) = 0;
-
-  // Called at the end of an handshake operation callback.
-  virtual void OnHandshakeCallbackDone() = 0;
-
-  // Whether a packet flusher is currently attached.
-  virtual bool PacketFlusherAttached() const = 0;
-
-  // Get the QUIC version currently in use. tls_handshaker needs this to pass
-  // to crypto_utils to apply version-dependent HKDF labels.
-  virtual ParsedQuicVersion parsed_version() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
diff --git a/quic/core/http/capsule.cc b/quic/core/http/capsule.cc
deleted file mode 100644
index fd89b38..0000000
--- a/quic/core/http/capsule.cc
+++ /dev/null
@@ -1,749 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/capsule.h"
-
-#include <type_traits>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-std::string CapsuleTypeToString(CapsuleType capsule_type) {
-  switch (capsule_type) {
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      return "REGISTER_DATAGRAM_CONTEXT";
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      return "CLOSE_DATAGRAM_CONTEXT";
-    case CapsuleType::LEGACY_DATAGRAM:
-      return "LEGACY_DATAGRAM";
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      return "DATAGRAM_WITH_CONTEXT";
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      return "DATAGRAM_WITHOUT_CONTEXT";
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      return "REGISTER_DATAGRAM_NO_CONTEXT";
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      return "CLOSE_WEBTRANSPORT_SESSION";
-  }
-  return absl::StrCat("Unknown(", static_cast<uint64_t>(capsule_type), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
-  os << CapsuleTypeToString(capsule_type);
-  return os;
-}
-
-std::string DatagramFormatTypeToString(
-    DatagramFormatType datagram_format_type) {
-  switch (datagram_format_type) {
-    case DatagramFormatType::UDP_PAYLOAD:
-      return "UDP_PAYLOAD";
-    case DatagramFormatType::WEBTRANSPORT:
-      return "WEBTRANSPORT";
-  }
-  return absl::StrCat("Unknown(", static_cast<uint64_t>(datagram_format_type),
-                      ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const DatagramFormatType& datagram_format_type) {
-  os << DatagramFormatTypeToString(datagram_format_type);
-  return os;
-}
-
-std::string ContextCloseCodeToString(ContextCloseCode context_close_code) {
-  switch (context_close_code) {
-    case ContextCloseCode::CLOSE_NO_ERROR:
-      return "NO_ERROR";
-    case ContextCloseCode::UNKNOWN_FORMAT:
-      return "UNKNOWN_FORMAT";
-    case ContextCloseCode::DENIED:
-      return "DENIED";
-    case ContextCloseCode::RESOURCE_LIMIT:
-      return "RESOURCE_LIMIT";
-  }
-  return absl::StrCat("Unknown(", static_cast<uint64_t>(context_close_code),
-                      ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const ContextCloseCode& context_close_code) {
-  os << ContextCloseCodeToString(context_close_code);
-  return os;
-}
-
-Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
-  switch (capsule_type) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      static_assert(
-          std::is_standard_layout<LegacyDatagramCapsule>::value &&
-              std::is_trivially_destructible<LegacyDatagramCapsule>::value,
-          "All capsule structs must have these properties");
-      legacy_datagram_capsule_ = LegacyDatagramCapsule();
-      break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      static_assert(
-          std::is_standard_layout<DatagramWithContextCapsule>::value &&
-              std::is_trivially_destructible<DatagramWithContextCapsule>::value,
-          "All capsule structs must have these properties");
-      datagram_with_context_capsule_ = DatagramWithContextCapsule();
-      break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      static_assert(
-          std::is_standard_layout<DatagramWithoutContextCapsule>::value &&
-              std::is_trivially_destructible<
-                  DatagramWithoutContextCapsule>::value,
-          "All capsule structs must have these properties");
-      datagram_without_context_capsule_ = DatagramWithoutContextCapsule();
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      static_assert(
-          std::is_standard_layout<RegisterDatagramContextCapsule>::value &&
-              std::is_trivially_destructible<
-                  RegisterDatagramContextCapsule>::value,
-          "All capsule structs must have these properties");
-      register_datagram_context_capsule_ = RegisterDatagramContextCapsule();
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      static_assert(
-          std::is_standard_layout<RegisterDatagramNoContextCapsule>::value &&
-              std::is_trivially_destructible<
-                  RegisterDatagramNoContextCapsule>::value,
-          "All capsule structs must have these properties");
-      register_datagram_no_context_capsule_ =
-          RegisterDatagramNoContextCapsule();
-      break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      static_assert(
-          std::is_standard_layout<CloseDatagramContextCapsule>::value &&
-              std::is_trivially_destructible<
-                  CloseDatagramContextCapsule>::value,
-          "All capsule structs must have these properties");
-      close_datagram_context_capsule_ = CloseDatagramContextCapsule();
-      break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      static_assert(
-          std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
-              std::is_trivially_destructible<
-                  CloseWebTransportSessionCapsule>::value,
-          "All capsule structs must have these properties");
-      close_web_transport_session_capsule_ = CloseWebTransportSessionCapsule();
-      break;
-    default:
-      unknown_capsule_data_ = absl::string_view();
-      break;
-  }
-}
-
-// static
-Capsule Capsule::LegacyDatagram(
-    absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view http_datagram_payload) {
-  Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
-  capsule.legacy_datagram_capsule().context_id = context_id;
-  capsule.legacy_datagram_capsule().http_datagram_payload =
-      http_datagram_payload;
-  return capsule;
-}
-
-// static
-Capsule Capsule::DatagramWithContext(QuicDatagramContextId context_id,
-                                     absl::string_view http_datagram_payload) {
-  Capsule capsule(CapsuleType::DATAGRAM_WITH_CONTEXT);
-  capsule.datagram_with_context_capsule().context_id = context_id;
-  capsule.datagram_with_context_capsule().http_datagram_payload =
-      http_datagram_payload;
-  return capsule;
-}
-
-// static
-Capsule Capsule::DatagramWithoutContext(
-    absl::string_view http_datagram_payload) {
-  Capsule capsule(CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
-  capsule.datagram_without_context_capsule().http_datagram_payload =
-      http_datagram_payload;
-  return capsule;
-}
-
-// static
-Capsule Capsule::RegisterDatagramContext(
-    QuicDatagramContextId context_id, DatagramFormatType format_type,
-    absl::string_view format_additional_data) {
-  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_CONTEXT);
-  capsule.register_datagram_context_capsule().context_id = context_id;
-  capsule.register_datagram_context_capsule().format_type = format_type;
-  capsule.register_datagram_context_capsule().format_additional_data =
-      format_additional_data;
-  return capsule;
-}
-
-// static
-Capsule Capsule::RegisterDatagramNoContext(
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
-  capsule.register_datagram_no_context_capsule().format_type = format_type;
-  capsule.register_datagram_no_context_capsule().format_additional_data =
-      format_additional_data;
-  return capsule;
-}
-
-// static
-Capsule Capsule::CloseDatagramContext(QuicDatagramContextId context_id,
-                                      ContextCloseCode close_code,
-                                      absl::string_view close_details) {
-  Capsule capsule(CapsuleType::CLOSE_DATAGRAM_CONTEXT);
-  capsule.close_datagram_context_capsule().context_id = context_id;
-  capsule.close_datagram_context_capsule().close_code = close_code;
-  capsule.close_datagram_context_capsule().close_details = close_details;
-  return capsule;
-}
-
-// static
-Capsule Capsule::CloseWebTransportSession(WebTransportSessionError error_code,
-                                          absl::string_view error_message) {
-  Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
-  capsule.close_web_transport_session_capsule().error_code = error_code;
-  capsule.close_web_transport_session_capsule().error_message = error_message;
-  return capsule;
-}
-
-// static
-Capsule Capsule::Unknown(uint64_t capsule_type,
-                         absl::string_view unknown_capsule_data) {
-  Capsule capsule(static_cast<CapsuleType>(capsule_type));
-  capsule.unknown_capsule_data() = unknown_capsule_data;
-  return capsule;
-}
-
-Capsule& Capsule::operator=(const Capsule& other) {
-  capsule_type_ = other.capsule_type_;
-  switch (capsule_type_) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
-      break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      datagram_with_context_capsule_ = other.datagram_with_context_capsule_;
-      break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      datagram_without_context_capsule_ =
-          other.datagram_without_context_capsule_;
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      register_datagram_context_capsule_ =
-          other.register_datagram_context_capsule_;
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      register_datagram_no_context_capsule_ =
-          other.register_datagram_no_context_capsule_;
-      break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      close_datagram_context_capsule_ = other.close_datagram_context_capsule_;
-      break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      close_web_transport_session_capsule_ =
-          other.close_web_transport_session_capsule_;
-      break;
-    default:
-      unknown_capsule_data_ = other.unknown_capsule_data_;
-      break;
-  }
-  return *this;
-}
-
-Capsule::Capsule(const Capsule& other) : Capsule(other.capsule_type_) {
-  *this = other;
-}
-
-bool Capsule::operator==(const Capsule& other) const {
-  if (capsule_type_ != other.capsule_type_) {
-    return false;
-  }
-  switch (capsule_type_) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      return legacy_datagram_capsule_.context_id ==
-                 other.legacy_datagram_capsule_.context_id &&
-             legacy_datagram_capsule_.http_datagram_payload ==
-                 other.legacy_datagram_capsule_.http_datagram_payload;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      return datagram_with_context_capsule_.context_id ==
-                 other.datagram_with_context_capsule_.context_id &&
-             datagram_with_context_capsule_.http_datagram_payload ==
-                 other.datagram_with_context_capsule_.http_datagram_payload;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      return datagram_without_context_capsule_.http_datagram_payload ==
-             other.datagram_without_context_capsule_.http_datagram_payload;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      return register_datagram_context_capsule_.context_id ==
-                 other.register_datagram_context_capsule_.context_id &&
-             register_datagram_context_capsule_.format_type ==
-                 other.register_datagram_context_capsule_.format_type &&
-             register_datagram_context_capsule_.format_additional_data ==
-                 other.register_datagram_context_capsule_
-                     .format_additional_data;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      return register_datagram_no_context_capsule_.format_type ==
-                 other.register_datagram_no_context_capsule_.format_type &&
-             register_datagram_no_context_capsule_.format_additional_data ==
-                 other.register_datagram_no_context_capsule_
-                     .format_additional_data;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      return close_datagram_context_capsule_.context_id ==
-                 other.close_datagram_context_capsule_.context_id &&
-             close_datagram_context_capsule_.close_code ==
-                 other.close_datagram_context_capsule_.close_code &&
-             close_datagram_context_capsule_.close_details ==
-                 other.close_datagram_context_capsule_.close_details;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      return close_web_transport_session_capsule_.error_code ==
-                 other.close_web_transport_session_capsule_.error_code &&
-             close_web_transport_session_capsule_.error_message ==
-                 other.close_web_transport_session_capsule_.error_message;
-    default:
-      return unknown_capsule_data_ == other.unknown_capsule_data_;
-  }
-}
-
-std::string Capsule::ToString() const {
-  std::string rv = CapsuleTypeToString(capsule_type_);
-  switch (capsule_type_) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      if (legacy_datagram_capsule_.context_id.has_value()) {
-        absl::StrAppend(&rv, "(", legacy_datagram_capsule_.context_id.value(),
-                        ")");
-      }
-      absl::StrAppend(&rv, "[",
-                      absl::BytesToHexString(
-                          legacy_datagram_capsule_.http_datagram_payload),
-                      "]");
-      break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      absl::StrAppend(&rv, "(", datagram_with_context_capsule_.context_id, ")[",
-                      absl::BytesToHexString(
-                          datagram_with_context_capsule_.http_datagram_payload),
-                      "]");
-      break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      absl::StrAppend(
-          &rv, "[",
-          absl::BytesToHexString(
-              datagram_without_context_capsule_.http_datagram_payload),
-          "]");
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      absl::StrAppend(
-          &rv, "(context_id=", register_datagram_context_capsule_.context_id,
-          ",format_type=",
-          DatagramFormatTypeToString(
-              register_datagram_context_capsule_.format_type),
-          "){",
-          absl::BytesToHexString(
-              register_datagram_context_capsule_.format_additional_data),
-          "}");
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      absl::StrAppend(
-          &rv, "(format_type=",
-          DatagramFormatTypeToString(
-              register_datagram_no_context_capsule_.format_type),
-          "){",
-          absl::BytesToHexString(
-              register_datagram_no_context_capsule_.format_additional_data),
-          "}");
-      break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      absl::StrAppend(
-          &rv, "(context_id=", close_datagram_context_capsule_.context_id,
-          ",close_code=",
-          ContextCloseCodeToString(close_datagram_context_capsule_.close_code),
-          ",close_details=\"",
-          absl::BytesToHexString(close_datagram_context_capsule_.close_details),
-          "\")");
-      break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      absl::StrAppend(
-          &rv, "(error_code=", close_web_transport_session_capsule_.error_code,
-          ",error_message=\"",
-          close_web_transport_session_capsule_.error_message, "\")");
-      break;
-    default:
-      absl::StrAppend(&rv, "[", absl::BytesToHexString(unknown_capsule_data_),
-                      "]");
-      break;
-  }
-  return rv;
-}
-
-std::ostream& operator<<(std::ostream& os, const Capsule& capsule) {
-  os << capsule.ToString();
-  return os;
-}
-
-CapsuleParser::CapsuleParser(Visitor* visitor) : visitor_(visitor) {
-  QUICHE_DCHECK_NE(visitor_, nullptr);
-}
-
-quiche::QuicheBuffer SerializeCapsule(
-    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator) {
-  QuicByteCount capsule_type_length = QuicDataWriter::GetVarInt62Len(
-      static_cast<uint64_t>(capsule.capsule_type()));
-  QuicByteCount capsule_data_length;
-  switch (capsule.capsule_type()) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      capsule_data_length =
-          capsule.legacy_datagram_capsule().http_datagram_payload.length();
-      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
-        capsule_data_length += QuicDataWriter::GetVarInt62Len(
-            capsule.legacy_datagram_capsule().context_id.value());
-      }
-      break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(
-              capsule.datagram_with_context_capsule().context_id) +
-          capsule.datagram_with_context_capsule()
-              .http_datagram_payload.length();
-      break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      capsule_data_length = capsule.datagram_without_context_capsule()
-                                .http_datagram_payload.length();
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(
-              capsule.register_datagram_context_capsule().context_id) +
-          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
-              capsule.register_datagram_context_capsule().format_type)) +
-          capsule.register_datagram_context_capsule()
-              .format_additional_data.length();
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
-              capsule.register_datagram_no_context_capsule().format_type)) +
-          capsule.register_datagram_no_context_capsule()
-              .format_additional_data.length();
-      break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      capsule_data_length =
-          QuicDataWriter::GetVarInt62Len(
-              capsule.close_datagram_context_capsule().context_id) +
-          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
-              capsule.close_datagram_context_capsule().close_code)) +
-          capsule.close_datagram_context_capsule().close_details.length();
-      break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      capsule_data_length =
-          sizeof(WebTransportSessionError) +
-          capsule.close_web_transport_session_capsule().error_message.size();
-      break;
-    default:
-      capsule_data_length = capsule.unknown_capsule_data().length();
-      break;
-  }
-  QuicByteCount capsule_length_length =
-      QuicDataWriter::GetVarInt62Len(capsule_data_length);
-  QuicByteCount total_capsule_length =
-      capsule_type_length + capsule_length_length + capsule_data_length;
-  quiche::QuicheBuffer buffer(allocator, total_capsule_length);
-  QuicDataWriter writer(buffer.size(), buffer.data());
-  if (!writer.WriteVarInt62(static_cast<uint64_t>(capsule.capsule_type()))) {
-    QUIC_BUG(capsule type write fail) << "Failed to write CAPSULE type";
-    return {};
-  }
-  if (!writer.WriteVarInt62(capsule_data_length)) {
-    QUIC_BUG(capsule length write fail) << "Failed to write CAPSULE length";
-    return {};
-  }
-  switch (capsule.capsule_type()) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
-        if (!writer.WriteVarInt62(
-                capsule.legacy_datagram_capsule().context_id.value())) {
-          QUIC_BUG(datagram capsule context ID write fail)
-              << "Failed to write LEGACY_DATAGRAM CAPSULE context ID";
-          return {};
-        }
-      }
-      if (!writer.WriteStringPiece(
-              capsule.legacy_datagram_capsule().http_datagram_payload)) {
-        QUIC_BUG(datagram capsule payload write fail)
-            << "Failed to write LEGACY_DATAGRAM CAPSULE payload";
-        return {};
-      }
-      break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      if (!writer.WriteVarInt62(
-              capsule.datagram_with_context_capsule().context_id)) {
-        QUIC_BUG(datagram capsule context ID write fail)
-            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE context ID";
-        return {};
-      }
-      if (!writer.WriteStringPiece(
-              capsule.datagram_with_context_capsule().http_datagram_payload)) {
-        QUIC_BUG(datagram capsule payload write fail)
-            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE payload";
-        return {};
-      }
-      break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
-                                       .http_datagram_payload)) {
-        QUIC_BUG(datagram capsule payload write fail)
-            << "Failed to write DATAGRAM_WITHOUT_CONTEXT CAPSULE payload";
-        return {};
-      }
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      if (!writer.WriteVarInt62(
-              capsule.register_datagram_context_capsule().context_id)) {
-        QUIC_BUG(register context capsule context ID write fail)
-            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE context ID";
-        return {};
-      }
-      if (!writer.WriteVarInt62(static_cast<uint64_t>(
-              capsule.register_datagram_context_capsule().format_type))) {
-        QUIC_BUG(register context capsule format type write fail)
-            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE format type";
-        return {};
-      }
-      if (!writer.WriteStringPiece(capsule.register_datagram_context_capsule()
-                                       .format_additional_data)) {
-        QUIC_BUG(register context capsule additional data write fail)
-            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE additional "
-               "data";
-        return {};
-      }
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      if (!writer.WriteVarInt62(static_cast<uint64_t>(
-              capsule.register_datagram_no_context_capsule().format_type))) {
-        QUIC_BUG(register no context capsule format type write fail)
-            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE format "
-               "type";
-        return {};
-      }
-      if (!writer.WriteStringPiece(
-              capsule.register_datagram_no_context_capsule()
-                  .format_additional_data)) {
-        QUIC_BUG(register no context capsule additional data write fail)
-            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE "
-               "additional data";
-        return {};
-      }
-      break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      if (!writer.WriteVarInt62(
-              capsule.close_datagram_context_capsule().context_id)) {
-        QUIC_BUG(close context capsule context ID write fail)
-            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE context ID";
-        return {};
-      }
-      if (!writer.WriteVarInt62(static_cast<uint64_t>(
-              capsule.close_datagram_context_capsule().close_code))) {
-        QUIC_BUG(close context capsule close code write fail)
-            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close code";
-        return {};
-      }
-      if (!writer.WriteStringPiece(
-              capsule.close_datagram_context_capsule().close_details)) {
-        QUIC_BUG(close context capsule close details write fail)
-            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close details";
-        return {};
-      }
-      break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      if (!writer.WriteUInt32(
-              capsule.close_web_transport_session_capsule().error_code)) {
-        QUIC_BUG(close webtransport session capsule error code write fail)
-            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error code";
-        return {};
-      }
-      if (!writer.WriteStringPiece(
-              capsule.close_web_transport_session_capsule().error_message)) {
-        QUIC_BUG(close webtransport session capsule error message write fail)
-            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error message";
-        return {};
-      }
-      break;
-    default:
-      if (!writer.WriteStringPiece(capsule.unknown_capsule_data())) {
-        QUIC_BUG(capsule data write fail) << "Failed to write CAPSULE data";
-        return {};
-      }
-      break;
-  }
-  if (writer.remaining() != 0) {
-    QUIC_BUG(capsule write length mismatch)
-        << "CAPSULE serialization wrote " << writer.length() << " instead of "
-        << writer.capacity();
-    return {};
-  }
-  return buffer;
-}
-
-bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
-  if (parsing_error_occurred_) {
-    return false;
-  }
-  absl::StrAppend(&buffered_data_, capsule_fragment);
-  while (true) {
-    const size_t buffered_data_read = AttemptParseCapsule();
-    if (parsing_error_occurred_) {
-      QUICHE_DCHECK_EQ(buffered_data_read, 0u);
-      buffered_data_.clear();
-      return false;
-    }
-    if (buffered_data_read == 0) {
-      break;
-    }
-    buffered_data_.erase(0, buffered_data_read);
-  }
-  static constexpr size_t kMaxCapsuleBufferSize = 1024 * 1024;
-  if (buffered_data_.size() > kMaxCapsuleBufferSize) {
-    buffered_data_.clear();
-    ReportParseFailure("Refusing to buffer too much capsule data");
-    return false;
-  }
-  return true;
-}
-
-size_t CapsuleParser::AttemptParseCapsule() {
-  QUICHE_DCHECK(!parsing_error_occurred_);
-  if (buffered_data_.empty()) {
-    return 0;
-  }
-  QuicDataReader capsule_fragment_reader(buffered_data_);
-  uint64_t capsule_type64;
-  if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
-    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule type";
-    return 0;
-  }
-  absl::string_view capsule_data;
-  if (!capsule_fragment_reader.ReadStringPieceVarInt62(&capsule_data)) {
-    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule length or "
-                     "full capsule data";
-    return 0;
-  }
-  QuicDataReader capsule_data_reader(capsule_data);
-  Capsule capsule(static_cast<CapsuleType>(capsule_type64));
-  switch (capsule.capsule_type()) {
-    case CapsuleType::LEGACY_DATAGRAM:
-      if (datagram_context_id_present_) {
-        uint64_t context_id;
-        if (!capsule_data_reader.ReadVarInt62(&context_id)) {
-          ReportParseFailure(
-              "Unable to parse capsule LEGACY_DATAGRAM context ID");
-          return 0;
-        }
-        capsule.legacy_datagram_capsule().context_id = context_id;
-      }
-      capsule.legacy_datagram_capsule().http_datagram_payload =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT:
-      uint64_t context_id;
-      if (!capsule_data_reader.ReadVarInt62(&context_id)) {
-        ReportParseFailure(
-            "Unable to parse capsule DATAGRAM_WITH_CONTEXT context ID");
-        return 0;
-      }
-      capsule.datagram_with_context_capsule().context_id = context_id;
-      capsule.datagram_with_context_capsule().http_datagram_payload =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
-      capsule.datagram_without_context_capsule().http_datagram_payload =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
-      if (!capsule_data_reader.ReadVarInt62(
-              &capsule.register_datagram_context_capsule().context_id)) {
-        ReportParseFailure(
-            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT context ID");
-        return 0;
-      }
-      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
-              &capsule.register_datagram_context_capsule().format_type))) {
-        ReportParseFailure(
-            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT format type");
-        return 0;
-      }
-      capsule.register_datagram_context_capsule().format_additional_data =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
-      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
-              &capsule.register_datagram_no_context_capsule().format_type))) {
-        ReportParseFailure(
-            "Unable to parse capsule REGISTER_DATAGRAM_NO_CONTEXT format type");
-        return 0;
-      }
-      capsule.register_datagram_no_context_capsule().format_additional_data =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
-      if (!capsule_data_reader.ReadVarInt62(
-              &capsule.close_datagram_context_capsule().context_id)) {
-        ReportParseFailure(
-            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT context ID");
-        return 0;
-      }
-      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
-              &capsule.close_datagram_context_capsule().close_code))) {
-        ReportParseFailure(
-            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT close code");
-        return 0;
-      }
-      capsule.close_datagram_context_capsule().close_details =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
-      if (!capsule_data_reader.ReadUInt32(
-              &capsule.close_web_transport_session_capsule().error_code)) {
-        ReportParseFailure(
-            "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
-        return 0;
-      }
-      capsule.close_web_transport_session_capsule().error_message =
-          capsule_data_reader.ReadRemainingPayload();
-      break;
-    default:
-      capsule.unknown_capsule_data() =
-          capsule_data_reader.ReadRemainingPayload();
-  }
-  if (!visitor_->OnCapsule(capsule)) {
-    ReportParseFailure("Visitor failed to process capsule");
-    return 0;
-  }
-  return capsule_fragment_reader.PreviouslyReadPayload().length();
-}
-
-void CapsuleParser::ReportParseFailure(const std::string& error_message) {
-  if (parsing_error_occurred_) {
-    QUIC_BUG(multiple parse errors) << "Experienced multiple parse failures";
-    return;
-  }
-  parsing_error_occurred_ = true;
-  visitor_->OnCapsuleParseFailure(error_message);
-}
-
-void CapsuleParser::ErrorIfThereIsRemainingBufferedData() {
-  if (parsing_error_occurred_) {
-    return;
-  }
-  if (!buffered_data_.empty()) {
-    ReportParseFailure("Incomplete capsule left at the end of the stream");
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/http/capsule.h b/quic/core/http/capsule.h
deleted file mode 100644
index 94601f9..0000000
--- a/quic/core/http/capsule.h
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
-#define QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_types.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quic {
-
-enum class CapsuleType : uint64_t {
-  // Casing in this enum matches the IETF specification.
-  LEGACY_DATAGRAM = 0xff37a0,  // draft-ietf-masque-h3-datagram-04
-  REGISTER_DATAGRAM_CONTEXT = 0xff37a1,
-  REGISTER_DATAGRAM_NO_CONTEXT = 0xff37a2,
-  CLOSE_DATAGRAM_CONTEXT = 0xff37a3,
-  DATAGRAM_WITH_CONTEXT = 0xff37a4,
-  DATAGRAM_WITHOUT_CONTEXT = 0xff37a5,
-  CLOSE_WEBTRANSPORT_SESSION = 0x2843,
-};
-
-QUIC_EXPORT_PRIVATE std::string CapsuleTypeToString(CapsuleType capsule_type);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const CapsuleType& capsule_type);
-
-enum class DatagramFormatType : uint64_t {
-  // Casing in this enum matches the IETF specification.
-  UDP_PAYLOAD = 0xff6f00,
-  WEBTRANSPORT = 0xff7c00,
-};
-
-QUIC_EXPORT_PRIVATE std::string DatagramFormatTypeToString(
-    DatagramFormatType datagram_format_type);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const DatagramFormatType& datagram_format_type);
-
-enum class ContextCloseCode : uint64_t {
-  // Casing in this enum matches the IETF specification.
-  CLOSE_NO_ERROR = 0xff78a0,  // NO_ERROR already exists in winerror.h.
-  UNKNOWN_FORMAT = 0xff78a1,
-  DENIED = 0xff78a2,
-  RESOURCE_LIMIT = 0xff78a3,
-};
-
-QUIC_EXPORT_PRIVATE std::string ContextCloseCodeToString(
-    ContextCloseCode context_close_code);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const ContextCloseCode& context_close_code);
-
-struct QUIC_EXPORT_PRIVATE LegacyDatagramCapsule {
-  absl::optional<QuicDatagramContextId> context_id;
-  absl::string_view http_datagram_payload;
-};
-struct QUIC_EXPORT_PRIVATE DatagramWithContextCapsule {
-  QuicDatagramContextId context_id;
-  absl::string_view http_datagram_payload;
-};
-struct QUIC_EXPORT_PRIVATE DatagramWithoutContextCapsule {
-  absl::string_view http_datagram_payload;
-};
-struct QUIC_EXPORT_PRIVATE RegisterDatagramContextCapsule {
-  QuicDatagramContextId context_id;
-  DatagramFormatType format_type;
-  absl::string_view format_additional_data;
-};
-struct QUIC_EXPORT_PRIVATE RegisterDatagramNoContextCapsule {
-  DatagramFormatType format_type;
-  absl::string_view format_additional_data;
-};
-struct QUIC_EXPORT_PRIVATE CloseDatagramContextCapsule {
-  QuicDatagramContextId context_id;
-  ContextCloseCode close_code;
-  absl::string_view close_details;
-};
-struct QUIC_EXPORT_PRIVATE CloseWebTransportSessionCapsule {
-  WebTransportSessionError error_code;
-  absl::string_view error_message;
-};
-
-// Capsule from draft-ietf-masque-h3-datagram.
-// IMPORTANT NOTE: Capsule does not own any of the absl::string_view memory it
-// points to. Strings saved into a capsule must outlive the capsule object. Any
-// code that sees a capsule in a callback needs to either process it immediately
-// or perform its own deep copy.
-class QUIC_EXPORT_PRIVATE Capsule {
- public:
-  static Capsule LegacyDatagram(
-      absl::optional<QuicDatagramContextId> context_id = absl::nullopt,
-      absl::string_view http_datagram_payload = absl::string_view());
-  static Capsule DatagramWithContext(
-      QuicDatagramContextId context_id,
-      absl::string_view http_datagram_payload = absl::string_view());
-  static Capsule DatagramWithoutContext(
-      absl::string_view http_datagram_payload = absl::string_view());
-  static Capsule RegisterDatagramContext(
-      QuicDatagramContextId context_id, DatagramFormatType format_type,
-      absl::string_view format_additional_data = absl::string_view());
-  static Capsule RegisterDatagramNoContext(
-      DatagramFormatType format_type,
-      absl::string_view format_additional_data = absl::string_view());
-  static Capsule CloseDatagramContext(
-      QuicDatagramContextId context_id,
-      ContextCloseCode close_code = ContextCloseCode::CLOSE_NO_ERROR,
-      absl::string_view close_details = absl::string_view());
-  static Capsule CloseWebTransportSession(
-      WebTransportSessionError error_code = 0,
-      absl::string_view error_message = "");
-  static Capsule Unknown(
-      uint64_t capsule_type,
-      absl::string_view unknown_capsule_data = absl::string_view());
-
-  explicit Capsule(CapsuleType capsule_type);
-  Capsule(const Capsule& other);
-  Capsule& operator=(const Capsule& other);
-  bool operator==(const Capsule& other) const;
-
-  // Human-readable information string for debugging purposes.
-  std::string ToString() const;
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                      const Capsule& capsule);
-
-  CapsuleType capsule_type() const { return capsule_type_; }
-  LegacyDatagramCapsule& legacy_datagram_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
-    return legacy_datagram_capsule_;
-  }
-  const LegacyDatagramCapsule& legacy_datagram_capsule() const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
-    return legacy_datagram_capsule_;
-  }
-  DatagramWithContextCapsule& datagram_with_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
-    return datagram_with_context_capsule_;
-  }
-  const DatagramWithContextCapsule& datagram_with_context_capsule() const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
-    return datagram_with_context_capsule_;
-  }
-  DatagramWithoutContextCapsule& datagram_without_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
-    return datagram_without_context_capsule_;
-  }
-  const DatagramWithoutContextCapsule& datagram_without_context_capsule()
-      const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
-    return datagram_without_context_capsule_;
-  }
-  RegisterDatagramContextCapsule& register_datagram_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
-    return register_datagram_context_capsule_;
-  }
-  const RegisterDatagramContextCapsule& register_datagram_context_capsule()
-      const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
-    return register_datagram_context_capsule_;
-  }
-  RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
-    return register_datagram_no_context_capsule_;
-  }
-  const RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule()
-      const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
-    return register_datagram_no_context_capsule_;
-  }
-  CloseDatagramContextCapsule& close_datagram_context_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
-    return close_datagram_context_capsule_;
-  }
-  const CloseDatagramContextCapsule& close_datagram_context_capsule() const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
-    return close_datagram_context_capsule_;
-  }
-  CloseWebTransportSessionCapsule& close_web_transport_session_capsule() {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
-    return close_web_transport_session_capsule_;
-  }
-  const CloseWebTransportSessionCapsule& close_web_transport_session_capsule()
-      const {
-    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
-    return close_web_transport_session_capsule_;
-  }
-  absl::string_view& unknown_capsule_data() {
-    QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
-                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
-                  capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
-                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
-                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
-                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
-                  capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
-        << capsule_type_;
-    return unknown_capsule_data_;
-  }
-  const absl::string_view& unknown_capsule_data() const {
-    QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
-                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
-                  capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
-                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
-                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
-                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
-                  capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
-        << capsule_type_;
-    return unknown_capsule_data_;
-  }
-
- private:
-  CapsuleType capsule_type_;
-  union {
-    LegacyDatagramCapsule legacy_datagram_capsule_;
-    DatagramWithContextCapsule datagram_with_context_capsule_;
-    DatagramWithoutContextCapsule datagram_without_context_capsule_;
-    RegisterDatagramContextCapsule register_datagram_context_capsule_;
-    RegisterDatagramNoContextCapsule register_datagram_no_context_capsule_;
-    CloseDatagramContextCapsule close_datagram_context_capsule_;
-    CloseWebTransportSessionCapsule close_web_transport_session_capsule_;
-    absl::string_view unknown_capsule_data_;
-  };
-};
-
-namespace test {
-class CapsuleParserPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE CapsuleParser {
- public:
-  class QUIC_EXPORT_PRIVATE Visitor {
-   public:
-    virtual ~Visitor() {}
-
-    // Called when a capsule has been successfully parsed. The return value
-    // indicates whether the contents of the capsule are valid: if false is
-    // returned, the parse operation will be considered failed and
-    // OnCapsuleParseFailure will be called. Note that since Capsule does not
-    // own the memory backing its string_views, that memory is only valid until
-    // this callback returns. Visitors that wish to access the capsule later
-    // MUST make a deep copy before this returns.
-    virtual bool OnCapsule(const Capsule& capsule) = 0;
-
-    virtual void OnCapsuleParseFailure(const std::string& error_message) = 0;
-  };
-
-  // |visitor| must be non-null, and must outlive CapsuleParser.
-  explicit CapsuleParser(Visitor* visitor);
-
-  void set_datagram_context_id_present(bool datagram_context_id_present) {
-    datagram_context_id_present_ = datagram_context_id_present;
-  }
-
-  // Ingests a capsule fragment (any fragment of bytes from the capsule data
-  // stream) and parses and complete capsules it encounters. Returns false if a
-  // parsing error occurred.
-  bool IngestCapsuleFragment(absl::string_view capsule_fragment);
-
-  void ErrorIfThereIsRemainingBufferedData();
-
-  friend class test::CapsuleParserPeer;
-
- private:
-  // Attempts to parse a single capsule from |buffered_data_|. If a full capsule
-  // is not available, returns 0. If a parsing error occurs, returns 0.
-  // Otherwise, returns the number of bytes in the parsed capsule.
-  size_t AttemptParseCapsule();
-  void ReportParseFailure(const std::string& error_message);
-
-  // Whether HTTP Datagram Context IDs are present.
-  bool datagram_context_id_present_ = false;
-  // Whether a parsing error has occurred.
-  bool parsing_error_occurred_ = false;
-  // Visitor which will receive callbacks, unowned.
-  Visitor* visitor_;
-
-  std::string buffered_data_;
-};
-
-// Serializes |capsule| into a newly allocated buffer.
-QUIC_EXPORT_PRIVATE quiche::QuicheBuffer SerializeCapsule(
-    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
diff --git a/quic/core/http/capsule_test.cc b/quic/core/http/capsule_test.cc
deleted file mode 100644
index c971826..0000000
--- a/quic/core/http/capsule_test.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/capsule.h"
-
-#include <cstddef>
-#include <deque>
-#include <string>
-#include <vector>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using ::testing::_;
-using ::testing::InSequence;
-using ::testing::Return;
-
-namespace quic {
-namespace test {
-
-class CapsuleParserPeer {
- public:
-  static std::string* buffered_data(CapsuleParser* capsule_parser) {
-    return &capsule_parser->buffered_data_;
-  }
-};
-
-namespace {
-
-constexpr DatagramFormatType kFakeFormatType =
-    static_cast<DatagramFormatType>(0x123456);
-constexpr ContextCloseCode kFakeCloseCode =
-    static_cast<ContextCloseCode>(0x654321);
-
-class MockCapsuleParserVisitor : public CapsuleParser::Visitor {
- public:
-  MockCapsuleParserVisitor() {
-    ON_CALL(*this, OnCapsule(_)).WillByDefault(Return(true));
-  }
-  ~MockCapsuleParserVisitor() override = default;
-  MOCK_METHOD(bool, OnCapsule, (const Capsule& capsule), (override));
-  MOCK_METHOD(void, OnCapsuleParseFailure, (const std::string& error_message),
-              (override));
-};
-
-class CapsuleTest : public QuicTest {
- public:
-  CapsuleTest() : capsule_parser_(&visitor_) {}
-
-  void ValidateParserIsEmpty() {
-    EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
-    EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
-    capsule_parser_.ErrorIfThereIsRemainingBufferedData();
-    EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
-  }
-
-  void TestSerialization(const Capsule& capsule,
-                         const std::string& expected_bytes) {
-    quiche::QuicheBuffer serialized_capsule =
-        SerializeCapsule(capsule, quiche::SimpleBufferAllocator::Get());
-    quiche::test::CompareCharArraysWithHexError(
-        "Serialized capsule", serialized_capsule.data(),
-        serialized_capsule.size(), expected_bytes.data(),
-        expected_bytes.size());
-  }
-
-  ::testing::StrictMock<MockCapsuleParserVisitor> visitor_;
-  CapsuleParser capsule_parser_;
-};
-
-TEST_F(CapsuleTest, LegacyDatagramCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a0"          // LEGACY_DATAGRAM capsule type
-      "08"                // capsule length
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-  );
-  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule =
-      Capsule::LegacyDatagram(/*context_id=*/absl::nullopt, datagram_payload);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, LegacyDatagramCapsuleWithContext) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a0"          // LEGACY_DATAGRAM capsule type
-      "09"                // capsule length
-      "04"                // context ID
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-  );
-  capsule_parser_.set_datagram_context_id_present(true);
-  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule =
-      Capsule::LegacyDatagram(/*context_id=*/4, datagram_payload);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, DatagramWithoutContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"                // capsule length
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-  );
-  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule = Capsule::DatagramWithoutContext(datagram_payload);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, DatagramWithContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a4"          // DATAGRAM_WITH_CONTEXT capsule type
-      "09"                // capsule length
-      "04"                // context ID
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-  );
-  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule =
-      Capsule::DatagramWithContext(/*context_id=*/4, datagram_payload);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, RegisterContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a1"          // REGISTER_DATAGRAM_CONTEXT capsule type
-      "0d"                // capsule length
-      "04"                // context ID
-      "80123456"          // 0x123456 datagram format type
-      "f1f2f3f4f5f6f7f8"  // format additional data
-  );
-  std::string format_additional_data =
-      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
-  Capsule expected_capsule = Capsule::RegisterDatagramContext(
-      /*context_id=*/4, kFakeFormatType, format_additional_data);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, RegisterNoContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a2"          // REGISTER_DATAGRAM_NO_CONTEXT capsule type
-      "0c"                // capsule length
-      "80123456"          // 0x123456 datagram format type
-      "f1f2f3f4f5f6f7f8"  // format additional data
-  );
-  std::string format_additional_data =
-      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
-  Capsule expected_capsule = Capsule::RegisterDatagramNoContext(
-      kFakeFormatType, format_additional_data);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, CloseContextCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a3"  // CLOSE_DATAGRAM_CONTEXT capsule type
-      "27"        // capsule length
-      "04"        // context ID
-      "80654321"  // 0x654321 close code
-  );
-  std::string close_details = "All your contexts are belong to us";
-  capsule_fragment += close_details;
-  Capsule expected_capsule = Capsule::CloseDatagramContext(
-      /*context_id=*/4, kFakeCloseCode, close_details);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, CloseWebTransportStreamCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "6843"        // CLOSE_WEBTRANSPORT_STREAM capsule type
-      "09"          // capsule length
-      "00001234"    // 0x1234 error code
-      "68656c6c6f"  // "hello" error message
-  );
-  Capsule expected_capsule = Capsule::CloseWebTransportSession(
-      /*error_code=*/0x1234, /*error_message=*/"hello");
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, UnknownCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "33"                // unknown capsule type of 0x33
-      "08"                // capsule length
-      "a1a2a3a4a5a6a7a8"  // unknown capsule data
-  );
-  std::string unknown_capsule_data = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  Capsule expected_capsule = Capsule::Unknown(0x33, unknown_capsule_data);
-  {
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-  TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, TwoCapsules) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"                // capsule length
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"                // capsule length
-      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload
-  );
-  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
-  Capsule expected_capsule1 =
-      Capsule::DatagramWithoutContext(datagram_payload1);
-  Capsule expected_capsule2 =
-      Capsule::DatagramWithoutContext(datagram_payload2);
-  {
-    InSequence s;
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  ValidateParserIsEmpty();
-}
-
-TEST_F(CapsuleTest, TwoCapsulesPartialReads) {
-  std::string capsule_fragment1 = absl::HexStringToBytes(
-      "80ff37a5"  // first capsule DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"        // frist capsule length
-      "a1a2a3a4"  // first half of HTTP Datagram payload of first capsule
-  );
-  std::string capsule_fragment2 = absl::HexStringToBytes(
-      "a5a6a7a8"  // second half of HTTP Datagram payload 1
-      "80ff37a5"  // second capsule DATAGRAM_WITHOUT_CONTEXT capsule type
-  );
-  std::string capsule_fragment3 = absl::HexStringToBytes(
-      "08"                // second capsule length
-      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload of second capsule
-  );
-  capsule_parser_.ErrorIfThereIsRemainingBufferedData();
-  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
-  Capsule expected_capsule1 =
-      Capsule::DatagramWithoutContext(datagram_payload1);
-  Capsule expected_capsule2 =
-      Capsule::DatagramWithoutContext(datagram_payload2);
-  {
-    InSequence s;
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
-    EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment1));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment2));
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment3));
-  }
-  ValidateParserIsEmpty();
-}
-
-TEST_F(CapsuleTest, TwoCapsulesOneByteAtATime) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"                // capsule length
-      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
-      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"                // capsule length
-      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload
-  );
-  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
-  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
-  Capsule expected_capsule1 =
-      Capsule::DatagramWithoutContext(datagram_payload1);
-  Capsule expected_capsule2 =
-      Capsule::DatagramWithoutContext(datagram_payload2);
-  for (size_t i = 0; i < capsule_fragment.size(); i++) {
-    if (i < capsule_fragment.size() / 2 - 1) {
-      EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
-      ASSERT_TRUE(
-          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
-    } else if (i == capsule_fragment.size() / 2 - 1) {
-      EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
-      ASSERT_TRUE(
-          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
-      EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
-    } else if (i < capsule_fragment.size() - 1) {
-      EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
-      ASSERT_TRUE(
-          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
-    } else {
-      EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
-      ASSERT_TRUE(
-          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
-      EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
-    }
-  }
-  capsule_parser_.ErrorIfThereIsRemainingBufferedData();
-  EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
-}
-
-TEST_F(CapsuleTest, PartialCapsuleThenError) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-      "80ff37a5"  // DATAGRAM_WITHOUT_CONTEXT capsule type
-      "08"        // capsule length
-      "a1a2a3a4"  // first half of HTTP Datagram payload
-  );
-  EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
-  {
-    EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
-    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-  }
-  {
-    EXPECT_CALL(visitor_,
-                OnCapsuleParseFailure(
-                    "Incomplete capsule left at the end of the stream"));
-    capsule_parser_.ErrorIfThereIsRemainingBufferedData();
-  }
-}
-
-TEST_F(CapsuleTest, RejectOverlyLongCapsule) {
-  std::string capsule_fragment = absl::HexStringToBytes(
-                                     "33"        // unknown capsule type of 0x33
-                                     "80123456"  // capsule length
-                                     ) +
-                                 std::string(1111111, '?');
-  EXPECT_CALL(visitor_, OnCapsuleParseFailure(
-                            "Refusing to buffer too much capsule data"));
-  EXPECT_FALSE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
deleted file mode 100644
index b995d39..0000000
--- a/quic/core/http/end_to_end_test.cc
+++ /dev/null
@@ -1,6908 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/time/clock.h"
-#include "absl/time/time.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_client_session_cache.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/test_tools/bad_packet_writer.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/packet_dropping_test_writer.h"
-#include "quic/test_tools/packet_reordering_writer.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "quic/test_tools/quic_client_peer.h"
-#include "quic/test_tools/quic_client_session_cache_peer.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_server_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_backend.h"
-#include "quic/test_tools/quic_test_client.h"
-#include "quic/test_tools/quic_test_server.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-#include "quic/test_tools/server_thread.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_client.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_server.h"
-#include "quic/tools/quic_simple_client_stream.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-using spdy::kV3LowestPriority;
-using spdy::SpdyFramer;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdySerializedFrame;
-using spdy::SpdySettingsIR;
-using ::testing::_;
-using ::testing::Assign;
-using ::testing::Invoke;
-using ::testing::NiceMock;
-using ::testing::UnorderedElementsAreArray;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kFooResponseBody[] = "Artichoke hearts make me happy.";
-const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
-const char kTestUserAgentId[] = "quic/core/http/end_to_end_test.cc";
-const float kSessionToStreamRatio = 1.5;
-
-// Run all tests with the cross products of all versions.
-struct TestParams {
-  TestParams(const ParsedQuicVersion& version, QuicTag congestion_control_tag)
-      : version(version), congestion_control_tag(congestion_control_tag) {}
-
-  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
-    os << "{ version: " << ParsedQuicVersionToString(p.version);
-    os << " congestion_control_tag: "
-       << QuicTagToString(p.congestion_control_tag) << " }";
-    return os;
-  }
-
-  ParsedQuicVersion version;
-  QuicTag congestion_control_tag;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  std::string rv = absl::StrCat(ParsedQuicVersionToString(p.version), "_",
-                                QuicTagToString(p.congestion_control_tag));
-  std::replace(rv.begin(), rv.end(), ',', '_');
-  std::replace(rv.begin(), rv.end(), ' ', '_');
-  return rv;
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC, kB2ON}) {
-    if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
-        congestion_control_tag == kB2ON) {
-      continue;
-    }
-    for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
-      params.push_back(TestParams(version, congestion_control_tag));
-    }  // End of outer version loop.
-  }    // End of congestion_control_tag loop.
-
-  return params;
-}
-
-void WriteHeadersOnStream(QuicSpdyStream* stream) {
-  // Since QuicSpdyStream uses QuicHeaderList::empty() to detect too large
-  // headers, it also fails when receiving empty headers.
-  SpdyHeaderBlock headers;
-  headers[":authority"] = "test.example.com:443";
-  headers[":path"] = "/path";
-  headers[":method"] = "GET";
-  headers[":scheme"] = "https";
-  stream->WriteHeaders(std::move(headers), /* fin = */ false, nullptr);
-}
-
-class ServerDelegate : public PacketDroppingTestWriter::Delegate {
- public:
-  explicit ServerDelegate(QuicDispatcher* dispatcher)
-      : dispatcher_(dispatcher) {}
-  ~ServerDelegate() override = default;
-  void OnCanWrite() override { dispatcher_->OnCanWrite(); }
-
- private:
-  QuicDispatcher* dispatcher_;
-};
-
-class ClientDelegate : public PacketDroppingTestWriter::Delegate {
- public:
-  explicit ClientDelegate(QuicClient* client) : client_(client) {}
-  ~ClientDelegate() override = default;
-  void OnCanWrite() override {
-    QuicEpollEvent event(EPOLLOUT);
-    client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
-  }
-
- private:
-  QuicClient* client_;
-};
-
-class EndToEndTest : public QuicTestWithParam<TestParams> {
- protected:
-  EndToEndTest()
-      : initialized_(false),
-        connect_to_server_on_initialize_(true),
-        server_address_(QuicSocketAddress(TestLoopback(), 0)),
-        server_hostname_("test.example.com"),
-        client_writer_(nullptr),
-        server_writer_(nullptr),
-        version_(GetParam().version),
-        client_supported_versions_({version_}),
-        server_supported_versions_(CurrentSupportedVersions()),
-        chlo_multiplier_(0),
-        stream_factory_(nullptr),
-        expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
-    QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
-
-    // Use different flow control windows for client/server.
-    client_config_.SetInitialStreamFlowControlWindowToSend(
-        2 * kInitialStreamFlowControlWindowForTest);
-    client_config_.SetInitialSessionFlowControlWindowToSend(
-        2 * kInitialSessionFlowControlWindowForTest);
-    server_config_.SetInitialStreamFlowControlWindowToSend(
-        3 * kInitialStreamFlowControlWindowForTest);
-    server_config_.SetInitialSessionFlowControlWindowToSend(
-        3 * kInitialSessionFlowControlWindowForTest);
-
-    // The default idle timeouts can be too strict when running on a busy
-    // machine.
-    const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
-    client_config_.set_max_time_before_crypto_handshake(timeout);
-    client_config_.set_max_idle_time_before_crypto_handshake(timeout);
-    server_config_.set_max_time_before_crypto_handshake(timeout);
-    server_config_.set_max_idle_time_before_crypto_handshake(timeout);
-
-    AddToCache("/foo", 200, kFooResponseBody);
-    AddToCache("/bar", 200, kBarResponseBody);
-    // Enable fixes for bugs found in tests and prod.
-  }
-
-  virtual void CreateClientWithWriter() {
-    client_.reset(CreateQuicClient(client_writer_));
-  }
-
-  QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
-    QuicTestClient* client =
-        new QuicTestClient(server_address_, server_hostname_, client_config_,
-                           client_supported_versions_,
-                           crypto_test_utils::ProofVerifierForTesting(),
-                           std::make_unique<QuicClientSessionCache>());
-    client->SetUserAgentID(kTestUserAgentId);
-    client->UseWriter(writer);
-    if (!pre_shared_key_client_.empty()) {
-      client->client()->SetPreSharedKey(pre_shared_key_client_);
-    }
-    client->UseConnectionIdLength(override_server_connection_id_length_);
-    client->UseClientConnectionIdLength(override_client_connection_id_length_);
-    client->client()->set_connection_debug_visitor(connection_debug_visitor_);
-    client->client()->set_enable_web_transport(enable_web_transport_);
-    client->client()->set_use_datagram_contexts(use_datagram_contexts_);
-    client->Connect();
-    return client;
-  }
-
-  void set_smaller_flow_control_receive_window() {
-    const uint32_t kClientIFCW = 64 * 1024;
-    const uint32_t kServerIFCW = 1024 * 1024;
-    set_client_initial_stream_flow_control_receive_window(kClientIFCW);
-    set_client_initial_session_flow_control_receive_window(
-        kSessionToStreamRatio * kClientIFCW);
-    set_server_initial_stream_flow_control_receive_window(kServerIFCW);
-    set_server_initial_session_flow_control_receive_window(
-        kSessionToStreamRatio * kServerIFCW);
-  }
-
-  void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
-    ASSERT_TRUE(client_ == nullptr);
-    QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
-                    << window;
-    client_config_.SetInitialStreamFlowControlWindowToSend(window);
-  }
-
-  void set_client_initial_session_flow_control_receive_window(uint32_t window) {
-    ASSERT_TRUE(client_ == nullptr);
-    QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
-                    << window;
-    client_config_.SetInitialSessionFlowControlWindowToSend(window);
-  }
-
-  void set_client_initial_max_stream_data_incoming_bidirectional(
-      uint32_t window) {
-    ASSERT_TRUE(client_ == nullptr);
-    QUIC_DLOG(INFO)
-        << "Setting client initial max stream data incoming bidirectional: "
-        << window;
-    client_config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-        window);
-  }
-
-  void set_server_initial_max_stream_data_outgoing_bidirectional(
-      uint32_t window) {
-    ASSERT_TRUE(client_ == nullptr);
-    QUIC_DLOG(INFO)
-        << "Setting server initial max stream data outgoing bidirectional: "
-        << window;
-    server_config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-        window);
-  }
-
-  void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
-    ASSERT_TRUE(server_thread_ == nullptr);
-    QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
-                    << window;
-    server_config_.SetInitialStreamFlowControlWindowToSend(window);
-  }
-
-  void set_server_initial_session_flow_control_receive_window(uint32_t window) {
-    ASSERT_TRUE(server_thread_ == nullptr);
-    QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
-                    << window;
-    server_config_.SetInitialSessionFlowControlWindowToSend(window);
-  }
-
-  const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
-    QuicConnection* server_connection = GetServerConnection();
-    if (server_connection == nullptr) {
-      ADD_FAILURE() << "Missing server connection";
-      return nullptr;
-    }
-    return &server_connection->sent_packet_manager();
-  }
-
-  const QuicSentPacketManager* GetSentPacketManagerFromClientSession() {
-    QuicConnection* client_connection = GetClientConnection();
-    if (client_connection == nullptr) {
-      ADD_FAILURE() << "Missing client connection";
-      return nullptr;
-    }
-    return &client_connection->sent_packet_manager();
-  }
-
-  QuicSpdyClientSession* GetClientSession() {
-    if (!client_) {
-      ADD_FAILURE() << "Missing QuicTestClient";
-      return nullptr;
-    }
-    if (client_->client() == nullptr) {
-      ADD_FAILURE() << "Missing MockableQuicClient";
-      return nullptr;
-    }
-    return client_->client()->client_session();
-  }
-
-  QuicConnection* GetClientConnection() {
-    QuicSpdyClientSession* client_session = GetClientSession();
-    if (client_session == nullptr) {
-      ADD_FAILURE() << "Missing client session";
-      return nullptr;
-    }
-    return client_session->connection();
-  }
-
-  QuicConnection* GetServerConnection() {
-    QuicSpdySession* server_session = GetServerSession();
-    if (server_session == nullptr) {
-      ADD_FAILURE() << "Missing server session";
-      return nullptr;
-    }
-    return server_session->connection();
-  }
-
-  QuicSpdySession* GetServerSession() {
-    if (!server_thread_) {
-      ADD_FAILURE() << "Missing server thread";
-      return nullptr;
-    }
-    QuicServer* quic_server = server_thread_->server();
-    if (quic_server == nullptr) {
-      ADD_FAILURE() << "Missing server";
-      return nullptr;
-    }
-    QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(quic_server);
-    if (dispatcher == nullptr) {
-      ADD_FAILURE() << "Missing dispatcher";
-      return nullptr;
-    }
-    if (dispatcher->NumSessions() == 0) {
-      ADD_FAILURE() << "Empty dispatcher session map";
-      return nullptr;
-    }
-    EXPECT_EQ(1u, dispatcher->NumSessions());
-    return static_cast<QuicSpdySession*>(
-        QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher));
-  }
-
-  bool Initialize() {
-    if (enable_web_transport_) {
-      memory_cache_backend_.set_enable_webtransport(true);
-    }
-    if (use_datagram_contexts_) {
-      memory_cache_backend_.set_use_datagram_contexts(true);
-    }
-
-    QuicTagVector copt;
-    server_config_.SetConnectionOptionsToSend(copt);
-    copt = client_extra_copts_;
-
-    // TODO(nimia): Consider setting the congestion control algorithm for the
-    // client as well according to the test parameter.
-    copt.push_back(GetParam().congestion_control_tag);
-    copt.push_back(k2PTO);
-    if (version_.HasIetfQuicFrames()) {
-      copt.push_back(kILD0);
-    }
-    copt.push_back(kPLE1);
-    if (!GetQuicReloadableFlag(
-            quic_remove_connection_migration_connection_option)) {
-      copt.push_back(kRVCM);
-    }
-    client_config_.SetConnectionOptionsToSend(copt);
-
-    // Start the server first, because CreateQuicClient() attempts
-    // to connect to the server.
-    StartServer();
-
-    if (!connect_to_server_on_initialize_) {
-      initialized_ = true;
-      return true;
-    }
-
-    CreateClientWithWriter();
-    if (!client_) {
-      ADD_FAILURE() << "Missing QuicTestClient";
-      return false;
-    }
-    MockableQuicClient* client = client_->client();
-    if (client == nullptr) {
-      ADD_FAILURE() << "Missing MockableQuicClient";
-      return false;
-    }
-    static QuicEpollEvent event(EPOLLOUT);
-    if (client_writer_ != nullptr) {
-      QuicConnection* client_connection = GetClientConnection();
-      if (client_connection == nullptr) {
-        ADD_FAILURE() << "Missing client connection";
-        return false;
-      }
-      client_writer_->Initialize(
-          QuicConnectionPeer::GetHelper(client_connection),
-          QuicConnectionPeer::GetAlarmFactory(client_connection),
-          std::make_unique<ClientDelegate>(client));
-    }
-    initialized_ = true;
-    return client->connected();
-  }
-
-  void SetUp() override {
-    // The ownership of these gets transferred to the QuicPacketWriterWrapper
-    // when Initialize() is executed.
-    client_writer_ = new PacketDroppingTestWriter();
-    server_writer_ = new PacketDroppingTestWriter();
-  }
-
-  void TearDown() override {
-    EXPECT_TRUE(initialized_) << "You must call Initialize() in every test "
-                              << "case. Otherwise, your test will leak memory.";
-    QuicConnection* client_connection = GetClientConnection();
-    if (client_connection != nullptr) {
-      client_connection->set_debug_visitor(nullptr);
-    } else {
-      ADD_FAILURE() << "Missing client connection";
-    }
-    StopServer();
-  }
-
-  void StartServer() {
-    auto* test_server = new QuicTestServer(
-        crypto_test_utils::ProofSourceForTesting(), server_config_,
-        server_supported_versions_, &memory_cache_backend_,
-        expected_server_connection_id_length_);
-    server_thread_ =
-        std::make_unique<ServerThread>(test_server, server_address_);
-    if (chlo_multiplier_ != 0) {
-      server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
-    }
-    if (!pre_shared_key_server_.empty()) {
-      server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
-    }
-    server_thread_->Initialize();
-    server_address_ =
-        QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
-    QuicDispatcher* dispatcher =
-        QuicServerPeer::GetDispatcher(server_thread_->server());
-    QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
-
-    server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
-                               QuicDispatcherPeer::GetAlarmFactory(dispatcher),
-                               std::make_unique<ServerDelegate>(dispatcher));
-    if (stream_factory_ != nullptr) {
-      static_cast<QuicTestServer*>(server_thread_->server())
-          ->SetSpdyStreamFactory(stream_factory_);
-    }
-
-    server_thread_->Start();
-  }
-
-  void StopServer() {
-    if (server_thread_) {
-      server_thread_->Quit();
-      server_thread_->Join();
-    }
-  }
-
-  void AddToCache(absl::string_view path, int response_code,
-                  absl::string_view body) {
-    memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
-                                            response_code, body);
-  }
-
-  void SetPacketLossPercentage(int32_t loss) {
-    client_writer_->set_fake_packet_loss_percentage(loss);
-    server_writer_->set_fake_packet_loss_percentage(loss);
-  }
-
-  void SetPacketSendDelay(QuicTime::Delta delay) {
-    client_writer_->set_fake_packet_delay(delay);
-    server_writer_->set_fake_packet_delay(delay);
-  }
-
-  void SetReorderPercentage(int32_t reorder) {
-    client_writer_->set_fake_reorder_percentage(reorder);
-    server_writer_->set_fake_reorder_percentage(reorder);
-  }
-
-  // Verifies that the client and server connections were both free of packets
-  // being discarded, based on connection stats.
-  // Calls server_thread_ Pause() and Resume(), which may only be called once
-  // per test.
-  void VerifyCleanConnection(bool had_packet_loss) {
-    QuicConnection* client_connection = GetClientConnection();
-    if (client_connection == nullptr) {
-      ADD_FAILURE() << "Missing client connection";
-      return;
-    }
-    QuicConnectionStats client_stats = client_connection->GetStats();
-    // TODO(ianswett): Determine why this becomes even more flaky with BBR
-    // enabled.  b/62141144
-    if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
-      EXPECT_EQ(0u, client_stats.packets_lost);
-    }
-    EXPECT_EQ(0u, client_stats.packets_discarded);
-    // When client starts with an unsupported version, the version negotiation
-    // packet sent by server for the old connection (respond for the connection
-    // close packet) will be dropped by the client.
-    if (!ServerSendsVersionNegotiation()) {
-      EXPECT_EQ(0u, client_stats.packets_dropped);
-    }
-    if (!version_.UsesTls()) {
-      // Only enforce this for QUIC crypto because accounting of number of
-      // packets received, processed gets complicated with packets coalescing
-      // and key dropping. For example, a received undecryptable coalesced
-      // packet can be processed later and each sub-packet increases
-      // packets_processed.
-      EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
-    }
-
-    if (!server_thread_) {
-      ADD_FAILURE() << "Missing server thread";
-      return;
-    }
-    server_thread_->Pause();
-    QuicSpdySession* server_session = GetServerSession();
-    if (server_session != nullptr) {
-      QuicConnection* server_connection = server_session->connection();
-      if (server_connection != nullptr) {
-        QuicConnectionStats server_stats = server_connection->GetStats();
-        if (!had_packet_loss) {
-          EXPECT_EQ(0u, server_stats.packets_lost);
-        }
-        EXPECT_EQ(0u, server_stats.packets_discarded);
-      } else {
-        ADD_FAILURE() << "Missing server connection";
-      }
-    } else {
-      ADD_FAILURE() << "Missing server session";
-    }
-    // TODO(ianswett): Restore the check for packets_dropped equals 0.
-    // The expect for packets received is equal to packets processed fails
-    // due to version negotiation packets.
-    server_thread_->Resume();
-  }
-
-  // Returns true when client starts with an unsupported version, and client
-  // closes connection when version negotiation is received.
-  bool ServerSendsVersionNegotiation() {
-    return client_supported_versions_[0] != version_;
-  }
-
-  bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
-    return version.HasIetfInvariantHeader() &&
-           version.handshake_protocol == PROTOCOL_TLS1_3;
-  }
-
-  static void ExpectFlowControlsSynced(QuicSession* client,
-                                       QuicSession* server) {
-    EXPECT_EQ(
-        QuicFlowControllerPeer::SendWindowSize(client->flow_controller()),
-        QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller()));
-    EXPECT_EQ(
-        QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()),
-        QuicFlowControllerPeer::SendWindowSize(server->flow_controller()));
-  }
-
-  static void ExpectFlowControlsSynced(QuicStream* client, QuicStream* server) {
-    EXPECT_EQ(QuicStreamPeer::SendWindowSize(client),
-              QuicStreamPeer::ReceiveWindowSize(server));
-    EXPECT_EQ(QuicStreamPeer::ReceiveWindowSize(client),
-              QuicStreamPeer::SendWindowSize(server));
-  }
-
-  // Must be called before Initialize to have effect.
-  void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
-    stream_factory_ = factory;
-  }
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return GetNthClientInitiatedBidirectionalStreamId(
-        version_.transport_version, n);
-  }
-
-  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
-    return GetNthServerInitiatedBidirectionalStreamId(
-        version_.transport_version, n);
-  }
-
-  bool CheckResponseHeaders(QuicTestClient* client,
-                            const std::string& expected_status) {
-    const spdy::SpdyHeaderBlock* response_headers = client->response_headers();
-    auto it = response_headers->find(":status");
-    if (it == response_headers->end()) {
-      ADD_FAILURE() << "Did not find :status header in response";
-      return false;
-    }
-    if (it->second != expected_status) {
-      ADD_FAILURE() << "Got bad :status response: \"" << it->second << "\"";
-      return false;
-    }
-    return true;
-  }
-
-  bool CheckResponseHeaders(QuicTestClient* client) {
-    return CheckResponseHeaders(client, "200");
-  }
-
-  bool CheckResponseHeaders(const std::string& expected_status) {
-    return CheckResponseHeaders(client_.get(), expected_status);
-  }
-
-  bool CheckResponseHeaders() { return CheckResponseHeaders(client_.get()); }
-
-  bool CheckResponse(QuicTestClient* client,
-                     const std::string& received_response,
-                     const std::string& expected_response) {
-    EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
-    EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-
-    if (received_response.empty() && !expected_response.empty()) {
-      ADD_FAILURE() << "Failed to get any response for request";
-      return false;
-    }
-    if (received_response != expected_response) {
-      ADD_FAILURE() << "Got wrong response: \"" << received_response << "\"";
-      return false;
-    }
-    return CheckResponseHeaders(client);
-  }
-
-  bool SendSynchronousRequestAndCheckResponse(
-      QuicTestClient* client, const std::string& request,
-      const std::string& expected_response) {
-    std::string received_response = client->SendSynchronousRequest(request);
-    return CheckResponse(client, received_response, expected_response);
-  }
-
-  bool SendSynchronousRequestAndCheckResponse(
-      const std::string& request, const std::string& expected_response) {
-    return SendSynchronousRequestAndCheckResponse(client_.get(), request,
-                                                  expected_response);
-  }
-
-  bool SendSynchronousFooRequestAndCheckResponse(QuicTestClient* client) {
-    return SendSynchronousRequestAndCheckResponse(client, "/foo",
-                                                  kFooResponseBody);
-  }
-
-  bool SendSynchronousFooRequestAndCheckResponse() {
-    return SendSynchronousFooRequestAndCheckResponse(client_.get());
-  }
-
-  bool SendSynchronousBarRequestAndCheckResponse() {
-    std::string received_response = client_->SendSynchronousRequest("/bar");
-    return CheckResponse(client_.get(), received_response, kBarResponseBody);
-  }
-
-  bool WaitForFooResponseAndCheckIt(QuicTestClient* client) {
-    client->WaitForResponse();
-    std::string received_response = client->response_body();
-    return CheckResponse(client_.get(), received_response, kFooResponseBody);
-  }
-
-  bool WaitForFooResponseAndCheckIt() {
-    return WaitForFooResponseAndCheckIt(client_.get());
-  }
-
-  WebTransportHttp3* CreateWebTransportSession(
-      const std::string& path, bool wait_for_server_response,
-      QuicSpdyStream** connect_stream_out = nullptr) {
-    // Wait until we receive the settings from the server indicating
-    // WebTransport support.
-    client_->WaitUntil(
-        2000, [this]() { return GetClientSession()->SupportsWebTransport(); });
-    if (!GetClientSession()->SupportsWebTransport()) {
-      return nullptr;
-    }
-
-    spdy::SpdyHeaderBlock headers;
-    headers[":scheme"] = "https";
-    headers[":authority"] = "localhost";
-    headers[":path"] = path;
-    headers[":method"] = "CONNECT";
-    headers[":protocol"] = "webtransport";
-
-    client_->SendMessage(headers, "", /*fin=*/false);
-    QuicSpdyStream* stream = client_->latest_created_stream();
-    if (stream->web_transport() == nullptr) {
-      return nullptr;
-    }
-    WebTransportSessionId id = client_->latest_created_stream()->id();
-    QuicSpdySession* client_session = GetClientSession();
-    if (client_session->GetWebTransportSession(id) == nullptr) {
-      return nullptr;
-    }
-    WebTransportHttp3* session = client_session->GetWebTransportSession(id);
-    if (wait_for_server_response) {
-      client_->WaitUntil(-1,
-                         [stream]() { return stream->headers_decompressed(); });
-      EXPECT_TRUE(session->ready());
-    }
-    if (connect_stream_out != nullptr) {
-      *connect_stream_out = stream;
-    }
-    return session;
-  }
-
-  NiceMock<MockClientVisitor>& SetupWebTransportVisitor(
-      WebTransportHttp3* session) {
-    auto visitor_owned = std::make_unique<NiceMock<MockClientVisitor>>();
-    NiceMock<MockClientVisitor>& visitor = *visitor_owned;
-    session->SetVisitor(std::move(visitor_owned));
-    return visitor;
-  }
-
-  std::string ReadDataFromWebTransportStreamUntilFin(
-      WebTransportStream* stream, MockStreamVisitor* visitor = nullptr) {
-    QuicStreamId id = stream->GetStreamId();
-    std::string buffer;
-
-    // Try reading data if immediately available.
-    WebTransportStream::ReadResult result = stream->Read(&buffer);
-    if (result.fin) {
-      return buffer;
-    }
-
-    while (true) {
-      bool can_read = false;
-      if (visitor == nullptr) {
-        auto visitor_owned = std::make_unique<MockStreamVisitor>();
-        visitor = visitor_owned.get();
-        stream->SetVisitor(std::move(visitor_owned));
-      }
-      EXPECT_CALL(*visitor, OnCanRead()).WillOnce(Assign(&can_read, true));
-      client_->WaitUntil(5000 /*ms*/, [&can_read]() { return can_read; });
-      if (!can_read) {
-        ADD_FAILURE() << "Waiting for readable data on stream " << id
-                      << " timed out";
-        return buffer;
-      }
-      if (GetClientSession()->GetOrCreateSpdyDataStream(id) == nullptr) {
-        ADD_FAILURE() << "Stream " << id
-                      << " was deleted while waiting for incoming data";
-        return buffer;
-      }
-
-      result = stream->Read(&buffer);
-      if (result.fin) {
-        return buffer;
-      }
-      if (result.bytes_read == 0) {
-        ADD_FAILURE() << "No progress made while reading from stream "
-                      << stream->GetStreamId();
-        return buffer;
-      }
-    }
-  }
-
-  void ReadAllIncomingWebTransportUnidirectionalStreams(
-      WebTransportSession* session) {
-    while (true) {
-      WebTransportStream* received_stream =
-          session->AcceptIncomingUnidirectionalStream();
-      if (received_stream == nullptr) {
-        break;
-      }
-      received_webtransport_unidirectional_streams_.push_back(
-          ReadDataFromWebTransportStreamUntilFin(received_stream));
-    }
-  }
-
-  void WaitForNewConnectionIds() {
-    // Wait until a new server CID is available for another migration.
-    const auto* client_connection = GetClientConnection();
-    while (!QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
-               client_connection) ||
-           (!client_connection->client_connection_id().IsEmpty() &&
-            !QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
-                client_connection))) {
-      client_->client()->WaitForEvents();
-    }
-  }
-
-  ScopedEnvironmentForThreads environment_;
-  bool initialized_;
-  // If true, the Initialize() function will create |client_| and starts to
-  // connect to the server.
-  // Default is true.
-  bool connect_to_server_on_initialize_;
-  QuicSocketAddress server_address_;
-  std::string server_hostname_;
-  QuicTestBackend memory_cache_backend_;
-  std::unique_ptr<ServerThread> server_thread_;
-  std::unique_ptr<QuicTestClient> client_;
-  QuicConnectionDebugVisitor* connection_debug_visitor_ = nullptr;
-  PacketDroppingTestWriter* client_writer_;
-  PacketDroppingTestWriter* server_writer_;
-  QuicConfig client_config_;
-  QuicConfig server_config_;
-  ParsedQuicVersion version_;
-  ParsedQuicVersionVector client_supported_versions_;
-  ParsedQuicVersionVector server_supported_versions_;
-  QuicTagVector client_extra_copts_;
-  size_t chlo_multiplier_;
-  QuicTestServer::StreamFactory* stream_factory_;
-  std::string pre_shared_key_client_;
-  std::string pre_shared_key_server_;
-  int override_server_connection_id_length_ = -1;
-  int override_client_connection_id_length_ = -1;
-  uint8_t expected_server_connection_id_length_;
-  bool enable_web_transport_ = false;
-  bool use_datagram_contexts_ = false;
-  std::vector<std::string> received_webtransport_unidirectional_streams_;
-};
-
-// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(EndToEndTest, HandshakeSuccessful) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(server_thread_);
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicCryptoStream* client_crypto_stream =
-      QuicSessionPeer::GetMutableCryptoStream(client_session);
-  ASSERT_TRUE(client_crypto_stream);
-  QuicStreamSequencer* client_sequencer =
-      QuicStreamPeer::sequencer(client_crypto_stream);
-  ASSERT_TRUE(client_sequencer);
-  EXPECT_FALSE(
-      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(client_sequencer));
-
-  // We've had bugs in the past where the connections could end up on the wrong
-  // version. This was never diagnosed but could have been due to in-connection
-  // version negotiation back when that existed. At this point in time, our test
-  // setup ensures that connections here always use |version_|, but we add this
-  // sanity check out of paranoia to catch a regression of this type.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(client_connection->version(), version_);
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  QuicConnection* server_connection = nullptr;
-  QuicCryptoStream* server_crypto_stream = nullptr;
-  QuicStreamSequencer* server_sequencer = nullptr;
-  if (server_session != nullptr) {
-    server_connection = server_session->connection();
-    server_crypto_stream =
-        QuicSessionPeer::GetMutableCryptoStream(server_session);
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  if (server_crypto_stream != nullptr) {
-    server_sequencer = QuicStreamPeer::sequencer(server_crypto_stream);
-  } else {
-    ADD_FAILURE() << "Missing server crypto stream";
-  }
-  if (server_sequencer != nullptr) {
-    EXPECT_FALSE(
-        QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(server_sequencer));
-  } else {
-    ADD_FAILURE() << "Missing server sequencer";
-  }
-  if (server_connection != nullptr) {
-    EXPECT_EQ(server_connection->version(), version_);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ExportKeyingMaterial) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.UsesTls()) {
-    return;
-  }
-  const char* kExportLabel = "label";
-  const int kExportLen = 30;
-  std::string client_keying_material_export, server_keying_material_export;
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(server_thread_);
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  QuicCryptoStream* server_crypto_stream = nullptr;
-  if (server_session != nullptr) {
-    server_crypto_stream =
-        QuicSessionPeer::GetMutableCryptoStream(server_session);
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  if (server_crypto_stream != nullptr) {
-    ASSERT_TRUE(server_crypto_stream->ExportKeyingMaterial(
-        kExportLabel, /*context=*/"", kExportLen,
-        &server_keying_material_export));
-
-  } else {
-    ADD_FAILURE() << "Missing server crypto stream";
-  }
-  server_thread_->Resume();
-
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicCryptoStream* client_crypto_stream =
-      QuicSessionPeer::GetMutableCryptoStream(client_session);
-  ASSERT_TRUE(client_crypto_stream);
-  ASSERT_TRUE(client_crypto_stream->ExportKeyingMaterial(
-      kExportLabel, /*context=*/"", kExportLen,
-      &client_keying_material_export));
-  ASSERT_EQ(client_keying_material_export.size(),
-            static_cast<size_t>(kExportLen));
-  EXPECT_EQ(client_keying_material_export, server_keying_material_export);
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponse) {
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-  if (version_.UsesHttp3()) {
-    QuicSpdyClientSession* client_session = GetClientSession();
-    ASSERT_TRUE(client_session);
-    EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(client_session));
-    EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(client_session));
-    server_thread_->Pause();
-    QuicSpdySession* server_session = GetServerSession();
-    if (server_session != nullptr) {
-      EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(server_session));
-      EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(server_session));
-    } else {
-      ADD_FAILURE() << "Missing server session";
-    }
-    server_thread_->Resume();
-  }
-  QuicConnectionStats client_stats = GetClientConnection()->GetStats();
-  EXPECT_TRUE(client_stats.handshake_completion_time.IsInitialized());
-}
-
-TEST_P(EndToEndTest, HandshakeConfirmed) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.UsesTls()) {
-    return;
-  }
-  SendSynchronousFooRequestAndCheckResponse();
-  // Verify handshake state.
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_EQ(HANDSHAKE_CONFIRMED, client_session->GetHandshakeState());
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  if (server_session != nullptr) {
-    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_session->GetHandshakeState());
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  server_thread_->Resume();
-  client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, SendAndReceiveCoalescedPackets) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.CanSendCoalescedPackets()) {
-    return;
-  }
-  SendSynchronousFooRequestAndCheckResponse();
-  // Verify client successfully processes coalesced packets.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionStats client_stats = client_connection->GetStats();
-  EXPECT_LT(0u, client_stats.num_coalesced_packets_received);
-  EXPECT_EQ(client_stats.num_coalesced_packets_processed,
-            client_stats.num_coalesced_packets_received);
-  // TODO(fayang): verify server successfully processes coalesced packets.
-}
-
-// Simple transaction, but set a non-default ack delay at the client
-// and ensure it gets to the server.
-TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
-  // Force the ACK delay to be something other than the default.
-  constexpr uint32_t kClientMaxAckDelay = kDefaultDelayedAckTimeMs + 100u;
-  client_config_.SetMaxAckDelayToSendMs(kClientMaxAckDelay);
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  server_thread_->Pause();
-  const QuicSentPacketManager* server_sent_packet_manager =
-      GetSentPacketManagerFromFirstServerSession();
-  if (server_sent_packet_manager != nullptr) {
-    EXPECT_EQ(
-        kClientMaxAckDelay,
-        server_sent_packet_manager->peer_max_ack_delay().ToMilliseconds());
-  } else {
-    ADD_FAILURE() << "Missing server sent packet manager";
-  }
-  server_thread_->Resume();
-}
-
-// Simple transaction, but set a non-default ack exponent at the client
-// and ensure it gets to the server.
-TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
-  const uint32_t kClientAckDelayExponent = 19;
-  EXPECT_NE(kClientAckDelayExponent, kDefaultAckDelayExponent);
-  // Force the ACK exponent to be something other than the default.
-  // Note that it is sent only with QUIC+TLS.
-  client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    if (version_.UsesTls()) {
-      // Should be only sent with QUIC+TLS.
-      EXPECT_EQ(kClientAckDelayExponent,
-                server_connection->framer().peer_ack_delay_exponent());
-    } else {
-      // No change for QUIC_CRYPTO.
-      EXPECT_EQ(kDefaultAckDelayExponent,
-                server_connection->framer().peer_ack_delay_exponent());
-    }
-    // No change, regardless of version.
-    EXPECT_EQ(kDefaultAckDelayExponent,
-              server_connection->framer().local_ack_delay_exponent());
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  NiceMock<MockQuicConnectionDebugVisitor> visitor;
-  connection_debug_visitor_ = &visitor;
-  EXPECT_CALL(visitor, OnVersionNegotiationPacket(_)).Times(1);
-  ASSERT_TRUE(Initialize());
-  ASSERT_TRUE(ServerSendsVersionNegotiation());
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-}
-
-TEST_P(EndToEndTest, ForcedVersionNegotiation) {
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  ASSERT_TRUE(Initialize());
-  ASSERT_TRUE(ServerSendsVersionNegotiation());
-
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_server_connection_id_length_ = 0;
-  expected_server_connection_id_length_ = 0;
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(client_connection->connection_id(),
-            QuicUtils::CreateZeroConnectionId(version_.transport_version));
-}
-
-TEST_P(EndToEndTest, ZeroConnectionID) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_server_connection_id_length_ = 0;
-  expected_server_connection_id_length_ = 0;
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(client_connection->connection_id(),
-            QuicUtils::CreateZeroConnectionId(version_.transport_version));
-}
-
-TEST_P(EndToEndTest, BadConnectionIdLength) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_server_connection_id_length_ = 9;
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
-                                                ->client_session()
-                                                ->connection()
-                                                ->connection_id()
-                                                .length());
-}
-
-// Tests a very long (16-byte) initial destination connection ID to make
-// sure the dispatcher properly replaces it with an 8-byte one.
-TEST_P(EndToEndTest, LongBadConnectionIdLength) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_server_connection_id_length_ = 16;
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
-                                                ->client_session()
-                                                ->connection()
-                                                ->connection_id()
-                                                .length());
-}
-
-TEST_P(EndToEndTest, ClientConnectionId) {
-  if (!version_.SupportsClientConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(override_client_connection_id_length_, client_->client()
-                                                       ->client_session()
-                                                       ->connection()
-                                                       ->client_connection_id()
-                                                       .length());
-}
-
-TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
-  if (!version_.SupportsClientConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
-  ASSERT_TRUE(Initialize());
-  ASSERT_TRUE(ServerSendsVersionNegotiation());
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(override_client_connection_id_length_, client_->client()
-                                                       ->client_session()
-                                                       ->connection()
-                                                       ->client_connection_id()
-                                                       .length());
-}
-
-TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  override_server_connection_id_length_ = 9;
-  ASSERT_TRUE(Initialize());
-  ASSERT_TRUE(ServerSendsVersionNegotiation());
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
-                                                ->client_session()
-                                                ->connection()
-                                                ->connection_id()
-                                                .length());
-}
-
-// Forced Version Negotiation with a client connection ID and a long
-// connection ID.
-TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
-  if (!version_.SupportsClientConnectionIds() ||
-      !version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  override_server_connection_id_length_ = 16;
-  override_client_connection_id_length_ = 18;
-  ASSERT_TRUE(Initialize());
-  ASSERT_TRUE(ServerSendsVersionNegotiation());
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
-                                                ->client_session()
-                                                ->connection()
-                                                ->connection_id()
-                                                .length());
-  EXPECT_EQ(override_client_connection_id_length_, client_->client()
-                                                       ->client_session()
-                                                       ->connection()
-                                                       ->client_connection_id()
-                                                       .length());
-}
-
-TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-
-  // Start client_ which will use a bad connection ID length.
-  override_server_connection_id_length_ = 9;
-  ASSERT_TRUE(Initialize());
-  override_server_connection_id_length_ = -1;
-
-  // Start client2 which will use a good connection ID length.
-  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = "3";
-  client2->SendMessage(headers, "", /*fin=*/false);
-  client2->SendData("eep", true);
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
-                                                ->client_session()
-                                                ->connection()
-                                                ->connection_id()
-                                                .length());
-
-  WaitForFooResponseAndCheckIt(client2.get());
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
-                                                ->client_session()
-                                                ->connection()
-                                                ->connection_id()
-                                                .length());
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseWithIetfDraftSupport) {
-  if (!version_.HasIetfQuicFrames()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  QuicVersionInitializeSupportForIetfDraft();
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
-  chlo_multiplier_ = 1;
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  if (version_.UsesTls()) {
-    // REJ messages are a QUIC crypto feature, so TLS always returns false.
-    EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-  } else {
-    EXPECT_TRUE(client_->client()->ReceivedInchoateReject());
-  }
-}
-
-TEST_P(EndToEndTest, SimpleRequestResponsev6) {
-  server_address_ =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest,
-       ClientDoesNotAllowServerDataOnServerInitiatedBidirectionalStreams) {
-  set_client_initial_max_stream_data_incoming_bidirectional(0);
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest,
-       ServerDoesNotAllowClientDataOnServerInitiatedBidirectionalStreams) {
-  set_server_initial_max_stream_data_outgoing_bidirectional(0);
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest,
-       BothEndpointsDisallowDataOnServerInitiatedBidirectionalStreams) {
-  set_client_initial_max_stream_data_incoming_bidirectional(0);
-  set_server_initial_max_stream_data_outgoing_bidirectional(0);
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-// Regression test for a bug where we would always fail to decrypt the first
-// initial packet. Undecryptable packets can be seen after the handshake
-// is complete due to dropping the initial keys at that point, so we only test
-// for undecryptable packets before then.
-TEST_P(EndToEndTest, NoUndecryptablePacketsBeforeHandshakeComplete) {
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionStats client_stats = client_connection->GetStats();
-  EXPECT_EQ(
-      0u,
-      client_stats.undecryptable_packets_received_before_handshake_complete);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    QuicConnectionStats server_stats = server_connection->GetStats();
-    EXPECT_EQ(
-        0u,
-        server_stats.undecryptable_packets_received_before_handshake_complete);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, SeparateFinPacket) {
-  ASSERT_TRUE(Initialize());
-
-  // Send a request in two parts: the request and then an empty packet with FIN.
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->SendData("", true);
-  WaitForFooResponseAndCheckIt();
-
-  // Now do the same thing but with a content length.
-  headers["content-length"] = "3";
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->SendData("foo", true);
-  WaitForFooResponseAndCheckIt();
-}
-
-TEST_P(EndToEndTest, MultipleRequestResponse) {
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  SendSynchronousBarRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_server_connection_id_length_ = 0;
-  expected_server_connection_id_length_ = 0;
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  SendSynchronousBarRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, MultipleStreams) {
-  // Verifies quic_test_client can track responses of all active streams.
-  ASSERT_TRUE(Initialize());
-
-  const int kNumRequests = 10;
-
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = "3";
-
-  for (int i = 0; i < kNumRequests; ++i) {
-    client_->SendMessage(headers, "bar", /*fin=*/true);
-  }
-
-  while (kNumRequests > client_->num_responses()) {
-    client_->ClearPerRequestState();
-    ASSERT_TRUE(WaitForFooResponseAndCheckIt());
-  }
-}
-
-TEST_P(EndToEndTest, MultipleClients) {
-  ASSERT_TRUE(Initialize());
-  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
-
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = "3";
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client2->SendMessage(headers, "", /*fin=*/false);
-
-  client_->SendData("bar", true);
-  WaitForFooResponseAndCheckIt();
-
-  client2->SendData("eep", true);
-  WaitForFooResponseAndCheckIt(client2.get());
-}
-
-TEST_P(EndToEndTest, RequestOverMultiplePackets) {
-  // Send a large enough request to guarantee fragmentation.
-  std::string huge_request =
-      "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
-  AddToCache(huge_request, 200, kBarResponseBody);
-
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
-}
-
-TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
-  // Send a large enough request to guarantee fragmentation.
-  std::string huge_request =
-      "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
-  AddToCache(huge_request, 200, kBarResponseBody);
-
-  ASSERT_TRUE(Initialize());
-  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
-  SetReorderPercentage(50);
-
-  SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
-}
-
-TEST_P(EndToEndTest, PostMissingBytes) {
-  ASSERT_TRUE(Initialize());
-
-  // Add a content length header with no body.
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = "3";
-
-  // This should be detected as stream fin without complete request,
-  // triggering an error response.
-  client_->SendCustomSynchronousRequest(headers, "");
-  EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
-            client_->response_body());
-  CheckResponseHeaders("500");
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLoss) {
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // 1 MB body.
-  std::string body(1024 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  // TODO(ianswett): There should not be packet loss in this test, but on some
-  // platforms the receive buffer overflows.
-  VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
-  ASSERT_TRUE(Initialize());
-  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // 100 KB body.
-  std::string body(100 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, LargePostWithPacketLoss) {
-  // Connect with lower fake packet loss than we'd like to test.
-  // Until b/10126687 is fixed, losing handshake packets is pretty
-  // brutal.
-  // Disable blackhole detection as this test is testing loss recovery.
-  client_extra_copts_.push_back(kNBHD);
-  SetPacketLossPercentage(5);
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  SetPacketLossPercentage(30);
-
-  // 10 KB body.
-  std::string body(1024 * 10, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  VerifyCleanConnection(true);
-}
-
-// Regression test for b/80090281.
-TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
-  // Disable blackhole detection as this test is testing loss recovery.
-  client_extra_copts_.push_back(kNBHD);
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Normally server only bundles a retransmittable frame once every other
-  // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
-  // to 0 to reliably reproduce b/80090281.
-  server_thread_->Schedule([this]() {
-    QuicConnection* server_connection = GetServerConnection();
-    if (server_connection != nullptr) {
-      QuicConnectionPeer::
-          SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
-              server_connection, 0);
-    } else {
-      ADD_FAILURE() << "Missing server connection";
-    }
-  });
-
-  SetPacketLossPercentage(30);
-
-  // 10 KB body.
-  std::string body(1024 * 10, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
-  // Connect with lower fake packet loss than we'd like to test.  Until
-  // b/10126687 is fixed, losing handshake packets is pretty brutal.
-  // Disable blackhole detection as this test is testing loss recovery.
-  client_extra_copts_.push_back(kNBHD);
-  SetPacketLossPercentage(5);
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  SetPacketLossPercentage(10);
-  client_writer_->set_fake_blocked_socket_percentage(10);
-
-  // 10 KB body.
-  std::string body(1024 * 10, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-}
-
-TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  // Both of these must be called when the writer is not actively used.
-  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
-  SetReorderPercentage(30);
-
-  // 1 MB body.
-  std::string body(1024 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-}
-
-TEST_P(EndToEndTest, AddressToken) {
-  client_extra_copts_.push_back(kTRTT);
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames()) {
-    return;
-  }
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // The 0-RTT handshake should succeed.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  ASSERT_TRUE(client_->client()->connected());
-  SendSynchronousFooRequestAndCheckResponse();
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_session != nullptr && server_connection != nullptr) {
-    // Verify address is validated via validating token received in INITIAL
-    // packet.
-    EXPECT_FALSE(
-        server_connection->GetStats().address_validated_via_decrypting_packet);
-    EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
-
-    // Verify the server received a cached min_rtt from the token and used it as
-    // the initial rtt.
-    const CachedNetworkParameters* server_received_network_params =
-        static_cast<const QuicCryptoServerStreamBase*>(
-            server_session->GetCryptoStream())
-            ->PreviousCachedNetworkParams();
-
-    ASSERT_NE(server_received_network_params, nullptr);
-    // QuicSentPacketManager::SetInitialRtt clamps the initial_rtt to between
-    // [min_initial_rtt, max_initial_rtt].
-    const QuicTime::Delta min_initial_rtt =
-        server_connection->sent_packet_manager().use_lower_min_irtt()
-            ? QuicTime::Delta::FromMicroseconds(
-                  kMinTrustedInitialRoundTripTimeUs)
-            : QuicTime::Delta::FromMicroseconds(
-                  kMinUntrustedInitialRoundTripTimeUs);
-    const QuicTime::Delta max_initial_rtt =
-        QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
-    const QuicTime::Delta expected_initial_rtt =
-        std::max(min_initial_rtt,
-                 std::min(max_initial_rtt,
-                          QuicTime::Delta::FromMilliseconds(
-                              server_received_network_params->min_rtt_ms())));
-    EXPECT_EQ(
-        server_connection->sent_packet_manager().GetRttStats()->initial_rtt(),
-        expected_initial_rtt);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-
-  server_thread_->Resume();
-
-  client_->Disconnect();
-
-  // Regression test for b/206087883.
-  // Mock server crash.
-  StopServer();
-
-  // The handshake fails due to idle timeout.
-  client_->Connect();
-  ASSERT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
-  client_->WaitForWriteToFlush();
-  client_->WaitForResponse();
-  ASSERT_FALSE(client_->client()->connected());
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_NETWORK_IDLE_TIMEOUT));
-
-  // Server restarts.
-  server_writer_ = new PacketDroppingTestWriter();
-  StartServer();
-
-  // Client re-connect.
-  client_->Connect();
-  ASSERT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  client_->WaitForWriteToFlush();
-  client_->WaitForResponse();
-  ASSERT_TRUE(client_->client()->connected());
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  server_thread_->Pause();
-  server_session = GetServerSession();
-  server_connection = GetServerConnection();
-  // Verify address token is only used once.
-  if (server_session != nullptr && server_connection != nullptr) {
-    // Verify address is validated via decrypting packet.
-    EXPECT_TRUE(
-        server_connection->GetStats().address_validated_via_decrypting_packet);
-    EXPECT_FALSE(server_connection->GetStats().address_validated_via_token);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-
-  client_->Disconnect();
-}
-
-// Verify that client does not reuse a source address token.
-TEST_P(EndToEndTest, AddressTokenNotReusedByClient) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames()) {
-    return;
-  }
-
-  QuicCryptoClientConfig* client_crypto_config =
-      client_->client()->crypto_config();
-  QuicServerId server_id = client_->client()->server_id();
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
-
-  client_->Disconnect();
-
-  QuicClientSessionCache* session_cache = static_cast<QuicClientSessionCache*>(
-      client_crypto_config->mutable_session_cache());
-  ASSERT_TRUE(
-      !QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
-
-  // Pause the server thread again to blackhole packets from client.
-  server_thread_->Pause();
-  client_->Connect();
-  EXPECT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
-  EXPECT_FALSE(client_->client()->connected());
-
-  // Verify address token gets cleared.
-  ASSERT_TRUE(
-      QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
-  // Send a request and then disconnect. This prepares the client to attempt
-  // a 0-RTT handshake for the next request.
-  ASSERT_TRUE(Initialize());
-
-  std::string body(20480, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // The 0-RTT handshake should succeed.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  client_->Disconnect();
-
-  // Restart the server so that the 0-RTT handshake will take 1 RTT.
-  StopServer();
-  server_writer_ = new PacketDroppingTestWriter();
-  StartServer();
-
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-  VerifyCleanConnection(false);
-}
-
-// Regression test for b/168020146.
-TEST_P(EndToEndTest, MultipleZeroRtt) {
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // The 0-RTT handshake should succeed.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  client_->Disconnect();
-
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
-  // Send a request and then disconnect. This prepares the client to attempt
-  // a 0-RTT handshake for the next request.
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // The 0-RTT handshake should succeed.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  client_->Disconnect();
-
-  // Restart the server so that the 0-RTT handshake will take 1 RTT.
-  StopServer();
-  server_writer_ = new PacketDroppingTestWriter();
-  StartServer();
-
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  VerifyCleanConnection(false);
-}
-
-TEST_P(EndToEndTest, LargePostSynchronousRequest) {
-  // Send a request and then disconnect. This prepares the client to attempt
-  // a 0-RTT handshake for the next request.
-  ASSERT_TRUE(Initialize());
-
-  std::string body(20480, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // The 0-RTT handshake should succeed.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  client_->Disconnect();
-
-  // Restart the server so that the 0-RTT handshake will take 1 RTT.
-  StopServer();
-  server_writer_ = new PacketDroppingTestWriter();
-  StartServer();
-
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  VerifyCleanConnection(false);
-}
-
-// This is a regression test for b/162595387
-TEST_P(EndToEndTest, PostZeroRTTRequestDuringHandshake) {
-  if (!version_.UsesTls()) {
-    // This test is TLS specific.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  // Send a request and then disconnect. This prepares the client to attempt
-  // a 0-RTT handshake for the next request.
-  NiceMock<MockQuicConnectionDebugVisitor> visitor;
-  connection_debug_visitor_ = &visitor;
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // The 0-RTT handshake should succeed.
-  ON_CALL(visitor, OnCryptoFrame(_))
-      .WillByDefault(Invoke([this](const QuicCryptoFrame& frame) {
-        if (frame.level != ENCRYPTION_HANDSHAKE) {
-          return;
-        }
-        // At this point in the handshake, the client should have derived
-        // ENCRYPTION_ZERO_RTT keys (thus set encryption_established). It
-        // should also have set ENCRYPTION_HANDSHAKE keys after receiving
-        // the server's ENCRYPTION_INITIAL flight.
-        EXPECT_TRUE(
-            GetClientSession()->GetCryptoStream()->encryption_established());
-        EXPECT_TRUE(
-            GetClientConnection()->framer().HasEncrypterOfEncryptionLevel(
-                ENCRYPTION_HANDSHAKE));
-        SpdyHeaderBlock headers;
-        headers[":method"] = "POST";
-        headers[":path"] = "/foo";
-        headers[":scheme"] = "https";
-        headers[":authority"] = server_hostname_;
-        EXPECT_GT(
-            client_->SendMessage(headers, "", /*fin*/ true, /*flush*/ false),
-            0);
-      }));
-  client_->Connect();
-  ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  client_->WaitForWriteToFlush();
-  client_->WaitForResponse();
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->response_body());
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-}
-
-// Regression test for b/166836136.
-TEST_P(EndToEndTest, RetransmissionAfterZeroRTTRejectBeforeOneRtt) {
-  if (!version_.UsesTls()) {
-    // This test is TLS specific.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  // Send a request and then disconnect. This prepares the client to attempt
-  // a 0-RTT handshake for the next request.
-  NiceMock<MockQuicConnectionDebugVisitor> visitor;
-  connection_debug_visitor_ = &visitor;
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  client_->Disconnect();
-
-  // Restart the server so that the 0-RTT handshake will take 1 RTT.
-  StopServer();
-  server_writer_ = new PacketDroppingTestWriter();
-  StartServer();
-
-  ON_CALL(visitor, OnZeroRttRejected(_)).WillByDefault(Invoke([this]() {
-    EXPECT_FALSE(GetClientSession()->IsEncryptionEstablished());
-  }));
-
-  // The 0-RTT handshake should fail.
-  client_->Connect();
-  ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  client_->WaitForWriteToFlush();
-  client_->WaitForResponse();
-  ASSERT_TRUE(client_->client()->connected());
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-}
-
-TEST_P(EndToEndTest, RejectWithPacketLoss) {
-  // In this test, we intentionally drop the first packet from the
-  // server, which corresponds with the initial REJ response from
-  // the server.
-  server_writer_->set_fake_drop_first_n_packets(1);
-  ASSERT_TRUE(Initialize());
-}
-
-TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
-  QuicTagVector initial_received_options;
-  initial_received_options.push_back(kTBBR);
-  initial_received_options.push_back(kIW10);
-  initial_received_options.push_back(kPRST);
-  EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
-      initial_received_options));
-
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
-      initial_received_options));
-
-  // Verify that server's configuration is correct.
-  server_thread_->Pause();
-  EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
-  EXPECT_TRUE(
-      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
-  EXPECT_TRUE(
-      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
-  EXPECT_TRUE(
-      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
-}
-
-TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
-  ASSERT_TRUE(Initialize());
-  SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
-  // 256KB per second with a 256KB buffer from server to client.  Wireless
-  // clients commonly have larger buffers, but our max CWND is 200.
-  server_writer_->set_max_bandwidth_and_buffer_size(
-      QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // 1 MB body.
-  std::string body(1024 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  // This connection may drop packets, because the buffer is smaller than the
-  // max CWND.
-  VerifyCleanConnection(true);
-}
-
-TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
-  // Regression test for b/14677858.
-  // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
-  // if currently connection level flow control blocked. If set, this results in
-  // an infinite loop in the EpollServer, as the alarm fires and is immediately
-  // rescheduled.
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // Ensure both stream and connection level are flow control blocked by setting
-  // the send window offset to 0.
-  const uint64_t flow_control_window =
-      server_config_.GetInitialStreamFlowControlWindowToSend();
-  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-  QuicSession* session = GetClientSession();
-  ASSERT_TRUE(session);
-  QuicStreamPeer::SetSendWindowOffset(stream, 0);
-  QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
-  EXPECT_TRUE(stream->IsFlowControlBlocked());
-  EXPECT_TRUE(session->flow_controller()->IsBlocked());
-
-  // Make sure that the stream has data pending so that it will be marked as
-  // write blocked when it receives a stream level WINDOW_UPDATE.
-  stream->WriteOrBufferBody("hello", false);
-
-  // The stream now attempts to write, fails because it is still connection
-  // level flow control blocked, and is added to the write blocked list.
-  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
-                                      2 * flow_control_window);
-  stream->OnWindowUpdateFrame(window_update);
-
-  // Prior to fixing b/14677858 this call would result in an infinite loop in
-  // Chromium. As a proxy for detecting this, we now check whether the
-  // send alarm is set after OnCanWrite. It should not be, as the
-  // connection is still flow control blocked.
-  session->connection()->OnCanWrite();
-
-  QuicAlarm* send_alarm =
-      QuicConnectionPeer::GetSendAlarm(session->connection());
-  EXPECT_FALSE(send_alarm->IsSet());
-}
-
-TEST_P(EndToEndTest, InvalidStream) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  std::string body(kMaxOutgoingPacketSize, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  // Force the client to write with a stream ID belonging to a nonexistent
-  // server-side stream.
-  QuicSpdySession* session = GetClientSession();
-  ASSERT_TRUE(session);
-  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
-      session, GetNthServerInitiatedBidirectionalId(0));
-
-  client_->SendCustomSynchronousRequest(headers, body);
-  EXPECT_THAT(client_->stream_error(),
-              IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_INVALID_STREAM_ID));
-}
-
-// Test that the server resets the stream if the client sends a request
-// with overly large headers.
-TEST_P(EndToEndTest, LargeHeaders) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  std::string body(kMaxOutgoingPacketSize, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["key1"] = std::string(15 * 1024, 'a');
-  headers["key2"] = std::string(15 * 1024, 'a');
-  headers["key3"] = std::string(15 * 1024, 'a');
-
-  client_->SendCustomSynchronousRequest(headers, body);
-
-  if (version_.UsesHttp3()) {
-    // QuicSpdyStream::OnHeadersTooLarge() resets the stream with
-    // QUIC_HEADERS_TOO_LARGE.  This is sent as H3_EXCESSIVE_LOAD, the closest
-    // HTTP/3 error code, and translated back to QUIC_STREAM_EXCESSIVE_LOAD on
-    // the receiving side.
-    EXPECT_THAT(client_->stream_error(),
-                IsStreamError(QUIC_STREAM_EXCESSIVE_LOAD));
-  } else {
-    EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
-  }
-  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  std::string large_body(1024 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  // Insert an invalid content_length field in request to trigger an early
-  // response from server.
-  headers["content-length"] = "-3";
-
-  client_->SendCustomSynchronousRequest(headers, large_body);
-  EXPECT_EQ("bad", client_->response_body());
-  CheckResponseHeaders("500");
-  EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
-  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-// TODO(rch): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
-  ASSERT_TRUE(Initialize());
-
-  // Set the offset so we won't frame.  Otherwise when we pick up termination
-  // before HTTP framing is complete, we send an error and close the stream,
-  // and the second write is picked up as writing on a closed stream.
-  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-  ASSERT_TRUE(stream != nullptr);
-  QuicStreamPeer::SetStreamBytesWritten(3, stream);
-
-  client_->SendData("bar", true);
-  client_->WaitForWriteToFlush();
-
-  // By default the stream protects itself from writes after terminte is set.
-  // Override this to test the server handling buggy clients.
-  QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
-
-  EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
-}
-
-TEST_P(EndToEndTest, Timeout) {
-  client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500));
-  // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
-  // that's enough to validate timeout in this case.
-  Initialize();
-  while (client_->client()->connected()) {
-    client_->client()->WaitForEvents();
-  }
-}
-
-TEST_P(EndToEndTest, MaxDynamicStreamsLimitRespected) {
-  // Set a limit on maximum number of incoming dynamic streams.
-  // Make sure the limit is respected by the peer.
-  const uint32_t kServerMaxDynamicStreams = 1;
-  server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
-  ASSERT_TRUE(Initialize());
-  if (version_.HasIetfQuicFrames()) {
-    // Do not run this test for /IETF QUIC. This test relies on the fact that
-    // Google QUIC allows a small number of additional streams beyond the
-    // negotiated limit, which is not supported in IETF QUIC. Note that the test
-    // needs to be here, after calling Initialize(), because all tests end up
-    // calling EndToEndTest::TearDown(), which asserts that Initialize has been
-    // called and then proceeds to tear things down -- which fails if they are
-    // not properly set up.
-    return;
-  }
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // Make the client misbehave after negotiation.
-  const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicSessionPeer::SetMaxOpenOutgoingStreams(client_session,
-                                             kServerMaxStreams + 1);
-
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = "3";
-
-  // The server supports a small number of additional streams beyond the
-  // negotiated limit. Open enough streams to go beyond that limit.
-  for (int i = 0; i < kServerMaxStreams + 1; ++i) {
-    client_->SendMessage(headers, "", /*fin=*/false);
-  }
-  client_->WaitForResponse();
-
-  EXPECT_TRUE(client_->connected());
-  EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_REFUSED_STREAM));
-  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) {
-  // Each endpoint can set max dynamic streams independently.
-  const uint32_t kClientMaxDynamicStreams = 4;
-  const uint32_t kServerMaxDynamicStreams = 3;
-  client_config_.SetMaxBidirectionalStreamsToSend(kClientMaxDynamicStreams);
-  server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
-  client_config_.SetMaxUnidirectionalStreamsToSend(kClientMaxDynamicStreams);
-  server_config_.SetMaxUnidirectionalStreamsToSend(kServerMaxDynamicStreams);
-
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // The client has received the server's limit and vice versa.
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  // The value returned by max_allowed... includes the Crypto and Header
-  // stream (created as a part of initialization). The config. values,
-  // above, are treated as "number of requests/responses" - that is, they do
-  // not include the static Crypto and Header streams. Reduce the value
-  // returned by max_allowed... by 2 to remove the static streams from the
-  // count.
-  size_t client_max_open_outgoing_bidirectional_streams =
-      version_.HasIetfQuicFrames()
-          ? QuicSessionPeer::ietf_streamid_manager(client_session)
-                ->max_outgoing_bidirectional_streams()
-          : QuicSessionPeer::GetStreamIdManager(client_session)
-                ->max_open_outgoing_streams();
-  size_t client_max_open_outgoing_unidirectional_streams =
-      version_.HasIetfQuicFrames()
-          ? QuicSessionPeer::ietf_streamid_manager(client_session)
-                    ->max_outgoing_unidirectional_streams() -
-                kHttp3StaticUnidirectionalStreamCount
-          : QuicSessionPeer::GetStreamIdManager(client_session)
-                ->max_open_outgoing_streams();
-  EXPECT_EQ(kServerMaxDynamicStreams,
-            client_max_open_outgoing_bidirectional_streams);
-  EXPECT_EQ(kServerMaxDynamicStreams,
-            client_max_open_outgoing_unidirectional_streams);
-  server_thread_->Pause();
-  QuicSession* server_session = GetServerSession();
-  if (server_session != nullptr) {
-    size_t server_max_open_outgoing_bidirectional_streams =
-        version_.HasIetfQuicFrames()
-            ? QuicSessionPeer::ietf_streamid_manager(server_session)
-                  ->max_outgoing_bidirectional_streams()
-            : QuicSessionPeer::GetStreamIdManager(server_session)
-                  ->max_open_outgoing_streams();
-    size_t server_max_open_outgoing_unidirectional_streams =
-        version_.HasIetfQuicFrames()
-            ? QuicSessionPeer::ietf_streamid_manager(server_session)
-                      ->max_outgoing_unidirectional_streams() -
-                  kHttp3StaticUnidirectionalStreamCount
-            : QuicSessionPeer::GetStreamIdManager(server_session)
-                  ->max_open_outgoing_streams();
-    EXPECT_EQ(kClientMaxDynamicStreams,
-              server_max_open_outgoing_bidirectional_streams);
-    EXPECT_EQ(kClientMaxDynamicStreams,
-              server_max_open_outgoing_unidirectional_streams);
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, NegotiateCongestionControl) {
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  CongestionControlType expected_congestion_control_type = kRenoBytes;
-  switch (GetParam().congestion_control_tag) {
-    case kRENO:
-      expected_congestion_control_type = kRenoBytes;
-      break;
-    case kTBBR:
-      expected_congestion_control_type = kBBR;
-      break;
-    case kQBIC:
-      expected_congestion_control_type = kCubicBytes;
-      break;
-    case kB2ON:
-      expected_congestion_control_type = kBBRv2;
-      break;
-    default:
-      QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
-  }
-
-  server_thread_->Pause();
-  const QuicSentPacketManager* server_sent_packet_manager =
-      GetSentPacketManagerFromFirstServerSession();
-  if (server_sent_packet_manager != nullptr) {
-    EXPECT_EQ(
-        expected_congestion_control_type,
-        QuicSentPacketManagerPeer::GetSendAlgorithm(*server_sent_packet_manager)
-            ->GetCongestionControlType());
-  } else {
-    ADD_FAILURE() << "Missing server sent packet manager";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ClientSuggestsRTT) {
-  // Client suggests initial RTT, verify it is used.
-  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
-  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
-
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(server_thread_);
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Pause the server so we can access the server's internals without races.
-  server_thread_->Pause();
-  const QuicSentPacketManager* client_sent_packet_manager =
-      GetSentPacketManagerFromClientSession();
-  const QuicSentPacketManager* server_sent_packet_manager =
-      GetSentPacketManagerFromFirstServerSession();
-  if (client_sent_packet_manager != nullptr &&
-      server_sent_packet_manager != nullptr) {
-    EXPECT_EQ(kInitialRTT,
-              client_sent_packet_manager->GetRttStats()->initial_rtt());
-    EXPECT_EQ(kInitialRTT,
-              server_sent_packet_manager->GetRttStats()->initial_rtt());
-  } else {
-    ADD_FAILURE() << "Missing sent packet manager";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
-  // Client suggests initial RTT, but also specifies NRTT, so it's not used.
-  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
-  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
-  QuicTagVector options;
-  options.push_back(kNRTT);
-  client_config_.SetConnectionOptionsToSend(options);
-
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(server_thread_);
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Pause the server so we can access the server's internals without races.
-  server_thread_->Pause();
-  const QuicSentPacketManager* client_sent_packet_manager =
-      GetSentPacketManagerFromClientSession();
-  const QuicSentPacketManager* server_sent_packet_manager =
-      GetSentPacketManagerFromFirstServerSession();
-  if (client_sent_packet_manager != nullptr &&
-      server_sent_packet_manager != nullptr) {
-    EXPECT_EQ(kInitialRTT,
-              client_sent_packet_manager->GetRttStats()->initial_rtt());
-    EXPECT_EQ(kInitialRTT,
-              server_sent_packet_manager->GetRttStats()->initial_rtt());
-  } else {
-    ADD_FAILURE() << "Missing sent packet manager";
-  }
-  server_thread_->Resume();
-}
-
-// Regression test for b/171378845
-TEST_P(EndToEndTest, ClientDisablesGQuicZeroRtt) {
-  if (version_.UsesTls()) {
-    // This feature is gQUIC only.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  QuicTagVector options;
-  options.push_back(kQNZ2);
-  client_config_.SetClientConnectionOptions(options);
-
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_session->ReceivedInchoateReject());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
-
-  client_->Disconnect();
-
-  // Make sure that the request succeeds but 0-RTT was not used.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
-}
-
-TEST_P(EndToEndTest, MaxInitialRTT) {
-  // Client tries to suggest twice the server's max initial rtt and the server
-  // uses the max.
-  client_config_.SetInitialRoundTripTimeUsToSend(2 *
-                                                 kMaxInitialRoundTripTimeUs);
-
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(server_thread_);
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Pause the server so we can access the server's internals without races.
-  server_thread_->Pause();
-  const QuicSentPacketManager* client_sent_packet_manager =
-      GetSentPacketManagerFromClientSession();
-  const QuicSentPacketManager* server_sent_packet_manager =
-      GetSentPacketManagerFromFirstServerSession();
-  if (client_sent_packet_manager != nullptr &&
-      server_sent_packet_manager != nullptr) {
-    // Now that acks have been exchanged, the RTT estimate has decreased on the
-    // server and is not infinite on the client.
-    EXPECT_FALSE(
-        client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
-    const RttStats* server_rtt_stats =
-        server_sent_packet_manager->GetRttStats();
-    EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
-              server_rtt_stats->initial_rtt().ToMicroseconds());
-    EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
-              server_rtt_stats->smoothed_rtt().ToMicroseconds());
-  } else {
-    ADD_FAILURE() << "Missing sent packet manager";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, MinInitialRTT) {
-  // Client tries to suggest 0 and the server uses the default.
-  client_config_.SetInitialRoundTripTimeUsToSend(0);
-
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Pause the server so we can access the server's internals without races.
-  server_thread_->Pause();
-  const QuicSentPacketManager* client_sent_packet_manager =
-      GetSentPacketManagerFromClientSession();
-  const QuicSentPacketManager* server_sent_packet_manager =
-      GetSentPacketManagerFromFirstServerSession();
-  if (client_sent_packet_manager != nullptr &&
-      server_sent_packet_manager != nullptr) {
-    // Now that acks have been exchanged, the RTT estimate has decreased on the
-    // server and is not infinite on the client.
-    EXPECT_FALSE(
-        client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
-    // Expect the default rtt of 100ms.
-    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
-              server_sent_packet_manager->GetRttStats()->initial_rtt());
-    // Ensure the bandwidth is valid.
-    client_sent_packet_manager->BandwidthEstimate();
-    server_sent_packet_manager->BandwidthEstimate();
-  } else {
-    ADD_FAILURE() << "Missing sent packet manager";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, 0ByteConnectionId) {
-  if (version_.HasIetfInvariantHeader()) {
-    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetBytesForConnectionIdToSend(0);
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicPacketHeader* header =
-      QuicConnectionPeer::GetLastHeader(client_connection);
-  EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
-}
-
-TEST_P(EndToEndTest, 8ByteConnectionId) {
-  if (version_.HasIetfInvariantHeader()) {
-    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetBytesForConnectionIdToSend(8);
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicPacketHeader* header =
-      QuicConnectionPeer::GetLastHeader(client_connection);
-  EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
-}
-
-TEST_P(EndToEndTest, 15ByteConnectionId) {
-  if (version_.HasIetfInvariantHeader()) {
-    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetBytesForConnectionIdToSend(15);
-  ASSERT_TRUE(Initialize());
-
-  // Our server is permissive and allows for out of bounds values.
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicPacketHeader* header =
-      QuicConnectionPeer::GetLastHeader(client_connection);
-  EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
-}
-
-TEST_P(EndToEndTest, ResetConnection) {
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  client_->ResetConnection();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  SendSynchronousBarRequestAndCheckResponse();
-}
-
-// Regression test for b/180737158.
-TEST_P(
-    EndToEndTest,
-    HalfRttResponseBlocksShloRetransmissionWithoutTokenBasedAddressValidation) {
-  // Turn off token based address validation to make the server get constrained
-  // by amplification factor during handshake.
-  SetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet, true);
-  ASSERT_TRUE(Initialize());
-  if (!version_.SupportsAntiAmplificationLimit()) {
-    return;
-  }
-  // Perform a full 1-RTT handshake to get the new session ticket such that the
-  // next connection will perform a 0-RTT handshake.
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  client_->Disconnect();
-
-  server_thread_->Pause();
-  // Drop the 1st server packet which is the coalesced INITIAL + HANDSHAKE +
-  // 1RTT.
-  PacketDroppingTestWriter* writer = new PacketDroppingTestWriter();
-  writer->set_fake_drop_first_n_packets(1);
-  QuicDispatcherPeer::UseWriter(
-      QuicServerPeer::GetDispatcher(server_thread_->server()), writer);
-  server_thread_->Resume();
-
-  // Large response (100KB) for 0-RTT request.
-  std::string large_body(102400, 'a');
-  AddToCache("/large_response", 200, large_body);
-  SendSynchronousRequestAndCheckResponse(client_.get(), "/large_response",
-                                         large_body);
-}
-
-TEST_P(EndToEndTest, MaxStreamsUberTest) {
-  // Connect with lower fake packet loss than we'd like to test.  Until
-  // b/10126687 is fixed, losing handshake packets is pretty brutal.
-  SetPacketLossPercentage(1);
-  ASSERT_TRUE(Initialize());
-  std::string large_body(10240, 'a');
-  int max_streams = 100;
-
-  AddToCache("/large_response", 200, large_body);
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  SetPacketLossPercentage(10);
-
-  for (int i = 0; i < max_streams; ++i) {
-    EXPECT_LT(0, client_->SendRequest("/large_response"));
-  }
-
-  // WaitForEvents waits 50ms and returns true if there are outstanding
-  // requests.
-  while (client_->client()->WaitForEvents()) {
-    ASSERT_TRUE(client_->connected());
-  }
-}
-
-TEST_P(EndToEndTest, StreamCancelErrorTest) {
-  ASSERT_TRUE(Initialize());
-  std::string small_body(256, 'a');
-
-  AddToCache("/small_response", 200, small_body);
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  QuicSession* session = GetClientSession();
-  ASSERT_TRUE(session);
-  // Lose the request.
-  SetPacketLossPercentage(100);
-  EXPECT_LT(0, client_->SendRequest("/small_response"));
-  client_->client()->WaitForEvents();
-  // Transmit the cancel, and ensure the connection is torn down properly.
-  SetPacketLossPercentage(0);
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  const QuicPacketCount packets_sent_before =
-      client_connection->GetStats().packets_sent;
-  session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
-  const QuicPacketCount packets_sent_now =
-      client_connection->GetStats().packets_sent;
-
-  if (version_.UsesHttp3()) {
-    // Make sure 2 packets were sent, one for QPACK instructions, another for
-    // RESET_STREAM and STOP_SENDING.
-    EXPECT_EQ(packets_sent_before + 2, packets_sent_now);
-  }
-
-  // WaitForEvents waits 50ms and returns true if there are outstanding
-  // requests.
-  while (client_->client()->WaitForEvents()) {
-    ASSERT_TRUE(client_->connected());
-  }
-  // It should be completely fine to RST a stream before any data has been
-  // received for that stream.
-  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress old_host =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_host, new_host);
-  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  if (!version_.HasIetfQuicFrames() ||
-      !client_->client()->session()->connection()->validate_client_address()) {
-    return;
-  }
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Send another request.
-  SendSynchronousBarRequestAndCheckResponse();
-  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
-  // received by the server.
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_FALSE(server_connection->HasPendingPathValidation());
-    EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, IetfConnectionMigrationClientIPChangedMultipleTimes) {
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress host0 =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection != nullptr);
-
-  // Migrate socket to a new IP address.
-  QuicIpAddress host1 = TestLoopback(2);
-  EXPECT_NE(host0, host1);
-  ASSERT_TRUE(
-      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-  QuicConnectionId server_cid0 = client_connection->connection_id();
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
-  QuicConnectionId server_cid1 = client_connection->connection_id();
-  EXPECT_FALSE(server_cid1.IsEmpty());
-  EXPECT_NE(server_cid0, server_cid1);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Send another request and wait for response making sure path response is
-  // received at server.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  // Migrate socket to a new IP address.
-  WaitForNewConnectionIds();
-  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
-  QuicIpAddress host2 = TestLoopback(3);
-  EXPECT_NE(host0, host2);
-  EXPECT_NE(host1, host2);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(client_->client()->MigrateSocket(host2));
-  QuicConnectionId server_cid2 = client_connection->connection_id();
-  EXPECT_FALSE(server_cid2.IsEmpty());
-  EXPECT_NE(server_cid0, server_cid2);
-  EXPECT_NE(server_cid1, server_cid2);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send another request using the new socket and wait for response making sure
-  // path response is received at server.
-  SendSynchronousBarRequestAndCheckResponse();
-  EXPECT_EQ(2u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Migrate socket back to an old IP address.
-  WaitForNewConnectionIds();
-  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
-  QuicConnectionId server_cid3 = client_connection->connection_id();
-  EXPECT_FALSE(server_cid3.IsEmpty());
-  EXPECT_NE(server_cid0, server_cid3);
-  EXPECT_NE(server_cid1, server_cid3);
-  EXPECT_NE(server_cid2, server_cid3);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  const auto* client_packet_creator =
-      QuicConnectionPeer::GetPacketCreator(client_connection);
-  EXPECT_TRUE(client_packet_creator->GetClientConnectionId().IsEmpty());
-  EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
-
-  // Send another request using the new socket and wait for response making sure
-  // path response is received at server.
-  SendSynchronousBarRequestAndCheckResponse();
-  // Even this is an old path, server has forgotten about it and thus needs to
-  // validate the path again.
-  EXPECT_EQ(3u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  WaitForNewConnectionIds();
-  EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
-  // received by the server.
-  EXPECT_FALSE(server_connection->HasPendingPathValidation());
-  EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
-  EXPECT_EQ(server_cid3, server_connection->connection_id());
-  const auto* server_packet_creator =
-      QuicConnectionPeer::GetPacketCreator(server_connection);
-  EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  server_connection)
-                  .IsEmpty());
-  EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest,
-       ConnectionMigrationWithNonZeroConnectionIDClientIPChangedMultipleTimes) {
-  if (!version_.SupportsClientConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress host0 =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection != nullptr);
-
-  // Migrate socket to a new IP address.
-  QuicIpAddress host1 = TestLoopback(2);
-  EXPECT_NE(host0, host1);
-  ASSERT_TRUE(
-      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-  QuicConnectionId server_cid0 = client_connection->connection_id();
-  QuicConnectionId client_cid0 = client_connection->client_connection_id();
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
-  QuicConnectionId server_cid1 = client_connection->connection_id();
-  QuicConnectionId client_cid1 = client_connection->client_connection_id();
-  EXPECT_FALSE(server_cid1.IsEmpty());
-  EXPECT_FALSE(client_cid1.IsEmpty());
-  EXPECT_NE(server_cid0, server_cid1);
-  EXPECT_NE(client_cid0, client_cid1);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send another request to ensure that the server will have time to finish the
-  // reverse path validation and send address token.
-  SendSynchronousBarRequestAndCheckResponse();
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Migrate socket to a new IP address.
-  WaitForNewConnectionIds();
-  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
-  QuicIpAddress host2 = TestLoopback(3);
-  EXPECT_NE(host0, host2);
-  EXPECT_NE(host1, host2);
-  EXPECT_TRUE(client_->client()->MigrateSocket(host2));
-  QuicConnectionId server_cid2 = client_connection->connection_id();
-  QuicConnectionId client_cid2 = client_connection->client_connection_id();
-  EXPECT_FALSE(server_cid2.IsEmpty());
-  EXPECT_NE(server_cid0, server_cid2);
-  EXPECT_NE(server_cid1, server_cid2);
-  EXPECT_FALSE(client_cid2.IsEmpty());
-  EXPECT_NE(client_cid0, client_cid2);
-  EXPECT_NE(client_cid1, client_cid2);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send another request to ensure that the server will have time to finish the
-  // reverse path validation and send address token.
-  SendSynchronousBarRequestAndCheckResponse();
-  EXPECT_EQ(2u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Migrate socket back to an old IP address.
-  WaitForNewConnectionIds();
-  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
-  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
-  QuicConnectionId server_cid3 = client_connection->connection_id();
-  QuicConnectionId client_cid3 = client_connection->client_connection_id();
-  EXPECT_FALSE(server_cid3.IsEmpty());
-  EXPECT_NE(server_cid0, server_cid3);
-  EXPECT_NE(server_cid1, server_cid3);
-  EXPECT_NE(server_cid2, server_cid3);
-  EXPECT_FALSE(client_cid3.IsEmpty());
-  EXPECT_NE(client_cid0, client_cid3);
-  EXPECT_NE(client_cid1, client_cid3);
-  EXPECT_NE(client_cid2, client_cid3);
-  const auto* client_packet_creator =
-      QuicConnectionPeer::GetPacketCreator(client_connection);
-  EXPECT_EQ(client_cid3, client_packet_creator->GetClientConnectionId());
-  EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send another request to ensure that the server will have time to finish the
-  // reverse path validation and send address token.
-  SendSynchronousBarRequestAndCheckResponse();
-  // Even this is an old path, server has forgotten about it and thus needs to
-  // validate the path again.
-  EXPECT_EQ(3u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  WaitForNewConnectionIds();
-  EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(4u, client_connection->GetStats().num_new_connection_id_sent);
-
-  server_thread_->Pause();
-  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
-  // received by the server.
-  QuicConnection* server_connection = GetServerConnection();
-  EXPECT_FALSE(server_connection->HasPendingPathValidation());
-  EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
-  EXPECT_EQ(server_cid3, server_connection->connection_id());
-  EXPECT_EQ(client_cid3, server_connection->client_connection_id());
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  server_connection)
-                  .IsEmpty());
-  const auto* server_packet_creator =
-      QuicConnectionPeer::GetPacketCreator(server_connection);
-  EXPECT_EQ(client_cid3, server_packet_creator->GetClientConnectionId());
-  EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
-  EXPECT_EQ(3u, server_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationNewTokenForNewIp) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames() ||
-      !client_->client()->session()->connection()->validate_client_address()) {
-    return;
-  }
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress old_host =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_host, new_host);
-  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Send another request to ensure that the server will have time to finish the
-  // reverse path validation and send address token.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  client_->Disconnect();
-  // The 0-RTT handshake should succeed.
-  client_->Connect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-  SendSynchronousFooRequestAndCheckResponse();
-
-  EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    // Verify address is validated via validating token received in INITIAL
-    // packet.
-    EXPECT_FALSE(
-        server_connection->GetStats().address_validated_via_decrypting_packet);
-    EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-  client_->Disconnect();
-}
-
-// A writer which copies the packet and send the copy with a specified self
-// address and then send the same packet with the original self address.
-class DuplicatePacketWithSpoofedSelfAddressWriter
-    : public QuicPacketWriterWrapper {
- public:
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override {
-    if (self_address_to_overwrite_.IsInitialized()) {
-      // Send the same packet on the overwriting address before sending on the
-      // actual self address.
-      QuicPacketWriterWrapper::WritePacket(
-          buffer, buf_len, self_address_to_overwrite_, peer_address, options);
-    }
-    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
-                                                peer_address, options);
-  }
-
-  void set_self_address_to_overwrite(const QuicIpAddress& self_address) {
-    self_address_to_overwrite_ = self_address;
-  }
-
- private:
-  QuicIpAddress self_address_to_overwrite_;
-};
-
-TEST_P(EndToEndTest, ClientAddressSpoofedForSomePeriod) {
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-  auto writer = new DuplicatePacketWithSpoofedSelfAddressWriter();
-  client_.reset(CreateQuicClient(writer));
-
-  // Make sure client has unused peer connection ID before migration.
-  SendSynchronousFooRequestAndCheckResponse();
-  ASSERT_TRUE(QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
-      GetClientConnection()));
-
-  QuicIpAddress real_host =
-      client_->client()->session()->connection()->self_address().host();
-  ASSERT_TRUE(client_->MigrateSocket(real_host));
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(
-      0u, GetClientConnection()->GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(
-      real_host,
-      client_->client()->network_helper()->GetLatestClientAddress().host());
-  client_->WaitForDelayedAcks();
-
-  std::string large_body(10240, 'a');
-  AddToCache("/large_response", 200, large_body);
-
-  QuicIpAddress spoofed_host = TestLoopback(2);
-  writer->set_self_address_to_overwrite(spoofed_host);
-
-  client_->SendRequest("/large_response");
-  QuicConnection* client_connection = GetClientConnection();
-  QuicPacketCount num_packets_received =
-      client_connection->GetStats().packets_received;
-
-  while (client_->client()->WaitForEvents() && client_->connected()) {
-    if (client_connection->GetStats().packets_received > num_packets_received) {
-      // Ideally the client won't receive any packets till the server finds out
-      // the new client address is not working. But there are 2 corner cases:
-      // 1) Before the server received the packet from spoofed address, it might
-      // send packets to the real client address. So the client will immediately
-      // switch back to use the original address;
-      // 2) Between the server fails reverse path validation and the client
-      // receives packets again, the client might sent some packets with the
-      // spoofed address and triggers another migration.
-      // In both corner cases, the attempted migration should fail and fall back
-      // to the working path.
-      writer->set_self_address_to_overwrite(QuicIpAddress());
-    }
-  }
-  client_->WaitForResponse();
-  EXPECT_EQ(large_body, client_->response_body());
-}
-
-TEST_P(EndToEndTest,
-       AsynchronousConnectionMigrationClientIPChangedMultipleTimes) {
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-  client_.reset(CreateQuicClient(nullptr));
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress host0 =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-  QuicConnection* client_connection = GetClientConnection();
-  QuicConnectionId server_cid0 = client_connection->connection_id();
-  // Server should have one new connection ID upon handshake completion.
-  ASSERT_TRUE(
-      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-
-  // Migrate socket to new IP address #1.
-  QuicIpAddress host1 = TestLoopback(2);
-  EXPECT_NE(host0, host1);
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(host1, client_->client()->session()->self_address().host());
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-  QuicConnectionId server_cid1 = client_connection->connection_id();
-  EXPECT_NE(server_cid0, server_cid1);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  // Migrate socket to new IP address #2.
-  WaitForNewConnectionIds();
-  QuicIpAddress host2 = TestLoopback(3);
-  EXPECT_NE(host0, host1);
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
-
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(host2, client_->client()->session()->self_address().host());
-  EXPECT_EQ(2u,
-            client_connection->GetStats().num_connectivity_probing_received);
-  QuicConnectionId server_cid2 = client_connection->connection_id();
-  EXPECT_NE(server_cid0, server_cid2);
-  EXPECT_NE(server_cid1, server_cid2);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  // Migrate socket back to IP address #1.
-  WaitForNewConnectionIds();
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
-
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(host1, client_->client()->session()->self_address().host());
-  EXPECT_EQ(3u,
-            client_connection->GetStats().num_connectivity_probing_received);
-  QuicConnectionId server_cid3 = client_connection->connection_id();
-  EXPECT_NE(server_cid0, server_cid3);
-  EXPECT_NE(server_cid1, server_cid3);
-  EXPECT_NE(server_cid2, server_cid3);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-  server_thread_->Pause();
-  const QuicConnection* server_connection = GetServerConnection();
-  EXPECT_EQ(server_connection->connection_id(), server_cid3);
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  server_connection)
-                  .IsEmpty());
-  server_thread_->Resume();
-
-  // There should be 1 new connection ID issued by the server.
-  WaitForNewConnectionIds();
-}
-
-TEST_P(EndToEndTest,
-       AsynchronousConnectionMigrationClientIPChangedWithNonEmptyClientCID) {
-  if (!version_.SupportsClientConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-  client_.reset(CreateQuicClient(nullptr));
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress old_host =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-  auto* client_connection = GetClientConnection();
-  QuicConnectionId client_cid0 = client_connection->client_connection_id();
-  QuicConnectionId server_cid0 = client_connection->connection_id();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_host, new_host);
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
-
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(new_host, client_->client()->session()->self_address().host());
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-  QuicConnectionId client_cid1 = client_connection->client_connection_id();
-  QuicConnectionId server_cid1 = client_connection->connection_id();
-  const auto* client_packet_creator =
-      QuicConnectionPeer::GetPacketCreator(client_connection);
-  EXPECT_EQ(client_cid1, client_packet_creator->GetClientConnectionId());
-  EXPECT_EQ(server_cid1, client_packet_creator->GetServerConnectionId());
-  // Send a request using the new socket.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  EXPECT_EQ(client_cid1, server_connection->client_connection_id());
-  EXPECT_EQ(server_cid1, server_connection->connection_id());
-  const auto* server_packet_creator =
-      QuicConnectionPeer::GetPacketCreator(server_connection);
-  EXPECT_EQ(client_cid1, server_packet_creator->GetClientConnectionId());
-  EXPECT_EQ(server_cid1, server_packet_creator->GetServerConnectionId());
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
-  // Tests that the client's port can change during an established QUIC
-  // connection, and that doing so does not result in the connection being
-  // closed by the server.
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client address which was used to send the first request.
-  QuicSocketAddress old_address =
-      client_->client()->network_helper()->GetLatestClientAddress();
-  int old_fd = client_->client()->GetLatestFD();
-
-  // Create a new socket before closing the old one, which will result in a new
-  // ephemeral port.
-  QuicClientPeer::CreateUDPSocketAndBind(client_->client());
-
-  // Stop listening and close the old FD.
-  QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
-
-  // The packet writer needs to be updated to use the new FD.
-  client_->client()->network_helper()->CreateQuicPacketWriter();
-
-  // Change the internal state of the client and connection to use the new port,
-  // this is done because in a real NAT rebinding the client wouldn't see any
-  // port change, and so expects no change to incoming port.
-  // This is kind of ugly, but needed as we are simply swapping out the client
-  // FD rather than any more complex NAT rebinding simulation.
-  int new_port =
-      client_->client()->network_helper()->GetLatestClientAddress().port();
-  QuicClientPeer::SetClientPort(client_->client(), new_port);
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionPeer::SetSelfAddress(
-      client_connection,
-      QuicSocketAddress(client_connection->self_address().host(), new_port));
-
-  // Register the new FD for epoll events.
-  int new_fd = client_->client()->GetLatestFD();
-  QuicEpollServer* eps = client_->epoll_server();
-  eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
-                  EPOLLIN | EPOLLOUT | EPOLLET);
-
-  // Send a second request, using the new FD.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  // Verify that the client's ephemeral port is different.
-  QuicSocketAddress new_address =
-      client_->client()->network_helper()->GetLatestClientAddress();
-  EXPECT_EQ(old_address.host(), new_address.host());
-  EXPECT_NE(old_address.port(), new_address.port());
-
-  if (!version_.HasIetfQuicFrames() ||
-      !GetClientConnection()->validate_client_address()) {
-    return;
-  }
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_FALSE(server_connection->HasPendingPathValidation());
-    EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
-  SetQuicReloadableFlag(quic_unified_iw_options, true);
-  client_extra_copts_.push_back(kIW03);
-
-  ASSERT_TRUE(Initialize());
-
-  // Values are exchanged during crypto handshake, so wait for that to finish.
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    QuicPacketCount cwnd =
-        server_connection->sent_packet_manager().initial_congestion_window();
-    EXPECT_EQ(3u, cwnd);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, DifferentFlowControlWindows) {
-  // Client and server can set different initial flow control receive windows.
-  // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
-  // in the crypto handshake.
-  const uint32_t kClientStreamIFCW = 123456;
-  const uint32_t kClientSessionIFCW = 234567;
-  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
-  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
-
-  uint32_t kServerStreamIFCW = 32 * 1024;
-  uint32_t kServerSessionIFCW = 48 * 1024;
-  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
-  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
-
-  ASSERT_TRUE(Initialize());
-
-  // Values are exchanged during crypto handshake, so wait for that to finish.
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Open a data stream to make sure the stream level flow control is updated.
-  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-  WriteHeadersOnStream(stream);
-  stream->WriteOrBufferBody("hello", false);
-
-  if (!version_.UsesTls()) {
-    // IFWA only exists with QUIC_CRYPTO.
-    // Client should have the right values for server's receive window.
-    ASSERT_TRUE(client_->client()
-                    ->client_session()
-                    ->config()
-                    ->HasReceivedInitialStreamFlowControlWindowBytes());
-    EXPECT_EQ(kServerStreamIFCW,
-              client_->client()
-                  ->client_session()
-                  ->config()
-                  ->ReceivedInitialStreamFlowControlWindowBytes());
-    ASSERT_TRUE(client_->client()
-                    ->client_session()
-                    ->config()
-                    ->HasReceivedInitialSessionFlowControlWindowBytes());
-    EXPECT_EQ(kServerSessionIFCW,
-              client_->client()
-                  ->client_session()
-                  ->config()
-                  ->ReceivedInitialSessionFlowControlWindowBytes());
-  }
-  EXPECT_EQ(kServerStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
-                                    client_session->flow_controller()));
-
-  // Server should have the right values for client's receive window.
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  if (server_session == nullptr) {
-    ADD_FAILURE() << "Missing server session";
-    server_thread_->Resume();
-    return;
-  }
-  QuicConfig server_config = *server_session->config();
-  EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
-                                    server_session->flow_controller()));
-  server_thread_->Resume();
-  if (version_.UsesTls()) {
-    // IFWA only exists with QUIC_CRYPTO.
-    return;
-  }
-  ASSERT_TRUE(server_config.HasReceivedInitialStreamFlowControlWindowBytes());
-  EXPECT_EQ(kClientStreamIFCW,
-            server_config.ReceivedInitialStreamFlowControlWindowBytes());
-  ASSERT_TRUE(server_config.HasReceivedInitialSessionFlowControlWindowBytes());
-  EXPECT_EQ(kClientSessionIFCW,
-            server_config.ReceivedInitialSessionFlowControlWindowBytes());
-}
-
-// Test negotiation of IFWA connection option.
-TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
-  const uint32_t kClientStreamIFCW = 123456;
-  const uint32_t kClientSessionIFCW = 234567;
-  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
-  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
-
-  uint32_t kServerStreamIFCW = 32 * 1024;
-  uint32_t kServerSessionIFCW = 48 * 1024;
-  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
-  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
-
-  // Bump the window.
-  const uint32_t kExpectedStreamIFCW = 1024 * 1024;
-  const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
-  client_extra_copts_.push_back(kIFWA);
-
-  ASSERT_TRUE(Initialize());
-
-  // Values are exchanged during crypto handshake, so wait for that to finish.
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  // Open a data stream to make sure the stream level flow control is updated.
-  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-  WriteHeadersOnStream(stream);
-  stream->WriteOrBufferBody("hello", false);
-
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-
-  if (!version_.UsesTls()) {
-    // IFWA only exists with QUIC_CRYPTO.
-    // Client should have the right values for server's receive window.
-    ASSERT_TRUE(client_session->config()
-                    ->HasReceivedInitialStreamFlowControlWindowBytes());
-    EXPECT_EQ(kExpectedStreamIFCW,
-              client_session->config()
-                  ->ReceivedInitialStreamFlowControlWindowBytes());
-    ASSERT_TRUE(client_session->config()
-                    ->HasReceivedInitialSessionFlowControlWindowBytes());
-    EXPECT_EQ(kExpectedSessionIFCW,
-              client_session->config()
-                  ->ReceivedInitialSessionFlowControlWindowBytes());
-  }
-  EXPECT_EQ(kExpectedStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
-  EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
-                                      client_session->flow_controller()));
-}
-
-TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
-  // The special headers and crypto streams should be subject to per-stream flow
-  // control limits, but should not be subject to connection level flow control
-  const uint32_t kStreamIFCW = 32 * 1024;
-  const uint32_t kSessionIFCW = 48 * 1024;
-  set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
-  set_client_initial_session_flow_control_receive_window(kSessionIFCW);
-  set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
-  set_server_initial_session_flow_control_receive_window(kSessionIFCW);
-
-  ASSERT_TRUE(Initialize());
-
-  // Wait for crypto handshake to finish. This should have contributed to the
-  // crypto stream flow control window, but not affected the session flow
-  // control window.
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicCryptoStream* crypto_stream =
-      QuicSessionPeer::GetMutableCryptoStream(client_session);
-  ASSERT_TRUE(crypto_stream);
-  // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
-  // subject to flow control.
-  if (!version_.UsesCryptoFrames()) {
-    EXPECT_LT(QuicStreamPeer::SendWindowSize(crypto_stream), kStreamIFCW);
-  }
-  // When stream type is enabled, control streams will send settings and
-  // contribute to flow control windows, so this expectation is no longer valid.
-  if (!version_.UsesHttp3()) {
-    EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
-                                client_session->flow_controller()));
-  }
-
-  // Send a request with no body, and verify that the connection level window
-  // has not been affected.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // No headers stream in IETF QUIC.
-  if (version_.UsesHttp3()) {
-    return;
-  }
-
-  QuicHeadersStream* headers_stream =
-      QuicSpdySessionPeer::GetHeadersStream(client_session);
-  ASSERT_TRUE(headers_stream);
-  EXPECT_LT(QuicStreamPeer::SendWindowSize(headers_stream), kStreamIFCW);
-  EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
-                              client_session->flow_controller()));
-
-  // Server should be in a similar state: connection flow control window should
-  // not have any bytes marked as received.
-  server_thread_->Pause();
-  QuicSession* server_session = GetServerSession();
-  if (server_session != nullptr) {
-    QuicFlowController* server_connection_flow_controller =
-        server_session->flow_controller();
-    EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
-                                server_connection_flow_controller));
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, FlowControlsSynced) {
-  set_smaller_flow_control_receive_window();
-
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  server_thread_->WaitForCryptoHandshakeConfirmed();
-
-  QuicSpdySession* const client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-
-  if (version_.UsesHttp3()) {
-    // Make sure that the client has received the initial SETTINGS frame, which
-    // is sent in the first packet on the control stream.
-    while (!QuicSpdySessionPeer::GetReceiveControlStream(client_session)) {
-      client_->client()->WaitForEvents();
-      ASSERT_TRUE(client_->connected());
-    }
-  }
-
-  // Make sure that all data sent by the client has been received by the server
-  // (and the ack received by the client).
-  while (client_session->HasUnackedStreamData()) {
-    client_->client()->WaitForEvents();
-    ASSERT_TRUE(client_->connected());
-  }
-
-  server_thread_->Pause();
-
-  QuicSpdySession* const server_session = GetServerSession();
-  if (server_session == nullptr) {
-    ADD_FAILURE() << "Missing server session";
-    server_thread_->Resume();
-    return;
-  }
-  ExpectFlowControlsSynced(client_session, server_session);
-
-  // Check control streams.
-  if (version_.UsesHttp3()) {
-    ExpectFlowControlsSynced(
-        QuicSpdySessionPeer::GetReceiveControlStream(client_session),
-        QuicSpdySessionPeer::GetSendControlStream(server_session));
-    ExpectFlowControlsSynced(
-        QuicSpdySessionPeer::GetSendControlStream(client_session),
-        QuicSpdySessionPeer::GetReceiveControlStream(server_session));
-  }
-
-  // Check crypto stream.
-  if (!version_.UsesCryptoFrames()) {
-    ExpectFlowControlsSynced(
-        QuicSessionPeer::GetMutableCryptoStream(client_session),
-        QuicSessionPeer::GetMutableCryptoStream(server_session));
-  }
-
-  // Check headers stream.
-  if (!version_.UsesHttp3()) {
-    SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
-    SpdySettingsIR settings_frame;
-    settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
-                              kDefaultMaxUncompressedHeaderSize);
-    SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
-
-    QuicHeadersStream* client_header_stream =
-        QuicSpdySessionPeer::GetHeadersStream(client_session);
-    QuicHeadersStream* server_header_stream =
-        QuicSpdySessionPeer::GetHeadersStream(server_session);
-    // Both client and server are sending this SETTINGS frame, and the send
-    // window is consumed. But because of timing issue, the server may send or
-    // not send the frame, and the client may send/ not send / receive / not
-    // receive the frame.
-    // TODO(fayang): Rewrite this part because it is hacky.
-    QuicByteCount win_difference1 =
-        QuicStreamPeer::ReceiveWindowSize(server_header_stream) -
-        QuicStreamPeer::SendWindowSize(client_header_stream);
-    if (win_difference1 != 0) {
-      EXPECT_EQ(frame.size(), win_difference1);
-    }
-
-    QuicByteCount win_difference2 =
-        QuicStreamPeer::ReceiveWindowSize(client_header_stream) -
-        QuicStreamPeer::SendWindowSize(server_header_stream);
-    if (win_difference2 != 0) {
-      EXPECT_EQ(frame.size(), win_difference2);
-    }
-
-    // Client *may* have received the SETTINGs frame.
-    // TODO(fayang): Rewrite this part because it is hacky.
-    float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
-                       client_session->flow_controller())) /
-                   QuicStreamPeer::ReceiveWindowSize(
-                       QuicSpdySessionPeer::GetHeadersStream(client_session));
-    float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
-                       client_session->flow_controller())) /
-                   (QuicStreamPeer::ReceiveWindowSize(
-                        QuicSpdySessionPeer::GetHeadersStream(client_session)) +
-                    frame.size());
-    EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
-                ratio2 == kSessionToStreamRatio);
-  }
-
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
-  // A stream created on receipt of a simple request with no body will never get
-  // a stream frame with a FIN. Verify that we don't keep track of the stream in
-  // the locally closed streams map: it will never be removed if so.
-  ASSERT_TRUE(Initialize());
-
-  // Send a simple headers only request, and receive response.
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Now verify that the server is not waiting for a final FIN or RST.
-  server_thread_->Pause();
-  QuicSession* server_session = GetServerSession();
-  if (server_session != nullptr) {
-    EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(
-                      server_session)
-                      .size());
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  server_thread_->Resume();
-}
-
-// TestAckListener counts how many bytes are acked during its lifetime.
-class TestAckListener : public QuicAckListenerInterface {
- public:
-  TestAckListener() {}
-
-  void OnPacketAcked(int acked_bytes,
-                     QuicTime::Delta /*delta_largest_observed*/) override {
-    total_bytes_acked_ += acked_bytes;
-  }
-
-  void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
-
-  int total_bytes_acked() const { return total_bytes_acked_; }
-
- protected:
-  // Object is ref counted.
-  ~TestAckListener() override {}
-
- private:
-  int total_bytes_acked_ = 0;
-};
-
-class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
- public:
-  void OnCompleteResponse(QuicStreamId id,
-                          const SpdyHeaderBlock& response_headers,
-                          const std::string& response_body) override {
-    QUIC_DVLOG(1) << "response for stream " << id << " "
-                  << response_headers.DebugString() << "\n"
-                  << response_body;
-  }
-};
-
-TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
-  // Verify that even in the presence of packet loss and occasionally blocked
-  // socket, an AckNotifierDelegate will get informed that the data it is
-  // interested in has been ACKed. This tests end-to-end ACK notification, and
-  // demonstrates that retransmissions do not break this functionality.
-  // Disable blackhole detection as this test is testing loss recovery.
-  client_extra_copts_.push_back(kNBHD);
-  SetPacketLossPercentage(5);
-  ASSERT_TRUE(Initialize());
-  // Wait for the server SHLO before upping the packet loss.
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  SetPacketLossPercentage(30);
-  client_writer_->set_fake_blocked_socket_percentage(10);
-
-  // Wait for SETTINGS frame from server that sets QPACK dynamic table capacity
-  // to make sure request headers will be compressed using the dynamic table.
-  if (version_.UsesHttp3()) {
-    while (true) {
-      // Waits for up to 50 ms.
-      client_->client()->WaitForEvents();
-      ASSERT_TRUE(client_->connected());
-      QuicSpdyClientSession* client_session = GetClientSession();
-      if (client_session == nullptr) {
-        ADD_FAILURE() << "Missing client session";
-        return;
-      }
-      QpackEncoder* qpack_encoder = client_session->qpack_encoder();
-      if (qpack_encoder == nullptr) {
-        ADD_FAILURE() << "Missing QPACK encoder";
-        return;
-      }
-      QpackEncoderHeaderTable* header_table =
-          QpackEncoderPeer::header_table(qpack_encoder);
-      if (header_table == nullptr) {
-        ADD_FAILURE() << "Missing header table";
-        return;
-      }
-      if (header_table->dynamic_table_capacity() > 0) {
-        break;
-      }
-    }
-  }
-
-  // Create a POST request and send the headers only.
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-
-  // Size of headers on the request stream. This is zero if headers are sent on
-  // the header stream.
-  size_t header_size = 0;
-  if (version_.UsesHttp3()) {
-    // Determine size of headers after QPACK compression.
-    NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
-    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
-    QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
-    qpack_encoder.set_qpack_stream_sender_delegate(
-        &encoder_stream_sender_delegate);
-
-    qpack_encoder.SetMaximumDynamicTableCapacity(
-        kDefaultQpackMaxDynamicTableCapacity);
-    qpack_encoder.SetDynamicTableCapacity(kDefaultQpackMaxDynamicTableCapacity);
-    qpack_encoder.SetMaximumBlockedStreams(kDefaultMaximumBlockedStreams);
-
-    std::string encoded_headers = qpack_encoder.EncodeHeaderList(
-        /* stream_id = */ 0, headers, nullptr);
-    header_size = encoded_headers.size();
-  }
-
-  // Test the AckNotifier's ability to track multiple packets by making the
-  // request body exceed the size of a single packet.
-  std::string request_string = "a request body bigger than one packet" +
-                               std::string(kMaxOutgoingPacketSize, '.');
-
-  const int expected_bytes_acked = header_size + request_string.length();
-
-  // The TestAckListener will cause a failure if not notified.
-  quiche::QuicheReferenceCountedPointer<TestAckListener> ack_listener(
-      new TestAckListener());
-
-  // Send the request, and register the delegate for ACKs.
-  client_->SendData(request_string, true, ack_listener);
-  WaitForFooResponseAndCheckIt();
-
-  // Send another request to flush out any pending ACKs on the server.
-  SendSynchronousBarRequestAndCheckResponse();
-
-  // Make sure the delegate does get the notification it expects.
-  while (ack_listener->total_bytes_acked() < expected_bytes_acked) {
-    // Waits for up to 50 ms.
-    client_->client()->WaitForEvents();
-    ASSERT_TRUE(client_->connected());
-  }
-  EXPECT_EQ(ack_listener->total_bytes_acked(), expected_bytes_acked)
-      << " header_size " << header_size << " request length "
-      << request_string.length();
-}
-
-// Send a public reset from the server.
-TEST_P(EndToEndTest, ServerSendPublicReset) {
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  QuicSpdySession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicConfig* config = client_session->config();
-  ASSERT_TRUE(config);
-  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
-  StatelessResetToken stateless_reset_token =
-      config->ReceivedStatelessResetToken();
-
-  // Send the public reset.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionId connection_id = client_connection->connection_id();
-  QuicPublicResetPacket header;
-  header.connection_id = connection_id;
-  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
-                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
-  std::unique_ptr<QuicEncryptedPacket> packet;
-  if (version_.HasIetfInvariantHeader()) {
-    packet = framer.BuildIetfStatelessResetPacket(
-        connection_id, /*received_packet_length=*/100, stateless_reset_token);
-  } else {
-    packet = framer.BuildPublicResetPacket(header);
-  }
-  // We must pause the server's thread in order to call WritePacket without
-  // race conditions.
-  server_thread_->Pause();
-  auto client_address = client_connection->self_address();
-  server_writer_->WritePacket(packet->data(), packet->length(),
-                              server_address_.host(), client_address, nullptr);
-  server_thread_->Resume();
-
-  // The request should fail.
-  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
-  EXPECT_TRUE(client_->response_headers()->empty());
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
-}
-
-// Send a public reset from the server for a different connection ID.
-// It should be ignored.
-TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  QuicSpdySession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicConfig* config = client_session->config();
-  ASSERT_TRUE(config);
-  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
-  StatelessResetToken stateless_reset_token =
-      config->ReceivedStatelessResetToken();
-  // Send the public reset.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionId incorrect_connection_id = TestConnectionId(
-      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
-  QuicPublicResetPacket header;
-  header.connection_id = incorrect_connection_id;
-  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
-                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
-  std::unique_ptr<QuicEncryptedPacket> packet;
-  NiceMock<MockQuicConnectionDebugVisitor> visitor;
-  client_connection->set_debug_visitor(&visitor);
-  if (version_.HasIetfInvariantHeader()) {
-    packet = framer.BuildIetfStatelessResetPacket(
-        incorrect_connection_id, /*received_packet_length=*/100,
-        stateless_reset_token);
-    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
-        .Times(0);
-  } else {
-    packet = framer.BuildPublicResetPacket(header);
-    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
-        .Times(1);
-  }
-  // We must pause the server's thread in order to call WritePacket without
-  // race conditions.
-  server_thread_->Pause();
-  auto client_address = client_connection->self_address();
-  server_writer_->WritePacket(packet->data(), packet->length(),
-                              server_address_.host(), client_address, nullptr);
-  server_thread_->Resume();
-
-  if (version_.HasIetfInvariantHeader()) {
-    // The request should fail. IETF stateless reset does not include connection
-    // ID.
-    EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
-    EXPECT_TRUE(client_->response_headers()->empty());
-    EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
-  } else {
-    // The connection should be unaffected.
-    SendSynchronousFooRequestAndCheckResponse();
-  }
-
-  client_connection->set_debug_visitor(nullptr);
-}
-
-// Send a public reset from the client for a different connection ID.
-// It should be ignored.
-TEST_P(EndToEndTest, ClientSendPublicResetWithDifferentConnectionId) {
-  ASSERT_TRUE(Initialize());
-
-  // Send the public reset.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionId incorrect_connection_id = TestConnectionId(
-      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
-  QuicPublicResetPacket header;
-  header.connection_id = incorrect_connection_id;
-  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
-                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      framer.BuildPublicResetPacket(header));
-  client_writer_->WritePacket(
-      packet->data(), packet->length(),
-      client_->client()->network_helper()->GetLatestClientAddress().host(),
-      server_address_, nullptr);
-
-  // The connection should be unaffected.
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-// Send a version negotiation packet from the server for a different
-// connection ID.  It should be ignored.
-TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // Send the version negotiation packet.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionId incorrect_connection_id = TestConnectionId(
-      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildVersionNegotiationPacket(
-          incorrect_connection_id, EmptyQuicConnectionId(),
-          version_.HasIetfInvariantHeader(),
-          version_.HasLengthPrefixedConnectionIds(),
-          server_supported_versions_));
-  NiceMock<MockQuicConnectionDebugVisitor> visitor;
-  client_connection->set_debug_visitor(&visitor);
-  EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
-      .Times(1);
-  // We must pause the server's thread in order to call WritePacket without
-  // race conditions.
-  server_thread_->Pause();
-  server_writer_->WritePacket(
-      packet->data(), packet->length(), server_address_.host(),
-      client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
-  server_thread_->Resume();
-
-  // The connection should be unaffected.
-  SendSynchronousFooRequestAndCheckResponse();
-
-  client_connection->set_debug_visitor(nullptr);
-}
-
-// DowngradePacketWriter is a client writer which will intercept all the client
-// writes for |target_version| and reply to them with version negotiation
-// packets to attempt a version downgrade attack. Once the client has downgraded
-// to a different version, the writer stops intercepting. |server_thread| must
-// start off paused, and will be resumed once interception is done.
-class DowngradePacketWriter : public PacketDroppingTestWriter {
- public:
-  explicit DowngradePacketWriter(
-      const ParsedQuicVersion& target_version,
-      const ParsedQuicVersionVector& supported_versions, QuicTestClient* client,
-      QuicPacketWriter* server_writer, ServerThread* server_thread)
-      : target_version_(target_version),
-        supported_versions_(supported_versions),
-        client_(client),
-        server_writer_(server_writer),
-        server_thread_(server_thread) {}
-  ~DowngradePacketWriter() override {}
-
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          quic::PerPacketOptions* options) override {
-    if (!intercept_enabled_) {
-      return PacketDroppingTestWriter::WritePacket(
-          buffer, buf_len, self_address, peer_address, options);
-    }
-    PacketHeaderFormat format;
-    QuicLongHeaderType long_packet_type;
-    bool version_present, has_length_prefix;
-    QuicVersionLabel version_label;
-    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-    QuicConnectionId destination_connection_id, source_connection_id;
-    absl::optional<absl::string_view> retry_token;
-    std::string detailed_error;
-    if (QuicFramer::ParsePublicHeaderDispatcher(
-            QuicEncryptedPacket(buffer, buf_len),
-            kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-            &version_present, &has_length_prefix, &version_label,
-            &parsed_version, &destination_connection_id, &source_connection_id,
-            &retry_token, &detailed_error) != QUIC_NO_ERROR) {
-      ADD_FAILURE() << "Failed to parse our own packet: " << detailed_error;
-      return WriteResult(WRITE_STATUS_ERROR, 0);
-    }
-    if (!version_present || parsed_version != target_version_) {
-      // Client is sending with another version, the attack has succeeded so we
-      // can stop intercepting.
-      intercept_enabled_ = false;
-      server_thread_->Resume();
-      // Pass the client-sent packet through.
-      return WritePacket(buffer, buf_len, self_address, peer_address, options);
-    }
-    // Send a version negotiation packet.
-    std::unique_ptr<QuicEncryptedPacket> packet(
-        QuicFramer::BuildVersionNegotiationPacket(
-            destination_connection_id, source_connection_id,
-            parsed_version.HasIetfInvariantHeader(), has_length_prefix,
-            supported_versions_));
-    server_writer_->WritePacket(
-        packet->data(), packet->length(), peer_address.host(),
-        client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
-    // Drop the client-sent packet but pretend it was sent.
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
- private:
-  bool intercept_enabled_ = true;
-  ParsedQuicVersion target_version_;
-  ParsedQuicVersionVector supported_versions_;
-  QuicTestClient* client_;           // Unowned.
-  QuicPacketWriter* server_writer_;  // Unowned.
-  ServerThread* server_thread_;      // Unowned.
-};
-
-TEST_P(EndToEndTest, VersionNegotiationDowngradeAttackIsDetected) {
-  ParsedQuicVersion target_version = server_supported_versions_.back();
-  if (!version_.UsesTls() || target_version == version_) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  connect_to_server_on_initialize_ = false;
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    target_version);
-  ParsedQuicVersionVector downgrade_versions{version_};
-  ASSERT_TRUE(Initialize());
-  ASSERT_TRUE(server_thread_);
-  // Pause the server thread to allow our DowngradePacketWriter to write version
-  // negotiation packets in a thread-safe manner. It will be resumed by the
-  // DowngradePacketWriter.
-  server_thread_->Pause();
-  client_.reset(new QuicTestClient(server_address_, server_hostname_,
-                                   client_config_, client_supported_versions_,
-                                   crypto_test_utils::ProofVerifierForTesting(),
-                                   std::make_unique<QuicClientSessionCache>()));
-  delete client_writer_;
-  client_writer_ = new DowngradePacketWriter(target_version, downgrade_versions,
-                                             client_.get(), server_writer_,
-                                             server_thread_.get());
-  client_->UseWriter(client_writer_);
-  // Have the client attempt to send a request.
-  client_->Connect();
-  EXPECT_TRUE(client_->SendSynchronousRequest("/foo").empty());
-  // Make sure the downgrade is detected and the handshake fails.
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
-}
-
-// A bad header shouldn't tear down the connection, because the receiver can't
-// tell the connection ID.
-TEST_P(EndToEndTest, BadPacketHeaderTruncated) {
-  ASSERT_TRUE(Initialize());
-
-  // Start the connection.
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Packet with invalid public flags.
-  char packet[] = {// public flags (8 byte connection_id)
-                   0x3C,
-                   // truncated connection ID
-                   0x11};
-  client_writer_->WritePacket(
-      &packet[0], sizeof(packet),
-      client_->client()->network_helper()->GetLatestClientAddress().host(),
-      server_address_, nullptr);
-  EXPECT_TRUE(server_thread_->WaitUntil(
-      [&] {
-        return QuicDispatcherPeer::GetAndClearLastError(
-                   QuicServerPeer::GetDispatcher(server_thread_->server())) ==
-               QUIC_INVALID_PACKET_HEADER;
-      },
-      QuicTime::Delta::FromSeconds(5)));
-
-  // The connection should not be terminated.
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-// A bad header shouldn't tear down the connection, because the receiver can't
-// tell the connection ID.
-TEST_P(EndToEndTest, BadPacketHeaderFlags) {
-  ASSERT_TRUE(Initialize());
-
-  // Start the connection.
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Packet with invalid public flags.
-  uint8_t packet[] = {
-      // invalid public flags
-      0xFF,
-      // connection_id
-      0x10,
-      0x32,
-      0x54,
-      0x76,
-      0x98,
-      0xBA,
-      0xDC,
-      0xFE,
-      // packet sequence number
-      0xBC,
-      0x9A,
-      0x78,
-      0x56,
-      0x34,
-      0x12,
-      // private flags
-      0x00,
-  };
-  client_writer_->WritePacket(
-      reinterpret_cast<const char*>(packet), sizeof(packet),
-      client_->client()->network_helper()->GetLatestClientAddress().host(),
-      server_address_, nullptr);
-
-  EXPECT_TRUE(server_thread_->WaitUntil(
-      [&] {
-        return QuicDispatcherPeer::GetAndClearLastError(
-                   QuicServerPeer::GetDispatcher(server_thread_->server())) ==
-               QUIC_INVALID_PACKET_HEADER;
-      },
-      QuicTime::Delta::FromSeconds(5)));
-
-  // The connection should not be terminated.
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-// Send a packet from the client with bad encrypted data.  The server should not
-// tear down the connection.
-TEST_P(EndToEndTest, BadEncryptedData) {
-  ASSERT_TRUE(Initialize());
-
-  // Start the connection.
-  SendSynchronousFooRequestAndCheckResponse();
-
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      client_connection->connection_id(), EmptyQuicConnectionId(), false, false,
-      1, "At least 20 characters.", CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
-      PACKET_4BYTE_PACKET_NUMBER));
-  // Damage the encrypted data.
-  std::string damaged_packet(packet->data(), packet->length());
-  damaged_packet[30] ^= 0x01;
-  QUIC_DLOG(INFO) << "Sending bad packet.";
-  client_writer_->WritePacket(
-      damaged_packet.data(), damaged_packet.length(),
-      client_->client()->network_helper()->GetLatestClientAddress().host(),
-      server_address_, nullptr);
-  // Give the server time to process the packet.
-  absl::SleepFor(absl::Seconds(1));
-  // This error is sent to the connection's OnError (which ignores it), so the
-  // dispatcher doesn't see it.
-  // Pause the server so we can access the server's internals without races.
-  server_thread_->Pause();
-  QuicDispatcher* dispatcher =
-      QuicServerPeer::GetDispatcher(server_thread_->server());
-  if (dispatcher != nullptr) {
-    EXPECT_THAT(QuicDispatcherPeer::GetAndClearLastError(dispatcher),
-                IsQuicNoError());
-  } else {
-    ADD_FAILURE() << "Missing dispatcher";
-  }
-  server_thread_->Resume();
-
-  // The connection should not be terminated.
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  // Lose the request.
-  SetPacketLossPercentage(100);
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  client_->SendMessage(headers, "test_body", /*fin=*/false);
-  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-
-  // Cancel the stream.
-  stream->Reset(QUIC_STREAM_CANCELLED);
-  QuicSession* session = GetClientSession();
-  ASSERT_TRUE(session);
-  // Verify canceled stream does not become zombie.
-  EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
-}
-
-// A test stream that gives |response_body_| as an error response body.
-class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
- public:
-  ServerStreamWithErrorResponseBody(
-      QuicStreamId id, QuicSpdySession* session,
-      QuicSimpleServerBackend* quic_simple_server_backend,
-      std::string response_body)
-      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
-                               quic_simple_server_backend),
-        response_body_(std::move(response_body)) {}
-
-  ~ServerStreamWithErrorResponseBody() override = default;
-
- protected:
-  void SendErrorResponse() override {
-    QUIC_DLOG(INFO) << "Sending error response for stream " << id();
-    SpdyHeaderBlock headers;
-    headers[":status"] = "500";
-    headers["content-length"] = absl::StrCat(response_body_.size());
-    // This method must call CloseReadSide to cause the test case, StopReading
-    // is not sufficient.
-    QuicStreamPeer::CloseReadSide(this);
-    SendHeadersAndBody(std::move(headers), response_body_);
-  }
-
-  std::string response_body_;
-};
-
-class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
- public:
-  explicit StreamWithErrorFactory(std::string response_body)
-      : response_body_(std::move(response_body)) {}
-
-  ~StreamWithErrorFactory() override = default;
-
-  QuicSimpleServerStream* CreateStream(
-      QuicStreamId id, QuicSpdySession* session,
-      QuicSimpleServerBackend* quic_simple_server_backend) override {
-    return new ServerStreamWithErrorResponseBody(
-        id, session, quic_simple_server_backend, response_body_);
-  }
-
-  QuicSimpleServerStream* CreateStream(
-      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
-      QuicSimpleServerBackend* /*response_cache*/) override {
-    return nullptr;
-  }
-
- private:
-  std::string response_body_;
-};
-
-// A test server stream that drops all received body.
-class ServerStreamThatDropsBody : public QuicSimpleServerStream {
- public:
-  ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
-                            QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
-                               quic_simple_server_backend) {}
-
-  ~ServerStreamThatDropsBody() override = default;
-
- protected:
-  void OnBodyAvailable() override {
-    while (HasBytesToRead()) {
-      struct iovec iov;
-      if (GetReadableRegions(&iov, 1) == 0) {
-        // No more data to read.
-        break;
-      }
-      QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
-                    << id();
-      MarkConsumed(iov.iov_len);
-    }
-
-    if (!sequencer()->IsClosed()) {
-      sequencer()->SetUnblocked();
-      return;
-    }
-
-    // If the sequencer is closed, then all the body, including the fin, has
-    // been consumed.
-    OnFinRead();
-
-    if (write_side_closed() || fin_buffered()) {
-      return;
-    }
-
-    SendResponse();
-  }
-};
-
-class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
- public:
-  ServerStreamThatDropsBodyFactory() = default;
-
-  ~ServerStreamThatDropsBodyFactory() override = default;
-
-  QuicSimpleServerStream* CreateStream(
-      QuicStreamId id, QuicSpdySession* session,
-      QuicSimpleServerBackend* quic_simple_server_backend) override {
-    return new ServerStreamThatDropsBody(id, session,
-                                         quic_simple_server_backend);
-  }
-
-  QuicSimpleServerStream* CreateStream(
-      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
-      QuicSimpleServerBackend* /*response_cache*/) override {
-    return nullptr;
-  }
-};
-
-// A test server stream that sends response with body size greater than 4GB.
-class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
- public:
-  ServerStreamThatSendsHugeResponse(
-      QuicStreamId id, QuicSpdySession* session,
-      QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
-      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
-                               quic_simple_server_backend),
-        body_bytes_(body_bytes) {}
-
-  ~ServerStreamThatSendsHugeResponse() override = default;
-
- protected:
-  void SendResponse() override {
-    QuicBackendResponse response;
-    std::string body(body_bytes_, 'a');
-    response.set_body(body);
-    SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
-                                  response.trailers().Clone());
-  }
-
- private:
-  // Use a explicit int64_t rather than size_t to simulate a 64-bit server
-  // talking to a 32-bit client.
-  int64_t body_bytes_;
-};
-
-class ServerStreamThatSendsHugeResponseFactory
-    : public QuicTestServer::StreamFactory {
- public:
-  explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
-      : body_bytes_(body_bytes) {}
-
-  ~ServerStreamThatSendsHugeResponseFactory() override = default;
-
-  QuicSimpleServerStream* CreateStream(
-      QuicStreamId id, QuicSpdySession* session,
-      QuicSimpleServerBackend* quic_simple_server_backend) override {
-    return new ServerStreamThatSendsHugeResponse(
-        id, session, quic_simple_server_backend, body_bytes_);
-  }
-
-  QuicSimpleServerStream* CreateStream(
-      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
-      QuicSimpleServerBackend* /*response_cache*/) override {
-    return nullptr;
-  }
-
-  int64_t body_bytes_;
-};
-
-TEST_P(EndToEndTest, EarlyResponseFinRecording) {
-  set_smaller_flow_control_receive_window();
-
-  // Verify that an incoming FIN is recorded in a stream object even if the read
-  // side has been closed.  This prevents an entry from being made in
-  // locally_close_streams_highest_offset_ (which will never be deleted).
-  // To set up the test condition, the server must do the following in order:
-  // start sending the response and call CloseReadSide
-  // receive the FIN of the request
-  // send the FIN of the response
-
-  // The response body must be larger than the flow control window so the server
-  // must receive a window update from the client before it can finish sending
-  // it.
-  uint32_t response_body_size =
-      2 * client_config_.GetInitialStreamFlowControlWindowToSend();
-  std::string response_body(response_body_size, 'a');
-
-  StreamWithErrorFactory stream_factory(response_body);
-  SetSpdyStreamFactory(&stream_factory);
-
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // A POST that gets an early error response, after the headers are received
-  // and before the body is received, due to invalid content-length.
-  // Set an invalid content-length, so the request will receive an early 500
-  // response.
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/garbage";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = "-1";
-
-  // The body must be large enough that the FIN will be in a different packet
-  // than the end of the headers, but short enough to not require a flow control
-  // update.  This allows headers processing to trigger the error response
-  // before the request FIN is processed but receive the request FIN before the
-  // response is sent completely.
-  const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
-  std::string request_body(kRequestBodySize, 'a');
-
-  // Send the request.
-  client_->SendMessage(headers, request_body);
-  client_->WaitForResponse();
-  CheckResponseHeaders("500");
-
-  // Pause the server so we can access the server's internals without races.
-  server_thread_->Pause();
-
-  QuicDispatcher* dispatcher =
-      QuicServerPeer::GetDispatcher(server_thread_->server());
-  QuicSession* server_session =
-      QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
-  EXPECT_TRUE(server_session != nullptr);
-
-  // The stream is not waiting for the arrival of the peer's final offset.
-  EXPECT_EQ(
-      0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
-              .size());
-
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, Trailers) {
-  // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  // Set reordering to ensure that Trailers arriving before body is ok.
-  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
-  SetReorderPercentage(30);
-
-  // Add a response with headers, body, and trailers.
-  const std::string kBody = "body content";
-
-  SpdyHeaderBlock headers;
-  headers[":status"] = "200";
-  headers["content-length"] = absl::StrCat(kBody.size());
-
-  SpdyHeaderBlock trailers;
-  trailers["some-trailing-header"] = "trailing-header-value";
-
-  memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
-                                    std::move(headers), kBody,
-                                    trailers.Clone());
-
-  SendSynchronousRequestAndCheckResponse("/trailer_url", kBody);
-  EXPECT_EQ(trailers, client_->response_trailers());
-}
-
-// TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
-  // This test tests a huge post with introduced packet loss from client to
-  // server and body size greater than 4GB, making sure QUIC code does not break
-  // for 32-bit builds.
-  ServerStreamThatDropsBodyFactory stream_factory;
-  SetSpdyStreamFactory(&stream_factory);
-  ASSERT_TRUE(Initialize());
-  // Set client's epoll server's time out to 0 to make this test be finished
-  // within a short time.
-  client_->epoll_server()->set_timeout_in_us(0);
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  SetPacketLossPercentage(1);
-  // To avoid storing the whole request body in memory, use a loop to repeatedly
-  // send body size of kSizeBytes until the whole request body size is reached.
-  const int kSizeBytes = 128 * 1024;
-  // Request body size is 4G plus one more kSizeBytes.
-  int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
-  ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
-  std::string body(kSizeBytes, 'a');
-
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["content-length"] = absl::StrCat(request_body_size_bytes);
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-
-  for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
-    bool fin = (i == request_body_size_bytes - 1);
-    client_->SendData(std::string(body.data(), kSizeBytes), fin);
-    client_->client()->WaitForEvents();
-  }
-  VerifyCleanConnection(true);
-}
-
-// TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
-  // This test tests a huge response with introduced loss from server to client
-  // and body size greater than 4GB, making sure QUIC code does not break for
-  // 32-bit builds.
-  const int kSizeBytes = 128 * 1024;
-  int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
-  ASSERT_LT(4294967296, response_body_size_bytes);
-  ServerStreamThatSendsHugeResponseFactory stream_factory(
-      response_body_size_bytes);
-  SetSpdyStreamFactory(&stream_factory);
-
-  StartServer();
-
-  // Use a quic client that drops received body.
-  QuicTestClient* client =
-      new QuicTestClient(server_address_, server_hostname_, client_config_,
-                         client_supported_versions_);
-  client->client()->set_drop_response_body(true);
-  client->UseWriter(client_writer_);
-  client->Connect();
-  client_.reset(client);
-  static QuicEpollEvent event(EPOLLOUT);
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  client_writer_->Initialize(
-      QuicConnectionPeer::GetHelper(client_connection),
-      QuicConnectionPeer::GetAlarmFactory(client_connection),
-      std::make_unique<ClientDelegate>(client_->client()));
-  initialized_ = true;
-  ASSERT_TRUE(client_->client()->connected());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  SetPacketLossPercentage(1);
-  client_->SendRequest("/huge_response");
-  client_->WaitForResponse();
-  VerifyCleanConnection(true);
-}
-
-// Regression test for b/111515567
-TEST_P(EndToEndTest, AgreeOnStopWaiting) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    // Verify client and server connections agree on the value of
-    // no_stop_waiting_frames.
-    EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
-              QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-// Regression test for b/111515567
-TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
-  QuicTagVector options;
-  options.push_back(kNSTP);
-  client_config_.SetConnectionOptionsToSend(options);
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    // Verify client and server connections agree on the value of
-    // no_stop_waiting_frames.
-    EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
-              QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
-  // Tests that when client side has no active request and no waiting
-  // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
-  ASSERT_TRUE(Initialize());
-  client_->SendSynchronousRequest("/foo");
-  if (version_.UsesHttp3()) {
-    return;
-  }
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicHeadersStream* headers_stream =
-      QuicSpdySessionPeer::GetHeadersStream(client_session);
-  ASSERT_TRUE(headers_stream);
-  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
-  ASSERT_TRUE(sequencer);
-  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-// A single large header value causes a different error than the total size of
-// headers exceeding a smaller limit, tested at EndToEndTest.LargeHeaders.
-TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
-  ASSERT_TRUE(Initialize());
-
-  SpdyHeaderBlock headers;
-  headers[":method"] = "GET";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  headers["key"] = std::string(2 * 1024 * 1024, 'a');
-
-  client_->SendMessage(headers, "");
-  client_->WaitForResponse();
-  if (version_.UsesHttp3()) {
-    EXPECT_THAT(client_->connection_error(),
-                IsError(QUIC_QPACK_DECOMPRESSION_FAILED));
-  } else {
-    EXPECT_THAT(client_->connection_error(),
-                IsError(QUIC_HPACK_VALUE_TOO_LONG));
-  }
-}
-
-class WindowUpdateObserver : public QuicConnectionDebugVisitor {
- public:
-  WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
-
-  size_t num_window_update_frames() const { return num_window_update_frames_; }
-
-  size_t num_ping_frames() const { return num_ping_frames_; }
-
-  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
-                           const QuicTime& /*receive_time*/) override {
-    ++num_window_update_frames_;
-  }
-
-  void OnPingFrame(const QuicPingFrame& /*frame*/,
-                   const QuicTime::Delta /*ping_received_delay*/) override {
-    ++num_ping_frames_;
-  }
-
- private:
-  size_t num_window_update_frames_;
-  size_t num_ping_frames_;
-};
-
-TEST_P(EndToEndTest, WindowUpdateInAck) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  WindowUpdateObserver observer;
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  client_connection->set_debug_visitor(&observer);
-  // 100KB body.
-  std::string body(100 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  EXPECT_EQ(kFooResponseBody,
-            client_->SendCustomSynchronousRequest(headers, body));
-  client_->Disconnect();
-  EXPECT_LT(0u, observer.num_window_update_frames());
-  EXPECT_EQ(0u, observer.num_ping_frames());
-  client_connection->set_debug_visitor(nullptr);
-}
-
-TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicConfig* config = client_session->config();
-  ASSERT_TRUE(config);
-  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
-  QuicConnection* client_connection = client_session->connection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
-                client_connection->connection_id()),
-            config->ReceivedStatelessResetToken());
-  client_->Disconnect();
-}
-
-// Regression test for b/116200989.
-TEST_P(EndToEndTest,
-       SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
-  connect_to_server_on_initialize_ = false;
-  ASSERT_TRUE(Initialize());
-
-  ASSERT_TRUE(server_thread_);
-  server_thread_->Pause();
-  QuicDispatcher* dispatcher =
-      QuicServerPeer::GetDispatcher(server_thread_->server());
-  if (dispatcher == nullptr) {
-    ADD_FAILURE() << "Missing dispatcher";
-    server_thread_->Resume();
-    return;
-  }
-  if (dispatcher->NumSessions() > 0) {
-    ADD_FAILURE() << "Dispatcher session map not empty";
-    server_thread_->Resume();
-    return;
-  }
-  // Note: this writer will only used by the server connection, not the time
-  // wait list.
-  QuicDispatcherPeer::UseWriter(
-      dispatcher,
-      // This cause the first server-sent packet, a.k.a REJ, to fail.
-      new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
-  server_thread_->Resume();
-
-  client_.reset(CreateQuicClient(client_writer_));
-  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
-}
-
-// Regression test for b/116200989.
-TEST_P(EndToEndTest,
-       SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
-  // Prevent the connection from expiring in the time wait list.
-  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
-  connect_to_server_on_initialize_ = false;
-  ASSERT_TRUE(Initialize());
-
-  // big_response_body is 64K, which is about 48 full-sized packets.
-  const size_t kBigResponseBodySize = 65536;
-  QuicData big_response_body(new char[kBigResponseBodySize](),
-                             kBigResponseBodySize, /*owns_buffer=*/true);
-  AddToCache("/big_response", 200, big_response_body.AsStringPiece());
-
-  ASSERT_TRUE(server_thread_);
-  server_thread_->Pause();
-  QuicDispatcher* dispatcher =
-      QuicServerPeer::GetDispatcher(server_thread_->server());
-  if (dispatcher == nullptr) {
-    ADD_FAILURE() << "Missing dispatcher";
-    server_thread_->Resume();
-    return;
-  }
-  if (dispatcher->NumSessions() > 0) {
-    ADD_FAILURE() << "Dispatcher session map not empty";
-    server_thread_->Resume();
-    return;
-  }
-  QuicDispatcherPeer::UseWriter(
-      dispatcher,
-      // This will cause an server write error with EPERM, while sending the
-      // response for /big_response.
-      new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
-  server_thread_->Resume();
-
-  client_.reset(CreateQuicClient(client_writer_));
-
-  // First, a /foo request with small response should succeed.
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Second, a /big_response request with big response should fail.
-  EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
-            kBigResponseBodySize);
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
-}
-
-// Regression test of b/70782529.
-TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
-  ASSERT_TRUE(Initialize());
-  BadPacketWriter* bad_writer =
-      new BadPacketWriter(/*packet_causing_write_error=*/5,
-                          /*error_code=*/90);
-  std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
-
-  // 1 MB body.
-  std::string body(1024 * 1024, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  client->SendCustomSynchronousRequest(headers, body);
-}
-
-// Regression test for b/71711996. This test sends a connectivity probing packet
-// as its last sent packet, and makes sure the server's ACK of that packet does
-// not cause the client to fail.
-TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Wait for the client's ACK (of the response) to be received by the server.
-  client_->WaitForDelayedAcks();
-
-  // We are sending a connectivity probing packet from an unchanged client
-  // address, so the server will not respond to us with a connectivity probing
-  // packet, however the server should send an ack-only packet to us.
-  client_->SendConnectivityProbing();
-
-  // Wait for the server's last ACK to be received by the client.
-  client_->WaitForDelayedAcks();
-}
-
-TEST_P(EndToEndTest, PreSharedKey) {
-  client_config_.set_max_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(5));
-  client_config_.set_max_idle_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(5));
-  pre_shared_key_client_ = "foobar";
-  pre_shared_key_server_ = "foobar";
-
-  if (version_.UsesTls()) {
-    // TODO(b/154162689) add PSK support to QUIC+TLS.
-    bool ok = true;
-    EXPECT_QUIC_BUG(ok = Initialize(),
-                    "QUIC client pre-shared keys not yet supported with TLS");
-    EXPECT_FALSE(ok);
-    return;
-  }
-
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-// TODO: reenable once we have a way to make this run faster.
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
-  client_config_.set_max_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(1));
-  client_config_.set_max_idle_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(1));
-  pre_shared_key_client_ = "foo";
-  pre_shared_key_server_ = "bar";
-
-  if (version_.UsesTls()) {
-    // TODO(b/154162689) add PSK support to QUIC+TLS.
-    bool ok = true;
-    EXPECT_QUIC_BUG(ok = Initialize(),
-                    "QUIC client pre-shared keys not yet supported with TLS");
-    EXPECT_FALSE(ok);
-    return;
-  }
-
-  // One of two things happens when Initialize() returns:
-  // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
-  //    returns false.
-  // 2. Crypto handshake has not completed, Initialize() returns true. The call
-  //    to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
-  //    return whether it is successful.
-  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
-}
-
-// TODO: reenable once we have a way to make this run faster.
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
-  client_config_.set_max_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(1));
-  client_config_.set_max_idle_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(1));
-  pre_shared_key_server_ = "foobar";
-
-  if (version_.UsesTls()) {
-    // TODO(b/154162689) add PSK support to QUIC+TLS.
-    bool ok = true;
-    EXPECT_QUIC_BUG(ok = Initialize(),
-                    "QUIC server pre-shared keys not yet supported with TLS");
-    EXPECT_FALSE(ok);
-    return;
-  }
-
-  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
-}
-
-// TODO: reenable once we have a way to make this run faster.
-TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
-  client_config_.set_max_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(1));
-  client_config_.set_max_idle_time_before_crypto_handshake(
-      QuicTime::Delta::FromSeconds(1));
-  pre_shared_key_client_ = "foobar";
-
-  if (version_.UsesTls()) {
-    // TODO(b/154162689) add PSK support to QUIC+TLS.
-    bool ok = true;
-    EXPECT_QUIC_BUG(ok = Initialize(),
-                    "QUIC client pre-shared keys not yet supported with TLS");
-    EXPECT_FALSE(ok);
-    return;
-  }
-
-  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
-}
-
-TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
-  // Regression test for b/80234898.
-  ASSERT_TRUE(Initialize());
-
-  // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
-  // (and the FIN) after the response body.
-  std::string response_body(1305, 'a');
-  SpdyHeaderBlock response_headers;
-  response_headers[":status"] = absl::StrCat(200);
-  response_headers["content-length"] = absl::StrCat(response_body.length());
-  memory_cache_backend_.AddSpecialResponse(
-      server_hostname_, "/test_url", std::move(response_headers), response_body,
-      QuicBackendResponse::INCOMPLETE_RESPONSE);
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  client_->WaitForDelayedAcks();
-
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  const QuicPacketCount packets_sent_before =
-      client_connection->GetStats().packets_sent;
-
-  client_->SendRequestAndRstTogether("/test_url");
-
-  // Expect exactly one packet is sent from the block above.
-  ASSERT_EQ(packets_sent_before + 1,
-            client_connection->GetStats().packets_sent);
-
-  // Wait for the connection to become idle.
-  client_->WaitForDelayedAcks();
-
-  // The real expectation is the test does not crash or timeout.
-  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
-  SetPacketLossPercentage(30);
-
-  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
-  // Set a TTL which expires immediately.
-  stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
-
-  WriteHeadersOnStream(stream);
-  // 1 MB body.
-  std::string body(1024 * 1024, 'a');
-  stream->WriteOrBufferBody(body, true);
-  client_->WaitForResponse();
-  EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_STREAM_TTL_EXPIRED));
-}
-
-TEST_P(EndToEndTest, SendMessages) {
-  if (!version_.SupportsMessageFrames()) {
-    Initialize();
-    return;
-  }
-  ASSERT_TRUE(Initialize());
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  QuicSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicConnection* client_connection = client_session->connection();
-  ASSERT_TRUE(client_connection);
-
-  SetPacketLossPercentage(30);
-  ASSERT_GT(kMaxOutgoingPacketSize,
-            client_session->GetCurrentLargestMessagePayload());
-  ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
-
-  std::string message_string(kMaxOutgoingPacketSize, 'a');
-  QuicRandom* random =
-      QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
-  {
-    QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
-    // Verify the largest message gets successfully sent.
-    EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
-              client_session->SendMessage(MemSliceFromString(absl::string_view(
-                  message_string.data(),
-                  client_session->GetCurrentLargestMessagePayload()))));
-    // Send more messages with size (0, largest_payload] until connection is
-    // write blocked.
-    const int kTestMaxNumberOfMessages = 100;
-    for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
-      size_t message_length =
-          random->RandUint64() %
-              client_session->GetGuaranteedLargestMessagePayload() +
-          1;
-      MessageResult result = client_session->SendMessage(MemSliceFromString(
-          absl::string_view(message_string.data(), message_length)));
-      if (result.status == MESSAGE_STATUS_BLOCKED) {
-        // Connection is write blocked.
-        break;
-      }
-      EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
-    }
-  }
-
-  client_->WaitForDelayedAcks();
-  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
-            client_session
-                ->SendMessage(MemSliceFromString(absl::string_view(
-                    message_string.data(),
-                    client_session->GetCurrentLargestMessagePayload() + 1)))
-                .status);
-  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
-}
-
-class EndToEndPacketReorderingTest : public EndToEndTest {
- public:
-  void CreateClientWithWriter() override {
-    QUIC_LOG(ERROR) << "create client with reorder_writer_";
-    reorder_writer_ = new PacketReorderingWriter();
-    client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
-  }
-
-  void SetUp() override {
-    // Don't initialize client writer in base class.
-    server_writer_ = new PacketDroppingTestWriter();
-  }
-
- protected:
-  PacketReorderingWriter* reorder_writer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
-                         EndToEndPacketReorderingTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
-  ASSERT_TRUE(Initialize());
-  if (version_.HasIetfQuicFrames()) {
-    return;
-  }
-
-  // Finish one request to make sure handshake established.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // Wait for the connection to become idle, to make sure the packet gets
-  // delayed is the connectivity probing packet.
-  client_->WaitForDelayedAcks();
-
-  QuicSocketAddress old_addr =
-      client_->client()->network_helper()->GetLatestClientAddress();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_addr.host(), new_host);
-  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
-
-  // Write a connectivity probing after the next /foo request.
-  reorder_writer_->SetDelay(1);
-  client_->SendConnectivityProbing();
-
-  ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
-                                                      old_addr.port()));
-
-  // The (delayed) connectivity probing will be sent after this request.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // Send yet another request after the connectivity probing, when this request
-  // returns, the probing is guaranteed to have been received by the server, and
-  // the server's response to probing is guaranteed to have been received by the
-  // client.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_EQ(1u,
-              server_connection->GetStats().num_connectivity_probing_received);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-
-  // Server definitely responded to the connectivity probing. Sometime it also
-  // sends a padded ping that is not a connectivity probing, which is recognized
-  // as connectivity probing because client's self address is ANY.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_LE(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-}
-
-// A writer which holds the next packet to be sent till ReleasePacket() is
-// called.
-class PacketHoldingWriter : public QuicPacketWriterWrapper {
- public:
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override {
-    if (!hold_next_packet_) {
-      return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
-                                                  peer_address, options);
-    }
-    QUIC_DLOG(INFO) << "Packet is held by the writer";
-    packet_content_ = std::string(buffer, buf_len);
-    self_address_ = self_address;
-    peer_address_ = peer_address;
-    options_ = (options == nullptr ? nullptr : options->Clone());
-    hold_next_packet_ = false;
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
-  void HoldNextPacket() {
-    QUICHE_DCHECK(packet_content_.empty())
-        << "There is already one packet on hold.";
-    hold_next_packet_ = true;
-  }
-
-  void ReleasePacket() {
-    QUIC_DLOG(INFO) << "Release packet";
-    ASSERT_EQ(WRITE_STATUS_OK,
-              QuicPacketWriterWrapper::WritePacket(
-                  packet_content_.data(), packet_content_.length(),
-                  self_address_, peer_address_, options_.release())
-                  .status);
-    packet_content_.clear();
-  }
-
- private:
-  bool hold_next_packet_{false};
-  std::string packet_content_;
-  QuicIpAddress self_address_;
-  QuicSocketAddress peer_address_;
-  std::unique_ptr<PerPacketOptions> options_;
-};
-
-TEST_P(EndToEndTest, ClientValidateNewNetwork) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames() ||
-      !GetClientConnection()->validate_client_address()) {
-    return;
-  }
-  client_.reset(EndToEndTest::CreateQuicClient(nullptr));
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Store the client IP address which was used to send the first request.
-  QuicIpAddress old_host =
-      client_->client()->network_helper()->GetLatestClientAddress().host();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_host, new_host);
-
-  client_->client()->ValidateNewNetwork(new_host);
-  // Send a request using the old socket.
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-  // Client should have received a PATH_CHALLENGE.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(1u,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  // Send another request to make sure THE server will receive PATH_RESPONSE.
-  client_->SendSynchronousRequest("/eep");
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_EQ(1u,
-              server_connection->GetStats().num_connectivity_probing_received);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndPacketReorderingTest, ReorderedPathChallenge) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames() ||
-      !client_->client()->session()->connection()->use_path_validator()) {
-    return;
-  }
-  client_.reset(EndToEndTest::CreateQuicClient(nullptr));
-
-  // Finish one request to make sure handshake established.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // Wait for the connection to become idle, to make sure the packet gets
-  // delayed is the connectivity probing packet.
-  client_->WaitForDelayedAcks();
-
-  QuicSocketAddress old_addr =
-      client_->client()->network_helper()->GetLatestClientAddress();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_addr.host(), new_host);
-
-  // Setup writer wrapper to hold the probing packet.
-  auto holding_writer = new PacketHoldingWriter();
-  client_->UseWriter(holding_writer);
-  // Write a connectivity probing after the next /foo request.
-  holding_writer->HoldNextPacket();
-
-  // A packet with PATH_CHALLENGE will be held in the writer.
-  client_->client()->ValidateNewNetwork(new_host);
-
-  // Send (on-hold) PATH_CHALLENGE after this request.
-  client_->SendRequest("/foo");
-  holding_writer->ReleasePacket();
-
-  client_->WaitForResponse();
-
-  EXPECT_EQ(kFooResponseBody, client_->response_body());
-  // Send yet another request after the PATH_CHALLENGE, when this request
-  // returns, the probing is guaranteed to have been received by the server, and
-  // the server's response to probing is guaranteed to have been received by the
-  // client.
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
-  // Client should have received a PATH_CHALLENGE.
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(client_connection->validate_client_address() ? 1u : 0,
-            client_connection->GetStats().num_connectivity_probing_received);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_EQ(1u,
-              server_connection->GetStats().num_connectivity_probing_received);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndPacketReorderingTest, PathValidationFailure) {
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames() ||
-      !client_->client()->session()->connection()->use_path_validator()) {
-    return;
-  }
-
-  client_.reset(CreateQuicClient(nullptr));
-  // Finish one request to make sure handshake established.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // Wait for the connection to become idle, to make sure the packet gets
-  // delayed is the connectivity probing packet.
-  client_->WaitForDelayedAcks();
-
-  QuicSocketAddress old_addr = client_->client()->session()->self_address();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress new_host = TestLoopback(2);
-  EXPECT_NE(old_addr.host(), new_host);
-
-  // Drop PATH_RESPONSE packets to timeout the path validation.
-  server_writer_->set_fake_packet_loss_percentage(100);
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(old_addr, client_->client()->session()->self_address());
-  server_writer_->set_fake_packet_loss_percentage(0);
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_EQ(3u,
-              server_connection->GetStats().num_connectivity_probing_received);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndPacketReorderingTest, MigrateAgainAfterPathValidationFailure) {
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-
-  client_.reset(CreateQuicClient(nullptr));
-  // Finish one request to make sure handshake established.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // Wait for the connection to become idle, to make sure the packet gets
-  // delayed is the connectivity probing packet.
-  client_->WaitForDelayedAcks();
-
-  QuicSocketAddress addr1 = client_->client()->session()->self_address();
-  QuicConnection* client_connection = GetClientConnection();
-  QuicConnectionId server_cid1 = client_connection->connection_id();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress host2 = TestLoopback(2);
-  EXPECT_NE(addr1.host(), host2);
-
-  // Drop PATH_RESPONSE packets to timeout the path validation.
-  server_writer_->set_fake_packet_loss_percentage(100);
-  ASSERT_TRUE(
-      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
-
-  QuicConnectionId server_cid2 =
-      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-          client_connection);
-  EXPECT_FALSE(server_cid2.IsEmpty());
-  EXPECT_NE(server_cid2, server_cid1);
-  // Wait until path validation fails at the client.
-  while (client_->client()->HasPendingPathValidation()) {
-    EXPECT_EQ(server_cid2,
-              QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection));
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(addr1, client_->client()->session()->self_address());
-  EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
-
-  server_writer_->set_fake_packet_loss_percentage(0);
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
-  WaitForNewConnectionIds();
-  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  // Server has received 3 path challenges.
-  EXPECT_EQ(3u,
-            server_connection->GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(server_cid1, server_connection->connection_id());
-  EXPECT_EQ(0u, server_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
-  server_thread_->Resume();
-
-  // Migrate socket to a new IP address again.
-  QuicIpAddress host3 = TestLoopback(3);
-  EXPECT_NE(addr1.host(), host3);
-  EXPECT_NE(host2, host3);
-
-  WaitForNewConnectionIds();
-  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
-
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
-  QuicConnectionId server_cid3 =
-      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-          client_connection);
-  EXPECT_FALSE(server_cid3.IsEmpty());
-  EXPECT_NE(server_cid1, server_cid3);
-  EXPECT_NE(server_cid2, server_cid3);
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(host3, client_->client()->session()->self_address().host());
-  EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
-  // Server should send a new connection ID to client.
-  WaitForNewConnectionIds();
-  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
-}
-
-TEST_P(EndToEndPacketReorderingTest,
-       MigrateAgainAfterPathValidationFailureWithNonZeroClientCid) {
-  if (!version_.SupportsClientConnectionIds()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  SetQuicReloadableFlag(quic_retire_cid_on_reverse_path_validation_failure,
-                        true);
-  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
-  ASSERT_TRUE(Initialize());
-  if (!GetClientConnection()->connection_migration_use_new_cid()) {
-    return;
-  }
-
-  client_.reset(CreateQuicClient(nullptr));
-  // Finish one request to make sure handshake established.
-  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
-
-  // Wait for the connection to become idle, to make sure the packet gets
-  // delayed is the connectivity probing packet.
-  client_->WaitForDelayedAcks();
-
-  QuicSocketAddress addr1 = client_->client()->session()->self_address();
-  QuicConnection* client_connection = GetClientConnection();
-  QuicConnectionId server_cid1 = client_connection->connection_id();
-  QuicConnectionId client_cid1 = client_connection->client_connection_id();
-
-  // Migrate socket to the new IP address.
-  QuicIpAddress host2 = TestLoopback(2);
-  EXPECT_NE(addr1.host(), host2);
-
-  // Drop PATH_RESPONSE packets to timeout the path validation.
-  server_writer_->set_fake_packet_loss_percentage(100);
-  ASSERT_TRUE(
-      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
-  QuicConnectionId server_cid2 =
-      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-          client_connection);
-  EXPECT_FALSE(server_cid2.IsEmpty());
-  EXPECT_NE(server_cid2, server_cid1);
-  QuicConnectionId client_cid2 =
-      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
-          client_connection);
-  EXPECT_FALSE(client_cid2.IsEmpty());
-  EXPECT_NE(client_cid2, client_cid1);
-  while (client_->client()->HasPendingPathValidation()) {
-    EXPECT_EQ(server_cid2,
-              QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection));
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(addr1, client_->client()->session()->self_address());
-  EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  server_writer_->set_fake_packet_loss_percentage(0);
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-  WaitForNewConnectionIds();
-  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection != nullptr) {
-    EXPECT_EQ(3u,
-              server_connection->GetStats().num_connectivity_probing_received);
-    EXPECT_EQ(server_cid1, server_connection->connection_id());
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  EXPECT_EQ(1u, server_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
-  server_thread_->Resume();
-
-  // Migrate socket to a new IP address again.
-  QuicIpAddress host3 = TestLoopback(3);
-  EXPECT_NE(addr1.host(), host3);
-  EXPECT_NE(host2, host3);
-  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
-
-  QuicConnectionId server_cid3 =
-      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-          client_connection);
-  EXPECT_FALSE(server_cid3.IsEmpty());
-  EXPECT_NE(server_cid1, server_cid3);
-  EXPECT_NE(server_cid2, server_cid3);
-  QuicConnectionId client_cid3 =
-      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
-          client_connection);
-  EXPECT_NE(client_cid1, client_cid3);
-  EXPECT_NE(client_cid2, client_cid3);
-  while (client_->client()->HasPendingPathValidation()) {
-    client_->client()->WaitForEvents();
-  }
-  EXPECT_EQ(host3, client_->client()->session()->self_address().host());
-  EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
-  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-                  client_connection)
-                  .IsEmpty());
-  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
-
-  // Server should send new server connection ID to client and retires old
-  // client connection ID.
-  WaitForNewConnectionIds();
-  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
-  EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
-}
-
-TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
-  ASSERT_TRUE(Initialize());
-  // Finish one request to make sure handshake established.
-  client_->SendSynchronousRequest("/foo");
-  // Disconnect for next 0-rtt request.
-  client_->Disconnect();
-
-  // Client get valid STK now. Do a 0-rtt request.
-  // Buffer a CHLO till another packets sent out.
-  reorder_writer_->SetDelay(1);
-  // Only send out a CHLO.
-  client_->client()->Initialize();
-  client_->client()->StartConnect();
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-  ASSERT_TRUE(client_->client()->connected());
-
-  // Send a request before handshake finishes.
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/bar";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  client_->SendMessage(headers, "");
-  client_->WaitForResponse();
-  EXPECT_EQ(kBarResponseBody, client_->response_body());
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  QuicConnectionStats client_stats = client_connection->GetStats();
-  // Client sends CHLO in packet 1 and retransmitted in packet 2. Because of
-  // the delay, server processes packet 2 and later drops packet 1. ACK is
-  // bundled with SHLO, such that 1 can be detected loss by time threshold.
-  EXPECT_LE(0u, client_stats.packets_lost);
-  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
-}
-
-TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
-  ASSERT_TRUE(Initialize());
-
-  // Send a request without a fin, to keep the stream open
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-  client_->SendMessage(headers, "", /*fin=*/false);
-  // Stream should be open
-  ASSERT_NE(nullptr, client_->latest_created_stream());
-  EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
-  EXPECT_FALSE(
-      QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
-
-  // Send a RST_STREAM+STOP_SENDING on the stream
-  // Code is not important.
-  client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-  client_->WaitForResponse();
-
-  // Stream should be gone.
-  ASSERT_EQ(nullptr, client_->latest_created_stream());
-}
-
-class BadShloPacketWriter : public QuicPacketWriterWrapper {
- public:
-  BadShloPacketWriter(ParsedQuicVersion version)
-      : error_returned_(false), version_(version) {}
-  ~BadShloPacketWriter() override {}
-
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          quic::PerPacketOptions* options) override {
-    const WriteResult result = QuicPacketWriterWrapper::WritePacket(
-        buffer, buf_len, self_address, peer_address, options);
-    const uint8_t type_byte = buffer[0];
-    if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
-        TypeByteIsServerHello(type_byte)) {
-      QUIC_DVLOG(1) << "Return write error for packet containing ServerHello";
-      error_returned_ = true;
-      return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
-    }
-    return result;
-  }
-
-  bool TypeByteIsServerHello(uint8_t type_byte) {
-    if (version_.UsesV2PacketTypes()) {
-      return ((type_byte & 0x30) >> 4) == 3;
-    }
-    if (version_.UsesQuicCrypto()) {
-      // ENCRYPTION_ZERO_RTT packet.
-      return ((type_byte & 0x30) >> 4) == 1;
-    }
-    // ENCRYPTION_HANDSHAKE packet.
-    return ((type_byte & 0x30) >> 4) == 2;
-  }
-
- private:
-  bool error_returned_;
-  ParsedQuicVersion version_;
-};
-
-TEST_P(EndToEndTest, ConnectionCloseBeforeHandshakeComplete) {
-  if (!version_.HasIetfInvariantHeader()) {
-    // Only runs for IETF QUIC header.
-    Initialize();
-    return;
-  }
-  // This test ensures ZERO_RTT_PROTECTED connection close could close a client
-  // which has switched to forward secure.
-  connect_to_server_on_initialize_ = false;
-  ASSERT_TRUE(Initialize());
-  server_thread_->Pause();
-  QuicDispatcher* dispatcher =
-      QuicServerPeer::GetDispatcher(server_thread_->server());
-  if (dispatcher == nullptr) {
-    ADD_FAILURE() << "Missing dispatcher";
-    server_thread_->Resume();
-    return;
-  }
-  if (dispatcher->NumSessions() > 0) {
-    ADD_FAILURE() << "Dispatcher session map not empty";
-    server_thread_->Resume();
-    return;
-  }
-  // Note: this writer will only used by the server connection, not the time
-  // wait list.
-  QuicDispatcherPeer::UseWriter(
-      dispatcher,
-      // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
-      // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
-      // ZERO_RTT_PROTECTED connection close would be sent to a client with
-      // encryption level FORWARD_SECURE.
-      new BadShloPacketWriter(version_));
-  server_thread_->Resume();
-
-  client_.reset(CreateQuicClient(client_writer_));
-  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
-  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
-  // client which switches to FORWARD_SECURE.
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
- public:
-  BadShloPacketWriter2(ParsedQuicVersion version)
-      : error_returned_(false), version_(version) {}
-  ~BadShloPacketWriter2() override {}
-
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          quic::PerPacketOptions* options) override {
-    const uint8_t type_byte = buffer[0];
-
-    if (type_byte & FLAGS_LONG_HEADER) {
-      if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
-          ((type_byte & 0x7F) == 0x7C)) {
-        QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
-        return WriteResult(WRITE_STATUS_OK, buf_len);
-      }
-    } else if (!error_returned_) {
-      QUIC_DVLOG(1) << "Return write error for short header packet";
-      error_returned_ = true;
-      return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
-    }
-    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
-                                                peer_address, options);
-  }
-
- private:
-  bool error_returned_;
-  ParsedQuicVersion version_;
-};
-
-TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
-  // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
-  // which has ZERO_RTT_PROTECTED encryption level.
-  connect_to_server_on_initialize_ = !version_.HasIetfInvariantHeader();
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfInvariantHeader()) {
-    // Only runs for IETF QUIC header.
-    return;
-  }
-  server_thread_->Pause();
-  QuicDispatcher* dispatcher =
-      QuicServerPeer::GetDispatcher(server_thread_->server());
-  if (dispatcher == nullptr) {
-    ADD_FAILURE() << "Missing dispatcher";
-    server_thread_->Resume();
-    return;
-  }
-  if (dispatcher->NumSessions() > 0) {
-    ADD_FAILURE() << "Dispatcher session map not empty";
-    server_thread_->Resume();
-    return;
-  }
-  // Note: this writer will only used by the server connection, not the time
-  // wait list.
-  QuicDispatcherPeer::UseWriter(
-      dispatcher,
-      // This causes the all server sent ZERO_RTT_PROTECTED packets to be
-      // dropped, and first short header packet causes write error.
-      new BadShloPacketWriter2(version_));
-  server_thread_->Resume();
-  client_.reset(CreateQuicClient(client_writer_));
-  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
-  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
-  // client.
-  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-// Test that the stream id manager closes the connection if a stream
-// in excess of the allowed maximum.
-TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
-  // Has to be before version test, see EndToEndTest::TearDown()
-  ASSERT_TRUE(Initialize());
-  if (!version_.HasIetfQuicFrames()) {
-    // Only runs for IETF QUIC.
-    return;
-  }
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  std::string body(kMaxOutgoingPacketSize, 'a');
-  SpdyHeaderBlock headers;
-  headers[":method"] = "POST";
-  headers[":path"] = "/foo";
-  headers[":scheme"] = "https";
-  headers[":authority"] = server_hostname_;
-
-  // Force the client to write with a stream ID that exceeds the limit.
-  QuicSpdySession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  QuicStreamIdManager* stream_id_manager =
-      QuicSessionPeer::ietf_bidirectional_stream_id_manager(client_session);
-  ASSERT_TRUE(stream_id_manager);
-  QuicStreamCount max_number_of_streams =
-      stream_id_manager->outgoing_max_streams();
-  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
-      client_session,
-      GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
-  client_->SendCustomSynchronousRequest(headers, body);
-  EXPECT_THAT(client_->stream_error(),
-              IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
-  EXPECT_THAT(client_session->error(), IsError(QUIC_INVALID_STREAM_ID));
-  EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, client_session->close_type());
-  EXPECT_TRUE(
-      IS_IETF_STREAM_FRAME(client_session->transport_close_frame_type()));
-}
-
-TEST_P(EndToEndTest, CustomTransportParameters) {
-  if (!version_.UsesTls()) {
-    // Custom transport parameters are only supported with TLS.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  constexpr auto kCustomParameter =
-      static_cast<TransportParameters::TransportParameterId>(0xff34);
-  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
-      "test";
-  NiceMock<MockQuicConnectionDebugVisitor> visitor;
-  connection_debug_visitor_ = &visitor;
-  EXPECT_CALL(visitor, OnTransportParametersSent(_))
-      .WillOnce(Invoke([kCustomParameter](
-                           const TransportParameters& transport_parameters) {
-        ASSERT_NE(transport_parameters.custom_parameters.find(kCustomParameter),
-                  transport_parameters.custom_parameters.end());
-        EXPECT_EQ(transport_parameters.custom_parameters.at(kCustomParameter),
-                  "test");
-      }));
-  EXPECT_CALL(visitor, OnTransportParametersReceived(_)).Times(1);
-  ASSERT_TRUE(Initialize());
-
-  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  QuicConfig* server_config = nullptr;
-  if (server_session != nullptr) {
-    server_config = server_session->config();
-  } else {
-    ADD_FAILURE() << "Missing server session";
-  }
-  if (server_config != nullptr) {
-    if (server_config->received_custom_transport_parameters().find(
-            kCustomParameter) !=
-        server_config->received_custom_transport_parameters().end()) {
-      EXPECT_EQ(server_config->received_custom_transport_parameters().at(
-                    kCustomParameter),
-                "test");
-    } else {
-      ADD_FAILURE() << "Did not find custom parameter";
-    }
-  } else {
-    ADD_FAILURE() << "Missing server config";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
-  if (!version_.HasLongHeaderLengths()) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
-  if (!version_.HasLongHeaderLengths()) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.UsesTls()) {
-    // This test uses custom transport parameters to increase the size of the
-    // CHLO, and those are only supported with TLS.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  constexpr auto kCustomParameter =
-      static_cast<TransportParameters::TransportParameterId>(0xff34);
-  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
-      std::string(2000, '?');
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
-  if (!version_.HasLongHeaderLengths()) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  client_supported_versions_.insert(client_supported_versions_.begin(),
-                                    QuicVersionReservedForNegotiation());
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
-  if (!version_.HasLongHeaderLengths()) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  SetPacketLossPercentage(30);
-  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  // Disable blackhole detection as this test is testing loss recovery.
-  client_extra_copts_.push_back(kNBHD);
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_GT(
-      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
-      0u);
-}
-
-// Testing packet writer that makes a copy of the first sent packets before
-// sending them. Useful for tests that need access to sent packets.
-class CopyingPacketWriter : public PacketDroppingTestWriter {
- public:
-  explicit CopyingPacketWriter(int num_packets_to_copy)
-      : num_packets_to_copy_(num_packets_to_copy) {}
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override {
-    if (num_packets_to_copy_ > 0) {
-      num_packets_to_copy_--;
-      packets_.push_back(
-          QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
-    }
-    return PacketDroppingTestWriter::WritePacket(buffer, buf_len, self_address,
-                                                 peer_address, options);
-  }
-
-  std::vector<std::unique_ptr<QuicEncryptedPacket>>& packets() {
-    return packets_;
-  }
-
- private:
-  int num_packets_to_copy_;
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
-};
-
-TEST_P(EndToEndTest, ChaosProtectionDisabled) {
-  if (!version_.UsesCryptoFrames()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  // Replace the client's writer with one that'll save the first packet.
-  auto copying_writer = new CopyingPacketWriter(1);
-  delete client_writer_;
-  client_writer_ = copying_writer;
-  // Disable chaos protection and perform an HTTP request.
-  client_config_.SetClientConnectionOptions(QuicTagVector{kNCHP});
-  ASSERT_TRUE(Initialize());
-  SendSynchronousFooRequestAndCheckResponse();
-  // Parse the saved packet to make sure it's valid.
-  SimpleQuicFramer validation_framer({version_});
-  validation_framer.framer()->SetInitialObfuscators(
-      GetClientConnection()->connection_id());
-  ASSERT_GT(copying_writer->packets().size(), 0u);
-  EXPECT_TRUE(validation_framer.ProcessPacket(*copying_writer->packets()[0]));
-  // TODO(dschinazi) figure out a way to use a MockRandom in this test so we
-  // can inspect the contents of this packet.
-}
-
-TEST_P(EndToEndTest, DisablePermuteTlsExtensions) {
-  if (!version_.UsesTls()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  // Disable TLS extension permutation and perform an HTTP request.
-  client_config_.SetClientConnectionOptions(QuicTagVector{kNBPE});
-  ASSERT_TRUE(Initialize());
-  EXPECT_FALSE(GetClientSession()->permutes_tls_extensions());
-  SendSynchronousFooRequestAndCheckResponse();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByClient) {
-  if (!version_.UsesTls()) {
-    // Key Update is only supported in TLS handshake.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
-
-  EXPECT_TRUE(
-      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
-  EXPECT_TRUE(
-      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection) {
-    QuicConnectionStats server_stats = server_connection->GetStats();
-    EXPECT_EQ(2u, server_stats.key_update_count);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByServer) {
-  if (!version_.UsesTls()) {
-    // Key Update is only supported in TLS handshake.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
-
-  // Use WaitUntil to ensure the server had executed the key update predicate
-  // before sending the Foo request, otherwise the test can be flaky if it
-  // receives the Foo request before executing the key update.
-  server_thread_->WaitUntil(
-      [this]() {
-        QuicConnection* server_connection = GetServerConnection();
-        if (server_connection != nullptr) {
-          if (!server_connection->IsKeyUpdateAllowed()) {
-            // Server may not have received ack from client yet for the current
-            // key phase, wait a bit and try again.
-            return false;
-          }
-          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
-              KeyUpdateReason::kLocalForTests));
-        } else {
-          ADD_FAILURE() << "Missing server connection";
-        }
-        return true;
-      },
-      QuicTime::Delta::FromSeconds(5));
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
-  server_thread_->WaitUntil(
-      [this]() {
-        QuicConnection* server_connection = GetServerConnection();
-        if (server_connection != nullptr) {
-          if (!server_connection->IsKeyUpdateAllowed()) {
-            return false;
-          }
-          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
-              KeyUpdateReason::kLocalForTests));
-        } else {
-          ADD_FAILURE() << "Missing server connection";
-        }
-        return true;
-      },
-      QuicTime::Delta::FromSeconds(5));
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection) {
-    QuicConnectionStats server_stats = server_connection->GetStats();
-    EXPECT_EQ(2u, server_stats.key_update_count);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByBoth) {
-  if (!version_.UsesTls()) {
-    // Key Update is only supported in TLS handshake.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-
-  ASSERT_TRUE(Initialize());
-
-  SendSynchronousFooRequestAndCheckResponse();
-
-  // Use WaitUntil to ensure the server had executed the key update predicate
-  // before the client sends the Foo request, otherwise the Foo request from
-  // the client could trigger the server key update before the server can
-  // initiate the key update locally. That would mean the test is no longer
-  // hitting the intended test state of both sides locally initiating a key
-  // update before receiving a packet in the new key phase from the other side.
-  // Additionally the test would fail since InitiateKeyUpdate() would not allow
-  // to do another key update yet and return false.
-  server_thread_->WaitUntil(
-      [this]() {
-        QuicConnection* server_connection = GetServerConnection();
-        if (server_connection != nullptr) {
-          if (!server_connection->IsKeyUpdateAllowed()) {
-            // Server may not have received ack from client yet for the current
-            // key phase, wait a bit and try again.
-            return false;
-          }
-          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
-              KeyUpdateReason::kLocalForTests));
-        } else {
-          ADD_FAILURE() << "Missing server connection";
-        }
-        return true;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_TRUE(
-      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
-
-  server_thread_->WaitUntil(
-      [this]() {
-        QuicConnection* server_connection = GetServerConnection();
-        if (server_connection != nullptr) {
-          if (!server_connection->IsKeyUpdateAllowed()) {
-            return false;
-          }
-          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
-              KeyUpdateReason::kLocalForTests));
-        } else {
-          ADD_FAILURE() << "Missing server connection";
-        }
-        return true;
-      },
-      QuicTime::Delta::FromSeconds(5));
-  EXPECT_TRUE(
-      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
-  SendSynchronousFooRequestAndCheckResponse();
-  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection) {
-    QuicConnectionStats server_stats = server_connection->GetStats();
-    EXPECT_EQ(2u, server_stats.key_update_count);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, KeyUpdateInitiatedByConfidentialityLimit) {
-  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 16U);
-
-  if (!version_.UsesTls()) {
-    // Key Update is only supported in TLS handshake.
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-
-  ASSERT_TRUE(Initialize());
-
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
-
-  server_thread_->WaitUntil(
-      [this]() {
-        QuicConnection* server_connection = GetServerConnection();
-        if (server_connection != nullptr) {
-          EXPECT_EQ(0u, server_connection->GetStats().key_update_count);
-        } else {
-          ADD_FAILURE() << "Missing server connection";
-        }
-        return true;
-      },
-      QuicTime::Delta::FromSeconds(5));
-
-  for (uint64_t i = 0;
-       i < GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit); ++i) {
-    SendSynchronousFooRequestAndCheckResponse();
-  }
-
-  // Don't know exactly how many packets will be sent in each request/response,
-  // so just test that at least one key update occurred.
-  EXPECT_LE(1u, client_connection->GetStats().key_update_count);
-
-  server_thread_->Pause();
-  QuicConnection* server_connection = GetServerConnection();
-  if (server_connection) {
-    QuicConnectionStats server_stats = server_connection->GetStats();
-    EXPECT_LE(1u, server_stats.key_update_count);
-  } else {
-    ADD_FAILURE() << "Missing server connection";
-  }
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, TlsResumptionEnabledOnTheFly) {
-  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesTls()) {
-    // This test is TLS specific.
-    return;
-  }
-
-  // Send the first request. Client should not have a resumption ticket.
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
-            ssl_early_data_no_session_offered);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  client_->Disconnect();
-
-  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
-
-  // Send the second request. Client should still have no resumption ticket, but
-  // it will receive one which can be used by the next request.
-  client_->Connect();
-  SendSynchronousFooRequestAndCheckResponse();
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
-            ssl_early_data_no_session_offered);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  client_->Disconnect();
-
-  // Send the third request in 0RTT.
-  client_->Connect();
-  SendSynchronousFooRequestAndCheckResponse();
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  client_->Disconnect();
-}
-
-TEST_P(EndToEndTest, TlsResumptionDisabledOnTheFly) {
-  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesTls()) {
-    // This test is TLS specific.
-    return;
-  }
-
-  // Send the first request and then disconnect.
-  SendSynchronousFooRequestAndCheckResponse();
-  QuicSpdyClientSession* client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  client_->Disconnect();
-
-  // Send the second request in 0RTT.
-  client_->Connect();
-  SendSynchronousFooRequestAndCheckResponse();
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_TRUE(client_session->EarlyDataAccepted());
-  client_->Disconnect();
-
-  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
-
-  // Send the third request. The client should try resumption but server should
-  // decline it.
-  client_->Connect();
-  SendSynchronousFooRequestAndCheckResponse();
-
-  client_session = GetClientSession();
-  ASSERT_TRUE(client_session);
-  EXPECT_FALSE(client_session->EarlyDataAccepted());
-  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
-            ssl_early_data_session_not_resumed);
-  client_->Disconnect();
-
-  // Keep sending until the client runs out of resumption tickets.
-  for (int i = 0; i < 10; ++i) {
-    client_->Connect();
-    SendSynchronousFooRequestAndCheckResponse();
-
-    client_session = GetClientSession();
-    ASSERT_TRUE(client_session);
-    EXPECT_FALSE(client_session->EarlyDataAccepted());
-    const auto early_data_reason =
-        client_session->GetCryptoStream()->EarlyDataReason();
-    client_->Disconnect();
-
-    if (early_data_reason != ssl_early_data_session_not_resumed) {
-      EXPECT_EQ(early_data_reason, ssl_early_data_unsupported_for_session);
-      return;
-    }
-  }
-
-  ADD_FAILURE() << "Client should not have 10 resumption tickets.";
-}
-
-TEST_P(EndToEndTest, WebTransportSessionSetup) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* web_transport =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_NE(web_transport, nullptr);
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
-              nullptr);
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, WebTransportSessionSetupWithEchoWithSuffix) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  // "/echoFoo" should be accepted as "echo" with "set-header" query.
-  WebTransportHttp3* web_transport = CreateWebTransportSession(
-      "/echoFoo?set-header=bar:baz", /*wait_for_server_response=*/true);
-  ASSERT_NE(web_transport, nullptr);
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
-              nullptr);
-  server_thread_->Resume();
-  const spdy::SpdyHeaderBlock* response_headers = client_->response_headers();
-  auto it = response_headers->find("bar");
-  EXPECT_NE(it, response_headers->end());
-  EXPECT_EQ(it->second, "baz");
-}
-
-TEST_P(EndToEndTest, WebTransportSessionWithLoss) {
-  enable_web_transport_ = true;
-  // Enable loss to verify all permutations of receiving SETTINGS and
-  // request/response data.
-  SetPacketLossPercentage(30);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* web_transport =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_NE(web_transport, nullptr);
-
-  server_thread_->Pause();
-  QuicSpdySession* server_session = GetServerSession();
-  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
-              nullptr);
-  server_thread_->Resume();
-}
-
-TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStream) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  WebTransportStream* outgoing_stream =
-      session->OpenOutgoingUnidirectionalStream();
-  ASSERT_TRUE(outgoing_stream != nullptr);
-
-  auto stream_visitor = std::make_unique<NiceMock<MockStreamVisitor>>();
-  bool data_acknowledged = false;
-  EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
-      .WillOnce(Assign(&data_acknowledged, true));
-  outgoing_stream->SetVisitor(std::move(stream_visitor));
-
-  EXPECT_TRUE(outgoing_stream->Write("test"));
-  EXPECT_TRUE(outgoing_stream->SendFin());
-
-  bool stream_received = false;
-  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
-      .WillOnce(Assign(&stream_received, true));
-  client_->WaitUntil(2000, [&stream_received]() { return stream_received; });
-  EXPECT_TRUE(stream_received);
-  WebTransportStream* received_stream =
-      session->AcceptIncomingUnidirectionalStream();
-  ASSERT_TRUE(received_stream != nullptr);
-  std::string received_data;
-  WebTransportStream::ReadResult result = received_stream->Read(&received_data);
-  EXPECT_EQ(received_data, "test");
-  EXPECT_TRUE(result.fin);
-
-  client_->WaitUntil(2000,
-                     [&data_acknowledged]() { return data_acknowledged; });
-  EXPECT_TRUE(data_acknowledged);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStreamSentEarly) {
-  enable_web_transport_ = true;
-  SetPacketLossPercentage(30);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  WebTransportStream* outgoing_stream =
-      session->OpenOutgoingUnidirectionalStream();
-  ASSERT_TRUE(outgoing_stream != nullptr);
-  EXPECT_TRUE(outgoing_stream->Write("test"));
-  EXPECT_TRUE(outgoing_stream->SendFin());
-
-  bool stream_received = false;
-  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
-      .WillOnce(Assign(&stream_received, true));
-  client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
-  EXPECT_TRUE(stream_received);
-  WebTransportStream* received_stream =
-      session->AcceptIncomingUnidirectionalStream();
-  ASSERT_TRUE(received_stream != nullptr);
-  std::string received_data;
-  WebTransportStream::ReadResult result = received_stream->Read(&received_data);
-  EXPECT_EQ(received_data, "test");
-  EXPECT_TRUE(result.fin);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionBidirectionalStream) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-
-  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-
-  auto stream_visitor_owned = std::make_unique<NiceMock<MockStreamVisitor>>();
-  MockStreamVisitor* stream_visitor = stream_visitor_owned.get();
-  bool data_acknowledged = false;
-  EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
-      .WillOnce(Assign(&data_acknowledged, true));
-  stream->SetVisitor(std::move(stream_visitor_owned));
-
-  EXPECT_TRUE(stream->Write("test"));
-  EXPECT_TRUE(stream->SendFin());
-
-  std::string received_data =
-      ReadDataFromWebTransportStreamUntilFin(stream, stream_visitor);
-  EXPECT_EQ(received_data, "test");
-
-  client_->WaitUntil(2000,
-                     [&data_acknowledged]() { return data_acknowledged; });
-  EXPECT_TRUE(data_acknowledged);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionBidirectionalStreamWithBuffering) {
-  enable_web_transport_ = true;
-  SetPacketLossPercentage(30);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
-  ASSERT_TRUE(session != nullptr);
-
-  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_TRUE(stream->Write("test"));
-  EXPECT_TRUE(stream->SendFin());
-
-  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
-  EXPECT_EQ(received_data, "test");
-}
-
-TEST_P(EndToEndTest, WebTransportSessionServerBidirectionalStream) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  bool stream_received = false;
-  EXPECT_CALL(visitor, OnIncomingBidirectionalStreamAvailable())
-      .WillOnce(Assign(&stream_received, true));
-  client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
-  EXPECT_TRUE(stream_received);
-
-  WebTransportStream* stream = session->AcceptIncomingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_TRUE(stream->Write("test"));
-  EXPECT_TRUE(stream->SendFin());
-
-  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
-  EXPECT_EQ(received_data, "test");
-}
-
-TEST_P(EndToEndTest, WebTransportDatagrams) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  quiche::SimpleBufferAllocator allocator;
-  for (int i = 0; i < 10; i++) {
-    session->SendOrQueueDatagram(MemSliceFromString("test"));
-  }
-
-  int received = 0;
-  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
-    received++;
-  });
-  client_->WaitUntil(5000, [&received]() { return received > 0; });
-  EXPECT_GT(received, 0);
-}
-
-TEST_P(EndToEndTest, WebTransportDatagramsWithContexts) {
-  enable_web_transport_ = true;
-  use_datagram_contexts_ = true;
-  SetPacketLossPercentage(30);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  QuicSpdyStream* connect_stream = nullptr;
-  WebTransportHttp3* session = CreateWebTransportSession(
-      "/echo", /*wait_for_server_response=*/true, &connect_stream);
-  ASSERT_TRUE(session != nullptr);
-  ASSERT_TRUE(connect_stream != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  quiche::SimpleBufferAllocator allocator;
-  for (int i = 0; i < 10; i++) {
-    session->SendOrQueueDatagram(MemSliceFromString("test"));
-  }
-
-  int received = 0;
-  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
-    received++;
-  });
-  client_->WaitUntil(5000, [&received]() { return received > 0; });
-  EXPECT_GT(received, 0);
-  EXPECT_TRUE(QuicSpdyStreamPeer::use_datagram_contexts(connect_stream));
-}
-
-TEST_P(EndToEndTest, WebTransportSessionClose) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  QuicStreamId stream_id = stream->GetStreamId();
-  EXPECT_TRUE(stream->Write("test"));
-  // Keep stream open.
-
-  bool close_received = false;
-  EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
-      .WillOnce(Assign(&close_received, true));
-  session->CloseSession(42, "test error");
-  client_->WaitUntil(2000, [&]() { return close_received; });
-  EXPECT_TRUE(close_received);
-
-  QuicSpdyStream* spdy_stream =
-      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
-  EXPECT_TRUE(spdy_stream == nullptr);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionCloseWithoutCapsule) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  QuicStreamId stream_id = stream->GetStreamId();
-  EXPECT_TRUE(stream->Write("test"));
-  // Keep stream open.
-
-  bool close_received = false;
-  EXPECT_CALL(visitor, OnSessionClosed(0, ""))
-      .WillOnce(Assign(&close_received, true));
-  session->CloseSessionWithFinOnlyForTests();
-  client_->WaitUntil(2000, [&]() { return close_received; });
-  EXPECT_TRUE(close_received);
-
-  QuicSpdyStream* spdy_stream =
-      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
-  EXPECT_TRUE(spdy_stream == nullptr);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionReceiveClose) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session = CreateWebTransportSession(
-      "/session-close", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-
-  WebTransportStream* stream = session->OpenOutgoingUnidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  QuicStreamId stream_id = stream->GetStreamId();
-  EXPECT_TRUE(stream->Write("42 test error"));
-  EXPECT_TRUE(stream->SendFin());
-
-  // Have some other streams open pending, to ensure they are closed properly.
-  stream = session->OpenOutgoingUnidirectionalStream();
-  stream = session->OpenOutgoingBidirectionalStream();
-
-  bool close_received = false;
-  EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
-      .WillOnce(Assign(&close_received, true));
-  client_->WaitUntil(2000, [&]() { return close_received; });
-  EXPECT_TRUE(close_received);
-
-  QuicSpdyStream* spdy_stream =
-      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
-  EXPECT_TRUE(spdy_stream == nullptr);
-}
-
-TEST_P(EndToEndTest, WebTransportSessionStreamTermination) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session =
-      CreateWebTransportSession("/resets", /*wait_for_server_response=*/true);
-  ASSERT_TRUE(session != nullptr);
-
-  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
-  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
-      .WillRepeatedly([this, session]() {
-        ReadAllIncomingWebTransportUnidirectionalStreams(session);
-      });
-
-  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
-  QuicStreamId id1 = stream->GetStreamId();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_TRUE(stream->Write("test"));
-  stream->ResetWithUserCode(42);
-
-  // This read fails if the stream is closed in both directions, since that
-  // results in stream object being deleted.
-  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
-  EXPECT_LE(received_data.size(), 4u);
-
-  stream = session->OpenOutgoingBidirectionalStream();
-  QuicStreamId id2 = stream->GetStreamId();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_TRUE(stream->Write("test"));
-  stream->SendStopSending(24);
-
-  std::array<std::string, 2> expected_log = {
-      absl::StrCat("Received reset for stream ", id1, " with error code 42"),
-      absl::StrCat("Received stop sending for stream ", id2,
-                   " with error code 24"),
-  };
-  client_->WaitUntil(2000, [this, &expected_log]() {
-    return received_webtransport_unidirectional_streams_.size() >=
-           expected_log.size();
-  });
-  EXPECT_THAT(received_webtransport_unidirectional_streams_,
-              UnorderedElementsAreArray(expected_log));
-
-  // Since we closed the read side, cleanly closing the write side should result
-  // in the stream getting deleted.
-  ASSERT_TRUE(GetClientSession()->GetOrCreateSpdyDataStream(id2) != nullptr);
-  EXPECT_TRUE(stream->SendFin());
-  EXPECT_TRUE(client_->WaitUntil(2000, [this, id2]() {
-    return GetClientSession()->GetOrCreateSpdyDataStream(id2) == nullptr;
-  }));
-}
-
-TEST_P(EndToEndTest, WebTransportSession404) {
-  enable_web_transport_ = true;
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-
-  WebTransportHttp3* session = CreateWebTransportSession(
-      "/does-not-exist", /*wait_for_server_response=*/false);
-  ASSERT_TRUE(session != nullptr);
-  QuicSpdyStream* connect_stream = client_->latest_created_stream();
-  QuicStreamId connect_stream_id = connect_stream->id();
-
-  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_TRUE(stream->Write("test"));
-  EXPECT_TRUE(stream->SendFin());
-
-  EXPECT_TRUE(client_->WaitUntil(-1, [this, connect_stream_id]() {
-    return GetClientSession()->GetOrCreateSpdyDataStream(connect_stream_id) ==
-           nullptr;
-  }));
-}
-
-TEST_P(EndToEndTest, InvalidExtendedConnect) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-  // Missing :path header.
-  spdy::SpdyHeaderBlock headers;
-  headers[":scheme"] = "https";
-  headers[":authority"] = "localhost";
-  headers[":method"] = "CONNECT";
-  headers[":protocol"] = "webtransport";
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->WaitForResponse();
-  // An early response should be received.
-  CheckResponseHeaders("400");
-}
-
-TEST_P(EndToEndTest, RejectExtendedConnect) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  // Disable extended CONNECT.
-  memory_cache_backend_.set_enable_extended_connect(false);
-  ASSERT_TRUE(Initialize());
-
-  if (!version_.UsesHttp3()) {
-    return;
-  }
-  // This extended CONNECT should be rejected.
-  spdy::SpdyHeaderBlock headers;
-  headers[":scheme"] = "https";
-  headers[":authority"] = "localhost";
-  headers[":method"] = "CONNECT";
-  headers[":path"] = "/echo";
-  headers[":protocol"] = "webtransport";
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->WaitForResponse();
-  CheckResponseHeaders("400");
-
-  // Vanilla CONNECT should be accepted.
-  spdy::SpdyHeaderBlock headers2;
-  headers2[":authority"] = "localhost";
-  headers2[":method"] = "CONNECT";
-
-  client_->SendMessage(headers2, "body", /*fin=*/true);
-  client_->WaitForResponse();
-  // No :path header, so 404.
-  CheckResponseHeaders("404");
-}
-
-TEST_P(EndToEndTest, RejectInvalidRequestHeader) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  ASSERT_TRUE(Initialize());
-
-  spdy::SpdyHeaderBlock headers;
-  headers[":scheme"] = "https";
-  headers[":authority"] = "localhost";
-  headers[":method"] = "GET";
-  headers[":path"] = "/echo";
-  // transfer-encoding header is not allowed.
-  headers["transfer-encoding"] = "chunk";
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->WaitForResponse();
-  CheckResponseHeaders("400");
-}
-
-TEST_P(EndToEndTest, RejectTransferEncodingResponse) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  ASSERT_TRUE(Initialize());
-
-  // Add a response with transfer-encoding headers.
-  SpdyHeaderBlock headers;
-  headers[":status"] = "200";
-  headers["transfer-encoding"] = "gzip";
-
-  SpdyHeaderBlock trailers;
-  trailers["some-trailing-header"] = "trailing-header-value";
-
-  memory_cache_backend_.AddResponse(server_hostname_, "/eep",
-                                    std::move(headers), "", trailers.Clone());
-
-  std::string received_response = client_->SendSynchronousRequest("/eep");
-  EXPECT_THAT(client_->stream_error(),
-              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(EndToEndTest, RejectUpperCaseRequest) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  ASSERT_TRUE(Initialize());
-
-  spdy::SpdyHeaderBlock headers;
-  headers[":scheme"] = "https";
-  headers[":authority"] = "localhost";
-  headers[":method"] = "GET";
-  headers[":path"] = "/echo";
-  headers["UpperCaseHeader"] = "foo";
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->WaitForResponse();
-  CheckResponseHeaders("400");
-}
-
-TEST_P(EndToEndTest, RejectRequestWithInvalidToken) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  ASSERT_TRUE(Initialize());
-
-  spdy::SpdyHeaderBlock headers;
-  headers[":scheme"] = "https";
-  headers[":authority"] = "localhost";
-  headers[":method"] = "GET";
-  headers[":path"] = "/echo";
-  headers["invalid,header"] = "foo";
-
-  client_->SendMessage(headers, "", /*fin=*/false);
-  client_->WaitForResponse();
-  CheckResponseHeaders("400");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/http_constants.cc b/quic/core/http/http_constants.cc
deleted file mode 100644
index 94d42fe..0000000
--- a/quic/core/http/http_constants.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_constants.h"
-
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x;
-
-std::string H3SettingsToString(Http3AndQpackSettingsIdentifiers identifier) {
-  switch (identifier) {
-    RETURN_STRING_LITERAL(SETTINGS_QPACK_MAX_TABLE_CAPACITY);
-    RETURN_STRING_LITERAL(SETTINGS_MAX_FIELD_SECTION_SIZE);
-    RETURN_STRING_LITERAL(SETTINGS_QPACK_BLOCKED_STREAMS);
-    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT00);
-    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT04);
-    RETURN_STRING_LITERAL(SETTINGS_WEBTRANS_DRAFT00);
-    RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
-  }
-  return absl::StrCat("UNSUPPORTED_SETTINGS_TYPE(", identifier, ")");
-}
-
-const absl::string_view kUserAgentHeaderName = "user-agent";
-
-#undef RETURN_STRING_LITERAL  // undef for jumbo builds
-
-}  // namespace quic
diff --git a/quic/core/http/http_constants.h b/quic/core/http/http_constants.h
deleted file mode 100644
index 213b7d9..0000000
--- a/quic/core/http/http_constants.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Unidirectional stream types.
-enum : uint64_t {
-  // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#unidirectional-streams
-  kControlStream = 0x00,
-  kServerPushStream = 0x01,
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#enc-dec-stream-def
-  kQpackEncoderStream = 0x02,
-  kQpackDecoderStream = 0x03,
-  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-unidirectional-streams
-  kWebTransportUnidirectionalStream = 0x54,
-};
-
-// This includes control stream, QPACK encoder stream, and QPACK decoder stream.
-enum : QuicStreamCount { kHttp3StaticUnidirectionalStreamCount = 3 };
-
-// HTTP/3 and QPACK settings identifiers.
-// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#settings-parameters
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#configuration
-enum Http3AndQpackSettingsIdentifiers : uint64_t {
-  // Same value as spdy::SETTINGS_HEADER_TABLE_SIZE.
-  SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0x01,
-  // Same value as spdy::SETTINGS_MAX_HEADER_LIST_SIZE.
-  SETTINGS_MAX_FIELD_SECTION_SIZE = 0x06,
-  SETTINGS_QPACK_BLOCKED_STREAMS = 0x07,
-  // draft-ietf-masque-h3-datagram-00.
-  SETTINGS_H3_DATAGRAM_DRAFT00 = 0x276,
-  // draft-ietf-masque-h3-datagram-04.
-  SETTINGS_H3_DATAGRAM_DRAFT04 = 0xffd277,
-  // draft-ietf-webtrans-http3-00
-  SETTINGS_WEBTRANS_DRAFT00 = 0x2b603742,
-  // draft-ietf-httpbis-h3-websockets
-  SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
-};
-
-// Returns HTTP/3 SETTINGS identifier as a string.
-QUIC_EXPORT std::string H3SettingsToString(
-    Http3AndQpackSettingsIdentifiers identifier);
-
-// Default maximum dynamic table capacity, communicated via
-// SETTINGS_QPACK_MAX_TABLE_CAPACITY.
-enum : QuicByteCount {
-  kDefaultQpackMaxDynamicTableCapacity = 64 * 1024  // 64 KB
-};
-
-// Default limit on the size of uncompressed headers,
-// communicated via SETTINGS_MAX_HEADER_LIST_SIZE.
-enum : QuicByteCount {
-  kDefaultMaxUncompressedHeaderSize = 16 * 1024  // 16 KB
-};
-
-// Default limit on number of blocked streams, communicated via
-// SETTINGS_QPACK_BLOCKED_STREAMS.
-enum : uint64_t { kDefaultMaximumBlockedStreams = 100 };
-
-ABSL_CONST_INIT QUIC_EXPORT_PRIVATE extern const absl::string_view
-    kUserAgentHeaderName;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
diff --git a/quic/core/http/http_decoder.cc b/quic/core/http/http_decoder.cc
deleted file mode 100644
index 02aa123..0000000
--- a/quic/core/http/http_decoder.cc
+++ /dev/null
@@ -1,674 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_decoder.h"
-
-#include <cstdint>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "http2/http2_constants.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Limit on the payload length for frames that are buffered by HttpDecoder.
-// If a frame header indicating a payload length exceeding this limit is
-// received, HttpDecoder closes the connection.  Does not apply to frames that
-// are not buffered here but each payload fragment is immediately passed to
-// Visitor, like HEADERS, DATA, and unknown frames.
-constexpr QuicByteCount kPayloadLengthLimit = 1024 * 1024;
-
-}  // anonymous namespace
-
-HttpDecoder::HttpDecoder(Visitor* visitor) : HttpDecoder(visitor, Options()) {}
-HttpDecoder::HttpDecoder(Visitor* visitor, Options options)
-    : visitor_(visitor),
-      allow_web_transport_stream_(options.allow_web_transport_stream),
-      state_(STATE_READING_FRAME_TYPE),
-      current_frame_type_(0),
-      current_length_field_length_(0),
-      remaining_length_field_length_(0),
-      current_frame_length_(0),
-      remaining_frame_length_(0),
-      current_type_field_length_(0),
-      remaining_type_field_length_(0),
-      error_(QUIC_NO_ERROR),
-      error_detail_("") {
-  QUICHE_DCHECK(visitor_);
-}
-
-HttpDecoder::~HttpDecoder() {}
-
-// static
-bool HttpDecoder::DecodeSettings(const char* data,
-                                 QuicByteCount len,
-                                 SettingsFrame* frame) {
-  QuicDataReader reader(data, len);
-  uint64_t frame_type;
-  if (!reader.ReadVarInt62(&frame_type)) {
-    QUIC_DLOG(ERROR) << "Unable to read frame type.";
-    return false;
-  }
-
-  if (frame_type != static_cast<uint64_t>(HttpFrameType::SETTINGS)) {
-    QUIC_DLOG(ERROR) << "Invalid frame type " << frame_type;
-    return false;
-  }
-
-  absl::string_view frame_contents;
-  if (!reader.ReadStringPieceVarInt62(&frame_contents)) {
-    QUIC_DLOG(ERROR) << "Failed to read SETTINGS frame contents";
-    return false;
-  }
-
-  QuicDataReader frame_reader(frame_contents);
-
-  while (!frame_reader.IsDoneReading()) {
-    uint64_t id;
-    if (!frame_reader.ReadVarInt62(&id)) {
-      QUIC_DLOG(ERROR) << "Unable to read setting identifier.";
-      return false;
-    }
-    uint64_t content;
-    if (!frame_reader.ReadVarInt62(&content)) {
-      QUIC_DLOG(ERROR) << "Unable to read setting value.";
-      return false;
-    }
-    auto result = frame->values.insert({id, content});
-    if (!result.second) {
-      QUIC_DLOG(ERROR) << "Duplicate setting identifier.";
-      return false;
-    }
-  }
-  return true;
-}
-
-QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
-  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
-  QUICHE_DCHECK_NE(STATE_ERROR, state_);
-
-  QuicDataReader reader(data, len);
-  bool continue_processing = true;
-  // BufferOrParsePayload() and FinishParsing() may need to be called even if
-  // there is no more data so that they can finish processing the current frame.
-  while (continue_processing && (reader.BytesRemaining() != 0 ||
-                                 state_ == STATE_BUFFER_OR_PARSE_PAYLOAD ||
-                                 state_ == STATE_FINISH_PARSING)) {
-    // |continue_processing| must have been set to false upon error.
-    QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
-    QUICHE_DCHECK_NE(STATE_ERROR, state_);
-
-    switch (state_) {
-      case STATE_READING_FRAME_TYPE:
-        continue_processing = ReadFrameType(&reader);
-        break;
-      case STATE_READING_FRAME_LENGTH:
-        continue_processing = ReadFrameLength(&reader);
-        break;
-      case STATE_BUFFER_OR_PARSE_PAYLOAD:
-        continue_processing = BufferOrParsePayload(&reader);
-        break;
-      case STATE_READING_FRAME_PAYLOAD:
-        continue_processing = ReadFramePayload(&reader);
-        break;
-      case STATE_FINISH_PARSING:
-        continue_processing = FinishParsing();
-        break;
-      case STATE_PARSING_NO_LONGER_POSSIBLE:
-        continue_processing = false;
-        QUIC_BUG(HttpDecoder PARSING_NO_LONGER_POSSIBLE)
-            << "HttpDecoder called after an indefinite-length frame has been "
-               "received";
-        RaiseError(QUIC_INTERNAL_ERROR,
-                   "HttpDecoder called after an indefinite-length frame has "
-                   "been received");
-        break;
-      case STATE_ERROR:
-        break;
-      default:
-        QUIC_BUG(quic_bug_10411_1) << "Invalid state: " << state_;
-    }
-  }
-
-  return len - reader.BytesRemaining();
-}
-
-bool HttpDecoder::ReadFrameType(QuicDataReader* reader) {
-  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
-  if (current_type_field_length_ == 0) {
-    // A new frame is coming.
-    current_type_field_length_ = reader->PeekVarInt62Length();
-    QUICHE_DCHECK_NE(0u, current_type_field_length_);
-    if (current_type_field_length_ > reader->BytesRemaining()) {
-      // Buffer a new type field.
-      remaining_type_field_length_ = current_type_field_length_;
-      BufferFrameType(reader);
-      return true;
-    }
-    // The reader has all type data needed, so no need to buffer.
-    bool success = reader->ReadVarInt62(&current_frame_type_);
-    QUICHE_DCHECK(success);
-  } else {
-    // Buffer the existing type field.
-    BufferFrameType(reader);
-    // The frame is still not buffered completely.
-    if (remaining_type_field_length_ != 0) {
-      return true;
-    }
-    QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
-    bool success = type_reader.ReadVarInt62(&current_frame_type_);
-    QUICHE_DCHECK(success);
-  }
-
-  // https://tools.ietf.org/html/draft-ietf-quic-http-31#section-7.2.8
-  // specifies that the following frames are treated as errors.
-  if (current_frame_type_ ==
-          static_cast<uint64_t>(http2::Http2FrameType::PRIORITY) ||
-      current_frame_type_ ==
-          static_cast<uint64_t>(http2::Http2FrameType::PING) ||
-      current_frame_type_ ==
-          static_cast<uint64_t>(http2::Http2FrameType::WINDOW_UPDATE) ||
-      current_frame_type_ ==
-          static_cast<uint64_t>(http2::Http2FrameType::CONTINUATION)) {
-    RaiseError(QUIC_HTTP_RECEIVE_SPDY_FRAME,
-               absl::StrCat("HTTP/2 frame received in a HTTP/3 connection: ",
-                            current_frame_type_));
-    return false;
-  }
-
-  if (current_frame_type_ ==
-      static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH)) {
-    RaiseError(QUIC_HTTP_FRAME_ERROR, "CANCEL_PUSH frame received.");
-    return false;
-  }
-  if (current_frame_type_ ==
-      static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE)) {
-    RaiseError(QUIC_HTTP_FRAME_ERROR, "PUSH_PROMISE frame received.");
-    return false;
-  }
-
-  state_ = STATE_READING_FRAME_LENGTH;
-  return true;
-}
-
-bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
-  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
-  if (current_length_field_length_ == 0) {
-    // A new frame is coming.
-    current_length_field_length_ = reader->PeekVarInt62Length();
-    QUICHE_DCHECK_NE(0u, current_length_field_length_);
-    if (current_length_field_length_ > reader->BytesRemaining()) {
-      // Buffer a new length field.
-      remaining_length_field_length_ = current_length_field_length_;
-      BufferFrameLength(reader);
-      return true;
-    }
-    // The reader has all length data needed, so no need to buffer.
-    bool success = reader->ReadVarInt62(&current_frame_length_);
-    QUICHE_DCHECK(success);
-  } else {
-    // Buffer the existing length field.
-    BufferFrameLength(reader);
-    // The frame is still not buffered completely.
-    if (remaining_length_field_length_ != 0) {
-      return true;
-    }
-    QuicDataReader length_reader(length_buffer_.data(),
-                                 current_length_field_length_);
-    bool success = length_reader.ReadVarInt62(&current_frame_length_);
-    QUICHE_DCHECK(success);
-  }
-
-  // WEBTRANSPORT_STREAM frames are indefinitely long, and thus require
-  // special handling; the number after the frame type is actually the
-  // WebTransport session ID, and not the length.
-  if (allow_web_transport_stream_ &&
-      current_frame_type_ ==
-          static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM)) {
-    visitor_->OnWebTransportStreamFrameType(
-        current_length_field_length_ + current_type_field_length_,
-        current_frame_length_);
-    state_ = STATE_PARSING_NO_LONGER_POSSIBLE;
-    return false;
-  }
-
-  if (IsFrameBuffered() &&
-      current_frame_length_ > MaxFrameLength(current_frame_type_)) {
-    RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
-    return false;
-  }
-
-  // Calling the following visitor methods does not require parsing of any
-  // frame payload.
-  bool continue_processing = true;
-  const QuicByteCount header_length =
-      current_length_field_length_ + current_type_field_length_;
-
-  switch (current_frame_type_) {
-    case static_cast<uint64_t>(HttpFrameType::DATA):
-      continue_processing =
-          visitor_->OnDataFrameStart(header_length, current_frame_length_);
-      break;
-    case static_cast<uint64_t>(HttpFrameType::HEADERS):
-      continue_processing =
-          visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
-      break;
-    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
-      QUICHE_NOTREACHED();
-      break;
-    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
-      continue_processing = visitor_->OnSettingsFrameStart(header_length);
-      break;
-    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
-      QUICHE_NOTREACHED();
-      break;
-    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
-      break;
-    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
-      break;
-    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
-      continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
-      break;
-    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
-      continue_processing = visitor_->OnAcceptChFrameStart(header_length);
-      break;
-    default:
-      continue_processing = visitor_->OnUnknownFrameStart(
-          current_frame_type_, header_length, current_frame_length_);
-      break;
-  }
-
-  remaining_frame_length_ = current_frame_length_;
-
-  if (IsFrameBuffered()) {
-    state_ = STATE_BUFFER_OR_PARSE_PAYLOAD;
-    return continue_processing;
-  }
-
-  state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
-                                          : STATE_READING_FRAME_PAYLOAD;
-  return continue_processing;
-}
-
-bool HttpDecoder::IsFrameBuffered() {
-  switch (current_frame_type_) {
-    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
-      return true;
-    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
-      return true;
-    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
-      return true;
-    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
-      return true;
-    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
-      return true;
-  }
-
-  // Other defined frame types as well as unknown frames are not buffered.
-  return false;
-}
-
-bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
-  QUICHE_DCHECK(!IsFrameBuffered());
-  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
-  QUICHE_DCHECK_NE(0u, remaining_frame_length_);
-
-  bool continue_processing = true;
-
-  switch (current_frame_type_) {
-    case static_cast<uint64_t>(HttpFrameType::DATA): {
-      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-          remaining_frame_length_, reader->BytesRemaining());
-      absl::string_view payload;
-      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
-      QUICHE_DCHECK(success);
-      QUICHE_DCHECK(!payload.empty());
-      continue_processing = visitor_->OnDataFramePayload(payload);
-      remaining_frame_length_ -= payload.length();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
-      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-          remaining_frame_length_, reader->BytesRemaining());
-      absl::string_view payload;
-      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
-      QUICHE_DCHECK(success);
-      QUICHE_DCHECK(!payload.empty());
-      continue_processing = visitor_->OnHeadersFramePayload(payload);
-      remaining_frame_length_ -= payload.length();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    default: {
-      continue_processing = HandleUnknownFramePayload(reader);
-      break;
-    }
-  }
-
-  if (remaining_frame_length_ == 0) {
-    state_ = STATE_FINISH_PARSING;
-  }
-
-  return continue_processing;
-}
-
-bool HttpDecoder::FinishParsing() {
-  QUICHE_DCHECK(!IsFrameBuffered());
-  QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
-
-  bool continue_processing = true;
-
-  switch (current_frame_type_) {
-    case static_cast<uint64_t>(HttpFrameType::DATA): {
-      continue_processing = visitor_->OnDataFrameEnd();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
-      continue_processing = visitor_->OnHeadersFrameEnd();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
-      QUICHE_NOTREACHED();
-      break;
-    }
-    default:
-      continue_processing = visitor_->OnUnknownFrameEnd();
-  }
-
-  ResetForNextFrame();
-  return continue_processing;
-}
-
-void HttpDecoder::ResetForNextFrame() {
-  current_length_field_length_ = 0;
-  current_type_field_length_ = 0;
-  state_ = STATE_READING_FRAME_TYPE;
-}
-
-bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader* reader) {
-  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_frame_length_, reader->BytesRemaining());
-  absl::string_view payload;
-  bool success = reader->ReadStringPiece(&payload, bytes_to_read);
-  QUICHE_DCHECK(success);
-  QUICHE_DCHECK(!payload.empty());
-  remaining_frame_length_ -= payload.length();
-  return visitor_->OnUnknownFramePayload(payload);
-}
-
-bool HttpDecoder::BufferOrParsePayload(QuicDataReader* reader) {
-  QUICHE_DCHECK(IsFrameBuffered());
-  QUICHE_DCHECK_EQ(current_frame_length_,
-                   buffer_.size() + remaining_frame_length_);
-
-  if (buffer_.empty() && reader->BytesRemaining() >= current_frame_length_) {
-    // |*reader| contains entire payload, which might be empty.
-    remaining_frame_length_ = 0;
-    QuicDataReader current_payload_reader(reader->PeekRemainingPayload().data(),
-                                          current_frame_length_);
-    bool continue_processing = ParseEntirePayload(&current_payload_reader);
-
-    reader->Seek(current_frame_length_);
-    ResetForNextFrame();
-    return continue_processing;
-  }
-
-  // Buffer as much of the payload as |*reader| contains.
-  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_frame_length_, reader->BytesRemaining());
-  absl::StrAppend(&buffer_, reader->PeekRemainingPayload().substr(
-                                /* pos = */ 0, bytes_to_read));
-  reader->Seek(bytes_to_read);
-  remaining_frame_length_ -= bytes_to_read;
-
-  QUICHE_DCHECK_EQ(current_frame_length_,
-                   buffer_.size() + remaining_frame_length_);
-
-  if (remaining_frame_length_ > 0) {
-    QUICHE_DCHECK(reader->IsDoneReading());
-    return false;
-  }
-
-  QuicDataReader buffer_reader(buffer_);
-  bool continue_processing = ParseEntirePayload(&buffer_reader);
-  buffer_.clear();
-
-  ResetForNextFrame();
-  return continue_processing;
-}
-
-bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
-  QUICHE_DCHECK(IsFrameBuffered());
-  QUICHE_DCHECK_EQ(current_frame_length_, reader->BytesRemaining());
-  QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
-
-  switch (current_frame_type_) {
-    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
-      QUICHE_NOTREACHED();
-      return false;
-    }
-    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
-      SettingsFrame frame;
-      if (!ParseSettingsFrame(reader, &frame)) {
-        return false;
-      }
-      return visitor_->OnSettingsFrame(frame);
-    }
-    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
-      GoAwayFrame frame;
-      if (!reader->ReadVarInt62(&frame.id)) {
-        RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY ID.");
-        return false;
-      }
-      if (!reader->IsDoneReading()) {
-        RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
-        return false;
-      }
-      return visitor_->OnGoAwayFrame(frame);
-    }
-    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
-      MaxPushIdFrame frame;
-      if (!reader->ReadVarInt62(&frame.push_id)) {
-        RaiseError(QUIC_HTTP_FRAME_ERROR,
-                   "Unable to read MAX_PUSH_ID push_id.");
-        return false;
-      }
-      if (!reader->IsDoneReading()) {
-        RaiseError(QUIC_HTTP_FRAME_ERROR,
-                   "Superfluous data in MAX_PUSH_ID frame.");
-        return false;
-      }
-      return visitor_->OnMaxPushIdFrame(frame);
-    }
-    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
-      PriorityUpdateFrame frame;
-      if (!ParsePriorityUpdateFrame(reader, &frame)) {
-        return false;
-      }
-      return visitor_->OnPriorityUpdateFrame(frame);
-    }
-    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
-      AcceptChFrame frame;
-      if (!ParseAcceptChFrame(reader, &frame)) {
-        return false;
-      }
-      return visitor_->OnAcceptChFrame(frame);
-    }
-    default:
-      // Only above frame types are parsed by ParseEntirePayload().
-      QUICHE_NOTREACHED();
-      return false;
-  }
-}
-
-void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
-  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_length_field_length_, reader->BytesRemaining());
-  bool success =
-      reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
-                            remaining_length_field_length_,
-                        bytes_to_read);
-  QUICHE_DCHECK(success);
-  remaining_length_field_length_ -= bytes_to_read;
-}
-
-void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
-  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_type_field_length_, reader->BytesRemaining());
-  bool success =
-      reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
-                            remaining_type_field_length_,
-                        bytes_to_read);
-  QUICHE_DCHECK(success);
-  remaining_type_field_length_ -= bytes_to_read;
-}
-
-void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
-  state_ = STATE_ERROR;
-  error_ = error;
-  error_detail_ = std::move(error_detail);
-  visitor_->OnError(this);
-}
-
-bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
-                                     SettingsFrame* frame) {
-  while (!reader->IsDoneReading()) {
-    uint64_t id;
-    if (!reader->ReadVarInt62(&id)) {
-      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
-      return false;
-    }
-    uint64_t content;
-    if (!reader->ReadVarInt62(&content)) {
-      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
-      return false;
-    }
-    auto result = frame->values.insert({id, content});
-    if (!result.second) {
-      RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
-                 "Duplicate setting identifier.");
-      return false;
-    }
-  }
-  return true;
-}
-
-bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
-                                              PriorityUpdateFrame* frame) {
-  frame->prioritized_element_type = REQUEST_STREAM;
-
-  if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
-    RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
-    return false;
-  }
-
-  absl::string_view priority_field_value = reader->ReadRemainingPayload();
-  frame->priority_field_value =
-      std::string(priority_field_value.data(), priority_field_value.size());
-
-  return true;
-}
-
-bool HttpDecoder::ParseAcceptChFrame(QuicDataReader* reader,
-                                     AcceptChFrame* frame) {
-  absl::string_view origin;
-  absl::string_view value;
-  while (!reader->IsDoneReading()) {
-    if (!reader->ReadStringPieceVarInt62(&origin)) {
-      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH origin.");
-      return false;
-    }
-    if (!reader->ReadStringPieceVarInt62(&value)) {
-      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH value.");
-      return false;
-    }
-    // Copy data.
-    frame->entries.push_back({std::string(origin.data(), origin.size()),
-                              std::string(value.data(), value.size())});
-  }
-  return true;
-}
-
-QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
-  QUICHE_DCHECK(IsFrameBuffered());
-
-  switch (frame_type) {
-    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
-      return kPayloadLengthLimit;
-    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
-      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
-    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
-      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
-    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
-      return kPayloadLengthLimit;
-    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
-      return kPayloadLengthLimit;
-    default:
-      QUICHE_NOTREACHED();
-      return 0;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/http/http_decoder.h b/quic/core/http/http_decoder.h
deleted file mode 100644
index 118fbcf..0000000
--- a/quic/core/http/http_decoder.h
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-
-class HttpDecoderPeer;
-
-}  // namespace test
-
-class QuicDataReader;
-
-// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
-// session.
-class QUIC_EXPORT_PRIVATE HttpDecoder {
- public:
-  struct QUIC_EXPORT_PRIVATE Options {
-    // Indicates that WEBTRANSPORT_STREAM should be parsed.
-    bool allow_web_transport_stream = false;
-  };
-
-  class QUIC_EXPORT_PRIVATE Visitor {
-   public:
-    virtual ~Visitor() {}
-
-    // Called if an error is detected.
-    virtual void OnError(HttpDecoder* decoder) = 0;
-
-    // All the following methods return true to continue decoding,
-    // and false to pause it.
-    // On*FrameStart() methods are called after the frame header is completely
-    // processed.  At that point it is safe to consume |header_length| bytes.
-
-    // Called when a MAX_PUSH_ID frame has been successfully parsed.
-    virtual bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
-
-    // Called when a GOAWAY frame has been successfully parsed.
-    virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
-
-    // Called when a SETTINGS frame has been received.
-    virtual bool OnSettingsFrameStart(QuicByteCount header_length) = 0;
-
-    // Called when a SETTINGS frame has been successfully parsed.
-    virtual bool OnSettingsFrame(const SettingsFrame& frame) = 0;
-
-    // Called when a DATA frame has been received.
-    // |header_length| and |payload_length| are the length of DATA frame header
-    // and payload, respectively.
-    virtual bool OnDataFrameStart(QuicByteCount header_length,
-                                  QuicByteCount payload_length) = 0;
-    // Called when part of the payload of a DATA frame has been read.  May be
-    // called multiple times for a single frame.  |payload| is guaranteed to be
-    // non-empty.
-    virtual bool OnDataFramePayload(absl::string_view payload) = 0;
-    // Called when a DATA frame has been completely processed.
-    virtual bool OnDataFrameEnd() = 0;
-
-    // Called when a HEADERS frame has been received.
-    // |header_length| and |payload_length| are the length of HEADERS frame
-    // header and payload, respectively.
-    virtual bool OnHeadersFrameStart(QuicByteCount header_length,
-                                     QuicByteCount payload_length) = 0;
-    // Called when part of the payload of a HEADERS frame has been read.  May be
-    // called multiple times for a single frame.  |payload| is guaranteed to be
-    // non-empty.
-    virtual bool OnHeadersFramePayload(absl::string_view payload) = 0;
-    // Called when a HEADERS frame has been completely processed.
-    virtual bool OnHeadersFrameEnd() = 0;
-
-    // Called when a PRIORITY_UPDATE frame has been received.
-    // |header_length| contains PRIORITY_UPDATE frame length and payload length.
-    virtual bool OnPriorityUpdateFrameStart(QuicByteCount header_length) = 0;
-
-    // Called when a PRIORITY_UPDATE frame has been successfully parsed.
-    virtual bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) = 0;
-
-    // Called when an ACCEPT_CH frame has been received.
-    // |header_length| contains ACCEPT_CH frame length and payload length.
-    virtual bool OnAcceptChFrameStart(QuicByteCount header_length) = 0;
-
-    // Called when an ACCEPT_CH frame has been successfully parsed.
-    virtual bool OnAcceptChFrame(const AcceptChFrame& frame) = 0;
-
-    // Called when a WEBTRANSPORT_STREAM frame type and the session ID varint
-    // immediately following it has been received.  Any further parsing should
-    // be done by the stream itself, and not the parser. Note that this does not
-    // return bool, because WEBTRANSPORT_STREAM always causes the parsing
-    // process to cease.
-    virtual void OnWebTransportStreamFrameType(
-        QuicByteCount header_length,
-        WebTransportSessionId session_id) = 0;
-
-    // Called when a frame of unknown type |frame_type| has been received.
-    // Frame type might be reserved, Visitor must make sure to ignore.
-    // |header_length| and |payload_length| are the length of the frame header
-    // and payload, respectively.
-    virtual bool OnUnknownFrameStart(uint64_t frame_type,
-                                     QuicByteCount header_length,
-                                     QuicByteCount payload_length) = 0;
-    // Called when part of the payload of the unknown frame has been read.  May
-    // be called multiple times for a single frame.  |payload| is guaranteed to
-    // be non-empty.
-    virtual bool OnUnknownFramePayload(absl::string_view payload) = 0;
-    // Called when the unknown frame has been completely processed.
-    virtual bool OnUnknownFrameEnd() = 0;
-  };
-
-  // |visitor| must be non-null, and must outlive HttpDecoder.
-  explicit HttpDecoder(Visitor* visitor);
-  explicit HttpDecoder(Visitor* visitor, Options options);
-
-  ~HttpDecoder();
-
-  // Processes the input and invokes the appropriate visitor methods, until a
-  // visitor method returns false or an error occurs.  Returns the number of
-  // bytes processed.  Does not process any input if called after an error.
-  // Paused processing can be resumed by calling ProcessInput() again with the
-  // unprocessed portion of data.  Must not be called after an error has
-  // occurred.
-  QuicByteCount ProcessInput(const char* data, QuicByteCount len);
-
-  // Decode settings frame from |data|.
-  // Upon successful decoding, |frame| will be populated, and returns true.
-  // This method is not used for regular processing of incoming data.
-  static bool DecodeSettings(const char* data,
-                             QuicByteCount len,
-                             SettingsFrame* frame);
-
-  // Returns an error code other than QUIC_NO_ERROR if and only if
-  // Visitor::OnError() has been called.
-  QuicErrorCode error() const { return error_; }
-
-  const std::string& error_detail() const { return error_detail_; }
-
-  // Returns true if input data processed so far ends on a frame boundary.
-  bool AtFrameBoundary() const { return state_ == STATE_READING_FRAME_TYPE; }
-
- private:
-  friend test::HttpDecoderPeer;
-
-  // Represents the current state of the parsing state machine.
-  enum HttpDecoderState {
-    STATE_READING_FRAME_LENGTH,
-    STATE_READING_FRAME_TYPE,
-
-    // States used for buffered frame types
-    STATE_BUFFER_OR_PARSE_PAYLOAD,
-
-    // States used for non-buffered frame types
-    STATE_READING_FRAME_PAYLOAD,
-    STATE_FINISH_PARSING,
-
-    STATE_PARSING_NO_LONGER_POSSIBLE,
-    STATE_ERROR
-  };
-
-  // Reads the type of a frame from |reader|. Sets error_ and error_detail_
-  // if there are any errors.  Also calls OnDataFrameStart() or
-  // OnHeadersFrameStart() for appropriate frame types. Returns whether the
-  // processing should continue.
-  bool ReadFrameType(QuicDataReader* reader);
-
-  // Reads the length of a frame from |reader|. Sets error_ and error_detail_
-  // if there are any errors.  Returns whether processing should continue.
-  bool ReadFrameLength(QuicDataReader* reader);
-
-  // Returns whether the current frame is of a buffered type.
-  // The payload of buffered frames is buffered by HttpDecoder, and parsed by
-  // HttpDecoder after the entire frame has been received.  (Copying to the
-  // buffer is skipped if the ProcessInput() call covers the entire payload.)
-  // Frames that are not buffered have every payload fragment synchronously
-  // passed to the Visitor without buffering.
-  bool IsFrameBuffered();
-
-  // For buffered frame types, calls BufferOrParsePayload().  For other frame
-  // types, reads the payload of the current frame from |reader| and calls
-  // visitor methods.  Returns whether processing should continue.
-  bool ReadFramePayload(QuicDataReader* reader);
-
-  // For buffered frame types, this method is only called if frame payload is
-  // empty, and it calls BufferOrParsePayload().  For other frame types, this
-  // method directly calls visitor methods to signal that frame had been
-  // received completely.  Returns whether processing should continue.
-  bool FinishParsing();
-
-  // Reset internal fields to prepare for reading next frame.
-  void ResetForNextFrame();
-
-  // Read payload of unknown frame from |reader| and call
-  // Visitor::OnUnknownFramePayload().  Returns true decoding should continue,
-  // false if it should be paused.
-  bool HandleUnknownFramePayload(QuicDataReader* reader);
-
-  // Buffers any remaining frame payload from |*reader| into |buffer_| if
-  // necessary.  Parses the frame payload if complete.  Parses out of |*reader|
-  // without unnecessary copy if |*reader| contains entire payload.
-  // Returns whether processing should continue.
-  // Must only be called when current frame type is buffered.
-  bool BufferOrParsePayload(QuicDataReader* reader);
-
-  // Parses the entire payload of certain kinds of frames that are parsed in a
-  // single pass.  |reader| must have at least |current_frame_length_| bytes.
-  // Returns whether processing should continue.
-  // Must only be called when current frame type is buffered.
-  bool ParseEntirePayload(QuicDataReader* reader);
-
-  // Buffers any remaining frame length field from |reader| into
-  // |length_buffer_|.
-  void BufferFrameLength(QuicDataReader* reader);
-
-  // Buffers any remaining frame type field from |reader| into |type_buffer_|.
-  void BufferFrameType(QuicDataReader* reader);
-
-  // Sets |error_| and |error_detail_| accordingly.
-  void RaiseError(QuicErrorCode error, std::string error_detail);
-
-  // Parses the payload of a SETTINGS frame from |reader| into |frame|.
-  bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
-
-  // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
-  // from |reader| into |frame|.
-  bool ParsePriorityUpdateFrame(QuicDataReader* reader,
-                                PriorityUpdateFrame* frame);
-
-  // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
-  bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
-
-  // Returns the max frame size of a given |frame_type|.
-  QuicByteCount MaxFrameLength(uint64_t frame_type);
-
-  // Visitor to invoke when messages are parsed.
-  Visitor* const visitor_;  // Unowned.
-  // Whether WEBTRANSPORT_STREAM should be parsed.
-  bool allow_web_transport_stream_;
-  // Current state of the parsing.
-  HttpDecoderState state_;
-  // Type of the frame currently being parsed.
-  uint64_t current_frame_type_;
-  // Size of the frame's length field.
-  QuicByteCount current_length_field_length_;
-  // Remaining length that's needed for the frame's length field.
-  QuicByteCount remaining_length_field_length_;
-  // Length of the payload of the frame currently being parsed.
-  QuicByteCount current_frame_length_;
-  // Remaining payload bytes to be parsed.
-  QuicByteCount remaining_frame_length_;
-  // Length of the frame's type field.
-  QuicByteCount current_type_field_length_;
-  // Remaining length that's needed for the frame's type field.
-  QuicByteCount remaining_type_field_length_;
-  // Last error.
-  QuicErrorCode error_;
-  // The issue which caused |error_|
-  std::string error_detail_;
-  // Remaining unparsed data.
-  std::string buffer_;
-  // Remaining unparsed length field data.
-  std::array<char, sizeof(uint64_t)> length_buffer_;
-  // Remaining unparsed type field data.
-  std::array<char, sizeof(uint64_t)> type_buffer_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
diff --git a/quic/core/http/http_decoder_test.cc b/quic/core/http/http_decoder_test.cc
deleted file mode 100644
index d8a54e0..0000000
--- a/quic/core/http/http_decoder_test.cc
+++ /dev/null
@@ -1,1136 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_decoder.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Eq;
-using ::testing::InSequence;
-using ::testing::Return;
-
-namespace quic {
-namespace test {
-
-class HttpDecoderPeer {
- public:
-  static uint64_t current_frame_type(HttpDecoder* decoder) {
-    return decoder->current_frame_type_;
-  }
-};
-
-namespace {
-
-class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
- public:
-  ~MockHttpDecoderVisitor() override = default;
-
-  // Called if an error is detected.
-  MOCK_METHOD(void, OnError, (HttpDecoder*), (override));
-
-  MOCK_METHOD(bool,
-              OnMaxPushIdFrame,
-              (const MaxPushIdFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnGoAwayFrame, (const GoAwayFrame& frame), (override));
-  MOCK_METHOD(bool,
-              OnSettingsFrameStart,
-              (QuicByteCount header_length),
-              (override));
-  MOCK_METHOD(bool, OnSettingsFrame, (const SettingsFrame& frame), (override));
-
-  MOCK_METHOD(bool,
-              OnDataFrameStart,
-              (QuicByteCount header_length, QuicByteCount payload_length),
-              (override));
-  MOCK_METHOD(bool,
-              OnDataFramePayload,
-              (absl::string_view payload),
-              (override));
-  MOCK_METHOD(bool, OnDataFrameEnd, (), (override));
-
-  MOCK_METHOD(bool,
-              OnHeadersFrameStart,
-              (QuicByteCount header_length, QuicByteCount payload_length),
-              (override));
-  MOCK_METHOD(bool,
-              OnHeadersFramePayload,
-              (absl::string_view payload),
-              (override));
-  MOCK_METHOD(bool, OnHeadersFrameEnd, (), (override));
-
-  MOCK_METHOD(bool,
-              OnPriorityUpdateFrameStart,
-              (QuicByteCount header_length),
-              (override));
-  MOCK_METHOD(bool,
-              OnPriorityUpdateFrame,
-              (const PriorityUpdateFrame& frame),
-              (override));
-
-  MOCK_METHOD(bool,
-              OnAcceptChFrameStart,
-              (QuicByteCount header_length),
-              (override));
-  MOCK_METHOD(bool, OnAcceptChFrame, (const AcceptChFrame& frame), (override));
-  MOCK_METHOD(void,
-              OnWebTransportStreamFrameType,
-              (QuicByteCount header_length, WebTransportSessionId session_id),
-              (override));
-
-  MOCK_METHOD(bool,
-              OnUnknownFrameStart,
-              (uint64_t frame_type,
-               QuicByteCount header_length,
-               QuicByteCount payload_length),
-              (override));
-  MOCK_METHOD(bool,
-              OnUnknownFramePayload,
-              (absl::string_view payload),
-              (override));
-  MOCK_METHOD(bool, OnUnknownFrameEnd, (), (override));
-};
-
-class HttpDecoderTest : public QuicTest {
- public:
-  HttpDecoderTest() : decoder_(&visitor_) {
-    ON_CALL(visitor_, OnMaxPushIdFrame(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnGoAwayFrame(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnSettingsFrameStart(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnSettingsFrame(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnDataFrameStart(_, _)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnDataFramePayload(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnDataFrameEnd()).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnHeadersFrameStart(_, _)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnHeadersFramePayload(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnHeadersFrameEnd()).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnPriorityUpdateFrameStart(_))
-        .WillByDefault(Return(true));
-    ON_CALL(visitor_, OnPriorityUpdateFrame(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnAcceptChFrameStart(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnAcceptChFrame(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnUnknownFrameStart(_, _, _)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnUnknownFramePayload(_)).WillByDefault(Return(true));
-    ON_CALL(visitor_, OnUnknownFrameEnd()).WillByDefault(Return(true));
-  }
-  ~HttpDecoderTest() override = default;
-
-  uint64_t current_frame_type() {
-    return HttpDecoderPeer::current_frame_type(&decoder_);
-  }
-
-  // Process |input| in a single call to HttpDecoder::ProcessInput().
-  QuicByteCount ProcessInput(absl::string_view input) {
-    return decoder_.ProcessInput(input.data(), input.size());
-  }
-
-  // Feed |input| to |decoder_| one character at a time,
-  // verifying that each character gets processed.
-  void ProcessInputCharByChar(absl::string_view input) {
-    for (char c : input) {
-      EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
-    }
-  }
-
-  // Append garbage to |input|, then process it in a single call to
-  // HttpDecoder::ProcessInput().  Verify that garbage is not read.
-  QuicByteCount ProcessInputWithGarbageAppended(absl::string_view input) {
-    std::string input_with_garbage_appended = absl::StrCat(input, "blahblah");
-    QuicByteCount processed_bytes = ProcessInput(input_with_garbage_appended);
-
-    // Guaranteed by HttpDecoder::ProcessInput() contract.
-    QUICHE_DCHECK_LE(processed_bytes, input_with_garbage_appended.size());
-
-    // Caller should set up visitor to pause decoding
-    // before HttpDecoder would read garbage.
-    EXPECT_LE(processed_bytes, input.size());
-
-    return processed_bytes;
-  }
-
-  testing::StrictMock<MockHttpDecoderVisitor> visitor_;
-  HttpDecoder decoder_;
-};
-
-TEST_F(HttpDecoderTest, InitialState) {
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, UnknownFrame) {
-  std::unique_ptr<char[]> input;
-
-  const QuicByteCount payload_lengths[] = {0, 14, 100};
-  const uint64_t frame_types[] = {
-      0x21, 0x40, 0x5f, 0x7e, 0x9d,  // some reserved frame types
-      0x6f, 0x14                     // some unknown, not reserved frame types
-  };
-
-  for (auto payload_length : payload_lengths) {
-    std::string data(payload_length, 'a');
-
-    for (auto frame_type : frame_types) {
-      const QuicByteCount total_length =
-          QuicDataWriter::GetVarInt62Len(frame_type) +
-          QuicDataWriter::GetVarInt62Len(payload_length) + payload_length;
-      input = std::make_unique<char[]>(total_length);
-
-      QuicDataWriter writer(total_length, input.get());
-      writer.WriteVarInt62(frame_type);
-      writer.WriteVarInt62(payload_length);
-      const QuicByteCount header_length = writer.length();
-      if (payload_length > 0) {
-        writer.WriteStringPiece(data);
-      }
-
-      EXPECT_CALL(visitor_, OnUnknownFrameStart(frame_type, header_length,
-                                                payload_length));
-      if (payload_length > 0) {
-        EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq(data)));
-      }
-      EXPECT_CALL(visitor_, OnUnknownFrameEnd());
-
-      EXPECT_EQ(total_length, decoder_.ProcessInput(input.get(), total_length));
-
-      EXPECT_THAT(decoder_.error(), IsQuicNoError());
-      ASSERT_EQ("", decoder_.error_detail());
-      EXPECT_EQ(frame_type, current_frame_type());
-    }
-  }
-}
-
-TEST_F(HttpDecoderTest, CancelPush) {
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "03"    // type (CANCEL_PUSH)
-      "01"    // length
-      "01");  // Push Id
-
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(1u, ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-  EXPECT_EQ("CANCEL_PUSH frame received.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, PushPromiseFrame) {
-  InSequence s;
-  std::string input =
-      absl::StrCat(absl::HexStringToBytes("05"    // type (PUSH PROMISE)
-                                          "08"    // length
-                                          "1f"),  // push id 31
-                   "Headers");                    // headers
-
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(1u, ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-  EXPECT_EQ("PUSH_PROMISE frame received.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, MaxPushId) {
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "0D"    // type (MAX_PUSH_ID)
-      "01"    // length
-      "01");  // Push Id
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})))
-      .WillOnce(Return(false));
-  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, SettingsFrame) {
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "07"    // length
-      "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
-      "02"    // content
-      "06"    // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
-      "05"    // content
-      "4100"  // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
-      "04");  // content
-
-  SettingsFrame frame;
-  frame.values[1] = 2;
-  frame.values[6] = 5;
-  frame.values[256] = 4;
-
-  // Visitor pauses processing.
-  absl::string_view remaining_input(input);
-  EXPECT_CALL(visitor_, OnSettingsFrameStart(2)).WillOnce(Return(false));
-  QuicByteCount processed_bytes =
-      ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(2u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnSettingsFrame(frame)).WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
-  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
-  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, CorruptSettingsFrame) {
-  const char* const kPayload =
-      "\x42\x11"                           // two-byte id
-      "\x80\x22\x33\x44"                   // four-byte value
-      "\x58\x39"                           // two-byte id
-      "\xf0\x22\x33\x44\x55\x66\x77\x88";  // eight-byte value
-  struct {
-    size_t payload_length;
-    const char* const error_message;
-  } kTestData[] = {
-      {1, "Unable to read setting identifier."},
-      {5, "Unable to read setting value."},
-      {7, "Unable to read setting identifier."},
-      {12, "Unable to read setting value."},
-  };
-
-  for (const auto& test_data : kTestData) {
-    std::string input;
-    input.push_back(4u);  // type SETTINGS
-    input.push_back(test_data.payload_length);
-    const size_t header_length = input.size();
-    input.append(kPayload, test_data.payload_length);
-
-    HttpDecoder decoder(&visitor_);
-    EXPECT_CALL(visitor_, OnSettingsFrameStart(header_length));
-    EXPECT_CALL(visitor_, OnError(&decoder));
-
-    QuicByteCount processed_bytes =
-        decoder.ProcessInput(input.data(), input.size());
-    EXPECT_EQ(input.size(), processed_bytes);
-    EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-    EXPECT_EQ(test_data.error_message, decoder.error_detail());
-  }
-}
-
-TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) {
-  std::string input = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "04"    // length
-      "01"    // identifier
-      "01"    // content
-      "01"    // identifier
-      "02");  // content
-
-  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-
-  EXPECT_EQ(input.size(), ProcessInput(input));
-
-  EXPECT_THAT(decoder_.error(),
-              IsError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER));
-  EXPECT_EQ("Duplicate setting identifier.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, DataFrame) {
-  InSequence s;
-  std::string input = absl::StrCat(absl::HexStringToBytes("00"    // type (DATA)
-                                                          "05"),  // length
-                                   "Data!");                      // data
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)).WillOnce(Return(false));
-  absl::string_view remaining_input(input);
-  QuicByteCount processed_bytes =
-      ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(2u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")))
-      .WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-
-  EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
-  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
-  EXPECT_CALL(visitor_, OnDataFrameEnd());
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("D")));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("t")));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("!")));
-  EXPECT_CALL(visitor_, OnDataFrameEnd());
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, FrameHeaderPartialDelivery) {
-  InSequence s;
-  // A large input that will occupy more than 1 byte in the length field.
-  std::string input(2048, 'x');
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      input.length(), quiche::SimpleBufferAllocator::Get());
-  // Partially send only 1 byte of the header to process.
-  EXPECT_EQ(1u, decoder_.ProcessInput(header.data(), 1));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Send the rest of the header.
-  EXPECT_CALL(visitor_, OnDataFrameStart(3, input.length()));
-  EXPECT_EQ(header.size() - 1,
-            decoder_.ProcessInput(header.data() + 1, header.size() - 1));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Send data.
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view(input)));
-  EXPECT_CALL(visitor_, OnDataFrameEnd());
-  EXPECT_EQ(2048u, decoder_.ProcessInput(input.data(), 2048));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, PartialDeliveryOfLargeFrameType) {
-  // Use a reserved type that takes four bytes as a varint.
-  const uint64_t frame_type = 0x1f * 0x222 + 0x21;
-  const QuicByteCount payload_length = 0;
-  const QuicByteCount header_length =
-      QuicDataWriter::GetVarInt62Len(frame_type) +
-      QuicDataWriter::GetVarInt62Len(payload_length);
-
-  auto input = std::make_unique<char[]>(header_length);
-  QuicDataWriter writer(header_length, input.get());
-  writer.WriteVarInt62(frame_type);
-  writer.WriteVarInt62(payload_length);
-
-  EXPECT_CALL(visitor_,
-              OnUnknownFrameStart(frame_type, header_length, payload_length));
-  EXPECT_CALL(visitor_, OnUnknownFrameEnd());
-
-  auto raw_input = input.get();
-  for (uint64_t i = 0; i < header_length; ++i) {
-    char c = raw_input[i];
-    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
-  }
-
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-  EXPECT_EQ(frame_type, current_frame_type());
-}
-
-TEST_F(HttpDecoderTest, GoAway) {
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "07"    // type (GOAWAY)
-      "01"    // length
-      "01");  // ID
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})))
-      .WillOnce(Return(false));
-  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, HeadersFrame) {
-  InSequence s;
-  std::string input =
-      absl::StrCat(absl::HexStringToBytes("01"    // type (HEADERS)
-                                          "07"),  // length
-                   "Headers");                    // headers
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)).WillOnce(Return(false));
-  absl::string_view remaining_input(input);
-  QuicByteCount processed_bytes =
-      ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(2u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")))
-      .WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
-  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("H")));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("a")));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("d")));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("r")));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("s")));
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyDataFrame) {
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "00"    // type (DATA)
-      "00");  // length
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0)).WillOnce(Return(false));
-  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
-
-  EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
-  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
-  EXPECT_CALL(visitor_, OnDataFrameEnd());
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
-  EXPECT_CALL(visitor_, OnDataFrameEnd());
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyHeadersFrame) {
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "01"    // type (HEADERS)
-      "00");  // length
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0)).WillOnce(Return(false));
-  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
-
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
-  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, GoawayWithOverlyLargePayload) {
-  std::string input = absl::HexStringToBytes(
-      "07"    // type (GOAWAY)
-      "10");  // length exceeding the maximum possible length for GOAWAY frame
-  // Process all data at once.
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(2u, ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
-  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, MaxPushIdWithOverlyLargePayload) {
-  std::string input = absl::HexStringToBytes(
-      "0d"    // type (MAX_PUSH_ID)
-      "10");  // length exceeding the maximum possible length for MAX_PUSH_ID
-              // frame
-  // Process all data at once.
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(2u, ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
-  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, FrameWithOverlyLargePayload) {
-  // Regression test for b/193919867: Ensure that reading frames with incredibly
-  // large payload lengths does not lead to allocating unbounded memory.
-  constexpr size_t max_input_length =
-      /*max frame type varint length*/ sizeof(uint64_t) +
-      /*max frame length varint length*/ sizeof(uint64_t) +
-      /*one byte of payload*/ sizeof(uint8_t);
-  char input[max_input_length];
-  for (uint64_t frame_type = 0; frame_type < 1025; frame_type++) {
-    ::testing::NiceMock<MockHttpDecoderVisitor> visitor;
-    HttpDecoder decoder(&visitor);
-    QuicDataWriter writer(max_input_length, input);
-    ASSERT_TRUE(writer.WriteVarInt62(frame_type));         // frame type.
-    ASSERT_TRUE(writer.WriteVarInt62(kVarInt62MaxValue));  // frame length.
-    ASSERT_TRUE(writer.WriteUInt8(0x00));  // one byte of payload.
-    EXPECT_NE(decoder.ProcessInput(input, writer.length()), 0u) << frame_type;
-  }
-}
-
-TEST_F(HttpDecoderTest, MalformedSettingsFrame) {
-  char input[30];
-  QuicDataWriter writer(30, input);
-  // Write type SETTINGS.
-  writer.WriteUInt8(0x04);
-  // Write length.
-  writer.WriteVarInt62(2048 * 1024);
-
-  writer.WriteStringPiece("Malformed payload");
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(5u, decoder_.ProcessInput(input, ABSL_ARRAYSIZE(input)));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
-  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, Http2Frame) {
-  std::string input = absl::HexStringToBytes(
-      "06"    // PING in HTTP/2 but not supported in HTTP/3.
-      "05"    // length
-      "15");  // random payload
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(1u, ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_RECEIVE_SPDY_FRAME));
-  EXPECT_EQ("HTTP/2 frame received in a HTTP/3 connection: 6",
-            decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, HeadersPausedThenData) {
-  InSequence s;
-  std::string input =
-      absl::StrCat(absl::HexStringToBytes("01"    // type (HEADERS)
-                                          "07"),  // length
-                   "Headers",                     // headers
-                   absl::HexStringToBytes("00"    // type (DATA)
-                                          "05"),  // length
-                   "Data!");                      // data
-
-  // Visitor pauses processing, maybe because header decompression is blocked.
-  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
-  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
-  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
-  absl::string_view remaining_input(input);
-  QuicByteCount processed_bytes =
-      ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(9u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  // Process DATA frame.
-  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
-  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
-  EXPECT_CALL(visitor_, OnDataFrameEnd());
-
-  processed_bytes = ProcessInput(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, CorruptFrame) {
-  InSequence s;
-
-  struct {
-    const char* const input;
-    const char* const error_message;
-  } kTestData[] = {{"\x0D"   // type (MAX_PUSH_ID)
-                    "\x01"   // length
-                    "\x40",  // first byte of two-byte varint push id
-                    "Unable to read MAX_PUSH_ID push_id."},
-                   {"\x0D"  // type (MAX_PUSH_ID)
-                    "\x04"  // length
-                    "\x05"  // valid push id
-                    "foo",  // superfluous data
-                    "Superfluous data in MAX_PUSH_ID frame."},
-                   {"\x07"   // type (GOAWAY)
-                    "\x01"   // length
-                    "\x40",  // first byte of two-byte varint stream id
-                    "Unable to read GOAWAY ID."},
-                   {"\x07"  // type (GOAWAY)
-                    "\x04"  // length
-                    "\x05"  // valid stream id
-                    "foo",  // superfluous data
-                    "Superfluous data in GOAWAY frame."},
-                   {"\x40\x89"  // type (ACCEPT_CH)
-                    "\x01"      // length
-                    "\x40",     // first byte of two-byte varint origin length
-                    "Unable to read ACCEPT_CH origin."},
-                   {"\x40\x89"  // type (ACCEPT_CH)
-                    "\x01"      // length
-                    "\x05",     // valid origin length but no origin string
-                    "Unable to read ACCEPT_CH origin."},
-                   {"\x40\x89"  // type (ACCEPT_CH)
-                    "\x04"      // length
-                    "\x05"      // valid origin length
-                    "foo",      // payload ends before origin ends
-                    "Unable to read ACCEPT_CH origin."},
-                   {"\x40\x89"  // type (ACCEPT_CH)
-                    "\x04"      // length
-                    "\x03"      // valid origin length
-                    "foo",      // payload ends at end of origin: no value
-                    "Unable to read ACCEPT_CH value."},
-                   {"\x40\x89"  // type (ACCEPT_CH)
-                    "\x05"      // length
-                    "\x03"      // valid origin length
-                    "foo"       // payload ends at end of origin: no value
-                    "\x40",     // first byte of two-byte varint value length
-                    "Unable to read ACCEPT_CH value."},
-                   {"\x40\x89"  // type (ACCEPT_CH)
-                    "\x08"      // length
-                    "\x03"      // valid origin length
-                    "foo"       // origin
-                    "\x05"      // valid value length
-                    "bar",      // payload ends before value ends
-                    "Unable to read ACCEPT_CH value."}};
-
-  for (const auto& test_data : kTestData) {
-    {
-      HttpDecoder decoder(&visitor_);
-      EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
-      EXPECT_CALL(visitor_, OnError(&decoder));
-
-      absl::string_view input(test_data.input);
-      decoder.ProcessInput(input.data(), input.size());
-      EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-      EXPECT_EQ(test_data.error_message, decoder.error_detail());
-    }
-    {
-      HttpDecoder decoder(&visitor_);
-      EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
-      EXPECT_CALL(visitor_, OnError(&decoder));
-
-      absl::string_view input(test_data.input);
-      for (auto c : input) {
-        decoder.ProcessInput(&c, 1);
-      }
-      EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-      EXPECT_EQ(test_data.error_message, decoder.error_detail());
-    }
-  }
-}
-
-TEST_F(HttpDecoderTest, EmptySettingsFrame) {
-  std::string input = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "00");  // frame length
-
-  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
-
-  SettingsFrame empty_frame;
-  EXPECT_CALL(visitor_, OnSettingsFrame(empty_frame));
-
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyGoAwayFrame) {
-  std::string input = absl::HexStringToBytes(
-      "07"    // type (GOAWAY)
-      "00");  // frame length
-
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-  EXPECT_EQ("Unable to read GOAWAY ID.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, EmptyMaxPushIdFrame) {
-  std::string input = absl::HexStringToBytes(
-      "0d"    // type (MAX_PUSH_ID)
-      "00");  // frame length
-
-  EXPECT_CALL(visitor_, OnError(&decoder_));
-  EXPECT_EQ(input.size(), ProcessInput(input));
-  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-  EXPECT_EQ("Unable to read MAX_PUSH_ID push_id.", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, LargeStreamIdInGoAway) {
-  GoAwayFrame frame;
-  frame.id = 1ull << 60;
-  std::unique_ptr<char[]> buffer;
-  uint64_t length = HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
-  EXPECT_CALL(visitor_, OnGoAwayFrame(frame));
-  EXPECT_GT(length, 0u);
-  EXPECT_EQ(length, decoder_.ProcessInput(buffer.get(), length));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-// Old PRIORITY_UPDATE frame is parsed as unknown frame.
-TEST_F(HttpDecoderTest, ObsoletePriorityUpdateFrame) {
-  const QuicByteCount header_length = 2;
-  const QuicByteCount payload_length = 3;
-  InSequence s;
-  std::string input = absl::HexStringToBytes(
-      "0f"        // type (obsolete PRIORITY_UPDATE)
-      "03"        // length
-      "666f6f");  // payload "foo"
-
-  // Process frame as a whole.
-  EXPECT_CALL(visitor_,
-              OnUnknownFrameStart(0x0f, header_length, payload_length));
-  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("foo")));
-  EXPECT_CALL(visitor_, OnUnknownFrameEnd()).WillOnce(Return(false));
-
-  EXPECT_EQ(header_length + payload_length,
-            ProcessInputWithGarbageAppended(input));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process frame byte by byte.
-  EXPECT_CALL(visitor_,
-              OnUnknownFrameStart(0x0f, header_length, payload_length));
-  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("f")));
-  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
-  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
-  EXPECT_CALL(visitor_, OnUnknownFrameEnd());
-
-  ProcessInputCharByChar(input);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, PriorityUpdateFrame) {
-  InSequence s;
-  std::string input1 = absl::HexStringToBytes(
-      "800f0700"  // type (PRIORITY_UPDATE)
-      "01"        // length
-      "03");      // prioritized element id
-
-  PriorityUpdateFrame priority_update1;
-  priority_update1.prioritized_element_type = REQUEST_STREAM;
-  priority_update1.prioritized_element_id = 0x03;
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
-  absl::string_view remaining_input(input1);
-  QuicByteCount processed_bytes =
-      ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(5u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1))
-      .WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
-  EXPECT_EQ(input1.size(), ProcessInput(input1));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
-  ProcessInputCharByChar(input1);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  std::string input2 = absl::HexStringToBytes(
-      "800f0700"  // type (PRIORITY_UPDATE)
-      "04"        // length
-      "05"        // prioritized element id
-      "666f6f");  // priority field value: "foo"
-
-  PriorityUpdateFrame priority_update2;
-  priority_update2.prioritized_element_type = REQUEST_STREAM;
-  priority_update2.prioritized_element_id = 0x05;
-  priority_update2.priority_field_value = "foo";
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
-  remaining_input = input2;
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(5u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2))
-      .WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
-  EXPECT_EQ(input2.size(), ProcessInput(input2));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
-  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
-  ProcessInputCharByChar(input2);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) {
-  std::string payload =
-      absl::HexStringToBytes("4005");  // prioritized element id
-  struct {
-    size_t payload_length;
-    const char* const error_message;
-  } kTestData[] = {
-      {0, "Unable to read prioritized element id."},
-      {1, "Unable to read prioritized element id."},
-  };
-
-  for (const auto& test_data : kTestData) {
-    std::string input =
-        absl::HexStringToBytes("800f0700");  // type PRIORITY_UPDATE
-    input.push_back(test_data.payload_length);
-    size_t header_length = input.size();
-    input.append(payload.data(), test_data.payload_length);
-
-    HttpDecoder decoder(&visitor_);
-    EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(header_length));
-    EXPECT_CALL(visitor_, OnError(&decoder));
-
-    QuicByteCount processed_bytes =
-        decoder.ProcessInput(input.data(), input.size());
-    EXPECT_EQ(input.size(), processed_bytes);
-    EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
-    EXPECT_EQ(test_data.error_message, decoder.error_detail());
-  }
-}
-
-TEST_F(HttpDecoderTest, AcceptChFrame) {
-  InSequence s;
-  std::string input1 = absl::HexStringToBytes(
-      "4089"  // type (ACCEPT_CH)
-      "00");  // length
-
-  AcceptChFrame accept_ch1;
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
-  absl::string_view remaining_input(input1);
-  QuicByteCount processed_bytes =
-      ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(3u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1)).WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
-  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
-  EXPECT_EQ(input1.size(), ProcessInput(input1));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
-  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
-  ProcessInputCharByChar(input1);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  std::string input2 = absl::HexStringToBytes(
-      "4089"      // type (ACCEPT_CH)
-      "08"        // length
-      "03"        // length of origin
-      "666f6f"    // origin "foo"
-      "03"        // length of value
-      "626172");  // value "bar"
-
-  AcceptChFrame accept_ch2;
-  accept_ch2.entries.push_back({"foo", "bar"});
-
-  // Visitor pauses processing.
-  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
-  remaining_input = input2;
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(3u, processed_bytes);
-  remaining_input = remaining_input.substr(processed_bytes);
-
-  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2)).WillOnce(Return(false));
-  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
-  EXPECT_EQ(remaining_input.size(), processed_bytes);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the full frame.
-  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
-  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
-  EXPECT_EQ(input2.size(), ProcessInput(input2));
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-
-  // Process the frame incrementally.
-  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
-  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
-  ProcessInputCharByChar(input2);
-  EXPECT_THAT(decoder_.error(), IsQuicNoError());
-  EXPECT_EQ("", decoder_.error_detail());
-}
-
-TEST_F(HttpDecoderTest, WebTransportStreamDisabled) {
-  InSequence s;
-
-  // Unknown frame of type 0x41 and length 0x104.
-  std::string input = absl::HexStringToBytes("40414104");
-  EXPECT_CALL(visitor_, OnUnknownFrameStart(0x41, input.size(), 0x104));
-  EXPECT_EQ(ProcessInput(input), input.size());
-}
-
-TEST(HttpDecoderTestNoFixture, WebTransportStream) {
-  HttpDecoder::Options options;
-  options.allow_web_transport_stream = true;
-  testing::StrictMock<MockHttpDecoderVisitor> visitor;
-  HttpDecoder decoder(&visitor, options);
-
-  // WebTransport stream for session ID 0x104, with four bytes of extra data.
-  std::string input = absl::HexStringToBytes("40414104ffffffff");
-  EXPECT_CALL(visitor, OnWebTransportStreamFrameType(4, 0x104));
-  QuicByteCount bytes = decoder.ProcessInput(input.data(), input.size());
-  EXPECT_EQ(bytes, 4u);
-}
-
-TEST(HttpDecoderTestNoFixture, WebTransportStreamError) {
-  HttpDecoder::Options options;
-  options.allow_web_transport_stream = true;
-  testing::StrictMock<MockHttpDecoderVisitor> visitor;
-  HttpDecoder decoder(&visitor, options);
-
-  std::string input = absl::HexStringToBytes("404100");
-  EXPECT_CALL(visitor, OnWebTransportStreamFrameType(_, _));
-  decoder.ProcessInput(input.data(), input.size());
-
-  EXPECT_CALL(visitor, OnError(_));
-  EXPECT_QUIC_BUG(decoder.ProcessInput(input.data(), input.size()),
-                  "HttpDecoder called after an indefinite-length frame");
-}
-
-TEST_F(HttpDecoderTest, DecodeSettings) {
-  std::string input = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "07"    // length
-      "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
-      "02"    // content
-      "06"    // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
-      "05"    // content
-      "4100"  // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
-      "04");  // content
-
-  SettingsFrame frame;
-  frame.values[1] = 2;
-  frame.values[6] = 5;
-  frame.values[256] = 4;
-
-  SettingsFrame out;
-  EXPECT_TRUE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
-  EXPECT_EQ(frame, out);
-
-  // non-settings frame.
-  input = absl::HexStringToBytes(
-      "0D"    // type (MAX_PUSH_ID)
-      "01"    // length
-      "01");  // Push Id
-
-  EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
-
-  // Corrupt SETTINGS.
-  input = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "01"    // length
-      "42");  // First byte of setting identifier, indicating a 2-byte varint62.
-
-  EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/http_encoder.cc b/quic/core/http/http_encoder.cc
deleted file mode 100644
index 684fdde..0000000
--- a/quic/core/http/http_encoder.cc
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_encoder.h"
-#include <cstdint>
-#include <memory>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-bool WriteFrameHeader(QuicByteCount length,
-                      HttpFrameType type,
-                      QuicDataWriter* writer) {
-  return writer->WriteVarInt62(static_cast<uint64_t>(type)) &&
-         writer->WriteVarInt62(length);
-}
-
-QuicByteCount GetTotalLength(QuicByteCount payload_length, HttpFrameType type) {
-  return QuicDataWriter::GetVarInt62Len(payload_length) +
-         QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(type)) +
-         payload_length;
-}
-
-}  // namespace
-
-// static
-QuicByteCount HttpEncoder::GetDataFrameHeaderLength(
-    QuicByteCount payload_length) {
-  QUICHE_DCHECK_NE(0u, payload_length);
-  return QuicDataWriter::GetVarInt62Len(payload_length) +
-         QuicDataWriter::GetVarInt62Len(
-             static_cast<uint64_t>(HttpFrameType::DATA));
-}
-
-// static
-quiche::QuicheBuffer HttpEncoder::SerializeDataFrameHeader(
-    QuicByteCount payload_length, quiche::QuicheBufferAllocator* allocator) {
-  QUICHE_DCHECK_NE(0u, payload_length);
-  QuicByteCount header_length = GetDataFrameHeaderLength(payload_length);
-
-  quiche::QuicheBuffer header(allocator, header_length);
-  QuicDataWriter writer(header.size(), header.data());
-
-  if (WriteFrameHeader(payload_length, HttpFrameType::DATA, &writer)) {
-    return header;
-  }
-  QUIC_DLOG(ERROR)
-      << "Http encoder failed when attempting to serialize data frame header.";
-  return quiche::QuicheBuffer();
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeHeadersFrameHeader(
-    QuicByteCount payload_length,
-    std::unique_ptr<char[]>* output) {
-  QUICHE_DCHECK_NE(0u, payload_length);
-  QuicByteCount header_length =
-      QuicDataWriter::GetVarInt62Len(payload_length) +
-      QuicDataWriter::GetVarInt62Len(
-          static_cast<uint64_t>(HttpFrameType::HEADERS));
-
-  output->reset(new char[header_length]);
-  QuicDataWriter writer(header_length, output->get());
-
-  if (WriteFrameHeader(payload_length, HttpFrameType::HEADERS, &writer)) {
-    return header_length;
-  }
-  QUIC_DLOG(ERROR)
-      << "Http encoder failed when attempting to serialize headers "
-         "frame header.";
-  return 0;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeSettingsFrame(
-    const SettingsFrame& settings,
-    std::unique_ptr<char[]>* output) {
-  QuicByteCount payload_length = 0;
-  std::vector<std::pair<uint64_t, uint64_t>> ordered_settings{
-      settings.values.begin(), settings.values.end()};
-  std::sort(ordered_settings.begin(), ordered_settings.end());
-  // Calculate the payload length.
-  for (const auto& p : ordered_settings) {
-    payload_length += QuicDataWriter::GetVarInt62Len(p.first);
-    payload_length += QuicDataWriter::GetVarInt62Len(p.second);
-  }
-
-  QuicByteCount total_length =
-      GetTotalLength(payload_length, HttpFrameType::SETTINGS);
-
-  output->reset(new char[total_length]);
-  QuicDataWriter writer(total_length, output->get());
-
-  if (!WriteFrameHeader(payload_length, HttpFrameType::SETTINGS, &writer)) {
-    QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
-                        "settings frame header.";
-    return 0;
-  }
-
-  for (const auto& p : ordered_settings) {
-    if (!writer.WriteVarInt62(p.first) || !writer.WriteVarInt62(p.second)) {
-      QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
-                          "settings frame payload.";
-      return 0;
-    }
-  }
-
-  return total_length;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeGoAwayFrame(
-    const GoAwayFrame& goaway,
-    std::unique_ptr<char[]>* output) {
-  QuicByteCount payload_length = QuicDataWriter::GetVarInt62Len(goaway.id);
-  QuicByteCount total_length =
-      GetTotalLength(payload_length, HttpFrameType::GOAWAY);
-
-  output->reset(new char[total_length]);
-  QuicDataWriter writer(total_length, output->get());
-
-  if (WriteFrameHeader(payload_length, HttpFrameType::GOAWAY, &writer) &&
-      writer.WriteVarInt62(goaway.id)) {
-    return total_length;
-  }
-  QUIC_DLOG(ERROR)
-      << "Http encoder failed when attempting to serialize goaway frame.";
-  return 0;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializePriorityUpdateFrame(
-    const PriorityUpdateFrame& priority_update,
-    std::unique_ptr<char[]>* output) {
-  if (priority_update.prioritized_element_type != REQUEST_STREAM) {
-    QUIC_BUG(quic_bug_10402_1)
-        << "PRIORITY_UPDATE for push streams not implemented";
-    return 0;
-  }
-
-  QuicByteCount payload_length =
-      QuicDataWriter::GetVarInt62Len(priority_update.prioritized_element_id) +
-      priority_update.priority_field_value.size();
-  QuicByteCount total_length = GetTotalLength(
-      payload_length, HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
-
-  output->reset(new char[total_length]);
-  QuicDataWriter writer(total_length, output->get());
-
-  if (WriteFrameHeader(payload_length,
-                       HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM,
-                       &writer) &&
-      writer.WriteVarInt62(priority_update.prioritized_element_id) &&
-      writer.WriteBytes(priority_update.priority_field_value.data(),
-                        priority_update.priority_field_value.size())) {
-    return total_length;
-  }
-
-  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
-                      "PRIORITY_UPDATE frame.";
-  return 0;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeAcceptChFrame(
-    const AcceptChFrame& accept_ch,
-    std::unique_ptr<char[]>* output) {
-  QuicByteCount payload_length = 0;
-  for (const auto& entry : accept_ch.entries) {
-    payload_length += QuicDataWriter::GetVarInt62Len(entry.origin.size());
-    payload_length += entry.origin.size();
-    payload_length += QuicDataWriter::GetVarInt62Len(entry.value.size());
-    payload_length += entry.value.size();
-  }
-
-  QuicByteCount total_length =
-      GetTotalLength(payload_length, HttpFrameType::ACCEPT_CH);
-
-  output->reset(new char[total_length]);
-  QuicDataWriter writer(total_length, output->get());
-
-  if (!WriteFrameHeader(payload_length, HttpFrameType::ACCEPT_CH, &writer)) {
-    QUIC_DLOG(ERROR)
-        << "Http encoder failed to serialize ACCEPT_CH frame header.";
-    return 0;
-  }
-
-  for (const auto& entry : accept_ch.entries) {
-    if (!writer.WriteStringPieceVarInt62(entry.origin) ||
-        !writer.WriteStringPieceVarInt62(entry.value)) {
-      QUIC_DLOG(ERROR)
-          << "Http encoder failed to serialize ACCEPT_CH frame payload.";
-      return 0;
-    }
-  }
-
-  return total_length;
-}
-
-// static
-QuicByteCount HttpEncoder::SerializeGreasingFrame(
-    std::unique_ptr<char[]>* output) {
-  uint64_t frame_type;
-  QuicByteCount payload_length;
-  std::string payload;
-  if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
-    frame_type = 0x40;
-    payload_length = 1;
-    payload = "a";
-  } else {
-    uint32_t result;
-    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
-    frame_type = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
-
-    // The payload length is random but within [0, 3];
-    payload_length = result % 4;
-
-    if (payload_length > 0) {
-      std::unique_ptr<char[]> buffer(new char[payload_length]);
-      QuicRandom::GetInstance()->RandBytes(buffer.get(), payload_length);
-      payload = std::string(buffer.get(), payload_length);
-    }
-  }
-  QuicByteCount total_length = QuicDataWriter::GetVarInt62Len(frame_type) +
-                               QuicDataWriter::GetVarInt62Len(payload_length) +
-                               payload_length;
-
-  output->reset(new char[total_length]);
-  QuicDataWriter writer(total_length, output->get());
-
-  bool success =
-      writer.WriteVarInt62(frame_type) && writer.WriteVarInt62(payload_length);
-
-  if (payload_length > 0) {
-    success &= writer.WriteBytes(payload.data(), payload_length);
-  }
-
-  if (success) {
-    return total_length;
-  }
-
-  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
-                      "greasing frame.";
-  return 0;
-}
-
-QuicByteCount HttpEncoder::SerializeWebTransportStreamFrameHeader(
-    WebTransportSessionId session_id,
-    std::unique_ptr<char[]>* output) {
-  uint64_t stream_type =
-      static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM);
-  QuicByteCount header_length = QuicDataWriter::GetVarInt62Len(stream_type) +
-                                QuicDataWriter::GetVarInt62Len(session_id);
-
-  *output = std::make_unique<char[]>(header_length);
-  QuicDataWriter writer(header_length, output->get());
-  bool success =
-      writer.WriteVarInt62(stream_type) && writer.WriteVarInt62(session_id);
-  if (success && writer.remaining() == 0) {
-    return header_length;
-  }
-
-  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
-                      "WEBTRANSPORT_STREAM frame header.";
-  return 0;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/http_encoder.h b/quic/core/http/http_encoder.h
deleted file mode 100644
index 97f4b3d..0000000
--- a/quic/core/http/http_encoder.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
-
-#include <memory>
-
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quic {
-
-class QuicDataWriter;
-
-// A class for encoding the HTTP frames that are exchanged in an HTTP over QUIC
-// session.
-class QUIC_EXPORT_PRIVATE HttpEncoder {
- public:
-  HttpEncoder() = delete;
-
-  // Returns the length of the header for a DATA frame.
-  static QuicByteCount GetDataFrameHeaderLength(QuicByteCount payload_length);
-
-  // Serializes a DATA frame header into a QuicheBuffer; returns said
-  // QuicheBuffer on success, empty buffer otherwise.
-  static quiche::QuicheBuffer SerializeDataFrameHeader(
-      QuicByteCount payload_length, quiche::QuicheBufferAllocator* allocator);
-
-  // Serializes a HEADERS frame header into a new buffer stored in |output|.
-  // Returns the length of the buffer on success, or 0 otherwise.
-  static QuicByteCount SerializeHeadersFrameHeader(
-      QuicByteCount payload_length,
-      std::unique_ptr<char[]>* output);
-
-  // Serializes a SETTINGS frame into a new buffer stored in |output|.
-  // Returns the length of the buffer on success, or 0 otherwise.
-  static QuicByteCount SerializeSettingsFrame(const SettingsFrame& settings,
-                                              std::unique_ptr<char[]>* output);
-
-  // Serializes a GOAWAY frame into a new buffer stored in |output|.
-  // Returns the length of the buffer on success, or 0 otherwise.
-  static QuicByteCount SerializeGoAwayFrame(const GoAwayFrame& goaway,
-                                            std::unique_ptr<char[]>* output);
-
-  // Serializes a PRIORITY_UPDATE frame into a new buffer stored in |output|.
-  // Returns the length of the buffer on success, or 0 otherwise.
-  static QuicByteCount SerializePriorityUpdateFrame(
-      const PriorityUpdateFrame& priority_update,
-      std::unique_ptr<char[]>* output);
-
-  // Serializes an ACCEPT_CH frame into a new buffer stored in |output|.
-  // Returns the length of the buffer on success, or 0 otherwise.
-  static QuicByteCount SerializeAcceptChFrame(const AcceptChFrame& accept_ch,
-                                              std::unique_ptr<char[]>* output);
-
-  // Serializes a frame with reserved frame type specified in
-  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9.
-  static QuicByteCount SerializeGreasingFrame(std::unique_ptr<char[]>* output);
-
-  // Serializes a WEBTRANSPORT_STREAM frame header as specified in
-  // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html#name-client-initiated-bidirectio
-  static QuicByteCount SerializeWebTransportStreamFrameHeader(
-      WebTransportSessionId session_id,
-      std::unique_ptr<char[]>* output);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
diff --git a/quic/core/http/http_encoder_test.cc b/quic/core/http/http_encoder_test.cc
deleted file mode 100644
index aab63a1..0000000
--- a/quic/core/http/http_encoder_test.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_encoder.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/simple_buffer_allocator.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-TEST(HttpEncoderTest, SerializeDataFrameHeader) {
-  quiche::QuicheBuffer buffer = HttpEncoder::SerializeDataFrameHeader(
-      /* payload_length = */ 5, quiche::SimpleBufferAllocator::Get());
-  char output[] = {// type (DATA)
-                   0x00,
-                   // length
-                   0x05};
-  EXPECT_EQ(ABSL_ARRAYSIZE(output), buffer.size());
-  quiche::test::CompareCharArraysWithHexError(
-      "DATA", buffer.data(), buffer.size(), output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializeHeadersFrameHeader) {
-  std::unique_ptr<char[]> buffer;
-  uint64_t length = HttpEncoder::SerializeHeadersFrameHeader(
-      /* payload_length = */ 7, &buffer);
-  char output[] = {// type (HEADERS)
-                   0x01,
-                   // length
-                   0x07};
-  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
-  quiche::test::CompareCharArraysWithHexError("HEADERS", buffer.get(), length,
-                                              output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializeSettingsFrame) {
-  SettingsFrame settings;
-  settings.values[1] = 2;
-  settings.values[6] = 5;
-  settings.values[256] = 4;
-  char output[] = {// type (SETTINGS)
-                   0x04,
-                   // length
-                   0x07,
-                   // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
-                   0x01,
-                   // content
-                   0x02,
-                   // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
-                   0x06,
-                   // content
-                   0x05,
-                   // identifier (256 in variable length integer)
-                   0x40 + 0x01, 0x00,
-                   // content
-                   0x04};
-  std::unique_ptr<char[]> buffer;
-  uint64_t length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
-  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
-  quiche::test::CompareCharArraysWithHexError("SETTINGS", buffer.get(), length,
-                                              output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializeGoAwayFrame) {
-  GoAwayFrame goaway;
-  goaway.id = 0x1;
-  char output[] = {// type (GOAWAY)
-                   0x07,
-                   // length
-                   0x1,
-                   // ID
-                   0x01};
-  std::unique_ptr<char[]> buffer;
-  uint64_t length = HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
-  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
-  quiche::test::CompareCharArraysWithHexError("GOAWAY", buffer.get(), length,
-                                              output, ABSL_ARRAYSIZE(output));
-}
-
-TEST(HttpEncoderTest, SerializePriorityUpdateFrame) {
-  PriorityUpdateFrame priority_update1;
-  priority_update1.prioritized_element_type = REQUEST_STREAM;
-  priority_update1.prioritized_element_id = 0x03;
-  uint8_t output1[] = {0x80, 0x0f, 0x07, 0x00,  // type (PRIORITY_UPDATE)
-                       0x01,                    // length
-                       0x03};                   // prioritized element id
-
-  std::unique_ptr<char[]> buffer;
-  uint64_t length =
-      HttpEncoder::SerializePriorityUpdateFrame(priority_update1, &buffer);
-  EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
-  quiche::test::CompareCharArraysWithHexError(
-      "PRIORITY_UPDATE", buffer.get(), length, reinterpret_cast<char*>(output1),
-      ABSL_ARRAYSIZE(output1));
-}
-
-TEST(HttpEncoderTest, SerializeAcceptChFrame) {
-  AcceptChFrame accept_ch;
-  uint8_t output1[] = {0x40, 0x89,  // type (ACCEPT_CH)
-                       0x00};       // length
-
-  std::unique_ptr<char[]> buffer;
-  uint64_t length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
-  EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
-  quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
-                                              reinterpret_cast<char*>(output1),
-                                              ABSL_ARRAYSIZE(output1));
-
-  accept_ch.entries.push_back({"foo", "bar"});
-  uint8_t output2[] = {0x40, 0x89,               // type (ACCEPT_CH)
-                       0x08,                     // payload length
-                       0x03, 0x66, 0x6f, 0x6f,   // length of "foo"; "foo"
-                       0x03, 0x62, 0x61, 0x72};  // length of "bar"; "bar"
-
-  length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
-  EXPECT_EQ(ABSL_ARRAYSIZE(output2), length);
-  quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
-                                              reinterpret_cast<char*>(output2),
-                                              ABSL_ARRAYSIZE(output2));
-}
-
-TEST(HttpEncoderTest, SerializeWebTransportStreamFrameHeader) {
-  WebTransportSessionId session_id = 0x17;
-  char output[] = {0x40, 0x41,  // type (WEBTRANSPORT_STREAM)
-                   0x17};       // session ID
-
-  std::unique_ptr<char[]> buffer;
-  uint64_t length =
-      HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &buffer);
-  EXPECT_EQ(sizeof(output), length);
-  quiche::test::CompareCharArraysWithHexError(
-      "WEBTRANSPORT_STREAM", buffer.get(), length, output, sizeof(output));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/http_frames.h b/quic/core/http/http_frames.h
deleted file mode 100644
index 6a00ad7..0000000
--- a/quic/core/http/http_frames.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
-#define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
-
-#include <algorithm>
-#include <cstdint>
-#include <map>
-#include <ostream>
-#include <sstream>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/quic_types.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-// TODO(b/171463363): Remove.
-using PushId = uint64_t;
-
-enum class HttpFrameType {
-  DATA = 0x0,
-  HEADERS = 0x1,
-  CANCEL_PUSH = 0X3,
-  SETTINGS = 0x4,
-  PUSH_PROMISE = 0x5,
-  GOAWAY = 0x7,
-  MAX_PUSH_ID = 0xD,
-  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
-  ACCEPT_CH = 0x89,
-  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-03
-  PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700,
-  // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html
-  WEBTRANSPORT_STREAM = 0x41,
-};
-
-// 7.2.1.  DATA
-//
-//   DATA frames (type=0x0) convey arbitrary, variable-length sequences of
-//   octets associated with an HTTP request or response payload.
-struct QUIC_EXPORT_PRIVATE DataFrame {
-  absl::string_view data;
-};
-
-// 7.2.2.  HEADERS
-//
-//   The HEADERS frame (type=0x1) is used to carry a header block,
-//   compressed using QPACK.
-struct QUIC_EXPORT_PRIVATE HeadersFrame {
-  absl::string_view headers;
-};
-
-// 7.2.4.  SETTINGS
-//
-//   The SETTINGS frame (type=0x4) conveys configuration parameters that
-//   affect how endpoints communicate, such as preferences and constraints
-//   on peer behavior
-
-using SettingsMap = absl::flat_hash_map<uint64_t, uint64_t>;
-
-struct QUIC_EXPORT_PRIVATE SettingsFrame {
-  SettingsMap values;
-
-  bool operator==(const SettingsFrame& rhs) const {
-    return values == rhs.values;
-  }
-
-  std::string ToString() const {
-    std::string s;
-    for (auto it : values) {
-      std::string setting = absl::StrCat(
-          H3SettingsToString(
-              static_cast<Http3AndQpackSettingsIdentifiers>(it.first)),
-          " = ", it.second, "; ");
-      absl::StrAppend(&s, setting);
-    }
-    return s;
-  }
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                      const SettingsFrame& s) {
-    os << s.ToString();
-    return os;
-  }
-};
-
-// 7.2.6.  GOAWAY
-//
-//   The GOAWAY frame (type=0x7) is used to initiate shutdown of a connection by
-//   either endpoint.
-struct QUIC_EXPORT_PRIVATE GoAwayFrame {
-  // When sent from server to client, |id| is a stream ID that should refer to
-  // a client-initiated bidirectional stream.
-  // When sent from client to server, |id| is a push ID.
-  uint64_t id;
-
-  bool operator==(const GoAwayFrame& rhs) const { return id == rhs.id; }
-};
-
-// 7.2.7.  MAX_PUSH_ID
-//
-//   The MAX_PUSH_ID frame (type=0xD) is used by clients to control the
-//   number of server pushes that the server can initiate.
-struct QUIC_EXPORT_PRIVATE MaxPushIdFrame {
-  PushId push_id;
-
-  bool operator==(const MaxPushIdFrame& rhs) const {
-    return push_id == rhs.push_id;
-  }
-};
-
-// https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html
-//
-// The PRIORITY_UPDATE frame specifies the sender-advised priority of a stream.
-// Frame type 0xf0700 (called PRIORITY_UPDATE_REQUEST_STREAM in the
-// implementation) is used for for request streams.
-// Frame type 0xf0701 is used for push streams and is not implemented.
-
-// Length of a priority frame's first byte.
-const QuicByteCount kPriorityFirstByteLength = 1;
-
-enum PrioritizedElementType : uint8_t {
-  REQUEST_STREAM = 0x00,
-  PUSH_STREAM = 0x80,
-};
-
-struct QUIC_EXPORT_PRIVATE PriorityUpdateFrame {
-  PrioritizedElementType prioritized_element_type = REQUEST_STREAM;
-  uint64_t prioritized_element_id = 0;
-  std::string priority_field_value;
-
-  bool operator==(const PriorityUpdateFrame& rhs) const {
-    return std::tie(prioritized_element_type, prioritized_element_id,
-                    priority_field_value) ==
-           std::tie(rhs.prioritized_element_type, rhs.prioritized_element_id,
-                    rhs.priority_field_value);
-  }
-  std::string ToString() const {
-    return absl::StrCat("Priority Frame : {prioritized_element_type: ",
-                        static_cast<int>(prioritized_element_type),
-                        ", prioritized_element_id: ", prioritized_element_id,
-                        ", priority_field_value: ", priority_field_value, "}");
-  }
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const PriorityUpdateFrame& s) {
-    os << s.ToString();
-    return os;
-  }
-};
-
-// ACCEPT_CH
-// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
-//
-struct QUIC_EXPORT_PRIVATE AcceptChFrame {
-  std::vector<spdy::AcceptChOriginValuePair> entries;
-
-  bool operator==(const AcceptChFrame& rhs) const {
-    return entries.size() == rhs.entries.size() &&
-           std::equal(entries.begin(), entries.end(), rhs.entries.begin());
-  }
-
-  std::string ToString() const {
-    std::stringstream s;
-    s << *this;
-    return s.str();
-  }
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const AcceptChFrame& frame) {
-    os << "ACCEPT_CH frame with " << frame.entries.size() << " entries: ";
-    for (auto& entry : frame.entries) {
-      os << "origin: " << entry.origin << "; value: " << entry.value;
-    }
-    return os;
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
diff --git a/quic/core/http/http_frames_test.cc b/quic/core/http/http_frames_test.cc
deleted file mode 100644
index 24fd578..0000000
--- a/quic/core/http/http_frames_test.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/http_frames.h"
-
-#include <sstream>
-
-#include "quic/core/http/http_constants.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-TEST(HttpFramesTest, SettingsFrame) {
-  SettingsFrame a;
-  EXPECT_TRUE(a == a);
-  EXPECT_EQ("", a.ToString());
-
-  SettingsFrame b;
-  b.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
-  EXPECT_FALSE(a == b);
-  EXPECT_TRUE(b == b);
-
-  a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-  EXPECT_FALSE(a == b);
-  a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
-  EXPECT_TRUE(a == b);
-
-  EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", b.ToString());
-  std::stringstream s;
-  s << b;
-  EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", s.str());
-}
-
-TEST(HttpFramesTest, GoAwayFrame) {
-  GoAwayFrame a{1};
-  EXPECT_TRUE(a == a);
-
-  GoAwayFrame b{2};
-  EXPECT_FALSE(a == b);
-
-  b.id = 1;
-  EXPECT_TRUE(a == b);
-}
-
-TEST(HttpFramesTest, MaxPushIdFrame) {
-  MaxPushIdFrame a{1};
-  EXPECT_TRUE(a == a);
-
-  MaxPushIdFrame b{2};
-  EXPECT_FALSE(a == b);
-
-  b.push_id = 1;
-  EXPECT_TRUE(a == b);
-}
-
-TEST(HttpFramesTest, PriorityUpdateFrame) {
-  PriorityUpdateFrame a{REQUEST_STREAM, 0, ""};
-  EXPECT_TRUE(a == a);
-  PriorityUpdateFrame b{REQUEST_STREAM, 4, ""};
-  EXPECT_FALSE(a == b);
-  a.prioritized_element_id = 4;
-  EXPECT_TRUE(a == b);
-
-  a.prioritized_element_type = PUSH_STREAM;
-  EXPECT_FALSE(a == b);
-  b.prioritized_element_type = PUSH_STREAM;
-  EXPECT_TRUE(a == b);
-
-  a.priority_field_value = "foo";
-  EXPECT_FALSE(a == b);
-
-  EXPECT_EQ(
-      "Priority Frame : {prioritized_element_type: 128, "
-      "prioritized_element_id: 4, priority_field_value: foo}",
-      a.ToString());
-  std::stringstream s;
-  s << a;
-  EXPECT_EQ(
-      "Priority Frame : {prioritized_element_type: 128, "
-      "prioritized_element_id: 4, priority_field_value: foo}",
-      s.str());
-}
-
-TEST(HttpFramesTest, AcceptChFrame) {
-  AcceptChFrame a;
-  EXPECT_TRUE(a == a);
-  EXPECT_EQ("ACCEPT_CH frame with 0 entries: ", a.ToString());
-
-  AcceptChFrame b{{{"foo", "bar"}}};
-  EXPECT_FALSE(a == b);
-
-  a.entries.push_back({"foo", "bar"});
-  EXPECT_TRUE(a == b);
-
-  EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar",
-            a.ToString());
-  std::stringstream s;
-  s << a;
-  EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar", s.str());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_client_promised_info.cc b/quic/core/http/quic_client_promised_info.cc
deleted file mode 100644
index 1c951ba..0000000
--- a/quic/core/http/quic_client_promised_info.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_promised_info.h"
-
-#include <string>
-#include <utility>
-
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicClientPromisedInfo::QuicClientPromisedInfo(
-    QuicSpdyClientSessionBase* session,
-    QuicStreamId id,
-    std::string url)
-    : session_(session),
-      id_(id),
-      url_(std::move(url)),
-      client_request_delegate_(nullptr) {}
-
-QuicClientPromisedInfo::~QuicClientPromisedInfo() {
-  if (cleanup_alarm_ != nullptr) {
-    cleanup_alarm_->PermanentCancel();
-  }
-}
-
-void QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
-  QUIC_DVLOG(1) << "self GC alarm for stream " << promised_->id_;
-  promised_->session()->OnPushStreamTimedOut(promised_->id_);
-  promised_->Reset(QUIC_PUSH_STREAM_TIMED_OUT);
-}
-
-void QuicClientPromisedInfo::Init() {
-  cleanup_alarm_.reset(session_->connection()->alarm_factory()->CreateAlarm(
-      new QuicClientPromisedInfo::CleanupAlarm(this)));
-  cleanup_alarm_->Set(
-      session_->connection()->helper()->GetClock()->ApproximateNow() +
-      QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs));
-}
-
-bool QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
-  // RFC7540, Section 8.2, requests MUST be safe [RFC7231], Section
-  // 4.2.1.  GET and HEAD are the methods that are safe and required.
-  SpdyHeaderBlock::const_iterator it = headers.find(spdy::kHttp2MethodHeader);
-  if (it == headers.end()) {
-    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has no method";
-    Reset(QUIC_INVALID_PROMISE_METHOD);
-    return false;
-  }
-  if (!(it->second == "GET" || it->second == "HEAD")) {
-    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid method "
-                  << it->second;
-    Reset(QUIC_INVALID_PROMISE_METHOD);
-    return false;
-  }
-  if (!SpdyServerPushUtils::PromisedUrlIsValid(headers)) {
-    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid URL "
-                  << url_;
-    Reset(QUIC_INVALID_PROMISE_URL);
-    return false;
-  }
-  if (!session_->IsAuthorized(
-          SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers))) {
-    Reset(QUIC_UNAUTHORIZED_PROMISE_URL);
-    return false;
-  }
-  request_headers_ = headers.Clone();
-  return true;
-}
-
-void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) {
-  response_headers_ = std::make_unique<SpdyHeaderBlock>(headers.Clone());
-  if (client_request_delegate_) {
-    // We already have a client request waiting.
-    FinalValidation();
-  }
-}
-
-void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) {
-  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
-  session_->ResetPromised(id_, error_code);
-  session_->DeletePromised(this);
-  if (delegate) {
-    delegate->OnRendezvousResult(nullptr);
-  }
-}
-
-QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() {
-  if (!client_request_delegate_->CheckVary(
-          client_request_headers_, request_headers_, *response_headers_)) {
-    Reset(QUIC_PROMISE_VARY_MISMATCH);
-    return QUIC_FAILURE;
-  }
-  QuicSpdyStream* stream = session_->GetPromisedStream(id_);
-  if (!stream) {
-    // This shouldn't be possible, as |ClientRequest| guards against
-    // closed stream for the synchronous case.  And in the
-    // asynchronous case, a RST can only be caught by |OnAlarm()|.
-    QUIC_BUG(quic_bug_10378_1) << "missing promised stream" << id_;
-  }
-  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
-  session_->DeletePromised(this);
-  // Stream can start draining now
-  if (delegate) {
-    delegate->OnRendezvousResult(stream);
-  }
-  return QUIC_SUCCESS;
-}
-
-QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest(
-    const SpdyHeaderBlock& request_headers,
-    QuicClientPushPromiseIndex::Delegate* delegate) {
-  if (session_->IsClosedStream(id_)) {
-    // There was a RST on the response stream.
-    session_->DeletePromised(this);
-    return QUIC_FAILURE;
-  }
-
-  if (is_validating()) {
-    // The push promise has already been matched to another request though
-    // pending for validation. Returns QUIC_FAILURE to the caller as it couldn't
-    // match a new request any more. This will not affect the validation of the
-    // other request.
-    return QUIC_FAILURE;
-  }
-
-  client_request_delegate_ = delegate;
-  client_request_headers_ = request_headers.Clone();
-  if (response_headers_ == nullptr) {
-    return QUIC_PENDING;
-  }
-  return FinalValidation();
-}
-
-void QuicClientPromisedInfo::Cancel() {
-  // Don't fire OnRendezvousResult() for client initiated cancel.
-  client_request_delegate_ = nullptr;
-  Reset(QUIC_STREAM_CANCELLED);
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_client_promised_info.h b/quic/core/http/quic_client_promised_info.h
deleted file mode 100644
index ec071f0..0000000
--- a/quic/core/http/quic_client_promised_info.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
-
-#include <cstddef>
-#include <string>
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session_base.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-namespace test {
-class QuicClientPromisedInfoPeer;
-}  // namespace test
-
-// QuicClientPromisedInfo tracks the client state of a server push
-// stream from the time a PUSH_PROMISE is received until rendezvous
-// between the promised response and the corresponding client request
-// is complete.
-class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
-    : public QuicClientPushPromiseIndex::TryHandle {
- public:
-  // Interface to QuicSpdyClientStream
-  QuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
-                         QuicStreamId id,
-                         std::string url);
-  QuicClientPromisedInfo(const QuicClientPromisedInfo&) = delete;
-  QuicClientPromisedInfo& operator=(const QuicClientPromisedInfo&) = delete;
-  virtual ~QuicClientPromisedInfo();
-
-  void Init();
-
-  // Validate promise headers etc. Returns true if headers are valid.
-  bool OnPromiseHeaders(const spdy::SpdyHeaderBlock& headers);
-
-  // Store response, possibly proceed with final validation.
-  void OnResponseHeaders(const spdy::SpdyHeaderBlock& headers);
-
-  // Rendezvous between this promised stream and a client request that
-  // has a matching URL.
-  virtual QuicAsyncStatus HandleClientRequest(
-      const spdy::SpdyHeaderBlock& headers,
-      QuicClientPushPromiseIndex::Delegate* delegate);
-
-  void Cancel() override;
-
-  void Reset(QuicRstStreamErrorCode error_code);
-
-  // Client requests are initially associated to promises by matching
-  // URL in the client request against the URL in the promise headers,
-  // uing the |promised_by_url| map.  The push can be cross-origin, so
-  // the client should validate that the session is authoritative for
-  // the promised URL.  If not, it should call |RejectUnauthorized|.
-  QuicSpdyClientSessionBase* session() { return session_; }
-
-  // If the promised response contains Vary header, then the fields
-  // specified by Vary must match between the client request header
-  // and the promise headers (see https://crbug.com//554220).  Vary
-  // validation requires the response headers (for the actual Vary
-  // field list), the promise headers (taking the role of the "cached"
-  // request), and the client request headers.
-  spdy::SpdyHeaderBlock* request_headers() { return &request_headers_; }
-
-  spdy::SpdyHeaderBlock* response_headers() { return response_headers_.get(); }
-
-  // After validation, client will use this to access the pushed stream.
-
-  QuicStreamId id() const { return id_; }
-
-  const std::string url() const { return url_; }
-
-  // Return true if there's a request pending matching this push promise.
-  bool is_validating() const { return client_request_delegate_ != nullptr; }
-
- private:
-  friend class test::QuicClientPromisedInfoPeer;
-
-  class QUIC_EXPORT_PRIVATE CleanupAlarm
-      : public QuicAlarm::DelegateWithoutContext {
-   public:
-    explicit CleanupAlarm(QuicClientPromisedInfo* promised)
-        : promised_(promised) {}
-
-    void OnAlarm() override;
-
-    QuicClientPromisedInfo* promised_;
-  };
-
-  QuicAsyncStatus FinalValidation();
-
-  QuicSpdyClientSessionBase* session_;
-  QuicStreamId id_;
-  std::string url_;
-  spdy::SpdyHeaderBlock request_headers_;
-  std::unique_ptr<spdy::SpdyHeaderBlock> response_headers_;
-  spdy::SpdyHeaderBlock client_request_headers_;
-  QuicClientPushPromiseIndex::Delegate* client_request_delegate_;
-
-  // The promise will commit suicide eventually if it is not claimed by a GET
-  // first.
-  std::unique_ptr<QuicAlarm> cleanup_alarm_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/quic/core/http/quic_client_promised_info_test.cc b/quic/core/http/quic_client_promised_info_test.cc
deleted file mode 100644
index 2f2b2a4..0000000
--- a/quic/core/http/quic_client_promised_info_test.cc
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_promised_info.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_client_promised_info_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::SpdyHeaderBlock;
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
-  explicit MockQuicSpdyClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      QuicClientPushPromiseIndex* push_promise_index)
-      : QuicSpdyClientSession(DefaultQuicConfig(),
-                              supported_versions,
-                              connection,
-                              QuicServerId("example.com", 443, false),
-                              &crypto_config_,
-                              push_promise_index),
-        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
-        authorized_(true) {}
-  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
-  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
-      delete;
-  ~MockQuicSpdyClientSession() override {}
-
-  bool IsAuthorized(const std::string& /*authority*/) override {
-    return authorized_;
-  }
-
-  void set_authorized(bool authorized) { authorized_ = authorized; }
-
-  MOCK_METHOD(bool,
-              WriteControlFrame,
-              (const QuicFrame& frame, TransmissionType type),
-              (override));
-
- private:
-  QuicCryptoClientConfig crypto_config_;
-
-  bool authorized_;
-};
-
-class QuicClientPromisedInfoTest : public QuicTest {
- public:
-  class StreamVisitor;
-
-  QuicClientPromisedInfoTest()
-      : connection_(new StrictMock<MockQuicConnection>(&helper_,
-                                                       &alarm_factory_,
-                                                       Perspective::IS_CLIENT)),
-        session_(connection_->supported_versions(),
-                 connection_,
-                 &push_promise_index_),
-        body_("hello world"),
-        promise_id_(
-            QuicUtils::GetInvalidStreamId(connection_->transport_version())) {
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    session_.Initialize();
-
-    headers_[":status"] = "200";
-    headers_["content-length"] = "11";
-
-    stream_ = std::make_unique<QuicSpdyClientStream>(
-        GetNthClientInitiatedBidirectionalStreamId(
-            connection_->transport_version(), 0),
-        &session_, BIDIRECTIONAL);
-    stream_visitor_ = std::make_unique<StreamVisitor>();
-    stream_->set_visitor(stream_visitor_.get());
-
-    push_promise_[":path"] = "/bar";
-    push_promise_[":authority"] = "www.google.com";
-    push_promise_[":method"] = "GET";
-    push_promise_[":scheme"] = "https";
-
-    promise_url_ =
-        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
-
-    client_request_ = push_promise_.Clone();
-    promise_id_ = GetNthServerInitiatedUnidirectionalStreamId(
-        connection_->transport_version(), 0);
-  }
-
-  class StreamVisitor : public QuicSpdyClientStream::Visitor {
-    void OnClose(QuicSpdyStream* stream) override {
-      QUIC_DVLOG(1) << "stream " << stream->id();
-    }
-  };
-
-  void ReceivePromise(QuicStreamId id) {
-    auto headers = AsHeaderList(push_promise_);
-    stream_->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
-                                 headers);
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  QuicClientPushPromiseIndex push_promise_index_;
-
-  MockQuicSpdyClientSession session_;
-  std::unique_ptr<QuicSpdyClientStream> stream_;
-  std::unique_ptr<StreamVisitor> stream_visitor_;
-  std::unique_ptr<QuicSpdyClientStream> promised_stream_;
-  SpdyHeaderBlock headers_;
-  std::string body_;
-  SpdyHeaderBlock push_promise_;
-  QuicStreamId promise_id_;
-  std::string promise_url_;
-  SpdyHeaderBlock client_request_;
-};
-
-TEST_F(QuicClientPromisedInfoTest, PushPromise) {
-  ReceivePromise(promise_id_);
-
-  // Verify that the promise is in the unclaimed streams map.
-  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) {
-  ReceivePromise(promise_id_);
-
-  // Verify that the promise is in the unclaimed streams map.
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  ASSERT_NE(promised, nullptr);
-
-  // Fire the alarm that will cancel the promised stream.
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
-  alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
-
-  // Verify that the promise is gone after the alarm fires.
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) {
-  // Promise with an unsafe method
-  push_promise_[":method"] = "PUT";
-
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
-  ReceivePromise(promise_id_);
-
-  // Verify that the promise headers were ignored
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) {
-  // Promise with a missing method
-  push_promise_.erase(":method");
-
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
-  ReceivePromise(promise_id_);
-
-  // Verify that the promise headers were ignored
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
-  // Remove required header field to make URL invalid
-  push_promise_.erase(":authority");
-
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
-  ReceivePromise(promise_id_);
-
-  // Verify that the promise headers were ignored
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
-  session_.set_authorized(false);
-
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
-
-  ReceivePromise(promise_id_);
-
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  ASSERT_EQ(promised, nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
-  ReceivePromise(promise_id_);
-
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  ASSERT_NE(promised, nullptr);
-
-  // Need to send the promised response headers and initiate the
-  // rendezvous for secondary validation to proceed.
-  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
-      session_.GetOrCreateStream(promise_id_));
-  auto headers = AsHeaderList(headers_);
-  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                                     headers);
-
-  TestPushPromiseDelegate delegate(/*match=*/false);
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
-
-  promised->HandleClientRequest(client_request_, &delegate);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryWaits) {
-  ReceivePromise(promise_id_);
-
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  EXPECT_FALSE(promised->is_validating());
-  ASSERT_NE(promised, nullptr);
-
-  // Now initiate rendezvous.
-  TestPushPromiseDelegate delegate(/*match=*/true);
-  promised->HandleClientRequest(client_request_, &delegate);
-  EXPECT_TRUE(promised->is_validating());
-
-  // Promise is still there, waiting for response.
-  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
-
-  // Send Response, should trigger promise validation and complete rendezvous
-  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
-      session_.GetOrCreateStream(promise_id_));
-  ASSERT_NE(promise_stream, nullptr);
-  auto headers = AsHeaderList(headers_);
-  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                                     headers);
-
-  // Promise is gone
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryNoWait) {
-  ReceivePromise(promise_id_);
-
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  ASSERT_NE(promised, nullptr);
-
-  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
-      session_.GetOrCreateStream(promise_id_));
-  ASSERT_NE(promise_stream, nullptr);
-
-  // Send Response, should trigger promise validation and complete rendezvous
-  auto headers = AsHeaderList(headers_);
-  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                                     headers);
-
-  // Now initiate rendezvous.
-  TestPushPromiseDelegate delegate(/*match=*/true);
-  promised->HandleClientRequest(client_request_, &delegate);
-
-  // Promise is gone
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-  // Have a push stream
-  EXPECT_TRUE(delegate.rendezvous_fired());
-
-  EXPECT_NE(delegate.rendezvous_stream(), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
-  ReceivePromise(promise_id_);
-
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  ASSERT_NE(promised, nullptr);
-
-  // Now initiate rendezvous.
-  TestPushPromiseDelegate delegate(/*match=*/true);
-  promised->HandleClientRequest(client_request_, &delegate);
-
-  // Promise is still there, waiting for response.
-  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
-
-  // Create response stream, but no data yet.
-  session_.GetOrCreateStream(promise_id_);
-
-  // Cancel the promised stream.
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
-  promised->Cancel();
-
-  // Promise is gone
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
-  ReceivePromise(promise_id_);
-
-  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
-  ASSERT_NE(promised, nullptr);
-
-  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
-      session_.GetOrCreateStream(promise_id_));
-  ASSERT_NE(promise_stream, nullptr);
-
-  // Send response, rendezvous will be able to finish synchronously.
-  auto headers = AsHeaderList(headers_);
-  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                                     headers);
-
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
-  session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY);
-
-  // Now initiate rendezvous.
-  TestPushPromiseDelegate delegate(/*match=*/true);
-  EXPECT_EQ(promised->HandleClientRequest(client_request_, &delegate),
-            QUIC_FAILURE);
-
-  // Got an indication of the stream failure, client should retry
-  // request.
-  EXPECT_FALSE(delegate.rendezvous_fired());
-  EXPECT_EQ(delegate.rendezvous_stream(), nullptr);
-
-  // Promise is gone
-  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_client_push_promise_index.cc b/quic/core/http/quic_client_push_promise_index.cc
deleted file mode 100644
index 79e4f31..0000000
--- a/quic/core/http/quic_client_push_promise_index.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-
-#include <string>
-
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicClientPushPromiseIndex::QuicClientPushPromiseIndex() {}
-
-QuicClientPushPromiseIndex::~QuicClientPushPromiseIndex() {}
-
-QuicClientPushPromiseIndex::TryHandle::~TryHandle() {}
-
-QuicClientPromisedInfo* QuicClientPushPromiseIndex::GetPromised(
-    const std::string& url) {
-  auto it = promised_by_url_.find(url);
-  if (it == promised_by_url_.end()) {
-    return nullptr;
-  }
-  return it->second;
-}
-
-QuicAsyncStatus QuicClientPushPromiseIndex::Try(
-    const spdy::SpdyHeaderBlock& request,
-    QuicClientPushPromiseIndex::Delegate* delegate,
-    TryHandle** handle) {
-  std::string url(SpdyServerPushUtils::GetPromisedUrlFromHeaders(request));
-  auto it = promised_by_url_.find(url);
-  if (it != promised_by_url_.end()) {
-    QuicClientPromisedInfo* promised = it->second;
-    QuicAsyncStatus rv = promised->HandleClientRequest(request, delegate);
-    if (rv == QUIC_PENDING) {
-      *handle = promised;
-    }
-    return rv;
-  }
-  return QUIC_FAILURE;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_client_push_promise_index.h b/quic/core/http/quic_client_push_promise_index.h
deleted file mode 100644
index de070e6..0000000
--- a/quic/core/http/quic_client_push_promise_index.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
-
-#include <string>
-
-#include "quic/core/http/quic_spdy_client_session_base.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicClientPushPromiseIndex is the interface to support rendezvous
-// between client requests and resources delivered via server push.
-// The same index can be shared across multiple sessions (e.g. for the
-// same browser users profile), since cross-origin pushes are allowed
-// (subject to authority constraints).
-
-class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
- public:
-  // Delegate is used to complete the rendezvous that began with
-  // |Try()|.
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // The primary lookup matched request with push promise by URL.  A
-    // secondary match is necessary to ensure Vary (RFC 2616, 14.14)
-    // is honored.  If Vary is not present, return true.  If Vary is
-    // present, return whether designated header fields of
-    // |promise_request| and |client_request| match.
-    virtual bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
-                           const spdy::SpdyHeaderBlock& promise_request,
-                           const spdy::SpdyHeaderBlock& promise_response) = 0;
-
-    // On rendezvous success, provides the promised |stream|.  Callee
-    // does not inherit ownership of |stream|.  On rendezvous failure,
-    // |stream| is |nullptr| and the client should retry the request.
-    // Rendezvous can fail due to promise validation failure or RST on
-    // promised stream.  |url| will have been removed from the index
-    // before |OnRendezvousResult()| is invoked, so a recursive call to
-    // |Try()| will return |QUIC_FAILURE|, which may be convenient for
-    // retry purposes.
-    virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
-  };
-
-  class QUIC_EXPORT_PRIVATE TryHandle {
-   public:
-    // Cancel the request.
-    virtual void Cancel() = 0;
-
-   protected:
-    TryHandle() {}
-    TryHandle(const TryHandle&) = delete;
-    TryHandle& operator=(const TryHandle&) = delete;
-    ~TryHandle();
-  };
-
-  QuicClientPushPromiseIndex();
-  QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete;
-  QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) =
-      delete;
-  virtual ~QuicClientPushPromiseIndex();
-
-  // Called by client code, used to enforce affinity between requests
-  // for promised streams and the session the promise came from.
-  QuicClientPromisedInfo* GetPromised(const std::string& url);
-
-  // Called by client code, to initiate rendezvous between a request
-  // and a server push stream.  If |request|'s url is in the index,
-  // rendezvous will be attempted and may complete immediately or
-  // asynchronously.  If the matching promise and response headers
-  // have already arrived, the delegate's methods will fire
-  // recursively from within |Try()|.  Returns |QUIC_SUCCESS| if the
-  // rendezvous was a success. Returns |QUIC_FAILURE| if there was no
-  // matching promise, or if there was but the rendezvous has failed.
-  // Returns QUIC_PENDING if a matching promise was found, but the
-  // rendezvous needs to complete asynchronously because the promised
-  // response headers are not yet available.  If result is
-  // QUIC_PENDING, then |*handle| will set so that the caller may
-  // cancel the request if need be.  The caller does not inherit
-  // ownership of |*handle|, and it ceases to be valid if the caller
-  // invokes |handle->Cancel()| or if |delegate->OnReponse()| fires.
-  QuicAsyncStatus Try(const spdy::SpdyHeaderBlock& request,
-                      Delegate* delegate,
-                      TryHandle** handle);
-
-  QuicPromisedByUrlMap* promised_by_url() { return &promised_by_url_; }
-
- private:
-  QuicPromisedByUrlMap promised_by_url_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
diff --git a/quic/core/http/quic_client_push_promise_index_test.cc b/quic/core/http/quic_client_push_promise_index_test.cc
deleted file mode 100644
index 03f4eb7..0000000
--- a/quic/core/http/quic_client_push_promise_index_test.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-
-#include <string>
-
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_client_promised_info.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
-  explicit MockQuicSpdyClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      QuicClientPushPromiseIndex* push_promise_index)
-      : QuicSpdyClientSession(DefaultQuicConfig(),
-                              supported_versions,
-                              connection,
-                              QuicServerId("example.com", 443, false),
-                              &crypto_config_,
-                              push_promise_index),
-        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
-  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
-  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
-      delete;
-  ~MockQuicSpdyClientSession() override {}
-
- private:
-  QuicCryptoClientConfig crypto_config_;
-};
-
-class QuicClientPushPromiseIndexTest : public QuicTest {
- public:
-  QuicClientPushPromiseIndexTest()
-      : connection_(new StrictMock<MockQuicConnection>(&helper_,
-                                                       &alarm_factory_,
-                                                       Perspective::IS_CLIENT)),
-        session_(connection_->supported_versions(), connection_, &index_),
-        promised_(&session_,
-                  GetNthServerInitiatedUnidirectionalStreamId(
-                      connection_->transport_version(),
-                      0),
-                  url_) {
-    request_[":path"] = "/bar";
-    request_[":authority"] = "www.google.com";
-    request_[":method"] = "GET";
-    request_[":scheme"] = "https";
-    url_ = SpdyServerPushUtils::GetPromisedUrlFromHeaders(request_);
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  MockQuicSpdyClientSession session_;
-  QuicClientPushPromiseIndex index_;
-  spdy::SpdyHeaderBlock request_;
-  std::string url_;
-  MockQuicClientPromisedInfo promised_;
-  QuicClientPushPromiseIndex::TryHandle* handle_;
-};
-
-TEST_F(QuicClientPushPromiseIndexTest, TryRequestSuccess) {
-  (*index_.promised_by_url())[url_] = &promised_;
-  EXPECT_CALL(promised_, HandleClientRequest(_, _))
-      .WillOnce(Return(QUIC_SUCCESS));
-  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_SUCCESS);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, TryRequestPending) {
-  (*index_.promised_by_url())[url_] = &promised_;
-  EXPECT_CALL(promised_, HandleClientRequest(_, _))
-      .WillOnce(Return(QUIC_PENDING));
-  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_PENDING);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, TryRequestFailure) {
-  (*index_.promised_by_url())[url_] = &promised_;
-  EXPECT_CALL(promised_, HandleClientRequest(_, _))
-      .WillOnce(Return(QUIC_FAILURE));
-  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, TryNoPromise) {
-  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, GetNoPromise) {
-  EXPECT_EQ(index_.GetPromised(url_), nullptr);
-}
-
-TEST_F(QuicClientPushPromiseIndexTest, GetPromise) {
-  (*index_.promised_by_url())[url_] = &promised_;
-  EXPECT_EQ(index_.GetPromised(url_), &promised_);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_header_list.cc b/quic/core/http/quic_header_list.cc
deleted file mode 100644
index 7ac768d..0000000
--- a/quic/core/http/quic_header_list.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_header_list.h"
-
-#include <limits>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicHeaderList::QuicHeaderList()
-    : max_header_list_size_(std::numeric_limits<size_t>::max()),
-      current_header_list_size_(0),
-      uncompressed_header_bytes_(0),
-      compressed_header_bytes_(0) {}
-
-QuicHeaderList::QuicHeaderList(QuicHeaderList&& other) = default;
-
-QuicHeaderList::QuicHeaderList(const QuicHeaderList& other) = default;
-
-QuicHeaderList& QuicHeaderList::operator=(const QuicHeaderList& other) =
-    default;
-
-QuicHeaderList& QuicHeaderList::operator=(QuicHeaderList&& other) = default;
-
-QuicHeaderList::~QuicHeaderList() {}
-
-void QuicHeaderList::OnHeaderBlockStart() {
-  QUIC_BUG_IF(quic_bug_12518_1, current_header_list_size_ != 0)
-      << "OnHeaderBlockStart called more than once!";
-}
-
-void QuicHeaderList::OnHeader(absl::string_view name, absl::string_view value) {
-  // Avoid infinite buffering of headers. No longer store headers
-  // once the current headers are over the limit.
-  if (current_header_list_size_ < max_header_list_size_) {
-    current_header_list_size_ += name.size();
-    current_header_list_size_ += value.size();
-    current_header_list_size_ += kQpackEntrySizeOverhead;
-    header_list_.emplace_back(std::string(name), std::string(value));
-  }
-}
-
-void QuicHeaderList::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
-                                      size_t compressed_header_bytes) {
-  uncompressed_header_bytes_ = uncompressed_header_bytes;
-  compressed_header_bytes_ = compressed_header_bytes;
-  if (current_header_list_size_ > max_header_list_size_) {
-    Clear();
-  }
-}
-
-void QuicHeaderList::Clear() {
-  header_list_.clear();
-  current_header_list_size_ = 0;
-  uncompressed_header_bytes_ = 0;
-  compressed_header_bytes_ = 0;
-}
-
-std::string QuicHeaderList::DebugString() const {
-  std::string s = "{ ";
-  for (const auto& p : *this) {
-    s.append(p.first + "=" + p.second + ", ");
-  }
-  s.append("}");
-  return s;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_header_list.h b/quic/core/http/quic_header_list.h
deleted file mode 100644
index 01c861d..0000000
--- a/quic/core/http/quic_header_list.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
-
-#include <algorithm>
-#include <functional>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-
-namespace quic {
-
-// A simple class that accumulates header pairs
-class QUIC_EXPORT_PRIVATE QuicHeaderList
-    : public spdy::SpdyHeadersHandlerInterface {
- public:
-  using ListType =
-      quiche::QuicheCircularDeque<std::pair<std::string, std::string>>;
-  using value_type = ListType::value_type;
-  using const_iterator = ListType::const_iterator;
-
-  QuicHeaderList();
-  QuicHeaderList(QuicHeaderList&& other);
-  QuicHeaderList(const QuicHeaderList& other);
-  QuicHeaderList& operator=(QuicHeaderList&& other);
-  QuicHeaderList& operator=(const QuicHeaderList& other);
-  ~QuicHeaderList() override;
-
-  // From SpdyHeadersHandlerInteface.
-  void OnHeaderBlockStart() override;
-  void OnHeader(absl::string_view name, absl::string_view value) override;
-  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
-                        size_t compressed_header_bytes) override;
-
-  void Clear();
-
-  const_iterator begin() const { return header_list_.begin(); }
-  const_iterator end() const { return header_list_.end(); }
-
-  bool empty() const { return header_list_.empty(); }
-  size_t uncompressed_header_bytes() const {
-    return uncompressed_header_bytes_;
-  }
-  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
-
-  // Deprecated.  TODO(b/145909215): remove.
-  void set_max_header_list_size(size_t max_header_list_size) {
-    max_header_list_size_ = max_header_list_size;
-  }
-
-  std::string DebugString() const;
-
- private:
-  quiche::QuicheCircularDeque<std::pair<std::string, std::string>> header_list_;
-
-  // The limit on the size of the header list (defined by spec as name + value +
-  // overhead for each header field). Headers over this limit will not be
-  // buffered, and the list will be cleared upon OnHeaderBlockEnd.
-  size_t max_header_list_size_;
-
-  // Defined per the spec as the size of all header fields with an additional
-  // overhead for each field.
-  size_t current_header_list_size_;
-
-  // TODO(dahollings) Are these fields necessary?
-  size_t uncompressed_header_bytes_;
-  size_t compressed_header_bytes_;
-};
-
-inline bool operator==(const QuicHeaderList& l1, const QuicHeaderList& l2) {
-  auto pred = [](const std::pair<std::string, std::string>& p1,
-                 const std::pair<std::string, std::string>& p2) {
-    return p1.first == p2.first && p1.second == p2.second;
-  };
-  return std::equal(l1.begin(), l1.end(), l2.begin(), pred);
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
diff --git a/quic/core/http/quic_header_list_test.cc b/quic/core/http/quic_header_list_test.cc
deleted file mode 100644
index edd52dd..0000000
--- a/quic/core/http/quic_header_list_test.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_header_list.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-using ::testing::ElementsAre;
-using ::testing::Pair;
-
-namespace quic {
-
-class QuicHeaderListTest : public QuicTest {};
-
-// This test verifies that QuicHeaderList accumulates header pairs in order.
-TEST_F(QuicHeaderListTest, OnHeader) {
-  QuicHeaderList headers;
-  headers.OnHeader("foo", "bar");
-  headers.OnHeader("april", "fools");
-  headers.OnHeader("beep", "");
-
-  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
-                                   Pair("beep", "")));
-}
-
-TEST_F(QuicHeaderListTest, DebugString) {
-  QuicHeaderList headers;
-  headers.OnHeader("foo", "bar");
-  headers.OnHeader("april", "fools");
-  headers.OnHeader("beep", "");
-
-  EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers.DebugString());
-}
-
-TEST_F(QuicHeaderListTest, TooLarge) {
-  const size_t kMaxHeaderListSize = 256;
-
-  QuicHeaderList headers;
-  headers.set_max_header_list_size(kMaxHeaderListSize);
-  std::string key = "key";
-  std::string value(kMaxHeaderListSize, '1');
-  // Send a header that exceeds max_header_list_size.
-  headers.OnHeader(key, value);
-  // Send a second header exceeding max_header_list_size.
-  headers.OnHeader(key + "2", value);
-  // We should not allocate more memory after exceeding max_header_list_size.
-  EXPECT_LT(headers.DebugString().size(), 2 * value.size());
-  size_t total_bytes = 2 * (key.size() + value.size()) + 1;
-  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
-
-  EXPECT_TRUE(headers.empty());
-  EXPECT_EQ("{ }", headers.DebugString());
-}
-
-TEST_F(QuicHeaderListTest, NotTooLarge) {
-  QuicHeaderList headers;
-  headers.set_max_header_list_size(1 << 20);
-  std::string key = "key";
-  std::string value(1 << 18, '1');
-  headers.OnHeader(key, value);
-  size_t total_bytes = key.size() + value.size();
-  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
-  EXPECT_FALSE(headers.empty());
-}
-
-// This test verifies that QuicHeaderList is copyable and assignable.
-TEST_F(QuicHeaderListTest, IsCopyableAndAssignable) {
-  QuicHeaderList headers;
-  headers.OnHeader("foo", "bar");
-  headers.OnHeader("april", "fools");
-  headers.OnHeader("beep", "");
-
-  QuicHeaderList headers2(headers);
-  QuicHeaderList headers3 = headers;
-
-  EXPECT_THAT(headers2, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
-                                    Pair("beep", "")));
-  EXPECT_THAT(headers3, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
-                                    Pair("beep", "")));
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_headers_stream.cc b/quic/core/http/quic_headers_stream.cc
deleted file mode 100644
index 1a8d0dd..0000000
--- a/quic/core/http/quic_headers_stream.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_headers_stream.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
-    QuicStreamOffset headers_stream_offset, QuicStreamOffset full_length,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener)
-    : headers_stream_offset(headers_stream_offset),
-      full_length(full_length),
-      unacked_length(full_length),
-      ack_listener(std::move(ack_listener)) {}
-
-QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
-    const CompressedHeaderInfo& other) = default;
-
-QuicHeadersStream::CompressedHeaderInfo::~CompressedHeaderInfo() {}
-
-QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
-    : QuicStream(QuicUtils::GetHeadersStreamId(session->transport_version()),
-                 session,
-                 /*is_static=*/true,
-                 BIDIRECTIONAL),
-      spdy_session_(session) {
-  // The headers stream is exempt from connection level flow control.
-  DisableConnectionFlowControlForThisStream();
-}
-
-QuicHeadersStream::~QuicHeadersStream() {}
-
-void QuicHeadersStream::OnDataAvailable() {
-  struct iovec iov;
-  while (sequencer()->GetReadableRegion(&iov)) {
-    if (spdy_session_->ProcessHeaderData(iov) != iov.iov_len) {
-      // Error processing data.
-      return;
-    }
-    sequencer()->MarkConsumed(iov.iov_len);
-    MaybeReleaseSequencerBuffer();
-  }
-}
-
-void QuicHeadersStream::MaybeReleaseSequencerBuffer() {
-  if (spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
-    sequencer()->ReleaseBufferIfEmpty();
-  }
-}
-
-bool QuicHeadersStream::OnStreamFrameAcked(QuicStreamOffset offset,
-                                           QuicByteCount data_length,
-                                           bool fin_acked,
-                                           QuicTime::Delta ack_delay_time,
-                                           QuicTime receive_timestamp,
-                                           QuicByteCount* newly_acked_length) {
-  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
-  newly_acked.Difference(bytes_acked());
-  for (const auto& acked : newly_acked) {
-    QuicStreamOffset acked_offset = acked.min();
-    QuicByteCount acked_length = acked.max() - acked.min();
-    for (CompressedHeaderInfo& header : unacked_headers_) {
-      if (acked_offset < header.headers_stream_offset) {
-        // This header frame offset belongs to headers with smaller offset, stop
-        // processing.
-        break;
-      }
-
-      if (acked_offset >= header.headers_stream_offset + header.full_length) {
-        // This header frame belongs to headers with larger offset.
-        continue;
-      }
-
-      QuicByteCount header_offset = acked_offset - header.headers_stream_offset;
-      QuicByteCount header_length =
-          std::min(acked_length, header.full_length - header_offset);
-
-      if (header.unacked_length < header_length) {
-        QUIC_BUG(quic_bug_10416_1)
-            << "Unsent stream data is acked. unacked_length: "
-            << header.unacked_length << " acked_length: " << header_length;
-        OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                             "Unsent stream data is acked");
-        return false;
-      }
-      if (header.ack_listener != nullptr && header_length > 0) {
-        header.ack_listener->OnPacketAcked(header_length, ack_delay_time);
-      }
-      header.unacked_length -= header_length;
-      acked_offset += header_length;
-      acked_length -= header_length;
-    }
-  }
-  // Remove headers which are fully acked. Please note, header frames can be
-  // acked out of order, but unacked_headers_ is cleaned up in order.
-  while (!unacked_headers_.empty() &&
-         unacked_headers_.front().unacked_length == 0) {
-    unacked_headers_.pop_front();
-  }
-  return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
-                                        ack_delay_time, receive_timestamp,
-                                        newly_acked_length);
-}
-
-void QuicHeadersStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
-                                                   QuicByteCount data_length,
-                                                   bool /*fin_retransmitted*/) {
-  QuicStream::OnStreamFrameRetransmitted(offset, data_length, false);
-  for (CompressedHeaderInfo& header : unacked_headers_) {
-    if (offset < header.headers_stream_offset) {
-      // This header frame offset belongs to headers with smaller offset, stop
-      // processing.
-      break;
-    }
-
-    if (offset >= header.headers_stream_offset + header.full_length) {
-      // This header frame belongs to headers with larger offset.
-      continue;
-    }
-
-    QuicByteCount header_offset = offset - header.headers_stream_offset;
-    QuicByteCount retransmitted_length =
-        std::min(data_length, header.full_length - header_offset);
-    if (header.ack_listener != nullptr && retransmitted_length > 0) {
-      header.ack_listener->OnPacketRetransmitted(retransmitted_length);
-    }
-    offset += retransmitted_length;
-    data_length -= retransmitted_length;
-  }
-}
-
-void QuicHeadersStream::OnDataBuffered(
-    QuicStreamOffset offset, QuicByteCount data_length,
-    const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
-        ack_listener) {
-  // Populate unacked_headers_.
-  if (!unacked_headers_.empty() &&
-      (offset == unacked_headers_.back().headers_stream_offset +
-                     unacked_headers_.back().full_length) &&
-      ack_listener == unacked_headers_.back().ack_listener) {
-    // Try to combine with latest inserted entry if they belong to the same
-    // header (i.e., having contiguous offset and the same ack listener).
-    unacked_headers_.back().full_length += data_length;
-    unacked_headers_.back().unacked_length += data_length;
-  } else {
-    unacked_headers_.push_back(
-        CompressedHeaderInfo(offset, data_length, ack_listener));
-  }
-}
-
-void QuicHeadersStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
-  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
-                                   "Attempt to reset headers stream");
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_headers_stream.h b/quic/core/http/quic_headers_stream.h
deleted file mode 100644
index 3e541ec..0000000
--- a/quic/core/http/quic_headers_stream.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-class QuicSpdySession;
-
-namespace test {
-class QuicHeadersStreamPeer;
-}  // namespace test
-
-// Headers in QUIC are sent as HTTP/2 HEADERS or PUSH_PROMISE frames over a
-// reserved stream with the id 3.  Each endpoint (client and server) will
-// allocate an instance of QuicHeadersStream to send and receive headers.
-class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
- public:
-  explicit QuicHeadersStream(QuicSpdySession* session);
-  QuicHeadersStream(const QuicHeadersStream&) = delete;
-  QuicHeadersStream& operator=(const QuicHeadersStream&) = delete;
-  ~QuicHeadersStream() override;
-
-  // QuicStream implementation
-  void OnDataAvailable() override;
-
-  // Release underlying buffer if allowed.
-  void MaybeReleaseSequencerBuffer();
-
-  bool OnStreamFrameAcked(QuicStreamOffset offset,
-                          QuicByteCount data_length,
-                          bool fin_acked,
-                          QuicTime::Delta ack_delay_time,
-                          QuicTime receive_timestamp,
-                          QuicByteCount* newly_acked_length) override;
-
-  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
-                                  QuicByteCount data_length,
-                                  bool fin_retransmitted) override;
-
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- private:
-  friend class test::QuicHeadersStreamPeer;
-
-  // CompressedHeaderInfo includes simple information of a header, including
-  // offset in headers stream, unacked length and ack listener of this header.
-  struct QUIC_EXPORT_PRIVATE CompressedHeaderInfo {
-    CompressedHeaderInfo(
-        QuicStreamOffset headers_stream_offset, QuicStreamOffset full_length,
-        quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-            ack_listener);
-    CompressedHeaderInfo(const CompressedHeaderInfo& other);
-    ~CompressedHeaderInfo();
-
-    // Offset the header was sent on the headers stream.
-    QuicStreamOffset headers_stream_offset;
-    // The full length of the header.
-    QuicByteCount full_length;
-    // The remaining bytes to be acked.
-    QuicByteCount unacked_length;
-    // Ack listener of this header, and it is notified once any of the bytes has
-    // been acked or retransmitted.
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener;
-  };
-
-  // Returns true if the session is still connected.
-  bool IsConnected();
-
-  // Override to store mapping from offset, length to ack_listener. This
-  // ack_listener is notified once data within [offset, offset + length] is
-  // acked or retransmitted.
-  void OnDataBuffered(
-      QuicStreamOffset offset, QuicByteCount data_length,
-      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
-          ack_listener) override;
-
-  QuicSpdySession* spdy_session_;
-
-  // Headers that have not been fully acked.
-  quiche::QuicheCircularDeque<CompressedHeaderInfo> unacked_headers_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
diff --git a/quic/core/http/quic_headers_stream_test.cc b/quic/core/http/quic_headers_stream_test.cc
deleted file mode 100644
index 14d9ad9..0000000
--- a/quic/core/http/quic_headers_stream_test.cc
+++ /dev/null
@@ -1,972 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_headers_stream.h"
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/recording_headers_handler.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/spdy_test_utils.h"
-
-using spdy::ERROR_CODE_PROTOCOL_ERROR;
-using spdy::RecordingHeadersHandler;
-using spdy::SETTINGS_ENABLE_PUSH;
-using spdy::SETTINGS_HEADER_TABLE_SIZE;
-using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
-using spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
-using spdy::SETTINGS_MAX_FRAME_SIZE;
-using spdy::Spdy3PriorityToHttp2Weight;
-using spdy::SpdyAltSvcWireFormat;
-using spdy::SpdyDataIR;
-using spdy::SpdyErrorCode;
-using spdy::SpdyFramer;
-using spdy::SpdyFramerVisitorInterface;
-using spdy::SpdyGoAwayIR;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyHeadersHandlerInterface;
-using spdy::SpdyHeadersIR;
-using spdy::SpdyPingId;
-using spdy::SpdyPingIR;
-using spdy::SpdyPriority;
-using spdy::SpdyPriorityIR;
-using spdy::SpdyPushPromiseIR;
-using spdy::SpdyRstStreamIR;
-using spdy::SpdySerializedFrame;
-using spdy::SpdySettingsId;
-using spdy::SpdySettingsIR;
-using spdy::SpdyStreamId;
-using spdy::SpdyWindowUpdateIR;
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-using testing::WithArgs;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockVisitor : public SpdyFramerVisitorInterface {
- public:
-  MOCK_METHOD(void,
-              OnError,
-              (http2::Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error),
-              (override));
-  MOCK_METHOD(void,
-              OnDataFrameHeader,
-              (SpdyStreamId stream_id, size_t length, bool fin),
-              (override));
-  MOCK_METHOD(void,
-              OnStreamFrameData,
-              (SpdyStreamId stream_id, const char*, size_t len),
-              (override));
-  MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
-  MOCK_METHOD(void,
-              OnStreamPadding,
-              (SpdyStreamId stream_id, size_t len),
-              (override));
-  MOCK_METHOD(SpdyHeadersHandlerInterface*,
-              OnHeaderFrameStart,
-              (SpdyStreamId stream_id),
-              (override));
-  MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
-  MOCK_METHOD(void,
-              OnRstStream,
-              (SpdyStreamId stream_id, SpdyErrorCode error_code),
-              (override));
-  MOCK_METHOD(void, OnSettings, (), (override));
-  MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
-  MOCK_METHOD(void, OnSettingsAck, (), (override));
-  MOCK_METHOD(void, OnSettingsEnd, (), (override));
-  MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
-  MOCK_METHOD(void,
-              OnGoAway,
-              (SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
-              (override));
-  MOCK_METHOD(void,
-              OnHeaders,
-              (SpdyStreamId stream_id,
-               bool has_priority,
-               int weight,
-               SpdyStreamId parent_stream_id,
-               bool exclusive,
-               bool fin,
-               bool end),
-              (override));
-  MOCK_METHOD(void,
-              OnWindowUpdate,
-              (SpdyStreamId stream_id, int delta_window_size),
-              (override));
-  MOCK_METHOD(void,
-              OnPushPromise,
-              (SpdyStreamId stream_id,
-               SpdyStreamId promised_stream_id,
-               bool end),
-              (override));
-  MOCK_METHOD(void,
-              OnContinuation,
-              (SpdyStreamId stream_id, bool end),
-              (override));
-  MOCK_METHOD(
-      void,
-      OnAltSvc,
-      (SpdyStreamId stream_id,
-       absl::string_view origin,
-       const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
-      (override));
-  MOCK_METHOD(void,
-              OnPriority,
-              (SpdyStreamId stream_id,
-               SpdyStreamId parent_stream_id,
-               int weight,
-               bool exclusive),
-              (override));
-  MOCK_METHOD(void,
-              OnPriorityUpdate,
-              (SpdyStreamId prioritized_stream_id,
-               absl::string_view priority_field_value),
-              (override));
-  MOCK_METHOD(bool,
-              OnUnknownFrame,
-              (SpdyStreamId stream_id, uint8_t frame_type),
-              (override));
-};
-
-struct TestParams {
-  TestParams(const ParsedQuicVersion& version, Perspective perspective)
-      : version(version), perspective(perspective) {
-    QUIC_LOG(INFO) << "TestParams:  " << *this;
-  }
-
-  TestParams(const TestParams& other)
-      : version(other.version), perspective(other.perspective) {}
-
-  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
-    os << "{ version: " << ParsedQuicVersionToString(tp.version)
-       << ", perspective: "
-       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
-       << "}";
-    return os;
-  }
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(tp.version), "_",
-      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
-    if (VersionUsesHttp3(all_supported_versions[i].transport_version)) {
-      continue;
-    }
-    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
-      params.emplace_back(all_supported_versions[i], p);
-    }
-  }
-  return params;
-}
-
-class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
- public:
-  QuicHeadersStreamTest()
-      : connection_(new StrictMock<MockQuicConnection>(&helper_,
-                                                       &alarm_factory_,
-                                                       perspective(),
-                                                       GetVersion())),
-        session_(connection_),
-        body_("hello world"),
-        stream_frame_(
-            QuicUtils::GetHeadersStreamId(connection_->transport_version()),
-            /*fin=*/false,
-            /*offset=*/0,
-            ""),
-        next_promised_stream_id_(2) {
-    QuicSpdySessionPeer::SetMaxInboundHeaderListSize(&session_, 256 * 1024);
-    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    session_.Initialize();
-    connection_->SetEncrypter(
-        quic::ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<quic::NullEncrypter>(connection_->perspective()));
-    headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
-    headers_[":status"] = "200 Ok";
-    headers_["content-length"] = "11";
-    framer_ = std::unique_ptr<SpdyFramer>(
-        new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION));
-    deframer_ = std::unique_ptr<http2::Http2DecoderAdapter>(
-        new http2::Http2DecoderAdapter());
-    deframer_->set_visitor(&visitor_);
-    EXPECT_EQ(transport_version(), session_.transport_version());
-    EXPECT_TRUE(headers_stream_ != nullptr);
-    connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-    client_id_1_ = GetNthClientInitiatedBidirectionalStreamId(
-        connection_->transport_version(), 0);
-    client_id_2_ = GetNthClientInitiatedBidirectionalStreamId(
-        connection_->transport_version(), 1);
-    client_id_3_ = GetNthClientInitiatedBidirectionalStreamId(
-        connection_->transport_version(), 2);
-    next_stream_id_ =
-        QuicUtils::StreamIdDelta(connection_->transport_version());
-  }
-
-  QuicStreamId GetNthClientInitiatedId(int n) {
-    return GetNthClientInitiatedBidirectionalStreamId(
-        connection_->transport_version(), n);
-  }
-
-  QuicConsumedData SaveIov(size_t write_length) {
-    char* buf = new char[write_length];
-    QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER);
-    headers_stream_->WriteStreamData(headers_stream_->stream_bytes_written(),
-                                     write_length, &writer);
-    saved_data_.append(buf, write_length);
-    delete[] buf;
-    return QuicConsumedData(write_length, false);
-  }
-
-  void SavePayload(const char* data, size_t len) {
-    saved_payloads_.append(data, len);
-  }
-
-  bool SaveHeaderData(const char* data, int len) {
-    saved_header_data_.append(data, len);
-    return true;
-  }
-
-  void SaveHeaderDataStringPiece(absl::string_view data) {
-    saved_header_data_.append(data.data(), data.length());
-  }
-
-  void SavePromiseHeaderList(QuicStreamId /* stream_id */,
-                             QuicStreamId /* promised_stream_id */,
-                             size_t size,
-                             const QuicHeaderList& header_list) {
-    SaveToHandler(size, header_list);
-  }
-
-  void SaveHeaderList(QuicStreamId /* stream_id */,
-                      bool /* fin */,
-                      size_t size,
-                      const QuicHeaderList& header_list) {
-    SaveToHandler(size, header_list);
-  }
-
-  void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
-    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-    headers_handler_->OnHeaderBlockStart();
-    for (const auto& p : header_list) {
-      headers_handler_->OnHeader(p.first, p.second);
-    }
-    headers_handler_->OnHeaderBlockEnd(size, size);
-  }
-
-  void WriteAndExpectRequestHeaders(QuicStreamId stream_id,
-                                    bool fin,
-                                    SpdyPriority priority) {
-    WriteHeadersAndCheckData(stream_id, fin, priority, true /*is_request*/);
-  }
-
-  void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) {
-    WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/);
-  }
-
-  void WriteHeadersAndCheckData(QuicStreamId stream_id,
-                                bool fin,
-                                SpdyPriority priority,
-                                bool is_request) {
-    // Write the headers and capture the outgoing data
-    EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
-                                         connection_->transport_version()),
-                                     _, _, NO_FIN, _, _))
-        .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
-    QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
-        &session_, stream_id, headers_.Clone(), fin,
-        spdy::SpdyStreamPrecedence(priority), nullptr);
-
-    // Parse the outgoing data and check that it matches was was written.
-    if (is_request) {
-      EXPECT_CALL(visitor_,
-                  OnHeaders(stream_id, kHasPriority,
-                            Spdy3PriorityToHttp2Weight(priority),
-                            /*parent_stream_id=*/0,
-                            /*exclusive=*/false, fin, kFrameComplete));
-    } else {
-      EXPECT_CALL(visitor_,
-                  OnHeaders(stream_id, !kHasPriority,
-                            /*weight=*/0,
-                            /*parent_stream_id=*/0,
-                            /*exclusive=*/false, fin, kFrameComplete));
-    }
-    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-    EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
-        .WillOnce(Return(headers_handler_.get()));
-    EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
-    if (fin) {
-      EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
-    }
-    deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
-    EXPECT_FALSE(deframer_->HasError())
-        << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer_->spdy_framer_error());
-
-    CheckHeaders();
-    saved_data_.clear();
-  }
-
-  void CheckHeaders() {
-    ASSERT_TRUE(headers_handler_);
-    EXPECT_EQ(headers_, headers_handler_->decoded_block());
-    headers_handler_.reset();
-  }
-
-  Perspective perspective() const { return GetParam().perspective; }
-
-  QuicTransportVersion transport_version() const {
-    return GetParam().version.transport_version;
-  }
-
-  ParsedQuicVersionVector GetVersion() {
-    ParsedQuicVersionVector versions;
-    versions.push_back(GetParam().version);
-    return versions;
-  }
-
-  void TearDownLocalConnectionState() {
-    QuicConnectionPeer::TearDownLocalConnectionState(connection_);
-  }
-
-  QuicStreamId NextPromisedStreamId() {
-    return next_promised_stream_id_ += next_stream_id_;
-  }
-
-  static constexpr bool kFrameComplete = true;
-  static constexpr bool kHasPriority = true;
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  StrictMock<MockQuicSpdySession> session_;
-  QuicHeadersStream* headers_stream_;
-  SpdyHeaderBlock headers_;
-  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
-  std::string body_;
-  std::string saved_data_;
-  std::string saved_header_data_;
-  std::string saved_payloads_;
-  std::unique_ptr<SpdyFramer> framer_;
-  std::unique_ptr<http2::Http2DecoderAdapter> deframer_;
-  StrictMock<MockVisitor> visitor_;
-  QuicStreamFrame stream_frame_;
-  QuicStreamId next_promised_stream_id_;
-  QuicStreamId client_id_1_;
-  QuicStreamId client_id_2_;
-  QuicStreamId client_id_3_;
-  QuicStreamId next_stream_id_;
-};
-
-// Run all tests with each version and perspective (client or server).
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicHeadersStreamTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicHeadersStreamTest, StreamId) {
-  EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_->transport_version()),
-            headers_stream_->id());
-}
-
-TEST_P(QuicHeadersStreamTest, WriteHeaders) {
-  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
-       stream_id += next_stream_id_) {
-    for (bool fin : {false, true}) {
-      if (perspective() == Perspective::IS_SERVER) {
-        WriteAndExpectResponseHeaders(stream_id, fin);
-      } else {
-        for (SpdyPriority priority = 0; priority < 7; ++priority) {
-          // TODO(rch): implement priorities correctly.
-          WriteAndExpectRequestHeaders(stream_id, fin, 0);
-        }
-      }
-    }
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, WritePushPromises) {
-  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
-       stream_id += next_stream_id_) {
-    QuicStreamId promised_stream_id = NextPromisedStreamId();
-    if (perspective() == Perspective::IS_SERVER) {
-      // Write the headers and capture the outgoing data
-      EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
-                                           connection_->transport_version()),
-                                       _, _, NO_FIN, _, _))
-          .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
-      session_.WritePushPromise(stream_id, promised_stream_id,
-                                headers_.Clone());
-
-      // Parse the outgoing data and check that it matches was was written.
-      EXPECT_CALL(visitor_,
-                  OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
-      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-      EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
-          .WillOnce(Return(headers_handler_.get()));
-      EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
-      deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
-      EXPECT_FALSE(deframer_->HasError())
-          << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
-                 deframer_->spdy_framer_error());
-      CheckHeaders();
-      saved_data_.clear();
-    } else {
-      EXPECT_QUIC_BUG(session_.WritePushPromise(stream_id, promised_stream_id,
-                                                headers_.Clone()),
-                      "Client shouldn't send PUSH_PROMISE");
-    }
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessRawData) {
-  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
-       stream_id += next_stream_id_) {
-    for (bool fin : {false, true}) {
-      for (SpdyPriority priority = 0; priority < 7; ++priority) {
-        // Replace with "WriteHeadersAndSaveData"
-        SpdySerializedFrame frame;
-        if (perspective() == Perspective::IS_SERVER) {
-          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
-          headers_frame.set_fin(fin);
-          headers_frame.set_has_priority(true);
-          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
-          frame = framer_->SerializeFrame(headers_frame);
-          EXPECT_CALL(session_, OnStreamHeadersPriority(
-                                    stream_id, spdy::SpdyStreamPrecedence(0)));
-        } else {
-          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
-          headers_frame.set_fin(fin);
-          frame = framer_->SerializeFrame(headers_frame);
-        }
-        EXPECT_CALL(session_,
-                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
-            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
-        stream_frame_.data_buffer = frame.data();
-        stream_frame_.data_length = frame.size();
-        headers_stream_->OnStreamFrame(stream_frame_);
-        stream_frame_.offset += frame.size();
-        CheckHeaders();
-      }
-    }
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
-  if (perspective() == Perspective::IS_SERVER) {
-    return;
-  }
-  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
-       stream_id += next_stream_id_) {
-    QuicStreamId promised_stream_id = NextPromisedStreamId();
-    SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
-                                   headers_.Clone());
-    SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
-    bool connection_closed = false;
-    if (perspective() == Perspective::IS_SERVER) {
-      EXPECT_CALL(*connection_,
-                  CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                  "PUSH_PROMISE not supported.", _))
-          .WillRepeatedly(InvokeWithoutArgs(
-              this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-    } else {
-      ON_CALL(*connection_, CloseConnection(_, _, _))
-          .WillByDefault(testing::Assign(&connection_closed, true));
-      EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id,
-                                                frame.size(), _))
-          .WillOnce(
-              Invoke(this, &QuicHeadersStreamTest::SavePromiseHeaderList));
-    }
-    stream_frame_.data_buffer = frame.data();
-    stream_frame_.data_length = frame.size();
-    headers_stream_->OnStreamFrame(stream_frame_);
-    if (perspective() == Perspective::IS_CLIENT) {
-      stream_frame_.offset += frame.size();
-      // CheckHeaders crashes if the connection is closed so this ensures we
-      // fail the test instead of crashing.
-      ASSERT_FALSE(connection_closed);
-      CheckHeaders();
-    }
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) {
-  QuicStreamId parent_stream_id = 0;
-  for (SpdyPriority priority = 0; priority < 7; ++priority) {
-    for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
-         stream_id += next_stream_id_) {
-      int weight = Spdy3PriorityToHttp2Weight(priority);
-      SpdyPriorityIR priority_frame(stream_id, parent_stream_id, weight, true);
-      SpdySerializedFrame frame(framer_->SerializeFrame(priority_frame));
-      parent_stream_id = stream_id;
-      if (perspective() == Perspective::IS_CLIENT) {
-        EXPECT_CALL(*connection_,
-                    CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                    "Server must not send PRIORITY frames.", _))
-            .WillRepeatedly(InvokeWithoutArgs(
-                this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-      } else {
-        EXPECT_CALL(
-            session_,
-            OnPriorityFrame(stream_id, spdy::SpdyStreamPrecedence(priority)))
-            .Times(1);
-      }
-      stream_frame_.data_buffer = frame.data();
-      stream_frame_.data_length = frame.size();
-      headers_stream_->OnStreamFrame(stream_frame_);
-      stream_frame_.offset += frame.size();
-    }
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
-  if (perspective() != Perspective::IS_CLIENT) {
-    return;
-  }
-
-  session_.OnConfigNegotiated();
-  SpdySettingsIR data;
-  // Respect supported settings frames SETTINGS_ENABLE_PUSH.
-  data.AddSetting(SETTINGS_ENABLE_PUSH, 0);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                      "Unsupported field of HTTP/2 SETTINGS frame: 2", _));
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
-  // We want to create a frame that is more than the SPDY Framer's max control
-  // frame size, which is 16K, but less than the HPACK decoders max decode
-  // buffer size, which is 32K.
-  headers_["key0"] = std::string(1 << 13, '.');
-  headers_["key1"] = std::string(1 << 13, '.');
-  headers_["key2"] = std::string(1 << 13, '.');
-  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
-       stream_id += next_stream_id_) {
-    for (bool fin : {false, true}) {
-      for (SpdyPriority priority = 0; priority < 7; ++priority) {
-        // Replace with "WriteHeadersAndSaveData"
-        SpdySerializedFrame frame;
-        if (perspective() == Perspective::IS_SERVER) {
-          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
-          headers_frame.set_fin(fin);
-          headers_frame.set_has_priority(true);
-          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
-          frame = framer_->SerializeFrame(headers_frame);
-          EXPECT_CALL(session_, OnStreamHeadersPriority(
-                                    stream_id, spdy::SpdyStreamPrecedence(0)));
-        } else {
-          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
-          headers_frame.set_fin(fin);
-          frame = framer_->SerializeFrame(headers_frame);
-        }
-        EXPECT_CALL(session_,
-                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
-            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
-        stream_frame_.data_buffer = frame.data();
-        stream_frame_.data_length = frame.size();
-        headers_stream_->OnStreamFrame(stream_frame_);
-        stream_frame_.offset += frame.size();
-        CheckHeaders();
-      }
-    }
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessBadData) {
-  const char kBadData[] = "blah blah blah";
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
-      .Times(::testing::AnyNumber());
-  stream_frame_.data_buffer = kBadData;
-  stream_frame_.data_length = strlen(kBadData);
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
-  SpdyDataIR data(/* stream_id = */ 2, "ping");
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                            "SPDY DATA frame received.", _))
-      .WillOnce(InvokeWithoutArgs(
-          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
-  SpdyRstStreamIR data(/* stream_id = */ 2, ERROR_CODE_PROTOCOL_ERROR);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                              "SPDY RST_STREAM frame received.", _))
-      .WillOnce(InvokeWithoutArgs(
-          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
-  const uint32_t kTestHeaderTableSize = 1000;
-  SpdySettingsIR data;
-  // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
-  // SETTINGS_MAX_HEADER_LIST_SIZE.
-  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize);
-  data.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, 2000);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-  EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_)
-                                      ->header_encoder_table_size());
-}
-
-// Regression bug for b/208997000.
-TEST_P(QuicHeadersStreamTest, LimitEncoderDynamicTableSize) {
-  const uint32_t kVeryLargeTableSizeLimit = 1024 * 1024 * 1024;
-  SpdySettingsIR data;
-  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kVeryLargeTableSizeLimit);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
-    EXPECT_EQ(16384u, QuicSpdySessionPeer::GetSpdyFramer(&session_)
-                          ->header_encoder_table_size());
-  } else {
-    EXPECT_EQ(kVeryLargeTableSizeLimit,
-              QuicSpdySessionPeer::GetSpdyFramer(&session_)
-                  ->header_encoder_table_size());
-  }
-}
-
-TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
-  SpdySettingsIR data;
-  // Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
-  // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
-  // SETTINGS_MAX_FRAME_SIZE.
-  data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 100);
-  data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 100);
-  data.AddSetting(SETTINGS_ENABLE_PUSH, 1);
-  data.AddSetting(SETTINGS_MAX_FRAME_SIZE, 1250);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_HEADERS_STREAM_DATA,
-                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
-                               SETTINGS_MAX_CONCURRENT_STREAMS),
-                  _));
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_HEADERS_STREAM_DATA,
-                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
-                               SETTINGS_INITIAL_WINDOW_SIZE),
-                  _));
-  if (session_.perspective() == Perspective::IS_CLIENT) {
-    EXPECT_CALL(*connection_,
-                CloseConnection(
-                    QUIC_INVALID_HEADERS_STREAM_DATA,
-                    absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
-                                 SETTINGS_ENABLE_PUSH),
-                    _));
-  }
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_HEADERS_STREAM_DATA,
-                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
-                               SETTINGS_MAX_FRAME_SIZE),
-                  _));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
-  SpdyPingIR data(1);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                            "SPDY PING frame received.", _))
-      .WillOnce(InvokeWithoutArgs(
-          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
-  SpdyGoAwayIR data(/* last_good_stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR,
-                    "go away");
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                            "SPDY GOAWAY frame received.", _))
-      .WillOnce(InvokeWithoutArgs(
-          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
-  SpdyWindowUpdateIR data(/* stream_id = */ 1, /* delta = */ 1);
-  SpdySerializedFrame frame(framer_->SerializeFrame(data));
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                              "SPDY WINDOW_UPDATE frame received.", _))
-      .WillOnce(InvokeWithoutArgs(
-          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
-  EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl(
-      headers_stream_));
-}
-
-TEST_P(QuicHeadersStreamTest, AckSentData) {
-  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
-                                       connection_->transport_version()),
-                                   _, _, NO_FIN, _, _))
-      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  InSequence s;
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
-      new MockAckListener());
-
-  // Packet 1.
-  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
-  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
-  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-
-  // Packet 2.
-  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-
-  // Packet 3.
-  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-
-  // Packet 2 gets retransmitted.
-  EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
-  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
-  headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
-  headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
-
-  // Packets are acked in order: 2, 3, 1.
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      21, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(7u, newly_acked_length);
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      28, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(7u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      35, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(7u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      0, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(7u, newly_acked_length);
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      7, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(7u, newly_acked_length);
-  // Unsent data is acked.
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      14, 10, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(7u, newly_acked_length);
-}
-
-TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
-  // In this test, a stream frame can contain multiple headers.
-  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
-                                       connection_->transport_version()),
-                                   _, _, NO_FIN, _, _))
-      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  InSequence s;
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
-      new MockAckListener());
-
-  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
-  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
-  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-
-  // Frame 1 is retransmitted.
-  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
-  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
-  headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
-
-  // Frames are acked in order: 2, 3, 1.
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(2, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      17, 13, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(13u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      30, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(12u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(14, _));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(3, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      0, 17, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(17u, newly_acked_length);
-}
-
-TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
-  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
-                                       connection_->transport_version()),
-                                   _, _, NO_FIN, _, _))
-      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  InSequence s;
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
-      new MockAckListener());
-
-  // Send [0, 42).
-  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
-  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
-  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
-  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
-
-  // Ack [15, 20), [5, 25), [10, 17), [0, 12) and [22, 42).
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      15, 5, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(5u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(9, _));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(4, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      5, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(15u, newly_acked_length);
-
-  // Duplicate ack.
-  EXPECT_FALSE(headers_stream_->OnStreamFrameAcked(
-      10, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(0u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      0, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(5u, newly_acked_length);
-
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(3, _));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
-  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
-  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
-      22, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
-      &newly_acked_length));
-  EXPECT_EQ(17u, newly_acked_length);
-}
-
-TEST_P(QuicHeadersStreamTest, CloseOnPushPromiseToServer) {
-  if (perspective() == Perspective::IS_CLIENT) {
-    return;
-  }
-  QuicStreamId promised_id = 1;
-  SpdyPushPromiseIR push_promise(client_id_1_, promised_id, headers_.Clone());
-  SpdySerializedFrame frame = framer_->SerializeFrame(push_promise);
-  stream_frame_.data_buffer = frame.data();
-  stream_frame_.data_length = frame.size();
-  EXPECT_CALL(session_, OnStreamHeaderList(_, _, _, _));
-  // TODO(lassey): Check for HTTP_WRONG_STREAM error code.
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                            "PUSH_PROMISE not supported.", _));
-  headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_receive_control_stream.cc b/quic/core/http/quic_receive_control_stream.cc
deleted file mode 100644
index 456d847..0000000
--- a/quic/core/http/quic_receive_control_stream.cc
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_receive_control_stream.h"
-
-#include <utility>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-QuicReceiveControlStream::QuicReceiveControlStream(
-    PendingStream* pending,
-    QuicSpdySession* spdy_session)
-    : QuicStream(pending,
-                 spdy_session,
-                 /*is_static=*/true),
-      settings_frame_received_(false),
-      decoder_(this),
-      spdy_session_(spdy_session) {
-  sequencer()->set_level_triggered(true);
-}
-
-QuicReceiveControlStream::~QuicReceiveControlStream() {}
-
-void QuicReceiveControlStream::OnStreamReset(
-    const QuicRstStreamFrame& /*frame*/) {
-  stream_delegate()->OnStreamError(
-      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-      "RESET_STREAM received for receive control stream");
-}
-
-void QuicReceiveControlStream::OnDataAvailable() {
-  iovec iov;
-  while (!reading_stopped() && decoder_.error() == QUIC_NO_ERROR &&
-         sequencer()->GetReadableRegion(&iov)) {
-    QUICHE_DCHECK(!sequencer()->IsClosed());
-
-    QuicByteCount processed_bytes = decoder_.ProcessInput(
-        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
-    sequencer()->MarkConsumed(processed_bytes);
-
-    if (!session()->connection()->connected()) {
-      return;
-    }
-
-    // The only reason QuicReceiveControlStream pauses HttpDecoder is an error,
-    // in which case the connection would have already been closed.
-    QUICHE_DCHECK_EQ(iov.iov_len, processed_bytes);
-  }
-}
-
-void QuicReceiveControlStream::OnError(HttpDecoder* decoder) {
-  stream_delegate()->OnStreamError(decoder->error(), decoder->error_detail());
-}
-
-bool QuicReceiveControlStream::OnMaxPushIdFrame(const MaxPushIdFrame& frame) {
-  if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_ignore_max_push_id);
-    return ValidateFrameType(HttpFrameType::MAX_PUSH_ID);
-  }
-
-  if (spdy_session()->debug_visitor()) {
-    spdy_session()->debug_visitor()->OnMaxPushIdFrameReceived(frame);
-  }
-
-  if (!ValidateFrameType(HttpFrameType::MAX_PUSH_ID)) {
-    return false;
-  }
-
-  return spdy_session()->OnMaxPushIdFrame(frame.push_id);
-}
-
-bool QuicReceiveControlStream::OnGoAwayFrame(const GoAwayFrame& frame) {
-  if (spdy_session()->debug_visitor()) {
-    spdy_session()->debug_visitor()->OnGoAwayFrameReceived(frame);
-  }
-
-  if (!ValidateFrameType(HttpFrameType::GOAWAY)) {
-    return false;
-  }
-
-  spdy_session()->OnHttp3GoAway(frame.id);
-  return true;
-}
-
-bool QuicReceiveControlStream::OnSettingsFrameStart(
-    QuicByteCount /*header_length*/) {
-  return ValidateFrameType(HttpFrameType::SETTINGS);
-}
-
-bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& frame) {
-  QUIC_DVLOG(1) << "Control Stream " << id()
-                << " received settings frame: " << frame;
-  return spdy_session_->OnSettingsFrame(frame);
-}
-
-bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/,
-                                                QuicByteCount
-                                                /*payload_length*/) {
-  return ValidateFrameType(HttpFrameType::DATA);
-}
-
-bool QuicReceiveControlStream::OnDataFramePayload(
-    absl::string_view /*payload*/) {
-  QUICHE_NOTREACHED();
-  return false;
-}
-
-bool QuicReceiveControlStream::OnDataFrameEnd() {
-  QUICHE_NOTREACHED();
-  return false;
-}
-
-bool QuicReceiveControlStream::OnHeadersFrameStart(
-    QuicByteCount /*header_length*/,
-    QuicByteCount
-    /*payload_length*/) {
-  return ValidateFrameType(HttpFrameType::HEADERS);
-}
-
-bool QuicReceiveControlStream::OnHeadersFramePayload(
-    absl::string_view /*payload*/) {
-  QUICHE_NOTREACHED();
-  return false;
-}
-
-bool QuicReceiveControlStream::OnHeadersFrameEnd() {
-  QUICHE_NOTREACHED();
-  return false;
-}
-
-bool QuicReceiveControlStream::OnPriorityUpdateFrameStart(
-    QuicByteCount /*header_length*/) {
-  return ValidateFrameType(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
-}
-
-bool QuicReceiveControlStream::OnPriorityUpdateFrame(
-    const PriorityUpdateFrame& frame) {
-  if (spdy_session()->debug_visitor()) {
-    spdy_session()->debug_visitor()->OnPriorityUpdateFrameReceived(frame);
-  }
-
-  // TODO(b/147306124): Use a proper structured headers parser instead.
-  for (absl::string_view key_value :
-       absl::StrSplit(frame.priority_field_value, ',')) {
-    std::vector<absl::string_view> key_and_value =
-        absl::StrSplit(key_value, '=');
-    if (key_and_value.size() != 2) {
-      continue;
-    }
-
-    absl::string_view key = key_and_value[0];
-    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&key);
-    if (key != "u") {
-      continue;
-    }
-
-    absl::string_view value = key_and_value[1];
-    int urgency;
-    if (!absl::SimpleAtoi(value, &urgency) || urgency < 0 || urgency > 7) {
-      stream_delegate()->OnStreamError(
-          QUIC_INVALID_PRIORITY_UPDATE,
-          "Invalid value for PRIORITY_UPDATE urgency parameter.");
-      return false;
-    }
-
-    if (frame.prioritized_element_type == REQUEST_STREAM) {
-      return spdy_session_->OnPriorityUpdateForRequestStream(
-          frame.prioritized_element_id, urgency);
-    } else {
-      return spdy_session_->OnPriorityUpdateForPushStream(
-          frame.prioritized_element_id, urgency);
-    }
-  }
-
-  // Ignore frame if no urgency parameter can be parsed.
-  return true;
-}
-
-bool QuicReceiveControlStream::OnAcceptChFrameStart(
-    QuicByteCount /* header_length */) {
-  return ValidateFrameType(HttpFrameType::ACCEPT_CH);
-}
-
-bool QuicReceiveControlStream::OnAcceptChFrame(const AcceptChFrame& frame) {
-  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, spdy_session()->perspective());
-
-  if (spdy_session()->debug_visitor()) {
-    spdy_session()->debug_visitor()->OnAcceptChFrameReceived(frame);
-  }
-
-  spdy_session()->OnAcceptChFrame(frame);
-  return true;
-}
-
-void QuicReceiveControlStream::OnWebTransportStreamFrameType(
-    QuicByteCount /*header_length*/,
-    WebTransportSessionId /*session_id*/) {
-  QUIC_BUG(WEBTRANSPORT_STREAM on Control Stream)
-      << "Parsed WEBTRANSPORT_STREAM on a control stream.";
-}
-
-bool QuicReceiveControlStream::OnUnknownFrameStart(
-    uint64_t frame_type,
-    QuicByteCount /*header_length*/,
-    QuicByteCount payload_length) {
-  if (spdy_session()->debug_visitor()) {
-    spdy_session()->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
-                                                            payload_length);
-  }
-
-  return ValidateFrameType(static_cast<HttpFrameType>(frame_type));
-}
-
-bool QuicReceiveControlStream::OnUnknownFramePayload(
-    absl::string_view /*payload*/) {
-  // Ignore unknown frame types.
-  return true;
-}
-
-bool QuicReceiveControlStream::OnUnknownFrameEnd() {
-  // Ignore unknown frame types.
-  return true;
-}
-
-bool QuicReceiveControlStream::ValidateFrameType(HttpFrameType frame_type) {
-  // Certain frame types are forbidden.
-  if (frame_type == HttpFrameType::DATA ||
-      frame_type == HttpFrameType::HEADERS ||
-      (spdy_session()->perspective() == Perspective::IS_CLIENT &&
-       frame_type == HttpFrameType::MAX_PUSH_ID) ||
-      (spdy_session()->perspective() == Perspective::IS_SERVER &&
-       frame_type == HttpFrameType::ACCEPT_CH)) {
-    stream_delegate()->OnStreamError(
-        QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
-        absl::StrCat("Invalid frame type ", static_cast<int>(frame_type),
-                     " received on control stream."));
-    return false;
-  }
-
-  if (settings_frame_received_) {
-    if (frame_type == HttpFrameType::SETTINGS) {
-      // SETTINGS frame may only be the first frame on the control stream.
-      stream_delegate()->OnStreamError(
-          QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
-          "SETTINGS frame can only be received once.");
-      return false;
-    }
-    return true;
-  }
-
-  if (frame_type == HttpFrameType::SETTINGS) {
-    settings_frame_received_ = true;
-    return true;
-  }
-  stream_delegate()->OnStreamError(
-      QUIC_HTTP_MISSING_SETTINGS_FRAME,
-      absl::StrCat("First frame received on control stream is type ",
-                   static_cast<int>(frame_type), ", but it must be SETTINGS."));
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_receive_control_stream.h b/quic/core/http/quic_receive_control_stream.h
deleted file mode 100644
index 3c61d3c..0000000
--- a/quic/core/http/quic_receive_control_stream.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
-
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicSpdySession;
-
-// 3.2.1 Control Stream.
-// The receive control stream is peer initiated and is read only.
-class QUIC_EXPORT_PRIVATE QuicReceiveControlStream
-    : public QuicStream,
-      public HttpDecoder::Visitor {
- public:
-  explicit QuicReceiveControlStream(PendingStream* pending,
-                                    QuicSpdySession* spdy_session);
-  QuicReceiveControlStream(const QuicReceiveControlStream&) = delete;
-  QuicReceiveControlStream& operator=(const QuicReceiveControlStream&) = delete;
-  ~QuicReceiveControlStream() override;
-
-  // Overriding QuicStream::OnStreamReset to make sure control stream is never
-  // closed before connection.
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
-  // Implementation of QuicStream.
-  void OnDataAvailable() override;
-
-  // HttpDecoder::Visitor implementation.
-  void OnError(HttpDecoder* decoder) override;
-  bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override;
-  bool OnGoAwayFrame(const GoAwayFrame& frame) override;
-  bool OnSettingsFrameStart(QuicByteCount header_length) override;
-  bool OnSettingsFrame(const SettingsFrame& frame) override;
-  bool OnDataFrameStart(QuicByteCount header_length,
-                        QuicByteCount payload_length) override;
-  bool OnDataFramePayload(absl::string_view payload) override;
-  bool OnDataFrameEnd() override;
-  bool OnHeadersFrameStart(QuicByteCount header_length,
-                           QuicByteCount payload_length) override;
-  bool OnHeadersFramePayload(absl::string_view payload) override;
-  bool OnHeadersFrameEnd() override;
-  bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override;
-  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override;
-  bool OnAcceptChFrameStart(QuicByteCount header_length) override;
-  bool OnAcceptChFrame(const AcceptChFrame& frame) override;
-  void OnWebTransportStreamFrameType(QuicByteCount header_length,
-                                     WebTransportSessionId session_id) override;
-  bool OnUnknownFrameStart(uint64_t frame_type,
-                           QuicByteCount header_length,
-                           QuicByteCount payload_length) override;
-  bool OnUnknownFramePayload(absl::string_view payload) override;
-  bool OnUnknownFrameEnd() override;
-
-  QuicSpdySession* spdy_session() { return spdy_session_; }
-
- private:
-  // Called when a frame of allowed type is received.  Returns true if the frame
-  // is allowed in this position.  Returns false and resets the stream
-  // otherwise.
-  bool ValidateFrameType(HttpFrameType frame_type);
-
-  // False until a SETTINGS frame is received.
-  bool settings_frame_received_;
-
-  HttpDecoder decoder_;
-  QuicSpdySession* const spdy_session_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
diff --git a/quic/core/http/quic_receive_control_stream_test.cc b/quic/core/http/quic_receive_control_stream_test.cc
deleted file mode 100644
index 4fc2ddf..0000000
--- a/quic/core/http/quic_receive_control_stream_test.cc
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_receive_control_stream.h"
-
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-
-class QpackEncoder;
-
-namespace test {
-
-namespace {
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::StrictMock;
-
-struct TestParams {
-  TestParams(const ParsedQuicVersion& version, Perspective perspective)
-      : version(version), perspective(perspective) {
-    QUIC_LOG(INFO) << "TestParams: " << *this;
-  }
-
-  TestParams(const TestParams& other)
-      : version(other.version), perspective(other.perspective) {}
-
-  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
-    os << "{ version: " << ParsedQuicVersionToString(tp.version)
-       << ", perspective: "
-       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
-       << "}";
-    return os;
-  }
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(tp.version), "_",
-      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (const auto& version : AllSupportedVersions()) {
-    if (!VersionUsesHttp3(version.transport_version)) {
-      continue;
-    }
-    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
-      params.emplace_back(version, p);
-    }
-  }
-  return params;
-}
-
-class TestStream : public QuicSpdyStream {
- public:
-  TestStream(QuicStreamId id, QuicSpdySession* session)
-      : QuicSpdyStream(id, session, BIDIRECTIONAL) {}
-  ~TestStream() override = default;
-
-  void OnBodyAvailable() override {}
-};
-
-class QuicReceiveControlStreamTest : public QuicTestWithParam<TestParams> {
- public:
-  QuicReceiveControlStreamTest()
-      : connection_(new StrictMock<MockQuicConnection>(
-            &helper_,
-            &alarm_factory_,
-            perspective(),
-            SupportedVersions(GetParam().version))),
-        session_(connection_) {
-    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    session_.Initialize();
-    QuicStreamId id = perspective() == Perspective::IS_SERVER
-                          ? GetNthClientInitiatedUnidirectionalStreamId(
-                                session_.transport_version(), 3)
-                          : GetNthServerInitiatedUnidirectionalStreamId(
-                                session_.transport_version(), 3);
-    char type[] = {kControlStream};
-
-    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
-    session_.OnStreamFrame(data1);
-
-    receive_control_stream_ =
-        QuicSpdySessionPeer::GetReceiveControlStream(&session_);
-
-    stream_ = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
-                                 GetParam().version.transport_version, 0),
-                             &session_);
-    session_.ActivateStream(absl::WrapUnique(stream_));
-  }
-
-  Perspective perspective() const { return GetParam().perspective; }
-
-  std::string EncodeSettings(const SettingsFrame& settings) {
-    std::unique_ptr<char[]> buffer;
-    QuicByteCount settings_frame_length =
-        HttpEncoder::SerializeSettingsFrame(settings, &buffer);
-    return std::string(buffer.get(), settings_frame_length);
-  }
-
-  std::string SerializePriorityUpdateFrame(
-      const PriorityUpdateFrame& priority_update) {
-    std::unique_ptr<char[]> priority_buffer;
-    QuicByteCount priority_frame_length =
-        HttpEncoder::SerializePriorityUpdateFrame(priority_update,
-                                                  &priority_buffer);
-    return std::string(priority_buffer.get(), priority_frame_length);
-  }
-
-  QuicStreamOffset NumBytesConsumed() {
-    return QuicStreamPeer::sequencer(receive_control_stream_)
-        ->NumBytesConsumed();
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  StrictMock<MockQuicSpdySession> session_;
-  QuicReceiveControlStream* receive_control_stream_;
-  TestStream* stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicReceiveControlStreamTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicReceiveControlStreamTest, ResetControlStream) {
-  EXPECT_TRUE(receive_control_stream_->is_static());
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
-                               receive_control_stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
-  receive_control_stream_->OnStreamReset(rst_frame);
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveSettings) {
-  SettingsFrame settings;
-  settings.values[10] = 2;
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 12;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 37;
-  std::string data = EncodeSettings(settings);
-  QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data);
-
-  QpackEncoder* qpack_encoder = session_.qpack_encoder();
-  QpackEncoderHeaderTable* header_table =
-      QpackEncoderPeer::header_table(qpack_encoder);
-  EXPECT_EQ(std::numeric_limits<size_t>::max(),
-            session_.max_outbound_header_list_size());
-  EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-  EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
-
-  receive_control_stream_->OnStreamFrame(frame);
-
-  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-  EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-  EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
-}
-
-// Regression test for https://crbug.com/982648.
-// QuicReceiveControlStream::OnDataAvailable() must stop processing input as
-// soon as OnSettingsFrameStart() is called by HttpDecoder for the second frame.
-TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsTwice) {
-  SettingsFrame settings;
-  // Reserved identifiers, must be ignored.
-  settings.values[0x21] = 100;
-  settings.values[0x40] = 200;
-
-  std::string settings_frame = EncodeSettings(settings);
-
-  QuicStreamOffset offset = 1;
-  EXPECT_EQ(offset, NumBytesConsumed());
-
-  // Receive first SETTINGS frame.
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
-                      settings_frame));
-  offset += settings_frame.length();
-
-  // First SETTINGS frame is consumed.
-  EXPECT_EQ(offset, NumBytesConsumed());
-
-  // Second SETTINGS frame causes the connection to be closed.
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
-                      "SETTINGS frame can only be received once.", _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
-  // Receive second SETTINGS frame.
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
-                      settings_frame));
-
-  // Frame header of second SETTINGS frame is consumed, but not frame payload.
-  QuicByteCount settings_frame_header_length = 2;
-  EXPECT_EQ(offset + settings_frame_header_length, NumBytesConsumed());
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsFragments) {
-  SettingsFrame settings;
-  settings.values[10] = 2;
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  std::string data = EncodeSettings(settings);
-  std::string data1 = data.substr(0, 1);
-  std::string data2 = data.substr(1, data.length() - 1);
-
-  QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data1);
-  QuicStreamFrame frame2(receive_control_stream_->id(), false, 2, data2);
-  EXPECT_NE(5u, session_.max_outbound_header_list_size());
-  receive_control_stream_->OnStreamFrame(frame);
-  receive_control_stream_->OnStreamFrame(frame2);
-  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveWrongFrame) {
-  // DATA frame header without payload.
-  quiche::QuicheBuffer data = HttpEncoder::SerializeDataFrameHeader(
-      /* payload_length = */ 2, quiche::SimpleBufferAllocator::Get());
-
-  QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
-                        data.AsStringView());
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM, _, _));
-  receive_control_stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicReceiveControlStreamTest,
-       ReceivePriorityUpdateFrameBeforeSettingsFrame) {
-  std::string serialized_frame = SerializePriorityUpdateFrame({});
-  QuicStreamFrame data(receive_control_stream_->id(), /* fin = */ false,
-                       /* offset = */ 1, serialized_frame);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
-                              "First frame received on control stream is type "
-                              "984832, but it must be SETTINGS.",
-                              _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
-  receive_control_stream_->OnStreamFrame(data);
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveGoAwayFrame) {
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  QuicStreamOffset offset = 1;
-
-  // Receive SETTINGS frame.
-  SettingsFrame settings;
-  std::string settings_frame = EncodeSettings(settings);
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
-                      settings_frame));
-  offset += settings_frame.length();
-
-  GoAwayFrame goaway{/* id = */ 0};
-
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount header_length =
-      HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
-  std::string data = std::string(buffer.get(), header_length);
-
-  QuicStreamFrame frame(receive_control_stream_->id(), false, offset, data);
-  EXPECT_FALSE(session_.goaway_received());
-
-  EXPECT_CALL(debug_visitor, OnGoAwayFrameReceived(goaway));
-
-  receive_control_stream_->OnStreamFrame(frame);
-  EXPECT_TRUE(session_.goaway_received());
-}
-
-TEST_P(QuicReceiveControlStreamTest, PushPromiseOnControlStreamShouldClose) {
-  std::string push_promise_frame = absl::HexStringToBytes(
-      "05"    // PUSH_PROMISE
-      "01"    // length
-      "00");  // push ID
-  QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
-                        push_promise_frame);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(session_, OnConnectionClosed(_, _));
-  receive_control_stream_->OnStreamFrame(frame);
-}
-
-// Regression test for b/137554973: unknown frames should be consumed.
-TEST_P(QuicReceiveControlStreamTest, ConsumeUnknownFrame) {
-  EXPECT_EQ(1u, NumBytesConsumed());
-
-  QuicStreamOffset offset = 1;
-
-  // Receive SETTINGS frame.
-  std::string settings_frame = EncodeSettings({});
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
-                      settings_frame));
-  offset += settings_frame.length();
-
-  // SETTINGS frame is consumed.
-  EXPECT_EQ(offset, NumBytesConsumed());
-
-  // Receive unknown frame.
-  std::string unknown_frame = absl::HexStringToBytes(
-      "21"        // reserved frame type
-      "03"        // payload length
-      "666f6f");  // payload "foo"
-
-  receive_control_stream_->OnStreamFrame(QuicStreamFrame(
-      receive_control_stream_->id(), /* fin = */ false, offset, unknown_frame));
-  offset += unknown_frame.size();
-
-  // Unknown frame is consumed.
-  EXPECT_EQ(offset, NumBytesConsumed());
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveUnknownFrame) {
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  const QuicStreamId id = receive_control_stream_->id();
-  QuicStreamOffset offset = 1;
-
-  // Receive SETTINGS frame.
-  SettingsFrame settings;
-  std::string settings_frame = EncodeSettings(settings);
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
-  offset += settings_frame.length();
-
-  // Receive unknown frame.
-  std::string unknown_frame = absl::HexStringToBytes(
-      "21"        // reserved frame type
-      "03"        // payload length
-      "666f6f");  // payload "foo"
-
-  EXPECT_CALL(debug_visitor, OnUnknownFrameReceived(id, /* frame_type = */ 0x21,
-                                                    /* payload_length = */ 3));
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(id, /* fin = */ false, offset, unknown_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) {
-  std::string cancel_push_frame = absl::HexStringToBytes(
-      "03"    // type CANCEL_PUSH
-      "01"    // payload length
-      "01");  // push ID
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
-                                            "CANCEL_PUSH frame received.", _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
-                      /* offset = */ 1, cancel_push_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, AcceptChFrameBeforeSettings) {
-  std::string accept_ch_frame = absl::HexStringToBytes(
-      "4089"  // type (ACCEPT_CH)
-      "00");  // length
-
-  if (perspective() == Perspective::IS_SERVER) {
-    EXPECT_CALL(*connection_,
-                CloseConnection(
-                    QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
-                    "Invalid frame type 137 received on control stream.", _))
-        .WillOnce(
-            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  } else {
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
-                                "First frame received on control stream is "
-                                "type 137, but it must be SETTINGS.",
-                                _))
-        .WillOnce(
-            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  }
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
-                      /* offset = */ 1, accept_ch_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, ReceiveAcceptChFrame) {
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  const QuicStreamId id = receive_control_stream_->id();
-  QuicStreamOffset offset = 1;
-
-  // Receive SETTINGS frame.
-  SettingsFrame settings;
-  std::string settings_frame = EncodeSettings(settings);
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
-  offset += settings_frame.length();
-
-  // Receive ACCEPT_CH frame.
-  std::string accept_ch_frame = absl::HexStringToBytes(
-      "4089"  // type (ACCEPT_CH)
-      "00");  // length
-
-  if (perspective() == Perspective::IS_CLIENT) {
-    EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(_));
-  } else {
-    EXPECT_CALL(*connection_,
-                CloseConnection(
-                    QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
-                    "Invalid frame type 137 received on control stream.", _))
-        .WillOnce(
-            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-    EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-    EXPECT_CALL(session_, OnConnectionClosed(_, _));
-  }
-
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(id, /* fin = */ false, offset, accept_ch_frame));
-}
-
-TEST_P(QuicReceiveControlStreamTest, UnknownFrameBeforeSettings) {
-  std::string unknown_frame = absl::HexStringToBytes(
-      "21"        // reserved frame type
-      "03"        // payload length
-      "666f6f");  // payload "foo"
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
-                              "First frame received on control stream is type "
-                              "33, but it must be SETTINGS.",
-                              _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(session_, OnConnectionClosed(_, _));
-
-  receive_control_stream_->OnStreamFrame(
-      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
-                      /* offset = */ 1, unknown_frame));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_send_control_stream.cc b/quic/core/http/quic_send_control_stream.cc
deleted file mode 100644
index 92831f2..0000000
--- a/quic/core/http/quic_send_control_stream.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_send_control_stream.h"
-#include <cstdint>
-#include <memory>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSendControlStream::QuicSendControlStream(QuicStreamId id,
-                                             QuicSpdySession* spdy_session,
-                                             const SettingsFrame& settings)
-    : QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
-      settings_sent_(false),
-      settings_(settings),
-      spdy_session_(spdy_session) {}
-
-void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
-  QUIC_BUG(quic_bug_10382_1)
-      << "OnStreamReset() called for write unidirectional stream.";
-}
-
-bool QuicSendControlStream::OnStopSending(QuicResetStreamError /* code */) {
-  stream_delegate()->OnStreamError(
-      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-      "STOP_SENDING received for send control stream");
-  return false;
-}
-
-void QuicSendControlStream::MaybeSendSettingsFrame() {
-  if (settings_sent_) {
-    return;
-  }
-
-  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-  // Send the stream type on so the peer knows about this stream.
-  char data[sizeof(kControlStream)];
-  QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
-  writer.WriteVarInt62(kControlStream);
-  WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
-                    nullptr);
-
-  SettingsFrame settings = settings_;
-  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1
-  // specifies that setting identifiers of 0x1f * N + 0x21 are reserved and
-  // greasing should be attempted.
-  if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
-    settings.values[0x40] = 20;
-  } else {
-    uint32_t result;
-    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
-    uint64_t setting_id = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
-    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
-    settings.values[setting_id] = result;
-  }
-
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount frame_length =
-      HttpEncoder::SerializeSettingsFrame(settings, &buffer);
-  QUIC_DVLOG(1) << "Control stream " << id() << " is writing settings frame "
-                << settings;
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnSettingsFrameSent(settings);
-  }
-  WriteOrBufferData(absl::string_view(buffer.get(), frame_length),
-                    /*fin = */ false, nullptr);
-  settings_sent_ = true;
-
-  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9
-  // specifies that a reserved frame type has no semantic meaning and should be
-  // discarded. A greasing frame is added here.
-  std::unique_ptr<char[]> grease;
-  QuicByteCount grease_length = HttpEncoder::SerializeGreasingFrame(&grease);
-  WriteOrBufferData(absl::string_view(grease.get(), grease_length),
-                    /*fin = */ false, nullptr);
-}
-
-void QuicSendControlStream::WritePriorityUpdate(
-    const PriorityUpdateFrame& priority_update) {
-  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-  MaybeSendSettingsFrame();
-
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnPriorityUpdateFrameSent(priority_update);
-  }
-
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount frame_length =
-      HttpEncoder::SerializePriorityUpdateFrame(priority_update, &buffer);
-  QUIC_DVLOG(1) << "Control Stream " << id() << " is writing "
-                << priority_update;
-  WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
-                    nullptr);
-}
-
-void QuicSendControlStream::SendGoAway(QuicStreamId id) {
-  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-  MaybeSendSettingsFrame();
-
-  GoAwayFrame frame;
-  frame.id = id;
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnGoAwayFrameSent(id);
-  }
-
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount frame_length =
-      HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
-  WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
-                    nullptr);
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_send_control_stream.h b/quic/core/http/quic_send_control_stream.h
deleted file mode 100644
index d376a63..0000000
--- a/quic/core/http/quic_send_control_stream.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
-
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-class QuicSpdySession;
-
-// 6.2.1 Control Stream.
-// The send control stream is self initiated and is write only.
-class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
- public:
-  // |session| can't be nullptr, and the ownership is not passed. The stream can
-  // only be accessed through the session.
-  QuicSendControlStream(QuicStreamId id,
-                        QuicSpdySession* session,
-                        const SettingsFrame& settings);
-  QuicSendControlStream(const QuicSendControlStream&) = delete;
-  QuicSendControlStream& operator=(const QuicSendControlStream&) = delete;
-  ~QuicSendControlStream() override = default;
-
-  // Overriding QuicStream::OnStopSending() to make sure control stream is never
-  // closed before connection.
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-  bool OnStopSending(QuicResetStreamError code) override;
-
-  // Send SETTINGS frame if it hasn't been sent yet. Settings frame must be the
-  // first frame sent on this stream.
-  void MaybeSendSettingsFrame();
-
-  // Send a PRIORITY_UPDATE frame on this stream, and a SETTINGS frame
-  // beforehand if one has not been already sent.
-  void WritePriorityUpdate(const PriorityUpdateFrame& priority_update);
-
-  // Send a GOAWAY frame on this stream, and a SETTINGS frame beforehand if one
-  // has not been already sent.
-  void SendGoAway(QuicStreamId id);
-
-  // The send control stream is write unidirectional, so this method should
-  // never be called.
-  void OnDataAvailable() override { QUIC_NOTREACHED(); }
-
- private:
-  // Track if a settings frame is already sent.
-  bool settings_sent_;
-
-  // SETTINGS values to send.
-  const SettingsFrame settings_;
-
-  QuicSpdySession* const spdy_session_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
diff --git a/quic/core/http/quic_send_control_stream_test.cc b/quic/core/http/quic_send_control_stream_test.cc
deleted file mode 100644
index fa1e584..0000000
--- a/quic/core/http/quic_send_control_stream_test.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_send_control_stream.h"
-
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-
-struct TestParams {
-  TestParams(const ParsedQuicVersion& version, Perspective perspective)
-      : version(version), perspective(perspective) {
-    QUIC_LOG(INFO) << "TestParams: " << *this;
-  }
-
-  TestParams(const TestParams& other)
-      : version(other.version), perspective(other.perspective) {}
-
-  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
-    os << "{ version: " << ParsedQuicVersionToString(tp.version)
-       << ", perspective: "
-       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
-       << "}";
-    return os;
-  }
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(tp.version), "_",
-      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (const auto& version : AllSupportedVersions()) {
-    if (!VersionUsesHttp3(version.transport_version)) {
-      continue;
-    }
-    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
-      params.emplace_back(version, p);
-    }
-  }
-  return params;
-}
-
-class QuicSendControlStreamTest : public QuicTestWithParam<TestParams> {
- public:
-  QuicSendControlStreamTest()
-      : connection_(new StrictMock<MockQuicConnection>(
-            &helper_, &alarm_factory_, perspective(),
-            SupportedVersions(GetParam().version))),
-        session_(connection_) {
-    ON_CALL(session_, WritevData(_, _, _, _, _, _))
-        .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  }
-
-  void Initialize() {
-    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    session_.Initialize();
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_);
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
-    session_.OnConfigNegotiated();
-  }
-
-  Perspective perspective() const { return GetParam().perspective; }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  StrictMock<MockQuicSpdySession> session_;
-  QuicSendControlStream* send_control_stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSendControlStreamTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSendControlStreamTest, WriteSettings) {
-  SetQuicFlag(FLAGS_quic_enable_http3_grease_randomness, false);
-  session_.set_qpack_maximum_dynamic_table_capacity(255);
-  session_.set_qpack_maximum_blocked_streams(16);
-  session_.set_max_inbound_header_list_size(1024);
-
-  Initialize();
-  testing::InSequence s;
-
-  std::string expected_write_data = absl::HexStringToBytes(
-      "00"    // stream type: control stream
-      "04"    // frame type: SETTINGS frame
-      "0b"    // frame length
-      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-      "40ff"  // 255
-      "06"    // SETTINGS_MAX_HEADER_LIST_SIZE
-      "4400"  // 1024
-      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
-      "10"    // 16
-      "4040"  // 0x40 as the reserved settings id
-      "14"    // 20
-      "4040"  // 0x40 as the reserved frame type
-      "01"    // 1 byte frame length
-      "61");  //  payload "a"
-  if ((!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
-       perspective() == Perspective::IS_CLIENT) &&
-      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
-          HttpDatagramSupport::kDraft00And04) {
-    expected_write_data = absl::HexStringToBytes(
-        "00"         // stream type: control stream
-        "04"         // frame type: SETTINGS frame
-        "0e"         // frame length
-        "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-        "40ff"       // 255
-        "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
-        "4400"       // 1024
-        "07"         // SETTINGS_QPACK_BLOCKED_STREAMS
-        "10"         // 16
-        "4040"       // 0x40 as the reserved settings id
-        "14"         // 20
-        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
-        "01"         // 1
-        "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
-        "01"         // 1
-        "4040"       // 0x40 as the reserved frame type
-        "01"         // 1 byte frame length
-        "61");       //  payload "a"
-  }
-  if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
-      perspective() == Perspective::IS_SERVER &&
-      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
-          HttpDatagramSupport::kNone) {
-    expected_write_data = absl::HexStringToBytes(
-        "00"    // stream type: control stream
-        "04"    // frame type: SETTINGS frame
-        "0d"    // frame length
-        "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-        "40ff"  // 255
-        "06"    // SETTINGS_MAX_HEADER_LIST_SIZE
-        "4400"  // 1024
-        "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
-        "10"    // 16
-        "08"    // SETTINGS_ENABLE_CONNECT_PROTOCOL
-        "01"    // 1
-        "4040"  // 0x40 as the reserved settings id
-        "14"    // 20
-        "4040"  // 0x40 as the reserved frame type
-        "01"    // 1 byte frame length
-        "61");  //  payload "a"
-  }
-  if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
-      perspective() == Perspective::IS_SERVER &&
-      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) !=
-          HttpDatagramSupport::kNone) {
-    expected_write_data = absl::HexStringToBytes(
-        "00"         // stream type: control stream
-        "04"         // frame type: SETTINGS frame
-        "11"         // frame length
-        "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-        "40ff"       // 255
-        "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
-        "4400"       // 1024
-        "07"         // SETTINGS_QPACK_BLOCKED_STREAMS
-        "10"         // 16
-        "08"         // SETTINGS_ENABLE_CONNECT_PROTOCOL
-        "01"         // 1
-        "4040"       // 0x40 as the reserved settings id
-        "14"         // 20
-        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
-        "01"         // 1
-        "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
-        "01"         // 1
-        "4040"       // 0x40 as the reserved frame type
-        "01"         // 1 byte frame length
-        "61");       //  payload "a"
-  }
-
-  auto buffer = std::make_unique<char[]>(expected_write_data.size());
-  QuicDataWriter writer(expected_write_data.size(), buffer.get());
-
-  // A lambda to save and consume stream data when QuicSession::WritevData() is
-  // called.
-  auto save_write_data =
-      [&writer, this](QuicStreamId /*id*/, size_t write_length,
-                      QuicStreamOffset offset, StreamSendingState /*state*/,
-                      TransmissionType /*type*/,
-                      absl::optional<EncryptionLevel> /*level*/) {
-        send_control_stream_->WriteStreamData(offset, write_length, &writer);
-        return QuicConsumedData(/* bytes_consumed = */ write_length,
-                                /* fin_consumed = */ false);
-      };
-
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _))
-      .WillOnce(Invoke(save_write_data));
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(),
-                                   expected_write_data.size() - 5, _, _, _, _))
-      .WillOnce(Invoke(save_write_data));
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 4, _, _, _, _))
-      .WillOnce(Invoke(save_write_data));
-
-  send_control_stream_->MaybeSendSettingsFrame();
-  quiche::test::CompareCharArraysWithHexError(
-      "settings", writer.data(), writer.length(), expected_write_data.data(),
-      expected_write_data.length());
-}
-
-TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyOnce) {
-  Initialize();
-  testing::InSequence s;
-
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _));
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
-      .Times(2);
-  send_control_stream_->MaybeSendSettingsFrame();
-
-  // No data should be written the second time MaybeSendSettingsFrame() is
-  // called.
-  send_control_stream_->MaybeSendSettingsFrame();
-}
-
-// Send stream type and SETTINGS frame if WritePriorityUpdate() is called first.
-TEST_P(QuicSendControlStreamTest, WritePriorityBeforeSettings) {
-  Initialize();
-  testing::InSequence s;
-
-  // The first write will trigger the control stream to write stream type, a
-  // SETTINGS frame, and a greased frame before the PRIORITY_UPDATE frame.
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
-      .Times(4);
-  PriorityUpdateFrame frame;
-  send_control_stream_->WritePriorityUpdate(frame);
-
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _));
-  send_control_stream_->WritePriorityUpdate(frame);
-}
-
-TEST_P(QuicSendControlStreamTest, CloseControlStream) {
-  Initialize();
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
-  send_control_stream_->OnStopSending(
-      QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QuicSendControlStreamTest, ReceiveDataOnSendControlStream) {
-  Initialize();
-  QuicStreamFrame frame(send_control_stream_->id(), false, 0, "test");
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
-  send_control_stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSendControlStreamTest, SendGoAway) {
-  Initialize();
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  QuicStreamId stream_id = 4;
-
-  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
-  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(stream_id));
-
-  send_control_stream_->SendGoAway(stream_id);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_server_initiated_spdy_stream.cc b/quic/core/http/quic_server_initiated_spdy_stream.cc
deleted file mode 100644
index 2a227a7..0000000
--- a/quic/core/http/quic_server_initiated_spdy_stream.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_server_initiated_spdy_stream.h"
-#include "quic/core/quic_error_codes.h"
-
-namespace quic {
-
-void QuicServerInitiatedSpdyStream::OnBodyAvailable() {
-  QUIC_BUG(Body received in QuicServerInitiatedSpdyStream)
-      << "Received body data in QuicServerInitiatedSpdyStream.";
-  OnUnrecoverableError(
-      QUIC_INTERNAL_ERROR,
-      "Received HTTP/3 body data in a server-initiated bidirectional stream");
-}
-
-size_t QuicServerInitiatedSpdyStream::WriteHeaders(
-    spdy::SpdyHeaderBlock /*header_block*/, bool /*fin*/,
-    quiche::QuicheReferenceCountedPointer<
-        QuicAckListenerInterface> /*ack_listener*/) {
-  QUIC_BUG(Writing headers in QuicServerInitiatedSpdyStream)
-      << "Attempting to write headers in QuicServerInitiatedSpdyStream";
-  OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                       "Attempted to send HTTP/3 headers in a server-initiated "
-                       "bidirectional stream");
-  return 0;
-}
-
-void QuicServerInitiatedSpdyStream::OnInitialHeadersComplete(
-    bool /*fin*/,
-    size_t /*frame_len*/,
-    const QuicHeaderList& /*header_list*/) {
-  QUIC_PEER_BUG(Reading headers in QuicServerInitiatedSpdyStream)
-      << "Attempting to receive headers in QuicServerInitiatedSpdyStream";
-
-  OnUnrecoverableError(IETF_QUIC_PROTOCOL_VIOLATION,
-                       "Received HTTP/3 headers in a server-initiated "
-                       "bidirectional stream without an extension setting "
-                       "explicitly allowing those");
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_server_initiated_spdy_stream.h b/quic/core/http/quic_server_initiated_spdy_stream.h
deleted file mode 100644
index 889f216..0000000
--- a/quic/core/http/quic_server_initiated_spdy_stream.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
-
-#include "quic/core/http/quic_spdy_stream.h"
-
-namespace quic {
-
-// QuicServerInitiatedSpdyStream is a subclass of QuicSpdyStream meant to handle
-// WebTransport traffic on server-initiated bidirectional streams.  Receiving or
-// sending any other traffic on this stream will result in a CONNECTION_CLOSE.
-class QUIC_EXPORT_PRIVATE QuicServerInitiatedSpdyStream
-    : public QuicSpdyStream {
- public:
-  using QuicSpdyStream::QuicSpdyStream;
-
-  void OnBodyAvailable() override;
-  size_t WriteHeaders(
-      spdy::SpdyHeaderBlock header_block, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener) override;
-  void OnInitialHeadersComplete(bool fin,
-                                size_t frame_len,
-                                const QuicHeaderList& header_list) override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
diff --git a/quic/core/http/quic_server_session_base.cc b/quic/core/http/quic_server_session_base.cc
deleted file mode 100644
index b96a693..0000000
--- a/quic/core/http/quic_server_session_base.cc
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_server_session_base.h"
-
-#include <string>
-
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicServerSessionBase::QuicServerSessionBase(
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection,
-    Visitor* visitor,
-    QuicCryptoServerStreamBase::Helper* helper,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache)
-    : QuicSpdySession(connection, visitor, config, supported_versions),
-      crypto_config_(crypto_config),
-      compressed_certs_cache_(compressed_certs_cache),
-      helper_(helper),
-      bandwidth_resumption_enabled_(false),
-      bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
-      last_scup_time_(QuicTime::Zero()) {}
-
-QuicServerSessionBase::~QuicServerSessionBase() {}
-
-void QuicServerSessionBase::Initialize() {
-  crypto_stream_ =
-      CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_);
-  QuicSpdySession::Initialize();
-  SendSettingsToCryptoStream();
-}
-
-void QuicServerSessionBase::OnConfigNegotiated() {
-  QuicSpdySession::OnConfigNegotiated();
-
-  const bool use_lower_min_irtt =
-      connection()->sent_packet_manager().use_lower_min_irtt();
-
-  if (!use_lower_min_irtt) {
-    if (!config()->HasReceivedConnectionOptions()) {
-      return;
-    }
-  }
-
-  const CachedNetworkParameters* cached_network_params =
-      crypto_stream_->PreviousCachedNetworkParams();
-
-  // Set the initial rtt from cached_network_params.min_rtt_ms, which comes from
-  // a validated address token. This will override the initial rtt that may have
-  // been set by the transport parameters.
-  if (version().UsesTls() && cached_network_params != nullptr) {
-    if (cached_network_params->serving_region() == serving_region_) {
-      QUIC_CODE_COUNT(quic_server_received_network_params_at_same_region);
-      if ((!use_lower_min_irtt || config()->HasReceivedConnectionOptions()) &&
-          ContainsQuicTag(config()->ReceivedConnectionOptions(), kTRTT)) {
-        QUIC_DLOG(INFO)
-            << "Server: Setting initial rtt to "
-            << cached_network_params->min_rtt_ms()
-            << "ms which is received from a validated address token";
-        connection()->sent_packet_manager().SetInitialRtt(
-            QuicTime::Delta::FromMilliseconds(
-                cached_network_params->min_rtt_ms()),
-            /*trusted=*/use_lower_min_irtt);
-      }
-    } else {
-      QUIC_CODE_COUNT(quic_server_received_network_params_at_different_region);
-    }
-  }
-
-  if (use_lower_min_irtt) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 1, 2);
-    if (!config()->HasReceivedConnectionOptions()) {
-      return;
-    }
-  }
-
-  // Enable bandwidth resumption if peer sent correct connection options.
-  const bool last_bandwidth_resumption =
-      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
-  const bool max_bandwidth_resumption =
-      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWMX);
-  bandwidth_resumption_enabled_ =
-      last_bandwidth_resumption || max_bandwidth_resumption;
-
-  // If the client has provided a bandwidth estimate from the same serving
-  // region as this server, then decide whether to use the data for bandwidth
-  // resumption.
-  if (cached_network_params != nullptr &&
-      cached_network_params->serving_region() == serving_region_) {
-    if (!version().UsesTls()) {
-      // Log the received connection parameters, regardless of how they
-      // get used for bandwidth resumption.
-      connection()->OnReceiveConnectionState(*cached_network_params);
-    }
-
-    if (bandwidth_resumption_enabled_) {
-      // Only do bandwidth resumption if estimate is recent enough.
-      const uint64_t seconds_since_estimate =
-          connection()->clock()->WallNow().ToUNIXSeconds() -
-          cached_network_params->timestamp();
-      if (seconds_since_estimate <= kNumSecondsPerHour) {
-        connection()->ResumeConnectionState(*cached_network_params,
-                                            max_bandwidth_resumption);
-      }
-    }
-  }
-}
-
-void QuicServerSessionBase::OnConnectionClosed(
-    const QuicConnectionCloseFrame& frame,
-    ConnectionCloseSource source) {
-  QuicSession::OnConnectionClosed(frame, source);
-  // In the unlikely event we get a connection close while doing an asynchronous
-  // crypto event, make sure we cancel the callback.
-  if (crypto_stream_ != nullptr) {
-    crypto_stream_->CancelOutstandingCallbacks();
-  }
-}
-
-void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
-  if (!bandwidth_resumption_enabled_) {
-    return;
-  }
-  // Only send updates when the application has no data to write.
-  if (HasDataToWrite()) {
-    return;
-  }
-
-  // If not enough time has passed since the last time we sent an update to the
-  // client, or not enough packets have been sent, then return early.
-  const QuicSentPacketManager& sent_packet_manager =
-      connection()->sent_packet_manager();
-  int64_t srtt_ms =
-      sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
-  int64_t now_ms = (now - last_scup_time_).ToMilliseconds();
-  int64_t packets_since_last_scup = 0;
-  const QuicPacketNumber largest_sent_packet =
-      connection()->sent_packet_manager().GetLargestSentPacket();
-  if (largest_sent_packet.IsInitialized()) {
-    packets_since_last_scup =
-        last_scup_packet_number_.IsInitialized()
-            ? largest_sent_packet - last_scup_packet_number_
-            : largest_sent_packet.ToUint64();
-  }
-  if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
-      now_ms < kMinIntervalBetweenServerConfigUpdatesMs ||
-      packets_since_last_scup < kMinPacketsBetweenServerConfigUpdates) {
-    return;
-  }
-
-  // If the bandwidth recorder does not have a valid estimate, return early.
-  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
-      sent_packet_manager.SustainedBandwidthRecorder();
-  if (bandwidth_recorder == nullptr || !bandwidth_recorder->HasEstimate()) {
-    return;
-  }
-
-  // The bandwidth recorder has recorded at least one sustained bandwidth
-  // estimate. Check that it's substantially different from the last one that
-  // we sent to the client, and if so, send the new one.
-  QuicBandwidth new_bandwidth_estimate =
-      bandwidth_recorder->BandwidthEstimate();
-
-  int64_t bandwidth_delta =
-      std::abs(new_bandwidth_estimate.ToBitsPerSecond() -
-               bandwidth_estimate_sent_to_client_.ToBitsPerSecond());
-
-  // Define "substantial" difference as a 50% increase or decrease from the
-  // last estimate.
-  bool substantial_difference =
-      bandwidth_delta >
-      0.5 * bandwidth_estimate_sent_to_client_.ToBitsPerSecond();
-  if (!substantial_difference) {
-    return;
-  }
-
-  if (version().UsesTls()) {
-    if (version().HasIetfQuicFrames() && MaybeSendAddressToken()) {
-      bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
-    }
-  } else {
-    absl::optional<CachedNetworkParameters> cached_network_params =
-        GenerateCachedNetworkParameters();
-
-    if (cached_network_params.has_value()) {
-      bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
-      QUIC_DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): "
-                    << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond();
-
-      QUICHE_DCHECK_EQ(
-          BandwidthToCachedParameterBytesPerSecond(
-              bandwidth_estimate_sent_to_client_),
-          cached_network_params->bandwidth_estimate_bytes_per_second());
-
-      crypto_stream_->SendServerConfigUpdate(&cached_network_params.value());
-
-      connection()->OnSendConnectionState(*cached_network_params);
-    }
-  }
-
-  last_scup_time_ = now;
-  last_scup_packet_number_ =
-      connection()->sent_packet_manager().GetLargestSentPacket();
-}
-
-bool QuicServerSessionBase::ShouldCreateIncomingStream(QuicStreamId id) {
-  if (!connection()->connected()) {
-    QUIC_BUG(quic_bug_10393_2)
-        << "ShouldCreateIncomingStream called when disconnected";
-    return false;
-  }
-
-  if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
-    QUIC_BUG(quic_bug_10393_3)
-        << "ShouldCreateIncomingStream called with server initiated "
-           "stream ID.";
-    return false;
-  }
-
-  if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
-    QUIC_DLOG(INFO) << "Invalid incoming even stream_id:" << id;
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Client created even numbered stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  return true;
-}
-
-bool QuicServerSessionBase::ShouldCreateOutgoingBidirectionalStream() {
-  if (!connection()->connected()) {
-    QUIC_BUG(quic_bug_12513_2)
-        << "ShouldCreateOutgoingBidirectionalStream called when disconnected";
-    return false;
-  }
-  if (!crypto_stream_->encryption_established()) {
-    QUIC_BUG(quic_bug_10393_4)
-        << "Encryption not established so no outgoing stream created.";
-    return false;
-  }
-
-  return CanOpenNextOutgoingBidirectionalStream();
-}
-
-bool QuicServerSessionBase::ShouldCreateOutgoingUnidirectionalStream() {
-  if (!connection()->connected()) {
-    QUIC_BUG(quic_bug_12513_3)
-        << "ShouldCreateOutgoingUnidirectionalStream called when disconnected";
-    return false;
-  }
-  if (!crypto_stream_->encryption_established()) {
-    QUIC_BUG(quic_bug_10393_5)
-        << "Encryption not established so no outgoing stream created.";
-    return false;
-  }
-
-  return CanOpenNextOutgoingUnidirectionalStream();
-}
-
-QuicCryptoServerStreamBase* QuicServerSessionBase::GetMutableCryptoStream() {
-  return crypto_stream_.get();
-}
-
-const QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream()
-    const {
-  return crypto_stream_.get();
-}
-
-int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
-    const QuicBandwidth& bandwidth) const {
-  return static_cast<int32_t>(std::min<int64_t>(
-      bandwidth.ToBytesPerSecond(), std::numeric_limits<uint32_t>::max()));
-}
-
-void QuicServerSessionBase::SendSettingsToCryptoStream() {
-  if (!version().UsesTls()) {
-    return;
-  }
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount buffer_size =
-      HttpEncoder::SerializeSettingsFrame(settings(), &buffer);
-
-  std::unique_ptr<ApplicationState> serialized_settings =
-      std::make_unique<ApplicationState>(buffer.get(),
-                                         buffer.get() + buffer_size);
-  GetMutableCryptoStream()->SetServerApplicationStateForResumption(
-      std::move(serialized_settings));
-}
-
-QuicSSLConfig QuicServerSessionBase::GetSSLConfig() const {
-  QUICHE_DCHECK(crypto_config_ && crypto_config_->proof_source());
-
-  QuicSSLConfig ssl_config = QuicSpdySession::GetSSLConfig();
-
-  ssl_config.disable_ticket_support =
-      GetQuicFlag(FLAGS_quic_disable_server_tls_resumption);
-
-  if (!crypto_config_ || !crypto_config_->proof_source()) {
-    return ssl_config;
-  }
-
-  absl::InlinedVector<uint16_t, 8> signature_algorithms =
-      crypto_config_->proof_source()->SupportedTlsSignatureAlgorithms();
-  if (!signature_algorithms.empty()) {
-    ssl_config.signing_algorithm_prefs = std::move(signature_algorithms);
-  }
-
-  return ssl_config;
-}
-
-absl::optional<CachedNetworkParameters>
-QuicServerSessionBase::GenerateCachedNetworkParameters() const {
-  const QuicSentPacketManager& sent_packet_manager =
-      connection()->sent_packet_manager();
-  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
-      sent_packet_manager.SustainedBandwidthRecorder();
-
-  CachedNetworkParameters cached_network_params;
-  cached_network_params.set_timestamp(
-      connection()->clock()->WallNow().ToUNIXSeconds());
-
-  if (!sent_packet_manager.GetRttStats()->min_rtt().IsZero()) {
-    cached_network_params.set_min_rtt_ms(
-        sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds());
-  }
-
-  // Populate bandwidth estimates if any.
-  if (bandwidth_recorder != nullptr && bandwidth_recorder->HasEstimate()) {
-    const int32_t bw_estimate_bytes_per_second =
-        BandwidthToCachedParameterBytesPerSecond(
-            bandwidth_recorder->BandwidthEstimate());
-    const int32_t max_bw_estimate_bytes_per_second =
-        BandwidthToCachedParameterBytesPerSecond(
-            bandwidth_recorder->MaxBandwidthEstimate());
-    QUIC_BUG_IF(quic_bug_12513_1, max_bw_estimate_bytes_per_second < 0)
-        << max_bw_estimate_bytes_per_second;
-    QUIC_BUG_IF(quic_bug_10393_1, bw_estimate_bytes_per_second < 0)
-        << bw_estimate_bytes_per_second;
-
-    cached_network_params.set_bandwidth_estimate_bytes_per_second(
-        bw_estimate_bytes_per_second);
-    cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
-        max_bw_estimate_bytes_per_second);
-    cached_network_params.set_max_bandwidth_timestamp_seconds(
-        bandwidth_recorder->MaxBandwidthTimestamp());
-
-    cached_network_params.set_previous_connection_state(
-        bandwidth_recorder->EstimateRecordedDuringSlowStart()
-            ? CachedNetworkParameters::SLOW_START
-            : CachedNetworkParameters::CONGESTION_AVOIDANCE);
-  }
-
-  if (!serving_region_.empty()) {
-    cached_network_params.set_serving_region(serving_region_);
-  }
-
-  return cached_network_params;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_server_session_base.h b/quic/core/http/quic_server_session_base.h
deleted file mode 100644
index e6afc19..0000000
--- a/quic/core/http/quic_server_session_base.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A server specific QuicSession subclass.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
-
-#include <cstdint>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicConfig;
-class QuicConnection;
-class QuicCryptoServerConfig;
-
-namespace test {
-class QuicServerSessionBasePeer;
-class QuicSimpleServerSessionPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
- public:
-  // Does not take ownership of |connection|. |crypto_config| must outlive the
-  // session. |helper| must outlive any created crypto streams.
-  QuicServerSessionBase(const QuicConfig& config,
-                        const ParsedQuicVersionVector& supported_versions,
-                        QuicConnection* connection,
-                        QuicSession::Visitor* visitor,
-                        QuicCryptoServerStreamBase::Helper* helper,
-                        const QuicCryptoServerConfig* crypto_config,
-                        QuicCompressedCertsCache* compressed_certs_cache);
-  QuicServerSessionBase(const QuicServerSessionBase&) = delete;
-  QuicServerSessionBase& operator=(const QuicServerSessionBase&) = delete;
-
-  // Override the base class to cancel any ongoing asychronous crypto.
-  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                          ConnectionCloseSource source) override;
-
-  // Sends a server config update to the client, containing new bandwidth
-  // estimate.
-  void OnCongestionWindowChange(QuicTime now) override;
-
-  ~QuicServerSessionBase() override;
-
-  void Initialize() override;
-
-  const QuicCryptoServerStreamBase* crypto_stream() const {
-    return crypto_stream_.get();
-  }
-
-  // Override base class to process bandwidth related config received from
-  // client.
-  void OnConfigNegotiated() override;
-
-  void set_serving_region(const std::string& serving_region) {
-    serving_region_ = serving_region;
-  }
-
-  const std::string& serving_region() const { return serving_region_; }
-
-  QuicSSLConfig GetSSLConfig() const override;
-
- protected:
-  // QuicSession methods(override them with return type of QuicSpdyStream*):
-  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
-
-  const QuicCryptoServerStreamBase* GetCryptoStream() const override;
-
-  absl::optional<CachedNetworkParameters> GenerateCachedNetworkParameters()
-      const override;
-
-  // If an outgoing stream can be created, return true.
-  // Return false when connection is closed or forward secure encryption hasn't
-  // established yet or number of server initiated streams already reaches the
-  // upper limit.
-  bool ShouldCreateOutgoingBidirectionalStream() override;
-  bool ShouldCreateOutgoingUnidirectionalStream() override;
-
-  // If we should create an incoming stream, returns true. Otherwise
-  // does error handling, including communicating the error to the client and
-  // possibly closing the connection, and returns false.
-  bool ShouldCreateIncomingStream(QuicStreamId id) override;
-
-  virtual std::unique_ptr<QuicCryptoServerStreamBase>
-  CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache) = 0;
-
-  const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
-
-  QuicCryptoServerStreamBase::Helper* stream_helper() { return helper_; }
-
- private:
-  friend class test::QuicServerSessionBasePeer;
-  friend class test::QuicSimpleServerSessionPeer;
-
-  // Informs the QuicCryptoStream of the SETTINGS that will be used on this
-  // connection, so that the server crypto stream knows whether to accept 0-RTT
-  // data.
-  void SendSettingsToCryptoStream();
-
-  const QuicCryptoServerConfig* crypto_config_;
-
-  // The cache which contains most recently compressed certs.
-  // Owned by QuicDispatcher.
-  QuicCompressedCertsCache* compressed_certs_cache_;
-
-  std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
-
-  // Pointer to the helper used to create crypto server streams. Must outlive
-  // streams created via CreateQuicCryptoServerStream.
-  QuicCryptoServerStreamBase::Helper* helper_;
-
-  // Whether bandwidth resumption is enabled for this connection.
-  bool bandwidth_resumption_enabled_;
-
-  // The most recent bandwidth estimate sent to the client.
-  QuicBandwidth bandwidth_estimate_sent_to_client_;
-
-  // Text describing server location. Sent to the client as part of the bandwith
-  // estimate in the source-address token. Optional, can be left empty.
-  std::string serving_region_;
-
-  // Time at which we send the last SCUP to the client.
-  QuicTime last_scup_time_;
-
-  // Number of packets sent to the peer, at the time we last sent a SCUP.
-  QuicPacketNumber last_scup_packet_number_;
-
-  // Converts QuicBandwidth to an int32 bytes/second that can be
-  // stored in CachedNetworkParameters.  TODO(jokulik): This function
-  // should go away once we fix http://b//27897982
-  int32_t BandwidthToCachedParameterBytesPerSecond(
-      const QuicBandwidth& bandwidth) const;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
diff --git a/quic/core/http/quic_server_session_base_test.cc b/quic/core/http/quic_server_session_base_test.cc
deleted file mode 100644
index 6121a81..0000000
--- a/quic/core/http/quic_server_session_base_test.cc
+++ /dev/null
@@ -1,809 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_server_session_base.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_server_stream.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/tls_server_handshaker.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_server_session_base_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-using testing::_;
-using testing::StrictMock;
-
-using testing::AtLeast;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Data to be sent on a request stream.  In Google QUIC, this is interpreted as
-// DATA payload (there is no framing on request streams).  In IETF QUIC, this is
-// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z').  Since
-// no payload is included, QPACK decoder will not be invoked.
-const char* const kStreamData = "\1z";
-
-class TestServerSession : public QuicServerSessionBase {
- public:
-  TestServerSession(const QuicConfig& config,
-                    QuicConnection* connection,
-                    QuicSession::Visitor* visitor,
-                    QuicCryptoServerStreamBase::Helper* helper,
-                    const QuicCryptoServerConfig* crypto_config,
-                    QuicCompressedCertsCache* compressed_certs_cache,
-                    QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicServerSessionBase(config,
-                              CurrentSupportedVersions(),
-                              connection,
-                              visitor,
-                              helper,
-                              crypto_config,
-                              compressed_certs_cache),
-        quic_simple_server_backend_(quic_simple_server_backend) {}
-
-  ~TestServerSession() override { DeleteConnection(); }
-
-  MOCK_METHOD(bool,
-              WriteControlFrame,
-              (const QuicFrame& frame, TransmissionType type),
-              (override));
-
- protected:
-  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
-    if (!ShouldCreateIncomingStream(id)) {
-      return nullptr;
-    }
-    QuicSpdyStream* stream = new QuicSimpleServerStream(
-        id, this, BIDIRECTIONAL, quic_simple_server_backend_);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override {
-    QuicSpdyStream* stream =
-        new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  QuicSpdyStream* CreateOutgoingBidirectionalStream() override {
-    QUICHE_DCHECK(false);
-    return nullptr;
-  }
-
-  QuicSpdyStream* CreateOutgoingUnidirectionalStream() override {
-    if (!ShouldCreateOutgoingUnidirectionalStream()) {
-      return nullptr;
-    }
-
-    QuicSpdyStream* stream = new QuicSimpleServerStream(
-        GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
-        quic_simple_server_backend_);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache) override {
-    return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
-                                    stream_helper());
-  }
-
- private:
-  QuicSimpleServerBackend*
-      quic_simple_server_backend_;  // Owned by QuicServerSessionBaseTest
-};
-
-const size_t kMaxStreamsForTest = 10;
-
-class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicServerSessionBaseTest()
-      : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
-
-  explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
-      : crypto_config_(QuicCryptoServerConfig::TESTING,
-                       QuicRandom::GetInstance(),
-                       std::move(proof_source),
-                       KeyExchangeSource::Default()),
-        compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
-    config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
-    config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
-    QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
-                                                       kMaxStreamsForTest);
-    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
-                                                        kMaxStreamsForTest);
-    config_.SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    config_.SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-
-    ParsedQuicVersionVector supported_versions = SupportedVersions(version());
-    connection_ = new StrictMock<MockQuicConnection>(
-        &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    session_ = std::make_unique<TestServerSession>(
-        config_, connection_, &owner_, &stream_helper_, &crypto_config_,
-        &compressed_certs_cache_, &memory_cache_backend_);
-    MockClock clock;
-    handshake_message_ = crypto_config_.AddDefaultConfig(
-        QuicRandom::GetInstance(), &clock,
-        QuicCryptoServerConfig::ConfigOptions());
-    session_->Initialize();
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_->config(), kMinimumFlowControlSendWindow);
-    session_->OnConfigNegotiated();
-    if (version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(connection_);
-    }
-  }
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
-  }
-
-  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
-    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
-        transport_version(), n);
-  }
-
-  ParsedQuicVersion version() const { return GetParam(); }
-
-  QuicTransportVersion transport_version() const {
-    return version().transport_version;
-  }
-
-  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
-  // one-way close. This method can be used to inject a STOP_SENDING, which
-  // would cause a close in the opposite direction. This allows tests to do the
-  // extra work to get a two-way (full) close where desired. Also sets up
-  // expects needed to ensure that the STOP_SENDING worked as expected.
-  void InjectStopSendingFrame(QuicStreamId stream_id) {
-    if (!VersionHasIetfQuicFrames(transport_version())) {
-      // Only needed for version 99/IETF QUIC. Noop otherwise.
-      return;
-    }
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
-                                      QUIC_ERROR_PROCESSING_STREAM);
-    EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
-    // Expect the RESET_STREAM that is generated in response to receiving a
-    // STOP_SENDING.
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    EXPECT_CALL(*connection_,
-                OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM));
-    session_->OnStopSendingFrame(stop_sending);
-  }
-
-  StrictMock<MockQuicSessionVisitor> owner_;
-  StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  QuicConfig config_;
-  QuicCryptoServerConfig crypto_config_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-  QuicMemoryCacheBackend memory_cache_backend_;
-  std::unique_ptr<TestServerSession> session_;
-  std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
-};
-
-// Compares CachedNetworkParameters.
-MATCHER_P(EqualsProto, network_params, "") {
-  CachedNetworkParameters reference(network_params);
-  return (arg->bandwidth_estimate_bytes_per_second() ==
-              reference.bandwidth_estimate_bytes_per_second() &&
-          arg->bandwidth_estimate_bytes_per_second() ==
-              reference.bandwidth_estimate_bytes_per_second() &&
-          arg->max_bandwidth_estimate_bytes_per_second() ==
-              reference.max_bandwidth_estimate_bytes_per_second() &&
-          arg->max_bandwidth_timestamp_seconds() ==
-              reference.max_bandwidth_timestamp_seconds() &&
-          arg->min_rtt_ms() == reference.min_rtt_ms() &&
-          arg->previous_connection_state() ==
-              reference.previous_connection_state());
-}
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicServerSessionBaseTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
-  // Send some data open a stream, then reset it.
-  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        kStreamData);
-  session_->OnStreamFrame(data1);
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Send a reset (and expect the peer to send a RST in response).
-  QuicRstStreamFrame rst1(kInvalidControlFrameId,
-                          GetNthClientInitiatedBidirectionalId(0),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For non-version 99, the RESET_STREAM will do the full close.
-    // Set up expects accordingly.
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  session_->OnRstStream(rst1);
-
-  // For version-99 will create and receive a stop-sending, completing
-  // the full-close expected by this test.
-  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  // Send the same two bytes of payload in a new packet.
-  session_->OnStreamFrame(data1);
-
-  // The stream should not be re-opened.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
-  // Send a reset (and expect the peer to send a RST in response).
-  QuicRstStreamFrame rst1(kInvalidControlFrameId,
-                          GetNthClientInitiatedBidirectionalId(0),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For non-version 99, the RESET_STREAM will do the full close.
-    // Set up expects accordingly.
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  session_->OnRstStream(rst1);
-
-  // For version-99 will create and receive a stop-sending, completing
-  // the full-close expected by this test.
-  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        kStreamData);
-  session_->OnStreamFrame(data1);
-
-  // The stream should never be opened, now that the reset is received.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
-  // Send some data to open two streams.
-  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                         kStreamData);
-  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
-                         kStreamData);
-  session_->OnStreamFrame(frame1);
-  session_->OnStreamFrame(frame2);
-  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Send a reset (and expect the peer to send a RST in response).
-  QuicRstStreamFrame rst(kInvalidControlFrameId,
-                         GetNthClientInitiatedBidirectionalId(0),
-                         QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For non-version 99, the RESET_STREAM will do the full close.
-    // Set up expects accordingly.
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  session_->OnRstStream(rst);
-
-  // For version-99 will create and receive a stop-sending, completing
-  // the full-close expected by this test.
-  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
-
-  // If we were tracking, we'd probably want to reject this because it's data
-  // past the reset point of stream 3.  As it's a closed stream we just drop the
-  // data on the floor, but accept the packet because it has data for stream 5.
-  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
-                         kStreamData);
-  QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
-                         kStreamData);
-  session_->OnStreamFrame(frame3);
-  session_->OnStreamFrame(frame4);
-  // The stream should never be opened, now that the reset is received.
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
-  // Test that the server refuses if a client attempts to open too many data
-  // streams.  For versions other than version 99, the server accepts slightly
-  // more than the negotiated stream limit to deal with rare cases where a
-  // client FIN/RST is lost.
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_->OnConfigNegotiated();
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // The slightly increased stream limit is set during config negotiation.  It
-    // is either an increase of 10 over negotiated limit, or a fixed percentage
-    // scaling, whichever is larger. Test both before continuing.
-    EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
-              kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
-    EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
-              session_->max_open_incoming_bidirectional_streams());
-  }
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  // Open the max configured number of streams, should be no problem.
-  for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
-    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
-                                                             stream_id));
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-  }
-
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // Open more streams: server should accept slightly more than the limit.
-    // Excess streams are for non-version-99 only.
-    for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
-      EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
-                                                               stream_id));
-      stream_id += QuicUtils::StreamIdDelta(transport_version());
-    }
-  }
-  // Now violate the server's internal stream limit.
-  stream_id += QuicUtils::StreamIdDelta(transport_version());
-
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For non-version 99, QUIC responds to an attempt to exceed the stream
-    // limit by resetting the stream.
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
-  } else {
-    // In version 99 QUIC responds to an attempt to exceed the stream limit by
-    // closing the connection.
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
-  }
-  // Even if the connection remains open, the stream creation should fail.
-  EXPECT_FALSE(
-      QuicServerSessionBasePeer::GetOrCreateStream(session_.get(), stream_id));
-}
-
-TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
-  // Test that the server closes the connection if a client makes too many data
-  // streams available.  The server accepts slightly more than the negotiated
-  // stream limit to deal with rare cases where a client FIN/RST is lost.
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_->OnConfigNegotiated();
-  const size_t kAvailableStreamLimit =
-      session_->MaxAvailableBidirectionalStreams();
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
-      session_.get(), GetNthClientInitiatedBidirectionalId(0)));
-
-  // Establish available streams up to the server's limit.
-  QuicStreamId next_id = QuicUtils::StreamIdDelta(transport_version());
-  const int kLimitingStreamId =
-      GetNthClientInitiatedBidirectionalId(kAvailableStreamLimit + 1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // This exceeds the stream limit. In versions other than 99
-    // this is allowed. Version 99 hews to the IETF spec and does
-    // not allow it.
-    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
-        session_.get(), kLimitingStreamId));
-    // A further available stream will result in connection close.
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
-  } else {
-    // A further available stream will result in connection close.
-    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
-  }
-
-  // This forces stream kLimitingStreamId + 2 to become available, which
-  // violates the quota.
-  EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateStream(
-      session_.get(), kLimitingStreamId + 2 * next_id));
-}
-
-TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
-  // Incoming streams on the server session must be odd.
-  const QuicErrorCode expected_error =
-      VersionHasIetfQuicFrames(transport_version())
-          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
-          : QUIC_INVALID_STREAM_ID;
-  EXPECT_CALL(*connection_, CloseConnection(expected_error, _, _));
-  EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateStream(
-                         session_.get(),
-                         session_->next_outgoing_unidirectional_stream_id()));
-}
-
-TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (version() != AllSupportedVersions()[0]) {
-    return;
-  }
-
-  // Don't create new streams if the connection is disconnected.
-  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
-  EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateStream(
-                      session_.get(), GetNthClientInitiatedBidirectionalId(0)),
-                  "ShouldCreateIncomingStream called when disconnected");
-}
-
-class MockQuicCryptoServerStream : public QuicCryptoServerStream {
- public:
-  explicit MockQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      QuicServerSessionBase* session,
-      QuicCryptoServerStreamBase::Helper* helper)
-      : QuicCryptoServerStream(crypto_config,
-                               compressed_certs_cache,
-                               session,
-                               helper) {}
-  MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
-  MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
-      delete;
-  ~MockQuicCryptoServerStream() override {}
-
-  MOCK_METHOD(void,
-              SendServerConfigUpdate,
-              (const CachedNetworkParameters*),
-              (override));
-};
-
-class MockTlsServerHandshaker : public TlsServerHandshaker {
- public:
-  explicit MockTlsServerHandshaker(QuicServerSessionBase* session,
-                                   const QuicCryptoServerConfig* crypto_config)
-      : TlsServerHandshaker(session, crypto_config) {}
-  MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
-  MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
-  ~MockTlsServerHandshaker() override {}
-
-  MOCK_METHOD(void, SendServerConfigUpdate, (const CachedNetworkParameters*),
-              (override));
-
-  MOCK_METHOD(std::string, GetAddressToken, (const CachedNetworkParameters*),
-              (const, override));
-};
-
-TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
-  if (version().UsesTls() && !version().HasIetfQuicFrames()) {
-    // Skip the Txxx versions.
-    return;
-  }
-
-  // Test that bandwidth estimate updates are sent to the client, only when
-  // bandwidth resumption is enabled, the bandwidth estimate has changed
-  // sufficiently, enough time has passed,
-  // and we don't have any other data to write.
-
-  // Client has sent kBWRE connection option to trigger bandwidth resumption.
-  QuicTagVector copt;
-  copt.push_back(kBWRE);
-  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_->OnConfigNegotiated();
-  EXPECT_TRUE(
-      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-
-  int32_t bandwidth_estimate_kbytes_per_second = 123;
-  int32_t max_bandwidth_estimate_kbytes_per_second = 134;
-  int32_t max_bandwidth_estimate_timestamp = 1122334455;
-  const std::string serving_region = "not a real region";
-  session_->set_serving_region(serving_region);
-
-  if (!VersionUsesHttp3(transport_version())) {
-    session_->UnregisterStreamPriority(
-        QuicUtils::GetHeadersStreamId(transport_version()),
-        /*is_static=*/true);
-  }
-  QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
-  MockQuicCryptoServerStream* quic_crypto_stream = nullptr;
-  MockTlsServerHandshaker* tls_server_stream = nullptr;
-  if (version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-    quic_crypto_stream = new MockQuicCryptoServerStream(
-        &crypto_config_, &compressed_certs_cache_, session_.get(),
-        &stream_helper_);
-    QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
-                                               quic_crypto_stream);
-  } else {
-    tls_server_stream =
-        new MockTlsServerHandshaker(session_.get(), &crypto_config_);
-    QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
-                                               tls_server_stream);
-  }
-  if (!VersionUsesHttp3(transport_version())) {
-    session_->RegisterStreamPriority(
-        QuicUtils::GetHeadersStreamId(transport_version()),
-        /*is_static=*/true,
-        spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
-  }
-
-  // Set some initial bandwidth values.
-  QuicSentPacketManager* sent_packet_manager =
-      QuicConnectionPeer::GetSentPacketManager(session_->connection());
-  QuicSustainedBandwidthRecorder& bandwidth_recorder =
-      QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
-  // Seed an rtt measurement equal to the initial default rtt.
-  RttStats* rtt_stats =
-      const_cast<RttStats*>(sent_packet_manager->GetRttStats());
-  rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(),
-                       QuicTime::Zero());
-  QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
-      &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
-  QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
-      &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
-      max_bandwidth_estimate_timestamp);
-  // Queue up some pending data.
-  if (!VersionUsesHttp3(transport_version())) {
-    session_->MarkConnectionLevelWriteBlocked(
-        QuicUtils::GetHeadersStreamId(transport_version()));
-  } else {
-    session_->MarkConnectionLevelWriteBlocked(
-        QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
-                                                  Perspective::IS_SERVER));
-  }
-  EXPECT_TRUE(session_->HasDataToWrite());
-
-  // There will be no update sent yet - not enough time has passed.
-  QuicTime now = QuicTime::Zero();
-  session_->OnCongestionWindowChange(now);
-
-  // Bandwidth estimate has now changed sufficiently but not enough time has
-  // passed to send a Server Config Update.
-  bandwidth_estimate_kbytes_per_second =
-      bandwidth_estimate_kbytes_per_second * 1.6;
-  session_->OnCongestionWindowChange(now);
-
-  // Bandwidth estimate has now changed sufficiently and enough time has passed,
-  // but not enough packets have been sent.
-  int64_t srtt_ms =
-      sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
-  now = now + QuicTime::Delta::FromMilliseconds(
-                  kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms);
-  session_->OnCongestionWindowChange(now);
-
-  // The connection no longer has pending data to be written.
-  session_->OnCanWrite();
-  EXPECT_FALSE(session_->HasDataToWrite());
-  session_->OnCongestionWindowChange(now);
-
-  // Bandwidth estimate has now changed sufficiently, enough time has passed,
-  // and enough packets have been sent.
-  SerializedPacket packet(
-      QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
-      PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
-  sent_packet_manager->OnPacketSent(&packet, now, NOT_RETRANSMISSION,
-                                    HAS_RETRANSMITTABLE_DATA, true);
-
-  // Verify that the proto has exactly the values we expect.
-  CachedNetworkParameters expected_network_params;
-  expected_network_params.set_bandwidth_estimate_bytes_per_second(
-      bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
-  expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
-      bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
-  expected_network_params.set_max_bandwidth_timestamp_seconds(
-      bandwidth_recorder.MaxBandwidthTimestamp());
-  expected_network_params.set_min_rtt_ms(session_->connection()
-                                             ->sent_packet_manager()
-                                             .GetRttStats()
-                                             ->min_rtt()
-                                             .ToMilliseconds());
-  expected_network_params.set_previous_connection_state(
-      CachedNetworkParameters::CONGESTION_AVOIDANCE);
-  expected_network_params.set_timestamp(
-      session_->connection()->clock()->WallNow().ToUNIXSeconds());
-  expected_network_params.set_serving_region(serving_region);
-
-  if (quic_crypto_stream) {
-    EXPECT_CALL(*quic_crypto_stream,
-                SendServerConfigUpdate(EqualsProto(expected_network_params)))
-        .Times(1);
-  } else {
-    EXPECT_CALL(*tls_server_stream,
-                GetAddressToken(EqualsProto(expected_network_params)))
-        .WillOnce(testing::Return("Test address token"));
-  }
-  EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
-  session_->OnCongestionWindowChange(now);
-}
-
-TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
-  if (version().UsesTls()) {
-    if (!version().HasIetfQuicFrames()) {
-      // Skip the Txxx versions.
-      return;
-    }
-    // Avoid a QUIC_BUG in QuicSession::OnConfigNegotiated.
-    connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  }
-
-  // Test that if a client provides a CachedNetworkParameters with the same
-  // serving region as the current server, and which was made within an hour of
-  // now, that this data is passed down to the send algorithm.
-
-  // Client has sent kBWRE connection option to trigger bandwidth resumption.
-  QuicTagVector copt;
-  copt.push_back(kBWRE);
-  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
-
-  const std::string kTestServingRegion = "a serving region";
-  session_->set_serving_region(kTestServingRegion);
-
-  // Set the time to be one hour + one second from the 0 baseline.
-  connection_->AdvanceTime(
-      QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
-
-  QuicCryptoServerStreamBase* crypto_stream =
-      static_cast<QuicCryptoServerStreamBase*>(
-          QuicSessionPeer::GetMutableCryptoStream(session_.get()));
-
-  // No effect if no CachedNetworkParameters provided.
-  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
-  session_->OnConfigNegotiated();
-
-  // No effect if CachedNetworkParameters provided, but different serving
-  // regions.
-  CachedNetworkParameters cached_network_params;
-  cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
-  cached_network_params.set_serving_region("different serving region");
-  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
-  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
-  session_->OnConfigNegotiated();
-
-  // Same serving region, but timestamp is too old, should have no effect.
-  cached_network_params.set_serving_region(kTestServingRegion);
-  cached_network_params.set_timestamp(0);
-  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
-  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
-  session_->OnConfigNegotiated();
-
-  // Same serving region, and timestamp is recent: estimate is stored.
-  cached_network_params.set_timestamp(
-      connection_->clock()->WallNow().ToUNIXSeconds());
-  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
-  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
-  session_->OnConfigNegotiated();
-}
-
-TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
-  EXPECT_FALSE(
-      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-
-  // Client has sent kBWMX connection option to trigger bandwidth resumption.
-  QuicTagVector copt;
-  copt.push_back(kBWMX);
-  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_->OnConfigNegotiated();
-  EXPECT_TRUE(
-      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-}
-
-TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
-  EXPECT_FALSE(
-      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_->OnConfigNegotiated();
-  EXPECT_FALSE(
-      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
-}
-
-// Tests which check the lifetime management of data members of
-// QuicCryptoServerStream objects when async GetProof is in use.
-class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
- public:
-  StreamMemberLifetimeTest()
-      : QuicServerSessionBaseTest(
-            std::unique_ptr<FakeProofSource>(new FakeProofSource())),
-        crypto_config_peer_(&crypto_config_) {
-    GetFakeProofSource()->Activate();
-  }
-
-  FakeProofSource* GetFakeProofSource() const {
-    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
-  }
-
- private:
-  QuicCryptoServerConfigPeer crypto_config_peer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(StreamMemberLifetimeTests,
-                         StreamMemberLifetimeTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-// Trigger an operation which causes an async invocation of
-// ProofSource::GetProof.  Delay the completion of the operation until after the
-// stream has been destroyed, and verify that there are no memory bugs.
-TEST_P(StreamMemberLifetimeTest, Basic) {
-  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
-    // This test depends on the QUIC crypto protocol, so it is disabled for the
-    // TLS handshake.
-    // TODO(nharper): Fix this test so it doesn't rely on QUIC crypto.
-    return;
-  }
-
-  const QuicClock* clock = helper_.GetClock();
-  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
-      clock, transport_version(), &crypto_config_);
-  chlo.SetVector(kCOPT, QuicTagVector{kREJ});
-  std::vector<ParsedQuicVersion> packet_version_list = {version()};
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      TestConnectionId(1), EmptyQuicConnectionId(), true, false, 1,
-      std::string(chlo.GetSerialized().AsStringPiece()), CONNECTION_ID_PRESENT,
-      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &packet_version_list));
-
-  EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _, _, _))
-      .WillOnce(testing::Return(true));
-
-  // Set the current packet
-  QuicConnectionPeer::SetCurrentPacket(session_->connection(),
-                                       packet->AsStringPiece());
-
-  // Yes, this is horrible.  But it's the easiest way to trigger the behavior we
-  // need to exercise.
-  QuicCryptoServerStreamBase* crypto_stream =
-      const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
-
-  // Feed the CHLO into the crypto stream, which will trigger a call to
-  // ProofSource::GetProof
-  crypto_test_utils::SendHandshakeMessageToStream(crypto_stream, chlo,
-                                                  Perspective::IS_CLIENT);
-  ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
-  // Destroy the stream
-  session_.reset();
-
-  // Allow the async ProofSource::GetProof call to complete.  Verify (under
-  // memory access checkers) that this does not result in accesses to any
-  // freed memory from the session or its subobjects.
-  GetFakeProofSource()->InvokePendingCallback(0);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session.cc b/quic/core/http/quic_spdy_client_session.cc
deleted file mode 100644
index 898398f..0000000
--- a/quic/core/http/quic_spdy_client_session.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_session.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/http/quic_server_initiated_spdy_stream.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSpdyClientSession::QuicSpdyClientSession(
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection,
-    const QuicServerId& server_id,
-    QuicCryptoClientConfig* crypto_config,
-    QuicClientPushPromiseIndex* push_promise_index)
-    : QuicSpdyClientSessionBase(connection,
-                                push_promise_index,
-                                config,
-                                supported_versions),
-      server_id_(server_id),
-      crypto_config_(crypto_config),
-      respect_goaway_(true) {}
-
-QuicSpdyClientSession::~QuicSpdyClientSession() = default;
-
-void QuicSpdyClientSession::Initialize() {
-  crypto_stream_ = CreateQuicCryptoStream();
-  if (config()->HasClientRequestedIndependentOption(kQLVE,
-                                                    Perspective::IS_CLIENT)) {
-    connection()->EnableLegacyVersionEncapsulation(server_id_.host());
-  }
-  QuicSpdyClientSessionBase::Initialize();
-}
-
-void QuicSpdyClientSession::OnProofValid(
-    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
-
-void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
-    const ProofVerifyDetails& /*verify_details*/) {}
-
-bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
-  if (!crypto_stream_->encryption_established()) {
-    QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
-    return false;
-  }
-  if (goaway_received() && respect_goaway_) {
-    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
-                    << "Already received goaway.";
-    return false;
-  }
-  return CanOpenNextOutgoingBidirectionalStream();
-}
-
-bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
-  QUIC_BUG(quic_bug_10396_1)
-      << "Try to create outgoing unidirectional client data streams";
-  return false;
-}
-
-QuicSpdyClientStream*
-QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
-  if (!ShouldCreateOutgoingBidirectionalStream()) {
-    return nullptr;
-  }
-  std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
-  QuicSpdyClientStream* stream_ptr = stream.get();
-  ActivateStream(std::move(stream));
-  return stream_ptr;
-}
-
-QuicSpdyClientStream*
-QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
-  QUIC_BUG(quic_bug_10396_2)
-      << "Try to create outgoing unidirectional client data streams";
-  return nullptr;
-}
-
-std::unique_ptr<QuicSpdyClientStream>
-QuicSpdyClientSession::CreateClientStream() {
-  return std::make_unique<QuicSpdyClientStream>(
-      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
-}
-
-QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
-  return crypto_stream_.get();
-}
-
-const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
-    const {
-  return crypto_stream_.get();
-}
-
-bool QuicSpdyClientSession::IsKnownServerAddress(
-    const QuicSocketAddress& address) const {
-  return std::find(known_server_addresses_.cbegin(),
-                   known_server_addresses_.cend(),
-                   address) != known_server_addresses_.cend();
-}
-
-void QuicSpdyClientSession::AddKnownServerAddress(
-    const QuicSocketAddress& address) {
-  known_server_addresses_.push_back(address);
-}
-
-void QuicSpdyClientSession::CryptoConnect() {
-  QUICHE_DCHECK(flow_controller());
-  crypto_stream_->CryptoConnect();
-}
-
-int QuicSpdyClientSession::GetNumSentClientHellos() const {
-  return crypto_stream_->num_sent_client_hellos();
-}
-
-bool QuicSpdyClientSession::IsResumption() const {
-  return crypto_stream_->IsResumption();
-}
-
-bool QuicSpdyClientSession::EarlyDataAccepted() const {
-  return crypto_stream_->EarlyDataAccepted();
-}
-
-bool QuicSpdyClientSession::ReceivedInchoateReject() const {
-  return crypto_stream_->ReceivedInchoateReject();
-}
-
-int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
-  return crypto_stream_->num_scup_messages_received();
-}
-
-bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
-  if (!connection()->connected()) {
-    QUIC_BUG(quic_bug_10396_3)
-        << "ShouldCreateIncomingStream called when disconnected";
-    return false;
-  }
-  if (goaway_received() && respect_goaway_) {
-    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
-                    << "Already received goaway.";
-    return false;
-  }
-
-  if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
-    QUIC_BUG(quic_bug_10396_4)
-        << "ShouldCreateIncomingStream called with client initiated "
-           "stream ID.";
-    return false;
-  }
-
-  if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
-    QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID,
-        "Server created non write unidirectional stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version()) &&
-      QuicUtils::IsBidirectionalStreamId(id, version()) &&
-      !WillNegotiateWebTransport()) {
-    connection()->CloseConnection(
-        QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM,
-        "Server created bidirectional stream.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  return true;
-}
-
-QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
-    PendingStream* pending) {
-  QuicSpdyStream* stream = new QuicSpdyClientStream(pending, this);
-  ActivateStream(absl::WrapUnique(stream));
-  return stream;
-}
-
-QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
-  if (!ShouldCreateIncomingStream(id)) {
-    return nullptr;
-  }
-  QuicSpdyStream* stream;
-  if (version().UsesHttp3() &&
-      QuicUtils::IsBidirectionalStreamId(id, version())) {
-    QUIC_BUG_IF(QuicServerInitiatedSpdyStream but no WebTransport support,
-                !WillNegotiateWebTransport())
-        << "QuicServerInitiatedSpdyStream created but no WebTransport support";
-    stream = new QuicServerInitiatedSpdyStream(id, this, BIDIRECTIONAL);
-  } else {
-    stream = new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
-  }
-  ActivateStream(absl::WrapUnique(stream));
-  return stream;
-}
-
-std::unique_ptr<QuicCryptoClientStreamBase>
-QuicSpdyClientSession::CreateQuicCryptoStream() {
-  return std::make_unique<QuicCryptoClientStream>(
-      server_id_, this,
-      crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
-      this, /*has_application_state = */ version().UsesHttp3());
-}
-
-bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session.h b/quic/core/http/quic_spdy_client_session.h
deleted file mode 100644
index 42471b1..0000000
--- a/quic/core/http/quic_spdy_client_session.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A client specific QuicSession subclass.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
-
-#include <memory>
-#include <string>
-
-#include "quic/core/http/quic_spdy_client_session_base.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicConnection;
-class QuicServerId;
-
-class QUIC_EXPORT_PRIVATE QuicSpdyClientSession
-    : public QuicSpdyClientSessionBase {
- public:
-  // Takes ownership of |connection|. Caller retains ownership of
-  // |promised_by_url|.
-  QuicSpdyClientSession(const QuicConfig& config,
-                        const ParsedQuicVersionVector& supported_versions,
-                        QuicConnection* connection,
-                        const QuicServerId& server_id,
-                        QuicCryptoClientConfig* crypto_config,
-                        QuicClientPushPromiseIndex* push_promise_index);
-  QuicSpdyClientSession(const QuicSpdyClientSession&) = delete;
-  QuicSpdyClientSession& operator=(const QuicSpdyClientSession&) = delete;
-  ~QuicSpdyClientSession() override;
-  // Set up the QuicSpdyClientSession. Must be called prior to use.
-  void Initialize() override;
-
-  // QuicSession methods:
-  QuicSpdyClientStream* CreateOutgoingBidirectionalStream() override;
-  QuicSpdyClientStream* CreateOutgoingUnidirectionalStream() override;
-  QuicCryptoClientStreamBase* GetMutableCryptoStream() override;
-  const QuicCryptoClientStreamBase* GetCryptoStream() const override;
-  bool IsKnownServerAddress(const QuicSocketAddress& address) const override;
-
-  void AddKnownServerAddress(const QuicSocketAddress& address);
-
-  bool IsAuthorized(const std::string& authority) override;
-
-  // QuicSpdyClientSessionBase methods:
-  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
-  void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& verify_details) override;
-
-  // Performs a crypto handshake with the server.
-  virtual void CryptoConnect();
-
-  // Returns the number of client hello messages that have been sent on the
-  // crypto stream. If the handshake has completed then this is one greater
-  // than the number of round-trips needed for the handshake.
-  int GetNumSentClientHellos() const;
-
-  // Return true if the handshake performed is a TLS resumption.
-  // Always return false for QUIC Crypto.
-  bool IsResumption() const;
-
-  // Returns true if early data (0-RTT data) was sent and the server accepted
-  // it.
-  bool EarlyDataAccepted() const;
-
-  // Returns true if the handshake was delayed one round trip by the server
-  // because the server wanted proof the client controls its source address
-  // before progressing further. In Google QUIC, this would be due to an
-  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
-  // to a Retry packet.
-  // TODO(nharper): Consider a better name for this method.
-  bool ReceivedInchoateReject() const;
-
-  int GetNumReceivedServerConfigUpdates() const;
-
-  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
-
-  void set_respect_goaway(bool respect_goaway) {
-    respect_goaway_ = respect_goaway;
-  }
-
- protected:
-  // QuicSession methods:
-  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
-  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
-  // If an outgoing stream can be created, return true.
-  bool ShouldCreateOutgoingBidirectionalStream() override;
-  bool ShouldCreateOutgoingUnidirectionalStream() override;
-
-  // If an incoming stream can be created, return true.
-  // TODO(fayang): move this up to QuicSpdyClientSessionBase.
-  bool ShouldCreateIncomingStream(QuicStreamId id) override;
-
-  // Create the crypto stream. Called by Initialize().
-  virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream();
-
-  // Unlike CreateOutgoingBidirectionalStream, which applies a bunch of
-  // sanity checks, this simply returns a new QuicSpdyClientStream. This may be
-  // used by subclasses which want to use a subclass of QuicSpdyClientStream for
-  // streams but wish to use the sanity checks in
-  // CreateOutgoingBidirectionalStream.
-  virtual std::unique_ptr<QuicSpdyClientStream> CreateClientStream();
-
-  const QuicServerId& server_id() const { return server_id_; }
-  QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
-
- private:
-  std::unique_ptr<QuicCryptoClientStreamBase> crypto_stream_;
-  QuicServerId server_id_;
-  QuicCryptoClientConfig* crypto_config_;
-  // Server addresses that are known to the client.
-  std::vector<QuicSocketAddress> known_server_addresses_;
-
-  // If this is set to false, the client will ignore server GOAWAYs and allow
-  // the creation of streams regardless of the high chance they will fail.
-  bool respect_goaway_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/quic/core/http/quic_spdy_client_session_base.cc b/quic/core/http/quic_spdy_client_session_base.cc
deleted file mode 100644
index b761a19..0000000
--- a/quic/core/http/quic_spdy_client_session_base.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_session_base.h"
-
-#include <string>
-
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicSpdyClientSessionBase::QuicSpdyClientSessionBase(
-    QuicConnection* connection,
-    QuicClientPushPromiseIndex* push_promise_index,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions)
-    : QuicSpdySession(connection, nullptr, config, supported_versions),
-      push_promise_index_(push_promise_index),
-      largest_promised_stream_id_(
-          QuicUtils::GetInvalidStreamId(connection->transport_version())) {}
-
-QuicSpdyClientSessionBase::~QuicSpdyClientSessionBase() {
-  //  all promised streams for this session
-  for (auto& it : promised_by_id_) {
-    QUIC_DVLOG(1) << "erase stream " << it.first << " url " << it.second->url();
-    push_promise_index_->promised_by_url()->erase(it.second->url());
-  }
-  DeleteConnection();
-}
-
-void QuicSpdyClientSessionBase::OnConfigNegotiated() {
-  QuicSpdySession::OnConfigNegotiated();
-}
-
-void QuicSpdyClientSessionBase::OnInitialHeadersComplete(
-    QuicStreamId stream_id,
-    const SpdyHeaderBlock& response_headers) {
-  // Note that the strong ordering of the headers stream means that
-  // QuicSpdyClientStream::OnPromiseHeadersComplete must have already
-  // been called (on the associated stream) if this is a promised
-  // stream. However, this stream may not have existed at this time,
-  // hence the need to query the session.
-  QuicClientPromisedInfo* promised = GetPromisedById(stream_id);
-  if (!promised)
-    return;
-
-  promised->OnResponseHeaders(response_headers);
-}
-
-void QuicSpdyClientSessionBase::OnPromiseHeaderList(
-    QuicStreamId stream_id,
-    QuicStreamId promised_stream_id,
-    size_t frame_len,
-    const QuicHeaderList& header_list) {
-  if (IsStaticStream(stream_id)) {
-    connection()->CloseConnection(
-        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  // In HTTP3, push promises are received on individual streams, so they could
-  // be arrive out of order.
-  if (!VersionUsesHttp3(transport_version()) &&
-      promised_stream_id !=
-          QuicUtils::GetInvalidStreamId(transport_version()) &&
-      largest_promised_stream_id_ !=
-          QuicUtils::GetInvalidStreamId(transport_version()) &&
-      promised_stream_id <= largest_promised_stream_id_) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID,
-        "Received push stream id lesser or equal to the"
-        " last accepted before",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  if (!IsIncomingStream(promised_stream_id)) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Received push stream id for outgoing stream.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (VersionUsesHttp3(transport_version())) {
-    // Received push stream id is higher than MAX_PUSH_ID
-    // because no MAX_PUSH_ID frame is ever sent.
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID,
-        "Received push stream id higher than MAX_PUSH_ID.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  largest_promised_stream_id_ = promised_stream_id;
-
-  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
-  if (!stream) {
-    // It's quite possible to receive headers after a stream has been reset.
-    return;
-  }
-  stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
-}
-
-bool QuicSpdyClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
-                                               QuicStreamId promised_id,
-                                               const SpdyHeaderBlock& headers) {
-  // TODO(b/136295430): Do not treat |promised_id| as a stream ID when using
-  // IETF QUIC.
-  // Due to pathalogical packet re-ordering, it is possible that
-  // frames for the promised stream have already arrived, and the
-  // promised stream could be active or closed.
-  if (IsClosedStream(promised_id)) {
-    // There was a RST on the data stream already, perhaps
-    // QUIC_REFUSED_STREAM?
-    QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id
-                  << " that is already closed";
-    return false;
-  }
-
-  if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
-    QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream "
-                  << promised_id;
-    ResetPromised(promised_id, QUIC_REFUSED_STREAM);
-    return false;
-  }
-
-  const std::string url =
-      SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers);
-  QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
-  if (old_promised) {
-    QUIC_DVLOG(1) << "Promise for stream " << promised_id
-                  << " is duplicate URL " << url
-                  << " of previous promise for stream " << old_promised->id();
-    ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL);
-    return false;
-  }
-
-  if (GetPromisedById(promised_id)) {
-    // OnPromiseHeadersComplete() would have closed the connection if
-    // promised id is a duplicate.
-    QUIC_BUG(quic_bug_10412_1) << "Duplicate promise for id " << promised_id;
-    return false;
-  }
-
-  QuicClientPromisedInfo* promised =
-      new QuicClientPromisedInfo(this, promised_id, url);
-  std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
-  promised->Init();
-  QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url;
-  (*push_promise_index_->promised_by_url())[url] = promised;
-  promised_by_id_[promised_id] = std::move(promised_owner);
-  bool result = promised->OnPromiseHeaders(headers);
-  if (result) {
-    QUICHE_DCHECK(promised_by_id_.find(promised_id) != promised_by_id_.end());
-  }
-  return result;
-}
-
-QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedByUrl(
-    const std::string& url) {
-  auto it = push_promise_index_->promised_by_url()->find(url);
-  if (it != push_promise_index_->promised_by_url()->end()) {
-    return it->second;
-  }
-  return nullptr;
-}
-
-QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedById(
-    const QuicStreamId id) {
-  auto it = promised_by_id_.find(id);
-  if (it != promised_by_id_.end()) {
-    return it->second.get();
-  }
-  return nullptr;
-}
-
-QuicSpdyStream* QuicSpdyClientSessionBase::GetPromisedStream(
-    const QuicStreamId id) {
-  QuicStream* stream = GetActiveStream(id);
-  if (stream != nullptr) {
-    return static_cast<QuicSpdyStream*>(stream);
-  }
-  return nullptr;
-}
-
-void QuicSpdyClientSessionBase::DeletePromised(
-    QuicClientPromisedInfo* promised) {
-  push_promise_index_->promised_by_url()->erase(promised->url());
-  // Since promised_by_id_ contains the unique_ptr, this will destroy
-  // promised.
-  // ToDo: Consider implementing logic to send a new MAX_PUSH_ID frame to allow
-  // another stream to be promised.
-  promised_by_id_.erase(promised->id());
-  if (!VersionUsesHttp3(transport_version())) {
-    headers_stream()->MaybeReleaseSequencerBuffer();
-  }
-}
-
-void QuicSpdyClientSessionBase::OnPushStreamTimedOut(
-    QuicStreamId /*stream_id*/) {}
-
-void QuicSpdyClientSessionBase::ResetPromised(
-    QuicStreamId id,
-    QuicRstStreamErrorCode error_code) {
-  QUICHE_DCHECK(QuicUtils::IsServerInitiatedStreamId(transport_version(), id));
-  ResetStream(id, error_code);
-  if (!IsOpenStream(id) && !IsClosedStream(id)) {
-    MaybeIncreaseLargestPeerStreamId(id);
-  }
-}
-
-void QuicSpdyClientSessionBase::OnStreamClosed(QuicStreamId stream_id) {
-  QuicSpdySession::OnStreamClosed(stream_id);
-  if (!VersionUsesHttp3(transport_version())) {
-    headers_stream()->MaybeReleaseSequencerBuffer();
-  }
-}
-
-bool QuicSpdyClientSessionBase::ShouldReleaseHeadersStreamSequencerBuffer() {
-  return !HasActiveRequestStreams() && promised_by_id_.empty();
-}
-
-bool QuicSpdyClientSessionBase::ShouldKeepConnectionAlive() const {
-  return QuicSpdySession::ShouldKeepConnectionAlive() ||
-         num_outgoing_draining_streams() > 0;
-}
-
-bool QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
-  if (!was_zero_rtt_rejected()) {
-    if (max_outbound_header_list_size() != std::numeric_limits<size_t>::max() &&
-        frame.values.find(SETTINGS_MAX_FIELD_SECTION_SIZE) ==
-            frame.values.end()) {
-      CloseConnectionWithDetails(
-          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-          "Server accepted 0-RTT but omitted non-default "
-          "SETTINGS_MAX_FIELD_SECTION_SIZE");
-      return false;
-    }
-
-    if (qpack_encoder()->maximum_blocked_streams() != 0 &&
-        frame.values.find(SETTINGS_QPACK_BLOCKED_STREAMS) ==
-            frame.values.end()) {
-      CloseConnectionWithDetails(
-          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-          "Server accepted 0-RTT but omitted non-default "
-          "SETTINGS_QPACK_BLOCKED_STREAMS");
-      return false;
-    }
-
-    if (qpack_encoder()->MaximumDynamicTableCapacity() != 0 &&
-        frame.values.find(SETTINGS_QPACK_MAX_TABLE_CAPACITY) ==
-            frame.values.end()) {
-      CloseConnectionWithDetails(
-          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-          "Server accepted 0-RTT but omitted non-default "
-          "SETTINGS_QPACK_MAX_TABLE_CAPACITY");
-      return false;
-    }
-  }
-
-  if (!QuicSpdySession::OnSettingsFrame(frame)) {
-    return false;
-  }
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount frame_length =
-      HttpEncoder::SerializeSettingsFrame(frame, &buffer);
-  auto serialized_data = std::make_unique<ApplicationState>(
-      buffer.get(), buffer.get() + frame_length);
-  GetMutableCryptoStream()->SetServerApplicationStateForResumption(
-      std::move(serialized_data));
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session_base.h b/quic/core/http/quic_spdy_client_session_base.h
deleted file mode 100644
index 71236bf..0000000
--- a/quic/core/http/quic_spdy_client_session_base.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
-
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicClientPromisedInfo;
-class QuicClientPushPromiseIndex;
-class QuicSpdyClientStream;
-
-// For client/http layer code. Lookup promised streams based on
-// matching promised request url. The same map can be shared across
-// multiple sessions, since cross-origin pushes are allowed (subject
-// to authority constraints).  Clients should use this map to enforce
-// session affinity for requests corresponding to cross-origin push
-// promised streams.
-using QuicPromisedByUrlMap =
-    absl::flat_hash_map<std::string, QuicClientPromisedInfo*>;
-
-// The maximum time a promises stream can be reserved without being
-// claimed by a client request.
-const int64_t kPushPromiseTimeoutSecs = 60;
-
-// Base class for all client-specific QuicSession subclasses.
-class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
-    : public QuicSpdySession,
-      public QuicCryptoClientStream::ProofHandler {
- public:
-  // Takes ownership of |connection|. Caller retains ownership of
-  // |promised_by_url|.
-  QuicSpdyClientSessionBase(QuicConnection* connection,
-                            QuicClientPushPromiseIndex* push_promise_index,
-                            const QuicConfig& config,
-                            const ParsedQuicVersionVector& supported_versions);
-  QuicSpdyClientSessionBase(const QuicSpdyClientSessionBase&) = delete;
-  QuicSpdyClientSessionBase& operator=(const QuicSpdyClientSessionBase&) =
-      delete;
-
-  ~QuicSpdyClientSessionBase() override;
-
-  void OnConfigNegotiated() override;
-
-  // Called by |headers_stream_| when push promise headers have been
-  // completely received.
-  void OnPromiseHeaderList(QuicStreamId stream_id,
-                           QuicStreamId promised_stream_id,
-                           size_t frame_len,
-                           const QuicHeaderList& header_list) override;
-
-  // Called by |QuicSpdyClientStream| on receipt of response headers,
-  // needed to detect promised server push streams, as part of
-  // client-request to push-stream rendezvous.
-  void OnInitialHeadersComplete(QuicStreamId stream_id,
-                                const spdy::SpdyHeaderBlock& response_headers);
-
-  // Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does
-  // some session level validation and creates the
-  // |QuicClientPromisedInfo| inserting into maps by (promised) id and
-  // url. Returns true if a new push promise is accepted. Resets the promised
-  // stream and returns false otherwise.
-  virtual bool HandlePromised(QuicStreamId associated_id,
-                              QuicStreamId promised_id,
-                              const spdy::SpdyHeaderBlock& headers);
-
-  // For cross-origin server push, this should verify the server is
-  // authoritative per [RFC2818], Section 3.  Roughly, subjectAltName
-  // list in the certificate should contain a matching DNS name, or IP
-  // address.  |hostname| is derived from the ":authority" header field of
-  // the PUSH_PROMISE frame, port if present there will be dropped.
-  virtual bool IsAuthorized(const std::string& hostname) = 0;
-
-  // Session retains ownership.
-  QuicClientPromisedInfo* GetPromisedByUrl(const std::string& url);
-  // Session retains ownership.
-  QuicClientPromisedInfo* GetPromisedById(const QuicStreamId id);
-
-  //
-  QuicSpdyStream* GetPromisedStream(const QuicStreamId id);
-
-  // Removes |promised| from the maps by url.
-  void ErasePromisedByUrl(QuicClientPromisedInfo* promised);
-
-  // Removes |promised| from the maps by url and id and destroys
-  // promised.
-  virtual void DeletePromised(QuicClientPromisedInfo* promised);
-
-  virtual void OnPushStreamTimedOut(QuicStreamId stream_id);
-
-  // Sends Rst for the stream, and makes sure that future calls to
-  // IsClosedStream(id) return true, which ensures that any subsequent
-  // frames related to this stream will be ignored (modulo flow
-  // control accounting).
-  void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
-
-  // Release headers stream's sequencer buffer if it's empty.
-  void OnStreamClosed(QuicStreamId stream_id) override;
-
-  // Returns true if there are no active requests and no promised streams.
-  bool ShouldReleaseHeadersStreamSequencerBuffer() override;
-
-  // Override to wait for all received responses to be consumed by application.
-  bool ShouldKeepConnectionAlive() const override;
-
-  size_t get_max_promises() const {
-    return max_open_incoming_unidirectional_streams() *
-           kMaxPromisedStreamsMultiplier;
-  }
-
-  QuicClientPushPromiseIndex* push_promise_index() {
-    return push_promise_index_;
-  }
-
-  // Override to serialize the settings and pass it down to the handshaker.
-  bool OnSettingsFrame(const SettingsFrame& frame) override;
-
- private:
-  // For QuicSpdyClientStream to detect that a response corresponds to a
-  // promise.
-  using QuicPromisedByIdMap =
-      absl::flat_hash_map<QuicStreamId,
-                          std::unique_ptr<QuicClientPromisedInfo>>;
-
-  // As per rfc7540, section 10.5: track promise streams in "reserved
-  // (remote)".  The primary key is URL from the promise request
-  // headers.  The promised stream id is a secondary key used to get
-  // promise info when the response headers of the promised stream
-  // arrive.
-  QuicClientPushPromiseIndex* push_promise_index_;
-  QuicPromisedByIdMap promised_by_id_;
-  QuicStreamId largest_promised_stream_id_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
deleted file mode 100644
index 2a62046..0000000
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ /dev/null
@@ -1,1345 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_session.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/spdy_server_push_utils.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_spdy_client_stream.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_packet_creator_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-
-using spdy::SpdyHeaderBlock;
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtLeast;
-using ::testing::AtMost;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-using ::testing::Truly;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kPort = 443;
-
-class TestQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
-  explicit TestQuicSpdyClientSession(
-      const QuicConfig& config,
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      const QuicServerId& server_id,
-      QuicCryptoClientConfig* crypto_config,
-      QuicClientPushPromiseIndex* push_promise_index)
-      : QuicSpdyClientSession(config,
-                              supported_versions,
-                              connection,
-                              server_id,
-                              crypto_config,
-                              push_promise_index) {}
-
-  std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
-    return std::make_unique<MockQuicSpdyClientStream>(
-        GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
-  }
-
-  MockQuicSpdyClientStream* CreateIncomingStream(QuicStreamId id) override {
-    if (!ShouldCreateIncomingStream(id)) {
-      return nullptr;
-    }
-    MockQuicSpdyClientStream* stream =
-        new MockQuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-};
-
-class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicSpdyClientSessionTest()
-      : promised_stream_id_(
-            QuicUtils::GetInvalidStreamId(GetParam().transport_version)),
-        associated_stream_id_(
-            QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
-    auto client_cache = std::make_unique<test::SimpleSessionCache>();
-    client_session_cache_ = client_cache.get();
-    client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
-        crypto_test_utils::ProofVerifierForTesting(), std::move(client_cache));
-    server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
-    Initialize();
-    // Advance the time, because timers do not like uninitialized times.
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-
-  ~QuicSpdyClientSessionTest() override {
-    // Session must be destroyed before promised_by_url_
-    session_.reset(nullptr);
-  }
-
-  void Initialize() {
-    session_.reset();
-    connection_ = new ::testing::NiceMock<PacketSavingConnection>(
-        &helper_, &alarm_factory_, Perspective::IS_CLIENT,
-        SupportedVersions(GetParam()));
-    session_ = std::make_unique<TestQuicSpdyClientSession>(
-        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
-        QuicServerId(kServerHostname, kPort, false),
-        client_crypto_config_.get(), &push_promise_index_);
-    session_->Initialize();
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
-        session_->GetMutableCryptoStream());
-    push_promise_[":path"] = "/bar";
-    push_promise_[":authority"] = "www.google.com";
-    push_promise_[":method"] = "GET";
-    push_promise_[":scheme"] = "https";
-    promise_url_ =
-        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
-    promised_stream_id_ = GetNthServerInitiatedUnidirectionalStreamId(
-        connection_->transport_version(), 0);
-    associated_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
-        connection_->transport_version(), 0);
-  }
-
-  // The function ensures that A) the MAX_STREAMS frames get properly deleted
-  // (since the test uses a 'did we leak memory' check ... if we just lose the
-  // frame, the test fails) and B) returns true (instead of the default, false)
-  // which ensures that the rest of the system thinks that the frame actually
-  // was transmitted.
-  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
-    if (frame.type == MAX_STREAMS_FRAME) {
-      DeleteFrame(&const_cast<QuicFrame&>(frame));
-      return true;
-    }
-    return false;
-  }
-
- public:
-  bool ClearStreamsBlockedControlFrame(const QuicFrame& frame) {
-    if (frame.type == STREAMS_BLOCKED_FRAME) {
-      DeleteFrame(&const_cast<QuicFrame&>(frame));
-      return true;
-    }
-    return false;
-  }
-
- protected:
-  void CompleteCryptoHandshake() {
-    CompleteCryptoHandshake(kDefaultMaxStreamsPerConnection);
-  }
-
-  void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
-    if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .Times(::testing::AnyNumber())
-          .WillRepeatedly(Invoke(
-              this, &QuicSpdyClientSessionTest::ClearMaxStreamsControlFrame));
-    }
-    session_->CryptoConnect();
-    QuicConfig config = DefaultQuicConfig();
-    if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-      config.SetMaxUnidirectionalStreamsToSend(server_max_incoming_streams);
-      config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
-    } else {
-      config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
-    }
-    crypto_test_utils::HandshakeWithFakeServer(
-        &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-        connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-  }
-
-  void CreateConnection() {
-    connection_ = new ::testing::NiceMock<PacketSavingConnection>(
-        &helper_, &alarm_factory_, Perspective::IS_CLIENT,
-        SupportedVersions(GetParam()));
-    // Advance the time, because timers do not like uninitialized times.
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    session_ = std::make_unique<TestQuicSpdyClientSession>(
-        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
-        QuicServerId(kServerHostname, kPort, false),
-        client_crypto_config_.get(), &push_promise_index_);
-    session_->Initialize();
-    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
-        session_->GetMutableCryptoStream());
-  }
-
-  void CompleteFirstConnection() {
-    CompleteCryptoHandshake();
-    EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
-    if (session_->version().UsesHttp3()) {
-      SettingsFrame settings;
-      settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-      settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-      settings.values[256] = 4;  // unknown setting
-      session_->OnSettingsFrame(settings);
-    }
-  }
-
-  // Owned by |session_|.
-  QuicCryptoClientStream* crypto_stream_;
-  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
-  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  ::testing::NiceMock<PacketSavingConnection>* connection_;
-  std::unique_ptr<TestQuicSpdyClientSession> session_;
-  QuicClientPushPromiseIndex push_promise_index_;
-  SpdyHeaderBlock push_promise_;
-  std::string promise_url_;
-  QuicStreamId promised_stream_id_;
-  QuicStreamId associated_stream_id_;
-  test::SimpleSessionCache* client_session_cache_;
-};
-
-std::string ParamNameFormatter(
-    const testing::TestParamInfo<QuicSpdyClientSessionTest::ParamType>& info) {
-  return ParsedQuicVersionToString(info.param);
-}
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicSpdyClientSessionTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ParamNameFormatter);
-
-TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
-  CompleteCryptoHandshake();
-}
-
-TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
-  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
-    // This test relies on resumption and is QUIC crypto specific, so it is
-    // disabled for TLS.
-    return;
-  }
-  // Complete a handshake in order to prime the crypto config for 0-RTT.
-  CompleteCryptoHandshake();
-
-  // Now create a second session using the same crypto config.
-  Initialize();
-
-  // Starting the handshake should move immediately to encryption
-  // established and will allow streams to be created.
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_FALSE(QuicUtils::IsCryptoStreamId(connection_->transport_version(),
-                                           stream->id()));
-
-  // Process an "inchoate" REJ from the server which will cause
-  // an inchoate CHLO to be sent and will leave the encryption level
-  // at NONE.
-  CryptoHandshakeMessage rej;
-  crypto_test_utils::FillInDummyReject(&rej);
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  crypto_test_utils::SendHandshakeMessageToStream(
-      session_->GetMutableCryptoStream(), rej, Perspective::IS_CLIENT);
-  EXPECT_FALSE(session_->IsEncryptionEstablished());
-  EXPECT_EQ(ENCRYPTION_INITIAL,
-            QuicPacketCreatorPeer::GetEncryptionLevel(
-                QuicConnectionPeer::GetPacketCreator(connection_)));
-  // Verify that no new streams may be created.
-  EXPECT_TRUE(session_->CreateOutgoingBidirectionalStream() == nullptr);
-  // Verify that no data may be send on existing streams.
-  char data[] = "hello world";
-  QuicConsumedData consumed =
-      session_->WritevData(stream->id(), ABSL_ARRAYSIZE(data), 0, NO_FIN,
-                           NOT_RETRANSMISSION, ENCRYPTION_INITIAL);
-  EXPECT_EQ(0u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-}
-
-TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
-  uint32_t kServerMaxIncomingStreams = 1;
-  CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream);
-  EXPECT_FALSE(session_->CreateOutgoingBidirectionalStream());
-
-  // Close the stream, but without having received a FIN or a RST_STREAM
-  // or MAX_STREAMS (IETF QUIC) and check that a new one can not be created.
-  session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  stream = session_->CreateOutgoingBidirectionalStream();
-  EXPECT_FALSE(stream);
-}
-
-TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
-  uint32_t kServerMaxIncomingStreams = 1;
-  CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_NE(nullptr, stream);
-  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
-
-  // Close the stream and receive an RST frame to remove the unfinished stream
-  session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
-  session_->OnRstStream(QuicRstStreamFrame(kInvalidControlFrameId, stream->id(),
-                                           QUIC_RST_ACKNOWLEDGEMENT, 0));
-  // Check that a new one can be created.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
-    // In IETF QUIC the stream limit increases only if we get a MAX_STREAMS
-    // frame; pretend we got one.
-
-    QuicMaxStreamsFrame frame(0, 2,
-                              /*unidirectional=*/false);
-    session_->OnMaxStreamsFrame(frame);
-  }
-  stream = session_->CreateOutgoingBidirectionalStream();
-  EXPECT_NE(nullptr, stream);
-  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
-    // Ensure that we have 2 total streams, 1 open and 1 closed.
-    QuicStreamCount expected_stream_count = 2;
-    EXPECT_EQ(expected_stream_count,
-              QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
-                  ->outgoing_stream_count());
-  }
-}
-
-TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
-  // Tests the situation in which the client sends a RST at the same time that
-  // the server sends trailing headers (trailers). Receipt of the trailers by
-  // the client should result in all outstanding stream state being tidied up
-  // (including flow control, and number of available outgoing streams).
-  uint32_t kServerMaxIncomingStreams = 1;
-  CompleteCryptoHandshake(kServerMaxIncomingStreams);
-
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_NE(nullptr, stream);
-
-  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
-    // For IETF QUIC, trying to open a stream and failing due to lack
-    // of stream ids will result in a STREAMS_BLOCKED. Make
-    // sure we get one. Also clear out the frame because if it's
-    // left sitting, the later SendRstStream will not actually
-    // transmit the RST_STREAM because the connection will be in write-blocked
-    // state. This means that the SendControlFrame that is expected w.r.t. the
-    // RST_STREAM, below, will not be satisfied.
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .WillOnce(Invoke(
-            this, &QuicSpdyClientSessionTest::ClearStreamsBlockedControlFrame));
-  }
-
-  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
-
-  QuicStreamId stream_id = stream->id();
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(AtLeast(1))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
-  session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
-
-  // A new stream cannot be created as the reset stream still counts as an open
-  // outgoing stream until closed by the server.
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  stream = session_->CreateOutgoingBidirectionalStream();
-  EXPECT_EQ(nullptr, stream);
-
-  // The stream receives trailers with final byte offset: this is one of three
-  // ways that a peer can signal the end of a stream (the others being RST,
-  // stream data + FIN).
-  QuicHeaderList trailers;
-  trailers.OnHeaderBlockStart();
-  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
-  trailers.OnHeaderBlockEnd(0, 0);
-  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
-
-  // The stream is now complete from the client's perspective, and it should
-  // be able to create a new outgoing stream.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
-    QuicMaxStreamsFrame frame(0, 2,
-                              /*unidirectional=*/false);
-
-    session_->OnMaxStreamsFrame(frame);
-  }
-  stream = session_->CreateOutgoingBidirectionalStream();
-  EXPECT_NE(nullptr, stream);
-  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
-    // Ensure that we have 2 open streams.
-    QuicStreamCount expected_stream_count = 2;
-    EXPECT_EQ(expected_stream_count,
-              QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
-                  ->outgoing_stream_count());
-  }
-}
-
-TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
-  // Tests the situation where the client has sent a RST to the server, and has
-  // received trailing headers with a malformed final byte offset value.
-  CompleteCryptoHandshake();
-
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_NE(nullptr, stream);
-
-  // Send the RST, which results in the stream being closed locally (but some
-  // state remains while the client waits for a response from the server).
-  QuicStreamId stream_id = stream->id();
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(AtLeast(1))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
-  session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
-
-  // The stream receives trailers with final byte offset, but the header value
-  // is non-numeric and should be treated as malformed.
-  QuicHeaderList trailers;
-  trailers.OnHeaderBlockStart();
-  trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
-  trailers.OnHeaderBlockEnd(0, 0);
-
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
-  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnStreamHeaderListWithStaticStream) {
-  // Test situation where OnStreamHeaderList is called by stream with static id.
-  CompleteCryptoHandshake();
-
-  QuicHeaderList trailers;
-  trailers.OnHeaderBlockStart();
-  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
-  trailers.OnHeaderBlockEnd(0, 0);
-
-  // Initialize H/3 control stream.
-  QuicStreamId id;
-  if (VersionUsesHttp3(connection_->transport_version())) {
-    id = GetNthServerInitiatedUnidirectionalStreamId(
-        connection_->transport_version(), 3);
-    char type[] = {0x00};
-
-    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
-    session_->OnStreamFrame(data1);
-  } else {
-    id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
-  }
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                            "stream is static", _))
-      .Times(1);
-  session_->OnStreamHeaderList(id,
-                               /*fin=*/false, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) {
-  // Test situation where OnPromiseHeaderList is called by stream with static
-  // id.
-  CompleteCryptoHandshake();
-
-  QuicHeaderList trailers;
-  trailers.OnHeaderBlockStart();
-  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
-  trailers.OnHeaderBlockEnd(0, 0);
-
-  // Initialize H/3 control stream.
-  QuicStreamId id;
-  if (VersionUsesHttp3(connection_->transport_version())) {
-    id = GetNthServerInitiatedUnidirectionalStreamId(
-        connection_->transport_version(), 3);
-    char type[] = {0x00};
-
-    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
-    session_->OnStreamFrame(data1);
-  } else {
-    id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
-  }
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                            "stream is static", _))
-      .Times(1);
-  session_->OnPromiseHeaderList(id, promised_stream_id_, 0, trailers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, GoAwayReceived) {
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    return;
-  }
-  CompleteCryptoHandshake();
-
-  // After receiving a GoAway, I should no longer be able to create outgoing
-  // streams.
-  session_->connection()->OnGoAwayFrame(QuicGoAwayFrame(
-      kInvalidControlFrameId, QUIC_PEER_GOING_AWAY, 1u, "Going away."));
-  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
-}
-
-static bool CheckForDecryptionError(QuicFramer* framer) {
-  return framer->error() == QUIC_DECRYPTION_FAILURE;
-}
-
-// Various sorts of invalid packets that should not cause a connection
-// to be closed.
-TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
-  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
-  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
-
-  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
-      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
-                             &MockQuicConnection::ReallyProcessUdpPacket));
-  EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
-  EXPECT_CALL(*connection_, OnError(_)).Times(1);
-
-  // Verify that empty packets don't close the connection.
-  QuicReceivedPacket zero_length_packet(nullptr, 0, QuicTime::Zero(), false);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_->ProcessUdpPacket(client_address, server_address,
-                             zero_length_packet);
-
-  // Verifiy that small, invalid packets don't close the connection.
-  char buf[2] = {0x00, 0x01};
-  QuicConnectionId connection_id = session_->connection()->connection_id();
-  QuicReceivedPacket valid_packet(buf, 2, QuicTime::Zero(), false);
-  // Close connection shouldn't be called.
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*connection_, OnError(_)).Times(AtMost(1));
-  session_->ProcessUdpPacket(client_address, server_address, valid_packet);
-
-  // Verify that a non-decryptable packet doesn't close the connection.
-  QuicFramerPeer::SetLastSerializedServerConnectionId(
-      QuicConnectionPeer::GetFramer(connection_), connection_id);
-  ParsedQuicVersionVector versions = SupportedVersions(GetParam());
-  QuicConnectionId destination_connection_id = EmptyQuicConnectionId();
-  QuicConnectionId source_connection_id = connection_id;
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      destination_connection_id, source_connection_id, false, false, 100,
-      "data", true, CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT,
-      PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*packet, QuicTime::Zero()));
-  // Change the last byte of the encrypted data.
-  *(const_cast<char*>(received->data() + received->length() - 1)) += 1;
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
-  session_->ProcessUdpPacket(client_address, server_address, *received);
-}
-
-// A packet with invalid framing should cause a connection to be closed.
-TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
-  const ParsedQuicVersion version = GetParam();
-  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
-  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
-  if (version.KnowsWhichDecrypterToUse()) {
-    connection_->InstallDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-  } else {
-    connection_->SetDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-  }
-
-  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
-      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
-                             &MockQuicConnection::ReallyProcessUdpPacket));
-  EXPECT_CALL(*connection_, OnError(_)).Times(1);
-
-  // Verify that a decryptable packet with bad frames does close the connection.
-  QuicConnectionId destination_connection_id =
-      session_->connection()->connection_id();
-  QuicConnectionId source_connection_id = EmptyQuicConnectionId();
-  QuicFramerPeer::SetLastSerializedServerConnectionId(
-      QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
-  bool version_flag = false;
-  QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
-  if (version.HasIetfInvariantHeader()) {
-    version_flag = true;
-    source_connection_id = destination_connection_id;
-    scid_included = CONNECTION_ID_PRESENT;
-  }
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
-      destination_connection_id, source_connection_id, version_flag, false, 100,
-      "data", CONNECTION_ID_ABSENT, scid_included, PACKET_4BYTE_PACKET_NUMBER,
-      version, Perspective::IS_SERVER));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*packet, QuicTime::Zero()));
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
-  session_->ProcessUdpPacket(client_address, server_address, *received);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeaders) {
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    return;
-  }
-
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
-      session_->CreateOutgoingBidirectionalStream());
-
-  EXPECT_CALL(*stream, OnPromiseHeaderList(_, _, _));
-  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
-                                QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseStreamIdTooHigh) {
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    return;
-  }
-
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-  QuicStreamId stream_id =
-      QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
-  QuicSessionPeer::ActivateStream(
-      session_.get(), std::make_unique<QuicSpdyClientStream>(
-                          stream_id, session_.get(), BIDIRECTIONAL));
-
-  QuicHeaderList headers;
-  headers.OnHeaderBlockStart();
-  headers.OnHeader(":path", "/bar");
-  headers.OnHeader(":authority", "www.google.com");
-  headers.OnHeader(":method", "GET");
-  headers.OnHeader(":scheme", "https");
-  headers.OnHeaderBlockEnd(0, 0);
-
-  const QuicStreamId promise_id = GetNthServerInitiatedUnidirectionalStreamId(
-      connection_->transport_version(), 11);
-  session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->CreateOutgoingBidirectionalStream();
-
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
-  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
-
-  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
-                                QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOutOfOrder) {
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    return;
-  }
-
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
-      session_->CreateOutgoingBidirectionalStream());
-
-  EXPECT_CALL(*stream, OnPromiseHeaderList(promised_stream_id_, _, _));
-  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
-                                QuicHeaderList());
-  associated_stream_id_ +=
-      QuicUtils::StreamIdDelta(connection_->transport_version());
-  if (!VersionUsesHttp3(session_->transport_version())) {
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_INVALID_STREAM_ID,
-                                "Received push stream id lesser or equal to the"
-                                " last accepted before",
-                                _));
-  }
-  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
-                                QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseOutgoingStreamId) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
-      session_->CreateOutgoingBidirectionalStream());
-
-  // Promise an illegal (outgoing) stream id.
-  promised_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
-      connection_->transport_version(), 0);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_STREAM_ID,
-                      "Received push stream id for outgoing stream.", _));
-
-  session_->OnPromiseHeaderList(stream->id(), promised_stream_id_, 0,
-                                QuicHeaderList());
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseHandlePromise) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->CreateOutgoingBidirectionalStream();
-
-  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
-                                       promised_stream_id_, push_promise_));
-
-  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->CreateOutgoingBidirectionalStream();
-  session_->GetOrCreateStream(promised_stream_id_);
-
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
-
-  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
-  SpdyHeaderBlock promise_headers;
-  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
-                                        promised_stream_id_, promise_headers));
-
-  // Verify that the promise was not created.
-  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->CreateOutgoingBidirectionalStream();
-
-  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
-                                       promised_stream_id_, push_promise_));
-
-  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
-  promised_stream_id_ +=
-      QuicUtils::StreamIdDelta(connection_->transport_version());
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
-
-  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
-                                        promised_stream_id_, push_promise_));
-
-  // Verify that the promise was not created.
-  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
-  CompleteCryptoHandshake();
-  for (size_t i = 0u; i < session_->get_max_promises(); i++) {
-    push_promise_[":path"] = absl::StrCat("/bar", i);
-
-    QuicStreamId id =
-        promised_stream_id_ +
-        i * QuicUtils::StreamIdDelta(connection_->transport_version());
-
-    EXPECT_TRUE(
-        session_->HandlePromised(associated_stream_id_, id, push_promise_));
-
-    // Verify that the promise is in the unclaimed streams map.
-    std::string promise_url(
-        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
-    EXPECT_NE(session_->GetPromisedByUrl(promise_url), nullptr);
-    EXPECT_NE(session_->GetPromisedById(id), nullptr);
-  }
-
-  // One more promise, this should be refused.
-  int i = session_->get_max_promises();
-  push_promise_[":path"] = absl::StrCat("/bar", i);
-
-  QuicStreamId id =
-      promised_stream_id_ +
-      i * QuicUtils::StreamIdDelta(connection_->transport_version());
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
-  EXPECT_FALSE(
-      session_->HandlePromised(associated_stream_id_, id, push_promise_));
-
-  // Verify that the promise was not created.
-  std::string promise_url(
-      SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
-  EXPECT_EQ(session_->GetPromisedById(id), nullptr);
-  EXPECT_EQ(session_->GetPromisedByUrl(promise_url), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->GetOrCreateStream(promised_stream_id_);
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
-  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
-  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
-}
-
-TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
-  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
-  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsPush) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-  session_->GetOrCreateStream(promised_stream_id_);
-  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
-                                       promised_stream_id_, push_promise_));
-  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
-  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
-  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
-}
-
-TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-  session_->CreateOutgoingBidirectionalStream();
-  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
-}
-
-TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-  session_->GetOrCreateStream(promised_stream_id_);
-  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
-                                       promised_stream_id_, push_promise_));
-  QuicClientPromisedInfo* promised =
-      session_->GetPromisedById(promised_stream_id_);
-  EXPECT_NE(promised, nullptr);
-  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
-  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-
-  session_->DeletePromised(promised);
-  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-  session_->GetOrCreateStream(promised_stream_id_);
-  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
-                                       promised_stream_id_, push_promise_));
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
-  session_->ResetStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY);
-  QuicClientPromisedInfo* promised =
-      session_->GetPromisedById(promised_stream_id_);
-  EXPECT_NE(promised, nullptr);
-  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
-  EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->CreateOutgoingBidirectionalStream();
-
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
-
-  push_promise_[":method"] = "POST";
-  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
-                                        promised_stream_id_, push_promise_));
-
-  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-
-  session_->CreateOutgoingBidirectionalStream();
-
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
-
-  push_promise_[":authority"] = "";
-  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
-                                        promised_stream_id_, push_promise_));
-
-  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
-  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
-}
-
-TEST_P(QuicSpdyClientSessionTest,
-       TryToCreateServerInitiatedBidirectionalStream) {
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM, _, _));
-  } else {
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  }
-  session_->GetOrCreateStream(GetNthServerInitiatedBidirectionalStreamId(
-      connection_->transport_version(), 0));
-}
-
-TEST_P(QuicSpdyClientSessionTest, TooManyPushPromises) {
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    return;
-  }
-
-  // Initialize crypto before the client session will create a stream.
-  CompleteCryptoHandshake();
-  QuicStreamId stream_id =
-      QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
-  QuicSessionPeer::ActivateStream(
-      session_.get(), std::make_unique<QuicSpdyClientStream>(
-                          stream_id, session_.get(), BIDIRECTIONAL));
-
-  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM));
-
-  for (size_t promise_count = 0; promise_count <= session_->get_max_promises();
-       promise_count++) {
-    auto promise_id = GetNthServerInitiatedUnidirectionalStreamId(
-        connection_->transport_version(), promise_count);
-    auto headers = QuicHeaderList();
-    headers.OnHeaderBlockStart();
-    headers.OnHeader(":path", absl::StrCat("/", promise_count));
-    headers.OnHeader(":authority", "www.google.com");
-    headers.OnHeader(":method", "GET");
-    headers.OnHeader(":scheme", "https");
-    headers.OnHeaderBlockEnd(0, 0);
-    session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
-  }
-}
-
-// Test that upon receiving HTTP/3 SETTINGS, the settings are serialized and
-// stored into client session cache.
-TEST_P(QuicSpdyClientSessionTest, OnSettingsFrame) {
-  // This feature is HTTP/3 only
-  if (!VersionUsesHttp3(session_->transport_version())) {
-    return;
-  }
-  CompleteCryptoHandshake();
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  settings.values[256] = 4;   // unknown setting
-  char application_state[] = {// type (SETTINGS)
-                              0x04,
-                              // length
-                              0x07,
-                              // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
-                              0x01,
-                              // content
-                              0x02,
-                              // identifier (SETTINGS_MAX_FIELD_SECTION_SIZE)
-                              0x06,
-                              // content
-                              0x05,
-                              // identifier (256 in variable length integer)
-                              0x40 + 0x01, 0x00,
-                              // content
-                              0x04};
-  ApplicationState expected(std::begin(application_state),
-                            std::end(application_state));
-  session_->OnSettingsFrame(settings);
-  EXPECT_EQ(expected, *client_session_cache_
-                           ->Lookup(QuicServerId(kServerHostname, kPort, false),
-                                    session_->GetClock()->WallNow(), nullptr)
-                           ->application_state);
-}
-
-TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
-  // This feature is TLS-only.
-  if (session_->version().UsesQuicCrypto()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  CreateConnection();
-  // Session configs should be in initial state.
-  if (session_->version().UsesHttp3()) {
-    EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
-    EXPECT_EQ(std::numeric_limits<size_t>::max(),
-              session_->max_outbound_header_list_size());
-  } else {
-    EXPECT_EQ(kMinimumFlowControlSendWindow,
-              session_->flow_controller()->send_window_offset());
-  }
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
-
-  // The client session should have a basic setup ready before the handshake
-  // succeeds.
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            session_->flow_controller()->send_window_offset());
-  if (session_->version().UsesHttp3()) {
-    auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
-    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-              id_manager->max_outgoing_bidirectional_streams());
-    EXPECT_EQ(
-        kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
-        id_manager->max_outgoing_unidirectional_streams());
-    auto* control_stream =
-        QuicSpdySessionPeer::GetSendControlStream(session_.get());
-    EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
-              QuicStreamPeer::SendWindowOffset(control_stream));
-    EXPECT_EQ(5u, session_->max_outbound_header_list_size());
-  } else {
-    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
-    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-              id_manager->max_open_outgoing_streams());
-  }
-
-  // Complete the handshake with a different config.
-  QuicConfig config = DefaultQuicConfig();
-  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
-      kInitialStreamFlowControlWindowForTest + 1);
-  config.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest + 1);
-  config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
-  config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-
-  EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1,
-            session_->flow_controller()->send_window_offset());
-  if (session_->version().UsesHttp3()) {
-    auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
-    auto* control_stream =
-        QuicSpdySessionPeer::GetSendControlStream(session_.get());
-    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
-              id_manager->max_outgoing_bidirectional_streams());
-    EXPECT_EQ(kDefaultMaxStreamsPerConnection +
-                  kHttp3StaticUnidirectionalStreamCount + 1,
-              id_manager->max_outgoing_unidirectional_streams());
-    EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
-              QuicStreamPeer::SendWindowOffset(control_stream));
-  } else {
-    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
-    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
-              id_manager->max_open_outgoing_streams());
-  }
-
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  // Let the session receive a new SETTINGS frame to complete the second
-  // connection.
-  if (session_->version().UsesHttp3()) {
-    SettingsFrame settings;
-    settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-    settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-    settings.values[256] = 4;  // unknown setting
-    session_->OnSettingsFrame(settings);
-  }
-}
-
-// Regression test for b/159168475
-TEST_P(QuicSpdyClientSessionTest, RetransmitDataOnZeroRttReject) {
-  // This feature is TLS-only.
-  if (session_->version().UsesQuicCrypto()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  // Create a second connection, but disable 0-RTT on the server.
-  CreateConnection();
-  ON_CALL(*connection_, OnCanWrite())
-      .WillByDefault(
-          testing::Invoke(connection_, &MockQuicConnection::ReallyOnCanWrite));
-  EXPECT_CALL(*connection_, OnCanWrite()).Times(0);
-
-  QuicConfig config = DefaultQuicConfig();
-  config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
-  config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-
-  // Packets will be written: CHLO, HTTP/3 SETTINGS (H/3 only), and request
-  // data.
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION))
-      .Times(session_->version().UsesHttp3() ? 2 : 1);
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream);
-  stream->WriteOrBufferData("hello", true, nullptr);
-
-  // When handshake is done, the client sends 2 packet: HANDSHAKE FINISHED, and
-  // coalesced retransmission of HTTP/3 SETTINGS and request data.
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
-  // TODO(b/158027651): change transmission type to ALL_ZERO_RTT_RETRANSMISSION.
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-  EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
-}
-
-// When IETF QUIC 0-RTT is rejected, a server-sent fresh transport params is
-// available. If the new transport params reduces stream/flow control limit to
-// lower than what the client has already used, connection will be closed.
-TEST_P(QuicSpdyClientSessionTest, ZeroRttRejectReducesStreamLimitTooMuch) {
-  // This feature is TLS-only.
-  if (session_->version().UsesQuicCrypto()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  // Create a second connection, but disable 0-RTT on the server.
-  CreateConnection();
-  QuicConfig config = DefaultQuicConfig();
-  // Server doesn't allow any bidirectional streams.
-  config.SetMaxBidirectionalStreamsToSend(0);
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream);
-
-  if (session_->version().UsesHttp3()) {
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(
-            QUIC_ZERO_RTT_UNRETRANSMITTABLE,
-            "Server rejected 0-RTT, aborting because new bidirectional initial "
-            "stream limit 0 is less than current open streams: 1",
-            _))
-        .WillOnce(testing::Invoke(connection_,
-                                  &MockQuicConnection::ReallyCloseConnection));
-  } else {
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_INTERNAL_ERROR,
-                        "Server rejected 0-RTT, aborting because new stream "
-                        "limit 0 is less than current open streams: 1",
-                        _))
-        .WillOnce(testing::Invoke(connection_,
-                                  &MockQuicConnection::ReallyCloseConnection));
-  }
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-}
-
-TEST_P(QuicSpdyClientSessionTest,
-       ZeroRttRejectReducesStreamFlowControlTooMuch) {
-  // This feature is TLS-only.
-  if (session_->version().UsesQuicCrypto()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  // Create a second connection, but disable 0-RTT on the server.
-  CreateConnection();
-  QuicConfig config = DefaultQuicConfig();
-  // Server doesn't allow any outgoing streams.
-  config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(2);
-  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(1);
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream);
-  // Let the stream write more than 1 byte of data.
-  stream->WriteOrBufferData("hello", true, nullptr);
-
-  if (session_->version().UsesHttp3()) {
-    // Both control stream and the request stream will report errors.
-    // Open question: should both streams be closed with the same error code?
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _))
-        .WillOnce(testing::Invoke(connection_,
-                                  &MockQuicConnection::ReallyCloseConnection));
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
-        .WillOnce(testing::Invoke(connection_,
-                                  &MockQuicConnection::ReallyCloseConnection))
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*connection_,
-                CloseConnection(
-                    QUIC_ZERO_RTT_UNRETRANSMITTABLE,
-                    "Server rejected 0-RTT, aborting because new stream max "
-                    "data 2 for stream 3 is less than currently used: 5",
-                    _))
-        .Times(1)
-        .WillOnce(testing::Invoke(connection_,
-                                  &MockQuicConnection::ReallyCloseConnection));
-  }
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-}
-
-TEST_P(QuicSpdyClientSessionTest,
-       ZeroRttRejectReducesSessionFlowControlTooMuch) {
-  // This feature is TLS-only.
-  if (session_->version().UsesQuicCrypto()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  // Create a second connection, but disable 0-RTT on the server.
-  CreateConnection();
-  QuicConfig config = DefaultQuicConfig();
-  // Server doesn't allow minimum data in session.
-  config.SetInitialSessionFlowControlWindowToSend(
-      kMinimumFlowControlSendWindow);
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
-  ASSERT_TRUE(stream);
-  std::string data_to_send(kMinimumFlowControlSendWindow + 1, 'x');
-  // Let the stream write some data.
-  stream->WriteOrBufferData(data_to_send, true, nullptr);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
-      .WillOnce(testing::Invoke(connection_,
-                                &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-}
-
-TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttResumption) {
-  if (!session_->version().UsesHttp3()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  CreateConnection();
-  CompleteCryptoHandshake();
-  EXPECT_TRUE(session_->GetCryptoStream()->EarlyDataAccepted());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
-      .WillOnce(testing::Invoke(connection_,
-                                &MockQuicConnection::ReallyCloseConnection));
-  // Let the session receive a different SETTINGS frame.
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  settings.values[256] = 4;  // unknown setting
-  session_->OnSettingsFrame(settings);
-}
-
-TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttRejection) {
-  if (!session_->version().UsesHttp3()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  CreateConnection();
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  session_->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-  QuicConfig config = DefaultQuicConfig();
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
-      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
-  EXPECT_FALSE(session_->GetCryptoStream()->EarlyDataAccepted());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH, _, _))
-      .WillOnce(testing::Invoke(connection_,
-                                &MockQuicConnection::ReallyCloseConnection));
-  // Let the session receive a different SETTINGS frame.
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-  // setting on SETTINGS_MAX_FIELD_SECTION_SIZE is reduced.
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 4;
-  settings.values[256] = 4;  // unknown setting
-  session_->OnSettingsFrame(settings);
-}
-
-TEST_P(QuicSpdyClientSessionTest, ServerAcceptsZeroRttButOmitSetting) {
-  if (!session_->version().UsesHttp3()) {
-    return;
-  }
-
-  CompleteFirstConnection();
-
-  CreateConnection();
-  CompleteCryptoHandshake();
-  EXPECT_TRUE(session_->GetMutableCryptoStream()->EarlyDataAccepted());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
-      .WillOnce(testing::Invoke(connection_,
-                                &MockQuicConnection::ReallyCloseConnection));
-  // Let the session receive a different SETTINGS frame.
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
-  // Intentionally omit SETTINGS_MAX_FIELD_SECTION_SIZE which was previously
-  // sent with a non-zero value.
-  settings.values[256] = 4;  // unknown setting
-  session_->OnSettingsFrame(settings);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_stream.cc b/quic/core/http/quic_spdy_client_stream.cc
deleted file mode 100644
index 2491900..0000000
--- a/quic/core/http/quic_spdy_client_stream.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_stream.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
-                                           QuicSpdyClientSession* session,
-                                           StreamType type)
-    : QuicSpdyStream(id, session, type),
-      content_length_(-1),
-      response_code_(0),
-      header_bytes_read_(0),
-      header_bytes_written_(0),
-      session_(session),
-      has_preliminary_headers_(false) {}
-
-QuicSpdyClientStream::QuicSpdyClientStream(PendingStream* pending,
-                                           QuicSpdyClientSession* session)
-    : QuicSpdyStream(pending, session),
-      content_length_(-1),
-      response_code_(0),
-      header_bytes_read_(0),
-      header_bytes_written_(0),
-      session_(session),
-      has_preliminary_headers_(false) {}
-
-QuicSpdyClientStream::~QuicSpdyClientStream() = default;
-
-void QuicSpdyClientStream::OnInitialHeadersComplete(
-    bool fin,
-    size_t frame_len,
-    const QuicHeaderList& header_list) {
-  QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
-
-  QUICHE_DCHECK(headers_decompressed());
-  header_bytes_read_ += frame_len;
-  if (rst_sent()) {
-    // QuicSpdyStream::OnInitialHeadersComplete already rejected invalid
-    // response header.
-    return;
-  }
-
-  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
-                                         &response_headers_)) {
-    QUIC_DLOG(ERROR) << "Failed to parse header list: "
-                     << header_list.DebugString() << " on stream " << id();
-    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-    return;
-  }
-
-  if (web_transport() != nullptr) {
-    web_transport()->HeadersReceived(response_headers_);
-    if (!web_transport()->ready()) {
-      // The request was rejected by WebTransport, typically due to not having a
-      // 2xx status.  The reason we're using Reset() here rather than closing
-      // cleanly is that even if the server attempts to send us any form of body
-      // with a 4xx request, we've already set up the capsule parser, and we
-      // don't have any way to process anything from the response body in
-      // question.
-      Reset(QUIC_STREAM_CANCELLED);
-      return;
-    }
-  }
-
-  if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
-    QUIC_DLOG(ERROR) << "Received invalid response code: "
-                     << response_headers_[":status"].as_string()
-                     << " on stream " << id();
-    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-    return;
-  }
-
-  if (response_code_ == 101) {
-    // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
-    // "HTTP Upgrade" section of draft-ietf-quic-http.
-    QUIC_DLOG(ERROR) << "Received forbidden 101 response code"
-                     << " on stream " << id();
-    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-    return;
-  }
-
-  if (response_code_ >= 100 && response_code_ < 200) {
-    // These are Informational 1xx headers, not the actual response headers.
-    QUIC_DLOG(INFO) << "Received informational response code: "
-                    << response_headers_[":status"].as_string() << " on stream "
-                    << id();
-    set_headers_decompressed(false);
-    if (response_code_ == 100 && !has_preliminary_headers_) {
-      // This is 100 Continue, save it to enable "Expect: 100-continue".
-      has_preliminary_headers_ = true;
-      preliminary_headers_ = std::move(response_headers_);
-    } else {
-      response_headers_.clear();
-    }
-  }
-
-  ConsumeHeaderList();
-  QUIC_DVLOG(1) << "headers complete for stream " << id();
-
-  session_->OnInitialHeadersComplete(id(), response_headers_);
-}
-
-void QuicSpdyClientStream::OnTrailingHeadersComplete(
-    bool fin,
-    size_t frame_len,
-    const QuicHeaderList& header_list) {
-  QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
-  MarkTrailersConsumed();
-}
-
-void QuicSpdyClientStream::OnPromiseHeaderList(
-    QuicStreamId promised_id,
-    size_t frame_len,
-    const QuicHeaderList& header_list) {
-  header_bytes_read_ += frame_len;
-  int64_t content_length = -1;
-  SpdyHeaderBlock promise_headers;
-  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length,
-                                         &promise_headers)) {
-    QUIC_DLOG(ERROR) << "Failed to parse promise headers: "
-                     << header_list.DebugString();
-    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-    return;
-  }
-
-  session_->HandlePromised(id(), promised_id, promise_headers);
-  if (visitor() != nullptr) {
-    visitor()->OnPromiseHeadersComplete(promised_id, frame_len);
-  }
-}
-
-void QuicSpdyClientStream::OnBodyAvailable() {
-  // For push streams, visitor will not be set until the rendezvous
-  // between server promise and client request is complete.
-  if (visitor() == nullptr)
-    return;
-
-  while (HasBytesToRead()) {
-    struct iovec iov;
-    if (GetReadableRegions(&iov, 1) == 0) {
-      // No more data to read.
-      break;
-    }
-    QUIC_DVLOG(1) << "Client processed " << iov.iov_len << " bytes for stream "
-                  << id();
-    data_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
-    if (content_length_ >= 0 &&
-        data_.size() > static_cast<uint64_t>(content_length_)) {
-      QUIC_DLOG(ERROR) << "Invalid content length (" << content_length_
-                       << ") with data of size " << data_.size();
-      Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-      return;
-    }
-    MarkConsumed(iov.iov_len);
-  }
-  if (sequencer()->IsClosed()) {
-    OnFinRead();
-  } else {
-    sequencer()->SetUnblocked();
-  }
-}
-
-size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
-                                         absl::string_view body,
-                                         bool fin) {
-  QuicConnection::ScopedPacketFlusher flusher(session_->connection());
-  bool send_fin_with_headers = fin && body.empty();
-  size_t bytes_sent = body.size();
-  header_bytes_written_ =
-      WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
-  bytes_sent += header_bytes_written_;
-
-  if (!body.empty()) {
-    WriteOrBufferBody(body, fin);
-  }
-
-  return bytes_sent;
-}
-
-bool QuicSpdyClientStream::AreHeadersValid(
-    const QuicHeaderList& header_list) const {
-  if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
-    return true;
-  }
-  if (!QuicSpdyStream::AreHeadersValid(header_list)) {
-    return false;
-  }
-  // Verify the presence of :status header.
-  bool saw_status = false;
-  for (const std::pair<std::string, std::string>& pair : header_list) {
-    if (pair.first == ":status") {
-      saw_status = true;
-    } else if (absl::StrContains(pair.first, ":")) {
-      QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
-      return false;
-    }
-  }
-  return saw_status;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_client_stream.h b/quic/core/http/quic_spdy_client_stream.h
deleted file mode 100644
index 7d420f5..0000000
--- a/quic/core/http/quic_spdy_client_stream.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
-
-#include <cstddef>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/quic_packets.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-class QuicSpdyClientSession;
-
-// All this does right now is send an SPDY request, and aggregate the
-// SPDY response.
-class QUIC_EXPORT_PRIVATE QuicSpdyClientStream : public QuicSpdyStream {
- public:
-  QuicSpdyClientStream(QuicStreamId id,
-                       QuicSpdyClientSession* session,
-                       StreamType type);
-  QuicSpdyClientStream(PendingStream* pending,
-                       QuicSpdyClientSession* spdy_session);
-  QuicSpdyClientStream(const QuicSpdyClientStream&) = delete;
-  QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete;
-  ~QuicSpdyClientStream() override;
-
-  // Override the base class to parse and store headers.
-  void OnInitialHeadersComplete(bool fin,
-                                size_t frame_len,
-                                const QuicHeaderList& header_list) override;
-
-  // Override the base class to parse and store trailers.
-  void OnTrailingHeadersComplete(bool fin,
-                                 size_t frame_len,
-                                 const QuicHeaderList& header_list) override;
-
-  // Override the base class to handle creation of the push stream.
-  void OnPromiseHeaderList(QuicStreamId promised_id,
-                           size_t frame_len,
-                           const QuicHeaderList& header_list) override;
-
-  // QuicStream implementation called by the session when there's data for us.
-  void OnBodyAvailable() override;
-
-  // Serializes the headers and body, sends it to the server, and
-  // returns the number of bytes sent.
-  size_t SendRequest(spdy::SpdyHeaderBlock headers,
-                     absl::string_view body,
-                     bool fin);
-
-  // Returns the response data.
-  const std::string& data() { return data_; }
-
-  // Returns whatever headers have been received for this stream.
-  const spdy::SpdyHeaderBlock& response_headers() { return response_headers_; }
-
-  const spdy::SpdyHeaderBlock& preliminary_headers() {
-    return preliminary_headers_;
-  }
-
-  size_t header_bytes_read() const { return header_bytes_read_; }
-
-  size_t header_bytes_written() const { return header_bytes_written_; }
-
-  int response_code() const { return response_code_; }
-
-  // While the server's SetPriority shouldn't be called externally, the creator
-  // of client-side streams should be able to set the priority.
-  using QuicSpdyStream::SetPriority;
-
- protected:
-  bool AreHeadersValid(const QuicHeaderList& header_list) const override;
-
- private:
-  // The parsed headers received from the server.
-  spdy::SpdyHeaderBlock response_headers_;
-
-  // The parsed content-length, or -1 if none is specified.
-  int64_t content_length_;
-  int response_code_;
-  std::string data_;
-  size_t header_bytes_read_;
-  size_t header_bytes_written_;
-
-  QuicSpdyClientSession* session_;
-
-  // These preliminary headers are used for the 100 Continue headers
-  // that may arrive before the response headers when the request has
-  // Expect: 100-continue.
-  bool has_preliminary_headers_;
-  spdy::SpdyHeaderBlock preliminary_headers_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/quic/core/http/quic_spdy_client_stream_test.cc b/quic/core/http/quic_spdy_client_stream_test.cc
deleted file mode 100644
index a7e5d86..0000000
--- a/quic/core/http/quic_spdy_client_stream_test.cc
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_client_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/simple_buffer_allocator.h"
-
-using spdy::SpdyHeaderBlock;
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-namespace {
-
-class MockQuicSpdyClientSession : public QuicSpdyClientSession {
- public:
-  explicit MockQuicSpdyClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      QuicClientPushPromiseIndex* push_promise_index)
-      : QuicSpdyClientSession(DefaultQuicConfig(),
-                              supported_versions,
-                              connection,
-                              QuicServerId("example.com", 443, false),
-                              &crypto_config_,
-                              push_promise_index),
-        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
-  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
-  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
-      delete;
-  ~MockQuicSpdyClientSession() override = default;
-
-  MOCK_METHOD(bool,
-              WriteControlFrame,
-              (const QuicFrame& frame, TransmissionType type),
-              (override));
-
-  using QuicSession::ActivateStream;
-
- private:
-  QuicCryptoClientConfig crypto_config_;
-};
-
-class QuicSpdyClientStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  class StreamVisitor;
-
-  QuicSpdyClientStreamTest()
-      : connection_(
-            new StrictMock<MockQuicConnection>(&helper_,
-                                               &alarm_factory_,
-                                               Perspective::IS_CLIENT,
-                                               SupportedVersions(GetParam()))),
-        session_(connection_->supported_versions(),
-                 connection_,
-                 &push_promise_index_),
-        body_("hello world") {
-    session_.Initialize();
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    headers_[":status"] = "200";
-    headers_["content-length"] = "11";
-
-    auto stream = std::make_unique<QuicSpdyClientStream>(
-        GetNthClientInitiatedBidirectionalStreamId(
-            connection_->transport_version(), 0),
-        &session_, BIDIRECTIONAL);
-    stream_ = stream.get();
-    session_.ActivateStream(std::move(stream));
-
-    stream_visitor_ = std::make_unique<StreamVisitor>();
-    stream_->set_visitor(stream_visitor_.get());
-  }
-
-  class StreamVisitor : public QuicSpdyClientStream::Visitor {
-    void OnClose(QuicSpdyStream* stream) override {
-      QUIC_DVLOG(1) << "stream " << stream->id();
-    }
-  };
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  QuicClientPushPromiseIndex push_promise_index_;
-
-  MockQuicSpdyClientSession session_;
-  QuicSpdyClientStream* stream_;
-  std::unique_ptr<StreamVisitor> stream_visitor_;
-  SpdyHeaderBlock headers_;
-  std::string body_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicSpdyClientStreamTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
-  headers_[":status"] = "200 ok";
-
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  EXPECT_THAT(stream_->stream_error(),
-              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, InvalidResponseHeader) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  auto headers = AsHeaderList(std::vector<std::pair<std::string, std::string>>{
-      {":status", "200"}, {":path", "/foo"}});
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  EXPECT_THAT(stream_->stream_error(),
-              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, MissingStatusCode) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  auto headers = AsHeaderList(
-      std::vector<std::pair<std::string, std::string>>{{"key", "value"}});
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  EXPECT_THAT(stream_->stream_error(),
-              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestFraming) {
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data = VersionUsesHttp3(connection_->transport_version())
-                         ? absl::StrCat(header.AsStringView(), body_)
-                         : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
-  EXPECT_EQ(200, stream_->response_code());
-  EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_P(QuicSpdyClientStreamTest, Test100ContinueBeforeSuccessful) {
-  // First send 100 Continue.
-  headers_[":status"] = "100";
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
-  EXPECT_EQ(0u, stream_->response_headers().size());
-  EXPECT_EQ(100, stream_->response_code());
-  EXPECT_EQ("", stream_->data());
-  // Then send 200 OK.
-  headers_[":status"] = "200";
-  headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data = VersionUsesHttp3(connection_->transport_version())
-                         ? absl::StrCat(header.AsStringView(), body_)
-                         : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  // Make sure the 200 response got parsed correctly.
-  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
-  EXPECT_EQ(200, stream_->response_code());
-  EXPECT_EQ(body_, stream_->data());
-  // Make sure the 100 response is still available.
-  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestUnknownInformationalBeforeSuccessful) {
-  // First send 199, an unknown Informational (1XX).
-  headers_[":status"] = "199";
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  EXPECT_EQ(0u, stream_->response_headers().size());
-  EXPECT_EQ(199, stream_->response_code());
-  EXPECT_EQ("", stream_->data());
-  // Then send 200 OK.
-  headers_[":status"] = "200";
-  headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data = VersionUsesHttp3(connection_->transport_version())
-                         ? absl::StrCat(header.AsStringView(), body_)
-                         : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  // Make sure the 200 response got parsed correctly.
-  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
-  EXPECT_EQ(200, stream_->response_code());
-  EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestReceiving101) {
-  // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
-  // "HTTP Upgrade" section of draft-ietf-quic-http.
-  headers_[":status"] = "101";
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  EXPECT_THAT(stream_->stream_error(),
-              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data = VersionUsesHttp3(connection_->transport_version())
-                         ? absl::StrCat(header.AsStringView(), body_)
-                         : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
-  EXPECT_EQ(200, stream_->response_code());
-  EXPECT_EQ(body_, stream_->data());
-}
-
-TEST_P(QuicSpdyClientStreamTest,
-       QUIC_TEST_DISABLED_IN_CHROME(TestFramingExtraData)) {
-  std::string large_body = "hello world!!!!!!";
-
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  // The headers should parse successfully.
-  EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
-  EXPECT_EQ(200, stream_->response_code());
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      large_body.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data = VersionUsesHttp3(connection_->transport_version())
-                         ? absl::StrCat(header.AsStringView(), large_body)
-                         : large_body;
-  EXPECT_CALL(session_, WriteControlFrame(_, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
-
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-
-  EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
-}
-
-// Test that receiving trailing headers (on the headers stream), containing a
-// final offset, results in the stream being closed at that byte offset.
-TEST_P(QuicSpdyClientStreamTest, ReceivingTrailers) {
-  // There is no kFinalOffsetHeaderKey if trailers are sent on the
-  // request/response stream.
-  if (VersionUsesHttp3(connection_->transport_version())) {
-    return;
-  }
-
-  // Send headers as usual.
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-
-  // Send trailers before sending the body. Even though a FIN has been received
-  // the stream should not be closed, as it does not yet have all the data bytes
-  // promised by the final offset field.
-  SpdyHeaderBlock trailer_block;
-  trailer_block["trailer key"] = "trailer value";
-  trailer_block[kFinalOffsetHeaderKey] = absl::StrCat(body_.size());
-  auto trailers = AsHeaderList(trailer_block);
-  stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(),
-                              trailers);
-
-  // Now send the body, which should close the stream as the FIN has been
-  // received, as well as all data.
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data = VersionUsesHttp3(connection_->transport_version())
-                         ? absl::StrCat(header.AsStringView(), body_)
-                         : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  EXPECT_TRUE(stream_->reading_stopped());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_server_stream_base.cc b/quic/core/http/quic_spdy_server_stream_base.cc
deleted file mode 100644
index 8b57fb6..0000000
--- a/quic/core/http/quic_spdy_server_stream_base.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_server_stream_base.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(QuicStreamId id,
-                                                   QuicSpdySession* session,
-                                                   StreamType type)
-    : QuicSpdyStream(id, session, type) {}
-
-QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(PendingStream* pending,
-                                                   QuicSpdySession* session)
-    : QuicSpdyStream(pending, session) {}
-
-void QuicSpdyServerStreamBase::CloseWriteSide() {
-  if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
-      !rst_sent()) {
-    // Early cancel the stream if it has stopped reading before receiving FIN
-    // or RST.
-    QUICHE_DCHECK(fin_sent() || !session()->connection()->connected());
-    // Tell the peer to stop sending further data.
-    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
-    MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
-  }
-
-  QuicSpdyStream::CloseWriteSide();
-}
-
-void QuicSpdyServerStreamBase::StopReading() {
-  if (!fin_received() && !rst_received() && write_side_closed() &&
-      !rst_sent()) {
-    QUICHE_DCHECK(fin_sent());
-    // Tell the peer to stop sending further data.
-    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
-    MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
-  }
-  QuicSpdyStream::StopReading();
-}
-
-bool QuicSpdyServerStreamBase::AreHeadersValid(
-    const QuicHeaderList& header_list) const {
-  if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
-    return true;
-  }
-  QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 2, 3);
-  if (!QuicSpdyStream::AreHeadersValid(header_list)) {
-    return false;
-  }
-
-  bool saw_connect = false;
-  bool saw_protocol = false;
-  bool saw_path = false;
-  bool saw_scheme = false;
-  bool saw_method = false;
-  bool saw_authority = false;
-  bool is_extended_connect = false;
-  // Check if it is missing any required headers and if there is any disallowed
-  // ones.
-  for (const std::pair<std::string, std::string>& pair : header_list) {
-    if (pair.first == ":method") {
-      saw_method = true;
-      if (pair.second == "CONNECT") {
-        saw_connect = true;
-        if (saw_protocol) {
-          is_extended_connect = true;
-        }
-      }
-    } else if (pair.first == ":protocol") {
-      saw_protocol = true;
-      if (saw_connect) {
-        is_extended_connect = true;
-      }
-    } else if (pair.first == ":scheme") {
-      saw_scheme = true;
-    } else if (pair.first == ":path") {
-      saw_path = true;
-    } else if (pair.first == ":authority") {
-      saw_authority = true;
-    } else if (absl::StrContains(pair.first, ":")) {
-      QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
-      return false;
-    }
-    if (is_extended_connect) {
-      if (!spdy_session()->allow_extended_connect()) {
-        QUIC_DLOG(ERROR)
-            << "Received extended-CONNECT request while it is disabled.";
-        return false;
-      }
-    } else if (saw_method && !saw_connect) {
-      if (saw_protocol) {
-        QUIC_DLOG(ERROR) << "Receive non-CONNECT request with :protocol.";
-        return false;
-      }
-    }
-  }
-
-  if (is_extended_connect) {
-    if (saw_scheme && saw_path && saw_authority) {
-      // Saw all the required pseudo headers.
-      return true;
-    }
-    QUIC_DLOG(ERROR) << "Missing required pseudo headers for extended-CONNECT.";
-    return false;
-  }
-  // This is a vanilla CONNECT or non-CONNECT request.
-  if (saw_connect) {
-    // Check vanilla CONNECT.
-    if (saw_path || saw_scheme) {
-      QUIC_DLOG(ERROR)
-          << "Received invalid CONNECT request with disallowed pseudo header.";
-      return false;
-    }
-    return true;
-  }
-  // Check non-CONNECT request.
-  if (saw_method && saw_authority && saw_path && saw_scheme) {
-    return true;
-  }
-  QUIC_LOG(ERROR) << "Missing required pseudo headers.";
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_server_stream_base.h b/quic/core/http/quic_spdy_server_stream_base.h
deleted file mode 100644
index d10a6d4..0000000
--- a/quic/core/http/quic_spdy_server_stream_base.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
-
-#include "quic/core/http/quic_spdy_stream.h"
-
-namespace quic {
-
-class QUIC_NO_EXPORT QuicSpdyServerStreamBase : public QuicSpdyStream {
- public:
-  QuicSpdyServerStreamBase(QuicStreamId id,
-                           QuicSpdySession* session,
-                           StreamType type);
-  QuicSpdyServerStreamBase(PendingStream* pending, QuicSpdySession* session);
-  QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete;
-  QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete;
-
-  // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
-  // when the stream has not received all the data.
-  void CloseWriteSide() override;
-  void StopReading() override;
-
- protected:
-  bool AreHeadersValid(const QuicHeaderList& header_list) const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/quic/core/http/quic_spdy_server_stream_base_test.cc b/quic/core/http/quic_spdy_server_stream_base_test.cc
deleted file mode 100644
index ae22781..0000000
--- a/quic/core/http/quic_spdy_server_stream_base_test.cc
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_server_stream_base.h"
-
-#include "absl/memory/memory.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestQuicSpdyServerStream : public QuicSpdyServerStreamBase {
- public:
-  TestQuicSpdyServerStream(QuicStreamId id, QuicSpdySession* session,
-                           StreamType type)
-      : QuicSpdyServerStreamBase(id, session, type) {}
-
-  void OnBodyAvailable() override {}
-};
-
-class QuicSpdyServerStreamBaseTest : public QuicTest {
- protected:
-  QuicSpdyServerStreamBaseTest()
-      : session_(new MockQuicConnection(&helper_, &alarm_factory_,
-                                        Perspective::IS_SERVER)) {
-    session_.Initialize();
-    session_.connection()->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(session_.perspective()));
-    stream_ =
-        new TestQuicSpdyServerStream(GetNthClientInitiatedBidirectionalStreamId(
-                                         session_.transport_version(), 0),
-                                     &session_, BIDIRECTIONAL);
-    session_.ActivateStream(absl::WrapUnique(stream_));
-    helper_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-
-  QuicSpdyServerStreamBase* stream_ = nullptr;
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicSpdySession session_;
-};
-
-TEST_F(QuicSpdyServerStreamBaseTest,
-       SendQuicRstStreamNoErrorWithEarlyResponse) {
-  stream_->StopReading();
-
-  if (session_.version().UsesHttp3()) {
-    EXPECT_CALL(session_,
-                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
-                                                 QUIC_STREAM_NO_ERROR)))
-        .Times(1);
-  } else {
-    EXPECT_CALL(
-        session_,
-        MaybeSendRstStreamFrame(
-            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
-        .Times(1);
-  }
-  QuicStreamPeer::SetFinSent(stream_);
-  stream_->CloseWriteSide();
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest,
-       DoNotSendQuicRstStreamNoErrorWithRstReceived) {
-  EXPECT_FALSE(stream_->reading_stopped());
-
-  EXPECT_CALL(session_,
-              MaybeSendRstStreamFrame(
-                  _,
-                  QuicResetStreamError::FromInternal(
-                      VersionHasIetfQuicFrames(session_.transport_version())
-                          ? QUIC_STREAM_CANCELLED
-                          : QUIC_RST_ACKNOWLEDGEMENT),
-                  _))
-      .Times(1);
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  if (VersionHasIetfQuicFrames(session_.transport_version())) {
-    // Create and inject a STOP SENDING frame to complete the close
-    // of the stream. This is only needed for version 99/IETF QUIC.
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
-                                      QUIC_STREAM_CANCELLED);
-    session_.OnStopSendingFrame(stop_sending);
-  }
-
-  EXPECT_TRUE(stream_->reading_stopped());
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnect) {
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  header_list.OnHeader(":protocol", "webtransport");
-  header_list.OnHeader(":path", "/path");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeaderBlockEnd(128, 128);
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
-                GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
-                !session_.allow_extended_connect(),
-            stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnectProtocolFirst) {
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":protocol", "webtransport");
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  header_list.OnHeader(":path", "/path");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeaderBlockEnd(128, 128);
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
-                GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
-                !session_.allow_extended_connect(),
-            stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidExtendedConnect) {
-  if (!session_.version().UsesHttp3()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  header_list.OnHeader(":protocol", "webtransport");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, VanillaConnectAllowed) {
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  header_list.OnHeaderBlockEnd(128, 128);
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_FALSE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidVanillaConnect) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidNonConnectWithProtocol) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "GET");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeader(":path", "/path");
-  header_list.OnHeader(":protocol", "webtransport");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutScheme) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  // A request without :scheme should be rejected.
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "GET");
-  header_list.OnHeader(":path", "/path");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutAuthority) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  // A request without :authority should be rejected.
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeader(":method", "GET");
-  header_list.OnHeader(":path", "/path");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutMethod) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  // A request without :method should be rejected.
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeader(":path", "/path");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutPath) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  // A request without :path should be rejected.
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeader(":method", "POST");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestHeader) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  // A request without :path should be rejected.
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":scheme", "http");
-  header_list.OnHeader(":method", "POST");
-  header_list.OnHeader("invalid:header", "value");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-TEST_F(QuicSpdyServerStreamBaseTest, EmptyHeaders) {
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  spdy::SpdyHeaderBlock empty_header;
-  quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
-  quic::test::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
-  auto qpack_encoder =
-      std::make_unique<quic::QpackEncoder>(&decoder_stream_error_delegate);
-  qpack_encoder->set_qpack_stream_sender_delegate(
-      &encoder_stream_sender_delegate);
-  std::string payload =
-      qpack_encoder->EncodeHeaderList(stream_->id(), empty_header, nullptr);
-  std::unique_ptr<char[]> headers_buffer;
-  quic::QuicByteCount headers_frame_header_length =
-      quic::HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
-                                                     &headers_buffer);
-  absl::string_view headers_frame_header(headers_buffer.get(),
-                                         headers_frame_header_length);
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
-          _));
-  stream_->OnStreamFrame(QuicStreamFrame(
-      stream_->id(), true, 0, absl::StrCat(headers_frame_header, payload)));
-  EXPECT_TRUE(stream_->rst_sent());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
deleted file mode 100644
index 5276671..0000000
--- a/quic/core/http/quic_spdy_session.cc
+++ /dev/null
@@ -1,1949 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_session.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_headers_stream.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-
-using http2::Http2DecoderAdapter;
-using spdy::Http2WeightToSpdy3Priority;
-using spdy::Spdy3PriorityToHttp2Weight;
-using spdy::SpdyErrorCode;
-using spdy::SpdyFramer;
-using spdy::SpdyFramerDebugVisitorInterface;
-using spdy::SpdyFramerVisitorInterface;
-using spdy::SpdyFrameType;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyHeadersHandlerInterface;
-using spdy::SpdyHeadersIR;
-using spdy::SpdyPingId;
-using spdy::SpdyPriority;
-using spdy::SpdyPriorityIR;
-using spdy::SpdyPushPromiseIR;
-using spdy::SpdySerializedFrame;
-using spdy::SpdySettingsId;
-using spdy::SpdyStreamId;
-
-namespace quic {
-
-ABSL_CONST_INIT const size_t kMaxUnassociatedWebTransportStreams = 24;
-
-namespace {
-
-// Limit on HPACK encoder dynamic table size.
-// Only used for Google QUIC, not IETF QUIC.
-constexpr uint64_t kHpackEncoderDynamicTableSizeLimit = 16384;
-
-#define ENDPOINT \
-  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-// Class to forward ACCEPT_CH frame to QuicSpdySession,
-// and ignore every other frame.
-class AlpsFrameDecoder : public HttpDecoder::Visitor {
- public:
-  explicit AlpsFrameDecoder(QuicSpdySession* session) : session_(session) {}
-  ~AlpsFrameDecoder() override = default;
-
-  // HttpDecoder::Visitor implementation.
-  void OnError(HttpDecoder* /*decoder*/) override {}
-  bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
-    error_detail_ = "MAX_PUSH_ID frame forbidden";
-    return false;
-  }
-  bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
-    error_detail_ = "GOAWAY frame forbidden";
-    return false;
-  }
-  bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
-    return true;
-  }
-  bool OnSettingsFrame(const SettingsFrame& frame) override {
-    if (settings_frame_received_via_alps_) {
-      error_detail_ = "multiple SETTINGS frames";
-      return false;
-    }
-
-    settings_frame_received_via_alps_ = true;
-
-    error_detail_ = session_->OnSettingsFrameViaAlps(frame);
-    return !error_detail_;
-  }
-  bool OnDataFrameStart(QuicByteCount /*header_length*/, QuicByteCount
-                        /*payload_length*/) override {
-    error_detail_ = "DATA frame forbidden";
-    return false;
-  }
-  bool OnDataFramePayload(absl::string_view /*payload*/) override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-  bool OnDataFrameEnd() override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-  bool OnHeadersFrameStart(QuicByteCount /*header_length*/,
-                           QuicByteCount /*payload_length*/) override {
-    error_detail_ = "HEADERS frame forbidden";
-    return false;
-  }
-  bool OnHeadersFramePayload(absl::string_view /*payload*/) override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-  bool OnHeadersFrameEnd() override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-  bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
-    error_detail_ = "PRIORITY_UPDATE frame forbidden";
-    return false;
-  }
-  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-  bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
-    return true;
-  }
-  bool OnAcceptChFrame(const AcceptChFrame& frame) override {
-    session_->OnAcceptChFrameReceivedViaAlps(frame);
-    return true;
-  }
-  void OnWebTransportStreamFrameType(
-      QuicByteCount /*header_length*/,
-      WebTransportSessionId /*session_id*/) override {
-    QUICHE_NOTREACHED();
-  }
-  bool OnUnknownFrameStart(uint64_t /*frame_type*/,
-                           QuicByteCount
-                           /*header_length*/,
-                           QuicByteCount /*payload_length*/) override {
-    return true;
-  }
-  bool OnUnknownFramePayload(absl::string_view /*payload*/) override {
-    return true;
-  }
-  bool OnUnknownFrameEnd() override { return true; }
-
-  const absl::optional<std::string>& error_detail() const {
-    return error_detail_;
-  }
-
- private:
-  QuicSpdySession* const session_;
-  absl::optional<std::string> error_detail_;
-
-  // True if SETTINGS frame has been received via ALPS.
-  bool settings_frame_received_via_alps_ = false;
-};
-
-}  // namespace
-
-// A SpdyFramerVisitor that passes HEADERS frames to the QuicSpdyStream, and
-// closes the connection if any unexpected frames are received.
-class QuicSpdySession::SpdyFramerVisitor
-    : public SpdyFramerVisitorInterface,
-      public SpdyFramerDebugVisitorInterface {
- public:
-  explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {}
-  SpdyFramerVisitor(const SpdyFramerVisitor&) = delete;
-  SpdyFramerVisitor& operator=(const SpdyFramerVisitor&) = delete;
-
-  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      SpdyStreamId /* stream_id */) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-    return &header_list_;
-  }
-
-  void OnHeaderFrameEnd(SpdyStreamId /* stream_id */) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-
-    LogHeaderCompressionRatioHistogram(
-        /* using_qpack = */ false,
-        /* is_sent = */ false, header_list_.compressed_header_bytes(),
-        header_list_.uncompressed_header_bytes());
-
-    if (session_->IsConnected()) {
-      session_->OnHeaderList(header_list_);
-    }
-    header_list_.Clear();
-  }
-
-  void OnStreamFrameData(SpdyStreamId /*stream_id*/, const char* /*data*/,
-                         size_t /*len*/) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-    CloseConnection("SPDY DATA frame received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnStreamEnd(SpdyStreamId /*stream_id*/) override {
-    // The framer invokes OnStreamEnd after processing a frame that had the fin
-    // bit set.
-  }
-
-  void OnStreamPadding(SpdyStreamId /*stream_id*/, size_t /*len*/) override {
-    CloseConnection("SPDY frame padding received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnError(Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error) override {
-    QuicErrorCode code;
-    switch (error) {
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INDEX_VARINT_ERROR:
-        code = QUIC_HPACK_INDEX_VARINT_ERROR;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
-        code = QUIC_HPACK_NAME_LENGTH_VARINT_ERROR;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
-        code = QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG:
-        code = QUIC_HPACK_NAME_TOO_LONG;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG:
-        code = QUIC_HPACK_VALUE_TOO_LONG;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_HUFFMAN_ERROR:
-        code = QUIC_HPACK_NAME_HUFFMAN_ERROR;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_HUFFMAN_ERROR:
-        code = QUIC_HPACK_VALUE_HUFFMAN_ERROR;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
-        code = QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX:
-        code = QUIC_HPACK_INVALID_INDEX;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_NAME_INDEX:
-        code = QUIC_HPACK_INVALID_NAME_INDEX;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
-        code = QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
-        code = QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
-        code = QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK:
-        code = QUIC_HPACK_TRUNCATED_BLOCK;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG:
-        code = QUIC_HPACK_FRAGMENT_TOO_LONG;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
-        code = QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
-        break;
-      case Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
-        code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE;
-        break;
-      default:
-        code = QUIC_INVALID_HEADERS_STREAM_DATA;
-    }
-    CloseConnection(
-        absl::StrCat("SPDY framing error: ", detailed_error,
-                     Http2DecoderAdapter::SpdyFramerErrorToString(error)),
-        code);
-  }
-
-  void OnDataFrameHeader(SpdyStreamId /*stream_id*/, size_t /*length*/,
-                         bool /*fin*/) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-    CloseConnection("SPDY DATA frame received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnRstStream(SpdyStreamId /*stream_id*/,
-                   SpdyErrorCode /*error_code*/) override {
-    CloseConnection("SPDY RST_STREAM frame received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnSetting(SpdySettingsId id, uint32_t value) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-    session_->OnSetting(id, value);
-  }
-
-  void OnSettingsEnd() override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-  }
-
-  void OnPing(SpdyPingId /*unique_id*/, bool /*is_ack*/) override {
-    CloseConnection("SPDY PING frame received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnGoAway(SpdyStreamId /*last_accepted_stream_id*/,
-                SpdyErrorCode /*error_code*/) override {
-    CloseConnection("SPDY GOAWAY frame received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
-                 SpdyStreamId /* parent_stream_id */, bool /* exclusive */,
-                 bool fin, bool /*end*/) override {
-    if (!session_->IsConnected()) {
-      return;
-    }
-
-    if (VersionUsesHttp3(session_->transport_version())) {
-      CloseConnection("HEADERS frame not allowed on headers stream.",
-                      QUIC_INVALID_HEADERS_STREAM_DATA);
-      return;
-    }
-
-    QUIC_BUG_IF(quic_bug_12477_1,
-                session_->destruction_indicator() != 123456789)
-        << "QuicSpdyStream use after free. "
-        << session_->destruction_indicator() << QuicStackTrace();
-
-    SpdyPriority priority =
-        has_priority ? Http2WeightToSpdy3Priority(weight) : 0;
-    session_->OnHeaders(stream_id, has_priority,
-                        spdy::SpdyStreamPrecedence(priority), fin);
-  }
-
-  void OnWindowUpdate(SpdyStreamId /*stream_id*/,
-                      int /*delta_window_size*/) override {
-    CloseConnection("SPDY WINDOW_UPDATE frame received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-  }
-
-  void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
-                     bool /*end*/) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-    if (session_->perspective() != Perspective::IS_CLIENT) {
-      CloseConnection("PUSH_PROMISE not supported.",
-                      QUIC_INVALID_HEADERS_STREAM_DATA);
-      return;
-    }
-    if (!session_->IsConnected()) {
-      return;
-    }
-    session_->OnPushPromise(stream_id, promised_stream_id);
-  }
-
-  void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
-
-  void OnPriority(SpdyStreamId stream_id, SpdyStreamId /* parent_id */,
-                  int weight, bool /* exclusive */) override {
-    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
-    if (!session_->IsConnected()) {
-      return;
-    }
-    SpdyPriority priority = Http2WeightToSpdy3Priority(weight);
-    session_->OnPriority(stream_id, spdy::SpdyStreamPrecedence(priority));
-  }
-
-  void OnPriorityUpdate(SpdyStreamId /*prioritized_stream_id*/,
-                        absl::string_view /*priority_field_value*/) override {
-    // TODO(b/171470299): Parse and call
-    // QuicSpdySession::OnPriorityUpdateForRequestStream().
-  }
-
-  bool OnUnknownFrame(SpdyStreamId /*stream_id*/,
-                      uint8_t /*frame_type*/) override {
-    CloseConnection("Unknown frame type received.",
-                    QUIC_INVALID_HEADERS_STREAM_DATA);
-    return false;
-  }
-
-  // SpdyFramerDebugVisitorInterface implementation
-  void OnSendCompressedFrame(SpdyStreamId /*stream_id*/, SpdyFrameType /*type*/,
-                             size_t payload_len, size_t frame_len) override {
-    if (payload_len == 0) {
-      QUIC_BUG(quic_bug_10360_1) << "Zero payload length.";
-      return;
-    }
-    int compression_pct = 100 - (100 * frame_len) / payload_len;
-    QUIC_DVLOG(1) << "Net.QuicHpackCompressionPercentage: " << compression_pct;
-  }
-
-  void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
-                                SpdyFrameType /*type*/,
-                                size_t frame_len) override {
-    if (session_->IsConnected()) {
-      session_->OnCompressedFrameSize(frame_len);
-    }
-  }
-
-  void set_max_header_list_size(size_t max_header_list_size) {
-    header_list_.set_max_header_list_size(max_header_list_size);
-  }
-
- private:
-  void CloseConnection(const std::string& details, QuicErrorCode code) {
-    if (session_->IsConnected()) {
-      session_->CloseConnectionWithDetails(code, details);
-    }
-  }
-
-  QuicSpdySession* session_;
-  QuicHeaderList header_list_;
-};
-
-Http3DebugVisitor::Http3DebugVisitor() {}
-
-Http3DebugVisitor::~Http3DebugVisitor() {}
-
-// Expected unidirectional static streams Requirement can be found at
-// https://tools.ietf.org/html/draft-ietf-quic-http-22#section-6.2.
-QuicSpdySession::QuicSpdySession(
-    QuicConnection* connection, QuicSession::Visitor* visitor,
-    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions)
-    : QuicSession(connection, visitor, config, supported_versions,
-                  /*num_expected_unidirectional_static_streams = */
-                  VersionUsesHttp3(connection->transport_version())
-                      ? static_cast<QuicStreamCount>(
-                            kHttp3StaticUnidirectionalStreamCount)
-                      : 0u,
-                  std::make_unique<DatagramObserver>(this)),
-      send_control_stream_(nullptr),
-      receive_control_stream_(nullptr),
-      qpack_encoder_receive_stream_(nullptr),
-      qpack_decoder_receive_stream_(nullptr),
-      qpack_encoder_send_stream_(nullptr),
-      qpack_decoder_send_stream_(nullptr),
-      qpack_maximum_dynamic_table_capacity_(
-          kDefaultQpackMaxDynamicTableCapacity),
-      qpack_maximum_blocked_streams_(kDefaultMaximumBlockedStreams),
-      max_inbound_header_list_size_(kDefaultMaxUncompressedHeaderSize),
-      max_outbound_header_list_size_(std::numeric_limits<size_t>::max()),
-      stream_id_(
-          QuicUtils::GetInvalidStreamId(connection->transport_version())),
-      promised_stream_id_(
-          QuicUtils::GetInvalidStreamId(connection->transport_version())),
-      frame_len_(0),
-      fin_(false),
-      spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
-      spdy_framer_visitor_(new SpdyFramerVisitor(this)),
-      debug_visitor_(nullptr),
-      destruction_indicator_(123456789),
-      allow_extended_connect_(
-          GetQuicReloadableFlag(quic_verify_request_headers_2) &&
-          perspective() == Perspective::IS_SERVER &&
-          VersionUsesHttp3(transport_version())) {
-  h2_deframer_.set_visitor(spdy_framer_visitor_.get());
-  h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get());
-  spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
-}
-
-QuicSpdySession::~QuicSpdySession() {
-  QUIC_BUG_IF(quic_bug_12477_2, destruction_indicator_ != 123456789)
-      << "QuicSpdySession use after free. " << destruction_indicator_
-      << QuicStackTrace();
-  destruction_indicator_ = 987654321;
-}
-
-void QuicSpdySession::Initialize() {
-  QuicSession::Initialize();
-
-  FillSettingsFrame();
-  if (!VersionUsesHttp3(transport_version())) {
-    if (perspective() == Perspective::IS_SERVER) {
-      set_largest_peer_created_stream_id(
-          QuicUtils::GetHeadersStreamId(transport_version()));
-    } else {
-      QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId();
-      QUICHE_DCHECK_EQ(headers_stream_id,
-                       QuicUtils::GetHeadersStreamId(transport_version()));
-    }
-    auto headers_stream = std::make_unique<QuicHeadersStream>((this));
-    QUICHE_DCHECK_EQ(QuicUtils::GetHeadersStreamId(transport_version()),
-                     headers_stream->id());
-
-    headers_stream_ = headers_stream.get();
-    ActivateStream(std::move(headers_stream));
-  } else {
-    qpack_encoder_ = std::make_unique<QpackEncoder>(this);
-    qpack_decoder_ =
-        std::make_unique<QpackDecoder>(qpack_maximum_dynamic_table_capacity_,
-                                       qpack_maximum_blocked_streams_, this);
-    MaybeInitializeHttp3UnidirectionalStreams();
-  }
-
-  spdy_framer_visitor_->set_max_header_list_size(max_inbound_header_list_size_);
-
-  // Limit HPACK buffering to 2x header list size limit.
-  h2_deframer_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
-      2 * max_inbound_header_list_size_);
-}
-
-void QuicSpdySession::FillSettingsFrame() {
-  settings_.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
-      qpack_maximum_dynamic_table_capacity_;
-  settings_.values[SETTINGS_QPACK_BLOCKED_STREAMS] =
-      qpack_maximum_blocked_streams_;
-  settings_.values[SETTINGS_MAX_FIELD_SECTION_SIZE] =
-      max_inbound_header_list_size_;
-  if (version().UsesHttp3()) {
-    HttpDatagramSupport local_http_datagram_support =
-        LocalHttpDatagramSupport();
-    if (local_http_datagram_support == HttpDatagramSupport::kDraft00 ||
-        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
-      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
-    }
-    if (local_http_datagram_support == HttpDatagramSupport::kDraft04 ||
-        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
-      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-    }
-  }
-  if (WillNegotiateWebTransport()) {
-    settings_.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
-  }
-  if (allow_extended_connect()) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 1, 3);
-    settings_.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
-  }
-}
-
-void QuicSpdySession::OnDecoderStreamError(QuicErrorCode error_code,
-                                           absl::string_view error_message) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  CloseConnectionWithDetails(
-      error_code, absl::StrCat("Decoder stream error: ", error_message));
-}
-
-void QuicSpdySession::OnEncoderStreamError(QuicErrorCode error_code,
-                                           absl::string_view error_message) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  CloseConnectionWithDetails(
-      error_code, absl::StrCat("Encoder stream error: ", error_message));
-}
-
-void QuicSpdySession::OnStreamHeadersPriority(
-    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
-  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
-  if (!stream) {
-    // It's quite possible to receive headers after a stream has been reset.
-    return;
-  }
-  stream->OnStreamHeadersPriority(precedence);
-}
-
-void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id, bool fin,
-                                         size_t frame_len,
-                                         const QuicHeaderList& header_list) {
-  if (IsStaticStream(stream_id)) {
-    connection()->CloseConnection(
-        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
-  if (stream == nullptr) {
-    // The stream no longer exists, but trailing headers may contain the final
-    // byte offset necessary for flow control and open stream accounting.
-    size_t final_byte_offset = 0;
-    for (const auto& header : header_list) {
-      const std::string& header_key = header.first;
-      const std::string& header_value = header.second;
-      if (header_key == kFinalOffsetHeaderKey) {
-        if (!absl::SimpleAtoi(header_value, &final_byte_offset)) {
-          connection()->CloseConnection(
-              QUIC_INVALID_HEADERS_STREAM_DATA,
-              "Trailers are malformed (no final offset)",
-              ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-          return;
-        }
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "Received final byte offset in trailers for stream "
-                      << stream_id << ", which no longer exists.";
-        OnFinalByteOffsetReceived(stream_id, final_byte_offset);
-      }
-    }
-
-    // It's quite possible to receive headers after a stream has been reset.
-    return;
-  }
-  stream->OnStreamHeaderList(fin, frame_len, header_list);
-}
-
-void QuicSpdySession::OnPriorityFrame(
-    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
-  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
-  if (!stream) {
-    // It's quite possible to receive a PRIORITY frame after a stream has been
-    // reset.
-    return;
-  }
-  stream->OnPriorityFrame(precedence);
-}
-
-bool QuicSpdySession::OnPriorityUpdateForRequestStream(QuicStreamId stream_id,
-                                                       int urgency) {
-  if (perspective() == Perspective::IS_CLIENT ||
-      !QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
-      !QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
-    return true;
-  }
-
-  QuicStreamCount advertised_max_incoming_bidirectional_streams =
-      GetAdvertisedMaxIncomingBidirectionalStreams();
-  if (advertised_max_incoming_bidirectional_streams == 0 ||
-      stream_id > QuicUtils::GetFirstBidirectionalStreamId(
-                      transport_version(), Perspective::IS_CLIENT) +
-                      QuicUtils::StreamIdDelta(transport_version()) *
-                          (advertised_max_incoming_bidirectional_streams - 1)) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID,
-        "PRIORITY_UPDATE frame received for invalid stream.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  if (MaybeSetStreamPriority(stream_id, spdy::SpdyStreamPrecedence(urgency))) {
-    return true;
-  }
-
-  if (IsClosedStream(stream_id)) {
-    return true;
-  }
-
-  buffered_stream_priorities_[stream_id] = urgency;
-
-  if (buffered_stream_priorities_.size() >
-      10 * max_open_incoming_bidirectional_streams()) {
-    // This should never happen, because |buffered_stream_priorities_| should
-    // only contain entries for streams that are allowed to be open by the peer
-    // but have not been opened yet.
-    std::string error_message =
-        absl::StrCat("Too many stream priority values buffered: ",
-                     buffered_stream_priorities_.size(),
-                     ", which should not exceed the incoming stream limit of ",
-                     max_open_incoming_bidirectional_streams());
-    QUIC_BUG(quic_bug_10360_2) << error_message;
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR, error_message,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicSpdySession::OnPriorityUpdateForPushStream(QuicStreamId /*push_id*/,
-                                                    int /*urgency*/) {
-  // TODO(b/147306124): Implement PRIORITY_UPDATE frames for pushed streams.
-  return true;
-}
-
-size_t QuicSpdySession::ProcessHeaderData(const struct iovec& iov) {
-  QUIC_BUG_IF(quic_bug_12477_4, destruction_indicator_ != 123456789)
-      << "QuicSpdyStream use after free. " << destruction_indicator_
-      << QuicStackTrace();
-  return h2_deframer_.ProcessInput(static_cast<char*>(iov.iov_base),
-                                   iov.iov_len);
-}
-
-size_t QuicSpdySession::WriteHeadersOnHeadersStream(
-    QuicStreamId id, SpdyHeaderBlock headers, bool fin,
-    const spdy::SpdyStreamPrecedence& precedence,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
-
-  return WriteHeadersOnHeadersStreamImpl(
-      id, std::move(headers), fin,
-      /* parent_stream_id = */ 0,
-      Spdy3PriorityToHttp2Weight(precedence.spdy3_priority()),
-      /* exclusive = */ false, std::move(ack_listener));
-}
-
-size_t QuicSpdySession::WritePriority(QuicStreamId id,
-                                      QuicStreamId parent_stream_id, int weight,
-                                      bool exclusive) {
-  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
-  SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
-  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame));
-  headers_stream()->WriteOrBufferData(
-      absl::string_view(frame.data(), frame.size()), false, nullptr);
-  return frame.size();
-}
-
-void QuicSpdySession::WriteHttp3PriorityUpdate(
-    const PriorityUpdateFrame& priority_update) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  send_control_stream_->WritePriorityUpdate(priority_update);
-}
-
-void QuicSpdySession::OnHttp3GoAway(uint64_t id) {
-  QUIC_BUG_IF(quic_bug_12477_5, !version().UsesHttp3())
-      << "HTTP/3 GOAWAY received on version " << version();
-
-  if (last_received_http3_goaway_id_.has_value() &&
-      id > last_received_http3_goaway_id_.value()) {
-    CloseConnectionWithDetails(
-        QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
-        absl::StrCat("GOAWAY received with ID ", id,
-                     " greater than previously received ID ",
-                     last_received_http3_goaway_id_.value()));
-    return;
-  }
-  last_received_http3_goaway_id_ = id;
-
-  if (perspective() == Perspective::IS_SERVER) {
-    // TODO(b/151749109): Cancel server pushes with push ID larger than |id|.
-    return;
-  }
-
-  // QuicStreamId is uint32_t.  Casting to this narrower type is well-defined
-  // and preserves the lower 32 bits.  Both IsBidirectionalStreamId() and
-  // IsIncomingStream() give correct results, because their return value is
-  // determined by the least significant two bits.
-  QuicStreamId stream_id = static_cast<QuicStreamId>(id);
-  if (!QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
-      IsIncomingStream(stream_id)) {
-    CloseConnectionWithDetails(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
-                               "GOAWAY with invalid stream ID");
-    return;
-  }
-
-  // TODO(b/161252736): Cancel client requests with ID larger than |id|.
-  // If |id| is larger than numeric_limits<QuicStreamId>::max(), then use
-  // max() instead of downcast value.
-}
-
-bool QuicSpdySession::OnStreamsBlockedFrame(
-    const QuicStreamsBlockedFrame& frame) {
-  if (!QuicSession::OnStreamsBlockedFrame(frame)) {
-    return false;
-  }
-
-  // The peer asked for stream space more than this implementation has. Send
-  // goaway.
-  if (perspective() == Perspective::IS_SERVER &&
-      frame.stream_count >= QuicUtils::GetMaxStreamCount()) {
-    QUICHE_DCHECK_EQ(frame.stream_count, QuicUtils::GetMaxStreamCount());
-    SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "stream count too large");
-  }
-  return true;
-}
-
-void QuicSpdySession::SendHttp3GoAway(QuicErrorCode error_code,
-                                      const std::string& reason) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  if (!IsEncryptionEstablished()) {
-    QUIC_CODE_COUNT(quic_h3_goaway_before_encryption_established);
-    connection()->CloseConnection(
-        error_code, reason,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  QuicStreamId stream_id;
-
-  stream_id = QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
-      transport_version());
-  if (last_sent_http3_goaway_id_.has_value()) {
-    if (last_sent_http3_goaway_id_.value() == stream_id) {
-      // Do not send GOAWAY twice.
-      return;
-    }
-    if (last_sent_http3_goaway_id_.value() < stream_id) {
-      // A previous GOAWAY frame was sent with smaller stream ID.  This is not
-      // possible, because the only time a GOAWAY frame with non-maximal
-      // stream ID is sent is right before closing connection.
-      QUIC_BUG(quic_bug_10360_3)
-          << "Not sending GOAWAY frame with " << stream_id
-          << " because one with " << last_sent_http3_goaway_id_.value()
-          << " already sent on connection " << connection()->connection_id();
-      return;
-    }
-  }
-
-  send_control_stream_->SendGoAway(stream_id);
-  last_sent_http3_goaway_id_ = stream_id;
-}
-
-void QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id,
-                                       QuicStreamId promised_stream_id,
-                                       SpdyHeaderBlock headers) {
-  if (perspective() == Perspective::IS_CLIENT) {
-    QUIC_BUG(quic_bug_10360_4) << "Client shouldn't send PUSH_PROMISE";
-    return;
-  }
-
-  if (VersionUsesHttp3(transport_version())) {
-    QUIC_BUG(quic_bug_12477_6)
-        << "Support for server push over HTTP/3 has been removed.";
-    return;
-  }
-
-  SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id,
-                                 std::move(headers));
-  // PUSH_PROMISE must not be the last frame sent out, at least followed by
-  // response headers.
-  push_promise.set_fin(false);
-
-  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
-  headers_stream()->WriteOrBufferData(
-      absl::string_view(frame.data(), frame.size()), false, nullptr);
-}
-
-void QuicSpdySession::SendInitialData() {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  QuicConnection::ScopedPacketFlusher flusher(connection());
-  send_control_stream_->MaybeSendSettingsFrame();
-}
-
-QpackEncoder* QuicSpdySession::qpack_encoder() {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  return qpack_encoder_.get();
-}
-
-QpackDecoder* QuicSpdySession::qpack_decoder() {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  return qpack_decoder_.get();
-}
-
-void QuicSpdySession::OnStreamCreated(QuicSpdyStream* stream) {
-  auto it = buffered_stream_priorities_.find(stream->id());
-  if (it == buffered_stream_priorities_.end()) {
-    return;
-  }
-
-  stream->SetPriority(spdy::SpdyStreamPrecedence(it->second));
-  buffered_stream_priorities_.erase(it);
-}
-
-QuicSpdyStream* QuicSpdySession::GetOrCreateSpdyDataStream(
-    const QuicStreamId stream_id) {
-  QuicStream* stream = GetOrCreateStream(stream_id);
-  if (stream && stream->is_static()) {
-    QUIC_BUG(quic_bug_10360_5)
-        << "GetOrCreateSpdyDataStream returns static stream " << stream_id
-        << " in version " << transport_version() << "\n"
-        << QuicStackTrace();
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID,
-        absl::StrCat("stream ", stream_id, " is static"),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return nullptr;
-  }
-  return static_cast<QuicSpdyStream*>(stream);
-}
-
-void QuicSpdySession::OnNewEncryptionKeyAvailable(
-    EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
-  QuicSession::OnNewEncryptionKeyAvailable(level, std::move(encrypter));
-  if (IsEncryptionEstablished()) {
-    // Send H3 SETTINGs once encryption is established.
-    SendInitialData();
-  }
-}
-
-bool QuicSpdySession::ShouldNegotiateWebTransport() { return false; }
-
-bool QuicSpdySession::ShouldNegotiateDatagramContexts() { return false; }
-
-bool QuicSpdySession::ShouldValidateWebTransportVersion() const { return true; }
-
-bool QuicSpdySession::WillNegotiateWebTransport() {
-  return LocalHttpDatagramSupport() != HttpDatagramSupport::kNone &&
-         version().UsesHttp3() && ShouldNegotiateWebTransport();
-}
-
-// True if there are open HTTP requests.
-bool QuicSpdySession::ShouldKeepConnectionAlive() const {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()) ||
-                0u == pending_streams_size());
-  return GetNumActiveStreams() + pending_streams_size() > 0;
-}
-
-bool QuicSpdySession::UsesPendingStreamForFrame(QuicFrameType type,
-                                                QuicStreamId stream_id) const {
-  // Pending streams can only be used to handle unidirectional stream with
-  // STREAM & RESET_STREAM frames in IETF QUIC.
-  return VersionUsesHttp3(transport_version()) &&
-         (type == STREAM_FRAME || type == RST_STREAM_FRAME) &&
-         QuicUtils::GetStreamType(stream_id, perspective(),
-                                  IsIncomingStream(stream_id),
-                                  version()) == READ_UNIDIRECTIONAL;
-}
-
-size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl(
-    QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
-    QuicStreamId parent_stream_id, int weight, bool exclusive,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
-
-  const QuicByteCount uncompressed_size = headers.TotalBytesUsed();
-  SpdyHeadersIR headers_frame(id, std::move(headers));
-  headers_frame.set_fin(fin);
-  if (perspective() == Perspective::IS_CLIENT) {
-    headers_frame.set_has_priority(true);
-    headers_frame.set_parent_stream_id(parent_stream_id);
-    headers_frame.set_weight(weight);
-    headers_frame.set_exclusive(exclusive);
-  }
-  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
-  headers_stream()->WriteOrBufferData(
-      absl::string_view(frame.data(), frame.size()), false,
-      std::move(ack_listener));
-
-  // Calculate compressed header block size without framing overhead.
-  QuicByteCount compressed_size = frame.size();
-  compressed_size -= spdy::kFrameHeaderSize;
-  if (perspective() == Perspective::IS_CLIENT) {
-    // Exclusive bit and Stream Dependency are four bytes, weight is one more.
-    compressed_size -= 5;
-  }
-
-  LogHeaderCompressionRatioHistogram(
-      /* using_qpack = */ false,
-      /* is_sent = */ true, compressed_size, uncompressed_size);
-
-  return frame.size();
-}
-
-void QuicSpdySession::OnPromiseHeaderList(
-    QuicStreamId /*stream_id*/, QuicStreamId /*promised_stream_id*/,
-    size_t /*frame_len*/, const QuicHeaderList& /*header_list*/) {
-  std::string error =
-      "OnPromiseHeaderList should be overridden in client code.";
-  QUIC_BUG(quic_bug_10360_6) << error;
-  connection()->CloseConnection(QUIC_INTERNAL_ERROR, error,
-                                ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-bool QuicSpdySession::ResumeApplicationState(ApplicationState* cached_state) {
-  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_CLIENT);
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  SettingsFrame out;
-  if (!HttpDecoder::DecodeSettings(
-          reinterpret_cast<char*>(cached_state->data()), cached_state->size(),
-          &out)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnSettingsFrameResumed(out);
-  }
-  QUICHE_DCHECK(streams_waiting_for_settings_.empty());
-  for (const auto& setting : out.values) {
-    OnSetting(setting.first, setting.second);
-  }
-  return true;
-}
-
-absl::optional<std::string> QuicSpdySession::OnAlpsData(
-    const uint8_t* alps_data, size_t alps_length) {
-  AlpsFrameDecoder alps_frame_decoder(this);
-  HttpDecoder decoder(&alps_frame_decoder);
-  decoder.ProcessInput(reinterpret_cast<const char*>(alps_data), alps_length);
-  if (alps_frame_decoder.error_detail()) {
-    return alps_frame_decoder.error_detail();
-  }
-
-  if (decoder.error() != QUIC_NO_ERROR) {
-    return decoder.error_detail();
-  }
-
-  if (!decoder.AtFrameBoundary()) {
-    return "incomplete HTTP/3 frame";
-  }
-
-  return absl::nullopt;
-}
-
-void QuicSpdySession::OnAcceptChFrameReceivedViaAlps(
-    const AcceptChFrame& frame) {
-  if (debug_visitor_) {
-    debug_visitor_->OnAcceptChFrameReceivedViaAlps(frame);
-  }
-}
-
-bool QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnSettingsFrameReceived(frame);
-  }
-  for (const auto& setting : frame.values) {
-    if (!OnSetting(setting.first, setting.second)) {
-      return false;
-    }
-  }
-  for (QuicStreamId stream_id : streams_waiting_for_settings_) {
-    QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
-    QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
-    if (stream == nullptr) {
-      // The stream may no longer exist, since it is possible for a stream to
-      // get reset while waiting for the SETTINGS frame.
-      continue;
-    }
-    stream->OnDataAvailable();
-  }
-  streams_waiting_for_settings_.clear();
-  return true;
-}
-
-absl::optional<std::string> QuicSpdySession::OnSettingsFrameViaAlps(
-    const SettingsFrame& frame) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnSettingsFrameReceivedViaAlps(frame);
-  }
-  for (const auto& setting : frame.values) {
-    if (!OnSetting(setting.first, setting.second)) {
-      // Do not bother adding the setting identifier or value to the error
-      // message, because OnSetting() already closed the connection, therefore
-      // the error message will be ignored.
-      return "error parsing setting";
-    }
-  }
-  return absl::nullopt;
-}
-
-bool QuicSpdySession::VerifySettingIsZeroOrOne(uint64_t id, uint64_t value) {
-  if (value == 0 || value == 1) {
-    return true;
-  }
-  std::string error_details = absl::StrCat(
-      "Received ",
-      H3SettingsToString(static_cast<Http3AndQpackSettingsIdentifiers>(id)),
-      " with invalid value ", value);
-  QUIC_PEER_BUG(bad received setting) << ENDPOINT << error_details;
-  CloseConnectionWithDetails(QUIC_HTTP_INVALID_SETTING_VALUE, error_details);
-  return false;
-}
-
-bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
-  any_settings_received_ = true;
-
-  if (VersionUsesHttp3(transport_version())) {
-    // SETTINGS frame received on the control stream.
-    switch (id) {
-      case SETTINGS_QPACK_MAX_TABLE_CAPACITY: {
-        QUIC_DVLOG(1)
-            << ENDPOINT
-            << "SETTINGS_QPACK_MAX_TABLE_CAPACITY received with value "
-            << value;
-        // Communicate |value| to encoder, because it is used for encoding
-        // Required Insert Count.
-        if (!qpack_encoder_->SetMaximumDynamicTableCapacity(value)) {
-          CloseConnectionWithDetails(
-              was_zero_rtt_rejected()
-                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
-                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-              absl::StrCat(was_zero_rtt_rejected()
-                               ? "Server rejected 0-RTT, aborting because "
-                               : "",
-                           "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: ",
-                           value, " while current value is: ",
-                           qpack_encoder_->MaximumDynamicTableCapacity()));
-          return false;
-        }
-        // However, limit the dynamic table capacity to
-        // |qpack_maximum_dynamic_table_capacity_|.
-        qpack_encoder_->SetDynamicTableCapacity(
-            std::min(value, qpack_maximum_dynamic_table_capacity_));
-        break;
-      }
-      case SETTINGS_MAX_FIELD_SECTION_SIZE:
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_MAX_FIELD_SECTION_SIZE received with value "
-                      << value;
-        if (max_outbound_header_list_size_ !=
-                std::numeric_limits<size_t>::max() &&
-            max_outbound_header_list_size_ > value) {
-          CloseConnectionWithDetails(
-              was_zero_rtt_rejected()
-                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
-                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-              absl::StrCat(was_zero_rtt_rejected()
-                               ? "Server rejected 0-RTT, aborting because "
-                               : "",
-                           "Server sent an SETTINGS_MAX_FIELD_SECTION_SIZE: ",
-                           value, " which reduces current value: ",
-                           max_outbound_header_list_size_));
-          return false;
-        }
-        max_outbound_header_list_size_ = value;
-        break;
-      case SETTINGS_QPACK_BLOCKED_STREAMS: {
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_QPACK_BLOCKED_STREAMS received with value "
-                      << value;
-        if (!qpack_encoder_->SetMaximumBlockedStreams(value)) {
-          CloseConnectionWithDetails(
-              was_zero_rtt_rejected()
-                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
-                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-              absl::StrCat(was_zero_rtt_rejected()
-                               ? "Server rejected 0-RTT, aborting because "
-                               : "",
-                           "Server sent an SETTINGS_QPACK_BLOCKED_STREAMS: ",
-                           value, " which reduces current value: ",
-                           qpack_encoder_->maximum_blocked_streams()));
-          return false;
-        }
-        break;
-      }
-      case SETTINGS_ENABLE_CONNECT_PROTOCOL: {
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_ENABLE_CONNECT_PROTOCOL received with value "
-                      << value;
-        if (!VerifySettingIsZeroOrOne(id, value)) {
-          return false;
-        }
-        if (perspective() == Perspective::IS_CLIENT) {
-          allow_extended_connect_ = value != 0;
-        }
-        break;
-      }
-      case spdy::SETTINGS_ENABLE_PUSH:
-        ABSL_FALLTHROUGH_INTENDED;
-      case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
-        ABSL_FALLTHROUGH_INTENDED;
-      case spdy::SETTINGS_INITIAL_WINDOW_SIZE:
-        ABSL_FALLTHROUGH_INTENDED;
-      case spdy::SETTINGS_MAX_FRAME_SIZE:
-        CloseConnectionWithDetails(
-            QUIC_HTTP_RECEIVE_SPDY_SETTING,
-            absl::StrCat("received HTTP/2 specific setting in HTTP/3 session: ",
-                         id));
-        return false;
-      case SETTINGS_H3_DATAGRAM_DRAFT00: {
-        HttpDatagramSupport local_http_datagram_support =
-            LocalHttpDatagramSupport();
-        if (local_http_datagram_support != HttpDatagramSupport::kDraft00 &&
-            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
-          break;
-        }
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_H3_DATAGRAM_DRAFT00 received with value "
-                      << value;
-        if (!version().UsesHttp3()) {
-          break;
-        }
-        if (!VerifySettingIsZeroOrOne(id, value)) {
-          return false;
-        }
-        if (value && http_datagram_support_ != HttpDatagramSupport::kDraft04) {
-          // If both draft-00 and draft-04 are supported, use draft-04.
-          http_datagram_support_ = HttpDatagramSupport::kDraft00;
-        }
-        break;
-      }
-      case SETTINGS_H3_DATAGRAM_DRAFT04: {
-        HttpDatagramSupport local_http_datagram_support =
-            LocalHttpDatagramSupport();
-        if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
-            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
-          break;
-        }
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_H3_DATAGRAM_DRAFT04 received with value "
-                      << value;
-        if (!version().UsesHttp3()) {
-          break;
-        }
-        if (!VerifySettingIsZeroOrOne(id, value)) {
-          return false;
-        }
-        if (value) {
-          http_datagram_support_ = HttpDatagramSupport::kDraft04;
-        }
-        break;
-      }
-      case SETTINGS_WEBTRANS_DRAFT00:
-        if (!WillNegotiateWebTransport()) {
-          break;
-        }
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "SETTINGS_ENABLE_WEBTRANSPORT received with value "
-                      << value;
-        if (!VerifySettingIsZeroOrOne(id, value)) {
-          return false;
-        }
-        peer_supports_webtransport_ = (value == 1);
-        if (perspective() == Perspective::IS_CLIENT && value == 1) {
-          allow_extended_connect_ = true;
-        }
-        break;
-      default:
-        QUIC_DVLOG(1) << ENDPOINT << "Unknown setting identifier " << id
-                      << " received with value " << value;
-        // Ignore unknown settings.
-        break;
-    }
-    return true;
-  }
-
-  // SETTINGS frame received on the headers stream.
-  switch (id) {
-    case spdy::SETTINGS_HEADER_TABLE_SIZE:
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "SETTINGS_HEADER_TABLE_SIZE received with value "
-                    << value;
-      if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
-        QUIC_RELOADABLE_FLAG_COUNT(quic_limit_encoder_dynamic_table_size);
-        spdy_framer_.UpdateHeaderEncoderTableSize(
-            std::min<uint64_t>(value, kHpackEncoderDynamicTableSizeLimit));
-        break;
-      }
-      spdy_framer_.UpdateHeaderEncoderTableSize(value);
-      break;
-    case spdy::SETTINGS_ENABLE_PUSH:
-      if (perspective() == Perspective::IS_SERVER) {
-        // See rfc7540, Section 6.5.2.
-        if (value > 1) {
-          QUIC_DLOG(ERROR) << ENDPOINT << "Invalid value " << value
-                           << " received for SETTINGS_ENABLE_PUSH.";
-          if (IsConnected()) {
-            CloseConnectionWithDetails(
-                QUIC_INVALID_HEADERS_STREAM_DATA,
-                absl::StrCat("Invalid value for SETTINGS_ENABLE_PUSH: ",
-                             value));
-          }
-          return true;
-        }
-        QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_ENABLE_PUSH received with value "
-                      << value << ", ignoring.";
-        break;
-      } else {
-        QUIC_DLOG(ERROR)
-            << ENDPOINT
-            << "Invalid SETTINGS_ENABLE_PUSH received by client with value "
-            << value;
-        if (IsConnected()) {
-          CloseConnectionWithDetails(
-              QUIC_INVALID_HEADERS_STREAM_DATA,
-              absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
-        }
-      }
-      break;
-    case spdy::SETTINGS_MAX_HEADER_LIST_SIZE:
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "SETTINGS_MAX_HEADER_LIST_SIZE received with value "
-                    << value;
-      max_outbound_header_list_size_ = value;
-      break;
-    default:
-      QUIC_DLOG(ERROR) << ENDPOINT << "Unknown setting identifier " << id
-                       << " received with value " << value;
-      if (IsConnected()) {
-        CloseConnectionWithDetails(
-            QUIC_INVALID_HEADERS_STREAM_DATA,
-            absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
-      }
-  }
-  return true;
-}
-
-bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() {
-  return false;
-}
-
-void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, bool has_priority,
-                                const spdy::SpdyStreamPrecedence& precedence,
-                                bool fin) {
-  if (has_priority) {
-    if (perspective() == Perspective::IS_CLIENT) {
-      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                 "Server must not send priorities.");
-      return;
-    }
-    OnStreamHeadersPriority(stream_id, precedence);
-  } else {
-    if (perspective() == Perspective::IS_SERVER) {
-      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                 "Client must send priorities.");
-      return;
-    }
-  }
-  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
-                   stream_id_);
-  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
-                   promised_stream_id_);
-  stream_id_ = stream_id;
-  fin_ = fin;
-}
-
-void QuicSpdySession::OnPushPromise(SpdyStreamId stream_id,
-                                    SpdyStreamId promised_stream_id) {
-  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
-                   stream_id_);
-  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
-                   promised_stream_id_);
-  stream_id_ = stream_id;
-  promised_stream_id_ = promised_stream_id;
-}
-
-// TODO (wangyix): Why is SpdyStreamId used instead of QuicStreamId?
-// This occurs in many places in this file.
-void QuicSpdySession::OnPriority(SpdyStreamId stream_id,
-                                 const spdy::SpdyStreamPrecedence& precedence) {
-  if (perspective() == Perspective::IS_CLIENT) {
-    CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
-                               "Server must not send PRIORITY frames.");
-    return;
-  }
-  OnPriorityFrame(stream_id, precedence);
-}
-
-void QuicSpdySession::OnHeaderList(const QuicHeaderList& header_list) {
-  QUIC_DVLOG(1) << ENDPOINT << "Received header list for stream " << stream_id_
-                << ": " << header_list.DebugString();
-  // This code path is only executed for push promise in IETF QUIC.
-  if (VersionUsesHttp3(transport_version())) {
-    QUICHE_DCHECK(promised_stream_id_ !=
-                  QuicUtils::GetInvalidStreamId(transport_version()));
-  }
-  if (promised_stream_id_ ==
-      QuicUtils::GetInvalidStreamId(transport_version())) {
-    OnStreamHeaderList(stream_id_, fin_, frame_len_, header_list);
-  } else {
-    OnPromiseHeaderList(stream_id_, promised_stream_id_, frame_len_,
-                        header_list);
-  }
-  // Reset state for the next frame.
-  promised_stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
-  stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
-  fin_ = false;
-  frame_len_ = 0;
-}
-
-void QuicSpdySession::OnCompressedFrameSize(size_t frame_len) {
-  frame_len_ += frame_len;
-}
-
-void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error,
-                                                 const std::string& details) {
-  connection()->CloseConnection(
-      error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-bool QuicSpdySession::HasActiveRequestStreams() const {
-  return GetNumActiveStreams() + num_draining_streams() > 0;
-}
-
-QuicStream* QuicSpdySession::ProcessPendingStream(PendingStream* pending) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  QUICHE_DCHECK(connection()->connected());
-  struct iovec iov;
-  if (!pending->sequencer()->GetReadableRegion(&iov)) {
-    // The first byte hasn't been received yet.
-    return nullptr;
-  }
-
-  QuicDataReader reader(static_cast<char*>(iov.iov_base), iov.iov_len);
-  uint8_t stream_type_length = reader.PeekVarInt62Length();
-  uint64_t stream_type = 0;
-  if (!reader.ReadVarInt62(&stream_type)) {
-    if (pending->sequencer()->NumBytesBuffered() ==
-        pending->sequencer()->close_offset()) {
-      // Stream received FIN but there are not enough bytes for stream type.
-      // Mark all bytes consumed in order to close stream.
-      pending->MarkConsumed(pending->sequencer()->close_offset());
-    }
-    return nullptr;
-  }
-  pending->MarkConsumed(stream_type_length);
-
-  switch (stream_type) {
-    case kControlStream: {  // HTTP/3 control stream.
-      if (receive_control_stream_) {
-        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("Control");
-        return nullptr;
-      }
-      auto receive_stream =
-          std::make_unique<QuicReceiveControlStream>(pending, this);
-      receive_control_stream_ = receive_stream.get();
-      ActivateStream(std::move(receive_stream));
-      QUIC_DVLOG(1) << ENDPOINT << "Receive Control stream is created";
-      if (debug_visitor_ != nullptr) {
-        debug_visitor_->OnPeerControlStreamCreated(
-            receive_control_stream_->id());
-      }
-      return receive_control_stream_;
-    }
-    case kServerPushStream: {  // Push Stream.
-      CloseConnectionWithDetails(QUIC_HTTP_RECEIVE_SERVER_PUSH,
-                                 "Received server push stream");
-      return nullptr;
-    }
-    case kQpackEncoderStream: {  // QPACK encoder stream.
-      if (qpack_encoder_receive_stream_) {
-        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK encoder");
-        return nullptr;
-      }
-      auto encoder_receive = std::make_unique<QpackReceiveStream>(
-          pending, this, qpack_decoder_->encoder_stream_receiver());
-      qpack_encoder_receive_stream_ = encoder_receive.get();
-      ActivateStream(std::move(encoder_receive));
-      QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Encoder stream is created";
-      if (debug_visitor_ != nullptr) {
-        debug_visitor_->OnPeerQpackEncoderStreamCreated(
-            qpack_encoder_receive_stream_->id());
-      }
-      return qpack_encoder_receive_stream_;
-    }
-    case kQpackDecoderStream: {  // QPACK decoder stream.
-      if (qpack_decoder_receive_stream_) {
-        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK decoder");
-        return nullptr;
-      }
-      auto decoder_receive = std::make_unique<QpackReceiveStream>(
-          pending, this, qpack_encoder_->decoder_stream_receiver());
-      qpack_decoder_receive_stream_ = decoder_receive.get();
-      ActivateStream(std::move(decoder_receive));
-      QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Decoder stream is created";
-      if (debug_visitor_ != nullptr) {
-        debug_visitor_->OnPeerQpackDecoderStreamCreated(
-            qpack_decoder_receive_stream_->id());
-      }
-      return qpack_decoder_receive_stream_;
-    }
-    case kWebTransportUnidirectionalStream: {
-      // Note that this checks whether WebTransport is enabled on the receiver
-      // side, as we may receive WebTransport streams before peer's SETTINGS are
-      // received.
-      // TODO(b/184156476): consider whether this means we should drop buffered
-      // streams if we don't receive indication of WebTransport support.
-      if (!WillNegotiateWebTransport()) {
-        // Treat as unknown stream type.
-        break;
-      }
-      QUIC_DVLOG(1) << ENDPOINT << "Created an incoming WebTransport stream "
-                    << pending->id();
-      auto stream_owned =
-          std::make_unique<WebTransportHttp3UnidirectionalStream>(pending,
-                                                                  this);
-      WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
-      ActivateStream(std::move(stream_owned));
-      return stream;
-    }
-    default:
-      break;
-  }
-  MaybeSendStopSendingFrame(
-      pending->id(),
-      QuicResetStreamError::FromInternal(QUIC_STREAM_STREAM_CREATION_ERROR));
-  pending->StopReading();
-  return nullptr;
-}
-
-void QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams() {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  if (!send_control_stream_ && CanOpenNextOutgoingUnidirectionalStream()) {
-    auto send_control = std::make_unique<QuicSendControlStream>(
-        GetNextOutgoingUnidirectionalStreamId(), this, settings_);
-    send_control_stream_ = send_control.get();
-    ActivateStream(std::move(send_control));
-    if (debug_visitor_) {
-      debug_visitor_->OnControlStreamCreated(send_control_stream_->id());
-    }
-  }
-
-  if (!qpack_decoder_send_stream_ &&
-      CanOpenNextOutgoingUnidirectionalStream()) {
-    auto decoder_send = std::make_unique<QpackSendStream>(
-        GetNextOutgoingUnidirectionalStreamId(), this, kQpackDecoderStream);
-    qpack_decoder_send_stream_ = decoder_send.get();
-    ActivateStream(std::move(decoder_send));
-    qpack_decoder_->set_qpack_stream_sender_delegate(
-        qpack_decoder_send_stream_);
-    if (debug_visitor_) {
-      debug_visitor_->OnQpackDecoderStreamCreated(
-          qpack_decoder_send_stream_->id());
-    }
-  }
-
-  if (!qpack_encoder_send_stream_ &&
-      CanOpenNextOutgoingUnidirectionalStream()) {
-    auto encoder_send = std::make_unique<QpackSendStream>(
-        GetNextOutgoingUnidirectionalStreamId(), this, kQpackEncoderStream);
-    qpack_encoder_send_stream_ = encoder_send.get();
-    ActivateStream(std::move(encoder_send));
-    qpack_encoder_->set_qpack_stream_sender_delegate(
-        qpack_encoder_send_stream_);
-    if (debug_visitor_) {
-      debug_visitor_->OnQpackEncoderStreamCreated(
-          qpack_encoder_send_stream_->id());
-    }
-  }
-}
-
-void QuicSpdySession::BeforeConnectionCloseSent() {
-  if (!VersionUsesHttp3(transport_version()) || !IsEncryptionEstablished()) {
-    return;
-  }
-
-  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
-
-  QuicStreamId stream_id =
-      GetLargestPeerCreatedStreamId(/*unidirectional = */ false);
-
-  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
-    // No client-initiated bidirectional streams received yet.
-    // Send 0 to let client know that all requests can be retried.
-    stream_id = 0;
-  } else {
-    // Tell client that streams starting with the next after the largest
-    // received one can be retried.
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-  }
-  if (last_sent_http3_goaway_id_.has_value() &&
-      last_sent_http3_goaway_id_.value() <= stream_id) {
-    // A previous GOAWAY frame was sent with smaller stream ID.  This is not
-    // possible, because this is the only method sending a GOAWAY frame with
-    // non-maximal stream ID, and this must only be called once, right
-    // before closing connection.
-    QUIC_BUG(QuicGoawayFrameAlreadySent)
-        << "Not sending GOAWAY frame with " << stream_id << " because one with "
-        << last_sent_http3_goaway_id_.value() << " already sent on connection "
-        << connection()->connection_id();
-
-    // MUST not send GOAWAY with identifier larger than previously sent.
-    // Do not bother sending one with same identifier as before, since GOAWAY
-    // frames on the control stream are guaranteed to be processed in order.
-    return;
-  }
-
-  send_control_stream_->SendGoAway(stream_id);
-  last_sent_http3_goaway_id_ = stream_id;
-}
-
-void QuicSpdySession::OnCanCreateNewOutgoingStream(bool unidirectional) {
-  if (unidirectional && VersionUsesHttp3(transport_version())) {
-    MaybeInitializeHttp3UnidirectionalStreams();
-  }
-}
-
-bool QuicSpdySession::OnMaxPushIdFrame(PushId max_push_id) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective());
-
-  if (max_push_id_.has_value()) {
-    QUIC_DVLOG(1) << "Setting max_push_id to:  " << max_push_id
-                  << " from: " << max_push_id_.value();
-  } else {
-    QUIC_DVLOG(1) << "Setting max_push_id to:  " << max_push_id
-                  << " from unset";
-  }
-  absl::optional<PushId> old_max_push_id = max_push_id_;
-  max_push_id_ = max_push_id;
-
-  if (!old_max_push_id.has_value() || max_push_id > old_max_push_id.value()) {
-    OnCanCreateNewOutgoingStream(true);
-    return true;
-  }
-
-  // Equal value is not considered an error.
-  if (max_push_id < old_max_push_id.value()) {
-    CloseConnectionWithDetails(
-        QUIC_HTTP_INVALID_MAX_PUSH_ID,
-        absl::StrCat("MAX_PUSH_ID received with value ", max_push_id,
-                     " which is smaller that previously received value ",
-                     old_max_push_id.value()));
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicSpdySession::goaway_received() const {
-  return VersionUsesHttp3(transport_version())
-             ? last_received_http3_goaway_id_.has_value()
-             : transport_goaway_received();
-}
-
-bool QuicSpdySession::goaway_sent() const {
-  return VersionUsesHttp3(transport_version())
-             ? last_sent_http3_goaway_id_.has_value()
-             : transport_goaway_sent();
-}
-
-void QuicSpdySession::CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
-    absl::string_view type) {
-  QUIC_PEER_BUG(quic_peer_bug_10360_9) << absl::StrCat(
-      "Received a duplicate ", type, " stream: Closing connection.");
-  CloseConnectionWithDetails(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
-                             absl::StrCat(type, " stream is received twice."));
-}
-
-// static
-void QuicSpdySession::LogHeaderCompressionRatioHistogram(
-    bool using_qpack, bool is_sent, QuicByteCount compressed,
-    QuicByteCount uncompressed) {
-  if (compressed <= 0 || uncompressed <= 0) {
-    return;
-  }
-
-  int ratio = 100 * (compressed) / (uncompressed);
-  if (ratio < 1) {
-    ratio = 1;
-  } else if (ratio > 200) {
-    ratio = 200;
-  }
-
-  // Note that when using histogram macros in Chromium, the histogram name must
-  // be the same across calls for any given call site.
-  if (using_qpack) {
-    if (is_sent) {
-      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackSent",
-                            ratio, 1, 200, 200,
-                            "Header compression ratio as percentage for sent "
-                            "headers using QPACK.");
-    } else {
-      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackReceived",
-                            ratio, 1, 200, 200,
-                            "Header compression ratio as percentage for "
-                            "received headers using QPACK.");
-    }
-  } else {
-    if (is_sent) {
-      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackSent",
-                            ratio, 1, 200, 200,
-                            "Header compression ratio as percentage for sent "
-                            "headers using HPACK.");
-    } else {
-      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackReceived",
-                            ratio, 1, 200, 200,
-                            "Header compression ratio as percentage for "
-                            "received headers using HPACK.");
-    }
-  }
-}
-
-MessageStatus QuicSpdySession::SendHttp3Datagram(
-    QuicDatagramStreamId stream_id,
-    absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
-  if (!SupportsH3Datagram()) {
-    QUIC_BUG(send http datagram too early)
-        << "Refusing to send HTTP Datagram before SETTINGS received";
-    return MESSAGE_STATUS_INTERNAL_ERROR;
-  }
-  uint64_t stream_id_to_write = stream_id;
-  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
-    // Stream ID is sent divided by four as per the specification.
-    stream_id_to_write /= kHttpDatagramStreamIdDivisor;
-  }
-  size_t slice_length =
-      QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
-  if (context_id.has_value()) {
-    slice_length += QuicDataWriter::GetVarInt62Len(context_id.value());
-  }
-  quiche::QuicheBuffer buffer(
-      connection()->helper()->GetStreamSendBufferAllocator(), slice_length);
-  QuicDataWriter writer(slice_length, buffer.data());
-  if (!writer.WriteVarInt62(stream_id_to_write)) {
-    QUIC_BUG(h3 datagram stream ID write fail)
-        << "Failed to write HTTP/3 datagram stream ID";
-    return MESSAGE_STATUS_INTERNAL_ERROR;
-  }
-  if (context_id.has_value()) {
-    if (!writer.WriteVarInt62(context_id.value())) {
-      QUIC_BUG(h3 datagram context ID write fail)
-          << "Failed to write HTTP/3 datagram context ID";
-      return MESSAGE_STATUS_INTERNAL_ERROR;
-    }
-  }
-  if (!writer.WriteBytes(payload.data(), payload.length())) {
-    QUIC_BUG(h3 datagram payload write fail)
-        << "Failed to write HTTP/3 datagram payload";
-    return MESSAGE_STATUS_INTERNAL_ERROR;
-  }
-
-  quiche::QuicheMemSlice slice(std::move(buffer));
-  return datagram_queue()->SendOrQueueDatagram(std::move(slice));
-}
-
-void QuicSpdySession::SetMaxDatagramTimeInQueueForStreamId(
-    QuicStreamId /*stream_id*/, QuicTime::Delta max_time_in_queue) {
-  // TODO(b/184598230): implement this in a way that works for multiple sessions
-  // on a same connection.
-  datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
-}
-
-void QuicSpdySession::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
-                                                  QuicStreamId stream_id) {
-  h3_datagram_flow_id_to_stream_id_map_[flow_id] = stream_id;
-}
-
-void QuicSpdySession::UnregisterHttp3DatagramFlowId(
-    QuicDatagramStreamId flow_id) {
-  h3_datagram_flow_id_to_stream_id_map_.erase(flow_id);
-}
-
-void QuicSpdySession::OnMessageReceived(absl::string_view message) {
-  QuicSession::OnMessageReceived(message);
-  if (!SupportsH3Datagram()) {
-    QUIC_DLOG(INFO) << "Ignoring unexpected received HTTP/3 datagram";
-    return;
-  }
-  QuicDataReader reader(message);
-  uint64_t stream_id64;
-  if (!reader.ReadVarInt62(&stream_id64)) {
-    QUIC_DLOG(ERROR) << "Failed to parse stream ID in received HTTP/3 datagram";
-    return;
-  }
-  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
-    // Stream ID is sent divided by four as per the specification.
-    stream_id64 *= kHttpDatagramStreamIdDivisor;
-  }
-  if (perspective() == Perspective::IS_SERVER &&
-      http_datagram_support_ == HttpDatagramSupport::kDraft00) {
-    auto it = h3_datagram_flow_id_to_stream_id_map_.find(stream_id64);
-    if (it == h3_datagram_flow_id_to_stream_id_map_.end()) {
-      QUIC_DLOG(INFO) << "Received unknown HTTP/3 datagram flow ID "
-                      << stream_id64;
-      return;
-    }
-    stream_id64 = it->second;
-  }
-  if (stream_id64 > std::numeric_limits<QuicStreamId>::max()) {
-    // TODO(b/181256914) make this a connection close once we deprecate
-    // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-    QUIC_DLOG(ERROR) << "Received unexpectedly high HTTP/3 datagram stream ID "
-                     << stream_id64;
-    return;
-  }
-  QuicStreamId stream_id = static_cast<QuicStreamId>(stream_id64);
-  QuicSpdyStream* stream =
-      static_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
-  if (stream == nullptr) {
-    QUIC_DLOG(INFO) << "Received HTTP/3 datagram for unknown stream ID "
-                    << stream_id;
-    // TODO(b/181256914) buffer unknown HTTP/3 datagram flow IDs for a short
-    // period of time in case they were reordered.
-    return;
-  }
-  stream->OnDatagramReceived(&reader);
-}
-
-bool QuicSpdySession::SupportsWebTransport() {
-  return WillNegotiateWebTransport() && SupportsH3Datagram() &&
-         peer_supports_webtransport_ &&
-         (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
-          allow_extended_connect_);
-}
-
-bool QuicSpdySession::SupportsH3Datagram() const {
-  return http_datagram_support_ != HttpDatagramSupport::kNone;
-}
-
-WebTransportHttp3* QuicSpdySession::GetWebTransportSession(
-    WebTransportSessionId id) {
-  if (!SupportsWebTransport()) {
-    return nullptr;
-  }
-  if (!IsValidWebTransportSessionId(id, version())) {
-    return nullptr;
-  }
-  QuicSpdyStream* connect_stream = GetOrCreateSpdyDataStream(id);
-  if (connect_stream == nullptr) {
-    return nullptr;
-  }
-  return connect_stream->web_transport();
-}
-
-bool QuicSpdySession::ShouldProcessIncomingRequests() {
-  if (!ShouldBufferRequestsUntilSettings()) {
-    return true;
-  }
-
-  return any_settings_received_;
-}
-
-void QuicSpdySession::OnStreamWaitingForClientSettings(QuicStreamId id) {
-  QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
-  QUICHE_DCHECK(QuicUtils::IsBidirectionalStreamId(id, version()));
-  streams_waiting_for_settings_.insert(id);
-}
-
-void QuicSpdySession::AssociateIncomingWebTransportStreamWithSession(
-    WebTransportSessionId session_id, QuicStreamId stream_id) {
-  if (QuicUtils::IsOutgoingStreamId(version(), stream_id, perspective())) {
-    QUIC_BUG(AssociateIncomingWebTransportStreamWithSession got outgoing stream)
-        << ENDPOINT
-        << "AssociateIncomingWebTransportStreamWithSession() got an outgoing "
-           "stream ID: "
-        << stream_id;
-    return;
-  }
-  WebTransportHttp3* session = GetWebTransportSession(session_id);
-  if (session != nullptr) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Successfully associated incoming WebTransport stream "
-                  << stream_id << " with session ID " << session_id;
-
-    session->AssociateStream(stream_id);
-    return;
-  }
-  // Evict the oldest streams until we are under the limit.
-  while (buffered_streams_.size() >= kMaxUnassociatedWebTransportStreams) {
-    QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
-                  << buffered_streams_.front().stream_id
-                  << " from buffered streams as the queue is full.";
-    ResetStream(buffered_streams_.front().stream_id,
-                QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
-    buffered_streams_.pop_front();
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Received a WebTransport stream " << stream_id
-                << " for session ID " << session_id
-                << " but cannot associate it; buffering instead.";
-  buffered_streams_.push_back(
-      BufferedWebTransportStream{session_id, stream_id});
-}
-
-void QuicSpdySession::ProcessBufferedWebTransportStreamsForSession(
-    WebTransportHttp3* session) {
-  const WebTransportSessionId session_id = session->id();
-  QUIC_DVLOG(1) << "Processing buffered WebTransport streams for "
-                << session_id;
-  auto it = buffered_streams_.begin();
-  while (it != buffered_streams_.end()) {
-    if (it->session_id == session_id) {
-      QUIC_DVLOG(1) << "Unbuffered and associated WebTransport stream "
-                    << it->stream_id << " with session " << it->session_id;
-      session->AssociateStream(it->stream_id);
-      it = buffered_streams_.erase(it);
-    } else {
-      it++;
-    }
-  }
-}
-
-WebTransportHttp3UnidirectionalStream*
-QuicSpdySession::CreateOutgoingUnidirectionalWebTransportStream(
-    WebTransportHttp3* session) {
-  if (!CanOpenNextOutgoingUnidirectionalStream()) {
-    return nullptr;
-  }
-
-  QuicStreamId stream_id = GetNextOutgoingUnidirectionalStreamId();
-  auto stream_owned = std::make_unique<WebTransportHttp3UnidirectionalStream>(
-      stream_id, this, session->id());
-  WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
-  ActivateStream(std::move(stream_owned));
-  stream->WritePreamble();
-  session->AssociateStream(stream_id);
-  return stream;
-}
-
-QuicSpdyStream* QuicSpdySession::CreateOutgoingBidirectionalWebTransportStream(
-    WebTransportHttp3* session) {
-  QuicSpdyStream* stream = CreateOutgoingBidirectionalStream();
-  if (stream == nullptr) {
-    return nullptr;
-  }
-  QuicStreamId stream_id = stream->id();
-  stream->ConvertToWebTransportDataStream(session->id());
-  if (stream->web_transport_stream() == nullptr) {
-    // An error in ConvertToWebTransportDataStream() would result in
-    // CONNECTION_CLOSE, thus we don't need to do anything here.
-    return nullptr;
-  }
-  session->AssociateStream(stream_id);
-  return stream;
-}
-
-void QuicSpdySession::OnDatagramProcessed(
-    absl::optional<MessageStatus> /*status*/) {
-  // TODO(b/184598230): make this work with multiple datagram flows.
-}
-
-void QuicSpdySession::DatagramObserver::OnDatagramProcessed(
-    absl::optional<MessageStatus> status) {
-  session_->OnDatagramProcessed(status);
-}
-
-HttpDatagramSupport QuicSpdySession::LocalHttpDatagramSupport() {
-  return HttpDatagramSupport::kNone;
-}
-
-std::string HttpDatagramSupportToString(
-    HttpDatagramSupport http_datagram_support) {
-  switch (http_datagram_support) {
-    case HttpDatagramSupport::kNone:
-      return "None";
-    case HttpDatagramSupport::kDraft00:
-      return "Draft00";
-    case HttpDatagramSupport::kDraft04:
-      return "Draft04";
-    case HttpDatagramSupport::kDraft00And04:
-      return "Draft00And04";
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(http_datagram_support), ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const HttpDatagramSupport& http_datagram_support) {
-  os << HttpDatagramSupportToString(http_datagram_support);
-  return os;
-}
-
-// Must not be called after Initialize().
-void QuicSpdySession::set_allow_extended_connect(bool allow_extended_connect) {
-  QUIC_BUG_IF(extended connect wrong version,
-              !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
-                  !VersionUsesHttp3(transport_version()))
-      << "Try to enable/disable extended CONNECT in Google QUIC";
-  QUIC_BUG_IF(extended connect on client,
-              !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
-                  perspective() == Perspective::IS_CLIENT)
-      << "Enabling/disabling extended CONNECT on the client side has no effect";
-  if (ShouldNegotiateWebTransport()) {
-    QUIC_BUG_IF(disable extended connect, !allow_extended_connect)
-        << "Disabling extended CONNECT with web transport enabled has no "
-           "effect.";
-    return;
-  }
-  allow_extended_connect_ = allow_extended_connect;
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h
deleted file mode 100644
index 50264a1..0000000
--- a/quic/core/http/quic_spdy_session.h
+++ /dev/null
@@ -1,706 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <memory>
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/quic_headers_stream.h"
-#include "quic/core/http/quic_receive_control_stream.h"
-#include "quic/core/http/quic_send_control_stream.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-#include "quic/core/qpack/qpack_receive_stream.h"
-#include "quic/core/qpack/qpack_send_stream.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-
-namespace quic {
-
-namespace test {
-class QuicSpdySessionPeer;
-}  // namespace test
-
-class WebTransportHttp3UnidirectionalStream;
-
-QUIC_EXPORT_PRIVATE extern const size_t kMaxUnassociatedWebTransportStreams;
-
-class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
- public:
-  Http3DebugVisitor();
-  Http3DebugVisitor(const Http3DebugVisitor&) = delete;
-  Http3DebugVisitor& operator=(const Http3DebugVisitor&) = delete;
-
-  virtual ~Http3DebugVisitor();
-
-  // TODO(https://crbug.com/1062700): Remove default implementation of all
-  // methods after Chrome's QuicHttp3Logger has overrides.  This is to make sure
-  // QUICHE merge is not blocked on having to add those overrides, they can
-  // happen asynchronously.
-
-  // Creation of unidirectional streams.
-
-  // Called when locally-initiated control stream is created.
-  virtual void OnControlStreamCreated(QuicStreamId /*stream_id*/) {}
-  // Called when locally-initiated QPACK encoder stream is created.
-  virtual void OnQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) {}
-  // Called when locally-initiated QPACK decoder stream is created.
-  virtual void OnQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) {}
-  // Called when peer's control stream type is received.
-  virtual void OnPeerControlStreamCreated(QuicStreamId /*stream_id*/) = 0;
-  // Called when peer's QPACK encoder stream type is received.
-  virtual void OnPeerQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
-  // Called when peer's QPACK decoder stream type is received.
-  virtual void OnPeerQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
-
-  // Incoming HTTP/3 frames in ALPS TLS extension.
-  virtual void OnSettingsFrameReceivedViaAlps(const SettingsFrame& /*frame*/) {}
-  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/) {}
-
-  // Incoming HTTP/3 frames on the control stream.
-  virtual void OnSettingsFrameReceived(const SettingsFrame& /*frame*/) = 0;
-  virtual void OnGoAwayFrameReceived(const GoAwayFrame& /*frame*/) {}
-  // TODO(b/171463363): Remove.
-  virtual void OnMaxPushIdFrameReceived(const MaxPushIdFrame& /*frame*/) {}
-  virtual void OnPriorityUpdateFrameReceived(
-      const PriorityUpdateFrame& /*frame*/) {}
-  virtual void OnAcceptChFrameReceived(const AcceptChFrame& /*frame*/) {}
-
-  // Incoming HTTP/3 frames on request or push streams.
-  virtual void OnDataFrameReceived(QuicStreamId /*stream_id*/,
-                                   QuicByteCount /*payload_length*/) {}
-  virtual void OnHeadersFrameReceived(
-      QuicStreamId /*stream_id*/, QuicByteCount /*compressed_headers_length*/) {
-  }
-  virtual void OnHeadersDecoded(QuicStreamId /*stream_id*/,
-                                QuicHeaderList /*headers*/) {}
-
-  // Incoming HTTP/3 frames of unknown type on any stream.
-  virtual void OnUnknownFrameReceived(QuicStreamId /*stream_id*/,
-                                      uint64_t /*frame_type*/,
-                                      QuicByteCount /*payload_length*/) {}
-
-  // Outgoing HTTP/3 frames on the control stream.
-  virtual void OnSettingsFrameSent(const SettingsFrame& /*frame*/) = 0;
-  virtual void OnGoAwayFrameSent(QuicStreamId /*stream_id*/) {}
-  virtual void OnPriorityUpdateFrameSent(const PriorityUpdateFrame& /*frame*/) {
-  }
-
-  // Outgoing HTTP/3 frames on request or push streams.
-  virtual void OnDataFrameSent(QuicStreamId /*stream_id*/,
-                               QuicByteCount /*payload_length*/) {}
-  virtual void OnHeadersFrameSent(
-      QuicStreamId /*stream_id*/,
-      const spdy::SpdyHeaderBlock& /*header_block*/) {}
-
-  // 0-RTT related events.
-  virtual void OnSettingsFrameResumed(const SettingsFrame& /*frame*/) {}
-};
-
-// Whether draft-ietf-masque-h3-datagram is supported on this session and if so
-// which draft is currently in use.
-enum class HttpDatagramSupport : uint8_t {
-  kNone = 0,  // HTTP Datagrams are not supported for this session.
-  kDraft00 = 1,
-  kDraft04 = 2,
-  kDraft00And04 = 3,  // only used locally, we only negotiate one draft.
-};
-
-QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
-    HttpDatagramSupport http_datagram_support);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const HttpDatagramSupport& http_datagram_support);
-
-// A QUIC session for HTTP.
-class QUIC_EXPORT_PRIVATE QuicSpdySession
-    : public QuicSession,
-      public QpackEncoder::DecoderStreamErrorDelegate,
-      public QpackDecoder::EncoderStreamErrorDelegate {
- public:
-  // Does not take ownership of |connection| or |visitor|.
-  QuicSpdySession(QuicConnection* connection, QuicSession::Visitor* visitor,
-                  const QuicConfig& config,
-                  const ParsedQuicVersionVector& supported_versions);
-  QuicSpdySession(const QuicSpdySession&) = delete;
-  QuicSpdySession& operator=(const QuicSpdySession&) = delete;
-
-  ~QuicSpdySession() override;
-
-  void Initialize() override;
-
-  // QpackEncoder::DecoderStreamErrorDelegate implementation.
-  void OnDecoderStreamError(QuicErrorCode error_code,
-                            absl::string_view error_message) override;
-
-  // QpackDecoder::EncoderStreamErrorDelegate implementation.
-  void OnEncoderStreamError(QuicErrorCode error_code,
-                            absl::string_view error_message) override;
-
-  // Called by |headers_stream_| when headers with a priority have been
-  // received for a stream.  This method will only be called for server streams.
-  virtual void OnStreamHeadersPriority(
-      QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence);
-
-  // Called by |headers_stream_| when headers have been completely received
-  // for a stream.  |fin| will be true if the fin flag was set in the headers
-  // frame.
-  virtual void OnStreamHeaderList(QuicStreamId stream_id, bool fin,
-                                  size_t frame_len,
-                                  const QuicHeaderList& header_list);
-
-  // Called by |headers_stream_| when push promise headers have been
-  // completely received.  |fin| will be true if the fin flag was set
-  // in the headers.
-  virtual void OnPromiseHeaderList(QuicStreamId stream_id,
-                                   QuicStreamId promised_stream_id,
-                                   size_t frame_len,
-                                   const QuicHeaderList& header_list);
-
-  // Called by |headers_stream_| when a PRIORITY frame has been received for a
-  // stream. This method will only be called for server streams.
-  virtual void OnPriorityFrame(QuicStreamId stream_id,
-                               const spdy::SpdyStreamPrecedence& precedence);
-
-  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a request
-  // stream.  Returns false and closes connection if |stream_id| is invalid.
-  bool OnPriorityUpdateForRequestStream(QuicStreamId stream_id, int urgency);
-
-  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a push
-  // stream.  Returns false and closes connection if |push_id| is invalid.
-  bool OnPriorityUpdateForPushStream(QuicStreamId push_id, int urgency);
-
-  // Called when an HTTP/3 ACCEPT_CH frame has been received.
-  // This method will only be called for client sessions.
-  virtual void OnAcceptChFrame(const AcceptChFrame& /*frame*/) {}
-
-  // Sends contents of |iov| to h2_deframer_, returns number of bytes processed.
-  size_t ProcessHeaderData(const struct iovec& iov);
-
-  // Writes |headers| for the stream |id| to the dedicated headers stream.
-  // If |fin| is true, then no more data will be sent for the stream |id|.
-  // If provided, |ack_notifier_delegate| will be registered to be notified when
-  // we have seen ACKs for all packets resulting from this call.
-  virtual size_t WriteHeadersOnHeadersStream(
-      QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
-      const spdy::SpdyStreamPrecedence& precedence,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  // Writes an HTTP/2 PRIORITY frame the to peer. Returns the size in bytes of
-  // the resulting PRIORITY frame.
-  size_t WritePriority(QuicStreamId id, QuicStreamId parent_stream_id,
-                       int weight, bool exclusive);
-
-  // Writes an HTTP/3 PRIORITY_UPDATE frame to the peer.
-  void WriteHttp3PriorityUpdate(const PriorityUpdateFrame& priority_update);
-
-  // Process received HTTP/3 GOAWAY frame.  When sent from server to client,
-  // |id| is a stream ID.  When sent from client to server, |id| is a push ID.
-  virtual void OnHttp3GoAway(uint64_t id);
-
-  // Send GOAWAY if the peer is blocked on the implementation max.
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
-
-  // Write GOAWAY frame with maximum stream ID on the control stream.  Called to
-  // initite graceful connection shutdown.  Do not use smaller stream ID, in
-  // case client does not implement retry on GOAWAY.  Do not send GOAWAY if one
-  // has already been sent. Send connection close with |error_code| and |reason|
-  // before encryption gets established.
-  void SendHttp3GoAway(QuicErrorCode error_code, const std::string& reason);
-
-  // Write |headers| for |promised_stream_id| on |original_stream_id| in a
-  // PUSH_PROMISE frame to peer.
-  virtual void WritePushPromise(QuicStreamId original_stream_id,
-                                QuicStreamId promised_stream_id,
-                                spdy::SpdyHeaderBlock headers);
-
-  QpackEncoder* qpack_encoder();
-  QpackDecoder* qpack_decoder();
-  QuicHeadersStream* headers_stream() { return headers_stream_; }
-
-  const QuicHeadersStream* headers_stream() const { return headers_stream_; }
-
-  // Called when the control stream receives HTTP/3 SETTINGS.
-  // Returns false in case of 0-RTT if received settings are incompatible with
-  // cached values, true otherwise.
-  virtual bool OnSettingsFrame(const SettingsFrame& frame);
-
-  // Called when an HTTP/3 SETTINGS frame is received via ALPS.
-  // Returns an error message if an error has occurred, or nullopt otherwise.
-  // May or may not close the connection on error.
-  absl::optional<std::string> OnSettingsFrameViaAlps(
-      const SettingsFrame& frame);
-
-  // Called when a setting is parsed from a SETTINGS frame received on the
-  // control stream or from cached application state.
-  // Returns true on success.
-  // Returns false if received setting is incompatible with cached value (in
-  // case of 0-RTT) or with previously received value (in case of ALPS).
-  // Also closes the connection on error.
-  bool OnSetting(uint64_t id, uint64_t value);
-
-  // Return true if this session wants to release headers stream's buffer
-  // aggressively.
-  virtual bool ShouldReleaseHeadersStreamSequencerBuffer();
-
-  void CloseConnectionWithDetails(QuicErrorCode error,
-                                  const std::string& details);
-
-  // Must not be called after Initialize().
-  // TODO(bnc): Move to constructor argument.
-  void set_qpack_maximum_dynamic_table_capacity(
-      uint64_t qpack_maximum_dynamic_table_capacity) {
-    qpack_maximum_dynamic_table_capacity_ =
-        qpack_maximum_dynamic_table_capacity;
-  }
-
-  // Must not be called after Initialize().
-  // TODO(bnc): Move to constructor argument.
-  void set_qpack_maximum_blocked_streams(
-      uint64_t qpack_maximum_blocked_streams) {
-    qpack_maximum_blocked_streams_ = qpack_maximum_blocked_streams;
-  }
-
-  // Should only be used by IETF QUIC server side.
-  // Must not be called after Initialize().
-  // TODO(bnc): Move to constructor argument.
-  void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) {
-    max_inbound_header_list_size_ = max_inbound_header_list_size;
-  }
-
-  // Must not be called after Initialize().
-  void set_allow_extended_connect(bool allow_extended_connect);
-
-  size_t max_outbound_header_list_size() const {
-    return max_outbound_header_list_size_;
-  }
-
-  size_t max_inbound_header_list_size() const {
-    return max_inbound_header_list_size_;
-  }
-
-  bool allow_extended_connect() const { return allow_extended_connect_; }
-
-  // Returns true if the session has active request streams.
-  bool HasActiveRequestStreams() const;
-
-  // Called when the size of the compressed frame payload is available.
-  void OnCompressedFrameSize(size_t frame_len);
-
-  // Called when a PUSH_PROMISE frame has been received.
-  // TODO(b/171463363): Remove.
-  void OnPushPromise(spdy::SpdyStreamId stream_id,
-                     spdy::SpdyStreamId promised_stream_id);
-
-  // Called when the complete list of headers is available.
-  void OnHeaderList(const QuicHeaderList& header_list);
-
-  QuicStreamId promised_stream_id() const { return promised_stream_id_; }
-
-  // Initialze HTTP/3 unidirectional streams if |unidirectional| is true and
-  // those streams are not initialized yet.
-  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
-
-  // Sets |max_push_id_|.
-  // This method must only be called if protocol is IETF QUIC and perspective is
-  // server.  It must only be called if a MAX_PUSH_ID frame is received.
-  // Returns whether |max_push_id| is greater than or equal to current
-  // |max_push_id_|.
-  // TODO(b/171463363): Remove.
-  bool OnMaxPushIdFrame(PushId max_push_id);
-
-  int32_t destruction_indicator() const { return destruction_indicator_; }
-
-  void set_debug_visitor(Http3DebugVisitor* debug_visitor) {
-    debug_visitor_ = debug_visitor;
-  }
-
-  Http3DebugVisitor* debug_visitor() { return debug_visitor_; }
-
-  // When using Google QUIC, return whether a transport layer GOAWAY frame has
-  // been received or sent.
-  // When using IETF QUIC, return whether an HTTP/3 GOAWAY frame has been
-  // received or sent.
-  bool goaway_received() const;
-  bool goaway_sent() const;
-
-  // Log header compression ratio histogram.
-  // |using_qpack| is true for QPACK, false for HPACK.
-  // |is_sent| is true for sent headers, false for received ones.
-  // Ratio is recorded as percentage.  Smaller value means more efficient
-  // compression.  Compressed size might be larger than uncompressed size, but
-  // recorded ratio is trunckated at 200%.
-  // Uncompressed size can be zero for an empty header list, and compressed size
-  // can be zero for an empty header list when using HPACK.  (QPACK always emits
-  // a header block prefix of at least two bytes.)  This method records nothing
-  // if either |compressed| or |uncompressed| is not positive.
-  // In order for measurements for different protocol to be comparable, the
-  // caller must ensure that uncompressed size is the total length of header
-  // names and values without any overhead.
-  static void LogHeaderCompressionRatioHistogram(bool using_qpack, bool is_sent,
-                                                 QuicByteCount compressed,
-                                                 QuicByteCount uncompressed);
-
-  // True if any dynamic table entries have been referenced from either a sent
-  // or received header block.  Used for stats.
-  bool dynamic_table_entry_referenced() const {
-    return (qpack_encoder_ &&
-            qpack_encoder_->dynamic_table_entry_referenced()) ||
-           (qpack_decoder_ && qpack_decoder_->dynamic_table_entry_referenced());
-  }
-
-  void OnStreamCreated(QuicSpdyStream* stream);
-
-  // Decode SETTINGS from |cached_state| and apply it to the session.
-  bool ResumeApplicationState(ApplicationState* cached_state) override;
-
-  absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
-                                         size_t alps_length) override;
-
-  // Called when ACCEPT_CH frame is parsed out of data received in TLS ALPS
-  // extension.
-  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/);
-
-  // Whether HTTP datagrams are supported on this session and which draft is in
-  // use, based on received SETTINGS.
-  HttpDatagramSupport http_datagram_support() const {
-    return http_datagram_support_;
-  }
-
-  // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
-  MessageStatus SendHttp3Datagram(
-      QuicDatagramStreamId stream_id,
-      absl::optional<QuicDatagramContextId> context_id,
-      absl::string_view payload);
-  // This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
-  void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
-                                            QuicTime::Delta max_time_in_queue);
-  // This must not be used except by
-  // QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders.
-  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
-                                   QuicStreamId stream_id);
-  // This must not be used except by QuicSpdyStream::OnClose.
-  void UnregisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
-
-  // Override from QuicSession to support HTTP/3 datagrams.
-  void OnMessageReceived(absl::string_view message) override;
-
-  // Indicates whether the HTTP/3 session supports WebTransport.
-  bool SupportsWebTransport();
-
-  // Indicates whether both the peer and us support HTTP/3 Datagrams.
-  bool SupportsH3Datagram() const;
-
-  // Indicates whether the HTTP/3 session will indicate WebTransport support to
-  // the peer.
-  bool WillNegotiateWebTransport();
-
-  // Returns a WebTransport session by its session ID.  Returns nullptr if no
-  // session is associated with the given ID.
-  WebTransportHttp3* GetWebTransportSession(WebTransportSessionId id);
-
-  // If true, no data on bidirectional streams will be processed by the server
-  // until the SETTINGS are received.  Only works for HTTP/3.
-  bool ShouldBufferRequestsUntilSettings() {
-    return version().UsesHttp3() && perspective() == Perspective::IS_SERVER &&
-           LocalHttpDatagramSupport() != HttpDatagramSupport::kNone;
-  }
-
-  // Returns if the incoming bidirectional streams should process data.  This is
-  // usually true, but in certain cases we would want to wait until the settings
-  // are received.
-  bool ShouldProcessIncomingRequests();
-
-  void OnStreamWaitingForClientSettings(QuicStreamId id);
-
-  // Links the specified stream with a WebTransport session.  If the session is
-  // not present, it is buffered until a corresponding stream is found.
-  void AssociateIncomingWebTransportStreamWithSession(
-      WebTransportSessionId session_id, QuicStreamId stream_id);
-
-  void ProcessBufferedWebTransportStreamsForSession(WebTransportHttp3* session);
-
-  bool CanOpenOutgoingUnidirectionalWebTransportStream(
-      WebTransportSessionId /*id*/) {
-    return CanOpenNextOutgoingUnidirectionalStream();
-  }
-  bool CanOpenOutgoingBidirectionalWebTransportStream(
-      WebTransportSessionId /*id*/) {
-    return CanOpenNextOutgoingBidirectionalStream();
-  }
-
-  // Creates an outgoing unidirectional WebTransport stream.  Returns nullptr if
-  // the stream cannot be created due to flow control or some other reason.
-  WebTransportHttp3UnidirectionalStream*
-  CreateOutgoingUnidirectionalWebTransportStream(WebTransportHttp3* session);
-
-  // Creates an outgoing bidirectional WebTransport stream.  Returns nullptr if
-  // the stream cannot be created due to flow control or some other reason.
-  QuicSpdyStream* CreateOutgoingBidirectionalWebTransportStream(
-      WebTransportHttp3* session);
-
-  QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id);
-
-  // Indicates whether we will try to negotiate datagram contexts on newly
-  // created WebTransport sessions over HTTP/3.
-  virtual bool ShouldNegotiateDatagramContexts();
-
-  // Indicates whether the client should check that the
-  // `Sec-Webtransport-Http3-Draft` header is valid.
-  // TODO(vasilvv): remove this once this is enabled in Chromium.
-  virtual bool ShouldValidateWebTransportVersion() const;
-
- protected:
-  // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
-  // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to
-  // make sure that all data streams are QuicSpdyStreams.
-  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0;
-  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override = 0;
-  virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0;
-  virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0;
-
-  // If an incoming stream can be created, return true.
-  virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0;
-
-  // If an outgoing bidirectional/unidirectional stream can be created, return
-  // true.
-  virtual bool ShouldCreateOutgoingBidirectionalStream() = 0;
-  virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0;
-
-  // Indicates whether the underlying backend can accept and process
-  // WebTransport sessions over HTTP/3.
-  virtual bool ShouldNegotiateWebTransport();
-
-  // Returns true if there are open HTTP requests.
-  bool ShouldKeepConnectionAlive() const override;
-
-  // Overridden to buffer incoming unidirectional streams for version 99.
-  bool UsesPendingStreamForFrame(QuicFrameType type,
-                                 QuicStreamId stream_id) const override;
-
-  // Processes incoming unidirectional streams; parses the stream type, and
-  // creates a new stream of the corresponding type.  Returns the pointer to the
-  // newly created stream, or nullptr if the stream type is not yet available.
-  QuicStream* ProcessPendingStream(PendingStream* pending) override;
-
-  size_t WriteHeadersOnHeadersStreamImpl(
-      QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
-      QuicStreamId parent_stream_id, int weight, bool exclusive,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  void OnNewEncryptionKeyAvailable(
-      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
-
-  // Sets the maximum size of the header compression table spdy_framer_ is
-  // willing to use to encode header blocks.
-  void UpdateHeaderEncoderTableSize(uint32_t value);
-
-  bool IsConnected() { return connection()->connected(); }
-
-  const QuicReceiveControlStream* receive_control_stream() const {
-    return receive_control_stream_;
-  }
-
-  const SettingsFrame& settings() const { return settings_; }
-
-  // Initializes HTTP/3 unidirectional streams if not yet initialzed.
-  virtual void MaybeInitializeHttp3UnidirectionalStreams();
-
-  // QuicConnectionVisitorInterface method.
-  void BeforeConnectionCloseSent() override;
-
-  // Called whenever a datagram is dequeued or dropped from datagram_queue().
-  virtual void OnDatagramProcessed(absl::optional<MessageStatus> status);
-
-  // Returns which version of the HTTP/3 datagram extension we should advertise
-  // in settings and accept remote settings for.
-  virtual HttpDatagramSupport LocalHttpDatagramSupport();
-
- private:
-  friend class test::QuicSpdySessionPeer;
-
-  class SpdyFramerVisitor;
-
-  // Proxies OnDatagramProcessed() calls to the session.
-  class QUIC_EXPORT_PRIVATE DatagramObserver
-      : public QuicDatagramQueue::Observer {
-   public:
-    explicit DatagramObserver(QuicSpdySession* session) : session_(session) {}
-    void OnDatagramProcessed(absl::optional<MessageStatus> status) override;
-
-   private:
-    QuicSpdySession* session_;  // not owned
-  };
-
-  struct QUIC_EXPORT_PRIVATE BufferedWebTransportStream {
-    WebTransportSessionId session_id;
-    QuicStreamId stream_id;
-  };
-
-  // The following methods are called by the SimpleVisitor.
-
-  // Called when a HEADERS frame has been received.
-  void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
-                 const spdy::SpdyStreamPrecedence& precedence, bool fin);
-
-  // Called when a PRIORITY frame has been received.
-  void OnPriority(spdy::SpdyStreamId stream_id,
-                  const spdy::SpdyStreamPrecedence& precedence);
-
-  void CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
-      absl::string_view type);
-
-  // Sends any data which should be sent at the start of a connection, including
-  // the initial SETTINGS frame, and (when IETF QUIC is used) also a MAX_PUSH_ID
-  // frame if SetMaxPushId() had been called before encryption was established.
-  // When using 0-RTT, this method is called twice: once when encryption is
-  // established, and again when 1-RTT keys are available.
-  void SendInitialData();
-
-  void FillSettingsFrame();
-
-  bool VerifySettingIsZeroOrOne(uint64_t id, uint64_t value);
-
-  std::unique_ptr<QpackEncoder> qpack_encoder_;
-  std::unique_ptr<QpackDecoder> qpack_decoder_;
-
-  // Pointer to the header stream in stream_map_.
-  QuicHeadersStream* headers_stream_;
-
-  // HTTP/3 control streams. They are owned by QuicSession inside
-  // stream map, and can be accessed by those unowned pointers below.
-  QuicSendControlStream* send_control_stream_;
-  QuicReceiveControlStream* receive_control_stream_;
-
-  // Pointers to HTTP/3 QPACK streams in stream map.
-  QpackReceiveStream* qpack_encoder_receive_stream_;
-  QpackReceiveStream* qpack_decoder_receive_stream_;
-  QpackSendStream* qpack_encoder_send_stream_;
-  QpackSendStream* qpack_decoder_send_stream_;
-
-  SettingsFrame settings_;
-
-  // Maximum dynamic table capacity as defined at
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity
-  // for the decoding context.  Value will be sent via
-  // SETTINGS_QPACK_MAX_TABLE_CAPACITY.
-  // |qpack_maximum_dynamic_table_capacity_| also serves as an upper bound for
-  // the dynamic table capacity of the encoding context, to limit memory usage
-  // if a larger SETTINGS_QPACK_MAX_TABLE_CAPACITY value is received.
-  uint64_t qpack_maximum_dynamic_table_capacity_;
-
-  // Maximum number of blocked streams as defined at
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams
-  // for the decoding context.  Value will be sent via
-  // SETTINGS_QPACK_BLOCKED_STREAMS.
-  uint64_t qpack_maximum_blocked_streams_;
-
-  // The maximum size of a header block that will be accepted from the peer,
-  // defined per spec as key + value + overhead per field (uncompressed).
-  // Value will be sent via SETTINGS_MAX_HEADER_LIST_SIZE.
-  size_t max_inbound_header_list_size_;
-
-  // The maximum size of a header block that can be sent to the peer. This field
-  // is informed and set by the peer via SETTINGS frame.
-  // TODO(b/148616439): Honor this field when sending headers.
-  size_t max_outbound_header_list_size_;
-
-  // Data about the stream whose headers are being processed.
-  QuicStreamId stream_id_;
-  QuicStreamId promised_stream_id_;
-  size_t frame_len_;
-  bool fin_;
-
-  spdy::SpdyFramer spdy_framer_;
-  http2::Http2DecoderAdapter h2_deframer_;
-  std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
-
-  // Used in IETF QUIC only.
-  // For a server:
-  //   the push ID in the most recently received MAX_PUSH_ID frame,
-  //   or unset if no MAX_PUSH_ID frame has been received.
-  // For a client:
-  //   unset until SetMaxPushId() is called;
-  //   before encryption is established, the push ID to be sent in the initial
-  //   MAX_PUSH_ID frame;
-  //   after encryption is established, the push ID in the most recently sent
-  //   MAX_PUSH_ID frame.
-  // Once set, never goes back to unset.
-  // TODO(b/171463363): Remove.
-  absl::optional<PushId> max_push_id_;
-
-  // Not owned by the session.
-  Http3DebugVisitor* debug_visitor_;
-
-  // Priority values received in PRIORITY_UPDATE frames for streams that are not
-  // open yet.
-  absl::flat_hash_map<QuicStreamId, int> buffered_stream_priorities_;
-
-  // An integer used for live check. The indicator is assigned a value in
-  // constructor. As long as it is not the assigned value, that would indicate
-  // an use-after-free.
-  int32_t destruction_indicator_;
-
-  // The identifier in the most recently received GOAWAY frame.  Unset if no
-  // GOAWAY frame has been received yet.
-  absl::optional<uint64_t> last_received_http3_goaway_id_;
-  // The identifier in the most recently sent GOAWAY frame.  Unset if no GOAWAY
-  // frame has been sent yet.
-  absl::optional<uint64_t> last_sent_http3_goaway_id_;
-
-  // Whether both this endpoint and our peer support HTTP datagrams and which
-  // draft is in use for this session.
-  HttpDatagramSupport http_datagram_support_ = HttpDatagramSupport::kNone;
-
-  // Whether the peer has indicated WebTransport support.
-  bool peer_supports_webtransport_ = false;
-
-  // This maps from draft-ietf-masque-h3-datagram-00 flow IDs to stream IDs.
-  // TODO(b/181256914) remove this when we deprecate support for that draft in
-  // favor of more recent ones.
-  absl::flat_hash_map<uint64_t, QuicStreamId>
-      h3_datagram_flow_id_to_stream_id_map_;
-
-  // Whether any settings have been received, either from the peer or from a
-  // session ticket.
-  bool any_settings_received_ = false;
-
-  // If ShouldBufferRequestsUntilSettings() is true, all streams that are
-  // blocked by that are tracked here.
-  absl::flat_hash_set<QuicStreamId> streams_waiting_for_settings_;
-
-  // WebTransport streams that do not have a session associated with them.
-  // Limited to kMaxUnassociatedWebTransportStreams; when the list is full,
-  // oldest streams are evicated first.
-  std::list<BufferedWebTransportStream> buffered_streams_;
-
-  // On the server side, if true, advertise and accept extended CONNECT method.
-  // On the client side, true if the peer advertised extended CONNECT.
-  bool allow_extended_connect_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
deleted file mode 100644
index 56ce579..0000000
--- a/quic/core/http/quic_spdy_session_test.cc
+++ /dev/null
@@ -1,3890 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_session.h"
-
-#include <cstdint>
-#include <limits>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/frames/quic_streams_blocked_frame.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_endian.h"
-#include "common/test_tools/quiche_test_utils.h"
-#include "spdy/core/spdy_framer.h"
-
-using spdy::kV3HighestPriority;
-using spdy::Spdy3PriorityToHttp2Weight;
-using spdy::SpdyFramer;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyPriority;
-using spdy::SpdyPriorityIR;
-using spdy::SpdySerializedFrame;
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtLeast;
-using ::testing::ElementsAre;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-bool VerifyAndClearStopSendingFrame(const QuicFrame& frame) {
-  EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
-  return ClearControlFrame(frame);
-}
-
-class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
- public:
-  explicit TestCryptoStream(QuicSession* session)
-      : QuicCryptoStream(session),
-        QuicCryptoHandshaker(this, session),
-        encryption_established_(false),
-        one_rtt_keys_available_(false),
-        params_(new QuicCryptoNegotiatedParameters) {
-    // Simulate a negotiated cipher_suite with a fake value.
-    params_->cipher_suite = 1;
-  }
-
-  void EstablishZeroRttEncryption() {
-    encryption_established_ = true;
-    session()->connection()->SetEncrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::make_unique<NullEncrypter>(session()->perspective()));
-  }
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
-    encryption_established_ = true;
-    one_rtt_keys_available_ = true;
-    QuicErrorCode error;
-    std::string error_details;
-    session()->config()->SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    session()->config()->SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-    if (session()->version().UsesTls()) {
-      if (session()->perspective() == Perspective::IS_CLIENT) {
-        session()->config()->SetOriginalConnectionIdToSend(
-            session()->connection()->connection_id());
-        session()->config()->SetInitialSourceConnectionIdToSend(
-            session()->connection()->connection_id());
-      } else {
-        session()->config()->SetInitialSourceConnectionIdToSend(
-            session()->connection()->client_connection_id());
-      }
-      TransportParameters transport_parameters;
-      EXPECT_TRUE(
-          session()->config()->FillTransportParameters(&transport_parameters));
-      error = session()->config()->ProcessTransportParameters(
-          transport_parameters, /* is_resumption = */ false, &error_details);
-    } else {
-      CryptoHandshakeMessage msg;
-      session()->config()->ToHandshakeMessage(&msg, transport_version());
-      error =
-          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
-    }
-    EXPECT_THAT(error, IsQuicNoError());
-    session()->OnNewEncryptionKeyAvailable(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(session()->perspective()));
-    session()->OnConfigNegotiated();
-    if (session()->connection()->version().handshake_protocol ==
-        PROTOCOL_TLS1_3) {
-      session()->OnTlsHandshakeComplete();
-    } else {
-      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    }
-    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-  }
-
-  // QuicCryptoStream implementation
-  ssl_early_data_reason_t EarlyDataReason() const override {
-    return ssl_early_data_unknown;
-  }
-  bool encryption_established() const override {
-    return encryption_established_;
-  }
-  bool one_rtt_keys_available() const override {
-    return one_rtt_keys_available_;
-  }
-  HandshakeState GetHandshakeState() const override {
-    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-  }
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override {
-    return *params_;
-  }
-  CryptoMessageParser* crypto_message_parser() override {
-    return QuicCryptoHandshaker::crypto_message_parser();
-  }
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnHandshakeDoneReceived() override {}
-  void OnNewTokenReceived(absl::string_view /*token*/) override {}
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_params*/) const override {
-    return "";
-  }
-  bool ValidateAddressToken(absl::string_view /*token*/) const override {
-    return true;
-  }
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
-    return nullptr;
-  }
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters /*cached_network_params*/) override {}
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-
-  bool HasPendingCryptoRetransmission() const override { return false; }
-
-  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
-  void OnConnectionClosed(QuicErrorCode /*error*/,
-                          ConnectionCloseSource /*source*/) override {}
-  SSL* GetSsl() const override { return nullptr; }
-
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    return false;
-  }
-
- private:
-  using QuicCryptoStream::session;
-
-  bool encryption_established_;
-  bool one_rtt_keys_available_;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-};
-
-class TestHeadersStream : public QuicHeadersStream {
- public:
-  explicit TestHeadersStream(QuicSpdySession* session)
-      : QuicHeadersStream(session) {}
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-};
-
-class TestStream : public QuicSpdyStream {
- public:
-  TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
-      : QuicSpdyStream(id, session, type) {}
-
-  TestStream(PendingStream* pending, QuicSpdySession* session)
-      : QuicSpdyStream(pending, session) {}
-
-  using QuicStream::CloseWriteSide;
-
-  void OnBodyAvailable() override {}
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-  MOCK_METHOD(bool, RetransmitStreamData,
-              (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
-              (override));
-
-  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
- protected:
-  bool AreHeadersValid(const QuicHeaderList& /*header_list*/) const override {
-    return true;
-  }
-};
-
-class TestSession : public QuicSpdySession {
- public:
-  explicit TestSession(QuicConnection* connection)
-      : QuicSpdySession(connection, nullptr, DefaultQuicConfig(),
-                        CurrentSupportedVersions()),
-        crypto_stream_(this),
-        writev_consumes_all_data_(false) {
-    this->connection()->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection->perspective()));
-    if (this->connection()->version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(this->connection());
-    }
-  }
-
-  ~TestSession() override { DeleteConnection(); }
-
-  TestCryptoStream* GetMutableCryptoStream() override {
-    return &crypto_stream_;
-  }
-
-  const TestCryptoStream* GetCryptoStream() const override {
-    return &crypto_stream_;
-  }
-
-  TestStream* CreateOutgoingBidirectionalStream() override {
-    TestStream* stream = new TestStream(GetNextOutgoingBidirectionalStreamId(),
-                                        this, BIDIRECTIONAL);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  TestStream* CreateOutgoingUnidirectionalStream() override {
-    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
-                                        this, WRITE_UNIDIRECTIONAL);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  TestStream* CreateIncomingStream(QuicStreamId id) override {
-    // Enforce the limit on the number of open streams.
-    if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
-        stream_id_manager().num_open_incoming_streams() + 1 >
-            max_open_incoming_bidirectional_streams()) {
-      connection()->CloseConnection(
-          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return nullptr;
-    } else {
-      TestStream* stream = new TestStream(
-          id, this,
-          DetermineStreamType(id, connection()->version(), perspective(),
-                              /*is_incoming=*/true, BIDIRECTIONAL));
-      ActivateStream(absl::WrapUnique(stream));
-      return stream;
-    }
-  }
-
-  TestStream* CreateIncomingStream(PendingStream* pending) override {
-    TestStream* stream = new TestStream(pending, this);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  bool ShouldCreateIncomingStream(QuicStreamId /*id*/) override { return true; }
-
-  bool ShouldCreateOutgoingBidirectionalStream() override { return true; }
-  bool ShouldCreateOutgoingUnidirectionalStream() override { return true; }
-
-  bool IsClosedStream(QuicStreamId id) {
-    return QuicSession::IsClosedStream(id);
-  }
-
-  QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
-    return QuicSpdySession::GetOrCreateStream(stream_id);
-  }
-
-  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
-                              QuicStreamOffset offset, StreamSendingState state,
-                              TransmissionType type,
-                              EncryptionLevel level) override {
-    bool fin = state != NO_FIN;
-    QuicConsumedData consumed(write_length, fin);
-    if (!writev_consumes_all_data_) {
-      consumed =
-          QuicSession::WritevData(id, write_length, offset, state, type, level);
-    }
-    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
-        id, consumed.bytes_consumed);
-    return consumed;
-  }
-
-  void set_writev_consumes_all_data(bool val) {
-    writev_consumes_all_data_ = val;
-  }
-
-  QuicConsumedData SendStreamData(QuicStream* stream) {
-    if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
-                                     stream->id()) &&
-        connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
-      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    }
-    QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
-    QuicConsumedData consumed =
-        WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
-                   GetEncryptionLevelToSendApplicationData());
-    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
-        consumed.bytes_consumed);
-    return consumed;
-  }
-
-  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
-    QUICHE_DCHECK(writev_consumes_all_data_);
-    return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
-                      GetEncryptionLevelToSendApplicationData());
-  }
-
-  bool ShouldNegotiateWebTransport() override { return supports_webtransport_; }
-  void set_supports_webtransport(bool value) { supports_webtransport_ = value; }
-
-  HttpDatagramSupport LocalHttpDatagramSupport() override {
-    return local_http_datagram_support_;
-  }
-  void set_local_http_datagram_support(HttpDatagramSupport value) {
-    local_http_datagram_support_ = value;
-  }
-
-  MOCK_METHOD(void, OnAcceptChFrame, (const AcceptChFrame&), (override));
-
-  using QuicSession::closed_streams;
-  using QuicSession::ShouldKeepConnectionAlive;
-  using QuicSpdySession::ProcessPendingStream;
-  using QuicSpdySession::UsesPendingStreamForFrame;
-
- private:
-  StrictMock<TestCryptoStream> crypto_stream_;
-
-  bool writev_consumes_all_data_;
-  bool supports_webtransport_ = false;
-  HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
-};
-
-class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
-    if (frame.type == MAX_STREAMS_FRAME) {
-      DeleteFrame(&const_cast<QuicFrame&>(frame));
-      return true;
-    }
-    return false;
-  }
-
- protected:
-  explicit QuicSpdySessionTestBase(Perspective perspective,
-                                   bool allow_extended_connect)
-      : connection_(new StrictMock<MockQuicConnection>(
-            &helper_, &alarm_factory_, perspective,
-            SupportedVersions(GetParam()))),
-        session_(connection_) {
-    if (perspective == Perspective::IS_SERVER &&
-        VersionUsesHttp3(transport_version()) &&
-        GetQuicReloadableFlag(quic_verify_request_headers_2)) {
-      session_.set_allow_extended_connect(allow_extended_connect);
-    }
-    session_.Initialize();
-    session_.config()->SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    session_.config()->SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-    if (VersionUsesHttp3(transport_version())) {
-      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
-          session_.config(), kHttp3StaticUnidirectionalStreamCount);
-    }
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    session_.OnConfigNegotiated();
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
-        .Times(testing::AnyNumber());
-    writer_ = static_cast<MockPacketWriter*>(
-        QuicConnectionPeer::GetWriter(session_.connection()));
-  }
-
-  void CheckClosedStreams() {
-    QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-        transport_version(), Perspective::IS_CLIENT);
-    if (!QuicVersionUsesCryptoFrames(transport_version())) {
-      first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
-    }
-    for (QuicStreamId i = first_stream_id; i < 100; i++) {
-      if (closed_streams_.find(i) == closed_streams_.end()) {
-        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
-      } else {
-        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
-      }
-    }
-  }
-
-  void CloseStream(QuicStreamId id) {
-    if (!VersionHasIetfQuicFrames(transport_version())) {
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .WillOnce(Invoke(&ClearControlFrame));
-    } else {
-      // IETF QUIC has two frames, RST_STREAM and STOP_SENDING
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .Times(2)
-          .WillRepeatedly(Invoke(&ClearControlFrame));
-    }
-    EXPECT_CALL(*connection_, OnStreamReset(id, _));
-
-    // QPACK streams might write data upon stream reset. Let the test session
-    // handle the data.
-    session_.set_writev_consumes_all_data(true);
-
-    session_.ResetStream(id, QUIC_STREAM_CANCELLED);
-    closed_streams_.insert(id);
-  }
-
-  ParsedQuicVersion version() const { return connection_->version(); }
-
-  QuicTransportVersion transport_version() const {
-    return connection_->transport_version();
-  }
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
-  }
-
-  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
-    return GetNthServerInitiatedBidirectionalStreamId(transport_version(), n);
-  }
-
-  QuicStreamId IdDelta() {
-    return QuicUtils::StreamIdDelta(transport_version());
-  }
-
-  std::string EncodeSettings(const SettingsFrame& settings) {
-    std::unique_ptr<char[]> buffer;
-    auto header_length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
-    return std::string(buffer.get(), header_length);
-  }
-
-  std::string SerializePriorityUpdateFrame(
-      const PriorityUpdateFrame& priority_update) {
-    std::unique_ptr<char[]> priority_buffer;
-    QuicByteCount priority_frame_length =
-        HttpEncoder::SerializePriorityUpdateFrame(priority_update,
-                                                  &priority_buffer);
-    return std::string(priority_buffer.get(), priority_frame_length);
-  }
-
-  // TODO(b/171463363): Remove.
-  std::string SerializeMaxPushIdFrame(PushId push_id) {
-    const QuicByteCount payload_length =
-        QuicDataWriter::GetVarInt62Len(push_id);
-
-    const QuicByteCount total_length =
-        QuicDataWriter::GetVarInt62Len(
-            static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)) +
-        QuicDataWriter::GetVarInt62Len(payload_length) +
-        QuicDataWriter::GetVarInt62Len(push_id);
-
-    std::string max_push_id_frame(total_length, '\0');
-    QuicDataWriter writer(total_length, &*max_push_id_frame.begin());
-
-    QUICHE_CHECK(writer.WriteVarInt62(
-        static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)));
-    QUICHE_CHECK(writer.WriteVarInt62(payload_length));
-    QUICHE_CHECK(writer.WriteVarInt62(push_id));
-    QUICHE_CHECK_EQ(0u, writer.remaining());
-
-    return max_push_id_frame;
-  }
-
-  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
-                               Perspective perspective, bool bidirectional) {
-    // Calculate and build up stream ID rather than use
-    // GetFirst... because the test that relies on this method
-    // needs to do the stream count where #1 is 0/1/2/3, and not
-    // take into account that stream 0 is special.
-    QuicStreamId id =
-        ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
-    if (!bidirectional) {
-      id |= 0x2;
-    }
-    if (perspective == Perspective::IS_SERVER) {
-      id |= 0x1;
-    }
-    return id;
-  }
-
-  void CompleteHandshake() {
-    if (VersionHasIetfQuicFrames(transport_version())) {
-      EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-          .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-    }
-    if (connection_->version().UsesTls() &&
-        connection_->perspective() == Perspective::IS_SERVER) {
-      // HANDSHAKE_DONE frame.
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .WillOnce(Invoke(&ClearControlFrame));
-    }
-
-    CryptoHandshakeMessage message;
-    session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
-    testing::Mock::VerifyAndClearExpectations(writer_);
-    testing::Mock::VerifyAndClearExpectations(connection_);
-  }
-
-  void ReceiveWebTransportSettings() {
-    SettingsFrame settings;
-    settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-    settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
-    settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
-    std::string data =
-        std::string(1, kControlStream) + EncodeSettings(settings);
-    QuicStreamId control_stream_id =
-        session_.perspective() == Perspective::IS_SERVER
-            ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(),
-                                                          3)
-            : GetNthServerInitiatedUnidirectionalStreamId(transport_version(),
-                                                          3);
-    QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
-    session_.OnStreamFrame(frame);
-  }
-
-  void ReceiveWebTransportSession(WebTransportSessionId session_id) {
-    QuicStreamFrame frame(session_id, /*fin=*/false, /*offset=*/0,
-                          absl::string_view());
-    session_.OnStreamFrame(frame);
-    QuicSpdyStream* stream =
-        static_cast<QuicSpdyStream*>(session_.GetOrCreateStream(session_id));
-    QuicHeaderList headers;
-    headers.OnHeaderBlockStart();
-    headers.OnHeader(":method", "CONNECT");
-    headers.OnHeader(":protocol", "webtransport");
-    if (session_.http_datagram_support() == HttpDatagramSupport::kDraft00) {
-      headers.OnHeader("datagram-flow-id", absl::StrCat(session_id));
-    } else {
-      headers.OnHeader("sec-webtransport-http3-draft02", "1");
-    }
-    stream->OnStreamHeaderList(/*fin=*/true, 0, headers);
-    if (session_.http_datagram_support() != HttpDatagramSupport::kDraft00) {
-      stream->OnCapsule(
-          Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
-    }
-    WebTransportHttp3* web_transport =
-        session_.GetWebTransportSession(session_id);
-    ASSERT_TRUE(web_transport != nullptr);
-    spdy::SpdyHeaderBlock header_block;
-    web_transport->HeadersReceived(header_block);
-  }
-
-  void ReceiveWebTransportUnidirectionalStream(WebTransportSessionId session_id,
-                                               QuicStreamId stream_id) {
-    char buffer[256];
-    QuicDataWriter data_writer(sizeof(buffer), buffer);
-    ASSERT_TRUE(data_writer.WriteVarInt62(kWebTransportUnidirectionalStream));
-    ASSERT_TRUE(data_writer.WriteVarInt62(session_id));
-    ASSERT_TRUE(data_writer.WriteStringPiece("test data"));
-    std::string data(buffer, data_writer.length());
-    QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
-    session_.OnStreamFrame(frame);
-  }
-
-  void TestHttpDatagramSetting(HttpDatagramSupport local_support,
-                               HttpDatagramSupport remote_support,
-                               HttpDatagramSupport expected_support,
-                               bool expected_datagram_supported);
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  TestSession session_;
-  std::set<QuicStreamId> closed_streams_;
-  MockPacketWriter* writer_;
-};
-
-class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
- protected:
-  QuicSpdySessionTestServer()
-      : QuicSpdySessionTestBase(Perspective::IS_SERVER, true) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServer,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdySessionTestServer, UsesPendingStreamsForFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
-      STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                        transport_version(), Perspective::IS_CLIENT)));
-  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
-      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                            transport_version(), Perspective::IS_CLIENT)));
-  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
-      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                            transport_version(), Perspective::IS_SERVER)));
-  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
-      STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                              transport_version(), Perspective::IS_CLIENT)));
-  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
-      RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
-                            transport_version(), Perspective::IS_CLIENT)));
-}
-
-TEST_P(QuicSpdySessionTestServer, PeerAddress) {
-  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
-            session_.peer_address());
-}
-
-TEST_P(QuicSpdySessionTestServer, SelfAddress) {
-  EXPECT_TRUE(session_.self_address().IsInitialized());
-}
-
-TEST_P(QuicSpdySessionTestServer, OneRttKeysAvailable) {
-  EXPECT_FALSE(session_.OneRttKeysAvailable());
-  CompleteHandshake();
-  EXPECT_TRUE(session_.OneRttKeysAvailable());
-}
-
-TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
-  // Ensure that no streams are initially closed.
-  QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
-  }
-  for (QuicStreamId i = first_stream_id; i < 100; i++) {
-    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
-  }
-}
-
-TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
-  // Both client initiated streams with smaller stream IDs are available.
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedBidirectionalId(0)));
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedBidirectionalId(1)));
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedBidirectionalId(0)) != nullptr);
-}
-
-TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
-  CompleteHandshake();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
-  QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
-
-  CheckClosedStreams();
-  CloseStream(GetNthServerInitiatedBidirectionalId(0));
-  CheckClosedStreams();
-  CloseStream(GetNthServerInitiatedBidirectionalId(1));
-  CheckClosedStreams();
-}
-
-TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
-  CompleteHandshake();
-  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
-  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
-  session_.GetOrCreateStream(stream_id1);
-  session_.GetOrCreateStream(stream_id2);
-
-  CheckClosedStreams();
-  CloseStream(stream_id1);
-  CheckClosedStreams();
-  CloseStream(stream_id2);
-  // Create a stream, and make another available.
-  QuicStream* stream3 = session_.GetOrCreateStream(stream_id2 + 4);
-  CheckClosedStreams();
-  // Close one, but make sure the other is still not closed
-  CloseStream(stream3->id());
-  CheckClosedStreams();
-}
-
-TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // For IETF QUIC, we should be able to obtain the max allowed
-    // stream ID, the next ID should fail. Since the actual limit
-    // is not the number of open streams, we allocate the max and the max+2.
-    // Get the max allowed stream ID, this should succeed.
-    QuicStreamId stream_id = StreamCountToId(
-        QuicSessionPeer::ietf_streamid_manager(&session_)
-            ->max_incoming_bidirectional_streams(),
-        Perspective::IS_CLIENT,  // Client initates stream, allocs stream id.
-        /*bidirectional=*/true);
-    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-    stream_id =
-        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
-                            ->max_incoming_unidirectional_streams(),
-                        Perspective::IS_CLIENT,
-                        /*bidirectional=*/false);
-    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(2);
-    // Get the (max allowed stream ID)++. These should all fail.
-    stream_id =
-        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
-                                ->max_incoming_bidirectional_streams() +
-                            1,
-                        Perspective::IS_CLIENT,
-                        /*bidirectional=*/true);
-    EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
-
-    stream_id =
-        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
-                                ->max_incoming_unidirectional_streams() +
-                            1,
-                        Perspective::IS_CLIENT,
-                        /*bidirectional=*/false);
-    EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
-  } else {
-    QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-    session_.GetOrCreateStream(stream_id);
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-    EXPECT_NE(
-        nullptr,
-        session_.GetOrCreateStream(
-            stream_id +
-            IdDelta() *
-                (session_.max_open_incoming_bidirectional_streams() - 1)));
-  }
-}
-
-TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
-  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
-  QuicStreamId stream_id2;
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
-  // A stream ID which is too large to create.
-  stream_id2 = GetNthClientInitiatedBidirectionalId(
-      2 * session_.MaxAvailableBidirectionalStreams() + 4);
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
-  } else {
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
-  }
-  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
-}
-
-TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
-  // When max_open_streams_ is 200, should be able to create 200 streams
-  // out-of-order, that is, creating the one with the largest stream ID first.
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
-  }
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  // Create one stream.
-  session_.GetOrCreateStream(stream_id);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  // Stream count is 200, GetNth... starts counting at 0, so the 200'th stream
-  // is 199. BUT actually we need to do 198 because the crypto stream (Stream
-  // ID 0) has not been registered, but GetNth... assumes that it has.
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(
-                         GetNthClientInitiatedBidirectionalId(198)));
-}
-
-TEST_P(QuicSpdySessionTestServer,
-       DebugDFatalIfMarkingClosedStreamWriteBlocked) {
-  CompleteHandshake();
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId closed_stream_id = stream2->id();
-  // Close the stream.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
-  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-  std::string msg =
-      absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
-  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
-                  msg);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWrite) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  InSequence s;
-
-  // Reregister, to test the loop limit.
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  // 2 will get called a second time as it didn't finish its block
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
-    session_.SendStreamData(stream6);
-  }));
-  // 4 will not get called, as we exceeded the loop limit.
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, TooLargeStreamBlocked) {
-  // STREAMS_BLOCKED frame is IETF QUIC only.
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  CompleteHandshake();
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Simualte the situation where the incoming stream count is at its limit and
-  // the peer is blocked.
-  QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
-      static_cast<QuicSession*>(&session_), QuicUtils::GetMaxStreamCount());
-  QuicStreamsBlockedFrame frame;
-  frame.stream_count = QuicUtils::GetMaxStreamCount();
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_));
-  session_.OnStreamsBlockedFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestServer, TestBatchedWrites) {
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.set_writev_consumes_all_data(true);
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  // With two sessions blocked, we should get two write calls.  They should both
-  // go to the first stream as it will only write 6k and mark itself blocked
-  // again.
-  InSequence s;
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  session_.OnCanWrite();
-
-  // We should get one more call for stream2, at which point it has used its
-  // write quota and we move over to stream 4.
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendLargeFakeData(stream4, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  }));
-  session_.OnCanWrite();
-
-  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
-  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
-  // will cede back to 4.
-  stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  EXPECT_CALL(*stream4, OnCanWrite())
-      .WillOnce(Invoke([this, stream4, stream6]() {
-        session_.SendLargeFakeData(stream4, 6000);
-        session_.MarkConnectionLevelWriteBlocked(stream4->id());
-        session_.MarkConnectionLevelWriteBlocked(stream6->id());
-      }));
-  EXPECT_CALL(*stream6, OnCanWrite())
-      .WillOnce(Invoke([this, stream4, stream6]() {
-        session_.SendStreamData(stream6);
-        session_.SendLargeFakeData(stream4, 6000);
-      }));
-  session_.OnCanWrite();
-
-  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
-  // cede and 2 should resume.
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendLargeFakeData(stream4, 12000);
-    session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  }));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  session_.OnCanWrite();
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
-  // Encryption needs to be established before data can be sent.
-  CompleteHandshake();
-
-  // Drive congestion control manually.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
-      .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
-  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-  }));
-  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
-    session_.SendStreamData(stream6);
-  }));
-
-  // Expect that we only send one packet, the writes from different streams
-  // should be bundled together.
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  InSequence s;
-
-  // Drive congestion control manually.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
-    session_.SendStreamData(stream6);
-  }));
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
-  // stream4->OnCanWrite is not called.
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // Still congestion-control blocked.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // stream4->OnCanWrite is called once the connection stops being
-  // congestion-control blocked.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-  }));
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
-  CompleteHandshake();
-  // Drive congestion control manually in order to ensure that
-  // application-limited signaling is handled correctly.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
-  // Drive packet writer manually.
-  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)).Times(0);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-
-  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
-  // This tests prioritization of the crypto stream when flow control limits are
-  // reached. When CRYPTO frames are in use, there is no flow control for the
-  // crypto handshake, so this test is irrelevant.
-  if (QuicVersionUsesCryptoFrames(transport_version())) {
-    return;
-  }
-  session_.set_writev_consumes_all_data(true);
-  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
-
-  // Test that blocking other streams does not change our status.
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  EXPECT_FALSE(session_.HasPendingHandshake());
-
-  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream3->id());
-  EXPECT_FALSE(session_.HasPendingHandshake());
-
-  // Blocking (due to buffering of) the Crypto stream is detected.
-  session_.MarkConnectionLevelWriteBlocked(
-      QuicUtils::GetCryptoStreamId(transport_version()));
-  EXPECT_TRUE(session_.HasPendingHandshake());
-
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  EXPECT_TRUE(session_.HasPendingHandshake());
-
-  InSequence s;
-  // Force most streams to re-register, which is common scenario when we block
-  // the Crypto stream, and only the crypto stream can "really" write.
-
-  // Due to prioritization, we *should* be asked to write the crypto stream
-  // first.
-  // Don't re-register the crypto stream (which signals complete writing).
-  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-  EXPECT_CALL(*crypto_stream, OnCanWrite());
-
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
-    session_.SendStreamData(stream3);
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-    session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  }));
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
-}
-
-TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  CloseStream(stream6->id());
-
-  InSequence s;
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-  }));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer,
-       OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
-  CompleteHandshake();
-  // Drive congestion control manually in order to ensure that
-  // application-limited signaling is handled correctly.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
-  // Ensure connection level flow control blockage.
-  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
-  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
-  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-
-  // Mark the crypto and headers streams as write blocked, we expect them to be
-  // allowed to write later.
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    session_.MarkConnectionLevelWriteBlocked(
-        QuicUtils::GetCryptoStreamId(transport_version()));
-  }
-
-  // Create a data stream, and although it is write blocked we never expect it
-  // to be allowed to write as we are connection level flow control blocked.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream->id());
-  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
-
-  // The crypto and headers streams should be called even though we are
-  // connection flow control blocked.
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-    EXPECT_CALL(*crypto_stream, OnCanWrite());
-  }
-
-  if (!VersionUsesHttp3(transport_version())) {
-    TestHeadersStream* headers_stream;
-    QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
-    headers_stream = new TestHeadersStream(&session_);
-    QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
-    session_.MarkConnectionLevelWriteBlocked(
-        QuicUtils::GetHeadersStreamId(transport_version()));
-    EXPECT_CALL(*headers_stream, OnCanWrite());
-  }
-
-  // After the crypto and header streams perform a write, the connection will be
-  // blocked by the flow control, hence it should become application-limited.
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, SendGoAway) {
-  CompleteHandshake();
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // HTTP/3 GOAWAY has different semantic and thus has its own test.
-    return;
-  }
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-  EXPECT_TRUE(session_.goaway_sent());
-
-  const QuicStreamId kTestStreamId = 5u;
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  EXPECT_CALL(*connection_,
-              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
-      .Times(0);
-  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-}
-
-TEST_P(QuicSpdySessionTestServer, SendGoAwayWithoutEncryption) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // HTTP/3 GOAWAY has different semantic and thus has its own test.
-    return;
-  }
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_PEER_GOING_AWAY, "Going Away.",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-  EXPECT_FALSE(session_.goaway_sent());
-}
-
-TEST_P(QuicSpdySessionTestServer, SendHttp3GoAway) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  CompleteHandshake();
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  // Send max stream id (currently 32 bits).
-  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
-  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-  EXPECT_TRUE(session_.goaway_sent());
-
-  // New incoming stream is not reset.
-  const QuicStreamId kTestStreamId =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
-  EXPECT_CALL(*connection_, OnStreamReset(kTestStreamId, _)).Times(0);
-  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-
-  // No more GOAWAY frames are sent because they could not convey new
-  // information to the client.
-  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-}
-
-TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayWithoutEncryption) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_PEER_GOING_AWAY, "Goaway",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-  EXPECT_FALSE(session_.goaway_sent());
-}
-
-TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  CompleteHandshake();
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  const QuicStreamId kTestStreamId =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
-  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  // Send max stream id (currently 32 bits).
-  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
-  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-  EXPECT_TRUE(session_.goaway_sent());
-
-  // No more GOAWAY frames are sent because they could not convey new
-  // information to the client.
-  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
-}
-
-TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
-  CompleteHandshake();
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // HTTP/3 GOAWAY doesn't have such restriction.
-    return;
-  }
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-  EXPECT_TRUE(session_.goaway_sent());
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-}
-
-TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // HTTP/3 GOAWAY has different semantics and thus has its own test.
-    return;
-  }
-  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
-                          session_.next_outgoing_bidirectional_stream_id(), "");
-  session_.OnGoAway(go_away);
-}
-
-TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  EXPECT_FALSE(session_.goaway_received());
-  PushId push_id1 = 0;
-  session_.OnHttp3GoAway(push_id1);
-  EXPECT_TRUE(session_.goaway_received());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(
-          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
-          "GOAWAY received with ID 1 greater than previously received ID 0",
-          _));
-  PushId push_id2 = 1;
-  session_.OnHttp3GoAway(push_id2);
-}
-
-// Test that server session will send a connectivity probe in response to a
-// connectivity probe on the same path.
-TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicSocketAddress old_peer_address =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
-  EXPECT_EQ(old_peer_address, session_.peer_address());
-
-  QuicSocketAddress new_peer_address =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
-
-    EXPECT_CALL(*connection_,
-                SendConnectivityProbingPacket(nullptr, new_peer_address));
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // Need to explicitly do this to emulate the reception of a PathChallenge,
-    // which stores its payload for use in generating the response.
-    connection_->OnPathChallengeFrame(
-        QuicPathChallengeFrame(0, {{0, 1, 2, 3, 4, 5, 6, 7}}));
-  }
-  session_.OnPacketReceived(session_.self_address(), new_peer_address,
-                            /*is_connectivity_probe=*/true);
-  EXPECT_EQ(old_peer_address, session_.peer_address());
-}
-
-TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
-  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
-            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
-  CompleteHandshake();
-  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
-            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
-}
-
-TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
-  CompleteHandshake();
-  // Send two bytes of payload.
-  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For version99, OnStreamReset gets called because of the STOP_SENDING,
-    // below. EXPECT the call there.
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0), _));
-  }
-
-  // In HTTP/3, Qpack stream will send data on stream reset and cause packet to
-  // be flushed.
-  if (VersionUsesHttp3(transport_version())) {
-    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-        .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  }
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  QuicRstStreamFrame rst1(kInvalidControlFrameId,
-                          GetNthClientInitiatedBidirectionalId(0),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  session_.OnRstStream(rst1);
-
-  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
-  // one-way close.
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // Only needed for version 99/IETF QUIC.
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId,
-                                      GetNthClientInitiatedBidirectionalId(0),
-                                      QUIC_ERROR_PROCESSING_STREAM);
-    // Expect the RESET_STREAM that is generated in response to receiving a
-    // STOP_SENDING.
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_ERROR_PROCESSING_STREAM));
-    session_.OnStopSendingFrame(stop_sending);
-  }
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-  // Connection should remain alive.
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
-  QuicStreamId id;
-  // Initialize HTTP/3 control stream.
-  if (VersionUsesHttp3(transport_version())) {
-    id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-    char type[] = {kControlStream};
-
-    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
-    session_.OnStreamFrame(data1);
-  } else {
-    id = QuicUtils::GetHeadersStreamId(transport_version());
-  }
-
-  // Send two bytes of payload.
-  QuicStreamFrame data1(id, true, 0, absl::string_view("HT"));
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
-  QuicStreamId id;
-  QuicErrorCode expected_error;
-  std::string error_message;
-  // Initialize HTTP/3 control stream.
-  if (VersionUsesHttp3(transport_version())) {
-    id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-    char type[] = {kControlStream};
-
-    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
-    session_.OnStreamFrame(data1);
-    expected_error = QUIC_HTTP_CLOSED_CRITICAL_STREAM;
-    error_message = "RESET_STREAM received for receive control stream";
-  } else {
-    id = QuicUtils::GetHeadersStreamId(transport_version());
-    expected_error = QUIC_INVALID_STREAM_ID;
-    error_message = "Attempt to reset headers stream";
-  }
-
-  // Send two bytes of payload.
-  QuicRstStreamFrame rst1(kInvalidControlFrameId, id,
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(expected_error, error_message,
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnRstStream(rst1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
-  // Send two bytes of payload.
-  QuicStreamFrame data1(QuicUtils::GetInvalidStreamId(transport_version()),
-                        true, 0, absl::string_view("HT"));
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
-  // Send two bytes of payload.
-  QuicRstStreamFrame rst1(kInvalidControlFrameId,
-                          QuicUtils::GetInvalidStreamId(transport_version()),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnRstStream(rst1);
-}
-
-TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
-  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
-    // This test requires Google QUIC crypto because it assumes streams start
-    // off unblocked.
-    return;
-  }
-  // Test that if a stream is flow control blocked, then on receipt of the SHLO
-  // containing a suitable send window offset, the stream becomes unblocked.
-
-  // Ensure that Writev consumes all the data it is given (simulate no socket
-  // blocking).
-  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
-  session_.set_writev_consumes_all_data(true);
-
-  // Create a stream, and send enough data to make it flow control blocked.
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  std::string body(kMinimumFlowControlSendWindow, '.');
-  EXPECT_FALSE(stream2->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
-  stream2->WriteOrBufferBody(body, false);
-  EXPECT_TRUE(stream2->IsFlowControlBlocked());
-  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
-  // Now complete the crypto handshake, resulting in an increased flow control
-  // send window.
-  CompleteHandshake();
-  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
-  // Stream is now unblocked.
-  EXPECT_FALSE(stream2->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-#if !defined(OS_IOS)
-// This test is failing flakily for iOS bots.
-// http://crbug.com/425050
-// NOTE: It's not possible to use the standard MAYBE_ convention to disable
-// this test on iOS because when this test gets instantiated it ends up with
-// various names that are dependent on the parameters passed.
-TEST_P(QuicSpdySessionTestServer,
-       HandshakeUnblocksFlowControlBlockedHeadersStream) {
-  // This test depends on stream-level flow control for the crypto stream, which
-  // doesn't exist when CRYPTO frames are used.
-  if (QuicVersionUsesCryptoFrames(transport_version())) {
-    return;
-  }
-
-  // This test depends on the headers stream, which does not exist when QPACK is
-  // used.
-  if (VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  // Test that if the header stream is flow control blocked, then if the SHLO
-  // contains a larger send window offset, the stream becomes unblocked.
-  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
-  session_.set_writev_consumes_all_data(true);
-  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-  EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-  QuicHeadersStream* headers_stream =
-      QuicSpdySessionPeer::GetHeadersStream(&session_);
-  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-  QuicStreamId stream_id = 5;
-  // Write until the header stream is flow control blocked.
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  SpdyHeaderBlock headers;
-  SimpleRandom random;
-  while (!headers_stream->IsFlowControlBlocked() && stream_id < 2000) {
-    EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-    EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-    headers["header"] = absl::StrCat(random.RandUint64(), random.RandUint64(),
-                                     random.RandUint64());
-    session_.WriteHeadersOnHeadersStream(stream_id, headers.Clone(), true,
-                                         spdy::SpdyStreamPrecedence(0),
-                                         nullptr);
-    stream_id += IdDelta();
-  }
-  // Write once more to ensure that the headers stream has buffered data. The
-  // random headers may have exactly filled the flow control window.
-  session_.WriteHeadersOnHeadersStream(stream_id, std::move(headers), true,
-                                       spdy::SpdyStreamPrecedence(0), nullptr);
-  EXPECT_TRUE(headers_stream->HasBufferedData());
-
-  EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-  EXPECT_FALSE(session_.HasDataToWrite());
-
-  // Now complete the crypto handshake, resulting in an increased flow control
-  // send window.
-  CompleteHandshake();
-
-  // Stream is now unblocked and will no longer have buffered data.
-  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-  EXPECT_TRUE(headers_stream->HasBufferedData());
-  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
-      &session_, QuicUtils::GetHeadersStreamId(transport_version())));
-}
-#endif  // !defined(OS_IOS)
-
-TEST_P(QuicSpdySessionTestServer,
-       ConnectionFlowControlAccountingRstOutOfOrder) {
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  CompleteHandshake();
-  // Test that when we receive an out of order stream RST we correctly adjust
-  // our connection level flow control receive window.
-  // On close, the stream should mark as consumed all bytes between the highest
-  // byte consumed so far and the final byte offset from the RST frame.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
-  const QuicStreamOffset kByteOffset =
-      1 + kInitialSessionFlowControlWindowForTest / 2;
-
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For version99 the call to OnStreamReset happens as a result of receiving
-    // the STOP_SENDING, so set up the EXPECT there.
-    EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-    EXPECT_CALL(*connection_, SendControlFrame(_));
-  } else {
-    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-        .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  }
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
-                               QUIC_STREAM_CANCELLED, kByteOffset);
-  session_.OnRstStream(rst_frame);
-  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
-  // one-way close.
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // Only needed for version 99/IETF QUIC.
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream->id(),
-                                      QUIC_STREAM_CANCELLED);
-    // Expect the RESET_STREAM that is generated in response to receiving a
-    // STOP_SENDING.
-    EXPECT_CALL(*connection_,
-                OnStreamReset(stream->id(), QUIC_STREAM_CANCELLED));
-    EXPECT_CALL(*connection_, SendControlFrame(_));
-    session_.OnStopSendingFrame(stop_sending);
-  }
-
-  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
-}
-
-TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
-  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
-    // IETF Quic doesn't require a minimum flow control window.
-    return;
-  }
-  // Test that receipt of an invalid (< default) stream flow control window from
-  // the peer results in the connection being torn down.
-  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
-  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
-                                                            kInvalidWindow);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
-  session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
-  QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(
-          _, "new unidirectional limit 2 decreases the current limit: 3", _));
-  session_.OnConfigNegotiated();
-}
-
-// Test negotiation of custom server initial flow control window.
-TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
-  QuicTagVector copt;
-  copt.push_back(kIFW7);
-  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
-                             session_.flow_controller()));
-}
-
-TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
-  if (VersionUsesHttp3(transport_version())) {
-    // The test relies on headers stream, which no longer exists in IETF QUIC.
-    return;
-  }
-
-  // Test that a flow control blocked headers stream gets unblocked on recipt of
-  // a WINDOW_UPDATE frame.
-
-  // Set the headers stream to be flow control blocked.
-  QuicHeadersStream* headers_stream =
-      QuicSpdySessionPeer::GetHeadersStream(&session_);
-  QuicStreamPeer::SetSendWindowOffset(headers_stream, 0);
-  EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
-  // Unblock the headers stream by supplying a WINDOW_UPDATE.
-  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId,
-                                            headers_stream->id(),
-                                            2 * kMinimumFlowControlSendWindow);
-  session_.OnWindowUpdateFrame(window_update_frame);
-  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-TEST_P(QuicSpdySessionTestServer,
-       TooManyUnfinishedStreamsCauseServerRejectStream) {
-  // If a buggy/malicious peer creates too many streams that are not ended
-  // with a FIN or RST then we send an RST to refuse streams for versions other
-  // than version 99. In version 99 the connection gets closed.
-  CompleteHandshake();
-  const QuicStreamId kMaxStreams = 5;
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
-                                                            kMaxStreams);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
-  }
-  // GetNth assumes that both the crypto and header streams have been
-  // open, but the stream id manager, using GetFirstBidirectional... only
-  // assumes that the crypto stream is open. This means that GetNth...(0)
-  // Will return stream ID == 8 (with id ==0 for crypto and id==4 for headers).
-  // It also means that GetNth(kMax..=5) returns 28 (streams 0/1/2/3/4 are ids
-  // 8, 12, 16, 20, 24, respectively, so stream#5 is stream id 28).
-  // However, the stream ID manager does not assume stream 4 is for headers.
-  // The ID manager would assume that stream#5 is streamid 24.
-  // In order to make this all work out properly, kFinalStreamId will
-  // be set to GetNth...(kMaxStreams-1)... but only for IETF QUIC
-  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
-  const QuicStreamId kFinalStreamId =
-      GetNthClientInitiatedBidirectionalId(kMaxStreams);
-  // Create kMaxStreams data streams, and close them all without receiving a
-  // FIN or a RST_STREAM from the client.
-  const QuicStreamId kNextId = QuicUtils::StreamIdDelta(transport_version());
-  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) {
-    QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
-    session_.OnStreamFrame(data1);
-    CloseStream(i);
-  }
-  // Try and open a stream that exceeds the limit.
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // On versions other than 99, opening such a stream results in a
-    // RST_STREAM.
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-    EXPECT_CALL(*connection_,
-                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
-        .Times(1);
-  } else {
-    // On version 99 opening such a stream results in a connection close.
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_INVALID_STREAM_ID,
-                        testing::MatchesRegex(
-                            "Stream id \\d+ would exceed stream count limit 5"),
-                        _));
-  }
-  // Create one more data streams to exceed limit of open stream.
-  QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
-  // Verify that a draining stream (which has received a FIN but not consumed
-  // it) does not count against the open quota (because it is closed from the
-  // protocol point of view).
-  CompleteHandshake();
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // Simulate receiving a config. so that MAX_STREAMS/etc frames may
-    // be transmitted
-    QuicSessionPeer::set_is_configured(&session_, true);
-    // Version 99 will result in a MAX_STREAMS frame as streams are consumed
-    // (via the OnStreamFrame call) and then released (via
-    // StreamDraining). Eventually this node will believe that the peer is
-    // running low on available stream ids and then send a MAX_STREAMS frame,
-    // caught by this EXPECT_CALL.
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  }
-  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
-  const QuicStreamId kMaxStreams = 5;
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
-                                                            kMaxStreams);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
-  }
-
-  // Create kMaxStreams + 1 data streams, and mark them draining.
-  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
-  const QuicStreamId kFinalStreamId =
-      GetNthClientInitiatedBidirectionalId(kMaxStreams + 1);
-  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) {
-    QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
-    session_.OnStreamFrame(data1);
-    EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-    session_.StreamDraining(i, /*unidirectional=*/false);
-    EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-  }
-}
-
-// TODO(b/171463363): Remove.
-TEST_P(QuicSpdySessionTestServer, ReduceMaxPushId) {
-  if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
-    return;
-  }
-
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Use an arbitrary stream id for incoming control stream.
-  QuicStreamId stream_id =
-      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-  absl::string_view stream_type(type, 1);
-
-  QuicStreamOffset offset = 0;
-  QuicStreamFrame data1(stream_id, false, offset, stream_type);
-  offset += stream_type.length();
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(stream_id,
-            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
-  SettingsFrame settings;
-  std::string settings_frame = EncodeSettings(settings);
-  QuicStreamFrame data2(stream_id, false, offset, settings_frame);
-  offset += settings_frame.length();
-
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
-  session_.OnStreamFrame(data2);
-
-  std::string max_push_id_frame1 = SerializeMaxPushIdFrame(/* push_id = */ 3);
-  QuicStreamFrame data3(stream_id, false, offset, max_push_id_frame1);
-  offset += max_push_id_frame1.length();
-
-  EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
-  session_.OnStreamFrame(data3);
-
-  std::string max_push_id_frame2 = SerializeMaxPushIdFrame(/* push_id = */ 1);
-  QuicStreamFrame data4(stream_id, false, offset, max_push_id_frame2);
-
-  EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_INVALID_MAX_PUSH_ID,
-                              "MAX_PUSH_ID received with value 1 which is "
-                              "smaller that previously received value 3",
-                              _));
-  session_.OnStreamFrame(data4);
-}
-
-class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
- protected:
-  QuicSpdySessionTestClient()
-      : QuicSpdySessionTestBase(Perspective::IS_CLIENT, false) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestClient,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdySessionTestClient, UsesPendingStreamsForFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
-      STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                        transport_version(), Perspective::IS_SERVER)));
-  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
-      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                            transport_version(), Perspective::IS_SERVER)));
-  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
-      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                            transport_version(), Perspective::IS_CLIENT)));
-  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
-      STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
-                              transport_version(), Perspective::IS_SERVER)));
-  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
-      RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
-                            transport_version(), Perspective::IS_SERVER)));
-}
-
-// Regression test for crbug.com/977581.
-TEST_P(QuicSpdySessionTestClient, BadStreamFramePendingStream) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-  QuicStreamId stream_id1 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  // A bad stream frame with no data and no fin.
-  QuicStreamFrame data1(stream_id1, false, 0, 0);
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestClient, PendingStreamKeepsConnectionAlive) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_SERVER);
-
-  QuicStreamFrame frame(stream_id, false, 1, "test");
-  EXPECT_FALSE(session_.ShouldKeepConnectionAlive());
-  session_.OnStreamFrame(frame);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_TRUE(session_.ShouldKeepConnectionAlive());
-}
-
-TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
-  // Both server initiated streams with smaller stream IDs should be available.
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthServerInitiatedBidirectionalId(0)));
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthServerInitiatedBidirectionalId(1)));
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
-  // And client initiated stream ID should be not available.
-  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedBidirectionalId(0)));
-}
-
-// Regression test for b/130740258 and https://crbug.com/971779.
-// If headers that are too large or empty are received (these cases are handled
-// the same way, as QuicHeaderList clears itself when headers exceed the limit),
-// then the stream is reset.  No more frames must be sent in this case.
-TEST_P(QuicSpdySessionTestClient, TooLargeHeadersMustNotCauseWriteAfterReset) {
-  // In IETF QUIC, HEADERS do not carry FIN flag, and OnStreamHeaderList() is
-  // never called after an error, including too large headers.
-  if (VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  // Write headers with FIN set to close write side of stream.
-  // Header block does not matter.
-  stream->WriteHeaders(SpdyHeaderBlock(), /* fin = */ true, nullptr);
-
-  // Receive headers that are too large or empty, with FIN set.
-  // This causes the stream to be reset.  No frames must be written after this.
-  QuicHeaderList headers;
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream->id(), QUIC_HEADERS_TOO_LARGE));
-  stream->OnStreamHeaderList(/* fin = */ true,
-                             headers.uncompressed_header_bytes(), headers);
-}
-
-TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
-  // Verify that an incoming FIN is recorded in a stream object even if the read
-  // side has been closed.  This prevents an entry from being made in
-  // locally_closed_streams_highest_offset_ (which will never be deleted).
-  CompleteHandshake();
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId stream_id = stream->id();
-
-  // Close the read side manually.
-  QuicStreamPeer::CloseReadSide(stream);
-
-  // Receive a stream data frame with FIN.
-  QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
-  session_.OnStreamFrame(frame);
-  EXPECT_TRUE(stream->fin_received());
-
-  // Reset stream locally.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  stream->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
-
-  EXPECT_TRUE(connection_->connected());
-  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
-  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
-
-  // The stream is not waiting for the arrival of the peer's final offset as it
-  // was received with the FIN earlier.
-  EXPECT_EQ(
-      0u,
-      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
-}
-
-TEST_P(QuicSpdySessionTestClient, WritePriority) {
-  if (VersionUsesHttp3(transport_version())) {
-    // IETF QUIC currently doesn't support PRIORITY.
-    return;
-  }
-  CompleteHandshake();
-
-  TestHeadersStream* headers_stream;
-  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
-  headers_stream = new TestHeadersStream(&session_);
-  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
-
-  // Make packet writer blocked so |headers_stream| will buffer its write data.
-  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
-
-  const QuicStreamId id = 4;
-  const QuicStreamId parent_stream_id = 9;
-  const SpdyPriority priority = kV3HighestPriority;
-  const bool exclusive = true;
-  session_.WritePriority(id, parent_stream_id,
-                         Spdy3PriorityToHttp2Weight(priority), exclusive);
-
-  QuicStreamSendBuffer& send_buffer =
-      QuicStreamPeer::SendBuffer(headers_stream);
-  ASSERT_EQ(1u, send_buffer.size());
-
-  SpdyPriorityIR priority_frame(
-      id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive);
-  SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
-  SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame);
-
-  const quiche::QuicheMemSlice& slice =
-      QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
-  EXPECT_EQ(absl::string_view(frame.data(), frame.size()),
-            absl::string_view(slice.data(), slice.length()));
-}
-
-TEST_P(QuicSpdySessionTestClient, Http3ServerPush) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  // Push unidirectional stream is type 0x01.
-  std::string frame_type1 = absl::HexStringToBytes("01");
-  QuicStreamId stream_id1 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
-      .Times(1);
-  session_.OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false,
-                                         /* offset = */ 0, frame_type1));
-}
-
-TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  // Push unidirectional stream is type 0x01.
-  std::string frame_type = absl::HexStringToBytes("01");
-  // The first field of a push stream is the Push ID.
-  std::string push_id = absl::HexStringToBytes("4000");
-
-  QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
-  QuicStreamFrame data1(stream_id,
-                        /* fin = */ false, /* offset = */ 0, frame_type);
-  QuicStreamFrame data2(stream_id,
-                        /* fin = */ false, /* offset = */ frame_type.size(),
-                        push_id);
-
-  // Receiving some stream data without stream type does not open the stream.
-  session_.OnStreamFrame(data2);
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
-      .Times(1);
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
-  CompleteHandshake();
-  InSequence s;
-
-  // Drive congestion control manually.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
-  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-
-  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
-  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
-
-  // Lost data on cryption stream, streams 2 and 4.
-  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
-        .WillOnce(Return(true));
-  }
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
-  session_.OnFrameLost(QuicFrame(frame3));
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    QuicStreamFrame frame1(QuicUtils::GetCryptoStreamId(transport_version()),
-                           false, 0, 1300);
-    session_.OnFrameLost(QuicFrame(frame1));
-  } else {
-    QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
-    session_.OnFrameLost(QuicFrame(&crypto_frame));
-  }
-  session_.OnFrameLost(QuicFrame(frame2));
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // Mark streams 2 and 4 write blocked.
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  // Lost data is retransmitted before new data, and retransmissions for crypto
-  // stream go first.
-  // Do not check congestion window when crypto stream has lost data.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    EXPECT_CALL(*crypto_stream, OnCanWrite());
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
-        .WillOnce(Return(false));
-  }
-  // Check congestion window for non crypto streams.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, OnCanWrite());
-  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
-  // Connection is blocked.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // Unblock connection.
-  // Stream 2 retransmits lost data.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  // Stream 2 sends new data.
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, OnCanWrite());
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
-  // Resetting a stream will send a QPACK Stream Cancellation instruction on the
-  // decoder stream.  For simplicity, ignore writes on this stream.
-  CompleteHandshake();
-  NoopQpackStreamSenderDelegate qpack_stream_sender_delegate;
-  if (VersionUsesHttp3(transport_version())) {
-    session_.qpack_decoder()->set_qpack_stream_sender_delegate(
-        &qpack_stream_sender_delegate);
-  }
-
-  InSequence s;
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
-  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
-  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
-
-  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
-  session_.OnFrameLost(QuicFrame(frame3));
-  session_.OnFrameLost(QuicFrame(frame2));
-  session_.OnFrameLost(QuicFrame(frame1));
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-
-  // Reset stream 4 locally.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
-  stream4->Reset(QUIC_STREAM_CANCELLED);
-
-  // Verify stream 4 is removed from streams with lost data list.
-  EXPECT_CALL(*stream6, OnCanWrite());
-  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*stream6, OnCanWrite());
-  session_.OnCanWrite();
-}
-
-TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
-  CompleteHandshake();
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-  InSequence s;
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  session_.SendWindowUpdate(stream2->id(), 9);
-
-  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
-  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
-  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
-  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1));
-  frames.push_back(QuicFrame(window_update));
-  frames.push_back(QuicFrame(frame2));
-  frames.push_back(QuicFrame(frame3));
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-
-  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  TestStream* stream = session_.CreateIncomingStream(stream_id);
-  session_.OnPriorityFrame(stream_id,
-                           spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
-            stream->precedence());
-}
-
-TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Create control stream.
-  QuicStreamId receive_control_stream_id =
-      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-  absl::string_view stream_type(type, 1);
-  QuicStreamOffset offset = 0;
-  QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
-  offset += stream_type.length();
-  EXPECT_CALL(debug_visitor,
-              OnPeerControlStreamCreated(receive_control_stream_id));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(receive_control_stream_id,
-            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
-  // Send SETTINGS frame.
-  std::string serialized_settings = EncodeSettings({});
-  QuicStreamFrame data2(receive_control_stream_id, false, offset,
-                        serialized_settings);
-  offset += serialized_settings.length();
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
-  session_.OnStreamFrame(data2);
-
-  // PRIORITY_UPDATE frame for first request stream.
-  const QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
-  struct PriorityUpdateFrame priority_update1;
-  priority_update1.prioritized_element_type = REQUEST_STREAM;
-  priority_update1.prioritized_element_id = stream_id1;
-  priority_update1.priority_field_value = "u=2";
-  std::string serialized_priority_update1 =
-      SerializePriorityUpdateFrame(priority_update1);
-  QuicStreamFrame data3(receive_control_stream_id,
-                        /* fin = */ false, offset, serialized_priority_update1);
-  offset += serialized_priority_update1.size();
-
-  // PRIORITY_UPDATE frame arrives after stream creation.
-  TestStream* stream1 = session_.CreateIncomingStream(stream_id1);
-  EXPECT_EQ(QuicStream::kDefaultUrgency,
-            stream1->precedence().spdy3_priority());
-  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update1));
-  session_.OnStreamFrame(data3);
-  EXPECT_EQ(2u, stream1->precedence().spdy3_priority());
-
-  // PRIORITY_UPDATE frame for second request stream.
-  const QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
-  struct PriorityUpdateFrame priority_update2;
-  priority_update2.prioritized_element_type = REQUEST_STREAM;
-  priority_update2.prioritized_element_id = stream_id2;
-  priority_update2.priority_field_value = "u=2";
-  std::string serialized_priority_update2 =
-      SerializePriorityUpdateFrame(priority_update2);
-  QuicStreamFrame stream_frame3(receive_control_stream_id,
-                                /* fin = */ false, offset,
-                                serialized_priority_update2);
-
-  // PRIORITY_UPDATE frame arrives before stream creation,
-  // priority value is buffered.
-  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update2));
-  session_.OnStreamFrame(stream_frame3);
-  // Priority is applied upon stream construction.
-  TestStream* stream2 = session_.CreateIncomingStream(stream_id2);
-  EXPECT_EQ(2u, stream2->precedence().spdy3_priority());
-}
-
-TEST_P(QuicSpdySessionTestServer, SimplePendingStreamType) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  char input[] = {0x04,            // type
-                  'a', 'b', 'c'};  // data
-  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
-
-  // This is a server test with a client-initiated unidirectional stream.
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-
-  for (bool fin : {true, false}) {
-    QuicStreamFrame frame(stream_id, fin, /* offset = */ 0, payload);
-
-    // A STOP_SENDING frame is sent in response to the unknown stream type.
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .WillOnce(Invoke([stream_id](const QuicFrame& frame) {
-          EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
-
-          const QuicStopSendingFrame& stop_sending = frame.stop_sending_frame;
-          EXPECT_EQ(stream_id, stop_sending.stream_id);
-          EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR, stop_sending.error_code);
-          EXPECT_EQ(
-              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
-              stop_sending.ietf_error_code);
-
-          return ClearControlFrame(frame);
-        }));
-    session_.OnStreamFrame(frame);
-
-    PendingStream* pending =
-        QuicSessionPeer::GetPendingStream(&session_, stream_id);
-    if (fin) {
-      // Stream is closed if FIN is received.
-      EXPECT_FALSE(pending);
-    } else {
-      ASSERT_TRUE(pending);
-      // The pending stream must ignore read data.
-      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-    }
-
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-  }
-}
-
-TEST_P(QuicSpdySessionTestServer, SimplePendingStreamTypeOutOfOrderDelivery) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  char input[] = {0x04,            // type
-                  'a', 'b', 'c'};  // data
-  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
-
-  // This is a server test with a client-initiated unidirectional stream.
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-
-  for (bool fin : {true, false}) {
-    QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
-                           payload.substr(0, 1));
-    QuicStreamFrame frame2(stream_id, fin, /* offset = */ 1, payload.substr(1));
-
-    // Deliver frames out of order.
-    session_.OnStreamFrame(frame2);
-    // A STOP_SENDING frame is sent in response to the unknown stream type.
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
-    session_.OnStreamFrame(frame1);
-
-    PendingStream* pending =
-        QuicSessionPeer::GetPendingStream(&session_, stream_id);
-    if (fin) {
-      // Stream is closed if FIN is received.
-      EXPECT_FALSE(pending);
-    } else {
-      ASSERT_TRUE(pending);
-      // The pending stream must ignore read data.
-      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-    }
-
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-  }
-}
-
-TEST_P(QuicSpdySessionTestServer,
-       MultipleBytesPendingStreamTypeOutOfOrderDelivery) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  char input[] = {0x41, 0x00,      // type (256)
-                  'a', 'b', 'c'};  // data
-  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
-
-  // This is a server test with a client-initiated unidirectional stream.
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-
-  for (bool fin : {true, false}) {
-    QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
-                           payload.substr(0, 1));
-    QuicStreamFrame frame2(stream_id, /* fin = */ false, /* offset = */ 1,
-                           payload.substr(1, 1));
-    QuicStreamFrame frame3(stream_id, fin, /* offset = */ 2, payload.substr(2));
-
-    // Deliver frames out of order.
-    session_.OnStreamFrame(frame3);
-    // The first byte does not contain the entire type varint.
-    session_.OnStreamFrame(frame1);
-    // A STOP_SENDING frame is sent in response to the unknown stream type.
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
-    session_.OnStreamFrame(frame2);
-
-    PendingStream* pending =
-        QuicSessionPeer::GetPendingStream(&session_, stream_id);
-    if (fin) {
-      // Stream is closed if FIN is received.
-      EXPECT_FALSE(pending);
-    } else {
-      ASSERT_TRUE(pending);
-      // The pending stream must ignore read data.
-      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-    }
-
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-  }
-}
-
-TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  CompleteHandshake();
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Use an arbitrary stream id.
-  QuicStreamId stream_id =
-      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-
-  QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(stream_id,
-            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 512;
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42;
-  std::string data = EncodeSettings(settings);
-  QuicStreamFrame frame(stream_id, false, 1, absl::string_view(data));
-
-  QpackEncoder* qpack_encoder = session_.qpack_encoder();
-  QpackEncoderHeaderTable* header_table =
-      QpackEncoderPeer::header_table(qpack_encoder);
-
-  EXPECT_NE(512u, header_table->maximum_dynamic_table_capacity());
-  EXPECT_NE(5u, session_.max_outbound_header_list_size());
-  EXPECT_NE(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
-  session_.OnStreamFrame(frame);
-
-  EXPECT_EQ(512u, header_table->maximum_dynamic_table_capacity());
-  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-  EXPECT_EQ(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-}
-
-TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  // Use an arbitrary stream id.
-  QuicStreamId stream_id =
-      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-  SettingsFrame settings;
-  settings.values[10] = 2;
-  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  std::string data = EncodeSettings(settings);
-
-  QuicStreamFrame data1(stream_id, false, 1, absl::string_view(data));
-  QuicStreamFrame data2(stream_id, false, 0, absl::string_view(type, 1));
-
-  session_.OnStreamFrame(data1);
-  EXPECT_NE(5u, session_.max_outbound_header_list_size());
-  session_.OnStreamFrame(data2);
-  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-}
-
-// Regression test for https://crbug.com/1009551.
-TEST_P(QuicSpdySessionTestServer, StreamClosedWhileHeaderDecodingBlocked) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  TestStream* stream = session_.CreateIncomingStream(stream_id);
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string headers_payload = absl::HexStringToBytes("020080");
-  std::unique_ptr<char[]> headers_buffer;
-  QuicByteCount headers_frame_header_length =
-      HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
-                                               &headers_buffer);
-  absl::string_view headers_frame_header(headers_buffer.get(),
-                                         headers_frame_header_length);
-  std::string headers = absl::StrCat(headers_frame_header, headers_payload);
-  stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream->headers_decompressed());
-
-  // Stream is closed and destroyed.
-  CloseStream(stream_id);
-  session_.CleanUpClosedStreams();
-
-  // Dynamic table entry arrived on the decoder stream.
-  // The destroyed stream object must not be referenced.
-  session_.qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-}
-
-// Regression test for https://crbug.com/1011294.
-TEST_P(QuicSpdySessionTestServer, SessionDestroyedWhileHeaderDecodingBlocked) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  TestStream* stream = session_.CreateIncomingStream(stream_id);
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string headers_payload = absl::HexStringToBytes("020080");
-  std::unique_ptr<char[]> headers_buffer;
-  QuicByteCount headers_frame_header_length =
-      HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
-                                               &headers_buffer);
-  absl::string_view headers_frame_header(headers_buffer.get(),
-                                         headers_frame_header_length);
-  std::string headers = absl::StrCat(headers_frame_header, headers_payload);
-  stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream->headers_decompressed());
-
-  // |session_| gets destoyed.  That destroys QpackDecoder, a member of
-  // QuicSpdySession (derived class), which destroys QpackDecoderHeaderTable.
-  // Then |*stream|, owned by QuicSession (base class) get destroyed, which
-  // destroys QpackProgessiveDecoder, a registered Observer of
-  // QpackDecoderHeaderTable.  This must not cause a crash.
-}
-
-TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-
-  const QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
-  // Payload consists of two bytes.  The first byte is an unknown unidirectional
-  // stream type.  The second one would be the type of a push stream, but it
-  // must not be interpreted as stream type.
-  std::string payload = absl::HexStringToBytes("3f01");
-  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
-                        payload);
-
-  // A STOP_SENDING frame is sent in response to the unknown stream type.
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
-  session_.OnStreamFrame(frame);
-
-  // There are no active streams.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  // The pending stream is still around, because it did not receive a FIN.
-  PendingStream* pending =
-      QuicSessionPeer::GetPendingStream(&session_, stream_id);
-  ASSERT_TRUE(pending);
-
-  // The pending stream must ignore read data.
-  EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-
-  // If the stream frame is received again, it should be ignored.
-  session_.OnStreamFrame(frame);
-
-  // Receive RESET_STREAM.
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
-                               QUIC_STREAM_CANCELLED,
-                               /* bytes_written = */ payload.size());
-
-  session_.OnRstStream(rst_frame);
-
-  // The stream is closed.
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-
-  const QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
-  // Payload consists of two bytes.  The first byte is an unknown unidirectional
-  // stream type.  The second one would be the type of a push stream, but it
-  // must not be interpreted as stream type.
-  std::string payload = absl::HexStringToBytes("3f01");
-  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
-                        payload);
-
-  // A STOP_SENDING frame is sent in response to the unknown stream type.
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
-  session_.OnStreamFrame(frame);
-
-  // The pending stream is still around, because it did not receive a FIN.
-  PendingStream* pending =
-      QuicSessionPeer::GetPendingStream(&session_, stream_id);
-  EXPECT_TRUE(pending);
-
-  // The pending stream must ignore read data.
-  EXPECT_TRUE(pending->sequencer()->ignore_read_data());
-
-  // If the stream frame is received again, it should be ignored.
-  session_.OnStreamFrame(frame);
-
-  // Receive FIN.
-  session_.OnStreamFrame(QuicStreamFrame(stream_id, /* fin = */ true,
-                                         /* offset = */ payload.size(), ""));
-
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, ResetInMiddleOfStreamType) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  const QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
-  // Payload is the first byte of a two byte varint encoding.
-  std::string payload = absl::HexStringToBytes("40");
-  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
-                        payload);
-
-  session_.OnStreamFrame(frame);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-
-  // Receive RESET_STREAM.
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
-                               QUIC_STREAM_CANCELLED,
-                               /* bytes_written = */ payload.size());
-
-  session_.OnRstStream(rst_frame);
-
-  // The stream is closed.
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, FinInMiddleOfStreamType) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  const QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
-
-  // Payload is the first byte of a two byte varint encoding with a FIN.
-  std::string payload = absl::HexStringToBytes("40");
-  QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload);
-
-  session_.OnStreamFrame(frame);
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-}
-
-TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  QuicStreamId id1 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  char type1[] = {kControlStream};
-
-  QuicStreamFrame data1(id1, false, 0, absl::string_view(type1, 1));
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id1));
-  session_.OnStreamFrame(data1);
-  QuicStreamId id2 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
-  QuicStreamFrame data2(id2, false, 0, absl::string_view(type1, 1));
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id2)).Times(0);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
-                              "Control stream is received twice.", _));
-  EXPECT_QUIC_PEER_BUG(
-      session_.OnStreamFrame(data2),
-      "Received a duplicate Control stream: Closing connection.");
-
-  QuicStreamId id3 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 2);
-  char type2[]{kQpackEncoderStream};
-
-  QuicStreamFrame data3(id3, false, 0, absl::string_view(type2, 1));
-  EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id3));
-  session_.OnStreamFrame(data3);
-
-  QuicStreamId id4 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  QuicStreamFrame data4(id4, false, 0, absl::string_view(type2, 1));
-  EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id4)).Times(0);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
-                              "QPACK encoder stream is received twice.", _));
-  EXPECT_QUIC_PEER_BUG(
-      session_.OnStreamFrame(data4),
-      "Received a duplicate QPACK encoder stream: Closing connection.");
-
-  QuicStreamId id5 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 4);
-  char type3[]{kQpackDecoderStream};
-
-  QuicStreamFrame data5(id5, false, 0, absl::string_view(type3, 1));
-  EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id5));
-  session_.OnStreamFrame(data5);
-
-  QuicStreamId id6 =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5);
-  QuicStreamFrame data6(id6, false, 0, absl::string_view(type3, 1));
-  EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id6)).Times(0);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
-                              "QPACK decoder stream is received twice.", _));
-  EXPECT_QUIC_PEER_BUG(
-      session_.OnStreamFrame(data6),
-      "Received a duplicate QPACK decoder stream: Closing connection.");
-}
-
-TEST_P(QuicSpdySessionTestClient, EncoderStreamError) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  std::string data = absl::HexStringToBytes(
-      "02"    // Encoder stream.
-      "00");  // Duplicate entry 0, but no entries exist.
-
-  QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
-  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
-                  "Encoder stream error: Invalid relative index.", _));
-  session_.OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestClient, DecoderStreamError) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  std::string data = absl::HexStringToBytes(
-      "03"    // Decoder stream.
-      "00");  // Insert Count Increment with forbidden increment value of zero.
-
-  QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
-  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
-                      "Decoder stream error: Invalid increment value 0.", _));
-  session_.OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestClient, InvalidHttp3GoAway) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
-                              "GOAWAY with invalid stream ID", _));
-  QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  session_.OnHttp3GoAway(stream_id);
-}
-
-TEST_P(QuicSpdySessionTestClient, Http3GoAwayLargerIdThanBefore) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  EXPECT_FALSE(session_.goaway_received());
-  QuicStreamId stream_id1 =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
-  session_.OnHttp3GoAway(stream_id1);
-  EXPECT_TRUE(session_.goaway_received());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(
-          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
-          "GOAWAY received with ID 4 greater than previously received ID 0",
-          _));
-  QuicStreamId stream_id2 =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-  session_.OnHttp3GoAway(stream_id2);
-}
-
-TEST_P(QuicSpdySessionTestClient, CloseConnectionOnCancelPush) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Create control stream.
-  QuicStreamId receive_control_stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-  absl::string_view stream_type(type, 1);
-  QuicStreamOffset offset = 0;
-  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
-                        stream_type);
-  offset += stream_type.length();
-  EXPECT_CALL(debug_visitor,
-              OnPeerControlStreamCreated(receive_control_stream_id));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(receive_control_stream_id,
-            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
-  // First frame has to be SETTINGS.
-  std::string serialized_settings = EncodeSettings({});
-  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
-                        serialized_settings);
-  offset += serialized_settings.length();
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
-  session_.OnStreamFrame(data2);
-
-  std::string cancel_push_frame = absl::HexStringToBytes(
-      "03"    // CANCEL_PUSH
-      "01"    // length
-      "00");  // push ID
-  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
-                        cancel_push_frame);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
-                                            "CANCEL_PUSH frame received.", _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_,
-              SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
-                                        "CANCEL_PUSH frame received."));
-  session_.OnStreamFrame(data3);
-}
-
-TEST_P(QuicSpdySessionTestServer, OnSetting) {
-  CompleteHandshake();
-  if (VersionUsesHttp3(transport_version())) {
-    EXPECT_EQ(std::numeric_limits<size_t>::max(),
-              session_.max_outbound_header_list_size());
-    session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
-    EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-
-    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-        .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
-    QpackEncoder* qpack_encoder = session_.qpack_encoder();
-    EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-    session_.OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12);
-    EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
-
-    QpackEncoderHeaderTable* header_table =
-        QpackEncoderPeer::header_table(qpack_encoder);
-    EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
-    session_.OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37);
-    EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
-
-    return;
-  }
-
-  EXPECT_EQ(std::numeric_limits<size_t>::max(),
-            session_.max_outbound_header_list_size());
-  session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
-  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
-
-  spdy::HpackEncoder* hpack_encoder =
-      QuicSpdySessionPeer::GetSpdyFramer(&session_)->GetHpackEncoder();
-  EXPECT_EQ(4096u, hpack_encoder->CurrentHeaderTableSizeSetting());
-  session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 59);
-  EXPECT_EQ(59u, hpack_encoder->CurrentHeaderTableSizeSetting());
-}
-
-TEST_P(QuicSpdySessionTestServer, FineGrainedHpackErrorCodes) {
-  if (VersionUsesHttp3(transport_version())) {
-    // HPACK is not used in HTTP/3.
-    return;
-  }
-
-  QuicStreamId request_stream_id = 5;
-  session_.CreateIncomingStream(request_stream_id);
-
-  // Index 126 does not exist (static table has 61 entries and dynamic table is
-  // empty).
-  std::string headers_frame = absl::HexStringToBytes(
-      "000006"    // length
-      "01"        // type
-      "24"        // flags: PRIORITY | END_HEADERS
-      "00000005"  // stream_id
-      "00000000"  // stream dependency
-      "10"        // weight
-      "fe");      // payload: reference to index 126.
-  QuicStreamId headers_stream_id =
-      QuicUtils::GetHeadersStreamId(transport_version());
-  QuicStreamFrame data(headers_stream_id, false, 0, headers_frame);
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HPACK_INVALID_INDEX,
-                      "SPDY framing error: HPACK_INVALID_INDEX",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnStreamFrame(data);
-}
-
-TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  struct {
-    char type;
-    const char* error_details;
-  } kTestData[] = {
-      {kControlStream, "RESET_STREAM received for receive control stream"},
-      {kQpackEncoderStream, "RESET_STREAM received for QPACK receive stream"},
-      {kQpackDecoderStream, "RESET_STREAM received for QPACK receive stream"},
-  };
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
-    QuicStreamId stream_id =
-        GetNthClientInitiatedUnidirectionalStreamId(transport_version(), i + 1);
-    const QuicByteCount data_length = 1;
-    QuicStreamFrame data(stream_id, false, 0,
-                         absl::string_view(&kTestData[i].type, data_length));
-    session_.OnStreamFrame(data);
-
-    EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-                                              kTestData[i].error_details, _));
-
-    QuicRstStreamFrame rst(kInvalidControlFrameId, stream_id,
-                           QUIC_STREAM_CANCELLED, data_length);
-    session_.OnRstStream(rst);
-  }
-}
-
-TEST_P(QuicSpdySessionTestServer,
-       H3ControlStreamsLimitedByConnectionFlowControl) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  // Ensure connection level flow control blockage.
-  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
-  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-
-  QuicSendControlStream* send_control_stream =
-      QuicSpdySessionPeer::GetSendControlStream(&session_);
-  // Mark send_control stream write blocked.
-  session_.MarkConnectionLevelWriteBlocked(send_control_stream->id());
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalSendStream) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  QuicSendControlStream* control_stream =
-      QuicSpdySessionPeer::GetSendControlStream(&session_);
-  ASSERT_TRUE(control_stream);
-
-  QuicStopSendingFrame stop_sending_control_stream(
-      kInvalidControlFrameId, control_stream->id(), QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-                      "STOP_SENDING received for send control stream", _));
-  session_.OnStopSendingFrame(stop_sending_control_stream);
-
-  QpackSendStream* decoder_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
-  ASSERT_TRUE(decoder_stream);
-
-  QuicStopSendingFrame stop_sending_decoder_stream(
-      kInvalidControlFrameId, decoder_stream->id(), QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-                      "STOP_SENDING received for QPACK send stream", _));
-  session_.OnStopSendingFrame(stop_sending_decoder_stream);
-
-  QpackSendStream* encoder_stream =
-      QuicSpdySessionPeer::GetQpackEncoderSendStream(&session_);
-  ASSERT_TRUE(encoder_stream);
-
-  QuicStopSendingFrame stop_sending_encoder_stream(
-      kInvalidControlFrameId, encoder_stream->id(), QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-                      "STOP_SENDING received for QPACK send stream", _));
-  session_.OnStopSendingFrame(stop_sending_encoder_stream);
-}
-
-TEST_P(QuicSpdySessionTestServer, CloseConnectionOnCancelPush) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Create control stream.
-  QuicStreamId receive_control_stream_id =
-      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-  absl::string_view stream_type(type, 1);
-  QuicStreamOffset offset = 0;
-  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
-                        stream_type);
-  offset += stream_type.length();
-  EXPECT_CALL(debug_visitor,
-              OnPeerControlStreamCreated(receive_control_stream_id));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(receive_control_stream_id,
-            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
-  // First frame has to be SETTINGS.
-  std::string serialized_settings = EncodeSettings({});
-  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
-                        serialized_settings);
-  offset += serialized_settings.length();
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
-  session_.OnStreamFrame(data2);
-
-  std::string cancel_push_frame = absl::HexStringToBytes(
-      "03"    // CANCEL_PUSH
-      "01"    // length
-      "00");  // push ID
-  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
-                        cancel_push_frame);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
-                                            "CANCEL_PUSH frame received.", _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_,
-              SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
-                                        "CANCEL_PUSH frame received."));
-  session_.OnStreamFrame(data3);
-}
-
-TEST_P(QuicSpdySessionTestServer, Http3GoAwayWhenClosingConnection) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
-  CompleteHandshake();
-
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-
-  // Create stream by receiving some data (CreateIncomingStream() would not
-  // update the session's largest peer created stream ID).
-  const size_t headers_payload_length = 10;
-  std::unique_ptr<char[]> headers_buffer;
-  QuicByteCount headers_frame_header_length =
-      HttpEncoder::SerializeHeadersFrameHeader(headers_payload_length,
-                                               &headers_buffer);
-  absl::string_view headers_frame_header(headers_buffer.get(),
-                                         headers_frame_header_length);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_id, headers_payload_length));
-  session_.OnStreamFrame(
-      QuicStreamFrame(stream_id, false, 0, headers_frame_header));
-
-  EXPECT_EQ(stream_id, QuicSessionPeer::GetLargestPeerCreatedStreamId(
-                           &session_, /*unidirectional = */ false));
-
-  // Stream with stream_id is already received and potentially processed,
-  // therefore a GOAWAY frame is sent with the next stream ID.
-  EXPECT_CALL(debug_visitor,
-              OnGoAwayFrameSent(stream_id +
-                                QuicUtils::StreamIdDelta(transport_version())));
-
-  // Close connection.
-  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
-      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(QUIC_NO_ERROR, _, _))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::ReallySendConnectionClosePacket));
-  connection_->CloseConnection(
-      QUIC_NO_ERROR, "closing connection",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-TEST_P(QuicSpdySessionTestClient, DoNotSendInitialMaxPushIdIfNotSet) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  InSequence s;
-  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
-
-  CompleteHandshake();
-}
-
-TEST_P(QuicSpdySessionTestClient, ReceiveSpdySettingInHttp3) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  SettingsFrame frame;
-  frame.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
-  // https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-30#section-7.2.4.1
-  // specifies the presence of HTTP/2 setting as error.
-  frame.values[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 100;
-
-  CompleteHandshake();
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_RECEIVE_SPDY_SETTING, _, _));
-  session_.OnSettingsFrame(frame);
-}
-
-TEST_P(QuicSpdySessionTestClient, ReceiveAcceptChFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  // Create control stream.
-  QuicStreamId receive_control_stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  char type[] = {kControlStream};
-  absl::string_view stream_type(type, 1);
-  QuicStreamOffset offset = 0;
-  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
-                        stream_type);
-  offset += stream_type.length();
-  EXPECT_CALL(debug_visitor,
-              OnPeerControlStreamCreated(receive_control_stream_id));
-
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(receive_control_stream_id,
-            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
-  // First frame has to be SETTINGS.
-  std::string serialized_settings = EncodeSettings({});
-  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
-                        serialized_settings);
-  offset += serialized_settings.length();
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
-
-  session_.OnStreamFrame(data2);
-
-  // Receive ACCEPT_CH frame.
-  AcceptChFrame accept_ch;
-  accept_ch.entries.push_back({"foo", "bar"});
-  std::unique_ptr<char[]> buffer;
-  auto frame_length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
-  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
-                        absl::string_view(buffer.get(), frame_length));
-
-  EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(accept_ch));
-  EXPECT_CALL(session_, OnAcceptChFrame(accept_ch));
-
-  session_.OnStreamFrame(data3);
-}
-
-TEST_P(QuicSpdySessionTestClient, AcceptChViaAlps) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  std::string serialized_accept_ch_frame = absl::HexStringToBytes(
-      "4089"      // type (ACCEPT_CH)
-      "08"        // length
-      "03"        // length of origin
-      "666f6f"    // origin "foo"
-      "03"        // length of value
-      "626172");  // value "bar"
-
-  AcceptChFrame expected_accept_ch_frame{{{"foo", "bar"}}};
-  EXPECT_CALL(debug_visitor,
-              OnAcceptChFrameReceivedViaAlps(expected_accept_ch_frame));
-
-  auto error = session_.OnAlpsData(
-      reinterpret_cast<const uint8_t*>(serialized_accept_ch_frame.data()),
-      serialized_accept_ch_frame.size());
-  EXPECT_FALSE(error);
-}
-
-TEST_P(QuicSpdySessionTestClient, AlpsForbiddenFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  std::string forbidden_frame = absl::HexStringToBytes(
-      "00"        // type (DATA)
-      "03"        // length
-      "66666f");  // "foo"
-
-  auto error = session_.OnAlpsData(
-      reinterpret_cast<const uint8_t*>(forbidden_frame.data()),
-      forbidden_frame.size());
-  ASSERT_TRUE(error);
-  EXPECT_EQ("DATA frame forbidden", error.value());
-}
-
-TEST_P(QuicSpdySessionTestClient, AlpsIncompleteFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  std::string incomplete_frame = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "03");  // non-zero length but empty payload
-
-  auto error = session_.OnAlpsData(
-      reinterpret_cast<const uint8_t*>(incomplete_frame.data()),
-      incomplete_frame.size());
-  ASSERT_TRUE(error);
-  EXPECT_EQ("incomplete HTTP/3 frame", error.value());
-}
-
-// After receiving a SETTINGS frame via ALPS,
-// another SETTINGS frame is still allowed on control frame.
-TEST_P(QuicSpdySessionTestClient, SettingsViaAlpsThenOnControlStream) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  QpackEncoder* qpack_encoder = session_.qpack_encoder();
-  EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
-  EXPECT_EQ(0u, qpack_encoder->maximum_blocked_streams());
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-
-  std::string serialized_settings_frame1 = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "05"    // length
-      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-      "4400"  // 0x0400 = 1024
-      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
-      "20");  // 0x20 = 32
-
-  SettingsFrame expected_settings_frame1{
-      {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
-       {SETTINGS_QPACK_BLOCKED_STREAMS, 32}}};
-  EXPECT_CALL(debug_visitor,
-              OnSettingsFrameReceivedViaAlps(expected_settings_frame1));
-
-  auto error = session_.OnAlpsData(
-      reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
-      serialized_settings_frame1.size());
-  EXPECT_FALSE(error);
-
-  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
-  EXPECT_EQ(32u, qpack_encoder->maximum_blocked_streams());
-
-  const QuicStreamId control_stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(control_stream_id));
-
-  std::string stream_type = absl::HexStringToBytes("00");
-  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
-                                         /* offset = */ 0, stream_type));
-
-  // SETTINGS_QPACK_MAX_TABLE_CAPACITY, if advertised again, MUST have identical
-  // value.
-  // SETTINGS_QPACK_BLOCKED_STREAMS is a limit.  Limits MUST NOT be reduced, but
-  // increasing is okay.
-  SettingsFrame expected_settings_frame2{
-      {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
-       {SETTINGS_QPACK_BLOCKED_STREAMS, 48}}};
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(expected_settings_frame2));
-  std::string serialized_settings_frame2 = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "05"    // length
-      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-      "4400"  // 0x0400 = 1024
-      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
-      "30");  // 0x30 = 48
-  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
-                                         /* offset = */ stream_type.length(),
-                                         serialized_settings_frame2));
-
-  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
-  EXPECT_EQ(48u, qpack_encoder->maximum_blocked_streams());
-}
-
-// A SETTINGS frame received via ALPS and another one on the control stream
-// cannot have conflicting values.
-TEST_P(QuicSpdySessionTestClient,
-       SettingsViaAlpsConflictsSettingsViaControlStream) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  QpackEncoder* qpack_encoder = session_.qpack_encoder();
-  EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
-
-  std::string serialized_settings_frame1 = absl::HexStringToBytes(
-      "04"      // type (SETTINGS)
-      "03"      // length
-      "01"      // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-      "4400");  // 0x0400 = 1024
-
-  auto error = session_.OnAlpsData(
-      reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
-      serialized_settings_frame1.size());
-  EXPECT_FALSE(error);
-
-  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
-
-  const QuicStreamId control_stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
-
-  std::string stream_type = absl::HexStringToBytes("00");
-  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
-                                         /* offset = */ 0, stream_type));
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
-                      "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: "
-                      "32 while current value is: 1024",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  std::string serialized_settings_frame2 = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "02"    // length
-      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
-      "20");  // 0x20 = 32
-  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
-                                         /* offset = */ stream_type.length(),
-                                         serialized_settings_frame2));
-}
-
-TEST_P(QuicSpdySessionTestClient, AlpsTwoSettingsFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  std::string banned_frame = absl::HexStringToBytes(
-      "04"    // type (SETTINGS)
-      "00"    // length
-      "04"    // type (SETTINGS)
-      "00");  // length
-
-  auto error =
-      session_.OnAlpsData(reinterpret_cast<const uint8_t*>(banned_frame.data()),
-                          banned_frame.size());
-  ASSERT_TRUE(error);
-  EXPECT_EQ("multiple SETTINGS frames", error.value());
-}
-
-void QuicSpdySessionTestBase::TestHttpDatagramSetting(
-    HttpDatagramSupport local_support, HttpDatagramSupport remote_support,
-    HttpDatagramSupport expected_support, bool expected_datagram_supported) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(local_support);
-  // HTTP/3 datagrams aren't supported before SETTINGS are received.
-  EXPECT_FALSE(session_.SupportsH3Datagram());
-  EXPECT_EQ(session_.http_datagram_support(), HttpDatagramSupport::kNone);
-  // Receive SETTINGS.
-  SettingsFrame settings;
-  switch (remote_support) {
-    case HttpDatagramSupport::kNone:
-      break;
-    case HttpDatagramSupport::kDraft00:
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
-      break;
-    case HttpDatagramSupport::kDraft04:
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-      break;
-    case HttpDatagramSupport::kDraft00And04:
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
-      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-      break;
-  }
-  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
-  QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_.set_debug_visitor(&debug_visitor);
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
-  session_.OnStreamFrame(frame);
-  EXPECT_EQ(session_.http_datagram_support(), expected_support);
-  EXPECT_EQ(session_.SupportsH3Datagram(), expected_datagram_supported);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00,
-      /*remote_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00,
-      /*remote_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_support=*/HttpDatagramSupport::kNone,
-      /*expected_datagram_supported=*/false);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00And04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00,
-      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
-      /*expected_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_support=*/HttpDatagramSupport::kNone,
-      /*expected_datagram_supported=*/false);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft04,
-      /*remote_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00And04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote00) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00And04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_support=*/HttpDatagramSupport::kDraft00,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00And04,
-      /*remote_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient,
-       HttpDatagramSettingLocal00And04Remote00And04) {
-  TestHttpDatagramSetting(
-      /*local_support=*/HttpDatagramSupport::kDraft00And04,
-      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
-      /*expected_support=*/HttpDatagramSupport::kDraft04,
-      /*expected_datagram_supported=*/true);
-}
-
-TEST_P(QuicSpdySessionTestClient, WebTransportSetting) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  EXPECT_FALSE(session_.SupportsWebTransport());
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  // Note that this does not actually fill out correct settings because the
-  // settings are filled in at the construction time.
-  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
-  session_.set_debug_visitor(&debug_visitor);
-  CompleteHandshake();
-
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(_));
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
-  ReceiveWebTransportSettings();
-  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-  EXPECT_TRUE(session_.SupportsWebTransport());
-}
-
-TEST_P(QuicSpdySessionTestClient, WebTransportSettingSetToZero) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  EXPECT_FALSE(session_.SupportsWebTransport());
-
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  // Note that this does not actually fill out correct settings because the
-  // settings are filled in at the construction time.
-  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
-  session_.set_debug_visitor(&debug_visitor);
-  CompleteHandshake();
-
-  SettingsFrame server_settings;
-  server_settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-  server_settings.values[SETTINGS_WEBTRANS_DRAFT00] = 0;
-  std::string data =
-      std::string(1, kControlStream) + EncodeSettings(server_settings);
-  QuicStreamId stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
-  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
-  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(server_settings));
-  session_.OnStreamFrame(frame);
-  EXPECT_FALSE(session_.SupportsWebTransport());
-}
-
-TEST_P(QuicSpdySessionTestServer, WebTransportSetting) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  EXPECT_FALSE(session_.SupportsWebTransport());
-  EXPECT_FALSE(session_.ShouldProcessIncomingRequests());
-
-  CompleteHandshake();
-
-  ReceiveWebTransportSettings();
-  EXPECT_TRUE(session_.SupportsWebTransport());
-  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-}
-
-TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreams) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  CompleteHandshake();
-  QuicStreamId session_id =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-
-  QuicStreamId data_stream_id =
-      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4);
-  ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
-
-  ReceiveWebTransportSettings();
-
-  ReceiveWebTransportSession(session_id);
-  WebTransportHttp3* web_transport =
-      session_.GetWebTransportSession(session_id);
-  ASSERT_TRUE(web_transport != nullptr);
-
-  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
-  EXPECT_CALL(
-      *connection_,
-      OnStreamReset(data_stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
-  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
-}
-
-TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsLimit) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  CompleteHandshake();
-  QuicStreamId session_id =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-
-  const int streams_to_send = kMaxUnassociatedWebTransportStreams + 4;
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(
-                  _, QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED))
-      .Times(4);
-  for (int i = 0; i < streams_to_send; i++) {
-    QuicStreamId data_stream_id =
-        GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4 + i);
-    ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
-  }
-
-  ReceiveWebTransportSettings();
-
-  ReceiveWebTransportSession(session_id);
-  WebTransportHttp3* web_transport =
-      session_.GetWebTransportSession(session_id);
-  ASSERT_TRUE(web_transport != nullptr);
-
-  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(),
-            kMaxUnassociatedWebTransportStreams);
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(_, _))
-      .Times(kMaxUnassociatedWebTransportStreams + 1);
-  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
-}
-
-TEST_P(QuicSpdySessionTestServer, ResetOutgoingWebTransportStreams) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  CompleteHandshake();
-  QuicStreamId session_id =
-      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
-
-  ReceiveWebTransportSettings();
-  ReceiveWebTransportSession(session_id);
-  WebTransportHttp3* web_transport =
-      session_.GetWebTransportSession(session_id);
-  ASSERT_TRUE(web_transport != nullptr);
-
-  session_.set_writev_consumes_all_data(true);
-  EXPECT_TRUE(web_transport->CanOpenNextOutgoingUnidirectionalStream());
-  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
-  WebTransportStream* stream =
-      web_transport->OpenOutgoingUnidirectionalStream();
-  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
-  ASSERT_TRUE(stream != nullptr);
-  QuicStreamId stream_id = stream->GetStreamId();
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
-  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
-  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
-}
-
-TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_.set_supports_webtransport(true);
-
-  EXPECT_FALSE(session_.SupportsWebTransport());
-  CompleteHandshake();
-
-  SettingsFrame settings;
-  settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
-  settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
-  // No SETTINGS_ENABLE_CONNECT_PROTOCOL here.
-  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
-  QuicStreamId control_stream_id =
-      session_.perspective() == Perspective::IS_SERVER
-          ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
-          : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
-  session_.OnStreamFrame(frame);
-
-  EXPECT_TRUE(session_.SupportsWebTransport());
-}
-
-// Regression bug for b/208997000.
-TEST_P(QuicSpdySessionTestClient, LimitEncoderDynamicTableSize) {
-  if (version().UsesHttp3()) {
-    return;
-  }
-  CompleteHandshake();
-
-  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
-  TestHeadersStream* headers_stream =
-      new StrictMock<TestHeadersStream>(&session_);
-  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
-  session_.MarkConnectionLevelWriteBlocked(headers_stream->id());
-
-  // Peer sends very large value.
-  session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 1024 * 1024 * 1024);
-
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
-  SpdyHeaderBlock headers;
-  headers[":method"] = "GET";  // entry with index 2 in HPACK static table
-  stream->WriteHeaders(std::move(headers), /* fin = */ true, nullptr);
-
-  EXPECT_TRUE(headers_stream->HasBufferedData());
-  QuicStreamSendBuffer& send_buffer =
-      QuicStreamPeer::SendBuffer(headers_stream);
-  ASSERT_EQ(1u, send_buffer.size());
-
-  const quiche::QuicheMemSlice& slice =
-      QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
-  absl::string_view stream_data(slice.data(), slice.length());
-
-  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
-    EXPECT_EQ(absl::HexStringToBytes(
-                  "000009"  // frame length
-                  "01"      // frame type HEADERS
-                  "25"),    // flags END_STREAM | END_HEADERS | PRIORITY
-              stream_data.substr(0, 5));
-    stream_data.remove_prefix(5);
-  } else {
-    EXPECT_EQ(absl::HexStringToBytes(
-                  "00000c"  // frame length
-                  "01"      // frame type HEADERS
-                  "25"),    // flags END_STREAM | END_HEADERS | PRIORITY
-              stream_data.substr(0, 5));
-    stream_data.remove_prefix(5);
-  }
-
-  // Ignore stream ID as it might differ between QUIC versions.
-  stream_data.remove_prefix(4);
-
-  // Ignore stream dependency and weight.
-  EXPECT_EQ(absl::HexStringToBytes("00000000"  // stream dependency
-                                   "92"),      // stream weight
-            stream_data.substr(0, 5));
-  stream_data.remove_prefix(5);
-
-  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
-    EXPECT_EQ(absl::HexStringToBytes(
-                  "3fe17f"  // Dynamic Table Size Update to 16384
-                  "82"),    // Indexed Header Field Representation with index 2
-              stream_data);
-  } else {
-    EXPECT_EQ(
-        absl::HexStringToBytes(
-            "3fe1ffffff03"  // Dynamic Table Size Update to 1024 * 1024 * 1024
-            "82"),          // Indexed Header Field Representation with index 2
-        stream_data);
-  }
-}
-
-class QuicSpdySessionTestServerNoExtendedConnect
-    : public QuicSpdySessionTestBase {
- public:
-  QuicSpdySessionTestServerNoExtendedConnect()
-      : QuicSpdySessionTestBase(Perspective::IS_SERVER, false) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServerNoExtendedConnect,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-// Tests that receiving SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 doesn't enable
-// server session to support extended CONNECT.
-TEST_P(QuicSpdySessionTestServerNoExtendedConnect,
-       WebTransportSettingNoEffect) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-
-  EXPECT_FALSE(session_.SupportsWebTransport());
-  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-
-  CompleteHandshake();
-
-  ReceiveWebTransportSettings();
-  EXPECT_FALSE(session_.allow_extended_connect());
-  EXPECT_FALSE(session_.SupportsWebTransport());
-  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-}
-
-TEST_P(QuicSpdySessionTestServerNoExtendedConnect, BadExtendedConnectSetting) {
-  if (!version().UsesHttp3()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
-  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
-
-  EXPECT_FALSE(session_.SupportsWebTransport());
-  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
-
-  CompleteHandshake();
-
-  // ENABLE_CONNECT_PROTOCOL setting value has to be 1 or 0;
-  SettingsFrame settings;
-  settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 2;
-  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
-  QuicStreamId control_stream_id =
-      session_.perspective() == Perspective::IS_SERVER
-          ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
-          : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
-  QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_INVALID_SETTING_VALUE, _, _));
-  EXPECT_QUIC_PEER_BUG(
-      session_.OnStreamFrame(frame),
-      "Received SETTINGS_ENABLE_CONNECT_PROTOCOL with invalid value");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
deleted file mode 100644
index e7080a3..0000000
--- a/quic/core/http/quic_spdy_stream.cc
+++ /dev/null
@@ -1,1942 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_stream.h"
-
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "http2/http2_constants.h"
-#include "quic/core/http/capsule.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_mem_slice_storage.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyPriority;
-
-namespace quic {
-
-// Visitor of HttpDecoder that passes data frame to QuicSpdyStream and closes
-// the connection on unexpected frames.
-class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor {
- public:
-  explicit HttpDecoderVisitor(QuicSpdyStream* stream) : stream_(stream) {}
-  HttpDecoderVisitor(const HttpDecoderVisitor&) = delete;
-  HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
-
-  void OnError(HttpDecoder* decoder) override {
-    stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
-  }
-
-  bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("Max Push Id");
-    return false;
-  }
-
-  bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("Goaway");
-    return false;
-  }
-
-  bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
-    CloseConnectionOnWrongFrame("Settings");
-    return false;
-  }
-
-  bool OnSettingsFrame(const SettingsFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("Settings");
-    return false;
-  }
-
-  bool OnDataFrameStart(QuicByteCount header_length,
-                        QuicByteCount payload_length) override {
-    return stream_->OnDataFrameStart(header_length, payload_length);
-  }
-
-  bool OnDataFramePayload(absl::string_view payload) override {
-    QUICHE_DCHECK(!payload.empty());
-    return stream_->OnDataFramePayload(payload);
-  }
-
-  bool OnDataFrameEnd() override { return stream_->OnDataFrameEnd(); }
-
-  bool OnHeadersFrameStart(QuicByteCount header_length,
-                           QuicByteCount payload_length) override {
-    if (!VersionUsesHttp3(stream_->transport_version())) {
-      CloseConnectionOnWrongFrame("Headers");
-      return false;
-    }
-    return stream_->OnHeadersFrameStart(header_length, payload_length);
-  }
-
-  bool OnHeadersFramePayload(absl::string_view payload) override {
-    QUICHE_DCHECK(!payload.empty());
-    if (!VersionUsesHttp3(stream_->transport_version())) {
-      CloseConnectionOnWrongFrame("Headers");
-      return false;
-    }
-    return stream_->OnHeadersFramePayload(payload);
-  }
-
-  bool OnHeadersFrameEnd() override {
-    if (!VersionUsesHttp3(stream_->transport_version())) {
-      CloseConnectionOnWrongFrame("Headers");
-      return false;
-    }
-    return stream_->OnHeadersFrameEnd();
-  }
-
-  bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
-    CloseConnectionOnWrongFrame("Priority update");
-    return false;
-  }
-
-  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("Priority update");
-    return false;
-  }
-
-  bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
-    CloseConnectionOnWrongFrame("ACCEPT_CH");
-    return false;
-  }
-
-  bool OnAcceptChFrame(const AcceptChFrame& /*frame*/) override {
-    CloseConnectionOnWrongFrame("ACCEPT_CH");
-    return false;
-  }
-
-  void OnWebTransportStreamFrameType(
-      QuicByteCount header_length, WebTransportSessionId session_id) override {
-    stream_->OnWebTransportStreamFrameType(header_length, session_id);
-  }
-
-  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
-                           QuicByteCount payload_length) override {
-    return stream_->OnUnknownFrameStart(frame_type, header_length,
-                                        payload_length);
-  }
-
-  bool OnUnknownFramePayload(absl::string_view payload) override {
-    return stream_->OnUnknownFramePayload(payload);
-  }
-
-  bool OnUnknownFrameEnd() override { return stream_->OnUnknownFrameEnd(); }
-
- private:
-  void CloseConnectionOnWrongFrame(absl::string_view frame_type) {
-    stream_->OnUnrecoverableError(
-        QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM,
-        absl::StrCat(frame_type, " frame received on data stream"));
-  }
-
-  QuicSpdyStream* stream_;
-};
-
-#define ENDPOINT                                                   \
-  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
-                                                      : "Client:"  \
-                                                        " ")
-
-namespace {
-HttpDecoder::Options HttpDecoderOptionsForBidiStream(
-    QuicSpdySession* spdy_session) {
-  HttpDecoder::Options options;
-  options.allow_web_transport_stream =
-      spdy_session->WillNegotiateWebTransport();
-  return options;
-}
-}  // namespace
-
-QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
-                               StreamType type)
-    : QuicStream(id, spdy_session, /*is_static=*/false, type),
-      spdy_session_(spdy_session),
-      on_body_available_called_because_sequencer_is_closed_(false),
-      visitor_(nullptr),
-      blocked_on_decoding_headers_(false),
-      headers_decompressed_(false),
-      header_list_size_limit_exceeded_(false),
-      headers_payload_length_(0),
-      trailers_decompressed_(false),
-      trailers_consumed_(false),
-      qpack_decoded_headers_accumulator_reset_reason_(
-          QpackDecodedHeadersAccumulatorResetReason::kUnSet),
-      http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
-      decoder_(http_decoder_visitor_.get(),
-               HttpDecoderOptionsForBidiStream(spdy_session)),
-      sequencer_offset_(0),
-      is_decoder_processing_input_(false),
-      ack_listener_(nullptr),
-      last_sent_urgency_(kDefaultUrgency),
-      datagram_next_available_context_id_(spdy_session->perspective() ==
-                                                  Perspective::IS_SERVER
-                                              ? kFirstDatagramContextIdServer
-                                              : kFirstDatagramContextIdClient) {
-  QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
-  QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
-  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
-  QUICHE_DCHECK_EQ(0u, sequencer()->NumBytesConsumed());
-  // If headers are sent on the headers stream, then do not receive any
-  // callbacks from the sequencer until headers are complete.
-  if (!VersionUsesHttp3(transport_version())) {
-    sequencer()->SetBlockedUntilFlush();
-  }
-
-  if (VersionUsesHttp3(transport_version())) {
-    sequencer()->set_level_triggered(true);
-  }
-
-  spdy_session_->OnStreamCreated(this);
-}
-
-QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
-                               QuicSpdySession* spdy_session)
-    : QuicStream(pending, spdy_session, /*is_static=*/false),
-      spdy_session_(spdy_session),
-      on_body_available_called_because_sequencer_is_closed_(false),
-      visitor_(nullptr),
-      blocked_on_decoding_headers_(false),
-      headers_decompressed_(false),
-      header_list_size_limit_exceeded_(false),
-      headers_payload_length_(0),
-      trailers_decompressed_(false),
-      trailers_consumed_(false),
-      qpack_decoded_headers_accumulator_reset_reason_(
-          QpackDecodedHeadersAccumulatorResetReason::kUnSet),
-      http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
-      decoder_(http_decoder_visitor_.get()),
-      sequencer_offset_(sequencer()->NumBytesConsumed()),
-      is_decoder_processing_input_(false),
-      ack_listener_(nullptr),
-      last_sent_urgency_(kDefaultUrgency) {
-  QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
-  QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
-  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id()));
-  // If headers are sent on the headers stream, then do not receive any
-  // callbacks from the sequencer until headers are complete.
-  if (!VersionUsesHttp3(transport_version())) {
-    sequencer()->SetBlockedUntilFlush();
-  }
-
-  if (VersionUsesHttp3(transport_version())) {
-    sequencer()->set_level_triggered(true);
-  }
-
-  spdy_session_->OnStreamCreated(this);
-}
-
-QuicSpdyStream::~QuicSpdyStream() {}
-
-bool QuicSpdyStream::ShouldUseDatagramContexts() const {
-  return spdy_session_->SupportsH3Datagram() &&
-         spdy_session_->http_datagram_support() !=
-             HttpDatagramSupport::kDraft00 &&
-         use_datagram_contexts_;
-}
-
-size_t QuicSpdyStream::WriteHeaders(
-    SpdyHeaderBlock header_block, bool fin,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  if (!AssertNotWebTransportDataStream("writing headers")) {
-    return 0;
-  }
-
-  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
-  // Send stream type for server push stream
-  if (VersionUsesHttp3(transport_version()) && type() == WRITE_UNIDIRECTIONAL &&
-      send_buffer().stream_offset() == 0) {
-    char data[sizeof(kServerPushStream)];
-    QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
-    writer.WriteVarInt62(kServerPushStream);
-
-    // Similar to frame headers, stream type byte shouldn't be exposed to upper
-    // layer applications.
-    unacked_frame_headers_offsets_.Add(0, writer.length());
-
-    QUIC_LOG(INFO) << ENDPOINT << "Stream " << id()
-                   << " is writing type as server push";
-    WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
-                      nullptr);
-  }
-
-  MaybeProcessSentWebTransportHeaders(header_block);
-
-  if (ShouldUseDatagramContexts()) {
-    // RegisterHttp3DatagramRegistrationVisitor caller wishes to use contexts,
-    // inform the peer.
-    header_block["sec-use-datagram-contexts"] = "?1";
-  }
-
-  if (web_transport_ != nullptr &&
-      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
-      spdy_session_->perspective() == Perspective::IS_SERVER) {
-    header_block["sec-webtransport-http3-draft"] = "draft02";
-  }
-
-  size_t bytes_written =
-      WriteHeadersImpl(std::move(header_block), fin, std::move(ack_listener));
-  if (!VersionUsesHttp3(transport_version()) && fin) {
-    // If HEADERS are sent on the headers stream, then |fin_sent_| needs to be
-    // set and write side needs to be closed without actually sending a FIN on
-    // this stream.
-    // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
-    SetFinSent();
-    CloseWriteSide();
-  }
-
-  if (web_transport_ != nullptr &&
-      session()->perspective() == Perspective::IS_CLIENT) {
-    // This will send a capsule and therefore needs to happen after headers have
-    // been sent.
-    RegisterHttp3DatagramContextId(
-        web_transport_->context_id(), DatagramFormatType::WEBTRANSPORT,
-        /*format_additional_data=*/absl::string_view(), web_transport_.get());
-  }
-
-  return bytes_written;
-}
-
-void QuicSpdyStream::WriteOrBufferBody(absl::string_view data, bool fin) {
-  if (!AssertNotWebTransportDataStream("writing body data")) {
-    return;
-  }
-  if (!VersionUsesHttp3(transport_version()) || data.length() == 0) {
-    WriteOrBufferData(data, fin, nullptr);
-    return;
-  }
-  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
-
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnDataFrameSent(id(), data.length());
-  }
-
-  const bool success =
-      WriteDataFrameHeader(data.length(), /*force_write=*/true);
-  QUICHE_DCHECK(success);
-
-  // Write body.
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
-                  << " is writing DATA frame payload of length "
-                  << data.length() << " with fin " << fin;
-  WriteOrBufferData(data, fin, nullptr);
-}
-
-size_t QuicSpdyStream::WriteTrailers(
-    SpdyHeaderBlock trailer_block,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  if (fin_sent()) {
-    QUIC_BUG(quic_bug_10410_1)
-        << "Trailers cannot be sent after a FIN, on stream " << id();
-    return 0;
-  }
-
-  if (!VersionUsesHttp3(transport_version())) {
-    // The header block must contain the final offset for this stream, as the
-    // trailers may be processed out of order at the peer.
-    const QuicStreamOffset final_offset =
-        stream_bytes_written() + BufferedDataBytes();
-    QUIC_DLOG(INFO) << ENDPOINT << "Inserting trailer: ("
-                    << kFinalOffsetHeaderKey << ", " << final_offset << ")";
-    trailer_block.insert(
-        std::make_pair(kFinalOffsetHeaderKey, absl::StrCat(final_offset)));
-  }
-
-  // Write the trailing headers with a FIN, and close stream for writing:
-  // trailers are the last thing to be sent on a stream.
-  const bool kFin = true;
-  size_t bytes_written =
-      WriteHeadersImpl(std::move(trailer_block), kFin, std::move(ack_listener));
-
-  // If trailers are sent on the headers stream, then |fin_sent_| needs to be
-  // set without actually sending a FIN on this stream.
-  if (!VersionUsesHttp3(transport_version())) {
-    SetFinSent();
-
-    // Also, write side of this stream needs to be closed.  However, only do
-    // this if there is no more buffered data, otherwise it will never be sent.
-    if (BufferedDataBytes() == 0) {
-      CloseWriteSide();
-    }
-  }
-
-  return bytes_written;
-}
-
-QuicConsumedData QuicSpdyStream::WritevBody(const struct iovec* iov, int count,
-                                            bool fin) {
-  quiche::QuicheMemSliceStorage storage(
-      iov, count,
-      session()->connection()->helper()->GetStreamSendBufferAllocator(),
-      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size));
-  return WriteBodySlices(storage.ToSpan(), fin);
-}
-
-bool QuicSpdyStream::WriteDataFrameHeader(QuicByteCount data_length,
-                                          bool force_write) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  QUICHE_DCHECK_GT(data_length, 0u);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      data_length,
-      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
-  const bool can_write = CanWriteNewDataAfterData(header.size());
-  if (!can_write && !force_write) {
-    return false;
-  }
-
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnDataFrameSent(id(), data_length);
-  }
-
-  unacked_frame_headers_offsets_.Add(
-      send_buffer().stream_offset(),
-      send_buffer().stream_offset() + header.size());
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
-                  << " is writing DATA frame header of length "
-                  << header.size();
-  if (can_write) {
-    // Save one copy and allocation if send buffer can accomodate the header.
-    quiche::QuicheMemSlice header_slice(std::move(header));
-    WriteMemSlices(absl::MakeSpan(&header_slice, 1), false);
-  } else {
-    QUICHE_DCHECK(force_write);
-    WriteOrBufferData(header.AsStringView(), false, nullptr);
-  }
-  return true;
-}
-
-QuicConsumedData QuicSpdyStream::WriteBodySlices(
-    absl::Span<quiche::QuicheMemSlice> slices, bool fin) {
-  if (!VersionUsesHttp3(transport_version()) || slices.empty()) {
-    return WriteMemSlices(slices, fin);
-  }
-
-  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
-  const QuicByteCount data_size = MemSliceSpanTotalSize(slices);
-  if (!WriteDataFrameHeader(data_size, /*force_write=*/false)) {
-    return {0, false};
-  }
-
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
-                  << " is writing DATA frame payload of length " << data_size;
-  return WriteMemSlices(slices, fin);
-}
-
-size_t QuicSpdyStream::Readv(const struct iovec* iov, size_t iov_len) {
-  QUICHE_DCHECK(FinishedReadingHeaders());
-  if (!VersionUsesHttp3(transport_version())) {
-    return sequencer()->Readv(iov, iov_len);
-  }
-  size_t bytes_read = 0;
-  sequencer()->MarkConsumed(body_manager_.ReadBody(iov, iov_len, &bytes_read));
-
-  return bytes_read;
-}
-
-int QuicSpdyStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
-  QUICHE_DCHECK(FinishedReadingHeaders());
-  if (!VersionUsesHttp3(transport_version())) {
-    return sequencer()->GetReadableRegions(iov, iov_len);
-  }
-  return body_manager_.PeekBody(iov, iov_len);
-}
-
-void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
-  QUICHE_DCHECK(FinishedReadingHeaders());
-  if (!VersionUsesHttp3(transport_version())) {
-    sequencer()->MarkConsumed(num_bytes);
-    return;
-  }
-
-  sequencer()->MarkConsumed(body_manager_.OnBodyConsumed(num_bytes));
-}
-
-bool QuicSpdyStream::IsDoneReading() const {
-  bool done_reading_headers = FinishedReadingHeaders();
-  bool done_reading_body = sequencer()->IsClosed();
-  bool done_reading_trailers = FinishedReadingTrailers();
-  return done_reading_headers && done_reading_body && done_reading_trailers;
-}
-
-bool QuicSpdyStream::HasBytesToRead() const {
-  if (!VersionUsesHttp3(transport_version())) {
-    return sequencer()->HasBytesToRead();
-  }
-  return body_manager_.HasBytesToRead();
-}
-
-void QuicSpdyStream::MarkTrailersConsumed() { trailers_consumed_ = true; }
-
-uint64_t QuicSpdyStream::total_body_bytes_read() const {
-  if (VersionUsesHttp3(transport_version())) {
-    return body_manager_.total_body_bytes_received();
-  }
-  return sequencer()->NumBytesConsumed();
-}
-
-void QuicSpdyStream::ConsumeHeaderList() {
-  header_list_.Clear();
-
-  if (!FinishedReadingHeaders()) {
-    return;
-  }
-
-  if (!VersionUsesHttp3(transport_version())) {
-    sequencer()->SetUnblocked();
-    return;
-  }
-
-  if (body_manager_.HasBytesToRead()) {
-    HandleBodyAvailable();
-    return;
-  }
-
-  if (sequencer()->IsClosed() &&
-      !on_body_available_called_because_sequencer_is_closed_) {
-    on_body_available_called_because_sequencer_is_closed_ = true;
-    HandleBodyAvailable();
-  }
-}
-
-void QuicSpdyStream::OnStreamHeadersPriority(
-    const spdy::SpdyStreamPrecedence& precedence) {
-  QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
-                   session()->connection()->perspective());
-  SetPriority(precedence);
-}
-
-void QuicSpdyStream::OnStreamHeaderList(bool fin, size_t frame_len,
-                                        const QuicHeaderList& header_list) {
-  if (!spdy_session()->user_agent_id().has_value()) {
-    std::string uaid;
-    for (const auto& kv : header_list) {
-      if (quiche::QuicheTextUtils::ToLower(kv.first) == kUserAgentHeaderName) {
-        uaid = kv.second;
-        break;
-      }
-    }
-    spdy_session()->SetUserAgentId(std::move(uaid));
-  }
-
-  // TODO(b/134706391): remove |fin| argument.
-  // When using Google QUIC, an empty header list indicates that the size limit
-  // has been exceeded.
-  // When using IETF QUIC, there is an explicit signal from
-  // QpackDecodedHeadersAccumulator.
-  if ((VersionUsesHttp3(transport_version()) &&
-       header_list_size_limit_exceeded_) ||
-      (!VersionUsesHttp3(transport_version()) && header_list.empty())) {
-    OnHeadersTooLarge();
-    if (IsDoneReading()) {
-      return;
-    }
-  }
-  if (!headers_decompressed_) {
-    OnInitialHeadersComplete(fin, frame_len, header_list);
-  } else {
-    OnTrailingHeadersComplete(fin, frame_len, header_list);
-  }
-}
-
-void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
-                                      bool header_list_size_limit_exceeded) {
-  header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
-  qpack_decoded_headers_accumulator_.reset();
-  qpack_decoded_headers_accumulator_reset_reason_ =
-      QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeadersDecoded;
-
-  QuicSpdySession::LogHeaderCompressionRatioHistogram(
-      /* using_qpack = */ true,
-      /* is_sent = */ false, headers.compressed_header_bytes(),
-      headers.uncompressed_header_bytes());
-
-  const QuicStreamId promised_stream_id = spdy_session()->promised_stream_id();
-  Http3DebugVisitor* const debug_visitor = spdy_session()->debug_visitor();
-  if (promised_stream_id ==
-      QuicUtils::GetInvalidStreamId(transport_version())) {
-    if (debug_visitor) {
-      debug_visitor->OnHeadersDecoded(id(), headers);
-    }
-
-    OnStreamHeaderList(/* fin = */ false, headers_payload_length_, headers);
-  } else {
-    spdy_session_->OnHeaderList(headers);
-  }
-
-  if (blocked_on_decoding_headers_) {
-    blocked_on_decoding_headers_ = false;
-    // Continue decoding HTTP/3 frames.
-    OnDataAvailable();
-  }
-}
-
-void QuicSpdyStream::OnHeaderDecodingError(QuicErrorCode error_code,
-                                           absl::string_view error_message) {
-  qpack_decoded_headers_accumulator_.reset();
-  qpack_decoded_headers_accumulator_reset_reason_ =
-      QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeaderDecodingError;
-
-  std::string connection_close_error_message = absl::StrCat(
-      "Error decoding ", headers_decompressed_ ? "trailers" : "headers",
-      " on stream ", id(), ": ", error_message);
-  OnUnrecoverableError(error_code, connection_close_error_message);
-}
-
-void QuicSpdyStream::MaybeSendPriorityUpdateFrame() {
-  if (!VersionUsesHttp3(transport_version()) ||
-      session()->perspective() != Perspective::IS_CLIENT) {
-    return;
-  }
-
-  // Value between 0 and 7, inclusive.  Lower value means higher priority.
-  int urgency = precedence().spdy3_priority();
-  if (last_sent_urgency_ == urgency) {
-    return;
-  }
-  last_sent_urgency_ = urgency;
-
-  PriorityUpdateFrame priority_update;
-  priority_update.prioritized_element_type = REQUEST_STREAM;
-  priority_update.prioritized_element_id = id();
-  priority_update.priority_field_value = absl::StrCat("u=", urgency);
-  spdy_session_->WriteHttp3PriorityUpdate(priority_update);
-}
-
-void QuicSpdyStream::OnHeadersTooLarge() { Reset(QUIC_HEADERS_TOO_LARGE); }
-
-void QuicSpdyStream::OnInitialHeadersComplete(
-    bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
-  // TODO(b/134706391): remove |fin| argument.
-  headers_decompressed_ = true;
-  header_list_ = header_list;
-  bool header_too_large = VersionUsesHttp3(transport_version())
-                              ? header_list_size_limit_exceeded_
-                              : header_list.empty();
-  // Validate request headers if it did not exceed size limit. If it did,
-  // OnHeadersTooLarge() should have already handled it previously.
-  if (!header_too_large && !AreHeadersValid(header_list)) {
-    QUIC_CODE_COUNT_N(quic_validate_request_header, 1, 2);
-    if (GetQuicReloadableFlag(quic_act_upon_invalid_header)) {
-      QUIC_RELOADABLE_FLAG_COUNT(quic_act_upon_invalid_header);
-      OnInvalidHeaders();
-      return;
-    }
-  }
-  QUIC_CODE_COUNT_N(quic_validate_request_header, 2, 2);
-
-  if (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
-      !header_too_large) {
-    MaybeProcessReceivedWebTransportHeaders();
-    if (ShouldUseDatagramContexts()) {
-      bool peer_wishes_to_use_datagram_contexts = false;
-      for (const auto& header : header_list_) {
-        if (header.first == "sec-use-datagram-contexts" &&
-            header.second == "?1") {
-          peer_wishes_to_use_datagram_contexts = true;
-          break;
-        }
-      }
-      if (!peer_wishes_to_use_datagram_contexts) {
-        use_datagram_contexts_ = false;
-      }
-    }
-  }
-
-  if (VersionUsesHttp3(transport_version())) {
-    if (fin) {
-      OnStreamFrame(QuicStreamFrame(id(), /* fin = */ true,
-                                    highest_received_byte_offset(),
-                                    absl::string_view()));
-    }
-    return;
-  }
-
-  if (fin && !rst_sent()) {
-    OnStreamFrame(
-        QuicStreamFrame(id(), fin, /* offset = */ 0, absl::string_view()));
-  }
-  if (FinishedReadingHeaders()) {
-    sequencer()->SetUnblocked();
-  }
-}
-
-void QuicSpdyStream::OnPromiseHeaderList(
-    QuicStreamId /* promised_id */, size_t /* frame_len */,
-    const QuicHeaderList& /*header_list */) {
-  // To be overridden in QuicSpdyClientStream.  Not supported on
-  // server side.
-  stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                   "Promise headers received by server");
-}
-
-void QuicSpdyStream::OnTrailingHeadersComplete(
-    bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
-  // TODO(b/134706391): remove |fin| argument.
-  QUICHE_DCHECK(!trailers_decompressed_);
-  if (!VersionUsesHttp3(transport_version()) && fin_received()) {
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Received Trailers after FIN, on stream: " << id();
-    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                     "Trailers after fin");
-    return;
-  }
-
-  if (!VersionUsesHttp3(transport_version()) && !fin) {
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Trailers must have FIN set, on stream: " << id();
-    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                     "Fin missing from trailers");
-    return;
-  }
-
-  size_t final_byte_offset = 0;
-  const bool expect_final_byte_offset = !VersionUsesHttp3(transport_version());
-  if (!SpdyUtils::CopyAndValidateTrailers(header_list, expect_final_byte_offset,
-                                          &final_byte_offset,
-                                          &received_trailers_)) {
-    QUIC_DLOG(ERROR) << ENDPOINT << "Trailers for stream " << id()
-                     << " are malformed.";
-    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
-                                     "Trailers are malformed");
-    return;
-  }
-  trailers_decompressed_ = true;
-  if (fin) {
-    const QuicStreamOffset offset = VersionUsesHttp3(transport_version())
-                                        ? highest_received_byte_offset()
-                                        : final_byte_offset;
-    OnStreamFrame(QuicStreamFrame(id(), fin, offset, absl::string_view()));
-  }
-}
-
-void QuicSpdyStream::OnPriorityFrame(
-    const spdy::SpdyStreamPrecedence& precedence) {
-  QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
-                   session()->connection()->perspective());
-  SetPriority(precedence);
-}
-
-void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
-  if (web_transport_data_ != nullptr) {
-    WebTransportStreamVisitor* webtransport_visitor =
-        web_transport_data_->adapter.visitor();
-    if (webtransport_visitor != nullptr) {
-      webtransport_visitor->OnResetStreamReceived(
-          Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
-    }
-    QuicStream::OnStreamReset(frame);
-    return;
-  }
-
-  // TODO(bnc): Merge the two blocks below when both
-  // quic_abort_qpack_on_stream_reset and quic_fix_on_stream_reset are
-  // deprecated.
-  if (frame.error_code != QUIC_STREAM_NO_ERROR) {
-    if (VersionUsesHttp3(transport_version()) && !fin_received() &&
-        spdy_session_->qpack_decoder()) {
-      QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
-      spdy_session_->qpack_decoder()->OnStreamReset(id());
-      if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
-        QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
-        qpack_decoded_headers_accumulator_.reset();
-        qpack_decoded_headers_accumulator_reset_reason_ =
-            QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset1;
-      }
-    }
-
-    QuicStream::OnStreamReset(frame);
-    return;
-  }
-
-  if (GetQuicReloadableFlag(quic_fix_on_stream_reset) &&
-      VersionUsesHttp3(transport_version())) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_fix_on_stream_reset);
-    if (!fin_received() && spdy_session_->qpack_decoder()) {
-      spdy_session_->qpack_decoder()->OnStreamReset(id());
-      qpack_decoded_headers_accumulator_.reset();
-      qpack_decoded_headers_accumulator_reset_reason_ =
-          QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
-    }
-
-    QuicStream::OnStreamReset(frame);
-    return;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT
-                << "Received QUIC_STREAM_NO_ERROR, not discarding response";
-  set_rst_received(true);
-  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
-  set_stream_error(frame.error());
-  CloseWriteSide();
-}
-
-void QuicSpdyStream::ResetWithError(QuicResetStreamError error) {
-  if (VersionUsesHttp3(transport_version()) && !fin_received() &&
-      spdy_session_->qpack_decoder() && web_transport_data_ == nullptr) {
-    QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
-    spdy_session_->qpack_decoder()->OnStreamReset(id());
-    if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
-      qpack_decoded_headers_accumulator_.reset();
-      qpack_decoded_headers_accumulator_reset_reason_ =
-          QpackDecodedHeadersAccumulatorResetReason::kResetInResetWithError;
-    }
-  }
-
-  QuicStream::ResetWithError(error);
-}
-
-bool QuicSpdyStream::OnStopSending(QuicResetStreamError error) {
-  if (web_transport_data_ != nullptr) {
-    WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
-    if (visitor != nullptr) {
-      visitor->OnStopSendingReceived(
-          Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
-    }
-  }
-
-  return QuicStream::OnStopSending(error);
-}
-
-void QuicSpdyStream::OnWriteSideInDataRecvdState() {
-  if (web_transport_data_ != nullptr) {
-    WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
-    if (visitor != nullptr) {
-      visitor->OnWriteSideInDataRecvdState();
-    }
-  }
-
-  QuicStream::OnWriteSideInDataRecvdState();
-}
-
-void QuicSpdyStream::OnDataAvailable() {
-  if (!VersionUsesHttp3(transport_version())) {
-    // Sequencer must be blocked until headers are consumed.
-    QUICHE_DCHECK(FinishedReadingHeaders());
-  }
-
-  if (!VersionUsesHttp3(transport_version())) {
-    HandleBodyAvailable();
-    return;
-  }
-
-  if (web_transport_data_ != nullptr) {
-    web_transport_data_->adapter.OnDataAvailable();
-    return;
-  }
-
-  if (!spdy_session()->ShouldProcessIncomingRequests()) {
-    spdy_session()->OnStreamWaitingForClientSettings(id());
-    return;
-  }
-
-  if (is_decoder_processing_input_) {
-    // Let the outermost nested OnDataAvailable() call do the work.
-    return;
-  }
-
-  if (blocked_on_decoding_headers_) {
-    return;
-  }
-
-  iovec iov;
-  while (session()->connection()->connected() && !reading_stopped() &&
-         decoder_.error() == QUIC_NO_ERROR) {
-    QUICHE_DCHECK_GE(sequencer_offset_, sequencer()->NumBytesConsumed());
-    if (!sequencer()->PeekRegion(sequencer_offset_, &iov)) {
-      break;
-    }
-
-    QUICHE_DCHECK(!sequencer()->IsClosed());
-    is_decoder_processing_input_ = true;
-    QuicByteCount processed_bytes = decoder_.ProcessInput(
-        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
-    is_decoder_processing_input_ = false;
-    sequencer_offset_ += processed_bytes;
-    if (blocked_on_decoding_headers_) {
-      return;
-    }
-    if (web_transport_data_ != nullptr) {
-      return;
-    }
-  }
-
-  // Do not call HandleBodyAvailable() until headers are consumed.
-  if (!FinishedReadingHeaders()) {
-    return;
-  }
-
-  if (body_manager_.HasBytesToRead()) {
-    HandleBodyAvailable();
-    return;
-  }
-
-  if (sequencer()->IsClosed() &&
-      !on_body_available_called_because_sequencer_is_closed_) {
-    on_body_available_called_because_sequencer_is_closed_ = true;
-    HandleBodyAvailable();
-  }
-}
-
-void QuicSpdyStream::OnClose() {
-  QuicStream::OnClose();
-
-  qpack_decoded_headers_accumulator_.reset();
-  qpack_decoded_headers_accumulator_reset_reason_ =
-      QpackDecodedHeadersAccumulatorResetReason::kResetInOnClose;
-
-  if (visitor_) {
-    Visitor* visitor = visitor_;
-    // Calling Visitor::OnClose() may result the destruction of the visitor,
-    // so we need to ensure we don't call it again.
-    visitor_ = nullptr;
-    visitor->OnClose(this);
-  }
-
-  if (datagram_flow_id_.has_value()) {
-    spdy_session_->UnregisterHttp3DatagramFlowId(datagram_flow_id_.value());
-  }
-
-  if (web_transport_ != nullptr) {
-    web_transport_->OnConnectStreamClosing();
-  }
-  if (web_transport_data_ != nullptr) {
-    WebTransportHttp3* web_transport =
-        spdy_session_->GetWebTransportSession(web_transport_data_->session_id);
-    if (web_transport == nullptr) {
-      // Since there is no guaranteed destruction order for streams, the session
-      // could be already removed from the stream map by the time we reach here.
-      QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
-                         << " attempted to notify parent session "
-                         << web_transport_data_->session_id
-                         << ", but the session could not be found.";
-      return;
-    }
-    web_transport->OnStreamClosed(id());
-  }
-}
-
-void QuicSpdyStream::OnCanWrite() {
-  QuicStream::OnCanWrite();
-
-  // Trailers (and hence a FIN) may have been sent ahead of queued body bytes.
-  if (!HasBufferedData() && fin_sent()) {
-    CloseWriteSide();
-  }
-}
-
-bool QuicSpdyStream::FinishedReadingHeaders() const {
-  return headers_decompressed_ && header_list_.empty();
-}
-
-// static
-bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header,
-                                           int* status_code) {
-  SpdyHeaderBlock::const_iterator it = header.find(spdy::kHttp2StatusHeader);
-  if (it == header.end()) {
-    return false;
-  }
-  const absl::string_view status(it->second);
-  if (status.size() != 3) {
-    return false;
-  }
-  // First character must be an integer in range [1,5].
-  if (status[0] < '1' || status[0] > '5') {
-    return false;
-  }
-  // The remaining two characters must be integers.
-  if (!isdigit(status[1]) || !isdigit(status[2])) {
-    return false;
-  }
-  return absl::SimpleAtoi(status, status_code);
-}
-
-bool QuicSpdyStream::FinishedReadingTrailers() const {
-  // If no further trailing headers are expected, and the decompressed trailers
-  // (if any) have been consumed, then reading of trailers is finished.
-  if (!fin_received()) {
-    return false;
-  } else if (!trailers_decompressed_) {
-    return true;
-  } else {
-    return trailers_consumed_;
-  }
-}
-
-bool QuicSpdyStream::OnDataFrameStart(QuicByteCount header_length,
-                                      QuicByteCount payload_length) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnDataFrameReceived(id(), payload_length);
-  }
-
-  if (!headers_decompressed_ || trailers_decompressed_) {
-    stream_delegate()->OnStreamError(
-        QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
-        "Unexpected DATA frame received.");
-    return false;
-  }
-
-  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
-
-  return true;
-}
-
-bool QuicSpdyStream::OnDataFramePayload(absl::string_view payload) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  body_manager_.OnBody(payload);
-
-  return true;
-}
-
-bool QuicSpdyStream::OnDataFrameEnd() {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  QUIC_DVLOG(1) << ENDPOINT
-                << "Reaches the end of a data frame. Total bytes received are "
-                << body_manager_.total_body_bytes_received();
-  return true;
-}
-
-bool QuicSpdyStream::OnStreamFrameAcked(QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        bool fin_acked,
-                                        QuicTime::Delta ack_delay_time,
-                                        QuicTime receive_timestamp,
-                                        QuicByteCount* newly_acked_length) {
-  const bool new_data_acked = QuicStream::OnStreamFrameAcked(
-      offset, data_length, fin_acked, ack_delay_time, receive_timestamp,
-      newly_acked_length);
-
-  const QuicByteCount newly_acked_header_length =
-      GetNumFrameHeadersInInterval(offset, data_length);
-  QUICHE_DCHECK_LE(newly_acked_header_length, *newly_acked_length);
-  unacked_frame_headers_offsets_.Difference(offset, offset + data_length);
-  if (ack_listener_ != nullptr && new_data_acked) {
-    ack_listener_->OnPacketAcked(
-        *newly_acked_length - newly_acked_header_length, ack_delay_time);
-  }
-  return new_data_acked;
-}
-
-void QuicSpdyStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
-                                                QuicByteCount data_length,
-                                                bool fin_retransmitted) {
-  QuicStream::OnStreamFrameRetransmitted(offset, data_length,
-                                         fin_retransmitted);
-
-  const QuicByteCount retransmitted_header_length =
-      GetNumFrameHeadersInInterval(offset, data_length);
-  QUICHE_DCHECK_LE(retransmitted_header_length, data_length);
-
-  if (ack_listener_ != nullptr) {
-    ack_listener_->OnPacketRetransmitted(data_length -
-                                         retransmitted_header_length);
-  }
-}
-
-QuicByteCount QuicSpdyStream::GetNumFrameHeadersInInterval(
-    QuicStreamOffset offset, QuicByteCount data_length) const {
-  QuicByteCount header_acked_length = 0;
-  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
-  newly_acked.Intersection(unacked_frame_headers_offsets_);
-  for (const auto& interval : newly_acked) {
-    header_acked_length += interval.Length();
-  }
-  return header_acked_length;
-}
-
-bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length,
-                                         QuicByteCount payload_length) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  QUICHE_DCHECK(!qpack_decoded_headers_accumulator_);
-
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnHeadersFrameReceived(id(),
-                                                           payload_length);
-  }
-
-  headers_payload_length_ = payload_length;
-
-  if (trailers_decompressed_) {
-    stream_delegate()->OnStreamError(
-        QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
-        "HEADERS frame received after trailing HEADERS.");
-    return false;
-  }
-
-  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
-
-  qpack_decoded_headers_accumulator_ =
-      std::make_unique<QpackDecodedHeadersAccumulator>(
-          id(), spdy_session_->qpack_decoder(), this,
-          spdy_session_->max_inbound_header_list_size());
-
-  return true;
-}
-
-bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  if (!qpack_decoded_headers_accumulator_) {
-    QUIC_BUG(b215142466_OnHeadersFramePayload)
-        << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
-    OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
-                          "qpack_decoded_headers_accumulator_ is nullptr");
-    return false;
-  }
-
-  qpack_decoded_headers_accumulator_->Decode(payload);
-
-  // |qpack_decoded_headers_accumulator_| is reset if an error is detected.
-  if (!qpack_decoded_headers_accumulator_) {
-    return false;
-  }
-
-  sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
-  return true;
-}
-
-bool QuicSpdyStream::OnHeadersFrameEnd() {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-
-  if (!qpack_decoded_headers_accumulator_) {
-    QUIC_BUG(b215142466_OnHeadersFrameEnd)
-        << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
-    OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
-                          "qpack_decoded_headers_accumulator_ is nullptr");
-    return false;
-  }
-
-  qpack_decoded_headers_accumulator_->EndHeaderBlock();
-
-  // If decoding is complete or an error is detected, then
-  // |qpack_decoded_headers_accumulator_| is already reset.
-  if (qpack_decoded_headers_accumulator_) {
-    blocked_on_decoding_headers_ = true;
-    return false;
-  }
-
-  return !sequencer()->IsClosed() && !reading_stopped();
-}
-
-void QuicSpdyStream::OnWebTransportStreamFrameType(
-    QuicByteCount header_length, WebTransportSessionId session_id) {
-  QUIC_DVLOG(1) << ENDPOINT << " Received WEBTRANSPORT_STREAM on stream "
-                << id() << " for session " << session_id;
-  sequencer()->MarkConsumed(header_length);
-
-  if (headers_payload_length_ > 0 || headers_decompressed_) {
-    QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on HTTP request)
-        << ENDPOINT << "Stream " << id()
-        << " tried to convert to WebTransport, but it already "
-           "has HTTP data on it";
-    Reset(QUIC_STREAM_FRAME_UNEXPECTED);
-  }
-  if (QuicUtils::IsOutgoingStreamId(spdy_session_->version(), id(),
-                                    spdy_session_->perspective())) {
-    QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on outgoing request)
-        << ENDPOINT << "Stream " << id()
-        << " tried to convert to WebTransport, but only the "
-           "initiator of the stream can do it.";
-    Reset(QUIC_STREAM_FRAME_UNEXPECTED);
-  }
-
-  QUICHE_DCHECK(web_transport_ == nullptr);
-  web_transport_data_ =
-      std::make_unique<WebTransportDataStream>(this, session_id);
-  spdy_session_->AssociateIncomingWebTransportStreamWithSession(session_id,
-                                                                id());
-}
-
-bool QuicSpdyStream::OnUnknownFrameStart(uint64_t frame_type,
-                                         QuicByteCount header_length,
-                                         QuicByteCount payload_length) {
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
-                                                           payload_length);
-  }
-
-  // Ignore unknown frames, but consume frame header.
-  QUIC_DVLOG(1) << ENDPOINT << "Discarding " << header_length
-                << " byte long frame header of frame of unknown type "
-                << frame_type << ".";
-  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
-  return true;
-}
-
-bool QuicSpdyStream::OnUnknownFramePayload(absl::string_view payload) {
-  // Ignore unknown frames, but consume frame payload.
-  QUIC_DVLOG(1) << ENDPOINT << "Discarding " << payload.size()
-                << " bytes of payload of frame of unknown type.";
-  sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
-  return true;
-}
-
-bool QuicSpdyStream::OnUnknownFrameEnd() { return true; }
-
-size_t QuicSpdyStream::WriteHeadersImpl(
-    spdy::SpdyHeaderBlock header_block, bool fin,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return spdy_session_->WriteHeadersOnHeadersStream(
-        id(), std::move(header_block), fin, precedence(),
-        std::move(ack_listener));
-  }
-
-  // Encode header list.
-  QuicByteCount encoder_stream_sent_byte_count;
-  std::string encoded_headers =
-      spdy_session_->qpack_encoder()->EncodeHeaderList(
-          id(), header_block, &encoder_stream_sent_byte_count);
-
-  if (spdy_session_->debug_visitor()) {
-    spdy_session_->debug_visitor()->OnHeadersFrameSent(id(), header_block);
-  }
-
-  // Write HEADERS frame.
-  std::unique_ptr<char[]> headers_frame_header;
-  const size_t headers_frame_header_length =
-      HttpEncoder::SerializeHeadersFrameHeader(encoded_headers.size(),
-                                               &headers_frame_header);
-  unacked_frame_headers_offsets_.Add(
-      send_buffer().stream_offset(),
-      send_buffer().stream_offset() + headers_frame_header_length);
-
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
-                  << " is writing HEADERS frame header of length "
-                  << headers_frame_header_length;
-  WriteOrBufferData(absl::string_view(headers_frame_header.get(),
-                                      headers_frame_header_length),
-                    /* fin = */ false, /* ack_listener = */ nullptr);
-
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
-                  << " is writing HEADERS frame payload of length "
-                  << encoded_headers.length() << " with fin " << fin;
-  WriteOrBufferData(encoded_headers, fin, nullptr);
-
-  QuicSpdySession::LogHeaderCompressionRatioHistogram(
-      /* using_qpack = */ true,
-      /* is_sent = */ true,
-      encoded_headers.size() + encoder_stream_sent_byte_count,
-      header_block.TotalBytesUsed());
-
-  return encoded_headers.size();
-}
-
-bool QuicSpdyStream::CanWriteNewBodyData(QuicByteCount write_size) const {
-  QUICHE_DCHECK_NE(0u, write_size);
-  if (!VersionUsesHttp3(transport_version())) {
-    return CanWriteNewData();
-  }
-
-  return CanWriteNewDataAfterData(
-      HttpEncoder::GetDataFrameHeaderLength(write_size));
-}
-
-void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
-  if (!spdy_session_->SupportsWebTransport()) {
-    return;
-  }
-  if (session()->perspective() != Perspective::IS_SERVER) {
-    return;
-  }
-  QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
-
-  std::string method;
-  std::string protocol;
-  absl::optional<QuicDatagramStreamId> flow_id;
-  bool version_indicated = false;
-  for (const auto& [header_name, header_value] : header_list_) {
-    if (header_name == ":method") {
-      if (!method.empty() || header_value.empty()) {
-        return;
-      }
-      method = header_value;
-    }
-    if (header_name == ":protocol") {
-      if (!protocol.empty() || header_value.empty()) {
-        return;
-      }
-      protocol = header_value;
-    }
-    if (header_name == "datagram-flow-id") {
-      if (spdy_session_->http_datagram_support() !=
-          HttpDatagramSupport::kDraft00) {
-        QUIC_DLOG(ERROR) << ENDPOINT
-                         << "Rejecting WebTransport due to unexpected "
-                            "Datagram-Flow-Id header";
-        return;
-      }
-      if (flow_id.has_value() || header_value.empty()) {
-        return;
-      }
-      QuicDatagramStreamId flow_id_out;
-      if (!absl::SimpleAtoi(header_value, &flow_id_out)) {
-        return;
-      }
-      flow_id = flow_id_out;
-    }
-    if (header_name == "sec-webtransport-http3-draft02") {
-      if (header_value != "1") {
-        QUIC_DLOG(ERROR) << ENDPOINT
-                         << "Rejecting WebTransport due to invalid value of "
-                            "Sec-Webtransport-Http3-Draft02 header";
-        return;
-      }
-      version_indicated = true;
-    }
-  }
-
-  if (method != "CONNECT" || protocol != "webtransport") {
-    return;
-  }
-
-  if (!version_indicated &&
-      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
-    QUIC_DLOG(ERROR)
-        << ENDPOINT
-        << "WebTransport request rejected due to missing version header.";
-    return;
-  }
-
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    if (!flow_id.has_value()) {
-      QUIC_DLOG(ERROR)
-          << ENDPOINT
-          << "Rejecting WebTransport due to missing Datagram-Flow-Id header";
-      return;
-    }
-    RegisterHttp3DatagramFlowId(*flow_id);
-  }
-
-  web_transport_ = std::make_unique<WebTransportHttp3>(
-      spdy_session_, this, id(),
-      spdy_session_->ShouldNegotiateDatagramContexts());
-
-  if (spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
-    return;
-  }
-  // If we're in draft-ietf-masque-h3-datagram-00 mode, pretend we also received
-  // a REGISTER_DATAGRAM_NO_CONTEXT capsule.
-  // TODO(b/181256914) remove this when we remove support for
-  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-  RegisterHttp3DatagramContextId(
-      /*context_id=*/absl::nullopt, DatagramFormatType::WEBTRANSPORT,
-      /*format_additional_data=*/absl::string_view(), web_transport_.get());
-}
-
-void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
-    spdy::SpdyHeaderBlock& headers) {
-  if (!spdy_session_->SupportsWebTransport()) {
-    return;
-  }
-  if (session()->perspective() != Perspective::IS_CLIENT) {
-    return;
-  }
-  QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
-
-  const auto method_it = headers.find(":method");
-  const auto protocol_it = headers.find(":protocol");
-  if (method_it == headers.end() || protocol_it == headers.end()) {
-    return;
-  }
-  if (method_it->second != "CONNECT" && protocol_it->second != "webtransport") {
-    return;
-  }
-
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    headers["datagram-flow-id"] = absl::StrCat(id());
-  } else {
-    headers["sec-webtransport-http3-draft02"] = "1";
-  }
-
-  web_transport_ = std::make_unique<WebTransportHttp3>(
-      spdy_session_, this, id(),
-      spdy_session_->ShouldNegotiateDatagramContexts());
-}
-
-void QuicSpdyStream::OnCanWriteNewData() {
-  if (web_transport_data_ != nullptr) {
-    web_transport_data_->adapter.OnCanWriteNewData();
-  }
-}
-
-bool QuicSpdyStream::AssertNotWebTransportDataStream(
-    absl::string_view operation) {
-  if (web_transport_data_ != nullptr) {
-    QUIC_BUG(Invalid operation on WebTransport stream)
-        << "Attempted to " << operation << " on WebTransport data stream "
-        << id() << " associated with session "
-        << web_transport_data_->session_id;
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                         absl::StrCat("Attempted to ", operation,
-                                      " on WebTransport data stream"));
-    return false;
-  }
-  return true;
-}
-
-void QuicSpdyStream::ConvertToWebTransportDataStream(
-    WebTransportSessionId session_id) {
-  if (send_buffer().stream_offset() != 0) {
-    QUIC_BUG(Sending WEBTRANSPORT_STREAM when data already sent)
-        << "Attempted to send a WEBTRANSPORT_STREAM frame when other data has "
-           "already been sent on the stream.";
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                         "Attempted to send a WEBTRANSPORT_STREAM frame when "
-                         "other data has already been sent on the stream.");
-    return;
-  }
-
-  std::unique_ptr<char[]> header;
-  QuicByteCount header_size =
-      HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &header);
-  if (header_size == 0) {
-    QUIC_BUG(Failed to serialize WEBTRANSPORT_STREAM)
-        << "Failed to serialize a WEBTRANSPORT_STREAM frame.";
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                         "Failed to serialize a WEBTRANSPORT_STREAM frame.");
-    return;
-  }
-
-  WriteOrBufferData(absl::string_view(header.get(), header_size), /*fin=*/false,
-                    nullptr);
-  web_transport_data_ =
-      std::make_unique<WebTransportDataStream>(this, session_id);
-  QUIC_DVLOG(1) << ENDPOINT << "Successfully opened WebTransport data stream "
-                << id() << " for session " << session_id;
-}
-
-QuicSpdyStream::WebTransportDataStream::WebTransportDataStream(
-    QuicSpdyStream* stream, WebTransportSessionId session_id)
-    : session_id(session_id),
-      adapter(stream->spdy_session_, stream, stream->sequencer()) {}
-
-void QuicSpdyStream::HandleReceivedDatagram(
-    absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
-  Http3DatagramVisitor* visitor;
-  if (context_id.has_value()) {
-    auto it = datagram_context_visitors_.find(context_id.value());
-    if (it == datagram_context_visitors_.end()) {
-      QUIC_DLOG(ERROR) << ENDPOINT
-                       << "Received datagram without any visitor for context "
-                       << context_id.value();
-      return;
-    }
-    visitor = it->second;
-  } else {
-    if (datagram_no_context_visitor_ == nullptr) {
-      QUIC_DLOG(ERROR)
-          << ENDPOINT << "Received datagram without any visitor for no context";
-      return;
-    }
-    visitor = datagram_no_context_visitor_;
-  }
-  visitor->OnHttp3Datagram(id(), context_id, payload);
-}
-
-bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " received capsule "
-                  << capsule;
-  if (!headers_decompressed_) {
-    QUIC_PEER_BUG(capsule before headers)
-        << ENDPOINT << "Stream " << id() << " received capsule " << capsule
-        << " before headers";
-    return false;
-  }
-  if (web_transport_ != nullptr && web_transport_->close_received()) {
-    QUIC_PEER_BUG(capsule after close)
-        << ENDPOINT << "Stream " << id() << " received capsule " << capsule
-        << " after CLOSE_WEBTRANSPORT_SESSION.";
-    return false;
-  }
-  switch (capsule.capsule_type()) {
-    case CapsuleType::LEGACY_DATAGRAM: {
-      HandleReceivedDatagram(
-          capsule.legacy_datagram_capsule().context_id,
-          capsule.legacy_datagram_capsule().http_datagram_payload);
-    } break;
-    case CapsuleType::DATAGRAM_WITH_CONTEXT: {
-      HandleReceivedDatagram(
-          capsule.datagram_with_context_capsule().context_id,
-          capsule.datagram_with_context_capsule().http_datagram_payload);
-    } break;
-    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT: {
-      absl::optional<QuicDatagramContextId> context_id;
-      if (use_datagram_contexts_) {
-        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
-        // DATAGRAM_WITHOUT_CONTEXT.
-        context_id = 0;
-      }
-      HandleReceivedDatagram(
-          context_id,
-          capsule.datagram_without_context_capsule().http_datagram_payload);
-    } break;
-    case CapsuleType::REGISTER_DATAGRAM_CONTEXT: {
-      if (datagram_registration_visitor_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " without any registration visitor";
-        return false;
-      }
-      datagram_registration_visitor_->OnContextReceived(
-          id(), capsule.register_datagram_context_capsule().context_id,
-          capsule.register_datagram_context_capsule().format_type,
-          capsule.register_datagram_context_capsule().format_additional_data);
-    } break;
-    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT: {
-      if (datagram_registration_visitor_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " without any registration visitor";
-        return false;
-      }
-      absl::optional<QuicDatagramContextId> context_id;
-      if (use_datagram_contexts_) {
-        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
-        // REGISTER_DATAGRAM_NO_CONTEXT.
-        context_id = 0;
-      }
-      datagram_registration_visitor_->OnContextReceived(
-          id(), context_id,
-          capsule.register_datagram_no_context_capsule().format_type,
-          capsule.register_datagram_no_context_capsule()
-              .format_additional_data);
-    } break;
-    case CapsuleType::CLOSE_DATAGRAM_CONTEXT: {
-      if (datagram_registration_visitor_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " without any registration visitor";
-        return false;
-      }
-      datagram_registration_visitor_->OnContextClosed(
-          id(), capsule.close_datagram_context_capsule().context_id,
-          capsule.close_datagram_context_capsule().close_code,
-          capsule.close_datagram_context_capsule().close_details);
-    } break;
-    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION: {
-      if (web_transport_ == nullptr) {
-        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
-                         << " for a non-WebTransport stream.";
-        return false;
-      }
-      web_transport_->OnCloseReceived(
-          capsule.close_web_transport_session_capsule().error_code,
-          capsule.close_web_transport_session_capsule().error_message);
-    } break;
-  }
-  return true;
-}
-
-void QuicSpdyStream::OnCapsuleParseFailure(const std::string& error_message) {
-  QUIC_DLOG(ERROR) << ENDPOINT << "Capsule parse failure: " << error_message;
-  Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-}
-
-void QuicSpdyStream::WriteCapsule(const Capsule& capsule, bool fin) {
-  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " sending capsule "
-                  << capsule;
-  quiche::QuicheBuffer serialized_capsule = SerializeCapsule(
-      capsule,
-      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
-  QUICHE_DCHECK_GT(serialized_capsule.size(), 0u);
-  WriteOrBufferBody(serialized_capsule.AsStringView(), /*fin=*/fin);
-}
-
-void QuicSpdyStream::WriteGreaseCapsule() {
-  // GREASE capsulde IDs have a form of 41 * N + 23.
-  QuicRandom* random = spdy_session_->connection()->random_generator();
-  uint64_t type = random->InsecureRandUint64() >> 4;
-  type = (type / 41) * 41 + 23;
-  QUICHE_DCHECK_EQ((type - 23) % 41, 0u);
-
-  constexpr size_t kMaxLength = 64;
-  size_t length = random->InsecureRandUint64() % kMaxLength;
-  std::string bytes(length, '\0');
-  random->InsecureRandBytes(&bytes[0], bytes.size());
-  Capsule capsule = Capsule::Unknown(type, bytes);
-  WriteCapsule(capsule, /*fin=*/false);
-}
-
-MessageStatus QuicSpdyStream::SendHttp3Datagram(
-    absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
-  QuicDatagramStreamId stream_id =
-      datagram_flow_id_.has_value() ? datagram_flow_id_.value() : id();
-  return spdy_session_->SendHttp3Datagram(stream_id, context_id, payload);
-}
-
-void QuicSpdyStream::RegisterHttp3DatagramRegistrationVisitor(
-    Http3DatagramRegistrationVisitor* visitor, bool use_datagram_contexts) {
-  if (visitor == nullptr) {
-    QUIC_BUG(null datagram registration visitor)
-        << ENDPOINT << "Null datagram registration visitor for" << id();
-    return;
-  }
-  if (datagram_registration_visitor_ != nullptr) {
-    QUIC_BUG(double datagram registration visitor)
-        << ENDPOINT << "Double datagram registration visitor for" << id();
-    return;
-  }
-  use_datagram_contexts_ = use_datagram_contexts;
-  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram stream ID " << id()
-                  << " with" << (use_datagram_contexts_ ? "" : "out")
-                  << " contexts";
-  datagram_registration_visitor_ = visitor;
-  QUICHE_DCHECK(!capsule_parser_);
-  capsule_parser_.reset(new CapsuleParser(this));
-}
-
-void QuicSpdyStream::UnregisterHttp3DatagramRegistrationVisitor() {
-  QUIC_BUG_IF(h3 datagram unregister unknown stream ID,
-              datagram_registration_visitor_ == nullptr)
-      << ENDPOINT
-      << "Attempted to unregister unknown HTTP/3 datagram stream ID " << id();
-  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram stream ID " << id();
-  datagram_registration_visitor_ = nullptr;
-}
-
-void QuicSpdyStream::MoveHttp3DatagramRegistration(
-    Http3DatagramRegistrationVisitor* visitor) {
-  QUIC_BUG_IF(h3 datagram move unknown stream ID,
-              datagram_registration_visitor_ == nullptr)
-      << ENDPOINT << "Attempted to move unknown HTTP/3 datagram stream ID "
-      << id();
-  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram stream ID " << id();
-  datagram_registration_visitor_ = visitor;
-}
-
-void QuicSpdyStream::RegisterHttp3DatagramContextId(
-    absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data,
-    Http3DatagramVisitor* visitor) {
-  if (visitor == nullptr) {
-    QUIC_BUG(null datagram visitor)
-        << ENDPOINT << "Null datagram visitor for stream ID " << id()
-        << " context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none");
-    return;
-  }
-  if (datagram_registration_visitor_ == nullptr) {
-    QUIC_BUG(context registration without registration visitor)
-        << ENDPOINT << "Cannot register context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " without registration visitor for stream ID " << id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram context ID "
-                  << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                             : "none")
-                  << " with stream ID " << id();
-
-  if (context_id.has_value()) {
-    if (datagram_no_context_visitor_ != nullptr) {
-      QUIC_BUG(h3 datagram context ID mix1)
-          << ENDPOINT
-          << "Attempted to mix registrations without and with context IDs "
-             "for stream ID "
-          << id();
-      return;
-    }
-    auto insertion_result =
-        datagram_context_visitors_.insert({context_id.value(), visitor});
-    if (!insertion_result.second) {
-      QUIC_BUG(h3 datagram double context registration)
-          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
-          << id() << " context ID " << context_id.value();
-      return;
-    }
-    capsule_parser_->set_datagram_context_id_present(true);
-  } else {
-    // Registration without a context ID.
-    if (!datagram_context_visitors_.empty()) {
-      QUIC_BUG(h3 datagram context ID mix2)
-          << ENDPOINT
-          << "Attempted to mix registrations with and without context IDs "
-             "for stream ID "
-          << id();
-      return;
-    }
-    if (datagram_no_context_visitor_ != nullptr) {
-      QUIC_BUG(h3 datagram double no context registration)
-          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
-          << id() << " with no context ID";
-      return;
-    }
-    datagram_no_context_visitor_ = visitor;
-    capsule_parser_->set_datagram_context_id_present(false);
-  }
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04) {
-    const bool is_client = session()->perspective() == Perspective::IS_CLIENT;
-    if (context_id.has_value()) {
-      const bool is_client_context = context_id.value() % 2 == 0;
-      if (is_client == is_client_context) {
-        QuicConnection::ScopedPacketFlusher flusher(
-            spdy_session_->connection());
-        WriteGreaseCapsule();
-        if (context_id.value() != 0) {
-          WriteCapsule(Capsule::RegisterDatagramContext(
-              context_id.value(), format_type, format_additional_data));
-        } else {
-          // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
-          // REGISTER_DATAGRAM_NO_CONTEXT.
-          WriteCapsule(Capsule::RegisterDatagramNoContext(
-              format_type, format_additional_data));
-        }
-        WriteGreaseCapsule();
-      }
-    } else if (is_client) {
-      QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
-      WriteGreaseCapsule();
-      WriteCapsule(Capsule::RegisterDatagramNoContext(format_type,
-                                                      format_additional_data));
-      WriteGreaseCapsule();
-    }
-  }
-}
-
-void QuicSpdyStream::UnregisterHttp3DatagramContextId(
-    absl::optional<QuicDatagramContextId> context_id) {
-  if (datagram_registration_visitor_ == nullptr) {
-    QUIC_BUG(context unregistration without registration visitor)
-        << ENDPOINT << "Cannot unregister context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " without registration visitor for stream ID " << id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram context ID "
-                  << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                             : "none")
-                  << " with stream ID " << id();
-  if (context_id.has_value()) {
-    size_t num_erased = datagram_context_visitors_.erase(context_id.value());
-    QUIC_BUG_IF(h3 datagram unregister unknown context, num_erased != 1)
-        << "Attempted to unregister unknown HTTP/3 context ID "
-        << context_id.value() << " on stream ID " << id();
-  } else {
-    // Unregistration without a context ID.
-    QUIC_BUG_IF(h3 datagram unknown context unregistration,
-                datagram_no_context_visitor_ == nullptr)
-        << "Attempted to unregister unknown no context on HTTP/3 stream ID "
-        << id();
-    datagram_no_context_visitor_ = nullptr;
-  }
-  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04 &&
-      context_id.has_value()) {
-    WriteCapsule(Capsule::CloseDatagramContext(context_id.value()));
-  }
-}
-
-void QuicSpdyStream::MoveHttp3DatagramContextIdRegistration(
-    absl::optional<QuicDatagramContextId> context_id,
-    Http3DatagramVisitor* visitor) {
-  if (datagram_registration_visitor_ == nullptr) {
-    QUIC_BUG(context move without registration visitor)
-        << ENDPOINT << "Cannot move context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " without registration visitor for stream ID " << id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram context ID "
-                  << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                             : "none")
-                  << " with stream ID " << id();
-  if (context_id.has_value()) {
-    QUIC_BUG_IF(h3 datagram move unknown context,
-                !datagram_context_visitors_.contains(context_id.value()))
-        << ENDPOINT << "Attempted to move unknown context ID "
-        << context_id.value() << " on stream ID " << id();
-    datagram_context_visitors_[context_id.value()] = visitor;
-    return;
-  }
-  // Move without a context ID.
-  QUIC_BUG_IF(h3 datagram unknown context move,
-              datagram_no_context_visitor_ == nullptr)
-      << "Attempted to move unknown no context on HTTP/3 stream ID " << id();
-  datagram_no_context_visitor_ = visitor;
-}
-
-void QuicSpdyStream::SetMaxDatagramTimeInQueue(
-    QuicTime::Delta max_time_in_queue) {
-  spdy_session_->SetMaxDatagramTimeInQueueForStreamId(id(), max_time_in_queue);
-}
-
-QuicDatagramContextId QuicSpdyStream::GetNextDatagramContextId() {
-  QuicDatagramContextId result = datagram_next_available_context_id_;
-  datagram_next_available_context_id_ += kDatagramContextIdIncrement;
-  return result;
-}
-
-void QuicSpdyStream::OnDatagramReceived(QuicDataReader* reader) {
-  if (!headers_decompressed_) {
-    QUIC_DLOG(INFO) << "Dropping datagram received before headers on stream ID "
-                    << id();
-    return;
-  }
-  absl::optional<QuicDatagramContextId> context_id;
-  if (use_datagram_contexts_) {
-    QuicDatagramContextId parsed_context_id;
-    if (!reader->ReadVarInt62(&parsed_context_id)) {
-      QUIC_DLOG(ERROR) << "Failed to parse context ID in received HTTP/3 "
-                          "datagram on stream ID "
-                       << id();
-      return;
-    }
-    context_id = parsed_context_id;
-  }
-  absl::string_view payload = reader->ReadRemainingPayload();
-  HandleReceivedDatagram(context_id, payload);
-}
-
-QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
-    absl::optional<QuicDatagramContextId> context_id) const {
-  QuicByteCount prefix_size = 0;
-  switch (spdy_session_->http_datagram_support()) {
-    case HttpDatagramSupport::kDraft00:
-      if (!datagram_flow_id_.has_value()) {
-        QUIC_BUG(GetMaxDatagramSize with no flow ID)
-            << "GetMaxDatagramSize() called when no flow ID available";
-        break;
-      }
-      prefix_size = QuicDataWriter::GetVarInt62Len(*datagram_flow_id_);
-      break;
-    case HttpDatagramSupport::kDraft04:
-      prefix_size =
-          QuicDataWriter::GetVarInt62Len(id() / kHttpDatagramStreamIdDivisor);
-      break;
-    case HttpDatagramSupport::kNone:
-    case HttpDatagramSupport::kDraft00And04:
-      QUIC_BUG(GetMaxDatagramSize called with no datagram support)
-          << "GetMaxDatagramSize() called when no HTTP/3 datagram support has "
-             "been negotiated.  Support value: "
-          << spdy_session_->http_datagram_support();
-      break;
-  }
-  // If the logic above fails, use the largest possible value as the safe one.
-  if (prefix_size == 0) {
-    prefix_size = 8;
-  }
-
-  if (context_id.has_value()) {
-    QUIC_BUG_IF(
-        context_id with draft00 in GetMaxDatagramSize,
-        spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00)
-        << "GetMaxDatagramSize() called with a context ID specified, but "
-           "draft00 does not support contexts.";
-    prefix_size += QuicDataWriter::GetVarInt62Len(*context_id);
-  }
-
-  QuicByteCount max_datagram_size =
-      session()->GetGuaranteedLargestMessagePayload();
-  if (max_datagram_size < prefix_size) {
-    QUIC_BUG(max_datagram_size smaller than prefix_size)
-        << "GetGuaranteedLargestMessagePayload() returned a datagram size that "
-           "is not sufficient to fit stream and/or context ID into it.";
-    return 0;
-  }
-  return max_datagram_size - prefix_size;
-}
-
-void QuicSpdyStream::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id) {
-  datagram_flow_id_ = flow_id;
-  spdy_session_->RegisterHttp3DatagramFlowId(datagram_flow_id_.value(), id());
-}
-
-void QuicSpdyStream::HandleBodyAvailable() {
-  if (!capsule_parser_) {
-    OnBodyAvailable();
-    return;
-  }
-  while (body_manager_.HasBytesToRead()) {
-    iovec iov;
-    int num_iov = GetReadableRegions(&iov, /*iov_len=*/1);
-    if (num_iov == 0) {
-      break;
-    }
-    if (!capsule_parser_->IngestCapsuleFragment(absl::string_view(
-            reinterpret_cast<const char*>(iov.iov_base), iov.iov_len))) {
-      break;
-    }
-    MarkConsumed(iov.iov_len);
-  }
-  // If we received a FIN, make sure that there isn't a partial capsule buffered
-  // in the capsule parser.
-  if (sequencer()->IsClosed()) {
-    capsule_parser_->ErrorIfThereIsRemainingBufferedData();
-    if (web_transport_ != nullptr) {
-      web_transport_->OnConnectStreamFinReceived();
-    }
-    OnFinRead();
-  }
-}
-
-namespace {
-// Return true if |c| is not allowed in an HTTP/3 wire-encoded header and
-// pseudo-header names according to
-// https://datatracker.ietf.org/doc/html/draft-ietf-quic-http#section-4.1.1 and
-// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-semantics-19#section-5.6.2
-constexpr bool isInvalidHeaderNameCharacter(unsigned char c) {
-  if (c == '!' || c == '|' || c == '~' || c == '*' || c == '+' || c == '-' ||
-      c == '.' ||
-      // #, $, %, &, '
-      (c >= '#' && c <= '\'') ||
-      // [0-9], :
-      (c >= '0' && c <= ':') ||
-      // ^, _, `, [a-z]
-      (c >= '^' && c <= 'z')) {
-    return false;
-  }
-  return true;
-}
-}  // namespace
-
-bool QuicSpdyStream::AreHeadersValid(const QuicHeaderList& header_list) const {
-  QUICHE_DCHECK(GetQuicReloadableFlag(quic_verify_request_headers_2));
-  for (const std::pair<std::string, std::string>& pair : header_list) {
-    const std::string& name = pair.first;
-    if (std::any_of(name.begin(), name.end(), isInvalidHeaderNameCharacter)) {
-      QUIC_DLOG(ERROR) << "Invalid request header " << name;
-      return false;
-    }
-    if (http2::GetInvalidHttp2HeaderSet().contains(name)) {
-      QUIC_DLOG(ERROR) << name << " header is not allowed";
-      return false;
-    }
-  }
-  return true;
-}
-
-void QuicSpdyStream::OnInvalidHeaders() { Reset(QUIC_BAD_APPLICATION_PAYLOAD); }
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream.h b/quic/core/http/quic_spdy_stream.h
deleted file mode 100644
index 5a77d6f..0000000
--- a/quic/core/http/quic_spdy_stream.h
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The base class for streams which deliver data to/from an application.
-// In each direction, the data on such a stream first contains compressed
-// headers then body data.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
-
-#include <sys/types.h>
-
-#include <cstddef>
-#include <list>
-#include <memory>
-#include <string>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "quic/core/http/capsule.h"
-#include "quic/core/http/http_decoder.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/quic_spdy_stream_body_manager.h"
-#include "quic/core/http/web_transport_stream_adapter.h"
-#include "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "spdy/core/spdy_framer.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-namespace test {
-class QuicSpdyStreamPeer;
-class QuicStreamPeer;
-}  // namespace test
-
-class QuicSpdySession;
-class WebTransportHttp3;
-
-// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
-class QUIC_EXPORT_PRIVATE QuicSpdyStream
-    : public QuicStream,
-      public CapsuleParser::Visitor,
-      public QpackDecodedHeadersAccumulator::Visitor {
- public:
-  // Visitor receives callbacks from the stream.
-  class QUIC_EXPORT_PRIVATE Visitor {
-   public:
-    Visitor() {}
-    Visitor(const Visitor&) = delete;
-    Visitor& operator=(const Visitor&) = delete;
-
-    // Called when the stream is closed.
-    virtual void OnClose(QuicSpdyStream* stream) = 0;
-
-    // Allows subclasses to override and do work.
-    virtual void OnPromiseHeadersComplete(QuicStreamId /*promised_id*/,
-                                          size_t /*frame_len*/) {}
-
-   protected:
-    virtual ~Visitor() {}
-  };
-
-  QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
-                 StreamType type);
-  QuicSpdyStream(PendingStream* pending, QuicSpdySession* spdy_session);
-  QuicSpdyStream(const QuicSpdyStream&) = delete;
-  QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
-  ~QuicSpdyStream() override;
-
-  // QuicStream implementation
-  void OnClose() override;
-
-  // Override to maybe close the write side after writing.
-  void OnCanWrite() override;
-
-  // Called by the session when headers with a priority have been received
-  // for this stream.  This method will only be called for server streams.
-  virtual void OnStreamHeadersPriority(
-      const spdy::SpdyStreamPrecedence& precedence);
-
-  // Called by the session when decompressed headers have been completely
-  // delivered to this stream.  If |fin| is true, then this stream
-  // should be closed; no more data will be sent by the peer.
-  virtual void OnStreamHeaderList(bool fin, size_t frame_len,
-                                  const QuicHeaderList& header_list);
-
-  // Called by the session when decompressed push promise headers have
-  // been completely delivered to this stream.
-  virtual void OnPromiseHeaderList(QuicStreamId promised_id, size_t frame_len,
-                                   const QuicHeaderList& header_list);
-
-  // Called by the session when a PRIORITY frame has been been received for this
-  // stream. This method will only be called for server streams.
-  void OnPriorityFrame(const spdy::SpdyStreamPrecedence& precedence);
-
-  // Override the base class to not discard response when receiving
-  // QUIC_STREAM_NO_ERROR.
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-  void ResetWithError(QuicResetStreamError error) override;
-  bool OnStopSending(QuicResetStreamError error) override;
-
-  // Called by the sequencer when new data is available. Decodes the data and
-  // calls OnBodyAvailable() to pass to the upper layer.
-  void OnDataAvailable() override;
-
-  // Called in OnDataAvailable() after it finishes the decoding job.
-  virtual void OnBodyAvailable() = 0;
-
-  // Writes the headers contained in |header_block| on the dedicated headers
-  // stream or on this stream, depending on VersionUsesHttp3().  Returns the
-  // number of bytes sent, including data sent on the encoder stream when using
-  // QPACK.
-  virtual size_t WriteHeaders(
-      spdy::SpdyHeaderBlock header_block, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  // Sends |data| to the peer, or buffers if it can't be sent immediately.
-  void WriteOrBufferBody(absl::string_view data, bool fin);
-
-  // Writes the trailers contained in |trailer_block| on the dedicated headers
-  // stream or on this stream, depending on VersionUsesHttp3().  Trailers will
-  // always have the FIN flag set.  Returns the number of bytes sent, including
-  // data sent on the encoder stream when using QPACK.
-  virtual size_t WriteTrailers(
-      spdy::SpdyHeaderBlock trailer_block,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  // Override to report newly acked bytes via ack_listener_.
-  bool OnStreamFrameAcked(QuicStreamOffset offset, QuicByteCount data_length,
-                          bool fin_acked, QuicTime::Delta ack_delay_time,
-                          QuicTime receive_timestamp,
-                          QuicByteCount* newly_acked_length) override;
-
-  // Override to report bytes retransmitted via ack_listener_.
-  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
-                                  QuicByteCount data_length,
-                                  bool fin_retransmitted) override;
-
-  // Does the same thing as WriteOrBufferBody except this method takes iovec
-  // as the data input. Right now it only calls WritevData.
-  QuicConsumedData WritevBody(const struct iovec* iov, int count, bool fin);
-
-  // Does the same thing as WriteOrBufferBody except this method takes
-  // memslicespan as the data input. Right now it only calls WriteMemSlices.
-  QuicConsumedData WriteBodySlices(absl::Span<quiche::QuicheMemSlice> slices,
-                                   bool fin);
-
-  // Marks the trailers as consumed. This applies to the case where this object
-  // receives headers and trailers as QuicHeaderLists via calls to
-  // OnStreamHeaderList(). Trailer data will be consumed from the sequencer only
-  // once all body data has been consumed.
-  void MarkTrailersConsumed();
-
-  // Clears |header_list_|.
-  void ConsumeHeaderList();
-
-  // This block of functions wraps the sequencer's functions of the same
-  // name.  These methods return uncompressed data until that has
-  // been fully processed.  Then they simply delegate to the sequencer.
-  virtual size_t Readv(const struct iovec* iov, size_t iov_len);
-  virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
-  void MarkConsumed(size_t num_bytes);
-
-  // Returns true if header contains a valid 3-digit status and parse the status
-  // code to |status_code|.
-  static bool ParseHeaderStatusCode(const spdy::SpdyHeaderBlock& header,
-                                    int* status_code);
-
-  // Returns true when all data from the peer has been read and consumed,
-  // including the fin.
-  bool IsDoneReading() const;
-  bool HasBytesToRead() const;
-
-  void set_visitor(Visitor* visitor) { visitor_ = visitor; }
-
-  bool headers_decompressed() const { return headers_decompressed_; }
-
-  // Returns total amount of body bytes that have been read.
-  uint64_t total_body_bytes_read() const;
-
-  const QuicHeaderList& header_list() const { return header_list_; }
-
-  bool trailers_decompressed() const { return trailers_decompressed_; }
-
-  // Returns whatever trailers have been received for this stream.
-  const spdy::SpdyHeaderBlock& received_trailers() const {
-    return received_trailers_;
-  }
-
-  // Returns true if headers have been fully read and consumed.
-  bool FinishedReadingHeaders() const;
-
-  // Returns true if FIN has been received and either trailers have been fully
-  // read and consumed or there are no trailers.
-  bool FinishedReadingTrailers() const;
-
-  // Returns true if the sequencer has delivered the FIN, and no more body bytes
-  // will be available.
-  bool IsSequencerClosed() { return sequencer()->IsClosed(); }
-
-  // QpackDecodedHeadersAccumulator::Visitor implementation.
-  void OnHeadersDecoded(QuicHeaderList headers,
-                        bool header_list_size_limit_exceeded) override;
-  void OnHeaderDecodingError(QuicErrorCode error_code,
-                             absl::string_view error_message) override;
-
-  QuicSpdySession* spdy_session() const { return spdy_session_; }
-
-  // Send PRIORITY_UPDATE frame and update |last_sent_urgency_| if
-  // |last_sent_urgency_| is different from current priority.
-  void MaybeSendPriorityUpdateFrame() override;
-
-  // Returns the WebTransport session owned by this stream, if one exists.
-  WebTransportHttp3* web_transport() { return web_transport_.get(); }
-
-  // Returns the WebTransport data stream associated with this QUIC stream, or
-  // null if this is not a WebTransport data stream.
-  WebTransportStream* web_transport_stream() {
-    if (web_transport_data_ == nullptr) {
-      return nullptr;
-    }
-    return &web_transport_data_->adapter;
-  }
-
-  // Sends a WEBTRANSPORT_STREAM frame and sets up the appropriate metadata.
-  void ConvertToWebTransportDataStream(WebTransportSessionId session_id);
-
-  void OnCanWriteNewData() override;
-
-  // If this stream is a WebTransport data stream, closes the connection with an
-  // error, and returns false.
-  bool AssertNotWebTransportDataStream(absl::string_view operation);
-
-  // Indicates whether a call to WriteBodySlices will be successful and not
-  // rejected due to buffer being full.  |write_size| must be non-zero.
-  bool CanWriteNewBodyData(QuicByteCount write_size) const;
-
-  // From CapsuleParser::Visitor.
-  bool OnCapsule(const Capsule& capsule) override;
-  void OnCapsuleParseFailure(const std::string& error_message) override;
-
-  // Sends an HTTP/3 datagram. The stream and context IDs are not part of
-  // |payload|.
-  MessageStatus SendHttp3Datagram(
-      absl::optional<QuicDatagramContextId> context_id,
-      absl::string_view payload);
-
-  class QUIC_EXPORT_PRIVATE Http3DatagramVisitor {
-   public:
-    virtual ~Http3DatagramVisitor() {}
-
-    // Called when an HTTP/3 datagram is received. |payload| does not contain
-    // the stream or context IDs. Note that this contains the stream ID even if
-    // flow IDs from draft-ietf-masque-h3-datagram-00 are in use.
-    virtual void OnHttp3Datagram(
-        QuicStreamId stream_id,
-        absl::optional<QuicDatagramContextId> context_id,
-        absl::string_view payload) = 0;
-  };
-
-  class QUIC_EXPORT_PRIVATE Http3DatagramRegistrationVisitor {
-   public:
-    virtual ~Http3DatagramRegistrationVisitor() {}
-
-    // Called when a REGISTER_DATAGRAM_CONTEXT or REGISTER_DATAGRAM_NO_CONTEXT
-    // capsule is received. Note that this contains the stream ID even if flow
-    // IDs from draft-ietf-masque-h3-datagram-00 are in use.
-    virtual void OnContextReceived(
-        QuicStreamId stream_id,
-        absl::optional<QuicDatagramContextId> context_id,
-        DatagramFormatType format_type,
-        absl::string_view format_additional_data) = 0;
-
-    // Called when a CLOSE_DATAGRAM_CONTEXT capsule is received. Note that this
-    // contains the stream ID even if flow IDs from
-    // draft-ietf-masque-h3-datagram-00 are in use.
-    virtual void OnContextClosed(
-        QuicStreamId stream_id,
-        absl::optional<QuicDatagramContextId> context_id,
-        ContextCloseCode close_code, absl::string_view close_details) = 0;
-  };
-
-  // Registers |visitor| to receive HTTP/3 datagram context registrations. This
-  // must not be called without first calling
-  // UnregisterHttp3DatagramRegistrationVisitor. |visitor| must be valid until a
-  // corresponding call to UnregisterHttp3DatagramRegistrationVisitor.
-  void RegisterHttp3DatagramRegistrationVisitor(
-      Http3DatagramRegistrationVisitor* visitor,
-      bool use_datagram_contexts = false);
-
-  // Unregisters for HTTP/3 datagram context registrations. Must not be called
-  // unless previously registered.
-  void UnregisterHttp3DatagramRegistrationVisitor();
-
-  // Moves an HTTP/3 datagram registration to a different visitor. Mainly meant
-  // to be used by the visitors' move operators.
-  void MoveHttp3DatagramRegistration(Http3DatagramRegistrationVisitor* visitor);
-
-  // Registers |visitor| to receive HTTP/3 datagrams for optional context ID
-  // |context_id|. This must not be called on a previously registered context ID
-  // without first calling UnregisterHttp3DatagramContextId. |visitor| must be
-  // valid until a corresponding call to UnregisterHttp3DatagramContextId. If
-  // this method is called multiple times, the context ID MUST either be always
-  // present, or always absent.
-  void RegisterHttp3DatagramContextId(
-      absl::optional<QuicDatagramContextId> context_id,
-      DatagramFormatType format_type, absl::string_view format_additional_data,
-      Http3DatagramVisitor* visitor);
-
-  // Unregisters an HTTP/3 datagram context ID. Must be called on a previously
-  // registered context.
-  void UnregisterHttp3DatagramContextId(
-      absl::optional<QuicDatagramContextId> context_id);
-
-  // Moves an HTTP/3 datagram context ID to a different visitor. Mainly meant
-  // to be used by the visitors' move operators.
-  void MoveHttp3DatagramContextIdRegistration(
-      absl::optional<QuicDatagramContextId> context_id,
-      Http3DatagramVisitor* visitor);
-
-  // Sets max datagram time in queue.
-  void SetMaxDatagramTimeInQueue(QuicTime::Delta max_time_in_queue);
-
-  // Generates a new HTTP/3 datagram context ID for this stream. A datagram
-  // registration visitor must be currently registered on this stream.
-  QuicDatagramContextId GetNextDatagramContextId();
-
-  void OnDatagramReceived(QuicDataReader* reader);
-
-  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
-
-  QuicByteCount GetMaxDatagramSize(
-      absl::optional<QuicDatagramContextId> context_id) const;
-
-  // Writes |capsule| onto the DATA stream.
-  void WriteCapsule(const Capsule& capsule, bool fin = false);
-
-  void WriteGreaseCapsule();
-
- protected:
-  // Called when the received headers are too large. By default this will
-  // reset the stream.
-  virtual void OnHeadersTooLarge();
-
-  virtual void OnInitialHeadersComplete(bool fin, size_t frame_len,
-                                        const QuicHeaderList& header_list);
-  virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len,
-                                         const QuicHeaderList& header_list);
-  virtual size_t WriteHeadersImpl(
-      spdy::SpdyHeaderBlock header_block, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  Visitor* visitor() { return visitor_; }
-
-  void set_headers_decompressed(bool val) { headers_decompressed_ = val; }
-
-  void set_ack_listener(
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener) {
-    ack_listener_ = std::move(ack_listener);
-  }
-
-  void OnWriteSideInDataRecvdState() override;
-
-  virtual bool AreHeadersValid(const QuicHeaderList& header_list) const;
-
-  // Reset stream upon invalid request headers.
-  virtual void OnInvalidHeaders();
-
- private:
-  friend class test::QuicSpdyStreamPeer;
-  friend class test::QuicStreamPeer;
-  friend class QuicStreamUtils;
-  class HttpDecoderVisitor;
-
-  struct QUIC_EXPORT_PRIVATE WebTransportDataStream {
-    WebTransportDataStream(QuicSpdyStream* stream,
-                           WebTransportSessionId session_id);
-
-    WebTransportSessionId session_id;
-    WebTransportStreamAdapter adapter;
-  };
-
-  // Reason codes for `qpack_decoded_headers_accumulator_` being nullptr.
-  enum class QpackDecodedHeadersAccumulatorResetReason {
-    // `qpack_decoded_headers_accumulator_` was default constructed to nullptr.
-    kUnSet = 0,
-    // `qpack_decoded_headers_accumulator_` was reset in the corresponding
-    // method.
-    kResetInOnHeadersDecoded = 1,
-    kResetInOnHeaderDecodingError = 2,
-    kResetInOnStreamReset1 = 3,
-    kResetInOnStreamReset2 = 4,
-    kResetInResetWithError = 5,
-    kResetInOnClose = 6,
-  };
-
-  // Called by HttpDecoderVisitor.
-  bool OnDataFrameStart(QuicByteCount header_length,
-                        QuicByteCount payload_length);
-  bool OnDataFramePayload(absl::string_view payload);
-  bool OnDataFrameEnd();
-  bool OnHeadersFrameStart(QuicByteCount header_length,
-                           QuicByteCount payload_length);
-  bool OnHeadersFramePayload(absl::string_view payload);
-  bool OnHeadersFrameEnd();
-  void OnWebTransportStreamFrameType(QuicByteCount header_length,
-                                     WebTransportSessionId session_id);
-  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
-                           QuicByteCount payload_length);
-  bool OnUnknownFramePayload(absl::string_view payload);
-  bool OnUnknownFrameEnd();
-
-  // Given the interval marked by [|offset|, |offset| + |data_length|), return
-  // the number of frame header bytes contained in it.
-  QuicByteCount GetNumFrameHeadersInInterval(QuicStreamOffset offset,
-                                             QuicByteCount data_length) const;
-
-  void MaybeProcessSentWebTransportHeaders(spdy::SpdyHeaderBlock& headers);
-  void MaybeProcessReceivedWebTransportHeaders();
-
-  // Writes HTTP/3 DATA frame header. If |force_write| is true, use
-  // WriteOrBufferData if send buffer cannot accomodate the header + data.
-  ABSL_MUST_USE_RESULT bool WriteDataFrameHeader(QuicByteCount data_length,
-                                                 bool force_write);
-
-  // Simply calls OnBodyAvailable() unless capsules are in use, in which case
-  // pass the capsule fragments to the capsule manager.
-  void HandleBodyAvailable();
-
-  // Called when a datagram frame or capsule is received.
-  void HandleReceivedDatagram(absl::optional<QuicDatagramContextId> context_id,
-                              absl::string_view payload);
-
-  // Whether datagram contexts should be used on this stream.
-  bool ShouldUseDatagramContexts() const;
-
-  QuicSpdySession* spdy_session_;
-
-  bool on_body_available_called_because_sequencer_is_closed_;
-
-  Visitor* visitor_;
-
-  // True if read side processing is blocked while waiting for callback from
-  // QPACK decoder.
-  bool blocked_on_decoding_headers_;
-  // True if the headers have been completely decompressed.
-  bool headers_decompressed_;
-  // True if uncompressed headers or trailers exceed maximum allowed size
-  // advertised to peer via SETTINGS_MAX_HEADER_LIST_SIZE.
-  bool header_list_size_limit_exceeded_;
-  // Contains a copy of the decompressed header (name, value) pairs until they
-  // are consumed via Readv.
-  QuicHeaderList header_list_;
-  // Length of most recently received HEADERS frame payload.
-  QuicByteCount headers_payload_length_;
-
-  // True if the trailers have been completely decompressed.
-  bool trailers_decompressed_;
-  // True if the trailers have been consumed.
-  bool trailers_consumed_;
-
-  // The parsed trailers received from the peer.
-  spdy::SpdyHeaderBlock received_trailers_;
-
-  // Headers accumulator for decoding HEADERS frame payload.
-  std::unique_ptr<QpackDecodedHeadersAccumulator>
-      qpack_decoded_headers_accumulator_;
-  // Reason for `qpack_decoded_headers_accumulator_` being nullptr.
-  QpackDecodedHeadersAccumulatorResetReason
-      qpack_decoded_headers_accumulator_reset_reason_;
-  // Visitor of the HttpDecoder.
-  std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
-  // HttpDecoder for processing raw incoming stream frames.
-  HttpDecoder decoder_;
-  // Object that manages references to DATA frame payload fragments buffered by
-  // the sequencer and calculates how much data should be marked consumed with
-  // the sequencer each time new stream data is processed.
-  QuicSpdyStreamBodyManager body_manager_;
-
-  std::unique_ptr<CapsuleParser> capsule_parser_;
-
-  // Sequencer offset keeping track of how much data HttpDecoder has processed.
-  // Initial value is zero for fresh streams, or sequencer()->NumBytesConsumed()
-  // at time of construction if a PendingStream is converted to account for the
-  // length of the unidirectional stream type at the beginning of the stream.
-  QuicStreamOffset sequencer_offset_;
-
-  // True when inside an HttpDecoder::ProcessInput() call.
-  // Used for detecting reentrancy.
-  bool is_decoder_processing_input_;
-
-  // Ack listener of this stream, and it is notified when any of written bytes
-  // are acked or retransmitted.
-  quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
-
-  // Offset of unacked frame headers.
-  QuicIntervalSet<QuicStreamOffset> unacked_frame_headers_offsets_;
-
-  // Urgency value sent in the last PRIORITY_UPDATE frame, or default urgency
-  // defined by the spec if no PRIORITY_UPDATE frame has been sent.
-  int last_sent_urgency_;
-
-  // If this stream is a WebTransport extended CONNECT stream, contains the
-  // WebTransport session associated with this stream.
-  std::unique_ptr<WebTransportHttp3> web_transport_;
-
-  // If this stream is a WebTransport data stream, |web_transport_data_|
-  // contains all of the associated metadata.
-  std::unique_ptr<WebTransportDataStream> web_transport_data_;
-
-  // HTTP/3 Datagram support.
-  Http3DatagramRegistrationVisitor* datagram_registration_visitor_ = nullptr;
-  Http3DatagramVisitor* datagram_no_context_visitor_ = nullptr;
-  absl::optional<QuicDatagramStreamId> datagram_flow_id_;
-  QuicDatagramContextId datagram_next_available_context_id_;
-  absl::flat_hash_map<QuicDatagramContextId, Http3DatagramVisitor*>
-      datagram_context_visitors_;
-  bool use_datagram_contexts_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
diff --git a/quic/core/http/quic_spdy_stream_body_manager.cc b/quic/core/http/quic_spdy_stream_body_manager.cc
deleted file mode 100644
index 2ae24d4..0000000
--- a/quic/core/http/quic_spdy_stream_body_manager.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_stream_body_manager.h"
-
-#include <algorithm>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSpdyStreamBodyManager::QuicSpdyStreamBodyManager()
-    : total_body_bytes_received_(0) {}
-
-size_t QuicSpdyStreamBodyManager::OnNonBody(QuicByteCount length) {
-  QUICHE_DCHECK_NE(0u, length);
-
-  if (fragments_.empty()) {
-    // Non-body bytes can be consumed immediately, because all previously
-    // received body bytes have been read.
-    return length;
-  }
-
-  // Non-body bytes will be consumed after last body fragment is read.
-  fragments_.back().trailing_non_body_byte_count += length;
-  return 0;
-}
-
-void QuicSpdyStreamBodyManager::OnBody(absl::string_view body) {
-  QUICHE_DCHECK(!body.empty());
-
-  fragments_.push_back({body, 0});
-  total_body_bytes_received_ += body.length();
-}
-
-size_t QuicSpdyStreamBodyManager::OnBodyConsumed(size_t num_bytes) {
-  QuicByteCount bytes_to_consume = 0;
-  size_t remaining_bytes = num_bytes;
-
-  while (remaining_bytes > 0) {
-    if (fragments_.empty()) {
-      QUIC_BUG(quic_bug_10394_1) << "Not enough available body to consume.";
-      return 0;
-    }
-
-    Fragment& fragment = fragments_.front();
-    const absl::string_view body = fragment.body;
-
-    if (body.length() > remaining_bytes) {
-      // Consume leading |remaining_bytes| bytes of body.
-      bytes_to_consume += remaining_bytes;
-      fragment.body = body.substr(remaining_bytes);
-      return bytes_to_consume;
-    }
-
-    // Consume entire fragment and the following
-    // |trailing_non_body_byte_count| bytes.
-    remaining_bytes -= body.length();
-    bytes_to_consume += body.length() + fragment.trailing_non_body_byte_count;
-    fragments_.pop_front();
-  }
-
-  return bytes_to_consume;
-}
-
-int QuicSpdyStreamBodyManager::PeekBody(iovec* iov, size_t iov_len) const {
-  QUICHE_DCHECK(iov);
-  QUICHE_DCHECK_GT(iov_len, 0u);
-
-  // TODO(bnc): Is this really necessary?
-  if (fragments_.empty()) {
-    iov[0].iov_base = nullptr;
-    iov[0].iov_len = 0;
-    return 0;
-  }
-
-  size_t iov_filled = 0;
-  while (iov_filled < fragments_.size() && iov_filled < iov_len) {
-    absl::string_view body = fragments_[iov_filled].body;
-    iov[iov_filled].iov_base = const_cast<char*>(body.data());
-    iov[iov_filled].iov_len = body.size();
-    iov_filled++;
-  }
-
-  return iov_filled;
-}
-
-size_t QuicSpdyStreamBodyManager::ReadBody(const struct iovec* iov,
-                                           size_t iov_len,
-                                           size_t* total_bytes_read) {
-  *total_bytes_read = 0;
-  QuicByteCount bytes_to_consume = 0;
-
-  // The index of iovec to write to.
-  size_t index = 0;
-  // Address to write to within current iovec.
-  char* dest = reinterpret_cast<char*>(iov[index].iov_base);
-  // Remaining space in current iovec.
-  size_t dest_remaining = iov[index].iov_len;
-
-  while (!fragments_.empty()) {
-    Fragment& fragment = fragments_.front();
-    const absl::string_view body = fragment.body;
-
-    const size_t bytes_to_copy =
-        std::min<size_t>(body.length(), dest_remaining);
-    memcpy(dest, body.data(), bytes_to_copy);
-    bytes_to_consume += bytes_to_copy;
-    *total_bytes_read += bytes_to_copy;
-
-    if (bytes_to_copy == body.length()) {
-      // Entire fragment read.
-      bytes_to_consume += fragment.trailing_non_body_byte_count;
-      fragments_.pop_front();
-    } else {
-      // Consume leading |bytes_to_copy| bytes of body.
-      fragment.body = body.substr(bytes_to_copy);
-    }
-
-    if (bytes_to_copy == dest_remaining) {
-      // Current iovec full.
-      ++index;
-      if (index == iov_len) {
-        break;
-      }
-      dest = reinterpret_cast<char*>(iov[index].iov_base);
-      dest_remaining = iov[index].iov_len;
-    } else {
-      // Advance destination parameters within this iovec.
-      dest += bytes_to_copy;
-      dest_remaining -= bytes_to_copy;
-    }
-  }
-
-  return bytes_to_consume;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream_body_manager.h b/quic/core/http/quic_spdy_stream_body_manager.h
deleted file mode 100644
index 76b34ae..0000000
--- a/quic/core/http/quic_spdy_stream_body_manager.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
-#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_iovec.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// All data that a request stream receives falls into one of two categories:
-//  * "body", that is, DATA frame payload, which the QuicStreamSequencer must
-//    buffer until it is read;
-//  * everything else, which QuicSpdyStream immediately processes and thus could
-//    be marked as consumed with QuicStreamSequencer, unless there is some piece
-//    of body received prior that still needs to be buffered.
-// QuicSpdyStreamBodyManager does two things: it keeps references to body
-// fragments (owned by QuicStreamSequencer) and offers methods to read them; and
-// it calculates the total number of bytes (including non-body bytes) the caller
-// needs to mark consumed (with QuicStreamSequencer) when non-body bytes are
-// received or when body is consumed.
-class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager {
- public:
-  QuicSpdyStreamBodyManager();
-  ~QuicSpdyStreamBodyManager() = default;
-
-  // One of the following two methods must be called every time data is received
-  // on the request stream.
-
-  // Called when data that could immediately be marked consumed with the
-  // sequencer (provided that all previous body fragments are consumed) is
-  // received.  |length| must be positive.  Returns number of bytes the caller
-  // must mark consumed, which might be zero.
-  ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length);
-
-  // Called when body is received.  |body| is added to |fragments_|.  The data
-  // pointed to by |body| must be kept alive until an OnBodyConsumed() or
-  // ReadBody() call consumes it.  |body| must not be empty.
-  void OnBody(absl::string_view body);
-
-  // Internally marks |num_bytes| of body consumed.  |num_bytes| might be zero.
-  // Returns the number of bytes that the caller should mark consumed with the
-  // sequencer, which is the sum of |num_bytes| for body, and the number of any
-  // interleaving or immediately trailing non-body bytes.
-  ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes);
-
-  // Set up to |iov_len| elements of iov[] to point to available bodies: each
-  // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be
-  // set to its length.  No data is copied, no data is consumed.  Returns the
-  // number of iov set.
-  int PeekBody(iovec* iov, size_t iov_len) const;
-
-  // Copies data from available bodies into at most |iov_len| elements of iov[].
-  // Internally consumes copied body bytes as well as all interleaving and
-  // immediately trailing non-body bytes.  |iov.iov_base| and |iov.iov_len| are
-  // preassigned and will not be changed.  Returns the total number of bytes the
-  // caller shall mark consumed.  Sets |*total_bytes_read| to the total number
-  // of body bytes read.
-  ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov,
-                                       size_t iov_len,
-                                       size_t* total_bytes_read);
-
-  bool HasBytesToRead() const { return !fragments_.empty(); }
-
-  uint64_t total_body_bytes_received() const {
-    return total_body_bytes_received_;
-  }
-
- private:
-  // A Fragment instance represents a body fragment with a count of bytes
-  // received afterwards but before the next body fragment that can be marked
-  // consumed as soon as all of the body fragment is read.
-  struct QUIC_EXPORT_PRIVATE Fragment {
-    // |body| must not be empty.
-    absl::string_view body;
-    // Might be zero.
-    QuicByteCount trailing_non_body_byte_count;
-  };
-  // Queue of body fragments and trailing non-body byte counts.
-  quiche::QuicheCircularDeque<Fragment> fragments_;
-  // Total body bytes received.
-  QuicByteCount total_body_bytes_received_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
diff --git a/quic/core/http/quic_spdy_stream_body_manager_test.cc b/quic/core/http/quic_spdy_stream_body_manager_test.cc
deleted file mode 100644
index 90e50d4..0000000
--- a/quic/core/http/quic_spdy_stream_body_manager_test.cc
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_stream_body_manager.h"
-
-#include <algorithm>
-#include <numeric>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-class QuicSpdyStreamBodyManagerTest : public QuicTest {
- protected:
-  QuicSpdyStreamBodyManager body_manager_;
-};
-
-TEST_F(QuicSpdyStreamBodyManagerTest, HasBytesToRead) {
-  EXPECT_FALSE(body_manager_.HasBytesToRead());
-  EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
-
-  const QuicByteCount header_length = 3;
-  EXPECT_EQ(header_length, body_manager_.OnNonBody(header_length));
-
-  EXPECT_FALSE(body_manager_.HasBytesToRead());
-  EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
-
-  std::string body(1024, 'a');
-  body_manager_.OnBody(body);
-
-  EXPECT_TRUE(body_manager_.HasBytesToRead());
-  EXPECT_EQ(1024u, body_manager_.total_body_bytes_received());
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, ConsumeMoreThanAvailable) {
-  std::string body(1024, 'a');
-  body_manager_.OnBody(body);
-  size_t bytes_to_consume = 0;
-  EXPECT_QUIC_BUG(bytes_to_consume = body_manager_.OnBodyConsumed(2048),
-                  "Not enough available body to consume.");
-  EXPECT_EQ(0u, bytes_to_consume);
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, OnBodyConsumed) {
-  struct {
-    std::vector<QuicByteCount> frame_header_lengths;
-    std::vector<const char*> frame_payloads;
-    std::vector<QuicByteCount> body_bytes_to_read;
-    std::vector<QuicByteCount> expected_return_values;
-  } const kOnBodyConsumedTestData[] = {
-      // One frame consumed in one call.
-      {{2}, {"foobar"}, {6}, {6}},
-      // Two frames consumed in one call.
-      {{3, 5}, {"foobar", "baz"}, {9}, {14}},
-      // One frame consumed in two calls.
-      {{2}, {"foobar"}, {4, 2}, {4, 2}},
-      // Two frames consumed in two calls matching frame boundaries.
-      {{3, 5}, {"foobar", "baz"}, {6, 3}, {11, 3}},
-      // Two frames consumed in two calls,
-      // the first call only consuming part of the first frame.
-      {{3, 5}, {"foobar", "baz"}, {5, 4}, {5, 9}},
-      // Two frames consumed in two calls,
-      // the first call consuming the entire first frame and part of the second.
-      {{3, 5}, {"foobar", "baz"}, {7, 2}, {12, 2}},
-  };
-
-  for (size_t test_case_index = 0;
-       test_case_index < ABSL_ARRAYSIZE(kOnBodyConsumedTestData);
-       ++test_case_index) {
-    const std::vector<QuicByteCount>& frame_header_lengths =
-        kOnBodyConsumedTestData[test_case_index].frame_header_lengths;
-    const std::vector<const char*>& frame_payloads =
-        kOnBodyConsumedTestData[test_case_index].frame_payloads;
-    const std::vector<QuicByteCount>& body_bytes_to_read =
-        kOnBodyConsumedTestData[test_case_index].body_bytes_to_read;
-    const std::vector<QuicByteCount>& expected_return_values =
-        kOnBodyConsumedTestData[test_case_index].expected_return_values;
-
-    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
-         ++frame_index) {
-      // Frame header of first frame can immediately be consumed, but not the
-      // other frames.  Each test case start with an empty
-      // QuicSpdyStreamBodyManager.
-      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
-                body_manager_.OnNonBody(frame_header_lengths[frame_index]));
-      body_manager_.OnBody(frame_payloads[frame_index]);
-    }
-
-    for (size_t call_index = 0; call_index < body_bytes_to_read.size();
-         ++call_index) {
-      EXPECT_EQ(expected_return_values[call_index],
-                body_manager_.OnBodyConsumed(body_bytes_to_read[call_index]));
-    }
-
-    EXPECT_FALSE(body_manager_.HasBytesToRead());
-  }
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, PeekBody) {
-  struct {
-    std::vector<QuicByteCount> frame_header_lengths;
-    std::vector<const char*> frame_payloads;
-    size_t iov_len;
-  } const kPeekBodyTestData[] = {
-      // No frames, more iovecs than frames.
-      {{}, {}, 1},
-      // One frame, same number of iovecs.
-      {{3}, {"foobar"}, 1},
-      // One frame, more iovecs than frames.
-      {{3}, {"foobar"}, 2},
-      // Two frames, fewer iovecs than frames.
-      {{3, 5}, {"foobar", "baz"}, 1},
-      // Two frames, same number of iovecs.
-      {{3, 5}, {"foobar", "baz"}, 2},
-      // Two frames, more iovecs than frames.
-      {{3, 5}, {"foobar", "baz"}, 3},
-  };
-
-  for (size_t test_case_index = 0;
-       test_case_index < ABSL_ARRAYSIZE(kPeekBodyTestData); ++test_case_index) {
-    const std::vector<QuicByteCount>& frame_header_lengths =
-        kPeekBodyTestData[test_case_index].frame_header_lengths;
-    const std::vector<const char*>& frame_payloads =
-        kPeekBodyTestData[test_case_index].frame_payloads;
-    size_t iov_len = kPeekBodyTestData[test_case_index].iov_len;
-
-    QuicSpdyStreamBodyManager body_manager;
-
-    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
-         ++frame_index) {
-      // Frame header of first frame can immediately be consumed, but not the
-      // other frames.  Each test case uses a new QuicSpdyStreamBodyManager
-      // instance.
-      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
-                body_manager.OnNonBody(frame_header_lengths[frame_index]));
-      body_manager.OnBody(frame_payloads[frame_index]);
-    }
-
-    std::vector<iovec> iovecs;
-    iovecs.resize(iov_len);
-    size_t iovs_filled = std::min(frame_payloads.size(), iov_len);
-    ASSERT_EQ(iovs_filled,
-              static_cast<size_t>(body_manager.PeekBody(&iovecs[0], iov_len)));
-    for (size_t iovec_index = 0; iovec_index < iovs_filled; ++iovec_index) {
-      EXPECT_EQ(frame_payloads[iovec_index],
-                absl::string_view(
-                    static_cast<const char*>(iovecs[iovec_index].iov_base),
-                    iovecs[iovec_index].iov_len));
-    }
-  }
-}
-
-TEST_F(QuicSpdyStreamBodyManagerTest, ReadBody) {
-  struct {
-    std::vector<QuicByteCount> frame_header_lengths;
-    std::vector<const char*> frame_payloads;
-    std::vector<std::vector<QuicByteCount>> iov_lengths;
-    std::vector<QuicByteCount> expected_total_bytes_read;
-    std::vector<QuicByteCount> expected_return_values;
-  } const kReadBodyTestData[] = {
-      // One frame, one read with smaller iovec.
-      {{4}, {"foo"}, {{2}}, {2}, {2}},
-      // One frame, one read with same size iovec.
-      {{4}, {"foo"}, {{3}}, {3}, {3}},
-      // One frame, one read with larger iovec.
-      {{4}, {"foo"}, {{5}}, {3}, {3}},
-      // One frame, one read with two iovecs, smaller total size.
-      {{4}, {"foobar"}, {{2, 3}}, {5}, {5}},
-      // One frame, one read with two iovecs, same total size.
-      {{4}, {"foobar"}, {{2, 4}}, {6}, {6}},
-      // One frame, one read with two iovecs, larger total size in last iovec.
-      {{4}, {"foobar"}, {{2, 6}}, {6}, {6}},
-      // One frame, one read with extra iovecs, body ends at iovec boundary.
-      {{4}, {"foobar"}, {{2, 4, 4, 3}}, {6}, {6}},
-      // One frame, one read with extra iovecs, body ends not at iovec boundary.
-      {{4}, {"foobar"}, {{2, 7, 4, 3}}, {6}, {6}},
-      // One frame, two reads with two iovecs each, smaller total size.
-      {{4}, {"foobarbaz"}, {{2, 1}, {3, 2}}, {3, 5}, {3, 5}},
-      // One frame, two reads with two iovecs each, same total size.
-      {{4}, {"foobarbaz"}, {{2, 1}, {4, 2}}, {3, 6}, {3, 6}},
-      // One frame, two reads with two iovecs each, larger total size.
-      {{4}, {"foobarbaz"}, {{2, 1}, {4, 10}}, {3, 6}, {3, 6}},
-      // Two frames, one read with smaller iovec.
-      {{4, 3}, {"foobar", "baz"}, {{8}}, {8}, {11}},
-      // Two frames, one read with same size iovec.
-      {{4, 3}, {"foobar", "baz"}, {{9}}, {9}, {12}},
-      // Two frames, one read with larger iovec.
-      {{4, 3}, {"foobar", "baz"}, {{10}}, {9}, {12}},
-      // Two frames, one read with two iovecs, smaller total size.
-      {{4, 3}, {"foobar", "baz"}, {{4, 3}}, {7}, {10}},
-      // Two frames, one read with two iovecs, same total size.
-      {{4, 3}, {"foobar", "baz"}, {{4, 5}}, {9}, {12}},
-      // Two frames, one read with two iovecs, larger total size in last iovec.
-      {{4, 3}, {"foobar", "baz"}, {{4, 6}}, {9}, {12}},
-      // Two frames, one read with extra iovecs, body ends at iovec boundary.
-      {{4, 3}, {"foobar", "baz"}, {{4, 6, 4, 3}}, {9}, {12}},
-      // Two frames, one read with extra iovecs, body ends not at iovec
-      // boundary.
-      {{4, 3}, {"foobar", "baz"}, {{4, 7, 4, 3}}, {9}, {12}},
-      // Two frames, two reads with two iovecs each, reads end on frame
-      // boundary.
-      {{4, 3}, {"foobar", "baz"}, {{2, 4}, {2, 1}}, {6, 3}, {9, 3}},
-      // Three frames, three reads, extra iovecs, no iovec ends on frame
-      // boundary.
-      {{4, 3, 6},
-       {"foobar", "bazquux", "qux"},
-       {{4, 3}, {2, 3}, {5, 3}},
-       {7, 5, 4},
-       {10, 5, 10}},
-  };
-
-  for (size_t test_case_index = 0;
-       test_case_index < ABSL_ARRAYSIZE(kReadBodyTestData); ++test_case_index) {
-    const std::vector<QuicByteCount>& frame_header_lengths =
-        kReadBodyTestData[test_case_index].frame_header_lengths;
-    const std::vector<const char*>& frame_payloads =
-        kReadBodyTestData[test_case_index].frame_payloads;
-    const std::vector<std::vector<QuicByteCount>>& iov_lengths =
-        kReadBodyTestData[test_case_index].iov_lengths;
-    const std::vector<QuicByteCount>& expected_total_bytes_read =
-        kReadBodyTestData[test_case_index].expected_total_bytes_read;
-    const std::vector<QuicByteCount>& expected_return_values =
-        kReadBodyTestData[test_case_index].expected_return_values;
-
-    QuicSpdyStreamBodyManager body_manager;
-
-    std::string received_body;
-
-    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
-         ++frame_index) {
-      // Frame header of first frame can immediately be consumed, but not the
-      // other frames.  Each test case uses a new QuicSpdyStreamBodyManager
-      // instance.
-      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
-                body_manager.OnNonBody(frame_header_lengths[frame_index]));
-      body_manager.OnBody(frame_payloads[frame_index]);
-      received_body.append(frame_payloads[frame_index]);
-    }
-
-    std::string read_body;
-
-    for (size_t call_index = 0; call_index < iov_lengths.size(); ++call_index) {
-      // Allocate single buffer for iovecs.
-      size_t total_iov_length = std::accumulate(iov_lengths[call_index].begin(),
-                                                iov_lengths[call_index].end(),
-                                                static_cast<size_t>(0));
-      std::string buffer(total_iov_length, 'z');
-
-      // Construct iovecs pointing to contiguous areas in the buffer.
-      std::vector<iovec> iovecs;
-      size_t offset = 0;
-      for (size_t iov_length : iov_lengths[call_index]) {
-        QUICHE_CHECK(offset + iov_length <= buffer.size());
-        iovecs.push_back({&buffer[offset], iov_length});
-        offset += iov_length;
-      }
-
-      // Make sure |total_bytes_read| differs from |expected_total_bytes_read|.
-      size_t total_bytes_read = expected_total_bytes_read[call_index] + 12;
-      EXPECT_EQ(
-          expected_return_values[call_index],
-          body_manager.ReadBody(&iovecs[0], iovecs.size(), &total_bytes_read));
-      read_body.append(buffer.substr(0, total_bytes_read));
-    }
-
-    EXPECT_EQ(received_body.substr(0, read_body.size()), read_body);
-    EXPECT_EQ(read_body.size() < received_body.size(),
-              body_manager.HasBytesToRead());
-  }
-}
-
-}  // anonymous namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
deleted file mode 100644
index 88f049f..0000000
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ /dev/null
@@ -1,3456 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/quic_spdy_stream.h"
-
-#include <cstring>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_stream_sequencer_buffer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_mem_slice_storage.h"
-#include "common/simple_buffer_allocator.h"
-
-using spdy::kV3HighestPriority;
-using spdy::kV3LowestPriority;
-using spdy::SpdyHeaderBlock;
-using spdy::SpdyPriority;
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::DoAll;
-using testing::ElementsAre;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::MatchesRegex;
-using testing::Pair;
-using testing::Return;
-using testing::SaveArg;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const bool kShouldProcessData = true;
-const char kDataFramePayload[] = "some data";
-
-class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
- public:
-  explicit TestCryptoStream(QuicSession* session)
-      : QuicCryptoStream(session),
-        QuicCryptoHandshaker(this, session),
-        encryption_established_(false),
-        one_rtt_keys_available_(false),
-        params_(new QuicCryptoNegotiatedParameters) {
-    // Simulate a negotiated cipher_suite with a fake value.
-    params_->cipher_suite = 1;
-  }
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
-    encryption_established_ = true;
-    one_rtt_keys_available_ = true;
-    QuicErrorCode error;
-    std::string error_details;
-    session()->config()->SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    session()->config()->SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-    if (session()->version().UsesTls()) {
-      if (session()->perspective() == Perspective::IS_CLIENT) {
-        session()->config()->SetOriginalConnectionIdToSend(
-            session()->connection()->connection_id());
-        session()->config()->SetInitialSourceConnectionIdToSend(
-            session()->connection()->connection_id());
-      } else {
-        session()->config()->SetInitialSourceConnectionIdToSend(
-            session()->connection()->client_connection_id());
-      }
-      TransportParameters transport_parameters;
-      EXPECT_TRUE(
-          session()->config()->FillTransportParameters(&transport_parameters));
-      error = session()->config()->ProcessTransportParameters(
-          transport_parameters, /* is_resumption = */ false, &error_details);
-    } else {
-      CryptoHandshakeMessage msg;
-      session()->config()->ToHandshakeMessage(&msg, transport_version());
-      error =
-          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
-    }
-    EXPECT_THAT(error, IsQuicNoError());
-    session()->OnNewEncryptionKeyAvailable(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(session()->perspective()));
-    session()->OnConfigNegotiated();
-    if (session()->version().UsesTls()) {
-      session()->OnTlsHandshakeComplete();
-    } else {
-      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    }
-    if (session()->version().UsesTls()) {
-      // HANDSHAKE_DONE frame.
-      EXPECT_CALL(*this, HasPendingRetransmission());
-    }
-    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-  }
-
-  // QuicCryptoStream implementation
-  ssl_early_data_reason_t EarlyDataReason() const override {
-    return ssl_early_data_unknown;
-  }
-  bool encryption_established() const override {
-    return encryption_established_;
-  }
-  bool one_rtt_keys_available() const override {
-    return one_rtt_keys_available_;
-  }
-  HandshakeState GetHandshakeState() const override {
-    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-  }
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override {
-    return *params_;
-  }
-  CryptoMessageParser* crypto_message_parser() override {
-    return QuicCryptoHandshaker::crypto_message_parser();
-  }
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnConnectionClosed(QuicErrorCode /*error*/,
-                          ConnectionCloseSource /*source*/) override {}
-  void OnHandshakeDoneReceived() override {}
-  void OnNewTokenReceived(absl::string_view /*token*/) override {}
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_parameters*/)
-      const override {
-    return "";
-  }
-  bool ValidateAddressToken(absl::string_view /*token*/) const override {
-    return true;
-  }
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
-    return nullptr;
-  }
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters /*cached_network_params*/) override {}
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-
-  bool HasPendingCryptoRetransmission() const override { return false; }
-
-  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    return false;
-  }
-
-  SSL* GetSsl() const override { return nullptr; }
-
- private:
-  using QuicCryptoStream::session;
-
-  bool encryption_established_;
-  bool one_rtt_keys_available_;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-};
-
-class TestStream : public QuicSpdyStream {
- public:
-  TestStream(QuicStreamId id, QuicSpdySession* session,
-             bool should_process_data)
-      : QuicSpdyStream(id, session, BIDIRECTIONAL),
-        should_process_data_(should_process_data),
-        headers_payload_length_(0) {}
-  ~TestStream() override = default;
-
-  using QuicSpdyStream::set_ack_listener;
-  using QuicStream::CloseWriteSide;
-  using QuicStream::WriteOrBufferData;
-
-  void OnBodyAvailable() override {
-    if (!should_process_data_) {
-      return;
-    }
-    char buffer[2048];
-    struct iovec vec;
-    vec.iov_base = buffer;
-    vec.iov_len = ABSL_ARRAYSIZE(buffer);
-    size_t bytes_read = Readv(&vec, 1);
-    data_ += std::string(buffer, bytes_read);
-  }
-
-  MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
-
-  size_t WriteHeadersImpl(
-      spdy::SpdyHeaderBlock header_block, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-      /*ack_listener*/) override {
-    saved_headers_ = std::move(header_block);
-    WriteHeadersMock(fin);
-    if (VersionUsesHttp3(transport_version())) {
-      // In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
-      // actual work of closing the stream.
-      return QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin,
-                                              nullptr);
-    }
-    return 0;
-  }
-
-  const std::string& data() const { return data_; }
-  const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
-
-  // Expose protected accessor.
-  const QuicStreamSequencer* sequencer() const {
-    return QuicStream::sequencer();
-  }
-
-  void OnStreamHeaderList(bool fin, size_t frame_len,
-                          const QuicHeaderList& header_list) override {
-    headers_payload_length_ = frame_len;
-    QuicSpdyStream::OnStreamHeaderList(fin, frame_len, header_list);
-  }
-
-  size_t headers_payload_length() const { return headers_payload_length_; }
-
-  bool AreHeadersValid(const QuicHeaderList& header_list) const override {
-    return !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
-           QuicSpdyStream::AreHeadersValid(header_list);
-  }
-
- private:
-  bool should_process_data_;
-  spdy::SpdyHeaderBlock saved_headers_;
-  std::string data_;
-  size_t headers_payload_length_;
-};
-
-class TestSession : public MockQuicSpdySession {
- public:
-  explicit TestSession(QuicConnection* connection)
-      : MockQuicSpdySession(connection, /*create_mock_crypto_stream=*/false),
-        crypto_stream_(this) {}
-
-  TestCryptoStream* GetMutableCryptoStream() override {
-    return &crypto_stream_;
-  }
-
-  const TestCryptoStream* GetCryptoStream() const override {
-    return &crypto_stream_;
-  }
-
-  bool ShouldNegotiateWebTransport() override { return enable_webtransport_; }
-  void EnableWebTransport() { enable_webtransport_ = true; }
-
-  HttpDatagramSupport LocalHttpDatagramSupport() override {
-    return local_http_datagram_support_;
-  }
-  void set_local_http_datagram_support(HttpDatagramSupport value) {
-    local_http_datagram_support_ = value;
-  }
-
- private:
-  bool enable_webtransport_ = false;
-  HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
-  StrictMock<TestCryptoStream> crypto_stream_;
-};
-
-class TestMockUpdateStreamSession : public MockQuicSpdySession {
- public:
-  explicit TestMockUpdateStreamSession(QuicConnection* connection)
-      : MockQuicSpdySession(connection),
-        expected_precedence_(
-            spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority)) {}
-
-  void UpdateStreamPriority(
-      QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence) override {
-    EXPECT_EQ(id, expected_stream_->id());
-    EXPECT_EQ(expected_precedence_, precedence);
-    EXPECT_EQ(expected_precedence_, expected_stream_->precedence());
-  }
-
-  void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
-  void SetExpectedPriority(const spdy::SpdyStreamPrecedence& precedence) {
-    expected_precedence_ = precedence;
-  }
-
- private:
-  QuicSpdyStream* expected_stream_;
-  spdy::SpdyStreamPrecedence expected_precedence_;
-};
-
-class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicSpdyStreamTest() {
-    headers_[":host"] = "www.google.com";
-    headers_[":path"] = "/index.hml";
-    headers_[":scheme"] = "https";
-    headers_["cookie"] =
-        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
-        "__utmc=160408618; "
-        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
-        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
-        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
-        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
-        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
-        "1zFMi5vzcns38-8_Sns; "
-        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
-        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
-        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
-        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
-        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
-        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
-        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
-        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
-        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
-        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
-        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
-        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
-        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
-        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
-        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
-  }
-
-  ~QuicSpdyStreamTest() override = default;
-
-  // Return QPACK-encoded header block without using the dynamic table.
-  std::string EncodeQpackHeaders(
-      std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
-    SpdyHeaderBlock header_block;
-    for (const auto& header_field : headers) {
-      header_block.AppendValueOrAddHeader(header_field.first,
-                                          header_field.second);
-    }
-
-    return EncodeQpackHeaders(header_block);
-  }
-
-  // Return QPACK-encoded header block without using the dynamic table.
-  std::string EncodeQpackHeaders(const SpdyHeaderBlock& header) {
-    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
-    auto qpack_encoder = std::make_unique<QpackEncoder>(session_.get());
-    qpack_encoder->set_qpack_stream_sender_delegate(
-        &encoder_stream_sender_delegate);
-    // QpackEncoder does not use the dynamic table by default,
-    // therefore the value of |stream_id| does not matter.
-    return qpack_encoder->EncodeHeaderList(/* stream_id = */ 0, header,
-                                           nullptr);
-  }
-
-  void Initialize(bool stream_should_process_data) {
-    InitializeWithPerspective(stream_should_process_data,
-                              Perspective::IS_SERVER);
-  }
-
-  void InitializeWithPerspective(bool stream_should_process_data,
-                                 Perspective perspective) {
-    connection_ = new StrictMock<MockQuicConnection>(
-        &helper_, &alarm_factory_, perspective, SupportedVersions(GetParam()));
-    session_ = std::make_unique<StrictMock<TestSession>>(connection_);
-    EXPECT_CALL(*session_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    session_->Initialize();
-    if (connection_->version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(connection_);
-    }
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    ON_CALL(*session_, WritevData(_, _, _, _, _, _))
-        .WillByDefault(
-            Invoke(session_.get(), &MockQuicSpdySession::ConsumeData));
-
-    stream_ =
-        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
-                                   session_.get(), stream_should_process_data);
-    session_->ActivateStream(absl::WrapUnique(stream_));
-    stream2_ =
-        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
-                                   session_.get(), stream_should_process_data);
-    session_->ActivateStream(absl::WrapUnique(stream2_));
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
-    session_->OnConfigNegotiated();
-    if (UsesHttp3()) {
-      // The control stream will write the stream type, a greased frame, and
-      // SETTINGS frame.
-      int num_control_stream_writes = 3;
-      auto send_control_stream =
-          QuicSpdySessionPeer::GetSendControlStream(session_.get());
-      EXPECT_CALL(*session_,
-                  WritevData(send_control_stream->id(), _, _, _, _, _))
-          .Times(num_control_stream_writes);
-    }
-    TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission()).Times(AnyNumber());
-
-    if (connection_->version().UsesTls() &&
-        session_->perspective() == Perspective::IS_SERVER) {
-      // HANDSHAKE_DONE frame.
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .WillOnce(Invoke(&ClearControlFrame));
-    }
-    CryptoHandshakeMessage message;
-    session_->GetMutableCryptoStream()->OnHandshakeMessage(message);
-  }
-
-  QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
-    QuicHeaderList h = AsHeaderList(headers);
-    stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
-    return h;
-  }
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return GetNthClientInitiatedBidirectionalStreamId(
-        connection_->transport_version(), n);
-  }
-
-  bool UsesHttp3() const {
-    return VersionUsesHttp3(GetParam().transport_version);
-  }
-
-  // Construct HEADERS frame with QPACK-encoded |headers| without using the
-  // dynamic table.
-  std::string HeadersFrame(
-      std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
-    return HeadersFrame(EncodeQpackHeaders(headers));
-  }
-
-  // Construct HEADERS frame with QPACK-encoded |headers| without using the
-  // dynamic table.
-  std::string HeadersFrame(const SpdyHeaderBlock& headers) {
-    return HeadersFrame(EncodeQpackHeaders(headers));
-  }
-
-  // Construct HEADERS frame with given payload.
-  std::string HeadersFrame(absl::string_view payload) {
-    std::unique_ptr<char[]> headers_buffer;
-    QuicByteCount headers_frame_header_length =
-        HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
-                                                 &headers_buffer);
-    absl::string_view headers_frame_header(headers_buffer.get(),
-                                           headers_frame_header_length);
-    return absl::StrCat(headers_frame_header, payload);
-  }
-
-  std::string DataFrame(absl::string_view payload) {
-    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-        payload.length(), quiche::SimpleBufferAllocator::Get());
-    return absl::StrCat(header.AsStringView(), payload);
-  }
-
-  std::string UnknownFrame(uint64_t frame_type, absl::string_view payload) {
-    std::string frame;
-    const size_t length = QuicDataWriter::GetVarInt62Len(frame_type) +
-                          QuicDataWriter::GetVarInt62Len(payload.size()) +
-                          payload.size();
-    frame.resize(length);
-
-    QuicDataWriter writer(length, const_cast<char*>(frame.data()));
-    writer.WriteVarInt62(frame_type);
-    writer.WriteStringPieceVarInt62(payload);
-    // Even though integers can be encoded with different lengths,
-    // QuicDataWriter is expected to produce an encoding in Write*() of length
-    // promised in GetVarInt62Len().
-    QUICHE_DCHECK_EQ(length, writer.length());
-
-    return frame;
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnection* connection_;
-  std::unique_ptr<TestSession> session_;
-
-  // Owned by the |session_|.
-  TestStream* stream_;
-  TestStream* stream2_;
-
-  SpdyHeaderBlock headers_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
-  Initialize(kShouldProcessData);
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  ProcessHeaders(false, headers_);
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
-  Initialize(kShouldProcessData);
-
-  if (!UsesHttp3()) {
-    QuicHeaderList headers;
-    stream_->OnStreamHeadersPriority(
-        spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
-    EXPECT_CALL(
-        *session_,
-        MaybeSendRstStreamFrame(
-            stream_->id(),
-            QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
-    stream_->OnStreamHeaderList(false, 1 << 20, headers);
-
-    EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
-
-    return;
-  }
-
-  // Header list size includes 32 bytes for overhead per header field.
-  session_->set_max_inbound_header_list_size(40);
-  std::string headers =
-      HeadersFrame({std::make_pair("foo", "too long headers")});
-
-  QuicStreamFrame frame(stream_->id(), false, 0, headers);
-
-  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
-                             stream_->id(), QuicResetStreamError::FromInternal(
-                                                QUIC_HEADERS_TOO_LARGE)));
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          stream_->id(),
-          QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
-
-  auto qpack_decoder_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-  // Stream type and stream cancellation.
-  EXPECT_CALL(*session_,
-              WritevData(qpack_decoder_stream->id(), _, _, NO_FIN, _, _))
-      .Times(2);
-
-  stream_->OnStreamFrame(frame);
-  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
-}
-
-TEST_P(QuicSpdyStreamTest, QpackProcessLargeHeaderListDiscountOverhead) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  // Setting this flag to false causes no per-entry overhead to be included
-  // in the header size.
-  SetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead, false);
-  Initialize(kShouldProcessData);
-  session_->set_max_inbound_header_list_size(40);
-  std::string headers =
-      HeadersFrame({std::make_pair("foo", "too long headers")});
-
-  QuicStreamFrame frame(stream_->id(), false, 0, headers);
-  stream_->OnStreamFrame(frame);
-  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_NO_ERROR));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
-  Initialize(kShouldProcessData);
-
-  size_t total_bytes = 0;
-  QuicHeaderList headers;
-  for (auto p : headers_) {
-    headers.OnHeader(p.first, p.second);
-    total_bytes += p.first.size() + p.second.size();
-  }
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  stream_->OnStreamHeaderList(true, total_bytes, headers);
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-// A valid status code should be 3-digit integer. The first digit should be in
-// the range of [1, 5]. All the others are invalid.
-TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
-  Initialize(kShouldProcessData);
-  int status_code = 0;
-
-  // Valid status codes.
-  headers_[":status"] = "404";
-  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-  EXPECT_EQ(404, status_code);
-
-  headers_[":status"] = "100";
-  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-  EXPECT_EQ(100, status_code);
-
-  headers_[":status"] = "599";
-  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-  EXPECT_EQ(599, status_code);
-
-  // Invalid status codes.
-  headers_[":status"] = "010";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "600";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "200 ok";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "2000";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "+200";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "+20";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "-10";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "-100";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  // Leading or trailing spaces are also invalid.
-  headers_[":status"] = " 200";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "200 ";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = " 200 ";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-
-  headers_[":status"] = "  ";
-  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
-}
-
-TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
-  Initialize(kShouldProcessData);
-
-  std::string body = "this is the body";
-  QuicHeaderList headers = ProcessHeaders(false, headers_);
-  EXPECT_EQ(headers, stream_->header_list());
-
-  stream_->ConsumeHeaderList();
-  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  GoAwayFrame goaway;
-  goaway.id = 0x1;
-  std::unique_ptr<char[]> buffer;
-  QuicByteCount header_length =
-      HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
-  std::string data = std::string(buffer.get(), header_length);
-
-  EXPECT_EQ("", stream_->data());
-  QuicHeaderList headers = ProcessHeaders(false, headers_);
-  EXPECT_EQ(headers, stream_->header_list());
-  stream_->ConsumeHeaderList();
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
-      .WillOnce(
-          (Invoke([this](QuicErrorCode error, const std::string& error_details,
-                         ConnectionCloseBehavior connection_close_behavior) {
-            connection_->ReallyCloseConnection(error, error_details,
-                                               connection_close_behavior);
-          })));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(*session_, OnConnectionClosed(_, _))
-      .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
-                              ConnectionCloseSource source) {
-        session_->ReallyOnConnectionClosed(frame, source);
-      }));
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
-
-  stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdyStreamTest, Http3FrameError) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // PUSH_PROMISE frame with empty payload is considered invalid.
-  std::string invalid_http3_frame = absl::HexStringToBytes("0500");
-  QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
-                               /* offset = */ 0, invalid_http3_frame);
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _));
-  stream_->OnStreamFrame(stream_frame);
-}
-
-TEST_P(QuicSpdyStreamTest, UnexpectedHttp3Frame) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // SETTINGS frame with empty payload.
-  std::string settings = absl::HexStringToBytes("0400");
-  QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
-                               /* offset = */ 0, settings);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _));
-  stream_->OnStreamFrame(stream_frame);
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
-  Initialize(kShouldProcessData);
-
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  EXPECT_EQ("", stream_->data());
-  QuicHeaderList headers = ProcessHeaders(false, headers_);
-  EXPECT_EQ(headers, stream_->header_list());
-  stream_->ConsumeHeaderList();
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  stream_->OnStreamFrame(frame);
-  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
-  EXPECT_EQ(body, stream_->data());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
-    Initialize(kShouldProcessData);
-    QuicHeaderList headers = ProcessHeaders(false, headers_);
-    ASSERT_EQ(headers, stream_->header_list());
-    stream_->ConsumeHeaderList();
-    for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
-      size_t remaining_data = data.size() - offset;
-      absl::string_view fragment(data.data() + offset,
-                                 std::min(fragment_size, remaining_data));
-      QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
-                            offset, absl::string_view(fragment));
-      stream_->OnStreamFrame(frame);
-    }
-    ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
-  }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
-    Initialize(kShouldProcessData);
-    QuicHeaderList headers = ProcessHeaders(false, headers_);
-    ASSERT_EQ(headers, stream_->header_list());
-    stream_->ConsumeHeaderList();
-
-    absl::string_view fragment1(data.data(), split_point);
-    QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                           absl::string_view(fragment1));
-    stream_->OnStreamFrame(frame1);
-
-    absl::string_view fragment2(data.data() + split_point,
-                                data.size() - split_point);
-    QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
-                           split_point, absl::string_view(fragment2));
-    stream_->OnStreamFrame(frame2);
-
-    ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
-  }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
-  Initialize(!kShouldProcessData);
-
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  ProcessHeaders(false, headers_);
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  stream_->OnStreamFrame(frame);
-  stream_->ConsumeHeaderList();
-
-  char buffer[2048];
-  ASSERT_LT(data.length(), ABSL_ARRAYSIZE(buffer));
-  struct iovec vec;
-  vec.iov_base = buffer;
-  vec.iov_len = ABSL_ARRAYSIZE(buffer);
-
-  size_t bytes_read = stream_->Readv(&vec, 1);
-  QuicStreamPeer::CloseReadSide(stream_);
-  EXPECT_EQ(body.length(), bytes_read);
-  EXPECT_EQ(body, std::string(buffer, bytes_read));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
-  Initialize(kShouldProcessData);
-  std::string body(12 * 1024, 'a');
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  ProcessHeaders(false, headers_);
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  stream_->OnStreamFrame(frame);
-  stream_->ConsumeHeaderList();
-  char buffer[2048];
-  char buffer2[2048];
-  struct iovec vec[2];
-  vec[0].iov_base = buffer;
-  vec[0].iov_len = ABSL_ARRAYSIZE(buffer);
-  vec[1].iov_base = buffer2;
-  vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
-  size_t bytes_read = stream_->Readv(vec, 2);
-  EXPECT_EQ(2048u * 2, bytes_read);
-  EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
-  EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
-  Initialize(!kShouldProcessData);
-
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  ProcessHeaders(false, headers_);
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  stream_->OnStreamFrame(frame);
-  stream_->ConsumeHeaderList();
-
-  struct iovec vec;
-
-  EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
-  EXPECT_EQ(body.length(), vec.iov_len);
-  EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
-
-  stream_->MarkConsumed(body.length());
-  EXPECT_EQ(data.length(), QuicStreamPeer::bytes_consumed(stream_));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
-  Initialize(!kShouldProcessData);
-  std::string body1 = "this is body 1";
-  std::string data1 = UsesHttp3() ? DataFrame(body1) : body1;
-  std::string body2 = "body 2";
-  std::string data2 = UsesHttp3() ? DataFrame(body2) : body2;
-
-  ProcessHeaders(false, headers_);
-  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                         absl::string_view(data1));
-  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
-                         data1.length(), absl::string_view(data2));
-  stream_->OnStreamFrame(frame1);
-  stream_->OnStreamFrame(frame2);
-  stream_->ConsumeHeaderList();
-
-  stream_->MarkConsumed(body1.length() + body2.length());
-  EXPECT_EQ(data1.length() + data2.length(),
-            QuicStreamPeer::bytes_consumed(stream_));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
-  Initialize(!kShouldProcessData);
-
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  ProcessHeaders(false, headers_);
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  stream_->OnStreamFrame(frame);
-  stream_->ConsumeHeaderList();
-
-  char buffer[1];
-  struct iovec vec;
-  vec.iov_base = buffer;
-  vec.iov_len = ABSL_ARRAYSIZE(buffer);
-
-  for (size_t i = 0; i < body.length(); ++i) {
-    size_t bytes_read = stream_->Readv(&vec, 1);
-    ASSERT_EQ(1u, bytes_read);
-    EXPECT_EQ(body.data()[i], buffer[0]);
-  }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
-  Initialize(!kShouldProcessData);
-
-  std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  ProcessHeaders(false, headers_);
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  stream_->OnStreamFrame(frame);
-  stream_->ConsumeHeaderList();
-
-  char buffer1[1];
-  char buffer2[1];
-  struct iovec vec[2];
-  vec[0].iov_base = buffer1;
-  vec[0].iov_len = ABSL_ARRAYSIZE(buffer1);
-  vec[1].iov_base = buffer2;
-  vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
-
-  for (size_t i = 0; i < body.length(); i += 2) {
-    size_t bytes_read = stream_->Readv(vec, 2);
-    ASSERT_EQ(2u, bytes_read) << i;
-    ASSERT_EQ(body.data()[i], buffer1[0]) << i;
-    ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
-  }
-}
-
-// Tests that we send a BLOCKED frame to the peer when we attempt to write, but
-// are flow control blocked.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
-  Initialize(kShouldProcessData);
-  testing::InSequence seq;
-
-  // Set a small flow control limit.
-  const uint64_t kWindow = 36;
-  QuicStreamPeer::SetSendWindowOffset(stream_, kWindow);
-  EXPECT_EQ(kWindow, QuicStreamPeer::SendWindowOffset(stream_));
-
-  // Try to send more data than the flow control limit allows.
-  const uint64_t kOverflow = 15;
-  std::string body(kWindow + kOverflow, 'a');
-
-  const uint64_t kHeaderLength = UsesHttp3() ? 2 : 0;
-  if (UsesHttp3()) {
-    EXPECT_CALL(*session_, WritevData(_, kHeaderLength, _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
-  EXPECT_CALL(*session_, SendBlocked(_));
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  stream_->WriteOrBufferBody(body, false);
-
-  // Should have sent as much as possible, resulting in no send window left.
-  EXPECT_EQ(0u, QuicStreamPeer::SendWindowSize(stream_));
-
-  // And we should have queued the overflowed data.
-  EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes());
-}
-
-// The flow control receive window decreases whenever we add new bytes to the
-// sequencer, whether they are consumed immediately or buffered. However we only
-// send WINDOW_UPDATE frames based on increasing number of bytes consumed.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
-  // Don't process data - it will be buffered instead.
-  Initialize(!kShouldProcessData);
-
-  // Expect no WINDOW_UPDATE frames to be sent.
-  EXPECT_CALL(*session_, SendWindowUpdate(_, _)).Times(0);
-
-  // Set a small flow control receive window.
-  const uint64_t kWindow = 36;
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
-  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
-
-  // Stream receives enough data to fill a fraction of the receive window.
-  std::string body(kWindow / 3, 'a');
-  QuicByteCount header_length = 0;
-  std::string data;
-
-  if (UsesHttp3()) {
-    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-        body.length(), quiche::SimpleBufferAllocator::Get());
-    data = absl::StrCat(header.AsStringView(), body);
-    header_length = header.size();
-  } else {
-    data = body;
-  }
-
-  ProcessHeaders(false, headers_);
-
-  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                         absl::string_view(data));
-  stream_->OnStreamFrame(frame1);
-  EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
-            QuicStreamPeer::ReceiveWindowSize(stream_));
-
-  // Now receive another frame which results in the receive window being over
-  // half full. This should all be buffered, decreasing the receive window but
-  // not sending WINDOW_UPDATE.
-  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
-                         kWindow / 3 + header_length, absl::string_view(data));
-  stream_->OnStreamFrame(frame2);
-  EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length,
-            QuicStreamPeer::ReceiveWindowSize(stream_));
-}
-
-// Tests that on receipt of data, the stream updates its receive window offset
-// appropriately, and sends WINDOW_UPDATE frames when its receive window drops
-// too low.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
-  Initialize(kShouldProcessData);
-
-  // Set a small flow control limit.
-  const uint64_t kWindow = 36;
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
-  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
-
-  // Stream receives enough data to fill a fraction of the receive window.
-  std::string body(kWindow / 3, 'a');
-  QuicByteCount header_length = 0;
-  std::string data;
-
-  if (UsesHttp3()) {
-    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-        body.length(), quiche::SimpleBufferAllocator::Get());
-    data = absl::StrCat(header.AsStringView(), body);
-    header_length = header.size();
-  } else {
-    data = body;
-  }
-
-  ProcessHeaders(false, headers_);
-  stream_->ConsumeHeaderList();
-
-  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                         absl::string_view(data));
-  stream_->OnStreamFrame(frame1);
-  EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
-            QuicStreamPeer::ReceiveWindowSize(stream_));
-
-  // Now receive another frame which results in the receive window being over
-  // half full.  This will trigger the stream to increase its receive window
-  // offset and send a WINDOW_UPDATE. The result will be again an available
-  // window of kWindow bytes.
-  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
-                         kWindow / 3 + header_length, absl::string_view(data));
-  EXPECT_CALL(*session_, SendWindowUpdate(_, _));
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  stream_->OnStreamFrame(frame2);
-  EXPECT_EQ(kWindow, QuicStreamPeer::ReceiveWindowSize(stream_));
-}
-
-// Tests that on receipt of data, the connection updates its receive window
-// offset appropriately, and sends WINDOW_UPDATE frames when its receive window
-// drops too low.
-TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
-  Initialize(kShouldProcessData);
-
-  // Set a small flow control limit for streams and connection.
-  const uint64_t kWindow = 36;
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
-  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
-  QuicStreamPeer::SetReceiveWindowOffset(stream2_, kWindow);
-  QuicStreamPeer::SetMaxReceiveWindow(stream2_, kWindow);
-  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
-                                                 kWindow);
-  QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
-                                              kWindow);
-
-  // Supply headers to both streams so that they are happy to receive data.
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  stream_->ConsumeHeaderList();
-  stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                               headers);
-  stream2_->ConsumeHeaderList();
-
-  // Each stream gets a quarter window of data. This should not trigger a
-  // WINDOW_UPDATE for either stream, nor for the connection.
-  QuicByteCount header_length = 0;
-  std::string body;
-  std::string data;
-  std::string data2;
-  std::string body2(1, 'a');
-
-  if (UsesHttp3()) {
-    body = std::string(kWindow / 4 - 2, 'a');
-    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-        body.length(), quiche::SimpleBufferAllocator::Get());
-    data = absl::StrCat(header.AsStringView(), body);
-    header_length = header.size();
-    quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
-        body.length(), quiche::SimpleBufferAllocator::Get());
-    data2 = absl::StrCat(header2.AsStringView(), body2);
-  } else {
-    body = std::string(kWindow / 4, 'a');
-    data = body;
-    data2 = body2;
-  }
-
-  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                         absl::string_view(data));
-  stream_->OnStreamFrame(frame1);
-  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
-                         absl::string_view(data));
-  stream2_->OnStreamFrame(frame2);
-
-  // Now receive a further single byte on one stream - again this does not
-  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
-  // is over half full and thus a connection WINDOW_UPDATE is sent.
-  EXPECT_CALL(*session_, SendWindowUpdate(_, _));
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
-                         body.length() + header_length,
-                         absl::string_view(data2));
-  stream_->OnStreamFrame(frame3);
-}
-
-// Tests that on if the peer sends too much data (i.e. violates the flow control
-// protocol), then we terminate the connection.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
-  // Stream should not process data, so that data gets buffered in the
-  // sequencer, triggering flow control limits.
-  Initialize(!kShouldProcessData);
-
-  // Set a small flow control limit.
-  const uint64_t kWindow = 50;
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
-
-  ProcessHeaders(false, headers_);
-
-  // Receive data to overflow the window, violating flow control.
-  std::string body(kWindow + 1, 'a');
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
-  Initialize(kShouldProcessData);
-  ProcessHeaders(false, headers_);
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
-
-  stream_->OnStreamReset(QuicRstStreamFrame(
-      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
-
-  if (GetQuicReloadableFlag(quic_fix_on_stream_reset) && UsesHttp3()) {
-    // RESET_STREAM should close the read side but not the write side.
-    EXPECT_TRUE(stream_->read_side_closed());
-    EXPECT_FALSE(stream_->write_side_closed());
-  } else {
-    EXPECT_TRUE(stream_->write_side_closed());
-    EXPECT_FALSE(stream_->reading_stopped());
-  }
-}
-
-// Tests that on if the peer sends too much data (i.e. violates the flow control
-// protocol), at the connection level (rather than the stream level) then we
-// terminate the connection.
-TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
-  // Stream should not process data, so that data gets buffered in the
-  // sequencer, triggering flow control limits.
-  Initialize(!kShouldProcessData);
-
-  // Set a small flow control window on streams, and connection.
-  const uint64_t kStreamWindow = 50;
-  const uint64_t kConnectionWindow = 10;
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, kStreamWindow);
-  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
-                                                 kConnectionWindow);
-
-  ProcessHeaders(false, headers_);
-
-  // Send enough data to overflow the connection level flow control window.
-  std::string body(kConnectionWindow + 1, 'a');
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  EXPECT_LT(data.size(), kStreamWindow);
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        absl::string_view(data));
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  stream_->OnStreamFrame(frame);
-}
-
-// An attempt to write a FIN with no data should not be flow control blocked,
-// even if the send window is 0.
-TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
-  Initialize(kShouldProcessData);
-
-  // Set a flow control limit of zero.
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, 0);
-
-  // Send a frame with a FIN but no data. This should not be blocked.
-  std::string body = "";
-  bool fin = true;
-
-  EXPECT_CALL(*session_, SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
-      .Times(0);
-  EXPECT_CALL(*session_, WritevData(_, 0, _, FIN, _, _));
-
-  stream_->WriteOrBufferBody(body, fin);
-}
-
-// Test that receiving trailing headers from the peer via OnStreamHeaderList()
-// works, and can be read from the stream and consumed.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
-  Initialize(kShouldProcessData);
-
-  // Receive initial headers.
-  size_t total_bytes = 0;
-  QuicHeaderList headers;
-  for (const auto& p : headers_) {
-    headers.OnHeader(p.first, p.second);
-    total_bytes += p.first.size() + p.second.size();
-  }
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
-  stream_->ConsumeHeaderList();
-
-  // Receive trailing headers.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["key1"] = "value1";
-  trailers_block["key2"] = "value2";
-  trailers_block["key3"] = "value3";
-  SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
-  if (!UsesHttp3()) {
-    // :final-offset pseudo-header is only added if trailers are sent
-    // on the headers stream.
-    trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
-  }
-  total_bytes = 0;
-  QuicHeaderList trailers;
-  for (const auto& p : trailers_block_with_final_offset) {
-    trailers.OnHeader(p.first, p.second);
-    total_bytes += p.first.size() + p.second.size();
-  }
-  stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
-
-  // The trailers should be decompressed, and readable from the stream.
-  EXPECT_TRUE(stream_->trailers_decompressed());
-  EXPECT_EQ(trailers_block, stream_->received_trailers());
-
-  // IsDoneReading() returns false until trailers marked consumed.
-  EXPECT_FALSE(stream_->IsDoneReading());
-  stream_->MarkTrailersConsumed();
-  EXPECT_TRUE(stream_->IsDoneReading());
-}
-
-// Test that when receiving trailing headers with an offset before response
-// body, stream is closed at the right offset.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
-  // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
-  // request/response stream.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Receive initial headers.
-  QuicHeaderList headers = ProcessHeaders(false, headers_);
-  stream_->ConsumeHeaderList();
-
-  const std::string body = "this is the body";
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  // Receive trailing headers.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["key1"] = "value1";
-  trailers_block["key2"] = "value2";
-  trailers_block["key3"] = "value3";
-  trailers_block[kFinalOffsetHeaderKey] = absl::StrCat(data.size());
-
-  QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
-
-  // The trailers should be decompressed, and readable from the stream.
-  EXPECT_TRUE(stream_->trailers_decompressed());
-
-  // The final offset trailer will be consumed by QUIC.
-  trailers_block.erase(kFinalOffsetHeaderKey);
-  EXPECT_EQ(trailers_block, stream_->received_trailers());
-
-  // Consuming the trailers erases them from the stream.
-  stream_->MarkTrailersConsumed();
-  EXPECT_TRUE(stream_->FinishedReadingTrailers());
-
-  EXPECT_FALSE(stream_->IsDoneReading());
-  // Receive and consume body.
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
-                        0, data);
-  stream_->OnStreamFrame(frame);
-  EXPECT_EQ(body, stream_->data());
-  EXPECT_TRUE(stream_->IsDoneReading());
-}
-
-// Test that receiving trailers without a final offset field is an error.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
-  // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
-  // request/response stream.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Receive initial headers.
-  ProcessHeaders(false, headers_);
-  stream_->ConsumeHeaderList();
-
-  // Receive trailing headers, without kFinalOffsetHeaderKey.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["key1"] = "value1";
-  trailers_block["key2"] = "value2";
-  trailers_block["key3"] = "value3";
-  auto trailers = AsHeaderList(trailers_block);
-
-  // Verify that the trailers block didn't contain a final offset.
-  EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
-
-  // Receipt of the malformed trailers will close the connection.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
-      .Times(1);
-  stream_->OnStreamHeaderList(/*fin=*/true,
-                              trailers.uncompressed_header_bytes(), trailers);
-}
-
-// Test that received Trailers must always have the FIN set.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
-  // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
-  // HEADERS frame.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Receive initial headers.
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(/*fin=*/false,
-                              headers.uncompressed_header_bytes(), headers);
-  stream_->ConsumeHeaderList();
-
-  // Receive trailing headers with FIN deliberately set to false.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["foo"] = "bar";
-  auto trailers = AsHeaderList(trailers_block);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
-      .Times(1);
-  stream_->OnStreamHeaderList(/*fin=*/false,
-                              trailers.uncompressed_header_bytes(), trailers);
-}
-
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
-  // If headers are received with a FIN, no trailers should then arrive.
-  Initialize(kShouldProcessData);
-
-  // If HEADERS frames are sent on the request/response stream, then the
-  // sequencer will signal an error if any stream data arrives after a FIN,
-  // so QuicSpdyStream does not need to.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  // Receive initial headers with FIN set.
-  ProcessHeaders(true, headers_);
-  stream_->ConsumeHeaderList();
-
-  // Receive trailing headers after FIN already received.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["foo"] = "bar";
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
-      .Times(1);
-  ProcessHeaders(true, trailers_block);
-}
-
-// If body data are received with a FIN, no trailers should then arrive.
-TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
-  // If HEADERS frames are sent on the request/response stream,
-  // then the sequencer will block them from reaching QuicSpdyStream
-  // after the stream is closed.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Receive initial headers without FIN set.
-  ProcessHeaders(false, headers_);
-  stream_->ConsumeHeaderList();
-
-  // Receive body data, with FIN.
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
-                        0, "body");
-  stream_->OnStreamFrame(frame);
-
-  // Receive trailing headers after FIN already received.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["foo"] = "bar";
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
-      .Times(1);
-  ProcessHeaders(true, trailers_block);
-}
-
-TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
-  // Verify that a stream receiving headers, body, and no trailers is correctly
-  // marked as done reading on consumption of headers and body.
-  Initialize(kShouldProcessData);
-
-  // Receive and consume initial headers with FIN not set.
-  auto h = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
-  stream_->ConsumeHeaderList();
-
-  // Receive and consume body with FIN set, and no trailers.
-  std::string body(1024, 'x');
-  std::string data = UsesHttp3() ? DataFrame(body) : body;
-
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
-                        0, data);
-  stream_->OnStreamFrame(frame);
-
-  EXPECT_TRUE(stream_->IsDoneReading());
-}
-
-// Test that writing trailers will send a FIN, as Trailers are the last thing to
-// be sent on a stream.
-TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
-  Initialize(kShouldProcessData);
-
-  if (UsesHttp3()) {
-    // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
-    // Four writes on the request stream: HEADERS frame header and payload both
-    // for headers and trailers.
-    EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
-  }
-
-  // Write the initial headers, without a FIN.
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
-  // Writing trailers implicitly sends a FIN.
-  SpdyHeaderBlock trailers;
-  trailers["trailer key"] = "trailer value";
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  stream_->WriteTrailers(std::move(trailers), nullptr);
-  EXPECT_TRUE(stream_->fin_sent());
-}
-
-TEST_P(QuicSpdyStreamTest, DoNotSendPriorityUpdateWithDefaultUrgency) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  // Four writes on the request stream: HEADERS frame header and payload both
-  // for headers and trailers.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
-
-  // No PRIORITY_UPDATE frames on the control stream,
-  // because the stream has default priority.
-  auto send_control_stream =
-      QuicSpdySessionPeer::GetSendControlStream(session_.get());
-  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _))
-      .Times(0);
-
-  // Write the initial headers, without a FIN.
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
-  // Writing trailers implicitly sends a FIN.
-  SpdyHeaderBlock trailers;
-  trailers["trailer key"] = "trailer value";
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
-  stream_->WriteTrailers(std::move(trailers), nullptr);
-  EXPECT_TRUE(stream_->fin_sent());
-}
-
-TEST_P(QuicSpdyStreamTest, ChangePriority) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  // Two writes on the request stream: HEADERS frame header and payload.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
-  // PRIORITY_UPDATE frame on the control stream.
-  auto send_control_stream =
-      QuicSpdySessionPeer::GetSendControlStream(session_.get());
-  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
-  PriorityUpdateFrame priority_update;
-  priority_update.prioritized_element_id = 0;
-  priority_update.priority_field_value = "u=0";
-  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameSent(priority_update));
-  stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-}
-
-TEST_P(QuicSpdyStreamTest, ChangePriorityBeforeWritingHeaders) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-
-  // PRIORITY_UPDATE frame sent on the control stream as soon as SetPriority()
-  // is called, before HEADERS frame is sent.
-  auto send_control_stream =
-      QuicSpdySessionPeer::GetSendControlStream(session_.get());
-  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
-
-  stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  testing::Mock::VerifyAndClearExpectations(session_.get());
-
-  // Two writes on the request stream: HEADERS frame header and payload.
-  // PRIORITY_UPDATE frame is not sent this time, because one is already sent.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
-}
-
-// Test that when writing trailers, the trailers that are actually sent to the
-// peer contain the final offset field indicating last byte of data.
-TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
-  Initialize(kShouldProcessData);
-
-  if (UsesHttp3()) {
-    // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
-    // HEADERS frame header and payload on the request stream.
-    EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
-  }
-
-  // Write the initial headers.
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
-  // Write non-zero body data to force a non-zero final offset.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  std::string body(1024, 'x');  // 1 kB
-  QuicByteCount header_length = 0;
-  if (UsesHttp3()) {
-    header_length = HttpEncoder::SerializeDataFrameHeader(
-                        body.length(), quiche::SimpleBufferAllocator::Get())
-                        .size();
-  }
-
-  stream_->WriteOrBufferBody(body, false);
-
-  // The final offset field in the trailing headers is populated with the
-  // number of body bytes written (including queued bytes).
-  SpdyHeaderBlock trailers;
-  trailers["trailer key"] = "trailer value";
-
-  SpdyHeaderBlock expected_trailers(trailers.Clone());
-  // :final-offset pseudo-header is only added if trailers are sent
-  // on the headers stream.
-  if (!UsesHttp3()) {
-    expected_trailers[kFinalOffsetHeaderKey] =
-        absl::StrCat(body.length() + header_length);
-  }
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  stream_->WriteTrailers(std::move(trailers), nullptr);
-  EXPECT_EQ(expected_trailers, stream_->saved_headers());
-}
-
-// Test that if trailers are written after all other data has been written
-// (headers and body), that this closes the stream for writing.
-TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
-  Initialize(kShouldProcessData);
-
-  // Expect data being written on the stream.  In addition to that, headers are
-  // also written on the stream in case of IETF QUIC.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-
-  // Write the initial headers.
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
-  // Write non-zero body data.
-  const int kBodySize = 1 * 1024;  // 1 kB
-  stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
-  EXPECT_EQ(0u, stream_->BufferedDataBytes());
-
-  // Headers and body have been fully written, there is no queued data. Writing
-  // trailers marks the end of this stream, and thus the write side is closed.
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-// Test that the stream is not closed for writing when trailers are sent while
-// there are still body bytes queued.
-TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
-  // This test exercises sending trailers on the headers stream while data is
-  // still queued on the response/request stream.  In IETF QUIC, data and
-  // trailers are sent on the same stream, so this test does not apply.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  testing::InSequence seq;
-  Initialize(kShouldProcessData);
-
-  // Write the initial headers.
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
-
-  // Write non-zero body data, but only consume partially, ensuring queueing.
-  const int kBodySize = 1 * 1024;  // 1 kB
-  if (UsesHttp3()) {
-    EXPECT_CALL(*session_, WritevData(_, 3, _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(*session_, WritevData(_, kBodySize, _, NO_FIN, _, _))
-      .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
-  stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
-  EXPECT_EQ(1u, stream_->BufferedDataBytes());
-
-  // Writing trailers will send a FIN, but not close the write side of the
-  // stream as there are queued bytes.
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
-  EXPECT_TRUE(stream_->fin_sent());
-  EXPECT_FALSE(stream_->write_side_closed());
-
-  // Writing the queued bytes will close the write side of the stream.
-  EXPECT_CALL(*session_, WritevData(_, 1, _, NO_FIN, _, _));
-  stream_->OnCanWrite();
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-// Test that it is not possible to write Trailers after a FIN has been sent.
-TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
-  // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
-  // HEADERS frame.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Write the initial headers, with a FIN.
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
-  EXPECT_TRUE(stream_->fin_sent());
-
-  // Writing Trailers should fail, as the FIN has already been sent.
-  // populated with the number of body bytes written.
-  EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
-                  "Trailers cannot be sent after a FIN");
-}
-
-TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
-  // There is no headers stream if QPACK is used.
-  if (UsesHttp3()) {
-    return;
-  }
-
-  const char kHeader1[] = "Header1";
-  const char kHeader2[] = "Header2";
-  const char kBody1[] = "Test1";
-  const char kBody2[] = "Test2";
-
-  Initialize(kShouldProcessData);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  testing::InSequence s;
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
-      new MockAckListener());
-  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
-      new MockAckListener());
-  stream_->set_ack_listener(ack_listener1);
-  stream2_->set_ack_listener(ack_listener2);
-
-  session_->headers_stream()->WriteOrBufferData(kHeader1, false, ack_listener1);
-  stream_->WriteOrBufferBody(kBody1, true);
-
-  session_->headers_stream()->WriteOrBufferData(kHeader2, false, ack_listener2);
-  stream2_->WriteOrBufferBody(kBody2, false);
-
-  QuicStreamFrame frame1(
-      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
-      kHeader1);
-
-  std::string data1 = UsesHttp3() ? DataFrame(kBody1) : kBody1;
-  QuicStreamFrame frame2(stream_->id(), true, 0, data1);
-  QuicStreamFrame frame3(
-      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
-      kHeader2);
-  std::string data2 = UsesHttp3() ? DataFrame(kBody2) : kBody2;
-  QuicStreamFrame frame4(stream2_->id(), false, 0, data2);
-
-  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
-  session_->OnStreamFrameRetransmitted(frame1);
-
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-}
-
-TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
-  Initialize(kShouldProcessData);
-  stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
-            stream_->precedence());
-}
-
-TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
-  Initialize(kShouldProcessData);
-  testing::InSequence seq;
-
-  if (UsesHttp3()) {
-    EXPECT_CALL(*session_, WritevData(_, 2, _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(*session_, WritevData(_, 4, _, FIN, _, _));
-  stream_->WriteOrBufferBody("data", true);
-  stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
-            stream_->precedence());
-}
-
-TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
-  MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
-      &helper_, &alarm_factory_, Perspective::IS_SERVER,
-      SupportedVersions(GetParam()));
-  std::unique_ptr<TestMockUpdateStreamSession> session(
-      new StrictMock<TestMockUpdateStreamSession>(connection));
-  auto stream =
-      new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalStreamId(
-                                     session->transport_version(), 0),
-                                 session.get(),
-                                 /*should_process_data=*/true);
-  session->ActivateStream(absl::WrapUnique(stream));
-
-  // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
-  // on the session. Make sure stream->priority() returns the updated priority
-  // if called within UpdateStreamPriority(). This expectation is enforced in
-  // TestMockUpdateStreamSession::UpdateStreamPriority().
-  session->SetExpectedStream(stream);
-  session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  stream->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
-  session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
-  stream->SetPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
-}
-
-TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
-  Initialize(kShouldProcessData);
-  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
-      new StrictMock<MockAckListener>);
-  stream_->set_ack_listener(mock_ack_listener);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  // Stream is not waiting for acks initially.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // Send kData1.
-  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  // Stream is not waiting for acks as all sent data is acked.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // Send kData2.
-  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Send FIN.
-  stream_->WriteOrBufferData("", true, nullptr);
-  // Fin only frame is not stored in send buffer.
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // kData2 is retransmitted.
-  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
-  stream_->OnStreamFrameRetransmitted(9, 9, false);
-
-  // kData2 is acked.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  // Stream is waiting for acks as FIN is not acked.
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // FIN is acked.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-}
-
-TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
-  Initialize(kShouldProcessData);
-  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
-      new StrictMock<MockAckListener>);
-  stream_->set_ack_listener(mock_ack_listener);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  // Send [0, 27) and fin.
-  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
-  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
-  stream_->WriteOrBufferData("FooAndBar", true, nullptr);
-
-  // Ack [0, 9), [5, 22) and [18, 26)
-  // Verify [0, 9) 9 bytes are acked.
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Verify [9, 22) 13 bytes are acked.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Verify [22, 26) 4 bytes are acked.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-
-  // Ack [0, 27).
-  // Verify [26, 27) 1 byte is acked.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-
-  // Ack Fin. Verify OnPacketAcked is called.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-
-  // Ack [10, 27) and fin.
-  // No new data is acked, verify OnPacketAcked is not called.
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
-  EXPECT_FALSE(
-      stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
-                                  QuicTime::Zero(), &newly_acked_length));
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-}
-
-// HTTP/3 only.
-TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
-      new StrictMock<MockAckListener>);
-  stream_->set_ack_listener(mock_ack_listener);
-  std::string body = "Test1";
-  std::string body2(100, 'x');
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  stream_->WriteOrBufferBody(body, false);
-  stream_->WriteOrBufferBody(body2, true);
-
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body.length(), quiche::SimpleBufferAllocator::Get());
-  quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
-      body2.length(), quiche::SimpleBufferAllocator::Get());
-
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
-  QuicStreamFrame frame(stream_->id(), false, 0,
-                        absl::StrCat(header.AsStringView(), body));
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
-  QuicStreamFrame frame2(stream_->id(), false, header.size() + body.length(),
-                         header2.AsStringView());
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-
-  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
-  QuicStreamFrame frame3(stream_->id(), true,
-                         header.size() + body.length() + header2.size(), body2);
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-
-  EXPECT_TRUE(
-      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
-}
-
-// HTTP/3 only.
-TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
-      new StrictMock<MockAckListener>);
-  stream_->set_ack_listener(mock_ack_listener);
-  std::string body1 = "Test1";
-  std::string body2(100, 'x');
-  struct iovec body1_iov = {const_cast<char*>(body1.data()), body1.length()};
-  struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
-  quiche::QuicheMemSliceStorage storage(
-      &body1_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
-  quiche::QuicheMemSliceStorage storage2(
-      &body2_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  stream_->WriteBodySlices(storage.ToSpan(), false);
-  stream_->WriteBodySlices(storage2.ToSpan(), true);
-
-  std::string data1 = DataFrame(body1);
-  std::string data2 = DataFrame(body2);
-
-  EXPECT_CALL(*mock_ack_listener,
-              OnPacketAcked(body1.length() + body2.length(), _));
-  QuicStreamFrame frame(stream_->id(), true, 0, data1 + data2);
-  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
-                                     QuicTime::Zero()));
-
-  EXPECT_TRUE(
-      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
-}
-
-// HTTP/3 only.
-TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
-      new StrictMock<MockAckListener>);
-  stream_->set_ack_listener(mock_ack_listener);
-  std::string body1 = "Test1";
-  std::string body2(100, 'x');
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
-  stream_->WriteOrBufferBody(body1, false);
-  stream_->WriteOrBufferBody(body2, true);
-
-  std::string data1 = DataFrame(body1);
-  std::string data2 = DataFrame(body2);
-
-  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body1.length()));
-  QuicStreamFrame frame(stream_->id(), false, 0, data1);
-  session_->OnStreamFrameRetransmitted(frame);
-
-  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
-  QuicStreamFrame frame2(stream_->id(), true, data1.length(), data2);
-  session_->OnStreamFrameRetransmitted(frame2);
-
-  EXPECT_FALSE(
-      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
-}
-
-TEST_P(QuicSpdyStreamTest, HeadersFrameOnRequestStream) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-  std::string data = DataFrame(kDataFramePayload);
-  std::string trailers =
-      HeadersFrame({std::make_pair("custom-key", "custom-value")});
-
-  std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
-  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
-  stream_->OnStreamFrame(frame);
-
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-
-  // QuicSpdyStream only calls OnBodyAvailable()
-  // after the header list has been consumed.
-  EXPECT_EQ("", stream_->data());
-  stream_->ConsumeHeaderList();
-  EXPECT_EQ(kDataFramePayload, stream_->data());
-
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("custom-key", "custom-value")));
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessBodyAfterTrailers) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(!kShouldProcessData);
-
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-  std::string data = DataFrame(kDataFramePayload);
-
-  // A header block that will take more than one block of sequencer buffer.
-  // This ensures that when the trailers are consumed, some buffer buckets will
-  // be freed.
-  SpdyHeaderBlock trailers_block;
-  trailers_block["key1"] = std::string(10000, 'x');
-  std::string trailers = HeadersFrame(trailers_block);
-
-  // Feed all three HTTP/3 frames in a single stream frame.
-  std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
-  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
-  stream_->OnStreamFrame(frame);
-
-  stream_->ConsumeHeaderList();
-  stream_->MarkTrailersConsumed();
-
-  EXPECT_TRUE(stream_->trailers_decompressed());
-  EXPECT_EQ(trailers_block, stream_->received_trailers());
-
-  EXPECT_TRUE(stream_->HasBytesToRead());
-
-  // Consume data.
-  char buffer[2048];
-  struct iovec vec;
-  vec.iov_base = buffer;
-  vec.iov_len = ABSL_ARRAYSIZE(buffer);
-  size_t bytes_read = stream_->Readv(&vec, 1);
-  EXPECT_EQ(kDataFramePayload, absl::string_view(buffer, bytes_read));
-
-  EXPECT_FALSE(stream_->HasBytesToRead());
-}
-
-// The test stream will receive a stream frame containing malformed headers and
-// normal body. Make sure the http decoder stops processing body after the
-// connection shuts down.
-TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
-  // Random bad headers.
-  std::string headers =
-      HeadersFrame(absl::HexStringToBytes("00002a94e7036261"));
-  std::string data = DataFrame(kDataFramePayload);
-
-  std::string stream_frame_payload = absl::StrCat(headers, data);
-  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
-                      MatchesRegex("Error decoding headers on stream \\d+: "
-                                   "Incomplete header block."),
-                      _))
-      .WillOnce(
-          (Invoke([this](QuicErrorCode error, const std::string& error_details,
-                         ConnectionCloseBehavior connection_close_behavior) {
-            connection_->ReallyCloseConnection(error, error_details,
-                                               connection_close_behavior);
-          })));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(*session_, OnConnectionClosed(_, _))
-      .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
-                              ConnectionCloseSource source) {
-        session_->ReallyOnConnectionClosed(frame, source);
-      }));
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
-  stream_->OnStreamFrame(frame);
-}
-
-// Regression test for https://crbug.com/1027895: a HEADERS frame triggers an
-// error in QuicSpdyStream::OnHeadersFramePayload().  This closes the
-// connection, freeing the buffer of QuicStreamSequencer.  Therefore
-// QuicStreamSequencer::MarkConsumed() must not be called from
-// QuicSpdyStream::OnHeadersFramePayload().
-TEST_P(QuicSpdyStreamTest, DoNotMarkConsumedAfterQpackDecodingError) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
-  {
-    testing::InSequence s;
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
-                        MatchesRegex("Error decoding headers on stream \\d+: "
-                                     "Invalid relative index."),
-                        _))
-        .WillOnce((
-            Invoke([this](QuicErrorCode error, const std::string& error_details,
-                          ConnectionCloseBehavior connection_close_behavior) {
-              connection_->ReallyCloseConnection(error, error_details,
-                                                 connection_close_behavior);
-            })));
-    EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-    EXPECT_CALL(*session_, OnConnectionClosed(_, _))
-        .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
-                                ConnectionCloseSource source) {
-          session_->ReallyOnConnectionClosed(frame, source);
-        }));
-  }
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream2_->id(), _, _));
-
-  // Invalid headers: Required Insert Count is zero, but the header block
-  // contains a dynamic table reference.
-  std::string headers = HeadersFrame(absl::HexStringToBytes("000080"));
-  QuicStreamFrame frame(stream_->id(), false, 0, headers);
-  stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  auto decoder_send_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-
-  // Deliver dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = absl::HexStringToBytes("020080");
-  std::string headers = HeadersFrame(encoded_headers);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
-  // Decoder stream type.
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  // Header acknowledgement.
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Headers can be decoded immediately.
-  EXPECT_TRUE(stream_->headers_decompressed());
-
-  // Verify headers.
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // DATA frame.
-  std::string data = DataFrame(kDataFramePayload);
-  EXPECT_CALL(debug_visitor,
-              OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
-                                         headers.length(), data));
-  EXPECT_EQ(kDataFramePayload, stream_->data());
-
-  // Deliver second dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
-
-  // Trailing HEADERS frame referencing second dynamic table entry.
-  std::string encoded_trailers = absl::HexStringToBytes("030080");
-  std::string trailers = HeadersFrame(encoded_trailers);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
-  // Header acknowledgement.
-  EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
-  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
-                                         headers.length() + data.length(),
-                                         trailers));
-
-  // Trailers can be decoded immediately.
-  EXPECT_TRUE(stream_->trailers_decompressed());
-
-  // Verify trailers.
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("trailing", "foobar")));
-  stream_->MarkTrailersConsumed();
-}
-
-TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = absl::HexStringToBytes("020080");
-  std::string headers = HeadersFrame(encoded_headers);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream_->headers_decompressed());
-
-  auto decoder_send_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-
-  // Decoder stream type.
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  // Header acknowledgement.
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
-  // Deliver dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-  EXPECT_TRUE(stream_->headers_decompressed());
-
-  // Verify headers.
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // DATA frame.
-  std::string data = DataFrame(kDataFramePayload);
-  EXPECT_CALL(debug_visitor,
-              OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
-                                         headers.length(), data));
-  EXPECT_EQ(kDataFramePayload, stream_->data());
-
-  // Trailing HEADERS frame referencing second dynamic table entry.
-  std::string encoded_trailers = absl::HexStringToBytes("030080");
-  std::string trailers = HeadersFrame(encoded_trailers);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
-                                         headers.length() + data.length(),
-                                         trailers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream_->trailers_decompressed());
-
-  // Header acknowledgement.
-  EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
-  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
-  // Deliver second dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
-  EXPECT_TRUE(stream_->trailers_decompressed());
-
-  // Verify trailers.
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("trailing", "foobar")));
-  stream_->MarkTrailersConsumed();
-}
-
-TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingHeaders) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
-  // HEADERS frame only referencing entry with absolute index 0 but with
-  // Required Insert Count = 2, which is incorrect.
-  std::string headers = HeadersFrame(absl::HexStringToBytes("030081"));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Even though entire header block is received and every referenced entry is
-  // available, decoding is blocked until insert count reaches the Required
-  // Insert Count value advertised in the header block prefix.
-  EXPECT_FALSE(stream_->headers_decompressed());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
-                      MatchesRegex("Error decoding headers on stream \\d+: "
-                                   "Required Insert Count too large."),
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
-  // Deliver two dynamic table entries to decoder
-  // to trigger decoding of header block.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-}
-
-// Regression test for https://crbug.com/1024263 and for
-// https://crbug.com/1025209#c11.
-TEST_P(QuicSpdyStreamTest, BlockedHeaderDecodingUnblockedWithBufferedError) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
-  // Relative index 2 is invalid because it is larger than or equal to the Base.
-  std::string headers = HeadersFrame(absl::HexStringToBytes("020082"));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Decoding is blocked.
-  EXPECT_FALSE(stream_->headers_decompressed());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
-                      MatchesRegex("Error decoding headers on stream \\d+: "
-                                   "Invalid relative index."),
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
-  // Deliver one dynamic table entry to decoder
-  // to trigger decoding of header block.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-}
-
-TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string headers = HeadersFrame(absl::HexStringToBytes("020080"));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream_->headers_decompressed());
-
-  auto decoder_send_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-
-  // Decoder stream type.
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  // Header acknowledgement.
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-  // Deliver dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-  EXPECT_TRUE(stream_->headers_decompressed());
-
-  // Verify headers.
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // DATA frame.
-  std::string data = DataFrame(kDataFramePayload);
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
-                                         headers.length(), data));
-  EXPECT_EQ(kDataFramePayload, stream_->data());
-
-  // Trailing HEADERS frame only referencing entry with absolute index 0 but
-  // with Required Insert Count = 2, which is incorrect.
-  std::string trailers = HeadersFrame(absl::HexStringToBytes("030081"));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
-                                         headers.length() + data.length(),
-                                         trailers));
-
-  // Even though entire header block is received and every referenced entry is
-  // available, decoding is blocked until insert count reaches the Required
-  // Insert Count value advertised in the header block prefix.
-  EXPECT_FALSE(stream_->trailers_decompressed());
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
-                      MatchesRegex("Error decoding trailers on stream \\d+: "
-                                   "Required Insert Count too large."),
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
-  // Deliver second dynamic table entry to decoder
-  // to trigger decoding of trailing header block.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
-}
-
-// Regression test for b/132603592: QPACK decoding unblocked after stream is
-// closed.
-TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = absl::HexStringToBytes("020080");
-  std::string headers = HeadersFrame(encoded_headers);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream_->headers_decompressed());
-
-  // Decoder stream type and stream cancellation instruction.
-  auto decoder_send_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-
-  // Reset stream by this endpoint, for example, due to stream cancellation.
-  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
-                             stream_->id(), QuicResetStreamError::FromInternal(
-                                                QUIC_STREAM_CANCELLED)));
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          stream_->id(),
-          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
-  stream_->Reset(QUIC_STREAM_CANCELLED);
-
-  // Deliver dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-
-  EXPECT_FALSE(stream_->headers_decompressed());
-}
-
-TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterResetReceived) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = absl::HexStringToBytes("020080");
-  std::string headers = HeadersFrame(encoded_headers);
-  EXPECT_CALL(debug_visitor,
-              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Decoding is blocked because dynamic table entry has not been received yet.
-  EXPECT_FALSE(stream_->headers_decompressed());
-
-  // Decoder stream type and stream cancellation instruction.
-  auto decoder_send_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  EXPECT_CALL(*session_,
-              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-
-  // OnStreamReset() is called when RESET_STREAM frame is received from peer.
-  stream_->OnStreamReset(QuicRstStreamFrame(
-      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
-
-  if (!GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
-    // Header acknowledgement.
-    EXPECT_CALL(*session_,
-                WritevData(decoder_send_stream->id(), /* write_length = */ 1,
-                           /* offset = */ 2, _, _, _));
-    EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
-  }
-
-  // Deliver dynamic table entry to decoder.
-  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
-
-  if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
-    EXPECT_FALSE(stream_->headers_decompressed());
-  } else {
-    // Verify headers.
-    EXPECT_TRUE(stream_->headers_decompressed());
-    EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  }
-}
-
-class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest {
- protected:
-  QuicSpdyStreamIncrementalConsumptionTest() : offset_(0), consumed_bytes_(0) {}
-  ~QuicSpdyStreamIncrementalConsumptionTest() override = default;
-
-  // Create QuicStreamFrame with |payload|
-  // and pass it to stream_->OnStreamFrame().
-  void OnStreamFrame(absl::string_view payload) {
-    QuicStreamFrame frame(stream_->id(), /* fin = */ false, offset_, payload);
-    stream_->OnStreamFrame(frame);
-    offset_ += payload.size();
-  }
-
-  // Return number of bytes marked consumed with sequencer
-  // since last NewlyConsumedBytes() call.
-  QuicStreamOffset NewlyConsumedBytes() {
-    QuicStreamOffset previously_consumed_bytes = consumed_bytes_;
-    consumed_bytes_ = stream_->sequencer()->NumBytesConsumed();
-    return consumed_bytes_ - previously_consumed_bytes;
-  }
-
-  // Read |size| bytes from the stream.
-  std::string ReadFromStream(QuicByteCount size) {
-    std::string buffer;
-    buffer.resize(size);
-
-    struct iovec vec;
-    vec.iov_base = const_cast<char*>(buffer.data());
-    vec.iov_len = size;
-
-    size_t bytes_read = stream_->Readv(&vec, 1);
-    EXPECT_EQ(bytes_read, size);
-
-    return buffer;
-  }
-
- private:
-  QuicStreamOffset offset_;
-  QuicStreamOffset consumed_bytes_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamIncrementalConsumptionTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-// Test that stream bytes are consumed (by calling
-// sequencer()->MarkConsumed()) incrementally, as soon as possible.
-TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(!kShouldProcessData);
-
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-
-  // All HEADERS frame bytes are consumed even if the frame is not received
-  // completely.
-  OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
-  EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
-
-  // The rest of the HEADERS frame is also consumed immediately.
-  OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
-  EXPECT_EQ(1u, NewlyConsumedBytes());
-
-  // Verify headers.
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // DATA frame.
-  absl::string_view data_payload(kDataFramePayload);
-  std::string data_frame = DataFrame(data_payload);
-  QuicByteCount data_frame_header_length =
-      data_frame.size() - data_payload.size();
-
-  // DATA frame header is consumed.
-  // DATA frame payload is not consumed because payload has to be buffered.
-  OnStreamFrame(data_frame);
-  EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
-
-  // Consume all but last byte of data.
-  EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
-            ReadFromStream(data_payload.size() - 1));
-  EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
-
-  std::string trailers =
-      HeadersFrame({std::make_pair("custom-key", "custom-value")});
-
-  // No bytes are consumed, because last byte of DATA payload is still buffered.
-  OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
-  EXPECT_EQ(0u, NewlyConsumedBytes());
-
-  // Reading last byte of DATA payload triggers consumption of all data received
-  // so far, even though last HEADERS frame has not been received completely.
-  EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
-  EXPECT_EQ(1 + trailers.size() - 1, NewlyConsumedBytes());
-
-  // Last byte of trailers is immediately consumed.
-  OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
-  EXPECT_EQ(1u, NewlyConsumedBytes());
-
-  // Verify trailers.
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("custom-key", "custom-value")));
-}
-
-TEST_P(QuicSpdyStreamIncrementalConsumptionTest, ReceiveUnknownFrame) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  StrictMock<MockHttp3DebugVisitor> debug_visitor;
-  session_->set_debug_visitor(&debug_visitor);
-
-  EXPECT_CALL(debug_visitor,
-              OnUnknownFrameReceived(stream_->id(), /* frame_type = */ 0x21,
-                                     /* payload_length = */ 3));
-  std::string unknown_frame = UnknownFrame(0x21, "foo");
-  OnStreamFrame(unknown_frame);
-}
-
-TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(!kShouldProcessData);
-
-  // Unknown frame of reserved type before HEADERS is consumed immediately.
-  std::string unknown_frame1 = UnknownFrame(0x21, "foo");
-  OnStreamFrame(unknown_frame1);
-  EXPECT_EQ(unknown_frame1.size(), NewlyConsumedBytes());
-
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-
-  // All HEADERS frame bytes are consumed even if the frame is not received
-  // completely.
-  OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
-  EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
-
-  // The rest of the HEADERS frame is also consumed immediately.
-  OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
-  EXPECT_EQ(1u, NewlyConsumedBytes());
-
-  // Verify headers.
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // Frame of unknown, not reserved type between HEADERS and DATA is consumed
-  // immediately.
-  std::string unknown_frame2 = UnknownFrame(0x3a, "");
-  OnStreamFrame(unknown_frame2);
-  EXPECT_EQ(unknown_frame2.size(), NewlyConsumedBytes());
-
-  // DATA frame.
-  absl::string_view data_payload(kDataFramePayload);
-  std::string data_frame = DataFrame(data_payload);
-  QuicByteCount data_frame_header_length =
-      data_frame.size() - data_payload.size();
-
-  // DATA frame header is consumed.
-  // DATA frame payload is not consumed because payload has to be buffered.
-  OnStreamFrame(data_frame);
-  EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
-
-  // Frame of unknown, not reserved type is not consumed because DATA payload is
-  // still buffered.
-  std::string unknown_frame3 = UnknownFrame(0x39, "bar");
-  OnStreamFrame(unknown_frame3);
-  EXPECT_EQ(0u, NewlyConsumedBytes());
-
-  // Consume all but last byte of data.
-  EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
-            ReadFromStream(data_payload.size() - 1));
-  EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
-
-  std::string trailers =
-      HeadersFrame({std::make_pair("custom-key", "custom-value")});
-
-  // No bytes are consumed, because last byte of DATA payload is still buffered.
-  OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
-  EXPECT_EQ(0u, NewlyConsumedBytes());
-
-  // Reading last byte of DATA payload triggers consumption of all data received
-  // so far, even though last HEADERS frame has not been received completely.
-  EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
-  EXPECT_EQ(1 + unknown_frame3.size() + trailers.size() - 1,
-            NewlyConsumedBytes());
-
-  // Last byte of trailers is immediately consumed.
-  OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
-  EXPECT_EQ(1u, NewlyConsumedBytes());
-
-  // Verify trailers.
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("custom-key", "custom-value")));
-
-  // Unknown frame of reserved type after trailers is consumed immediately.
-  std::string unknown_frame4 = UnknownFrame(0x40, "");
-  OnStreamFrame(unknown_frame4);
-  EXPECT_EQ(unknown_frame4.size(), NewlyConsumedBytes());
-}
-
-// Close connection if a DATA frame is received before a HEADERS frame.
-TEST_P(QuicSpdyStreamTest, DataBeforeHeaders) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Closing the connection is mocked out in tests.  Instead, simply stop
-  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
-                      "Unexpected DATA frame received.",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
-      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
-
-  std::string data = DataFrame(kDataFramePayload);
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, data));
-}
-
-// Close connection if a HEADERS frame is received after the trailing HEADERS.
-TEST_P(QuicSpdyStreamTest, TrailersAfterTrailers) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Receive and consume headers.
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-  QuicStreamOffset offset = 0;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), false, offset, headers));
-  offset += headers.size();
-
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // Receive data.  It is consumed by TestStream.
-  std::string data = DataFrame(kDataFramePayload);
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data));
-  offset += data.size();
-
-  EXPECT_EQ(kDataFramePayload, stream_->data());
-
-  // Receive and consume trailers.
-  std::string trailers1 =
-      HeadersFrame({std::make_pair("custom-key", "custom-value")});
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), false, offset, trailers1));
-  offset += trailers1.size();
-
-  EXPECT_TRUE(stream_->trailers_decompressed());
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("custom-key", "custom-value")));
-
-  // Closing the connection is mocked out in tests.  Instead, simply stop
-  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
-                      "HEADERS frame received after trailing HEADERS.",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
-      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
-
-  // Receive another HEADERS frame, with no header fields.
-  std::string trailers2 = HeadersFrame(SpdyHeaderBlock());
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), false, offset, trailers2));
-}
-
-// Regression test for https://crbug.com/978733.
-// Close connection if a DATA frame is received after the trailing HEADERS.
-TEST_P(QuicSpdyStreamTest, DataAfterTrailers) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Receive and consume headers.
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-  QuicStreamOffset offset = 0;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), false, offset, headers));
-  offset += headers.size();
-
-  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
-  stream_->ConsumeHeaderList();
-
-  // Receive data.  It is consumed by TestStream.
-  std::string data1 = DataFrame(kDataFramePayload);
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data1));
-  offset += data1.size();
-  EXPECT_EQ(kDataFramePayload, stream_->data());
-
-  // Receive trailers, with single header field "custom-key: custom-value".
-  std::string trailers =
-      HeadersFrame({std::make_pair("custom-key", "custom-value")});
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), false, offset, trailers));
-  offset += trailers.size();
-
-  EXPECT_THAT(stream_->received_trailers(),
-              ElementsAre(Pair("custom-key", "custom-value")));
-
-  // Closing the connection is mocked out in tests.  Instead, simply stop
-  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
-                      "Unexpected DATA frame received.",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
-      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
-
-  // Receive more data.
-  std::string data2 = DataFrame("This payload should not be proccessed.");
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data2));
-}
-
-// SETTINGS frames are invalid on bidirectional streams.  If one is received,
-// the connection is closed.  No more data should be processed.
-TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // SETTINGS frame with empty payload.
-  std::string settings = absl::HexStringToBytes("0400");
-
-  // HEADERS frame.
-  // Since it arrives after a SETTINGS frame, it should never be read.
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-
-  // Combine the two frames to make sure they are processed in a single
-  // QuicSpdyStream::OnDataAvailable() call.
-  std::string frames = absl::StrCat(settings, headers);
-
-  EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-  EXPECT_CALL(*session_, OnConnectionClosed(_, _));
-
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), /* fin = */ false,
-                                         /* offset = */ 0, frames));
-
-  EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
-}
-
-// Stream Cancellation instruction is sent on QPACK decoder stream
-// when stream is reset.
-TEST_P(QuicSpdyStreamTest, StreamCancellationWhenStreamReset) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  auto qpack_decoder_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-  // Stream type.
-  EXPECT_CALL(*session_,
-              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  // Stream cancellation.
-  EXPECT_CALL(*session_,
-              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
-                             stream_->id(), QuicResetStreamError::FromInternal(
-                                                QUIC_STREAM_CANCELLED)));
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          stream_->id(),
-          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
-
-  stream_->Reset(QUIC_STREAM_CANCELLED);
-}
-
-// Stream Cancellation instruction is sent on QPACK decoder stream
-// when RESET_STREAM frame is received.
-TEST_P(QuicSpdyStreamTest, StreamCancellationOnResetReceived) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  auto qpack_decoder_stream =
-      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
-  // Stream type.
-  EXPECT_CALL(*session_,
-              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 0, _, _, _));
-  // Stream cancellation.
-  EXPECT_CALL(*session_,
-              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
-                         /* offset = */ 1, _, _, _));
-
-  stream_->OnStreamReset(QuicRstStreamFrame(
-      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
-}
-
-TEST_P(QuicSpdyStreamTest, WriteHeadersReturnValue) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  testing::InSequence s;
-
-  // Enable QPACK dynamic table.
-  session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024);
-  session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 1);
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(true));
-
-  QpackSendStream* encoder_stream =
-      QuicSpdySessionPeer::GetQpackEncoderSendStream(session_.get());
-  EXPECT_CALL(*session_, WritevData(encoder_stream->id(), _, _, _, _, _))
-      .Times(AnyNumber());
-
-  // HEADERS frame header.
-  EXPECT_CALL(*session_,
-              WritevData(stream_->id(), _, /* offset = */ 0, _, _, _));
-  // HEADERS frame payload.
-  size_t headers_frame_payload_length = 0;
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .WillOnce(
-          DoAll(SaveArg<1>(&headers_frame_payload_length),
-                Invoke(session_.get(), &MockQuicSpdySession::ConsumeData)));
-
-  SpdyHeaderBlock request_headers;
-  request_headers["foo"] = "bar";
-  size_t write_headers_return_value =
-      stream_->WriteHeaders(std::move(request_headers), /*fin=*/true, nullptr);
-  EXPECT_TRUE(stream_->fin_sent());
-
-  EXPECT_EQ(headers_frame_payload_length, write_headers_return_value);
-}
-
-// Regression test for https://crbug.com/1177662.
-// RESET_STREAM with QUIC_STREAM_NO_ERROR should not be treated in a special
-// way: it should close the read side but not the write side.
-TEST_P(QuicSpdyStreamTest, TwoResetStreamFrames) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
-
-  QuicRstStreamFrame rst_frame1(kInvalidControlFrameId, stream_->id(),
-                                QUIC_STREAM_CANCELLED, /* bytes_written = */ 0);
-  stream_->OnStreamReset(rst_frame1);
-  EXPECT_TRUE(stream_->read_side_closed());
-  EXPECT_FALSE(stream_->write_side_closed());
-
-  QuicRstStreamFrame rst_frame2(kInvalidControlFrameId, stream_->id(),
-                                QUIC_STREAM_NO_ERROR, /* bytes_written = */ 0);
-  if (GetQuicReloadableFlag(quic_fix_on_stream_reset)) {
-    stream_->OnStreamReset(rst_frame2);
-    EXPECT_TRUE(stream_->read_side_closed());
-    EXPECT_FALSE(stream_->write_side_closed());
-  } else {
-    EXPECT_CALL(
-        *session_,
-        MaybeSendRstStreamFrame(
-            stream_->id(),
-            QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), _));
-    EXPECT_QUIC_BUG(
-        stream_->OnStreamReset(rst_frame2),
-        "The stream should've already sent RST in response to STOP_SENDING");
-  }
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft00) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AnyNumber());
-
-  spdy::SpdyHeaderBlock headers;
-  headers[":method"] = "CONNECT";
-  headers[":protocol"] = "webtransport";
-  headers["datagram-flow-id"] = absl::StrCat(stream_->id());
-  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft04) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AnyNumber());
-
-  spdy::SpdyHeaderBlock headers;
-  headers[":method"] = "CONNECT";
-  headers[":protocol"] = "webtransport";
-  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft04) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["sec-webtransport-http3-draft02"] = "1";
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  ProcessHeaders(false, headers_);
-  stream_->OnCapsule(
-      Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft00) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  ProcessHeaders(false, headers_);
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest,
-       ProcessIncomingWebTransportHeadersWithMismatchedFlowId) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  // TODO(b/181256914) Remove this test when we deprecate
-  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  session_->EnableWebTransport();
-  QuicSpdySessionPeer::EnableWebTransport(session_.get());
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["datagram-flow-id"] = "2";
-
-  stream_->OnStreamHeadersPriority(
-      spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  ProcessHeaders(false, headers_);
-  EXPECT_EQ("", stream_->data());
-  EXPECT_FALSE(stream_->header_list().empty());
-  EXPECT_FALSE(stream_->IsDoneReading());
-  ASSERT_TRUE(stream_->web_transport() != nullptr);
-  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdClient) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
-  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 0u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 2u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 4u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 6u);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdServer) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_SERVER);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
-  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 1u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 3u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 5u);
-  EXPECT_EQ(stream_->GetNextDatagramContextId(), 7u);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithoutContextDraft00) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft00);
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
-  ProcessHeaders(false, headers_);
-  session_->RegisterHttp3DatagramFlowId(stream_->id(), stream_->id());
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor;
-  SavingHttp3DatagramVisitor h3_datagram_visitor;
-  absl::optional<QuicDatagramContextId> context_id;
-  absl::string_view format_additional_data;
-  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
-  std::array<char, 256> datagram;
-  datagram[0] = stream_->id();
-  for (size_t i = 1; i < datagram.size(); i++) {
-    datagram[i] = i;
-  }
-  stream_->RegisterHttp3DatagramRegistrationVisitor(
-      &h3_datagram_registration_visitor);
-  stream_->RegisterHttp3DatagramContextId(
-      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
-      &h3_datagram_visitor);
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
-  // Test move.
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor2;
-  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
-  SavingHttp3DatagramVisitor h3_datagram_visitor2;
-  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
-                                                  &h3_datagram_visitor2);
-  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
-  // Cleanup.
-  stream_->UnregisterHttp3DatagramContextId(context_id);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-  session_->UnregisterHttp3DatagramFlowId(stream_->id());
-}
-
-TEST_P(QuicSpdyStreamTest, H3DatagramRegistrationWithoutContextDraft04) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  ProcessHeaders(false, headers_);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor;
-  SavingHttp3DatagramVisitor h3_datagram_visitor;
-  absl::optional<QuicDatagramContextId> context_id;
-  absl::string_view format_additional_data;
-  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
-  std::array<char, 256> datagram;
-  datagram[0] = stream_->id();
-  for (size_t i = 1; i < datagram.size(); i++) {
-    datagram[i] = i;
-  }
-  stream_->RegisterHttp3DatagramRegistrationVisitor(
-      &h3_datagram_registration_visitor);
-
-  // Expect us to send a REGISTER_DATAGRAM_NO_CONTEXT capsule.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-
-  stream_->RegisterHttp3DatagramContextId(
-      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
-      &h3_datagram_visitor);
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
-  // Test move.
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor2;
-  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
-  SavingHttp3DatagramVisitor h3_datagram_visitor2;
-  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
-                                                  &h3_datagram_visitor2);
-  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[1], datagram.size() - 1)}));
-  // Cleanup.
-  stream_->UnregisterHttp3DatagramContextId(context_id);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithContext) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor;
-  SavingHttp3DatagramVisitor h3_datagram_visitor;
-  absl::optional<QuicDatagramContextId> context_id = 42;
-  absl::string_view format_additional_data;
-  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
-  std::array<char, 256> datagram;
-  datagram[0] = stream_->id();
-  datagram[1] = context_id.value();
-  for (size_t i = 2; i < datagram.size(); i++) {
-    datagram[i] = i;
-  }
-  stream_->RegisterHttp3DatagramRegistrationVisitor(
-      &h3_datagram_registration_visitor, /*use_datagram_contexts=*/true);
-  headers_[":method"] = "CONNECT";
-  headers_[":protocol"] = "webtransport";
-  headers_["sec-use-datagram-contexts"] = "?1";
-  ProcessHeaders(false, headers_);
-
-  // Expect us to send a REGISTER_DATAGRAM_CONTEXT capsule.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-
-  stream_->RegisterHttp3DatagramContextId(
-      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
-      &h3_datagram_visitor);
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[2], datagram.size() - 2)}));
-  // Test move.
-  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
-      h3_datagram_registration_visitor2;
-  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
-  SavingHttp3DatagramVisitor h3_datagram_visitor2;
-  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
-                                                  &h3_datagram_visitor2);
-  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
-  session_->OnMessageReceived(
-      absl::string_view(datagram.data(), datagram.size()));
-  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
-              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
-                  stream_->id(), context_id,
-                  std::string(&datagram[2], datagram.size() - 2)}));
-  // Cleanup.
-
-  // Expect us to send a CLOSE_DATAGRAM_CONTEXT capsule.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(AtLeast(1));
-  stream_->UnregisterHttp3DatagramContextId(context_id);
-  stream_->UnregisterHttp3DatagramRegistrationVisitor();
-  session_->UnregisterHttp3DatagramFlowId(stream_->id());
-}
-
-TEST_P(QuicSpdyStreamTest, SendHttp3Datagram) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-  absl::optional<QuicDatagramContextId> context_id;
-  std::string h3_datagram_payload = {1, 2, 3, 4, 5, 6};
-  EXPECT_CALL(*connection_, SendMessage(1, _, false))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-  EXPECT_EQ(stream_->SendHttp3Datagram(context_id, h3_datagram_payload),
-            MESSAGE_STATUS_SUCCESS);
-}
-
-TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
-  if (!UsesHttp3()) {
-    return;
-  }
-  Initialize(kShouldProcessData);
-  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
-  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
-                                              HttpDatagramSupport::kDraft04);
-
-  QuicByteCount size = stream_->GetMaxDatagramSize(absl::nullopt);
-  QuicByteCount size_with_context =
-      stream_->GetMaxDatagramSize(/*context_id=*/1);
-  EXPECT_GT(size, 512u);
-  EXPECT_EQ(size - 1, size_with_context);
-}
-
-TEST_P(QuicSpdyStreamTest,
-       QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
-  if (!UsesHttp3()) {
-    return;
-  }
-
-  Initialize(kShouldProcessData);
-
-  // Creates QpackDecodedHeadersAccumulator in
-  // `qpack_decoded_headers_accumulator_`.
-  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
-  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
-
-  // Resets `qpack_decoded_headers_accumulator_`.
-  stream_->OnHeadersDecoded({}, false);
-
-  // This private method should never be called when
-  // `qpack_decoded_headers_accumulator_` is nullptr.  The number 1 identifies
-  // the site where `qpack_decoded_headers_accumulator_` was last reset.
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _));
-  bool result = true;
-  EXPECT_QUIC_BUG(result = QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_),
-                  "b215142466_OnHeadersFrameEnd.: 1$");
-  EXPECT_FALSE(result);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/spdy_server_push_utils.cc b/quic/core/http/spdy_server_push_utils.cc
deleted file mode 100644
index eb81810..0000000
--- a/quic/core/http/spdy_server_push_utils.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/spdy_server_push_utils.h"
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-// static
-std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders(
-    const SpdyHeaderBlock& headers) {
-  // RFC 7540, Section 8.1.2.3: All HTTP/2 requests MUST include exactly
-  // one valid value for the ":method", ":scheme", and ":path" pseudo-header
-  // fields, unless it is a CONNECT request.
-
-  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
-  // subsequent CONTINUATION frames MUST be a valid and complete set of request
-  // header fields (Section 8.1.2.3).  The server MUST include a method in the
-  // ":method" pseudo-header field that is safe and cacheable.
-  //
-  // RFC 7231, Section  4.2.1: Of the request methods defined by this
-  // specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be
-  // safe.
-  //
-  // RFC 7231, Section  4.2.1: ... this specification defines GET, HEAD, and
-  // POST as cacheable, ...
-  //
-  // So the only methods allowed in a PUSH_PROMISE are GET and HEAD.
-  SpdyHeaderBlock::const_iterator it = headers.find(":method");
-  if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) {
-    return std::string();
-  }
-
-  it = headers.find(":scheme");
-  if (it == headers.end() || it->second.empty()) {
-    return std::string();
-  }
-  absl::string_view scheme = it->second;
-
-  // RFC 7540, Section 8.2: The server MUST include a value in the
-  // ":authority" pseudo-header field for which the server is authoritative
-  // (see Section 10.1).
-  it = headers.find(":authority");
-  if (it == headers.end() || it->second.empty()) {
-    return std::string();
-  }
-  absl::string_view authority = it->second;
-
-  // RFC 7540, Section 8.1.2.3 requires that the ":path" pseudo-header MUST
-  // NOT be empty for "http" or "https" URIs;
-  //
-  // However, to ensure the scheme is consistently canonicalized, that check
-  // is deferred to implementations in QuicUrlUtils::GetPushPromiseUrl().
-  it = headers.find(":path");
-  if (it == headers.end()) {
-    return std::string();
-  }
-  absl::string_view path = it->second;
-
-  return GetPushPromiseUrl(scheme, authority, path);
-}
-
-// static
-std::string SpdyServerPushUtils::GetPromisedHostNameFromHeaders(
-    const SpdyHeaderBlock& headers) {
-  // TODO(fayang): Consider just checking out the value of the ":authority" key
-  // in headers.
-  return GURL(GetPromisedUrlFromHeaders(headers)).host();
-}
-
-// static
-bool SpdyServerPushUtils::PromisedUrlIsValid(const SpdyHeaderBlock& headers) {
-  std::string url(GetPromisedUrlFromHeaders(headers));
-  return !url.empty() && GURL(url).is_valid();
-}
-
-// static
-std::string SpdyServerPushUtils::GetPushPromiseUrl(absl::string_view scheme,
-                                                   absl::string_view authority,
-                                                   absl::string_view path) {
-  // RFC 7540, Section 8.1.2.3: The ":path" pseudo-header field includes the
-  // path and query parts of the target URI (the "path-absolute" production
-  // and optionally a '?' character followed by the "query" production (see
-  // Sections 3.3 and 3.4 of RFC3986). A request in asterisk form includes the
-  // value '*' for the ":path" pseudo-header field.
-  //
-  // This pseudo-header field MUST NOT be empty for "http" or "https" URIs;
-  // "http" or "https" URIs that do not contain a path MUST include a value of
-  // '/'. The exception to this rule is an OPTIONS request for an "http" or
-  // "https" URI that does not include a path component; these MUST include a
-  // ":path" pseudo-header with a value of '*' (see RFC7230, Section 5.3.4).
-  //
-  // In addition to the above restriction from RFC 7540, note that RFC3986
-  // defines the "path-absolute" construction as starting with "/" but not "//".
-  //
-  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
-  // subsequent CONTINUATION frames MUST be a valid and complete set of request
-  // header fields (Section 8.1.2.3).  The server MUST include a method in the
-  // ":method" pseudo-header field that is safe and cacheable.
-  //
-  // RFC 7231, Section  4.2.1:
-  // ... this specification defines GET, HEAD, and POST as cacheable, ...
-  //
-  // Since the OPTIONS method is not cacheable, it cannot be the method of a
-  // PUSH_PROMISE. Therefore, the exception mentioned in RFC 7540, Section
-  // 8.1.2.3 about OPTIONS requests does not apply here (i.e. ":path" cannot be
-  // "*").
-  if (path.empty() || path[0] != '/' || (path.size() >= 2 && path[1] == '/')) {
-    return std::string();
-  }
-
-  // Validate the scheme; this is to ensure a scheme of "foo://bar" is not
-  // parsed as a URL of "foo://bar://baz" when combined with a host of "baz".
-  std::string canonical_scheme;
-  url::StdStringCanonOutput canon_scheme_output(&canonical_scheme);
-  url::Component canon_component;
-  url::Component scheme_component(0, scheme.size());
-
-  if (!url::CanonicalizeScheme(scheme.data(), scheme_component,
-                               &canon_scheme_output, &canon_component) ||
-      !canon_component.is_nonempty() || canon_component.begin != 0) {
-    return std::string();
-  }
-  canonical_scheme.resize(canon_component.len + 1);
-
-  // Validate the authority; this is to ensure an authority such as
-  // "host/path" is not accepted, as when combined with a scheme like
-  // "http://", could result in a URL of "http://host/path".
-  url::Component auth_component(0, authority.size());
-  url::Component username_component;
-  url::Component password_component;
-  url::Component host_component;
-  url::Component port_component;
-
-  url::ParseAuthority(authority.data(), auth_component, &username_component,
-                      &password_component, &host_component, &port_component);
-
-  // RFC 7540, Section 8.1.2.3: The authority MUST NOT include the deprecated
-  // "userinfo" subcomponent for "http" or "https" schemed URIs.
-  //
-  // Note: Although |canonical_scheme| has not yet been checked for that, as
-  // it is performed later in processing, only "http" and "https" schemed
-  // URIs are supported for PUSH.
-  if (username_component.is_valid() || password_component.is_valid()) {
-    return std::string();
-  }
-
-  // Failed parsing or no host present. ParseAuthority() will ensure that
-  // host_component + port_component cover the entire string, if
-  // username_component and password_component are not present.
-  if (!host_component.is_nonempty()) {
-    return std::string();
-  }
-
-  // Validate the port (if present; it's optional).
-  int parsed_port_number = url::PORT_INVALID;
-  if (port_component.is_nonempty()) {
-    parsed_port_number = url::ParsePort(authority.data(), port_component);
-    if (parsed_port_number < 0 && parsed_port_number != url::PORT_UNSPECIFIED) {
-      return std::string();
-    }
-  }
-
-  // Validate the host by attempting to canonicalize it. Invalid characters
-  // will result in a canonicalization failure (e.g. '/')
-  std::string canon_host;
-  url::StdStringCanonOutput canon_host_output(&canon_host);
-  canon_component.reset();
-  if (!url::CanonicalizeHost(authority.data(), host_component,
-                             &canon_host_output, &canon_component) ||
-      !canon_component.is_nonempty() || canon_component.begin != 0) {
-    return std::string();
-  }
-
-  // At this point, "authority" has been validated to either be of the form
-  // 'host:port' or 'host', with 'host' being a valid domain or IP address,
-  // and 'port' (if present), being a valid port. Attempt to construct a
-  // URL of just the (scheme, host, port), which should be safe and will not
-  // result in ambiguous parsing.
-  //
-  // This also enforces that all PUSHed URLs are either HTTP or HTTPS-schemed
-  // URIs, consistent with the other restrictions enforced above.
-  //
-  // Note: url::CanonicalizeScheme() will have added the ':' to
-  // |canonical_scheme|.
-  GURL origin_url(canonical_scheme + "//" + std::string(authority));
-  if (!origin_url.is_valid() || !origin_url.SchemeIsHTTPOrHTTPS() ||
-      // The following checks are merely defense in depth.
-      origin_url.has_username() || origin_url.has_password() ||
-      (origin_url.has_path() && origin_url.path_piece() != "/") ||
-      origin_url.has_query() || origin_url.has_ref()) {
-    return std::string();
-  }
-
-  // Attempt to parse the path.
-  std::string spec = origin_url.GetWithEmptyPath().spec();
-  spec.pop_back();  // Remove the '/', as ":path" must contain it.
-  spec.append(std::string(path));
-
-  // Attempt to parse the full URL, with the path as well. Ensure there is no
-  // fragment to the query.
-  GURL full_url(spec);
-  if (!full_url.is_valid() || full_url.has_ref()) {
-    return std::string();
-  }
-
-  return full_url.spec();
-}
-
-}  // namespace quic
diff --git a/quic/core/http/spdy_server_push_utils.h b/quic/core/http/spdy_server_push_utils.h
deleted file mode 100644
index 63cfb88..0000000
--- a/quic/core/http/spdy_server_push_utils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
-#define QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE SpdyServerPushUtils {
- public:
-  SpdyServerPushUtils() = delete;
-
-  // Returns a canonicalized URL composed from the :scheme, :authority, and
-  // :path headers of a PUSH_PROMISE. Returns empty string if the headers do not
-  // conform to HTTP/2 spec or if the ":method" header contains a forbidden
-  // method for PUSH_PROMISE.
-  static std::string GetPromisedUrlFromHeaders(
-      const spdy::SpdyHeaderBlock& headers);
-
-  // Returns hostname, or empty string if missing.
-  static std::string GetPromisedHostNameFromHeaders(
-      const spdy::SpdyHeaderBlock& headers);
-
-  // Returns true if result of |GetPromisedUrlFromHeaders()| is non-empty
-  // and is a well-formed URL.
-  static bool PromisedUrlIsValid(const spdy::SpdyHeaderBlock& headers);
-
-  // Returns a canonical, valid URL for a PUSH_PROMISE with the specified
-  // ":scheme", ":authority", and ":path" header fields, or an empty
-  // string if the resulting URL is not valid or supported.
-  static std::string GetPushPromiseUrl(absl::string_view scheme,
-                                       absl::string_view authority,
-                                       absl::string_view path);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
diff --git a/quic/core/http/spdy_server_push_utils_test.cc b/quic/core/http/spdy_server_push_utils_test.cc
deleted file mode 100644
index df1659d..0000000
--- a/quic/core/http/spdy_server_push_utils_test.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/spdy_server_push_utils.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-namespace test {
-
-using GetPromisedUrlFromHeaders = QuicTest;
-
-TEST_F(GetPromisedUrlFromHeaders, Basic) {
-  SpdyHeaderBlock headers;
-  headers[":method"] = "GET";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-  headers[":scheme"] = "https";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-  headers[":authority"] = "www.google.com";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-  headers[":path"] = "/index.html";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
-            "https://www.google.com/index.html");
-  headers["key1"] = "value1";
-  headers["key2"] = "value2";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
-            "https://www.google.com/index.html");
-}
-
-TEST_F(GetPromisedUrlFromHeaders, Connect) {
-  SpdyHeaderBlock headers;
-  headers[":method"] = "CONNECT";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-  headers[":authority"] = "www.google.com";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-  headers[":scheme"] = "https";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-  headers[":path"] = "https";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-}
-
-TEST_F(GetPromisedUrlFromHeaders, InvalidUserinfo) {
-  SpdyHeaderBlock headers;
-  headers[":method"] = "GET";
-  headers[":authority"] = "user@www.google.com";
-  headers[":scheme"] = "https";
-  headers[":path"] = "/";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-}
-
-TEST_F(GetPromisedUrlFromHeaders, InvalidPath) {
-  SpdyHeaderBlock headers;
-  headers[":method"] = "GET";
-  headers[":authority"] = "www.google.com";
-  headers[":scheme"] = "https";
-  headers[":path"] = "";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
-}
-
-using GetPromisedHostNameFromHeaders = QuicTest;
-
-TEST_F(GetPromisedHostNameFromHeaders, NormalUsage) {
-  SpdyHeaderBlock headers;
-  headers[":method"] = "GET";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
-  headers[":scheme"] = "https";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
-  headers[":authority"] = "www.google.com";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
-  headers[":path"] = "/index.html";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
-            "www.google.com");
-  headers["key1"] = "value1";
-  headers["key2"] = "value2";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
-            "www.google.com");
-  headers[":authority"] = "www.google.com:6666";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
-            "www.google.com");
-  headers[":authority"] = "192.168.1.1";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
-            "192.168.1.1");
-  headers[":authority"] = "192.168.1.1:6666";
-  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
-            "192.168.1.1");
-}
-
-using PushPromiseUrlTest = QuicTest;
-
-TEST_F(PushPromiseUrlTest, GetPushPromiseUrl) {
-  // Test rejection of various inputs.
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("file", "localhost",
-                                                       "/etc/password"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
-                    "file", "", "/C:/Windows/System32/Config/"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
-                    "", "https://www.google.com", "/"));
-
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://www.google.com",
-                                                       "www.google.com", "/"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://",
-                                                       "www.google.com", "/"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "", "/"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "",
-                                                       "www.google.com/"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
-                                                       "www.google.com/", "/"));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
-                                                       "www.google.com", ""));
-  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "www.google",
-                                                       ".com/"));
-
-  // Test acception/rejection of various input combinations.
-  // |input_headers| is an array of pairs. The first value of each pair is a
-  // string that will be used as one of the inputs of GetPushPromiseUrl(). The
-  // second value of each pair is a bitfield where the lowest 3 bits indicate
-  // for which headers that string is valid (in a PUSH_PROMISE). For example,
-  // the string "http" would be valid for both the ":scheme" and ":authority"
-  // headers, so the bitfield paired with it is set to SCHEME | AUTH.
-  const unsigned char SCHEME = (1u << 0);
-  const unsigned char AUTH = (1u << 1);
-  const unsigned char PATH = (1u << 2);
-  const std::pair<const char*, unsigned char> input_headers[] = {
-      {"http", SCHEME | AUTH},
-      {"https", SCHEME | AUTH},
-      {"hTtP", SCHEME | AUTH},
-      {"HTTPS", SCHEME | AUTH},
-      {"www.google.com", AUTH},
-      {"90af90e0", AUTH},
-      {"12foo%20-bar:00001233", AUTH},
-      {"GOO\u200b\u2060\ufeffgoo", AUTH},
-      {"192.168.0.5", AUTH},
-      {"[::ffff:192.168.0.1.]", AUTH},
-      {"http:", AUTH},
-      {"bife l", AUTH},
-      {"/", PATH},
-      {"/foo/bar/baz", PATH},
-      {"/%20-2DVdkj.cie/foe_.iif/", PATH},
-      {"http://", 0},
-      {":443", 0},
-      {":80/eddd", 0},
-      {"google.com:-0", 0},
-      {"google.com:65536", 0},
-      {"http://google.com", 0},
-      {"http://google.com:39", 0},
-      {"//google.com/foo", 0},
-      {".com/", 0},
-      {"http://www.google.com/", 0},
-      {"http://foo:439", 0},
-      {"[::ffff:192.168", 0},
-      {"]/", 0},
-      {"//", 0}};
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(input_headers); ++i) {
-    bool should_accept = (input_headers[i].second & SCHEME);
-    for (size_t j = 0; j < ABSL_ARRAYSIZE(input_headers); ++j) {
-      bool should_accept_2 = should_accept && (input_headers[j].second & AUTH);
-      for (size_t k = 0; k < ABSL_ARRAYSIZE(input_headers); ++k) {
-        // |should_accept_3| indicates whether or not GetPushPromiseUrl() is
-        // expected to accept this input combination.
-        bool should_accept_3 =
-            should_accept_2 && (input_headers[k].second & PATH);
-
-        std::string url = SpdyServerPushUtils::GetPushPromiseUrl(
-            input_headers[i].first, input_headers[j].first,
-            input_headers[k].first);
-
-        ::testing::AssertionResult result = ::testing::AssertionSuccess();
-        if (url.empty() == should_accept_3) {
-          result = ::testing::AssertionFailure()
-                   << "GetPushPromiseUrl() accepted/rejected the inputs when "
-                      "it shouldn't have."
-                   << std::endl
-                   << "     scheme: " << input_headers[i].first << std::endl
-                   << "  authority: " << input_headers[j].first << std::endl
-                   << "       path: " << input_headers[k].first << std::endl
-                   << "Output: " << url << std::endl;
-        }
-        ASSERT_TRUE(result);
-      }
-    }
-  }
-
-  // Test canonicalization of various valid inputs.
-  EXPECT_EQ("http://www.google.com/", SpdyServerPushUtils::GetPushPromiseUrl(
-                                          "http", "www.google.com", "/"));
-  EXPECT_EQ("https://www.goo-gle.com/fOOo/baRR",
-            SpdyServerPushUtils::GetPushPromiseUrl("hTtPs", "wWw.gOo-gLE.cOm",
-                                                   "/fOOo/baRR"));
-  EXPECT_EQ("https://www.goo-gle.com:3278/pAth/To/reSOurce",
-            SpdyServerPushUtils::GetPushPromiseUrl(
-                "hTtPs", "Www.gOo-Gle.Com:000003278", "/pAth/To/reSOurce"));
-  EXPECT_EQ("https://foo%20bar/foo/bar/baz",
-            SpdyServerPushUtils::GetPushPromiseUrl("https", "foo bar",
-                                                   "/foo/bar/baz"));
-  EXPECT_EQ("http://foo.com:70/e/", SpdyServerPushUtils::GetPushPromiseUrl(
-                                        "http", "foo.com:0000070", "/e/"));
-  EXPECT_EQ("http://192.168.0.1:70/e/",
-            SpdyServerPushUtils::GetPushPromiseUrl(
-                "http", "0300.0250.00.01:0070", "/e/"));
-  EXPECT_EQ("http://192.168.0.1/e/", SpdyServerPushUtils::GetPushPromiseUrl(
-                                         "http", "0xC0a80001", "/e/"));
-  EXPECT_EQ("http://[::c0a8:1]/", SpdyServerPushUtils::GetPushPromiseUrl(
-                                      "http", "[::192.168.0.1]", "/"));
-  EXPECT_EQ("https://[::ffff:c0a8:1]/",
-            SpdyServerPushUtils::GetPushPromiseUrl(
-                "https", "[::ffff:0xC0.0Xa8.0x0.0x1]", "/"));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/spdy_utils.cc b/quic/core/http/spdy_utils.cc
deleted file mode 100644
index 5b74407..0000000
--- a/quic/core/http/spdy_utils.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/spdy_utils.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::SpdyHeaderBlock;
-
-namespace quic {
-
-// static
-bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length,
-                                                SpdyHeaderBlock* headers) {
-  auto it = headers->find("content-length");
-  if (it == headers->end()) {
-    return false;
-  } else {
-    // Check whether multiple values are consistent.
-    absl::string_view content_length_header = it->second;
-    std::vector<absl::string_view> values =
-        absl::StrSplit(content_length_header, '\0');
-    for (const absl::string_view& value : values) {
-      uint64_t new_value;
-      if (!absl::SimpleAtoi(value, &new_value) ||
-          !quiche::QuicheTextUtils::IsAllDigits(value)) {
-        QUIC_DLOG(ERROR)
-            << "Content length was either unparseable or negative.";
-        return false;
-      }
-      if (*content_length < 0) {
-        *content_length = new_value;
-        continue;
-      }
-      if (new_value != static_cast<uint64_t>(*content_length)) {
-        QUIC_DLOG(ERROR)
-            << "Parsed content length " << new_value << " is "
-            << "inconsistent with previously detected content length "
-            << *content_length;
-        return false;
-      }
-    }
-    return true;
-  }
-}
-
-bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
-                                       int64_t* content_length,
-                                       SpdyHeaderBlock* headers) {
-  for (const auto& p : header_list) {
-    const std::string& name = p.first;
-    if (name.empty()) {
-      QUIC_DLOG(ERROR) << "Header name must not be empty.";
-      return false;
-    }
-
-    if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
-      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
-                       << " contains upper-case characters.";
-      return false;
-    }
-
-    headers->AppendValueOrAddHeader(name, p.second);
-  }
-
-  if (headers->contains("content-length") &&
-      !ExtractContentLengthFromHeaders(content_length, headers)) {
-    return false;
-  }
-
-  QUIC_DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
-  return true;
-}
-
-bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
-                                        bool expect_final_byte_offset,
-                                        size_t* final_byte_offset,
-                                        SpdyHeaderBlock* trailers) {
-  bool found_final_byte_offset = false;
-  for (const auto& p : header_list) {
-    const std::string& name = p.first;
-
-    // Pull out the final offset pseudo header which indicates the number of
-    // response body bytes expected.
-    if (expect_final_byte_offset && !found_final_byte_offset &&
-        name == kFinalOffsetHeaderKey &&
-        absl::SimpleAtoi(p.second, final_byte_offset)) {
-      found_final_byte_offset = true;
-      continue;
-    }
-
-    if (name.empty() || name[0] == ':') {
-      QUIC_DLOG(ERROR)
-          << "Trailers must not be empty, and must not contain pseudo-"
-          << "headers. Found: '" << name << "'";
-      return false;
-    }
-
-    if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
-      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
-                       << " contains upper-case characters.";
-      return false;
-    }
-
-    trailers->AppendValueOrAddHeader(name, p.second);
-  }
-
-  if (expect_final_byte_offset && !found_final_byte_offset) {
-    QUIC_DLOG(ERROR) << "Required key '" << kFinalOffsetHeaderKey
-                     << "' not present";
-    return false;
-  }
-
-  // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
-
-  QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
-  return true;
-}
-
-// static
-// TODO(danzh): Move it to quic/tools/ and switch to use GURL.
-bool SpdyUtils::PopulateHeaderBlockFromUrl(const std::string url,
-                                           SpdyHeaderBlock* headers) {
-  (*headers)[":method"] = "GET";
-  size_t pos = url.find("://");
-  if (pos == std::string::npos) {
-    return false;
-  }
-  (*headers)[":scheme"] = url.substr(0, pos);
-  size_t start = pos + 3;
-  pos = url.find('/', start);
-  if (pos == std::string::npos) {
-    (*headers)[":authority"] = url.substr(start);
-    (*headers)[":path"] = "/";
-    return true;
-  }
-  (*headers)[":authority"] = url.substr(start, pos - start);
-  (*headers)[":path"] = url.substr(pos);
-  return true;
-}
-
-// static
-absl::optional<QuicDatagramStreamId> SpdyUtils::ParseDatagramFlowIdHeader(
-    const spdy::SpdyHeaderBlock& headers) {
-  auto flow_id_pair = headers.find("datagram-flow-id");
-  if (flow_id_pair == headers.end()) {
-    return absl::nullopt;
-  }
-  std::vector<absl::string_view> flow_id_strings =
-      absl::StrSplit(flow_id_pair->second, ',');
-  absl::optional<QuicDatagramStreamId> first_named_flow_id;
-  for (absl::string_view flow_id_string : flow_id_strings) {
-    std::vector<absl::string_view> flow_id_components =
-        absl::StrSplit(flow_id_string, ';');
-    if (flow_id_components.empty()) {
-      continue;
-    }
-    absl::string_view flow_id_value_string = flow_id_components[0];
-    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
-        &flow_id_value_string);
-    QuicDatagramStreamId flow_id;
-    if (!absl::SimpleAtoi(flow_id_value_string, &flow_id)) {
-      continue;
-    }
-    if (flow_id_components.size() == 1) {
-      // This flow ID is unnamed, return this one.
-      return flow_id;
-    }
-    // Otherwise this is a named flow ID.
-    if (!first_named_flow_id.has_value()) {
-      first_named_flow_id = flow_id;
-    }
-  }
-  return first_named_flow_id;
-}
-
-// static
-void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
-                                        QuicDatagramStreamId flow_id) {
-  (*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
-}
-
-// static
-ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
-    const spdy::SpdyAltSvcWireFormat::AlternativeService&
-        alternative_service_entry,
-    const ParsedQuicVersionVector& supported_versions) {
-  for (const ParsedQuicVersion& version : supported_versions) {
-    if (version.AlpnDeferToRFCv1()) {
-      // Versions with share an ALPN with v1 are currently unable to be
-      // advertised with Alt-Svc.
-      continue;
-    }
-    if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
-      return version;
-    }
-  }
-
-  return ParsedQuicVersion::Unsupported();
-}
-
-}  // namespace quic
diff --git a/quic/core/http/spdy_utils.h b/quic/core/http/spdy_utils.h
deleted file mode 100644
index 85099ab..0000000
--- a/quic/core/http/spdy_utils.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
-#define QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/types/optional.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE SpdyUtils {
- public:
-  SpdyUtils() = delete;
-
-  // Populate |content length| with the value of the content-length header.
-  // Returns true on success, false if parsing fails or content-length header is
-  // missing.
-  static bool ExtractContentLengthFromHeaders(int64_t* content_length,
-                                              spdy::SpdyHeaderBlock* headers);
-
-  // Copies a list of headers to a SpdyHeaderBlock.
-  static bool CopyAndValidateHeaders(const QuicHeaderList& header_list,
-                                     int64_t* content_length,
-                                     spdy::SpdyHeaderBlock* headers);
-
-  // Copies a list of headers to a SpdyHeaderBlock.
-  // If |expect_final_byte_offset| is true, requires exactly one header field
-  // with key kFinalOffsetHeaderKey and an integer value.
-  // If |expect_final_byte_offset| is false, no kFinalOffsetHeaderKey may be
-  // present.
-  // Returns true if parsing is successful.  Returns false if the presence of
-  // kFinalOffsetHeaderKey does not match the value of
-  // |expect_final_byte_offset|, the kFinalOffsetHeaderKey value cannot be
-  // parsed, any other pseudo-header is present, an empty header key is present,
-  // or a header key contains an uppercase character.
-  static bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
-                                      bool expect_final_byte_offset,
-                                      size_t* final_byte_offset,
-                                      spdy::SpdyHeaderBlock* trailers);
-
-  // Populates the fields of |headers| to make a GET request of |url|,
-  // which must be fully-qualified.
-  static bool PopulateHeaderBlockFromUrl(const std::string url,
-                                         spdy::SpdyHeaderBlock* headers);
-
-  // Parses the "datagram-flow-id" header, returns the flow ID on success, or
-  // returns absl::nullopt if the header was not present or failed to parse.
-  static absl::optional<QuicDatagramStreamId> ParseDatagramFlowIdHeader(
-      const spdy::SpdyHeaderBlock& headers);
-
-  // Adds the "datagram-flow-id" header.
-  static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
-                                      QuicDatagramStreamId flow_id);
-
-  // Returns the advertised QUIC version from the specified alternative service
-  // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
-  // is advertised.
-  static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
-      const spdy::SpdyAltSvcWireFormat::AlternativeService&
-          alternative_service_entry,
-      const ParsedQuicVersionVector& supported_versions);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
diff --git a/quic/core/http/spdy_utils_test.cc b/quic/core/http/spdy_utils_test.cc
deleted file mode 100644
index 85c5cec..0000000
--- a/quic/core/http/spdy_utils_test.cc
+++ /dev/null
@@ -1,442 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/spdy_utils.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-
-using spdy::SpdyHeaderBlock;
-using testing::Pair;
-using testing::UnorderedElementsAre;
-
-namespace quic {
-namespace test {
-namespace {
-
-const bool kExpectFinalByteOffset = true;
-const bool kDoNotExpectFinalByteOffset = false;
-
-static std::unique_ptr<QuicHeaderList> FromList(
-    const QuicHeaderList::ListType& src) {
-  std::unique_ptr<QuicHeaderList> headers(new QuicHeaderList);
-  headers->OnHeaderBlockStart();
-  for (const auto& p : src) {
-    headers->OnHeader(p.first, p.second);
-  }
-  headers->OnHeaderBlockEnd(0, 0);
-  return headers;
-}
-
-static void ValidateDatagramFlowId(
-    const std::string& header_value,
-    absl::optional<QuicDatagramStreamId> expected_flow_id) {
-  SpdyHeaderBlock headers;
-  headers["datagram-flow-id"] = header_value;
-  ASSERT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), expected_flow_id);
-}
-
-}  // anonymous namespace
-
-using CopyAndValidateHeaders = QuicTest;
-
-TEST_F(CopyAndValidateHeaders, NormalUsage) {
-  auto headers = FromList({// All cookie crumbs are joined.
-                           {"cookie", " part 1"},
-                           {"cookie", "part 2 "},
-                           {"cookie", "part3"},
-
-                           // Already-delimited headers are passed through.
-                           {"passed-through", std::string("foo\0baz", 7)},
-
-                           // Other headers are joined on \0.
-                           {"joined", "value 1"},
-                           {"joined", "value 2"},
-
-                           // Empty headers remain empty.
-                           {"empty", ""},
-
-                           // Joined empty headers work as expected.
-                           {"empty-joined", ""},
-                           {"empty-joined", "foo"},
-                           {"empty-joined", ""},
-                           {"empty-joined", ""},
-
-                           // Non-continguous cookie crumb.
-                           {"cookie", " fin!"}});
-
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block,
-              UnorderedElementsAre(
-                  Pair("cookie", " part 1; part 2 ; part3;  fin!"),
-                  Pair("passed-through", absl::string_view("foo\0baz", 7)),
-                  Pair("joined", absl::string_view("value 1\0value 2", 15)),
-                  Pair("empty", ""),
-                  Pair("empty-joined", absl::string_view("\0foo\0\0", 6))));
-  EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, EmptyName) {
-  auto headers = FromList({{"foo", "foovalue"}, {"", "barvalue"}, {"baz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_FALSE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, UpperCaseName) {
-  auto headers =
-      FromList({{"foo", "foovalue"}, {"bar", "barvalue"}, {"bAz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_FALSE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, MultipleContentLengths) {
-  auto headers = FromList({{"content-length", "9"},
-                           {"foo", "foovalue"},
-                           {"content-length", "9"},
-                           {"bar", "barvalue"},
-                           {"baz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block, UnorderedElementsAre(
-                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
-                         Pair("content-length", absl::string_view("9\09", 3)),
-                         Pair("baz", "")));
-  EXPECT_EQ(9, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, InconsistentContentLengths) {
-  auto headers = FromList({{"content-length", "9"},
-                           {"foo", "foovalue"},
-                           {"content-length", "8"},
-                           {"bar", "barvalue"},
-                           {"baz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_FALSE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, LargeContentLength) {
-  auto headers = FromList({{"content-length", "9000000000"},
-                           {"foo", "foovalue"},
-                           {"bar", "barvalue"},
-                           {"baz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block,
-              UnorderedElementsAre(
-                  Pair("foo", "foovalue"), Pair("bar", "barvalue"),
-                  Pair("content-length", absl::string_view("9000000000")),
-                  Pair("baz", "")));
-  EXPECT_EQ(9000000000, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, NonDigitContentLength) {
-  // Section 3.3.2 of RFC 7230 defines content-length as being only digits.
-  // Number parsers might accept symbols like a leading plus; test that this
-  // fails to parse.
-  auto headers = FromList({{"content-length", "+123"},
-                           {"foo", "foovalue"},
-                           {"bar", "barvalue"},
-                           {"baz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  EXPECT_FALSE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-}
-
-TEST_F(CopyAndValidateHeaders, MultipleValues) {
-  auto headers = FromList({{"foo", "foovalue"},
-                           {"bar", "barvalue"},
-                           {"baz", ""},
-                           {"foo", "boo"},
-                           {"baz", "buzz"}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block, UnorderedElementsAre(
-                         Pair("foo", absl::string_view("foovalue\0boo", 12)),
-                         Pair("bar", "barvalue"),
-                         Pair("baz", absl::string_view("\0buzz", 5))));
-  EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, MoreThanTwoValues) {
-  auto headers = FromList({{"set-cookie", "value1"},
-                           {"set-cookie", "value2"},
-                           {"set-cookie", "value3"}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block, UnorderedElementsAre(Pair(
-                         "set-cookie",
-                         absl::string_view("value1\0value2\0value3", 20))));
-  EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, Cookie) {
-  auto headers = FromList({{"foo", "foovalue"},
-                           {"bar", "barvalue"},
-                           {"cookie", "value1"},
-                           {"baz", ""}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block, UnorderedElementsAre(
-                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
-                         Pair("cookie", "value1"), Pair("baz", "")));
-  EXPECT_EQ(-1, content_length);
-}
-
-TEST_F(CopyAndValidateHeaders, MultipleCookies) {
-  auto headers = FromList({{"foo", "foovalue"},
-                           {"bar", "barvalue"},
-                           {"cookie", "value1"},
-                           {"baz", ""},
-                           {"cookie", "value2"}});
-  int64_t content_length = -1;
-  SpdyHeaderBlock block;
-  ASSERT_TRUE(
-      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
-  EXPECT_THAT(block, UnorderedElementsAre(
-                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
-                         Pair("cookie", "value1; value2"), Pair("baz", "")));
-  EXPECT_EQ(-1, content_length);
-}
-
-using CopyAndValidateTrailers = QuicTest;
-
-TEST_F(CopyAndValidateTrailers, SimplestValidList) {
-  // Verify that the simplest trailers are valid: just a final byte offset that
-  // gets parsed successfully.
-  auto trailers = FromList({{kFinalOffsetHeaderKey, "1234"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-  EXPECT_EQ(1234u, final_byte_offset);
-}
-
-TEST_F(CopyAndValidateTrailers, EmptyTrailerListWithFinalByteOffsetExpected) {
-  // An empty trailer list will fail as expected key kFinalOffsetHeaderKey is
-  // not present.
-  QuicHeaderList trailers;
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
-      trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers,
-       EmptyTrailerListWithFinalByteOffsetNotExpected) {
-  // An empty trailer list will pass successfully if kFinalOffsetHeaderKey is
-  // not expected.
-  QuicHeaderList trailers;
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
-      trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
-  EXPECT_TRUE(block.empty());
-}
-
-TEST_F(CopyAndValidateTrailers, FinalByteOffsetExpectedButNotPresent) {
-  // Validation fails if expected kFinalOffsetHeaderKey is not present, even if
-  // the rest of the header block is valid.
-  auto trailers = FromList({{"key", "value"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedButPresent) {
-  // Validation fails if kFinalOffsetHeaderKey is present but should not be,
-  // even if the rest of the header block is valid.
-  auto trailers = FromList({{"key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedAndNotPresent) {
-  // Validation succeeds if kFinalOffsetHeaderKey is not expected and not
-  // present.
-  auto trailers = FromList({{"key", "value"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
-  EXPECT_THAT(block, UnorderedElementsAre(Pair("key", "value")));
-}
-
-TEST_F(CopyAndValidateTrailers, EmptyName) {
-  // Trailer validation will fail with an empty header key, in an otherwise
-  // valid block of trailers.
-  auto trailers = FromList({{"", "value"}, {kFinalOffsetHeaderKey, "1234"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, PseudoHeaderInTrailers) {
-  // Pseudo headers are illegal in trailers.
-  auto trailers =
-      FromList({{":pseudo_key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-}
-
-TEST_F(CopyAndValidateTrailers, DuplicateTrailers) {
-  // Duplicate trailers are allowed, and their values are concatenated into a
-  // single string delimted with '\0'. Some of the duplicate headers
-  // deliberately have an empty value.
-  auto trailers = FromList({{"key", "value0"},
-                            {"key", "value1"},
-                            {"key", ""},
-                            {"key", ""},
-                            {"key", "value2"},
-                            {"key", ""},
-                            {kFinalOffsetHeaderKey, "1234"},
-                            {"other_key", "value"},
-                            {"key", "non_contiguous_duplicate"}});
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
-      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
-  EXPECT_THAT(
-      block,
-      UnorderedElementsAre(
-          Pair("key",
-               absl::string_view(
-                   "value0\0value1\0\0\0value2\0\0non_contiguous_duplicate",
-                   48)),
-          Pair("other_key", "value")));
-}
-
-TEST_F(CopyAndValidateTrailers, DuplicateCookies) {
-  // Duplicate cookie headers in trailers should be concatenated into a single
-  //  "; " delimted string.
-  auto headers = FromList({{"cookie", " part 1"},
-                           {"cookie", "part 2 "},
-                           {"cookie", "part3"},
-                           {"key", "value"},
-                           {kFinalOffsetHeaderKey, "1234"},
-                           {"cookie", " non_contiguous_cookie!"}});
-
-  size_t final_byte_offset = 0;
-  SpdyHeaderBlock block;
-  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
-      *headers, kExpectFinalByteOffset, &final_byte_offset, &block));
-  EXPECT_THAT(
-      block,
-      UnorderedElementsAre(
-          Pair("cookie", " part 1; part 2 ; part3;  non_contiguous_cookie!"),
-          Pair("key", "value")));
-}
-
-using PopulateHeaderBlockFromUrl = QuicTest;
-
-TEST_F(PopulateHeaderBlockFromUrl, NormalUsage) {
-  std::string url = "https://www.google.com/index.html";
-  SpdyHeaderBlock headers;
-  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
-  EXPECT_EQ("https", headers[":scheme"].as_string());
-  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
-  EXPECT_EQ("/index.html", headers[":path"].as_string());
-}
-
-TEST_F(PopulateHeaderBlockFromUrl, UrlWithNoPath) {
-  std::string url = "https://www.google.com";
-  SpdyHeaderBlock headers;
-  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
-  EXPECT_EQ("https", headers[":scheme"].as_string());
-  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
-  EXPECT_EQ("/", headers[":path"].as_string());
-}
-
-TEST_F(PopulateHeaderBlockFromUrl, Failure) {
-  SpdyHeaderBlock headers;
-  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/", &headers));
-  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/index.html", &headers));
-  EXPECT_FALSE(
-      SpdyUtils::PopulateHeaderBlockFromUrl("www.google.com/", &headers));
-}
-
-using DatagramFlowIdTest = QuicTest;
-
-TEST_F(DatagramFlowIdTest, DatagramFlowId) {
-  // Test missing header.
-  SpdyHeaderBlock headers;
-  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), absl::nullopt);
-  // Add header and verify it parses.
-  QuicDatagramStreamId flow_id = 123;
-  SpdyUtils::AddDatagramFlowIdHeader(&headers, flow_id);
-  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), flow_id);
-  // Test empty header.
-  ValidateDatagramFlowId("", absl::nullopt);
-  // Test invalid header.
-  ValidateDatagramFlowId("M4SQU3", absl::nullopt);
-  // Test simple header.
-  ValidateDatagramFlowId("42", 42);
-  // Test with parameter.
-  ValidateDatagramFlowId("42; abc=def", 42);
-  // Test list.
-  ValidateDatagramFlowId("42, 44; ecn-ect0, 46; ecn-ect1, 48; ecn-ce", 42);
-  // Test reordered list.
-  ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
-}
-
-using ExtractQuicVersionFromAltSvcEntry = QuicTest;
-
-TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
-  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
-  spdy::SpdyAltSvcWireFormat::AlternativeService entry;
-  for (const ParsedQuicVersion& version : supported_versions) {
-    entry.protocol_id = AlpnForVersion(version);
-    ParsedQuicVersion expected_version = version;
-    // Versions with share an ALPN with v1 are currently unable to be
-    // advertised with Alt-Svc.
-    if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
-        version != ParsedQuicVersion::RFCv1()) {
-      expected_version = ParsedQuicVersion::RFCv1();
-    }
-    EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
-                                    entry, supported_versions))
-        << "version: " << version;
-  }
-}
-
-TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
-  spdy::SpdyAltSvcWireFormat::AlternativeService entry;
-  entry.protocol_id = "quic";
-  EXPECT_EQ(ParsedQuicVersion::Unsupported(),
-            SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
-                entry, AllSupportedVersions()));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/http/web_transport_http3.cc b/quic/core/http/web_transport_http3.cc
deleted file mode 100644
index f4e8040..0000000
--- a/quic/core/http/web_transport_http3.cc
+++ /dev/null
@@ -1,546 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/web_transport_http3.h"
-
-#include <limits>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/capsule.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-#define ENDPOINT \
-  (session_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-namespace quic {
-
-namespace {
-class QUIC_NO_EXPORT NoopWebTransportVisitor : public WebTransportVisitor {
-  void OnSessionReady(const spdy::SpdyHeaderBlock&) override {}
-  void OnSessionClosed(WebTransportSessionError /*error_code*/,
-                       const std::string& /*error_message*/) override {}
-  void OnIncomingBidirectionalStreamAvailable() override {}
-  void OnIncomingUnidirectionalStreamAvailable() override {}
-  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
-  void OnCanCreateNewOutgoingBidirectionalStream() override {}
-  void OnCanCreateNewOutgoingUnidirectionalStream() override {}
-};
-}  // namespace
-
-WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
-                                     QuicSpdyStream* connect_stream,
-                                     WebTransportSessionId id,
-                                     bool attempt_to_use_datagram_contexts)
-    : session_(session),
-      connect_stream_(connect_stream),
-      id_(id),
-      visitor_(std::make_unique<NoopWebTransportVisitor>()) {
-  QUICHE_DCHECK(session_->SupportsWebTransport());
-  QUICHE_DCHECK(IsValidWebTransportSessionId(id, session_->version()));
-  QUICHE_DCHECK_EQ(connect_stream_->id(), id);
-  connect_stream_->RegisterHttp3DatagramRegistrationVisitor(
-      this, attempt_to_use_datagram_contexts);
-  if (session_->perspective() == Perspective::IS_CLIENT) {
-    context_is_known_ = true;
-    context_currently_registered_ = true;
-    if (attempt_to_use_datagram_contexts) {
-      context_id_ = connect_stream_->GetNextDatagramContextId();
-    }
-  }
-}
-
-void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
-  streams_.insert(stream_id);
-
-  ParsedQuicVersion version = session_->version();
-  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
-                                    session_->perspective())) {
-    return;
-  }
-  if (QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
-    incoming_bidirectional_streams_.push_back(stream_id);
-    visitor_->OnIncomingBidirectionalStreamAvailable();
-  } else {
-    incoming_unidirectional_streams_.push_back(stream_id);
-    visitor_->OnIncomingUnidirectionalStreamAvailable();
-  }
-}
-
-void WebTransportHttp3::OnConnectStreamClosing() {
-  // Copy the stream list before iterating over it, as calls to ResetStream()
-  // can potentially mutate the |session_| list.
-  std::vector<QuicStreamId> streams(streams_.begin(), streams_.end());
-  streams_.clear();
-  for (QuicStreamId id : streams) {
-    session_->ResetStream(id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
-  }
-  if (context_currently_registered_) {
-    context_currently_registered_ = false;
-    connect_stream_->UnregisterHttp3DatagramContextId(context_id_);
-  }
-  connect_stream_->UnregisterHttp3DatagramRegistrationVisitor();
-
-  MaybeNotifyClose();
-}
-
-void WebTransportHttp3::CloseSession(WebTransportSessionError error_code,
-                                     absl::string_view error_message) {
-  if (close_sent_) {
-    QUIC_BUG(WebTransportHttp3 close sent twice)
-        << "Calling WebTransportHttp3::CloseSession() more than once is not "
-           "allowed.";
-    return;
-  }
-  close_sent_ = true;
-
-  // There can be a race between us trying to send our close and peer sending
-  // one.  If we received a close, however, we cannot send ours since we already
-  // closed the stream in response.
-  if (close_received_) {
-    QUIC_DLOG(INFO) << "Not sending CLOSE_WEBTRANSPORT_SESSION as we've "
-                       "already sent one from peer.";
-    return;
-  }
-
-  error_code_ = error_code;
-  error_message_ = std::string(error_message);
-  QuicConnection::ScopedPacketFlusher flusher(
-      connect_stream_->spdy_session()->connection());
-  connect_stream_->WriteCapsule(
-      Capsule::CloseWebTransportSession(error_code, error_message),
-      /*fin=*/true);
-}
-
-void WebTransportHttp3::OnCloseReceived(WebTransportSessionError error_code,
-                                        absl::string_view error_message) {
-  if (close_received_) {
-    QUIC_BUG(WebTransportHttp3 notified of close received twice)
-        << "WebTransportHttp3::OnCloseReceived() may be only called once.";
-  }
-  close_received_ = true;
-
-  // If the peer has sent a close after we sent our own, keep the local error.
-  if (close_sent_) {
-    QUIC_DLOG(INFO) << "Ignoring received CLOSE_WEBTRANSPORT_SESSION as we've "
-                       "already sent our own.";
-    return;
-  }
-
-  error_code_ = error_code;
-  error_message_ = std::string(error_message);
-  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
-  MaybeNotifyClose();
-}
-
-void WebTransportHttp3::OnConnectStreamFinReceived() {
-  // If we already received a CLOSE_WEBTRANSPORT_SESSION capsule, we don't need
-  // to do anything about receiving a FIN, since we already sent one in
-  // response.
-  if (close_received_) {
-    return;
-  }
-  close_received_ = true;
-  if (close_sent_) {
-    QUIC_DLOG(INFO) << "Ignoring received FIN as we've already sent our close.";
-    return;
-  }
-
-  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
-  MaybeNotifyClose();
-}
-
-void WebTransportHttp3::CloseSessionWithFinOnlyForTests() {
-  QUICHE_DCHECK(!close_sent_);
-  close_sent_ = true;
-  if (close_received_) {
-    return;
-  }
-
-  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
-}
-
-void WebTransportHttp3::HeadersReceived(const spdy::SpdyHeaderBlock& headers) {
-  if (session_->perspective() == Perspective::IS_CLIENT) {
-    int status_code;
-    if (!QuicSpdyStream::ParseHeaderStatusCode(headers, &status_code)) {
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "Received WebTransport headers from server without "
-                       "a valid status code, rejecting.";
-      rejection_reason_ = WebTransportHttp3RejectionReason::kNoStatusCode;
-      return;
-    }
-    bool valid_status = status_code >= 200 && status_code <= 299;
-    if (!valid_status) {
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "Received WebTransport headers from server with "
-                       "status code "
-                    << status_code << ", rejecting.";
-      rejection_reason_ = WebTransportHttp3RejectionReason::kWrongStatusCode;
-      return;
-    }
-    bool should_validate_version =
-        session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
-        session_->ShouldValidateWebTransportVersion();
-    if (should_validate_version) {
-      auto draft_version_it = headers.find("sec-webtransport-http3-draft");
-      if (draft_version_it == headers.end()) {
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "Received WebTransport headers from server without "
-                         "a draft version, rejecting.";
-        rejection_reason_ =
-            WebTransportHttp3RejectionReason::kMissingDraftVersion;
-        return;
-      }
-      if (draft_version_it->second != "draft02") {
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "Received WebTransport headers from server with "
-                         "an unknown draft version ("
-                      << draft_version_it->second << "), rejecting.";
-        rejection_reason_ =
-            WebTransportHttp3RejectionReason::kUnsupportedDraftVersion;
-        return;
-      }
-    }
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "WebTransport session " << id_ << " ready.";
-  ready_ = true;
-  visitor_->OnSessionReady(headers);
-  session_->ProcessBufferedWebTransportStreamsForSession(this);
-}
-
-WebTransportStream* WebTransportHttp3::AcceptIncomingBidirectionalStream() {
-  while (!incoming_bidirectional_streams_.empty()) {
-    QuicStreamId id = incoming_bidirectional_streams_.front();
-    incoming_bidirectional_streams_.pop_front();
-    QuicSpdyStream* stream = session_->GetOrCreateSpdyDataStream(id);
-    if (stream == nullptr) {
-      // Skip the streams that were reset in between the time they were
-      // receieved and the time the client has polled for them.
-      continue;
-    }
-    return stream->web_transport_stream();
-  }
-  return nullptr;
-}
-
-WebTransportStream* WebTransportHttp3::AcceptIncomingUnidirectionalStream() {
-  while (!incoming_unidirectional_streams_.empty()) {
-    QuicStreamId id = incoming_unidirectional_streams_.front();
-    incoming_unidirectional_streams_.pop_front();
-    QuicStream* stream = session_->GetOrCreateStream(id);
-    if (stream == nullptr) {
-      // Skip the streams that were reset in between the time they were
-      // receieved and the time the client has polled for them.
-      continue;
-    }
-    return static_cast<WebTransportHttp3UnidirectionalStream*>(stream)
-        ->interface();
-  }
-  return nullptr;
-}
-
-bool WebTransportHttp3::CanOpenNextOutgoingBidirectionalStream() {
-  return session_->CanOpenOutgoingBidirectionalWebTransportStream(id_);
-}
-bool WebTransportHttp3::CanOpenNextOutgoingUnidirectionalStream() {
-  return session_->CanOpenOutgoingUnidirectionalWebTransportStream(id_);
-}
-WebTransportStream* WebTransportHttp3::OpenOutgoingBidirectionalStream() {
-  QuicSpdyStream* stream =
-      session_->CreateOutgoingBidirectionalWebTransportStream(this);
-  if (stream == nullptr) {
-    // If stream cannot be created due to flow control or other errors, return
-    // nullptr.
-    return nullptr;
-  }
-  return stream->web_transport_stream();
-}
-
-WebTransportStream* WebTransportHttp3::OpenOutgoingUnidirectionalStream() {
-  WebTransportHttp3UnidirectionalStream* stream =
-      session_->CreateOutgoingUnidirectionalWebTransportStream(this);
-  if (stream == nullptr) {
-    // If stream cannot be created due to flow control, return nullptr.
-    return nullptr;
-  }
-  return stream->interface();
-}
-
-MessageStatus WebTransportHttp3::SendOrQueueDatagram(
-    quiche::QuicheMemSlice datagram) {
-  return connect_stream_->SendHttp3Datagram(
-      context_id_, absl::string_view(datagram.data(), datagram.length()));
-}
-
-QuicByteCount WebTransportHttp3::GetMaxDatagramSize() const {
-  return connect_stream_->GetMaxDatagramSize(context_id_);
-}
-
-void WebTransportHttp3::SetDatagramMaxTimeInQueue(
-    QuicTime::Delta max_time_in_queue) {
-  connect_stream_->SetMaxDatagramTimeInQueue(max_time_in_queue);
-}
-
-void WebTransportHttp3::OnHttp3Datagram(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
-  QUICHE_DCHECK_EQ(stream_id, connect_stream_->id());
-  QUICHE_DCHECK(context_id == context_id_);
-  visitor_->OnDatagramReceived(payload);
-}
-
-void WebTransportHttp3::OnContextReceived(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  if (stream_id != connect_stream_->id()) {
-    QUIC_BUG(WT3 bad datagram context registration)
-        << ENDPOINT << "Registered stream ID " << stream_id << ", expected "
-        << connect_stream_->id();
-    return;
-  }
-  if (format_type != DatagramFormatType::WEBTRANSPORT) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected datagram format type "
-                    << DatagramFormatTypeToString(format_type);
-    return;
-  }
-  if (!format_additional_data.empty()) {
-    QUIC_DLOG(ERROR)
-        << ENDPOINT
-        << "Received non-empty format additional data for context ID "
-        << (context_id_.has_value() ? context_id_.value() : 0)
-        << " on stream ID " << connect_stream_->id();
-    session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
-    return;
-  }
-  if (!context_is_known_) {
-    context_is_known_ = true;
-    context_id_ = context_id;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected context ID "
-                    << (context_id.has_value() ? context_id.value() : 0)
-                    << " instead of "
-                    << (context_id_.has_value() ? context_id_.value() : 0)
-                    << " on stream ID " << connect_stream_->id();
-    return;
-  }
-  if (session_->perspective() == Perspective::IS_SERVER) {
-    if (context_currently_registered_) {
-      QUIC_DLOG(ERROR) << ENDPOINT << "Received duplicate context ID "
-                       << (context_id_.has_value() ? context_id_.value() : 0)
-                       << " on stream ID " << connect_stream_->id();
-      session_->ResetStream(connect_stream_->id(), QUIC_STREAM_CANCELLED);
-      return;
-    }
-    context_currently_registered_ = true;
-    connect_stream_->RegisterHttp3DatagramContextId(
-        context_id_, format_type, format_additional_data, this);
-  }
-}
-
-void WebTransportHttp3::OnContextClosed(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    ContextCloseCode close_code, absl::string_view close_details) {
-  if (stream_id != connect_stream_->id()) {
-    QUIC_BUG(WT3 bad datagram context registration)
-        << ENDPOINT << "Closed context on stream ID " << stream_id
-        << ", expected " << connect_stream_->id();
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected close of context ID "
-                    << (context_id.has_value() ? context_id.value() : 0)
-                    << " instead of "
-                    << (context_id_.has_value() ? context_id_.value() : 0)
-                    << " on stream ID " << connect_stream_->id();
-    return;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT
-                  << "Received datagram context close with close code "
-                  << close_code << " close details \"" << close_details
-                  << "\" on stream ID " << connect_stream_->id()
-                  << ", resetting stream";
-  session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
-}
-
-void WebTransportHttp3::MaybeNotifyClose() {
-  if (close_notified_) {
-    return;
-  }
-  close_notified_ = true;
-  visitor_->OnSessionClosed(error_code_, error_message_);
-}
-
-WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
-    PendingStream* pending, QuicSpdySession* session)
-    : QuicStream(pending, session, /*is_static=*/false),
-      session_(session),
-      adapter_(session, this, sequencer()),
-      needs_to_send_preamble_(false) {}
-
-WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
-    QuicStreamId id, QuicSpdySession* session, WebTransportSessionId session_id)
-    : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL),
-      session_(session),
-      adapter_(session, this, sequencer()),
-      session_id_(session_id),
-      needs_to_send_preamble_(true) {}
-
-void WebTransportHttp3UnidirectionalStream::WritePreamble() {
-  if (!needs_to_send_preamble_ || !session_id_.has_value()) {
-    QUIC_BUG(WebTransportHttp3UnidirectionalStream duplicate preamble)
-        << ENDPOINT << "Sending preamble on stream ID " << id()
-        << " at the wrong time.";
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                         "Attempting to send a WebTransport unidirectional "
-                         "stream preamble at the wrong time.");
-    return;
-  }
-
-  QuicConnection::ScopedPacketFlusher flusher(session_->connection());
-  char buffer[sizeof(uint64_t) * 2];  // varint62, varint62
-  QuicDataWriter writer(sizeof(buffer), buffer);
-  bool success = true;
-  success = success && writer.WriteVarInt62(kWebTransportUnidirectionalStream);
-  success = success && writer.WriteVarInt62(*session_id_);
-  QUICHE_DCHECK(success);
-  WriteOrBufferData(absl::string_view(buffer, writer.length()), /*fin=*/false,
-                    /*ack_listener=*/nullptr);
-  QUIC_DVLOG(1) << ENDPOINT << "Sent stream type and session ID ("
-                << *session_id_ << ") on WebTransport stream " << id();
-  needs_to_send_preamble_ = false;
-}
-
-bool WebTransportHttp3UnidirectionalStream::ReadSessionId() {
-  iovec iov;
-  if (!sequencer()->GetReadableRegion(&iov)) {
-    return false;
-  }
-  QuicDataReader reader(static_cast<const char*>(iov.iov_base), iov.iov_len);
-  WebTransportSessionId session_id;
-  uint8_t session_id_length = reader.PeekVarInt62Length();
-  if (!reader.ReadVarInt62(&session_id)) {
-    // If all of the data has been received, and we still cannot associate the
-    // stream with a session, consume all of the data so that the stream can
-    // be closed.
-    if (sequencer()->NumBytesConsumed() + sequencer()->NumBytesBuffered() >=
-        sequencer()->close_offset()) {
-      QUIC_DLOG(WARNING)
-          << ENDPOINT << "Failed to associate WebTransport stream " << id()
-          << " with a session because the stream ended prematurely.";
-      sequencer()->MarkConsumed(sequencer()->NumBytesBuffered());
-    }
-    return false;
-  }
-  sequencer()->MarkConsumed(session_id_length);
-  session_id_ = session_id;
-  session_->AssociateIncomingWebTransportStreamWithSession(session_id, id());
-  return true;
-}
-
-void WebTransportHttp3UnidirectionalStream::OnDataAvailable() {
-  if (!session_id_.has_value()) {
-    if (!ReadSessionId()) {
-      return;
-    }
-  }
-
-  adapter_.OnDataAvailable();
-}
-
-void WebTransportHttp3UnidirectionalStream::OnCanWriteNewData() {
-  adapter_.OnCanWriteNewData();
-}
-
-void WebTransportHttp3UnidirectionalStream::OnClose() {
-  QuicStream::OnClose();
-
-  if (!session_id_.has_value()) {
-    return;
-  }
-  WebTransportHttp3* session = session_->GetWebTransportSession(*session_id_);
-  if (session == nullptr) {
-    QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
-                       << " attempted to notify parent session " << *session_id_
-                       << ", but the session could not be found.";
-    return;
-  }
-  session->OnStreamClosed(id());
-}
-
-void WebTransportHttp3UnidirectionalStream::OnStreamReset(
-    const QuicRstStreamFrame& frame) {
-  if (adapter_.visitor() != nullptr) {
-    adapter_.visitor()->OnResetStreamReceived(
-        Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
-  }
-  QuicStream::OnStreamReset(frame);
-}
-bool WebTransportHttp3UnidirectionalStream::OnStopSending(
-    QuicResetStreamError error) {
-  if (adapter_.visitor() != nullptr) {
-    adapter_.visitor()->OnStopSendingReceived(
-        Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
-  }
-  return QuicStream::OnStopSending(error);
-}
-void WebTransportHttp3UnidirectionalStream::OnWriteSideInDataRecvdState() {
-  if (adapter_.visitor() != nullptr) {
-    adapter_.visitor()->OnWriteSideInDataRecvdState();
-  }
-
-  QuicStream::OnWriteSideInDataRecvdState();
-}
-
-namespace {
-constexpr uint64_t kWebTransportMappedErrorCodeFirst = 0x52e4a40fa8db;
-constexpr uint64_t kWebTransportMappedErrorCodeLast = 0x52e4a40fa9e2;
-constexpr WebTransportStreamError kDefaultWebTransportError = 0;
-}  // namespace
-
-absl::optional<WebTransportStreamError> Http3ErrorToWebTransport(
-    uint64_t http3_error_code) {
-  // Ensure the code is within the valid range.
-  if (http3_error_code < kWebTransportMappedErrorCodeFirst ||
-      http3_error_code > kWebTransportMappedErrorCodeLast) {
-    return absl::nullopt;
-  }
-  // Exclude GREASE codepoints.
-  if ((http3_error_code - 0x21) % 0x1f == 0) {
-    return absl::nullopt;
-  }
-
-  uint64_t shifted = http3_error_code - kWebTransportMappedErrorCodeFirst;
-  uint64_t result = shifted - shifted / 0x1f;
-  QUICHE_DCHECK_LE(result, std::numeric_limits<uint8_t>::max());
-  return result;
-}
-
-WebTransportStreamError Http3ErrorToWebTransportOrDefault(
-    uint64_t http3_error_code) {
-  absl::optional<WebTransportStreamError> result =
-      Http3ErrorToWebTransport(http3_error_code);
-  return result.has_value() ? *result : kDefaultWebTransportError;
-}
-
-uint64_t WebTransportErrorToHttp3(
-    WebTransportStreamError webtransport_error_code) {
-  return kWebTransportMappedErrorCodeFirst + webtransport_error_code +
-         webtransport_error_code / 0x1e;
-}
-
-}  // namespace quic
diff --git a/quic/core/http/web_transport_http3.h b/quic/core/http/web_transport_http3.h
deleted file mode 100644
index f6f94cd..0000000
--- a/quic/core/http/web_transport_http3.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
-#define QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
-
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/http/web_transport_stream_adapter.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-class QuicSpdySession;
-class QuicSpdyStream;
-
-enum class WebTransportHttp3RejectionReason {
-  kNone,
-  kNoStatusCode,
-  kWrongStatusCode,
-  kMissingDraftVersion,
-  kUnsupportedDraftVersion,
-};
-
-// A session of WebTransport over HTTP/3.  The session is owned by
-// QuicSpdyStream object for the CONNECT stream that established it.
-//
-// WebTransport over HTTP/3 specification:
-// <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3>
-class QUIC_EXPORT_PRIVATE WebTransportHttp3
-    : public WebTransportSession,
-      public QuicSpdyStream::Http3DatagramRegistrationVisitor,
-      public QuicSpdyStream::Http3DatagramVisitor {
- public:
-  WebTransportHttp3(QuicSpdySession* session, QuicSpdyStream* connect_stream,
-                    WebTransportSessionId id,
-                    bool attempt_to_use_datagram_contexts);
-
-  void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
-  void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
-    visitor_ = std::move(visitor);
-  }
-
-  WebTransportSessionId id() { return id_; }
-  bool ready() { return ready_; }
-  absl::optional<QuicDatagramContextId> context_id() const {
-    return context_id_;
-  }
-
-  void AssociateStream(QuicStreamId stream_id);
-  void OnStreamClosed(QuicStreamId stream_id) { streams_.erase(stream_id); }
-  void OnConnectStreamClosing();
-
-  size_t NumberOfAssociatedStreams() { return streams_.size(); }
-
-  void CloseSession(WebTransportSessionError error_code,
-                    absl::string_view error_message) override;
-  void OnCloseReceived(WebTransportSessionError error_code,
-                       absl::string_view error_message);
-  void OnConnectStreamFinReceived();
-
-  // It is legal for WebTransport to be closed without a
-  // CLOSE_WEBTRANSPORT_SESSION capsule.  We always send a capsule, but we still
-  // need to ensure we handle this case correctly.
-  void CloseSessionWithFinOnlyForTests();
-
-  // Return the earliest incoming stream that has been received by the session
-  // but has not been accepted.  Returns nullptr if there are no incoming
-  // streams.
-  WebTransportStream* AcceptIncomingBidirectionalStream() override;
-  WebTransportStream* AcceptIncomingUnidirectionalStream() override;
-
-  bool CanOpenNextOutgoingBidirectionalStream() override;
-  bool CanOpenNextOutgoingUnidirectionalStream() override;
-  WebTransportStream* OpenOutgoingBidirectionalStream() override;
-  WebTransportStream* OpenOutgoingUnidirectionalStream() override;
-
-  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram) override;
-  QuicByteCount GetMaxDatagramSize() const override;
-  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override;
-
-  // From QuicSpdyStream::Http3DatagramVisitor.
-  void OnHttp3Datagram(QuicStreamId stream_id,
-                       absl::optional<QuicDatagramContextId> context_id,
-                       absl::string_view payload) override;
-
-  // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
-  void OnContextReceived(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         DatagramFormatType format_type,
-                         absl::string_view format_additional_data) override;
-  void OnContextClosed(QuicStreamId stream_id,
-                       absl::optional<QuicDatagramContextId> context_id,
-                       ContextCloseCode close_code,
-                       absl::string_view close_details) override;
-
-  bool close_received() const { return close_received_; }
-  WebTransportHttp3RejectionReason rejection_reason() const {
-    return rejection_reason_;
-  }
-
- private:
-  // Notifies the visitor that the connection has been closed.  Ensures that the
-  // visitor is only ever called once.
-  void MaybeNotifyClose();
-
-  QuicSpdySession* const session_;        // Unowned.
-  QuicSpdyStream* const connect_stream_;  // Unowned.
-  const WebTransportSessionId id_;
-  absl::optional<QuicDatagramContextId> context_id_;
-  // |ready_| is set to true when the peer has seen both sets of headers.
-  bool ready_ = false;
-  // Whether we know which |context_id_| to use. On the client this is always
-  // true, and on the server it becomes true when we receive a context
-  // registration capsule.
-  bool context_is_known_ = false;
-  // Whether |context_id_| is currently registered with |connect_stream_|.
-  bool context_currently_registered_ = false;
-  std::unique_ptr<WebTransportVisitor> visitor_;
-  absl::flat_hash_set<QuicStreamId> streams_;
-  quiche::QuicheCircularDeque<QuicStreamId> incoming_bidirectional_streams_;
-  quiche::QuicheCircularDeque<QuicStreamId> incoming_unidirectional_streams_;
-
-  bool close_sent_ = false;
-  bool close_received_ = false;
-  bool close_notified_ = false;
-
-  WebTransportHttp3RejectionReason rejection_reason_ =
-      WebTransportHttp3RejectionReason::kNone;
-  // Those are set to default values, which are used if the session is not
-  // closed cleanly using an appropriate capsule.
-  WebTransportSessionError error_code_ = 0;
-  std::string error_message_ = "";
-};
-
-class QUIC_EXPORT_PRIVATE WebTransportHttp3UnidirectionalStream
-    : public QuicStream {
- public:
-  // Incoming stream.
-  WebTransportHttp3UnidirectionalStream(PendingStream* pending,
-                                        QuicSpdySession* session);
-  // Outgoing stream.
-  WebTransportHttp3UnidirectionalStream(QuicStreamId id,
-                                        QuicSpdySession* session,
-                                        WebTransportSessionId session_id);
-
-  // Sends the stream type and the session ID on the stream.
-  void WritePreamble();
-
-  // Implementation of QuicStream.
-  void OnDataAvailable() override;
-  void OnCanWriteNewData() override;
-  void OnClose() override;
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-  bool OnStopSending(QuicResetStreamError error) override;
-  void OnWriteSideInDataRecvdState() override;
-
-  WebTransportStream* interface() { return &adapter_; }
-  void SetUnblocked() { sequencer()->SetUnblocked(); }
-
- private:
-  QuicSpdySession* session_;
-  WebTransportStreamAdapter adapter_;
-  absl::optional<WebTransportSessionId> session_id_;
-  bool needs_to_send_preamble_;
-
-  bool ReadSessionId();
-  // Closes the stream if all of the data has been received.
-  void MaybeCloseIncompleteStream();
-};
-
-// Remaps HTTP/3 error code into a WebTransport error code.  Returns nullopt if
-// the provided code is outside of valid range.
-QUIC_EXPORT_PRIVATE absl::optional<WebTransportStreamError>
-Http3ErrorToWebTransport(uint64_t http3_error_code);
-
-// Same as above, but returns default error value (zero) when none could be
-// mapped.
-QUIC_EXPORT_PRIVATE WebTransportStreamError
-Http3ErrorToWebTransportOrDefault(uint64_t http3_error_code);
-
-// Remaps WebTransport error code into an HTTP/3 error code.
-QUIC_EXPORT_PRIVATE uint64_t
-WebTransportErrorToHttp3(WebTransportStreamError webtransport_error_code);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
diff --git a/quic/core/http/web_transport_http3_test.cc b/quic/core/http/web_transport_http3_test.cc
deleted file mode 100644
index 0cf5b94..0000000
--- a/quic/core/http/web_transport_http3_test.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/web_transport_http3.h"
-
-#include <cstdint>
-#include <limits>
-
-#include "absl/types/optional.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-using ::testing::Optional;
-
-TEST(WebTransportHttp3Test, ErrorCodesToHttp3) {
-  EXPECT_EQ(0x52e4a40fa8dbu, WebTransportErrorToHttp3(0x00));
-  EXPECT_EQ(0x52e4a40fa9e2u, WebTransportErrorToHttp3(0xff));
-
-  EXPECT_EQ(0x52e4a40fa8f7u, WebTransportErrorToHttp3(0x1c));
-  EXPECT_EQ(0x52e4a40fa8f8u, WebTransportErrorToHttp3(0x1d));
-  //        0x52e4a40fa8f9 is a GREASE codepoint
-  EXPECT_EQ(0x52e4a40fa8fau, WebTransportErrorToHttp3(0x1e));
-}
-
-TEST(WebTransportHttp3Test, ErrorCodesToWebTransport) {
-  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8db), Optional(0x00));
-  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa9e2), Optional(0xff));
-
-  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f7), Optional(0x1cu));
-  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f8), Optional(0x1du));
-  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f9), absl::nullopt);
-  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8fa), Optional(0x1eu));
-
-  EXPECT_EQ(Http3ErrorToWebTransport(0), absl::nullopt);
-  EXPECT_EQ(Http3ErrorToWebTransport(std::numeric_limits<uint64_t>::max()),
-            absl::nullopt);
-}
-
-TEST(WebTransportHttp3Test, ErrorCodeRoundTrip) {
-  for (int error = 0; error < 256; error++) {
-    uint64_t http_error = WebTransportErrorToHttp3(error);
-    absl::optional<WebTransportStreamError> mapped_back =
-        quic::Http3ErrorToWebTransport(http_error);
-    EXPECT_THAT(mapped_back, Optional(error));
-  }
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/http/web_transport_stream_adapter.cc b/quic/core/http/web_transport_stream_adapter.cc
deleted file mode 100644
index 7c6e990..0000000
--- a/quic/core/http/web_transport_stream_adapter.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/http/web_transport_stream_adapter.h"
-
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_error_codes.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-namespace quic {
-
-WebTransportStreamAdapter::WebTransportStreamAdapter(
-    QuicSession* session,
-    QuicStream* stream,
-    QuicStreamSequencer* sequencer)
-    : session_(session), stream_(stream), sequencer_(sequencer) {}
-
-WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
-    char* buffer,
-    size_t buffer_size) {
-  iovec iov;
-  iov.iov_base = buffer;
-  iov.iov_len = buffer_size;
-  const size_t result = sequencer_->Readv(&iov, 1);
-  if (!fin_read_ && sequencer_->IsClosed()) {
-    fin_read_ = true;
-    stream_->OnFinRead();
-  }
-  return ReadResult{result, sequencer_->IsClosed()};
-}
-
-WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
-    std::string* output) {
-  const size_t old_size = output->size();
-  const size_t bytes_to_read = ReadableBytes();
-  output->resize(old_size + bytes_to_read);
-  ReadResult result = Read(&(*output)[old_size], bytes_to_read);
-  QUICHE_DCHECK_EQ(bytes_to_read, result.bytes_read);
-  output->resize(old_size + result.bytes_read);
-  return result;
-}
-
-bool WebTransportStreamAdapter::Write(absl::string_view data) {
-  if (!CanWrite()) {
-    return false;
-  }
-
-  quiche::QuicheMemSlice memslice(quiche::QuicheBuffer::Copy(
-      session_->connection()->helper()->GetStreamSendBufferAllocator(), data));
-  QuicConsumedData consumed =
-      stream_->WriteMemSlices(absl::MakeSpan(&memslice, 1), /*fin=*/false);
-
-  if (consumed.bytes_consumed == data.size()) {
-    return true;
-  }
-  if (consumed.bytes_consumed == 0) {
-    return false;
-  }
-  // WebTransportStream::Write() is an all-or-nothing write API.  To achieve
-  // that property, it relies on WriteMemSlices() being an all-or-nothing API.
-  // If WriteMemSlices() fails to provide that guarantee, we have no way to
-  // communicate a partial write to the caller, and thus it's safer to just
-  // close the connection.
-  QUIC_BUG(WebTransportStreamAdapter partial write)
-      << "WriteMemSlices() unexpectedly partially consumed the input "
-         "data, provided: "
-      << data.size() << ", written: " << consumed.bytes_consumed;
-  stream_->OnUnrecoverableError(
-      QUIC_INTERNAL_ERROR,
-      "WriteMemSlices() unexpectedly partially consumed the input data");
-  return false;
-}
-
-bool WebTransportStreamAdapter::SendFin() {
-  if (!CanWrite()) {
-    return false;
-  }
-
-  quiche::QuicheMemSlice empty;
-  QuicConsumedData consumed =
-      stream_->WriteMemSlices(absl::MakeSpan(&empty, 1), /*fin=*/true);
-  QUICHE_DCHECK_EQ(consumed.bytes_consumed, 0u);
-  return consumed.fin_consumed;
-}
-
-bool WebTransportStreamAdapter::CanWrite() const {
-  return stream_->CanWriteNewData() && !stream_->write_side_closed();
-}
-
-size_t WebTransportStreamAdapter::ReadableBytes() const {
-  return sequencer_->ReadableBytes();
-}
-
-void WebTransportStreamAdapter::OnDataAvailable() {
-  if (visitor_ == nullptr) {
-    return;
-  }
-  const bool fin_readable = sequencer_->IsClosed() && !fin_read_;
-  if (ReadableBytes() == 0 && !fin_readable) {
-    return;
-  }
-  visitor_->OnCanRead();
-}
-
-void WebTransportStreamAdapter::OnCanWriteNewData() {
-  // Ensure the origin check has been completed, as the stream can be notified
-  // about being writable before that.
-  if (!CanWrite()) {
-    return;
-  }
-  if (visitor_ != nullptr) {
-    visitor_->OnCanWrite();
-  }
-}
-
-void WebTransportStreamAdapter::ResetWithUserCode(
-    WebTransportStreamError error) {
-  stream_->ResetWriteSide(QuicResetStreamError(
-      QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
-}
-
-void WebTransportStreamAdapter::SendStopSending(WebTransportStreamError error) {
-  stream_->SendStopSending(QuicResetStreamError(
-      QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
-}
-
-}  // namespace quic
diff --git a/quic/core/http/web_transport_stream_adapter.h b/quic/core/http/web_transport_stream_adapter.h
deleted file mode 100644
index a761f6f..0000000
--- a/quic/core/http/web_transport_stream_adapter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
-#define QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
-
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-
-namespace quic {
-
-// Converts WebTransportStream API calls into QuicStream API calls.  The users
-// of this class can either subclass it, or wrap around it.
-class QUIC_EXPORT_PRIVATE WebTransportStreamAdapter
-    : public WebTransportStream {
- public:
-  WebTransportStreamAdapter(QuicSession* session,
-                            QuicStream* stream,
-                            QuicStreamSequencer* sequencer);
-
-  // WebTransportStream implementation.
-  ABSL_MUST_USE_RESULT ReadResult Read(char* buffer,
-                                       size_t buffer_size) override;
-  ABSL_MUST_USE_RESULT ReadResult Read(std::string* output) override;
-  ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
-  ABSL_MUST_USE_RESULT bool SendFin() override;
-  bool CanWrite() const override;
-  size_t ReadableBytes() const override;
-  void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
-    visitor_ = std::move(visitor);
-  }
-  QuicStreamId GetStreamId() const override { return stream_->id(); }
-
-  void ResetWithUserCode(WebTransportStreamError error) override;
-  void ResetDueToInternalError() override {
-    stream_->Reset(QUIC_STREAM_INTERNAL_ERROR);
-  }
-  void SendStopSending(WebTransportStreamError error) override;
-  void MaybeResetDueToStreamObjectGone() override {
-    if (stream_->write_side_closed() && stream_->read_side_closed()) {
-      return;
-    }
-    stream_->Reset(QUIC_STREAM_CANCELLED);
-  }
-
-  WebTransportStreamVisitor* visitor() override { return visitor_.get(); }
-
-  // Calls that need to be passed from the corresponding QuicStream methods.
-  void OnDataAvailable();
-  void OnCanWriteNewData();
-
- private:
-  QuicSession* session_;            // Unowned.
-  QuicStream* stream_;              // Unowned.
-  QuicStreamSequencer* sequencer_;  // Unowned.
-  std::unique_ptr<WebTransportStreamVisitor> visitor_;
-  bool fin_read_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
diff --git a/quic/core/legacy_quic_stream_id_manager.cc b/quic/core/legacy_quic_stream_id_manager.cc
deleted file mode 100644
index 19128ab..0000000
--- a/quic/core/legacy_quic_stream_id_manager.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/core/legacy_quic_stream_id_manager.h"
-
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-LegacyQuicStreamIdManager::LegacyQuicStreamIdManager(
-    Perspective perspective,
-    QuicTransportVersion transport_version,
-    size_t max_open_outgoing_streams,
-    size_t max_open_incoming_streams)
-    : perspective_(perspective),
-      transport_version_(transport_version),
-      max_open_outgoing_streams_(max_open_outgoing_streams),
-      max_open_incoming_streams_(max_open_incoming_streams),
-      next_outgoing_stream_id_(
-          QuicUtils::GetFirstBidirectionalStreamId(transport_version_,
-                                                   perspective_)),
-      largest_peer_created_stream_id_(
-          perspective_ == Perspective::IS_SERVER
-              ? (QuicVersionUsesCryptoFrames(transport_version_)
-                     ? QuicUtils::GetInvalidStreamId(transport_version_)
-                     : QuicUtils::GetCryptoStreamId(transport_version_))
-              : QuicUtils::GetInvalidStreamId(transport_version_)),
-      num_open_incoming_streams_(0),
-      num_open_outgoing_streams_(0) {}
-
-LegacyQuicStreamIdManager::~LegacyQuicStreamIdManager() {}
-
-bool LegacyQuicStreamIdManager::CanOpenNextOutgoingStream() const {
-  QUICHE_DCHECK_LE(num_open_outgoing_streams_, max_open_outgoing_streams_);
-  QUIC_DLOG_IF(INFO, num_open_outgoing_streams_ == max_open_outgoing_streams_)
-      << "Failed to create a new outgoing stream. "
-      << "Already " << num_open_outgoing_streams_ << " open.";
-  return num_open_outgoing_streams_ < max_open_outgoing_streams_;
-}
-
-bool LegacyQuicStreamIdManager::CanOpenIncomingStream() const {
-  return num_open_incoming_streams_ < max_open_incoming_streams_;
-}
-
-bool LegacyQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
-    const QuicStreamId stream_id) {
-  available_streams_.erase(stream_id);
-
-  if (largest_peer_created_stream_id_ !=
-          QuicUtils::GetInvalidStreamId(transport_version_) &&
-      stream_id <= largest_peer_created_stream_id_) {
-    return true;
-  }
-
-  // Check if the new number of available streams would cause the number of
-  // available streams to exceed the limit.  Note that the peer can create
-  // only alternately-numbered streams.
-  size_t additional_available_streams =
-      (stream_id - largest_peer_created_stream_id_) / 2 - 1;
-  if (largest_peer_created_stream_id_ ==
-      QuicUtils::GetInvalidStreamId(transport_version_)) {
-    additional_available_streams = (stream_id + 1) / 2 - 1;
-  }
-  size_t new_num_available_streams =
-      GetNumAvailableStreams() + additional_available_streams;
-  if (new_num_available_streams > MaxAvailableStreams()) {
-    QUIC_DLOG(INFO) << perspective_
-                    << "Failed to create a new incoming stream with id:"
-                    << stream_id << ".  There are already "
-                    << GetNumAvailableStreams()
-                    << " streams available, which would become "
-                    << new_num_available_streams << ", which exceeds the limit "
-                    << MaxAvailableStreams() << ".";
-    return false;
-  }
-  QuicStreamId first_available_stream = largest_peer_created_stream_id_ + 2;
-  if (largest_peer_created_stream_id_ ==
-      QuicUtils::GetInvalidStreamId(transport_version_)) {
-    first_available_stream = QuicUtils::GetFirstBidirectionalStreamId(
-        transport_version_, QuicUtils::InvertPerspective(perspective_));
-  }
-  for (QuicStreamId id = first_available_stream; id < stream_id; id += 2) {
-    available_streams_.insert(id);
-  }
-  largest_peer_created_stream_id_ = stream_id;
-
-  return true;
-}
-
-QuicStreamId LegacyQuicStreamIdManager::GetNextOutgoingStreamId() {
-  QuicStreamId id = next_outgoing_stream_id_;
-  next_outgoing_stream_id_ += 2;
-  return id;
-}
-
-void LegacyQuicStreamIdManager::ActivateStream(bool is_incoming) {
-  if (is_incoming) {
-    ++num_open_incoming_streams_;
-    return;
-  }
-  ++num_open_outgoing_streams_;
-}
-
-void LegacyQuicStreamIdManager::OnStreamClosed(bool is_incoming) {
-  if (is_incoming) {
-    QUIC_BUG_IF(quic_bug_12720_1, num_open_incoming_streams_ == 0);
-    --num_open_incoming_streams_;
-    return;
-  }
-  QUIC_BUG_IF(quic_bug_12720_2, num_open_outgoing_streams_ == 0);
-  --num_open_outgoing_streams_;
-}
-
-bool LegacyQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
-  if (!IsIncomingStream(id)) {
-    // Stream IDs under next_ougoing_stream_id_ are either open or previously
-    // open but now closed.
-    return id >= next_outgoing_stream_id_;
-  }
-  // For peer created streams, we also need to consider available streams.
-  return largest_peer_created_stream_id_ ==
-             QuicUtils::GetInvalidStreamId(transport_version_) ||
-         id > largest_peer_created_stream_id_ ||
-         available_streams_.contains(id);
-}
-
-bool LegacyQuicStreamIdManager::IsIncomingStream(QuicStreamId id) const {
-  return id % 2 != next_outgoing_stream_id_ % 2;
-}
-
-size_t LegacyQuicStreamIdManager::GetNumAvailableStreams() const {
-  return available_streams_.size();
-}
-
-size_t LegacyQuicStreamIdManager::MaxAvailableStreams() const {
-  return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier;
-}
-
-}  // namespace quic
diff --git a/quic/core/legacy_quic_stream_id_manager.h b/quic/core/legacy_quic_stream_id_manager.h
deleted file mode 100644
index 728d288..0000000
--- a/quic/core/legacy_quic_stream_id_manager.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
-
-#include "absl/container/flat_hash_set.h"
-#include "quic/core/quic_stream_id_manager.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-namespace test {
-class QuicSessionPeer;
-}  // namespace test
-
-class QuicSession;
-
-// Manages Google QUIC stream IDs. This manager is responsible for two
-// questions: 1) can next outgoing stream ID be allocated (if yes, what is the
-// next outgoing stream ID) and 2) can a new incoming stream be opened.
-class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
- public:
-  LegacyQuicStreamIdManager(Perspective perspective,
-                            QuicTransportVersion transport_version,
-                            size_t max_open_outgoing_streams,
-                            size_t max_open_incoming_streams);
-
-  ~LegacyQuicStreamIdManager();
-
-  // Returns true if the next outgoing stream ID can be allocated.
-  bool CanOpenNextOutgoingStream() const;
-
-  // Returns true if a new incoming stream can be opened.
-  bool CanOpenIncomingStream() const;
-
-  // Returns false when increasing the largest created stream id to |id| would
-  // violate the limit, so the connection should be closed.
-  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId id);
-
-  // Returns true if |id| is still available.
-  bool IsAvailableStream(QuicStreamId id) const;
-
-  // Returns the stream ID for a new outgoing stream, and increments the
-  // underlying counter.
-  QuicStreamId GetNextOutgoingStreamId();
-
-  // Called when a new stream is open.
-  void ActivateStream(bool is_incoming);
-
-  // Called when a stream ID is closed.
-  void OnStreamClosed(bool is_incoming);
-
-  // Return true if |id| is peer initiated.
-  bool IsIncomingStream(QuicStreamId id) const;
-
-  size_t MaxAvailableStreams() const;
-
-  void set_max_open_incoming_streams(size_t max_open_incoming_streams) {
-    max_open_incoming_streams_ = max_open_incoming_streams;
-  }
-
-  void set_max_open_outgoing_streams(size_t max_open_outgoing_streams) {
-    max_open_outgoing_streams_ = max_open_outgoing_streams;
-  }
-
-  void set_largest_peer_created_stream_id(
-      QuicStreamId largest_peer_created_stream_id) {
-    largest_peer_created_stream_id_ = largest_peer_created_stream_id;
-  }
-
-  size_t max_open_incoming_streams() const {
-    return max_open_incoming_streams_;
-  }
-
-  size_t max_open_outgoing_streams() const {
-    return max_open_outgoing_streams_;
-  }
-
-  QuicStreamId next_outgoing_stream_id() const {
-    return next_outgoing_stream_id_;
-  }
-
-  QuicStreamId largest_peer_created_stream_id() const {
-    return largest_peer_created_stream_id_;
-  }
-
-  size_t GetNumAvailableStreams() const;
-
-  size_t num_open_incoming_streams() const {
-    return num_open_incoming_streams_;
-  }
-  size_t num_open_outgoing_streams() const {
-    return num_open_outgoing_streams_;
-  }
-
- private:
-  friend class test::QuicSessionPeer;
-
-  const Perspective perspective_;
-  const QuicTransportVersion transport_version_;
-
-  // The maximum number of outgoing streams this connection can open.
-  size_t max_open_outgoing_streams_;
-
-  // The maximum number of incoming streams this connection will allow.
-  size_t max_open_incoming_streams_;
-
-  // The ID to use for the next outgoing stream.
-  QuicStreamId next_outgoing_stream_id_;
-
-  // Set of stream ids that are less than the largest stream id that has been
-  // received, but are nonetheless available to be created.
-  absl::flat_hash_set<QuicStreamId> available_streams_;
-
-  QuicStreamId largest_peer_created_stream_id_;
-
-  // A counter for peer initiated open streams.
-  size_t num_open_incoming_streams_;
-
-  // A counter for self initiated open streams.
-  size_t num_open_outgoing_streams_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quic/core/legacy_quic_stream_id_manager_test.cc b/quic/core/legacy_quic_stream_id_manager_test.cc
deleted file mode 100644
index a91a2f0..0000000
--- a/quic/core/legacy_quic_stream_id_manager_test.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/legacy_quic_stream_id_manager.h"
-
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::StrictMock;
-
-struct TestParams {
-  TestParams(ParsedQuicVersion version, Perspective perspective)
-      : version(version), perspective(perspective) {}
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(p.version),
-      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (ParsedQuicVersion version : AllSupportedVersions()) {
-    for (auto perspective : {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
-      // LegacyQuicStreamIdManager is only used when IETF QUIC frames are not
-      // presented.
-      if (!VersionHasIetfQuicFrames(version.transport_version)) {
-        params.push_back(TestParams(version, perspective));
-      }
-    }
-  }
-  return params;
-}
-
-class LegacyQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
- public:
-  LegacyQuicStreamIdManagerTest()
-      : manager_(GetParam().perspective,
-                 GetParam().version.transport_version,
-                 kDefaultMaxStreamsPerConnection,
-                 kDefaultMaxStreamsPerConnection) {}
-
- protected:
-  QuicStreamId GetNthPeerInitiatedId(int n) {
-    if (GetParam().perspective == Perspective::IS_SERVER) {
-      return QuicUtils::GetFirstBidirectionalStreamId(
-                 GetParam().version.transport_version, Perspective::IS_CLIENT) +
-             2 * n;
-    } else {
-      return 2 + 2 * n;
-    }
-  }
-
-  LegacyQuicStreamIdManager manager_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         LegacyQuicStreamIdManagerTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(LegacyQuicStreamIdManagerTest, CanOpenNextOutgoingStream) {
-  for (size_t i = 0; i < manager_.max_open_outgoing_streams() - 1; ++i) {
-    manager_.ActivateStream(/*is_incoming=*/false);
-  }
-  EXPECT_TRUE(manager_.CanOpenNextOutgoingStream());
-  manager_.ActivateStream(/*is_incoming=*/false);
-  EXPECT_FALSE(manager_.CanOpenNextOutgoingStream());
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, CanOpenIncomingStream) {
-  for (size_t i = 0; i < manager_.max_open_incoming_streams() - 1; ++i) {
-    manager_.ActivateStream(/*is_incoming=*/true);
-  }
-  EXPECT_TRUE(manager_.CanOpenIncomingStream());
-  manager_.ActivateStream(/*is_incoming=*/true);
-  EXPECT_FALSE(manager_.CanOpenIncomingStream());
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, AvailableStreams) {
-  ASSERT_TRUE(
-      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(3)));
-  EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(1)));
-  EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(2)));
-  ASSERT_TRUE(
-      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(2)));
-  ASSERT_TRUE(
-      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(1)));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, MaxAvailableStreams) {
-  // Test that the server closes the connection if a client makes too many data
-  // streams available.  The server accepts slightly more than the negotiated
-  // stream limit to deal with rare cases where a client FIN/RST is lost.
-  const size_t kMaxStreamsForTest = 10;
-  const size_t kAvailableStreamLimit = manager_.MaxAvailableStreams();
-  EXPECT_EQ(
-      manager_.max_open_incoming_streams() * kMaxAvailableStreamsMultiplier,
-      manager_.MaxAvailableStreams());
-  // The protocol specification requires that there can be at least 10 times
-  // as many available streams as the connection's maximum open streams.
-  EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit);
-
-  EXPECT_TRUE(
-      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(0)));
-
-  // Establish available streams up to the server's limit.
-  const int kLimitingStreamId =
-      GetNthPeerInitiatedId(kAvailableStreamLimit + 1);
-  // This exceeds the stream limit. In versions other than 99
-  // this is allowed. Version 99 hews to the IETF spec and does
-  // not allow it.
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId));
-
-  // This forces stream kLimitingStreamId + 2 to become available, which
-  // violates the quota.
-  EXPECT_FALSE(
-      manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId + 2 * 2));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, MaximumAvailableOpenedStreams) {
-  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
-
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-      stream_id + 2 * (manager_.max_open_incoming_streams() - 1)));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, TooManyAvailableStreams) {
-  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
-
-  // A stream ID which is too large to create.
-  QuicStreamId stream_id2 =
-      GetNthPeerInitiatedId(2 * manager_.MaxAvailableStreams() + 4);
-  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id2));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest, ManyAvailableStreams) {
-  // When max_open_streams_ is 200, should be able to create 200 streams
-  // out-of-order, that is, creating the one with the largest stream ID first.
-  manager_.set_max_open_incoming_streams(200);
-  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
-
-  // Create the largest stream ID of a threatened total of 200 streams.
-  // GetNth... starts at 0, so for 200 streams, get the 199th.
-  EXPECT_TRUE(
-      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(199)));
-}
-
-TEST_P(LegacyQuicStreamIdManagerTest,
-       TestMaxIncomingAndOutgoingStreamsAllowed) {
-  EXPECT_EQ(manager_.max_open_incoming_streams(),
-            kDefaultMaxStreamsPerConnection);
-  EXPECT_EQ(manager_.max_open_outgoing_streams(),
-            kDefaultMaxStreamsPerConnection);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/packet_number_indexed_queue.h b/quic/core/packet_number_indexed_queue.h
deleted file mode 100644
index 8e80c7d..0000000
--- a/quic/core/packet_number_indexed_queue.h
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
-#define QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-// PacketNumberIndexedQueue is a queue of mostly continuous numbered entries
-// which supports the following operations:
-// - adding elements to the end of the queue, or at some point past the end
-// - removing elements in any order
-// - retrieving elements
-// If all elements are inserted in order, all of the operations above are
-// amortized O(1) time.
-//
-// Internally, the data structure is a deque where each element is marked as
-// present or not.  The deque starts at the lowest present index.  Whenever an
-// element is removed, it's marked as not present, and the front of the deque is
-// cleared of elements that are not present.
-//
-// The tail of the queue is not cleared due to the assumption of entries being
-// inserted in order, though removing all elements of the queue will return it
-// to its initial state.
-//
-// Note that this data structure is inherently hazardous, since an addition of
-// just two entries will cause it to consume all of the memory available.
-// Because of that, it is not a general-purpose container and should not be used
-// as one.
-// TODO(wub): Update the comments when deprecating
-// --quic_bw_sampler_remove_packets_once_per_congestion_event.
-template <typename T>
-class QUIC_NO_EXPORT PacketNumberIndexedQueue {
- public:
-  PacketNumberIndexedQueue() : number_of_present_entries_(0) {}
-
-  // Retrieve the entry associated with the packet number.  Returns the pointer
-  // to the entry in case of success, or nullptr if the entry does not exist.
-  T* GetEntry(QuicPacketNumber packet_number);
-  const T* GetEntry(QuicPacketNumber packet_number) const;
-
-  // Inserts data associated |packet_number| into (or past) the end of the
-  // queue, filling up the missing intermediate entries as necessary.  Returns
-  // true if the element has been inserted successfully, false if it was already
-  // in the queue or inserted out of order.
-  template <typename... Args>
-  bool Emplace(QuicPacketNumber packet_number, Args&&... args);
-
-  // Removes data associated with |packet_number| and frees the slots in the
-  // queue as necessary.
-  bool Remove(QuicPacketNumber packet_number);
-
-  // Same as above, but if an entry is present in the queue, also call f(entry)
-  // before removing it.
-  template <typename Function>
-  bool Remove(QuicPacketNumber packet_number, Function f);
-
-  // Remove up to, but not including |packet_number|.
-  // Unused slots in the front are also removed, which means when the function
-  // returns, |first_packet()| can be larger than |packet_number|.
-  void RemoveUpTo(QuicPacketNumber packet_number);
-
-  bool IsEmpty() const { return number_of_present_entries_ == 0; }
-
-  // Returns the number of entries in the queue.
-  size_t number_of_present_entries() const {
-    return number_of_present_entries_;
-  }
-
-  // Returns the number of entries allocated in the underlying deque.  This is
-  // proportional to the memory usage of the queue.
-  size_t entry_slots_used() const { return entries_.size(); }
-
-  // Packet number of the first entry in the queue.
-  QuicPacketNumber first_packet() const { return first_packet_; }
-
-  // Packet number of the last entry ever inserted in the queue.  Note that the
-  // entry in question may have already been removed.  Zero if the queue is
-  // empty.
-  QuicPacketNumber last_packet() const {
-    if (IsEmpty()) {
-      return QuicPacketNumber();
-    }
-    return first_packet_ + entries_.size() - 1;
-  }
-
- private:
-  // Wrapper around T used to mark whether the entry is actually in the map.
-  struct QUIC_NO_EXPORT EntryWrapper : T {
-    // NOTE(wub): When quic_bw_sampler_remove_packets_once_per_congestion_event
-    // is enabled, |present| is false if and only if this is a placeholder entry
-    // for holes in the parent's |entries|.
-    bool present;
-
-    EntryWrapper() : present(false) {}
-
-    template <typename... Args>
-    explicit EntryWrapper(Args&&... args)
-        : T(std::forward<Args>(args)...), present(true) {}
-  };
-
-  // Cleans up unused slots in the front after removing an element.
-  void Cleanup();
-
-  const EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) const;
-  EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) {
-    const auto* const_this = this;
-    return const_cast<EntryWrapper*>(const_this->GetEntryWrapper(offset));
-  }
-
-  quiche::QuicheCircularDeque<EntryWrapper> entries_;
-  // NOTE(wub): When --quic_bw_sampler_remove_packets_once_per_congestion_event
-  // is enabled, |number_of_present_entries_| only represents number of holes,
-  // which does not include number of acked or lost packets.
-  size_t number_of_present_entries_;
-  QuicPacketNumber first_packet_;
-};
-
-template <typename T>
-T* PacketNumberIndexedQueue<T>::GetEntry(QuicPacketNumber packet_number) {
-  EntryWrapper* entry = GetEntryWrapper(packet_number);
-  if (entry == nullptr) {
-    return nullptr;
-  }
-  return entry;
-}
-
-template <typename T>
-const T* PacketNumberIndexedQueue<T>::GetEntry(
-    QuicPacketNumber packet_number) const {
-  const EntryWrapper* entry = GetEntryWrapper(packet_number);
-  if (entry == nullptr) {
-    return nullptr;
-  }
-  return entry;
-}
-
-template <typename T>
-template <typename... Args>
-bool PacketNumberIndexedQueue<T>::Emplace(QuicPacketNumber packet_number,
-                                          Args&&... args) {
-  if (!packet_number.IsInitialized()) {
-    QUIC_BUG(quic_bug_10359_1)
-        << "Try to insert an uninitialized packet number";
-    return false;
-  }
-
-  if (IsEmpty()) {
-    QUICHE_DCHECK(entries_.empty());
-    QUICHE_DCHECK(!first_packet_.IsInitialized());
-
-    entries_.emplace_back(std::forward<Args>(args)...);
-    number_of_present_entries_ = 1;
-    first_packet_ = packet_number;
-    return true;
-  }
-
-  // Do not allow insertion out-of-order.
-  if (packet_number <= last_packet()) {
-    return false;
-  }
-
-  // Handle potentially missing elements.
-  size_t offset = packet_number - first_packet_;
-  if (offset > entries_.size()) {
-    entries_.resize(offset);
-  }
-
-  number_of_present_entries_++;
-  entries_.emplace_back(std::forward<Args>(args)...);
-  QUICHE_DCHECK_EQ(packet_number, last_packet());
-  return true;
-}
-
-template <typename T>
-bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number) {
-  return Remove(packet_number, [](const T&) {});
-}
-
-template <typename T>
-template <typename Function>
-bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number,
-                                         Function f) {
-  EntryWrapper* entry = GetEntryWrapper(packet_number);
-  if (entry == nullptr) {
-    return false;
-  }
-  f(*static_cast<const T*>(entry));
-  entry->present = false;
-  number_of_present_entries_--;
-
-  if (packet_number == first_packet()) {
-    Cleanup();
-  }
-  return true;
-}
-
-template <typename T>
-void PacketNumberIndexedQueue<T>::RemoveUpTo(QuicPacketNumber packet_number) {
-  while (!entries_.empty() && first_packet_.IsInitialized() &&
-         first_packet_ < packet_number) {
-    if (entries_.front().present) {
-      number_of_present_entries_--;
-    }
-    entries_.pop_front();
-    first_packet_++;
-  }
-  Cleanup();
-}
-
-template <typename T>
-void PacketNumberIndexedQueue<T>::Cleanup() {
-  while (!entries_.empty() && !entries_.front().present) {
-    entries_.pop_front();
-    first_packet_++;
-  }
-  if (entries_.empty()) {
-    first_packet_.Clear();
-  }
-}
-
-template <typename T>
-auto PacketNumberIndexedQueue<T>::GetEntryWrapper(
-    QuicPacketNumber packet_number) const -> const EntryWrapper* {
-  if (!packet_number.IsInitialized() || IsEmpty() ||
-      packet_number < first_packet_) {
-    return nullptr;
-  }
-
-  uint64_t offset = packet_number - first_packet_;
-  if (offset >= entries_.size()) {
-    return nullptr;
-  }
-
-  const EntryWrapper* entry = &entries_[offset];
-  if (!entry->present) {
-    return nullptr;
-  }
-
-  return entry;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
diff --git a/quic/core/packet_number_indexed_queue_test.cc b/quic/core/packet_number_indexed_queue_test.cc
deleted file mode 100644
index cd41f9e..0000000
--- a/quic/core/packet_number_indexed_queue_test.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/packet_number_indexed_queue.h"
-
-#include <limits>
-#include <map>
-#include <string>
-
-#include "quic/core/quic_packet_number.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-class PacketNumberIndexedQueueTest : public QuicTest {
- public:
-  PacketNumberIndexedQueueTest() {}
-
- protected:
-  PacketNumberIndexedQueue<std::string> queue_;
-};
-
-TEST_F(PacketNumberIndexedQueueTest, InitialState) {
-  EXPECT_TRUE(queue_.IsEmpty());
-  EXPECT_FALSE(queue_.first_packet().IsInitialized());
-  EXPECT_FALSE(queue_.last_packet().IsInitialized());
-  EXPECT_EQ(0u, queue_.number_of_present_entries());
-  EXPECT_EQ(0u, queue_.entry_slots_used());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingContinuousElements) {
-  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1001), "one"));
-  EXPECT_EQ("one", *queue_.GetEntry(QuicPacketNumber(1001)));
-
-  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1002), "two"));
-  EXPECT_EQ("two", *queue_.GetEntry(QuicPacketNumber(1002)));
-
-  EXPECT_FALSE(queue_.IsEmpty());
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(1002u), queue_.last_packet());
-  EXPECT_EQ(2u, queue_.number_of_present_entries());
-  EXPECT_EQ(2u, queue_.entry_slots_used());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingOutOfOrder) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-
-  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1003), "three"));
-  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
-  EXPECT_EQ("three", *queue_.GetEntry(QuicPacketNumber(1003)));
-
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
-  EXPECT_EQ(2u, queue_.number_of_present_entries());
-  EXPECT_EQ(3u, queue_.entry_slots_used());
-
-  ASSERT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingIntoPast) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1000), "zero"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, InsertingDuplicate) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1001), "one"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveInTheMiddle) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  queue_.Emplace(QuicPacketNumber(1002), "two");
-  queue_.Emplace(QuicPacketNumber(1003), "three");
-
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
-  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
-
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
-  EXPECT_EQ(2u, queue_.number_of_present_entries());
-  EXPECT_EQ(3u, queue_.entry_slots_used());
-
-  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
-  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveAtImmediateEdges) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  queue_.Emplace(QuicPacketNumber(1002), "two");
-  queue_.Emplace(QuicPacketNumber(1003), "three");
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
-  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1001)));
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1003)));
-  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1003)));
-
-  EXPECT_EQ(QuicPacketNumber(1002u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
-  EXPECT_EQ(1u, queue_.number_of_present_entries());
-  EXPECT_EQ(2u, queue_.entry_slots_used());
-
-  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantFront) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  queue_.Emplace(QuicPacketNumber(1002), "one (kinda)");
-  queue_.Emplace(QuicPacketNumber(2001), "two");
-
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-  EXPECT_EQ(3u, queue_.number_of_present_entries());
-  EXPECT_EQ(1001u, queue_.entry_slots_used());
-
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-  EXPECT_EQ(2u, queue_.number_of_present_entries());
-  EXPECT_EQ(1001u, queue_.entry_slots_used());
-
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-  EXPECT_EQ(1u, queue_.number_of_present_entries());
-  EXPECT_EQ(1u, queue_.entry_slots_used());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantBack) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  queue_.Emplace(QuicPacketNumber(2001), "two");
-
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, ClearAndRepopulate) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  queue_.Emplace(QuicPacketNumber(2001), "two");
-
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
-  EXPECT_TRUE(queue_.IsEmpty());
-  EXPECT_FALSE(queue_.first_packet().IsInitialized());
-  EXPECT_FALSE(queue_.last_packet().IsInitialized());
-
-  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(101), "one"));
-  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(201), "two"));
-  EXPECT_EQ(QuicPacketNumber(101u), queue_.first_packet());
-  EXPECT_EQ(QuicPacketNumber(201u), queue_.last_packet());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsThatNeverExisted) {
-  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
-  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1002)));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsTwice) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
-  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
-  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
-}
-
-TEST_F(PacketNumberIndexedQueueTest, RemoveUpTo) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  queue_.Emplace(QuicPacketNumber(2001), "two");
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(2u, queue_.number_of_present_entries());
-
-  queue_.RemoveUpTo(QuicPacketNumber(1001));
-  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
-  EXPECT_EQ(2u, queue_.number_of_present_entries());
-
-  // Remove up to 1100, since [1100, 2001) are !present, they should be cleaned
-  // up from the front.
-  queue_.RemoveUpTo(QuicPacketNumber(1100));
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
-  EXPECT_EQ(1u, queue_.number_of_present_entries());
-
-  queue_.RemoveUpTo(QuicPacketNumber(2001));
-  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
-  EXPECT_EQ(1u, queue_.number_of_present_entries());
-
-  queue_.RemoveUpTo(QuicPacketNumber(2002));
-  EXPECT_FALSE(queue_.first_packet().IsInitialized());
-  EXPECT_EQ(0u, queue_.number_of_present_entries());
-}
-
-TEST_F(PacketNumberIndexedQueueTest, ConstGetter) {
-  queue_.Emplace(QuicPacketNumber(1001), "one");
-  const auto& const_queue = queue_;
-
-  EXPECT_EQ("one", *const_queue.GetEntry(QuicPacketNumber(1001)));
-  EXPECT_EQ(nullptr, const_queue.GetEntry(QuicPacketNumber(1002)));
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/proto/cached_network_parameters_proto.h b/quic/core/proto/cached_network_parameters_proto.h
deleted file mode 100644
index 5714801..0000000
--- a/quic/core/proto/cached_network_parameters_proto.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
-#define QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "quic/core/proto/cached_network_parameters.pb.h"
-
-#pragma clang diagnostic pop
-
-#endif  // QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
diff --git a/quic/core/proto/crypto_server_config_proto.h b/quic/core/proto/crypto_server_config_proto.h
deleted file mode 100644
index 908a289..0000000
--- a/quic/core/proto/crypto_server_config_proto.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
-#define QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "quic/core/proto/crypto_server_config.pb.h"
-
-#pragma clang diagnostic pop
-
-#endif  // QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
diff --git a/quic/core/proto/source_address_token.proto b/quic/core/proto/source_address_token.proto
deleted file mode 100644
index df12fa5..0000000
--- a/quic/core/proto/source_address_token.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-import "quic/core/proto/cached_network_parameters.proto";
-
-package quic;
-
-// A SourceAddressToken is serialised, encrypted and sent to clients so that
-// they can prove ownership of an IP address.
-message SourceAddressToken {
-  // ip contains either 4 (IPv4) or 16 (IPv6) bytes of IP address in network
-  // byte order.
-  required bytes ip = 1;
-  // timestamp contains a UNIX timestamp value of the time when the token was
-  // created.
-  required int64 timestamp = 2;
-  // The server can provide estimated network parameters to be used for
-  // initial parameter selection in future connections.
-  optional CachedNetworkParameters cached_network_parameters = 3;
-};
-
-// SourceAddressTokens are simply lists of SourceAddressToken messages.
-message SourceAddressTokens {
-  // This field has id 4 to avoid ambiguity between the serialized form of
-  // SourceAddressToken vs SourceAddressTokens.
-  repeated SourceAddressToken tokens = 4;
-};
diff --git a/quic/core/proto/source_address_token_proto.h b/quic/core/proto/source_address_token_proto.h
deleted file mode 100644
index a63bd89..0000000
--- a/quic/core/proto/source_address_token_proto.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
-#define QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "quic/core/proto/source_address_token.pb.h"
-
-#pragma clang diagnostic pop
-
-#endif  // QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
diff --git a/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
deleted file mode 100644
index b3d15f3..0000000
--- a/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-namespace quic {
-namespace test {
-
-struct DecoderAndHandler {
-  std::unique_ptr<QpackProgressiveDecoder> decoder;
-  std::unique_ptr<QpackProgressiveDecoder::HeadersHandlerInterface> handler;
-};
-
-using DecoderAndHandlerMap = std::map<QuicStreamId, DecoderAndHandler>;
-
-// Class that sets externally owned |error_detected| to true
-// on encoder stream error.
-class ErrorDelegate : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
-  ErrorDelegate(bool* error_detected) : error_detected_(error_detected) {}
-  ~ErrorDelegate() override = default;
-
-  void OnEncoderStreamError(QuicErrorCode /*error_code*/,
-                            absl::string_view /*error_message*/) override {
-    *error_detected_ = true;
-  }
-
- private:
-  bool* const error_detected_;
-};
-
-// Class that destroys DecoderAndHandler when decoding completes, and sets
-// externally owned |error_detected| to true on encoder stream error.
-class HeadersHandler : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
-  HeadersHandler(QuicStreamId stream_id,
-                 DecoderAndHandlerMap* processing_decoders,
-                 bool* error_detected)
-      : stream_id_(stream_id),
-        processing_decoders_(processing_decoders),
-        error_detected_(error_detected) {}
-  ~HeadersHandler() override = default;
-
-  void OnHeaderDecoded(absl::string_view /*name*/,
-                       absl::string_view /*value*/) override {}
-
-  // Remove DecoderAndHandler from |*processing_decoders|.
-  void OnDecodingCompleted() override {
-    // Will delete |this|.
-    size_t result = processing_decoders_->erase(stream_id_);
-    QUICHE_CHECK_EQ(1u, result);
-  }
-
-  void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
-                               absl::string_view /*error_message*/) override {
-    *error_detected_ = true;
-  }
-
- private:
-  const QuicStreamId stream_id_;
-  DecoderAndHandlerMap* const processing_decoders_;
-  bool* const error_detected_;
-};
-
-// This fuzzer exercises QpackDecoder.  It should be able to cover all possible
-// code paths.  There is no point in encoding QpackDecoder's output to turn this
-// into a roundtrip test, because the same header list can be encoded in many
-// different ways, so the output could not be expected to match the original
-// input.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  FuzzedDataProvider provider(data, size);
-
-  // Maximum 256 byte dynamic table.  Such a small size helps test draining
-  // entries and eviction.
-  const uint64_t maximum_dynamic_table_capacity =
-      provider.ConsumeIntegral<uint8_t>();
-  // Maximum 256 blocked streams.
-  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();
-
-  // |error_detected| will be set to true if an error is encountered either in a
-  // header block or on the encoder stream.
-  bool error_detected = false;
-
-  ErrorDelegate encoder_stream_error_delegate(&error_detected);
-  QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
-                       &encoder_stream_error_delegate);
-
-  NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
-  decoder.set_qpack_stream_sender_delegate(&decoder_stream_sender_delegate);
-
-  // Decoders still reading the header block, with corresponding handlers.
-  DecoderAndHandlerMap reading_decoders;
-
-  // Decoders still processing the completely read header block,
-  // with corresponding handlers.
-  DecoderAndHandlerMap processing_decoders;
-
-  // Maximum 256 data fragments to limit runtime and memory usage.
-  auto fragment_count = provider.ConsumeIntegral<uint8_t>();
-  while (fragment_count > 0 && !error_detected &&
-         provider.remaining_bytes() > 0) {
-    --fragment_count;
-    switch (provider.ConsumeIntegralInRange<uint8_t>(0, 3)) {
-      // Feed encoder stream data to QpackDecoder.
-      case 0: {
-        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
-        std::string data = provider.ConsumeRandomLengthString(fragment_size);
-        decoder.encoder_stream_receiver()->Decode(data);
-
-        continue;
-      }
-
-      // Create new progressive decoder.
-      case 1: {
-        QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
-        if (reading_decoders.find(stream_id) != reading_decoders.end() ||
-            processing_decoders.find(stream_id) != processing_decoders.end()) {
-          continue;
-        }
-
-        DecoderAndHandler decoder_and_handler;
-        decoder_and_handler.handler = std::make_unique<HeadersHandler>(
-            stream_id, &processing_decoders, &error_detected);
-        decoder_and_handler.decoder = decoder.CreateProgressiveDecoder(
-            stream_id, decoder_and_handler.handler.get());
-        reading_decoders.insert({stream_id, std::move(decoder_and_handler)});
-
-        continue;
-      }
-
-      // Feed header block data to existing decoder.
-      case 2: {
-        if (reading_decoders.empty()) {
-          continue;
-        }
-
-        auto it = reading_decoders.begin();
-        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
-            0, reading_decoders.size() - 1);
-        std::advance(it, distance);
-
-        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
-        std::string data = provider.ConsumeRandomLengthString(fragment_size);
-        it->second.decoder->Decode(data);
-
-        continue;
-      }
-
-      // End header block.
-      case 3: {
-        if (reading_decoders.empty()) {
-          continue;
-        }
-
-        auto it = reading_decoders.begin();
-        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
-            0, reading_decoders.size() - 1);
-        std::advance(it, distance);
-
-        QpackProgressiveDecoder* decoder = it->second.decoder.get();
-
-        // Move DecoderAndHandler to |reading_decoders| first, because
-        // EndHeaderBlock() might synchronously call OnDecodingCompleted().
-        QuicStreamId stream_id = it->first;
-        processing_decoders.insert({stream_id, std::move(it->second)});
-        reading_decoders.erase(it);
-
-        decoder->EndHeaderBlock();
-
-        continue;
-      }
-    }
-  }
-
-  return 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc
deleted file mode 100644
index 8c2d650..0000000
--- a/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// A QpackDecoderStreamReceiver::Delegate implementation that ignores all
-// decoded instructions but keeps track of whether an error has been detected.
-class NoOpDelegate : public QpackDecoderStreamReceiver::Delegate {
- public:
-  NoOpDelegate() : error_detected_(false) {}
-  ~NoOpDelegate() override = default;
-
-  void OnInsertCountIncrement(uint64_t /*increment*/) override {}
-  void OnHeaderAcknowledgement(QuicStreamId /*stream_id*/) override {}
-  void OnStreamCancellation(QuicStreamId /*stream_id*/) override {}
-  void OnErrorDetected(QuicErrorCode /*error_code*/,
-                       absl::string_view /*error_message*/) override {
-    error_detected_ = true;
-  }
-
-  bool error_detected() const { return error_detected_; }
-
- private:
-  bool error_detected_;
-};
-
-}  // namespace
-
-// This fuzzer exercises QpackDecoderStreamReceiver.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  NoOpDelegate delegate;
-  QpackDecoderStreamReceiver receiver(&delegate);
-
-  FuzzedDataProvider provider(data, size);
-
-  while (!delegate.error_detected() && provider.remaining_bytes() != 0) {
-    // Process up to 64 kB fragments at a time.  Too small upper bound might not
-    // provide enough coverage, too large might make fuzzing too inefficient.
-    size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>(
-        0, std::numeric_limits<uint16_t>::max());
-    receiver.Decode(provider.ConsumeRandomLengthString(fragment_size));
-  }
-
-  return 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc
deleted file mode 100644
index 8ba29d3..0000000
--- a/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <cstddef>
-#include <cstdint>
-
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-#include "quic/core/quic_types.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// This fuzzer exercises QpackDecoderStreamSender.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  NoopQpackStreamSenderDelegate delegate;
-  QpackDecoderStreamSender sender;
-  sender.set_qpack_stream_sender_delegate(&delegate);
-
-  FuzzedDataProvider provider(data, size);
-
-  while (provider.remaining_bytes() != 0) {
-    switch (provider.ConsumeIntegral<uint8_t>() % 4) {
-      case 0: {
-        uint64_t increment = provider.ConsumeIntegral<uint64_t>();
-        sender.SendInsertCountIncrement(increment);
-        break;
-      }
-      case 1: {
-        QuicStreamId stream_id = provider.ConsumeIntegral<QuicStreamId>();
-        sender.SendHeaderAcknowledgement(stream_id);
-        break;
-      }
-      case 2: {
-        QuicStreamId stream_id = provider.ConsumeIntegral<QuicStreamId>();
-        sender.SendStreamCancellation(stream_id);
-        break;
-      }
-      case 3: {
-        sender.Flush();
-        break;
-      }
-    }
-  }
-
-  sender.Flush();
-  return 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc
deleted file mode 100644
index ac7fac9..0000000
--- a/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// A QpackEncoderStreamReceiver::Delegate implementation that ignores all
-// decoded instructions but keeps track of whether an error has been detected.
-class NoOpDelegate : public QpackEncoderStreamReceiver::Delegate {
- public:
-  NoOpDelegate() : error_detected_(false) {}
-  ~NoOpDelegate() override = default;
-
-  void OnInsertWithNameReference(bool /*is_static*/,
-                                 uint64_t /*name_index*/,
-                                 absl::string_view /*value*/) override {}
-  void OnInsertWithoutNameReference(absl::string_view /*name*/,
-                                    absl::string_view /*value*/) override {}
-  void OnDuplicate(uint64_t /*index*/) override {}
-  void OnSetDynamicTableCapacity(uint64_t /*capacity*/) override {}
-  void OnErrorDetected(QuicErrorCode /*error_code*/,
-                       absl::string_view /*error_message*/) override {
-    error_detected_ = true;
-  }
-
-  bool error_detected() const { return error_detected_; }
-
- private:
-  bool error_detected_;
-};
-
-}  // namespace
-
-// This fuzzer exercises QpackEncoderStreamReceiver.
-// Note that since string literals may be encoded with or without Huffman
-// encoding, one could not expect identical encoded data if the decoded
-// instructions were fed into QpackEncoderStreamSender.  Therefore there is no
-// point in extending this fuzzer into a round-trip test.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  NoOpDelegate delegate;
-  QpackEncoderStreamReceiver receiver(&delegate);
-
-  FuzzedDataProvider provider(data, size);
-
-  while (!delegate.error_detected() && provider.remaining_bytes() != 0) {
-    // Process up to 64 kB fragments at a time.  Too small upper bound might not
-    // provide enough coverage, too large might make fuzzing too inefficient.
-    size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>(
-        0, std::numeric_limits<uint16_t>::max());
-    receiver.Decode(provider.ConsumeRandomLengthString(fragment_size));
-  }
-
-  return 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
deleted file mode 100644
index ab0e083..0000000
--- a/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <string>
-
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// This fuzzer exercises QpackEncoderStreamSender.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  NoopQpackStreamSenderDelegate delegate;
-  QpackEncoderStreamSender sender;
-  sender.set_qpack_stream_sender_delegate(&delegate);
-
-  FuzzedDataProvider provider(data, size);
-  // Limit string literal length to 2 kB for efficiency.
-  const uint16_t kMaxStringLength = 2048;
-
-  while (provider.remaining_bytes() != 0) {
-    switch (provider.ConsumeIntegral<uint8_t>() % 5) {
-      case 0: {
-        bool is_static = provider.ConsumeBool();
-        uint64_t name_index = provider.ConsumeIntegral<uint64_t>();
-        uint16_t value_length =
-            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
-        std::string value = provider.ConsumeRandomLengthString(value_length);
-
-        sender.SendInsertWithNameReference(is_static, name_index, value);
-        break;
-      }
-      case 1: {
-        uint16_t name_length =
-            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
-        std::string name = provider.ConsumeRandomLengthString(name_length);
-        uint16_t value_length =
-            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
-        std::string value = provider.ConsumeRandomLengthString(value_length);
-        sender.SendInsertWithoutNameReference(name, value);
-        break;
-      }
-      case 2: {
-        uint64_t index = provider.ConsumeIntegral<uint64_t>();
-        sender.SendDuplicate(index);
-        break;
-      }
-      case 3: {
-        uint64_t capacity = provider.ConsumeIntegral<uint64_t>();
-        sender.SendSetDynamicTableCapacity(capacity);
-        break;
-      }
-      case 4: {
-        sender.Flush();
-        break;
-      }
-    }
-  }
-
-  sender.Flush();
-  return 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
deleted file mode 100644
index 676121e..0000000
--- a/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/qpack/value_splitting_header_list.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// Find the first occurrence of invalid characters NUL, LF, CR in |*value| and
-// remove that and the remaining of the string.
-void TruncateValueOnInvalidChars(std::string* value) {
-  for (auto it = value->begin(); it != value->end(); ++it) {
-    if (*it == '\0' || *it == '\n' || *it == '\r') {
-      value->erase(it, value->end());
-      return;
-    }
-  }
-}
-
-}  // anonymous namespace
-
-// Class to hold QpackEncoder and its DecoderStreamErrorDelegate.
-class EncodingEndpoint {
- public:
-  EncodingEndpoint(uint64_t maximum_dynamic_table_capacity,
-                   uint64_t maximum_blocked_streams)
-      : encoder_(&decoder_stream_error_delegate) {
-    encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
-    encoder_.SetMaximumBlockedStreams(maximum_blocked_streams);
-  }
-
-  ~EncodingEndpoint() {
-    // Every reference should be acknowledged.
-    QUICHE_CHECK_EQ(std::numeric_limits<uint64_t>::max(),
-                    QpackEncoderPeer::smallest_blocking_index(&encoder_));
-  }
-
-  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
-    encoder_.set_qpack_stream_sender_delegate(delegate);
-  }
-
-  void SetDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity) {
-    encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
-  }
-
-  QpackStreamReceiver* decoder_stream_receiver() {
-    return encoder_.decoder_stream_receiver();
-  }
-
-  std::string EncodeHeaderList(QuicStreamId stream_id,
-                               const spdy::Http2HeaderBlock& header_list) {
-    return encoder_.EncodeHeaderList(stream_id, header_list, nullptr);
-  }
-
- private:
-  // DecoderStreamErrorDelegate implementation that crashes on error.
-  class CrashingDecoderStreamErrorDelegate
-      : public QpackEncoder::DecoderStreamErrorDelegate {
-   public:
-    ~CrashingDecoderStreamErrorDelegate() override = default;
-
-    void OnDecoderStreamError(QuicErrorCode error_code,
-                              absl::string_view error_message) override {
-      QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
-                          << error_message;
-    }
-  };
-
-  CrashingDecoderStreamErrorDelegate decoder_stream_error_delegate;
-  QpackEncoder encoder_;
-};
-
-// Class that receives all header blocks from the encoding endpoint and passes
-// them to the decoding endpoint, with delay determined by fuzzer data,
-// preserving order within each stream but not among streams.
-class DelayedHeaderBlockTransmitter {
- public:
-  class Visitor {
-   public:
-    virtual ~Visitor() = default;
-
-    // If decoding of the previous header block is still in progress, then
-    // DelayedHeaderBlockTransmitter will not start transmitting the next header
-    // block.
-    virtual bool IsDecodingInProgressOnStream(QuicStreamId stream_id) = 0;
-
-    // Called when a header block starts.
-    virtual void OnHeaderBlockStart(QuicStreamId stream_id) = 0;
-    // Called when part or all of a header block is transmitted.
-    virtual void OnHeaderBlockFragment(QuicStreamId stream_id,
-                                       absl::string_view data) = 0;
-    // Called when transmission of a header block is complete.
-    virtual void OnHeaderBlockEnd(QuicStreamId stream_id) = 0;
-  };
-
-  DelayedHeaderBlockTransmitter(Visitor* visitor, FuzzedDataProvider* provider)
-      : visitor_(visitor), provider_(provider) {}
-
-  ~DelayedHeaderBlockTransmitter() { QUICHE_CHECK(header_blocks_.empty()); }
-
-  // Enqueues |encoded_header_block| for delayed transmission.
-  void SendEncodedHeaderBlock(QuicStreamId stream_id,
-                              std::string encoded_header_block) {
-    auto it = header_blocks_.lower_bound(stream_id);
-    if (it == header_blocks_.end() || it->first != stream_id) {
-      it = header_blocks_.insert(it, {stream_id, {}});
-    }
-    QUICHE_CHECK_EQ(stream_id, it->first);
-    it->second.push(HeaderBlock(std::move(encoded_header_block)));
-  }
-
-  // Release some (possibly none) header block data.
-  void MaybeTransmitSomeData() {
-    if (header_blocks_.empty()) {
-      return;
-    }
-
-    auto index =
-        provider_->ConsumeIntegralInRange<size_t>(0, header_blocks_.size() - 1);
-    auto it = header_blocks_.begin();
-    std::advance(it, index);
-    const QuicStreamId stream_id = it->first;
-
-    // Do not start new header block if processing of previous header block is
-    // blocked.
-    if (visitor_->IsDecodingInProgressOnStream(stream_id)) {
-      return;
-    }
-
-    auto& header_block_queue = it->second;
-    HeaderBlock& header_block = header_block_queue.front();
-
-    if (header_block.ConsumedLength() == 0) {
-      visitor_->OnHeaderBlockStart(stream_id);
-    }
-
-    QUICHE_DCHECK_NE(0u, header_block.RemainingLength());
-
-    size_t length = provider_->ConsumeIntegralInRange<size_t>(
-        1, header_block.RemainingLength());
-    visitor_->OnHeaderBlockFragment(stream_id, header_block.Consume(length));
-
-    QUICHE_DCHECK_NE(0u, header_block.ConsumedLength());
-
-    if (header_block.RemainingLength() == 0) {
-      visitor_->OnHeaderBlockEnd(stream_id);
-
-      header_block_queue.pop();
-      if (header_block_queue.empty()) {
-        header_blocks_.erase(it);
-      }
-    }
-  }
-
-  // Release all header block data.  Must be called before destruction.  All
-  // encoder stream data must have been released before calling Flush() so that
-  // all header blocks can be decoded synchronously.
-  void Flush() {
-    while (!header_blocks_.empty()) {
-      auto it = header_blocks_.begin();
-      const QuicStreamId stream_id = it->first;
-
-      auto& header_block_queue = it->second;
-      HeaderBlock& header_block = header_block_queue.front();
-
-      if (header_block.ConsumedLength() == 0) {
-        QUICHE_CHECK(!visitor_->IsDecodingInProgressOnStream(stream_id));
-        visitor_->OnHeaderBlockStart(stream_id);
-      }
-
-      QUICHE_DCHECK_NE(0u, header_block.RemainingLength());
-
-      visitor_->OnHeaderBlockFragment(stream_id,
-                                      header_block.ConsumeRemaining());
-
-      QUICHE_DCHECK_NE(0u, header_block.ConsumedLength());
-      QUICHE_DCHECK_EQ(0u, header_block.RemainingLength());
-
-      visitor_->OnHeaderBlockEnd(stream_id);
-      QUICHE_CHECK(!visitor_->IsDecodingInProgressOnStream(stream_id));
-
-      header_block_queue.pop();
-      if (header_block_queue.empty()) {
-        header_blocks_.erase(it);
-      }
-    }
-  }
-
- private:
-  // Helper class that allows the header block to be consumed in parts.
-  class HeaderBlock {
-   public:
-    explicit HeaderBlock(std::string data)
-        : data_(std::move(data)), offset_(0) {
-      // Valid QPACK header block cannot be empty.
-      QUICHE_DCHECK(!data_.empty());
-    }
-
-    size_t ConsumedLength() const { return offset_; }
-
-    size_t RemainingLength() const { return data_.length() - offset_; }
-
-    absl::string_view Consume(size_t length) {
-      QUICHE_DCHECK_NE(0u, length);
-      QUICHE_DCHECK_LE(length, RemainingLength());
-
-      absl::string_view consumed = absl::string_view(&data_[offset_], length);
-      offset_ += length;
-      return consumed;
-    }
-
-    absl::string_view ConsumeRemaining() { return Consume(RemainingLength()); }
-
-   private:
-    // Complete header block.
-    const std::string data_;
-
-    // Offset of the part not consumed yet.  Same as number of consumed bytes.
-    size_t offset_;
-  };
-
-  Visitor* const visitor_;
-  FuzzedDataProvider* const provider_;
-
-  std::map<QuicStreamId, std::queue<HeaderBlock>> header_blocks_;
-};
-
-// Class to decode and verify a header block, and in case of blocked decoding,
-// keep necessary decoding context while waiting for decoding to complete.
-class VerifyingDecoder : public QpackDecodedHeadersAccumulator::Visitor {
- public:
-  class Visitor {
-   public:
-    virtual ~Visitor() = default;
-
-    // Called when header block is decoded, either synchronously or
-    // asynchronously.  Might destroy VerifyingDecoder.
-    virtual void OnHeaderBlockDecoded(QuicStreamId stream_id) = 0;
-  };
-
-  VerifyingDecoder(QuicStreamId stream_id,
-                   Visitor* visitor,
-                   QpackDecoder* qpack_decoder,
-                   QuicHeaderList expected_header_list)
-      : stream_id_(stream_id),
-        visitor_(visitor),
-        accumulator_(
-            stream_id,
-            qpack_decoder,
-            this,
-            /* max_header_list_size = */ std::numeric_limits<size_t>::max()),
-        expected_header_list_(std::move(expected_header_list)) {}
-
-  VerifyingDecoder(const VerifyingDecoder&) = delete;
-  VerifyingDecoder& operator=(const VerifyingDecoder&) = delete;
-  // VerifyingDecoder must not be moved because it passes |this| to
-  // |accumulator_| upon construction.
-  VerifyingDecoder(VerifyingDecoder&&) = delete;
-  VerifyingDecoder& operator=(VerifyingDecoder&&) = delete;
-
-  virtual ~VerifyingDecoder() = default;
-
-  // QpackDecodedHeadersAccumulator::Visitor implementation.
-  void OnHeadersDecoded(QuicHeaderList headers,
-                        bool header_list_size_limit_exceeded) override {
-    // Verify headers.
-    QUICHE_CHECK(!header_list_size_limit_exceeded);
-    QUICHE_CHECK(expected_header_list_ == headers);
-
-    // Might destroy |this|.
-    visitor_->OnHeaderBlockDecoded(stream_id_);
-  }
-
-  void OnHeaderDecodingError(QuicErrorCode error_code,
-                             absl::string_view error_message) override {
-    QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
-                        << error_message;
-  }
-
-  void Decode(absl::string_view data) { accumulator_.Decode(data); }
-
-  void EndHeaderBlock() { accumulator_.EndHeaderBlock(); }
-
- private:
-  QuicStreamId stream_id_;
-  Visitor* const visitor_;
-  QpackDecodedHeadersAccumulator accumulator_;
-  QuicHeaderList expected_header_list_;
-};
-
-// Class that holds QpackDecoder and its EncoderStreamErrorDelegate, and creates
-// and keeps VerifyingDecoders for each received header block until decoding is
-// complete.
-class DecodingEndpoint : public DelayedHeaderBlockTransmitter::Visitor,
-                         public VerifyingDecoder::Visitor {
- public:
-  DecodingEndpoint(uint64_t maximum_dynamic_table_capacity,
-                   uint64_t maximum_blocked_streams)
-      : decoder_(maximum_dynamic_table_capacity,
-                 maximum_blocked_streams,
-                 &encoder_stream_error_delegate_) {}
-
-  ~DecodingEndpoint() override {
-    // All decoding must have been completed.
-    QUICHE_CHECK(expected_header_lists_.empty());
-    QUICHE_CHECK(verifying_decoders_.empty());
-  }
-
-  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
-    decoder_.set_qpack_stream_sender_delegate(delegate);
-  }
-
-  QpackStreamReceiver* encoder_stream_receiver() {
-    return decoder_.encoder_stream_receiver();
-  }
-
-  void AddExpectedHeaderList(QuicStreamId stream_id,
-                             QuicHeaderList expected_header_list) {
-    auto it = expected_header_lists_.lower_bound(stream_id);
-    if (it == expected_header_lists_.end() || it->first != stream_id) {
-      it = expected_header_lists_.insert(it, {stream_id, {}});
-    }
-    QUICHE_CHECK_EQ(stream_id, it->first);
-    it->second.push(std::move(expected_header_list));
-  }
-
-  // VerifyingDecoder::Visitor implementation.
-  void OnHeaderBlockDecoded(QuicStreamId stream_id) override {
-    auto result = verifying_decoders_.erase(stream_id);
-    QUICHE_CHECK_EQ(1u, result);
-  }
-
-  // DelayedHeaderBlockTransmitter::Visitor implementation.
-  bool IsDecodingInProgressOnStream(QuicStreamId stream_id) override {
-    return verifying_decoders_.find(stream_id) != verifying_decoders_.end();
-  }
-
-  void OnHeaderBlockStart(QuicStreamId stream_id) override {
-    QUICHE_CHECK(!IsDecodingInProgressOnStream(stream_id));
-    auto it = expected_header_lists_.find(stream_id);
-    QUICHE_CHECK(it != expected_header_lists_.end());
-
-    auto& header_list_queue = it->second;
-    QuicHeaderList expected_header_list = std::move(header_list_queue.front());
-
-    header_list_queue.pop();
-    if (header_list_queue.empty()) {
-      expected_header_lists_.erase(it);
-    }
-
-    auto verifying_decoder = std::make_unique<VerifyingDecoder>(
-        stream_id, this, &decoder_, std::move(expected_header_list));
-    auto result =
-        verifying_decoders_.insert({stream_id, std::move(verifying_decoder)});
-    QUICHE_CHECK(result.second);
-  }
-
-  void OnHeaderBlockFragment(QuicStreamId stream_id,
-                             absl::string_view data) override {
-    auto it = verifying_decoders_.find(stream_id);
-    QUICHE_CHECK(it != verifying_decoders_.end());
-    it->second->Decode(data);
-  }
-
-  void OnHeaderBlockEnd(QuicStreamId stream_id) override {
-    auto it = verifying_decoders_.find(stream_id);
-    QUICHE_CHECK(it != verifying_decoders_.end());
-    it->second->EndHeaderBlock();
-  }
-
- private:
-  // EncoderStreamErrorDelegate implementation that crashes on error.
-  class CrashingEncoderStreamErrorDelegate
-      : public QpackDecoder::EncoderStreamErrorDelegate {
-   public:
-    ~CrashingEncoderStreamErrorDelegate() override = default;
-
-    void OnEncoderStreamError(QuicErrorCode error_code,
-                              absl::string_view error_message) override {
-      QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
-                          << error_message;
-    }
-  };
-
-  CrashingEncoderStreamErrorDelegate encoder_stream_error_delegate_;
-  QpackDecoder decoder_;
-
-  // Expected header lists in order for each stream.
-  std::map<QuicStreamId, std::queue<QuicHeaderList>> expected_header_lists_;
-
-  // A VerifyingDecoder object keeps context necessary for asynchronously
-  // decoding blocked header blocks.  It is destroyed as soon as it signals that
-  // decoding is completed, which might happen synchronously within an
-  // EndHeaderBlock() call.
-  std::map<QuicStreamId, std::unique_ptr<VerifyingDecoder>> verifying_decoders_;
-};
-
-// Class that receives encoder stream data from the encoder and passes it to the
-// decoder, or receives decoder stream data from the decoder and passes it to
-// the encoder, with delay determined by fuzzer data.
-class DelayedStreamDataTransmitter : public QpackStreamSenderDelegate {
- public:
-  DelayedStreamDataTransmitter(QpackStreamReceiver* receiver,
-                               FuzzedDataProvider* provider)
-      : receiver_(receiver), provider_(provider) {}
-
-  ~DelayedStreamDataTransmitter() { QUICHE_CHECK(stream_data.empty()); }
-
-  // QpackStreamSenderDelegate implementation.
-  void WriteStreamData(absl::string_view data) override {
-    stream_data.push_back(std::string(data.data(), data.size()));
-  }
-  uint64_t NumBytesBuffered() const override { return 0; }
-
-  // Release some (possibly none) delayed stream data.
-  void MaybeTransmitSomeData() {
-    auto count = provider_->ConsumeIntegral<uint8_t>();
-    while (!stream_data.empty() && count > 0) {
-      receiver_->Decode(stream_data.front());
-      stream_data.pop_front();
-      --count;
-    }
-  }
-
-  // Release all delayed stream data.  Must be called before destruction.
-  void Flush() {
-    while (!stream_data.empty()) {
-      receiver_->Decode(stream_data.front());
-      stream_data.pop_front();
-    }
-  }
-
- private:
-  QpackStreamReceiver* const receiver_;
-  FuzzedDataProvider* const provider_;
-  quiche::QuicheCircularDeque<std::string> stream_data;
-};
-
-// Generate header list using fuzzer data.
-spdy::Http2HeaderBlock GenerateHeaderList(FuzzedDataProvider* provider) {
-  spdy::Http2HeaderBlock header_list;
-  uint8_t header_count = provider->ConsumeIntegral<uint8_t>();
-  for (uint8_t header_index = 0; header_index < header_count; ++header_index) {
-    if (provider->remaining_bytes() == 0) {
-      // Do not add more headers if there is no more fuzzer data.
-      break;
-    }
-
-    std::string name;
-    std::string value;
-    switch (provider->ConsumeIntegral<uint8_t>()) {
-      case 0:
-        // Static table entry with no header value.
-        name = ":authority";
-        break;
-      case 1:
-        // Static table entry with no header value, using non-empty header
-        // value.
-        name = ":authority";
-        value = "www.example.org";
-        break;
-      case 2:
-        // Static table entry with header value, using that header value.
-        name = ":accept-encoding";
-        value = "gzip, deflate";
-        break;
-      case 3:
-        // Static table entry with header value, using empty header value.
-        name = ":accept-encoding";
-        break;
-      case 4:
-        // Static table entry with header value, using different, non-empty
-        // header value.
-        name = ":accept-encoding";
-        value = "brotli";
-        break;
-      case 5:
-        // Header name that has multiple entries in the static table,
-        // using header value from one of them.
-        name = ":method";
-        value = "GET";
-        break;
-      case 6:
-        // Header name that has multiple entries in the static table,
-        // using empty header value.
-        name = ":method";
-        break;
-      case 7:
-        // Header name that has multiple entries in the static table,
-        // using different, non-empty header value.
-        name = ":method";
-        value = "CONNECT";
-        break;
-      case 8:
-        // Header name not in the static table, empty header value.
-        name = "foo";
-        value = "";
-        break;
-      case 9:
-        // Header name not in the static table, non-empty fixed header value.
-        name = "foo";
-        value = "bar";
-        break;
-      case 10:
-        // Header name not in the static table, fuzzed header value.
-        name = "foo";
-        value = provider->ConsumeRandomLengthString(128);
-        TruncateValueOnInvalidChars(&value);
-        break;
-      case 11:
-        // Another header name not in the static table, empty header value.
-        name = "bar";
-        value = "";
-        break;
-      case 12:
-        // Another header name not in the static table, non-empty fixed header
-        // value.
-        name = "bar";
-        value = "baz";
-        break;
-      case 13:
-        // Another header name not in the static table, fuzzed header value.
-        name = "bar";
-        value = provider->ConsumeRandomLengthString(128);
-        TruncateValueOnInvalidChars(&value);
-        break;
-      default:
-        // Fuzzed header name and header value.
-        name = provider->ConsumeRandomLengthString(128);
-        value = provider->ConsumeRandomLengthString(128);
-        TruncateValueOnInvalidChars(&value);
-    }
-
-    header_list.AppendValueOrAddHeader(name, value);
-  }
-
-  return header_list;
-}
-
-// Splits |*header_list| header values along '\0' or ';' separators.
-QuicHeaderList SplitHeaderList(const spdy::Http2HeaderBlock& header_list) {
-  QuicHeaderList split_header_list;
-  split_header_list.OnHeaderBlockStart();
-
-  size_t total_size = 0;
-  ValueSplittingHeaderList splitting_header_list(&header_list);
-  for (const auto& header : splitting_header_list) {
-    split_header_list.OnHeader(header.first, header.second);
-    total_size += header.first.size() + header.second.size();
-  }
-
-  split_header_list.OnHeaderBlockEnd(total_size, total_size);
-
-  return split_header_list;
-}
-
-// This fuzzer exercises QpackEncoder and QpackDecoder.  It should be able to
-// cover all possible code paths of QpackEncoder.  However, since the resulting
-// header block is always valid and is encoded in a particular way, this fuzzer
-// is not expected to cover all code paths of QpackDecoder.  On the other hand,
-// encoding then decoding is expected to result in the original header list, and
-// this fuzzer checks for that.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  FuzzedDataProvider provider(data, size);
-
-  // Maximum 256 byte dynamic table.  Such a small size helps test draining
-  // entries and eviction.
-  const uint64_t maximum_dynamic_table_capacity =
-      provider.ConsumeIntegral<uint8_t>();
-  // Maximum 256 blocked streams.
-  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();
-
-  // Set up encoder.
-  EncodingEndpoint encoder(maximum_dynamic_table_capacity,
-                           maximum_blocked_streams);
-
-  // Set up decoder.
-  DecodingEndpoint decoder(maximum_dynamic_table_capacity,
-                           maximum_blocked_streams);
-
-  // Transmit encoder stream data from encoder to decoder.
-  DelayedStreamDataTransmitter encoder_stream_transmitter(
-      decoder.encoder_stream_receiver(), &provider);
-  encoder.set_qpack_stream_sender_delegate(&encoder_stream_transmitter);
-
-  // Use a dynamic table as large as the peer allows.  This sends data on the
-  // encoder stream, so it can only be done after delegate is set.
-  encoder.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
-
-  // Transmit decoder stream data from encoder to decoder.
-  DelayedStreamDataTransmitter decoder_stream_transmitter(
-      encoder.decoder_stream_receiver(), &provider);
-  decoder.set_qpack_stream_sender_delegate(&decoder_stream_transmitter);
-
-  // Transmit header blocks from encoder to decoder.
-  DelayedHeaderBlockTransmitter header_block_transmitter(&decoder, &provider);
-
-  // Maximum 256 header lists to limit runtime and memory usage.
-  auto header_list_count = provider.ConsumeIntegral<uint8_t>();
-  while (header_list_count > 0 && provider.remaining_bytes() > 0) {
-    const QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
-
-    // Generate header list.
-    spdy::Http2HeaderBlock header_list = GenerateHeaderList(&provider);
-
-    // Encode header list.
-    std::string encoded_header_block =
-        encoder.EncodeHeaderList(stream_id, header_list);
-
-    // TODO(bnc): Randomly cancel the stream.
-
-    // Encoder splits |header_list| header values along '\0' or ';' separators.
-    // Do the same here so that we get matching results.
-    QuicHeaderList expected_header_list = SplitHeaderList(header_list);
-    decoder.AddExpectedHeaderList(stream_id, std::move(expected_header_list));
-
-    header_block_transmitter.SendEncodedHeaderBlock(
-        stream_id, std::move(encoded_header_block));
-
-    // Transmit some encoder stream data, decoder stream data, or header blocks
-    // on the request stream, repeating a few times.
-    for (auto transmit_data_count = provider.ConsumeIntegralInRange(1, 5);
-         transmit_data_count > 0; --transmit_data_count) {
-      encoder_stream_transmitter.MaybeTransmitSomeData();
-      decoder_stream_transmitter.MaybeTransmitSomeData();
-      header_block_transmitter.MaybeTransmitSomeData();
-    }
-
-    --header_list_count;
-  }
-
-  // Release all delayed encoder stream data so that remaining header blocks can
-  // be decoded synchronously.
-  encoder_stream_transmitter.Flush();
-  // Release all delayed header blocks.
-  header_block_transmitter.Flush();
-  // Release all delayed decoder stream data.
-  decoder_stream_transmitter.Flush();
-
-  return 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_blocking_manager.cc b/quic/core/qpack/qpack_blocking_manager.cc
deleted file mode 100644
index 3b03710..0000000
--- a/quic/core/qpack/qpack_blocking_manager.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_blocking_manager.h"
-
-#include <limits>
-#include <utility>
-
-namespace quic {
-
-QpackBlockingManager::QpackBlockingManager() : known_received_count_(0) {}
-
-bool QpackBlockingManager::OnHeaderAcknowledgement(QuicStreamId stream_id) {
-  auto it = header_blocks_.find(stream_id);
-  if (it == header_blocks_.end()) {
-    return false;
-  }
-
-  QUICHE_DCHECK(!it->second.empty());
-
-  const IndexSet& indices = it->second.front();
-  QUICHE_DCHECK(!indices.empty());
-
-  const uint64_t required_index_count = RequiredInsertCount(indices);
-  if (known_received_count_ < required_index_count) {
-    known_received_count_ = required_index_count;
-  }
-
-  DecreaseReferenceCounts(indices);
-
-  it->second.pop_front();
-  if (it->second.empty()) {
-    header_blocks_.erase(it);
-  }
-
-  return true;
-}
-
-void QpackBlockingManager::OnStreamCancellation(QuicStreamId stream_id) {
-  auto it = header_blocks_.find(stream_id);
-  if (it == header_blocks_.end()) {
-    return;
-  }
-
-  for (const IndexSet& indices : it->second) {
-    DecreaseReferenceCounts(indices);
-  }
-
-  header_blocks_.erase(it);
-}
-
-bool QpackBlockingManager::OnInsertCountIncrement(uint64_t increment) {
-  if (increment >
-      std::numeric_limits<uint64_t>::max() - known_received_count_) {
-    return false;
-  }
-
-  known_received_count_ += increment;
-  return true;
-}
-
-void QpackBlockingManager::OnHeaderBlockSent(QuicStreamId stream_id,
-                                             IndexSet indices) {
-  QUICHE_DCHECK(!indices.empty());
-
-  IncreaseReferenceCounts(indices);
-  header_blocks_[stream_id].push_back(std::move(indices));
-}
-
-bool QpackBlockingManager::blocking_allowed_on_stream(
-    QuicStreamId stream_id,
-    uint64_t maximum_blocked_streams) const {
-  // This should be the most common case: the limit is larger than the number of
-  // streams that have unacknowledged header blocks (regardless of whether they
-  // are blocked or not) plus one for stream |stream_id|.
-  if (header_blocks_.size() + 1 <= maximum_blocked_streams) {
-    return true;
-  }
-
-  // This should be another common case: no blocked stream allowed.
-  if (maximum_blocked_streams == 0) {
-    return false;
-  }
-
-  uint64_t blocked_stream_count = 0;
-  for (const auto& header_blocks_for_stream : header_blocks_) {
-    for (const IndexSet& indices : header_blocks_for_stream.second) {
-      if (RequiredInsertCount(indices) > known_received_count_) {
-        if (header_blocks_for_stream.first == stream_id) {
-          // Sending blocking references is allowed if stream |stream_id| is
-          // already blocked.
-          return true;
-        }
-        ++blocked_stream_count;
-        // If stream |stream_id| is already blocked, then it is not counted yet,
-        // therefore the number of blocked streams is at least
-        // |blocked_stream_count + 1|, which cannot be more than
-        // |maximum_blocked_streams| by API contract.
-        // If stream |stream_id| is not blocked, then blocking will increase the
-        // blocked stream count to at least |blocked_stream_count + 1|.  If that
-        // is larger than |maximum_blocked_streams|, then blocking is not
-        // allowed on stream |stream_id|.
-        if (blocked_stream_count + 1 > maximum_blocked_streams) {
-          return false;
-        }
-        break;
-      }
-    }
-  }
-
-  // Stream |stream_id| is not blocked.
-  // If there are no blocked streams, then
-  // |blocked_stream_count + 1 <= maximum_blocked_streams| because
-  // |maximum_blocked_streams| is larger than zero.
-  // If there are are blocked streams, then
-  // |blocked_stream_count + 1 <= maximum_blocked_streams| otherwise the method
-  // would have returned false when |blocked_stream_count| was incremented.
-  // Therefore blocking on |stream_id| is allowed.
-  return true;
-}
-
-uint64_t QpackBlockingManager::smallest_blocking_index() const {
-  return entry_reference_counts_.empty()
-             ? std::numeric_limits<uint64_t>::max()
-             : entry_reference_counts_.begin()->first;
-}
-
-// static
-uint64_t QpackBlockingManager::RequiredInsertCount(const IndexSet& indices) {
-  return *indices.rbegin() + 1;
-}
-
-void QpackBlockingManager::IncreaseReferenceCounts(const IndexSet& indices) {
-  for (const uint64_t index : indices) {
-    auto it = entry_reference_counts_.lower_bound(index);
-    if (it != entry_reference_counts_.end() && it->first == index) {
-      ++it->second;
-    } else {
-      entry_reference_counts_.insert(it, {index, 1});
-    }
-  }
-}
-
-void QpackBlockingManager::DecreaseReferenceCounts(const IndexSet& indices) {
-  for (const uint64_t index : indices) {
-    auto it = entry_reference_counts_.find(index);
-    QUICHE_DCHECK(it != entry_reference_counts_.end());
-    QUICHE_DCHECK_NE(0u, it->second);
-
-    if (it->second == 1) {
-      entry_reference_counts_.erase(it);
-    } else {
-      --it->second;
-    }
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_blocking_manager.h b/quic/core/qpack/qpack_blocking_manager.h
deleted file mode 100644
index 4188350..0000000
--- a/quic/core/qpack/qpack_blocking_manager.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
-
-#include <cstdint>
-#include <map>
-#include <set>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-
-class QpackBlockingManagerPeer;
-
-}  // namespace test
-
-// Class to keep track of blocked streams and blocking dynamic table entries:
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-decoding
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-insertion
-class QUIC_EXPORT_PRIVATE QpackBlockingManager {
- public:
-  using IndexSet = std::multiset<uint64_t>;
-
-  QpackBlockingManager();
-
-  // Called when a Header Acknowledgement instruction is received on the decoder
-  // stream.  Returns false if there are no outstanding header blocks to be
-  // acknowledged on |stream_id|.
-  bool OnHeaderAcknowledgement(QuicStreamId stream_id);
-
-  // Called when a Stream Cancellation instruction is received on the decoder
-  // stream.
-  void OnStreamCancellation(QuicStreamId stream_id);
-
-  // Called when an Insert Count Increment instruction is received on the
-  // decoder stream.  Returns true if Known Received Count is successfully
-  // updated.  Returns false on overflow.
-  bool OnInsertCountIncrement(uint64_t increment);
-
-  // Called when sending a header block containing references to dynamic table
-  // entries with |indices|.  |indices| must not be empty.
-  void OnHeaderBlockSent(QuicStreamId stream_id, IndexSet indices);
-
-  // Returns true if sending blocking references on stream |stream_id| would not
-  // increase the total number of blocked streams above
-  // |maximum_blocked_streams|.  Note that if |stream_id| is already blocked
-  // then it is always allowed to send more blocking references on it.
-  // Behavior is undefined if |maximum_blocked_streams| is smaller than number
-  // of currently blocked streams.
-  bool blocking_allowed_on_stream(QuicStreamId stream_id,
-                                  uint64_t maximum_blocked_streams) const;
-
-  // Returns the index of the blocking entry with the smallest index,
-  // or std::numeric_limits<uint64_t>::max() if there are no blocking entries.
-  uint64_t smallest_blocking_index() const;
-
-  // Returns the Known Received Count as defined at
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
-  uint64_t known_received_count() const { return known_received_count_; }
-
-  // Required Insert Count for set of indices.
-  static uint64_t RequiredInsertCount(const IndexSet& indices);
-
- private:
-  friend test::QpackBlockingManagerPeer;
-
-  // A stream typically has only one header block, except for the rare cases of
-  // 1xx responses, trailers, or push promises.  Even if there are multiple
-  // header blocks sent on a single stream, they might not be blocked at the
-  // same time.  Use std::list instead of quiche::QuicheCircularDeque because it
-  // has lower memory footprint when holding few elements.
-  using HeaderBlocksForStream = std::list<IndexSet>;
-  using HeaderBlocks = absl::flat_hash_map<QuicStreamId, HeaderBlocksForStream>;
-
-  // Increase or decrease the reference count for each index in |indices|.
-  void IncreaseReferenceCounts(const IndexSet& indices);
-  void DecreaseReferenceCounts(const IndexSet& indices);
-
-  // Multiset of indices in each header block for each stream.
-  // Must not contain a stream id with an empty queue.
-  HeaderBlocks header_blocks_;
-
-  // Number of references in |header_blocks_| for each entry index.
-  std::map<uint64_t, uint64_t> entry_reference_counts_;
-
-  uint64_t known_received_count_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
diff --git a/quic/core/qpack/qpack_blocking_manager_test.cc b/quic/core/qpack/qpack_blocking_manager_test.cc
deleted file mode 100644
index 4bc8419..0000000
--- a/quic/core/qpack/qpack_blocking_manager_test.cc
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_blocking_manager.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QpackBlockingManagerPeer {
- public:
-  static bool stream_is_blocked(const QpackBlockingManager* manager,
-                                QuicStreamId stream_id) {
-    for (const auto& header_blocks_for_stream : manager->header_blocks_) {
-      if (header_blocks_for_stream.first != stream_id) {
-        continue;
-      }
-      for (const auto& indices : header_blocks_for_stream.second) {
-        if (QpackBlockingManager::RequiredInsertCount(indices) >
-            manager->known_received_count_) {
-          return true;
-        }
-      }
-    }
-
-    return false;
-  }
-};
-
-namespace {
-
-class QpackBlockingManagerTest : public QuicTest {
- protected:
-  QpackBlockingManagerTest() = default;
-  ~QpackBlockingManagerTest() override = default;
-
-  bool stream_is_blocked(QuicStreamId stream_id) const {
-    return QpackBlockingManagerPeer::stream_is_blocked(&manager_, stream_id);
-  }
-
-  QpackBlockingManager manager_;
-};
-
-TEST_F(QpackBlockingManagerTest, Empty) {
-  EXPECT_EQ(0u, manager_.known_received_count());
-  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
-            manager_.smallest_blocking_index());
-
-  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(1));
-}
-
-TEST_F(QpackBlockingManagerTest, NotBlockedByInsertCountIncrement) {
-  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
-
-  // Stream 0 is not blocked, because it only references entries that are
-  // already acknowledged by an Insert Count Increment instruction.
-  manager_.OnHeaderBlockSent(0, {1, 0});
-  EXPECT_FALSE(stream_is_blocked(0));
-}
-
-TEST_F(QpackBlockingManagerTest, UnblockedByInsertCountIncrement) {
-  manager_.OnHeaderBlockSent(0, {1, 0});
-  EXPECT_TRUE(stream_is_blocked(0));
-
-  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
-  EXPECT_FALSE(stream_is_blocked(0));
-}
-
-TEST_F(QpackBlockingManagerTest, NotBlockedByHeaderAcknowledgement) {
-  manager_.OnHeaderBlockSent(0, {2, 1, 1});
-  EXPECT_TRUE(stream_is_blocked(0));
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_FALSE(stream_is_blocked(0));
-
-  // Stream 1 is not blocked, because it only references entries that are
-  // already acknowledged by a Header Acknowledgement instruction.
-  manager_.OnHeaderBlockSent(1, {2, 2});
-  EXPECT_FALSE(stream_is_blocked(1));
-}
-
-TEST_F(QpackBlockingManagerTest, UnblockedByHeaderAcknowledgement) {
-  manager_.OnHeaderBlockSent(0, {2, 1, 1});
-  manager_.OnHeaderBlockSent(1, {2, 2});
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_TRUE(stream_is_blocked(1));
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_FALSE(stream_is_blocked(0));
-  EXPECT_FALSE(stream_is_blocked(1));
-}
-
-TEST_F(QpackBlockingManagerTest, KnownReceivedCount) {
-  EXPECT_EQ(0u, manager_.known_received_count());
-
-  // Sending a header block does not change Known Received Count.
-  manager_.OnHeaderBlockSent(0, {0});
-  EXPECT_EQ(0u, manager_.known_received_count());
-
-  manager_.OnHeaderBlockSent(1, {1});
-  EXPECT_EQ(0u, manager_.known_received_count());
-
-  // Header Acknowledgement might increase Known Received Count.
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_EQ(1u, manager_.known_received_count());
-
-  manager_.OnHeaderBlockSent(2, {5});
-  EXPECT_EQ(1u, manager_.known_received_count());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
-  EXPECT_EQ(2u, manager_.known_received_count());
-
-  // Insert Count Increment increases Known Received Count.
-  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
-  EXPECT_EQ(4u, manager_.known_received_count());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(2));
-  EXPECT_EQ(6u, manager_.known_received_count());
-
-  // Stream Cancellation does not change Known Received Count.
-  manager_.OnStreamCancellation(0);
-  EXPECT_EQ(6u, manager_.known_received_count());
-
-  // Header Acknowledgement of a block with smaller Required Insert Count does
-  // not increase Known Received Count.
-  manager_.OnHeaderBlockSent(0, {3});
-  EXPECT_EQ(6u, manager_.known_received_count());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_EQ(6u, manager_.known_received_count());
-
-  // Header Acknowledgement of a block with equal Required Insert Count does not
-  // increase Known Received Count.
-  manager_.OnHeaderBlockSent(1, {5});
-  EXPECT_EQ(6u, manager_.known_received_count());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
-  EXPECT_EQ(6u, manager_.known_received_count());
-}
-
-TEST_F(QpackBlockingManagerTest, SmallestBlockingIndex) {
-  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
-            manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(0, {0});
-  EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(1, {2});
-  EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_EQ(2u, manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(1, {1});
-  EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
-  EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
-  // Insert Count Increment does not change smallest blocking index.
-  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
-  EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
-  manager_.OnStreamCancellation(1);
-  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
-            manager_.smallest_blocking_index());
-}
-
-TEST_F(QpackBlockingManagerTest, HeaderAcknowledgementsOnSingleStream) {
-  EXPECT_EQ(0u, manager_.known_received_count());
-  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
-            manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(0, {2, 1, 1});
-  EXPECT_EQ(0u, manager_.known_received_count());
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_EQ(1u, manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(0, {1, 0});
-  EXPECT_EQ(0u, manager_.known_received_count());
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_EQ(3u, manager_.known_received_count());
-  EXPECT_FALSE(stream_is_blocked(0));
-  EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(0, {3});
-  EXPECT_EQ(3u, manager_.known_received_count());
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_EQ(0u, manager_.smallest_blocking_index());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_EQ(3u, manager_.known_received_count());
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_EQ(3u, manager_.smallest_blocking_index());
-
-  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
-  EXPECT_EQ(4u, manager_.known_received_count());
-  EXPECT_FALSE(stream_is_blocked(0));
-  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
-            manager_.smallest_blocking_index());
-
-  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
-}
-
-TEST_F(QpackBlockingManagerTest, CancelStream) {
-  manager_.OnHeaderBlockSent(0, {3});
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_EQ(3u, manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(0, {2});
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_EQ(2u, manager_.smallest_blocking_index());
-
-  manager_.OnHeaderBlockSent(1, {4});
-  EXPECT_TRUE(stream_is_blocked(0));
-  EXPECT_TRUE(stream_is_blocked(1));
-  EXPECT_EQ(2u, manager_.smallest_blocking_index());
-
-  manager_.OnStreamCancellation(0);
-  EXPECT_FALSE(stream_is_blocked(0));
-  EXPECT_TRUE(stream_is_blocked(1));
-  EXPECT_EQ(4u, manager_.smallest_blocking_index());
-
-  manager_.OnStreamCancellation(1);
-  EXPECT_FALSE(stream_is_blocked(0));
-  EXPECT_FALSE(stream_is_blocked(1));
-  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
-            manager_.smallest_blocking_index());
-}
-
-TEST_F(QpackBlockingManagerTest, BlockingAllowedOnStream) {
-  const QuicStreamId kStreamId1 = 1;
-  const QuicStreamId kStreamId2 = 2;
-  const QuicStreamId kStreamId3 = 3;
-
-  // No stream can block if limit is 0.
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
-
-  // Either stream can block if limit is larger.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-
-  // Doubly block first stream.
-  manager_.OnHeaderBlockSent(kStreamId1, {0});
-  manager_.OnHeaderBlockSent(kStreamId1, {1});
-
-  // First stream is already blocked so it can carry more blocking references.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
-  // Second stream is not allowed to block if limit is already reached.
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-
-  // Either stream can block if limit is larger than number of blocked streams.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
-  // Block second stream.
-  manager_.OnHeaderBlockSent(kStreamId2, {2});
-
-  // Streams are already blocked so either can carry more blocking references.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
-  // Third, unblocked stream is not allowed to block unless limit is strictly
-  // larger than number of blocked streams.
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId3, 2));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId3, 3));
-
-  // Acknowledge decoding of first header block on first stream.
-  // Stream is still blocked on its second header block.
-  manager_.OnHeaderAcknowledgement(kStreamId1);
-
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
-  // Acknowledge decoding of second header block on first stream.
-  // This unblocks the stream.
-  manager_.OnHeaderAcknowledgement(kStreamId1);
-
-  // First stream is not allowed to block if limit is already reached.
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
-  // Second stream is already blocked so it can carry more blocking references.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-
-  // Either stream can block if limit is larger than number of blocked streams.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
-
-  // Unblock second stream.
-  manager_.OnHeaderAcknowledgement(kStreamId2);
-
-  // No stream can block if limit is 0.
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
-  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
-
-  // Either stream can block if limit is larger.
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
-  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
-}
-
-TEST_F(QpackBlockingManagerTest, InsertCountIncrementOverflow) {
-  EXPECT_TRUE(manager_.OnInsertCountIncrement(10));
-  EXPECT_EQ(10u, manager_.known_received_count());
-
-  EXPECT_FALSE(manager_.OnInsertCountIncrement(
-      std::numeric_limits<uint64_t>::max() - 5));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/quic/core/qpack/qpack_decoded_headers_accumulator.cc
deleted file mode 100644
index 934cc5f..0000000
--- a/quic/core/qpack/qpack_decoded_headers_accumulator.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QpackDecodedHeadersAccumulator::QpackDecodedHeadersAccumulator(
-    QuicStreamId id,
-    QpackDecoder* qpack_decoder,
-    Visitor* visitor,
-    size_t max_header_list_size)
-    : decoder_(qpack_decoder->CreateProgressiveDecoder(id, this)),
-      visitor_(visitor),
-      max_header_list_size_(max_header_list_size),
-      uncompressed_header_bytes_including_overhead_(0),
-      uncompressed_header_bytes_without_overhead_(0),
-      compressed_header_bytes_(0),
-      header_list_size_limit_exceeded_(false),
-      headers_decoded_(false),
-      error_detected_(false) {
-  quic_header_list_.OnHeaderBlockStart();
-}
-
-void QpackDecodedHeadersAccumulator::OnHeaderDecoded(absl::string_view name,
-                                                     absl::string_view value) {
-  QUICHE_DCHECK(!error_detected_);
-
-  uncompressed_header_bytes_without_overhead_ += name.size() + value.size();
-
-  if (header_list_size_limit_exceeded_) {
-    return;
-  }
-
-  uncompressed_header_bytes_including_overhead_ +=
-      name.size() + value.size() + kQpackEntrySizeOverhead;
-
-  const size_t uncompressed_header_bytes =
-      GetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead)
-          ? uncompressed_header_bytes_including_overhead_
-          : uncompressed_header_bytes_without_overhead_;
-  if (uncompressed_header_bytes > max_header_list_size_) {
-    header_list_size_limit_exceeded_ = true;
-    quic_header_list_.Clear();
-  } else {
-    quic_header_list_.OnHeader(name, value);
-  }
-}
-
-void QpackDecodedHeadersAccumulator::OnDecodingCompleted() {
-  QUICHE_DCHECK(!headers_decoded_);
-  QUICHE_DCHECK(!error_detected_);
-
-  headers_decoded_ = true;
-
-  quic_header_list_.OnHeaderBlockEnd(
-      uncompressed_header_bytes_without_overhead_, compressed_header_bytes_);
-
-  // Might destroy |this|.
-  visitor_->OnHeadersDecoded(std::move(quic_header_list_),
-                             header_list_size_limit_exceeded_);
-}
-
-void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected(
-    QuicErrorCode error_code, absl::string_view error_message) {
-  QUICHE_DCHECK(!error_detected_);
-  QUICHE_DCHECK(!headers_decoded_);
-
-  error_detected_ = true;
-  // Might destroy |this|.
-  visitor_->OnHeaderDecodingError(error_code, error_message);
-}
-
-void QpackDecodedHeadersAccumulator::Decode(absl::string_view data) {
-  QUICHE_DCHECK(!error_detected_);
-
-  compressed_header_bytes_ += data.size();
-  // Might destroy |this|.
-  decoder_->Decode(data);
-}
-
-void QpackDecodedHeadersAccumulator::EndHeaderBlock() {
-  QUICHE_DCHECK(!error_detected_);
-  QUICHE_DCHECK(!headers_decoded_);
-
-  if (!decoder_) {
-    QUIC_BUG(b215142466_EndHeaderBlock);
-    return;
-  }
-
-  // Might destroy |this|.
-  decoder_->EndHeaderBlock();
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator.h b/quic/core/qpack/qpack_decoded_headers_accumulator.h
deleted file mode 100644
index 57d1839..0000000
--- a/quic/core/qpack/qpack_decoded_headers_accumulator.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
-
-#include <cstddef>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QpackDecoder;
-
-// A class that creates and owns a QpackProgressiveDecoder instance, accumulates
-// decoded headers in a QuicHeaderList, and keeps track of uncompressed and
-// compressed size so that it can be passed to
-// QuicHeaderList::OnHeaderBlockEnd().
-class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator
-    : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
-  // Visitor interface to signal success or error.
-  // Exactly one method will be called.
-  // Methods may be called synchronously from Decode() and EndHeaderBlock(),
-  // or asynchronously.
-  // Method implementations are allowed to destroy |this|.
-  class QUIC_EXPORT_PRIVATE Visitor {
-   public:
-    virtual ~Visitor() = default;
-
-    // Called when headers are successfully decoded.  If the uncompressed header
-    // list size including an overhead for each header field exceeds the limit
-    // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator
-    // constructor, then |header_list_size_limit_exceeded| will be true, and
-    // |headers| will be empty but will still have the correct compressed and
-    // uncompressed size
-    // information.
-    virtual void OnHeadersDecoded(QuicHeaderList headers,
-                                  bool header_list_size_limit_exceeded) = 0;
-
-    // Called when an error has occurred.
-    virtual void OnHeaderDecodingError(QuicErrorCode error_code,
-                                       absl::string_view error_message) = 0;
-  };
-
-  QpackDecodedHeadersAccumulator(QuicStreamId id,
-                                 QpackDecoder* qpack_decoder,
-                                 Visitor* visitor,
-                                 size_t max_header_list_size);
-  virtual ~QpackDecodedHeadersAccumulator() = default;
-
-  // QpackProgressiveDecoder::HeadersHandlerInterface implementation.
-  // These methods should only be called by |decoder_|.
-  void OnHeaderDecoded(absl::string_view name,
-                       absl::string_view value) override;
-  void OnDecodingCompleted() override;
-  void OnDecodingErrorDetected(QuicErrorCode error_code,
-                               absl::string_view error_message) override;
-
-  // Decode payload data.
-  // Must not be called if an error has been detected.
-  // Must not be called after EndHeaderBlock().
-  void Decode(absl::string_view data);
-
-  // Signal end of HEADERS frame.
-  // Must not be called if an error has been detected.
-  // Must not be called more that once.
-  void EndHeaderBlock();
-
- private:
-  std::unique_ptr<QpackProgressiveDecoder> decoder_;
-  Visitor* visitor_;
-  // Maximum header list size including overhead.
-  size_t max_header_list_size_;
-  // Uncompressed header list size including overhead, for enforcing the limit.
-  size_t uncompressed_header_bytes_including_overhead_;
-  QuicHeaderList quic_header_list_;
-  // Uncompressed header list size with overhead,
-  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
-  size_t uncompressed_header_bytes_without_overhead_;
-  // Compressed header list size
-  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
-  size_t compressed_header_bytes_;
-
-  // True if the header size limit has been exceeded.
-  // Input data is still fed to QpackProgressiveDecoder.
-  bool header_list_size_limit_exceeded_;
-
-  // The following two members are only used for QUICHE_DCHECKs.
-
-  // True if headers have been completedly and successfully decoded.
-  bool headers_decoded_;
-  // True if an error has been detected during decoding.
-  bool error_detected_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
deleted file mode 100644
index 0aa08a0..0000000
--- a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoded_headers_accumulator.h"
-
-#include <cstring>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::_;
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::Pair;
-using ::testing::SaveArg;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Arbitrary stream ID used for testing.
-QuicStreamId kTestStreamId = 1;
-
-// Limit on header list size.
-const size_t kMaxHeaderListSize = 100;
-
-// Maximum dynamic table capacity.
-const size_t kMaxDynamicTableCapacity = 100;
-
-// Maximum number of blocked streams.
-const uint64_t kMaximumBlockedStreams = 1;
-
-// Header Acknowledgement decoder stream instruction with stream_id = 1.
-const char* const kHeaderAcknowledgement = "\x81";
-
-class MockVisitor : public QpackDecodedHeadersAccumulator::Visitor {
- public:
-  ~MockVisitor() override = default;
-  MOCK_METHOD(void,
-              OnHeadersDecoded,
-              (QuicHeaderList headers, bool header_list_size_limit_exceeded),
-              (override));
-  MOCK_METHOD(void, OnHeaderDecodingError,
-              (QuicErrorCode error_code, absl::string_view error_message),
-              (override));
-};
-
-}  // anonymous namespace
-
-class QpackDecodedHeadersAccumulatorTest : public QuicTest {
- protected:
-  QpackDecodedHeadersAccumulatorTest()
-      : qpack_decoder_(kMaxDynamicTableCapacity,
-                       kMaximumBlockedStreams,
-                       &encoder_stream_error_delegate_),
-        accumulator_(kTestStreamId,
-                     &qpack_decoder_,
-                     &visitor_,
-                     kMaxHeaderListSize) {
-    qpack_decoder_.set_qpack_stream_sender_delegate(
-        &decoder_stream_sender_delegate_);
-  }
-
-  NoopEncoderStreamErrorDelegate encoder_stream_error_delegate_;
-  StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
-  QpackDecoder qpack_decoder_;
-  StrictMock<MockVisitor> visitor_;
-  QpackDecodedHeadersAccumulator accumulator_;
-};
-
-// HEADERS frame payload must have a complete Header Block Prefix.
-TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyPayload) {
-  EXPECT_CALL(visitor_,
-              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                    Eq("Incomplete header data prefix.")));
-  accumulator_.EndHeaderBlock();
-}
-
-// HEADERS frame payload must have a complete Header Block Prefix.
-TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) {
-  accumulator_.Decode(absl::HexStringToBytes("00"));
-
-  EXPECT_CALL(visitor_,
-              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                    Eq("Incomplete header data prefix.")));
-  accumulator_.EndHeaderBlock();
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) {
-  std::string encoded_data(absl::HexStringToBytes("0000"));
-  accumulator_.Decode(encoded_data);
-
-  QuicHeaderList header_list;
-  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
-      .WillOnce(SaveArg<0>(&header_list));
-  accumulator_.EndHeaderBlock();
-
-  EXPECT_EQ(0u, header_list.uncompressed_header_bytes());
-  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
-  EXPECT_TRUE(header_list.empty());
-}
-
-// This payload is the prefix of a valid payload, but EndHeaderBlock() is called
-// before it can be completely decoded.
-TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) {
-  accumulator_.Decode(absl::HexStringToBytes("00002366"));
-
-  EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                              Eq("Incomplete header block.")));
-  accumulator_.EndHeaderBlock();
-}
-
-// This payload is invalid because it refers to a non-existing static entry.
-TEST_F(QpackDecodedHeadersAccumulatorTest, InvalidPayload) {
-  EXPECT_CALL(visitor_,
-              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                    Eq("Static table entry not found.")));
-  accumulator_.Decode(absl::HexStringToBytes("0000ff23ff24"));
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest, Success) {
-  std::string encoded_data(absl::HexStringToBytes("000023666f6f03626172"));
-  accumulator_.Decode(encoded_data);
-
-  QuicHeaderList header_list;
-  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
-      .WillOnce(SaveArg<0>(&header_list));
-  accumulator_.EndHeaderBlock();
-
-  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
-  EXPECT_EQ(strlen("foo") + strlen("bar"),
-            header_list.uncompressed_header_bytes());
-  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
-}
-
-// Test that Decode() calls are not ignored after header list limit is exceeded,
-// otherwise decoding could fail with "incomplete header block" error.
-TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) {
-  // Total length of header list exceeds kMaxHeaderListSize.
-  accumulator_.Decode(absl::HexStringToBytes(
-      "0000"                                      // header block prefix
-      "26666f6f626172"                            // header key: "foobar"
-      "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
-      "616161616161616161616161616161616161616161616161616161616161616161616161"
-      "616161616161616161616161616161616161616161616161616161616161616161616161"
-      "61616161616161616161616161616161616161616161616161616161616161616161"
-      "ff"));  // first byte of a two-byte long Indexed Header Field instruction
-  accumulator_.Decode(absl::HexStringToBytes(
-      "0f"  // second byte of a two-byte long Indexed Header Field instruction
-      ));
-
-  EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
-  accumulator_.EndHeaderBlock();
-}
-
-// Test that header list limit enforcement works with blocked encoding.
-TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) {
-  // Total length of header list exceeds kMaxHeaderListSize.
-  accumulator_.Decode(absl::HexStringToBytes(
-      "0200"            // header block prefix
-      "80"              // reference to dynamic table entry not yet received
-      "26666f6f626172"  // header key: "foobar"
-      "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
-      "616161616161616161616161616161616161616161616161616161616161616161616161"
-      "616161616161616161616161616161616161616161616161616161616161616161616161"
-      "61616161616161616161616161616161616161616161616161616161616161616161"));
-  accumulator_.EndHeaderBlock();
-
-  // Set dynamic table capacity.
-  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
-  // Adding dynamic table entry unblocks decoding.
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-
-  EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
-  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) {
-  // Reference to dynamic table entry not yet received.
-  std::string encoded_data(absl::HexStringToBytes("020080"));
-  accumulator_.Decode(encoded_data);
-  accumulator_.EndHeaderBlock();
-
-  // Set dynamic table capacity.
-  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
-  // Adding dynamic table entry unblocks decoding.
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-
-  QuicHeaderList header_list;
-  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
-      .WillOnce(SaveArg<0>(&header_list));
-  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-
-  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
-  EXPECT_EQ(strlen("foo") + strlen("bar"),
-            header_list.uncompressed_header_bytes());
-  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
-}
-
-TEST_F(QpackDecodedHeadersAccumulatorTest,
-       BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
-  // Reference to dynamic table entry not yet received.
-  accumulator_.Decode(absl::HexStringToBytes("020080"));
-
-  // Set dynamic table capacity.
-  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
-  // Adding dynamic table entry unblocks decoding.
-  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-
-  // Rest of header block: same entry again.
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-  accumulator_.Decode(absl::HexStringToBytes("80"));
-
-  QuicHeaderList header_list;
-  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
-      .WillOnce(SaveArg<0>(&header_list));
-  accumulator_.EndHeaderBlock();
-
-  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar"), Pair("foo", "bar")));
-}
-
-// Regression test for https://crbug.com/1024263.
-TEST_F(QpackDecodedHeadersAccumulatorTest,
-       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
-  // Required Insert Count higher than number of entries causes decoding to be
-  // blocked.
-  accumulator_.Decode(absl::HexStringToBytes("0200"));
-  // Indexed Header Field instruction addressing dynamic table entry with
-  // relative index 0, absolute index 0.
-  accumulator_.Decode(absl::HexStringToBytes("80"));
-  // Relative index larger than or equal to Base is invalid.
-  accumulator_.Decode(absl::HexStringToBytes("81"));
-
-  // Set dynamic table capacity.
-  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
-
-  // Adding dynamic table entry unblocks decoding.  Error is detected.
-  EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                              Eq("Invalid relative index.")));
-  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoder.cc b/quic/core/qpack/qpack_decoder.cc
deleted file mode 100644
index b992616..0000000
--- a/quic/core/qpack/qpack_decoder.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_index_conversions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackDecoder::QpackDecoder(
-    uint64_t maximum_dynamic_table_capacity,
-    uint64_t maximum_blocked_streams,
-    EncoderStreamErrorDelegate* encoder_stream_error_delegate)
-    : encoder_stream_error_delegate_(encoder_stream_error_delegate),
-      encoder_stream_receiver_(this),
-      maximum_blocked_streams_(maximum_blocked_streams),
-      known_received_count_(0) {
-  QUICHE_DCHECK(encoder_stream_error_delegate_);
-
-  header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
-}
-
-QpackDecoder::~QpackDecoder() {}
-
-void QpackDecoder::OnStreamReset(QuicStreamId stream_id) {
-  if (header_table_.maximum_dynamic_table_capacity() > 0) {
-    decoder_stream_sender_.SendStreamCancellation(stream_id);
-    decoder_stream_sender_.Flush();
-  }
-}
-
-bool QpackDecoder::OnStreamBlocked(QuicStreamId stream_id) {
-  auto result = blocked_streams_.insert(stream_id);
-  QUICHE_DCHECK(result.second);
-  return blocked_streams_.size() <= maximum_blocked_streams_;
-}
-
-void QpackDecoder::OnStreamUnblocked(QuicStreamId stream_id) {
-  size_t result = blocked_streams_.erase(stream_id);
-  QUICHE_DCHECK_EQ(1u, result);
-}
-
-void QpackDecoder::OnDecodingCompleted(QuicStreamId stream_id,
-                                       uint64_t required_insert_count) {
-  if (required_insert_count > 0) {
-    decoder_stream_sender_.SendHeaderAcknowledgement(stream_id);
-
-    if (known_received_count_ < required_insert_count) {
-      known_received_count_ = required_insert_count;
-    }
-  }
-
-  // Send an Insert Count Increment instruction if not all dynamic table entries
-  // have been acknowledged yet.  This is necessary for efficient compression in
-  // case the encoder chooses not to reference unacknowledged dynamic table
-  // entries, otherwise inserted entries would never be acknowledged.
-  if (known_received_count_ < header_table_.inserted_entry_count()) {
-    decoder_stream_sender_.SendInsertCountIncrement(
-        header_table_.inserted_entry_count() - known_received_count_);
-    known_received_count_ = header_table_.inserted_entry_count();
-  }
-
-  decoder_stream_sender_.Flush();
-}
-
-void QpackDecoder::OnInsertWithNameReference(bool is_static,
-                                             uint64_t name_index,
-                                             absl::string_view value) {
-  if (is_static) {
-    auto entry = header_table_.LookupEntry(/* is_static = */ true, name_index);
-    if (!entry) {
-      OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
-                      "Invalid static table entry.");
-      return;
-    }
-
-    if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
-      OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC,
-                      "Error inserting entry with name reference.");
-      return;
-    }
-    header_table_.InsertEntry(entry->name(), value);
-    return;
-  }
-
-  uint64_t absolute_index;
-  if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-          name_index, header_table_.inserted_entry_count(), &absolute_index)) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
-                    "Invalid relative index.");
-    return;
-  }
-
-  const QpackEntry* entry =
-      header_table_.LookupEntry(/* is_static = */ false, absolute_index);
-  if (!entry) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND,
-                    "Dynamic table entry not found.");
-    return;
-  }
-  if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC,
-                    "Error inserting entry with name reference.");
-    return;
-  }
-  header_table_.InsertEntry(entry->name(), value);
-}
-
-void QpackDecoder::OnInsertWithoutNameReference(absl::string_view name,
-                                                absl::string_view value) {
-  if (!header_table_.EntryFitsDynamicTableCapacity(name, value)) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
-                    "Error inserting literal entry.");
-    return;
-  }
-  header_table_.InsertEntry(name, value);
-}
-
-void QpackDecoder::OnDuplicate(uint64_t index) {
-  uint64_t absolute_index;
-  if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-          index, header_table_.inserted_entry_count(), &absolute_index)) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
-                    "Invalid relative index.");
-    return;
-  }
-
-  const QpackEntry* entry =
-      header_table_.LookupEntry(/* is_static = */ false, absolute_index);
-  if (!entry) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND,
-                    "Dynamic table entry not found.");
-    return;
-  }
-  if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(),
-                                                   entry->value())) {
-    // This is impossible since entry was retrieved from the dynamic table.
-    OnErrorDetected(QUIC_INTERNAL_ERROR, "Error inserting duplicate entry.");
-    return;
-  }
-  header_table_.InsertEntry(entry->name(), entry->value());
-}
-
-void QpackDecoder::OnSetDynamicTableCapacity(uint64_t capacity) {
-  if (!header_table_.SetDynamicTableCapacity(capacity)) {
-    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
-                    "Error updating dynamic table capacity.");
-  }
-}
-
-void QpackDecoder::OnErrorDetected(QuicErrorCode error_code,
-                                   absl::string_view error_message) {
-  encoder_stream_error_delegate_->OnEncoderStreamError(error_code,
-                                                       error_message);
-}
-
-std::unique_ptr<QpackProgressiveDecoder> QpackDecoder::CreateProgressiveDecoder(
-    QuicStreamId stream_id,
-    QpackProgressiveDecoder::HeadersHandlerInterface* handler) {
-  return std::make_unique<QpackProgressiveDecoder>(stream_id, this, this,
-                                                   &header_table_, handler);
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoder.h b/quic/core/qpack/qpack_decoder.h
deleted file mode 100644
index b947ce3..0000000
--- a/quic/core/qpack/qpack_decoder.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
-
-#include <cstdint>
-#include <memory>
-#include <set>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QPACK decoder class.  Exactly one instance should exist per QUIC connection.
-// This class vends a new QpackProgressiveDecoder instance for each new header
-// list to be encoded.
-// QpackProgressiveDecoder detects and signals errors with header blocks, which
-// are stream errors.
-// The only input of QpackDecoder is the encoder stream.  Any error QpackDecoder
-// signals is an encoder stream error, which is fatal to the connection.
-class QUIC_EXPORT_PRIVATE QpackDecoder
-    : public QpackEncoderStreamReceiver::Delegate,
-      public QpackProgressiveDecoder::BlockedStreamLimitEnforcer,
-      public QpackProgressiveDecoder::DecodingCompletedVisitor {
- public:
-  // Interface for receiving notification that an error has occurred on the
-  // encoder stream.  This MUST be treated as a connection error of type
-  // HTTP_QPACK_ENCODER_STREAM_ERROR.
-  class QUIC_EXPORT_PRIVATE EncoderStreamErrorDelegate {
-   public:
-    virtual ~EncoderStreamErrorDelegate() {}
-
-    virtual void OnEncoderStreamError(QuicErrorCode error_code,
-                                      absl::string_view error_message) = 0;
-  };
-
-  QpackDecoder(uint64_t maximum_dynamic_table_capacity,
-               uint64_t maximum_blocked_streams,
-               EncoderStreamErrorDelegate* encoder_stream_error_delegate);
-  ~QpackDecoder() override;
-
-  // Signal to the peer's encoder that a stream is reset.  This lets the peer's
-  // encoder know that no more header blocks will be processed on this stream,
-  // therefore references to dynamic table entries shall not prevent their
-  // eviction.
-  // This method should be called regardless of whether a header block is being
-  // decoded on that stream, because a header block might be in flight from the
-  // peer.
-  // This method should be called every time a request or push stream is reset
-  // for any reason: for example, client cancels request, or a decoding error
-  // occurs and HeadersHandlerInterface::OnDecodingErrorDetected() is called.
-  // This method should also be called if the stream is reset by the peer,
-  // because the peer's encoder can only evict entries referenced by header
-  // blocks once it receives acknowledgement from this endpoint that the stream
-  // is reset.
-  // However, this method should not be called if the stream is closed normally
-  // using the FIN bit.
-  void OnStreamReset(QuicStreamId stream_id);
-
-  // QpackProgressiveDecoder::BlockedStreamLimitEnforcer implementation.
-  bool OnStreamBlocked(QuicStreamId stream_id) override;
-  void OnStreamUnblocked(QuicStreamId stream_id) override;
-
-  // QpackProgressiveDecoder::DecodingCompletedVisitor implementation.
-  void OnDecodingCompleted(QuicStreamId stream_id,
-                           uint64_t required_insert_count) override;
-
-  // Factory method to create a QpackProgressiveDecoder for decoding a header
-  // block.  |handler| must remain valid until the returned
-  // QpackProgressiveDecoder instance is destroyed or the decoder calls
-  // |handler->OnHeaderBlockEnd()|.
-  std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
-      QuicStreamId stream_id,
-      QpackProgressiveDecoder::HeadersHandlerInterface* handler);
-
-  // QpackEncoderStreamReceiver::Delegate implementation
-  void OnInsertWithNameReference(bool is_static,
-                                 uint64_t name_index,
-                                 absl::string_view value) override;
-  void OnInsertWithoutNameReference(absl::string_view name,
-                                    absl::string_view value) override;
-  void OnDuplicate(uint64_t index) override;
-  void OnSetDynamicTableCapacity(uint64_t capacity) override;
-  void OnErrorDetected(QuicErrorCode error_code,
-                       absl::string_view error_message) override;
-
-  // delegate must be set if dynamic table capacity is not zero.
-  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
-    decoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
-  }
-
-  QpackStreamReceiver* encoder_stream_receiver() {
-    return &encoder_stream_receiver_;
-  }
-
-  // True if any dynamic table entries have been referenced from a header block.
-  bool dynamic_table_entry_referenced() const {
-    return header_table_.dynamic_table_entry_referenced();
-  }
-
- private:
-  EncoderStreamErrorDelegate* const encoder_stream_error_delegate_;
-  QpackEncoderStreamReceiver encoder_stream_receiver_;
-  QpackDecoderStreamSender decoder_stream_sender_;
-  QpackDecoderHeaderTable header_table_;
-  std::set<QuicStreamId> blocked_streams_;
-  const uint64_t maximum_blocked_streams_;
-
-  // Known Received Count is the number of insertions the encoder has received
-  // acknowledgement for (through Header Acknowledgement and Insert Count
-  // Increment instructions).  The encoder must keep track of it in order to be
-  // able to send Insert Count Increment instructions.  See
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
-  uint64_t known_received_count_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
diff --git a/quic/core/qpack/qpack_decoder_stream_receiver.cc b/quic/core/qpack/qpack_decoder_stream_receiver.cc
deleted file mode 100644
index aed660e..0000000
--- a/quic/core/qpack/qpack_decoder_stream_receiver.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "quic/core/qpack/qpack_instructions.h"
-
-namespace quic {
-
-QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate)
-    : instruction_decoder_(QpackDecoderStreamLanguage(), this),
-      delegate_(delegate),
-      error_detected_(false) {
-  QUICHE_DCHECK(delegate_);
-}
-
-void QpackDecoderStreamReceiver::Decode(absl::string_view data) {
-  if (data.empty() || error_detected_) {
-    return;
-  }
-
-  instruction_decoder_.Decode(data);
-}
-
-bool QpackDecoderStreamReceiver::OnInstructionDecoded(
-    const QpackInstruction* instruction) {
-  if (instruction == InsertCountIncrementInstruction()) {
-    delegate_->OnInsertCountIncrement(instruction_decoder_.varint());
-    return true;
-  }
-
-  if (instruction == HeaderAcknowledgementInstruction()) {
-    delegate_->OnHeaderAcknowledgement(instruction_decoder_.varint());
-    return true;
-  }
-
-  QUICHE_DCHECK_EQ(instruction, StreamCancellationInstruction());
-  delegate_->OnStreamCancellation(instruction_decoder_.varint());
-  return true;
-}
-
-void QpackDecoderStreamReceiver::OnInstructionDecodingError(
-    QpackInstructionDecoder::ErrorCode error_code,
-    absl::string_view error_message) {
-  QUICHE_DCHECK(!error_detected_);
-
-  error_detected_ = true;
-
-  // There is no string literals on the decoder stream,
-  // the only possible error is INTEGER_TOO_LARGE.
-  QuicErrorCode quic_error_code =
-      (error_code == QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE)
-          ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE
-          : QUIC_INTERNAL_ERROR;
-  delegate_->OnErrorDetected(quic_error_code, error_message);
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoder_stream_receiver.h b/quic/core/qpack/qpack_decoder_stream_receiver.h
deleted file mode 100644
index 026c7b9..0000000
--- a/quic/core/qpack/qpack_decoder_stream_receiver.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-#include "quic/core/qpack/qpack_stream_receiver.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class decodes data received on the decoder stream,
-// and passes it along to its Delegate.
-class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver
-    : public QpackInstructionDecoder::Delegate,
-      public QpackStreamReceiver {
- public:
-  // An interface for handling instructions decoded from the decoder stream, see
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() = default;
-
-    // 5.3.1 Insert Count Increment
-    virtual void OnInsertCountIncrement(uint64_t increment) = 0;
-    // 5.3.2 Header Acknowledgement
-    virtual void OnHeaderAcknowledgement(QuicStreamId stream_id) = 0;
-    // 5.3.3 Stream Cancellation
-    virtual void OnStreamCancellation(QuicStreamId stream_id) = 0;
-    // Decoding error
-    virtual void OnErrorDetected(QuicErrorCode error_code,
-                                 absl::string_view error_message) = 0;
-  };
-
-  explicit QpackDecoderStreamReceiver(Delegate* delegate);
-  QpackDecoderStreamReceiver() = delete;
-  QpackDecoderStreamReceiver(const QpackDecoderStreamReceiver&) = delete;
-  QpackDecoderStreamReceiver& operator=(const QpackDecoderStreamReceiver&) =
-      delete;
-
-  // Implements QpackStreamReceiver::Decode().
-  // Decode data and call appropriate Delegate method after each decoded
-  // instruction.  Once an error occurs, Delegate::OnErrorDetected() is called,
-  // and all further data is ignored.
-  void Decode(absl::string_view data) override;
-
-  // QpackInstructionDecoder::Delegate implementation.
-  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
-  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
-                                  absl::string_view error_message) override;
-
- private:
-  QpackInstructionDecoder instruction_decoder_;
-  Delegate* const delegate_;
-
-  // True if a decoding error has been detected.
-  bool error_detected_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
diff --git a/quic/core/qpack/qpack_decoder_stream_receiver_test.cc b/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
deleted file mode 100644
index 0a76a17..0000000
--- a/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-using testing::Eq;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QpackDecoderStreamReceiver::Delegate {
- public:
-  ~MockDelegate() override = default;
-
-  MOCK_METHOD(void, OnInsertCountIncrement, (uint64_t increment), (override));
-  MOCK_METHOD(void,
-              OnHeaderAcknowledgement,
-              (QuicStreamId stream_id),
-              (override));
-  MOCK_METHOD(void, OnStreamCancellation, (QuicStreamId stream_id), (override));
-  MOCK_METHOD(void,
-              OnErrorDetected,
-              (QuicErrorCode error_code, absl::string_view error_message),
-              (override));
-};
-
-class QpackDecoderStreamReceiverTest : public QuicTest {
- protected:
-  QpackDecoderStreamReceiverTest() : stream_(&delegate_) {}
-  ~QpackDecoderStreamReceiverTest() override = default;
-
-  QpackDecoderStreamReceiver stream_;
-  StrictMock<MockDelegate> delegate_;
-};
-
-TEST_F(QpackDecoderStreamReceiverTest, InsertCountIncrement) {
-  EXPECT_CALL(delegate_, OnInsertCountIncrement(0));
-  stream_.Decode(absl::HexStringToBytes("00"));
-
-  EXPECT_CALL(delegate_, OnInsertCountIncrement(10));
-  stream_.Decode(absl::HexStringToBytes("0a"));
-
-  EXPECT_CALL(delegate_, OnInsertCountIncrement(63));
-  stream_.Decode(absl::HexStringToBytes("3f00"));
-
-  EXPECT_CALL(delegate_, OnInsertCountIncrement(200));
-  stream_.Decode(absl::HexStringToBytes("3f8901"));
-
-  EXPECT_CALL(delegate_,
-              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-  stream_.Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
-}
-
-TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
-  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
-  stream_.Decode(absl::HexStringToBytes("80"));
-
-  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
-  stream_.Decode(absl::HexStringToBytes("a5"));
-
-  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
-  stream_.Decode(absl::HexStringToBytes("ff00"));
-
-  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
-  stream_.Decode(absl::HexStringToBytes("fff802"));
-
-  EXPECT_CALL(delegate_,
-              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-  stream_.Decode(absl::HexStringToBytes("ffffffffffffffffffffff"));
-}
-
-TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
-  EXPECT_CALL(delegate_, OnStreamCancellation(0));
-  stream_.Decode(absl::HexStringToBytes("40"));
-
-  EXPECT_CALL(delegate_, OnStreamCancellation(19));
-  stream_.Decode(absl::HexStringToBytes("53"));
-
-  EXPECT_CALL(delegate_, OnStreamCancellation(63));
-  stream_.Decode(absl::HexStringToBytes("7f00"));
-
-  EXPECT_CALL(delegate_, OnStreamCancellation(110));
-  stream_.Decode(absl::HexStringToBytes("7f2f"));
-
-  EXPECT_CALL(delegate_,
-              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-  stream_.Decode(absl::HexStringToBytes("7fffffffffffffffffffff"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoder_stream_sender.cc b/quic/core/qpack/qpack_decoder_stream_sender.cc
deleted file mode 100644
index 9e2488d..0000000
--- a/quic/core/qpack/qpack_decoder_stream_sender.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-
-#include <cstddef>
-#include <limits>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackDecoderStreamSender::QpackDecoderStreamSender() : delegate_(nullptr) {}
-
-void QpackDecoderStreamSender::SendInsertCountIncrement(uint64_t increment) {
-  instruction_encoder_.Encode(
-      QpackInstructionWithValues::InsertCountIncrement(increment), &buffer_);
-}
-
-void QpackDecoderStreamSender::SendHeaderAcknowledgement(
-    QuicStreamId stream_id) {
-  instruction_encoder_.Encode(
-      QpackInstructionWithValues::HeaderAcknowledgement(stream_id), &buffer_);
-}
-
-void QpackDecoderStreamSender::SendStreamCancellation(QuicStreamId stream_id) {
-  instruction_encoder_.Encode(
-      QpackInstructionWithValues::StreamCancellation(stream_id), &buffer_);
-}
-
-void QpackDecoderStreamSender::Flush() {
-  if (buffer_.empty()) {
-    return;
-  }
-
-  delegate_->WriteStreamData(buffer_);
-  buffer_.clear();
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoder_stream_sender.h b/quic/core/qpack/qpack_decoder_stream_sender.h
deleted file mode 100644
index c554651..0000000
--- a/quic/core/qpack/qpack_decoder_stream_sender.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
-
-#include <cstdint>
-
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class serializes instructions for transmission on the decoder stream.
-// Serialized instructions are buffered until Flush() is called.
-class QUIC_EXPORT_PRIVATE QpackDecoderStreamSender {
- public:
-  QpackDecoderStreamSender();
-  QpackDecoderStreamSender(const QpackDecoderStreamSender&) = delete;
-  QpackDecoderStreamSender& operator=(const QpackDecoderStreamSender&) = delete;
-
-  // Methods for serializing and buffering instructions, see
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
-
-  // 5.3.1 Insert Count Increment
-  void SendInsertCountIncrement(uint64_t increment);
-  // 5.3.2 Header Acknowledgement
-  void SendHeaderAcknowledgement(QuicStreamId stream_id);
-  // 5.3.3 Stream Cancellation
-  void SendStreamCancellation(QuicStreamId stream_id);
-
-  // Writes all buffered instructions on the decoder stream.
-  void Flush();
-
-  // delegate must be set if dynamic table capacity is not zero.
-  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
-    delegate_ = delegate;
-  }
-
- private:
-  QpackStreamSenderDelegate* delegate_;
-  QpackInstructionEncoder instruction_encoder_;
-  std::string buffer_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
diff --git a/quic/core/qpack/qpack_decoder_stream_sender_test.cc b/quic/core/qpack/qpack_decoder_stream_sender_test.cc
deleted file mode 100644
index 708e7a3..0000000
--- a/quic/core/qpack/qpack_decoder_stream_sender_test.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder_stream_sender.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::Eq;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QpackDecoderStreamSenderTest : public QuicTest {
- protected:
-  QpackDecoderStreamSenderTest() {
-    stream_.set_qpack_stream_sender_delegate(&delegate_);
-  }
-  ~QpackDecoderStreamSenderTest() override = default;
-
-  StrictMock<MockQpackStreamSenderDelegate> delegate_;
-  QpackDecoderStreamSender stream_;
-};
-
-TEST_F(QpackDecoderStreamSenderTest, InsertCountIncrement) {
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("00"))));
-  stream_.SendInsertCountIncrement(0);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0a"))));
-  stream_.SendInsertCountIncrement(10);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f00"))));
-  stream_.SendInsertCountIncrement(63);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f8901"))));
-  stream_.SendInsertCountIncrement(200);
-  stream_.Flush();
-}
-
-TEST_F(QpackDecoderStreamSenderTest, HeaderAcknowledgement) {
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("80"))));
-  stream_.SendHeaderAcknowledgement(0);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("a5"))));
-  stream_.SendHeaderAcknowledgement(37);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("ff00"))));
-  stream_.SendHeaderAcknowledgement(127);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("fff802"))));
-  stream_.SendHeaderAcknowledgement(503);
-  stream_.Flush();
-}
-
-TEST_F(QpackDecoderStreamSenderTest, StreamCancellation) {
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("40"))));
-  stream_.SendStreamCancellation(0);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("53"))));
-  stream_.SendStreamCancellation(19);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f00"))));
-  stream_.SendStreamCancellation(63);
-  stream_.Flush();
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f2f"))));
-  stream_.SendStreamCancellation(110);
-  stream_.Flush();
-}
-
-TEST_F(QpackDecoderStreamSenderTest, Coalesce) {
-  stream_.SendInsertCountIncrement(10);
-  stream_.SendHeaderAcknowledgement(37);
-  stream_.SendStreamCancellation(0);
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0aa540"))));
-  stream_.Flush();
-
-  stream_.SendInsertCountIncrement(63);
-  stream_.SendStreamCancellation(110);
-
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(absl::HexStringToBytes("3f007f2f"))));
-  stream_.Flush();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_decoder_test.cc b/quic/core/qpack/qpack_decoder_test.cc
deleted file mode 100644
index fe45397..0000000
--- a/quic/core/qpack/qpack_decoder_test.cc
+++ /dev/null
@@ -1,984 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_decoder.h"
-
-#include <algorithm>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::Mock;
-using ::testing::Sequence;
-using ::testing::StrictMock;
-using ::testing::Values;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Header Acknowledgement decoder stream instruction with stream_id = 1.
-const char* const kHeaderAcknowledgement = "\x81";
-
-const uint64_t kMaximumDynamicTableCapacity = 1024;
-const uint64_t kMaximumBlockedStreams = 1;
-
-class QpackDecoderTest : public QuicTestWithParam<FragmentMode> {
- protected:
-  QpackDecoderTest()
-      : qpack_decoder_(kMaximumDynamicTableCapacity,
-                       kMaximumBlockedStreams,
-                       &encoder_stream_error_delegate_),
-        fragment_mode_(GetParam()) {
-    qpack_decoder_.set_qpack_stream_sender_delegate(
-        &decoder_stream_sender_delegate_);
-  }
-
-  ~QpackDecoderTest() override = default;
-
-  void SetUp() override {
-    // Destroy QpackProgressiveDecoder on error to test that it does not crash.
-    // See https://crbug.com/1025209.
-    ON_CALL(handler_, OnDecodingErrorDetected(_, _))
-        .WillByDefault(Invoke([this](QuicErrorCode /* error_code */,
-                                     absl::string_view /* error_message */) {
-          progressive_decoder_.reset();
-        }));
-  }
-
-  void DecodeEncoderStreamData(absl::string_view data) {
-    qpack_decoder_.encoder_stream_receiver()->Decode(data);
-  }
-
-  std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
-      QuicStreamId stream_id) {
-    return qpack_decoder_.CreateProgressiveDecoder(stream_id, &handler_);
-  }
-
-  // Set up |progressive_decoder_|.
-  void StartDecoding() {
-    progressive_decoder_ = CreateProgressiveDecoder(/* stream_id = */ 1);
-  }
-
-  // Pass header block data to QpackProgressiveDecoder::Decode()
-  // in fragments dictated by |fragment_mode_|.
-  void DecodeData(absl::string_view data) {
-    auto fragment_size_generator =
-        FragmentModeToFragmentSizeGenerator(fragment_mode_);
-    while (progressive_decoder_ && !data.empty()) {
-      size_t fragment_size = std::min(fragment_size_generator(), data.size());
-      progressive_decoder_->Decode(data.substr(0, fragment_size));
-      data = data.substr(fragment_size);
-    }
-  }
-
-  // Signal end of header block to QpackProgressiveDecoder.
-  void EndDecoding() {
-    if (progressive_decoder_) {
-      progressive_decoder_->EndHeaderBlock();
-    }
-    // If no error was detected, |*progressive_decoder_| is kept alive so that
-    // it can handle callbacks later in case of blocked decoding.
-  }
-
-  // Decode an entire header block.
-  void DecodeHeaderBlock(absl::string_view data) {
-    StartDecoding();
-    DecodeData(data);
-    EndDecoding();
-  }
-
-  StrictMock<MockEncoderStreamErrorDelegate> encoder_stream_error_delegate_;
-  StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
-  StrictMock<MockHeadersHandler> handler_;
-
- private:
-  QpackDecoder qpack_decoder_;
-  const FragmentMode fragment_mode_;
-  std::unique_ptr<QpackProgressiveDecoder> progressive_decoder_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         QpackDecoderTest,
-                         Values(FragmentMode::kSingleChunk,
-                                FragmentMode::kOctetByOctet));
-
-TEST_P(QpackDecoderTest, NoPrefix) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Incomplete header data prefix.")));
-
-  // Header Data Prefix is at least two bytes long.
-  DecodeHeaderBlock(absl::HexStringToBytes("00"));
-}
-
-// Regression test for https://1025209: QpackProgressiveDecoder must not crash
-// in Decode() if it is destroyed by handler_.OnDecodingErrorDetected().
-TEST_P(QpackDecoderTest, InvalidPrefix) {
-  StartDecoding();
-
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Encoded integer too large.")));
-
-  // Encoded Required Insert Count in Header Data Prefix is too large.
-  DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff"));
-}
-
-TEST_P(QpackDecoderTest, EmptyHeaderBlock) {
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes("0000"));
-}
-
-TEST_P(QpackDecoderTest, LiteralEntryEmptyName) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f"));
-}
-
-TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00"));
-}
-
-TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes("00002000"));
-}
-
-TEST_P(QpackDecoderTest, SimpleLiteralEntry) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172"));
-}
-
-TEST_P(QpackDecoderTest, MultipleLiteralEntries) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  std::string str(127, 'a');
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str)));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0000"                // prefix
-      "23666f6f03626172"    // foo: bar
-      "2700666f6f62616172"  // 7 octet long header name, the smallest number
-                            // that does not fit on a 3-bit prefix.
-      "7f0061616161616161"  // 127 octet long header value, the smallest number
-      "616161616161616161"  // that does not fit on a 7-bit prefix.
-      "6161616161616161616161616161616161616161616161616161616161616161616161"
-      "6161616161616161616161616161616161616161616161616161616161616161616161"
-      "6161616161616161616161616161616161616161616161616161616161616161616161"
-      "616161616161"));
-}
-
-// Name Length value is too large for varint decoder to decode.
-TEST_P(QpackDecoderTest, NameLenTooLargeForVarintDecoder) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Encoded integer too large.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff"));
-}
-
-// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_P(QpackDecoderTest, NameLenExceedsLimit) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("String literal too long.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f"));
-}
-
-// Value Length value is too large for varint decoder to decode.
-TEST_P(QpackDecoderTest, ValueLenTooLargeForVarintDecoder) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Encoded integer too large.")));
-
-  DecodeHeaderBlock(
-      absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff"));
-}
-
-// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_P(QpackDecoderTest, ValueLenExceedsLimit) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("String literal too long.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f"));
-}
-
-TEST_P(QpackDecoderTest, LineFeedInValue) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
-                                      "Invalid character in field value."));
-
-  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f0462610a72"));
-}
-
-TEST_P(QpackDecoderTest, IncompleteHeaderBlock) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Incomplete header block.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes("00002366"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanSimple) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(
-      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
-}
-
-TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) {
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")))
-      .Times(4);
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0000"                        // Prefix.
-      "2f0125a849e95ba97d7f"        // Huffman-encoded name.
-      "8925a849e95bb8e8b4bf"        // Huffman-encoded value.
-      "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
-      "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
-      "2f0125a849e95ba97d7f"        // Huffman-encoded name.
-      "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
-      "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
-      "8925a849e95bb8e8b4bf"));     // Huffman-encoded value.
-}
-
-TEST_P(QpackDecoderTest, HuffmanNameDoesNotHaveEOSPrefix) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Error in Huffman-encoded string.")));
-
-  // 'y' ends in 0b0 on the most significant bit of the last byte.
-  // The remaining 7 bits must be a prefix of EOS, which is all 1s.
-  DecodeHeaderBlock(
-      absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Error in Huffman-encoded string.")));
-
-  // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte.
-  // The remaining 5 bits must be a prefix of EOS, which is all 1s.
-  DecodeHeaderBlock(
-      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Error in Huffman-encoded string.")));
-
-  // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
-  // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a
-  // prefix of EOS.
-  DecodeHeaderBlock(
-      absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
-}
-
-TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) {
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Error in Huffman-encoded string.")));
-
-  // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
-  // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a
-  // prefix of EOS.
-  DecodeHeaderBlock(
-      absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
-}
-
-TEST_P(QpackDecoderTest, StaticTable) {
-  // A header name that has multiple entries with different values.
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("POST")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("TRACE")));
-
-  // A header name that has a single entry with non-empty value.
-  EXPECT_CALL(handler_,
-              OnHeaderDecoded(Eq("accept-encoding"), Eq("gzip, deflate, br")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("compress")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("")));
-
-  // A header name that has a single entry with empty value.
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("foo")));
-
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000"));
-}
-
-TEST_P(QpackDecoderTest, TooHighStaticTableIndex) {
-  // This is the last entry in the static table with index 98.
-  EXPECT_CALL(handler_,
-              OnHeaderDecoded(Eq("x-frame-options"), Eq("sameorigin")));
-
-  // Addressing entry 99 should trigger an error.
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Static table entry not found.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24"));
-}
-
-TEST_P(QpackDecoderTest, DynamicTable) {
-  DecodeEncoderStreamData(absl::HexStringToBytes(
-      "3fe107"          // Set dynamic table capacity to 1024.
-      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
-      "80035a5a5a"      // Add entry with name of dynamic table entry index 0
-                        // (relative index) and value "ZZZ".
-      "cf8294e7"        // Add entry with name of static table entry index 15
-                        // and value "foo".
-      "01"));           // Duplicate entry with relative index 1.
-
-  // Now there are four entries in the dynamic table.
-  // Entry 0: "foo", "bar"
-  // Entry 1: "foo", "ZZZ"
-  // Entry 2: ":method", "foo"
-  // Entry 3: "foo", "ZZZ"
-
-  // Use a Sequence to test that mock methods are called in order.
-  Sequence s;
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
-      .InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)))
-      .InSequence(s);
-  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0500"  // Required Insert Count 4 and Delta Base 0.
-              // Base is 4 + 0 = 4.
-      "83"    // Dynamic table entry with relative index 3, absolute index 0.
-      "82"    // Dynamic table entry with relative index 2, absolute index 1.
-      "81"    // Dynamic table entry with relative index 1, absolute index 2.
-      "80"    // Dynamic table entry with relative index 0, absolute index 3.
-      "41025a5a"));  // Name of entry 1 (relative index) from dynamic table,
-                     // with value "ZZ".
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
-      .InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)))
-      .InSequence(s);
-  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0502"  // Required Insert Count 4 and Delta Base 2.
-              // Base is 4 + 2 = 6.
-      "85"    // Dynamic table entry with relative index 5, absolute index 0.
-      "84"    // Dynamic table entry with relative index 4, absolute index 1.
-      "83"    // Dynamic table entry with relative index 3, absolute index 2.
-      "82"    // Dynamic table entry with relative index 2, absolute index 3.
-      "43025a5a"));  // Name of entry 3 (relative index) from dynamic table,
-                     // with value "ZZ".
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
-      .InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)))
-      .InSequence(s);
-  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0582"  // Required Insert Count 4 and Delta Base 2 with sign bit set.
-              // Base is 4 - 2 - 1 = 1.
-      "80"    // Dynamic table entry with relative index 0, absolute index 0.
-      "10"    // Dynamic table entry with post-base index 0, absolute index 1.
-      "11"    // Dynamic table entry with post-base index 1, absolute index 2.
-      "12"    // Dynamic table entry with post-base index 2, absolute index 3.
-      "01025a5a"));  // Name of entry 1 (post-base index) from dynamic table,
-                     // with value "ZZ".
-}
-
-TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) {
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
-
-  // Change dynamic table capacity to 32 bytes, smaller than the entry.
-  // This must cause the entry to be evicted.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3f01"));
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Dynamic table entry already evicted.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorEntryTooLarge) {
-  EXPECT_CALL(
-      encoder_stream_error_delegate_,
-      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
-                           Eq("Error inserting literal entry.")));
-
-  // Set dynamic table capacity to 34.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3f03"));
-  // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38.
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) {
-  EXPECT_CALL(
-      encoder_stream_error_delegate_,
-      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
-                           Eq("Invalid static table entry.")));
-
-  // Address invalid static table entry index 99.
-  DecodeEncoderStreamData(absl::HexStringToBytes("ff2400"));
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) {
-  EXPECT_CALL(encoder_stream_error_delegate_,
-              OnEncoderStreamError(
-                  QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
-                  Eq("Invalid relative index.")));
-
-  DecodeEncoderStreamData(absl::HexStringToBytes(
-      "3fe107"          // Set dynamic table capacity to 1024.
-      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
-      "8100"));  // Address dynamic table entry with relative index 1.  Such
-                 // entry does not exist.  The most recently added and only
-                 // dynamic table entry has relative index 0.
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) {
-  EXPECT_CALL(encoder_stream_error_delegate_,
-              OnEncoderStreamError(
-                  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
-                  Eq("Invalid relative index.")));
-
-  DecodeEncoderStreamData(absl::HexStringToBytes(
-      "3fe107"          // Set dynamic table capacity to 1024.
-      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
-      "01"));  // Duplicate dynamic table entry with relative index 1.  Such
-               // entry does not exist.  The most recently added and only
-               // dynamic table entry has relative index 0.
-}
-
-TEST_P(QpackDecoderTest, EncoderStreamErrorTooLargeInteger) {
-  EXPECT_CALL(encoder_stream_error_delegate_,
-              OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                                   Eq("Encoded integer too large.")));
-
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff"));
-}
-
-TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) {
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                                Eq("Invalid relative index.")));
-
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0280"   // Required Insert Count is 1.  Base 1 - 1 - 0 = 0 is explicitly
-               // permitted by the spec.
-      "80"));  // However, addressing entry with relative index 0 would point to
-               // absolute index -1, which is invalid.
-}
-
-TEST_P(QpackDecoderTest, InvalidNegativeBase) {
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                                Eq("Error calculating Base.")));
-
-  // Required Insert Count 1, Delta Base 1 with sign bit set, Base would
-  // be 1 - 1 - 1 = -1, but it is not allowed to be negative.
-  DecodeHeaderBlock(absl::HexStringToBytes("0281"));
-}
-
-TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) {
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                                Eq("Invalid relative index.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "81"));  // Indexed Header Field instruction addressing relative index 1.
-               // This is absolute index -1, which is invalid.
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                                Eq("Invalid relative index.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"     // Required Insert Count 1 and Delta Base 0.
-                 // Base is 1 + 0 = 1.
-      "4100"));  // Literal Header Field with Name Reference instruction
-                 // addressing relative index 1.  This is absolute index -1,
-                 // which is invalid.
-}
-
-TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) {
-  // Update dynamic table capacity to 128.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
-
-  // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38.
-  // This fits in the table three times.
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-  // Duplicate entry four times.  This evicts the first two instances.
-  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Dynamic table entry already evicted.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0500"   // Required Insert Count 4 and Delta Base 0.
-               // Base is 4 + 0 = 4.
-      "82"));  // Indexed Header Field instruction addressing relative index 2.
-               // This is absolute index 1. Such entry does not exist.
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Dynamic table entry already evicted.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0500"     // Required Insert Count 4 and Delta Base 0.
-                 // Base is 4 + 0 = 4.
-      "4200"));  // Literal Header Field with Name Reference instruction
-                 // addressing relative index 2.  This is absolute index 1. Such
-                 // entry does not exist.
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Dynamic table entry already evicted.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0380"   // Required Insert Count 2 and Delta Base 0 with sign bit set.
-               // Base is 2 - 0 - 1 = 1
-      "10"));  // Indexed Header Field instruction addressing dynamic table
-               // entry with post-base index 0, absolute index 1.  Such entry
-               // does not exist.
-
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Dynamic table entry already evicted.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0380"     // Required Insert Count 2 and Delta Base 0 with sign bit set.
-                 // Base is 2 - 0 - 1 = 1
-      "0000"));  // Literal Header Field With Name Reference instruction
-                 // addressing dynamic table entry with post-base index 0,
-                 // absolute index 1.  Such entry does not exist.
-}
-
-TEST_P(QpackDecoderTest, TableCapacityMustNotExceedMaximum) {
-  EXPECT_CALL(
-      encoder_stream_error_delegate_,
-      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
-                           Eq("Error updating dynamic table capacity.")));
-
-  // Try to update dynamic table capacity to 2048, which exceeds the maximum.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f"));
-}
-
-TEST_P(QpackDecoderTest, SetDynamicTableCapacity) {
-  // Update dynamic table capacity to 128, which does not exceed the maximum.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
-}
-
-TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) {
-  // Maximum dynamic table capacity is 1024.
-  // MaxEntries is 1024 / 32 = 32.
-  // Required Insert Count is decoded modulo 2 * MaxEntries, that is, modulo 64.
-  // A value of 1 cannot be encoded as 65 even though it has the same remainder.
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Error decoding Required Insert Count.")));
-  DecodeHeaderBlock(absl::HexStringToBytes("4100"));
-}
-
-// Regression test for https://crbug.com/970218:  Decoder must stop processing
-// after a Header Block Prefix with an invalid Encoded Required Insert Count.
-TEST_P(QpackDecoderTest, DataAfterInvalidEncodedRequiredInsertCount) {
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(
-                            QUIC_QPACK_DECOMPRESSION_FAILED,
-                            Eq("Error decoding Required Insert Count.")));
-  // Header Block Prefix followed by some extra data.
-  DecodeHeaderBlock(absl::HexStringToBytes("410000"));
-}
-
-TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) {
-  // Maximum dynamic table capacity is 1024.
-  // MaxEntries is 1024 / 32 = 32.
-
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and a 600 byte long value.  This will fit
-  // in the dynamic table once but not twice.
-  DecodeEncoderStreamData(
-      absl::HexStringToBytes("6294e7"     // Name "foo".
-                             "7fd903"));  // Value length 600.
-  std::string header_value(600, 'Z');
-  DecodeEncoderStreamData(header_value);
-
-  // Duplicate most recent entry 200 times.
-  DecodeEncoderStreamData(std::string(200, '\x00'));
-
-  // Now there is only one entry in the dynamic table, with absolute index 200.
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq(header_value)));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-
-  // Send header block with Required Insert Count = 201.
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0a00"   // Encoded Required Insert Count 10, Required Insert Count 201,
-               // Delta Base 0, Base 201.
-      "80"));  // Emit dynamic table entry with relative index 0.
-}
-
-TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) {
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Required Insert Count too large.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count is 1.
-      "d1"));  // But the only instruction references the static table.
-}
-
-TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) {
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
-  EXPECT_CALL(
-      handler_,
-      OnDecodingErrorDetected(
-          QUIC_QPACK_DECOMPRESSION_FAILED,
-          Eq("Absolute Index must be smaller than Required Insert Count.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0201"   // Required Insert Count 1 and Delta Base 1.
-               // Base is 1 + 1 = 2.
-      "80"));  // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 0, absolute index 1.  This is not
-               // allowed by Required Insert Count.
-
-  EXPECT_CALL(
-      handler_,
-      OnDecodingErrorDetected(
-          QUIC_QPACK_DECOMPRESSION_FAILED,
-          Eq("Absolute Index must be smaller than Required Insert Count.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0201"     // Required Insert Count 1 and Delta Base 1.
-                 // Base is 1 + 1 = 2.
-      "4000"));  // Literal Header Field with Name Reference instruction
-                 // addressing dynamic table entry with relative index 0,
-                 // absolute index 1.  This is not allowed by Required Index
-                 // Count.
-
-  EXPECT_CALL(
-      handler_,
-      OnDecodingErrorDetected(
-          QUIC_QPACK_DECOMPRESSION_FAILED,
-          Eq("Absolute Index must be smaller than Required Insert Count.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "10"));  // Indexed Header Field with Post-Base Index instruction
-               // addressing dynamic table entry with post-base index 0,
-               // absolute index 1.  This is not allowed by Required Insert
-               // Count.
-
-  EXPECT_CALL(
-      handler_,
-      OnDecodingErrorDetected(
-          QUIC_QPACK_DECOMPRESSION_FAILED,
-          Eq("Absolute Index must be smaller than Required Insert Count.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"     // Required Insert Count 1 and Delta Base 0.
-                 // Base is 1 + 0 = 1.
-      "0000"));  // Literal Header Field with Post-Base Name Reference
-                 // instruction addressing dynamic table entry with post-base
-                 // index 0, absolute index 1.  This is not allowed by Required
-                 // Index Count.
-}
-
-TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) {
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-  // Duplicate entry twice so that decoding of header blocks with Required
-  // Insert Count not exceeding 3 is not blocked.
-  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
-  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Required Insert Count too large.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0300"   // Required Insert Count 2 and Delta Base 0.
-               // Base is 2 + 0 = 2.
-      "81"));  // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 1, absolute index 0.  Header block
-               // requires insert count of 1, even though Required Insert Count
-               // is 2.
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Required Insert Count too large.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0300"     // Required Insert Count 2 and Delta Base 0.
-                 // Base is 2 + 0 = 2.
-      "4100"));  // Literal Header Field with Name Reference instruction
-                 // addressing dynamic table entry with relative index 1,
-                 // absolute index 0.  Header block requires insert count of 1,
-                 // even though Required Insert Count is 2.
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Required Insert Count too large.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0481"   // Required Insert Count 3 and Delta Base 1 with sign bit set.
-               // Base is 3 - 1 - 1 = 1.
-      "10"));  // Indexed Header Field with Post-Base Index instruction
-               // addressing dynamic table entry with post-base index 0,
-               // absolute index 1.  Header block requires insert count of 2,
-               // even though Required Insert Count is 3.
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                      Eq("Required Insert Count too large.")));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0481"     // Required Insert Count 3 and Delta Base 1 with sign bit set.
-                 // Base is 3 - 1 - 1 = 1.
-      "0000"));  // Literal Header Field with Post-Base Name Reference
-                 // instruction addressing dynamic table entry with post-base
-                 // index 0, absolute index 1.  Header block requires insert
-                 // count of 2, even though Required Insert Count is 3.
-}
-
-TEST_P(QpackDecoderTest, BlockedDecoding) {
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "80"));  // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 0, absolute index 0.
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-}
-
-TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
-  StartDecoding();
-  DecodeData(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "80"     // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 0, absolute index 0.
-      "d1"));  // Static table entry with index 17.
-
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-
-  // Add literal entry with name "foo" and value "bar".  Decoding is now
-  // unblocked because dynamic table Insert Count reached the Required Insert
-  // Count of the header block.  |handler_| methods are called immediately for
-  // the already consumed part of the header block.
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-  Mock::VerifyAndClearExpectations(&handler_);
-
-  // Rest of header block is processed by QpackProgressiveDecoder
-  // in the unblocked state.
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https")));
-  DecodeData(absl::HexStringToBytes(
-      "80"     // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 0, absolute index 0.
-      "d7"));  // Static table entry with index 23.
-  Mock::VerifyAndClearExpectations(&handler_);
-
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-  EndDecoding();
-}
-
-// Regression test for https://crbug.com/1024263.
-TEST_P(QpackDecoderTest,
-       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
-  StartDecoding();
-  DecodeData(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "80"     // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 0, absolute index 0.
-      "81"));  // Relative index 1 is equal to Base, therefore invalid.
-
-  // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
-
-  // Add literal entry with name "foo" and value "bar".  Decoding is now
-  // unblocked because dynamic table Insert Count reached the Required Insert
-  // Count of the header block.  |handler_| methods are called immediately for
-  // the already consumed part of the header block.
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
-                                                Eq("Invalid relative index.")));
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-}
-
-// Make sure that Required Insert Count is compared to Insert Count,
-// not size of dynamic table.
-TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {
-  // Update dynamic table capacity to 128.
-  // At most three non-empty entries fit in the dynamic table.
-  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0700"   // Required Insert Count 6 and Delta Base 0.
-               // Base is 6 + 0 = 6.
-      "80"));  // Indexed Header Field instruction addressing dynamic table
-               // entry with relative index 0, absolute index 5.
-
-  // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
-
-  // Duplicate entry four times.  This evicts the first two instances.
-  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(kHeaderAcknowledgement)));
-
-  // Add literal entry with name "foo" and value "bar".
-  // Insert Count is now 6, reaching Required Insert Count of the header block.
-  DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a"));
-}
-
-TEST_P(QpackDecoderTest, TooManyBlockedStreams) {
-  // Required Insert Count 1 and Delta Base 0.
-  // Without any dynamic table entries received, decoding is blocked.
-  std::string data = absl::HexStringToBytes("0200");
-
-  auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1);
-  progressive_decoder1->Decode(data);
-
-  EXPECT_CALL(handler_,
-              OnDecodingErrorDetected(
-                  QUIC_QPACK_DECOMPRESSION_FAILED,
-                  Eq("Limit on number of blocked streams exceeded.")));
-
-  auto progressive_decoder2 = CreateProgressiveDecoder(/* stream_id = */ 2);
-  progressive_decoder2->Decode(data);
-}
-
-TEST_P(QpackDecoderTest, InsertCountIncrement) {
-  DecodeEncoderStreamData(absl::HexStringToBytes(
-      "3fe107"          // Set dynamic table capacity to 1024.
-      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
-      "00"));           // Duplicate entry.
-
-  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
-  EXPECT_CALL(handler_, OnDecodingCompleted());
-
-  // Decoder received two insertions, but Header Acknowledgement only increases
-  // Known Insert Count to one.  Decoder should send an Insert Count Increment
-  // instruction with increment of one to update Known Insert Count to two.
-  EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(absl::HexStringToBytes(
-                  "81"       // Header Acknowledgement on stream 1
-                  "01"))));  // Insert Count Increment with increment of one
-
-  DecodeHeaderBlock(absl::HexStringToBytes(
-      "0200"   // Required Insert Count 1 and Delta Base 0.
-               // Base is 1 + 0 = 1.
-      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder.cc b/quic/core/qpack/qpack_encoder.cc
deleted file mode 100644
index 8037542..0000000
--- a/quic/core/qpack/qpack_encoder.cc
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_index_conversions.h"
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-#include "quic/core/qpack/qpack_required_insert_count.h"
-#include "quic/core/qpack/value_splitting_header_list.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Fraction to calculate draining index.  The oldest |kDrainingFraction| entries
-// will not be referenced in header blocks.  A new entry (duplicate or literal
-// with name reference) will be added to the dynamic table instead.  This allows
-// the number of references to the draining entry to go to zero faster, so that
-// it can be evicted.  See
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
-// TODO(bnc): Fine tune.
-const float kDrainingFraction = 0.25;
-
-}  // anonymous namespace
-
-QpackEncoder::QpackEncoder(
-    DecoderStreamErrorDelegate* decoder_stream_error_delegate)
-    : decoder_stream_error_delegate_(decoder_stream_error_delegate),
-      decoder_stream_receiver_(this),
-      maximum_blocked_streams_(0),
-      header_list_count_(0) {
-  QUICHE_DCHECK(decoder_stream_error_delegate_);
-}
-
-QpackEncoder::~QpackEncoder() {}
-
-// static
-QpackEncoder::Representation QpackEncoder::EncodeIndexedHeaderField(
-    bool is_static,
-    uint64_t index,
-    QpackBlockingManager::IndexSet* referred_indices) {
-  // Add |index| to |*referred_indices| only if entry is in the dynamic table.
-  if (!is_static) {
-    referred_indices->insert(index);
-  }
-  return Representation::IndexedHeaderField(is_static, index);
-}
-
-// static
-QpackEncoder::Representation
-QpackEncoder::EncodeLiteralHeaderFieldWithNameReference(
-    bool is_static,
-    uint64_t index,
-    absl::string_view value,
-    QpackBlockingManager::IndexSet* referred_indices) {
-  // Add |index| to |*referred_indices| only if entry is in the dynamic table.
-  if (!is_static) {
-    referred_indices->insert(index);
-  }
-  return Representation::LiteralHeaderFieldNameReference(is_static, index,
-                                                         value);
-}
-
-// static
-QpackEncoder::Representation QpackEncoder::EncodeLiteralHeaderField(
-    absl::string_view name,
-    absl::string_view value) {
-  return Representation::LiteralHeaderField(name, value);
-}
-
-QpackEncoder::Representations QpackEncoder::FirstPassEncode(
-    QuicStreamId stream_id,
-    const spdy::Http2HeaderBlock& header_list,
-    QpackBlockingManager::IndexSet* referred_indices,
-    QuicByteCount* encoder_stream_sent_byte_count) {
-  // If previous instructions are buffered in |encoder_stream_sender_|,
-  // do not count them towards the current header block.
-  const QuicByteCount initial_encoder_stream_buffered_byte_count =
-      encoder_stream_sender_.BufferedByteCount();
-
-  const bool can_write_to_encoder_stream = encoder_stream_sender_.CanWrite();
-
-  Representations representations;
-  representations.reserve(header_list.size());
-
-  // The index of the oldest entry that must not be evicted.
-  uint64_t smallest_blocking_index =
-      blocking_manager_.smallest_blocking_index();
-  // Entries with index larger than or equal to |known_received_count| are
-  // blocking.
-  const uint64_t known_received_count =
-      blocking_manager_.known_received_count();
-  // Only entries with index greater than or equal to |draining_index| are
-  // allowed to be referenced.
-  const uint64_t draining_index =
-      header_table_.draining_index(kDrainingFraction);
-  // Blocking references are allowed if the number of blocked streams is less
-  // than the limit.
-  const bool blocking_allowed = blocking_manager_.blocking_allowed_on_stream(
-      stream_id, maximum_blocked_streams_);
-
-  // Track events for histograms.
-  bool dynamic_table_insertion_blocked = false;
-  bool blocked_stream_limit_exhausted = false;
-
-  for (const auto& header : ValueSplittingHeaderList(&header_list)) {
-    // These strings are owned by |header_list|.
-    absl::string_view name = header.first;
-    absl::string_view value = header.second;
-
-    bool is_static;
-    uint64_t index;
-
-    auto match_type =
-        header_table_.FindHeaderField(name, value, &is_static, &index);
-
-    switch (match_type) {
-      case QpackEncoderHeaderTable::MatchType::kNameAndValue:
-        if (is_static) {
-          // Refer to entry directly.
-          representations.push_back(
-              EncodeIndexedHeaderField(is_static, index, referred_indices));
-
-          break;
-        }
-
-        if (index >= draining_index) {
-          // If allowed, refer to entry directly.
-          if (!blocking_allowed && index >= known_received_count) {
-            blocked_stream_limit_exhausted = true;
-          } else {
-            representations.push_back(
-                EncodeIndexedHeaderField(is_static, index, referred_indices));
-            smallest_blocking_index = std::min(smallest_blocking_index, index);
-            header_table_.set_dynamic_table_entry_referenced();
-
-            break;
-          }
-        } else {
-          // Entry is draining, needs to be duplicated.
-          if (!blocking_allowed) {
-            blocked_stream_limit_exhausted = true;
-          } else if (QpackEntry::Size(name, value) >
-                     header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
-                         std::min(smallest_blocking_index, index))) {
-            dynamic_table_insertion_blocked = true;
-          } else {
-            if (can_write_to_encoder_stream) {
-              // If allowed, duplicate entry and refer to it.
-              encoder_stream_sender_.SendDuplicate(
-                  QpackAbsoluteIndexToEncoderStreamRelativeIndex(
-                      index, header_table_.inserted_entry_count()));
-              uint64_t new_index = header_table_.InsertEntry(name, value);
-              representations.push_back(EncodeIndexedHeaderField(
-                  is_static, new_index, referred_indices));
-              smallest_blocking_index =
-                  std::min(smallest_blocking_index, index);
-              header_table_.set_dynamic_table_entry_referenced();
-
-              break;
-            }
-          }
-        }
-
-        // Encode entry as string literals.
-        // TODO(b/112770235): Use already acknowledged entry with lower index if
-        // exists.
-        // TODO(b/112770235): Use static entry name with literal value if
-        // dynamic entry exists but cannot be used.
-        representations.push_back(EncodeLiteralHeaderField(name, value));
-
-        break;
-
-      case QpackEncoderHeaderTable::MatchType::kName:
-        if (is_static) {
-          if (blocking_allowed &&
-              QpackEntry::Size(name, value) <=
-                  header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
-                      smallest_blocking_index)) {
-            // If allowed, insert entry into dynamic table and refer to it.
-            if (can_write_to_encoder_stream) {
-              encoder_stream_sender_.SendInsertWithNameReference(is_static,
-                                                                 index, value);
-              uint64_t new_index = header_table_.InsertEntry(name, value);
-              representations.push_back(EncodeIndexedHeaderField(
-                  /* is_static = */ false, new_index, referred_indices));
-              smallest_blocking_index =
-                  std::min<uint64_t>(smallest_blocking_index, new_index);
-
-              break;
-            }
-          }
-
-          // Emit literal field with name reference.
-          representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
-              is_static, index, value, referred_indices));
-
-          break;
-        }
-
-        if (!blocking_allowed) {
-          blocked_stream_limit_exhausted = true;
-        } else if (QpackEntry::Size(name, value) >
-                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
-                       std::min(smallest_blocking_index, index))) {
-          dynamic_table_insertion_blocked = true;
-        } else {
-          // If allowed, insert entry with name reference and refer to it.
-          if (can_write_to_encoder_stream) {
-            encoder_stream_sender_.SendInsertWithNameReference(
-                is_static,
-                QpackAbsoluteIndexToEncoderStreamRelativeIndex(
-                    index, header_table_.inserted_entry_count()),
-                value);
-            uint64_t new_index = header_table_.InsertEntry(name, value);
-            representations.push_back(EncodeIndexedHeaderField(
-                is_static, new_index, referred_indices));
-            smallest_blocking_index = std::min(smallest_blocking_index, index);
-            header_table_.set_dynamic_table_entry_referenced();
-
-            break;
-          }
-        }
-
-        if ((blocking_allowed || index < known_received_count) &&
-            index >= draining_index) {
-          // If allowed, refer to entry name directly, with literal value.
-          representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
-              is_static, index, value, referred_indices));
-          smallest_blocking_index = std::min(smallest_blocking_index, index);
-          header_table_.set_dynamic_table_entry_referenced();
-
-          break;
-        }
-
-        // Encode entry as string literals.
-        // TODO(b/112770235): Use already acknowledged entry with lower index if
-        // exists.
-        // TODO(b/112770235): Use static entry name with literal value if
-        // dynamic entry exists but cannot be used.
-        representations.push_back(EncodeLiteralHeaderField(name, value));
-
-        break;
-
-      case QpackEncoderHeaderTable::MatchType::kNoMatch:
-        // If allowed, insert entry and refer to it.
-        if (!blocking_allowed) {
-          blocked_stream_limit_exhausted = true;
-        } else if (QpackEntry::Size(name, value) >
-                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
-                       smallest_blocking_index)) {
-          dynamic_table_insertion_blocked = true;
-        } else {
-          if (can_write_to_encoder_stream) {
-            encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
-            uint64_t new_index = header_table_.InsertEntry(name, value);
-            representations.push_back(EncodeIndexedHeaderField(
-                /* is_static = */ false, new_index, referred_indices));
-            smallest_blocking_index =
-                std::min<uint64_t>(smallest_blocking_index, new_index);
-
-            break;
-          }
-        }
-
-        // Encode entry as string literals.
-        // TODO(b/112770235): Consider also adding to dynamic table to improve
-        // compression ratio for subsequent header blocks with peers that do not
-        // allow any blocked streams.
-        representations.push_back(EncodeLiteralHeaderField(name, value));
-
-        break;
-    }
-  }
-
-  const QuicByteCount encoder_stream_buffered_byte_count =
-      encoder_stream_sender_.BufferedByteCount();
-  QUICHE_DCHECK_GE(encoder_stream_buffered_byte_count,
-                   initial_encoder_stream_buffered_byte_count);
-
-  if (encoder_stream_sent_byte_count) {
-    *encoder_stream_sent_byte_count =
-        encoder_stream_buffered_byte_count -
-        initial_encoder_stream_buffered_byte_count;
-  }
-  if (can_write_to_encoder_stream) {
-    encoder_stream_sender_.Flush();
-  } else {
-    QUICHE_DCHECK_EQ(encoder_stream_buffered_byte_count,
-                     initial_encoder_stream_buffered_byte_count);
-  }
-
-  ++header_list_count_;
-
-  if (dynamic_table_insertion_blocked) {
-    QUIC_HISTOGRAM_COUNTS(
-        "QuicSession.Qpack.HeaderListCountWhenInsertionBlocked",
-        header_list_count_, /* min = */ 1, /* max = */ 1000,
-        /* bucket_count = */ 50,
-        "The ordinality of a header list within a connection during the "
-        "encoding of which at least one dynamic table insertion was "
-        "blocked.");
-  } else {
-    QUIC_HISTOGRAM_COUNTS(
-        "QuicSession.Qpack.HeaderListCountWhenInsertionNotBlocked",
-        header_list_count_, /* min = */ 1, /* max = */ 1000,
-        /* bucket_count = */ 50,
-        "The ordinality of a header list within a connection during the "
-        "encoding of which no dynamic table insertion was blocked.");
-  }
-
-  if (blocked_stream_limit_exhausted) {
-    QUIC_HISTOGRAM_COUNTS(
-        "QuicSession.Qpack.HeaderListCountWhenBlockedStreamLimited",
-        header_list_count_, /* min = */ 1, /* max = */ 1000,
-        /* bucket_count = */ 50,
-        "The ordinality of a header list within a connection during the "
-        "encoding of which unacknowledged dynamic table entries could not be "
-        "referenced due to the limit on the number of blocked streams.");
-  } else {
-    QUIC_HISTOGRAM_COUNTS(
-        "QuicSession.Qpack.HeaderListCountWhenNotBlockedStreamLimited",
-        header_list_count_, /* min = */ 1, /* max = */ 1000,
-        /* bucket_count = */ 50,
-        "The ordinality of a header list within a connection during the "
-        "encoding of which the limit on the number of blocked streams did "
-        "not "
-        "prevent referencing unacknowledged dynamic table entries.");
-  }
-
-  return representations;
-}
-
-std::string QpackEncoder::SecondPassEncode(
-    QpackEncoder::Representations representations,
-    uint64_t required_insert_count) const {
-  QpackInstructionEncoder instruction_encoder;
-  std::string encoded_headers;
-
-  // Header block prefix.
-  instruction_encoder.Encode(
-      Representation::Prefix(QpackEncodeRequiredInsertCount(
-          required_insert_count, header_table_.max_entries())),
-      &encoded_headers);
-
-  const uint64_t base = required_insert_count;
-
-  for (auto& representation : representations) {
-    // Dynamic table references must be transformed from absolute to relative
-    // indices.
-    if ((representation.instruction() == QpackIndexedHeaderFieldInstruction() ||
-         representation.instruction() ==
-             QpackLiteralHeaderFieldNameReferenceInstruction()) &&
-        !representation.s_bit()) {
-      representation.set_varint(QpackAbsoluteIndexToRequestStreamRelativeIndex(
-          representation.varint(), base));
-    }
-    instruction_encoder.Encode(representation, &encoded_headers);
-  }
-
-  return encoded_headers;
-}
-
-std::string QpackEncoder::EncodeHeaderList(
-    QuicStreamId stream_id,
-    const spdy::Http2HeaderBlock& header_list,
-    QuicByteCount* encoder_stream_sent_byte_count) {
-  // Keep track of all dynamic table indices that this header block refers to so
-  // that it can be passed to QpackBlockingManager.
-  QpackBlockingManager::IndexSet referred_indices;
-
-  // First pass: encode into |representations|.
-  Representations representations =
-      FirstPassEncode(stream_id, header_list, &referred_indices,
-                      encoder_stream_sent_byte_count);
-
-  const uint64_t required_insert_count =
-      referred_indices.empty()
-          ? 0
-          : QpackBlockingManager::RequiredInsertCount(referred_indices);
-  if (!referred_indices.empty()) {
-    blocking_manager_.OnHeaderBlockSent(stream_id, std::move(referred_indices));
-  }
-
-  // Second pass.
-  return SecondPassEncode(std::move(representations), required_insert_count);
-}
-
-bool QpackEncoder::SetMaximumDynamicTableCapacity(
-    uint64_t maximum_dynamic_table_capacity) {
-  return header_table_.SetMaximumDynamicTableCapacity(
-      maximum_dynamic_table_capacity);
-}
-
-void QpackEncoder::SetDynamicTableCapacity(uint64_t dynamic_table_capacity) {
-  encoder_stream_sender_.SendSetDynamicTableCapacity(dynamic_table_capacity);
-  // Do not flush encoder stream.  This write can safely be delayed until more
-  // instructions are written.
-
-  bool success = header_table_.SetDynamicTableCapacity(dynamic_table_capacity);
-  QUICHE_DCHECK(success);
-}
-
-bool QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
-  if (maximum_blocked_streams < maximum_blocked_streams_) {
-    return false;
-  }
-  maximum_blocked_streams_ = maximum_blocked_streams;
-  return true;
-}
-
-void QpackEncoder::OnInsertCountIncrement(uint64_t increment) {
-  if (increment == 0) {
-    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
-                    "Invalid increment value 0.");
-    return;
-  }
-
-  if (!blocking_manager_.OnInsertCountIncrement(increment)) {
-    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
-                    "Insert Count Increment instruction causes overflow.");
-  }
-
-  if (blocking_manager_.known_received_count() >
-      header_table_.inserted_entry_count()) {
-    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
-                    absl::StrCat("Increment value ", increment,
-                                 " raises known received count to ",
-                                 blocking_manager_.known_received_count(),
-                                 " exceeding inserted entry count ",
-                                 header_table_.inserted_entry_count()));
-  }
-}
-
-void QpackEncoder::OnHeaderAcknowledgement(QuicStreamId stream_id) {
-  if (!blocking_manager_.OnHeaderAcknowledgement(stream_id)) {
-    OnErrorDetected(
-        QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
-        absl::StrCat("Header Acknowledgement received for stream ", stream_id,
-                     " with no outstanding header blocks."));
-  }
-}
-
-void QpackEncoder::OnStreamCancellation(QuicStreamId stream_id) {
-  blocking_manager_.OnStreamCancellation(stream_id);
-}
-
-void QpackEncoder::OnErrorDetected(QuicErrorCode error_code,
-                                   absl::string_view error_message) {
-  decoder_stream_error_delegate_->OnDecoderStreamError(error_code,
-                                                       error_message);
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder.h b/quic/core/qpack/qpack_encoder.h
deleted file mode 100644
index c3d77fe..0000000
--- a/quic/core/qpack/qpack_encoder.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_blocking_manager.h"
-#include "quic/core/qpack/qpack_decoder_stream_receiver.h"
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-namespace test {
-
-class QpackEncoderPeer;
-
-}  // namespace test
-
-// QPACK encoder class.  Exactly one instance should exist per QUIC connection.
-class QUIC_EXPORT_PRIVATE QpackEncoder
-    : public QpackDecoderStreamReceiver::Delegate {
- public:
-  // Interface for receiving notification that an error has occurred on the
-  // decoder stream.  This MUST be treated as a connection error of type
-  // HTTP_QPACK_DECODER_STREAM_ERROR.
-  class QUIC_EXPORT_PRIVATE DecoderStreamErrorDelegate {
-   public:
-    virtual ~DecoderStreamErrorDelegate() {}
-
-    virtual void OnDecoderStreamError(QuicErrorCode error_code,
-                                      absl::string_view error_message) = 0;
-  };
-
-  QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate);
-  ~QpackEncoder() override;
-
-  // Encode a header list.  If |encoder_stream_sent_byte_count| is not null,
-  // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent
-  // on the encoder stream to insert dynamic table entries.
-  std::string EncodeHeaderList(QuicStreamId stream_id,
-                               const spdy::Http2HeaderBlock& header_list,
-                               QuicByteCount* encoder_stream_sent_byte_count);
-
-  // Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|,
-  // measured in bytes.  Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
-  // received.  Encoder needs to know this value so that it can calculate
-  // MaxEntries, used as a modulus to encode Required Insert Count.
-  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
-  // or if it doesn't change current value. The setting is not changed when
-  // returning false.
-  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
-
-  // Set dynamic table capacity to |dynamic_table_capacity|.
-  // |dynamic_table_capacity| must not exceed maximum dynamic table capacity.
-  // Also sends Set Dynamic Table Capacity instruction on encoder stream.
-  void SetDynamicTableCapacity(uint64_t dynamic_table_capacity);
-
-  // Set maximum number of blocked streams.
-  // Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
-  // Returns true if |maximum_blocked_streams| doesn't decrease current value.
-  // The setting is not changed when returning false.
-  bool SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
-
-  // QpackDecoderStreamReceiver::Delegate implementation
-  void OnInsertCountIncrement(uint64_t increment) override;
-  void OnHeaderAcknowledgement(QuicStreamId stream_id) override;
-  void OnStreamCancellation(QuicStreamId stream_id) override;
-  void OnErrorDetected(QuicErrorCode error_code,
-                       absl::string_view error_message) override;
-
-  // delegate must be set if dynamic table capacity is not zero.
-  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
-    encoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
-  }
-
-  QpackStreamReceiver* decoder_stream_receiver() {
-    return &decoder_stream_receiver_;
-  }
-
-  // True if any dynamic table entries have been referenced from a header block.
-  bool dynamic_table_entry_referenced() const {
-    return header_table_.dynamic_table_entry_referenced();
-  }
-
-  uint64_t maximum_blocked_streams() const { return maximum_blocked_streams_; }
-
-  uint64_t MaximumDynamicTableCapacity() const {
-    return header_table_.maximum_dynamic_table_capacity();
-  }
-
- private:
-  friend class test::QpackEncoderPeer;
-
-  using Representation = QpackInstructionWithValues;
-  using Representations = std::vector<Representation>;
-
-  // Generate indexed header field representation
-  // and optionally update |*referred_indices|.
-  static Representation EncodeIndexedHeaderField(
-      bool is_static,
-      uint64_t index,
-      QpackBlockingManager::IndexSet* referred_indices);
-
-  // Generate literal header field with name reference representation
-  // and optionally update |*referred_indices|.
-  static Representation EncodeLiteralHeaderFieldWithNameReference(
-      bool is_static,
-      uint64_t index,
-      absl::string_view value,
-      QpackBlockingManager::IndexSet* referred_indices);
-
-  // Generate literal header field representation.
-  static Representation EncodeLiteralHeaderField(absl::string_view name,
-                                                 absl::string_view value);
-
-  // Performs first pass of two-pass encoding: represent each header field in
-  // |*header_list| as a reference to an existing entry, the name of an existing
-  // entry with a literal value, or a literal name and value pair.  Sends
-  // necessary instructions on the encoder stream coalesced in a single write.
-  // Records absolute indices of referred dynamic table entries in
-  // |*referred_indices|.  If |encoder_stream_sent_byte_count| is not null, then
-  // sets |*encoder_stream_sent_byte_count| to the number of bytes sent on the
-  // encoder stream to insert dynamic table entries.  Returns list of header
-  // field representations, with all dynamic table entries referred to with
-  // absolute indices.  Returned representation objects may have
-  // absl::string_views pointing to strings owned by |*header_list|.
-  Representations FirstPassEncode(
-      QuicStreamId stream_id,
-      const spdy::Http2HeaderBlock& header_list,
-      QpackBlockingManager::IndexSet* referred_indices,
-      QuicByteCount* encoder_stream_sent_byte_count);
-
-  // Performs second pass of two-pass encoding: serializes representations
-  // generated in first pass, transforming absolute indices of dynamic table
-  // entries to relative indices.
-  std::string SecondPassEncode(Representations representations,
-                               uint64_t required_insert_count) const;
-
-  DecoderStreamErrorDelegate* const decoder_stream_error_delegate_;
-  QpackDecoderStreamReceiver decoder_stream_receiver_;
-  QpackEncoderStreamSender encoder_stream_sender_;
-  QpackEncoderHeaderTable header_table_;
-  uint64_t maximum_blocked_streams_;
-  QpackBlockingManager blocking_manager_;
-  int header_list_count_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
diff --git a/quic/core/qpack/qpack_encoder_stream_receiver.cc b/quic/core/qpack/qpack_encoder_stream_receiver.cc
deleted file mode 100644
index bf71faf..0000000
--- a/quic/core/qpack/qpack_encoder_stream_receiver.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-
-#include "absl/strings/string_view.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate)
-    : instruction_decoder_(QpackEncoderStreamLanguage(), this),
-      delegate_(delegate),
-      error_detected_(false) {
-  QUICHE_DCHECK(delegate_);
-}
-
-void QpackEncoderStreamReceiver::Decode(absl::string_view data) {
-  if (data.empty() || error_detected_) {
-    return;
-  }
-
-  instruction_decoder_.Decode(data);
-}
-
-bool QpackEncoderStreamReceiver::OnInstructionDecoded(
-    const QpackInstruction* instruction) {
-  if (instruction == InsertWithNameReferenceInstruction()) {
-    delegate_->OnInsertWithNameReference(instruction_decoder_.s_bit(),
-                                         instruction_decoder_.varint(),
-                                         instruction_decoder_.value());
-    return true;
-  }
-
-  if (instruction == InsertWithoutNameReferenceInstruction()) {
-    delegate_->OnInsertWithoutNameReference(instruction_decoder_.name(),
-                                            instruction_decoder_.value());
-    return true;
-  }
-
-  if (instruction == DuplicateInstruction()) {
-    delegate_->OnDuplicate(instruction_decoder_.varint());
-    return true;
-  }
-
-  QUICHE_DCHECK_EQ(instruction, SetDynamicTableCapacityInstruction());
-  delegate_->OnSetDynamicTableCapacity(instruction_decoder_.varint());
-  return true;
-}
-
-void QpackEncoderStreamReceiver::OnInstructionDecodingError(
-    QpackInstructionDecoder::ErrorCode error_code,
-    absl::string_view error_message) {
-  QUICHE_DCHECK(!error_detected_);
-
-  error_detected_ = true;
-
-  QuicErrorCode quic_error_code;
-  switch (error_code) {
-    case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE:
-      quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE;
-      break;
-    case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG:
-      quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG;
-      break;
-    case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR:
-      quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR;
-      break;
-    default:
-      quic_error_code = QUIC_INTERNAL_ERROR;
-  }
-
-  delegate_->OnErrorDetected(quic_error_code, error_message);
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder_stream_receiver.h b/quic/core/qpack/qpack_encoder_stream_receiver.h
deleted file mode 100644
index b3e43cf..0000000
--- a/quic/core/qpack/qpack_encoder_stream_receiver.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-#include "quic/core/qpack/qpack_stream_receiver.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class decodes data received on the encoder stream.
-class QUIC_EXPORT_PRIVATE QpackEncoderStreamReceiver
-    : public QpackInstructionDecoder::Delegate,
-      public QpackStreamReceiver {
- public:
-  // An interface for handling instructions decoded from the encoder stream, see
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() = default;
-
-    // 5.2.1. Insert With Name Reference
-    virtual void OnInsertWithNameReference(bool is_static,
-                                           uint64_t name_index,
-                                           absl::string_view value) = 0;
-    // 5.2.2. Insert Without Name Reference
-    virtual void OnInsertWithoutNameReference(absl::string_view name,
-                                              absl::string_view value) = 0;
-    // 5.2.3. Duplicate
-    virtual void OnDuplicate(uint64_t index) = 0;
-    // 5.2.4. Set Dynamic Table Capacity
-    virtual void OnSetDynamicTableCapacity(uint64_t capacity) = 0;
-    // Decoding error
-    virtual void OnErrorDetected(QuicErrorCode error_code,
-                                 absl::string_view error_message) = 0;
-  };
-
-  explicit QpackEncoderStreamReceiver(Delegate* delegate);
-  QpackEncoderStreamReceiver() = delete;
-  QpackEncoderStreamReceiver(const QpackEncoderStreamReceiver&) = delete;
-  QpackEncoderStreamReceiver& operator=(const QpackEncoderStreamReceiver&) =
-      delete;
-  ~QpackEncoderStreamReceiver() override = default;
-
-  // Implements QpackStreamReceiver::Decode().
-  // Decode data and call appropriate Delegate method after each decoded
-  // instruction.  Once an error occurs, Delegate::OnErrorDetected() is called,
-  // and all further data is ignored.
-  void Decode(absl::string_view data) override;
-
-  // QpackInstructionDecoder::Delegate implementation.
-  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
-  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
-                                  absl::string_view error_message) override;
-
- private:
-  QpackInstructionDecoder instruction_decoder_;
-  Delegate* const delegate_;
-
-  // True if a decoding error has been detected.
-  bool error_detected_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
diff --git a/quic/core/qpack/qpack_encoder_stream_receiver_test.cc b/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
deleted file mode 100644
index 2fa440b..0000000
--- a/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-using testing::Eq;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QpackEncoderStreamReceiver::Delegate {
- public:
-  ~MockDelegate() override = default;
-
-  MOCK_METHOD(void,
-              OnInsertWithNameReference,
-              (bool is_static, uint64_t name_index, absl::string_view value),
-              (override));
-  MOCK_METHOD(void,
-              OnInsertWithoutNameReference,
-              (absl::string_view name, absl::string_view value),
-              (override));
-  MOCK_METHOD(void, OnDuplicate, (uint64_t index), (override));
-  MOCK_METHOD(void, OnSetDynamicTableCapacity, (uint64_t capacity), (override));
-  MOCK_METHOD(void,
-              OnErrorDetected,
-              (QuicErrorCode error_code, absl::string_view error_message),
-              (override));
-};
-
-class QpackEncoderStreamReceiverTest : public QuicTest {
- protected:
-  QpackEncoderStreamReceiverTest() : stream_(&delegate_) {}
-  ~QpackEncoderStreamReceiverTest() override = default;
-
-  void Decode(absl::string_view data) { stream_.Decode(data); }
-  StrictMock<MockDelegate>* delegate() { return &delegate_; }
-
- private:
-  QpackEncoderStreamReceiver stream_;
-  StrictMock<MockDelegate> delegate_;
-};
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) {
-  // Static, index fits in prefix, empty value.
-  EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 5, Eq("")));
-  // Static, index fits in prefix, Huffman encoded value.
-  EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 2, Eq("foo")));
-  // Not static, index does not fit in prefix, not Huffman encoded value.
-  EXPECT_CALL(*delegate(), OnInsertWithNameReference(false, 137, Eq("bar")));
-  // Value length does not fit in prefix.
-  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  EXPECT_CALL(*delegate(),
-              OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z'))));
-
-  Decode(absl::HexStringToBytes(
-      "c500"
-      "c28294e7"
-      "bf4a03626172"
-      "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceIndexTooLarge) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-
-  Decode(absl::HexStringToBytes("bfffffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-
-  Decode(absl::HexStringToBytes("c57fffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) {
-  // Empty name and value.
-  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq(""), Eq("")));
-  // Huffman encoded short strings.
-  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("bar"), Eq("bar")));
-  // Not Huffman encoded short strings.
-  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("foo"), Eq("foo")));
-  // Not Huffman encoded long strings; length does not fit on prefix.
-  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  EXPECT_CALL(*delegate(),
-              OnInsertWithoutNameReference(Eq(std::string(31, 'Z')),
-                                           Eq(std::string(127, 'Z'))));
-
-  Decode(absl::HexStringToBytes(
-      "4000"
-      "4362617203626172"
-      "6294e78294e7"
-      "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f005a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
-}
-
-// Name Length value is too large for varint decoder to decode.
-TEST_F(QpackEncoderStreamReceiverTest,
-       InsertWithoutNameReferenceNameTooLongForVarintDecoder) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-
-  Decode(absl::HexStringToBytes("5fffffffffffffffffffff"));
-}
-
-// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_F(QpackEncoderStreamReceiverTest,
-       InsertWithoutNameReferenceNameExceedsLimit) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
-                              Eq("String literal too long.")));
-
-  Decode(absl::HexStringToBytes("5fffff7f"));
-}
-
-// Value Length value is too large for varint decoder to decode.
-TEST_F(QpackEncoderStreamReceiverTest,
-       InsertWithoutNameReferenceValueTooLongForVarintDecoder) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-
-  Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff"));
-}
-
-// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
-TEST_F(QpackEncoderStreamReceiverTest,
-       InsertWithoutNameReferenceValueExceedsLimit) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
-                              Eq("String literal too long.")));
-
-  Decode(absl::HexStringToBytes("436261727fffff7f"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, Duplicate) {
-  // Small index fits in prefix.
-  EXPECT_CALL(*delegate(), OnDuplicate(17));
-  // Large index requires two extension bytes.
-  EXPECT_CALL(*delegate(), OnDuplicate(500));
-
-  Decode(absl::HexStringToBytes("111fd503"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-
-  Decode(absl::HexStringToBytes("1fffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) {
-  // Small capacity fits in prefix.
-  EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(17));
-  // Large capacity requires two extension bytes.
-  EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500));
-
-  Decode(absl::HexStringToBytes("313fd503"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
-                              Eq("Encoded integer too large.")));
-
-  Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) {
-  EXPECT_CALL(*delegate(),
-              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR,
-                              Eq("Error in Huffman-encoded string.")));
-
-  Decode(absl::HexStringToBytes("c281ff"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder_stream_sender.cc b/quic/core/qpack/qpack_encoder_stream_sender.cc
deleted file mode 100644
index 8b6f887..0000000
--- a/quic/core/qpack/qpack_encoder_stream_sender.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-
-#include <cstddef>
-#include <limits>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// If QUIC stream bufferes more that this number of bytes,
-// CanWrite() will return false.
-constexpr uint64_t kMaxBytesBufferedByStream = 64 * 1024;
-
-}  // anonymous namespace
-
-QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
-
-void QpackEncoderStreamSender::SendInsertWithNameReference(
-    bool is_static,
-    uint64_t name_index,
-    absl::string_view value) {
-  instruction_encoder_.Encode(
-      QpackInstructionWithValues::InsertWithNameReference(is_static, name_index,
-                                                          value),
-      &buffer_);
-}
-
-void QpackEncoderStreamSender::SendInsertWithoutNameReference(
-    absl::string_view name,
-    absl::string_view value) {
-  instruction_encoder_.Encode(
-      QpackInstructionWithValues::InsertWithoutNameReference(name, value),
-      &buffer_);
-}
-
-void QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
-  instruction_encoder_.Encode(QpackInstructionWithValues::Duplicate(index),
-                              &buffer_);
-}
-
-void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
-  instruction_encoder_.Encode(
-      QpackInstructionWithValues::SetDynamicTableCapacity(capacity), &buffer_);
-}
-
-bool QpackEncoderStreamSender::CanWrite() const {
-  return delegate_ && delegate_->NumBytesBuffered() + buffer_.size() <=
-                          kMaxBytesBufferedByStream;
-}
-
-void QpackEncoderStreamSender::Flush() {
-  if (buffer_.empty()) {
-    return;
-  }
-
-  delegate_->WriteStreamData(buffer_);
-  buffer_.clear();
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder_stream_sender.h b/quic/core/qpack/qpack_encoder_stream_sender.h
deleted file mode 100644
index d8c6430..0000000
--- a/quic/core/qpack/qpack_encoder_stream_sender.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This class serializes instructions for transmission on the encoder stream.
-// Serialized instructions are buffered until Flush() is called.
-class QUIC_EXPORT_PRIVATE QpackEncoderStreamSender {
- public:
-  QpackEncoderStreamSender();
-  QpackEncoderStreamSender(const QpackEncoderStreamSender&) = delete;
-  QpackEncoderStreamSender& operator=(const QpackEncoderStreamSender&) = delete;
-
-  // Methods for serializing and buffering instructions, see
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
-
-  // 5.2.1. Insert With Name Reference
-  void SendInsertWithNameReference(bool is_static,
-                                   uint64_t name_index,
-                                   absl::string_view value);
-  // 5.2.2. Insert Without Name Reference
-  void SendInsertWithoutNameReference(absl::string_view name,
-                                      absl::string_view value);
-  // 5.2.3. Duplicate
-  void SendDuplicate(uint64_t index);
-  // 5.2.4. Set Dynamic Table Capacity
-  void SendSetDynamicTableCapacity(uint64_t capacity);
-
-  // Returns number of bytes buffered by this object.
-  // There is no limit on how much data this object is willing to buffer.
-  QuicByteCount BufferedByteCount() const { return buffer_.size(); }
-
-  // Returns whether writing to the encoder stream is allowed.  Writing is
-  // disallowed if the amount of data buffered by the underlying stream exceeds
-  // a hardcoded limit, in order to limit memory consumption in case the encoder
-  // stream is blocked.  CanWrite() returning true does not mean that the
-  // encoder stream is not blocked, it just means the blocked data does not
-  // exceed the threshold.
-  bool CanWrite() const;
-
-  // Writes all buffered instructions on the encoder stream.
-  void Flush();
-
-  // delegate must be set if dynamic table capacity is not zero.
-  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
-    delegate_ = delegate;
-  }
-
- private:
-  QpackStreamSenderDelegate* delegate_;
-  QpackInstructionEncoder instruction_encoder_;
-  std::string buffer_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
diff --git a/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
deleted file mode 100644
index 98e3e23..0000000
--- a/quic/core/qpack/qpack_encoder_stream_sender_test.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder_stream_sender.h"
-
-#include "absl/strings/escaping.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::Eq;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QpackEncoderStreamSenderTest : public QuicTest {
- protected:
-  QpackEncoderStreamSenderTest() {
-    stream_.set_qpack_stream_sender_delegate(&delegate_);
-  }
-  ~QpackEncoderStreamSenderTest() override = default;
-
-  StrictMock<MockQpackStreamSenderDelegate> delegate_;
-  QpackEncoderStreamSender stream_;
-};
-
-TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) {
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-
-  // Static, index fits in prefix, empty value.
-  std::string expected_encoded_data = absl::HexStringToBytes("c500");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithNameReference(true, 5, "");
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Static, index fits in prefix, Huffman encoded value.
-  expected_encoded_data = absl::HexStringToBytes("c28294e7");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithNameReference(true, 2, "foo");
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Not static, index does not fit in prefix, not Huffman encoded value.
-  expected_encoded_data = absl::HexStringToBytes("bf4a03626172");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithNameReference(false, 137, "bar");
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Value length does not fit in prefix.
-  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  expected_encoded_data = absl::HexStringToBytes(
-      "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-}
-
-TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-
-  // Empty name and value.
-  std::string expected_encoded_data = absl::HexStringToBytes("4000");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithoutNameReference("", "");
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Huffman encoded short strings.
-  expected_encoded_data = absl::HexStringToBytes("6294e78294e7");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithoutNameReference("foo", "foo");
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Not Huffman encoded short strings.
-  expected_encoded_data = absl::HexStringToBytes("4362617203626172");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithoutNameReference("bar", "bar");
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Not Huffman encoded long strings; length does not fit on prefix.
-  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  expected_encoded_data = absl::HexStringToBytes(
-      "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
-      "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
-                                         std::string(127, 'Z'));
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-}
-
-TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-
-  // Small index fits in prefix.
-  std::string expected_encoded_data = absl::HexStringToBytes("11");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendDuplicate(17);
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-
-  // Large index requires two extension bytes.
-  expected_encoded_data = absl::HexStringToBytes("1fd503");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendDuplicate(500);
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-}
-
-TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-
-  // Small capacity fits in prefix.
-  std::string expected_encoded_data = absl::HexStringToBytes("31");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendSetDynamicTableCapacity(17);
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-
-  // Large capacity requires two extension bytes.
-  expected_encoded_data = absl::HexStringToBytes("3fd503");
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  stream_.SendSetDynamicTableCapacity(500);
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-}
-
-// No writes should happen until Flush is called.
-TEST_F(QpackEncoderStreamSenderTest, Coalesce) {
-  // Insert entry with static name reference, empty value.
-  stream_.SendInsertWithNameReference(true, 5, "");
-
-  // Insert entry with static name reference, Huffman encoded value.
-  stream_.SendInsertWithNameReference(true, 2, "foo");
-
-  // Insert literal entry, Huffman encoded short strings.
-  stream_.SendInsertWithoutNameReference("foo", "foo");
-
-  // Duplicate entry.
-  stream_.SendDuplicate(17);
-
-  std::string expected_encoded_data = absl::HexStringToBytes(
-      "c500"          // Insert entry with static name reference.
-      "c28294e7"      // Insert entry with static name reference.
-      "6294e78294e7"  // Insert literal entry.
-      "11");          // Duplicate entry.
-
-  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
-  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
-  stream_.Flush();
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-}
-
-// No writes should happen if QpackEncoderStreamSender::Flush() is called
-// when the buffer is empty.
-TEST_F(QpackEncoderStreamSenderTest, FlushEmpty) {
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-  stream_.Flush();
-  EXPECT_EQ(0u, stream_.BufferedByteCount());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_encoder_test.cc b/quic/core/qpack/qpack_encoder_test.cc
deleted file mode 100644
index 7f75f97..0000000
--- a/quic/core/qpack/qpack_encoder_test.cc
+++ /dev/null
@@ -1,623 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_encoder.h"
-
-#include <limits>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// A number larger than kMaxBytesBufferedByStream in
-// qpack_encoder_stream_sender.cc.  Returning this value from NumBytesBuffered()
-// will instruct QpackEncoder not to generate any instructions for the encoder
-// stream.
-constexpr uint64_t kTooManyBytesBuffered = 1024 * 1024;
-
-class QpackEncoderTest : public QuicTest {
- protected:
-  QpackEncoderTest()
-      : encoder_(&decoder_stream_error_delegate_),
-        encoder_stream_sent_byte_count_(0) {
-    encoder_.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
-    encoder_.SetMaximumBlockedStreams(1);
-  }
-
-  ~QpackEncoderTest() override = default;
-
-  std::string Encode(const spdy::Http2HeaderBlock& header_list) {
-    return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list,
-                                     &encoder_stream_sent_byte_count_);
-  }
-
-  StrictMock<MockDecoderStreamErrorDelegate> decoder_stream_error_delegate_;
-  StrictMock<MockQpackStreamSenderDelegate> encoder_stream_sender_delegate_;
-  QpackEncoder encoder_;
-  QuicByteCount encoder_stream_sent_byte_count_;
-};
-
-TEST_F(QpackEncoderTest, Empty) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(absl::HexStringToBytes("0000"), output);
-}
-
-TEST_F(QpackEncoderTest, EmptyName) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  header_list[""] = "foo";
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(absl::HexStringToBytes("0000208294e7"), output);
-}
-
-TEST_F(QpackEncoderTest, EmptyValue) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "";
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(absl::HexStringToBytes("00002a94e700"), output);
-}
-
-TEST_F(QpackEncoderTest, EmptyNameAndValue) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  header_list[""] = "";
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(absl::HexStringToBytes("00002000"), output);
-}
-
-TEST_F(QpackEncoderTest, Simple) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "bar";
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(absl::HexStringToBytes("00002a94e703626172"), output);
-}
-
-TEST_F(QpackEncoderTest, Multiple) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "bar";
-  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  header_list["ZZZZZZZ"] = std::string(127, 'Z');
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(
-      absl::HexStringToBytes(
-          "0000"                // prefix
-          "2a94e703626172"      // foo: bar
-          "27005a5a5a5a5a5a5a"  // 7 octet long header name, the smallest number
-                                // that does not fit on a 3-bit prefix.
-          "7f005a5a5a5a5a5a5a"  // 127 octet long header value, the smallest
-          "5a5a5a5a5a5a5a5a5a"  // number that does not fit on a 7-bit prefix.
-          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
-          "5a5a5a5a5a5a5a5a5a"),
-      output);
-}
-
-TEST_F(QpackEncoderTest, StaticTable) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  {
-    spdy::Http2HeaderBlock header_list;
-    header_list[":method"] = "GET";
-    header_list["accept-encoding"] = "gzip, deflate, br";
-    header_list["location"] = "";
-
-    std::string output = Encode(header_list);
-    EXPECT_EQ(absl::HexStringToBytes("0000d1dfcc"), output);
-  }
-  {
-    spdy::Http2HeaderBlock header_list;
-    header_list[":method"] = "POST";
-    header_list["accept-encoding"] = "compress";
-    header_list["location"] = "foo";
-
-    std::string output = Encode(header_list);
-    EXPECT_EQ(absl::HexStringToBytes("0000d45f108621e9aec2a11f5c8294e7"),
-              output);
-  }
-  {
-    spdy::Http2HeaderBlock header_list;
-    header_list[":method"] = "TRACE";
-    header_list["accept-encoding"] = "";
-
-    std::string output = Encode(header_list);
-    EXPECT_EQ(absl::HexStringToBytes("00005f000554524143455f1000"), output);
-  }
-}
-
-TEST_F(QpackEncoderTest, DecoderStreamError) {
-  EXPECT_CALL(decoder_stream_error_delegate_,
-              OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
-                                   Eq("Encoded integer too large.")));
-
-  QpackEncoder encoder(&decoder_stream_error_delegate_);
-  encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
-  encoder.decoder_stream_receiver()->Decode(
-      absl::HexStringToBytes("ffffffffffffffffffffff"));
-}
-
-TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
-  std::string output = Encode(header_list);
-
-  EXPECT_EQ(absl::HexStringToBytes("0000"            // prefix
-                                   "2a94e703626172"  // foo: bar
-                                   "2a94e703626172"  // foo: bar
-                                   "2a94e70362617a"  // foo: baz
-                                   ),
-            output);
-}
-
-TEST_F(QpackEncoderTest, ZeroInsertCountIncrement) {
-  // Encoder receives insert count increment with forbidden value 0.
-  EXPECT_CALL(
-      decoder_stream_error_delegate_,
-      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
-                           Eq("Invalid increment value 0.")));
-  encoder_.OnInsertCountIncrement(0);
-}
-
-TEST_F(QpackEncoderTest, TooLargeInsertCountIncrement) {
-  // Encoder receives insert count increment with value that increases Known
-  // Received Count to a value (one) which is larger than the number of dynamic
-  // table insertions sent (zero).
-  EXPECT_CALL(
-      decoder_stream_error_delegate_,
-      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
-                           Eq("Increment value 1 raises known received count "
-                              "to 1 exceeding inserted entry count 0")));
-  encoder_.OnInsertCountIncrement(1);
-}
-
-// Regression test for https://crbug.com/1014372.
-TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) {
-  QpackEncoderHeaderTable* header_table =
-      QpackEncoderPeer::header_table(&encoder_);
-
-  // Set dynamic table capacity large enough to hold one entry.
-  header_table->SetMaximumDynamicTableCapacity(4096);
-  header_table->SetDynamicTableCapacity(4096);
-  // Insert one entry into the header table.
-  header_table->InsertEntry("foo", "bar");
-
-  // Receive Insert Count Increment instruction with increment value 1.
-  encoder_.OnInsertCountIncrement(1);
-
-  // Receive Insert Count Increment instruction that overflows the known
-  // received count.  This must result in an error instead of a crash.
-  EXPECT_CALL(decoder_stream_error_delegate_,
-              OnDecoderStreamError(
-                  QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
-                  Eq("Insert Count Increment instruction causes overflow.")));
-  encoder_.OnInsertCountIncrement(std::numeric_limits<uint64_t>::max());
-}
-
-TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) {
-  // Encoder receives header acknowledgement for a stream on which no header
-  // block with dynamic table entries was ever sent.
-  EXPECT_CALL(
-      decoder_stream_error_delegate_,
-      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
-                           Eq("Header Acknowledgement received for stream 0 "
-                              "with no outstanding header blocks.")));
-  encoder_.OnHeaderAcknowledgement(/* stream_id = */ 0);
-}
-
-TEST_F(QpackEncoderTest, DynamicTable) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  encoder_.SetMaximumBlockedStreams(1);
-  encoder_.SetMaximumDynamicTableCapacity(4096);
-  encoder_.SetDynamicTableCapacity(4096);
-
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "bar";
-  header_list.AppendValueOrAddHeader("foo",
-                                     "baz");  // name matches dynamic entry
-  header_list["cookie"] = "baz";              // name matches static entry
-
-  // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
-  // Insert three entries into the dynamic table.
-  std::string insert_entries = absl::HexStringToBytes(
-      "62"          // insert without name reference
-      "94e7"        // Huffman-encoded name "foo"
-      "03626172"    // value "bar"
-      "80"          // insert with name reference, dynamic index 0
-      "0362617a"    // value "baz"
-      "c5"          // insert with name reference, static index 5
-      "0362617a");  // value "baz"
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(
-                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
-
-  EXPECT_EQ(absl::HexStringToBytes(
-                "0400"      // prefix
-                "828180"),  // dynamic entries with relative index 0, 1, and 2
-            Encode(header_list));
-
-  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-}
-
-// There is no room in the dynamic table after inserting the first entry.
-TEST_F(QpackEncoderTest, SmallDynamicTable) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  encoder_.SetMaximumBlockedStreams(1);
-  encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
-  encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
-
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "bar";
-  header_list.AppendValueOrAddHeader("foo",
-                                     "baz");  // name matches dynamic entry
-  header_list["cookie"] = "baz";              // name matches static entry
-  header_list["bar"] = "baz";                 // no match
-
-  // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3f07");
-  // Insert one entry into the dynamic table.
-  std::string insert_entry = absl::HexStringToBytes(
-      "62"          // insert without name reference
-      "94e7"        // Huffman-encoded name "foo"
-      "03626172");  // value "bar"
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(
-                  Eq(absl::StrCat(set_dyanamic_table_capacity, insert_entry))));
-
-  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
-                                   "80"    // dynamic entry 0
-                                   "40"    // reference to dynamic entry 0 name
-                                   "0362617a"  // with literal value "baz"
-                                   "55"  // reference to static entry 5 name
-                                   "0362617a"    // with literal value "baz"
-                                   "23626172"    // literal name "bar"
-                                   "0362617a"),  // with literal value "baz"
-            Encode(header_list));
-
-  EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_);
-}
-
-TEST_F(QpackEncoderTest, BlockedStream) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  encoder_.SetMaximumBlockedStreams(1);
-  encoder_.SetMaximumDynamicTableCapacity(4096);
-  encoder_.SetDynamicTableCapacity(4096);
-
-  spdy::Http2HeaderBlock header_list1;
-  header_list1["foo"] = "bar";
-
-  // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
-  // Insert one entry into the dynamic table.
-  std::string insert_entry1 = absl::HexStringToBytes(
-      "62"          // insert without name reference
-      "94e7"        // Huffman-encoded name "foo"
-      "03626172");  // value "bar"
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(
-                  absl::StrCat(set_dyanamic_table_capacity, insert_entry1))));
-
-  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
-                                   "80"),  // dynamic entry 0
-            encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1,
-                                      &encoder_stream_sent_byte_count_));
-  EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_);
-
-  // Stream 1 is blocked.  Stream 2 is not allowed to block.
-  spdy::Http2HeaderBlock header_list2;
-  header_list2["foo"] = "bar";  // name and value match dynamic entry
-  header_list2.AppendValueOrAddHeader("foo",
-                                      "baz");  // name matches dynamic entry
-  header_list2["cookie"] = "baz";              // name matches static entry
-  header_list2["bar"] = "baz";                 // no match
-
-  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
-                                   "2a94e7"      // literal name "foo"
-                                   "03626172"    // with literal value "bar"
-                                   "2a94e7"      // literal name "foo"
-                                   "0362617a"    // with literal value "baz"
-                                   "55"          // name of static entry 5
-                                   "0362617a"    // with literal value "baz"
-                                   "23626172"    // literal name "bar"
-                                   "0362617a"),  // with literal value "baz"
-            encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2,
-                                      &encoder_stream_sent_byte_count_));
-  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
-  // Peer acknowledges receipt of one dynamic table entry.
-  // Stream 1 is no longer blocked.
-  encoder_.OnInsertCountIncrement(1);
-
-  // Insert three entries into the dynamic table.
-  std::string insert_entries = absl::HexStringToBytes(
-      "80"          // insert with name reference, dynamic index 0
-      "0362617a"    // value "baz"
-      "c5"          // insert with name reference, static index 5
-      "0362617a"    // value "baz"
-      "43"          // insert without name reference
-      "626172"      // name "bar"
-      "0362617a");  // value "baz"
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(insert_entries)));
-
-  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
-                                   "83828180"),  // dynamic entries
-            encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2,
-                                      &encoder_stream_sent_byte_count_));
-  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-
-  // Stream 3 is blocked.  Stream 4 is not allowed to block, but it can
-  // reference already acknowledged dynamic entry 0.
-  EXPECT_EQ(absl::HexStringToBytes("0200"        // prefix
-                                   "80"          // dynamic entry 0
-                                   "2a94e7"      // literal name "foo"
-                                   "0362617a"    // with literal value "baz"
-                                   "2c21cfd4c5"  // literal name "cookie"
-                                   "0362617a"    // with literal value "baz"
-                                   "23626172"    // literal name "bar"
-                                   "0362617a"),  // with literal value "baz"
-            encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2,
-                                      &encoder_stream_sent_byte_count_));
-  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
-  // Peer acknowledges receipt of two more dynamic table entries.
-  // Stream 3 is still blocked.
-  encoder_.OnInsertCountIncrement(2);
-
-  // Stream 5 is not allowed to block, but it can reference already acknowledged
-  // dynamic entries 0, 1, and 2.
-  EXPECT_EQ(absl::HexStringToBytes("0400"        // prefix
-                                   "828180"      // dynamic entries
-                                   "23626172"    // literal name "bar"
-                                   "0362617a"),  // with literal value "baz"
-            encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2,
-                                      &encoder_stream_sent_byte_count_));
-  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
-  // Peer acknowledges decoding header block on stream 3.
-  // Stream 3 is not blocked any longer.
-  encoder_.OnHeaderAcknowledgement(3);
-
-  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
-                                   "83828180"),  // dynamic entries
-            encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2,
-                                      &encoder_stream_sent_byte_count_));
-  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-}
-
-TEST_F(QpackEncoderTest, Draining) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  spdy::Http2HeaderBlock header_list1;
-  header_list1["one"] = "foo";
-  header_list1["two"] = "foo";
-  header_list1["three"] = "foo";
-  header_list1["four"] = "foo";
-  header_list1["five"] = "foo";
-  header_list1["six"] = "foo";
-  header_list1["seven"] = "foo";
-  header_list1["eight"] = "foo";
-  header_list1["nine"] = "foo";
-  header_list1["ten"] = "foo";
-
-  // Make just enough room in the dynamic table for the header list plus the
-  // first entry duplicated.  This will ensure that the oldest entries are
-  // draining.
-  uint64_t maximum_dynamic_table_capacity = 0;
-  for (const auto& header_field : header_list1) {
-    maximum_dynamic_table_capacity +=
-        QpackEntry::Size(header_field.first, header_field.second);
-  }
-  maximum_dynamic_table_capacity += QpackEntry::Size("one", "foo");
-  encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
-  encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
-
-  // Set Dynamic Table Capacity instruction and insert ten entries into the
-  // dynamic table.
-  EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(_));
-
-  EXPECT_EQ(absl::HexStringToBytes("0b00"                    // prefix
-                                   "89888786858483828180"),  // dynamic entries
-            Encode(header_list1));
-
-  // Entry is identical to oldest one, which is draining.  It will be
-  // duplicated and referenced.
-  spdy::Http2HeaderBlock header_list2;
-  header_list2["one"] = "foo";
-
-  // Duplicate oldest entry.
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(absl::HexStringToBytes("09"))));
-
-  EXPECT_EQ(absl::HexStringToBytes("0c00"  // prefix
-                                   "80"),  // most recent dynamic table entry
-            Encode(header_list2));
-
-  spdy::Http2HeaderBlock header_list3;
-  // Entry is identical to second oldest one, which is draining.  There is no
-  // room to duplicate, it will be encoded with string literals.
-  header_list3.AppendValueOrAddHeader("two", "foo");
-  // Entry has name identical to second oldest one, which is draining.  There is
-  // no room to insert new entry, it will be encoded with string literals.
-  header_list3.AppendValueOrAddHeader("two", "bar");
-
-  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
-                                   "2374776f"    // literal name "two"
-                                   "8294e7"      // literal value "foo"
-                                   "2374776f"    // literal name "two"
-                                   "03626172"),  // literal value "bar"
-            Encode(header_list3));
-}
-
-TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
-  encoder_.SetMaximumDynamicTableCapacity(1024);
-  encoder_.SetDynamicTableCapacity(30);
-
-  QpackEncoderHeaderTable* header_table =
-      QpackEncoderPeer::header_table(&encoder_);
-
-  EXPECT_EQ(1024u, header_table->maximum_dynamic_table_capacity());
-  EXPECT_EQ(30u, header_table->dynamic_table_capacity());
-}
-
-TEST_F(QpackEncoderTest, EncoderStreamWritesDisallowedThenAllowed) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(kTooManyBytesBuffered));
-  encoder_.SetMaximumBlockedStreams(1);
-  encoder_.SetMaximumDynamicTableCapacity(4096);
-  encoder_.SetDynamicTableCapacity(4096);
-
-  spdy::Http2HeaderBlock header_list1;
-  header_list1["foo"] = "bar";
-  header_list1.AppendValueOrAddHeader("foo", "baz");
-  header_list1["cookie"] = "baz";  // name matches static entry
-
-  // Encoder is not allowed to write on the encoder stream.
-  // No Set Dynamic Table Capacity or Insert instructions are sent.
-  // Headers are encoded as string literals.
-  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
-                                   "2a94e7"      // literal name "foo"
-                                   "03626172"    // with literal value "bar"
-                                   "2a94e7"      // literal name "foo"
-                                   "0362617a"    // with literal value "baz"
-                                   "55"          // name of static entry 5
-                                   "0362617a"),  // with literal value "baz"
-            Encode(header_list1));
-
-  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-
-  // If number of bytes buffered by encoder stream goes under the threshold,
-  // then QpackEncoder will resume emitting encoder stream instructions.
-  ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-
-  spdy::Http2HeaderBlock header_list2;
-  header_list2["foo"] = "bar";
-  header_list2.AppendValueOrAddHeader("foo",
-                                      "baz");  // name matches dynamic entry
-  header_list2["cookie"] = "baz";              // name matches static entry
-
-  // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
-  // Insert three entries into the dynamic table.
-  std::string insert_entries = absl::HexStringToBytes(
-      "62"          // insert without name reference
-      "94e7"        // Huffman-encoded name "foo"
-      "03626172"    // value "bar"
-      "80"          // insert with name reference, dynamic index 0
-      "0362617a"    // value "baz"
-      "c5"          // insert with name reference, static index 5
-      "0362617a");  // value "baz"
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(
-                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
-
-  EXPECT_EQ(absl::HexStringToBytes(
-                "0400"      // prefix
-                "828180"),  // dynamic entries with relative index 0, 1, and 2
-            Encode(header_list2));
-
-  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-}
-
-TEST_F(QpackEncoderTest, EncoderStreamWritesAllowedThenDisallowed) {
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(0));
-  encoder_.SetMaximumBlockedStreams(1);
-  encoder_.SetMaximumDynamicTableCapacity(4096);
-  encoder_.SetDynamicTableCapacity(4096);
-
-  spdy::Http2HeaderBlock header_list1;
-  header_list1["foo"] = "bar";
-  header_list1.AppendValueOrAddHeader("foo",
-                                      "baz");  // name matches dynamic entry
-  header_list1["cookie"] = "baz";              // name matches static entry
-
-  // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
-  // Insert three entries into the dynamic table.
-  std::string insert_entries = absl::HexStringToBytes(
-      "62"          // insert without name reference
-      "94e7"        // Huffman-encoded name "foo"
-      "03626172"    // value "bar"
-      "80"          // insert with name reference, dynamic index 0
-      "0362617a"    // value "baz"
-      "c5"          // insert with name reference, static index 5
-      "0362617a");  // value "baz"
-  EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(
-                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
-
-  EXPECT_EQ(absl::HexStringToBytes(
-                "0400"      // prefix
-                "828180"),  // dynamic entries with relative index 0, 1, and 2
-            Encode(header_list1));
-
-  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
-
-  // If number of bytes buffered by encoder stream goes over the threshold,
-  // then QpackEncoder will stop emitting encoder stream instructions.
-  ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
-  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
-      .WillRepeatedly(Return(kTooManyBytesBuffered));
-
-  spdy::Http2HeaderBlock header_list2;
-  header_list2["foo"] = "bar";  // matches previously inserted dynamic entry
-  header_list2["bar"] = "baz";
-  header_list2["cookie"] = "baz";  // name matches static entry
-
-  // Encoder is not allowed to write on the encoder stream.
-  // No Set Dynamic Table Capacity or Insert instructions are sent.
-  // Headers are encoded as string literals.
-  EXPECT_EQ(
-      absl::HexStringToBytes("0400"      // prefix
-                             "82"        // dynamic entry with relative index 0
-                             "23626172"  // literal name "bar"
-                             "0362617a"  // with literal value "baz"
-                             "80"),      // dynamic entry with relative index 2
-      Encode(header_list2));
-
-  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_header_table.cc b/quic/core/qpack/qpack_header_table.cc
deleted file mode 100644
index 6607272..0000000
--- a/quic/core/qpack/qpack_header_table.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_header_table.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_static_table.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackEncoderHeaderTable::QpackEncoderHeaderTable()
-    : static_index_(ObtainQpackStaticTable().GetStaticIndex()),
-      static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()) {}
-
-uint64_t QpackEncoderHeaderTable::InsertEntry(absl::string_view name,
-                                              absl::string_view value) {
-  const uint64_t index =
-      QpackHeaderTableBase<QpackEncoderDynamicTable>::InsertEntry(name, value);
-
-  // Make name and value point to the new entry.
-  name = dynamic_entries().back().name();
-  value = dynamic_entries().back().value();
-
-  auto index_result = dynamic_index_.insert(
-      std::make_pair(QpackLookupEntry{name, value}, index));
-  if (!index_result.second) {
-    // An entry with the same name and value already exists.  It needs to be
-    // replaced, because |dynamic_index_| tracks the most recent entry for a
-    // given name and value.
-    QUICHE_DCHECK_GT(index, index_result.first->second);
-    dynamic_index_.erase(index_result.first);
-    auto result = dynamic_index_.insert(
-        std::make_pair(QpackLookupEntry{name, value}, index));
-    QUICHE_CHECK(result.second);
-  }
-
-  auto name_result = dynamic_name_index_.insert({name, index});
-  if (!name_result.second) {
-    // An entry with the same name already exists.  It needs to be replaced,
-    // because |dynamic_name_index_| tracks the most recent entry for a given
-    // name.
-    QUICHE_DCHECK_GT(index, name_result.first->second);
-    dynamic_name_index_.erase(name_result.first);
-    auto result = dynamic_name_index_.insert({name, index});
-    QUICHE_CHECK(result.second);
-  }
-
-  return index;
-}
-
-QpackEncoderHeaderTable::MatchType QpackEncoderHeaderTable::FindHeaderField(
-    absl::string_view name,
-    absl::string_view value,
-    bool* is_static,
-    uint64_t* index) const {
-  QpackLookupEntry query{name, value};
-
-  // Look for exact match in static table.
-  auto index_it = static_index_.find(query);
-  if (index_it != static_index_.end()) {
-    *index = index_it->second;
-    *is_static = true;
-    return MatchType::kNameAndValue;
-  }
-
-  // Look for exact match in dynamic table.
-  index_it = dynamic_index_.find(query);
-  if (index_it != dynamic_index_.end()) {
-    *index = index_it->second;
-    *is_static = false;
-    return MatchType::kNameAndValue;
-  }
-
-  // Look for name match in static table.
-  auto name_index_it = static_name_index_.find(name);
-  if (name_index_it != static_name_index_.end()) {
-    *index = name_index_it->second;
-    *is_static = true;
-    return MatchType::kName;
-  }
-
-  // Look for name match in dynamic table.
-  name_index_it = dynamic_name_index_.find(name);
-  if (name_index_it != dynamic_name_index_.end()) {
-    *index = name_index_it->second;
-    *is_static = false;
-    return MatchType::kName;
-  }
-
-  return MatchType::kNoMatch;
-}
-
-uint64_t QpackEncoderHeaderTable::MaxInsertSizeWithoutEvictingGivenEntry(
-    uint64_t index) const {
-  QUICHE_DCHECK_LE(dropped_entry_count(), index);
-
-  if (index > inserted_entry_count()) {
-    // All entries are allowed to be evicted.
-    return dynamic_table_capacity();
-  }
-
-  // Initialize to current available capacity.
-  uint64_t max_insert_size = dynamic_table_capacity() - dynamic_table_size();
-
-  uint64_t entry_index = dropped_entry_count();
-  for (const auto& entry : dynamic_entries()) {
-    if (entry_index >= index) {
-      break;
-    }
-    ++entry_index;
-    max_insert_size += entry.Size();
-  }
-
-  return max_insert_size;
-}
-
-uint64_t QpackEncoderHeaderTable::draining_index(
-    float draining_fraction) const {
-  QUICHE_DCHECK_LE(0.0, draining_fraction);
-  QUICHE_DCHECK_LE(draining_fraction, 1.0);
-
-  const uint64_t required_space = draining_fraction * dynamic_table_capacity();
-  uint64_t space_above_draining_index =
-      dynamic_table_capacity() - dynamic_table_size();
-
-  if (dynamic_entries().empty() ||
-      space_above_draining_index >= required_space) {
-    return dropped_entry_count();
-  }
-
-  auto it = dynamic_entries().begin();
-  uint64_t entry_index = dropped_entry_count();
-  while (space_above_draining_index < required_space) {
-    space_above_draining_index += it->Size();
-    ++it;
-    ++entry_index;
-    if (it == dynamic_entries().end()) {
-      return inserted_entry_count();
-    }
-  }
-
-  return entry_index;
-}
-
-void QpackEncoderHeaderTable::RemoveEntryFromEnd() {
-  const QpackEntry* const entry = &dynamic_entries().front();
-  const uint64_t index = dropped_entry_count();
-
-  auto index_it = dynamic_index_.find({entry->name(), entry->value()});
-  // Remove |dynamic_index_| entry only if it points to the same
-  // QpackEntry in dynamic_entries().
-  if (index_it != dynamic_index_.end() && index_it->second == index) {
-    dynamic_index_.erase(index_it);
-  }
-
-  auto name_it = dynamic_name_index_.find(entry->name());
-  // Remove |dynamic_name_index_| entry only if it points to the same
-  // QpackEntry in dynamic_entries().
-  if (name_it != dynamic_name_index_.end() && name_it->second == index) {
-    dynamic_name_index_.erase(name_it);
-  }
-
-  QpackHeaderTableBase<QpackEncoderDynamicTable>::RemoveEntryFromEnd();
-}
-
-QpackDecoderHeaderTable::QpackDecoderHeaderTable()
-    : static_entries_(ObtainQpackStaticTable().GetStaticEntries()) {}
-
-QpackDecoderHeaderTable::~QpackDecoderHeaderTable() {
-  for (auto& entry : observers_) {
-    entry.second->Cancel();
-  }
-}
-
-uint64_t QpackDecoderHeaderTable::InsertEntry(absl::string_view name,
-                                              absl::string_view value) {
-  const uint64_t index =
-      QpackHeaderTableBase<QpackDecoderDynamicTable>::InsertEntry(name, value);
-
-  // Notify and deregister observers whose threshold is met, if any.
-  while (!observers_.empty()) {
-    auto it = observers_.begin();
-    if (it->first > inserted_entry_count()) {
-      break;
-    }
-    Observer* observer = it->second;
-    observers_.erase(it);
-    observer->OnInsertCountReachedThreshold();
-  }
-
-  return index;
-}
-
-const QpackEntry* QpackDecoderHeaderTable::LookupEntry(bool is_static,
-                                                       uint64_t index) const {
-  if (is_static) {
-    if (index >= static_entries_.size()) {
-      return nullptr;
-    }
-
-    return &static_entries_[index];
-  }
-
-  if (index < dropped_entry_count()) {
-    return nullptr;
-  }
-
-  index -= dropped_entry_count();
-
-  if (index >= dynamic_entries().size()) {
-    return nullptr;
-  }
-
-  return &dynamic_entries()[index];
-}
-
-void QpackDecoderHeaderTable::RegisterObserver(uint64_t required_insert_count,
-                                               Observer* observer) {
-  QUICHE_DCHECK_GT(required_insert_count, 0u);
-  observers_.insert({required_insert_count, observer});
-}
-
-void QpackDecoderHeaderTable::UnregisterObserver(uint64_t required_insert_count,
-                                                 Observer* observer) {
-  auto it = observers_.lower_bound(required_insert_count);
-  while (it != observers_.end() && it->first == required_insert_count) {
-    if (it->second == observer) {
-      observers_.erase(it);
-      return;
-    }
-    ++it;
-  }
-
-  // |observer| must have been registered.
-  QUIC_NOTREACHED();
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_header_table.h b/quic/core/qpack/qpack_header_table.h
deleted file mode 100644
index 7193d10..0000000
--- a/quic/core/qpack/qpack_header_table.h
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
-
-#include <cstdint>
-#include <deque>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-#include "spdy/core/hpack/hpack_entry.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-
-namespace quic {
-
-using QpackEntry = spdy::HpackEntry;
-using QpackLookupEntry = spdy::HpackLookupEntry;
-constexpr size_t kQpackEntrySizeOverhead = spdy::kHpackEntrySizeOverhead;
-
-// Encoder needs pointer stability for |dynamic_index_| and
-// |dynamic_name_index_|.  However, it does not need random access.
-// TODO(b/182349990): Change to a more memory efficient container.
-using QpackEncoderDynamicTable = std::deque<QpackEntry>;
-
-// Decoder needs random access for LookupEntry().
-// However, it does not need pointer stability.
-using QpackDecoderDynamicTable = quiche::QuicheCircularDeque<QpackEntry>;
-
-// This is a base class for encoder and decoder classes that manage the QPACK
-// static and dynamic tables.  For dynamic entries, it only has a concept of
-// absolute indices.  The caller needs to perform the necessary transformations
-// to and from relative indices and post-base indices.
-template <typename DynamicEntryTable>
-class QUIC_EXPORT_PRIVATE QpackHeaderTableBase {
- public:
-  QpackHeaderTableBase();
-  QpackHeaderTableBase(const QpackHeaderTableBase&) = delete;
-  QpackHeaderTableBase& operator=(const QpackHeaderTableBase&) = delete;
-
-  virtual ~QpackHeaderTableBase() = default;
-
-  // Returns whether an entry with |name| and |value| has a size (including
-  // overhead) that is smaller than or equal to the capacity of the dynamic
-  // table.
-  bool EntryFitsDynamicTableCapacity(absl::string_view name,
-                                     absl::string_view value) const;
-
-  // Inserts (name, value) into the dynamic table.  Entry must not be larger
-  // than the capacity of the dynamic table.  May evict entries.  |name| and
-  // |value| are copied first, therefore it is safe for them to point to an
-  // entry in the dynamic table, even if it is about to be evicted, or even if
-  // the underlying container might move entries around when resizing for
-  // insertion.
-  // Returns the absolute index of the inserted dynamic table entry.
-  virtual uint64_t InsertEntry(absl::string_view name, absl::string_view value);
-
-  // Change dynamic table capacity to |capacity|.  Returns true on success.
-  // Returns false is |capacity| exceeds maximum dynamic table capacity.
-  bool SetDynamicTableCapacity(uint64_t capacity);
-
-  // Set |maximum_dynamic_table_capacity_|.  The initial value is zero.  The
-  // final value is determined by the decoder and is sent to the encoder as
-  // SETTINGS_HEADER_TABLE_SIZE.  Therefore in the decoding context the final
-  // value can be set upon connection establishment, whereas in the encoding
-  // context it can be set when the SETTINGS frame is received.
-  // This method must only be called at most once.
-  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
-  // or if it doesn't change current value. The setting is not changed when
-  // returning false.
-  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
-
-  uint64_t dynamic_table_size() const { return dynamic_table_size_; }
-  uint64_t dynamic_table_capacity() const { return dynamic_table_capacity_; }
-  uint64_t maximum_dynamic_table_capacity() const {
-    return maximum_dynamic_table_capacity_;
-  }
-  uint64_t max_entries() const { return max_entries_; }
-
-  // The number of entries inserted to the dynamic table (including ones that
-  // were dropped since).  Used for relative indexing on the encoder stream.
-  uint64_t inserted_entry_count() const {
-    return dynamic_entries_.size() + dropped_entry_count_;
-  }
-
-  // The number of entries dropped from the dynamic table.
-  uint64_t dropped_entry_count() const { return dropped_entry_count_; }
-
-  void set_dynamic_table_entry_referenced() {
-    dynamic_table_entry_referenced_ = true;
-  }
-  bool dynamic_table_entry_referenced() const {
-    return dynamic_table_entry_referenced_;
-  }
-
- protected:
-  // Removes a single entry from the end of the dynamic table, updates
-  // |dynamic_table_size_| and |dropped_entry_count_|.
-  virtual void RemoveEntryFromEnd();
-
-  const DynamicEntryTable& dynamic_entries() const { return dynamic_entries_; }
-
- private:
-  // Evict entries from the dynamic table until table size is less than or equal
-  // to |capacity|.
-  void EvictDownToCapacity(uint64_t capacity);
-
-  // Dynamic Table entries.
-  DynamicEntryTable dynamic_entries_;
-
-  // Size of the dynamic table.  This is the sum of the size of its entries.
-  uint64_t dynamic_table_size_;
-
-  // Dynamic Table Capacity is the maximum allowed value of
-  // |dynamic_table_size_|.  Entries are evicted if necessary before inserting a
-  // new entry to ensure that dynamic table size never exceeds capacity.
-  // Initial value is |maximum_dynamic_table_capacity_|.  Capacity can be
-  // changed by the encoder, as long as it does not exceed
-  // |maximum_dynamic_table_capacity_|.
-  uint64_t dynamic_table_capacity_;
-
-  // Maximum allowed value of |dynamic_table_capacity|.  The initial value is
-  // zero.  Can be changed by SetMaximumDynamicTableCapacity().
-  uint64_t maximum_dynamic_table_capacity_;
-
-  // MaxEntries, see Section 3.2.2.  Calculated based on
-  // |maximum_dynamic_table_capacity_|.  Used on request streams to encode and
-  // decode Required Insert Count.
-  uint64_t max_entries_;
-
-  // The number of entries dropped from the dynamic table.
-  uint64_t dropped_entry_count_;
-
-  // True if any dynamic table entries have been referenced from a header block.
-  // Set directly by the encoder or decoder.  Used for stats.
-  bool dynamic_table_entry_referenced_;
-};
-
-template <typename DynamicEntryTable>
-QpackHeaderTableBase<DynamicEntryTable>::QpackHeaderTableBase()
-    : dynamic_table_size_(0),
-      dynamic_table_capacity_(0),
-      maximum_dynamic_table_capacity_(0),
-      max_entries_(0),
-      dropped_entry_count_(0),
-      dynamic_table_entry_referenced_(false) {}
-
-template <typename DynamicEntryTable>
-bool QpackHeaderTableBase<DynamicEntryTable>::EntryFitsDynamicTableCapacity(
-    absl::string_view name,
-    absl::string_view value) const {
-  return QpackEntry::Size(name, value) <= dynamic_table_capacity_;
-}
-
-template <typename DynamicEntryTable>
-uint64_t QpackHeaderTableBase<DynamicEntryTable>::InsertEntry(
-    absl::string_view name,
-    absl::string_view value) {
-  QUICHE_DCHECK(EntryFitsDynamicTableCapacity(name, value));
-
-  const uint64_t index = dropped_entry_count_ + dynamic_entries_.size();
-
-  // Copy name and value before modifying the container, because evicting
-  // entries or even inserting a new one might invalidate |name| or |value| if
-  // they point to an entry.
-  QpackEntry new_entry((std::string(name)), (std::string(value)));
-  const size_t entry_size = new_entry.Size();
-
-  EvictDownToCapacity(dynamic_table_capacity_ - entry_size);
-
-  dynamic_table_size_ += entry_size;
-  dynamic_entries_.push_back(std::move(new_entry));
-
-  return index;
-}
-
-template <typename DynamicEntryTable>
-bool QpackHeaderTableBase<DynamicEntryTable>::SetDynamicTableCapacity(
-    uint64_t capacity) {
-  if (capacity > maximum_dynamic_table_capacity_) {
-    return false;
-  }
-
-  dynamic_table_capacity_ = capacity;
-  EvictDownToCapacity(capacity);
-
-  QUICHE_DCHECK_LE(dynamic_table_size_, dynamic_table_capacity_);
-
-  return true;
-}
-
-template <typename DynamicEntryTable>
-bool QpackHeaderTableBase<DynamicEntryTable>::SetMaximumDynamicTableCapacity(
-    uint64_t maximum_dynamic_table_capacity) {
-  if (maximum_dynamic_table_capacity_ == 0) {
-    maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
-    max_entries_ = maximum_dynamic_table_capacity / 32;
-    return true;
-  }
-  // If the value is already set, it should not be changed.
-  return maximum_dynamic_table_capacity == maximum_dynamic_table_capacity_;
-}
-
-template <typename DynamicEntryTable>
-void QpackHeaderTableBase<DynamicEntryTable>::RemoveEntryFromEnd() {
-  const uint64_t entry_size = dynamic_entries_.front().Size();
-  QUICHE_DCHECK_GE(dynamic_table_size_, entry_size);
-  dynamic_table_size_ -= entry_size;
-
-  dynamic_entries_.pop_front();
-  ++dropped_entry_count_;
-}
-
-template <typename DynamicEntryTable>
-void QpackHeaderTableBase<DynamicEntryTable>::EvictDownToCapacity(
-    uint64_t capacity) {
-  while (dynamic_table_size_ > capacity) {
-    QUICHE_DCHECK(!dynamic_entries_.empty());
-    RemoveEntryFromEnd();
-  }
-}
-
-class QUIC_EXPORT_PRIVATE QpackEncoderHeaderTable
-    : public QpackHeaderTableBase<QpackEncoderDynamicTable> {
- public:
-  // Result of header table lookup.
-  enum class MatchType { kNameAndValue, kName, kNoMatch };
-
-  QpackEncoderHeaderTable();
-  ~QpackEncoderHeaderTable() override = default;
-
-  uint64_t InsertEntry(absl::string_view name,
-                       absl::string_view value) override;
-
-  // Returns the absolute index of an entry with matching name and value if such
-  // exists, otherwise one with matching name is such exists.  |index| is zero
-  // based for both the static and the dynamic table.
-  MatchType FindHeaderField(absl::string_view name,
-                            absl::string_view value,
-                            bool* is_static,
-                            uint64_t* index) const;
-
-  // Returns the size of the largest entry that could be inserted into the
-  // dynamic table without evicting entry |index|.  |index| might be larger than
-  // inserted_entry_count(), in which case the capacity of the table is
-  // returned.  |index| must not be smaller than dropped_entry_count().
-  uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const;
-
-  // Returns the draining index described at
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
-  // Entries with an index larger than or equal to the draining index take up
-  // approximately |1.0 - draining_fraction| of dynamic table capacity.  The
-  // remaining capacity is taken up by draining entries and unused space.
-  // The returned index might not be the index of a valid entry.
-  uint64_t draining_index(float draining_fraction) const;
-
- protected:
-  void RemoveEntryFromEnd() override;
-
- private:
-  using NameValueToEntryMap = spdy::HpackHeaderTable::NameValueToEntryMap;
-  using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap;
-
-  // Static Table
-
-  // |static_index_| and |static_name_index_| are owned by QpackStaticTable
-  // singleton.
-
-  // Tracks the unique static entry for a given header name and value.
-  const NameValueToEntryMap& static_index_;
-
-  // Tracks the first static entry for a given header name.
-  const NameToEntryMap& static_name_index_;
-
-  // Dynamic Table
-
-  // An unordered set of QpackEntry pointers with a comparison operator that
-  // only cares about name and value.  This allows fast lookup of the most
-  // recently inserted dynamic entry for a given header name and value pair.
-  // Entries point to entries owned by |QpackHeaderTableBase::dynamic_entries_|.
-  NameValueToEntryMap dynamic_index_;
-
-  // An unordered map of QpackEntry pointers keyed off header name.  This allows
-  // fast lookup of the most recently inserted dynamic entry for a given header
-  // name.  Entries point to entries owned by
-  // |QpackHeaderTableBase::dynamic_entries_|.
-  NameToEntryMap dynamic_name_index_;
-};
-
-class QUIC_EXPORT_PRIVATE QpackDecoderHeaderTable
-    : public QpackHeaderTableBase<QpackDecoderDynamicTable> {
- public:
-  // Observer interface for dynamic table insertion.
-  class QUIC_EXPORT_PRIVATE Observer {
-   public:
-    virtual ~Observer() = default;
-
-    // Called when inserted_entry_count() reaches the threshold the Observer was
-    // registered with.  After this call the Observer automatically gets
-    // deregistered.
-    virtual void OnInsertCountReachedThreshold() = 0;
-
-    // Called when QpackDecoderHeaderTable is destroyed to let the Observer know
-    // that it must not call UnregisterObserver().
-    virtual void Cancel() = 0;
-  };
-
-  QpackDecoderHeaderTable();
-  ~QpackDecoderHeaderTable() override;
-
-  uint64_t InsertEntry(absl::string_view name,
-                       absl::string_view value) override;
-
-  // Returns the entry at absolute index |index| from the static or dynamic
-  // table according to |is_static|.  |index| is zero based for both the static
-  // and the dynamic table.  The returned pointer is valid until the entry is
-  // evicted, even if other entries are inserted into the dynamic table.
-  // Returns nullptr if entry does not exist.
-  const QpackEntry* LookupEntry(bool is_static, uint64_t index) const;
-
-  // Register an observer to be notified when inserted_entry_count() reaches
-  // |required_insert_count|.  After the notification, |observer| automatically
-  // gets unregistered.  Each observer must only be registered at most once.
-  void RegisterObserver(uint64_t required_insert_count, Observer* observer);
-
-  // Unregister previously registered observer.  Must be called with the same
-  // |required_insert_count| value that |observer| was registered with.  Must be
-  // called before an observer still waiting for notification is destroyed,
-  // unless QpackDecoderHeaderTable already called Observer::Cancel(), in which
-  // case this method must not be called.
-  void UnregisterObserver(uint64_t required_insert_count, Observer* observer);
-
- private:
-  // Static Table entries.  Owned by QpackStaticTable singleton.
-  using StaticEntryTable = spdy::HpackHeaderTable::StaticEntryTable;
-  const StaticEntryTable& static_entries_;
-
-  // Observers waiting to be notified, sorted by required insert count.
-  std::multimap<uint64_t, Observer*> observers_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
diff --git a/quic/core/qpack/qpack_header_table_test.cc b/quic/core/qpack/qpack_header_table_test.cc
deleted file mode 100644
index 4a1e39c..0000000
--- a/quic/core/qpack/qpack_header_table_test.cc
+++ /dev/null
@@ -1,655 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_header_table.h"
-
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_static_table.h"
-#include "quic/platform/api/quic_test.h"
-#include "spdy/core/hpack/hpack_entry.h"
-
-using ::testing::Mock;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const uint64_t kMaximumDynamicTableCapacityForTesting = 1024 * 1024;
-
-template <typename T>
-class QpackHeaderTableTest : public QuicTest {
- protected:
-  ~QpackHeaderTableTest() override = default;
-
-  void SetUp() override {
-    ASSERT_TRUE(table_.SetMaximumDynamicTableCapacity(
-        kMaximumDynamicTableCapacityForTesting));
-    ASSERT_TRUE(
-        table_.SetDynamicTableCapacity(kMaximumDynamicTableCapacityForTesting));
-  }
-
-  bool EntryFitsDynamicTableCapacity(absl::string_view name,
-                                     absl::string_view value) const {
-    return table_.EntryFitsDynamicTableCapacity(name, value);
-  }
-
-  void InsertEntry(absl::string_view name, absl::string_view value) {
-    table_.InsertEntry(name, value);
-  }
-
-  bool SetDynamicTableCapacity(uint64_t capacity) {
-    return table_.SetDynamicTableCapacity(capacity);
-  }
-
-  uint64_t max_entries() const { return table_.max_entries(); }
-  uint64_t inserted_entry_count() const {
-    return table_.inserted_entry_count();
-  }
-  uint64_t dropped_entry_count() const { return table_.dropped_entry_count(); }
-
-  T table_;
-};
-
-using MyTypes =
-    ::testing::Types<QpackEncoderHeaderTable, QpackDecoderHeaderTable>;
-TYPED_TEST_SUITE(QpackHeaderTableTest, MyTypes);
-
-// MaxEntries is determined by maximum dynamic table capacity,
-// which is set at construction time.
-TYPED_TEST(QpackHeaderTableTest, MaxEntries) {
-  TypeParam table1;
-  table1.SetMaximumDynamicTableCapacity(1024);
-  EXPECT_EQ(32u, table1.max_entries());
-
-  TypeParam table2;
-  table2.SetMaximumDynamicTableCapacity(500);
-  EXPECT_EQ(15u, table2.max_entries());
-}
-
-TYPED_TEST(QpackHeaderTableTest, SetDynamicTableCapacity) {
-  // Dynamic table capacity does not affect MaxEntries.
-  EXPECT_TRUE(this->SetDynamicTableCapacity(1024));
-  EXPECT_EQ(32u * 1024, this->max_entries());
-
-  EXPECT_TRUE(this->SetDynamicTableCapacity(500));
-  EXPECT_EQ(32u * 1024, this->max_entries());
-
-  // Dynamic table capacity cannot exceed maximum dynamic table capacity.
-  EXPECT_FALSE(this->SetDynamicTableCapacity(
-      2 * kMaximumDynamicTableCapacityForTesting));
-}
-
-TYPED_TEST(QpackHeaderTableTest, EntryFitsDynamicTableCapacity) {
-  EXPECT_TRUE(this->SetDynamicTableCapacity(39));
-
-  EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar"));
-  EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar2"));
-  EXPECT_FALSE(this->EntryFitsDynamicTableCapacity("foo", "bar12"));
-}
-
-class QpackEncoderHeaderTableTest
-    : public QpackHeaderTableTest<QpackEncoderHeaderTable> {
- protected:
-  ~QpackEncoderHeaderTableTest() override = default;
-
-  void ExpectMatch(absl::string_view name,
-                   absl::string_view value,
-                   QpackEncoderHeaderTable::MatchType expected_match_type,
-                   bool expected_is_static,
-                   uint64_t expected_index) const {
-    // Initialize outparams to a value different from the expected to ensure
-    // that FindHeaderField() sets them.
-    bool is_static = !expected_is_static;
-    uint64_t index = expected_index + 1;
-
-    QpackEncoderHeaderTable::MatchType matchtype =
-        table_.FindHeaderField(name, value, &is_static, &index);
-
-    EXPECT_EQ(expected_match_type, matchtype) << name << ": " << value;
-    EXPECT_EQ(expected_is_static, is_static) << name << ": " << value;
-    EXPECT_EQ(expected_index, index) << name << ": " << value;
-  }
-
-  void ExpectNoMatch(absl::string_view name, absl::string_view value) const {
-    bool is_static = false;
-    uint64_t index = 0;
-
-    QpackEncoderHeaderTable::MatchType matchtype =
-        table_.FindHeaderField(name, value, &is_static, &index);
-
-    EXPECT_EQ(QpackEncoderHeaderTable::MatchType::kNoMatch, matchtype)
-        << name << ": " << value;
-  }
-
-  uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const {
-    return table_.MaxInsertSizeWithoutEvictingGivenEntry(index);
-  }
-
-  uint64_t draining_index(float draining_fraction) const {
-    return table_.draining_index(draining_fraction);
-  }
-};
-
-TEST_F(QpackEncoderHeaderTableTest, FindStaticHeaderField) {
-  // A header name that has multiple entries with different values.
-  ExpectMatch(":method", "GET",
-              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
-
-  ExpectMatch(":method", "POST",
-              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 20u);
-
-  ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
-              true, 15u);
-
-  // A header name that has a single entry with non-empty value.
-  ExpectMatch("accept-encoding", "gzip, deflate, br",
-              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 31u);
-
-  ExpectMatch("accept-encoding", "compress",
-              QpackEncoderHeaderTable::MatchType::kName, true, 31u);
-
-  ExpectMatch("accept-encoding", "", QpackEncoderHeaderTable::MatchType::kName,
-              true, 31u);
-
-  // A header name that has a single entry with empty value.
-  ExpectMatch("location", "", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              true, 12u);
-
-  ExpectMatch("location", "foo", QpackEncoderHeaderTable::MatchType::kName,
-              true, 12u);
-
-  // No matching header name.
-  ExpectNoMatch("foo", "");
-  ExpectNoMatch("foo", "bar");
-}
-
-TEST_F(QpackEncoderHeaderTableTest, FindDynamicHeaderField) {
-  // Dynamic table is initially entry.
-  ExpectNoMatch("foo", "bar");
-  ExpectNoMatch("foo", "baz");
-
-  // Insert one entry.
-  InsertEntry("foo", "bar");
-
-  // Match name and value.
-  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              false, 0u);
-
-  // Match name only.
-  ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
-              0u);
-
-  // Insert an identical entry.  FindHeaderField() should return the index of
-  // the most recently inserted matching entry.
-  InsertEntry("foo", "bar");
-
-  // Match name and value.
-  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              false, 1u);
-
-  // Match name only.
-  ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
-              1u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, FindHeaderFieldPrefersStaticTable) {
-  // Insert an entry to the dynamic table that exists in the static table.
-  InsertEntry(":method", "GET");
-
-  // FindHeaderField() prefers static table if both have name-and-value match.
-  ExpectMatch(":method", "GET",
-              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
-
-  // FindHeaderField() prefers static table if both have name match but no value
-  // match, and prefers the first entry with matching name.
-  ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
-              true, 15u);
-
-  // Add new entry to the dynamic table.
-  InsertEntry(":method", "TRACE");
-
-  // FindHeaderField prefers name-and-value match in dynamic table over name
-  // only match in static table.
-  ExpectMatch(":method", "TRACE",
-              QpackEncoderHeaderTable::MatchType::kNameAndValue, false, 1u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictByInsertion) {
-  EXPECT_TRUE(SetDynamicTableCapacity(40));
-
-  // Entry size is 3 + 3 + 32 = 38.
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(1u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 0u);
-
-  // Inserting second entry evicts the first one.
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectNoMatch("foo", "bar");
-  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 1u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictByUpdateTableSize) {
-  // Entry size is 3 + 3 + 32 = 38.
-  InsertEntry("foo", "bar");
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 0u);
-  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 1u);
-
-  EXPECT_TRUE(SetDynamicTableCapacity(40));
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectNoMatch("foo", "bar");
-  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 1u);
-
-  EXPECT_TRUE(SetDynamicTableCapacity(20));
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(2u, dropped_entry_count());
-
-  ExpectNoMatch("foo", "bar");
-  ExpectNoMatch("baz", "qux");
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfIdentical) {
-  EXPECT_TRUE(SetDynamicTableCapacity(80));
-
-  // Entry size is 3 + 3 + 32 = 38.
-  // Insert same entry twice.
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  // Find most recently inserted entry.
-  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 1u);
-
-  // Inserting third entry evicts the first one, not the second.
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(3u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 1u);
-  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 2u);
-}
-
-TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfSameName) {
-  EXPECT_TRUE(SetDynamicTableCapacity(80));
-
-  // Entry size is 3 + 3 + 32 = 38.
-  // Insert two entries with same name but different values.
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "baz");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  // Find most recently inserted entry with matching name.
-  ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
-              /* expected_is_static = */ false, 1u);
-
-  // Inserting third entry evicts the first one, not the second.
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(3u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
-              /* expected_is_static = */ false, 1u);
-  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
-              /* expected_is_static = */ false, 2u);
-}
-
-// Returns the size of the largest entry that could be inserted into the
-// dynamic table without evicting entry |index|.
-TEST_F(QpackEncoderHeaderTableTest, MaxInsertSizeWithoutEvictingGivenEntry) {
-  const uint64_t dynamic_table_capacity = 100;
-  EXPECT_TRUE(SetDynamicTableCapacity(dynamic_table_capacity));
-
-  // Empty table can take an entry up to its capacity.
-  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(0));
-
-  const uint64_t entry_size1 = QpackEntry::Size("foo", "bar");
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(dynamic_table_capacity - entry_size1,
-            MaxInsertSizeWithoutEvictingGivenEntry(0));
-  // Table can take an entry up to its capacity if all entries are allowed to be
-  // evicted.
-  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(1));
-
-  const uint64_t entry_size2 = QpackEntry::Size("baz", "foobar");
-  InsertEntry("baz", "foobar");
-  // Table can take an entry up to its capacity if all entries are allowed to be
-  // evicted.
-  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(2));
-  // Second entry must stay.
-  EXPECT_EQ(dynamic_table_capacity - entry_size2,
-            MaxInsertSizeWithoutEvictingGivenEntry(1));
-  // First and second entry must stay.
-  EXPECT_EQ(dynamic_table_capacity - entry_size2 - entry_size1,
-            MaxInsertSizeWithoutEvictingGivenEntry(0));
-
-  // Third entry evicts first one.
-  const uint64_t entry_size3 = QpackEntry::Size("last", "entry");
-  InsertEntry("last", "entry");
-  EXPECT_EQ(1u, dropped_entry_count());
-  // Table can take an entry up to its capacity if all entries are allowed to be
-  // evicted.
-  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(3));
-  // Third entry must stay.
-  EXPECT_EQ(dynamic_table_capacity - entry_size3,
-            MaxInsertSizeWithoutEvictingGivenEntry(2));
-  // Second and third entry must stay.
-  EXPECT_EQ(dynamic_table_capacity - entry_size3 - entry_size2,
-            MaxInsertSizeWithoutEvictingGivenEntry(1));
-}
-
-TEST_F(QpackEncoderHeaderTableTest, DrainingIndex) {
-  EXPECT_TRUE(SetDynamicTableCapacity(4 * QpackEntry::Size("foo", "bar")));
-
-  // Empty table: no draining entry.
-  EXPECT_EQ(0u, draining_index(0.0));
-  EXPECT_EQ(0u, draining_index(1.0));
-
-  // Table with one entry.
-  InsertEntry("foo", "bar");
-  // Any entry can be referenced if none of the table is draining.
-  EXPECT_EQ(0u, draining_index(0.0));
-  // No entry can be referenced if all of the table is draining.
-  EXPECT_EQ(1u, draining_index(1.0));
-
-  // Table with two entries is at half capacity.
-  InsertEntry("foo", "bar");
-  // Any entry can be referenced if at most half of the table is draining,
-  // because current entries only take up half of total capacity.
-  EXPECT_EQ(0u, draining_index(0.0));
-  EXPECT_EQ(0u, draining_index(0.5));
-  // No entry can be referenced if all of the table is draining.
-  EXPECT_EQ(2u, draining_index(1.0));
-
-  // Table with four entries is full.
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "bar");
-  // Any entry can be referenced if none of the table is draining.
-  EXPECT_EQ(0u, draining_index(0.0));
-  // In a full table with identically sized entries, |draining_fraction| of all
-  // entries are draining.
-  EXPECT_EQ(2u, draining_index(0.5));
-  // No entry can be referenced if all of the table is draining.
-  EXPECT_EQ(4u, draining_index(1.0));
-}
-
-class MockObserver : public QpackDecoderHeaderTable::Observer {
- public:
-  ~MockObserver() override = default;
-
-  MOCK_METHOD(void, OnInsertCountReachedThreshold, (), (override));
-  MOCK_METHOD(void, Cancel, (), (override));
-};
-
-class QpackDecoderHeaderTableTest
-    : public QpackHeaderTableTest<QpackDecoderHeaderTable> {
- protected:
-  ~QpackDecoderHeaderTableTest() override = default;
-
-  void ExpectEntryAtIndex(bool is_static,
-                          uint64_t index,
-                          absl::string_view expected_name,
-                          absl::string_view expected_value) const {
-    const auto* entry = table_.LookupEntry(is_static, index);
-    ASSERT_TRUE(entry);
-    EXPECT_EQ(expected_name, entry->name());
-    EXPECT_EQ(expected_value, entry->value());
-  }
-
-  void ExpectNoEntryAtIndex(bool is_static, uint64_t index) const {
-    EXPECT_FALSE(table_.LookupEntry(is_static, index));
-  }
-
-  void RegisterObserver(uint64_t required_insert_count,
-                        QpackDecoderHeaderTable::Observer* observer) {
-    table_.RegisterObserver(required_insert_count, observer);
-  }
-
-  void UnregisterObserver(uint64_t required_insert_count,
-                          QpackDecoderHeaderTable::Observer* observer) {
-    table_.UnregisterObserver(required_insert_count, observer);
-  }
-};
-
-TEST_F(QpackDecoderHeaderTableTest, LookupStaticEntry) {
-  ExpectEntryAtIndex(/* is_static = */ true, 0, ":authority", "");
-
-  ExpectEntryAtIndex(/* is_static = */ true, 1, ":path", "/");
-
-  // 98 is the last entry.
-  ExpectEntryAtIndex(/* is_static = */ true, 98, "x-frame-options",
-                     "sameorigin");
-
-  ASSERT_EQ(99u, QpackStaticTableVector().size());
-  ExpectNoEntryAtIndex(/* is_static = */ true, 99);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, InsertAndLookupDynamicEntry) {
-  // Dynamic table is initially entry.
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 1);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-
-  // Insert one entry.
-  InsertEntry("foo", "bar");
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 1);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-
-  // Insert a different entry.
-  InsertEntry("baz", "bing");
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
-
-  ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-
-  // Insert an entry identical to the most recently inserted one.
-  InsertEntry("baz", "bing");
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
-
-  ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
-
-  ExpectEntryAtIndex(/* is_static = */ false, 2, "baz", "bing");
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictByInsertion) {
-  EXPECT_TRUE(SetDynamicTableCapacity(40));
-
-  // Entry size is 3 + 3 + 32 = 38.
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(1u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
-
-  // Inserting second entry evicts the first one.
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictByUpdateTableSize) {
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
-
-  // Entry size is 3 + 3 + 32 = 38.
-  InsertEntry("foo", "bar");
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
-
-  EXPECT_TRUE(SetDynamicTableCapacity(40));
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
-
-  EXPECT_TRUE(SetDynamicTableCapacity(20));
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(2u, dropped_entry_count());
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
-  ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfIdentical) {
-  EXPECT_TRUE(SetDynamicTableCapacity(80));
-
-  // Entry size is 3 + 3 + 32 = 38.
-  // Insert same entry twice.
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
-  ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
-
-  // Inserting third entry evicts the first one, not the second.
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(3u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
-  ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
-}
-
-TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfSameName) {
-  EXPECT_TRUE(SetDynamicTableCapacity(80));
-
-  // Entry size is 3 + 3 + 32 = 38.
-  // Insert two entries with same name but different values.
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "baz");
-  EXPECT_EQ(2u, inserted_entry_count());
-  EXPECT_EQ(0u, dropped_entry_count());
-
-  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
-  ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
-
-  // Inserting third entry evicts the first one, not the second.
-  InsertEntry("baz", "qux");
-  EXPECT_EQ(3u, inserted_entry_count());
-  EXPECT_EQ(1u, dropped_entry_count());
-
-  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
-  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
-  ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
-}
-
-TEST_F(QpackDecoderHeaderTableTest, RegisterObserver) {
-  StrictMock<MockObserver> observer1;
-  RegisterObserver(1, &observer1);
-  EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(1u, inserted_entry_count());
-  Mock::VerifyAndClearExpectations(&observer1);
-
-  // Registration order does not matter.
-  StrictMock<MockObserver> observer2;
-  StrictMock<MockObserver> observer3;
-  RegisterObserver(3, &observer3);
-  RegisterObserver(2, &observer2);
-
-  EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(2u, inserted_entry_count());
-  Mock::VerifyAndClearExpectations(&observer3);
-
-  EXPECT_CALL(observer3, OnInsertCountReachedThreshold);
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(3u, inserted_entry_count());
-  Mock::VerifyAndClearExpectations(&observer2);
-
-  // Multiple observers with identical |required_insert_count| should all be
-  // notified.
-  StrictMock<MockObserver> observer4;
-  StrictMock<MockObserver> observer5;
-  RegisterObserver(4, &observer4);
-  RegisterObserver(4, &observer5);
-
-  EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
-  EXPECT_CALL(observer5, OnInsertCountReachedThreshold);
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(4u, inserted_entry_count());
-  Mock::VerifyAndClearExpectations(&observer4);
-  Mock::VerifyAndClearExpectations(&observer5);
-}
-
-TEST_F(QpackDecoderHeaderTableTest, UnregisterObserver) {
-  StrictMock<MockObserver> observer1;
-  StrictMock<MockObserver> observer2;
-  StrictMock<MockObserver> observer3;
-  StrictMock<MockObserver> observer4;
-  RegisterObserver(1, &observer1);
-  RegisterObserver(2, &observer2);
-  RegisterObserver(2, &observer3);
-  RegisterObserver(3, &observer4);
-
-  UnregisterObserver(2, &observer3);
-
-  EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
-  EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
-  EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "bar");
-  InsertEntry("foo", "bar");
-  EXPECT_EQ(3u, inserted_entry_count());
-}
-
-TEST_F(QpackDecoderHeaderTableTest, Cancel) {
-  StrictMock<MockObserver> observer;
-  auto table = std::make_unique<QpackDecoderHeaderTable>();
-  table->RegisterObserver(1, &observer);
-
-  EXPECT_CALL(observer, Cancel);
-  table.reset();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_index_conversions.cc b/quic/core/qpack/qpack_index_conversions.cc
deleted file mode 100644
index 66f2ea3..0000000
--- a/quic/core/qpack/qpack_index_conversions.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_index_conversions.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-uint64_t QpackAbsoluteIndexToEncoderStreamRelativeIndex(
-    uint64_t absolute_index,
-    uint64_t inserted_entry_count) {
-  QUICHE_DCHECK_LT(absolute_index, inserted_entry_count);
-
-  return inserted_entry_count - absolute_index - 1;
-}
-
-uint64_t QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
-                                                        uint64_t base) {
-  QUICHE_DCHECK_LT(absolute_index, base);
-
-  return base - absolute_index - 1;
-}
-
-bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-    uint64_t relative_index,
-    uint64_t inserted_entry_count,
-    uint64_t* absolute_index) {
-  if (relative_index >= inserted_entry_count) {
-    return false;
-  }
-
-  *absolute_index = inserted_entry_count - relative_index - 1;
-  return true;
-}
-
-bool QpackRequestStreamRelativeIndexToAbsoluteIndex(uint64_t relative_index,
-                                                    uint64_t base,
-                                                    uint64_t* absolute_index) {
-  if (relative_index >= base) {
-    return false;
-  }
-
-  *absolute_index = base - relative_index - 1;
-  return true;
-}
-
-bool QpackPostBaseIndexToAbsoluteIndex(uint64_t post_base_index,
-                                       uint64_t base,
-                                       uint64_t* absolute_index) {
-  if (post_base_index >= std::numeric_limits<uint64_t>::max() - base) {
-    return false;
-  }
-
-  *absolute_index = base + post_base_index;
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_index_conversions.h b/quic/core/qpack/qpack_index_conversions.h
deleted file mode 100644
index 101858a..0000000
--- a/quic/core/qpack/qpack_index_conversions.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Utility methods to convert between absolute indexing (used in the dynamic
-// table), relative indexing used on the encoder stream, and relative indexing
-// and post-base indexing used on request streams (in header blocks).  See:
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#indexing
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#relative-indexing
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#post-base
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Conversion functions used in the encoder do not check for overflow/underflow.
-// Since the maximum index is limited by maximum dynamic table capacity
-// (represented on uint64_t) divided by minimum header field size (defined to be
-// 32 bytes), overflow is not possible.  The caller is responsible for providing
-// input that does not underflow.
-
-QUIC_EXPORT_PRIVATE uint64_t
-QpackAbsoluteIndexToEncoderStreamRelativeIndex(uint64_t absolute_index,
-                                               uint64_t inserted_entry_count);
-
-QUIC_EXPORT_PRIVATE uint64_t
-QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
-                                               uint64_t base);
-
-// Conversion functions used in the decoder operate on input received from the
-// network.  These functions return false on overflow or underflow.
-
-QUIC_EXPORT_PRIVATE bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-    uint64_t relative_index,
-    uint64_t inserted_entry_count,
-    uint64_t* absolute_index);
-
-// On success, |*absolute_index| is guaranteed to be strictly less than
-// std::numeric_limits<uint64_t>::max().
-QUIC_EXPORT_PRIVATE bool QpackRequestStreamRelativeIndexToAbsoluteIndex(
-    uint64_t relative_index,
-    uint64_t base,
-    uint64_t* absolute_index);
-
-// On success, |*absolute_index| is guaranteed to be strictly less than
-// std::numeric_limits<uint64_t>::max().
-QUIC_EXPORT_PRIVATE bool QpackPostBaseIndexToAbsoluteIndex(
-    uint64_t post_base_index,
-    uint64_t base,
-    uint64_t* absolute_index);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
diff --git a/quic/core/qpack/qpack_index_conversions_test.cc b/quic/core/qpack/qpack_index_conversions_test.cc
deleted file mode 100644
index 335adc4..0000000
--- a/quic/core/qpack/qpack_index_conversions_test.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_index_conversions.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct {
-  uint64_t relative_index;
-  uint64_t inserted_entry_count;
-  uint64_t expected_absolute_index;
-} kEncoderStreamRelativeIndexTestData[] = {{0, 1, 0},  {0, 2, 1},  {1, 2, 0},
-                                           {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
-
-TEST(QpackIndexConversions, EncoderStreamRelativeIndex) {
-  for (const auto& test_data : kEncoderStreamRelativeIndexTestData) {
-    uint64_t absolute_index = 42;
-    EXPECT_TRUE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-        test_data.relative_index, test_data.inserted_entry_count,
-        &absolute_index));
-    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
-
-    EXPECT_EQ(test_data.relative_index,
-              QpackAbsoluteIndexToEncoderStreamRelativeIndex(
-                  absolute_index, test_data.inserted_entry_count));
-  }
-}
-
-struct {
-  uint64_t relative_index;
-  uint64_t base;
-  uint64_t expected_absolute_index;
-} kRequestStreamRelativeIndexTestData[] = {{0, 1, 0},  {0, 2, 1},  {1, 2, 0},
-                                           {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
-
-TEST(QpackIndexConversions, RequestStreamRelativeIndex) {
-  for (const auto& test_data : kRequestStreamRelativeIndexTestData) {
-    uint64_t absolute_index = 42;
-    EXPECT_TRUE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
-        test_data.relative_index, test_data.base, &absolute_index));
-    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
-
-    EXPECT_EQ(test_data.relative_index,
-              QpackAbsoluteIndexToRequestStreamRelativeIndex(absolute_index,
-                                                             test_data.base));
-  }
-}
-
-struct {
-  uint64_t post_base_index;
-  uint64_t base;
-  uint64_t expected_absolute_index;
-} kPostBaseIndexTestData[] = {{0, 1, 1}, {1, 0, 1}, {2, 0, 2},
-                              {1, 1, 2}, {0, 2, 2}, {1, 2, 3}};
-
-TEST(QpackIndexConversions, PostBaseIndex) {
-  for (const auto& test_data : kPostBaseIndexTestData) {
-    uint64_t absolute_index = 42;
-    EXPECT_TRUE(QpackPostBaseIndexToAbsoluteIndex(
-        test_data.post_base_index, test_data.base, &absolute_index));
-    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
-  }
-}
-
-TEST(QpackIndexConversions, EncoderStreamRelativeIndexUnderflow) {
-  uint64_t absolute_index;
-  EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-      /* relative_index = */ 10,
-      /* inserted_entry_count = */ 10, &absolute_index));
-  EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
-      /* relative_index = */ 12,
-      /* inserted_entry_count = */ 10, &absolute_index));
-}
-
-TEST(QpackIndexConversions, RequestStreamRelativeIndexUnderflow) {
-  uint64_t absolute_index;
-  EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
-      /* relative_index = */ 10,
-      /* base = */ 10, &absolute_index));
-  EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
-      /* relative_index = */ 12,
-      /* base = */ 10, &absolute_index));
-}
-
-TEST(QpackIndexConversions, QpackPostBaseIndexToAbsoluteIndexOverflow) {
-  uint64_t absolute_index;
-  EXPECT_FALSE(QpackPostBaseIndexToAbsoluteIndex(
-      /* post_base_index = */ 20,
-      /* base = */ std::numeric_limits<uint64_t>::max() - 10, &absolute_index));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_instruction_decoder.cc b/quic/core/qpack/qpack_instruction_decoder.cc
deleted file mode 100644
index acd52c2..0000000
--- a/quic/core/qpack/qpack_instruction_decoder.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Maximum length of header name and header value.  This limits the amount of
-// memory the peer can make the decoder allocate when sending string literals.
-const size_t kStringLiteralLengthLimit = 1024 * 1024;
-
-}  // namespace
-
-QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language,
-                                                 Delegate* delegate)
-    : language_(language),
-      delegate_(delegate),
-      s_bit_(false),
-      varint_(0),
-      varint2_(0),
-      is_huffman_encoded_(false),
-      string_length_(0),
-      error_detected_(false),
-      state_(State::kStartInstruction) {}
-
-bool QpackInstructionDecoder::Decode(absl::string_view data) {
-  QUICHE_DCHECK(!data.empty());
-  QUICHE_DCHECK(!error_detected_);
-
-  while (true) {
-    bool success = true;
-    size_t bytes_consumed = 0;
-
-    switch (state_) {
-      case State::kStartInstruction:
-        success = DoStartInstruction(data);
-        break;
-      case State::kStartField:
-        success = DoStartField();
-        break;
-      case State::kReadBit:
-        success = DoReadBit(data);
-        break;
-      case State::kVarintStart:
-        success = DoVarintStart(data, &bytes_consumed);
-        break;
-      case State::kVarintResume:
-        success = DoVarintResume(data, &bytes_consumed);
-        break;
-      case State::kVarintDone:
-        success = DoVarintDone();
-        break;
-      case State::kReadString:
-        success = DoReadString(data, &bytes_consumed);
-        break;
-      case State::kReadStringDone:
-        success = DoReadStringDone();
-        break;
-    }
-
-    if (!success) {
-      return false;
-    }
-
-    // |success| must be false if an error is detected.
-    QUICHE_DCHECK(!error_detected_);
-
-    QUICHE_DCHECK_LE(bytes_consumed, data.size());
-
-    data = absl::string_view(data.data() + bytes_consumed,
-                             data.size() - bytes_consumed);
-
-    // Stop processing if no more data but next state would require it.
-    if (data.empty() && (state_ != State::kStartField) &&
-        (state_ != State::kVarintDone) && (state_ != State::kReadStringDone)) {
-      return true;
-    }
-  }
-}
-
-bool QpackInstructionDecoder::AtInstructionBoundary() const {
-  return state_ == State::kStartInstruction;
-}
-
-bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) {
-  QUICHE_DCHECK(!data.empty());
-
-  instruction_ = LookupOpcode(data[0]);
-  field_ = instruction_->fields.begin();
-
-  state_ = State::kStartField;
-  return true;
-}
-
-bool QpackInstructionDecoder::DoStartField() {
-  if (field_ == instruction_->fields.end()) {
-    // Completed decoding this instruction.
-
-    if (!delegate_->OnInstructionDecoded(instruction_)) {
-      return false;
-    }
-
-    state_ = State::kStartInstruction;
-    return true;
-  }
-
-  switch (field_->type) {
-    case QpackInstructionFieldType::kSbit:
-    case QpackInstructionFieldType::kName:
-    case QpackInstructionFieldType::kValue:
-      state_ = State::kReadBit;
-      return true;
-    case QpackInstructionFieldType::kVarint:
-    case QpackInstructionFieldType::kVarint2:
-      state_ = State::kVarintStart;
-      return true;
-    default:
-      QUIC_BUG(quic_bug_10767_1) << "Invalid field type.";
-      return false;
-  }
-}
-
-bool QpackInstructionDecoder::DoReadBit(absl::string_view data) {
-  QUICHE_DCHECK(!data.empty());
-
-  switch (field_->type) {
-    case QpackInstructionFieldType::kSbit: {
-      const uint8_t bitmask = field_->param;
-      s_bit_ = (data[0] & bitmask) == bitmask;
-
-      ++field_;
-      state_ = State::kStartField;
-
-      return true;
-    }
-    case QpackInstructionFieldType::kName:
-    case QpackInstructionFieldType::kValue: {
-      const uint8_t prefix_length = field_->param;
-      QUICHE_DCHECK_GE(7, prefix_length);
-      const uint8_t bitmask = 1 << prefix_length;
-      is_huffman_encoded_ = (data[0] & bitmask) == bitmask;
-
-      state_ = State::kVarintStart;
-
-      return true;
-    }
-    default:
-      QUIC_BUG(quic_bug_10767_2) << "Invalid field type.";
-      return false;
-  }
-}
-
-bool QpackInstructionDecoder::DoVarintStart(absl::string_view data,
-                                            size_t* bytes_consumed) {
-  QUICHE_DCHECK(!data.empty());
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
-                field_->type == QpackInstructionFieldType::kVarint2 ||
-                field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  http2::DecodeBuffer buffer(data.data() + 1, data.size() - 1);
-  http2::DecodeStatus status =
-      varint_decoder_.Start(data[0], field_->param, &buffer);
-
-  *bytes_consumed = 1 + buffer.Offset();
-  switch (status) {
-    case http2::DecodeStatus::kDecodeDone:
-      state_ = State::kVarintDone;
-      return true;
-    case http2::DecodeStatus::kDecodeInProgress:
-      state_ = State::kVarintResume;
-      return true;
-    case http2::DecodeStatus::kDecodeError:
-      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
-      return false;
-    default:
-      QUIC_BUG(quic_bug_10767_3) << "Unknown decode status " << status;
-      return false;
-  }
-}
-
-bool QpackInstructionDecoder::DoVarintResume(absl::string_view data,
-                                             size_t* bytes_consumed) {
-  QUICHE_DCHECK(!data.empty());
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
-                field_->type == QpackInstructionFieldType::kVarint2 ||
-                field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  http2::DecodeBuffer buffer(data);
-  http2::DecodeStatus status = varint_decoder_.Resume(&buffer);
-
-  *bytes_consumed = buffer.Offset();
-  switch (status) {
-    case http2::DecodeStatus::kDecodeDone:
-      state_ = State::kVarintDone;
-      return true;
-    case http2::DecodeStatus::kDecodeInProgress:
-      QUICHE_DCHECK_EQ(*bytes_consumed, data.size());
-      QUICHE_DCHECK(buffer.Empty());
-      return true;
-    case http2::DecodeStatus::kDecodeError:
-      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
-      return false;
-    default:
-      QUIC_BUG(quic_bug_10767_4) << "Unknown decode status " << status;
-      return false;
-  }
-}
-
-bool QpackInstructionDecoder::DoVarintDone() {
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
-                field_->type == QpackInstructionFieldType::kVarint2 ||
-                field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  if (field_->type == QpackInstructionFieldType::kVarint) {
-    varint_ = varint_decoder_.value();
-
-    ++field_;
-    state_ = State::kStartField;
-    return true;
-  }
-
-  if (field_->type == QpackInstructionFieldType::kVarint2) {
-    varint2_ = varint_decoder_.value();
-
-    ++field_;
-    state_ = State::kStartField;
-    return true;
-  }
-
-  string_length_ = varint_decoder_.value();
-  if (string_length_ > kStringLiteralLengthLimit) {
-    OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long.");
-    return false;
-  }
-
-  std::string* const string =
-      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
-  string->clear();
-
-  if (string_length_ == 0) {
-    ++field_;
-    state_ = State::kStartField;
-    return true;
-  }
-
-  string->reserve(string_length_);
-
-  state_ = State::kReadString;
-  return true;
-}
-
-bool QpackInstructionDecoder::DoReadString(absl::string_view data,
-                                           size_t* bytes_consumed) {
-  QUICHE_DCHECK(!data.empty());
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  std::string* const string =
-      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
-  QUICHE_DCHECK_LT(string->size(), string_length_);
-
-  *bytes_consumed = std::min(string_length_ - string->size(), data.size());
-  string->append(data.data(), *bytes_consumed);
-
-  QUICHE_DCHECK_LE(string->size(), string_length_);
-  if (string->size() == string_length_) {
-    state_ = State::kReadStringDone;
-  }
-  return true;
-}
-
-bool QpackInstructionDecoder::DoReadStringDone() {
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  std::string* const string =
-      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
-  QUICHE_DCHECK_EQ(string->size(), string_length_);
-
-  if (is_huffman_encoded_) {
-    huffman_decoder_.Reset();
-    // HpackHuffmanDecoder::Decode() cannot perform in-place decoding.
-    std::string decoded_value;
-    huffman_decoder_.Decode(*string, &decoded_value);
-    if (!huffman_decoder_.InputProperlyTerminated()) {
-      OnError(ErrorCode::HUFFMAN_ENCODING_ERROR,
-              "Error in Huffman-encoded string.");
-      return false;
-    }
-    *string = std::move(decoded_value);
-  }
-
-  ++field_;
-  state_ = State::kStartField;
-  return true;
-}
-
-const QpackInstruction* QpackInstructionDecoder::LookupOpcode(
-    uint8_t byte) const {
-  for (const auto* instruction : *language_) {
-    if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
-      return instruction;
-    }
-  }
-  // |language_| should be defined such that instruction opcodes cover every
-  // possible input.
-  QUICHE_DCHECK(false);
-  return nullptr;
-}
-
-void QpackInstructionDecoder::OnError(ErrorCode error_code,
-                                      absl::string_view error_message) {
-  QUICHE_DCHECK(!error_detected_);
-
-  error_detected_ = true;
-  delegate_->OnInstructionDecodingError(error_code, error_message);
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_instruction_decoder.h b/quic/core/qpack/qpack_instruction_decoder.h
deleted file mode 100644
index fc9b96e..0000000
--- a/quic/core/qpack/qpack_instruction_decoder.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/huffman/hpack_huffman_decoder.h"
-#include "http2/hpack/varint/hpack_varint_decoder.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Generic instruction decoder class.  Takes a QpackLanguage that describes a
-// language, that is, a set of instruction opcodes together with a list of
-// fields that follow each instruction.
-class QUIC_EXPORT_PRIVATE QpackInstructionDecoder {
- public:
-  enum class ErrorCode {
-    INTEGER_TOO_LARGE,
-    STRING_LITERAL_TOO_LONG,
-    HUFFMAN_ENCODING_ERROR,
-  };
-
-  // Delegate is notified each time an instruction is decoded or when an error
-  // occurs.
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() = default;
-
-    // Called when an instruction (including all its fields) is decoded.
-    // |instruction| points to an entry in |language|.
-    // Returns true if decoded fields are valid.
-    // Returns false otherwise, in which case QpackInstructionDecoder stops
-    // decoding: Delegate methods will not be called, and Decode() must not be
-    // called.  Implementations are allowed to destroy the
-    // QpackInstructionDecoder instance synchronously if OnInstructionDecoded()
-    // returns false.
-    virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
-
-    // Called by QpackInstructionDecoder if an error has occurred.
-    // No more data is processed afterwards.
-    // Implementations are allowed to destroy the QpackInstructionDecoder
-    // instance synchronously.
-    virtual void OnInstructionDecodingError(
-        ErrorCode error_code,
-        absl::string_view error_message) = 0;
-  };
-
-  // Both |*language| and |*delegate| must outlive this object.
-  QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
-  QpackInstructionDecoder() = delete;
-  QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
-  QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
-
-  // Provide a data fragment to decode.  Must not be called after an error has
-  // occurred.  Must not be called with empty |data|.  Return true on success,
-  // false on error (in which case Delegate::OnInstructionDecodingError() is
-  // called synchronously).
-  bool Decode(absl::string_view data);
-
-  // Returns true if no decoding has taken place yet or if the last instruction
-  // has been entirely parsed.
-  bool AtInstructionBoundary() const;
-
-  // Accessors for decoded values.  Should only be called for fields that are
-  // part of the most recently decoded instruction, and only after |this| calls
-  // Delegate::OnInstructionDecoded() but before Decode() is called again.
-  bool s_bit() const { return s_bit_; }
-  uint64_t varint() const { return varint_; }
-  uint64_t varint2() const { return varint2_; }
-  const std::string& name() const { return name_; }
-  const std::string& value() const { return value_; }
-
- private:
-  enum class State {
-    // Identify instruction.
-    kStartInstruction,
-    // Start decoding next field.
-    kStartField,
-    // Read a single bit.
-    kReadBit,
-    // Start reading integer.
-    kVarintStart,
-    // Resume reading integer.
-    kVarintResume,
-    // Done reading integer.
-    kVarintDone,
-    // Read string.
-    kReadString,
-    // Done reading string.
-    kReadStringDone
-  };
-
-  // One method for each state.  They each return true on success, false on
-  // error (in which case |this| might already be destroyed).  Some take input
-  // data and set |*bytes_consumed| to the number of octets processed.  Some
-  // take input data but do not consume any bytes.  Some do not take any
-  // arguments because they only change internal state.
-  bool DoStartInstruction(absl::string_view data);
-  bool DoStartField();
-  bool DoReadBit(absl::string_view data);
-  bool DoVarintStart(absl::string_view data, size_t* bytes_consumed);
-  bool DoVarintResume(absl::string_view data, size_t* bytes_consumed);
-  bool DoVarintDone();
-  bool DoReadString(absl::string_view data, size_t* bytes_consumed);
-  bool DoReadStringDone();
-
-  // Identify instruction based on opcode encoded in |byte|.
-  // Returns a pointer to an element of |*language_|.
-  const QpackInstruction* LookupOpcode(uint8_t byte) const;
-
-  // Stops decoding and calls Delegate::OnInstructionDecodingError().
-  void OnError(ErrorCode error_code, absl::string_view error_message);
-
-  // Describes the language used for decoding.
-  const QpackLanguage* const language_;
-
-  // The Delegate to notify of decoded instructions and errors.
-  Delegate* const delegate_;
-
-  // Storage for decoded field values.
-  bool s_bit_;
-  uint64_t varint_;
-  uint64_t varint2_;
-  std::string name_;
-  std::string value_;
-  // Whether the currently decoded header name or value is Huffman encoded.
-  bool is_huffman_encoded_;
-  // Length of string being read into |name_| or |value_|.
-  size_t string_length_;
-
-  // Decoder instance for decoding integers.
-  http2::HpackVarintDecoder varint_decoder_;
-
-  // Decoder instance for decoding Huffman encoded strings.
-  http2::HpackHuffmanDecoder huffman_decoder_;
-
-  // True if a decoding error has been detected by QpackInstructionDecoder.
-  // Only used in QUICHE_DCHECKs.
-  bool error_detected_;
-
-  // Decoding state.
-  State state_;
-
-  // Instruction currently being decoded.
-  const QpackInstruction* instruction_;
-
-  // Field currently being decoded.
-  QpackInstructionFields::const_iterator field_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
diff --git a/quic/core/qpack/qpack_instruction_decoder_test.cc b/quic/core/qpack/qpack_instruction_decoder_test.cc
deleted file mode 100644
index b10c1b4..0000000
--- a/quic/core/qpack/qpack_instruction_decoder_test.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-
-#include <algorithm>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Expectation;
-using ::testing::InvokeWithoutArgs;
-using ::testing::Return;
-using ::testing::StrictMock;
-using ::testing::Values;
-
-namespace quic {
-namespace test {
-namespace {
-
-// This instruction has three fields: an S bit and two varints.
-const QpackInstruction* TestInstruction1() {
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{QpackInstructionOpcode{0x00, 0x80},
-                           {{QpackInstructionFieldType::kSbit, 0x40},
-                            {QpackInstructionFieldType::kVarint, 6},
-                            {QpackInstructionFieldType::kVarint2, 8}}};
-  return instruction;
-}
-
-// This instruction has two fields: a header name with a 6-bit prefix, and a
-// header value with a 7-bit prefix, both preceded by a Huffman bit.
-const QpackInstruction* TestInstruction2() {
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{QpackInstructionOpcode{0x80, 0x80},
-                           {{QpackInstructionFieldType::kName, 6},
-                            {QpackInstructionFieldType::kValue, 7}}};
-  return instruction;
-}
-
-const QpackLanguage* TestLanguage() {
-  static const QpackLanguage* const language =
-      new QpackLanguage{TestInstruction1(), TestInstruction2()};
-  return language;
-}
-
-class MockDelegate : public QpackInstructionDecoder::Delegate {
- public:
-  MockDelegate() {
-    ON_CALL(*this, OnInstructionDecoded(_)).WillByDefault(Return(true));
-  }
-
-  MockDelegate(const MockDelegate&) = delete;
-  MockDelegate& operator=(const MockDelegate&) = delete;
-  ~MockDelegate() override = default;
-
-  MOCK_METHOD(bool,
-              OnInstructionDecoded,
-              (const QpackInstruction*),
-              (override));
-  MOCK_METHOD(void,
-              OnInstructionDecodingError,
-              (QpackInstructionDecoder::ErrorCode error_code,
-               absl::string_view error_message),
-              (override));
-};
-
-class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> {
- protected:
-  QpackInstructionDecoderTest()
-      : decoder_(std::make_unique<QpackInstructionDecoder>(TestLanguage(),
-                                                           &delegate_)),
-        fragment_mode_(GetParam()) {}
-  ~QpackInstructionDecoderTest() override = default;
-
-  void SetUp() override {
-    // Destroy QpackInstructionDecoder on error to test that it does not crash.
-    // See https://crbug.com/1025209.
-    ON_CALL(delegate_, OnInstructionDecodingError(_, _))
-        .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); }));
-  }
-
-  // Decode one full instruction with fragment sizes dictated by
-  // |fragment_mode_|.
-  // Assumes that |data| is a single complete instruction, and accordingly
-  // verifies that AtInstructionBoundary() returns true before and after the
-  // instruction, and returns false while decoding is in progress.
-  // Assumes that delegate methods destroy |decoder_| if they return false.
-  void DecodeInstruction(absl::string_view data) {
-    EXPECT_TRUE(decoder_->AtInstructionBoundary());
-
-    FragmentSizeGenerator fragment_size_generator =
-        FragmentModeToFragmentSizeGenerator(fragment_mode_);
-
-    while (!data.empty()) {
-      size_t fragment_size = std::min(fragment_size_generator(), data.size());
-      bool success = decoder_->Decode(data.substr(0, fragment_size));
-      if (!decoder_) {
-        EXPECT_FALSE(success);
-        return;
-      }
-      EXPECT_TRUE(success);
-      data = data.substr(fragment_size);
-      if (!data.empty()) {
-        EXPECT_FALSE(decoder_->AtInstructionBoundary());
-      }
-    }
-
-    EXPECT_TRUE(decoder_->AtInstructionBoundary());
-  }
-
-  StrictMock<MockDelegate> delegate_;
-  std::unique_ptr<QpackInstructionDecoder> decoder_;
-
- private:
-  const FragmentMode fragment_mode_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         QpackInstructionDecoderTest,
-                         Values(FragmentMode::kSingleChunk,
-                                FragmentMode::kOctetByOctet));
-
-TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
-  DecodeInstruction(absl::HexStringToBytes("7f01ff65"));
-
-  EXPECT_TRUE(decoder_->s_bit());
-  EXPECT_EQ(64u, decoder_->varint());
-  EXPECT_EQ(356u, decoder_->varint2());
-
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
-  DecodeInstruction(absl::HexStringToBytes("05c8"));
-
-  EXPECT_FALSE(decoder_->s_bit());
-  EXPECT_EQ(5u, decoder_->varint());
-  EXPECT_EQ(200u, decoder_->varint2());
-}
-
-TEST_P(QpackInstructionDecoderTest, NameAndValue) {
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
-  DecodeInstruction(absl::HexStringToBytes("83666f6f03626172"));
-
-  EXPECT_EQ("foo", decoder_->name());
-  EXPECT_EQ("bar", decoder_->value());
-
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
-  DecodeInstruction(absl::HexStringToBytes("8000"));
-
-  EXPECT_EQ("", decoder_->name());
-  EXPECT_EQ("", decoder_->value());
-
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
-  DecodeInstruction(absl::HexStringToBytes("c294e7838c767f"));
-
-  EXPECT_EQ("foo", decoder_->name());
-  EXPECT_EQ("bar", decoder_->value());
-}
-
-TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) {
-  EXPECT_CALL(delegate_,
-              OnInstructionDecodingError(
-                  QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR,
-                  Eq("Error in Huffman-encoded string.")));
-  DecodeInstruction(absl::HexStringToBytes("c1ff"));
-}
-
-TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
-  EXPECT_CALL(delegate_,
-              OnInstructionDecodingError(
-                  QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE,
-                  Eq("Encoded integer too large.")));
-  DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff"));
-}
-
-TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
-  EXPECT_CALL(delegate_,
-              OnInstructionDecodingError(
-                  QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG,
-                  Eq("String literal too long.")));
-  DecodeInstruction(absl::HexStringToBytes("bfffff7f"));
-}
-
-TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
-  // First instruction is valid.
-  Expectation first_call =
-      EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
-          .WillOnce(InvokeWithoutArgs([this]() -> bool {
-            EXPECT_EQ(1u, decoder_->varint());
-            return true;
-          }));
-
-  // Second instruction is invalid.  Decoding must halt.
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
-      .After(first_call)
-      .WillOnce(InvokeWithoutArgs([this]() -> bool {
-        EXPECT_EQ(2u, decoder_->varint());
-        return false;
-      }));
-
-  EXPECT_FALSE(
-      decoder_->Decode(absl::HexStringToBytes("01000200030004000500")));
-}
-
-// QpackInstructionDecoder must not crash if it is destroyed from a
-// Delegate::OnInstructionDecoded() call as long as it returns false.
-TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) {
-  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
-      .WillOnce(InvokeWithoutArgs([this]() -> bool {
-        EXPECT_EQ(1u, decoder_->varint());
-        decoder_.reset();
-        return false;
-      }));
-  DecodeInstruction(absl::HexStringToBytes("0100"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_instruction_encoder.cc b/quic/core/qpack/qpack_instruction_encoder.cc
deleted file mode 100644
index 527c43c..0000000
--- a/quic/core/qpack/qpack_instruction_encoder.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-#include "http2/hpack/varint/hpack_varint_encoder.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QpackInstructionEncoder::QpackInstructionEncoder()
-    : use_huffman_(false),
-      string_length_(0),
-      byte_(0),
-      state_(State::kOpcode),
-      instruction_(nullptr) {}
-
-void QpackInstructionEncoder::Encode(
-    const QpackInstructionWithValues& instruction_with_values,
-    std::string* output) {
-  QUICHE_DCHECK(instruction_with_values.instruction());
-
-  state_ = State::kOpcode;
-  instruction_ = instruction_with_values.instruction();
-  field_ = instruction_->fields.begin();
-
-  // Field list must not be empty.
-  QUICHE_DCHECK(field_ != instruction_->fields.end());
-
-  do {
-    switch (state_) {
-      case State::kOpcode:
-        DoOpcode();
-        break;
-      case State::kStartField:
-        DoStartField();
-        break;
-      case State::kSbit:
-        DoSBit(instruction_with_values.s_bit());
-        break;
-      case State::kVarintEncode:
-        DoVarintEncode(instruction_with_values.varint(),
-                       instruction_with_values.varint2(), output);
-        break;
-      case State::kStartString:
-        DoStartString(instruction_with_values.name(),
-                      instruction_with_values.value());
-        break;
-      case State::kWriteString:
-        DoWriteString(instruction_with_values.name(),
-                      instruction_with_values.value(), output);
-        break;
-    }
-  } while (field_ != instruction_->fields.end());
-
-  QUICHE_DCHECK(state_ == State::kStartField);
-}
-
-void QpackInstructionEncoder::DoOpcode() {
-  QUICHE_DCHECK_EQ(0u, byte_);
-
-  byte_ = instruction_->opcode.value;
-
-  state_ = State::kStartField;
-}
-
-void QpackInstructionEncoder::DoStartField() {
-  switch (field_->type) {
-    case QpackInstructionFieldType::kSbit:
-      state_ = State::kSbit;
-      return;
-    case QpackInstructionFieldType::kVarint:
-    case QpackInstructionFieldType::kVarint2:
-      state_ = State::kVarintEncode;
-      return;
-    case QpackInstructionFieldType::kName:
-    case QpackInstructionFieldType::kValue:
-      state_ = State::kStartString;
-      return;
-  }
-}
-
-void QpackInstructionEncoder::DoSBit(bool s_bit) {
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kSbit);
-
-  if (s_bit) {
-    QUICHE_DCHECK_EQ(0, byte_ & field_->param);
-
-    byte_ |= field_->param;
-  }
-
-  ++field_;
-  state_ = State::kStartField;
-}
-
-void QpackInstructionEncoder::DoVarintEncode(uint64_t varint,
-                                             uint64_t varint2,
-                                             std::string* output) {
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
-                field_->type == QpackInstructionFieldType::kVarint2 ||
-                field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-  uint64_t integer_to_encode;
-  switch (field_->type) {
-    case QpackInstructionFieldType::kVarint:
-      integer_to_encode = varint;
-      break;
-    case QpackInstructionFieldType::kVarint2:
-      integer_to_encode = varint2;
-      break;
-    default:
-      integer_to_encode = string_length_;
-      break;
-  }
-
-  http2::HpackVarintEncoder::Encode(byte_, field_->param, integer_to_encode,
-                                    output);
-  byte_ = 0;
-
-  if (field_->type == QpackInstructionFieldType::kVarint ||
-      field_->type == QpackInstructionFieldType::kVarint2) {
-    ++field_;
-    state_ = State::kStartField;
-    return;
-  }
-
-  state_ = State::kWriteString;
-}
-
-void QpackInstructionEncoder::DoStartString(absl::string_view name,
-                                            absl::string_view value) {
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  absl::string_view string_to_write =
-      (field_->type == QpackInstructionFieldType::kName) ? name : value;
-  string_length_ = string_to_write.size();
-
-  size_t encoded_size = http2::HuffmanSize(string_to_write);
-  use_huffman_ = encoded_size < string_length_;
-
-  if (use_huffman_) {
-    QUICHE_DCHECK_EQ(0, byte_ & (1 << field_->param));
-    byte_ |= (1 << field_->param);
-
-    string_length_ = encoded_size;
-  }
-
-  state_ = State::kVarintEncode;
-}
-
-void QpackInstructionEncoder::DoWriteString(absl::string_view name,
-                                            absl::string_view value,
-                                            std::string* output) {
-  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
-                field_->type == QpackInstructionFieldType::kValue);
-
-  absl::string_view string_to_write =
-      (field_->type == QpackInstructionFieldType::kName) ? name : value;
-  if (use_huffman_) {
-    http2::HuffmanEncodeFast(string_to_write, string_length_, output);
-  } else {
-    absl::StrAppend(output, string_to_write);
-  }
-
-  ++field_;
-  state_ = State::kStartField;
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_instruction_encoder.h b/quic/core/qpack/qpack_instruction_encoder.h
deleted file mode 100644
index 66a76ea..0000000
--- a/quic/core/qpack/qpack_instruction_encoder.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Generic instruction encoder class.  Takes a QpackLanguage that describes a
-// language, that is, a set of instruction opcodes together with a list of
-// fields that follow each instruction.
-class QUIC_EXPORT_PRIVATE QpackInstructionEncoder {
- public:
-  QpackInstructionEncoder();
-  QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
-  QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
-
-  // Append encoded instruction to |output|.
-  void Encode(const QpackInstructionWithValues& instruction_with_values,
-              std::string* output);
-
- private:
-  enum class State {
-    // Write instruction opcode to |byte_|.
-    kOpcode,
-    // Select state based on type of current field.
-    kStartField,
-    // Write static bit to |byte_|.
-    kSbit,
-    // Encode an integer (|varint_| or |varint2_| or string length) with a
-    // prefix, using |byte_| for the high bits.
-    kVarintEncode,
-    // Determine if Huffman encoding should be used for the header name or
-    // value, set |use_huffman_| and |string_length_| appropriately, write the
-    // Huffman bit to |byte_|.
-    kStartString,
-    // Write header name or value, performing Huffman encoding if |use_huffman_|
-    // is true.
-    kWriteString
-  };
-
-  // One method for each state.  Some append encoded bytes to |output|.
-  // Some only change internal state.
-  void DoOpcode();
-  void DoStartField();
-  void DoSBit(bool s_bit);
-  void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output);
-  void DoStartString(absl::string_view name, absl::string_view value);
-  void DoWriteString(absl::string_view name,
-                     absl::string_view value,
-                     std::string* output);
-
-  // True if name or value should be Huffman encoded.
-  bool use_huffman_;
-
-  // Length of name or value string to be written.
-  // If |use_huffman_| is true, length is after Huffman encoding.
-  size_t string_length_;
-
-  // Storage for a single byte that contains multiple fields, that is, multiple
-  // states are writing it.
-  uint8_t byte_;
-
-  // Encoding state.
-  State state_;
-
-  // Instruction currently being decoded.
-  const QpackInstruction* instruction_;
-
-  // Field currently being decoded.
-  QpackInstructionFields::const_iterator field_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
diff --git a/quic/core/qpack/qpack_instruction_encoder_test.cc b/quic/core/qpack/qpack_instruction_encoder_test.cc
deleted file mode 100644
index c84634b..0000000
--- a/quic/core/qpack/qpack_instruction_encoder_test.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instruction_encoder.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QpackInstructionWithValuesPeer {
- public:
-  static QpackInstructionWithValues CreateQpackInstructionWithValues(
-      const QpackInstruction* instruction) {
-    QpackInstructionWithValues instruction_with_values;
-    instruction_with_values.instruction_ = instruction;
-    return instruction_with_values;
-  }
-
-  static void set_s_bit(QpackInstructionWithValues* instruction_with_values,
-                        bool s_bit) {
-    instruction_with_values->s_bit_ = s_bit;
-  }
-
-  static void set_varint(QpackInstructionWithValues* instruction_with_values,
-                         uint64_t varint) {
-    instruction_with_values->varint_ = varint;
-  }
-
-  static void set_varint2(QpackInstructionWithValues* instruction_with_values,
-                          uint64_t varint2) {
-    instruction_with_values->varint2_ = varint2;
-  }
-
-  static void set_name(QpackInstructionWithValues* instruction_with_values,
-                       absl::string_view name) {
-    instruction_with_values->name_ = name;
-  }
-
-  static void set_value(QpackInstructionWithValues* instruction_with_values,
-                        absl::string_view value) {
-    instruction_with_values->value_ = value;
-  }
-};
-
-namespace {
-
-class QpackInstructionEncoderTest : public QuicTest {
- protected:
-  QpackInstructionEncoderTest() : verified_position_(0) {}
-  ~QpackInstructionEncoderTest() override = default;
-
-  // Append encoded |instruction| to |output_|.
-  void EncodeInstruction(
-      const QpackInstructionWithValues& instruction_with_values) {
-    encoder_.Encode(instruction_with_values, &output_);
-  }
-
-  // Compare substring appended to |output_| since last EncodedSegmentMatches()
-  // call against hex-encoded argument.
-  bool EncodedSegmentMatches(absl::string_view hex_encoded_expected_substring) {
-    auto recently_encoded =
-        absl::string_view(output_).substr(verified_position_);
-    auto expected = absl::HexStringToBytes(hex_encoded_expected_substring);
-    verified_position_ = output_.size();
-    return recently_encoded == expected;
-  }
-
- private:
-  QpackInstructionEncoder encoder_;
-  std::string output_;
-  std::string::size_type verified_position_;
-};
-
-TEST_F(QpackInstructionEncoderTest, Varint) {
-  const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80},
-                                     {{QpackInstructionFieldType::kVarint, 7}}};
-
-  auto instruction_with_values =
-      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
-          &instruction);
-  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("05"));
-
-  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 127);
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("7f00"));
-}
-
-TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
-  const QpackInstruction instruction{
-      QpackInstructionOpcode{0x80, 0xc0},
-      {{QpackInstructionFieldType::kSbit, 0x20},
-       {QpackInstructionFieldType::kVarint, 5},
-       {QpackInstructionFieldType::kVarint2, 8}}};
-
-  auto instruction_with_values =
-      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
-          &instruction);
-  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
-  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
-  QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 200);
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("a5c8"));
-
-  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
-  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 31);
-  QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 356);
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("9f00ff65"));
-}
-
-TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
-  const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0},
-                                     {{QpackInstructionFieldType::kSbit, 0x20},
-                                      {QpackInstructionFieldType::kVarint, 5},
-                                      {QpackInstructionFieldType::kValue, 7}}};
-
-  auto instruction_with_values =
-      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
-          &instruction);
-  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
-  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 100);
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("ff458294e7"));
-
-  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
-  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 3);
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("c303626172"));
-}
-
-TEST_F(QpackInstructionEncoderTest, Name) {
-  const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0},
-                                     {{QpackInstructionFieldType::kName, 4}}};
-
-  auto instruction_with_values =
-      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
-          &instruction);
-  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("e0"));
-
-  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("f294e7"));
-
-  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "bar");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("e3626172"));
-}
-
-TEST_F(QpackInstructionEncoderTest, Value) {
-  const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
-                                     {{QpackInstructionFieldType::kValue, 3}}};
-
-  auto instruction_with_values =
-      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
-          &instruction);
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("f0"));
-
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("fa94e7"));
-
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("f3626172"));
-}
-
-TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) {
-  const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
-                                     {{QpackInstructionFieldType::kSbit, 0x08},
-                                      {QpackInstructionFieldType::kName, 2},
-                                      {QpackInstructionFieldType::kValue, 7}}};
-
-  auto instruction_with_values =
-      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
-          &instruction);
-  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
-  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("f000"));
-
-  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
-  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
-  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
-  EncodeInstruction(instruction_with_values);
-  EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_instructions.cc b/quic/core/qpack/qpack_instructions.cc
deleted file mode 100644
index 7f95762..0000000
--- a/quic/core/qpack/qpack_instructions.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_instructions.h"
-
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// Validate that
-//  * in each instruction, the bits of |value| that are zero in |mask| are zero;
-//  * every byte matches exactly one opcode.
-void ValidateLangague(const QpackLanguage* language) {
-#ifndef NDEBUG
-  for (const auto* instruction : *language) {
-    QUICHE_DCHECK_EQ(0, instruction->opcode.value & ~instruction->opcode.mask);
-  }
-
-  for (uint8_t byte = 0; byte < std::numeric_limits<uint8_t>::max(); ++byte) {
-    size_t match_count = 0;
-    for (const auto* instruction : *language) {
-      if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
-        ++match_count;
-      }
-    }
-    QUICHE_DCHECK_EQ(1u, match_count) << static_cast<int>(byte);
-  }
-#else
-  (void)language;
-#endif
-}
-
-}  // namespace
-
-bool operator==(const QpackInstructionOpcode& a,
-                const QpackInstructionOpcode& b) {
-  return std::tie(a.value, a.mask) == std::tie(b.value, b.mask);
-}
-
-const QpackInstruction* InsertWithNameReferenceInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b10000000, 0b10000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kSbit, 0b01000000},
-                            {QpackInstructionFieldType::kVarint, 6},
-                            {QpackInstructionFieldType::kValue, 7}}};
-  return instruction;
-}
-
-const QpackInstruction* InsertWithoutNameReferenceInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b01000000, 0b11000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kName, 5},
-                            {QpackInstructionFieldType::kValue, 7}}};
-  return instruction;
-}
-
-const QpackInstruction* DuplicateInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00000000, 0b11100000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
-  return instruction;
-}
-
-const QpackInstruction* SetDynamicTableCapacityInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00100000, 0b11100000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
-  return instruction;
-}
-
-const QpackLanguage* QpackEncoderStreamLanguage() {
-  static const QpackLanguage* const language = new QpackLanguage{
-      InsertWithNameReferenceInstruction(),
-      InsertWithoutNameReferenceInstruction(), DuplicateInstruction(),
-      SetDynamicTableCapacityInstruction()};
-  ValidateLangague(language);
-  return language;
-}
-
-const QpackInstruction* InsertCountIncrementInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00000000, 0b11000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
-  return instruction;
-}
-
-const QpackInstruction* HeaderAcknowledgementInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b10000000, 0b10000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 7}}};
-  return instruction;
-}
-
-const QpackInstruction* StreamCancellationInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b01000000, 0b11000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
-  return instruction;
-}
-
-const QpackLanguage* QpackDecoderStreamLanguage() {
-  static const QpackLanguage* const language = new QpackLanguage{
-      InsertCountIncrementInstruction(), HeaderAcknowledgementInstruction(),
-      StreamCancellationInstruction()};
-  ValidateLangague(language);
-  return language;
-}
-
-const QpackInstruction* QpackPrefixInstruction() {
-  // This opcode matches every input.
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00000000, 0b00000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kVarint, 8},
-                            {QpackInstructionFieldType::kSbit, 0b10000000},
-                            {QpackInstructionFieldType::kVarint2, 7}}};
-  return instruction;
-}
-
-const QpackLanguage* QpackPrefixLanguage() {
-  static const QpackLanguage* const language =
-      new QpackLanguage{QpackPrefixInstruction()};
-  ValidateLangague(language);
-  return language;
-}
-
-const QpackInstruction* QpackIndexedHeaderFieldInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b10000000, 0b10000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kSbit, 0b01000000},
-                            {QpackInstructionFieldType::kVarint, 6}}};
-  return instruction;
-}
-
-const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00010000, 0b11110000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 4}}};
-  return instruction;
-}
-
-const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b01000000, 0b11000000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kSbit, 0b00010000},
-                            {QpackInstructionFieldType::kVarint, 4},
-                            {QpackInstructionFieldType::kValue, 7}}};
-  return instruction;
-}
-
-const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00000000, 0b11110000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kVarint, 3},
-                            {QpackInstructionFieldType::kValue, 7}}};
-  return instruction;
-}
-
-const QpackInstruction* QpackLiteralHeaderFieldInstruction() {
-  static const QpackInstructionOpcode* const opcode =
-      new QpackInstructionOpcode{0b00100000, 0b11100000};
-  static const QpackInstruction* const instruction =
-      new QpackInstruction{*opcode,
-                           {{QpackInstructionFieldType::kName, 3},
-                            {QpackInstructionFieldType::kValue, 7}}};
-  return instruction;
-}
-
-const QpackLanguage* QpackRequestStreamLanguage() {
-  static const QpackLanguage* const language =
-      new QpackLanguage{QpackIndexedHeaderFieldInstruction(),
-                        QpackIndexedHeaderFieldPostBaseInstruction(),
-                        QpackLiteralHeaderFieldNameReferenceInstruction(),
-                        QpackLiteralHeaderFieldPostBaseInstruction(),
-                        QpackLiteralHeaderFieldInstruction()};
-  ValidateLangague(language);
-  return language;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::InsertWithNameReference(
-    bool is_static,
-    uint64_t name_index,
-    absl::string_view value) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = InsertWithNameReferenceInstruction();
-  instruction_with_values.s_bit_ = is_static;
-  instruction_with_values.varint_ = name_index;
-  instruction_with_values.value_ = value;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues
-QpackInstructionWithValues::InsertWithoutNameReference(
-    absl::string_view name,
-    absl::string_view value) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ =
-      InsertWithoutNameReferenceInstruction();
-  instruction_with_values.name_ = name;
-  instruction_with_values.value_ = value;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::Duplicate(
-    uint64_t index) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = DuplicateInstruction();
-  instruction_with_values.varint_ = index;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::SetDynamicTableCapacity(
-    uint64_t capacity) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = SetDynamicTableCapacityInstruction();
-  instruction_with_values.varint_ = capacity;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::InsertCountIncrement(
-    uint64_t increment) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = InsertCountIncrementInstruction();
-  instruction_with_values.varint_ = increment;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::HeaderAcknowledgement(
-    uint64_t stream_id) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = HeaderAcknowledgementInstruction();
-  instruction_with_values.varint_ = stream_id;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::StreamCancellation(
-    uint64_t stream_id) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = StreamCancellationInstruction();
-  instruction_with_values.varint_ = stream_id;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::Prefix(
-    uint64_t required_insert_count) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = QpackPrefixInstruction();
-  instruction_with_values.varint_ = required_insert_count;
-  instruction_with_values.varint2_ = 0;    // Delta Base.
-  instruction_with_values.s_bit_ = false;  // Delta Base sign.
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::IndexedHeaderField(
-    bool is_static,
-    uint64_t index) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = QpackIndexedHeaderFieldInstruction();
-  instruction_with_values.s_bit_ = is_static;
-  instruction_with_values.varint_ = index;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues
-QpackInstructionWithValues::LiteralHeaderFieldNameReference(
-    bool is_static,
-    uint64_t index,
-    absl::string_view value) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ =
-      QpackLiteralHeaderFieldNameReferenceInstruction();
-  instruction_with_values.s_bit_ = is_static;
-  instruction_with_values.varint_ = index;
-  instruction_with_values.value_ = value;
-
-  return instruction_with_values;
-}
-
-// static
-QpackInstructionWithValues QpackInstructionWithValues::LiteralHeaderField(
-    absl::string_view name,
-    absl::string_view value) {
-  QpackInstructionWithValues instruction_with_values;
-  instruction_with_values.instruction_ = QpackLiteralHeaderFieldInstruction();
-  instruction_with_values.name_ = name;
-  instruction_with_values.value_ = value;
-
-  return instruction_with_values;
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_instructions.h b/quic/core/qpack/qpack_instructions.h
deleted file mode 100644
index 56613de..0000000
--- a/quic/core/qpack/qpack_instructions.h
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
-
-#include <cstdint>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QpackInstructionWithValuesPeer;
-}  // namespace test
-
-// Each instruction is identified with an opcode in the first byte.
-// |mask| determines which bits are part of the opcode.
-// |value| is the value of these bits.  (Other bits in value must be zero.)
-struct QUIC_EXPORT_PRIVATE QpackInstructionOpcode {
-  uint8_t value;
-  uint8_t mask;
-};
-
-bool operator==(const QpackInstructionOpcode& a,
-                const QpackInstructionOpcode& b);
-
-// Possible types of an instruction field.  Decoding a static bit does not
-// consume the current byte.  Decoding an integer or a length-prefixed string
-// literal consumes all bytes containing the field value.
-enum class QpackInstructionFieldType {
-  // A single bit indicating whether the index refers to the static table, or
-  // indicating the sign of Delta Base.  Called "S" bit because both "static"
-  // and "sign" start with the letter "S".
-  kSbit,
-  // An integer encoded with variable length encoding.  This could be an index,
-  // stream ID, maximum size, or Encoded Required Insert Count.
-  kVarint,
-  // A second integer encoded with variable length encoding.  This could be
-  // Delta Base.
-  kVarint2,
-  // A header name or header value encoded as:
-  //   a bit indicating whether it is Huffman encoded;
-  //   the encoded length of the string;
-  //   the header name or value optionally Huffman encoded.
-  kName,
-  kValue
-};
-
-// Each instruction field has a type and a parameter.
-// The meaning of the parameter depends on the field type.
-struct QUIC_EXPORT_PRIVATE QpackInstructionField {
-  QpackInstructionFieldType type;
-  // For a kSbit field, |param| is a mask with exactly one bit set.
-  // For kVarint fields, |param| is the prefix length of the integer encoding.
-  // For kName and kValue fields, |param| is the prefix length of the length of
-  // the string, and the bit immediately preceding the prefix is interpreted as
-  // the Huffman bit.
-  uint8_t param;
-};
-
-using QpackInstructionFields = std::vector<QpackInstructionField>;
-
-// A QPACK instruction consists of an opcode identifying the instruction,
-// followed by a non-empty list of fields.  The last field must be integer or
-// string literal type to guarantee that all bytes of the instruction are
-// consumed.
-struct QUIC_EXPORT_PRIVATE QpackInstruction {
-  QpackInstruction(const QpackInstruction&) = delete;
-  const QpackInstruction& operator=(const QpackInstruction&) = delete;
-
-  QpackInstructionOpcode opcode;
-  QpackInstructionFields fields;
-};
-
-// A language is a collection of instructions.  The order does not matter.
-// Every possible input must match exactly one instruction.
-using QpackLanguage = std::vector<const QpackInstruction*>;
-
-// Wire format defined in
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5
-
-// 5.2 Encoder stream instructions
-
-// 5.2.1 Insert With Name Reference
-const QpackInstruction* InsertWithNameReferenceInstruction();
-
-// 5.2.2 Insert Without Name Reference
-const QpackInstruction* InsertWithoutNameReferenceInstruction();
-
-// 5.2.3 Duplicate
-const QpackInstruction* DuplicateInstruction();
-
-// 5.2.4 Dynamic Table Size Update
-const QpackInstruction* SetDynamicTableCapacityInstruction();
-
-// Encoder stream language.
-const QpackLanguage* QpackEncoderStreamLanguage();
-
-// 5.3 Decoder stream instructions
-
-// 5.3.1 Insert Count Increment
-const QpackInstruction* InsertCountIncrementInstruction();
-
-// 5.3.2 Header Acknowledgement
-const QpackInstruction* HeaderAcknowledgementInstruction();
-
-// 5.3.3 Stream Cancellation
-const QpackInstruction* StreamCancellationInstruction();
-
-// Decoder stream language.
-const QpackLanguage* QpackDecoderStreamLanguage();
-
-// 5.4.1. Header data prefix instructions
-
-const QpackInstruction* QpackPrefixInstruction();
-
-const QpackLanguage* QpackPrefixLanguage();
-
-// 5.4.2. Request and push stream instructions
-
-// 5.4.2.1. Indexed Header Field
-const QpackInstruction* QpackIndexedHeaderFieldInstruction();
-
-// 5.4.2.2. Indexed Header Field With Post-Base Index
-const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction();
-
-// 5.4.2.3. Literal Header Field With Name Reference
-const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction();
-
-// 5.4.2.4. Literal Header Field With Post-Base Name Reference
-const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction();
-
-// 5.4.2.5. Literal Header Field Without Name Reference
-const QpackInstruction* QpackLiteralHeaderFieldInstruction();
-
-// Request and push stream language.
-const QpackLanguage* QpackRequestStreamLanguage();
-
-// Storage for instruction and field values to be encoded.
-// This class can only be instantiated using factory methods that take exactly
-// the arguments that the corresponding instruction needs.
-class QUIC_EXPORT_PRIVATE QpackInstructionWithValues {
- public:
-  // 5.2 Encoder stream instructions
-  static QpackInstructionWithValues InsertWithNameReference(
-      bool is_static,
-      uint64_t name_index,
-      absl::string_view value);
-  static QpackInstructionWithValues InsertWithoutNameReference(
-      absl::string_view name,
-      absl::string_view value);
-  static QpackInstructionWithValues Duplicate(uint64_t index);
-  static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity);
-
-  // 5.3 Decoder stream instructions
-  static QpackInstructionWithValues InsertCountIncrement(uint64_t increment);
-  static QpackInstructionWithValues HeaderAcknowledgement(uint64_t stream_id);
-  static QpackInstructionWithValues StreamCancellation(uint64_t stream_id);
-
-  // 5.4.1. Header data prefix.  Delta Base is hardcoded to be zero.
-  static QpackInstructionWithValues Prefix(uint64_t required_insert_count);
-
-  // 5.4.2. Request and push stream instructions
-  static QpackInstructionWithValues IndexedHeaderField(bool is_static,
-                                                       uint64_t index);
-  static QpackInstructionWithValues LiteralHeaderFieldNameReference(
-      bool is_static,
-      uint64_t index,
-      absl::string_view value);
-  static QpackInstructionWithValues LiteralHeaderField(absl::string_view name,
-                                                       absl::string_view value);
-
-  const QpackInstruction* instruction() const { return instruction_; }
-  bool s_bit() const { return s_bit_; }
-  uint64_t varint() const { return varint_; }
-  uint64_t varint2() const { return varint2_; }
-  absl::string_view name() const { return name_; }
-  absl::string_view value() const { return value_; }
-
-  // Used by QpackEncoder, because in the first pass it stores absolute indices,
-  // which are converted into relative indices in the second pass after base is
-  // determined.
-  void set_varint(uint64_t varint) { varint_ = varint; }
-
- private:
-  friend test::QpackInstructionWithValuesPeer;
-
-  QpackInstructionWithValues() = default;
-
-  // |*instruction| is not owned.
-  const QpackInstruction* instruction_ = nullptr;
-  bool s_bit_ = false;
-  uint64_t varint_ = 0;
-  uint64_t varint2_ = 0;
-  absl::string_view name_;
-  absl::string_view value_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
diff --git a/quic/core/qpack/qpack_offline_decoder_bin.cc b/quic/core/qpack/qpack_offline_decoder_bin.cc
deleted file mode 100644
index 20f7a62..0000000
--- a/quic/core/qpack/qpack_offline_decoder_bin.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstddef>
-#include <iostream>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/qpack/qpack_offline_decoder.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-int main(int argc, char* argv[]) {
-  const char* usage =
-      "Usage: qpack_offline_decoder input_filename expected_headers_filename "
-      "....";
-  std::vector<std::string> args =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-
-  if (args.size() < 2 || args.size() % 2 != 0) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    return 1;
-  }
-
-  size_t i;
-  size_t success_count = 0;
-  for (i = 0; 2 * i < args.size(); ++i) {
-    const absl::string_view input_filename(args[2 * i]);
-    const absl::string_view expected_headers_filename(args[2 * i + 1]);
-
-    // Every file represents a different connection,
-    // therefore every file needs a fresh decoding context.
-    quic::QpackOfflineDecoder decoder;
-    if (decoder.DecodeAndVerifyOfflineData(input_filename,
-                                           expected_headers_filename)) {
-      ++success_count;
-    }
-  }
-
-  std::cout << "Processed " << i << " pairs of input files, " << success_count
-            << " passed, " << (i - success_count) << " failed." << std::endl;
-
-  // Return success if all input files pass.
-  return (success_count == i) ? 0 : 1;
-}
diff --git a/quic/core/qpack/qpack_progressive_decoder.cc b/quic/core/qpack/qpack_progressive_decoder.cc
deleted file mode 100644
index 12ad7f6..0000000
--- a/quic/core/qpack/qpack_progressive_decoder.cc
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-
-#include <algorithm>
-#include <limits>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_index_conversions.h"
-#include "quic/core/qpack/qpack_instructions.h"
-#include "quic/core/qpack/qpack_required_insert_count.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// The value argument passed to OnHeaderDecoded() is from an entry in the static
-// table.
-constexpr bool kValueFromStaticTable = true;
-
-}  // anonymous namespace
-
-QpackProgressiveDecoder::QpackProgressiveDecoder(
-    QuicStreamId stream_id, BlockedStreamLimitEnforcer* enforcer,
-    DecodingCompletedVisitor* visitor, QpackDecoderHeaderTable* header_table,
-    HeadersHandlerInterface* handler)
-    : stream_id_(stream_id),
-      prefix_decoder_(std::make_unique<QpackInstructionDecoder>(
-          QpackPrefixLanguage(), this)),
-      instruction_decoder_(QpackRequestStreamLanguage(), this),
-      enforcer_(enforcer),
-      visitor_(visitor),
-      header_table_(header_table),
-      handler_(handler),
-      required_insert_count_(0),
-      base_(0),
-      required_insert_count_so_far_(0),
-      prefix_decoded_(false),
-      blocked_(false),
-      decoding_(true),
-      error_detected_(false),
-      cancelled_(false) {}
-
-QpackProgressiveDecoder::~QpackProgressiveDecoder() {
-  if (blocked_ && !cancelled_) {
-    header_table_->UnregisterObserver(required_insert_count_, this);
-  }
-}
-
-void QpackProgressiveDecoder::Decode(absl::string_view data) {
-  QUICHE_DCHECK(decoding_);
-
-  if (data.empty() || error_detected_) {
-    return;
-  }
-
-  // Decode prefix byte by byte until the first (and only) instruction is
-  // decoded.
-  while (!prefix_decoded_) {
-    QUICHE_DCHECK(!blocked_);
-
-    if (!prefix_decoder_->Decode(data.substr(0, 1))) {
-      return;
-    }
-
-    // |prefix_decoder_->Decode()| must return false if an error is detected.
-    QUICHE_DCHECK(!error_detected_);
-
-    data = data.substr(1);
-    if (data.empty()) {
-      return;
-    }
-  }
-
-  if (blocked_) {
-    buffer_.append(data.data(), data.size());
-  } else {
-    QUICHE_DCHECK(buffer_.empty());
-
-    instruction_decoder_.Decode(data);
-  }
-}
-
-void QpackProgressiveDecoder::EndHeaderBlock() {
-  QUICHE_DCHECK(decoding_);
-  decoding_ = false;
-
-  if (!blocked_) {
-    FinishDecoding();
-  }
-}
-
-bool QpackProgressiveDecoder::OnInstructionDecoded(
-    const QpackInstruction* instruction) {
-  if (instruction == QpackPrefixInstruction()) {
-    return DoPrefixInstruction();
-  }
-
-  QUICHE_DCHECK(prefix_decoded_);
-  QUICHE_DCHECK_LE(required_insert_count_,
-                   header_table_->inserted_entry_count());
-
-  if (instruction == QpackIndexedHeaderFieldInstruction()) {
-    return DoIndexedHeaderFieldInstruction();
-  }
-  if (instruction == QpackIndexedHeaderFieldPostBaseInstruction()) {
-    return DoIndexedHeaderFieldPostBaseInstruction();
-  }
-  if (instruction == QpackLiteralHeaderFieldNameReferenceInstruction()) {
-    return DoLiteralHeaderFieldNameReferenceInstruction();
-  }
-  if (instruction == QpackLiteralHeaderFieldPostBaseInstruction()) {
-    return DoLiteralHeaderFieldPostBaseInstruction();
-  }
-  QUICHE_DCHECK_EQ(instruction, QpackLiteralHeaderFieldInstruction());
-  return DoLiteralHeaderFieldInstruction();
-}
-
-void QpackProgressiveDecoder::OnInstructionDecodingError(
-    QpackInstructionDecoder::ErrorCode /* error_code */,
-    absl::string_view error_message) {
-  // Ignore |error_code| and always use QUIC_QPACK_DECOMPRESSION_FAILED to avoid
-  // having to define a new QuicErrorCode for every instruction decoder error.
-  OnError(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
-}
-
-void QpackProgressiveDecoder::OnInsertCountReachedThreshold() {
-  QUICHE_DCHECK(blocked_);
-
-  // Clear |blocked_| before calling instruction_decoder_.Decode() below,
-  // because that might destroy |this| and ~QpackProgressiveDecoder() needs to
-  // know not to call UnregisterObserver().
-  blocked_ = false;
-  enforcer_->OnStreamUnblocked(stream_id_);
-
-  if (!buffer_.empty()) {
-    std::string buffer(std::move(buffer_));
-    buffer_.clear();
-    if (!instruction_decoder_.Decode(buffer)) {
-      // |this| might be destroyed.
-      return;
-    }
-  }
-
-  if (!decoding_) {
-    FinishDecoding();
-  }
-}
-
-void QpackProgressiveDecoder::Cancel() {
-  cancelled_ = true;
-}
-
-bool QpackProgressiveDecoder::DoIndexedHeaderFieldInstruction() {
-  if (!instruction_decoder_.s_bit()) {
-    uint64_t absolute_index;
-    if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
-            instruction_decoder_.varint(), base_, &absolute_index)) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
-      return false;
-    }
-
-    if (absolute_index >= required_insert_count_) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-              "Absolute Index must be smaller than Required Insert Count.");
-      return false;
-    }
-
-    QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
-    required_insert_count_so_far_ =
-        std::max(required_insert_count_so_far_, absolute_index + 1);
-
-    auto entry =
-        header_table_->LookupEntry(/* is_static = */ false, absolute_index);
-    if (!entry) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-              "Dynamic table entry already evicted.");
-      return false;
-    }
-
-    header_table_->set_dynamic_table_entry_referenced();
-    return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
-                           entry->value());
-  }
-
-  auto entry = header_table_->LookupEntry(/* is_static = */ true,
-                                          instruction_decoder_.varint());
-  if (!entry) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
-    return false;
-  }
-
-  return OnHeaderDecoded(kValueFromStaticTable, entry->name(), entry->value());
-}
-
-bool QpackProgressiveDecoder::DoIndexedHeaderFieldPostBaseInstruction() {
-  uint64_t absolute_index;
-  if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
-                                         &absolute_index)) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
-    return false;
-  }
-
-  if (absolute_index >= required_insert_count_) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-            "Absolute Index must be smaller than Required Insert Count.");
-    return false;
-  }
-
-  QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
-  required_insert_count_so_far_ =
-      std::max(required_insert_count_so_far_, absolute_index + 1);
-
-  auto entry =
-      header_table_->LookupEntry(/* is_static = */ false, absolute_index);
-  if (!entry) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-            "Dynamic table entry already evicted.");
-    return false;
-  }
-
-  header_table_->set_dynamic_table_entry_referenced();
-  return OnHeaderDecoded(!kValueFromStaticTable, entry->name(), entry->value());
-}
-
-bool QpackProgressiveDecoder::DoLiteralHeaderFieldNameReferenceInstruction() {
-  if (!instruction_decoder_.s_bit()) {
-    uint64_t absolute_index;
-    if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
-            instruction_decoder_.varint(), base_, &absolute_index)) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
-      return false;
-    }
-
-    if (absolute_index >= required_insert_count_) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-              "Absolute Index must be smaller than Required Insert Count.");
-      return false;
-    }
-
-    QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
-    required_insert_count_so_far_ =
-        std::max(required_insert_count_so_far_, absolute_index + 1);
-
-    auto entry =
-        header_table_->LookupEntry(/* is_static = */ false, absolute_index);
-    if (!entry) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-              "Dynamic table entry already evicted.");
-      return false;
-    }
-
-    header_table_->set_dynamic_table_entry_referenced();
-    return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
-                           instruction_decoder_.value());
-  }
-
-  auto entry = header_table_->LookupEntry(/* is_static = */ true,
-                                          instruction_decoder_.varint());
-  if (!entry) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
-    return false;
-  }
-
-  return OnHeaderDecoded(kValueFromStaticTable, entry->name(),
-                         instruction_decoder_.value());
-}
-
-bool QpackProgressiveDecoder::DoLiteralHeaderFieldPostBaseInstruction() {
-  uint64_t absolute_index;
-  if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
-                                         &absolute_index)) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
-    return false;
-  }
-
-  if (absolute_index >= required_insert_count_) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-            "Absolute Index must be smaller than Required Insert Count.");
-    return false;
-  }
-
-  QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
-  required_insert_count_so_far_ =
-      std::max(required_insert_count_so_far_, absolute_index + 1);
-
-  auto entry =
-      header_table_->LookupEntry(/* is_static = */ false, absolute_index);
-  if (!entry) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-            "Dynamic table entry already evicted.");
-    return false;
-  }
-
-  header_table_->set_dynamic_table_entry_referenced();
-  return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
-                         instruction_decoder_.value());
-}
-
-bool QpackProgressiveDecoder::DoLiteralHeaderFieldInstruction() {
-  return OnHeaderDecoded(!kValueFromStaticTable, instruction_decoder_.name(),
-                         instruction_decoder_.value());
-}
-
-bool QpackProgressiveDecoder::DoPrefixInstruction() {
-  QUICHE_DCHECK(!prefix_decoded_);
-
-  if (!QpackDecodeRequiredInsertCount(
-          prefix_decoder_->varint(), header_table_->max_entries(),
-          header_table_->inserted_entry_count(), &required_insert_count_)) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-            "Error decoding Required Insert Count.");
-    return false;
-  }
-
-  const bool sign = prefix_decoder_->s_bit();
-  const uint64_t delta_base = prefix_decoder_->varint2();
-  if (!DeltaBaseToBase(sign, delta_base, &base_)) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Error calculating Base.");
-    return false;
-  }
-
-  prefix_decoded_ = true;
-
-  if (required_insert_count_ > header_table_->inserted_entry_count()) {
-    if (!enforcer_->OnStreamBlocked(stream_id_)) {
-      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-              "Limit on number of blocked streams exceeded.");
-      return false;
-    }
-    blocked_ = true;
-    header_table_->RegisterObserver(required_insert_count_, this);
-  }
-
-  return true;
-}
-
-bool QpackProgressiveDecoder::OnHeaderDecoded(bool value_from_static_table,
-                                              absl::string_view name,
-                                              absl::string_view value) {
-  // Skip test for static table entries as they are all known to be valid.
-  if (!value_from_static_table) {
-    // According to Section 10.3 of
-    // https://quicwg.org/base-drafts/draft-ietf-quic-http.html,
-    // "[...] HTTP/3 can transport field values that are not valid. While most
-    // values that can be encoded will not alter field parsing, carriage return
-    // (CR, ASCII 0x0d), line feed (LF, ASCII 0x0a), and the zero character
-    // (NUL, ASCII 0x00) might be exploited by an attacker if they are
-    // translated verbatim. Any request or response that contains a character
-    // not permitted in a field value MUST be treated as malformed [...]"
-    for (const auto c : value) {
-      if (c == '\0' || c == '\n' || c == '\r') {
-        OnError(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
-                "Invalid character in field value.");
-        return false;
-      }
-    }
-  }
-
-  handler_->OnHeaderDecoded(name, value);
-  return true;
-}
-
-void QpackProgressiveDecoder::FinishDecoding() {
-  QUICHE_DCHECK(buffer_.empty());
-  QUICHE_DCHECK(!blocked_);
-  QUICHE_DCHECK(!decoding_);
-
-  if (error_detected_) {
-    return;
-  }
-
-  if (!instruction_decoder_.AtInstructionBoundary()) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header block.");
-    return;
-  }
-
-  if (!prefix_decoded_) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header data prefix.");
-    return;
-  }
-
-  if (required_insert_count_ != required_insert_count_so_far_) {
-    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
-            "Required Insert Count too large.");
-    return;
-  }
-
-  visitor_->OnDecodingCompleted(stream_id_, required_insert_count_);
-  handler_->OnDecodingCompleted();
-}
-
-void QpackProgressiveDecoder::OnError(QuicErrorCode error_code,
-                                      absl::string_view error_message) {
-  QUICHE_DCHECK(!error_detected_);
-
-  error_detected_ = true;
-  // Might destroy |this|.
-  handler_->OnDecodingErrorDetected(error_code, error_message);
-}
-
-bool QpackProgressiveDecoder::DeltaBaseToBase(bool sign,
-                                              uint64_t delta_base,
-                                              uint64_t* base) {
-  if (sign) {
-    if (delta_base == std::numeric_limits<uint64_t>::max() ||
-        required_insert_count_ < delta_base + 1) {
-      return false;
-    }
-    *base = required_insert_count_ - delta_base - 1;
-    return true;
-  }
-
-  if (delta_base >
-      std::numeric_limits<uint64_t>::max() - required_insert_count_) {
-    return false;
-  }
-  *base = required_insert_count_ + delta_base;
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_progressive_decoder.h b/quic/core/qpack/qpack_progressive_decoder.h
deleted file mode 100644
index c234b31..0000000
--- a/quic/core/qpack/qpack_progressive_decoder.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_encoder_stream_receiver.h"
-#include "quic/core/qpack/qpack_header_table.h"
-#include "quic/core/qpack/qpack_instruction_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QpackDecoderHeaderTable;
-
-// Class to decode a single header block.
-class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder
-    : public QpackInstructionDecoder::Delegate,
-      public QpackDecoderHeaderTable::Observer {
- public:
-  // Interface for receiving decoded header block from the decoder.
-  class QUIC_EXPORT_PRIVATE HeadersHandlerInterface {
-   public:
-    virtual ~HeadersHandlerInterface() {}
-
-    // Called when a new header name-value pair is decoded.  Multiple values for
-    // a given name will be emitted as multiple calls to OnHeader.
-    virtual void OnHeaderDecoded(absl::string_view name,
-                                 absl::string_view value) = 0;
-
-    // Called when the header block is completely decoded.
-    // Indicates the total number of bytes in this block.
-    // The decoder will not access the handler after this call.
-    // Note that this method might not be called synchronously when the header
-    // block is received on the wire, in case decoding is blocked on receiving
-    // entries on the encoder stream.
-    virtual void OnDecodingCompleted() = 0;
-
-    // Called when a decoding error has occurred.  No other methods will be
-    // called afterwards.  Implementations are allowed to destroy
-    // the QpackProgressiveDecoder instance synchronously.
-    virtual void OnDecodingErrorDetected(QuicErrorCode error_code,
-                                         absl::string_view error_message) = 0;
-  };
-
-  // Interface for keeping track of blocked streams for the purpose of enforcing
-  // the limit communicated to peer via QPACK_BLOCKED_STREAMS settings.
-  class QUIC_EXPORT_PRIVATE BlockedStreamLimitEnforcer {
-   public:
-    virtual ~BlockedStreamLimitEnforcer() {}
-
-    // Called when the stream becomes blocked.  Returns true if allowed. Returns
-    // false if limit is violated, in which case QpackProgressiveDecoder signals
-    // an error.
-    // Stream must not be already blocked.
-    virtual bool OnStreamBlocked(QuicStreamId stream_id) = 0;
-
-    // Called when the stream becomes unblocked.
-    // Stream must be blocked.
-    virtual void OnStreamUnblocked(QuicStreamId stream_id) = 0;
-  };
-
-  // Visitor to be notified when decoding is completed.
-  class QUIC_EXPORT_PRIVATE DecodingCompletedVisitor {
-   public:
-    virtual ~DecodingCompletedVisitor() = default;
-
-    // Called when decoding is completed, with Required Insert Count of the
-    // decoded header block.  Required Insert Count is defined at
-    // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams.
-    virtual void OnDecodingCompleted(QuicStreamId stream_id,
-                                     uint64_t required_insert_count) = 0;
-  };
-
-  QpackProgressiveDecoder() = delete;
-  QpackProgressiveDecoder(QuicStreamId stream_id,
-                          BlockedStreamLimitEnforcer* enforcer,
-                          DecodingCompletedVisitor* visitor,
-                          QpackDecoderHeaderTable* header_table,
-                          HeadersHandlerInterface* handler);
-  QpackProgressiveDecoder(const QpackProgressiveDecoder&) = delete;
-  QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
-  ~QpackProgressiveDecoder() override;
-
-  // Provide a data fragment to decode.
-  void Decode(absl::string_view data);
-
-  // Signal that the entire header block has been received and passed in
-  // through Decode().  No methods must be called afterwards.
-  void EndHeaderBlock();
-
-  // QpackInstructionDecoder::Delegate implementation.
-  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
-  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
-                                  absl::string_view error_message) override;
-
-  // QpackDecoderHeaderTable::Observer implementation.
-  void OnInsertCountReachedThreshold() override;
-  void Cancel() override;
-
- private:
-  bool DoIndexedHeaderFieldInstruction();
-  bool DoIndexedHeaderFieldPostBaseInstruction();
-  bool DoLiteralHeaderFieldNameReferenceInstruction();
-  bool DoLiteralHeaderFieldPostBaseInstruction();
-  bool DoLiteralHeaderFieldInstruction();
-  bool DoPrefixInstruction();
-
-  // Called when an entry is decoded.  Performs validation and calls
-  // HeadersHandlerInterface::OnHeaderDecoded() or OnError() as needed.  Returns
-  // true if header value is valid, false otherwise.  Skips validation if
-  // |value_from_static_table| is true, because static table entries are always
-  // valid.
-  bool OnHeaderDecoded(bool value_from_static_table, absl::string_view name,
-                       absl::string_view value);
-
-  // Called as soon as EndHeaderBlock() is called and decoding is not blocked.
-  void FinishDecoding();
-
-  // Called on error.
-  void OnError(QuicErrorCode error_code, absl::string_view error_message);
-
-  // Calculates Base from |required_insert_count_|, which must be set before
-  // calling this method, and sign bit and Delta Base in the Header Data Prefix,
-  // which are passed in as arguments.  Returns true on success, false on
-  // failure due to overflow/underflow.
-  bool DeltaBaseToBase(bool sign, uint64_t delta_base, uint64_t* base);
-
-  const QuicStreamId stream_id_;
-
-  // |prefix_decoder_| only decodes a handful of bytes then it can be
-  // destroyed to conserve memory.  |instruction_decoder_|, on the other hand,
-  // is used until the entire header block is decoded.
-  std::unique_ptr<QpackInstructionDecoder> prefix_decoder_;
-  QpackInstructionDecoder instruction_decoder_;
-
-  BlockedStreamLimitEnforcer* const enforcer_;
-  DecodingCompletedVisitor* const visitor_;
-  QpackDecoderHeaderTable* const header_table_;
-  HeadersHandlerInterface* const handler_;
-
-  // Required Insert Count and Base are decoded from the Header Data Prefix.
-  uint64_t required_insert_count_;
-  uint64_t base_;
-
-  // Required Insert Count is one larger than the largest absolute index of all
-  // referenced dynamic table entries, or zero if no dynamic table entries are
-  // referenced.  |required_insert_count_so_far_| starts out as zero and keeps
-  // track of the Required Insert Count based on entries decoded so far.
-  // After decoding is completed, it is compared to |required_insert_count_|.
-  uint64_t required_insert_count_so_far_;
-
-  // False until prefix is fully read and decoded.
-  bool prefix_decoded_;
-
-  // True if waiting for dynamic table entries to arrive.
-  bool blocked_;
-
-  // Buffer the entire header block after the prefix while decoding is blocked.
-  std::string buffer_;
-
-  // True until EndHeaderBlock() is called.
-  bool decoding_;
-
-  // True if a decoding error has been detected.
-  bool error_detected_;
-
-  // True if QpackDecoderHeaderTable has been destroyed
-  // while decoding is still blocked.
-  bool cancelled_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
diff --git a/quic/core/qpack/qpack_receive_stream.cc b/quic/core/qpack/qpack_receive_stream.cc
deleted file mode 100644
index 1f75919..0000000
--- a/quic/core/qpack/qpack_receive_stream.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_receive_stream.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-
-namespace quic {
-QpackReceiveStream::QpackReceiveStream(PendingStream* pending,
-                                       QuicSession* session,
-                                       QpackStreamReceiver* receiver)
-    : QuicStream(pending, session, /*is_static=*/true), receiver_(receiver) {}
-
-void QpackReceiveStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
-  stream_delegate()->OnStreamError(
-      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-      "RESET_STREAM received for QPACK receive stream");
-}
-
-void QpackReceiveStream::OnDataAvailable() {
-  iovec iov;
-  while (!reading_stopped() && sequencer()->GetReadableRegion(&iov)) {
-    QUICHE_DCHECK(!sequencer()->IsClosed());
-
-    receiver_->Decode(absl::string_view(
-        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
-    sequencer()->MarkConsumed(iov.iov_len);
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_receive_stream.h b/quic/core/qpack/qpack_receive_stream.h
deleted file mode 100644
index 6c04b94..0000000
--- a/quic/core/qpack/qpack_receive_stream.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
-
-#include "quic/core/qpack/qpack_stream_receiver.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicSession;
-
-// QPACK 4.2.1 Encoder and Decoder Streams.
-// The QPACK receive stream is peer initiated and is read only.
-class QUIC_EXPORT_PRIVATE QpackReceiveStream : public QuicStream {
- public:
-  // Construct receive stream from pending stream, the |pending| object needs
-  // to be deleted after the construction.
-  QpackReceiveStream(PendingStream* pending,
-                     QuicSession* session,
-                     QpackStreamReceiver* receiver);
-  QpackReceiveStream(const QpackReceiveStream&) = delete;
-  QpackReceiveStream& operator=(const QpackReceiveStream&) = delete;
-  ~QpackReceiveStream() override = default;
-
-  // Overriding QuicStream::OnStreamReset to make sure QPACK stream is never
-  // closed before connection.
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
-  // Implementation of QuicStream.
-  void OnDataAvailable() override;
-
- private:
-  QpackStreamReceiver* receiver_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
diff --git a/quic/core/qpack/qpack_receive_stream_test.cc b/quic/core/qpack/qpack_receive_stream_test.cc
deleted file mode 100644
index cc0e251..0000000
--- a/quic/core/qpack/qpack_receive_stream_test.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_receive_stream.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::StrictMock;
-
-struct TestParams {
-  TestParams(const ParsedQuicVersion& version, Perspective perspective)
-      : version(version), perspective(perspective) {
-    QUIC_LOG(INFO) << "TestParams: version: "
-                   << ParsedQuicVersionToString(version)
-                   << ", perspective: " << perspective;
-  }
-
-  TestParams(const TestParams& other)
-      : version(other.version), perspective(other.perspective) {}
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (const auto& version : AllSupportedVersions()) {
-    if (!VersionUsesHttp3(version.transport_version)) {
-      continue;
-    }
-    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
-      params.emplace_back(version, p);
-    }
-  }
-  return params;
-}
-
-class QpackReceiveStreamTest : public QuicTestWithParam<TestParams> {
- public:
-  QpackReceiveStreamTest()
-      : connection_(new StrictMock<MockQuicConnection>(
-            &helper_,
-            &alarm_factory_,
-            perspective(),
-            SupportedVersions(GetParam().version))),
-        session_(connection_) {
-    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    session_.Initialize();
-    QuicStreamId id = perspective() == Perspective::IS_SERVER
-                          ? GetNthClientInitiatedUnidirectionalStreamId(
-                                session_.transport_version(), 3)
-                          : GetNthServerInitiatedUnidirectionalStreamId(
-                                session_.transport_version(), 3);
-    char type[] = {0x03};
-    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
-    session_.OnStreamFrame(data1);
-    qpack_receive_stream_ =
-        QuicSpdySessionPeer::GetQpackDecoderReceiveStream(&session_);
-  }
-
-  Perspective perspective() const { return GetParam().perspective; }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  StrictMock<MockQuicSpdySession> session_;
-  QpackReceiveStream* qpack_receive_stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QpackReceiveStreamTest,
-                         ::testing::ValuesIn(GetTestParams()));
-
-TEST_P(QpackReceiveStreamTest, ResetQpackReceiveStream) {
-  EXPECT_TRUE(qpack_receive_stream_->is_static());
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
-                               qpack_receive_stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
-  qpack_receive_stream_->OnStreamReset(rst_frame);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_required_insert_count.cc b/quic/core/qpack/qpack_required_insert_count.cc
deleted file mode 100644
index 6e17b24..0000000
--- a/quic/core/qpack/qpack_required_insert_count.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_required_insert_count.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-uint64_t QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
-                                        uint64_t max_entries) {
-  if (required_insert_count == 0) {
-    return 0;
-  }
-
-  return required_insert_count % (2 * max_entries) + 1;
-}
-
-bool QpackDecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
-                                    uint64_t max_entries,
-                                    uint64_t total_number_of_inserts,
-                                    uint64_t* required_insert_count) {
-  if (encoded_required_insert_count == 0) {
-    *required_insert_count = 0;
-    return true;
-  }
-
-  // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
-  // precluding all calculations in this method from overflowing.
-  QUICHE_DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
-
-  if (encoded_required_insert_count > 2 * max_entries) {
-    return false;
-  }
-
-  *required_insert_count = encoded_required_insert_count - 1;
-  QUICHE_DCHECK_LT(*required_insert_count,
-                   std::numeric_limits<uint64_t>::max() / 16);
-
-  uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
-  QUICHE_DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
-
-  if (current_wrapped >= *required_insert_count + max_entries) {
-    // Required Insert Count wrapped around 1 extra time.
-    *required_insert_count += 2 * max_entries;
-  } else if (current_wrapped + max_entries < *required_insert_count) {
-    // Decoder wrapped around 1 extra time.
-    current_wrapped += 2 * max_entries;
-  }
-
-  if (*required_insert_count >
-      std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
-    return false;
-  }
-
-  *required_insert_count += total_number_of_inserts;
-
-  // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
-  if (current_wrapped >= *required_insert_count) {
-    return false;
-  }
-
-  *required_insert_count -= current_wrapped;
-
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_required_insert_count.h b/quic/core/qpack/qpack_required_insert_count.h
deleted file mode 100644
index 60b1f83..0000000
--- a/quic/core/qpack/qpack_required_insert_count.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
-#define QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Calculate Encoded Required Insert Count from Required Insert Count and
-// MaxEntries according to
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.
-QUIC_EXPORT_PRIVATE uint64_t
-QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
-                               uint64_t max_entries);
-
-// Calculate Required Insert Count from Encoded Required Insert Count,
-// MaxEntries, and total number of dynamic table insertions according to
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.  Returns true
-// on success, false on invalid input or overflow/underflow.
-QUIC_EXPORT_PRIVATE bool QpackDecodeRequiredInsertCount(
-    uint64_t encoded_required_insert_count,
-    uint64_t max_entries,
-    uint64_t total_number_of_inserts,
-    uint64_t* required_insert_count);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
diff --git a/quic/core/qpack/qpack_required_insert_count_test.cc b/quic/core/qpack/qpack_required_insert_count_test.cc
deleted file mode 100644
index 3fa7146..0000000
--- a/quic/core/qpack/qpack_required_insert_count_test.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_required_insert_count.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QpackRequiredInsertCountTest, QpackEncodeRequiredInsertCount) {
-  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 0));
-  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 8));
-  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 1024));
-
-  EXPECT_EQ(2u, QpackEncodeRequiredInsertCount(1, 8));
-  EXPECT_EQ(5u, QpackEncodeRequiredInsertCount(20, 8));
-  EXPECT_EQ(7u, QpackEncodeRequiredInsertCount(106, 10));
-}
-
-// For testing valid decodings, the Encoded Required Insert Count is calculated
-// from Required Insert Count, so that there is an expected value to compare
-// the decoded value against, and so that intricate inequalities can be
-// documented.
-struct {
-  uint64_t required_insert_count;
-  uint64_t max_entries;
-  uint64_t total_number_of_inserts;
-} kTestData[] = {
-    // Maximum dynamic table capacity is zero.
-    {0, 0, 0},
-    // No dynamic entries in header.
-    {0, 100, 0},
-    {0, 100, 500},
-    // Required Insert Count has not wrapped around yet, no entries evicted.
-    {15, 100, 25},
-    {20, 100, 10},
-    // Required Insert Count has not wrapped around yet, some entries evicted.
-    {90, 100, 110},
-    // Required Insert Count has wrapped around.
-    {234, 100, 180},
-    // Required Insert Count has wrapped around many times.
-    {5678, 100, 5701},
-    // Lowest and highest possible Required Insert Count values
-    // for given MaxEntries and total number of insertions.
-    {401, 100, 500},
-    {600, 100, 500}};
-
-TEST(QpackRequiredInsertCountTest, QpackDecodeRequiredInsertCount) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
-    const uint64_t required_insert_count = kTestData[i].required_insert_count;
-    const uint64_t max_entries = kTestData[i].max_entries;
-    const uint64_t total_number_of_inserts =
-        kTestData[i].total_number_of_inserts;
-
-    if (required_insert_count != 0) {
-      // Dynamic entries cannot be referenced if dynamic table capacity is zero.
-      ASSERT_LT(0u, max_entries) << i;
-      // Entry |total_number_of_inserts - 1 - max_entries| and earlier entries
-      // are evicted.  Entry |required_insert_count - 1| is referenced.  No
-      // evicted entry can be referenced.
-      ASSERT_LT(total_number_of_inserts, required_insert_count + max_entries)
-          << i;
-      // Entry |required_insert_count - 1 - max_entries| and earlier entries are
-      // evicted, entry |total_number_of_inserts - 1| is the last acknowledged
-      // entry.  Every evicted entry must be acknowledged.
-      ASSERT_LE(required_insert_count, total_number_of_inserts + max_entries)
-          << i;
-    }
-
-    uint64_t encoded_required_insert_count =
-        QpackEncodeRequiredInsertCount(required_insert_count, max_entries);
-
-    // Initialize to a value different from the expected output to confirm that
-    // QpackDecodeRequiredInsertCount() modifies the value of
-    // |decoded_required_insert_count|.
-    uint64_t decoded_required_insert_count = required_insert_count + 1;
-    EXPECT_TRUE(QpackDecodeRequiredInsertCount(
-        encoded_required_insert_count, max_entries, total_number_of_inserts,
-        &decoded_required_insert_count))
-        << i;
-
-    EXPECT_EQ(decoded_required_insert_count, required_insert_count) << i;
-  }
-}
-
-// Failures are tested with hardcoded values for encoded required insert count,
-// to provide test coverage for values that would never be produced by a well
-// behaved encoding function.
-struct {
-  uint64_t encoded_required_insert_count;
-  uint64_t max_entries;
-  uint64_t total_number_of_inserts;
-} kInvalidTestData[] = {
-    // Maximum dynamic table capacity is zero, yet header block
-    // claims to have a reference to a dynamic table entry.
-    {1, 0, 0},
-    {9, 0, 0},
-    // Examples from
-    // https://github.com/quicwg/base-drafts/issues/2112#issue-389626872.
-    {1, 10, 2},
-    {18, 10, 2},
-    // Encoded Required Insert Count value too small or too large
-    // for given MaxEntries and total number of insertions.
-    {400, 100, 500},
-    {601, 100, 500}};
-
-TEST(QpackRequiredInsertCountTest, DecodeRequiredInsertCountError) {
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kInvalidTestData); ++i) {
-    uint64_t decoded_required_insert_count = 0;
-    EXPECT_FALSE(QpackDecodeRequiredInsertCount(
-        kInvalidTestData[i].encoded_required_insert_count,
-        kInvalidTestData[i].max_entries,
-        kInvalidTestData[i].total_number_of_inserts,
-        &decoded_required_insert_count))
-        << i;
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_round_trip_test.cc b/quic/core/qpack/qpack_round_trip_test.cc
deleted file mode 100644
index 35530d0..0000000
--- a/quic/core/qpack/qpack_round_trip_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-#include <tuple>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-using ::testing::Values;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QpackRoundTripTest : public QuicTestWithParam<FragmentMode> {
- public:
-  QpackRoundTripTest() = default;
-  ~QpackRoundTripTest() override = default;
-
-  spdy::Http2HeaderBlock EncodeThenDecode(
-      const spdy::Http2HeaderBlock& header_list) {
-    NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
-    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
-    QpackEncoder encoder(&decoder_stream_error_delegate);
-    encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate);
-    std::string encoded_header_block =
-        encoder.EncodeHeaderList(/* stream_id = */ 1, header_list, nullptr);
-
-    TestHeadersHandler handler;
-    NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;
-    NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
-    // TODO(b/112770235): Test dynamic table and blocked streams.
-    QpackDecode(
-        /* maximum_dynamic_table_capacity = */ 0,
-        /* maximum_blocked_streams = */ 0, &encoder_stream_error_delegate,
-        &decoder_stream_sender_delegate, &handler,
-        FragmentModeToFragmentSizeGenerator(GetParam()), encoded_header_block);
-
-    EXPECT_TRUE(handler.decoding_completed());
-    EXPECT_FALSE(handler.decoding_error_detected());
-
-    return handler.ReleaseHeaderList();
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         QpackRoundTripTest,
-                         Values(FragmentMode::kSingleChunk,
-                                FragmentMode::kOctetByOctet));
-
-TEST_P(QpackRoundTripTest, Empty) {
-  spdy::Http2HeaderBlock header_list;
-  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-  EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, EmptyName) {
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "bar";
-  header_list[""] = "bar";
-
-  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-  EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, EmptyValue) {
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "";
-  header_list[""] = "";
-
-  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-  EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, MultipleWithLongEntries) {
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = "bar";
-  header_list[":path"] = "/";
-  header_list["foobaar"] = std::string(127, 'Z');
-  header_list[std::string(1000, 'b')] = std::string(1000, 'c');
-
-  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-  EXPECT_EQ(header_list, output);
-}
-
-TEST_P(QpackRoundTripTest, StaticTable) {
-  {
-    spdy::Http2HeaderBlock header_list;
-    header_list[":method"] = "GET";
-    header_list["accept-encoding"] = "gzip, deflate";
-    header_list["cache-control"] = "";
-    header_list["foo"] = "bar";
-    header_list[":path"] = "/";
-
-    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-    EXPECT_EQ(header_list, output);
-  }
-  {
-    spdy::Http2HeaderBlock header_list;
-    header_list[":method"] = "POST";
-    header_list["accept-encoding"] = "brotli";
-    header_list["cache-control"] = "foo";
-    header_list["foo"] = "bar";
-    header_list[":path"] = "/";
-
-    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-    EXPECT_EQ(header_list, output);
-  }
-  {
-    spdy::Http2HeaderBlock header_list;
-    header_list[":method"] = "CONNECT";
-    header_list["accept-encoding"] = "";
-    header_list["foo"] = "bar";
-    header_list[":path"] = "/";
-
-    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-    EXPECT_EQ(header_list, output);
-  }
-}
-
-TEST_P(QpackRoundTripTest, ValueHasNullCharacter) {
-  spdy::Http2HeaderBlock header_list;
-  header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
-
-  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
-  EXPECT_EQ(header_list, output);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_send_stream.cc b/quic/core/qpack/qpack_send_stream.cc
deleted file mode 100644
index 3e921d8..0000000
--- a/quic/core/qpack/qpack_send_stream.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_send_stream.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-
-namespace quic {
-QpackSendStream::QpackSendStream(QuicStreamId id,
-                                 QuicSession* session,
-                                 uint64_t http3_stream_type)
-    : QuicStream(id, session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
-      http3_stream_type_(http3_stream_type),
-      stream_type_sent_(false) {}
-
-void QpackSendStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
-  QUIC_BUG(quic_bug_10805_1)
-      << "OnStreamReset() called for write unidirectional stream.";
-}
-
-bool QpackSendStream::OnStopSending(QuicResetStreamError /* code */) {
-  stream_delegate()->OnStreamError(
-      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
-      "STOP_SENDING received for QPACK send stream");
-  return false;
-}
-
-void QpackSendStream::WriteStreamData(absl::string_view data) {
-  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-  MaybeSendStreamType();
-  WriteOrBufferData(data, false, nullptr);
-}
-
-uint64_t QpackSendStream::NumBytesBuffered() const {
-  return QuicStream::BufferedDataBytes();
-}
-
-void QpackSendStream::MaybeSendStreamType() {
-  if (!stream_type_sent_) {
-    char type[sizeof(http3_stream_type_)];
-    QuicDataWriter writer(ABSL_ARRAYSIZE(type), type);
-    writer.WriteVarInt62(http3_stream_type_);
-    WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
-                      nullptr);
-    stream_type_sent_ = true;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_send_stream.h b/quic/core/qpack/qpack_send_stream.h
deleted file mode 100644
index 72dc677..0000000
--- a/quic/core/qpack/qpack_send_stream.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QuicSession;
-
-// QPACK 4.2.1 Encoder and Decoder Streams.
-// The QPACK send stream is self initiated and is write only.
-class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream,
-                                            public QpackStreamSenderDelegate {
- public:
-  // |session| can't be nullptr, and the ownership is not passed. |session| owns
-  // this stream.
-  QpackSendStream(QuicStreamId id,
-                  QuicSession* session,
-                  uint64_t http3_stream_type);
-  QpackSendStream(const QpackSendStream&) = delete;
-  QpackSendStream& operator=(const QpackSendStream&) = delete;
-  ~QpackSendStream() override = default;
-
-  // Overriding QuicStream::OnStopSending() to make sure QPACK stream is never
-  // closed before connection.
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-  bool OnStopSending(QuicResetStreamError code) override;
-
-  // The send QPACK stream is write unidirectional, so this method
-  // should never be called.
-  void OnDataAvailable() override { QUIC_NOTREACHED(); }
-
-  // Writes the instructions to peer. The stream type will be sent
-  // before the first instruction so that the peer can open an qpack stream.
-  void WriteStreamData(absl::string_view data) override;
-
-  // Return the number of bytes buffered due to underlying stream being blocked.
-  uint64_t NumBytesBuffered() const override;
-
-  // TODO(b/112770235): Remove this method once QuicStreamIdManager supports
-  // creating HTTP/3 unidirectional streams dynamically.
-  void MaybeSendStreamType();
-
- private:
-  const uint64_t http3_stream_type_;
-  bool stream_type_sent_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
diff --git a/quic/core/qpack/qpack_send_stream_test.cc b/quic/core/qpack/qpack_send_stream_test.cc
deleted file mode 100644
index 5a98951..0000000
--- a/quic/core/qpack/qpack_send_stream_test.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_send_stream.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_constants.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-
-struct TestParams {
-  TestParams(const ParsedQuicVersion& version, Perspective perspective)
-      : version(version), perspective(perspective) {
-    QUIC_LOG(INFO) << "TestParams: version: "
-                   << ParsedQuicVersionToString(version)
-                   << ", perspective: " << perspective;
-  }
-
-  TestParams(const TestParams& other)
-      : version(other.version), perspective(other.perspective) {}
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& tp) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(tp.version), "_",
-      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (const auto& version : AllSupportedVersions()) {
-    if (!VersionUsesHttp3(version.transport_version)) {
-      continue;
-    }
-    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
-      params.emplace_back(version, p);
-    }
-  }
-  return params;
-}
-
-class QpackSendStreamTest : public QuicTestWithParam<TestParams> {
- public:
-  QpackSendStreamTest()
-      : connection_(new StrictMock<MockQuicConnection>(
-            &helper_,
-            &alarm_factory_,
-            perspective(),
-            SupportedVersions(GetParam().version))),
-        session_(connection_) {
-    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    session_.Initialize();
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    if (connection_->version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(connection_);
-    }
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
-    session_.OnConfigNegotiated();
-
-    qpack_send_stream_ =
-        QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
-
-    ON_CALL(session_, WritevData(_, _, _, _, _, _))
-        .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  }
-
-  Perspective perspective() const { return GetParam().perspective; }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  StrictMock<MockQuicSpdySession> session_;
-  QpackSendStream* qpack_send_stream_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QpackSendStreamTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) {
-  std::string data = "data";
-  EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _));
-  EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
-  qpack_send_stream_->WriteStreamData(absl::string_view(data));
-
-  EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
-  qpack_send_stream_->WriteStreamData(absl::string_view(data));
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
-  qpack_send_stream_->MaybeSendStreamType();
-}
-
-TEST_P(QpackSendStreamTest, StopSendingQpackStream) {
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
-  qpack_send_stream_->OnStopSending(
-      QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QpackSendStreamTest, ReceiveDataOnSendStream) {
-  QuicStreamFrame frame(qpack_send_stream_->id(), false, 0, "test");
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
-  qpack_send_stream_->OnStreamFrame(frame);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_static_table.cc b/quic/core/qpack/qpack_static_table.cc
deleted file mode 100644
index 869d09c..0000000
--- a/quic/core/qpack/qpack_static_table.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_static_table.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// The "constructor" for a QpackStaticEntry that computes the lengths at
-// compile time.
-#define STATIC_ENTRY(name, value) \
-  { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 }
-
-const std::vector<QpackStaticEntry>& QpackStaticTableVector() {
-  static const auto* kQpackStaticTable = new std::vector<QpackStaticEntry>{
-      STATIC_ENTRY(":authority", ""),                                     // 0
-      STATIC_ENTRY(":path", "/"),                                         // 1
-      STATIC_ENTRY("age", "0"),                                           // 2
-      STATIC_ENTRY("content-disposition", ""),                            // 3
-      STATIC_ENTRY("content-length", "0"),                                // 4
-      STATIC_ENTRY("cookie", ""),                                         // 5
-      STATIC_ENTRY("date", ""),                                           // 6
-      STATIC_ENTRY("etag", ""),                                           // 7
-      STATIC_ENTRY("if-modified-since", ""),                              // 8
-      STATIC_ENTRY("if-none-match", ""),                                  // 9
-      STATIC_ENTRY("last-modified", ""),                                  // 10
-      STATIC_ENTRY("link", ""),                                           // 11
-      STATIC_ENTRY("location", ""),                                       // 12
-      STATIC_ENTRY("referer", ""),                                        // 13
-      STATIC_ENTRY("set-cookie", ""),                                     // 14
-      STATIC_ENTRY(":method", "CONNECT"),                                 // 15
-      STATIC_ENTRY(":method", "DELETE"),                                  // 16
-      STATIC_ENTRY(":method", "GET"),                                     // 17
-      STATIC_ENTRY(":method", "HEAD"),                                    // 18
-      STATIC_ENTRY(":method", "OPTIONS"),                                 // 19
-      STATIC_ENTRY(":method", "POST"),                                    // 20
-      STATIC_ENTRY(":method", "PUT"),                                     // 21
-      STATIC_ENTRY(":scheme", "http"),                                    // 22
-      STATIC_ENTRY(":scheme", "https"),                                   // 23
-      STATIC_ENTRY(":status", "103"),                                     // 24
-      STATIC_ENTRY(":status", "200"),                                     // 25
-      STATIC_ENTRY(":status", "304"),                                     // 26
-      STATIC_ENTRY(":status", "404"),                                     // 27
-      STATIC_ENTRY(":status", "503"),                                     // 28
-      STATIC_ENTRY("accept", "*/*"),                                      // 29
-      STATIC_ENTRY("accept", "application/dns-message"),                  // 30
-      STATIC_ENTRY("accept-encoding", "gzip, deflate, br"),               // 31
-      STATIC_ENTRY("accept-ranges", "bytes"),                             // 32
-      STATIC_ENTRY("access-control-allow-headers", "cache-control"),      // 33
-      STATIC_ENTRY("access-control-allow-headers", "content-type"),       // 35
-      STATIC_ENTRY("access-control-allow-origin", "*"),                   // 35
-      STATIC_ENTRY("cache-control", "max-age=0"),                         // 36
-      STATIC_ENTRY("cache-control", "max-age=2592000"),                   // 37
-      STATIC_ENTRY("cache-control", "max-age=604800"),                    // 38
-      STATIC_ENTRY("cache-control", "no-cache"),                          // 39
-      STATIC_ENTRY("cache-control", "no-store"),                          // 40
-      STATIC_ENTRY("cache-control", "public, max-age=31536000"),          // 41
-      STATIC_ENTRY("content-encoding", "br"),                             // 42
-      STATIC_ENTRY("content-encoding", "gzip"),                           // 43
-      STATIC_ENTRY("content-type", "application/dns-message"),            // 44
-      STATIC_ENTRY("content-type", "application/javascript"),             // 45
-      STATIC_ENTRY("content-type", "application/json"),                   // 46
-      STATIC_ENTRY("content-type", "application/x-www-form-urlencoded"),  // 47
-      STATIC_ENTRY("content-type", "image/gif"),                          // 48
-      STATIC_ENTRY("content-type", "image/jpeg"),                         // 49
-      STATIC_ENTRY("content-type", "image/png"),                          // 50
-      STATIC_ENTRY("content-type", "text/css"),                           // 51
-      STATIC_ENTRY("content-type", "text/html; charset=utf-8"),           // 52
-      STATIC_ENTRY("content-type", "text/plain"),                         // 53
-      STATIC_ENTRY("content-type", "text/plain;charset=utf-8"),           // 54
-      STATIC_ENTRY("range", "bytes=0-"),                                  // 55
-      STATIC_ENTRY("strict-transport-security", "max-age=31536000"),      // 56
-      STATIC_ENTRY("strict-transport-security",
-                   "max-age=31536000; includesubdomains"),  // 57
-      STATIC_ENTRY("strict-transport-security",
-                   "max-age=31536000; includesubdomains; preload"),        // 58
-      STATIC_ENTRY("vary", "accept-encoding"),                             // 59
-      STATIC_ENTRY("vary", "origin"),                                      // 60
-      STATIC_ENTRY("x-content-type-options", "nosniff"),                   // 61
-      STATIC_ENTRY("x-xss-protection", "1; mode=block"),                   // 62
-      STATIC_ENTRY(":status", "100"),                                      // 63
-      STATIC_ENTRY(":status", "204"),                                      // 64
-      STATIC_ENTRY(":status", "206"),                                      // 65
-      STATIC_ENTRY(":status", "302"),                                      // 66
-      STATIC_ENTRY(":status", "400"),                                      // 67
-      STATIC_ENTRY(":status", "403"),                                      // 68
-      STATIC_ENTRY(":status", "421"),                                      // 69
-      STATIC_ENTRY(":status", "425"),                                      // 70
-      STATIC_ENTRY(":status", "500"),                                      // 71
-      STATIC_ENTRY("accept-language", ""),                                 // 72
-      STATIC_ENTRY("access-control-allow-credentials", "FALSE"),           // 73
-      STATIC_ENTRY("access-control-allow-credentials", "TRUE"),            // 74
-      STATIC_ENTRY("access-control-allow-headers", "*"),                   // 75
-      STATIC_ENTRY("access-control-allow-methods", "get"),                 // 76
-      STATIC_ENTRY("access-control-allow-methods", "get, post, options"),  // 77
-      STATIC_ENTRY("access-control-allow-methods", "options"),             // 78
-      STATIC_ENTRY("access-control-expose-headers", "content-length"),     // 79
-      STATIC_ENTRY("access-control-request-headers", "content-type"),      // 80
-      STATIC_ENTRY("access-control-request-method", "get"),                // 81
-      STATIC_ENTRY("access-control-request-method", "post"),               // 82
-      STATIC_ENTRY("alt-svc", "clear"),                                    // 83
-      STATIC_ENTRY("authorization", ""),                                   // 84
-      STATIC_ENTRY(
-          "content-security-policy",
-          "script-src 'none'; object-src 'none'; base-uri 'none'"),  // 85
-      STATIC_ENTRY("early-data", "1"),                               // 86
-      STATIC_ENTRY("expect-ct", ""),                                 // 87
-      STATIC_ENTRY("forwarded", ""),                                 // 88
-      STATIC_ENTRY("if-range", ""),                                  // 89
-      STATIC_ENTRY("origin", ""),                                    // 90
-      STATIC_ENTRY("purpose", "prefetch"),                           // 91
-      STATIC_ENTRY("server", ""),                                    // 92
-      STATIC_ENTRY("timing-allow-origin", "*"),                      // 93
-      STATIC_ENTRY("upgrade-insecure-requests", "1"),                // 94
-      STATIC_ENTRY("user-agent", ""),                                // 95
-      STATIC_ENTRY("x-forwarded-for", ""),                           // 96
-      STATIC_ENTRY("x-frame-options", "deny"),                       // 97
-      STATIC_ENTRY("x-frame-options", "sameorigin"),                 // 98
-  };
-  return *kQpackStaticTable;
-}
-
-#undef STATIC_ENTRY
-
-const QpackStaticTable& ObtainQpackStaticTable() {
-  static const QpackStaticTable* const shared_static_table = []() {
-    auto* table = new QpackStaticTable();
-    table->Initialize(QpackStaticTableVector().data(),
-                      QpackStaticTableVector().size());
-    QUICHE_CHECK(table->IsInitialized());
-    return table;
-  }();
-  return *shared_static_table;
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_static_table.h b/quic/core/qpack/qpack_static_table.h
deleted file mode 100644
index 7f03cf9..0000000
--- a/quic/core/qpack/qpack_static_table.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
-
-#include <vector>
-
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_static_table.h"
-
-namespace quic {
-
-using QpackStaticEntry = spdy::HpackStaticEntry;
-using QpackStaticTable = spdy::HpackStaticTable;
-
-// QPACK static table defined at
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#static-table.
-QUIC_EXPORT_PRIVATE const std::vector<QpackStaticEntry>&
-QpackStaticTableVector();
-
-// Returns a QpackStaticTable instance initialized with kQpackStaticTable.
-// The instance is read-only, has static lifetime, and is safe to share amoung
-// threads. This function is thread-safe.
-QUIC_EXPORT_PRIVATE const QpackStaticTable& ObtainQpackStaticTable();
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
diff --git a/quic/core/qpack/qpack_static_table_test.cc b/quic/core/qpack/qpack_static_table_test.cc
deleted file mode 100644
index 53ab0f4..0000000
--- a/quic/core/qpack/qpack_static_table_test.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/qpack_static_table.h"
-
-#include <set>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-// Check that an initialized instance has the right number of entries.
-TEST(QpackStaticTableTest, Initialize) {
-  QpackStaticTable table;
-  EXPECT_FALSE(table.IsInitialized());
-
-  table.Initialize(QpackStaticTableVector().data(),
-                   QpackStaticTableVector().size());
-  EXPECT_TRUE(table.IsInitialized());
-
-  const auto& static_entries = table.GetStaticEntries();
-  EXPECT_EQ(QpackStaticTableVector().size(), static_entries.size());
-
-  const auto& static_index = table.GetStaticIndex();
-  EXPECT_EQ(QpackStaticTableVector().size(), static_index.size());
-
-  const auto& static_name_index = table.GetStaticNameIndex();
-  // Count distinct names in static table.
-  std::set<absl::string_view> names;
-  for (const auto& entry : static_entries) {
-    names.insert(entry.name());
-  }
-  EXPECT_EQ(names.size(), static_name_index.size());
-}
-
-// Test that ObtainQpackStaticTable returns the same instance every time.
-TEST(QpackStaticTableTest, IsSingleton) {
-  const QpackStaticTable* static_table_one = &ObtainQpackStaticTable();
-  const QpackStaticTable* static_table_two = &ObtainQpackStaticTable();
-  EXPECT_EQ(static_table_one, static_table_two);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/core/qpack/qpack_stream_receiver.h b/quic/core/qpack/qpack_stream_receiver.h
deleted file mode 100644
index a543496..0000000
--- a/quic/core/qpack/qpack_stream_receiver.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This interface decodes QPACK data that are received on a QpackReceiveStream.
-class QUIC_EXPORT_PRIVATE QpackStreamReceiver {
- public:
-  virtual ~QpackStreamReceiver() = default;
-
-  // Decode data.
-  virtual void Decode(absl::string_view data) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
diff --git a/quic/core/qpack/qpack_stream_sender_delegate.h b/quic/core/qpack/qpack_stream_sender_delegate.h
deleted file mode 100644
index 04f533d..0000000
--- a/quic/core/qpack/qpack_stream_sender_delegate.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
-#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// This interface writes encoder/decoder data to peer.
-class QUIC_EXPORT_PRIVATE QpackStreamSenderDelegate {
- public:
-  virtual ~QpackStreamSenderDelegate() = default;
-
-  // Write data on the unidirectional stream.
-  virtual void WriteStreamData(absl::string_view data) = 0;
-
-  // Return the number of bytes buffered due to underlying stream being blocked.
-  virtual uint64_t NumBytesBuffered() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
diff --git a/quic/core/qpack/value_splitting_header_list.cc b/quic/core/qpack/value_splitting_header_list.cc
deleted file mode 100644
index 9d4231d..0000000
--- a/quic/core/qpack/value_splitting_header_list.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/value_splitting_header_list.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-
-const char kCookieKey[] = "cookie";
-const char kCookieSeparator = ';';
-const char kOptionalSpaceAfterCookieSeparator = ' ';
-const char kNonCookieSeparator = '\0';
-
-}  // namespace
-
-ValueSplittingHeaderList::const_iterator::const_iterator(
-    const spdy::Http2HeaderBlock* header_list,
-    spdy::Http2HeaderBlock::const_iterator header_list_iterator)
-    : header_list_(header_list),
-      header_list_iterator_(header_list_iterator),
-      value_start_(0) {
-  UpdateHeaderField();
-}
-
-bool ValueSplittingHeaderList::const_iterator::operator==(
-    const const_iterator& other) const {
-  return header_list_iterator_ == other.header_list_iterator_ &&
-         value_start_ == other.value_start_;
-}
-
-bool ValueSplittingHeaderList::const_iterator::operator!=(
-    const const_iterator& other) const {
-  return !(*this == other);
-}
-
-const ValueSplittingHeaderList::const_iterator&
-ValueSplittingHeaderList::const_iterator::operator++() {
-  if (value_end_ == absl::string_view::npos) {
-    // This was the last frament within |*header_list_iterator_|,
-    // move on to the next header element of |header_list_|.
-    ++header_list_iterator_;
-    value_start_ = 0;
-  } else {
-    // Find the next fragment within |*header_list_iterator_|.
-    value_start_ = value_end_ + 1;
-  }
-  UpdateHeaderField();
-
-  return *this;
-}
-
-const ValueSplittingHeaderList::value_type&
-    ValueSplittingHeaderList::const_iterator::operator*() const {
-  return header_field_;
-}
-const ValueSplittingHeaderList::value_type*
-    ValueSplittingHeaderList::const_iterator::operator->() const {
-  return &header_field_;
-}
-
-void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() {
-  QUICHE_DCHECK(value_start_ != absl::string_view::npos);
-
-  if (header_list_iterator_ == header_list_->end()) {
-    return;
-  }
-
-  const absl::string_view name = header_list_iterator_->first;
-  const absl::string_view original_value = header_list_iterator_->second;
-
-  if (name == kCookieKey) {
-    value_end_ = original_value.find(kCookieSeparator, value_start_);
-  } else {
-    value_end_ = original_value.find(kNonCookieSeparator, value_start_);
-  }
-
-  const absl::string_view value =
-      original_value.substr(value_start_, value_end_ - value_start_);
-  header_field_ = std::make_pair(name, value);
-
-  // Skip character after ';' separator if it is a space.
-  if (name == kCookieKey && value_end_ != absl::string_view::npos &&
-      value_end_ + 1 < original_value.size() &&
-      original_value[value_end_ + 1] == kOptionalSpaceAfterCookieSeparator) {
-    ++value_end_;
-  }
-}
-
-ValueSplittingHeaderList::ValueSplittingHeaderList(
-    const spdy::Http2HeaderBlock* header_list)
-    : header_list_(header_list) {
-  QUICHE_DCHECK(header_list_);
-}
-
-ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::begin()
-    const {
-  return const_iterator(header_list_, header_list_->begin());
-}
-
-ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::end() const {
-  return const_iterator(header_list_, header_list_->end());
-}
-
-}  // namespace quic
diff --git a/quic/core/qpack/value_splitting_header_list.h b/quic/core/qpack/value_splitting_header_list.h
deleted file mode 100644
index 939a4ce..0000000
--- a/quic/core/qpack/value_splitting_header_list.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
-#define QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// A wrapper class around Http2HeaderBlock that splits header values along ';'
-// separators (while also removing optional space following separator) for
-// cookies and along '\0' separators for other header fields.
-class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList {
- public:
-  using value_type = spdy::Http2HeaderBlock::value_type;
-
-  class QUIC_EXPORT_PRIVATE const_iterator {
-   public:
-    // |header_list| must outlive this object.
-    const_iterator(const spdy::Http2HeaderBlock* header_list,
-                   spdy::Http2HeaderBlock::const_iterator header_list_iterator);
-    const_iterator(const const_iterator&) = default;
-    const_iterator& operator=(const const_iterator&) = delete;
-
-    bool operator==(const const_iterator& other) const;
-    bool operator!=(const const_iterator& other) const;
-
-    const const_iterator& operator++();
-
-    const value_type& operator*() const;
-    const value_type* operator->() const;
-
-   private:
-    // Find next separator; update |value_end_| and |header_field_|.
-    void UpdateHeaderField();
-
-    const spdy::Http2HeaderBlock* const header_list_;
-    spdy::Http2HeaderBlock::const_iterator header_list_iterator_;
-    absl::string_view::size_type value_start_;
-    absl::string_view::size_type value_end_;
-    value_type header_field_;
-  };
-
-  // |header_list| must outlive this object.
-  explicit ValueSplittingHeaderList(const spdy::Http2HeaderBlock* header_list);
-  ValueSplittingHeaderList(const ValueSplittingHeaderList&) = delete;
-  ValueSplittingHeaderList& operator=(const ValueSplittingHeaderList&) = delete;
-
-  const_iterator begin() const;
-  const_iterator end() const;
-
- private:
-  const spdy::Http2HeaderBlock* const header_list_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
diff --git a/quic/core/qpack/value_splitting_header_list_test.cc b/quic/core/qpack/value_splitting_header_list_test.cc
deleted file mode 100644
index bc3072a..0000000
--- a/quic/core/qpack/value_splitting_header_list_test.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/qpack/value_splitting_header_list.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::Pair;
-
-TEST(ValueSplittingHeaderListTest, Comparison) {
-  spdy::Http2HeaderBlock block;
-  block["foo"] = absl::string_view("bar\0baz", 7);
-  block["baz"] = "qux";
-  block["cookie"] = "foo; bar";
-
-  ValueSplittingHeaderList headers(&block);
-  ValueSplittingHeaderList::const_iterator it1 = headers.begin();
-  const int kEnd = 6;
-  for (int i = 0; i < kEnd; ++i) {
-    // Compare to begin().
-    if (i == 0) {
-      EXPECT_TRUE(it1 == headers.begin());
-      EXPECT_TRUE(headers.begin() == it1);
-      EXPECT_FALSE(it1 != headers.begin());
-      EXPECT_FALSE(headers.begin() != it1);
-    } else {
-      EXPECT_FALSE(it1 == headers.begin());
-      EXPECT_FALSE(headers.begin() == it1);
-      EXPECT_TRUE(it1 != headers.begin());
-      EXPECT_TRUE(headers.begin() != it1);
-    }
-
-    // Compare to end().
-    if (i == kEnd - 1) {
-      EXPECT_TRUE(it1 == headers.end());
-      EXPECT_TRUE(headers.end() == it1);
-      EXPECT_FALSE(it1 != headers.end());
-      EXPECT_FALSE(headers.end() != it1);
-    } else {
-      EXPECT_FALSE(it1 == headers.end());
-      EXPECT_FALSE(headers.end() == it1);
-      EXPECT_TRUE(it1 != headers.end());
-      EXPECT_TRUE(headers.end() != it1);
-    }
-
-    // Compare to another iterator walking through the container.
-    ValueSplittingHeaderList::const_iterator it2 = headers.begin();
-    for (int j = 0; j < kEnd; ++j) {
-      if (i == j) {
-        EXPECT_TRUE(it1 == it2);
-        EXPECT_FALSE(it1 != it2);
-      } else {
-        EXPECT_FALSE(it1 == it2);
-        EXPECT_TRUE(it1 != it2);
-      }
-      if (j < kEnd - 1) {
-        ASSERT_NE(it2, headers.end());
-        ++it2;
-      }
-    }
-
-    if (i < kEnd - 1) {
-      ASSERT_NE(it1, headers.end());
-      ++it1;
-    }
-  }
-}
-
-TEST(ValueSplittingHeaderListTest, Empty) {
-  spdy::Http2HeaderBlock block;
-
-  ValueSplittingHeaderList headers(&block);
-  EXPECT_THAT(headers, ElementsAre());
-  EXPECT_EQ(headers.begin(), headers.end());
-}
-
-TEST(ValueSplittingHeaderListTest, Split) {
-  struct {
-    const char* name;
-    absl::string_view value;
-    std::vector<const char*> expected_values;
-  } kTestData[]{
-      // Empty value.
-      {"foo", "", {""}},
-      // Trivial case.
-      {"foo", "bar", {"bar"}},
-      // Simple split.
-      {"foo", {"bar\0baz", 7}, {"bar", "baz"}},
-      {"cookie", "foo;bar", {"foo", "bar"}},
-      {"cookie", "foo; bar", {"foo", "bar"}},
-      // Empty fragments with \0 separator.
-      {"foo", {"\0", 1}, {"", ""}},
-      {"bar", {"foo\0", 4}, {"foo", ""}},
-      {"baz", {"\0bar", 4}, {"", "bar"}},
-      {"qux", {"\0foobar\0", 8}, {"", "foobar", ""}},
-      // Empty fragments with ";" separator.
-      {"cookie", ";", {"", ""}},
-      {"cookie", "foo;", {"foo", ""}},
-      {"cookie", ";bar", {"", "bar"}},
-      {"cookie", ";foobar;", {"", "foobar", ""}},
-      // Empty fragments with "; " separator.
-      {"cookie", "; ", {"", ""}},
-      {"cookie", "foo; ", {"foo", ""}},
-      {"cookie", "; bar", {"", "bar"}},
-      {"cookie", "; foobar; ", {"", "foobar", ""}},
-  };
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
-    spdy::Http2HeaderBlock block;
-    block[kTestData[i].name] = kTestData[i].value;
-
-    ValueSplittingHeaderList headers(&block);
-    auto it = headers.begin();
-    for (const char* expected_value : kTestData[i].expected_values) {
-      ASSERT_NE(it, headers.end());
-      EXPECT_EQ(it->first, kTestData[i].name);
-      EXPECT_EQ(it->second, expected_value);
-      ++it;
-    }
-    EXPECT_EQ(it, headers.end());
-  }
-}
-
-TEST(ValueSplittingHeaderListTest, MultipleFields) {
-  spdy::Http2HeaderBlock block;
-  block["foo"] = absl::string_view("bar\0baz\0", 8);
-  block["cookie"] = "foo; bar";
-  block["bar"] = absl::string_view("qux\0foo", 7);
-
-  ValueSplittingHeaderList headers(&block);
-  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("foo", "baz"),
-                                   Pair("foo", ""), Pair("cookie", "foo"),
-                                   Pair("cookie", "bar"), Pair("bar", "qux"),
-                                   Pair("bar", "foo")));
-}
-
-TEST(ValueSplittingHeaderListTest, CookieStartsWithSpace) {
-  spdy::Http2HeaderBlock block;
-  block["foo"] = "bar";
-  block["cookie"] = " foo";
-  block["bar"] = "baz";
-
-  ValueSplittingHeaderList headers(&block);
-  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("cookie", " foo"),
-                                   Pair("bar", "baz")));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_ack_listener_interface.cc b/quic/core/quic_ack_listener_interface.cc
deleted file mode 100644
index 4a85481..0000000
--- a/quic/core/quic_ack_listener_interface.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_ack_listener_interface.h"
-
-namespace quic {
-
-QuicAckListenerInterface::~QuicAckListenerInterface() {}
-
-}  // namespace quic
diff --git a/quic/core/quic_ack_listener_interface.h b/quic/core/quic_ack_listener_interface.h
deleted file mode 100644
index 7592e0f..0000000
--- a/quic/core/quic_ack_listener_interface.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
-#define QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
-
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_reference_counted.h"
-
-namespace quic {
-
-// Pure virtual class to listen for packet acknowledgements.
-class QUIC_EXPORT_PRIVATE QuicAckListenerInterface
-    : public quiche::QuicheReferenceCounted {
- public:
-  QuicAckListenerInterface() {}
-
-  // Called when a packet is acked.  Called once per packet.
-  // |acked_bytes| is the number of data bytes acked.
-  virtual void OnPacketAcked(int acked_bytes,
-                             QuicTime::Delta ack_delay_time) = 0;
-
-  // Called when a packet is retransmitted.  Called once per packet.
-  // |retransmitted_bytes| is the number of data bytes retransmitted.
-  virtual void OnPacketRetransmitted(int retransmitted_bytes) = 0;
-
- protected:
-  // Delegates are ref counted.
-  ~QuicAckListenerInterface() override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
diff --git a/quic/core/quic_alarm.cc b/quic/core/quic_alarm.cc
deleted file mode 100644
index 33b96ed..0000000
--- a/quic/core/quic_alarm.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_alarm.h"
-
-#include <atomic>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-QuicAlarm::QuicAlarm(QuicArenaScopedPtr<Delegate> delegate)
-    : delegate_(std::move(delegate)), deadline_(QuicTime::Zero()) {}
-
-QuicAlarm::~QuicAlarm() {
-  if (IsSet()) {
-    QUIC_CODE_COUNT(quic_alarm_not_cancelled_in_dtor);
-  }
-}
-
-void QuicAlarm::Set(QuicTime new_deadline) {
-  QUICHE_DCHECK(!IsSet());
-  QUICHE_DCHECK(new_deadline.IsInitialized());
-
-  if (IsPermanentlyCancelled()) {
-    QUIC_BUG(quic_alarm_illegal_set)
-        << "Set called after alarm is permanently cancelled. new_deadline:"
-        << new_deadline;
-    return;
-  }
-
-  deadline_ = new_deadline;
-  SetImpl();
-}
-
-void QuicAlarm::CancelInternal(bool permanent) {
-  if (IsSet()) {
-    deadline_ = QuicTime::Zero();
-    CancelImpl();
-  }
-
-  if (permanent) {
-    delegate_.reset();
-  }
-}
-
-bool QuicAlarm::IsPermanentlyCancelled() const { return delegate_ == nullptr; }
-
-void QuicAlarm::Update(QuicTime new_deadline, QuicTime::Delta granularity) {
-  if (IsPermanentlyCancelled()) {
-    QUIC_BUG(quic_alarm_illegal_update)
-        << "Update called after alarm is permanently cancelled. new_deadline:"
-        << new_deadline << ", granularity:" << granularity;
-    return;
-  }
-
-  if (!new_deadline.IsInitialized()) {
-    Cancel();
-    return;
-  }
-  if (std::abs((new_deadline - deadline_).ToMicroseconds()) <
-      granularity.ToMicroseconds()) {
-    return;
-  }
-  const bool was_set = IsSet();
-  deadline_ = new_deadline;
-  if (was_set) {
-    UpdateImpl();
-  } else {
-    SetImpl();
-  }
-}
-
-bool QuicAlarm::IsSet() const {
-  return deadline_.IsInitialized();
-}
-
-void QuicAlarm::Fire() {
-  if (!IsSet()) {
-    return;
-  }
-
-  deadline_ = QuicTime::Zero();
-  if (!IsPermanentlyCancelled()) {
-    QuicConnectionContextSwitcher context_switcher(
-        delegate_->GetConnectionContext());
-    delegate_->OnAlarm();
-  }
-}
-
-void QuicAlarm::UpdateImpl() {
-  // CancelImpl and SetImpl take the new deadline by way of the deadline_
-  // member, so save and restore deadline_ before canceling.
-  const QuicTime new_deadline = deadline_;
-
-  deadline_ = QuicTime::Zero();
-  CancelImpl();
-
-  deadline_ = new_deadline;
-  SetImpl();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_alarm.h b/quic/core/quic_alarm.h
deleted file mode 100644
index 26ebfe8..0000000
--- a/quic/core/quic_alarm.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ALARM_H_
-#define QUICHE_QUIC_CORE_QUIC_ALARM_H_
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Abstract class which represents an alarm which will go off at a
-// scheduled time, and execute the |OnAlarm| method of the delegate.
-// An alarm may be cancelled, in which case it may or may not be
-// removed from the underlying scheduling system, but in either case
-// the task will not be executed.
-class QUIC_EXPORT_PRIVATE QuicAlarm {
- public:
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // If the alarm belongs to a single QuicConnection, return the corresponding
-    // QuicConnection.context_. Note the context_ is the first member of
-    // QuicConnection, so it should outlive the delegate.
-    // Otherwise return nullptr.
-    // The OnAlarm function will be called under the connection context, if any.
-    virtual QuicConnectionContext* GetConnectionContext() = 0;
-
-    // Invoked when the alarm fires.
-    virtual void OnAlarm() = 0;
-  };
-
-  // DelegateWithContext is a Delegate with a QuicConnectionContext* stored as a
-  // member variable.
-  class QUIC_EXPORT_PRIVATE DelegateWithContext : public Delegate {
-   public:
-    explicit DelegateWithContext(QuicConnectionContext* context)
-        : context_(context) {}
-    ~DelegateWithContext() override {}
-    QuicConnectionContext* GetConnectionContext() override { return context_; }
-
-   private:
-    QuicConnectionContext* context_;
-  };
-
-  // DelegateWithoutContext is a Delegate that does not have a corresponding
-  // context. Typically this means one object of the child class deals with many
-  // connections.
-  class QUIC_EXPORT_PRIVATE DelegateWithoutContext : public Delegate {
-   public:
-    ~DelegateWithoutContext() override {}
-    QuicConnectionContext* GetConnectionContext() override { return nullptr; }
-  };
-
-  explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate);
-  QuicAlarm(const QuicAlarm&) = delete;
-  QuicAlarm& operator=(const QuicAlarm&) = delete;
-  virtual ~QuicAlarm();
-
-  // Sets the alarm to fire at |deadline|.  Must not be called while
-  // the alarm is set.  To reschedule an alarm, call Cancel() first,
-  // then Set().
-  void Set(QuicTime new_deadline);
-
-  // Both PermanentCancel() and Cancel() can cancel the alarm. If permanent,
-  // future calls to Set() and Update() will become no-op except emitting an
-  // error log.
-  //
-  // Both may be called repeatedly.  Does not guarantee that the underlying
-  // scheduling system will remove the alarm's associated task, but guarantees
-  // that the delegates OnAlarm method will not be called.
-  void PermanentCancel() { CancelInternal(true); }
-  void Cancel() { CancelInternal(false); }
-
-  // Return true if PermanentCancel() has been called.
-  bool IsPermanentlyCancelled() const;
-
-  // Cancels and sets the alarm if the |deadline| is farther from the current
-  // deadline than |granularity|, and otherwise does nothing.  If |deadline| is
-  // not initialized, the alarm is cancelled.
-  void Update(QuicTime new_deadline, QuicTime::Delta granularity);
-
-  // Returns true if |deadline_| has been set to a non-zero time.
-  bool IsSet() const;
-
-  QuicTime deadline() const { return deadline_; }
-
- protected:
-  // Subclasses implement this method to perform the platform-specific
-  // scheduling of the alarm.  Is called from Set() or Fire(), after the
-  // deadline has been updated.
-  virtual void SetImpl() = 0;
-
-  // Subclasses implement this method to perform the platform-specific
-  // cancelation of the alarm.
-  virtual void CancelImpl() = 0;
-
-  // Subclasses implement this method to perform the platform-specific update of
-  // the alarm if there exists a more optimal implementation than calling
-  // CancelImpl() and SetImpl().
-  virtual void UpdateImpl();
-
-  // Called by subclasses when the alarm fires.  Invokes the
-  // delegates |OnAlarm| if a delegate is set, and if the deadline
-  // has been exceeded.  Implementations which do not remove the
-  // alarm from the underlying scheduler on Cancel() may need to handle
-  // the situation where the task executes before the deadline has been
-  // reached, in which case they need to reschedule the task and must not
-  // call invoke this method.
-  void Fire();
-
- private:
-  void CancelInternal(bool permanent);
-
-  QuicArenaScopedPtr<Delegate> delegate_;
-  QuicTime deadline_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_ALARM_H_
diff --git a/quic/core/quic_alarm_factory.h b/quic/core/quic_alarm_factory.h
deleted file mode 100644
index 57505ef..0000000
--- a/quic/core/quic_alarm_factory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
-#define QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Creates platform-specific alarms used throughout QUIC.
-class QUIC_EXPORT_PRIVATE QuicAlarmFactory {
- public:
-  virtual ~QuicAlarmFactory() {}
-
-  // Creates a new platform-specific alarm which will be configured to notify
-  // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
-  // Caller takes ownership of the new alarm, which will not yet be "set" to
-  // fire.
-  virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
-
-  // Creates a new platform-specific alarm which will be configured to notify
-  // |delegate| when the alarm fires. Caller takes ownership of the new alarm,
-  // which will not yet be "set" to fire. If |arena| is null, then the alarm
-  // will be created on the heap. Otherwise, it will be created in |arena|.
-  virtual QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-      QuicConnectionArena* arena) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
diff --git a/quic/core/quic_alarm_test.cc b/quic/core/quic_alarm_test.cc
deleted file mode 100644
index b27f96e..0000000
--- a/quic/core/quic_alarm_test.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_alarm.h"
-
-#include "quic/core/quic_connection_context.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-
-using testing::ElementsAre;
-using testing::Invoke;
-using testing::Return;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TraceCollector : public QuicConnectionTracer {
- public:
-  ~TraceCollector() override = default;
-
-  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
-
-  void PrintString(absl::string_view s) override {
-    trace_.push_back(std::string(s));
-  }
-
-  const std::vector<std::string>& trace() const { return trace_; }
-
- private:
-  std::vector<std::string> trace_;
-};
-
-class MockDelegate : public QuicAlarm::Delegate {
- public:
-  MOCK_METHOD(QuicConnectionContext*, GetConnectionContext, (), (override));
-  MOCK_METHOD(void, OnAlarm, (), (override));
-};
-
-class DestructiveDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
-  DestructiveDelegate() : alarm_(nullptr) {}
-
-  void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; }
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(alarm_);
-    delete alarm_;
-  }
-
- private:
-  QuicAlarm* alarm_;
-};
-
-class TestAlarm : public QuicAlarm {
- public:
-  explicit TestAlarm(QuicAlarm::Delegate* delegate)
-      : QuicAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)) {}
-
-  bool scheduled() const { return scheduled_; }
-
-  void FireAlarm() {
-    scheduled_ = false;
-    Fire();
-  }
-
- protected:
-  void SetImpl() override {
-    QUICHE_DCHECK(deadline().IsInitialized());
-    scheduled_ = true;
-  }
-
-  void CancelImpl() override {
-    QUICHE_DCHECK(!deadline().IsInitialized());
-    scheduled_ = false;
-  }
-
- private:
-  bool scheduled_;
-};
-
-class DestructiveAlarm : public QuicAlarm {
- public:
-  explicit DestructiveAlarm(DestructiveDelegate* delegate)
-      : QuicAlarm(QuicArenaScopedPtr<DestructiveDelegate>(delegate)) {}
-
-  void FireAlarm() { Fire(); }
-
- protected:
-  void SetImpl() override {}
-
-  void CancelImpl() override {}
-};
-
-class QuicAlarmTest : public QuicTest {
- public:
-  QuicAlarmTest()
-      : delegate_(new MockDelegate()),
-        alarm_(delegate_),
-        deadline_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(7)),
-        deadline2_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(14)),
-        new_deadline_(QuicTime::Zero()) {}
-
-  void ResetAlarm() { alarm_.Set(new_deadline_); }
-
-  MockDelegate* delegate_;  // not owned
-  TestAlarm alarm_;
-  QuicTime deadline_;
-  QuicTime deadline2_;
-  QuicTime new_deadline_;
-};
-
-TEST_F(QuicAlarmTest, IsSet) {
-  EXPECT_FALSE(alarm_.IsSet());
-}
-
-TEST_F(QuicAlarmTest, Set) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-  EXPECT_TRUE(alarm_.IsSet());
-  EXPECT_TRUE(alarm_.scheduled());
-  EXPECT_EQ(deadline, alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, Cancel) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-  alarm_.Cancel();
-  EXPECT_FALSE(alarm_.IsSet());
-  EXPECT_FALSE(alarm_.scheduled());
-  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, PermanentCancel) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-  alarm_.PermanentCancel();
-  EXPECT_FALSE(alarm_.IsSet());
-  EXPECT_FALSE(alarm_.scheduled());
-  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-
-  EXPECT_QUIC_BUG(alarm_.Set(deadline),
-                  "Set called after alarm is permanently cancelled");
-  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
-  EXPECT_FALSE(alarm_.IsSet());
-  EXPECT_FALSE(alarm_.scheduled());
-  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-
-  EXPECT_QUIC_BUG(alarm_.Update(deadline, QuicTime::Delta::Zero()),
-                  "Update called after alarm is permanently cancelled");
-  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
-  EXPECT_FALSE(alarm_.IsSet());
-  EXPECT_FALSE(alarm_.scheduled());
-  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, Update) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-  QuicTime new_deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(8);
-  alarm_.Update(new_deadline, QuicTime::Delta::Zero());
-  EXPECT_TRUE(alarm_.IsSet());
-  EXPECT_TRUE(alarm_.scheduled());
-  EXPECT_EQ(new_deadline, alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, UpdateWithZero) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-  alarm_.Update(QuicTime::Zero(), QuicTime::Delta::Zero());
-  EXPECT_FALSE(alarm_.IsSet());
-  EXPECT_FALSE(alarm_.scheduled());
-  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, Fire) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-  EXPECT_CALL(*delegate_, OnAlarm());
-  alarm_.FireAlarm();
-  EXPECT_FALSE(alarm_.IsSet());
-  EXPECT_FALSE(alarm_.scheduled());
-  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, FireAndResetViaSet) {
-  alarm_.Set(deadline_);
-  new_deadline_ = deadline2_;
-  EXPECT_CALL(*delegate_, OnAlarm())
-      .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm));
-  alarm_.FireAlarm();
-  EXPECT_TRUE(alarm_.IsSet());
-  EXPECT_TRUE(alarm_.scheduled());
-  EXPECT_EQ(deadline2_, alarm_.deadline());
-}
-
-TEST_F(QuicAlarmTest, FireDestroysAlarm) {
-  DestructiveDelegate* delegate(new DestructiveDelegate);
-  DestructiveAlarm* alarm = new DestructiveAlarm(delegate);
-  delegate->set_alarm(alarm);
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm->Set(deadline);
-  // This should not crash, even though it will destroy alarm.
-  alarm->FireAlarm();
-}
-
-TEST_F(QuicAlarmTest, NullAlarmContext) {
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-
-  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(nullptr));
-
-  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
-    QUIC_TRACELITERAL("Alarm fired.");
-  }));
-  alarm_.FireAlarm();
-}
-
-TEST_F(QuicAlarmTest, AlarmContextWithNullTracer) {
-  QuicConnectionContext context;
-  ASSERT_EQ(context.tracer, nullptr);
-
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-
-  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
-
-  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
-    QUIC_TRACELITERAL("Alarm fired.");
-  }));
-  alarm_.FireAlarm();
-}
-
-TEST_F(QuicAlarmTest, AlarmContextWithTracer) {
-  QuicConnectionContext context;
-  std::unique_ptr<TraceCollector> tracer = std::make_unique<TraceCollector>();
-  const TraceCollector& tracer_ref = *tracer;
-  context.tracer = std::move(tracer);
-
-  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
-  alarm_.Set(deadline);
-
-  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
-
-  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
-    QUIC_TRACELITERAL("Alarm fired.");
-  }));
-
-  // Since |context| is not installed in the current thread, the messages before
-  // and after FireAlarm() should not be collected by |tracer|.
-  QUIC_TRACELITERAL("Should not be collected before alarm.");
-  alarm_.FireAlarm();
-  QUIC_TRACELITERAL("Should not be collected after alarm.");
-
-  EXPECT_THAT(tracer_ref.trace(), ElementsAre("Alarm fired."));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_arena_scoped_ptr.h b/quic/core/quic_arena_scoped_ptr.h
deleted file mode 100644
index 19b89a3..0000000
--- a/quic/core/quic_arena_scoped_ptr.h
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// unique_ptr-style pointer that stores values that may be from an arena. Takes
-// up the same storage as the platform's native pointer type. Takes ownership
-// of the value it's constructed with; if holding a value in an arena, and the
-// type has a non-trivial destructor, the arena must outlive the
-// QuicArenaScopedPtr. Does not support array overloads.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
-#define QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
-
-#include <cstdint>  // for uintptr_t
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_NO_EXPORT QuicArenaScopedPtr {
-  static_assert(alignof(T*) > 1,
-                "QuicArenaScopedPtr can only store objects that are aligned to "
-                "greater than 1 byte.");
-
- public:
-  // Constructs an empty QuicArenaScopedPtr.
-  QuicArenaScopedPtr();
-
-  // Constructs a QuicArenaScopedPtr referencing the heap-allocated memory
-  // provided.
-  explicit QuicArenaScopedPtr(T* value);
-
-  template <typename U>
-  QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other);  // NOLINT
-  template <typename U>
-  QuicArenaScopedPtr& operator=(QuicArenaScopedPtr<U>&& other);
-  ~QuicArenaScopedPtr();
-
-  // Returns a pointer to the value.
-  T* get() const;
-
-  // Returns a reference to the value.
-  T& operator*() const;
-
-  // Returns a pointer to the value.
-  T* operator->() const;
-
-  // Swaps the value of this pointer with |other|.
-  void swap(QuicArenaScopedPtr& other);
-
-  // Resets the held value to |value|.
-  void reset(T* value = nullptr);
-
-  // Returns true if |this| came from an arena. Primarily exposed for testing
-  // and assertions.
-  bool is_from_arena();
-
- private:
-  // Friends with other derived types of QuicArenaScopedPtr, to support the
-  // derived-types case.
-  template <typename U>
-  friend class QuicArenaScopedPtr;
-  // Also befriend all known arenas, only to prevent misuse.
-  template <uint32_t ArenaSize>
-  friend class QuicOneBlockArena;
-
-  // Tag to denote that a QuicArenaScopedPtr is being explicitly created by an
-  // arena.
-  enum class ConstructFrom { kHeap, kArena };
-
-  // Constructs a QuicArenaScopedPtr with the given representation.
-  QuicArenaScopedPtr(void* value, ConstructFrom from);
-  QuicArenaScopedPtr(const QuicArenaScopedPtr&) = delete;
-  QuicArenaScopedPtr& operator=(const QuicArenaScopedPtr&) = delete;
-
-  // Low-order bits of value_ that determine if the pointer came from an arena.
-  static const uintptr_t kFromArenaMask = 0x1;
-
-  // Every platform we care about has at least 4B aligned integers, so store the
-  // is_from_arena bit in the least significant bit.
-  void* value_;
-};
-
-template <typename T>
-bool operator==(const QuicArenaScopedPtr<T>& left,
-                const QuicArenaScopedPtr<T>& right) {
-  return left.get() == right.get();
-}
-
-template <typename T>
-bool operator!=(const QuicArenaScopedPtr<T>& left,
-                const QuicArenaScopedPtr<T>& right) {
-  return left.get() != right.get();
-}
-
-template <typename T>
-bool operator==(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
-  return nullptr == right.get();
-}
-
-template <typename T>
-bool operator!=(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
-  return nullptr != right.get();
-}
-
-template <typename T>
-bool operator==(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
-  return left.get() == nullptr;
-}
-
-template <typename T>
-bool operator!=(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
-  return left.get() != nullptr;
-}
-
-template <typename T>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr() : value_(nullptr) {}
-
-template <typename T>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr(T* value)
-    : QuicArenaScopedPtr(value, ConstructFrom::kHeap) {}
-
-template <typename T>
-template <typename U>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other)
-    : value_(other.value_) {
-  static_assert(
-      std::is_base_of<T, U>::value || std::is_same<T, U>::value,
-      "Cannot construct QuicArenaScopedPtr; type is not derived or same.");
-  other.value_ = nullptr;
-}
-
-template <typename T>
-template <typename U>
-QuicArenaScopedPtr<T>& QuicArenaScopedPtr<T>::operator=(
-    QuicArenaScopedPtr<U>&& other) {
-  static_assert(
-      std::is_base_of<T, U>::value || std::is_same<T, U>::value,
-      "Cannot assign QuicArenaScopedPtr; type is not derived or same.");
-  swap(other);
-  return *this;
-}
-
-template <typename T>
-QuicArenaScopedPtr<T>::~QuicArenaScopedPtr() {
-  reset();
-}
-
-template <typename T>
-T* QuicArenaScopedPtr<T>::get() const {
-  return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(value_) &
-                              ~kFromArenaMask);
-}
-
-template <typename T>
-T& QuicArenaScopedPtr<T>::operator*() const {
-  return *get();
-}
-
-template <typename T>
-T* QuicArenaScopedPtr<T>::operator->() const {
-  return get();
-}
-
-template <typename T>
-void QuicArenaScopedPtr<T>::swap(QuicArenaScopedPtr& other) {
-  using std::swap;
-  swap(value_, other.value_);
-}
-
-template <typename T>
-bool QuicArenaScopedPtr<T>::is_from_arena() {
-  return (reinterpret_cast<uintptr_t>(value_) & kFromArenaMask) != 0;
-}
-
-template <typename T>
-void QuicArenaScopedPtr<T>::reset(T* value) {
-  if (value_ != nullptr) {
-    if (is_from_arena()) {
-      // Manually invoke the destructor.
-      get()->~T();
-    } else {
-      delete get();
-    }
-  }
-  QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value) & kFromArenaMask);
-  value_ = value;
-}
-
-template <typename T>
-QuicArenaScopedPtr<T>::QuicArenaScopedPtr(void* value, ConstructFrom from_arena)
-    : value_(value) {
-  QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value_) & kFromArenaMask);
-  switch (from_arena) {
-    case ConstructFrom::kHeap:
-      break;
-    case ConstructFrom::kArena:
-      value_ = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(value_) |
-                                       QuicArenaScopedPtr<T>::kFromArenaMask);
-      break;
-  }
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
diff --git a/quic/core/quic_arena_scoped_ptr_test.cc b/quic/core/quic_arena_scoped_ptr_test.cc
deleted file mode 100644
index 6388cf3..0000000
--- a/quic/core/quic_arena_scoped_ptr_test.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-enum class TestParam { kFromHeap, kFromArena };
-
-struct TestObject {
-  explicit TestObject(uintptr_t value) : value(value) { buffer.resize(1024); }
-  uintptr_t value;
-
-  // Ensure that we have a non-trivial destructor that will leak memory if it's
-  // not called.
-  std::vector<char> buffer;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParam& p) {
-  switch (p) {
-    case TestParam::kFromHeap:
-      return "heap";
-    case TestParam::kFromArena:
-      return "arena";
-  }
-  QUICHE_DCHECK(false);
-  return "?";
-}
-
-class QuicArenaScopedPtrParamTest : public QuicTestWithParam<TestParam> {
- protected:
-  QuicArenaScopedPtr<TestObject> CreateObject(uintptr_t value) {
-    QuicArenaScopedPtr<TestObject> ptr;
-    switch (GetParam()) {
-      case TestParam::kFromHeap:
-        ptr = QuicArenaScopedPtr<TestObject>(new TestObject(value));
-        QUICHE_CHECK(!ptr.is_from_arena());
-        break;
-      case TestParam::kFromArena:
-        ptr = arena_.New<TestObject>(value);
-        QUICHE_CHECK(ptr.is_from_arena());
-        break;
-    }
-    return ptr;
-  }
-
- private:
-  QuicOneBlockArena<1024> arena_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicArenaScopedPtrParamTest,
-                         QuicArenaScopedPtrParamTest,
-                         testing::Values(TestParam::kFromHeap,
-                                         TestParam::kFromArena),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicArenaScopedPtrParamTest, NullObjects) {
-  QuicArenaScopedPtr<TestObject> def;
-  QuicArenaScopedPtr<TestObject> null(nullptr);
-  EXPECT_EQ(def, null);
-  EXPECT_EQ(def, nullptr);
-  EXPECT_EQ(null, nullptr);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, FromArena) {
-  QuicOneBlockArena<1024> arena_;
-  EXPECT_TRUE(arena_.New<TestObject>(0).is_from_arena());
-  EXPECT_FALSE(
-      QuicArenaScopedPtr<TestObject>(new TestObject(0)).is_from_arena());
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Assign) {
-  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
-  ptr = CreateObject(54321);
-  EXPECT_EQ(54321u, ptr->value);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, MoveConstruct) {
-  QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
-  QuicArenaScopedPtr<TestObject> ptr2(std::move(ptr1));
-  EXPECT_EQ(nullptr, ptr1);
-  EXPECT_EQ(12345u, ptr2->value);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Accessors) {
-  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
-  EXPECT_EQ(12345u, (*ptr).value);
-  EXPECT_EQ(12345u, ptr->value);
-  // We explicitly want to test that get() returns a valid pointer to the data,
-  // but the call looks redundant.
-  EXPECT_EQ(12345u, ptr.get()->value);  // NOLINT
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Reset) {
-  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
-  ptr.reset(new TestObject(54321));
-  EXPECT_EQ(54321u, ptr->value);
-}
-
-TEST_P(QuicArenaScopedPtrParamTest, Swap) {
-  QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
-  QuicArenaScopedPtr<TestObject> ptr2 = CreateObject(54321);
-  ptr1.swap(ptr2);
-  EXPECT_EQ(12345u, ptr2->value);
-  EXPECT_EQ(54321u, ptr1->value);
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/quic_bandwidth.cc b/quic/core/quic_bandwidth.cc
deleted file mode 100644
index b4108be..0000000
--- a/quic/core/quic_bandwidth.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_bandwidth.h"
-
-#include <cinttypes>
-#include <string>
-
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-std::string QuicBandwidth::ToDebuggingValue() const {
-  if (bits_per_second_ < 80000) {
-    return absl::StrFormat("%d bits/s (%d bytes/s)", bits_per_second_,
-                           bits_per_second_ / 8);
-  }
-
-  double divisor;
-  char unit;
-  if (bits_per_second_ < 8 * 1000 * 1000) {
-    divisor = 1e3;
-    unit = 'k';
-  } else if (bits_per_second_ < INT64_C(8) * 1000 * 1000 * 1000) {
-    divisor = 1e6;
-    unit = 'M';
-  } else {
-    divisor = 1e9;
-    unit = 'G';
-  }
-
-  double bits_per_second_with_unit = bits_per_second_ / divisor;
-  double bytes_per_second_with_unit = bits_per_second_with_unit / 8;
-  return absl::StrFormat("%.2f %cbits/s (%.2f %cbytes/s)",
-                         bits_per_second_with_unit, unit,
-                         bytes_per_second_with_unit, unit);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_bandwidth.h b/quic/core/quic_bandwidth.h
deleted file mode 100644
index 767564b..0000000
--- a/quic/core/quic_bandwidth.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// QuicBandwidth represents a bandwidth, stored in bits per second resolution.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
-#define QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
-
-#include <cmath>
-#include <cstdint>
-#include <limits>
-#include <ostream>
-#include <string>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicBandwidth {
- public:
-  // Creates a new QuicBandwidth with an internal value of 0.
-  static constexpr QuicBandwidth Zero() { return QuicBandwidth(0); }
-
-  // Creates a new QuicBandwidth with an internal value of INT64_MAX.
-  static constexpr QuicBandwidth Infinite() {
-    return QuicBandwidth(std::numeric_limits<int64_t>::max());
-  }
-
-  // Create a new QuicBandwidth holding the bits per second.
-  static constexpr QuicBandwidth FromBitsPerSecond(int64_t bits_per_second) {
-    return QuicBandwidth(bits_per_second);
-  }
-
-  // Create a new QuicBandwidth holding the kilo bits per second.
-  static constexpr QuicBandwidth FromKBitsPerSecond(int64_t k_bits_per_second) {
-    return QuicBandwidth(k_bits_per_second * 1000);
-  }
-
-  // Create a new QuicBandwidth holding the bytes per second.
-  static constexpr QuicBandwidth FromBytesPerSecond(int64_t bytes_per_second) {
-    return QuicBandwidth(bytes_per_second * 8);
-  }
-
-  // Create a new QuicBandwidth holding the kilo bytes per second.
-  static constexpr QuicBandwidth FromKBytesPerSecond(
-      int64_t k_bytes_per_second) {
-    return QuicBandwidth(k_bytes_per_second * 8000);
-  }
-
-  // Create a new QuicBandwidth based on the bytes per the elapsed delta.
-  static QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes,
-                                             QuicTime::Delta delta) {
-    if (bytes == 0) {
-      return QuicBandwidth(0);
-    }
-
-    // 1 bit is 1000000 micro bits.
-    int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond;
-    if (num_micro_bits < delta.ToMicroseconds()) {
-      return QuicBandwidth(1);
-    }
-
-    return QuicBandwidth(num_micro_bits / delta.ToMicroseconds());
-  }
-
-  int64_t ToBitsPerSecond() const { return bits_per_second_; }
-
-  int64_t ToKBitsPerSecond() const { return bits_per_second_ / 1000; }
-
-  int64_t ToBytesPerSecond() const { return bits_per_second_ / 8; }
-
-  int64_t ToKBytesPerSecond() const { return bits_per_second_ / 8000; }
-
-  QuicByteCount ToBytesPerPeriod(QuicTime::Delta time_period) const {
-    return bits_per_second_ * time_period.ToMicroseconds() / 8 /
-           kNumMicrosPerSecond;
-  }
-
-  int64_t ToKBytesPerPeriod(QuicTime::Delta time_period) const {
-    return bits_per_second_ * time_period.ToMicroseconds() / 8000 /
-           kNumMicrosPerSecond;
-  }
-
-  bool IsZero() const { return bits_per_second_ == 0; }
-  bool IsInfinite() const {
-    return bits_per_second_ == Infinite().ToBitsPerSecond();
-  }
-
-  QuicTime::Delta TransferTime(QuicByteCount bytes) const {
-    if (bits_per_second_ == 0) {
-      return QuicTime::Delta::Zero();
-    }
-    return QuicTime::Delta::FromMicroseconds(bytes * 8 * kNumMicrosPerSecond /
-                                             bits_per_second_);
-  }
-
-  std::string ToDebuggingValue() const;
-
- private:
-  explicit constexpr QuicBandwidth(int64_t bits_per_second)
-      : bits_per_second_(bits_per_second >= 0 ? bits_per_second : 0) {}
-
-  int64_t bits_per_second_;
-
-  friend QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs);
-  friend QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs);
-  friend QuicBandwidth operator*(QuicBandwidth lhs, float factor);
-};
-
-// Non-member relational operators for QuicBandwidth.
-inline bool operator==(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return lhs.ToBitsPerSecond() == rhs.ToBitsPerSecond();
-}
-inline bool operator!=(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return !(lhs == rhs);
-}
-inline bool operator<(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return lhs.ToBitsPerSecond() < rhs.ToBitsPerSecond();
-}
-inline bool operator>(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return rhs < lhs;
-}
-inline bool operator<=(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return !(rhs < lhs);
-}
-inline bool operator>=(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return !(lhs < rhs);
-}
-
-// Non-member arithmetic operators for QuicBandwidth.
-inline QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return QuicBandwidth(lhs.bits_per_second_ + rhs.bits_per_second_);
-}
-inline QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs) {
-  return QuicBandwidth(lhs.bits_per_second_ - rhs.bits_per_second_);
-}
-inline QuicBandwidth operator*(QuicBandwidth lhs, float rhs) {
-  return QuicBandwidth(
-      static_cast<int64_t>(std::llround(lhs.bits_per_second_ * rhs)));
-}
-inline QuicBandwidth operator*(float lhs, QuicBandwidth rhs) {
-  return rhs * lhs;
-}
-inline QuicByteCount operator*(QuicBandwidth lhs, QuicTime::Delta rhs) {
-  return lhs.ToBytesPerPeriod(rhs);
-}
-inline QuicByteCount operator*(QuicTime::Delta lhs, QuicBandwidth rhs) {
-  return rhs * lhs;
-}
-
-// Override stream output operator for gtest.
-inline std::ostream& operator<<(std::ostream& output,
-                                const QuicBandwidth bandwidth) {
-  output << bandwidth.ToDebuggingValue();
-  return output;
-}
-
-}  // namespace quic
-#endif  // QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
diff --git a/quic/core/quic_bandwidth_test.cc b/quic/core/quic_bandwidth_test.cc
deleted file mode 100644
index 7811b47..0000000
--- a/quic/core/quic_bandwidth_test.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_bandwidth.h"
-
-#include <limits>
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicBandwidthTest : public QuicTest {};
-
-TEST_F(QuicBandwidthTest, FromTo) {
-  EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(1),
-            QuicBandwidth::FromBitsPerSecond(1000));
-  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1),
-            QuicBandwidth::FromBytesPerSecond(1000));
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(8000),
-            QuicBandwidth::FromBytesPerSecond(1000));
-  EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(8),
-            QuicBandwidth::FromKBytesPerSecond(1));
-
-  EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
-  EXPECT_EQ(0, QuicBandwidth::Zero().ToKBitsPerSecond());
-  EXPECT_EQ(0, QuicBandwidth::Zero().ToBytesPerSecond());
-  EXPECT_EQ(0, QuicBandwidth::Zero().ToKBytesPerSecond());
-
-  EXPECT_EQ(1, QuicBandwidth::FromBitsPerSecond(1000).ToKBitsPerSecond());
-  EXPECT_EQ(1000, QuicBandwidth::FromKBitsPerSecond(1).ToBitsPerSecond());
-  EXPECT_EQ(1, QuicBandwidth::FromBytesPerSecond(1000).ToKBytesPerSecond());
-  EXPECT_EQ(1000, QuicBandwidth::FromKBytesPerSecond(1).ToBytesPerSecond());
-}
-
-TEST_F(QuicBandwidthTest, Add) {
-  QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
-  QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
-
-  EXPECT_EQ(9000, (bandwidht_1 + bandwidht_2).ToBitsPerSecond());
-  EXPECT_EQ(9000, (bandwidht_2 + bandwidht_1).ToBitsPerSecond());
-}
-
-TEST_F(QuicBandwidthTest, Subtract) {
-  QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
-  QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
-
-  EXPECT_EQ(7000, (bandwidht_2 - bandwidht_1).ToBitsPerSecond());
-}
-
-TEST_F(QuicBandwidthTest, TimeDelta) {
-  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1000),
-            QuicBandwidth::FromBytesAndTimeDelta(
-                1000, QuicTime::Delta::FromMilliseconds(1)));
-
-  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(10),
-            QuicBandwidth::FromBytesAndTimeDelta(
-                1000, QuicTime::Delta::FromMilliseconds(100)));
-
-  EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta(
-                                       0, QuicTime::Delta::FromSeconds(9)));
-
-  EXPECT_EQ(
-      QuicBandwidth::FromBitsPerSecond(1),
-      QuicBandwidth::FromBytesAndTimeDelta(1, QuicTime::Delta::FromSeconds(9)));
-}
-
-TEST_F(QuicBandwidthTest, Scale) {
-  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(500),
-            QuicBandwidth::FromKBytesPerSecond(1000) * 0.5f);
-  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(750),
-            0.75f * QuicBandwidth::FromKBytesPerSecond(1000));
-  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1250),
-            QuicBandwidth::FromKBytesPerSecond(1000) * 1.25f);
-
-  // Ensure we are rounding correctly within a 1bps level of precision.
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(5),
-            QuicBandwidth::FromBitsPerSecond(9) * 0.5f);
-  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(2),
-            QuicBandwidth::FromBitsPerSecond(12) * 0.2f);
-}
-
-TEST_F(QuicBandwidthTest, BytesPerPeriod) {
-  EXPECT_EQ(2000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
-                       QuicTime::Delta::FromMilliseconds(1)));
-  EXPECT_EQ(2u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
-                    QuicTime::Delta::FromMilliseconds(1)));
-  EXPECT_EQ(200000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
-                         QuicTime::Delta::FromMilliseconds(100)));
-  EXPECT_EQ(200u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
-                      QuicTime::Delta::FromMilliseconds(100)));
-
-  // 1599 * 1001 = 1600599 bits/ms = 200.074875 bytes/s.
-  EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToBytesPerPeriod(
-                      QuicTime::Delta::FromMilliseconds(1001)));
-
-  EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToKBytesPerPeriod(
-                      QuicTime::Delta::FromSeconds(1001)));
-}
-
-TEST_F(QuicBandwidthTest, TransferTime) {
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
-            QuicBandwidth::FromKBytesPerSecond(1).TransferTime(1000));
-  EXPECT_EQ(QuicTime::Delta::Zero(), QuicBandwidth::Zero().TransferTime(1000));
-}
-
-TEST_F(QuicBandwidthTest, RelOps) {
-  const QuicBandwidth b1 = QuicBandwidth::FromKBitsPerSecond(1);
-  const QuicBandwidth b2 = QuicBandwidth::FromKBytesPerSecond(2);
-  EXPECT_EQ(b1, b1);
-  EXPECT_NE(b1, b2);
-  EXPECT_LT(b1, b2);
-  EXPECT_GT(b2, b1);
-  EXPECT_LE(b1, b1);
-  EXPECT_LE(b1, b2);
-  EXPECT_GE(b1, b1);
-  EXPECT_GE(b2, b1);
-}
-
-TEST_F(QuicBandwidthTest, DebuggingValue) {
-  EXPECT_EQ("128 bits/s (16 bytes/s)",
-            QuicBandwidth::FromBytesPerSecond(16).ToDebuggingValue());
-  EXPECT_EQ("4096 bits/s (512 bytes/s)",
-            QuicBandwidth::FromBytesPerSecond(512).ToDebuggingValue());
-
-  QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000 * 50);
-  EXPECT_EQ("400.00 kbits/s (50.00 kbytes/s)", bandwidth.ToDebuggingValue());
-
-  bandwidth = bandwidth * 1000;
-  EXPECT_EQ("400.00 Mbits/s (50.00 Mbytes/s)", bandwidth.ToDebuggingValue());
-
-  bandwidth = bandwidth * 1000;
-  EXPECT_EQ("400.00 Gbits/s (50.00 Gbytes/s)", bandwidth.ToDebuggingValue());
-}
-
-TEST_F(QuicBandwidthTest, SpecialValues) {
-  EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
-  EXPECT_EQ(std::numeric_limits<int64_t>::max(),
-            QuicBandwidth::Infinite().ToBitsPerSecond());
-
-  EXPECT_TRUE(QuicBandwidth::Zero().IsZero());
-  EXPECT_FALSE(QuicBandwidth::Zero().IsInfinite());
-
-  EXPECT_TRUE(QuicBandwidth::Infinite().IsInfinite());
-  EXPECT_FALSE(QuicBandwidth::Infinite().IsZero());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_blocked_writer_interface.h b/quic/core/quic_blocked_writer_interface.h
deleted file mode 100644
index b441d92..0000000
--- a/quic/core/quic_blocked_writer_interface.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is an interface for all objects that want to be notified that
-// the underlying UDP socket is available for writing (not write blocked
-// anymore).
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
-#define QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicBlockedWriterInterface {
- public:
-  virtual ~QuicBlockedWriterInterface() {}
-
-  // Called by the PacketWriter when the underlying socket becomes writable
-  // so that the BlockedWriter can go ahead and try writing.
-  virtual void OnBlockedWriterCanWrite() = 0;
-
-  virtual bool IsWriterBlocked() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
diff --git a/quic/core/quic_buffered_packet_store.cc b/quic/core/quic_buffered_packet_store.cc
deleted file mode 100644
index f597ce0..0000000
--- a/quic/core/quic_buffered_packet_store.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_buffered_packet_store.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
-using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
-using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
-
-// Max number of connections this store can keep track.
-static const size_t kDefaultMaxConnectionsInStore = 100;
-// Up to half of the capacity can be used for storing non-CHLO packets.
-static const size_t kMaxConnectionsWithoutCHLO =
-    kDefaultMaxConnectionsInStore / 2;
-
-namespace {
-
-// This alarm removes expired entries in map each time this alarm fires.
-class ConnectionExpireAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit ConnectionExpireAlarm(QuicBufferedPacketStore* store)
-      : connection_store_(store) {}
-
-  void OnAlarm() override { connection_store_->OnExpirationTimeout(); }
-
-  ConnectionExpireAlarm(const ConnectionExpireAlarm&) = delete;
-  ConnectionExpireAlarm& operator=(const ConnectionExpireAlarm&) = delete;
-
- private:
-  QuicBufferedPacketStore* connection_store_;
-};
-
-}  // namespace
-
-BufferedPacket::BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
-                               QuicSocketAddress self_address,
-                               QuicSocketAddress peer_address)
-    : packet(std::move(packet)),
-      self_address(self_address),
-      peer_address(peer_address) {}
-
-BufferedPacket::BufferedPacket(BufferedPacket&& other) = default;
-
-BufferedPacket& BufferedPacket::operator=(BufferedPacket&& other) = default;
-
-BufferedPacket::~BufferedPacket() {}
-
-BufferedPacketList::BufferedPacketList()
-    : creation_time(QuicTime::Zero()),
-      ietf_quic(false),
-      version(ParsedQuicVersion::Unsupported()) {}
-
-BufferedPacketList::BufferedPacketList(BufferedPacketList&& other) = default;
-
-BufferedPacketList& BufferedPacketList::operator=(BufferedPacketList&& other) =
-    default;
-
-BufferedPacketList::~BufferedPacketList() {}
-
-QuicBufferedPacketStore::QuicBufferedPacketStore(
-    VisitorInterface* visitor,
-    const QuicClock* clock,
-    QuicAlarmFactory* alarm_factory)
-    : connection_life_span_(
-          QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)),
-      visitor_(visitor),
-      clock_(clock),
-      expiration_alarm_(
-          alarm_factory->CreateAlarm(new ConnectionExpireAlarm(this))) {}
-
-QuicBufferedPacketStore::~QuicBufferedPacketStore() {
-  if (expiration_alarm_ != nullptr) {
-    expiration_alarm_->PermanentCancel();
-  }
-}
-
-EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket(
-    QuicConnectionId connection_id, bool ietf_quic,
-    const QuicReceivedPacket& packet, QuicSocketAddress self_address,
-    QuicSocketAddress peer_address, const ParsedQuicVersion& version,
-    absl::optional<ParsedClientHello> parsed_chlo) {
-  const bool is_chlo = parsed_chlo.has_value();
-  QUIC_BUG_IF(quic_bug_12410_1, !GetQuicFlag(FLAGS_quic_allow_chlo_buffering))
-      << "Shouldn't buffer packets if disabled via flag.";
-  QUIC_BUG_IF(quic_bug_12410_2,
-              is_chlo && connections_with_chlo_.contains(connection_id))
-      << "Shouldn't buffer duplicated CHLO on connection " << connection_id;
-  QUIC_BUG_IF(quic_bug_12410_4, is_chlo && !version.IsKnown())
-      << "Should have version for CHLO packet.";
-
-  const bool is_first_packet = !undecryptable_packets_.contains(connection_id);
-  if (is_first_packet) {
-    if (ShouldNotBufferPacket(is_chlo)) {
-      // Drop the packet if the upper limit of undecryptable packets has been
-      // reached or the whole capacity of the store has been reached.
-      return TOO_MANY_CONNECTIONS;
-    }
-    undecryptable_packets_.emplace(
-        std::make_pair(connection_id, BufferedPacketList()));
-    undecryptable_packets_.back().second.ietf_quic = ietf_quic;
-    undecryptable_packets_.back().second.version = version;
-  }
-  QUICHE_CHECK(undecryptable_packets_.contains(connection_id));
-  BufferedPacketList& queue =
-      undecryptable_packets_.find(connection_id)->second;
-
-  if (!is_chlo) {
-    // If current packet is not CHLO, it might not be buffered because store
-    // only buffers certain number of undecryptable packets per connection.
-    size_t num_non_chlo_packets = connections_with_chlo_.contains(connection_id)
-                                      ? (queue.buffered_packets.size() - 1)
-                                      : queue.buffered_packets.size();
-    if (num_non_chlo_packets >= kDefaultMaxUndecryptablePackets) {
-      // If there are kMaxBufferedPacketsPerConnection packets buffered up for
-      // this connection, drop the current packet.
-      return TOO_MANY_PACKETS;
-    }
-  }
-
-  if (queue.buffered_packets.empty()) {
-    // If this is the first packet arrived on a new connection, initialize the
-    // creation time.
-    queue.creation_time = clock_->ApproximateNow();
-  }
-
-  BufferedPacket new_entry(std::unique_ptr<QuicReceivedPacket>(packet.Clone()),
-                           self_address, peer_address);
-  if (is_chlo) {
-    // Add CHLO to the beginning of buffered packets so that it can be delivered
-    // first later.
-    queue.buffered_packets.push_front(std::move(new_entry));
-    queue.parsed_chlo = std::move(parsed_chlo);
-    connections_with_chlo_[connection_id] = false;  // Dummy value.
-    // Set the version of buffered packets of this connection on CHLO.
-    queue.version = version;
-  } else {
-    // Buffer non-CHLO packets in arrival order.
-    queue.buffered_packets.push_back(std::move(new_entry));
-
-    // Attempt to parse multi-packet TLS CHLOs.
-    if (is_first_packet) {
-      queue.tls_chlo_extractor.IngestPacket(version, packet);
-      // Since this is the first packet and it's not a CHLO, the
-      // TlsChloExtractor should not have the entire CHLO.
-      QUIC_BUG_IF(quic_bug_12410_5,
-                  queue.tls_chlo_extractor.HasParsedFullChlo())
-          << "First packet in list should not contain full CHLO";
-    }
-    // TODO(b/154857081) Reorder CHLO packets ahead of other ones.
-  }
-
-  MaybeSetExpirationAlarm();
-  return SUCCESS;
-}
-
-bool QuicBufferedPacketStore::HasBufferedPackets(
-    QuicConnectionId connection_id) const {
-  return undecryptable_packets_.contains(connection_id);
-}
-
-bool QuicBufferedPacketStore::HasChlosBuffered() const {
-  return !connections_with_chlo_.empty();
-}
-
-BufferedPacketList QuicBufferedPacketStore::DeliverPackets(
-    QuicConnectionId connection_id) {
-  BufferedPacketList packets_to_deliver;
-  auto it = undecryptable_packets_.find(connection_id);
-  if (it != undecryptable_packets_.end()) {
-    packets_to_deliver = std::move(it->second);
-    undecryptable_packets_.erase(connection_id);
-  }
-  return packets_to_deliver;
-}
-
-void QuicBufferedPacketStore::DiscardPackets(QuicConnectionId connection_id) {
-  undecryptable_packets_.erase(connection_id);
-  connections_with_chlo_.erase(connection_id);
-}
-
-void QuicBufferedPacketStore::DiscardAllPackets() {
-  undecryptable_packets_.clear();
-  connections_with_chlo_.clear();
-  expiration_alarm_->Cancel();
-}
-
-void QuicBufferedPacketStore::OnExpirationTimeout() {
-  QuicTime expiration_time = clock_->ApproximateNow() - connection_life_span_;
-  while (!undecryptable_packets_.empty()) {
-    auto& entry = undecryptable_packets_.front();
-    if (entry.second.creation_time > expiration_time) {
-      break;
-    }
-    QuicConnectionId connection_id = entry.first;
-    visitor_->OnExpiredPackets(connection_id, std::move(entry.second));
-    undecryptable_packets_.pop_front();
-    connections_with_chlo_.erase(connection_id);
-  }
-  if (!undecryptable_packets_.empty()) {
-    MaybeSetExpirationAlarm();
-  }
-}
-
-void QuicBufferedPacketStore::MaybeSetExpirationAlarm() {
-  if (!expiration_alarm_->IsSet()) {
-    expiration_alarm_->Set(clock_->ApproximateNow() + connection_life_span_);
-  }
-}
-
-bool QuicBufferedPacketStore::ShouldNotBufferPacket(bool is_chlo) {
-  bool is_store_full =
-      undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore;
-
-  if (is_chlo) {
-    return is_store_full;
-  }
-
-  size_t num_connections_without_chlo =
-      undecryptable_packets_.size() - connections_with_chlo_.size();
-  bool reach_non_chlo_limit =
-      num_connections_without_chlo >= kMaxConnectionsWithoutCHLO;
-
-  return is_store_full || reach_non_chlo_limit;
-}
-
-BufferedPacketList QuicBufferedPacketStore::DeliverPacketsForNextConnection(
-    QuicConnectionId* connection_id) {
-  if (connections_with_chlo_.empty()) {
-    // Returns empty list if no CHLO has been buffered.
-    return BufferedPacketList();
-  }
-  *connection_id = connections_with_chlo_.front().first;
-  connections_with_chlo_.pop_front();
-
-  BufferedPacketList packets = DeliverPackets(*connection_id);
-  QUICHE_DCHECK(!packets.buffered_packets.empty() &&
-                packets.parsed_chlo.has_value())
-      << "Try to deliver connectons without CHLO. # packets:"
-      << packets.buffered_packets.size()
-      << ", has_parsed_chlo:" << packets.parsed_chlo.has_value();
-  return packets;
-}
-
-bool QuicBufferedPacketStore::HasChloForConnection(
-    QuicConnectionId connection_id) {
-  return connections_with_chlo_.contains(connection_id);
-}
-
-bool QuicBufferedPacketStore::IngestPacketForTlsChloExtraction(
-    const QuicConnectionId& connection_id, const ParsedQuicVersion& version,
-    const QuicReceivedPacket& packet, std::vector<std::string>* out_alpns,
-    std::string* out_sni, bool* out_resumption_attempted,
-    bool* out_early_data_attempted) {
-  QUICHE_DCHECK_NE(out_alpns, nullptr);
-  QUICHE_DCHECK_NE(out_sni, nullptr);
-  QUICHE_DCHECK_EQ(version.handshake_protocol, PROTOCOL_TLS1_3);
-  auto it = undecryptable_packets_.find(connection_id);
-  if (it == undecryptable_packets_.end()) {
-    QUIC_BUG(quic_bug_10838_1)
-        << "Cannot ingest packet for unknown connection ID " << connection_id;
-    return false;
-  }
-  it->second.tls_chlo_extractor.IngestPacket(version, packet);
-  if (!it->second.tls_chlo_extractor.HasParsedFullChlo()) {
-    return false;
-  }
-  const TlsChloExtractor& tls_chlo_extractor = it->second.tls_chlo_extractor;
-  *out_alpns = tls_chlo_extractor.alpns();
-  *out_sni = tls_chlo_extractor.server_name();
-  *out_resumption_attempted = tls_chlo_extractor.resumption_attempted();
-  *out_early_data_attempted = tls_chlo_extractor.early_data_attempted();
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_buffered_packet_store.h b/quic/core/quic_buffered_packet_store.h
deleted file mode 100644
index 9607054..0000000
--- a/quic/core/quic_buffered_packet_store.h
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
-#define QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
-
-#include <list>
-#include <string>
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/tls_chlo_extractor.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-namespace test {
-class QuicBufferedPacketStorePeer;
-}  // namespace test
-
-// This class buffers packets for each connection until either
-// 1) They are requested to be delivered via
-//    DeliverPacket()/DeliverPacketsForNextConnection(), or
-// 2) They expire after exceeding their lifetime in the store.
-//
-// It can only buffer packets on certain number of connections. It has two pools
-// of connections: connections with CHLO buffered and those without CHLO. The
-// latter has its own upper limit along with the max number of connections this
-// store can hold. The former pool can grow till this store is full.
-class QUIC_NO_EXPORT QuicBufferedPacketStore {
- public:
-  enum EnqueuePacketResult {
-    SUCCESS = 0,
-    TOO_MANY_PACKETS,  // Too many packets stored up for a certain connection.
-    TOO_MANY_CONNECTIONS  // Too many connections stored up in the store.
-  };
-
-  struct QUIC_NO_EXPORT BufferedPacket {
-    BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
-                   QuicSocketAddress self_address,
-                   QuicSocketAddress peer_address);
-    BufferedPacket(BufferedPacket&& other);
-
-    BufferedPacket& operator=(BufferedPacket&& other);
-
-    ~BufferedPacket();
-
-    std::unique_ptr<QuicReceivedPacket> packet;
-    QuicSocketAddress self_address;
-    QuicSocketAddress peer_address;
-  };
-
-  // A queue of BufferedPackets for a connection.
-  struct QUIC_NO_EXPORT BufferedPacketList {
-    BufferedPacketList();
-    BufferedPacketList(BufferedPacketList&& other);
-
-    BufferedPacketList& operator=(BufferedPacketList&& other);
-
-    ~BufferedPacketList();
-
-    std::list<BufferedPacket> buffered_packets;
-    QuicTime creation_time;
-    // |parsed_chlo| is set iff the entire CHLO has been received.
-    absl::optional<ParsedClientHello> parsed_chlo;
-    // Indicating whether this is an IETF QUIC connection.
-    bool ietf_quic;
-    // If buffered_packets contains the CHLO, it is the version of the CHLO.
-    // Otherwise, it is the version of the first packet in |buffered_packets|.
-    ParsedQuicVersion version;
-    TlsChloExtractor tls_chlo_extractor;
-  };
-
-  using BufferedPacketMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
-                                                        BufferedPacketList,
-                                                        QuicConnectionIdHash>;
-
-  class QUIC_NO_EXPORT VisitorInterface {
-   public:
-    virtual ~VisitorInterface() {}
-
-    // Called for each expired connection when alarm fires.
-    virtual void OnExpiredPackets(QuicConnectionId connection_id,
-                                  BufferedPacketList early_arrived_packets) = 0;
-  };
-
-  QuicBufferedPacketStore(VisitorInterface* visitor, const QuicClock* clock,
-                          QuicAlarmFactory* alarm_factory);
-
-  QuicBufferedPacketStore(const QuicBufferedPacketStore&) = delete;
-
-  ~QuicBufferedPacketStore();
-
-  QuicBufferedPacketStore& operator=(const QuicBufferedPacketStore&) = delete;
-
-  // Adds a copy of packet into the packet queue for given connection. If the
-  // packet is the last one of the CHLO, |parsed_chlo| will contain a parsed
-  // version of the CHLO.
-  EnqueuePacketResult EnqueuePacket(
-      QuicConnectionId connection_id, bool ietf_quic,
-      const QuicReceivedPacket& packet, QuicSocketAddress self_address,
-      QuicSocketAddress peer_address, const ParsedQuicVersion& version,
-      absl::optional<ParsedClientHello> parsed_chlo);
-
-  // Returns true if there are any packets buffered for |connection_id|.
-  bool HasBufferedPackets(QuicConnectionId connection_id) const;
-
-  // Ingests this packet into the corresponding TlsChloExtractor. This should
-  // only be called when HasBufferedPackets(connection_id) is true.
-  // Returns whether we've now parsed a full multi-packet TLS CHLO.
-  // When this returns true, |out_alpns| is populated with the list of ALPNs
-  // extracted from the CHLO. |out_sni| is populated with the SNI tag in CHLO.
-  // |out_resumption_attempted| is populated if the CHLO has the
-  // 'pre_shared_key' TLS extension. |out_early_data_attempted| is populated if
-  // the CHLO has the 'early_data' TLS extension.
-  bool IngestPacketForTlsChloExtraction(const QuicConnectionId& connection_id,
-                                        const ParsedQuicVersion& version,
-                                        const QuicReceivedPacket& packet,
-                                        std::vector<std::string>* out_alpns,
-                                        std::string* out_sni,
-                                        bool* out_resumption_attempted,
-                                        bool* out_early_data_attempted);
-
-  // Returns the list of buffered packets for |connection_id| and removes them
-  // from the store. Returns an empty list if no early arrived packets for this
-  // connection are present.
-  BufferedPacketList DeliverPackets(QuicConnectionId connection_id);
-
-  // Discards packets buffered for |connection_id|, if any.
-  void DiscardPackets(QuicConnectionId connection_id);
-
-  // Discards all the packets.
-  void DiscardAllPackets();
-
-  // Examines how long packets have been buffered in the store for each
-  // connection. If they stay too long, removes them for new coming packets and
-  // calls |visitor_|'s OnPotentialConnectionExpire().
-  // Resets the alarm at the end.
-  void OnExpirationTimeout();
-
-  // Delivers buffered packets for next connection with CHLO to open.
-  // Return connection id for next connection in |connection_id|
-  // and all buffered packets including CHLO.
-  // The returned list should at least has one packet(CHLO) if
-  // store does have any connection to open. If no connection in the store has
-  // received CHLO yet, empty list will be returned.
-  BufferedPacketList DeliverPacketsForNextConnection(
-      QuicConnectionId* connection_id);
-
-  // Is given connection already buffered in the store?
-  bool HasChloForConnection(QuicConnectionId connection_id);
-
-  // Is there any CHLO buffered in the store?
-  bool HasChlosBuffered() const;
-
- private:
-  friend class test::QuicBufferedPacketStorePeer;
-
-  // Set expiration alarm if it hasn't been set.
-  void MaybeSetExpirationAlarm();
-
-  // Return true if add an extra packet will go beyond allowed max connection
-  // limit. The limit for non-CHLO packet and CHLO packet is different.
-  bool ShouldNotBufferPacket(bool is_chlo);
-
-  // A map to store packet queues with creation time for each connection.
-  BufferedPacketMap undecryptable_packets_;
-
-  // The max time the packets of a connection can be buffer in the store.
-  const QuicTime::Delta connection_life_span_;
-
-  VisitorInterface* visitor_;  // Unowned.
-
-  const QuicClock* clock_;  // Unowned.
-
-  // This alarm fires every |connection_life_span_| to clean up
-  // packets staying in the store for too long.
-  std::unique_ptr<QuicAlarm> expiration_alarm_;
-
-  // Keeps track of connection with CHLO buffered up already and the order they
-  // arrive.
-  quiche::QuicheLinkedHashMap<QuicConnectionId, bool, QuicConnectionIdHash>
-      connections_with_chlo_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
diff --git a/quic/core/quic_buffered_packet_store_test.cc b/quic/core/quic_buffered_packet_store_test.cc
deleted file mode 100644
index 301d641..0000000
--- a/quic/core/quic_buffered_packet_store_test.cc
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_buffered_packet_store.h"
-
-#include <list>
-#include <string>
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_buffered_packet_store_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-static const size_t kDefaultMaxConnectionsInStore = 100;
-static const size_t kMaxConnectionsWithoutCHLO =
-    kDefaultMaxConnectionsInStore / 2;
-
-namespace test {
-namespace {
-
-const absl::optional<ParsedClientHello> kNoParsedChlo;
-const absl::optional<ParsedClientHello> kDefaultParsedChlo =
-    absl::make_optional<ParsedClientHello>();
-
-using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
-using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
-using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
-using ::testing::ElementsAre;
-class QuicBufferedPacketStoreVisitor
-    : public QuicBufferedPacketStore::VisitorInterface {
- public:
-  QuicBufferedPacketStoreVisitor() {}
-
-  ~QuicBufferedPacketStoreVisitor() override {}
-
-  void OnExpiredPackets(QuicConnectionId /*connection_id*/,
-                        BufferedPacketList early_arrived_packets) override {
-    last_expired_packet_queue_ = std::move(early_arrived_packets);
-  }
-
-  // The packets queue for most recently expirect connection.
-  BufferedPacketList last_expired_packet_queue_;
-};
-
-class QuicBufferedPacketStoreTest : public QuicTest {
- public:
-  QuicBufferedPacketStoreTest()
-      : store_(&visitor_, &clock_, &alarm_factory_),
-        self_address_(QuicIpAddress::Any6(), 65535),
-        peer_address_(QuicIpAddress::Any6(), 65535),
-        packet_content_("some encrypted content"),
-        packet_time_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(42)),
-        packet_(packet_content_.data(), packet_content_.size(), packet_time_),
-        invalid_version_(UnsupportedQuicVersion()),
-        valid_version_(CurrentSupportedVersions().front()) {}
-
- protected:
-  QuicBufferedPacketStoreVisitor visitor_;
-  MockClock clock_;
-  MockAlarmFactory alarm_factory_;
-  QuicBufferedPacketStore store_;
-  QuicSocketAddress self_address_;
-  QuicSocketAddress peer_address_;
-  std::string packet_content_;
-  QuicTime packet_time_;
-  QuicReceivedPacket packet_;
-  const ParsedQuicVersion invalid_version_;
-  const ParsedQuicVersion valid_version_;
-};
-
-TEST_F(QuicBufferedPacketStoreTest, SimpleEnqueueAndDeliverPacket) {
-  QuicConnectionId connection_id = TestConnectionId(1);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
-  auto packets = store_.DeliverPackets(connection_id);
-  const std::list<BufferedPacket>& queue = packets.buffered_packets;
-  ASSERT_EQ(1u, queue.size());
-  ASSERT_FALSE(packets.parsed_chlo.has_value());
-  // There is no valid version because CHLO has not arrived.
-  EXPECT_EQ(invalid_version_, packets.version);
-  // Check content of the only packet in the queue.
-  EXPECT_EQ(packet_content_, queue.front().packet->AsStringPiece());
-  EXPECT_EQ(packet_time_, queue.front().packet->receipt_time());
-  EXPECT_EQ(peer_address_, queue.front().peer_address);
-  EXPECT_EQ(self_address_, queue.front().self_address);
-  // No more packets on connection 1 should remain in the store.
-  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-}
-
-TEST_F(QuicBufferedPacketStoreTest, DifferentPacketAddressOnOneConnection) {
-  QuicSocketAddress addr_with_new_port(QuicIpAddress::Any4(), 256);
-  QuicConnectionId connection_id = TestConnectionId(1);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       addr_with_new_port, invalid_version_, kNoParsedChlo);
-  std::list<BufferedPacket> queue =
-      store_.DeliverPackets(connection_id).buffered_packets;
-  ASSERT_EQ(2u, queue.size());
-  // The address migration path should be preserved.
-  EXPECT_EQ(peer_address_, queue.front().peer_address);
-  EXPECT_EQ(addr_with_new_port, queue.back().peer_address);
-}
-
-TEST_F(QuicBufferedPacketStoreTest,
-       EnqueueAndDeliverMultiplePacketsOnMultipleConnections) {
-  size_t num_connections = 10;
-  for (uint64_t conn_id = 1; conn_id <= num_connections; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                         peer_address_, invalid_version_, kNoParsedChlo);
-    store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                         peer_address_, invalid_version_, kNoParsedChlo);
-  }
-
-  // Deliver packets in reversed order.
-  for (uint64_t conn_id = num_connections; conn_id > 0; --conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    std::list<BufferedPacket> queue =
-        store_.DeliverPackets(connection_id).buffered_packets;
-    ASSERT_EQ(2u, queue.size());
-  }
-}
-
-TEST_F(QuicBufferedPacketStoreTest,
-       FailToBufferTooManyPacketsOnExistingConnection) {
-  // Tests that for one connection, only limited number of packets can be
-  // buffered.
-  size_t num_packets = kDefaultMaxUndecryptablePackets + 1;
-  QuicConnectionId connection_id = TestConnectionId(1);
-  // Arrived CHLO packet shouldn't affect how many non-CHLO pacekts store can
-  // keep.
-  EXPECT_EQ(
-      QuicBufferedPacketStore::SUCCESS,
-      store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                           peer_address_, valid_version_, kDefaultParsedChlo));
-  for (size_t i = 1; i <= num_packets; ++i) {
-    // Only first |kDefaultMaxUndecryptablePackets packets| will be buffered.
-    EnqueuePacketResult result =
-        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                             peer_address_, invalid_version_, kNoParsedChlo);
-    if (i <= kDefaultMaxUndecryptablePackets) {
-      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
-    } else {
-      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_PACKETS, result);
-    }
-  }
-
-  // Only first |kDefaultMaxUndecryptablePackets| non-CHLO packets and CHLO are
-  // buffered.
-  EXPECT_EQ(kDefaultMaxUndecryptablePackets + 1,
-            store_.DeliverPackets(connection_id).buffered_packets.size());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, ReachNonChloConnectionUpperLimit) {
-  // Tests that store can only keep early arrived packets for limited number of
-  // connections.
-  const size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
-  for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    EnqueuePacketResult result =
-        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                             peer_address_, invalid_version_, kNoParsedChlo);
-    if (conn_id <= kMaxConnectionsWithoutCHLO) {
-      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
-    } else {
-      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
-    }
-  }
-  // Store only keeps early arrived packets upto |kNumConnections| connections.
-  for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    std::list<BufferedPacket> queue =
-        store_.DeliverPackets(connection_id).buffered_packets;
-    if (conn_id <= kMaxConnectionsWithoutCHLO) {
-      EXPECT_EQ(1u, queue.size());
-    } else {
-      EXPECT_EQ(0u, queue.size());
-    }
-  }
-}
-
-TEST_F(QuicBufferedPacketStoreTest,
-       FullStoreFailToBufferDataPacketOnNewConnection) {
-  // Send enough CHLOs so that store gets full before number of connections
-  // without CHLO reaches its upper limit.
-  size_t num_chlos =
-      kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
-  for (uint64_t conn_id = 1; conn_id <= num_chlos; ++conn_id) {
-    EXPECT_EQ(EnqueuePacketResult::SUCCESS,
-              store_.EnqueuePacket(TestConnectionId(conn_id), false, packet_,
-                                   self_address_, peer_address_, valid_version_,
-                                   kDefaultParsedChlo));
-  }
-
-  // Send data packets on another |kMaxConnectionsWithoutCHLO| connections.
-  // Store should only be able to buffer till it's full.
-  for (uint64_t conn_id = num_chlos + 1;
-       conn_id <= (kDefaultMaxConnectionsInStore + 1); ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    EnqueuePacketResult result =
-        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                             peer_address_, valid_version_, kDefaultParsedChlo);
-    if (conn_id <= kDefaultMaxConnectionsInStore) {
-      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
-    } else {
-      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
-    }
-  }
-}
-
-TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
-  // Buffer data packets on different connections upto limit.
-  for (uint64_t conn_id = 1; conn_id <= kMaxConnectionsWithoutCHLO; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    EXPECT_EQ(
-        EnqueuePacketResult::SUCCESS,
-        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                             peer_address_, invalid_version_, kNoParsedChlo));
-  }
-
-  // Buffer CHLOs on other connections till store is full.
-  for (size_t i = kMaxConnectionsWithoutCHLO + 1;
-       i <= kDefaultMaxConnectionsInStore + 1; ++i) {
-    QuicConnectionId connection_id = TestConnectionId(i);
-    EnqueuePacketResult rs =
-        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                             peer_address_, valid_version_, kDefaultParsedChlo);
-    if (i <= kDefaultMaxConnectionsInStore) {
-      EXPECT_EQ(EnqueuePacketResult::SUCCESS, rs);
-      EXPECT_TRUE(store_.HasChloForConnection(connection_id));
-    } else {
-      // Last CHLO can't be buffered because store is full.
-      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, rs);
-      EXPECT_FALSE(store_.HasChloForConnection(connection_id));
-    }
-  }
-
-  // But buffering a CHLO belonging to a connection already has data packet
-  // buffered in the store should success. This is the connection should be
-  // delivered at last.
-  EXPECT_EQ(
-      EnqueuePacketResult::SUCCESS,
-      store_.EnqueuePacket(
-          /*connection_id=*/TestConnectionId(1), false, packet_, self_address_,
-          peer_address_, valid_version_, kDefaultParsedChlo));
-  EXPECT_TRUE(store_.HasChloForConnection(
-      /*connection_id=*/TestConnectionId(1)));
-
-  QuicConnectionId delivered_conn_id;
-  for (size_t i = 0;
-       i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
-       ++i) {
-    if (i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO) {
-      // Only CHLO is buffered.
-      EXPECT_EQ(1u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
-                        .buffered_packets.size());
-      EXPECT_EQ(TestConnectionId(i + kMaxConnectionsWithoutCHLO + 1),
-                delivered_conn_id);
-    } else {
-      EXPECT_EQ(2u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
-                        .buffered_packets.size());
-      EXPECT_EQ(TestConnectionId(1u), delivered_conn_id);
-    }
-  }
-  EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-// Tests that store expires long-staying connections appropriately for
-// connections both with and without CHLOs.
-TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
-  QuicConnectionId connection_id = TestConnectionId(1);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  EXPECT_EQ(
-      EnqueuePacketResult::SUCCESS,
-      store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                           peer_address_, valid_version_, kDefaultParsedChlo));
-  QuicConnectionId connection_id2 = TestConnectionId(2);
-  EXPECT_EQ(
-      EnqueuePacketResult::SUCCESS,
-      store_.EnqueuePacket(connection_id2, false, packet_, self_address_,
-                           peer_address_, invalid_version_, kNoParsedChlo));
-
-  // CHLO on connection 3 arrives 1ms later.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  QuicConnectionId connection_id3 = TestConnectionId(3);
-  // Use different client address to differetiate packets from different
-  // connections.
-  QuicSocketAddress another_client_address(QuicIpAddress::Any4(), 255);
-  store_.EnqueuePacket(connection_id3, false, packet_, self_address_,
-                       another_client_address, valid_version_,
-                       kDefaultParsedChlo);
-
-  // Advance clock to the time when connection 1 and 2 expires.
-  clock_.AdvanceTime(
-      QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
-      clock_.ApproximateNow());
-  ASSERT_GE(clock_.ApproximateNow(),
-            QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline());
-  // Fire alarm to remove long-staying connection 1 and 2 packets.
-  alarm_factory_.FireAlarm(
-      QuicBufferedPacketStorePeer::expiration_alarm(&store_));
-  EXPECT_EQ(1u, visitor_.last_expired_packet_queue_.buffered_packets.size());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id2));
-
-  // Try to deliver packets, but packet queue has been removed so no
-  // packets can be returned.
-  ASSERT_EQ(0u, store_.DeliverPackets(connection_id).buffered_packets.size());
-  ASSERT_EQ(0u, store_.DeliverPackets(connection_id2).buffered_packets.size());
-  QuicConnectionId delivered_conn_id;
-  auto queue = store_.DeliverPacketsForNextConnection(&delivered_conn_id)
-                   .buffered_packets;
-  // Connection 3 is the next to be delivered as connection 1 already expired.
-  EXPECT_EQ(connection_id3, delivered_conn_id);
-  ASSERT_EQ(1u, queue.size());
-  // Packets in connection 3 should use another peer address.
-  EXPECT_EQ(another_client_address, queue.front().peer_address);
-
-  // Test the alarm is reset by enqueueing 2 packets for 4th connection and wait
-  // for them to expire.
-  QuicConnectionId connection_id4 = TestConnectionId(4);
-  store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  clock_.AdvanceTime(
-      QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
-      clock_.ApproximateNow());
-  alarm_factory_.FireAlarm(
-      QuicBufferedPacketStorePeer::expiration_alarm(&store_));
-  // |last_expired_packet_queue_| should be updated.
-  EXPECT_EQ(2u, visitor_.last_expired_packet_queue_.buffered_packets.size());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, SimpleDiscardPackets) {
-  QuicConnectionId connection_id = TestConnectionId(1);
-
-  // Enqueue some packets
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-
-  // Dicard the packets
-  store_.DiscardPackets(connection_id);
-
-  // No packets on connection 1 should remain in the store
-  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-
-  // Check idempotency
-  store_.DiscardPackets(connection_id);
-  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, DiscardWithCHLOs) {
-  QuicConnectionId connection_id = TestConnectionId(1);
-
-  // Enqueue some packets, which include a CHLO
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, valid_version_, kDefaultParsedChlo);
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
-  EXPECT_TRUE(store_.HasChlosBuffered());
-
-  // Dicard the packets
-  store_.DiscardPackets(connection_id);
-
-  // No packets on connection 1 should remain in the store
-  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-
-  // Check idempotency
-  store_.DiscardPackets(connection_id);
-  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, MultipleDiscardPackets) {
-  QuicConnectionId connection_id_1 = TestConnectionId(1);
-  QuicConnectionId connection_id_2 = TestConnectionId(2);
-
-  // Enqueue some packets for two connection IDs
-  store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-  store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
-                       peer_address_, invalid_version_, kNoParsedChlo);
-
-  ParsedClientHello parsed_chlo;
-  parsed_chlo.alpns.push_back("h3");
-  parsed_chlo.sni = TestHostname();
-  store_.EnqueuePacket(connection_id_2, false, packet_, self_address_,
-                       peer_address_, valid_version_, parsed_chlo);
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_1));
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
-  EXPECT_TRUE(store_.HasChlosBuffered());
-
-  // Discard the packets for connection 1
-  store_.DiscardPackets(connection_id_1);
-
-  // No packets on connection 1 should remain in the store
-  EXPECT_TRUE(store_.DeliverPackets(connection_id_1).buffered_packets.empty());
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id_1));
-  EXPECT_TRUE(store_.HasChlosBuffered());
-
-  // Packets on connection 2 should remain
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
-  auto packets = store_.DeliverPackets(connection_id_2);
-  EXPECT_EQ(1u, packets.buffered_packets.size());
-  ASSERT_EQ(1u, packets.parsed_chlo->alpns.size());
-  EXPECT_EQ("h3", packets.parsed_chlo->alpns[0]);
-  EXPECT_EQ(TestHostname(), packets.parsed_chlo->sni);
-  // Since connection_id_2's chlo arrives, verify version is set.
-  EXPECT_EQ(valid_version_, packets.version);
-  EXPECT_TRUE(store_.HasChlosBuffered());
-
-  // Discard the packets for connection 2
-  store_.DiscardPackets(connection_id_2);
-  EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, DiscardPacketsEmpty) {
-  // Check that DiscardPackets on an unknown connection ID is safe and does
-  // nothing.
-  QuicConnectionId connection_id = TestConnectionId(11235);
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-  store_.DiscardPackets(connection_id);
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.HasChlosBuffered());
-}
-
-TEST_F(QuicBufferedPacketStoreTest, IngestPacketForTlsChloExtraction) {
-  QuicConnectionId connection_id = TestConnectionId(1);
-  std::vector<std::string> alpns;
-  std::string sni;
-  bool resumption_attempted = false;
-  bool early_data_attempted = false;
-  QuicConfig config;
-
-  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
-  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
-                       peer_address_, valid_version_, kNoParsedChlo);
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
-
-  // The packet in 'packet_' is not a TLS CHLO packet.
-  EXPECT_FALSE(store_.IngestPacketForTlsChloExtraction(
-      connection_id, valid_version_, packet_, &alpns, &sni,
-      &resumption_attempted, &early_data_attempted));
-
-  store_.DiscardPackets(connection_id);
-
-  // Force the TLS CHLO to span multiple packets.
-  constexpr auto kCustomParameterId =
-      static_cast<TransportParameters::TransportParameterId>(0xff33);
-  std::string kCustomParameterValue(2000, '-');
-  config.custom_transport_parameters_to_send()[kCustomParameterId] =
-      kCustomParameterValue;
-  auto packets = GetFirstFlightOfPackets(valid_version_, config);
-  ASSERT_EQ(packets.size(), 2u);
-
-  store_.EnqueuePacket(connection_id, false, *packets[0], self_address_,
-                       peer_address_, valid_version_, kNoParsedChlo);
-  store_.EnqueuePacket(connection_id, false, *packets[1], self_address_,
-                       peer_address_, valid_version_, kNoParsedChlo);
-
-  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
-  EXPECT_FALSE(store_.IngestPacketForTlsChloExtraction(
-      connection_id, valid_version_, *packets[0], &alpns, &sni,
-      &resumption_attempted, &early_data_attempted));
-  EXPECT_TRUE(store_.IngestPacketForTlsChloExtraction(
-      connection_id, valid_version_, *packets[1], &alpns, &sni,
-      &resumption_attempted, &early_data_attempted));
-
-  EXPECT_THAT(alpns, ElementsAre(AlpnForVersion(valid_version_)));
-  EXPECT_EQ(sni, TestHostname());
-
-  EXPECT_FALSE(resumption_attempted);
-  EXPECT_FALSE(early_data_attempted);
-}
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_chaos_protector.cc b/quic/core/quic_chaos_protector.cc
deleted file mode 100644
index e21d26c..0000000
--- a/quic/core/quic_chaos_protector.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_chaos_protector.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_padding_frame.h"
-#include "quic/core/frames/quic_ping_frame.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-QuicChaosProtector::QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
-                                       int num_padding_bytes,
-                                       size_t packet_size,
-                                       QuicFramer* framer,
-                                       QuicRandom* random)
-    : packet_size_(packet_size),
-      crypto_data_length_(crypto_frame.data_length),
-      crypto_buffer_offset_(crypto_frame.offset),
-      level_(crypto_frame.level),
-      remaining_padding_bytes_(num_padding_bytes),
-      framer_(framer),
-      random_(random) {
-  QUICHE_DCHECK_NE(framer_, nullptr);
-  QUICHE_DCHECK_NE(framer_->data_producer(), nullptr);
-  QUICHE_DCHECK_NE(random_, nullptr);
-}
-
-QuicChaosProtector::~QuicChaosProtector() {
-  DeleteFrames(&frames_);
-}
-
-absl::optional<size_t> QuicChaosProtector::BuildDataPacket(
-    const QuicPacketHeader& header,
-    char* buffer) {
-  if (!CopyCryptoDataToLocalBuffer()) {
-    return absl::nullopt;
-  }
-  SplitCryptoFrame();
-  AddPingFrames();
-  SpreadPadding();
-  ReorderFrames();
-  return BuildPacket(header, buffer);
-}
-
-WriteStreamDataResult QuicChaosProtector::WriteStreamData(
-    QuicStreamId id,
-    QuicStreamOffset offset,
-    QuicByteCount data_length,
-    QuicDataWriter* /*writer*/) {
-  QUIC_BUG(chaos stream) << "This should never be called; id " << id
-                         << " offset " << offset << " data_length "
-                         << data_length;
-  return STREAM_MISSING;
-}
-
-bool QuicChaosProtector::WriteCryptoData(EncryptionLevel level,
-                                         QuicStreamOffset offset,
-                                         QuicByteCount data_length,
-                                         QuicDataWriter* writer) {
-  if (level != level_) {
-    QUIC_BUG(chaos bad level) << "Unexpected " << level << " != " << level_;
-    return false;
-  }
-  // This is `offset + data_length > buffer_offset_ + buffer_length_`
-  // but with integer overflow protection.
-  if (offset < crypto_buffer_offset_ || data_length > crypto_data_length_ ||
-      offset - crypto_buffer_offset_ > crypto_data_length_ - data_length) {
-    QUIC_BUG(chaos bad lengths)
-        << "Unexpected buffer_offset_ " << crypto_buffer_offset_ << " offset "
-        << offset << " buffer_length_ " << crypto_data_length_
-        << " data_length " << data_length;
-    return false;
-  }
-  writer->WriteBytes(&crypto_data_buffer_[offset - crypto_buffer_offset_],
-                     data_length);
-  return true;
-}
-
-bool QuicChaosProtector::CopyCryptoDataToLocalBuffer() {
-  crypto_frame_buffer_ = std::make_unique<char[]>(packet_size_);
-  frames_.push_back(QuicFrame(
-      new QuicCryptoFrame(level_, crypto_buffer_offset_, crypto_data_length_)));
-  // We use |framer_| to serialize the CRYPTO frame in order to extract its
-  // data from the crypto data producer. This ensures that we reuse the
-  // usual serialization code path, but has the downside that we then need to
-  // parse the offset and length in order to skip over those fields.
-  QuicDataWriter writer(packet_size_, crypto_frame_buffer_.get());
-  if (!framer_->AppendCryptoFrame(*frames_.front().crypto_frame, &writer)) {
-    QUIC_BUG(chaos write crypto data);
-    return false;
-  }
-  QuicDataReader reader(crypto_frame_buffer_.get(), writer.length());
-  uint64_t parsed_offset, parsed_length;
-  if (!reader.ReadVarInt62(&parsed_offset) ||
-      !reader.ReadVarInt62(&parsed_length)) {
-    QUIC_BUG(chaos parse crypto frame);
-    return false;
-  }
-
-  absl::string_view crypto_data = reader.ReadRemainingPayload();
-  crypto_data_buffer_ = crypto_data.data();
-
-  QUICHE_DCHECK_EQ(parsed_offset, crypto_buffer_offset_);
-  QUICHE_DCHECK_EQ(parsed_length, crypto_data_length_);
-  QUICHE_DCHECK_EQ(parsed_length, crypto_data.length());
-
-  return true;
-}
-
-void QuicChaosProtector::SplitCryptoFrame() {
-  const int max_overhead_of_adding_a_crypto_frame =
-      static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
-          crypto_buffer_offset_ + crypto_data_length_, crypto_data_length_));
-  // Pick a random number of CRYPTO frames to add.
-  constexpr uint64_t kMaxAddedCryptoFrames = 10;
-  const uint64_t num_added_crypto_frames =
-      random_->InsecureRandUint64() % (kMaxAddedCryptoFrames + 1);
-  for (uint64_t i = 0; i < num_added_crypto_frames; i++) {
-    if (remaining_padding_bytes_ < max_overhead_of_adding_a_crypto_frame) {
-      break;
-    }
-    // Pick a random frame and split it by shrinking the picked frame and
-    // moving the second half of its data to a new frame that is then appended
-    // to |frames|.
-    size_t frame_to_split_index =
-        random_->InsecureRandUint64() % frames_.size();
-    QuicCryptoFrame* frame_to_split =
-        frames_[frame_to_split_index].crypto_frame;
-    if (frame_to_split->data_length <= 1) {
-      continue;
-    }
-    const int frame_to_split_old_overhead =
-        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
-            frame_to_split->offset, frame_to_split->data_length));
-    const QuicPacketLength frame_to_split_new_data_length =
-        1 + (random_->InsecureRandUint64() % (frame_to_split->data_length - 1));
-    const QuicPacketLength new_frame_data_length =
-        frame_to_split->data_length - frame_to_split_new_data_length;
-    const QuicStreamOffset new_frame_offset =
-        frame_to_split->offset + frame_to_split_new_data_length;
-    frame_to_split->data_length -= new_frame_data_length;
-    frames_.push_back(QuicFrame(
-        new QuicCryptoFrame(level_, new_frame_offset, new_frame_data_length)));
-    const int frame_to_split_new_overhead =
-        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
-            frame_to_split->offset, frame_to_split->data_length));
-    const int new_frame_overhead =
-        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
-            new_frame_offset, new_frame_data_length));
-    QUICHE_DCHECK_LE(frame_to_split_new_overhead, frame_to_split_old_overhead);
-    // Readjust padding based on increased overhead.
-    remaining_padding_bytes_ -= new_frame_overhead;
-    remaining_padding_bytes_ -= frame_to_split_new_overhead;
-    remaining_padding_bytes_ += frame_to_split_old_overhead;
-  }
-}
-
-void QuicChaosProtector::AddPingFrames() {
-  if (remaining_padding_bytes_ == 0) {
-    return;
-  }
-  constexpr uint64_t kMaxAddedPingFrames = 10;
-  const uint64_t num_ping_frames =
-      random_->InsecureRandUint64() %
-      std::min<uint64_t>(kMaxAddedPingFrames, remaining_padding_bytes_);
-  for (uint64_t i = 0; i < num_ping_frames; i++) {
-    frames_.push_back(QuicFrame(QuicPingFrame()));
-  }
-  remaining_padding_bytes_ -= static_cast<int>(num_ping_frames);
-}
-
-void QuicChaosProtector::ReorderFrames() {
-  // Walk the array backwards and swap each frame with a random earlier one.
-  for (size_t i = frames_.size() - 1; i > 0; i--) {
-    std::swap(frames_[i], frames_[random_->InsecureRandUint64() % (i + 1)]);
-  }
-}
-
-void QuicChaosProtector::SpreadPadding() {
-  for (auto it = frames_.begin(); it != frames_.end(); ++it) {
-    const int padding_bytes_in_this_frame =
-        random_->InsecureRandUint64() % (remaining_padding_bytes_ + 1);
-    if (padding_bytes_in_this_frame <= 0) {
-      continue;
-    }
-    it = frames_.insert(
-        it, QuicFrame(QuicPaddingFrame(padding_bytes_in_this_frame)));
-    ++it;  // Skip over the padding frame we just added.
-    remaining_padding_bytes_ -= padding_bytes_in_this_frame;
-  }
-  if (remaining_padding_bytes_ > 0) {
-    frames_.push_back(QuicFrame(QuicPaddingFrame(remaining_padding_bytes_)));
-  }
-}
-
-absl::optional<size_t> QuicChaosProtector::BuildPacket(
-    const QuicPacketHeader& header,
-    char* buffer) {
-  QuicStreamFrameDataProducer* original_data_producer =
-      framer_->data_producer();
-  framer_->set_data_producer(this);
-
-  size_t length =
-      framer_->BuildDataPacket(header, frames_, buffer, packet_size_, level_);
-
-  framer_->set_data_producer(original_data_producer);
-  if (length == 0) {
-    return absl::nullopt;
-  }
-  return length;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_chaos_protector.h b/quic/core/quic_chaos_protector.h
deleted file mode 100644
index 6bcd420..0000000
--- a/quic/core/quic_chaos_protector.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
-#define QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-namespace test {
-class QuicChaosProtectorTest;
-}
-
-// QuicChaosProtector will take a crypto frame and an amount of padding and
-// build a data packet that will parse to something equivalent.
-class QUIC_EXPORT_PRIVATE QuicChaosProtector
-    : public QuicStreamFrameDataProducer {
- public:
-  // |framer| and |random| must be valid for the lifetime of QuicChaosProtector.
-  explicit QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
-                              int num_padding_bytes,
-                              size_t packet_size,
-                              QuicFramer* framer,
-                              QuicRandom* random);
-
-  ~QuicChaosProtector() override;
-
-  QuicChaosProtector(const QuicChaosProtector&) = delete;
-  QuicChaosProtector(QuicChaosProtector&&) = delete;
-  QuicChaosProtector& operator=(const QuicChaosProtector&) = delete;
-  QuicChaosProtector& operator=(QuicChaosProtector&&) = delete;
-
-  // Attempts to build a data packet with chaos protection. If an error occurs,
-  // then absl::nullopt is returned. Otherwise returns the serialized length.
-  absl::optional<size_t> BuildDataPacket(const QuicPacketHeader& header,
-                                         char* buffer);
-
-  // From QuicStreamFrameDataProducer.
-  WriteStreamDataResult WriteStreamData(QuicStreamId id,
-                                        QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        QuicDataWriter* /*writer*/) override;
-  bool WriteCryptoData(EncryptionLevel level,
-                       QuicStreamOffset offset,
-                       QuicByteCount data_length,
-                       QuicDataWriter* writer) override;
-
- private:
-  friend class test::QuicChaosProtectorTest;
-
-  // Allocate the crypto data buffer, create the CRYPTO frame and write the
-  // crypto data to our buffer.
-  bool CopyCryptoDataToLocalBuffer();
-
-  // Split the CRYPTO frame in |frames_| into one or more CRYPTO frames that
-  // collectively represent the same data. Adjusts padding to compensate.
-  void SplitCryptoFrame();
-
-  // Add a random number of PING frames to |frames_| and adjust padding.
-  void AddPingFrames();
-
-  // Randomly reorder |frames_|.
-  void ReorderFrames();
-
-  // Add PADDING frames randomly between all other frames.
-  void SpreadPadding();
-
-  // Serialize |frames_| using |framer_|.
-  absl::optional<size_t> BuildPacket(const QuicPacketHeader& header,
-                                     char* buffer);
-
-  size_t packet_size_;
-  std::unique_ptr<char[]> crypto_frame_buffer_;
-  const char* crypto_data_buffer_ = nullptr;
-  QuicByteCount crypto_data_length_;
-  QuicStreamOffset crypto_buffer_offset_;
-  EncryptionLevel level_;
-  int remaining_padding_bytes_;
-  QuicFrames frames_;   // Inner frames owned, will be deleted by destructor.
-  QuicFramer* framer_;  // Unowned.
-  QuicRandom* random_;  // Unowned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
diff --git a/quic/core/quic_chaos_protector_test.cc b/quic/core/quic_chaos_protector_test.cc
deleted file mode 100644
index 675e00f..0000000
--- a/quic/core/quic_chaos_protector_test.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_chaos_protector.h"
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_quic_framer.h"
-
-namespace quic {
-namespace test {
-
-class QuicChaosProtectorTest : public QuicTestWithParam<ParsedQuicVersion>,
-                               public QuicStreamFrameDataProducer {
- public:
-  QuicChaosProtectorTest()
-      : version_(GetParam()),
-        framer_({version_}, QuicTime::Zero(), Perspective::IS_CLIENT,
-                kQuicDefaultConnectionIdLength),
-        validation_framer_({version_}),
-        random_(/*base=*/3),
-        level_(ENCRYPTION_INITIAL),
-        crypto_offset_(0),
-        crypto_data_length_(100),
-        crypto_frame_(level_, crypto_offset_, crypto_data_length_),
-        num_padding_bytes_(50),
-        packet_size_(1000),
-        packet_buffer_(std::make_unique<char[]>(packet_size_)) {
-    ReCreateChaosProtector();
-  }
-
-  void ReCreateChaosProtector() {
-    chaos_protector_ = std::make_unique<QuicChaosProtector>(
-        crypto_frame_, num_padding_bytes_, packet_size_,
-        SetupHeaderAndFramers(), &random_);
-  }
-
-  // From QuicStreamFrameDataProducer.
-  WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
-                                        QuicStreamOffset /*offset*/,
-                                        QuicByteCount /*data_length*/,
-                                        QuicDataWriter* /*writer*/) override {
-    ADD_FAILURE() << "This should never be called";
-    return STREAM_MISSING;
-  }
-
-  // From QuicStreamFrameDataProducer.
-  bool WriteCryptoData(EncryptionLevel level,
-                       QuicStreamOffset offset,
-                       QuicByteCount data_length,
-                       QuicDataWriter* writer) override {
-    EXPECT_EQ(level, level);
-    EXPECT_EQ(offset, crypto_offset_);
-    EXPECT_EQ(data_length, crypto_data_length_);
-    for (QuicByteCount i = 0; i < data_length; i++) {
-      EXPECT_TRUE(writer->WriteUInt8(static_cast<uint8_t>(i & 0xFF)));
-    }
-    return true;
-  }
-
- protected:
-  QuicFramer* SetupHeaderAndFramers() {
-    // Setup header.
-    header_.destination_connection_id = TestConnectionId();
-    header_.destination_connection_id_included = CONNECTION_ID_PRESENT;
-    header_.source_connection_id = EmptyQuicConnectionId();
-    header_.source_connection_id_included = CONNECTION_ID_PRESENT;
-    header_.reset_flag = false;
-    header_.version_flag = true;
-    header_.has_possible_stateless_reset_token = false;
-    header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
-    header_.version = version_;
-    header_.packet_number = QuicPacketNumber(1);
-    header_.form = IETF_QUIC_LONG_HEADER_PACKET;
-    header_.long_packet_type = INITIAL;
-    header_.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header_.length_length = kQuicDefaultLongHeaderLengthLength;
-    // Setup validation framer.
-    validation_framer_.framer()->SetInitialObfuscators(
-        header_.destination_connection_id);
-    // Setup framer.
-    framer_.SetInitialObfuscators(header_.destination_connection_id);
-    framer_.set_data_producer(this);
-    return &framer_;
-  }
-
-  void BuildEncryptAndParse() {
-    absl::optional<size_t> length =
-        chaos_protector_->BuildDataPacket(header_, packet_buffer_.get());
-    ASSERT_TRUE(length.has_value());
-    ASSERT_GT(length.value(), 0u);
-    size_t encrypted_length = framer_.EncryptInPlace(
-        level_, header_.packet_number,
-        GetStartOfEncryptedData(framer_.transport_version(), header_),
-        length.value(), packet_size_, packet_buffer_.get());
-    ASSERT_GT(encrypted_length, 0u);
-    ASSERT_TRUE(validation_framer_.ProcessPacket(QuicEncryptedPacket(
-        absl::string_view(packet_buffer_.get(), encrypted_length))));
-  }
-
-  void ResetOffset(QuicStreamOffset offset) {
-    crypto_offset_ = offset;
-    crypto_frame_.offset = offset;
-    ReCreateChaosProtector();
-  }
-
-  void ResetLength(QuicByteCount length) {
-    crypto_data_length_ = length;
-    crypto_frame_.data_length = length;
-    ReCreateChaosProtector();
-  }
-
-  ParsedQuicVersion version_;
-  QuicPacketHeader header_;
-  QuicFramer framer_;
-  SimpleQuicFramer validation_framer_;
-  MockRandom random_;
-  EncryptionLevel level_;
-  QuicStreamOffset crypto_offset_;
-  QuicByteCount crypto_data_length_;
-  QuicCryptoFrame crypto_frame_;
-  int num_padding_bytes_;
-  size_t packet_size_;
-  std::unique_ptr<char[]> packet_buffer_;
-  std::unique_ptr<QuicChaosProtector> chaos_protector_;
-};
-
-namespace {
-
-ParsedQuicVersionVector TestVersions() {
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version.UsesCryptoFrames()) {
-      versions.push_back(version);
-    }
-  }
-  return versions;
-}
-
-INSTANTIATE_TEST_SUITE_P(QuicChaosProtectorTests,
-                         QuicChaosProtectorTest,
-                         ::testing::ValuesIn(TestVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicChaosProtectorTest, Main) {
-  BuildEncryptAndParse();
-  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, 0u);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
-  ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
-  ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
-  EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
-}
-
-TEST_P(QuicChaosProtectorTest, DifferentRandom) {
-  random_.ResetBase(4);
-  BuildEncryptAndParse();
-  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
-  ASSERT_EQ(validation_framer_.ping_frames().size(), 4u);
-  ASSERT_EQ(validation_framer_.padding_frames().size(), 8u);
-}
-
-TEST_P(QuicChaosProtectorTest, RandomnessZero) {
-  random_.ResetBase(0);
-  BuildEncryptAndParse();
-  ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
-            crypto_data_length_);
-  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
-  ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
-}
-
-TEST_P(QuicChaosProtectorTest, Offset) {
-  ResetOffset(123);
-  BuildEncryptAndParse();
-  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
-  ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
-  ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
-  EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
-}
-
-TEST_P(QuicChaosProtectorTest, OffsetAndRandomnessZero) {
-  ResetOffset(123);
-  random_.ResetBase(0);
-  BuildEncryptAndParse();
-  ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
-            crypto_data_length_);
-  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
-  ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
-}
-
-TEST_P(QuicChaosProtectorTest, ZeroRemainingBytesAfterSplit) {
-  QuicPacketLength new_length = 63;
-  num_padding_bytes_ = QuicFramer::GetMinCryptoFrameSize(
-      crypto_frame_.offset + new_length, new_length);
-  ResetLength(new_length);
-  BuildEncryptAndParse();
-
-  ASSERT_EQ(validation_framer_.crypto_frames().size(), 2u);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
-  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 4);
-  EXPECT_EQ(validation_framer_.crypto_frames()[1]->offset, crypto_offset_ + 4);
-  EXPECT_EQ(validation_framer_.crypto_frames()[1]->data_length,
-            crypto_data_length_ - 4);
-  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_clock.cc b/quic/core/quic_clock.cc
deleted file mode 100644
index 4d865b5..0000000
--- a/quic/core/quic_clock.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_clock.h"
-
-#include <limits>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicClock::QuicClock()
-    : is_calibrated_(false), calibration_offset_(QuicTime::Delta::Zero()) {}
-
-QuicClock::~QuicClock() {}
-
-QuicTime::Delta QuicClock::ComputeCalibrationOffset() const {
-  // In the ideal world, all we need to do is to return the difference of
-  // WallNow() and Now(). In the real world, things like context switch may
-  // happen between the calls to WallNow() and Now(), causing their difference
-  // to be arbitrarily large, so we repeat the calculation many times and use
-  // the one with the minimum difference as the true offset.
-  int64_t min_offset_us = std::numeric_limits<int64_t>::max();
-
-  for (int i = 0; i < 128; ++i) {
-    int64_t now_in_us = (Now() - QuicTime::Zero()).ToMicroseconds();
-    int64_t wallnow_in_us =
-        static_cast<int64_t>(WallNow().ToUNIXMicroseconds());
-
-    int64_t offset_us = wallnow_in_us - now_in_us;
-    if (offset_us < min_offset_us) {
-      min_offset_us = offset_us;
-    }
-  }
-
-  return QuicTime::Delta::FromMicroseconds(min_offset_us);
-}
-
-void QuicClock::SetCalibrationOffset(QuicTime::Delta offset) {
-  QUICHE_DCHECK(!is_calibrated_) << "A clock should only be calibrated once";
-  calibration_offset_ = offset;
-  is_calibrated_ = true;
-}
-
-QuicTime QuicClock::ConvertWallTimeToQuicTime(
-    const QuicWallTime& walltime) const {
-  if (is_calibrated_) {
-    int64_t time_in_us = static_cast<int64_t>(walltime.ToUNIXMicroseconds()) -
-                         calibration_offset_.ToMicroseconds();
-    return QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(time_in_us);
-  }
-
-  //     ..........................
-  //     |            |           |
-  // unix epoch   |walltime|   WallNow()
-  //     ..........................
-  //            |     |           |
-  //     clock epoch  |         Now()
-  //               result
-  //
-  // result = Now() - (WallNow() - walltime)
-  return Now() - QuicTime::Delta::FromMicroseconds(
-                     WallNow()
-                         .Subtract(QuicTime::Delta::FromMicroseconds(
-                             walltime.ToUNIXMicroseconds()))
-                         .ToUNIXMicroseconds());
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_clock.h b/quic/core/quic_clock.h
deleted file mode 100644
index 6164caf..0000000
--- a/quic/core/quic_clock.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CLOCK_H_
-#define QUICHE_QUIC_CORE_QUIC_CLOCK_H_
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-
-/* API_DESCRIPTION
- QuicClock is used by QUIC core to get current time. Its instance is created by
- applications and passed into QuicDispatcher and QuicConnectionHelperInterface.
- API-DESCRIPTION */
-
-namespace quic {
-
-// Interface for retrieving the current time.
-class QUIC_EXPORT_PRIVATE QuicClock {
- public:
-  QuicClock();
-  virtual ~QuicClock();
-
-  QuicClock(const QuicClock&) = delete;
-  QuicClock& operator=(const QuicClock&) = delete;
-
-  // Compute the offset between this clock with the Unix Epoch clock.
-  // Return the calibrated offset between WallNow() and Now(), in the form of
-  // (wallnow_in_us - now_in_us).
-  // The return value can be used by SetCalibrationOffset() to actually
-  // calibrate the clock, or all instances of this clock type.
-  QuicTime::Delta ComputeCalibrationOffset() const;
-
-  // Calibrate this clock. A calibrated clock guarantees that the
-  // ConvertWallTimeToQuicTime() function always return the same result for the
-  // same walltime.
-  // Should not be called more than once for each QuicClock.
-  void SetCalibrationOffset(QuicTime::Delta offset);
-
-  // Returns the approximate current time as a QuicTime object.
-  virtual QuicTime ApproximateNow() const = 0;
-
-  // Returns the current time as a QuicTime object.
-  // Note: this use significant resources please use only if needed.
-  virtual QuicTime Now() const = 0;
-
-  // WallNow returns the current wall-time - a time that is consistent across
-  // different clocks.
-  virtual QuicWallTime WallNow() const = 0;
-
-  // Converts |walltime| to a QuicTime relative to this clock's epoch.
-  virtual QuicTime ConvertWallTimeToQuicTime(
-      const QuicWallTime& walltime) const;
-
- protected:
-  // Creates a new QuicTime using |time_us| as the internal value.
-  QuicTime CreateTimeFromMicroseconds(uint64_t time_us) const {
-    return QuicTime(time_us);
-  }
-
- private:
-  // True if |calibration_offset_| is valid.
-  bool is_calibrated_;
-  // If |is_calibrated_|, |calibration_offset_| is the (fixed) offset between
-  // the Unix Epoch clock and this clock.
-  // In other words, the offset between WallNow() and Now().
-  QuicTime::Delta calibration_offset_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CLOCK_H_
diff --git a/quic/core/quic_coalesced_packet.cc b/quic/core/quic_coalesced_packet.cc
deleted file mode 100644
index dcfcb09..0000000
--- a/quic/core/quic_coalesced_packet.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_coalesced_packet.h"
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicCoalescedPacket::QuicCoalescedPacket()
-    : length_(0), max_packet_length_(0) {}
-
-QuicCoalescedPacket::~QuicCoalescedPacket() {
-  Clear();
-}
-
-bool QuicCoalescedPacket::MaybeCoalescePacket(
-    const SerializedPacket& packet, const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    quiche::QuicheBufferAllocator* allocator,
-    QuicPacketLength current_max_packet_length) {
-  if (packet.encrypted_length == 0) {
-    QUIC_BUG(quic_bug_10611_1) << "Trying to coalesce an empty packet";
-    return true;
-  }
-  if (length_ == 0) {
-#ifndef NDEBUG
-    for (const auto& buffer : encrypted_buffers_) {
-      QUICHE_DCHECK(buffer.empty());
-    }
-#endif
-    QUICHE_DCHECK(initial_packet_ == nullptr);
-    // This is the first packet, set max_packet_length and self/peer
-    // addresses.
-    max_packet_length_ = current_max_packet_length;
-    self_address_ = self_address;
-    peer_address_ = peer_address;
-  } else {
-    if (self_address_ != self_address || peer_address_ != peer_address) {
-      // Do not coalesce packet with different self/peer addresses.
-      QUIC_DLOG(INFO)
-          << "Cannot coalesce packet because self/peer address changed";
-      return false;
-    }
-    if (max_packet_length_ != current_max_packet_length) {
-      QUIC_BUG(quic_bug_10611_2)
-          << "Max packet length changes in the middle of the write path";
-      return false;
-    }
-    if (ContainsPacketOfEncryptionLevel(packet.encryption_level)) {
-      // Do not coalesce packets of the same encryption level.
-      return false;
-    }
-  }
-
-  if (length_ + packet.encrypted_length > max_packet_length_) {
-    // Packet does not fit.
-    return false;
-  }
-  QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
-                << packet.encryption_level
-                << ", encrypted_length: " << packet.encrypted_length
-                << ", current length: " << length_
-                << ", max_packet_length: " << max_packet_length_;
-  if (length_ > 0) {
-    QUIC_CODE_COUNT(QUIC_SUCCESSFULLY_COALESCED_MULTIPLE_PACKETS);
-  }
-  length_ += packet.encrypted_length;
-  transmission_types_[packet.encryption_level] = packet.transmission_type;
-  if (packet.encryption_level == ENCRYPTION_INITIAL) {
-    // Save a copy of ENCRYPTION_INITIAL packet (excluding encrypted buffer, as
-    // the packet will be re-serialized later).
-    initial_packet_ = absl::WrapUnique<SerializedPacket>(
-        CopySerializedPacket(packet, allocator, /*copy_buffer=*/false));
-    return true;
-  }
-  // Copy encrypted buffer of packets with other encryption levels.
-  encrypted_buffers_[packet.encryption_level] =
-      std::string(packet.encrypted_buffer, packet.encrypted_length);
-  return true;
-}
-
-void QuicCoalescedPacket::Clear() {
-  self_address_ = QuicSocketAddress();
-  peer_address_ = QuicSocketAddress();
-  length_ = 0;
-  max_packet_length_ = 0;
-  for (auto& packet : encrypted_buffers_) {
-    packet.clear();
-  }
-  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    transmission_types_[i] = NOT_RETRANSMISSION;
-  }
-  initial_packet_ = nullptr;
-}
-
-void QuicCoalescedPacket::NeuterInitialPacket() {
-  if (initial_packet_ == nullptr) {
-    return;
-  }
-  if (length_ < initial_packet_->encrypted_length) {
-    QUIC_BUG(quic_bug_10611_3)
-        << "length_: " << length_ << ", is less than initial packet length: "
-        << initial_packet_->encrypted_length;
-    Clear();
-    return;
-  }
-  length_ -= initial_packet_->encrypted_length;
-  if (length_ == 0) {
-    Clear();
-    return;
-  }
-  transmission_types_[ENCRYPTION_INITIAL] = NOT_RETRANSMISSION;
-  initial_packet_ = nullptr;
-}
-
-bool QuicCoalescedPacket::CopyEncryptedBuffers(char* buffer,
-                                               size_t buffer_len,
-                                               size_t* length_copied) const {
-  *length_copied = 0;
-  for (const auto& packet : encrypted_buffers_) {
-    if (packet.empty()) {
-      continue;
-    }
-    if (packet.length() > buffer_len) {
-      return false;
-    }
-    memcpy(buffer, packet.data(), packet.length());
-    buffer += packet.length();
-    buffer_len -= packet.length();
-    *length_copied += packet.length();
-  }
-  return true;
-}
-
-bool QuicCoalescedPacket::ContainsPacketOfEncryptionLevel(
-    EncryptionLevel level) const {
-  return !encrypted_buffers_[level].empty() ||
-         (level == ENCRYPTION_INITIAL && initial_packet_ != nullptr);
-}
-
-TransmissionType QuicCoalescedPacket::TransmissionTypeOfPacket(
-    EncryptionLevel level) const {
-  if (!ContainsPacketOfEncryptionLevel(level)) {
-    QUIC_BUG(quic_bug_10611_4)
-        << "Coalesced packet does not contain packet of encryption level: "
-        << EncryptionLevelToString(level);
-    return NOT_RETRANSMISSION;
-  }
-  return transmission_types_[level];
-}
-
-size_t QuicCoalescedPacket::NumberOfPackets() const {
-  size_t num_of_packets = 0;
-  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
-      ++num_of_packets;
-    }
-  }
-  return num_of_packets;
-}
-
-std::string QuicCoalescedPacket::ToString(size_t serialized_length) const {
-  // Total length and padding size.
-  std::string info = absl::StrCat(
-      "total_length: ", serialized_length,
-      " padding_size: ", serialized_length - length_, " packets: {");
-  // Packets' encryption levels.
-  bool first_packet = true;
-  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
-      absl::StrAppend(&info, first_packet ? "" : ", ",
-                      EncryptionLevelToString(static_cast<EncryptionLevel>(i)));
-      first_packet = false;
-    }
-  }
-  absl::StrAppend(&info, "}");
-  return info;
-}
-
-std::vector<size_t> QuicCoalescedPacket::packet_lengths() const {
-  std::vector<size_t> lengths;
-  for (const auto& packet : encrypted_buffers_) {
-    if (lengths.empty()) {
-      lengths.push_back(
-          initial_packet_ == nullptr ? 0 : initial_packet_->encrypted_length);
-    } else {
-      lengths.push_back(packet.length());
-    }
-  }
-  return lengths;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_coalesced_packet.h b/quic/core/quic_coalesced_packet.h
deleted file mode 100644
index 2e4165d..0000000
--- a/quic/core/quic_coalesced_packet.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
-#define QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-namespace test {
-class QuicCoalescedPacketPeer;
-}
-
-// QuicCoalescedPacket is used to buffer multiple packets which can be coalesced
-// into the same UDP datagram.
-class QUIC_EXPORT_PRIVATE QuicCoalescedPacket {
- public:
-  QuicCoalescedPacket();
-  ~QuicCoalescedPacket();
-
-  // Returns true if |packet| is successfully coalesced with existing packets.
-  // Returns false otherwise.
-  bool MaybeCoalescePacket(const SerializedPacket& packet,
-                           const QuicSocketAddress& self_address,
-                           const QuicSocketAddress& peer_address,
-                           quiche::QuicheBufferAllocator* allocator,
-                           QuicPacketLength current_max_packet_length);
-
-  // Clears this coalesced packet.
-  void Clear();
-
-  // Clears all state associated with initial_packet_.
-  void NeuterInitialPacket();
-
-  // Copies encrypted_buffers_ to |buffer| and sets |length_copied| to the
-  // copied amount. Returns false if copy fails (i.e., |buffer_len| is not
-  // enough).
-  bool CopyEncryptedBuffers(char* buffer,
-                            size_t buffer_len,
-                            size_t* length_copied) const;
-
-  std::string ToString(size_t serialized_length) const;
-
-  // Returns true if this coalesced packet contains packet of |level|.
-  bool ContainsPacketOfEncryptionLevel(EncryptionLevel level) const;
-
-  // Returns transmission type of packet of |level|. This should only be called
-  // when this coalesced packet contains packet of |level|.
-  TransmissionType TransmissionTypeOfPacket(EncryptionLevel level) const;
-
-  // Returns number of packets contained in this coalesced packet.
-  size_t NumberOfPackets() const;
-
-  const SerializedPacket* initial_packet() const {
-    return initial_packet_.get();
-  }
-
-  const QuicSocketAddress& self_address() const { return self_address_; }
-
-  const QuicSocketAddress& peer_address() const { return peer_address_; }
-
-  QuicPacketLength length() const { return length_; }
-
-  QuicPacketLength max_packet_length() const { return max_packet_length_; }
-
-  std::vector<size_t> packet_lengths() const;
-
- private:
-  friend class test::QuicCoalescedPacketPeer;
-
-  // self/peer addresses are set when trying to coalesce the first packet.
-  // Packets with different self/peer addresses cannot be coalesced.
-  QuicSocketAddress self_address_;
-  QuicSocketAddress peer_address_;
-  // Length of this coalesced packet.
-  QuicPacketLength length_;
-  // Max packet length. Do not try to coalesce packet when max packet length
-  // changes (e.g., with MTU discovery).
-  QuicPacketLength max_packet_length_;
-  // Copies of packets' encrypted buffers according to different encryption
-  // levels.
-  std::string encrypted_buffers_[NUM_ENCRYPTION_LEVELS];
-  // Recorded transmission type according to different encryption levels.
-  TransmissionType transmission_types_[NUM_ENCRYPTION_LEVELS];
-
-  // A copy of ENCRYPTION_INITIAL packet if this coalesced packet contains one.
-  // Null otherwise. Please note, the encrypted_buffer field is not copied. The
-  // frames are copied to allow it be re-serialized when this coalesced packet
-  // gets sent.
-  std::unique_ptr<SerializedPacket> initial_packet_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
diff --git a/quic/core/quic_coalesced_packet_test.cc b/quic/core/quic_coalesced_packet_test.cc
deleted file mode 100644
index f626891..0000000
--- a/quic/core/quic_coalesced_packet_test.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_coalesced_packet.h"
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QuicCoalescedPacketTest, MaybeCoalescePacket) {
-  QuicCoalescedPacket coalesced;
-  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
-            coalesced.ToString(0));
-  quiche::SimpleBufferAllocator allocator;
-  EXPECT_EQ(0u, coalesced.length());
-  EXPECT_EQ(0u, coalesced.NumberOfPackets());
-  char buffer[1000];
-  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
-  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
-  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 500, false, false);
-  packet1.transmission_type = PTO_RETRANSMISSION;
-  QuicAckFrame ack_frame(InitAckFrame(1));
-  packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
-  packet1.retransmittable_frames.push_back(
-      QuicFrame(QuicStreamFrame(1, true, 0, 100)));
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
-                                            &allocator, 1500));
-  EXPECT_EQ(PTO_RETRANSMISSION,
-            coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(500u, coalesced.length());
-  EXPECT_EQ(1u, coalesced.NumberOfPackets());
-  EXPECT_EQ(
-      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
-      coalesced.ToString(1500));
-
-  // Cannot coalesce packet of the same encryption level.
-  SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 500, false, false);
-  EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet2, self_address,
-                                             peer_address, &allocator, 1500));
-
-  SerializedPacket packet3(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 500, false, false);
-  packet3.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
-  packet3.encryption_level = ENCRYPTION_ZERO_RTT;
-  packet3.transmission_type = LOSS_RETRANSMISSION;
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
-                                            &allocator, 1500));
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(1000u, coalesced.length());
-  EXPECT_EQ(2u, coalesced.NumberOfPackets());
-  EXPECT_EQ(LOSS_RETRANSMISSION,
-            coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
-  EXPECT_EQ(
-      "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
-      "ENCRYPTION_ZERO_RTT}",
-      coalesced.ToString(1500));
-
-  SerializedPacket packet4(QuicPacketNumber(4), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 500, false, false);
-  packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  // Cannot coalesce packet of changed self/peer address.
-  EXPECT_FALSE(coalesced.MaybeCoalescePacket(
-      packet4, QuicSocketAddress(QuicIpAddress::Loopback4(), 3), peer_address,
-      &allocator, 1500));
-
-  // Packet does not fit.
-  SerializedPacket packet5(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 501, false, false);
-  packet5.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet5, self_address,
-                                             peer_address, &allocator, 1500));
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(1000u, coalesced.length());
-  EXPECT_EQ(2u, coalesced.NumberOfPackets());
-
-  // Max packet number length changed.
-  SerializedPacket packet6(QuicPacketNumber(6), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 100, false, false);
-  packet6.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  EXPECT_QUIC_BUG(coalesced.MaybeCoalescePacket(packet6, self_address,
-                                                peer_address, &allocator, 1000),
-                  "Max packet length changes in the middle of the write path");
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(1000u, coalesced.length());
-  EXPECT_EQ(2u, coalesced.NumberOfPackets());
-}
-
-TEST(QuicCoalescedPacketTest, CopyEncryptedBuffers) {
-  QuicCoalescedPacket coalesced;
-  quiche::SimpleBufferAllocator allocator;
-  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
-  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
-  std::string buffer(500, 'a');
-  std::string buffer2(500, 'b');
-  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer.data(), 500,
-                           /*has_ack=*/false, /*has_stop_waiting=*/false);
-  packet1.encryption_level = ENCRYPTION_ZERO_RTT;
-  SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer2.data(), 500,
-                           /*has_ack=*/false, /*has_stop_waiting=*/false);
-  packet2.encryption_level = ENCRYPTION_FORWARD_SECURE;
-
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
-                                            &allocator, 1500));
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
-                                            &allocator, 1500));
-  EXPECT_EQ(1000u, coalesced.length());
-
-  char copy_buffer[1000];
-  size_t length_copied = 0;
-  EXPECT_FALSE(
-      coalesced.CopyEncryptedBuffers(copy_buffer, 900, &length_copied));
-  ASSERT_TRUE(
-      coalesced.CopyEncryptedBuffers(copy_buffer, 1000, &length_copied));
-  EXPECT_EQ(1000u, length_copied);
-  char expected[1000];
-  memset(expected, 'a', 500);
-  memset(expected + 500, 'b', 500);
-  quiche::test::CompareCharArraysWithHexError("copied buffers", copy_buffer,
-                                              length_copied, expected, 1000);
-}
-
-TEST(QuicCoalescedPacketTest, NeuterInitialPacket) {
-  QuicCoalescedPacket coalesced;
-  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
-            coalesced.ToString(0));
-  // Noop when neutering initial packet on a empty coalescer.
-  coalesced.NeuterInitialPacket();
-  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
-            coalesced.ToString(0));
-
-  quiche::SimpleBufferAllocator allocator;
-  EXPECT_EQ(0u, coalesced.length());
-  char buffer[1000];
-  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
-  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
-  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 500, false, false);
-  packet1.transmission_type = PTO_RETRANSMISSION;
-  QuicAckFrame ack_frame(InitAckFrame(1));
-  packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
-  packet1.retransmittable_frames.push_back(
-      QuicFrame(QuicStreamFrame(1, true, 0, 100)));
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
-                                            &allocator, 1500));
-  EXPECT_EQ(PTO_RETRANSMISSION,
-            coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(500u, coalesced.length());
-  EXPECT_EQ(
-      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
-      coalesced.ToString(1500));
-  // Neuter initial packet.
-  coalesced.NeuterInitialPacket();
-  EXPECT_EQ(0u, coalesced.max_packet_length());
-  EXPECT_EQ(0u, coalesced.length());
-  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
-            coalesced.ToString(0));
-
-  // Coalesce initial packet again.
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
-                                            &allocator, 1500));
-
-  SerializedPacket packet2(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 500, false, false);
-  packet2.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
-  packet2.encryption_level = ENCRYPTION_ZERO_RTT;
-  packet2.transmission_type = LOSS_RETRANSMISSION;
-  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
-                                            &allocator, 1500));
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(1000u, coalesced.length());
-  EXPECT_EQ(LOSS_RETRANSMISSION,
-            coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
-  EXPECT_EQ(
-      "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
-      "ENCRYPTION_ZERO_RTT}",
-      coalesced.ToString(1500));
-
-  // Neuter initial packet.
-  coalesced.NeuterInitialPacket();
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(500u, coalesced.length());
-  EXPECT_EQ(
-      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_ZERO_RTT}",
-      coalesced.ToString(1500));
-
-  SerializedPacket packet3(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
-                           buffer, 501, false, false);
-  packet3.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  EXPECT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
-                                            &allocator, 1500));
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(1001u, coalesced.length());
-  // Neuter initial packet.
-  coalesced.NeuterInitialPacket();
-  EXPECT_EQ(1500u, coalesced.max_packet_length());
-  EXPECT_EQ(1001u, coalesced.length());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_config.cc b/quic/core/quic_config.cc
deleted file mode 100644
index 8313ef7..0000000
--- a/quic/core/quic_config.cc
+++ /dev/null
@@ -1,1424 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_config.h"
-
-#include <algorithm>
-#include <cstring>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Reads the value corresponding to |name_| from |msg| into |out|. If the
-// |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
-// to |default_value|.
-QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
-                         QuicTag tag,
-                         QuicConfigPresence presence,
-                         uint32_t default_value,
-                         uint32_t* out,
-                         std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-  QuicErrorCode error = msg.GetUint32(tag, out);
-  switch (error) {
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      if (presence == PRESENCE_REQUIRED) {
-        *error_details = "Missing " + QuicTagToString(tag);
-        break;
-      }
-      error = QUIC_NO_ERROR;
-      *out = default_value;
-      break;
-    case QUIC_NO_ERROR:
-      break;
-    default:
-      *error_details = "Bad " + QuicTagToString(tag);
-      break;
-  }
-  return error;
-}
-
-QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
-    : tag_(tag), presence_(presence) {}
-QuicConfigValue::~QuicConfigValue() {}
-
-QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
-    : QuicConfigValue(tag, presence),
-      has_send_value_(false),
-      has_receive_value_(false) {}
-QuicFixedUint32::~QuicFixedUint32() {}
-
-bool QuicFixedUint32::HasSendValue() const {
-  return has_send_value_;
-}
-
-uint32_t QuicFixedUint32::GetSendValue() const {
-  QUIC_BUG_IF(quic_bug_12743_1, !has_send_value_)
-      << "No send value to get for tag:" << QuicTagToString(tag_);
-  return send_value_;
-}
-
-void QuicFixedUint32::SetSendValue(uint32_t value) {
-  has_send_value_ = true;
-  send_value_ = value;
-}
-
-bool QuicFixedUint32::HasReceivedValue() const {
-  return has_receive_value_;
-}
-
-uint32_t QuicFixedUint32::GetReceivedValue() const {
-  QUIC_BUG_IF(quic_bug_12743_2, !has_receive_value_)
-      << "No receive value to get for tag:" << QuicTagToString(tag_);
-  return receive_value_;
-}
-
-void QuicFixedUint32::SetReceivedValue(uint32_t value) {
-  has_receive_value_ = true;
-  receive_value_ = value;
-}
-
-void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
-  if (tag_ == 0) {
-    QUIC_BUG(quic_bug_12743_3)
-        << "This parameter does not support writing to CryptoHandshakeMessage";
-    return;
-  }
-  if (has_send_value_) {
-    out->SetValue(tag_, send_value_);
-  }
-}
-
-QuicErrorCode QuicFixedUint32::ProcessPeerHello(
-    const CryptoHandshakeMessage& peer_hello,
-    HelloType /*hello_type*/,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-  if (tag_ == 0) {
-    *error_details =
-        "This parameter does not support reading from CryptoHandshakeMessage";
-    QUIC_BUG(quic_bug_10575_1) << *error_details;
-    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-  }
-  QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
-  switch (error) {
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      if (presence_ == PRESENCE_OPTIONAL) {
-        return QUIC_NO_ERROR;
-      }
-      *error_details = "Missing " + QuicTagToString(tag_);
-      break;
-    case QUIC_NO_ERROR:
-      has_receive_value_ = true;
-      break;
-    default:
-      *error_details = "Bad " + QuicTagToString(tag_);
-      break;
-  }
-  return error;
-}
-
-QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
-    : QuicConfigValue(name, presence),
-      has_send_value_(false),
-      has_receive_value_(false) {}
-
-QuicFixedUint62::~QuicFixedUint62() {}
-
-bool QuicFixedUint62::HasSendValue() const {
-  return has_send_value_;
-}
-
-uint64_t QuicFixedUint62::GetSendValue() const {
-  if (!has_send_value_) {
-    QUIC_BUG(quic_bug_10575_2)
-        << "No send value to get for tag:" << QuicTagToString(tag_);
-    return 0;
-  }
-  return send_value_;
-}
-
-void QuicFixedUint62::SetSendValue(uint64_t value) {
-  if (value > kVarInt62MaxValue) {
-    QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
-    value = kVarInt62MaxValue;
-  }
-  has_send_value_ = true;
-  send_value_ = value;
-}
-
-bool QuicFixedUint62::HasReceivedValue() const {
-  return has_receive_value_;
-}
-
-uint64_t QuicFixedUint62::GetReceivedValue() const {
-  if (!has_receive_value_) {
-    QUIC_BUG(quic_bug_10575_4)
-        << "No receive value to get for tag:" << QuicTagToString(tag_);
-    return 0;
-  }
-  return receive_value_;
-}
-
-void QuicFixedUint62::SetReceivedValue(uint64_t value) {
-  has_receive_value_ = true;
-  receive_value_ = value;
-}
-
-void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
-  if (!has_send_value_) {
-    return;
-  }
-  uint32_t send_value32;
-  if (send_value_ > std::numeric_limits<uint32_t>::max()) {
-    QUIC_BUG(quic_bug_10575_5) << "Attempting to send " << send_value_
-                               << " for tag:" << QuicTagToString(tag_);
-    send_value32 = std::numeric_limits<uint32_t>::max();
-  } else {
-    send_value32 = static_cast<uint32_t>(send_value_);
-  }
-  out->SetValue(tag_, send_value32);
-}
-
-QuicErrorCode QuicFixedUint62::ProcessPeerHello(
-    const CryptoHandshakeMessage& peer_hello,
-    HelloType /*hello_type*/,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-  uint32_t receive_value32;
-  QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
-  // GetUint32 is guaranteed to always initialize receive_value32.
-  receive_value_ = receive_value32;
-  switch (error) {
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      if (presence_ == PRESENCE_OPTIONAL) {
-        return QUIC_NO_ERROR;
-      }
-      *error_details = "Missing " + QuicTagToString(tag_);
-      break;
-    case QUIC_NO_ERROR:
-      has_receive_value_ = true;
-      break;
-    default:
-      *error_details = "Bad " + QuicTagToString(tag_);
-      break;
-  }
-  return error;
-}
-
-QuicFixedStatelessResetToken::QuicFixedStatelessResetToken(
-    QuicTag tag,
-    QuicConfigPresence presence)
-    : QuicConfigValue(tag, presence),
-      has_send_value_(false),
-      has_receive_value_(false) {}
-QuicFixedStatelessResetToken::~QuicFixedStatelessResetToken() {}
-
-bool QuicFixedStatelessResetToken::HasSendValue() const {
-  return has_send_value_;
-}
-
-const StatelessResetToken& QuicFixedStatelessResetToken::GetSendValue() const {
-  QUIC_BUG_IF(quic_bug_12743_4, !has_send_value_)
-      << "No send value to get for tag:" << QuicTagToString(tag_);
-  return send_value_;
-}
-
-void QuicFixedStatelessResetToken::SetSendValue(
-    const StatelessResetToken& value) {
-  has_send_value_ = true;
-  send_value_ = value;
-}
-
-bool QuicFixedStatelessResetToken::HasReceivedValue() const {
-  return has_receive_value_;
-}
-
-const StatelessResetToken& QuicFixedStatelessResetToken::GetReceivedValue()
-    const {
-  QUIC_BUG_IF(quic_bug_12743_5, !has_receive_value_)
-      << "No receive value to get for tag:" << QuicTagToString(tag_);
-  return receive_value_;
-}
-
-void QuicFixedStatelessResetToken::SetReceivedValue(
-    const StatelessResetToken& value) {
-  has_receive_value_ = true;
-  receive_value_ = value;
-}
-
-void QuicFixedStatelessResetToken::ToHandshakeMessage(
-    CryptoHandshakeMessage* out) const {
-  if (has_send_value_) {
-    out->SetValue(tag_, send_value_);
-  }
-}
-
-QuicErrorCode QuicFixedStatelessResetToken::ProcessPeerHello(
-    const CryptoHandshakeMessage& peer_hello,
-    HelloType /*hello_type*/,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-  QuicErrorCode error =
-      peer_hello.GetStatelessResetToken(tag_, &receive_value_);
-  switch (error) {
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      if (presence_ == PRESENCE_OPTIONAL) {
-        return QUIC_NO_ERROR;
-      }
-      *error_details = "Missing " + QuicTagToString(tag_);
-      break;
-    case QUIC_NO_ERROR:
-      has_receive_value_ = true;
-      break;
-    default:
-      *error_details = "Bad " + QuicTagToString(tag_);
-      break;
-  }
-  return error;
-}
-
-QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
-                                       QuicConfigPresence presence)
-    : QuicConfigValue(name, presence),
-      has_send_values_(false),
-      has_receive_values_(false) {}
-
-QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
-    default;
-
-QuicFixedTagVector::~QuicFixedTagVector() {}
-
-bool QuicFixedTagVector::HasSendValues() const {
-  return has_send_values_;
-}
-
-const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
-  QUIC_BUG_IF(quic_bug_12743_6, !has_send_values_)
-      << "No send values to get for tag:" << QuicTagToString(tag_);
-  return send_values_;
-}
-
-void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
-  has_send_values_ = true;
-  send_values_ = values;
-}
-
-bool QuicFixedTagVector::HasReceivedValues() const {
-  return has_receive_values_;
-}
-
-const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
-  QUIC_BUG_IF(quic_bug_12743_7, !has_receive_values_)
-      << "No receive value to get for tag:" << QuicTagToString(tag_);
-  return receive_values_;
-}
-
-void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
-  has_receive_values_ = true;
-  receive_values_ = values;
-}
-
-void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
-  if (has_send_values_) {
-    out->SetVector(tag_, send_values_);
-  }
-}
-
-QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
-    const CryptoHandshakeMessage& peer_hello,
-    HelloType /*hello_type*/,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-  QuicTagVector values;
-  QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
-  switch (error) {
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      if (presence_ == PRESENCE_OPTIONAL) {
-        return QUIC_NO_ERROR;
-      }
-      *error_details = "Missing " + QuicTagToString(tag_);
-      break;
-    case QUIC_NO_ERROR:
-      QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
-      has_receive_values_ = true;
-      receive_values_.insert(receive_values_.end(), values.begin(),
-                             values.end());
-      break;
-    default:
-      *error_details = "Bad " + QuicTagToString(tag_);
-      break;
-  }
-  return error;
-}
-
-QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
-                                               QuicConfigPresence presence)
-    : QuicConfigValue(tag, presence),
-      has_send_value_(false),
-      has_receive_value_(false) {}
-
-QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
-
-bool QuicFixedSocketAddress::HasSendValue() const {
-  return has_send_value_;
-}
-
-const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
-  QUIC_BUG_IF(quic_bug_12743_8, !has_send_value_)
-      << "No send value to get for tag:" << QuicTagToString(tag_);
-  return send_value_;
-}
-
-void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
-  has_send_value_ = true;
-  send_value_ = value;
-}
-
-bool QuicFixedSocketAddress::HasReceivedValue() const {
-  return has_receive_value_;
-}
-
-const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
-  QUIC_BUG_IF(quic_bug_12743_9, !has_receive_value_)
-      << "No receive value to get for tag:" << QuicTagToString(tag_);
-  return receive_value_;
-}
-
-void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
-  has_receive_value_ = true;
-  receive_value_ = value;
-}
-
-void QuicFixedSocketAddress::ToHandshakeMessage(
-    CryptoHandshakeMessage* out) const {
-  if (has_send_value_) {
-    QuicSocketAddressCoder address_coder(send_value_);
-    out->SetStringPiece(tag_, address_coder.Encode());
-  }
-}
-
-QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
-    const CryptoHandshakeMessage& peer_hello,
-    HelloType /*hello_type*/,
-    std::string* error_details) {
-  absl::string_view address;
-  if (!peer_hello.GetStringPiece(tag_, &address)) {
-    if (presence_ == PRESENCE_REQUIRED) {
-      *error_details = "Missing " + QuicTagToString(tag_);
-      return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
-    }
-  } else {
-    QuicSocketAddressCoder address_coder;
-    if (address_coder.Decode(address.data(), address.length())) {
-      SetReceivedValue(
-          QuicSocketAddress(address_coder.ip(), address_coder.port()));
-    }
-  }
-  return QUIC_NO_ERROR;
-}
-
-QuicConfig::QuicConfig()
-    : negotiated_(false),
-      max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
-      max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
-      max_undecryptable_packets_(0),
-      connection_options_(kCOPT, PRESENCE_OPTIONAL),
-      client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
-      max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
-      max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
-      max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
-      bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
-      initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
-      initial_max_stream_data_bytes_incoming_bidirectional_(0,
-                                                            PRESENCE_OPTIONAL),
-      initial_max_stream_data_bytes_outgoing_bidirectional_(0,
-                                                            PRESENCE_OPTIONAL),
-      initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
-      initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
-      initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
-      connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
-      alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
-      alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
-      stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
-      max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
-      min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
-      ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
-      max_udp_payload_size_(0, PRESENCE_OPTIONAL),
-      max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
-      active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
-  SetDefaults();
-}
-
-QuicConfig::QuicConfig(const QuicConfig& other) = default;
-
-QuicConfig::~QuicConfig() {}
-
-bool QuicConfig::SetInitialReceivedConnectionOptions(
-    const QuicTagVector& tags) {
-  if (HasReceivedConnectionOptions()) {
-    // If we have already received connection options (via handshake or due to
-    // a previous call), don't re-initialize.
-    return false;
-  }
-  connection_options_.SetReceivedValues(tags);
-  return true;
-}
-
-void QuicConfig::SetConnectionOptionsToSend(
-    const QuicTagVector& connection_options) {
-  connection_options_.SetSendValues(connection_options);
-}
-
-bool QuicConfig::HasReceivedConnectionOptions() const {
-  return connection_options_.HasReceivedValues();
-}
-
-const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
-  return connection_options_.GetReceivedValues();
-}
-
-bool QuicConfig::HasSendConnectionOptions() const {
-  return connection_options_.HasSendValues();
-}
-
-const QuicTagVector& QuicConfig::SendConnectionOptions() const {
-  return connection_options_.GetSendValues();
-}
-
-bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
-                                               Perspective perspective) const {
-  if (perspective == Perspective::IS_SERVER) {
-    if (HasReceivedConnectionOptions() &&
-        ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
-      return true;
-    }
-  } else if (HasSendConnectionOptions() &&
-             ContainsQuicTag(SendConnectionOptions(), tag)) {
-    return true;
-  }
-  return false;
-}
-
-void QuicConfig::SetClientConnectionOptions(
-    const QuicTagVector& client_connection_options) {
-  client_connection_options_.SetSendValues(client_connection_options);
-}
-
-bool QuicConfig::HasClientRequestedIndependentOption(
-    QuicTag tag,
-    Perspective perspective) const {
-  if (perspective == Perspective::IS_SERVER) {
-    return (HasReceivedConnectionOptions() &&
-            ContainsQuicTag(ReceivedConnectionOptions(), tag));
-  }
-
-  return (client_connection_options_.HasSendValues() &&
-          ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
-}
-
-const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
-    Perspective perspective) const {
-  static const QuicTagVector* no_options = new QuicTagVector;
-  if (perspective == Perspective::IS_SERVER) {
-    return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
-                                          : *no_options;
-  }
-
-  return client_connection_options_.HasSendValues()
-             ? client_connection_options_.GetSendValues()
-             : *no_options;
-}
-
-void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
-  if (idle_network_timeout.ToMicroseconds() <= 0) {
-    QUIC_BUG(quic_bug_10575_6)
-        << "Invalid idle network timeout " << idle_network_timeout;
-    return;
-  }
-  max_idle_timeout_to_send_ = idle_network_timeout;
-}
-
-QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
-  // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
-  // received the peer's values. This is true in production code but not in all
-  // of our tests that use a fake QuicConfig.
-  if (!received_max_idle_timeout_.has_value()) {
-    return max_idle_timeout_to_send_;
-  }
-  return received_max_idle_timeout_.value();
-}
-
-void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
-  max_bidirectional_streams_.SetSendValue(max_streams);
-}
-
-uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
-  return max_bidirectional_streams_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
-  return max_bidirectional_streams_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
-  return max_bidirectional_streams_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
-  max_unidirectional_streams_.SetSendValue(max_streams);
-}
-
-uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
-  return max_unidirectional_streams_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
-  return max_unidirectional_streams_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
-  return max_unidirectional_streams_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
-  max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
-}
-
-uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
-  return max_ack_delay_ms_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxAckDelayMs() const {
-  return max_ack_delay_ms_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
-  return max_ack_delay_ms_.GetReceivedValue();
-}
-
-void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
-  min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
-}
-
-uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
-  return min_ack_delay_ms_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMinAckDelayMs() const {
-  return min_ack_delay_ms_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
-  return min_ack_delay_ms_.GetReceivedValue();
-}
-
-void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
-  ack_delay_exponent_.SetSendValue(exponent);
-}
-
-uint32_t QuicConfig::GetAckDelayExponentToSend() const {
-  return ack_delay_exponent_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedAckDelayExponent() const {
-  return ack_delay_exponent_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedAckDelayExponent() const {
-  return ack_delay_exponent_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
-  max_udp_payload_size_.SetSendValue(max_udp_payload_size);
-}
-
-uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
-  return max_udp_payload_size_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxPacketSize() const {
-  return max_udp_payload_size_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedMaxPacketSize() const {
-  return max_udp_payload_size_.GetReceivedValue();
-}
-
-void QuicConfig::SetMaxDatagramFrameSizeToSend(
-    uint64_t max_datagram_frame_size) {
-  max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
-}
-
-uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
-  return max_datagram_frame_size_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
-  return max_datagram_frame_size_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
-  return max_datagram_frame_size_.GetReceivedValue();
-}
-
-void QuicConfig::SetActiveConnectionIdLimitToSend(
-    uint64_t active_connection_id_limit) {
-  active_connection_id_limit_.SetSendValue(active_connection_id_limit);
-}
-
-uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
-  return active_connection_id_limit_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
-  return active_connection_id_limit_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
-  return active_connection_id_limit_.GetReceivedValue();
-}
-
-bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
-  return bytes_for_connection_id_.HasSendValue();
-}
-
-void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
-  bytes_for_connection_id_.SetSendValue(bytes);
-}
-
-bool QuicConfig::HasReceivedBytesForConnectionId() const {
-  return bytes_for_connection_id_.HasReceivedValue();
-}
-
-uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
-  return bytes_for_connection_id_.GetReceivedValue();
-}
-
-void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
-  initial_round_trip_time_us_.SetSendValue(rtt);
-}
-
-bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
-  return initial_round_trip_time_us_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
-  return initial_round_trip_time_us_.GetReceivedValue();
-}
-
-bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
-  return initial_round_trip_time_us_.HasSendValue();
-}
-
-uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
-  return initial_round_trip_time_us_.GetSendValue();
-}
-
-void QuicConfig::SetInitialStreamFlowControlWindowToSend(
-    uint64_t window_bytes) {
-  if (window_bytes < kMinimumFlowControlSendWindow) {
-    QUIC_BUG(quic_bug_10575_7)
-        << "Initial stream flow control receive window (" << window_bytes
-        << ") cannot be set lower than minimum ("
-        << kMinimumFlowControlSendWindow << ").";
-    window_bytes = kMinimumFlowControlSendWindow;
-  }
-  initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
-  return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
-  return initial_stream_flow_control_window_bytes_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
-  return initial_stream_flow_control_window_bytes_.GetReceivedValue();
-}
-
-void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-    uint64_t window_bytes) {
-  initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
-      window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
-    const {
-  if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
-    return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
-  }
-  return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
-    const {
-  return initial_max_stream_data_bytes_incoming_bidirectional_
-      .HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
-    const {
-  return initial_max_stream_data_bytes_incoming_bidirectional_
-      .GetReceivedValue();
-}
-
-void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-    uint64_t window_bytes) {
-  initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
-      window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
-    const {
-  if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
-    return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
-  }
-  return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
-    const {
-  return initial_max_stream_data_bytes_outgoing_bidirectional_
-      .HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
-    const {
-  return initial_max_stream_data_bytes_outgoing_bidirectional_
-      .GetReceivedValue();
-}
-
-void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
-    uint64_t window_bytes) {
-  initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
-  if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
-    return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
-  }
-  return initial_stream_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
-  return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
-  return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
-}
-
-void QuicConfig::SetInitialSessionFlowControlWindowToSend(
-    uint64_t window_bytes) {
-  if (window_bytes < kMinimumFlowControlSendWindow) {
-    QUIC_BUG(quic_bug_10575_8)
-        << "Initial session flow control receive window (" << window_bytes
-        << ") cannot be set lower than default ("
-        << kMinimumFlowControlSendWindow << ").";
-    window_bytes = kMinimumFlowControlSendWindow;
-  }
-  initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
-}
-
-uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
-  return initial_session_flow_control_window_bytes_.GetSendValue();
-}
-
-bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
-  return initial_session_flow_control_window_bytes_.HasReceivedValue();
-}
-
-uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
-  return initial_session_flow_control_window_bytes_.GetReceivedValue();
-}
-
-void QuicConfig::SetDisableConnectionMigration() {
-  connection_migration_disabled_.SetSendValue(1);
-}
-
-bool QuicConfig::DisableConnectionMigration() const {
-  return connection_migration_disabled_.HasReceivedValue();
-}
-
-void QuicConfig::SetIPv6AlternateServerAddressToSend(
-    const QuicSocketAddress& alternate_server_address_ipv6) {
-  if (!alternate_server_address_ipv6.host().IsIPv6()) {
-    QUIC_BUG(quic_bug_10575_9)
-        << "Cannot use SetIPv6AlternateServerAddressToSend with "
-        << alternate_server_address_ipv6;
-    return;
-  }
-  alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
-}
-
-void QuicConfig::SetIPv6AlternateServerAddressToSend(
-    const QuicSocketAddress& alternate_server_address_ipv6,
-    const QuicConnectionId& connection_id,
-    const StatelessResetToken& stateless_reset_token) {
-  if (!alternate_server_address_ipv6.host().IsIPv6()) {
-    QUIC_BUG(quic_bug_10575_10)
-        << "Cannot use SetIPv6AlternateServerAddressToSend with "
-        << alternate_server_address_ipv6;
-    return;
-  }
-  alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
-  preferred_address_connection_id_and_token_ =
-      std::make_pair(connection_id, stateless_reset_token);
-}
-
-bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
-  return alternate_server_address_ipv6_.HasReceivedValue();
-}
-
-const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
-    const {
-  return alternate_server_address_ipv6_.GetReceivedValue();
-}
-
-void QuicConfig::SetIPv4AlternateServerAddressToSend(
-    const QuicSocketAddress& alternate_server_address_ipv4) {
-  if (!alternate_server_address_ipv4.host().IsIPv4()) {
-    QUIC_BUG(quic_bug_10575_11)
-        << "Cannot use SetIPv4AlternateServerAddressToSend with "
-        << alternate_server_address_ipv4;
-    return;
-  }
-  alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
-}
-
-void QuicConfig::SetIPv4AlternateServerAddressToSend(
-    const QuicSocketAddress& alternate_server_address_ipv4,
-    const QuicConnectionId& connection_id,
-    const StatelessResetToken& stateless_reset_token) {
-  if (!alternate_server_address_ipv4.host().IsIPv4()) {
-    QUIC_BUG(quic_bug_10575_12)
-        << "Cannot use SetIPv4AlternateServerAddressToSend with "
-        << alternate_server_address_ipv4;
-    return;
-  }
-  alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
-  preferred_address_connection_id_and_token_ =
-      std::make_pair(connection_id, stateless_reset_token);
-}
-
-bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
-  return alternate_server_address_ipv4_.HasReceivedValue();
-}
-
-const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
-    const {
-  return alternate_server_address_ipv4_.GetReceivedValue();
-}
-
-bool QuicConfig::HasReceivedPreferredAddressConnectionIdAndToken() const {
-  return (HasReceivedIPv6AlternateServerAddress() ||
-          HasReceivedIPv4AlternateServerAddress()) &&
-         preferred_address_connection_id_and_token_.has_value();
-}
-
-const std::pair<QuicConnectionId, StatelessResetToken>&
-QuicConfig::ReceivedPreferredAddressConnectionIdAndToken() const {
-  QUICHE_DCHECK(HasReceivedPreferredAddressConnectionIdAndToken());
-  return *preferred_address_connection_id_and_token_;
-}
-
-void QuicConfig::SetOriginalConnectionIdToSend(
-    const QuicConnectionId& original_destination_connection_id) {
-  original_destination_connection_id_to_send_ =
-      original_destination_connection_id;
-}
-
-bool QuicConfig::HasReceivedOriginalConnectionId() const {
-  return received_original_destination_connection_id_.has_value();
-}
-
-QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
-  if (!HasReceivedOriginalConnectionId()) {
-    QUIC_BUG(quic_bug_10575_13) << "No received original connection ID";
-    return EmptyQuicConnectionId();
-  }
-  return received_original_destination_connection_id_.value();
-}
-
-void QuicConfig::SetInitialSourceConnectionIdToSend(
-    const QuicConnectionId& initial_source_connection_id) {
-  initial_source_connection_id_to_send_ = initial_source_connection_id;
-}
-
-bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
-  return received_initial_source_connection_id_.has_value();
-}
-
-QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
-  if (!HasReceivedInitialSourceConnectionId()) {
-    QUIC_BUG(quic_bug_10575_14) << "No received initial source connection ID";
-    return EmptyQuicConnectionId();
-  }
-  return received_initial_source_connection_id_.value();
-}
-
-void QuicConfig::SetRetrySourceConnectionIdToSend(
-    const QuicConnectionId& retry_source_connection_id) {
-  retry_source_connection_id_to_send_ = retry_source_connection_id;
-}
-
-bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
-  return received_retry_source_connection_id_.has_value();
-}
-
-QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
-  if (!HasReceivedRetrySourceConnectionId()) {
-    QUIC_BUG(quic_bug_10575_15) << "No received retry source connection ID";
-    return EmptyQuicConnectionId();
-  }
-  return received_retry_source_connection_id_.value();
-}
-
-void QuicConfig::SetStatelessResetTokenToSend(
-    const StatelessResetToken& stateless_reset_token) {
-  stateless_reset_token_.SetSendValue(stateless_reset_token);
-}
-
-bool QuicConfig::HasReceivedStatelessResetToken() const {
-  return stateless_reset_token_.HasReceivedValue();
-}
-
-const StatelessResetToken& QuicConfig::ReceivedStatelessResetToken() const {
-  return stateless_reset_token_.GetReceivedValue();
-}
-
-bool QuicConfig::negotiated() const {
-  return negotiated_;
-}
-
-void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
-  create_session_tag_indicators_ = std::move(tags);
-}
-
-const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
-  return create_session_tag_indicators_;
-}
-
-void QuicConfig::SetDefaults() {
-  SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
-  SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
-  SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
-  max_time_before_crypto_handshake_ =
-      QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
-  max_idle_time_before_crypto_handshake_ =
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
-  max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
-
-  SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
-  SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
-  SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
-  SetAckDelayExponentToSend(kDefaultAckDelayExponent);
-  SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
-  SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
-}
-
-void QuicConfig::ToHandshakeMessage(
-    CryptoHandshakeMessage* out,
-    QuicTransportVersion transport_version) const {
-  // Idle timeout has custom rules that are different from other values.
-  // We configure ourselves with the minumum value between the one sent and
-  // the one received. Additionally, when QUIC_CRYPTO is used, the server
-  // MUST send an idle timeout no greater than the idle timeout it received
-  // from the client. We therefore send the received value if it is lower.
-  QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
-  uint32_t max_idle_timeout_to_send_seconds =
-      max_idle_timeout_to_send_.ToSeconds();
-  if (received_max_idle_timeout_.has_value() &&
-      received_max_idle_timeout_->ToSeconds() <
-          max_idle_timeout_to_send_seconds) {
-    max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
-  }
-  max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
-  max_idle_timeout_seconds.ToHandshakeMessage(out);
-
-  // Do not need a version check here, max...bi... will encode
-  // as "MIDS" -- the max initial dynamic streams tag -- if
-  // doing some version other than IETF QUIC.
-  max_bidirectional_streams_.ToHandshakeMessage(out);
-  if (VersionHasIetfQuicFrames(transport_version)) {
-    max_unidirectional_streams_.ToHandshakeMessage(out);
-    ack_delay_exponent_.ToHandshakeMessage(out);
-  }
-  if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
-    // Only send max ack delay if it is using a non-default value, because
-    // the default value is used by QuicSentPacketManager if it is not
-    // sent during the handshake, and we want to save bytes.
-    max_ack_delay_ms_.ToHandshakeMessage(out);
-  }
-  bytes_for_connection_id_.ToHandshakeMessage(out);
-  initial_round_trip_time_us_.ToHandshakeMessage(out);
-  initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
-  initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
-  connection_migration_disabled_.ToHandshakeMessage(out);
-  connection_options_.ToHandshakeMessage(out);
-  if (alternate_server_address_ipv6_.HasSendValue()) {
-    alternate_server_address_ipv6_.ToHandshakeMessage(out);
-  } else {
-    alternate_server_address_ipv4_.ToHandshakeMessage(out);
-  }
-  stateless_reset_token_.ToHandshakeMessage(out);
-}
-
-QuicErrorCode QuicConfig::ProcessPeerHello(
-    const CryptoHandshakeMessage& peer_hello,
-    HelloType hello_type,
-    std::string* error_details) {
-  QUICHE_DCHECK(error_details != nullptr);
-
-  QuicErrorCode error = QUIC_NO_ERROR;
-  if (error == QUIC_NO_ERROR) {
-    // Idle timeout has custom rules that are different from other values.
-    // We configure ourselves with the minumum value between the one sent and
-    // the one received. Additionally, when QUIC_CRYPTO is used, the server
-    // MUST send an idle timeout no greater than the idle timeout it received
-    // from the client.
-    QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
-    error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
-                                                      error_details);
-    if (error == QUIC_NO_ERROR) {
-      if (max_idle_timeout_seconds.GetReceivedValue() >
-          max_idle_timeout_to_send_.ToSeconds()) {
-        // The received value is higher than ours, ignore it if from the client
-        // and raise an error if from the server.
-        if (hello_type == SERVER) {
-          error = QUIC_INVALID_NEGOTIATED_VALUE;
-          *error_details =
-              "Invalid value received for " + QuicTagToString(kICSL);
-        }
-      } else {
-        received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
-            max_idle_timeout_seconds.GetReceivedValue());
-      }
-    }
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
-                                                        error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
-                                                         error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
-                                                      error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
-                                                         error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
-        peer_hello, hello_type, error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
-        peer_hello, hello_type, error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = connection_migration_disabled_.ProcessPeerHello(
-        peer_hello, hello_type, error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
-                                                 error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
-    error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
-                                                      error_details);
-    if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
-      const QuicSocketAddress& received_address =
-          alternate_server_address.GetReceivedValue();
-      if (received_address.host().IsIPv6()) {
-        alternate_server_address_ipv6_.SetReceivedValue(received_address);
-      } else if (received_address.host().IsIPv4()) {
-        alternate_server_address_ipv4_.SetReceivedValue(received_address);
-      }
-    }
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
-                                                    error_details);
-  }
-
-  if (error == QUIC_NO_ERROR) {
-    error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
-                                               error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
-                                                 error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
-    negotiated_ = true;
-  }
-  return error;
-}
-
-bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
-  if (original_destination_connection_id_to_send_.has_value()) {
-    params->original_destination_connection_id =
-        original_destination_connection_id_to_send_.value();
-  }
-
-  params->max_idle_timeout_ms.set_value(
-      max_idle_timeout_to_send_.ToMilliseconds());
-
-  if (stateless_reset_token_.HasSendValue()) {
-    StatelessResetToken stateless_reset_token =
-        stateless_reset_token_.GetSendValue();
-    params->stateless_reset_token.assign(
-        reinterpret_cast<const char*>(&stateless_reset_token),
-        reinterpret_cast<const char*>(&stateless_reset_token) +
-            sizeof(stateless_reset_token));
-  }
-
-  params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
-  params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
-  params->initial_max_data.set_value(
-      GetInitialSessionFlowControlWindowToSend());
-  // The max stream data bidirectional transport parameters can be either local
-  // or remote. A stream is local iff it is initiated by the endpoint that sent
-  // the transport parameter (see the Transport Parameter Definitions section of
-  // draft-ietf-quic-transport). In this function we are sending transport
-  // parameters, so a local stream is one we initiated, which means an outgoing
-  // stream.
-  params->initial_max_stream_data_bidi_local.set_value(
-      GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
-  params->initial_max_stream_data_bidi_remote.set_value(
-      GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
-  params->initial_max_stream_data_uni.set_value(
-      GetInitialMaxStreamDataBytesUnidirectionalToSend());
-  params->initial_max_streams_bidi.set_value(
-      GetMaxBidirectionalStreamsToSend());
-  params->initial_max_streams_uni.set_value(
-      GetMaxUnidirectionalStreamsToSend());
-  params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
-  if (min_ack_delay_ms_.HasSendValue()) {
-    params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
-                                       kNumMicrosPerMilli);
-  }
-  params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
-  params->disable_active_migration =
-      connection_migration_disabled_.HasSendValue() &&
-      connection_migration_disabled_.GetSendValue() != 0;
-
-  if (alternate_server_address_ipv6_.HasSendValue() ||
-      alternate_server_address_ipv4_.HasSendValue()) {
-    TransportParameters::PreferredAddress preferred_address;
-    if (alternate_server_address_ipv6_.HasSendValue()) {
-      preferred_address.ipv6_socket_address =
-          alternate_server_address_ipv6_.GetSendValue();
-    }
-    if (alternate_server_address_ipv4_.HasSendValue()) {
-      preferred_address.ipv4_socket_address =
-          alternate_server_address_ipv4_.GetSendValue();
-    }
-    if (preferred_address_connection_id_and_token_) {
-      preferred_address.connection_id =
-          preferred_address_connection_id_and_token_->first;
-      auto* begin = reinterpret_cast<const char*>(
-          &preferred_address_connection_id_and_token_->second);
-      auto* end =
-          begin + sizeof(preferred_address_connection_id_and_token_->second);
-      preferred_address.stateless_reset_token.assign(begin, end);
-    }
-    params->preferred_address =
-        std::make_unique<TransportParameters::PreferredAddress>(
-            preferred_address);
-  }
-
-  if (active_connection_id_limit_.HasSendValue()) {
-    params->active_connection_id_limit.set_value(
-        active_connection_id_limit_.GetSendValue());
-  }
-
-  if (initial_source_connection_id_to_send_.has_value()) {
-    params->initial_source_connection_id =
-        initial_source_connection_id_to_send_.value();
-  }
-
-  if (retry_source_connection_id_to_send_.has_value()) {
-    params->retry_source_connection_id =
-        retry_source_connection_id_to_send_.value();
-  }
-
-  if (initial_round_trip_time_us_.HasSendValue()) {
-    params->initial_round_trip_time_us.set_value(
-        initial_round_trip_time_us_.GetSendValue());
-  }
-  if (connection_options_.HasSendValues() &&
-      !connection_options_.GetSendValues().empty()) {
-    params->google_connection_options = connection_options_.GetSendValues();
-  }
-
-  params->custom_parameters = custom_transport_parameters_to_send_;
-
-  return true;
-}
-
-QuicErrorCode QuicConfig::ProcessTransportParameters(
-    const TransportParameters& params,
-    bool is_resumption,
-    std::string* error_details) {
-  if (!is_resumption && params.original_destination_connection_id.has_value()) {
-    received_original_destination_connection_id_ =
-        params.original_destination_connection_id.value();
-  }
-
-  if (params.max_idle_timeout_ms.value() > 0 &&
-      params.max_idle_timeout_ms.value() <
-          static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
-    // An idle timeout of zero indicates it is disabled.
-    // We also ignore values higher than ours which will cause us to use the
-    // smallest value between ours and our peer's.
-    received_max_idle_timeout_ =
-        QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
-  }
-
-  if (!is_resumption && !params.stateless_reset_token.empty()) {
-    StatelessResetToken stateless_reset_token;
-    if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
-      QUIC_BUG(quic_bug_10575_16) << "Bad stateless reset token length "
-                                  << params.stateless_reset_token.size();
-      *error_details = "Bad stateless reset token length";
-      return QUIC_INTERNAL_ERROR;
-    }
-    memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
-           params.stateless_reset_token.size());
-    stateless_reset_token_.SetReceivedValue(stateless_reset_token);
-  }
-
-  if (params.max_udp_payload_size.IsValid()) {
-    max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
-  }
-
-  if (params.max_datagram_frame_size.IsValid()) {
-    max_datagram_frame_size_.SetReceivedValue(
-        params.max_datagram_frame_size.value());
-  }
-
-  initial_session_flow_control_window_bytes_.SetReceivedValue(
-      params.initial_max_data.value());
-
-  // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
-  // our implementation uses uint32_t to represent them to save memory.
-  max_bidirectional_streams_.SetReceivedValue(
-      std::min<uint64_t>(params.initial_max_streams_bidi.value(),
-                         std::numeric_limits<uint32_t>::max()));
-  max_unidirectional_streams_.SetReceivedValue(
-      std::min<uint64_t>(params.initial_max_streams_uni.value(),
-                         std::numeric_limits<uint32_t>::max()));
-
-  // The max stream data bidirectional transport parameters can be either local
-  // or remote. A stream is local iff it is initiated by the endpoint that sent
-  // the transport parameter (see the Transport Parameter Definitions section of
-  // draft-ietf-quic-transport). However in this function we are processing
-  // received transport parameters, so a local stream is one initiated by our
-  // peer, which means an incoming stream.
-  initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
-      params.initial_max_stream_data_bidi_local.value());
-  initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
-      params.initial_max_stream_data_bidi_remote.value());
-  initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
-      params.initial_max_stream_data_uni.value());
-
-  if (!is_resumption) {
-    max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
-    if (params.ack_delay_exponent.IsValid()) {
-      ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
-    }
-    if (params.preferred_address != nullptr) {
-      if (params.preferred_address->ipv6_socket_address.port() != 0) {
-        alternate_server_address_ipv6_.SetReceivedValue(
-            params.preferred_address->ipv6_socket_address);
-      }
-      if (params.preferred_address->ipv4_socket_address.port() != 0) {
-        alternate_server_address_ipv4_.SetReceivedValue(
-            params.preferred_address->ipv4_socket_address);
-      }
-      // TODO(haoyuewang) Treat 0 length connection ID sent in preferred_address
-      // as a connection error of type TRANSPORT_PARAMETER_ERROR when server
-      // fully supports it.
-      if (!params.preferred_address->connection_id.IsEmpty()) {
-        preferred_address_connection_id_and_token_ = std::make_pair(
-            params.preferred_address->connection_id,
-            *reinterpret_cast<const StatelessResetToken*>(
-                &params.preferred_address->stateless_reset_token.front()));
-      }
-    }
-    if (params.min_ack_delay_us.value() != 0) {
-      if (params.min_ack_delay_us.value() >
-          params.max_ack_delay.value() * kNumMicrosPerMilli) {
-        *error_details = "MinAckDelay is greater than MaxAckDelay.";
-        return IETF_QUIC_PROTOCOL_VIOLATION;
-      }
-      min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
-                                         kNumMicrosPerMilli);
-    }
-  }
-
-  if (params.disable_active_migration) {
-    connection_migration_disabled_.SetReceivedValue(1u);
-  }
-
-  active_connection_id_limit_.SetReceivedValue(
-      params.active_connection_id_limit.value());
-
-  if (!is_resumption) {
-    if (params.initial_source_connection_id.has_value()) {
-      received_initial_source_connection_id_ =
-          params.initial_source_connection_id.value();
-    }
-    if (params.retry_source_connection_id.has_value()) {
-      received_retry_source_connection_id_ =
-          params.retry_source_connection_id.value();
-    }
-  }
-
-  if (params.initial_round_trip_time_us.value() > 0) {
-    initial_round_trip_time_us_.SetReceivedValue(
-        params.initial_round_trip_time_us.value());
-  }
-  if (params.google_connection_options.has_value()) {
-    connection_options_.SetReceivedValues(
-        params.google_connection_options.value());
-  }
-
-  received_custom_transport_parameters_ = params.custom_parameters;
-
-  if (!is_resumption) {
-    negotiated_ = true;
-  }
-  *error_details = "";
-  return QUIC_NO_ERROR;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_config.h b/quic/core/quic_config.h
deleted file mode 100644
index cb8b4ec..0000000
--- a/quic/core/quic_config.h
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONFIG_H_
-#define QUICHE_QUIC_CORE_QUIC_CONFIG_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/types/optional.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicConfigPeer;
-}  // namespace test
-
-class CryptoHandshakeMessage;
-
-// Describes whether or not a given QuicTag is required or optional in the
-// handshake message.
-enum QuicConfigPresence : uint8_t {
-  // This negotiable value can be absent from the handshake message. Default
-  // value is selected as the negotiated value in such a case.
-  PRESENCE_OPTIONAL,
-  // This negotiable value is required in the handshake message otherwise the
-  // Process*Hello function returns an error.
-  PRESENCE_REQUIRED,
-};
-
-// Whether the CryptoHandshakeMessage is from the client or server.
-enum HelloType {
-  CLIENT,
-  SERVER,
-};
-
-// An abstract base class that stores a value that can be sent in CHLO/SHLO
-// message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
-class QUIC_EXPORT_PRIVATE QuicConfigValue {
- public:
-  QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
-  virtual ~QuicConfigValue();
-
-  // Serialises tag name and value(s) to |out|.
-  virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0;
-
-  // Selects a mutually acceptable value from those offered in |peer_hello|
-  // and those defined in the subclass.
-  virtual QuicErrorCode ProcessPeerHello(
-      const CryptoHandshakeMessage& peer_hello,
-      HelloType hello_type,
-      std::string* error_details) = 0;
-
- protected:
-  const QuicTag tag_;
-  const QuicConfigPresence presence_;
-};
-
-// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
- public:
-  QuicFixedUint32(QuicTag tag, QuicConfigPresence presence);
-  ~QuicFixedUint32() override;
-
-  bool HasSendValue() const;
-
-  uint32_t GetSendValue() const;
-
-  void SetSendValue(uint32_t value);
-
-  bool HasReceivedValue() const;
-
-  uint32_t GetReceivedValue() const;
-
-  void SetReceivedValue(uint32_t value);
-
-  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
-  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
-  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
-  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
-                                 HelloType hello_type,
-                                 std::string* error_details) override;
-
- private:
-  bool has_send_value_;
-  bool has_receive_value_;
-  uint32_t send_value_;
-  uint32_t receive_value_;
-};
-
-// Stores 62bit numbers from handshake messages that unilaterally shared by each
-// endpoint. IMPORTANT: these are serialized as 32-bit unsigned integers when
-// using QUIC_CRYPTO versions and CryptoHandshakeMessage.
-class QUIC_EXPORT_PRIVATE QuicFixedUint62 : public QuicConfigValue {
- public:
-  QuicFixedUint62(QuicTag name, QuicConfigPresence presence);
-  ~QuicFixedUint62() override;
-
-  bool HasSendValue() const;
-
-  uint64_t GetSendValue() const;
-
-  void SetSendValue(uint64_t value);
-
-  bool HasReceivedValue() const;
-
-  uint64_t GetReceivedValue() const;
-
-  void SetReceivedValue(uint64_t value);
-
-  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
-  // IMPORTANT: this method serializes |send_value_| as an unsigned 32bit
-  // integer.
-  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
-  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
-  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
-                                 HelloType hello_type,
-                                 std::string* error_details) override;
-
- private:
-  bool has_send_value_;
-  bool has_receive_value_;
-  uint64_t send_value_;
-  uint64_t receive_value_;
-};
-
-// Stores StatelessResetToken from CHLO or SHLO messages that are not
-// negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedStatelessResetToken
-    : public QuicConfigValue {
- public:
-  QuicFixedStatelessResetToken(QuicTag tag, QuicConfigPresence presence);
-  ~QuicFixedStatelessResetToken() override;
-
-  bool HasSendValue() const;
-
-  const StatelessResetToken& GetSendValue() const;
-
-  void SetSendValue(const StatelessResetToken& value);
-
-  bool HasReceivedValue() const;
-
-  const StatelessResetToken& GetReceivedValue() const;
-
-  void SetReceivedValue(const StatelessResetToken& value);
-
-  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
-  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
-  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
-  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
-                                 HelloType hello_type,
-                                 std::string* error_details) override;
-
- private:
-  bool has_send_value_;
-  bool has_receive_value_;
-  StatelessResetToken send_value_;
-  StatelessResetToken receive_value_;
-};
-
-// Stores tag from CHLO or SHLO messages that are not negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
- public:
-  QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
-  QuicFixedTagVector(const QuicFixedTagVector& other);
-  ~QuicFixedTagVector() override;
-
-  bool HasSendValues() const;
-
-  const QuicTagVector& GetSendValues() const;
-
-  void SetSendValues(const QuicTagVector& values);
-
-  bool HasReceivedValues() const;
-
-  const QuicTagVector& GetReceivedValues() const;
-
-  void SetReceivedValues(const QuicTagVector& values);
-
-  // If has_send_value is true, serialises |tag_vector_| and |send_value_| to
-  // |out|.
-  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
-  // Sets |receive_values_| to the corresponding value from |client_hello_| if
-  // it exists.
-  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
-                                 HelloType hello_type,
-                                 std::string* error_details) override;
-
- private:
-  bool has_send_values_;
-  bool has_receive_values_;
-  QuicTagVector send_values_;
-  QuicTagVector receive_values_;
-};
-
-// Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
-class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
- public:
-  QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
-  ~QuicFixedSocketAddress() override;
-
-  bool HasSendValue() const;
-
-  const QuicSocketAddress& GetSendValue() const;
-
-  void SetSendValue(const QuicSocketAddress& value);
-
-  bool HasReceivedValue() const;
-
-  const QuicSocketAddress& GetReceivedValue() const;
-
-  void SetReceivedValue(const QuicSocketAddress& value);
-
-  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
-
-  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
-                                 HelloType hello_type,
-                                 std::string* error_details) override;
-
- private:
-  bool has_send_value_;
-  bool has_receive_value_;
-  QuicSocketAddress send_value_;
-  QuicSocketAddress receive_value_;
-};
-
-// QuicConfig contains non-crypto configuration options that are negotiated in
-// the crypto handshake.
-class QUIC_EXPORT_PRIVATE QuicConfig {
- public:
-  QuicConfig();
-  QuicConfig(const QuicConfig& other);
-  ~QuicConfig();
-
-  void SetConnectionOptionsToSend(const QuicTagVector& connection_options);
-
-  bool HasReceivedConnectionOptions() const;
-
-  // Sets initial received connection options.  All received connection options
-  // will be initialized with these fields. Initial received options may only be
-  // set once per config, prior to the setting of any other options.  If options
-  // have already been set (either by previous calls or via handshake), this
-  // function does nothing and returns false.
-  bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags);
-
-  const QuicTagVector& ReceivedConnectionOptions() const;
-
-  bool HasSendConnectionOptions() const;
-
-  const QuicTagVector& SendConnectionOptions() const;
-
-  // Returns true if the client is sending or the server has received a
-  // connection option.
-  // TODO(ianswett): Rename to HasClientRequestedSharedOption
-  bool HasClientSentConnectionOption(QuicTag tag,
-                                     Perspective perspective) const;
-
-  void SetClientConnectionOptions(
-      const QuicTagVector& client_connection_options);
-
-  // Returns true if the client has requested the specified connection option.
-  // Checks the client connection options if the |perspective| is client and
-  // connection options if the |perspective| is the server.
-  bool HasClientRequestedIndependentOption(QuicTag tag,
-                                           Perspective perspective) const;
-
-  const QuicTagVector& ClientRequestedIndependentOptions(
-      Perspective perspective) const;
-
-  void SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout);
-
-  QuicTime::Delta IdleNetworkTimeout() const;
-
-  // Sets the max bidirectional stream count that this endpoint supports.
-  void SetMaxBidirectionalStreamsToSend(uint32_t max_streams);
-  uint32_t GetMaxBidirectionalStreamsToSend() const;
-
-  bool HasReceivedMaxBidirectionalStreams() const;
-  // Gets the max bidirectional stream limit imposed by the peer.
-  uint32_t ReceivedMaxBidirectionalStreams() const;
-
-  // Sets the max unidirectional stream count that this endpoint supports.
-  void SetMaxUnidirectionalStreamsToSend(uint32_t max_streams);
-  uint32_t GetMaxUnidirectionalStreamsToSend() const;
-
-  bool HasReceivedMaxUnidirectionalStreams() const;
-  // Gets the max unidirectional stream limit imposed by the peer.
-  uint32_t ReceivedMaxUnidirectionalStreams() const;
-
-  void set_max_time_before_crypto_handshake(
-      QuicTime::Delta max_time_before_crypto_handshake) {
-    max_time_before_crypto_handshake_ = max_time_before_crypto_handshake;
-  }
-
-  QuicTime::Delta max_time_before_crypto_handshake() const {
-    return max_time_before_crypto_handshake_;
-  }
-
-  void set_max_idle_time_before_crypto_handshake(
-      QuicTime::Delta max_idle_time_before_crypto_handshake) {
-    max_idle_time_before_crypto_handshake_ =
-        max_idle_time_before_crypto_handshake;
-  }
-
-  QuicTime::Delta max_idle_time_before_crypto_handshake() const {
-    return max_idle_time_before_crypto_handshake_;
-  }
-
-  void set_max_undecryptable_packets(size_t max_undecryptable_packets) {
-    max_undecryptable_packets_ = max_undecryptable_packets;
-  }
-
-  size_t max_undecryptable_packets() const {
-    return max_undecryptable_packets_;
-  }
-
-  // Peer's connection id length, in bytes. Only used in Q043 and Q046.
-  bool HasSetBytesForConnectionIdToSend() const;
-  void SetBytesForConnectionIdToSend(uint32_t bytes);
-  bool HasReceivedBytesForConnectionId() const;
-  uint32_t ReceivedBytesForConnectionId() const;
-
-  // Estimated initial round trip time in us.
-  void SetInitialRoundTripTimeUsToSend(uint64_t rtt_us);
-  bool HasReceivedInitialRoundTripTimeUs() const;
-  uint64_t ReceivedInitialRoundTripTimeUs() const;
-  bool HasInitialRoundTripTimeUsToSend() const;
-  uint64_t GetInitialRoundTripTimeUsToSend() const;
-
-  // Sets an initial stream flow control window size to transmit to the peer.
-  void SetInitialStreamFlowControlWindowToSend(uint64_t window_bytes);
-  uint64_t GetInitialStreamFlowControlWindowToSend() const;
-  bool HasReceivedInitialStreamFlowControlWindowBytes() const;
-  uint64_t ReceivedInitialStreamFlowControlWindowBytes() const;
-
-  // Specifies the initial flow control window (max stream data) for
-  // incoming bidirectional streams. Incoming means streams initiated by our
-  // peer. If not set, GetInitialMaxStreamDataBytesIncomingBidirectionalToSend
-  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
-  void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-      uint64_t window_bytes);
-  uint64_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const;
-  bool HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
-  uint64_t ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
-
-  // Specifies the initial flow control window (max stream data) for
-  // outgoing bidirectional streams. Outgoing means streams initiated by us.
-  // If not set, GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend
-  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
-  void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-      uint64_t window_bytes);
-  uint64_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const;
-  bool HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
-  uint64_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
-
-  // Specifies the initial flow control window (max stream data) for
-  // unidirectional streams. If not set,
-  // GetInitialMaxStreamDataBytesUnidirectionalToSend returns the value passed
-  // to SetInitialStreamFlowControlWindowToSend.
-  void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint64_t window_bytes);
-  uint64_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const;
-  bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const;
-  uint64_t ReceivedInitialMaxStreamDataBytesUnidirectional() const;
-
-  // Sets an initial session flow control window size to transmit to the peer.
-  void SetInitialSessionFlowControlWindowToSend(uint64_t window_bytes);
-  uint64_t GetInitialSessionFlowControlWindowToSend() const;
-  bool HasReceivedInitialSessionFlowControlWindowBytes() const;
-  uint64_t ReceivedInitialSessionFlowControlWindowBytes() const;
-
-  // Disable connection migration.
-  void SetDisableConnectionMigration();
-  bool DisableConnectionMigration() const;
-
-  // IPv6 alternate server address.
-  void SetIPv6AlternateServerAddressToSend(
-      const QuicSocketAddress& alternate_server_address_ipv6);
-  void SetIPv6AlternateServerAddressToSend(
-      const QuicSocketAddress& alternate_server_address_ipv6,
-      const QuicConnectionId& connection_id,
-      const StatelessResetToken& stateless_reset_token);
-  bool HasReceivedIPv6AlternateServerAddress() const;
-  const QuicSocketAddress& ReceivedIPv6AlternateServerAddress() const;
-
-  // IPv4 alternate server address.
-  void SetIPv4AlternateServerAddressToSend(
-      const QuicSocketAddress& alternate_server_address_ipv4);
-  void SetIPv4AlternateServerAddressToSend(
-      const QuicSocketAddress& alternate_server_address_ipv4,
-      const QuicConnectionId& connection_id,
-      const StatelessResetToken& stateless_reset_token);
-  bool HasReceivedIPv4AlternateServerAddress() const;
-  const QuicSocketAddress& ReceivedIPv4AlternateServerAddress() const;
-
-  // Preferred Address Connection ID and Token.
-  bool HasReceivedPreferredAddressConnectionIdAndToken() const;
-  const std::pair<QuicConnectionId, StatelessResetToken>&
-  ReceivedPreferredAddressConnectionIdAndToken() const;
-
-  // Original destination connection ID.
-  void SetOriginalConnectionIdToSend(
-      const QuicConnectionId& original_destination_connection_id);
-  bool HasReceivedOriginalConnectionId() const;
-  QuicConnectionId ReceivedOriginalConnectionId() const;
-
-  // Stateless reset token.
-  void SetStatelessResetTokenToSend(
-      const StatelessResetToken& stateless_reset_token);
-  bool HasReceivedStatelessResetToken() const;
-  const StatelessResetToken& ReceivedStatelessResetToken() const;
-
-  // Manage the IETF QUIC Max ACK Delay transport parameter.
-  // The sent value is the delay that this node uses
-  // (QuicSentPacketManager::local_max_ack_delay_).
-  // The received delay is the value received from
-  // the peer (QuicSentPacketManager::peer_max_ack_delay_).
-  void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
-  uint32_t GetMaxAckDelayToSendMs() const;
-  bool HasReceivedMaxAckDelayMs() const;
-  uint32_t ReceivedMaxAckDelayMs() const;
-
-  // Manage the IETF QUIC extension Min Ack Delay transport parameter.
-  // An endpoint uses min_ack_delay to advsertise its support for
-  // AckFrequencyFrame sent by peer.
-  void SetMinAckDelayMs(uint32_t min_ack_delay_ms);
-  uint32_t GetMinAckDelayToSendMs() const;
-  bool HasReceivedMinAckDelayMs() const;
-  uint32_t ReceivedMinAckDelayMs() const;
-
-  void SetAckDelayExponentToSend(uint32_t exponent);
-  uint32_t GetAckDelayExponentToSend() const;
-  bool HasReceivedAckDelayExponent() const;
-  uint32_t ReceivedAckDelayExponent() const;
-
-  // IETF QUIC max_udp_payload_size transport parameter.
-  void SetMaxPacketSizeToSend(uint64_t max_udp_payload_size);
-  uint64_t GetMaxPacketSizeToSend() const;
-  bool HasReceivedMaxPacketSize() const;
-  uint64_t ReceivedMaxPacketSize() const;
-
-  // IETF QUIC max_datagram_frame_size transport parameter.
-  void SetMaxDatagramFrameSizeToSend(uint64_t max_datagram_frame_size);
-  uint64_t GetMaxDatagramFrameSizeToSend() const;
-  bool HasReceivedMaxDatagramFrameSize() const;
-  uint64_t ReceivedMaxDatagramFrameSize() const;
-
-  // IETF QUIC active_connection_id_limit transport parameter.
-  void SetActiveConnectionIdLimitToSend(uint64_t active_connection_id_limit);
-  uint64_t GetActiveConnectionIdLimitToSend() const;
-  bool HasReceivedActiveConnectionIdLimit() const;
-  uint64_t ReceivedActiveConnectionIdLimit() const;
-
-  // Initial source connection ID.
-  void SetInitialSourceConnectionIdToSend(
-      const QuicConnectionId& initial_source_connection_id);
-  bool HasReceivedInitialSourceConnectionId() const;
-  QuicConnectionId ReceivedInitialSourceConnectionId() const;
-
-  // Retry source connection ID.
-  void SetRetrySourceConnectionIdToSend(
-      const QuicConnectionId& retry_source_connection_id);
-  bool HasReceivedRetrySourceConnectionId() const;
-  QuicConnectionId ReceivedRetrySourceConnectionId() const;
-
-  bool negotiated() const;
-
-  void SetCreateSessionTagIndicators(QuicTagVector tags);
-
-  const QuicTagVector& create_session_tag_indicators() const;
-
-  // ToHandshakeMessage serialises the settings in this object as a series of
-  // tags /value pairs and adds them to |out|.
-  void ToHandshakeMessage(CryptoHandshakeMessage* out,
-                          QuicTransportVersion transport_version) const;
-
-  // Calls ProcessPeerHello on each negotiable parameter. On failure returns
-  // the corresponding QuicErrorCode and sets detailed error in |error_details|.
-  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
-                                 HelloType hello_type,
-                                 std::string* error_details);
-
-  // FillTransportParameters writes the values to send for ICSL, MIDS, CFCW, and
-  // SFCW to |*params|, returning true if the values could be written and false
-  // if something prevents them from being written (e.g. a value is too large).
-  bool FillTransportParameters(TransportParameters* params) const;
-
-  // ProcessTransportParameters reads from |params| which were received from a
-  // peer. If |is_resumption|, some configs will not be processed.
-  // On failure, it returns a QuicErrorCode and puts a detailed error in
-  // |*error_details|.
-  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
-                                           bool is_resumption,
-                                           std::string* error_details);
-
-  TransportParameters::ParameterMap& custom_transport_parameters_to_send() {
-    return custom_transport_parameters_to_send_;
-  }
-  const TransportParameters::ParameterMap&
-  received_custom_transport_parameters() const {
-    return received_custom_transport_parameters_;
-  }
-
- private:
-  friend class test::QuicConfigPeer;
-
-  // SetDefaults sets the members to sensible, default values.
-  void SetDefaults();
-
-  // Whether we've received the peer's config.
-  bool negotiated_;
-
-  // Configurations options that are not negotiated.
-  // Maximum time the session can be alive before crypto handshake is finished.
-  QuicTime::Delta max_time_before_crypto_handshake_;
-  // Maximum idle time before the crypto handshake has completed.
-  QuicTime::Delta max_idle_time_before_crypto_handshake_;
-  // Maximum number of undecryptable packets stored before CHLO/SHLO.
-  size_t max_undecryptable_packets_;
-
-  // Connection options which affect the server side.  May also affect the
-  // client side in cases when identical behavior is desirable.
-  QuicFixedTagVector connection_options_;
-  // Connection options which only affect the client side.
-  QuicFixedTagVector client_connection_options_;
-  // Maximum idle network timeout.
-  // Uses the max_idle_timeout transport parameter in IETF QUIC.
-  // Note that received_max_idle_timeout_ is only populated if we receive the
-  // peer's value, which isn't guaranteed in IETF QUIC as sending is optional.
-  QuicTime::Delta max_idle_timeout_to_send_;
-  absl::optional<QuicTime::Delta> received_max_idle_timeout_;
-  // Maximum number of dynamic streams that a Google QUIC connection
-  // can support or the maximum number of bidirectional streams that
-  // an IETF QUIC connection can support.
-  // The SendValue is the limit on peer-created streams that this endpoint is
-  // advertising.
-  // The ReceivedValue is the limit on locally-created streams that
-  // the peer advertised.
-  // Uses the initial_max_streams_bidi transport parameter in IETF QUIC.
-  QuicFixedUint32 max_bidirectional_streams_;
-  // Maximum number of unidirectional streams that the connection can
-  // support.
-  // The SendValue is the limit on peer-created streams that this endpoint is
-  // advertising.
-  // The ReceivedValue is the limit on locally-created streams that the peer
-  // advertised.
-  // Uses the initial_max_streams_uni transport parameter in IETF QUIC.
-  QuicFixedUint32 max_unidirectional_streams_;
-  // The number of bytes required for the connection ID. This is only used in
-  // the legacy header format used only by Q043 at this point.
-  QuicFixedUint32 bytes_for_connection_id_;
-  // Initial round trip time estimate in microseconds.
-  QuicFixedUint62 initial_round_trip_time_us_;
-
-  // Initial IETF QUIC stream flow control receive windows in bytes.
-  // Incoming bidirectional streams.
-  // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
-  // in IETF QUIC, depending on whether we're sending or receiving.
-  QuicFixedUint62 initial_max_stream_data_bytes_incoming_bidirectional_;
-  // Outgoing bidirectional streams.
-  // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
-  // in IETF QUIC, depending on whether we're sending or receiving.
-  QuicFixedUint62 initial_max_stream_data_bytes_outgoing_bidirectional_;
-  // Unidirectional streams.
-  // Uses the initial_max_stream_data_uni transport parameter in IETF QUIC.
-  QuicFixedUint62 initial_max_stream_data_bytes_unidirectional_;
-
-  // Initial Google QUIC stream flow control receive window in bytes.
-  QuicFixedUint62 initial_stream_flow_control_window_bytes_;
-
-  // Initial session flow control receive window in bytes.
-  // Uses the initial_max_data transport parameter in IETF QUIC.
-  QuicFixedUint62 initial_session_flow_control_window_bytes_;
-
-  // Whether active connection migration is allowed.
-  // Uses the disable_active_migration transport parameter in IETF QUIC.
-  QuicFixedUint32 connection_migration_disabled_;
-
-  // Alternate server addresses the client could connect to.
-  // Uses the preferred_address transport parameter in IETF QUIC.
-  // Note that when QUIC_CRYPTO is in use, only one of the addresses is sent.
-  QuicFixedSocketAddress alternate_server_address_ipv6_;
-  QuicFixedSocketAddress alternate_server_address_ipv4_;
-  // Connection Id data to send from the server or receive at the client as part
-  // of the preferred address transport parameter.
-  absl::optional<std::pair<QuicConnectionId, StatelessResetToken>>
-      preferred_address_connection_id_and_token_;
-
-  // Stateless reset token used in IETF public reset packet.
-  // Uses the stateless_reset_token transport parameter in IETF QUIC.
-  QuicFixedStatelessResetToken stateless_reset_token_;
-
-  // List of QuicTags whose presence immediately causes the session to
-  // be created. This allows for CHLOs that are larger than a single
-  // packet to be processed.
-  QuicTagVector create_session_tag_indicators_;
-
-  // Maximum ack delay. The sent value is the value used on this node.
-  // The received value is the value received from the peer and used by
-  // the peer.
-  // Uses the max_ack_delay transport parameter in IETF QUIC.
-  QuicFixedUint32 max_ack_delay_ms_;
-
-  // Minimum ack delay. Used to enable sender control of max_ack_delay.
-  // Uses the min_ack_delay transport parameter in IETF QUIC extension.
-  QuicFixedUint32 min_ack_delay_ms_;
-
-  // The sent exponent is the exponent that this node uses when serializing an
-  // ACK frame (and the peer should use when deserializing the frame);
-  // the received exponent is the value the peer uses to serialize frames and
-  // this node uses to deserialize them.
-  // Uses the ack_delay_exponent transport parameter in IETF QUIC.
-  QuicFixedUint32 ack_delay_exponent_;
-
-  // Maximum packet size in bytes.
-  // Uses the max_udp_payload_size transport parameter in IETF QUIC.
-  QuicFixedUint62 max_udp_payload_size_;
-
-  // Maximum DATAGRAM/MESSAGE frame size in bytes.
-  // Uses the max_datagram_frame_size transport parameter in IETF QUIC.
-  QuicFixedUint62 max_datagram_frame_size_;
-
-  // Maximum number of connection IDs from the peer.
-  // Uses the active_connection_id_limit transport parameter in IETF QUIC.
-  QuicFixedUint62 active_connection_id_limit_;
-
-  // The value of the Destination Connection ID field from the first
-  // Initial packet sent by the client.
-  // Uses the original_destination_connection_id transport parameter in
-  // IETF QUIC.
-  absl::optional<QuicConnectionId> original_destination_connection_id_to_send_;
-  absl::optional<QuicConnectionId> received_original_destination_connection_id_;
-
-  // The value that the endpoint included in the Source Connection ID field of
-  // the first Initial packet it sent.
-  // Uses the initial_source_connection_id transport parameter in IETF QUIC.
-  absl::optional<QuicConnectionId> initial_source_connection_id_to_send_;
-  absl::optional<QuicConnectionId> received_initial_source_connection_id_;
-
-  // The value that the server included in the Source Connection ID field of a
-  // Retry packet it sent.
-  // Uses the retry_source_connection_id transport parameter in IETF QUIC.
-  absl::optional<QuicConnectionId> retry_source_connection_id_to_send_;
-  absl::optional<QuicConnectionId> received_retry_source_connection_id_;
-
-  // Custom transport parameters that can be sent and received in the TLS
-  // handshake.
-  TransportParameters::ParameterMap custom_transport_parameters_to_send_;
-  TransportParameters::ParameterMap received_custom_transport_parameters_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONFIG_H_
diff --git a/quic/core/quic_config_test.cc b/quic/core/quic_config_test.cc
deleted file mode 100644
index e53d429..0000000
--- a/quic/core/quic_config_test.cc
+++ /dev/null
@@ -1,727 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_config.h"
-
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicConfigTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  QuicConfigTest() : version_(GetParam()) {}
-
- protected:
-  ParsedQuicVersion version_;
-  QuicConfig config_;
-};
-
-// Run all tests with all versions of QUIC.
-INSTANTIATE_TEST_SUITE_P(QuicConfigTests,
-                         QuicConfigTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicConfigTest, SetDefaults) {
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialStreamFlowControlWindowToSend());
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
-  EXPECT_FALSE(config_.HasReceivedInitialStreamFlowControlWindowBytes());
-  EXPECT_FALSE(
-      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-  EXPECT_FALSE(
-      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-  EXPECT_EQ(kMaxIncomingPacketSize, config_.GetMaxPacketSizeToSend());
-  EXPECT_FALSE(config_.HasReceivedMaxPacketSize());
-}
-
-TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialStreamFlowControlWindowToSend());
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
-  static const uint32_t kTestWindowSize = 1234567;
-  config_.SetInitialStreamFlowControlWindowToSend(kTestWindowSize);
-  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
-  EXPECT_EQ(kTestWindowSize,
-            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
-  EXPECT_EQ(kTestWindowSize,
-            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
-  EXPECT_EQ(kTestWindowSize,
-            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
-  static const uint32_t kTestWindowSizeTwo = 2345678;
-  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-      kTestWindowSizeTwo);
-  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
-  EXPECT_EQ(kTestWindowSizeTwo,
-            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
-  EXPECT_EQ(kTestWindowSize,
-            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
-  EXPECT_EQ(kTestWindowSize,
-            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
-}
-
-TEST_P(QuicConfigTest, ToHandshakeMessage) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  config_.SetInitialStreamFlowControlWindowToSend(
-      kInitialStreamFlowControlWindowForTest);
-  config_.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest);
-  config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5));
-  CryptoHandshakeMessage msg;
-  config_.ToHandshakeMessage(&msg, version_.transport_version);
-
-  uint32_t value;
-  QuicErrorCode error = msg.GetUint32(kICSL, &value);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_EQ(5u, value);
-
-  error = msg.GetUint32(kSFCW, &value);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
-
-  error = msg.GetUint32(kCFCW, &value);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
-}
-
-TEST_P(QuicConfigTest, ProcessClientHello) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  const uint32_t kTestMaxAckDelayMs =
-      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
-  QuicConfig client_config;
-  QuicTagVector cgst;
-  cgst.push_back(kQBIC);
-  client_config.SetIdleNetworkTimeout(
-      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
-  client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
-  client_config.SetInitialStreamFlowControlWindowToSend(
-      2 * kInitialStreamFlowControlWindowForTest);
-  client_config.SetInitialSessionFlowControlWindowToSend(
-      2 * kInitialSessionFlowControlWindowForTest);
-  QuicTagVector copt;
-  copt.push_back(kTBBR);
-  client_config.SetConnectionOptionsToSend(copt);
-  client_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
-  CryptoHandshakeMessage msg;
-  client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
-  std::string error_details;
-  QuicTagVector initial_received_options;
-  initial_received_options.push_back(kIW50);
-  EXPECT_TRUE(
-      config_.SetInitialReceivedConnectionOptions(initial_received_options));
-  EXPECT_FALSE(
-      config_.SetInitialReceivedConnectionOptions(initial_received_options))
-      << "You can only set initial options once.";
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_FALSE(
-      config_.SetInitialReceivedConnectionOptions(initial_received_options))
-      << "You cannot set initial options after the hello.";
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
-            config_.IdleNetworkTimeout());
-  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
-  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
-  EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
-  EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
-  EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
-  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
-            2 * kInitialStreamFlowControlWindowForTest);
-  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
-            2 * kInitialSessionFlowControlWindowForTest);
-  EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
-  EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
-
-  // IETF QUIC stream limits should not be received in QUIC crypto messages.
-  EXPECT_FALSE(
-      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-  EXPECT_FALSE(
-      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-}
-
-TEST_P(QuicConfigTest, ProcessServerHello) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  QuicIpAddress host;
-  host.FromString("127.0.3.1");
-  const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
-  const StatelessResetToken kTestStatelessResetToken{
-      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
-  const uint32_t kTestMaxAckDelayMs =
-      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
-  QuicConfig server_config;
-  QuicTagVector cgst;
-  cgst.push_back(kQBIC);
-  server_config.SetIdleNetworkTimeout(
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
-  server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
-  server_config.SetInitialStreamFlowControlWindowToSend(
-      2 * kInitialStreamFlowControlWindowForTest);
-  server_config.SetInitialSessionFlowControlWindowToSend(
-      2 * kInitialSessionFlowControlWindowForTest);
-  server_config.SetIPv4AlternateServerAddressToSend(kTestServerAddress);
-  server_config.SetStatelessResetTokenToSend(kTestStatelessResetToken);
-  server_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
-  CryptoHandshakeMessage msg;
-  server_config.ToHandshakeMessage(&msg, version_.transport_version);
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, SERVER, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
-            config_.IdleNetworkTimeout());
-  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
-  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
-            2 * kInitialStreamFlowControlWindowForTest);
-  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
-            2 * kInitialSessionFlowControlWindowForTest);
-  EXPECT_TRUE(config_.HasReceivedIPv4AlternateServerAddress());
-  EXPECT_EQ(kTestServerAddress, config_.ReceivedIPv4AlternateServerAddress());
-  EXPECT_FALSE(config_.HasReceivedIPv6AlternateServerAddress());
-  EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
-  EXPECT_EQ(kTestStatelessResetToken, config_.ReceivedStatelessResetToken());
-  EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
-  EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
-
-  // IETF QUIC stream limits should not be received in QUIC crypto messages.
-  EXPECT_FALSE(
-      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-  EXPECT_FALSE(
-      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-}
-
-TEST_P(QuicConfigTest, MissingOptionalValuesInCHLO) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  CryptoHandshakeMessage msg;
-  msg.SetValue(kICSL, 1);
-
-  // Set all REQUIRED tags.
-  msg.SetValue(kICSL, 1);
-  msg.SetValue(kMIBS, 1);
-
-  // No error, as rest are optional.
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-}
-
-TEST_P(QuicConfigTest, MissingOptionalValuesInSHLO) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  CryptoHandshakeMessage msg;
-
-  // Set all REQUIRED tags.
-  msg.SetValue(kICSL, 1);
-  msg.SetValue(kMIBS, 1);
-
-  // No error, as rest are optional.
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, SERVER, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-}
-
-TEST_P(QuicConfigTest, MissingValueInCHLO) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  // Server receives CHLO with missing kICSL.
-  CryptoHandshakeMessage msg;
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
-}
-
-TEST_P(QuicConfigTest, MissingValueInSHLO) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  // Client receives SHLO with missing kICSL.
-  CryptoHandshakeMessage msg;
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, SERVER, &error_details);
-  EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
-}
-
-TEST_P(QuicConfigTest, OutOfBoundSHLO) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  QuicConfig server_config;
-  server_config.SetIdleNetworkTimeout(
-      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
-
-  CryptoHandshakeMessage msg;
-  server_config.ToHandshakeMessage(&msg, version_.transport_version);
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, SERVER, &error_details);
-  EXPECT_THAT(error, IsError(QUIC_INVALID_NEGOTIATED_VALUE));
-}
-
-TEST_P(QuicConfigTest, InvalidFlowControlWindow) {
-  // QuicConfig should not accept an invalid flow control window to send to the
-  // peer: the receive window must be at least the default of 16 Kb.
-  QuicConfig config;
-  const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
-  EXPECT_QUIC_BUG(
-      config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
-      "Initial stream flow control receive window");
-
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            config.GetInitialStreamFlowControlWindowToSend());
-}
-
-TEST_P(QuicConfigTest, HasClientSentConnectionOption) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector copt;
-  copt.push_back(kTBBR);
-  client_config.SetConnectionOptionsToSend(copt);
-  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
-      kTBBR, Perspective::IS_CLIENT));
-
-  CryptoHandshakeMessage msg;
-  client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-
-  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
-  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
-  EXPECT_TRUE(
-      config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
-}
-
-TEST_P(QuicConfigTest, DontSendClientConnectionOptions) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector copt;
-  copt.push_back(kTBBR);
-  client_config.SetClientConnectionOptions(copt);
-
-  CryptoHandshakeMessage msg;
-  client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-
-  EXPECT_FALSE(config_.HasReceivedConnectionOptions());
-}
-
-TEST_P(QuicConfigTest, HasClientRequestedIndependentOption) {
-  if (version_.UsesTls()) {
-    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector client_opt;
-  client_opt.push_back(kRENO);
-  QuicTagVector copt;
-  copt.push_back(kTBBR);
-  client_config.SetClientConnectionOptions(client_opt);
-  client_config.SetConnectionOptionsToSend(copt);
-  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
-      kTBBR, Perspective::IS_CLIENT));
-  EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
-      kRENO, Perspective::IS_CLIENT));
-  EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
-      kTBBR, Perspective::IS_CLIENT));
-
-  CryptoHandshakeMessage msg;
-  client_config.ToHandshakeMessage(&msg, version_.transport_version);
-
-  std::string error_details;
-  const QuicErrorCode error =
-      config_.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-  EXPECT_TRUE(config_.negotiated());
-
-  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
-  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
-  EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
-      kRENO, Perspective::IS_SERVER));
-  EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
-      kTBBR, Perspective::IS_SERVER));
-}
-
-TEST_P(QuicConfigTest, IncomingLargeIdleTimeoutTransportParameter) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  // Configure our idle timeout to 60s, then receive 120s from peer.
-  // Since the received value is above ours, we should then use ours.
-  config_.SetIdleNetworkTimeout(quic::QuicTime::Delta::FromSeconds(60));
-  TransportParameters params;
-  params.max_idle_timeout_ms.set_value(120000);
-
-  std::string error_details = "foobar";
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_EQ("", error_details);
-  EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(60),
-            config_.IdleNetworkTimeout());
-}
-
-TEST_P(QuicConfigTest, ReceivedInvalidMinAckDelayInTransportParameter) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  TransportParameters params;
-
-  params.max_ack_delay.set_value(25 /*ms*/);
-  params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli + 1);
-  std::string error_details = "foobar";
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-  EXPECT_EQ("MinAckDelay is greater than MaxAckDelay.", error_details);
-
-  params.max_ack_delay.set_value(25 /*ms*/);
-  params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli);
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_TRUE(error_details.empty());
-}
-
-TEST_P(QuicConfigTest, FillTransportParams) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-      2 * kMinimumFlowControlSendWindow);
-  config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-      3 * kMinimumFlowControlSendWindow);
-  config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
-      4 * kMinimumFlowControlSendWindow);
-  config_.SetMaxPacketSizeToSend(kMaxPacketSizeForTest);
-  config_.SetMaxDatagramFrameSizeToSend(kMaxDatagramFrameSizeForTest);
-  config_.SetActiveConnectionIdLimitToSend(kActiveConnectionIdLimitForTest);
-
-  config_.SetOriginalConnectionIdToSend(TestConnectionId(0x1111));
-  config_.SetInitialSourceConnectionIdToSend(TestConnectionId(0x2222));
-  config_.SetRetrySourceConnectionIdToSend(TestConnectionId(0x3333));
-  config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
-
-  QuicIpAddress host;
-  host.FromString("127.0.3.1");
-  QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
-  QuicConnectionId new_connection_id = TestConnectionId(5);
-  StatelessResetToken new_stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(new_connection_id);
-  config_.SetIPv4AlternateServerAddressToSend(
-      kTestServerAddress, new_connection_id, new_stateless_reset_token);
-
-  TransportParameters params;
-  config_.FillTransportParameters(&params);
-
-  EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
-            params.initial_max_stream_data_bidi_remote.value());
-  EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
-            params.initial_max_stream_data_bidi_local.value());
-  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
-            params.initial_max_stream_data_uni.value());
-
-  EXPECT_EQ(static_cast<uint64_t>(kMaximumIdleTimeoutSecs * 1000),
-            params.max_idle_timeout_ms.value());
-
-  EXPECT_EQ(kMaxPacketSizeForTest, params.max_udp_payload_size.value());
-  EXPECT_EQ(kMaxDatagramFrameSizeForTest,
-            params.max_datagram_frame_size.value());
-  EXPECT_EQ(kActiveConnectionIdLimitForTest,
-            params.active_connection_id_limit.value());
-
-  ASSERT_TRUE(params.original_destination_connection_id.has_value());
-  EXPECT_EQ(TestConnectionId(0x1111),
-            params.original_destination_connection_id.value());
-  ASSERT_TRUE(params.initial_source_connection_id.has_value());
-  EXPECT_EQ(TestConnectionId(0x2222),
-            params.initial_source_connection_id.value());
-  ASSERT_TRUE(params.retry_source_connection_id.has_value());
-  EXPECT_EQ(TestConnectionId(0x3333),
-            params.retry_source_connection_id.value());
-
-  EXPECT_EQ(
-      static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli,
-      params.min_ack_delay_us.value());
-
-  EXPECT_EQ(params.preferred_address->ipv4_socket_address, kTestServerAddress);
-  EXPECT_EQ(*reinterpret_cast<StatelessResetToken*>(
-                &params.preferred_address->stateless_reset_token.front()),
-            new_stateless_reset_token);
-}
-
-TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  TransportParameters params;
-
-  params.initial_max_stream_data_bidi_local.set_value(
-      2 * kMinimumFlowControlSendWindow);
-  params.initial_max_stream_data_bidi_remote.set_value(
-      3 * kMinimumFlowControlSendWindow);
-  params.initial_max_stream_data_uni.set_value(4 *
-                                               kMinimumFlowControlSendWindow);
-  params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
-  params.max_datagram_frame_size.set_value(kMaxDatagramFrameSizeForTest);
-  params.initial_max_streams_bidi.set_value(kDefaultMaxStreamsPerConnection);
-  params.stateless_reset_token = CreateStatelessResetTokenForTest();
-  params.max_ack_delay.set_value(kMaxAckDelayForTest);
-  params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
-  params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
-  params.active_connection_id_limit.set_value(kActiveConnectionIdLimitForTest);
-  params.original_destination_connection_id = TestConnectionId(0x1111);
-  params.initial_source_connection_id = TestConnectionId(0x2222);
-  params.retry_source_connection_id = TestConnectionId(0x3333);
-
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ true, &error_details),
-              IsQuicNoError())
-      << error_details;
-
-  EXPECT_FALSE(config_.negotiated());
-
-  ASSERT_TRUE(
-      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-  EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
-            config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-
-  ASSERT_TRUE(
-      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-  EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
-            config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-
-  ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
-            config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
-
-  ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
-  EXPECT_EQ(kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
-
-  ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
-  EXPECT_EQ(kMaxDatagramFrameSizeForTest,
-            config_.ReceivedMaxDatagramFrameSize());
-
-  ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            config_.ReceivedMaxBidirectionalStreams());
-
-  EXPECT_FALSE(config_.DisableConnectionMigration());
-
-  // The following config shouldn't be processed because of resumption.
-  EXPECT_FALSE(config_.HasReceivedStatelessResetToken());
-  EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
-  EXPECT_FALSE(config_.HasReceivedAckDelayExponent());
-  EXPECT_FALSE(config_.HasReceivedMinAckDelayMs());
-  EXPECT_FALSE(config_.HasReceivedOriginalConnectionId());
-  EXPECT_FALSE(config_.HasReceivedInitialSourceConnectionId());
-  EXPECT_FALSE(config_.HasReceivedRetrySourceConnectionId());
-
-  // Let the config process another slightly tweaked transport paramters.
-  // Note that the values for flow control and stream limit cannot be smaller
-  // than before. This rule is enforced in QuicSession::OnConfigNegotiated().
-  params.initial_max_stream_data_bidi_local.set_value(
-      2 * kMinimumFlowControlSendWindow + 1);
-  params.initial_max_stream_data_bidi_remote.set_value(
-      4 * kMinimumFlowControlSendWindow);
-  params.initial_max_stream_data_uni.set_value(5 *
-                                               kMinimumFlowControlSendWindow);
-  params.max_udp_payload_size.set_value(2 * kMaxPacketSizeForTest);
-  params.max_datagram_frame_size.set_value(2 * kMaxDatagramFrameSizeForTest);
-  params.initial_max_streams_bidi.set_value(2 *
-                                            kDefaultMaxStreamsPerConnection);
-  params.disable_active_migration = true;
-
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError())
-      << error_details;
-
-  EXPECT_TRUE(config_.negotiated());
-
-  ASSERT_TRUE(
-      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-  EXPECT_EQ(2 * kMinimumFlowControlSendWindow + 1,
-            config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-
-  ASSERT_TRUE(
-      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
-            config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-
-  ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
-  EXPECT_EQ(5 * kMinimumFlowControlSendWindow,
-            config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
-
-  ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
-  EXPECT_EQ(2 * kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
-
-  ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
-  EXPECT_EQ(2 * kMaxDatagramFrameSizeForTest,
-            config_.ReceivedMaxDatagramFrameSize());
-
-  ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
-  EXPECT_EQ(2 * kDefaultMaxStreamsPerConnection,
-            config_.ReceivedMaxBidirectionalStreams());
-
-  EXPECT_TRUE(config_.DisableConnectionMigration());
-
-  ASSERT_TRUE(config_.HasReceivedStatelessResetToken());
-
-  ASSERT_TRUE(config_.HasReceivedMaxAckDelayMs());
-  EXPECT_EQ(config_.ReceivedMaxAckDelayMs(), kMaxAckDelayForTest);
-
-  ASSERT_TRUE(config_.HasReceivedMinAckDelayMs());
-  EXPECT_EQ(config_.ReceivedMinAckDelayMs(),
-            kMinAckDelayUsForTest / kNumMicrosPerMilli);
-
-  ASSERT_TRUE(config_.HasReceivedAckDelayExponent());
-  EXPECT_EQ(config_.ReceivedAckDelayExponent(), kAckDelayExponentForTest);
-
-  ASSERT_TRUE(config_.HasReceivedActiveConnectionIdLimit());
-  EXPECT_EQ(config_.ReceivedActiveConnectionIdLimit(),
-            kActiveConnectionIdLimitForTest);
-
-  ASSERT_TRUE(config_.HasReceivedOriginalConnectionId());
-  EXPECT_EQ(config_.ReceivedOriginalConnectionId(), TestConnectionId(0x1111));
-  ASSERT_TRUE(config_.HasReceivedInitialSourceConnectionId());
-  EXPECT_EQ(config_.ReceivedInitialSourceConnectionId(),
-            TestConnectionId(0x2222));
-  ASSERT_TRUE(config_.HasReceivedRetrySourceConnectionId());
-  EXPECT_EQ(config_.ReceivedRetrySourceConnectionId(),
-            TestConnectionId(0x3333));
-}
-
-TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-  TransportParameters params;
-  params.disable_active_migration = true;
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  EXPECT_TRUE(config_.DisableConnectionMigration());
-}
-
-TEST_P(QuicConfigTest, SendPreferredIPv4Address) {
-  if (!version_.UsesTls()) {
-    // TransportParameters are only used for QUIC+TLS.
-    return;
-  }
-
-  EXPECT_FALSE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
-
-  TransportParameters params;
-  QuicIpAddress host;
-  host.FromString("::ffff:192.0.2.128");
-  QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
-  QuicConnectionId new_connection_id = TestConnectionId(5);
-  StatelessResetToken new_stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(new_connection_id);
-  auto preferred_address =
-      std::make_unique<TransportParameters::PreferredAddress>();
-  preferred_address->ipv6_socket_address = kTestServerAddress;
-  preferred_address->connection_id = new_connection_id;
-  preferred_address->stateless_reset_token.assign(
-      reinterpret_cast<const char*>(&new_stateless_reset_token),
-      reinterpret_cast<const char*>(&new_stateless_reset_token) +
-          sizeof(new_stateless_reset_token));
-  params.preferred_address = std::move(preferred_address);
-
-  std::string error_details;
-  EXPECT_THAT(config_.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-
-  EXPECT_TRUE(config_.HasReceivedIPv6AlternateServerAddress());
-  EXPECT_EQ(config_.ReceivedIPv6AlternateServerAddress(), kTestServerAddress);
-  EXPECT_TRUE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
-  const std::pair<QuicConnectionId, StatelessResetToken>&
-      preferred_address_connection_id_and_token =
-          config_.ReceivedPreferredAddressConnectionIdAndToken();
-  EXPECT_EQ(preferred_address_connection_id_and_token.first, new_connection_id);
-  EXPECT_EQ(preferred_address_connection_id_and_token.second,
-            new_stateless_reset_token);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
deleted file mode 100644
index 510e096..0000000
--- a/quic/core/quic_connection.cc
+++ /dev/null
@@ -1,7118 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection.h"
-
-#include <string.h>
-#include <sys/types.h>
-
-#include <algorithm>
-#include <iterator>
-#include <limits>
-#include <memory>
-#include <optional>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_legacy_version_encapsulator.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_flag_utils.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-class QuicDecrypter;
-class QuicEncrypter;
-
-namespace {
-
-// Maximum number of consecutive sent nonretransmittable packets.
-const QuicPacketCount kMaxConsecutiveNonRetransmittablePackets = 19;
-
-// The minimum release time into future in ms.
-const int kMinReleaseTimeIntoFutureMs = 1;
-
-// Base class of all alarms owned by a QuicConnection.
-class QuicConnectionAlarmDelegate : public QuicAlarm::Delegate {
- public:
-  explicit QuicConnectionAlarmDelegate(QuicConnection* connection)
-      : connection_(connection) {}
-  QuicConnectionAlarmDelegate(const QuicConnectionAlarmDelegate&) = delete;
-  QuicConnectionAlarmDelegate& operator=(const QuicConnectionAlarmDelegate&) =
-      delete;
-
-  QuicConnectionContext* GetConnectionContext() override {
-    return (connection_ == nullptr) ? nullptr : connection_->context();
-  }
-
- protected:
-  QuicConnection* connection_;
-};
-
-// An alarm that is scheduled to send an ack if a timeout occurs.
-class AckAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->ack_frame_updated());
-    QUICHE_DCHECK(connection_->connected());
-    QuicConnection::ScopedPacketFlusher flusher(connection_);
-    if (connection_->SupportsMultiplePacketNumberSpaces()) {
-      connection_->SendAllPendingAcks();
-    } else {
-      connection_->SendAck();
-    }
-  }
-};
-
-// This alarm will be scheduled any time a data-bearing packet is sent out.
-// When the alarm goes off, the connection checks to see if the oldest packets
-// have been acked, and retransmit them if they have not.
-class RetransmissionAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    connection_->OnRetransmissionTimeout();
-  }
-};
-
-// An alarm that is scheduled when the SentPacketManager requires a delay
-// before sending packets and fires when the packet may be sent.
-class SendAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    connection_->WriteIfNotBlocked();
-  }
-};
-
-class PingAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    connection_->OnPingTimeout();
-  }
-};
-
-class MtuDiscoveryAlarmDelegate : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    connection_->DiscoverMtu();
-  }
-};
-
-class ProcessUndecryptablePacketsAlarmDelegate
-    : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    QuicConnection::ScopedPacketFlusher flusher(connection_);
-    connection_->MaybeProcessUndecryptablePackets();
-  }
-};
-
-class DiscardPreviousOneRttKeysAlarmDelegate
-    : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    connection_->DiscardPreviousOneRttKeys();
-  }
-};
-
-class DiscardZeroRttDecryptionKeysAlarmDelegate
-    : public QuicConnectionAlarmDelegate {
- public:
-  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
-
-  void OnAlarm() override {
-    QUICHE_DCHECK(connection_->connected());
-    QUIC_DLOG(INFO) << "0-RTT discard alarm fired";
-    connection_->RemoveDecrypter(ENCRYPTION_ZERO_RTT);
-  }
-};
-
-// When the clearer goes out of scope, the coalesced packet gets cleared.
-class ScopedCoalescedPacketClearer {
- public:
-  explicit ScopedCoalescedPacketClearer(QuicCoalescedPacket* coalesced)
-      : coalesced_(coalesced) {}
-  ~ScopedCoalescedPacketClearer() { coalesced_->Clear(); }
-
- private:
-  QuicCoalescedPacket* coalesced_;  // Unowned.
-};
-
-// Whether this incoming packet is allowed to replace our connection ID.
-bool PacketCanReplaceServerConnectionId(const QuicPacketHeader& header,
-                                        Perspective perspective) {
-  return perspective == Perspective::IS_CLIENT &&
-         header.form == IETF_QUIC_LONG_HEADER_PACKET &&
-         header.version.IsKnown() &&
-         header.version.AllowsVariableLengthConnectionIds() &&
-         (header.long_packet_type == INITIAL ||
-          header.long_packet_type == RETRY);
-}
-
-CongestionControlType GetDefaultCongestionControlType() {
-  if (GetQuicReloadableFlag(quic_default_to_bbr_v2)) {
-    return kBBRv2;
-  }
-
-  if (GetQuicReloadableFlag(quic_default_to_bbr)) {
-    return kBBR;
-  }
-
-  return kCubicBytes;
-}
-
-}  // namespace
-
-#define ENDPOINT \
-  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicConnection::QuicConnection(
-    QuicConnectionId server_connection_id,
-    QuicSocketAddress initial_self_address,
-    QuicSocketAddress initial_peer_address,
-    QuicConnectionHelperInterface* helper, QuicAlarmFactory* alarm_factory,
-    QuicPacketWriter* writer, bool owns_writer, Perspective perspective,
-    const ParsedQuicVersionVector& supported_versions)
-    : framer_(supported_versions, helper->GetClock()->ApproximateNow(),
-              perspective, server_connection_id.length()),
-      current_packet_content_(NO_FRAMES_RECEIVED),
-      is_current_packet_connectivity_probing_(false),
-      has_path_challenge_in_current_packet_(false),
-      current_effective_peer_migration_type_(NO_CHANGE),
-      helper_(helper),
-      alarm_factory_(alarm_factory),
-      per_packet_options_(nullptr),
-      writer_(writer),
-      owns_writer_(owns_writer),
-      encryption_level_(ENCRYPTION_INITIAL),
-      clock_(helper->GetClock()),
-      random_generator_(helper->GetRandomGenerator()),
-      client_connection_id_is_set_(false),
-      direct_peer_address_(initial_peer_address),
-      default_path_(initial_self_address, QuicSocketAddress(),
-                    /*client_connection_id=*/EmptyQuicConnectionId(),
-                    server_connection_id,
-                    /*stateless_reset_token=*/absl::nullopt),
-      active_effective_peer_migration_type_(NO_CHANGE),
-      support_key_update_for_connection_(false),
-      last_packet_decrypted_(false),
-      last_size_(0),
-      current_packet_data_(nullptr),
-      last_decrypted_packet_level_(ENCRYPTION_INITIAL),
-      should_last_packet_instigate_acks_(false),
-      max_undecryptable_packets_(0),
-      max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
-      idle_timeout_connection_close_behavior_(
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET),
-      num_rtos_for_blackhole_detection_(0),
-      uber_received_packet_manager_(&stats_),
-      stop_waiting_count_(0),
-      pending_retransmission_alarm_(false),
-      defer_send_in_response_to_packets_(false),
-      ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
-      initial_retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
-      consecutive_retransmittable_on_wire_ping_count_(0),
-      retransmittable_on_wire_ping_count_(0),
-      arena_(),
-      ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this),
-                                             &arena_)),
-      retransmission_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<RetransmissionAlarmDelegate>(this), &arena_)),
-      send_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<SendAlarmDelegate>(this), &arena_)),
-      ping_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<PingAlarmDelegate>(this), &arena_)),
-      mtu_discovery_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<MtuDiscoveryAlarmDelegate>(this), &arena_)),
-      process_undecryptable_packets_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<ProcessUndecryptablePacketsAlarmDelegate>(this), &arena_)),
-      discard_previous_one_rtt_keys_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<DiscardPreviousOneRttKeysAlarmDelegate>(this), &arena_)),
-      discard_zero_rtt_decryption_keys_alarm_(alarm_factory_->CreateAlarm(
-          arena_.New<DiscardZeroRttDecryptionKeysAlarmDelegate>(this),
-          &arena_)),
-      visitor_(nullptr),
-      debug_visitor_(nullptr),
-      packet_creator_(server_connection_id, &framer_, random_generator_, this),
-      last_received_packet_info_(clock_->ApproximateNow()),
-      sent_packet_manager_(perspective, clock_, random_generator_, &stats_,
-                           GetDefaultCongestionControlType()),
-      version_negotiated_(false),
-      perspective_(perspective),
-      connected_(true),
-      can_truncate_connection_ids_(perspective == Perspective::IS_SERVER),
-      mtu_probe_count_(0),
-      previous_validated_mtu_(0),
-      peer_max_packet_size_(kDefaultMaxPacketSizeTransportParam),
-      largest_received_packet_size_(0),
-      write_error_occurred_(false),
-      no_stop_waiting_frames_(version().HasIetfInvariantHeader()),
-      consecutive_num_packets_with_no_retransmittable_frames_(0),
-      max_consecutive_num_packets_with_no_retransmittable_frames_(
-          kMaxConsecutiveNonRetransmittablePackets),
-      bundle_retransmittable_with_pto_ack_(false),
-      fill_up_link_during_probing_(false),
-      probing_retransmission_pending_(false),
-      last_control_frame_id_(kInvalidControlFrameId),
-      is_path_degrading_(false),
-      processing_ack_frame_(false),
-      supports_release_time_(false),
-      release_time_into_future_(QuicTime::Delta::Zero()),
-      blackhole_detector_(this, &arena_, alarm_factory_, &context_),
-      idle_network_detector_(this, clock_->ApproximateNow(), &arena_,
-                             alarm_factory_, &context_),
-      path_validator_(alarm_factory_, &arena_, this, random_generator_,
-                      &context_),
-      most_recent_frame_type_(NUM_FRAME_TYPES) {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
-                default_path_.self_address.IsInitialized());
-
-  QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
-                  << server_connection_id
-                  << " and version: " << ParsedQuicVersionToString(version());
-
-  QUIC_BUG_IF(quic_bug_12714_2, !QuicUtils::IsConnectionIdValidForVersion(
-                                    server_connection_id, transport_version()))
-      << "QuicConnection: attempted to use server connection ID "
-      << server_connection_id << " which is invalid with version " << version();
-  framer_.set_visitor(this);
-  stats_.connection_creation_time = clock_->ApproximateNow();
-  // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
-  // and make it required non-null, because it's always used.
-  sent_packet_manager_.SetNetworkChangeVisitor(this);
-  if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) {
-    sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero());
-    release_time_into_future_ =
-        QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs);
-  }
-  // Allow the packet writer to potentially reduce the packet size to a value
-  // even smaller than kDefaultMaxPacketSize.
-  SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
-                         ? kDefaultServerMaxPacketSize
-                         : kDefaultMaxPacketSize);
-  uber_received_packet_manager_.set_max_ack_ranges(255);
-  MaybeEnableMultiplePacketNumberSpacesSupport();
-  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
-                supported_versions.size() == 1);
-  InstallInitialCrypters(default_path_.server_connection_id);
-
-  // On the server side, version negotiation has been done by the dispatcher,
-  // and the server connection is created with the right version.
-  if (perspective_ == Perspective::IS_SERVER) {
-    SetVersionNegotiated();
-  }
-  if (default_enable_5rto_blackhole_detection_) {
-    num_rtos_for_blackhole_detection_ = 5;
-    if (GetQuicReloadableFlag(quic_disable_server_blackhole_detection) &&
-        perspective_ == Perspective::IS_SERVER) {
-      QUIC_RELOADABLE_FLAG_COUNT(quic_disable_server_blackhole_detection);
-      blackhole_detection_disabled_ = true;
-    }
-  }
-  packet_creator_.SetDefaultPeerAddress(initial_peer_address);
-}
-
-void QuicConnection::InstallInitialCrypters(QuicConnectionId connection_id) {
-  CrypterPair crypters;
-  CryptoUtils::CreateInitialObfuscators(perspective_, version(), connection_id,
-                                        &crypters);
-  SetEncrypter(ENCRYPTION_INITIAL, std::move(crypters.encrypter));
-  if (version().KnowsWhichDecrypterToUse()) {
-    InstallDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
-  } else {
-    SetDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
-  }
-}
-
-QuicConnection::~QuicConnection() {
-  QUICHE_DCHECK_GE(stats_.max_egress_mtu, long_term_mtu_);
-  if (owns_writer_) {
-    delete writer_;
-  }
-  ClearQueuedPackets();
-  if (stats_
-          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter >
-      0) {
-    QUIC_CODE_COUNT_N(
-        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 2,
-        3);
-  } else {
-    QUIC_CODE_COUNT_N(
-        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 3,
-        3);
-  }
-}
-
-void QuicConnection::ClearQueuedPackets() {
-  buffered_packets_.clear();
-}
-
-bool QuicConnection::ValidateConfigConnectionIds(const QuicConfig& config) {
-  QUICHE_DCHECK(config.negotiated());
-  if (!version().UsesTls()) {
-    // QUIC+TLS is required to transmit connection ID transport parameters.
-    return true;
-  }
-  // This function validates connection IDs as defined in IETF draft-28 and
-  // later.
-
-  // Validate initial_source_connection_id.
-  QuicConnectionId expected_initial_source_connection_id;
-  if (perspective_ == Perspective::IS_CLIENT) {
-    expected_initial_source_connection_id = default_path_.server_connection_id;
-  } else {
-    expected_initial_source_connection_id = default_path_.client_connection_id;
-  }
-  if (!config.HasReceivedInitialSourceConnectionId() ||
-      config.ReceivedInitialSourceConnectionId() !=
-          expected_initial_source_connection_id) {
-    std::string received_value;
-    if (config.HasReceivedInitialSourceConnectionId()) {
-      received_value = config.ReceivedInitialSourceConnectionId().ToString();
-    } else {
-      received_value = "none";
-    }
-    std::string error_details =
-        absl::StrCat("Bad initial_source_connection_id: expected ",
-                     expected_initial_source_connection_id.ToString(),
-                     ", received ", received_value);
-    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  if (perspective_ == Perspective::IS_CLIENT) {
-    // Validate original_destination_connection_id.
-    if (!config.HasReceivedOriginalConnectionId() ||
-        config.ReceivedOriginalConnectionId() !=
-            GetOriginalDestinationConnectionId()) {
-      std::string received_value;
-      if (config.HasReceivedOriginalConnectionId()) {
-        received_value = config.ReceivedOriginalConnectionId().ToString();
-      } else {
-        received_value = "none";
-      }
-      std::string error_details =
-          absl::StrCat("Bad original_destination_connection_id: expected ",
-                       GetOriginalDestinationConnectionId().ToString(),
-                       ", received ", received_value);
-      CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return false;
-    }
-    // Validate retry_source_connection_id.
-    if (retry_source_connection_id_.has_value()) {
-      // We received a RETRY packet, validate that the retry source
-      // connection ID from the config matches the one from the RETRY.
-      if (!config.HasReceivedRetrySourceConnectionId() ||
-          config.ReceivedRetrySourceConnectionId() !=
-              retry_source_connection_id_.value()) {
-        std::string received_value;
-        if (config.HasReceivedRetrySourceConnectionId()) {
-          received_value = config.ReceivedRetrySourceConnectionId().ToString();
-        } else {
-          received_value = "none";
-        }
-        std::string error_details =
-            absl::StrCat("Bad retry_source_connection_id: expected ",
-                         retry_source_connection_id_.value().ToString(),
-                         ", received ", received_value);
-        CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
-                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-        return false;
-      }
-    } else {
-      // We did not receive a RETRY packet, make sure we did not receive the
-      // retry_source_connection_id transport parameter.
-      if (config.HasReceivedRetrySourceConnectionId()) {
-        std::string error_details = absl::StrCat(
-            "Bad retry_source_connection_id: did not receive RETRY but "
-            "received ",
-            config.ReceivedRetrySourceConnectionId().ToString());
-        CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
-                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-void QuicConnection::SetFromConfig(const QuicConfig& config) {
-  if (config.negotiated()) {
-    // Handshake complete, set handshake timeout to Infinite.
-    SetNetworkTimeouts(QuicTime::Delta::Infinite(),
-                       config.IdleNetworkTimeout());
-    idle_timeout_connection_close_behavior_ =
-        ConnectionCloseBehavior::SILENT_CLOSE;
-    if (perspective_ == Perspective::IS_SERVER) {
-      idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior::
-          SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED;
-    }
-    if (config.HasClientRequestedIndependentOption(kNSLC, perspective_)) {
-      idle_timeout_connection_close_behavior_ =
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET;
-    }
-    if (!ValidateConfigConnectionIds(config)) {
-      return;
-    }
-    support_key_update_for_connection_ = version().UsesTls();
-    framer_.SetKeyUpdateSupportForConnection(
-        support_key_update_for_connection_);
-  } else {
-    SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
-                       config.max_idle_time_before_crypto_handshake());
-    if (config.HasClientRequestedIndependentOption(kNCHP, perspective_)) {
-      packet_creator_.set_chaos_protection_enabled(false);
-    }
-  }
-
-  if (version().HasIetfQuicFrames() &&
-      config.HasReceivedPreferredAddressConnectionIdAndToken()) {
-    QuicNewConnectionIdFrame frame;
-    std::tie(frame.connection_id, frame.stateless_reset_token) =
-        config.ReceivedPreferredAddressConnectionIdAndToken();
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    OnNewConnectionIdFrameInner(frame);
-  }
-
-  sent_packet_manager_.SetFromConfig(config);
-  if (perspective_ == Perspective::IS_SERVER &&
-      config.HasClientSentConnectionOption(kAFF2, perspective_)) {
-    send_ack_frequency_on_handshake_completion_ = true;
-  }
-  if (config.HasReceivedBytesForConnectionId() &&
-      can_truncate_connection_ids_) {
-    packet_creator_.SetServerConnectionIdLength(
-        config.ReceivedBytesForConnectionId());
-  }
-  max_undecryptable_packets_ = config.max_undecryptable_packets();
-
-  if (!GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
-    if (config.HasClientRequestedIndependentOption(kMTUH, perspective_)) {
-      SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
-    }
-  }
-  if (config.HasClientRequestedIndependentOption(kMTUL, perspective_)) {
-    SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
-  }
-  if (default_enable_5rto_blackhole_detection_) {
-    if (config.HasClientRequestedIndependentOption(kCBHD, perspective_)) {
-      QUIC_CODE_COUNT(quic_client_only_blackhole_detection);
-      blackhole_detection_disabled_ = true;
-    }
-    if (config.HasClientSentConnectionOption(kNBHD, perspective_)) {
-      blackhole_detection_disabled_ = true;
-    }
-    if (config.HasClientSentConnectionOption(k2RTO, perspective_)) {
-      QUIC_CODE_COUNT(quic_2rto_blackhole_detection);
-      num_rtos_for_blackhole_detection_ = 2;
-    }
-    if (config.HasClientSentConnectionOption(k3RTO, perspective_)) {
-      QUIC_CODE_COUNT(quic_3rto_blackhole_detection);
-      num_rtos_for_blackhole_detection_ = 3;
-    }
-    if (config.HasClientSentConnectionOption(k4RTO, perspective_)) {
-      QUIC_CODE_COUNT(quic_4rto_blackhole_detection);
-      num_rtos_for_blackhole_detection_ = 4;
-    }
-    if (config.HasClientSentConnectionOption(k6RTO, perspective_)) {
-      QUIC_CODE_COUNT(quic_6rto_blackhole_detection);
-      num_rtos_for_blackhole_detection_ = 6;
-    }
-  }
-
-  if (config.HasClientRequestedIndependentOption(kFIDT, perspective_)) {
-    idle_network_detector_.enable_shorter_idle_timeout_on_sent_packet();
-  }
-  if (config.HasClientRequestedIndependentOption(k3AFF, perspective_)) {
-    anti_amplification_factor_ = 3;
-  }
-  if (config.HasClientRequestedIndependentOption(k10AF, perspective_)) {
-    anti_amplification_factor_ = 10;
-  }
-
-  if (GetQuicReloadableFlag(quic_enable_server_on_wire_ping) &&
-      perspective_ == Perspective::IS_SERVER &&
-      config.HasClientSentConnectionOption(kSRWP, perspective_)) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_server_on_wire_ping);
-    set_initial_retransmittable_on_wire_timeout(
-        QuicTime::Delta::FromMilliseconds(200));
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnSetFromConfig(config);
-  }
-  uber_received_packet_manager_.SetFromConfig(config, perspective_);
-  if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
-    num_rtos_for_blackhole_detection_ = 5;
-  }
-  if (sent_packet_manager_.pto_enabled()) {
-    if (config.HasClientSentConnectionOption(k6PTO, perspective_) ||
-        config.HasClientSentConnectionOption(k7PTO, perspective_) ||
-        config.HasClientSentConnectionOption(k8PTO, perspective_)) {
-      num_rtos_for_blackhole_detection_ = 5;
-    }
-  }
-  if (config.HasClientSentConnectionOption(kNSTP, perspective_)) {
-    no_stop_waiting_frames_ = true;
-  }
-  if (config.HasReceivedStatelessResetToken()) {
-    default_path_.stateless_reset_token = config.ReceivedStatelessResetToken();
-  }
-  if (config.HasReceivedAckDelayExponent()) {
-    framer_.set_peer_ack_delay_exponent(config.ReceivedAckDelayExponent());
-  }
-  if (config.HasClientSentConnectionOption(kEACK, perspective_)) {
-    bundle_retransmittable_with_pto_ack_ = true;
-  }
-  if (config.HasClientSentConnectionOption(kDFER, perspective_)) {
-    defer_send_in_response_to_packets_ = false;
-  }
-
-  if (config.HasClientRequestedIndependentOption(kINVC, perspective_)) {
-    send_connection_close_for_invalid_version_ = true;
-  }
-  const bool remove_connection_migration_connection_option =
-      GetQuicReloadableFlag(quic_remove_connection_migration_connection_option);
-  if (remove_connection_migration_connection_option) {
-    QUIC_RELOADABLE_FLAG_COUNT(
-        quic_remove_connection_migration_connection_option);
-  }
-  if (framer_.version().HasIetfQuicFrames() && use_path_validator_ &&
-      count_bytes_on_alternative_path_separately_ &&
-      GetQuicReloadableFlag(quic_server_reverse_validate_new_path3) &&
-      (remove_connection_migration_connection_option ||
-       config.HasClientSentConnectionOption(kRVCM, perspective_))) {
-    QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 6, 6);
-    validate_client_addresses_ = true;
-  }
-  // Having connection_migration_use_new_cid_ depends on the same set of flags
-  // and connection option on both client and server sides has the advantage of:
-  // 1) Less chance of skew in using new connection ID or not between client
-  //    and server in unit tests with random flag combinations.
-  // 2) Client side's rollout can be protected by the same connection option.
-  connection_migration_use_new_cid_ =
-      validate_client_addresses_ &&
-      GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
-  if (config.HasReceivedMaxPacketSize()) {
-    peer_max_packet_size_ = config.ReceivedMaxPacketSize();
-    MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-  }
-  if (config.HasReceivedMaxDatagramFrameSize()) {
-    packet_creator_.SetMaxDatagramFrameSize(
-        config.ReceivedMaxDatagramFrameSize());
-  }
-
-  supports_release_time_ =
-      writer_ != nullptr && writer_->SupportsReleaseTime() &&
-      !config.HasClientSentConnectionOption(kNPCO, perspective_);
-
-  if (supports_release_time_) {
-    UpdateReleaseTimeIntoFuture();
-  }
-}
-
-void QuicConnection::EnableLegacyVersionEncapsulation(
-    const std::string& server_name) {
-  if (perspective_ != Perspective::IS_CLIENT) {
-    QUIC_BUG(quic_bug_10511_1)
-        << "Cannot enable Legacy Version Encapsulation on the server";
-    return;
-  }
-  if (legacy_version_encapsulation_enabled_) {
-    QUIC_BUG(quic_bug_10511_2)
-        << "Do not call EnableLegacyVersionEncapsulation twice";
-    return;
-  }
-  if (!QuicHostnameUtils::IsValidSNI(server_name)) {
-    // Legacy Version Encapsulation is only used when SNI is transmitted.
-    QUIC_DLOG(INFO)
-        << "Refusing to use Legacy Version Encapsulation with invalid SNI \""
-        << server_name << "\"";
-    return;
-  }
-  QUIC_DLOG(INFO) << "Enabling Legacy Version Encapsulation with SNI \""
-                  << server_name << "\"";
-  legacy_version_encapsulation_enabled_ = true;
-  legacy_version_encapsulation_sni_ = server_name;
-}
-
-bool QuicConnection::MaybeTestLiveness() {
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
-    return false;
-  }
-  const QuicTime idle_network_deadline =
-      idle_network_detector_.GetIdleNetworkDeadline();
-  if (!idle_network_deadline.IsInitialized()) {
-    return false;
-  }
-  const QuicTime now = clock_->ApproximateNow();
-  if (now > idle_network_deadline) {
-    QUIC_DLOG(WARNING) << "Idle network deadline has passed";
-    return false;
-  }
-  const QuicTime::Delta timeout = idle_network_deadline - now;
-  if (2 * timeout > idle_network_detector_.idle_network_timeout()) {
-    // Do not test liveness if timeout is > half timeout. This is used to
-    // prevent an infinite loop for short idle timeout.
-    return false;
-  }
-  if (!sent_packet_manager_.IsLessThanThreePTOs(timeout)) {
-    return false;
-  }
-  SendConnectivityProbingPacket(writer_, peer_address());
-  return true;
-}
-
-void QuicConnection::ApplyConnectionOptions(
-    const QuicTagVector& connection_options) {
-  sent_packet_manager_.ApplyConnectionOptions(connection_options);
-}
-
-void QuicConnection::OnSendConnectionState(
-    const CachedNetworkParameters& cached_network_params) {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnSendConnectionState(cached_network_params);
-  }
-}
-
-void QuicConnection::OnReceiveConnectionState(
-    const CachedNetworkParameters& cached_network_params) {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnReceiveConnectionState(cached_network_params);
-  }
-}
-
-void QuicConnection::ResumeConnectionState(
-    const CachedNetworkParameters& cached_network_params,
-    bool max_bandwidth_resumption) {
-  sent_packet_manager_.ResumeConnectionState(cached_network_params,
-                                             max_bandwidth_resumption);
-}
-
-void QuicConnection::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
-  sent_packet_manager_.SetMaxPacingRate(max_pacing_rate);
-}
-
-void QuicConnection::AdjustNetworkParameters(
-    const SendAlgorithmInterface::NetworkParams& params) {
-  sent_packet_manager_.AdjustNetworkParameters(params);
-}
-
-void QuicConnection::SetLossDetectionTuner(
-    std::unique_ptr<LossDetectionTunerInterface> tuner) {
-  sent_packet_manager_.SetLossDetectionTuner(std::move(tuner));
-}
-
-void QuicConnection::OnConfigNegotiated() {
-  sent_packet_manager_.OnConfigNegotiated();
-
-  if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server) &&
-      perspective_ == Perspective::IS_SERVER) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_mtu_discovery_at_server);
-    SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
-  }
-}
-
-QuicBandwidth QuicConnection::MaxPacingRate() const {
-  return sent_packet_manager_.MaxPacingRate();
-}
-
-bool QuicConnection::SelectMutualVersion(
-    const ParsedQuicVersionVector& available_versions) {
-  // Try to find the highest mutual version by iterating over supported
-  // versions, starting with the highest, and breaking out of the loop once we
-  // find a matching version in the provided available_versions vector.
-  const ParsedQuicVersionVector& supported_versions =
-      framer_.supported_versions();
-  for (size_t i = 0; i < supported_versions.size(); ++i) {
-    const ParsedQuicVersion& version = supported_versions[i];
-    if (std::find(available_versions.begin(), available_versions.end(),
-                  version) != available_versions.end()) {
-      framer_.set_version(version);
-      return true;
-    }
-  }
-
-  return false;
-}
-
-void QuicConnection::OnError(QuicFramer* framer) {
-  // Packets that we can not or have not decrypted are dropped.
-  // TODO(rch): add stats to measure this.
-  if (!connected_ || last_packet_decrypted_ == false) {
-    return;
-  }
-  CloseConnection(framer->error(), framer->detailed_error(),
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicConnection::OnPacket() {
-  last_packet_decrypted_ = false;
-}
-
-void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
-  // Check that any public reset packet with a different connection ID that was
-  // routed to this QuicConnection has been redirected before control reaches
-  // here.  (Check for a bug regression.)
-  QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  QUICHE_DCHECK(!version().HasIetfInvariantHeader());
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnPublicResetPacket(packet);
-  }
-  std::string error_details = "Received public reset.";
-  if (perspective_ == Perspective::IS_CLIENT && !packet.endpoint_id.empty()) {
-    absl::StrAppend(&error_details, " From ", packet.endpoint_id, ".");
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << error_details;
-  QUIC_CODE_COUNT(quic_tear_down_local_connection_on_public_reset);
-  TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
-                               error_details, ConnectionCloseSource::FROM_PEER);
-}
-
-bool QuicConnection::OnProtocolVersionMismatch(
-    ParsedQuicVersion received_version) {
-  QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
-                  << ParsedQuicVersionToString(received_version);
-  if (perspective_ == Perspective::IS_CLIENT) {
-    const std::string error_details = "Protocol version mismatch.";
-    QUIC_BUG(quic_bug_10511_3) << ENDPOINT << error_details;
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
-                    ConnectionCloseBehavior::SILENT_CLOSE);
-  }
-
-  // Server drops old packets that were sent by the client before the version
-  // was negotiated.
-  return false;
-}
-
-// Handles version negotiation for client connection.
-void QuicConnection::OnVersionNegotiationPacket(
-    const QuicVersionNegotiationPacket& packet) {
-  // Check that any public reset packet with a different connection ID that was
-  // routed to this QuicConnection has been redirected before control reaches
-  // here.  (Check for a bug regression.)
-  QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
-  if (perspective_ == Perspective::IS_SERVER) {
-    const std::string error_details =
-        "Server received version negotiation packet.";
-    QUIC_BUG(quic_bug_10511_4) << error_details;
-    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_version_negotiation);
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
-                    ConnectionCloseBehavior::SILENT_CLOSE);
-    return;
-  }
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnVersionNegotiationPacket(packet);
-  }
-
-  if (version_negotiated_) {
-    // Possibly a duplicate version negotiation packet.
-    return;
-  }
-
-  if (std::find(packet.versions.begin(), packet.versions.end(), version()) !=
-      packet.versions.end()) {
-    const std::string error_details = absl::StrCat(
-        "Server already supports client's version ",
-        ParsedQuicVersionToString(version()),
-        " and should have accepted the connection instead of sending {",
-        ParsedQuicVersionVectorToString(packet.versions), "}.");
-    QUIC_DLOG(WARNING) << error_details;
-    CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, error_details,
-                    ConnectionCloseBehavior::SILENT_CLOSE);
-    return;
-  }
-
-  server_supported_versions_ = packet.versions;
-  CloseConnection(
-      QUIC_INVALID_VERSION,
-      absl::StrCat(
-          "Client may support one of the versions in the server's list, but "
-          "it's going to close the connection anyway. Supported versions: {",
-          ParsedQuicVersionVectorToString(framer_.supported_versions()),
-          "}, peer supported versions: {",
-          ParsedQuicVersionVectorToString(packet.versions), "}"),
-      send_connection_close_for_invalid_version_
-          ? ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET
-          : ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-// Handles retry for client connection.
-void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
-                                   QuicConnectionId new_connection_id,
-                                   absl::string_view retry_token,
-                                   absl::string_view retry_integrity_tag,
-                                   absl::string_view retry_without_tag) {
-  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-  if (version().UsesTls()) {
-    if (!CryptoUtils::ValidateRetryIntegrityTag(
-            version(), default_path_.server_connection_id, retry_without_tag,
-            retry_integrity_tag)) {
-      QUIC_DLOG(ERROR) << "Ignoring RETRY with invalid integrity tag";
-      return;
-    }
-  } else {
-    if (original_connection_id != default_path_.server_connection_id) {
-      QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
-                       << original_connection_id << " not matching expected "
-                       << default_path_.server_connection_id << " token "
-                       << absl::BytesToHexString(retry_token);
-      return;
-    }
-  }
-  framer_.set_drop_incoming_retry_packets(true);
-  stats_.retry_packet_processed = true;
-  QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
-                  << default_path_.server_connection_id << " with "
-                  << new_connection_id << ", received token "
-                  << absl::BytesToHexString(retry_token);
-  if (!original_destination_connection_id_.has_value()) {
-    original_destination_connection_id_ = default_path_.server_connection_id;
-  }
-  QUICHE_DCHECK(!retry_source_connection_id_.has_value())
-      << retry_source_connection_id_.value();
-  retry_source_connection_id_ = new_connection_id;
-  ReplaceInitialServerConnectionId(new_connection_id);
-  packet_creator_.SetRetryToken(retry_token);
-
-  // Reinstall initial crypters because the connection ID changed.
-  InstallInitialCrypters(default_path_.server_connection_id);
-
-  sent_packet_manager_.MarkInitialPacketsForRetransmission();
-}
-
-void QuicConnection::SetOriginalDestinationConnectionId(
-    const QuicConnectionId& original_destination_connection_id) {
-  QUIC_DLOG(INFO) << "Setting original_destination_connection_id to "
-                  << original_destination_connection_id
-                  << " on connection with server_connection_id "
-                  << default_path_.server_connection_id;
-  QUICHE_DCHECK_NE(original_destination_connection_id,
-                   default_path_.server_connection_id);
-  InstallInitialCrypters(original_destination_connection_id);
-  QUICHE_DCHECK(!original_destination_connection_id_.has_value())
-      << original_destination_connection_id_.value();
-  original_destination_connection_id_ = original_destination_connection_id;
-  original_destination_connection_id_replacement_ =
-      default_path_.server_connection_id;
-}
-
-QuicConnectionId QuicConnection::GetOriginalDestinationConnectionId() {
-  if (original_destination_connection_id_.has_value()) {
-    return original_destination_connection_id_.value();
-  }
-  return default_path_.server_connection_id;
-}
-
-bool QuicConnection::ValidateServerConnectionId(
-    const QuicPacketHeader& header) const {
-  if (perspective_ == Perspective::IS_CLIENT &&
-      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
-    return true;
-  }
-
-  QuicConnectionId server_connection_id =
-      GetServerConnectionIdAsRecipient(header, perspective_);
-
-  if (server_connection_id == default_path_.server_connection_id ||
-      server_connection_id == original_destination_connection_id_) {
-    return true;
-  }
-
-  if (PacketCanReplaceServerConnectionId(header, perspective_)) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
-                    << server_connection_id << " instead of "
-                    << default_path_.server_connection_id;
-    return true;
-  }
-
-  if (connection_migration_use_new_cid_ &&
-      perspective_ == Perspective::IS_SERVER &&
-      self_issued_cid_manager_ != nullptr &&
-      self_issued_cid_manager_->IsConnectionIdInUse(server_connection_id)) {
-    return true;
-  }
-
-  return false;
-}
-
-bool QuicConnection::OnUnauthenticatedPublicHeader(
-    const QuicPacketHeader& header) {
-  last_packet_destination_connection_id_ = header.destination_connection_id;
-  // If last packet destination connection ID is the original server
-  // connection ID chosen by client, replaces it with the connection ID chosen
-  // by server.
-  if (perspective_ == Perspective::IS_SERVER &&
-      original_destination_connection_id_.has_value() &&
-      last_packet_destination_connection_id_ ==
-          *original_destination_connection_id_) {
-    last_packet_destination_connection_id_ =
-        original_destination_connection_id_replacement_;
-  }
-
-  // As soon as we receive an initial we start ignoring subsequent retries.
-  if (header.version_flag && header.long_packet_type == INITIAL) {
-    framer_.set_drop_incoming_retry_packets(true);
-  }
-
-  if (!ValidateServerConnectionId(header)) {
-    ++stats_.packets_dropped;
-    QuicConnectionId server_connection_id =
-        GetServerConnectionIdAsRecipient(header, perspective_);
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Ignoring packet from unexpected server connection ID "
-                    << server_connection_id << " instead of "
-                    << default_path_.server_connection_id;
-    if (debug_visitor_ != nullptr) {
-      debug_visitor_->OnIncorrectConnectionId(server_connection_id);
-    }
-    // If this is a server, the dispatcher routes each packet to the
-    // QuicConnection responsible for the packet's connection ID.  So if control
-    // arrives here and this is a server, the dispatcher must be malfunctioning.
-    QUICHE_DCHECK_NE(Perspective::IS_SERVER, perspective_);
-    return false;
-  }
-
-  if (!version().SupportsClientConnectionIds()) {
-    return true;
-  }
-
-  if (perspective_ == Perspective::IS_SERVER &&
-      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
-    return true;
-  }
-
-  QuicConnectionId client_connection_id =
-      GetClientConnectionIdAsRecipient(header, perspective_);
-
-  if (client_connection_id == default_path_.client_connection_id) {
-    return true;
-  }
-
-  if (!client_connection_id_is_set_ && perspective_ == Perspective::IS_SERVER) {
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Setting client connection ID from first packet to "
-                    << client_connection_id;
-    set_client_connection_id(client_connection_id);
-    return true;
-  }
-
-  if (connection_migration_use_new_cid_ &&
-      perspective_ == Perspective::IS_CLIENT &&
-      self_issued_cid_manager_ != nullptr &&
-      self_issued_cid_manager_->IsConnectionIdInUse(client_connection_id)) {
-    return true;
-  }
-
-  ++stats_.packets_dropped;
-  QUIC_DLOG(INFO) << ENDPOINT
-                  << "Ignoring packet from unexpected client connection ID "
-                  << client_connection_id << " instead of "
-                  << default_path_.client_connection_id;
-  return false;
-}
-
-bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnUnauthenticatedHeader(header);
-  }
-
-  // Sanity check on the server connection ID in header.
-  QUICHE_DCHECK(ValidateServerConnectionId(header));
-
-  if (packet_creator_.HasPendingFrames()) {
-    // Incoming packets may change a queued ACK frame.
-    const std::string error_details =
-        "Pending frames must be serialized before incoming packets are "
-        "processed.";
-    QUIC_BUG(quic_pending_frames_not_serialized)
-        << error_details << ", received header: " << header;
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  return true;
-}
-
-void QuicConnection::OnSuccessfulVersionNegotiation() {
-  visitor_->OnSuccessfulVersionNegotiation(version());
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnSuccessfulVersionNegotiation(version());
-  }
-}
-
-void QuicConnection::OnSuccessfulMigration(bool is_port_change) {
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  if (IsPathDegrading()) {
-    // If path was previously degrading, and migration is successful after
-    // probing, restart the path degrading and blackhole detection.
-    OnForwardProgressMade();
-  }
-  if (IsAlternativePath(default_path_.self_address,
-                        default_path_.peer_address)) {
-    // Reset alternative path state even if it is still under validation.
-    alternative_path_.Clear();
-  }
-  // TODO(b/159074035): notify SentPacketManger with RTT sample from probing.
-  if (version().HasIetfQuicFrames() && !is_port_change) {
-    sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
-  }
-}
-
-void QuicConnection::OnTransportParametersSent(
-    const TransportParameters& transport_parameters) const {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnTransportParametersSent(transport_parameters);
-  }
-}
-
-void QuicConnection::OnTransportParametersReceived(
-    const TransportParameters& transport_parameters) const {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnTransportParametersReceived(transport_parameters);
-  }
-}
-
-void QuicConnection::OnTransportParametersResumed(
-    const TransportParameters& transport_parameters) const {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnTransportParametersResumed(transport_parameters);
-  }
-}
-
-bool QuicConnection::HasPendingAcks() const {
-  return ack_alarm_->IsSet();
-}
-
-void QuicConnection::OnUserAgentIdKnown(const std::string& /*user_agent_id*/) {
-  sent_packet_manager_.OnUserAgentIdKnown();
-}
-
-void QuicConnection::OnDecryptedPacket(size_t /*length*/,
-                                       EncryptionLevel level) {
-  last_decrypted_packet_level_ = level;
-  last_packet_decrypted_ = true;
-  if (level == ENCRYPTION_FORWARD_SECURE &&
-      !have_decrypted_first_one_rtt_packet_) {
-    have_decrypted_first_one_rtt_packet_ = true;
-    if (version().UsesTls() && perspective_ == Perspective::IS_SERVER) {
-      // Servers MAY temporarily retain 0-RTT keys to allow decrypting reordered
-      // packets without requiring their contents to be retransmitted with 1-RTT
-      // keys. After receiving a 1-RTT packet, servers MUST discard 0-RTT keys
-      // within a short time; the RECOMMENDED time period is three times the
-      // Probe Timeout.
-      // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-discarding-0-rtt-keys
-      discard_zero_rtt_decryption_keys_alarm_->Set(
-          clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
-    }
-  }
-  if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
-      (last_decrypted_packet_level_ == ENCRYPTION_HANDSHAKE ||
-       last_decrypted_packet_level_ == ENCRYPTION_FORWARD_SECURE)) {
-    // Address is validated by successfully processing a HANDSHAKE or 1-RTT
-    // packet.
-    default_path_.validated = true;
-    stats_.address_validated_via_decrypting_packet = true;
-  }
-  idle_network_detector_.OnPacketReceived(
-      last_received_packet_info_.receipt_time);
-
-  visitor_->OnPacketDecrypted(level);
-}
-
-QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
-    const {
-  // By default, the connection is not proxied, and the effective peer address
-  // is the packet's source address, i.e. the direct peer address.
-  return last_received_packet_info_.source_address;
-}
-
-bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnPacketHeader(header, clock_->ApproximateNow(),
-                                   last_decrypted_packet_level_);
-  }
-
-  // Will be decremented below if we fall through to return true.
-  ++stats_.packets_dropped;
-
-  if (!ProcessValidatedPacket(header)) {
-    return false;
-  }
-
-  // Initialize the current packet content state.
-  most_recent_frame_type_ = NUM_FRAME_TYPES;
-  current_packet_content_ = NO_FRAMES_RECEIVED;
-  is_current_packet_connectivity_probing_ = false;
-  has_path_challenge_in_current_packet_ = false;
-  current_effective_peer_migration_type_ = NO_CHANGE;
-
-  if (perspective_ == Perspective::IS_CLIENT) {
-    if (!GetLargestReceivedPacket().IsInitialized() ||
-        header.packet_number > GetLargestReceivedPacket()) {
-      // Update direct_peer_address_ and default path peer_address immediately
-      // for client connections.
-      // TODO(fayang): only change peer addresses in application data packet
-      // number space.
-      UpdatePeerAddress(last_received_packet_info_.source_address);
-      default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
-    }
-  } else {
-    // At server, remember the address change type of effective_peer_address
-    // in current_effective_peer_migration_type_. But this variable alone
-    // doesn't necessarily starts a migration. A migration will be started
-    // later, once the current packet is confirmed to meet the following
-    // conditions:
-    // 1) current_effective_peer_migration_type_ is not NO_CHANGE.
-    // 2) The current packet is not a connectivity probing.
-    // 3) The current packet is not reordered, i.e. its packet number is the
-    //    largest of this connection so far.
-    // Once the above conditions are confirmed, a new migration will start
-    // even if there is an active migration underway.
-    current_effective_peer_migration_type_ =
-        QuicUtils::DetermineAddressChangeType(
-            default_path_.peer_address,
-            GetEffectivePeerAddressFromCurrentPacket());
-
-    if (connection_migration_use_new_cid_) {
-      auto effective_peer_address = GetEffectivePeerAddressFromCurrentPacket();
-      // Since server does not send new connection ID to client before handshake
-      // completion and source connection ID is omitted in short header packet,
-      // the server_connection_id on PathState on the server side does not
-      // affect the packets server writes after handshake completion. On the
-      // other hand, it is still desirable to have the "correct" server
-      // connection ID set on path.
-      // 1) If client uses 1 unique server connection ID per path and the packet
-      // is received from an existing path, then
-      // last_packet_destination_connection_id_ will always be the same as the
-      // server connection ID on path. Server side will maintain the 1-to-1
-      // mapping from server connection ID to path.
-      // 2) If client uses multiple server connection IDs on the same path,
-      // compared to the server_connection_id on path,
-      // last_packet_destination_connection_id_ has the advantage that it is
-      // still present in the session map since the packet can be routed here
-      // regardless of packet reordering.
-      if (IsDefaultPath(last_received_packet_info_.destination_address,
-                        effective_peer_address)) {
-        default_path_.server_connection_id =
-            last_packet_destination_connection_id_;
-      } else if (IsAlternativePath(
-                     last_received_packet_info_.destination_address,
-                     effective_peer_address)) {
-        alternative_path_.server_connection_id =
-            last_packet_destination_connection_id_;
-      }
-    }
-
-    if (last_packet_destination_connection_id_ !=
-            default_path_.server_connection_id &&
-        (!original_destination_connection_id_.has_value() ||
-         last_packet_destination_connection_id_ !=
-             *original_destination_connection_id_)) {
-      QUIC_CODE_COUNT(quic_connection_id_change);
-    }
-
-    QUIC_DLOG_IF(INFO, current_effective_peer_migration_type_ != NO_CHANGE)
-        << ENDPOINT << "Effective peer's ip:port changed from "
-        << default_path_.peer_address.ToString() << " to "
-        << GetEffectivePeerAddressFromCurrentPacket().ToString()
-        << ", active_effective_peer_migration_type is "
-        << active_effective_peer_migration_type_;
-  }
-
-  --stats_.packets_dropped;
-  QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
-  last_header_ = header;
-  if (!stats_.first_decrypted_packet.IsInitialized()) {
-    stats_.first_decrypted_packet = last_header_.packet_number;
-  }
-
-  // Record packet receipt to populate ack info before processing stream
-  // frames, since the processing may result in sending a bundled ack.
-  QuicTime receipt_time = idle_network_detector_.time_of_last_received_packet();
-  if (SupportsMultiplePacketNumberSpaces()) {
-    receipt_time = last_received_packet_info_.receipt_time;
-  }
-  uber_received_packet_manager_.RecordPacketReceived(
-      last_decrypted_packet_level_, last_header_, receipt_time);
-  if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
-      !header.retry_token.empty() &&
-      visitor_->ValidateToken(header.retry_token)) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Address validated via token.";
-    QUIC_CODE_COUNT(quic_address_validated_via_token);
-    default_path_.validated = true;
-    stats_.address_validated_via_token = true;
-  }
-  QUICHE_DCHECK(connected_);
-  return true;
-}
-
-bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_3, !connected_)
-      << "Processing STREAM frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a stream frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(STREAM_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnStreamFrame(frame);
-  }
-  if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
-      last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
-    if (MaybeConsiderAsMemoryCorruption(frame)) {
-      CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
-                      "Received crypto frame on non crypto stream.",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return false;
-    }
-
-    QUIC_PEER_BUG(quic_peer_bug_10511_6)
-        << ENDPOINT << "Received an unencrypted data frame: closing connection"
-        << " packet_number:" << last_header_.packet_number
-        << " stream_id:" << frame.stream_id
-        << " received_packets:" << ack_frame();
-    CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
-                    "Unencrypted stream data seen.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  // TODO(fayang): Consider moving UpdatePacketContent and
-  // MaybeUpdateAckTimeout to a stand-alone function instead of calling them for
-  // all frames.
-  MaybeUpdateAckTimeout();
-  visitor_->OnStreamFrame(frame);
-  stats_.stream_bytes_received += frame.data_length;
-  consecutive_retransmittable_on_wire_ping_count_ = 0;
-  return connected_;
-}
-
-bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_4, !connected_)
-      << "Processing CRYPTO frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a CRYPTO frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(CRYPTO_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnCryptoFrame(frame);
-  }
-  MaybeUpdateAckTimeout();
-  visitor_->OnCryptoFrame(frame);
-  return connected_;
-}
-
-bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
-                                     QuicTime::Delta ack_delay_time) {
-  QUIC_BUG_IF(quic_bug_12714_5, !connected_)
-      << "Processing ACK frame start when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  if (processing_ack_frame_) {
-    CloseConnection(QUIC_INVALID_ACK_DATA,
-                    "Received a new ack while processing an ack frame.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  // Since an ack frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(ACK_FRAME)) {
-    return false;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT
-                << "OnAckFrameStart, largest_acked: " << largest_acked;
-
-  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
-      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
-    return true;
-  }
-
-  if (!sent_packet_manager_.GetLargestSentPacket().IsInitialized() ||
-      largest_acked > sent_packet_manager_.GetLargestSentPacket()) {
-    QUIC_DLOG(WARNING) << ENDPOINT
-                       << "Peer's observed unsent packet:" << largest_acked
-                       << " vs " << sent_packet_manager_.GetLargestSentPacket()
-                       << ". SupportsMultiplePacketNumberSpaces():"
-                       << SupportsMultiplePacketNumberSpaces()
-                       << ", last_decrypted_packet_level_:"
-                       << last_decrypted_packet_level_;
-    // We got an ack for data we have not sent.
-    CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  processing_ack_frame_ = true;
-  sent_packet_manager_.OnAckFrameStart(
-      largest_acked, ack_delay_time,
-      idle_network_detector_.time_of_last_received_packet());
-  return true;
-}
-
-bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
-  QUIC_BUG_IF(quic_bug_12714_6, !connected_)
-      << "Processing ACK frame range when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
-
-  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
-      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
-    return true;
-  }
-
-  sent_packet_manager_.OnAckRange(start, end);
-  return true;
-}
-
-bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
-                                    QuicTime timestamp) {
-  QUIC_BUG_IF(quic_bug_10511_7, !connected_)
-      << "Processing ACK frame time stamp when connection "
-         "is closed. Last frame: "
-      << most_recent_frame_type_;
-  QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
-                << timestamp.ToDebuggingValue() << ")";
-
-  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
-      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
-    return true;
-  }
-
-  sent_packet_manager_.OnAckTimestamp(packet_number, timestamp);
-  return true;
-}
-
-bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
-  QUIC_BUG_IF(quic_bug_12714_7, !connected_)
-      << "Processing ACK frame end when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
-
-  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
-      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
-    return true;
-  }
-  const bool one_rtt_packet_was_acked =
-      sent_packet_manager_.one_rtt_packet_acked();
-  const bool zero_rtt_packet_was_acked =
-      sent_packet_manager_.zero_rtt_packet_acked();
-  const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
-      idle_network_detector_.time_of_last_received_packet(),
-      last_header_.packet_number, last_decrypted_packet_level_);
-  if (ack_result != PACKETS_NEWLY_ACKED &&
-      ack_result != NO_PACKETS_NEWLY_ACKED) {
-    // Error occurred (e.g., this ACK tries to ack packets in wrong packet
-    // number space), and this would cause the connection to be closed.
-    QUIC_DLOG(ERROR) << ENDPOINT
-                     << "Error occurred when processing an ACK frame: "
-                     << QuicUtils::AckResultToString(ack_result);
-    return false;
-  }
-  if (SupportsMultiplePacketNumberSpaces() && !one_rtt_packet_was_acked &&
-      sent_packet_manager_.one_rtt_packet_acked()) {
-    visitor_->OnOneRttPacketAcknowledged();
-  }
-  if (debug_visitor_ != nullptr && version().UsesTls() &&
-      !zero_rtt_packet_was_acked &&
-      sent_packet_manager_.zero_rtt_packet_acked()) {
-    debug_visitor_->OnZeroRttPacketAcked();
-  }
-  // Cancel the send alarm because new packets likely have been acked, which
-  // may change the congestion window and/or pacing rate.  Canceling the alarm
-  // causes CanWrite to recalculate the next send time.
-  if (send_alarm_->IsSet()) {
-    send_alarm_->Cancel();
-  }
-  if (supports_release_time_) {
-    // Update pace time into future because smoothed RTT is likely updated.
-    UpdateReleaseTimeIntoFuture();
-  }
-  SetLargestReceivedPacketWithAck(last_header_.packet_number);
-  // If the incoming ack's packets set expresses missing packets: peer is still
-  // waiting for a packet lower than a packet that we are no longer planning to
-  // send.
-  // If the incoming ack's packets set expresses received packets: peer is still
-  // acking packets which we never care about.
-  // Send an ack to raise the high water mark.
-  const bool send_stop_waiting =
-      no_stop_waiting_frames_ ? false : GetLeastUnacked() > start;
-  PostProcessAfterAckFrame(send_stop_waiting,
-                           ack_result == PACKETS_NEWLY_ACKED);
-  processing_ack_frame_ = false;
-  return connected_;
-}
-
-bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_8, !connected_)
-      << "Processing STOP_WAITING frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a stop waiting frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(STOP_WAITING_FRAME)) {
-    return false;
-  }
-
-  if (no_stop_waiting_frames_) {
-    return true;
-  }
-  if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
-      last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Received an old stop waiting frame: ignoring";
-    return true;
-  }
-
-  const char* error = ValidateStopWaitingFrame(frame);
-  if (error != nullptr) {
-    CloseConnection(QUIC_INVALID_STOP_WAITING_DATA, error,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnStopWaitingFrame(frame);
-  }
-
-  largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
-  uber_received_packet_manager_.DontWaitForPacketsBefore(
-      last_decrypted_packet_level_, frame.least_unacked);
-  return connected_;
-}
-
-bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_9, !connected_)
-      << "Processing PADDING frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(PADDING_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnPaddingFrame(frame);
-  }
-  return true;
-}
-
-bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_10, !connected_)
-      << "Processing PING frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(PING_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    QuicTime::Delta ping_received_delay = QuicTime::Delta::Zero();
-    const QuicTime now = clock_->ApproximateNow();
-    if (now > stats_.connection_creation_time) {
-      ping_received_delay = now - stats_.connection_creation_time;
-    }
-    debug_visitor_->OnPingFrame(frame, ping_received_delay);
-  }
-  MaybeUpdateAckTimeout();
-  return true;
-}
-
-const char* QuicConnection::ValidateStopWaitingFrame(
-    const QuicStopWaitingFrame& stop_waiting) {
-  const QuicPacketNumber peer_least_packet_awaiting_ack =
-      uber_received_packet_manager_.peer_least_packet_awaiting_ack();
-  if (peer_least_packet_awaiting_ack.IsInitialized() &&
-      stop_waiting.least_unacked < peer_least_packet_awaiting_ack) {
-    QUIC_DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
-                     << stop_waiting.least_unacked << " vs "
-                     << peer_least_packet_awaiting_ack;
-    // We never process old ack frames, so this number should only increase.
-    return "Least unacked too small.";
-  }
-
-  if (stop_waiting.least_unacked > last_header_.packet_number) {
-    QUIC_DLOG(ERROR) << ENDPOINT
-                     << "Peer sent least_unacked:" << stop_waiting.least_unacked
-                     << " greater than the enclosing packet number:"
-                     << last_header_.packet_number;
-    return "Least unacked too large.";
-  }
-
-  return nullptr;
-}
-
-bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_11, !connected_)
-      << "Processing RST_STREAM frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a reset stream frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(RST_STREAM_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnRstStreamFrame(frame);
-  }
-  QUIC_DLOG(INFO) << ENDPOINT
-                  << "RST_STREAM_FRAME received for stream: " << frame.stream_id
-                  << " with error: "
-                  << QuicRstStreamErrorCodeToString(frame.error_code);
-  MaybeUpdateAckTimeout();
-  visitor_->OnRstStream(frame);
-  return connected_;
-}
-
-bool QuicConnection::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_12, !connected_)
-      << "Processing STOP_SENDING frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a reset stream frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(STOP_SENDING_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnStopSendingFrame(frame);
-  }
-
-  QUIC_DLOG(INFO) << ENDPOINT << "STOP_SENDING frame received for stream: "
-                  << frame.stream_id
-                  << " with error: " << frame.ietf_error_code;
-  MaybeUpdateAckTimeout();
-  visitor_->OnStopSendingFrame(frame);
-  return connected_;
-}
-
-class ReversePathValidationContext : public QuicPathValidationContext {
- public:
-  ReversePathValidationContext(const QuicSocketAddress& self_address,
-                               const QuicSocketAddress& peer_address,
-                               const QuicSocketAddress& effective_peer_address,
-                               QuicConnection* connection)
-      : QuicPathValidationContext(self_address,
-                                  peer_address,
-                                  effective_peer_address),
-        connection_(connection) {}
-
-  QuicPacketWriter* WriterToUse() override { return connection_->writer(); }
-
- private:
-  QuicConnection* connection_;
-};
-
-bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_8, !connected_)
-      << "Processing PATH_CHALLENGE frame when connection "
-         "is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (has_path_challenge_in_current_packet_) {
-    // Only respond to the 1st PATH_CHALLENGE in the packet.
-    return true;
-  }
-  if (!validate_client_addresses_) {
-    return OnPathChallengeFrameInternal(frame);
-  }
-  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 1, 6);
-  {
-    // TODO(danzh) inline OnPathChallengeFrameInternal() once
-    // validate_client_addresses_ is deprecated.
-    if (!OnPathChallengeFrameInternal(frame)) {
-      return false;
-    }
-  }
-  return connected_;
-}
-
-bool QuicConnection::OnPathChallengeFrameInternal(
-    const QuicPathChallengeFrame& frame) {
-  should_proactively_validate_peer_address_on_path_challenge_ = false;
-  // UpdatePacketContent() may start reverse path validation.
-  if (!UpdatePacketContent(PATH_CHALLENGE_FRAME)) {
-    return false;
-  }
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnPathChallengeFrame(frame);
-  }
-
-  const QuicSocketAddress current_effective_peer_address =
-      GetEffectivePeerAddressFromCurrentPacket();
-  QuicConnectionId client_cid, server_cid;
-  FindOnPathConnectionIds(last_received_packet_info_.destination_address,
-                          current_effective_peer_address, &client_cid,
-                          &server_cid);
-  QuicPacketCreator::ScopedPeerAddressContext context(
-      &packet_creator_, last_received_packet_info_.source_address, client_cid,
-      server_cid, connection_migration_use_new_cid_);
-  if (should_proactively_validate_peer_address_on_path_challenge_) {
-    // Conditions to proactively validate peer address:
-    // The perspective is server
-    // The PATH_CHALLENGE is received on an unvalidated alternative path.
-    // The connection isn't validating migrated peer address, which is of
-    // higher prority.
-    QUIC_DVLOG(1) << "Proactively validate the effective peer address "
-                  << current_effective_peer_address;
-    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 2, 6);
-    ValidatePath(std::make_unique<ReversePathValidationContext>(
-                     default_path_.self_address,
-                     last_received_packet_info_.source_address,
-                     current_effective_peer_address, this),
-                 std::make_unique<ReversePathValidationResultDelegate>(
-                     this, peer_address()));
-  }
-  has_path_challenge_in_current_packet_ = true;
-  MaybeUpdateAckTimeout();
-  // Queue or send PATH_RESPONSE. Send PATH_RESPONSE to the source address of
-  // the current incoming packet, even if it's not the default path or the
-  // alternative path.
-  if (!SendPathResponse(frame.data_buffer,
-                        last_received_packet_info_.source_address,
-                        current_effective_peer_address)) {
-    QUIC_CODE_COUNT(quic_failed_to_send_path_response);
-  }
-  // TODO(b/150095588): change the stats to
-  // num_valid_path_challenge_received.
-  ++stats_.num_connectivity_probing_received;
-
-  // SendPathResponse() might cause connection to be closed.
-  return connected_;
-}
-
-bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_9, !connected_)
-      << "Processing PATH_RESPONSE frame when connection "
-         "is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(PATH_RESPONSE_FRAME)) {
-    return false;
-  }
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnPathResponseFrame(frame);
-  }
-  MaybeUpdateAckTimeout();
-  if (use_path_validator_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 1, 4);
-    path_validator_.OnPathResponse(
-        frame.data_buffer, last_received_packet_info_.destination_address);
-  } else {
-    if (!transmitted_connectivity_probe_payload_ ||
-        *transmitted_connectivity_probe_payload_ != frame.data_buffer) {
-      // Is not for the probe we sent, ignore it.
-      return true;
-    }
-    // Have received the matching PATH RESPONSE, saved payload no longer valid.
-    transmitted_connectivity_probe_payload_ = nullptr;
-  }
-  return connected_;
-}
-
-bool QuicConnection::OnConnectionCloseFrame(
-    const QuicConnectionCloseFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_10, !connected_)
-      << "Processing CONNECTION_CLOSE frame when "
-         "connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a connection close frame was received, this is not a connectivity
-  // probe. A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(CONNECTION_CLOSE_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnConnectionCloseFrame(frame);
-  }
-  switch (frame.close_type) {
-    case GOOGLE_QUIC_CONNECTION_CLOSE:
-      QUIC_DLOG(INFO) << ENDPOINT << "Received ConnectionClose for connection: "
-                      << connection_id() << ", with error: "
-                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
-                      << frame.error_details << ")";
-      break;
-    case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
-      QUIC_DLOG(INFO) << ENDPOINT
-                      << "Received Transport ConnectionClose for connection: "
-                      << connection_id() << ", with error: "
-                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
-                      << frame.error_details << ")"
-                      << ", transport error code: "
-                      << QuicIetfTransportErrorCodeString(
-                             static_cast<QuicIetfTransportErrorCodes>(
-                                 frame.wire_error_code))
-                      << ", error frame type: "
-                      << frame.transport_close_frame_type;
-      break;
-    case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
-      QUIC_DLOG(INFO) << ENDPOINT
-                      << "Received Application ConnectionClose for connection: "
-                      << connection_id() << ", with error: "
-                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
-                      << frame.error_details << ")"
-                      << ", application error code: " << frame.wire_error_code;
-      break;
-  }
-
-  if (frame.quic_error_code == QUIC_BAD_MULTIPATH_FLAG) {
-    QUIC_LOG_FIRST_N(ERROR, 10) << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
-                                << " last_received_header: " << last_header_
-                                << " encryption_level: " << encryption_level_;
-  }
-  TearDownLocalConnectionState(frame, ConnectionCloseSource::FROM_PEER);
-  return connected_;
-}
-
-bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_13, !connected_)
-      << "Processing MAX_STREAMS frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(MAX_STREAMS_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnMaxStreamsFrame(frame);
-  }
-  MaybeUpdateAckTimeout();
-  return visitor_->OnMaxStreamsFrame(frame) && connected_;
-}
-
-bool QuicConnection::OnStreamsBlockedFrame(
-    const QuicStreamsBlockedFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_11, !connected_)
-      << "Processing STREAMS_BLOCKED frame when "
-         "connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(STREAMS_BLOCKED_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnStreamsBlockedFrame(frame);
-  }
-  MaybeUpdateAckTimeout();
-  return visitor_->OnStreamsBlockedFrame(frame) && connected_;
-}
-
-bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_14, !connected_)
-      << "Processing GOAWAY frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a go away frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(GOAWAY_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnGoAwayFrame(frame);
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
-                  << frame.last_good_stream_id
-                  << " and error: " << QuicErrorCodeToString(frame.error_code)
-                  << " and reason: " << frame.reason_phrase;
-  MaybeUpdateAckTimeout();
-  visitor_->OnGoAway(frame);
-  return connected_;
-}
-
-bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_12, !connected_)
-      << "Processing WINDOW_UPDATE frame when connection "
-         "is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a window update frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(WINDOW_UPDATE_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnWindowUpdateFrame(
-        frame, idle_network_detector_.time_of_last_received_packet());
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "WINDOW_UPDATE_FRAME received " << frame;
-  MaybeUpdateAckTimeout();
-  visitor_->OnWindowUpdateFrame(frame);
-  return connected_;
-}
-
-void QuicConnection::OnClientConnectionIdAvailable() {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
-  if (!peer_issued_cid_manager_->HasUnusedConnectionId()) {
-    return;
-  }
-  if (default_path_.client_connection_id.IsEmpty()) {
-    // Count client connection ID patched onto the default path.
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 3,
-                                 6);
-    const QuicConnectionIdData* unused_cid_data =
-        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-    QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
-                  << unused_cid_data->connection_id << " to default path";
-    default_path_.client_connection_id = unused_cid_data->connection_id;
-    default_path_.stateless_reset_token =
-        unused_cid_data->stateless_reset_token;
-    QUICHE_DCHECK(!packet_creator_.HasPendingFrames());
-    QUICHE_DCHECK(packet_creator_.GetDestinationConnectionId().IsEmpty());
-    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
-    return;
-  }
-  if (alternative_path_.peer_address.IsInitialized() &&
-      alternative_path_.client_connection_id.IsEmpty()) {
-    // Count client connection ID patched onto the alternative path.
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 4,
-                                 6);
-    const QuicConnectionIdData* unused_cid_data =
-        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-    QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
-                  << unused_cid_data->connection_id << " to alternative path";
-    alternative_path_.client_connection_id = unused_cid_data->connection_id;
-    alternative_path_.stateless_reset_token =
-        unused_cid_data->stateless_reset_token;
-  }
-}
-
-bool QuicConnection::ShouldSetRetransmissionAlarmOnPacketSent(
-    bool in_flight, EncryptionLevel level) const {
-  QUICHE_DCHECK(!sent_packet_manager_.simplify_set_retransmission_alarm());
-  if (!retransmission_alarm_->IsSet()) {
-    return true;
-  }
-  if (!in_flight) {
-    return false;
-  }
-
-  if (!SupportsMultiplePacketNumberSpaces()) {
-    return true;
-  }
-  // Before handshake gets confirmed, do not re-arm PTO timer on application
-  // data. Think about this scenario: on the client side, the CHLO gets
-  // acknowledged and the SHLO is not received yet. The PTO alarm is set when
-  // the CHLO acknowledge is received (and there is no in flight INITIAL
-  // packet). Re-arming PTO alarm on 0-RTT packet would keep postponing the PTO
-  // alarm.
-  return IsHandshakeConfirmed() || level == ENCRYPTION_INITIAL ||
-         level == ENCRYPTION_HANDSHAKE;
-}
-
-bool QuicConnection::OnNewConnectionIdFrameInner(
-    const QuicNewConnectionIdFrame& frame) {
-  if (peer_issued_cid_manager_ == nullptr) {
-    CloseConnection(
-        IETF_QUIC_PROTOCOL_VIOLATION,
-        "Receives NEW_CONNECTION_ID while peer uses zero length connection ID",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  std::string error_detail;
-  QuicErrorCode error =
-      peer_issued_cid_manager_->OnNewConnectionIdFrame(frame, &error_detail);
-  if (error != QUIC_NO_ERROR) {
-    CloseConnection(error, error_detail,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  if (perspective_ == Perspective::IS_SERVER) {
-    OnClientConnectionIdAvailable();
-  }
-  MaybeUpdateAckTimeout();
-  return true;
-}
-
-bool QuicConnection::OnNewConnectionIdFrame(
-    const QuicNewConnectionIdFrame& frame) {
-  QUICHE_DCHECK(version().HasIetfQuicFrames());
-  QUIC_BUG_IF(quic_bug_10511_13, !connected_)
-      << "Processing NEW_CONNECTION_ID frame when "
-         "connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(NEW_CONNECTION_ID_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnNewConnectionIdFrame(frame);
-  }
-  return OnNewConnectionIdFrameInner(frame);
-}
-
-bool QuicConnection::OnRetireConnectionIdFrame(
-    const QuicRetireConnectionIdFrame& frame) {
-  QUICHE_DCHECK(version().HasIetfQuicFrames());
-  QUIC_BUG_IF(quic_bug_10511_14, !connected_)
-      << "Processing RETIRE_CONNECTION_ID frame when "
-         "connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnRetireConnectionIdFrame(frame);
-  }
-  if (!connection_migration_use_new_cid_) {
-    // Do not respond to RetireConnectionId frame.
-    return true;
-  }
-  if (self_issued_cid_manager_ == nullptr) {
-    CloseConnection(
-        IETF_QUIC_PROTOCOL_VIOLATION,
-        "Receives RETIRE_CONNECTION_ID while new connection ID is never issued",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  std::string error_detail;
-  QuicErrorCode error = self_issued_cid_manager_->OnRetireConnectionIdFrame(
-      frame, sent_packet_manager_.GetPtoDelay(), &error_detail);
-  if (error != QUIC_NO_ERROR) {
-    CloseConnection(error, error_detail,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  // Count successfully received RETIRE_CONNECTION_ID frames.
-  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 5, 6);
-  MaybeUpdateAckTimeout();
-  return true;
-}
-
-bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_15, !connected_)
-      << "Processing NEW_TOKEN frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!UpdatePacketContent(NEW_TOKEN_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnNewTokenFrame(frame);
-  }
-  if (perspective_ == Perspective::IS_SERVER) {
-    CloseConnection(QUIC_INVALID_NEW_TOKEN, "Server received new token frame.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  // NEW_TOKEN frame should insitgate ACKs.
-  MaybeUpdateAckTimeout();
-  visitor_->OnNewTokenReceived(frame.token);
-  return true;
-}
-
-bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_16, !connected_)
-      << "Processing MESSAGE frame when connection is closed. Last frame: "
-      << most_recent_frame_type_;
-
-  // Since a message frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(MESSAGE_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnMessageFrame(frame);
-  }
-  MaybeUpdateAckTimeout();
-  visitor_->OnMessageReceived(
-      absl::string_view(frame.data, frame.message_length));
-  return connected_;
-}
-
-bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_15, !connected_)
-      << "Processing HANDSHAKE_DONE frame when connection "
-         "is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (!version().UsesTls()) {
-    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
-                    "Handshake done frame is unsupported",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  if (perspective_ == Perspective::IS_SERVER) {
-    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
-                    "Server received handshake done frame.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-
-  // Since a handshake done frame was received, this is not a connectivity
-  // probe. A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(HANDSHAKE_DONE_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnHandshakeDoneFrame(frame);
-  }
-  MaybeUpdateAckTimeout();
-  visitor_->OnHandshakeDoneReceived();
-  return connected_;
-}
-
-bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) {
-  QUIC_BUG_IF(quic_bug_10511_16, !connected_)
-      << "Processing ACK_FREQUENCY frame when connection "
-         "is closed. Last frame: "
-      << most_recent_frame_type_;
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnAckFrequencyFrame(frame);
-  }
-  if (!UpdatePacketContent(ACK_FREQUENCY_FRAME)) {
-    return false;
-  }
-
-  if (!can_receive_ack_frequency_frame_) {
-    QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame.";
-    return false;
-  }
-  if (auto packet_number_space =
-          QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_) ==
-          APPLICATION_DATA) {
-    uber_received_packet_manager_.OnAckFrequencyFrame(frame);
-  } else {
-    QUIC_LOG_EVERY_N_SEC(ERROR, 120)
-        << "Get AckFrequencyFrame in packet number space "
-        << packet_number_space;
-  }
-  MaybeUpdateAckTimeout();
-  return true;
-}
-
-bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12714_17, !connected_)
-      << "Processing BLOCKED frame when connection is closed. Last frame was "
-      << most_recent_frame_type_;
-
-  // Since a blocked frame was received, this is not a connectivity probe.
-  // A probe only contains a PING and full padding.
-  if (!UpdatePacketContent(BLOCKED_FRAME)) {
-    return false;
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnBlockedFrame(frame);
-  }
-  QUIC_DLOG(INFO) << ENDPOINT
-                  << "BLOCKED_FRAME received for stream: " << frame.stream_id;
-  MaybeUpdateAckTimeout();
-  visitor_->OnBlockedFrame(frame);
-  stats_.blocked_frames_received++;
-  return connected_;
-}
-
-void QuicConnection::OnPacketComplete() {
-  // Don't do anything if this packet closed the connection.
-  if (!connected_) {
-    ClearLastFrames();
-    return;
-  }
-
-  if (IsCurrentPacketConnectivityProbing()) {
-    QUICHE_DCHECK(!version().HasIetfQuicFrames());
-    ++stats_.num_connectivity_probing_received;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "Got"
-                << (SupportsMultiplePacketNumberSpaces()
-                        ? (" " + EncryptionLevelToString(
-                                     last_decrypted_packet_level_))
-                        : "")
-                << " packet " << last_header_.packet_number << " for "
-                << GetServerConnectionIdAsRecipient(last_header_, perspective_);
-
-  QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
-      << ENDPOINT << "Received a padded PING packet. is_probing: "
-      << IsCurrentPacketConnectivityProbing();
-
-  if (!version().HasIetfQuicFrames()) {
-    MaybeRespondToConnectivityProbingOrMigration();
-  }
-
-  current_effective_peer_migration_type_ = NO_CHANGE;
-
-  // For IETF QUIC, it is guaranteed that TLS will give connection the
-  // corresponding write key before read key. In other words, connection should
-  // never process a packet while an ACK for it cannot be encrypted.
-  if (!should_last_packet_instigate_acks_) {
-    uber_received_packet_manager_.MaybeUpdateAckTimeout(
-        should_last_packet_instigate_acks_, last_decrypted_packet_level_,
-        last_header_.packet_number, last_received_packet_info_.receipt_time,
-        clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
-  }
-
-  ClearLastFrames();
-  CloseIfTooManyOutstandingSentPackets();
-}
-
-void QuicConnection::MaybeRespondToConnectivityProbingOrMigration() {
-  QUICHE_DCHECK(!version().HasIetfQuicFrames());
-  if (IsCurrentPacketConnectivityProbing()) {
-    visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
-                               last_received_packet_info_.source_address,
-                               /*is_connectivity_probe=*/true);
-    return;
-  }
-  if (perspective_ == Perspective::IS_CLIENT) {
-    // This node is a client, notify that a speculative connectivity probing
-    // packet has been received anyway.
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Received a speculative connectivity probing packet for "
-                  << GetServerConnectionIdAsRecipient(last_header_,
-                                                      perspective_)
-                  << " from ip:port: "
-                  << last_received_packet_info_.source_address.ToString()
-                  << " to ip:port: "
-                  << last_received_packet_info_.destination_address.ToString();
-    visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
-                               last_received_packet_info_.source_address,
-                               /*is_connectivity_probe=*/false);
-    return;
-  }
-}
-
-bool QuicConnection::IsValidStatelessResetToken(
-    const StatelessResetToken& token) const {
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  return default_path_.stateless_reset_token.has_value() &&
-         QuicUtils::AreStatelessResetTokensEqual(
-             token, *default_path_.stateless_reset_token);
-}
-
-void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
-    const QuicIetfStatelessResetPacket& /*packet*/) {
-  // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
-  // debug_visitor_.
-  QUICHE_DCHECK(version().HasIetfInvariantHeader());
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-
-  if (use_path_validator_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 4, 4);
-    if (!IsDefaultPath(last_received_packet_info_.destination_address,
-                       last_received_packet_info_.source_address)) {
-      // This packet is received on a probing path. Do not close connection.
-      if (IsAlternativePath(last_received_packet_info_.destination_address,
-                            GetEffectivePeerAddressFromCurrentPacket())) {
-        QUIC_BUG_IF(quic_bug_12714_18, alternative_path_.validated)
-            << "STATELESS_RESET received on alternate path after it's "
-               "validated.";
-        path_validator_.CancelPathValidation();
-      } else {
-        QUIC_BUG(quic_bug_10511_17)
-            << "Received Stateless Reset on unknown socket.";
-      }
-      return;
-    }
-  } else if (!visitor_->ValidateStatelessReset(
-                 last_received_packet_info_.destination_address,
-                 last_received_packet_info_.source_address)) {
-    // This packet is received on a probing path. Do not close connection.
-    return;
-  }
-
-  const std::string error_details = "Received stateless reset.";
-  QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
-  TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
-                               error_details, ConnectionCloseSource::FROM_PEER);
-}
-
-void QuicConnection::OnKeyUpdate(KeyUpdateReason reason) {
-  QUICHE_DCHECK(support_key_update_for_connection_);
-  QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated for " << reason;
-
-  lowest_packet_sent_in_current_key_phase_.Clear();
-  stats_.key_update_count++;
-
-  // If another key update triggers while the previous
-  // discard_previous_one_rtt_keys_alarm_ hasn't fired yet, cancel it since the
-  // old keys would already be discarded.
-  discard_previous_one_rtt_keys_alarm_->Cancel();
-
-  visitor_->OnKeyUpdate(reason);
-}
-
-void QuicConnection::OnDecryptedFirstPacketInKeyPhase() {
-  QUIC_DLOG(INFO) << ENDPOINT << "OnDecryptedFirstPacketInKeyPhase";
-  // An endpoint SHOULD retain old read keys for no more than three times the
-  // PTO after having received a packet protected using the new keys. After this
-  // period, old read keys and their corresponding secrets SHOULD be discarded.
-  //
-  // Note that this will cause an unnecessary
-  // discard_previous_one_rtt_keys_alarm_ on the first packet in the 1RTT
-  // encryption level, but this is harmless.
-  discard_previous_one_rtt_keys_alarm_->Set(
-      clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicConnection::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  QUIC_DLOG(INFO) << ENDPOINT << "AdvanceKeysAndCreateCurrentOneRttDecrypter";
-  return visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter> QuicConnection::CreateCurrentOneRttEncrypter() {
-  QUIC_DLOG(INFO) << ENDPOINT << "CreateCurrentOneRttEncrypter";
-  return visitor_->CreateCurrentOneRttEncrypter();
-}
-
-void QuicConnection::ClearLastFrames() {
-  should_last_packet_instigate_acks_ = false;
-}
-
-void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
-  // This occurs if we don't discard old packets we've seen fast enough. It's
-  // possible largest observed is less than leaset unacked.
-  const bool should_close =
-      sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
-      sent_packet_manager_.GetLargestSentPacket() >
-          sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_;
-
-  if (should_close) {
-    CloseConnection(
-        QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
-        absl::StrCat("More than ", max_tracked_packets_,
-                     " outstanding, least_unacked: ",
-                     sent_packet_manager_.GetLeastUnacked().ToUint64(),
-                     ", packets_processed: ", stats_.packets_processed,
-                     ", last_decrypted_packet_level: ",
-                     EncryptionLevelToString(last_decrypted_packet_level_)),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  }
-}
-
-const QuicFrame QuicConnection::GetUpdatedAckFrame() {
-  QUICHE_DCHECK(!uber_received_packet_manager_.IsAckFrameEmpty(
-      QuicUtils::GetPacketNumberSpace(encryption_level_)))
-      << "Try to retrieve an empty ACK frame";
-  return uber_received_packet_manager_.GetUpdatedAckFrame(
-      QuicUtils::GetPacketNumberSpace(encryption_level_),
-      clock_->ApproximateNow());
-}
-
-void QuicConnection::PopulateStopWaitingFrame(
-    QuicStopWaitingFrame* stop_waiting) {
-  stop_waiting->least_unacked = GetLeastUnacked();
-}
-
-QuicPacketNumber QuicConnection::GetLeastUnacked() const {
-  return sent_packet_manager_.GetLeastUnacked();
-}
-
-bool QuicConnection::HandleWriteBlocked() {
-  if (!writer_->IsWriteBlocked()) {
-    return false;
-  }
-
-  visitor_->OnWriteBlocked();
-  return true;
-}
-
-void QuicConnection::MaybeSendInResponseToPacket() {
-  if (!connected_) {
-    return;
-  }
-
-  // If the writer is blocked, don't attempt to send packets now or in the send
-  // alarm. When the writer unblocks, OnCanWrite() will be called for this
-  // connection to send.
-  if (HandleWriteBlocked()) {
-    return;
-  }
-
-  // Now that we have received an ack, we might be able to send packets which
-  // are queued locally, or drain streams which are blocked.
-  if (defer_send_in_response_to_packets_) {
-    send_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
-  } else {
-    WriteIfNotBlocked();
-  }
-}
-
-void QuicConnection::MaybeActivateLegacyVersionEncapsulation() {
-  if (!legacy_version_encapsulation_enabled_) {
-    return;
-  }
-  QUICHE_DCHECK(!legacy_version_encapsulation_in_progress_);
-  QUIC_BUG_IF(quic_bug_12714_19, !packet_creator_.CanSetMaxPacketLength())
-      << "Cannot activate Legacy Version Encapsulation mid-packet";
-  QUIC_BUG_IF(quic_bug_12714_20, coalesced_packet_.length() != 0u)
-      << "Cannot activate Legacy Version Encapsulation mid-coalesced-packet";
-  legacy_version_encapsulation_in_progress_ = true;
-  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-void QuicConnection::MaybeDisactivateLegacyVersionEncapsulation() {
-  if (!legacy_version_encapsulation_in_progress_) {
-    return;
-  }
-  // Flush any remaining packet before disactivating encapsulation.
-  packet_creator_.FlushCurrentPacket();
-  QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
-  legacy_version_encapsulation_in_progress_ = false;
-  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-
-size_t QuicConnection::SendCryptoData(EncryptionLevel level,
-                                      size_t write_length,
-                                      QuicStreamOffset offset) {
-  if (write_length == 0) {
-    QUIC_BUG(quic_bug_10511_18) << "Attempt to send empty crypto frame";
-    return 0;
-  }
-  if (level == ENCRYPTION_INITIAL) {
-    MaybeActivateLegacyVersionEncapsulation();
-  }
-  size_t consumed_length;
-  {
-    ScopedPacketFlusher flusher(this);
-    consumed_length =
-        packet_creator_.ConsumeCryptoData(level, write_length, offset);
-  }  // Added scope ensures packets are flushed before continuing.
-  MaybeDisactivateLegacyVersionEncapsulation();
-  return consumed_length;
-}
-
-QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
-                                                size_t write_length,
-                                                QuicStreamOffset offset,
-                                                StreamSendingState state) {
-  if (state == NO_FIN && write_length == 0) {
-    QUIC_BUG(quic_bug_10511_19) << "Attempt to send empty stream frame";
-    return QuicConsumedData(0, false);
-  }
-
-  if (packet_creator_.encryption_level() == ENCRYPTION_INITIAL &&
-      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
-    MaybeActivateLegacyVersionEncapsulation();
-  }
-  if (perspective_ == Perspective::IS_SERVER &&
-      version().CanSendCoalescedPackets() && !IsHandshakeConfirmed()) {
-    if (in_on_retransmission_time_out_ &&
-        coalesced_packet_.NumberOfPackets() == 0u) {
-      // PTO fires while handshake is not confirmed. Do not preempt handshake
-      // data with stream data.
-      QUIC_CODE_COUNT(quic_try_to_send_half_rtt_data_when_pto_fires);
-      return QuicConsumedData(0, false);
-    }
-    if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
-        coalesced_packet_.NumberOfPackets() == 1u) {
-      // Handshake is not confirmed yet, if there is only an initial packet in
-      // the coalescer, try to bundle an ENCRYPTION_HANDSHAKE packet before
-      // sending stream data.
-      sent_packet_manager_.RetransmitDataOfSpaceIfAny(HANDSHAKE_DATA);
-    }
-  }
-  QuicConsumedData consumed_data(0, false);
-  {
-    // Opportunistically bundle an ack with every outgoing packet.
-    // Particularly, we want to bundle with handshake packets since we don't
-    // know which decrypter will be used on an ack packet following a handshake
-    // packet (a handshake packet from client to server could result in a REJ or
-    // a SHLO from the server, leading to two different decrypters at the
-    // server.)
-    ScopedPacketFlusher flusher(this);
-    consumed_data =
-        packet_creator_.ConsumeData(id, write_length, offset, state);
-  }  // Added scope ensures packets are flushed before continuing.
-  MaybeDisactivateLegacyVersionEncapsulation();
-  return consumed_data;
-}
-
-bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
-  if (SupportsMultiplePacketNumberSpaces() &&
-      (encryption_level_ == ENCRYPTION_INITIAL ||
-       encryption_level_ == ENCRYPTION_HANDSHAKE) &&
-      frame.type != PING_FRAME) {
-    // Allow PING frame to be sent without APPLICATION key. For example, when
-    // anti-amplification limit is used, client needs to send something to avoid
-    // handshake deadlock.
-    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame
-                  << " at encryption level: " << encryption_level_;
-    return false;
-  }
-  ScopedPacketFlusher flusher(this);
-  const bool consumed =
-      packet_creator_.ConsumeRetransmittableControlFrame(frame);
-  if (!consumed) {
-    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
-    return false;
-  }
-  if (frame.type == PING_FRAME) {
-    // Flush PING frame immediately.
-    packet_creator_.FlushCurrentPacket();
-    stats_.ping_frames_sent++;
-    if (debug_visitor_ != nullptr) {
-      debug_visitor_->OnPingSent();
-    }
-  }
-  if (frame.type == BLOCKED_FRAME) {
-    stats_.blocked_frames_sent++;
-  }
-  return true;
-}
-
-void QuicConnection::OnStreamReset(QuicStreamId id,
-                                   QuicRstStreamErrorCode error) {
-  if (error == QUIC_STREAM_NO_ERROR) {
-    // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
-    // be received by the peer.
-    return;
-  }
-  // Flush stream frames of reset stream.
-  if (packet_creator_.HasPendingStreamFramesOfStream(id)) {
-    ScopedPacketFlusher flusher(this);
-    packet_creator_.FlushCurrentPacket();
-  }
-  // TODO(ianswett): Consider checking for 3 RTOs when the last stream is
-  // cancelled as well.
-}
-
-const QuicConnectionStats& QuicConnection::GetStats() {
-  const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
-
-  // Update rtt and estimated bandwidth.
-  QuicTime::Delta min_rtt = rtt_stats->min_rtt();
-  if (min_rtt.IsZero()) {
-    // If min RTT has not been set, use initial RTT instead.
-    min_rtt = rtt_stats->initial_rtt();
-  }
-  stats_.min_rtt_us = min_rtt.ToMicroseconds();
-
-  QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt();
-  stats_.srtt_us = srtt.ToMicroseconds();
-
-  stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
-  sent_packet_manager_.GetSendAlgorithm()->PopulateConnectionStats(&stats_);
-  stats_.egress_mtu = long_term_mtu_;
-  stats_.ingress_mtu = largest_received_packet_size_;
-  return stats_;
-}
-
-void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
-  QueueCoalescedPacket(packet);
-}
-
-void QuicConnection::OnUndecryptablePacket(const QuicEncryptedPacket& packet,
-                                           EncryptionLevel decryption_level,
-                                           bool has_decryption_key) {
-  QUIC_DVLOG(1) << ENDPOINT << "Received undecryptable packet of length "
-                << packet.length() << " with"
-                << (has_decryption_key ? "" : "out") << " key at level "
-                << decryption_level
-                << " while connection is at encryption level "
-                << encryption_level_;
-  QUICHE_DCHECK(EncryptionLevelIsValid(decryption_level));
-  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
-    ++stats_.undecryptable_packets_received_before_handshake_complete;
-  }
-
-  const bool should_enqueue =
-      ShouldEnqueueUnDecryptablePacket(decryption_level, has_decryption_key);
-  if (should_enqueue) {
-    QueueUndecryptablePacket(packet, decryption_level);
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnUndecryptablePacket(decryption_level,
-                                          /*dropped=*/!should_enqueue);
-  }
-
-  if (has_decryption_key) {
-    stats_.num_failed_authentication_packets_received++;
-    if (version().UsesTls()) {
-      // Should always be non-null if has_decryption_key is true.
-      QUICHE_DCHECK(framer_.GetDecrypter(decryption_level));
-      const QuicPacketCount integrity_limit =
-          framer_.GetDecrypter(decryption_level)->GetIntegrityLimit();
-      QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD integrity limits:"
-                    << " num_failed_authentication_packets_received="
-                    << stats_.num_failed_authentication_packets_received
-                    << " integrity_limit=" << integrity_limit;
-      if (stats_.num_failed_authentication_packets_received >=
-          integrity_limit) {
-        const std::string error_details = absl::StrCat(
-            "decrypter integrity limit reached:"
-            " num_failed_authentication_packets_received=",
-            stats_.num_failed_authentication_packets_received,
-            " integrity_limit=", integrity_limit);
-        CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
-                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      }
-    }
-  }
-
-  if (version().UsesTls() && perspective_ == Perspective::IS_SERVER &&
-      decryption_level == ENCRYPTION_ZERO_RTT && !has_decryption_key &&
-      had_zero_rtt_decrypter_) {
-    QUIC_CODE_COUNT_N(
-        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 1,
-        3);
-    stats_
-        .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter++;
-  }
-}
-
-bool QuicConnection::ShouldEnqueueUnDecryptablePacket(
-    EncryptionLevel decryption_level, bool has_decryption_key) const {
-  if (has_decryption_key) {
-    // We already have the key for this decryption level, therefore no
-    // future keys will allow it be decrypted.
-    return false;
-  }
-  if (IsHandshakeComplete()) {
-    // We do not expect to install any further keys.
-    return false;
-  }
-  if (undecryptable_packets_.size() >= max_undecryptable_packets_) {
-    // We do not queue more than max_undecryptable_packets_ packets.
-    return false;
-  }
-  if (version().KnowsWhichDecrypterToUse() &&
-      decryption_level == ENCRYPTION_INITIAL) {
-    // When the corresponding decryption key is not available, all
-    // non-Initial packets should be buffered until the handshake is complete.
-    return false;
-  }
-  if (perspective_ == Perspective::IS_CLIENT && version().UsesTls() &&
-      decryption_level == ENCRYPTION_ZERO_RTT) {
-    // Only clients send Zero RTT packets in IETF QUIC.
-    QUIC_PEER_BUG(quic_peer_bug_client_received_zero_rtt)
-        << "Client received a Zero RTT packet, not buffering.";
-    return false;
-  }
-  return true;
-}
-
-std::string QuicConnection::UndecryptablePacketsInfo() const {
-  std::string info = absl::StrCat(
-      "num_undecryptable_packets: ", undecryptable_packets_.size(), " {");
-  for (const auto& packet : undecryptable_packets_) {
-    absl::StrAppend(&info, "[",
-                    EncryptionLevelToString(packet.encryption_level), ", ",
-                    packet.packet->length(), "]");
-  }
-  absl::StrAppend(&info, "}");
-  return info;
-}
-
-void QuicConnection::MaybeUpdatePacketCreatorMaxPacketLengthAndPadding() {
-  QuicByteCount max_packet_length = GetLimitedMaxPacketSize(long_term_mtu_);
-  if (legacy_version_encapsulation_in_progress_) {
-    QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
-    const QuicByteCount minimum_overhead =
-        QuicLegacyVersionEncapsulator::GetMinimumOverhead(
-            legacy_version_encapsulation_sni_);
-    if (max_packet_length < minimum_overhead) {
-      QUIC_BUG(quic_bug_10511_20)
-          << "Cannot apply Legacy Version Encapsulation overhead because "
-          << "max_packet_length " << max_packet_length << " < minimum_overhead "
-          << minimum_overhead;
-      legacy_version_encapsulation_in_progress_ = false;
-      legacy_version_encapsulation_enabled_ = false;
-      MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-      return;
-    }
-    max_packet_length -= minimum_overhead;
-  }
-  packet_creator_.SetMaxPacketLength(max_packet_length);
-}
-
-void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
-                                      const QuicSocketAddress& peer_address,
-                                      const QuicReceivedPacket& packet) {
-  if (!connected_) {
-    return;
-  }
-  QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length()
-                << " bytes:" << std::endl
-                << quiche::QuicheTextUtils::HexDump(
-                       absl::string_view(packet.data(), packet.length()));
-  QUIC_BUG_IF(quic_bug_12714_21, current_packet_data_ != nullptr)
-      << "ProcessUdpPacket must not be called while processing a packet.";
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
-  }
-  last_received_packet_info_ =
-      ReceivedPacketInfo(self_address, peer_address, packet.receipt_time());
-  last_size_ = packet.length();
-  current_packet_data_ = packet.data();
-
-  if (!default_path_.self_address.IsInitialized()) {
-    default_path_.self_address = last_received_packet_info_.destination_address;
-  }
-
-  if (!direct_peer_address_.IsInitialized()) {
-    UpdatePeerAddress(last_received_packet_info_.source_address);
-  }
-
-  if (!default_path_.peer_address.IsInitialized()) {
-    const QuicSocketAddress effective_peer_addr =
-        GetEffectivePeerAddressFromCurrentPacket();
-
-    // The default path peer_address must be initialized at the beginning of the
-    // first packet processed(here). If effective_peer_addr is uninitialized,
-    // just set effective_peer_address_ to the direct peer address.
-    default_path_.peer_address = effective_peer_addr.IsInitialized()
-                                     ? effective_peer_addr
-                                     : direct_peer_address_;
-  }
-
-  stats_.bytes_received += packet.length();
-  ++stats_.packets_received;
-  if (!count_bytes_on_alternative_path_separately_) {
-    if (EnforceAntiAmplificationLimit()) {
-      default_path_.bytes_received_before_address_validation += last_size_;
-    }
-  } else if (IsDefaultPath(last_received_packet_info_.destination_address,
-                           last_received_packet_info_.source_address) &&
-             EnforceAntiAmplificationLimit()) {
-    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 1, 5);
-    last_received_packet_info_.received_bytes_counted = true;
-    default_path_.bytes_received_before_address_validation += last_size_;
-  }
-
-  // Ensure the time coming from the packet reader is within 2 minutes of now.
-  if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
-      2 * 60) {
-    QUIC_BUG(quic_bug_10511_21)
-        << "Packet receipt time:" << packet.receipt_time().ToDebuggingValue()
-        << " too far from current time:"
-        << clock_->ApproximateNow().ToDebuggingValue();
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
-                << packet.receipt_time().ToDebuggingValue() << " from peer "
-                << last_received_packet_info_.source_address;
-
-  ScopedPacketFlusher flusher(this);
-  if (!framer_.ProcessPacket(packet)) {
-    // If we are unable to decrypt this packet, it might be
-    // because the CHLO or SHLO packet was lost.
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Unable to process packet.  Last packet processed: "
-                  << last_header_.packet_number;
-    current_packet_data_ = nullptr;
-    is_current_packet_connectivity_probing_ = false;
-
-    MaybeProcessCoalescedPackets();
-    return;
-  }
-
-  ++stats_.packets_processed;
-
-  QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
-      << "sent_packet_manager_.GetLargestObserved() = "
-      << sent_packet_manager_.GetLargestObserved()
-      << ", highest_packet_sent_before_effective_peer_migration_ = "
-      << highest_packet_sent_before_effective_peer_migration_;
-  if (!validate_client_addresses_ &&
-      active_effective_peer_migration_type_ != NO_CHANGE &&
-      sent_packet_manager_.GetLargestObserved().IsInitialized() &&
-      (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
-       sent_packet_manager_.GetLargestObserved() >
-           highest_packet_sent_before_effective_peer_migration_)) {
-    if (perspective_ == Perspective::IS_SERVER) {
-      OnEffectivePeerMigrationValidated();
-    }
-  }
-
-  if (!MaybeProcessCoalescedPackets()) {
-    MaybeProcessUndecryptablePackets();
-    MaybeSendInResponseToPacket();
-  }
-  SetPingAlarm();
-  RetirePeerIssuedConnectionIdsNoLongerOnPath();
-  current_packet_data_ = nullptr;
-  is_current_packet_connectivity_probing_ = false;
-}
-
-void QuicConnection::OnBlockedWriterCanWrite() {
-  writer_->SetWritable();
-  OnCanWrite();
-}
-
-void QuicConnection::OnCanWrite() {
-  if (!connected_) {
-    return;
-  }
-  if (writer_->IsWriteBlocked()) {
-    const std::string error_details =
-        "Writer is blocked while calling OnCanWrite.";
-    QUIC_BUG(quic_bug_10511_22) << ENDPOINT << error_details;
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  ScopedPacketFlusher flusher(this);
-
-  WriteQueuedPackets();
-  const QuicTime ack_timeout =
-      uber_received_packet_manager_.GetEarliestAckTimeout();
-  if (ack_timeout.IsInitialized() && ack_timeout <= clock_->ApproximateNow()) {
-    // Send an ACK now because either 1) we were write blocked when we last
-    // tried to send an ACK, or 2) both ack alarm and send alarm were set to
-    // go off together.
-    if (SupportsMultiplePacketNumberSpaces()) {
-      SendAllPendingAcks();
-    } else {
-      SendAck();
-    }
-  }
-
-  // Sending queued packets may have caused the socket to become write blocked,
-  // or the congestion manager to prohibit sending.
-  if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
-    return;
-  }
-
-  // Tell the session it can write.
-  visitor_->OnCanWrite();
-
-  // After the visitor writes, it may have caused the socket to become write
-  // blocked or the congestion manager to prohibit sending, so check again.
-  if (visitor_->WillingAndAbleToWrite() && !send_alarm_->IsSet() &&
-      CanWrite(HAS_RETRANSMITTABLE_DATA)) {
-    // We're not write blocked, but some data wasn't written. Register for
-    // 'immediate' resumption so we'll keep writing after other connections.
-    send_alarm_->Set(clock_->ApproximateNow());
-  }
-}
-
-void QuicConnection::WriteIfNotBlocked() {
-  if (framer().is_processing_packet()) {
-    QUIC_BUG(connection_write_mid_packet_processing)
-        << ENDPOINT << "Tried to write in mid of packet processing";
-    return;
-  }
-  if (!HandleWriteBlocked()) {
-    OnCanWrite();
-  }
-}
-
-void QuicConnection::MaybeClearQueuedPacketsOnPathChange() {
-  if (connection_migration_use_new_cid_ &&
-      peer_issued_cid_manager_ != nullptr && HasQueuedPackets()) {
-    // Discard packets serialized with the connection ID on the old code path.
-    // It is possible to clear queued packets only if connection ID changes.
-    // However, the case where connection ID is unchanged and queued packets are
-    // non-empty is quite rare.
-    ClearQueuedPackets();
-  }
-}
-
-void QuicConnection::ReplaceInitialServerConnectionId(
-    const QuicConnectionId& new_server_connection_id) {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
-  if (version().HasIetfQuicFrames()) {
-    if (new_server_connection_id.IsEmpty()) {
-      peer_issued_cid_manager_ = nullptr;
-    } else {
-      if (peer_issued_cid_manager_ != nullptr) {
-        QUIC_BUG_IF(quic_bug_12714_22,
-                    !peer_issued_cid_manager_->IsConnectionIdActive(
-                        default_path_.server_connection_id))
-            << "Connection ID replaced header is no longer active. old id: "
-            << default_path_.server_connection_id
-            << " new_id: " << new_server_connection_id;
-        peer_issued_cid_manager_->ReplaceConnectionId(
-            default_path_.server_connection_id, new_server_connection_id);
-      } else {
-        peer_issued_cid_manager_ =
-            std::make_unique<QuicPeerIssuedConnectionIdManager>(
-                kMinNumOfActiveConnectionIds, new_server_connection_id, clock_,
-                alarm_factory_, this, context());
-      }
-    }
-  }
-  default_path_.server_connection_id = new_server_connection_id;
-  packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
-}
-
-void QuicConnection::FindMatchingOrNewClientConnectionIdOrToken(
-    const PathState& default_path, const PathState& alternative_path,
-    const QuicConnectionId& server_connection_id,
-    QuicConnectionId* client_connection_id,
-    absl::optional<StatelessResetToken>* stateless_reset_token) {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
-  if (peer_issued_cid_manager_ == nullptr ||
-      server_connection_id == default_path.server_connection_id) {
-    *client_connection_id = default_path.client_connection_id;
-    *stateless_reset_token = default_path.stateless_reset_token;
-    return;
-  }
-  if (server_connection_id == alternative_path_.server_connection_id) {
-    *client_connection_id = alternative_path.client_connection_id;
-    *stateless_reset_token = alternative_path.stateless_reset_token;
-    return;
-  }
-  if (!connection_migration_use_new_cid_) {
-    QUIC_BUG(quic_bug_46004) << "Cannot find matching connection ID.";
-    return;
-  }
-  auto* connection_id_data =
-      peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-  if (connection_id_data == nullptr) {
-    return;
-  }
-  *client_connection_id = connection_id_data->connection_id;
-  *stateless_reset_token = connection_id_data->stateless_reset_token;
-}
-
-bool QuicConnection::FindOnPathConnectionIds(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    QuicConnectionId* client_connection_id,
-    QuicConnectionId* server_connection_id) const {
-  if (IsDefaultPath(self_address, peer_address)) {
-    *client_connection_id = default_path_.client_connection_id,
-    *server_connection_id = default_path_.server_connection_id;
-    return true;
-  }
-  if (IsAlternativePath(self_address, peer_address)) {
-    *client_connection_id = alternative_path_.client_connection_id,
-    *server_connection_id = alternative_path_.server_connection_id;
-    return true;
-  }
-  return false;
-}
-
-void QuicConnection::SetDefaultPathState(PathState new_path_state) {
-  default_path_ = std::move(new_path_state);
-  if (connection_migration_use_new_cid_) {
-    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
-    packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
-  }
-}
-
-bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
-  if (perspective_ == Perspective::IS_CLIENT && version().HasIetfQuicFrames() &&
-      direct_peer_address_.IsInitialized() &&
-      last_received_packet_info_.source_address.IsInitialized() &&
-      direct_peer_address_ != last_received_packet_info_.source_address &&
-      !visitor_->IsKnownServerAddress(
-          last_received_packet_info_.source_address)) {
-    // TODO(haoyuewang) Revisit this when preferred_address transport parameter
-    // is used on the client side.
-    // Discard packets received from unseen server addresses.
-    return false;
-  }
-
-  if (perspective_ == Perspective::IS_SERVER &&
-      default_path_.self_address.IsInitialized() &&
-      last_received_packet_info_.destination_address.IsInitialized() &&
-      default_path_.self_address !=
-          last_received_packet_info_.destination_address) {
-    // Allow change between pure IPv4 and equivalent mapped IPv4 address.
-    if (default_path_.self_address.port() !=
-            last_received_packet_info_.destination_address.port() ||
-        default_path_.self_address.host().Normalized() !=
-            last_received_packet_info_.destination_address.host()
-                .Normalized()) {
-      if (!visitor_->AllowSelfAddressChange()) {
-        const std::string error_details = absl::StrCat(
-            "Self address migration is not supported at the server, current "
-            "address: ",
-            default_path_.self_address.ToString(),
-            ", received packet address: ",
-            last_received_packet_info_.destination_address.ToString(),
-            ", size: ", last_size_,
-            ", packet number: ", header.packet_number.ToString(),
-            ", encryption level: ",
-            EncryptionLevelToString(last_decrypted_packet_level_));
-        if (GetQuicReloadableFlag(
-                quic_drop_packets_with_changed_server_address)) {
-          QUIC_LOG_EVERY_N_SEC(INFO, 100) << error_details;
-          QUIC_CODE_COUNT(quic_dropped_packets_with_changed_server_address);
-          return false;
-        }
-        QUIC_PEER_BUG(Server self address change) << error_details;
-        CloseConnection(QUIC_ERROR_MIGRATING_ADDRESS, error_details,
-                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-        return false;
-      }
-    }
-    default_path_.self_address = last_received_packet_info_.destination_address;
-  }
-
-  if (PacketCanReplaceServerConnectionId(header, perspective_) &&
-      default_path_.server_connection_id != header.source_connection_id) {
-    QUICHE_DCHECK_EQ(header.long_packet_type, INITIAL);
-    if (server_connection_id_replaced_by_initial_) {
-      QUIC_DLOG(ERROR) << ENDPOINT << "Refusing to replace connection ID "
-                       << default_path_.server_connection_id << " with "
-                       << header.source_connection_id;
-      return false;
-    }
-    server_connection_id_replaced_by_initial_ = true;
-    QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
-                    << default_path_.server_connection_id << " with "
-                    << header.source_connection_id;
-    if (!original_destination_connection_id_.has_value()) {
-      original_destination_connection_id_ = default_path_.server_connection_id;
-    }
-    ReplaceInitialServerConnectionId(header.source_connection_id);
-  }
-
-  if (!ValidateReceivedPacketNumber(header.packet_number)) {
-    return false;
-  }
-
-  if (!version_negotiated_) {
-    if (perspective_ == Perspective::IS_CLIENT) {
-      QUICHE_DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
-      if (!version().HasIetfInvariantHeader()) {
-        // If the client gets a packet without the version flag from the server
-        // it should stop sending version since the version negotiation is done.
-        // IETF QUIC stops sending version once encryption level switches to
-        // forward secure.
-        packet_creator_.StopSendingVersion();
-      }
-      version_negotiated_ = true;
-      OnSuccessfulVersionNegotiation();
-    }
-  }
-
-  if (last_size_ > largest_received_packet_size_) {
-    largest_received_packet_size_ = last_size_;
-  }
-
-  if (perspective_ == Perspective::IS_SERVER &&
-      encryption_level_ == ENCRYPTION_INITIAL &&
-      last_size_ > packet_creator_.max_packet_length()) {
-    if (GetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test)) {
-      SetMaxPacketLength(std::min(last_size_, QuicByteCount(1250)));
-    } else {
-      SetMaxPacketLength(last_size_);
-    }
-  }
-  return true;
-}
-
-bool QuicConnection::ValidateReceivedPacketNumber(
-    QuicPacketNumber packet_number) {
-  // If this packet has already been seen, or the sender has told us that it
-  // will not be retransmitted, then stop processing the packet.
-  if (!uber_received_packet_manager_.IsAwaitingPacket(
-          last_decrypted_packet_level_, packet_number)) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
-                    << " no longer being waited for at level "
-                    << static_cast<int>(last_decrypted_packet_level_)
-                    << ".  Discarding.";
-    if (debug_visitor_ != nullptr) {
-      debug_visitor_->OnDuplicatePacket(packet_number);
-    }
-    return false;
-  }
-
-  return true;
-}
-
-void QuicConnection::WriteQueuedPackets() {
-  QUICHE_DCHECK(!writer_->IsWriteBlocked());
-
-  QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsBeforeWrite",
-                               buffered_packets_.size(), 1, 1000, 50, "");
-
-  while (!buffered_packets_.empty()) {
-    if (HandleWriteBlocked()) {
-      break;
-    }
-    const BufferedPacket& packet = buffered_packets_.front();
-    WriteResult result = writer_->WritePacket(
-        packet.encrypted_buffer.data(), packet.encrypted_buffer.length(),
-        packet.self_address.host(), packet.peer_address, per_packet_options_);
-    QUIC_DVLOG(1) << ENDPOINT << "Sending buffered packet, result: " << result;
-    if (IsMsgTooBig(writer_, result) &&
-        packet.encrypted_buffer.length() > long_term_mtu_) {
-      // When MSG_TOO_BIG is returned, the system typically knows what the
-      // actual MTU is, so there is no need to probe further.
-      // TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
-      mtu_discoverer_.Disable();
-      mtu_discovery_alarm_->Cancel();
-      buffered_packets_.pop_front();
-      continue;
-    }
-    if (IsWriteError(result.status)) {
-      OnWriteError(result.error_code);
-      break;
-    }
-    if (result.status == WRITE_STATUS_OK ||
-        result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
-      buffered_packets_.pop_front();
-    }
-    if (IsWriteBlockedStatus(result.status)) {
-      visitor_->OnWriteBlocked();
-      break;
-    }
-  }
-}
-
-void QuicConnection::SendProbingRetransmissions() {
-  while (sent_packet_manager_.GetSendAlgorithm()->ShouldSendProbingPacket() &&
-         CanWrite(HAS_RETRANSMITTABLE_DATA)) {
-    if (!visitor_->SendProbingData()) {
-      QUIC_DVLOG(1)
-          << "Cannot send probing retransmissions: nothing to retransmit.";
-      break;
-    }
-  }
-}
-
-void QuicConnection::MarkZeroRttPacketsForRetransmission(int reject_reason) {
-  sent_packet_manager_.MarkZeroRttPacketsForRetransmission();
-  if (debug_visitor_ != nullptr && version().UsesTls()) {
-    debug_visitor_->OnZeroRttRejected(reject_reason);
-  }
-}
-
-void QuicConnection::NeuterUnencryptedPackets() {
-  sent_packet_manager_.NeuterUnencryptedPackets();
-  // This may have changed the retransmission timer, so re-arm it.
-  SetRetransmissionAlarm();
-  if (default_enable_5rto_blackhole_detection_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
-                                 1, 3);
-    // Consider this as forward progress since this is called when initial key
-    // gets discarded (or previous unencrypted data is not needed anymore).
-    OnForwardProgressMade();
-  }
-  if (SupportsMultiplePacketNumberSpaces()) {
-    // Stop sending ack of initial packet number space.
-    uber_received_packet_manager_.ResetAckStates(ENCRYPTION_INITIAL);
-    // Re-arm ack alarm.
-    ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
-                       kAlarmGranularity);
-  }
-}
-
-bool QuicConnection::ShouldGeneratePacket(
-    HasRetransmittableData retransmittable,
-    IsHandshake handshake) {
-  QUICHE_DCHECK(handshake != IS_HANDSHAKE ||
-                QuicVersionUsesCryptoFrames(transport_version()))
-      << ENDPOINT
-      << "Handshake in STREAM frames should not check ShouldGeneratePacket";
-  if (peer_issued_cid_manager_ != nullptr &&
-      packet_creator_.GetDestinationConnectionId().IsEmpty()) {
-    QUICHE_DCHECK(version().HasIetfQuicFrames());
-    QUIC_CODE_COUNT(quic_generate_packet_blocked_by_no_connection_id);
-    QUIC_BUG_IF(quic_bug_90265_1, perspective_ == Perspective::IS_CLIENT);
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "There is no destination connection ID available to "
-                       "generate packet.";
-    return false;
-  }
-  if (!count_bytes_on_alternative_path_separately_) {
-    return CanWrite(retransmittable);
-  }
-  QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 4, 5);
-  if (IsDefaultPath(default_path_.self_address,
-                    packet_creator_.peer_address())) {
-    return CanWrite(retransmittable);
-  }
-  // This is checking on the alternative path with a different peer address. The
-  // self address and the writer used are the same as the default path. In the
-  // case of different self address and writer, writing packet would use a
-  // differnt code path without checking the states of the default writer.
-  return connected_ && !HandleWriteBlocked();
-}
-
-const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
-  if (!ack_frequency_sent_ && sent_packet_manager_.CanSendAckFrequency()) {
-    if (packet_creator_.NextSendingPacketNumber() >=
-        FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 3, 3);
-      ack_frequency_sent_ = true;
-      auto frame = sent_packet_manager_.GetUpdatedAckFrequencyFrame();
-      visitor_->SendAckFrequency(frame);
-    }
-  }
-
-  QuicFrames frames;
-  const bool has_pending_ack =
-      uber_received_packet_manager_
-          .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
-          .IsInitialized();
-  if (!has_pending_ack && stop_waiting_count_ <= 1) {
-    // No need to send an ACK.
-    return frames;
-  }
-  ResetAckStates();
-
-  QUIC_DVLOG(1) << ENDPOINT << "Bundle an ACK opportunistically";
-  QuicFrame updated_ack_frame = GetUpdatedAckFrame();
-  QUIC_BUG_IF(quic_bug_12714_23, updated_ack_frame.ack_frame->packets.Empty())
-      << ENDPOINT << "Attempted to opportunistically bundle an empty "
-      << encryption_level_ << " ACK, " << (has_pending_ack ? "" : "!")
-      << "has_pending_ack, stop_waiting_count_ " << stop_waiting_count_;
-  frames.push_back(updated_ack_frame);
-
-  if (!no_stop_waiting_frames_) {
-    QuicStopWaitingFrame stop_waiting;
-    PopulateStopWaitingFrame(&stop_waiting);
-    frames.push_back(QuicFrame(stop_waiting));
-  }
-  return frames;
-}
-
-bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
-  if (!connected_) {
-    return false;
-  }
-
-  if (version().CanSendCoalescedPackets() &&
-      framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL) &&
-      framer_.is_processing_packet()) {
-    // While we still have initial keys, suppress sending in mid of packet
-    // processing.
-    // TODO(fayang): always suppress sending while in the mid of packet
-    // processing.
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Suppress sending in the mid of packet processing";
-    return false;
-  }
-
-  if (fill_coalesced_packet_) {
-    // Try to coalesce packet, only allow to write when creator is on soft max
-    // packet length. Given the next created packet is going to fill current
-    // coalesced packet, do not check amplification factor.
-    return packet_creator_.HasSoftMaxPacketLength();
-  }
-
-  if (sent_packet_manager_.pending_timer_transmission_count() > 0) {
-    // Allow sending if there are pending tokens, which occurs when:
-    // 1) firing PTO,
-    // 2) bundling CRYPTO data with ACKs,
-    // 3) coalescing CRYPTO data of higher space.
-    return true;
-  }
-
-  if (LimitedByAmplificationFactor()) {
-    // Server is constrained by the amplification restriction.
-    QUIC_CODE_COUNT(quic_throttled_by_amplification_limit);
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Constrained by amplification restriction to peer address "
-                  << default_path_.peer_address << " bytes received "
-                  << default_path_.bytes_received_before_address_validation
-                  << ", bytes sent"
-                  << default_path_.bytes_sent_before_address_validation;
-    ++stats_.num_amplification_throttling;
-    return false;
-  }
-
-  if (HandleWriteBlocked()) {
-    return false;
-  }
-
-  // Allow acks and probing frames to be sent immediately.
-  if (retransmittable == NO_RETRANSMITTABLE_DATA) {
-    return true;
-  }
-  // If the send alarm is set, wait for it to fire.
-  if (send_alarm_->IsSet()) {
-    return false;
-  }
-
-  QuicTime now = clock_->Now();
-  QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(now);
-  if (delay.IsInfinite()) {
-    send_alarm_->Cancel();
-    return false;
-  }
-
-  // Scheduler requires a delay.
-  if (!delay.IsZero()) {
-    if (delay <= release_time_into_future_) {
-      // Required delay is within pace time into future, send now.
-      return true;
-    }
-    // Cannot send packet now because delay is too far in the future.
-    send_alarm_->Update(now + delay, kAlarmGranularity);
-    QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
-                  << "ms";
-    return false;
-  }
-  return true;
-}
-
-QuicTime QuicConnection::CalculatePacketSentTime() {
-  const QuicTime now = clock_->Now();
-  if (!supports_release_time_ || per_packet_options_ == nullptr) {
-    // Don't change the release delay.
-    return now;
-  }
-
-  auto next_release_time_result = sent_packet_manager_.GetNextReleaseTime();
-
-  // Release before |now| is impossible.
-  QuicTime next_release_time =
-      std::max(now, next_release_time_result.release_time);
-  per_packet_options_->release_time_delay = next_release_time - now;
-  per_packet_options_->allow_burst = next_release_time_result.allow_burst;
-  return next_release_time;
-}
-
-bool QuicConnection::WritePacket(SerializedPacket* packet) {
-  if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
-      packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
-    QUIC_BUG(quic_bug_10511_23)
-        << "Attempt to write packet:" << packet->packet_number
-        << " after:" << sent_packet_manager_.GetLargestSentPacket();
-    CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return true;
-  }
-  const bool is_mtu_discovery = QuicUtils::ContainsFrameType(
-      packet->nonretransmittable_frames, MTU_DISCOVERY_FRAME);
-  const SerializedPacketFate fate = packet->fate;
-  // Termination packets are encrypted and saved, so don't exit early.
-  QuicErrorCode error_code = QUIC_NO_ERROR;
-  const bool is_termination_packet = IsTerminationPacket(*packet, &error_code);
-  QuicPacketNumber packet_number = packet->packet_number;
-  QuicPacketLength encrypted_length = packet->encrypted_length;
-  // Termination packets are eventually owned by TimeWaitListManager.
-  // Others are deleted at the end of this call.
-  if (is_termination_packet) {
-    if (termination_packets_ == nullptr) {
-      termination_packets_.reset(
-          new std::vector<std::unique_ptr<QuicEncryptedPacket>>);
-    }
-    // Copy the buffer so it's owned in the future.
-    char* buffer_copy = CopyBuffer(*packet);
-    termination_packets_->emplace_back(
-        new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
-    if (error_code == QUIC_SILENT_IDLE_TIMEOUT) {
-      QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
-      // TODO(fayang): populate histogram indicating the time elapsed from this
-      // connection gets closed to following client packets get received.
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "Added silent connection close to termination packets, "
-                       "num of termination packets: "
-                    << termination_packets_->size();
-      return true;
-    }
-  }
-
-  QUICHE_DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
-  QUICHE_DCHECK(is_mtu_discovery ||
-                encrypted_length <= packet_creator_.max_packet_length())
-      << " encrypted_length=" << encrypted_length
-      << " > packet_creator max_packet_length="
-      << packet_creator_.max_packet_length();
-  QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
-                << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
-                        ? "data bearing "
-                        : " ack or probing only ")
-                << ", encryption level: " << packet->encryption_level
-                << ", encrypted length:" << encrypted_length
-                << ", fate: " << fate << " to peer " << packet->peer_address;
-  QUIC_DVLOG(2) << ENDPOINT << packet->encryption_level << " packet number "
-                << packet_number << " of length " << encrypted_length << ": "
-                << std::endl
-                << quiche::QuicheTextUtils::HexDump(absl::string_view(
-                       packet->encrypted_buffer, encrypted_length));
-
-  // Measure the RTT from before the write begins to avoid underestimating the
-  // min_rtt_, especially in cases where the thread blocks or gets swapped out
-  // during the WritePacket below.
-  QuicTime packet_send_time = CalculatePacketSentTime();
-  WriteResult result(WRITE_STATUS_OK, encrypted_length);
-  QuicSocketAddress send_to_address = packet->peer_address;
-  // Self address is always the default self address on this code path.
-  bool send_on_current_path = send_to_address == peer_address();
-  switch (fate) {
-    case DISCARD:
-      ++stats_.packets_discarded;
-      if (debug_visitor_ != nullptr) {
-        debug_visitor_->OnPacketDiscarded(*packet);
-      }
-      return true;
-    case COALESCE:
-      QUIC_BUG_IF(quic_bug_12714_24,
-                  !version().CanSendCoalescedPackets() || coalescing_done_);
-      if (!coalesced_packet_.MaybeCoalescePacket(
-              *packet, self_address(), send_to_address,
-              helper_->GetStreamSendBufferAllocator(),
-              packet_creator_.max_packet_length())) {
-        // Failed to coalesce packet, flush current coalesced packet.
-        if (!FlushCoalescedPacket()) {
-          QUIC_BUG_IF(quic_connection_connected_after_flush_coalesced_failure,
-                      connected_)
-              << "QUIC connection is still connected after failing to flush "
-                 "coalesced packet.";
-          // Failed to flush coalesced packet, write error has been handled.
-          return false;
-        }
-        if (!coalesced_packet_.MaybeCoalescePacket(
-                *packet, self_address(), send_to_address,
-                helper_->GetStreamSendBufferAllocator(),
-                packet_creator_.max_packet_length())) {
-          // Failed to coalesce packet even it is the only packet, raise a write
-          // error.
-          QUIC_DLOG(ERROR) << ENDPOINT << "Failed to coalesce packet";
-          result.error_code = WRITE_STATUS_FAILED_TO_COALESCE_PACKET;
-          break;
-        }
-      }
-      if (coalesced_packet_.length() < coalesced_packet_.max_packet_length()) {
-        QUIC_DVLOG(1) << ENDPOINT << "Trying to set soft max packet length to "
-                      << coalesced_packet_.max_packet_length() -
-                             coalesced_packet_.length();
-        packet_creator_.SetSoftMaxPacketLength(
-            coalesced_packet_.max_packet_length() - coalesced_packet_.length());
-      }
-      break;
-    case BUFFER:
-      QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
-                    << " to buffered packets";
-      buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
-      break;
-    case SEND_TO_WRITER:
-      // Stop using coalescer from now on.
-      coalescing_done_ = true;
-      // At this point, packet->release_encrypted_buffer is either nullptr,
-      // meaning |packet->encrypted_buffer| is a stack buffer, or not-nullptr,
-      /// meaning it's a writer-allocated buffer. Note that connectivity probing
-      // packets do not use this function, so setting release_encrypted_buffer
-      // to nullptr will not cause probing packets to be leaked.
-      //
-      // writer_->WritePacket transfers buffer ownership back to the writer.
-      packet->release_encrypted_buffer = nullptr;
-      result = writer_->WritePacket(packet->encrypted_buffer, encrypted_length,
-                                    self_address().host(), send_to_address,
-                                    per_packet_options_);
-      // This is a work around for an issue with linux UDP GSO batch writers.
-      // When sending a GSO packet with 2 segments, if the first segment is
-      // larger than the path MTU, instead of EMSGSIZE, the linux kernel returns
-      // EINVAL, which translates to WRITE_STATUS_ERROR and causes conneciton to
-      // be closed. By manually flush the writer here, the MTU probe is sent in
-      // a normal(non-GSO) packet, so the kernel can return EMSGSIZE and we will
-      // not close the connection.
-      if (is_mtu_discovery && writer_->IsBatchMode()) {
-        result = writer_->Flush();
-      }
-      break;
-    case LEGACY_VERSION_ENCAPSULATE: {
-      QUICHE_DCHECK(!is_mtu_discovery);
-      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-      QUICHE_DCHECK_EQ(packet->encryption_level, ENCRYPTION_INITIAL);
-      QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
-      QUICHE_DCHECK(legacy_version_encapsulation_in_progress_);
-      QuicPacketLength encapsulated_length =
-          QuicLegacyVersionEncapsulator::Encapsulate(
-              legacy_version_encapsulation_sni_,
-              absl::string_view(packet->encrypted_buffer,
-                                packet->encrypted_length),
-              default_path_.server_connection_id, framer_.creation_time(),
-              GetLimitedMaxPacketSize(long_term_mtu_),
-              const_cast<char*>(packet->encrypted_buffer));
-      if (encapsulated_length != 0) {
-        stats_.sent_legacy_version_encapsulated_packets++;
-        packet->encrypted_length = encapsulated_length;
-        encrypted_length = encapsulated_length;
-        QUIC_DVLOG(2)
-            << ENDPOINT
-            << "Successfully performed Legacy Version Encapsulation on "
-            << packet->encryption_level << " packet number " << packet_number
-            << " of length " << encrypted_length << ": " << std::endl
-            << quiche::QuicheTextUtils::HexDump(absl::string_view(
-                   packet->encrypted_buffer, encrypted_length));
-      } else {
-        QUIC_BUG(quic_bug_10511_24)
-            << ENDPOINT << "Failed to perform Legacy Version Encapsulation on "
-            << packet->encryption_level << " packet number " << packet_number
-            << " of length " << encrypted_length;
-      }
-      if (!buffered_packets_.empty() || HandleWriteBlocked()) {
-        // Buffer the packet.
-        buffered_packets_.emplace_back(*packet, self_address(),
-                                       send_to_address);
-      } else {  // Send the packet to the writer.
-        // writer_->WritePacket transfers buffer ownership back to the writer.
-        packet->release_encrypted_buffer = nullptr;
-        result = writer_->WritePacket(packet->encrypted_buffer,
-                                      encrypted_length, self_address().host(),
-                                      send_to_address, per_packet_options_);
-      }
-    } break;
-    default:
-      QUICHE_DCHECK(false);
-      break;
-  }
-
-  QUIC_HISTOGRAM_ENUM(
-      "QuicConnection.WritePacketStatus", result.status,
-      WRITE_STATUS_NUM_VALUES,
-      "Status code returned by writer_->WritePacket() in QuicConnection.");
-
-  if (IsWriteBlockedStatus(result.status)) {
-    // Ensure the writer is still write blocked, otherwise QUIC may continue
-    // trying to write when it will not be able to.
-    QUICHE_DCHECK(writer_->IsWriteBlocked());
-    visitor_->OnWriteBlocked();
-    // If the socket buffers the data, then the packet should not
-    // be queued and sent again, which would result in an unnecessary
-    // duplicate packet being sent.  The helper must call OnCanWrite
-    // when the write completes, and OnWriteError if an error occurs.
-    if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
-      QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
-                    << " to buffered packets";
-      buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
-    }
-  }
-
-  // In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
-  // MTU discovery is permanently unsuccessful.
-  if (IsMsgTooBig(writer_, result)) {
-    if (is_mtu_discovery) {
-      // When MSG_TOO_BIG is returned, the system typically knows what the
-      // actual MTU is, so there is no need to probe further.
-      // TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
-      QUIC_DVLOG(1) << ENDPOINT
-                    << " MTU probe packet too big, size:" << encrypted_length
-                    << ", long_term_mtu_:" << long_term_mtu_;
-      mtu_discoverer_.Disable();
-      mtu_discovery_alarm_->Cancel();
-      // The write failed, but the writer is not blocked, so return true.
-      return true;
-    }
-    if (use_path_validator_ && !send_on_current_path) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 2, 4);
-      // Only handle MSG_TOO_BIG as error on current path.
-      return true;
-    }
-  }
-
-  if (IsWriteError(result.status)) {
-    QUIC_LOG_FIRST_N(ERROR, 10)
-        << ENDPOINT << "Failed writing packet " << packet_number << " of "
-        << encrypted_length << " bytes from " << self_address().host() << " to "
-        << send_to_address << ", with error code " << result.error_code
-        << ". long_term_mtu_:" << long_term_mtu_
-        << ", previous_validated_mtu_:" << previous_validated_mtu_
-        << ", max_packet_length():" << max_packet_length()
-        << ", is_mtu_discovery:" << is_mtu_discovery;
-    if (MaybeRevertToPreviousMtu()) {
-      return true;
-    }
-
-    OnWriteError(result.error_code);
-    return false;
-  }
-
-  if (result.status == WRITE_STATUS_OK) {
-    // packet_send_time is the ideal send time, if allow_burst is true, writer
-    // may have sent it earlier than that.
-    packet_send_time = packet_send_time + result.send_time_offset;
-  }
-
-  if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA &&
-      !is_termination_packet) {
-    // Start blackhole/path degrading detections if the sent packet is not
-    // termination packet and contains retransmittable data.
-    // Do not restart detection if detection is in progress indicating no
-    // forward progress has been made since last event (i.e., packet was sent
-    // or new packets were acknowledged).
-    if (!blackhole_detector_.IsDetectionInProgress()) {
-      // Try to start detections if no detection in progress. This could
-      // because either both detections are inactive when sending last packet
-      // or this connection just gets out of quiescence.
-      blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
-                                           GetNetworkBlackholeDeadline(),
-                                           GetPathMtuReductionDeadline());
-    }
-    idle_network_detector_.OnPacketSent(packet_send_time,
-                                        sent_packet_manager_.GetPtoDelay());
-  }
-
-  MaybeSetMtuAlarm(packet_number);
-  QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
-                << packet_send_time.ToDebuggingValue();
-
-  if (!count_bytes_on_alternative_path_separately_) {
-    if (EnforceAntiAmplificationLimit()) {
-      // Include bytes sent even if they are not in flight.
-      default_path_.bytes_sent_before_address_validation += encrypted_length;
-    }
-  } else {
-    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 2, 5);
-    if (IsDefaultPath(default_path_.self_address, send_to_address)) {
-      if (EnforceAntiAmplificationLimit()) {
-        // Include bytes sent even if they are not in flight.
-        default_path_.bytes_sent_before_address_validation += encrypted_length;
-      }
-    } else {
-      MaybeUpdateBytesSentToAlternativeAddress(send_to_address,
-                                               encrypted_length);
-    }
-  }
-
-  // Do not measure rtt of this packet if it's not sent on current path.
-  QUIC_DLOG_IF(INFO, !send_on_current_path)
-      << ENDPOINT << " Sent packet " << packet->packet_number
-      << " on a different path with remote address " << send_to_address
-      << " while current path has peer address " << peer_address();
-  const bool in_flight = sent_packet_manager_.OnPacketSent(
-      packet, packet_send_time, packet->transmission_type,
-      IsRetransmittable(*packet), /*measure_rtt=*/send_on_current_path);
-  QUIC_BUG_IF(quic_bug_12714_25,
-              perspective_ == Perspective::IS_SERVER &&
-                  default_enable_5rto_blackhole_detection_ &&
-                  blackhole_detector_.IsDetectionInProgress() &&
-                  !sent_packet_manager_.HasInFlightPackets())
-      << ENDPOINT
-      << "Trying to start blackhole detection without no bytes in flight";
-
-  if (debug_visitor_ != nullptr) {
-    if (sent_packet_manager_.unacked_packets().empty()) {
-      QUIC_BUG(quic_bug_10511_25)
-          << "Unacked map is empty right after packet is sent";
-    } else {
-      debug_visitor_->OnPacketSent(
-          packet->packet_number, packet->encrypted_length,
-          packet->has_crypto_handshake, packet->transmission_type,
-          packet->encryption_level,
-          sent_packet_manager_.unacked_packets()
-              .rbegin()
-              ->retransmittable_frames,
-          packet->nonretransmittable_frames, packet_send_time);
-    }
-  }
-  if (packet->encryption_level == ENCRYPTION_HANDSHAKE) {
-    handshake_packet_sent_ = true;
-  }
-
-  if (packet->encryption_level == ENCRYPTION_FORWARD_SECURE) {
-    if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
-      QUIC_DLOG(INFO) << ENDPOINT
-                      << "lowest_packet_sent_in_current_key_phase_ = "
-                      << packet_number;
-      lowest_packet_sent_in_current_key_phase_ = packet_number;
-    }
-    if (!is_termination_packet &&
-        MaybeHandleAeadConfidentialityLimits(*packet)) {
-      return true;
-    }
-  }
-  if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 1, 2);
-    if (in_flight || !retransmission_alarm_->IsSet()) {
-      SetRetransmissionAlarm();
-    }
-  } else if (ShouldSetRetransmissionAlarmOnPacketSent(
-                 in_flight, packet->encryption_level)) {
-    SetRetransmissionAlarm();
-  }
-  SetPingAlarm();
-  RetirePeerIssuedConnectionIdsNoLongerOnPath();
-
-  // The packet number length must be updated after OnPacketSent, because it
-  // may change the packet number length in packet.
-  packet_creator_.UpdatePacketNumberLength(
-      sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
-      sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
-
-  stats_.bytes_sent += result.bytes_written;
-  ++stats_.packets_sent;
-  if (packet->transmission_type != NOT_RETRANSMISSION) {
-    stats_.bytes_retransmitted += result.bytes_written;
-    ++stats_.packets_retransmitted;
-  }
-
-  return true;
-}
-
-bool QuicConnection::MaybeHandleAeadConfidentialityLimits(
-    const SerializedPacket& packet) {
-  if (!version().UsesTls()) {
-    return false;
-  }
-
-  if (packet.encryption_level != ENCRYPTION_FORWARD_SECURE) {
-    QUIC_BUG(quic_bug_12714_26)
-        << "MaybeHandleAeadConfidentialityLimits called on non 1-RTT packet";
-    return false;
-  }
-  if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
-    QUIC_BUG(quic_bug_10511_26)
-        << "lowest_packet_sent_in_current_key_phase_ must be initialized "
-           "before calling MaybeHandleAeadConfidentialityLimits";
-    return false;
-  }
-
-  // Calculate the number of packets encrypted from the packet number, which is
-  // simpler than keeping another counter. The packet number space may be
-  // sparse, so this might overcount, but doing a key update earlier than
-  // necessary would only improve security and has negligible cost.
-  if (packet.packet_number < lowest_packet_sent_in_current_key_phase_) {
-    const std::string error_details =
-        absl::StrCat("packet_number(", packet.packet_number.ToString(),
-                     ") < lowest_packet_sent_in_current_key_phase_ (",
-                     lowest_packet_sent_in_current_key_phase_.ToString(), ")");
-    QUIC_BUG(quic_bug_10511_27) << error_details;
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return true;
-  }
-  const QuicPacketCount num_packets_encrypted_in_current_key_phase =
-      packet.packet_number - lowest_packet_sent_in_current_key_phase_ + 1;
-
-  const QuicPacketCount confidentiality_limit =
-      framer_.GetOneRttEncrypterConfidentialityLimit();
-
-  // Attempt to initiate a key update before reaching the AEAD
-  // confidentiality limit when the number of packets sent in the current
-  // key phase gets within |kKeyUpdateConfidentialityLimitOffset| packets of
-  // the limit, unless overridden by
-  // FLAGS_quic_key_update_confidentiality_limit.
-  constexpr QuicPacketCount kKeyUpdateConfidentialityLimitOffset = 1000;
-  QuicPacketCount key_update_limit = 0;
-  if (confidentiality_limit > kKeyUpdateConfidentialityLimitOffset) {
-    key_update_limit =
-        confidentiality_limit - kKeyUpdateConfidentialityLimitOffset;
-  }
-  const QuicPacketCount key_update_limit_override =
-      GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit);
-  if (key_update_limit_override) {
-    key_update_limit = key_update_limit_override;
-  }
-
-  QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD confidentiality limits: "
-                << "num_packets_encrypted_in_current_key_phase="
-                << num_packets_encrypted_in_current_key_phase
-                << " key_update_limit=" << key_update_limit
-                << " confidentiality_limit=" << confidentiality_limit
-                << " IsKeyUpdateAllowed()=" << IsKeyUpdateAllowed();
-
-  if (num_packets_encrypted_in_current_key_phase >= confidentiality_limit) {
-    // Reached the confidentiality limit without initiating a key update,
-    // must close the connection.
-    const std::string error_details = absl::StrCat(
-        "encrypter confidentiality limit reached: "
-        "num_packets_encrypted_in_current_key_phase=",
-        num_packets_encrypted_in_current_key_phase,
-        " key_update_limit=", key_update_limit,
-        " confidentiality_limit=", confidentiality_limit,
-        " IsKeyUpdateAllowed()=", IsKeyUpdateAllowed());
-    CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return true;
-  }
-
-  if (IsKeyUpdateAllowed() &&
-      num_packets_encrypted_in_current_key_phase >= key_update_limit) {
-    // Approaching the confidentiality limit, initiate key update so that
-    // the next set of keys will be ready for the next packet before the
-    // limit is reached.
-    KeyUpdateReason reason = KeyUpdateReason::kLocalAeadConfidentialityLimit;
-    if (key_update_limit_override) {
-      QUIC_DLOG(INFO) << ENDPOINT
-                      << "reached FLAGS_quic_key_update_confidentiality_limit, "
-                         "initiating key update: "
-                      << "num_packets_encrypted_in_current_key_phase="
-                      << num_packets_encrypted_in_current_key_phase
-                      << " key_update_limit=" << key_update_limit
-                      << " confidentiality_limit=" << confidentiality_limit;
-      reason = KeyUpdateReason::kLocalKeyUpdateLimitOverride;
-    } else {
-      QUIC_DLOG(INFO) << ENDPOINT
-                      << "approaching AEAD confidentiality limit, "
-                         "initiating key update: "
-                      << "num_packets_encrypted_in_current_key_phase="
-                      << num_packets_encrypted_in_current_key_phase
-                      << " key_update_limit=" << key_update_limit
-                      << " confidentiality_limit=" << confidentiality_limit;
-    }
-    InitiateKeyUpdate(reason);
-  }
-
-  return false;
-}
-
-void QuicConnection::FlushPackets() {
-  if (!connected_) {
-    return;
-  }
-
-  if (!writer_->IsBatchMode()) {
-    return;
-  }
-
-  if (HandleWriteBlocked()) {
-    QUIC_DLOG(INFO) << ENDPOINT << "FlushPackets called while blocked.";
-    return;
-  }
-
-  WriteResult result = writer_->Flush();
-
-  QUIC_HISTOGRAM_ENUM("QuicConnection.FlushPacketStatus", result.status,
-                      WRITE_STATUS_NUM_VALUES,
-                      "Status code returned by writer_->Flush() in "
-                      "QuicConnection::FlushPackets.");
-
-  if (HandleWriteBlocked()) {
-    QUICHE_DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status)
-        << "Unexpected flush result:" << result;
-    QUIC_DLOG(INFO) << ENDPOINT << "Write blocked in FlushPackets.";
-    return;
-  }
-
-  if (IsWriteError(result.status) && !MaybeRevertToPreviousMtu()) {
-    OnWriteError(result.error_code);
-  }
-}
-
-bool QuicConnection::IsMsgTooBig(const QuicPacketWriter* writer,
-                                 const WriteResult& result) {
-  absl::optional<int> writer_error_code = writer->MessageTooBigErrorCode();
-  return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
-         (writer_error_code.has_value() && IsWriteError(result.status) &&
-          result.error_code == *writer_error_code);
-}
-
-bool QuicConnection::ShouldDiscardPacket(EncryptionLevel encryption_level) {
-  if (!connected_) {
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Not sending packet as connection is disconnected.";
-    return true;
-  }
-
-  if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
-      encryption_level == ENCRYPTION_INITIAL) {
-    // Drop packets that are NULL encrypted since the peer won't accept them
-    // anymore.
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Dropping NULL encrypted packet since the connection is "
-                       "forward secure.";
-    return true;
-  }
-
-  return false;
-}
-
-QuicTime QuicConnection::GetPathMtuReductionDeadline() const {
-  if (previous_validated_mtu_ == 0) {
-    return QuicTime::Zero();
-  }
-  QuicTime::Delta delay = sent_packet_manager_.GetMtuReductionDelay(
-      num_rtos_for_blackhole_detection_);
-  if (delay.IsZero()) {
-    return QuicTime::Zero();
-  }
-  return clock_->ApproximateNow() + delay;
-}
-
-bool QuicConnection::MaybeRevertToPreviousMtu() {
-  if (previous_validated_mtu_ == 0) {
-    return false;
-  }
-
-  SetMaxPacketLength(previous_validated_mtu_);
-  mtu_discoverer_.Disable();
-  mtu_discovery_alarm_->Cancel();
-  previous_validated_mtu_ = 0;
-  return true;
-}
-
-void QuicConnection::OnWriteError(int error_code) {
-  if (write_error_occurred_) {
-    // A write error already occurred. The connection is being closed.
-    return;
-  }
-  write_error_occurred_ = true;
-
-  const std::string error_details = absl::StrCat(
-      "Write failed with error: ", error_code, " (", strerror(error_code), ")");
-  QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details;
-  absl::optional<int> writer_error_code = writer_->MessageTooBigErrorCode();
-  if (writer_error_code.has_value() && error_code == *writer_error_code) {
-    CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  // We can't send an error as the socket is presumably borked.
-  if (version().HasIetfInvariantHeader()) {
-    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
-  } else {
-    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_non_ietf);
-  }
-  CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
-                  ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-QuicPacketBuffer QuicConnection::GetPacketBuffer() {
-  if (version().CanSendCoalescedPackets() && !coalescing_done_) {
-    // Do not use writer's packet buffer for coalesced packets which may
-    // contain multiple QUIC packets.
-    return {nullptr, nullptr};
-  }
-  return writer_->GetNextWriteLocation(self_address().host(), peer_address());
-}
-
-void QuicConnection::OnSerializedPacket(SerializedPacket serialized_packet) {
-  if (serialized_packet.encrypted_buffer == nullptr) {
-    // We failed to serialize the packet, so close the connection.
-    // Specify that the close is silent, that no packet be sent, so no infinite
-    // loop here.
-    // TODO(ianswett): This is actually an internal error, not an
-    // encryption failure.
-    if (version().HasIetfInvariantHeader()) {
-      QUIC_CODE_COUNT(
-          quic_tear_down_local_connection_on_serialized_packet_ietf);
-    } else {
-      QUIC_CODE_COUNT(
-          quic_tear_down_local_connection_on_serialized_packet_non_ietf);
-    }
-    CloseConnection(QUIC_ENCRYPTION_FAILURE,
-                    "Serialized packet does not have an encrypted buffer.",
-                    ConnectionCloseBehavior::SILENT_CLOSE);
-    return;
-  }
-
-  if (serialized_packet.retransmittable_frames.empty()) {
-    // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
-    // this packet is a new transmission with no retransmittable frames.
-    ++consecutive_num_packets_with_no_retransmittable_frames_;
-  } else {
-    consecutive_num_packets_with_no_retransmittable_frames_ = 0;
-  }
-  SendOrQueuePacket(std::move(serialized_packet));
-}
-
-void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
-                                          const std::string& error_details) {
-  // The packet creator or generator encountered an unrecoverable error: tear
-  // down local connection state immediately.
-  if (version().HasIetfInvariantHeader()) {
-    QUIC_CODE_COUNT(
-        quic_tear_down_local_connection_on_unrecoverable_error_ietf);
-  } else {
-    QUIC_CODE_COUNT(
-        quic_tear_down_local_connection_on_unrecoverable_error_non_ietf);
-  }
-  CloseConnection(error, error_details, ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-void QuicConnection::OnCongestionChange() {
-  visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
-
-  // Uses the connection's smoothed RTT. If zero, uses initial_rtt.
-  QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt();
-  if (rtt.IsZero()) {
-    rtt = sent_packet_manager_.GetRttStats()->initial_rtt();
-  }
-
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnRttChanged(rtt);
-  }
-}
-
-void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) {
-  if (packet_size > max_packet_length()) {
-    previous_validated_mtu_ = max_packet_length();
-    SetMaxPacketLength(packet_size);
-    mtu_discoverer_.OnMaxPacketLengthUpdated(previous_validated_mtu_,
-                                             max_packet_length());
-  }
-}
-
-std::unique_ptr<QuicSelfIssuedConnectionIdManager>
-QuicConnection::MakeSelfIssuedConnectionIdManager() {
-  QUICHE_DCHECK((perspective_ == Perspective::IS_CLIENT &&
-                 !default_path_.client_connection_id.IsEmpty()) ||
-                (perspective_ == Perspective::IS_SERVER &&
-                 !default_path_.server_connection_id.IsEmpty()));
-  return std::make_unique<QuicSelfIssuedConnectionIdManager>(
-      kMinNumOfActiveConnectionIds,
-      perspective_ == Perspective::IS_CLIENT
-          ? default_path_.client_connection_id
-          : default_path_.server_connection_id,
-      clock_, alarm_factory_, this, context());
-}
-
-void QuicConnection::MaybeSendConnectionIdToClient() {
-  if (perspective_ == Perspective::IS_CLIENT) {
-    return;
-  }
-  QUICHE_DCHECK(self_issued_cid_manager_ != nullptr);
-  self_issued_cid_manager_->MaybeSendNewConnectionIds();
-}
-
-void QuicConnection::OnHandshakeComplete() {
-  sent_packet_manager_.SetHandshakeConfirmed();
-  if (connection_migration_use_new_cid_ &&
-      perspective_ == Perspective::IS_SERVER &&
-      self_issued_cid_manager_ != nullptr) {
-    self_issued_cid_manager_->MaybeSendNewConnectionIds();
-  }
-  if (send_ack_frequency_on_handshake_completion_ &&
-      sent_packet_manager_.CanSendAckFrequency()) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 2, 3);
-    auto ack_frequency_frame =
-        sent_packet_manager_.GetUpdatedAckFrequencyFrame();
-    // This AckFrequencyFrame is meant to only update the max_ack_delay. Set
-    // packet tolerance to the default value for now.
-    ack_frequency_frame.packet_tolerance =
-        kDefaultRetransmittablePacketsBeforeAck;
-    visitor_->SendAckFrequency(ack_frequency_frame);
-    if (!connected_) {
-      return;
-    }
-  }
-  // This may have changed the retransmission timer, so re-arm it.
-  SetRetransmissionAlarm();
-  if (default_enable_5rto_blackhole_detection_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
-                                 2, 3);
-    OnForwardProgressMade();
-  }
-  if (!SupportsMultiplePacketNumberSpaces()) {
-    // The client should immediately ack the SHLO to confirm the handshake is
-    // complete with the server.
-    if (perspective_ == Perspective::IS_CLIENT && ack_frame_updated()) {
-      ack_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
-    }
-    return;
-  }
-  // Stop sending ack of handshake packet number space.
-  uber_received_packet_manager_.ResetAckStates(ENCRYPTION_HANDSHAKE);
-  // Re-arm ack alarm.
-  ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
-                     kAlarmGranularity);
-}
-
-void QuicConnection::SendOrQueuePacket(SerializedPacket packet) {
-  // The caller of this function is responsible for checking CanWrite().
-  WritePacket(&packet);
-}
-
-void QuicConnection::OnPingTimeout() {
-  if (retransmission_alarm_->IsSet() ||
-      !visitor_->ShouldKeepConnectionAlive()) {
-    return;
-  }
-  SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
-}
-
-void QuicConnection::SendAck() {
-  QUICHE_DCHECK(!SupportsMultiplePacketNumberSpaces());
-  QUIC_DVLOG(1) << ENDPOINT << "Sending an ACK proactively";
-  QuicFrames frames;
-  frames.push_back(GetUpdatedAckFrame());
-  if (!no_stop_waiting_frames_) {
-    QuicStopWaitingFrame stop_waiting;
-    PopulateStopWaitingFrame(&stop_waiting);
-    frames.push_back(QuicFrame(stop_waiting));
-  }
-  if (!packet_creator_.FlushAckFrame(frames)) {
-    return;
-  }
-  ResetAckStates();
-  if (!ShouldBundleRetransmittableFrameWithAck()) {
-    return;
-  }
-  consecutive_num_packets_with_no_retransmittable_frames_ = 0;
-  if (packet_creator_.HasPendingRetransmittableFrames() ||
-      visitor_->WillingAndAbleToWrite()) {
-    // There are pending retransmittable frames.
-    return;
-  }
-
-  visitor_->OnAckNeedsRetransmittableFrame();
-}
-
-void QuicConnection::OnRetransmissionTimeout() {
-  ScopedRetransmissionTimeoutIndicator indicator(this);
-#ifndef NDEBUG
-  if (sent_packet_manager_.unacked_packets().empty()) {
-    QUICHE_DCHECK(sent_packet_manager_.handshake_mode_disabled());
-    QUICHE_DCHECK(!IsHandshakeComplete());
-  }
-#endif
-  if (!connected_) {
-    return;
-  }
-
-  QuicPacketNumber previous_created_packet_number =
-      packet_creator_.packet_number();
-  const auto retransmission_mode =
-      sent_packet_manager_.OnRetransmissionTimeout();
-  if (sent_packet_manager_.skip_packet_number_for_pto() &&
-      retransmission_mode == QuicSentPacketManager::PTO_MODE &&
-      sent_packet_manager_.pending_timer_transmission_count() == 1) {
-    // Skip a packet number when a single PTO packet is sent to elicit an
-    // immediate ACK.
-    const QuicPacketCount num_packet_numbers_to_skip = 1;
-    packet_creator_.SkipNPacketNumbers(
-        num_packet_numbers_to_skip,
-        sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
-        sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
-    previous_created_packet_number += num_packet_numbers_to_skip;
-    if (debug_visitor_ != nullptr) {
-      debug_visitor_->OnNPacketNumbersSkipped(num_packet_numbers_to_skip,
-                                              clock_->Now());
-    }
-  }
-  if (default_enable_5rto_blackhole_detection_ &&
-      !sent_packet_manager_.HasInFlightPackets() &&
-      blackhole_detector_.IsDetectionInProgress()) {
-    // Stop detection in quiescence.
-    QUICHE_DCHECK_EQ(QuicSentPacketManager::LOSS_MODE, retransmission_mode);
-    blackhole_detector_.StopDetection(/*permanent=*/false);
-  }
-  WriteIfNotBlocked();
-
-  // A write failure can result in the connection being closed, don't attempt to
-  // write further packets, or to set alarms.
-  if (!connected_) {
-    return;
-  }
-
-  // In the PTO and TLP cases, the SentPacketManager gives the connection the
-  // opportunity to send new data before retransmitting.
-  if (sent_packet_manager_.pto_enabled()) {
-    sent_packet_manager_.MaybeSendProbePackets();
-  } else if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) {
-    // Send the pending retransmission now that it's been queued.
-    WriteIfNotBlocked();
-  }
-
-  if (packet_creator_.packet_number() == previous_created_packet_number &&
-      (retransmission_mode == QuicSentPacketManager::TLP_MODE ||
-       retransmission_mode == QuicSentPacketManager::RTO_MODE ||
-       retransmission_mode == QuicSentPacketManager::PTO_MODE) &&
-      !visitor_->WillingAndAbleToWrite()) {
-    // Send PING if timer fires in TLP/RTO/PTO mode but there is no data to
-    // send.
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "No packet gets sent when timer fires in mode "
-                    << retransmission_mode << ", send PING";
-    QUICHE_DCHECK_LT(0u,
-                     sent_packet_manager_.pending_timer_transmission_count());
-    if (SupportsMultiplePacketNumberSpaces()) {
-      // Based on https://datatracker.ietf.org/doc/html/rfc9002#appendix-A.9
-      PacketNumberSpace packet_number_space;
-      if (sent_packet_manager_
-              .GetEarliestPacketSentTimeForPto(&packet_number_space)
-              .IsInitialized()) {
-        SendPingAtLevel(QuicUtils::GetEncryptionLevel(packet_number_space));
-      } else {
-        // The client must PTO when there is nothing in flight if the server
-        // could be blocked from sending by the amplification limit
-        QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-        if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE)) {
-          SendPingAtLevel(ENCRYPTION_HANDSHAKE);
-        } else if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
-          SendPingAtLevel(ENCRYPTION_INITIAL);
-        } else {
-          QUIC_BUG(quic_bug_no_pto) << "PTO fired but nothing was sent.";
-        }
-      }
-    } else {
-      SendPingAtLevel(encryption_level_);
-    }
-  }
-  if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
-    sent_packet_manager_.AdjustPendingTimerTransmissions();
-  }
-  if (retransmission_mode != QuicSentPacketManager::LOSS_MODE &&
-      retransmission_mode != QuicSentPacketManager::HANDSHAKE_MODE) {
-    // When timer fires in TLP/RTO/PTO mode, ensure 1) at least one packet is
-    // created, or there is data to send and available credit (such that
-    // packets will be sent eventually).
-    QUIC_BUG_IF(
-        quic_bug_12714_27,
-        packet_creator_.packet_number() == previous_created_packet_number &&
-            (!visitor_->WillingAndAbleToWrite() ||
-             sent_packet_manager_.pending_timer_transmission_count() == 0u))
-        << "retransmission_mode: " << retransmission_mode
-        << ", packet_number: " << packet_creator_.packet_number()
-        << ", session has data to write: " << visitor_->WillingAndAbleToWrite()
-        << ", writer is blocked: " << writer_->IsWriteBlocked()
-        << ", pending_timer_transmission_count: "
-        << sent_packet_manager_.pending_timer_transmission_count();
-  }
-
-  // Ensure the retransmission alarm is always set if there are unacked packets
-  // and nothing waiting to be sent.
-  // This happens if the loss algorithm invokes a timer based loss, but the
-  // packet doesn't need to be retransmitted.
-  if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
-    SetRetransmissionAlarm();
-  }
-}
-
-void QuicConnection::SetEncrypter(EncryptionLevel level,
-                                  std::unique_ptr<QuicEncrypter> encrypter) {
-  packet_creator_.SetEncrypter(level, std::move(encrypter));
-}
-
-void QuicConnection::RemoveEncrypter(EncryptionLevel level) {
-  framer_.RemoveEncrypter(level);
-}
-
-void QuicConnection::SetDiversificationNonce(
-    const DiversificationNonce& nonce) {
-  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
-  packet_creator_.SetDiversificationNonce(nonce);
-}
-
-void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
-  QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from "
-                << encryption_level_ << " to " << level;
-  const bool changing_level = level != encryption_level_;
-  if (changing_level && packet_creator_.HasPendingFrames()) {
-    // Flush all queued frames when encryption level changes.
-    ScopedPacketFlusher flusher(this);
-    packet_creator_.FlushCurrentPacket();
-  }
-  encryption_level_ = level;
-  packet_creator_.set_encryption_level(level);
-  QUIC_BUG_IF(quic_bug_12714_28, !framer_.HasEncrypterOfEncryptionLevel(level))
-      << ENDPOINT << "Trying to set encryption level to "
-      << EncryptionLevelToString(level) << " while the key is missing";
-
-  if (!changing_level) {
-    return;
-  }
-  // The least packet awaited by the peer depends on the encryption level so
-  // we recalculate it here.
-  packet_creator_.UpdatePacketNumberLength(
-      sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
-      sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
-}
-
-void QuicConnection::SetDecrypter(EncryptionLevel level,
-                                  std::unique_ptr<QuicDecrypter> decrypter) {
-  framer_.SetDecrypter(level, std::move(decrypter));
-
-  if (!undecryptable_packets_.empty() &&
-      !process_undecryptable_packets_alarm_->IsSet()) {
-    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
-  }
-}
-
-void QuicConnection::SetAlternativeDecrypter(
-    EncryptionLevel level,
-    std::unique_ptr<QuicDecrypter> decrypter,
-    bool latch_once_used) {
-  framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
-
-  if (!undecryptable_packets_.empty() &&
-      !process_undecryptable_packets_alarm_->IsSet()) {
-    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
-  }
-}
-
-void QuicConnection::InstallDecrypter(
-    EncryptionLevel level,
-    std::unique_ptr<QuicDecrypter> decrypter) {
-  if (level == ENCRYPTION_ZERO_RTT) {
-    had_zero_rtt_decrypter_ = true;
-  }
-  framer_.InstallDecrypter(level, std::move(decrypter));
-  if (!undecryptable_packets_.empty() &&
-      !process_undecryptable_packets_alarm_->IsSet()) {
-    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
-  }
-}
-
-void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
-  framer_.RemoveDecrypter(level);
-}
-
-void QuicConnection::DiscardPreviousOneRttKeys() {
-  framer_.DiscardPreviousOneRttKeys();
-}
-
-bool QuicConnection::IsKeyUpdateAllowed() const {
-  return support_key_update_for_connection_ &&
-         GetLargestAckedPacket().IsInitialized() &&
-         lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
-         GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_;
-}
-
-bool QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const {
-  return lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
-         (!GetLargestAckedPacket().IsInitialized() ||
-          GetLargestAckedPacket() < lowest_packet_sent_in_current_key_phase_);
-}
-
-QuicPacketCount QuicConnection::PotentialPeerKeyUpdateAttemptCount() const {
-  return framer_.PotentialPeerKeyUpdateAttemptCount();
-}
-
-bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) {
-  QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate";
-  if (!IsKeyUpdateAllowed()) {
-    QUIC_BUG(quic_bug_10511_28) << "key update not allowed";
-    return false;
-  }
-  return framer_.DoKeyUpdate(reason);
-}
-
-const QuicDecrypter* QuicConnection::decrypter() const {
-  return framer_.decrypter();
-}
-
-const QuicDecrypter* QuicConnection::alternative_decrypter() const {
-  return framer_.alternative_decrypter();
-}
-
-void QuicConnection::QueueUndecryptablePacket(
-    const QuicEncryptedPacket& packet,
-    EncryptionLevel decryption_level) {
-  for (const auto& saved_packet : undecryptable_packets_) {
-    if (packet.data() == saved_packet.packet->data() &&
-        packet.length() == saved_packet.packet->length()) {
-      QUIC_DVLOG(1) << ENDPOINT << "Not queueing known undecryptable packet";
-      return;
-    }
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet.";
-  undecryptable_packets_.emplace_back(packet, decryption_level,
-                                      last_received_packet_info_);
-  if (perspective_ == Perspective::IS_CLIENT) {
-    if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
-      SetRetransmissionAlarm();
-    } else if (!retransmission_alarm_->IsSet() ||
-               GetRetransmissionDeadline() <
-                   retransmission_alarm_->deadline()) {
-      // Re-arm PTO only if we can make it sooner to speed up recovery.
-      SetRetransmissionAlarm();
-    }
-  }
-}
-
-void QuicConnection::MaybeProcessUndecryptablePackets() {
-  process_undecryptable_packets_alarm_->Cancel();
-
-  if (undecryptable_packets_.empty() ||
-      encryption_level_ == ENCRYPTION_INITIAL) {
-    return;
-  }
-
-  auto iter = undecryptable_packets_.begin();
-  while (connected_ && iter != undecryptable_packets_.end()) {
-    // Making sure there is no pending frames when processing next undecrypted
-    // packet because the queued ack frame may change.
-    packet_creator_.FlushCurrentPacket();
-    if (!connected_) {
-      return;
-    }
-    UndecryptablePacket* undecryptable_packet = &*iter;
-    QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
-    if (debug_visitor_ != nullptr) {
-      debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
-          undecryptable_packet->encryption_level);
-    }
-    last_received_packet_info_ = undecryptable_packet->packet_info;
-    last_size_ = undecryptable_packet->packet->length();
-    current_packet_data_ = undecryptable_packet->packet->data();
-    const bool processed = framer_.ProcessPacket(*undecryptable_packet->packet);
-    current_packet_data_ = nullptr;
-
-    if (processed) {
-      QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
-      iter = undecryptable_packets_.erase(iter);
-      ++stats_.packets_processed;
-      continue;
-    }
-    const bool has_decryption_key = version().KnowsWhichDecrypterToUse() &&
-                                    framer_.HasDecrypterOfEncryptionLevel(
-                                        undecryptable_packet->encryption_level);
-    if (framer_.error() == QUIC_DECRYPTION_FAILURE &&
-        ShouldEnqueueUnDecryptablePacket(undecryptable_packet->encryption_level,
-                                         has_decryption_key)) {
-      QUIC_DVLOG(1)
-          << ENDPOINT
-          << "Need to attempt to process this undecryptable packet later";
-      ++iter;
-      continue;
-    }
-    iter = undecryptable_packets_.erase(iter);
-  }
-
-  // Once handshake is complete, there will be no new keys installed and hence
-  // any undecryptable packets will never be able to be decrypted.
-  if (IsHandshakeComplete()) {
-    if (debug_visitor_ != nullptr) {
-      for (const auto& undecryptable_packet : undecryptable_packets_) {
-        debug_visitor_->OnUndecryptablePacket(
-            undecryptable_packet.encryption_level, /*dropped=*/true);
-      }
-    }
-    undecryptable_packets_.clear();
-  }
-  if (perspective_ == Perspective::IS_CLIENT) {
-    if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
-      SetRetransmissionAlarm();
-    } else if (!retransmission_alarm_->IsSet() ||
-               undecryptable_packets_.empty() ||
-               GetRetransmissionDeadline() <
-                   retransmission_alarm_->deadline()) {
-      // 1) If there is still undecryptable packet, only re-arm PTO to make it
-      // sooner to speed up recovery.
-      // 2) If all undecryptable packets get processed, re-arm (which may
-      // postpone) PTO since no immediate recovery is needed.
-      SetRetransmissionAlarm();
-    }
-  }
-}
-
-void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) {
-  QUIC_DVLOG(1) << ENDPOINT << "Queueing coalesced packet.";
-  received_coalesced_packets_.push_back(packet.Clone());
-  ++stats_.num_coalesced_packets_received;
-}
-
-bool QuicConnection::MaybeProcessCoalescedPackets() {
-  bool processed = false;
-  while (connected_ && !received_coalesced_packets_.empty()) {
-    // Making sure there are no pending frames when processing the next
-    // coalesced packet because the queued ack frame may change.
-    packet_creator_.FlushCurrentPacket();
-    if (!connected_) {
-      return processed;
-    }
-
-    std::unique_ptr<QuicEncryptedPacket> packet =
-        std::move(received_coalesced_packets_.front());
-    received_coalesced_packets_.pop_front();
-
-    QUIC_DVLOG(1) << ENDPOINT << "Processing coalesced packet";
-    if (framer_.ProcessPacket(*packet)) {
-      processed = true;
-      ++stats_.num_coalesced_packets_processed;
-    } else {
-      // If we are unable to decrypt this packet, it might be
-      // because the CHLO or SHLO packet was lost.
-    }
-  }
-  if (processed) {
-    MaybeProcessUndecryptablePackets();
-    MaybeSendInResponseToPacket();
-  }
-  return processed;
-}
-
-void QuicConnection::CloseConnection(
-    QuicErrorCode error,
-    const std::string& details,
-    ConnectionCloseBehavior connection_close_behavior) {
-  CloseConnection(error, NO_IETF_QUIC_ERROR, details,
-                  connection_close_behavior);
-}
-
-void QuicConnection::CloseConnection(
-    QuicErrorCode error,
-    QuicIetfTransportErrorCodes ietf_error,
-    const std::string& error_details,
-    ConnectionCloseBehavior connection_close_behavior) {
-  QUICHE_DCHECK(!error_details.empty());
-  if (!connected_) {
-    QUIC_DLOG(INFO) << "Connection is already closed.";
-    return;
-  }
-
-  if (ietf_error != NO_IETF_QUIC_ERROR) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
-                    << ", with wire error: " << ietf_error
-                    << ", error: " << QuicErrorCodeToString(error)
-                    << ", and details:  " << error_details;
-  } else {
-    QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
-                    << ", with error: " << QuicErrorCodeToString(error) << " ("
-                    << error << "), and details:  " << error_details;
-  }
-
-  if (connection_close_behavior != ConnectionCloseBehavior::SILENT_CLOSE) {
-    SendConnectionClosePacket(error, ietf_error, error_details);
-  }
-
-  TearDownLocalConnectionState(error, ietf_error, error_details,
-                               ConnectionCloseSource::FROM_SELF);
-}
-
-void QuicConnection::SendConnectionClosePacket(
-    QuicErrorCode error,
-    QuicIetfTransportErrorCodes ietf_error,
-    const std::string& details) {
-  // Always use the current path to send CONNECTION_CLOSE.
-  QuicPacketCreator::ScopedPeerAddressContext context(
-      &packet_creator_, peer_address(), default_path_.client_connection_id,
-      default_path_.server_connection_id, connection_migration_use_new_cid_);
-  if (!SupportsMultiplePacketNumberSpaces()) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
-    ScopedEncryptionLevelContext context(this,
-                                         GetConnectionCloseEncryptionLevel());
-    if (version().CanSendCoalescedPackets()) {
-      coalesced_packet_.Clear();
-    }
-    ClearQueuedPackets();
-    // If there was a packet write error, write the smallest close possible.
-    ScopedPacketFlusher flusher(this);
-    // Always bundle an ACK with connection close for debugging purpose.
-    if (error != QUIC_PACKET_WRITE_ERROR &&
-        !uber_received_packet_manager_.IsAckFrameEmpty(
-            QuicUtils::GetPacketNumberSpace(encryption_level_)) &&
-        !packet_creator_.has_ack()) {
-      SendAck();
-    }
-    QuicConnectionCloseFrame* frame;
-
-    frame = new QuicConnectionCloseFrame(transport_version(), error, ietf_error,
-                                         details,
-                                         framer_.current_received_frame_type());
-    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
-    packet_creator_.FlushCurrentPacket();
-    if (version().CanSendCoalescedPackets()) {
-      FlushCoalescedPacket();
-    }
-    ClearQueuedPackets();
-    return;
-  }
-  ScopedPacketFlusher flusher(this);
-
-  // Now that the connection is being closed, discard any unsent packets
-  // so the only packets to be sent will be connection close packets.
-  if (version().CanSendCoalescedPackets()) {
-    coalesced_packet_.Clear();
-  }
-  ClearQueuedPackets();
-
-  for (EncryptionLevel level :
-       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
-        ENCRYPTION_FORWARD_SECURE}) {
-    if (!framer_.HasEncrypterOfEncryptionLevel(level)) {
-      continue;
-    }
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Sending connection close packet at level: " << level;
-    ScopedEncryptionLevelContext context(this, level);
-    // Bundle an ACK of the corresponding packet number space for debugging
-    // purpose.
-    if (error != QUIC_PACKET_WRITE_ERROR &&
-        !uber_received_packet_manager_.IsAckFrameEmpty(
-            QuicUtils::GetPacketNumberSpace(encryption_level_)) &&
-        !packet_creator_.has_ack()) {
-      QuicFrames frames;
-      frames.push_back(GetUpdatedAckFrame());
-      packet_creator_.FlushAckFrame(frames);
-    }
-
-    if (level == ENCRYPTION_FORWARD_SECURE &&
-        perspective_ == Perspective::IS_SERVER) {
-      visitor_->BeforeConnectionCloseSent();
-    }
-
-    auto* frame = new QuicConnectionCloseFrame(
-        transport_version(), error, ietf_error, details,
-        framer_.current_received_frame_type());
-    if (level == ENCRYPTION_FORWARD_SECURE) {
-      if (connection_close_frame_sent_.has_value()) {
-        QUIC_BUG(quic_send_multiple_connection_closes)
-            << ENDPOINT << "Already sent connection close: "
-            << connection_close_frame_sent_.value()
-            << ", going to send connection close: " << *frame;
-      } else {
-        connection_close_frame_sent_ = *frame;
-      }
-    }
-    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
-    packet_creator_.FlushCurrentPacket();
-  }
-  if (version().CanSendCoalescedPackets()) {
-    FlushCoalescedPacket();
-  }
-  // Since the connection is closing, if the connection close packets were not
-  // sent, then they should be discarded.
-  ClearQueuedPackets();
-}
-
-void QuicConnection::TearDownLocalConnectionState(
-    QuicErrorCode error,
-    QuicIetfTransportErrorCodes ietf_error,
-    const std::string& error_details,
-    ConnectionCloseSource source) {
-  QuicConnectionCloseFrame frame(transport_version(), error, ietf_error,
-                                 error_details,
-                                 framer_.current_received_frame_type());
-  return TearDownLocalConnectionState(frame, source);
-}
-
-void QuicConnection::TearDownLocalConnectionState(
-    const QuicConnectionCloseFrame& frame,
-    ConnectionCloseSource source) {
-  if (!connected_) {
-    QUIC_DLOG(INFO) << "Connection is already closed.";
-    return;
-  }
-
-  // If we are using a batch writer, flush packets queued in it, if any.
-  FlushPackets();
-  connected_ = false;
-  QUICHE_DCHECK(visitor_ != nullptr);
-  visitor_->OnConnectionClosed(frame, source);
-  // LossDetectionTunerInterface::Finish() may be called from
-  // sent_packet_manager_.OnConnectionClosed. Which may require the session to
-  // finish its business first.
-  sent_packet_manager_.OnConnectionClosed();
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnConnectionClosed(frame, source);
-  }
-  // Cancel the alarms so they don't trigger any action now that the
-  // connection is closed.
-  CancelAllAlarms();
-  if (use_path_validator_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 3, 4);
-    CancelPathValidation();
-  }
-  peer_issued_cid_manager_.reset();
-  self_issued_cid_manager_.reset();
-}
-
-void QuicConnection::CancelAllAlarms() {
-  QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
-
-  ack_alarm_->PermanentCancel();
-  ping_alarm_->PermanentCancel();
-  retransmission_alarm_->PermanentCancel();
-  send_alarm_->PermanentCancel();
-  mtu_discovery_alarm_->PermanentCancel();
-  process_undecryptable_packets_alarm_->PermanentCancel();
-  discard_previous_one_rtt_keys_alarm_->PermanentCancel();
-  discard_zero_rtt_decryption_keys_alarm_->PermanentCancel();
-  blackhole_detector_.StopDetection(/*permanent=*/true);
-  idle_network_detector_.StopDetection();
-}
-
-QuicByteCount QuicConnection::max_packet_length() const {
-  return packet_creator_.max_packet_length();
-}
-
-void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
-  long_term_mtu_ = length;
-  stats_.max_egress_mtu = std::max(stats_.max_egress_mtu, long_term_mtu_);
-  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-}
-
-bool QuicConnection::HasQueuedData() const {
-  return packet_creator_.HasPendingFrames() || !buffered_packets_.empty();
-}
-
-void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
-                                        QuicTime::Delta idle_timeout) {
-  QUIC_BUG_IF(quic_bug_12714_29, idle_timeout > handshake_timeout)
-      << "idle_timeout:" << idle_timeout.ToMilliseconds()
-      << " handshake_timeout:" << handshake_timeout.ToMilliseconds();
-  // Adjust the idle timeout on client and server to prevent clients from
-  // sending requests to servers which have already closed the connection.
-  if (perspective_ == Perspective::IS_SERVER) {
-    idle_timeout = idle_timeout + QuicTime::Delta::FromSeconds(3);
-  } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) {
-    idle_timeout = idle_timeout - QuicTime::Delta::FromSeconds(1);
-  }
-  idle_network_detector_.SetTimeouts(handshake_timeout, idle_timeout);
-}
-
-void QuicConnection::SetPingAlarm() {
-  if (!connected_) {
-    return;
-  }
-  if (perspective_ == Perspective::IS_SERVER &&
-      initial_retransmittable_on_wire_timeout_.IsInfinite()) {
-    // The PING alarm exists to support two features:
-    // 1) clients send PINGs every 15s to prevent NAT timeouts,
-    // 2) both clients and servers can send retransmittable on the wire PINGs
-    // (ROWP) while ShouldKeepConnectionAlive is true and there is no packets in
-    // flight.
-    return;
-  }
-  if (!visitor_->ShouldKeepConnectionAlive()) {
-    ping_alarm_->Cancel();
-    // Don't send a ping unless the application (ie: HTTP/3) says to, usually
-    // because it is expecting a response from the server.
-    return;
-  }
-  if (initial_retransmittable_on_wire_timeout_.IsInfinite() ||
-      sent_packet_manager_.HasInFlightPackets() ||
-      retransmittable_on_wire_ping_count_ >
-          GetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count)) {
-    if (perspective_ == Perspective::IS_CLIENT) {
-      // Clients send 15s PINGs to avoid NATs from timing out.
-      ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
-                          QuicTime::Delta::FromSeconds(1));
-    } else {
-      // Servers do not send 15s PINGs.
-      ping_alarm_->Cancel();
-    }
-    return;
-  }
-  QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_, ping_timeout_);
-  QuicTime::Delta retransmittable_on_wire_timeout =
-      initial_retransmittable_on_wire_timeout_;
-  int max_aggressive_retransmittable_on_wire_ping_count =
-      GetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count);
-  QUICHE_DCHECK_LE(0, max_aggressive_retransmittable_on_wire_ping_count);
-  if (consecutive_retransmittable_on_wire_ping_count_ >
-      max_aggressive_retransmittable_on_wire_ping_count) {
-    // Exponentially back off the timeout if the number of consecutive
-    // retransmittable on wire pings has exceeds the allowance.
-    int shift = consecutive_retransmittable_on_wire_ping_count_ -
-                max_aggressive_retransmittable_on_wire_ping_count;
-    retransmittable_on_wire_timeout =
-        initial_retransmittable_on_wire_timeout_ * (1 << shift);
-  }
-  // If it's already set to an earlier time, then don't update it.
-  if (ping_alarm_->IsSet() &&
-      ping_alarm_->deadline() <
-          clock_->ApproximateNow() + retransmittable_on_wire_timeout) {
-    return;
-  }
-
-  if (retransmittable_on_wire_timeout < ping_timeout_) {
-    // Use a shorter timeout if there are open streams, but nothing on the wire.
-    ping_alarm_->Update(
-        clock_->ApproximateNow() + retransmittable_on_wire_timeout,
-        kAlarmGranularity);
-    if (max_aggressive_retransmittable_on_wire_ping_count != 0) {
-      consecutive_retransmittable_on_wire_ping_count_++;
-    }
-    retransmittable_on_wire_ping_count_++;
-    return;
-  }
-
-  ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
-                      kAlarmGranularity);
-}
-
-void QuicConnection::SetRetransmissionAlarm() {
-  if (!connected_) {
-    if (retransmission_alarm_->IsSet()) {
-      QUIC_BUG(quic_bug_10511_29)
-          << ENDPOINT << "Retransmission alarm is set while disconnected";
-      retransmission_alarm_->Cancel();
-    }
-    return;
-  }
-  if (packet_creator_.PacketFlusherAttached()) {
-    pending_retransmission_alarm_ = true;
-    return;
-  }
-  if (LimitedByAmplificationFactor()) {
-    // Do not set retransmission timer if connection is anti-amplification limit
-    // throttled. Otherwise, nothing can be sent when timer fires.
-    retransmission_alarm_->Cancel();
-    return;
-  }
-  PacketNumberSpace packet_number_space;
-  if (sent_packet_manager_.simplify_set_retransmission_alarm() &&
-      SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
-      !sent_packet_manager_
-           .GetEarliestPacketSentTimeForPto(&packet_number_space)
-           .IsInitialized()) {
-    // Before handshake gets confirmed, GetEarliestPacketSentTimeForPto
-    // returning 0 indicates no packets are in flight or only application data
-    // is in flight.
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 2, 2);
-    if (perspective_ == Perspective::IS_SERVER) {
-      // No need to arm PTO on server side.
-      retransmission_alarm_->Cancel();
-      return;
-    }
-    if (retransmission_alarm_->IsSet() &&
-        GetRetransmissionDeadline() > retransmission_alarm_->deadline()) {
-      // Do not postpone armed PTO on the client side.
-      return;
-    }
-  }
-
-  retransmission_alarm_->Update(GetRetransmissionDeadline(), kAlarmGranularity);
-}
-
-void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
-  if (mtu_discovery_alarm_->IsSet() ||
-      !mtu_discoverer_.ShouldProbeMtu(sent_packet_number)) {
-    return;
-  }
-  mtu_discovery_alarm_->Set(clock_->ApproximateNow());
-}
-
-QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
-    QuicConnection* connection)
-    : connection_(connection),
-      flush_and_set_pending_retransmission_alarm_on_delete_(false),
-      handshake_packet_sent_(connection != nullptr &&
-                             connection->handshake_packet_sent_) {
-  if (connection_ == nullptr) {
-    return;
-  }
-
-  if (!connection_->packet_creator_.PacketFlusherAttached()) {
-    flush_and_set_pending_retransmission_alarm_on_delete_ = true;
-    connection->packet_creator_.AttachPacketFlusher();
-  }
-}
-
-QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
-  if (connection_ == nullptr || !connection_->connected()) {
-    return;
-  }
-
-  if (flush_and_set_pending_retransmission_alarm_on_delete_) {
-    const QuicTime ack_timeout =
-        connection_->uber_received_packet_manager_.GetEarliestAckTimeout();
-    if (ack_timeout.IsInitialized()) {
-      if (ack_timeout <= connection_->clock_->ApproximateNow() &&
-          !connection_->CanWrite(NO_RETRANSMITTABLE_DATA)) {
-        // Cancel ACK alarm if connection is write blocked, and ACK will be
-        // sent when connection gets unblocked.
-        connection_->ack_alarm_->Cancel();
-      } else if (!connection_->ack_alarm_->IsSet() ||
-                 connection_->ack_alarm_->deadline() > ack_timeout) {
-        connection_->ack_alarm_->Update(ack_timeout, QuicTime::Delta::Zero());
-      }
-    }
-    if (connection_->ack_alarm_->IsSet() &&
-        connection_->ack_alarm_->deadline() <=
-            connection_->clock_->ApproximateNow()) {
-      // An ACK needs to be sent right now. This ACK did not get bundled
-      // because either there was no data to write or packets were marked as
-      // received after frames were queued in the generator.
-      if (connection_->send_alarm_->IsSet() &&
-          connection_->send_alarm_->deadline() <=
-              connection_->clock_->ApproximateNow()) {
-        // If send alarm will go off soon, let send alarm send the ACK.
-        connection_->ack_alarm_->Cancel();
-      } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
-        connection_->SendAllPendingAcks();
-      } else {
-        connection_->SendAck();
-      }
-    }
-
-    if (connection_->flush_after_coalesce_higher_space_packets_) {
-      // INITIAL or HANDSHAKE retransmission could cause peer to derive new
-      // keys, such that the buffered undecryptable packets may be processed.
-      // This endpoint would derive an inflated RTT sample when receiving ACKs
-      // of those undecryptable packets. To mitigate this, tries to coalesce as
-      // many higher space packets as possible (via for loop inside
-      // MaybeCoalescePacketOfHigherSpace) to fill the remaining space in the
-      // coalescer.
-      QUIC_RELOADABLE_FLAG_COUNT(
-          quic_flush_after_coalesce_higher_space_packets);
-      if (connection_->version().CanSendCoalescedPackets()) {
-        connection_->MaybeCoalescePacketOfHigherSpace();
-      }
-      connection_->packet_creator_.Flush();
-      if (connection_->version().CanSendCoalescedPackets()) {
-        connection_->FlushCoalescedPacket();
-      }
-    } else {
-      connection_->packet_creator_.Flush();
-      if (connection_->version().CanSendCoalescedPackets()) {
-        connection_->MaybeCoalescePacketOfHigherSpace();
-        connection_->FlushCoalescedPacket();
-      }
-    }
-    connection_->FlushPackets();
-    if (!handshake_packet_sent_ && connection_->handshake_packet_sent_) {
-      // This would cause INITIAL key to be dropped. Drop keys here to avoid
-      // missing the write keys in the middle of writing.
-      connection_->visitor_->OnHandshakePacketSent();
-    }
-    // Reset transmission type.
-    connection_->SetTransmissionType(NOT_RETRANSMISSION);
-
-    // Once all transmissions are done, check if there is any outstanding data
-    // to send and notify the congestion controller if not.
-    //
-    // Note that this means that the application limited check will happen as
-    // soon as the last flusher gets destroyed, which is typically after a
-    // single stream write is finished.  This means that if all the data from a
-    // single write goes through the connection, the application-limited signal
-    // will fire even if the caller does a write operation immediately after.
-    // There are two important approaches to remedy this situation:
-    // (1) Instantiate ScopedPacketFlusher before performing multiple subsequent
-    //     writes, thus deferring this check until all writes are done.
-    // (2) Write data in chunks sufficiently large so that they cause the
-    //     connection to be limited by the congestion control.  Typically, this
-    //     would mean writing chunks larger than the product of the current
-    //     pacing rate and the pacer granularity.  So, for instance, if the
-    //     pacing rate of the connection is 1 Gbps, and the pacer granularity is
-    //     1 ms, the caller should send at least 125k bytes in order to not
-    //     be marked as application-limited.
-    connection_->CheckIfApplicationLimited();
-
-    if (connection_->pending_retransmission_alarm_) {
-      connection_->SetRetransmissionAlarm();
-      connection_->pending_retransmission_alarm_ = false;
-    }
-  }
-  QUICHE_DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
-                   !connection_->packet_creator_.PacketFlusherAttached());
-}
-
-QuicConnection::ScopedEncryptionLevelContext::ScopedEncryptionLevelContext(
-    QuicConnection* connection,
-    EncryptionLevel encryption_level)
-    : connection_(connection), latched_encryption_level_(ENCRYPTION_INITIAL) {
-  if (connection_ == nullptr) {
-    return;
-  }
-  latched_encryption_level_ = connection_->encryption_level_;
-  connection_->SetDefaultEncryptionLevel(encryption_level);
-}
-
-QuicConnection::ScopedEncryptionLevelContext::~ScopedEncryptionLevelContext() {
-  if (connection_ == nullptr || !connection_->connected_) {
-    return;
-  }
-  connection_->SetDefaultEncryptionLevel(latched_encryption_level_);
-}
-
-QuicConnection::BufferedPacket::BufferedPacket(
-    const SerializedPacket& packet,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address)
-    : encrypted_buffer(CopyBuffer(packet), packet.encrypted_length),
-      self_address(self_address),
-      peer_address(peer_address) {}
-
-QuicConnection::BufferedPacket::BufferedPacket(
-    char* encrypted_buffer,
-    QuicPacketLength encrypted_length,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address)
-    : encrypted_buffer(CopyBuffer(encrypted_buffer, encrypted_length),
-                       encrypted_length),
-      self_address(self_address),
-      peer_address(peer_address) {}
-
-QuicConnection::BufferedPacket::~BufferedPacket() {
-  delete[] encrypted_buffer.data();
-}
-
-HasRetransmittableData QuicConnection::IsRetransmittable(
-    const SerializedPacket& packet) {
-  // Retransmitted packets retransmittable frames are owned by the unacked
-  // packet map, but are not present in the serialized packet.
-  if (packet.transmission_type != NOT_RETRANSMISSION ||
-      !packet.retransmittable_frames.empty()) {
-    return HAS_RETRANSMITTABLE_DATA;
-  } else {
-    return NO_RETRANSMITTABLE_DATA;
-  }
-}
-
-bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet,
-                                         QuicErrorCode* error_code) {
-  if (packet.retransmittable_frames.empty()) {
-    return false;
-  }
-  for (const QuicFrame& frame : packet.retransmittable_frames) {
-    if (frame.type == CONNECTION_CLOSE_FRAME) {
-      *error_code = frame.connection_close_frame->quic_error_code;
-      return true;
-    }
-  }
-  return false;
-}
-
-void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
-  QUIC_DVLOG(2) << ENDPOINT << "SetMtuDiscoveryTarget: " << target;
-  mtu_discoverer_.Disable();
-  mtu_discoverer_.Enable(max_packet_length(), GetLimitedMaxPacketSize(target));
-}
-
-QuicByteCount QuicConnection::GetLimitedMaxPacketSize(
-    QuicByteCount suggested_max_packet_size) {
-  if (!peer_address().IsInitialized()) {
-    QUIC_BUG(quic_bug_10511_30)
-        << "Attempted to use a connection without a valid peer address";
-    return suggested_max_packet_size;
-  }
-
-  const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
-
-  QuicByteCount max_packet_size = suggested_max_packet_size;
-  if (max_packet_size > writer_limit) {
-    max_packet_size = writer_limit;
-  }
-  if (max_packet_size > peer_max_packet_size_) {
-    max_packet_size = peer_max_packet_size_;
-  }
-  if (max_packet_size > kMaxOutgoingPacketSize) {
-    max_packet_size = kMaxOutgoingPacketSize;
-  }
-  return max_packet_size;
-}
-
-void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
-  // Currently, this limit is ensured by the caller.
-  QUICHE_DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
-
-  // Send the probe.
-  packet_creator_.GenerateMtuDiscoveryPacket(target_mtu);
-}
-
-// TODO(zhongyi): change this method to generate a connectivity probing packet
-// and let the caller to call writer to write the packet and handle write
-// status.
-bool QuicConnection::SendConnectivityProbingPacket(
-    QuicPacketWriter* probing_writer,
-    const QuicSocketAddress& peer_address) {
-  QUICHE_DCHECK(peer_address.IsInitialized());
-  if (!connected_) {
-    QUIC_BUG(quic_bug_10511_31)
-        << "Not sending connectivity probing packet as connection is "
-        << "disconnected.";
-    return false;
-  }
-  if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
-    // Server can use default packet writer to write packet.
-    probing_writer = writer_;
-  }
-  QUICHE_DCHECK(probing_writer);
-
-  if (probing_writer->IsWriteBlocked()) {
-    QUIC_DLOG(INFO)
-        << ENDPOINT
-        << "Writer blocked when sending connectivity probing packet.";
-    if (probing_writer == writer_) {
-      // Visitor should not be write blocked if the probing writer is not the
-      // default packet writer.
-      visitor_->OnWriteBlocked();
-    }
-    return true;
-  }
-
-  QUIC_DLOG(INFO) << ENDPOINT
-                  << "Sending path probe packet for connection_id = "
-                  << default_path_.server_connection_id;
-
-  std::unique_ptr<SerializedPacket> probing_packet;
-  if (!version().HasIetfQuicFrames()) {
-    // Non-IETF QUIC, generate a padded ping regardless of whether this is a
-    // request or a response.
-    probing_packet = packet_creator_.SerializeConnectivityProbingPacket();
-  } else {
-    // IETF QUIC path challenge.
-    // Send a path probe request using IETF QUIC PATH_CHALLENGE frame.
-    transmitted_connectivity_probe_payload_ =
-        std::make_unique<QuicPathFrameBuffer>();
-    random_generator_->RandBytes(transmitted_connectivity_probe_payload_.get(),
-                                 sizeof(QuicPathFrameBuffer));
-    probing_packet =
-        packet_creator_.SerializePathChallengeConnectivityProbingPacket(
-            *transmitted_connectivity_probe_payload_);
-    if (!probing_packet) {
-      transmitted_connectivity_probe_payload_ = nullptr;
-    }
-  }
-  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
-  return WritePacketUsingWriter(std::move(probing_packet), probing_writer,
-                                self_address(), peer_address,
-                                /*measure_rtt=*/true);
-}
-
-bool QuicConnection::WritePacketUsingWriter(
-    std::unique_ptr<SerializedPacket> packet,
-    QuicPacketWriter* writer,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    bool measure_rtt) {
-  const QuicTime packet_send_time = clock_->Now();
-  QUIC_DVLOG(2) << ENDPOINT
-                << "Sending path probe packet for server connection ID "
-                << default_path_.server_connection_id << std::endl
-                << quiche::QuicheTextUtils::HexDump(absl::string_view(
-                       packet->encrypted_buffer, packet->encrypted_length));
-  WriteResult result = writer->WritePacket(
-      packet->encrypted_buffer, packet->encrypted_length, self_address.host(),
-      peer_address, per_packet_options_);
-
-  // If using a batch writer and the probing packet is buffered, flush it.
-  if (writer->IsBatchMode() && result.status == WRITE_STATUS_OK &&
-      result.bytes_written == 0) {
-    result = writer->Flush();
-  }
-
-  if (IsWriteError(result.status)) {
-    // Write error for any connectivity probe should not affect the connection
-    // as it is sent on a different path.
-    QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
-                    << result.error_code;
-    return false;
-  }
-
-  // Send in currrent path. Call OnPacketSent regardless of the write result.
-  sent_packet_manager_.OnPacketSent(packet.get(), packet_send_time,
-                                    packet->transmission_type,
-                                    NO_RETRANSMITTABLE_DATA, measure_rtt);
-
-  if (debug_visitor_ != nullptr) {
-    if (sent_packet_manager_.unacked_packets().empty()) {
-      QUIC_BUG(quic_bug_10511_32)
-          << "Unacked map is empty right after packet is sent";
-    } else {
-      debug_visitor_->OnPacketSent(
-          packet->packet_number, packet->encrypted_length,
-          packet->has_crypto_handshake, packet->transmission_type,
-          packet->encryption_level,
-          sent_packet_manager_.unacked_packets()
-              .rbegin()
-              ->retransmittable_frames,
-          packet->nonretransmittable_frames, packet_send_time);
-    }
-  }
-
-  if (IsWriteBlockedStatus(result.status)) {
-    if (writer == writer_) {
-      // Visitor should not be write blocked if the probing writer is not the
-      // default packet writer.
-      visitor_->OnWriteBlocked();
-    }
-    if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
-      QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
-    }
-  }
-
-  return true;
-}
-
-void QuicConnection::DisableMtuDiscovery() {
-  mtu_discoverer_.Disable();
-  mtu_discovery_alarm_->Cancel();
-}
-
-void QuicConnection::DiscoverMtu() {
-  QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
-
-  const QuicPacketNumber largest_sent_packet =
-      sent_packet_manager_.GetLargestSentPacket();
-  if (mtu_discoverer_.ShouldProbeMtu(largest_sent_packet)) {
-    ++mtu_probe_count_;
-    SendMtuDiscoveryPacket(
-        mtu_discoverer_.GetUpdatedMtuProbeSize(largest_sent_packet));
-  }
-  QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
-}
-
-void QuicConnection::OnEffectivePeerMigrationValidated() {
-  if (active_effective_peer_migration_type_ == NO_CHANGE) {
-    QUIC_BUG(quic_bug_10511_33) << "No migration underway.";
-    return;
-  }
-  highest_packet_sent_before_effective_peer_migration_.Clear();
-  const bool send_address_token =
-      active_effective_peer_migration_type_ != PORT_CHANGE;
-  active_effective_peer_migration_type_ = NO_CHANGE;
-  ++stats_.num_validated_peer_migration;
-  if (!validate_client_addresses_) {
-    return;
-  }
-  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 2, 6);
-  if (debug_visitor_ != nullptr) {
-    const QuicTime now = clock_->ApproximateNow();
-    if (now >= stats_.handshake_completion_time) {
-      debug_visitor_->OnPeerMigrationValidated(
-          now - stats_.handshake_completion_time);
-    } else {
-      QUIC_BUG(quic_bug_10511_34)
-          << "Handshake completion time is larger than current time.";
-    }
-  }
-
-  // Lift anti-amplification limit.
-  default_path_.validated = true;
-  alternative_path_.Clear();
-  if (send_address_token) {
-    visitor_->MaybeSendAddressToken();
-  }
-}
-
-void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
-  // TODO(fayang): Currently, all peer address change type are allowed. Need to
-  // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
-  // determine whether |type| is allowed.
-  if (!validate_client_addresses_) {
-    if (type == NO_CHANGE) {
-      QUIC_BUG(quic_bug_10511_35)
-          << "EffectivePeerMigration started without address change.";
-      return;
-    }
-    QUIC_DLOG(INFO)
-        << ENDPOINT << "Effective peer's ip:port changed from "
-        << default_path_.peer_address.ToString() << " to "
-        << GetEffectivePeerAddressFromCurrentPacket().ToString()
-        << ", address change type is " << type
-        << ", migrating connection without validating new client address.";
-
-    highest_packet_sent_before_effective_peer_migration_ =
-        sent_packet_manager_.GetLargestSentPacket();
-    default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
-    active_effective_peer_migration_type_ = type;
-
-    OnConnectionMigration();
-    return;
-  }
-
-  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 3, 6);
-  if (type == NO_CHANGE) {
-    UpdatePeerAddress(last_received_packet_info_.source_address);
-    QUIC_BUG(quic_bug_10511_36)
-        << "EffectivePeerMigration started without address change.";
-    return;
-  }
-  if (GetQuicReloadableFlag(
-          quic_flush_pending_frames_and_padding_bytes_on_migration)) {
-    QUIC_RELOADABLE_FLAG_COUNT(
-        quic_flush_pending_frames_and_padding_bytes_on_migration);
-    // There could be pending NEW_TOKEN_FRAME triggered by non-probing
-    // PATH_RESPONSE_FRAME in the same packet or pending padding bytes in the
-    // packet creator.
-    packet_creator_.FlushCurrentPacket();
-    packet_creator_.SendRemainingPendingPadding();
-    if (!connected_) {
-      return;
-    }
-  } else {
-    if (packet_creator_.HasPendingFrames()) {
-      packet_creator_.FlushCurrentPacket();
-      if (!connected_) {
-        return;
-      }
-    }
-  }
-
-  // Action items:
-  //   1. Switch congestion controller;
-  //   2. Update default_path_ (addresses, validation and bytes accounting);
-  //   3. Save previous default path if needed;
-  //   4. Kick off reverse path validation if needed.
-  // Items 1 and 2 are must-to-do. Items 3 and 4 depends on if the new address
-  // is validated or not and which path the incoming packet is on.
-
-  const QuicSocketAddress current_effective_peer_address =
-      GetEffectivePeerAddressFromCurrentPacket();
-  QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
-                  << default_path_.peer_address.ToString() << " to "
-                  << current_effective_peer_address.ToString()
-                  << ", address change type is " << type
-                  << ", migrating connection.";
-
-  const QuicSocketAddress previous_direct_peer_address = direct_peer_address_;
-  PathState previous_default_path = std::move(default_path_);
-  active_effective_peer_migration_type_ = type;
-  MaybeClearQueuedPacketsOnPathChange();
-  OnConnectionMigration();
-
-  // Update congestion controller if the address change type is not PORT_CHANGE.
-  if (type == PORT_CHANGE) {
-    QUICHE_DCHECK(previous_default_path.validated ||
-                  (alternative_path_.validated &&
-                   alternative_path_.send_algorithm != nullptr));
-    // No need to store previous congestion controller because either the new
-    // default path is validated or the alternative path is validated and
-    // already has associated congestion controller.
-  } else {
-    previous_default_path.rtt_stats.emplace();
-    previous_default_path.rtt_stats->CloneFrom(
-        *sent_packet_manager_.GetRttStats());
-    // If the new peer address share the same IP with the alternative path, the
-    // connection should switch to the congestion controller of the alternative
-    // path. Otherwise, the connection should use a brand new one.
-    // In order to re-use existing code in sent_packet_manager_, reset
-    // congestion controller to initial state first and then change to the one
-    // on alternative path.
-    // TODO(danzh) combine these two steps into one after deprecating gQUIC.
-    previous_default_path.send_algorithm = OnPeerIpAddressChanged();
-
-    if (alternative_path_.peer_address.host() ==
-            current_effective_peer_address.host() &&
-        alternative_path_.send_algorithm != nullptr) {
-      // Update the default path with the congestion controller of the
-      // alternative path.
-      sent_packet_manager_.SetSendAlgorithm(
-          alternative_path_.send_algorithm.release());
-      sent_packet_manager_.SetRttStats(
-          std::move(alternative_path_.rtt_stats).value());
-    }
-  }
-  // Update to the new peer address.
-  UpdatePeerAddress(last_received_packet_info_.source_address);
-  // Update the default path.
-  if (IsAlternativePath(last_received_packet_info_.destination_address,
-                        current_effective_peer_address)) {
-    SetDefaultPathState(std::move(alternative_path_));
-  } else {
-    QuicConnectionId client_connection_id;
-    absl::optional<StatelessResetToken> stateless_reset_token;
-    FindMatchingOrNewClientConnectionIdOrToken(
-        previous_default_path, alternative_path_,
-        last_packet_destination_connection_id_, &client_connection_id,
-        &stateless_reset_token);
-    SetDefaultPathState(PathState(
-        last_received_packet_info_.destination_address,
-        current_effective_peer_address, client_connection_id,
-        last_packet_destination_connection_id_, stateless_reset_token));
-    // The path is considered validated if its peer IP address matches any
-    // validated path's peer IP address.
-    default_path_.validated =
-        (alternative_path_.peer_address.host() ==
-             current_effective_peer_address.host() &&
-         alternative_path_.validated) ||
-        (previous_default_path.validated && type == PORT_CHANGE);
-  }
-  if (!last_received_packet_info_.received_bytes_counted) {
-    // Increment bytes counting on the new default path.
-    default_path_.bytes_received_before_address_validation += last_size_;
-    last_received_packet_info_.received_bytes_counted = true;
-  }
-
-  if (!previous_default_path.validated) {
-    // If the old address is under validation, cancel and fail it. Failing to
-    // validate the old path shouldn't take any effect.
-    QUIC_DVLOG(1) << "Cancel validation of previous peer address change to "
-                  << previous_default_path.peer_address
-                  << " upon peer migration to " << default_path_.peer_address;
-    path_validator_.CancelPathValidation();
-    ++stats_.num_peer_migration_while_validating_default_path;
-  }
-
-  // Clear alternative path if the new default path shares the same IP as the
-  // alternative path.
-  if (alternative_path_.peer_address.host() ==
-      default_path_.peer_address.host()) {
-    alternative_path_.Clear();
-  }
-
-  if (default_path_.validated) {
-    QUIC_DVLOG(1) << "Peer migrated to a validated address.";
-    // No need to save previous default path, validate new peer address or
-    // update bytes sent/received.
-    if (!(previous_default_path.validated && type == PORT_CHANGE)) {
-      // The alternative path was validated because of proactive reverse path
-      // validation.
-      ++stats_.num_peer_migration_to_proactively_validated_address;
-    }
-    OnEffectivePeerMigrationValidated();
-    return;
-  }
-
-  // The new default address is not validated yet. Anti-amplification limit is
-  // enforced.
-  QUICHE_DCHECK(EnforceAntiAmplificationLimit());
-  QUIC_DVLOG(1) << "Apply anti-amplification limit to effective peer address "
-                << default_path_.peer_address << " with "
-                << default_path_.bytes_sent_before_address_validation
-                << " bytes sent and "
-                << default_path_.bytes_received_before_address_validation
-                << " bytes received.";
-
-  QUICHE_DCHECK(!alternative_path_.peer_address.IsInitialized() ||
-                alternative_path_.peer_address.host() !=
-                    default_path_.peer_address.host());
-
-  // Save previous default path to the altenative path.
-  if (previous_default_path.validated) {
-    // The old path is a validated path which the connection might revert back
-    // to later. Store it as the alternative path.
-    alternative_path_ = std::move(previous_default_path);
-    QUICHE_DCHECK(alternative_path_.send_algorithm != nullptr);
-  }
-
-  // If the new address is not validated and the connection is not already
-  // validating that address, a new reverse path validation is needed.
-  if (!path_validator_.IsValidatingPeerAddress(
-          current_effective_peer_address)) {
-    ++stats_.num_reverse_path_validtion_upon_migration;
-    ValidatePath(std::make_unique<ReversePathValidationContext>(
-                     default_path_.self_address, peer_address(),
-                     default_path_.peer_address, this),
-                 std::make_unique<ReversePathValidationResultDelegate>(
-                     this, previous_direct_peer_address));
-  } else {
-    QUIC_DVLOG(1) << "Peer address " << default_path_.peer_address
-                  << " is already under validation, wait for result.";
-    ++stats_.num_peer_migration_to_proactively_validated_address;
-  }
-}
-
-void QuicConnection::OnConnectionMigration() {
-  if (debug_visitor_ != nullptr) {
-    const QuicTime now = clock_->ApproximateNow();
-    if (now >= stats_.handshake_completion_time) {
-      debug_visitor_->OnPeerAddressChange(
-          active_effective_peer_migration_type_,
-          now - stats_.handshake_completion_time);
-    }
-  }
-  visitor_->OnConnectionMigration(active_effective_peer_migration_type_);
-  if (active_effective_peer_migration_type_ != PORT_CHANGE &&
-      active_effective_peer_migration_type_ != IPV4_SUBNET_CHANGE &&
-      !validate_client_addresses_) {
-    sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/false);
-  }
-}
-
-bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
-  return is_current_packet_connectivity_probing_;
-}
-
-bool QuicConnection::ack_frame_updated() const {
-  return uber_received_packet_manager_.IsAckFrameUpdated();
-}
-
-absl::string_view QuicConnection::GetCurrentPacket() {
-  if (current_packet_data_ == nullptr) {
-    return absl::string_view();
-  }
-  return absl::string_view(current_packet_data_, last_size_);
-}
-
-bool QuicConnection::MaybeConsiderAsMemoryCorruption(
-    const QuicStreamFrame& frame) {
-  if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
-      last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
-    return false;
-  }
-
-  if (perspective_ == Perspective::IS_SERVER &&
-      frame.data_length >= sizeof(kCHLO) &&
-      strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kCHLO),
-              sizeof(kCHLO)) == 0) {
-    return true;
-  }
-
-  if (perspective_ == Perspective::IS_CLIENT &&
-      frame.data_length >= sizeof(kREJ) &&
-      strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kREJ),
-              sizeof(kREJ)) == 0) {
-    return true;
-  }
-
-  return false;
-}
-
-void QuicConnection::MaybeSendProbingRetransmissions() {
-  QUICHE_DCHECK(fill_up_link_during_probing_);
-
-  // Don't send probing retransmissions until the handshake has completed.
-  if (!IsHandshakeComplete() ||
-      sent_packet_manager().HasUnackedCryptoPackets()) {
-    return;
-  }
-
-  if (probing_retransmission_pending_) {
-    QUIC_BUG(quic_bug_10511_37)
-        << "MaybeSendProbingRetransmissions is called while another call "
-           "to it is already in progress";
-    return;
-  }
-
-  probing_retransmission_pending_ = true;
-  SendProbingRetransmissions();
-  probing_retransmission_pending_ = false;
-}
-
-void QuicConnection::CheckIfApplicationLimited() {
-  if (!connected_ || probing_retransmission_pending_) {
-    return;
-  }
-
-  bool application_limited =
-      buffered_packets_.empty() && !visitor_->WillingAndAbleToWrite();
-
-  if (!application_limited) {
-    return;
-  }
-
-  if (fill_up_link_during_probing_) {
-    MaybeSendProbingRetransmissions();
-    if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
-      return;
-    }
-  }
-
-  sent_packet_manager_.OnApplicationLimited();
-}
-
-bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
-  most_recent_frame_type_ = type;
-  if (version().HasIetfQuicFrames()) {
-    if (!QuicUtils::IsProbingFrame(type)) {
-      MaybeStartIetfPeerMigration();
-      return connected_;
-    }
-    QuicSocketAddress current_effective_peer_address =
-        GetEffectivePeerAddressFromCurrentPacket();
-    if (!count_bytes_on_alternative_path_separately_ ||
-        IsDefaultPath(last_received_packet_info_.destination_address,
-                      last_received_packet_info_.source_address)) {
-      return connected_;
-    }
-    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 3, 5);
-    if (perspective_ == Perspective::IS_SERVER &&
-        type == PATH_CHALLENGE_FRAME &&
-        !IsAlternativePath(last_received_packet_info_.destination_address,
-                           current_effective_peer_address)) {
-      QUIC_DVLOG(1)
-          << "The peer is probing a new path with effective peer address "
-          << current_effective_peer_address << ",  self address "
-          << last_received_packet_info_.destination_address;
-      if (!validate_client_addresses_) {
-        QuicConnectionId client_cid;
-        absl::optional<StatelessResetToken> stateless_reset_token;
-        FindMatchingOrNewClientConnectionIdOrToken(
-            default_path_, alternative_path_,
-            last_packet_destination_connection_id_, &client_cid,
-            &stateless_reset_token);
-        alternative_path_ = PathState(
-            last_received_packet_info_.destination_address,
-            current_effective_peer_address, client_cid,
-            last_packet_destination_connection_id_, stateless_reset_token);
-      } else if (!default_path_.validated) {
-        QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 4, 6);
-        // Skip reverse path validation because either handshake hasn't
-        // completed or the connection is validating the default path. Using
-        // PATH_CHALLENGE to validate alternative client address before
-        // handshake gets comfirmed is meaningless because anyone can respond to
-        // it. If the connection is validating the default path, this
-        // alternative path is currently the only validated path which shouldn't
-        // be overridden.
-        QUIC_DVLOG(1) << "The connection hasn't finished handshake or is "
-                         "validating a recent peer address change.";
-        QUIC_BUG_IF(quic_bug_12714_30,
-                    IsHandshakeConfirmed() && !alternative_path_.validated)
-            << "No validated peer address to send after handshake comfirmed.";
-      } else if (!IsReceivedPeerAddressValidated()) {
-        QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 5, 6);
-        QuicConnectionId client_connection_id;
-        absl::optional<StatelessResetToken> stateless_reset_token;
-        FindMatchingOrNewClientConnectionIdOrToken(
-            default_path_, alternative_path_,
-            last_packet_destination_connection_id_, &client_connection_id,
-            &stateless_reset_token);
-        // Only override alternative path state upon receiving a PATH_CHALLENGE
-        // from an unvalidated peer address, and the connection isn't validating
-        // a recent peer migration.
-        alternative_path_ = PathState(
-            last_received_packet_info_.destination_address,
-            current_effective_peer_address, client_connection_id,
-            last_packet_destination_connection_id_, stateless_reset_token);
-        should_proactively_validate_peer_address_on_path_challenge_ = true;
-      }
-    }
-    MaybeUpdateBytesReceivedFromAlternativeAddress(last_size_);
-    return connected_;
-  }
-  // Packet content is tracked to identify connectivity probe in non-IETF
-  // version, where a connectivity probe is defined as
-  // - a padded PING packet with peer address change received by server,
-  // - a padded PING packet on new path received by client.
-
-  if (current_packet_content_ == NOT_PADDED_PING) {
-    // We have already learned the current packet is not a connectivity
-    // probing packet. Peer migration should have already been started earlier
-    // if needed.
-    return connected_;
-  }
-
-  if (type == PING_FRAME) {
-    if (current_packet_content_ == NO_FRAMES_RECEIVED) {
-      current_packet_content_ = FIRST_FRAME_IS_PING;
-      return connected_;
-    }
-  }
-
-  // In Google QUIC, we look for a packet with just a PING and PADDING.
-  // If the condition is met, mark things as connectivity-probing, causing
-  // later processing to generate the correct response.
-  if (type == PADDING_FRAME && current_packet_content_ == FIRST_FRAME_IS_PING) {
-    current_packet_content_ = SECOND_FRAME_IS_PADDING;
-    if (perspective_ == Perspective::IS_SERVER) {
-      is_current_packet_connectivity_probing_ =
-          current_effective_peer_migration_type_ != NO_CHANGE;
-      QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
-          << ENDPOINT
-          << "Detected connectivity probing packet. "
-             "current_effective_peer_migration_type_:"
-          << current_effective_peer_migration_type_;
-    } else {
-      is_current_packet_connectivity_probing_ =
-          (last_received_packet_info_.source_address != peer_address()) ||
-          (last_received_packet_info_.destination_address !=
-           default_path_.self_address);
-      QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
-          << ENDPOINT
-          << "Detected connectivity probing packet. "
-             "last_packet_source_address:"
-          << last_received_packet_info_.source_address
-          << ", peer_address_:" << peer_address()
-          << ", last_packet_destination_address:"
-          << last_received_packet_info_.destination_address
-          << ", default path self_address :" << default_path_.self_address;
-    }
-    return connected_;
-  }
-
-  current_packet_content_ = NOT_PADDED_PING;
-  if (GetLargestReceivedPacket().IsInitialized() &&
-      last_header_.packet_number == GetLargestReceivedPacket()) {
-    UpdatePeerAddress(last_received_packet_info_.source_address);
-    if (current_effective_peer_migration_type_ != NO_CHANGE) {
-      // Start effective peer migration immediately when the current packet is
-      // confirmed not a connectivity probing packet.
-      StartEffectivePeerMigration(current_effective_peer_migration_type_);
-    }
-  }
-  current_effective_peer_migration_type_ = NO_CHANGE;
-  return connected_;
-}
-
-void QuicConnection::MaybeStartIetfPeerMigration() {
-  QUICHE_DCHECK(version().HasIetfQuicFrames());
-  if (current_effective_peer_migration_type_ != NO_CHANGE &&
-      !IsHandshakeConfirmed()) {
-    QUIC_LOG_EVERY_N_SEC(INFO, 60)
-        << ENDPOINT << "Effective peer's ip:port changed from "
-        << default_path_.peer_address.ToString() << " to "
-        << GetEffectivePeerAddressFromCurrentPacket().ToString()
-        << " before handshake confirmed, "
-           "current_effective_peer_migration_type_: "
-        << current_effective_peer_migration_type_;
-    // Peer migrated before handshake gets confirmed.
-    CloseConnection((current_effective_peer_migration_type_ == PORT_CHANGE
-                         ? QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED
-                         : QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED),
-                    "Peer address changed before handshake is confirmed.",
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (GetLargestReceivedPacket().IsInitialized() &&
-      last_header_.packet_number == GetLargestReceivedPacket()) {
-    if (current_effective_peer_migration_type_ != NO_CHANGE) {
-      // Start effective peer migration when the current packet contains a
-      // non-probing frame.
-      // TODO(fayang): When multiple packet number spaces is supported, only
-      // start peer migration for the application data.
-      if (!validate_client_addresses_) {
-        UpdatePeerAddress(last_received_packet_info_.source_address);
-      }
-      StartEffectivePeerMigration(current_effective_peer_migration_type_);
-    } else {
-      UpdatePeerAddress(last_received_packet_info_.source_address);
-    }
-  }
-  current_effective_peer_migration_type_ = NO_CHANGE;
-}
-
-void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
-                                              bool acked_new_packet) {
-  if (no_stop_waiting_frames_ && !packet_creator_.has_ack()) {
-    uber_received_packet_manager_.DontWaitForPacketsBefore(
-        last_decrypted_packet_level_,
-        SupportsMultiplePacketNumberSpaces()
-            ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
-                  last_decrypted_packet_level_)
-            : sent_packet_manager_.largest_packet_peer_knows_is_acked());
-  }
-  // Always reset the retransmission alarm when an ack comes in, since we now
-  // have a better estimate of the current rtt than when it was set.
-  SetRetransmissionAlarm();
-  if (acked_new_packet) {
-    OnForwardProgressMade();
-  } else if (default_enable_5rto_blackhole_detection_ &&
-             !sent_packet_manager_.HasInFlightPackets() &&
-             blackhole_detector_.IsDetectionInProgress()) {
-    // In case no new packets get acknowledged, it is possible packets are
-    // detected lost because of time based loss detection. Cancel blackhole
-    // detection if there is no packets in flight.
-    blackhole_detector_.StopDetection(/*permanent=*/false);
-  }
-
-  if (send_stop_waiting) {
-    ++stop_waiting_count_;
-  } else {
-    stop_waiting_count_ = 0;
-  }
-}
-
-void QuicConnection::SetSessionNotifier(
-    SessionNotifierInterface* session_notifier) {
-  sent_packet_manager_.SetSessionNotifier(session_notifier);
-}
-
-void QuicConnection::SetDataProducer(
-    QuicStreamFrameDataProducer* data_producer) {
-  framer_.set_data_producer(data_producer);
-}
-
-void QuicConnection::SetTransmissionType(TransmissionType type) {
-  packet_creator_.SetTransmissionType(type);
-}
-
-void QuicConnection::UpdateReleaseTimeIntoFuture() {
-  QUICHE_DCHECK(supports_release_time_);
-
-  const QuicTime::Delta prior_max_release_time = release_time_into_future_;
-  release_time_into_future_ = std::max(
-      QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
-      std::min(
-          QuicTime::Delta::FromMilliseconds(
-              GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
-          sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
-              GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
-  QUIC_DVLOG(3) << "Updated max release time delay from "
-                << prior_max_release_time << " to "
-                << release_time_into_future_;
-}
-
-void QuicConnection::ResetAckStates() {
-  ack_alarm_->Cancel();
-  stop_waiting_count_ = 0;
-  uber_received_packet_manager_.ResetAckStates(encryption_level_);
-}
-
-MessageStatus QuicConnection::SendMessage(
-    QuicMessageId message_id, absl::Span<quiche::QuicheMemSlice> message,
-    bool flush) {
-  if (!VersionSupportsMessageFrames(transport_version())) {
-    QUIC_BUG(quic_bug_10511_38)
-        << "MESSAGE frame is not supported for version " << transport_version();
-    return MESSAGE_STATUS_UNSUPPORTED;
-  }
-  if (MemSliceSpanTotalSize(message) > GetCurrentLargestMessagePayload()) {
-    return MESSAGE_STATUS_TOO_LARGE;
-  }
-  if (!connected_ || (!flush && !CanWrite(HAS_RETRANSMITTABLE_DATA))) {
-    return MESSAGE_STATUS_BLOCKED;
-  }
-  ScopedPacketFlusher flusher(this);
-  return packet_creator_.AddMessageFrame(message_id, message);
-}
-
-QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
-  return packet_creator_.GetCurrentLargestMessagePayload();
-}
-
-QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
-  return packet_creator_.GetGuaranteedLargestMessagePayload();
-}
-
-uint32_t QuicConnection::cipher_id() const {
-  if (version().KnowsWhichDecrypterToUse()) {
-    return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
-  }
-  return framer_.decrypter()->cipher_id();
-}
-
-EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
-  if (perspective_ == Perspective::IS_CLIENT) {
-    return encryption_level_;
-  }
-  if (IsHandshakeComplete()) {
-    // A forward secure packet has been received.
-    QUIC_BUG_IF(quic_bug_12714_31,
-                encryption_level_ != ENCRYPTION_FORWARD_SECURE)
-        << ENDPOINT << "Unexpected connection close encryption level "
-        << encryption_level_;
-    return ENCRYPTION_FORWARD_SECURE;
-  }
-  if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
-    if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
-      if (version().HasIetfInvariantHeader()) {
-        QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
-      } else {
-        QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
-      }
-    }
-    return ENCRYPTION_ZERO_RTT;
-  }
-  return ENCRYPTION_INITIAL;
-}
-
-void QuicConnection::MaybeBundleCryptoDataWithAcks() {
-  QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
-  if (IsHandshakeConfirmed()) {
-    return;
-  }
-  PacketNumberSpace space = HANDSHAKE_DATA;
-  if (perspective() == Perspective::IS_SERVER &&
-      framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
-    // On the server side, sends INITIAL data with INITIAL ACK if initial key is
-    // available.
-    space = INITIAL_DATA;
-  }
-  const QuicTime ack_timeout =
-      uber_received_packet_manager_.GetAckTimeout(space);
-  if (!ack_timeout.IsInitialized() ||
-      (ack_timeout > clock_->ApproximateNow() &&
-       ack_timeout > uber_received_packet_manager_.GetEarliestAckTimeout())) {
-    // No pending ACK of space.
-    return;
-  }
-  if (coalesced_packet_.length() > 0) {
-    // Do not bundle CRYPTO data if the ACK could be coalesced with other
-    // packets.
-    return;
-  }
-
-  if (!framer_.HasAnEncrypterForSpace(space)) {
-    QUIC_BUG(quic_bug_10511_39)
-        << ENDPOINT
-        << "Try to bundle crypto with ACK with missing key of space "
-        << PacketNumberSpaceToString(space);
-    return;
-  }
-
-  sent_packet_manager_.RetransmitDataOfSpaceIfAny(space);
-}
-
-void QuicConnection::SendAllPendingAcks() {
-  QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
-  QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
-  ack_alarm_->Cancel();
-  QuicTime earliest_ack_timeout =
-      uber_received_packet_manager_.GetEarliestAckTimeout();
-  QUIC_BUG_IF(quic_bug_12714_32, !earliest_ack_timeout.IsInitialized());
-  MaybeBundleCryptoDataWithAcks();
-  earliest_ack_timeout = uber_received_packet_manager_.GetEarliestAckTimeout();
-  if (!earliest_ack_timeout.IsInitialized()) {
-    return;
-  }
-  for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
-    const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
-        static_cast<PacketNumberSpace>(i));
-    if (!ack_timeout.IsInitialized()) {
-      continue;
-    }
-    if (!framer_.HasAnEncrypterForSpace(static_cast<PacketNumberSpace>(i))) {
-      // The key has been dropped.
-      continue;
-    }
-    if (ack_timeout > clock_->ApproximateNow() &&
-        ack_timeout > earliest_ack_timeout) {
-      // Always send the earliest ACK to make forward progress in case alarm
-      // fires early.
-      continue;
-    }
-    QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space "
-                  << PacketNumberSpaceToString(
-                         static_cast<PacketNumberSpace>(i));
-    ScopedEncryptionLevelContext context(
-        this, QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
-    QuicFrames frames;
-    frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
-        static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
-    const bool flushed = packet_creator_.FlushAckFrame(frames);
-    if (!flushed) {
-      // Connection is write blocked.
-      QUIC_BUG_IF(quic_bug_12714_33,
-                  !writer_->IsWriteBlocked() && !LimitedByAmplificationFactor())
-          << "Writer not blocked and not throttled by amplification factor, "
-             "but ACK not flushed for packet space:"
-          << i;
-      break;
-    }
-    ResetAckStates();
-  }
-
-  const QuicTime timeout =
-      uber_received_packet_manager_.GetEarliestAckTimeout();
-  if (timeout.IsInitialized()) {
-    // If there are ACKs pending, re-arm ack alarm.
-    ack_alarm_->Update(timeout, kAlarmGranularity);
-  }
-  // Only try to bundle retransmittable data with ACK frame if default
-  // encryption level is forward secure.
-  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
-      !ShouldBundleRetransmittableFrameWithAck()) {
-    return;
-  }
-  consecutive_num_packets_with_no_retransmittable_frames_ = 0;
-  if (packet_creator_.HasPendingRetransmittableFrames() ||
-      visitor_->WillingAndAbleToWrite()) {
-    // There are pending retransmittable frames.
-    return;
-  }
-
-  visitor_->OnAckNeedsRetransmittableFrame();
-}
-
-bool QuicConnection::ShouldBundleRetransmittableFrameWithAck() const {
-  if (consecutive_num_packets_with_no_retransmittable_frames_ >=
-      max_consecutive_num_packets_with_no_retransmittable_frames_) {
-    return true;
-  }
-  if (bundle_retransmittable_with_pto_ack_ &&
-      (sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
-       sent_packet_manager_.GetConsecutivePtoCount() > 0)) {
-    // Bundle a retransmittable frame with an ACK if the PTO or RTO has fired
-    // in order to recover more quickly in cases of temporary network outage.
-    return true;
-  }
-  return false;
-}
-
-void QuicConnection::MaybeCoalescePacketOfHigherSpace() {
-  if (!connected() || !packet_creator_.HasSoftMaxPacketLength()) {
-    return;
-  }
-  if (fill_coalesced_packet_) {
-    // Make sure MaybeCoalescePacketOfHigherSpace is not re-entrant.
-    QUIC_BUG_IF(quic_coalesce_packet_reentrant,
-                flush_after_coalesce_higher_space_packets_);
-    return;
-  }
-  for (EncryptionLevel retransmission_level :
-       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE}) {
-    // Coalesce HANDSHAKE with INITIAL retransmission, and coalesce 1-RTT with
-    // HANDSHAKE retransmission.
-    const EncryptionLevel coalesced_level =
-        retransmission_level == ENCRYPTION_INITIAL ? ENCRYPTION_HANDSHAKE
-                                                   : ENCRYPTION_FORWARD_SECURE;
-    if (coalesced_packet_.ContainsPacketOfEncryptionLevel(
-            retransmission_level) &&
-        coalesced_packet_.TransmissionTypeOfPacket(retransmission_level) !=
-            NOT_RETRANSMISSION &&
-        framer_.HasEncrypterOfEncryptionLevel(coalesced_level) &&
-        !coalesced_packet_.ContainsPacketOfEncryptionLevel(coalesced_level)) {
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "Trying to coalesce packet of encryption level: "
-                    << EncryptionLevelToString(coalesced_level);
-      fill_coalesced_packet_ = true;
-      sent_packet_manager_.RetransmitDataOfSpaceIfAny(
-          QuicUtils::GetPacketNumberSpace(coalesced_level));
-      fill_coalesced_packet_ = false;
-    }
-  }
-}
-
-bool QuicConnection::FlushCoalescedPacket() {
-  ScopedCoalescedPacketClearer clearer(&coalesced_packet_);
-  if (!connected_) {
-    return false;
-  }
-  if (!version().CanSendCoalescedPackets()) {
-    QUIC_BUG_IF(quic_bug_12714_34, coalesced_packet_.length() > 0);
-    return true;
-  }
-  if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
-      !framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
-    // Initial packet will be re-serialized. Neuter it in case initial key has
-    // been dropped.
-    QUIC_BUG(quic_bug_10511_40)
-        << ENDPOINT
-        << "Coalescer contains initial packet while initial key has "
-           "been dropped.";
-    coalesced_packet_.NeuterInitialPacket();
-  }
-  if (coalesced_packet_.length() == 0) {
-    return true;
-  }
-
-  char buffer[kMaxOutgoingPacketSize];
-  const size_t length = packet_creator_.SerializeCoalescedPacket(
-      coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
-  if (length == 0) {
-    if (packet_creator_
-            .close_connection_if_fail_to_serialzie_coalesced_packet() &&
-        connected_) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(
-          quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 2, 2);
-      CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET,
-                      "Failed to serialize coalesced packet.",
-                      ConnectionCloseBehavior::SILENT_CLOSE);
-    }
-    return false;
-  }
-  if (debug_visitor_ != nullptr) {
-    debug_visitor_->OnCoalescedPacketSent(coalesced_packet_, length);
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet "
-                << coalesced_packet_.ToString(length);
-
-  if (!buffered_packets_.empty() || HandleWriteBlocked()) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Buffering coalesced packet of len: " << length;
-    buffered_packets_.emplace_back(
-        buffer, static_cast<QuicPacketLength>(length),
-        coalesced_packet_.self_address(), coalesced_packet_.peer_address());
-    return true;
-  }
-
-  WriteResult result = writer_->WritePacket(
-      buffer, length, coalesced_packet_.self_address().host(),
-      coalesced_packet_.peer_address(), per_packet_options_);
-  if (IsWriteError(result.status)) {
-    OnWriteError(result.error_code);
-    return false;
-  }
-  if (IsWriteBlockedStatus(result.status)) {
-    visitor_->OnWriteBlocked();
-    if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "Buffering coalesced packet of len: " << length;
-      buffered_packets_.emplace_back(
-          buffer, static_cast<QuicPacketLength>(length),
-          coalesced_packet_.self_address(), coalesced_packet_.peer_address());
-    }
-  }
-  // Account for added padding.
-  if (length > coalesced_packet_.length()) {
-    size_t padding_size = length - coalesced_packet_.length();
-    if (!count_bytes_on_alternative_path_separately_) {
-      if (EnforceAntiAmplificationLimit()) {
-        default_path_.bytes_sent_before_address_validation += padding_size;
-      }
-    } else {
-      QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 5, 5);
-      if (IsDefaultPath(coalesced_packet_.self_address(),
-                        coalesced_packet_.peer_address())) {
-        if (EnforceAntiAmplificationLimit()) {
-          // Include bytes sent even if they are not in flight.
-          default_path_.bytes_sent_before_address_validation += padding_size;
-        }
-      } else {
-        MaybeUpdateBytesSentToAlternativeAddress(
-            coalesced_packet_.peer_address(), padding_size);
-      }
-    }
-    stats_.bytes_sent += padding_size;
-    if (coalesced_packet_.initial_packet() != nullptr &&
-        coalesced_packet_.initial_packet()->transmission_type !=
-            NOT_RETRANSMISSION) {
-      stats_.bytes_retransmitted += padding_size;
-    }
-  }
-  return true;
-}
-
-void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
-  if (version().handshake_protocol != PROTOCOL_TLS1_3) {
-    return;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
-                << " supports multiple packet number spaces";
-  framer_.EnableMultiplePacketNumberSpacesSupport();
-  sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
-  uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport(
-      perspective_);
-}
-
-bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
-  return sent_packet_manager_.supports_multiple_packet_number_spaces();
-}
-
-void QuicConnection::SetLargestReceivedPacketWithAck(
-    QuicPacketNumber new_value) {
-  if (SupportsMultiplePacketNumberSpaces()) {
-    largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
-        last_decrypted_packet_level_)] = new_value;
-  } else {
-    largest_seen_packet_with_ack_ = new_value;
-  }
-}
-
-void QuicConnection::OnForwardProgressMade() {
-  if (!connected_) {
-    return;
-  }
-  if (is_path_degrading_) {
-    visitor_->OnForwardProgressMadeAfterPathDegrading();
-    is_path_degrading_ = false;
-  }
-  if (sent_packet_manager_.HasInFlightPackets()) {
-    // Restart detections if forward progress has been made.
-    blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
-                                         GetNetworkBlackholeDeadline(),
-                                         GetPathMtuReductionDeadline());
-  } else {
-    // Stop detections in quiecense.
-    blackhole_detector_.StopDetection(/*permanent=*/false);
-  }
-  QUIC_BUG_IF(quic_bug_12714_35,
-              perspective_ == Perspective::IS_SERVER &&
-                  default_enable_5rto_blackhole_detection_ &&
-                  blackhole_detector_.IsDetectionInProgress() &&
-                  !sent_packet_manager_.HasInFlightPackets())
-      << ENDPOINT
-      << "Trying to start blackhole detection without no bytes in flight";
-}
-
-QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
-  if (SupportsMultiplePacketNumberSpaces()) {
-    return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
-        last_decrypted_packet_level_)];
-  }
-  return largest_seen_packet_with_ack_;
-}
-
-QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
-  if (SupportsMultiplePacketNumberSpaces()) {
-    return sent_packet_manager_.GetLargestAckedPacket(
-        last_decrypted_packet_level_);
-  }
-  return sent_packet_manager_.GetLargestObserved();
-}
-
-QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
-  return uber_received_packet_manager_.GetLargestObserved(
-      last_decrypted_packet_level_);
-}
-
-bool QuicConnection::EnforceAntiAmplificationLimit() const {
-  return version().SupportsAntiAmplificationLimit() &&
-         perspective_ == Perspective::IS_SERVER && !default_path_.validated;
-}
-
-// TODO(danzh) Pass in path object or its reference of some sort to use this
-// method to check anti-amplification limit on non-default path.
-bool QuicConnection::LimitedByAmplificationFactor() const {
-  return EnforceAntiAmplificationLimit() &&
-         default_path_.bytes_sent_before_address_validation >=
-             anti_amplification_factor_ *
-                 default_path_.bytes_received_before_address_validation;
-}
-
-SerializedPacketFate QuicConnection::GetSerializedPacketFate(
-    bool is_mtu_discovery,
-    EncryptionLevel encryption_level) {
-  if (ShouldDiscardPacket(encryption_level)) {
-    return DISCARD;
-  }
-  if (legacy_version_encapsulation_in_progress_) {
-    QUICHE_DCHECK(!is_mtu_discovery);
-    return LEGACY_VERSION_ENCAPSULATE;
-  }
-  if (version().CanSendCoalescedPackets() && !coalescing_done_ &&
-      !is_mtu_discovery) {
-    if (!IsHandshakeConfirmed()) {
-      // Before receiving ACK for any 1-RTT packets, always try to coalesce
-      // packet (except MTU discovery packet).
-      return COALESCE;
-    }
-    if (coalesced_packet_.length() > 0) {
-      // If the coalescer is not empty, let this packet go through coalescer
-      // to avoid potential out of order sending.
-      return COALESCE;
-    }
-  }
-  if (!buffered_packets_.empty() || HandleWriteBlocked()) {
-    return BUFFER;
-  }
-  return SEND_TO_WRITER;
-}
-
-bool QuicConnection::IsHandshakeComplete() const {
-  return visitor_->GetHandshakeState() >= HANDSHAKE_COMPLETE;
-}
-
-bool QuicConnection::IsHandshakeConfirmed() const {
-  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, version().handshake_protocol);
-  return visitor_->GetHandshakeState() == HANDSHAKE_CONFIRMED;
-}
-
-size_t QuicConnection::min_received_before_ack_decimation() const {
-  return uber_received_packet_manager_.min_received_before_ack_decimation();
-}
-
-void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
-  uber_received_packet_manager_.set_min_received_before_ack_decimation(
-      new_value);
-}
-
-const QuicAckFrame& QuicConnection::ack_frame() const {
-  if (SupportsMultiplePacketNumberSpaces()) {
-    return uber_received_packet_manager_.GetAckFrame(
-        QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
-  }
-  return uber_received_packet_manager_.ack_frame();
-}
-
-void QuicConnection::set_client_connection_id(
-    QuicConnectionId client_connection_id) {
-  if (!version().SupportsClientConnectionIds()) {
-    QUIC_BUG_IF(quic_bug_12714_36, !client_connection_id.IsEmpty())
-        << ENDPOINT << "Attempted to use client connection ID "
-        << client_connection_id << " with unsupported version " << version();
-    return;
-  }
-  default_path_.client_connection_id = client_connection_id;
-
-  client_connection_id_is_set_ = true;
-  if (version().HasIetfQuicFrames() && !client_connection_id.IsEmpty()) {
-    if (perspective_ == Perspective::IS_SERVER) {
-      QUICHE_DCHECK(peer_issued_cid_manager_ == nullptr);
-      peer_issued_cid_manager_ =
-          std::make_unique<QuicPeerIssuedConnectionIdManager>(
-              kMinNumOfActiveConnectionIds, client_connection_id, clock_,
-              alarm_factory_, this, context());
-    } else {
-      // Note in Chromium client, set_client_connection_id is not called and
-      // thus self_issued_cid_manager_ should be null.
-      self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
-    }
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
-                  << default_path_.client_connection_id
-                  << " for connection with server connection ID "
-                  << default_path_.server_connection_id;
-  packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
-  framer_.SetExpectedClientConnectionIdLength(
-      default_path_.client_connection_id.length());
-}
-
-void QuicConnection::OnPathDegradingDetected() {
-  is_path_degrading_ = true;
-  visitor_->OnPathDegrading();
-}
-
-void QuicConnection::OnBlackholeDetected() {
-  if (default_enable_5rto_blackhole_detection_ &&
-      !sent_packet_manager_.HasInFlightPackets()) {
-    QUIC_BUG(quic_bug_10511_41)
-        << ENDPOINT
-        << "Blackhole detected, but there is no bytes in flight, version: "
-        << version();
-    // Do not close connection if there is no bytes in flight.
-    return;
-  }
-  CloseConnection(QUIC_TOO_MANY_RTOS, "Network blackhole detected",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicConnection::OnPathMtuReductionDetected() {
-  MaybeRevertToPreviousMtu();
-}
-
-void QuicConnection::OnHandshakeTimeout() {
-  const QuicTime::Delta duration =
-      clock_->ApproximateNow() - stats_.connection_creation_time;
-  std::string error_details = absl::StrCat(
-      "Handshake timeout expired after ", duration.ToDebuggingValue(),
-      ". Timeout:",
-      idle_network_detector_.handshake_timeout().ToDebuggingValue());
-  if (perspective() == Perspective::IS_CLIENT && version().UsesTls()) {
-    absl::StrAppend(&error_details, UndecryptablePacketsInfo());
-  }
-  QUIC_DVLOG(1) << ENDPOINT << error_details;
-  CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicConnection::OnIdleNetworkDetected() {
-  const QuicTime::Delta duration =
-      clock_->ApproximateNow() -
-      idle_network_detector_.last_network_activity_time();
-  std::string error_details = absl::StrCat(
-      "No recent network activity after ", duration.ToDebuggingValue(),
-      ". Timeout:",
-      idle_network_detector_.idle_network_timeout().ToDebuggingValue());
-  if (perspective() == Perspective::IS_CLIENT && version().UsesTls() &&
-      !IsHandshakeComplete()) {
-    absl::StrAppend(&error_details, UndecryptablePacketsInfo());
-  }
-  QUIC_DVLOG(1) << ENDPOINT << error_details;
-  const bool has_consecutive_pto =
-      sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
-      sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
-      sent_packet_manager_.GetConsecutivePtoCount() > 0;
-  if (has_consecutive_pto || visitor_->ShouldKeepConnectionAlive()) {
-    if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail) &&
-        !has_consecutive_pto) {
-      // Include stream information in error detail if there are open streams.
-      QUIC_RELOADABLE_FLAG_COUNT(quic_add_stream_info_to_idle_close_detail);
-      absl::StrAppend(&error_details, ", ",
-                      visitor_->GetStreamsInfoForLogging());
-    }
-    CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
-                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  QuicErrorCode error_code = QUIC_NETWORK_IDLE_TIMEOUT;
-  if (idle_timeout_connection_close_behavior_ ==
-      ConnectionCloseBehavior::
-          SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED) {
-    error_code = QUIC_SILENT_IDLE_TIMEOUT;
-  }
-  CloseConnection(error_code, error_details,
-                  idle_timeout_connection_close_behavior_);
-}
-
-void QuicConnection::OnPeerIssuedConnectionIdRetired() {
-  QUICHE_DCHECK(peer_issued_cid_manager_ != nullptr);
-  QuicConnectionId* default_path_cid =
-      perspective_ == Perspective::IS_CLIENT
-          ? &default_path_.server_connection_id
-          : &default_path_.client_connection_id;
-  QuicConnectionId* alternative_path_cid =
-      perspective_ == Perspective::IS_CLIENT
-          ? &alternative_path_.server_connection_id
-          : &alternative_path_.client_connection_id;
-  bool default_path_and_alternative_path_use_the_same_peer_connection_id =
-      *default_path_cid == *alternative_path_cid;
-  if (!default_path_cid->IsEmpty() &&
-      !peer_issued_cid_manager_->IsConnectionIdActive(*default_path_cid)) {
-    *default_path_cid = QuicConnectionId();
-  }
-  // TODO(haoyuewang) Handle the change for default_path_ & alternatvie_path_
-  // via the same helper function.
-  if (default_path_cid->IsEmpty()) {
-    // Try setting a new connection ID now such that subsequent
-    // RetireConnectionId frames can be sent on the default path.
-    const QuicConnectionIdData* unused_connection_id_data =
-        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-    if (unused_connection_id_data != nullptr) {
-      *default_path_cid = unused_connection_id_data->connection_id;
-      default_path_.stateless_reset_token =
-          unused_connection_id_data->stateless_reset_token;
-      if (perspective_ == Perspective::IS_CLIENT) {
-        packet_creator_.SetServerConnectionId(
-            unused_connection_id_data->connection_id);
-      } else {
-        packet_creator_.SetClientConnectionId(
-            unused_connection_id_data->connection_id);
-      }
-    }
-  }
-  if (default_path_and_alternative_path_use_the_same_peer_connection_id) {
-    *alternative_path_cid = *default_path_cid;
-    alternative_path_.stateless_reset_token =
-        default_path_.stateless_reset_token;
-  } else if (!alternative_path_cid->IsEmpty() &&
-             !peer_issued_cid_manager_->IsConnectionIdActive(
-                 *alternative_path_cid)) {
-    *alternative_path_cid = EmptyQuicConnectionId();
-    const QuicConnectionIdData* unused_connection_id_data =
-        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-    if (unused_connection_id_data != nullptr) {
-      *alternative_path_cid = unused_connection_id_data->connection_id;
-      alternative_path_.stateless_reset_token =
-          unused_connection_id_data->stateless_reset_token;
-    }
-  }
-
-  std::vector<uint64_t> retired_cid_sequence_numbers =
-      peer_issued_cid_manager_->ConsumeToBeRetiredConnectionIdSequenceNumbers();
-  QUICHE_DCHECK(!retired_cid_sequence_numbers.empty());
-  for (const auto& sequence_number : retired_cid_sequence_numbers) {
-    ++stats_.num_retire_connection_id_sent;
-    visitor_->SendRetireConnectionId(sequence_number);
-  }
-}
-
-bool QuicConnection::SendNewConnectionId(
-    const QuicNewConnectionIdFrame& frame) {
-  visitor_->SendNewConnectionId(frame);
-  ++stats_.num_new_connection_id_sent;
-  return connected_;
-}
-
-void QuicConnection::OnNewConnectionIdIssued(
-    const QuicConnectionId& connection_id) {
-  if (perspective_ == Perspective::IS_SERVER) {
-    visitor_->OnServerConnectionIdIssued(connection_id);
-  }
-}
-
-void QuicConnection::OnSelfIssuedConnectionIdRetired(
-    const QuicConnectionId& connection_id) {
-  if (perspective_ == Perspective::IS_SERVER) {
-    visitor_->OnServerConnectionIdRetired(connection_id);
-  }
-}
-
-void QuicConnection::MaybeUpdateAckTimeout() {
-  if (should_last_packet_instigate_acks_) {
-    return;
-  }
-  should_last_packet_instigate_acks_ = true;
-  uber_received_packet_manager_.MaybeUpdateAckTimeout(
-      /*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_,
-      last_header_.packet_number, last_received_packet_info_.receipt_time,
-      clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
-}
-
-QuicTime QuicConnection::GetPathDegradingDeadline() const {
-  if (!ShouldDetectPathDegrading()) {
-    return QuicTime::Zero();
-  }
-  return clock_->ApproximateNow() +
-         sent_packet_manager_.GetPathDegradingDelay();
-}
-
-bool QuicConnection::ShouldDetectPathDegrading() const {
-  if (!connected_) {
-    return false;
-  }
-  // No path degrading detection before handshake completes.
-  if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
-    return false;
-  }
-  return perspective_ == Perspective::IS_CLIENT && !is_path_degrading_;
-}
-
-QuicTime QuicConnection::GetNetworkBlackholeDeadline() const {
-  if (!ShouldDetectBlackhole()) {
-    return QuicTime::Zero();
-  }
-  QUICHE_DCHECK_LT(0u, num_rtos_for_blackhole_detection_);
-  return clock_->ApproximateNow() +
-         sent_packet_manager_.GetNetworkBlackholeDelay(
-             num_rtos_for_blackhole_detection_);
-}
-
-bool QuicConnection::ShouldDetectBlackhole() const {
-  if (!connected_ || blackhole_detection_disabled_) {
-    return false;
-  }
-  // No blackhole detection before handshake completes.
-  if (default_enable_5rto_blackhole_detection_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
-                                 3, 3);
-    return IsHandshakeComplete();
-  }
-
-  if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
-    return false;
-  }
-  return num_rtos_for_blackhole_detection_ > 0;
-}
-
-QuicTime QuicConnection::GetRetransmissionDeadline() const {
-  if (perspective_ == Perspective::IS_CLIENT &&
-      SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
-      stats_.pto_count == 0 &&
-      !framer_.HasDecrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE) &&
-      !undecryptable_packets_.empty()) {
-    // Retransmits ClientHello quickly when a Handshake or 1-RTT packet is
-    // received prior to having Handshake keys. Adding kAlarmGranulary will
-    // avoid spurious retransmissions in the case of small-scale reordering.
-    return clock_->ApproximateNow() + kAlarmGranularity;
-  }
-  return sent_packet_manager_.GetRetransmissionTime();
-}
-
-bool QuicConnection::SendPathChallenge(
-    const QuicPathFrameBuffer& data_buffer,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    const QuicSocketAddress& effective_peer_address,
-    QuicPacketWriter* writer) {
-  if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
-    return connected_;
-  }
-  if (connection_migration_use_new_cid_) {
-    {
-      QuicConnectionId client_cid, server_cid;
-      FindOnPathConnectionIds(self_address, effective_peer_address, &client_cid,
-                              &server_cid);
-      QuicPacketCreator::ScopedPeerAddressContext context(
-          &packet_creator_, peer_address, client_cid, server_cid,
-          connection_migration_use_new_cid_);
-      if (writer == writer_) {
-        ScopedPacketFlusher flusher(this);
-        // It's on current path, add the PATH_CHALLENGE the same way as other
-        // frames. This may cause connection to be closed.
-        packet_creator_.AddPathChallengeFrame(data_buffer);
-      } else {
-        std::unique_ptr<SerializedPacket> probing_packet =
-            packet_creator_.SerializePathChallengeConnectivityProbingPacket(
-                data_buffer);
-        QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet),
-                         NO_RETRANSMITTABLE_DATA);
-        QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
-        WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
-                               peer_address, /*measure_rtt=*/false);
-      }
-    }
-    return connected_;
-  }
-  if (writer == writer_) {
-    ScopedPacketFlusher flusher(this);
-    {
-      // It's on current path, add the PATH_CHALLENGE the same way as other
-      // frames.
-      QuicPacketCreator::ScopedPeerAddressContext context(
-          &packet_creator_, peer_address, /*update_connection_id=*/false);
-      // This may cause connection to be closed.
-      packet_creator_.AddPathChallengeFrame(data_buffer);
-    }
-    // Return outside of the scope so that the flush result can be reflected.
-    return connected_;
-  }
-  std::unique_ptr<SerializedPacket> probing_packet =
-      packet_creator_.SerializePathChallengeConnectivityProbingPacket(
-          data_buffer);
-  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
-  QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
-  WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
-                         peer_address, /*measure_rtt=*/false);
-  return true;
-}
-
-QuicTime QuicConnection::GetRetryTimeout(
-    const QuicSocketAddress& peer_address_to_use,
-    QuicPacketWriter* writer_to_use) const {
-  if (writer_to_use == writer_ && peer_address_to_use == peer_address()) {
-    return clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay();
-  }
-  return clock_->ApproximateNow() +
-         QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
-}
-
-void QuicConnection::ValidatePath(
-    std::unique_ptr<QuicPathValidationContext> context,
-    std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
-  QUICHE_DCHECK(use_path_validator_);
-  if (!connection_migration_use_new_cid_ &&
-      perspective_ == Perspective::IS_CLIENT &&
-      !IsDefaultPath(context->self_address(), context->peer_address())) {
-    alternative_path_ = PathState(
-        context->self_address(), context->peer_address(),
-        default_path_.client_connection_id, default_path_.server_connection_id,
-        default_path_.stateless_reset_token);
-  }
-  if (path_validator_.HasPendingPathValidation()) {
-    // Cancel and fail any earlier validation.
-    path_validator_.CancelPathValidation();
-  }
-  if (connection_migration_use_new_cid_ &&
-      perspective_ == Perspective::IS_CLIENT &&
-      !IsDefaultPath(context->self_address(), context->peer_address())) {
-    if (self_issued_cid_manager_ != nullptr) {
-      self_issued_cid_manager_->MaybeSendNewConnectionIds();
-      if (!connected_) {
-        return;
-      }
-    }
-    if ((self_issued_cid_manager_ != nullptr &&
-         !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
-        (peer_issued_cid_manager_ != nullptr &&
-         !peer_issued_cid_manager_->HasUnusedConnectionId())) {
-      QUIC_DVLOG(1) << "Client cannot start new path validation as there is no "
-                       "requried connection ID is available.";
-      result_delegate->OnPathValidationFailure(std::move(context));
-      return;
-    }
-    QuicConnectionId client_connection_id, server_connection_id;
-    absl::optional<StatelessResetToken> stateless_reset_token;
-    if (self_issued_cid_manager_ != nullptr) {
-      client_connection_id =
-          *self_issued_cid_manager_->ConsumeOneConnectionId();
-    }
-    if (peer_issued_cid_manager_ != nullptr) {
-      const auto* connection_id_data =
-          peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-      server_connection_id = connection_id_data->connection_id;
-      stateless_reset_token = connection_id_data->stateless_reset_token;
-    }
-    alternative_path_ = PathState(context->self_address(),
-                                  context->peer_address(), client_connection_id,
-                                  server_connection_id, stateless_reset_token);
-  }
-  path_validator_.StartPathValidation(std::move(context),
-                                      std::move(result_delegate));
-}
-
-bool QuicConnection::SendPathResponse(
-    const QuicPathFrameBuffer& data_buffer,
-    const QuicSocketAddress& peer_address_to_send,
-    const QuicSocketAddress& effective_peer_address) {
-  if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
-    return false;
-  }
-  QuicConnectionId client_cid, server_cid;
-  if (connection_migration_use_new_cid_) {
-    FindOnPathConnectionIds(last_received_packet_info_.destination_address,
-                            effective_peer_address, &client_cid, &server_cid);
-  }
-  // Send PATH_RESPONSE using the provided peer address. If the creator has been
-  // using a different peer address, it will flush before and after serializing
-  // the current PATH_RESPONSE.
-  QuicPacketCreator::ScopedPeerAddressContext context(
-      &packet_creator_, peer_address_to_send, client_cid, server_cid,
-      connection_migration_use_new_cid_);
-  QUIC_DVLOG(1) << ENDPOINT << "Send PATH_RESPONSE to " << peer_address_to_send;
-  if (default_path_.self_address ==
-      last_received_packet_info_.destination_address) {
-    // The PATH_CHALLENGE is received on the default socket. Respond on the same
-    // socket.
-    return packet_creator_.AddPathResponseFrame(data_buffer);
-  }
-
-  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-  // This PATH_CHALLENGE is received on an alternative socket which should be
-  // used to send PATH_RESPONSE.
-  if (!path_validator_.HasPendingPathValidation() ||
-      path_validator_.GetContext()->self_address() !=
-          last_received_packet_info_.destination_address) {
-    // Ignore this PATH_CHALLENGE if it's received from an uninteresting
-    // socket.
-    return true;
-  }
-  QuicPacketWriter* writer = path_validator_.GetContext()->WriterToUse();
-
-  std::unique_ptr<SerializedPacket> probing_packet =
-      packet_creator_.SerializePathResponseConnectivityProbingPacket(
-          {data_buffer}, /*is_padded=*/true);
-  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
-  QUIC_DVLOG(1) << ENDPOINT
-                << "Send PATH_RESPONSE from alternative socket with address "
-                << last_received_packet_info_.destination_address;
-  // Ignore the return value to treat write error on the alternative writer as
-  // part of network error. If the writer becomes blocked, wait for the peer to
-  // send another PATH_CHALLENGE.
-  WritePacketUsingWriter(std::move(probing_packet), writer,
-                         last_received_packet_info_.destination_address,
-                         peer_address_to_send,
-                         /*measure_rtt=*/false);
-  return true;
-}
-
-void QuicConnection::UpdatePeerAddress(QuicSocketAddress peer_address) {
-  direct_peer_address_ = peer_address;
-  packet_creator_.SetDefaultPeerAddress(peer_address);
-}
-
-void QuicConnection::SendPingAtLevel(EncryptionLevel level) {
-  ScopedEncryptionLevelContext context(this, level);
-  SendControlFrame(QuicFrame(QuicPingFrame()));
-}
-
-bool QuicConnection::HasPendingPathValidation() const {
-  QUICHE_DCHECK(use_path_validator_);
-  return path_validator_.HasPendingPathValidation();
-}
-
-QuicPathValidationContext* QuicConnection::GetPathValidationContext() const {
-  QUICHE_DCHECK(use_path_validator_);
-  return path_validator_.GetContext();
-}
-
-void QuicConnection::CancelPathValidation() {
-  QUICHE_DCHECK(use_path_validator_);
-  path_validator_.CancelPathValidation();
-}
-
-bool QuicConnection::UpdateConnectionIdsOnClientMigration(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address) {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
-  if (IsAlternativePath(self_address, peer_address)) {
-    // Client migration is after path validation.
-    default_path_.client_connection_id = alternative_path_.client_connection_id;
-    default_path_.server_connection_id = alternative_path_.server_connection_id;
-    default_path_.stateless_reset_token =
-        alternative_path_.stateless_reset_token;
-    return true;
-  }
-  // Client migration is without path validation.
-  if (self_issued_cid_manager_ != nullptr) {
-    self_issued_cid_manager_->MaybeSendNewConnectionIds();
-    if (!connected_) {
-      return false;
-    }
-  }
-  if ((self_issued_cid_manager_ != nullptr &&
-       !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
-      (peer_issued_cid_manager_ != nullptr &&
-       !peer_issued_cid_manager_->HasUnusedConnectionId())) {
-    return false;
-  }
-  if (self_issued_cid_manager_ != nullptr) {
-    default_path_.client_connection_id =
-        *self_issued_cid_manager_->ConsumeOneConnectionId();
-  }
-  if (peer_issued_cid_manager_ != nullptr) {
-    const auto* connection_id_data =
-        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
-    default_path_.server_connection_id = connection_id_data->connection_id;
-    default_path_.stateless_reset_token =
-        connection_id_data->stateless_reset_token;
-  }
-  return true;
-}
-
-void QuicConnection::RetirePeerIssuedConnectionIdsNoLongerOnPath() {
-  if (!connection_migration_use_new_cid_ ||
-      peer_issued_cid_manager_ == nullptr) {
-    return;
-  }
-  if (perspective_ == Perspective::IS_CLIENT) {
-    peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
-        {default_path_.server_connection_id,
-         alternative_path_.server_connection_id});
-  } else {
-    peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
-        {default_path_.client_connection_id,
-         alternative_path_.client_connection_id});
-  }
-}
-
-void QuicConnection::RetirePeerIssuedConnectionIdsOnPathValidationFailure() {
-  // The alarm to retire connection IDs no longer on paths is scheduled at the
-  // end of writing and reading packet. On path validation failure, there could
-  // be no packet to write or read. Hence the retirement alarm for the
-  // connection ID associated with the failed path needs to be proactively
-  // scheduled here.
-  if (GetQuicReloadableFlag(
-          quic_retire_cid_on_reverse_path_validation_failure) ||
-      perspective_ == Perspective::IS_CLIENT) {
-    QUIC_RELOADABLE_FLAG_COUNT(
-        quic_retire_cid_on_reverse_path_validation_failure);
-    RetirePeerIssuedConnectionIdsNoLongerOnPath();
-  }
-}
-
-bool QuicConnection::MigratePath(const QuicSocketAddress& self_address,
-                                 const QuicSocketAddress& peer_address,
-                                 QuicPacketWriter* writer,
-                                 bool owns_writer) {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
-  if (!connected_) {
-    if (owns_writer) {
-      delete writer;
-    }
-    return false;
-  }
-  QUICHE_DCHECK(!version().UsesHttp3() || IsHandshakeConfirmed());
-
-  if (connection_migration_use_new_cid_) {
-    if (!UpdateConnectionIdsOnClientMigration(self_address, peer_address)) {
-      if (owns_writer) {
-        delete writer;
-      }
-      return false;
-    }
-    if (packet_creator_.GetServerConnectionId().length() !=
-        default_path_.server_connection_id.length()) {
-      packet_creator_.FlushCurrentPacket();
-    }
-    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
-    packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
-  }
-
-  const auto self_address_change_type = QuicUtils::DetermineAddressChangeType(
-      default_path_.self_address, self_address);
-  const auto peer_address_change_type = QuicUtils::DetermineAddressChangeType(
-      default_path_.peer_address, peer_address);
-  QUICHE_DCHECK(self_address_change_type != NO_CHANGE ||
-                peer_address_change_type != NO_CHANGE);
-  const bool is_port_change = (self_address_change_type == PORT_CHANGE ||
-                               self_address_change_type == NO_CHANGE) &&
-                              (peer_address_change_type == PORT_CHANGE ||
-                               peer_address_change_type == NO_CHANGE);
-  SetSelfAddress(self_address);
-  UpdatePeerAddress(peer_address);
-  SetQuicPacketWriter(writer, owns_writer);
-  MaybeClearQueuedPacketsOnPathChange();
-  OnSuccessfulMigration(is_port_change);
-  return true;
-}
-
-void QuicConnection::OnPathValidationFailureAtClient() {
-  if (connection_migration_use_new_cid_) {
-    QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
-    alternative_path_.Clear();
-  }
-  RetirePeerIssuedConnectionIdsOnPathValidationFailure();
-}
-
-QuicConnectionId QuicConnection::GetOneActiveServerConnectionId() const {
-  if (perspective_ == Perspective::IS_CLIENT ||
-      self_issued_cid_manager_ == nullptr) {
-    return connection_id();
-  }
-  auto active_connection_ids = GetActiveServerConnectionIds();
-  QUIC_BUG_IF(quic_bug_6944, active_connection_ids.empty());
-  if (active_connection_ids.empty() ||
-      std::find(active_connection_ids.begin(), active_connection_ids.end(),
-                connection_id()) != active_connection_ids.end()) {
-    return connection_id();
-  }
-  QUICHE_CODE_COUNT(connection_id_on_default_path_has_been_retired);
-  auto active_connection_id =
-      self_issued_cid_manager_->GetOneActiveConnectionId();
-  return active_connection_id;
-}
-
-std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
-    const {
-  if (self_issued_cid_manager_ == nullptr) {
-    return {default_path_.server_connection_id};
-  }
-  QUICHE_DCHECK(version().HasIetfQuicFrames());
-  return self_issued_cid_manager_->GetUnretiredConnectionIds();
-}
-
-void QuicConnection::CreateConnectionIdManager() {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-
-  if (perspective_ == Perspective::IS_CLIENT) {
-    if (!default_path_.server_connection_id.IsEmpty()) {
-      peer_issued_cid_manager_ =
-          std::make_unique<QuicPeerIssuedConnectionIdManager>(
-              kMinNumOfActiveConnectionIds, default_path_.server_connection_id,
-              clock_, alarm_factory_, this, context());
-    }
-  } else {
-    if (!default_path_.server_connection_id.IsEmpty()) {
-      self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
-    }
-  }
-}
-
-void QuicConnection::SetUnackedMapInitialCapacity() {
-  sent_packet_manager_.ReserveUnackedPacketsInitialCapacity(
-      GetUnackedMapInitialCapacity());
-}
-
-void QuicConnection::SetSourceAddressTokenToSend(absl::string_view token) {
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  if (!packet_creator_.HasRetryToken()) {
-    // Ignore received tokens (via NEW_TOKEN frame) from previous connections
-    // when a RETRY token has been received.
-    packet_creator_.SetRetryToken(std::string(token.data(), token.length()));
-  }
-}
-
-void QuicConnection::MaybeUpdateBytesSentToAlternativeAddress(
-    const QuicSocketAddress& peer_address,
-    QuicByteCount sent_packet_size) {
-  if (!version().SupportsAntiAmplificationLimit() ||
-      perspective_ != Perspective::IS_SERVER) {
-    return;
-  }
-  QUICHE_DCHECK(!IsDefaultPath(default_path_.self_address, peer_address));
-  if (!IsAlternativePath(default_path_.self_address, peer_address)) {
-    QUIC_DLOG(INFO) << "Wrote to uninteresting peer address: " << peer_address
-                    << " default direct_peer_address_ " << direct_peer_address_
-                    << " alternative path peer address "
-                    << alternative_path_.peer_address;
-    return;
-  }
-  if (alternative_path_.validated) {
-    return;
-  }
-  if (alternative_path_.bytes_sent_before_address_validation >=
-      anti_amplification_factor_ *
-          alternative_path_.bytes_received_before_address_validation) {
-    QUIC_LOG_FIRST_N(WARNING, 100)
-        << "Server sent more data than allowed to unverified alternative "
-           "peer address "
-        << peer_address << " bytes sent "
-        << alternative_path_.bytes_sent_before_address_validation
-        << ", bytes received "
-        << alternative_path_.bytes_received_before_address_validation;
-  }
-  alternative_path_.bytes_sent_before_address_validation += sent_packet_size;
-}
-
-void QuicConnection::MaybeUpdateBytesReceivedFromAlternativeAddress(
-    QuicByteCount received_packet_size) {
-  if (!version().SupportsAntiAmplificationLimit() ||
-      perspective_ != Perspective::IS_SERVER ||
-      !IsAlternativePath(last_received_packet_info_.destination_address,
-                         GetEffectivePeerAddressFromCurrentPacket()) ||
-      last_received_packet_info_.received_bytes_counted) {
-    return;
-  }
-  // Only update bytes received if this probing frame is received on the most
-  // recent alternative path.
-  QUICHE_DCHECK(!IsDefaultPath(last_received_packet_info_.destination_address,
-                               GetEffectivePeerAddressFromCurrentPacket()));
-  if (!alternative_path_.validated) {
-    alternative_path_.bytes_received_before_address_validation +=
-        received_packet_size;
-  }
-  last_received_packet_info_.received_bytes_counted = true;
-}
-
-bool QuicConnection::IsDefaultPath(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address) const {
-  return direct_peer_address_ == peer_address &&
-         default_path_.self_address == self_address;
-}
-
-bool QuicConnection::IsAlternativePath(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address) const {
-  return alternative_path_.peer_address == peer_address &&
-         alternative_path_.self_address == self_address;
-}
-
-void QuicConnection::PathState::Clear() {
-  self_address = QuicSocketAddress();
-  peer_address = QuicSocketAddress();
-  client_connection_id = {};
-  server_connection_id = {};
-  validated = false;
-  bytes_received_before_address_validation = 0;
-  bytes_sent_before_address_validation = 0;
-  send_algorithm = nullptr;
-  rtt_stats = absl::nullopt;
-  stateless_reset_token.reset();
-}
-
-QuicConnection::PathState::PathState(PathState&& other) {
-  *this = std::move(other);
-}
-
-QuicConnection::PathState& QuicConnection::PathState::operator=(
-    QuicConnection::PathState&& other) {
-  if (this != &other) {
-    self_address = other.self_address;
-    peer_address = other.peer_address;
-    client_connection_id = other.client_connection_id;
-    server_connection_id = other.server_connection_id;
-    stateless_reset_token = other.stateless_reset_token;
-    validated = other.validated;
-    bytes_received_before_address_validation =
-        other.bytes_received_before_address_validation;
-    bytes_sent_before_address_validation =
-        other.bytes_sent_before_address_validation;
-    send_algorithm = std::move(other.send_algorithm);
-    if (other.rtt_stats.has_value()) {
-      rtt_stats.emplace();
-      rtt_stats->CloneFrom(other.rtt_stats.value());
-    } else {
-      rtt_stats.reset();
-    }
-    other.Clear();
-  }
-  return *this;
-}
-
-bool QuicConnection::IsReceivedPeerAddressValidated() const {
-  QuicSocketAddress current_effective_peer_address =
-      GetEffectivePeerAddressFromCurrentPacket();
-  QUICHE_DCHECK(current_effective_peer_address.IsInitialized());
-  return (alternative_path_.peer_address.host() ==
-              current_effective_peer_address.host() &&
-          alternative_path_.validated) ||
-         (default_path_.validated && default_path_.peer_address.host() ==
-                                         current_effective_peer_address.host());
-}
-
-QuicConnection::ReversePathValidationResultDelegate::
-    ReversePathValidationResultDelegate(
-        QuicConnection* connection,
-        const QuicSocketAddress& direct_peer_address)
-    : QuicPathValidator::ResultDelegate(),
-      connection_(connection),
-      original_direct_peer_address_(direct_peer_address),
-      peer_address_default_path_(connection->direct_peer_address_),
-      peer_address_alternative_path_(
-          connection_->alternative_path_.peer_address),
-      active_effective_peer_migration_type_(
-          connection_->active_effective_peer_migration_type_) {}
-
-void QuicConnection::ReversePathValidationResultDelegate::
-    OnPathValidationSuccess(
-        std::unique_ptr<QuicPathValidationContext> context) {
-  QUIC_DLOG(INFO) << "Successfully validated new path " << *context;
-  if (connection_->IsDefaultPath(context->self_address(),
-                                 context->peer_address())) {
-    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 3, 6);
-    if (connection_->active_effective_peer_migration_type_ == NO_CHANGE) {
-      connection_->quic_bug_10511_43_timestamp_ =
-          connection_->clock_->WallNow();
-      connection_->quic_bug_10511_43_error_detail_ = absl::StrCat(
-          "Reverse path validation on default path from ",
-          context->self_address().ToString(), " to ",
-          context->peer_address().ToString(),
-          " completed without active peer address change: current "
-          "peer address on default path ",
-          connection_->direct_peer_address_.ToString(),
-          ", peer address on default path when the reverse path "
-          "validation was kicked off ",
-          peer_address_default_path_.ToString(),
-          ", peer address on alternative path when the reverse "
-          "path validation was kicked off ",
-          peer_address_alternative_path_.ToString(),
-          ", with active_effective_peer_migration_type_ = ",
-          AddressChangeTypeToString(active_effective_peer_migration_type_),
-          ". The last received packet number ",
-          connection_->last_header_.packet_number.ToString(),
-          " Connection is connected: ", connection_->connected_);
-      QUIC_BUG(quic_bug_10511_43)
-          << connection_->quic_bug_10511_43_error_detail_;
-    }
-    connection_->OnEffectivePeerMigrationValidated();
-  } else {
-    QUICHE_DCHECK(connection_->IsAlternativePath(
-        context->self_address(), context->effective_peer_address()));
-    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 4, 6);
-    QUIC_DVLOG(1) << "Mark alternative peer address "
-                  << context->effective_peer_address() << " validated.";
-    connection_->alternative_path_.validated = true;
-  }
-}
-
-void QuicConnection::ReversePathValidationResultDelegate::
-    OnPathValidationFailure(
-        std::unique_ptr<QuicPathValidationContext> context) {
-  if (!connection_->connected()) {
-    return;
-  }
-  QUIC_DLOG(INFO) << "Fail to validate new path " << *context;
-  if (connection_->IsDefaultPath(context->self_address(),
-                                 context->peer_address())) {
-    // Only act upon validation failure on the default path.
-    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 5, 6);
-    connection_->RestoreToLastValidatedPath(original_direct_peer_address_);
-  } else if (connection_->IsAlternativePath(
-                 context->self_address(), context->effective_peer_address())) {
-    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 6, 6);
-    connection_->alternative_path_.Clear();
-  }
-  connection_->RetirePeerIssuedConnectionIdsOnPathValidationFailure();
-}
-
-QuicConnection::ScopedRetransmissionTimeoutIndicator::
-    ScopedRetransmissionTimeoutIndicator(QuicConnection* connection)
-    : connection_(connection) {
-  QUICHE_DCHECK(!connection_->in_on_retransmission_time_out_)
-      << "ScopedRetransmissionTimeoutIndicator is not supposed to be nested";
-  connection_->in_on_retransmission_time_out_ = true;
-}
-
-QuicConnection::ScopedRetransmissionTimeoutIndicator::
-    ~ScopedRetransmissionTimeoutIndicator() {
-  QUICHE_DCHECK(connection_->in_on_retransmission_time_out_);
-  connection_->in_on_retransmission_time_out_ = false;
-}
-
-void QuicConnection::RestoreToLastValidatedPath(
-    QuicSocketAddress original_direct_peer_address) {
-  QUIC_DLOG(INFO) << "Switch back to use the old peer address "
-                  << alternative_path_.peer_address;
-  if (!alternative_path_.validated) {
-    // If not validated by now, close connection silently so that the following
-    // packets received will be rejected.
-    CloseConnection(QUIC_INTERNAL_ERROR,
-                    "No validated peer address to use after reverse path "
-                    "validation failure.",
-                    ConnectionCloseBehavior::SILENT_CLOSE);
-    return;
-  }
-  MaybeClearQueuedPacketsOnPathChange();
-
-  // Revert congestion control context to old state.
-  OnPeerIpAddressChanged();
-
-  if (alternative_path_.send_algorithm != nullptr) {
-    sent_packet_manager_.SetSendAlgorithm(
-        alternative_path_.send_algorithm.release());
-    sent_packet_manager_.SetRttStats(alternative_path_.rtt_stats.value());
-  } else {
-    QUIC_BUG(quic_bug_10511_42)
-        << "Fail to store congestion controller before migration.";
-  }
-
-  UpdatePeerAddress(original_direct_peer_address);
-  SetDefaultPathState(std::move(alternative_path_));
-
-  active_effective_peer_migration_type_ = NO_CHANGE;
-  ++stats_.num_invalid_peer_migration;
-  // The reverse path validation failed because of alarm firing, flush all the
-  // pending writes previously throttled by anti-amplification limit.
-  WriteIfNotBlocked();
-}
-
-std::unique_ptr<SendAlgorithmInterface>
-QuicConnection::OnPeerIpAddressChanged() {
-  QUICHE_DCHECK(validate_client_addresses_);
-  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
-      sent_packet_manager_.OnConnectionMigration(
-          /*reset_send_algorithm=*/true);
-  // OnConnectionMigration() should have marked in-flight packets to be
-  // retransmitted if there is any.
-  QUICHE_DCHECK(!sent_packet_manager_.HasInFlightPackets());
-  // OnConnectionMigration() may have changed the retransmission timer, so
-  // re-arm it.
-  SetRetransmissionAlarm();
-  // Stop detections in quiecense.
-  blackhole_detector_.StopDetection(/*permanent=*/false);
-  return old_send_algorithm;
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
deleted file mode 100644
index 7f4ac8b..0000000
--- a/quic/core/quic_connection.h
+++ /dev/null
@@ -1,2290 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The entity that handles framing writes for a Quic client or server.
-// Each QuicSession will have a connection associated with it.
-//
-// On the server side, the Dispatcher handles the raw reads, and hands off
-// packets via ProcessUdpPacket for framing and processing.
-//
-// On the client side, the Connection handles the raw reads, as well as the
-// processing.
-//
-// Note: this class is not thread-safe.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_max_streams_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_blocked_writer_interface.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_connection_id_manager.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_idle_network_detector.h"
-#include "quic/core/quic_mtu_discovery.h"
-#include "quic/core/quic_network_blackhole_detector.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_sent_packet_manager.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/uber_received_packet_manager.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-class QuicClock;
-class QuicConfig;
-class QuicConnection;
-class QuicRandom;
-
-namespace test {
-class QuicConnectionPeer;
-}  // namespace test
-
-// Class that receives callbacks from the connection when frames are received
-// and when other interesting events happen.
-class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
- public:
-  virtual ~QuicConnectionVisitorInterface() {}
-
-  // A simple visitor interface for dealing with a data frame.
-  virtual void OnStreamFrame(const QuicStreamFrame& frame) = 0;
-
-  // Called when a CRYPTO frame containing handshake data is received.
-  virtual void OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
-
-  // The session should process the WINDOW_UPDATE frame, adjusting both stream
-  // and connection level flow control windows.
-  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
-
-  // A BLOCKED frame indicates the peer is flow control blocked
-  // on a specified stream.
-  virtual void OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
-
-  // Called when the stream is reset by the peer.
-  virtual void OnRstStream(const QuicRstStreamFrame& frame) = 0;
-
-  // Called when the connection is going away according to the peer.
-  virtual void OnGoAway(const QuicGoAwayFrame& frame) = 0;
-
-  // Called when |message| has been received.
-  virtual void OnMessageReceived(absl::string_view message) = 0;
-
-  // Called when a HANDSHAKE_DONE frame has been received.
-  virtual void OnHandshakeDoneReceived() = 0;
-
-  // Called when a NEW_TOKEN frame has been received.
-  virtual void OnNewTokenReceived(absl::string_view token) = 0;
-
-  // Called when a MAX_STREAMS frame has been received from the peer.
-  virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
-
-  // Called when a STREAMS_BLOCKED frame has been received from the peer.
-  virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
-
-  // Called when the connection is closed either locally by the framer, or
-  // remotely by the peer.
-  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                                  ConnectionCloseSource source) = 0;
-
-  // Called when the connection failed to write because the socket was blocked.
-  virtual void OnWriteBlocked() = 0;
-
-  // Called once a specific QUIC version is agreed by both endpoints.
-  virtual void OnSuccessfulVersionNegotiation(
-      const ParsedQuicVersion& version) = 0;
-
-  // Called when a packet has been received by the connection, after being
-  // validated and parsed. Only called when the client receives a valid packet
-  // or the server receives a connectivity probing packet.
-  // |is_connectivity_probe| is true if the received packet is a connectivity
-  // probe.
-  virtual void OnPacketReceived(const QuicSocketAddress& self_address,
-                                const QuicSocketAddress& peer_address,
-                                bool is_connectivity_probe) = 0;
-
-  // Called when a blocked socket becomes writable.
-  virtual void OnCanWrite() = 0;
-
-  // Called when the connection needs more data to probe for additional
-  // bandwidth.  Returns true if data was sent, false otherwise.
-  virtual bool SendProbingData() = 0;
-
-  // Called when stateless reset packet is received. Returns true if the
-  // connection needs to be closed.
-  virtual bool ValidateStatelessReset(
-      const quic::QuicSocketAddress& self_address,
-      const quic::QuicSocketAddress& peer_address) = 0;
-
-  // Called when the connection experiences a change in congestion window.
-  virtual void OnCongestionWindowChange(QuicTime now) = 0;
-
-  // Called when the connection receives a packet from a migrated client.
-  virtual void OnConnectionMigration(AddressChangeType type) = 0;
-
-  // Called when the peer seems unreachable over the current path.
-  virtual void OnPathDegrading() = 0;
-
-  // Called when forward progress made after path degrading.
-  virtual void OnForwardProgressMadeAfterPathDegrading() = 0;
-
-  // Called when the connection sends ack after
-  // max_consecutive_num_packets_with_no_retransmittable_frames_ consecutive not
-  // retransmittable packets sent. To instigate an ack from peer, a
-  // retransmittable frame needs to be added.
-  virtual void OnAckNeedsRetransmittableFrame() = 0;
-
-  // Called when an AckFrequency frame need to be sent.
-  virtual void SendAckFrequency(const QuicAckFrequencyFrame& frame) = 0;
-
-  // Called to send a NEW_CONNECTION_ID frame.
-  virtual void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
-
-  // Called to send a RETIRE_CONNECTION_ID frame.
-  virtual void SendRetireConnectionId(uint64_t sequence_number) = 0;
-
-  // Called when server starts to use a server issued connection ID.
-  virtual void OnServerConnectionIdIssued(
-      const QuicConnectionId& server_connection_id) = 0;
-
-  // Called when server stops to use a server issued connection ID.
-  virtual void OnServerConnectionIdRetired(
-      const QuicConnectionId& server_connection_id) = 0;
-
-  // Called to ask if the visitor wants to schedule write resumption as it both
-  // has pending data to write, and is able to write (e.g. based on flow control
-  // limits).
-  // Writes may be pending because they were write-blocked, congestion-throttled
-  // or yielded to other connections.
-  virtual bool WillingAndAbleToWrite() const = 0;
-
-  // Called to ask if the connection should be kept alive and prevented
-  // from timing out, for example if there are outstanding application
-  // transactions expecting a response.
-  virtual bool ShouldKeepConnectionAlive() const = 0;
-
-  // Called to retrieve streams information for logging purpose.
-  virtual std::string GetStreamsInfoForLogging() const = 0;
-
-  // Called when a self address change is observed. Returns true if self address
-  // change is allowed.
-  virtual bool AllowSelfAddressChange() const = 0;
-
-  // Called to get current handshake state.
-  virtual HandshakeState GetHandshakeState() const = 0;
-
-  // Called when a STOP_SENDING frame has been received.
-  virtual void OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
-
-  // Called when a packet of encryption |level| has been successfully decrypted.
-  virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
-
-  // Called when a 1RTT packet has been acknowledged.
-  virtual void OnOneRttPacketAcknowledged() = 0;
-
-  // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
-  virtual void OnHandshakePacketSent() = 0;
-
-  // Called when a key update has occurred.
-  virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
-
-  // Called to generate a decrypter for the next key phase. Each call should
-  // generate the key for phase n+1.
-  virtual std::unique_ptr<QuicDecrypter>
-  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
-  // Called to generate an encrypter for the same key phase of the last
-  // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
-  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-
-  // Called when connection is being closed right before a CONNECTION_CLOSE
-  // frame is serialized, but only on the server and only if forward secure
-  // encryption has already been established.
-  virtual void BeforeConnectionCloseSent() = 0;
-
-  // Called by the server to validate |token| in received INITIAL packets.
-  // Consider the client address gets validated (and therefore remove
-  // amplification factor) once the |token| gets successfully validated.
-  virtual bool ValidateToken(absl::string_view token) = 0;
-
-  // Called by the server to send another token.
-  // Return false if the crypto stream fail to generate one.
-  virtual bool MaybeSendAddressToken() = 0;
-
-  // Whether the server address is known to the connection.
-  virtual bool IsKnownServerAddress(const QuicSocketAddress& address) const = 0;
-};
-
-// Interface which gets callbacks from the QuicConnection at interesting
-// points.  Implementations must not mutate the state of the connection
-// as a result of these callbacks.
-class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
-    : public QuicSentPacketManager::DebugDelegate {
- public:
-  ~QuicConnectionDebugVisitor() override {}
-
-  // Called when a packet has been sent.
-  virtual void OnPacketSent(QuicPacketNumber /*packet_number*/,
-                            QuicPacketLength /*packet_length*/,
-                            bool /*has_crypto_handshake*/,
-                            TransmissionType /*transmission_type*/,
-                            EncryptionLevel /*encryption_level*/,
-                            const QuicFrames& /*retransmittable_frames*/,
-                            const QuicFrames& /*nonretransmittable_frames*/,
-                            QuicTime /*sent_time*/) {}
-
-  // Called when a coalesced packet is successfully serialized.
-  virtual void OnCoalescedPacketSent(
-      const QuicCoalescedPacket& /*coalesced_packet*/, size_t /*length*/) {}
-
-  // Called when a PING frame has been sent.
-  virtual void OnPingSent() {}
-
-  // Called when a packet has been received, but before it is
-  // validated or parsed.
-  virtual void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
-                                const QuicSocketAddress& /*peer_address*/,
-                                const QuicEncryptedPacket& /*packet*/) {}
-
-  // Called when the unauthenticated portion of the header has been parsed.
-  virtual void OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) {}
-
-  // Called when a packet is received with a connection id that does not
-  // match the ID of this connection.
-  virtual void OnIncorrectConnectionId(QuicConnectionId /*connection_id*/) {}
-
-  // Called when an undecryptable packet has been received. If |dropped| is
-  // true, the packet has been dropped. Otherwise, the packet will be queued and
-  // connection will attempt to process it later.
-  virtual void OnUndecryptablePacket(EncryptionLevel /*decryption_level*/,
-                                     bool /*dropped*/) {}
-
-  // Called when attempting to process a previously undecryptable packet.
-  virtual void OnAttemptingToProcessUndecryptablePacket(
-      EncryptionLevel /*decryption_level*/) {}
-
-  // Called when a duplicate packet has been received.
-  virtual void OnDuplicatePacket(QuicPacketNumber /*packet_number*/) {}
-
-  // Called when the protocol version on the received packet doensn't match
-  // current protocol version of the connection.
-  virtual void OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) {}
-
-  // Called when the complete header of a packet has been parsed.
-  virtual void OnPacketHeader(const QuicPacketHeader& /*header*/,
-                              QuicTime /*receive_time*/,
-                              EncryptionLevel /*level*/) {}
-
-  // Called when a StreamFrame has been parsed.
-  virtual void OnStreamFrame(const QuicStreamFrame& /*frame*/) {}
-
-  // Called when a CRYPTO frame containing handshake data is received.
-  virtual void OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
-
-  // Called when a StopWaitingFrame has been parsed.
-  virtual void OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) {}
-
-  // Called when a QuicPaddingFrame has been parsed.
-  virtual void OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {}
-
-  // Called when a Ping has been parsed.
-  virtual void OnPingFrame(const QuicPingFrame& /*frame*/,
-                           QuicTime::Delta /*ping_received_delay*/) {}
-
-  // Called when a GoAway has been parsed.
-  virtual void OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {}
-
-  // Called when a RstStreamFrame has been parsed.
-  virtual void OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {}
-
-  // Called when a ConnectionCloseFrame has been parsed. All forms
-  // of CONNECTION CLOSE are handled, Google QUIC, IETF QUIC
-  // CONNECTION CLOSE/Transport and IETF QUIC CONNECTION CLOSE/Application
-  virtual void OnConnectionCloseFrame(
-      const QuicConnectionCloseFrame& /*frame*/) {}
-
-  // Called when a WindowUpdate has been parsed.
-  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
-                                   const QuicTime& /*receive_time*/) {}
-
-  // Called when a BlockedFrame has been parsed.
-  virtual void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {}
-
-  // Called when a NewConnectionIdFrame has been parsed.
-  virtual void OnNewConnectionIdFrame(
-      const QuicNewConnectionIdFrame& /*frame*/) {}
-
-  // Called when a RetireConnectionIdFrame has been parsed.
-  virtual void OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& /*frame*/) {}
-
-  // Called when a NewTokenFrame has been parsed.
-  virtual void OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {}
-
-  // Called when a MessageFrame has been parsed.
-  virtual void OnMessageFrame(const QuicMessageFrame& /*frame*/) {}
-
-  // Called when a HandshakeDoneFrame has been parsed.
-  virtual void OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) {}
-
-  // Called when a public reset packet has been received.
-  virtual void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) {}
-
-  // Called when a version negotiation packet has been received.
-  virtual void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& /*packet*/) {}
-
-  // Called when the connection is closed.
-  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
-                                  ConnectionCloseSource /*source*/) {}
-
-  // Called when the version negotiation is successful.
-  virtual void OnSuccessfulVersionNegotiation(
-      const ParsedQuicVersion& /*version*/) {}
-
-  // Called when a CachedNetworkParameters is sent to the client.
-  virtual void OnSendConnectionState(
-      const CachedNetworkParameters& /*cached_network_params*/) {}
-
-  // Called when a CachedNetworkParameters are received from the client.
-  virtual void OnReceiveConnectionState(
-      const CachedNetworkParameters& /*cached_network_params*/) {}
-
-  // Called when the connection parameters are set from the supplied
-  // |config|.
-  virtual void OnSetFromConfig(const QuicConfig& /*config*/) {}
-
-  // Called when RTT may have changed, including when an RTT is read from
-  // the config.
-  virtual void OnRttChanged(QuicTime::Delta /*rtt*/) const {}
-
-  // Called when a StopSendingFrame has been parsed.
-  virtual void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) {}
-
-  // Called when a PathChallengeFrame has been parsed.
-  virtual void OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) {}
-
-  // Called when a PathResponseFrame has been parsed.
-  virtual void OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) {}
-
-  // Called when a StreamsBlockedFrame has been parsed.
-  virtual void OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& /*frame*/) {
-  }
-
-  // Called when a MaxStreamsFrame has been parsed.
-  virtual void OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) {}
-
-  // Called when an AckFrequencyFrame has been parsed.
-  virtual void OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) {}
-
-  // Called when |count| packet numbers have been skipped.
-  virtual void OnNPacketNumbersSkipped(QuicPacketCount /*count*/,
-                                       QuicTime /*now*/) {}
-
-  // Called when a packet is serialized but discarded (i.e. not sent).
-  virtual void OnPacketDiscarded(const SerializedPacket& /*packet*/) {}
-
-  // Called for QUIC+TLS versions when we send transport parameters.
-  virtual void OnTransportParametersSent(
-      const TransportParameters& /*transport_parameters*/) {}
-
-  // Called for QUIC+TLS versions when we receive transport parameters.
-  virtual void OnTransportParametersReceived(
-      const TransportParameters& /*transport_parameters*/) {}
-
-  // Called for QUIC+TLS versions when we resume cached transport parameters for
-  // 0-RTT.
-  virtual void OnTransportParametersResumed(
-      const TransportParameters& /*transport_parameters*/) {}
-
-  // Called for QUIC+TLS versions when 0-RTT is rejected.
-  virtual void OnZeroRttRejected(int /*reject_reason*/) {}
-
-  // Called for QUIC+TLS versions when 0-RTT packet gets acked.
-  virtual void OnZeroRttPacketAcked() {}
-
-  // Called on peer address change.
-  virtual void OnPeerAddressChange(AddressChangeType /*type*/,
-                                   QuicTime::Delta /*connection_time*/) {}
-
-  // Called after peer migration is validated.
-  virtual void OnPeerMigrationValidated(QuicTime::Delta /*connection_time*/) {}
-};
-
-class QUIC_EXPORT_PRIVATE QuicConnectionHelperInterface {
- public:
-  virtual ~QuicConnectionHelperInterface() {}
-
-  // Returns a QuicClock to be used for all time related functions.
-  virtual const QuicClock* GetClock() const = 0;
-
-  // Returns a QuicRandom to be used for all random number related functions.
-  virtual QuicRandom* GetRandomGenerator() = 0;
-
-  // Returns a QuicheBufferAllocator to be used for stream send buffers.
-  virtual quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() = 0;
-};
-
-class QUIC_EXPORT_PRIVATE QuicConnection
-    : public QuicFramerVisitorInterface,
-      public QuicBlockedWriterInterface,
-      public QuicPacketCreator::DelegateInterface,
-      public QuicSentPacketManager::NetworkChangeVisitor,
-      public QuicNetworkBlackholeDetector::Delegate,
-      public QuicIdleNetworkDetector::Delegate,
-      public QuicPathValidator::SendDelegate,
-      public QuicConnectionIdManagerVisitorInterface {
- public:
-  // Constructs a new QuicConnection for |connection_id| and
-  // |initial_peer_address| using |writer| to write packets. |owns_writer|
-  // specifies whether the connection takes ownership of |writer|. |helper| must
-  // outlive this connection.
-  QuicConnection(QuicConnectionId server_connection_id,
-                 QuicSocketAddress initial_self_address,
-                 QuicSocketAddress initial_peer_address,
-                 QuicConnectionHelperInterface* helper,
-                 QuicAlarmFactory* alarm_factory,
-                 QuicPacketWriter* writer,
-                 bool owns_writer,
-                 Perspective perspective,
-                 const ParsedQuicVersionVector& supported_versions);
-  QuicConnection(const QuicConnection&) = delete;
-  QuicConnection& operator=(const QuicConnection&) = delete;
-  ~QuicConnection() override;
-
-  // Sets connection parameters from the supplied |config|.
-  void SetFromConfig(const QuicConfig& config);
-
-  // Apply |connection_options| for this connection. Unlike SetFromConfig, this
-  // can happen at anytime in the life of a connection.
-  // Note there is no guarantee that all options can be applied. Components will
-  // only apply cherrypicked options that make sense at the time of the call.
-  void ApplyConnectionOptions(const QuicTagVector& connection_options);
-
-  // Called by the session when sending connection state to the client.
-  virtual void OnSendConnectionState(
-      const CachedNetworkParameters& cached_network_params);
-
-  // Called by the session when receiving connection state from the client.
-  virtual void OnReceiveConnectionState(
-      const CachedNetworkParameters& cached_network_params);
-
-  // Called by the Session when the client has provided CachedNetworkParameters.
-  virtual void ResumeConnectionState(
-      const CachedNetworkParameters& cached_network_params,
-      bool max_bandwidth_resumption);
-
-  // Called by the Session when a max pacing rate for the connection is needed.
-  virtual void SetMaxPacingRate(QuicBandwidth max_pacing_rate);
-
-  // Allows the client to adjust network parameters based on external
-  // information.
-  void AdjustNetworkParameters(
-      const SendAlgorithmInterface::NetworkParams& params);
-  void AdjustNetworkParameters(QuicBandwidth bandwidth,
-                               QuicTime::Delta rtt,
-                               bool allow_cwnd_to_decrease);
-
-  // Install a loss detection tuner. Must be called before OnConfigNegotiated.
-  void SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface> tuner);
-  // Called by the session when session->is_configured() becomes true.
-  void OnConfigNegotiated();
-
-  // Returns the max pacing rate for the connection.
-  virtual QuicBandwidth MaxPacingRate() const;
-
-  // Sends crypto handshake messages of length |write_length| to the peer in as
-  // few packets as possible. Returns the number of bytes consumed from the
-  // data.
-  virtual size_t SendCryptoData(EncryptionLevel level,
-                                size_t write_length,
-                                QuicStreamOffset offset);
-
-  // Send the data of length |write_length| to the peer in as few packets as
-  // possible. Returns the number of bytes consumed from data, and a boolean
-  // indicating if the fin bit was consumed.  This does not indicate the data
-  // has been sent on the wire: it may have been turned into a packet and queued
-  // if the socket was unexpectedly blocked.
-  virtual QuicConsumedData SendStreamData(QuicStreamId id,
-                                          size_t write_length,
-                                          QuicStreamOffset offset,
-                                          StreamSendingState state);
-
-  // Send |frame| to the peer. Returns true if frame is consumed, false
-  // otherwise.
-  virtual bool SendControlFrame(const QuicFrame& frame);
-
-  // Called when stream |id| is reset because of |error|.
-  virtual void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
-
-  // Closes the connection.
-  // |connection_close_behavior| determines whether or not a connection close
-  // packet is sent to the peer.
-  virtual void CloseConnection(
-      QuicErrorCode error,
-      const std::string& details,
-      ConnectionCloseBehavior connection_close_behavior);
-  // Closes the connection, specifying the wire error code |ietf_error|
-  // explicitly.
-  virtual void CloseConnection(
-      QuicErrorCode error,
-      QuicIetfTransportErrorCodes ietf_error,
-      const std::string& details,
-      ConnectionCloseBehavior connection_close_behavior);
-
-  QuicConnectionStats& mutable_stats() { return stats_; }
-
-  int retransmittable_on_wire_ping_count() const {
-    return retransmittable_on_wire_ping_count_;
-  }
-
-  // Returns statistics tracked for this connection.
-  const QuicConnectionStats& GetStats();
-
-  // Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from
-  // the peer.
-  // In a client, the packet may be "stray" and have a different connection ID
-  // than that of this connection.
-  virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
-                                const QuicSocketAddress& peer_address,
-                                const QuicReceivedPacket& packet);
-
-  // QuicBlockedWriterInterface
-  // Called when the underlying connection becomes writable to allow queued
-  // writes to happen.
-  void OnBlockedWriterCanWrite() override;
-
-  bool IsWriterBlocked() const override {
-    return writer_ != nullptr && writer_->IsWriteBlocked();
-  }
-
-  // Called when the caller thinks it's worth a try to write.
-  // TODO(fayang): consider unifying this with QuicSession::OnCanWrite.
-  virtual void OnCanWrite();
-
-  // Called when an error occurs while attempting to write a packet to the
-  // network.
-  void OnWriteError(int error_code);
-
-  // Whether |result| represents a MSG TOO BIG write error.
-  bool IsMsgTooBig(const QuicPacketWriter* writer, const WriteResult& result);
-
-  // If the socket is not blocked, writes queued packets.
-  void WriteIfNotBlocked();
-
-  // Set the packet writer.
-  void SetQuicPacketWriter(QuicPacketWriter* writer, bool owns_writer) {
-    QUICHE_DCHECK(writer != nullptr);
-    if (writer_ != nullptr && owns_writer_) {
-      delete writer_;
-    }
-    writer_ = writer;
-    owns_writer_ = owns_writer;
-  }
-
-  // Set self address.
-  void SetSelfAddress(QuicSocketAddress address) {
-    default_path_.self_address = address;
-  }
-
-  // The version of the protocol this connection is using.
-  QuicTransportVersion transport_version() const {
-    return framer_.transport_version();
-  }
-
-  ParsedQuicVersion version() const { return framer_.version(); }
-
-  // The versions of the protocol that this connection supports.
-  const ParsedQuicVersionVector& supported_versions() const {
-    return framer_.supported_versions();
-  }
-
-  // Mark version negotiated for this connection. Once called, the connection
-  // will ignore received version negotiation packets.
-  void SetVersionNegotiated() {
-    version_negotiated_ = true;
-    if (perspective_ == Perspective::IS_SERVER) {
-      framer_.InferPacketHeaderTypeFromVersion();
-    }
-  }
-
-  // From QuicFramerVisitorInterface
-  void OnError(QuicFramer* framer) override;
-  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
-  void OnPacket() override;
-  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& packet) override;
-  void OnRetryPacket(QuicConnectionId original_connection_id,
-                     QuicConnectionId new_connection_id,
-                     absl::string_view retry_token,
-                     absl::string_view retry_integrity_tag,
-                     absl::string_view retry_without_tag) override;
-  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
-  void OnDecryptedPacket(size_t length, EncryptionLevel level) override;
-  bool OnPacketHeader(const QuicPacketHeader& header) override;
-  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
-  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
-                             EncryptionLevel decryption_level,
-                             bool has_decryption_key) override;
-  bool OnStreamFrame(const QuicStreamFrame& frame) override;
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta ack_delay_time) override;
-  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
-  bool OnAckTimestamp(QuicPacketNumber packet_number,
-                      QuicTime timestamp) override;
-  bool OnAckFrameEnd(QuicPacketNumber start) override;
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
-  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
-  bool OnPingFrame(const QuicPingFrame& frame) override;
-  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
-  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
-  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
-  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
-  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
-  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
-  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) override;
-  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
-  bool OnMessageFrame(const QuicMessageFrame& frame) override;
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
-  void OnPacketComplete() override;
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& token) const override;
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& packet) override;
-  void OnKeyUpdate(KeyUpdateReason reason) override;
-  void OnDecryptedFirstPacketInKeyPhase() override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-
-  // QuicPacketCreator::DelegateInterface
-  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
-                            IsHandshake handshake) override;
-  const QuicFrames MaybeBundleAckOpportunistically() override;
-  QuicPacketBuffer GetPacketBuffer() override;
-  void OnSerializedPacket(SerializedPacket packet) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            const std::string& error_details) override;
-  SerializedPacketFate GetSerializedPacketFate(
-      bool is_mtu_discovery,
-      EncryptionLevel encryption_level) override;
-
-  // QuicSentPacketManager::NetworkChangeVisitor
-  void OnCongestionChange() override;
-  void OnPathMtuIncreased(QuicPacketLength packet_size) override;
-
-  // QuicNetworkBlackholeDetector::Delegate
-  void OnPathDegradingDetected() override;
-  void OnBlackholeDetected() override;
-  void OnPathMtuReductionDetected() override;
-
-  // QuicIdleNetworkDetector::Delegate
-  void OnHandshakeTimeout() override;
-  void OnIdleNetworkDetected() override;
-
-  // QuicConnectionIdManagerVisitorInterface
-  void OnPeerIssuedConnectionIdRetired() override;
-  bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
-  void OnNewConnectionIdIssued(const QuicConnectionId& connection_id) override;
-  void OnSelfIssuedConnectionIdRetired(
-      const QuicConnectionId& connection_id) override;
-
-  // Please note, this is not a const function. For logging purpose, please use
-  // ack_frame().
-  const QuicFrame GetUpdatedAckFrame();
-
-  // Called to send a new connection ID to client if the # of connection ID has
-  // not exceeded the active connection ID limits.
-  void MaybeSendConnectionIdToClient();
-
-  // Called when the handshake completes. On the client side, handshake
-  // completes on receipt of SHLO. On the server side, handshake completes when
-  // SHLO gets ACKed (or a forward secure packet gets decrypted successfully).
-  // TODO(fayang): Add a guard that this only gets called once.
-  void OnHandshakeComplete();
-
-  // Accessors
-  void set_visitor(QuicConnectionVisitorInterface* visitor) {
-    visitor_ = visitor;
-  }
-  void set_debug_visitor(QuicConnectionDebugVisitor* debug_visitor) {
-    debug_visitor_ = debug_visitor;
-    sent_packet_manager_.SetDebugDelegate(debug_visitor);
-  }
-  // Used in Chromium, but not internally.
-  // Must only be called before ping_alarm_ is set.
-  void set_ping_timeout(QuicTime::Delta ping_timeout) {
-    QUICHE_DCHECK(!ping_alarm_->IsSet());
-    ping_timeout_ = ping_timeout;
-  }
-  const QuicTime::Delta ping_timeout() const { return ping_timeout_; }
-  // Sets an initial timeout for the ping alarm when there is no retransmittable
-  // data in flight, allowing for a more aggressive ping alarm in that case.
-  void set_initial_retransmittable_on_wire_timeout(
-      QuicTime::Delta retransmittable_on_wire_timeout) {
-    QUICHE_DCHECK(!ping_alarm_->IsSet());
-    initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
-  }
-  const QuicTime::Delta initial_retransmittable_on_wire_timeout() const {
-    return initial_retransmittable_on_wire_timeout_;
-  }
-  // Used in Chromium, but not internally.
-  void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
-    packet_creator_.set_debug_delegate(visitor);
-  }
-  const QuicSocketAddress& self_address() const {
-    return default_path_.self_address;
-  }
-  const QuicSocketAddress& peer_address() const { return direct_peer_address_; }
-  const QuicSocketAddress& effective_peer_address() const {
-    return default_path_.peer_address;
-  }
-
-  // Returns the server connection ID used on the default path.
-  const QuicConnectionId& connection_id() const {
-    return default_path_.server_connection_id;
-  }
-
-  const QuicConnectionId& client_connection_id() const {
-    return default_path_.client_connection_id;
-  }
-  void set_client_connection_id(QuicConnectionId client_connection_id);
-  const QuicClock* clock() const { return clock_; }
-  QuicRandom* random_generator() const { return random_generator_; }
-  QuicByteCount max_packet_length() const;
-  void SetMaxPacketLength(QuicByteCount length);
-
-  size_t mtu_probe_count() const { return mtu_probe_count_; }
-
-  bool connected() const { return connected_; }
-
-  // Must only be called on client connections.
-  const ParsedQuicVersionVector& server_supported_versions() const {
-    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-    return server_supported_versions_;
-  }
-
-  bool HasQueuedPackets() const { return !buffered_packets_.empty(); }
-  // Testing only. TODO(ianswett): Use a peer instead.
-  size_t NumQueuedPackets() const { return buffered_packets_.size(); }
-
-  // Returns true if the connection has queued packets or frames.
-  bool HasQueuedData() const;
-
-  // Sets the handshake and idle state connection timeouts.
-  void SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
-                          QuicTime::Delta idle_timeout);
-
-  // Called when the ping alarm fires. Causes a ping frame to be sent only
-  // if the retransmission alarm is not running.
-  void OnPingTimeout();
-
-  // Sets up a packet with an QuicAckFrame and sends it out.
-  void SendAck();
-
-  // Called when an RTO fires.  Resets the retransmission alarm if there are
-  // remaining unacked packets.
-  void OnRetransmissionTimeout();
-
-  // Mark all sent 0-RTT encrypted packets for retransmission. Called when new
-  // 0-RTT or 1-RTT key is available in gQUIC, or when 0-RTT is rejected in IETF
-  // QUIC. |reject_reason| is used in TLS-QUIC to log why 0-RTT was rejected.
-  void MarkZeroRttPacketsForRetransmission(int reject_reason);
-
-  // Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the
-  // connection becomes forward secure and hasn't received acks for all packets.
-  void NeuterUnencryptedPackets();
-
-  // Changes the encrypter used for level |level| to |encrypter|.
-  void SetEncrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicEncrypter> encrypter);
-
-  // Called to remove encrypter of encryption |level|.
-  void RemoveEncrypter(EncryptionLevel level);
-
-  // SetNonceForPublicHeader sets the nonce that will be transmitted in the
-  // header of each packet encrypted at the initial encryption level decrypted.
-  // This should only be called on the server side.
-  void SetDiversificationNonce(const DiversificationNonce& nonce);
-
-  // SetDefaultEncryptionLevel sets the encryption level that will be applied
-  // to new packets.
-  void SetDefaultEncryptionLevel(EncryptionLevel level);
-
-  // SetDecrypter sets the primary decrypter, replacing any that already exists.
-  // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
-  // This is intended for cases where one knows that future packets will be
-  // using the new decrypter and the previous decrypter is now obsolete. |level|
-  // indicates the encryption level of the new decrypter.
-  void SetDecrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicDecrypter> decrypter);
-
-  // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
-  // future packets. |level| indicates the encryption level of the decrypter. If
-  // |latch_once_used| is true, then the first time that the decrypter is
-  // successful it will replace the primary decrypter.  Otherwise both
-  // decrypters will remain active and the primary decrypter will be the one
-  // last used.
-  void SetAlternativeDecrypter(EncryptionLevel level,
-                               std::unique_ptr<QuicDecrypter> decrypter,
-                               bool latch_once_used);
-
-  void InstallDecrypter(EncryptionLevel level,
-                        std::unique_ptr<QuicDecrypter> decrypter);
-  void RemoveDecrypter(EncryptionLevel level);
-
-  // Discard keys for the previous key phase.
-  void DiscardPreviousOneRttKeys();
-
-  // Returns true if it is currently allowed to initiate a key update.
-  bool IsKeyUpdateAllowed() const;
-
-  // Returns true if packets have been sent in the current 1-RTT key phase but
-  // none of these packets have been acked.
-  bool HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const;
-
-  // Returns the count of packets received that appeared to attempt a key
-  // update but failed decryption that have been received since the last
-  // successfully decrypted packet.
-  QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
-
-  // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed()
-  // is false. Returns false on error.
-  bool InitiateKeyUpdate(KeyUpdateReason reason);
-
-  const QuicDecrypter* decrypter() const;
-  const QuicDecrypter* alternative_decrypter() const;
-
-  Perspective perspective() const { return perspective_; }
-
-  // Allow easy overriding of truncated connection IDs.
-  void set_can_truncate_connection_ids(bool can) {
-    can_truncate_connection_ids_ = can;
-  }
-
-  // Returns the underlying sent packet manager.
-  const QuicSentPacketManager& sent_packet_manager() const {
-    return sent_packet_manager_;
-  }
-
-  // Returns the underlying sent packet manager.
-  QuicSentPacketManager& sent_packet_manager() { return sent_packet_manager_; }
-
-  UberReceivedPacketManager& received_packet_manager() {
-    return uber_received_packet_manager_;
-  }
-
-  bool CanWrite(HasRetransmittableData retransmittable);
-
-  // When the flusher is out of scope, only the outermost flusher will cause a
-  // flush of the connection and set the retransmission alarm if there is one
-  // pending.  In addition, this flusher can be configured to ensure that an ACK
-  // frame is included in the first packet created, if there's new ack
-  // information to be sent.
-  class QUIC_EXPORT_PRIVATE ScopedPacketFlusher {
-   public:
-    explicit ScopedPacketFlusher(QuicConnection* connection);
-    ~ScopedPacketFlusher();
-
-   private:
-    QuicConnection* connection_;
-    // If true, when this flusher goes out of scope, flush connection and set
-    // retransmission alarm if there is one pending.
-    bool flush_and_set_pending_retransmission_alarm_on_delete_;
-    // Latched connection's handshake_packet_sent_ on creation of this flusher.
-    const bool handshake_packet_sent_;
-  };
-
-  class QUIC_EXPORT_PRIVATE ScopedEncryptionLevelContext {
-   public:
-    ScopedEncryptionLevelContext(QuicConnection* connection,
-                                 EncryptionLevel level);
-    ~ScopedEncryptionLevelContext();
-
-   private:
-    QuicConnection* connection_;
-    // Latched current write encryption level on creation of this context.
-    EncryptionLevel latched_encryption_level_;
-  };
-
-  QuicPacketWriter* writer() { return writer_; }
-  const QuicPacketWriter* writer() const { return writer_; }
-
-  // Sends an MTU discovery packet of size |target_mtu|.  If the packet is
-  // acknowledged by the peer, the maximum packet size will be increased to
-  // |target_mtu|.
-  void SendMtuDiscoveryPacket(QuicByteCount target_mtu);
-
-  // Sends a connectivity probing packet to |peer_address| with
-  // |probing_writer|. If |probing_writer| is nullptr, will use default
-  // packet writer to write the packet. Returns true if subsequent packets can
-  // be written to the probing writer. If connection is V99, a padded IETF QUIC
-  // PATH_CHALLENGE packet is transmitted; if not V99, a Google QUIC padded PING
-  // packet is transmitted.
-  virtual bool SendConnectivityProbingPacket(
-      QuicPacketWriter* probing_writer,
-      const QuicSocketAddress& peer_address);
-
-  // Disable MTU discovery on this connection.
-  void DisableMtuDiscovery();
-
-  // Sends an MTU discovery packet and updates the MTU discovery alarm.
-  void DiscoverMtu();
-
-  // Sets the session notifier on the SentPacketManager.
-  void SetSessionNotifier(SessionNotifierInterface* session_notifier);
-
-  // Set data producer in framer.
-  void SetDataProducer(QuicStreamFrameDataProducer* data_producer);
-
-  // Set transmission type of next sending packets.
-  void SetTransmissionType(TransmissionType type);
-
-  // Tries to send |message| and returns the message status.
-  // If |flush| is false, this will return a MESSAGE_STATUS_BLOCKED
-  // when the connection is deemed unwritable.
-  virtual MessageStatus SendMessage(QuicMessageId message_id,
-                                    absl::Span<quiche::QuicheMemSlice> message,
-                                    bool flush);
-
-  // Returns the largest payload that will fit into a single MESSAGE frame.
-  // Because overhead can vary during a connection, this method should be
-  // checked for every message.
-  QuicPacketLength GetCurrentLargestMessagePayload() const;
-  // Returns the largest payload that will fit into a single MESSAGE frame at
-  // any point during the connection.  This assumes the version and
-  // connection ID lengths do not change.
-  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
-  void SetUnackedMapInitialCapacity();
-
-  virtual int GetUnackedMapInitialCapacity() const {
-    return kDefaultUnackedPacketsInitialCapacity;
-  }
-
-  // Returns the id of the cipher last used for decrypting packets.
-  uint32_t cipher_id() const;
-
-  std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets() {
-    return termination_packets_.get();
-  }
-
-  bool ack_frame_updated() const;
-
-  QuicConnectionHelperInterface* helper() { return helper_; }
-  const QuicConnectionHelperInterface* helper() const { return helper_; }
-  QuicAlarmFactory* alarm_factory() { return alarm_factory_; }
-
-  absl::string_view GetCurrentPacket();
-
-  const QuicFramer& framer() const { return framer_; }
-
-  const QuicPacketCreator& packet_creator() const { return packet_creator_; }
-
-  EncryptionLevel encryption_level() const { return encryption_level_; }
-  EncryptionLevel last_decrypted_level() const {
-    return last_decrypted_packet_level_;
-  }
-
-  const QuicSocketAddress& last_packet_source_address() const {
-    return last_received_packet_info_.source_address;
-  }
-
-  bool fill_up_link_during_probing() const {
-    return fill_up_link_during_probing_;
-  }
-  void set_fill_up_link_during_probing(bool new_value) {
-    fill_up_link_during_probing_ = new_value;
-  }
-
-  // This setting may be changed during the crypto handshake in order to
-  // enable/disable padding of different packets in the crypto handshake.
-  //
-  // This setting should never be set to false in public facing endpoints. It
-  // can only be set to false if there is some other mechanism of preventing
-  // amplification attacks, such as ICE (plus its a non-standard quic).
-  void set_fully_pad_crypto_handshake_packets(bool new_value) {
-    packet_creator_.set_fully_pad_crypto_handshake_packets(new_value);
-  }
-
-  bool fully_pad_during_crypto_handshake() const {
-    return packet_creator_.fully_pad_crypto_handshake_packets();
-  }
-
-  size_t min_received_before_ack_decimation() const;
-  void set_min_received_before_ack_decimation(size_t new_value);
-
-  // If |defer| is true, configures the connection to defer sending packets in
-  // response to an ACK to the SendAlarm. If |defer| is false, packets may be
-  // sent immediately after receiving an ACK.
-  void set_defer_send_in_response_to_packets(bool defer) {
-    defer_send_in_response_to_packets_ = defer;
-  }
-
-  // Sets the current per-packet options for the connection. The QuicConnection
-  // does not take ownership of |options|; |options| must live for as long as
-  // the QuicConnection is in use.
-  void set_per_packet_options(PerPacketOptions* options) {
-    per_packet_options_ = options;
-  }
-
-  bool IsPathDegrading() const { return is_path_degrading_; }
-
-  // Attempts to process any queued undecryptable packets.
-  void MaybeProcessUndecryptablePackets();
-
-  // Queue a coalesced packet.
-  void QueueCoalescedPacket(const QuicEncryptedPacket& packet);
-
-  // Process previously queued coalesced packets. Returns true if any coalesced
-  // packets have been successfully processed.
-  bool MaybeProcessCoalescedPackets();
-
-  enum PacketContent : uint8_t {
-    NO_FRAMES_RECEIVED,
-    // TODO(fkastenholz): Change name when we get rid of padded ping/
-    // pre-version-99.
-    // Also PATH CHALLENGE and PATH RESPONSE.
-    FIRST_FRAME_IS_PING,
-    SECOND_FRAME_IS_PADDING,
-    NOT_PADDED_PING,  // Set if the packet is not {PING, PADDING}.
-  };
-
-  // Whether the handshake completes from this connection's perspective.
-  bool IsHandshakeComplete() const;
-
-  // Whether peer completes handshake. Only used with TLS handshake.
-  bool IsHandshakeConfirmed() const;
-
-  // Returns the largest received packet number sent by peer.
-  QuicPacketNumber GetLargestReceivedPacket() const;
-
-  // Sets the original destination connection ID on the connection.
-  // This is called by QuicDispatcher when it has replaced the connection ID.
-  void SetOriginalDestinationConnectionId(
-      const QuicConnectionId& original_destination_connection_id);
-
-  // Returns the original destination connection ID used for this connection.
-  QuicConnectionId GetOriginalDestinationConnectionId();
-
-  // Called when ACK alarm goes off. Sends ACKs of those packet number spaces
-  // which have expired ACK timeout. Only used when this connection supports
-  // multiple packet number spaces.
-  void SendAllPendingAcks();
-
-  // Returns true if this connection supports multiple packet number spaces.
-  bool SupportsMultiplePacketNumberSpaces() const;
-
-  // For logging purpose.
-  const QuicAckFrame& ack_frame() const;
-
-  // Install encrypter and decrypter for ENCRYPTION_INITIAL using
-  // |connection_id| as the first client-sent destination connection ID,
-  // or the one sent after an IETF Retry.
-  void InstallInitialCrypters(QuicConnectionId connection_id);
-
-  // Called when version is considered negotiated.
-  void OnSuccessfulVersionNegotiation();
-
-  // Called when self migration succeeds after probing.
-  void OnSuccessfulMigration(bool is_port_change);
-
-  // Called for QUIC+TLS versions when we send transport parameters.
-  void OnTransportParametersSent(
-      const TransportParameters& transport_parameters) const;
-
-  // Called for QUIC+TLS versions when we receive transport parameters.
-  void OnTransportParametersReceived(
-      const TransportParameters& transport_parameters) const;
-
-  // Called for QUIC+TLS versions when we resume cached transport parameters for
-  // 0-RTT.
-  void OnTransportParametersResumed(
-      const TransportParameters& transport_parameters) const;
-
-  // Returns true if ack_alarm_ is set.
-  bool HasPendingAcks() const;
-
-  virtual void OnUserAgentIdKnown(const std::string& user_agent_id);
-
-  // Enables Legacy Version Encapsulation using |server_name| as SNI.
-  // Can only be set if this is a client connection.
-  void EnableLegacyVersionEncapsulation(const std::string& server_name);
-
-  bool use_path_validator() const { return use_path_validator_; }
-
-  // If now is close to idle timeout, returns true and sends a connectivity
-  // probing packet to test the connection for liveness. Otherwise, returns
-  // false.
-  bool MaybeTestLiveness();
-
-  // QuicPathValidator::SendDelegate
-  // Send PATH_CHALLENGE using the given path information. If |writer| is the
-  // default writer, PATH_CHALLENGE can be bundled with other frames, and the
-  // containing packet can be buffered if the writer is blocked. Otherwise,
-  // PATH_CHALLENGE will be written in an individual packet and it will be
-  // dropped if write fails. |data_buffer| will be populated with the payload
-  // for future validation.
-  // Return false if the connection is closed thus the caller will not continue
-  // the validation, otherwise return true.
-  bool SendPathChallenge(const QuicPathFrameBuffer& data_buffer,
-                         const QuicSocketAddress& self_address,
-                         const QuicSocketAddress& peer_address,
-                         const QuicSocketAddress& effective_peer_address,
-                         QuicPacketWriter* writer) override;
-  // If |writer| is the default writer and |peer_address| is the same as
-  // peer_address(), return the PTO of this connection. Otherwise, return 3 *
-  // kInitialRtt.
-  QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address_to_use,
-                           QuicPacketWriter* writer_to_use) const override;
-
-  // Start vaildating the path defined by |context| asynchronously and call the
-  // |result_delegate| after validation finishes. If the connection is
-  // validating another path, cancel and fail that validation before starting
-  // this one.
-  void ValidatePath(
-      std::unique_ptr<QuicPathValidationContext> context,
-      std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
-
-  bool can_receive_ack_frequency_frame() const {
-    return can_receive_ack_frequency_frame_;
-  }
-
-  void set_can_receive_ack_frequency_frame() {
-    can_receive_ack_frequency_frame_ = true;
-  }
-
-  bool is_processing_packet() const { return framer_.is_processing_packet(); }
-
-  bool HasPendingPathValidation() const;
-
-  QuicPathValidationContext* GetPathValidationContext() const;
-
-  void CancelPathValidation();
-
-  // Returns true if the migration succeeds, otherwise returns false (e.g., no
-  // available CIDs, connection disconnected, etc).
-  bool MigratePath(const QuicSocketAddress& self_address,
-                   const QuicSocketAddress& peer_address,
-                   QuicPacketWriter* writer,
-                   bool owns_writer);
-
-  // Called to clear the alternative_path_ when path validation failed on the
-  // client side.
-  void OnPathValidationFailureAtClient();
-
-  void SetSourceAddressTokenToSend(absl::string_view token);
-
-  void SendPing() {
-    SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
-  }
-
-  // Returns one server connection ID that associates the current session in the
-  // session map.
-  virtual QuicConnectionId GetOneActiveServerConnectionId() const;
-
-  // Returns all server connection IDs that have not been removed from the
-  // session map.
-  virtual std::vector<QuicConnectionId> GetActiveServerConnectionIds() const;
-
-  bool validate_client_address() const { return validate_client_addresses_; }
-
-  bool connection_migration_use_new_cid() const {
-    return connection_migration_use_new_cid_;
-  }
-
-  bool count_bytes_on_alternative_path_separately() const {
-    return count_bytes_on_alternative_path_separately_;
-  }
-
-  // Instantiates connection ID manager.
-  void CreateConnectionIdManager();
-
-  QuicConnectionContext* context() { return &context_; }
-  const QuicConnectionContext* context() const { return &context_; }
-
-  void set_tracer(std::unique_ptr<QuicConnectionTracer> tracer) {
-    context_.tracer.swap(tracer);
-  }
-
-  void set_bug_listener(std::unique_ptr<QuicBugListener> bug_listener) {
-    context_.bug_listener.swap(bug_listener);
-  }
-
-  absl::optional<QuicWallTime> quic_bug_10511_43_timestamp() const {
-    return quic_bug_10511_43_timestamp_;
-  }
-
-  const std::string& quic_bug_10511_43_error_detail() const {
-    return quic_bug_10511_43_error_detail_;
-  }
-
- protected:
-  // Calls cancel() on all the alarms owned by this connection.
-  void CancelAllAlarms();
-
-  // Send a packet to the peer, and takes ownership of the packet if the packet
-  // cannot be written immediately.
-  virtual void SendOrQueuePacket(SerializedPacket packet);
-
-  // Called after a packet is received from a new effective peer address and is
-  // decrypted. Starts validation of effective peer's address change. Calls
-  // OnConnectionMigration as soon as the address changed.
-  void StartEffectivePeerMigration(AddressChangeType type);
-
-  // Called when a effective peer address migration is validated.
-  virtual void OnEffectivePeerMigrationValidated();
-
-  // Get the effective peer address from the packet being processed. For proxied
-  // connections, effective peer address is the address of the endpoint behind
-  // the proxy. For non-proxied connections, effective peer address is the same
-  // as peer address.
-  //
-  // Notes for implementations in subclasses:
-  // - If the connection is not proxied, the overridden method should use the
-  //   base implementation:
-  //
-  //       return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
-  //
-  // - If the connection is proxied, the overridden method may return either of
-  //   the following:
-  //   a) The address of the endpoint behind the proxy. The address is used to
-  //      drive effective peer migration.
-  //   b) An uninitialized address, meaning the effective peer address does not
-  //      change.
-  virtual QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const;
-
-  // Selects and updates the version of the protocol being used by selecting a
-  // version from |available_versions| which is also supported. Returns true if
-  // such a version exists, false otherwise.
-  bool SelectMutualVersion(const ParsedQuicVersionVector& available_versions);
-
-  // Returns the current per-packet options for the connection.
-  PerPacketOptions* per_packet_options() { return per_packet_options_; }
-
-  AddressChangeType active_effective_peer_migration_type() const {
-    return active_effective_peer_migration_type_;
-  }
-
-  // Sends a connection close packet to the peer and includes an ACK if the ACK
-  // is not empty, the |error| is not PACKET_WRITE_ERROR, and it fits.
-  // |ietf_error| may optionally be be used to directly specify the wire
-  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
-  // QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
-  virtual void SendConnectionClosePacket(QuicErrorCode error,
-                                         QuicIetfTransportErrorCodes ietf_error,
-                                         const std::string& details);
-
-  // Returns true if the packet should be discarded and not sent.
-  virtual bool ShouldDiscardPacket(EncryptionLevel encryption_level);
-
-  // Retransmits packets continuously until blocked by the congestion control.
-  // If there are no packets to retransmit, does not do anything.
-  void SendProbingRetransmissions();
-
-  // Decides whether to send probing retransmissions, and does so if required.
-  void MaybeSendProbingRetransmissions();
-
-  // Notify various components(Session etc.) that this connection has been
-  // migrated.
-  virtual void OnConnectionMigration();
-
-  // Return whether the packet being processed is a connectivity probing.
-  // A packet is a connectivity probing if it is a padded ping packet with self
-  // and/or peer address changes.
-  bool IsCurrentPacketConnectivityProbing() const;
-
-  // Return true iff the writer is blocked, if blocked, call
-  // visitor_->OnWriteBlocked() to add the connection into the write blocked
-  // list.
-  bool HandleWriteBlocked();
-
-  // Whether connection enforces anti-amplification limit.
-  bool EnforceAntiAmplificationLimit() const;
-
-  void AddBytesReceivedBeforeAddressValidation(size_t length) {
-    default_path_.bytes_received_before_address_validation += length;
-  }
-
-  void set_validate_client_addresses(bool value) {
-    validate_client_addresses_ = value;
-  }
-
- private:
-  friend class test::QuicConnectionPeer;
-
-  struct QUIC_EXPORT_PRIVATE PendingPathChallenge {
-    QuicPathFrameBuffer received_path_challenge;
-    QuicSocketAddress peer_address;
-  };
-
-  struct QUIC_EXPORT_PRIVATE PathState {
-    PathState() = default;
-
-    PathState(const QuicSocketAddress& alternative_self_address,
-              const QuicSocketAddress& alternative_peer_address,
-              const QuicConnectionId& client_connection_id,
-              const QuicConnectionId& server_connection_id,
-              absl::optional<StatelessResetToken> stateless_reset_token)
-        : self_address(alternative_self_address),
-          peer_address(alternative_peer_address),
-          client_connection_id(client_connection_id),
-          server_connection_id(server_connection_id),
-          stateless_reset_token(stateless_reset_token) {}
-
-    PathState(PathState&& other);
-
-    PathState& operator=(PathState&& other);
-
-    // Reset all the members.
-    void Clear();
-
-    QuicSocketAddress self_address;
-    // The actual peer address behind the proxy if there is any.
-    QuicSocketAddress peer_address;
-    QuicConnectionId client_connection_id;
-    QuicConnectionId server_connection_id;
-    absl::optional<StatelessResetToken> stateless_reset_token;
-    // True if the peer address has been validated. Address is considered
-    // validated when 1) an address token of the peer address is received and
-    // validated, or 2) a HANDSHAKE packet has been successfully processed on
-    // this path, or 3) a path validation on this path has succeeded.
-    bool validated = false;
-    // Used by the sever to apply anti-amplification limit after this path
-    // becomes the default path if |peer_address| hasn't been validated.
-    QuicByteCount bytes_received_before_address_validation = 0;
-    QuicByteCount bytes_sent_before_address_validation = 0;
-    // Points to the send algorithm on the old default path while connection is
-    // validating migrated peer address. Nullptr otherwise.
-    std::unique_ptr<SendAlgorithmInterface> send_algorithm;
-    absl::optional<RttStats> rtt_stats;
-  };
-
-  using QueuedPacketList = std::list<SerializedPacket>;
-
-  // BufferedPacket stores necessary information (encrypted buffer and self/peer
-  // addresses) of those packets which are serialized but failed to send because
-  // socket is blocked. From unacked packet map and send algorithm's
-  // perspective, buffered packets are treated as sent.
-  struct QUIC_EXPORT_PRIVATE BufferedPacket {
-    BufferedPacket(const SerializedPacket& packet,
-                   const QuicSocketAddress& self_address,
-                   const QuicSocketAddress& peer_address);
-    BufferedPacket(char* encrypted_buffer,
-                   QuicPacketLength encrypted_length,
-                   const QuicSocketAddress& self_address,
-                   const QuicSocketAddress& peer_address);
-    BufferedPacket(const BufferedPacket& other) = delete;
-    BufferedPacket(const BufferedPacket&& other) = delete;
-
-    ~BufferedPacket();
-
-    // encrypted_buffer is owned by buffered packet.
-    absl::string_view encrypted_buffer;
-    // Self and peer addresses when the packet is serialized.
-    const QuicSocketAddress self_address;
-    const QuicSocketAddress peer_address;
-  };
-
-  // ReceivedPacketInfo comprises the received packet information, which can be
-  // retrieved before the packet gets successfully decrypted.
-  struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
-    explicit ReceivedPacketInfo(QuicTime receipt_time)
-        : received_bytes_counted(false), receipt_time(receipt_time) {}
-    ReceivedPacketInfo(const QuicSocketAddress& destination_address,
-                       const QuicSocketAddress& source_address,
-                       QuicTime receipt_time)
-        : received_bytes_counted(false),
-          destination_address(destination_address),
-          source_address(source_address),
-          receipt_time(receipt_time) {}
-
-    bool received_bytes_counted;
-    QuicSocketAddress destination_address;
-    QuicSocketAddress source_address;
-    QuicTime receipt_time;
-  };
-
-  // UndecrytablePacket comprises a undecryptable packet and related
-  // information.
-  struct QUIC_EXPORT_PRIVATE UndecryptablePacket {
-    UndecryptablePacket(const QuicEncryptedPacket& packet,
-                        EncryptionLevel encryption_level,
-                        const ReceivedPacketInfo& packet_info)
-        : packet(packet.Clone()),
-          encryption_level(encryption_level),
-          packet_info(packet_info) {}
-
-    std::unique_ptr<QuicEncryptedPacket> packet;
-    EncryptionLevel encryption_level;
-    ReceivedPacketInfo packet_info;
-  };
-
-  // Handles the reverse path validation result depending on connection state:
-  // whether the connection is validating a migrated peer address or is
-  // validating an alternative path.
-  class ReversePathValidationResultDelegate
-      : public QuicPathValidator::ResultDelegate {
-   public:
-    ReversePathValidationResultDelegate(
-        QuicConnection* connection,
-        const QuicSocketAddress& direct_peer_address);
-
-    void OnPathValidationSuccess(
-        std::unique_ptr<QuicPathValidationContext> context) override;
-
-    void OnPathValidationFailure(
-        std::unique_ptr<QuicPathValidationContext> context) override;
-
-   private:
-    QuicConnection* connection_;
-    QuicSocketAddress original_direct_peer_address_;
-    // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
-    // fixed.
-    QuicSocketAddress peer_address_default_path_;
-    QuicSocketAddress peer_address_alternative_path_;
-    AddressChangeType active_effective_peer_migration_type_;
-  };
-
-  // A class which sets and clears in_on_retransmission_time_out_ when entering
-  // and exiting OnRetransmissionTimeout, respectively.
-  class QUIC_EXPORT_PRIVATE ScopedRetransmissionTimeoutIndicator {
-   public:
-    // |connection| must outlive this indicator.
-    explicit ScopedRetransmissionTimeoutIndicator(QuicConnection* connection);
-
-    ~ScopedRetransmissionTimeoutIndicator();
-
-   private:
-    QuicConnection* connection_;  // Not owned.
-  };
-
-  // If peer uses non-empty connection ID, discards any buffered packets on path
-  // change in IETF QUIC.
-  void MaybeClearQueuedPacketsOnPathChange();
-
-  // Notifies the visitor of the close and marks the connection as disconnected.
-  // Does not send a connection close frame to the peer. It should only be
-  // called by CloseConnection or OnConnectionCloseFrame, OnPublicResetPacket,
-  // and OnAuthenticatedIetfStatelessResetPacket.
-  // |ietf_error| may optionally be be used to directly specify the wire
-  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
-  // QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
-  void TearDownLocalConnectionState(QuicErrorCode error,
-                                    QuicIetfTransportErrorCodes ietf_error,
-                                    const std::string& details,
-                                    ConnectionCloseSource source);
-  void TearDownLocalConnectionState(const QuicConnectionCloseFrame& frame,
-                                    ConnectionCloseSource source);
-
-  // Replace server connection ID on the client side from retry packet or
-  // initial packets with a different source connection ID.
-  void ReplaceInitialServerConnectionId(
-      const QuicConnectionId& new_server_connection_id);
-
-  // Given the server_connection_id find if there is already a corresponding
-  // client connection ID used on default/alternative path. If not, find if
-  // there is an unused connection ID.
-  void FindMatchingOrNewClientConnectionIdOrToken(
-      const PathState& default_path, const PathState& alternative_path,
-      const QuicConnectionId& server_connection_id,
-      QuicConnectionId* client_connection_id,
-      absl::optional<StatelessResetToken>* stateless_reset_token);
-
-  // Returns true and sets connection IDs if (self_address, peer_address)
-  // corresponds to either the default path or alternative path. Returns false
-  // otherwise.
-  bool FindOnPathConnectionIds(const QuicSocketAddress& self_address,
-                               const QuicSocketAddress& peer_address,
-                               QuicConnectionId* client_connection_id,
-                               QuicConnectionId* server_connection_id) const;
-
-  // Set default_path_ to the new_path_state and update the connection IDs in
-  // packet creator accordingly.
-  void SetDefaultPathState(PathState new_path_state);
-
-  // Returns true if header contains valid server connection ID.
-  bool ValidateServerConnectionId(const QuicPacketHeader& header) const;
-
-  // Update the connection IDs when client migrates with/without validation.
-  // Returns false if required connection ID is not available.
-  bool UpdateConnectionIdsOnClientMigration(
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address);
-
-  // Retire active peer issued connection IDs after they are no longer used on
-  // any path.
-  void RetirePeerIssuedConnectionIdsNoLongerOnPath();
-
-  // When path validation fails, proactively retire peer issued connection IDs
-  // no longer used on any path.
-  void RetirePeerIssuedConnectionIdsOnPathValidationFailure();
-
-  // Writes the given packet to socket, encrypted with packet's
-  // encryption_level. Returns true on successful write, and false if the writer
-  // was blocked and the write needs to be tried again. Notifies the
-  // SentPacketManager when the write is successful and sets
-  // retransmittable frames to nullptr.
-  // Saves the connection close packet for later transmission, even if the
-  // writer is write blocked.
-  bool WritePacket(SerializedPacket* packet);
-
-  // Enforce AEAD Confidentiality limits by iniating key update or closing
-  // connection if too many packets have been encrypted with the current key.
-  // Returns true if the connection was closed. Should not be called for
-  // termination packets.
-  bool MaybeHandleAeadConfidentialityLimits(const SerializedPacket& packet);
-
-  // Flush packets buffered in the writer, if any.
-  void FlushPackets();
-
-  // Make sure a stop waiting we got from our peer is sane.
-  // Returns nullptr if the frame is valid or an error string if it was invalid.
-  const char* ValidateStopWaitingFrame(
-      const QuicStopWaitingFrame& stop_waiting);
-
-  // Sends a version negotiation packet to the peer.
-  void SendVersionNegotiationPacket(bool ietf_quic, bool has_length_prefix);
-
-  // Clears any accumulated frames from the last received packet.
-  void ClearLastFrames();
-
-  // Deletes and clears any queued packets.
-  void ClearQueuedPackets();
-
-  // Closes the connection if the sent packet manager is tracking too many
-  // outstanding packets.
-  void CloseIfTooManyOutstandingSentPackets();
-
-  // Writes as many queued packets as possible.  The connection must not be
-  // blocked when this is called.
-  void WriteQueuedPackets();
-
-  // Queues |packet| in the hopes that it can be decrypted in the
-  // future, when a new key is installed.
-  void QueueUndecryptablePacket(const QuicEncryptedPacket& packet,
-                                EncryptionLevel decryption_level);
-
-  // Sends any packets which are a response to the last packet, including both
-  // acks and pending writes if an ack opened the congestion window.
-  void MaybeSendInResponseToPacket();
-
-  // Gets the least unacked packet number, which is the next packet number to be
-  // sent if there are no outstanding packets.
-  QuicPacketNumber GetLeastUnacked() const;
-
-  // Sets the ping alarm to the appropriate value, if any.
-  void SetPingAlarm();
-
-  // Sets the retransmission alarm based on SentPacketManager.
-  void SetRetransmissionAlarm();
-
-  // Sets the MTU discovery alarm if necessary.
-  // |sent_packet_number| is the recently sent packet number.
-  void MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number);
-
-  HasRetransmittableData IsRetransmittable(const SerializedPacket& packet);
-  bool IsTerminationPacket(const SerializedPacket& packet,
-                           QuicErrorCode* error_code);
-
-  // Set the size of the packet we are targeting while doing path MTU discovery.
-  void SetMtuDiscoveryTarget(QuicByteCount target);
-
-  // Returns |suggested_max_packet_size| clamped to any limits set by the
-  // underlying writer, connection, or protocol.
-  QuicByteCount GetLimitedMaxPacketSize(
-      QuicByteCount suggested_max_packet_size);
-
-  // Do any work which logically would be done in OnPacket but can not be
-  // safely done until the packet is validated. Returns true if packet can be
-  // handled, false otherwise.
-  bool ProcessValidatedPacket(const QuicPacketHeader& header);
-
-  // Returns true if received |packet_number| can be processed. Please note,
-  // this is called after packet got decrypted successfully.
-  bool ValidateReceivedPacketNumber(QuicPacketNumber packet_number);
-
-  // Consider receiving crypto frame on non crypto stream as memory corruption.
-  bool MaybeConsiderAsMemoryCorruption(const QuicStreamFrame& frame);
-
-  // Check if the connection has no outstanding data to send and notify
-  // congestion controller if it is the case.
-  void CheckIfApplicationLimited();
-
-  // Sets |current_packet_content_| to |type| if applicable. And
-  // starts effective peer migration if current packet is confirmed not a
-  // connectivity probe and |current_effective_peer_migration_type_| indicates
-  // effective peer address change.
-  // Returns true if connection is still alive.
-  ABSL_MUST_USE_RESULT bool UpdatePacketContent(QuicFrameType type);
-
-  // Called when last received ack frame has been processed.
-  // |send_stop_waiting| indicates whether a stop waiting needs to be sent.
-  // |acked_new_packet| is true if a previously-unacked packet was acked.
-  void PostProcessAfterAckFrame(bool send_stop_waiting, bool acked_new_packet);
-
-  // Updates the release time into the future.
-  void UpdateReleaseTimeIntoFuture();
-
-  // Sends generic path probe packet to the peer. If we are not IETF QUIC, will
-  // always send a padded ping, regardless of whether this is a request or not.
-  bool SendGenericPathProbePacket(QuicPacketWriter* probing_writer,
-                                  const QuicSocketAddress& peer_address);
-
-  // Called when an ACK is about to send. Resets ACK related internal states,
-  // e.g., cancels ack_alarm_, resets
-  // num_retransmittable_packets_received_since_last_ack_sent_ etc.
-  void ResetAckStates();
-
-  // Returns true if the ACK frame should be bundled with ACK-eliciting frame.
-  bool ShouldBundleRetransmittableFrameWithAck() const;
-
-  void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting);
-
-  // Enables multiple packet number spaces support based on handshake protocol
-  // and flags.
-  void MaybeEnableMultiplePacketNumberSpacesSupport();
-
-  // Called to update ACK timeout when an retransmittable frame has been parsed.
-  void MaybeUpdateAckTimeout();
-
-  // Tries to fill coalesced packet with data of higher packet space.
-  void MaybeCoalescePacketOfHigherSpace();
-
-  // Serialize and send coalesced_packet. Returns false if serialization fails
-  // or the write causes errors, otherwise, returns true.
-  bool FlushCoalescedPacket();
-
-  // Returns the encryption level the connection close packet should be sent at,
-  // which is the highest encryption level that peer can guarantee to process.
-  EncryptionLevel GetConnectionCloseEncryptionLevel() const;
-
-  // Called after an ACK frame is successfully processed to update largest
-  // received packet number which contains an ACK frame.
-  void SetLargestReceivedPacketWithAck(QuicPacketNumber new_value);
-
-  // Called when new packets have been acknowledged or old keys have been
-  // discarded.
-  void OnForwardProgressMade();
-
-  // Returns largest received packet number which contains an ACK frame.
-  QuicPacketNumber GetLargestReceivedPacketWithAck() const;
-
-  // Returns the largest packet number that has been sent.
-  QuicPacketNumber GetLargestSentPacket() const;
-
-  // Returns the largest sent packet number that has been ACKed by peer.
-  QuicPacketNumber GetLargestAckedPacket() const;
-
-  // Whether connection is limited by amplification factor.
-  bool LimitedByAmplificationFactor() const;
-
-  // Called before sending a packet to get packet send time and to set the
-  // release time delay in |per_packet_options_|. Return the time when the
-  // packet is scheduled to be released(a.k.a send time), which is NOW + delay.
-  // Returns Now() and does not update release time delay if
-  // |supports_release_time_| is false.
-  QuicTime CalculatePacketSentTime();
-
-  // If we have a previously validate MTU value, e.g. due to a write error,
-  // revert to it and disable MTU discovery.
-  // Return true iff we reverted to a previously validate MTU.
-  bool MaybeRevertToPreviousMtu();
-
-  QuicTime GetPathMtuReductionDeadline() const;
-
-  // Returns path degrading deadline. QuicTime::Zero() means no path degrading
-  // detection is needed.
-  QuicTime GetPathDegradingDeadline() const;
-
-  // Returns true if path degrading should be detected.
-  bool ShouldDetectPathDegrading() const;
-
-  // Returns network blackhole deadline. QuicTime::Zero() means no blackhole
-  // detection is needed.
-  QuicTime GetNetworkBlackholeDeadline() const;
-
-  // Returns true if network blackhole should be detected.
-  bool ShouldDetectBlackhole() const;
-
-  // Returns retransmission deadline.
-  QuicTime GetRetransmissionDeadline() const;
-
-  // Validate connection IDs used during the handshake. Closes the connection
-  // on validation failure.
-  bool ValidateConfigConnectionIds(const QuicConfig& config);
-
-  // Called when ACK alarm goes off. Try to bundle crypto data with ACKs.
-  void MaybeBundleCryptoDataWithAcks();
-
-  // Returns true if an undecryptable packet of |decryption_level| should be
-  // buffered (such that connection can try to decrypt it later).
-  bool ShouldEnqueueUnDecryptablePacket(EncryptionLevel decryption_level,
-                                        bool has_decryption_key) const;
-
-  // Returns string which contains undecryptable packets information.
-  std::string UndecryptablePacketsInfo() const;
-
-  // Sets the max packet length on the packet creator if needed.
-  void MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
-
-  // Sets internal state to enable or disable Legacy Version Encapsulation.
-  void MaybeActivateLegacyVersionEncapsulation();
-  void MaybeDisactivateLegacyVersionEncapsulation();
-
-  // For Google Quic, if the current packet is connectivity probing packet, call
-  // session OnPacketReceived() which eventually sends connectivity probing
-  // response on server side. And no-op on client side. And for both Google Quic
-  // and IETF Quic, start migration if the current packet is a non-probing
-  // packet.
-  // TODO(danzh) rename to MaybeRespondToPeerMigration() when Google Quic is
-  // deprecated.
-  void MaybeRespondToConnectivityProbingOrMigration();
-
-  // Called in IETF QUIC. Start peer migration if a non-probing frame is
-  // received and the current packet number is largest received so far.
-  void MaybeStartIetfPeerMigration();
-
-  // Send PATH_RESPONSE to the given peer address.
-  bool SendPathResponse(const QuicPathFrameBuffer& data_buffer,
-                        const QuicSocketAddress& peer_address_to_send,
-                        const QuicSocketAddress& effective_peer_address);
-
-  // Update both connection's and packet creator's peer address.
-  void UpdatePeerAddress(QuicSocketAddress peer_address);
-
-  // Send PING at encryption level.
-  void SendPingAtLevel(EncryptionLevel level);
-
-  // Write the given packet with |self_address| and |peer_address| using
-  // |writer|.
-  bool WritePacketUsingWriter(std::unique_ptr<SerializedPacket> packet,
-                              QuicPacketWriter* writer,
-                              const QuicSocketAddress& self_address,
-                              const QuicSocketAddress& peer_address,
-                              bool measure_rtt);
-
-  // Increment bytes sent/received on the alternative path if the current packet
-  // is sent/received on that path.
-  void MaybeUpdateBytesSentToAlternativeAddress(
-      const QuicSocketAddress& peer_address,
-      QuicByteCount sent_packet_size);
-  void MaybeUpdateBytesReceivedFromAlternativeAddress(
-      QuicByteCount received_packet_size);
-
-  // TODO(danzh) pass in PathState of the incoming packet or the packet sent
-  // once PathState is used in packet creator. Return true if the given self
-  // address and peer address is the same as the self address and peer address
-  // of the default path.
-  bool IsDefaultPath(const QuicSocketAddress& self_address,
-                     const QuicSocketAddress& peer_address) const;
-
-  // Return true if the |self_address| and |peer_address| is the same as the
-  // self address and peer address of the alternative path.
-  bool IsAlternativePath(const QuicSocketAddress& self_address,
-                         const QuicSocketAddress& peer_address) const;
-
-  // Restore connection default path and congestion control state to the last
-  // validated path and its state. Called after fail to validate peer address
-  // upon detecting a peer migration.
-  void RestoreToLastValidatedPath(
-      QuicSocketAddress original_direct_peer_address);
-
-  // Return true if the current incoming packet is from a peer address that is
-  // validated.
-  bool IsReceivedPeerAddressValidated() const;
-
-  // Called after receiving PATH_CHALLENGE. Update packet content and
-  // alternative path state if the current packet is from a non-default path.
-  // Return true if framer should continue processing the packet.
-  bool OnPathChallengeFrameInternal(const QuicPathChallengeFrame& frame);
-
-  virtual std::unique_ptr<QuicSelfIssuedConnectionIdManager>
-  MakeSelfIssuedConnectionIdManager();
-
-  // Called on peer IP change or restoring to previous address to reset
-  // congestion window, RTT stats, retransmission timer, etc. Only used in IETF
-  // QUIC.
-  std::unique_ptr<SendAlgorithmInterface> OnPeerIpAddressChanged();
-
-  // Process NewConnectionIdFrame either sent from peer or synsthesized from
-  // preferred_address transport parameter.
-  bool OnNewConnectionIdFrameInner(const QuicNewConnectionIdFrame& frame);
-
-  // Called to patch missing client connection ID on default/alternative paths
-  // when a new client connection ID is received.
-  void OnClientConnectionIdAvailable();
-
-  // Returns true if connection needs to set retransmission alarm after a packet
-  // gets sent.
-  bool ShouldSetRetransmissionAlarmOnPacketSent(bool in_flight,
-                                                EncryptionLevel level) const;
-
-  QuicConnectionContext context_;
-
-  QuicFramer framer_;
-
-  // Contents received in the current packet, especially used to identify
-  // whether the current packet is a padded PING packet.
-  PacketContent current_packet_content_;
-  // Set to true as soon as the packet currently being processed has been
-  // detected as a connectivity probing.
-  // Always false outside the context of ProcessUdpPacket().
-  bool is_current_packet_connectivity_probing_;
-
-  bool has_path_challenge_in_current_packet_;
-
-  // Caches the current effective peer migration type if a effective peer
-  // migration might be initiated. As soon as the current packet is confirmed
-  // not a connectivity probe, effective peer migration will start.
-  AddressChangeType current_effective_peer_migration_type_;
-  QuicConnectionHelperInterface* helper_;  // Not owned.
-  QuicAlarmFactory* alarm_factory_;        // Not owned.
-  PerPacketOptions* per_packet_options_;   // Not owned.
-  QuicPacketWriter* writer_;  // Owned or not depending on |owns_writer_|.
-  bool owns_writer_;
-  // Encryption level for new packets. Should only be changed via
-  // SetDefaultEncryptionLevel().
-  EncryptionLevel encryption_level_;
-  const QuicClock* clock_;
-  QuicRandom* random_generator_;
-
-  // On the server, the connection ID is set when receiving the first packet.
-  // This variable ensures we only set it this way once.
-  bool client_connection_id_is_set_;
-
-  // Whether we've already replaced our server connection ID due to receiving an
-  // INITIAL packet with a different source connection ID. Only used on client.
-  bool server_connection_id_replaced_by_initial_ = false;
-  // Address on the last successfully processed packet received from the
-  // direct peer.
-
-  // Other than initialization, do not modify it directly, use
-  // UpdatePeerAddress() instead.
-  QuicSocketAddress direct_peer_address_;
-  // The default path on which the endpoint sends non-probing packets.
-  // The send algorithm and RTT stats of this path are stored in
-  // |sent_packet_manager_| instead of in this object.
-  PathState default_path_;
-
-  // Records change type when the effective peer initiates migration to a new
-  // address. Reset to NO_CHANGE after effective peer migration is validated.
-  AddressChangeType active_effective_peer_migration_type_;
-
-  // Records highest sent packet number when effective peer migration is
-  // started.
-  QuicPacketNumber highest_packet_sent_before_effective_peer_migration_;
-
-  // True if Key Update is supported on this connection.
-  bool support_key_update_for_connection_;
-
-  // Tracks the lowest packet sent in the current key phase. Will be
-  // uninitialized before the first one-RTT packet has been sent or after a
-  // key update but before the first packet has been sent.
-  QuicPacketNumber lowest_packet_sent_in_current_key_phase_;
-
-  // True if the last packet has gotten far enough in the framer to be
-  // decrypted.
-  bool last_packet_decrypted_;
-  QuicByteCount last_size_;  // Size of the last received packet.
-  // TODO(rch): remove this when b/27221014 is fixed.
-  const char* current_packet_data_;  // UDP payload of packet currently being
-                                     // parsed or nullptr.
-  EncryptionLevel last_decrypted_packet_level_;
-  QuicPacketHeader last_header_;
-  bool should_last_packet_instigate_acks_;
-
-  // Track some peer state so we can do less bookkeeping
-  // Largest sequence sent by the peer which had an ack frame (latest ack info).
-  // Do not read or write directly, use GetLargestReceivedPacketWithAck() and
-  // SetLargestReceivedPacketWithAck() instead.
-  QuicPacketNumber largest_seen_packet_with_ack_;
-  // Largest packet number sent by the peer which had an ACK frame per packet
-  // number space. Only used when this connection supports multiple packet
-  // number spaces.
-  QuicPacketNumber largest_seen_packets_with_ack_[NUM_PACKET_NUMBER_SPACES];
-
-  // Largest packet number sent by the peer which had a stop waiting frame.
-  QuicPacketNumber largest_seen_packet_with_stop_waiting_;
-
-  // Collection of packets which were received before encryption was
-  // established, but which could not be decrypted.  We buffer these on
-  // the assumption that they could not be processed because they were
-  // sent with the INITIAL encryption and the CHLO message was lost.
-  std::deque<UndecryptablePacket> undecryptable_packets_;
-
-  // Collection of coalesced packets which were received while processing
-  // the current packet.
-  quiche::QuicheCircularDeque<std::unique_ptr<QuicEncryptedPacket>>
-      received_coalesced_packets_;
-
-  // Maximum number of undecryptable packets the connection will store.
-  size_t max_undecryptable_packets_;
-
-  // Maximum number of tracked packets.
-  QuicPacketCount max_tracked_packets_;
-
-  // Contains the connection close packets if the connection has been closed.
-  std::unique_ptr<std::vector<std::unique_ptr<QuicEncryptedPacket>>>
-      termination_packets_;
-
-  // Determines whether or not a connection close packet is sent to the peer
-  // after idle timeout due to lack of network activity. During the handshake,
-  // a connection close packet is sent, but not after.
-  ConnectionCloseBehavior idle_timeout_connection_close_behavior_;
-
-  // When > 0, close the QUIC connection after this number of RTOs.
-  size_t num_rtos_for_blackhole_detection_;
-
-  // Statistics for this session.
-  QuicConnectionStats stats_;
-
-  UberReceivedPacketManager uber_received_packet_manager_;
-
-  // Indicates how many consecutive times an ack has arrived which indicates
-  // the peer needs to stop waiting for some packets.
-  // TODO(fayang): remove this when deprecating Q043.
-  int stop_waiting_count_;
-
-  // Indicates the retransmission alarm needs to be set.
-  bool pending_retransmission_alarm_;
-
-  // If true, defer sending data in response to received packets to the
-  // SendAlarm.
-  bool defer_send_in_response_to_packets_;
-
-  // The timeout for PING.
-  QuicTime::Delta ping_timeout_;
-
-  // Initial timeout for how long the wire can have no retransmittable packets.
-  QuicTime::Delta initial_retransmittable_on_wire_timeout_;
-
-  // Indicates how many retransmittable-on-wire pings have been emitted without
-  // receiving any new data in between.
-  int consecutive_retransmittable_on_wire_ping_count_;
-
-  // Indicates how many retransmittable-on-wire pings have been emitted.
-  int retransmittable_on_wire_ping_count_;
-
-  // Arena to store class implementations within the QuicConnection.
-  QuicConnectionArena arena_;
-
-  // An alarm that fires when an ACK should be sent to the peer.
-  QuicArenaScopedPtr<QuicAlarm> ack_alarm_;
-  // An alarm that fires when a packet needs to be retransmitted.
-  QuicArenaScopedPtr<QuicAlarm> retransmission_alarm_;
-  // An alarm that is scheduled when the SentPacketManager requires a delay
-  // before sending packets and fires when the packet may be sent.
-  QuicArenaScopedPtr<QuicAlarm> send_alarm_;
-  // An alarm that fires when a ping should be sent.
-  QuicArenaScopedPtr<QuicAlarm> ping_alarm_;
-  // An alarm that fires when an MTU probe should be sent.
-  QuicArenaScopedPtr<QuicAlarm> mtu_discovery_alarm_;
-  // An alarm that fires to process undecryptable packets when new decyrption
-  // keys are available.
-  QuicArenaScopedPtr<QuicAlarm> process_undecryptable_packets_alarm_;
-  // An alarm that fires to discard keys for the previous key phase some time
-  // after a key update has completed.
-  QuicArenaScopedPtr<QuicAlarm> discard_previous_one_rtt_keys_alarm_;
-  // An alarm that fires to discard 0-RTT decryption keys some time after the
-  // first 1-RTT packet has been decrypted. Only used on server connections with
-  // TLS handshaker.
-  QuicArenaScopedPtr<QuicAlarm> discard_zero_rtt_decryption_keys_alarm_;
-  // Neither visitor is owned by this class.
-  QuicConnectionVisitorInterface* visitor_;
-  QuicConnectionDebugVisitor* debug_visitor_;
-
-  QuicPacketCreator packet_creator_;
-
-  // Information about the last received QUIC packet, which may not have been
-  // successfully decrypted and processed.
-  ReceivedPacketInfo last_received_packet_info_;
-
-  // Sent packet manager which tracks the status of packets sent by this
-  // connection and contains the send and receive algorithms to determine when
-  // to send packets.
-  QuicSentPacketManager sent_packet_manager_;
-
-  // Indicates whether connection version has been negotiated.
-  // Always true for server connections.
-  bool version_negotiated_;
-
-  // Tracks if the connection was created by the server or the client.
-  Perspective perspective_;
-
-  // True by default.  False if we've received or sent an explicit connection
-  // close.
-  bool connected_;
-
-  // Destination connection ID of the last received packet. If this ID is the
-  // original server connection ID chosen by client and server replaces it with
-  // a different ID, last_packet_destination_connection_id_ is set to the
-  // replacement connection ID on the server side.
-  QuicConnectionId last_packet_destination_connection_id_;
-
-  // Set to false if the connection should not send truncated connection IDs to
-  // the peer, even if the peer supports it.
-  bool can_truncate_connection_ids_;
-
-  // If non-empty this contains the set of versions received in a
-  // version negotiation packet.
-  ParsedQuicVersionVector server_supported_versions_;
-
-  // The number of MTU probes already sent.
-  size_t mtu_probe_count_;
-
-  // The value of |long_term_mtu_| prior to the last successful MTU increase.
-  // 0 means either
-  // - MTU discovery has never been enabled, or
-  // - MTU discovery has been enabled, but the connection got a packet write
-  //   error with a new (successfully probed) MTU, so it reverted
-  //   |long_term_mtu_| to the value before the last increase.
-  QuicPacketLength previous_validated_mtu_;
-  // The value of the MTU regularly used by the connection. This is different
-  // from the value returned by max_packet_size(), as max_packet_size() returns
-  // the value of the MTU as currently used by the serializer, so if
-  // serialization of an MTU probe is in progress, those two values will be
-  // different.
-  QuicByteCount long_term_mtu_;
-
-  // The maximum UDP payload size that our peer has advertised support for.
-  // Defaults to kDefaultMaxPacketSizeTransportParam until received from peer.
-  QuicByteCount peer_max_packet_size_;
-
-  // The size of the largest packet received from peer.
-  QuicByteCount largest_received_packet_size_;
-
-  // Indicates whether a write error is encountered currently. This is used to
-  // avoid infinite write errors.
-  bool write_error_occurred_;
-
-  // Indicates not to send or process stop waiting frames.
-  bool no_stop_waiting_frames_;
-
-  // Consecutive number of sent packets which have no retransmittable frames.
-  size_t consecutive_num_packets_with_no_retransmittable_frames_;
-
-  // After this many packets sent without retransmittable frames, an artificial
-  // retransmittable frame(a WINDOW_UPDATE) will be created to solicit an ack
-  // from the peer. Default to kMaxConsecutiveNonRetransmittablePackets.
-  size_t max_consecutive_num_packets_with_no_retransmittable_frames_;
-
-  // If true, bundle an ack-eliciting frame with an ACK if the PTO or RTO alarm
-  // have previously fired.
-  bool bundle_retransmittable_with_pto_ack_;
-
-  // If true, the connection will fill up the pipe with extra data whenever the
-  // congestion controller needs it in order to make a bandwidth estimate.  This
-  // is useful if the application pesistently underutilizes the link, but still
-  // relies on having a reasonable bandwidth estimate from the connection, e.g.
-  // for real time applications.
-  bool fill_up_link_during_probing_;
-
-  // If true, the probing retransmission will not be started again.  This is
-  // used to safeguard against an accidental tail recursion in probing
-  // retransmission code.
-  bool probing_retransmission_pending_;
-
-  // Id of latest sent control frame. 0 if no control frame has been sent.
-  QuicControlFrameId last_control_frame_id_;
-
-  // True if the peer is unreachable on the current path.
-  bool is_path_degrading_;
-
-  // True if an ack frame is being processed.
-  bool processing_ack_frame_;
-
-  // True if the writer supports release timestamp.
-  bool supports_release_time_;
-
-  std::unique_ptr<QuicPeerIssuedConnectionIdManager> peer_issued_cid_manager_;
-  std::unique_ptr<QuicSelfIssuedConnectionIdManager> self_issued_cid_manager_;
-
-  // Time this connection can release packets into the future.
-  QuicTime::Delta release_time_into_future_;
-
-  // Payload of most recently transmitted IETF QUIC connectivity
-  // probe packet (the PATH_CHALLENGE payload). This implementation transmits
-  // only one PATH_CHALLENGE per connectivity probe, so only one
-  // QuicPathFrameBuffer is needed.
-  std::unique_ptr<QuicPathFrameBuffer> transmitted_connectivity_probe_payload_;
-
-  // Payloads that were received in the most recent probe. This needs to be a
-  // Deque because the peer might no be using this implementation, and others
-  // might send a packet with more than one PATH_CHALLENGE, so all need to be
-  // saved and responded to.
-  // TODO(danzh) deprecate this field when deprecating
-  // --quic_send_path_response.
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer>
-      received_path_challenge_payloads_;
-
-  // When we receive a RETRY packet or some INITIAL packets, we replace
-  // |server_connection_id_| with the value from that packet and save off the
-  // original value of |server_connection_id_| into
-  // |original_destination_connection_id_| for validation.
-  absl::optional<QuicConnectionId> original_destination_connection_id_;
-
-  // The connection ID that replaces original_destination_connection_id_.
-  QuicConnectionId original_destination_connection_id_replacement_;
-
-  // After we receive a RETRY packet, |retry_source_connection_id_| contains
-  // the source connection ID from that packet.
-  absl::optional<QuicConnectionId> retry_source_connection_id_;
-
-  // Used to store content of packets which cannot be sent because of write
-  // blocked. Packets' encrypted buffers are copied and owned by
-  // buffered_packets_. From unacked_packet_map (and congestion control)'s
-  // perspective, those packets are considered sent.
-  std::list<BufferedPacket> buffered_packets_;
-
-  // Used to coalesce packets of different encryption level into the same UDP
-  // datagram. Connection stops trying to coalesce packets if a forward secure
-  // packet gets acknowledged.
-  QuicCoalescedPacket coalesced_packet_;
-
-  QuicConnectionMtuDiscoverer mtu_discoverer_;
-
-  QuicNetworkBlackholeDetector blackhole_detector_;
-
-  QuicIdleNetworkDetector idle_network_detector_;
-
-  bool blackhole_detection_disabled_ = false;
-
-  const bool default_enable_5rto_blackhole_detection_ =
-      GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2);
-
-  // Whether the Legacy Version Encapsulation feature is enabled.
-  bool legacy_version_encapsulation_enabled_ = false;
-  // Whether we are in the middle of sending a packet using Legacy Version
-  // Encapsulation.
-  bool legacy_version_encapsulation_in_progress_ = false;
-  // SNI to send when using Legacy Version Encapsulation.
-  std::string legacy_version_encapsulation_sni_;
-  // True if next packet is intended to consume remaining space in the
-  // coalescer.
-  bool fill_coalesced_packet_ = false;
-
-  size_t anti_amplification_factor_ =
-      GetQuicFlag(FLAGS_quic_anti_amplification_factor);
-
-  bool use_path_validator_ =
-      GetQuicReloadableFlag(quic_pass_path_response_to_validator);
-
-  // True if AckFrequencyFrame is supported.
-  bool can_receive_ack_frequency_frame_ = false;
-
-  // Indicate whether coalescing is done.
-  bool coalescing_done_ = false;
-
-  // Indicate whether any ENCRYPTION_HANDSHAKE packet has been sent.
-  bool handshake_packet_sent_ = false;
-
-  // Indicate whether to send an AckFrequencyFrame upon handshake completion.
-  // The AckFrequencyFrame sent will updates client's max_ack_delay, which if
-  // chosen properly can reduce the CPU and bandwidth usage for ACK frames.
-  bool send_ack_frequency_on_handshake_completion_ = false;
-
-  // Indicate whether AckFrequency frame has been sent.
-  bool ack_frequency_sent_ = false;
-
-  // True if a 0-RTT decrypter was or is installed at some point in the
-  // connection's lifetime.
-  bool had_zero_rtt_decrypter_ = false;
-
-  // True after the first 1-RTT packet has successfully decrypted.
-  bool have_decrypted_first_one_rtt_packet_ = false;
-
-  // True if we are currently processing OnRetransmissionTimeout.
-  bool in_on_retransmission_time_out_ = false;
-
-  QuicPathValidator path_validator_;
-
-  // Stores information of a path which maybe used as default path in the
-  // future. On the client side, it gets created when the client starts
-  // validating a new path and gets cleared once it becomes the default path or
-  // the path validation fails or replaced by a newer path of interest. On the
-  // server side, alternative_path gets created when server: 1) receives
-  // PATH_CHALLENGE on non-default path, or 2) switches to a not yet validated
-  // default path such that it needs to store the previous validated default
-  // path.
-  // Note that if alternative_path_ stores a validated path information (case
-  // 2), do not override it on receiving PATH_CHALLENGE (case 1).
-  PathState alternative_path_;
-
-  // This field is used to debug b/177312785.
-  QuicFrameType most_recent_frame_type_;
-
-  bool count_bytes_on_alternative_path_separately_ =
-      GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately);
-
-  // If true, upon seeing a new client address, validate the client address.
-  bool validate_client_addresses_ = false;
-
-  // Indicates whether we should proactively validate peer address on a
-  // PATH_CHALLENGE received.
-  bool should_proactively_validate_peer_address_on_path_challenge_ = false;
-
-  // Enable this via reloadable flag once this feature is complete.
-  bool connection_migration_use_new_cid_ = false;
-
-  const bool flush_after_coalesce_higher_space_packets_ =
-      GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets);
-
-  // Records the 1-RTT connection close frame sent.
-  // TODO(b/180103273): remove this after the bug gets fixed.
-  absl::optional<QuicConnectionCloseFrame> connection_close_frame_sent_;
-
-  // If true, send connection close packet on INVALID_VERSION.
-  bool send_connection_close_for_invalid_version_ = false;
-
-  // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
-  // fixed.
-  absl::optional<QuicWallTime> quic_bug_10511_43_timestamp_;
-  std::string quic_bug_10511_43_error_detail_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
diff --git a/quic/core/quic_connection_context.cc b/quic/core/quic_connection_context.cc
deleted file mode 100644
index e77fc43..0000000
--- a/quic/core/quic_connection_context.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_context.h"
-
-#include "common/platform/api/quiche_thread_local.h"
-
-namespace quic {
-namespace {
-DEFINE_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, QuicConnectionContext);
-}  // namespace
-
-// static
-QuicConnectionContext* QuicConnectionContext::Current() {
-  return GET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext);
-}
-
-QuicConnectionContextSwitcher::QuicConnectionContextSwitcher(
-    QuicConnectionContext* new_context)
-    : old_context_(QuicConnectionContext::Current()) {
-  SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, new_context);
-  if (new_context && new_context->tracer) {
-    new_context->tracer->Activate();
-  }
-}
-
-QuicConnectionContextSwitcher::~QuicConnectionContextSwitcher() {
-  QuicConnectionContext* current = QuicConnectionContext::Current();
-  if (current && current->tracer) {
-    current->tracer->Deactivate();
-  }
-  SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, old_context_);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_connection_context.h b/quic/core/quic_connection_context.h
deleted file mode 100644
index a1d76e3..0000000
--- a/quic/core/quic_connection_context.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
-
-#include "absl/strings/str_format.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-// QuicConnectionTracer is responsible for emit trace messages for a single
-// QuicConnection.
-// QuicConnectionTracer is part of the QuicConnectionContext.
-class QUIC_EXPORT_PRIVATE QuicConnectionTracer {
- public:
-  virtual ~QuicConnectionTracer() = default;
-
-  // Emit a trace message from a string literal. The trace may simply remember
-  // the address of the literal in this function and read it at a later time.
-  virtual void PrintLiteral(const char* literal) = 0;
-
-  // Emit a trace message from a string_view. Unlike PrintLiteral, this function
-  // will not read |s| after it returns.
-  virtual void PrintString(absl::string_view s) = 0;
-
-  // Emit a trace message from printf-style arguments.
-  template <typename... Args>
-  void Printf(const absl::FormatSpec<Args...>& format, const Args&... args) {
-    std::string s = absl::StrFormat(format, args...);
-    PrintString(s);
-  }
-
- private:
-  friend class QuicConnectionContextSwitcher;
-
-  // Called by QuicConnectionContextSwitcher, when |this| becomes the current
-  // thread's QUIC connection tracer.
-  //
-  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
-  // constructor/destructor, they always come in pairs.
-  virtual void Activate() {}
-
-  // Called by QuicConnectionContextSwitcher, when |this| stops from being the
-  // current thread's QUIC connection tracer.
-  //
-  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
-  // constructor/destructor, they always come in pairs.
-  virtual void Deactivate() {}
-};
-
-// QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
-// implementation can send the bug information into quic::CurrentBugListener().
-class QUIC_EXPORT_PRIVATE QuicBugListener {
- public:
-  virtual ~QuicBugListener() = default;
-  virtual void OnQuicBug(const char* bug_id, const char* file, int line,
-                         absl::string_view bug_message) = 0;
-};
-
-// QuicConnectionContext is a per-QuicConnection context that includes
-// facilities useable by any part of a QuicConnection. A QuicConnectionContext
-// is owned by a QuicConnection.
-//
-// The 'top-level' QuicConnection functions are responsible for maintaining the
-// thread-local QuicConnectionContext pointer, such that any function called by
-// them(directly or indirectly) can access the context.
-//
-// Like QuicConnection, all facilities in QuicConnectionContext are assumed to
-// be called from a single thread at a time, they are NOT thread-safe.
-struct QUIC_EXPORT_PRIVATE QuicConnectionContext final {
-  // Get the context on the current executing thread. nullptr if the current
-  // function is not called from a 'top-level' QuicConnection function.
-  static QuicConnectionContext* Current();
-
-  std::unique_ptr<QuicConnectionTracer> tracer;
-  std::unique_ptr<QuicBugListener> bug_listener;
-};
-
-// QuicConnectionContextSwitcher is a RAII object used for maintaining the
-// thread-local QuicConnectionContext pointer.
-class QUIC_EXPORT_PRIVATE QuicConnectionContextSwitcher final {
- public:
-  // The constructor switches from QuicConnectionContext::Current() to
-  // |new_context|.
-  explicit QuicConnectionContextSwitcher(QuicConnectionContext* new_context);
-
-  // The destructor switches from QuicConnectionContext::Current() back to the
-  // old context.
-  ~QuicConnectionContextSwitcher();
-
- private:
-  QuicConnectionContext* old_context_;
-};
-
-// Emit a trace message from a string literal to the current tracer(if any).
-inline void QUIC_TRACELITERAL(const char* literal) {
-  QuicConnectionContext* current = QuicConnectionContext::Current();
-  if (current && current->tracer) {
-    current->tracer->PrintLiteral(literal);
-  }
-}
-
-// Emit a trace message from a string_view to the current tracer(if any).
-inline void QUIC_TRACESTRING(absl::string_view s) {
-  QuicConnectionContext* current = QuicConnectionContext::Current();
-  if (current && current->tracer) {
-    current->tracer->PrintString(s);
-  }
-}
-
-// Emit a trace message from printf-style arguments to the current tracer(if
-// any).
-template <typename... Args>
-void QUIC_TRACEPRINTF(const absl::FormatSpec<Args...>& format,
-                      const Args&... args) {
-  QuicConnectionContext* current = QuicConnectionContext::Current();
-  if (current && current->tracer) {
-    current->tracer->Printf(format, args...);
-  }
-}
-
-inline QuicBugListener* CurrentBugListener() {
-  QuicConnectionContext* current = QuicConnectionContext::Current();
-  return (current != nullptr) ? current->bug_listener.get() : nullptr;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
diff --git a/quic/core/quic_connection_context_test.cc b/quic/core/quic_connection_context_test.cc
deleted file mode 100644
index 0f5b2c4..0000000
--- a/quic/core/quic_connection_context_test.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_context.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_thread.h"
-
-using testing::ElementsAre;
-
-namespace quic {
-namespace {
-
-class TraceCollector : public QuicConnectionTracer {
- public:
-  ~TraceCollector() override = default;
-
-  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
-
-  void PrintString(absl::string_view s) override {
-    trace_.push_back(std::string(s));
-  }
-
-  const std::vector<std::string>& trace() const { return trace_; }
-
- private:
-  std::vector<std::string> trace_;
-};
-
-struct FakeConnection {
-  FakeConnection() { context.tracer = std::make_unique<TraceCollector>(); }
-
-  const std::vector<std::string>& trace() const {
-    return static_cast<const TraceCollector*>(context.tracer.get())->trace();
-  }
-
-  QuicConnectionContext context;
-};
-
-void SimpleSwitch() {
-  FakeConnection connection;
-
-  // These should be ignored since current context is nullptr.
-  EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
-  QUIC_TRACELITERAL("before switch: literal");
-  QUIC_TRACESTRING(std::string("before switch: string"));
-  QUIC_TRACEPRINTF("%s: %s", "before switch", "printf");
-
-  {
-    QuicConnectionContextSwitcher switcher(&connection.context);
-    QUIC_TRACELITERAL("literal");
-    QUIC_TRACESTRING(std::string("string"));
-    QUIC_TRACEPRINTF("%s", "printf");
-  }
-
-  EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
-  QUIC_TRACELITERAL("after switch: literal");
-  QUIC_TRACESTRING(std::string("after switch: string"));
-  QUIC_TRACEPRINTF("%s: %s", "after switch", "printf");
-
-  EXPECT_THAT(connection.trace(), ElementsAre("literal", "string", "printf"));
-}
-
-void NestedSwitch() {
-  FakeConnection outer, inner;
-
-  {
-    QuicConnectionContextSwitcher switcher(&outer.context);
-    QUIC_TRACELITERAL("outer literal 0");
-    QUIC_TRACESTRING(std::string("outer string 0"));
-    QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 0);
-
-    {
-      QuicConnectionContextSwitcher switcher(&inner.context);
-      QUIC_TRACELITERAL("inner literal");
-      QUIC_TRACESTRING(std::string("inner string"));
-      QUIC_TRACEPRINTF("%s %s", "inner", "printf");
-    }
-
-    QUIC_TRACELITERAL("outer literal 1");
-    QUIC_TRACESTRING(std::string("outer string 1"));
-    QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 1);
-  }
-
-  EXPECT_THAT(outer.trace(), ElementsAre("outer literal 0", "outer string 0",
-                                         "outer printf 0", "outer literal 1",
-                                         "outer string 1", "outer printf 1"));
-
-  EXPECT_THAT(inner.trace(),
-              ElementsAre("inner literal", "inner string", "inner printf"));
-}
-
-void AlternatingSwitch() {
-  FakeConnection zero, one, two;
-  for (int i = 0; i < 15; ++i) {
-    FakeConnection* connection =
-        ((i % 3) == 0) ? &zero : (((i % 3) == 1) ? &one : &two);
-
-    QuicConnectionContextSwitcher switcher(&connection->context);
-    QUIC_TRACEPRINTF("%d", i);
-  }
-
-  EXPECT_THAT(zero.trace(), ElementsAre("0", "3", "6", "9", "12"));
-  EXPECT_THAT(one.trace(), ElementsAre("1", "4", "7", "10", "13"));
-  EXPECT_THAT(two.trace(), ElementsAre("2", "5", "8", "11", "14"));
-}
-
-typedef void (*ThreadFunction)();
-
-template <ThreadFunction func>
-class TestThread : public QuicThread {
- public:
-  TestThread() : QuicThread("TestThread") {}
-  ~TestThread() override = default;
-
- protected:
-  void Run() override { func(); }
-};
-
-template <ThreadFunction func>
-void RunInThreads(size_t n_threads) {
-  using ThreadType = TestThread<func>;
-  std::vector<ThreadType> threads(n_threads);
-
-  for (ThreadType& t : threads) {
-    t.Start();
-  }
-
-  for (ThreadType& t : threads) {
-    t.Join();
-  }
-}
-
-class QuicConnectionContextTest : public QuicTest {
- protected:
-};
-
-TEST_F(QuicConnectionContextTest, NullTracerOK) {
-  FakeConnection connection;
-  std::unique_ptr<QuicConnectionTracer> tracer;
-
-  {
-    QuicConnectionContextSwitcher switcher(&connection.context);
-    QUIC_TRACELITERAL("msg 1 recorded");
-  }
-
-  connection.context.tracer.swap(tracer);
-
-  {
-    QuicConnectionContextSwitcher switcher(&connection.context);
-    // Should be a no-op since connection.context.tracer is nullptr.
-    QUIC_TRACELITERAL("msg 2 ignored");
-  }
-
-  EXPECT_THAT(static_cast<TraceCollector*>(tracer.get())->trace(),
-              ElementsAre("msg 1 recorded"));
-}
-
-TEST_F(QuicConnectionContextTest, TestSimpleSwitch) {
-  RunInThreads<SimpleSwitch>(10);
-}
-
-TEST_F(QuicConnectionContextTest, TestNestedSwitch) {
-  RunInThreads<NestedSwitch>(10);
-}
-
-TEST_F(QuicConnectionContextTest, TestAlternatingSwitch) {
-  RunInThreads<AlternatingSwitch>(10);
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/quic_connection_id.cc b/quic/core/quic_connection_id.cc
deleted file mode 100644
index 15de7cb..0000000
--- a/quic/core/quic_connection_id.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <iomanip>
-#include <string>
-
-#include "absl/strings/escaping.h"
-#include "third_party/boringssl/src/include/openssl/siphash.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-// QuicConnectionIdHasher can be used to generate a stable connection ID hash
-// function that will return the same value for two equal connection IDs for
-// the duration of process lifetime. It is meant to be used as input to data
-// structures that do not outlast process lifetime. A new key is generated once
-// per process to prevent attackers from crafting connection IDs in such a way
-// that they always land in the same hash bucket.
-class QuicConnectionIdHasher {
- public:
-  inline QuicConnectionIdHasher()
-      : QuicConnectionIdHasher(QuicRandom::GetInstance()) {}
-
-  explicit inline QuicConnectionIdHasher(QuicRandom* random) {
-    random->RandBytes(&sip_hash_key_, sizeof(sip_hash_key_));
-  }
-
-  inline size_t Hash(const char* input, size_t input_len) const {
-    return static_cast<size_t>(SIPHASH_24(
-        sip_hash_key_, reinterpret_cast<const uint8_t*>(input), input_len));
-  }
-
- private:
-  uint64_t sip_hash_key_[2];
-};
-
-}  // namespace
-
-QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {
-  static_assert(offsetof(QuicConnectionId, padding_) ==
-                    offsetof(QuicConnectionId, length_),
-                "bad offset");
-  static_assert(sizeof(QuicConnectionId) <= 16, "bad size");
-}
-
-QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
-  length_ = length;
-  if (length_ == 0) {
-    return;
-  }
-  if (length_ <= sizeof(data_short_)) {
-    memcpy(data_short_, data, length_);
-    return;
-  }
-  data_long_ = reinterpret_cast<char*>(malloc(length_));
-  QUICHE_CHECK_NE(nullptr, data_long_);
-  memcpy(data_long_, data, length_);
-}
-
-QuicConnectionId::QuicConnectionId(const absl::Span<const uint8_t> data)
-    : QuicConnectionId(reinterpret_cast<const char*>(data.data()),
-                       data.length()) {}
-
-QuicConnectionId::~QuicConnectionId() {
-  if (length_ > sizeof(data_short_)) {
-    free(data_long_);
-    data_long_ = nullptr;
-  }
-}
-
-QuicConnectionId::QuicConnectionId(const QuicConnectionId& other)
-    : QuicConnectionId(other.data(), other.length()) {}
-
-QuicConnectionId& QuicConnectionId::operator=(const QuicConnectionId& other) {
-  set_length(other.length());
-  memcpy(mutable_data(), other.data(), length_);
-  return *this;
-}
-
-const char* QuicConnectionId::data() const {
-  if (length_ <= sizeof(data_short_)) {
-    return data_short_;
-  }
-  return data_long_;
-}
-
-char* QuicConnectionId::mutable_data() {
-  if (length_ <= sizeof(data_short_)) {
-    return data_short_;
-  }
-  return data_long_;
-}
-
-uint8_t QuicConnectionId::length() const { return length_; }
-
-void QuicConnectionId::set_length(uint8_t length) {
-  char temporary_data[sizeof(data_short_)];
-  if (length > sizeof(data_short_)) {
-    if (length_ <= sizeof(data_short_)) {
-      // Copy data from data_short_ to data_long_.
-      memcpy(temporary_data, data_short_, length_);
-      data_long_ = reinterpret_cast<char*>(malloc(length));
-      QUICHE_CHECK_NE(nullptr, data_long_);
-      memcpy(data_long_, temporary_data, length_);
-    } else {
-      // Resize data_long_.
-      char* realloc_result =
-          reinterpret_cast<char*>(realloc(data_long_, length));
-      QUICHE_CHECK_NE(nullptr, realloc_result);
-      data_long_ = realloc_result;
-    }
-  } else if (length_ > sizeof(data_short_)) {
-    // Copy data from data_long_ to data_short_.
-    memcpy(temporary_data, data_long_, length);
-    free(data_long_);
-    data_long_ = nullptr;
-    memcpy(data_short_, temporary_data, length);
-  }
-  length_ = length;
-}
-
-bool QuicConnectionId::IsEmpty() const { return length_ == 0; }
-
-size_t QuicConnectionId::Hash() const {
-  static const QuicConnectionIdHasher hasher = QuicConnectionIdHasher();
-  return hasher.Hash(data(), length_);
-}
-
-std::string QuicConnectionId::ToString() const {
-  if (IsEmpty()) {
-    return std::string("0");
-  }
-  return absl::BytesToHexString(absl::string_view(data(), length_));
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) {
-  os << v.ToString();
-  return os;
-}
-
-bool QuicConnectionId::operator==(const QuicConnectionId& v) const {
-  return length_ == v.length_ && memcmp(data(), v.data(), length_) == 0;
-}
-
-bool QuicConnectionId::operator!=(const QuicConnectionId& v) const {
-  return !(v == *this);
-}
-
-bool QuicConnectionId::operator<(const QuicConnectionId& v) const {
-  if (length_ < v.length_) {
-    return true;
-  }
-  if (length_ > v.length_) {
-    return false;
-  }
-  return memcmp(data(), v.data(), length_) < 0;
-}
-
-QuicConnectionId EmptyQuicConnectionId() { return QuicConnectionId(); }
-
-static_assert(kQuicDefaultConnectionIdLength == sizeof(uint64_t),
-              "kQuicDefaultConnectionIdLength changed");
-static_assert(kQuicDefaultConnectionIdLength == PACKET_8BYTE_CONNECTION_ID,
-              "kQuicDefaultConnectionIdLength changed");
-
-}  // namespace quic
diff --git a/quic/core/quic_connection_id.h b/quic/core/quic_connection_id.h
deleted file mode 100644
index 88fb418..0000000
--- a/quic/core/quic_connection_id.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
-
-#include <string>
-#include <vector>
-
-#include "absl/types/span.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-enum QuicConnectionIdLength {
-  PACKET_0BYTE_CONNECTION_ID = 0,
-  PACKET_8BYTE_CONNECTION_ID = 8,
-};
-
-// This is a property of QUIC headers, it indicates whether the connection ID
-// should actually be sent over the wire (or was sent on received packets).
-enum QuicConnectionIdIncluded : uint8_t {
-  CONNECTION_ID_PRESENT = 1,
-  CONNECTION_ID_ABSENT = 2,
-};
-
-// Maximum connection ID length supported by versions that use the encoding from
-// draft-ietf-quic-invariants-06.
-const uint8_t kQuicMaxConnectionIdWithLengthPrefixLength = 20;
-
-// Maximum connection ID length supported by versions that use the encoding from
-// draft-ietf-quic-invariants-05.
-const uint8_t kQuicMaxConnectionId4BitLength = 18;
-
-// kQuicDefaultConnectionIdLength is the only supported length for QUIC
-// versions < v99, and is the default picked for all versions.
-const uint8_t kQuicDefaultConnectionIdLength = 8;
-
-// According to the IETF spec, the initial server connection ID generated by
-// the client must be at least this long.
-const uint8_t kQuicMinimumInitialConnectionIdLength = 8;
-
-class QUIC_EXPORT_PRIVATE QuicConnectionId {
- public:
-  // Creates a connection ID of length zero.
-  QuicConnectionId();
-
-  // Creates a connection ID from network order bytes.
-  QuicConnectionId(const char* data, uint8_t length);
-  QuicConnectionId(const absl::Span<const uint8_t> data);
-
-  // Creates a connection ID from another connection ID.
-  QuicConnectionId(const QuicConnectionId& other);
-
-  // Assignment operator.
-  QuicConnectionId& operator=(const QuicConnectionId& other);
-
-  ~QuicConnectionId();
-
-  // Returns the length of the connection ID, in bytes.
-  uint8_t length() const;
-
-  // Sets the length of the connection ID, in bytes.
-  // WARNING: Calling set_length() can change the in-memory location of the
-  // connection ID. Callers must therefore ensure they call data() or
-  // mutable_data() after they call set_length().
-  void set_length(uint8_t length);
-
-  // Returns a pointer to the connection ID bytes, in network byte order.
-  const char* data() const;
-
-  // Returns a mutable pointer to the connection ID bytes,
-  // in network byte order.
-  char* mutable_data();
-
-  // Returns whether the connection ID has length zero.
-  bool IsEmpty() const;
-
-  // Hash() is required to use connection IDs as keys in hash tables.
-  // During the lifetime of a process, the output of Hash() is guaranteed to be
-  // the same for connection IDs that are equal to one another. Note however
-  // that this property is not guaranteed across process lifetimes. This makes
-  // Hash() suitable for data structures such as hash tables but not for sending
-  // a hash over the network.
-  size_t Hash() const;
-
-  // Generates an ASCII string that represents
-  // the contents of the connection ID, or "0" if it is empty.
-  std::string ToString() const;
-
-  // operator<< allows easily logging connection IDs.
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os, const QuicConnectionId& v);
-
-  bool operator==(const QuicConnectionId& v) const;
-  bool operator!=(const QuicConnectionId& v) const;
-  // operator< is required to use connection IDs as keys in hash tables.
-  bool operator<(const QuicConnectionId& v) const;
-
- private:
-  // The connection ID is represented in network byte order.
-  union {
-    // If the connection ID fits in |data_short_|, it is stored in the
-    // first |length_| bytes of |data_short_|.
-    // Otherwise it is stored in |data_long_| which is guaranteed to have a size
-    // equal to |length_|.
-    // A value of 11 was chosen because our commonly used connection ID length
-    // is 8 and with the length, the class is padded to at least 12 bytes
-    // anyway.
-    struct {
-      uint8_t padding_;  // Match length_ field of the other union member.
-      char data_short_[11];
-    };
-    struct {
-      uint8_t length_;  // length of the connection ID, in bytes.
-      char* data_long_;
-    };
-  };
-};
-
-// Creates a connection ID of length zero, unless the restart flag
-// quic_connection_ids_network_byte_order is false in which case
-// it returns an 8-byte all-zeroes connection ID.
-QUIC_EXPORT_PRIVATE QuicConnectionId EmptyQuicConnectionId();
-
-// QuicConnectionIdHash can be passed as hash argument to hash tables.
-// During the lifetime of a process, the output of QuicConnectionIdHash is
-// guaranteed to be the same for connection IDs that are equal to one another.
-// Note however that this property is not guaranteed across process lifetimes.
-// This makes QuicConnectionIdHash suitable for data structures such as hash
-// tables but not for sending a hash over the network.
-class QUIC_EXPORT_PRIVATE QuicConnectionIdHash {
- public:
-  size_t operator()(QuicConnectionId const& connection_id) const noexcept {
-    return connection_id.Hash();
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
diff --git a/quic/core/quic_connection_id_manager.cc b/quic/core/quic_connection_id_manager.cc
deleted file mode 100644
index 1138a2e..0000000
--- a/quic/core/quic_connection_id_manager.cc
+++ /dev/null
@@ -1,460 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id_manager.h"
-
-#include <cstdio>
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_utils.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-QuicConnectionIdData::QuicConnectionIdData(
-    const QuicConnectionId& connection_id,
-    uint64_t sequence_number,
-    const StatelessResetToken& stateless_reset_token)
-    : connection_id(connection_id),
-      sequence_number(sequence_number),
-      stateless_reset_token(stateless_reset_token) {}
-
-namespace {
-
-class RetirePeerIssuedConnectionIdAlarm
-    : public QuicAlarm::DelegateWithContext {
- public:
-  explicit RetirePeerIssuedConnectionIdAlarm(
-      QuicConnectionIdManagerVisitorInterface* visitor,
-      QuicConnectionContext* context)
-      : QuicAlarm::DelegateWithContext(context), visitor_(visitor) {}
-  RetirePeerIssuedConnectionIdAlarm(const RetirePeerIssuedConnectionIdAlarm&) =
-      delete;
-  RetirePeerIssuedConnectionIdAlarm& operator=(
-      const RetirePeerIssuedConnectionIdAlarm&) = delete;
-
-  void OnAlarm() override { visitor_->OnPeerIssuedConnectionIdRetired(); }
-
- private:
-  QuicConnectionIdManagerVisitorInterface* visitor_;
-};
-
-std::vector<QuicConnectionIdData>::const_iterator FindConnectionIdData(
-    const std::vector<QuicConnectionIdData>& cid_data_vector,
-    const QuicConnectionId& cid) {
-  return std::find_if(cid_data_vector.begin(), cid_data_vector.end(),
-                      [&cid](const QuicConnectionIdData& cid_data) {
-                        return cid == cid_data.connection_id;
-                      });
-}
-
-std::vector<QuicConnectionIdData>::iterator FindConnectionIdData(
-    std::vector<QuicConnectionIdData>* cid_data_vector,
-    const QuicConnectionId& cid) {
-  return std::find_if(cid_data_vector->begin(), cid_data_vector->end(),
-                      [&cid](const QuicConnectionIdData& cid_data) {
-                        return cid == cid_data.connection_id;
-                      });
-}
-
-}  // namespace
-
-QuicPeerIssuedConnectionIdManager::QuicPeerIssuedConnectionIdManager(
-    size_t active_connection_id_limit,
-    const QuicConnectionId& initial_peer_issued_connection_id,
-    const QuicClock* clock, QuicAlarmFactory* alarm_factory,
-    QuicConnectionIdManagerVisitorInterface* visitor,
-    QuicConnectionContext* context)
-    : active_connection_id_limit_(active_connection_id_limit),
-      clock_(clock),
-      retire_connection_id_alarm_(alarm_factory->CreateAlarm(
-          new RetirePeerIssuedConnectionIdAlarm(visitor, context))) {
-  QUICHE_DCHECK_GE(active_connection_id_limit_, 2u);
-  QUICHE_DCHECK(!initial_peer_issued_connection_id.IsEmpty());
-  active_connection_id_data_.emplace_back<const QuicConnectionId&, uint64_t,
-                                          const StatelessResetToken&>(
-      initial_peer_issued_connection_id,
-      /*sequence_number=*/0u, {});
-  recent_new_connection_id_sequence_numbers_.Add(0u, 1u);
-}
-
-QuicPeerIssuedConnectionIdManager::~QuicPeerIssuedConnectionIdManager() {
-  retire_connection_id_alarm_->Cancel();
-}
-
-bool QuicPeerIssuedConnectionIdManager::IsConnectionIdNew(
-    const QuicNewConnectionIdFrame& frame) {
-  auto is_old_connection_id = [&frame](const QuicConnectionIdData& cid_data) {
-    return cid_data.connection_id == frame.connection_id;
-  };
-  if (std::any_of(active_connection_id_data_.begin(),
-                  active_connection_id_data_.end(), is_old_connection_id)) {
-    return false;
-  }
-  if (std::any_of(unused_connection_id_data_.begin(),
-                  unused_connection_id_data_.end(), is_old_connection_id)) {
-    return false;
-  }
-  if (std::any_of(to_be_retired_connection_id_data_.begin(),
-                  to_be_retired_connection_id_data_.end(),
-                  is_old_connection_id)) {
-    return false;
-  }
-  return true;
-}
-
-void QuicPeerIssuedConnectionIdManager::PrepareToRetireConnectionIdPriorTo(
-    uint64_t retire_prior_to,
-    std::vector<QuicConnectionIdData>* cid_data_vector) {
-  auto it2 = cid_data_vector->begin();
-  for (auto it = cid_data_vector->begin(); it != cid_data_vector->end(); ++it) {
-    if (it->sequence_number >= retire_prior_to) {
-      *it2++ = *it;
-    } else {
-      to_be_retired_connection_id_data_.push_back(*it);
-      if (!retire_connection_id_alarm_->IsSet()) {
-        retire_connection_id_alarm_->Set(clock_->ApproximateNow());
-      }
-    }
-  }
-  cid_data_vector->erase(it2, cid_data_vector->end());
-}
-
-QuicErrorCode QuicPeerIssuedConnectionIdManager::OnNewConnectionIdFrame(
-    const QuicNewConnectionIdFrame& frame,
-    std::string* error_detail) {
-  if (recent_new_connection_id_sequence_numbers_.Contains(
-          frame.sequence_number)) {
-    // This frame has a recently seen sequence number. Ignore.
-    return QUIC_NO_ERROR;
-  }
-  if (!IsConnectionIdNew(frame)) {
-    *error_detail =
-        "Received a NEW_CONNECTION_ID frame that reuses a previously seen Id.";
-    return IETF_QUIC_PROTOCOL_VIOLATION;
-  }
-
-  recent_new_connection_id_sequence_numbers_.AddOptimizedForAppend(
-      frame.sequence_number, frame.sequence_number + 1);
-
-  if (recent_new_connection_id_sequence_numbers_.Size() >
-      kMaxNumConnectionIdSequenceNumberIntervals) {
-    *error_detail =
-        "Too many disjoint connection Id sequence number intervals.";
-    return IETF_QUIC_PROTOCOL_VIOLATION;
-  }
-
-  // QuicFramer::ProcessNewConnectionIdFrame guarantees that
-  // frame.sequence_number >= frame.retire_prior_to, and hence there is no need
-  // to check that.
-  if (frame.sequence_number < max_new_connection_id_frame_retire_prior_to_) {
-    // Later frames have asked for retirement of the current frame.
-    to_be_retired_connection_id_data_.emplace_back(frame.connection_id,
-                                                   frame.sequence_number,
-                                                   frame.stateless_reset_token);
-    if (!retire_connection_id_alarm_->IsSet()) {
-      retire_connection_id_alarm_->Set(clock_->ApproximateNow());
-    }
-    return QUIC_NO_ERROR;
-  }
-  if (frame.retire_prior_to > max_new_connection_id_frame_retire_prior_to_) {
-    max_new_connection_id_frame_retire_prior_to_ = frame.retire_prior_to;
-    PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
-                                       &active_connection_id_data_);
-    PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
-                                       &unused_connection_id_data_);
-  }
-
-  if (active_connection_id_data_.size() + unused_connection_id_data_.size() >=
-      active_connection_id_limit_) {
-    *error_detail = "Peer provides more connection IDs than the limit.";
-    return QUIC_CONNECTION_ID_LIMIT_ERROR;
-  }
-
-  unused_connection_id_data_.emplace_back(
-      frame.connection_id, frame.sequence_number, frame.stateless_reset_token);
-  return QUIC_NO_ERROR;
-}
-
-const QuicConnectionIdData*
-QuicPeerIssuedConnectionIdManager::ConsumeOneUnusedConnectionId() {
-  if (unused_connection_id_data_.empty()) {
-    return nullptr;
-  }
-  active_connection_id_data_.push_back(unused_connection_id_data_.back());
-  unused_connection_id_data_.pop_back();
-  return &active_connection_id_data_.back();
-}
-
-void QuicPeerIssuedConnectionIdManager::PrepareToRetireActiveConnectionId(
-    const QuicConnectionId& cid) {
-  auto it = FindConnectionIdData(active_connection_id_data_, cid);
-  if (it == active_connection_id_data_.end()) {
-    // The cid has already been retired.
-    return;
-  }
-  to_be_retired_connection_id_data_.push_back(*it);
-  active_connection_id_data_.erase(it);
-  if (!retire_connection_id_alarm_->IsSet()) {
-    retire_connection_id_alarm_->Set(clock_->ApproximateNow());
-  }
-}
-
-void QuicPeerIssuedConnectionIdManager::MaybeRetireUnusedConnectionIds(
-    const std::vector<QuicConnectionId>& active_connection_ids_on_path) {
-  std::vector<QuicConnectionId> cids_to_retire;
-  for (const auto& cid_data : active_connection_id_data_) {
-    if (std::find(active_connection_ids_on_path.begin(),
-                  active_connection_ids_on_path.end(),
-                  cid_data.connection_id) ==
-        active_connection_ids_on_path.end()) {
-      cids_to_retire.push_back(cid_data.connection_id);
-    }
-  }
-  for (const auto& cid : cids_to_retire) {
-    PrepareToRetireActiveConnectionId(cid);
-  }
-}
-
-bool QuicPeerIssuedConnectionIdManager::IsConnectionIdActive(
-    const QuicConnectionId& cid) const {
-  return FindConnectionIdData(active_connection_id_data_, cid) !=
-         active_connection_id_data_.end();
-}
-
-std::vector<uint64_t> QuicPeerIssuedConnectionIdManager::
-    ConsumeToBeRetiredConnectionIdSequenceNumbers() {
-  std::vector<uint64_t> result;
-  for (auto const& cid_data : to_be_retired_connection_id_data_) {
-    result.push_back(cid_data.sequence_number);
-  }
-  to_be_retired_connection_id_data_.clear();
-  return result;
-}
-
-void QuicPeerIssuedConnectionIdManager::ReplaceConnectionId(
-    const QuicConnectionId& old_connection_id,
-    const QuicConnectionId& new_connection_id) {
-  auto it1 =
-      FindConnectionIdData(&active_connection_id_data_, old_connection_id);
-  if (it1 != active_connection_id_data_.end()) {
-    it1->connection_id = new_connection_id;
-    return;
-  }
-  auto it2 = FindConnectionIdData(&to_be_retired_connection_id_data_,
-                                  old_connection_id);
-  if (it2 != to_be_retired_connection_id_data_.end()) {
-    it2->connection_id = new_connection_id;
-  }
-}
-
-namespace {
-
-class RetireSelfIssuedConnectionIdAlarmDelegate
-    : public QuicAlarm::DelegateWithContext {
- public:
-  explicit RetireSelfIssuedConnectionIdAlarmDelegate(
-      QuicSelfIssuedConnectionIdManager* connection_id_manager,
-      QuicConnectionContext* context)
-      : QuicAlarm::DelegateWithContext(context),
-        connection_id_manager_(connection_id_manager) {}
-  RetireSelfIssuedConnectionIdAlarmDelegate(
-      const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
-  RetireSelfIssuedConnectionIdAlarmDelegate& operator=(
-      const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
-
-  void OnAlarm() override { connection_id_manager_->RetireConnectionId(); }
-
- private:
-  QuicSelfIssuedConnectionIdManager* connection_id_manager_;
-};
-
-}  // namespace
-
-QuicSelfIssuedConnectionIdManager::QuicSelfIssuedConnectionIdManager(
-    size_t active_connection_id_limit,
-    const QuicConnectionId& initial_connection_id, const QuicClock* clock,
-    QuicAlarmFactory* alarm_factory,
-    QuicConnectionIdManagerVisitorInterface* visitor,
-    QuicConnectionContext* context)
-    : active_connection_id_limit_(active_connection_id_limit),
-      clock_(clock),
-      visitor_(visitor),
-      retire_connection_id_alarm_(alarm_factory->CreateAlarm(
-          new RetireSelfIssuedConnectionIdAlarmDelegate(this, context))),
-      last_connection_id_(initial_connection_id),
-      next_connection_id_sequence_number_(1u),
-      last_connection_id_consumed_by_self_sequence_number_(0u) {
-  active_connection_ids_.emplace_back(initial_connection_id, 0u);
-}
-
-QuicSelfIssuedConnectionIdManager::~QuicSelfIssuedConnectionIdManager() {
-  retire_connection_id_alarm_->Cancel();
-}
-
-QuicConnectionId QuicSelfIssuedConnectionIdManager::GenerateNewConnectionId(
-    const QuicConnectionId& old_connection_id) const {
-  return QuicUtils::CreateReplacementConnectionId(old_connection_id);
-}
-
-QuicNewConnectionIdFrame
-QuicSelfIssuedConnectionIdManager::IssueNewConnectionId() {
-  QuicNewConnectionIdFrame frame;
-  frame.connection_id = GenerateNewConnectionId(last_connection_id_);
-  frame.sequence_number = next_connection_id_sequence_number_++;
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  visitor_->OnNewConnectionIdIssued(frame.connection_id);
-  active_connection_ids_.emplace_back(frame.connection_id,
-                                      frame.sequence_number);
-  frame.retire_prior_to = active_connection_ids_.front().second;
-  last_connection_id_ = frame.connection_id;
-  return frame;
-}
-
-QuicNewConnectionIdFrame
-QuicSelfIssuedConnectionIdManager::IssueNewConnectionIdForPreferredAddress() {
-  QuicNewConnectionIdFrame frame = IssueNewConnectionId();
-  QUICHE_DCHECK_EQ(frame.sequence_number, 1u);
-  return frame;
-}
-
-QuicErrorCode QuicSelfIssuedConnectionIdManager::OnRetireConnectionIdFrame(
-    const QuicRetireConnectionIdFrame& frame,
-    QuicTime::Delta pto_delay,
-    std::string* error_detail) {
-  QUICHE_DCHECK(!active_connection_ids_.empty());
-  if (frame.sequence_number > active_connection_ids_.back().second) {
-    *error_detail = "To be retired connecton ID is never issued.";
-    return IETF_QUIC_PROTOCOL_VIOLATION;
-  }
-
-  auto it =
-      std::find_if(active_connection_ids_.begin(), active_connection_ids_.end(),
-                   [&frame](const std::pair<QuicConnectionId, uint64_t>& p) {
-                     return p.second == frame.sequence_number;
-                   });
-  // The corresponding connection ID has been retired. Ignore.
-  if (it == active_connection_ids_.end()) {
-    return QUIC_NO_ERROR;
-  }
-
-  if (to_be_retired_connection_ids_.size() + active_connection_ids_.size() >=
-      kMaxNumConnectonIdsInUse) {
-    // Close connection if the number of connection IDs in use will exeed the
-    // limit, i.e., peer retires connection ID too fast.
-    *error_detail = "There are too many connection IDs in use.";
-    return QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE;
-  }
-
-  QuicTime retirement_time = clock_->ApproximateNow() + 3 * pto_delay;
-  if (!to_be_retired_connection_ids_.empty()) {
-    retirement_time =
-        std::max(retirement_time, to_be_retired_connection_ids_.back().second);
-  }
-
-  to_be_retired_connection_ids_.emplace_back(it->first, retirement_time);
-  if (!retire_connection_id_alarm_->IsSet()) {
-    retire_connection_id_alarm_->Set(retirement_time);
-  }
-
-  active_connection_ids_.erase(it);
-  MaybeSendNewConnectionIds();
-
-  return QUIC_NO_ERROR;
-}
-
-std::vector<QuicConnectionId>
-QuicSelfIssuedConnectionIdManager::GetUnretiredConnectionIds() const {
-  std::vector<QuicConnectionId> unretired_ids;
-  for (const auto& cid_pair : to_be_retired_connection_ids_) {
-    unretired_ids.push_back(cid_pair.first);
-  }
-  for (const auto& cid_pair : active_connection_ids_) {
-    unretired_ids.push_back(cid_pair.first);
-  }
-  return unretired_ids;
-}
-
-QuicConnectionId QuicSelfIssuedConnectionIdManager::GetOneActiveConnectionId()
-    const {
-  QUICHE_DCHECK(!active_connection_ids_.empty());
-  return active_connection_ids_.front().first;
-}
-
-void QuicSelfIssuedConnectionIdManager::RetireConnectionId() {
-  if (to_be_retired_connection_ids_.empty()) {
-    QUIC_BUG(quic_bug_12420_1)
-        << "retire_connection_id_alarm fired but there is no connection ID "
-           "to be retired.";
-    return;
-  }
-  QuicTime now = clock_->ApproximateNow();
-  auto it = to_be_retired_connection_ids_.begin();
-  do {
-    visitor_->OnSelfIssuedConnectionIdRetired(it->first);
-    ++it;
-  } while (it != to_be_retired_connection_ids_.end() && it->second <= now);
-  to_be_retired_connection_ids_.erase(to_be_retired_connection_ids_.begin(),
-                                      it);
-  // Set the alarm again if there is another connection ID to be removed.
-  if (!to_be_retired_connection_ids_.empty()) {
-    retire_connection_id_alarm_->Set(
-        to_be_retired_connection_ids_.front().second);
-  }
-}
-
-void QuicSelfIssuedConnectionIdManager::MaybeSendNewConnectionIds() {
-  while (active_connection_ids_.size() < active_connection_id_limit_) {
-    QuicNewConnectionIdFrame frame = IssueNewConnectionId();
-    if (!visitor_->SendNewConnectionId(frame)) {
-      break;
-    }
-  }
-}
-
-bool QuicSelfIssuedConnectionIdManager::HasConnectionIdToConsume() const {
-  for (const auto& active_cid_data : active_connection_ids_) {
-    if (active_cid_data.second >
-        last_connection_id_consumed_by_self_sequence_number_) {
-      return true;
-    }
-  }
-  return false;
-}
-
-absl::optional<QuicConnectionId>
-QuicSelfIssuedConnectionIdManager::ConsumeOneConnectionId() {
-  for (const auto& active_cid_data : active_connection_ids_) {
-    if (active_cid_data.second >
-        last_connection_id_consumed_by_self_sequence_number_) {
-      // Since connection IDs in active_connection_ids_ has monotonically
-      // increasing sequence numbers, the returned connection ID has the
-      // smallest sequence number among all unconsumed active connection IDs.
-      last_connection_id_consumed_by_self_sequence_number_ =
-          active_cid_data.second;
-      return active_cid_data.first;
-    }
-  }
-  return absl::nullopt;
-}
-
-bool QuicSelfIssuedConnectionIdManager::IsConnectionIdInUse(
-    const QuicConnectionId& cid) const {
-  for (const auto& active_cid_data : active_connection_ids_) {
-    if (active_cid_data.first == cid) {
-      return true;
-    }
-  }
-  for (const auto& to_be_retired_cid_data : to_be_retired_connection_ids_) {
-    if (to_be_retired_cid_data.first == cid) {
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_connection_id_manager.h b/quic/core/quic_connection_id_manager.h
deleted file mode 100644
index 6755c62..0000000
--- a/quic/core/quic_connection_id_manager.h
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// QuicPeerIssuedConnectionIdManager handles the states associated with receving
-// and retiring peer issued connection Ids.
-// QuicSelfIssuedConnectionIdManager handles the states associated with
-// connection Ids issued by the current end point.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionIdManagerPeer;
-}  // namespace test
-
-struct QUIC_EXPORT_PRIVATE QuicConnectionIdData {
-  QuicConnectionIdData(const QuicConnectionId& connection_id,
-                       uint64_t sequence_number,
-                       const StatelessResetToken& stateless_reset_token);
-
-  QuicConnectionId connection_id;
-  uint64_t sequence_number;
-  StatelessResetToken stateless_reset_token;
-};
-
-// Used by QuicSelfIssuedConnectionIdManager
-// and QuicPeerIssuedConnectionIdManager.
-class QUIC_EXPORT_PRIVATE QuicConnectionIdManagerVisitorInterface {
- public:
-  virtual ~QuicConnectionIdManagerVisitorInterface() = default;
-  virtual void OnPeerIssuedConnectionIdRetired() = 0;
-  virtual bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
-  virtual void OnNewConnectionIdIssued(
-      const QuicConnectionId& connection_id) = 0;
-  virtual void OnSelfIssuedConnectionIdRetired(
-      const QuicConnectionId& connection_id) = 0;
-};
-
-class QUIC_EXPORT_PRIVATE QuicPeerIssuedConnectionIdManager {
- public:
-  // QuicPeerIssuedConnectionIdManager should be instantiated only when a peer
-  // issued-non empty connection ID is received.
-  QuicPeerIssuedConnectionIdManager(
-      size_t active_connection_id_limit,
-      const QuicConnectionId& initial_peer_issued_connection_id,
-      const QuicClock* clock, QuicAlarmFactory* alarm_factory,
-      QuicConnectionIdManagerVisitorInterface* visitor,
-      QuicConnectionContext* context);
-
-  ~QuicPeerIssuedConnectionIdManager();
-
-  QuicErrorCode OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
-                                       std::string* error_detail);
-
-  bool HasUnusedConnectionId() const {
-    return !unused_connection_id_data_.empty();
-  }
-
-  // Returns the data associated with an unused connection Id. After the call,
-  // the Id is marked as used. Returns nullptr if there is no unused connection
-  // Id.
-  const QuicConnectionIdData* ConsumeOneUnusedConnectionId();
-
-  // Add each active connection Id that is no longer on path to the pending
-  // retirement connection Id list.
-  void MaybeRetireUnusedConnectionIds(
-      const std::vector<QuicConnectionId>& active_connection_ids_on_path);
-
-  bool IsConnectionIdActive(const QuicConnectionId& cid) const;
-
-  // Get the sequence numbers of all the connection Ids pending retirement when
-  // it is safe to retires these Ids.
-  std::vector<uint64_t> ConsumeToBeRetiredConnectionIdSequenceNumbers();
-
-  // If old_connection_id is still tracked by QuicPeerIssuedConnectionIdManager,
-  // replace it with new_connection_id. Otherwise, this is a no-op.
-  void ReplaceConnectionId(const QuicConnectionId& old_connection_id,
-                           const QuicConnectionId& new_connection_id);
-
- private:
-  friend class test::QuicConnectionIdManagerPeer;
-
-  // Add the connection Id to the pending retirement connection Id list and
-  // schedule an alarm if needed.
-  void PrepareToRetireActiveConnectionId(const QuicConnectionId& cid);
-
-  bool IsConnectionIdNew(const QuicNewConnectionIdFrame& frame);
-
-  void PrepareToRetireConnectionIdPriorTo(
-      uint64_t retire_prior_to,
-      std::vector<QuicConnectionIdData>* cid_data_vector);
-
-  size_t active_connection_id_limit_;
-  const QuicClock* clock_;
-  std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
-  std::vector<QuicConnectionIdData> active_connection_id_data_;
-  std::vector<QuicConnectionIdData> unused_connection_id_data_;
-  std::vector<QuicConnectionIdData> to_be_retired_connection_id_data_;
-  // Track sequence numbers of recent NEW_CONNECTION_ID frames received from
-  // the peer.
-  QuicIntervalSet<uint64_t> recent_new_connection_id_sequence_numbers_;
-  uint64_t max_new_connection_id_frame_retire_prior_to_ = 0u;
-};
-
-class QUIC_EXPORT_PRIVATE QuicSelfIssuedConnectionIdManager {
- public:
-  QuicSelfIssuedConnectionIdManager(
-      size_t active_connection_id_limit,
-      const QuicConnectionId& initial_connection_id, const QuicClock* clock,
-      QuicAlarmFactory* alarm_factory,
-      QuicConnectionIdManagerVisitorInterface* visitor,
-      QuicConnectionContext* context);
-
-  virtual ~QuicSelfIssuedConnectionIdManager();
-
-  QuicNewConnectionIdFrame IssueNewConnectionIdForPreferredAddress();
-
-  QuicErrorCode OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame,
-      QuicTime::Delta pto_delay,
-      std::string* error_detail);
-
-  std::vector<QuicConnectionId> GetUnretiredConnectionIds() const;
-
-  QuicConnectionId GetOneActiveConnectionId() const;
-
-  // Called when the retire_connection_id alarm_ fires. Removes the to be
-  // retired connection ID locally.
-  void RetireConnectionId();
-
-  // Sends new connection IDs if more can be sent.
-  void MaybeSendNewConnectionIds();
-
-  // The two functions are called on the client side to associate a client
-  // connection ID with a new probing/migration path when client uses
-  // non-empty connection ID.
-  bool HasConnectionIdToConsume() const;
-  absl::optional<QuicConnectionId> ConsumeOneConnectionId();
-
-  // Returns true if the given connection ID is issued by the
-  // QuicSelfIssuedConnectionIdManager and not retired locally yet. Called to
-  // tell if a received packet has a valid connection ID.
-  bool IsConnectionIdInUse(const QuicConnectionId& cid) const;
-
-  virtual QuicConnectionId GenerateNewConnectionId(
-      const QuicConnectionId& old_connection_id) const;
-
- private:
-  friend class test::QuicConnectionIdManagerPeer;
-
-  QuicNewConnectionIdFrame IssueNewConnectionId();
-
-  // This should be set to the min of:
-  // (1) # of active connection IDs that peer can maintain.
-  // (2) maximum # of active connection IDs self plans to issue.
-  size_t active_connection_id_limit_;
-  const QuicClock* clock_;
-  QuicConnectionIdManagerVisitorInterface* visitor_;
-  // This tracks connection IDs issued to the peer but not retired by the peer.
-  // Each pair is a connection ID and its sequence number.
-  std::vector<std::pair<QuicConnectionId, uint64_t>> active_connection_ids_;
-  // This tracks connection IDs retired by the peer but has not been retired
-  // locally. Each pair is a connection ID and the time by which it should be
-  // retired.
-  std::vector<std::pair<QuicConnectionId, QuicTime>>
-      to_be_retired_connection_ids_;
-  // An alarm that fires when a connection ID should be retired.
-  std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
-  // State of the last issued connection Id.
-  QuicConnectionId last_connection_id_;
-  uint64_t next_connection_id_sequence_number_;
-  // The sequence number of last connection ID consumed.
-  uint64_t last_connection_id_consumed_by_self_sequence_number_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
diff --git a/quic/core/quic_connection_id_manager_test.cc b/quic/core/quic_connection_id_manager_test.cc
deleted file mode 100644
index fdb73da..0000000
--- a/quic/core/quic_connection_id_manager_test.cc
+++ /dev/null
@@ -1,964 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id_manager.h"
-#include <cstddef>
-
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_connection_id_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace {
-
-using ::quic::test::IsError;
-using ::quic::test::IsQuicNoError;
-using ::quic::test::QuicConnectionIdManagerPeer;
-using ::quic::test::TestConnectionId;
-using ::testing::_;
-using ::testing::ElementsAre;
-using ::testing::IsNull;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-class TestPeerIssuedConnectionIdManagerVisitor
-    : public QuicConnectionIdManagerVisitorInterface {
- public:
-  void SetPeerIssuedConnectionIdManager(
-      QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager) {
-    peer_issued_connection_id_manager_ = peer_issued_connection_id_manager;
-  }
-
-  void OnPeerIssuedConnectionIdRetired() override {
-    // Replace current connection Id if it has been retired.
-    if (!peer_issued_connection_id_manager_->IsConnectionIdActive(
-            current_peer_issued_connection_id_)) {
-      current_peer_issued_connection_id_ =
-          peer_issued_connection_id_manager_->ConsumeOneUnusedConnectionId()
-              ->connection_id;
-    }
-    // Retire all the to-be-retired connection Ids.
-    most_recent_retired_connection_id_sequence_numbers_ =
-        peer_issued_connection_id_manager_
-            ->ConsumeToBeRetiredConnectionIdSequenceNumbers();
-  }
-
-  const std::vector<uint64_t>&
-  most_recent_retired_connection_id_sequence_numbers() {
-    return most_recent_retired_connection_id_sequence_numbers_;
-  }
-
-  void SetCurrentPeerConnectionId(QuicConnectionId cid) {
-    current_peer_issued_connection_id_ = cid;
-  }
-
-  const QuicConnectionId& GetCurrentPeerConnectionId() {
-    return current_peer_issued_connection_id_;
-  }
-
-  bool SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
-    return false;
-  }
-  void OnNewConnectionIdIssued(
-      const QuicConnectionId& /*connection_id*/) override {}
-  void OnSelfIssuedConnectionIdRetired(
-      const QuicConnectionId& /*connection_id*/) override {}
-
- private:
-  QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager_ =
-      nullptr;
-  QuicConnectionId current_peer_issued_connection_id_;
-  std::vector<uint64_t> most_recent_retired_connection_id_sequence_numbers_;
-};
-
-class QuicPeerIssuedConnectionIdManagerTest : public QuicTest {
- public:
-  QuicPeerIssuedConnectionIdManagerTest()
-      : peer_issued_cid_manager_(
-            /*active_connection_id_limit=*/2, initial_connection_id_, &clock_,
-            &alarm_factory_, &cid_manager_visitor_, /*context=*/nullptr) {
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-    cid_manager_visitor_.SetPeerIssuedConnectionIdManager(
-        &peer_issued_cid_manager_);
-    cid_manager_visitor_.SetCurrentPeerConnectionId(initial_connection_id_);
-    retire_peer_issued_cid_alarm_ =
-        QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
-            &peer_issued_cid_manager_);
-  }
-
- protected:
-  MockClock clock_;
-  test::MockAlarmFactory alarm_factory_;
-  TestPeerIssuedConnectionIdManagerVisitor cid_manager_visitor_;
-  QuicConnectionId initial_connection_id_ = TestConnectionId(0);
-  QuicPeerIssuedConnectionIdManager peer_issued_cid_manager_;
-  QuicAlarm* retire_peer_issued_cid_alarm_ = nullptr;
-  std::string error_details_;
-};
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       ConnectionIdSequenceWhenMigrationSucceed) {
-  {
-    // Receives CID #1 from peer.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-
-    // Start to use CID #1 for alternative path.
-    const QuicConnectionIdData* aternative_connection_id_data =
-        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-    ASSERT_THAT(aternative_connection_id_data, testing::NotNull());
-    EXPECT_EQ(aternative_connection_id_data->connection_id,
-              TestConnectionId(1));
-    EXPECT_EQ(aternative_connection_id_data->stateless_reset_token,
-              frame.stateless_reset_token);
-
-    // Connection migration succeed. Prepares to retire CID #0.
-    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-        {TestConnectionId(1)});
-    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(1));
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(0u));
-  }
-
-  {
-    // Receives CID #2 from peer since CID #0 is retired.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(2);
-    frame.sequence_number = 2u;
-    frame.retire_prior_to = 1u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    // Start to use CID #2 for alternative path.
-    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-    // Connection migration succeed. Prepares to retire CID #1.
-    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-        {TestConnectionId(2)});
-    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(2));
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(1u));
-  }
-
-  {
-    // Receives CID #3 from peer since CID #1 is retired.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(3);
-    frame.sequence_number = 3u;
-    frame.retire_prior_to = 2u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    // Start to use CID #3 for alternative path.
-    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-    // Connection migration succeed. Prepares to retire CID #2.
-    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-        {TestConnectionId(3)});
-    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(2u));
-  }
-
-  {
-    // Receives CID #4 from peer since CID #2 is retired.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(4);
-    frame.sequence_number = 4u;
-    frame.retire_prior_to = 3u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       ConnectionIdSequenceWhenMigrationFail) {
-  {
-    // Receives CID #1 from peer.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    // Start to use CID #1 for alternative path.
-    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-    // Connection migration fails. Prepares to retire CID #1.
-    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-        {initial_connection_id_});
-    // Actually retires CID #1.
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(1u));
-  }
-
-  {
-    // Receives CID #2 from peer since CID #1 is retired.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(2);
-    frame.sequence_number = 2u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    // Start to use CID #2 for alternative path.
-    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-    // Connection migration fails again. Prepares to retire CID #2.
-    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-        {initial_connection_id_});
-    // Actually retires CID #2.
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(2u));
-  }
-
-  {
-    // Receives CID #3 from peer since CID #2 is retired.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(3);
-    frame.sequence_number = 3u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    // Start to use CID #3 for alternative path.
-    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-    // Connection migration succeed. Prepares to retire CID #0.
-    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-        {TestConnectionId(3)});
-    // After CID #3 is default (i.e., when there is no pending frame to write
-    // associated with CID #0), #0 can actually be retired.
-    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(0u));
-  }
-
-  {
-    // Receives CID #4 from peer since CID #0 is retired.
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(4);
-    frame.sequence_number = 4u;
-    frame.retire_prior_to = 3u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    EXPECT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    EXPECT_FALSE(retire_peer_issued_cid_alarm_->IsSet());
-  }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       ReceivesNewConnectionIdOutOfOrder) {
-  {
-    // Receives new CID #1 that retires prior to #0.
-    // Outcome: (active: #0 unused: #1)
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    // Start to use CID #1 for alternative path.
-    // Outcome: (active: #0 #1 unused: None)
-    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-  }
-
-  {
-    // Receives new CID #3 that retires prior to #2.
-    // Outcome: (active: None unused: #3)
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(3);
-    frame.sequence_number = 3u;
-    frame.retire_prior_to = 2u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-
-  {
-    // Receives new CID #2 that retires prior to #1.
-    // Outcome: (active: None unused: #3, #2)
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(2);
-    frame.sequence_number = 2u;
-    frame.retire_prior_to = 1u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-
-  {
-    EXPECT_FALSE(
-        peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(0)));
-    EXPECT_FALSE(
-        peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
-    // When there is no frame associated with #0 and #1 to write, replace the
-    // in-use CID with an unused CID (#2) and retires #0 & #1.
-    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-    EXPECT_THAT(cid_manager_visitor_
-                    .most_recent_retired_connection_id_sequence_numbers(),
-                ElementsAre(0u, 1u));
-    EXPECT_EQ(cid_manager_visitor_.GetCurrentPeerConnectionId(),
-              TestConnectionId(2));
-    // Get another unused CID for path validation.
-    EXPECT_EQ(
-        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
-        TestConnectionId(3));
-  }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       VisitedNewConnectionIdFrameIsIgnored) {
-  // Receives new CID #1 that retires prior to #0.
-  // Outcome: (active: #0 unused: #1)
-  QuicNewConnectionIdFrame frame;
-  frame.connection_id = TestConnectionId(1);
-  frame.sequence_number = 1u;
-  frame.retire_prior_to = 0u;
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  ASSERT_THAT(
-      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-      IsQuicNoError());
-  // Start to use CID #1 for alternative path.
-  // Outcome: (active: #0 #1 unused: None)
-  peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
-  // Prepare to retire CID #1 as path validation fails.
-  peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
-      {initial_connection_id_});
-  // Actually retires CID #1.
-  ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
-  alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
-  EXPECT_THAT(
-      cid_manager_visitor_.most_recent_retired_connection_id_sequence_numbers(),
-      ElementsAre(1u));
-  // Receives the same frame again. Should be a no-op.
-  ASSERT_THAT(
-      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-      IsQuicNoError());
-  EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
-              testing::IsNull());
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       ErrorWhenActiveConnectionIdLimitExceeded) {
-  {
-    // Receives new CID #1 that retires prior to #0.
-    // Outcome: (active: #0 unused: #1)
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-
-  {
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(2);
-    frame.sequence_number = 2u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsError(QUIC_CONNECTION_ID_LIMIT_ERROR));
-  }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       ErrorWhenTheSameConnectionIdIsSeenWithDifferentSequenceNumbers) {
-  {
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-
-  {
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 2u;
-    frame.retire_prior_to = 1u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-  }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       NewConnectionIdFrameWithTheSameSequenceNumberIsIgnored) {
-  {
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(1);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-
-  {
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(2);
-    frame.sequence_number = 1u;
-    frame.retire_prior_to = 0u;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
-    EXPECT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-    EXPECT_EQ(
-        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
-        TestConnectionId(1));
-    EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
-                IsNull());
-  }
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest,
-       ErrorWhenThereAreTooManyGapsInIssuedConnectionIdSequenceNumbers) {
-  // Add 20 intervals: [0, 1), [2, 3), ..., [38,39)
-  for (int i = 2; i <= 38; i += 2) {
-    QuicNewConnectionIdFrame frame;
-    frame.connection_id = TestConnectionId(i);
-    frame.sequence_number = i;
-    frame.retire_prior_to = i;
-    frame.stateless_reset_token =
-        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-    ASSERT_THAT(
-        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-        IsQuicNoError());
-  }
-
-  // Interval [40, 41) goes over the limit.
-  QuicNewConnectionIdFrame frame;
-  frame.connection_id = TestConnectionId(40);
-  frame.sequence_number = 40u;
-  frame.retire_prior_to = 40u;
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  ASSERT_THAT(
-      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
-      IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_F(QuicPeerIssuedConnectionIdManagerTest, ReplaceConnectionId) {
-  ASSERT_TRUE(
-      peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
-  peer_issued_cid_manager_.ReplaceConnectionId(initial_connection_id_,
-                                               TestConnectionId(1));
-  EXPECT_FALSE(
-      peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
-  EXPECT_TRUE(
-      peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
-}
-
-class TestSelfIssuedConnectionIdManagerVisitor
-    : public QuicConnectionIdManagerVisitorInterface {
- public:
-  void OnPeerIssuedConnectionIdRetired() override {}
-
-  MOCK_METHOD(bool,
-              SendNewConnectionId,
-              (const QuicNewConnectionIdFrame& frame),
-              (override));
-  MOCK_METHOD(void,
-              OnNewConnectionIdIssued,
-              (const QuicConnectionId& connection_id),
-              (override));
-  MOCK_METHOD(void,
-              OnSelfIssuedConnectionIdRetired,
-              (const QuicConnectionId& connection_id),
-              (override));
-};
-
-class QuicSelfIssuedConnectionIdManagerTest : public QuicTest {
- public:
-  QuicSelfIssuedConnectionIdManagerTest()
-      : cid_manager_(/*active_connection_id_limit*/ 2, initial_connection_id_,
-                     &clock_, &alarm_factory_, &cid_manager_visitor_,
-                     /*context=*/nullptr) {
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-    retire_self_issued_cid_alarm_ =
-        QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
-            &cid_manager_);
-  }
-
- protected:
-  MockClock clock_;
-  test::MockAlarmFactory alarm_factory_;
-  TestSelfIssuedConnectionIdManagerVisitor cid_manager_visitor_;
-  QuicConnectionId initial_connection_id_ = TestConnectionId(0);
-  StrictMock<QuicSelfIssuedConnectionIdManager> cid_manager_;
-  QuicAlarm* retire_self_issued_cid_alarm_ = nullptr;
-  std::string error_details_;
-  QuicTime::Delta pto_delay_ = QuicTime::Delta::FromMilliseconds(10);
-};
-
-MATCHER_P3(ExpectedNewConnectionIdFrame,
-           connection_id,
-           sequence_number,
-           retire_prior_to,
-           "") {
-  return (arg.connection_id == connection_id) &&
-         (arg.sequence_number == sequence_number) &&
-         (arg.retire_prior_to == retire_prior_to);
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       RetireSelfIssuedConnectionIdInOrder) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
-  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
-  QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
-  QuicConnectionId cid5 = cid_manager_.GenerateNewConnectionId(cid4);
-
-  // Sends CID #1 to peer.
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
-  EXPECT_CALL(cid_manager_visitor_,
-              SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
-      .WillOnce(Return(true));
-  cid_manager_.MaybeSendNewConnectionIds();
-
-  {
-    // Peer retires CID #0;
-    // Sends CID #2 and asks peer to retire CIDs prior to #1.
-    // Outcome: (#1, #2) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 1u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 0u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #1;
-    // Sends CID #3 and asks peer to retire CIDs prior to #2.
-    // Outcome: (#2, #3) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 1u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #2;
-    // Sends CID #4 and asks peer to retire CIDs prior to #3.
-    // Outcome: (#3, #4) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 3u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 2u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #3;
-    // Sends CID #5 and asks peer to retire CIDs prior to #4.
-    // Outcome: (#4, #5) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid5));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid5, 5u, 4u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 3u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       RetireSelfIssuedConnectionIdOutOfOrder) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
-  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
-  QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
-
-  // Sends CID #1 to peer.
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
-  EXPECT_CALL(cid_manager_visitor_,
-              SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
-      .WillOnce(Return(true));
-  cid_manager_.MaybeSendNewConnectionIds();
-
-  {
-    // Peer retires CID #1;
-    // Sends CID #2 and asks peer to retire CIDs prior to #0.
-    // Outcome: (#0, #2) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 0u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 1u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #1 again. This is a no-op.
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 1u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #0;
-    // Sends CID #3 and asks peer to retire CIDs prior to #2.
-    // Outcome: (#2, #3) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 0u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #3;
-    // Sends CID #4 and asks peer to retire CIDs prior to #2.
-    // Outcome: (#2, #4) are active.
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
-    EXPECT_CALL(cid_manager_visitor_,
-                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 2u)))
-        .WillOnce(Return(true));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 3u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-
-  {
-    // Peer retires CID #0 again. This is a no-op.
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = 0u;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-  }
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       ScheduleConnectionIdRetirementOneAtATime) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
-  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
-  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
-      .Times(3)
-      .WillRepeatedly(Return(true));
-  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
-  QuicRetireConnectionIdFrame retire_cid_frame;
-
-  // CID #1 is sent to peer.
-  cid_manager_.MaybeSendNewConnectionIds();
-
-  // CID #0's retirement is scheduled and CID #2 is sent to peer.
-  retire_cid_frame.sequence_number = 0u;
-  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                  retire_cid_frame, pto_delay_, &error_details_),
-              IsQuicNoError());
-  // While CID #0's retirement is scheduled, it is not retired yet.
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid0, cid1, cid2));
-  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
-  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
-            clock_.ApproximateNow() + connection_id_expire_timeout);
-
-  // CID #0 is actually retired.
-  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
-  clock_.AdvanceTime(connection_id_expire_timeout);
-  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid1, cid2));
-  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-
-  // CID #1's retirement is scheduled and CID #3 is sent to peer.
-  retire_cid_frame.sequence_number = 1u;
-  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                  retire_cid_frame, pto_delay_, &error_details_),
-              IsQuicNoError());
-  // While CID #1's retirement is scheduled, it is not retired yet.
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid1, cid2, cid3));
-  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
-  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
-            clock_.ApproximateNow() + connection_id_expire_timeout);
-
-  // CID #1 is actually retired.
-  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
-  clock_.AdvanceTime(connection_id_expire_timeout);
-  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid2, cid3));
-  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       ScheduleMultipleConnectionIdRetirement) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
-  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
-  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
-      .Times(3)
-      .WillRepeatedly(Return(true));
-  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
-  QuicRetireConnectionIdFrame retire_cid_frame;
-
-  // CID #1 is sent to peer.
-  cid_manager_.MaybeSendNewConnectionIds();
-
-  // CID #0's retirement is scheduled and CID #2 is sent to peer.
-  retire_cid_frame.sequence_number = 0u;
-  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                  retire_cid_frame, pto_delay_, &error_details_),
-              IsQuicNoError());
-
-  clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
-
-  // CID #1's retirement is scheduled and CID #3 is sent to peer.
-  retire_cid_frame.sequence_number = 1u;
-  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                  retire_cid_frame, pto_delay_, &error_details_),
-              IsQuicNoError());
-
-  // While CID #0, #1s retirement is scheduled, they are not retired yet.
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid0, cid1, cid2, cid3));
-  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
-  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
-            clock_.ApproximateNow() + connection_id_expire_timeout * 0.75);
-
-  // CID #0 is actually retired.
-  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
-  clock_.AdvanceTime(connection_id_expire_timeout * 0.75);
-  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid1, cid2, cid3));
-  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
-  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
-            clock_.ApproximateNow() + connection_id_expire_timeout * 0.25);
-
-  // CID #1 is actually retired.
-  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
-  clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
-  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid2, cid3));
-  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       AllExpiredConnectionIdsAreRetiredInOneBatch) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
-  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
-  QuicConnectionId cid;
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
-  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
-      .Times(3)
-      .WillRepeatedly(Return(true));
-  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
-  QuicRetireConnectionIdFrame retire_cid_frame;
-  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
-  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
-  EXPECT_FALSE(cid_manager_.ConsumeOneConnectionId().has_value());
-
-  // CID #1 is sent to peer.
-  cid_manager_.MaybeSendNewConnectionIds();
-  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
-  EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
-  cid = *cid_manager_.ConsumeOneConnectionId();
-  EXPECT_EQ(cid1, cid);
-  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
-
-  // CID #0's retirement is scheduled and CID #2 is sent to peer.
-  retire_cid_frame.sequence_number = 0u;
-  cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
-                                         &error_details_);
-  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
-  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
-  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
-  EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
-  cid = *cid_manager_.ConsumeOneConnectionId();
-  EXPECT_EQ(cid2, cid);
-  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
-
-  clock_.AdvanceTime(connection_id_expire_timeout * 0.1);
-
-  // CID #1's retirement is scheduled and CID #3 is sent to peer.
-  retire_cid_frame.sequence_number = 1u;
-  cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
-                                         &error_details_);
-
-  {
-    // CID #0 & #1 are retired in a single alarm fire.
-    clock_.AdvanceTime(connection_id_expire_timeout);
-    testing::InSequence s;
-    EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
-    EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
-    alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
-    EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid0));
-    EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid1));
-    EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
-    EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-                ElementsAre(cid2, cid3));
-    EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
-  }
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       ErrorWhenRetireConnectionIdNeverIssued) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-
-  // CID #1 is sent to peer.
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(1);
-  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
-      .WillOnce(Return(true));
-  cid_manager_.MaybeSendNewConnectionIds();
-
-  // CID #2 is never issued.
-  QuicRetireConnectionIdFrame retire_cid_frame;
-  retire_cid_frame.sequence_number = 2u;
-  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                  retire_cid_frame, pto_delay_, &error_details_),
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       ErrorWhenTooManyConnectionIdWaitingToBeRetired) {
-  // CID #0 & #1 are issued.
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
-  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
-      .WillOnce(Return(true));
-  cid_manager_.MaybeSendNewConnectionIds();
-
-  // Add 8 connection IDs to the to-be-retired list.
-  QuicConnectionId last_connection_id =
-      cid_manager_.GenerateNewConnectionId(initial_connection_id_);
-  for (int i = 0; i < 8; ++i) {
-    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
-    EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_));
-    QuicRetireConnectionIdFrame retire_cid_frame;
-    retire_cid_frame.sequence_number = i;
-    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                    retire_cid_frame, pto_delay_, &error_details_),
-                IsQuicNoError());
-    last_connection_id =
-        cid_manager_.GenerateNewConnectionId(last_connection_id);
-  }
-  QuicRetireConnectionIdFrame retire_cid_frame;
-  retire_cid_frame.sequence_number = 8u;
-  // This would have push the number of to-be-retired connection IDs over its
-  // limit.
-  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
-                  retire_cid_frame, pto_delay_, &error_details_),
-              IsError(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE));
-}
-
-TEST_F(QuicSelfIssuedConnectionIdManagerTest,
-       DoNotIssueConnectionIdVoluntarilyIfOneHasIssuedForPerferredAddress) {
-  QuicConnectionId cid0 = initial_connection_id_;
-  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
-  ASSERT_THAT(cid_manager_.IssueNewConnectionIdForPreferredAddress(),
-              ExpectedNewConnectionIdFrame(cid1, 1u, 0u));
-  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
-              ElementsAre(cid0, cid1));
-
-  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(0);
-  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_)).Times(0);
-  cid_manager_.MaybeSendNewConnectionIds();
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/quic_connection_id_test.cc b/quic/core/quic_connection_id_test.cc
deleted file mode 100644
index 3f944e3..0000000
--- a/quic/core/quic_connection_id_test.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_id.h"
-
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace {
-
-class QuicConnectionIdTest : public QuicTest {};
-
-TEST_F(QuicConnectionIdTest, Empty) {
-  QuicConnectionId connection_id_empty = EmptyQuicConnectionId();
-  EXPECT_TRUE(connection_id_empty.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, DefaultIsEmpty) {
-  QuicConnectionId connection_id_empty = QuicConnectionId();
-  EXPECT_TRUE(connection_id_empty.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, NotEmpty) {
-  QuicConnectionId connection_id = test::TestConnectionId(1);
-  EXPECT_FALSE(connection_id.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, ZeroIsNotEmpty) {
-  QuicConnectionId connection_id = test::TestConnectionId(0);
-  EXPECT_FALSE(connection_id.IsEmpty());
-}
-
-TEST_F(QuicConnectionIdTest, Data) {
-  char connection_id_data[kQuicDefaultConnectionIdLength];
-  memset(connection_id_data, 0x42, sizeof(connection_id_data));
-  QuicConnectionId connection_id1 =
-      QuicConnectionId(connection_id_data, sizeof(connection_id_data));
-  QuicConnectionId connection_id2 =
-      QuicConnectionId(connection_id_data, sizeof(connection_id_data));
-  EXPECT_EQ(connection_id1, connection_id2);
-  EXPECT_EQ(connection_id1.length(), kQuicDefaultConnectionIdLength);
-  EXPECT_EQ(connection_id1.data(), connection_id1.mutable_data());
-  EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id2.data(),
-                      sizeof(connection_id_data)));
-  EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id_data,
-                      sizeof(connection_id_data)));
-  connection_id2.mutable_data()[0] = 0x33;
-  EXPECT_NE(connection_id1, connection_id2);
-  static const uint8_t kNewLength = 4;
-  connection_id2.set_length(kNewLength);
-  EXPECT_EQ(kNewLength, connection_id2.length());
-}
-
-TEST_F(QuicConnectionIdTest, SpanData) {
-  QuicConnectionId connection_id = QuicConnectionId({0x01, 0x02, 0x03});
-  EXPECT_EQ(connection_id.length(), 3);
-  QuicConnectionId empty_connection_id =
-      QuicConnectionId(absl::Span<uint8_t>());
-  EXPECT_EQ(empty_connection_id.length(), 0);
-  QuicConnectionId connection_id2 = QuicConnectionId({
-      0x01,
-      0x02,
-      0x03,
-      0x04,
-      0x05,
-      0x06,
-      0x07,
-      0x08,
-      0x09,
-      0x0a,
-      0x0b,
-      0x0c,
-      0x0d,
-      0x0e,
-      0x0f,
-      0x10,
-  });
-  EXPECT_EQ(connection_id2.length(), 16);
-}
-
-TEST_F(QuicConnectionIdTest, DoubleConvert) {
-  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
-  QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
-  QuicConnectionId connection_id64_3 =
-      test::TestConnectionId(UINT64_C(0xfedcba9876543210));
-  EXPECT_EQ(connection_id64_1,
-            test::TestConnectionId(
-                test::TestConnectionIdToUInt64(connection_id64_1)));
-  EXPECT_EQ(connection_id64_2,
-            test::TestConnectionId(
-                test::TestConnectionIdToUInt64(connection_id64_2)));
-  EXPECT_EQ(connection_id64_3,
-            test::TestConnectionId(
-                test::TestConnectionIdToUInt64(connection_id64_3)));
-  EXPECT_NE(connection_id64_1, connection_id64_2);
-  EXPECT_NE(connection_id64_1, connection_id64_3);
-  EXPECT_NE(connection_id64_2, connection_id64_3);
-}
-
-TEST_F(QuicConnectionIdTest, Hash) {
-  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
-  QuicConnectionId connection_id64_1b = test::TestConnectionId(1);
-  QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
-  QuicConnectionId connection_id64_3 =
-      test::TestConnectionId(UINT64_C(0xfedcba9876543210));
-  EXPECT_EQ(connection_id64_1.Hash(), connection_id64_1b.Hash());
-  EXPECT_NE(connection_id64_1.Hash(), connection_id64_2.Hash());
-  EXPECT_NE(connection_id64_1.Hash(), connection_id64_3.Hash());
-  EXPECT_NE(connection_id64_2.Hash(), connection_id64_3.Hash());
-
-  // Verify that any two all-zero connection IDs of different lengths never
-  // have the same hash.
-  const char connection_id_bytes[255] = {};
-  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
-    QuicConnectionId connection_id_i(connection_id_bytes, i);
-    for (uint8_t j = i + 1; j < sizeof(connection_id_bytes); ++j) {
-      QuicConnectionId connection_id_j(connection_id_bytes, j);
-      EXPECT_NE(connection_id_i.Hash(), connection_id_j.Hash());
-    }
-  }
-}
-
-TEST_F(QuicConnectionIdTest, AssignAndCopy) {
-  QuicConnectionId connection_id = test::TestConnectionId(1);
-  QuicConnectionId connection_id2 = test::TestConnectionId(2);
-  connection_id = connection_id2;
-  EXPECT_EQ(connection_id, test::TestConnectionId(2));
-  EXPECT_NE(connection_id, test::TestConnectionId(1));
-  connection_id = QuicConnectionId(test::TestConnectionId(1));
-  EXPECT_EQ(connection_id, test::TestConnectionId(1));
-  EXPECT_NE(connection_id, test::TestConnectionId(2));
-}
-
-TEST_F(QuicConnectionIdTest, ChangeLength) {
-  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
-  QuicConnectionId connection_id64_2 = test::TestConnectionId(2);
-  QuicConnectionId connection_id136_2 = test::TestConnectionId(2);
-  connection_id136_2.set_length(17);
-  memset(connection_id136_2.mutable_data() + 8, 0, 9);
-  char connection_id136_2_bytes[17] = {0, 0, 0, 0, 0, 0, 0, 2, 0,
-                                       0, 0, 0, 0, 0, 0, 0, 0};
-  QuicConnectionId connection_id136_2b(connection_id136_2_bytes,
-                                       sizeof(connection_id136_2_bytes));
-  EXPECT_EQ(connection_id136_2, connection_id136_2b);
-  QuicConnectionId connection_id = connection_id64_1;
-  connection_id.set_length(17);
-  EXPECT_NE(connection_id64_1, connection_id);
-  // Check resizing big to small.
-  connection_id.set_length(8);
-  EXPECT_EQ(connection_id64_1, connection_id);
-  // Check resizing small to big.
-  connection_id.set_length(17);
-  memset(connection_id.mutable_data(), 0, connection_id.length());
-  memcpy(connection_id.mutable_data(), connection_id64_2.data(),
-         connection_id64_2.length());
-  EXPECT_EQ(connection_id136_2, connection_id);
-  EXPECT_EQ(connection_id136_2b, connection_id);
-  QuicConnectionId connection_id120(connection_id136_2_bytes, 15);
-  connection_id.set_length(15);
-  EXPECT_EQ(connection_id120, connection_id);
-  // Check resizing big to big.
-  QuicConnectionId connection_id2 = connection_id120;
-  connection_id2.set_length(17);
-  connection_id2.mutable_data()[15] = 0;
-  connection_id2.mutable_data()[16] = 0;
-  EXPECT_EQ(connection_id136_2, connection_id2);
-  EXPECT_EQ(connection_id136_2b, connection_id2);
-}
-
-}  // namespace
-
-}  // namespace quic
diff --git a/quic/core/quic_connection_stats.cc b/quic/core/quic_connection_stats.cc
deleted file mode 100644
index fbaa20a..0000000
--- a/quic/core/quic_connection_stats.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection_stats.h"
-
-namespace quic {
-
-std::ostream& operator<<(std::ostream& os, const QuicConnectionStats& s) {
-  os << "{ bytes_sent: " << s.bytes_sent;
-  os << " packets_sent: " << s.packets_sent;
-  os << " stream_bytes_sent: " << s.stream_bytes_sent;
-  os << " packets_discarded: " << s.packets_discarded;
-  os << " bytes_received: " << s.bytes_received;
-  os << " packets_received: " << s.packets_received;
-  os << " packets_processed: " << s.packets_processed;
-  os << " stream_bytes_received: " << s.stream_bytes_received;
-  os << " bytes_retransmitted: " << s.bytes_retransmitted;
-  os << " packets_retransmitted: " << s.packets_retransmitted;
-  os << " bytes_spuriously_retransmitted: " << s.bytes_spuriously_retransmitted;
-  os << " packets_spuriously_retransmitted: "
-     << s.packets_spuriously_retransmitted;
-  os << " packets_lost: " << s.packets_lost;
-  os << " slowstart_packets_sent: " << s.slowstart_packets_sent;
-  os << " slowstart_packets_lost: " << s.slowstart_packets_lost;
-  os << " slowstart_bytes_lost: " << s.slowstart_bytes_lost;
-  os << " packets_dropped: " << s.packets_dropped;
-  os << " undecryptable_packets_received_before_handshake_complete: "
-     << s.undecryptable_packets_received_before_handshake_complete;
-  os << " crypto_retransmit_count: " << s.crypto_retransmit_count;
-  os << " loss_timeout_count: " << s.loss_timeout_count;
-  os << " tlp_count: " << s.tlp_count;
-  os << " rto_count: " << s.rto_count;
-  os << " pto_count: " << s.pto_count;
-  os << " min_rtt_us: " << s.min_rtt_us;
-  os << " srtt_us: " << s.srtt_us;
-  os << " egress_mtu: " << s.egress_mtu;
-  os << " max_egress_mtu: " << s.max_egress_mtu;
-  os << " ingress_mtu: " << s.ingress_mtu;
-  os << " estimated_bandwidth: " << s.estimated_bandwidth;
-  os << " packets_reordered: " << s.packets_reordered;
-  os << " max_sequence_reordering: " << s.max_sequence_reordering;
-  os << " max_time_reordering_us: " << s.max_time_reordering_us;
-  os << " tcp_loss_events: " << s.tcp_loss_events;
-  os << " connection_creation_time: "
-     << s.connection_creation_time.ToDebuggingValue();
-  os << " blocked_frames_received: " << s.blocked_frames_received;
-  os << " blocked_frames_sent: " << s.blocked_frames_sent;
-  os << " num_connectivity_probing_received: "
-     << s.num_connectivity_probing_received;
-  os << " retry_packet_processed: "
-     << (s.retry_packet_processed ? "yes" : "no");
-  os << " num_coalesced_packets_received: " << s.num_coalesced_packets_received;
-  os << " num_coalesced_packets_processed: "
-     << s.num_coalesced_packets_processed;
-  os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs;
-  os << " sent_legacy_version_encapsulated_packets: "
-     << s.sent_legacy_version_encapsulated_packets;
-  os << " key_update_count: " << s.key_update_count;
-  os << " num_failed_authentication_packets_received: "
-     << s.num_failed_authentication_packets_received;
-  os << " num_tls_server_zero_rtt_packets_received_after_discarding_decrypter: "
-     << s.num_tls_server_zero_rtt_packets_received_after_discarding_decrypter;
-  os << " address_validated_via_decrypting_packet: "
-     << s.address_validated_via_decrypting_packet;
-  os << " address_validated_via_token: " << s.address_validated_via_token;
-  os << " }";
-
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_connection_stats.h b/quic/core/quic_connection_stats.h
deleted file mode 100644
index 39fd5b0..0000000
--- a/quic/core/quic_connection_stats.h
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
-#define QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
-
-#include <cstdint>
-#include <ostream>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Structure to hold stats for a QuicConnection.
-struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicConnectionStats& s);
-
-  QuicByteCount bytes_sent = 0;  // Includes retransmissions.
-  QuicPacketCount packets_sent = 0;
-  // Non-retransmitted bytes sent in a stream frame.
-  QuicByteCount stream_bytes_sent = 0;
-  // Packets serialized and discarded before sending.
-  QuicPacketCount packets_discarded = 0;
-
-  // These include version negotiation and public reset packets, which do not
-  // have packet numbers or frame data.
-  QuicByteCount bytes_received = 0;  // Includes duplicate data for a stream.
-  // Includes packets which were not processable.
-  QuicPacketCount packets_received = 0;
-  // Excludes packets which were not processable.
-  QuicPacketCount packets_processed = 0;
-  QuicByteCount stream_bytes_received = 0;  // Bytes received in a stream frame.
-
-  QuicByteCount bytes_retransmitted = 0;
-  QuicPacketCount packets_retransmitted = 0;
-
-  QuicByteCount bytes_spuriously_retransmitted = 0;
-  QuicPacketCount packets_spuriously_retransmitted = 0;
-  // Number of packets abandoned as lost by the loss detection algorithm.
-  QuicPacketCount packets_lost = 0;
-  QuicPacketCount packet_spuriously_detected_lost = 0;
-
-  // The sum of loss detection response times of all lost packets, in number of
-  // round trips.
-  // Given a packet detected as lost:
-  //   T(S)                            T(1Rtt)    T(D)
-  //     |_________________________________|_______|
-  // Where
-  //   T(S) is the time when the packet is sent.
-  //   T(1Rtt) is one rtt after T(S), using the rtt at the time of detection.
-  //   T(D) is the time of detection, i.e. when the packet is declared as lost.
-  // The loss detection response time is defined as
-  //     (T(D) - T(S)) / (T(1Rtt) - T(S))
-  //
-  // The average loss detection response time is this number divided by
-  // |packets_lost|. Smaller result means detection is faster.
-  float total_loss_detection_response_time = 0.0;
-
-  // Number of times this connection went through the slow start phase.
-  uint32_t slowstart_count = 0;
-  // Number of round trips spent in slow start.
-  uint32_t slowstart_num_rtts = 0;
-  // Number of packets sent in slow start.
-  QuicPacketCount slowstart_packets_sent = 0;
-  // Number of bytes sent in slow start.
-  QuicByteCount slowstart_bytes_sent = 0;
-  // Number of packets lost exiting slow start.
-  QuicPacketCount slowstart_packets_lost = 0;
-  // Number of bytes lost exiting slow start.
-  QuicByteCount slowstart_bytes_lost = 0;
-  // Time spent in slow start. Populated for BBRv1 and BBRv2.
-  QuicTimeAccumulator slowstart_duration;
-
-  // Number of PROBE_BW cycles. Populated for BBRv1 and BBRv2.
-  uint32_t bbr_num_cycles = 0;
-  // Number of PROBE_BW cycles shortened for reno coexistence. BBRv2 only.
-  uint32_t bbr_num_short_cycles_for_reno_coexistence = 0;
-  // Whether BBR exited STARTUP due to excessive loss. Populated for BBRv1 and
-  // BBRv2.
-  bool bbr_exit_startup_due_to_loss = false;
-
-  QuicPacketCount packets_dropped = 0;  // Duplicate or less than least unacked.
-
-  // Packets that failed to decrypt when they were first received,
-  // before the handshake was complete.
-  QuicPacketCount undecryptable_packets_received_before_handshake_complete = 0;
-
-  size_t crypto_retransmit_count = 0;
-  // Count of times the loss detection alarm fired.  At least one packet should
-  // be lost when the alarm fires.
-  size_t loss_timeout_count = 0;
-  size_t tlp_count = 0;
-  size_t rto_count = 0;  // Count of times the rto timer fired.
-  size_t pto_count = 0;
-
-  int64_t min_rtt_us = 0;  // Minimum RTT in microseconds.
-  int64_t srtt_us = 0;     // Smoothed RTT in microseconds.
-  int64_t cwnd_bootstrapping_rtt_us = 0;  // RTT used in cwnd_bootstrapping.
-  // The connection's |long_term_mtu_| used for sending packets, populated by
-  // QuicConnection::GetStats().
-  QuicByteCount egress_mtu = 0;
-  // The maximum |long_term_mtu_| the connection ever used.
-  QuicByteCount max_egress_mtu = 0;
-  // Size of the largest packet received from the peer, populated by
-  // QuicConnection::GetStats().
-  QuicByteCount ingress_mtu = 0;
-  QuicBandwidth estimated_bandwidth = QuicBandwidth::Zero();
-
-  // Reordering stats for received packets.
-  // Number of packets received out of packet number order.
-  QuicPacketCount packets_reordered = 0;
-  // Maximum reordering observed in packet number space.
-  QuicPacketCount max_sequence_reordering = 0;
-  // Maximum reordering observed in microseconds
-  int64_t max_time_reordering_us = 0;
-
-  // Maximum sequence reordering observed from acked packets.
-  QuicPacketCount sent_packets_max_sequence_reordering = 0;
-  // Number of times that a packet is not detected as lost per reordering_shift,
-  // but would have been if the reordering_shift increases by one.
-  QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
-
-  // The following stats are used only in TcpCubicSender.
-  // The number of loss events from TCP's perspective.  Each loss event includes
-  // one or more lost packets.
-  uint32_t tcp_loss_events = 0;
-
-  // Creation time, as reported by the QuicClock.
-  QuicTime connection_creation_time = QuicTime::Zero();
-
-  // Handshake completion time.
-  QuicTime handshake_completion_time = QuicTime::Zero();
-
-  uint64_t blocked_frames_received = 0;
-  uint64_t blocked_frames_sent = 0;
-
-  // Number of connectivity probing packets received by this connection.
-  uint64_t num_connectivity_probing_received = 0;
-
-  // Whether a RETRY packet was successfully processed.
-  bool retry_packet_processed = false;
-
-  // Number of received coalesced packets.
-  uint64_t num_coalesced_packets_received = 0;
-  // Number of successfully processed coalesced packets.
-  uint64_t num_coalesced_packets_processed = 0;
-  // Number of ack aggregation epochs. For the same number of bytes acked, the
-  // smaller this value, the more ack aggregation is going on.
-  uint64_t num_ack_aggregation_epochs = 0;
-
-  // Whether overshooting is detected (and pacing rate decreases) during start
-  // up with network parameters adjusted.
-  bool overshooting_detected_with_network_parameters_adjusted = false;
-
-  // Whether there is any non app-limited bandwidth sample.
-  bool has_non_app_limited_sample = false;
-
-  // Packet number of first decrypted packet.
-  QuicPacketNumber first_decrypted_packet;
-
-  // Max consecutive retransmission timeout before making forward progress.
-  size_t max_consecutive_rto_with_forward_progress = 0;
-
-  // Number of sent packets that were encapsulated using Legacy Version
-  // Encapsulation.
-  QuicPacketCount sent_legacy_version_encapsulated_packets = 0;
-
-  // Number of times when the connection tries to send data but gets throttled
-  // by amplification factor.
-  size_t num_amplification_throttling = 0;
-
-  // Number of key phase updates that have occurred. In the case of a locally
-  // initiated key update, this is incremented when the keys are updated, before
-  // the peer has acknowledged the key update.
-  uint32_t key_update_count = 0;
-
-  // Counts the number of undecryptable packets received across all keys. Does
-  // not include packets where a decryption key for that level was absent.
-  QuicPacketCount num_failed_authentication_packets_received = 0;
-
-  // Counts the number of QUIC+TLS 0-RTT packets received after 0-RTT decrypter
-  // was discarded, only on server connections.
-  QuicPacketCount
-      num_tls_server_zero_rtt_packets_received_after_discarding_decrypter = 0;
-
-  // True if address is validated via decrypting HANDSHAKE or 1-RTT packet.
-  bool address_validated_via_decrypting_packet = false;
-
-  // True if address is validated via validating token received in INITIAL
-  // packet.
-  bool address_validated_via_token = false;
-
-  size_t ping_frames_sent = 0;
-
-  // Number of detected peer address changes which changes to a peer address
-  // validated by earlier path validation.
-  size_t num_peer_migration_to_proactively_validated_address = 0;
-  // Number of detected peer address changes which triggers reverse path
-  // validation.
-  size_t num_reverse_path_validtion_upon_migration = 0;
-  // Number of detected peer migrations which either succeed reverse path
-  // validation or no need to be validated.
-  size_t num_validated_peer_migration = 0;
-  // Number of detected peer migrations which triggered reverse path validation
-  // and failed and fell back to the old path.
-  size_t num_invalid_peer_migration = 0;
-  // Number of detected peer migrations which triggered reverse path validation
-  // which was canceled because the peer migrated again. Such migration is also
-  // counted as invalid peer migration.
-  size_t num_peer_migration_while_validating_default_path = 0;
-  // Number of NEW_CONNECTION_ID frames sent.
-  size_t num_new_connection_id_sent = 0;
-  // Number of RETIRE_CONNECTION_ID frames sent.
-  size_t num_retire_connection_id_sent = 0;
-
-  struct QUIC_NO_EXPORT TlsServerOperationStats {
-    bool success = false;
-    // If the operation is performed asynchronously, how long did it take.
-    // Zero() for synchronous operations.
-    QuicTime::Delta async_latency = QuicTime::Delta::Zero();
-  };
-
-  // The TLS server op stats only have values when the corresponding operation
-  // is performed by TlsServerHandshaker. If an operation is done within
-  // BoringSSL, e.g. ticket decrypted without using
-  // TlsServerHandshaker::SessionTicketOpen, it will not be recorded here.
-  absl::optional<TlsServerOperationStats> tls_server_select_cert_stats;
-  absl::optional<TlsServerOperationStats> tls_server_compute_signature_stats;
-  absl::optional<TlsServerOperationStats> tls_server_decrypt_ticket_stats;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
deleted file mode 100644
index 6f7b4e2..0000000
--- a/quic/core/quic_connection_test.cc
+++ /dev/null
@@ -1,15834 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_connection.h"
-
-#include <errno.h>
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/frames/quic_connection_close_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_path_response_frame.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_coalesced_packet_peer.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_packet_creator_peer.h"
-#include "quic/test_tools/quic_path_validator_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-#include "quic/test_tools/simple_session_notifier.h"
-#include "common/platform/api/quiche_reference_counted.h"
-#include "common/simple_buffer_allocator.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::DoAll;
-using testing::ElementsAre;
-using testing::Ge;
-using testing::IgnoreResult;
-using testing::InSequence;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::Lt;
-using testing::Ref;
-using testing::Return;
-using testing::SaveArg;
-using testing::SetArgPointee;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char data1[] = "foo data";
-const char data2[] = "bar data";
-
-const bool kHasStopWaiting = true;
-
-const int kDefaultRetransmissionTimeMs = 500;
-
-DiversificationNonce kTestDiversificationNonce = {
-    'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a',
-    'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
-    'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
-};
-
-const StatelessResetToken kTestStatelessResetToken{
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
-
-const QuicSocketAddress kPeerAddress =
-    QuicSocketAddress(QuicIpAddress::Loopback6(),
-                      /*port=*/12345);
-const QuicSocketAddress kSelfAddress =
-    QuicSocketAddress(QuicIpAddress::Loopback6(),
-                      /*port=*/443);
-
-QuicStreamId GetNthClientInitiatedStreamId(int n,
-                                           QuicTransportVersion version) {
-  return QuicUtils::GetFirstBidirectionalStreamId(version,
-                                                  Perspective::IS_CLIENT) +
-         n * 2;
-}
-
-QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-      return INITIAL;
-    case ENCRYPTION_HANDSHAKE:
-      return HANDSHAKE;
-    case ENCRYPTION_ZERO_RTT:
-      return ZERO_RTT_PROTECTED;
-    case ENCRYPTION_FORWARD_SECURE:
-      QUICHE_DCHECK(false);
-      return INVALID_PACKET_TYPE;
-    default:
-      QUICHE_DCHECK(false);
-      return INVALID_PACKET_TYPE;
-  }
-}
-
-// A NullEncrypterWithConfidentialityLimit is a NullEncrypter that allows
-// specifying the confidentiality limit on the maximum number of packets that
-// may be encrypted per key phase in TLS+QUIC.
-class NullEncrypterWithConfidentialityLimit : public NullEncrypter {
- public:
-  NullEncrypterWithConfidentialityLimit(Perspective perspective,
-                                        QuicPacketCount confidentiality_limit)
-      : NullEncrypter(perspective),
-        confidentiality_limit_(confidentiality_limit) {}
-
-  QuicPacketCount GetConfidentialityLimit() const override {
-    return confidentiality_limit_;
-  }
-
- private:
-  QuicPacketCount confidentiality_limit_;
-};
-
-class StrictTaggingDecrypterWithIntegrityLimit : public StrictTaggingDecrypter {
- public:
-  StrictTaggingDecrypterWithIntegrityLimit(uint8_t tag,
-                                           QuicPacketCount integrity_limit)
-      : StrictTaggingDecrypter(tag), integrity_limit_(integrity_limit) {}
-
-  QuicPacketCount GetIntegrityLimit() const override {
-    return integrity_limit_;
-  }
-
- private:
-  QuicPacketCount integrity_limit_;
-};
-
-class TestConnectionHelper : public QuicConnectionHelperInterface {
- public:
-  TestConnectionHelper(MockClock* clock, MockRandom* random_generator)
-      : clock_(clock), random_generator_(random_generator) {
-    clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-  TestConnectionHelper(const TestConnectionHelper&) = delete;
-  TestConnectionHelper& operator=(const TestConnectionHelper&) = delete;
-
-  // QuicConnectionHelperInterface
-  const QuicClock* GetClock() const override { return clock_; }
-
-  QuicRandom* GetRandomGenerator() override { return random_generator_; }
-
-  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override {
-    return &buffer_allocator_;
-  }
-
- private:
-  MockClock* clock_;
-  MockRandom* random_generator_;
-  quiche::SimpleBufferAllocator buffer_allocator_;
-};
-
-class TestConnection : public QuicConnection {
- public:
-  TestConnection(QuicConnectionId connection_id,
-                 QuicSocketAddress initial_self_address,
-                 QuicSocketAddress initial_peer_address,
-                 TestConnectionHelper* helper, TestAlarmFactory* alarm_factory,
-                 TestPacketWriter* writer, Perspective perspective,
-                 ParsedQuicVersion version)
-      : QuicConnection(connection_id, initial_self_address,
-                       initial_peer_address, helper, alarm_factory, writer,
-                       /* owns_writer= */ false, perspective,
-                       SupportedVersions(version)),
-        notifier_(nullptr) {
-    writer->set_perspective(perspective);
-    SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                 std::make_unique<NullEncrypter>(perspective));
-    SetDataProducer(&producer_);
-    ON_CALL(*this, OnSerializedPacket(_))
-        .WillByDefault([this](SerializedPacket packet) {
-          QuicConnection::OnSerializedPacket(std::move(packet));
-        });
-  }
-  TestConnection(const TestConnection&) = delete;
-  TestConnection& operator=(const TestConnection&) = delete;
-
-  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket packet), (override));
-
-  void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
-    QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
-  }
-
-  void SetLossAlgorithm(LossDetectionInterface* loss_algorithm) {
-    QuicConnectionPeer::SetLossAlgorithm(this, loss_algorithm);
-  }
-
-  void SendPacket(EncryptionLevel /*level*/, uint64_t packet_number,
-                  std::unique_ptr<QuicPacket> packet,
-                  HasRetransmittableData retransmittable, bool has_ack,
-                  bool has_pending_frames) {
-    ScopedPacketFlusher flusher(this);
-    char buffer[kMaxOutgoingPacketSize];
-    size_t encrypted_length =
-        QuicConnectionPeer::GetFramer(this)->EncryptPayload(
-            ENCRYPTION_INITIAL, QuicPacketNumber(packet_number), *packet,
-            buffer, kMaxOutgoingPacketSize);
-    SerializedPacket serialized_packet(
-        QuicPacketNumber(packet_number), PACKET_4BYTE_PACKET_NUMBER, buffer,
-        encrypted_length, has_ack, has_pending_frames);
-    serialized_packet.peer_address = kPeerAddress;
-    if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
-      serialized_packet.retransmittable_frames.push_back(
-          QuicFrame(QuicPingFrame()));
-    }
-    OnSerializedPacket(std::move(serialized_packet));
-  }
-
-  QuicConsumedData SaveAndSendStreamData(QuicStreamId id,
-                                         absl::string_view data,
-                                         QuicStreamOffset offset,
-                                         StreamSendingState state) {
-    ScopedPacketFlusher flusher(this);
-    producer_.SaveStreamData(id, data);
-    if (notifier_ != nullptr) {
-      return notifier_->WriteOrBufferData(id, data.length(), state);
-    }
-    return QuicConnection::SendStreamData(id, data.length(), offset, state);
-  }
-
-  QuicConsumedData SendStreamDataWithString(QuicStreamId id,
-                                            absl::string_view data,
-                                            QuicStreamOffset offset,
-                                            StreamSendingState state) {
-    ScopedPacketFlusher flusher(this);
-    if (!QuicUtils::IsCryptoStreamId(transport_version(), id) &&
-        this->encryption_level() == ENCRYPTION_INITIAL) {
-      this->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-      if (perspective() == Perspective::IS_CLIENT && !IsHandshakeComplete()) {
-        OnHandshakeComplete();
-      }
-      if (version().SupportsAntiAmplificationLimit()) {
-        QuicConnectionPeer::SetAddressValidated(this);
-      }
-    }
-    return SaveAndSendStreamData(id, data, offset, state);
-  }
-
-  QuicConsumedData SendApplicationDataAtLevel(EncryptionLevel encryption_level,
-                                              QuicStreamId id,
-                                              absl::string_view data,
-                                              QuicStreamOffset offset,
-                                              StreamSendingState state) {
-    ScopedPacketFlusher flusher(this);
-    QUICHE_DCHECK(encryption_level >= ENCRYPTION_ZERO_RTT);
-    SetEncrypter(encryption_level, std::make_unique<TaggingEncrypter>(0x01));
-    SetDefaultEncryptionLevel(encryption_level);
-    return SaveAndSendStreamData(id, data, offset, state);
-  }
-
-  QuicConsumedData SendStreamData3() {
-    return SendStreamDataWithString(
-        GetNthClientInitiatedStreamId(1, transport_version()), "food", 0,
-        NO_FIN);
-  }
-
-  QuicConsumedData SendStreamData5() {
-    return SendStreamDataWithString(
-        GetNthClientInitiatedStreamId(2, transport_version()), "food2", 0,
-        NO_FIN);
-  }
-
-  // Ensures the connection can write stream data before writing.
-  QuicConsumedData EnsureWritableAndSendStreamData5() {
-    EXPECT_TRUE(CanWrite(HAS_RETRANSMITTABLE_DATA));
-    return SendStreamData5();
-  }
-
-  // The crypto stream has special semantics so that it is not blocked by a
-  // congestion window limitation, and also so that it gets put into a separate
-  // packet (so that it is easier to reason about a crypto frame not being
-  // split needlessly across packet boundaries).  As a result, we have separate
-  // tests for some cases for this stream.
-  QuicConsumedData SendCryptoStreamData() {
-    QuicStreamOffset offset = 0;
-    absl::string_view data("chlo");
-    if (!QuicVersionUsesCryptoFrames(transport_version())) {
-      return SendCryptoDataWithString(data, offset);
-    }
-    producer_.SaveCryptoData(ENCRYPTION_INITIAL, offset, data);
-    size_t bytes_written;
-    if (notifier_) {
-      bytes_written =
-          notifier_->WriteCryptoData(ENCRYPTION_INITIAL, data.length(), offset);
-    } else {
-      bytes_written = QuicConnection::SendCryptoData(ENCRYPTION_INITIAL,
-                                                     data.length(), offset);
-    }
-    return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
-  }
-
-  QuicConsumedData SendCryptoDataWithString(absl::string_view data,
-                                            QuicStreamOffset offset) {
-    return SendCryptoDataWithString(data, offset, ENCRYPTION_INITIAL);
-  }
-
-  QuicConsumedData SendCryptoDataWithString(absl::string_view data,
-                                            QuicStreamOffset offset,
-                                            EncryptionLevel encryption_level) {
-    if (!QuicVersionUsesCryptoFrames(transport_version())) {
-      return SendStreamDataWithString(
-          QuicUtils::GetCryptoStreamId(transport_version()), data, offset,
-          NO_FIN);
-    }
-    producer_.SaveCryptoData(encryption_level, offset, data);
-    size_t bytes_written;
-    if (notifier_) {
-      bytes_written =
-          notifier_->WriteCryptoData(encryption_level, data.length(), offset);
-    } else {
-      bytes_written = QuicConnection::SendCryptoData(encryption_level,
-                                                     data.length(), offset);
-    }
-    return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
-  }
-
-  void set_version(ParsedQuicVersion version) {
-    QuicConnectionPeer::GetFramer(this)->set_version(version);
-  }
-
-  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
-    QuicConnectionPeer::GetFramer(this)->SetSupportedVersions(versions);
-    writer()->SetSupportedVersions(versions);
-  }
-
-  // This should be called before setting customized encrypters/decrypters for
-  // connection and peer creator.
-  void set_perspective(Perspective perspective) {
-    writer()->set_perspective(perspective);
-    QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(this);
-    QuicConnectionPeer::SetPerspective(this, perspective);
-    QuicSentPacketManagerPeer::SetPerspective(
-        QuicConnectionPeer::GetSentPacketManager(this), perspective);
-    QuicConnectionPeer::GetFramer(this)->SetInitialObfuscators(
-        TestConnectionId());
-    for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
-                                  ENCRYPTION_FORWARD_SECURE}) {
-      if (QuicConnectionPeer::GetFramer(this)->HasEncrypterOfEncryptionLevel(
-              level)) {
-        SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
-      }
-      if (QuicConnectionPeer::GetFramer(this)->HasDecrypterOfEncryptionLevel(
-              level)) {
-        InstallDecrypter(level, std::make_unique<NullDecrypter>(perspective));
-      }
-    }
-  }
-
-  // Enable path MTU discovery.  Assumes that the test is performed from the
-  // server perspective and the higher value of MTU target is used.
-  void EnablePathMtuDiscovery(MockSendAlgorithm* send_algorithm) {
-    ASSERT_EQ(Perspective::IS_SERVER, perspective());
-
-    if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
-      OnConfigNegotiated();
-    } else {
-      QuicConfig config;
-      QuicTagVector connection_options;
-      connection_options.push_back(kMTUH);
-      config.SetInitialReceivedConnectionOptions(connection_options);
-      EXPECT_CALL(*send_algorithm, SetFromConfig(_, _));
-      SetFromConfig(config);
-    }
-
-    // Normally, the pacing would be disabled in the test, but calling
-    // SetFromConfig enables it.  Set nearly-infinite bandwidth to make the
-    // pacing algorithm work.
-    EXPECT_CALL(*send_algorithm, PacingRate(_))
-        .WillRepeatedly(Return(QuicBandwidth::Infinite()));
-  }
-
-  TestAlarmFactory::TestAlarm* GetAckAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetAckAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetPingAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetPingAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetRetransmissionAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetRetransmissionAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetSendAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetSendAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetTimeoutAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetIdleNetworkDetectorAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetMtuDiscoveryAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetProcessUndecryptablePacketsAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetDiscardPreviousOneRttKeysAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetDiscardZeroRttDecryptionKeysAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetBlackholeDetectorAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetBlackholeDetectorAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetRetirePeerIssuedConnectionIdAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(this));
-  }
-
-  TestAlarmFactory::TestAlarm* GetRetireSelfIssuedConnectionIdAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(this));
-  }
-
-  void PathDegradingTimeout() {
-    QUICHE_DCHECK(PathDegradingDetectionInProgress());
-    GetBlackholeDetectorAlarm()->Fire();
-  }
-
-  bool PathDegradingDetectionInProgress() {
-    return QuicConnectionPeer::GetPathDegradingDeadline(this).IsInitialized();
-  }
-
-  bool BlackholeDetectionInProgress() {
-    return QuicConnectionPeer::GetBlackholeDetectionDeadline(this)
-        .IsInitialized();
-  }
-
-  bool PathMtuReductionDetectionInProgress() {
-    return QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(this)
-        .IsInitialized();
-  }
-
-  void SetMaxTailLossProbes(size_t max_tail_loss_probes) {
-    QuicSentPacketManagerPeer::SetMaxTailLossProbes(
-        QuicConnectionPeer::GetSentPacketManager(this), max_tail_loss_probes);
-  }
-
-  QuicByteCount GetBytesInFlight() {
-    return QuicConnectionPeer::GetSentPacketManager(this)->GetBytesInFlight();
-  }
-
-  void set_notifier(SimpleSessionNotifier* notifier) { notifier_ = notifier; }
-
-  void ReturnEffectivePeerAddressForNextPacket(const QuicSocketAddress& addr) {
-    next_effective_peer_addr_ = std::make_unique<QuicSocketAddress>(addr);
-  }
-
-  bool PtoEnabled() {
-    if (QuicConnectionPeer::GetSentPacketManager(this)->pto_enabled()) {
-      // TLP/RTO related tests are stale when PTO is enabled.
-      QUICHE_DCHECK(PROTOCOL_TLS1_3 == version().handshake_protocol ||
-                    GetQuicRestartFlag(quic_default_on_pto2));
-      return true;
-    }
-    return false;
-  }
-
-  void SendOrQueuePacket(SerializedPacket packet) override {
-    QuicConnection::SendOrQueuePacket(std::move(packet));
-    self_address_on_default_path_while_sending_packet_ = self_address();
-  }
-
-  QuicSocketAddress self_address_on_default_path_while_sending_packet() {
-    return self_address_on_default_path_while_sending_packet_;
-  }
-
-  SimpleDataProducer* producer() { return &producer_; }
-
-  using QuicConnection::active_effective_peer_migration_type;
-  using QuicConnection::IsCurrentPacketConnectivityProbing;
-  using QuicConnection::SelectMutualVersion;
-  using QuicConnection::SendProbingRetransmissions;
-  using QuicConnection::set_defer_send_in_response_to_packets;
-
- protected:
-  QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const override {
-    if (next_effective_peer_addr_) {
-      return *std::move(next_effective_peer_addr_);
-    }
-    return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
-  }
-
- private:
-  TestPacketWriter* writer() {
-    return static_cast<TestPacketWriter*>(QuicConnection::writer());
-  }
-
-  SimpleDataProducer producer_;
-
-  SimpleSessionNotifier* notifier_;
-
-  std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_;
-
-  QuicSocketAddress self_address_on_default_path_while_sending_packet_;
-};
-
-enum class AckResponse { kDefer, kImmediate };
-
-// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
-struct TestParams {
-  TestParams(ParsedQuicVersion version, AckResponse ack_response,
-             bool no_stop_waiting)
-      : version(version),
-        ack_response(ack_response),
-        no_stop_waiting(no_stop_waiting) {}
-
-  ParsedQuicVersion version;
-  AckResponse ack_response;
-  bool no_stop_waiting;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(p.version), "_",
-      (p.ack_response == AckResponse::kDefer ? "defer" : "immediate"), "_",
-      (p.no_stop_waiting ? "No" : ""), "StopWaiting");
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
-  QuicFlagSaver flags;
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
-    for (AckResponse ack_response :
-         {AckResponse::kDefer, AckResponse::kImmediate}) {
-      params.push_back(
-          TestParams(all_supported_versions[i], ack_response, true));
-      if (!all_supported_versions[i].HasIetfInvariantHeader()) {
-        params.push_back(
-            TestParams(all_supported_versions[i], ack_response, false));
-      }
-    }
-  }
-  return params;
-}
-
-class QuicConnectionTest : public QuicTestWithParam<TestParams> {
- public:
-  // For tests that do silent connection closes, no such packet is generated. In
-  // order to verify the contents of the OnConnectionClosed upcall, EXPECTs
-  // should invoke this method, saving the frame, and then the test can verify
-  // the contents.
-  void SaveConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
-                                ConnectionCloseSource /*source*/) {
-    saved_connection_close_frame_ = frame;
-    connection_close_frame_count_++;
-  }
-
- protected:
-  QuicConnectionTest()
-      : connection_id_(TestConnectionId()),
-        framer_(SupportedVersions(version()), QuicTime::Zero(),
-                Perspective::IS_CLIENT, connection_id_.length()),
-        send_algorithm_(new StrictMock<MockSendAlgorithm>),
-        loss_algorithm_(new MockLossAlgorithm()),
-        helper_(new TestConnectionHelper(&clock_, &random_generator_)),
-        alarm_factory_(new TestAlarmFactory()),
-        peer_framer_(SupportedVersions(version()), QuicTime::Zero(),
-                     Perspective::IS_SERVER, connection_id_.length()),
-        peer_creator_(connection_id_, &peer_framer_,
-                      /*delegate=*/nullptr),
-        writer_(
-            new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)),
-        connection_(connection_id_, kSelfAddress, kPeerAddress, helper_.get(),
-                    alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT,
-                    version()),
-        creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
-        manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
-        frame1_(0, false, 0, absl::string_view(data1)),
-        frame2_(0, false, 3, absl::string_view(data2)),
-        crypto_frame_(ENCRYPTION_INITIAL, 0, absl::string_view(data1)),
-        packet_number_length_(PACKET_4BYTE_PACKET_NUMBER),
-        connection_id_included_(CONNECTION_ID_PRESENT),
-        notifier_(&connection_),
-        connection_close_frame_count_(0) {
-    QUIC_DVLOG(2) << "QuicConnectionTest(" << PrintToString(GetParam()) << ")";
-    connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
-                                                      AckResponse::kDefer);
-    framer_.SetInitialObfuscators(TestConnectionId());
-    connection_.InstallInitialCrypters(TestConnectionId());
-    CrypterPair crypters;
-    CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version(),
-                                          TestConnectionId(), &crypters);
-    peer_creator_.SetEncrypter(ENCRYPTION_INITIAL,
-                               std::move(crypters.encrypter));
-    if (version().KnowsWhichDecrypterToUse()) {
-      peer_framer_.InstallDecrypter(ENCRYPTION_INITIAL,
-                                    std::move(crypters.decrypter));
-    } else {
-      peer_framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                                std::move(crypters.decrypter));
-    }
-    for (EncryptionLevel level :
-         {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
-      peer_creator_.SetEncrypter(
-          level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
-    }
-    QuicFramerPeer::SetLastSerializedServerConnectionId(
-        QuicConnectionPeer::GetFramer(&connection_), connection_id_);
-    QuicFramerPeer::SetLastWrittenPacketNumberLength(
-        QuicConnectionPeer::GetFramer(&connection_), packet_number_length_);
-    if (version().HasIetfInvariantHeader()) {
-      EXPECT_TRUE(QuicConnectionPeer::GetNoStopWaitingFrames(&connection_));
-    } else {
-      QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
-                                                 GetParam().no_stop_waiting);
-    }
-    QuicStreamId stream_id;
-    if (QuicVersionUsesCryptoFrames(version().transport_version)) {
-      stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-          version().transport_version, Perspective::IS_CLIENT);
-    } else {
-      stream_id = QuicUtils::GetCryptoStreamId(version().transport_version);
-    }
-    frame1_.stream_id = stream_id;
-    frame2_.stream_id = stream_id;
-    connection_.set_visitor(&visitor_);
-    connection_.SetSessionNotifier(&notifier_);
-    connection_.set_notifier(&notifier_);
-    connection_.SetSendAlgorithm(send_algorithm_);
-    connection_.SetLossAlgorithm(loss_algorithm_.get());
-    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-        .WillRepeatedly(Return(kDefaultTCPMSS));
-    EXPECT_CALL(*send_algorithm_, PacingRate(_))
-        .WillRepeatedly(Return(QuicBandwidth::Zero()));
-    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-        .Times(AnyNumber())
-        .WillRepeatedly(Return(QuicBandwidth::Zero()));
-    EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_))
-        .Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
-        .Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
-        .Times(AnyNumber());
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
-    EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
-    EXPECT_CALL(visitor_, OnCanWrite())
-        .WillRepeatedly(Invoke(&notifier_, &SimpleSessionNotifier::OnCanWrite));
-    EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-        .WillRepeatedly(Return(false));
-    EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
-    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(AnyNumber());
-    EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged())
-        .Times(testing::AtMost(1));
-    EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
-        .WillRepeatedly(Return(QuicTime::Zero()));
-    EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-        .Times(AnyNumber());
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_START));
-    if (connection_.version().KnowsWhichDecrypterToUse()) {
-      connection_.InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-    }
-    peer_creator_.SetDefaultPeerAddress(kSelfAddress);
-  }
-
-  QuicConnectionTest(const QuicConnectionTest&) = delete;
-  QuicConnectionTest& operator=(const QuicConnectionTest&) = delete;
-
-  ParsedQuicVersion version() { return GetParam().version; }
-
-  QuicStopWaitingFrame* stop_waiting() {
-    QuicConnectionPeer::PopulateStopWaitingFrame(&connection_, &stop_waiting_);
-    return &stop_waiting_;
-  }
-
-  QuicPacketNumber least_unacked() {
-    if (writer_->stop_waiting_frames().empty()) {
-      return QuicPacketNumber();
-    }
-    return writer_->stop_waiting_frames()[0].least_unacked;
-  }
-
-  void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
-
-  void SetClientConnectionId(const QuicConnectionId& client_connection_id) {
-    connection_.set_client_connection_id(client_connection_id);
-    writer_->framer()->framer()->SetExpectedClientConnectionIdLength(
-        client_connection_id.length());
-  }
-
-  void SetDecrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicDecrypter> decrypter) {
-    if (connection_.version().KnowsWhichDecrypterToUse()) {
-      connection_.InstallDecrypter(level, std::move(decrypter));
-    } else {
-      connection_.SetDecrypter(level, std::move(decrypter));
-    }
-  }
-
-  void ProcessPacket(uint64_t number) {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacket(number);
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-  }
-
-  void ProcessReceivedPacket(const QuicSocketAddress& self_address,
-                             const QuicSocketAddress& peer_address,
-                             const QuicReceivedPacket& packet) {
-    connection_.ProcessUdpPacket(self_address, peer_address, packet);
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-  }
-
-  QuicFrame MakeCryptoFrame() const {
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      return QuicFrame(new QuicCryptoFrame(crypto_frame_));
-    }
-    return QuicFrame(QuicStreamFrame(
-        QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
-        0u, absl::string_view()));
-  }
-
-  void ProcessFramePacket(QuicFrame frame) {
-    ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress,
-                                    ENCRYPTION_FORWARD_SECURE);
-  }
-
-  void ProcessFramePacketWithAddresses(QuicFrame frame,
-                                       QuicSocketAddress self_address,
-                                       QuicSocketAddress peer_address,
-                                       EncryptionLevel level) {
-    QuicFrames frames;
-    frames.push_back(QuicFrame(frame));
-    return ProcessFramesPacketWithAddresses(frames, self_address, peer_address,
-                                            level);
-  }
-
-  std::unique_ptr<QuicReceivedPacket> ConstructPacket(QuicFrames frames,
-                                                      EncryptionLevel level,
-                                                      char* buffer,
-                                                      size_t buffer_len) {
-    QUICHE_DCHECK(peer_framer_.HasEncrypterOfEncryptionLevel(level));
-    peer_creator_.set_encryption_level(level);
-    QuicPacketCreatorPeer::SetSendVersionInPacket(
-        &peer_creator_,
-        level < ENCRYPTION_FORWARD_SECURE &&
-            connection_.perspective() == Perspective::IS_SERVER);
-
-    SerializedPacket serialized_packet =
-        QuicPacketCreatorPeer::SerializeAllFrames(&peer_creator_, frames,
-                                                  buffer, buffer_len);
-    return std::make_unique<QuicReceivedPacket>(
-        serialized_packet.encrypted_buffer, serialized_packet.encrypted_length,
-        clock_.Now());
-  }
-
-  void ProcessFramesPacketWithAddresses(QuicFrames frames,
-                                        QuicSocketAddress self_address,
-                                        QuicSocketAddress peer_address,
-                                        EncryptionLevel level) {
-    char buffer[kMaxOutgoingPacketSize];
-    connection_.ProcessUdpPacket(
-        self_address, peer_address,
-        *ConstructPacket(std::move(frames), level, buffer,
-                         kMaxOutgoingPacketSize));
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-  }
-
-  // Bypassing the packet creator is unrealistic, but allows us to process
-  // packets the QuicPacketCreator won't allow us to create.
-  void ForceProcessFramePacket(QuicFrame frame) {
-    QuicFrames frames;
-    frames.push_back(QuicFrame(frame));
-    bool send_version = connection_.perspective() == Perspective::IS_SERVER;
-    if (connection_.version().KnowsWhichDecrypterToUse()) {
-      send_version = true;
-    }
-    QuicPacketCreatorPeer::SetSendVersionInPacket(&peer_creator_, send_version);
-    QuicPacketHeader header;
-    QuicPacketCreatorPeer::FillPacketHeader(&peer_creator_, &header);
-    char encrypted_buffer[kMaxOutgoingPacketSize];
-    size_t length = peer_framer_.BuildDataPacket(
-        header, frames, encrypted_buffer, kMaxOutgoingPacketSize,
-        ENCRYPTION_INITIAL);
-    QUICHE_DCHECK_GT(length, 0u);
-
-    const size_t encrypted_length = peer_framer_.EncryptInPlace(
-        ENCRYPTION_INITIAL, header.packet_number,
-        GetStartOfEncryptedData(peer_framer_.version().transport_version,
-                                header),
-        length, kMaxOutgoingPacketSize, encrypted_buffer);
-    QUICHE_DCHECK_GT(encrypted_length, 0u);
-
-    connection_.ProcessUdpPacket(
-        kSelfAddress, kPeerAddress,
-        QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
-  }
-
-  size_t ProcessFramePacketAtLevel(uint64_t number, QuicFrame frame,
-                                   EncryptionLevel level) {
-    QuicFrames frames;
-    frames.push_back(frame);
-    return ProcessFramesPacketAtLevel(number, frames, level);
-  }
-
-  size_t ProcessFramesPacketAtLevel(uint64_t number, const QuicFrames& frames,
-                                    EncryptionLevel level) {
-    QuicPacketHeader header = ConstructPacketHeader(number, level);
-    // Set the correct encryption level and encrypter on peer_creator and
-    // peer_framer, respectively.
-    peer_creator_.set_encryption_level(level);
-    if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
-        ENCRYPTION_INITIAL) {
-      peer_framer_.SetEncrypter(
-          QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-          std::make_unique<TaggingEncrypter>(0x01));
-      // Set the corresponding decrypter.
-      if (connection_.version().KnowsWhichDecrypterToUse()) {
-        connection_.InstallDecrypter(
-            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-            std::make_unique<StrictTaggingDecrypter>(0x01));
-      } else {
-        connection_.SetDecrypter(
-            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-            std::make_unique<StrictTaggingDecrypter>(0x01));
-      }
-    }
-    std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-
-    char buffer[kMaxOutgoingPacketSize];
-    size_t encrypted_length =
-        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
-                                    buffer, kMaxOutgoingPacketSize);
-    connection_.ProcessUdpPacket(
-        kSelfAddress, kPeerAddress,
-        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-    return encrypted_length;
-  }
-
-  struct PacketInfo {
-    PacketInfo(uint64_t packet_number, QuicFrames frames, EncryptionLevel level)
-        : packet_number(packet_number), frames(frames), level(level) {}
-
-    uint64_t packet_number;
-    QuicFrames frames;
-    EncryptionLevel level;
-  };
-
-  size_t ProcessCoalescedPacket(std::vector<PacketInfo> packets) {
-    char coalesced_buffer[kMaxOutgoingPacketSize];
-    size_t coalesced_size = 0;
-    bool contains_initial = false;
-    for (const auto& packet : packets) {
-      QuicPacketHeader header =
-          ConstructPacketHeader(packet.packet_number, packet.level);
-      // Set the correct encryption level and encrypter on peer_creator and
-      // peer_framer, respectively.
-      peer_creator_.set_encryption_level(packet.level);
-      if (packet.level == ENCRYPTION_INITIAL) {
-        contains_initial = true;
-      }
-      if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
-          ENCRYPTION_INITIAL) {
-        peer_framer_.SetEncrypter(
-            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-            std::make_unique<TaggingEncrypter>(0x01));
-        // Set the corresponding decrypter.
-        if (connection_.version().KnowsWhichDecrypterToUse()) {
-          connection_.InstallDecrypter(
-              QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-              std::make_unique<StrictTaggingDecrypter>(0x01));
-        } else {
-          connection_.SetDecrypter(
-              QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
-              std::make_unique<StrictTaggingDecrypter>(0x01));
-        }
-      }
-      std::unique_ptr<QuicPacket> constructed_packet(
-          ConstructPacket(header, packet.frames));
-
-      char buffer[kMaxOutgoingPacketSize];
-      size_t encrypted_length = peer_framer_.EncryptPayload(
-          packet.level, QuicPacketNumber(packet.packet_number),
-          *constructed_packet, buffer, kMaxOutgoingPacketSize);
-      QUICHE_DCHECK_LE(coalesced_size + encrypted_length,
-                       kMaxOutgoingPacketSize);
-      memcpy(coalesced_buffer + coalesced_size, buffer, encrypted_length);
-      coalesced_size += encrypted_length;
-    }
-    if (contains_initial) {
-      // Padded coalesced packet to full if it contains initial packet.
-      memset(coalesced_buffer + coalesced_size, '0',
-             kMaxOutgoingPacketSize - coalesced_size);
-    }
-    connection_.ProcessUdpPacket(
-        kSelfAddress, kPeerAddress,
-        QuicReceivedPacket(coalesced_buffer, coalesced_size, clock_.Now(),
-                           false));
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-    return coalesced_size;
-  }
-
-  size_t ProcessDataPacket(uint64_t number) {
-    return ProcessDataPacketAtLevel(number, false, ENCRYPTION_FORWARD_SECURE);
-  }
-
-  size_t ProcessDataPacket(QuicPacketNumber packet_number) {
-    return ProcessDataPacketAtLevel(packet_number, false,
-                                    ENCRYPTION_FORWARD_SECURE);
-  }
-
-  size_t ProcessDataPacketAtLevel(QuicPacketNumber packet_number,
-                                  bool has_stop_waiting,
-                                  EncryptionLevel level) {
-    return ProcessDataPacketAtLevel(packet_number.ToUint64(), has_stop_waiting,
-                                    level);
-  }
-
-  size_t ProcessCryptoPacketAtLevel(uint64_t number, EncryptionLevel level) {
-    QuicPacketHeader header = ConstructPacketHeader(number, level);
-    QuicFrames frames;
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      frames.push_back(QuicFrame(&crypto_frame_));
-    } else {
-      frames.push_back(QuicFrame(frame1_));
-    }
-    if (level == ENCRYPTION_INITIAL) {
-      frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-    }
-    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
-    char buffer[kMaxOutgoingPacketSize];
-    peer_creator_.set_encryption_level(level);
-    size_t encrypted_length =
-        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
-                                    buffer, kMaxOutgoingPacketSize);
-    connection_.ProcessUdpPacket(
-        kSelfAddress, kPeerAddress,
-        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-    return encrypted_length;
-  }
-
-  size_t ProcessDataPacketAtLevel(uint64_t number, bool has_stop_waiting,
-                                  EncryptionLevel level) {
-    std::unique_ptr<QuicPacket> packet(
-        ConstructDataPacket(number, has_stop_waiting, level));
-    char buffer[kMaxOutgoingPacketSize];
-    peer_creator_.set_encryption_level(level);
-    size_t encrypted_length =
-        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
-                                    buffer, kMaxOutgoingPacketSize);
-    connection_.ProcessUdpPacket(
-        kSelfAddress, kPeerAddress,
-        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-    if (connection_.GetSendAlarm()->IsSet()) {
-      connection_.GetSendAlarm()->Fire();
-    }
-    return encrypted_length;
-  }
-
-  void ProcessClosePacket(uint64_t number) {
-    std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number));
-    char buffer[kMaxOutgoingPacketSize];
-    size_t encrypted_length = peer_framer_.EncryptPayload(
-        ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(number), *packet, buffer,
-        kMaxOutgoingPacketSize);
-    connection_.ProcessUdpPacket(
-        kSelfAddress, kPeerAddress,
-        QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
-  }
-
-  QuicByteCount SendStreamDataToPeer(QuicStreamId id, absl::string_view data,
-                                     QuicStreamOffset offset,
-                                     StreamSendingState state,
-                                     QuicPacketNumber* last_packet) {
-    QuicByteCount packet_size;
-    // Save the last packet's size.
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AnyNumber())
-        .WillRepeatedly(SaveArg<3>(&packet_size));
-    connection_.SendStreamDataWithString(id, data, offset, state);
-    if (last_packet != nullptr) {
-      *last_packet = creator_->packet_number();
-    }
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AnyNumber());
-    return packet_size;
-  }
-
-  void SendAckPacketToPeer() {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    {
-      QuicConnection::ScopedPacketFlusher flusher(&connection_);
-      connection_.SendAck();
-    }
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AnyNumber());
-  }
-
-  void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error,
-                     QuicStreamOffset bytes_written) {
-    notifier_.WriteOrBufferRstStream(id, error, bytes_written);
-    connection_.OnStreamReset(id, error);
-  }
-
-  void SendPing() { notifier_.WriteOrBufferPing(); }
-
-  MessageStatus SendMessage(absl::string_view message) {
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    quiche::QuicheMemSlice slice(quiche::QuicheBuffer::Copy(
-        connection_.helper()->GetStreamSendBufferAllocator(), message));
-    return connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false);
-  }
-
-  void ProcessAckPacket(uint64_t packet_number, QuicAckFrame* frame) {
-    if (packet_number > 1) {
-      QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, packet_number - 1);
-    } else {
-      QuicPacketCreatorPeer::ClearPacketNumber(&peer_creator_);
-    }
-    ProcessFramePacket(QuicFrame(frame));
-  }
-
-  void ProcessAckPacket(QuicAckFrame* frame) {
-    ProcessFramePacket(QuicFrame(frame));
-  }
-
-  void ProcessStopWaitingPacket(QuicStopWaitingFrame frame) {
-    ProcessFramePacket(QuicFrame(frame));
-  }
-
-  size_t ProcessStopWaitingPacketAtLevel(uint64_t number,
-                                         QuicStopWaitingFrame frame,
-                                         EncryptionLevel /*level*/) {
-    return ProcessFramePacketAtLevel(number, QuicFrame(frame),
-                                     ENCRYPTION_ZERO_RTT);
-  }
-
-  void ProcessGoAwayPacket(QuicGoAwayFrame* frame) {
-    ProcessFramePacket(QuicFrame(frame));
-  }
-
-  bool IsMissing(uint64_t number) {
-    return IsAwaitingPacket(connection_.ack_frame(), QuicPacketNumber(number),
-                            QuicPacketNumber());
-  }
-
-  std::unique_ptr<QuicPacket> ConstructPacket(const QuicPacketHeader& header,
-                                              const QuicFrames& frames) {
-    auto packet = BuildUnsizedDataPacket(&peer_framer_, header, frames);
-    EXPECT_NE(nullptr, packet.get());
-    return packet;
-  }
-
-  QuicPacketHeader ConstructPacketHeader(uint64_t number,
-                                         EncryptionLevel level) {
-    QuicPacketHeader header;
-    if (peer_framer_.version().HasIetfInvariantHeader() &&
-        level < ENCRYPTION_FORWARD_SECURE) {
-      // Set long header type accordingly.
-      header.version_flag = true;
-      header.form = IETF_QUIC_LONG_HEADER_PACKET;
-      header.long_packet_type = EncryptionlevelToLongHeaderType(level);
-      if (QuicVersionHasLongHeaderLengths(
-              peer_framer_.version().transport_version)) {
-        header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-        if (header.long_packet_type == INITIAL) {
-          header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-        }
-      }
-    }
-    // Set connection_id to peer's in memory representation as this data packet
-    // is created by peer_framer.
-    if (peer_framer_.perspective() == Perspective::IS_SERVER) {
-      header.source_connection_id = connection_id_;
-      header.source_connection_id_included = connection_id_included_;
-      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-    } else {
-      header.destination_connection_id = connection_id_;
-      header.destination_connection_id_included = connection_id_included_;
-    }
-    if (peer_framer_.version().HasIetfInvariantHeader() &&
-        peer_framer_.perspective() == Perspective::IS_SERVER) {
-      if (!connection_.client_connection_id().IsEmpty()) {
-        header.destination_connection_id = connection_.client_connection_id();
-        header.destination_connection_id_included = CONNECTION_ID_PRESENT;
-      } else {
-        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-      }
-      if (header.version_flag) {
-        header.source_connection_id = connection_id_;
-        header.source_connection_id_included = CONNECTION_ID_PRESENT;
-        if (GetParam().version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
-            header.long_packet_type == ZERO_RTT_PROTECTED) {
-          header.nonce = &kTestDiversificationNonce;
-        }
-      }
-    }
-    header.packet_number_length = packet_number_length_;
-    header.packet_number = QuicPacketNumber(number);
-    return header;
-  }
-
-  std::unique_ptr<QuicPacket> ConstructDataPacket(uint64_t number,
-                                                  bool has_stop_waiting,
-                                                  EncryptionLevel level) {
-    QuicPacketHeader header = ConstructPacketHeader(number, level);
-    QuicFrames frames;
-    if (VersionHasIetfQuicFrames(version().transport_version) &&
-        (level == ENCRYPTION_INITIAL || level == ENCRYPTION_HANDSHAKE)) {
-      frames.push_back(QuicFrame(QuicPingFrame()));
-      frames.push_back(QuicFrame(QuicPaddingFrame(100)));
-    } else {
-      frames.push_back(QuicFrame(frame1_));
-      if (has_stop_waiting) {
-        frames.push_back(QuicFrame(stop_waiting_));
-      }
-    }
-    return ConstructPacket(header, frames);
-  }
-
-  std::unique_ptr<SerializedPacket> ConstructProbingPacket() {
-    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-    if (VersionHasIetfQuicFrames(version().transport_version)) {
-      QuicPathFrameBuffer payload = {
-          {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
-      return QuicPacketCreatorPeer::
-          SerializePathChallengeConnectivityProbingPacket(&peer_creator_,
-                                                          payload);
-    }
-    return QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
-        &peer_creator_);
-  }
-
-  std::unique_ptr<QuicPacket> ConstructClosePacket(uint64_t number) {
-    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-    QuicPacketHeader header;
-    // Set connection_id to peer's in memory representation as this connection
-    // close packet is created by peer_framer.
-    if (peer_framer_.perspective() == Perspective::IS_SERVER) {
-      header.source_connection_id = connection_id_;
-      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-      if (!peer_framer_.version().HasIetfInvariantHeader()) {
-        header.source_connection_id_included = CONNECTION_ID_PRESENT;
-      }
-    } else {
-      header.destination_connection_id = connection_id_;
-      if (peer_framer_.version().HasIetfInvariantHeader()) {
-        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-      }
-    }
-
-    header.packet_number = QuicPacketNumber(number);
-
-    QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
-    QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
-                                  kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
-                                  /*transport_close_frame_type=*/0);
-    QuicFrames frames;
-    frames.push_back(QuicFrame(&qccf));
-    return ConstructPacket(header, frames);
-  }
-
-  QuicTime::Delta DefaultRetransmissionTime() {
-    return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
-  }
-
-  QuicTime::Delta DefaultDelayedAckTime() {
-    return QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  }
-
-  const QuicStopWaitingFrame InitStopWaitingFrame(uint64_t least_unacked) {
-    QuicStopWaitingFrame frame;
-    frame.least_unacked = QuicPacketNumber(least_unacked);
-    return frame;
-  }
-
-  // Construct a ack_frame that acks all packet numbers between 1 and
-  // |largest_acked|, except |missing|.
-  // REQUIRES: 1 <= |missing| < |largest_acked|
-  QuicAckFrame ConstructAckFrame(uint64_t largest_acked, uint64_t missing) {
-    return ConstructAckFrame(QuicPacketNumber(largest_acked),
-                             QuicPacketNumber(missing));
-  }
-
-  QuicAckFrame ConstructAckFrame(QuicPacketNumber largest_acked,
-                                 QuicPacketNumber missing) {
-    if (missing == QuicPacketNumber(1)) {
-      return InitAckFrame({{missing + 1, largest_acked + 1}});
-    }
-    return InitAckFrame(
-        {{QuicPacketNumber(1), missing}, {missing + 1, largest_acked + 1}});
-  }
-
-  // Undo nacking a packet within the frame.
-  void AckPacket(QuicPacketNumber arrived, QuicAckFrame* frame) {
-    EXPECT_FALSE(frame->packets.Contains(arrived));
-    frame->packets.Add(arrived);
-  }
-
-  void TriggerConnectionClose() {
-    // Send an erroneous packet to close the connection.
-    EXPECT_CALL(visitor_,
-                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-
-    EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-    // Triggers a connection by receiving ACK of unsent packet.
-    QuicAckFrame frame = InitAckFrame(10000);
-    ProcessAckPacket(1, &frame);
-    EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
-                 nullptr);
-    EXPECT_EQ(1, connection_close_frame_count_);
-    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-                IsError(QUIC_INVALID_ACK_DATA));
-  }
-
-  void BlockOnNextWrite() {
-    writer_->BlockOnNextWrite();
-    EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
-  }
-
-  void SimulateNextPacketTooLarge() { writer_->SimulateNextPacketTooLarge(); }
-
-  void AlwaysGetPacketTooLarge() { writer_->AlwaysGetPacketTooLarge(); }
-
-  void SetWritePauseTimeDelta(QuicTime::Delta delta) {
-    writer_->SetWritePauseTimeDelta(delta);
-  }
-
-  void CongestionBlockWrites() {
-    EXPECT_CALL(*send_algorithm_, CanSend(_))
-        .WillRepeatedly(testing::Return(false));
-  }
-
-  void CongestionUnblockWrites() {
-    EXPECT_CALL(*send_algorithm_, CanSend(_))
-        .WillRepeatedly(testing::Return(true));
-  }
-
-  void set_perspective(Perspective perspective) {
-    connection_.set_perspective(perspective);
-    if (perspective == Perspective::IS_SERVER) {
-      QuicConfig config;
-      if (!GetQuicReloadableFlag(
-              quic_remove_connection_migration_connection_option)) {
-        QuicTagVector connection_options;
-        connection_options.push_back(kRVCM);
-        config.SetInitialReceivedConnectionOptions(connection_options);
-      }
-      EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-      connection_.SetFromConfig(config);
-
-      connection_.set_can_truncate_connection_ids(true);
-      QuicConnectionPeer::SetNegotiatedVersion(&connection_);
-      connection_.OnSuccessfulVersionNegotiation();
-    }
-    QuicFramerPeer::SetPerspective(&peer_framer_,
-                                   QuicUtils::InvertPerspective(perspective));
-    peer_framer_.SetInitialObfuscators(TestConnectionId());
-    for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
-                                  ENCRYPTION_FORWARD_SECURE}) {
-      if (peer_framer_.HasEncrypterOfEncryptionLevel(level)) {
-        peer_creator_.SetEncrypter(
-            level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
-      }
-    }
-  }
-
-  void set_packets_between_probes_base(
-      const QuicPacketCount packets_between_probes_base) {
-    QuicConnectionPeer::ReInitializeMtuDiscoverer(
-        &connection_, packets_between_probes_base,
-        QuicPacketNumber(packets_between_probes_base));
-  }
-
-  bool IsDefaultTestConfiguration() {
-    TestParams p = GetParam();
-    return p.ack_response == AckResponse::kImmediate &&
-           p.version == AllSupportedVersions()[0] && p.no_stop_waiting;
-  }
-
-  void TestConnectionCloseQuicErrorCode(QuicErrorCode expected_code) {
-    // Not strictly needed for this test, but is commonly done.
-    EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
-                 nullptr);
-    const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
-        writer_->connection_close_frames();
-    ASSERT_EQ(1u, connection_close_frames.size());
-
-    EXPECT_THAT(connection_close_frames[0].quic_error_code,
-                IsError(expected_code));
-
-    if (!VersionHasIetfQuicFrames(version().transport_version)) {
-      EXPECT_THAT(connection_close_frames[0].wire_error_code,
-                  IsError(expected_code));
-      EXPECT_EQ(GOOGLE_QUIC_CONNECTION_CLOSE,
-                connection_close_frames[0].close_type);
-      return;
-    }
-
-    QuicErrorCodeToIetfMapping mapping =
-        QuicErrorCodeToTransportErrorCode(expected_code);
-
-    if (mapping.is_transport_close) {
-      // This Google QUIC Error Code maps to a transport close,
-      EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
-                connection_close_frames[0].close_type);
-    } else {
-      // This maps to an application close.
-      EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
-                connection_close_frames[0].close_type);
-    }
-    EXPECT_EQ(mapping.error_code, connection_close_frames[0].wire_error_code);
-  }
-
-  void MtuDiscoveryTestInit() {
-    set_perspective(Perspective::IS_SERVER);
-    QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-    if (version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(&connection_);
-    }
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-    // QuicFramer::GetMaxPlaintextSize uses the smallest max plaintext size
-    // across all encrypters. The initial encrypter used with IETF QUIC has a
-    // 16-byte overhead, while the NullEncrypter used throughout this test has a
-    // 12-byte overhead. This test tests behavior that relies on computing the
-    // packet size correctly, so by unsetting the initial encrypter, we avoid
-    // having a mismatch between the overheads for the encrypters used. In
-    // non-test scenarios all encrypters used for a given connection have the
-    // same overhead, either 12 bytes for ones using Google QUIC crypto, or 16
-    // bytes for ones using TLS.
-    connection_.SetEncrypter(ENCRYPTION_INITIAL, nullptr);
-    // Prevent packets from being coalesced.
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-    EXPECT_TRUE(connection_.connected());
-  }
-
-  void PathProbeTestInit(Perspective perspective,
-                         bool receive_new_server_connection_id = true) {
-    set_perspective(perspective);
-    connection_.CreateConnectionIdManager();
-    EXPECT_EQ(connection_.perspective(), perspective);
-    if (perspective == Perspective::IS_SERVER) {
-      QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-    }
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-    // Discard INITIAL key.
-    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-    connection_.NeuterUnencryptedPackets();
-    // Prevent packets from being coalesced.
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-    if (version().SupportsAntiAmplificationLimit() &&
-        perspective == Perspective::IS_SERVER) {
-      QuicConnectionPeer::SetAddressValidated(&connection_);
-    }
-    // Clear direct_peer_address.
-    QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-    // Clear effective_peer_address, it is the same as direct_peer_address for
-    // this test.
-    QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                                QuicSocketAddress());
-    EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-    } else {
-      EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-    }
-    QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
-    ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
-                                    kPeerAddress, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(kPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-    if (perspective == Perspective::IS_CLIENT &&
-        receive_new_server_connection_id && version().HasIetfQuicFrames()) {
-      QuicNewConnectionIdFrame frame;
-      frame.connection_id = TestConnectionId(1234);
-      ASSERT_NE(frame.connection_id, connection_.connection_id());
-      frame.stateless_reset_token =
-          QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-      frame.retire_prior_to = 0u;
-      frame.sequence_number = 1u;
-      connection_.OnNewConnectionIdFrame(frame);
-    }
-  }
-
-  void TestClientRetryHandling(bool invalid_retry_tag,
-                               bool missing_original_id_in_config,
-                               bool wrong_original_id_in_config,
-                               bool missing_retry_id_in_config,
-                               bool wrong_retry_id_in_config);
-
-  void TestReplaceConnectionIdFromInitial();
-
-  QuicConnectionId connection_id_;
-  QuicFramer framer_;
-
-  MockSendAlgorithm* send_algorithm_;
-  std::unique_ptr<MockLossAlgorithm> loss_algorithm_;
-  MockClock clock_;
-  MockRandom random_generator_;
-  quiche::SimpleBufferAllocator buffer_allocator_;
-  std::unique_ptr<TestConnectionHelper> helper_;
-  std::unique_ptr<TestAlarmFactory> alarm_factory_;
-  QuicFramer peer_framer_;
-  QuicPacketCreator peer_creator_;
-  std::unique_ptr<TestPacketWriter> writer_;
-  TestConnection connection_;
-  QuicPacketCreator* creator_;
-  QuicSentPacketManager* manager_;
-  StrictMock<MockQuicConnectionVisitor> visitor_;
-
-  QuicStreamFrame frame1_;
-  QuicStreamFrame frame2_;
-  QuicCryptoFrame crypto_frame_;
-  QuicAckFrame ack_;
-  QuicStopWaitingFrame stop_waiting_;
-  QuicPacketNumberLength packet_number_length_;
-  QuicConnectionIdIncluded connection_id_included_;
-
-  SimpleSessionNotifier notifier_;
-
-  QuicConnectionCloseFrame saved_connection_close_frame_;
-  int connection_close_frame_count_;
-};
-
-// Run all end to end tests with all supported versions.
-INSTANTIATE_TEST_SUITE_P(QuicConnectionTests, QuicConnectionTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-// These two tests ensure that the QuicErrorCode mapping works correctly.
-// Both tests expect to see a Google QUIC close if not running IETF QUIC.
-// If running IETF QUIC, the first will generate a transport connection
-// close, the second an application connection close.
-// The connection close codes for the two tests are manually chosen;
-// they are expected to always map to transport- and application-
-// closes, respectively. If that changes, new codes should be chosen.
-TEST_P(QuicConnectionTest, CloseErrorCodeTestTransport) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  connection_.CloseConnection(
-      IETF_QUIC_PROTOCOL_VIOLATION, "Should be transport close",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-}
-
-// Test that the IETF QUIC Error code mapping function works
-// properly for application connection close codes.
-TEST_P(QuicConnectionTest, CloseErrorCodeTestApplication) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  connection_.CloseConnection(
-      QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
-      "Should be application close",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
-}
-
-TEST_P(QuicConnectionTest, SelfAddressChangeAtClient) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-  EXPECT_TRUE(connection_.connected());
-
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_));
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_));
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  // Cause change in self_address.
-  QuicIpAddress host;
-  host.FromString("1.1.1.1");
-  QuicSocketAddress self_address(host, 123);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_));
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_));
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  EXPECT_TRUE(connection_.connected());
-
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_));
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_));
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  // Cause change in self_address.
-  QuicIpAddress host;
-  host.FromString("1.1.1.1");
-  QuicSocketAddress self_address(host, 123);
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
-  if (GetQuicReloadableFlag(quic_drop_packets_with_changed_server_address)) {
-    ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
-                                    kPeerAddress, ENCRYPTION_INITIAL);
-    EXPECT_TRUE(connection_.connected());
-    EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
-    return;
-  }
-  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
-    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  }
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  EXPECT_QUIC_PEER_BUG(
-      ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
-                                      kPeerAddress, ENCRYPTION_INITIAL),
-      "Self address migration is not supported at the server");
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_ERROR_MIGRATING_ADDRESS);
-  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
-}
-
-TEST_P(QuicConnectionTest, AllowSelfAddressChangeToMappedIpv4AddressAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  EXPECT_TRUE(connection_.connected());
-
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
-  }
-  QuicIpAddress host;
-  host.FromString("1.1.1.1");
-  QuicSocketAddress self_address1(host, 443);
-  connection_.SetSelfAddress(self_address1);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
-                                  kPeerAddress, ENCRYPTION_INITIAL);
-  // Cause self_address change to mapped Ipv4 address.
-  QuicIpAddress host2;
-  host2.FromString(
-      absl::StrCat("::ffff:", connection_.self_address().host().ToString()));
-  QuicSocketAddress self_address2(host2, connection_.self_address().port());
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address2,
-                                  kPeerAddress, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.connected());
-  // self_address change back to Ipv4 address.
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
-                                  kPeerAddress, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  }
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(),
-                        /*port=*/23456);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
-                                  kNewPeerAddress, ENCRYPTION_INITIAL);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-
-  // Decrease packet number to simulate out-of-order packets.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
-  // This is an old packet, do not migrate.
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, PeerPortChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Prevent packets from being coalesced.
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
-  rtt_stats->set_initial_rtt(default_init_rtt * 2);
-  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
-
-  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
-  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
-  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
-  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
-
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .WillOnce(Invoke(
-          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
-      .WillOnce(Invoke(
-          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Process another packet with a different peer address on server side will
-  // start connection migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  // PORT_CHANGE shouldn't state change in sent packet manager.
-  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
-  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
-  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
-  EXPECT_EQ(manager_->GetSendAlgorithm(), send_algorithm_);
-  if (connection_.validate_client_address()) {
-    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-    EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-  }
-}
-
-TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.validate_client_address()) {
-    return;
-  }
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  // Prevent packets from being coalesced.
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-  connection_.OnHandshakeComplete();
-
-  // Enable 5 RTO
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k5RTO);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  QuicConfigPeer::SetNegotiated(&config, true);
-  QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
-                                                  connection_.connection_id());
-  QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
-                                                       QuicConnectionId());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .WillOnce(Invoke(
-          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
-      .WillOnce(Invoke(
-          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Send some data to make connection has packets in flight.
-  connection_.SendStreamData3();
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Process another packet with a different peer address on server side will
-  // start connection migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  // IETF QUIC send algorithm should be changed to a different object, so no
-  // OnPacketSent() called on the old send algorithm.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
-      .Times(0);
-  // Do not propagate OnCanWrite() to session notifier.
-  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
-
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-  EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-  EXPECT_FALSE(writer_->path_challenge_frames().empty());
-  QuicPathFrameBuffer payload =
-      writer_->path_challenge_frames().front().data_buffer;
-  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
-            send_algorithm_);
-  // Switch to use the mock send algorithm.
-  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(kDefaultTCPMSS));
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-      .Times(AnyNumber())
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
-  connection_.SetSendAlgorithm(send_algorithm_);
-
-  // PATH_CHALLENGE is expanded upto the max packet size which may exceeds the
-  // anti-amplification limit.
-  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(1u,
-            connection_.GetStats().num_reverse_path_validtion_upon_migration);
-
-  // Verify server is throttled by anti-amplification limit.
-  connection_.SendCryptoDataWithString("foo", 0);
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Receiving an ACK to the packet sent after changing peer address doesn't
-  // finish migration validation.
-  QuicAckFrame ack_frame = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
-                                  kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-
-  // Receiving PATH_RESPONSE should lift the anti-amplification limit.
-  QuicFrames frames3;
-  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
-  EXPECT_CALL(visitor_, MaybeSendAddressToken());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(testing::AtLeast(1u));
-  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-
-  // Verify the anti-amplification limit is lifted by sending a packet larger
-  // than the anti-amplification limit.
-  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
-  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-}
-
-TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServerWithMissingConnectionId) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-
-  QuicConnectionId client_cid0 = TestConnectionId(1);
-  QuicConnectionId client_cid1 = TestConnectionId(3);
-  QuicConnectionId server_cid1;
-  SetClientConnectionId(client_cid0);
-  connection_.CreateConnectionIdManager();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Prevent packets from being coalesced.
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-
-  // Sends new server CID to client.
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(
-          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  connection_.OnHandshakeComplete();
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Send some data to make connection has packets in flight.
-  connection_.SendStreamData3();
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  // Process another packet with a different peer address on server side will
-  // start connection migration.
-  peer_creator_.SetServerConnectionId(server_cid1);
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  // Do not propagate OnCanWrite() to session notifier.
-  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
-
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-
-  // Writing path response & reverse path challenge is blocked due to missing
-  // client connection ID, i.e., packets_write_attempts is unchanged.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  // Receives new client CID from client would unblock write.
-  QuicNewConnectionIdFrame new_cid_frame;
-  new_cid_frame.connection_id = client_cid1;
-  new_cid_frame.sequence_number = 1u;
-  new_cid_frame.retire_prior_to = 0u;
-  connection_.OnNewConnectionIdFrame(new_cid_frame);
-  connection_.SendStreamData3();
-
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is different from direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  const QuicSocketAddress kEffectivePeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/43210);
-  connection_.ReturnEffectivePeerAddressForNextPacket(kEffectivePeerAddress);
-
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address());
-
-  // Process another packet with the same direct peer address and different
-  // effective peer address on server side will start connection migration.
-  const QuicSocketAddress kNewEffectivePeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321);
-  connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
-  if (connection_.validate_client_address()) {
-    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-    EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-  }
-
-  // Process another packet with a different direct peer address and the same
-  // effective peer address on server side will not start connection migration.
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-  connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-
-  if (!connection_.validate_client_address()) {
-    // ack_frame is used to complete the migration started by the last packet,
-    // we need to make sure a new migration does not start after the previous
-    // one is completed.
-    QuicAckFrame ack_frame = InitAckFrame(1);
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-    ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
-                                    kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
-    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-  }
-
-  // Process another packet with different direct peer address and different
-  // effective peer address on server side will start connection migration.
-  const QuicSocketAddress kNewerEffectivePeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/65432);
-  const QuicSocketAddress kFinalPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/34567);
-  connection_.ReturnEffectivePeerAddressForNextPacket(
-      kNewerEffectivePeerAddress);
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
-                                  kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewerEffectivePeerAddress, connection_.effective_peer_address());
-  if (connection_.validate_client_address()) {
-    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-    EXPECT_EQ(send_algorithm_,
-              connection_.sent_packet_manager().GetSendAlgorithm());
-    EXPECT_EQ(2u, connection_.GetStats().num_validated_peer_migration);
-  }
-
-  // While the previous migration is ongoing, process another packet with the
-  // same direct peer address and different effective peer address on server
-  // side will start a new connection migration.
-  const QuicSocketAddress kNewestEffectivePeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/65430);
-  connection_.ReturnEffectivePeerAddressForNextPacket(
-      kNewestEffectivePeerAddress);
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  if (!connection_.validate_client_address()) {
-    EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(1);
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
-                                  kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewestEffectivePeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-  if (connection_.validate_client_address()) {
-    EXPECT_NE(send_algorithm_,
-              connection_.sent_packet_manager().GetSendAlgorithm());
-    EXPECT_EQ(kFinalPeerAddress, writer_->last_write_peer_address());
-    EXPECT_FALSE(writer_->path_challenge_frames().empty());
-    EXPECT_EQ(0u, connection_.GetStats()
-                      .num_peer_migration_while_validating_default_path);
-    EXPECT_TRUE(connection_.HasPendingPathValidation());
-  }
-}
-
-// Regression test for b/200020764.
-TEST_P(QuicConnectionTest, ConnectionMigrationWithPendingPaddingBytes) {
-  // TODO(haoyuewang) Move these test setup code to a common member function.
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  connection_.CreateConnectionIdManager();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-
-  // Sends new server CID to client.
-  QuicConnectionId new_cid;
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
-  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
-  packet_creator->FlushCurrentPacket();
-  packet_creator->AddPendingPadding(50u);
-  const QuicSocketAddress kPeerAddress3 =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
-  auto ack_frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-  ProcessFramesPacketWithAddresses({QuicFrame(&ack_frame)}, kSelfAddress,
-                                   kPeerAddress3, ENCRYPTION_FORWARD_SECURE);
-  if (GetQuicReloadableFlag(
-          quic_flush_pending_frames_and_padding_bytes_on_migration)) {
-    // Any pending frames/padding should be flushed before default_path_ is
-    // temporarily reset.
-    ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
-                  .host()
-                  .address_family(),
-              IpAddressFamily::IP_V6);
-  } else {
-    ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
-                  .host()
-                  .address_family(),
-              IpAddressFamily::IP_UNSPEC);
-  }
-}
-
-// Regression test for b/196208556.
-TEST_P(QuicConnectionTest,
-       ReversePathValidationResponseReceivedFromUnexpectedPeerAddress) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  connection_.CreateConnectionIdManager();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Sends new server CID to client.
-  QuicConnectionId new_cid;
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
-  // Process a non-probing packet to migrate to path 2 and kick off reverse path
-  // validation.
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  const QuicSocketAddress kPeerAddress2 =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
-  peer_creator_.SetServerConnectionId(new_cid);
-  ProcessFramesPacketWithAddresses({QuicFrame(QuicPingFrame())}, kSelfAddress,
-                                   kPeerAddress2, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_FALSE(writer_->path_challenge_frames().empty());
-  QuicPathFrameBuffer reverse_path_challenge_payload =
-      writer_->path_challenge_frames().front().data_buffer;
-
-  // Receiveds a packet from path 3 with PATH_RESPONSE frame intended to
-  // validate path 2 and a non-probing frame.
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    const QuicSocketAddress kPeerAddress3 =
-        QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
-    auto ack_frame = InitAckFrame(1);
-    EXPECT_CALL(visitor_, OnConnectionMigration(IPV4_TO_IPV6_CHANGE)).Times(1);
-    EXPECT_CALL(visitor_, MaybeSendAddressToken()).WillOnce(Invoke([this]() {
-      connection_.SendControlFrame(
-          QuicFrame(new QuicNewTokenFrame(1, "new_token")));
-      return true;
-    }));
-    ProcessFramesPacketWithAddresses({QuicFrame(new QuicPathResponseFrame(
-                                          0, reverse_path_challenge_payload)),
-                                      QuicFrame(&ack_frame)},
-                                     kSelfAddress, kPeerAddress3,
-                                     ENCRYPTION_FORWARD_SECURE);
-  }
-}
-
-TEST_P(QuicConnectionTest, ReversePathValidationFailureAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  SetClientConnectionId(TestConnectionId(1));
-  connection_.CreateConnectionIdManager();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  // Prevent packets from being coalesced.
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-
-  QuicConnectionId client_cid0 = connection_.client_connection_id();
-  QuicConnectionId client_cid1 = TestConnectionId(2);
-  QuicConnectionId server_cid0 = connection_.connection_id();
-  QuicConnectionId server_cid1;
-  // Sends new server CID to client.
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(
-          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  connection_.OnHandshakeComplete();
-  // Receives new client CID from client.
-  QuicNewConnectionIdFrame new_cid_frame;
-  new_cid_frame.connection_id = client_cid1;
-  new_cid_frame.sequence_number = 1u;
-  new_cid_frame.retire_prior_to = 0u;
-  connection_.OnNewConnectionIdFrame(new_cid_frame);
-  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
-  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
-  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .WillOnce(Invoke(
-          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
-      .WillOnce(Invoke(
-          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Process another packet with a different peer address on server side will
-  // start connection migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  // IETF QUIC send algorithm should be changed to a different object, so no
-  // OnPacketSent() called on the old send algorithm.
-  EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(0);
-
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  QuicPaddingFrame padding;
-  frames2.push_back(QuicFrame(padding));
-  peer_creator_.SetServerConnectionId(server_cid1);
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-  EXPECT_LT(0u, writer_->packets_write_attempts());
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
-            send_algorithm_);
-  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  const auto* alternative_path =
-      QuicConnectionPeer::GetAlternativePath(&connection_);
-  EXPECT_EQ(default_path->client_connection_id, client_cid1);
-  EXPECT_EQ(default_path->server_connection_id, server_cid1);
-  EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
-  EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
-  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
-  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
-
-  for (size_t i = 0; i < QuicPathValidator::kMaxRetryTimes; ++i) {
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-    static_cast<TestAlarmFactory::TestAlarm*>(
-        QuicPathValidatorPeer::retry_timer(
-            QuicConnectionPeer::path_validator(&connection_)))
-        ->Fire();
-  }
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-
-  // Make sure anti-amplification limit is not reached.
-  ProcessFramesPacketWithAddresses(
-      {QuicFrame(QuicPingFrame()), QuicFrame(QuicPaddingFrame())}, kSelfAddress,
-      kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Advance the time so that the reverse path validation times out.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-  static_cast<TestAlarmFactory::TestAlarm*>(
-      QuicPathValidatorPeer::retry_timer(
-          QuicConnectionPeer::path_validator(&connection_)))
-      ->Fire();
-  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(connection_.sent_packet_manager().GetSendAlgorithm(),
-            send_algorithm_);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Verify that default_path_ is reverted and alternative_path_ is cleared.
-  EXPECT_EQ(default_path->client_connection_id, client_cid0);
-  EXPECT_EQ(default_path->server_connection_id, server_cid0);
-  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
-  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
-  retire_peer_issued_cid_alarm->Fire();
-  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
-  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-}
-
-TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  EXPECT_CALL(visitor_, OnPacketReceived(_, _, false)).Times(0);
-
-  // Process a padded PING packet with no peer address change on server side
-  // will be ignored. But a PATH CHALLENGE packet with no peer address change
-  // will be considered as path probing.
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-
-  uint64_t num_probing_received =
-      connection_.GetStats().num_connectivity_probing_received;
-  ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
-
-  EXPECT_EQ(
-      num_probing_received + (GetParam().version.HasIetfQuicFrames() ? 1u : 0u),
-      connection_.GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-// Regression test for b/150161358.
-TEST_P(QuicConnectionTest, BufferedMtuPacketTooBig) {
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
-  writer_->SetWriteBlocked();
-
-  // Send a MTU packet while blocked. It should be buffered.
-  connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-
-  writer_->AlwaysGetPacketTooLarge();
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, WriteOutOfOrderQueuedPackets) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration()) {
-    return;
-  }
-
-  set_perspective(Perspective::IS_CLIENT);
-
-  BlockOnNextWrite();
-
-  QuicStreamId stream_id = 2;
-  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
-
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  writer_->SetWritable();
-  connection_.SendConnectivityProbingPacket(writer_.get(),
-                                            connection_.peer_address());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-  connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
-  // Regression test for b/74073386.
-  {
-    InSequence seq;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AtLeast(1));
-    EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(AtLeast(1));
-  }
-
-  set_perspective(Perspective::IS_CLIENT);
-
-  writer_->SimulateNextPacketTooLarge();
-
-  // This packet write should fail, which should cause the connection to close
-  // after sending a connection close packet, then the failed packet should be
-  // queued.
-  connection_.SendStreamDataWithString(/*id=*/2, "foo", 0, NO_FIN);
-
-  EXPECT_FALSE(connection_.connected());
-  // No need to buffer packets.
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
-  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
-}
-
-class TestQuicPathValidationContext : public QuicPathValidationContext {
- public:
-  TestQuicPathValidationContext(const QuicSocketAddress& self_address,
-                                const QuicSocketAddress& peer_address,
-
-                                QuicPacketWriter* writer)
-      : QuicPathValidationContext(self_address, peer_address),
-        writer_(writer) {}
-
-  QuicPacketWriter* WriterToUse() override { return writer_; }
-
- private:
-  QuicPacketWriter* writer_;
-};
-
-class TestValidationResultDelegate : public QuicPathValidator::ResultDelegate {
- public:
-  TestValidationResultDelegate(QuicConnection* connection,
-                               const QuicSocketAddress& expected_self_address,
-                               const QuicSocketAddress& expected_peer_address,
-                               bool* success)
-      : QuicPathValidator::ResultDelegate(),
-        connection_(connection),
-        expected_self_address_(expected_self_address),
-        expected_peer_address_(expected_peer_address),
-        success_(success) {}
-  void OnPathValidationSuccess(
-      std::unique_ptr<QuicPathValidationContext> context) override {
-    EXPECT_EQ(expected_self_address_, context->self_address());
-    EXPECT_EQ(expected_peer_address_, context->peer_address());
-    *success_ = true;
-  }
-
-  void OnPathValidationFailure(
-      std::unique_ptr<QuicPathValidationContext> context) override {
-    EXPECT_EQ(expected_self_address_, context->self_address());
-    EXPECT_EQ(expected_peer_address_, context->peer_address());
-    if (connection_->perspective() == Perspective::IS_CLIENT) {
-      connection_->OnPathValidationFailureAtClient();
-    }
-    *success_ = false;
-  }
-
- private:
-  QuicConnection* connection_;
-  QuicSocketAddress expected_self_address_;
-  QuicSocketAddress expected_peer_address_;
-  bool* success_;
-};
-
-// Receive a path probe request at the server side, i.e.,
-// in non-IETF version: receive a padded PING packet with a peer addess change;
-// in IETF version: receive a packet contains PATH CHALLENGE with peer address
-// change.
-TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  QuicPathFrameBuffer payload;
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    EXPECT_CALL(visitor_,
-                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
-        .Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
-    if (connection_.validate_client_address()) {
-      EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-          .Times(AtLeast(1u))
-          .WillOnce(Invoke([&]() {
-            EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-            EXPECT_EQ(1u, writer_->path_response_frames().size());
-            payload = writer_->path_challenge_frames().front().data_buffer;
-          }));
-    }
-  }
-  // Process a probing packet from a new peer address on server side
-  // is effectively receiving a connectivity probing.
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/23456);
-
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-  uint64_t num_probing_received =
-      connection_.GetStats().num_connectivity_probing_received;
-  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-
-  EXPECT_EQ(num_probing_received + 1,
-            connection_.GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-  if (GetParam().version.HasIetfQuicFrames() &&
-      connection_.use_path_validator() &&
-      GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately)) {
-    QuicByteCount bytes_sent =
-        QuicConnectionPeer::BytesSentOnAlternativePath(&connection_);
-    EXPECT_LT(0u, bytes_sent);
-    EXPECT_EQ(received->length(),
-              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
-
-    // Receiving one more probing packet should update the bytes count.
-    probing_packet = ConstructProbingPacket();
-    received.reset(ConstructReceivedPacket(
-        QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                            probing_packet->encrypted_length),
-        clock_.Now()));
-    ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-
-    EXPECT_EQ(num_probing_received + 2,
-              connection_.GetStats().num_connectivity_probing_received);
-    EXPECT_EQ(2 * bytes_sent,
-              QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
-    EXPECT_EQ(2 * received->length(),
-              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
-
-    bool success = false;
-    if (!connection_.validate_client_address()) {
-      EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-          .Times(AtLeast(1u))
-          .WillOnce(Invoke([&]() {
-            EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-            payload = writer_->path_challenge_frames().front().data_buffer;
-          }));
-
-      connection_.ValidatePath(
-          std::make_unique<TestQuicPathValidationContext>(
-              connection_.self_address(), kNewPeerAddress, writer_.get()),
-          std::make_unique<TestValidationResultDelegate>(
-              &connection_, connection_.self_address(), kNewPeerAddress,
-              &success));
-    }
-    EXPECT_EQ((connection_.validate_client_address() ? 2 : 3) * bytes_sent,
-              QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
-    QuicFrames frames;
-    frames.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
-    ProcessFramesPacketWithAddresses(frames, connection_.self_address(),
-                                     kNewPeerAddress,
-                                     ENCRYPTION_FORWARD_SECURE);
-    EXPECT_LT(2 * received->length(),
-              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
-    if (connection_.validate_client_address()) {
-      EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
-    }
-    // Receiving another probing packet from a newer address with a different
-    // port shouldn't trigger another reverse path validation.
-    QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
-                                        /*port=*/34567);
-    probing_packet = ConstructProbingPacket();
-    received.reset(ConstructReceivedPacket(
-        QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                            probing_packet->encrypted_length),
-        clock_.Now()));
-    ProcessReceivedPacket(kSelfAddress, kNewerPeerAddress, *received);
-    EXPECT_FALSE(connection_.HasPendingPathValidation());
-    EXPECT_EQ(connection_.validate_client_address(),
-              QuicConnectionPeer::IsAlternativePathValidated(&connection_));
-  }
-
-  // Process another packet with the old peer address on server side will not
-  // start peer migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-// Receive a padded PING packet with a port change on server side.
-TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  if (GetParam().version.UsesCryptoFrames()) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  if (GetParam().version.HasIetfQuicFrames()) {
-    // In IETF version, a padded PING packet with port change is not taken as
-    // connectivity probe.
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
-  } else {
-    // In non-IETF version, process a padded PING packet from a new peer
-    // address on server side is effectively receiving a connectivity probing.
-    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-    EXPECT_CALL(visitor_,
-                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
-        .Times(1);
-  }
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
-  QuicFrames frames;
-  // Write a PING frame, which has no data payload.
-  QuicPingFrame ping_frame;
-  frames.push_back(QuicFrame(ping_frame));
-
-  // Add padding to the rest of the packet.
-  QuicPaddingFrame padding_frame;
-  frames.push_back(QuicFrame(padding_frame));
-
-  uint64_t num_probing_received =
-      connection_.GetStats().num_connectivity_probing_received;
-
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_INITIAL);
-
-  if (GetParam().version.HasIetfQuicFrames()) {
-    // Padded PING with port changen is not considered as connectivity probe but
-    // a PORT CHANGE.
-    EXPECT_EQ(num_probing_received,
-              connection_.GetStats().num_connectivity_probing_received);
-    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  } else {
-    EXPECT_EQ(num_probing_received + 1,
-              connection_.GetStats().num_connectivity_probing_received);
-    EXPECT_EQ(kPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-  }
-
-  if (GetParam().version.HasIetfQuicFrames()) {
-    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-  }
-  // Process another packet with the old peer address on server side. gQUIC
-  // shouldn't regard this as a peer migration.
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  // Decrease packet number to simulate out-of-order packets.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    EXPECT_CALL(visitor_,
-                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
-        .Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
-  }
-
-  // Process a padded PING packet from a new peer address on server side
-  // is effectively receiving a connectivity probing, even if a newer packet has
-  // been received before this one.
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-
-  uint64_t num_probing_received =
-      connection_.GetStats().num_connectivity_probing_received;
-  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-
-  EXPECT_EQ(num_probing_received + 1,
-            connection_.GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    EXPECT_CALL(visitor_,
-                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
-        .Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
-  }
-
-  // Process a padded PING packet from a new peer address on server side
-  // is effectively receiving a connectivity probing.
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Process another non-probing packet with the new peer address on server
-  // side will start peer migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
-
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
-                                  kNewPeerAddress, ENCRYPTION_INITIAL);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, ReceiveConnectivityProbingPacketAtClient) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  // Client takes all padded PING packet as speculative connectivity
-  // probing packet, and reports to visitor.
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-  uint64_t num_probing_received =
-      connection_.GetStats().num_connectivity_probing_received;
-  ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
-
-  EXPECT_EQ(
-      num_probing_received + (GetParam().version.HasIetfQuicFrames() ? 1u : 0u),
-      connection_.GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, ReceiveConnectivityProbingResponseAtClient) {
-  // TODO(b/150095484): add test coverage for IETF to verify that client takes
-  // PATH RESPONSE with peer address change as correct validation on the new
-  // path.
-  if (GetParam().version.HasIetfQuicFrames()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  // Process a padded PING packet with a different self address on client side
-  // is effectively receiving a connectivity probing.
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    EXPECT_CALL(visitor_,
-                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
-        .Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
-  }
-
-  const QuicSocketAddress kNewSelfAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-  uint64_t num_probing_received =
-      connection_.GetStats().num_connectivity_probing_received;
-  ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
-
-  EXPECT_EQ(num_probing_received + 1,
-            connection_.GetStats().num_connectivity_probing_received);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-}
-
-TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  set_perspective(Perspective::IS_CLIENT);
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Process another packet with a different peer address on client side will
-  // only update peer address.
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
-                                  kNewPeerAddress, ENCRYPTION_INITIAL);
-  if (connection_.version().HasIetfQuicFrames()) {
-    // IETF QUIC disallows server initiated address change.
-    EXPECT_EQ(kPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-  } else {
-    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  }
-}
-
-TEST_P(QuicConnectionTest, MaxPacketSize) {
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-  EXPECT_EQ(1250u, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, PeerLowersMaxPacketSize) {
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-
-  // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  constexpr uint32_t kTestMaxPacketSize = 1233u;
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
-  connection_.SetFromConfig(config);
-
-  EXPECT_EQ(kTestMaxPacketSize, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, PeerCannotRaiseMaxPacketSize) {
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-
-  // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  constexpr uint32_t kTestMaxPacketSize = 1450u;
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
-  connection_.SetFromConfig(config);
-
-  EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
-  TestConnection connection(TestConnectionId(), kSelfAddress, kPeerAddress,
-                            helper_.get(), alarm_factory_.get(), writer_.get(),
-                            Perspective::IS_SERVER, version());
-  EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
-  EXPECT_EQ(1000u, connection.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, LowerServerResponseMtuTest) {
-  set_perspective(Perspective::IS_SERVER);
-  connection_.SetMaxPacketLength(1000);
-  EXPECT_EQ(1000u, connection_.max_packet_length());
-
-  SetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test, true);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(::testing::AtMost(1));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(::testing::AtMost(1));
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  EXPECT_EQ(1250u, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
-  set_perspective(Perspective::IS_SERVER);
-  connection_.SetMaxPacketLength(1000);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = connection_id_;
-  header.version_flag = true;
-  header.packet_number = QuicPacketNumber(12);
-
-  if (QuicVersionHasLongHeaderLengths(
-          peer_framer_.version().transport_version)) {
-    header.long_packet_type = INITIAL;
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-
-  QuicFrames frames;
-  QuicPaddingFrame padding;
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    frames.push_back(QuicFrame(&crypto_frame_));
-  } else {
-    frames.push_back(QuicFrame(frame1_));
-  }
-  frames.push_back(QuicFrame(padding));
-  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
-                                  *packet, buffer, kMaxOutgoingPacketSize);
-  EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
-
-  framer_.set_version(version());
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  }
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, clock_.ApproximateNow(),
-                         false));
-
-  EXPECT_EQ(kMaxOutgoingPacketSize, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
-  const QuicByteCount lower_max_packet_size = 1240;
-  writer_->set_max_packet_size(lower_max_packet_size);
-  set_perspective(Perspective::IS_SERVER);
-  connection_.SetMaxPacketLength(1000);
-  EXPECT_EQ(1000u, connection_.max_packet_length());
-
-  QuicPacketHeader header;
-  header.destination_connection_id = connection_id_;
-  header.version_flag = true;
-  header.packet_number = QuicPacketNumber(12);
-
-  if (QuicVersionHasLongHeaderLengths(
-          peer_framer_.version().transport_version)) {
-    header.long_packet_type = INITIAL;
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-
-  QuicFrames frames;
-  QuicPaddingFrame padding;
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    frames.push_back(QuicFrame(&crypto_frame_));
-  } else {
-    frames.push_back(QuicFrame(frame1_));
-  }
-  frames.push_back(QuicFrame(padding));
-  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
-                                  *packet, buffer, kMaxOutgoingPacketSize);
-  EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
-
-  framer_.set_version(version());
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  }
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, clock_.ApproximateNow(),
-                         false));
-
-  // Here, the limit imposed by the writer is lower than the size of the packet
-  // received, so the writer max packet size is used.
-  EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriter) {
-  const QuicByteCount lower_max_packet_size = 1240;
-  writer_->set_max_packet_size(lower_max_packet_size);
-
-  static_assert(lower_max_packet_size < kDefaultMaxPacketSize,
-                "Default maximum packet size is too low");
-  connection_.SetMaxPacketLength(kDefaultMaxPacketSize);
-
-  EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) {
-  const QuicConnectionId connection_id = TestConnectionId(17);
-  const QuicByteCount lower_max_packet_size = 1240;
-  writer_->set_max_packet_size(lower_max_packet_size);
-  TestConnection connection(connection_id, kSelfAddress, kPeerAddress,
-                            helper_.get(), alarm_factory_.get(), writer_.get(),
-                            Perspective::IS_CLIENT, version());
-  EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
-  EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
-}
-
-TEST_P(QuicConnectionTest, PacketsInOrder) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  ProcessPacket(1);
-  EXPECT_EQ(QuicPacketNumber(1u), LargestAcked(connection_.ack_frame()));
-  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
-  ProcessPacket(2);
-  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(connection_.ack_frame()));
-  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
-  ProcessPacket(3);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-}
-
-TEST_P(QuicConnectionTest, PacketsOutOfOrder) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  ProcessPacket(3);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_TRUE(IsMissing(2));
-  EXPECT_TRUE(IsMissing(1));
-
-  ProcessPacket(2);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_FALSE(IsMissing(2));
-  EXPECT_TRUE(IsMissing(1));
-
-  ProcessPacket(1);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_FALSE(IsMissing(2));
-  EXPECT_FALSE(IsMissing(1));
-}
-
-TEST_P(QuicConnectionTest, DuplicatePacket) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  ProcessPacket(3);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_TRUE(IsMissing(2));
-  EXPECT_TRUE(IsMissing(1));
-
-  // Send packet 3 again, but do not set the expectation that
-  // the visitor OnStreamFrame() will be called.
-  ProcessDataPacket(3);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_TRUE(IsMissing(2));
-  EXPECT_TRUE(IsMissing(1));
-}
-
-TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  ProcessPacket(3);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_TRUE(IsMissing(2));
-  EXPECT_TRUE(IsMissing(1));
-
-  ProcessPacket(2);
-  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
-  EXPECT_TRUE(IsMissing(1));
-
-  ProcessPacket(5);
-  EXPECT_EQ(QuicPacketNumber(5u), LargestAcked(connection_.ack_frame()));
-  EXPECT_TRUE(IsMissing(1));
-  EXPECT_TRUE(IsMissing(4));
-
-  // Pretend at this point the client has gotten acks for 2 and 3 and 1 is a
-  // packet the peer will not retransmit.  It indicates this by sending 'least
-  // awaiting' is 4.  The connection should then realize 1 will not be
-  // retransmitted, and will remove it from the missing list.
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessAckPacket(6, &frame);
-
-  // Force an ack to be sent.
-  SendAckPacketToPeer();
-  EXPECT_TRUE(IsMissing(4));
-}
-
-TEST_P(QuicConnectionTest, RejectUnencryptedStreamData) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration() ||
-      VersionHasIetfQuicFrames(version().transport_version)) {
-    return;
-  }
-
-  // Process an unencrypted packet from the non-crypto stream.
-  frame1_.stream_id = 3;
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_QUIC_PEER_BUG(ProcessDataPacketAtLevel(1, false, ENCRYPTION_INITIAL),
-                       "");
-  TestConnectionCloseQuicErrorCode(QUIC_UNENCRYPTED_STREAM_DATA);
-}
-
-TEST_P(QuicConnectionTest, OutOfOrderReceiptCausesAckSend) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  ProcessPacket(3);
-  // Should not cause an ack.
-  EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-  ProcessPacket(2);
-  // Should ack immediately, since this fills the last hole.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  ProcessPacket(1);
-  // Should ack immediately, since this fills the last hole.
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-
-  ProcessPacket(4);
-  // Should not cause an ack.
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, OutOfOrderAckReceiptCausesNoAck) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-
-  QuicAckFrame ack1 = InitAckFrame(1);
-  QuicAckFrame ack2 = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(1);
-  }
-  ProcessAckPacket(2, &ack2);
-  // Should ack immediately since we have missing packets.
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(0);
-  }
-  ProcessAckPacket(1, &ack1);
-  // Should not ack an ack filling a missing packet.
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  QuicPacketNumber original, second;
-
-  QuicByteCount packet_size =
-      SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original);  // 1st packet.
-  SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second);        // 2nd packet.
-
-  QuicAckFrame frame = InitAckFrame({{second, second + 1}});
-  // First nack triggers early retransmit.
-  LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicPacketNumber retransmission;
-  // Packet 1 is short header for IETF QUIC because the encryption level
-  // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _,
-                           GetParam().version.HasIetfInvariantHeader()
-                               ? packet_size
-                               : packet_size - kQuicVersionSize,
-                           _))
-      .WillOnce(SaveArg<2>(&retransmission));
-
-  ProcessAckPacket(&frame);
-
-  QuicAckFrame frame2 = ConstructAckFrame(retransmission, original);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  ProcessAckPacket(&frame2);
-
-  // Now if the peer sends an ack which still reports the retransmitted packet
-  // as missing, that will bundle an ack with data after two acks in a row
-  // indicate the high water mark needs to be raised.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
-  connection_.SendStreamDataWithString(3, "foo", 6, NO_FIN);
-  // No ack sent.
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-
-  // No more packet loss for the rest of the test.
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .Times(AnyNumber());
-  ProcessAckPacket(&frame2);
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
-  connection_.SendStreamDataWithString(3, "foofoofoo", 9, NO_FIN);
-  // Ack bundled.
-  if (GetParam().no_stop_waiting) {
-    // Do not ACK acks.
-    EXPECT_EQ(1u, writer_->frame_count());
-  } else {
-    EXPECT_EQ(3u, writer_->frame_count());
-  }
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  if (GetParam().no_stop_waiting) {
-    EXPECT_TRUE(writer_->ack_frames().empty());
-  } else {
-    EXPECT_FALSE(writer_->ack_frames().empty());
-  }
-
-  // But an ack with no missing packets will not send an ack.
-  AckPacket(original, &frame2);
-  ProcessAckPacket(&frame2);
-  ProcessAckPacket(&frame2);
-}
-
-TEST_P(QuicConnectionTest, AckFrequencyUpdatedFromAckFrequencyFrame) {
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    return;
-  }
-  connection_.set_can_receive_ack_frequency_frame();
-
-  // Expect 13 acks, every 3rd packet including the first packet with
-  // AckFrequencyFrame.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(13);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  QuicAckFrequencyFrame ack_frequency_frame;
-  ack_frequency_frame.packet_tolerance = 3;
-  ProcessFramePacketAtLevel(1, QuicFrame(&ack_frequency_frame),
-                            ENCRYPTION_FORWARD_SECURE);
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(38);
-  // Receives packets 2 - 39.
-  for (size_t i = 2; i <= 39; ++i) {
-    ProcessDataPacket(i);
-  }
-}
-
-TEST_P(QuicConnectionTest, AckDecimationReducesAcks) {
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
-
-  // Start ack decimation from 10th packet.
-  connection_.set_min_received_before_ack_decimation(10);
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(30);
-
-  // Expect 6 acks: 5 acks between packets 1-10, and ack at 20.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
-  // Receives packets 1 - 29.
-  for (size_t i = 1; i <= 29; ++i) {
-    ProcessDataPacket(i);
-  }
-
-  // We now receive the 30th packet, and so we send an ack.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessDataPacket(30);
-}
-
-TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(99);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
-  // Receives packets 1 - 39.
-  for (size_t i = 1; i <= 39; ++i) {
-    ProcessDataPacket(i);
-  }
-  // Receiving Packet 40 causes 20th ack to send. Session is informed and adds
-  // WINDOW_UPDATE.
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
-      .WillOnce(Invoke([this]() {
-        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
-      }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_EQ(0u, writer_->window_update_frames().size());
-  ProcessDataPacket(40);
-  EXPECT_EQ(1u, writer_->window_update_frames().size());
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
-  // Receives packets 41 - 59.
-  for (size_t i = 41; i <= 59; ++i) {
-    ProcessDataPacket(i);
-  }
-  // Send a packet containing stream frame.
-  SendStreamDataToPeer(
-      QuicUtils::GetFirstBidirectionalStreamId(
-          connection_.version().transport_version, Perspective::IS_CLIENT),
-      "bar", 0, NO_FIN, nullptr);
-
-  // Session will not be informed until receiving another 20 packets.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
-  for (size_t i = 60; i <= 98; ++i) {
-    ProcessDataPacket(i);
-    EXPECT_EQ(0u, writer_->window_update_frames().size());
-  }
-  // Session does not add a retransmittable frame.
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
-      .WillOnce(Invoke([this]() {
-        connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
-      }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_EQ(0u, writer_->ping_frames().size());
-  ProcessDataPacket(99);
-  EXPECT_EQ(0u, writer_->window_update_frames().size());
-  // A ping frame will be added.
-  EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, AckNeedsRetransmittableFramesAfterPto) {
-  // Disable TLP so the RTO fires immediately.
-  connection_.SetMaxTailLossProbes(0);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kEACK);
-  config.SetConnectionOptionsToSend(connection_options);
-  connection_.SetFromConfig(config);
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.OnHandshakeComplete();
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(10);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
-  // Receive packets 1 - 9.
-  for (size_t i = 1; i <= 9; ++i) {
-    ProcessDataPacket(i);
-  }
-
-  // Send a ping and fire the retransmission alarm.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  SendPing();
-  QuicTime retransmission_time =
-      connection_.GetRetransmissionAlarm()->deadline();
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  connection_.GetRetransmissionAlarm()->Fire();
-  ASSERT_TRUE(manager_->GetConsecutiveRtoCount() > 0 ||
-              manager_->GetConsecutivePtoCount() > 0);
-
-  // Process a packet, which requests a retransmittable frame be bundled
-  // with the ACK.
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
-      .WillOnce(Invoke([this]() {
-        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
-      }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessDataPacket(11);
-  EXPECT_EQ(1u, writer_->window_update_frames().size());
-}
-
-TEST_P(QuicConnectionTest, LeastUnackedLower) {
-  if (GetParam().version.HasIetfInvariantHeader()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
-  SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
-
-  // Start out saying the least unacked is 2.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
-  ProcessStopWaitingPacket(InitStopWaitingFrame(2));
-
-  // Change it to 1, but lower the packet number to fake out-of-order packets.
-  // This should be fine.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
-  // The scheduler will not process out of order acks, but all packet processing
-  // causes the connection to try to write.
-  if (!GetParam().no_stop_waiting) {
-    EXPECT_CALL(visitor_, OnCanWrite());
-  }
-  ProcessStopWaitingPacket(InitStopWaitingFrame(1));
-
-  // Now claim it's one, but set the ordering so it was sent "after" the first
-  // one.  This should cause a connection error.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 7);
-  if (!GetParam().no_stop_waiting) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AtLeast(1));
-    EXPECT_CALL(visitor_,
-                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-        .Times(AtLeast(1));
-  }
-  ProcessStopWaitingPacket(InitStopWaitingFrame(1));
-  if (!GetParam().no_stop_waiting) {
-    TestConnectionCloseQuicErrorCode(QUIC_INVALID_STOP_WAITING_DATA);
-  }
-}
-
-TEST_P(QuicConnectionTest, TooManySentPackets) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  QuicPacketCount max_tracked_packets = 50;
-  QuicConnectionPeer::SetMaxTrackedPackets(&connection_, max_tracked_packets);
-
-  const int num_packets = max_tracked_packets + 5;
-
-  for (int i = 0; i < num_packets; ++i) {
-    SendStreamDataToPeer(1, "foo", 3 * i, NO_FIN, nullptr);
-  }
-
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-
-  ProcessFramePacket(QuicFrame(QuicPingFrame()));
-
-  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
-}
-
-TEST_P(QuicConnectionTest, LargestObservedLower) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
-  SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
-  // Start out saying the largest observed is 2.
-  QuicAckFrame frame1 = InitAckFrame(1);
-  QuicAckFrame frame2 = InitAckFrame(2);
-  ProcessAckPacket(&frame2);
-
-  EXPECT_CALL(visitor_, OnCanWrite());
-  ProcessAckPacket(&frame1);
-}
-
-TEST_P(QuicConnectionTest, AckUnsentData) {
-  // Ack a packet which has not been sent.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
-  ProcessAckPacket(&frame);
-  TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
-}
-
-TEST_P(QuicConnectionTest, BasicSending) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  const QuicConnectionStats& stats = connection_.GetStats();
-  EXPECT_FALSE(stats.first_decrypted_packet.IsInitialized());
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(1);
-  EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
-  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-  SendAckPacketToPeer();  // Packet 2
-
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
-  }
-
-  SendAckPacketToPeer();  // Packet 3
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
-  }
-
-  SendStreamDataToPeer(1, "bar", 3, NO_FIN, &last_packet);  // Packet 4
-  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
-  SendAckPacketToPeer();  // Packet 5
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
-  }
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
-  // Peer acks up to packet 3.
-  QuicAckFrame frame = InitAckFrame(3);
-  ProcessAckPacket(&frame);
-  SendAckPacketToPeer();  // Packet 6
-
-  // As soon as we've acked one, we skip ack packets 2 and 3 and note lack of
-  // ack for 4.
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
-  }
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
-  // Peer acks up to packet 4, the last packet.
-  QuicAckFrame frame2 = InitAckFrame(6);
-  ProcessAckPacket(&frame2);  // Acks don't instigate acks.
-
-  // Verify that we did not send an ack.
-  EXPECT_EQ(QuicPacketNumber(6u), writer_->header().packet_number);
-
-  // So the last ack has not changed.
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
-  }
-
-  // If we force an ack, we shouldn't change our retransmit state.
-  SendAckPacketToPeer();  // Packet 7
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
-  }
-
-  // But if we send more data it should.
-  SendStreamDataToPeer(1, "eep", 6, NO_FIN, &last_packet);  // Packet 8
-  EXPECT_EQ(QuicPacketNumber(8u), last_packet);
-  SendAckPacketToPeer();  // Packet 9
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
-  }
-  EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
-}
-
-// QuicConnection should record the packet sent-time prior to sending the
-// packet.
-TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
-  // We're using a MockClock for the tests, so we have complete control over the
-  // time.
-  // Our recorded timestamp for the last packet sent time will be passed in to
-  // the send_algorithm.  Make sure that it is set to the correct value.
-  QuicTime actual_recorded_send_time = QuicTime::Zero();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<0>(&actual_recorded_send_time));
-
-  // First send without any pause and check the result.
-  QuicTime expected_recorded_send_time = clock_.Now();
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
-      << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
-      << ".  Actual time = " << actual_recorded_send_time.ToDebuggingValue();
-
-  // Now pause during the write, and check the results.
-  actual_recorded_send_time = QuicTime::Zero();
-  const QuicTime::Delta write_pause_time_delta =
-      QuicTime::Delta::FromMilliseconds(5000);
-  SetWritePauseTimeDelta(write_pause_time_delta);
-  expected_recorded_send_time = clock_.Now();
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<0>(&actual_recorded_send_time));
-  connection_.SendStreamDataWithString(2, "baz", 0, NO_FIN);
-  EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
-      << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
-      << ".  Actual time = " << actual_recorded_send_time.ToDebuggingValue();
-}
-
-TEST_P(QuicConnectionTest, FramePacking) {
-  // Send two stream frames in 1 packet by queueing them.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendStreamData3();
-    connection_.SendStreamData5();
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  }
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Parse the last packet and ensure it's an ack and two stream frames from
-  // two different streams.
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(2u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(2u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  }
-
-  EXPECT_TRUE(writer_->ack_frames().empty());
-
-  ASSERT_EQ(2u, writer_->stream_frames().size());
-  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
-            writer_->stream_frames()[0]->stream_id);
-  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
-            writer_->stream_frames()[1]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
-  // Send two stream frames (one non-crypto, then one crypto) in 2 packets by
-  // queueing them.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendStreamData3();
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoStreamData();
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  }
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Parse the last packet and ensure it contains a crypto stream frame.
-  EXPECT_LE(2u, writer_->frame_count());
-  ASSERT_LE(1u, writer_->padding_frames().size());
-  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    ASSERT_EQ(1u, writer_->stream_frames().size());
-    EXPECT_EQ(QuicUtils::GetCryptoStreamId(connection_.transport_version()),
-              writer_->stream_frames()[0]->stream_id);
-  } else {
-    EXPECT_LE(1u, writer_->crypto_frames().size());
-  }
-}
-
-TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
-  // Send two stream frames (one crypto, then one non-crypto) in 2 packets by
-  // queueing them.
-  {
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendCryptoStreamData();
-    connection_.SendStreamData3();
-  }
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Parse the last packet and ensure it's the stream frame from stream 3.
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  ASSERT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
-            writer_->stream_frames()[0]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, FramePackingAckResponse) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  // Process a data packet to queue up a pending ack.
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  }
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
-  QuicPacketNumber last_packet;
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    connection_.SendCryptoDataWithString("foo", 0);
-  } else {
-    SendStreamDataToPeer(
-        QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
-        NO_FIN, &last_packet);
-  }
-  // Verify ack is bundled with outging packet.
-  EXPECT_FALSE(writer_->ack_frames().empty());
-
-  EXPECT_CALL(visitor_, OnCanWrite())
-      .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
-                          &connection_, &TestConnection::SendStreamData3)),
-                      IgnoreResult(InvokeWithoutArgs(
-                          &connection_, &TestConnection::SendStreamData5))));
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-
-  // Process a data packet to cause the visitor's OnCanWrite to be invoked.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  ProcessDataPacket(2);
-
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Parse the last packet and ensure it's an ack and two stream frames from
-  // two different streams.
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(4u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  ASSERT_EQ(2u, writer_->stream_frames().size());
-  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
-            writer_->stream_frames()[0]->stream_id);
-  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
-            writer_->stream_frames()[1]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, FramePackingSendv) {
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      connection_.transport_version(), Perspective::IS_CLIENT);
-  connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN);
-
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Parse the last packet and ensure multiple iovector blocks have
-  // been packed into a single stream frame from one stream.
-  EXPECT_EQ(1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(0u, writer_->padding_frames().size());
-  QuicStreamFrame* frame = writer_->stream_frames()[0].get();
-  EXPECT_EQ(stream_id, frame->stream_id);
-  EXPECT_EQ("ABCDEF",
-            absl::string_view(frame->data_buffer, frame->data_length));
-}
-
-TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-
-  BlockOnNextWrite();
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      connection_.transport_version(), Perspective::IS_CLIENT);
-  connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN);
-
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-  EXPECT_TRUE(connection_.HasQueuedData());
-
-  // Unblock the writes and actually send.
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
-  // Parse the last packet and ensure it's one stream frame from one stream.
-  EXPECT_EQ(1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(0u, writer_->padding_frames().size());
-  QuicStreamFrame* frame = writer_->stream_frames()[0].get();
-  EXPECT_EQ(stream_id, frame->stream_id);
-  EXPECT_EQ("ABCDEF",
-            absl::string_view(frame->data_buffer, frame->data_length));
-}
-
-TEST_P(QuicConnectionTest, SendingZeroBytes) {
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Send a zero byte write with a fin using writev.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      connection_.transport_version(), Perspective::IS_CLIENT);
-  connection_.SaveAndSendStreamData(stream_id, {}, 0, FIN);
-
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Padding frames are added by v99 to ensure a minimum packet size.
-  size_t extra_padding_frames = 0;
-  if (GetParam().version.HasHeaderProtection()) {
-    extra_padding_frames = 1;
-  }
-
-  // Parse the last packet and ensure it's one stream frame from one stream.
-  EXPECT_EQ(1u + extra_padding_frames, writer_->frame_count());
-  EXPECT_EQ(extra_padding_frames, writer_->padding_frames().size());
-  ASSERT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
-  EXPECT_TRUE(writer_->stream_frames()[0]->fin);
-}
-
-TEST_P(QuicConnectionTest, LargeSendWithPendingAck) {
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  // Set the ack alarm by processing a ping frame.
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  // Processs a PING frame.
-  ProcessFramePacket(QuicFrame(QuicPingFrame()));
-  // Ensure that this has caused the ACK alarm to be set.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  // Send data and ensure the ack is bundled.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
-  const std::string data(10000, '?');
-  QuicConsumedData consumed = connection_.SaveAndSendStreamData(
-      GetNthClientInitiatedStreamId(0, connection_.transport_version()), data,
-      0, FIN);
-  EXPECT_EQ(data.length(), consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.HasQueuedData());
-
-  // Parse the last packet and ensure it's one stream frame with a fin.
-  EXPECT_EQ(1u, writer_->frame_count());
-  ASSERT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(GetNthClientInitiatedStreamId(0, connection_.transport_version()),
-            writer_->stream_frames()[0]->stream_id);
-  EXPECT_TRUE(writer_->stream_frames()[0]->fin);
-  // Ensure the ack alarm was cancelled when the ack was sent.
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, OnCanWrite) {
-  // Visitor's OnCanWrite will send data, but will have more pending writes.
-  EXPECT_CALL(visitor_, OnCanWrite())
-      .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
-                          &connection_, &TestConnection::SendStreamData3)),
-                      IgnoreResult(InvokeWithoutArgs(
-                          &connection_, &TestConnection::SendStreamData5))));
-  {
-    InSequence seq;
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true));
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
-        .WillRepeatedly(Return(false));
-  }
-
-  EXPECT_CALL(*send_algorithm_, CanSend(_))
-      .WillRepeatedly(testing::Return(true));
-
-  connection_.OnCanWrite();
-
-  // Parse the last packet and ensure it's the two stream frames from
-  // two different streams.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_EQ(2u, writer_->stream_frames().size());
-  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
-            writer_->stream_frames()[0]->stream_id);
-  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
-            writer_->stream_frames()[1]->stream_id);
-}
-
-TEST_P(QuicConnectionTest, RetransmitOnNack) {
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(3, "foos", 3, NO_FIN, &last_packet);
-  SendStreamDataToPeer(3, "fooos", 7, NO_FIN, &last_packet);
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  // Don't lose a packet on an ack, and nothing is retransmitted.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame ack_one = InitAckFrame(1);
-  ProcessAckPacket(&ack_one);
-
-  // Lose a packet and ensure it triggers retransmission.
-  QuicAckFrame nack_two = ConstructAckFrame(3, 2);
-  LostPacketVector lost_packets;
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
-  ProcessAckPacket(&nack_two);
-}
-
-TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
-  // Block the connection to queue the packet.
-  BlockOnNextWrite();
-
-  QuicStreamId stream_id = 2;
-  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
-
-  // Now that there is a queued packet, reset the stream.
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
-  // Unblock the connection and verify that only the RST_STREAM is sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, SendQueuedPacketForQuicRstStreamNoError) {
-  // Block the connection to queue the packet.
-  BlockOnNextWrite();
-
-  QuicStreamId stream_id = 2;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
-
-  // Now that there is a queued packet, reset the stream.
-  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
-
-  // Unblock the connection and verify that the RST_STREAM is sent and the data
-  // packet is sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) {
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
-
-  // Lose a packet and ensure it does not trigger retransmission.
-  QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessAckPacket(&nack_two);
-}
-
-TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnNack) {
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
-
-  // Lose a packet, ensure it triggers retransmission.
-  QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  ProcessAckPacket(&nack_two);
-}
-
-TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
-  // Fire the RTO and verify that the RST_STREAM is resent, not stream data.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  connection_.GetRetransmissionAlarm()->Fire();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-  EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
-}
-
-// Ensure that if the only data in flight is non-retransmittable, the
-// retransmission alarm is not set.
-TEST_P(QuicConnectionTest, CancelRetransmissionAlarmAfterResetStream) {
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_data_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
-
-  // Cancel the stream.
-  const QuicPacketNumber rst_packet = last_data_packet + 1;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, rst_packet, _, _)).Times(1);
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
-  // Ack the RST_STREAM frame (since it's retransmittable), but not the data
-  // packet, which is no longer retransmittable since the stream was cancelled.
-  QuicAckFrame nack_stream_data =
-      ConstructAckFrame(rst_packet, last_data_packet);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessAckPacket(&nack_stream_data);
-
-  // Ensure that the data is still in flight, but the retransmission alarm is no
-  // longer set.
-  EXPECT_GT(manager_->GetBytesInFlight(), 0u);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
-  connection_.SetMaxTailLossProbes(0);
-
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
-
-  // Fire the RTO and verify that the RST_STREAM is resent, the stream data
-  // is sent.
-  const size_t num_retransmissions = connection_.PtoEnabled() ? 1 : 2;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(num_retransmissions));
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  connection_.GetRetransmissionAlarm()->Fire();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  if (num_retransmissions == 2) {
-    ASSERT_EQ(1u, writer_->rst_stream_frames().size());
-    EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
-  }
-}
-
-TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
-
-  // Lose a packet which will trigger a pending retransmission.
-  QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessAckPacket(&ack);
-
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
-
-  // Unblock the connection and verify that the RST_STREAM is sent but not the
-  // second data packet nor a retransmit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  ASSERT_EQ(1u, writer_->rst_stream_frames().size());
-  EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
-}
-
-TEST_P(QuicConnectionTest, SendPendingRetransmissionForQuicRstStreamNoError) {
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
-
-  // Lose a packet which will trigger a pending retransmission.
-  QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessAckPacket(&ack);
-
-  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
-
-  // Unblock the connection and verify that the RST_STREAM is sent and the
-  // second data packet or a retransmit is sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2));
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  // The RST_STREAM_FRAME is sent after queued packets and pending
-  // retransmission.
-  connection_.SendControlFrame(QuicFrame(
-      new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, RetransmitAckedPacket) {
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);    // Packet 1
-  SendStreamDataToPeer(1, "foos", 3, NO_FIN, &last_packet);   // Packet 2
-  SendStreamDataToPeer(1, "fooos", 7, NO_FIN, &last_packet);  // Packet 3
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  // Instigate a loss with an ack.
-  QuicAckFrame nack_two = ConstructAckFrame(3, 2);
-  // The first nack should trigger a fast retransmission, but we'll be
-  // write blocked, so the packet will be queued.
-  BlockOnNextWrite();
-
-  LostPacketVector lost_packets;
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
-      .Times(1);
-  ProcessAckPacket(&nack_two);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Now, ack the previous transmission.
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _));
-  QuicAckFrame ack_all = InitAckFrame(3);
-  ProcessAckPacket(&ack_all);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
-      .Times(0);
-
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  // We do not store retransmittable frames of this retransmission.
-  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 4));
-}
-
-TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  QuicPacketNumber original, second;
-
-  QuicByteCount packet_size =
-      SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original);  // 1st packet.
-  SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second);        // 2nd packet.
-
-  QuicAckFrame frame = InitAckFrame({{second, second + 1}});
-  // The first nack should retransmit the largest observed packet.
-  LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  // Packet 1 is short header for IETF QUIC because the encryption level
-  // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _,
-                           GetParam().version.HasIetfInvariantHeader()
-                               ? packet_size
-                               : packet_size - kQuicVersionSize,
-                           _));
-  ProcessAckPacket(&frame);
-}
-
-TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(0);
-
-  for (int i = 0; i < 10; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendStreamDataWithString(3, "foo", i * 3, NO_FIN);
-  }
-
-  // Block the writer and ensure they're queued.
-  BlockOnNextWrite();
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_TRUE(connection_.HasQueuedData());
-
-  // Unblock the writer.
-  writer_->SetWritable();
-  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
-      2 * DefaultRetransmissionTime().ToMicroseconds()));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  connection_.GetRetransmissionAlarm()->Fire();
-  connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedBufferedThenSent) {
-  BlockOnNextWrite();
-  writer_->set_is_write_blocked_data_buffered(true);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  BlockOnNextWrite();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // The second packet should also be queued, in order to ensure packets are
-  // never sent out of order.
-  writer_->SetWritable();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_EQ(2u, connection_.NumQueuedPackets());
-
-  // Now both are sent in order when we unblock.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.OnCanWrite();
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  BlockOnNextWrite();
-  writer_->set_is_write_blocked_data_buffered(true);
-  // Simulate the retransmission alarm firing.
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  // Ack the sent packet before the callback returns, which happens in
-  // rare circumstances with write blocked sockets.
-  QuicAckFrame ack = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&ack);
-
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  uint64_t retransmission = connection_.PtoEnabled() ? 3 : 2;
-  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
-                                                            retransmission));
-}
-
-TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) {
-  // Block the connection.
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-
-  // Set the send alarm. Fire the alarm and ensure it doesn't attempt to write.
-  connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
-  connection_.GetSendAlarm()->Fire();
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, NoSendAlarmAfterProcessPacketWhenWriteBlocked) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  // Block the connection.
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  // Process packet number 1. Can not call ProcessPacket or ProcessDataPacket
-  // here, because they will fire the alarm after QuicConnection::ProcessPacket
-  // is returned.
-  const uint64_t received_packet_num = 1;
-  const bool has_stop_waiting = false;
-  const EncryptionLevel level = ENCRYPTION_FORWARD_SECURE;
-  std::unique_ptr<QuicPacket> packet(
-      ConstructDataPacket(received_packet_num, has_stop_waiting, level));
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
-                                  *packet, buffer, kMaxOutgoingPacketSize);
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, AddToWriteBlockedListIfWriterBlockedWhenProcessing) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-
-  // Simulate the case where a shared writer gets blocked by another connection.
-  writer_->SetWriteBlocked();
-
-  // Process an ACK, make sure the connection calls visitor_->OnWriteBlocked().
-  QuicAckFrame ack1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
-  ProcessAckPacket(1, &ack1);
-}
-
-TEST_P(QuicConnectionTest, DoNotAddToWriteBlockedListAfterDisconnect) {
-  writer_->SetBatchMode(true);
-  EXPECT_TRUE(connection_.connected());
-  // Have to explicitly grab the OnConnectionClosed frame and check
-  // its parameters because this is a silent connection close and the
-  // frame is not also transmitted to the peer.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
-
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
-                                ConnectionCloseBehavior::SILENT_CLOSE);
-
-    EXPECT_FALSE(connection_.connected());
-    writer_->SetWriteBlocked();
-  }
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, AddToWriteBlockedListIfBlockedOnFlushPackets) {
-  writer_->SetBatchMode(true);
-  writer_->BlockOnNextFlush();
-
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // flusher's destructor will call connection_.FlushPackets, which should add
-    // the connection to the write blocked list.
-  }
-}
-
-TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  int offset = 0;
-  // Send packets 1 to 15.
-  for (int i = 0; i < 15; ++i) {
-    SendStreamDataToPeer(1, "foo", offset, NO_FIN, nullptr);
-    offset += 3;
-  }
-
-  // Ack 15, nack 1-14.
-
-  QuicAckFrame nack =
-      InitAckFrame({{QuicPacketNumber(15), QuicPacketNumber(16)}});
-
-  // 14 packets have been NACK'd and lost.
-  LostPacketVector lost_packets;
-  for (int i = 1; i < 15; ++i) {
-    lost_packets.push_back(
-        LostPacket(QuicPacketNumber(i), kMaxOutgoingPacketSize));
-  }
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessAckPacket(&nack);
-}
-
-// Test sending multiple acks from the connection to the session.
-TEST_P(QuicConnectionTest, MultipleAcks) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(1);
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
-  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 2
-  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
-  SendAckPacketToPeer();                                    // Packet 3
-  SendStreamDataToPeer(5, "foo", 0, NO_FIN, &last_packet);  // Packet 4
-  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
-  SendStreamDataToPeer(1, "foo", 3, NO_FIN, &last_packet);  // Packet 5
-  EXPECT_EQ(QuicPacketNumber(5u), last_packet);
-  SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 6
-  EXPECT_EQ(QuicPacketNumber(6u), last_packet);
-
-  // Client will ack packets 1, 2, [!3], 4, 5.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame1 = ConstructAckFrame(5, 3);
-  ProcessAckPacket(&frame1);
-
-  // Now the client implicitly acks 3, and explicitly acks 6.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame2 = InitAckFrame(6);
-  ProcessAckPacket(&frame2);
-}
-
-TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(1);
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);  // Packet 1;
-  // From now on, we send acks, so the send algorithm won't mark them pending.
-  SendAckPacketToPeer();  // Packet 2
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame(1);
-  ProcessAckPacket(&frame);
-
-  // Verify that our internal state has least-unacked as 2, because we're still
-  // waiting for a potential ack for 2.
-
-  EXPECT_EQ(QuicPacketNumber(2u), stop_waiting()->least_unacked);
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame(2);
-  ProcessAckPacket(&frame);
-  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
-
-  // When we send an ack, we make sure our least-unacked makes sense.  In this
-  // case since we're not waiting on an ack for 2 and all packets are acked, we
-  // set it to 3.
-  SendAckPacketToPeer();  // Packet 3
-  // Least_unacked remains at 3 until another ack is received.
-  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    // Check that the outgoing ack had its packet number as least_unacked.
-    EXPECT_EQ(QuicPacketNumber(3u), least_unacked());
-  }
-
-  // Ack the ack, which updates the rtt and raises the least unacked.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame(3);
-  ProcessAckPacket(&frame);
-
-  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);  // Packet 4
-  EXPECT_EQ(QuicPacketNumber(4u), stop_waiting()->least_unacked);
-  SendAckPacketToPeer();  // Packet 5
-  if (GetParam().no_stop_waiting) {
-    // Expect no stop waiting frame is sent.
-    EXPECT_FALSE(least_unacked().IsInitialized());
-  } else {
-    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
-  }
-
-  // Send two data packets at the end, and ensure if the last one is acked,
-  // the least unacked is raised above the ack packets.
-  SendStreamDataToPeer(1, "bar", 6, NO_FIN, nullptr);  // Packet 6
-  SendStreamDataToPeer(1, "bar", 9, NO_FIN, nullptr);  // Packet 7
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
-                        {QuicPacketNumber(7), QuicPacketNumber(8)}});
-  ProcessAckPacket(&frame);
-
-  EXPECT_EQ(QuicPacketNumber(6u), stop_waiting()->least_unacked);
-}
-
-TEST_P(QuicConnectionTest, TLP) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(1);
-
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
-  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-  QuicTime retransmission_time =
-      connection_.GetRetransmissionAlarm()->deadline();
-  EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
-  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
-  // Simulate the retransmission alarm firing and sending a tlp,
-  // so send algorithm's OnRetransmissionTimeout is not called.
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  const QuicPacketNumber retransmission(
-      connection_.SupportsMultiplePacketNumberSpaces() ? 3 : 2);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, retransmission, _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(retransmission, writer_->header().packet_number);
-  // We do not raise the high water mark yet.
-  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-}
-
-TEST_P(QuicConnectionTest, RTO) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(0);
-
-  QuicTime default_retransmission_time =
-      clock_.ApproximateNow() + DefaultRetransmissionTime();
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
-  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-
-  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
-  EXPECT_EQ(default_retransmission_time,
-            connection_.GetRetransmissionAlarm()->deadline());
-  // Simulate the retransmission alarm firing.
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
-  // We do not raise the high water mark yet.
-  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-}
-
-// Regression test of b/133771183.
-TEST_P(QuicConnectionTest, RtoWithNoDataToRetransmit) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  connection_.SetMaxTailLossProbes(0);
-
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
-  // Connection is cwnd limited.
-  CongestionBlockWrites();
-  // Stream gets reset.
-  SendRstStream(3, QUIC_ERROR_PROCESSING_STREAM, 3);
-  // Simulate the retransmission alarm firing.
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  // RTO fires, but there is no packet to be RTOed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(40);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(20);
-  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(1);
-  // Receives packets 1 - 40.
-  for (size_t i = 1; i <= 40; ++i) {
-    ProcessDataPacket(i);
-  }
-}
-
-TEST_P(QuicConnectionTest, SendHandshakeMessages) {
-  use_tagging_decrypter();
-  // A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
-  // the end of the packet. We can test this to check which encrypter was used.
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-
-  // Attempt to send a handshake message and have the socket block.
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  BlockOnNextWrite();
-  connection_.SendCryptoDataWithString("foo", 0);
-  // The packet should be serialized, but not queued.
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Switch to the new encrypter.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
-  // Now become writeable and flush the packets.
-  writer_->SetWritable();
-  EXPECT_CALL(visitor_, OnCanWrite());
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
-  // Verify that the handshake packet went out at the null encryption.
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-}
-
-TEST_P(QuicConnectionTest,
-       DropRetransmitsForNullEncryptedPacketAfterForwardSecure) {
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SendCryptoStreamData();
-
-  // Simulate the retransmission alarm firing and the socket blocking.
-  BlockOnNextWrite();
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Go forward secure.
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  notifier_.NeuterUnencryptedData();
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-
-  EXPECT_EQ(QuicTime::Zero(), connection_.GetRetransmissionAlarm()->deadline());
-  // Unblock the socket and ensure that no packets are sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-}
-
-TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
-  connection_.SendCryptoDataWithString("foo", 0);
-
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
-  SendStreamDataToPeer(2, "bar", 0, NO_FIN, nullptr);
-  EXPECT_FALSE(notifier_.HasLostStreamData());
-  connection_.MarkZeroRttPacketsForRetransmission(0);
-  EXPECT_TRUE(notifier_.HasLostStreamData());
-}
-
-TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  use_tagging_decrypter();
-
-  const uint8_t tag = 0x07;
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(tag));
-
-  // Process an encrypted packet which can not yet be decrypted which should
-  // result in the packet being buffered.
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  // Transition to the new encryption state and process another encrypted packet
-  // which should result in the original packet being processed.
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(tag));
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
-  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  // Finally, process a third packet and note that we do not reprocess the
-  // buffered packet.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-}
-
-TEST_P(QuicConnectionTest, TestRetransmitOrder) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(0);
-
-  QuicByteCount first_packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&first_packet_size));
-
-  connection_.SendStreamDataWithString(3, "first_packet", 0, NO_FIN);
-  QuicByteCount second_packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&second_packet_size));
-  connection_.SendStreamDataWithString(3, "second_packet", 12, NO_FIN);
-  EXPECT_NE(first_packet_size, second_packet_size);
-  // Advance the clock by huge time to make sure packets will be retransmitted.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
-  {
-    InSequence s;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
-  }
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  // Advance again and expect the packets to be sent again in the same order.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
-  {
-    InSequence s;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
-  }
-  connection_.GetRetransmissionAlarm()->Fire();
-}
-
-TEST_P(QuicConnectionTest, Buffer100NonDecryptablePacketsThenKeyChange) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  config.set_max_undecryptable_packets(100);
-  connection_.SetFromConfig(config);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  use_tagging_decrypter();
-
-  const uint8_t tag = 0x07;
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(tag));
-
-  // Process an encrypted packet which can not yet be decrypted which should
-  // result in the packet being buffered.
-  for (uint64_t i = 1; i <= 100; ++i) {
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  }
-
-  // Transition to the new encryption state and process another encrypted packet
-  // which should result in the original packets being processed.
-  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(tag));
-  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(100);
-  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-
-  // Finally, process a third packet and note that we do not reprocess the
-  // buffered packet.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(102, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-}
-
-TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) {
-  BlockOnNextWrite();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Test that RTO is started once we write to the socket.
-  writer_->SetWritable();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.OnCanWrite();
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(0);
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-  connection_.SendStreamDataWithString(3, "bar", 0, NO_FIN);
-  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
-  EXPECT_TRUE(retransmission_alarm->IsSet());
-  EXPECT_EQ(DefaultRetransmissionTime(),
-            retransmission_alarm->deadline() - clock_.Now());
-
-  // Advance the time right before the RTO, then receive an ack for the first
-  // packet to delay the RTO.
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame ack = InitAckFrame(1);
-  ProcessAckPacket(&ack);
-  // Now we have an RTT sample of DefaultRetransmissionTime(500ms),
-  // so the RTO has increased to 2 * SRTT.
-  EXPECT_TRUE(retransmission_alarm->IsSet());
-  EXPECT_EQ(retransmission_alarm->deadline() - clock_.Now(),
-            2 * DefaultRetransmissionTime());
-
-  // Move forward past the original RTO and ensure the RTO is still pending.
-  clock_.AdvanceTime(2 * DefaultRetransmissionTime());
-
-  // Ensure the second packet gets retransmitted when it finally fires.
-  EXPECT_TRUE(retransmission_alarm->IsSet());
-  EXPECT_EQ(retransmission_alarm->deadline(), clock_.ApproximateNow());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  // Manually cancel the alarm to simulate a real test.
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  // The new retransmitted packet number should set the RTO to a larger value
-  // than previously.
-  EXPECT_TRUE(retransmission_alarm->IsSet());
-  QuicTime next_rto_time = retransmission_alarm->deadline();
-  QuicTime expected_rto_time =
-      connection_.sent_packet_manager().GetRetransmissionTime();
-  EXPECT_EQ(next_rto_time, expected_rto_time);
-}
-
-TEST_P(QuicConnectionTest, TestQueued) {
-  connection_.SetMaxTailLossProbes(0);
-
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Unblock the writes and actually send.
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, InitialTimeout) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-
-  // SetFromConfig sets the initial timeouts before negotiation.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  // Subtract a second from the idle timeout on the client side.
-  QuicTime default_timeout =
-      clock_.ApproximateNow() +
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  // Simulate the timeout alarm firing.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1));
-  connection_.GetTimeoutAlarm()->Fire();
-
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, IdleTimeoutAfterFirstSentPacket) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  QuicTime initial_ddl =
-      clock_.ApproximateNow() +
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
-  EXPECT_TRUE(connection_.connected());
-
-  // Advance the time and send the first packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-  // This will be the updated deadline for the connection to idle time out.
-  QuicTime new_ddl = clock_.ApproximateNow() +
-                     QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-
-  // Simulate the timeout alarm firing, the connection should not be closed as
-  // a new packet has been sent.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-  QuicTime::Delta delay = initial_ddl - clock_.ApproximateNow();
-  clock_.AdvanceTime(delay);
-  // Verify the timeout alarm deadline is updated.
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_EQ(new_ddl, connection_.GetTimeoutAlarm()->deadline());
-
-  // Simulate the timeout alarm firing again, the connection now should be
-  // closed.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  clock_.AdvanceTime(new_ddl - clock_.ApproximateNow());
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, IdleTimeoutAfterSendTwoPackets) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  QuicTime initial_ddl =
-      clock_.ApproximateNow() +
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
-  EXPECT_TRUE(connection_.connected());
-
-  // Immediately send the first packet, this is a rare case but test code will
-  // hit this issue often as MockClock used for tests doesn't move with code
-  // execution until manually adjusted.
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-
-  // Advance the time and send the second packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
-
-  // Simulate the timeout alarm firing, the connection will be closed.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  clock_.AdvanceTime(initial_ddl - clock_.ApproximateNow());
-  connection_.GetTimeoutAlarm()->Fire();
-
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, HandshakeTimeout) {
-  // Use a shorter handshake timeout than idle timeout for this test.
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
-  connection_.SetNetworkTimeouts(timeout, timeout);
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
-  QuicTime handshake_timeout =
-      clock_.ApproximateNow() + timeout - QuicTime::Delta::FromSeconds(1);
-  EXPECT_EQ(handshake_timeout, connection_.GetTimeoutAlarm()->deadline());
-  EXPECT_TRUE(connection_.connected());
-
-  // Send and ack new data 3 seconds later to lengthen the idle timeout.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
-      "GET /", 0, FIN, nullptr);
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(3));
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&frame);
-
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_TRUE(connection_.connected());
-
-  clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(2));
-
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  // Simulate the timeout alarm firing.
-  connection_.GetTimeoutAlarm()->Fire();
-
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-  TestConnectionCloseQuicErrorCode(QUIC_HANDSHAKE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, PingAfterSend) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
-  // Advance to 5ms, and send a packet to the peer, which will set
-  // the ping alarm.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
-      "GET /", 0, FIN, nullptr);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now recevie an ACK of the previous packet, which will move the
-  // ping alarm forward.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  // The ping timer is set slightly less than 15 seconds in the future, because
-  // of the 1s ping timer alarm granularity.
-  EXPECT_EQ(
-      QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
-      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  writer_->Reset();
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
-  connection_.GetPingAlarm()->Fire();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  ASSERT_EQ(1u, writer_->ping_frames().size());
-  writer_->Reset();
-
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(false));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  SendAckPacketToPeer();
-
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, ReducedPingTimeout) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
-  // Use a reduced ping timeout for this connection.
-  connection_.set_ping_timeout(QuicTime::Delta::FromSeconds(10));
-
-  // Advance to 5ms, and send a packet to the peer, which will set
-  // the ping alarm.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
-      "GET /", 0, FIN, nullptr);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(10),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now recevie an ACK of the previous packet, which will move the
-  // ping alarm forward.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  // The ping timer is set slightly less than 10 seconds in the future, because
-  // of the 1s ping timer alarm granularity.
-  EXPECT_EQ(
-      QuicTime::Delta::FromSeconds(10) - QuicTime::Delta::FromMilliseconds(5),
-      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  writer_->Reset();
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
-  connection_.GetPingAlarm()->Fire();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  ASSERT_EQ(1u, writer_->ping_frames().size());
-  writer_->Reset();
-
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(false));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  SendAckPacketToPeer();
-
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-}
-
-// Tests whether sending an MTU discovery packet to peer successfully causes the
-// maximum packet size to increase.
-TEST_P(QuicConnectionTest, SendMtuDiscoveryPacket) {
-  MtuDiscoveryTestInit();
-
-  // Send an MTU probe.
-  const size_t new_mtu = kDefaultMaxPacketSize + 100;
-  QuicByteCount mtu_probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&mtu_probe_size));
-  connection_.SendMtuDiscoveryPacket(new_mtu);
-  EXPECT_EQ(new_mtu, mtu_probe_size);
-  EXPECT_EQ(QuicPacketNumber(1u), creator_->packet_number());
-
-  // Send more than MTU worth of data.  No acknowledgement was received so far,
-  // so the MTU should be at its old value.
-  const std::string data(kDefaultMaxPacketSize + 1, '.');
-  QuicByteCount size_before_mtu_change;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(2)
-      .WillOnce(SaveArg<3>(&size_before_mtu_change))
-      .WillOnce(Return());
-  connection_.SendStreamDataWithString(3, data, 0, FIN);
-  EXPECT_EQ(QuicPacketNumber(3u), creator_->packet_number());
-  EXPECT_EQ(kDefaultMaxPacketSize, size_before_mtu_change);
-
-  // Acknowledge all packets so far.
-  QuicAckFrame probe_ack = InitAckFrame(3);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&probe_ack);
-  EXPECT_EQ(new_mtu, connection_.max_packet_length());
-
-  // Send the same data again.  Check that it fits into a single packet now.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(3, data, 0, FIN);
-  EXPECT_EQ(QuicPacketNumber(4u), creator_->packet_number());
-}
-
-// Verifies that when a MTU probe packet is sent and buffered in a batch writer,
-// the writer is flushed immediately.
-TEST_P(QuicConnectionTest, BatchWriterFlushedAfterMtuDiscoveryPacket) {
-  writer_->SetBatchMode(true);
-  MtuDiscoveryTestInit();
-
-  // Send an MTU probe.
-  const size_t target_mtu = kDefaultMaxPacketSize + 100;
-  QuicByteCount mtu_probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&mtu_probe_size));
-  const uint32_t prior_flush_attempts = writer_->flush_attempts();
-  connection_.SendMtuDiscoveryPacket(target_mtu);
-  EXPECT_EQ(target_mtu, mtu_probe_size);
-  EXPECT_EQ(writer_->flush_attempts(), prior_flush_attempts + 1);
-}
-
-// Tests whether MTU discovery does not happen when it is not explicitly enabled
-// by the connection options.
-TEST_P(QuicConnectionTest, MtuDiscoveryDisabled) {
-  MtuDiscoveryTestInit();
-
-  const QuicPacketCount packets_between_probes_base = 10;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  const QuicPacketCount number_of_packets = packets_between_probes_base * 2;
-  for (QuicPacketCount i = 0; i < number_of_packets; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-    EXPECT_EQ(0u, connection_.mtu_probe_count());
-  }
-}
-
-// Tests whether MTU discovery works when all probes are acknowledged on the
-// first try.
-TEST_P(QuicConnectionTest, MtuDiscoveryEnabled) {
-  MtuDiscoveryTestInit();
-
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  // Send enough packets so that the next one triggers path MTU discovery.
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the probe.
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  QuicByteCount probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&probe_size));
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-
-  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
-                                  kMtuDiscoveryTargetPacketSizeHigh));
-
-  const QuicPacketNumber probe_packet_number =
-      FirstSendingPacketNumber() + packets_between_probes_base;
-  ASSERT_EQ(probe_packet_number, creator_->packet_number());
-
-  // Acknowledge all packets sent so far.
-  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-  ProcessAckPacket(&probe_ack);
-  EXPECT_EQ(probe_size, connection_.max_packet_length());
-  EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
-  EXPECT_EQ(1u, connection_.mtu_probe_count());
-
-  QuicStreamOffset stream_offset = packets_between_probes_base;
-  QuicByteCount last_probe_size = 0;
-  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
-       ++num_probes) {
-    // Send just enough packets without triggering the next probe.
-    for (QuicPacketCount i = 0;
-         i < (packets_between_probes_base << num_probes) - 1; ++i) {
-      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
-      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-    }
-
-    // Trigger the next probe.
-    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
-    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-    QuicByteCount new_probe_size;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .WillOnce(SaveArg<3>(&new_probe_size));
-    connection_.GetMtuDiscoveryAlarm()->Fire();
-    EXPECT_THAT(new_probe_size,
-                InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
-    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
-
-    // Acknowledge all packets sent so far.
-    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
-    ProcessAckPacket(&probe_ack);
-    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
-    EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
-    last_probe_size = probe_size;
-    probe_size = new_probe_size;
-  }
-
-  // The last probe size should be equal to the target.
-  EXPECT_EQ(probe_size, kMtuDiscoveryTargetPacketSizeHigh);
-
-  writer_->SetShouldWriteFail();
-
-  // Ignore PACKET_WRITE_ERROR once.
-  SendStreamDataToPeer(3, "(", stream_offset++, NO_FIN, nullptr);
-  EXPECT_EQ(last_probe_size, connection_.max_packet_length());
-  EXPECT_TRUE(connection_.connected());
-
-  // Close connection on another PACKET_WRITE_ERROR.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  SendStreamDataToPeer(3, ")", stream_offset++, NO_FIN, nullptr);
-  EXPECT_EQ(last_probe_size, connection_.max_packet_length());
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-// After a successful MTU probe, one and only one write error should be ignored
-// if it happened in QuicConnection::FlushPacket.
-TEST_P(QuicConnectionTest,
-       MtuDiscoveryIgnoreOneWriteErrorInFlushAfterSuccessfulProbes) {
-  MtuDiscoveryTestInit();
-  writer_->SetBatchMode(true);
-
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  const QuicByteCount original_max_packet_length =
-      connection_.max_packet_length();
-  // Send enough packets so that the next one triggers path MTU discovery.
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the probe.
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  QuicByteCount probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&probe_size));
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-
-  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
-                                  kMtuDiscoveryTargetPacketSizeHigh));
-
-  const QuicPacketNumber probe_packet_number =
-      FirstSendingPacketNumber() + packets_between_probes_base;
-  ASSERT_EQ(probe_packet_number, creator_->packet_number());
-
-  // Acknowledge all packets sent so far.
-  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-  ProcessAckPacket(&probe_ack);
-  EXPECT_EQ(probe_size, connection_.max_packet_length());
-  EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
-  EXPECT_EQ(1u, connection_.mtu_probe_count());
-
-  writer_->SetShouldWriteFail();
-
-  // Ignore PACKET_WRITE_ERROR once.
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // flusher's destructor will call connection_.FlushPackets, which should
-    // get a WRITE_STATUS_ERROR from the writer and ignore it.
-  }
-  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
-  EXPECT_TRUE(connection_.connected());
-
-  // Close connection on another PACKET_WRITE_ERROR.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // flusher's destructor will call connection_.FlushPackets, which should
-    // get a WRITE_STATUS_ERROR from the writer and ignore it.
-  }
-  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PACKET_WRITE_ERROR));
-}
-
-// Simulate the case where the first attempt to send a probe is write blocked,
-// and after unblock, the second attempt returns a MSG_TOO_BIG error.
-TEST_P(QuicConnectionTest, MtuDiscoveryWriteBlocked) {
-  MtuDiscoveryTestInit();
-
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  // Send enough packets so that the next one triggers path MTU discovery.
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  QuicByteCount original_max_packet_length = connection_.max_packet_length();
-
-  // Trigger the probe.
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  BlockOnNextWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-  EXPECT_EQ(1u, connection_.mtu_probe_count());
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-  ASSERT_TRUE(connection_.connected());
-
-  writer_->SetWritable();
-  SimulateNextPacketTooLarge();
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
-  EXPECT_TRUE(connection_.connected());
-}
-
-// Tests whether MTU discovery works correctly when the probes never get
-// acknowledged.
-TEST_P(QuicConnectionTest, MtuDiscoveryFailed) {
-  MtuDiscoveryTestInit();
-
-  // Lower the number of probes between packets in order to make the test go
-  // much faster.
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
-
-  EXPECT_EQ(packets_between_probes_base,
-            QuicConnectionPeer::GetPacketsBetweenMtuProbes(&connection_));
-
-  // This tests sends more packets than strictly necessary to make sure that if
-  // the connection was to send more discovery packets than needed, those would
-  // get caught as well.
-  const QuicPacketCount number_of_packets =
-      packets_between_probes_base * (1 << (kMtuDiscoveryAttempts + 1));
-  std::vector<QuicPacketNumber> mtu_discovery_packets;
-  // Called on many acks.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-  for (QuicPacketCount i = 0; i < number_of_packets; i++) {
-    SendStreamDataToPeer(3, "!", i, NO_FIN, nullptr);
-    clock_.AdvanceTime(rtt);
-
-    // Receive an ACK, which marks all data packets as received, and all MTU
-    // discovery packets as missing.
-
-    QuicAckFrame ack;
-
-    if (!mtu_discovery_packets.empty()) {
-      QuicPacketNumber min_packet = *min_element(mtu_discovery_packets.begin(),
-                                                 mtu_discovery_packets.end());
-      QuicPacketNumber max_packet = *max_element(mtu_discovery_packets.begin(),
-                                                 mtu_discovery_packets.end());
-      ack.packets.AddRange(QuicPacketNumber(1), min_packet);
-      ack.packets.AddRange(QuicPacketNumber(max_packet + 1),
-                           creator_->packet_number() + 1);
-      ack.largest_acked = creator_->packet_number();
-
-    } else {
-      ack.packets.AddRange(QuicPacketNumber(1), creator_->packet_number() + 1);
-      ack.largest_acked = creator_->packet_number();
-    }
-
-    ProcessAckPacket(&ack);
-
-    // Trigger MTU probe if it would be scheduled now.
-    if (!connection_.GetMtuDiscoveryAlarm()->IsSet()) {
-      continue;
-    }
-
-    // Fire the alarm.  The alarm should cause a packet to be sent.
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    connection_.GetMtuDiscoveryAlarm()->Fire();
-    // Record the packet number of the MTU discovery packet in order to
-    // mark it as NACK'd.
-    mtu_discovery_packets.push_back(creator_->packet_number());
-  }
-
-  // Ensure the number of packets between probes grows exponentially by checking
-  // it against the closed-form expression for the packet number.
-  ASSERT_EQ(kMtuDiscoveryAttempts, mtu_discovery_packets.size());
-  for (uint64_t i = 0; i < kMtuDiscoveryAttempts; i++) {
-    // 2^0 + 2^1 + 2^2 + ... + 2^n = 2^(n + 1) - 1
-    const QuicPacketCount packets_between_probes =
-        packets_between_probes_base * ((1 << (i + 1)) - 1);
-    EXPECT_EQ(QuicPacketNumber(packets_between_probes + (i + 1)),
-              mtu_discovery_packets[i]);
-  }
-
-  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
-  EXPECT_EQ(kMtuDiscoveryAttempts, connection_.mtu_probe_count());
-}
-
-// Probe 3 times, the first one succeeds, then fails, then succeeds again.
-TEST_P(QuicConnectionTest, MtuDiscoverySecondProbeFailed) {
-  MtuDiscoveryTestInit();
-
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  // Send enough packets so that the next one triggers path MTU discovery.
-  QuicStreamOffset stream_offset = 0;
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the probe.
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  QuicByteCount probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&probe_size));
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
-                                  kMtuDiscoveryTargetPacketSizeHigh));
-
-  const QuicPacketNumber probe_packet_number =
-      FirstSendingPacketNumber() + packets_between_probes_base;
-  ASSERT_EQ(probe_packet_number, creator_->packet_number());
-
-  // Acknowledge all packets sent so far.
-  QuicAckFrame first_ack = InitAckFrame(probe_packet_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-  ProcessAckPacket(&first_ack);
-  EXPECT_EQ(probe_size, connection_.max_packet_length());
-  EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
-  EXPECT_EQ(1u, connection_.mtu_probe_count());
-
-  // Send just enough packets without triggering the second probe.
-  for (QuicPacketCount i = 0; i < (packets_between_probes_base << 1) - 1; ++i) {
-    SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the second probe.
-  SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  QuicByteCount second_probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&second_probe_size));
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-  EXPECT_THAT(second_probe_size,
-              InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
-  EXPECT_EQ(2u, connection_.mtu_probe_count());
-
-  // Acknowledge all packets sent so far, except the second probe.
-  QuicPacketNumber second_probe_packet_number = creator_->packet_number();
-  QuicAckFrame second_ack = InitAckFrame(second_probe_packet_number - 1);
-  ProcessAckPacket(&first_ack);
-  EXPECT_EQ(probe_size, connection_.max_packet_length());
-
-  // Send just enough packets without triggering the third probe.
-  for (QuicPacketCount i = 0; i < (packets_between_probes_base << 2) - 1; ++i) {
-    SendStreamDataToPeer(3, "@", stream_offset++, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the third probe.
-  SendStreamDataToPeer(3, "#", stream_offset++, NO_FIN, nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  QuicByteCount third_probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&third_probe_size));
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-  EXPECT_THAT(third_probe_size, InRange(probe_size, second_probe_size));
-  EXPECT_EQ(3u, connection_.mtu_probe_count());
-
-  // Acknowledge all packets sent so far, except the second probe.
-  QuicAckFrame third_ack =
-      ConstructAckFrame(creator_->packet_number(), second_probe_packet_number);
-  ProcessAckPacket(&third_ack);
-  EXPECT_EQ(third_probe_size, connection_.max_packet_length());
-
-  SendStreamDataToPeer(3, "$", stream_offset++, NO_FIN, nullptr);
-  EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
-
-  if (connection_.PathDegradingDetectionInProgress() &&
-      QuicConnectionPeer::GetPathDegradingDeadline(&connection_) <
-          QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
-              &connection_)) {
-    // Fire path degrading alarm first.
-    connection_.PathDegradingTimeout();
-  }
-
-  // Verify the max packet size has not reduced.
-  EXPECT_EQ(third_probe_size, connection_.max_packet_length());
-
-  // Fire alarm to get path mtu reduction callback called.
-  EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
-  connection_.GetBlackholeDetectorAlarm()->Fire();
-
-  // Verify the max packet size has reduced to the previous value.
-  EXPECT_EQ(probe_size, connection_.max_packet_length());
-}
-
-// Tests whether MTU discovery works when the writer has a limit on how large a
-// packet can be.
-TEST_P(QuicConnectionTest, MtuDiscoveryWriterLimited) {
-  MtuDiscoveryTestInit();
-
-  const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
-  writer_->set_max_packet_size(mtu_limit);
-
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  // Send enough packets so that the next one triggers path MTU discovery.
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the probe.
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  QuicByteCount probe_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(SaveArg<3>(&probe_size));
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-
-  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(), mtu_limit));
-
-  const QuicPacketNumber probe_sequence_number =
-      FirstSendingPacketNumber() + packets_between_probes_base;
-  ASSERT_EQ(probe_sequence_number, creator_->packet_number());
-
-  // Acknowledge all packets sent so far.
-  QuicAckFrame probe_ack = InitAckFrame(probe_sequence_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-  ProcessAckPacket(&probe_ack);
-  EXPECT_EQ(probe_size, connection_.max_packet_length());
-  EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
-  EXPECT_EQ(1u, connection_.mtu_probe_count());
-
-  QuicStreamOffset stream_offset = packets_between_probes_base;
-  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
-       ++num_probes) {
-    // Send just enough packets without triggering the next probe.
-    for (QuicPacketCount i = 0;
-         i < (packets_between_probes_base << num_probes) - 1; ++i) {
-      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
-      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-    }
-
-    // Trigger the next probe.
-    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
-    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-    QuicByteCount new_probe_size;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .WillOnce(SaveArg<3>(&new_probe_size));
-    connection_.GetMtuDiscoveryAlarm()->Fire();
-    EXPECT_THAT(new_probe_size, InRange(probe_size, mtu_limit));
-    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
-
-    // Acknowledge all packets sent so far.
-    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
-    ProcessAckPacket(&probe_ack);
-    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
-    EXPECT_EQ(0u, connection_.GetBytesInFlight());
-
-    probe_size = new_probe_size;
-  }
-
-  // The last probe size should be equal to the target.
-  EXPECT_EQ(probe_size, mtu_limit);
-}
-
-// Tests whether MTU discovery works when the writer returns an error despite
-// advertising higher packet length.
-TEST_P(QuicConnectionTest, MtuDiscoveryWriterFailed) {
-  MtuDiscoveryTestInit();
-
-  const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
-  const QuicByteCount initial_mtu = connection_.max_packet_length();
-  EXPECT_LT(initial_mtu, mtu_limit);
-  writer_->set_max_packet_size(mtu_limit);
-
-  const QuicPacketCount packets_between_probes_base = 5;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  // Send enough packets so that the next one triggers path MTU discovery.
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Trigger the probe.
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  writer_->SimulateNextPacketTooLarge();
-  connection_.GetMtuDiscoveryAlarm()->Fire();
-  ASSERT_TRUE(connection_.connected());
-
-  // Send more data.
-  QuicPacketNumber probe_number = creator_->packet_number();
-  QuicPacketCount extra_packets = packets_between_probes_base * 3;
-  for (QuicPacketCount i = 0; i < extra_packets; i++) {
-    connection_.EnsureWritableAndSendStreamData5();
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  // Acknowledge all packets sent so far, except for the lost probe.
-  QuicAckFrame probe_ack =
-      ConstructAckFrame(creator_->packet_number(), probe_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&probe_ack);
-  EXPECT_EQ(initial_mtu, connection_.max_packet_length());
-
-  // Send more packets, and ensure that none of them sets the alarm.
-  for (QuicPacketCount i = 0; i < 4 * packets_between_probes_base; i++) {
-    connection_.EnsureWritableAndSendStreamData5();
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  EXPECT_EQ(initial_mtu, connection_.max_packet_length());
-  EXPECT_EQ(1u, connection_.mtu_probe_count());
-}
-
-TEST_P(QuicConnectionTest, NoMtuDiscoveryAfterConnectionClosed) {
-  MtuDiscoveryTestInit();
-
-  const QuicPacketCount packets_between_probes_base = 10;
-  set_packets_between_probes_base(packets_between_probes_base);
-
-  connection_.EnablePathMtuDiscovery(send_algorithm_);
-
-  // Send enough packets so that the next one triggers path MTU discovery.
-  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
-    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
-    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-  }
-
-  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
-                       nullptr);
-  EXPECT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
-                              ConnectionCloseBehavior::SILENT_CLOSE);
-  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterSendDuringHandshake) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-
-  const QuicTime::Delta initial_idle_timeout =
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
-
-  // When we send a packet, the timeout will change to 5ms +
-  // kInitialIdleTimeoutSecs.
-  clock_.AdvanceTime(five_ms);
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // Now send more data. This will not move the timeout because
-  // no data has been received since the previous write.
-  clock_.AdvanceTime(five_ms);
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      3, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // The original alarm will fire.  We should not time out because we had a
-  // network event at t=5ms.  The alarm will reregister.
-  clock_.AdvanceTime(initial_idle_timeout - five_ms - five_ms);
-  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // This time, we should time out.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  clock_.AdvanceTime(five_ms);
-  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterRetransmission) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-
-  const QuicTime start_time = clock_.Now();
-  const QuicTime::Delta initial_idle_timeout =
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  QuicTime default_timeout = clock_.Now() + initial_idle_timeout;
-
-  connection_.SetMaxTailLossProbes(0);
-  const QuicTime default_retransmission_time =
-      start_time + DefaultRetransmissionTime();
-
-  ASSERT_LT(default_retransmission_time, default_timeout);
-
-  // When we send a packet, the timeout will change to 5 ms +
-  // kInitialIdleTimeoutSecs (but it will not reschedule the alarm).
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  const QuicTime send_time = start_time + five_ms;
-  clock_.AdvanceTime(five_ms);
-  ASSERT_EQ(send_time, clock_.Now());
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // Move forward 5 ms and receive a packet, which will move the timeout
-  // forward 5 ms more (but will not reschedule the alarm).
-  const QuicTime receive_time = send_time + five_ms;
-  clock_.AdvanceTime(receive_time - clock_.Now());
-  ASSERT_EQ(receive_time, clock_.Now());
-  ProcessPacket(1);
-
-  // Now move forward to the retransmission time and retransmit the
-  // packet, which should move the timeout forward again (but will not
-  // reschedule the alarm).
-  EXPECT_EQ(default_retransmission_time + five_ms,
-            connection_.GetRetransmissionAlarm()->deadline());
-  // Simulate the retransmission alarm firing.
-  const QuicTime rto_time = send_time + DefaultRetransmissionTime();
-  const QuicTime final_timeout = rto_time + initial_idle_timeout;
-  clock_.AdvanceTime(rto_time - clock_.Now());
-  ASSERT_EQ(rto_time, clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  // Advance to the original timeout and fire the alarm. The connection should
-  // timeout, and the alarm should be registered based on the time of the
-  // retransmission.
-  clock_.AdvanceTime(default_timeout - clock_.Now());
-  ASSERT_EQ(default_timeout.ToDebuggingValue(),
-            clock_.Now().ToDebuggingValue());
-  EXPECT_EQ(default_timeout, clock_.Now());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_TRUE(connection_.connected());
-  ASSERT_EQ(final_timeout.ToDebuggingValue(),
-            connection_.GetTimeoutAlarm()->deadline().ToDebuggingValue());
-
-  // This time, we should time out.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  clock_.AdvanceTime(final_timeout - clock_.Now());
-  EXPECT_EQ(connection_.GetTimeoutAlarm()->deadline(), clock_.Now());
-  EXPECT_EQ(final_timeout, clock_.Now());
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
-  // When the idle timeout fires, verify that by default we do not send any
-  // connection close packets.
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-
-  // Create a handshake message that also enables silent close.
-  CryptoHandshakeMessage msg;
-  std::string error_details;
-  QuicConfig client_config;
-  client_config.SetInitialStreamFlowControlWindowToSend(
-      kInitialStreamFlowControlWindowForTest);
-  client_config.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest);
-  client_config.SetIdleNetworkTimeout(
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
-  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
-  const QuicErrorCode error =
-      config.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  connection_.SetFromConfig(config);
-
-  const QuicTime::Delta default_idle_timeout =
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
-
-  // When we send a packet, the timeout will change to 5ms +
-  // kInitialIdleTimeoutSecs.
-  clock_.AdvanceTime(five_ms);
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // Now send more data. This will not move the timeout because
-  // no data has been received since the previous write.
-  clock_.AdvanceTime(five_ms);
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      3, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // The original alarm will fire.  We should not time out because we had a
-  // network event at t=5ms.  The alarm will reregister.
-  clock_.AdvanceTime(default_idle_timeout - five_ms - five_ms);
-  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // This time, we should time out.
-  // This results in a SILENT_CLOSE, so the writer will not be invoked
-  // and will not save the frame. Grab the frame from OnConnectionClosed
-  // directly.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-
-  clock_.AdvanceTime(five_ms);
-  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_NETWORK_IDLE_TIMEOUT));
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseAndTLP) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  // Same test as above, but sending TLPs causes a connection close to be sent.
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-
-  // Create a handshake message that also enables silent close.
-  CryptoHandshakeMessage msg;
-  std::string error_details;
-  QuicConfig client_config;
-  client_config.SetInitialStreamFlowControlWindowToSend(
-      kInitialStreamFlowControlWindowForTest);
-  client_config.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest);
-  client_config.SetIdleNetworkTimeout(
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
-  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
-  const QuicErrorCode error =
-      config.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-
-  connection_.SetFromConfig(config);
-
-  const QuicTime::Delta default_idle_timeout =
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
-
-  // When we send a packet, the timeout will change to 5ms +
-  // kInitialIdleTimeoutSecs.
-  clock_.AdvanceTime(five_ms);
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // Retransmit the packet via tail loss probe.
-  clock_.AdvanceTime(connection_.GetRetransmissionAlarm()->deadline() -
-                     clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  // This time, we should time out and send a connection close due to the TLP.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
-                     clock_.ApproximateNow() + five_ms);
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
-  // Same test as above, but having open streams causes a connection close
-  // to be sent.
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-
-  // Create a handshake message that also enables silent close.
-  CryptoHandshakeMessage msg;
-  std::string error_details;
-  QuicConfig client_config;
-  client_config.SetInitialStreamFlowControlWindowToSend(
-      kInitialStreamFlowControlWindowForTest);
-  client_config.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest);
-  client_config.SetIdleNetworkTimeout(
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
-  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
-  const QuicErrorCode error =
-      config.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  connection_.SetFromConfig(config);
-
-  const QuicTime::Delta default_idle_timeout =
-      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
-
-  // When we send a packet, the timeout will change to 5ms +
-  // kInitialIdleTimeoutSecs.
-  clock_.AdvanceTime(five_ms);
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // Indicate streams are still open.
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-  if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail)) {
-    EXPECT_CALL(visitor_, GetStreamsInfoForLogging()).WillOnce(Return(""));
-  }
-
-  // This time, we should time out and send a connection close due to the TLP.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
-                     clock_.ApproximateNow() + five_ms);
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterReceive) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-
-  const QuicTime::Delta initial_idle_timeout =
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
-
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, NO_FIN);
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      3, NO_FIN);
-
-  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-  clock_.AdvanceTime(five_ms);
-
-  // When we receive a packet, the timeout will change to 5ms +
-  // kInitialIdleTimeoutSecs.
-  QuicAckFrame ack = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&ack);
-
-  // The original alarm will fire.  We should not time out because we had a
-  // network event at t=5ms.  The alarm will reregister.
-  clock_.AdvanceTime(initial_idle_timeout - five_ms);
-  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // This time, we should time out.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  clock_.AdvanceTime(five_ms);
-  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
-  connection_.GetTimeoutAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-
-  const QuicTime::Delta initial_idle_timeout =
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  connection_.SetNetworkTimeouts(
-      QuicTime::Delta::Infinite(),
-      initial_idle_timeout + QuicTime::Delta::FromSeconds(1));
-  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
-  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, NO_FIN);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      3, NO_FIN);
-
-  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
-  clock_.AdvanceTime(five_ms);
-
-  // When we receive a packet, the timeout will change to 5ms +
-  // kInitialIdleTimeoutSecs.
-  QuicAckFrame ack = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&ack);
-
-  // The original alarm will fire.  We should not time out because we had a
-  // network event at t=5ms.  The alarm will reregister.
-  clock_.AdvanceTime(initial_idle_timeout - five_ms);
-  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_EQ(default_timeout + five_ms,
-            connection_.GetTimeoutAlarm()->deadline());
-
-  // Now, send packets while advancing the time and verify that the connection
-  // eventually times out.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  for (int i = 0; i < 100 && connection_.connected(); ++i) {
-    QUIC_LOG(INFO) << "sending data packet";
-    connection_.SendStreamDataWithString(
-        GetNthClientInitiatedStreamId(1, connection_.transport_version()),
-        "foo", 0, NO_FIN);
-    connection_.GetTimeoutAlarm()->Fire();
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
-TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(2);
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k5RTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  }
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  connection_.SetFromConfig(config);
-
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-
-  // Fire the retransmission alarm 6 times, twice for TLP and 4 times for RTO.
-  for (int i = 0; i < 6; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    connection_.GetRetransmissionAlarm()->Fire();
-    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_TRUE(connection_.connected());
-  }
-  EXPECT_CALL(visitor_, OnPathDegrading());
-  connection_.PathDegradingTimeout();
-
-  EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
-  EXPECT_EQ(4u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
-  // This time, we should time out.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-  connection_.GetBlackholeDetectorAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
-}
-
-TEST_P(QuicConnectionTest, SendScheduler) {
-  // Test that if we send a packet without delay, it is not queued.
-  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> packet =
-      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
-  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
-                         HAS_RETRANSMITTABLE_DATA, false, false);
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
-  // Test that the connection does not crash when it fails to send the first
-  // packet at which point self_address_ might be uninitialized.
-  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
-  std::unique_ptr<QuicPacket> packet =
-      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
-  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
-  writer_->SetShouldWriteFail();
-  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
-                         HAS_RETRANSMITTABLE_DATA, false, false);
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
-  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> packet =
-      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
-  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
-  BlockOnNextWrite();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _))
-      .Times(0);
-  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
-                         HAS_RETRANSMITTABLE_DATA, false, false);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
-  // Queue the first packet.
-  size_t payload_length = connection_.max_packet_length();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(testing::Return(false));
-  const std::string payload(payload_length, 'a');
-  QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
-      connection_.version().transport_version, Perspective::IS_CLIENT));
-  EXPECT_EQ(0u, connection_
-                    .SendStreamDataWithString(first_bidi_stream_id, payload, 0,
-                                              NO_FIN)
-                    .bytes_consumed);
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, SendingThreePackets) {
-  // Make the payload twice the size of the packet, so 3 packets are written.
-  size_t total_payload_length = 2 * connection_.max_packet_length();
-  const std::string payload(total_payload_length, 'a');
-  QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
-      connection_.version().transport_version, Perspective::IS_CLIENT));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
-  EXPECT_EQ(payload.size(), connection_
-                                .SendStreamDataWithString(first_bidi_stream_id,
-                                                          payload, 0, NO_FIN)
-                                .bytes_consumed);
-}
-
-TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!GetParam().version.HasIetfInvariantHeader()) {
-    // For IETF QUIC, encryption level will be switched to FORWARD_SECURE in
-    // SendStreamDataWithString.
-    QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  }
-  // Set up a larger payload than will fit in one packet.
-  const std::string payload(connection_.max_packet_length(), 'a');
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
-
-  // Now send some packets with no truncation.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  EXPECT_EQ(payload.size(),
-            connection_.SendStreamDataWithString(3, payload, 0, NO_FIN)
-                .bytes_consumed);
-  // Track the size of the second packet here.  The overhead will be the largest
-  // we see in this test, due to the non-truncated connection id.
-  size_t non_truncated_packet_size = writer_->last_packet_size();
-
-  // Change to a 0 byte connection id.
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
-  connection_.SetFromConfig(config);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  EXPECT_EQ(payload.size(),
-            connection_.SendStreamDataWithString(3, payload, 1350, NO_FIN)
-                .bytes_consumed);
-  if (connection_.version().HasIetfInvariantHeader()) {
-    // Short header packets sent from server omit connection ID already, and
-    // stream offset size increases from 0 to 2.
-    EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() - 2);
-  } else {
-    // Just like above, we save 8 bytes on payload, and 8 on truncation. -2
-    // because stream offset size is 2 instead of 0.
-    EXPECT_EQ(non_truncated_packet_size,
-              writer_->last_packet_size() + 8 * 2 - 2);
-  }
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAck) {
-  QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(tag));
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(tag));
-  // Process a packet from the non-crypto stream.
-  frame1_.stream_id = 3;
-
-  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
-  // instead of ENCRYPTION_INITIAL.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  // Check if delayed ack timer is running for the expected interval.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-  // Simulate delayed ack alarm firing.
-  clock_.AdvanceTime(DefaultDelayedAckTime());
-  connection_.GetAckAlarm()->Fire();
-  // Check that ack is sent and that delayed ack alarm is reset.
-  size_t padding_frame_count = writer_->padding_frames().size();
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
-
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  // The ack time should be based on min_rtt/4, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() +
-                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(tag));
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(tag));
-  // Process a packet from the non-crypto stream.
-  frame1_.stream_id = 3;
-
-  // Process all the initial packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  }
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
-  // instead of ENCRYPTION_INITIAL.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
-                           ENCRYPTION_ZERO_RTT);
-
-  // Check if delayed ack timer is running for the expected interval.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
-  // The 10th received packet causes an ack to be sent.
-  for (int i = 0; i < 9; ++i) {
-    EXPECT_TRUE(connection_.HasPendingAcks());
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_ZERO_RTT);
-  }
-  // Check that ack is sent and that delayed ack alarm is reset.
-  size_t padding_frame_count = writer_->padding_frames().size();
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  QuicTagVector connection_options;
-  // No limit on the number of packets received before sending an ack.
-  connection_options.push_back(kAKDU);
-  config.SetConnectionOptionsToSend(connection_options);
-  connection_.SetFromConfig(config);
-
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  // The ack time should be based on min_rtt/4, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() +
-                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(tag));
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(tag));
-  // Process a packet from the non-crypto stream.
-  frame1_.stream_id = 3;
-
-  // Process all the initial packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  }
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
-  // instead of ENCRYPTION_INITIAL.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
-                           ENCRYPTION_ZERO_RTT);
-
-  // Check if delayed ack timer is running for the expected interval.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
-  // 18 packets will not cause an ack to be sent.  19 will because when
-  // stop waiting frames are in use, we ack every 20 packets no matter what.
-  for (int i = 0; i < 18; ++i) {
-    EXPECT_TRUE(connection_.HasPendingAcks());
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_ZERO_RTT);
-  }
-  // The delayed ack timer should still be set to the expected deadline.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
-  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
-  QuicConnectionPeer::SetAckDecimationDelay(&connection_, 0.125);
-
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  // The ack time should be based on min_rtt/8, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() +
-                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  const uint8_t tag = 0x07;
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(tag));
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(tag));
-  // Process a packet from the non-crypto stream.
-  frame1_.stream_id = 3;
-
-  // Process all the initial packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  }
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
-  // instead of ENCRYPTION_INITIAL.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
-                           ENCRYPTION_ZERO_RTT);
-
-  // Check if delayed ack timer is running for the expected interval.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
-  // The 10th received packet causes an ack to be sent.
-  for (int i = 0; i < 9; ++i) {
-    EXPECT_TRUE(connection_.HasPendingAcks());
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_ZERO_RTT);
-  }
-  // Check that ack is sent and that delayed ack alarm is reset.
-  size_t padding_frame_count = writer_->padding_frames().size();
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(1);
-  // Check that ack is sent and that delayed ack alarm is set.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
-  // Completing the handshake as the server does nothing.
-  QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_SERVER);
-  connection_.OnHandshakeComplete();
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
-
-  // Complete the handshake as the client decreases the delayed ack time to 0ms.
-  QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_CLIENT);
-  connection_.OnHandshakeComplete();
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
-              connection_.GetAckAlarm()->deadline());
-  } else {
-    EXPECT_EQ(clock_.ApproximateNow(), connection_.GetAckAlarm()->deadline());
-  }
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(1);
-  ProcessPacket(2);
-  // Check that ack is sent and that delayed ack alarm is reset.
-  size_t padding_frame_count = writer_->padding_frames().size();
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessPacket(2);
-  size_t frames_per_ack = GetParam().no_stop_waiting ? 1 : 2;
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessPacket(3);
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  writer_->Reset();
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessPacket(4);
-  EXPECT_EQ(0u, writer_->frame_count());
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessPacket(5);
-  padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  writer_->Reset();
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  // Now only set the timer on the 6th packet, instead of sending another ack.
-  ProcessPacket(6);
-  padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count, writer_->frame_count());
-  EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_));
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  ProcessDataPacket(1);
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, NO_FIN);
-  // Check that ack is bundled with outgoing data and that delayed ack
-  // alarm is reset.
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(2u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  }
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  connection_.SendCryptoDataWithString("foo", 0);
-  // Check that ack is bundled with outgoing crypto data.
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(4u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(1);
-  BlockOnNextWrite();
-  writer_->set_is_write_blocked_data_buffered(true);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  } else {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  }
-  connection_.SendCryptoDataWithString("foo", 0);
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-  EXPECT_FALSE(connection_.HasQueuedData());
-  connection_.SendCryptoDataWithString("bar", 3);
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    // CRYPTO frames are not flushed when writer is blocked.
-    EXPECT_FALSE(connection_.HasQueuedData());
-  } else {
-    EXPECT_TRUE(connection_.HasQueuedData());
-  }
-}
-
-TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  EXPECT_CALL(visitor_, OnCanWrite())
-      .WillOnce(IgnoreResult(InvokeWithoutArgs(
-          &connection_, &TestConnection::SendCryptoStreamData)));
-  // Process a packet from the crypto stream, which is frame1_'s default.
-  // Receiving the CHLO as packet 2 first will cause the connection to
-  // immediately send an ack, due to the packet gap.
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  }
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  // Check that ack is sent and that delayed ack alarm is reset.
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(4u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_EQ(1u, writer_->stream_frames().size());
-  } else {
-    EXPECT_EQ(1u, writer_->crypto_frames().size());
-  }
-  EXPECT_EQ(1u, writer_->padding_frames().size());
-  ASSERT_FALSE(writer_->ack_frames().empty());
-  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-
-  // Process two packets from the crypto stream, which is frame1_'s default,
-  // simulating a 2 packet reject.
-  {
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-    } else {
-      EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    }
-    ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-    // Send the new CHLO when the REJ is processed.
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      EXPECT_CALL(visitor_, OnCryptoFrame(_))
-          .WillOnce(IgnoreResult(InvokeWithoutArgs(
-              &connection_, &TestConnection::SendCryptoStreamData)));
-    } else {
-      EXPECT_CALL(visitor_, OnStreamFrame(_))
-          .WillOnce(IgnoreResult(InvokeWithoutArgs(
-              &connection_, &TestConnection::SendCryptoStreamData)));
-    }
-    ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  }
-  // Check that ack is sent and that delayed ack alarm is reset.
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(4u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_EQ(1u, writer_->stream_frames().size());
-  } else {
-    EXPECT_EQ(1u, writer_->crypto_frames().size());
-  }
-  EXPECT_EQ(1u, writer_->padding_frames().size());
-  ASSERT_FALSE(writer_->ack_frames().empty());
-  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, NO_FIN);
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      3, NO_FIN);
-  // Ack the second packet, which will retransmit the first packet.
-  QuicAckFrame ack = ConstructAckFrame(2, 1);
-  LostPacketVector lost_packets;
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&ack);
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  writer_->Reset();
-
-  // Now ack the retransmission, which will both raise the high water mark
-  // and see if there is more data to send.
-  ack = ConstructAckFrame(3, 1);
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(&ack);
-
-  // Check that no packet is sent and the ack alarm isn't set.
-  EXPECT_EQ(0u, writer_->frame_count());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  writer_->Reset();
-
-  // Send the same ack, but send both data and an ack together.
-  ack = ConstructAckFrame(3, 1);
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(visitor_, OnCanWrite())
-      .WillOnce(IgnoreResult(InvokeWithoutArgs(
-          &connection_, &TestConnection::EnsureWritableAndSendStreamData5)));
-  ProcessAckPacket(&ack);
-
-  // Check that ack is bundled with outgoing data and the delayed ack
-  // alarm is reset.
-  if (GetParam().no_stop_waiting) {
-    // Do not ACK acks.
-    EXPECT_EQ(1u, writer_->frame_count());
-  } else {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  }
-  if (GetParam().no_stop_waiting) {
-    EXPECT_TRUE(writer_->ack_frames().empty());
-  } else {
-    EXPECT_FALSE(writer_->ack_frames().empty());
-    EXPECT_EQ(QuicPacketNumber(3u),
-              LargestAcked(writer_->ack_frames().front()));
-  }
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, NoAckSentForClose) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(1);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessClosePacket(2);
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, SendWhenDisconnected) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
-                              ConnectionCloseBehavior::SILENT_CLOSE);
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
-  EXPECT_EQ(DISCARD, connection_.GetSerializedPacketFate(
-                         /*is_mtu_discovery=*/false, ENCRYPTION_INITIAL));
-}
-
-TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration()) {
-    return;
-  }
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
-                              ConnectionCloseBehavior::SILENT_CLOSE);
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
-      .Times(0);
-
-  EXPECT_QUIC_BUG(connection_.SendConnectivityProbingPacket(
-                      writer_.get(), connection_.peer_address()),
-                  "Not sending connectivity probing packet as connection is "
-                  "disconnected.");
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
-  // Block next write so that sending connectivity probe will encounter a
-  // blocked write when send a connectivity probe to the peer.
-  probing_writer.BlockOnNextWrite();
-  // Connection will not be marked as write blocked as connectivity probe only
-  // affects the probing_writer which is not the default.
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
-      .Times(1);
-  connection_.SendConnectivityProbingPacket(&probing_writer,
-                                            connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-
-  // Block next write so that sending connectivity probe will encounter a
-  // blocked write when send a connectivity probe to the peer.
-  writer_->BlockOnNextWrite();
-  // Connection will be marked as write blocked as server uses the default
-  // writer to send connectivity probes.
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
-      .Times(1);
-  if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
-    QuicPathFrameBuffer payload{
-        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendPathChallenge(
-        payload, connection_.self_address(), connection_.peer_address(),
-        connection_.effective_peer_address(), writer_.get());
-  } else {
-    connection_.SendConnectivityProbingPacket(writer_.get(),
-                                              connection_.peer_address());
-  }
-}
-
-TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
-  probing_writer.SetShouldWriteFail();
-
-  // Connection should not be closed if a connectivity probe is failed to be
-  // sent.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
-      .Times(0);
-  connection_.SendConnectivityProbingPacket(&probing_writer,
-                                            connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, WriterErrorWhenServerSendsConnectivityProbe) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  writer_->SetShouldWriteFail();
-  // Connection should not be closed if a connectivity probe is failed to be
-  // sent.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
-      .Times(0);
-  connection_.SendConnectivityProbingPacket(writer_.get(),
-                                            connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, PublicReset) {
-  if (GetParam().version.HasIetfInvariantHeader()) {
-    return;
-  }
-  QuicPublicResetPacket header;
-  // Public reset packet in only built by server.
-  header.connection_id = connection_id_;
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      framer_.BuildPublicResetPacket(header));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*packet, QuicTime::Zero()));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PUBLIC_RESET));
-}
-
-TEST_P(QuicConnectionTest, IetfStatelessReset) {
-  if (!GetParam().version.HasIetfInvariantHeader()) {
-    return;
-  }
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
-                                                 kTestStatelessResetToken);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
-                                                /*received_packet_length=*/100,
-                                                kTestStatelessResetToken));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*packet, QuicTime::Zero()));
-  if (!connection_.use_path_validator()) {
-    EXPECT_CALL(visitor_, ValidateStatelessReset(_, _)).WillOnce(Return(true));
-  }
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PUBLIC_RESET));
-}
-
-TEST_P(QuicConnectionTest, GoAway) {
-  if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
-    // GoAway is not available in version 99.
-    return;
-  }
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  QuicGoAwayFrame* goaway = new QuicGoAwayFrame();
-  goaway->last_good_stream_id = 1;
-  goaway->error_code = QUIC_PEER_GOING_AWAY;
-  goaway->reason_phrase = "Going away.";
-  EXPECT_CALL(visitor_, OnGoAway(_));
-  ProcessGoAwayPacket(goaway);
-}
-
-TEST_P(QuicConnectionTest, WindowUpdate) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  QuicWindowUpdateFrame window_update;
-  window_update.stream_id = 3;
-  window_update.max_data = 1234;
-  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
-  ProcessFramePacket(QuicFrame(window_update));
-}
-
-TEST_P(QuicConnectionTest, Blocked) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  QuicBlockedFrame blocked;
-  blocked.stream_id = 3;
-  EXPECT_CALL(visitor_, OnBlockedFrame(_));
-  ProcessFramePacket(QuicFrame(blocked));
-  EXPECT_EQ(1u, connection_.GetStats().blocked_frames_received);
-  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
-}
-
-TEST_P(QuicConnectionTest, ZeroBytePacket) {
-  // Don't close the connection for zero byte packets.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-  QuicReceivedPacket encrypted(nullptr, 0, QuicTime::Zero());
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, encrypted);
-}
-
-TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
-  if (GetParam().version.HasIetfInvariantHeader()) {
-    return;
-  }
-  // Set the packet number of the ack packet to be least unacked (4).
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 3);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessStopWaitingPacket(InitStopWaitingFrame(4));
-  EXPECT_FALSE(connection_.ack_frame().packets.Empty());
-}
-
-TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
-  // All supported versions except the one the connection supports.
-  ParsedQuicVersionVector versions;
-  for (auto version : AllSupportedVersions()) {
-    if (version != connection_.version()) {
-      versions.push_back(version);
-    }
-  }
-
-  // Send a version negotiation packet.
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, EmptyQuicConnectionId(),
-          connection_.version().HasIetfInvariantHeader(),
-          connection_.version().HasLengthPrefixedConnectionIds(), versions));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  // Verify no connection close packet gets sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_INVALID_VERSION));
-}
-
-TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiationWithConnectionClose) {
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kINVC);
-  config.SetClientConnectionOptions(connection_options);
-  connection_.SetFromConfig(config);
-
-  // All supported versions except the one the connection supports.
-  ParsedQuicVersionVector versions;
-  for (auto version : AllSupportedVersions()) {
-    if (version != connection_.version()) {
-      versions.push_back(version);
-    }
-  }
-
-  // Send a version negotiation packet.
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, EmptyQuicConnectionId(),
-          connection_.version().HasIetfInvariantHeader(),
-          connection_.version().HasLengthPrefixedConnectionIds(), versions));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  // Verify connection close packet gets sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1u));
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_INVALID_VERSION));
-}
-
-TEST_P(QuicConnectionTest, BadVersionNegotiation) {
-  // Send a version negotiation packet with the version the client started with.
-  // It should be rejected.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, EmptyQuicConnectionId(),
-          connection_.version().HasIetfInvariantHeader(),
-          connection_.version().HasLengthPrefixedConnectionIds(),
-          AllSupportedVersions()));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
-}
-
-TEST_P(QuicConnectionTest, CheckSendStats) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(0);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendStreamDataWithString(3, "first", 0, NO_FIN);
-  size_t first_packet_size = writer_->last_packet_size();
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendStreamDataWithString(5, "second", 0, NO_FIN);
-  size_t second_packet_size = writer_->last_packet_size();
-
-  // 2 retransmissions due to rto, 1 due to explicit nack.
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
-
-  // Retransmit due to RTO.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  // Retransmit due to explicit nacks.
-  QuicAckFrame nack_three =
-      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
-                    {QuicPacketNumber(4), QuicPacketNumber(5)}});
-
-  LostPacketVector lost_packets;
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(3), kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessAckPacket(&nack_three);
-
-  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-      .WillOnce(Return(QuicBandwidth::Zero()));
-
-  const QuicConnectionStats& stats = connection_.GetStats();
-  // For IETF QUIC, version is not included as the encryption level switches to
-  // FORWARD_SECURE in SendStreamDataWithString.
-  size_t save_on_version =
-      GetParam().version.HasIetfInvariantHeader() ? 0 : kQuicVersionSize;
-  EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - save_on_version,
-            stats.bytes_sent);
-  EXPECT_EQ(5u, stats.packets_sent);
-  EXPECT_EQ(2 * first_packet_size + second_packet_size - save_on_version,
-            stats.bytes_retransmitted);
-  EXPECT_EQ(3u, stats.packets_retransmitted);
-  EXPECT_EQ(1u, stats.rto_count);
-  EXPECT_EQ(kDefaultMaxPacketSize, stats.egress_mtu);
-}
-
-TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
-  // Construct a packet with stream frame and connection close frame.
-  QuicPacketHeader header;
-  if (peer_framer_.perspective() == Perspective::IS_SERVER) {
-    header.source_connection_id = connection_id_;
-    header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-    if (!peer_framer_.version().HasIetfInvariantHeader()) {
-      header.source_connection_id_included = CONNECTION_ID_PRESENT;
-    }
-  } else {
-    header.destination_connection_id = connection_id_;
-    if (peer_framer_.version().HasIetfInvariantHeader()) {
-      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
-    }
-  }
-  header.packet_number = QuicPacketNumber(1);
-  header.version_flag = false;
-
-  QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
-  // This QuicConnectionCloseFrame will default to being for a Google QUIC
-  // close. If doing IETF QUIC then set fields appropriately for CC/T or CC/A,
-  // depending on the mapping.
-  QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
-                                kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
-                                /*transport_close_frame_type=*/0);
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  frames.push_back(QuicFrame(&qccf));
-  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-  EXPECT_TRUE(nullptr != packet);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
-      kMaxOutgoingPacketSize);
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_PEER_GOING_AWAY));
-}
-
-TEST_P(QuicConnectionTest, SelectMutualVersion) {
-  connection_.SetSupportedVersions(AllSupportedVersions());
-  // Set the connection to speak the lowest quic version.
-  connection_.set_version(QuicVersionMin());
-  EXPECT_EQ(QuicVersionMin(), connection_.version());
-
-  // Pass in available versions which includes a higher mutually supported
-  // version.  The higher mutually supported version should be selected.
-  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
-  EXPECT_TRUE(connection_.SelectMutualVersion(supported_versions));
-  EXPECT_EQ(QuicVersionMax(), connection_.version());
-
-  // Expect that the lowest version is selected.
-  // Ensure the lowest supported version is less than the max, unless they're
-  // the same.
-  ParsedQuicVersionVector lowest_version_vector;
-  lowest_version_vector.push_back(QuicVersionMin());
-  EXPECT_TRUE(connection_.SelectMutualVersion(lowest_version_vector));
-  EXPECT_EQ(QuicVersionMin(), connection_.version());
-
-  // Shouldn't be able to find a mutually supported version.
-  ParsedQuicVersionVector unsupported_version;
-  unsupported_version.push_back(UnsupportedQuicVersion());
-  EXPECT_FALSE(connection_.SelectMutualVersion(unsupported_version));
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseWhenWritable) {
-  EXPECT_FALSE(writer_->IsWriteBlocked());
-
-  // Send a packet.
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  TriggerConnectionClose();
-  EXPECT_LE(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseGettingWriteBlocked) {
-  BlockOnNextWrite();
-  TriggerConnectionClose();
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_TRUE(writer_->IsWriteBlocked());
-  TriggerConnectionClose();
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, OnPacketSentDebugVisitor) {
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
-
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-  connection_.SendConnectivityProbingPacket(writer_.get(),
-                                            connection_.peer_address());
-}
-
-TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
-  QuicPacketHeader header;
-  header.packet_number = QuicPacketNumber(1);
-  if (GetParam().version.HasIetfInvariantHeader()) {
-    header.form = IETF_QUIC_LONG_HEADER_PACKET;
-  }
-
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  EXPECT_CALL(debug_visitor, OnPacketHeader(Ref(header), _, _)).Times(1);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(1);
-  EXPECT_CALL(debug_visitor, OnSuccessfulVersionNegotiation(_)).Times(1);
-  connection_.OnPacketHeader(header);
-}
-
-TEST_P(QuicConnectionTest, Pacing) {
-  TestConnection server(connection_id_, kPeerAddress, kSelfAddress,
-                        helper_.get(), alarm_factory_.get(), writer_.get(),
-                        Perspective::IS_SERVER, version());
-  TestConnection client(connection_id_, kSelfAddress, kPeerAddress,
-                        helper_.get(), alarm_factory_.get(), writer_.get(),
-                        Perspective::IS_CLIENT, version());
-  EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
-      static_cast<const QuicSentPacketManager*>(
-          &client.sent_packet_manager())));
-  EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
-      static_cast<const QuicSentPacketManager*>(
-          &server.sent_packet_manager())));
-}
-
-TEST_P(QuicConnectionTest, WindowUpdateInstigateAcks) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  // Send a WINDOW_UPDATE frame.
-  QuicWindowUpdateFrame window_update;
-  window_update.stream_id = 3;
-  window_update.max_data = 1234;
-  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
-  ProcessFramePacket(QuicFrame(window_update));
-
-  // Ensure that this has caused the ACK alarm to be set.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  // Send a BLOCKED frame.
-  QuicBlockedFrame blocked;
-  blocked.stream_id = 3;
-  EXPECT_CALL(visitor_, OnBlockedFrame(_));
-  ProcessFramePacket(QuicFrame(blocked));
-
-  // Ensure that this has caused the ACK alarm to be set.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
-  // Enable pacing.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-
-  // Send two packets.  One packet is not sufficient because if it gets acked,
-  // there will be no packets in flight after that and the pacer will always
-  // allow the next packet in that situation.
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, NO_FIN);
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "bar",
-      3, NO_FIN);
-  connection_.OnCanWrite();
-
-  // Schedule the next packet for a few milliseconds in future.
-  QuicSentPacketManagerPeer::DisablePacerBursts(manager_);
-  QuicTime scheduled_pacing_time =
-      clock_.Now() + QuicTime::Delta::FromMilliseconds(5);
-  QuicSentPacketManagerPeer::SetNextPacedPacketTime(manager_,
-                                                    scheduled_pacing_time);
-
-  // Send a packet and have it be blocked by congestion control.
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
-  connection_.SendStreamDataWithString(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "baz",
-      6, NO_FIN);
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-
-  // Process an ack and the send alarm will be set to the new 5ms delay.
-  QuicAckFrame ack = InitAckFrame(1);
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  ProcessAckPacket(&ack);
-  size_t padding_frame_count = writer_->padding_frames().size();
-  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_TRUE(connection_.GetSendAlarm()->IsSet());
-  EXPECT_EQ(scheduled_pacing_time, connection_.GetSendAlarm()->deadline());
-  writer_->Reset();
-}
-
-TEST_P(QuicConnectionTest, SendAcksImmediately) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(1);
-  CongestionBlockWrites();
-  SendAckPacketToPeer();
-}
-
-TEST_P(QuicConnectionTest, SendPingImmediately) {
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-
-  CongestionBlockWrites();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-  EXPECT_CALL(debug_visitor, OnPingSent()).Times(1);
-  connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
-  EXPECT_FALSE(connection_.HasQueuedData());
-}
-
-TEST_P(QuicConnectionTest, SendBlockedImmediately) {
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
-  connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
-  EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent);
-  EXPECT_FALSE(connection_.HasQueuedData());
-}
-
-TEST_P(QuicConnectionTest, FailedToSendBlockedFrames) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  QuicBlockedFrame blocked(1, 3);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
-  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
-  connection_.SendControlFrame(QuicFrame(blocked));
-  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
-  EXPECT_FALSE(connection_.HasQueuedData());
-}
-
-TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration()) {
-    return;
-  }
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, {}, 0, FIN),
-                  "Cannot send stream data with level: ENCRYPTION_INITIAL");
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA));
-}
-
-TEST_P(QuicConnectionTest, SetRetransmissionAlarmForCryptoPacket) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendCryptoStreamData();
-
-  // Verify retransmission timer is correctly set after crypto packet has been
-  // sent.
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  QuicTime retransmission_time =
-      QuicConnectionPeer::GetSentPacketManager(&connection_)
-          ->GetRetransmissionTime();
-  EXPECT_NE(retransmission_time, clock_.ApproximateNow());
-  EXPECT_EQ(retransmission_time,
-            connection_.GetRetransmissionAlarm()->deadline());
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.GetRetransmissionAlarm()->Fire();
-}
-
-// Includes regression test for b/69979024.
-TEST_P(QuicConnectionTest, PathDegradingDetectionForNonCryptoPackets) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_FALSE(connection_.IsPathDegrading());
-
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-
-  for (int i = 0; i < 2; ++i) {
-    // Send a packet. Now there's a retransmittable packet on the wire, so the
-    // path degrading detection should be set.
-    connection_.SendStreamDataWithString(
-        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
-        offset, NO_FIN);
-    offset += data_size;
-    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-    // Check the deadline of the path degrading detection.
-    QuicTime::Delta delay =
-        QuicConnectionPeer::GetSentPacketManager(&connection_)
-            ->GetPathDegradingDelay();
-    EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                         clock_.ApproximateNow());
-
-    // Send a second packet. The path degrading detection's deadline should
-    // remain the same.
-    // Regression test for b/69979024.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-    QuicTime prev_deadline =
-        connection_.GetBlackholeDetectorAlarm()->deadline();
-    connection_.SendStreamDataWithString(
-        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
-        offset, NO_FIN);
-    offset += data_size;
-    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-    EXPECT_EQ(prev_deadline,
-              connection_.GetBlackholeDetectorAlarm()->deadline());
-
-    // Now receive an ACK of the first packet. This should advance the path
-    // degrading detection's deadline since forward progress has been made.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-    if (i == 0) {
-      EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-    }
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-    QuicAckFrame frame = InitAckFrame(
-        {{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
-    ProcessAckPacket(&frame);
-    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-    // Check the deadline of the path degrading detection.
-    delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-                ->GetPathDegradingDelay();
-    EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                         clock_.ApproximateNow());
-
-    if (i == 0) {
-      // Now receive an ACK of the second packet. Since there are no more
-      // retransmittable packets on the wire, this should cancel the path
-      // degrading detection.
-      clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-      EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-      frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-      ProcessAckPacket(&frame);
-      EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-    } else {
-      // Advance time to the path degrading alarm's deadline and simulate
-      // firing the alarm.
-      clock_.AdvanceTime(delay);
-      EXPECT_CALL(visitor_, OnPathDegrading());
-      connection_.PathDegradingTimeout();
-      EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-    }
-  }
-  EXPECT_TRUE(connection_.IsPathDegrading());
-}
-
-TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPingAlarm) {
-  const QuicTime::Delta retransmittable_on_wire_timeout =
-      QuicTime::Delta::FromMilliseconds(50);
-  connection_.set_initial_retransmittable_on_wire_timeout(
-      retransmittable_on_wire_timeout);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-
-  // Send a packet.
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  // Now there's a retransmittable packet on the wire, so the path degrading
-  // alarm should be set.
-  // The retransmittable-on-wire alarm should not be set.
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-                              ->GetPathDegradingDelay();
-  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                       clock_.ApproximateNow());
-  ASSERT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
-  EXPECT_EQ(ping_delay,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now receive an ACK of the packet.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
-  ProcessAckPacket(&frame);
-  // No more retransmittable packets on the wire, so the path degrading alarm
-  // should be cancelled, and the ping alarm should be set to the
-  // retransmittable_on_wire_timeout.
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Simulate firing the ping alarm and sending a PING.
-  clock_.AdvanceTime(retransmittable_on_wire_timeout);
-  connection_.GetPingAlarm()->Fire();
-
-  // Now there's a retransmittable packet (PING) on the wire, so the path
-  // degrading alarm should be set.
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-              ->GetPathDegradingDelay();
-  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                       clock_.ApproximateNow());
-}
-
-TEST_P(QuicConnectionTest, ServerRetransmittableOnWire) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  SetQuicReloadableFlag(quic_enable_server_on_wire_ping, true);
-
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kSRWP);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  connection_.SetFromConfig(config);
-
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-
-  ProcessPacket(1);
-
-  ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
-  QuicTime::Delta ping_delay = QuicTime::Delta::FromMilliseconds(200);
-  EXPECT_EQ(ping_delay,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-  // Verify PING alarm gets cancelled.
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-
-  // Now receive an ACK of the packet.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
-  ProcessAckPacket(2, &frame);
-  // Verify PING alarm gets scheduled.
-  ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(ping_delay,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-// This test verifies that the connection marks path as degrading and does not
-// spin timer to detect path degrading when a new packet is sent on the
-// degraded path.
-TEST_P(QuicConnectionTest, NoPathDegradingDetectionIfPathIsDegrading) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_FALSE(connection_.IsPathDegrading());
-
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-
-  // Send the first packet. Now there's a retransmittable packet on the wire, so
-  // the path degrading alarm should be set.
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  // Check the deadline of the path degrading detection.
-  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-                              ->GetPathDegradingDelay();
-  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                       clock_.ApproximateNow());
-
-  // Send a second packet. The path degrading detection's deadline should remain
-  // the same.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
-
-  // Now receive an ACK of the first packet. This should advance the path
-  // degrading detection's deadline since forward progress has been made.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  // Check the deadline of the path degrading alarm.
-  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-              ->GetPathDegradingDelay();
-  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                       clock_.ApproximateNow());
-
-  // Advance time to the path degrading detection's deadline and simulate
-  // firing the path degrading detection. This path will be considered as
-  // degrading.
-  clock_.AdvanceTime(delay);
-  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
-  connection_.PathDegradingTimeout();
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_TRUE(connection_.IsPathDegrading());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  // Send a third packet. The path degrading detection is no longer set but path
-  // should still be marked as degrading.
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_TRUE(connection_.IsPathDegrading());
-}
-
-// This test verifies that the connection unmarks path as degrarding and spins
-// the timer to detect future path degrading when forward progress is made
-// after path has been marked degrading.
-TEST_P(QuicConnectionTest, UnmarkPathDegradingOnForwardProgress) {
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_FALSE(connection_.IsPathDegrading());
-
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-
-  // Send the first packet. Now there's a retransmittable packet on the wire, so
-  // the path degrading alarm should be set.
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  // Check the deadline of the path degrading alarm.
-  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-                              ->GetPathDegradingDelay();
-  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                       clock_.ApproximateNow());
-
-  // Send a second packet. The path degrading alarm's deadline should remain
-  // the same.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
-
-  // Now receive an ACK of the first packet. This should advance the path
-  // degrading alarm's deadline since forward progress has been made.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  // Check the deadline of the path degrading alarm.
-  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
-              ->GetPathDegradingDelay();
-  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
-                       clock_.ApproximateNow());
-
-  // Advance time to the path degrading alarm's deadline and simulate
-  // firing the alarm.
-  clock_.AdvanceTime(delay);
-  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
-  connection_.PathDegradingTimeout();
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_TRUE(connection_.IsPathDegrading());
-
-  // Send a third packet. The path degrading alarm is no longer set but path
-  // should still be marked as degrading.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_TRUE(connection_.IsPathDegrading());
-
-  // Now receive an ACK of the second packet. This should unmark the path as
-  // degrading. And will set a timer to detect new path degrading.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
-  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  ProcessAckPacket(&frame);
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, NoPathDegradingOnServer) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
-  // Send data.
-  const char data[] = "data";
-  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
-  // Ack data.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
-  ProcessAckPacket(&frame);
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, NoPathDegradingAfterSendingAck) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(1);
-  SendAckPacketToPeer();
-  EXPECT_FALSE(connection_.sent_packet_manager().unacked_packets().empty());
-  EXPECT_FALSE(connection_.sent_packet_manager().HasInFlightPackets());
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, MultipleCallsToCloseConnection) {
-  // Verifies that multiple calls to CloseConnection do not
-  // result in multiple attempts to close the connection - it will be marked as
-  // disconnected after the first call.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
-  connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
-                              ConnectionCloseBehavior::SILENT_CLOSE);
-  connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
-                              ConnectionCloseBehavior::SILENT_CLOSE);
-}
-
-TEST_P(QuicConnectionTest, ServerReceivesChloOnNonCryptoStream) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  CryptoHandshakeMessage message;
-  CryptoFramer framer;
-  message.set_tag(kCHLO);
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  frame1_.stream_id = 10;
-  frame1_.data_buffer = data->data();
-  frame1_.data_length = data->length();
-
-  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
-    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  }
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  ForceProcessFramePacket(QuicFrame(frame1_));
-  if (VersionHasIetfQuicFrames(version().transport_version)) {
-    // INITIAL packet should not contain STREAM frame.
-    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-  } else {
-    TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
-  }
-}
-
-TEST_P(QuicConnectionTest, ClientReceivesRejOnNonCryptoStream) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  CryptoHandshakeMessage message;
-  CryptoFramer framer;
-  message.set_tag(kREJ);
-  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
-  frame1_.stream_id = 10;
-  frame1_.data_buffer = data->data();
-  frame1_.data_length = data->length();
-
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  ForceProcessFramePacket(QuicFrame(frame1_));
-  if (VersionHasIetfQuicFrames(version().transport_version)) {
-    // INITIAL packet should not contain STREAM frame.
-    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-  } else {
-    TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
-  }
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnPacketTooLarge) {
-  SimulateNextPacketTooLarge();
-  // A connection close packet is sent
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(1);
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, AlwaysGetPacketTooLarge) {
-  // Test even we always get packet too large, we do not infinitely try to send
-  // close packet.
-  AlwaysGetPacketTooLarge();
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(1);
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnQueuedWriteError) {
-  // Regression test for crbug.com/979507.
-  //
-  // If we get a write error when writing queued packets, we should attempt to
-  // send a connection close packet, but if sending that fails, it shouldn't get
-  // queued.
-
-  // Queue a packet to write.
-  BlockOnNextWrite();
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Configure writer to always fail.
-  AlwaysGetPacketTooLarge();
-
-  // Expect that we attempt to close the connection exactly once.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(1);
-
-  // Unblock the writes and actually send.
-  writer_->SetWritable();
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
-  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-// Verify that if connection has no outstanding data, it notifies the send
-// algorithm after the write.
-TEST_P(QuicConnectionTest, SendDataAndBecomeApplicationLimited) {
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
-  {
-    InSequence seq;
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
-        .WillRepeatedly(Return(false));
-  }
-
-  connection_.SendStreamData3();
-}
-
-// Verify that the connection does not become app-limited if there is
-// outstanding data to send after the write.
-TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedIfMoreDataAvailable) {
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
-  {
-    InSequence seq;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
-  }
-
-  connection_.SendStreamData3();
-}
-
-// Verify that the connection does not become app-limited after blocked write
-// even if there is outstanding data to send after the write.
-TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedDueToWriteBlock) {
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
-  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
-  BlockOnNextWrite();
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamData3();
-
-  // Now unblock the writer, become congestion control blocked,
-  // and ensure we become app-limited after writing.
-  writer_->SetWritable();
-  CongestionBlockWrites();
-  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
-  connection_.OnCanWrite();
-}
-
-// Test the mode in which the link is filled up with probing retransmissions if
-// the connection becomes application-limited.
-TEST_P(QuicConnectionTest, SendDataWhenApplicationLimited) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
-      .WillRepeatedly(Return(true));
-  {
-    InSequence seq;
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
-        .WillRepeatedly(Return(false));
-  }
-  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
-    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
-        PROBING_RETRANSMISSION);
-  });
-  // Fix congestion window to be 20,000 bytes.
-  EXPECT_CALL(*send_algorithm_, CanSend(Ge(20000u)))
-      .WillRepeatedly(Return(false));
-  EXPECT_CALL(*send_algorithm_, CanSend(Lt(20000u)))
-      .WillRepeatedly(Return(true));
-
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
-  ASSERT_EQ(0u, connection_.GetStats().packets_sent);
-  connection_.set_fill_up_link_during_probing(true);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-  connection_.SendStreamData3();
-
-  // We expect a lot of packets from a 20 kbyte window.
-  EXPECT_GT(connection_.GetStats().packets_sent, 10u);
-  // Ensure that the packets are padded.
-  QuicByteCount average_packet_size =
-      connection_.GetStats().bytes_sent / connection_.GetStats().packets_sent;
-  EXPECT_GT(average_packet_size, 1000u);
-
-  // Acknowledge all packets sent, except for the last one.
-  QuicAckFrame ack = InitAckFrame(
-      connection_.sent_packet_manager().GetLargestSentPacket() - 1);
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
-  // Ensure that since we no longer have retransmittable bytes in flight, this
-  // will not cause any responses to be sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
-  ProcessAckPacket(&ack);
-}
-
-TEST_P(QuicConnectionTest, DoNotForceSendingAckOnPacketTooLarge) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  // Send an ack by simulating delayed ack alarm firing.
-  ProcessPacket(1);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  connection_.GetAckAlarm()->Fire();
-  // Simulate data packet causes write error.
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  SimulateNextPacketTooLarge();
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  EXPECT_EQ(1u, writer_->connection_close_frames().size());
-  // Ack frame is not bundled in connection close packet.
-  EXPECT_TRUE(writer_->ack_frames().empty());
-  if (writer_->padding_frames().empty()) {
-    EXPECT_EQ(1u, writer_->frame_count());
-  } else {
-    EXPECT_EQ(2u, writer_->frame_count());
-  }
-
-  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAllLevels) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
-  connection_.CloseConnection(
-      kQuicErrorCode, "Some random error message",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
-  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
-  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
-  EXPECT_EQ(1u, writer_->connection_close_frames().size());
-
-  if (!connection_.version().CanSendCoalescedPackets()) {
-    // Each connection close packet should be sent in distinct UDP packets.
-    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
-              writer_->connection_close_packets());
-    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
-              writer_->packets_write_attempts());
-    return;
-  }
-
-  // A single UDP packet should be sent with multiple connection close packets
-  // coalesced together.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  // Only the first packet has been processed yet.
-  EXPECT_EQ(1u, writer_->connection_close_packets());
-
-  // ProcessPacket resets the visitor and frees the coalesced packet.
-  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-  auto packet = writer_->coalesced_packet()->Clone();
-  writer_->framer()->ProcessPacket(*packet);
-  EXPECT_EQ(1u, writer_->connection_close_packets());
-  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOneLevel) {
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
-  connection_.CloseConnection(
-      kQuicErrorCode, "Some random error message",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
-  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
-  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
-  EXPECT_EQ(1u, writer_->connection_close_frames().size());
-  EXPECT_EQ(1u, writer_->connection_close_packets());
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-TEST_P(QuicConnectionTest, DoNotPadServerInitialConnectionClose) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-
-  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
-    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  }
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
-  connection_.CloseConnection(
-      kQuicErrorCode, "Some random error message",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
-  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
-  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
-  EXPECT_EQ(1u, writer_->connection_close_frames().size());
-  EXPECT_TRUE(writer_->padding_frames().empty());
-  EXPECT_EQ(ENCRYPTION_INITIAL, writer_->framer()->last_decrypted_level());
-}
-
-// Regression test for b/63620844.
-TEST_P(QuicConnectionTest, FailedToWriteHandshakePacket) {
-  SimulateNextPacketTooLarge();
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(1);
-
-  connection_.SendCryptoStreamData();
-  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
-}
-
-TEST_P(QuicConnectionTest, MaxPacingRate) {
-  EXPECT_EQ(0, connection_.MaxPacingRate().ToBytesPerSecond());
-  connection_.SetMaxPacingRate(QuicBandwidth::FromBytesPerSecond(100));
-  EXPECT_EQ(100, connection_.MaxPacingRate().ToBytesPerSecond());
-}
-
-TEST_P(QuicConnectionTest, ClientAlwaysSendConnectionId) {
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
-  EXPECT_EQ(CONNECTION_ID_PRESENT,
-            writer_->last_packet_header().destination_connection_id_included);
-
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
-  connection_.SetFromConfig(config);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(3, "bar", 3, NO_FIN);
-  // Verify connection id is still sent in the packet.
-  EXPECT_EQ(CONNECTION_ID_PRESENT,
-            writer_->last_packet_header().destination_connection_id_included);
-}
-
-TEST_P(QuicConnectionTest, SendProbingRetransmissions) {
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-
-  const QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "bar", 3, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "test", 6, NO_FIN, &last_packet);
-
-  const QuicByteCount old_bytes_in_flight =
-      connection_.sent_packet_manager().GetBytesInFlight();
-
-  // Allow 9 probing retransmissions to be sent.
-  {
-    InSequence seq;
-    EXPECT_CALL(*send_algorithm_, CanSend(_))
-        .Times(9 * 2)
-        .WillRepeatedly(Return(true));
-    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
-  }
-  // Expect them retransmitted in cyclic order (foo, bar, test, foo, bar...).
-  QuicPacketCount sent_count = 0;
-
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
-      .WillRepeatedly(Invoke(
-          [this, &sent_count](QuicPacketNumber, QuicPacketLength, bool,
-                              TransmissionType, EncryptionLevel,
-                              const QuicFrames&, const QuicFrames&, QuicTime) {
-            ASSERT_EQ(1u, writer_->stream_frames().size());
-            if (connection_.version().CanSendCoalescedPackets()) {
-              // There is a delay of sending coalesced packet, so (6, 0, 3, 6,
-              // 0...).
-              EXPECT_EQ(3 * ((sent_count + 2) % 3),
-                        writer_->stream_frames()[0]->offset);
-            } else {
-              // Identify the frames by stream offset (0, 3, 6, 0, 3...).
-              EXPECT_EQ(3 * (sent_count % 3),
-                        writer_->stream_frames()[0]->offset);
-            }
-            sent_count++;
-          }));
-
-  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
-      .WillRepeatedly(Return(true));
-  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
-    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
-        PROBING_RETRANSMISSION);
-  });
-
-  connection_.SendProbingRetransmissions();
-
-  // Ensure that the in-flight has increased.
-  const QuicByteCount new_bytes_in_flight =
-      connection_.sent_packet_manager().GetBytesInFlight();
-  EXPECT_GT(new_bytes_in_flight, old_bytes_in_flight);
-}
-
-// Ensure that SendProbingRetransmissions() does not retransmit anything when
-// there are no outstanding packets.
-TEST_P(QuicConnectionTest,
-       SendProbingRetransmissionsFailsWhenNothingToRetransmit) {
-  ASSERT_TRUE(connection_.sent_packet_manager().unacked_packets().empty());
-
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
-      .WillRepeatedly(Return(true));
-  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
-    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
-        PROBING_RETRANSMISSION);
-  });
-
-  connection_.SendProbingRetransmissions();
-}
-
-TEST_P(QuicConnectionTest, PingAfterLastRetransmittablePacketAcked) {
-  const QuicTime::Delta retransmittable_on_wire_timeout =
-      QuicTime::Delta::FromMilliseconds(50);
-  connection_.set_initial_retransmittable_on_wire_timeout(
-      retransmittable_on_wire_timeout);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-
-  // Advance 5ms, send a retransmittable packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
-  EXPECT_EQ(ping_delay,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Advance 5ms, send a second retransmittable packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-
-  // Now receive an ACK of the first packet. This should not set the
-  // retransmittable-on-wire alarm since packet 2 is still on the wire.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  // The ping alarm has a 1 second granularity, and the clock has been advanced
-  // 10ms since it was originally set.
-  EXPECT_EQ(ping_delay - QuicTime::Delta::FromMilliseconds(10),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now receive an ACK of the second packet. This should set the
-  // retransmittable-on-wire alarm now that no retransmittable packets are on
-  // the wire.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now receive a duplicate ACK of the second packet. This should not update
-  // the ping alarm.
-  QuicTime prev_deadline = connection_.GetPingAlarm()->deadline();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
-
-  // Now receive a non-ACK packet.  This should not update the ping alarm.
-  prev_deadline = connection_.GetPingAlarm()->deadline();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  ProcessPacket(4);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
-
-  // Simulate the alarm firing and check that a PING is sent.
-  connection_.GetPingAlarm()->Fire();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  if (GetParam().no_stop_waiting) {
-    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
-  } else {
-    EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
-  }
-  ASSERT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, NoPingIfRetransmittablePacketSent) {
-  const QuicTime::Delta retransmittable_on_wire_timeout =
-      QuicTime::Delta::FromMilliseconds(50);
-  connection_.set_initial_retransmittable_on_wire_timeout(
-      retransmittable_on_wire_timeout);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-
-  // Advance 5ms, send a retransmittable packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
-  EXPECT_EQ(ping_delay,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now receive an ACK of the first packet. This should set the
-  // retransmittable-on-wire alarm now that no retransmittable packets are on
-  // the wire.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Before the alarm fires, send another retransmittable packet. This should
-  // cancel the retransmittable-on-wire alarm since now there's a
-  // retransmittable packet on the wire.
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-
-  // Now receive an ACK of the second packet. This should set the
-  // retransmittable-on-wire alarm now that no retransmittable packets are on
-  // the wire.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Simulate the alarm firing and check that a PING is sent.
-  writer_->Reset();
-  connection_.GetPingAlarm()->Fire();
-  size_t padding_frame_count = writer_->padding_frames().size();
-  if (GetParam().no_stop_waiting) {
-    // Do not ACK acks.
-    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
-  } else {
-    EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
-  }
-  ASSERT_EQ(1u, writer_->ping_frames().size());
-}
-
-// When there is no stream data received but are open streams, send the
-// first few consecutive pings with aggressive retransmittable-on-wire
-// timeout. Exponentially back off the retransmittable-on-wire ping timeout
-// afterwards until it exceeds the default ping timeout.
-TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
-  int max_aggressive_retransmittable_on_wire_ping_count = 5;
-  SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
-              max_aggressive_retransmittable_on_wire_ping_count);
-  const QuicTime::Delta initial_retransmittable_on_wire_timeout =
-      QuicTime::Delta::FromMilliseconds(200);
-  connection_.set_initial_retransmittable_on_wire_timeout(
-      initial_retransmittable_on_wire_timeout);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-
-  const char data[] = "data";
-  // Advance 5ms, send a retransmittable data packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
-  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(connection_.ping_timeout(),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-
-  // Verify that the first few consecutive retransmittable on wire pings are
-  // sent with aggressive timeout.
-  for (int i = 0; i <= max_aggressive_retransmittable_on_wire_ping_count; i++) {
-    // Receive an ACK of the previous packet. This should set the ping alarm
-    // with the initial retransmittable-on-wire timeout.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-    QuicPacketNumber ack_num = creator_->packet_number();
-    QuicAckFrame frame = InitAckFrame(
-        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-    ProcessAckPacket(&frame);
-    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-    // Simulate the alarm firing and check that a PING is sent.
-    writer_->Reset();
-    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
-    connection_.GetPingAlarm()->Fire();
-  }
-
-  QuicTime::Delta retransmittable_on_wire_timeout =
-      initial_retransmittable_on_wire_timeout;
-
-  // Verify subsequent pings are sent with timeout that is exponentially backed
-  // off.
-  while (retransmittable_on_wire_timeout * 2 < connection_.ping_timeout()) {
-    // Receive an ACK for the previous PING. This should set the
-    // ping alarm with backed off retransmittable-on-wire timeout.
-    retransmittable_on_wire_timeout = retransmittable_on_wire_timeout * 2;
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-    QuicPacketNumber ack_num = creator_->packet_number();
-    QuicAckFrame frame = InitAckFrame(
-        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-    ProcessAckPacket(&frame);
-    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-    EXPECT_EQ(retransmittable_on_wire_timeout,
-              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-    // Simulate the alarm firing and check that a PING is sent.
-    writer_->Reset();
-    clock_.AdvanceTime(retransmittable_on_wire_timeout);
-    connection_.GetPingAlarm()->Fire();
-  }
-
-  // The ping alarm is set with default ping timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(connection_.ping_timeout(),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Receive an ACK for the previous PING. The ping alarm is set with an
-  // earlier deadline.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicPacketNumber ack_num = creator_->packet_number();
-  QuicAckFrame frame = InitAckFrame(
-      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(connection_.ping_timeout() - QuicTime::Delta::FromMilliseconds(5),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-// This test verify that the count of consecutive aggressive pings is reset
-// when new data is received. And it also verifies the connection resets
-// the exponential back-off of the retransmittable-on-wire ping timeout
-// after receiving new stream data.
-TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
-  int max_aggressive_retransmittable_on_wire_ping_count = 3;
-  SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count, 3);
-  const QuicTime::Delta initial_retransmittable_on_wire_timeout =
-      QuicTime::Delta::FromMilliseconds(200);
-  connection_.set_initial_retransmittable_on_wire_timeout(
-      initial_retransmittable_on_wire_timeout);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-
-  const char data[] = "data";
-  // Advance 5ms, send a retransmittable data packet to the peer.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
-  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(connection_.ping_timeout(),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Receive an ACK of the first packet. This should set the ping alarm with
-  // initial retransmittable-on-wire timeout since there is no retransmittable
-  // packet on the wire.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Simulate the alarm firing and check that a PING is sent.
-  writer_->Reset();
-  clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
-  connection_.GetPingAlarm()->Fire();
-
-  // Receive an ACK for the previous PING. Ping alarm will be set with
-  // aggressive timeout.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicPacketNumber ack_num = creator_->packet_number();
-  frame = InitAckFrame(
-      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Process a data packet.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(peer_creator_.packet_number() + 1);
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
-                                         peer_creator_.packet_number() + 1);
-  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Verify the count of consecutive aggressive pings is reset.
-  for (int i = 0; i < max_aggressive_retransmittable_on_wire_ping_count; i++) {
-    // Receive an ACK of the previous packet. This should set the ping alarm
-    // with the initial retransmittable-on-wire timeout.
-    QuicPacketNumber ack_num = creator_->packet_number();
-    QuicAckFrame frame = InitAckFrame(
-        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-    ProcessAckPacket(&frame);
-    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-    // Simulate the alarm firing and check that a PING is sent.
-    writer_->Reset();
-    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
-    connection_.GetPingAlarm()->Fire();
-    // Advance 5ms to receive next packet.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  }
-
-  // Receive another ACK for the previous PING. This should set the
-  // ping alarm with backed off retransmittable-on-wire timeout.
-  ack_num = creator_->packet_number();
-  frame = InitAckFrame(
-      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(initial_retransmittable_on_wire_timeout * 2,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  writer_->Reset();
-  clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout);
-  connection_.GetPingAlarm()->Fire();
-
-  // Process another data packet and a new ACK packet. The ping alarm is set
-  // with aggressive ping timeout again.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  ProcessDataPacket(peer_creator_.packet_number() + 1);
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
-                                         peer_creator_.packet_number() + 1);
-  ack_num = creator_->packet_number();
-  frame = InitAckFrame(
-      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-// Make sure that we never send more retransmissible on the wire pings than
-// the limit in FLAGS_quic_max_retransmittable_on_wire_ping_count.
-TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) {
-  static constexpr int kMaxRetransmittableOnWirePingCount = 3;
-  SetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count,
-              kMaxRetransmittableOnWirePingCount);
-  static constexpr QuicTime::Delta initial_retransmittable_on_wire_timeout =
-      QuicTime::Delta::FromMilliseconds(200);
-  static constexpr QuicTime::Delta short_delay =
-      QuicTime::Delta::FromMilliseconds(5);
-  ASSERT_LT(short_delay * 10, initial_retransmittable_on_wire_timeout);
-  connection_.set_initial_retransmittable_on_wire_timeout(
-      initial_retransmittable_on_wire_timeout);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-
-  const char data[] = "data";
-  // Advance 5ms, send a retransmittable data packet to the peer.
-  clock_.AdvanceTime(short_delay);
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
-  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
-  // The ping alarm is set for the ping timeout, not the shorter
-  // retransmittable_on_wire_timeout.
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(connection_.ping_timeout(),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
-      .Times(AnyNumber());
-
-  // Verify that the first few consecutive retransmittable on wire pings are
-  // sent with aggressive timeout.
-  for (int i = 0; i <= kMaxRetransmittableOnWirePingCount; i++) {
-    // Receive an ACK of the previous packet. This should set the ping alarm
-    // with the initial retransmittable-on-wire timeout.
-    clock_.AdvanceTime(short_delay);
-    QuicPacketNumber ack_num = creator_->packet_number();
-    QuicAckFrame frame = InitAckFrame(
-        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-    ProcessAckPacket(&frame);
-    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
-              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-    // Simulate the alarm firing and check that a PING is sent.
-    writer_->Reset();
-    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
-    connection_.GetPingAlarm()->Fire();
-  }
-
-  // Receive an ACK of the previous packet. This should set the ping alarm
-  // but this time with the default ping timeout.
-  QuicPacketNumber ack_num = creator_->packet_number();
-  QuicAckFrame frame = InitAckFrame(
-      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
-  ProcessAckPacket(&frame);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(connection_.ping_timeout(),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-}
-
-TEST_P(QuicConnectionTest, ValidStatelessResetToken) {
-  const StatelessResetToken kTestToken{0, 1, 0, 1, 0, 1, 0, 1,
-                                       0, 1, 0, 1, 0, 1, 0, 1};
-  const StatelessResetToken kWrongTestToken{0, 1, 0, 1, 0, 1, 0, 1,
-                                            0, 1, 0, 1, 0, 1, 0, 2};
-  QuicConfig config;
-  // No token has been received.
-  EXPECT_FALSE(connection_.IsValidStatelessResetToken(kTestToken));
-
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(2);
-  // Token is different from received token.
-  QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
-  connection_.SetFromConfig(config);
-  EXPECT_FALSE(connection_.IsValidStatelessResetToken(kWrongTestToken));
-
-  QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
-  connection_.SetFromConfig(config);
-  EXPECT_TRUE(connection_.IsValidStatelessResetToken(kTestToken));
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedWithInvalidAck) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-  BlockOnNextWrite();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendStreamDataWithString(5, "foo", 0, FIN);
-  // This causes connection to be closed because packet 1 has not been sent yet.
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessAckPacket(1, &frame);
-  EXPECT_EQ(0, connection_close_frame_count_);
-}
-
-TEST_P(QuicConnectionTest, SendMessage) {
-  if (!VersionSupportsMessageFrames(connection_.transport_version())) {
-    return;
-  }
-  if (connection_.version().UsesTls()) {
-    QuicConfig config;
-    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
-        &config, kMaxAcceptedDatagramFrameSize);
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  std::string message(connection_.GetCurrentLargestMessagePayload() * 2, 'a');
-  quiche::QuicheMemSlice slice;
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendStreamData3();
-    // Send a message which cannot fit into current open packet, and 2 packets
-    // get sent, one contains stream frame, and the other only contains the
-    // message frame.
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-    slice = MemSliceFromString(absl::string_view(
-        message.data(), connection_.GetCurrentLargestMessagePayload()));
-    EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
-              connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false));
-  }
-  // Fail to send a message if connection is congestion control blocked.
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
-  slice = MemSliceFromString("message");
-  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
-            connection_.SendMessage(2, absl::MakeSpan(&slice, 1), false));
-
-  // Always fail to send a message which cannot fit into one packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  slice = MemSliceFromString(absl::string_view(
-      message.data(), connection_.GetCurrentLargestMessagePayload() + 1));
-  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
-            connection_.SendMessage(3, absl::MakeSpan(&slice, 1), false));
-}
-
-TEST_P(QuicConnectionTest, GetCurrentLargestMessagePayload) {
-  if (!connection_.version().SupportsMessageFrames()) {
-    return;
-  }
-  // Force use of this encrypter to simplify test expectations by making sure
-  // that the encryption overhead is constant across versions.
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x00));
-  QuicPacketLength expected_largest_payload = 1219;
-  if (connection_.version().SendsVariableLengthPacketNumberInLongHeader()) {
-    expected_largest_payload += 3;
-  }
-  if (connection_.version().HasLongHeaderLengths()) {
-    expected_largest_payload -= 2;
-  }
-  if (connection_.version().HasLengthPrefixedConnectionIds()) {
-    expected_largest_payload -= 1;
-  }
-  if (connection_.version().UsesTls()) {
-    // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
-    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
-    QuicConfig config;
-    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
-        &config, kMaxAcceptedDatagramFrameSize);
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-    // Verify the value post-handshake.
-    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
-              expected_largest_payload);
-  } else {
-    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
-              expected_largest_payload);
-  }
-}
-
-TEST_P(QuicConnectionTest, GetGuaranteedLargestMessagePayload) {
-  if (!connection_.version().SupportsMessageFrames()) {
-    return;
-  }
-  // Force use of this encrypter to simplify test expectations by making sure
-  // that the encryption overhead is constant across versions.
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x00));
-  QuicPacketLength expected_largest_payload = 1219;
-  if (connection_.version().HasLongHeaderLengths()) {
-    expected_largest_payload -= 2;
-  }
-  if (connection_.version().HasLengthPrefixedConnectionIds()) {
-    expected_largest_payload -= 1;
-  }
-  if (connection_.version().UsesTls()) {
-    // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
-    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
-    QuicConfig config;
-    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
-        &config, kMaxAcceptedDatagramFrameSize);
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-    // Verify the value post-handshake.
-    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
-              expected_largest_payload);
-  } else {
-    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
-              expected_largest_payload);
-  }
-}
-
-TEST_P(QuicConnectionTest, LimitedLargestMessagePayload) {
-  if (!connection_.version().SupportsMessageFrames() ||
-      !connection_.version().UsesTls()) {
-    return;
-  }
-  constexpr QuicPacketLength kFrameSizeLimit = 1000;
-  constexpr QuicPacketLength kPayloadSizeLimit =
-      kFrameSizeLimit - kQuicFrameTypeSize;
-  // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
-  EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
-  EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMaxDatagramFrameSize(&config, kFrameSizeLimit);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  // Verify the value post-handshake.
-  EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), kPayloadSizeLimit);
-  EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
-            kPayloadSizeLimit);
-}
-
-// Test to check that the path challenge/path response logic works
-// correctly. This test is only for version-99
-TEST_P(QuicConnectionTest, ServerResponseToPathChallenge) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-  // First check if the server can send probing packet.
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  // Create and send the probe request (PATH_CHALLENGE frame).
-  // SendConnectivityProbingPacket ends up calling
-  // TestPacketWriter::WritePacket() which in turns receives and parses the
-  // packet by calling framer_.ProcessPacket() -- which in turn calls
-  // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
-  // the packet in writer_->path_challenge_frames()
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendConnectivityProbingPacket(writer_.get(),
-                                            connection_.peer_address());
-  // Save the random contents of the challenge for later comparison to the
-  // response.
-  ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
-  QuicPathFrameBuffer challenge_data =
-      writer_->path_challenge_frames().front().data_buffer;
-
-  // Normally, QuicConnection::OnPathChallengeFrame and OnPaddingFrame would be
-  // called and it will perform actions to ensure that the rest of the protocol
-  // is performed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_TRUE(connection_.OnPathChallengeFrame(
-      writer_->path_challenge_frames().front()));
-  EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
-  creator_->FlushCurrentPacket();
-
-  // The final check is to ensure that the random data in the response matches
-  // the random data from the challenge.
-  EXPECT_EQ(1u, writer_->path_response_frames().size());
-  EXPECT_EQ(0, memcmp(&challenge_data,
-                      &(writer_->path_response_frames().front().data_buffer),
-                      sizeof(challenge_data)));
-}
-
-TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnDefaulSocket) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  // First check if the client can send probing packet.
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  // Create and send the probe request (PATH_CHALLENGE frame).
-  // SendConnectivityProbingPacket ends up calling
-  // TestPacketWriter::WritePacket() which in turns receives and parses the
-  // packet by calling framer_.ProcessPacket() -- which in turn calls
-  // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
-  // the packet in writer_->path_challenge_frames()
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.SendConnectivityProbingPacket(writer_.get(),
-                                            connection_.peer_address());
-  // Save the random contents of the challenge for later validation against the
-  // response.
-  ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
-  QuicPathFrameBuffer challenge_data =
-      writer_->path_challenge_frames().front().data_buffer;
-
-  // Normally, QuicConnection::OnPathChallengeFrame would be
-  // called and it will perform actions to ensure that the rest of the protocol
-  // is performed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_TRUE(connection_.OnPathChallengeFrame(
-      writer_->path_challenge_frames().front()));
-  EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
-  creator_->FlushCurrentPacket();
-
-  // The final check is to ensure that the random data in the response matches
-  // the random data from the challenge.
-  EXPECT_EQ(1u, writer_->path_response_frames().size());
-  EXPECT_EQ(0, memcmp(&challenge_data,
-                      &(writer_->path_response_frames().front().data_buffer),
-                      sizeof(challenge_data)));
-}
-
-TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnAlternativeSocket) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-
-  QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(1u, new_writer.packets_write_attempts());
-        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
-        EXPECT_EQ(1u, new_writer.padding_frames().size());
-        EXPECT_EQ(kNewSelfAddress.host(),
-                  new_writer.last_write_source_address());
-      }));
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-
-  // Receiving a PATH_CHALLENGE on the alternative path. Response to this
-  // PATH_CHALLENGE should be sent via the alternative writer.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(2u, new_writer.packets_write_attempts());
-        EXPECT_EQ(1u, new_writer.path_response_frames().size());
-        EXPECT_EQ(1u, new_writer.padding_frames().size());
-        EXPECT_EQ(kNewSelfAddress.host(),
-                  new_writer.last_write_source_address());
-      }));
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-  ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
-
-  QuicSocketAddress kNewerSelfAddress(QuicIpAddress::Loopback6(),
-                                      /*port=*/34567);
-  // Receiving a PATH_CHALLENGE on an unknown socket should be ignored.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
-  ProcessReceivedPacket(kNewerSelfAddress, kPeerAddress, *received);
-}
-
-TEST_P(QuicConnectionTest,
-       RestartPathDegradingDetectionAfterMigrationWithProbe) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  // Send data and verify the path degrading detection is set.
-  const char data[] = "data";
-  size_t data_size = strlen(data);
-  QuicStreamOffset offset = 0;
-  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
-  offset += data_size;
-
-  // Verify the path degrading detection is in progress.
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  QuicTime ddl = connection_.GetBlackholeDetectorAlarm()->deadline();
-
-  // Simulate the firing of path degrading.
-  clock_.AdvanceTime(ddl - clock_.ApproximateNow());
-  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
-  connection_.PathDegradingTimeout();
-  EXPECT_TRUE(connection_.IsPathDegrading());
-  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    // Simulate path degrading handling by sending a probe on an alternet path.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-    TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
-    connection_.SendConnectivityProbingPacket(&probing_writer,
-                                              connection_.peer_address());
-    // Verify that path degrading detection is not reset.
-    EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-
-    // Simulate successful path degrading handling by receiving probe response.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
-    EXPECT_CALL(visitor_,
-                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
-        .Times(1);
-    const QuicSocketAddress kNewSelfAddress =
-        QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-
-    std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-    std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-        QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                            probing_packet->encrypted_length),
-        clock_.Now()));
-    uint64_t num_probing_received =
-        connection_.GetStats().num_connectivity_probing_received;
-    ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
-
-    EXPECT_EQ(num_probing_received + 1,
-              connection_.GetStats().num_connectivity_probing_received);
-    EXPECT_EQ(kPeerAddress, connection_.peer_address());
-    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-    EXPECT_TRUE(connection_.IsPathDegrading());
-  }
-
-  // Verify new path degrading detection is activated.
-  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
-  connection_.OnSuccessfulMigration(/*is_port_change*/ true);
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
-  if (!GetParam().version.HasIetfQuicFrames()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  EXPECT_EQ(kSelfAddress, connection_.self_address());
-
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
-  rtt_stats->set_initial_rtt(default_init_rtt * 2);
-  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
-
-  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
-  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
-  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
-  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
-  const SendAlgorithmInterface* send_algorithm = manager_->GetSendAlgorithm();
-
-  // Migrate to a new address with different IP.
-  const QuicSocketAddress kNewSelfAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
-                          &new_writer, false);
-  EXPECT_EQ(default_init_rtt, manager_->GetRttStats()->initial_rtt());
-  EXPECT_EQ(0u, manager_->GetConsecutiveRtoCount());
-  EXPECT_EQ(0u, manager_->GetConsecutiveTlpCount());
-  EXPECT_NE(send_algorithm, manager_->GetSendAlgorithm());
-}
-
-// Regression test for b/110259444
-TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
-  writer_->SetWriteBlocked();
-
-  ProcessPacket(1);
-  // Verify ack alarm is set.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  // Fire the ack alarm, verify no packet is sent because the writer is blocked.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.GetAckAlarm()->Fire();
-
-  writer_->SetWritable();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessPacket(2);
-  // Verify ack alarm is not set.
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, DisablePacingOffloadConnectionOptions) {
-  EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
-  writer_->set_supports_release_time(true);
-  QuicConfig config;
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  EXPECT_TRUE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
-
-  QuicTagVector connection_options;
-  connection_options.push_back(kNPCO);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  // Verify pacing offload is disabled.
-  EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
-}
-
-// Regression test for b/110259444
-// Get a path response without having issued a path challenge...
-TEST_P(QuicConnectionTest, OrphanPathResponse) {
-  QuicPathFrameBuffer data = {{0, 1, 2, 3, 4, 5, 6, 7}};
-
-  QuicPathResponseFrame frame(99, data);
-  EXPECT_TRUE(connection_.OnPathResponseFrame(frame));
-  // If PATH_RESPONSE was accepted (payload matches the payload saved
-  // in QuicConnection::transmitted_connectivity_probe_payload_) then
-  // current_packet_content_ would be set to FIRST_FRAME_IS_PING.
-  // Since this PATH_RESPONSE does not match, current_packet_content_
-  // must not be FIRST_FRAME_IS_PING.
-  EXPECT_NE(QuicConnection::FIRST_FRAME_IS_PING,
-            QuicConnectionPeer::GetCurrentPacketContent(&connection_));
-}
-
-// Regression test for b/120791670
-TEST_P(QuicConnectionTest, StopProcessingGQuicPacketInIetfQuicConnection) {
-  // This test mimics a problematic scenario where a QUIC connection using a
-  // modern version received a Q043 packet and processed it incorrectly.
-  // We can remove this test once Q043 is deprecated.
-  if (!version().HasIetfInvariantHeader()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-
-  // Let connection process a Google QUIC packet.
-  peer_framer_.set_version_for_tests(ParsedQuicVersion::Q043());
-  std::unique_ptr<QuicPacket> packet(
-      ConstructDataPacket(2, !kHasStopWaiting, ENCRYPTION_INITIAL));
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
-                                  *packet, buffer, kMaxOutgoingPacketSize);
-  // Make sure no stream frame is processed.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-
-  EXPECT_EQ(2u, connection_.GetStats().packets_received);
-  EXPECT_EQ(1u, connection_.GetStats().packets_processed);
-}
-
-TEST_P(QuicConnectionTest, AcceptPacketNumberZero) {
-  if (!VersionHasIetfQuicFrames(version().transport_version)) {
-    return;
-  }
-  // Set first_sending_packet_number to be 0 to allow successfully processing
-  // acks which ack packet number 0.
-  QuicFramerPeer::SetFirstSendingPacketNumber(writer_->framer()->framer(), 0);
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  ProcessPacket(0);
-  EXPECT_EQ(QuicPacketNumber(0), LargestAcked(connection_.ack_frame()));
-  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
-  ProcessPacket(1);
-  EXPECT_EQ(QuicPacketNumber(1), LargestAcked(connection_.ack_frame()));
-  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-
-  ProcessPacket(2);
-  EXPECT_EQ(QuicPacketNumber(2), LargestAcked(connection_.ack_frame()));
-  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
-}
-
-TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicSending) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-
-  connection_.SendCryptoStreamData();
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  QuicAckFrame frame1 = InitAckFrame(1);
-  // Received ACK for packet 1.
-  ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
-                                         NO_FIN);
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
-                                         NO_FIN);
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
-                                         8, NO_FIN);
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
-                                         12, FIN);
-  // Received ACK for packets 2, 4, 5.
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  QuicAckFrame frame2 =
-      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
-                    {QuicPacketNumber(4), QuicPacketNumber(6)}});
-  // Make sure although the same packet number is used, but they are in
-  // different packet number spaces.
-  ProcessFramePacketAtLevel(30, QuicFrame(&frame2), ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, PeerAcksPacketsInWrongPacketNumberSpace) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x01));
-
-  connection_.SendCryptoStreamData();
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  QuicAckFrame frame1 = InitAckFrame(1);
-  // Received ACK for packet 1.
-  ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
-                                         NO_FIN);
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
-                                         NO_FIN);
-
-  // Received ACK for packets 2 and 3 in wrong packet number space.
-  QuicAckFrame invalid_ack =
-      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(4)}});
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  ProcessFramePacketAtLevel(300, QuicFrame(&invalid_ack), ENCRYPTION_INITIAL);
-  TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
-}
-
-TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  // Receives packet 1000 in application data.
-  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
-                                         0, NO_FIN);
-  // Verify application data ACK gets bundled with outgoing data.
-  EXPECT_EQ(2u, writer_->frame_count());
-  // Make sure ACK alarm is still set because initial data is not ACKed.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  // Receive packet 1001 in application data.
-  ProcessDataPacketAtLevel(1001, false, ENCRYPTION_FORWARD_SECURE);
-  clock_.AdvanceTime(DefaultRetransmissionTime());
-  // Simulates ACK alarm fires and verify two ACKs are flushed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.GetAckAlarm()->Fire();
-  EXPECT_FALSE(connection_.HasPendingAcks());
-  // Receives more packets in application data.
-  ProcessDataPacketAtLevel(1002, false, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  // Verify zero rtt and forward secure packets get acked in the same packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessDataPacket(1003);
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  // Receives packet 1000 in application data.
-  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  writer_->SetWriteBlocked();
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AnyNumber());
-  // Simulates ACK alarm fires and verify no ACK is flushed because of write
-  // blocked.
-  clock_.AdvanceTime(DefaultDelayedAckTime());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.GetAckAlarm()->Fire();
-  // Verify ACK alarm is not set.
-  EXPECT_FALSE(connection_.HasPendingAcks());
-
-  writer_->SetWritable();
-  // Verify 2 ACKs are sent when connection gets unblocked.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  connection_.OnCanWrite();
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-// Make sure a packet received with the right client connection ID is processed.
-TEST_P(QuicConnectionTest, ValidClientConnectionId) {
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  SetClientConnectionId(TestConnectionId(0x33));
-  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
-  header.destination_connection_id = TestConnectionId(0x33);
-  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
-  header.source_connection_id_included = CONNECTION_ID_ABSENT;
-  QuicFrames frames;
-  QuicPingFrame ping_frame;
-  QuicPaddingFrame padding_frame;
-  frames.push_back(QuicFrame(ping_frame));
-  frames.push_back(QuicFrame(padding_frame));
-  std::unique_ptr<QuicPacket> packet =
-      BuildUnsizedDataPacket(&peer_framer_, header, frames);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
-      kMaxOutgoingPacketSize);
-  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
-                                     false);
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-}
-
-// Make sure a packet received with a different client connection ID is dropped.
-TEST_P(QuicConnectionTest, InvalidClientConnectionId) {
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  SetClientConnectionId(TestConnectionId(0x33));
-  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
-  header.destination_connection_id = TestConnectionId(0xbad);
-  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
-  header.source_connection_id_included = CONNECTION_ID_ABSENT;
-  QuicFrames frames;
-  QuicPingFrame ping_frame;
-  QuicPaddingFrame padding_frame;
-  frames.push_back(QuicFrame(ping_frame));
-  frames.push_back(QuicFrame(padding_frame));
-  std::unique_ptr<QuicPacket> packet =
-      BuildUnsizedDataPacket(&peer_framer_, header, frames);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
-      kMaxOutgoingPacketSize);
-  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
-                                     false);
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
-  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
-}
-
-// Make sure the first packet received with a different client connection ID on
-// the server is processed and it changes the client connection ID.
-TEST_P(QuicConnectionTest, UpdateClientConnectionIdFromFirstPacket) {
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
-  header.source_connection_id = TestConnectionId(0x33);
-  header.source_connection_id_included = CONNECTION_ID_PRESENT;
-  QuicFrames frames;
-  QuicPingFrame ping_frame;
-  QuicPaddingFrame padding_frame;
-  frames.push_back(QuicFrame(ping_frame));
-  frames.push_back(QuicFrame(padding_frame));
-  std::unique_ptr<QuicPacket> packet =
-      BuildUnsizedDataPacket(&peer_framer_, header, frames);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
-                                  *packet, buffer, kMaxOutgoingPacketSize);
-  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
-                                     false);
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  EXPECT_EQ(TestConnectionId(0x33), connection_.client_connection_id());
-}
-void QuicConnectionTest::TestReplaceConnectionIdFromInitial() {
-  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
-    return;
-  }
-  // We start with a known connection ID.
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  EXPECT_NE(TestConnectionId(0x33), connection_.connection_id());
-  // Receiving an initial can replace the connection ID once.
-  {
-    QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
-    header.source_connection_id = TestConnectionId(0x33);
-    header.source_connection_id_included = CONNECTION_ID_PRESENT;
-    QuicFrames frames;
-    QuicPingFrame ping_frame;
-    QuicPaddingFrame padding_frame;
-    frames.push_back(QuicFrame(ping_frame));
-    frames.push_back(QuicFrame(padding_frame));
-    std::unique_ptr<QuicPacket> packet =
-        BuildUnsizedDataPacket(&peer_framer_, header, frames);
-    char buffer[kMaxOutgoingPacketSize];
-    size_t encrypted_length =
-        peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
-                                    *packet, buffer, kMaxOutgoingPacketSize);
-    QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
-                                       false);
-    ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
-  }
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
-  EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
-  // Trying to replace the connection ID a second time drops the packet.
-  {
-    QuicPacketHeader header = ConstructPacketHeader(2, ENCRYPTION_INITIAL);
-    header.source_connection_id = TestConnectionId(0x66);
-    header.source_connection_id_included = CONNECTION_ID_PRESENT;
-    QuicFrames frames;
-    QuicPingFrame ping_frame;
-    QuicPaddingFrame padding_frame;
-    frames.push_back(QuicFrame(ping_frame));
-    frames.push_back(QuicFrame(padding_frame));
-    std::unique_ptr<QuicPacket> packet =
-        BuildUnsizedDataPacket(&peer_framer_, header, frames);
-    char buffer[kMaxOutgoingPacketSize];
-    size_t encrypted_length =
-        peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
-                                    *packet, buffer, kMaxOutgoingPacketSize);
-    QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
-                                       false);
-    ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
-  }
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
-  EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
-}
-
-TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromInitial) {
-  TestReplaceConnectionIdFromInitial();
-}
-
-TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromRetryAndInitial) {
-  // First make the connection process a RETRY and replace the server connection
-  // ID a first time.
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-  // Reset the test framer to use the right connection ID.
-  peer_framer_.SetInitialObfuscators(connection_.connection_id());
-  // Now process an INITIAL and replace the server connection ID a second time.
-  TestReplaceConnectionIdFromInitial();
-}
-
-// Regression test for b/134416344.
-TEST_P(QuicConnectionTest, CheckConnectedBeforeFlush) {
-  // This test mimics a scenario where a connection processes 2 packets and the
-  // 2nd packet contains connection close frame. When the 2nd flusher goes out
-  // of scope, a delayed ACK is pending, and ACK alarm should not be scheduled
-  // because connection is disconnected.
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-  const QuicErrorCode kErrorCode = QUIC_INTERNAL_ERROR;
-  std::unique_ptr<QuicConnectionCloseFrame> connection_close_frame(
-      new QuicConnectionCloseFrame(connection_.transport_version(), kErrorCode,
-                                   NO_IETF_QUIC_ERROR, "",
-                                   /*transport_close_frame_type=*/0));
-
-  // Received 2 packets.
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  }
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  ProcessFramePacketWithAddresses(QuicFrame(connection_close_frame.release()),
-                                  kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  // Verify ack alarm is not set.
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-// Verify that a packet containing three coalesced packets is parsed correctly.
-TEST_P(QuicConnectionTest, CoalescedPacket) {
-  if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
-    // Coalesced packets can only be encoded using long header lengths.
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_TRUE(connection_.connected());
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
-  }
-
-  uint64_t packet_numbers[3] = {1, 2, 3};
-  EncryptionLevel encryption_levels[3] = {
-      ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
-  char buffer[kMaxOutgoingPacketSize] = {};
-  size_t total_encrypted_length = 0;
-  for (int i = 0; i < 3; i++) {
-    QuicPacketHeader header =
-        ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
-    QuicFrames frames;
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      frames.push_back(QuicFrame(&crypto_frame_));
-    } else {
-      frames.push_back(QuicFrame(frame1_));
-    }
-    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
-    peer_creator_.set_encryption_level(encryption_levels[i]);
-    size_t encrypted_length = peer_framer_.EncryptPayload(
-        encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
-        buffer + total_encrypted_length,
-        sizeof(buffer) - total_encrypted_length);
-    EXPECT_GT(encrypted_length, 0u);
-    total_encrypted_length += encrypted_length;
-  }
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
-  if (connection_.GetSendAlarm()->IsSet()) {
-    connection_.GetSendAlarm()->Fire();
-  }
-
-  EXPECT_TRUE(connection_.connected());
-}
-
-// Regression test for crbug.com/992831.
-TEST_P(QuicConnectionTest, CoalescedPacketThatSavesFrames) {
-  if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
-    // Coalesced packets can only be encoded using long header lengths.
-    return;
-  }
-  if (connection_.SupportsMultiplePacketNumberSpaces()) {
-    // TODO(b/129151114) Enable this test with multiple packet number spaces.
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_TRUE(connection_.connected());
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_))
-        .Times(3)
-        .WillRepeatedly([this](const QuicCryptoFrame& /*frame*/) {
-          // QuicFrame takes ownership of the QuicBlockedFrame.
-          connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
-        });
-  } else {
-    EXPECT_CALL(visitor_, OnStreamFrame(_))
-        .Times(3)
-        .WillRepeatedly([this](const QuicStreamFrame& /*frame*/) {
-          // QuicFrame takes ownership of the QuicBlockedFrame.
-          connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
-        });
-  }
-
-  uint64_t packet_numbers[3] = {1, 2, 3};
-  EncryptionLevel encryption_levels[3] = {
-      ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
-  char buffer[kMaxOutgoingPacketSize] = {};
-  size_t total_encrypted_length = 0;
-  for (int i = 0; i < 3; i++) {
-    QuicPacketHeader header =
-        ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
-    QuicFrames frames;
-    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-      frames.push_back(QuicFrame(&crypto_frame_));
-    } else {
-      frames.push_back(QuicFrame(frame1_));
-    }
-    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
-    peer_creator_.set_encryption_level(encryption_levels[i]);
-    size_t encrypted_length = peer_framer_.EncryptPayload(
-        encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
-        buffer + total_encrypted_length,
-        sizeof(buffer) - total_encrypted_length);
-    EXPECT_GT(encrypted_length, 0u);
-    total_encrypted_length += encrypted_length;
-  }
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
-  if (connection_.GetSendAlarm()->IsSet()) {
-    connection_.GetSendAlarm()->Fire();
-  }
-
-  EXPECT_TRUE(connection_.connected());
-
-  SendAckPacketToPeer();
-}
-
-// Regresstion test for b/138962304.
-TEST_P(QuicConnectionTest, RtoAndWriteBlocked) {
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_data_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Writer gets blocked.
-  writer_->SetWriteBlocked();
-
-  // Cancel the stream.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
-  EXPECT_CALL(visitor_, WillingAndAbleToWrite())
-      .WillRepeatedly(
-          Invoke(&notifier_, &SimpleSessionNotifier::WillingToWrite));
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
-  // Retransmission timer fires in RTO mode.
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify no packets get flushed when writer is blocked.
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-// Regresstion test for b/138962304.
-TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  connection_.SetMaxTailLossProbes(1);
-
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_data_packet;
-  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
-  SendStreamDataToPeer(4, "foo", 0, NO_FIN, &last_data_packet);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Writer gets blocked.
-  writer_->SetWriteBlocked();
-
-  // Cancel stream 2.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  // Retransmission timer fires in TLP mode.
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify one packets is forced flushed when writer is blocked.
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-}
-
-// Regresstion test for b/139375344.
-TEST_P(QuicConnectionTest, RtoForcesSendingPing) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  connection_.SetMaxTailLossProbes(2);
-  EXPECT_EQ(0u, connection_.GetStats().tlp_count);
-  EXPECT_EQ(0u, connection_.GetStats().rto_count);
-
-  SendStreamDataToPeer(2, "foo", 0, NO_FIN, nullptr);
-  QuicTime retransmission_time =
-      connection_.GetRetransmissionAlarm()->deadline();
-  EXPECT_NE(QuicTime::Zero(), retransmission_time);
-  // TLP fires.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, connection_.GetStats().tlp_count);
-  EXPECT_EQ(0u, connection_.GetStats().rto_count);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Packet 1 gets acked.
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessAckPacket(1, &frame);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
-
-  // RTO fires, verify a PING packet gets sent because there is no data to send.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, connection_.GetStats().tlp_count);
-  EXPECT_EQ(1u, connection_.GetStats().rto_count);
-  EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, ProbeTimeout) {
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k2PTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Reset stream.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
-
-  // Fire the PTO and verify only the RST_STREAM is resent, not stream data.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(0u, writer_->stream_frames().size());
-  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAfter6ClientPTOs) {
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k1PTO);
-  connection_options.push_back(k6PTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  }
-  connection_.OnHandshakeComplete();
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-
-  // Fire the retransmission alarm 5 times.
-  for (int i = 0; i < 5; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.GetRetransmissionAlarm()->Fire();
-    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_TRUE(connection_.connected());
-  }
-  EXPECT_CALL(visitor_, OnPathDegrading());
-  connection_.PathDegradingTimeout();
-
-  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
-  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
-  EXPECT_EQ(5u, connection_.sent_packet_manager().GetConsecutivePtoCount());
-  // Closes connection on 6th PTO.
-  // May send multiple connecction close packets with multiple PN spaces.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-  connection_.GetBlackholeDetectorAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAfter7ClientPTOs) {
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k2PTO);
-  connection_options.push_back(k7PTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  }
-  connection_.OnHandshakeComplete();
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-
-  // Fire the retransmission alarm 6 times.
-  for (int i = 0; i < 6; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    connection_.GetRetransmissionAlarm()->Fire();
-    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_TRUE(connection_.connected());
-  }
-  EXPECT_CALL(visitor_, OnPathDegrading());
-  connection_.PathDegradingTimeout();
-
-  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
-  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
-  EXPECT_EQ(6u, connection_.sent_packet_manager().GetConsecutivePtoCount());
-  // Closes connection on 7th PTO.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-  connection_.GetBlackholeDetectorAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionAfter8ClientPTOs) {
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k2PTO);
-  connection_options.push_back(k8PTO);
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  }
-  connection_.OnHandshakeComplete();
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-
-  // Fire the retransmission alarm 7 times.
-  for (int i = 0; i < 7; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    connection_.GetRetransmissionAlarm()->Fire();
-    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_TRUE(connection_.connected());
-  }
-  EXPECT_CALL(visitor_, OnPathDegrading());
-  connection_.PathDegradingTimeout();
-
-  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
-  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
-  EXPECT_EQ(7u, connection_.sent_packet_manager().GetConsecutivePtoCount());
-  // Closes connection on 8th PTO.
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
-  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-  connection_.GetBlackholeDetectorAlarm()->Fire();
-  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
-}
-
-TEST_P(QuicConnectionTest, DeprecateHandshakeMode) {
-  if (!connection_.version().SupportsAntiAmplificationLimit()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Send CHLO.
-  connection_.SendCryptoStreamData();
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  QuicAckFrame frame1 = InitAckFrame(1);
-  // Received ACK for packet 1.
-  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-
-  // Verify retransmission alarm is still set because handshake is not
-  // confirmed although there is nothing in flight.
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_EQ(0u, connection_.GetStats().pto_count);
-  EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
-
-  // PTO fires, verify a PING packet gets sent because there is no data to send.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, connection_.GetStats().pto_count);
-  EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count);
-  EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-TEST_P(QuicConnectionTest, AntiAmplificationLimit) {
-  if (!connection_.version().SupportsAntiAmplificationLimit()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
-  set_perspective(Perspective::IS_SERVER);
-  // Verify no data can be sent at the beginning because bytes received is 0.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo", 0);
-  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
-  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Receives packet 1.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
-  const size_t anti_amplification_factor =
-      GetQuicFlag(FLAGS_quic_anti_amplification_factor);
-  // Verify now packets can be sent.
-  for (size_t i = 1; i < anti_amplification_factor; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendCryptoDataWithString("foo", i * 3);
-    // Verify retransmission alarm is not set if throttled by anti-amplification
-    // limit.
-    EXPECT_EQ(i != anti_amplification_factor - 1,
-              connection_.GetRetransmissionAlarm()->IsSet());
-  }
-  // Verify server is throttled by anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
-
-  // Receives packet 2.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  // Verify more packets can be sent.
-  for (size_t i = anti_amplification_factor + 1;
-       i < anti_amplification_factor * 2; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendCryptoDataWithString("foo", i * 3);
-  }
-  // Verify server is throttled by anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo",
-                                       2 * anti_amplification_factor * 3);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessPacket(3);
-  // Verify anti-amplification limit is gone after address validation.
-  for (size_t i = 0; i < 100; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
-  }
-}
-
-TEST_P(QuicConnectionTest, 3AntiAmplificationLimit) {
-  if (!connection_.version().SupportsAntiAmplificationLimit()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
-  set_perspective(Perspective::IS_SERVER);
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k3AFF);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
-                                                         QuicConnectionId());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  // Verify no data can be sent at the beginning because bytes received is 0.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo", 0);
-  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
-  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Receives packet 1.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
-  const size_t anti_amplification_factor = 3;
-  // Verify now packets can be sent.
-  for (size_t i = 1; i < anti_amplification_factor; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendCryptoDataWithString("foo", i * 3);
-    // Verify retransmission alarm is not set if throttled by anti-amplification
-    // limit.
-    EXPECT_EQ(i != anti_amplification_factor - 1,
-              connection_.GetRetransmissionAlarm()->IsSet());
-  }
-  // Verify server is throttled by anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
-
-  // Receives packet 2.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  // Verify more packets can be sent.
-  for (size_t i = anti_amplification_factor + 1;
-       i < anti_amplification_factor * 2; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendCryptoDataWithString("foo", i * 3);
-  }
-  // Verify server is throttled by anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo",
-                                       2 * anti_amplification_factor * 3);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessPacket(3);
-  // Verify anti-amplification limit is gone after address validation.
-  for (size_t i = 0; i < 100; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
-  }
-}
-
-TEST_P(QuicConnectionTest, 10AntiAmplificationLimit) {
-  if (!connection_.version().SupportsAntiAmplificationLimit()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
-  set_perspective(Perspective::IS_SERVER);
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k10AF);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
-                                                         QuicConnectionId());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  // Verify no data can be sent at the beginning because bytes received is 0.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo", 0);
-  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
-  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Receives packet 1.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
-  const size_t anti_amplification_factor = 10;
-  // Verify now packets can be sent.
-  for (size_t i = 1; i < anti_amplification_factor; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendCryptoDataWithString("foo", i * 3);
-    // Verify retransmission alarm is not set if throttled by anti-amplification
-    // limit.
-    EXPECT_EQ(i != anti_amplification_factor - 1,
-              connection_.GetRetransmissionAlarm()->IsSet());
-  }
-  // Verify server is throttled by anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
-
-  // Receives packet 2.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  // Verify more packets can be sent.
-  for (size_t i = anti_amplification_factor + 1;
-       i < anti_amplification_factor * 2; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendCryptoDataWithString("foo", i * 3);
-  }
-  // Verify server is throttled by anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.SendCryptoDataWithString("foo",
-                                       2 * anti_amplification_factor * 3);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessPacket(3);
-  // Verify anti-amplification limit is gone after address validation.
-  for (size_t i = 0; i < 100; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
-  }
-}
-
-TEST_P(QuicConnectionTest, AckPendingWithAmplificationLimited) {
-  if (!connection_.version().SupportsAntiAmplificationLimit()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
-  set_perspective(Perspective::IS_SERVER);
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Receives packet 1.
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  // Send response in different encryption level and cause amplification factor
-  // throttled.
-  size_t i = 0;
-  while (connection_.CanWrite(HAS_RETRANSMITTABLE_DATA)) {
-    connection_.SendCryptoDataWithString(std::string(1024, 'a'), i * 1024,
-                                         ENCRYPTION_HANDSHAKE);
-    ++i;
-  }
-  // Verify ACK is still pending.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  // Fire ACK alarm and verify ACK cannot be sent due to amplification factor.
-  clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.GetAckAlarm()->Fire();
-  // Verify ACK alarm is cancelled.
-  EXPECT_FALSE(connection_.HasPendingAcks());
-
-  // Receives packet 2 and verify ACK gets flushed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  EXPECT_FALSE(writer_->ack_frames().empty());
-}
-
-TEST_P(QuicConnectionTest, ConnectionCloseFrameType) {
-  if (!VersionHasIetfQuicFrames(version().transport_version)) {
-    // Test relevent only for IETF QUIC.
-    return;
-  }
-  const QuicErrorCode kQuicErrorCode = IETF_QUIC_PROTOCOL_VIOLATION;
-  // Use the (unknown) frame type of 9999 to avoid triggering any logic
-  // which might be associated with the processing of a known frame type.
-  const uint64_t kTransportCloseFrameType = 9999u;
-  QuicFramerPeer::set_current_received_frame_type(
-      QuicConnectionPeer::GetFramer(&connection_), kTransportCloseFrameType);
-  // Do a transport connection close
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  connection_.CloseConnection(
-      kQuicErrorCode, "Some random error message",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
-      writer_->connection_close_frames();
-  ASSERT_EQ(1u, connection_close_frames.size());
-  EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
-            connection_close_frames[0].close_type);
-  EXPECT_EQ(kQuicErrorCode, connection_close_frames[0].quic_error_code);
-  EXPECT_EQ(kTransportCloseFrameType,
-            connection_close_frames[0].transport_close_frame_type);
-}
-
-// Regression test for b/137401387 and b/138962304.
-TEST_P(QuicConnectionTest, RtoPacketAsTwo) {
-  if (connection_.PtoEnabled()) {
-    return;
-  }
-  connection_.SetMaxTailLossProbes(1);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  std::string stream_data(3000, 's');
-  // Send packets 1 - 66 and exhaust cwnd.
-  for (size_t i = 0; i < 22; ++i) {
-    // 3 packets for each stream, the first 2 are guaranteed to be full packets.
-    SendStreamDataToPeer(i + 2, stream_data, 0, FIN, nullptr);
-  }
-  CongestionBlockWrites();
-
-  // Fires TLP. Please note, this tail loss probe has 1 byte less stream data
-  // compared to packet 1 because packet number length increases.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(67), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Fires RTO. Please note, although packets 2 and 3 *should* be RTOed, but
-  // packet 2 gets RTOed to two packets because packet number length increases.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(68), _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(69), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  // Resets all streams except 2 and ack packets 1 and 2. Now, packet 3 is the
-  // only one containing retransmittable frames.
-  for (size_t i = 1; i < 22; ++i) {
-    notifier_.OnStreamReset(i + 2, QUIC_STREAM_CANCELLED);
-  }
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(3)}});
-  ProcessAckPacket(1, &frame);
-  CongestionUnblockWrites();
-
-  // Fires TLP, verify a PING gets sent because packet 3 is marked
-  // RTO_RETRANSMITTED.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(70), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-}
-
-TEST_P(QuicConnectionTest, PtoSkipsPacketNumber) {
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k1PTO);
-  connection_options.push_back(kPTOS);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  QuicStreamId stream_id = 2;
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
-  SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(2), last_packet);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Fire PTO and verify the PTO retransmission skips one packet number.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(QuicPacketNumber(4), writer_->last_packet_header().packet_number);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, SendCoalescedPackets) {
-  if (!connection_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(3);
-  EXPECT_CALL(debug_visitor, OnCoalescedPacketSent(_, _)).Times(1);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    use_tagging_decrypter();
-    connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                             std::make_unique<TaggingEncrypter>(0x01));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0);
-    // Verify this packet is on hold.
-    EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                             std::make_unique<TaggingEncrypter>(0x02));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString("bar", 3);
-    EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                             std::make_unique<TaggingEncrypter>(0x03));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
-  }
-  // Verify all 3 packets are coalesced in the same UDP datagram.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
-  // Verify the packet is padded to full.
-  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
-
-  // Verify packet process.
-  EXPECT_EQ(1u, writer_->crypto_frames().size());
-  EXPECT_EQ(0u, writer_->stream_frames().size());
-  // Verify there is coalesced packet.
-  EXPECT_NE(nullptr, writer_->coalesced_packet());
-}
-
-TEST_P(QuicConnectionTest, FailToCoalescePacket) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration() ||
-      !connection_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-
-  set_perspective(Perspective::IS_SERVER);
-  use_tagging_decrypter();
-
-  EXPECT_CALL(visitor_, OnHandshakePacketSent());
-
-  if (GetQuicReloadableFlag(
-          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
-    EXPECT_CALL(visitor_,
-                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  }
-
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
-  auto test_body = [&] {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                             std::make_unique<TaggingEncrypter>(0x01));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0);
-    // Verify this packet is on hold.
-    EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                             std::make_unique<TaggingEncrypter>(0x02));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString("bar", 3);
-    EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                             std::make_unique<TaggingEncrypter>(0x03));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
-
-    creator_->Flush();
-
-    auto& coalesced_packet =
-        QuicConnectionPeer::GetCoalescedPacket(&connection_);
-    QuicPacketLength coalesced_packet_max_length =
-        coalesced_packet.max_packet_length();
-    QuicCoalescedPacketPeer::SetMaxPacketLength(coalesced_packet,
-                                                coalesced_packet.length());
-
-    // Make the coalescer's FORWARD_SECURE packet longer.
-    *QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
-        coalesced_packet, ENCRYPTION_FORWARD_SECURE) += "!!! TEST !!!";
-
-    QUIC_LOG(INFO) << "Reduced coalesced_packet_max_length from "
-                   << coalesced_packet_max_length << " to "
-                   << coalesced_packet.max_packet_length()
-                   << ", coalesced_packet.length:" << coalesced_packet.length()
-                   << ", coalesced_packet.packet_lengths:"
-                   << absl::StrJoin(coalesced_packet.packet_lengths(), ":");
-  };
-
-  EXPECT_QUIC_BUG(test_body(), "SerializeCoalescedPacket failed.");
-
-  if (GetQuicReloadableFlag(
-          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
-    EXPECT_FALSE(connection_.connected());
-    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-                IsError(QUIC_FAILED_TO_SERIALIZE_PACKET));
-    EXPECT_EQ(saved_connection_close_frame_.error_details,
-              "Failed to serialize coalesced packet.");
-  } else {
-    EXPECT_TRUE(connection_.connected());
-  }
-}
-
-TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
-  connection_.EnableLegacyVersionEncapsulation("test.example.org");
-
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
-
-  // Our TestPacketWriter normally parses the sent packet using the version
-  // from the connection, so here we need to tell it to use the encapsulation
-  // version, and reset the initial decrypter for that version.
-  writer_->framer()->SetSupportedVersions(
-      SupportedVersions(LegacyVersionForEncapsulation()));
-  writer_->framer()->framer()->SetInitialObfuscators(
-      connection_.connection_id());
-
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendCryptoDataWithString("TEST_CRYPTO_DATA", /*offset=*/0);
-  }
-
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  // Verify that the packet is fully padded.
-  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
-
-  // Check that the connection stats show Legacy Version Encapsulation was used.
-  EXPECT_GT(connection_.GetStats().sent_legacy_version_encapsulated_packets,
-            0u);
-
-  // Verify that the sent packet was in fact encapsulated, and check header.
-  const QuicPacketHeader& encapsulated_header = writer_->last_packet_header();
-  EXPECT_TRUE(encapsulated_header.version_flag);
-  EXPECT_EQ(encapsulated_header.version, LegacyVersionForEncapsulation());
-  EXPECT_EQ(encapsulated_header.destination_connection_id,
-            connection_.connection_id());
-
-  // Encapsulated packet should contain a stream frame for the crypto stream,
-  // optionally padding, and nothing else.
-  EXPECT_EQ(0u, writer_->crypto_frames().size());
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(writer_->frame_count(), writer_->framer()->padding_frames().size() +
-                                        writer_->stream_frames().size());
-}
-
-TEST_P(QuicConnectionTest, ClientReceivedHandshakeDone) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
-  QuicFrames frames;
-  frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
-  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, ServerReceivedHandshakeDone) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(visitor_, OnHandshakeDoneReceived()).Times(0);
-  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
-    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  }
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
-  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(1, connection_close_frame_count_);
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest, MultiplePacketNumberSpacePto) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  use_tagging_decrypter();
-  // Send handshake packet.
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-  EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
-
-  // Send application data.
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
-                                         0, NO_FIN);
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-  QuicTime retransmission_time =
-      connection_.GetRetransmissionAlarm()->deadline();
-  EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
-  // Retransmit handshake data.
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify 1-RTT packet gets coalesced with handshake retransmission.
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-
-  // Send application data.
-  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
-                                         4, NO_FIN);
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
-  EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
-  // Retransmit handshake data again.
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(9), _, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(8), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify 1-RTT packet gets coalesced with handshake retransmission.
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-
-  // Discard handshake key.
-  connection_.OnHandshakeComplete();
-  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
-  EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
-  // Retransmit application data.
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(11), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-}
-
-void QuicConnectionTest::TestClientRetryHandling(
-    bool invalid_retry_tag, bool missing_original_id_in_config,
-    bool wrong_original_id_in_config, bool missing_retry_id_in_config,
-    bool wrong_retry_id_in_config) {
-  if (invalid_retry_tag) {
-    ASSERT_FALSE(missing_original_id_in_config);
-    ASSERT_FALSE(wrong_original_id_in_config);
-    ASSERT_FALSE(missing_retry_id_in_config);
-    ASSERT_FALSE(wrong_retry_id_in_config);
-  } else {
-    ASSERT_FALSE(missing_original_id_in_config && wrong_original_id_in_config);
-    ASSERT_FALSE(missing_retry_id_in_config && wrong_retry_id_in_config);
-  }
-  if (!version().UsesTls()) {
-    return;
-  }
-
-  // These values come from draft-ietf-quic-v2 Appendix A.4.
-  uint8_t retry_packet_rfcv2[] = {
-      0xcf, 0x70, 0x9a, 0x50, 0xc4, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
-      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1d, 0xc7, 0x11, 0x30,
-      0xcd, 0x1e, 0xd3, 0x9d, 0x6e, 0xfc, 0xee, 0x5c, 0x85, 0x80, 0x65, 0x01};
-  // These values come from RFC9001 Appendix A.4.
-  uint8_t retry_packet_rfcv1[] = {
-      0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
-      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x04, 0xa2, 0x65, 0xba,
-      0x2e, 0xff, 0x4d, 0x82, 0x90, 0x58, 0xfb, 0x3f, 0x0f, 0x24, 0x96, 0xba};
-  uint8_t retry_packet29[] = {
-      0xff, 0xff, 0x00, 0x00, 0x1d, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
-      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xd1, 0x69, 0x26, 0xd8,
-      0x1f, 0x6f, 0x9c, 0xa2, 0x95, 0x3a, 0x8a, 0xa4, 0x57, 0x5e, 0x1e, 0x49};
-
-  uint8_t* retry_packet;
-  size_t retry_packet_length;
-  if (version() == ParsedQuicVersion::V2Draft01()) {
-    retry_packet = retry_packet_rfcv2;
-    retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv2);
-  } else if (version() == ParsedQuicVersion::RFCv1()) {
-    retry_packet = retry_packet_rfcv1;
-    retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv1);
-  } else if (version() == ParsedQuicVersion::Draft29()) {
-    retry_packet = retry_packet29;
-    retry_packet_length = ABSL_ARRAYSIZE(retry_packet29);
-  } else {
-    // TODO(dschinazi) generate retry packets for all versions once we have
-    // server-side support for generating these programmatically.
-    return;
-  }
-
-  uint8_t original_connection_id_bytes[] = {0x83, 0x94, 0xc8, 0xf0,
-                                            0x3e, 0x51, 0x57, 0x08};
-  uint8_t new_connection_id_bytes[] = {0xf0, 0x67, 0xa5, 0x50,
-                                       0x2a, 0x42, 0x62, 0xb5};
-  uint8_t retry_token_bytes[] = {0x74, 0x6f, 0x6b, 0x65, 0x6e};
-
-  QuicConnectionId original_connection_id(
-      reinterpret_cast<char*>(original_connection_id_bytes),
-      ABSL_ARRAYSIZE(original_connection_id_bytes));
-  QuicConnectionId new_connection_id(
-      reinterpret_cast<char*>(new_connection_id_bytes),
-      ABSL_ARRAYSIZE(new_connection_id_bytes));
-
-  std::string retry_token(reinterpret_cast<char*>(retry_token_bytes),
-                          ABSL_ARRAYSIZE(retry_token_bytes));
-
-  if (invalid_retry_tag) {
-    // Flip the last bit of the retry packet to prevent the integrity tag
-    // from validating correctly.
-    retry_packet[retry_packet_length - 1] ^= 1;
-  }
-
-  QuicConnectionId config_original_connection_id = original_connection_id;
-  if (wrong_original_id_in_config) {
-    // Flip the first bit of the connection ID.
-    ASSERT_FALSE(config_original_connection_id.IsEmpty());
-    config_original_connection_id.mutable_data()[0] ^= 0x80;
-  }
-  QuicConnectionId config_retry_source_connection_id = new_connection_id;
-  if (wrong_retry_id_in_config) {
-    // Flip the first bit of the connection ID.
-    ASSERT_FALSE(config_retry_source_connection_id.IsEmpty());
-    config_retry_source_connection_id.mutable_data()[0] ^= 0x80;
-  }
-
-  // Make sure the connection uses the connection ID from the test vectors,
-  QuicConnectionPeer::SetServerConnectionId(&connection_,
-                                            original_connection_id);
-  // Make sure our fake framer has the new post-retry INITIAL keys so that any
-  // retransmission triggered by retry can be decrypted.
-  writer_->framer()->framer()->SetInitialObfuscators(new_connection_id);
-
-  // Process the RETRY packet.
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(reinterpret_cast<char*>(retry_packet),
-                         retry_packet_length, clock_.Now()));
-
-  if (invalid_retry_tag) {
-    // Make sure we refuse to process a RETRY with invalid tag.
-    EXPECT_FALSE(connection_.GetStats().retry_packet_processed);
-    EXPECT_EQ(connection_.connection_id(), original_connection_id);
-    EXPECT_TRUE(QuicPacketCreatorPeer::GetRetryToken(
-                    QuicConnectionPeer::GetPacketCreator(&connection_))
-                    .empty());
-    return;
-  }
-
-  // Make sure we correctly parsed the RETRY.
-  EXPECT_TRUE(connection_.GetStats().retry_packet_processed);
-  EXPECT_EQ(connection_.connection_id(), new_connection_id);
-  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
-                QuicConnectionPeer::GetPacketCreator(&connection_)),
-            retry_token);
-
-  // Test validating the original_connection_id from the config.
-  QuicConfig received_config;
-  QuicConfigPeer::SetNegotiated(&received_config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &received_config, connection_.connection_id());
-    if (!missing_retry_id_in_config) {
-      QuicConfigPeer::SetReceivedRetrySourceConnectionId(
-          &received_config, config_retry_source_connection_id);
-    }
-  }
-  if (!missing_original_id_in_config) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &received_config, config_original_connection_id);
-  }
-
-  if (missing_original_id_in_config || wrong_original_id_in_config ||
-      missing_retry_id_in_config || wrong_retry_id_in_config) {
-    EXPECT_CALL(visitor_,
-                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-        .Times(1);
-  } else {
-    EXPECT_CALL(visitor_,
-                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-        .Times(0);
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
-  connection_.SetFromConfig(received_config);
-  if (missing_original_id_in_config || wrong_original_id_in_config ||
-      missing_retry_id_in_config || wrong_retry_id_in_config) {
-    ASSERT_FALSE(connection_.connected());
-    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-  } else {
-    EXPECT_TRUE(connection_.connected());
-  }
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetry) {
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryInvalidTag) {
-  TestClientRetryHandling(/*invalid_retry_tag=*/true,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryMissingOriginalId) {
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/true,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryWrongOriginalId) {
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/true,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryMissingRetryId) {
-  if (!connection_.version().UsesTls()) {
-    // Versions that do not authenticate connection IDs never send the
-    // retry_source_connection_id transport parameter.
-    return;
-  }
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/true,
-                          /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, ClientParsesRetryWrongRetryId) {
-  if (!connection_.version().UsesTls()) {
-    // Versions that do not authenticate connection IDs never send the
-    // retry_source_connection_id transport parameter.
-    return;
-  }
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/true);
-}
-
-TEST_P(QuicConnectionTest, ClientRetransmitsInitialPacketsOnRetry) {
-  if (!connection_.version().HasIetfQuicFrames()) {
-    // TestClientRetryHandling() currently only supports IETF draft versions.
-    return;
-  }
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
-  connection_.SendCryptoStreamData();
-
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-
-  // Verify that initial data is retransmitted immediately after receiving
-  // RETRY.
-  if (GetParam().ack_response == AckResponse::kImmediate) {
-    EXPECT_EQ(2u, writer_->packets_write_attempts());
-    EXPECT_EQ(1u, writer_->framer()->crypto_frames().size());
-  }
-}
-
-TEST_P(QuicConnectionTest, NoInitialPacketsRetransmissionOnInvalidRetry) {
-  if (!connection_.version().HasIetfQuicFrames()) {
-    return;
-  }
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
-  connection_.SendCryptoStreamData();
-
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  TestClientRetryHandling(/*invalid_retry_tag=*/true,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, ClientReceivesOriginalConnectionIdWithoutRetry) {
-  if (!connection_.version().UsesTls()) {
-    // QUIC+TLS is required to transmit connection ID transport parameters.
-    return;
-  }
-  if (connection_.version().UsesTls()) {
-    // Versions that authenticate connection IDs always send the
-    // original_destination_connection_id transport parameter.
-    return;
-  }
-  // Make sure that receiving the original_destination_connection_id transport
-  // parameter fails the handshake when no RETRY packet was received before it.
-  QuicConfig received_config;
-  QuicConfigPeer::SetNegotiated(&received_config, true);
-  QuicConfigPeer::SetReceivedOriginalConnectionId(&received_config,
-                                                  TestConnectionId(0x12345));
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(1);
-  connection_.SetFromConfig(received_config);
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-}
-
-TEST_P(QuicConnectionTest, ClientReceivesRetrySourceConnectionIdWithoutRetry) {
-  if (!connection_.version().UsesTls()) {
-    // Versions that do not authenticate connection IDs never send the
-    // retry_source_connection_id transport parameter.
-    return;
-  }
-  // Make sure that receiving the retry_source_connection_id transport parameter
-  // fails the handshake when no RETRY packet was received before it.
-  QuicConfig received_config;
-  QuicConfigPeer::SetNegotiated(&received_config, true);
-  QuicConfigPeer::SetReceivedRetrySourceConnectionId(&received_config,
-                                                     TestConnectionId(0x12345));
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(1);
-  connection_.SetFromConfig(received_config);
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
-}
-
-// Regression test for http://crbug/1047977
-TEST_P(QuicConnectionTest, MaxStreamsFrameCausesConnectionClose) {
-  if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
-    return;
-  }
-  // Received frame causes connection close.
-  EXPECT_CALL(visitor_, OnMaxStreamsFrame(_))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-        connection_.CloseConnection(
-            QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
-            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-        return true;
-      }));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
-  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, StreamsBlockedFrameCausesConnectionClose) {
-  if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
-    return;
-  }
-  // Received frame causes connection close.
-  EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-        connection_.CloseConnection(
-            QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
-            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-        return true;
-      }));
-  QuicFrames frames;
-  frames.push_back(
-      QuicFrame(QuicStreamsBlockedFrame(kInvalidControlFrameId, 10, false)));
-  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest,
-       BundleAckWithConnectionCloseMultiplePacketNumberSpace) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  // Receives packet 1000 in initial data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  // Receives packet 2000 in application data.
-  ProcessDataPacketAtLevel(2000, false, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
-  connection_.CloseConnection(
-      kQuicErrorCode, "Some random error message",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
-  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
-
-  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
-  EXPECT_EQ(1u, writer_->connection_close_frames().size());
-  // Verify ack is bundled.
-  EXPECT_EQ(1u, writer_->ack_frames().size());
-
-  if (!connection_.version().CanSendCoalescedPackets()) {
-    // Each connection close packet should be sent in distinct UDP packets.
-    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
-              writer_->connection_close_packets());
-    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
-              writer_->packets_write_attempts());
-    return;
-  }
-
-  // A single UDP packet should be sent with multiple connection close packets
-  // coalesced together.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  // Only the first packet has been processed yet.
-  EXPECT_EQ(1u, writer_->connection_close_packets());
-
-  // ProcessPacket resets the visitor and frees the coalesced packet.
-  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-  auto packet = writer_->coalesced_packet()->Clone();
-  writer_->framer()->ProcessPacket(*packet);
-  EXPECT_EQ(1u, writer_->connection_close_packets());
-  EXPECT_EQ(1u, writer_->connection_close_frames().size());
-  // Verify ack is bundled.
-  EXPECT_EQ(1u, writer_->ack_frames().size());
-  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-// Regression test for b/151220135.
-TEST_P(QuicConnectionTest, SendPingWhenSkipPacketNumberForPto) {
-  if (!VersionSupportsMessageFrames(connection_.transport_version())) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kPTOS);
-  connection_options.push_back(k1PTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
-        &config, kMaxAcceptedDatagramFrameSize);
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  connection_.OnHandshakeComplete();
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, SendMessage("message"));
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // PTO fires, verify a PING packet gets sent because there is no data to
-  // send.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(1u, connection_.GetStats().pto_count);
-  EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
-  EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
-// Regression test for b/155757133
-TEST_P(QuicConnectionTest, DonotChangeQueuedAcks) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
-  ProcessPacket(2);
-  ProcessPacket(3);
-  ProcessPacket(4);
-  // Process a packet containing stream frame followed by ACK of packets 1.
-  QuicFrames frames;
-  frames.push_back(QuicFrame(QuicStreamFrame(
-      QuicUtils::GetFirstBidirectionalStreamId(
-          connection_.version().transport_version, Perspective::IS_CLIENT),
-      false, 0u, absl::string_view())));
-  QuicAckFrame ack_frame = InitAckFrame(1);
-  frames.push_back(QuicFrame(&ack_frame));
-  // Receiving stream frame causes something to send.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
-    connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
-    // Verify now the queued ACK contains packet number 2.
-    EXPECT_TRUE(QuicPacketCreatorPeer::QueuedFrames(
-                    QuicConnectionPeer::GetPacketCreator(&connection_))[0]
-                    .ack_frame->packets.Contains(QuicPacketNumber(2)));
-  }));
-  ProcessFramesPacketAtLevel(9, frames, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(writer_->ack_frames()[0].packets.Contains(QuicPacketNumber(2)));
-}
-
-TEST_P(QuicConnectionTest, DonotExtendIdleTimeOnUndecryptablePackets) {
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  // Subtract a second from the idle timeout on the client side.
-  QuicTime initial_deadline =
-      clock_.ApproximateNow() +
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
-  EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
-
-  // Received an undecryptable packet.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  const uint8_t tag = 0x07;
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(tag));
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  // Verify deadline does not get extended.
-  EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
-  QuicTime::Delta delay = initial_deadline - clock_.ApproximateNow();
-  clock_.AdvanceTime(delay);
-  connection_.GetTimeoutAlarm()->Fire();
-  // Verify connection gets closed.
-  EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, BundleAckWithImmediateResponse) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
-    notifier_.WriteOrBufferWindowUpate(0, 0);
-  }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  ProcessDataPacket(1);
-  // Verify ACK is bundled with WINDOW_UPDATE.
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_FALSE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, AckAlarmFiresEarly) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  // Receives packet 1000 in application data.
-  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  // Verify ACK deadline does not change.
-  EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
-            connection_.GetAckAlarm()->deadline());
-
-  // Ack alarm fires early.
-  // Verify the earliest ACK is flushed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.GetAckAlarm()->Fire();
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
-            connection_.GetAckAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionClient) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kCBHD);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify blackhole detection is in progress.
-  EXPECT_TRUE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionServer) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(kCBHD);
-  config.SetInitialReceivedConnectionOptions(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify blackhole detection is disabled.
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, 2RtoBlackholeDetection) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k2RTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify blackhole delay is expected.
-  EXPECT_EQ(clock_.Now() +
-                connection_.sent_packet_manager().GetNetworkBlackholeDelay(2),
-            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-TEST_P(QuicConnectionTest, 3RtoBlackholeDetection) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k3RTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify blackhole delay is expected.
-  EXPECT_EQ(clock_.Now() +
-                connection_.sent_packet_manager().GetNetworkBlackholeDelay(3),
-            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-TEST_P(QuicConnectionTest, 4RtoBlackholeDetection) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k4RTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify blackhole delay is expected.
-  EXPECT_EQ(clock_.Now() +
-                connection_.sent_packet_manager().GetNetworkBlackholeDelay(4),
-            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-TEST_P(QuicConnectionTest, 6RtoBlackholeDetection) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k6RTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify blackhole delay is expected.
-  EXPECT_EQ(clock_.Now() +
-                connection_.sent_packet_manager().GetNetworkBlackholeDelay(6),
-            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
-}
-
-// Regresstion test for b/158491591.
-TEST_P(QuicConnectionTest, MadeForwardProgressOnDiscardingKeys) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  use_tagging_decrypter();
-  // Send handshake packet.
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  QuicConfig config;
-  QuicTagVector connection_options;
-  connection_options.push_back(k5RTO);
-  config.SetConnectionOptionsToSend(connection_options);
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  }
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-  // Discard handshake keys.
-  connection_.OnHandshakeComplete();
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    // Verify blackhole detection stops.
-    EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
-  } else {
-    // Problematic: although there is nothing in flight, blackhole detection is
-    // still in progress.
-    EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-  }
-}
-
-TEST_P(QuicConnectionTest, ProcessUndecryptablePacketsBasedOnEncryptionLevel) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
-  use_tagging_decrypter();
-
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x02));
-
-  for (uint64_t i = 1; i <= 3; ++i) {
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
-  }
-  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  for (uint64_t j = 5; j <= 7; ++j) {
-    ProcessDataPacketAtLevel(j, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
-  }
-  EXPECT_EQ(7u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  // Verify all ENCRYPTION_HANDSHAKE packets get processed.
-  if (!VersionHasIetfQuicFrames(version().transport_version)) {
-    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(6);
-  }
-  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-  EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  // Verify the 1-RTT packet gets processed.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-}
-
-TEST_P(QuicConnectionTest, ServerBundlesInitialDataWithInitialAck) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-  QuicTime expected_pto_time =
-      connection_.sent_packet_manager().GetRetransmissionTime();
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-  // Verify PTO time does not change.
-  EXPECT_EQ(expected_pto_time,
-            connection_.sent_packet_manager().GetRetransmissionTime());
-
-  // Receives packet 1001 in initial data.
-  ProcessCryptoPacketAtLevel(1001, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  // Receives packet 1002 in initial data.
-  ProcessCryptoPacketAtLevel(1002, ENCRYPTION_INITIAL);
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  // Verify CRYPTO frame is bundled with INITIAL ACK.
-  EXPECT_FALSE(writer_->crypto_frames().empty());
-  // Verify PTO time changes.
-  EXPECT_NE(expected_pto_time,
-            connection_.sent_packet_manager().GetRetransmissionTime());
-}
-
-TEST_P(QuicConnectionTest, ClientBundlesHandshakeDataWithHandshakeAck) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  // Receives packet 1000 in handshake data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_HANDSHAKE);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-
-  // Receives packet 1001 in handshake data.
-  ProcessCryptoPacketAtLevel(1001, ENCRYPTION_HANDSHAKE);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  // Receives packet 1002 in handshake data.
-  ProcessCryptoPacketAtLevel(1002, ENCRYPTION_HANDSHAKE);
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  // Verify CRYPTO frame is bundled with HANDSHAKE ACK.
-  EXPECT_FALSE(writer_->crypto_frames().empty());
-}
-
-// Regresstion test for b/156232673.
-TEST_P(QuicConnectionTest, CoalescePacketOfLowerEncryptionLevel) {
-  if (!connection_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    use_tagging_decrypter();
-    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                             std::make_unique<TaggingEncrypter>(0x01));
-    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                             std::make_unique<TaggingEncrypter>(0x02));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    SendStreamDataToPeer(2, std::string(1286, 'a'), 0, NO_FIN, nullptr);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    // Try to coalesce a HANDSHAKE packet after 1-RTT packet.
-    // Verify soft max packet length gets resumed and handshake packet gets
-    // successfully sent.
-    connection_.SendCryptoDataWithString("a", 0, ENCRYPTION_HANDSHAKE);
-  }
-}
-
-// Regression test for b/160790422.
-TEST_P(QuicConnectionTest, ServerRetransmitsHandshakeDataEarly) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send INITIAL 1.
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-  QuicTime expected_pto_time =
-      connection_.sent_packet_manager().GetRetransmissionTime();
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  // Send HANDSHAKE 2 and 3.
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-  connection_.SendCryptoDataWithString("bar", 3, ENCRYPTION_HANDSHAKE);
-  // Verify PTO time does not change.
-  EXPECT_EQ(expected_pto_time,
-            connection_.sent_packet_manager().GetRetransmissionTime());
-
-  // Receives ACK for HANDSHAKE 2.
-  QuicFrames frames;
-  auto ack_frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  frames.push_back(QuicFrame(&ack_frame));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessFramesPacketAtLevel(30, frames, ENCRYPTION_HANDSHAKE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  // Receives PING from peer.
-  frames.clear();
-  frames.push_back(QuicFrame(QuicPingFrame()));
-  frames.push_back(QuicFrame(QuicPaddingFrame(3)));
-  ProcessFramesPacketAtLevel(31, frames, ENCRYPTION_HANDSHAKE);
-  EXPECT_EQ(clock_.Now() + kAlarmGranularity,
-            connection_.GetAckAlarm()->deadline());
-  // Fire ACK alarm.
-  clock_.AdvanceTime(kAlarmGranularity);
-  connection_.GetAckAlarm()->Fire();
-  EXPECT_FALSE(writer_->ack_frames().empty());
-  // Verify handshake data gets retransmitted early.
-  EXPECT_FALSE(writer_->crypto_frames().empty());
-}
-
-// Regression test for b/161228202
-TEST_P(QuicConnectionTest, InflatedRttSample) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  // 30ms RTT.
-  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
-  set_perspective(Perspective::IS_SERVER);
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send INITIAL 1.
-  std::string initial_crypto_data(512, 'a');
-  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
-                                       ENCRYPTION_INITIAL);
-  ASSERT_TRUE(connection_.sent_packet_manager()
-                  .GetRetransmissionTime()
-                  .IsInitialized());
-  QuicTime::Delta pto_timeout =
-      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
-  // Send Handshake 2.
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  std::string handshake_crypto_data(1024, 'a');
-  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
-                                       ENCRYPTION_HANDSHAKE);
-
-  // INITIAL 1 gets lost and PTO fires.
-  clock_.AdvanceTime(pto_timeout);
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  clock_.AdvanceTime(kTestRTT);
-  // Assume retransmitted INITIAL gets received.
-  QuicFrames frames;
-  auto ack_frame = InitAckFrame({{QuicPacketNumber(4), QuicPacketNumber(5)}});
-  frames.push_back(QuicFrame(&ack_frame));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  ProcessFramesPacketAtLevel(1001, frames, ENCRYPTION_INITIAL);
-  EXPECT_EQ(kTestRTT, rtt_stats->latest_rtt());
-  // Because retransmitted INITIAL gets received so HANDSHAKE 2 gets processed.
-  frames.clear();
-  // HANDSHAKE 5 is also processed.
-  QuicAckFrame ack_frame2 =
-      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
-                    {QuicPacketNumber(5), QuicPacketNumber(6)}});
-  ack_frame2.ack_delay_time = QuicTime::Delta::Zero();
-  frames.push_back(QuicFrame(&ack_frame2));
-  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_HANDSHAKE);
-  // Verify RTT inflation gets mitigated.
-  EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
-}
-
-// Regression test for b/161228202
-TEST_P(QuicConnectionTest, CoalscingPacketCausesInfiniteLoop) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  use_tagging_decrypter();
-  // Receives packet 1000 in initial data.
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-
-  // Set anti amplification factor to 2, such that RetransmitDataOfSpaceIfAny
-  // makes no forward progress and causes infinite loop.
-  SetQuicFlag(FLAGS_quic_anti_amplification_factor, 2);
-
-  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send INITIAL 1.
-  std::string initial_crypto_data(512, 'a');
-  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
-                                       ENCRYPTION_INITIAL);
-  ASSERT_TRUE(connection_.sent_packet_manager()
-                  .GetRetransmissionTime()
-                  .IsInitialized());
-  QuicTime::Delta pto_timeout =
-      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
-  // Send Handshake 2.
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  // Verify HANDSHAKE packet is coalesced with INITIAL retransmission.
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  std::string handshake_crypto_data(1024, 'a');
-  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
-                                       ENCRYPTION_HANDSHAKE);
-
-  // INITIAL 1 gets lost and PTO fires.
-  clock_.AdvanceTime(pto_timeout);
-  connection_.GetRetransmissionAlarm()->Fire();
-}
-
-TEST_P(QuicConnectionTest, ClientAckDelayForAsyncPacketProcessing) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
-    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-    connection_.NeuterUnencryptedPackets();
-  }));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
-  // Received undecryptable HANDSHAKE 2.
-  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
-  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-  // Received INITIAL 4 (which is retransmission of INITIAL 1) after 100ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_INITIAL);
-  // Generate HANDSHAKE key.
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  // Verify HANDSHAKE packet gets processed.
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  } else {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  }
-  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    // Verify immediate ACK has been sent out when flush went out of scope.
-    ASSERT_FALSE(connection_.HasPendingAcks());
-  } else {
-    ASSERT_TRUE(connection_.HasPendingAcks());
-    // Send ACKs.
-    clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
-    connection_.GetAckAlarm()->Fire();
-  }
-  ASSERT_FALSE(writer_->ack_frames().empty());
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    // Verify the ack_delay_time in the sent HANDSHAKE ACK frame is 100ms.
-    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
-              writer_->ack_frames()[0].ack_delay_time);
-    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-    return;
-  }
-  // Verify the ack_delay_time in the INITIAL ACK frame is 1ms.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
-            writer_->ack_frames()[0].ack_delay_time);
-  // Process the coalesced HANDSHAKE packet.
-  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-  auto packet = writer_->coalesced_packet()->Clone();
-  writer_->framer()->ProcessPacket(*packet);
-  ASSERT_FALSE(writer_->ack_frames().empty());
-  // Verify the ack_delay_time in the HANDSHAKE ACK frame includes the
-  // buffering time.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(101),
-            writer_->ack_frames()[0].ack_delay_time);
-  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-}
-
-TEST_P(QuicConnectionTest, TestingLiveness) {
-  const size_t kMinRttMs = 40;
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-
-  CryptoHandshakeMessage msg;
-  std::string error_details;
-  QuicConfig client_config;
-  client_config.SetInitialStreamFlowControlWindowToSend(
-      kInitialStreamFlowControlWindowForTest);
-  client_config.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest);
-  client_config.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(30));
-  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
-  const QuicErrorCode error =
-      config.ProcessPeerHello(msg, CLIENT, &error_details);
-  EXPECT_THAT(error, IsQuicNoError());
-
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-
-  connection_.SetFromConfig(config);
-  connection_.OnHandshakeComplete();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_FALSE(connection_.MaybeTestLiveness());
-
-  QuicTime deadline = connection_.GetTimeoutAlarm()->deadline();
-  QuicTime::Delta timeout = deadline - clock_.ApproximateNow();
-  // Advance time to near the idle timeout.
-  clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_TRUE(connection_.MaybeTestLiveness());
-  // Verify idle deadline does not change.
-  EXPECT_EQ(deadline, connection_.GetTimeoutAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, SilentIdleTimeout) {
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-
-  QuicConfig config;
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
-                                                         QuicConnectionId());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-
-  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
-    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  }
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.GetTimeoutAlarm()->Fire();
-  // Verify the connection close packets get serialized and added to
-  // termination packets list.
-  EXPECT_NE(nullptr,
-            QuicConnectionPeer::GetConnectionClosePacket(&connection_));
-}
-
-TEST_P(QuicConnectionTest, DonotSendPing) {
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.OnHandshakeComplete();
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(true));
-  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
-      "GET /", 0, FIN, nullptr);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
-            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  // Now recevie an ACK and response of the previous packet, which will move the
-  // ping alarm forward.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicFrames frames;
-  QuicAckFrame ack_frame = InitAckFrame(1);
-  frames.push_back(QuicFrame(&ack_frame));
-  frames.push_back(QuicFrame(QuicStreamFrame(
-      GetNthClientInitiatedStreamId(0, connection_.transport_version()), true,
-      0u, absl::string_view())));
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  // The ping timer is set slightly less than 15 seconds in the future, because
-  // of the 1s ping timer alarm granularity.
-  EXPECT_EQ(
-      QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
-      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
-  // Suppose now ShouldKeepConnectionAlive returns false.
-  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
-      .WillRepeatedly(Return(false));
-  // Verify PING does not get sent.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.GetPingAlarm()->Fire();
-}
-
-// Regression test for b/159698337
-TEST_P(QuicConnectionTest, DuplicateAckCausesLostPackets) {
-  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  // Finish handshake.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  notifier_.NeuterUnencryptedData();
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
-  std::string data(1200, 'a');
-  // Send data packets 1 - 5.
-  for (size_t i = 0; i < 5; ++i) {
-    SendStreamDataToPeer(
-        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
-        i * 1200, i == 4 ? FIN : NO_FIN, nullptr);
-  }
-  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(3);
-
-  // ACK packet 5 and 1 and 2 are detected lost.
-  QuicAckFrame frame =
-      InitAckFrame({{QuicPacketNumber(5), QuicPacketNumber(6)}});
-  LostPacketVector lost_packets;
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .Times(AnyNumber())
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  ProcessAckPacket(1, &frame);
-  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
-  EXPECT_TRUE(retransmission_alarm->IsSet());
-
-  // ACK packet 1 - 5 and 7.
-  QuicAckFrame frame2 =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(6)},
-                    {QuicPacketNumber(7), QuicPacketNumber(8)}});
-  ProcessAckPacket(2, &frame2);
-  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-
-  // ACK packet 7 again and assume packet 6 is detected lost.
-  QuicAckFrame frame3 =
-      InitAckFrame({{QuicPacketNumber(7), QuicPacketNumber(8)}});
-  lost_packets.clear();
-  lost_packets.push_back(
-      LostPacket(QuicPacketNumber(6), kMaxOutgoingPacketSize));
-  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
-      .Times(AnyNumber())
-      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
-                      Return(LossDetectionInterface::DetectionStats())));
-  ProcessAckPacket(3, &frame3);
-  // Make sure loss detection is cancelled even there is no new acked packets.
-  EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
-}
-
-TEST_P(QuicConnectionTest, ShorterIdleTimeoutOnSentPackets) {
-  EXPECT_TRUE(connection_.connected());
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  config.SetClientConnectionOptions(QuicTagVector{kFIDT});
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    EXPECT_CALL(visitor_, GetHandshakeState())
-        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-  }
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  connection_.SetFromConfig(config);
-
-  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  // Send a packet close to timeout.
-  QuicTime::Delta timeout =
-      connection_.GetTimeoutAlarm()->deadline() - clock_.Now();
-  clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(1));
-  // Send stream data.
-  SendStreamDataToPeer(
-      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
-      0, FIN, nullptr);
-  // Verify this sent packet does not extend idle timeout since 1s is > PTO
-  // delay.
-  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
-            connection_.GetTimeoutAlarm()->deadline() - clock_.Now());
-
-  // Received an ACK 100ms later.
-  clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(100));
-  QuicAckFrame ack = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  ProcessAckPacket(1, &ack);
-  // Verify idle timeout gets extended.
-  EXPECT_EQ(clock_.Now() + timeout, connection_.GetTimeoutAlarm()->deadline());
-}
-
-// Regression test for b/166255274
-TEST_P(QuicConnectionTest,
-       ReserializeInitialPacketInCoalescerAfterDiscardingInitialKey) {
-  if (!connection_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
-    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-    connection_.NeuterUnencryptedPackets();
-  }));
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-    // Verify the packet is on hold.
-    EXPECT_EQ(0u, writer_->packets_write_attempts());
-    // Flush pending ACKs.
-    connection_.GetAckAlarm()->Fire();
-  }
-  EXPECT_FALSE(connection_.packet_creator().HasPendingFrames());
-  // The ACK frame is deleted along with initial_packet_ in coalescer. Sending
-  // connection close would cause this (released) ACK frame be serialized (and
-  // crashes).
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, PathValidationOnNewSocketSuccess) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(1u, new_writer.packets_write_attempts());
-        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
-        EXPECT_EQ(1u, new_writer.padding_frames().size());
-        EXPECT_EQ(kNewSelfAddress.host(),
-                  new_writer.last_write_source_address());
-      }));
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-  EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-  QuicFrames frames;
-  frames.push_back(QuicFrame(new QuicPathResponseFrame(
-      99, new_writer.path_challenge_frames().front().data_buffer)));
-  ProcessFramesPacketWithAddresses(frames, kNewSelfAddress, kPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(success);
-}
-
-TEST_P(QuicConnectionTest, NewPathValidationCancelsPreviousOne) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(1u, new_writer.packets_write_attempts());
-        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
-        EXPECT_EQ(1u, new_writer.padding_frames().size());
-        EXPECT_EQ(kNewSelfAddress.host(),
-                  new_writer.last_write_source_address());
-      }));
-  bool success = true;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-  EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-  // Start another path validation request.
-  const QuicSocketAddress kNewSelfAddress2(QuicIpAddress::Any4(), 12346);
-  EXPECT_NE(kNewSelfAddress2, connection_.self_address());
-  TestPacketWriter new_writer2(version(), &clock_, Perspective::IS_CLIENT);
-  if (!connection_.connection_migration_use_new_cid()) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-        .Times(AtLeast(1u))
-        .WillOnce(Invoke([&]() {
-          EXPECT_EQ(1u, new_writer2.packets_write_attempts());
-          EXPECT_EQ(1u, new_writer2.path_challenge_frames().size());
-          EXPECT_EQ(1u, new_writer2.padding_frames().size());
-          EXPECT_EQ(kNewSelfAddress2.host(),
-                    new_writer2.last_write_source_address());
-        }));
-  }
-  bool success2 = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress2, connection_.peer_address(), &new_writer2),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress2, connection_.peer_address(),
-          &success2));
-  EXPECT_FALSE(success);
-  if (connection_.connection_migration_use_new_cid()) {
-    // There is no pening path validation as there is no available connection
-    // ID.
-    EXPECT_FALSE(connection_.HasPendingPathValidation());
-  } else {
-    EXPECT_TRUE(connection_.HasPendingPathValidation());
-  }
-}
-
-// Regression test for b/182571515.
-TEST_P(QuicConnectionTest, PathValidationRetry) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(2u)
-      .WillRepeatedly(Invoke([&]() {
-        EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-        EXPECT_EQ(1u, writer_->padding_frames().size());
-      }));
-  bool success = true;
-  connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
-                               connection_.self_address(),
-                               connection_.peer_address(), writer_.get()),
-                           std::make_unique<TestValidationResultDelegate>(
-                               &connection_, connection_.self_address(),
-                               connection_.peer_address(), &success));
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-
-  // Retry after time out.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
-  static_cast<TestAlarmFactory::TestAlarm*>(
-      QuicPathValidatorPeer::retry_timer(
-          QuicConnectionPeer::path_validator(&connection_)))
-      ->Fire();
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-}
-
-TEST_P(QuicConnectionTest, PathValidationReceivesStatelessReset) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
-                                                 kTestStatelessResetToken);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(1u, new_writer.packets_write_attempts());
-        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
-        EXPECT_EQ(1u, new_writer.padding_frames().size());
-        EXPECT_EQ(kNewSelfAddress.host(),
-                  new_writer.last_write_source_address());
-      }));
-  bool success = true;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-  EXPECT_EQ(0u, writer_->packets_write_attempts());
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
-                                                /*received_packet_length=*/100,
-                                                kTestStatelessResetToken));
-  std::unique_ptr<QuicReceivedPacket> received(
-      ConstructReceivedPacket(*packet, QuicTime::Zero()));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
-  connection_.ProcessUdpPacket(kNewSelfAddress, kPeerAddress, *received);
-  EXPECT_FALSE(connection_.HasPendingPathValidation());
-  EXPECT_FALSE(success);
-}
-
-// Tests that PATH_CHALLENGE is dropped if it is sent via a blocked alternative
-// writer.
-TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedNewSocket) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  new_writer.BlockOnNextWrite();
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1))
-      .WillOnce(Invoke([&]() {
-        // Even though the socket is blocked, the PATH_CHALLENGE should still be
-        // treated as sent.
-        EXPECT_EQ(1u, new_writer.packets_write_attempts());
-        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
-        EXPECT_EQ(1u, new_writer.padding_frames().size());
-        EXPECT_EQ(kNewSelfAddress.host(),
-                  new_writer.last_write_source_address());
-      }));
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-  EXPECT_EQ(0u, writer_->packets_write_attempts());
-
-  new_writer.SetWritable();
-  // Write event on the default socket shouldn't make any difference.
-  connection_.OnCanWrite();
-  // A NEW_CONNECTION_ID frame is received in PathProbeTestInit and OnCanWrite
-  // will write a acking packet.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_EQ(1u, new_writer.packets_write_attempts());
-}
-
-//  Tests that PATH_CHALLENGE is dropped if it is sent via the default writer
-//  and the writer is blocked.
-TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedDefaultSocket) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
-  writer_->BlockOnNextWrite();
-  // 1st time is after writer returns WRITE_STATUS_BLOCKED. 2nd time is in
-  // ShouldGeneratePacket().
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(2));
-  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([&]() {
-        // This packet isn't sent actually, instead it is buffered in the
-        // connection.
-        EXPECT_EQ(1u, writer_->packets_write_attempts());
-        if (connection_.validate_client_address()) {
-          EXPECT_EQ(1u, writer_->path_response_frames().size());
-          EXPECT_EQ(0,
-                    memcmp(&path_challenge_payload,
-                           &writer_->path_response_frames().front().data_buffer,
-                           sizeof(path_challenge_payload)));
-        }
-        EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-        EXPECT_EQ(1u, writer_->padding_frames().size());
-        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-      }))
-      .WillRepeatedly(Invoke([&]() {
-        // Only one PATH_CHALLENGE should be sent out.
-        EXPECT_EQ(0u, writer_->path_challenge_frames().size());
-      }));
-  bool success = false;
-  if (connection_.validate_client_address()) {
-    // Receiving a PATH_CHALLENGE from the new peer address should trigger
-    // address validation.
-    QuicFrames frames;
-    frames.push_back(
-        QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
-    ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                     ENCRYPTION_FORWARD_SECURE);
-  } else {
-    // Manually start to validate the new peer address.
-    connection_.ValidatePath(
-        std::make_unique<TestQuicPathValidationContext>(
-            connection_.self_address(), kNewPeerAddress, writer_.get()),
-        std::make_unique<TestValidationResultDelegate>(
-            &connection_, connection_.self_address(), kNewPeerAddress,
-            &success));
-  }
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  // Try again with the new socket blocked from the beginning. The 2nd
-  // PATH_CHALLENGE shouldn't be serialized, but be dropped.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
-  static_cast<TestAlarmFactory::TestAlarm*>(
-      QuicPathValidatorPeer::retry_timer(
-          QuicConnectionPeer::path_validator(&connection_)))
-      ->Fire();
-
-  // No more write attempt should be made.
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-
-  writer_->SetWritable();
-  // OnCanWrite() should actually write out the 1st PATH_CHALLENGE packet
-  // buffered earlier, thus incrementing the write counter. It may also send
-  // ACKs to previously received packets.
-  connection_.OnCanWrite();
-  EXPECT_LE(2u, writer_->packets_write_attempts());
-}
-
-// Tests that write error on the alternate socket should be ignored.
-TEST_P(QuicConnectionTest, SendPathChallengeFailOnNewSocket) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  new_writer.SetShouldWriteFail();
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(0);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
-
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-  EXPECT_EQ(1u, new_writer.packets_write_attempts());
-  EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
-  EXPECT_EQ(1u, new_writer.padding_frames().size());
-  EXPECT_EQ(kNewSelfAddress.host(), new_writer.last_write_source_address());
-
-  EXPECT_EQ(0u, writer_->packets_write_attempts());
-  //  Regardless of the write error, the connection should still be connected.
-  EXPECT_TRUE(connection_.connected());
-}
-
-// Tests that write error while sending PATH_CHALLANGE from the default socket
-// should close the connection.
-TEST_P(QuicConnectionTest, SendPathChallengeFailOnDefaultPath) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  writer_->SetShouldWriteFail();
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(
-          Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
-            EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
-          }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
-  {
-    // Add a flusher to force flush, otherwise the frames will remain in the
-    // packet creator.
-    bool success = false;
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
-                                 connection_.self_address(),
-                                 connection_.peer_address(), writer_.get()),
-                             std::make_unique<TestValidationResultDelegate>(
-                                 &connection_, connection_.self_address(),
-                                 connection_.peer_address(), &success));
-  }
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-  EXPECT_EQ(1u, writer_->padding_frames().size());
-  EXPECT_EQ(connection_.peer_address(), writer_->last_write_peer_address());
-  EXPECT_FALSE(connection_.connected());
-  // Closing connection should abandon ongoing path validation.
-  EXPECT_FALSE(connection_.HasPendingPathValidation());
-}
-
-TEST_P(QuicConnectionTest, SendPathChallengeFailOnAlternativePeerAddress) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  writer_->SetShouldWriteFail();
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(
-          Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
-            EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
-          }));
-  // Sending PATH_CHALLENGE to trigger a flush write which will fail and close
-  // the connection.
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          connection_.self_address(), kNewPeerAddress, writer_.get()),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, connection_.self_address(), kNewPeerAddress, &success));
-
-  EXPECT_EQ(1u, writer_->packets_write_attempts());
-  EXPECT_FALSE(connection_.HasPendingPathValidation());
-  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-  EXPECT_EQ(1u, writer_->padding_frames().size());
-  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-  EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest,
-       SendPathChallengeFailPacketTooBigOnAlternativePeerAddress) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  // Make sure there is no outstanding ACK_FRAME to write.
-  connection_.OnCanWrite();
-  uint32_t num_packets_write_attempts = writer_->packets_write_attempts();
-
-  writer_->SetShouldWriteFail();
-  writer_->SetWriteError(*writer_->MessageTooBigErrorCode());
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .Times(0u);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
-  // Sending PATH_CHALLENGE to trigger a flush write which will fail with
-  // MSG_TOO_BIG.
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          connection_.self_address(), kNewPeerAddress, writer_.get()),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, connection_.self_address(), kNewPeerAddress, &success));
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  // Connection shouldn't be closed.
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_EQ(++num_packets_write_attempts, writer_->packets_write_attempts());
-  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-  EXPECT_EQ(1u, writer_->padding_frames().size());
-  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-}
-
-// Check that if there are two PATH_CHALLENGE frames in the packet, the latter
-// one is ignored.
-TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  QuicPathFrameBuffer path_frame_buffer1{0, 1, 2, 3, 4, 5, 6, 7};
-  QuicPathFrameBuffer path_frame_buffer2{8, 9, 10, 11, 12, 13, 14, 15};
-  QuicFrames frames;
-  frames.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer1)));
-  frames.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer2)));
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
-                                          /*port=*/23456);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
-
-  // Expect 2 packets to be sent: the first are padded PATH_RESPONSE(s) to the
-  // alternative peer address. The 2nd is a ACK-only packet to the original
-  // peer address.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(2)
-      .WillOnce(Invoke([=]() {
-        EXPECT_EQ(1u, writer_->path_response_frames().size());
-        // The final check is to ensure that the random data in the response
-        // matches the random data from the challenge.
-        EXPECT_EQ(0,
-                  memcmp(path_frame_buffer1.data(),
-                         &(writer_->path_response_frames().front().data_buffer),
-                         sizeof(path_frame_buffer1)));
-        EXPECT_EQ(1u, writer_->padding_frames().size());
-        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-      }))
-      .WillOnce(Invoke([=]() {
-        // The last write of ACK-only packet should still use the old peer
-        // address.
-        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
-      }));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-}
-
-TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/23456);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
-  EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
-      .Times(connection_.validate_client_address() ? 0u : 1u);
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
-        // Send some data on the stream. The STREAM_FRAME should be built into
-        // one packet together with the latter PATH_RESPONSE and PATH_CHALLENGE.
-        const std::string data{"response body"};
-        connection_.producer()->SaveStreamData(frame.stream_id, data);
-        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
-                                           NO_FIN);
-      }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(connection_.validate_client_address() ? 0u : 1u);
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-
-  // Verify that this packet contains a STREAM_FRAME and a
-  // PATH_RESPONSE_FRAME.
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-  EXPECT_EQ(1u, writer_->path_response_frames().size());
-  EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
-            writer_->path_challenge_frames().size());
-  // The final check is to ensure that the random data in the response
-  // matches the random data from the challenge.
-  EXPECT_EQ(0, memcmp(path_frame_buffer.data(),
-                      &(writer_->path_response_frames().front().data_buffer),
-                      sizeof(path_frame_buffer)));
-  EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
-            writer_->path_challenge_frames().size());
-  EXPECT_EQ(1u, writer_->padding_frames().size());
-  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-  if (connection_.validate_client_address()) {
-    EXPECT_TRUE(connection_.HasPendingPathValidation());
-  }
-}
-
-TEST_P(QuicConnectionTest, ReceiveStreamFrameFollowingPathChallenge) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  QuicFrames frames;
-  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
-  // PATH_RESPONSE should be flushed out before the rest packet is parsed.
-  frames.push_back(QuicFrame(frame1_));
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/23456);
-  QuicByteCount received_packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(AtLeast(1u))
-      .WillOnce(Invoke([=, &received_packet_size]() {
-        // Verify that this packet contains a PATH_RESPONSE_FRAME.
-        EXPECT_EQ(0u, writer_->stream_frames().size());
-        EXPECT_EQ(1u, writer_->path_response_frames().size());
-        // The final check is to ensure that the random data in the response
-        // matches the random data from the challenge.
-        EXPECT_EQ(0,
-                  memcmp(path_frame_buffer.data(),
-                         &(writer_->path_response_frames().front().data_buffer),
-                         sizeof(path_frame_buffer)));
-        EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
-                  writer_->path_challenge_frames().size());
-        EXPECT_EQ(1u, writer_->padding_frames().size());
-        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-        received_packet_size =
-            QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_);
-      }));
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
-  EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
-      .Times(connection_.validate_client_address() ? 0u : 1u);
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
-        // Send some data on the stream. The STREAM_FRAME should be built into a
-        // new packet but throttled by anti-amplifciation limit.
-        const std::string data{"response body"};
-        connection_.producer()->SaveStreamData(frame.stream_id, data);
-        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
-                                           NO_FIN);
-      }));
-
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  if (!connection_.validate_client_address()) {
-    return;
-  }
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  EXPECT_EQ(0u,
-            QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
-  EXPECT_EQ(
-      received_packet_size,
-      QuicConnectionPeer::BytesReceivedBeforeAddressValidation(&connection_));
-}
-
-// Tests that a PATH_CHALLENGE is received in between other frames in an out of
-// order packet.
-TEST_P(QuicConnectionTest, PathChallengeWithDataInOutOfOrderPacket) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
-  frames.push_back(QuicFrame(frame2_));
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
-                                          /*port=*/23456);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .Times(2)
-      .WillRepeatedly(Invoke([=](const QuicStreamFrame& frame) {
-        // Send some data on the stream. The STREAM_FRAME should be built into
-        // one packet together with the latter PATH_RESPONSE.
-        const std::string data{"response body"};
-        connection_.producer()->SaveStreamData(frame.stream_id, data);
-        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
-                                           NO_FIN);
-      }));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(Invoke([=]() {
-        // Verify that this packet contains a STREAM_FRAME and is sent to the
-        // original peer address.
-        EXPECT_EQ(1u, writer_->stream_frames().size());
-        // No connection migration should happen because the packet is received
-        // out of order.
-        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
-      }))
-      .WillOnce(Invoke([=]() {
-        EXPECT_EQ(1u, writer_->path_response_frames().size());
-        // The final check is to ensure that the random data in the response
-        // matches the random data from the challenge.
-        EXPECT_EQ(0,
-                  memcmp(path_frame_buffer.data(),
-                         &(writer_->path_response_frames().front().data_buffer),
-                         sizeof(path_frame_buffer)));
-        EXPECT_EQ(1u, writer_->padding_frames().size());
-        // PATH_RESPONSE should be sent in another packet to a different peer
-        // address.
-        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-      }))
-      .WillOnce(Invoke([=]() {
-        // Verify that this packet contains a STREAM_FRAME and is sent to the
-        // original peer address.
-        EXPECT_EQ(1u, writer_->stream_frames().size());
-        // No connection migration should happen because the packet is received
-        // out of order.
-        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
-      }));
-  // Lower the packet number so that receiving this packet shouldn't trigger
-  // peer migration.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-}
-
-// Tests that a PATH_CHALLENGE is cached if its PATH_RESPONSE can't be sent.
-TEST_P(QuicConnectionTest, FailToWritePathResponse) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-
-  QuicFrames frames;
-  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
-                                          /*port=*/23456);
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
-  // Lower the packet number so that receiving this packet shouldn't trigger
-  // peer migration.
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
-  writer_->SetWriteBlocked();
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-}
-
-// Regression test for b/168101557.
-TEST_P(QuicConnectionTest, HandshakeDataDoesNotGetPtoed) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send INITIAL 1.
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  // Send HANDSHAKE packets.
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Send half RTT packet.
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
-  // Receives HANDSHAKE 1.
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  // Verify there is pending ACK.
-  ASSERT_TRUE(connection_.HasPendingAcks());
-  // Set the send alarm.
-  connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
-
-  // Fire ACK alarm.
-  connection_.GetAckAlarm()->Fire();
-  // Verify 1-RTT packet is coalesced with handshake packet.
-  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
-  connection_.GetSendAlarm()->Fire();
-
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify a handshake packet gets PTOed and 1-RTT packet gets coalesced.
-  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
-}
-
-// Regression test for b/168294218.
-TEST_P(QuicConnectionTest, CoalescerHandlesInitialKeyDiscard) {
-  if (!connection_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_discard_initial_packet_with_key_dropped, true);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
-    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-    connection_.NeuterUnencryptedPackets();
-  }));
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-
-  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    use_tagging_decrypter();
-    ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-    connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                             std::make_unique<TaggingEncrypter>(0x01));
-    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                             std::make_unique<TaggingEncrypter>(0x02));
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
-    // Verify this packet is on hold.
-    EXPECT_EQ(0u, writer_->packets_write_attempts());
-  }
-  EXPECT_TRUE(connection_.connected());
-}
-
-// Regresstion test for b/168294218
-TEST_P(QuicConnectionTest, ZeroRttRejectionAndMissingInitialKeys) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  // Not defer send in response to packet.
-  connection_.set_defer_send_in_response_to_packets(false);
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
-    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-    connection_.NeuterUnencryptedPackets();
-  }));
-  EXPECT_CALL(visitor_, OnCryptoFrame(_))
-      .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
-        if (frame.level == ENCRYPTION_HANDSHAKE) {
-          // 0-RTT gets rejected.
-          connection_.MarkZeroRttPacketsForRetransmission(0);
-          // Send Crypto data.
-          connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                                   std::make_unique<TaggingEncrypter>(0x03));
-          connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-          connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-          connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                                   std::make_unique<TaggingEncrypter>(0x04));
-          connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-          // Advance INITIAL ack delay to trigger initial ACK to be sent AFTER
-          // the retransmission of rejected 0-RTT packets while the HANDSHAKE
-          // packet is still in the coalescer, such that the INITIAL key gets
-          // dropped between SendAllPendingAcks and actually send the ack frame,
-          // bummer.
-          clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-        }
-      }));
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-  // Send 0-RTT packet.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
-  QuicAckFrame frame1 = InitAckFrame(1);
-  // Received ACK for packet 1.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Fire retransmission alarm.
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  QuicFrames frames1;
-  frames1.push_back(QuicFrame(&crypto_frame_));
-  QuicFrames frames2;
-  QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
-                               absl::string_view(data1));
-  frames2.push_back(QuicFrame(&crypto_frame));
-  ProcessCoalescedPacket(
-      {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
-}
-
-TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SendCryptoStreamData();
-  // Send 0-RTT packet.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-  connection_.SendStreamDataWithString(4, "bar", 0, NO_FIN);
-  // Received ACK for packet 1, HANDSHAKE packet and 1-RTT ACK.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  QuicFrames frames1;
-  QuicAckFrame ack_frame1 = InitAckFrame(1);
-  frames1.push_back(QuicFrame(&ack_frame1));
-
-  QuicFrames frames2;
-  QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
-                               absl::string_view(data1));
-  frames2.push_back(QuicFrame(&crypto_frame));
-  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
-  ProcessCoalescedPacket(
-      {{1, frames1, ENCRYPTION_INITIAL}, {2, frames2, ENCRYPTION_HANDSHAKE}});
-
-  QuicFrames frames3;
-  QuicAckFrame ack_frame2 =
-      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  frames3.push_back(QuicFrame(&ack_frame2));
-  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(1);
-  ProcessCoalescedPacket({{3, frames3, ENCRYPTION_FORWARD_SECURE}});
-
-  QuicFrames frames4;
-  QuicAckFrame ack_frame3 =
-      InitAckFrame({{QuicPacketNumber(3), QuicPacketNumber(4)}});
-  frames4.push_back(QuicFrame(&ack_frame3));
-  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
-  ProcessCoalescedPacket({{4, frames4, ENCRYPTION_FORWARD_SECURE}});
-}
-
-TEST_P(QuicConnectionTest, InitiateKeyUpdate) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  TransportParameters params;
-  QuicConfig config;
-  std::string error_details;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-
-  MockFramerVisitor peer_framer_visitor_;
-  peer_framer_.set_visitor(&peer_framer_visitor_);
-
-  use_tagging_decrypter();
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-
-  // Key update should still not be allowed, since no packet has been acked
-  // from the current key phase.
-  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  // Send packet 1.
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-
-  // Key update should still not be allowed, even though a packet was sent in
-  // the current key phase it hasn't been acked yet.
-  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
-  // Receive ack for packet 1.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  ProcessAckPacket(&frame1);
-
-  // OnDecryptedFirstPacketInKeyPhase is called even on the first key phase,
-  // so discard_previous_keys_alarm_ should be set now.
-  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
-  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  // Key update should now be allowed.
-  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce(
-          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
-  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
-    return std::make_unique<TaggingEncrypter>(0x02);
-  });
-  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
-  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-  // discard_previous_keys_alarm_ should not be set until a packet from the new
-  // key phase has been received. (The alarm that was set above should be
-  // cleared if it hasn't fired before the next key update happened.)
-  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
-  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  // Pretend that peer accepts the key update.
-  EXPECT_CALL(peer_framer_visitor_,
-              AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce(
-          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
-  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
-      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
-  peer_framer_.SetKeyUpdateSupportForConnection(true);
-  peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
-
-  // Another key update should not be allowed yet.
-  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-
-  // Send packet 2.
-  SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
-  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-  // Receive ack for packet 2.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame2 = InitAckFrame(2);
-  ProcessAckPacket(&frame2);
-  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
-  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  // Key update should be allowed again now that a packet has been acked from
-  // the current key phase.
-  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce(
-          []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
-  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
-    return std::make_unique<TaggingEncrypter>(0x03);
-  });
-  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
-  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
-  // Pretend that peer accepts the key update.
-  EXPECT_CALL(peer_framer_visitor_,
-              AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce(
-          []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
-  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
-      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); });
-  peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
-
-  // Another key update should not be allowed yet.
-  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-
-  // Send packet 3.
-  SendStreamDataToPeer(3, "baz", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(3u), last_packet);
-
-  // Another key update should not be allowed yet.
-  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
-  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  // Receive ack for packet 3.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame3 = InitAckFrame(3);
-  ProcessAckPacket(&frame3);
-  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
-  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-
-  // Key update should be allowed now.
-  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce(
-          []() { return std::make_unique<StrictTaggingDecrypter>(0x04); });
-  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
-    return std::make_unique<TaggingEncrypter>(0x04);
-  });
-  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
-  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
-  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
-}
-
-TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 3U);
-
-  std::string error_details;
-  TransportParameters params;
-  // Key update is enabled.
-  QuicConfig config;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  MockFramerVisitor peer_framer_visitor_;
-  peer_framer_.set_visitor(&peer_framer_visitor_);
-
-  use_tagging_decrypter();
-
-  uint8_t current_tag = 0x01;
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(current_tag));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(current_tag));
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-
-  peer_framer_.SetKeyUpdateSupportForConnection(true);
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(current_tag));
-
-  const QuicConnectionStats& stats = connection_.GetStats();
-
-  for (int packet_num = 1; packet_num <= 8; ++packet_num) {
-    if (packet_num == 3 || packet_num == 6) {
-      current_tag++;
-      EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
-          .WillOnce([current_tag]() {
-            return std::make_unique<StrictTaggingDecrypter>(current_tag);
-          });
-      EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter())
-          .WillOnce([current_tag]() {
-            return std::make_unique<TaggingEncrypter>(current_tag);
-          });
-      EXPECT_CALL(visitor_,
-                  OnKeyUpdate(KeyUpdateReason::kLocalKeyUpdateLimitOverride));
-    }
-    // Send packet.
-    QuicPacketNumber last_packet;
-    SendStreamDataToPeer(packet_num, "foo", 0, NO_FIN, &last_packet);
-    EXPECT_EQ(QuicPacketNumber(packet_num), last_packet);
-    if (packet_num >= 6) {
-      EXPECT_EQ(2U, stats.key_update_count);
-    } else if (packet_num >= 3) {
-      EXPECT_EQ(1U, stats.key_update_count);
-    } else {
-      EXPECT_EQ(0U, stats.key_update_count);
-    }
-
-    if (packet_num == 4 || packet_num == 7) {
-      // Pretend that peer accepts the key update.
-      EXPECT_CALL(peer_framer_visitor_,
-                  AdvanceKeysAndCreateCurrentOneRttDecrypter())
-          .WillOnce([current_tag]() {
-            return std::make_unique<StrictTaggingDecrypter>(current_tag);
-          });
-      EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
-          .WillOnce([current_tag]() {
-            return std::make_unique<TaggingEncrypter>(current_tag);
-          });
-      peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
-    }
-    // Receive ack for packet.
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-    QuicAckFrame frame1 = InitAckFrame(packet_num);
-    ProcessAckPacket(&frame1);
-  }
-}
-
-TEST_P(QuicConnectionTest,
-       CloseConnectionOnConfidentialityLimitKeyUpdateNotAllowed) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  // Set key update confidentiality limit to 1 packet.
-  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
-  // Use confidentiality limit for connection close of 3 packets.
-  constexpr size_t kConfidentialityLimit = 3U;
-
-  std::string error_details;
-  TransportParameters params;
-  // Key update is enabled.
-  QuicConfig config;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypterWithConfidentialityLimit>(
-          Perspective::IS_CLIENT, kConfidentialityLimit));
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-
-  QuicPacketNumber last_packet;
-  // Send 3 packets without receiving acks for any of them. Key update will not
-  // be allowed, so the confidentiality limit should be reached, forcing the
-  // connection to be closed.
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.connected());
-  SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_FALSE(connection_.connected());
-  const QuicConnectionStats& stats = connection_.GetStats();
-  EXPECT_EQ(0U, stats.key_update_count);
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitDuringHandshake) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  constexpr uint8_t correct_tag = 0x01;
-  constexpr uint8_t wrong_tag = 0xFE;
-  constexpr QuicPacketCount kIntegrityLimit = 3;
-
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-                   correct_tag, kIntegrityLimit));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(correct_tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(wrong_tag));
-  for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    if (i == kIntegrityLimit) {
-      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-      EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
-    }
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
-    EXPECT_EQ(
-        i, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAfterHandshake) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  constexpr uint8_t correct_tag = 0x01;
-  constexpr uint8_t wrong_tag = 0xFE;
-  constexpr QuicPacketCount kIntegrityLimit = 3;
-
-  use_tagging_decrypter();
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-                   correct_tag, kIntegrityLimit));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(correct_tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(wrong_tag));
-  for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    if (i == kIntegrityLimit) {
-      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-    }
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(
-        i, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest,
-       CloseConnectionOnIntegrityLimitAcrossEncryptionLevels) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  constexpr uint8_t correct_tag = 0x01;
-  constexpr uint8_t wrong_tag = 0xFE;
-  constexpr QuicPacketCount kIntegrityLimit = 4;
-
-  use_tagging_decrypter();
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-                   correct_tag, kIntegrityLimit));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(correct_tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(wrong_tag));
-  for (uint64_t i = 1; i <= 2; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
-    EXPECT_EQ(
-        i, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-                   correct_tag, kIntegrityLimit));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(correct_tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(wrong_tag));
-  for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    if (i == kIntegrityLimit) {
-      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-    }
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(
-        i, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, IntegrityLimitDoesNotApplyWithoutDecryptionKey) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  constexpr uint8_t correct_tag = 0x01;
-  constexpr uint8_t wrong_tag = 0xFE;
-  constexpr QuicPacketCount kIntegrityLimit = 3;
-
-  use_tagging_decrypter();
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-                   correct_tag, kIntegrityLimit));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(correct_tag));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
-
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(wrong_tag));
-  for (uint64_t i = 1; i <= kIntegrityLimit * 2; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(
-        0u, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-  EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAcrossKeyPhases) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  constexpr QuicPacketCount kIntegrityLimit = 4;
-
-  TransportParameters params;
-  QuicConfig config;
-  std::string error_details;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  QuicConfigPeer::SetNegotiated(&config, true);
-  if (connection_.version().UsesTls()) {
-    QuicConfigPeer::SetReceivedOriginalConnectionId(
-        &config, connection_.connection_id());
-    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-        &config, connection_.connection_id());
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  MockFramerVisitor peer_framer_visitor_;
-  peer_framer_.set_visitor(&peer_framer_visitor_);
-
-  use_tagging_decrypter();
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-                   0x01, kIntegrityLimit));
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  connection_.OnHandshakeComplete();
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0xFF));
-  for (uint64_t i = 1; i <= 2; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(
-        i, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  // Send packet 1.
-  QuicPacketNumber last_packet;
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
-  // Receive ack for packet 1.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  ProcessAckPacket(&frame1);
-  // Key update should now be allowed, initiate it.
-  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce([kIntegrityLimit]() {
-        return std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
-            0x02, kIntegrityLimit);
-      });
-  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
-    return std::make_unique<TaggingEncrypter>(0x02);
-  });
-  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
-  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
-
-  // Pretend that peer accepts the key update.
-  EXPECT_CALL(peer_framer_visitor_,
-              AdvanceKeysAndCreateCurrentOneRttDecrypter())
-      .WillOnce(
-          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
-  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
-      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
-  peer_framer_.SetKeyUpdateSupportForConnection(true);
-  peer_framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests);
-
-  // Send packet 2.
-  SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
-  // Receive ack for packet 2.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame2 = InitAckFrame(2);
-  ProcessAckPacket(&frame2);
-
-  EXPECT_EQ(2u,
-            connection_.GetStats().num_failed_authentication_packets_received);
-
-  // Do two more undecryptable packets. Integrity limit should be reached.
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0xFF));
-  for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
-    EXPECT_TRUE(connection_.connected());
-    if (i == kIntegrityLimit) {
-      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-    }
-    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-    EXPECT_EQ(
-        i, connection_.GetStats().num_failed_authentication_packets_received);
-  }
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
-}
-
-TEST_P(QuicConnectionTest, SendAckFrequencyFrame) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  connection_.OnHandshakeComplete();
-
-  writer_->SetWritable();
-  QuicPacketCreatorPeer::SetPacketNumber(creator_, 99);
-  // Send packet 100
-  SendStreamDataToPeer(/*id=*/1, "foo", /*offset=*/0, NO_FIN, nullptr);
-
-  QuicAckFrequencyFrame captured_frame;
-  EXPECT_CALL(visitor_, SendAckFrequency(_))
-      .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
-        captured_frame = frame;
-      }));
-  // Send packet 101.
-  SendStreamDataToPeer(/*id=*/1, "bar", /*offset=*/3, NO_FIN, nullptr);
-
-  EXPECT_EQ(captured_frame.packet_tolerance, 10u);
-  EXPECT_EQ(captured_frame.max_ack_delay,
-            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
-
-  // Sending packet 102 does not trigger sending another AckFrequencyFrame.
-  SendStreamDataToPeer(/*id=*/1, "baz", /*offset=*/6, NO_FIN, nullptr);
-}
-
-TEST_P(QuicConnectionTest, SendAckFrequencyFrameUponHandshakeCompletion) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
-  QuicTagVector quic_tag_vector;
-  // Enable sending AckFrequency upon handshake completion.
-  quic_tag_vector.push_back(kAFF2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  QuicAckFrequencyFrame captured_frame;
-  EXPECT_CALL(visitor_, SendAckFrequency(_))
-      .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
-        captured_frame = frame;
-      }));
-
-  connection_.OnHandshakeComplete();
-
-  EXPECT_EQ(captured_frame.packet_tolerance, 2u);
-  EXPECT_EQ(captured_frame.max_ack_delay,
-            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
-}
-
-TEST_P(QuicConnectionTest, FastRecoveryOfLostServerHello) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  connection_.SendCryptoStreamData();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
-  // Assume ServerHello gets lost.
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  // Shorten PTO for fast recovery from lost ServerHello.
-  EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
-            connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, ServerHelloGetsReordered) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  connection_.SetFromConfig(config);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_))
-      .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
-        if (frame.level == ENCRYPTION_INITIAL) {
-          // Install handshake read keys.
-          SetDecrypter(ENCRYPTION_HANDSHAKE,
-                       std::make_unique<StrictTaggingDecrypter>(0x02));
-          connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                                   std::make_unique<TaggingEncrypter>(0x02));
-          connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-        }
-      }));
-
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  connection_.SendCryptoStreamData();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
-  // Assume ServerHello gets reordered.
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x02));
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  // Verify fast recovery is not enabled.
-  EXPECT_EQ(connection_.sent_packet_manager().GetRetransmissionTime(),
-            connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, MigratePath) {
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-  EXPECT_CALL(visitor_, OnPathDegrading());
-  connection_.OnPathDegradingDetected();
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-
-  // Buffer a packet.
-  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
-  writer_->SetWriteBlocked();
-  connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading());
-  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
-                          &new_writer, /*owns_writer=*/false);
-
-  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
-  EXPECT_EQ(&new_writer, QuicConnectionPeer::GetWriter(&connection_));
-  EXPECT_FALSE(connection_.IsPathDegrading());
-  // Buffered packet on the old path should be discarded.
-  if (connection_.connection_migration_use_new_cid()) {
-    EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  } else {
-    EXPECT_EQ(1u, connection_.NumQueuedPackets());
-  }
-}
-
-TEST_P(QuicConnectionTest, MigrateToNewPathDuringProbing) {
-  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
-      !connection_.use_path_validator()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
-  EXPECT_NE(kNewSelfAddress, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  bool success = false;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), &new_writer),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath(
-      &connection_, kNewSelfAddress, connection_.peer_address()));
-
-  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
-                          &new_writer, /*owns_writer=*/false);
-  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  EXPECT_FALSE(QuicConnectionPeer::IsAlternativePath(
-      &connection_, kNewSelfAddress, connection_.peer_address()));
-}
-
-TEST_P(QuicConnectionTest, SingleAckInPacket) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
-    connection_.SendStreamData3();
-    connection_.CloseConnection(
-        QUIC_INTERNAL_ERROR, "error",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  }));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  ASSERT_FALSE(writer_->ack_frames().empty());
-  EXPECT_EQ(1u, writer_->ack_frames().size());
-}
-
-TEST_P(QuicConnectionTest,
-       ServerReceivedZeroRttPacketAfterOneRttPacketWithRetainedKey) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  set_perspective(Perspective::IS_SERVER);
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  // Finish handshake.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  notifier_.NeuterUnencryptedData();
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-
-  // 0-RTT packet received out of order should be decoded since the decrypter
-  // is temporarily retained.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(
-      0u,
-      connection_.GetStats()
-          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
-
-  // Simulate the timeout for discarding 0-RTT keys passing.
-  connection_.GetDiscardZeroRttDecryptionKeysAlarm()->Fire();
-
-  // Another 0-RTT packet received now should not be decoded.
-  EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
-  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(
-      1u,
-      connection_.GetStats()
-          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
-
-  // The |discard_zero_rtt_decryption_keys_alarm_| should only be set on the
-  // first 1-RTT packet received.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(5, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, NewTokenFrameInstigateAcks) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
-  QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
-  EXPECT_CALL(visitor_, OnNewTokenReceived(_));
-  ProcessFramePacket(QuicFrame(new_token));
-
-  // Ensure that this has caused the ACK alarm to be set.
-  EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-TEST_P(QuicConnectionTest, ServerClosesConnectionOnNewTokenFrame) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
-  EXPECT_CALL(visitor_, OnNewTokenReceived(_)).Times(0);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  ProcessFramePacket(QuicFrame(new_token));
-  EXPECT_FALSE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, OverrideRetryTokenWithRetryPacket) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  std::string address_token = "TestAddressToken";
-  connection_.SetSourceAddressTokenToSend(address_token);
-  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
-                QuicConnectionPeer::GetPacketCreator(&connection_)),
-            address_token);
-  // Passes valid retry and verify token gets overridden.
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-}
-
-TEST_P(QuicConnectionTest, DonotOverrideRetryTokenWithAddressToken) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  // Passes valid retry and verify token gets overridden.
-  TestClientRetryHandling(/*invalid_retry_tag=*/false,
-                          /*missing_original_id_in_config=*/false,
-                          /*wrong_original_id_in_config=*/false,
-                          /*missing_retry_id_in_config=*/false,
-                          /*wrong_retry_id_in_config=*/false);
-  std::string retry_token = QuicPacketCreatorPeer::GetRetryToken(
-      QuicConnectionPeer::GetPacketCreator(&connection_));
-
-  std::string address_token = "TestAddressToken";
-  connection_.SetSourceAddressTokenToSend(address_token);
-  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
-                QuicConnectionPeer::GetPacketCreator(&connection_)),
-            retry_token);
-}
-
-TEST_P(QuicConnectionTest,
-       ServerReceivedZeroRttWithHigherPacketNumberThanOneRtt) {
-  if (!connection_.version().UsesTls()) {
-    return;
-  }
-
-  // The code that checks for this error piggybacks on some book-keeping state
-  // kept for key update, so enable key update for the test.
-  std::string error_details;
-  TransportParameters params;
-  QuicConfig config;
-  EXPECT_THAT(config.ProcessTransportParameters(
-                  params, /* is_resumption = */ false, &error_details),
-              IsQuicNoError());
-  QuicConfigPeer::SetNegotiated(&config, true);
-  QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
-                                                  connection_.connection_id());
-  QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-      &config, connection_.connection_id());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-
-  set_perspective(Perspective::IS_SERVER);
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  // Finish handshake.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  notifier_.NeuterUnencryptedData();
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
-  // Decrypt a 1-RTT packet.
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
-
-  // 0-RTT packet with higher packet number than a 1-RTT packet is invalid and
-  // should cause the connection to be closed.
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  EXPECT_FALSE(connection_.connected());
-  TestConnectionCloseQuicErrorCode(
-      QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
-}
-
-// Regression test for b/177312785
-TEST_P(QuicConnectionTest, PeerMigrateBeforeHandshakeConfirm) {
-  if (!VersionHasIetfQuicFrames(version().transport_version)) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_START));
-
-  // Clear direct_peer_address.
-  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
-  // Clear effective_peer_address, it is the same as direct_peer_address for
-  // this test.
-  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
-                                              QuicSocketAddress());
-  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
-
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
-                                  ENCRYPTION_INITIAL);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-
-  // Process another packet with a different peer address on server side will
-  // close connection.
-  QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  EXPECT_CALL(visitor_,
-              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
-  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(0);
-  ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
-                                  kNewPeerAddress, ENCRYPTION_INITIAL);
-  EXPECT_FALSE(connection_.connected());
-}
-
-// Regresstion test for b/175685916
-TEST_P(QuicConnectionTest, TryToFlushAckWithAckQueued) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
-  set_perspective(Perspective::IS_SERVER);
-
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  connection_.SetFromConfig(config);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_.OnHandshakeComplete();
-  QuicPacketCreatorPeer::SetPacketNumber(creator_, 200);
-
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  // Sending ACK_FREQUENCY bundles ACK. QuicConnectionPeer::SendPing
-  // will try to bundle ACK but there is no pending ACK.
-  EXPECT_CALL(visitor_, SendAckFrequency(_))
-      .WillOnce(Invoke(&notifier_,
-                       &SimpleSessionNotifier::WriteOrBufferAckFrequency));
-  QuicConnectionPeer::SendPing(&connection_);
-}
-
-TEST_P(QuicConnectionTest, PathChallengeBeforePeerIpAddressChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-  SetClientConnectionId(TestConnectionId(1));
-  connection_.CreateConnectionIdManager();
-
-  QuicConnectionId server_cid0 = connection_.connection_id();
-  QuicConnectionId client_cid0 = connection_.client_connection_id();
-  QuicConnectionId client_cid1 = TestConnectionId(2);
-  QuicConnectionId server_cid1;
-  // Sends new server CID to client.
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(
-          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  connection_.MaybeSendConnectionIdToClient();
-  // Receives new client CID from client.
-  QuicNewConnectionIdFrame new_cid_frame;
-  new_cid_frame.connection_id = client_cid1;
-  new_cid_frame.sequence_number = 1u;
-  new_cid_frame.retire_prior_to = 0u;
-  connection_.OnNewConnectionIdFrame(new_cid_frame);
-  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
-  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
-  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
-  peer_creator_.SetServerConnectionId(server_cid1);
-  const QuicSocketAddress kNewPeerAddress =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
-  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
-  QuicFrames frames1;
-  frames1.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
-  QuicPathFrameBuffer payload;
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
-      .Times(AtLeast(1))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-        EXPECT_EQ(kPeerAddress, connection_.peer_address());
-        EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-        EXPECT_FALSE(writer_->path_response_frames().empty());
-        EXPECT_FALSE(writer_->path_challenge_frames().empty());
-        payload = writer_->path_challenge_frames().front().data_buffer;
-      }));
-  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  const auto* alternative_path =
-      QuicConnectionPeer::GetAlternativePath(&connection_);
-  EXPECT_EQ(default_path->client_connection_id, client_cid0);
-  EXPECT_EQ(default_path->server_connection_id, server_cid0);
-  EXPECT_EQ(alternative_path->client_connection_id, client_cid1);
-  EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
-  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
-  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
-  // Process another packet with a different peer address on server side will
-  // start connection migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
-    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  }));
-  // IETF QUIC send algorithm should be changed to a different object, so no
-  // OnPacketSent() called on the old send algorithm.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
-      .Times(0);
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-  EXPECT_TRUE(writer_->path_challenge_frames().empty());
-  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
-            send_algorithm_);
-  // Switch to use the mock send algorithm.
-  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(kDefaultTCPMSS));
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-      .Times(AnyNumber())
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
-  connection_.SetSendAlgorithm(send_algorithm_);
-  EXPECT_EQ(default_path->client_connection_id, client_cid1);
-  EXPECT_EQ(default_path->server_connection_id, server_cid1);
-  // The previous default path is kept as alternative path before reverse path
-  // validation finishes.
-  EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
-  EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
-  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
-  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
-
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            connection_.active_effective_peer_migration_type());
-  EXPECT_EQ(1u, connection_.GetStats()
-                    .num_peer_migration_to_proactively_validated_address);
-
-  // The PATH_CHALLENGE and PATH_RESPONSE is expanded upto the max packet size
-  // which may exceeds the anti-amplification limit. Verify server is throttled
-  // by anti-amplification limit.
-  connection_.SendCryptoDataWithString("foo", 0);
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Receiving PATH_RESPONSE should lift the anti-amplification limit.
-  QuicFrames frames3;
-  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
-  EXPECT_CALL(visitor_, MaybeSendAddressToken());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .Times(testing::AtLeast(1u));
-  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-  // Verify that alternative_path_ is cleared and the peer CID is retired.
-  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
-  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
-  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
-  retire_peer_issued_cid_alarm->Fire();
-
-  // Verify the anti-amplification limit is lifted by sending a packet larger
-  // than the anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
-  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-}
-
-TEST_P(QuicConnectionTest,
-       PathValidationSucceedsBeforePeerIpAddressChangeAtServer) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-  connection_.CreateConnectionIdManager();
-
-  QuicConnectionId server_cid0 = connection_.connection_id();
-  QuicConnectionId server_cid1;
-  // Sends new server CID to client.
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(
-          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  connection_.MaybeSendConnectionIdToClient();
-  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
-  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
-  // Receive probing packet with new peer address.
-  peer_creator_.SetServerConnectionId(server_cid1);
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/23456);
-  QuicPathFrameBuffer payload;
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
-        EXPECT_EQ(kPeerAddress, connection_.peer_address());
-        EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
-        EXPECT_FALSE(writer_->path_response_frames().empty());
-        EXPECT_FALSE(writer_->path_challenge_frames().empty());
-        payload = writer_->path_challenge_frames().front().data_buffer;
-      }))
-      .WillRepeatedly(Invoke([&]() {
-        // Only start reverse path validation once.
-        EXPECT_TRUE(writer_->path_challenge_frames().empty());
-      }));
-  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
-  QuicFrames frames1;
-  frames1.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
-  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  const auto* alternative_path =
-      QuicConnectionPeer::GetAlternativePath(&connection_);
-  EXPECT_EQ(default_path->server_connection_id, server_cid0);
-  EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
-  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
-
-  // Receive PATH_RESPONSE should mark the new peer address validated.
-  QuicFrames frames3;
-  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
-  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-
-  // Process another packet with a newer peer address with the same port will
-  // start connection migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  // IETF QUIC send algorithm should be changed to a different object, so no
-  // OnPacketSent() called on the old send algorithm.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
-      .Times(0);
-  const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
-                                            /*port=*/34567);
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
-    EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
-  }));
-  EXPECT_CALL(visitor_, MaybeSendAddressToken());
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewerPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
-  EXPECT_EQ(kNewerPeerAddress, connection_.effective_peer_address());
-  // Since the newer address has the same IP as the previously validated probing
-  // address. The peer migration becomes validated immediately.
-  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
-  EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
-  EXPECT_EQ(1u, connection_.GetStats()
-                    .num_peer_migration_to_proactively_validated_address);
-  EXPECT_FALSE(connection_.HasPendingPathValidation());
-  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
-            send_algorithm_);
-
-  EXPECT_EQ(default_path->server_connection_id, server_cid1);
-  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
-  // Verify that alternative_path_ is cleared.
-  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
-  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-
-  // Switch to use the mock send algorithm.
-  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(kDefaultTCPMSS));
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-      .Times(AnyNumber())
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
-  connection_.SetSendAlgorithm(send_algorithm_);
-
-  // Verify the server is not throttled by the anti-amplification limit by
-  // sending a packet larger than the anti-amplification limit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
-  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
-}
-
-TEST_P(QuicConnectionTest,
-       ProbedOnAnotherPathAfterPeerIpAddressChangeAtServer) {
-  PathProbeTestInit(Perspective::IS_SERVER);
-  if (!connection_.validate_client_address()) {
-    return;
-  }
-
-  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/23456);
-
-  // Process a packet with a new peer address will start connection migration.
-  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
-  // IETF QUIC send algorithm should be changed to a different object, so no
-  // OnPacketSent() called on the old send algorithm.
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
-      .Times(0);
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
-    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  }));
-  QuicFrames frames2;
-  frames2.push_back(QuicFrame(frame2_));
-  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-
-  // Switch to use the mock send algorithm.
-  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(kDefaultTCPMSS));
-  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-      .Times(AnyNumber())
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
-  connection_.SetSendAlgorithm(send_algorithm_);
-
-  // Receive probing packet with a newer peer address shouldn't override the
-  // on-going path validation.
-  const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
-                                            /*port=*/34567);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
-      .WillOnce(Invoke([&]() {
-        EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
-        EXPECT_FALSE(writer_->path_response_frames().empty());
-        EXPECT_TRUE(writer_->path_challenge_frames().empty());
-      }));
-  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
-  QuicFrames frames1;
-  frames1.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
-  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewerPeerAddress,
-                                   ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
-  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
-  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
-  EXPECT_TRUE(connection_.HasPendingPathValidation());
-}
-
-TEST_P(QuicConnectionTest,
-       PathValidationFailedOnClientDueToLackOfServerConnectionId) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-    config.SetConnectionOptionsToSend({kRVCM});
-  }
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT,
-                    /*receive_new_server_connection_id=*/false);
-
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/34567);
-
-  bool success;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), writer_.get()),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-
-  EXPECT_FALSE(success);
-}
-
-TEST_P(QuicConnectionTest,
-       PathValidationFailedOnClientDueToLackOfClientConnectionIdTheSecondTime) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    config.SetConnectionOptionsToSend({kRVCM});
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT,
-                    /*receive_new_server_connection_id=*/false);
-  SetClientConnectionId(TestConnectionId(1));
-
-  // Make sure server connection ID is available for the 1st validation.
-  QuicConnectionId server_cid0 = connection_.connection_id();
-  QuicConnectionId server_cid1 = TestConnectionId(2);
-  QuicConnectionId server_cid2 = TestConnectionId(4);
-  QuicConnectionId client_cid1;
-  QuicNewConnectionIdFrame frame1;
-  frame1.connection_id = server_cid1;
-  frame1.sequence_number = 1u;
-  frame1.retire_prior_to = 0u;
-  frame1.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
-  connection_.OnNewConnectionIdFrame(frame1);
-  const auto* packet_creator =
-      QuicConnectionPeer::GetPacketCreator(&connection_);
-  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid0);
-
-  // Client will issue a new client connection ID to server.
-  EXPECT_CALL(visitor_, SendNewConnectionId(_))
-      .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
-        client_cid1 = frame.connection_id;
-      }));
-
-  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
-  ASSERT_NE(kSelfAddress1, connection_.self_address());
-  bool success1;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kSelfAddress1, connection_.peer_address(), writer_.get()),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kSelfAddress1, connection_.peer_address(), &success1));
-
-  // Migrate upon 1st validation success.
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
-                                      &new_writer, /*owns_writer=*/false));
-  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
-  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  EXPECT_EQ(default_path->client_connection_id, client_cid1);
-  EXPECT_EQ(default_path->server_connection_id, server_cid1);
-  EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
-  const auto* alternative_path =
-      QuicConnectionPeer::GetAlternativePath(&connection_);
-  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
-  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
-  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid1);
-
-  // Client will retire server connection ID on old default_path.
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
-  retire_peer_issued_cid_alarm->Fire();
-
-  // Another server connection ID is available to client.
-  QuicNewConnectionIdFrame frame2;
-  frame2.connection_id = server_cid2;
-  frame2.sequence_number = 2u;
-  frame2.retire_prior_to = 1u;
-  frame2.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
-  connection_.OnNewConnectionIdFrame(frame2);
-
-  const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
-                                        /*port=*/45678);
-  bool success2;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kSelfAddress2, connection_.peer_address(), writer_.get()),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kSelfAddress2, connection_.peer_address(), &success2));
-  // Since server does not retire any client connection ID yet, 2nd validation
-  // would fail due to lack of client connection ID.
-  EXPECT_FALSE(success2);
-}
-
-TEST_P(QuicConnectionTest, ServerConnectionIdRetiredUponPathValidationFailure) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    config.SetConnectionOptionsToSend({kRVCM});
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT);
-
-  // Make sure server connection ID is available for validation.
-  QuicNewConnectionIdFrame frame;
-  frame.connection_id = TestConnectionId(2);
-  frame.sequence_number = 1u;
-  frame.retire_prior_to = 0u;
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  connection_.OnNewConnectionIdFrame(frame);
-
-  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
-                                          /*port=*/34567);
-  bool success;
-  connection_.ValidatePath(
-      std::make_unique<TestQuicPathValidationContext>(
-          kNewSelfAddress, connection_.peer_address(), writer_.get()),
-      std::make_unique<TestValidationResultDelegate>(
-          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
-
-  auto* path_validator = QuicConnectionPeer::path_validator(&connection_);
-  path_validator->CancelPathValidation();
-  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
-  EXPECT_FALSE(success);
-  const auto* alternative_path =
-      QuicConnectionPeer::GetAlternativePath(&connection_);
-  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
-  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
-  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
-
-  // Client will retire server connection ID on alternative_path.
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
-  retire_peer_issued_cid_alarm->Fire();
-}
-
-TEST_P(QuicConnectionTest,
-       MigratePathDirectlyFailedDueToLackOfServerConnectionId) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    config.SetConnectionOptionsToSend({kRVCM});
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT,
-                    /*receive_new_server_connection_id=*/false);
-  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
-  ASSERT_NE(kSelfAddress1, connection_.self_address());
-
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  ASSERT_FALSE(connection_.MigratePath(kSelfAddress1,
-                                       connection_.peer_address(), &new_writer,
-                                       /*owns_writer=*/false));
-}
-
-TEST_P(QuicConnectionTest,
-       MigratePathDirectlyFailedDueToLackOfClientConnectionIdTheSecondTime) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    config.SetConnectionOptionsToSend({kRVCM});
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_CLIENT,
-                    /*receive_new_server_connection_id=*/false);
-  SetClientConnectionId(TestConnectionId(1));
-
-  // Make sure server connection ID is available for the 1st migration.
-  QuicNewConnectionIdFrame frame1;
-  frame1.connection_id = TestConnectionId(2);
-  frame1.sequence_number = 1u;
-  frame1.retire_prior_to = 0u;
-  frame1.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
-  connection_.OnNewConnectionIdFrame(frame1);
-
-  // Client will issue a new client connection ID to server.
-  QuicConnectionId new_client_connection_id;
-  EXPECT_CALL(visitor_, SendNewConnectionId(_))
-      .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
-        new_client_connection_id = frame.connection_id;
-      }));
-
-  // 1st migration is successful.
-  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
-  ASSERT_NE(kSelfAddress1, connection_.self_address());
-  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
-  ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
-                                      &new_writer,
-                                      /*owns_writer=*/false));
-  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
-  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  EXPECT_EQ(default_path->client_connection_id, new_client_connection_id);
-  EXPECT_EQ(default_path->server_connection_id, frame1.connection_id);
-  EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
-
-  // Client will retire server connection ID on old default_path.
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
-  retire_peer_issued_cid_alarm->Fire();
-
-  // Another server connection ID is available to client.
-  QuicNewConnectionIdFrame frame2;
-  frame2.connection_id = TestConnectionId(4);
-  frame2.sequence_number = 2u;
-  frame2.retire_prior_to = 1u;
-  frame2.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
-  connection_.OnNewConnectionIdFrame(frame2);
-
-  // Since server does not retire any client connection ID yet, 2nd migration
-  // would fail due to lack of client connection ID.
-  const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
-                                        /*port=*/45678);
-  auto new_writer2 = std::make_unique<TestPacketWriter>(version(), &clock_,
-                                                        Perspective::IS_CLIENT);
-  ASSERT_FALSE(connection_.MigratePath(
-      kSelfAddress2, connection_.peer_address(), new_writer2.release(),
-      /*owns_writer=*/true));
-}
-
-TEST_P(QuicConnectionTest,
-       CloseConnectionAfterReceiveNewConnectionIdFromPeerUsingEmptyCID) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  ASSERT_TRUE(connection_.client_connection_id().IsEmpty());
-
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = TestConnectionId(1);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-
-  EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
-
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest, NewConnectionIdFrameResultsInError) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  connection_.CreateConnectionIdManager();
-  ASSERT_FALSE(connection_.connection_id().IsEmpty());
-
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = connection_id_;  // Reuses connection ID casuing error.
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-
-  EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
-
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest,
-       ClientRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  connection_.CreateConnectionIdManager();
-
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = TestConnectionId(1);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-
-  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
-
-  frame.sequence_number = 2u;
-  frame.connection_id = TestConnectionId(2);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
-
-  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_EQ(connection_.connection_id(), connection_id_);
-
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
-  retire_peer_issued_cid_alarm->Fire();
-  EXPECT_EQ(connection_.connection_id(), TestConnectionId(2));
-  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
-            TestConnectionId(2));
-}
-
-TEST_P(QuicConnectionTest,
-       ServerRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  SetClientConnectionId(TestConnectionId(0));
-
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = TestConnectionId(1);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-
-  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
-
-  frame.sequence_number = 2u;
-  frame.connection_id = TestConnectionId(2);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
-
-  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
-
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
-  retire_peer_issued_cid_alarm->Fire();
-  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
-  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
-            TestConnectionId(2));
-}
-
-TEST_P(
-    QuicConnectionTest,
-    ReplacePeerIssuedConnectionIdOnBothPathsTriggeredByNewConnectionIdFrame) {
-  if (!version().HasIetfQuicFrames() || !connection_.use_path_validator() ||
-      !connection_.count_bytes_on_alternative_path_separately()) {
-    return;
-  }
-  PathProbeTestInit(Perspective::IS_SERVER);
-  SetClientConnectionId(TestConnectionId(0));
-
-  // Populate alternative_path_ with probing packet.
-  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
-
-  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
-      QuicEncryptedPacket(probing_packet->encrypted_buffer,
-                          probing_packet->encrypted_length),
-      clock_.Now()));
-  QuicIpAddress new_host;
-  new_host.FromString("1.1.1.1");
-  ProcessReceivedPacket(kSelfAddress,
-                        QuicSocketAddress(new_host, /*port=*/23456), *received);
-
-  EXPECT_EQ(
-      TestConnectionId(0),
-      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
-
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = TestConnectionId(1);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-
-  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
-  auto* retire_peer_issued_cid_alarm =
-      connection_.GetRetirePeerIssuedConnectionIdAlarm();
-  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
-
-  frame.sequence_number = 2u;
-  frame.connection_id = TestConnectionId(2);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
-
-  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
-  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
-  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
-
-  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
-  retire_peer_issued_cid_alarm->Fire();
-  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
-  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
-            TestConnectionId(2));
-  // Clean up alternative path connection ID.
-  EXPECT_EQ(
-      TestConnectionId(2),
-      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
-}
-
-TEST_P(QuicConnectionTest,
-       CloseConnectionAfterReceiveRetireConnectionIdWhenNoCIDIssued) {
-  if (!version().HasIetfQuicFrames() ||
-      !connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  QuicRetireConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-
-  EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
-
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest, RetireConnectionIdFrameResultsInError) {
-  if (!version().HasIetfQuicFrames() ||
-      !connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  connection_.CreateConnectionIdManager();
-
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  connection_.MaybeSendConnectionIdToClient();
-
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
-      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
-  QuicRetireConnectionIdFrame frame;
-  frame.sequence_number = 2u;  // The corresponding ID is never issued.
-
-  EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
-
-  EXPECT_FALSE(connection_.connected());
-  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
-              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-}
-
-TEST_P(QuicConnectionTest,
-       ServerRetireSelfIssuedConnectionIdWithoutSendingNewConnectionIdBefore) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  connection_.CreateConnectionIdManager();
-
-  auto* retire_self_issued_cid_alarm =
-      connection_.GetRetireSelfIssuedConnectionIdAlarm();
-  ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
-
-  QuicConnectionId cid0 = connection_id_;
-  QuicRetireConnectionIdFrame frame;
-  frame.sequence_number = 0u;
-  if (connection_.connection_migration_use_new_cid()) {
-    EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_)).Times(2);
-    EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
-  }
-  EXPECT_TRUE(connection_.OnRetireConnectionIdFrame(frame));
-}
-
-TEST_P(QuicConnectionTest, ServerRetireSelfIssuedConnectionId) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    config.SetConnectionOptionsToSend({kRVCM});
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  if (!connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  connection_.CreateConnectionIdManager();
-  QuicConnectionId recorded_cid;
-  auto cid_recorder = [&recorded_cid](const QuicConnectionId& cid) {
-    recorded_cid = cid;
-  };
-  QuicConnectionId cid0 = connection_id_;
-  QuicConnectionId cid1;
-  QuicConnectionId cid2;
-  EXPECT_EQ(connection_.connection_id(), cid0);
-  EXPECT_EQ(connection_.GetOneActiveServerConnectionId(), cid0);
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(Invoke(cid_recorder));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  connection_.MaybeSendConnectionIdToClient();
-  cid1 = recorded_cid;
-
-  auto* retire_self_issued_cid_alarm =
-      connection_.GetRetireSelfIssuedConnectionIdAlarm();
-  ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
-
-  // Generate three packets with different connection IDs that will arrive out
-  // of order (2, 1, 3) later.
-  char buffers[3][kMaxOutgoingPacketSize];
-  // Destination connection ID of packet1 is cid0.
-  auto packet1 =
-      ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
-                      buffers[0], kMaxOutgoingPacketSize);
-  peer_creator_.SetServerConnectionId(cid1);
-  auto retire_cid_frame = std::make_unique<QuicRetireConnectionIdFrame>();
-  retire_cid_frame->sequence_number = 0u;
-  // Destination connection ID of packet2 is cid1.
-  auto packet2 = ConstructPacket({QuicFrame(retire_cid_frame.release())},
-                                 ENCRYPTION_FORWARD_SECURE, buffers[1],
-                                 kMaxOutgoingPacketSize);
-  // Destination connection ID of packet3 is cid1.
-  auto packet3 =
-      ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
-                      buffers[2], kMaxOutgoingPacketSize);
-
-  // Packet2 with RetireConnectionId frame trigers sending NewConnectionId
-  // immediately.
-  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
-      .WillOnce(Invoke(cid_recorder));
-  EXPECT_CALL(visitor_, SendNewConnectionId(_));
-  peer_creator_.SetServerConnectionId(cid1);
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet2);
-  cid2 = recorded_cid;
-  // cid0 is not retired immediately.
-  EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
-              ElementsAre(cid0, cid1, cid2));
-  ASSERT_TRUE(retire_self_issued_cid_alarm->IsSet());
-  EXPECT_EQ(connection_.connection_id(), cid1);
-  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
-              connection_.GetOneActiveServerConnectionId() == cid1 ||
-              connection_.GetOneActiveServerConnectionId() == cid2);
-
-  // Packet1 updates the connection ID on the default path but not the active
-  // connection ID.
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet1);
-  EXPECT_EQ(connection_.connection_id(), cid0);
-  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
-              connection_.GetOneActiveServerConnectionId() == cid1 ||
-              connection_.GetOneActiveServerConnectionId() == cid2);
-
-  // cid0 is retired when the retire CID alarm fires.
-  EXPECT_CALL(visitor_, OnServerConnectionIdRetired(cid0));
-  retire_self_issued_cid_alarm->Fire();
-  EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
-              ElementsAre(cid1, cid2));
-  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
-              connection_.GetOneActiveServerConnectionId() == cid2);
-
-  // Packet3 updates the connection ID on the default path.
-  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet3);
-  EXPECT_EQ(connection_.connection_id(), cid1);
-  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
-              connection_.GetOneActiveServerConnectionId() == cid2);
-}
-
-TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoAlternativePath) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  connection_.CreateConnectionIdManager();
-  connection_.set_client_connection_id(TestConnectionId(1));
-
-  // Set up the state after path probing.
-  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
-  QuicIpAddress new_host;
-  new_host.FromString("12.12.12.12");
-  alternative_path->self_address = default_path->self_address;
-  alternative_path->peer_address = QuicSocketAddress(new_host, 12345);
-  alternative_path->server_connection_id = TestConnectionId(3);
-  ASSERT_TRUE(alternative_path->client_connection_id.IsEmpty());
-  ASSERT_FALSE(alternative_path->stateless_reset_token.has_value());
-
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = TestConnectionId(5);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-  // New ID is patched onto the alternative path when the needed
-  // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
-  connection_.OnNewConnectionIdFrame(frame);
-
-  ASSERT_EQ(alternative_path->client_connection_id, frame.connection_id);
-  ASSERT_EQ(alternative_path->stateless_reset_token,
-            frame.stateless_reset_token);
-}
-
-TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoDefaultPath) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  connection_.CreateConnectionIdManager();
-  connection_.set_client_connection_id(TestConnectionId(1));
-
-  // Set up the state after peer migration without probing.
-  auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
-  auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
-  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
-  *alternative_path = std::move(*default_path);
-  QuicIpAddress new_host;
-  new_host.FromString("12.12.12.12");
-  default_path->self_address = default_path->self_address;
-  default_path->peer_address = QuicSocketAddress(new_host, 12345);
-  default_path->server_connection_id = TestConnectionId(3);
-  packet_creator->SetDefaultPeerAddress(default_path->peer_address);
-  packet_creator->SetServerConnectionId(default_path->server_connection_id);
-  packet_creator->SetClientConnectionId(default_path->client_connection_id);
-
-  ASSERT_FALSE(default_path->validated);
-  ASSERT_TRUE(default_path->client_connection_id.IsEmpty());
-  ASSERT_FALSE(default_path->stateless_reset_token.has_value());
-
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 1u;
-  frame.connection_id = TestConnectionId(5);
-  frame.stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
-  frame.retire_prior_to = 0u;
-  // New ID is patched onto the default path when the needed
-  // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
-  connection_.OnNewConnectionIdFrame(frame);
-
-  ASSERT_EQ(default_path->client_connection_id, frame.connection_id);
-  ASSERT_EQ(default_path->stateless_reset_token, frame.stateless_reset_token);
-  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), frame.connection_id);
-}
-
-TEST_P(QuicConnectionTest, ShouldGeneratePacketBlockedByMissingConnectionId) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  connection_.set_client_connection_id(TestConnectionId(1));
-  connection_.CreateConnectionIdManager();
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-
-  ASSERT_TRUE(
-      connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
-
-  QuicPacketCreator* packet_creator =
-      QuicConnectionPeer::GetPacketCreator(&connection_);
-  QuicIpAddress peer_host1;
-  peer_host1.FromString("12.12.12.12");
-  QuicSocketAddress peer_address1(peer_host1, 1235);
-
-  {
-    // No connection ID is available as context is created without any.
-    QuicPacketCreator::ScopedPeerAddressContext context(
-        packet_creator, peer_address1, EmptyQuicConnectionId(),
-        EmptyQuicConnectionId(),
-        /*update_connection_id=*/true);
-    ASSERT_FALSE(connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                                  NOT_HANDSHAKE));
-  }
-  ASSERT_TRUE(
-      connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
-}
-
-// Regression test for b/182571515
-TEST_P(QuicConnectionTest, LostDataThenGetAcknowledged) {
-  set_perspective(Perspective::IS_SERVER);
-  if (!connection_.validate_client_address()) {
-    return;
-  }
-
-  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
-  if (version().SupportsAntiAmplificationLimit()) {
-    QuicConnectionPeer::SetAddressValidated(&connection_);
-  }
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  // Discard INITIAL key.
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
-
-  QuicPacketNumber last_packet;
-  // Send packets 1 to 4.
-  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 1
-  SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 2
-  SendStreamDataToPeer(3, "foo", 6, NO_FIN, &last_packet);  // Packet 3
-  SendStreamDataToPeer(3, "foo", 9, NO_FIN, &last_packet);  // Packet 4
-
-  // Process a PING packet to set peer address.
-  ProcessFramePacket(QuicFrame(QuicPingFrame()));
-
-  // Process a packet containing a STREAM_FRAME and an ACK with changed peer
-  // address.
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1_));
-  QuicAckFrame ack = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)}});
-  frames.push_back(QuicFrame(&ack));
-
-  EXPECT_CALL(visitor_, OnConnectionMigration(_)).Times(1);
-
-  // Invoke OnCanWrite.
-  EXPECT_CALL(visitor_, OnStreamFrame(_))
-      .WillOnce(
-          InvokeWithoutArgs(&notifier_, &SimpleSessionNotifier::OnCanWrite));
-  QuicIpAddress ip_address;
-  ASSERT_TRUE(ip_address.FromString("127.0.52.223"));
-  EXPECT_QUIC_BUG(ProcessFramesPacketWithAddresses(
-                      frames, kSelfAddress, QuicSocketAddress(ip_address, 1000),
-                      ENCRYPTION_FORWARD_SECURE),
-                  "Try to write mid packet processing");
-  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
-  // Verify stream frame will not be retransmitted.
-  EXPECT_TRUE(writer_->stream_frames().empty());
-}
-
-TEST_P(QuicConnectionTest, PtoSendStreamData) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  }
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send INITIAL 1.
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  // Send HANDSHAKE packets.
-  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // Send half RTT packet with congestion control blocked.
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
-  connection_.SendStreamDataWithString(2, std::string(1500, 'a'), 0, NO_FIN);
-
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify INITIAL and HANDSHAKE get retransmitted.
-  EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
-}
-
-TEST_P(QuicConnectionTest, SendingZeroRttPacketsDoesNotPostponePTO) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send CHLO.
-  connection_.SendCryptoStreamData();
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  // Install 0-RTT keys.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-
-  // CHLO gets acknowledged after 10ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-  // Verify PTO is still armed since address validation is not finished yet.
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
-  // Send 0-RTT packet.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  // PTO deadline should be unchanged.
-  EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, QueueingUndecryptablePacketsDoesntPostponePTO) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  config.set_max_undecryptable_packets(3);
-  connection_.SetFromConfig(config);
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
-  // Send CHLO.
-  connection_.SendCryptoStreamData();
-
-  // Send 0-RTT packet.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
-  // CHLO gets acknowledged after 10ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-  // Verify PTO is still armed since address validation is not finished yet.
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
-  // Receive an undecryptable packets.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0xFF));
-  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO deadline is sooner.
-  EXPECT_GT(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
-  pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
-  // PTO fires.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify PTO is still armed since address validation is not finished yet.
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
-  // Verify PTO deadline does not change.
-  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
-}
-
-TEST_P(QuicConnectionTest, QueueUndecryptableHandshakePackets) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  config.set_max_undecryptable_packets(3);
-  connection_.SetFromConfig(config);
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  connection_.RemoveDecrypter(ENCRYPTION_HANDSHAKE);
-  // Send CHLO.
-  connection_.SendCryptoStreamData();
-
-  // Send 0-RTT packet.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
-  // Receive an undecryptable handshake packet.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0xFF));
-  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
-  // Verify this handshake packet gets queued.
-  EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-}
-
-TEST_P(QuicConnectionTest, PingNotSentAt0RTTLevelWhenInitialAvailable) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  use_tagging_decrypter();
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  // Send CHLO.
-  connection_.SendCryptoStreamData();
-  // Send 0-RTT packet.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
-
-  // CHLO gets acknowledged after 10ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  QuicAckFrame frame1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
-  // Verify PTO is still armed since address validation is not finished yet.
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
-
-  // PTO fires.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
-  connection_.GetRetransmissionAlarm()->Fire();
-  // Verify the PING gets sent in ENCRYPTION_INITIAL.
-  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-}
-
-TEST_P(QuicConnectionTest, AckElicitingFrames) {
-  if (!GetQuicReloadableFlag(
-          quic_remove_connection_migration_connection_option)) {
-    QuicConfig config;
-    config.SetConnectionOptionsToSend({kRVCM});
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    connection_.SetFromConfig(config);
-  }
-  if (!version().HasIetfQuicFrames() ||
-      !connection_.connection_migration_use_new_cid()) {
-    return;
-  }
-  EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
-  EXPECT_CALL(visitor_, OnRstStream(_));
-  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
-  EXPECT_CALL(visitor_, OnBlockedFrame(_));
-  EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
-  EXPECT_CALL(visitor_, OnStreamFrame(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  EXPECT_CALL(visitor_, OnMaxStreamsFrame(_));
-  EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_));
-  EXPECT_CALL(visitor_, OnStopSendingFrame(_));
-  EXPECT_CALL(visitor_, OnMessageReceived(""));
-  EXPECT_CALL(visitor_, OnNewTokenReceived(""));
-
-  SetClientConnectionId(TestConnectionId(12));
-  connection_.CreateConnectionIdManager();
-  QuicConnectionPeer::GetSelfIssuedConnectionIdManager(&connection_)
-      ->MaybeSendNewConnectionIds();
-  connection_.set_can_receive_ack_frequency_frame();
-
-  QuicAckFrame ack_frame = InitAckFrame(1);
-  QuicRstStreamFrame rst_stream_frame;
-  QuicWindowUpdateFrame window_update_frame;
-  QuicPathChallengeFrame path_challenge_frame;
-  QuicNewConnectionIdFrame new_connection_id_frame;
-  QuicRetireConnectionIdFrame retire_connection_id_frame;
-  retire_connection_id_frame.sequence_number = 1u;
-  QuicStopSendingFrame stop_sending_frame;
-  QuicPathResponseFrame path_response_frame;
-  QuicMessageFrame message_frame;
-  QuicNewTokenFrame new_token_frame;
-  QuicAckFrequencyFrame ack_frequency_frame;
-  QuicBlockedFrame blocked_frame;
-  size_t packet_number = 1;
-
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
-  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
-    QuicFrameType frame_type = static_cast<QuicFrameType>(i);
-    bool skipped = false;
-    QuicFrame frame;
-    QuicFrames frames;
-    // Add some padding to fullfill the min size requirement of header
-    // protection.
-    frames.push_back(QuicFrame(QuicPaddingFrame(10)));
-    switch (frame_type) {
-      case PADDING_FRAME:
-        frame = QuicFrame(QuicPaddingFrame(10));
-        break;
-      case MTU_DISCOVERY_FRAME:
-        frame = QuicFrame(QuicMtuDiscoveryFrame());
-        break;
-      case PING_FRAME:
-        frame = QuicFrame(QuicPingFrame());
-        break;
-      case MAX_STREAMS_FRAME:
-        frame = QuicFrame(QuicMaxStreamsFrame());
-        break;
-      case STOP_WAITING_FRAME:
-        // Not supported.
-        skipped = true;
-        break;
-      case STREAMS_BLOCKED_FRAME:
-        frame = QuicFrame(QuicStreamsBlockedFrame());
-        break;
-      case STREAM_FRAME:
-        frame = QuicFrame(QuicStreamFrame());
-        break;
-      case HANDSHAKE_DONE_FRAME:
-        frame = QuicFrame(QuicHandshakeDoneFrame());
-        break;
-      case ACK_FRAME:
-        frame = QuicFrame(&ack_frame);
-        break;
-      case RST_STREAM_FRAME:
-        frame = QuicFrame(&rst_stream_frame);
-        break;
-      case CONNECTION_CLOSE_FRAME:
-        // Do not test connection close.
-        skipped = true;
-        break;
-      case GOAWAY_FRAME:
-        // Does not exist in IETF QUIC.
-        skipped = true;
-        break;
-      case BLOCKED_FRAME:
-        frame = QuicFrame(blocked_frame);
-        break;
-      case WINDOW_UPDATE_FRAME:
-        frame = QuicFrame(window_update_frame);
-        break;
-      case PATH_CHALLENGE_FRAME:
-        frame = QuicFrame(&path_challenge_frame);
-        break;
-      case STOP_SENDING_FRAME:
-        frame = QuicFrame(stop_sending_frame);
-        break;
-      case NEW_CONNECTION_ID_FRAME:
-        frame = QuicFrame(&new_connection_id_frame);
-        break;
-      case RETIRE_CONNECTION_ID_FRAME:
-        frame = QuicFrame(&retire_connection_id_frame);
-        break;
-      case PATH_RESPONSE_FRAME:
-        frame = QuicFrame(&path_response_frame);
-        break;
-      case MESSAGE_FRAME:
-        frame = QuicFrame(&message_frame);
-        break;
-      case CRYPTO_FRAME:
-        // CRYPTO_FRAME is ack eliciting is covered by other tests.
-        skipped = true;
-        break;
-      case NEW_TOKEN_FRAME:
-        frame = QuicFrame(&new_token_frame);
-        break;
-      case ACK_FREQUENCY_FRAME:
-        frame = QuicFrame(&ack_frequency_frame);
-        break;
-      case NUM_FRAME_TYPES:
-        skipped = true;
-        break;
-    }
-    if (skipped) {
-      continue;
-    }
-    ASSERT_EQ(frame_type, frame.type);
-    frames.push_back(frame);
-    EXPECT_FALSE(connection_.HasPendingAcks());
-    // Process frame.
-    ProcessFramesPacketAtLevel(packet_number++, frames,
-                               ENCRYPTION_FORWARD_SECURE);
-    if (QuicUtils::IsAckElicitingFrame(frame_type)) {
-      ASSERT_TRUE(connection_.HasPendingAcks()) << frame;
-      // Flush ACK.
-      clock_.AdvanceTime(DefaultDelayedAckTime());
-      connection_.GetAckAlarm()->Fire();
-    }
-    EXPECT_FALSE(connection_.HasPendingAcks());
-    ASSERT_TRUE(connection_.connected());
-  }
-}
-
-TEST_P(QuicConnectionTest, ReceivedChloAndAck) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  QuicFrames frames;
-  QuicAckFrame ack_frame = InitAckFrame(1);
-  frames.push_back(MakeCryptoFrame());
-  frames.push_back(QuicFrame(&ack_frame));
-
-  EXPECT_CALL(visitor_, OnCryptoFrame(_))
-      .WillOnce(IgnoreResult(InvokeWithoutArgs(
-          &connection_, &TestConnection::SendCryptoStreamData)));
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
-                                   ENCRYPTION_INITIAL);
-}
-
-// Regression test for b/201643321.
-TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Received INITIAL 1.
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(0x02));
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x04));
-  // Received ENCRYPTION_ZERO_RTT 1.
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // Send INITIAL 1.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-    // Send HANDSHAKE 2.
-    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    // Send half RTT data to exhaust amplification credit.
-    connection_.SendStreamDataWithString(0, std::string(100 * 1024, 'a'), 0,
-                                         NO_FIN);
-  }
-  // Received INITIAL 2.
-  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
-  ASSERT_TRUE(connection_.HasPendingAcks());
-  // Verify ACK delay is 1ms.
-  EXPECT_EQ(clock_.Now() + kAlarmGranularity,
-            connection_.GetAckAlarm()->deadline());
-  // ACK is not throttled by amplification limit, and SHLO is bundled. Also
-  // HANDSHAKE + 1RTT packets get coalesced.
-  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
-  } else {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
-  }
-  // ACK alarm fires.
-  clock_.AdvanceTime(kAlarmGranularity);
-  connection_.GetAckAlarm()->Fire();
-  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
-    // Verify 1-RTT packet is coalesced.
-    EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
-  } else {
-    // Verify HANDSHAKE packet is coalesced with INITIAL ACK + SHLO.
-    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
-  }
-  // Only the first packet in the coalesced packet has been processed,
-  // verify SHLO is bundled with INITIAL ACK.
-  EXPECT_EQ(1u, writer_->ack_frames().size());
-  EXPECT_EQ(1u, writer_->crypto_frames().size());
-  // Process the coalesced HANDSHAKE packet.
-  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-  auto packet = writer_->coalesced_packet()->Clone();
-  writer_->framer()->ProcessPacket(*packet);
-  EXPECT_EQ(0u, writer_->ack_frames().size());
-  EXPECT_EQ(1u, writer_->crypto_frames().size());
-  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
-    // Process the coalesced 1-RTT packet.
-    ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-    packet = writer_->coalesced_packet()->Clone();
-    writer_->framer()->ProcessPacket(*packet);
-    EXPECT_EQ(0u, writer_->crypto_frames().size());
-    EXPECT_EQ(1u, writer_->stream_frames().size());
-  } else {
-    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-  }
-
-  // Received INITIAL 3.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  ProcessCryptoPacketAtLevel(3, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-}
-
-// Regression test for b/216133388.
-TEST_P(QuicConnectionTest, FailedToConsumeCryptoData) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-  // Received INITIAL 1.
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  EXPECT_TRUE(connection_.HasPendingAcks());
-
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(0x02));
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x03));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x04));
-  // Received ENCRYPTION_ZERO_RTT 1.
-  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // Send INITIAL 1.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-    // Send HANDSHAKE 2.
-    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
-                                         ENCRYPTION_HANDSHAKE);
-    // Send 1-RTT 3.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    connection_.SendStreamDataWithString(0, std::string(40, 'a'), 0, NO_FIN);
-  }
-  // Received HANDSHAKE Ping, hence discard INITIAL keys.
-  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                            std::make_unique<TaggingEncrypter>(0x03));
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.NeuterUnencryptedPackets();
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
-  clock_.AdvanceTime(kAlarmGranularity);
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // Sending this 1-RTT data would leave the coalescer only have space to
-    // accommodate the HANDSHAKE ACK. The crypto data cannot be bundled with the
-    // ACK.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    connection_.SendStreamDataWithString(0, std::string(1395, 'a'), 40, NO_FIN);
-  }
-  // Verify retransmission alarm is armed.
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-  const QuicTime retransmission_time =
-      connection_.GetRetransmissionAlarm()->deadline();
-  clock_.AdvanceTime(retransmission_time - clock_.Now());
-  connection_.GetRetransmissionAlarm()->Fire();
-
-  if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
-    // Verify the retransmission is a coalesced packet with HANDSHAKE 2 and
-    // 1-RTT 3.
-    EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
-    // Only the first packet in the coalesced packet has been processed.
-    EXPECT_EQ(1u, writer_->crypto_frames().size());
-    // Process the coalesced 1-RTT packet.
-    ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-    auto packet = writer_->coalesced_packet()->Clone();
-    writer_->framer()->ProcessPacket(*packet);
-    EXPECT_EQ(1u, writer_->stream_frames().size());
-    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-  } else {
-    // Although packet 2 has not been retransmitted, it has been marked PTOed
-    // and a HANDHSAKE PING gets retransmitted.
-    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
-    EXPECT_EQ(1u, writer_->ping_frames().size());
-    EXPECT_TRUE(writer_->stream_frames().empty());
-    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-  }
-  // Verify retransmission alarm is still armed.
-  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest,
-       RTTSampleDoesNotIncludeQueuingDelayWithPostponedAckProcessing) {
-  // An endpoint might postpone the processing of ACK when the corresponding
-  // decryption key is not available. This test makes sure the RTT sample does
-  // not include the queuing delay.
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  config.set_max_undecryptable_packets(3);
-  connection_.SetFromConfig(config);
-
-  // 30ms RTT.
-  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
-  rtt_stats->UpdateRtt(kTestRTT, QuicTime::Delta::Zero(), QuicTime::Zero());
-  use_tagging_decrypter();
-
-  // Send 0-RTT packet.
-  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                           std::make_unique<TaggingEncrypter>(0x02));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  connection_.SendStreamDataWithString(0, std::string(10, 'a'), 0, FIN);
-
-  // Receives 1-RTT ACK for 0-RTT packet after RTT + ack_delay.
-  clock_.AdvanceTime(
-      kTestRTT + QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
-  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  QuicAckFrame ack_frame = InitAckFrame(1);
-  // Peer reported ACK delay.
-  ack_frame.ack_delay_time =
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  QuicFrames frames;
-  frames.push_back(QuicFrame(&ack_frame));
-  QuicPacketHeader header =
-      ConstructPacketHeader(30, ENCRYPTION_FORWARD_SECURE);
-  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(30), *packet, buffer,
-      kMaxOutgoingPacketSize);
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-  if (connection_.GetSendAlarm()->IsSet()) {
-    connection_.GetSendAlarm()->Fire();
-  }
-  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-
-  // Assume 1-RTT decrypter is available after 10ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
-  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-  // Verify RTT sample does not include queueing delay.
-  EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
-}
-
-// Regression test for b/112480134.
-TEST_P(QuicConnectionTest, NoExtraPaddingInReserializedInitial) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration() ||
-      !connection_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-
-  set_perspective(Perspective::IS_SERVER);
-  MockQuicConnectionDebugVisitor debug_visitor;
-  connection_.set_debug_visitor(&debug_visitor);
-
-  uint64_t debug_visitor_sent_count = 0;
-  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
-      .WillRepeatedly([&]() { debug_visitor_sent_count++; });
-
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-
-  // Received INITIAL 1.
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(0x02));
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x03));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x04));
-
-  // Received ENCRYPTION_ZERO_RTT 2.
-  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // Send INITIAL 1.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-    // Send HANDSHAKE 2.
-    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
-                                         ENCRYPTION_HANDSHAKE);
-    // Send 1-RTT 3.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    connection_.SendStreamDataWithString(0, std::string(400, 'b'), 0, NO_FIN);
-  }
-
-  // Arrange the stream data to be sent in response to ENCRYPTION_INITIAL 3.
-  const std::string data4(1000, '4');  // Data to send in stream id 4
-  const std::string data8(3000, '8');  // Data to send in stream id 8
-  EXPECT_CALL(visitor_, OnCanWrite()).WillOnce([&]() {
-    connection_.producer()->SaveStreamData(4, data4);
-    connection_.producer()->SaveStreamData(8, data8);
-
-    notifier_.WriteOrBufferData(4, data4.size(), FIN_AND_PADDING);
-
-    // This should trigger FlushCoalescedPacket.
-    notifier_.WriteOrBufferData(8, data8.size(), FIN);
-  });
-
-  QuicByteCount pending_padding_after_serialize_2nd_1rtt_packet = 0;
-  QuicPacketCount num_1rtt_packets_serialized = 0;
-  EXPECT_CALL(connection_, OnSerializedPacket(_))
-      .WillRepeatedly([&](SerializedPacket packet) {
-        if (packet.encryption_level == ENCRYPTION_FORWARD_SECURE) {
-          num_1rtt_packets_serialized++;
-          if (num_1rtt_packets_serialized == 2) {
-            pending_padding_after_serialize_2nd_1rtt_packet =
-                connection_.packet_creator().pending_padding_bytes();
-          }
-        }
-        connection_.QuicConnection::OnSerializedPacket(std::move(packet));
-      });
-
-  // Server receives INITIAL 3, this will serialzie FS 7 (stream 4, stream 8),
-  // which will trigger a flush of a coalesced packet consists of INITIAL 4,
-  // HS 5 and FS 6 (stream 4).
-  if (GetQuicReloadableFlag(
-          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
-    // Expect no QUIC_BUG.
-    ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
-    EXPECT_EQ(
-        debug_visitor_sent_count,
-        connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
-  } else {
-    // Expect QUIC_BUG due to extra padding.
-    EXPECT_QUIC_BUG(
-        { ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL); },
-        "Reserialize initial packet in coalescer has unexpected size");
-    EXPECT_EQ(
-        debug_visitor_sent_count + 1,
-        connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
-  }
-
-  // The error only happens if after serializing the second 1RTT packet(pkt #7),
-  // the pending padding bytes is non zero.
-  EXPECT_GT(pending_padding_after_serialize_2nd_1rtt_packet, 0u);
-  EXPECT_TRUE(connection_.connected());
-}
-
-TEST_P(QuicConnectionTest, ReportedAckDelayIncludesQueuingDelay) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  QuicConfig config;
-  config.set_max_undecryptable_packets(3);
-  connection_.SetFromConfig(config);
-
-  // Receive 1-RTT ack-eliciting packet while keys are not available.
-  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
-  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<TaggingEncrypter>(0x01));
-  QuicFrames frames;
-  frames.push_back(QuicFrame(QuicPingFrame()));
-  frames.push_back(QuicFrame(QuicPaddingFrame(100)));
-  QuicPacketHeader header =
-      ConstructPacketHeader(30, ENCRYPTION_FORWARD_SECURE);
-  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
-
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(30), *packet, buffer,
-      kMaxOutgoingPacketSize);
-  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-  const QuicTime packet_receipt_time = clock_.Now();
-  connection_.ProcessUdpPacket(
-      kSelfAddress, kPeerAddress,
-      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
-  if (connection_.GetSendAlarm()->IsSet()) {
-    connection_.GetSendAlarm()->Fire();
-  }
-  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
-  // 1-RTT keys become available after 10ms.
-  const QuicTime::Delta kQueuingDelay = QuicTime::Delta::FromMilliseconds(10);
-  clock_.AdvanceTime(kQueuingDelay);
-  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-               std::make_unique<StrictTaggingDecrypter>(0x01));
-  ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
-
-  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
-  ASSERT_TRUE(connection_.HasPendingAcks());
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    EXPECT_EQ(packet_receipt_time + DefaultDelayedAckTime(),
-              connection_.GetAckAlarm()->deadline());
-    clock_.AdvanceTime(packet_receipt_time + DefaultDelayedAckTime() -
-                       clock_.Now());
-  } else {
-    EXPECT_EQ(clock_.Now() + DefaultDelayedAckTime(),
-              connection_.GetAckAlarm()->deadline());
-    clock_.AdvanceTime(DefaultDelayedAckTime());
-  }
-  // Fire ACK alarm.
-  connection_.GetAckAlarm()->Fire();
-  ASSERT_EQ(1u, writer_->ack_frames().size());
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    // Verify ACK delay time does not include queuing delay.
-    EXPECT_EQ(DefaultDelayedAckTime(), writer_->ack_frames()[0].ack_delay_time);
-  } else {
-    // Verify ACK delay time = queuing delay + ack delay
-    EXPECT_EQ(DefaultDelayedAckTime() + kQueuingDelay,
-              writer_->ack_frames()[0].ack_delay_time);
-  }
-}
-
-TEST_P(QuicConnectionTest, CoalesceOneRTTPacketWithInitialAndHandshakePackets) {
-  if (!version().HasIetfQuicFrames()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-
-  // Received INITIAL 1.
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-
-  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                            std::make_unique<TaggingEncrypter>(0x02));
-
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x03));
-  SetDecrypter(ENCRYPTION_ZERO_RTT,
-               std::make_unique<StrictTaggingDecrypter>(0x02));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x04));
-
-  // Received ENCRYPTION_ZERO_RTT 2.
-  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
-
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // Send INITIAL 1.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-    // Send HANDSHAKE 2.
-    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
-                                         ENCRYPTION_HANDSHAKE);
-    // Send 1-RTT data.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    connection_.SendStreamDataWithString(0, std::string(2000, 'b'), 0, FIN);
-  }
-  // Verify coalesced packet [INITIAL 1 + HANDSHAKE 2 + part of 1-RTT data] +
-  // rest of 1-RTT data get sent.
-  EXPECT_EQ(2u, writer_->packets_write_attempts());
-
-  // Received ENCRYPTION_INITIAL 3.
-  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
-
-  // Verify a coalesced packet gets sent.
-  EXPECT_EQ(3u, writer_->packets_write_attempts());
-
-  // Only the first INITIAL packet has been processed yet.
-  EXPECT_EQ(1u, writer_->ack_frames().size());
-  EXPECT_EQ(1u, writer_->crypto_frames().size());
-
-  // Process HANDSHAKE packet.
-  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-  auto packet = writer_->coalesced_packet()->Clone();
-  writer_->framer()->ProcessPacket(*packet);
-  EXPECT_EQ(1u, writer_->crypto_frames().size());
-  if (!GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
-    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
-    return;
-  }
-  // Process 1-RTT packet.
-  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
-  packet = writer_->coalesced_packet()->Clone();
-  writer_->framer()->ProcessPacket(*packet);
-  EXPECT_EQ(1u, writer_->stream_frames().size());
-}
-
-// Regression test for b/180103273
-TEST_P(QuicConnectionTest, SendMultipleConnectionCloses) {
-  if (!version().HasIetfQuicFrames() ||
-      !GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  // Finish handshake.
-  QuicConnectionPeer::SetAddressValidated(&connection_);
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  notifier_.NeuterUnencryptedData();
-  connection_.NeuterUnencryptedPackets();
-  connection_.OnHandshakeComplete();
-  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
-  connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(visitor_, GetHandshakeState())
-      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
-
-  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
-  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
-  // Verify BeforeConnectionCloseSent gets called twice while OnConnectionClosed
-  // is called once.
-  EXPECT_CALL(visitor_, BeforeConnectionCloseSent()).Times(2);
-  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
-  // Send connection close w/o closing connection.
-  QuicConnectionPeer::SendConnectionClosePacket(
-      &connection_, INTERNAL_ERROR, QUIC_INTERNAL_ERROR, "internal error");
-  // Fire blackhole detection alarm.
-  EXPECT_QUIC_BUG(connection_.GetBlackholeDetectorAlarm()->Fire(),
-                  "Already sent connection close");
-}
-
-// Regression test for b/157895910.
-TEST_P(QuicConnectionTest, EarliestSentTimeNotInitializedWhenPtoFires) {
-  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
-    return;
-  }
-  set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
-  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
-  use_tagging_decrypter();
-
-  // Received INITIAL 1.
-  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
-  connection_.SetEncrypter(ENCRYPTION_INITIAL,
-                           std::make_unique<TaggingEncrypter>(0x01));
-  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
-                           std::make_unique<TaggingEncrypter>(0x03));
-  SetDecrypter(ENCRYPTION_HANDSHAKE,
-               std::make_unique<StrictTaggingDecrypter>(0x03));
-  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<TaggingEncrypter>(0x04));
-  {
-    QuicConnection::ScopedPacketFlusher flusher(&connection_);
-    // Send INITIAL 1.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
-    // Send HANDSHAKE 2.
-    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
-                                         ENCRYPTION_HANDSHAKE);
-    // Send half RTT data.
-    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    connection_.SendStreamDataWithString(0, std::string(2000, 'b'), 0, FIN);
-  }
-
-  // Received ACKs for both INITIAL and HANDSHAKE packets.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  QuicFrames frames1;
-  QuicAckFrame ack_frame1 = InitAckFrame(1);
-  frames1.push_back(QuicFrame(&ack_frame1));
-
-  QuicFrames frames2;
-  QuicAckFrame ack_frame2 =
-      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
-  frames2.push_back(QuicFrame(&ack_frame2));
-  ProcessCoalescedPacket(
-      {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
-  // Verify PTO is not armed given the only outstanding data is half RTT data.
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_constants.cc b/quic/core/quic_constants.cc
deleted file mode 100644
index 36ede3c..0000000
--- a/quic/core/quic_constants.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_constants.h"
-
-namespace quic {
-
-const char* const kFinalOffsetHeaderKey = ":final-offset";
-
-const char* const kEPIDGoogleFrontEnd = "GFE";
-const char* const kEPIDGoogleFrontEnd0 = "GFE0";
-
-QuicPacketNumber MaxRandomInitialPacketNumber() {
-  static const QuicPacketNumber kMaxRandomInitialPacketNumber =
-      QuicPacketNumber(0x7fffffff);
-  return kMaxRandomInitialPacketNumber;
-}
-
-QuicPacketNumber FirstSendingPacketNumber() {
-  static const QuicPacketNumber kFirstSendingPacketNumber = QuicPacketNumber(1);
-  return kFirstSendingPacketNumber;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_constants.h b/quic/core/quic_constants.h
deleted file mode 100644
index 812b28b..0000000
--- a/quic/core/quic_constants.h
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
-#define QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <limits>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-// Definitions of constant values used throughout the QUIC code.
-
-namespace quic {
-
-// Simple time constants.
-const uint64_t kNumSecondsPerMinute = 60;
-const uint64_t kNumSecondsPerHour = kNumSecondsPerMinute * 60;
-const uint64_t kNumSecondsPerWeek = kNumSecondsPerHour * 24 * 7;
-const uint64_t kNumMillisPerSecond = 1000;
-const uint64_t kNumMicrosPerMilli = 1000;
-const uint64_t kNumMicrosPerSecond = kNumMicrosPerMilli * kNumMillisPerSecond;
-
-// Default number of connections for N-connection emulation.
-const uint32_t kDefaultNumConnections = 2;
-// Default initial maximum size in bytes of a QUIC packet.
-const QuicByteCount kDefaultMaxPacketSize = 1250;
-// Default initial maximum size in bytes of a QUIC packet for servers.
-const QuicByteCount kDefaultServerMaxPacketSize = 1000;
-// Maximum transmission unit on Ethernet.
-const QuicByteCount kEthernetMTU = 1500;
-// The maximum packet size of any QUIC packet over IPv6, based on ethernet's max
-// size, minus the IP and UDP headers. IPv6 has a 40 byte header, UDP adds an
-// additional 8 bytes.  This is a total overhead of 48 bytes.  Ethernet's
-// max packet size is 1500 bytes,  1500 - 48 = 1452.
-const QuicByteCount kMaxV6PacketSize = 1452;
-// The maximum packet size of any QUIC packet over IPv4.
-// 1500(Ethernet) - 20(IPv4 header) - 8(UDP header) = 1472.
-const QuicByteCount kMaxV4PacketSize = 1472;
-// The maximum incoming packet size allowed.
-const QuicByteCount kMaxIncomingPacketSize = kMaxV4PacketSize;
-// The maximum outgoing packet size allowed.
-const QuicByteCount kMaxOutgoingPacketSize = kMaxV6PacketSize;
-// ETH_MAX_MTU - MAX(sizeof(iphdr), sizeof(ip6_hdr)) - sizeof(udphdr).
-const QuicByteCount kMaxGsoPacketSize = 65535 - 40 - 8;
-// The maximal IETF DATAGRAM frame size we'll accept. Choosing 2^16 ensures
-// that it is greater than the biggest frame we could ever fit in a QUIC packet.
-const QuicByteCount kMaxAcceptedDatagramFrameSize = 65536;
-// Default value of the max_packet_size transport parameter if it is not
-// transmitted.
-const QuicByteCount kDefaultMaxPacketSizeTransportParam = 65527;
-// Default maximum packet size used in the Linux TCP implementation.
-// Used in QUIC for congestion window computations in bytes.
-const QuicByteCount kDefaultTCPMSS = 1460;
-const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
-// The minimum size of a packet which can elicit a version negotiation packet,
-// as per section 8.1 of the QUIC spec.
-const QuicByteCount kMinPacketSizeForVersionNegotiation = 1200;
-
-// We match SPDY's use of 32 (since we'd compete with SPDY).
-const QuicPacketCount kInitialCongestionWindow = 32;
-
-// Do not allow initial congestion window to be greater than 200 packets.
-const QuicPacketCount kMaxInitialCongestionWindow = 200;
-
-// Do not allow initial congestion window to be smaller than 10 packets.
-const QuicPacketCount kMinInitialCongestionWindow = 10;
-
-// Minimum size of initial flow control window, for both stream and session.
-// This is only enforced when version.AllowsLowFlowControlLimits() is false.
-const QuicByteCount kMinimumFlowControlSendWindow = 16 * 1024;  // 16 KB
-// Default size of initial flow control window, for both stream and session.
-const QuicByteCount kDefaultFlowControlSendWindow = 16 * 1024;  // 16 KB
-
-// Maximum flow control receive window limits for connection and stream.
-const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024;   // 16 MB
-const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024;  // 24 MB
-
-// Minimum size of the CWND, in packets, when doing bandwidth resumption.
-const QuicPacketCount kMinCongestionWindowForBandwidthResumption = 10;
-
-// Default size of the socket receive buffer in bytes.
-const QuicByteCount kDefaultSocketReceiveBuffer = 1024 * 1024;
-
-// The lower bound of an untrusted initial rtt value.
-const uint32_t kMinUntrustedInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli;
-
-// The lower bound of a trusted initial rtt value.
-const uint32_t kMinTrustedInitialRoundTripTimeUs = 5 * kNumMicrosPerMilli;
-
-// Don't allow a client to suggest an RTT longer than 1 second.
-const uint32_t kMaxInitialRoundTripTimeUs = kNumMicrosPerSecond;
-
-// Maximum number of open streams per connection.
-const size_t kDefaultMaxStreamsPerConnection = 100;
-
-// Number of bytes reserved for public flags in the packet header.
-const size_t kPublicFlagsSize = 1;
-// Number of bytes reserved for version number in the packet header.
-const size_t kQuicVersionSize = 4;
-
-// Minimum number of active connection IDs that an end point can maintain.
-const uint32_t kMinNumOfActiveConnectionIds = 2;
-
-// Length of the retry integrity tag in bytes.
-// https://tools.ietf.org/html/draft-ietf-quic-transport-25#section-17.2.5
-const size_t kRetryIntegrityTagLength = 16;
-
-// By default, UnackedPacketsMap allocates buffer of 64 after the first packet
-// is added.
-const int kDefaultUnackedPacketsInitialCapacity = 64;
-
-// Signifies that the QuicPacket will contain version of the protocol.
-const bool kIncludeVersion = true;
-// Signifies that the QuicPacket will include a diversification nonce.
-const bool kIncludeDiversificationNonce = true;
-
-// Header key used to identify final offset on data stream when sending HTTP/2
-// trailing headers over QUIC.
-QUIC_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
-
-// Default maximum delayed ack time, in ms.
-// Uses a 25ms delayed ack timer. Helps with better signaling
-// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
-const int64_t kDefaultDelayedAckTimeMs = 25;
-
-// Default minimum delayed ack time, in ms (used only for sender control of ack
-// frequency).
-const uint32_t kDefaultMinAckDelayTimeMs = 5;
-
-// Default shift of the ACK delay in the IETF QUIC ACK frame.
-const uint32_t kDefaultAckDelayExponent = 3;
-
-// Minimum tail loss probe time in ms.
-static const int64_t kMinTailLossProbeTimeoutMs = 10;
-
-// The timeout before the handshake succeeds.
-const int64_t kInitialIdleTimeoutSecs = 5;
-// The maximum idle timeout that can be negotiated.
-const int64_t kMaximumIdleTimeoutSecs = 60 * 10;  // 10 minutes.
-// The default timeout for a connection until the crypto handshake succeeds.
-const int64_t kMaxTimeForCryptoHandshakeSecs = 10;  // 10 secs.
-
-// Default limit on the number of undecryptable packets the connection buffers
-// before the CHLO/SHLO arrive.
-const size_t kDefaultMaxUndecryptablePackets = 10;
-
-// Default ping timeout.
-const int64_t kPingTimeoutSecs = 15;  // 15 secs.
-
-// Minimum number of RTTs between Server Config Updates (SCUP) sent to client.
-const int kMinIntervalBetweenServerConfigUpdatesRTTs = 10;
-
-// Minimum time between Server Config Updates (SCUP) sent to client.
-const int kMinIntervalBetweenServerConfigUpdatesMs = 1000;
-
-// Minimum number of packets between Server Config Updates (SCUP).
-const int kMinPacketsBetweenServerConfigUpdates = 100;
-
-// The number of open streams that a server will accept is set to be slightly
-// larger than the negotiated limit. Immediately closing the connection if the
-// client opens slightly too many streams is not ideal: the client may have sent
-// a FIN that was lost, and simultaneously opened a new stream. The number of
-// streams a server accepts is a fixed increment over the negotiated limit, or a
-// percentage increase, whichever is larger.
-const float kMaxStreamsMultiplier = 1.1f;
-const int kMaxStreamsMinimumIncrement = 10;
-
-// Available streams are ones with IDs less than the highest stream that has
-// been opened which have neither been opened or reset. The limit on the number
-// of available streams is 10 times the limit on the number of open streams.
-const int kMaxAvailableStreamsMultiplier = 10;
-
-// Track the number of promises that are not yet claimed by a
-// corresponding get.  This must be smaller than
-// kMaxAvailableStreamsMultiplier, because RST on a promised stream my
-// create available streams entries.
-const int kMaxPromisedStreamsMultiplier = kMaxAvailableStreamsMultiplier - 1;
-
-// TCP RFC calls for 1 second RTO however Linux differs from this default and
-// define the minimum RTO to 200ms, we will use the same until we have data to
-// support a higher or lower value.
-static const int64_t kMinRetransmissionTimeMs = 200;
-// The delayed ack time must not be greater than half the min RTO.
-static_assert(kDefaultDelayedAckTimeMs <= kMinRetransmissionTimeMs / 2,
-              "Delayed ack time must be less than or equal half the MinRTO");
-
-// We define an unsigned 16-bit floating point value, inspired by IEEE floats
-// (http://en.wikipedia.org/wiki/Half_precision_floating-point_format),
-// with 5-bit exponent (bias 1), 11-bit mantissa (effective 12 with hidden
-// bit) and denormals, but without signs, transfinites or fractions. Wire format
-// 16 bits (little-endian byte order) are split into exponent (high 5) and
-// mantissa (low 11) and decoded as:
-//   uint64_t value;
-//   if (exponent == 0) value = mantissa;
-//   else value = (mantissa | 1 << 11) << (exponent - 1)
-const int kUFloat16ExponentBits = 5;
-const int kUFloat16MaxExponent = (1 << kUFloat16ExponentBits) - 2;     // 30
-const int kUFloat16MantissaBits = 16 - kUFloat16ExponentBits;          // 11
-const int kUFloat16MantissaEffectiveBits = kUFloat16MantissaBits + 1;  // 12
-const uint64_t kUFloat16MaxValue =  // 0x3FFC0000000
-    ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1)
-    << kUFloat16MaxExponent;
-
-// kDiversificationNonceSize is the size, in bytes, of the nonce that a server
-// may set in the packet header to ensure that its INITIAL keys are not
-// duplicated.
-const size_t kDiversificationNonceSize = 32;
-
-// The largest gap in packets we'll accept without closing the connection.
-// This will likely have to be tuned.
-const QuicPacketCount kMaxPacketGap = 5000;
-
-// The max number of sequence number intervals that
-// QuicPeerIssuedConnetionIdManager can maintain.
-const size_t kMaxNumConnectionIdSequenceNumberIntervals = 20;
-
-// The maximum number of random padding bytes to add.
-const QuicByteCount kMaxNumRandomPaddingBytes = 256;
-
-// The size of stream send buffer data slice size in bytes. A data slice is
-// piece of stream data stored in contiguous memory, and a stream frame can
-// contain data from multiple data slices.
-const QuicByteCount kQuicStreamSendBufferSliceSize = 4 * 1024;
-
-// For When using Random Initial Packet Numbers, they can start
-// anyplace in the range 1...((2^31)-1) or 0x7fffffff
-QUIC_EXPORT_PRIVATE QuicPacketNumber MaxRandomInitialPacketNumber();
-
-// Used to represent an invalid or no control frame id.
-const QuicControlFrameId kInvalidControlFrameId = 0;
-
-// The max length a stream can have.
-const QuicByteCount kMaxStreamLength = (UINT64_C(1) << 62) - 1;
-
-// The max value that can be encoded using IETF Var Ints.
-const uint64_t kMaxIetfVarInt = UINT64_C(0x3fffffffffffffff);
-
-// The maximum stream id value that is supported - (2^32)-1
-const QuicStreamId kMaxQuicStreamId = 0xffffffff;
-
-// The maximum value that can be stored in a 32-bit QuicStreamCount.
-const QuicStreamCount kMaxQuicStreamCount = 0xffffffff;
-
-// Number of bytes reserved for packet header type.
-const size_t kPacketHeaderTypeSize = 1;
-
-// Number of bytes reserved for connection ID length.
-const size_t kConnectionIdLengthSize = 1;
-
-// Minimum length of random bytes in IETF stateless reset packet.
-const size_t kMinRandomBytesLengthInStatelessReset = 24;
-
-// Maximum length allowed for the token in a NEW_TOKEN frame.
-const size_t kMaxNewTokenTokenLength = 0xffff;
-
-// The prefix used by a source address token in a NEW_TOKEN frame.
-const uint8_t kAddressTokenPrefix = 0;
-
-// Default initial rtt used before any samples are received.
-const int kInitialRttMs = 100;
-
-// Default threshold of packet reordering before a packet is declared lost.
-static const QuicPacketCount kDefaultPacketReorderingThreshold = 3;
-
-// Default fraction (1/4) of an RTT the algorithm waits before determining a
-// packet is lost due to early retransmission by time based loss detection.
-static const int kDefaultLossDelayShift = 2;
-
-// Default fraction (1/8) of an RTT when doing IETF loss detection.
-static const int kDefaultIetfLossDelayShift = 3;
-
-// Maximum number of retransmittable packets received before sending an ack.
-const QuicPacketCount kDefaultRetransmittablePacketsBeforeAck = 2;
-// Wait for up to 10 retransmittable packets before sending an ack.
-const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10;
-// Minimum number of packets received before ack decimation is enabled.
-// This intends to avoid the beginning of slow start, when CWNDs may be
-// rapidly increasing.
-const QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
-// One quarter RTT delay when doing ack decimation.
-const float kAckDecimationDelay = 0.25;
-
-// The default alarm granularity assumed by QUIC code.
-const QuicTime::Delta kAlarmGranularity = QuicTime::Delta::FromMilliseconds(1);
-
-// Maximum number of unretired connection IDs a connection can have.
-const size_t kMaxNumConnectonIdsInUse = 10u;
-
-// Packet number of first sending packet of a connection. Please note, this
-// cannot be used as first received packet because peer can choose its starting
-// packet number.
-QUIC_EXPORT_PRIVATE QuicPacketNumber FirstSendingPacketNumber();
-
-// Used by clients to tell if a public reset is sent from a Google frontend.
-QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd;
-QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd0;
-
-// HTTP/3 Datagrams.
-enum : QuicDatagramContextId {
-  kFirstDatagramContextIdClient = 0,
-  kFirstDatagramContextIdServer = 1,
-  kDatagramContextIdIncrement = 2,
-};
-
-enum : uint64_t {
-  kHttpDatagramStreamIdDivisor = 4,
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/quic/core/quic_control_frame_manager.cc b/quic/core/quic_control_frame_manager.cc
deleted file mode 100644
index b41263b..0000000
--- a/quic/core/quic_control_frame_manager.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_control_frame_manager.h"
-
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-
-// The maximum number of buffered control frames which are waiting to be ACKed
-// or sent for the first time.
-const size_t kMaxNumControlFrames = 1000;
-
-}  // namespace
-
-QuicControlFrameManager::QuicControlFrameManager(QuicSession* session)
-    : last_control_frame_id_(kInvalidControlFrameId),
-      least_unacked_(1),
-      least_unsent_(1),
-      delegate_(session) {}
-
-QuicControlFrameManager::~QuicControlFrameManager() {
-  while (!control_frames_.empty()) {
-    DeleteFrame(&control_frames_.front());
-    control_frames_.pop_front();
-  }
-}
-
-void QuicControlFrameManager::WriteOrBufferQuicFrame(QuicFrame frame) {
-  const bool had_buffered_frames = HasBufferedFrames();
-  control_frames_.emplace_back(frame);
-  if (control_frames_.size() > kMaxNumControlFrames) {
-    delegate_->OnControlFrameManagerError(
-        QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES,
-        absl::StrCat("More than ", kMaxNumControlFrames,
-                     "buffered control frames, least_unacked: ", least_unacked_,
-                     ", least_unsent_: ", least_unsent_));
-    return;
-  }
-  if (had_buffered_frames) {
-    return;
-  }
-  WriteBufferedFrames();
-}
-
-void QuicControlFrameManager::WriteOrBufferRstStream(
-    QuicStreamId id, QuicResetStreamError error,
-    QuicStreamOffset bytes_written) {
-  QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
-  WriteOrBufferQuicFrame((QuicFrame(new QuicRstStreamFrame(
-      ++last_control_frame_id_, id, error, bytes_written))));
-}
-
-void QuicControlFrameManager::WriteOrBufferGoAway(
-    QuicErrorCode error, QuicStreamId last_good_stream_id,
-    const std::string& reason) {
-  QUIC_DVLOG(1) << "Writing GOAWAY_FRAME";
-  WriteOrBufferQuicFrame(QuicFrame(new QuicGoAwayFrame(
-      ++last_control_frame_id_, error, last_good_stream_id, reason)));
-}
-
-void QuicControlFrameManager::WriteOrBufferWindowUpdate(
-    QuicStreamId id, QuicStreamOffset byte_offset) {
-  QUIC_DVLOG(1) << "Writing WINDOW_UPDATE_FRAME";
-  WriteOrBufferQuicFrame(QuicFrame(
-      QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
-}
-
-void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
-  QUIC_DVLOG(1) << "Writing BLOCKED_FRAME";
-  WriteOrBufferQuicFrame(
-      QuicFrame(QuicBlockedFrame(++last_control_frame_id_, id)));
-}
-
-void QuicControlFrameManager::WriteOrBufferStreamsBlocked(QuicStreamCount count,
-                                                          bool unidirectional) {
-  QUIC_DVLOG(1) << "Writing STREAMS_BLOCKED Frame";
-  QUIC_CODE_COUNT(quic_streams_blocked_transmits);
-  WriteOrBufferQuicFrame(QuicFrame(QuicStreamsBlockedFrame(
-      ++last_control_frame_id_, count, unidirectional)));
-}
-
-void QuicControlFrameManager::WriteOrBufferMaxStreams(QuicStreamCount count,
-                                                      bool unidirectional) {
-  QUIC_DVLOG(1) << "Writing MAX_STREAMS Frame";
-  QUIC_CODE_COUNT(quic_max_streams_transmits);
-  WriteOrBufferQuicFrame(QuicFrame(
-      QuicMaxStreamsFrame(++last_control_frame_id_, count, unidirectional)));
-}
-
-void QuicControlFrameManager::WriteOrBufferStopSending(
-    QuicResetStreamError error, QuicStreamId stream_id) {
-  QUIC_DVLOG(1) << "Writing STOP_SENDING_FRAME";
-  WriteOrBufferQuicFrame(QuicFrame(
-      QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
-}
-
-void QuicControlFrameManager::WriteOrBufferHandshakeDone() {
-  QUIC_DVLOG(1) << "Writing HANDSHAKE_DONE";
-  WriteOrBufferQuicFrame(
-      QuicFrame(QuicHandshakeDoneFrame(++last_control_frame_id_)));
-}
-
-void QuicControlFrameManager::WriteOrBufferAckFrequency(
-    const QuicAckFrequencyFrame& ack_frequency_frame) {
-  QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame";
-  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
-  // Using the control_frame_id for sequence_number here leaves gaps in
-  // sequence_number.
-  WriteOrBufferQuicFrame(
-      QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
-                                          /*sequence_number=*/control_frame_id,
-                                          ack_frequency_frame.packet_tolerance,
-                                          ack_frequency_frame.max_ack_delay)));
-}
-
-void QuicControlFrameManager::WriteOrBufferNewConnectionId(
-    const QuicConnectionId& connection_id, uint64_t sequence_number,
-    uint64_t retire_prior_to,
-    const StatelessResetToken& stateless_reset_token) {
-  QUIC_DVLOG(1) << "Writing NEW_CONNECTION_ID frame";
-  WriteOrBufferQuicFrame(QuicFrame(new QuicNewConnectionIdFrame(
-      ++last_control_frame_id_, connection_id, sequence_number,
-      stateless_reset_token, retire_prior_to)));
-}
-
-void QuicControlFrameManager::WriteOrBufferRetireConnectionId(
-    uint64_t sequence_number) {
-  QUIC_DVLOG(1) << "Writing RETIRE_CONNECTION_ID frame";
-  WriteOrBufferQuicFrame(QuicFrame(new QuicRetireConnectionIdFrame(
-      ++last_control_frame_id_, sequence_number)));
-}
-
-void QuicControlFrameManager::WriteOrBufferNewToken(absl::string_view token) {
-  QUIC_DVLOG(1) << "Writing NEW_TOKEN frame";
-  WriteOrBufferQuicFrame(
-      QuicFrame(new QuicNewTokenFrame(++last_control_frame_id_, token)));
-}
-
-void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    QUIC_BUG(quic_bug_12727_1)
-        << "Send or retransmit a control frame with invalid control frame id";
-    return;
-  }
-  if (frame.type == WINDOW_UPDATE_FRAME) {
-    QuicStreamId stream_id = frame.window_update_frame.stream_id;
-    if (window_update_frames_.contains(stream_id) &&
-        id > window_update_frames_[stream_id]) {
-      // Consider the older window update of the same stream as acked.
-      OnControlFrameIdAcked(window_update_frames_[stream_id]);
-    }
-    window_update_frames_[stream_id] = id;
-  }
-  if (pending_retransmissions_.contains(id)) {
-    // This is retransmitted control frame.
-    pending_retransmissions_.erase(id);
-    return;
-  }
-  if (id > least_unsent_) {
-    QUIC_BUG(quic_bug_10517_1)
-        << "Try to send control frames out of order, id: " << id
-        << " least_unsent: " << least_unsent_;
-    delegate_->OnControlFrameManagerError(
-        QUIC_INTERNAL_ERROR, "Try to send control frames out of order");
-    return;
-  }
-  ++least_unsent_;
-}
-
-bool QuicControlFrameManager::OnControlFrameAcked(const QuicFrame& frame) {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (!OnControlFrameIdAcked(id)) {
-    return false;
-  }
-  if (frame.type == WINDOW_UPDATE_FRAME) {
-    QuicStreamId stream_id = frame.window_update_frame.stream_id;
-    if (window_update_frames_.contains(stream_id) &&
-        window_update_frames_[stream_id] == id) {
-      window_update_frames_.erase(stream_id);
-    }
-  }
-  return true;
-}
-
-void QuicControlFrameManager::OnControlFrameLost(const QuicFrame& frame) {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    // Frame does not have a valid control frame ID, ignore it.
-    return;
-  }
-  if (id >= least_unsent_) {
-    QUIC_BUG(quic_bug_10517_2) << "Try to mark unsent control frame as lost";
-    delegate_->OnControlFrameManagerError(
-        QUIC_INTERNAL_ERROR, "Try to mark unsent control frame as lost");
-    return;
-  }
-  if (id < least_unacked_ ||
-      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
-          kInvalidControlFrameId) {
-    // This frame has already been acked.
-    return;
-  }
-  if (!pending_retransmissions_.contains(id)) {
-    pending_retransmissions_[id] = true;
-    QUIC_BUG_IF(quic_bug_12727_2,
-                pending_retransmissions_.size() > control_frames_.size())
-        << "least_unacked_: " << least_unacked_
-        << ", least_unsent_: " << least_unsent_;
-  }
-}
-
-bool QuicControlFrameManager::IsControlFrameOutstanding(
-    const QuicFrame& frame) const {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    // Frame without a control frame ID should not be retransmitted.
-    return false;
-  }
-  // Consider this frame is outstanding if it does not get acked.
-  return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
-         GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
-             kInvalidControlFrameId;
-}
-
-bool QuicControlFrameManager::HasPendingRetransmission() const {
-  return !pending_retransmissions_.empty();
-}
-
-bool QuicControlFrameManager::WillingToWrite() const {
-  return HasPendingRetransmission() || HasBufferedFrames();
-}
-
-QuicFrame QuicControlFrameManager::NextPendingRetransmission() const {
-  QUIC_BUG_IF(quic_bug_12727_3, pending_retransmissions_.empty())
-      << "Unexpected call to NextPendingRetransmission() with empty pending "
-      << "retransmission list.";
-  QuicControlFrameId id = pending_retransmissions_.begin()->first;
-  return control_frames_.at(id - least_unacked_);
-}
-
-void QuicControlFrameManager::OnCanWrite() {
-  if (HasPendingRetransmission()) {
-    // Exit early to allow streams to write pending retransmissions if any.
-    WritePendingRetransmission();
-    return;
-  }
-  WriteBufferedFrames();
-}
-
-bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame,
-                                                     TransmissionType type) {
-  QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
-                type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    // Frame does not have a valid control frame ID, ignore it. Returns true
-    // to allow writing following frames.
-    return true;
-  }
-  if (id >= least_unsent_) {
-    QUIC_BUG(quic_bug_10517_3) << "Try to retransmit unsent control frame";
-    delegate_->OnControlFrameManagerError(
-        QUIC_INTERNAL_ERROR, "Try to retransmit unsent control frame");
-    return false;
-  }
-  if (id < least_unacked_ ||
-      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
-          kInvalidControlFrameId) {
-    // This frame has already been acked.
-    return true;
-  }
-  QuicFrame copy = CopyRetransmittableControlFrame(frame);
-  QUIC_DVLOG(1) << "control frame manager is forced to retransmit frame: "
-                << frame;
-  if (delegate_->WriteControlFrame(copy, type)) {
-    return true;
-  }
-  DeleteFrame(&copy);
-  return false;
-}
-
-void QuicControlFrameManager::WriteBufferedFrames() {
-  while (HasBufferedFrames()) {
-    QuicFrame frame_to_send =
-        control_frames_.at(least_unsent_ - least_unacked_);
-    QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
-    if (!delegate_->WriteControlFrame(copy, NOT_RETRANSMISSION)) {
-      // Connection is write blocked.
-      DeleteFrame(&copy);
-      break;
-    }
-    OnControlFrameSent(frame_to_send);
-  }
-}
-
-void QuicControlFrameManager::WritePendingRetransmission() {
-  while (HasPendingRetransmission()) {
-    QuicFrame pending = NextPendingRetransmission();
-    QuicFrame copy = CopyRetransmittableControlFrame(pending);
-    if (!delegate_->WriteControlFrame(copy, LOSS_RETRANSMISSION)) {
-      // Connection is write blocked.
-      DeleteFrame(&copy);
-      break;
-    }
-    OnControlFrameSent(pending);
-  }
-}
-
-bool QuicControlFrameManager::OnControlFrameIdAcked(QuicControlFrameId id) {
-  if (id == kInvalidControlFrameId) {
-    // Frame does not have a valid control frame ID, ignore it.
-    return false;
-  }
-  if (id >= least_unsent_) {
-    QUIC_BUG(quic_bug_10517_4) << "Try to ack unsent control frame";
-    delegate_->OnControlFrameManagerError(QUIC_INTERNAL_ERROR,
-                                          "Try to ack unsent control frame");
-    return false;
-  }
-  if (id < least_unacked_ ||
-      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
-          kInvalidControlFrameId) {
-    // This frame has already been acked.
-    return false;
-  }
-
-  // Set control frame ID of acked frames to 0.
-  SetControlFrameId(kInvalidControlFrameId,
-                    &control_frames_.at(id - least_unacked_));
-  // Remove acked control frames from pending retransmissions.
-  pending_retransmissions_.erase(id);
-  // Clean up control frames queue and increment least_unacked_.
-  while (!control_frames_.empty() &&
-         GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
-    DeleteFrame(&control_frames_.front());
-    control_frames_.pop_front();
-    ++least_unacked_;
-  }
-  return true;
-}
-
-bool QuicControlFrameManager::HasBufferedFrames() const {
-  return least_unsent_ < least_unacked_ + control_frames_.size();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_control_frame_manager.h b/quic/core/quic_control_frame_manager.h
deleted file mode 100644
index e83fc3b..0000000
--- a/quic/core/quic_control_frame_manager.h
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "common/quiche_circular_deque.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class QuicSession;
-
-namespace test {
-class QuicControlFrameManagerPeer;
-}  // namespace test
-
-// Control frame manager contains a list of sent control frames with valid
-// control frame IDs. Control frames without valid control frame IDs include:
-// (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
-// STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
-// APPLICATION_CLOSE frames.
-// New control frames are added to the tail of the list when they are added to
-// the generator. Control frames are removed from the head of the list when they
-// get acked. Control frame manager also keeps track of lost control frames
-// which need to be retransmitted.
-class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
- public:
-  class QUIC_EXPORT_PRIVATE DelegateInterface {
-   public:
-    virtual ~DelegateInterface() = default;
-
-    // Notifies the delegate of errors.
-    virtual void OnControlFrameManagerError(QuicErrorCode error_code,
-                                            std::string error_details) = 0;
-
-    virtual bool WriteControlFrame(const QuicFrame& frame,
-                                   TransmissionType type) = 0;
-  };
-
-  explicit QuicControlFrameManager(QuicSession* session);
-  QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
-  QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
-  ~QuicControlFrameManager();
-
-  // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
-  // immediately.
-  void WriteOrBufferRstStream(QuicControlFrameId id, QuicResetStreamError error,
-                              QuicStreamOffset bytes_written);
-
-  // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
-  // immediately.
-  void WriteOrBufferGoAway(QuicErrorCode error,
-                           QuicStreamId last_good_stream_id,
-                           const std::string& reason);
-
-  // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
-  // immediately.
-  void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
-
-  // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
-  // immediately.
-  void WriteOrBufferBlocked(QuicStreamId id);
-
-  // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
-  // sent immediately.
-  void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
-
-  // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
-  // immediately.
-  void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
-
-  // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
-  // can not be sent immediately.
-  void WriteOrBufferStopSending(QuicResetStreamError error,
-                                QuicStreamId stream_id);
-
-  // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
-  // be sent immediately.
-  void WriteOrBufferHandshakeDone();
-
-  // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
-  // sent immediately.
-  void WriteOrBufferAckFrequency(
-      const QuicAckFrequencyFrame& ack_frequency_frame);
-
-  // Tries to send a NEW_CONNECTION_ID frame. The frame is buffered if it cannot
-  // be sent immediately.
-  void WriteOrBufferNewConnectionId(
-      const QuicConnectionId& connection_id, uint64_t sequence_number,
-      uint64_t retire_prior_to,
-      const StatelessResetToken& stateless_reset_token);
-
-  // Tries to send a RETIRE_CONNNECTION_ID frame. The frame is buffered if it
-  // cannot be sent immediately.
-  void WriteOrBufferRetireConnectionId(uint64_t sequence_number);
-
-  // Tries to send a NEW_TOKEN frame. Buffers the frame if it cannot be sent
-  // immediately.
-  void WriteOrBufferNewToken(absl::string_view token);
-
-  // Called when |frame| gets acked. Returns true if |frame| gets acked for the
-  // first time, return false otherwise.
-  bool OnControlFrameAcked(const QuicFrame& frame);
-
-  // Called when |frame| is considered as lost.
-  void OnControlFrameLost(const QuicFrame& frame);
-
-  // Called by the session when the connection becomes writable.
-  void OnCanWrite();
-
-  // Retransmit |frame| if it is still outstanding. Returns false if the frame
-  // does not get retransmitted because the connection is blocked. Otherwise,
-  // returns true.
-  bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
-
-  // Returns true if |frame| is outstanding and waiting to be acked. Returns
-  // false otherwise.
-  bool IsControlFrameOutstanding(const QuicFrame& frame) const;
-
-  // Returns true if there is any lost control frames waiting to be
-  // retransmitted.
-  bool HasPendingRetransmission() const;
-
-  // Returns true if there are any lost or new control frames waiting to be
-  // sent.
-  bool WillingToWrite() const;
-
- private:
-  friend class test::QuicControlFrameManagerPeer;
-
-  // Tries to write buffered control frames to the peer.
-  void WriteBufferedFrames();
-
-  // Called when |frame| is sent for the first time or gets retransmitted.
-  void OnControlFrameSent(const QuicFrame& frame);
-
-  // Writes pending retransmissions if any.
-  void WritePendingRetransmission();
-
-  // Called when frame with |id| gets acked. Returns true if |id| gets acked for
-  // the first time, return false otherwise.
-  bool OnControlFrameIdAcked(QuicControlFrameId id);
-
-  // Retrieves the next pending retransmission. This must only be called when
-  // there are pending retransmissions.
-  QuicFrame NextPendingRetransmission() const;
-
-  // Returns true if there are buffered frames waiting to be sent for the first
-  // time.
-  bool HasBufferedFrames() const;
-
-  // Writes or buffers a control frame.  Frame is buffered if there already
-  // are frames waiting to be sent. If no others waiting, will try to send the
-  // frame.
-  void WriteOrBufferQuicFrame(QuicFrame frame);
-
-  quiche::QuicheCircularDeque<QuicFrame> control_frames_;
-
-  // Id of latest saved control frame. 0 if no control frame has been saved.
-  QuicControlFrameId last_control_frame_id_;
-
-  // The control frame at the 0th index of control_frames_.
-  QuicControlFrameId least_unacked_;
-
-  // ID of the least unsent control frame.
-  QuicControlFrameId least_unsent_;
-
-  // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
-  // is not used here.
-  // Lost control frames waiting to be retransmitted.
-  quiche::QuicheLinkedHashMap<QuicControlFrameId, bool>
-      pending_retransmissions_;
-
-  DelegateInterface* delegate_;
-
-  // Last sent window update frame for each stream.
-  absl::flat_hash_map<QuicStreamId, QuicControlFrameId> window_update_frames_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
diff --git a/quic/core/quic_control_frame_manager_test.cc b/quic/core/quic_control_frame_manager_test.cc
deleted file mode 100644
index 0fb836a..0000000
--- a/quic/core/quic_control_frame_manager_test.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_control_frame_manager.h"
-
-#include <utility>
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_retire_connection_id_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-class QuicControlFrameManagerPeer {
- public:
-  static size_t QueueSize(QuicControlFrameManager* manager) {
-    return manager->control_frames_.size();
-  }
-};
-
-namespace {
-
-const QuicStreamId kTestStreamId = 5;
-const QuicRstStreamErrorCode kTestStopSendingCode =
-    QUIC_STREAM_ENCODER_STREAM_ERROR;
-
-class QuicControlFrameManagerTest : public QuicTest {
- public:
-  bool SaveControlFrame(const QuicFrame& frame, TransmissionType /*type*/) {
-    frame_ = frame;
-    return true;
-  }
-
- protected:
-  // Pre-fills the control frame queue with the following frames:
-  //  ID Type
-  //  1  RST_STREAM
-  //  2  GO_AWAY
-  //  3  WINDOW_UPDATE
-  //  4  BLOCKED
-  //  5  STOP_SENDING
-  // This is verified. The tests then perform manipulations on these.
-  void Initialize() {
-    connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
-                                         Perspective::IS_SERVER);
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
-    manager_ = std::make_unique<QuicControlFrameManager>(session_.get());
-    EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
-    EXPECT_FALSE(manager_->HasPendingRetransmission());
-    EXPECT_FALSE(manager_->WillingToWrite());
-
-    EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-    manager_->WriteOrBufferRstStream(
-        kTestStreamId,
-        QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
-    manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
-                                  "Going away.");
-    manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
-    manager_->WriteOrBufferBlocked(kTestStreamId);
-    manager_->WriteOrBufferStopSending(
-        QuicResetStreamError::FromInternal(kTestStopSendingCode),
-        kTestStreamId);
-    number_of_frames_ = 5u;
-    EXPECT_EQ(number_of_frames_,
-              QuicControlFrameManagerPeer::QueueSize(manager_.get()));
-    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
-    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
-    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
-    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
-    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
-
-    EXPECT_FALSE(manager_->HasPendingRetransmission());
-    EXPECT_TRUE(manager_->WillingToWrite());
-  }
-
-  QuicRstStreamFrame rst_stream_ = {1, kTestStreamId, QUIC_STREAM_CANCELLED, 0};
-  QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
-                             "Going away."};
-  QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
-  QuicBlockedFrame blocked_ = {4, kTestStreamId};
-  QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnection* connection_;
-  std::unique_ptr<StrictMock<MockQuicSession>> session_;
-  std::unique_ptr<QuicControlFrameManager> manager_;
-  QuicFrame frame_;
-  size_t number_of_frames_;
-};
-
-TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
-  Initialize();
-  InSequence s;
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(3)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  // Send control frames 1, 2, 3.
-  manager_->OnCanWrite();
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
-
-  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(window_update_)));
-  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
-  EXPECT_EQ(number_of_frames_,
-            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
-
-  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
-  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
-  EXPECT_EQ(number_of_frames_,
-            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
-  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&rst_stream_)));
-  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
-  // Only after the first frame in the queue is acked do the frames get
-  // removed ... now see that the length has been reduced by 3.
-  EXPECT_EQ(number_of_frames_ - 3u,
-            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
-  // Duplicate ack.
-  EXPECT_FALSE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
-
-  EXPECT_FALSE(manager_->HasPendingRetransmission());
-  EXPECT_TRUE(manager_->WillingToWrite());
-
-  // Send control frames 4, 5.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-  EXPECT_FALSE(manager_->WillingToWrite());
-}
-
-TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
-  Initialize();
-  InSequence s;
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(3)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  // Send control frames 1, 2, 3.
-  manager_->OnCanWrite();
-
-  // Lost control frames 1, 2, 3.
-  manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
-  manager_->OnControlFrameLost(QuicFrame(&goaway_));
-  manager_->OnControlFrameLost(QuicFrame(window_update_));
-  EXPECT_TRUE(manager_->HasPendingRetransmission());
-
-  // Ack control frame 2.
-  manager_->OnControlFrameAcked(QuicFrame(&goaway_));
-
-  // Retransmit control frames 1, 3.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(2)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-  EXPECT_FALSE(manager_->HasPendingRetransmission());
-  EXPECT_TRUE(manager_->WillingToWrite());
-
-  // Send control frames 4, 5, and 6.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(number_of_frames_ - 3u)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-  EXPECT_FALSE(manager_->WillingToWrite());
-}
-
-TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) {
-  Initialize();
-  InSequence s;
-  // Send control frames 1, 2, 3, 4.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(number_of_frames_)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-
-  // Ack control frame 2.
-  manager_->OnControlFrameAcked(QuicFrame(&goaway_));
-  // Do not retransmit an acked frame
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(0);
-  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_),
-                                               PTO_RETRANSMISSION));
-
-  // Retransmit control frame 3.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
-                                               PTO_RETRANSMISSION));
-
-  // Retransmit control frame 4, and connection is write blocked.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
-                                                PTO_RETRANSMISSION));
-}
-
-TEST_F(QuicControlFrameManagerTest, SendAndAckAckFrequencyFrame) {
-  Initialize();
-  InSequence s;
-  // Send Non-AckFrequency frame 1-5.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(5)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  manager_->OnCanWrite();
-
-  // Send AckFrequencyFrame as frame 6.
-  QuicAckFrequencyFrame frame_to_send;
-  frame_to_send.packet_tolerance = 10;
-  frame_to_send.max_ack_delay = QuicTime::Delta::FromMilliseconds(24);
-  manager_->WriteOrBufferAckFrequency(frame_to_send);
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-
-  // Ack AckFrequencyFrame.
-  QuicAckFrequencyFrame expected_ack_frequency = {
-      6, 6, 10, QuicTime::Delta::FromMilliseconds(24)};
-  EXPECT_TRUE(
-      manager_->OnControlFrameAcked(QuicFrame(&expected_ack_frequency)));
-}
-
-TEST_F(QuicControlFrameManagerTest, NewAndRetireConnectionIdFrames) {
-  Initialize();
-  InSequence s;
-
-  // Send other frames 1-5.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(5)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(2)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  // Send NewConnectionIdFrame as frame 6.
-  manager_->WriteOrBufferNewConnectionId(
-      TestConnectionId(3), /*sequence_number=*/2, /*retire_prior_to=*/1,
-      /*stateless_reset_token=*/
-      {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1});
-  // Send RetireConnectionIdFrame as frame 7.
-  manager_->WriteOrBufferRetireConnectionId(/*sequence_number=*/0);
-  manager_->OnCanWrite();
-
-  // Ack both frames.
-  QuicNewConnectionIdFrame new_connection_id_frame;
-  new_connection_id_frame.control_frame_id = 6;
-  QuicRetireConnectionIdFrame retire_connection_id_frame;
-  retire_connection_id_frame.control_frame_id = 7;
-  EXPECT_TRUE(
-      manager_->OnControlFrameAcked(QuicFrame(&new_connection_id_frame)));
-  EXPECT_TRUE(
-      manager_->OnControlFrameAcked(QuicFrame(&retire_connection_id_frame)));
-}
-
-TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) {
-  Initialize();
-  // Send two more window updates of the same stream.
-  manager_->WriteOrBufferWindowUpdate(kTestStreamId, 200);
-  QuicWindowUpdateFrame window_update2(number_of_frames_ + 1, kTestStreamId,
-                                       200);
-
-  manager_->WriteOrBufferWindowUpdate(kTestStreamId, 300);
-  QuicWindowUpdateFrame window_update3(number_of_frames_ + 2, kTestStreamId,
-                                       300);
-  InSequence s;
-  // Flush all buffered control frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-
-  // Mark all 3 window updates as lost.
-  manager_->OnControlFrameLost(QuicFrame(window_update_));
-  manager_->OnControlFrameLost(QuicFrame(window_update2));
-  manager_->OnControlFrameLost(QuicFrame(window_update3));
-  EXPECT_TRUE(manager_->HasPendingRetransmission());
-  EXPECT_TRUE(manager_->WillingToWrite());
-
-  // Verify only the latest window update gets retransmitted.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
-  manager_->OnCanWrite();
-  EXPECT_EQ(number_of_frames_ + 2u,
-            frame_.window_update_frame.control_frame_id);
-  EXPECT_FALSE(manager_->HasPendingRetransmission());
-  EXPECT_FALSE(manager_->WillingToWrite());
-  DeleteFrame(&frame_);
-}
-
-TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) {
-  Initialize();
-  // Send two more window updates of different streams.
-  manager_->WriteOrBufferWindowUpdate(kTestStreamId + 2, 200);
-  QuicWindowUpdateFrame window_update2(5, kTestStreamId + 2, 200);
-
-  manager_->WriteOrBufferWindowUpdate(kTestStreamId + 4, 300);
-  QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
-  InSequence s;
-  // Flush all buffered control frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-
-  // Mark all 3 window updates as lost.
-  manager_->OnControlFrameLost(QuicFrame(window_update_));
-  manager_->OnControlFrameLost(QuicFrame(window_update2));
-  manager_->OnControlFrameLost(QuicFrame(window_update3));
-  EXPECT_TRUE(manager_->HasPendingRetransmission());
-  EXPECT_TRUE(manager_->WillingToWrite());
-
-  // Verify all 3 window updates get retransmitted.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(3)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  manager_->OnCanWrite();
-  EXPECT_FALSE(manager_->HasPendingRetransmission());
-  EXPECT_FALSE(manager_->WillingToWrite());
-}
-
-TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
-  Initialize();
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(5)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  // Flush buffered frames.
-  manager_->OnCanWrite();
-  // Write 995 control frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
-  for (size_t i = 0; i < 995; ++i) {
-    manager_->WriteOrBufferRstStream(
-        kTestStreamId,
-        QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
-  }
-  // Verify write one more control frame causes connection close.
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, _,
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  manager_->WriteOrBufferRstStream(
-      kTestStreamId, QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED),
-      0);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_crypto_client_handshaker.cc b/quic/core/quic_crypto_client_handshaker.cc
deleted file mode 100644
index 872b050..0000000
--- a/quic/core/quic_crypto_client_handshaker.cc
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_handshaker.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
-    ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent)
-    : parent_(parent) {}
-
-QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
-    ~ProofVerifierCallbackImpl() {}
-
-void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Run(
-    bool ok,
-    const std::string& error_details,
-    std::unique_ptr<ProofVerifyDetails>* details) {
-  if (parent_ == nullptr) {
-    return;
-  }
-
-  parent_->verify_ok_ = ok;
-  parent_->verify_error_details_ = error_details;
-  parent_->verify_details_ = std::move(*details);
-  parent_->proof_verify_callback_ = nullptr;
-  parent_->DoHandshakeLoop(nullptr);
-
-  // The ProofVerifier owns this object and will delete it when this method
-  // returns.
-}
-
-void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
-  parent_ = nullptr;
-}
-
-QuicCryptoClientHandshaker::QuicCryptoClientHandshaker(
-    const QuicServerId& server_id,
-    QuicCryptoClientStream* stream,
-    QuicSession* session,
-    std::unique_ptr<ProofVerifyContext> verify_context,
-    QuicCryptoClientConfig* crypto_config,
-    QuicCryptoClientStream::ProofHandler* proof_handler)
-    : QuicCryptoHandshaker(stream, session),
-      stream_(stream),
-      session_(session),
-      delegate_(session),
-      next_state_(STATE_IDLE),
-      num_client_hellos_(0),
-      crypto_config_(crypto_config),
-      server_id_(server_id),
-      generation_counter_(0),
-      verify_context_(std::move(verify_context)),
-      proof_verify_callback_(nullptr),
-      proof_handler_(proof_handler),
-      verify_ok_(false),
-      proof_verify_start_time_(QuicTime::Zero()),
-      num_scup_messages_received_(0),
-      encryption_established_(false),
-      one_rtt_keys_available_(false),
-      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
-
-QuicCryptoClientHandshaker::~QuicCryptoClientHandshaker() {
-  if (proof_verify_callback_) {
-    proof_verify_callback_->Cancel();
-  }
-}
-
-void QuicCryptoClientHandshaker::OnHandshakeMessage(
-    const CryptoHandshakeMessage& message) {
-  QuicCryptoHandshaker::OnHandshakeMessage(message);
-  if (message.tag() == kSCUP) {
-    if (!one_rtt_keys_available()) {
-      stream_->OnUnrecoverableError(
-          QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
-          "Early SCUP disallowed");
-      return;
-    }
-
-    // |message| is an update from the server, so we treat it differently from a
-    // handshake message.
-    HandleServerConfigUpdateMessage(message);
-    num_scup_messages_received_++;
-    return;
-  }
-
-  // Do not process handshake messages after the handshake is confirmed.
-  if (one_rtt_keys_available()) {
-    stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
-                                  "Unexpected handshake message");
-    return;
-  }
-
-  DoHandshakeLoop(&message);
-}
-
-bool QuicCryptoClientHandshaker::CryptoConnect() {
-  next_state_ = STATE_INITIALIZE;
-  DoHandshakeLoop(nullptr);
-  return session()->connection()->connected();
-}
-
-int QuicCryptoClientHandshaker::num_sent_client_hellos() const {
-  return num_client_hellos_;
-}
-
-bool QuicCryptoClientHandshaker::IsResumption() const {
-  QUIC_BUG_IF(quic_bug_12522_1, !one_rtt_keys_available_);
-  // While 0-RTT handshakes could be considered to be like resumption, QUIC
-  // Crypto doesn't have the same notion of a resumption like TLS does.
-  return false;
-}
-
-bool QuicCryptoClientHandshaker::EarlyDataAccepted() const {
-  QUIC_BUG_IF(quic_bug_12522_2, !one_rtt_keys_available_);
-  return num_client_hellos_ == 1;
-}
-
-ssl_early_data_reason_t QuicCryptoClientHandshaker::EarlyDataReason() const {
-  return early_data_reason_;
-}
-
-bool QuicCryptoClientHandshaker::ReceivedInchoateReject() const {
-  QUIC_BUG_IF(quic_bug_12522_3, !one_rtt_keys_available_);
-  return num_client_hellos_ >= 3;
-}
-
-int QuicCryptoClientHandshaker::num_scup_messages_received() const {
-  return num_scup_messages_received_;
-}
-
-std::string QuicCryptoClientHandshaker::chlo_hash() const {
-  return chlo_hash_;
-}
-
-bool QuicCryptoClientHandshaker::encryption_established() const {
-  return encryption_established_;
-}
-
-bool QuicCryptoClientHandshaker::one_rtt_keys_available() const {
-  return one_rtt_keys_available_;
-}
-
-const QuicCryptoNegotiatedParameters&
-QuicCryptoClientHandshaker::crypto_negotiated_params() const {
-  return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* QuicCryptoClientHandshaker::crypto_message_parser() {
-  return QuicCryptoHandshaker::crypto_message_parser();
-}
-
-HandshakeState QuicCryptoClientHandshaker::GetHandshakeState() const {
-  return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-}
-
-void QuicCryptoClientHandshaker::OnHandshakeDoneReceived() {
-  QUICHE_DCHECK(false);
-}
-
-void QuicCryptoClientHandshaker::OnNewTokenReceived(
-    absl::string_view /*token*/) {
-  QUICHE_DCHECK(false);
-}
-
-size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
-    EncryptionLevel level) const {
-  return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  // Key update is only defined in QUIC+TLS.
-  QUICHE_DCHECK(false);
-  return nullptr;
-}
-
-std::unique_ptr<QuicEncrypter>
-QuicCryptoClientHandshaker::CreateCurrentOneRttEncrypter() {
-  // Key update is only defined in QUIC+TLS.
-  QUICHE_DCHECK(false);
-  return nullptr;
-}
-
-void QuicCryptoClientHandshaker::OnConnectionClosed(
-    QuicErrorCode /*error*/,
-    ConnectionCloseSource /*source*/) {
-  next_state_ = STATE_CONNECTION_CLOSED;
-}
-
-void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
-    const CryptoHandshakeMessage& server_config_update) {
-  QUICHE_DCHECK(server_config_update.tag() == kSCUP);
-  std::string error_details;
-  QuicCryptoClientConfig::CachedState* cached =
-      crypto_config_->LookupOrCreate(server_id_);
-  QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
-      server_config_update, session()->connection()->clock()->WallNow(),
-      session()->transport_version(), chlo_hash_, cached,
-      crypto_negotiated_params_, &error_details);
-
-  if (error != QUIC_NO_ERROR) {
-    stream_->OnUnrecoverableError(
-        error, "Server config update invalid: " + error_details);
-    return;
-  }
-
-  QUICHE_DCHECK(one_rtt_keys_available());
-  if (proof_verify_callback_) {
-    proof_verify_callback_->Cancel();
-  }
-  next_state_ = STATE_INITIALIZE_SCUP;
-  DoHandshakeLoop(nullptr);
-}
-
-void QuicCryptoClientHandshaker::DoHandshakeLoop(
-    const CryptoHandshakeMessage* in) {
-  QuicCryptoClientConfig::CachedState* cached =
-      crypto_config_->LookupOrCreate(server_id_);
-
-  QuicAsyncStatus rv = QUIC_SUCCESS;
-  do {
-    QUICHE_CHECK_NE(STATE_NONE, next_state_);
-    const State state = next_state_;
-    next_state_ = STATE_IDLE;
-    rv = QUIC_SUCCESS;
-    switch (state) {
-      case STATE_INITIALIZE:
-        DoInitialize(cached);
-        break;
-      case STATE_SEND_CHLO:
-        DoSendCHLO(cached);
-        return;  // return waiting to hear from server.
-      case STATE_RECV_REJ:
-        DoReceiveREJ(in, cached);
-        break;
-      case STATE_VERIFY_PROOF:
-        rv = DoVerifyProof(cached);
-        break;
-      case STATE_VERIFY_PROOF_COMPLETE:
-        DoVerifyProofComplete(cached);
-        break;
-      case STATE_RECV_SHLO:
-        DoReceiveSHLO(in, cached);
-        break;
-      case STATE_IDLE:
-        // This means that the peer sent us a message that we weren't expecting.
-        stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                      "Handshake in idle state");
-        return;
-      case STATE_INITIALIZE_SCUP:
-        DoInitializeServerConfigUpdate(cached);
-        break;
-      case STATE_NONE:
-        QUIC_NOTREACHED();
-        return;
-      case STATE_CONNECTION_CLOSED:
-        rv = QUIC_FAILURE;
-        return;  // We are done.
-    }
-  } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
-}
-
-void QuicCryptoClientHandshaker::DoInitialize(
-    QuicCryptoClientConfig::CachedState* cached) {
-  if (!cached->IsEmpty() && !cached->signature().empty()) {
-    // Note that we verify the proof even if the cached proof is valid.
-    // This allows us to respond to CA trust changes or certificate
-    // expiration because it may have been a while since we last verified
-    // the proof.
-    QUICHE_DCHECK(crypto_config_->proof_verifier());
-    // Track proof verification time when cached server config is used.
-    proof_verify_start_time_ = session()->connection()->clock()->Now();
-    chlo_hash_ = cached->chlo_hash();
-    // If the cached state needs to be verified, do it now.
-    next_state_ = STATE_VERIFY_PROOF;
-  } else {
-    next_state_ = STATE_SEND_CHLO;
-  }
-}
-
-void QuicCryptoClientHandshaker::DoSendCHLO(
-    QuicCryptoClientConfig::CachedState* cached) {
-  // Send the client hello in plaintext.
-  session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  encryption_established_ = false;
-  if (num_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) {
-    stream_->OnUnrecoverableError(
-        QUIC_CRYPTO_TOO_MANY_REJECTS,
-        absl::StrCat("More than ", QuicCryptoClientStream::kMaxClientHellos,
-                     " rejects"));
-    return;
-  }
-  num_client_hellos_++;
-
-  CryptoHandshakeMessage out;
-  QUICHE_DCHECK(session() != nullptr);
-  QUICHE_DCHECK(session()->config() != nullptr);
-  // Send all the options, regardless of whether we're sending an
-  // inchoate or subsequent hello.
-  session()->config()->ToHandshakeMessage(&out, session()->transport_version());
-
-  bool fill_inchoate_client_hello = false;
-  if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
-    early_data_reason_ = ssl_early_data_no_session_offered;
-    fill_inchoate_client_hello = true;
-  } else if (session()->config()->HasClientRequestedIndependentOption(
-                 kQNZ2, session()->perspective()) &&
-             num_client_hellos_ == 1) {
-    early_data_reason_ = ssl_early_data_disabled;
-    fill_inchoate_client_hello = true;
-  }
-  if (fill_inchoate_client_hello) {
-    crypto_config_->FillInchoateClientHello(
-        server_id_, session()->supported_versions().front(), cached,
-        session()->connection()->random_generator(),
-        /* demand_x509_proof= */ true, crypto_negotiated_params_, &out);
-    // Pad the inchoate client hello to fill up a packet.
-    const QuicByteCount kFramingOverhead = 50;  // A rough estimate.
-    const QuicByteCount max_packet_size =
-        session()->connection()->max_packet_length();
-    if (max_packet_size <= kFramingOverhead) {
-      QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
-                        << ") has no room for framing overhead.";
-      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                                    "max_packet_size too smalll");
-      return;
-    }
-    if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
-      QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
-      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR, "CHLO too large");
-      return;
-    }
-    next_state_ = STATE_RECV_REJ;
-    chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
-    session()->connection()->set_fully_pad_crypto_handshake_packets(
-        crypto_config_->pad_inchoate_hello());
-    SendHandshakeMessage(out, ENCRYPTION_INITIAL);
-    return;
-  }
-
-  std::string error_details;
-  QuicErrorCode error = crypto_config_->FillClientHello(
-      server_id_, session()->connection()->connection_id(),
-      session()->supported_versions().front(),
-      session()->connection()->version(), cached,
-      session()->connection()->clock()->WallNow(),
-      session()->connection()->random_generator(), crypto_negotiated_params_,
-      &out, &error_details);
-  if (error != QUIC_NO_ERROR) {
-    // Flush the cached config so that, if it's bad, the server has a
-    // chance to send us another in the future.
-    cached->InvalidateServerConfig();
-    stream_->OnUnrecoverableError(error, error_details);
-    return;
-  }
-  chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
-  if (cached->proof_verify_details()) {
-    proof_handler_->OnProofVerifyDetailsAvailable(
-        *cached->proof_verify_details());
-  }
-  next_state_ = STATE_RECV_SHLO;
-  session()->connection()->set_fully_pad_crypto_handshake_packets(
-      crypto_config_->pad_full_hello());
-  SendHandshakeMessage(out, ENCRYPTION_INITIAL);
-  // Be prepared to decrypt with the new server write key.
-  delegate_->OnNewEncryptionKeyAvailable(
-      ENCRYPTION_ZERO_RTT,
-      std::move(crypto_negotiated_params_->initial_crypters.encrypter));
-  delegate_->OnNewDecryptionKeyAvailable(
-      ENCRYPTION_ZERO_RTT,
-      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
-      /*set_alternative_decrypter=*/true,
-      /*latch_once_used=*/true);
-  encryption_established_ = true;
-  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  if (early_data_reason_ == ssl_early_data_unknown && num_client_hellos_ > 1) {
-    early_data_reason_ = ssl_early_data_peer_declined;
-  }
-}
-
-void QuicCryptoClientHandshaker::DoReceiveREJ(
-    const CryptoHandshakeMessage* in,
-    QuicCryptoClientConfig::CachedState* cached) {
-  // We sent a dummy CHLO because we didn't have enough information to
-  // perform a handshake, or we sent a full hello that the server
-  // rejected. Here we hope to have a REJ that contains the information
-  // that we need.
-  if (in->tag() != kREJ) {
-    next_state_ = STATE_NONE;
-    stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                  "Expected REJ");
-    return;
-  }
-
-  QuicTagVector reject_reasons;
-  static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
-  if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) {
-    uint32_t packed_error = 0;
-    for (size_t i = 0; i < reject_reasons.size(); ++i) {
-      // HANDSHAKE_OK is 0 and don't report that as error.
-      if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
-        continue;
-      }
-      HandshakeFailureReason reason =
-          static_cast<HandshakeFailureReason>(reject_reasons[i]);
-      packed_error |= 1 << (reason - 1);
-    }
-    QUIC_DVLOG(1) << "Reasons for rejection: " << packed_error;
-    if (num_client_hellos_ == QuicCryptoClientStream::kMaxClientHellos) {
-      QuicClientSparseHistogram("QuicClientHelloRejectReasons.TooMany",
-                                packed_error);
-    }
-    QuicClientSparseHistogram("QuicClientHelloRejectReasons.Secure",
-                              packed_error);
-  }
-
-  // Receipt of a REJ message means that the server received the CHLO
-  // so we can cancel and retransmissions.
-  delegate_->NeuterUnencryptedData();
-
-  std::string error_details;
-  QuicErrorCode error = crypto_config_->ProcessRejection(
-      *in, session()->connection()->clock()->WallNow(),
-      session()->transport_version(), chlo_hash_, cached,
-      crypto_negotiated_params_, &error_details);
-
-  if (error != QUIC_NO_ERROR) {
-    next_state_ = STATE_NONE;
-    stream_->OnUnrecoverableError(error, error_details);
-    return;
-  }
-  if (!cached->proof_valid()) {
-    if (!cached->signature().empty()) {
-      // Note that we only verify the proof if the cached proof is not
-      // valid. If the cached proof is valid here, someone else must have
-      // just added the server config to the cache and verified the proof,
-      // so we can assume no CA trust changes or certificate expiration
-      // has happened since then.
-      next_state_ = STATE_VERIFY_PROOF;
-      return;
-    }
-  }
-  next_state_ = STATE_SEND_CHLO;
-}
-
-QuicAsyncStatus QuicCryptoClientHandshaker::DoVerifyProof(
-    QuicCryptoClientConfig::CachedState* cached) {
-  ProofVerifier* verifier = crypto_config_->proof_verifier();
-  QUICHE_DCHECK(verifier);
-  next_state_ = STATE_VERIFY_PROOF_COMPLETE;
-  generation_counter_ = cached->generation_counter();
-
-  ProofVerifierCallbackImpl* proof_verify_callback =
-      new ProofVerifierCallbackImpl(this);
-
-  verify_ok_ = false;
-
-  QuicAsyncStatus status = verifier->VerifyProof(
-      server_id_.host(), server_id_.port(), cached->server_config(),
-      session()->transport_version(), chlo_hash_, cached->certs(),
-      cached->cert_sct(), cached->signature(), verify_context_.get(),
-      &verify_error_details_, &verify_details_,
-      std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
-
-  switch (status) {
-    case QUIC_PENDING:
-      proof_verify_callback_ = proof_verify_callback;
-      QUIC_DVLOG(1) << "Doing VerifyProof";
-      break;
-    case QUIC_FAILURE:
-      break;
-    case QUIC_SUCCESS:
-      verify_ok_ = true;
-      break;
-  }
-  return status;
-}
-
-void QuicCryptoClientHandshaker::DoVerifyProofComplete(
-    QuicCryptoClientConfig::CachedState* cached) {
-  if (proof_verify_start_time_.IsInitialized()) {
-    QUIC_CLIENT_HISTOGRAM_TIMES(
-        "QuicSession.VerifyProofTime.CachedServerConfig",
-        (session()->connection()->clock()->Now() - proof_verify_start_time_),
-        QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::FromSeconds(10),
-        50, "");
-  }
-  if (!verify_ok_) {
-    if (verify_details_) {
-      proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
-    }
-    if (num_client_hellos_ == 0) {
-      cached->Clear();
-      next_state_ = STATE_INITIALIZE;
-      return;
-    }
-    next_state_ = STATE_NONE;
-    QUIC_CLIENT_HISTOGRAM_BOOL("QuicVerifyProofFailed.HandshakeConfirmed",
-                               one_rtt_keys_available(), "");
-    stream_->OnUnrecoverableError(QUIC_PROOF_INVALID,
-                                  "Proof invalid: " + verify_error_details_);
-    return;
-  }
-
-  // Check if generation_counter has changed between STATE_VERIFY_PROOF and
-  // STATE_VERIFY_PROOF_COMPLETE state changes.
-  if (generation_counter_ != cached->generation_counter()) {
-    next_state_ = STATE_VERIFY_PROOF;
-  } else {
-    SetCachedProofValid(cached);
-    cached->SetProofVerifyDetails(verify_details_.release());
-    if (!one_rtt_keys_available()) {
-      next_state_ = STATE_SEND_CHLO;
-    } else {
-      next_state_ = STATE_NONE;
-    }
-  }
-}
-
-void QuicCryptoClientHandshaker::DoReceiveSHLO(
-    const CryptoHandshakeMessage* in,
-    QuicCryptoClientConfig::CachedState* cached) {
-  next_state_ = STATE_NONE;
-  // We sent a CHLO that we expected to be accepted and now we're
-  // hoping for a SHLO from the server to confirm that.  First check
-  // to see whether the response was a reject, and if so, move on to
-  // the reject-processing state.
-  if (in->tag() == kREJ) {
-    // A reject message must be sent in ENCRYPTION_INITIAL.
-    if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
-      // The rejection was sent encrypted!
-      stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
-                                    "encrypted REJ message");
-      return;
-    }
-    next_state_ = STATE_RECV_REJ;
-    return;
-  }
-
-  if (in->tag() != kSHLO) {
-    stream_->OnUnrecoverableError(
-        QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-        absl::StrCat("Expected SHLO or REJ. Received: ",
-                     QuicTagToString(in->tag())));
-    return;
-  }
-
-  if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
-    // The server hello was sent without encryption.
-    stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
-                                  "unencrypted SHLO message");
-    return;
-  }
-  if (num_client_hellos_ == 1) {
-    early_data_reason_ = ssl_early_data_accepted;
-  }
-
-  std::string error_details;
-  QuicErrorCode error = crypto_config_->ProcessServerHello(
-      *in, session()->connection()->connection_id(),
-      session()->connection()->version(),
-      session()->connection()->server_supported_versions(), cached,
-      crypto_negotiated_params_, &error_details);
-
-  if (error != QUIC_NO_ERROR) {
-    stream_->OnUnrecoverableError(error,
-                                  "Server hello invalid: " + error_details);
-    return;
-  }
-  error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
-  if (error != QUIC_NO_ERROR) {
-    stream_->OnUnrecoverableError(error,
-                                  "Server hello invalid: " + error_details);
-    return;
-  }
-  session()->OnConfigNegotiated();
-
-  CrypterPair* crypters = &crypto_negotiated_params_->forward_secure_crypters;
-  // TODO(agl): we don't currently latch this decrypter because the idea
-  // has been floated that the server shouldn't send packets encrypted
-  // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
-  // packet from the client.
-  delegate_->OnNewEncryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
-                                         std::move(crypters->encrypter));
-  delegate_->OnNewDecryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
-                                         std::move(crypters->decrypter),
-                                         /*set_alternative_decrypter=*/true,
-                                         /*latch_once_used=*/false);
-  one_rtt_keys_available_ = true;
-  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-  delegate_->NeuterHandshakeData();
-}
-
-void QuicCryptoClientHandshaker::DoInitializeServerConfigUpdate(
-    QuicCryptoClientConfig::CachedState* cached) {
-  bool update_ignored = false;
-  if (!cached->IsEmpty() && !cached->signature().empty()) {
-    // Note that we verify the proof even if the cached proof is valid.
-    QUICHE_DCHECK(crypto_config_->proof_verifier());
-    next_state_ = STATE_VERIFY_PROOF;
-  } else {
-    update_ignored = true;
-    next_state_ = STATE_NONE;
-  }
-  QUIC_CLIENT_HISTOGRAM_COUNTS("QuicNumServerConfig.UpdateMessagesIgnored",
-                               update_ignored, 1, 1000000, 50, "");
-}
-
-void QuicCryptoClientHandshaker::SetCachedProofValid(
-    QuicCryptoClientConfig::CachedState* cached) {
-  cached->SetProofValid();
-  proof_handler_->OnProofValid(*cached);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_crypto_client_handshaker.h b/quic/core/quic_crypto_client_handshaker.h
deleted file mode 100644
index b458ee4..0000000
--- a/quic/core/quic_crypto_client_handshaker.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
-
-#include <string>
-
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-
-// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
-// QUIC crypto as the crypto handshake protocol.
-class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
-    : public QuicCryptoClientStream::HandshakerInterface,
-      public QuicCryptoHandshaker {
- public:
-  QuicCryptoClientHandshaker(
-      const QuicServerId& server_id,
-      QuicCryptoClientStream* stream,
-      QuicSession* session,
-      std::unique_ptr<ProofVerifyContext> verify_context,
-      QuicCryptoClientConfig* crypto_config,
-      QuicCryptoClientStream::ProofHandler* proof_handler);
-  QuicCryptoClientHandshaker(const QuicCryptoClientHandshaker&) = delete;
-  QuicCryptoClientHandshaker& operator=(const QuicCryptoClientHandshaker&) =
-      delete;
-
-  ~QuicCryptoClientHandshaker() override;
-
-  // From QuicCryptoClientStream::HandshakerInterface
-  bool CryptoConnect() override;
-  int num_sent_client_hellos() const override;
-  bool IsResumption() const override;
-  bool EarlyDataAccepted() const override;
-  ssl_early_data_reason_t EarlyDataReason() const override;
-  bool ReceivedInchoateReject() const override;
-  int num_scup_messages_received() const override;
-  std::string chlo_hash() const override;
-  bool encryption_established() const override;
-  bool one_rtt_keys_available() const override;
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override;
-  CryptoMessageParser* crypto_message_parser() override;
-  HandshakeState GetHandshakeState() const override;
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnConnectionClosed(QuicErrorCode /*error*/,
-                          ConnectionCloseSource /*source*/) override;
-  void OnHandshakeDoneReceived() override;
-  void OnNewTokenReceived(absl::string_view token) override;
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> /*application_state*/) override {
-    QUICHE_NOTREACHED();
-  }
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-
-  // From QuicCryptoHandshaker
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- protected:
-  // Returns the QuicSession that this stream belongs to.
-  QuicSession* session() const { return session_; }
-
-  // Send either InchoateClientHello or ClientHello message to the server.
-  void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached);
-
- private:
-  // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
-  // The ProofVerifier calls this class with the result of proof verification
-  // when verification is performed asynchronously.
-  class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
-      : public ProofVerifierCallback {
-   public:
-    explicit ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent);
-    ~ProofVerifierCallbackImpl() override;
-
-    // ProofVerifierCallback interface.
-    void Run(bool ok,
-             const std::string& error_details,
-             std::unique_ptr<ProofVerifyDetails>* details) override;
-
-    // Cancel causes any future callbacks to be ignored. It must be called on
-    // the same thread as the callback will be made on.
-    void Cancel();
-
-   private:
-    QuicCryptoClientHandshaker* parent_;
-  };
-
-  enum State {
-    STATE_IDLE,
-    STATE_INITIALIZE,
-    STATE_SEND_CHLO,
-    STATE_RECV_REJ,
-    STATE_VERIFY_PROOF,
-    STATE_VERIFY_PROOF_COMPLETE,
-    STATE_RECV_SHLO,
-    STATE_INITIALIZE_SCUP,
-    STATE_NONE,
-    STATE_CONNECTION_CLOSED,
-  };
-
-  // Handles new server config and optional source-address token provided by the
-  // server during a connection.
-  void HandleServerConfigUpdateMessage(
-      const CryptoHandshakeMessage& server_config_update);
-
-  // DoHandshakeLoop performs a step of the handshake state machine. Note that
-  // |in| may be nullptr if the call did not result from a received message.
-  void DoHandshakeLoop(const CryptoHandshakeMessage* in);
-
-  // Start the handshake process.
-  void DoInitialize(QuicCryptoClientConfig::CachedState* cached);
-
-  // Process REJ message from the server.
-  void DoReceiveREJ(const CryptoHandshakeMessage* in,
-                    QuicCryptoClientConfig::CachedState* cached);
-
-  // Start the proof verification process. Returns the QuicAsyncStatus returned
-  // by the ProofVerifier's VerifyProof.
-  QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
-
-  // If proof is valid then it sets the proof as valid (which persists the
-  // server config). If not, it closes the connection.
-  void DoVerifyProofComplete(QuicCryptoClientConfig::CachedState* cached);
-
-  // Process SHLO message from the server.
-  void DoReceiveSHLO(const CryptoHandshakeMessage* in,
-                     QuicCryptoClientConfig::CachedState* cached);
-
-  // Start the proof verification if |server_id_| is https and |cached| has
-  // signature.
-  void DoInitializeServerConfigUpdate(
-      QuicCryptoClientConfig::CachedState* cached);
-
-  // Called to set the proof of |cached| valid.  Also invokes the session's
-  // OnProofValid() method.
-  void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);
-
-  QuicCryptoClientStream* stream_;
-
-  QuicSession* session_;
-  HandshakerDelegateInterface* delegate_;
-
-  State next_state_;
-  // num_client_hellos_ contains the number of client hello messages that this
-  // connection has sent.
-  int num_client_hellos_;
-
-  ssl_early_data_reason_t early_data_reason_ = ssl_early_data_unknown;
-
-  QuicCryptoClientConfig* const crypto_config_;
-
-  // SHA-256 hash of the most recently sent CHLO.
-  std::string chlo_hash_;
-
-  // Server's (hostname, port, is_https, privacy_mode) tuple.
-  const QuicServerId server_id_;
-
-  // Generation counter from QuicCryptoClientConfig's CachedState.
-  uint64_t generation_counter_;
-
-  // verify_context_ contains the context object that we pass to asynchronous
-  // proof verifications.
-  std::unique_ptr<ProofVerifyContext> verify_context_;
-
-  // proof_verify_callback_ contains the callback object that we passed to an
-  // asynchronous proof verification. The ProofVerifier owns this object.
-  ProofVerifierCallbackImpl* proof_verify_callback_;
-  // proof_handler_ contains the callback object used by a quic client
-  // for proof verification. It is not owned by this class.
-  QuicCryptoClientStream::ProofHandler* proof_handler_;
-
-  // These members are used to store the result of an asynchronous proof
-  // verification. These members must not be used after
-  // STATE_VERIFY_PROOF_COMPLETE.
-  bool verify_ok_;
-  std::string verify_error_details_;
-  std::unique_ptr<ProofVerifyDetails> verify_details_;
-
-  QuicTime proof_verify_start_time_;
-
-  int num_scup_messages_received_;
-
-  bool encryption_established_;
-  bool one_rtt_keys_available_;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      crypto_negotiated_params_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
diff --git a/quic/core/quic_crypto_client_handshaker_test.cc b/quic/core/quic_crypto_client_handshaker_test.cc
deleted file mode 100644
index bb1e40f..0000000
--- a/quic/core/quic_crypto_client_handshaker_test.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_handshaker.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace {
-
-class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
- public:
-  ~TestProofHandler() override {}
-  void OnProofValid(
-      const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
-  void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& /*verify_details*/) override {}
-};
-
-class InsecureProofVerifier : public ProofVerifier {
- public:
-  InsecureProofVerifier() {}
-  ~InsecureProofVerifier() override {}
-
-  // ProofVerifier override.
-  QuicAsyncStatus VerifyProof(
-      const std::string& /*hostname*/,
-      const uint16_t /*port*/,
-      const std::string& /*server_config*/,
-      QuicTransportVersion /*transport_version*/,
-      absl::string_view /*chlo_hash*/,
-      const std::vector<std::string>& /*certs*/,
-      const std::string& /*cert_sct*/,
-      const std::string& /*signature*/,
-      const ProofVerifyContext* /*context*/,
-      std::string* /*error_details*/,
-      std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
-      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
-    return QUIC_SUCCESS;
-  }
-
-  QuicAsyncStatus VerifyCertChain(
-      const std::string& /*hostname*/,
-      const uint16_t /*port*/,
-      const std::vector<std::string>& /*certs*/,
-      const std::string& /*ocsp_response*/,
-      const std::string& /*cert_sct*/,
-      const ProofVerifyContext* /*context*/,
-      std::string* /*error_details*/,
-      std::unique_ptr<ProofVerifyDetails>* /*details*/,
-      uint8_t* /*out_alert*/,
-      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
-    return QUIC_SUCCESS;
-  }
-
-  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
-    return nullptr;
-  }
-};
-
-class DummyProofSource : public ProofSource {
- public:
-  DummyProofSource() {}
-  ~DummyProofSource() override {}
-
-  // ProofSource override.
-  void GetProof(const QuicSocketAddress& server_address,
-                const QuicSocketAddress& client_address,
-                const std::string& hostname,
-                const std::string& /*server_config*/,
-                QuicTransportVersion /*transport_version*/,
-                absl::string_view /*chlo_hash*/,
-                std::unique_ptr<Callback> callback) override {
-    bool cert_matched_sni;
-    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
-        GetCertChain(server_address, client_address, hostname,
-                     &cert_matched_sni);
-    QuicCryptoProof proof;
-    proof.signature = "Dummy signature";
-    proof.leaf_cert_scts = "Dummy timestamp";
-    proof.cert_matched_sni = cert_matched_sni;
-    callback->Run(true, chain, proof, /*details=*/nullptr);
-  }
-
-  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
-      const QuicSocketAddress& /*server_address*/,
-      const QuicSocketAddress& /*client_address*/,
-      const std::string& /*hostname*/, bool* /*cert_matched_sni*/) override {
-    std::vector<std::string> certs;
-    certs.push_back("Dummy cert");
-    return quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
-        new ProofSource::Chain(certs));
-  }
-
-  void ComputeTlsSignature(
-      const QuicSocketAddress& /*server_address*/,
-      const QuicSocketAddress& /*client_address*/,
-      const std::string& /*hostname*/,
-      uint16_t /*signature_algorit*/,
-      absl::string_view /*in*/,
-      std::unique_ptr<SignatureCallback> callback) override {
-    callback->Run(true, "Dummy signature", /*details=*/nullptr);
-  }
-
-  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
-      const override {
-    return {};
-  }
-
-  TicketCrypter* GetTicketCrypter() override { return nullptr; }
-};
-
-class Handshaker : public QuicCryptoClientHandshaker {
- public:
-  Handshaker(const QuicServerId& server_id,
-             QuicCryptoClientStream* stream,
-             QuicSession* session,
-             std::unique_ptr<ProofVerifyContext> verify_context,
-             QuicCryptoClientConfig* crypto_config,
-             QuicCryptoClientStream::ProofHandler* proof_handler)
-      : QuicCryptoClientHandshaker(server_id,
-                                   stream,
-                                   session,
-                                   std::move(verify_context),
-                                   crypto_config,
-                                   proof_handler) {}
-
-  void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
-    QuicCryptoClientHandshaker::DoSendCHLO(cached);
-  }
-};
-
-class QuicCryptoClientHandshakerTest
-    : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicCryptoClientHandshakerTest()
-      : version_(GetParam()),
-        proof_handler_(),
-        helper_(),
-        alarm_factory_(),
-        server_id_("host", 123),
-        connection_(new test::MockQuicConnection(&helper_,
-                                                 &alarm_factory_,
-                                                 Perspective::IS_CLIENT,
-                                                 {version_})),
-        session_(connection_, false),
-        crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
-        client_stream_(
-            new QuicCryptoClientStream(server_id_,
-                                       &session_,
-                                       nullptr,
-                                       &crypto_client_config_,
-                                       &proof_handler_,
-                                       /*has_application_state = */ false)),
-        handshaker_(server_id_,
-                    client_stream_,
-                    &session_,
-                    nullptr,
-                    &crypto_client_config_,
-                    &proof_handler_),
-        state_() {
-    // Session takes the ownership of the client stream! (but handshaker also
-    // takes a reference to it, but doesn't take the ownership).
-    session_.SetCryptoStream(client_stream_);
-    session_.Initialize();
-  }
-
-  void InitializeServerParametersToEnableFullHello() {
-    QuicCryptoServerConfig::ConfigOptions options;
-    QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
-        helper_.GetRandomGenerator(), helper_.GetClock(), options);
-    state_.Initialize(
-        config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
-        "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
-        helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
-
-    state_.SetProofValid();
-  }
-
-  ParsedQuicVersion version_;
-  TestProofHandler proof_handler_;
-  test::MockQuicConnectionHelper helper_;
-  test::MockAlarmFactory alarm_factory_;
-  QuicServerId server_id_;
-  // Session takes the ownership of the connection.
-  test::MockQuicConnection* connection_;
-  test::MockQuicSession session_;
-  QuicCryptoClientConfig crypto_client_config_;
-  QuicCryptoClientStream* client_stream_;
-  Handshaker handshaker_;
-  QuicCryptoClientConfig::CachedState state_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    QuicCryptoClientHandshakerTests,
-    QuicCryptoClientHandshakerTest,
-    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
-    ::testing::PrintToStringParamName());
-
-TEST_P(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
-  handshaker_.DoSendCHLOTest(&state_);
-
-  EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
-}
-
-TEST_P(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
-  crypto_client_config_.set_pad_inchoate_hello(false);
-  handshaker_.DoSendCHLOTest(&state_);
-  EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
-}
-
-TEST_P(QuicCryptoClientHandshakerTest,
-       TestPaddingInFullHelloEvenIfInchoateDisabled) {
-  // Disable inchoate, but full hello should still be padded.
-  crypto_client_config_.set_pad_inchoate_hello(false);
-
-  InitializeServerParametersToEnableFullHello();
-
-  handshaker_.DoSendCHLOTest(&state_);
-  EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
-}
-
-TEST_P(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
-  crypto_client_config_.set_pad_full_hello(false);
-
-  InitializeServerParametersToEnableFullHello();
-
-  handshaker_.DoSendCHLOTest(&state_);
-  EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/quic_crypto_client_stream.cc b/quic/core/quic_crypto_client_stream.cc
deleted file mode 100644
index 27a2a46..0000000
--- a/quic/core/quic_crypto_client_stream.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_crypto_client_handshaker.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-const int QuicCryptoClientStream::kMaxClientHellos;
-
-QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(QuicSession* session)
-    : QuicCryptoStream(session) {}
-
-QuicCryptoClientStream::QuicCryptoClientStream(
-    const QuicServerId& server_id,
-    QuicSession* session,
-    std::unique_ptr<ProofVerifyContext> verify_context,
-    QuicCryptoClientConfig* crypto_config,
-    ProofHandler* proof_handler,
-    bool has_application_state)
-    : QuicCryptoClientStreamBase(session) {
-  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT,
-                   session->connection()->perspective());
-  switch (session->connection()->version().handshake_protocol) {
-    case PROTOCOL_QUIC_CRYPTO:
-      handshaker_ = std::make_unique<QuicCryptoClientHandshaker>(
-          server_id, this, session, std::move(verify_context), crypto_config,
-          proof_handler);
-      break;
-    case PROTOCOL_TLS1_3: {
-      auto handshaker = std::make_unique<TlsClientHandshaker>(
-          server_id, this, session, std::move(verify_context), crypto_config,
-          proof_handler, has_application_state);
-      tls_handshaker_ = handshaker.get();
-      handshaker_ = std::move(handshaker);
-      break;
-    }
-    case PROTOCOL_UNSUPPORTED:
-      QUIC_BUG(quic_bug_10296_1)
-          << "Attempting to create QuicCryptoClientStream for unknown "
-             "handshake protocol";
-  }
-}
-
-QuicCryptoClientStream::~QuicCryptoClientStream() {}
-
-bool QuicCryptoClientStream::CryptoConnect() {
-  return handshaker_->CryptoConnect();
-}
-
-int QuicCryptoClientStream::num_sent_client_hellos() const {
-  return handshaker_->num_sent_client_hellos();
-}
-
-bool QuicCryptoClientStream::IsResumption() const {
-  return handshaker_->IsResumption();
-}
-
-bool QuicCryptoClientStream::EarlyDataAccepted() const {
-  return handshaker_->EarlyDataAccepted();
-}
-
-ssl_early_data_reason_t QuicCryptoClientStream::EarlyDataReason() const {
-  return handshaker_->EarlyDataReason();
-}
-
-bool QuicCryptoClientStream::ReceivedInchoateReject() const {
-  return handshaker_->ReceivedInchoateReject();
-}
-
-int QuicCryptoClientStream::num_scup_messages_received() const {
-  return handshaker_->num_scup_messages_received();
-}
-
-bool QuicCryptoClientStream::encryption_established() const {
-  return handshaker_->encryption_established();
-}
-
-bool QuicCryptoClientStream::one_rtt_keys_available() const {
-  return handshaker_->one_rtt_keys_available();
-}
-
-const QuicCryptoNegotiatedParameters&
-QuicCryptoClientStream::crypto_negotiated_params() const {
-  return handshaker_->crypto_negotiated_params();
-}
-
-CryptoMessageParser* QuicCryptoClientStream::crypto_message_parser() {
-  return handshaker_->crypto_message_parser();
-}
-
-HandshakeState QuicCryptoClientStream::GetHandshakeState() const {
-  return handshaker_->GetHandshakeState();
-}
-
-size_t QuicCryptoClientStream::BufferSizeLimitForLevel(
-    EncryptionLevel level) const {
-  return handshaker_->BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter>
-QuicCryptoClientStream::CreateCurrentOneRttEncrypter() {
-  return handshaker_->CreateCurrentOneRttEncrypter();
-}
-
-bool QuicCryptoClientStream::ExportKeyingMaterial(absl::string_view label,
-                                                  absl::string_view context,
-                                                  size_t result_len,
-                                                  std::string* result) {
-  return handshaker_->ExportKeyingMaterial(label, context, result_len, result);
-}
-
-std::string QuicCryptoClientStream::chlo_hash() const {
-  return handshaker_->chlo_hash();
-}
-
-void QuicCryptoClientStream::OnOneRttPacketAcknowledged() {
-  handshaker_->OnOneRttPacketAcknowledged();
-}
-
-void QuicCryptoClientStream::OnHandshakePacketSent() {
-  handshaker_->OnHandshakePacketSent();
-}
-
-void QuicCryptoClientStream::OnConnectionClosed(QuicErrorCode error,
-                                                ConnectionCloseSource source) {
-  handshaker_->OnConnectionClosed(error, source);
-}
-
-void QuicCryptoClientStream::OnHandshakeDoneReceived() {
-  handshaker_->OnHandshakeDoneReceived();
-}
-
-void QuicCryptoClientStream::OnNewTokenReceived(absl::string_view token) {
-  handshaker_->OnNewTokenReceived(token);
-}
-
-void QuicCryptoClientStream::SetServerApplicationStateForResumption(
-    std::unique_ptr<ApplicationState> application_state) {
-  handshaker_->SetServerApplicationStateForResumption(
-      std::move(application_state));
-}
-
-SSL* QuicCryptoClientStream::GetSsl() const {
-  return tls_handshaker_ == nullptr ? nullptr : tls_handshaker_->ssl();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_crypto_client_stream.h b/quic/core/quic_crypto_client_stream.h
deleted file mode 100644
index 34928b6..0000000
--- a/quic/core/quic_crypto_client_stream.h
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_handshaker.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicCryptoClientStreamPeer;
-}  // namespace test
-
-class TlsClientHandshaker;
-
-class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
- public:
-  explicit QuicCryptoClientStreamBase(QuicSession* session);
-
-  ~QuicCryptoClientStreamBase() override {}
-
-  // Performs a crypto handshake with the server. Returns true if the connection
-  // is still connected.
-  virtual bool CryptoConnect() = 0;
-
-  // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
-  // ReceivedInchoateReject instead.
-  //
-  // num_sent_client_hellos returns the number of client hello messages that
-  // have been sent. If the handshake has completed then this is one greater
-  // than the number of round-trips needed for the handshake.
-  virtual int num_sent_client_hellos() const = 0;
-
-  // Returns true if the handshake performed was a resumption instead of a full
-  // handshake. Resumption only makes sense for TLS handshakes - there is no
-  // concept of resumption for QUIC crypto even though it supports a 0-RTT
-  // handshake. This function only returns valid results once the handshake is
-  // complete.
-  virtual bool IsResumption() const = 0;
-
-  // Returns true if early data (0-RTT) was accepted in the connection.
-  virtual bool EarlyDataAccepted() const = 0;
-
-  // Returns true if the client received an inchoate REJ during the handshake,
-  // extending the handshake by one round trip. This only applies for QUIC
-  // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
-  // but that is handled at the connection layer instead of the crypto layer.
-  virtual bool ReceivedInchoateReject() const = 0;
-
-  // The number of server config update messages received by the
-  // client.  Does not count update messages that were received prior
-  // to handshake confirmation.
-  virtual int num_scup_messages_received() const = 0;
-
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_params*/) const override {
-    QUICHE_DCHECK(false);
-    return "";
-  }
-
-  bool ValidateAddressToken(absl::string_view /*token*/) const override {
-    QUICHE_DCHECK(false);
-    return false;
-  }
-
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
-    QUICHE_DCHECK(false);
-    return nullptr;
-  }
-
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters /*cached_network_params*/) override {
-    QUICHE_DCHECK(false);
-  }
-};
-
-class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
-    : public QuicCryptoClientStreamBase {
- public:
-  // kMaxClientHellos is the maximum number of times that we'll send a client
-  // hello. The value 4 accounts for:
-  //   * One failure due to an incorrect or missing source-address token.
-  //   * One failure due the server's certificate chain being unavailible and
-  //     the server being unwilling to send it without a valid source-address
-  //     token.
-  //   * One failure due to the ServerConfig private key being located on a
-  //     remote oracle which has become unavailable, forcing the server to send
-  //     the client a fallback ServerConfig.
-  static const int kMaxClientHellos = 4;
-
-  // QuicCryptoClientStream creates a HandshakerInterface at construction time
-  // based on the QuicTransportVersion of the connection. Different
-  // HandshakerInterfaces provide implementations of different crypto handshake
-  // protocols. Currently QUIC crypto is the only protocol implemented; a future
-  // HandshakerInterface will use TLS as the handshake protocol.
-  // QuicCryptoClientStream delegates all of its public methods to its
-  // HandshakerInterface.
-  //
-  // This setup of the crypto stream delegating its implementation to the
-  // handshaker results in the handshaker reading and writing bytes on the
-  // crypto stream, instead of the handshaker passing the stream bytes to send.
-  class QUIC_EXPORT_PRIVATE HandshakerInterface {
-   public:
-    virtual ~HandshakerInterface() {}
-
-    // Performs a crypto handshake with the server. Returns true if the
-    // connection is still connected.
-    virtual bool CryptoConnect() = 0;
-
-    // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
-    // ReceivedInchoateReject instead.
-    //
-    // num_sent_client_hellos returns the number of client hello messages that
-    // have been sent. If the handshake has completed then this is one greater
-    // than the number of round-trips needed for the handshake.
-    virtual int num_sent_client_hellos() const = 0;
-
-    // Returns true if the handshake performed was a resumption instead of a
-    // full handshake. Resumption only makes sense for TLS handshakes - there is
-    // no concept of resumption for QUIC crypto even though it supports a 0-RTT
-    // handshake. This function only returns valid results once the handshake is
-    // complete.
-    virtual bool IsResumption() const = 0;
-
-    // Returns true if early data (0-RTT) was accepted in the connection.
-    virtual bool EarlyDataAccepted() const = 0;
-
-    // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
-    // rejected.
-    virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
-
-    // Returns true if the client received an inchoate REJ during the handshake,
-    // extending the handshake by one round trip. This only applies for QUIC
-    // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
-    // but that is handled at the connection layer instead of the crypto layer.
-    virtual bool ReceivedInchoateReject() const = 0;
-
-    // The number of server config update messages received by the
-    // client.  Does not count update messages that were received prior
-    // to handshake confirmation.
-    virtual int num_scup_messages_received() const = 0;
-
-    virtual std::string chlo_hash() const = 0;
-
-    // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
-    // for the connection.
-    virtual bool encryption_established() const = 0;
-
-    // Returns true once 1RTT keys are available.
-    virtual bool one_rtt_keys_available() const = 0;
-
-    // Returns the parameters negotiated in the crypto handshake.
-    virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-        const = 0;
-
-    // Used by QuicCryptoStream to parse data received on this stream.
-    virtual CryptoMessageParser* crypto_message_parser() = 0;
-
-    // Used by QuicCryptoStream to know how much unprocessed data can be
-    // buffered at each encryption level.
-    virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
-
-    // Called to generate a decrypter for the next key phase. Each call should
-    // generate the key for phase n+1.
-    virtual std::unique_ptr<QuicDecrypter>
-    AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
-    // Called to generate an encrypter for the same key phase of the last
-    // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
-    virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-
-    // Returns current handshake state.
-    virtual HandshakeState GetHandshakeState() const = 0;
-
-    // Called when a 1RTT packet has been acknowledged.
-    virtual void OnOneRttPacketAcknowledged() = 0;
-
-    // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
-    virtual void OnHandshakePacketSent() = 0;
-
-    // Called when connection gets closed.
-    virtual void OnConnectionClosed(QuicErrorCode error,
-                                    ConnectionCloseSource source) = 0;
-
-    // Called when handshake done has been received.
-    virtual void OnHandshakeDoneReceived() = 0;
-
-    // Called when new token has been received.
-    virtual void OnNewTokenReceived(absl::string_view token) = 0;
-
-    // Called when application state is received.
-    virtual void SetServerApplicationStateForResumption(
-        std::unique_ptr<ApplicationState> application_state) = 0;
-
-    // Called to obtain keying material export of length |result_len| with the
-    // given |label| and |context|. Returns false on failure.
-    virtual bool ExportKeyingMaterial(absl::string_view label,
-                                      absl::string_view context,
-                                      size_t result_len,
-                                      std::string* result) = 0;
-  };
-
-  // ProofHandler is an interface that handles callbacks from the crypto
-  // stream when the client has proof verification details of the server.
-  class QUIC_EXPORT_PRIVATE ProofHandler {
-   public:
-    virtual ~ProofHandler() {}
-
-    // Called when the proof in |cached| is marked valid.  If this is a secure
-    // QUIC session, then this will happen only after the proof verifier
-    // completes.
-    virtual void OnProofValid(
-        const QuicCryptoClientConfig::CachedState& cached) = 0;
-
-    // Called when proof verification details become available, either because
-    // proof verification is complete, or when cached details are used. This
-    // will only be called for secure QUIC connections.
-    virtual void OnProofVerifyDetailsAvailable(
-        const ProofVerifyDetails& verify_details) = 0;
-  };
-
-  QuicCryptoClientStream(const QuicServerId& server_id,
-                         QuicSession* session,
-                         std::unique_ptr<ProofVerifyContext> verify_context,
-                         QuicCryptoClientConfig* crypto_config,
-                         ProofHandler* proof_handler,
-                         bool has_application_state);
-  QuicCryptoClientStream(const QuicCryptoClientStream&) = delete;
-  QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete;
-
-  ~QuicCryptoClientStream() override;
-
-  // From QuicCryptoClientStreamBase
-  bool CryptoConnect() override;
-  int num_sent_client_hellos() const override;
-  bool IsResumption() const override;
-  bool EarlyDataAccepted() const override;
-  ssl_early_data_reason_t EarlyDataReason() const override;
-  bool ReceivedInchoateReject() const override;
-
-  int num_scup_messages_received() const override;
-
-  // From QuicCryptoStream
-  bool encryption_established() const override;
-  bool one_rtt_keys_available() const override;
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override;
-  CryptoMessageParser* crypto_message_parser() override;
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override;
-  void OnHandshakePacketSent() override;
-  void OnConnectionClosed(QuicErrorCode error,
-                          ConnectionCloseSource source) override;
-  void OnHandshakeDoneReceived() override;
-  void OnNewTokenReceived(absl::string_view token) override;
-  HandshakeState GetHandshakeState() const override;
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> application_state) override;
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-  SSL* GetSsl() const override;
-  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
-                            size_t result_len, std::string* result) override;
-  std::string chlo_hash() const;
-
- protected:
-  void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) {
-    handshaker_ = std::move(handshaker);
-  }
-
- private:
-  friend class test::QuicCryptoClientStreamPeer;
-  std::unique_ptr<HandshakerInterface> handshaker_;
-  // Points to |handshaker_| if it uses TLS1.3. Otherwise, nullptr.
-  // TODO(danzh) change the type of |handshaker_| to TlsClientHandshaker after
-  // deprecating Google QUIC.
-  TlsClientHandshaker* tls_handshaker_{nullptr};
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
diff --git a/quic/core/quic_crypto_client_stream_test.cc b/quic/core/quic_crypto_client_stream_test.cc
deleted file mode 100644
index ac0a4fc..0000000
--- a/quic/core/quic_crypto_client_stream_test.cc
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_client_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "quic/test_tools/simple_session_cache.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kServerPort = 443;
-
-// This test tests the client-side of the QUIC crypto handshake. It does not
-// test the TLS handshake - that is in tls_client_handshaker_test.cc.
-class QuicCryptoClientStreamTest : public QuicTest {
- public:
-  QuicCryptoClientStreamTest()
-      : supported_versions_(AllSupportedVersionsWithQuicCrypto()),
-        server_id_(kServerHostname, kServerPort, false),
-        crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
-                       std::make_unique<test::SimpleSessionCache>()),
-        server_crypto_config_(
-            crypto_test_utils::CryptoServerConfigForTesting()) {
-    CreateConnection();
-  }
-
-  void CreateSession() {
-    session_ = std::make_unique<TestQuicSpdyClientSession>(
-        connection_, DefaultQuicConfig(), supported_versions_, server_id_,
-        &crypto_config_);
-    EXPECT_CALL(*session_, GetAlpnsToOffer())
-        .WillRepeatedly(testing::Return(std::vector<std::string>(
-            {AlpnForVersion(connection_->version())})));
-  }
-
-  void CreateConnection() {
-    connection_ =
-        new PacketSavingConnection(&client_helper_, &alarm_factory_,
-                                   Perspective::IS_CLIENT, supported_versions_);
-    // Advance the time, because timers do not like uninitialized times.
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    CreateSession();
-  }
-
-  void CompleteCryptoHandshake() {
-    int proof_verify_details_calls = 1;
-    if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
-      EXPECT_CALL(*session_, OnProofValid(testing::_))
-          .Times(testing::AtLeast(1));
-      proof_verify_details_calls = 0;
-    }
-    EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
-        .Times(testing::AtLeast(proof_verify_details_calls));
-    stream()->CryptoConnect();
-    QuicConfig config;
-    crypto_test_utils::HandshakeWithFakeServer(
-        &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
-        connection_, stream(), AlpnForVersion(connection_->version()));
-  }
-
-  QuicCryptoClientStream* stream() {
-    return session_->GetMutableCryptoStream();
-  }
-
-  MockQuicConnectionHelper server_helper_;
-  MockQuicConnectionHelper client_helper_;
-  MockAlarmFactory alarm_factory_;
-  PacketSavingConnection* connection_;
-  ParsedQuicVersionVector supported_versions_;
-  std::unique_ptr<TestQuicSpdyClientSession> session_;
-  QuicServerId server_id_;
-  CryptoHandshakeMessage message_;
-  QuicCryptoClientConfig crypto_config_;
-  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
-};
-
-TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
-  EXPECT_FALSE(stream()->encryption_established());
-  EXPECT_FALSE(stream()->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
-  CompleteCryptoHandshake();
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_no_session_offered);
-}
-
-TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
-  CompleteCryptoHandshake();
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
-  message_.set_tag(kCHLO);
-  crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
-                                                  Perspective::IS_CLIENT);
-}
-
-TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
-  stream()->CryptoConnect();
-
-  message_.set_tag(kCHLO);
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                            "Expected REJ", _));
-  crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
-                                                  Perspective::IS_CLIENT);
-}
-
-TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
-  CompleteCryptoHandshake();
-
-  const QuicConfig* config = session_->config();
-  EXPECT_EQ(kMaximumIdleTimeoutSecs, config->IdleNetworkTimeout().ToSeconds());
-
-  const QuicCryptoNegotiatedParameters& crypto_params(
-      stream()->crypto_negotiated_params());
-  EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
-  EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
-}
-
-TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
-  // Seed the config with a cached server config.
-  CompleteCryptoHandshake();
-
-  // Recreate connection with the new config.
-  CreateConnection();
-
-  // Advance time 5 years to ensure that we pass the expiry time of the cached
-  // server config.
-  connection_->AdvanceTime(
-      QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
-
-  EXPECT_CALL(*session_, OnProofValid(testing::_));
-  stream()->CryptoConnect();
-  // Check that a client hello was sent.
-  ASSERT_EQ(1u, connection_->encrypted_packets_.size());
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ClientTurnedOffZeroRtt) {
-  // Seed the config with a cached server config.
-  CompleteCryptoHandshake();
-
-  // Recreate connection with the new config.
-  CreateConnection();
-
-  // Set connection option.
-  QuicTagVector options;
-  options.push_back(kQNZ2);
-  session_->config()->SetClientConnectionOptions(options);
-
-  CompleteCryptoHandshake();
-  // Check that two client hellos were sent, one inchoate and one normal.
-  EXPECT_EQ(2, stream()->num_sent_client_hellos());
-  EXPECT_FALSE(stream()->EarlyDataAccepted());
-  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_disabled);
-}
-
-TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
-  // Test that if the client's clock is skewed with respect to the server,
-  // the handshake succeeds. In the past, the client would get the server
-  // config, notice that it had already expired and then close the connection.
-
-  // Advance time 5 years to ensure that we pass the expiry time in the server
-  // config, but the TTL is used instead.
-  connection_->AdvanceTime(
-      QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
-
-  // The handshakes completes!
-  CompleteCryptoHandshake();
-}
-
-TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
-  // Seed the config with a cached server config.
-  CompleteCryptoHandshake();
-
-  // Recreate connection with the new config.
-  CreateConnection();
-
-  QuicCryptoClientConfig::CachedState* state =
-      crypto_config_.LookupOrCreate(server_id_);
-
-  std::vector<std::string> certs = state->certs();
-  std::string cert_sct = state->cert_sct();
-  std::string signature = state->signature();
-  std::string chlo_hash = state->chlo_hash();
-  state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
-
-  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
-      .Times(testing::AnyNumber());
-  stream()->CryptoConnect();
-  // Check that a client hello was sent.
-  ASSERT_EQ(1u, connection_->encrypted_packets_.size());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
-  // Test that the crypto client stream can receive server config updates after
-  // the connection has been established.
-  CompleteCryptoHandshake();
-
-  QuicCryptoClientConfig::CachedState* state =
-      crypto_config_.LookupOrCreate(server_id_);
-
-  // Ensure cached STK is different to what we send in the handshake.
-  EXPECT_NE("xstk", state->source_address_token());
-
-  // Initialize using {...} syntax to avoid trailing \0 if converting from
-  // string.
-  unsigned char stk[] = {'x', 's', 't', 'k'};
-
-  // Minimum SCFG that passes config validation checks.
-  unsigned char scfg[] = {// SCFG
-                          0x53, 0x43, 0x46, 0x47,
-                          // num entries
-                          0x01, 0x00,
-                          // padding
-                          0x00, 0x00,
-                          // EXPY
-                          0x45, 0x58, 0x50, 0x59,
-                          // EXPY end offset
-                          0x08, 0x00, 0x00, 0x00,
-                          // Value
-                          '1', '2', '3', '4', '5', '6', '7', '8'};
-
-  CryptoHandshakeMessage server_config_update;
-  server_config_update.set_tag(kSCUP);
-  server_config_update.SetValue(kSourceAddressTokenTag, stk);
-  server_config_update.SetValue(kSCFG, scfg);
-  const uint64_t expiry_seconds = 60 * 60 * 24 * 2;
-  server_config_update.SetValue(kSTTL, expiry_seconds);
-
-  crypto_test_utils::SendHandshakeMessageToStream(
-      stream(), server_config_update, Perspective::IS_SERVER);
-
-  // Make sure that the STK and SCFG are cached correctly.
-  EXPECT_EQ("xstk", state->source_address_token());
-
-  const std::string& cached_scfg = state->server_config();
-  quiche::test::CompareCharArraysWithHexError(
-      "scfg", cached_scfg.data(), cached_scfg.length(),
-      reinterpret_cast<char*>(scfg), ABSL_ARRAYSIZE(scfg));
-
-  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
-  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
-}
-
-TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
-  // Test that the crypto client stream can receive and use server config
-  // updates with certificates after the connection has been established.
-  CompleteCryptoHandshake();
-
-  // Build a server config update message with certificates
-  QuicCryptoServerConfig crypto_config(
-      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-      crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
-  crypto_test_utils::SetupCryptoServerConfigForTest(
-      connection_->clock(), QuicRandom::GetInstance(), &crypto_config);
-  SourceAddressTokens tokens;
-  QuicCompressedCertsCache cache(1);
-  CachedNetworkParameters network_params;
-  CryptoHandshakeMessage server_config_update;
-
-  class Callback : public BuildServerConfigUpdateMessageResultCallback {
-   public:
-    Callback(bool* ok, CryptoHandshakeMessage* message)
-        : ok_(ok), message_(message) {}
-    void Run(bool ok, const CryptoHandshakeMessage& message) override {
-      *ok_ = ok;
-      *message_ = message;
-    }
-
-   private:
-    bool* ok_;
-    CryptoHandshakeMessage* message_;
-  };
-
-  // Note: relies on the callback being invoked synchronously
-  bool ok = false;
-  crypto_config.BuildServerConfigUpdateMessage(
-      session_->transport_version(), stream()->chlo_hash(), tokens,
-      QuicSocketAddress(QuicIpAddress::Loopback6(), 1234),
-      QuicSocketAddress(QuicIpAddress::Loopback6(), 4321), connection_->clock(),
-      QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(),
-      &network_params,
-      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>(
-          new Callback(&ok, &server_config_update)));
-  EXPECT_TRUE(ok);
-
-  EXPECT_CALL(*session_, OnProofValid(testing::_));
-  crypto_test_utils::SendHandshakeMessageToStream(
-      stream(), server_config_update, Perspective::IS_SERVER);
-
-  // Recreate connection with the new config and verify a 0-RTT attempt.
-  CreateConnection();
-
-  EXPECT_CALL(*session_, OnProofValid(testing::_));
-  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
-      .Times(testing::AnyNumber());
-  stream()->CryptoConnect();
-  EXPECT_TRUE(session_->IsEncryptionEstablished());
-}
-
-TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
-  CryptoHandshakeMessage server_config_update;
-  server_config_update.set_tag(kSCUP);
-  crypto_test_utils::SendHandshakeMessageToStream(
-      stream(), server_config_update, Perspective::IS_SERVER);
-}
-
-TEST_F(QuicCryptoClientStreamTest, PreferredVersion) {
-  // This mimics the case where client receives version negotiation packet, such
-  // that, the preferred version is different from the packets' version.
-  connection_ = new PacketSavingConnection(
-      &client_helper_, &alarm_factory_, Perspective::IS_CLIENT,
-      ParsedVersionOfIndex(supported_versions_, 1));
-  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
-  CreateSession();
-  CompleteCryptoHandshake();
-  // 2 CHLOs are sent.
-  ASSERT_EQ(2u, session_->sent_crypto_handshake_messages().size());
-  // Verify preferred version is the highest version that session supports, and
-  // is different from connection's version.
-  QuicVersionLabel client_version_label;
-  EXPECT_THAT(session_->sent_crypto_handshake_messages()[0].GetVersionLabel(
-                  kVER, &client_version_label),
-              IsQuicNoError());
-  EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
-            client_version_label);
-  EXPECT_THAT(session_->sent_crypto_handshake_messages()[1].GetVersionLabel(
-                  kVER, &client_version_label),
-              IsQuicNoError());
-  EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
-            client_version_label);
-  EXPECT_NE(CreateQuicVersionLabel(connection_->version()),
-            client_version_label);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_crypto_handshaker.cc b/quic/core/quic_crypto_handshaker.cc
deleted file mode 100644
index 79142c4..0000000
--- a/quic/core/quic_crypto_handshaker.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_handshaker.h"
-
-#include "quic/core/quic_session.h"
-
-namespace quic {
-
-#define ENDPOINT \
-  (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicCryptoHandshaker::QuicCryptoHandshaker(QuicCryptoStream* stream,
-                                           QuicSession* session)
-    : stream_(stream), session_(session), last_sent_handshake_message_tag_(0) {
-  crypto_framer_.set_visitor(this);
-}
-
-QuicCryptoHandshaker::~QuicCryptoHandshaker() {}
-
-void QuicCryptoHandshaker::SendHandshakeMessage(
-    const CryptoHandshakeMessage& message,
-    EncryptionLevel level) {
-  QUIC_DVLOG(1) << ENDPOINT << "Sending " << message.DebugString();
-  session()->NeuterUnencryptedData();
-  session()->OnCryptoHandshakeMessageSent(message);
-  last_sent_handshake_message_tag_ = message.tag();
-  const QuicData& data = message.GetSerialized();
-  stream_->WriteCryptoData(level, data.AsStringPiece());
-}
-
-void QuicCryptoHandshaker::OnError(CryptoFramer* framer) {
-  QUIC_DLOG(WARNING) << "Error processing crypto data: "
-                     << QuicErrorCodeToString(framer->error());
-}
-
-void QuicCryptoHandshaker::OnHandshakeMessage(
-    const CryptoHandshakeMessage& message) {
-  QUIC_DVLOG(1) << ENDPOINT << "Received " << message.DebugString();
-  session()->OnCryptoHandshakeMessageReceived(message);
-}
-
-CryptoMessageParser* QuicCryptoHandshaker::crypto_message_parser() {
-  return &crypto_framer_;
-}
-
-size_t QuicCryptoHandshaker::BufferSizeLimitForLevel(EncryptionLevel) const {
-  return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_crypto_handshaker.h b/quic/core/quic_crypto_handshaker.h
deleted file mode 100644
index b5077d9..0000000
--- a/quic/core/quic_crypto_handshaker.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
-
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicCryptoHandshaker
-    : public CryptoFramerVisitorInterface {
- public:
-  QuicCryptoHandshaker(QuicCryptoStream* stream, QuicSession* session);
-  QuicCryptoHandshaker(const QuicCryptoHandshaker&) = delete;
-  QuicCryptoHandshaker& operator=(const QuicCryptoHandshaker&) = delete;
-
-  ~QuicCryptoHandshaker() override;
-
-  // Sends |message| to the peer.
-  // TODO(wtc): return a success/failure status.
-  void SendHandshakeMessage(const CryptoHandshakeMessage& message,
-                            EncryptionLevel level);
-
-  void OnError(CryptoFramer* framer) override;
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
-  CryptoMessageParser* crypto_message_parser();
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
-
- protected:
-  QuicTag last_sent_handshake_message_tag() const {
-    return last_sent_handshake_message_tag_;
-  }
-
- private:
-  QuicSession* session() { return session_; }
-
-  QuicCryptoStream* stream_;
-  QuicSession* session_;
-
-  CryptoFramer crypto_framer_;
-
-  // Records last sent crypto handshake message tag.
-  QuicTag last_sent_handshake_message_tag_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
diff --git a/quic/core/quic_crypto_server_stream.cc b/quic/core/quic_crypto_server_stream.cc
deleted file mode 100644
index 3612c77..0000000
--- a/quic/core/quic_crypto_server_stream.cc
+++ /dev/null
@@ -1,538 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_server_stream.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-class QuicCryptoServerStream::ProcessClientHelloCallback
-    : public ProcessClientHelloResultCallback {
- public:
-  ProcessClientHelloCallback(
-      QuicCryptoServerStream* parent,
-      const quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>& result)
-      : parent_(parent), result_(result) {}
-
-  void Run(
-      QuicErrorCode error,
-      const std::string& error_details,
-      std::unique_ptr<CryptoHandshakeMessage> message,
-      std::unique_ptr<DiversificationNonce> diversification_nonce,
-      std::unique_ptr<ProofSource::Details> proof_source_details) override {
-    if (parent_ == nullptr) {
-      return;
-    }
-
-    parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
-        *result_, error, error_details, std::move(message),
-        std::move(diversification_nonce), std::move(proof_source_details));
-  }
-
-  void Cancel() { parent_ = nullptr; }
-
- private:
-  QuicCryptoServerStream* parent_;
-  quiche::QuicheReferenceCountedPointer<
-      ValidateClientHelloResultCallback::Result>
-      result_;
-};
-
-QuicCryptoServerStream::QuicCryptoServerStream(
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    QuicSession* session,
-    QuicCryptoServerStreamBase::Helper* helper)
-    : QuicCryptoServerStreamBase(session),
-      QuicCryptoHandshaker(this, session),
-      session_(session),
-      delegate_(session),
-      crypto_config_(crypto_config),
-      compressed_certs_cache_(compressed_certs_cache),
-      signed_config_(new QuicSignedServerConfig),
-      helper_(helper),
-      num_handshake_messages_(0),
-      num_handshake_messages_with_server_nonces_(0),
-      send_server_config_update_cb_(nullptr),
-      num_server_config_update_messages_sent_(0),
-      zero_rtt_attempted_(false),
-      chlo_packet_size_(0),
-      validate_client_hello_cb_(nullptr),
-      process_client_hello_cb_(nullptr),
-      encryption_established_(false),
-      one_rtt_keys_available_(false),
-      one_rtt_packet_decrypted_(false),
-      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
-
-QuicCryptoServerStream::~QuicCryptoServerStream() {
-  CancelOutstandingCallbacks();
-}
-
-void QuicCryptoServerStream::CancelOutstandingCallbacks() {
-  // Detach from the validation callback.  Calling this multiple times is safe.
-  if (validate_client_hello_cb_ != nullptr) {
-    validate_client_hello_cb_->Cancel();
-    validate_client_hello_cb_ = nullptr;
-  }
-  if (send_server_config_update_cb_ != nullptr) {
-    send_server_config_update_cb_->Cancel();
-    send_server_config_update_cb_ = nullptr;
-  }
-  if (process_client_hello_cb_ != nullptr) {
-    process_client_hello_cb_->Cancel();
-    process_client_hello_cb_ = nullptr;
-  }
-}
-
-void QuicCryptoServerStream::OnHandshakeMessage(
-    const CryptoHandshakeMessage& message) {
-  QuicCryptoHandshaker::OnHandshakeMessage(message);
-  ++num_handshake_messages_;
-  chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
-
-  // Do not process handshake messages after the handshake is confirmed.
-  if (one_rtt_keys_available_) {
-    OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
-                         "Unexpected handshake message from client");
-    return;
-  }
-
-  if (message.tag() != kCHLO) {
-    OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                         "Handshake packet not CHLO");
-    return;
-  }
-
-  if (validate_client_hello_cb_ != nullptr ||
-      process_client_hello_cb_ != nullptr) {
-    // Already processing some other handshake message.  The protocol
-    // does not allow for clients to send multiple handshake messages
-    // before the server has a chance to respond.
-    OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
-                         "Unexpected handshake message while processing CHLO");
-    return;
-  }
-
-  chlo_hash_ =
-      CryptoUtils::HashHandshakeMessage(message, Perspective::IS_SERVER);
-
-  std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
-  QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
-  QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
-  validate_client_hello_cb_ = cb.get();
-  crypto_config_->ValidateClientHello(
-      message, GetClientAddress(), session()->connection()->self_address(),
-      transport_version(), session()->connection()->clock(), signed_config_,
-      std::move(cb));
-}
-
-void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
-    quiche::QuicheReferenceCountedPointer<
-        ValidateClientHelloResultCallback::Result>
-        result,
-    std::unique_ptr<ProofSource::Details> details) {
-  // Clear the callback that got us here.
-  QUICHE_DCHECK(validate_client_hello_cb_ != nullptr);
-  QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
-  validate_client_hello_cb_ = nullptr;
-
-  std::unique_ptr<ProcessClientHelloCallback> cb(
-      new ProcessClientHelloCallback(this, result));
-  process_client_hello_cb_ = cb.get();
-  ProcessClientHello(result, std::move(details), std::move(cb));
-}
-
-void QuicCryptoServerStream::
-    FinishProcessingHandshakeMessageAfterProcessClientHello(
-        const ValidateClientHelloResultCallback::Result& result,
-        QuicErrorCode error,
-        const std::string& error_details,
-        std::unique_ptr<CryptoHandshakeMessage> reply,
-        std::unique_ptr<DiversificationNonce> diversification_nonce,
-        std::unique_ptr<ProofSource::Details> proof_source_details) {
-  // Clear the callback that got us here.
-  QUICHE_DCHECK(process_client_hello_cb_ != nullptr);
-  QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
-  process_client_hello_cb_ = nullptr;
-  proof_source_details_ = std::move(proof_source_details);
-
-  AdjustTestValue("quic::QuicCryptoServerStream::after_process_client_hello",
-                  session());
-
-  if (!session()->connection()->connected()) {
-    QUIC_CODE_COUNT(quic_crypto_disconnected_after_process_client_hello);
-    QUIC_LOG_FIRST_N(INFO, 10)
-        << "After processing CHLO, QUIC connection has been closed with code "
-        << session()->error() << ", details: " << session()->error_details();
-    return;
-  }
-
-  const CryptoHandshakeMessage& message = result.client_hello;
-  if (error != QUIC_NO_ERROR) {
-    OnUnrecoverableError(error, error_details);
-    return;
-  }
-
-  if (reply->tag() != kSHLO) {
-    session()->connection()->set_fully_pad_crypto_handshake_packets(
-        crypto_config_->pad_rej());
-    // Send REJ in plaintext.
-    SendHandshakeMessage(*reply, ENCRYPTION_INITIAL);
-    return;
-  }
-
-  // If we are returning a SHLO then we accepted the handshake.  Now
-  // process the negotiated configuration options as part of the
-  // session config.
-  QuicConfig* config = session()->config();
-  OverrideQuicConfigDefaults(config);
-  std::string process_error_details;
-  const QuicErrorCode process_error =
-      config->ProcessPeerHello(message, CLIENT, &process_error_details);
-  if (process_error != QUIC_NO_ERROR) {
-    OnUnrecoverableError(process_error, process_error_details);
-    return;
-  }
-
-  session()->OnConfigNegotiated();
-
-  config->ToHandshakeMessage(reply.get(), session()->transport_version());
-
-  // Receiving a full CHLO implies the client is prepared to decrypt with
-  // the new server write key.  We can start to encrypt with the new server
-  // write key.
-  //
-  // NOTE: the SHLO will be encrypted with the new server write key.
-  delegate_->OnNewEncryptionKeyAvailable(
-      ENCRYPTION_ZERO_RTT,
-      std::move(crypto_negotiated_params_->initial_crypters.encrypter));
-  delegate_->OnNewDecryptionKeyAvailable(
-      ENCRYPTION_ZERO_RTT,
-      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
-      /*set_alternative_decrypter=*/false,
-      /*latch_once_used=*/false);
-  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  delegate_->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
-  session()->connection()->SetDiversificationNonce(*diversification_nonce);
-
-  session()->connection()->set_fully_pad_crypto_handshake_packets(
-      crypto_config_->pad_shlo());
-  // Send SHLO in ENCRYPTION_ZERO_RTT.
-  SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT);
-  delegate_->OnNewEncryptionKeyAvailable(
-      ENCRYPTION_FORWARD_SECURE,
-      std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
-  delegate_->OnNewDecryptionKeyAvailable(
-      ENCRYPTION_FORWARD_SECURE,
-      std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
-      /*set_alternative_decrypter=*/true,
-      /*latch_once_used=*/false);
-  encryption_established_ = true;
-  one_rtt_keys_available_ = true;
-  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-}
-
-void QuicCryptoServerStream::SendServerConfigUpdate(
-    const CachedNetworkParameters* cached_network_params) {
-  if (!one_rtt_keys_available_) {
-    return;
-  }
-
-  if (send_server_config_update_cb_ != nullptr) {
-    QUIC_DVLOG(1)
-        << "Skipped server config update since one is already in progress";
-    return;
-  }
-
-  std::unique_ptr<SendServerConfigUpdateCallback> cb(
-      new SendServerConfigUpdateCallback(this));
-  send_server_config_update_cb_ = cb.get();
-
-  crypto_config_->BuildServerConfigUpdateMessage(
-      session()->transport_version(), chlo_hash_,
-      previous_source_address_tokens_, session()->connection()->self_address(),
-      GetClientAddress(), session()->connection()->clock(),
-      session()->connection()->random_generator(), compressed_certs_cache_,
-      *crypto_negotiated_params_, cached_network_params, std::move(cb));
-}
-
-QuicCryptoServerStream::SendServerConfigUpdateCallback::
-    SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
-    : parent_(parent) {}
-
-void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
-  parent_ = nullptr;
-}
-
-// From BuildServerConfigUpdateMessageResultCallback
-void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
-    bool ok,
-    const CryptoHandshakeMessage& message) {
-  if (parent_ == nullptr) {
-    return;
-  }
-  parent_->FinishSendServerConfigUpdate(ok, message);
-}
-
-void QuicCryptoServerStream::FinishSendServerConfigUpdate(
-    bool ok,
-    const CryptoHandshakeMessage& message) {
-  // Clear the callback that got us here.
-  QUICHE_DCHECK(send_server_config_update_cb_ != nullptr);
-  send_server_config_update_cb_ = nullptr;
-
-  if (!ok) {
-    QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!";
-    return;
-  }
-
-  QUIC_DVLOG(1) << "Server: Sending server config update: "
-                << message.DebugString();
-
-  // Send server config update in ENCRYPTION_FORWARD_SECURE.
-  SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE);
-
-  ++num_server_config_update_messages_sent_;
-}
-
-bool QuicCryptoServerStream::DisableResumption() {
-  QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
-  return false;
-}
-
-bool QuicCryptoServerStream::IsZeroRtt() const {
-  return num_handshake_messages_ == 1 &&
-         num_handshake_messages_with_server_nonces_ == 0;
-}
-
-bool QuicCryptoServerStream::IsResumption() const {
-  // QUIC Crypto doesn't have a non-0-RTT resumption mode.
-  return IsZeroRtt();
-}
-
-int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
-  return num_server_config_update_messages_sent_;
-}
-
-const CachedNetworkParameters*
-QuicCryptoServerStream::PreviousCachedNetworkParams() const {
-  return previous_cached_network_params_.get();
-}
-
-bool QuicCryptoServerStream::ResumptionAttempted() const {
-  return zero_rtt_attempted_;
-}
-
-bool QuicCryptoServerStream::EarlyDataAttempted() const {
-  QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
-  return zero_rtt_attempted_;
-}
-
-void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
-    CachedNetworkParameters cached_network_params) {
-  previous_cached_network_params_.reset(
-      new CachedNetworkParameters(cached_network_params));
-}
-
-void QuicCryptoServerStream::OnPacketDecrypted(EncryptionLevel level) {
-  if (level == ENCRYPTION_FORWARD_SECURE) {
-    one_rtt_packet_decrypted_ = true;
-    delegate_->NeuterHandshakeData();
-  }
-}
-
-void QuicCryptoServerStream::OnHandshakeDoneReceived() {
-  QUICHE_DCHECK(false);
-}
-
-void QuicCryptoServerStream::OnNewTokenReceived(absl::string_view /*token*/) {
-  QUICHE_DCHECK(false);
-}
-
-std::string QuicCryptoServerStream::GetAddressToken(
-    const CachedNetworkParameters* /*cached_network_parameters*/) const {
-  QUICHE_DCHECK(false);
-  return "";
-}
-
-bool QuicCryptoServerStream::ValidateAddressToken(
-    absl::string_view /*token*/) const {
-  QUICHE_DCHECK(false);
-  return false;
-}
-
-bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
-  return signed_config_->proof.send_expect_ct_header;
-}
-
-bool QuicCryptoServerStream::DidCertMatchSni() const {
-  return signed_config_->proof.cert_matched_sni;
-}
-
-const ProofSource::Details* QuicCryptoServerStream::ProofSourceDetails() const {
-  return proof_source_details_.get();
-}
-
-bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
-    std::string* output) const {
-  if (!encryption_established() ||
-      crypto_negotiated_params_->channel_id.empty()) {
-    return false;
-  }
-
-  const std::string& channel_id(crypto_negotiated_params_->channel_id);
-  uint8_t digest[SHA256_DIGEST_LENGTH];
-  SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
-         digest);
-
-  quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output);
-  return true;
-}
-
-ssl_early_data_reason_t QuicCryptoServerStream::EarlyDataReason() const {
-  if (IsZeroRtt()) {
-    return ssl_early_data_accepted;
-  }
-  if (zero_rtt_attempted_) {
-    return ssl_early_data_session_not_resumed;
-  }
-  return ssl_early_data_no_session_offered;
-}
-
-bool QuicCryptoServerStream::encryption_established() const {
-  return encryption_established_;
-}
-
-bool QuicCryptoServerStream::one_rtt_keys_available() const {
-  return one_rtt_keys_available_;
-}
-
-const QuicCryptoNegotiatedParameters&
-QuicCryptoServerStream::crypto_negotiated_params() const {
-  return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* QuicCryptoServerStream::crypto_message_parser() {
-  return QuicCryptoHandshaker::crypto_message_parser();
-}
-
-HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
-  return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-}
-
-void QuicCryptoServerStream::SetServerApplicationStateForResumption(
-    std::unique_ptr<ApplicationState> /*state*/) {
-  // QUIC Crypto doesn't need to remember any application state as part of doing
-  // 0-RTT resumption, so this function is a no-op.
-}
-
-size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
-    EncryptionLevel level) const {
-  return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  // Key update is only defined in QUIC+TLS.
-  QUICHE_DCHECK(false);
-  return nullptr;
-}
-
-std::unique_ptr<QuicEncrypter>
-QuicCryptoServerStream::CreateCurrentOneRttEncrypter() {
-  // Key update is only defined in QUIC+TLS.
-  QUICHE_DCHECK(false);
-  return nullptr;
-}
-
-void QuicCryptoServerStream::ProcessClientHello(
-    quiche::QuicheReferenceCountedPointer<
-        ValidateClientHelloResultCallback::Result>
-        result,
-    std::unique_ptr<ProofSource::Details> proof_source_details,
-    std::unique_ptr<ProcessClientHelloResultCallback> done_cb) {
-  proof_source_details_ = std::move(proof_source_details);
-  const CryptoHandshakeMessage& message = result->client_hello;
-  std::string error_details;
-  if (!helper_->CanAcceptClientHello(
-          message, GetClientAddress(), session()->connection()->peer_address(),
-          session()->connection()->self_address(), &error_details)) {
-    done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr,
-                 nullptr);
-    return;
-  }
-
-  absl::string_view user_agent_id;
-  message.GetStringPiece(quic::kUAID, &user_agent_id);
-  if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) {
-    session()->SetUserAgentId(std::string(user_agent_id));
-  }
-
-  if (!result->info.server_nonce.empty()) {
-    ++num_handshake_messages_with_server_nonces_;
-  }
-
-  if (num_handshake_messages_ == 1) {
-    // Client attempts zero RTT handshake by sending a non-inchoate CHLO.
-    absl::string_view public_value;
-    zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value);
-  }
-
-  // Store the bandwidth estimate from the client.
-  if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
-    previous_cached_network_params_.reset(
-        new CachedNetworkParameters(result->cached_network_params));
-  }
-  previous_source_address_tokens_ = result->info.source_address_tokens;
-
-  QuicConnection* connection = session()->connection();
-  crypto_config_->ProcessClientHello(
-      result, /*reject_only=*/false, connection->connection_id(),
-      connection->self_address(), GetClientAddress(), connection->version(),
-      session()->supported_versions(), connection->clock(),
-      connection->random_generator(), compressed_certs_cache_,
-      crypto_negotiated_params_, signed_config_,
-      QuicCryptoStream::CryptoMessageFramingOverhead(
-          transport_version(), connection->connection_id()),
-      chlo_packet_size_, std::move(done_cb));
-}
-
-void QuicCryptoServerStream::OverrideQuicConfigDefaults(
-    QuicConfig* /*config*/) {}
-
-QuicCryptoServerStream::ValidateCallback::ValidateCallback(
-    QuicCryptoServerStream* parent)
-    : parent_(parent) {}
-
-void QuicCryptoServerStream::ValidateCallback::Cancel() {
-  parent_ = nullptr;
-}
-
-void QuicCryptoServerStream::ValidateCallback::Run(
-    quiche::QuicheReferenceCountedPointer<Result> result,
-    std::unique_ptr<ProofSource::Details> details) {
-  if (parent_ != nullptr) {
-    parent_->FinishProcessingHandshakeMessage(std::move(result),
-                                              std::move(details));
-  }
-}
-
-const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
-  return session()->connection()->peer_address();
-}
-
-SSL* QuicCryptoServerStream::GetSsl() const { return nullptr; }
-
-}  // namespace quic
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
deleted file mode 100644
index d26b751..0000000
--- a/quic/core/quic_crypto_server_stream.h
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
-
-#include <string>
-
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/proto/source_address_token_proto.h"
-#include "quic/core/quic_crypto_handshaker.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicCryptoServerStreamPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
-    : public QuicCryptoServerStreamBase,
-      public QuicCryptoHandshaker {
- public:
-  QuicCryptoServerStream(const QuicCryptoServerStream&) = delete;
-  QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete;
-
-  ~QuicCryptoServerStream() override;
-
-  // From QuicCryptoServerStreamBase
-  void CancelOutstandingCallbacks() override;
-  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
-  void SendServerConfigUpdate(
-      const CachedNetworkParameters* cached_network_params) override;
-  bool DisableResumption() override;
-  bool IsZeroRtt() const override;
-  bool IsResumption() const override;
-  bool ResumptionAttempted() const override;
-  bool EarlyDataAttempted() const override;
-  int NumServerConfigUpdateMessagesSent() const override;
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters cached_network_params) override;
-  void OnPacketDecrypted(EncryptionLevel level) override;
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnConnectionClosed(QuicErrorCode /*error*/,
-                          ConnectionCloseSource /*source*/) override {}
-  void OnHandshakeDoneReceived() override;
-  void OnNewTokenReceived(absl::string_view token) override;
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_params*/) const override;
-  bool ValidateAddressToken(absl::string_view token) const override;
-  bool ShouldSendExpectCTHeader() const override;
-  bool DidCertMatchSni() const override;
-  const ProofSource::Details* ProofSourceDetails() const override;
-
-  // From QuicCryptoStream
-  ssl_early_data_reason_t EarlyDataReason() const override;
-  bool encryption_established() const override;
-  bool one_rtt_keys_available() const override;
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override;
-  CryptoMessageParser* crypto_message_parser() override;
-  HandshakeState GetHandshakeState() const override;
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> state) override;
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-  SSL* GetSsl() const override;
-
-  // From QuicCryptoHandshaker
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
-
- protected:
-  QUIC_EXPORT_PRIVATE friend std::unique_ptr<QuicCryptoServerStreamBase>
-  CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
-                           QuicCompressedCertsCache* compressed_certs_cache,
-                           QuicSession* session,
-                           QuicCryptoServerStreamBase::Helper* helper);
-
-  // |crypto_config| must outlive the stream.
-  // |session| must outlive the stream.
-  // |helper| must outlive the stream.
-  QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
-                         QuicCompressedCertsCache* compressed_certs_cache,
-                         QuicSession* session,
-                         QuicCryptoServerStreamBase::Helper* helper);
-
-  virtual void ProcessClientHello(
-      quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>
-          result,
-      std::unique_ptr<ProofSource::Details> proof_source_details,
-      std::unique_ptr<ProcessClientHelloResultCallback> done_cb);
-
-  // Hook that allows the server to set QuicConfig defaults just
-  // before going through the parameter negotiation step.
-  virtual void OverrideQuicConfigDefaults(QuicConfig* config);
-
-  // Returns client address used to generate and validate source address token.
-  virtual const QuicSocketAddress GetClientAddress();
-
-  // Returns the QuicSession that this stream belongs to.
-  QuicSession* session() const { return session_; }
-
-  void set_encryption_established(bool encryption_established) {
-    encryption_established_ = encryption_established;
-  }
-
-  void set_one_rtt_keys_available(bool one_rtt_keys_available) {
-    one_rtt_keys_available_ = one_rtt_keys_available;
-  }
-
- private:
-  friend class test::QuicCryptoServerStreamPeer;
-
-  class QUIC_EXPORT_PRIVATE ValidateCallback
-      : public ValidateClientHelloResultCallback {
-   public:
-    explicit ValidateCallback(QuicCryptoServerStream* parent);
-    ValidateCallback(const ValidateCallback&) = delete;
-    ValidateCallback& operator=(const ValidateCallback&) = delete;
-    // To allow the parent to detach itself from the callback before deletion.
-    void Cancel();
-
-    // From ValidateClientHelloResultCallback
-    void Run(quiche::QuicheReferenceCountedPointer<Result> result,
-             std::unique_ptr<ProofSource::Details> details) override;
-
-   private:
-    QuicCryptoServerStream* parent_;
-  };
-
-  class SendServerConfigUpdateCallback
-      : public BuildServerConfigUpdateMessageResultCallback {
-   public:
-    explicit SendServerConfigUpdateCallback(QuicCryptoServerStream* parent);
-    SendServerConfigUpdateCallback(const SendServerConfigUpdateCallback&) =
-        delete;
-    void operator=(const SendServerConfigUpdateCallback&) = delete;
-
-    // To allow the parent to detach itself from the callback before deletion.
-    void Cancel();
-
-    // From BuildServerConfigUpdateMessageResultCallback
-    void Run(bool ok, const CryptoHandshakeMessage& message) override;
-
-   private:
-    QuicCryptoServerStream* parent_;
-  };
-
-  // Invoked by ValidateCallback::RunImpl once initial validation of
-  // the client hello is complete.  Finishes processing of the client
-  // hello message and handles handshake success/failure.
-  void FinishProcessingHandshakeMessage(
-      quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>
-          result,
-      std::unique_ptr<ProofSource::Details> details);
-
-  class ProcessClientHelloCallback;
-  friend class ProcessClientHelloCallback;
-
-  // Portion of FinishProcessingHandshakeMessage which executes after
-  // ProcessClientHello has been called.
-  void FinishProcessingHandshakeMessageAfterProcessClientHello(
-      const ValidateClientHelloResultCallback::Result& result,
-      QuicErrorCode error,
-      const std::string& error_details,
-      std::unique_ptr<CryptoHandshakeMessage> reply,
-      std::unique_ptr<DiversificationNonce> diversification_nonce,
-      std::unique_ptr<ProofSource::Details> proof_source_details);
-
-  // Invoked by SendServerConfigUpdateCallback::RunImpl once the proof has been
-  // received.  |ok| indicates whether or not the proof was successfully
-  // acquired, and |message| holds the partially-constructed message from
-  // SendServerConfigUpdate.
-  void FinishSendServerConfigUpdate(bool ok,
-                                    const CryptoHandshakeMessage& message);
-
-  // Returns the QuicTransportVersion of the connection.
-  QuicTransportVersion transport_version() const {
-    return session_->transport_version();
-  }
-
-  QuicSession* session_;
-  HandshakerDelegateInterface* delegate_;
-
-  // crypto_config_ contains crypto parameters for the handshake.
-  const QuicCryptoServerConfig* crypto_config_;
-
-  // compressed_certs_cache_ contains a set of most recently compressed certs.
-  // Owned by QuicDispatcher.
-  QuicCompressedCertsCache* compressed_certs_cache_;
-
-  // Server's certificate chain and signature of the server config, as provided
-  // by ProofSource::GetProof.
-  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
-
-  // Hash of the last received CHLO message which can be used for generating
-  // server config update messages.
-  std::string chlo_hash_;
-
-  // Pointer to the helper for this crypto stream. Must outlive this stream.
-  QuicCryptoServerStreamBase::Helper* helper_;
-
-  // Number of handshake messages received by this stream.
-  uint8_t num_handshake_messages_;
-
-  // Number of handshake messages received by this stream that contain
-  // server nonces (indicating that this is a non-zero-RTT handshake
-  // attempt).
-  uint8_t num_handshake_messages_with_server_nonces_;
-
-  // Pointer to the active callback that will receive the result of
-  // BuildServerConfigUpdateMessage and forward it to
-  // FinishSendServerConfigUpdate.  nullptr if no update message is currently
-  // being built.
-  SendServerConfigUpdateCallback* send_server_config_update_cb_;
-
-  // Number of server config update (SCUP) messages sent by this stream.
-  int num_server_config_update_messages_sent_;
-
-  // If the client provides CachedNetworkParameters in the STK in the CHLO, then
-  // store here, and send back in future STKs if we have no better bandwidth
-  // estimate to send.
-  std::unique_ptr<CachedNetworkParameters> previous_cached_network_params_;
-
-  // Contains any source address tokens which were present in the CHLO.
-  SourceAddressTokens previous_source_address_tokens_;
-
-  // True if client attempts 0-rtt handshake (which can succeed or fail).
-  bool zero_rtt_attempted_;
-
-  // Size of the packet containing the most recently received CHLO.
-  QuicByteCount chlo_packet_size_;
-
-  // Pointer to the active callback that will receive the result of the client
-  // hello validation request and forward it to FinishProcessingHandshakeMessage
-  // for processing.  nullptr if no handshake message is being validated.  Note
-  // that this field is mutually exclusive with process_client_hello_cb_.
-  ValidateCallback* validate_client_hello_cb_;
-
-  // Pointer to the active callback which will receive the results of
-  // ProcessClientHello and forward it to
-  // FinishProcessingHandshakeMessageAfterProcessClientHello.  Note that this
-  // field is mutually exclusive with validate_client_hello_cb_.
-  ProcessClientHelloCallback* process_client_hello_cb_;
-
-  // The ProofSource::Details from this connection.
-  std::unique_ptr<ProofSource::Details> proof_source_details_;
-
-  bool encryption_established_;
-  bool one_rtt_keys_available_;
-  bool one_rtt_packet_decrypted_;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      crypto_negotiated_params_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
diff --git a/quic/core/quic_crypto_server_stream_base.cc b/quic/core/quic_crypto_server_stream_base.cc
deleted file mode 100644
index 708b175..0000000
--- a/quic/core/quic_crypto_server_stream_base.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_server_stream_base.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_server_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/tls_server_handshaker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicCryptoServerStreamBase::QuicCryptoServerStreamBase(QuicSession* session)
-    : QuicCryptoStream(session) {}
-
-std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoServerStream(
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    QuicSession* session,
-    QuicCryptoServerStreamBase::Helper* helper) {
-  switch (session->connection()->version().handshake_protocol) {
-    case PROTOCOL_QUIC_CRYPTO:
-      return std::unique_ptr<QuicCryptoServerStream>(new QuicCryptoServerStream(
-          crypto_config, compressed_certs_cache, session, helper));
-    case PROTOCOL_TLS1_3:
-      return std::unique_ptr<TlsServerHandshaker>(
-          new TlsServerHandshaker(session, crypto_config));
-    case PROTOCOL_UNSUPPORTED:
-      break;
-  }
-  QUIC_BUG(quic_bug_10492_1)
-      << "Unknown handshake protocol: "
-      << static_cast<int>(session->connection()->version().handshake_protocol);
-  return nullptr;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_crypto_server_stream_base.h b/quic/core/quic_crypto_server_stream_base.h
deleted file mode 100644
index dcefdfb..0000000
--- a/quic/core/quic_crypto_server_stream_base.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_crypto_handshaker.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CachedNetworkParameters;
-class CryptoHandshakeMessage;
-class QuicCryptoServerConfig;
-class QuicCryptoServerStreamBase;
-
-// TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
-// various code and test refactoring.
-class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
- public:
-  explicit QuicCryptoServerStreamBase(QuicSession* session);
-
-  class QUIC_EXPORT_PRIVATE Helper {
-   public:
-    virtual ~Helper() {}
-
-    // Returns true if |message|, which was received on |self_address| is
-    // acceptable according to the visitor's policy. Otherwise, returns false
-    // and populates |error_details|.
-    virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
-                                      const QuicSocketAddress& client_address,
-                                      const QuicSocketAddress& peer_address,
-                                      const QuicSocketAddress& self_address,
-                                      std::string* error_details) const = 0;
-  };
-
-  ~QuicCryptoServerStreamBase() override {}
-
-  // Cancel any outstanding callbacks, such as asynchronous validation of client
-  // hello.
-  virtual void CancelOutstandingCallbacks() = 0;
-
-  // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
-  // SHA-256 hash of the client's ChannelID key and returns true, if the client
-  // presented a ChannelID. Otherwise it returns false.
-  virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0;
-
-  virtual int NumServerConfigUpdateMessagesSent() const = 0;
-
-  // Sends the latest server config and source-address token to the client.
-  virtual void SendServerConfigUpdate(
-      const CachedNetworkParameters* cached_network_params) = 0;
-
-  // Disables TLS resumption, should be called as early as possible.
-  // Return true if resumption is disabled.
-  // Return false if nothing happened, typically it means it is called too late.
-  virtual bool DisableResumption() = 0;
-
-  // Returns true if the connection was a successful 0-RTT resumption.
-  virtual bool IsZeroRtt() const = 0;
-
-  // Returns true if the connection was the result of a resumption handshake,
-  // whether 0-RTT or not.
-  virtual bool IsResumption() const = 0;
-
-  // Returns true if the client attempted a resumption handshake, whether or not
-  // the resumption actually occurred.
-  virtual bool ResumptionAttempted() const = 0;
-
-  // Returns true if the client attempted to use early data, as indicated by the
-  // "early_data" TLS extension. TLS only.
-  virtual bool EarlyDataAttempted() const = 0;
-
-  // NOTE: Indicating that the Expect-CT header should be sent here presents
-  // a layering violation to some extent. The Expect-CT header only applies to
-  // HTTP connections, while this class can be used for non-HTTP applications.
-  // However, it is exposed here because that is the only place where the
-  // configuration for the certificate used in the connection is accessible.
-  virtual bool ShouldSendExpectCTHeader() const = 0;
-
-  // Return true if a cert was picked that matched the SNI hostname.
-  virtual bool DidCertMatchSni() const = 0;
-
-  // Returns the Details from the latest call to ProofSource::GetProof or
-  // ProofSource::ComputeTlsSignature. Returns nullptr if no such call has been
-  // made. The Details are owned by the QuicCryptoServerStreamBase and the
-  // pointer is only valid while the owning object is still valid.
-  virtual const ProofSource::Details* ProofSourceDetails() const = 0;
-
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    QUICHE_NOTREACHED();
-    return false;
-  }
-};
-
-// Creates an appropriate QuicCryptoServerStream for the provided parameters,
-// including the version used by |session|. |crypto_config|, |session|, and
-// |helper| must all outlive the stream. The caller takes ownership of the
-// returned object.
-QUIC_EXPORT_PRIVATE std::unique_ptr<QuicCryptoServerStreamBase>
-CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
-                         QuicCompressedCertsCache* compressed_certs_cache,
-                         QuicSession* session,
-                         QuicCryptoServerStreamBase::Helper* helper);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
diff --git a/quic/core/quic_crypto_server_stream_test.cc b/quic/core/quic_crypto_server_stream_test.cc
deleted file mode 100644
index 4e07f34..0000000
--- a/quic/core/quic_crypto_server_stream_test.cc
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_server_stream_base.h"
-
-#include <map>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/aes_128_gcm_12_encrypter.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/failing_proof_source.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-class QuicConnection;
-class QuicStream;
-}  // namespace quic
-
-using testing::_;
-using testing::NiceMock;
-
-namespace quic {
-namespace test {
-
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kServerPort = 443;
-
-// This test tests the server-side of the QUIC crypto handshake. It does not
-// test the TLS handshake - that is in tls_server_handshaker_test.cc.
-class QuicCryptoServerStreamTest : public QuicTest {
- public:
-  QuicCryptoServerStreamTest()
-      : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) {
-  }
-
-  explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
-      : server_crypto_config_(QuicCryptoServerConfig::TESTING,
-                              QuicRandom::GetInstance(),
-                              std::move(proof_source),
-                              KeyExchangeSource::Default()),
-        server_compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
-        server_id_(kServerHostname, kServerPort, false),
-        client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
-
-  void Initialize() { InitializeServer(); }
-
-  ~QuicCryptoServerStreamTest() override {
-    // Ensure that anything that might reference |helpers_| is destroyed before
-    // |helpers_| is destroyed.
-    server_session_.reset();
-    client_session_.reset();
-    helpers_.clear();
-    alarm_factories_.clear();
-  }
-
-  // Initializes the crypto server stream state for testing.  May be
-  // called multiple times.
-  void InitializeServer() {
-    TestQuicSpdyServerSession* server_session = nullptr;
-    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
-    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
-    CreateServerSessionForTest(
-        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
-        helpers_.back().get(), alarm_factories_.back().get(),
-        &server_crypto_config_, &server_compressed_certs_cache_,
-        &server_connection_, &server_session);
-    QUICHE_CHECK(server_session);
-    server_session_.reset(server_session);
-    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
-        .Times(testing::AnyNumber());
-    EXPECT_CALL(*server_session_, SelectAlpn(_))
-        .WillRepeatedly(
-            [this](const std::vector<absl::string_view>& alpns) {
-              return std::find(
-                  alpns.cbegin(), alpns.cend(),
-                  AlpnForVersion(server_session_->connection()->version()));
-            });
-    crypto_test_utils::SetupCryptoServerConfigForTest(
-        server_connection_->clock(), server_connection_->random_generator(),
-        &server_crypto_config_);
-  }
-
-  QuicCryptoServerStreamBase* server_stream() {
-    return server_session_->GetMutableCryptoStream();
-  }
-
-  QuicCryptoClientStream* client_stream() {
-    return client_session_->GetMutableCryptoStream();
-  }
-
-  // Initializes a fake client, and all its associated state, for
-  // testing.  May be called multiple times.
-  void InitializeFakeClient() {
-    TestQuicSpdyClientSession* client_session = nullptr;
-    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
-    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
-    CreateClientSessionForTest(
-        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
-        helpers_.back().get(), alarm_factories_.back().get(),
-        &client_crypto_config_, &client_connection_, &client_session);
-    QUICHE_CHECK(client_session);
-    client_session_.reset(client_session);
-  }
-
-  int CompleteCryptoHandshake() {
-    QUICHE_CHECK(server_connection_);
-    QUICHE_CHECK(server_session_ != nullptr);
-
-    return crypto_test_utils::HandshakeWithFakeClient(
-        helpers_.back().get(), alarm_factories_.back().get(),
-        server_connection_, server_stream(), server_id_, client_options_,
-        /*alpn=*/"");
-  }
-
-  // Performs a single round of handshake message-exchange between the
-  // client and server.
-  void AdvanceHandshakeWithFakeClient() {
-    QUICHE_CHECK(server_connection_);
-    QUICHE_CHECK(client_session_ != nullptr);
-
-    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
-    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
-        .Times(testing::AnyNumber());
-    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
-    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
-    client_stream()->CryptoConnect();
-    crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0,
-                                        server_connection_, server_stream(), 0);
-  }
-
- protected:
-  // Every connection gets its own MockQuicConnectionHelper and
-  // MockAlarmFactory, tracked separately from the server and client state so
-  // their lifetimes persist through the whole test.
-  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
-  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
-
-  // Server state.
-  PacketSavingConnection* server_connection_;
-  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
-  QuicCryptoServerConfig server_crypto_config_;
-  QuicCompressedCertsCache server_compressed_certs_cache_;
-  QuicServerId server_id_;
-
-  // Client state.
-  PacketSavingConnection* client_connection_;
-  QuicCryptoClientConfig client_crypto_config_;
-  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
-
-  CryptoHandshakeMessage message_;
-  crypto_test_utils::FakeClientOptions client_options_;
-
-  // Which QUIC versions the client and server support.
-  ParsedQuicVersionVector supported_versions_ =
-      AllSupportedVersionsWithQuicCrypto();
-};
-
-TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
-  Initialize();
-  EXPECT_FALSE(server_stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
-  // CompleteCryptoHandshake returns the number of client hellos sent. This
-  // test should send:
-  //   * One to get a source-address token and certificates.
-  //   * One to complete the handshake.
-  Initialize();
-  EXPECT_EQ(2, CompleteCryptoHandshake());
-  EXPECT_TRUE(server_stream()->encryption_established());
-  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
-  Initialize();
-  InitializeFakeClient();
-
-  // Do a first handshake in order to prime the client config with the server's
-  // information.
-  AdvanceHandshakeWithFakeClient();
-  EXPECT_FALSE(server_stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-
-  // Now do another handshake, with the blocking SHLO connection option.
-  InitializeServer();
-  InitializeFakeClient();
-
-  AdvanceHandshakeWithFakeClient();
-  EXPECT_TRUE(server_stream()->encryption_established());
-  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
-            server_session_->connection()->encryption_level());
-}
-
-TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
-  Initialize();
-  InitializeFakeClient();
-
-  // Do a first handshake in order to prime the client config with the server's
-  // information.
-  AdvanceHandshakeWithFakeClient();
-  EXPECT_FALSE(server_stream()->ResumptionAttempted());
-
-  // Now do another handshake, hopefully in 0-RTT.
-  QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
-  InitializeFakeClient();
-  InitializeServer();
-
-  EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
-  EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
-      .Times(testing::AnyNumber());
-  EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
-  client_stream()->CryptoConnect();
-
-  EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
-  EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
-      .Times(testing::AnyNumber());
-  EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
-  crypto_test_utils::CommunicateHandshakeMessages(
-      client_connection_, client_stream(), server_connection_, server_stream());
-
-  EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
-  EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_F(QuicCryptoServerStreamTest, FailByPolicy) {
-  Initialize();
-  InitializeFakeClient();
-
-  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
-  AdvanceHandshakeWithFakeClient();
-}
-
-TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
-  Initialize();
-  CompleteCryptoHandshake();
-  EXPECT_CALL(
-      *server_connection_,
-      CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
-  message_.set_tag(kCHLO);
-  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
-                                                  Perspective::IS_CLIENT);
-}
-
-TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
-  Initialize();
-
-  message_.set_tag(kSHLO);
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _, _));
-  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
-                                                  Perspective::IS_SERVER);
-}
-
-TEST_F(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
-  // An attempt to send a SCUP before completing handshake should fail.
-  Initialize();
-
-  server_stream()->SendServerConfigUpdate(nullptr);
-  EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
-}
-
-TEST_F(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
-  Initialize();
-
-  InitializeFakeClient();
-
-  // Do a first handshake in order to prime the client config with the server's
-  // information.
-  AdvanceHandshakeWithFakeClient();
-
-  // Now do another handshake, with the blocking SHLO connection option.
-  InitializeServer();
-  InitializeFakeClient();
-  AdvanceHandshakeWithFakeClient();
-
-  // Send a SCUP message and ensure that the client was able to verify it.
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  server_stream()->SendServerConfigUpdate(nullptr);
-  crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1,
-                                      server_connection_, server_stream(), 1);
-
-  EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent());
-  EXPECT_EQ(1, client_stream()->num_scup_messages_received());
-}
-
-class QuicCryptoServerStreamTestWithFailingProofSource
-    : public QuicCryptoServerStreamTest {
- public:
-  QuicCryptoServerStreamTestWithFailingProofSource()
-      : QuicCryptoServerStreamTest(
-            std::unique_ptr<FailingProofSource>(new FailingProofSource)) {}
-};
-
-TEST_F(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
-  Initialize();
-  InitializeFakeClient();
-
-  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
-      .WillOnce(testing::Return(true));
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to get proof", _));
-  // Regression test for b/31521252, in which a crash would happen here.
-  AdvanceHandshakeWithFakeClient();
-  EXPECT_FALSE(server_stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-class QuicCryptoServerStreamTestWithFakeProofSource
-    : public QuicCryptoServerStreamTest {
- public:
-  QuicCryptoServerStreamTestWithFakeProofSource()
-      : QuicCryptoServerStreamTest(
-            std::unique_ptr<FakeProofSource>(new FakeProofSource)),
-        crypto_config_peer_(&server_crypto_config_) {}
-
-  FakeProofSource* GetFakeProofSource() const {
-    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
-  }
-
- protected:
-  QuicCryptoServerConfigPeer crypto_config_peer_;
-};
-
-// Regression test for b/35422225, in which multiple CHLOs arriving on the same
-// connection in close succession could cause a crash.
-TEST_F(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
-  Initialize();
-  GetFakeProofSource()->Activate();
-  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
-      .WillOnce(testing::Return(true));
-
-  // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
-  // first one from the list of supported versions.
-  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-      transport_version = version.transport_version;
-      break;
-    }
-  }
-  ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
-
-  // Create a minimal CHLO
-  MockClock clock;
-  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
-      &clock, transport_version, &server_crypto_config_);
-
-  // Send in the CHLO, and check that a callback is now pending in the
-  // ProofSource.
-  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
-                                                  Perspective::IS_CLIENT);
-  EXPECT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
-
-  // Send in a second CHLO while processing of the first is still pending.
-  // Verify that the server closes the connection rather than crashing.  Note
-  // that the crash is a use-after-free, so it may only show up consistently in
-  // ASAN tests.
-  EXPECT_CALL(
-      *server_connection_,
-      CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
-                      "Unexpected handshake message while processing CHLO", _));
-  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
-                                                  Perspective::IS_CLIENT);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc
deleted file mode 100644
index 5690743..0000000
--- a/quic/core/quic_crypto_stream.cc
+++ /dev/null
@@ -1,482 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_stream.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define ENDPOINT                                                   \
-  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
-                                                      : "Client:"  \
-                                                        " ")
-
-QuicCryptoStream::QuicCryptoStream(QuicSession* session)
-    : QuicStream(
-          QuicVersionUsesCryptoFrames(session->transport_version())
-              ? QuicUtils::GetInvalidStreamId(session->transport_version())
-              : QuicUtils::GetCryptoStreamId(session->transport_version()),
-          session,
-          /*is_static=*/true,
-          QuicVersionUsesCryptoFrames(session->transport_version())
-              ? CRYPTO
-              : BIDIRECTIONAL),
-      substreams_{{{this, ENCRYPTION_INITIAL},
-                   {this, ENCRYPTION_HANDSHAKE},
-                   {this, ENCRYPTION_ZERO_RTT},
-                   {this, ENCRYPTION_FORWARD_SECURE}}} {
-  // The crypto stream is exempt from connection level flow control.
-  DisableConnectionFlowControlForThisStream();
-}
-
-QuicCryptoStream::~QuicCryptoStream() {}
-
-// static
-QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead(
-    QuicTransportVersion version,
-    QuicConnectionId connection_id) {
-  QUICHE_DCHECK(
-      QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_1;
-  QuicVariableLengthIntegerLength length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  if (!QuicVersionHasLongHeaderLengths(version)) {
-    retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  }
-  return QuicPacketCreator::StreamFramePacketOverhead(
-      version, static_cast<QuicConnectionIdLength>(connection_id.length()),
-      PACKET_0BYTE_CONNECTION_ID,
-      /*include_version=*/true,
-      /*include_diversification_nonce=*/true,
-      VersionHasIetfInvariantHeader(version) ? PACKET_4BYTE_PACKET_NUMBER
-                                             : PACKET_1BYTE_PACKET_NUMBER,
-      retry_token_length_length, length_length,
-      /*offset=*/0);
-}
-
-void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12573_1,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 shouldn't receive CRYPTO frames";
-  EncryptionLevel level = session()->connection()->last_decrypted_level();
-  substreams_[level].sequencer.OnCryptoFrame(frame);
-  EncryptionLevel frame_level = level;
-  if (substreams_[level].sequencer.NumBytesBuffered() >
-      BufferSizeLimitForLevel(frame_level)) {
-    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-                         "Too much crypto data received");
-  }
-}
-
-void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
-  if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    QUIC_PEER_BUG(quic_peer_bug_12573_2)
-        << "Crypto data received in stream frame instead of crypto frame";
-    OnUnrecoverableError(QUIC_INVALID_STREAM_DATA, "Unexpected stream frame");
-  }
-  QuicStream::OnStreamFrame(frame);
-}
-
-void QuicCryptoStream::OnDataAvailable() {
-  EncryptionLevel level = session()->connection()->last_decrypted_level();
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    // Versions less than 47 only support QUIC crypto, which ignores the
-    // EncryptionLevel passed into CryptoMessageParser::ProcessInput (and
-    // OnDataAvailableInSequencer).
-    OnDataAvailableInSequencer(sequencer(), level);
-    return;
-  }
-  OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
-}
-
-void QuicCryptoStream::OnDataAvailableInSequencer(
-    QuicStreamSequencer* sequencer,
-    EncryptionLevel level) {
-  struct iovec iov;
-  while (sequencer->GetReadableRegion(&iov)) {
-    absl::string_view data(static_cast<char*>(iov.iov_base), iov.iov_len);
-    if (!crypto_message_parser()->ProcessInput(data, level)) {
-      OnUnrecoverableError(crypto_message_parser()->error(),
-                           crypto_message_parser()->error_detail());
-      return;
-    }
-    sequencer->MarkConsumed(iov.iov_len);
-    if (one_rtt_keys_available() &&
-        crypto_message_parser()->InputBytesRemaining() == 0) {
-      // If the handshake is complete and the current message has been fully
-      // processed then no more handshake messages are likely to arrive soon
-      // so release the memory in the stream sequencer.
-      sequencer->ReleaseBufferIfEmpty();
-    }
-  }
-}
-
-void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
-                                       absl::string_view data) {
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    WriteOrBufferDataAtLevel(data, /*fin=*/false, level,
-                             /*ack_listener=*/nullptr);
-    return;
-  }
-  if (data.empty()) {
-    QUIC_BUG(quic_bug_10322_1) << "Empty crypto data being written";
-    return;
-  }
-  const bool had_buffered_data = HasBufferedCryptoFrames();
-  // Append |data| to the send buffer for this encryption level.
-  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
-  QuicStreamOffset offset = send_buffer->stream_offset();
-  send_buffer->SaveStreamData(data);
-  if (kMaxStreamLength - offset < data.length()) {
-    QUIC_BUG(quic_bug_10322_2) << "Writing too much crypto handshake data";
-    // TODO(nharper): Switch this to an IETF QUIC error code, possibly
-    // INTERNAL_ERROR?
-    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
-                         "Writing too much crypto handshake data");
-  }
-  if (had_buffered_data) {
-    // Do not try to write if there is buffered data.
-    return;
-  }
-
-  size_t bytes_consumed = stream_delegate()->SendCryptoData(
-      level, data.length(), offset, NOT_RETRANSMISSION);
-  send_buffer->OnStreamDataConsumed(bytes_consumed);
-}
-
-size_t QuicCryptoStream::BufferSizeLimitForLevel(EncryptionLevel) const {
-  return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
-}
-
-bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
-                                          QuicTime::Delta /*ack_delay_time*/) {
-  QuicByteCount newly_acked_length = 0;
-  if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
-          frame.offset, frame.data_length, &newly_acked_length)) {
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
-                         "Trying to ack unsent crypto data.");
-    return false;
-  }
-  return newly_acked_length > 0;
-}
-
-void QuicCryptoStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
-  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
-                                   "Attempt to reset crypto stream");
-}
-
-void QuicCryptoStream::NeuterUnencryptedStreamData() {
-  NeuterStreamDataOfEncryptionLevel(ENCRYPTION_INITIAL);
-}
-
-void QuicCryptoStream::NeuterStreamDataOfEncryptionLevel(
-    EncryptionLevel level) {
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    for (const auto& interval : bytes_consumed_[level]) {
-      QuicByteCount newly_acked_length = 0;
-      send_buffer().OnStreamDataAcked(
-          interval.min(), interval.max() - interval.min(), &newly_acked_length);
-    }
-    return;
-  }
-  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
-  // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer to
-  // replace the following code.
-  QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
-  to_ack.Complement(0, send_buffer->stream_offset());
-  for (const auto& interval : to_ack) {
-    QuicByteCount newly_acked_length = 0;
-    send_buffer->OnStreamDataAcked(
-        interval.min(), interval.max() - interval.min(), &newly_acked_length);
-  }
-}
-
-void QuicCryptoStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
-  if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    QUIC_BUG(quic_bug_10322_3)
-        << "Stream data consumed when CRYPTO frames should be in use";
-  }
-  if (bytes_consumed > 0) {
-    bytes_consumed_[session()->connection()->encryption_level()].Add(
-        stream_bytes_written(), stream_bytes_written() + bytes_consumed);
-  }
-  QuicStream::OnStreamDataConsumed(bytes_consumed);
-}
-
-namespace {
-
-constexpr std::array<EncryptionLevel, NUM_ENCRYPTION_LEVELS>
-AllEncryptionLevels() {
-  return {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
-          ENCRYPTION_FORWARD_SECURE};
-}
-
-}  // namespace
-
-bool QuicCryptoStream::HasPendingCryptoRetransmission() const {
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    return false;
-  }
-  for (EncryptionLevel level : AllEncryptionLevels()) {
-    if (substreams_[level].send_buffer.HasPendingRetransmission()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void QuicCryptoStream::WritePendingCryptoRetransmission() {
-  QUIC_BUG_IF(quic_bug_12573_3,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 don't write CRYPTO frames";
-  for (EncryptionLevel level : AllEncryptionLevels()) {
-    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
-    while (send_buffer->HasPendingRetransmission()) {
-      auto pending = send_buffer->NextPendingRetransmission();
-      size_t bytes_consumed = stream_delegate()->SendCryptoData(
-          level, pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
-      send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
-      if (bytes_consumed < pending.length) {
-        return;
-      }
-    }
-  }
-}
-
-void QuicCryptoStream::WritePendingRetransmission() {
-  while (HasPendingRetransmission()) {
-    StreamPendingRetransmission pending =
-        send_buffer().NextPendingRetransmission();
-    QuicIntervalSet<QuicStreamOffset> retransmission(
-        pending.offset, pending.offset + pending.length);
-    EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
-    // Determine the encryption level to write the retransmission
-    // at. The retransmission should be written at the same encryption level
-    // as the original transmission.
-    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
-      if (retransmission.Intersects(bytes_consumed_[i])) {
-        retransmission_encryption_level = static_cast<EncryptionLevel>(i);
-        retransmission.Intersection(bytes_consumed_[i]);
-        break;
-      }
-    }
-    pending.offset = retransmission.begin()->min();
-    pending.length =
-        retransmission.begin()->max() - retransmission.begin()->min();
-    QuicConsumedData consumed = RetransmitStreamDataAtLevel(
-        pending.offset, pending.length, retransmission_encryption_level,
-        HANDSHAKE_RETRANSMISSION);
-    if (consumed.bytes_consumed < pending.length) {
-      // The connection is write blocked.
-      break;
-    }
-  }
-}
-
-bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset,
-                                            QuicByteCount data_length,
-                                            bool /*fin*/,
-                                            TransmissionType type) {
-  QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
-  QuicIntervalSet<QuicStreamOffset> retransmission(offset,
-                                                   offset + data_length);
-  // Determine the encryption level to send data. This only needs to be once as
-  // [offset, offset + data_length) is guaranteed to be in the same packet.
-  EncryptionLevel send_encryption_level = ENCRYPTION_INITIAL;
-  for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    if (retransmission.Intersects(bytes_consumed_[i])) {
-      send_encryption_level = static_cast<EncryptionLevel>(i);
-      break;
-    }
-  }
-  retransmission.Difference(bytes_acked());
-  for (const auto& interval : retransmission) {
-    QuicStreamOffset retransmission_offset = interval.min();
-    QuicByteCount retransmission_length = interval.max() - interval.min();
-    QuicConsumedData consumed = RetransmitStreamDataAtLevel(
-        retransmission_offset, retransmission_length, send_encryption_level,
-        type);
-    if (consumed.bytes_consumed < retransmission_length) {
-      // The connection is write blocked.
-      return false;
-    }
-  }
-
-  return true;
-}
-
-QuicConsumedData QuicCryptoStream::RetransmitStreamDataAtLevel(
-    QuicStreamOffset retransmission_offset,
-    QuicByteCount retransmission_length,
-    EncryptionLevel encryption_level,
-    TransmissionType type) {
-  QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
-  const auto consumed = stream_delegate()->WritevData(
-      id(), retransmission_length, retransmission_offset, NO_FIN, type,
-      encryption_level);
-  QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
-                << " is forced to retransmit stream data ["
-                << retransmission_offset << ", "
-                << retransmission_offset + retransmission_length
-                << "), with encryption level: " << encryption_level
-                << ", consumed: " << consumed;
-  OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
-                             consumed.fin_consumed);
-
-  return consumed;
-}
-
-uint64_t QuicCryptoStream::crypto_bytes_read() const {
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    return stream_bytes_read();
-  }
-  uint64_t bytes_read = 0;
-  for (EncryptionLevel level : AllEncryptionLevels()) {
-    bytes_read += substreams_[level].sequencer.NumBytesConsumed();
-  }
-  return bytes_read;
-}
-
-uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
-  return substreams_[level].sequencer.NumBytesConsumed();
-}
-
-bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
-                                        QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        QuicDataWriter* writer) {
-  QUIC_BUG_IF(quic_bug_12573_4,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 don't write CRYPTO frames (2)";
-  return substreams_[level].send_buffer.WriteStreamData(offset, data_length,
-                                                        writer);
-}
-
-void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
-  QUIC_BUG_IF(quic_bug_12573_5,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 don't lose CRYPTO frames";
-  substreams_[crypto_frame->level].send_buffer.OnStreamDataLost(
-      crypto_frame->offset, crypto_frame->data_length);
-}
-
-bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
-                                      TransmissionType type) {
-  QUIC_BUG_IF(quic_bug_12573_6,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 don't retransmit CRYPTO frames";
-  QuicIntervalSet<QuicStreamOffset> retransmission(
-      crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
-  QuicStreamSendBuffer* send_buffer =
-      &substreams_[crypto_frame->level].send_buffer;
-  retransmission.Difference(send_buffer->bytes_acked());
-  if (retransmission.Empty()) {
-    return true;
-  }
-  for (const auto& interval : retransmission) {
-    size_t retransmission_offset = interval.min();
-    size_t retransmission_length = interval.max() - interval.min();
-    size_t bytes_consumed = stream_delegate()->SendCryptoData(
-        crypto_frame->level, retransmission_length, retransmission_offset,
-        type);
-    send_buffer->OnStreamDataRetransmitted(retransmission_offset,
-                                           bytes_consumed);
-    if (bytes_consumed < retransmission_length) {
-      return false;
-    }
-  }
-  return true;
-}
-
-void QuicCryptoStream::WriteBufferedCryptoFrames() {
-  QUIC_BUG_IF(quic_bug_12573_7,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 don't use CRYPTO frames";
-  for (EncryptionLevel level : AllEncryptionLevels()) {
-    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
-    const size_t data_length =
-        send_buffer->stream_offset() - send_buffer->stream_bytes_written();
-    if (data_length == 0) {
-      // No buffered data for this encryption level.
-      continue;
-    }
-    size_t bytes_consumed = stream_delegate()->SendCryptoData(
-        level, data_length, send_buffer->stream_bytes_written(),
-        NOT_RETRANSMISSION);
-    send_buffer->OnStreamDataConsumed(bytes_consumed);
-    if (bytes_consumed < data_length) {
-      // Connection is write blocked.
-      break;
-    }
-  }
-}
-
-bool QuicCryptoStream::HasBufferedCryptoFrames() const {
-  QUIC_BUG_IF(quic_bug_12573_8,
-              !QuicVersionUsesCryptoFrames(session()->transport_version()))
-      << "Versions less than 47 don't use CRYPTO frames";
-  for (EncryptionLevel level : AllEncryptionLevels()) {
-    const QuicStreamSendBuffer& send_buffer = substreams_[level].send_buffer;
-    QUICHE_DCHECK_GE(send_buffer.stream_offset(),
-                     send_buffer.stream_bytes_written());
-    if (send_buffer.stream_offset() > send_buffer.stream_bytes_written()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level,
-                                          size_t offset,
-                                          size_t length) const {
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    // This only happens if a client was originally configured for a version
-    // greater than 45, but received a version negotiation packet and is
-    // attempting to retransmit for a version less than 47. Outside of tests,
-    // this is a misconfiguration of the client, and this connection will be
-    // doomed. Return false here to avoid trying to retransmit CRYPTO frames on
-    // the wrong transport version.
-    return false;
-  }
-  return substreams_[level].send_buffer.IsStreamDataOutstanding(offset, length);
-}
-
-bool QuicCryptoStream::IsWaitingForAcks() const {
-  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
-    return QuicStream::IsWaitingForAcks();
-  }
-  for (EncryptionLevel level : AllEncryptionLevels()) {
-    if (substreams_[level].send_buffer.stream_bytes_outstanding()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-QuicCryptoStream::CryptoSubstream::CryptoSubstream(
-    QuicCryptoStream* crypto_stream,
-    EncryptionLevel)
-    : sequencer(crypto_stream),
-      send_buffer(crypto_stream->session()
-                      ->connection()
-                      ->helper()
-                      ->GetStreamSendBufferAllocator()) {}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_crypto_stream.h b/quic/core/quic_crypto_stream.h
deleted file mode 100644
index cada7db..0000000
--- a/quic/core/quic_crypto_stream.h
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
-
-#include <array>
-#include <cstddef>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class CachedNetworkParameters;
-class QuicSession;
-
-// Crypto handshake messages in QUIC take place over a reserved stream with the
-// id 1.  Each endpoint (client and server) will allocate an instance of a
-// subclass of QuicCryptoStream to send and receive handshake messages.  (In the
-// normal 1-RTT handshake, the client will send a client hello, CHLO, message.
-// The server will receive this message and respond with a server hello message,
-// SHLO.  At this point both sides will have established a crypto context they
-// can use to send encrypted messages.
-//
-// For more details:
-// https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
-class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
- public:
-  explicit QuicCryptoStream(QuicSession* session);
-  QuicCryptoStream(const QuicCryptoStream&) = delete;
-  QuicCryptoStream& operator=(const QuicCryptoStream&) = delete;
-
-  ~QuicCryptoStream() override;
-
-  // Returns the per-packet framing overhead associated with sending a
-  // handshake message for |version|.
-  static QuicByteCount CryptoMessageFramingOverhead(
-      QuicTransportVersion version,
-      QuicConnectionId connection_id);
-
-  // QuicStream implementation
-  void OnStreamFrame(const QuicStreamFrame& frame) override;
-  void OnDataAvailable() override;
-
-  // Called when a CRYPTO frame is received.
-  void OnCryptoFrame(const QuicCryptoFrame& frame);
-
-  // Called when a CRYPTO frame is ACKed.
-  bool OnCryptoFrameAcked(const QuicCryptoFrame& frame,
-                          QuicTime::Delta ack_delay_time);
-
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
-  // Performs key extraction to derive a new secret of |result_len| bytes
-  // dependent on |label|, |context|, and the stream's negotiated subkey secret.
-  // Returns false if the handshake has not been confirmed or the parameters are
-  // invalid (e.g. |label| contains null bytes); returns true on success. This
-  // method is only supported for IETF QUIC and MUST NOT be called in gQUIC as
-  // that'll trigger an assert in DEBUG build.
-  virtual bool ExportKeyingMaterial(absl::string_view label,
-                                    absl::string_view context,
-                                    size_t result_len, std::string* result) = 0;
-
-  // Writes |data| to the QuicStream at level |level|.
-  virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data);
-
-  // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
-  // rejected. Note that the value returned by this function may vary during the
-  // handshake. Once |one_rtt_keys_available| returns true, the value returned
-  // by this function will not change for the rest of the lifetime of the
-  // QuicCryptoStream.
-  virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
-
-  // Returns true once an encrypter has been set for the connection.
-  virtual bool encryption_established() const = 0;
-
-  // Returns true once the crypto handshake has completed.
-  virtual bool one_rtt_keys_available() const = 0;
-
-  // Returns the parameters negotiated in the crypto handshake.
-  virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const = 0;
-
-  // Provides the message parser to use when data is received on this stream.
-  virtual CryptoMessageParser* crypto_message_parser() = 0;
-
-  // Called when a packet of encryption |level| has been successfully decrypted.
-  virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
-
-  // Called when a 1RTT packet has been acknowledged.
-  virtual void OnOneRttPacketAcknowledged() = 0;
-
-  // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
-  virtual void OnHandshakePacketSent() = 0;
-
-  // Called when a handshake done frame has been received.
-  virtual void OnHandshakeDoneReceived() = 0;
-
-  // Called when a new token frame has been received.
-  virtual void OnNewTokenReceived(absl::string_view token) = 0;
-
-  // Called to get an address token.
-  virtual std::string GetAddressToken(
-      const CachedNetworkParameters* cached_network_params) const = 0;
-
-  // Called to validate |token|.
-  virtual bool ValidateAddressToken(absl::string_view token) const = 0;
-
-  // Get the last CachedNetworkParameters received from a valid address token.
-  virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
-      const = 0;
-
-  // Set the CachedNetworkParameters that will be returned by
-  // PreviousCachedNetworkParams.
-  // TODO(wub): This function is test only, move it to a test only library.
-  virtual void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters cached_network_params) = 0;
-
-  // Returns current handshake state.
-  virtual HandshakeState GetHandshakeState() const = 0;
-
-  // Called to provide the server-side application state that must be checked
-  // when performing a 0-RTT TLS resumption.
-  //
-  // On a client, this may be called at any time; 0-RTT tickets will not be
-  // cached until this function is called. When a 0-RTT resumption is attempted,
-  // QuicSession::SetApplicationState will be called with the state provided by
-  // a call to this function on a previous connection.
-  //
-  // On a server, this function must be called before commencing the handshake,
-  // otherwise 0-RTT tickets will not be issued. On subsequent connections,
-  // 0-RTT will be rejected if the data passed into this function does not match
-  // the data passed in on the connection where the 0-RTT ticket was issued.
-  virtual void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> state) = 0;
-
-  // Returns the maximum number of bytes that can be buffered at a particular
-  // encryption level |level|.
-  virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
-
-  // Called to generate a decrypter for the next key phase. Each call should
-  // generate the key for phase n+1.
-  virtual std::unique_ptr<QuicDecrypter>
-  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
-  // Called to generate an encrypter for the same key phase of the last
-  // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
-  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-
-  // Return the SSL struct object created by BoringSSL if the stream is using
-  // TLS1.3. Otherwise, return nullptr.
-  // This method is used in Envoy.
-  virtual SSL* GetSsl() const = 0;
-
-  // Called to cancel retransmission of unencrypted crypto stream data.
-  void NeuterUnencryptedStreamData();
-
-  // Called to cancel retransmission of data of encryption |level|.
-  void NeuterStreamDataOfEncryptionLevel(EncryptionLevel level);
-
-  // Override to record the encryption level of consumed data.
-  void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
-
-  // Returns whether there are any bytes pending retransmission in CRYPTO
-  // frames.
-  virtual bool HasPendingCryptoRetransmission() const;
-
-  // Writes any pending CRYPTO frame retransmissions.
-  void WritePendingCryptoRetransmission();
-
-  // Override to retransmit lost crypto data with the appropriate encryption
-  // level.
-  void WritePendingRetransmission() override;
-
-  // Override to send unacked crypto data with the appropriate encryption level.
-  bool RetransmitStreamData(QuicStreamOffset offset,
-                            QuicByteCount data_length,
-                            bool fin,
-                            TransmissionType type) override;
-
-  // Sends stream retransmission data at |encryption_level|.
-  QuicConsumedData RetransmitStreamDataAtLevel(
-      QuicStreamOffset retransmission_offset,
-      QuicByteCount retransmission_length,
-      EncryptionLevel encryption_level,
-      TransmissionType type);
-
-  // Returns the number of bytes of handshake data that have been received from
-  // the peer in either CRYPTO or STREAM frames.
-  uint64_t crypto_bytes_read() const;
-
-  // Returns the number of bytes of handshake data that have been received from
-  // the peer in CRYPTO frames at a particular encryption level.
-  QuicByteCount BytesReadOnLevel(EncryptionLevel level) const;
-
-  // Writes |data_length| of data of a crypto frame to |writer|. The data
-  // written is from the send buffer for encryption level |level| and starts at
-  // |offset|.
-  bool WriteCryptoFrame(EncryptionLevel level,
-                        QuicStreamOffset offset,
-                        QuicByteCount data_length,
-                        QuicDataWriter* writer);
-
-  // Called when data from a CRYPTO frame is considered lost. The lost data is
-  // identified by the encryption level, offset, and length in |crypto_frame|.
-  void OnCryptoFrameLost(QuicCryptoFrame* crypto_frame);
-
-  // Called to retransmit any outstanding data in the range indicated by the
-  // encryption level, offset, and length in |crypto_frame|. Returns true if all
-  // data gets retransmitted.
-  bool RetransmitData(QuicCryptoFrame* crypto_frame, TransmissionType type);
-
-  // Called to write buffered crypto frames.
-  void WriteBufferedCryptoFrames();
-
-  // Returns true if there is buffered crypto frames.
-  bool HasBufferedCryptoFrames() const;
-
-  // Returns true if any portion of the data at encryption level |level|
-  // starting at |offset| for |length| bytes is outstanding.
-  bool IsFrameOutstanding(EncryptionLevel level,
-                          size_t offset,
-                          size_t length) const;
-
-  // Returns true if the crypto handshake is still waiting for acks of sent
-  // data, and false if all data has been acked.
-  bool IsWaitingForAcks() const;
-
-  // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
-  // with the data available in |sequencer| and |level|, and marks the data
-  // passed to ProcessInput as consumed.
-  virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
-                                          EncryptionLevel level);
-
-  QuicStreamSequencer* GetStreamSequencerForLevel(EncryptionLevel level) {
-    return &substreams_[level].sequencer;
-  }
-
- private:
-  // Data sent and received in CRYPTO frames is sent at multiple encryption
-  // levels. Some of the state for the single logical crypto stream is split
-  // across encryption levels, and a CryptoSubstream is used to manage that
-  // state for a particular encryption level.
-  struct QUIC_EXPORT_PRIVATE CryptoSubstream {
-    CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
-
-    QuicStreamSequencer sequencer;
-    QuicStreamSendBuffer send_buffer;
-  };
-
-  // Consumed data according to encryption levels.
-  // TODO(fayang): This is not needed once switching from QUIC crypto to
-  // TLS 1.3, which never encrypts crypto data.
-  QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
-
-  // Keeps state for data sent/received in CRYPTO frames at each encryption
-  // level.
-  std::array<CryptoSubstream, NUM_ENCRYPTION_LEVELS> substreams_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
diff --git a/quic/core/quic_crypto_stream_test.cc b/quic/core/quic_crypto_stream_test.cc
deleted file mode 100644
index 3760c7d..0000000
--- a/quic/core/quic_crypto_stream_test.cc
+++ /dev/null
@@ -1,722 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_crypto_stream.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::Return;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicCryptoStream : public QuicCryptoStream,
-                             public QuicCryptoHandshaker {
- public:
-  explicit MockQuicCryptoStream(QuicSession* session)
-      : QuicCryptoStream(session),
-        QuicCryptoHandshaker(this, session),
-        params_(new QuicCryptoNegotiatedParameters) {}
-  MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
-  MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
-    messages_.push_back(message);
-  }
-
-  std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }
-
-  ssl_early_data_reason_t EarlyDataReason() const override {
-    return ssl_early_data_unknown;
-  }
-  bool encryption_established() const override { return false; }
-  bool one_rtt_keys_available() const override { return false; }
-
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override {
-    return *params_;
-  }
-  CryptoMessageParser* crypto_message_parser() override {
-    return QuicCryptoHandshaker::crypto_message_parser();
-  }
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnHandshakeDoneReceived() override {}
-  void OnNewTokenReceived(absl::string_view /*token*/) override {}
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_parameters*/)
-      const override {
-    return "";
-  }
-  bool ValidateAddressToken(absl::string_view /*token*/) const override {
-    return true;
-  }
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
-    return nullptr;
-  }
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters /*cached_network_params*/) override {}
-  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    return false;
-  }
-  SSL* GetSsl() const override { return nullptr; }
-
- private:
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-  std::vector<CryptoHandshakeMessage> messages_;
-};
-
-class QuicCryptoStreamTest : public QuicTest {
- public:
-  QuicCryptoStreamTest()
-      : connection_(new MockQuicConnection(&helper_,
-                                           &alarm_factory_,
-                                           Perspective::IS_CLIENT)),
-        session_(connection_, /*create_mock_crypto_stream=*/false) {
-    EXPECT_CALL(*static_cast<MockPacketWriter*>(connection_->writer()),
-                WritePacket(_, _, _, _, _))
-        .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
-    stream_ = new MockQuicCryptoStream(&session_);
-    session_.SetCryptoStream(stream_);
-    session_.Initialize();
-    message_.set_tag(kSHLO);
-    message_.SetStringPiece(1, "abc");
-    message_.SetStringPiece(2, "def");
-    ConstructHandshakeMessage();
-  }
-  QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
-  QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;
-
-  void ConstructHandshakeMessage() {
-    CryptoFramer framer;
-    message_data_ = framer.ConstructHandshakeMessage(message_);
-  }
-
- protected:
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnection* connection_;
-  MockQuicSpdySession session_;
-  MockQuicCryptoStream* stream_;
-  CryptoHandshakeMessage message_;
-  std::unique_ptr<QuicData> message_data_;
-};
-
-TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
-  EXPECT_FALSE(stream_->encryption_established());
-  EXPECT_FALSE(stream_->one_rtt_keys_available());
-}
-
-TEST_F(QuicCryptoStreamTest, ProcessRawData) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    stream_->OnStreamFrame(QuicStreamFrame(
-        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-        /*fin=*/false,
-        /*offset=*/0, message_data_->AsStringPiece()));
-  } else {
-    stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
-                                           message_data_->AsStringPiece()));
-  }
-  ASSERT_EQ(1u, stream_->messages()->size());
-  const CryptoHandshakeMessage& message = (*stream_->messages())[0];
-  EXPECT_EQ(kSHLO, message.tag());
-  EXPECT_EQ(2u, message.tag_value_map().size());
-  EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
-  EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
-}
-
-TEST_F(QuicCryptoStreamTest, ProcessBadData) {
-  std::string bad(message_data_->data(), message_data_->length());
-  const int kFirstTagIndex = sizeof(uint32_t) +  // message tag
-                             sizeof(uint16_t) +  // number of tag-value pairs
-                             sizeof(uint16_t);   // padding
-  EXPECT_EQ(1, bad[kFirstTagIndex]);
-  bad[kFirstTagIndex] = 0x7F;  // out of order tag
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
-                                            testing::_, testing::_));
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    stream_->OnStreamFrame(QuicStreamFrame(
-        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-        /*fin=*/false, /*offset=*/0, bad));
-  } else {
-    stream_->OnCryptoFrame(
-        QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
-  }
-}
-
-TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
-  EXPECT_FALSE(
-      QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  InSequence s;
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 0, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 1350, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Lost [0, 1000).
-  stream_->OnStreamFrameLost(0, 1000, false);
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-  // Lost [1200, 2000).
-  stream_->OnStreamFrameLost(1200, 800, false);
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1000, 0, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
-  // they are in different encryption levels.
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 150, 1200, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 650, 1350, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->OnCanWrite();
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-  // Verify connection's encryption level has restored.
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  InSequence s;
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
-  std::unique_ptr<NullEncrypter> encrypter =
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
-  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-  connection_->SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Lost [0, 1000).
-  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-  // Lost [1200, 2000).
-  lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
-  // they are in different encryption levels.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WritePendingCryptoRetransmission();
-  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-  // Verify connection's encryption level has restored.
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-}
-
-// Regression test for handling the missing ENCRYPTION_HANDSHAKE in
-// quic_crypto_stream.cc. This test is essentially the same as
-// RetransmitCryptoDataInCryptoFrames, except it uses ENCRYPTION_HANDSHAKE in
-// place of ENCRYPTION_ZERO_RTT.
-TEST_F(QuicCryptoStreamTest, RetransmitEncryptionHandshakeLevelCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  InSequence s;
-  // Send [0, 1000) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1000, 'a');
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  // Send [1000, 2000) in ENCRYPTION_HANDSHAKE.
-  std::unique_ptr<NullEncrypter> encrypter =
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
-  connection_->SetEncrypter(ENCRYPTION_HANDSHAKE, std::move(encrypter));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  EXPECT_EQ(ENCRYPTION_HANDSHAKE, connection_->encryption_level());
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 1000, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_HANDSHAKE, data);
-  connection_->SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Lost [1000, 1200).
-  QuicCryptoFrame lost_frame(ENCRYPTION_HANDSHAKE, 0, 200);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-  // Verify [1000, 1200) is sent.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 200, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WritePendingCryptoRetransmission();
-  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-}
-
-TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 0, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 1350, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-
-  // Lost [0, 1350).
-  stream_->OnStreamFrameLost(0, 1350, false);
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-  // Neuters [0, 1350).
-  stream_->NeuterUnencryptedStreamData();
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-  // Lost [0, 1350) again.
-  stream_->OnStreamFrameLost(0, 1350, false);
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-
-  // Lost [1350, 2000).
-  stream_->OnStreamFrameLost(1350, 650, false);
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-  stream_->NeuterUnencryptedStreamData();
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-}
-
-TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
-  connection_->SetEncrypter(
-      ENCRYPTION_ZERO_RTT,
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  std::unique_ptr<NullEncrypter> encrypter =
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
-  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-
-  // Lost [0, 1350).
-  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-  // Neuters [0, 1350).
-  stream_->NeuterUnencryptedStreamData();
-  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-  // Lost [0, 1350) again.
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-
-  // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
-  // level.
-  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-  stream_->NeuterUnencryptedStreamData();
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  InSequence s;
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 0, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 1350, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Ack [2000, 2500).
-  QuicByteCount newly_acked_length = 0;
-  stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
-                              QuicTime::Zero(), &newly_acked_length);
-  EXPECT_EQ(500u, newly_acked_length);
-
-  // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 650, 1350, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_.ConsumeData(
-            QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
-            1350, NO_FIN, HANDSHAKE_RETRANSMISSION, absl::nullopt);
-      }));
-
-  EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false,
-                                             HANDSHAKE_RETRANSMISSION));
-  // Verify connection's encryption level has restored.
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Force session to send [1350, 1500) again and all data is consumed.
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 650, 1350, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 200, 2500, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false,
-                                            HANDSHAKE_RETRANSMISSION));
-  // Verify connection's encryption level has restored.
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
-  // Force to send an empty frame.
-  EXPECT_TRUE(
-      stream_->RetransmitStreamData(0, 0, false, HANDSHAKE_RETRANSMISSION));
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  InSequence s;
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
-  std::unique_ptr<NullEncrypter> encrypter =
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
-  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-  connection_->SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Ack [2000, 2500).
-  QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
-  EXPECT_TRUE(
-      stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
-
-  // Retransmit only [1350, 1500).
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
-  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
-
-  // Verify connection's encryption level has restored.
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  // Retransmit [1350, 2700) again and all data is sent.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
-  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
-  // Verify connection's encryption level has restored.
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
-
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  // Force to send an empty frame.
-  QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
-  stream_->RetransmitData(&empty_frame, HANDSHAKE_RETRANSMISSION);
-}
-
-// Regression test for b/115926584.
-TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  std::string data(1350, 'a');
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 0, _, _, _))
-      .WillOnce(testing::Return(QuicConsumedData(0, false)));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  // Although there is no outstanding data, verify session has pending crypto
-  // data.
-  EXPECT_TRUE(session_.HasUnackedCryptoData());
-
-  EXPECT_CALL(
-      session_,
-      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-                 1350, 0, _, _, _))
-      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
-  stream_->OnCanWrite();
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_.HasUnackedCryptoData());
-}
-
-TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_.HasUnackedCryptoData());
-}
-
-// Regression test for bugfix of GetPacketHeaderSize.
-TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
-  for (const ParsedQuicVersion& version :
-       AllSupportedVersionsWithQuicCrypto()) {
-    SCOPED_TRACE(version);
-    QuicByteCount expected_overhead = 48;
-    if (version.HasIetfInvariantHeader()) {
-      expected_overhead += 4;
-    }
-    if (version.HasLongHeaderLengths()) {
-      expected_overhead += 3;
-    }
-    if (version.HasLengthPrefixedConnectionIds()) {
-      expected_overhead += 1;
-    }
-    EXPECT_EQ(expected_overhead,
-              QuicCryptoStream::CryptoMessageFramingOverhead(
-                  version.transport_version, TestConnectionId()));
-  }
-}
-
-TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
-  InSequence s;
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  // Only consumed 1000 bytes.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Return(1000));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
-
-  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
-  // because there is buffered data.
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  connection_->SetEncrypter(
-      ENCRYPTION_ZERO_RTT,
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
-      .WillOnce(Return(350));
-  // Partial write of ENCRYPTION_ZERO_RTT data.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
-      .WillOnce(Return(1000));
-  stream_->WriteBufferedCryptoFrames();
-  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
-  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
-
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
-      .WillOnce(Return(350));
-  stream_->WriteBufferedCryptoFrames();
-  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
-}
-
-TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
-                          'a');
-
-  // Set offset to 1 so that we guarantee the data gets buffered instead of
-  // immediately processed.
-  QuicStreamOffset offset = 1;
-  stream_->OnCryptoFrame(
-      QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
-}
-
-TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  InSequence s;
-  // Send [0, 1350) in ENCRYPTION_INITIAL.
-  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
-  std::string data(1350, 'a');
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
-
-  // Lost [0, 1000).
-  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
-  stream_->OnCryptoFrameLost(&lost_frame);
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-  // Simulate connection is constrained by amplification restriction.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
-      .WillOnce(Return(0));
-  stream_->WritePendingCryptoRetransmission();
-  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
-  // Connection gets unblocked.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
-      .WillOnce(Invoke(connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  stream_->WritePendingCryptoRetransmission();
-  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
-}
-
-// Regression test for b/203199510
-TEST_F(QuicCryptoStreamTest, EmptyCryptoFrame) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  QuicCryptoFrame empty_crypto_frame(ENCRYPTION_INITIAL, 0, nullptr, 0);
-  stream_->OnCryptoFrame(empty_crypto_frame);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_data_reader.cc b/quic/core/quic_data_reader.cc
deleted file mode 100644
index 7b605d3..0000000
--- a/quic/core/quic_data_reader.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_data_reader.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-QuicDataReader::QuicDataReader(absl::string_view data)
-    : quiche::QuicheDataReader(data) {}
-
-QuicDataReader::QuicDataReader(const char* data, const size_t len)
-    : QuicDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
-
-QuicDataReader::QuicDataReader(const char* data,
-                               const size_t len,
-                               quiche::Endianness endianness)
-    : quiche::QuicheDataReader(data, len, endianness) {}
-
-bool QuicDataReader::ReadUFloat16(uint64_t* result) {
-  uint16_t value;
-  if (!ReadUInt16(&value)) {
-    return false;
-  }
-
-  *result = value;
-  if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
-    // Fast path: either the value is denormalized (no hidden bit), or
-    // normalized (hidden bit set, exponent offset by one) with exponent zero.
-    // Zero exponent offset by one sets the bit exactly where the hidden bit is.
-    // So in both cases the value encodes itself.
-    return true;
-  }
-
-  uint16_t exponent =
-      value >> kUFloat16MantissaBits;  // No sign extend on uint!
-  // After the fast pass, the exponent is at least one (offset by one).
-  // Un-offset the exponent.
-  --exponent;
-  QUICHE_DCHECK_GE(exponent, 1);
-  QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
-  // Here we need to clear the exponent and set the hidden bit. We have already
-  // decremented the exponent, so when we subtract it, it leaves behind the
-  // hidden bit.
-  *result -= exponent << kUFloat16MantissaBits;
-  *result <<= exponent;
-  QUICHE_DCHECK_GE(*result,
-                   static_cast<uint64_t>(1 << kUFloat16MantissaEffectiveBits));
-  QUICHE_DCHECK_LE(*result, kUFloat16MaxValue);
-  return true;
-}
-
-bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id,
-                                      uint8_t length) {
-  if (length == 0) {
-    connection_id->set_length(0);
-    return true;
-  }
-
-  if (BytesRemaining() < length) {
-    return false;
-  }
-
-  connection_id->set_length(length);
-  const bool ok =
-      ReadBytes(connection_id->mutable_data(), connection_id->length());
-  QUICHE_DCHECK(ok);
-  return ok;
-}
-
-bool QuicDataReader::ReadLengthPrefixedConnectionId(
-    QuicConnectionId* connection_id) {
-  uint8_t connection_id_length;
-  if (!ReadUInt8(&connection_id_length)) {
-    return false;
-  }
-  return ReadConnectionId(connection_id, connection_id_length);
-}
-
-QuicVariableLengthIntegerLength QuicDataReader::PeekVarInt62Length() {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-  const unsigned char* next =
-      reinterpret_cast<const unsigned char*>(data() + pos());
-  if (BytesRemaining() == 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  }
-  return static_cast<QuicVariableLengthIntegerLength>(
-      1 << ((*next & 0b11000000) >> 6));
-}
-
-// Read an IETF/QUIC formatted 62-bit Variable Length Integer.
-//
-// Performance notes
-//
-// Measurements and experiments showed that unrolling the four cases
-// like this and dereferencing next_ as we do (*(next_+n) --- and then
-// doing a single pos_+=x at the end) gains about 10% over making a
-// loop and dereferencing next_ such as *(next_++)
-//
-// Using a register for pos_ was not helpful.
-//
-// Branches are ordered to increase the likelihood of the first being
-// taken.
-//
-// Low-level optimization is useful here because this function will be
-// called frequently, leading to outsize benefits.
-bool QuicDataReader::ReadVarInt62(uint64_t* result) {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
-  size_t remaining = BytesRemaining();
-  const unsigned char* next =
-      reinterpret_cast<const unsigned char*>(data() + pos());
-  if (remaining != 0) {
-    switch (*next & 0xc0) {
-      case 0xc0:
-        // Leading 0b11...... is 8 byte encoding
-        if (remaining >= 8) {
-          *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) +
-                    (static_cast<uint64_t>(*(next + 1)) << 48) +
-                    (static_cast<uint64_t>(*(next + 2)) << 40) +
-                    (static_cast<uint64_t>(*(next + 3)) << 32) +
-                    (static_cast<uint64_t>(*(next + 4)) << 24) +
-                    (static_cast<uint64_t>(*(next + 5)) << 16) +
-                    (static_cast<uint64_t>(*(next + 6)) << 8) +
-                    (static_cast<uint64_t>(*(next + 7)) << 0);
-          AdvancePos(8);
-          return true;
-        }
-        return false;
-
-      case 0x80:
-        // Leading 0b10...... is 4 byte encoding
-        if (remaining >= 4) {
-          *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) +
-                    (((*(next + 2)) << 8)) + (((*(next + 3)) << 0));
-          AdvancePos(4);
-          return true;
-        }
-        return false;
-
-      case 0x40:
-        // Leading 0b01...... is 2 byte encoding
-        if (remaining >= 2) {
-          *result = (((*(next)) & 0x3f) << 8) + (*(next + 1));
-          AdvancePos(2);
-          return true;
-        }
-        return false;
-
-      case 0x00:
-        // Leading 0b00...... is 1 byte encoding
-        *result = (*next) & 0x3f;
-        AdvancePos(1);
-        return true;
-    }
-  }
-  return false;
-}
-
-bool QuicDataReader::ReadStringPieceVarInt62(absl::string_view* result) {
-  uint64_t result_length;
-  if (!ReadVarInt62(&result_length)) {
-    return false;
-  }
-  return ReadStringPiece(result, result_length);
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_data_reader.h b/quic/core/quic_data_reader.h
deleted file mode 100644
index cca2241..0000000
--- a/quic/core/quic_data_reader.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
-#define QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_data_reader.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-// Used for reading QUIC data. Though there isn't really anything terribly
-// QUIC-specific here, it's a helper class that's useful when doing QUIC
-// framing.
-//
-// To use, simply construct a QuicDataReader using the underlying buffer that
-// you'd like to read fields from, then call one of the Read*() methods to
-// actually do some reading.
-//
-// This class keeps an internal iterator to keep track of what's already been
-// read and each successive Read*() call automatically increments said iterator
-// on success. On failure, internal state of the QuicDataReader should not be
-// trusted and it is up to the caller to throw away the failed instance and
-// handle the error as appropriate. None of the Read*() methods should ever be
-// called after failure, as they will also fail immediately.
-class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader {
- public:
-  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
-  // Caller must provide an underlying buffer to work on.
-  explicit QuicDataReader(absl::string_view data);
-  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
-  // Caller must provide an underlying buffer to work on.
-  QuicDataReader(const char* data, const size_t len);
-  // Constructs a reader using the specified endianness.
-  // Caller must provide an underlying buffer to work on.
-  QuicDataReader(const char* data,
-                 const size_t len,
-                 quiche::Endianness endianness);
-  QuicDataReader(const QuicDataReader&) = delete;
-  QuicDataReader& operator=(const QuicDataReader&) = delete;
-
-  // Empty destructor.
-  ~QuicDataReader() {}
-
-  // Reads a 16-bit unsigned float into the given output parameter.
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadUFloat16(uint64_t* result);
-
-  // Reads connection ID into the given output parameter.
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadConnectionId(QuicConnectionId* connection_id, uint8_t length);
-
-  // Reads 8-bit connection ID length followed by connection ID of that length.
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadLengthPrefixedConnectionId(QuicConnectionId* connection_id);
-
-  // Returns the length in bytes of a variable length integer based on the next
-  // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure.
-  QuicVariableLengthIntegerLength PeekVarInt62Length();
-
-  // Read an IETF-encoded Variable Length Integer and place the result
-  // in |*result|.
-  // Returns true if it works, false if not. The only error is that
-  // there is not enough in the buffer to read the number.
-  // If there is an error, |*result| is not altered.
-  // Numbers are encoded per the rules in draft-ietf-quic-transport-10.txt
-  // and that the integers in the range 0 ... (2^62)-1.
-  bool ReadVarInt62(uint64_t* result);
-
-  // Reads a string prefixed with a Variable Length integer length into the
-  // given output parameter.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadStringPieceVarInt62(absl::string_view* result);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
diff --git a/quic/core/quic_data_writer.cc b/quic/core/quic_data_writer.cc
deleted file mode 100644
index ee3c861..0000000
--- a/quic/core/quic_data_writer.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_data_writer.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-QuicDataWriter::QuicDataWriter(size_t size, char* buffer)
-    : quiche::QuicheDataWriter(size, buffer) {}
-
-QuicDataWriter::QuicDataWriter(size_t size,
-                               char* buffer,
-                               quiche::Endianness endianness)
-    : quiche::QuicheDataWriter(size, buffer, endianness) {}
-
-QuicDataWriter::~QuicDataWriter() {}
-
-bool QuicDataWriter::WriteUFloat16(uint64_t value) {
-  uint16_t result;
-  if (value < (UINT64_C(1) << kUFloat16MantissaEffectiveBits)) {
-    // Fast path: either the value is denormalized, or has exponent zero.
-    // Both cases are represented by the value itself.
-    result = static_cast<uint16_t>(value);
-  } else if (value >= kUFloat16MaxValue) {
-    // Value is out of range; clamp it to the maximum representable.
-    result = std::numeric_limits<uint16_t>::max();
-  } else {
-    // The highest bit is between position 13 and 42 (zero-based), which
-    // corresponds to exponent 1-30. In the output, mantissa is from 0 to 10,
-    // hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11
-    // and count the shifts.
-    uint16_t exponent = 0;
-    for (uint16_t offset = 16; offset > 0; offset /= 2) {
-      // Right-shift the value until the highest bit is in position 11.
-      // For offset of 16, 8, 4, 2 and 1 (binary search over 1-30),
-      // shift if the bit is at or above 11 + offset.
-      if (value >= (UINT64_C(1) << (kUFloat16MantissaBits + offset))) {
-        exponent += offset;
-        value >>= offset;
-      }
-    }
-
-    QUICHE_DCHECK_GE(exponent, 1);
-    QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
-    QUICHE_DCHECK_GE(value, UINT64_C(1) << kUFloat16MantissaBits);
-    QUICHE_DCHECK_LT(value, UINT64_C(1) << kUFloat16MantissaEffectiveBits);
-
-    // Hidden bit (position 11) is set. We should remove it and increment the
-    // exponent. Equivalently, we just add it to the exponent.
-    // This hides the bit.
-    result = static_cast<uint16_t>(value + (exponent << kUFloat16MantissaBits));
-  }
-
-  if (endianness() == quiche::NETWORK_BYTE_ORDER) {
-    result = quiche::QuicheEndian::HostToNet16(result);
-  }
-  return WriteBytes(&result, sizeof(result));
-}
-
-bool QuicDataWriter::WriteConnectionId(QuicConnectionId connection_id) {
-  if (connection_id.IsEmpty()) {
-    return true;
-  }
-  return WriteBytes(connection_id.data(), connection_id.length());
-}
-
-bool QuicDataWriter::WriteLengthPrefixedConnectionId(
-    QuicConnectionId connection_id) {
-  return WriteUInt8(connection_id.length()) && WriteConnectionId(connection_id);
-}
-
-bool QuicDataWriter::WriteRandomBytes(QuicRandom* random, size_t length) {
-  char* dest = BeginWrite(length);
-  if (!dest) {
-    return false;
-  }
-
-  random->RandBytes(dest, length);
-  IncreaseLength(length);
-  return true;
-}
-
-bool QuicDataWriter::WriteInsecureRandomBytes(QuicRandom* random,
-                                              size_t length) {
-  char* dest = BeginWrite(length);
-  if (!dest) {
-    return false;
-  }
-
-  random->InsecureRandBytes(dest, length);
-  IncreaseLength(length);
-  return true;
-}
-
-// Converts a uint64_t into an IETF/Quic formatted Variable Length
-// Integer. IETF Variable Length Integers have 62 significant bits, so
-// the value to write must be in the range of 0..(2^62)-1.
-//
-// Performance notes
-//
-// Measurements and experiments showed that unrolling the four cases
-// like this and dereferencing next_ as we do (*(next_+n)) gains about
-// 10% over making a loop and dereferencing it as *(next_++)
-//
-// Using a register for next didn't help.
-//
-// Branches are ordered to increase the likelihood of the first being
-// taken.
-//
-// Low-level optimization is useful here because this function will be
-// called frequently, leading to outsize benefits.
-bool QuicDataWriter::WriteVarInt62(uint64_t value) {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
-  size_t remaining_bytes = remaining();
-  char* next = buffer() + length();
-
-  if ((value & kVarInt62ErrorMask) == 0) {
-    // We know the high 2 bits are 0 so |value| is legal.
-    // We can do the encoding.
-    if ((value & kVarInt62Mask8Bytes) != 0) {
-      // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte
-      // encoding.
-      if (remaining_bytes >= 8) {
-        *(next + 0) = ((value >> 56) & 0x3f) + 0xc0;
-        *(next + 1) = (value >> 48) & 0xff;
-        *(next + 2) = (value >> 40) & 0xff;
-        *(next + 3) = (value >> 32) & 0xff;
-        *(next + 4) = (value >> 24) & 0xff;
-        *(next + 5) = (value >> 16) & 0xff;
-        *(next + 6) = (value >> 8) & 0xff;
-        *(next + 7) = value & 0xff;
-        IncreaseLength(8);
-        return true;
-      }
-      return false;
-    }
-    // The high-order-4 bytes are all 0, check for a 1, 2, or 4-byte
-    // encoding
-    if ((value & kVarInt62Mask4Bytes) != 0) {
-      // The encoding will not fit into 2 bytes, Do a 4-byte
-      // encoding.
-      if (remaining_bytes >= 4) {
-        *(next + 0) = ((value >> 24) & 0x3f) + 0x80;
-        *(next + 1) = (value >> 16) & 0xff;
-        *(next + 2) = (value >> 8) & 0xff;
-        *(next + 3) = value & 0xff;
-        IncreaseLength(4);
-        return true;
-      }
-      return false;
-    }
-    // The high-order bits are all 0. Check to see if the number
-    // can be encoded as one or two bytes. One byte encoding has
-    // only 6 significant bits (bits 0xffffffff ffffffc0 are all 0).
-    // Two byte encoding has more than 6, but 14 or less significant
-    // bits (bits 0xffffffff ffffc000 are 0 and 0x00000000 00003fc0
-    // are not 0)
-    if ((value & kVarInt62Mask2Bytes) != 0) {
-      // Do 2-byte encoding
-      if (remaining_bytes >= 2) {
-        *(next + 0) = ((value >> 8) & 0x3f) + 0x40;
-        *(next + 1) = (value)&0xff;
-        IncreaseLength(2);
-        return true;
-      }
-      return false;
-    }
-    if (remaining_bytes >= 1) {
-      // Do 1-byte encoding
-      *next = (value & 0x3f);
-      IncreaseLength(1);
-      return true;
-    }
-    return false;
-  }
-  // Can not encode, high 2 bits not 0
-  return false;
-}
-
-bool QuicDataWriter::WriteVarInt62(
-    uint64_t value,
-    QuicVariableLengthIntegerLength write_length) {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
-  size_t remaining_bytes = remaining();
-  if (remaining_bytes < write_length) {
-    return false;
-  }
-
-  const QuicVariableLengthIntegerLength min_length = GetVarInt62Len(value);
-  if (write_length < min_length) {
-    QUIC_BUG(quic_bug_10347_1) << "Cannot write value " << value
-                               << " with write_length " << write_length;
-    return false;
-  }
-  if (write_length == min_length) {
-    return WriteVarInt62(value);
-  }
-
-  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_2) {
-    return WriteUInt8(0b01000000) && WriteUInt8(value);
-  }
-  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_4) {
-    return WriteUInt8(0b10000000) && WriteUInt8(0) && WriteUInt16(value);
-  }
-  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_8) {
-    return WriteUInt8(0b11000000) && WriteUInt8(0) && WriteUInt16(0) &&
-           WriteUInt32(value);
-  }
-
-  QUIC_BUG(quic_bug_10347_2)
-      << "Invalid write_length " << static_cast<int>(write_length);
-  return false;
-}
-
-// static
-QuicVariableLengthIntegerLength QuicDataWriter::GetVarInt62Len(uint64_t value) {
-  if ((value & kVarInt62ErrorMask) != 0) {
-    QUIC_BUG(quic_bug_10347_3) << "Attempted to encode a value, " << value
-                               << ", that is too big for VarInt62";
-    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  }
-  if ((value & kVarInt62Mask8Bytes) != 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_8;
-  }
-  if ((value & kVarInt62Mask4Bytes) != 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_4;
-  }
-  if ((value & kVarInt62Mask2Bytes) != 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-  return VARIABLE_LENGTH_INTEGER_LENGTH_1;
-}
-
-bool QuicDataWriter::WriteStringPieceVarInt62(
-    const absl::string_view& string_piece) {
-  if (!WriteVarInt62(string_piece.size())) {
-    return false;
-  }
-  if (!string_piece.empty()) {
-    if (!WriteBytes(string_piece.data(), string_piece.size())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_data_writer.h b/quic/core/quic_data_writer.h
deleted file mode 100644
index 2a23ce2..0000000
--- a/quic/core/quic_data_writer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
-#define QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_data_writer.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-class QuicRandom;
-
-// Maximum value that can be properly encoded using VarInt62 coding.
-const uint64_t kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff);
-
-// VarInt62 encoding masks
-// If a uint64_t anded with a mask is not 0 then the value is encoded
-// using that length (or is too big, in the case of kVarInt62ErrorMask).
-// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
-// and if none are non-0, the value is encoded in 1 byte.
-const uint64_t kVarInt62ErrorMask = UINT64_C(0xc000000000000000);
-const uint64_t kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000);
-const uint64_t kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000);
-const uint64_t kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0);
-
-// This class provides facilities for packing QUIC data.
-//
-// The QuicDataWriter supports appending primitive values (int, string, etc)
-// to a frame instance.  The internal memory buffer is exposed as the "data"
-// of the QuicDataWriter.
-class QUIC_EXPORT_PRIVATE QuicDataWriter : public quiche::QuicheDataWriter {
- public:
-  // Creates a QuicDataWriter where |buffer| is not owned
-  // using NETWORK_BYTE_ORDER endianness.
-  QuicDataWriter(size_t size, char* buffer);
-  // Creates a QuicDataWriter where |buffer| is not owned
-  // using the specified endianness.
-  QuicDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
-  QuicDataWriter(const QuicDataWriter&) = delete;
-  QuicDataWriter& operator=(const QuicDataWriter&) = delete;
-
-  ~QuicDataWriter();
-
-  // Methods for adding to the payload.  These values are appended to the end
-  // of the QuicDataWriter payload.
-
-  // Write an unsigned-integer value per the IETF QUIC/Variable Length
-  // Integer encoding rules (see draft-ietf-quic-transport-08.txt).
-  // IETF Variable Length Integers have 62 significant bits, so the
-  // value to write must be in the range of 0...(2^62)-1. Returns
-  // false if the value is out of range or if there is no room in the
-  // buffer.
-  bool WriteVarInt62(uint64_t value);
-
-  // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
-  // This is not as optimized as WriteVarInt62(uint64_t).
-  // Returns false if the value does not fit in the specified write_length or if
-  // there is no room in the buffer.
-  bool WriteVarInt62(uint64_t value,
-                     QuicVariableLengthIntegerLength write_length);
-
-  // Writes a string piece as a consecutive length/content pair. The
-  // length is VarInt62 encoded.
-  bool WriteStringPieceVarInt62(const absl::string_view& string_piece);
-
-  // Utility function to return the number of bytes needed to encode
-  // the given value using IETF VarInt62 encoding. Returns the number
-  // of bytes required to encode the given integer or 0 if the value
-  // is too large to encode.
-  static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value);
-
-  // Write unsigned floating point corresponding to the value. Large values are
-  // clamped to the maximum representable (kUFloat16MaxValue). Values that can
-  // not be represented directly are rounded down.
-  bool WriteUFloat16(uint64_t value);
-  // Write connection ID to the payload.
-  bool WriteConnectionId(QuicConnectionId connection_id);
-
-  // Write 8-bit length followed by connection ID to the payload.
-  bool WriteLengthPrefixedConnectionId(QuicConnectionId connection_id);
-
-  // Write |length| random bytes generated by |random|.
-  bool WriteRandomBytes(QuicRandom* random, size_t length);
-
-  // Write |length| random bytes generated by |random|. This MUST NOT be used
-  // for any application that requires cryptographically-secure randomness.
-  bool WriteInsecureRandomBytes(QuicRandom* random, size_t length);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
diff --git a/quic/core/quic_data_writer_test.cc b/quic/core/quic_data_writer_test.cc
deleted file mode 100644
index cbe0351..0000000
--- a/quic/core/quic_data_writer_test.cc
+++ /dev/null
@@ -1,1281 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_data_writer.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_endian.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-char* AsChars(unsigned char* data) {
-  return reinterpret_cast<char*>(data);
-}
-
-struct TestParams {
-  explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
-
-  quiche::Endianness endianness;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
-      "ByteOrder");
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (quiche::Endianness endianness :
-       {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
-    params.push_back(TestParams(endianness));
-  }
-  return params;
-}
-
-class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
-
-INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
-                         QuicDataWriterTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
-  // Check the arithmetic on the constants - otherwise the values below make
-  // no sense.
-  EXPECT_EQ(30, kUFloat16MaxExponent);
-  EXPECT_EQ(11, kUFloat16MantissaBits);
-  EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
-  EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
-}
-
-TEST_P(QuicDataWriterTest, WriteUFloat16) {
-  struct TestCase {
-    uint64_t decoded;
-    uint16_t encoded;
-  };
-  TestCase test_cases[] = {
-      // Small numbers represent themselves.
-      {0, 0},
-      {1, 1},
-      {2, 2},
-      {3, 3},
-      {4, 4},
-      {5, 5},
-      {6, 6},
-      {7, 7},
-      {15, 15},
-      {31, 31},
-      {42, 42},
-      {123, 123},
-      {1234, 1234},
-      // Check transition through 2^11.
-      {2046, 2046},
-      {2047, 2047},
-      {2048, 2048},
-      {2049, 2049},
-      // Running out of mantissa at 2^12.
-      {4094, 4094},
-      {4095, 4095},
-      {4096, 4096},
-      {4097, 4096},
-      {4098, 4097},
-      {4099, 4097},
-      {4100, 4098},
-      {4101, 4098},
-      // Check transition through 2^13.
-      {8190, 6143},
-      {8191, 6143},
-      {8192, 6144},
-      {8193, 6144},
-      {8194, 6144},
-      {8195, 6144},
-      {8196, 6145},
-      {8197, 6145},
-      // Half-way through the exponents.
-      {0x7FF8000, 0x87FF},
-      {0x7FFFFFF, 0x87FF},
-      {0x8000000, 0x8800},
-      {0xFFF0000, 0x8FFF},
-      {0xFFFFFFF, 0x8FFF},
-      {0x10000000, 0x9000},
-      // Transition into the largest exponent.
-      {0x1FFFFFFFFFE, 0xF7FF},
-      {0x1FFFFFFFFFF, 0xF7FF},
-      {0x20000000000, 0xF800},
-      {0x20000000001, 0xF800},
-      {0x2003FFFFFFE, 0xF800},
-      {0x2003FFFFFFF, 0xF800},
-      {0x20040000000, 0xF801},
-      {0x20040000001, 0xF801},
-      // Transition into the max value and clamping.
-      {0x3FF80000000, 0xFFFE},
-      {0x3FFBFFFFFFF, 0xFFFE},
-      {0x3FFC0000000, 0xFFFF},
-      {0x3FFC0000001, 0xFFFF},
-      {0x3FFFFFFFFFF, 0xFFFF},
-      {0x40000000000, 0xFFFF},
-      {0xFFFFFFFFFFFFFFFF, 0xFFFF},
-  };
-  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
-
-  for (int i = 0; i < num_test_cases; ++i) {
-    char buffer[2];
-    QuicDataWriter writer(2, buffer, GetParam().endianness);
-    EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
-    uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
-    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
-      result = quiche::QuicheEndian::HostToNet16(result);
-    }
-    EXPECT_EQ(test_cases[i].encoded, result);
-  }
-}
-
-TEST_P(QuicDataWriterTest, ReadUFloat16) {
-  struct TestCase {
-    uint64_t decoded;
-    uint16_t encoded;
-  };
-  TestCase test_cases[] = {
-      // There are fewer decoding test cases because encoding truncates, and
-      // decoding returns the smallest expansion.
-      // Small numbers represent themselves.
-      {0, 0},
-      {1, 1},
-      {2, 2},
-      {3, 3},
-      {4, 4},
-      {5, 5},
-      {6, 6},
-      {7, 7},
-      {15, 15},
-      {31, 31},
-      {42, 42},
-      {123, 123},
-      {1234, 1234},
-      // Check transition through 2^11.
-      {2046, 2046},
-      {2047, 2047},
-      {2048, 2048},
-      {2049, 2049},
-      // Running out of mantissa at 2^12.
-      {4094, 4094},
-      {4095, 4095},
-      {4096, 4096},
-      {4098, 4097},
-      {4100, 4098},
-      // Check transition through 2^13.
-      {8190, 6143},
-      {8192, 6144},
-      {8196, 6145},
-      // Half-way through the exponents.
-      {0x7FF8000, 0x87FF},
-      {0x8000000, 0x8800},
-      {0xFFF0000, 0x8FFF},
-      {0x10000000, 0x9000},
-      // Transition into the largest exponent.
-      {0x1FFE0000000, 0xF7FF},
-      {0x20000000000, 0xF800},
-      {0x20040000000, 0xF801},
-      // Transition into the max value.
-      {0x3FF80000000, 0xFFFE},
-      {0x3FFC0000000, 0xFFFF},
-  };
-  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
-
-  for (int i = 0; i < num_test_cases; ++i) {
-    uint16_t encoded_ufloat = test_cases[i].encoded;
-    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
-      encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
-    }
-    QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
-                          GetParam().endianness);
-    uint64_t value;
-    EXPECT_TRUE(reader.ReadUFloat16(&value));
-    EXPECT_EQ(test_cases[i].decoded, value);
-  }
-}
-
-TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
-  // Just test all 16-bit encoded values. 0 and max already tested above.
-  uint64_t previous_value = 0;
-  for (uint16_t i = 1; i < 0xFFFF; ++i) {
-    // Read the two bytes.
-    uint16_t read_number = i;
-    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
-      read_number = quiche::QuicheEndian::HostToNet16(read_number);
-    }
-    QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
-                          GetParam().endianness);
-    uint64_t value;
-    // All values must be decodable.
-    EXPECT_TRUE(reader.ReadUFloat16(&value));
-    // Check that small numbers represent themselves
-    if (i < 4097) {
-      EXPECT_EQ(i, value);
-    }
-    // Check there's monotonic growth.
-    EXPECT_LT(previous_value, value);
-    // Check that precision is within 0.5% away from the denormals.
-    if (i > 2000) {
-      EXPECT_GT(previous_value * 1005, value * 1000);
-    }
-    // Check we're always within the promised range.
-    EXPECT_LT(value, UINT64_C(0x3FFC0000000));
-    previous_value = value;
-    char buffer[6];
-    QuicDataWriter writer(6, buffer, GetParam().endianness);
-    EXPECT_TRUE(writer.WriteUFloat16(value - 1));
-    EXPECT_TRUE(writer.WriteUFloat16(value));
-    EXPECT_TRUE(writer.WriteUFloat16(value + 1));
-    // Check minimal decoding (previous decoding has previous encoding).
-    uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
-    uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
-    uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
-    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
-      encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
-      encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
-      encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
-    }
-    EXPECT_EQ(i - 1, encoded1);
-    // Check roundtrip.
-    EXPECT_EQ(i, encoded2);
-    // Check next decoding.
-    EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
-  }
-}
-
-TEST_P(QuicDataWriterTest, WriteConnectionId) {
-  QuicConnectionId connection_id =
-      TestConnectionId(UINT64_C(0x0011223344556677));
-  char big_endian[] = {
-      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-  };
-  EXPECT_EQ(connection_id.length(), ABSL_ARRAYSIZE(big_endian));
-  ASSERT_LE(connection_id.length(), 255);
-  char buffer[255];
-  QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
-  EXPECT_TRUE(writer.WriteConnectionId(connection_id));
-  quiche::test::CompareCharArraysWithHexError(
-      "connection_id", buffer, connection_id.length(), big_endian,
-      connection_id.length());
-
-  QuicConnectionId read_connection_id;
-  QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
-  EXPECT_TRUE(
-      reader.ReadConnectionId(&read_connection_id, ABSL_ARRAYSIZE(big_endian)));
-  EXPECT_EQ(connection_id, read_connection_id);
-}
-
-TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
-  QuicConnectionId connection_id =
-      TestConnectionId(UINT64_C(0x0011223344556677));
-  char length_prefixed_connection_id[] = {
-      0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-  };
-  EXPECT_EQ(ABSL_ARRAYSIZE(length_prefixed_connection_id),
-            kConnectionIdLengthSize + connection_id.length());
-  char buffer[kConnectionIdLengthSize + 255] = {};
-  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer);
-  EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
-  quiche::test::CompareCharArraysWithHexError(
-      "WriteLengthPrefixedConnectionId", buffer, writer.length(),
-      length_prefixed_connection_id,
-      ABSL_ARRAYSIZE(length_prefixed_connection_id));
-
-  // Verify that writing length then connection ID produces the same output.
-  memset(buffer, 0, ABSL_ARRAYSIZE(buffer));
-  QuicDataWriter writer2(ABSL_ARRAYSIZE(buffer), buffer);
-  EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
-  EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
-  quiche::test::CompareCharArraysWithHexError(
-      "Write length then ConnectionId", buffer, writer2.length(),
-      length_prefixed_connection_id,
-      ABSL_ARRAYSIZE(length_prefixed_connection_id));
-
-  QuicConnectionId read_connection_id;
-  QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer));
-  EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
-  EXPECT_EQ(connection_id, read_connection_id);
-
-  // Verify that reading length then connection ID produces the same output.
-  uint8_t read_connection_id_length2 = 33;
-  QuicConnectionId read_connection_id2;
-  QuicDataReader reader2(buffer, ABSL_ARRAYSIZE(buffer));
-  ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
-  EXPECT_EQ(connection_id.length(), read_connection_id_length2);
-  EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
-                                       read_connection_id_length2));
-  EXPECT_EQ(connection_id, read_connection_id2);
-}
-
-TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
-  QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
-  char buffer[2];
-  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
-  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
-  EXPECT_TRUE(writer.WriteUInt8(1));
-  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
-  EXPECT_TRUE(writer.WriteUInt8(2));
-  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
-  EXPECT_FALSE(writer.WriteUInt8(3));
-
-  EXPECT_EQ(buffer[0], 1);
-  EXPECT_EQ(buffer[1], 2);
-
-  QuicConnectionId read_connection_id = TestConnectionId();
-  uint8_t read_byte;
-  QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer), GetParam().endianness);
-  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
-  EXPECT_EQ(read_connection_id, empty_connection_id);
-  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
-  EXPECT_EQ(read_byte, 1);
-  // Reset read_connection_id to something else to verify that
-  // ReadConnectionId properly sets it back to empty.
-  read_connection_id = TestConnectionId();
-  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
-  EXPECT_EQ(read_connection_id, empty_connection_id);
-  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
-  EXPECT_EQ(read_byte, 2);
-  read_connection_id = TestConnectionId();
-  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
-  EXPECT_EQ(read_connection_id, empty_connection_id);
-  EXPECT_FALSE(reader.ReadUInt8(&read_byte));
-}
-
-TEST_P(QuicDataWriterTest, WriteTag) {
-  char CHLO[] = {
-      'C',
-      'H',
-      'L',
-      'O',
-  };
-  const int kBufferLength = sizeof(QuicTag);
-  char buffer[kBufferLength];
-  QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
-  writer.WriteTag(kCHLO);
-  quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
-                                              CHLO, kBufferLength);
-
-  QuicTag read_chlo;
-  QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
-  reader.ReadTag(&read_chlo);
-  EXPECT_EQ(kCHLO, read_chlo);
-}
-
-TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
-  char little_endian16[] = {0x22, 0x11};
-  char big_endian16[] = {0x11, 0x22};
-  char buffer16[2];
-  {
-    uint16_t in_memory16 = 0x1122;
-    QuicDataWriter writer(2, buffer16, GetParam().endianness);
-    writer.WriteUInt16(in_memory16);
-    quiche::test::CompareCharArraysWithHexError(
-        "uint16_t", buffer16, 2,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
-                                                            : little_endian16,
-        2);
-
-    uint16_t read_number16;
-    QuicDataReader reader(buffer16, 2, GetParam().endianness);
-    reader.ReadUInt16(&read_number16);
-    EXPECT_EQ(in_memory16, read_number16);
-  }
-
-  {
-    uint64_t in_memory16 = 0x0000000000001122;
-    QuicDataWriter writer(2, buffer16, GetParam().endianness);
-    writer.WriteBytesToUInt64(2, in_memory16);
-    quiche::test::CompareCharArraysWithHexError(
-        "uint16_t", buffer16, 2,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
-                                                            : little_endian16,
-        2);
-
-    uint64_t read_number16;
-    QuicDataReader reader(buffer16, 2, GetParam().endianness);
-    reader.ReadBytesToUInt64(2, &read_number16);
-    EXPECT_EQ(in_memory16, read_number16);
-  }
-}
-
-TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
-  char little_endian24[] = {0x33, 0x22, 0x11};
-  char big_endian24[] = {0x11, 0x22, 0x33};
-  char buffer24[3];
-  uint64_t in_memory24 = 0x0000000000112233;
-  QuicDataWriter writer(3, buffer24, GetParam().endianness);
-  writer.WriteBytesToUInt64(3, in_memory24);
-  quiche::test::CompareCharArraysWithHexError(
-      "uint24", buffer24, 3,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
-                                                          : little_endian24,
-      3);
-
-  uint64_t read_number24;
-  QuicDataReader reader(buffer24, 3, GetParam().endianness);
-  reader.ReadBytesToUInt64(3, &read_number24);
-  EXPECT_EQ(in_memory24, read_number24);
-}
-
-TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
-  char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
-  char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
-  char buffer32[4];
-  {
-    uint32_t in_memory32 = 0x11223344;
-    QuicDataWriter writer(4, buffer32, GetParam().endianness);
-    writer.WriteUInt32(in_memory32);
-    quiche::test::CompareCharArraysWithHexError(
-        "uint32_t", buffer32, 4,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
-                                                            : little_endian32,
-        4);
-
-    uint32_t read_number32;
-    QuicDataReader reader(buffer32, 4, GetParam().endianness);
-    reader.ReadUInt32(&read_number32);
-    EXPECT_EQ(in_memory32, read_number32);
-  }
-
-  {
-    uint64_t in_memory32 = 0x11223344;
-    QuicDataWriter writer(4, buffer32, GetParam().endianness);
-    writer.WriteBytesToUInt64(4, in_memory32);
-    quiche::test::CompareCharArraysWithHexError(
-        "uint32_t", buffer32, 4,
-        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
-                                                            : little_endian32,
-        4);
-
-    uint64_t read_number32;
-    QuicDataReader reader(buffer32, 4, GetParam().endianness);
-    reader.ReadBytesToUInt64(4, &read_number32);
-    EXPECT_EQ(in_memory32, read_number32);
-  }
-}
-
-TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
-  uint64_t in_memory40 = 0x0000001122334455;
-  char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
-  char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
-  char buffer40[5];
-  QuicDataWriter writer(5, buffer40, GetParam().endianness);
-  writer.WriteBytesToUInt64(5, in_memory40);
-  quiche::test::CompareCharArraysWithHexError(
-      "uint40", buffer40, 5,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
-                                                          : little_endian40,
-      5);
-
-  uint64_t read_number40;
-  QuicDataReader reader(buffer40, 5, GetParam().endianness);
-  reader.ReadBytesToUInt64(5, &read_number40);
-  EXPECT_EQ(in_memory40, read_number40);
-}
-
-TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
-  uint64_t in_memory48 = 0x0000112233445566;
-  char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
-  char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
-  char buffer48[6];
-  QuicDataWriter writer(6, buffer48, GetParam().endianness);
-  writer.WriteBytesToUInt64(6, in_memory48);
-  quiche::test::CompareCharArraysWithHexError(
-      "uint48", buffer48, 6,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
-                                                          : little_endian48,
-      6);
-
-  uint64_t read_number48;
-  QuicDataReader reader(buffer48, 6, GetParam().endianness);
-  reader.ReadBytesToUInt64(6., &read_number48);
-  EXPECT_EQ(in_memory48, read_number48);
-}
-
-TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
-  uint64_t in_memory56 = 0x0011223344556677;
-  char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
-  char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
-  char buffer56[7];
-  QuicDataWriter writer(7, buffer56, GetParam().endianness);
-  writer.WriteBytesToUInt64(7, in_memory56);
-  quiche::test::CompareCharArraysWithHexError(
-      "uint56", buffer56, 7,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
-                                                          : little_endian56,
-      7);
-
-  uint64_t read_number56;
-  QuicDataReader reader(buffer56, 7, GetParam().endianness);
-  reader.ReadBytesToUInt64(7, &read_number56);
-  EXPECT_EQ(in_memory56, read_number56);
-}
-
-TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
-  uint64_t in_memory64 = 0x1122334455667788;
-  unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
-                                     0x44, 0x33, 0x22, 0x11};
-  unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
-                                  0x55, 0x66, 0x77, 0x88};
-  char buffer64[8];
-  QuicDataWriter writer(8, buffer64, GetParam().endianness);
-  writer.WriteBytesToUInt64(8, in_memory64);
-  quiche::test::CompareCharArraysWithHexError(
-      "uint64_t", buffer64, 8,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
-          ? AsChars(big_endian64)
-          : AsChars(little_endian64),
-      8);
-
-  uint64_t read_number64;
-  QuicDataReader reader(buffer64, 8, GetParam().endianness);
-  reader.ReadBytesToUInt64(8, &read_number64);
-  EXPECT_EQ(in_memory64, read_number64);
-
-  QuicDataWriter writer2(8, buffer64, GetParam().endianness);
-  writer2.WriteUInt64(in_memory64);
-  quiche::test::CompareCharArraysWithHexError(
-      "uint64_t", buffer64, 8,
-      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
-          ? AsChars(big_endian64)
-          : AsChars(little_endian64),
-      8);
-  read_number64 = 0u;
-  QuicDataReader reader2(buffer64, 8, GetParam().endianness);
-  reader2.ReadUInt64(&read_number64);
-  EXPECT_EQ(in_memory64, read_number64);
-}
-
-TEST_P(QuicDataWriterTest, WriteIntegers) {
-  char buf[43];
-  uint8_t i8 = 0x01;
-  uint16_t i16 = 0x0123;
-  uint32_t i32 = 0x01234567;
-  uint64_t i64 = 0x0123456789ABCDEF;
-  QuicDataWriter writer(46, buf, GetParam().endianness);
-  for (size_t i = 0; i < 10; ++i) {
-    switch (i) {
-      case 0u:
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 1u:
-        EXPECT_TRUE(writer.WriteUInt8(i8));
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 2u:
-        EXPECT_TRUE(writer.WriteUInt16(i16));
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 3u:
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 4u:
-        EXPECT_TRUE(writer.WriteUInt32(i32));
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      case 5u:
-      case 6u:
-      case 7u:
-      case 8u:
-        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
-        break;
-      default:
-        EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
-    }
-  }
-
-  QuicDataReader reader(buf, 46, GetParam().endianness);
-  for (size_t i = 0; i < 10; ++i) {
-    uint8_t read8;
-    uint16_t read16;
-    uint32_t read32;
-    uint64_t read64;
-    switch (i) {
-      case 0u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0u, read64);
-        break;
-      case 1u:
-        EXPECT_TRUE(reader.ReadUInt8(&read8));
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(i8, read8);
-        EXPECT_EQ(0xEFu, read64);
-        break;
-      case 2u:
-        EXPECT_TRUE(reader.ReadUInt16(&read16));
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(i16, read16);
-        EXPECT_EQ(0xCDEFu, read64);
-        break;
-      case 3u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0xABCDEFu, read64);
-        break;
-      case 4u:
-        EXPECT_TRUE(reader.ReadUInt32(&read32));
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(i32, read32);
-        EXPECT_EQ(0x89ABCDEFu, read64);
-        break;
-      case 5u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x6789ABCDEFu, read64);
-        break;
-      case 6u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x456789ABCDEFu, read64);
-        break;
-      case 7u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x23456789ABCDEFu, read64);
-        break;
-      case 8u:
-        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
-        EXPECT_EQ(0x0123456789ABCDEFu, read64);
-        break;
-      default:
-        EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
-    }
-  }
-}
-
-TEST_P(QuicDataWriterTest, WriteBytes) {
-  char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
-  char buf[ABSL_ARRAYSIZE(bytes)];
-  QuicDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
-  EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
-  for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
-    EXPECT_EQ(bytes[i], buf[i]);
-  }
-}
-
-const int kVarIntBufferLength = 1024;
-
-// Encodes and then decodes a specified value, checks that the
-// value that was encoded is the same as the decoded value, the length
-// is correct, and that after decoding, all data in the buffer has
-// been consumed..
-// Returns true if everything works, false if not.
-bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
-  // Init the buffer to all 0, just for cleanliness. Makes for better
-  // output if, in debugging, we need to dump out the buffer.
-  memset(buffer, 0, size_of_buffer);
-  // make a writer. Note that for IETF encoding
-  // we do not care about endianness... It's always big-endian,
-  // but the c'tor expects to be told what endianness is in force...
-  QuicDataWriter writer(size_of_buffer, buffer,
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-
-  // Try to write the value.
-  if (writer.WriteVarInt62(value_in) != true) {
-    return false;
-  }
-  // Look at the value we encoded. Determine how much should have been
-  // used based on the value, and then check the state of the writer
-  // to see that it matches.
-  size_t expected_length = 0;
-  if (value_in <= 0x3f) {
-    expected_length = 1;
-  } else if (value_in <= 0x3fff) {
-    expected_length = 2;
-  } else if (value_in <= 0x3fffffff) {
-    expected_length = 4;
-  } else {
-    expected_length = 8;
-  }
-  if (writer.length() != expected_length) {
-    return false;
-  }
-
-  // set up a reader, just the length we've used, no more, no less.
-  QuicDataReader reader(buffer, expected_length,
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  uint64_t value_out;
-
-  if (reader.ReadVarInt62(&value_out) == false) {
-    return false;
-  }
-  if (value_in != value_out) {
-    return false;
-  }
-  // We only write one value so there had better be nothing left to read
-  return reader.IsDoneReading();
-}
-
-// Test that 8-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt8Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer is correct. Bytes
-  // are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
-            (0x31 + 0xc0));  // 0xc0 for encoding
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
-}
-
-// Test that 4-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt4Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer is correct. Bytes
-  // are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
-            (0x32 + 0x80));  // 0x80 for encoding
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
-}
-
-// Test that 2-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt2Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer is correct. Bytes
-  // are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(0x3647));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
-            (0x36 + 0x40));  // 0x40 for encoding
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
-}
-
-// Test that 1-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt1Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer
-  // is correct. Bytes are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(0x3f));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
-}
-
-// Test certain, targeted, values that are expected to succeed:
-// 0, 1,
-// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
-// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
-// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
-//                          transition)
-// 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
-// 0xfe, 0xff, 0x100, 0x101,
-// 0xfffe, 0xffff, 0x10000, 0x10001,
-// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
-// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
-// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
-// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
-// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
-TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
-  char buffer[kVarIntBufferLength];
-  uint64_t passing_values[] = {
-      0,
-      1,
-      0x3e,
-      0x3f,
-      0x40,
-      0x41,
-      0x3ffe,
-      0x3fff,
-      0x4000,
-      0x4001,
-      0x3ffffffe,
-      0x3fffffff,
-      0x40000000,
-      0x40000001,
-      0x3ffffffffffffffe,
-      0x3fffffffffffffff,
-      0xfe,
-      0xff,
-      0x100,
-      0x101,
-      0xfffe,
-      0xffff,
-      0x10000,
-      0x10001,
-      0xfffffe,
-      0xffffff,
-      0x1000000,
-      0x1000001,
-      0xfffffffe,
-      0xffffffff,
-      0x100000000,
-      0x100000001,
-      0xfffffffffe,
-      0xffffffffff,
-      0x10000000000,
-      0x10000000001,
-      0xfffffffffffe,
-      0xffffffffffff,
-      0x1000000000000,
-      0x1000000000001,
-      0xfffffffffffffe,
-      0xffffffffffffff,
-      0x100000000000000,
-      0x100000000000001,
-  };
-  for (uint64_t test_val : passing_values) {
-    EXPECT_TRUE(
-        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
-        << " encode/decode of " << test_val << " failed";
-  }
-}
-//
-// Test certain, targeted, values where failure is expected (the
-// values are invalid w.r.t. IETF VarInt encoding):
-// 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
-// 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
-TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
-  char buffer[kVarIntBufferLength];
-  uint64_t failing_values[] = {
-      0x4000000000000000,
-      0x4000000000000001,
-      0xfffffffffffffffe,
-      0xffffffffffffffff,
-  };
-  for (uint64_t test_val : failing_values) {
-    EXPECT_FALSE(
-        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
-        << " encode/decode of " << test_val << " succeeded, but was an "
-        << "invalid value";
-  }
-}
-
-// Following tests all try to fill the buffer with multiple values,
-// go one value more than the buffer can accommodate, then read
-// the successfully encoded values, and try to read the unsuccessfully
-// encoded value. The following is the number of values to encode.
-const int kMultiVarCount = 1000;
-
-// Test writing & reading multiple 8-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt8) {
-  uint64_t test_val;
-  char buffer[8 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
-  }
-  EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 4-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt4) {
-  uint64_t test_val;
-  char buffer[4 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
-  }
-  EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 2-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt2) {
-  uint64_t test_val;
-  char buffer[2 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
-  }
-  EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 1-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt1) {
-  uint64_t test_val;
-  char buffer[1 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over. &0xf ensures we do not
-  // overflow the max value for single-byte encoding.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
-  }
-  EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing varints with a forced length.
-TEST_P(QuicDataWriterTest, VarIntFixedLength) {
-  char buffer[90];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-
-  uint64_t test_val = 0;
-  for (int i = 0; i < 4; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 1u);
-  }
-  for (int i = 0; i < 4; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 63u);
-  }
-
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 64u);
-  }
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 16383u);
-  }
-
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 16384u);
-  }
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 1073741823u);
-  }
-
-  EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-  EXPECT_EQ(test_val, 1073741824u);
-
-  // We are at the end of the buffer so this should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test encoding/decoding stream-id values.
-void EncodeDecodeStreamId(uint64_t value_in) {
-  char buffer[1 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-
-  // Encode the given Stream ID.
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(value_in));
-
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  QuicStreamId received_stream_id;
-  uint64_t temp;
-  EXPECT_TRUE(reader.ReadVarInt62(&temp));
-  received_stream_id = static_cast<QuicStreamId>(temp);
-  EXPECT_EQ(value_in, received_stream_id);
-}
-
-// Test writing & reading stream-ids of various value.
-TEST_P(QuicDataWriterTest, StreamId1) {
-  // Check a 1-byte QuicStreamId, should work
-  EncodeDecodeStreamId(UINT64_C(0x15));
-
-  // Check a 2-byte QuicStream ID. It should work.
-  EncodeDecodeStreamId(UINT64_C(0x1567));
-
-  // Check a QuicStreamId that requires 4 bytes of encoding
-  // This should work.
-  EncodeDecodeStreamId(UINT64_C(0x34567890));
-
-  // Check a QuicStreamId that requires 8 bytes of encoding
-  // but whose value is in the acceptable range.
-  // This should work.
-  EncodeDecodeStreamId(UINT64_C(0xf4567890));
-}
-
-TEST_P(QuicDataWriterTest, WriteRandomBytes) {
-  char buffer[20];
-  char expected[20];
-  for (size_t i = 0; i < 20; ++i) {
-    expected[i] = 'r';
-  }
-  MockRandom random;
-  QuicDataWriter writer(20, buffer, GetParam().endianness);
-  EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
-
-  EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
-  quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
-                                              20);
-}
-
-TEST_P(QuicDataWriterTest, WriteInsecureRandomBytes) {
-  char buffer[20];
-  char expected[20];
-  for (size_t i = 0; i < 20; ++i) {
-    expected[i] = 'r';
-  }
-  MockRandom random;
-  QuicDataWriter writer(20, buffer, GetParam().endianness);
-  EXPECT_FALSE(writer.WriteInsecureRandomBytes(&random, 30));
-
-  EXPECT_TRUE(writer.WriteInsecureRandomBytes(&random, 20));
-  quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
-                                              20);
-}
-
-TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
-  // In range [0, 63], variable length should be 1 byte.
-  char buffer[20];
-  QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(50));
-  QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_EQ(1, reader.PeekVarInt62Length());
-  // In range (63-16383], variable length should be 2 byte2.
-  char buffer2[20];
-  QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer2.WriteVarInt62(100));
-  QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_EQ(2, reader2.PeekVarInt62Length());
-  // In range (16383, 1073741823], variable length should be 4 bytes.
-  char buffer3[20];
-  QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer3.WriteVarInt62(20000));
-  QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_EQ(4, reader3.PeekVarInt62Length());
-  // In range (1073741823, 4611686018427387903], variable length should be 8
-  // bytes.
-  char buffer4[20];
-  QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
-  QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
-  EXPECT_EQ(8, reader4.PeekVarInt62Length());
-}
-
-TEST_P(QuicDataWriterTest, ValidStreamCount) {
-  char buffer[1024];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  QuicDataReader reader(buffer, sizeof(buffer));
-  const QuicStreamCount write_stream_count = 0xffeeddcc;
-  EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
-  QuicStreamCount read_stream_count;
-  uint64_t temp;
-  EXPECT_TRUE(reader.ReadVarInt62(&temp));
-  read_stream_count = static_cast<QuicStreamId>(temp);
-  EXPECT_EQ(write_stream_count, read_stream_count);
-}
-
-TEST_P(QuicDataWriterTest, Seek) {
-  char buffer[3] = {};
-  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
-  EXPECT_TRUE(writer.WriteUInt8(42));
-  EXPECT_TRUE(writer.Seek(1));
-  EXPECT_TRUE(writer.WriteUInt8(3));
-
-  char expected[] = {42, 0, 3};
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
-    EXPECT_EQ(buffer[i], expected[i]);
-  }
-}
-
-TEST_P(QuicDataWriterTest, SeekTooFarFails) {
-  char buffer[20];
-
-  // Check that one can seek to the end of the writer, but not past.
-  {
-    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                          GetParam().endianness);
-    EXPECT_TRUE(writer.Seek(20));
-    EXPECT_FALSE(writer.Seek(1));
-  }
-
-  // Seeking several bytes past the end fails.
-  {
-    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                          GetParam().endianness);
-    EXPECT_FALSE(writer.Seek(100));
-  }
-
-  // Seeking so far that arithmetic overflow could occur also fails.
-  {
-    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
-                          GetParam().endianness);
-    EXPECT_TRUE(writer.Seek(10));
-    EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
-  }
-}
-
-TEST_P(QuicDataWriterTest, PayloadReads) {
-  char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-  char expected_first_read[4] = {1, 2, 3, 4};
-  char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-  QuicDataReader reader(buffer, sizeof(buffer));
-  char first_read_buffer[4] = {};
-  EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
-  quiche::test::CompareCharArraysWithHexError(
-      "first read", first_read_buffer, sizeof(first_read_buffer),
-      expected_first_read, sizeof(expected_first_read));
-  absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
-  quiche::test::CompareCharArraysWithHexError(
-      "peeked_remaining_payload", peeked_remaining_payload.data(),
-      peeked_remaining_payload.length(), expected_remaining,
-      sizeof(expected_remaining));
-  absl::string_view full_payload = reader.FullPayload();
-  quiche::test::CompareCharArraysWithHexError(
-      "full_payload", full_payload.data(), full_payload.length(), buffer,
-      sizeof(buffer));
-  absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
-  quiche::test::CompareCharArraysWithHexError(
-      "read_remaining_payload", read_remaining_payload.data(),
-      read_remaining_payload.length(), expected_remaining,
-      sizeof(expected_remaining));
-  EXPECT_TRUE(reader.IsDoneReading());
-  absl::string_view full_payload2 = reader.FullPayload();
-  quiche::test::CompareCharArraysWithHexError(
-      "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
-      sizeof(buffer));
-}
-
-TEST_P(QuicDataWriterTest, StringPieceVarInt62) {
-  char inner_buffer[16] = {1, 2,  3,  4,  5,  6,  7,  8,
-                           9, 10, 11, 12, 13, 14, 15, 16};
-  absl::string_view inner_payload_write(inner_buffer, sizeof(inner_buffer));
-  char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {};
-  QuicDataWriter writer(sizeof(buffer), buffer);
-  EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write));
-  EXPECT_EQ(0u, writer.remaining());
-  QuicDataReader reader(buffer, sizeof(buffer));
-  absl::string_view inner_payload_read;
-  EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read));
-  quiche::test::CompareCharArraysWithHexError(
-      "inner_payload", inner_payload_write.data(), inner_payload_write.length(),
-      inner_payload_read.data(), inner_payload_read.length());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_datagram_queue.cc b/quic/core/quic_datagram_queue.cc
deleted file mode 100644
index 0851878..0000000
--- a/quic/core/quic_datagram_queue.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_datagram_queue.h"
-
-#include "absl/types/span.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-
-constexpr float kExpiryInMinRtts = 1.25;
-constexpr float kMinPacingWindows = 4;
-
-QuicDatagramQueue::QuicDatagramQueue(QuicSession* session)
-    : QuicDatagramQueue(session, nullptr) {}
-
-QuicDatagramQueue::QuicDatagramQueue(QuicSession* session,
-                                     std::unique_ptr<Observer> observer)
-    : session_(session),
-      clock_(session->connection()->clock()),
-      observer_(std::move(observer)) {}
-
-MessageStatus QuicDatagramQueue::SendOrQueueDatagram(
-    quiche::QuicheMemSlice datagram) {
-  // If the queue is non-empty, always queue the daragram.  This ensures that
-  // the datagrams are sent in the same order that they were sent by the
-  // application.
-  if (queue_.empty()) {
-    MessageResult result = session_->SendMessage(absl::MakeSpan(&datagram, 1));
-    if (result.status != MESSAGE_STATUS_BLOCKED) {
-      if (observer_) {
-        observer_->OnDatagramProcessed(result.status);
-      }
-      return result.status;
-    }
-  }
-
-  queue_.emplace_back(Datagram{std::move(datagram),
-                               clock_->ApproximateNow() + GetMaxTimeInQueue()});
-  return MESSAGE_STATUS_BLOCKED;
-}
-
-absl::optional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() {
-  RemoveExpiredDatagrams();
-  if (queue_.empty()) {
-    return absl::nullopt;
-  }
-
-  MessageResult result =
-      session_->SendMessage(absl::MakeSpan(&queue_.front().datagram, 1));
-  if (result.status != MESSAGE_STATUS_BLOCKED) {
-    queue_.pop_front();
-    if (observer_) {
-      observer_->OnDatagramProcessed(result.status);
-    }
-  }
-  return result.status;
-}
-
-size_t QuicDatagramQueue::SendDatagrams() {
-  size_t num_datagrams = 0;
-  for (;;) {
-    absl::optional<MessageStatus> status = TrySendingNextDatagram();
-    if (!status.has_value()) {
-      break;
-    }
-    if (*status == MESSAGE_STATUS_BLOCKED) {
-      break;
-    }
-    num_datagrams++;
-  }
-  return num_datagrams;
-}
-
-QuicTime::Delta QuicDatagramQueue::GetMaxTimeInQueue() const {
-  if (!max_time_in_queue_.IsZero()) {
-    return max_time_in_queue_;
-  }
-
-  const QuicTime::Delta min_rtt =
-      session_->connection()->sent_packet_manager().GetRttStats()->min_rtt();
-  return std::max(kExpiryInMinRtts * min_rtt,
-                  kMinPacingWindows * kAlarmGranularity);
-}
-
-void QuicDatagramQueue::RemoveExpiredDatagrams() {
-  QuicTime now = clock_->ApproximateNow();
-  while (!queue_.empty() && queue_.front().expiry <= now) {
-    queue_.pop_front();
-    if (observer_) {
-      observer_->OnDatagramProcessed(absl::nullopt);
-    }
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_datagram_queue.h b/quic/core/quic_datagram_queue.h
deleted file mode 100644
index 6374a64..0000000
--- a/quic/core/quic_datagram_queue.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
-#define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
-
-#include <memory>
-
-#include "absl/types/optional.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-class QuicSession;
-
-// Provides a way to buffer QUIC datagrams (messages) in case they cannot
-// be sent due to congestion control.  Datagrams are buffered for a limited
-// amount of time, and deleted after that time passes.
-class QUIC_EXPORT_PRIVATE QuicDatagramQueue {
- public:
-  // An interface used to monitor events on the associated `QuicDatagramQueue`.
-  class QUIC_EXPORT_PRIVATE Observer {
-   public:
-    virtual ~Observer() = default;
-
-    // Called when a datagram in the associated queue is sent or discarded.
-    // Identity information for the datagram is not given, because the sending
-    // and discarding order is always first-in-first-out.
-    // This function is called synchronously in `QuicDatagramQueue` methods.
-    // `status` is nullopt when the datagram is dropped due to being in the
-    // queue for too long.
-    virtual void OnDatagramProcessed(absl::optional<MessageStatus> status) = 0;
-  };
-
-  // |session| is not owned and must outlive this object.
-  explicit QuicDatagramQueue(QuicSession* session);
-
-  // |session| is not owned and must outlive this object.
-  QuicDatagramQueue(QuicSession* session, std::unique_ptr<Observer> observer);
-
-  // Adds the datagram to the end of the queue.  May send it immediately; if
-  // not, MESSAGE_STATUS_BLOCKED is returned.
-  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram);
-
-  // Attempts to send a single datagram from the queue.  Returns the result of
-  // SendMessage(), or nullopt if there were no unexpired datagrams to send.
-  absl::optional<MessageStatus> TrySendingNextDatagram();
-
-  // Sends all of the unexpired datagrams until either the connection becomes
-  // write-blocked or the queue is empty.  Returns the number of datagrams sent.
-  size_t SendDatagrams();
-
-  // Returns the amount of time a datagram is allowed to be in the queue before
-  // it is dropped.  If not set explicitly using SetMaxTimeInQueue(), an
-  // RTT-based heuristic is used.
-  QuicTime::Delta GetMaxTimeInQueue() const;
-
-  void SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue) {
-    max_time_in_queue_ = max_time_in_queue;
-  }
-
-  size_t queue_size() { return queue_.size(); }
-
-  bool empty() { return queue_.empty(); }
-
- private:
-  struct QUIC_EXPORT_PRIVATE Datagram {
-    quiche::QuicheMemSlice datagram;
-    QuicTime expiry;
-  };
-
-  // Removes expired datagrams from the front of the queue.
-  void RemoveExpiredDatagrams();
-
-  QuicSession* session_;  // Not owned.
-  const QuicClock* clock_;
-
-  QuicTime::Delta max_time_in_queue_ = QuicTime::Delta::Zero();
-  quiche::QuicheCircularDeque<Datagram> queue_;
-  std::unique_ptr<Observer> observer_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
diff --git a/quic/core/quic_datagram_queue_test.cc b/quic/core/quic_datagram_queue_test.cc
deleted file mode 100644
index 4c0e0f2..0000000
--- a/quic/core/quic_datagram_queue_test.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_datagram_queue.h"
-
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/platform/api/quiche_reference_counted.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-
-using testing::_;
-using testing::ElementsAre;
-using testing::Return;
-
-class EstablishedCryptoStream : public MockQuicCryptoStream {
- public:
-  using MockQuicCryptoStream::MockQuicCryptoStream;
-
-  bool encryption_established() const override { return true; }
-};
-
-class QuicDatagramQueueObserver final : public QuicDatagramQueue::Observer {
- public:
-  class Context : public quiche::QuicheReferenceCounted {
-   public:
-    std::vector<absl::optional<MessageStatus>> statuses;
-  };
-
-  QuicDatagramQueueObserver() : context_(new Context()) {}
-  QuicDatagramQueueObserver(const QuicDatagramQueueObserver&) = delete;
-  QuicDatagramQueueObserver& operator=(const QuicDatagramQueueObserver&) =
-      delete;
-
-  void OnDatagramProcessed(absl::optional<MessageStatus> status) override {
-    context_->statuses.push_back(std::move(status));
-  }
-
-  const quiche::QuicheReferenceCountedPointer<Context>& context() {
-    return context_;
-  }
-
- private:
-  quiche::QuicheReferenceCountedPointer<Context> context_;
-};
-
-class QuicDatagramQueueTestBase : public QuicTest {
- protected:
-  QuicDatagramQueueTestBase()
-      : connection_(new MockQuicConnection(&helper_,
-                                           &alarm_factory_,
-                                           Perspective::IS_CLIENT)),
-        session_(connection_) {
-    session_.SetCryptoStream(new EstablishedCryptoStream(&session_));
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-  }
-
-  ~QuicDatagramQueueTestBase() = default;
-
-  quiche::QuicheMemSlice CreateMemSlice(absl::string_view data) {
-    return quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
-        helper_.GetStreamSendBufferAllocator(), data));
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnection* connection_;  // Owned by |session_|.
-  MockQuicSession session_;
-};
-
-class QuicDatagramQueueTest : public QuicDatagramQueueTestBase {
- public:
-  QuicDatagramQueueTest() : queue_(&session_) {}
-
- protected:
-  QuicDatagramQueue queue_;
-};
-
-TEST_F(QuicDatagramQueueTest, SendDatagramImmediately) {
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-  MessageStatus status = queue_.SendOrQueueDatagram(CreateMemSlice("test"));
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, status);
-  EXPECT_EQ(0u, queue_.queue_size());
-}
-
-TEST_F(QuicDatagramQueueTest, SendDatagramAfterBuffering) {
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-  MessageStatus initial_status =
-      queue_.SendOrQueueDatagram(CreateMemSlice("test"));
-  EXPECT_EQ(MESSAGE_STATUS_BLOCKED, initial_status);
-  EXPECT_EQ(1u, queue_.queue_size());
-
-  // Verify getting write blocked does not remove the datagram from the queue.
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-  absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
-  ASSERT_TRUE(status.has_value());
-  EXPECT_EQ(MESSAGE_STATUS_BLOCKED, *status);
-  EXPECT_EQ(1u, queue_.queue_size());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-  status = queue_.TrySendingNextDatagram();
-  ASSERT_TRUE(status.has_value());
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, *status);
-  EXPECT_EQ(0u, queue_.queue_size());
-}
-
-TEST_F(QuicDatagramQueueTest, EmptyBuffer) {
-  absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
-  EXPECT_FALSE(status.has_value());
-
-  size_t num_messages = queue_.SendDatagrams();
-  EXPECT_EQ(0u, num_messages);
-}
-
-TEST_F(QuicDatagramQueueTest, MultipleDatagrams) {
-  // Note that SendMessage() is called only once here, since all the remaining
-  // messages are automatically queued due to the queue being non-empty.
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
-  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
-  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
-  queue_.SendOrQueueDatagram(CreateMemSlice("d"));
-  queue_.SendOrQueueDatagram(CreateMemSlice("e"));
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .Times(5)
-      .WillRepeatedly(Return(MESSAGE_STATUS_SUCCESS));
-  size_t num_messages = queue_.SendDatagrams();
-  EXPECT_EQ(5u, num_messages);
-}
-
-TEST_F(QuicDatagramQueueTest, DefaultMaxTimeInQueue) {
-  EXPECT_EQ(QuicTime::Delta::Zero(),
-            connection_->sent_packet_manager().GetRttStats()->min_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(4), queue_.GetMaxTimeInQueue());
-
-  RttStats* stats =
-      const_cast<RttStats*>(connection_->sent_packet_manager().GetRttStats());
-  stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                   QuicTime::Delta::Zero(), helper_.GetClock()->Now());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(125), queue_.GetMaxTimeInQueue());
-}
-
-TEST_F(QuicDatagramQueueTest, Expiry) {
-  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
-  queue_.SetMaxTimeInQueue(expiry);
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
-  helper_.AdvanceTime(0.6 * expiry);
-  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
-  helper_.AdvanceTime(0.6 * expiry);
-  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
-
-  std::vector<std::string> messages;
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillRepeatedly([&messages](QuicMessageId /*id*/,
-                                  absl::Span<quiche::QuicheMemSlice> message,
-                                  bool /*flush*/) {
-        messages.push_back(std::string(message[0].AsStringView()));
-        return MESSAGE_STATUS_SUCCESS;
-      });
-  EXPECT_EQ(2u, queue_.SendDatagrams());
-  EXPECT_THAT(messages, ElementsAre("b", "c"));
-}
-
-TEST_F(QuicDatagramQueueTest, ExpireAll) {
-  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
-  queue_.SetMaxTimeInQueue(expiry);
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
-  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
-  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
-
-  helper_.AdvanceTime(100 * expiry);
-  EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
-  EXPECT_EQ(0u, queue_.SendDatagrams());
-}
-
-class QuicDatagramQueueWithObserverTest : public QuicDatagramQueueTestBase {
- public:
-  QuicDatagramQueueWithObserverTest()
-      : observer_(std::make_unique<QuicDatagramQueueObserver>()),
-        context_(observer_->context()),
-        queue_(&session_, std::move(observer_)) {}
-
- protected:
-  // This is moved out immediately.
-  std::unique_ptr<QuicDatagramQueueObserver> observer_;
-
-  quiche::QuicheReferenceCountedPointer<QuicDatagramQueueObserver::Context>
-      context_;
-  QuicDatagramQueue queue_;
-};
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessImmediately) {
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
-            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
-  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveFailureImmediately) {
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
-
-  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
-            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
-  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_TOO_LARGE));
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, BlockingShouldNotBeObserved) {
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillRepeatedly(Return(MESSAGE_STATUS_BLOCKED));
-
-  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
-            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-  EXPECT_EQ(0u, queue_.SendDatagrams());
-
-  EXPECT_TRUE(context_->statuses.empty());
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessAfterBuffering) {
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-
-  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
-            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-
-  EXPECT_EQ(1u, queue_.SendDatagrams());
-  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
-}
-
-TEST_F(QuicDatagramQueueWithObserverTest, ObserveExpiry) {
-  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
-  queue_.SetMaxTimeInQueue(expiry);
-
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _))
-      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
-
-  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
-            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
-
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
-  helper_.AdvanceTime(100 * expiry);
-
-  EXPECT_TRUE(context_->statuses.empty());
-
-  EXPECT_EQ(0u, queue_.SendDatagrams());
-  EXPECT_THAT(context_->statuses, ElementsAre(absl::nullopt));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_default_packet_writer.cc b/quic/core/quic_default_packet_writer.cc
deleted file mode 100644
index 23ff3c2..0000000
--- a/quic/core/quic_default_packet_writer.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_default_packet_writer.h"
-
-#include "quic/core/quic_udp_socket.h"
-
-namespace quic {
-
-QuicDefaultPacketWriter::QuicDefaultPacketWriter(int fd)
-    : fd_(fd), write_blocked_(false) {}
-
-QuicDefaultPacketWriter::~QuicDefaultPacketWriter() = default;
-
-WriteResult QuicDefaultPacketWriter::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  QUICHE_DCHECK(!write_blocked_);
-  QUICHE_DCHECK(nullptr == options)
-      << "QuicDefaultPacketWriter does not accept any options.";
-  QuicUdpPacketInfo packet_info;
-  packet_info.SetPeerAddress(peer_address);
-  packet_info.SetSelfIp(self_address);
-  WriteResult result =
-      QuicUdpSocketApi().WritePacket(fd_, buffer, buf_len, packet_info);
-  if (IsWriteBlockedStatus(result.status)) {
-    write_blocked_ = true;
-  }
-  return result;
-}
-
-bool QuicDefaultPacketWriter::IsWriteBlocked() const {
-  return write_blocked_;
-}
-
-void QuicDefaultPacketWriter::SetWritable() {
-  write_blocked_ = false;
-}
-
-absl::optional<int> QuicDefaultPacketWriter::MessageTooBigErrorCode() const {
-  return EMSGSIZE;
-}
-
-QuicByteCount QuicDefaultPacketWriter::GetMaxPacketSize(
-    const QuicSocketAddress& /*peer_address*/) const {
-  return kMaxOutgoingPacketSize;
-}
-
-bool QuicDefaultPacketWriter::SupportsReleaseTime() const {
-  return false;
-}
-
-bool QuicDefaultPacketWriter::IsBatchMode() const {
-  return false;
-}
-
-QuicPacketBuffer QuicDefaultPacketWriter::GetNextWriteLocation(
-    const QuicIpAddress& /*self_address*/,
-    const QuicSocketAddress& /*peer_address*/) {
-  return {nullptr, nullptr};
-}
-
-WriteResult QuicDefaultPacketWriter::Flush() {
-  return WriteResult(WRITE_STATUS_OK, 0);
-}
-
-void QuicDefaultPacketWriter::set_write_blocked(bool is_blocked) {
-  write_blocked_ = is_blocked;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_default_packet_writer.h b/quic/core/quic_default_packet_writer.h
deleted file mode 100644
index f332c96..0000000
--- a/quic/core/quic_default_packet_writer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
-#define QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
-
-#include <cstddef>
-
-#include "quic/core/quic_packet_writer.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-struct WriteResult;
-
-// Default packet writer which wraps QuicSocketUtils WritePacket.
-class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
- public:
-  explicit QuicDefaultPacketWriter(int fd);
-  QuicDefaultPacketWriter(const QuicDefaultPacketWriter&) = delete;
-  QuicDefaultPacketWriter& operator=(const QuicDefaultPacketWriter&) = delete;
-  ~QuicDefaultPacketWriter() override;
-
-  // QuicPacketWriter
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-  bool IsWriteBlocked() const override;
-  void SetWritable() override;
-  absl::optional<int> MessageTooBigErrorCode() const override;
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& peer_address) const override;
-  bool SupportsReleaseTime() const override;
-  bool IsBatchMode() const override;
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& self_address,
-      const QuicSocketAddress& peer_address) override;
-  WriteResult Flush() override;
-
-  void set_fd(int fd) { fd_ = fd; }
-
- protected:
-  void set_write_blocked(bool is_blocked);
-  int fd() { return fd_; }
-
- private:
-  int fd_;
-  bool write_blocked_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
deleted file mode 100644
index 1cc4cf3..0000000
--- a/quic/core/quic_dispatcher.cc
+++ /dev/null
@@ -1,1456 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_dispatcher.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/chlo_extractor.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_chlo_extractor.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
-using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
-using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
-
-namespace {
-
-// Minimal INITIAL packet length sent by clients is 1200.
-const QuicPacketLength kMinClientInitialPacketLength = 1200;
-
-// An alarm that informs the QuicDispatcher to delete old sessions.
-class DeleteSessionsAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
-      : dispatcher_(dispatcher) {}
-  DeleteSessionsAlarm(const DeleteSessionsAlarm&) = delete;
-  DeleteSessionsAlarm& operator=(const DeleteSessionsAlarm&) = delete;
-
-  void OnAlarm() override { dispatcher_->DeleteSessions(); }
-
- private:
-  // Not owned.
-  QuicDispatcher* dispatcher_;
-};
-
-// An alarm that informs the QuicDispatcher to clear
-// recent_stateless_reset_addresses_.
-class ClearStatelessResetAddressesAlarm
-    : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit ClearStatelessResetAddressesAlarm(QuicDispatcher* dispatcher)
-      : dispatcher_(dispatcher) {}
-  ClearStatelessResetAddressesAlarm(const DeleteSessionsAlarm&) = delete;
-  ClearStatelessResetAddressesAlarm& operator=(const DeleteSessionsAlarm&) =
-      delete;
-
-  void OnAlarm() override { dispatcher_->ClearStatelessResetAddresses(); }
-
- private:
-  // Not owned.
-  QuicDispatcher* dispatcher_;
-};
-
-// Collects packets serialized by a QuicPacketCreator in order
-// to be handed off to the time wait list manager.
-class PacketCollector : public QuicPacketCreator::DelegateInterface,
-                        public QuicStreamFrameDataProducer {
- public:
-  explicit PacketCollector(quiche::QuicheBufferAllocator* allocator)
-      : send_buffer_(allocator) {}
-  ~PacketCollector() override = default;
-
-  // QuicPacketCreator::DelegateInterface methods:
-  void OnSerializedPacket(SerializedPacket serialized_packet) override {
-    // Make a copy of the serialized packet to send later.
-    packets_.emplace_back(
-        new QuicEncryptedPacket(CopyBuffer(serialized_packet),
-                                serialized_packet.encrypted_length, true));
-  }
-
-  QuicPacketBuffer GetPacketBuffer() override {
-    // Let QuicPacketCreator to serialize packets on stack buffer.
-    return {nullptr, nullptr};
-  }
-
-  void OnUnrecoverableError(QuicErrorCode /*error*/,
-                            const std::string& /*error_details*/) override {}
-
-  bool ShouldGeneratePacket(HasRetransmittableData /*retransmittable*/,
-                            IsHandshake /*handshake*/) override {
-    QUICHE_DCHECK(false);
-    return true;
-  }
-
-  const QuicFrames MaybeBundleAckOpportunistically() override {
-    QUICHE_DCHECK(false);
-    return {};
-  }
-
-  SerializedPacketFate GetSerializedPacketFate(
-      bool /*is_mtu_discovery*/,
-      EncryptionLevel /*encryption_level*/) override {
-    return SEND_TO_WRITER;
-  }
-
-  // QuicStreamFrameDataProducer
-  WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
-                                        QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        QuicDataWriter* writer) override {
-    if (send_buffer_.WriteStreamData(offset, data_length, writer)) {
-      return WRITE_SUCCESS;
-    }
-    return WRITE_FAILED;
-  }
-  bool WriteCryptoData(EncryptionLevel /*level*/,
-                       QuicStreamOffset offset,
-                       QuicByteCount data_length,
-                       QuicDataWriter* writer) override {
-    return send_buffer_.WriteStreamData(offset, data_length, writer);
-  }
-
-  std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
-    return &packets_;
-  }
-
- private:
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
-  // This is only needed until the packets are encrypted. Once packets are
-  // encrypted, the stream data is no longer required.
-  QuicStreamSendBuffer send_buffer_;
-};
-
-// Helper for statelessly closing connections by generating the
-// correct termination packets and adding the connection to the time wait
-// list manager.
-class StatelessConnectionTerminator {
- public:
-  StatelessConnectionTerminator(QuicConnectionId server_connection_id,
-                                const ParsedQuicVersion version,
-                                QuicConnectionHelperInterface* helper,
-                                QuicTimeWaitListManager* time_wait_list_manager)
-      : server_connection_id_(server_connection_id),
-        framer_(ParsedQuicVersionVector{version},
-                /*unused*/ QuicTime::Zero(),
-                Perspective::IS_SERVER,
-                /*unused*/ kQuicDefaultConnectionIdLength),
-        collector_(helper->GetStreamSendBufferAllocator()),
-        creator_(server_connection_id, &framer_, &collector_),
-        time_wait_list_manager_(time_wait_list_manager) {
-    framer_.set_data_producer(&collector_);
-    framer_.SetInitialObfuscators(server_connection_id);
-  }
-
-  ~StatelessConnectionTerminator() {
-    // Clear framer's producer.
-    framer_.set_data_producer(nullptr);
-  }
-
-  // Generates a packet containing a CONNECTION_CLOSE frame specifying
-  // |error_code| and |error_details| and add the connection to time wait.
-  void CloseConnection(QuicErrorCode error_code,
-                       const std::string& error_details,
-                       bool ietf_quic,
-                       std::vector<QuicConnectionId> active_connection_ids) {
-    SerializeConnectionClosePacket(error_code, error_details);
-
-    time_wait_list_manager_->AddConnectionIdToTimeWait(
-        QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
-        TimeWaitConnectionInfo(ietf_quic, collector_.packets(),
-                               std::move(active_connection_ids),
-                               /*srtt=*/QuicTime::Delta::Zero()));
-  }
-
- private:
-  void SerializeConnectionClosePacket(QuicErrorCode error_code,
-                                      const std::string& error_details) {
-    QuicConnectionCloseFrame* frame =
-        new QuicConnectionCloseFrame(framer_.transport_version(), error_code,
-                                     NO_IETF_QUIC_ERROR, error_details,
-                                     /*transport_close_frame_type=*/0);
-
-    if (!creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION)) {
-      QUIC_BUG(quic_bug_10287_1) << "Unable to add frame to an empty packet";
-      delete frame;
-      return;
-    }
-    creator_.FlushCurrentPacket();
-    QUICHE_DCHECK_EQ(1u, collector_.packets()->size());
-  }
-
-  QuicConnectionId server_connection_id_;
-  QuicFramer framer_;
-  // Set as the visitor of |creator_| to collect any generated packets.
-  PacketCollector collector_;
-  QuicPacketCreator creator_;
-  QuicTimeWaitListManager* time_wait_list_manager_;
-};
-
-// Class which extracts the ALPN and SNI from a QUIC_CRYPTO CHLO packet.
-class ChloAlpnSniExtractor : public ChloExtractor::Delegate {
- public:
-  void OnChlo(QuicTransportVersion version,
-              QuicConnectionId /*server_connection_id*/,
-              const CryptoHandshakeMessage& chlo) override {
-    absl::string_view alpn_value;
-    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
-      alpn_ = std::string(alpn_value);
-    }
-    absl::string_view sni;
-    if (chlo.GetStringPiece(quic::kSNI, &sni)) {
-      sni_ = std::string(sni);
-    }
-    absl::string_view uaid_value;
-    if (chlo.GetStringPiece(quic::kUAID, &uaid_value)) {
-      uaid_ = std::string(uaid_value);
-    }
-    if (version == LegacyVersionForEncapsulation().transport_version) {
-      absl::string_view qlve_value;
-      if (chlo.GetStringPiece(kQLVE, &qlve_value)) {
-        legacy_version_encapsulation_inner_packet_ = std::string(qlve_value);
-      }
-    }
-  }
-
-  std::string&& ConsumeAlpn() { return std::move(alpn_); }
-
-  std::string&& ConsumeSni() { return std::move(sni_); }
-
-  std::string&& ConsumeUaid() { return std::move(uaid_); }
-
-  std::string&& ConsumeLegacyVersionEncapsulationInnerPacket() {
-    return std::move(legacy_version_encapsulation_inner_packet_);
-  }
-
- private:
-  std::string alpn_;
-  std::string sni_;
-  std::string uaid_;
-  std::string legacy_version_encapsulation_inner_packet_;
-};
-
-bool MaybeHandleLegacyVersionEncapsulation(
-    QuicDispatcher* dispatcher,
-    std::string legacy_version_encapsulation_inner_packet,
-    const ReceivedPacketInfo& packet_info) {
-  if (legacy_version_encapsulation_inner_packet.empty()) {
-    // This CHLO did not contain the Legacy Version Encapsulation tag.
-    return false;
-  }
-  PacketHeaderFormat format;
-  QuicLongHeaderType long_packet_type;
-  bool version_present;
-  bool has_length_prefix;
-  QuicVersionLabel version_label;
-  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-  QuicConnectionId destination_connection_id, source_connection_id;
-  absl::optional<absl::string_view> retry_token;
-  std::string detailed_error;
-  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-      QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(),
-                          legacy_version_encapsulation_inner_packet.length()),
-      kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  if (error != QUIC_NO_ERROR) {
-    QUIC_DLOG(ERROR)
-        << "Failed to parse Legacy Version Encapsulation inner packet:"
-        << detailed_error;
-    return false;
-  }
-  if (destination_connection_id != packet_info.destination_connection_id) {
-    // We enforce that the inner and outer connection IDs match to make sure
-    // this never impacts routing of packets.
-    QUIC_DLOG(ERROR) << "Ignoring Legacy Version Encapsulation packet "
-                        "with mismatched connection ID "
-                     << destination_connection_id << " vs "
-                     << packet_info.destination_connection_id;
-    return false;
-  }
-  if (legacy_version_encapsulation_inner_packet.length() >=
-      packet_info.packet.length()) {
-    QUIC_BUG(quic_bug_10287_2)
-        << "Inner packet cannot be larger than outer "
-        << legacy_version_encapsulation_inner_packet.length() << " vs "
-        << packet_info.packet.length();
-    return false;
-  }
-
-  QUIC_DVLOG(1) << "Extracted a Legacy Version Encapsulation "
-                << legacy_version_encapsulation_inner_packet.length()
-                << " byte packet of version " << parsed_version;
-
-  // Append zeroes to the end of the packet. This will ensure that
-  // we use the right number of bytes for calculating anti-amplification
-  // limits. Note that this only works for long headers of versions that carry
-  // long header lengths, since they'll ignore any trailing zeroes. We still
-  // do this for all packets to ensure version negotiation works.
-  legacy_version_encapsulation_inner_packet.append(
-      packet_info.packet.length() -
-          legacy_version_encapsulation_inner_packet.length(),
-      0x00);
-
-  // Process the inner packet as if it had been received by itself.
-  QuicReceivedPacket received_encapsulated_packet(
-      legacy_version_encapsulation_inner_packet.data(),
-      legacy_version_encapsulation_inner_packet.length(),
-      packet_info.packet.receipt_time());
-  dispatcher->ProcessPacket(packet_info.self_address, packet_info.peer_address,
-                            received_encapsulated_packet);
-  QUIC_CODE_COUNT(quic_legacy_version_encapsulation_decapsulated);
-  return true;
-}
-
-}  // namespace
-
-QuicDispatcher::QuicDispatcher(
-    const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
-    QuicVersionManager* version_manager,
-    std::unique_ptr<QuicConnectionHelperInterface> helper,
-    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-    std::unique_ptr<QuicAlarmFactory> alarm_factory,
-    uint8_t expected_server_connection_id_length)
-    : config_(config),
-      crypto_config_(crypto_config),
-      compressed_certs_cache_(
-          QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
-      helper_(std::move(helper)),
-      session_helper_(std::move(session_helper)),
-      alarm_factory_(std::move(alarm_factory)),
-      delete_sessions_alarm_(
-          alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))),
-      buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()),
-      version_manager_(version_manager),
-      last_error_(QUIC_NO_ERROR),
-      new_sessions_allowed_per_event_loop_(0u),
-      accept_new_connections_(true),
-      allow_short_initial_server_connection_ids_(false),
-      expected_server_connection_id_length_(
-          expected_server_connection_id_length),
-      clear_stateless_reset_addresses_alarm_(alarm_factory_->CreateAlarm(
-          new ClearStatelessResetAddressesAlarm(this))),
-      should_update_expected_server_connection_id_length_(false) {
-  QUIC_BUG_IF(quic_bug_12724_1, GetSupportedVersions().empty())
-      << "Trying to create dispatcher without any supported versions";
-  QUIC_DLOG(INFO) << "Created QuicDispatcher with versions: "
-                  << ParsedQuicVersionVectorToString(GetSupportedVersions());
-}
-
-QuicDispatcher::~QuicDispatcher() {
-  if (delete_sessions_alarm_ != nullptr) {
-    delete_sessions_alarm_->PermanentCancel();
-  }
-  if (clear_stateless_reset_addresses_alarm_ != nullptr) {
-    clear_stateless_reset_addresses_alarm_->PermanentCancel();
-  }
-  reference_counted_session_map_.clear();
-  closed_session_list_.clear();
-  num_sessions_in_session_map_ = 0;
-}
-
-void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) {
-  QUICHE_DCHECK(writer_ == nullptr);
-  writer_.reset(writer);
-  time_wait_list_manager_.reset(CreateQuicTimeWaitListManager());
-}
-
-void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
-                                   const QuicSocketAddress& peer_address,
-                                   const QuicReceivedPacket& packet) {
-  QUIC_DVLOG(2) << "Dispatcher received encrypted " << packet.length()
-                << " bytes:" << std::endl
-                << quiche::QuicheTextUtils::HexDump(
-                       absl::string_view(packet.data(), packet.length()));
-  ReceivedPacketInfo packet_info(self_address, peer_address, packet);
-  std::string detailed_error;
-  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-      packet, expected_server_connection_id_length_, &packet_info.form,
-      &packet_info.long_packet_type, &packet_info.version_flag,
-      &packet_info.use_length_prefix, &packet_info.version_label,
-      &packet_info.version, &packet_info.destination_connection_id,
-      &packet_info.source_connection_id, &packet_info.retry_token,
-      &detailed_error);
-  if (error != QUIC_NO_ERROR) {
-    // Packet has framing error.
-    SetLastError(error);
-    QUIC_DLOG(ERROR) << detailed_error;
-    return;
-  }
-  if (packet_info.destination_connection_id.length() !=
-          expected_server_connection_id_length_ &&
-      !should_update_expected_server_connection_id_length_ &&
-      packet_info.version.IsKnown() &&
-      !packet_info.version.AllowsVariableLengthConnectionIds()) {
-    SetLastError(QUIC_INVALID_PACKET_HEADER);
-    QUIC_DLOG(ERROR) << "Invalid Connection Id Length";
-    return;
-  }
-
-  if (packet_info.version_flag && IsSupportedVersion(packet_info.version)) {
-    if (!QuicUtils::IsConnectionIdValidForVersion(
-            packet_info.destination_connection_id,
-            packet_info.version.transport_version)) {
-      SetLastError(QUIC_INVALID_PACKET_HEADER);
-      QUIC_DLOG(ERROR)
-          << "Invalid destination connection ID length for version";
-      return;
-    }
-    if (packet_info.version.SupportsClientConnectionIds() &&
-        !QuicUtils::IsConnectionIdValidForVersion(
-            packet_info.source_connection_id,
-            packet_info.version.transport_version)) {
-      SetLastError(QUIC_INVALID_PACKET_HEADER);
-      QUIC_DLOG(ERROR) << "Invalid source connection ID length for version";
-      return;
-    }
-  }
-
-  if (should_update_expected_server_connection_id_length_) {
-    expected_server_connection_id_length_ =
-        packet_info.destination_connection_id.length();
-  }
-
-  if (MaybeDispatchPacket(packet_info)) {
-    // Packet has been dropped or successfully dispatched, stop processing.
-    return;
-  }
-  ProcessHeader(&packet_info);
-}
-
-QuicConnectionId QuicDispatcher::MaybeReplaceServerConnectionId(
-    const QuicConnectionId& server_connection_id,
-    const ParsedQuicVersion& version) const {
-  const uint8_t server_connection_id_length = server_connection_id.length();
-  if (server_connection_id_length == expected_server_connection_id_length_) {
-    return server_connection_id;
-  }
-  QUICHE_DCHECK(version.AllowsVariableLengthConnectionIds());
-  QuicConnectionId new_connection_id;
-  if (server_connection_id_length < expected_server_connection_id_length_) {
-    new_connection_id = ReplaceShortServerConnectionId(
-        version, server_connection_id, expected_server_connection_id_length_);
-    // Verify that ReplaceShortServerConnectionId is deterministic.
-    QUICHE_DCHECK_EQ(
-        new_connection_id,
-        ReplaceShortServerConnectionId(version, server_connection_id,
-                                       expected_server_connection_id_length_));
-  } else {
-    new_connection_id = ReplaceLongServerConnectionId(
-        version, server_connection_id, expected_server_connection_id_length_);
-    // Verify that ReplaceLongServerConnectionId is deterministic.
-    QUICHE_DCHECK_EQ(
-        new_connection_id,
-        ReplaceLongServerConnectionId(version, server_connection_id,
-                                      expected_server_connection_id_length_));
-  }
-  QUICHE_DCHECK_EQ(expected_server_connection_id_length_,
-                   new_connection_id.length());
-
-  QUIC_DLOG(INFO) << "Replacing incoming connection ID " << server_connection_id
-                  << " with " << new_connection_id;
-  return new_connection_id;
-}
-
-QuicConnectionId QuicDispatcher::ReplaceShortServerConnectionId(
-    const ParsedQuicVersion& /*version*/,
-    const QuicConnectionId& server_connection_id,
-    uint8_t expected_server_connection_id_length) const {
-  QUICHE_DCHECK_LT(server_connection_id.length(),
-                   expected_server_connection_id_length);
-  return QuicUtils::CreateReplacementConnectionId(
-      server_connection_id, expected_server_connection_id_length);
-}
-
-QuicConnectionId QuicDispatcher::ReplaceLongServerConnectionId(
-    const ParsedQuicVersion& /*version*/,
-    const QuicConnectionId& server_connection_id,
-    uint8_t expected_server_connection_id_length) const {
-  QUICHE_DCHECK_GT(server_connection_id.length(),
-                   expected_server_connection_id_length);
-  return QuicUtils::CreateReplacementConnectionId(
-      server_connection_id, expected_server_connection_id_length);
-}
-
-namespace {
-constexpr bool IsSourceUdpPortBlocked(uint16_t port) {
-  // These UDP source ports have been observed in large scale denial of service
-  // attacks and are not expected to ever carry user traffic, they are therefore
-  // blocked as a safety measure. See draft-ietf-quic-applicability for details.
-  constexpr uint16_t blocked_ports[] = {
-      0,      // We cannot send to port 0 so drop that source port.
-      17,     // Quote of the Day, can loop with QUIC.
-      19,     // Chargen, can loop with QUIC.
-      53,     // DNS, vulnerable to reflection attacks.
-      111,    // Portmap.
-      123,    // NTP, vulnerable to reflection attacks.
-      137,    // NETBIOS Name Service,
-      128,    // NETBIOS Datagram Service
-      161,    // SNMP.
-      389,    // CLDAP.
-      500,    // IKE, can loop with QUIC.
-      1900,   // SSDP, vulnerable to reflection attacks.
-      5353,   // mDNS, vulnerable to reflection attacks.
-      11211,  // memcache, vulnerable to reflection attacks.
-              // This list MUST be sorted in increasing order.
-  };
-  constexpr size_t num_blocked_ports = ABSL_ARRAYSIZE(blocked_ports);
-  constexpr uint16_t highest_blocked_port =
-      blocked_ports[num_blocked_ports - 1];
-  if (QUICHE_PREDICT_TRUE(port > highest_blocked_port)) {
-    // Early-return to skip comparisons for the majority of traffic.
-    return false;
-  }
-  for (size_t i = 0; i < num_blocked_ports; i++) {
-    if (port == blocked_ports[i]) {
-      return true;
-    }
-  }
-  return false;
-}
-}  // namespace
-
-bool QuicDispatcher::MaybeDispatchPacket(
-    const ReceivedPacketInfo& packet_info) {
-  if (IsSourceUdpPortBlocked(packet_info.peer_address.port())) {
-    // Silently drop the received packet.
-    QUIC_CODE_COUNT(quic_dropped_blocked_port);
-    return true;
-  }
-
-  QuicConnectionId server_connection_id = packet_info.destination_connection_id;
-
-  // The IETF spec requires the client to generate an initial server
-  // connection ID that is at least 64 bits long. After that initial
-  // connection ID, the dispatcher picks a new one of its expected length.
-  // Therefore we should never receive a connection ID that is smaller
-  // than 64 bits and smaller than what we expect. Unless the version is
-  // unknown, in which case we allow short connection IDs for version
-  // negotiation because that version could allow those.
-  if (packet_info.version_flag && packet_info.version.IsKnown() &&
-      server_connection_id.length() < kQuicMinimumInitialConnectionIdLength &&
-      server_connection_id.length() < expected_server_connection_id_length_ &&
-      !allow_short_initial_server_connection_ids_) {
-    QUICHE_DCHECK(packet_info.version_flag);
-    QUICHE_DCHECK(packet_info.version.AllowsVariableLengthConnectionIds());
-    QUIC_DLOG(INFO) << "Packet with short destination connection ID "
-                    << server_connection_id << " expected "
-                    << static_cast<int>(expected_server_connection_id_length_);
-    // Drop the packet silently.
-    QUIC_CODE_COUNT(quic_dropped_invalid_small_initial_connection_id);
-    return true;
-  }
-
-  if (packet_info.version_flag && packet_info.version.IsKnown() &&
-      !QuicUtils::IsConnectionIdLengthValidForVersion(
-          server_connection_id.length(),
-          packet_info.version.transport_version)) {
-    QUIC_DLOG(INFO) << "Packet with destination connection ID "
-                    << server_connection_id << " is invalid with version "
-                    << packet_info.version;
-    // Drop the packet silently.
-    QUIC_CODE_COUNT(quic_dropped_invalid_initial_connection_id);
-    return true;
-  }
-
-  // Packets with connection IDs for active connections are processed
-  // immediately.
-  auto it = reference_counted_session_map_.find(server_connection_id);
-  if (it != reference_counted_session_map_.end()) {
-    QUICHE_DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
-    if (packet_info.version_flag &&
-        packet_info.version != it->second->version() &&
-        packet_info.version == LegacyVersionForEncapsulation()) {
-      // This packet is using the Legacy Version Encapsulation version but the
-      // corresponding session isn't, attempt extraction of inner packet.
-      ChloAlpnSniExtractor alpn_extractor;
-      if (ChloExtractor::Extract(packet_info.packet, packet_info.version,
-                                 config_->create_session_tag_indicators(),
-                                 &alpn_extractor,
-                                 server_connection_id.length())) {
-        if (MaybeHandleLegacyVersionEncapsulation(
-                this,
-                alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket(),
-                packet_info)) {
-          return true;
-        }
-      }
-    }
-    it->second->ProcessUdpPacket(packet_info.self_address,
-                                 packet_info.peer_address, packet_info.packet);
-    return true;
-  }
-  if (packet_info.version.IsKnown()) {
-    // We did not find the connection ID, check if we've replaced it.
-    // This is only performed for supported versions because packets with
-    // unsupported versions can flow through this function in order to send
-    // a version negotiation packet, but we know that their connection ID
-    // did not get replaced since that is performed on connection creation,
-    // and that only happens for known verions.
-    QuicConnectionId replaced_connection_id = MaybeReplaceServerConnectionId(
-        server_connection_id, packet_info.version);
-    if (replaced_connection_id != server_connection_id) {
-      // Search for the replacement.
-      auto it2 = reference_counted_session_map_.find(replaced_connection_id);
-      if (it2 != reference_counted_session_map_.end()) {
-        QUICHE_DCHECK(
-            !buffered_packets_.HasBufferedPackets(replaced_connection_id));
-        it2->second->ProcessUdpPacket(packet_info.self_address,
-                                      packet_info.peer_address,
-                                      packet_info.packet);
-        return true;
-      }
-    }
-  }
-
-  if (buffered_packets_.HasChloForConnection(server_connection_id)) {
-    BufferEarlyPacket(packet_info);
-    return true;
-  }
-
-  if (OnFailedToDispatchPacket(packet_info)) {
-    return true;
-  }
-
-  if (time_wait_list_manager_->IsConnectionIdInTimeWait(server_connection_id)) {
-    // This connection ID is already in time-wait state.
-    time_wait_list_manager_->ProcessPacket(
-        packet_info.self_address, packet_info.peer_address,
-        packet_info.destination_connection_id, packet_info.form,
-        packet_info.packet.length(), GetPerPacketContext());
-    return true;
-  }
-
-  // The packet has an unknown connection ID.
-  if (!accept_new_connections_ && packet_info.version_flag) {
-    // If not accepting new connections, reject packets with version which can
-    // potentially result in new connection creation. But if the packet doesn't
-    // have version flag, leave it to ValidityChecks() to reset it.
-    // By adding the connection to time wait list, following packets on this
-    // connection will not reach ShouldAcceptNewConnections().
-    StatelesslyTerminateConnection(
-        packet_info.destination_connection_id, packet_info.form,
-        packet_info.version_flag, packet_info.use_length_prefix,
-        packet_info.version, QUIC_HANDSHAKE_FAILED,
-        "Stop accepting new connections",
-        quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
-    // Time wait list will reject the packet correspondingly..
-    time_wait_list_manager()->ProcessPacket(
-        packet_info.self_address, packet_info.peer_address,
-        packet_info.destination_connection_id, packet_info.form,
-        packet_info.packet.length(), GetPerPacketContext());
-    OnNewConnectionRejected();
-    return true;
-  }
-
-  // Unless the packet provides a version, assume that we can continue
-  // processing using our preferred version.
-  if (packet_info.version_flag) {
-    if (!IsSupportedVersion(packet_info.version)) {
-      if (ShouldCreateSessionForUnknownVersion(packet_info.version_label)) {
-        return false;
-      }
-      if (!crypto_config()->validate_chlo_size() ||
-          packet_info.packet.length() >= kMinPacketSizeForVersionNegotiation) {
-        // Since the version is not supported, send a version negotiation
-        // packet and stop processing the current packet.
-        QuicConnectionId client_connection_id =
-            packet_info.source_connection_id;
-        time_wait_list_manager()->SendVersionNegotiationPacket(
-            server_connection_id, client_connection_id,
-            packet_info.form != GOOGLE_QUIC_PACKET,
-            packet_info.use_length_prefix, GetSupportedVersions(),
-            packet_info.self_address, packet_info.peer_address,
-            GetPerPacketContext());
-      }
-      return true;
-    }
-
-    if (crypto_config()->validate_chlo_size() &&
-        packet_info.form == IETF_QUIC_LONG_HEADER_PACKET &&
-        packet_info.long_packet_type == INITIAL &&
-        packet_info.packet.length() < kMinClientInitialPacketLength) {
-      QUIC_DVLOG(1) << "Dropping initial packet which is too short, length: "
-                    << packet_info.packet.length();
-      QUIC_CODE_COUNT(quic_drop_small_initial_packets);
-      return true;
-    }
-  }
-
-  return false;
-}
-
-void QuicDispatcher::ProcessHeader(ReceivedPacketInfo* packet_info) {
-  QuicConnectionId server_connection_id =
-      packet_info->destination_connection_id;
-  // Packet's connection ID is unknown.  Apply the validity checks.
-  QuicPacketFate fate = ValidityChecks(*packet_info);
-
-  if (fate == kFateProcess) {
-    absl::optional<ParsedClientHello> parsed_chlo =
-        TryExtractChloOrBufferEarlyPacket(*packet_info);
-    if (!parsed_chlo.has_value()) {
-      // Client Hello incomplete. Packet has been buffered or (rarely) dropped.
-      return;
-    }
-
-    // Client Hello fully received.
-    fate = ValidityChecksOnFullChlo(*packet_info, *parsed_chlo);
-
-    if (fate == kFateProcess) {
-      QUICHE_DCHECK(
-          parsed_chlo->legacy_version_encapsulation_inner_packet.empty() ||
-          !packet_info->version.UsesTls());
-      if (MaybeHandleLegacyVersionEncapsulation(
-              this, parsed_chlo->legacy_version_encapsulation_inner_packet,
-              *packet_info)) {
-        return;
-      }
-
-      ProcessChlo(*std::move(parsed_chlo), packet_info);
-      return;
-    }
-  }
-
-  switch (fate) {
-    case kFateProcess:
-      // kFateProcess have been processed above.
-      QUIC_BUG(quic_dispatcher_bad_packet_fate) << fate;
-      break;
-    case kFateTimeWait:
-      // Add this connection_id to the time-wait state, to safely reject
-      // future packets.
-      QUIC_DLOG(INFO) << "Adding connection ID " << server_connection_id
-                      << " to time-wait list.";
-      QUIC_CODE_COUNT(quic_reject_fate_time_wait);
-      StatelesslyTerminateConnection(
-          server_connection_id, packet_info->form, packet_info->version_flag,
-          packet_info->use_length_prefix, packet_info->version,
-          QUIC_HANDSHAKE_FAILED, "Reject connection",
-          quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
-
-      QUICHE_DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
-          server_connection_id));
-      time_wait_list_manager_->ProcessPacket(
-          packet_info->self_address, packet_info->peer_address,
-          server_connection_id, packet_info->form, packet_info->packet.length(),
-          GetPerPacketContext());
-
-      buffered_packets_.DiscardPackets(server_connection_id);
-      break;
-    case kFateDrop:
-      break;
-  }
-}
-
-absl::optional<ParsedClientHello>
-QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
-    const ReceivedPacketInfo& packet_info) {
-  if (packet_info.version.UsesTls()) {
-    bool has_full_tls_chlo = false;
-    std::string sni;
-    std::vector<std::string> alpns;
-    bool resumption_attempted = false, early_data_attempted = false;
-    if (buffered_packets_.HasBufferedPackets(
-            packet_info.destination_connection_id)) {
-      // If we already have buffered packets for this connection ID,
-      // use the associated TlsChloExtractor to parse this packet.
-      has_full_tls_chlo = buffered_packets_.IngestPacketForTlsChloExtraction(
-          packet_info.destination_connection_id, packet_info.version,
-          packet_info.packet, &alpns, &sni, &resumption_attempted,
-          &early_data_attempted);
-    } else {
-      // If we do not have a BufferedPacketList for this connection ID,
-      // create a single-use one to check whether this packet contains a
-      // full single-packet CHLO.
-      TlsChloExtractor tls_chlo_extractor;
-      tls_chlo_extractor.IngestPacket(packet_info.version, packet_info.packet);
-      if (tls_chlo_extractor.HasParsedFullChlo()) {
-        // This packet contains a full single-packet CHLO.
-        has_full_tls_chlo = true;
-        alpns = tls_chlo_extractor.alpns();
-        sni = tls_chlo_extractor.server_name();
-        resumption_attempted = tls_chlo_extractor.resumption_attempted();
-        early_data_attempted = tls_chlo_extractor.early_data_attempted();
-      }
-    }
-    if (!has_full_tls_chlo) {
-      // This packet does not contain a full CHLO. It could be a 0-RTT
-      // packet that arrived before the CHLO (due to loss or reordering),
-      // or it could be a fragment of a multi-packet CHLO.
-      BufferEarlyPacket(packet_info);
-      return absl::nullopt;
-    }
-
-    ParsedClientHello parsed_chlo;
-    parsed_chlo.sni = std::move(sni);
-    parsed_chlo.alpns = std::move(alpns);
-    if (packet_info.retry_token.has_value()) {
-      parsed_chlo.retry_token = std::string(*packet_info.retry_token);
-    }
-    parsed_chlo.resumption_attempted = resumption_attempted;
-    parsed_chlo.early_data_attempted = early_data_attempted;
-    return parsed_chlo;
-  }
-
-  ChloAlpnSniExtractor alpn_extractor;
-  if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
-      !ChloExtractor::Extract(packet_info.packet, packet_info.version,
-                              config_->create_session_tag_indicators(),
-                              &alpn_extractor,
-                              packet_info.destination_connection_id.length())) {
-    // Buffer non-CHLO packets.
-    BufferEarlyPacket(packet_info);
-    return absl::nullopt;
-  }
-
-  // We only apply this check for versions that do not use the IETF
-  // invariant header because those versions are already checked in
-  // QuicDispatcher::MaybeDispatchPacket.
-  if (packet_info.version_flag &&
-      !packet_info.version.HasIetfInvariantHeader() &&
-      crypto_config()->validate_chlo_size() &&
-      packet_info.packet.length() < kMinClientInitialPacketLength) {
-    QUIC_DVLOG(1) << "Dropping CHLO packet which is too short, length: "
-                  << packet_info.packet.length();
-    QUIC_CODE_COUNT(quic_drop_small_chlo_packets);
-    return absl::nullopt;
-  }
-
-  ParsedClientHello parsed_chlo;
-  parsed_chlo.legacy_version_encapsulation_inner_packet =
-      alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket();
-  parsed_chlo.sni = alpn_extractor.ConsumeSni();
-  parsed_chlo.uaid = alpn_extractor.ConsumeUaid();
-  parsed_chlo.alpns = {alpn_extractor.ConsumeAlpn()};
-  return parsed_chlo;
-}
-
-std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) {
-  if (alpns.empty()) {
-    return "";
-  }
-  if (alpns.size() > 1u) {
-    const std::vector<std::string>& supported_alpns =
-        version_manager_->GetSupportedAlpns();
-    for (const std::string& alpn : alpns) {
-      if (std::find(supported_alpns.begin(), supported_alpns.end(), alpn) !=
-          supported_alpns.end()) {
-        return alpn;
-      }
-    }
-  }
-  return alpns[0];
-}
-
-QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
-    const ReceivedPacketInfo& packet_info) {
-  if (!packet_info.version_flag) {
-    QUIC_DLOG(INFO)
-        << "Packet without version arrived for unknown connection ID "
-        << packet_info.destination_connection_id;
-    MaybeResetPacketsWithNoVersion(packet_info);
-    return kFateDrop;
-  }
-
-  // Let the connection parse and validate packet number.
-  return kFateProcess;
-}
-
-void QuicDispatcher::CleanUpSession(QuicConnectionId server_connection_id,
-                                    QuicConnection* connection,
-                                    QuicErrorCode /*error*/,
-                                    const std::string& /*error_details*/,
-                                    ConnectionCloseSource /*source*/) {
-  write_blocked_list_.erase(connection);
-  QuicTimeWaitListManager::TimeWaitAction action =
-      QuicTimeWaitListManager::SEND_STATELESS_RESET;
-  if (connection->termination_packets() != nullptr &&
-      !connection->termination_packets()->empty()) {
-    action = QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS;
-  } else {
-    if (!connection->IsHandshakeComplete()) {
-      // TODO(fayang): Do not serialize connection close packet if the
-      // connection is closed by the client.
-      if (!connection->version().HasIetfInvariantHeader()) {
-        QUIC_CODE_COUNT(gquic_add_to_time_wait_list_with_handshake_failed);
-      } else {
-        QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_handshake_failed);
-      }
-      // This serializes a connection close termination packet and adds the
-      // connection to the time wait list.
-      StatelessConnectionTerminator terminator(
-          server_connection_id, connection->version(), helper_.get(),
-          time_wait_list_manager_.get());
-      terminator.CloseConnection(
-          QUIC_HANDSHAKE_FAILED,
-          "Connection is closed by server before handshake confirmed",
-          connection->version().HasIetfInvariantHeader(),
-          connection->GetActiveServerConnectionIds());
-      return;
-    }
-    QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_stateless_reset);
-  }
-  time_wait_list_manager_->AddConnectionIdToTimeWait(
-      action,
-      TimeWaitConnectionInfo(
-          connection->version().HasIetfInvariantHeader(),
-          connection->termination_packets(),
-          connection->GetActiveServerConnectionIds(),
-          connection->sent_packet_manager().GetRttStats()->smoothed_rtt()));
-}
-
-void QuicDispatcher::StartAcceptingNewConnections() {
-  accept_new_connections_ = true;
-}
-
-void QuicDispatcher::StopAcceptingNewConnections() {
-  accept_new_connections_ = false;
-  // No more CHLO will arrive and buffered CHLOs shouldn't be able to create
-  // connections.
-  buffered_packets_.DiscardAllPackets();
-}
-
-void QuicDispatcher::PerformActionOnActiveSessions(
-    std::function<void(QuicSession*)> operation) const {
-  absl::flat_hash_set<QuicSession*> visited_session;
-  visited_session.reserve(reference_counted_session_map_.size());
-  for (auto const& kv : reference_counted_session_map_) {
-    QuicSession* session = kv.second.get();
-    if (visited_session.insert(session).second) {
-      operation(session);
-    }
-  }
-}
-
-// Get a snapshot of all sessions.
-std::vector<std::shared_ptr<QuicSession>> QuicDispatcher::GetSessionsSnapshot()
-    const {
-  std::vector<std::shared_ptr<QuicSession>> snapshot;
-  snapshot.reserve(reference_counted_session_map_.size());
-  absl::flat_hash_set<QuicSession*> visited_session;
-  visited_session.reserve(reference_counted_session_map_.size());
-  for (auto const& kv : reference_counted_session_map_) {
-    QuicSession* session = kv.second.get();
-    if (visited_session.insert(session).second) {
-      snapshot.push_back(kv.second);
-    }
-  }
-  return snapshot;
-}
-
-std::unique_ptr<QuicPerPacketContext> QuicDispatcher::GetPerPacketContext()
-    const {
-  return nullptr;
-}
-
-void QuicDispatcher::DeleteSessions() {
-  if (!write_blocked_list_.empty()) {
-    for (const auto& session : closed_session_list_) {
-      if (write_blocked_list_.erase(session->connection()) != 0) {
-        QUIC_BUG(quic_bug_12724_2)
-            << "QuicConnection was in WriteBlockedList before destruction "
-            << session->connection()->connection_id();
-      }
-    }
-  }
-  closed_session_list_.clear();
-}
-
-void QuicDispatcher::ClearStatelessResetAddresses() {
-  recent_stateless_reset_addresses_.clear();
-}
-
-void QuicDispatcher::OnCanWrite() {
-  // The socket is now writable.
-  writer_->SetWritable();
-
-  // Move every blocked writer in |write_blocked_list_| to a temporary list.
-  const size_t num_blocked_writers_before = write_blocked_list_.size();
-  WriteBlockedList temp_list;
-  temp_list.swap(write_blocked_list_);
-  QUICHE_DCHECK(write_blocked_list_.empty());
-
-  // Give each blocked writer a chance to write what they indended to write.
-  // If they are blocked again, they will call |OnWriteBlocked| to add
-  // themselves back into |write_blocked_list_|.
-  while (!temp_list.empty()) {
-    QuicBlockedWriterInterface* blocked_writer = temp_list.begin()->first;
-    temp_list.erase(temp_list.begin());
-    blocked_writer->OnBlockedWriterCanWrite();
-  }
-  const size_t num_blocked_writers_after = write_blocked_list_.size();
-  if (num_blocked_writers_after != 0) {
-    if (num_blocked_writers_before == num_blocked_writers_after) {
-      QUIC_CODE_COUNT(quic_zero_progress_on_can_write);
-    } else {
-      QUIC_CODE_COUNT(quic_blocked_again_on_can_write);
-    }
-  }
-}
-
-bool QuicDispatcher::HasPendingWrites() const {
-  return !write_blocked_list_.empty();
-}
-
-void QuicDispatcher::Shutdown() {
-  while (!reference_counted_session_map_.empty()) {
-    QuicSession* session = reference_counted_session_map_.begin()->second.get();
-    session->connection()->CloseConnection(
-        QUIC_PEER_GOING_AWAY, "Server shutdown imminent",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    // Validate that the session removes itself from the session map on close.
-    QUICHE_DCHECK(reference_counted_session_map_.empty() ||
-                  reference_counted_session_map_.begin()->second.get() !=
-                      session);
-  }
-  DeleteSessions();
-}
-
-void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
-                                        QuicErrorCode error,
-                                        const std::string& error_details,
-                                        ConnectionCloseSource source) {
-  auto it = reference_counted_session_map_.find(server_connection_id);
-  if (it == reference_counted_session_map_.end()) {
-    QUIC_BUG(quic_bug_10287_3) << "ConnectionId " << server_connection_id
-                               << " does not exist in the session map.  Error: "
-                               << QuicErrorCodeToString(error);
-    QUIC_BUG(quic_bug_10287_4) << QuicStackTrace();
-    return;
-  }
-
-  QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
-      << "Closing connection (" << server_connection_id
-      << ") due to error: " << QuicErrorCodeToString(error)
-      << ", with details: " << error_details;
-
-  QuicConnection* connection = it->second->connection();
-  if (ShouldDestroySessionAsynchronously()) {
-    // Set up alarm to fire immediately to bring destruction of this session
-    // out of current call stack.
-    if (closed_session_list_.empty()) {
-      delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(),
-                                     QuicTime::Delta::Zero());
-    }
-    closed_session_list_.push_back(std::move(it->second));
-  }
-  CleanUpSession(it->first, connection, error, error_details, source);
-  for (const QuicConnectionId& cid :
-       connection->GetActiveServerConnectionIds()) {
-    reference_counted_session_map_.erase(cid);
-  }
-  --num_sessions_in_session_map_;
-}
-
-void QuicDispatcher::OnWriteBlocked(
-    QuicBlockedWriterInterface* blocked_writer) {
-  if (!blocked_writer->IsWriterBlocked()) {
-    // It is a programming error if this ever happens. When we are sure it is
-    // not happening, replace it with a QUICHE_DCHECK.
-    QUIC_BUG(quic_bug_12724_4)
-        << "Tried to add writer into blocked list when it shouldn't be added";
-    // Return without adding the connection to the blocked list, to avoid
-    // infinite loops in OnCanWrite.
-    return;
-  }
-
-  write_blocked_list_.insert(std::make_pair(blocked_writer, true));
-}
-
-void QuicDispatcher::OnRstStreamReceived(const QuicRstStreamFrame& /*frame*/) {}
-
-void QuicDispatcher::OnStopSendingReceived(
-    const QuicStopSendingFrame& /*frame*/) {}
-
-void QuicDispatcher::OnNewConnectionIdSent(
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& new_connection_id) {
-  auto it = reference_counted_session_map_.find(server_connection_id);
-  if (it == reference_counted_session_map_.end()) {
-    QUIC_BUG(quic_bug_10287_7)
-        << "Couldn't locate the session that issues the connection ID in "
-           "reference_counted_session_map_.  server_connection_id:"
-        << server_connection_id << " new_connection_id: " << new_connection_id;
-    return;
-  }
-  // Count new connection ID added to the dispatcher map.
-  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 6, 6);
-  auto insertion_result = reference_counted_session_map_.insert(
-      std::make_pair(new_connection_id, it->second));
-  QUICHE_DCHECK(insertion_result.second);
-}
-
-void QuicDispatcher::OnConnectionIdRetired(
-    const QuicConnectionId& server_connection_id) {
-  reference_counted_session_map_.erase(server_connection_id);
-}
-
-void QuicDispatcher::OnConnectionAddedToTimeWaitList(
-    QuicConnectionId server_connection_id) {
-  QUIC_DLOG(INFO) << "Connection " << server_connection_id
-                  << " added to time wait list.";
-}
-
-void QuicDispatcher::StatelesslyTerminateConnection(
-    QuicConnectionId server_connection_id,
-    PacketHeaderFormat format,
-    bool version_flag,
-    bool use_length_prefix,
-    ParsedQuicVersion version,
-    QuicErrorCode error_code,
-    const std::string& error_details,
-    QuicTimeWaitListManager::TimeWaitAction action) {
-  if (format != IETF_QUIC_LONG_HEADER_PACKET && !version_flag) {
-    QUIC_DVLOG(1) << "Statelessly terminating " << server_connection_id
-                  << " based on a non-ietf-long packet, action:" << action
-                  << ", error_code:" << error_code
-                  << ", error_details:" << error_details;
-    time_wait_list_manager_->AddConnectionIdToTimeWait(
-        action, TimeWaitConnectionInfo(format != GOOGLE_QUIC_PACKET, nullptr,
-                                       {server_connection_id}));
-    return;
-  }
-
-  // If the version is known and supported by framer, send a connection close.
-  if (IsSupportedVersion(version)) {
-    QUIC_DVLOG(1)
-        << "Statelessly terminating " << server_connection_id
-        << " based on an ietf-long packet, which has a supported version:"
-        << version << ", error_code:" << error_code
-        << ", error_details:" << error_details;
-
-    StatelessConnectionTerminator terminator(server_connection_id, version,
-                                             helper_.get(),
-                                             time_wait_list_manager_.get());
-    // This also adds the connection to time wait list.
-    terminator.CloseConnection(
-        error_code, error_details, format != GOOGLE_QUIC_PACKET,
-        /*active_connection_ids=*/{server_connection_id});
-    QUIC_CODE_COUNT(quic_dispatcher_generated_connection_close);
-    QuicSession::RecordConnectionCloseAtServer(
-        error_code, ConnectionCloseSource::FROM_SELF);
-    return;
-  }
-
-  QUIC_DVLOG(1)
-      << "Statelessly terminating " << server_connection_id
-      << " based on an ietf-long packet, which has an unsupported version:"
-      << version << ", error_code:" << error_code
-      << ", error_details:" << error_details;
-  // Version is unknown or unsupported by framer, send a version negotiation
-  // with an empty version list, which can be understood by the client.
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(QuicFramer::BuildVersionNegotiationPacket(
-      server_connection_id, EmptyQuicConnectionId(),
-      /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, use_length_prefix,
-      /*versions=*/{}));
-  time_wait_list_manager()->AddConnectionIdToTimeWait(
-      QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
-      TimeWaitConnectionInfo(/*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
-                             &termination_packets, {server_connection_id}));
-}
-
-bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
-    QuicVersionLabel /*version_label*/) {
-  return false;
-}
-
-void QuicDispatcher::OnExpiredPackets(
-    QuicConnectionId server_connection_id,
-    BufferedPacketList early_arrived_packets) {
-  QUIC_CODE_COUNT(quic_reject_buffered_packets_expired);
-  StatelesslyTerminateConnection(
-      server_connection_id,
-      early_arrived_packets.ietf_quic ? IETF_QUIC_LONG_HEADER_PACKET
-                                      : GOOGLE_QUIC_PACKET,
-      /*version_flag=*/true,
-      early_arrived_packets.version.HasLengthPrefixedConnectionIds(),
-      early_arrived_packets.version, QUIC_HANDSHAKE_FAILED,
-      "Packets buffered for too long",
-      quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
-}
-
-void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
-  // Reset the counter before starting creating connections.
-  new_sessions_allowed_per_event_loop_ = max_connections_to_create;
-  for (; new_sessions_allowed_per_event_loop_ > 0;
-       --new_sessions_allowed_per_event_loop_) {
-    QuicConnectionId server_connection_id;
-    BufferedPacketList packet_list =
-        buffered_packets_.DeliverPacketsForNextConnection(
-            &server_connection_id);
-    const std::list<BufferedPacket>& packets = packet_list.buffered_packets;
-    if (packets.empty()) {
-      return;
-    }
-    if (!packet_list.parsed_chlo.has_value()) {
-      QUIC_BUG(quic_dispatcher_no_parsed_chlo_in_buffered_packets)
-          << "Buffered connection has no CHLO. connection_id:"
-          << server_connection_id;
-      continue;
-    }
-    const ParsedClientHello& parsed_chlo = *packet_list.parsed_chlo;
-    QuicConnectionId original_connection_id = server_connection_id;
-    server_connection_id = MaybeReplaceServerConnectionId(server_connection_id,
-                                                          packet_list.version);
-    std::string alpn = SelectAlpn(parsed_chlo.alpns);
-    std::unique_ptr<QuicSession> session = CreateQuicSession(
-        server_connection_id, packets.front().self_address,
-        packets.front().peer_address, alpn, packet_list.version, parsed_chlo);
-    if (original_connection_id != server_connection_id) {
-      session->connection()->SetOriginalDestinationConnectionId(
-          original_connection_id);
-    }
-    QUIC_DLOG(INFO) << "Created new session for " << server_connection_id;
-
-    auto insertion_result = reference_counted_session_map_.insert(
-        std::make_pair(server_connection_id,
-                       std::shared_ptr<QuicSession>(std::move(session))));
-    if (!insertion_result.second) {
-      QUIC_BUG(quic_bug_12724_5)
-          << "Tried to add a session to session_map with existing connection "
-             "id: "
-          << server_connection_id;
-    } else {
-      ++num_sessions_in_session_map_;
-    }
-    DeliverPacketsToSession(packets, insertion_result.first->second.get());
-  }
-}
-
-bool QuicDispatcher::HasChlosBuffered() const {
-  return buffered_packets_.HasChlosBuffered();
-}
-
-bool QuicDispatcher::ShouldCreateOrBufferPacketForConnection(
-    const ReceivedPacketInfo& packet_info) {
-  QUIC_VLOG(1) << "Received packet from new connection "
-               << packet_info.destination_connection_id;
-  return true;
-}
-
-// Return true if there is any packet buffered in the store.
-bool QuicDispatcher::HasBufferedPackets(QuicConnectionId server_connection_id) {
-  return buffered_packets_.HasBufferedPackets(server_connection_id);
-}
-
-void QuicDispatcher::OnBufferPacketFailure(
-    EnqueuePacketResult result,
-    QuicConnectionId server_connection_id) {
-  QUIC_DLOG(INFO) << "Fail to buffer packet on connection "
-                  << server_connection_id << " because of " << result;
-}
-
-QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
-  return new QuicTimeWaitListManager(writer_.get(), this, helper_->GetClock(),
-                                     alarm_factory_.get());
-}
-
-void QuicDispatcher::BufferEarlyPacket(const ReceivedPacketInfo& packet_info) {
-  bool is_new_connection = !buffered_packets_.HasBufferedPackets(
-      packet_info.destination_connection_id);
-  if (is_new_connection &&
-      !ShouldCreateOrBufferPacketForConnection(packet_info)) {
-    return;
-  }
-
-  EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
-      packet_info.destination_connection_id,
-      packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet,
-      packet_info.self_address, packet_info.peer_address, packet_info.version,
-      /*parsed_chlo=*/absl::nullopt);
-  if (rs != EnqueuePacketResult::SUCCESS) {
-    OnBufferPacketFailure(rs, packet_info.destination_connection_id);
-  }
-}
-
-void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
-                                 ReceivedPacketInfo* packet_info) {
-  if (!buffered_packets_.HasBufferedPackets(
-          packet_info->destination_connection_id) &&
-      !ShouldCreateOrBufferPacketForConnection(*packet_info)) {
-    return;
-  }
-  if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
-      new_sessions_allowed_per_event_loop_ <= 0) {
-    // Can't create new session any more. Wait till next event loop.
-    QUIC_BUG_IF(quic_bug_12724_7, buffered_packets_.HasChloForConnection(
-                                      packet_info->destination_connection_id));
-    EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
-        packet_info->destination_connection_id,
-        packet_info->form != GOOGLE_QUIC_PACKET, packet_info->packet,
-        packet_info->self_address, packet_info->peer_address,
-        packet_info->version, std::move(parsed_chlo));
-    if (rs != EnqueuePacketResult::SUCCESS) {
-      OnBufferPacketFailure(rs, packet_info->destination_connection_id);
-    }
-    return;
-  }
-
-  QuicConnectionId original_connection_id =
-      packet_info->destination_connection_id;
-  packet_info->destination_connection_id = MaybeReplaceServerConnectionId(
-      original_connection_id, packet_info->version);
-  // Creates a new session and process all buffered packets for this connection.
-  std::string alpn = SelectAlpn(parsed_chlo.alpns);
-  std::unique_ptr<QuicSession> session = CreateQuicSession(
-      packet_info->destination_connection_id, packet_info->self_address,
-      packet_info->peer_address, alpn, packet_info->version, parsed_chlo);
-  if (QUIC_PREDICT_FALSE(session == nullptr)) {
-    QUIC_BUG(quic_bug_10287_8)
-        << "CreateQuicSession returned nullptr for "
-        << packet_info->destination_connection_id << " from "
-        << packet_info->peer_address << " to " << packet_info->self_address
-        << " ALPN \"" << alpn << "\" version " << packet_info->version;
-    return;
-  }
-  if (original_connection_id != packet_info->destination_connection_id) {
-    session->connection()->SetOriginalDestinationConnectionId(
-        original_connection_id);
-  }
-  QUIC_DLOG(INFO) << "Created new session for "
-                  << packet_info->destination_connection_id;
-
-  QuicSession* session_ptr;
-  auto insertion_result = reference_counted_session_map_.insert(std::make_pair(
-      packet_info->destination_connection_id,
-      std::shared_ptr<QuicSession>(std::move(session.release()))));
-  if (!insertion_result.second) {
-    QUIC_BUG(quic_bug_10287_9)
-        << "Tried to add a session to session_map with existing "
-           "connection id: "
-        << packet_info->destination_connection_id;
-  } else {
-    ++num_sessions_in_session_map_;
-  }
-  session_ptr = insertion_result.first->second.get();
-  std::list<BufferedPacket> packets =
-      buffered_packets_.DeliverPackets(packet_info->destination_connection_id)
-          .buffered_packets;
-  // Process CHLO at first.
-  session_ptr->ProcessUdpPacket(packet_info->self_address,
-                                packet_info->peer_address, packet_info->packet);
-  // Deliver queued-up packets in the same order as they arrived.
-  // Do this even when flag is off because there might be still some packets
-  // buffered in the store before flag is turned off.
-  DeliverPacketsToSession(packets, session_ptr);
-  --new_sessions_allowed_per_event_loop_;
-}
-
-bool QuicDispatcher::ShouldDestroySessionAsynchronously() {
-  return true;
-}
-
-void QuicDispatcher::SetLastError(QuicErrorCode error) {
-  last_error_ = error;
-}
-
-bool QuicDispatcher::OnFailedToDispatchPacket(
-    const ReceivedPacketInfo& /*packet_info*/) {
-  return false;
-}
-
-const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
-  return version_manager_->GetSupportedVersions();
-}
-
-void QuicDispatcher::DeliverPacketsToSession(
-    const std::list<BufferedPacket>& packets,
-    QuicSession* session) {
-  for (const BufferedPacket& packet : packets) {
-    session->ProcessUdpPacket(packet.self_address, packet.peer_address,
-                              *(packet.packet));
-  }
-}
-
-bool QuicDispatcher::IsSupportedVersion(const ParsedQuicVersion version) {
-  for (const ParsedQuicVersion& supported_version :
-       version_manager_->GetSupportedVersions()) {
-    if (version == supported_version) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void QuicDispatcher::MaybeResetPacketsWithNoVersion(
-    const ReceivedPacketInfo& packet_info) {
-  QUICHE_DCHECK(!packet_info.version_flag);
-  // Do not send a stateless reset if a reset has been sent to this address
-  // recently.
-  if (recent_stateless_reset_addresses_.contains(packet_info.peer_address)) {
-    QUIC_CODE_COUNT(quic_donot_send_reset_repeatedly);
-    QUICHE_DCHECK(use_recent_reset_addresses_);
-    return;
-  }
-  if (packet_info.form != GOOGLE_QUIC_PACKET) {
-    // Drop IETF packets smaller than the minimal stateless reset length.
-    if (packet_info.packet.length() <=
-        QuicFramer::GetMinStatelessResetPacketLength()) {
-      QUIC_CODE_COUNT(quic_drop_too_small_short_header_packets);
-      return;
-    }
-  } else {
-    const size_t MinValidPacketLength =
-        kPacketHeaderTypeSize + expected_server_connection_id_length_ +
-        PACKET_1BYTE_PACKET_NUMBER + /*payload size=*/1 + /*tag size=*/12;
-    if (packet_info.packet.length() < MinValidPacketLength) {
-      // The packet size is too small.
-      QUIC_CODE_COUNT(drop_too_small_packets);
-      return;
-    }
-  }
-  if (use_recent_reset_addresses_) {
-    QUIC_RESTART_FLAG_COUNT(quic_use_recent_reset_addresses);
-    // Do not send a stateless reset if there are too many stateless reset
-    // addresses.
-    if (recent_stateless_reset_addresses_.size() >=
-        GetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses)) {
-      QUIC_CODE_COUNT(quic_too_many_recent_reset_addresses);
-      return;
-    }
-    if (recent_stateless_reset_addresses_.empty()) {
-      clear_stateless_reset_addresses_alarm_->Update(
-          helper()->GetClock()->ApproximateNow() +
-              QuicTime::Delta::FromMilliseconds(GetQuicFlag(
-                  FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms)),
-          QuicTime::Delta::Zero());
-    }
-    recent_stateless_reset_addresses_.emplace(packet_info.peer_address);
-  }
-
-  time_wait_list_manager()->SendPublicReset(
-      packet_info.self_address, packet_info.peer_address,
-      packet_info.destination_connection_id,
-      packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet.length(),
-      GetPerPacketContext());
-}
-
-size_t QuicDispatcher::NumSessions() const {
-  return num_sessions_in_session_map_;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_dispatcher.h b/quic/core/quic_dispatcher.h
deleted file mode 100644
index 72ea5cd..0000000
--- a/quic/core/quic_dispatcher.h
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A server side dispatcher which dispatches a given client's data to their
-// stream.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
-#define QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
-
-#include <cstddef>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_blocked_writer_interface.h"
-#include "quic/core/quic_buffered_packet_store.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_process_packet_interface.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/core/quic_version_manager.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_reference_counted.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-namespace test {
-class QuicDispatcherPeer;
-}  // namespace test
-
-class QuicConfig;
-class QuicCryptoServerConfig;
-
-class QUIC_NO_EXPORT QuicDispatcher
-    : public QuicTimeWaitListManager::Visitor,
-      public ProcessPacketInterface,
-      public QuicBufferedPacketStore::VisitorInterface {
- public:
-  // Ideally we'd have a linked_hash_set: the  boolean is unused.
-  using WriteBlockedList =
-      quiche::QuicheLinkedHashMap<QuicBlockedWriterInterface*, bool>;
-
-  QuicDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      uint8_t expected_server_connection_id_length);
-  QuicDispatcher(const QuicDispatcher&) = delete;
-  QuicDispatcher& operator=(const QuicDispatcher&) = delete;
-
-  ~QuicDispatcher() override;
-
-  // Takes ownership of |writer|.
-  void InitializeWithWriter(QuicPacketWriter* writer);
-
-  // Process the incoming packet by creating a new session, passing it to
-  // an existing session, or passing it to the time wait list.
-  void ProcessPacket(const QuicSocketAddress& self_address,
-                     const QuicSocketAddress& peer_address,
-                     const QuicReceivedPacket& packet) override;
-
-  // Called when the socket becomes writable to allow queued writes to happen.
-  virtual void OnCanWrite();
-
-  // Returns true if there's anything in the blocked writer list.
-  virtual bool HasPendingWrites() const;
-
-  // Sends ConnectionClose frames to all connected clients.
-  void Shutdown();
-
-  // QuicSession::Visitor interface implementation (via inheritance of
-  // QuicTimeWaitListManager::Visitor):
-  // Ensure that the closed connection is cleaned up asynchronously.
-  void OnConnectionClosed(QuicConnectionId server_connection_id,
-                          QuicErrorCode error,
-                          const std::string& error_details,
-                          ConnectionCloseSource source) override;
-
-  // QuicSession::Visitor interface implementation (via inheritance of
-  // QuicTimeWaitListManager::Visitor):
-  // Queues the blocked writer for later resumption.
-  void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
-
-  // QuicSession::Visitor interface implementation (via inheritance of
-  // QuicTimeWaitListManager::Visitor):
-  // Collects reset error code received on streams.
-  void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
-
-  // QuicSession::Visitor interface implementation (via inheritance of
-  // QuicTimeWaitListManager::Visitor):
-  // Collects reset error code received on streams.
-  void OnStopSendingReceived(const QuicStopSendingFrame& frame) override;
-
-  // QuicSession::Visitor interface implementation (via inheritance of
-  // QuicTimeWaitListManager::Visitor):
-  // Add the newly issued connection ID to the session map.
-  void OnNewConnectionIdSent(
-      const QuicConnectionId& server_connection_id,
-      const QuicConnectionId& new_connection_id) override;
-
-  // QuicSession::Visitor interface implementation (via inheritance of
-  // QuicTimeWaitListManager::Visitor):
-  // Remove the retired connection ID from the session map.
-  void OnConnectionIdRetired(
-      const QuicConnectionId& server_connection_id) override;
-
-  // QuicTimeWaitListManager::Visitor interface implementation
-  // Called whenever the time wait list manager adds a new connection to the
-  // time-wait list.
-  void OnConnectionAddedToTimeWaitList(
-      QuicConnectionId server_connection_id) override;
-
-  using ReferenceCountedSessionMap =
-      absl::flat_hash_map<QuicConnectionId,
-                          std::shared_ptr<QuicSession>,
-                          QuicConnectionIdHash>;
-
-  size_t NumSessions() const;
-
-  // Deletes all sessions on the closed session list and clears the list.
-  virtual void DeleteSessions();
-
-  // Clear recent_stateless_reset_addresses_.
-  void ClearStatelessResetAddresses();
-
-  using ConnectionIdMap = absl::
-      flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>;
-
-  // QuicBufferedPacketStore::VisitorInterface implementation.
-  void OnExpiredPackets(QuicConnectionId server_connection_id,
-                        QuicBufferedPacketStore::BufferedPacketList
-                            early_arrived_packets) override;
-
-  // Create connections for previously buffered CHLOs as many as allowed.
-  virtual void ProcessBufferedChlos(size_t max_connections_to_create);
-
-  // Return true if there is CHLO buffered.
-  virtual bool HasChlosBuffered() const;
-
-  // Start accepting new ConnectionIds.
-  void StartAcceptingNewConnections();
-
-  // Stop accepting new ConnectionIds, either as a part of the lame
-  // duck process or because explicitly configured.
-  void StopAcceptingNewConnections();
-
-  // Apply an operation for each session.
-  void PerformActionOnActiveSessions(
-      std::function<void(QuicSession*)> operation) const;
-
-  // Get a snapshot of all sessions.
-  std::vector<std::shared_ptr<QuicSession>> GetSessionsSnapshot() const;
-
-  bool accept_new_connections() const { return accept_new_connections_; }
-
- protected:
-  // Creates a QUIC session based on the given information.
-  // |alpn| is the selected ALPN from |parsed_chlo.alpns|.
-  virtual std::unique_ptr<QuicSession> CreateQuicSession(
-      QuicConnectionId server_connection_id,
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address, absl::string_view alpn,
-      const ParsedQuicVersion& version,
-      const ParsedClientHello& parsed_chlo) = 0;
-
-  // Tries to validate and dispatch packet based on available information.
-  // Returns true if packet is dropped or successfully dispatched (e.g.,
-  // processed by existing session, processed by time wait list, etc.),
-  // otherwise, returns false and the packet needs further processing.
-  virtual bool MaybeDispatchPacket(const ReceivedPacketInfo& packet_info);
-
-  // Generate a connection ID with a length that is expected by the dispatcher.
-  // Called only when |server_connection_id| is shorter than
-  // |expected_connection_id_length|.
-  // Note that this MUST produce a deterministic result (calling this method
-  // with two connection IDs that are equal must produce the same result).
-  // Note that this is not used in general operation because our default
-  // |expected_server_connection_id_length| is 8, and the IETF specification
-  // requires clients to use an initial length of at least 8. However, we
-  // allow disabling that requirement via
-  // |allow_short_initial_server_connection_ids_|.
-  virtual QuicConnectionId ReplaceShortServerConnectionId(
-      const ParsedQuicVersion& version,
-      const QuicConnectionId& server_connection_id,
-      uint8_t expected_server_connection_id_length) const;
-
-  // Generate a connection ID with a length that is expected by the dispatcher.
-  // Called only when |server_connection_id| is longer than
-  // |expected_connection_id_length|.
-  // Note that this MUST produce a deterministic result (calling this method
-  // with two connection IDs that are equal must produce the same result).
-  virtual QuicConnectionId ReplaceLongServerConnectionId(
-      const ParsedQuicVersion& version,
-      const QuicConnectionId& server_connection_id,
-      uint8_t expected_server_connection_id_length) const;
-
-  // Values to be returned by ValidityChecks() to indicate what should be done
-  // with a packet. Fates with greater values are considered to be higher
-  // priority. ValidityChecks should return fate based on the priority order
-  // (i.e., returns higher priority fate first)
-  enum QuicPacketFate {
-    // Process the packet normally, which is usually to establish a connection.
-    kFateProcess,
-    // Put the connection ID into time-wait state and send a public reset.
-    kFateTimeWait,
-    // Drop the packet.
-    kFateDrop,
-  };
-
-  // This method is called by ProcessHeader on packets not associated with a
-  // known connection ID.  It applies validity checks and returns a
-  // QuicPacketFate to tell what should be done with the packet.
-  // TODO(fayang): Merge ValidityChecks into MaybeDispatchPacket.
-  virtual QuicPacketFate ValidityChecks(const ReceivedPacketInfo& packet_info);
-
-  // Extra validity checks after the full Client Hello is parsed, this allows
-  // subclasses to reject a connection based on sni or alpn.
-  // Only called if ValidityChecks returns kFateProcess.
-  virtual QuicPacketFate ValidityChecksOnFullChlo(
-      const ReceivedPacketInfo& /*packet_info*/,
-      const ParsedClientHello& /*parsed_chlo*/) const {
-    return kFateProcess;
-  }
-
-  // Create and return the time wait list manager for this dispatcher, which
-  // will be owned by the dispatcher as time_wait_list_manager_
-  virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
-
-  // Buffers packet until it can be delivered to a connection.
-  void BufferEarlyPacket(const ReceivedPacketInfo& packet_info);
-
-  // Called when |packet_info| is the last received packet of the client hello.
-  // |parsed_chlo| is the parsed version of the client hello. Creates a new
-  // connection and delivers any buffered packets for that connection id.
-  void ProcessChlo(ParsedClientHello parsed_chlo,
-                   ReceivedPacketInfo* packet_info);
-
-  // Return true if dispatcher wants to destroy session outside of
-  // OnConnectionClosed() call stack.
-  virtual bool ShouldDestroySessionAsynchronously();
-
-  QuicTimeWaitListManager* time_wait_list_manager() {
-    return time_wait_list_manager_.get();
-  }
-
-  const ParsedQuicVersionVector& GetSupportedVersions();
-
-  const QuicConfig& config() const { return *config_; }
-
-  const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
-
-  QuicCompressedCertsCache* compressed_certs_cache() {
-    return &compressed_certs_cache_;
-  }
-
-  QuicConnectionHelperInterface* helper() { return helper_.get(); }
-
-  QuicCryptoServerStreamBase::Helper* session_helper() {
-    return session_helper_.get();
-  }
-
-  const QuicCryptoServerStreamBase::Helper* session_helper() const {
-    return session_helper_.get();
-  }
-
-  QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
-
-  QuicPacketWriter* writer() { return writer_.get(); }
-
-  // Returns true if a session should be created for a connection with an
-  // unknown version identified by |version_label|.
-  virtual bool ShouldCreateSessionForUnknownVersion(
-      QuicVersionLabel version_label);
-
-  void SetLastError(QuicErrorCode error);
-
-  // Called by MaybeDispatchPacket when current packet cannot be dispatched.
-  // Used by subclasses to conduct specific logic to dispatch packet. Returns
-  // true if packet is successfully dispatched.
-  virtual bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info);
-
-  // Called when a new connection starts to be handled by this dispatcher.
-  // Either this connection is created or its packets is buffered while waiting
-  // for CHLO. Returns true if a new connection should be created or its packets
-  // should be buffered, false otherwise.
-  virtual bool ShouldCreateOrBufferPacketForConnection(
-      const ReceivedPacketInfo& packet_info);
-
-  bool HasBufferedPackets(QuicConnectionId server_connection_id);
-
-  // Called when BufferEarlyPacket() fail to buffer the packet.
-  virtual void OnBufferPacketFailure(
-      QuicBufferedPacketStore::EnqueuePacketResult result,
-      QuicConnectionId server_connection_id);
-
-  // Removes the session from the write blocked list, and adds the ConnectionId
-  // to the time-wait list.  The caller needs to manually remove the session
-  // from the map after that.
-  void CleanUpSession(QuicConnectionId server_connection_id,
-                      QuicConnection* connection,
-                      QuicErrorCode error,
-                      const std::string& error_details,
-                      ConnectionCloseSource source);
-
-  // Called to terminate a connection statelessly. Depending on |format|, either
-  // 1) send connection close with |error_code| and |error_details| and add
-  // connection to time wait list or 2) directly add connection to time wait
-  // list with |action|.
-  void StatelesslyTerminateConnection(
-      QuicConnectionId server_connection_id,
-      PacketHeaderFormat format,
-      bool version_flag,
-      bool use_length_prefix,
-      ParsedQuicVersion version,
-      QuicErrorCode error_code,
-      const std::string& error_details,
-      QuicTimeWaitListManager::TimeWaitAction action);
-
-  // Save/Restore per packet context.
-  virtual std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const;
-  virtual void RestorePerPacketContext(
-      std::unique_ptr<QuicPerPacketContext> /*context*/) {}
-
-  // If true, our framer will change its expected connection ID length
-  // to the received destination connection ID length of all IETF long headers.
-  void SetShouldUpdateExpectedServerConnectionIdLength(
-      bool should_update_expected_server_connection_id_length) {
-    should_update_expected_server_connection_id_length_ =
-        should_update_expected_server_connection_id_length;
-  }
-
-  // If true, the dispatcher will allow incoming initial packets that have
-  // destination connection IDs shorter than 64 bits.
-  void SetAllowShortInitialServerConnectionIds(
-      bool allow_short_initial_server_connection_ids) {
-    allow_short_initial_server_connection_ids_ =
-        allow_short_initial_server_connection_ids;
-  }
-
-  // Called if a packet from an unseen connection is reset or rejected.
-  virtual void OnNewConnectionRejected() {}
-
-  // Selects the preferred ALPN from a vector of ALPNs.
-  // This runs through the list of ALPNs provided by the client and picks the
-  // first one it supports. If no supported versions are found, the first
-  // element of the vector is returned.
-  std::string SelectAlpn(const std::vector<std::string>& alpns);
-
-  // If the connection ID length is different from what the dispatcher expects,
-  // replace the connection ID with one of the right length.
-  // Note that this MUST produce a deterministic result (calling this method
-  // with two connection IDs that are equal must produce the same result).
-  QuicConnectionId MaybeReplaceServerConnectionId(
-      const QuicConnectionId& server_connection_id,
-      const ParsedQuicVersion& version) const;
-
-  // Sends public/stateless reset packets with no version and unknown
-  // connection ID according to the packet's size.
-  virtual void MaybeResetPacketsWithNoVersion(
-      const quic::ReceivedPacketInfo& packet_info);
-
- private:
-  friend class test::QuicDispatcherPeer;
-
-  // TODO(fayang): Consider to rename this function to
-  // ProcessValidatedPacketWithUnknownConnectionId.
-  void ProcessHeader(ReceivedPacketInfo* packet_info);
-
-  // Try to extract information(sni, alpns, ...) if the full Client Hello has
-  // been parsed.
-  //
-  // Return the parsed client hello if the full Client Hello has been
-  // successfully parsed.
-  //
-  // Otherwise return absl::nullopt and either buffer or (rarely) drop the
-  // packet.
-  absl::optional<ParsedClientHello> TryExtractChloOrBufferEarlyPacket(
-      const ReceivedPacketInfo& packet_info);
-
-  // Deliver |packets| to |session| for further processing.
-  void DeliverPacketsToSession(
-      const std::list<QuicBufferedPacketStore::BufferedPacket>& packets,
-      QuicSession* session);
-
-  // Returns true if |version| is a supported protocol version.
-  bool IsSupportedVersion(const ParsedQuicVersion version);
-
-  const QuicConfig* config_;
-
-  const QuicCryptoServerConfig* crypto_config_;
-
-  // The cache for most recently compressed certs.
-  QuicCompressedCertsCache compressed_certs_cache_;
-
-  // The list of connections waiting to write.
-  WriteBlockedList write_blocked_list_;
-
-  ReferenceCountedSessionMap reference_counted_session_map_;
-
-  // Entity that manages connection_ids in time wait state.
-  std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
-
-  // The list of closed but not-yet-deleted sessions.
-  std::vector<std::shared_ptr<QuicSession>> closed_session_list_;
-
-  // The helper used for all connections.
-  std::unique_ptr<QuicConnectionHelperInterface> helper_;
-
-  // The helper used for all sessions.
-  std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper_;
-
-  // Creates alarms.
-  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-
-  // An alarm which deletes closed sessions.
-  std::unique_ptr<QuicAlarm> delete_sessions_alarm_;
-
-  // The writer to write to the socket with.
-  std::unique_ptr<QuicPacketWriter> writer_;
-
-  // Packets which are buffered until a connection can be created to handle
-  // them.
-  QuicBufferedPacketStore buffered_packets_;
-
-  // Used to get the supported versions based on flag. Does not own.
-  QuicVersionManager* version_manager_;
-
-  // The last error set by SetLastError().
-  // TODO(fayang): consider removing last_error_.
-  QuicErrorCode last_error_;
-
-  // Number of unique session in session map.
-  size_t num_sessions_in_session_map_ = 0;
-
-  // A backward counter of how many new sessions can be create within current
-  // event loop. When reaches 0, it means can't create sessions for now.
-  int16_t new_sessions_allowed_per_event_loop_;
-
-  // True if this dispatcher is accepting new ConnectionIds (new client
-  // connections), false otherwise.
-  bool accept_new_connections_;
-
-  // If false, the dispatcher follows the IETF spec and rejects packets with
-  // invalid destination connection IDs lengths below 64 bits.
-  // If true they are allowed.
-  bool allow_short_initial_server_connection_ids_;
-
-  // IETF short headers contain a destination connection ID but do not
-  // encode its length. This variable contains the length we expect to read.
-  // This is also used to signal an error when a long header packet with
-  // different destination connection ID length is received when
-  // should_update_expected_server_connection_id_length_ is false and packet's
-  // version does not allow variable length connection ID.
-  uint8_t expected_server_connection_id_length_;
-
-  // Records client addresses that have been recently reset.
-  absl::flat_hash_set<QuicSocketAddress, QuicSocketAddressHash>
-      recent_stateless_reset_addresses_;
-
-  // An alarm which clear recent_stateless_reset_addresses_.
-  std::unique_ptr<QuicAlarm> clear_stateless_reset_addresses_alarm_;
-
-  // If true, change expected_server_connection_id_length_ to be the received
-  // destination connection ID length of all IETF long headers.
-  bool should_update_expected_server_connection_id_length_;
-
-  const bool use_recent_reset_addresses_ =
-      GetQuicRestartFlag(quic_use_recent_reset_addresses);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
deleted file mode 100644
index 2d5c78c..0000000
--- a/quic/core/quic_dispatcher_test.cc
+++ /dev/null
@@ -1,2914 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_dispatcher.h"
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/chlo_extractor.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_new_connection_id_frame.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/mock_quic_time_wait_list_manager.h"
-#include "quic/test_tools/quic_buffered_packet_store_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_time_wait_list_manager_peer.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-using testing::ByMove;
-using testing::Eq;
-using testing::InSequence;
-using testing::Invoke;
-using testing::NiceMock;
-using testing::Return;
-using testing::WithArg;
-using testing::WithoutArgs;
-
-static const size_t kDefaultMaxConnectionsInStore = 100;
-static const size_t kMaxConnectionsWithoutCHLO =
-    kDefaultMaxConnectionsInStore / 2;
-static const int16_t kMaxNumSessionsToCreate = 16;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestQuicSpdyServerSession : public QuicServerSessionBase {
- public:
-  TestQuicSpdyServerSession(const QuicConfig& config,
-                            QuicConnection* connection,
-                            const QuicCryptoServerConfig* crypto_config,
-                            QuicCompressedCertsCache* compressed_certs_cache)
-      : QuicServerSessionBase(config, CurrentSupportedVersions(), connection,
-                              nullptr, nullptr, crypto_config,
-                              compressed_certs_cache) {
-    Initialize();
-  }
-  TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
-  TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
-      delete;
-
-  ~TestQuicSpdyServerSession() override { DeleteConnection(); }
-
-  MOCK_METHOD(void, OnConnectionClosed,
-              (const QuicConnectionCloseFrame& frame,
-               ConnectionCloseSource source),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
-              (override));
-
-  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache) override {
-    return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
-                                    stream_helper());
-  }
-
-  QuicCryptoServerStreamBase::Helper* stream_helper() {
-    return QuicServerSessionBase::stream_helper();
-  }
-};
-
-class TestDispatcher : public QuicDispatcher {
- public:
-  TestDispatcher(const QuicConfig* config,
-                 const QuicCryptoServerConfig* crypto_config,
-                 QuicVersionManager* version_manager, QuicRandom* random)
-      : QuicDispatcher(config, crypto_config, version_manager,
-                       std::make_unique<MockQuicConnectionHelper>(),
-                       std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
-                           new QuicSimpleCryptoServerStreamHelper()),
-                       std::make_unique<TestAlarmFactory>(),
-                       kQuicDefaultConnectionIdLength),
-        random_(random) {}
-
-  MOCK_METHOD(std::unique_ptr<QuicSession>, CreateQuicSession,
-              (QuicConnectionId connection_id,
-               const QuicSocketAddress& self_address,
-               const QuicSocketAddress& peer_address, absl::string_view alpn,
-               const ParsedQuicVersion& version,
-               const ParsedClientHello& parsed_chlo),
-              (override));
-
-  MOCK_METHOD(bool, ShouldCreateOrBufferPacketForConnection,
-              (const ReceivedPacketInfo& packet_info), (override));
-
-  struct TestQuicPerPacketContext : public QuicPerPacketContext {
-    std::string custom_packet_context;
-  };
-
-  std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
-    auto test_context = std::make_unique<TestQuicPerPacketContext>();
-    test_context->custom_packet_context = custom_packet_context_;
-    return std::move(test_context);
-  }
-
-  void RestorePerPacketContext(
-      std::unique_ptr<QuicPerPacketContext> context) override {
-    TestQuicPerPacketContext* test_context =
-        static_cast<TestQuicPerPacketContext*>(context.get());
-    custom_packet_context_ = test_context->custom_packet_context;
-  }
-
-  std::string custom_packet_context_;
-
-  using QuicDispatcher::MaybeDispatchPacket;
-  using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
-  using QuicDispatcher::writer;
-
-  QuicRandom* random_;
-};
-
-// A Connection class which unregisters the session from the dispatcher when
-// sending connection close.
-// It'd be slightly more realistic to do this from the Session but it would
-// involve a lot more mocking.
-class MockServerConnection : public MockQuicConnection {
- public:
-  MockServerConnection(QuicConnectionId connection_id,
-                       MockQuicConnectionHelper* helper,
-                       MockAlarmFactory* alarm_factory,
-                       QuicDispatcher* dispatcher)
-      : MockQuicConnection(connection_id, helper, alarm_factory,
-                           Perspective::IS_SERVER),
-        dispatcher_(dispatcher),
-        active_connection_ids_({connection_id}) {}
-
-  void AddNewConnectionId(QuicConnectionId id) {
-    dispatcher_->OnNewConnectionIdSent(active_connection_ids_.back(), id);
-    QuicConnectionPeer::SetServerConnectionId(this, id);
-    active_connection_ids_.push_back(id);
-  }
-
-  void RetireConnectionId(QuicConnectionId id) {
-    auto it = std::find(active_connection_ids_.begin(),
-                        active_connection_ids_.end(), id);
-    QUICHE_DCHECK(it != active_connection_ids_.end());
-    dispatcher_->OnConnectionIdRetired(id);
-    active_connection_ids_.erase(it);
-  }
-
-  std::vector<QuicConnectionId> GetActiveServerConnectionIds() const override {
-    return active_connection_ids_;
-  }
-
-  void UnregisterOnConnectionClosed() {
-    QUIC_LOG(ERROR) << "Unregistering " << connection_id();
-    dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
-                                    "Unregistering.",
-                                    ConnectionCloseSource::FROM_SELF);
-  }
-
- private:
-  QuicDispatcher* dispatcher_;
-  std::vector<QuicConnectionId> active_connection_ids_;
-};
-
-class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  QuicDispatcherTestBase()
-      : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
-
-  explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
-      : version_(GetParam()),
-        version_manager_(AllSupportedVersions()),
-        crypto_config_(QuicCryptoServerConfig::TESTING,
-                       QuicRandom::GetInstance(), std::move(proof_source),
-                       KeyExchangeSource::Default()),
-        server_address_(QuicIpAddress::Any4(), 5),
-        dispatcher_(new NiceMock<TestDispatcher>(
-            &config_, &crypto_config_, &version_manager_,
-            mock_helper_.GetRandomGenerator())),
-        time_wait_list_manager_(nullptr),
-        session1_(nullptr),
-        session2_(nullptr),
-        store_(nullptr),
-        connection_id_(1) {}
-
-  void SetUp() override {
-    dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
-    // Set the counter to some value to start with.
-    QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
-        dispatcher_.get(), kMaxNumSessionsToCreate);
-    ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
-        .WillByDefault(Return(true));
-  }
-
-  MockQuicConnection* connection1() {
-    if (session1_ == nullptr) {
-      return nullptr;
-    }
-    return reinterpret_cast<MockQuicConnection*>(session1_->connection());
-  }
-
-  MockQuicConnection* connection2() {
-    if (session2_ == nullptr) {
-      return nullptr;
-    }
-    return reinterpret_cast<MockQuicConnection*>(session2_->connection());
-  }
-
-  // Process a packet with an 8 byte connection id,
-  // 6 byte packet number, default path id, and packet number 1,
-  // using the version under test.
-  void ProcessPacket(QuicSocketAddress peer_address,
-                     QuicConnectionId server_connection_id,
-                     bool has_version_flag, const std::string& data) {
-    ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
-                  CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
-  }
-
-  // Process a packet with a default path id, and packet number 1,
-  // using the version under test.
-  void ProcessPacket(QuicSocketAddress peer_address,
-                     QuicConnectionId server_connection_id,
-                     bool has_version_flag, const std::string& data,
-                     QuicConnectionIdIncluded server_connection_id_included,
-                     QuicPacketNumberLength packet_number_length) {
-    ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
-                  server_connection_id_included, packet_number_length, 1);
-  }
-
-  // Process a packet using the version under test.
-  void ProcessPacket(QuicSocketAddress peer_address,
-                     QuicConnectionId server_connection_id,
-                     bool has_version_flag, const std::string& data,
-                     QuicConnectionIdIncluded server_connection_id_included,
-                     QuicPacketNumberLength packet_number_length,
-                     uint64_t packet_number) {
-    ProcessPacket(peer_address, server_connection_id, has_version_flag,
-                  version_, data, true, server_connection_id_included,
-                  packet_number_length, packet_number);
-  }
-
-  // Processes a packet.
-  void ProcessPacket(QuicSocketAddress peer_address,
-                     QuicConnectionId server_connection_id,
-                     bool has_version_flag, ParsedQuicVersion version,
-                     const std::string& data, bool full_padding,
-                     QuicConnectionIdIncluded server_connection_id_included,
-                     QuicPacketNumberLength packet_number_length,
-                     uint64_t packet_number) {
-    ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
-                  has_version_flag, version, data, full_padding,
-                  server_connection_id_included, CONNECTION_ID_ABSENT,
-                  packet_number_length, packet_number);
-  }
-
-  // Processes a packet.
-  void ProcessPacket(QuicSocketAddress peer_address,
-                     QuicConnectionId server_connection_id,
-                     QuicConnectionId client_connection_id,
-                     bool has_version_flag, ParsedQuicVersion version,
-                     const std::string& data, bool full_padding,
-                     QuicConnectionIdIncluded server_connection_id_included,
-                     QuicConnectionIdIncluded client_connection_id_included,
-                     QuicPacketNumberLength packet_number_length,
-                     uint64_t packet_number) {
-    ParsedQuicVersionVector versions(SupportedVersions(version));
-    std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-        server_connection_id, client_connection_id, has_version_flag, false,
-        packet_number, data, full_padding, server_connection_id_included,
-        client_connection_id_included, packet_number_length, &versions));
-    std::unique_ptr<QuicReceivedPacket> received_packet(
-        ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
-    ProcessReceivedPacket(std::move(received_packet), peer_address, version,
-                          server_connection_id);
-  }
-
-  void ProcessReceivedPacket(
-      std::unique_ptr<QuicReceivedPacket> received_packet,
-      const QuicSocketAddress& peer_address, const ParsedQuicVersion& version,
-      const QuicConnectionId& server_connection_id) {
-    if (version.UsesQuicCrypto() &&
-        ChloExtractor::Extract(*received_packet, version, {}, nullptr,
-                               server_connection_id.length())) {
-      // Add CHLO packet to the beginning to be verified first, because it is
-      // also processed first by new session.
-      data_connection_map_[server_connection_id].push_front(
-          std::string(received_packet->data(), received_packet->length()));
-    } else {
-      // For non-CHLO, always append to last.
-      data_connection_map_[server_connection_id].push_back(
-          std::string(received_packet->data(), received_packet->length()));
-    }
-    dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
-  }
-
-  void ValidatePacket(QuicConnectionId conn_id,
-                      const QuicEncryptedPacket& packet) {
-    EXPECT_EQ(data_connection_map_[conn_id].front().length(),
-              packet.AsStringPiece().length());
-    EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
-    data_connection_map_[conn_id].pop_front();
-  }
-
-  std::unique_ptr<QuicSession> CreateSession(
-      TestDispatcher* dispatcher, const QuicConfig& config,
-      QuicConnectionId connection_id, const QuicSocketAddress& /*peer_address*/,
-      MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      TestQuicSpdyServerSession** session_ptr) {
-    MockServerConnection* connection = new MockServerConnection(
-        connection_id, helper, alarm_factory, dispatcher);
-    connection->SetQuicPacketWriter(dispatcher->writer(),
-                                    /*owns_writer=*/false);
-    auto session = std::make_unique<TestQuicSpdyServerSession>(
-        config, connection, crypto_config, compressed_certs_cache);
-    *session_ptr = session.get();
-    connection->set_visitor(session.get());
-    ON_CALL(*connection, CloseConnection(_, _, _))
-        .WillByDefault(WithoutArgs(Invoke(
-            connection, &MockServerConnection::UnregisterOnConnectionClosed)));
-    return session;
-  }
-
-  void CreateTimeWaitListManager() {
-    time_wait_list_manager_ = new MockTimeWaitListManager(
-        QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
-        mock_helper_.GetClock(), &mock_alarm_factory_);
-    // dispatcher_ takes the ownership of time_wait_list_manager_.
-    QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
-                                               time_wait_list_manager_);
-  }
-
-  std::string SerializeCHLO() {
-    CryptoHandshakeMessage client_hello;
-    client_hello.set_tag(kCHLO);
-    client_hello.SetStringPiece(kALPN, ExpectedAlpn());
-    return std::string(client_hello.GetSerialized().AsStringPiece());
-  }
-
-  void ProcessUndecryptableEarlyPacket(
-      const QuicSocketAddress& peer_address,
-      const QuicConnectionId& server_connection_id) {
-    ProcessUndecryptableEarlyPacket(version_, peer_address,
-                                    server_connection_id);
-  }
-
-  void ProcessUndecryptableEarlyPacket(
-      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
-      const QuicConnectionId& server_connection_id) {
-    std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
-        GetUndecryptableEarlyPacket(version, server_connection_id);
-    std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
-        *encrypted_packet, mock_helper_.GetClock()->Now()));
-    ProcessReceivedPacket(std::move(received_packet), peer_address, version,
-                          server_connection_id);
-  }
-
-  void ProcessFirstFlight(const QuicSocketAddress& peer_address,
-                          const QuicConnectionId& server_connection_id) {
-    ProcessFirstFlight(version_, peer_address, server_connection_id);
-  }
-
-  void ProcessFirstFlight(const ParsedQuicVersion& version,
-                          const QuicSocketAddress& peer_address,
-                          const QuicConnectionId& server_connection_id) {
-    ProcessFirstFlight(version, peer_address, server_connection_id,
-                       EmptyQuicConnectionId());
-  }
-
-  void ProcessFirstFlight(const ParsedQuicVersion& version,
-                          const QuicSocketAddress& peer_address,
-                          const QuicConnectionId& server_connection_id,
-                          const QuicConnectionId& client_connection_id) {
-    ProcessFirstFlight(version, peer_address, server_connection_id,
-                       client_connection_id, TestClientCryptoConfig());
-  }
-
-  void ProcessFirstFlight(
-      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
-      const QuicConnectionId& server_connection_id,
-      const QuicConnectionId& client_connection_id,
-      std::unique_ptr<QuicCryptoClientConfig> client_crypto_config) {
-    std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
-        GetFirstFlightOfPackets(version, DefaultQuicConfig(),
-                                server_connection_id, client_connection_id,
-                                std::move(client_crypto_config));
-    for (auto&& packet : packets) {
-      ProcessReceivedPacket(std::move(packet), peer_address, version,
-                            server_connection_id);
-    }
-  }
-
-  std::unique_ptr<QuicCryptoClientConfig> TestClientCryptoConfig() {
-    auto client_crypto_config = std::make_unique<QuicCryptoClientConfig>(
-        crypto_test_utils::ProofVerifierForTesting());
-    if (address_token_.has_value()) {
-      client_crypto_config->LookupOrCreate(TestServerId())
-          ->set_source_address_token(*address_token_);
-    }
-    return client_crypto_config;
-  }
-
-  // If called, the first flight packets generated in |ProcessFirstFlight| will
-  // contain the given |address_token|.
-  void SetAddressToken(std::string address_token) {
-    address_token_ = std::move(address_token);
-  }
-
-  std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
-    return AlpnForVersion(version);
-  }
-
-  std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
-
-  ParsedClientHello ParsedClientHelloForTest() {
-    ParsedClientHello parsed_chlo;
-    parsed_chlo.alpns = {ExpectedAlpn()};
-    parsed_chlo.sni = TestHostname();
-    return parsed_chlo;
-  }
-
-  void MarkSession1Deleted() { session1_ = nullptr; }
-
-  void VerifyVersionSupported(ParsedQuicVersion version) {
-    QuicConnectionId connection_id = TestConnectionId(++connection_id_);
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-    EXPECT_CALL(*dispatcher_,
-                CreateQuicSession(connection_id, _, client_address,
-                                  Eq(ExpectedAlpnForVersion(version)), _, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, connection_id, client_address,
-            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillOnce(WithArg<2>(
-            Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
-              ValidatePacket(connection_id, packet);
-            })));
-    EXPECT_CALL(*dispatcher_,
-                ShouldCreateOrBufferPacketForConnection(
-                    ReceivedPacketInfoConnectionIdEquals(connection_id)));
-    ProcessFirstFlight(version, client_address, connection_id);
-  }
-
-  void VerifyVersionNotSupported(ParsedQuicVersion version) {
-    QuicConnectionId connection_id = TestConnectionId(++connection_id_);
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-    EXPECT_CALL(*dispatcher_,
-                CreateQuicSession(connection_id, _, client_address, _, _, _))
-        .Times(0);
-    ProcessFirstFlight(version, client_address, connection_id);
-  }
-
-  void TestTlsMultiPacketClientHello(bool add_reordering);
-
-  void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
-      const QuicConnectionId& server_connection_id,
-      const QuicConnectionId& client_connection_id);
-
-  TestAlarmFactory::TestAlarm* GetClearResetAddressesAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        QuicDispatcherPeer::GetClearResetAddressesAlarm(dispatcher_.get()));
-  }
-
-  ParsedQuicVersion version_;
-  MockQuicConnectionHelper mock_helper_;
-  MockAlarmFactory mock_alarm_factory_;
-  QuicConfig config_;
-  QuicVersionManager version_manager_;
-  QuicCryptoServerConfig crypto_config_;
-  QuicSocketAddress server_address_;
-  std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
-  MockTimeWaitListManager* time_wait_list_manager_;
-  TestQuicSpdyServerSession* session1_;
-  TestQuicSpdyServerSession* session2_;
-  std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
-  QuicBufferedPacketStore* store_;
-  uint64_t connection_id_;
-  absl::optional<std::string> address_token_;
-};
-
-class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
-class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
-                         QuicDispatcherTestAllVersions,
-                         ::testing::ValuesIn(CurrentSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
-                         QuicDispatcherTestOneVersion,
-                         ::testing::Values(CurrentSupportedVersions().front()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
-  if (version_.UsesQuicCrypto()) {
-    return;
-  }
-  SetAddressToken("hsdifghdsaifnasdpfjdsk");
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(
-      *dispatcher_,
-      CreateQuicSession(TestConnectionId(1), _, client_address,
-                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-}
-
-void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
-    bool add_reordering) {
-  if (!version_.UsesTls()) {
-    return;
-  }
-  SetAddressToken("857293462398");
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId server_connection_id = TestConnectionId();
-  QuicConfig client_config = DefaultQuicConfig();
-  // Add a 2000-byte custom parameter to increase the length of the CHLO.
-  constexpr auto kCustomParameterId =
-      static_cast<TransportParameters::TransportParameterId>(0xff33);
-  std::string kCustomParameterValue(2000, '-');
-  client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
-      kCustomParameterValue;
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
-      GetFirstFlightOfPackets(version_, client_config, server_connection_id,
-                              EmptyQuicConnectionId(),
-                              TestClientCryptoConfig());
-  ASSERT_EQ(packets.size(), 2u);
-  if (add_reordering) {
-    std::swap(packets[0], packets[1]);
-  }
-
-  // Processing the first packet should not create a new session.
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
-  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
-                        server_connection_id);
-
-  EXPECT_EQ(dispatcher_->NumSessions(), 0u)
-      << "No session should be created before the rest of the CHLO arrives.";
-
-  // Processing the second packet should create the new session.
-  EXPECT_CALL(
-      *dispatcher_,
-      CreateQuicSession(server_connection_id, _, client_address,
-                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, server_connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(2);
-
-  ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
-                        server_connection_id);
-  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
-  TestTlsMultiPacketClientHello(/*add_reordering=*/false);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
-  TestTlsMultiPacketClientHello(/*add_reordering=*/true);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
-  if (!version_.HasLongHeaderLengths()) {
-    // Decapsulating Legacy Version Encapsulation packets from these versions
-    // is not currently supported in QuicDispatcher.
-    return;
-  }
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId server_connection_id = TestConnectionId();
-  QuicConfig client_config = DefaultQuicConfig();
-  client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
-      GetFirstFlightOfPackets(version_, client_config, server_connection_id);
-  ASSERT_EQ(packets.size(), 1u);
-
-  // Validate that Legacy Version Encapsulation is actually being used by
-  // checking the version of the packet before processing it.
-  PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
-  QuicLongHeaderType long_packet_type;
-  bool version_present;
-  bool has_length_prefix;
-  QuicVersionLabel version_label;
-  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-  QuicConnectionId destination_connection_id, source_connection_id;
-  absl::optional<absl::string_view> retry_token;
-  std::string detailed_error;
-  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-      QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
-      kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
-  EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
-  EXPECT_TRUE(version_present);
-  EXPECT_FALSE(has_length_prefix);
-  EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
-  EXPECT_EQ(destination_connection_id, server_connection_id);
-  EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
-  EXPECT_FALSE(retry_token.has_value());
-  EXPECT_TRUE(detailed_error.empty());
-
-  // Processing the packet should create a new session.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(server_connection_id, _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, server_connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(2);
-
-  ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
-                        server_connection_id);
-  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-
-  // Processing the same packet a second time should also be routed by the
-  // dispatcher to the right connection (we expect ProcessUdpPacket to be
-  // called twice, see the EXPECT_CALL above).
-  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
-                        server_connection_id);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(
-      *dispatcher_,
-      CreateQuicSession(TestConnectionId(1), _, client_address,
-                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-
-  EXPECT_CALL(
-      *dispatcher_,
-      CreateQuicSession(TestConnectionId(2), _, client_address,
-                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(2), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(2), packet);
-      })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
-  ProcessFirstFlight(client_address, TestConnectionId(2));
-
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(1)
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  ProcessPacket(client_address, TestConnectionId(1), false, "data");
-}
-
-// Regression test of b/93325907.
-TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(1), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  // Verify both packets 1 and 2 are processed by connection 1.
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(2)
-      .WillRepeatedly(
-          WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-            ValidatePacket(TestConnectionId(1), packet);
-          })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-  // Packet number 256 with packet number length 1 would be considered as 0 in
-  // dispatcher.
-  ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
-                CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
-      .Times(1);
-  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
-                     TestConnectionId(1));
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       StatelessVersionNegotiationWithVeryLongConnectionId) {
-  QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_,
-              SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
-      .Times(1);
-  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
-                     connection_id);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       StatelessVersionNegotiationWithClientConnectionId) {
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_,
-              SendVersionNegotiationPacket(
-                  TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
-      .Times(1);
-  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
-                     TestConnectionId(1), TestConnectionId(2));
-}
-
-TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_,
-              SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
-      .Times(0);
-  std::string chlo = SerializeCHLO() + std::string(1200, 'a');
-  // Truncate to 1100 bytes of payload which results in a packet just
-  // under 1200 bytes after framing, packet, and encryption overhead.
-  QUICHE_DCHECK_LE(1200u, chlo.length());
-  std::string truncated_chlo = chlo.substr(0, 1100);
-  QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
-  ProcessPacket(client_address, TestConnectionId(1), true,
-                QuicVersionReservedForNegotiation(), truncated_chlo, false,
-                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-// Disabling CHLO size validation allows the dispatcher to send version
-// negotiation packets in response to a CHLO that is otherwise too small.
-TEST_P(QuicDispatcherTestOneVersion,
-       VersionNegotiationWithoutChloSizeValidation) {
-  crypto_config_.set_validate_chlo_size(false);
-
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_,
-              SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
-      .Times(1);
-  std::string chlo = SerializeCHLO() + std::string(1200, 'a');
-  // Truncate to 1100 bytes of payload which results in a packet just
-  // under 1200 bytes after framing, packet, and encryption overhead.
-  QUICHE_DCHECK_LE(1200u, chlo.length());
-  std::string truncated_chlo = chlo.substr(0, 1100);
-  QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
-  ProcessPacket(client_address, TestConnectionId(1), true,
-                QuicVersionReservedForNegotiation(), truncated_chlo, true,
-                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-
-  dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
-  CreateTimeWaitListManager();
-
-  // Create a new session.
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId connection_id = TestConnectionId(1);
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, _, client_address,
-                                              Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-  ProcessFirstFlight(client_address, connection_id);
-
-  // Now close the connection, which should add it to the time wait list.
-  session1_->connection()->CloseConnection(
-      QUIC_INVALID_VERSION,
-      "Server: Packet 2 without version flag before version negotiated.",
-      ConnectionCloseBehavior::SILENT_CLOSE);
-  EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
-
-  // Dispatcher forwards subsequent packets for this connection_id to the time
-  // wait list manager.
-  EXPECT_CALL(*time_wait_list_manager_,
-              ProcessPacket(_, _, connection_id, _, _, _))
-      .Times(1);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  ProcessPacket(client_address, connection_id, true, "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId connection_id = TestConnectionId(1);
-  // Dispatcher forwards all packets for this connection_id to the time wait
-  // list manager.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_,
-              ProcessPacket(_, _, connection_id, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-      .Times(1);
-  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
-                "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
-       DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-
-  uint8_t short_packet[21] = {0x70, 0xa7, 0x02, 0x6b};
-  QuicReceivedPacket packet(reinterpret_cast<char*>(short_packet), 21,
-                            QuicTime::Zero());
-  uint8_t valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
-  QuicReceivedPacket packet2(reinterpret_cast<char*>(valid_size_packet), 23,
-                             QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  // Verify small packet is silently dropped.
-  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-      .Times(0);
-  dispatcher_->ProcessPacket(server_address_, client_address, packet);
-  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, packet2);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, DropPacketWithInvalidFlags) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t all_zero_packet[1200] = {};
-  QuicReceivedPacket packet(reinterpret_cast<char*>(all_zero_packet),
-                            sizeof(all_zero_packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-      .Times(0);
-  dispatcher_->ProcessPacket(server_address_, client_address, packet);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, LimitResetsToSameClientAddress) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
-  QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
-  QuicConnectionId connection_id = TestConnectionId(1);
-
-  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
-    // Verify only one reset is sent to the address, although multiple packets
-    // are received.
-    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-        .Times(1);
-  } else {
-    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-        .Times(3);
-  }
-  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
-                "data");
-  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
-                "data2");
-  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
-                "data3");
-
-  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-      .Times(2);
-  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
-                "data");
-  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
-                "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
-       StopSendingResetOnTooManyRecentAddresses) {
-  SetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses, 2);
-  const size_t kTestLifeTimeMs = 10;
-  SetQuicFlag(FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms,
-              kTestLifeTimeMs);
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
-  QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
-  QuicConnectionId connection_id = TestConnectionId(1);
-
-  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-      .Times(2);
-  EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
-  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
-                "data");
-  const QuicTime expected_deadline =
-      mock_helper_.GetClock()->Now() +
-      QuicTime::Delta::FromMilliseconds(kTestLifeTimeMs);
-  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
-    ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
-    EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
-  } else {
-    EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
-  }
-  // Received no version packet 2 after 5ms.
-  mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
-                "data");
-  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
-    ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
-    // Verify deadline does not change.
-    EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
-  } else {
-    EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
-  }
-  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
-    // Verify reset gets throttled since there are too many recent addresses.
-    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-        .Times(0);
-  } else {
-    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-        .Times(1);
-  }
-  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
-                "data");
-
-  mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
-    GetClearResetAddressesAlarm()->Fire();
-    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-        .Times(2);
-  } else {
-    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
-        .Times(3);
-  }
-  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
-                "data");
-  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
-                "data");
-  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
-                "data");
-}
-
-// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
-TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    // When variable length connection IDs are not supported, the connection
-    // fails. See StrayPacketTruncatedConnectionId.
-    return;
-  }
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
-  QuicConnectionId fixed_connection_id =
-      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(fixed_connection_id, _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, fixed_connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(
-          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
-            ValidatePacket(bad_connection_id, packet);
-          })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
-  ProcessFirstFlight(client_address, bad_connection_id);
-}
-
-// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
-TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    // When variable length connection IDs are not supported, the connection
-    // fails. See StrayPacketTruncatedConnectionId.
-    return;
-  }
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
-  QuicConnectionId fixed_connection_id =
-      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
-
-  // Disable validation of invalid short connection IDs.
-  dispatcher_->SetAllowShortInitialServerConnectionIds(true);
-  // Note that StrayPacketTruncatedConnectionId covers the case where the
-  // validation is still enabled.
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(fixed_connection_id, _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, fixed_connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(
-          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
-            ValidatePacket(bad_connection_id, packet);
-          })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
-  ProcessFirstFlight(client_address, bad_connection_id);
-}
-
-// Makes sure TestConnectionId(1) creates a new connection and
-// TestConnectionIdNineBytesLong(2) gets replaced.
-TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    return;
-  }
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
-  QuicConnectionId fixed_connection_id =
-      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(1), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(fixed_connection_id, _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, fixed_connection_id, client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(
-          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
-            ValidatePacket(bad_connection_id, packet);
-          })));
-  EXPECT_CALL(*dispatcher_,
-              ShouldCreateOrBufferPacketForConnection(
-                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
-  ProcessFirstFlight(client_address, bad_connection_id);
-
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(1)
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  ProcessPacket(client_address, TestConnectionId(1), false, "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
-
-  // dispatcher_ should drop this packet.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
-                                              client_address, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
-                "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithBlockedPort) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 17);
-
-  // dispatcher_ should drop this packet.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
-                                              client_address, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
-                "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithNonBlockedPort) {
-  CreateTimeWaitListManager();
-
-  // Port 443 must not be blocked because it might be useful for proxies to send
-  // proxied traffic with source port 443 as that allows building a full QUIC
-  // proxy using a single UDP socket.
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 443);
-
-  // dispatcher_ should not drop this packet.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(1), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
-       DropPacketWithKnownVersionAndInvalidShortInitialConnectionId) {
-  if (!version_.AllowsVariableLengthConnectionIds()) {
-    return;
-  }
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  // dispatcher_ should drop this packet.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  ProcessFirstFlight(client_address, EmptyQuicConnectionId());
-}
-
-TEST_P(QuicDispatcherTestAllVersions,
-       DropPacketWithKnownVersionAndInvalidInitialConnectionId) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress server_address;
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  // dispatcher_ should drop this packet with invalid connection ID.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  absl::string_view cid_str = "123456789abcdefg123456789abcdefg";
-  QuicConnectionId invalid_connection_id(cid_str.data(), cid_str.length());
-  QuicReceivedPacket packet("packet", 6, QuicTime::Zero());
-  ReceivedPacketInfo packet_info(server_address, client_address, packet);
-  packet_info.version_flag = true;
-  packet_info.version = version_;
-  packet_info.destination_connection_id = invalid_connection_id;
-
-  ASSERT_TRUE(dispatcher_->MaybeDispatchPacket(packet_info));
-}
-
-void QuicDispatcherTestBase::
-    TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
-        const QuicConnectionId& server_connection_id,
-        const QuicConnectionId& client_connection_id) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_,
-              SendVersionNegotiationPacket(
-                  server_connection_id, client_connection_id,
-                  /*ietf_quic=*/true,
-                  /*use_length_prefix=*/true, _, _, client_address, _))
-      .Times(1);
-  ProcessFirstFlight(ParsedQuicVersion::ReservedForNegotiation(),
-                     client_address, server_connection_id,
-                     client_connection_id);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId) {
-  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
-      EmptyQuicConnectionId(), EmptyQuicConnectionId());
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2) {
-  char server_connection_id_bytes[3] = {1, 2, 3};
-  QuicConnectionId server_connection_id(server_connection_id_bytes,
-                                        sizeof(server_connection_id_bytes));
-  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
-      server_connection_id, EmptyQuicConnectionId());
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3) {
-  char client_connection_id_bytes[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-  QuicConnectionId client_connection_id(client_connection_id_bytes,
-                                        sizeof(client_connection_id_bytes));
-  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
-      EmptyQuicConnectionId(), client_connection_id);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
-  VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
-  for (ParsedQuicVersion version : CurrentSupportedVersions()) {
-    VerifyVersionSupported(version);
-    QuicDisableVersion(version);
-    VerifyVersionNotSupported(version);
-    QuicEnableVersion(version);
-    VerifyVersionSupported(version);
-  }
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionDraft28WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 0xFF, 0x00, 0x00, 28, /*destination connection ID length*/ 0x08};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionDraft27WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 0xFF, 0x00, 0x00, 27, /*destination connection ID length*/ 0x08};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionDraft25WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 0xFF, 0x00, 0x00, 25, /*destination connection ID length*/ 0x08};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionT050WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 'T', '0', '5', '0', /*destination connection ID length*/ 0x08};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionQ049WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 'Q', '0', '4', '9', /*destination connection ID length*/ 0x08};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionQ048WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/false, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionQ047WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/false, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionQ045WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/false, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionQ044WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet44[kMinPacketSizeForVersionNegotiation] = {
-      0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
-  QuicReceivedPacket received_packet44(reinterpret_cast<char*>(packet44),
-                                       kMinPacketSizeForVersionNegotiation,
-                                       QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/false, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address,
-                             received_packet44);
-}
-
-TEST_P(QuicDispatcherTestOneVersion,
-       RejectDeprecatedVersionT051WithVersionNegotiation) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
-      0xFF, 'T', '0', '5', '1', /*destination connection ID length*/ 0x08};
-  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
-                                     kMinPacketSizeForVersionNegotiation,
-                                     QuicTime::Zero());
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(
-      *time_wait_list_manager_,
-      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
-                                   /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
-}
-
-static_assert(quic::SupportedVersions().size() == 6u,
-              "Please add new RejectDeprecatedVersion tests above this assert "
-              "when deprecating versions");
-
-TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  CreateTimeWaitListManager();
-  char packet[1200];
-  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                            0x6c, 0x7a, 0x20, 0x21};
-  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
-      packet, sizeof(packet), destination_connection_id_bytes,
-      sizeof(destination_connection_id_bytes)));
-  QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
-  std::unique_ptr<QuicReceivedPacket> received_packet(
-      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
-  QuicConnectionId client_connection_id = EmptyQuicConnectionId();
-  QuicConnectionId server_connection_id(
-      destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
-  EXPECT_CALL(*time_wait_list_manager_,
-              SendVersionNegotiationPacket(
-                  server_connection_id, client_connection_id,
-                  /*ietf_quic=*/true, /*use_length_prefix=*/true, _, _, _, _))
-      .Times(1);
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
-  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
-}
-
-// Testing packet writer that saves all packets instead of sending them.
-// Useful for tests that need access to sent packets.
-class SavingWriter : public QuicPacketWriterWrapper {
- public:
-  bool IsWriteBlocked() const override { return false; }
-
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& /*self_client_address*/,
-                          const QuicSocketAddress& /*peer_client_address*/,
-                          PerPacketOptions* /*options*/) override {
-    packets_.push_back(
-        QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
-  std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
-    return &packets_;
-  }
-
- private:
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
-};
-
-TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
-  SavingWriter* saving_writer = new SavingWriter();
-  // dispatcher_ takes ownership of saving_writer.
-  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
-  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
-      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
-      &mock_alarm_factory_);
-  // dispatcher_ takes ownership of time_wait_list_manager.
-  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
-                                             time_wait_list_manager);
-  char packet[1200] = {};
-  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                            0x6c, 0x7a, 0x20, 0x21};
-  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
-      packet, sizeof(packet), destination_connection_id_bytes,
-      sizeof(destination_connection_id_bytes)));
-  QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
-  std::unique_ptr<QuicReceivedPacket> received_packet(
-      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
-  ASSERT_EQ(1u, saving_writer->packets()->size());
-
-  char source_connection_id_bytes[255] = {};
-  uint8_t source_connection_id_length = sizeof(source_connection_id_bytes);
-  std::string detailed_error = "foobar";
-  EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
-      (*(saving_writer->packets()))[0]->data(),
-      (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
-      &source_connection_id_length, &detailed_error));
-  EXPECT_EQ("", detailed_error);
-
-  // The source connection ID of the probe response should match the
-  // destination connection ID of the probe request.
-  quiche::test::CompareCharArraysWithHexError(
-      "parsed probe", source_connection_id_bytes, source_connection_id_length,
-      destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
-}
-
-TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
-  // WARNING: do not remove or modify this test without making sure that we
-  // still have adequate coverage for the Android conformance test.
-  SavingWriter* saving_writer = new SavingWriter();
-  // dispatcher_ takes ownership of saving_writer.
-  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
-  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
-      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
-      &mock_alarm_factory_);
-  // dispatcher_ takes ownership of time_wait_list_manager.
-  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
-                                             time_wait_list_manager);
-  // clang-format off
-  static const unsigned char packet[1200] = {
-    // Android UDP network conformance test packet as it was after this change:
-    // https://android-review.googlesource.com/c/platform/cts/+/1454515
-    0xc0,  // long header
-    0xaa, 0xda, 0xca, 0xca,  // reserved-space version number
-    0x08,  // destination connection ID length
-    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  // 8-byte connection ID
-    0x00,  // source connection ID length
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
-                                sizeof(packet), false);
-  std::unique_ptr<QuicReceivedPacket> received_packet(
-      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
-  ASSERT_EQ(1u, saving_writer->packets()->size());
-
-  // The Android UDP network conformance test directly checks that these bytes
-  // of the response match the connection ID that was sent.
-  ASSERT_GE((*(saving_writer->packets()))[0]->length(), 15u);
-  quiche::test::CompareCharArraysWithHexError(
-      "response connection ID", &(*(saving_writer->packets()))[0]->data()[7], 8,
-      reinterpret_cast<const char*>(&packet[6]), 8);
-}
-
-TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) {
-  // WARNING: this test covers an old Android Conformance Test that has now been
-  // changed, but it'll take time for the change to propagate through the
-  // Android ecosystem. The Android team has asked us to keep this test
-  // supported until at least 2021-03-31. After that date, and when we drop
-  // support for sending QUIC version negotiation packets using the legacy
-  // Google QUIC format (Q001-Q043), then we can delete this test.
-  // TODO(dschinazi) delete this test after 2021-03-31
-  SavingWriter* saving_writer = new SavingWriter();
-  // dispatcher_ takes ownership of saving_writer.
-  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
-  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
-      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
-      &mock_alarm_factory_);
-  // dispatcher_ takes ownership of time_wait_list_manager.
-  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
-                                             time_wait_list_manager);
-  // clang-format off
-  static const unsigned char packet[1200] = {
-    // Android UDP network conformance test packet as it was after this change:
-    // https://android-review.googlesource.com/c/platform/cts/+/1104285
-    // but before this change:
-    // https://android-review.googlesource.com/c/platform/cts/+/1454515
-    0x0d,  // public flags: version, 8-byte connection ID, 1-byte packet number
-    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  // 8-byte connection ID
-    0xaa, 0xda, 0xca, 0xaa,  // reserved-space version number
-    0x01,  // 1-byte packet number
-    0x00,  // private flags
-    0x07,  // PING frame
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
-                                sizeof(packet), false);
-  std::unique_ptr<QuicReceivedPacket> received_packet(
-      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
-  ASSERT_EQ(1u, saving_writer->packets()->size());
-
-  // The Android UDP network conformance test directly checks that bytes 1-9
-  // of the response match the connection ID that was sent.
-  static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
-                                             0x75, 0x76, 0x77, 0x78};
-  ASSERT_GE((*(saving_writer->packets()))[0]->length(),
-            1u + sizeof(connection_id_bytes));
-  quiche::test::CompareCharArraysWithHexError(
-      "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
-      sizeof(connection_id_bytes), connection_id_bytes,
-      sizeof(connection_id_bytes));
-}
-
-TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
-                version_, SerializeCHLO(), /*full_padding=*/false,
-                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
-  CreateTimeWaitListManager();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
-
-  // clang-format off
-  uint8_t coalesced_packet[1200] = {
-    // first coalesced packet
-      // public flags (long header with packet type INITIAL and
-      // 4-byte packet number)
-      0xC3,
-      // version
-      'Q', '0', '9', '9',
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x05,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // Padding
-      0x00,
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xC3,
-      // version
-      'Q', '0', '9', '9',
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-  };
-  // clang-format on
-  QuicReceivedPacket packet(reinterpret_cast<char*>(coalesced_packet), 1200,
-                            QuicTime::Zero());
-  dispatcher_->ProcessPacket(server_address_, client_address, packet);
-}
-
-TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(1), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-
-  dispatcher_->StopAcceptingNewConnections();
-  EXPECT_FALSE(dispatcher_->accept_new_connections());
-
-  // No more new connections afterwards.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(2), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .Times(0u);
-  ProcessFirstFlight(client_address, TestConnectionId(2));
-
-  // Existing connections should be able to continue.
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(1u)
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  ProcessPacket(client_address, TestConnectionId(1), false, "data");
-}
-
-TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
-  dispatcher_->StopAcceptingNewConnections();
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-  // No more new connections afterwards.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(2), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .Times(0u);
-  ProcessFirstFlight(client_address, TestConnectionId(2));
-
-  dispatcher_->StartAcceptingNewConnections();
-  EXPECT_TRUE(dispatcher_->accept_new_connections());
-
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(1), _, client_address,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, TestConnectionId(1), client_address,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-        ValidatePacket(TestConnectionId(1), packet);
-      })));
-  ProcessFirstFlight(client_address, TestConnectionId(1));
-}
-
-TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
-  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
-  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
-  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
-  // Q033 is no longer supported but Q050 is.
-  QuicEnableVersion(ParsedQuicVersion::Q050());
-  EXPECT_EQ(
-      QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
-      "h3-Q050");
-}
-
-// Verify the stopgap test: Packets with truncated connection IDs should be
-// dropped.
-class QuicDispatcherTestStrayPacketConnectionId
-    : public QuicDispatcherTestBase {};
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
-                         QuicDispatcherTestStrayPacketConnectionId,
-                         ::testing::ValuesIn(CurrentSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-// Packets with truncated connection IDs should be dropped.
-TEST_P(QuicDispatcherTestStrayPacketConnectionId,
-       StrayPacketTruncatedConnectionId) {
-  CreateTimeWaitListManager();
-
-  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-  QuicConnectionId connection_id = TestConnectionId(1);
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
-      .Times(0);
-  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
-      .Times(0);
-
-  ProcessPacket(client_address, connection_id, true, "data",
-                CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
-}
-
-class BlockingWriter : public QuicPacketWriterWrapper {
- public:
-  BlockingWriter() : write_blocked_(false) {}
-
-  bool IsWriteBlocked() const override { return write_blocked_; }
-  void SetWritable() override { write_blocked_ = false; }
-
-  WriteResult WritePacket(const char* /*buffer*/, size_t /*buf_len*/,
-                          const QuicIpAddress& /*self_client_address*/,
-                          const QuicSocketAddress& /*peer_client_address*/,
-                          PerPacketOptions* /*options*/) override {
-    // It would be quite possible to actually implement this method here with
-    // the fake blocked status, but it would be significantly more work in
-    // Chromium, and since it's not called anyway, don't bother.
-    QUIC_LOG(DFATAL) << "Not supported";
-    return WriteResult();
-  }
-
-  bool write_blocked_;
-};
-
-class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
- public:
-  void SetUp() override {
-    QuicDispatcherTestBase::SetUp();
-    writer_ = new BlockingWriter;
-    QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
-
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-
-    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
-                                                Eq(ExpectedAlpn()), _, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, TestConnectionId(1), client_address,
-            &helper_, &alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-          ValidatePacket(TestConnectionId(1), packet);
-        })));
-    EXPECT_CALL(*dispatcher_,
-                ShouldCreateOrBufferPacketForConnection(
-                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-    ProcessFirstFlight(client_address, TestConnectionId(1));
-
-    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
-                                                Eq(ExpectedAlpn()), _, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, TestConnectionId(2), client_address,
-            &helper_, &alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-          ValidatePacket(TestConnectionId(2), packet);
-        })));
-    EXPECT_CALL(*dispatcher_,
-                ShouldCreateOrBufferPacketForConnection(
-                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
-    ProcessFirstFlight(client_address, TestConnectionId(2));
-
-    blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
-  }
-
-  void TearDown() override {
-    if (connection1() != nullptr) {
-      EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-    }
-
-    if (connection2() != nullptr) {
-      EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-    }
-    dispatcher_->Shutdown();
-  }
-
-  // Set the dispatcher's writer to be blocked. By default, all connections use
-  // the same writer as the dispatcher in this test.
-  void SetBlocked() {
-    QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
-    writer_->write_blocked_ = true;
-  }
-
-  // Simulate what happens when connection1 gets blocked when writing.
-  void BlockConnection1() {
-    Connection1Writer()->write_blocked_ = true;
-    dispatcher_->OnWriteBlocked(connection1());
-  }
-
-  BlockingWriter* Connection1Writer() {
-    return static_cast<BlockingWriter*>(connection1()->writer());
-  }
-
-  // Simulate what happens when connection2 gets blocked when writing.
-  void BlockConnection2() {
-    Connection2Writer()->write_blocked_ = true;
-    dispatcher_->OnWriteBlocked(connection2());
-  }
-
-  BlockingWriter* Connection2Writer() {
-    return static_cast<BlockingWriter*>(connection2()->writer());
-  }
-
- protected:
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  BlockingWriter* writer_;
-  QuicDispatcher::WriteBlockedList* blocked_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
-                         QuicDispatcherWriteBlockedListTest,
-                         ::testing::Values(CurrentSupportedVersions().front()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
-  // No OnCanWrite calls because no connections are blocked.
-  dispatcher_->OnCanWrite();
-
-  // Register connection 1 for events, and make sure it's notified.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  EXPECT_CALL(*connection1(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-
-  // It should get only one notification.
-  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
-  dispatcher_->OnCanWrite();
-  EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
-  // Make sure we handle events in order.
-  InSequence s;
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection2());
-  EXPECT_CALL(*connection1(), OnCanWrite());
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-
-  // Check the other ordering.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection2());
-  dispatcher_->OnWriteBlocked(connection1());
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  EXPECT_CALL(*connection1(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
-  // Add and remove one connction.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  blocked_list_->erase(connection1());
-  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
-  dispatcher_->OnCanWrite();
-
-  // Add and remove one connction and make sure it doesn't affect others.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection2());
-  blocked_list_->erase(connection1());
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-
-  // Add it, remove it, and add it back and make sure things are OK.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  blocked_list_->erase(connection1());
-  dispatcher_->OnWriteBlocked(connection1());
-  EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
-  dispatcher_->OnCanWrite();
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
-  // Make sure a double add does not necessitate a double remove.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection1());
-  blocked_list_->erase(connection1());
-  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
-  dispatcher_->OnCanWrite();
-
-  // Make sure a double add does not result in two OnCanWrite calls.
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection1());
-  EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
-  dispatcher_->OnCanWrite();
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
-  // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
-  // into the write blocked list.
-  InSequence s;
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection2());
-  EXPECT_CALL(*connection1(), OnCanWrite())
-      .WillOnce(
-          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-
-  // connection1 should be still in the write blocked list.
-  EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
-  // Now call OnCanWrite again, connection1 should get its second chance.
-  EXPECT_CALL(*connection1(), OnCanWrite());
-  EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
-  dispatcher_->OnCanWrite();
-  EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
-  // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
-  // into the write blocked list.
-  InSequence s;
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection2());
-  EXPECT_CALL(*connection1(), OnCanWrite());
-  EXPECT_CALL(*connection2(), OnCanWrite())
-      .WillOnce(
-          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
-  dispatcher_->OnCanWrite();
-
-  // connection2 should be still in the write blocked list.
-  EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
-  // Now call OnCanWrite again, connection2 should get its second chance.
-  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-  EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest,
-       OnCanWriteHandleBlockBothConnections) {
-  // Both connections get blocked in OnCanWrite, and added back into the write
-  // blocked list.
-  InSequence s;
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  dispatcher_->OnWriteBlocked(connection2());
-  EXPECT_CALL(*connection1(), OnCanWrite())
-      .WillOnce(
-          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
-  EXPECT_CALL(*connection2(), OnCanWrite())
-      .WillOnce(
-          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
-  dispatcher_->OnCanWrite();
-
-  // Both connections should be still in the write blocked list.
-  EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
-  // Now call OnCanWrite again, both connections should get its second chance.
-  EXPECT_CALL(*connection1(), OnCanWrite());
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-  EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
-  // By default, all connections share the same packet writer with the
-  // dispatcher.
-  EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
-  EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
-
-  // Test the case where connection1 shares the same packet writer as the
-  // dispatcher, whereas connection2 owns it's packet writer.
-  // Change connection2's writer.
-  connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
-  EXPECT_NE(dispatcher_->writer(), connection2()->writer());
-
-  BlockConnection2();
-  EXPECT_TRUE(dispatcher_->HasPendingWrites());
-
-  EXPECT_CALL(*connection2(), OnCanWrite());
-  dispatcher_->OnCanWrite();
-  EXPECT_FALSE(dispatcher_->HasPendingWrites());
-}
-
-TEST_P(QuicDispatcherWriteBlockedListTest,
-       RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
-  dispatcher_->OnConnectionClosed(connection1()->connection_id(),
-                                  QUIC_PACKET_WRITE_ERROR, "Closed by test.",
-                                  ConnectionCloseSource::FROM_SELF);
-
-  SetBlocked();
-
-  ASSERT_FALSE(dispatcher_->HasPendingWrites());
-  SetBlocked();
-  dispatcher_->OnWriteBlocked(connection1());
-  ASSERT_TRUE(dispatcher_->HasPendingWrites());
-
-  EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
-                  "QuicConnection was in WriteBlockedList before destruction");
-  MarkSession1Deleted();
-}
-
-class QuicDispatcherSupportMultipleConnectionIdPerConnectionTest
-    : public QuicDispatcherTestBase {
- public:
-  QuicDispatcherSupportMultipleConnectionIdPerConnectionTest()
-      : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {
-    dispatcher_ = std::make_unique<NiceMock<TestDispatcher>>(
-        &config_, &crypto_config_, &version_manager_,
-        mock_helper_.GetRandomGenerator());
-  }
-  void AddConnection1() {
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
-    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
-                                                Eq(ExpectedAlpn()), _, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, TestConnectionId(1), client_address,
-            &helper_, &alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-          ValidatePacket(TestConnectionId(1), packet);
-        })));
-    EXPECT_CALL(*dispatcher_,
-                ShouldCreateOrBufferPacketForConnection(
-                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
-    ProcessFirstFlight(client_address, TestConnectionId(1));
-  }
-
-  void AddConnection2() {
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 2);
-    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
-                                                Eq(ExpectedAlpn()), _, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, TestConnectionId(2), client_address,
-            &helper_, &alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
-          ValidatePacket(TestConnectionId(2), packet);
-        })));
-    EXPECT_CALL(*dispatcher_,
-                ShouldCreateOrBufferPacketForConnection(
-                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
-    ProcessFirstFlight(client_address, TestConnectionId(2));
-  }
-
- protected:
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    QuicDispatcherSupportMultipleConnectionIdPerConnectionTests,
-    QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
-    ::testing::Values(CurrentSupportedVersions().front()),
-    ::testing::PrintToStringParamName());
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
-       OnNewConnectionIdSent) {
-  AddConnection1();
-  ASSERT_EQ(dispatcher_->NumSessions(), 1u);
-  ASSERT_THAT(session1_, testing::NotNull());
-  MockServerConnection* mock_server_connection1 =
-      reinterpret_cast<MockServerConnection*>(connection1());
-
-  {
-    mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
-    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-    auto* session =
-        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(3));
-    ASSERT_EQ(session, session1_);
-  }
-
-  {
-    mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
-    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-    auto* session =
-        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(4));
-    ASSERT_EQ(session, session1_);
-  }
-
-  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-  // Would timed out unless all sessions have been removed from the session map.
-  dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
-       RetireConnectionIdFromSingleConnection) {
-  AddConnection1();
-  ASSERT_EQ(dispatcher_->NumSessions(), 1u);
-  ASSERT_THAT(session1_, testing::NotNull());
-  MockServerConnection* mock_server_connection1 =
-      reinterpret_cast<MockServerConnection*>(connection1());
-
-  // Adds 1 new connection id every turn and retires 2 connection ids every
-  // other turn.
-  for (int i = 2; i < 10; ++i) {
-    mock_server_connection1->AddNewConnectionId(TestConnectionId(i));
-    ASSERT_EQ(
-        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(i)),
-        session1_);
-    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
-                                              TestConnectionId(i - 1)),
-              session1_);
-    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
-    if (i % 2 == 1) {
-      mock_server_connection1->RetireConnectionId(TestConnectionId(i - 2));
-      mock_server_connection1->RetireConnectionId(TestConnectionId(i - 1));
-    }
-  }
-
-  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-  // Would timed out unless all sessions have been removed from the session map.
-  dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
-       RetireConnectionIdFromMultipleConnections) {
-  AddConnection1();
-  AddConnection2();
-  ASSERT_EQ(dispatcher_->NumSessions(), 2u);
-  MockServerConnection* mock_server_connection1 =
-      reinterpret_cast<MockServerConnection*>(connection1());
-  MockServerConnection* mock_server_connection2 =
-      reinterpret_cast<MockServerConnection*>(connection2());
-
-  for (int i = 2; i < 10; ++i) {
-    mock_server_connection1->AddNewConnectionId(TestConnectionId(2 * i - 1));
-    mock_server_connection2->AddNewConnectionId(TestConnectionId(2 * i));
-    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
-                                              TestConnectionId(2 * i - 1)),
-              session1_);
-    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
-                                              TestConnectionId(2 * i)),
-              session2_);
-    EXPECT_EQ(dispatcher_->NumSessions(), 2u);
-    mock_server_connection1->RetireConnectionId(TestConnectionId(2 * i - 3));
-    mock_server_connection2->RetireConnectionId(TestConnectionId(2 * i - 2));
-  }
-
-  mock_server_connection1->AddNewConnectionId(TestConnectionId(19));
-  mock_server_connection2->AddNewConnectionId(TestConnectionId(20));
-  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-  EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-  // Would timed out unless all sessions have been removed from the session map.
-  dispatcher_->Shutdown();
-}
-
-TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
-       TimeWaitListPoplulateCorrectly) {
-  QuicTimeWaitListManager* time_wait_list_manager =
-      QuicDispatcherPeer::GetTimeWaitListManager(dispatcher_.get());
-  AddConnection1();
-  MockServerConnection* mock_server_connection1 =
-      reinterpret_cast<MockServerConnection*>(connection1());
-
-  mock_server_connection1->AddNewConnectionId(TestConnectionId(2));
-  mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
-  mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
-  mock_server_connection1->RetireConnectionId(TestConnectionId(1));
-  mock_server_connection1->RetireConnectionId(TestConnectionId(2));
-
-  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
-  connection1()->CloseConnection(
-      QUIC_PEER_GOING_AWAY, "Close for testing",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
-  EXPECT_FALSE(
-      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(1)));
-  EXPECT_FALSE(
-      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(2)));
-  EXPECT_TRUE(
-      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(3)));
-  EXPECT_TRUE(
-      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(4)));
-
-  dispatcher_->Shutdown();
-}
-
-class BufferedPacketStoreTest : public QuicDispatcherTestBase {
- public:
-  BufferedPacketStoreTest()
-      : QuicDispatcherTestBase(),
-        client_addr_(QuicIpAddress::Loopback4(), 1234) {}
-
-  void ProcessFirstFlight(const ParsedQuicVersion& version,
-                          const QuicSocketAddress& peer_address,
-                          const QuicConnectionId& server_connection_id) {
-    QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
-                                               server_connection_id);
-  }
-
-  void ProcessFirstFlight(const QuicSocketAddress& peer_address,
-                          const QuicConnectionId& server_connection_id) {
-    ProcessFirstFlight(version_, peer_address, server_connection_id);
-  }
-
-  void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
-    ProcessFirstFlight(client_addr_, server_connection_id);
-  }
-
-  void ProcessFirstFlight(const ParsedQuicVersion& version,
-                          const QuicConnectionId& server_connection_id) {
-    ProcessFirstFlight(version, client_addr_, server_connection_id);
-  }
-
-  void ProcessUndecryptableEarlyPacket(
-      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
-      const QuicConnectionId& server_connection_id) {
-    QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
-        version, peer_address, server_connection_id);
-  }
-
-  void ProcessUndecryptableEarlyPacket(
-      const QuicSocketAddress& peer_address,
-      const QuicConnectionId& server_connection_id) {
-    ProcessUndecryptableEarlyPacket(version_, peer_address,
-                                    server_connection_id);
-  }
-
-  void ProcessUndecryptableEarlyPacket(
-      const QuicConnectionId& server_connection_id) {
-    ProcessUndecryptableEarlyPacket(version_, client_addr_,
-                                    server_connection_id);
-  }
-
- protected:
-  QuicSocketAddress client_addr_;
-};
-
-INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests, BufferedPacketStoreTest,
-                         ::testing::ValuesIn(CurrentSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
-  InSequence s;
-  QuicConnectionId conn_id = TestConnectionId(1);
-  // Non-CHLO should be buffered upon arrival, and should trigger
-  // ShouldCreateOrBufferPacketForConnection().
-  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
-                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
-  // Process non-CHLO packet.
-  ProcessUndecryptableEarlyPacket(conn_id);
-  EXPECT_EQ(0u, dispatcher_->NumSessions())
-      << "No session should be created before CHLO arrives.";
-
-  // When CHLO arrives, a new session should be created, and all packets
-  // buffered should be delivered to the session.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(conn_id, _, client_addr_, Eq(ExpectedAlpn()), _,
-                                Eq(ParsedClientHelloForTest())))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
-          &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(2)  // non-CHLO + CHLO.
-      .WillRepeatedly(
-          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-            if (version_.UsesQuicCrypto()) {
-              ValidatePacket(conn_id, packet);
-            }
-          })));
-  ProcessFirstFlight(conn_id);
-}
-
-TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
-  InSequence s;
-  QuicConnectionId conn_id = TestConnectionId(1);
-  // A bunch of non-CHLO should be buffered upon arrival, and the first one
-  // should trigger ShouldCreateOrBufferPacketForConnection().
-  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
-                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
-  for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
-    ProcessUndecryptableEarlyPacket(conn_id);
-  }
-  EXPECT_EQ(0u, dispatcher_->NumSessions())
-      << "No session should be created before CHLO arrives.";
-
-  // Pop out the last packet as it is also be dropped by the store.
-  data_connection_map_[conn_id].pop_back();
-  // When CHLO arrives, a new session should be created, and all packets
-  // buffered should be delivered to the session.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
-                                              Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
-          &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-
-  // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
-  // should be delivered in arrival order.
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(kDefaultMaxUndecryptablePackets + 1)  // + 1 for CHLO.
-      .WillRepeatedly(
-          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-            if (version_.UsesQuicCrypto()) {
-              ValidatePacket(conn_id, packet);
-            }
-          })));
-  ProcessFirstFlight(conn_id);
-}
-
-TEST_P(BufferedPacketStoreTest,
-       ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
-  InSequence s;
-  // A bunch of non-CHLO should be buffered upon arrival.
-  size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
-  for (size_t i = 1; i <= kNumConnections; ++i) {
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
-    QuicConnectionId conn_id = TestConnectionId(i);
-    EXPECT_CALL(*dispatcher_,
-                ShouldCreateOrBufferPacketForConnection(
-                    ReceivedPacketInfoConnectionIdEquals(conn_id)));
-    ProcessUndecryptableEarlyPacket(client_address, conn_id);
-  }
-
-  // Pop out the packet on last connection as it shouldn't be enqueued in store
-  // as well.
-  data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
-
-  // Reset session creation counter to ensure processing CHLO can always
-  // create session.
-  QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
-                                                              kNumConnections);
-  // Process CHLOs to create session for these connections.
-  for (size_t i = 1; i <= kNumConnections; ++i) {
-    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
-    QuicConnectionId conn_id = TestConnectionId(i);
-    if (i == kNumConnections) {
-      EXPECT_CALL(*dispatcher_,
-                  ShouldCreateOrBufferPacketForConnection(
-                      ReceivedPacketInfoConnectionIdEquals(conn_id)));
-    }
-    EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_address,
-                                                Eq(ExpectedAlpn()), _, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
-            &mock_alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-    // First |kNumConnections| - 1 connections should have buffered
-    // a packet in store. The rest should have been dropped.
-    size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-                ProcessUdpPacket(_, client_address, _))
-        .Times(num_packet_to_process)
-        .WillRepeatedly(WithArg<2>(
-            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-              if (version_.UsesQuicCrypto()) {
-                ValidatePacket(conn_id, packet);
-              }
-            })));
-
-    ProcessFirstFlight(client_address, conn_id);
-  }
-}
-
-// Tests that store delivers empty packet list if CHLO arrives firstly.
-TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
-  QuicConnectionId conn_id = TestConnectionId(1);
-  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
-                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
-                                              Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
-          &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, client_addr_, _));
-  ProcessFirstFlight(conn_id);
-}
-
-// Tests that a retransmitted CHLO arrives after a connection for the
-// CHLO has been created.
-TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
-  InSequence s;
-  QuicConnectionId conn_id = TestConnectionId(1);
-  ProcessUndecryptableEarlyPacket(conn_id);
-
-  // When CHLO arrives, a new session should be created, and all packets
-  // buffered should be delivered to the session.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
-                                              Eq(ExpectedAlpn()), _, _))
-      .Times(1)  // Only triggered by 1st CHLO.
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
-          &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(3)  // Triggered by 1 data packet and 2 CHLOs.
-      .WillRepeatedly(
-          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-            if (version_.UsesQuicCrypto()) {
-              ValidatePacket(conn_id, packet);
-            }
-          })));
-
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
-      GetFirstFlightOfPackets(version_, conn_id);
-  ASSERT_EQ(packets.size(), 1u);
-  // Receive the CHLO once.
-  ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
-  // Receive the CHLO a second time to simulate retransmission.
-  ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
-}
-
-// Tests that expiration of a connection add connection id to time wait list.
-TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
-  InSequence s;
-  CreateTimeWaitListManager();
-  QuicBufferedPacketStore* store =
-      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-  QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
-
-  QuicConnectionId conn_id = TestConnectionId(1);
-  ProcessPacket(client_addr_, conn_id, true, absl::StrCat("data packet ", 2),
-                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
-                /*packet_number=*/2);
-
-  mock_helper_.AdvanceTime(
-      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
-  QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
-  // Cancel alarm as if it had been fired.
-  alarm->Cancel();
-  store->OnExpirationTimeout();
-  // New arrived CHLO will be dropped because this connection is in time wait
-  // list.
-  ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
-  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _, _));
-  ProcessFirstFlight(conn_id);
-}
-
-TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
-  // Process more than (|kMaxNumSessionsToCreate| +
-  // |kDefaultMaxConnectionsInStore|) CHLOs,
-  // the first |kMaxNumSessionsToCreate| should create connections immediately,
-  // the next |kDefaultMaxConnectionsInStore| should be buffered,
-  // the rest should be dropped.
-  QuicBufferedPacketStore* store =
-      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-  const size_t kNumCHLOs =
-      kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
-  for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
-    EXPECT_CALL(
-        *dispatcher_,
-        ShouldCreateOrBufferPacketForConnection(
-            ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
-    if (conn_id <= kMaxNumSessionsToCreate) {
-      EXPECT_CALL(*dispatcher_,
-                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                                    Eq(ExpectedAlpn()), _,
-                                    Eq(ParsedClientHelloForTest())))
-          .WillOnce(Return(ByMove(CreateSession(
-              dispatcher_.get(), config_, TestConnectionId(conn_id),
-              client_addr_, &mock_helper_, &mock_alarm_factory_,
-              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
-              &session1_))));
-      EXPECT_CALL(
-          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-          ProcessUdpPacket(_, _, _))
-          .WillOnce(WithArg<2>(
-              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-                if (version_.UsesQuicCrypto()) {
-                  ValidatePacket(TestConnectionId(conn_id), packet);
-                }
-              })));
-    }
-    ProcessFirstFlight(TestConnectionId(conn_id));
-    if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
-        conn_id > kMaxNumSessionsToCreate) {
-      EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
-    } else {
-      // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
-      // connections immediately, and the last CHLO should be dropped as the
-      // store is full.
-      EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
-    }
-  }
-
-  // Graduately consume buffered CHLOs. The buffered connections should be
-  // created but the dropped one shouldn't.
-  for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
-       conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
-       ++conn_id) {
-    EXPECT_CALL(*dispatcher_,
-                CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                                  Eq(ExpectedAlpn()), _,
-                                  Eq(ParsedClientHelloForTest())))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
-            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillOnce(WithArg<2>(
-            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-              if (version_.UsesQuicCrypto()) {
-                ValidatePacket(TestConnectionId(conn_id), packet);
-              }
-            })));
-  }
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(TestConnectionId(kNumCHLOs), _, client_addr_,
-                                Eq(ExpectedAlpn()), _, _))
-      .Times(0);
-
-  while (store->HasChlosBuffered()) {
-    dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-  }
-
-  EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
-                             kDefaultMaxConnectionsInStore),
-            session1_->connection_id());
-}
-
-// Duplicated CHLO shouldn't be buffered.
-TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
-  for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
-       ++conn_id) {
-    // Last CHLO will be buffered. Others will create connection right away.
-    if (conn_id <= kMaxNumSessionsToCreate) {
-      EXPECT_CALL(*dispatcher_,
-                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                                    Eq(ExpectedAlpn()), _, _))
-          .WillOnce(Return(ByMove(CreateSession(
-              dispatcher_.get(), config_, TestConnectionId(conn_id),
-              client_addr_, &mock_helper_, &mock_alarm_factory_,
-              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
-              &session1_))));
-      EXPECT_CALL(
-          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-          ProcessUdpPacket(_, _, _))
-          .WillOnce(WithArg<2>(
-              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-                if (version_.UsesQuicCrypto()) {
-                  ValidatePacket(TestConnectionId(conn_id), packet);
-                }
-              })));
-    }
-    ProcessFirstFlight(TestConnectionId(conn_id));
-  }
-  // Retransmit CHLO on last connection should be dropped.
-  QuicConnectionId last_connection =
-      TestConnectionId(kMaxNumSessionsToCreate + 1);
-  ProcessFirstFlight(last_connection);
-
-  size_t packets_buffered = 2;
-
-  // Reset counter and process buffered CHLO.
-  EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, _, client_addr_,
-                                              Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, last_connection, client_addr_,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  // Only one packet(CHLO) should be process.
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(packets_buffered)
-      .WillRepeatedly(WithArg<2>(
-          Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
-            if (version_.UsesQuicCrypto()) {
-              ValidatePacket(last_connection, packet);
-            }
-          })));
-  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
-  uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
-  QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
-  for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
-    // Last CHLO will be buffered. Others will create connection right away.
-    if (conn_id <= kMaxNumSessionsToCreate) {
-      EXPECT_CALL(*dispatcher_,
-                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                                    Eq(ExpectedAlpn()), _, _))
-          .WillOnce(Return(ByMove(CreateSession(
-              dispatcher_.get(), config_, TestConnectionId(conn_id),
-              client_addr_, &mock_helper_, &mock_alarm_factory_,
-              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
-              &session1_))));
-      EXPECT_CALL(
-          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-          ProcessUdpPacket(_, _, _))
-          .WillRepeatedly(WithArg<2>(
-              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-                if (version_.UsesQuicCrypto()) {
-                  ValidatePacket(TestConnectionId(conn_id), packet);
-                }
-              })));
-    }
-    ProcessFirstFlight(TestConnectionId(conn_id));
-  }
-
-  // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
-  // last one should be dropped.
-  for (uint64_t packet_number = 2;
-       packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
-    ProcessPacket(client_addr_, last_connection_id, true, "data packet");
-  }
-
-  // Reset counter and process buffered CHLO.
-  EXPECT_CALL(*dispatcher_,
-              CreateQuicSession(last_connection_id, _, client_addr_,
-                                Eq(ExpectedAlpn()), _, _))
-      .WillOnce(Return(ByMove(CreateSession(
-          dispatcher_.get(), config_, last_connection_id, client_addr_,
-          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-  // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
-  // should be process.
-  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-              ProcessUdpPacket(_, _, _))
-      .Times(kDefaultMaxUndecryptablePackets + 1)
-      .WillRepeatedly(WithArg<2>(
-          Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
-            if (version_.UsesQuicCrypto()) {
-              ValidatePacket(last_connection_id, packet);
-            }
-          })));
-  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-// Tests that when dispatcher's packet buffer is full, a CHLO on connection
-// which doesn't have buffered CHLO should be buffered.
-TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
-  QuicBufferedPacketStore* store =
-      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
-
-  uint64_t conn_id = 1;
-  ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
-  // Fill packet buffer to full with CHLOs on other connections. Need to feed
-  // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
-  // session directly.
-  for (conn_id = 2;
-       conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
-       ++conn_id) {
-    if (conn_id <= kMaxNumSessionsToCreate + 1) {
-      EXPECT_CALL(*dispatcher_,
-                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                                    Eq(ExpectedAlpn()), _, _))
-          .WillOnce(Return(ByMove(CreateSession(
-              dispatcher_.get(), config_, TestConnectionId(conn_id),
-              client_addr_, &mock_helper_, &mock_alarm_factory_,
-              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
-              &session1_))));
-      EXPECT_CALL(
-          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-          ProcessUdpPacket(_, _, _))
-          .WillOnce(WithArg<2>(
-              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-                if (version_.UsesQuicCrypto()) {
-                  ValidatePacket(TestConnectionId(conn_id), packet);
-                }
-              })));
-    }
-    ProcessFirstFlight(TestConnectionId(conn_id));
-  }
-  EXPECT_FALSE(store->HasChloForConnection(
-      /*connection_id=*/TestConnectionId(1)));
-
-  // CHLO on connection 1 should still be buffered.
-  ProcessFirstFlight(TestConnectionId(1));
-  EXPECT_TRUE(store->HasChloForConnection(
-      /*connection_id=*/TestConnectionId(1)));
-}
-
-// Regression test for b/117874922.
-TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
-  // Ensure the preferred version is not supported by the server.
-  QuicDisableVersion(AllSupportedVersions().front());
-
-  uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
-  ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
-  for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
-    // Last 5 CHLOs will be buffered. Others will create connection right away.
-    ParsedQuicVersion version =
-        supported_versions[(conn_id - 1) % supported_versions.size()];
-    if (conn_id <= kMaxNumSessionsToCreate) {
-      EXPECT_CALL(
-          *dispatcher_,
-          CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                            Eq(ExpectedAlpnForVersion(version)), version, _))
-          .WillOnce(Return(ByMove(CreateSession(
-              dispatcher_.get(), config_, TestConnectionId(conn_id),
-              client_addr_, &mock_helper_, &mock_alarm_factory_,
-              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
-              &session1_))));
-      EXPECT_CALL(
-          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-          ProcessUdpPacket(_, _, _))
-          .WillRepeatedly(WithArg<2>(
-              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-                if (version_.UsesQuicCrypto()) {
-                  ValidatePacket(TestConnectionId(conn_id), packet);
-                }
-              })));
-    }
-    ProcessFirstFlight(version, TestConnectionId(conn_id));
-  }
-
-  // Process buffered CHLOs. Verify the version is correct.
-  for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
-       conn_id <= last_connection_id; ++conn_id) {
-    ParsedQuicVersion version =
-        supported_versions[(conn_id - 1) % supported_versions.size()];
-    EXPECT_CALL(
-        *dispatcher_,
-        CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
-                          Eq(ExpectedAlpnForVersion(version)), version, _))
-        .WillOnce(Return(ByMove(CreateSession(
-            dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
-            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
-            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
-    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
-                ProcessUdpPacket(_, _, _))
-        .WillRepeatedly(WithArg<2>(
-            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
-              if (version_.UsesQuicCrypto()) {
-                ValidatePacket(TestConnectionId(conn_id), packet);
-              }
-            })));
-  }
-  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_epoll_alarm_factory.cc b/quic/core/quic_epoll_alarm_factory.cc
deleted file mode 100644
index 2a08868..0000000
--- a/quic/core/quic_epoll_alarm_factory.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_alarm_factory.h"
-
-#include <type_traits>
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-
-namespace quic {
-namespace {
-
-class QuicEpollAlarm : public QuicAlarm {
- public:
-  QuicEpollAlarm(QuicEpollServer* epoll_server,
-                 QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
-      : QuicAlarm(std::move(delegate)),
-        epoll_server_(epoll_server),
-        epoll_alarm_impl_(this) {}
-
- protected:
-  void SetImpl() override {
-    QUICHE_DCHECK(deadline().IsInitialized());
-    epoll_server_->RegisterAlarm(
-        (deadline() - QuicTime::Zero()).ToMicroseconds(), &epoll_alarm_impl_);
-  }
-
-  void CancelImpl() override {
-    QUICHE_DCHECK(!deadline().IsInitialized());
-    epoll_alarm_impl_.UnregisterIfRegistered();
-  }
-
-  void UpdateImpl() override {
-    QUICHE_DCHECK(deadline().IsInitialized());
-    int64_t epoll_deadline = (deadline() - QuicTime::Zero()).ToMicroseconds();
-    if (epoll_alarm_impl_.registered()) {
-      epoll_alarm_impl_.ReregisterAlarm(epoll_deadline);
-    } else {
-      epoll_server_->RegisterAlarm(epoll_deadline, &epoll_alarm_impl_);
-    }
-  }
-
- private:
-  class EpollAlarmImpl : public QuicEpollAlarmBase {
-   public:
-    using int64_epoll = decltype(QuicEpollAlarmBase().OnAlarm());
-
-    explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
-
-    // Use the same integer type as the base class.
-    int64_epoll OnAlarm() override {
-      QuicEpollAlarmBase::OnAlarm();
-      alarm_->Fire();
-      // Fire will take care of registering the alarm, if needed.
-      return 0;
-    }
-
-   private:
-    QuicEpollAlarm* alarm_;
-  };
-
-  QuicEpollServer* epoll_server_;
-  EpollAlarmImpl epoll_alarm_impl_;
-};
-
-}  // namespace
-
-QuicEpollAlarmFactory::QuicEpollAlarmFactory(QuicEpollServer* epoll_server)
-    : epoll_server_(epoll_server) {}
-
-QuicEpollAlarmFactory::~QuicEpollAlarmFactory() = default;
-
-QuicAlarm* QuicEpollAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
-  return new QuicEpollAlarm(epoll_server_,
-                            QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> QuicEpollAlarmFactory::CreateAlarm(
-    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-    QuicConnectionArena* arena) {
-  if (arena != nullptr) {
-    return arena->New<QuicEpollAlarm>(epoll_server_, std::move(delegate));
-  }
-  return QuicArenaScopedPtr<QuicAlarm>(
-      new QuicEpollAlarm(epoll_server_, std::move(delegate)));
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_epoll_alarm_factory.h b/quic/core/quic_epoll_alarm_factory.h
deleted file mode 100644
index 986b842..0000000
--- a/quic/core/quic_epoll_alarm_factory.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
-#define QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_epoll.h"
-
-namespace quic {
-
-// Creates alarms that use the supplied EpollServer for timing and firing.
-class QUIC_EXPORT_PRIVATE QuicEpollAlarmFactory : public QuicAlarmFactory {
- public:
-  explicit QuicEpollAlarmFactory(QuicEpollServer* epoll_server);
-  QuicEpollAlarmFactory(const QuicEpollAlarmFactory&) = delete;
-  QuicEpollAlarmFactory& operator=(const QuicEpollAlarmFactory&) = delete;
-  ~QuicEpollAlarmFactory() override;
-
-  // QuicAlarmFactory interface.
-  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
-  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-      QuicConnectionArena* arena) override;
-
- private:
-  QuicEpollServer* epoll_server_;  // Not owned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
diff --git a/quic/core/quic_epoll_alarm_factory_test.cc b/quic/core/quic_epoll_alarm_factory_test.cc
deleted file mode 100644
index 976469b..0000000
--- a/quic/core/quic_epoll_alarm_factory_test.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_alarm_factory.h"
-
-#include "quic/core/quic_epoll_clock.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/platform/api/quiche_epoll_test_tools.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
-  TestDelegate() : fired_(false) {}
-
-  void OnAlarm() override { fired_ = true; }
-
-  bool fired() const { return fired_; }
-
- private:
-  bool fired_;
-};
-
-// The boolean parameter denotes whether or not to use an arena.
-class QuicEpollAlarmFactoryTest : public QuicTestWithParam<bool> {
- protected:
-  QuicEpollAlarmFactoryTest()
-      : clock_(&epoll_server_), alarm_factory_(&epoll_server_) {}
-
-  QuicConnectionArena* GetArenaParam() {
-    return GetParam() ? &arena_ : nullptr;
-  }
-
-  const QuicEpollClock clock_;
-  QuicEpollAlarmFactory alarm_factory_;
-  quiche::QuicheFakeEpollServer epoll_server_;
-  QuicConnectionArena arena_;
-};
-
-INSTANTIATE_TEST_SUITE_P(UseArena,
-                         QuicEpollAlarmFactoryTest,
-                         ::testing::ValuesIn({true, false}),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarm) {
-  QuicArenaScopedPtr<TestDelegate> delegate =
-      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
-  QuicArenaScopedPtr<QuicAlarm> alarm(
-      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
-  QuicTime start = clock_.Now();
-  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
-  alarm->Set(start + delta);
-
-  epoll_server_.AdvanceByAndWaitForEventsAndExecuteCallbacks(
-      delta.ToMicroseconds());
-  EXPECT_EQ(start + delta, clock_.Now());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndCancel) {
-  QuicArenaScopedPtr<TestDelegate> delegate =
-      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
-  TestDelegate* unowned_delegate = delegate.get();
-  QuicArenaScopedPtr<QuicAlarm> alarm(
-      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
-  QuicTime start = clock_.Now();
-  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
-  alarm->Set(start + delta);
-  alarm->Cancel();
-
-  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
-  EXPECT_EQ(start + delta, clock_.Now());
-  EXPECT_FALSE(unowned_delegate->fired());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndReset) {
-  QuicArenaScopedPtr<TestDelegate> delegate =
-      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
-  TestDelegate* unowned_delegate = delegate.get();
-  QuicArenaScopedPtr<QuicAlarm> alarm(
-      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
-  QuicTime start = clock_.Now();
-  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
-  alarm->Set(clock_.Now() + delta);
-  alarm->Cancel();
-  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
-  alarm->Set(clock_.Now() + new_delta);
-
-  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
-  EXPECT_EQ(start + delta, clock_.Now());
-  EXPECT_FALSE(unowned_delegate->fired());
-
-  epoll_server_.AdvanceByExactlyAndCallCallbacks(
-      (new_delta - delta).ToMicroseconds());
-  EXPECT_EQ(start + new_delta, clock_.Now());
-  EXPECT_TRUE(unowned_delegate->fired());
-}
-
-TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndUpdate) {
-  QuicArenaScopedPtr<TestDelegate> delegate =
-      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
-  TestDelegate* unowned_delegate = delegate.get();
-  QuicArenaScopedPtr<QuicAlarm> alarm(
-      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
-
-  QuicTime start = clock_.Now();
-  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
-  alarm->Set(clock_.Now() + delta);
-  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
-  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
-
-  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
-  EXPECT_EQ(start + delta, clock_.Now());
-  EXPECT_FALSE(unowned_delegate->fired());
-
-  // Move the alarm forward 1us and ensure it doesn't move forward.
-  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(2));
-
-  epoll_server_.AdvanceByExactlyAndCallCallbacks(
-      (new_delta - delta).ToMicroseconds());
-  EXPECT_EQ(start + new_delta, clock_.Now());
-  EXPECT_TRUE(unowned_delegate->fired());
-
-  // Set the alarm via an update call.
-  new_delta = QuicTime::Delta::FromMicroseconds(5);
-  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
-  EXPECT_TRUE(alarm->IsSet());
-
-  // Update it with an uninitialized time and ensure it's cancelled.
-  alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
-  EXPECT_FALSE(alarm->IsSet());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_epoll_clock.cc b/quic/core/quic_epoll_clock.cc
deleted file mode 100644
index 2c2e5e0..0000000
--- a/quic/core/quic_epoll_clock.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_clock.h"
-
-#include "common/platform/api/quiche_flag_utils.h"
-
-namespace quic {
-
-QuicEpollClock::QuicEpollClock(QuicEpollServer* epoll_server)
-    : epoll_server_(epoll_server), largest_time_(QuicTime::Zero()) {}
-
-QuicEpollClock::~QuicEpollClock() {}
-
-QuicTime QuicEpollClock::ApproximateNow() const {
-  return CreateTimeFromMicroseconds(epoll_server_->ApproximateNowInUsec());
-}
-
-QuicTime QuicEpollClock::Now() const {
-  QuicTime now = CreateTimeFromMicroseconds(epoll_server_->NowInUsec());
-
-  if (now <= largest_time_) {
-    if (now < largest_time_) {
-      QUICHE_CODE_COUNT(quic_epoll_clock_step_backward);
-    }
-    // Time not increasing, return |largest_time_|.
-    return largest_time_;
-  }
-
-  largest_time_ = now;
-  return largest_time_;
-}
-
-QuicWallTime QuicEpollClock::WallNow() const {
-  return QuicWallTime::FromUNIXMicroseconds(
-      epoll_server_->ApproximateNowInUsec());
-}
-
-QuicTime QuicEpollClock::ConvertWallTimeToQuicTime(
-    const QuicWallTime& walltime) const {
-  return QuicTime::Zero() +
-         QuicTime::Delta::FromMicroseconds(walltime.ToUNIXMicroseconds());
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_epoll_clock.h b/quic/core/quic_epoll_clock.h
deleted file mode 100644
index 282b1ca..0000000
--- a/quic/core/quic_epoll_clock.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
-#define QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Clock to efficiently retrieve an approximately accurate time from an
-// EpollServer.
-class QUIC_EXPORT_PRIVATE QuicEpollClock : public QuicClock {
- public:
-  explicit QuicEpollClock(QuicEpollServer* epoll_server);
-  QuicEpollClock(const QuicEpollClock&) = delete;
-  QuicEpollClock& operator=(const QuicEpollClock&) = delete;
-  ~QuicEpollClock() override;
-
-  // Returns the approximate current time as a QuicTime object.
-  QuicTime ApproximateNow() const override;
-
-  // Returns the current time as a QuicTime object.
-  // Note: this use significant resources please use only if needed.
-  QuicTime Now() const override;
-
-  // WallNow returns the current wall-time - a time that is consistent across
-  // different clocks.
-  QuicWallTime WallNow() const override;
-
-  // Override to do less work in this implementation.  The epoll clock is
-  // already based on system (unix epoch) time, no conversion required.
-  QuicTime ConvertWallTimeToQuicTime(
-      const QuicWallTime& walltime) const override;
-
- protected:
-  QuicEpollServer* epoll_server_;
-  // Largest time returned from Now() so far.
-  mutable QuicTime largest_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
diff --git a/quic/core/quic_epoll_clock_test.cc b/quic/core/quic_epoll_clock_test.cc
deleted file mode 100644
index cbe8123..0000000
--- a/quic/core/quic_epoll_clock_test.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_clock.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "common/platform/api/quiche_epoll_test_tools.h"
-
-namespace quic {
-namespace test {
-
-class QuicEpollClockTest : public QuicTest {};
-
-TEST_F(QuicEpollClockTest, ApproximateNowInUsec) {
-  quiche::QuicheFakeEpollServer epoll_server;
-  QuicEpollClock clock(&epoll_server);
-
-  epoll_server.set_now_in_usec(1000000);
-  EXPECT_EQ(1000000,
-            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
-  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
-  EXPECT_EQ(1000000u, clock.WallNow().ToUNIXMicroseconds());
-
-  epoll_server.AdvanceBy(5);
-  EXPECT_EQ(1000005,
-            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
-  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
-  EXPECT_EQ(1000005u, clock.WallNow().ToUNIXMicroseconds());
-
-  epoll_server.AdvanceBy(10 * 1000000);
-  EXPECT_EQ(11u, clock.WallNow().ToUNIXSeconds());
-  EXPECT_EQ(11000005u, clock.WallNow().ToUNIXMicroseconds());
-}
-
-TEST_F(QuicEpollClockTest, NowInUsec) {
-  quiche::QuicheFakeEpollServer epoll_server;
-  QuicEpollClock clock(&epoll_server);
-
-  epoll_server.set_now_in_usec(1000000);
-  EXPECT_EQ(1000000, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
-
-  epoll_server.AdvanceBy(5);
-  EXPECT_EQ(1000005, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
-}
-
-TEST_F(QuicEpollClockTest, CalibrateRealEpollClock) {
-  QuicEpollServer epoll_server;
-
-  QuicEpollClock uncalibrated_clock(&epoll_server);
-  QuicEpollClock calibrated_clock(&epoll_server);
-  EXPECT_TRUE(calibrated_clock.ComputeCalibrationOffset().IsZero());
-
-  for (int i = 0; i < 100; ++i) {
-    QuicWallTime wallnow = uncalibrated_clock.WallNow();
-    EXPECT_EQ(uncalibrated_clock.ConvertWallTimeToQuicTime(wallnow),
-              calibrated_clock.ConvertWallTimeToQuicTime(wallnow));
-  }
-}
-
-// ClockWithOffset is a clock whose offset(WallNow() - Now() at any instant) is
-// given at construction time.
-class ClockWithOffset : public QuicEpollClock {
- public:
-  ClockWithOffset(QuicEpollServer* epoll_server, QuicTime::Delta offset)
-      : QuicEpollClock(epoll_server), offset_(offset) {}
-
-  QuicTime Now() const override { return QuicEpollClock::Now() - offset_; }
-
-  // QuicEpollClock disables ConvertWallTimeToQuicTime since it always have a
-  // zero offset. We need to re-enable it here in order to test the calibration
-  // and conversion code in QuicClock.
-  QuicTime ConvertWallTimeToQuicTime(
-      const QuicWallTime& walltime) const override {
-    return QuicClock::ConvertWallTimeToQuicTime(walltime);
-  }
-
- private:
-  QuicTime::Delta offset_;
-};
-
-TEST_F(QuicEpollClockTest, CalibrateClockWithOffset) {
-  QuicEpollServer epoll_server;
-
-  for (const QuicTime::Delta& offset : {QuicTime::Delta::FromSeconds(5000),
-                                        QuicTime::Delta::FromSeconds(-8000)}) {
-    ClockWithOffset clock(&epoll_server, offset);
-    ASSERT_EQ(offset, clock.ComputeCalibrationOffset())
-        << "offset (us): " << offset.ToMicroseconds();
-    // Test fails without this.
-    clock.SetCalibrationOffset(offset);
-
-    QuicWallTime last_walltime = clock.WallNow();
-    QuicTime last_time = clock.ConvertWallTimeToQuicTime(last_walltime);
-
-    for (int i = 0; i < 1e5; ++i) {
-      QuicWallTime wallnow = clock.WallNow();
-      QuicTime now = clock.ConvertWallTimeToQuicTime(wallnow);
-
-      if (wallnow.IsAfter(last_walltime)) {
-        ASSERT_LT(0, (now - last_time).ToMicroseconds())
-            << "offset (us): " << offset.ToMicroseconds();
-
-        last_walltime = wallnow;
-        last_time = now;
-      }
-    }
-  }
-}
-
-TEST_F(QuicEpollClockTest, MonotonicityWithRealEpollClock) {
-  QuicEpollServer epoll_server;
-  QuicEpollClock clock(&epoll_server);
-
-  QuicTime last_now = clock.Now();
-  for (int i = 0; i < 1e5; ++i) {
-    QuicTime now = clock.Now();
-
-    ASSERT_LE(last_now, now);
-
-    last_now = now;
-  }
-}
-
-TEST_F(QuicEpollClockTest, MonotonicityWithFakeEpollClock) {
-  quiche::QuicheFakeEpollServer epoll_server;
-  QuicEpollClock clock(&epoll_server);
-
-  epoll_server.set_now_in_usec(100);
-  QuicTime last_now = clock.Now();
-
-  epoll_server.set_now_in_usec(90);
-  QuicTime now = clock.Now();
-
-  ASSERT_EQ(last_now, now);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_epoll_connection_helper.cc b/quic/core/quic_epoll_connection_helper.cc
deleted file mode 100644
index 980a09f..0000000
--- a/quic/core/quic_epoll_connection_helper.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_connection_helper.h"
-
-#include <errno.h>
-#include <sys/socket.h>
-
-#include "quic/core/crypto/quic_random.h"
-
-namespace quic {
-
-QuicEpollConnectionHelper::QuicEpollConnectionHelper(
-    QuicEpollServer* epoll_server, QuicAllocator allocator_type)
-    : clock_(epoll_server),
-      random_generator_(QuicRandom::GetInstance()),
-      allocator_type_(allocator_type) {}
-
-QuicEpollConnectionHelper::~QuicEpollConnectionHelper() = default;
-
-const QuicClock* QuicEpollConnectionHelper::GetClock() const {
-  return &clock_;
-}
-
-QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() {
-  return random_generator_;
-}
-
-quiche::QuicheBufferAllocator*
-QuicEpollConnectionHelper::GetStreamSendBufferAllocator() {
-  if (allocator_type_ == QuicAllocator::BUFFER_POOL) {
-    return &stream_buffer_allocator_;
-  } else {
-    QUICHE_DCHECK(allocator_type_ == QuicAllocator::SIMPLE);
-    return &simple_buffer_allocator_;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_epoll_connection_helper.h b/quic/core/quic_epoll_connection_helper.h
deleted file mode 100644
index d944c0e..0000000
--- a/quic/core/quic_epoll_connection_helper.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The epoll-specific helper for QuicConnection which uses
-// EpollAlarm for alarms, and used an int fd_ for writing data.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
-#define QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
-
-#include <sys/types.h>
-
-#include <set>
-
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_epoll_clock.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_stream_buffer_allocator.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-
-class QuicRandom;
-
-enum class QuicAllocator { SIMPLE, BUFFER_POOL };
-
-class QUIC_EXPORT_PRIVATE QuicEpollConnectionHelper
-    : public QuicConnectionHelperInterface {
- public:
-  QuicEpollConnectionHelper(QuicEpollServer* epoll_server,
-                            QuicAllocator allocator_type);
-  QuicEpollConnectionHelper(const QuicEpollConnectionHelper&) = delete;
-  QuicEpollConnectionHelper& operator=(const QuicEpollConnectionHelper&) =
-      delete;
-  ~QuicEpollConnectionHelper() override;
-
-  // QuicConnectionHelperInterface
-  const QuicClock* GetClock() const override;
-  QuicRandom* GetRandomGenerator() override;
-  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
-
- private:
-  const QuicEpollClock clock_;
-  QuicRandom* random_generator_;
-  // Set up allocators.  They take up minimal memory before use.
-  // Allocator for stream send buffers.
-  QuicStreamBufferAllocator stream_buffer_allocator_;
-  quiche::SimpleBufferAllocator simple_buffer_allocator_;
-  QuicAllocator allocator_type_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
diff --git a/quic/core/quic_epoll_connection_helper_test.cc b/quic/core/quic_epoll_connection_helper_test.cc
deleted file mode 100644
index 6965cd2..0000000
--- a/quic/core/quic_epoll_connection_helper_test.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_epoll_connection_helper.h"
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/platform/api/quiche_epoll_test_tools.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicEpollConnectionHelperTest : public QuicTest {
- protected:
-  QuicEpollConnectionHelperTest()
-      : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL) {}
-
-  quiche::QuicheFakeEpollServer epoll_server_;
-  QuicEpollConnectionHelper helper_;
-};
-
-TEST_F(QuicEpollConnectionHelperTest, GetClock) {
-  const QuicClock* clock = helper_.GetClock();
-  QuicTime start = clock->Now();
-
-  QuicTime::Delta delta = QuicTime::Delta::FromMilliseconds(5);
-  epoll_server_.AdvanceBy(delta.ToMicroseconds());
-
-  EXPECT_EQ(start + delta, clock->Now());
-}
-
-TEST_F(QuicEpollConnectionHelperTest, GetRandomGenerator) {
-  QuicRandom* random = helper_.GetRandomGenerator();
-  EXPECT_EQ(QuicRandom::GetInstance(), random);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_error_codes.cc b/quic/core/quic_error_codes.cc
deleted file mode 100644
index 36c5510..0000000
--- a/quic/core/quic_error_codes.cc
+++ /dev/null
@@ -1,975 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_error_codes.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/strings/str_cat.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x;
-
-const char* QuicRstStreamErrorCodeToString(QuicRstStreamErrorCode error) {
-  switch (error) {
-    RETURN_STRING_LITERAL(QUIC_STREAM_NO_ERROR);
-    RETURN_STRING_LITERAL(QUIC_ERROR_PROCESSING_STREAM);
-    RETURN_STRING_LITERAL(QUIC_MULTIPLE_TERMINATION_OFFSETS);
-    RETURN_STRING_LITERAL(QUIC_BAD_APPLICATION_PAYLOAD);
-    RETURN_STRING_LITERAL(QUIC_STREAM_CONNECTION_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY);
-    RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED);
-    RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT);
-    RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_URL);
-    RETURN_STRING_LITERAL(QUIC_UNAUTHORIZED_PROMISE_URL);
-    RETURN_STRING_LITERAL(QUIC_DUPLICATE_PROMISE_URL);
-    RETURN_STRING_LITERAL(QUIC_PROMISE_VARY_MISMATCH);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_METHOD);
-    RETURN_STRING_LITERAL(QUIC_PUSH_STREAM_TIMED_OUT);
-    RETURN_STRING_LITERAL(QUIC_HEADERS_TOO_LARGE);
-    RETURN_STRING_LITERAL(QUIC_STREAM_TTL_EXPIRED);
-    RETURN_STRING_LITERAL(QUIC_DATA_AFTER_CLOSE_OFFSET);
-    RETURN_STRING_LITERAL(QUIC_STREAM_GENERAL_PROTOCOL_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_INTERNAL_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_STREAM_CREATION_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_CLOSED_CRITICAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_UNEXPECTED);
-    RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_EXCESSIVE_LOAD);
-    RETURN_STRING_LITERAL(QUIC_STREAM_ID_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_SETTINGS_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_MISSING_SETTINGS);
-    RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_REJECTED);
-    RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_INCOMPLETE);
-    RETURN_STRING_LITERAL(QUIC_STREAM_CONNECT_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_VERSION_FALLBACK);
-    RETURN_STRING_LITERAL(QUIC_STREAM_DECOMPRESSION_FAILED);
-    RETURN_STRING_LITERAL(QUIC_STREAM_ENCODER_STREAM_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_DECODER_STREAM_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE);
-    RETURN_STRING_LITERAL(QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
-    RETURN_STRING_LITERAL(
-        QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
-    RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR);
-  }
-  // Return a default value so that we return this when |error| doesn't match
-  // any of the QuicRstStreamErrorCodes. This can happen when the RstStream
-  // frame sent by the peer (attacker) has invalid error code.
-  return "INVALID_RST_STREAM_ERROR_CODE";
-}
-
-const char* QuicErrorCodeToString(QuicErrorCode error) {
-  switch (error) {
-    RETURN_STRING_LITERAL(QUIC_NO_ERROR);
-    RETURN_STRING_LITERAL(QUIC_INTERNAL_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STREAM_DATA_AFTER_TERMINATION);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PACKET_HEADER);
-    RETURN_STRING_LITERAL(QUIC_INVALID_FRAME_DATA);
-    RETURN_STRING_LITERAL(QUIC_MISSING_PAYLOAD);
-    RETURN_STRING_LITERAL(QUIC_INVALID_FEC_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_DATA);
-    RETURN_STRING_LITERAL(QUIC_OVERLAPPING_STREAM_DATA);
-    RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_STREAM_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_RST_STREAM_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_CONNECTION_CLOSE_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_GOAWAY_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_WINDOW_UPDATE_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_BLOCKED_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_STOP_WAITING_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CLOSE_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_ACK_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PUBLIC_RST_PACKET);
-    RETURN_STRING_LITERAL(QUIC_DECRYPTION_FAILURE);
-    RETURN_STRING_LITERAL(QUIC_ENCRYPTION_FAILURE);
-    RETURN_STRING_LITERAL(QUIC_PACKET_TOO_LARGE);
-    RETURN_STRING_LITERAL(QUIC_PEER_GOING_AWAY);
-    RETURN_STRING_LITERAL(QUIC_HANDSHAKE_FAILED);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_TAGS_OUT_OF_ORDER);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_ENTRIES);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_REJECTS);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_INVALID_VALUE_LENGTH)
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_INTERNAL_ERROR);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_VERSION_NOT_SUPPORTED);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_NO_SUPPORT);
-    RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
-    RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND);
-    RETURN_STRING_LITERAL(QUIC_UNSUPPORTED_PROOF_DEMAND);
-    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_ID);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OPEN_STREAMS);
-    RETURN_STRING_LITERAL(QUIC_PUBLIC_RESET);
-    RETURN_STRING_LITERAL(QUIC_INVALID_VERSION);
-    RETURN_STRING_LITERAL(QUIC_PACKET_WRONG_VERSION);
-    RETURN_STRING_LITERAL(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
-    RETURN_STRING_LITERAL(QUIC_INVALID_HEADER_ID);
-    RETURN_STRING_LITERAL(QUIC_INVALID_NEGOTIATED_VALUE);
-    RETURN_STRING_LITERAL(QUIC_DECOMPRESSION_FAILURE);
-    RETURN_STRING_LITERAL(QUIC_NETWORK_IDLE_TIMEOUT);
-    RETURN_STRING_LITERAL(QUIC_HANDSHAKE_TIMEOUT);
-    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_ADDRESS);
-    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_PORT);
-    RETURN_STRING_LITERAL(QUIC_PACKET_WRITE_ERROR);
-    RETURN_STRING_LITERAL(QUIC_PACKET_READ_ERROR);
-    RETURN_STRING_LITERAL(QUIC_EMPTY_STREAM_FRAME_NO_FIN);
-    RETURN_STRING_LITERAL(QUIC_INVALID_HEADERS_STREAM_DATA);
-    RETURN_STRING_LITERAL(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
-    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
-    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
-    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_INVALID_WINDOW);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_IP_POOLED);
-    RETURN_STRING_LITERAL(QUIC_PROOF_INVALID);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_DUPLICATE_TAG);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED);
-    RETURN_STRING_LITERAL(QUIC_INVALID_CHANNEL_ID_SIGNATURE);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE);
-    RETURN_STRING_LITERAL(QUIC_VERSION_NEGOTIATION_MISMATCH);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_CANCELLED);
-    RETURN_STRING_LITERAL(QUIC_BAD_PACKET_LOSS_RATE);
-    RETURN_STRING_LITERAL(QUIC_PUBLIC_RESETS_POST_HANDSHAKE);
-    RETURN_STRING_LITERAL(QUIC_FAILED_TO_SERIALIZE_PACKET);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_AVAILABLE_STREAMS);
-    RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_FEC_DATA);
-    RETURN_STRING_LITERAL(QUIC_BAD_MULTIPATH_FLAG);
-    RETURN_STRING_LITERAL(QUIC_IP_ADDRESS_CHANGED);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_RTOS);
-    RETURN_STRING_LITERAL(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA);
-    RETURN_STRING_LITERAL(QUIC_MAYBE_CORRUPTED_MEMORY);
-    RETURN_STRING_LITERAL(QUIC_CRYPTO_CHLO_TOO_LARGE);
-    RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST);
-    RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_NOT_ACTIVE);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_STREAM_DATA_INTERVALS);
-    RETURN_STRING_LITERAL(QUIC_STREAM_SEQUENCER_INVALID_STATE);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_SESSIONS_ON_SERVER);
-    RETURN_STRING_LITERAL(QUIC_STREAM_LENGTH_OVERFLOW);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR);
-    RETURN_STRING_LITERAL(QUIC_INVALID_MAX_DATA_FRAME_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_BLOCKED_DATA);
-    RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_DATA);
-    RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_ID_LIMIT_ERROR);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE);
-    RETURN_STRING_LITERAL(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CHALLENGE_DATA);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_RESPONSE_DATA);
-    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED);
-    RETURN_STRING_LITERAL(QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED);
-    RETURN_STRING_LITERAL(QUIC_INVALID_MESSAGE_DATA);
-    RETURN_STRING_LITERAL(IETF_QUIC_PROTOCOL_VIOLATION);
-    RETURN_STRING_LITERAL(QUIC_INVALID_NEW_TOKEN);
-    RETURN_STRING_LITERAL(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_ERROR);
-    RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HTTP_DECODER_ERROR);
-    RETURN_STRING_LITERAL(QUIC_STALE_CONNECTION_CANCELLED);
-    RETURN_STRING_LITERAL(QUIC_IETF_GQUIC_ERROR_MISSING);
-    RETURN_STRING_LITERAL(
-        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES);
-    RETURN_STRING_LITERAL(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECOMPRESSION_FAILED);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_ERROR);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC);
-    RETURN_STRING_LITERAL(
-        QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX);
-    RETURN_STRING_LITERAL(
-        QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL);
-    RETURN_STRING_LITERAL(
-        QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX);
-    RETURN_STRING_LITERAL(
-        QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND);
-    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT);
-    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT);
-    RETURN_STRING_LITERAL(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET);
-    RETURN_STRING_LITERAL(QUIC_STREAM_MULTIPLE_OFFSET);
-    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_TOO_LARGE);
-    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_WRONG_DIRECTION);
-    RETURN_STRING_LITERAL(QUIC_HTTP_CLOSED_CRITICAL_STREAM);
-    RETURN_STRING_LITERAL(QUIC_HTTP_MISSING_SETTINGS_FRAME);
-    RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER);
-    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_MAX_PUSH_ID);
-    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_LIMIT_TOO_LOW);
-    RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH);
-    RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH);
-    RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID);
-    RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS);
-    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_SETTING);
-    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_FRAME);
-    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SERVER_PUSH);
-    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_SETTING_VALUE);
-    RETURN_STRING_LITERAL(QUIC_HPACK_INDEX_VARINT_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_TOO_LONG);
-    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_TOO_LONG);
-    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_HUFFMAN_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_HUFFMAN_ERROR);
-    RETURN_STRING_LITERAL(QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE);
-    RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_INDEX);
-    RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_NAME_INDEX);
-    RETURN_STRING_LITERAL(QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED);
-    RETURN_STRING_LITERAL(
-        QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK);
-    RETURN_STRING_LITERAL(
-        QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING);
-    RETURN_STRING_LITERAL(QUIC_HPACK_TRUNCATED_BLOCK);
-    RETURN_STRING_LITERAL(QUIC_HPACK_FRAGMENT_TOO_LONG);
-    RETURN_STRING_LITERAL(QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT);
-    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_UNRETRANSMITTABLE);
-    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED);
-    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED);
-    RETURN_STRING_LITERAL(QUIC_SILENT_IDLE_TIMEOUT);
-    RETURN_STRING_LITERAL(QUIC_MISSING_WRITE_KEYS);
-    RETURN_STRING_LITERAL(QUIC_KEY_UPDATE_ERROR);
-    RETURN_STRING_LITERAL(QUIC_AEAD_LIMIT_REACHED);
-    RETURN_STRING_LITERAL(QUIC_MAX_AGE_TIMEOUT);
-    RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY_UPDATE);
-    RETURN_STRING_LITERAL(QUIC_TLS_BAD_CERTIFICATE);
-    RETURN_STRING_LITERAL(QUIC_TLS_UNSUPPORTED_CERTIFICATE);
-    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REVOKED);
-    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_EXPIRED);
-    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_UNKNOWN);
-    RETURN_STRING_LITERAL(QUIC_TLS_INTERNAL_ERROR);
-    RETURN_STRING_LITERAL(QUIC_TLS_UNRECOGNIZED_NAME);
-    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REQUIRED);
-    RETURN_STRING_LITERAL(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE);
-    RETURN_STRING_LITERAL(QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL);
-    RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH);
-    RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE);
-    RETURN_STRING_LITERAL(QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED);
-
-    RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
-    // Intentionally have no default case, so we'll break the build
-    // if we add errors and don't put them here.
-  }
-  // Return a default value so that we return this when |error| doesn't match
-  // any of the QuicErrorCodes. This can happen when the ConnectionClose
-  // frame sent by the peer (attacker) has invalid error code.
-  return "INVALID_ERROR_CODE";
-}
-
-std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) {
-  if (c >= CRYPTO_ERROR_FIRST && c <= CRYPTO_ERROR_LAST) {
-    const int tls_error = static_cast<int>(c - CRYPTO_ERROR_FIRST);
-    const char* tls_error_description = SSL_alert_desc_string_long(tls_error);
-    if (strcmp("unknown", tls_error_description) != 0) {
-      return absl::StrCat("CRYPTO_ERROR(", tls_error_description, ")");
-    }
-    return absl::StrCat("CRYPTO_ERROR(unknown(", tls_error, "))");
-  }
-
-  switch (c) {
-    RETURN_STRING_LITERAL(NO_IETF_QUIC_ERROR);
-    RETURN_STRING_LITERAL(INTERNAL_ERROR);
-    RETURN_STRING_LITERAL(SERVER_BUSY_ERROR);
-    RETURN_STRING_LITERAL(FLOW_CONTROL_ERROR);
-    RETURN_STRING_LITERAL(STREAM_LIMIT_ERROR);
-    RETURN_STRING_LITERAL(STREAM_STATE_ERROR);
-    RETURN_STRING_LITERAL(FINAL_SIZE_ERROR);
-    RETURN_STRING_LITERAL(FRAME_ENCODING_ERROR);
-    RETURN_STRING_LITERAL(TRANSPORT_PARAMETER_ERROR);
-    RETURN_STRING_LITERAL(CONNECTION_ID_LIMIT_ERROR);
-    RETURN_STRING_LITERAL(PROTOCOL_VIOLATION);
-    RETURN_STRING_LITERAL(INVALID_TOKEN);
-    RETURN_STRING_LITERAL(CRYPTO_BUFFER_EXCEEDED);
-    RETURN_STRING_LITERAL(KEY_UPDATE_ERROR);
-    RETURN_STRING_LITERAL(AEAD_LIMIT_REACHED);
-    // CRYPTO_ERROR is handled in the if before this switch, these cases do not
-    // change behavior and are only here to make the compiler happy.
-    case CRYPTO_ERROR_FIRST:
-    case CRYPTO_ERROR_LAST:
-      QUICHE_DCHECK(false) << "Unexpected error " << static_cast<uint64_t>(c);
-      break;
-  }
-
-  return absl::StrCat("Unknown(", static_cast<uint64_t>(c), ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicIetfTransportErrorCodes& c) {
-  os << QuicIetfTransportErrorCodeString(c);
-  return os;
-}
-
-QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
-    QuicErrorCode error) {
-  switch (error) {
-    case QUIC_NO_ERROR:
-      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
-    case QUIC_INTERNAL_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_STREAM_DATA_AFTER_TERMINATION:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_PACKET_HEADER:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_FRAME_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_MISSING_PAYLOAD:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_FEC_DATA:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_STREAM_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_OVERLAPPING_STREAM_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_UNENCRYPTED_STREAM_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_MAYBE_CORRUPTED_MEMORY:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_UNENCRYPTED_FEC_DATA:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_RST_STREAM_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_CONNECTION_CLOSE_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_GOAWAY_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_WINDOW_UPDATE_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_BLOCKED_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_STOP_WAITING_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_PATH_CLOSE_DATA:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_ACK_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_MESSAGE_DATA:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_VERSION_NEGOTIATION_PACKET:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_PUBLIC_RST_PACKET:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_DECRYPTION_FAILURE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_ENCRYPTION_FAILURE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_PACKET_TOO_LARGE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_PEER_GOING_AWAY:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_STREAM_ID:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_PRIORITY:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_TOO_MANY_OPEN_STREAMS:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_TOO_MANY_AVAILABLE_STREAMS:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_PUBLIC_RESET:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_VERSION:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_PACKET_WRONG_VERSION:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_HEADER_ID:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_NEGOTIATED_VALUE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_DECOMPRESSION_FAILURE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_NETWORK_IDLE_TIMEOUT:
-      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
-    case QUIC_SILENT_IDLE_TIMEOUT:
-      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
-    case QUIC_HANDSHAKE_TIMEOUT:
-      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
-    case QUIC_ERROR_MIGRATING_ADDRESS:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_ERROR_MIGRATING_PORT:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_PACKET_WRITE_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_PACKET_READ_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_EMPTY_STREAM_FRAME_NO_FIN:
-      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
-    case QUIC_INVALID_HEADERS_STREAM_DATA:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA:
-      return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
-    case QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_FLOW_CONTROL_INVALID_WINDOW:
-      return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
-    case QUIC_CONNECTION_IP_POOLED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_CANCELLED:
-      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
-    case QUIC_BAD_PACKET_LOSS_RATE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_PUBLIC_RESETS_POST_HANDSHAKE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_FAILED_TO_SERIALIZE_PACKET:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_TOO_MANY_RTOS:
-      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
-    case QUIC_HANDSHAKE_FAILED:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_TAGS_OUT_OF_ORDER:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_TOO_MANY_ENTRIES:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_INVALID_VALUE_LENGTH:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_CRYPTO_MESSAGE_TYPE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_CHANNEL_ID_SIGNATURE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_UNSUPPORTED_PROOF_DEMAND:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_INTERNAL_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CRYPTO_VERSION_NOT_SUPPORTED:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_NO_SUPPORT:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_TOO_MANY_REJECTS:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_PROOF_INVALID:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_DUPLICATE_TAG:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_SERVER_CONFIG_EXPIRED:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_CRYPTO_CHLO_TOO_LARGE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_VERSION_NEGOTIATION_MISMATCH:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_BAD_MULTIPATH_FLAG:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_MULTIPATH_PATH_DOES_NOT_EXIST:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_MULTIPATH_PATH_NOT_ACTIVE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_IP_ADDRESS_CHANGED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_TOO_MANY_STREAM_DATA_INTERVALS:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_STREAM_SEQUENCER_INVALID_STATE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_TOO_MANY_SESSIONS_ON_SERVER:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_STREAM_LENGTH_OVERFLOW:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_MAX_DATA_FRAME_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_MAX_STREAMS_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_STREAMS_BLOCKED_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_STREAM_BLOCKED_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_NEW_CONNECTION_ID_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_STOP_SENDING_FRAME_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_PATH_CHALLENGE_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_PATH_RESPONSE_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case IETF_QUIC_PROTOCOL_VIOLATION:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_INVALID_NEW_TOKEN:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM:
-      return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
-    case QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_RETIRE_CONNECTION_ID_DATA:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_STREAMS_BLOCKED_ERROR:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_MAX_STREAMS_ERROR:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_HTTP_DECODER_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_STALE_CONNECTION_CANCELLED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_IETF_GQUIC_ERROR_MISSING:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_QPACK_DECOMPRESSION_FAILED:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECOMPRESSION_FAILED)};
-    case QUIC_QPACK_ENCODER_STREAM_ERROR:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_DECODER_STREAM_ERROR:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
-    case QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
-    case QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
-    case QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
-    case QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
-    case QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT:
-      return {false, static_cast<uint64_t>(
-                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
-    case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_STREAM_MULTIPLE_OFFSET:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_HTTP_FRAME_TOO_LARGE:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD)};
-    case QUIC_HTTP_FRAME_ERROR:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR)};
-    case QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
-    case QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
-    case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
-    case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
-    case QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
-    case QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
-    case QUIC_HTTP_STREAM_WRONG_DIRECTION:
-      return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
-    case QUIC_HTTP_CLOSED_CRITICAL_STREAM:
-      return {false, static_cast<uint64_t>(
-                         QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM)};
-    case QUIC_HTTP_MISSING_SETTINGS_FRAME:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS)};
-    case QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
-    case QUIC_HTTP_INVALID_MAX_PUSH_ID:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
-    case QUIC_HTTP_STREAM_LIMIT_TOO_LOW:
-      return {false, static_cast<uint64_t>(
-                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
-    case QUIC_HTTP_RECEIVE_SERVER_PUSH:
-      return {false, static_cast<uint64_t>(
-                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
-    case QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
-    case QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HTTP_GOAWAY_INVALID_STREAM_ID:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
-    case QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
-    case QUIC_HTTP_RECEIVE_SPDY_SETTING:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
-    case QUIC_HTTP_INVALID_SETTING_VALUE:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
-    case QUIC_HTTP_RECEIVE_SPDY_FRAME:
-      return {false,
-              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
-    case QUIC_HPACK_INDEX_VARINT_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_NAME_TOO_LONG:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_VALUE_TOO_LONG:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_NAME_HUFFMAN_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_VALUE_HUFFMAN_ERROR:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_INVALID_INDEX:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_INVALID_NAME_INDEX:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_TRUNCATED_BLOCK:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_FRAGMENT_TOO_LONG:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_ZERO_RTT_UNRETRANSMITTABLE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_MISSING_WRITE_KEYS:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_KEY_UPDATE_ERROR:
-      return {true, static_cast<uint64_t>(KEY_UPDATE_ERROR)};
-    case QUIC_AEAD_LIMIT_REACHED:
-      return {true, static_cast<uint64_t>(AEAD_LIMIT_REACHED)};
-    case QUIC_MAX_AGE_TIMEOUT:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR)};
-    case QUIC_INVALID_PRIORITY_UPDATE:
-      return {false, static_cast<uint64_t>(
-                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
-    case QUIC_TLS_BAD_CERTIFICATE:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_BAD_CERTIFICATE)};
-    case QUIC_TLS_UNSUPPORTED_CERTIFICATE:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_UNSUPPORTED_CERTIFICATE)};
-    case QUIC_TLS_CERTIFICATE_REVOKED:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_CERTIFICATE_REVOKED)};
-    case QUIC_TLS_CERTIFICATE_EXPIRED:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_CERTIFICATE_EXPIRED)};
-    case QUIC_TLS_CERTIFICATE_UNKNOWN:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_CERTIFICATE_UNKNOWN)};
-    case QUIC_TLS_INTERNAL_ERROR:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_INTERNAL_ERROR)};
-    case QUIC_TLS_UNRECOGNIZED_NAME:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_UNRECOGNIZED_NAME)};
-    case QUIC_TLS_CERTIFICATE_REQUIRED:
-      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
-                                          SSL_AD_CERTIFICATE_REQUIRED)};
-    case QUIC_CONNECTION_ID_LIMIT_ERROR:
-      return {true, static_cast<uint64_t>(CONNECTION_ID_LIMIT_ERROR)};
-    case QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE:
-      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-    case QUIC_INVALID_CHARACTER_IN_FIELD_VALUE:
-      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::MESSAGE_ERROR)};
-    case QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED:
-      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
-    case QUIC_LAST_ERROR:
-      return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)};
-  }
-  // This function should not be called with unknown error code.
-  return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
-}
-
-QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc) {
-  switch (desc) {
-    case SSL_AD_BAD_CERTIFICATE:
-      return QUIC_TLS_BAD_CERTIFICATE;
-    case SSL_AD_UNSUPPORTED_CERTIFICATE:
-      return QUIC_TLS_UNSUPPORTED_CERTIFICATE;
-    case SSL_AD_CERTIFICATE_REVOKED:
-      return QUIC_TLS_CERTIFICATE_REVOKED;
-    case SSL_AD_CERTIFICATE_EXPIRED:
-      return QUIC_TLS_CERTIFICATE_EXPIRED;
-    case SSL_AD_CERTIFICATE_UNKNOWN:
-      return QUIC_TLS_CERTIFICATE_UNKNOWN;
-    case SSL_AD_INTERNAL_ERROR:
-      return QUIC_TLS_INTERNAL_ERROR;
-    case SSL_AD_UNRECOGNIZED_NAME:
-      return QUIC_TLS_UNRECOGNIZED_NAME;
-    case SSL_AD_CERTIFICATE_REQUIRED:
-      return QUIC_TLS_CERTIFICATE_REQUIRED;
-    default:
-      return QUIC_HANDSHAKE_FAILED;
-  }
-}
-
-// Convert a QuicRstStreamErrorCode to an application error code to be used in
-// an IETF QUIC RESET_STREAM frame
-uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
-    QuicRstStreamErrorCode rst_stream_error_code) {
-  switch (rst_stream_error_code) {
-    case QUIC_STREAM_NO_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
-    case QUIC_ERROR_PROCESSING_STREAM:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
-    case QUIC_MULTIPLE_TERMINATION_OFFSETS:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
-    case QUIC_BAD_APPLICATION_PAYLOAD:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
-    case QUIC_STREAM_CONNECTION_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
-    case QUIC_STREAM_PEER_GOING_AWAY:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
-    case QUIC_STREAM_CANCELLED:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
-    case QUIC_RST_ACKNOWLEDGEMENT:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
-    case QUIC_REFUSED_STREAM:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
-    case QUIC_INVALID_PROMISE_URL:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
-    case QUIC_UNAUTHORIZED_PROMISE_URL:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
-    case QUIC_DUPLICATE_PROMISE_URL:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
-    case QUIC_PROMISE_VARY_MISMATCH:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
-    case QUIC_INVALID_PROMISE_METHOD:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
-    case QUIC_PUSH_STREAM_TIMED_OUT:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
-    case QUIC_HEADERS_TOO_LARGE:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
-    case QUIC_STREAM_TTL_EXPIRED:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
-    case QUIC_DATA_AFTER_CLOSE_OFFSET:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
-    case QUIC_STREAM_GENERAL_PROTOCOL_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
-    case QUIC_STREAM_INTERNAL_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
-    case QUIC_STREAM_STREAM_CREATION_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
-    case QUIC_STREAM_CLOSED_CRITICAL_STREAM:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM);
-    case QUIC_STREAM_FRAME_UNEXPECTED:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED);
-    case QUIC_STREAM_FRAME_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR);
-    case QUIC_STREAM_EXCESSIVE_LOAD:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
-    case QUIC_STREAM_ID_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
-    case QUIC_STREAM_SETTINGS_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR);
-    case QUIC_STREAM_MISSING_SETTINGS:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS);
-    case QUIC_STREAM_REQUEST_REJECTED:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED);
-    case QUIC_STREAM_REQUEST_INCOMPLETE:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE);
-    case QUIC_STREAM_CONNECT_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
-    case QUIC_STREAM_VERSION_FALLBACK:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK);
-    case QUIC_STREAM_DECOMPRESSION_FAILED:
-      return static_cast<uint64_t>(
-          QuicHttpQpackErrorCode::DECOMPRESSION_FAILED);
-    case QUIC_STREAM_ENCODER_STREAM_ERROR:
-      return static_cast<uint64_t>(
-          QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
-    case QUIC_STREAM_DECODER_STREAM_ERROR:
-      return static_cast<uint64_t>(
-          QuicHttpQpackErrorCode::DECODER_STREAM_ERROR);
-    case QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
-    case QUIC_STREAM_WEBTRANSPORT_SESSION_GONE:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
-    case QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
-    case QUIC_STREAM_LAST_ERROR:
-      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
-  }
-  return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
-}
-
-// Convert the application error code of an IETF QUIC RESET_STREAM frame
-// to QuicRstStreamErrorCode.
-QuicRstStreamErrorCode IetfResetStreamErrorCodeToRstStreamErrorCode(
-    uint64_t ietf_error_code) {
-  switch (ietf_error_code) {
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR):
-      return QUIC_STREAM_NO_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR):
-      return QUIC_STREAM_GENERAL_PROTOCOL_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR):
-      return QUIC_STREAM_INTERNAL_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR):
-      return QUIC_STREAM_STREAM_CREATION_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM):
-      return QUIC_STREAM_CLOSED_CRITICAL_STREAM;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED):
-      return QUIC_STREAM_FRAME_UNEXPECTED;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR):
-      return QUIC_STREAM_FRAME_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD):
-      return QUIC_STREAM_EXCESSIVE_LOAD;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR):
-      return QUIC_STREAM_ID_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR):
-      return QUIC_STREAM_SETTINGS_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS):
-      return QUIC_STREAM_MISSING_SETTINGS;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED):
-      return QUIC_STREAM_REQUEST_REJECTED;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED):
-      return QUIC_STREAM_CANCELLED;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE):
-      return QUIC_STREAM_REQUEST_INCOMPLETE;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR):
-      return QUIC_STREAM_CONNECT_ERROR;
-    case static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK):
-      return QUIC_STREAM_VERSION_FALLBACK;
-    case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED):
-      return QUIC_STREAM_DECOMPRESSION_FAILED;
-    case static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR):
-      return QUIC_STREAM_ENCODER_STREAM_ERROR;
-    case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR):
-      return QUIC_STREAM_DECODER_STREAM_ERROR;
-  }
-  return QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE;
-}
-
-// static
-QuicResetStreamError QuicResetStreamError::FromInternal(
-    QuicRstStreamErrorCode code) {
-  return QuicResetStreamError(
-      code, RstStreamErrorCodeToIetfResetStreamErrorCode(code));
-}
-
-// static
-QuicResetStreamError QuicResetStreamError::FromIetf(uint64_t code) {
-  return QuicResetStreamError(
-      IetfResetStreamErrorCodeToRstStreamErrorCode(code), code);
-}
-
-#undef RETURN_STRING_LITERAL  // undef for jumbo builds
-
-}  // namespace quic
diff --git a/quic/core/quic_error_codes.h b/quic/core/quic_error_codes.h
deleted file mode 100644
index 09e6fb2..0000000
--- a/quic/core/quic_error_codes.h
+++ /dev/null
@@ -1,769 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
-#define QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
-
-#include <cstdint>
-#include <limits>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicRstStreamErrorCode is encoded as a single octet on-the-wire in IETF QUIC
-// and a 32-bit integer in gQUIC.
-enum QuicRstStreamErrorCode : uint32_t {
-  // Complete response has been sent, sending a RST to ask the other endpoint
-  // to stop sending request data without discarding the response.
-  QUIC_STREAM_NO_ERROR = 0,
-
-  // There was some error which halted stream processing.
-  QUIC_ERROR_PROCESSING_STREAM = 1,
-  // We got two fin or reset offsets which did not match.
-  QUIC_MULTIPLE_TERMINATION_OFFSETS = 2,
-  // We got bad payload and can not respond to it at the protocol level.
-  QUIC_BAD_APPLICATION_PAYLOAD = 3,
-  // Stream closed due to connection error. No reset frame is sent when this
-  // happens.
-  QUIC_STREAM_CONNECTION_ERROR = 4,
-  // GoAway frame sent. No more stream can be created.
-  QUIC_STREAM_PEER_GOING_AWAY = 5,
-  // The stream has been cancelled.
-  QUIC_STREAM_CANCELLED = 6,
-  // Closing stream locally, sending a RST to allow for proper flow control
-  // accounting. Sent in response to a RST from the peer.
-  QUIC_RST_ACKNOWLEDGEMENT = 7,
-  // Receiver refused to create the stream (because its limit on open streams
-  // has been reached).  The sender should retry the request later (using
-  // another stream).
-  QUIC_REFUSED_STREAM = 8,
-  // Invalid URL in PUSH_PROMISE request header.
-  QUIC_INVALID_PROMISE_URL = 9,
-  // Server is not authoritative for this URL.
-  QUIC_UNAUTHORIZED_PROMISE_URL = 10,
-  // Can't have more than one active PUSH_PROMISE per URL.
-  QUIC_DUPLICATE_PROMISE_URL = 11,
-  // Vary check failed.
-  QUIC_PROMISE_VARY_MISMATCH = 12,
-  // Only GET and HEAD methods allowed.
-  QUIC_INVALID_PROMISE_METHOD = 13,
-  // The push stream is unclaimed and timed out.
-  QUIC_PUSH_STREAM_TIMED_OUT = 14,
-  // Received headers were too large.
-  QUIC_HEADERS_TOO_LARGE = 15,
-  // The data is not likely arrive in time.
-  QUIC_STREAM_TTL_EXPIRED = 16,
-  // The stream received data that goes beyond its close offset.
-  QUIC_DATA_AFTER_CLOSE_OFFSET = 17,
-  // Peer violated protocol requirements in a way which does not match a more
-  // specific error code, or endpoint declines to use the more specific error
-  // code.
-  QUIC_STREAM_GENERAL_PROTOCOL_ERROR = 18,
-  // An internal error has occurred.
-  QUIC_STREAM_INTERNAL_ERROR = 19,
-  // Peer created a stream that will not be accepted.
-  QUIC_STREAM_STREAM_CREATION_ERROR = 20,
-  // A stream required by the connection was closed or reset.
-  QUIC_STREAM_CLOSED_CRITICAL_STREAM = 21,
-  // A frame was received which was not permitted in the current state or on the
-  // current stream.
-  QUIC_STREAM_FRAME_UNEXPECTED = 22,
-  // A frame that fails to satisfy layout requirements or with an invalid size
-  // was received.
-  QUIC_STREAM_FRAME_ERROR = 23,
-  // Peer exhibits a behavior that might be generating excessive load.
-  QUIC_STREAM_EXCESSIVE_LOAD = 24,
-  // A Stream ID or Push ID was used incorrectly, such as exceeding a limit,
-  // reducing a limit, or being reused.
-  QUIC_STREAM_ID_ERROR = 25,
-  // Error in the payload of a SETTINGS frame.
-  QUIC_STREAM_SETTINGS_ERROR = 26,
-  // No SETTINGS frame was received at the beginning of the control stream.
-  QUIC_STREAM_MISSING_SETTINGS = 27,
-  // A server rejected a request without performing any application processing.
-  QUIC_STREAM_REQUEST_REJECTED = 28,
-  // The client's stream terminated without containing a fully-formed request.
-  QUIC_STREAM_REQUEST_INCOMPLETE = 29,
-  // The connection established in response to a CONNECT request was reset or
-  // abnormally closed.
-  QUIC_STREAM_CONNECT_ERROR = 30,
-  // The requested operation cannot be served over HTTP/3.
-  // The peer should retry over HTTP/1.1.
-  QUIC_STREAM_VERSION_FALLBACK = 31,
-  // The QPACK decoder failed to interpret a header block and is not able to
-  // continue decoding that header block.
-  QUIC_STREAM_DECOMPRESSION_FAILED = 32,
-  // The QPACK decoder failed to interpret an encoder instruction received on
-  // the encoder stream.
-  QUIC_STREAM_ENCODER_STREAM_ERROR = 33,
-  // The QPACK encoder failed to interpret a decoder instruction received on the
-  // decoder stream.
-  QUIC_STREAM_DECODER_STREAM_ERROR = 34,
-  // IETF RESET_FRAME application error code not matching any HTTP/3 or QPACK
-  // error codes.
-  QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE = 35,
-  // WebTransport session is going away, causing all underlying streams to be
-  // reset.
-  QUIC_STREAM_WEBTRANSPORT_SESSION_GONE = 36,
-  // There is no corresponding WebTransport session to associate this stream
-  // with, and the limit for buffered streams has been exceeded.
-  QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED = 37,
-  // No error. Used as bound while iterating.
-  QUIC_STREAM_LAST_ERROR = 38,
-};
-// QuicRstStreamErrorCode is encoded as a single octet on-the-wire.
-static_assert(static_cast<int>(QUIC_STREAM_LAST_ERROR) <=
-                  std::numeric_limits<uint8_t>::max(),
-              "QuicRstStreamErrorCode exceeds single octet");
-
-// These values must remain stable as they are uploaded to UMA histograms.
-// To add a new error code, use the current value of QUIC_LAST_ERROR and
-// increment QUIC_LAST_ERROR.
-enum QuicErrorCode {
-  QUIC_NO_ERROR = 0,
-
-  // Connection has reached an invalid state.
-  QUIC_INTERNAL_ERROR = 1,
-  // There were data frames after the a fin or reset.
-  QUIC_STREAM_DATA_AFTER_TERMINATION = 2,
-  // Control frame is malformed.
-  QUIC_INVALID_PACKET_HEADER = 3,
-  // Frame data is malformed.
-  QUIC_INVALID_FRAME_DATA = 4,
-  // The packet contained no payload.
-  QUIC_MISSING_PAYLOAD = 48,
-  // FEC data is malformed.
-  QUIC_INVALID_FEC_DATA = 5,
-  // STREAM frame data is malformed.
-  QUIC_INVALID_STREAM_DATA = 46,
-  // STREAM frame data overlaps with buffered data.
-  QUIC_OVERLAPPING_STREAM_DATA = 87,
-  // Received STREAM frame data is not encrypted.
-  QUIC_UNENCRYPTED_STREAM_DATA = 61,
-  // Attempt to send unencrypted STREAM frame.
-  QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA = 88,
-  // Received a frame which is likely the result of memory corruption.
-  QUIC_MAYBE_CORRUPTED_MEMORY = 89,
-  // FEC frame data is not encrypted.
-  QUIC_UNENCRYPTED_FEC_DATA = 77,
-  // RST_STREAM frame data is malformed.
-  QUIC_INVALID_RST_STREAM_DATA = 6,
-  // CONNECTION_CLOSE frame data is malformed.
-  QUIC_INVALID_CONNECTION_CLOSE_DATA = 7,
-  // GOAWAY frame data is malformed.
-  QUIC_INVALID_GOAWAY_DATA = 8,
-  // WINDOW_UPDATE frame data is malformed.
-  QUIC_INVALID_WINDOW_UPDATE_DATA = 57,
-  // BLOCKED frame data is malformed.
-  QUIC_INVALID_BLOCKED_DATA = 58,
-  // STOP_WAITING frame data is malformed.
-  QUIC_INVALID_STOP_WAITING_DATA = 60,
-  // PATH_CLOSE frame data is malformed.
-  QUIC_INVALID_PATH_CLOSE_DATA = 78,
-  // ACK frame data is malformed.
-  QUIC_INVALID_ACK_DATA = 9,
-  // Message frame data is malformed.
-  QUIC_INVALID_MESSAGE_DATA = 112,
-
-  // Version negotiation packet is malformed.
-  QUIC_INVALID_VERSION_NEGOTIATION_PACKET = 10,
-  // Public RST packet is malformed.
-  QUIC_INVALID_PUBLIC_RST_PACKET = 11,
-  // There was an error decrypting.
-  QUIC_DECRYPTION_FAILURE = 12,
-  // There was an error encrypting.
-  QUIC_ENCRYPTION_FAILURE = 13,
-  // The packet exceeded kMaxOutgoingPacketSize.
-  QUIC_PACKET_TOO_LARGE = 14,
-  // The peer is going away.  May be a client or server.
-  QUIC_PEER_GOING_AWAY = 16,
-  // A stream ID was invalid.
-  QUIC_INVALID_STREAM_ID = 17,
-  // A priority was invalid.
-  QUIC_INVALID_PRIORITY = 49,
-  // Too many streams already open.
-  QUIC_TOO_MANY_OPEN_STREAMS = 18,
-  // The peer created too many available streams.
-  QUIC_TOO_MANY_AVAILABLE_STREAMS = 76,
-  // Received public reset for this connection.
-  QUIC_PUBLIC_RESET = 19,
-  // Version selected by client is not acceptable to the server.
-  QUIC_INVALID_VERSION = 20,
-  // Received packet indicates version that does not match connection version.
-  QUIC_PACKET_WRONG_VERSION = 212,
-
-  // The Header ID for a stream was too far from the previous.
-  QUIC_INVALID_HEADER_ID = 22,
-  // Negotiable parameter received during handshake had invalid value.
-  QUIC_INVALID_NEGOTIATED_VALUE = 23,
-  // There was an error decompressing data.
-  QUIC_DECOMPRESSION_FAILURE = 24,
-  // The connection timed out due to no network activity.
-  QUIC_NETWORK_IDLE_TIMEOUT = 25,
-  // The connection timed out waiting for the handshake to complete.
-  QUIC_HANDSHAKE_TIMEOUT = 67,
-  // There was an error encountered migrating addresses.
-  QUIC_ERROR_MIGRATING_ADDRESS = 26,
-  // There was an error encountered migrating port only.
-  QUIC_ERROR_MIGRATING_PORT = 86,
-  // There was an error while writing to the socket.
-  QUIC_PACKET_WRITE_ERROR = 27,
-  // There was an error while reading from the socket.
-  QUIC_PACKET_READ_ERROR = 51,
-  // We received a STREAM_FRAME with no data and no fin flag set.
-  QUIC_EMPTY_STREAM_FRAME_NO_FIN = 50,
-  // We received invalid data on the headers stream.
-  QUIC_INVALID_HEADERS_STREAM_DATA = 56,
-  // Invalid data on the headers stream received because of decompression
-  // failure.
-  QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE = 97,
-  // The peer received too much data, violating flow control.
-  QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA = 59,
-  // The peer sent too much data, violating flow control.
-  QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA = 63,
-  // The peer received an invalid flow control window.
-  QUIC_FLOW_CONTROL_INVALID_WINDOW = 64,
-  // The connection has been IP pooled into an existing connection.
-  QUIC_CONNECTION_IP_POOLED = 62,
-  // The connection has too many outstanding sent packets.
-  QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS = 68,
-  // The connection has too many outstanding received packets.
-  QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS = 69,
-  // The quic connection has been cancelled.
-  QUIC_CONNECTION_CANCELLED = 70,
-  // Disabled QUIC because of high packet loss rate.
-  QUIC_BAD_PACKET_LOSS_RATE = 71,
-  // Disabled QUIC because of too many PUBLIC_RESETs post handshake.
-  QUIC_PUBLIC_RESETS_POST_HANDSHAKE = 73,
-  // Closed because we failed to serialize a packet.
-  QUIC_FAILED_TO_SERIALIZE_PACKET = 75,
-  // QUIC timed out after too many RTOs.
-  QUIC_TOO_MANY_RTOS = 85,
-
-  // Crypto errors.
-
-  // Handshake failed.
-  QUIC_HANDSHAKE_FAILED = 28,
-  // Handshake message contained out of order tags.
-  QUIC_CRYPTO_TAGS_OUT_OF_ORDER = 29,
-  // Handshake message contained too many entries.
-  QUIC_CRYPTO_TOO_MANY_ENTRIES = 30,
-  // Handshake message contained an invalid value length.
-  QUIC_CRYPTO_INVALID_VALUE_LENGTH = 31,
-  // A crypto message was received after the handshake was complete.
-  QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE = 32,
-  // A crypto message was received with an illegal message tag.
-  QUIC_INVALID_CRYPTO_MESSAGE_TYPE = 33,
-  // A crypto message was received with an illegal parameter.
-  QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER = 34,
-  // An invalid channel id signature was supplied.
-  QUIC_INVALID_CHANNEL_ID_SIGNATURE = 52,
-  // A crypto message was received with a mandatory parameter missing.
-  QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND = 35,
-  // A crypto message was received with a parameter that has no overlap
-  // with the local parameter.
-  QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP = 36,
-  // A crypto message was received that contained a parameter with too few
-  // values.
-  QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND = 37,
-  // A demand for an unsupport proof type was received.
-  QUIC_UNSUPPORTED_PROOF_DEMAND = 94,
-  // An internal error occurred in crypto processing.
-  QUIC_CRYPTO_INTERNAL_ERROR = 38,
-  // A crypto handshake message specified an unsupported version.
-  QUIC_CRYPTO_VERSION_NOT_SUPPORTED = 39,
-  // (Deprecated) A crypto handshake message resulted in a stateless reject.
-  // QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT = 72,
-  // There was no intersection between the crypto primitives supported by the
-  // peer and ourselves.
-  QUIC_CRYPTO_NO_SUPPORT = 40,
-  // The server rejected our client hello messages too many times.
-  QUIC_CRYPTO_TOO_MANY_REJECTS = 41,
-  // The client rejected the server's certificate chain or signature.
-  QUIC_PROOF_INVALID = 42,
-  // A crypto message was received with a duplicate tag.
-  QUIC_CRYPTO_DUPLICATE_TAG = 43,
-  // A crypto message was received with the wrong encryption level (i.e. it
-  // should have been encrypted but was not.)
-  QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT = 44,
-  // The server config for a server has expired.
-  QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45,
-  // We failed to setup the symmetric keys for a connection.
-  QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED = 53,
-  // A handshake message arrived, but we are still validating the
-  // previous handshake message.
-  QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO = 54,
-  // A server config update arrived before the handshake is complete.
-  QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE = 65,
-  // CHLO cannot fit in one packet.
-  QUIC_CRYPTO_CHLO_TOO_LARGE = 90,
-  // This connection involved a version negotiation which appears to have been
-  // tampered with.
-  QUIC_VERSION_NEGOTIATION_MISMATCH = 55,
-
-  // Multipath errors.
-  // Multipath is not enabled, but a packet with multipath flag on is received.
-  QUIC_BAD_MULTIPATH_FLAG = 79,
-  // A path is supposed to exist but does not.
-  QUIC_MULTIPATH_PATH_DOES_NOT_EXIST = 91,
-  // A path is supposed to be active but is not.
-  QUIC_MULTIPATH_PATH_NOT_ACTIVE = 92,
-
-  // IP address changed causing connection close.
-  QUIC_IP_ADDRESS_CHANGED = 80,
-
-  // Connection migration errors.
-  // Network changed, but connection had no migratable streams.
-  QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS = 81,
-  // Connection changed networks too many times.
-  QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES = 82,
-  // Connection migration was attempted, but there was no new network to
-  // migrate to.
-  QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK = 83,
-  // Network changed, but connection had one or more non-migratable streams.
-  QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
-  // Network changed, but connection migration was disabled by config.
-  QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG = 99,
-  // Network changed, but error was encountered on the alternative network.
-  QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR = 100,
-  // Network changed, but handshake is not confirmed yet.
-  QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED = 111,
-  QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED = 194,
-
-  // Stream frames arrived too discontiguously so that stream sequencer buffer
-  // maintains too many intervals.
-  QUIC_TOO_MANY_STREAM_DATA_INTERVALS = 93,
-
-  // Sequencer buffer get into weird state where continuing read/write will lead
-  // to crash.
-  QUIC_STREAM_SEQUENCER_INVALID_STATE = 95,
-
-  // Connection closed because of server hits max number of sessions allowed.
-  QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96,
-
-  // Receive a RST_STREAM with offset larger than kMaxStreamLength.
-  QUIC_STREAM_LENGTH_OVERFLOW = 98,
-  // Received a MAX DATA frame with errors.
-  QUIC_INVALID_MAX_DATA_FRAME_DATA = 102,
-  // Received a MAX STREAM DATA frame with errors.
-  QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA = 103,
-  // Received a MAX_STREAMS frame with bad data
-  QUIC_MAX_STREAMS_DATA = 104,
-  // Received a STREAMS_BLOCKED frame with bad data
-  QUIC_STREAMS_BLOCKED_DATA = 105,
-  // Error deframing a STREAM BLOCKED frame.
-  QUIC_INVALID_STREAM_BLOCKED_DATA = 106,
-  // NEW CONNECTION ID frame data is malformed.
-  QUIC_INVALID_NEW_CONNECTION_ID_DATA = 107,
-  // More connection IDs than allowed are issued.
-  QUIC_CONNECTION_ID_LIMIT_ERROR = 203,
-  // The peer retires connection IDs too quickly.
-  QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE = 204,
-  // Received a MAX STREAM DATA frame with errors.
-  QUIC_INVALID_STOP_SENDING_FRAME_DATA = 108,
-  // Error deframing PATH CHALLENGE or PATH RESPONSE frames.
-  QUIC_INVALID_PATH_CHALLENGE_DATA = 109,
-  QUIC_INVALID_PATH_RESPONSE_DATA = 110,
-  // This is used to indicate an IETF QUIC PROTOCOL VIOLATION
-  // transport error within Google (pre-v99) QUIC.
-  IETF_QUIC_PROTOCOL_VIOLATION = 113,
-  QUIC_INVALID_NEW_TOKEN = 114,
-
-  // Received stream data on a WRITE_UNIDIRECTIONAL stream.
-  QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM = 115,
-  // Try to send stream data on a READ_UNIDIRECTIONAL stream.
-  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM = 116,
-
-  // RETIRE CONNECTION ID frame data is malformed.
-  QUIC_INVALID_RETIRE_CONNECTION_ID_DATA = 117,
-
-  // Error in a received STREAMS BLOCKED frame.
-  QUIC_STREAMS_BLOCKED_ERROR = 118,
-  // Error in a received MAX STREAMS frame
-  QUIC_MAX_STREAMS_ERROR = 119,
-  // Error in Http decoder
-  QUIC_HTTP_DECODER_ERROR = 120,
-  // Connection from stale host needs to be cancelled.
-  QUIC_STALE_CONNECTION_CANCELLED = 121,
-
-  // A pseudo error, used as an extended error reason code in the error_details
-  // of IETF-QUIC CONNECTION_CLOSE frames. It is used in
-  // OnConnectionClosed upcalls to indicate that extended error information was
-  // not available in a received CONNECTION_CLOSE frame.
-  QUIC_IETF_GQUIC_ERROR_MISSING = 122,
-
-  // Received WindowUpdate on a READ_UNIDIRECTIONAL stream.
-  QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM = 123,
-
-  // There are too many buffered control frames in control frame manager.
-  QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES = 124,
-
-  // QuicTransport received invalid client indication.
-  QUIC_TRANSPORT_INVALID_CLIENT_INDICATION = 125,
-
-  // Internal error codes for QPACK errors.
-  QUIC_QPACK_DECOMPRESSION_FAILED = 126,
-
-  // Obsolete generic QPACK encoder and decoder stream error codes.
-  QUIC_QPACK_ENCODER_STREAM_ERROR = 127,
-  QUIC_QPACK_DECODER_STREAM_ERROR = 128,
-
-  // QPACK encoder stream errors.
-
-  // Variable integer exceeding 2^64-1 received.
-  QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE = 174,
-  // String literal exceeding kStringLiteralLengthLimit in length received.
-  QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG = 175,
-  // String literal with invalid Huffman encoding received.
-  QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR = 176,
-  // Invalid static table index in Insert With Name Reference instruction.
-  QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY = 177,
-  // Error inserting entry with static name reference in Insert With Name
-  // Reference instruction due to entry size exceeding dynamic table capacity.
-  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC = 178,
-  // Invalid relative index in Insert With Name Reference instruction.
-  QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX = 179,
-  // Dynamic entry not found in Insert With Name Reference instruction.
-  QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND = 180,
-  // Error inserting entry with dynamic name reference in Insert With Name
-  // Reference instruction due to entry size exceeding dynamic table capacity.
-  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC = 181,
-  // Error inserting entry in Insert With Literal Name instruction due to entry
-  // size exceeding dynamic table capacity.
-  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL = 182,
-  // Invalid relative index in Duplicate instruction.
-  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX = 183,
-  // Dynamic entry not found in Duplicate instruction.
-  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND = 184,
-  // Error in Set Dynamic Table Capacity instruction due to new capacity
-  // exceeding maximum dynamic table capacity.
-  QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY = 185,
-
-  // QPACK decoder stream errors.
-
-  // Variable integer exceeding 2^64-1 received.
-  QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE = 186,
-  // Insert Count Increment instruction received with invalid 0 increment.
-  QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT = 187,
-  // Insert Count Increment instruction causes uint64_t overflow.
-  QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW = 188,
-  // Insert Count Increment instruction increases Known Received Count beyond
-  // inserted entry cound.
-  QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT = 189,
-  // Header Acknowledgement received for stream that has no outstanding header
-  // blocks.
-  QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT = 190,
-
-  // Received stream data beyond close offset.
-  QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET = 129,
-
-  // Received multiple close offset.
-  QUIC_STREAM_MULTIPLE_OFFSET = 130,
-
-  // HTTP/3 errors.
-
-  // Frame payload larger than what HttpDecoder is willing to buffer.
-  QUIC_HTTP_FRAME_TOO_LARGE = 131,
-  // Malformed HTTP/3 frame, or PUSH_PROMISE or CANCEL_PUSH received (which is
-  // an error because MAX_PUSH_ID is never sent).
-  QUIC_HTTP_FRAME_ERROR = 132,
-  // A frame that is never allowed on a request stream is received.
-  QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM = 133,
-  // A frame that is never allowed on the control stream is received.
-  QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM = 134,
-  // An invalid sequence of frames normally allowed on a request stream is
-  // received.
-  QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM = 151,
-  // A second SETTINGS frame is received on the control stream.
-  QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM = 152,
-  // A second instance of a unidirectional stream of a certain type is created.
-  QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM = 153,
-  // Client receives a server-initiated bidirectional stream.
-  QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM = 154,
-  // Server opens stream with stream ID corresponding to client-initiated
-  // stream or vice versa.
-  QUIC_HTTP_STREAM_WRONG_DIRECTION = 155,
-  // Peer closes one of the six critical unidirectional streams (control, QPACK
-  // encoder or decoder, in either direction).
-  QUIC_HTTP_CLOSED_CRITICAL_STREAM = 156,
-  // The first frame received on the control stream is not a SETTINGS frame.
-  QUIC_HTTP_MISSING_SETTINGS_FRAME = 157,
-  // The received SETTINGS frame contains duplicate setting identifiers.
-  QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER = 158,
-  // MAX_PUSH_ID frame received with push ID value smaller than a previously
-  // received value.
-  QUIC_HTTP_INVALID_MAX_PUSH_ID = 159,
-  // Received unidirectional stream limit is lower than required by HTTP/3.
-  QUIC_HTTP_STREAM_LIMIT_TOO_LOW = 160,
-  // Received mismatched SETTINGS frame from HTTP/3 connection where early data
-  // is accepted. Server violated the HTTP/3 spec.
-  QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH = 164,
-  // Received mismatched SETTINGS frame from HTTP/3 connection where early data
-  // is rejected. Our implementation currently doesn't support it.
-  QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH = 165,
-  // Client received GOAWAY frame with stream ID that is not for a
-  // client-initiated bidirectional stream.
-  QUIC_HTTP_GOAWAY_INVALID_STREAM_ID = 166,
-  // Received GOAWAY frame with ID that is greater than previously received ID.
-  QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS = 167,
-  // HTTP/3 session received SETTINGS frame which contains HTTP/2 specific
-  // settings.
-  QUIC_HTTP_RECEIVE_SPDY_SETTING = 169,
-  // HTTP/3 session received an HTTP/2 only frame.
-  QUIC_HTTP_RECEIVE_SPDY_FRAME = 171,
-  // HTTP/3 session received SERVER_PUSH stream, which is an error because
-  // PUSH_PROMISE is not accepted.
-  QUIC_HTTP_RECEIVE_SERVER_PUSH = 205,
-  // HTTP/3 session received invalid SETTING value.
-  QUIC_HTTP_INVALID_SETTING_VALUE = 207,
-
-  // HPACK header block decoding errors.
-  // Index varint beyond implementation limit.
-  QUIC_HPACK_INDEX_VARINT_ERROR = 135,
-  // Name length varint beyond implementation limit.
-  QUIC_HPACK_NAME_LENGTH_VARINT_ERROR = 136,
-  // Value length varint beyond implementation limit.
-  QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR = 137,
-  // Name length exceeds buffer limit.
-  QUIC_HPACK_NAME_TOO_LONG = 138,
-  // Value length exceeds buffer limit.
-  QUIC_HPACK_VALUE_TOO_LONG = 139,
-  // Name Huffman encoding error.
-  QUIC_HPACK_NAME_HUFFMAN_ERROR = 140,
-  // Value Huffman encoding error.
-  QUIC_HPACK_VALUE_HUFFMAN_ERROR = 141,
-  // Next instruction should have been a dynamic table size update.
-  QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE = 142,
-  // Invalid index in indexed header field representation.
-  QUIC_HPACK_INVALID_INDEX = 143,
-  // Invalid index in literal header field with indexed name representation.
-  QUIC_HPACK_INVALID_NAME_INDEX = 144,
-  // Dynamic table size update not allowed.
-  QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED = 145,
-  // Initial dynamic table size update is above low water mark.
-  QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK = 146,
-  // Dynamic table size update is above acknowledged setting.
-  QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING = 147,
-  // HPACK block ends in the middle of an instruction.
-  QUIC_HPACK_TRUNCATED_BLOCK = 148,
-  // Incoming data fragment exceeds buffer limit.
-  QUIC_HPACK_FRAGMENT_TOO_LONG = 149,
-  // Total compressed HPACK data size exceeds limit.
-  QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT = 150,
-
-  // Stream/flow control limit from 1-RTT handshake is too low to retransmit
-  // 0-RTT data. This is our implentation error. We could in theory keep the
-  // connection alive but chose not to for simplicity.
-  QUIC_ZERO_RTT_UNRETRANSMITTABLE = 161,
-  // Stream/flow control limit from 0-RTT rejection reduces cached limit.
-  // This is our implentation error. We could in theory keep the connection
-  // alive but chose not to for simplicity.
-  QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED = 162,
-  // Stream/flow control limit from 0-RTT resumption reduces cached limit.
-  // This is the peer violating QUIC spec.
-  QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED = 163,
-
-  // The connection silently timed out due to no network activity.
-  QUIC_SILENT_IDLE_TIMEOUT = 168,
-
-  // Try to write data without the right write keys.
-  QUIC_MISSING_WRITE_KEYS = 170,
-
-  // An endpoint detected errors in performing key updates.
-  QUIC_KEY_UPDATE_ERROR = 172,
-
-  // An endpoint has reached the confidentiality or integrity limit for the
-  // AEAD algorithm used by the given connection.
-  QUIC_AEAD_LIMIT_REACHED = 173,
-
-  // Connection reached maximum age (regardless of activity), no new requests
-  // are accepted.  This error code is sent in transport layer GOAWAY frame when
-  // using gQUIC, and only used internally when using HTTP/3.  Active requests
-  // are still served, after which connection will be closed due to idle
-  // timeout.
-  QUIC_MAX_AGE_TIMEOUT = 191,
-
-  // Decrypted a 0-RTT packet with a higher packet number than a 1-RTT packet.
-  QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER = 192,
-
-  // Received PRIORITY_UPDATE frame with invalid payload.
-  QUIC_INVALID_PRIORITY_UPDATE = 193,
-
-  // Maps to specific errors from the CRYPTO_ERROR range from
-  // https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
-  // This attempts to choose a subset of the most interesting errors rather
-  // than mapping every possible CRYPTO_ERROR code.
-  QUIC_TLS_BAD_CERTIFICATE = 195,
-  QUIC_TLS_UNSUPPORTED_CERTIFICATE = 196,
-  QUIC_TLS_CERTIFICATE_REVOKED = 197,
-  QUIC_TLS_CERTIFICATE_EXPIRED = 198,
-  QUIC_TLS_CERTIFICATE_UNKNOWN = 199,
-  QUIC_TLS_INTERNAL_ERROR = 200,
-  QUIC_TLS_UNRECOGNIZED_NAME = 201,
-  QUIC_TLS_CERTIFICATE_REQUIRED = 202,
-
-  // An HTTP field value containing an invalid character has been received.
-  QUIC_INVALID_CHARACTER_IN_FIELD_VALUE = 206,
-
-  // Error code related to the usage of TLS keying material export.
-  QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL = 208,
-  QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH = 209,
-  QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE = 210,
-  QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED = 211,
-
-  // No error. Used as bound while iterating.
-  QUIC_LAST_ERROR = 213,
-};
-// QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
-// or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
-// the smaller of the two limits.
-static_assert(static_cast<uint64_t>(QUIC_LAST_ERROR) <=
-                  static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()),
-              "QuicErrorCode exceeds four octets");
-
-// Represents a reason for resetting a stream in both gQUIC and IETF error code
-// space.  Both error codes have to be present.
-class QUIC_EXPORT_PRIVATE QuicResetStreamError {
- public:
-  // Constructs a QuicResetStreamError from QuicRstStreamErrorCode; the IETF
-  // error code is inferred.
-  static QuicResetStreamError FromInternal(QuicRstStreamErrorCode code);
-  // Constructs a QuicResetStreamError from an IETF error code; the internal
-  // error code is inferred.
-  static QuicResetStreamError FromIetf(uint64_t code);
-  // Constructs a QuicResetStreamError with no error.
-  static QuicResetStreamError NoError() {
-    return FromInternal(QUIC_STREAM_NO_ERROR);
-  }
-
-  QuicResetStreamError(QuicRstStreamErrorCode internal_code,
-                       uint64_t ietf_application_code)
-      : internal_code_(internal_code),
-        ietf_application_code_(ietf_application_code) {}
-
-  QuicRstStreamErrorCode internal_code() const { return internal_code_; }
-  uint64_t ietf_application_code() const { return ietf_application_code_; }
-
-  bool operator==(const QuicResetStreamError& other) const {
-    return internal_code() == other.internal_code() &&
-           ietf_application_code() == other.ietf_application_code();
-  }
-
-  // Returns true if the object holds no error.
-  bool ok() const { return internal_code() == QUIC_STREAM_NO_ERROR; }
-
- private:
-  // Error code used in gQUIC.  Even when IETF QUIC is in use, this needs to be
-  // populated as we use those internally.
-  QuicRstStreamErrorCode internal_code_;
-  // Application error code used in IETF QUIC.
-  uint64_t ietf_application_code_;
-};
-
-// Convert TLS alert code to QuicErrorCode.
-QUIC_EXPORT_PRIVATE QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc);
-
-// Returns the name of the QuicRstStreamErrorCode as a char*
-QUIC_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
-    QuicRstStreamErrorCode error);
-
-// Returns the name of the QuicErrorCode as a char*
-QUIC_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
-
-// Wire values for QUIC transport errors.
-// https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
-enum QuicIetfTransportErrorCodes : uint64_t {
-  NO_IETF_QUIC_ERROR = 0x0,
-  INTERNAL_ERROR = 0x1,
-  SERVER_BUSY_ERROR = 0x2,
-  FLOW_CONTROL_ERROR = 0x3,
-  STREAM_LIMIT_ERROR = 0x4,
-  STREAM_STATE_ERROR = 0x5,
-  FINAL_SIZE_ERROR = 0x6,
-  FRAME_ENCODING_ERROR = 0x7,
-  TRANSPORT_PARAMETER_ERROR = 0x8,
-  CONNECTION_ID_LIMIT_ERROR = 0x9,
-  PROTOCOL_VIOLATION = 0xA,
-  INVALID_TOKEN = 0xB,
-  CRYPTO_BUFFER_EXCEEDED = 0xD,
-  KEY_UPDATE_ERROR = 0xE,
-  AEAD_LIMIT_REACHED = 0xF,
-  CRYPTO_ERROR_FIRST = 0x100,
-  CRYPTO_ERROR_LAST = 0x1FF,
-};
-
-QUIC_EXPORT_PRIVATE std::string QuicIetfTransportErrorCodeString(
-    QuicIetfTransportErrorCodes c);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const QuicIetfTransportErrorCodes& c);
-
-// A transport error code (if is_transport_close is true) or application error
-// code (if is_transport_close is false) to be used in CONNECTION_CLOSE frames.
-struct QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping {
-  bool is_transport_close;
-  uint64_t error_code;
-};
-
-// Convert QuicErrorCode to transport or application IETF error code
-// to be used in CONNECTION_CLOSE frames.
-QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping
-QuicErrorCodeToTransportErrorCode(QuicErrorCode error);
-
-// Wire values for HTTP/3 errors.
-// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#http-error-codes
-enum class QuicHttp3ErrorCode {
-  // NO_ERROR is defined as a C preprocessor macro on Windows.
-  HTTP3_NO_ERROR = 0x100,
-  GENERAL_PROTOCOL_ERROR = 0x101,
-  INTERNAL_ERROR = 0x102,
-  STREAM_CREATION_ERROR = 0x103,
-  CLOSED_CRITICAL_STREAM = 0x104,
-  FRAME_UNEXPECTED = 0x105,
-  FRAME_ERROR = 0x106,
-  EXCESSIVE_LOAD = 0x107,
-  ID_ERROR = 0x108,
-  SETTINGS_ERROR = 0x109,
-  MISSING_SETTINGS = 0x10A,
-  REQUEST_REJECTED = 0x10B,
-  REQUEST_CANCELLED = 0x10C,
-  REQUEST_INCOMPLETE = 0x10D,
-  MESSAGE_ERROR = 0x10E,
-  CONNECT_ERROR = 0x10F,
-  VERSION_FALLBACK = 0x110,
-};
-
-// Wire values for QPACK errors.
-// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#error-code-registration
-enum class QuicHttpQpackErrorCode {
-  DECOMPRESSION_FAILED = 0x200,
-  ENCODER_STREAM_ERROR = 0x201,
-  DECODER_STREAM_ERROR = 0x202
-};
-
-// Convert a QuicRstStreamErrorCode to an application error code to be used in
-// an IETF QUIC RESET_STREAM frame
-QUIC_EXPORT_PRIVATE uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
-    QuicRstStreamErrorCode rst_stream_error_code);
-
-// Convert the application error code of an IETF QUIC RESET_STREAM frame
-// to QuicRstStreamErrorCode.
-QUIC_EXPORT_PRIVATE QuicRstStreamErrorCode
-IetfResetStreamErrorCodeToRstStreamErrorCode(uint64_t ietf_error_code);
-
-QUIC_EXPORT_PRIVATE inline std::string HistogramEnumString(
-    QuicErrorCode enum_value) {
-  return QuicErrorCodeToString(enum_value);
-}
-
-QUIC_EXPORT_PRIVATE inline std::string HistogramEnumDescription(
-    QuicErrorCode /*dummy*/) {
-  return "cause";
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
diff --git a/quic/core/quic_error_codes_test.cc b/quic/core/quic_error_codes_test.cc
deleted file mode 100644
index 4c5517f..0000000
--- a/quic/core/quic_error_codes_test.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_error_codes.h"
-
-#include <cstdint>
-
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using QuicErrorCodesTest = QuicTest;
-
-TEST_F(QuicErrorCodesTest, QuicErrorCodeToString) {
-  EXPECT_STREQ("QUIC_NO_ERROR", QuicErrorCodeToString(QUIC_NO_ERROR));
-}
-
-TEST_F(QuicErrorCodesTest, QuicIetfTransportErrorCodeString) {
-  EXPECT_EQ("CRYPTO_ERROR(missing extension)",
-            QuicIetfTransportErrorCodeString(
-                static_cast<quic::QuicIetfTransportErrorCodes>(
-                    CRYPTO_ERROR_FIRST + SSL_AD_MISSING_EXTENSION)));
-
-  EXPECT_EQ("NO_IETF_QUIC_ERROR",
-            QuicIetfTransportErrorCodeString(NO_IETF_QUIC_ERROR));
-  EXPECT_EQ("INTERNAL_ERROR", QuicIetfTransportErrorCodeString(INTERNAL_ERROR));
-  EXPECT_EQ("SERVER_BUSY_ERROR",
-            QuicIetfTransportErrorCodeString(SERVER_BUSY_ERROR));
-  EXPECT_EQ("FLOW_CONTROL_ERROR",
-            QuicIetfTransportErrorCodeString(FLOW_CONTROL_ERROR));
-  EXPECT_EQ("STREAM_LIMIT_ERROR",
-            QuicIetfTransportErrorCodeString(STREAM_LIMIT_ERROR));
-  EXPECT_EQ("STREAM_STATE_ERROR",
-            QuicIetfTransportErrorCodeString(STREAM_STATE_ERROR));
-  EXPECT_EQ("FINAL_SIZE_ERROR",
-            QuicIetfTransportErrorCodeString(FINAL_SIZE_ERROR));
-  EXPECT_EQ("FRAME_ENCODING_ERROR",
-            QuicIetfTransportErrorCodeString(FRAME_ENCODING_ERROR));
-  EXPECT_EQ("TRANSPORT_PARAMETER_ERROR",
-            QuicIetfTransportErrorCodeString(TRANSPORT_PARAMETER_ERROR));
-  EXPECT_EQ("CONNECTION_ID_LIMIT_ERROR",
-            QuicIetfTransportErrorCodeString(CONNECTION_ID_LIMIT_ERROR));
-  EXPECT_EQ("PROTOCOL_VIOLATION",
-            QuicIetfTransportErrorCodeString(PROTOCOL_VIOLATION));
-  EXPECT_EQ("INVALID_TOKEN", QuicIetfTransportErrorCodeString(INVALID_TOKEN));
-  EXPECT_EQ("CRYPTO_BUFFER_EXCEEDED",
-            QuicIetfTransportErrorCodeString(CRYPTO_BUFFER_EXCEEDED));
-  EXPECT_EQ("KEY_UPDATE_ERROR",
-            QuicIetfTransportErrorCodeString(KEY_UPDATE_ERROR));
-  EXPECT_EQ("AEAD_LIMIT_REACHED",
-            QuicIetfTransportErrorCodeString(AEAD_LIMIT_REACHED));
-
-  EXPECT_EQ("Unknown(1024)",
-            QuicIetfTransportErrorCodeString(
-                static_cast<quic::QuicIetfTransportErrorCodes>(0x400)));
-}
-
-TEST_F(QuicErrorCodesTest, QuicErrorCodeToTransportErrorCode) {
-  for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR;
-       ++internal_error_code) {
-    std::string internal_error_code_string =
-        QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code));
-    if (internal_error_code_string == "INVALID_ERROR_CODE") {
-      // Not a valid QuicErrorCode.
-      continue;
-    }
-    QuicErrorCodeToIetfMapping ietf_error_code =
-        QuicErrorCodeToTransportErrorCode(
-            static_cast<QuicErrorCode>(internal_error_code));
-    if (ietf_error_code.is_transport_close) {
-      QuicIetfTransportErrorCodes transport_error_code =
-          static_cast<QuicIetfTransportErrorCodes>(ietf_error_code.error_code);
-      bool is_transport_crypto_error_code =
-          transport_error_code >= 0x100 && transport_error_code <= 0x1ff;
-      if (is_transport_crypto_error_code) {
-        // Ensure that every QuicErrorCode that maps to a CRYPTO_ERROR code has
-        // a corresponding reverse mapping in TlsAlertToQuicErrorCode:
-        EXPECT_EQ(
-            internal_error_code,
-            TlsAlertToQuicErrorCode(transport_error_code - CRYPTO_ERROR_FIRST));
-      }
-      bool is_valid_transport_error_code =
-          transport_error_code <= 0x0f || is_transport_crypto_error_code;
-      EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string;
-    } else {
-      // Non-transport errors are application errors, either HTTP/3 or QPACK.
-      uint64_t application_error_code = ietf_error_code.error_code;
-      bool is_valid_http3_error_code =
-          application_error_code >= 0x100 && application_error_code <= 0x110;
-      bool is_valid_qpack_error_code =
-          application_error_code >= 0x200 && application_error_code <= 0x202;
-      EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code)
-          << internal_error_code_string;
-    }
-  }
-}
-
-using QuicRstErrorCodesTest = QuicTest;
-
-TEST_F(QuicRstErrorCodesTest, QuicRstStreamErrorCodeToString) {
-  EXPECT_STREQ("QUIC_BAD_APPLICATION_PAYLOAD",
-               QuicRstStreamErrorCodeToString(QUIC_BAD_APPLICATION_PAYLOAD));
-}
-
-// When an IETF application protocol error code (sent on the wire in
-// RESET_STREAM and STOP_SENDING frames) is translated into a
-// QuicRstStreamErrorCode and back, it must yield the original value.
-TEST_F(QuicRstErrorCodesTest,
-       IetfResetStreamErrorCodeToRstStreamErrorCodeAndBack) {
-  for (uint64_t wire_code :
-       {static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR),
-        static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK),
-        static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED),
-        static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR),
-        static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}) {
-    QuicRstStreamErrorCode rst_stream_error_code =
-        IetfResetStreamErrorCodeToRstStreamErrorCode(wire_code);
-    EXPECT_EQ(wire_code, RstStreamErrorCodeToIetfResetStreamErrorCode(
-                             rst_stream_error_code));
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_flow_controller.cc b/quic/core/quic_flow_controller.cc
deleted file mode 100644
index 88dc3ed..0000000
--- a/quic/core/quic_flow_controller.cc
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_flow_controller.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define ENDPOINT \
-  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-std::string QuicFlowController::LogLabel() {
-  if (is_connection_flow_controller_) {
-    return "connection";
-  }
-  return absl::StrCat("stream ", id_);
-}
-
-QuicFlowController::QuicFlowController(
-    QuicSession* session,
-    QuicStreamId id,
-    bool is_connection_flow_controller,
-    QuicStreamOffset send_window_offset,
-    QuicStreamOffset receive_window_offset,
-    QuicByteCount receive_window_size_limit,
-    bool should_auto_tune_receive_window,
-    QuicFlowControllerInterface* session_flow_controller)
-    : session_(session),
-      connection_(session->connection()),
-      id_(id),
-      is_connection_flow_controller_(is_connection_flow_controller),
-      perspective_(session->perspective()),
-      bytes_sent_(0),
-      send_window_offset_(send_window_offset),
-      bytes_consumed_(0),
-      highest_received_byte_offset_(0),
-      receive_window_offset_(receive_window_offset),
-      receive_window_size_(receive_window_offset),
-      receive_window_size_limit_(receive_window_size_limit),
-      auto_tune_receive_window_(should_auto_tune_receive_window),
-      session_flow_controller_(session_flow_controller),
-      last_blocked_send_window_offset_(0),
-      prev_window_update_time_(QuicTime::Zero()) {
-  QUICHE_DCHECK_LE(receive_window_size_, receive_window_size_limit_);
-  QUICHE_DCHECK_EQ(
-      is_connection_flow_controller_,
-      QuicUtils::GetInvalidStreamId(session_->transport_version()) == id_);
-
-  QUIC_DVLOG(1) << ENDPOINT << "Created flow controller for " << LogLabel()
-                << ", setting initial receive window offset to: "
-                << receive_window_offset_
-                << ", max receive window to: " << receive_window_size_
-                << ", max receive window limit to: "
-                << receive_window_size_limit_
-                << ", setting send window offset to: " << send_window_offset_;
-}
-
-void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) {
-  bytes_consumed_ += bytes_consumed;
-  QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " consumed " << bytes_consumed_
-                << " bytes.";
-
-  MaybeSendWindowUpdate();
-}
-
-bool QuicFlowController::UpdateHighestReceivedOffset(
-    QuicStreamOffset new_offset) {
-  // Only update if offset has increased.
-  if (new_offset <= highest_received_byte_offset_) {
-    return false;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << LogLabel()
-                << " highest byte offset increased from "
-                << highest_received_byte_offset_ << " to " << new_offset;
-  highest_received_byte_offset_ = new_offset;
-  return true;
-}
-
-void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
-  if (bytes_sent_ + bytes_sent > send_window_offset_) {
-    QUIC_BUG(quic_bug_10836_1)
-        << ENDPOINT << LogLabel() << " Trying to send an extra " << bytes_sent
-        << " bytes, when bytes_sent = " << bytes_sent_
-        << ", and send_window_offset_ = " << send_window_offset_;
-    bytes_sent_ = send_window_offset_;
-
-    // This is an error on our side, close the connection as soon as possible.
-    connection_->CloseConnection(
-        QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA,
-        absl::StrCat(send_window_offset_ - (bytes_sent_ + bytes_sent),
-                     "bytes over send window offset"),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  bytes_sent_ += bytes_sent;
-  QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " sent " << bytes_sent_
-                << " bytes.";
-}
-
-bool QuicFlowController::FlowControlViolation() {
-  if (highest_received_byte_offset_ > receive_window_offset_) {
-    QUIC_DLOG(INFO) << ENDPOINT << "Flow control violation on " << LogLabel()
-                    << ", receive window offset: " << receive_window_offset_
-                    << ", highest received byte offset: "
-                    << highest_received_byte_offset_;
-    return true;
-  }
-  return false;
-}
-
-void QuicFlowController::MaybeIncreaseMaxWindowSize() {
-  // Core of receive window auto tuning.  This method should be called before a
-  // WINDOW_UPDATE frame is sent.  Ideally, window updates should occur close to
-  // once per RTT.  If a window update happens much faster than RTT, it implies
-  // that the flow control window is imposing a bottleneck.  To prevent this,
-  // this method will increase the receive window size (subject to a reasonable
-  // upper bound).  For simplicity this algorithm is deliberately asymmetric, in
-  // that it may increase window size but never decreases.
-
-  // Keep track of timing between successive window updates.
-  QuicTime now = connection_->clock()->ApproximateNow();
-  QuicTime prev = prev_window_update_time_;
-  prev_window_update_time_ = now;
-  if (!prev.IsInitialized()) {
-    QUIC_DVLOG(1) << ENDPOINT << "first window update for " << LogLabel();
-    return;
-  }
-
-  if (!auto_tune_receive_window_) {
-    return;
-  }
-
-  // Get outbound RTT.
-  QuicTime::Delta rtt =
-      connection_->sent_packet_manager().GetRttStats()->smoothed_rtt();
-  if (rtt.IsZero()) {
-    QUIC_DVLOG(1) << ENDPOINT << "rtt zero for " << LogLabel();
-    return;
-  }
-
-  // Now we can compare timing of window updates with RTT.
-  QuicTime::Delta since_last = now - prev;
-  QuicTime::Delta two_rtt = 2 * rtt;
-
-  if (since_last >= two_rtt) {
-    // If interval between window updates is sufficiently large, there
-    // is no need to increase receive_window_size_.
-    return;
-  }
-  QuicByteCount old_window = receive_window_size_;
-  IncreaseWindowSize();
-
-  if (receive_window_size_ > old_window) {
-    QUIC_DVLOG(1) << ENDPOINT << "New max window increase for " << LogLabel()
-                  << " after " << since_last.ToMicroseconds()
-                  << " us, and RTT is " << rtt.ToMicroseconds()
-                  << "us. max wndw: " << receive_window_size_;
-    if (session_flow_controller_ != nullptr) {
-      session_flow_controller_->EnsureWindowAtLeast(
-          kSessionFlowControlMultiplier * receive_window_size_);
-    }
-  } else {
-    // TODO(ckrasic) - add a varz to track this (?).
-    QUIC_LOG_FIRST_N(INFO, 1)
-        << ENDPOINT << "Max window at limit for " << LogLabel() << " after "
-        << since_last.ToMicroseconds() << " us, and RTT is "
-        << rtt.ToMicroseconds() << "us. Limit size: " << receive_window_size_;
-  }
-}
-
-void QuicFlowController::IncreaseWindowSize() {
-  receive_window_size_ *= 2;
-  receive_window_size_ =
-      std::min(receive_window_size_, receive_window_size_limit_);
-}
-
-QuicByteCount QuicFlowController::WindowUpdateThreshold() {
-  return receive_window_size_ / 2;
-}
-
-void QuicFlowController::MaybeSendWindowUpdate() {
-  if (!session_->connection()->connected()) {
-    return;
-  }
-  // Send WindowUpdate to increase receive window if
-  // (receive window offset - consumed bytes) < (max window / 2).
-  // This is behaviour copied from SPDY.
-  QUICHE_DCHECK_LE(bytes_consumed_, receive_window_offset_);
-  QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
-  QuicByteCount threshold = WindowUpdateThreshold();
-
-  if (!prev_window_update_time_.IsInitialized()) {
-    // Treat the initial window as if it is a window update, so if 1/2 the
-    // window is used in less than 2 RTTs, the window is increased.
-    prev_window_update_time_ = connection_->clock()->ApproximateNow();
-  }
-
-  if (available_window >= threshold) {
-    QUIC_DVLOG(1) << ENDPOINT << "Not sending WindowUpdate for " << LogLabel()
-                  << ", available window: " << available_window
-                  << " >= threshold: " << threshold;
-    return;
-  }
-
-  MaybeIncreaseMaxWindowSize();
-  UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
-}
-
-void QuicFlowController::UpdateReceiveWindowOffsetAndSendWindowUpdate(
-    QuicStreamOffset available_window) {
-  // Update our receive window.
-  receive_window_offset_ += (receive_window_size_ - available_window);
-
-  QUIC_DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for " << LogLabel()
-                << ", consumed bytes: " << bytes_consumed_
-                << ", available window: " << available_window
-                << ", and threshold: " << WindowUpdateThreshold()
-                << ", and receive window size: " << receive_window_size_
-                << ". New receive window offset is: " << receive_window_offset_;
-
-  SendWindowUpdate();
-}
-
-bool QuicFlowController::ShouldSendBlocked() {
-  if (SendWindowSize() != 0 ||
-      last_blocked_send_window_offset_ >= send_window_offset_) {
-    return false;
-  }
-  QUIC_DLOG(INFO) << ENDPOINT << LogLabel() << " is flow control blocked. "
-                  << "Send window: " << SendWindowSize()
-                  << ", bytes sent: " << bytes_sent_
-                  << ", send limit: " << send_window_offset_;
-  // The entire send_window has been consumed, we are now flow control
-  // blocked.
-
-  // Keep track of when we last sent a BLOCKED frame so that we only send one
-  // at a given send offset.
-  last_blocked_send_window_offset_ = send_window_offset_;
-  return true;
-}
-
-bool QuicFlowController::UpdateSendWindowOffset(
-    QuicStreamOffset new_send_window_offset) {
-  // Only update if send window has increased.
-  if (new_send_window_offset <= send_window_offset_) {
-    return false;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for " << LogLabel()
-                << " with new offset " << new_send_window_offset
-                << " current offset: " << send_window_offset_
-                << " bytes_sent: " << bytes_sent_;
-
-  // The flow is now unblocked but could have also been unblocked
-  // before.  Return true iff this update caused a change from blocked
-  // to unblocked.
-  const bool was_previously_blocked = IsBlocked();
-  send_window_offset_ = new_send_window_offset;
-  return was_previously_blocked;
-}
-
-void QuicFlowController::EnsureWindowAtLeast(QuicByteCount window_size) {
-  if (receive_window_size_limit_ >= window_size) {
-    return;
-  }
-
-  QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
-  IncreaseWindowSize();
-  UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
-}
-
-bool QuicFlowController::IsBlocked() const {
-  return SendWindowSize() == 0;
-}
-
-uint64_t QuicFlowController::SendWindowSize() const {
-  if (bytes_sent_ > send_window_offset_) {
-    return 0;
-  }
-  return send_window_offset_ - bytes_sent_;
-}
-
-void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) {
-  QUICHE_DCHECK_LE(size, receive_window_size_limit_);
-  QUIC_DVLOG(1) << ENDPOINT << "UpdateReceiveWindowSize for " << LogLabel()
-                << ": " << size;
-  if (receive_window_size_ != receive_window_offset_) {
-    QUIC_BUG(quic_bug_10836_2)
-        << "receive_window_size_:" << receive_window_size_
-        << " != receive_window_offset:" << receive_window_offset_;
-    return;
-  }
-  receive_window_size_ = size;
-  receive_window_offset_ = size;
-}
-
-void QuicFlowController::SendWindowUpdate() {
-  QuicStreamId id = id_;
-  if (is_connection_flow_controller_) {
-    id = QuicUtils::GetInvalidStreamId(connection_->transport_version());
-  }
-  session_->SendWindowUpdate(id, receive_window_offset_);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_flow_controller.h b/quic/core/quic_flow_controller.h
deleted file mode 100644
index 3998081..0000000
--- a/quic/core/quic_flow_controller.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
-#define QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicFlowControllerPeer;
-}  // namespace test
-
-class QuicConnection;
-class QuicSession;
-
-// How much larger the session flow control window needs to be relative to any
-// stream's flow control window.
-const float kSessionFlowControlMultiplier = 1.5;
-
-class QUIC_EXPORT_PRIVATE QuicFlowControllerInterface {
- public:
-  virtual ~QuicFlowControllerInterface() {}
-
-  // Ensures the flow control window is at least |window_size| and send out an
-  // update frame if it is increased.
-  virtual void EnsureWindowAtLeast(QuicByteCount window_size) = 0;
-};
-
-// QuicFlowController allows a QUIC stream or connection to perform flow
-// control. The stream/connection owns a QuicFlowController which keeps track of
-// bytes sent/received, can tell the owner if it is flow control blocked, and
-// can send WINDOW_UPDATE or BLOCKED frames when needed.
-class QUIC_EXPORT_PRIVATE QuicFlowController
-    : public QuicFlowControllerInterface {
- public:
-  QuicFlowController(QuicSession* session,
-                     QuicStreamId id,
-                     bool is_connection_flow_controller,
-                     QuicStreamOffset send_window_offset,
-                     QuicStreamOffset receive_window_offset,
-                     QuicByteCount receive_window_size_limit,
-                     bool should_auto_tune_receive_window,
-                     QuicFlowControllerInterface* session_flow_controller);
-
-  QuicFlowController(const QuicFlowController&) = delete;
-  QuicFlowController(QuicFlowController&&) = default;
-  QuicFlowController& operator=(const QuicFlowController&) = delete;
-
-  ~QuicFlowController() override {}
-
-  // Called when we see a new highest received byte offset from the peer, either
-  // via a data frame or a RST.
-  // Returns true if this call changes highest_received_byte_offset_, and false
-  // in the case where |new_offset| is <= highest_received_byte_offset_.
-  bool UpdateHighestReceivedOffset(QuicStreamOffset new_offset);
-
-  // Called when bytes received from the peer are consumed locally. This may
-  // trigger the sending of a WINDOW_UPDATE frame using |connection|.
-  void AddBytesConsumed(QuicByteCount bytes_consumed);
-
-  // Called when bytes are sent to the peer.
-  void AddBytesSent(QuicByteCount bytes_sent);
-
-  // Increases |send_window_offset_| if |new_send_window_offset| is
-  // greater than the current value.  Returns true if this increase
-  // also causes us to change from a blocked state to unblocked.  In
-  // all other cases, returns false.
-  bool UpdateSendWindowOffset(QuicStreamOffset new_send_window_offset);
-
-  // QuicFlowControllerInterface.
-  void EnsureWindowAtLeast(QuicByteCount window_size) override;
-
-  // Returns the current available send window.
-  QuicByteCount SendWindowSize() const;
-
-  QuicByteCount receive_window_size() const { return receive_window_size_; }
-
-  // Returns whether a BLOCKED frame should be sent.
-  bool ShouldSendBlocked();
-
-  // Returns true if flow control send limits have been reached.
-  bool IsBlocked() const;
-
-  // Returns true if flow control receive limits have been violated by the peer.
-  bool FlowControlViolation();
-
-  // Inform the peer of new receive window.
-  void SendWindowUpdate();
-
-  QuicByteCount bytes_consumed() const { return bytes_consumed_; }
-
-  QuicByteCount bytes_sent() const { return bytes_sent_; }
-
-  QuicStreamOffset send_window_offset() const { return send_window_offset_; }
-
-  QuicStreamOffset highest_received_byte_offset() const {
-    return highest_received_byte_offset_;
-  }
-
-  void set_receive_window_size_limit(QuicByteCount receive_window_size_limit) {
-    QUICHE_DCHECK_GE(receive_window_size_limit, receive_window_size_limit_);
-    receive_window_size_limit_ = receive_window_size_limit;
-  }
-
-  // Should only be called before any data is received.
-  void UpdateReceiveWindowSize(QuicStreamOffset size);
-
-  bool auto_tune_receive_window() { return auto_tune_receive_window_; }
-
- private:
-  friend class test::QuicFlowControllerPeer;
-
-  // Send a WINDOW_UPDATE frame if appropriate.
-  void MaybeSendWindowUpdate();
-
-  // Auto-tune the max receive window size.
-  void MaybeIncreaseMaxWindowSize();
-
-  // Updates the current offset and sends a window update frame.
-  void UpdateReceiveWindowOffsetAndSendWindowUpdate(
-      QuicStreamOffset available_window);
-
-  // Double the window size as long as we haven't hit the max window size.
-  void IncreaseWindowSize();
-
-  // Returns "stream $ID" (where $ID is set to |id_|) or "connection" based on
-  // |is_connection_flow_controller_|.
-  std::string LogLabel();
-
-  // The parent session/connection, used to send connection close on flow
-  // control violation, and WINDOW_UPDATE and BLOCKED frames when appropriate.
-  // Not owned.
-  QuicSession* session_;
-  QuicConnection* connection_;
-
-  // ID of stream this flow controller belongs to. If
-  // |is_connection_flow_controller_| is false, this must be a valid stream ID.
-  QuicStreamId id_;
-
-  // Whether this flow controller is the connection level flow controller
-  // instead of the flow controller for a stream. If true, |id_| is ignored.
-  bool is_connection_flow_controller_;
-
-  // Tracks if this is owned by a server or a client.
-  Perspective perspective_;
-
-  // Tracks number of bytes sent to the peer.
-  QuicByteCount bytes_sent_;
-
-  // The absolute offset in the outgoing byte stream. If this offset is reached
-  // then we become flow control blocked until we receive a WINDOW_UPDATE.
-  QuicStreamOffset send_window_offset_;
-
-  // Overview of receive flow controller.
-  //
-  // 0=...===1=======2-------3 ...... FIN
-  //         |<--- <= 4  --->|
-  //
-
-  // 1) bytes_consumed_ - moves forward when data is read out of the
-  //    stream.
-  //
-  // 2) highest_received_byte_offset_ - moves when data is received
-  //    from the peer.
-  //
-  // 3) receive_window_offset_ - moves when WINDOW_UPDATE is sent.
-  //
-  // 4) receive_window_size_ - maximum allowed unread data (3 - 1).
-  //    This value may be increased by auto-tuning.
-  //
-  // 5) receive_window_size_limit_ - limit on receive_window_size_;
-  //    auto-tuning will not increase window size beyond this limit.
-
-  // Track number of bytes received from the peer, which have been consumed
-  // locally.
-  QuicByteCount bytes_consumed_;
-
-  // The highest byte offset we have seen from the peer. This could be the
-  // highest offset in a data frame, or a final value in a RST.
-  QuicStreamOffset highest_received_byte_offset_;
-
-  // The absolute offset in the incoming byte stream. The peer should never send
-  // us bytes which are beyond this offset.
-  QuicStreamOffset receive_window_offset_;
-
-  // Largest size the receive window can grow to.
-  QuicByteCount receive_window_size_;
-
-  // Upper limit on receive_window_size_;
-  QuicByteCount receive_window_size_limit_;
-
-  // Used to dynamically enable receive window auto-tuning.
-  bool auto_tune_receive_window_;
-
-  // The session's flow controller. Null if this is the session flow controller.
-  // Not owned.
-  QuicFlowControllerInterface* session_flow_controller_;
-
-  // Send window update when receive window size drops below this.
-  QuicByteCount WindowUpdateThreshold();
-
-  // Keep track of the last time we sent a BLOCKED frame. We should only send
-  // another when the number of bytes we have sent has changed.
-  QuicStreamOffset last_blocked_send_window_offset_;
-
-  // Keep time of the last time a window update was sent.  We use this
-  // as part of the receive window auto tuning.
-  QuicTime prev_window_update_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
diff --git a/quic/core/quic_flow_controller_test.cc b/quic/core/quic_flow_controller_test.cc
deleted file mode 100644
index 4c2ce45..0000000
--- a/quic/core/quic_flow_controller_test.cc
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_flow_controller.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-// Receive window auto-tuning uses RTT in its logic.
-const int64_t kRtt = 100;
-
-class MockFlowController : public QuicFlowControllerInterface {
- public:
-  MockFlowController() {}
-  MockFlowController(const MockFlowController&) = delete;
-  MockFlowController& operator=(const MockFlowController&) = delete;
-  ~MockFlowController() override {}
-
-  MOCK_METHOD(void, EnsureWindowAtLeast, (QuicByteCount), (override));
-};
-
-class QuicFlowControllerTest : public QuicTest {
- public:
-  void Initialize() {
-    connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
-                                         Perspective::IS_CLIENT);
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    session_ = std::make_unique<MockQuicSession>(connection_);
-    flow_controller_ = std::make_unique<QuicFlowController>(
-        session_.get(), stream_id_, /*is_connection_flow_controller*/ false,
-        send_window_, receive_window_, kStreamReceiveWindowLimit,
-        should_auto_tune_receive_window_, &session_flow_controller_);
-  }
-
- protected:
-  QuicStreamId stream_id_ = 1234;
-  QuicByteCount send_window_ = kInitialSessionFlowControlWindowForTest;
-  QuicByteCount receive_window_ = kInitialSessionFlowControlWindowForTest;
-  std::unique_ptr<QuicFlowController> flow_controller_;
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnection* connection_;
-  std::unique_ptr<MockQuicSession> session_;
-  MockFlowController session_flow_controller_;
-  bool should_auto_tune_receive_window_ = false;
-};
-
-TEST_F(QuicFlowControllerTest, SendingBytes) {
-  Initialize();
-
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
-  // Send some bytes, but not enough to block.
-  flow_controller_->AddBytesSent(send_window_ / 2);
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
-
-  // Send enough bytes to block.
-  flow_controller_->AddBytesSent(send_window_ / 2);
-  EXPECT_TRUE(flow_controller_->IsBlocked());
-  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-
-  // BLOCKED frame should get sent.
-  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
-
-  // Update the send window, and verify this has unblocked.
-  EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
-  // Updating with a smaller offset doesn't change anything.
-  EXPECT_FALSE(flow_controller_->UpdateSendWindowOffset(send_window_ / 10));
-  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
-  // Try to send more bytes, violating flow control.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _, _));
-  EXPECT_QUIC_BUG(
-      flow_controller_->AddBytesSent(send_window_ * 10),
-      absl::StrCat("Trying to send an extra ", send_window_ * 10, " bytes"));
-  EXPECT_TRUE(flow_controller_->IsBlocked());
-  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytes) {
-  Initialize();
-
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  // Receive some bytes, updating highest received offset, but not enough to
-  // fill flow control receive window.
-  EXPECT_TRUE(
-      flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ((receive_window_ / 2) - 1,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  // Consume enough bytes to send a WINDOW_UPDATE frame.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
-
-  flow_controller_->AddBytesConsumed(1 + receive_window_ / 2);
-
-  // Result is that once again we have a fully open receive window.
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-}
-
-TEST_F(QuicFlowControllerTest, Move) {
-  Initialize();
-
-  flow_controller_->AddBytesSent(send_window_ / 2);
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
-
-  EXPECT_TRUE(
-      flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ((receive_window_ / 2) - 1,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  QuicFlowController flow_controller2(std::move(*flow_controller_));
-  EXPECT_EQ(send_window_ / 2, flow_controller2.SendWindowSize());
-  EXPECT_FALSE(flow_controller2.FlowControlViolation());
-  EXPECT_EQ((receive_window_ / 2) - 1,
-            QuicFlowControllerPeer::ReceiveWindowSize(&flow_controller2));
-}
-
-TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
-  Initialize();
-
-  // Test that we don't send duplicate BLOCKED frames. We should only send one
-  // BLOCKED frame at a given send window offset.
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-
-  // Send enough bytes to block.
-  flow_controller_->AddBytesSent(send_window_);
-  EXPECT_TRUE(flow_controller_->IsBlocked());
-  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-
-  // BLOCKED frame should get sent.
-  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
-
-  // BLOCKED frame should not get sent again until our send offset changes.
-  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
-  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
-  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
-  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
-  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
-
-  // Update the send window, then send enough bytes to block again.
-  EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
-  flow_controller_->AddBytesSent(send_window_);
-  EXPECT_TRUE(flow_controller_->IsBlocked());
-  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
-
-  // BLOCKED frame should get sent as send offset has changed.
-  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
-  should_auto_tune_receive_window_ = true;
-  Initialize();
-  // This test will generate two WINDOW_UPDATE frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
-  EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
-
-  // Make sure clock is inititialized.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicSentPacketManager* manager =
-      QuicConnectionPeer::GetSentPacketManager(connection_);
-
-  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  QuicByteCount threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
-  QuicStreamOffset receive_offset = threshold + 1;
-  // Receive some bytes, updating highest received offset, but not enough to
-  // fill flow control receive window.
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-  EXPECT_CALL(
-      session_flow_controller_,
-      EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
-
-  // Consume enough bytes to send a WINDOW_UPDATE frame.
-  flow_controller_->AddBytesConsumed(threshold + 1);
-  // Result is that once again we have a fully open receive window.
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
-  receive_offset += threshold + 1;
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-  flow_controller_->AddBytesConsumed(threshold + 1);
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  QuicByteCount new_threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-  EXPECT_GT(new_threshold, threshold);
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) {
-  Initialize();
-  // This test will generate two WINDOW_UPDATE frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(2)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
-
-  // Make sure clock is inititialized.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicSentPacketManager* manager =
-      QuicConnectionPeer::GetSentPacketManager(connection_);
-
-  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  QuicByteCount threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
-  QuicStreamOffset receive_offset = threshold + 1;
-  // Receive some bytes, updating highest received offset, but not enough to
-  // fill flow control receive window.
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  // Consume enough bytes to send a WINDOW_UPDATE frame.
-  flow_controller_->AddBytesConsumed(threshold + 1);
-  // Result is that once again we have a fully open receive window.
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  // Move time forward, but by less than two RTTs.  Then receive and consume
-  // some more, forcing a second WINDOW_UPDATE with an increased max window
-  // size.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
-  receive_offset += threshold + 1;
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-  flow_controller_->AddBytesConsumed(threshold + 1);
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  QuicByteCount new_threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-  EXPECT_EQ(new_threshold, threshold);
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) {
-  should_auto_tune_receive_window_ = true;
-  Initialize();
-  // This test will generate two WINDOW_UPDATE frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
-  EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
-
-  // Make sure clock is inititialized.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicSentPacketManager* manager =
-      QuicConnectionPeer::GetSentPacketManager(connection_);
-  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  QuicByteCount threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
-  QuicStreamOffset receive_offset = threshold + 1;
-  // Receive some bytes, updating highest received offset, but not enough to
-  // fill flow control receive window.
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-  EXPECT_CALL(
-      session_flow_controller_,
-      EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
-  flow_controller_->AddBytesConsumed(threshold + 1);
-
-  // Result is that once again we have a fully open receive window.
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  // Move time forward, but by more than two RTTs.  Then receive and consume
-  // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
-
-  receive_offset += threshold + 1;
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-
-  flow_controller_->AddBytesConsumed(threshold + 1);
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-
-  QuicByteCount new_threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-  EXPECT_EQ(new_threshold, 2 * threshold);
-}
-
-TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) {
-  Initialize();
-  // This test will generate two WINDOW_UPDATE frames.
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(2)
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-  EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
-
-  // Make sure clock is inititialized.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicSentPacketManager* manager =
-      QuicConnectionPeer::GetSentPacketManager(connection_);
-  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  EXPECT_FALSE(flow_controller_->IsBlocked());
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  QuicByteCount threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
-  QuicStreamOffset receive_offset = threshold + 1;
-  // Receive some bytes, updating highest received offset, but not enough to
-  // fill flow control receive window.
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  flow_controller_->AddBytesConsumed(threshold + 1);
-
-  // Result is that once again we have a fully open receive window.
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
-            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
-
-  // Move time forward, but by more than two RTTs.  Then receive and consume
-  // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
-  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
-
-  receive_offset += threshold + 1;
-  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
-
-  flow_controller_->AddBytesConsumed(threshold + 1);
-  EXPECT_FALSE(flow_controller_->FlowControlViolation());
-
-  QuicByteCount new_threshold =
-      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
-
-  EXPECT_EQ(new_threshold, threshold);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
deleted file mode 100644
index c1b3228..0000000
--- a/quic/core/quic_framer.cc
+++ /dev/null
@@ -1,7244 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_framer.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_socket_address_coder.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-namespace {
-
-#define ENDPOINT \
-  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-// Number of bits the packet number length bits are shifted from the right
-// edge of the header.
-const uint8_t kPublicHeaderSequenceNumberShift = 4;
-
-// There are two interpretations for the Frame Type byte in the QUIC protocol,
-// resulting in two Frame Types: Special Frame Types and Regular Frame Types.
-//
-// Regular Frame Types use the Frame Type byte simply. Currently defined
-// Regular Frame Types are:
-// Padding            : 0b 00000000 (0x00)
-// ResetStream        : 0b 00000001 (0x01)
-// ConnectionClose    : 0b 00000010 (0x02)
-// GoAway             : 0b 00000011 (0x03)
-// WindowUpdate       : 0b 00000100 (0x04)
-// Blocked            : 0b 00000101 (0x05)
-//
-// Special Frame Types encode both a Frame Type and corresponding flags
-// all in the Frame Type byte. Currently defined Special Frame Types
-// are:
-// Stream             : 0b 1xxxxxxx
-// Ack                : 0b 01xxxxxx
-//
-// Semantics of the flag bits above (the x bits) depends on the frame type.
-
-// Masks to determine if the frame type is a special use
-// and for specific special frame types.
-const uint8_t kQuicFrameTypeBrokenMask = 0xE0;   // 0b 11100000
-const uint8_t kQuicFrameTypeSpecialMask = 0xC0;  // 0b 11000000
-const uint8_t kQuicFrameTypeStreamMask = 0x80;
-const uint8_t kQuicFrameTypeAckMask = 0x40;
-static_assert(kQuicFrameTypeSpecialMask ==
-                  (kQuicFrameTypeStreamMask | kQuicFrameTypeAckMask),
-              "Invalid kQuicFrameTypeSpecialMask");
-
-// The stream type format is 1FDOOOSS, where
-//    F is the fin bit.
-//    D is the data length bit (0 or 2 bytes).
-//    OO/OOO are the size of the offset.
-//    SS is the size of the stream ID.
-// Note that the stream encoding can not be determined by inspection. It can
-// be determined only by knowing the QUIC Version.
-// Stream frame relative shifts and masks for interpreting the stream flags.
-// StreamID may be 1, 2, 3, or 4 bytes.
-const uint8_t kQuicStreamIdShift = 2;
-const uint8_t kQuicStreamIDLengthMask = 0x03;
-
-// Offset may be 0, 2, 4, or 8 bytes.
-const uint8_t kQuicStreamShift = 3;
-const uint8_t kQuicStreamOffsetMask = 0x07;
-
-// Data length may be 0 or 2 bytes.
-const uint8_t kQuicStreamDataLengthShift = 1;
-const uint8_t kQuicStreamDataLengthMask = 0x01;
-
-// Fin bit may be set or not.
-const uint8_t kQuicStreamFinShift = 1;
-const uint8_t kQuicStreamFinMask = 0x01;
-
-// The format is 01M0LLOO, where
-//   M if set, there are multiple ack blocks in the frame.
-//  LL is the size of the largest ack field.
-//  OO is the size of the ack blocks offset field.
-// packet number size shift used in AckFrames.
-const uint8_t kQuicSequenceNumberLengthNumBits = 2;
-const uint8_t kActBlockLengthOffset = 0;
-const uint8_t kLargestAckedOffset = 2;
-
-// Acks may have only one ack block.
-const uint8_t kQuicHasMultipleAckBlocksOffset = 5;
-
-// Timestamps are 4 bytes followed by 2 bytes.
-const uint8_t kQuicNumTimestampsLength = 1;
-const uint8_t kQuicFirstTimestampLength = 4;
-const uint8_t kQuicTimestampLength = 2;
-// Gaps between packet numbers are 1 byte.
-const uint8_t kQuicTimestampPacketNumberGapLength = 1;
-
-// Maximum length of encoded error strings.
-const int kMaxErrorStringLength = 256;
-
-const uint8_t kConnectionIdLengthAdjustment = 3;
-const uint8_t kDestinationConnectionIdLengthMask = 0xF0;
-const uint8_t kSourceConnectionIdLengthMask = 0x0F;
-
-// Returns the absolute value of the difference between |a| and |b|.
-uint64_t Delta(uint64_t a, uint64_t b) {
-  // Since these are unsigned numbers, we can't just return abs(a - b)
-  if (a < b) {
-    return b - a;
-  }
-  return a - b;
-}
-
-uint64_t ClosestTo(uint64_t target, uint64_t a, uint64_t b) {
-  return (Delta(target, a) < Delta(target, b)) ? a : b;
-}
-
-QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
-  switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
-    case PACKET_FLAGS_8BYTE_PACKET:
-      return PACKET_6BYTE_PACKET_NUMBER;
-    case PACKET_FLAGS_4BYTE_PACKET:
-      return PACKET_4BYTE_PACKET_NUMBER;
-    case PACKET_FLAGS_2BYTE_PACKET:
-      return PACKET_2BYTE_PACKET_NUMBER;
-    case PACKET_FLAGS_1BYTE_PACKET:
-      return PACKET_1BYTE_PACKET_NUMBER;
-    default:
-      QUIC_BUG(quic_bug_10850_1) << "Unreachable case statement.";
-      return PACKET_6BYTE_PACKET_NUMBER;
-  }
-}
-
-QuicPacketNumberLength ReadAckPacketNumberLength(uint8_t flags) {
-  switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
-    case PACKET_FLAGS_8BYTE_PACKET:
-      return PACKET_6BYTE_PACKET_NUMBER;
-    case PACKET_FLAGS_4BYTE_PACKET:
-      return PACKET_4BYTE_PACKET_NUMBER;
-    case PACKET_FLAGS_2BYTE_PACKET:
-      return PACKET_2BYTE_PACKET_NUMBER;
-    case PACKET_FLAGS_1BYTE_PACKET:
-      return PACKET_1BYTE_PACKET_NUMBER;
-    default:
-      QUIC_BUG(quic_bug_10850_2) << "Unreachable case statement.";
-      return PACKET_6BYTE_PACKET_NUMBER;
-  }
-}
-
-uint8_t PacketNumberLengthToOnWireValue(
-    QuicPacketNumberLength packet_number_length) {
-  return packet_number_length - 1;
-}
-
-QuicPacketNumberLength GetShortHeaderPacketNumberLength(uint8_t type) {
-  QUICHE_DCHECK(!(type & FLAGS_LONG_HEADER));
-  return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
-}
-
-uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type,
-                                    const ParsedQuicVersion& version) {
-  switch (type) {
-    case INITIAL:
-      return version.UsesV2PacketTypes() ? (1 << 4) : 0;
-    case ZERO_RTT_PROTECTED:
-      return version.UsesV2PacketTypes() ? (2 << 4) : (1 << 4);
-    case HANDSHAKE:
-      return version.UsesV2PacketTypes() ? (3 << 4) : (2 << 4);
-    case RETRY:
-      return version.UsesV2PacketTypes() ? 0 : (3 << 4);
-    case VERSION_NEGOTIATION:
-      return 0xF0;  // Value does not matter
-    default:
-      QUIC_BUG(quic_bug_10850_3) << "Invalid long header type: " << type;
-      return 0xFF;
-  }
-}
-
-QuicLongHeaderType GetLongHeaderType(uint8_t type,
-                                     const ParsedQuicVersion& version) {
-  QUICHE_DCHECK((type & FLAGS_LONG_HEADER));
-  switch ((type & 0x30) >> 4) {
-    case 0:
-      return version.UsesV2PacketTypes() ? RETRY : INITIAL;
-    case 1:
-      return version.UsesV2PacketTypes() ? INITIAL : ZERO_RTT_PROTECTED;
-    case 2:
-      return version.UsesV2PacketTypes() ? ZERO_RTT_PROTECTED : HANDSHAKE;
-    case 3:
-      return version.UsesV2PacketTypes() ? HANDSHAKE : RETRY;
-    default:
-      QUIC_BUG(quic_bug_10850_4) << "Unreachable statement";
-      return INVALID_PACKET_TYPE;
-  }
-}
-
-QuicPacketNumberLength GetLongHeaderPacketNumberLength(uint8_t type) {
-  return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
-}
-
-// Used to get packet number space before packet gets decrypted.
-PacketNumberSpace GetPacketNumberSpace(const QuicPacketHeader& header) {
-  switch (header.form) {
-    case GOOGLE_QUIC_PACKET:
-      QUIC_BUG(quic_bug_10850_5)
-          << "Try to get packet number space of Google QUIC packet";
-      break;
-    case IETF_QUIC_SHORT_HEADER_PACKET:
-      return APPLICATION_DATA;
-    case IETF_QUIC_LONG_HEADER_PACKET:
-      switch (header.long_packet_type) {
-        case INITIAL:
-          return INITIAL_DATA;
-        case HANDSHAKE:
-          return HANDSHAKE_DATA;
-        case ZERO_RTT_PROTECTED:
-          return APPLICATION_DATA;
-        case VERSION_NEGOTIATION:
-        case RETRY:
-        case INVALID_PACKET_TYPE:
-          QUIC_BUG(quic_bug_10850_6)
-              << "Try to get packet number space of long header type: "
-              << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
-          break;
-      }
-  }
-
-  return NUM_PACKET_NUMBER_SPACES;
-}
-
-EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) {
-  switch (header.form) {
-    case GOOGLE_QUIC_PACKET:
-      QUIC_BUG(quic_bug_10850_7)
-          << "Cannot determine EncryptionLevel from Google QUIC header";
-      break;
-    case IETF_QUIC_SHORT_HEADER_PACKET:
-      return ENCRYPTION_FORWARD_SECURE;
-    case IETF_QUIC_LONG_HEADER_PACKET:
-      switch (header.long_packet_type) {
-        case INITIAL:
-          return ENCRYPTION_INITIAL;
-        case HANDSHAKE:
-          return ENCRYPTION_HANDSHAKE;
-        case ZERO_RTT_PROTECTED:
-          return ENCRYPTION_ZERO_RTT;
-        case VERSION_NEGOTIATION:
-        case RETRY:
-        case INVALID_PACKET_TYPE:
-          QUIC_BUG(quic_bug_10850_8)
-              << "No encryption used with type "
-              << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
-      }
-  }
-  return NUM_ENCRYPTION_LEVELS;
-}
-
-absl::string_view TruncateErrorString(absl::string_view error) {
-  if (error.length() <= kMaxErrorStringLength) {
-    return error;
-  }
-  return absl::string_view(error.data(), kMaxErrorStringLength);
-}
-
-size_t TruncatedErrorStringSize(const absl::string_view& error) {
-  if (error.length() < kMaxErrorStringLength) {
-    return error.length();
-  }
-  return kMaxErrorStringLength;
-}
-
-uint8_t GetConnectionIdLengthValue(QuicConnectionIdLength length) {
-  if (length == 0) {
-    return 0;
-  }
-  return static_cast<uint8_t>(length - kConnectionIdLengthAdjustment);
-}
-
-bool IsValidPacketNumberLength(QuicPacketNumberLength packet_number_length) {
-  size_t length = packet_number_length;
-  return length == 1 || length == 2 || length == 4 || length == 6 ||
-         length == 8;
-}
-
-bool IsValidFullPacketNumber(uint64_t full_packet_number,
-                             ParsedQuicVersion version) {
-  return full_packet_number > 0 || version.HasIetfQuicFrames();
-}
-
-bool AppendIetfConnectionIds(bool version_flag, bool use_length_prefix,
-                             QuicConnectionId destination_connection_id,
-                             QuicConnectionId source_connection_id,
-                             QuicDataWriter* writer) {
-  if (!version_flag) {
-    return writer->WriteConnectionId(destination_connection_id);
-  }
-
-  if (use_length_prefix) {
-    return writer->WriteLengthPrefixedConnectionId(destination_connection_id) &&
-           writer->WriteLengthPrefixedConnectionId(source_connection_id);
-  }
-
-  // Compute connection ID length byte.
-  uint8_t dcil = GetConnectionIdLengthValue(
-      static_cast<QuicConnectionIdLength>(destination_connection_id.length()));
-  uint8_t scil = GetConnectionIdLengthValue(
-      static_cast<QuicConnectionIdLength>(source_connection_id.length()));
-  uint8_t connection_id_length = dcil << 4 | scil;
-
-  return writer->WriteUInt8(connection_id_length) &&
-         writer->WriteConnectionId(destination_connection_id) &&
-         writer->WriteConnectionId(source_connection_id);
-}
-
-enum class DroppedPacketReason {
-  // General errors
-  INVALID_PUBLIC_HEADER,
-  VERSION_MISMATCH,
-  // Version negotiation packet errors
-  INVALID_VERSION_NEGOTIATION_PACKET,
-  // Public reset packet errors, pre-v44
-  INVALID_PUBLIC_RESET_PACKET,
-  // Data packet errors
-  INVALID_PACKET_NUMBER,
-  INVALID_DIVERSIFICATION_NONCE,
-  DECRYPTION_FAILURE,
-  NUM_REASONS,
-};
-
-void RecordDroppedPacketReason(DroppedPacketReason reason) {
-  QUIC_CLIENT_HISTOGRAM_ENUM("QuicDroppedPacketReason", reason,
-                             DroppedPacketReason::NUM_REASONS,
-                             "The reason a packet was not processed. Recorded "
-                             "each time such a packet is dropped");
-}
-
-PacketHeaderFormat GetIetfPacketHeaderFormat(uint8_t type_byte) {
-  return type_byte & FLAGS_LONG_HEADER ? IETF_QUIC_LONG_HEADER_PACKET
-                                       : IETF_QUIC_SHORT_HEADER_PACKET;
-}
-
-std::string GenerateErrorString(std::string initial_error_string,
-                                QuicErrorCode quic_error_code) {
-  if (quic_error_code == QUIC_IETF_GQUIC_ERROR_MISSING) {
-    // QUIC_IETF_GQUIC_ERROR_MISSING is special -- it means not to encode
-    // the error value in the string.
-    return initial_error_string;
-  }
-  return absl::StrCat(std::to_string(static_cast<unsigned>(quic_error_code)),
-                      ":", initial_error_string);
-}
-
-}  // namespace
-
-QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
-                       QuicTime creation_time, Perspective perspective,
-                       uint8_t expected_server_connection_id_length)
-    : visitor_(nullptr),
-      error_(QUIC_NO_ERROR),
-      last_serialized_server_connection_id_(EmptyQuicConnectionId()),
-      last_serialized_client_connection_id_(EmptyQuicConnectionId()),
-      version_(ParsedQuicVersion::Unsupported()),
-      supported_versions_(supported_versions),
-      decrypter_level_(ENCRYPTION_INITIAL),
-      alternative_decrypter_level_(NUM_ENCRYPTION_LEVELS),
-      alternative_decrypter_latch_(false),
-      perspective_(perspective),
-      validate_flags_(true),
-      process_timestamps_(false),
-      max_receive_timestamps_per_ack_(std::numeric_limits<uint32_t>::max()),
-      receive_timestamps_exponent_(0),
-      creation_time_(creation_time),
-      last_timestamp_(QuicTime::Delta::Zero()),
-      support_key_update_for_connection_(false),
-      current_key_phase_bit_(false),
-      potential_peer_key_update_attempt_count_(0),
-      first_sending_packet_number_(FirstSendingPacketNumber()),
-      data_producer_(nullptr),
-      infer_packet_header_type_from_version_(perspective ==
-                                             Perspective::IS_CLIENT),
-      expected_server_connection_id_length_(
-          expected_server_connection_id_length),
-      expected_client_connection_id_length_(0),
-      supports_multiple_packet_number_spaces_(false),
-      last_written_packet_number_length_(0),
-      peer_ack_delay_exponent_(kDefaultAckDelayExponent),
-      local_ack_delay_exponent_(kDefaultAckDelayExponent),
-      current_received_frame_type_(0),
-      previously_received_frame_type_(0) {
-  QUICHE_DCHECK(!supported_versions.empty());
-  version_ = supported_versions_[0];
-  QUICHE_DCHECK(version_.IsKnown())
-      << ParsedQuicVersionVectorToString(supported_versions_);
-}
-
-QuicFramer::~QuicFramer() {}
-
-// static
-size_t QuicFramer::GetMinStreamFrameSize(QuicTransportVersion version,
-                                         QuicStreamId stream_id,
-                                         QuicStreamOffset offset,
-                                         bool last_frame_in_packet,
-                                         size_t data_length) {
-  if (VersionHasIetfQuicFrames(version)) {
-    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(stream_id) +
-           (last_frame_in_packet
-                ? 0
-                : QuicDataWriter::GetVarInt62Len(data_length)) +
-           (offset != 0 ? QuicDataWriter::GetVarInt62Len(offset) : 0);
-  }
-  return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
-         GetStreamOffsetSize(offset) +
-         (last_frame_in_packet ? 0 : kQuicStreamPayloadLengthSize);
-}
-
-// static
-size_t QuicFramer::GetMinCryptoFrameSize(QuicStreamOffset offset,
-                                         QuicPacketLength data_length) {
-  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(offset) +
-         QuicDataWriter::GetVarInt62Len(data_length);
-}
-
-// static
-size_t QuicFramer::GetMessageFrameSize(QuicTransportVersion version,
-                                       bool last_frame_in_packet,
-                                       QuicByteCount length) {
-  QUIC_BUG_IF(quic_bug_12975_1, !VersionSupportsMessageFrames(version))
-      << "Try to serialize MESSAGE frame in " << version;
-  return kQuicFrameTypeSize +
-         (last_frame_in_packet ? 0 : QuicDataWriter::GetVarInt62Len(length)) +
-         length;
-}
-
-// static
-size_t QuicFramer::GetMinAckFrameSize(
-    QuicTransportVersion version, const QuicAckFrame& ack_frame,
-    uint32_t local_ack_delay_exponent,
-    bool use_ietf_ack_with_receive_timestamp) {
-  if (VersionHasIetfQuicFrames(version)) {
-    // The minimal ack frame consists of the following fields: Largest
-    // Acknowledged, ACK Delay, 0 ACK Block Count, First ACK Block and either 0
-    // Timestamp Range Count or ECN counts.
-    // Type byte + largest acked.
-    size_t min_size =
-        kQuicFrameTypeSize +
-        QuicDataWriter::GetVarInt62Len(LargestAcked(ack_frame).ToUint64());
-    // Ack delay.
-    min_size += QuicDataWriter::GetVarInt62Len(
-        ack_frame.ack_delay_time.ToMicroseconds() >> local_ack_delay_exponent);
-    // 0 ack block count.
-    min_size += QuicDataWriter::GetVarInt62Len(0);
-    // First ack block.
-    min_size += QuicDataWriter::GetVarInt62Len(
-        ack_frame.packets.Empty() ? 0
-                                  : ack_frame.packets.rbegin()->Length() - 1);
-
-    if (use_ietf_ack_with_receive_timestamp) {
-      // 0 Timestamp Range Count.
-      min_size += QuicDataWriter::GetVarInt62Len(0);
-    } else if (ack_frame.ecn_counters_populated &&
-               (ack_frame.ect_0_count || ack_frame.ect_1_count ||
-                ack_frame.ecn_ce_count)) {
-      // ECN counts.
-      min_size += (QuicDataWriter::GetVarInt62Len(ack_frame.ect_0_count) +
-                   QuicDataWriter::GetVarInt62Len(ack_frame.ect_1_count) +
-                   QuicDataWriter::GetVarInt62Len(ack_frame.ecn_ce_count));
-    }
-    return min_size;
-  }
-  return kQuicFrameTypeSize +
-         GetMinPacketNumberLength(LargestAcked(ack_frame)) +
-         kQuicDeltaTimeLargestObservedSize + kQuicNumTimestampsSize;
-}
-
-// static
-size_t QuicFramer::GetStopWaitingFrameSize(
-    QuicPacketNumberLength packet_number_length) {
-  size_t min_size = kQuicFrameTypeSize + packet_number_length;
-  return min_size;
-}
-
-// static
-size_t QuicFramer::GetRstStreamFrameSize(QuicTransportVersion version,
-                                         const QuicRstStreamFrame& frame) {
-  if (VersionHasIetfQuicFrames(version)) {
-    return QuicDataWriter::GetVarInt62Len(frame.stream_id) +
-           QuicDataWriter::GetVarInt62Len(frame.byte_offset) +
-           kQuicFrameTypeSize +
-           QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
-  }
-  return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
-         kQuicErrorCodeSize;
-}
-
-// static
-size_t QuicFramer::GetConnectionCloseFrameSize(
-    QuicTransportVersion version, const QuicConnectionCloseFrame& frame) {
-  if (!VersionHasIetfQuicFrames(version)) {
-    // Not IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
-    return kQuicFrameTypeSize + kQuicErrorCodeSize +
-           kQuicErrorDetailsLengthSize +
-           TruncatedErrorStringSize(frame.error_details);
-  }
-
-  // Prepend the extra error information to the string and get the result's
-  // length.
-  const size_t truncated_error_string_size = TruncatedErrorStringSize(
-      GenerateErrorString(frame.error_details, frame.quic_error_code));
-
-  const size_t frame_size =
-      truncated_error_string_size +
-      QuicDataWriter::GetVarInt62Len(truncated_error_string_size) +
-      kQuicFrameTypeSize +
-      QuicDataWriter::GetVarInt62Len(frame.wire_error_code);
-  if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
-    return frame_size;
-  }
-  // The Transport close frame has the transport_close_frame_type, so include
-  // its length.
-  return frame_size +
-         QuicDataWriter::GetVarInt62Len(frame.transport_close_frame_type);
-}
-
-// static
-size_t QuicFramer::GetMinGoAwayFrameSize() {
-  return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
-         kQuicMaxStreamIdSize;
-}
-
-// static
-size_t QuicFramer::GetWindowUpdateFrameSize(
-    QuicTransportVersion version, const QuicWindowUpdateFrame& frame) {
-  if (!VersionHasIetfQuicFrames(version)) {
-    return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
-  }
-  if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
-    // Frame would be a MAX DATA frame, which has only a Maximum Data field.
-    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data);
-  }
-  // Frame would be MAX STREAM DATA, has Maximum Stream Data and Stream ID
-  // fields.
-  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data) +
-         QuicDataWriter::GetVarInt62Len(frame.stream_id);
-}
-
-// static
-size_t QuicFramer::GetMaxStreamsFrameSize(QuicTransportVersion version,
-                                          const QuicMaxStreamsFrame& frame) {
-  if (!VersionHasIetfQuicFrames(version)) {
-    QUIC_BUG(quic_bug_10850_9)
-        << "In version " << version
-        << ", which does not support IETF Frames, and tried to serialize "
-           "MaxStreams Frame.";
-  }
-  return kQuicFrameTypeSize +
-         QuicDataWriter::GetVarInt62Len(frame.stream_count);
-}
-
-// static
-size_t QuicFramer::GetStreamsBlockedFrameSize(
-    QuicTransportVersion version, const QuicStreamsBlockedFrame& frame) {
-  if (!VersionHasIetfQuicFrames(version)) {
-    QUIC_BUG(quic_bug_10850_10)
-        << "In version " << version
-        << ", which does not support IETF frames, and tried to serialize "
-           "StreamsBlocked Frame.";
-  }
-
-  return kQuicFrameTypeSize +
-         QuicDataWriter::GetVarInt62Len(frame.stream_count);
-}
-
-// static
-size_t QuicFramer::GetBlockedFrameSize(QuicTransportVersion version,
-                                       const QuicBlockedFrame& frame) {
-  if (!VersionHasIetfQuicFrames(version)) {
-    return kQuicFrameTypeSize + kQuicMaxStreamIdSize;
-  }
-  if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
-    // return size of IETF QUIC Blocked frame
-    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset);
-  }
-  // return size of IETF QUIC Stream Blocked frame.
-  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset) +
-         QuicDataWriter::GetVarInt62Len(frame.stream_id);
-}
-
-// static
-size_t QuicFramer::GetStopSendingFrameSize(const QuicStopSendingFrame& frame) {
-  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.stream_id) +
-         QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
-}
-
-// static
-size_t QuicFramer::GetAckFrequencyFrameSize(
-    const QuicAckFrequencyFrame& frame) {
-  return QuicDataWriter::GetVarInt62Len(IETF_ACK_FREQUENCY) +
-         QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
-         QuicDataWriter::GetVarInt62Len(frame.packet_tolerance) +
-         QuicDataWriter::GetVarInt62Len(frame.max_ack_delay.ToMicroseconds()) +
-         // One byte for encoding boolean
-         1;
-}
-
-// static
-size_t QuicFramer::GetPathChallengeFrameSize(
-    const QuicPathChallengeFrame& frame) {
-  return kQuicFrameTypeSize + sizeof(frame.data_buffer);
-}
-
-// static
-size_t QuicFramer::GetPathResponseFrameSize(
-    const QuicPathResponseFrame& frame) {
-  return kQuicFrameTypeSize + sizeof(frame.data_buffer);
-}
-
-// static
-size_t QuicFramer::GetRetransmittableControlFrameSize(
-    QuicTransportVersion version, const QuicFrame& frame) {
-  switch (frame.type) {
-    case PING_FRAME:
-      // Ping has no payload.
-      return kQuicFrameTypeSize;
-    case RST_STREAM_FRAME:
-      return GetRstStreamFrameSize(version, *frame.rst_stream_frame);
-    case CONNECTION_CLOSE_FRAME:
-      return GetConnectionCloseFrameSize(version,
-                                         *frame.connection_close_frame);
-    case GOAWAY_FRAME:
-      return GetMinGoAwayFrameSize() +
-             TruncatedErrorStringSize(frame.goaway_frame->reason_phrase);
-    case WINDOW_UPDATE_FRAME:
-      // For IETF QUIC, this could be either a MAX DATA or MAX STREAM DATA.
-      // GetWindowUpdateFrameSize figures this out and returns the correct
-      // length.
-      return GetWindowUpdateFrameSize(version, frame.window_update_frame);
-    case BLOCKED_FRAME:
-      return GetBlockedFrameSize(version, frame.blocked_frame);
-    case NEW_CONNECTION_ID_FRAME:
-      return GetNewConnectionIdFrameSize(*frame.new_connection_id_frame);
-    case RETIRE_CONNECTION_ID_FRAME:
-      return GetRetireConnectionIdFrameSize(*frame.retire_connection_id_frame);
-    case NEW_TOKEN_FRAME:
-      return GetNewTokenFrameSize(*frame.new_token_frame);
-    case MAX_STREAMS_FRAME:
-      return GetMaxStreamsFrameSize(version, frame.max_streams_frame);
-    case STREAMS_BLOCKED_FRAME:
-      return GetStreamsBlockedFrameSize(version, frame.streams_blocked_frame);
-    case PATH_RESPONSE_FRAME:
-      return GetPathResponseFrameSize(*frame.path_response_frame);
-    case PATH_CHALLENGE_FRAME:
-      return GetPathChallengeFrameSize(*frame.path_challenge_frame);
-    case STOP_SENDING_FRAME:
-      return GetStopSendingFrameSize(frame.stop_sending_frame);
-    case HANDSHAKE_DONE_FRAME:
-      // HANDSHAKE_DONE has no payload.
-      return kQuicFrameTypeSize;
-    case ACK_FREQUENCY_FRAME:
-      return GetAckFrequencyFrameSize(*frame.ack_frequency_frame);
-    case STREAM_FRAME:
-    case ACK_FRAME:
-    case STOP_WAITING_FRAME:
-    case MTU_DISCOVERY_FRAME:
-    case PADDING_FRAME:
-    case MESSAGE_FRAME:
-    case CRYPTO_FRAME:
-    case NUM_FRAME_TYPES:
-      QUICHE_DCHECK(false);
-      return 0;
-  }
-
-  // Not reachable, but some Chrome compilers can't figure that out.  *sigh*
-  QUICHE_DCHECK(false);
-  return 0;
-}
-
-// static
-size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) {
-  // Sizes are 1 through 4 bytes.
-  for (int i = 1; i <= 4; ++i) {
-    stream_id >>= 8;
-    if (stream_id == 0) {
-      return i;
-    }
-  }
-  QUIC_BUG(quic_bug_10850_11) << "Failed to determine StreamIDSize.";
-  return 4;
-}
-
-// static
-size_t QuicFramer::GetStreamOffsetSize(QuicStreamOffset offset) {
-  // 0 is a special case.
-  if (offset == 0) {
-    return 0;
-  }
-  // 2 through 8 are the remaining sizes.
-  offset >>= 8;
-  for (int i = 2; i <= 8; ++i) {
-    offset >>= 8;
-    if (offset == 0) {
-      return i;
-    }
-  }
-  QUIC_BUG(quic_bug_10850_12) << "Failed to determine StreamOffsetSize.";
-  return 8;
-}
-
-// static
-size_t QuicFramer::GetNewConnectionIdFrameSize(
-    const QuicNewConnectionIdFrame& frame) {
-  return kQuicFrameTypeSize +
-         QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
-         QuicDataWriter::GetVarInt62Len(frame.retire_prior_to) +
-         kConnectionIdLengthSize + frame.connection_id.length() +
-         sizeof(frame.stateless_reset_token);
-}
-
-// static
-size_t QuicFramer::GetRetireConnectionIdFrameSize(
-    const QuicRetireConnectionIdFrame& frame) {
-  return kQuicFrameTypeSize +
-         QuicDataWriter::GetVarInt62Len(frame.sequence_number);
-}
-
-// static
-size_t QuicFramer::GetNewTokenFrameSize(const QuicNewTokenFrame& frame) {
-  return kQuicFrameTypeSize +
-         QuicDataWriter::GetVarInt62Len(frame.token.length()) +
-         frame.token.length();
-}
-
-// TODO(nharper): Change this method to take a ParsedQuicVersion.
-bool QuicFramer::IsSupportedTransportVersion(
-    const QuicTransportVersion version) const {
-  for (const ParsedQuicVersion& supported_version : supported_versions_) {
-    if (version == supported_version.transport_version) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicFramer::IsSupportedVersion(const ParsedQuicVersion version) const {
-  for (const ParsedQuicVersion& supported_version : supported_versions_) {
-    if (version == supported_version) {
-      return true;
-    }
-  }
-  return false;
-}
-
-size_t QuicFramer::GetSerializedFrameLength(
-    const QuicFrame& frame, size_t free_bytes, bool first_frame,
-    bool last_frame, QuicPacketNumberLength packet_number_length) {
-  // Prevent a rare crash reported in b/19458523.
-  if (frame.type == ACK_FRAME && frame.ack_frame == nullptr) {
-    QUIC_BUG(quic_bug_10850_13)
-        << "Cannot compute the length of a null ack frame. free_bytes:"
-        << free_bytes << " first_frame:" << first_frame
-        << " last_frame:" << last_frame
-        << " seq num length:" << packet_number_length;
-    set_error(QUIC_INTERNAL_ERROR);
-    visitor_->OnError(this);
-    return 0;
-  }
-  if (frame.type == PADDING_FRAME) {
-    if (frame.padding_frame.num_padding_bytes == -1) {
-      // Full padding to the end of the packet.
-      return free_bytes;
-    } else {
-      // Lite padding.
-      return free_bytes <
-                     static_cast<size_t>(frame.padding_frame.num_padding_bytes)
-                 ? free_bytes
-                 : frame.padding_frame.num_padding_bytes;
-    }
-  }
-
-  size_t frame_len =
-      ComputeFrameLength(frame, last_frame, packet_number_length);
-  if (frame_len <= free_bytes) {
-    // Frame fits within packet. Note that acks may be truncated.
-    return frame_len;
-  }
-  // Only truncate the first frame in a packet, so if subsequent ones go
-  // over, stop including more frames.
-  if (!first_frame) {
-    return 0;
-  }
-  bool can_truncate =
-      frame.type == ACK_FRAME &&
-      free_bytes >=
-          GetMinAckFrameSize(version_.transport_version, *frame.ack_frame,
-                             local_ack_delay_exponent_,
-                             UseIetfAckWithReceiveTimestamp(*frame.ack_frame));
-  if (can_truncate) {
-    // Truncate the frame so the packet will not exceed kMaxOutgoingPacketSize.
-    // Note that we may not use every byte of the writer in this case.
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Truncating large frame, free bytes: " << free_bytes;
-    return free_bytes;
-  }
-  return 0;
-}
-
-QuicFramer::AckFrameInfo::AckFrameInfo()
-    : max_block_length(0), first_block_length(0), num_ack_blocks(0) {}
-
-QuicFramer::AckFrameInfo::AckFrameInfo(const AckFrameInfo& other) = default;
-
-QuicFramer::AckFrameInfo::~AckFrameInfo() {}
-
-bool QuicFramer::WriteIetfLongHeaderLength(const QuicPacketHeader& header,
-                                           QuicDataWriter* writer,
-                                           size_t length_field_offset,
-                                           EncryptionLevel level) {
-  if (!QuicVersionHasLongHeaderLengths(transport_version()) ||
-      !header.version_flag || length_field_offset == 0) {
-    return true;
-  }
-  if (writer->length() < length_field_offset ||
-      writer->length() - length_field_offset <
-          kQuicDefaultLongHeaderLengthLength) {
-    set_detailed_error("Invalid length_field_offset.");
-    QUIC_BUG(quic_bug_10850_14) << "Invalid length_field_offset.";
-    return false;
-  }
-  size_t length_to_write = writer->length() - length_field_offset -
-                           kQuicDefaultLongHeaderLengthLength;
-  // Add length of auth tag.
-  length_to_write = GetCiphertextSize(level, length_to_write);
-
-  QuicDataWriter length_writer(writer->length() - length_field_offset,
-                               writer->data() + length_field_offset);
-  if (!length_writer.WriteVarInt62(length_to_write,
-                                   kQuicDefaultLongHeaderLengthLength)) {
-    set_detailed_error("Failed to overwrite long header length.");
-    QUIC_BUG(quic_bug_10850_15) << "Failed to overwrite long header length.";
-    return false;
-  }
-  return true;
-}
-
-size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
-                                   const QuicFrames& frames, char* buffer,
-                                   size_t packet_length,
-                                   EncryptionLevel level) {
-  QUIC_BUG_IF(quic_bug_12975_2,
-              header.version_flag && version().HasIetfInvariantHeader() &&
-                  header.long_packet_type == RETRY && !frames.empty())
-      << "IETF RETRY packets cannot contain frames " << header;
-  QuicDataWriter writer(packet_length, buffer);
-  size_t length_field_offset = 0;
-  if (!AppendPacketHeader(header, &writer, &length_field_offset)) {
-    QUIC_BUG(quic_bug_10850_16) << "AppendPacketHeader failed";
-    return 0;
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    if (AppendIetfFrames(frames, &writer) == 0) {
-      return 0;
-    }
-    if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset,
-                                   level)) {
-      return 0;
-    }
-    return writer.length();
-  }
-
-  size_t i = 0;
-  for (const QuicFrame& frame : frames) {
-    // Determine if we should write stream frame length in header.
-    const bool last_frame_in_packet = i == frames.size() - 1;
-    if (!AppendTypeByte(frame, last_frame_in_packet, &writer)) {
-      QUIC_BUG(quic_bug_10850_17) << "AppendTypeByte failed";
-      return 0;
-    }
-
-    switch (frame.type) {
-      case PADDING_FRAME:
-        if (!AppendPaddingFrame(frame.padding_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_18)
-              << "AppendPaddingFrame of "
-              << frame.padding_frame.num_padding_bytes << " failed";
-          return 0;
-        }
-        break;
-      case STREAM_FRAME:
-        if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
-                               &writer)) {
-          QUIC_BUG(quic_bug_10850_19) << "AppendStreamFrame failed";
-          return 0;
-        }
-        break;
-      case ACK_FRAME:
-        if (!AppendAckFrameAndTypeByte(*frame.ack_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_20)
-              << "AppendAckFrameAndTypeByte failed: " << detailed_error_;
-          return 0;
-        }
-        break;
-      case STOP_WAITING_FRAME:
-        if (!AppendStopWaitingFrame(header, frame.stop_waiting_frame,
-                                    &writer)) {
-          QUIC_BUG(quic_bug_10850_21) << "AppendStopWaitingFrame failed";
-          return 0;
-        }
-        break;
-      case MTU_DISCOVERY_FRAME:
-        // MTU discovery frames are serialized as ping frames.
-        ABSL_FALLTHROUGH_INTENDED;
-      case PING_FRAME:
-        // Ping has no payload.
-        break;
-      case RST_STREAM_FRAME:
-        if (!AppendRstStreamFrame(*frame.rst_stream_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_22) << "AppendRstStreamFrame failed";
-          return 0;
-        }
-        break;
-      case CONNECTION_CLOSE_FRAME:
-        if (!AppendConnectionCloseFrame(*frame.connection_close_frame,
-                                        &writer)) {
-          QUIC_BUG(quic_bug_10850_23) << "AppendConnectionCloseFrame failed";
-          return 0;
-        }
-        break;
-      case GOAWAY_FRAME:
-        if (!AppendGoAwayFrame(*frame.goaway_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_24) << "AppendGoAwayFrame failed";
-          return 0;
-        }
-        break;
-      case WINDOW_UPDATE_FRAME:
-        if (!AppendWindowUpdateFrame(frame.window_update_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_25) << "AppendWindowUpdateFrame failed";
-          return 0;
-        }
-        break;
-      case BLOCKED_FRAME:
-        if (!AppendBlockedFrame(frame.blocked_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_26) << "AppendBlockedFrame failed";
-          return 0;
-        }
-        break;
-      case NEW_CONNECTION_ID_FRAME:
-        set_detailed_error(
-            "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case RETIRE_CONNECTION_ID_FRAME:
-        set_detailed_error(
-            "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF "
-            "QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case NEW_TOKEN_FRAME:
-        set_detailed_error(
-            "Attempt to append NEW_TOKEN_ID frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case MAX_STREAMS_FRAME:
-        set_detailed_error(
-            "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case STREAMS_BLOCKED_FRAME:
-        set_detailed_error(
-            "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case PATH_RESPONSE_FRAME:
-        set_detailed_error(
-            "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case PATH_CHALLENGE_FRAME:
-        set_detailed_error(
-            "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case STOP_SENDING_FRAME:
-        set_detailed_error(
-            "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      case MESSAGE_FRAME:
-        if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
-                                           last_frame_in_packet, &writer)) {
-          QUIC_BUG(quic_bug_10850_27) << "AppendMessageFrame failed";
-          return 0;
-        }
-        break;
-      case CRYPTO_FRAME:
-        if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
-          set_detailed_error(
-              "Attempt to append CRYPTO frame in version prior to 47.");
-          return RaiseError(QUIC_INTERNAL_ERROR);
-        }
-        if (!AppendCryptoFrame(*frame.crypto_frame, &writer)) {
-          QUIC_BUG(quic_bug_10850_28) << "AppendCryptoFrame failed";
-          return 0;
-        }
-        break;
-      case HANDSHAKE_DONE_FRAME:
-        // HANDSHAKE_DONE has no payload.
-        break;
-      default:
-        RaiseError(QUIC_INVALID_FRAME_DATA);
-        QUIC_BUG(quic_bug_10850_29) << "QUIC_INVALID_FRAME_DATA";
-        return 0;
-    }
-    ++i;
-  }
-
-  if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset, level)) {
-    return 0;
-  }
-
-  return writer.length();
-}
-
-size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames,
-                                    QuicDataWriter* writer) {
-  size_t i = 0;
-  for (const QuicFrame& frame : frames) {
-    // Determine if we should write stream frame length in header.
-    const bool last_frame_in_packet = i == frames.size() - 1;
-    if (!AppendIetfFrameType(frame, last_frame_in_packet, writer)) {
-      QUIC_BUG(quic_bug_10850_30)
-          << "AppendIetfFrameType failed: " << detailed_error();
-      return 0;
-    }
-
-    switch (frame.type) {
-      case PADDING_FRAME:
-        if (!AppendPaddingFrame(frame.padding_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_31) << "AppendPaddingFrame of "
-                                      << frame.padding_frame.num_padding_bytes
-                                      << " failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case STREAM_FRAME:
-        if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
-                               writer)) {
-          QUIC_BUG(quic_bug_10850_32)
-              << "AppendStreamFrame " << frame.stream_frame
-              << " failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case ACK_FRAME:
-        if (!AppendIetfAckFrameAndTypeByte(*frame.ack_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_33)
-              << "AppendIetfAckFrameAndTypeByte failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case STOP_WAITING_FRAME:
-        set_detailed_error(
-            "Attempt to append STOP WAITING frame in IETF QUIC.");
-        RaiseError(QUIC_INTERNAL_ERROR);
-        QUIC_BUG(quic_bug_10850_34) << detailed_error();
-        return 0;
-      case MTU_DISCOVERY_FRAME:
-        // MTU discovery frames are serialized as ping frames.
-        ABSL_FALLTHROUGH_INTENDED;
-      case PING_FRAME:
-        // Ping has no payload.
-        break;
-      case RST_STREAM_FRAME:
-        if (!AppendRstStreamFrame(*frame.rst_stream_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_35)
-              << "AppendRstStreamFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case CONNECTION_CLOSE_FRAME:
-        if (!AppendIetfConnectionCloseFrame(*frame.connection_close_frame,
-                                            writer)) {
-          QUIC_BUG(quic_bug_10850_36)
-              << "AppendIetfConnectionCloseFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case GOAWAY_FRAME:
-        set_detailed_error("Attempt to append GOAWAY frame in IETF QUIC.");
-        RaiseError(QUIC_INTERNAL_ERROR);
-        QUIC_BUG(quic_bug_10850_37) << detailed_error();
-        return 0;
-      case WINDOW_UPDATE_FRAME:
-        // Depending on whether there is a stream ID or not, will be either a
-        // MAX STREAM DATA frame or a MAX DATA frame.
-        if (frame.window_update_frame.stream_id ==
-            QuicUtils::GetInvalidStreamId(transport_version())) {
-          if (!AppendMaxDataFrame(frame.window_update_frame, writer)) {
-            QUIC_BUG(quic_bug_10850_38)
-                << "AppendMaxDataFrame failed: " << detailed_error();
-            return 0;
-          }
-        } else {
-          if (!AppendMaxStreamDataFrame(frame.window_update_frame, writer)) {
-            QUIC_BUG(quic_bug_10850_39)
-                << "AppendMaxStreamDataFrame failed: " << detailed_error();
-            return 0;
-          }
-        }
-        break;
-      case BLOCKED_FRAME:
-        if (!AppendBlockedFrame(frame.blocked_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_40)
-              << "AppendBlockedFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case MAX_STREAMS_FRAME:
-        if (!AppendMaxStreamsFrame(frame.max_streams_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_41)
-              << "AppendMaxStreamsFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case STREAMS_BLOCKED_FRAME:
-        if (!AppendStreamsBlockedFrame(frame.streams_blocked_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_42)
-              << "AppendStreamsBlockedFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case NEW_CONNECTION_ID_FRAME:
-        if (!AppendNewConnectionIdFrame(*frame.new_connection_id_frame,
-                                        writer)) {
-          QUIC_BUG(quic_bug_10850_43)
-              << "AppendNewConnectionIdFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case RETIRE_CONNECTION_ID_FRAME:
-        if (!AppendRetireConnectionIdFrame(*frame.retire_connection_id_frame,
-                                           writer)) {
-          QUIC_BUG(quic_bug_10850_44)
-              << "AppendRetireConnectionIdFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case NEW_TOKEN_FRAME:
-        if (!AppendNewTokenFrame(*frame.new_token_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_45)
-              << "AppendNewTokenFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case STOP_SENDING_FRAME:
-        if (!AppendStopSendingFrame(frame.stop_sending_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_46)
-              << "AppendStopSendingFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case PATH_CHALLENGE_FRAME:
-        if (!AppendPathChallengeFrame(*frame.path_challenge_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_47)
-              << "AppendPathChallengeFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case PATH_RESPONSE_FRAME:
-        if (!AppendPathResponseFrame(*frame.path_response_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_48)
-              << "AppendPathResponseFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case MESSAGE_FRAME:
-        if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
-                                           last_frame_in_packet, writer)) {
-          QUIC_BUG(quic_bug_10850_49)
-              << "AppendMessageFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case CRYPTO_FRAME:
-        if (!AppendCryptoFrame(*frame.crypto_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_50)
-              << "AppendCryptoFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      case HANDSHAKE_DONE_FRAME:
-        // HANDSHAKE_DONE has no payload.
-        break;
-      case ACK_FREQUENCY_FRAME:
-        if (!AppendAckFrequencyFrame(*frame.ack_frequency_frame, writer)) {
-          QUIC_BUG(quic_bug_10850_51)
-              << "AppendAckFrequencyFrame failed: " << detailed_error();
-          return 0;
-        }
-        break;
-      default:
-        set_detailed_error("Tried to append unknown frame type.");
-        RaiseError(QUIC_INVALID_FRAME_DATA);
-        QUIC_BUG(quic_bug_10850_52)
-            << "QUIC_INVALID_FRAME_DATA: " << frame.type;
-        return 0;
-    }
-    ++i;
-  }
-
-  return writer->length();
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildPublicResetPacket(
-    const QuicPublicResetPacket& packet) {
-  CryptoHandshakeMessage reset;
-  reset.set_tag(kPRST);
-  reset.SetValue(kRNON, packet.nonce_proof);
-  if (packet.client_address.host().address_family() !=
-      IpAddressFamily::IP_UNSPEC) {
-    // packet.client_address is non-empty.
-    QuicSocketAddressCoder address_coder(packet.client_address);
-    std::string serialized_address = address_coder.Encode();
-    if (serialized_address.empty()) {
-      return nullptr;
-    }
-    reset.SetStringPiece(kCADR, serialized_address);
-  }
-  if (!packet.endpoint_id.empty()) {
-    reset.SetStringPiece(kEPID, packet.endpoint_id);
-  }
-  const QuicData& reset_serialized = reset.GetSerialized();
-
-  size_t len = kPublicFlagsSize + packet.connection_id.length() +
-               reset_serialized.length();
-  std::unique_ptr<char[]> buffer(new char[len]);
-  QuicDataWriter writer(len, buffer.get());
-
-  uint8_t flags = static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_RST |
-                                       PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
-  // This hack makes post-v33 public reset packet look like pre-v33 packets.
-  flags |= static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
-  if (!writer.WriteUInt8(flags)) {
-    return nullptr;
-  }
-
-  if (!writer.WriteConnectionId(packet.connection_id)) {
-    return nullptr;
-  }
-
-  if (!writer.WriteBytes(reset_serialized.data(), reset_serialized.length())) {
-    return nullptr;
-  }
-
-  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
-}
-
-// static
-size_t QuicFramer::GetMinStatelessResetPacketLength() {
-  // 5 bytes (40 bits) = 2 Fixed Bits (01) + 38 Unpredictable bits
-  return 5 + kStatelessResetTokenLength;
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildIetfStatelessResetPacket(
-    QuicConnectionId /*connection_id*/, size_t received_packet_length,
-    StatelessResetToken stateless_reset_token) {
-  QUIC_DVLOG(1) << "Building IETF stateless reset packet.";
-  if (received_packet_length <= GetMinStatelessResetPacketLength()) {
-    QUICHE_DLOG(ERROR)
-        << "Tried to build stateless reset packet with received packet "
-           "length "
-        << received_packet_length;
-    return nullptr;
-  }
-  // To ensure stateless reset is indistinguishable from a valid packet,
-  // include the max connection ID length.
-  size_t len = std::min(received_packet_length - 1,
-                        GetMinStatelessResetPacketLength() + 1 +
-                            kQuicMaxConnectionIdWithLengthPrefixLength);
-  std::unique_ptr<char[]> buffer(new char[len]);
-  QuicDataWriter writer(len, buffer.get());
-  // Append random bytes. This randomness only exists to prevent middleboxes
-  // from comparing the entire packet to a known value. Therefore it has no
-  // cryptographic use, and does not need a secure cryptographic pseudo-random
-  // number generator. It's therefore safe to use WriteInsecureRandomBytes.
-  if (!writer.WriteInsecureRandomBytes(QuicRandom::GetInstance(),
-                                       len - kStatelessResetTokenLength)) {
-    QUIC_BUG(362045737_2) << "Failed to append random bytes of length: "
-                          << len - kStatelessResetTokenLength;
-    return nullptr;
-  }
-  // Change first 2 fixed bits to 01.
-  buffer[0] &= ~FLAGS_LONG_HEADER;
-  buffer[0] |= FLAGS_FIXED_BIT;
-
-  // Append stateless reset token.
-  if (!writer.WriteBytes(&stateless_reset_token,
-                         sizeof(stateless_reset_token))) {
-    QUIC_BUG(362045737_3) << "Failed to write stateless reset token";
-    return nullptr;
-  }
-  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len,
-                                               /*owns_buffer=*/true);
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
-    QuicConnectionId server_connection_id,
-    QuicConnectionId client_connection_id, bool ietf_quic,
-    bool use_length_prefix, const ParsedQuicVersionVector& versions) {
-  QUIC_CODE_COUNT(quic_build_version_negotiation);
-  if (use_length_prefix) {
-    QUICHE_DCHECK(ietf_quic);
-    QUIC_CODE_COUNT(quic_build_version_negotiation_ietf);
-  } else if (ietf_quic) {
-    QUIC_CODE_COUNT(quic_build_version_negotiation_old_ietf);
-  } else {
-    QUIC_CODE_COUNT(quic_build_version_negotiation_old_gquic);
-  }
-  ParsedQuicVersionVector wire_versions = versions;
-  // Add a version reserved for negotiation as suggested by the
-  // "Using Reserved Versions" section of draft-ietf-quic-transport.
-  if (wire_versions.empty()) {
-    // Ensure that version negotiation packets we send have at least two
-    // versions. This guarantees that, under all circumstances, all QUIC
-    // packets we send are at least 14 bytes long.
-    wire_versions = {QuicVersionReservedForNegotiation(),
-                     QuicVersionReservedForNegotiation()};
-  } else {
-    // This is not uniformely distributed but is acceptable since no security
-    // depends on this randomness.
-    size_t version_index = 0;
-    const bool disable_randomness =
-        GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness);
-    if (!disable_randomness) {
-      version_index =
-          QuicRandom::GetInstance()->RandUint64() % (wire_versions.size() + 1);
-    }
-    wire_versions.insert(wire_versions.begin() + version_index,
-                         QuicVersionReservedForNegotiation());
-  }
-  if (ietf_quic) {
-    return BuildIetfVersionNegotiationPacket(
-        use_length_prefix, server_connection_id, client_connection_id,
-        wire_versions);
-  }
-
-  // The GQUIC encoding does not support encoding client connection IDs.
-  QUICHE_DCHECK(client_connection_id.IsEmpty());
-  // The GQUIC encoding does not support length-prefixed connection IDs.
-  QUICHE_DCHECK(!use_length_prefix);
-
-  QUICHE_DCHECK(!wire_versions.empty());
-  size_t len = kPublicFlagsSize + server_connection_id.length() +
-               wire_versions.size() * kQuicVersionSize;
-  std::unique_ptr<char[]> buffer(new char[len]);
-  QuicDataWriter writer(len, buffer.get());
-
-  uint8_t flags = static_cast<uint8_t>(
-      PACKET_PUBLIC_FLAGS_VERSION | PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID |
-      PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
-  if (!writer.WriteUInt8(flags)) {
-    return nullptr;
-  }
-
-  if (!writer.WriteConnectionId(server_connection_id)) {
-    return nullptr;
-  }
-
-  for (const ParsedQuicVersion& version : wire_versions) {
-    if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
-      return nullptr;
-    }
-  }
-
-  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
-}
-
-// static
-std::unique_ptr<QuicEncryptedPacket>
-QuicFramer::BuildIetfVersionNegotiationPacket(
-    bool use_length_prefix, QuicConnectionId server_connection_id,
-    QuicConnectionId client_connection_id,
-    const ParsedQuicVersionVector& versions) {
-  QUIC_DVLOG(1) << "Building IETF version negotiation packet with"
-                << (use_length_prefix ? "" : "out")
-                << " length prefix, server_connection_id "
-                << server_connection_id << " client_connection_id "
-                << client_connection_id << " versions "
-                << ParsedQuicVersionVectorToString(versions);
-  QUICHE_DCHECK(!versions.empty());
-  size_t len = kPacketHeaderTypeSize + kConnectionIdLengthSize +
-               client_connection_id.length() + server_connection_id.length() +
-               (versions.size() + 1) * kQuicVersionSize;
-  if (use_length_prefix) {
-    // When using length-prefixed connection IDs, packets carry two lengths
-    // instead of one.
-    len += kConnectionIdLengthSize;
-  }
-  std::unique_ptr<char[]> buffer(new char[len]);
-  QuicDataWriter writer(len, buffer.get());
-
-  // TODO(fayang): Randomly select a value for the type.
-  uint8_t type = static_cast<uint8_t>(FLAGS_LONG_HEADER | FLAGS_FIXED_BIT);
-  if (!writer.WriteUInt8(type)) {
-    return nullptr;
-  }
-
-  if (!writer.WriteUInt32(0)) {
-    return nullptr;
-  }
-
-  if (!AppendIetfConnectionIds(true, use_length_prefix, client_connection_id,
-                               server_connection_id, &writer)) {
-    return nullptr;
-  }
-
-  for (const ParsedQuicVersion& version : versions) {
-    if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
-      return nullptr;
-    }
-  }
-
-  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
-}
-
-bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
-  QUICHE_DCHECK(!is_processing_packet_) << ENDPOINT << "Nested ProcessPacket";
-  is_processing_packet_ = true;
-  bool result = ProcessPacketInternal(packet);
-  is_processing_packet_ = false;
-  return result;
-}
-
-bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) {
-  QuicDataReader reader(packet.data(), packet.length());
-
-  bool packet_has_ietf_packet_header = false;
-  if (infer_packet_header_type_from_version_) {
-    packet_has_ietf_packet_header = version_.HasIetfInvariantHeader();
-  } else if (!reader.IsDoneReading()) {
-    uint8_t type = reader.PeekByte();
-    packet_has_ietf_packet_header = QuicUtils::IsIetfPacketHeader(type);
-  }
-  if (packet_has_ietf_packet_header) {
-    QUIC_DVLOG(1) << ENDPOINT << "Processing IETF QUIC packet.";
-  }
-
-  visitor_->OnPacket();
-
-  QuicPacketHeader header;
-  if (!ProcessPublicHeader(&reader, packet_has_ietf_packet_header, &header)) {
-    QUICHE_DCHECK_NE("", detailed_error_);
-    QUIC_DVLOG(1) << ENDPOINT << "Unable to process public header. Error: "
-                  << detailed_error_;
-    QUICHE_DCHECK_NE("", detailed_error_);
-    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_HEADER);
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-
-  if (!visitor_->OnUnauthenticatedPublicHeader(header)) {
-    // The visitor suppresses further processing of the packet.
-    return true;
-  }
-
-  if (IsVersionNegotiation(header, packet_has_ietf_packet_header)) {
-    if (perspective_ == Perspective::IS_CLIENT) {
-      QUIC_DVLOG(1) << "Client received version negotiation packet";
-      return ProcessVersionNegotiationPacket(&reader, header);
-    } else {
-      QUIC_DLOG(ERROR) << "Server received version negotiation packet";
-      set_detailed_error("Server received version negotiation packet.");
-      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-    }
-  }
-
-  if (header.version_flag && header.version != version_) {
-    if (perspective_ == Perspective::IS_SERVER) {
-      if (!visitor_->OnProtocolVersionMismatch(header.version)) {
-        RecordDroppedPacketReason(DroppedPacketReason::VERSION_MISMATCH);
-        return true;
-      }
-    } else {
-      // A client received a packet of a different version but that packet is
-      // not a version negotiation packet. It is therefore invalid and dropped.
-      QUIC_DLOG(ERROR) << "Client received unexpected version "
-                       << ParsedQuicVersionToString(header.version)
-                       << " instead of " << ParsedQuicVersionToString(version_);
-      set_detailed_error("Client received unexpected version.");
-      return RaiseError(QUIC_PACKET_WRONG_VERSION);
-    }
-  }
-
-  bool rv;
-  if (header.long_packet_type == RETRY) {
-    rv = ProcessRetryPacket(&reader, header);
-  } else if (header.reset_flag) {
-    rv = ProcessPublicResetPacket(&reader, header);
-  } else if (packet.length() <= kMaxIncomingPacketSize) {
-    // The optimized decryption algorithm implementations run faster when
-    // operating on aligned memory.
-    ABSL_CACHELINE_ALIGNED char buffer[kMaxIncomingPacketSize];
-    if (packet_has_ietf_packet_header) {
-      rv = ProcessIetfDataPacket(&reader, &header, packet, buffer,
-                                 ABSL_ARRAYSIZE(buffer));
-    } else {
-      rv = ProcessDataPacket(&reader, &header, packet, buffer,
-                             ABSL_ARRAYSIZE(buffer));
-    }
-  } else {
-    std::unique_ptr<char[]> large_buffer(new char[packet.length()]);
-    if (packet_has_ietf_packet_header) {
-      rv = ProcessIetfDataPacket(&reader, &header, packet, large_buffer.get(),
-                                 packet.length());
-    } else {
-      rv = ProcessDataPacket(&reader, &header, packet, large_buffer.get(),
-                             packet.length());
-    }
-    QUIC_BUG_IF(quic_bug_10850_53, rv)
-        << "QUIC should never successfully process packets larger"
-        << "than kMaxIncomingPacketSize. packet size:" << packet.length();
-  }
-  return rv;
-}
-
-bool QuicFramer::ProcessVersionNegotiationPacket(
-    QuicDataReader* reader, const QuicPacketHeader& header) {
-  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-
-  QuicVersionNegotiationPacket packet(
-      GetServerConnectionIdAsRecipient(header, perspective_));
-  // Try reading at least once to raise error if the packet is invalid.
-  do {
-    QuicVersionLabel version_label;
-    if (!ProcessVersionLabel(reader, &version_label)) {
-      set_detailed_error("Unable to read supported version in negotiation.");
-      RecordDroppedPacketReason(
-          DroppedPacketReason::INVALID_VERSION_NEGOTIATION_PACKET);
-      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-    }
-    ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
-    if (parsed_version != UnsupportedQuicVersion()) {
-      packet.versions.push_back(parsed_version);
-    }
-  } while (!reader->IsDoneReading());
-
-  QUIC_DLOG(INFO) << ENDPOINT << "parsed version negotiation: "
-                  << ParsedQuicVersionVectorToString(packet.versions);
-
-  visitor_->OnVersionNegotiationPacket(packet);
-  return true;
-}
-
-bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader,
-                                    const QuicPacketHeader& header) {
-  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-  if (drop_incoming_retry_packets_) {
-    QUIC_DLOG(INFO) << "Ignoring received RETRY packet";
-    return true;
-  }
-
-  if (version_.UsesTls()) {
-    QUICHE_DCHECK(version_.HasLengthPrefixedConnectionIds()) << version_;
-    const size_t bytes_remaining = reader->BytesRemaining();
-    if (bytes_remaining <= kRetryIntegrityTagLength) {
-      set_detailed_error("Retry packet too short to parse integrity tag.");
-      return false;
-    }
-    const size_t retry_token_length =
-        bytes_remaining - kRetryIntegrityTagLength;
-    QUICHE_DCHECK_GT(retry_token_length, 0u);
-    absl::string_view retry_token;
-    if (!reader->ReadStringPiece(&retry_token, retry_token_length)) {
-      set_detailed_error("Failed to read retry token.");
-      return false;
-    }
-    absl::string_view retry_without_tag = reader->PreviouslyReadPayload();
-    absl::string_view integrity_tag = reader->ReadRemainingPayload();
-    QUICHE_DCHECK_EQ(integrity_tag.length(), kRetryIntegrityTagLength);
-    visitor_->OnRetryPacket(EmptyQuicConnectionId(),
-                            header.source_connection_id, retry_token,
-                            integrity_tag, retry_without_tag);
-    return true;
-  }
-
-  QuicConnectionId original_destination_connection_id;
-  if (version_.HasLengthPrefixedConnectionIds()) {
-    // Parse Original Destination Connection ID.
-    if (!reader->ReadLengthPrefixedConnectionId(
-            &original_destination_connection_id)) {
-      set_detailed_error("Unable to read Original Destination ConnectionId.");
-      return false;
-    }
-  } else {
-    // Parse Original Destination Connection ID Length.
-    uint8_t odcil = header.type_byte & 0xf;
-    if (odcil != 0) {
-      odcil += kConnectionIdLengthAdjustment;
-    }
-
-    // Parse Original Destination Connection ID.
-    if (!reader->ReadConnectionId(&original_destination_connection_id, odcil)) {
-      set_detailed_error("Unable to read Original Destination ConnectionId.");
-      return false;
-    }
-  }
-
-  if (!QuicUtils::IsConnectionIdValidForVersion(
-          original_destination_connection_id, transport_version())) {
-    set_detailed_error(
-        "Received Original Destination ConnectionId with invalid length.");
-    return false;
-  }
-
-  absl::string_view retry_token = reader->ReadRemainingPayload();
-  visitor_->OnRetryPacket(original_destination_connection_id,
-                          header.source_connection_id, retry_token,
-                          /*retry_integrity_tag=*/absl::string_view(),
-                          /*retry_without_tag=*/absl::string_view());
-  return true;
-}
-
-// Seeks the current packet to check for a coalesced packet at the end.
-// If the IETF length field only spans part of the outer packet,
-// then there is a coalesced packet after this one.
-void QuicFramer::MaybeProcessCoalescedPacket(
-    const QuicDataReader& encrypted_reader, uint64_t remaining_bytes_length,
-    const QuicPacketHeader& header) {
-  if (header.remaining_packet_length >= remaining_bytes_length) {
-    // There is no coalesced packet.
-    return;
-  }
-
-  absl::string_view remaining_data = encrypted_reader.PeekRemainingPayload();
-  QUICHE_DCHECK_EQ(remaining_data.length(), remaining_bytes_length);
-
-  const char* coalesced_data =
-      remaining_data.data() + header.remaining_packet_length;
-  uint64_t coalesced_data_length =
-      remaining_bytes_length - header.remaining_packet_length;
-  QuicDataReader coalesced_reader(coalesced_data, coalesced_data_length);
-
-  QuicPacketHeader coalesced_header;
-  if (!ProcessIetfPacketHeader(&coalesced_reader, &coalesced_header)) {
-    // Some implementations pad their INITIAL packets by sending random invalid
-    // data after the INITIAL, and that is allowed by the specification. If we
-    // fail to parse a subsequent coalesced packet, simply ignore it.
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Failed to parse received coalesced header of length "
-                    << coalesced_data_length
-                    << " with error: " << detailed_error_ << ": "
-                    << absl::BytesToHexString(absl::string_view(
-                           coalesced_data, coalesced_data_length))
-                    << " previous header was " << header;
-    return;
-  }
-
-  if (coalesced_header.destination_connection_id !=
-      header.destination_connection_id) {
-    // Drop coalesced packets with mismatched connection IDs.
-    QUIC_DLOG(INFO) << ENDPOINT << "Received mismatched coalesced header "
-                    << coalesced_header << " previous header was " << header;
-    QUIC_CODE_COUNT(
-        quic_received_coalesced_packets_with_mismatched_connection_id);
-    return;
-  }
-
-  QuicEncryptedPacket coalesced_packet(coalesced_data, coalesced_data_length,
-                                       /*owns_buffer=*/false);
-  visitor_->OnCoalescedPacket(coalesced_packet);
-}
-
-bool QuicFramer::MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
-                                        QuicPacketHeader* header) {
-  if (!QuicVersionHasLongHeaderLengths(header->version.transport_version) ||
-      header->form != IETF_QUIC_LONG_HEADER_PACKET ||
-      (header->long_packet_type != INITIAL &&
-       header->long_packet_type != HANDSHAKE &&
-       header->long_packet_type != ZERO_RTT_PROTECTED)) {
-    return true;
-  }
-  header->length_length = encrypted_reader->PeekVarInt62Length();
-  if (!encrypted_reader->ReadVarInt62(&header->remaining_packet_length)) {
-    set_detailed_error("Unable to read long header payload length.");
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-  uint64_t remaining_bytes_length = encrypted_reader->BytesRemaining();
-  if (header->remaining_packet_length > remaining_bytes_length) {
-    set_detailed_error("Long header payload length longer than packet.");
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-
-  MaybeProcessCoalescedPacket(*encrypted_reader, remaining_bytes_length,
-                              *header);
-
-  if (!encrypted_reader->TruncateRemaining(header->remaining_packet_length)) {
-    set_detailed_error("Length TruncateRemaining failed.");
-    QUIC_BUG(quic_bug_10850_54) << "Length TruncateRemaining failed.";
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
-                                       QuicPacketHeader* header,
-                                       const QuicEncryptedPacket& packet,
-                                       char* decrypted_buffer,
-                                       size_t buffer_length) {
-  QUICHE_DCHECK_NE(GOOGLE_QUIC_PACKET, header->form);
-  QUICHE_DCHECK(!header->has_possible_stateless_reset_token);
-  header->length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  header->remaining_packet_length = 0;
-  if (header->form == IETF_QUIC_SHORT_HEADER_PACKET &&
-      perspective_ == Perspective::IS_CLIENT) {
-    // Peek possible stateless reset token. Will only be used on decryption
-    // failure.
-    absl::string_view remaining = encrypted_reader->PeekRemainingPayload();
-    if (remaining.length() >= sizeof(header->possible_stateless_reset_token)) {
-      header->has_possible_stateless_reset_token = true;
-      memcpy(&header->possible_stateless_reset_token,
-             &remaining.data()[remaining.length() -
-                               sizeof(header->possible_stateless_reset_token)],
-             sizeof(header->possible_stateless_reset_token));
-    }
-  }
-
-  if (!MaybeProcessIetfLength(encrypted_reader, header)) {
-    return false;
-  }
-
-  absl::string_view associated_data;
-  std::vector<char> ad_storage;
-  QuicPacketNumber base_packet_number;
-  if (header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
-      header->long_packet_type != VERSION_NEGOTIATION) {
-    QUICHE_DCHECK(header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
-                  header->long_packet_type == INITIAL ||
-                  header->long_packet_type == HANDSHAKE ||
-                  header->long_packet_type == ZERO_RTT_PROTECTED);
-    // Process packet number.
-    if (supports_multiple_packet_number_spaces_) {
-      PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
-      if (pn_space == NUM_PACKET_NUMBER_SPACES) {
-        return RaiseError(QUIC_INVALID_PACKET_HEADER);
-      }
-      base_packet_number = largest_decrypted_packet_numbers_[pn_space];
-    } else {
-      base_packet_number = largest_packet_number_;
-    }
-    uint64_t full_packet_number;
-    bool hp_removal_failed = false;
-    if (version_.HasHeaderProtection()) {
-      if (!RemoveHeaderProtection(encrypted_reader, packet, header,
-                                  &full_packet_number, &ad_storage)) {
-        hp_removal_failed = true;
-      }
-      associated_data = absl::string_view(ad_storage.data(), ad_storage.size());
-    } else if (!ProcessAndCalculatePacketNumber(
-                   encrypted_reader, header->packet_number_length,
-                   base_packet_number, &full_packet_number)) {
-      set_detailed_error("Unable to read packet number.");
-      RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
-      return RaiseError(QUIC_INVALID_PACKET_HEADER);
-    }
-
-    if (hp_removal_failed ||
-        !IsValidFullPacketNumber(full_packet_number, version())) {
-      if (IsIetfStatelessResetPacket(*header)) {
-        // This is a stateless reset packet.
-        QuicIetfStatelessResetPacket packet(
-            *header, header->possible_stateless_reset_token);
-        visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
-        return true;
-      }
-      if (hp_removal_failed) {
-        const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
-        const bool has_decryption_key = decrypter_[decryption_level] != nullptr;
-        visitor_->OnUndecryptablePacket(
-            QuicEncryptedPacket(encrypted_reader->FullPayload()),
-            decryption_level, has_decryption_key);
-        RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
-        set_detailed_error(absl::StrCat(
-            "Unable to decrypt ", EncryptionLevelToString(decryption_level),
-            " header protection", has_decryption_key ? "" : " (missing key)",
-            "."));
-        return RaiseError(QUIC_DECRYPTION_FAILURE);
-      }
-      RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
-      set_detailed_error("packet numbers cannot be 0.");
-      return RaiseError(QUIC_INVALID_PACKET_HEADER);
-    }
-    header->packet_number = QuicPacketNumber(full_packet_number);
-  }
-
-  // A nonce should only present in SHLO from the server to the client when
-  // using QUIC crypto.
-  if (header->form == IETF_QUIC_LONG_HEADER_PACKET &&
-      header->long_packet_type == ZERO_RTT_PROTECTED &&
-      perspective_ == Perspective::IS_CLIENT &&
-      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-    if (!encrypted_reader->ReadBytes(
-            reinterpret_cast<uint8_t*>(last_nonce_.data()),
-            last_nonce_.size())) {
-      set_detailed_error("Unable to read nonce.");
-      RecordDroppedPacketReason(
-          DroppedPacketReason::INVALID_DIVERSIFICATION_NONCE);
-      return RaiseError(QUIC_INVALID_PACKET_HEADER);
-    }
-
-    header->nonce = &last_nonce_;
-  } else {
-    header->nonce = nullptr;
-  }
-
-  if (!visitor_->OnUnauthenticatedHeader(*header)) {
-    set_detailed_error(
-        "Visitor asked to stop processing of unauthenticated header.");
-    return false;
-  }
-
-  absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
-  if (!version_.HasHeaderProtection()) {
-    associated_data = GetAssociatedDataFromEncryptedPacket(
-        version_.transport_version, packet,
-        GetIncludedDestinationConnectionIdLength(*header),
-        GetIncludedSourceConnectionIdLength(*header), header->version_flag,
-        header->nonce != nullptr, header->packet_number_length,
-        header->retry_token_length_length, header->retry_token.length(),
-        header->length_length);
-  }
-
-  size_t decrypted_length = 0;
-  EncryptionLevel decrypted_level;
-  if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
-                      decrypted_buffer, buffer_length, &decrypted_length,
-                      &decrypted_level)) {
-    if (IsIetfStatelessResetPacket(*header)) {
-      // This is a stateless reset packet.
-      QuicIetfStatelessResetPacket packet(
-          *header, header->possible_stateless_reset_token);
-      visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
-      return true;
-    }
-    const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
-    const bool has_decryption_key = version_.KnowsWhichDecrypterToUse() &&
-                                    decrypter_[decryption_level] != nullptr;
-    visitor_->OnUndecryptablePacket(
-        QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
-        has_decryption_key);
-    set_detailed_error(absl::StrCat(
-        "Unable to decrypt ", EncryptionLevelToString(decryption_level),
-        " payload with reconstructed packet number ",
-        header->packet_number.ToString(), " (largest decrypted was ",
-        base_packet_number.ToString(), ")",
-        has_decryption_key || !version_.KnowsWhichDecrypterToUse()
-            ? ""
-            : " (missing key)",
-        "."));
-    RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
-    return RaiseError(QUIC_DECRYPTION_FAILURE);
-  }
-  QuicDataReader reader(decrypted_buffer, decrypted_length);
-
-  // Update the largest packet number after we have decrypted the packet
-  // so we are confident is not attacker controlled.
-  if (supports_multiple_packet_number_spaces_) {
-    largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
-                                          decrypted_level)]
-        .UpdateMax(header->packet_number);
-  } else {
-    largest_packet_number_.UpdateMax(header->packet_number);
-  }
-
-  if (!visitor_->OnPacketHeader(*header)) {
-    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
-    // The visitor suppresses further processing of the packet.
-    return true;
-  }
-
-  if (packet.length() > kMaxIncomingPacketSize) {
-    set_detailed_error("Packet too large.");
-    return RaiseError(QUIC_PACKET_TOO_LARGE);
-  }
-
-  // Handle the payload.
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    current_received_frame_type_ = 0;
-    previously_received_frame_type_ = 0;
-    if (!ProcessIetfFrameData(&reader, *header, decrypted_level)) {
-      current_received_frame_type_ = 0;
-      previously_received_frame_type_ = 0;
-      QUICHE_DCHECK_NE(QUIC_NO_ERROR,
-                       error_);  // ProcessIetfFrameData sets the error.
-      QUICHE_DCHECK_NE("", detailed_error_);
-      QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
-                         << detailed_error_;
-      return false;
-    }
-    current_received_frame_type_ = 0;
-    previously_received_frame_type_ = 0;
-  } else {
-    if (!ProcessFrameData(&reader, *header)) {
-      QUICHE_DCHECK_NE(QUIC_NO_ERROR,
-                       error_);  // ProcessFrameData sets the error.
-      QUICHE_DCHECK_NE("", detailed_error_);
-      QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
-                         << detailed_error_;
-      return false;
-    }
-  }
-
-  visitor_->OnPacketComplete();
-  return true;
-}
-
-bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
-                                   QuicPacketHeader* header,
-                                   const QuicEncryptedPacket& packet,
-                                   char* decrypted_buffer,
-                                   size_t buffer_length) {
-  if (!ProcessUnauthenticatedHeader(encrypted_reader, header)) {
-    QUICHE_DCHECK_NE("", detailed_error_);
-    QUIC_DVLOG(1)
-        << ENDPOINT
-        << "Unable to process packet header. Stopping parsing. Error: "
-        << detailed_error_;
-    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
-    return false;
-  }
-
-  absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
-  absl::string_view associated_data = GetAssociatedDataFromEncryptedPacket(
-      version_.transport_version, packet,
-      GetIncludedDestinationConnectionIdLength(*header),
-      GetIncludedSourceConnectionIdLength(*header), header->version_flag,
-      header->nonce != nullptr, header->packet_number_length,
-      header->retry_token_length_length, header->retry_token.length(),
-      header->length_length);
-
-  size_t decrypted_length = 0;
-  EncryptionLevel decrypted_level;
-  if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
-                      decrypted_buffer, buffer_length, &decrypted_length,
-                      &decrypted_level)) {
-    const EncryptionLevel decryption_level = decrypter_level_;
-    // This version uses trial decryption so we always report to our visitor
-    // that we are not certain we have the correct decryption key.
-    const bool has_decryption_key = false;
-    visitor_->OnUndecryptablePacket(
-        QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
-        has_decryption_key);
-    RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
-    set_detailed_error(absl::StrCat("Unable to decrypt ",
-                                    EncryptionLevelToString(decryption_level),
-                                    " payload."));
-    return RaiseError(QUIC_DECRYPTION_FAILURE);
-  }
-
-  QuicDataReader reader(decrypted_buffer, decrypted_length);
-
-  // Update the largest packet number after we have decrypted the packet
-  // so we are confident is not attacker controlled.
-  if (supports_multiple_packet_number_spaces_) {
-    largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
-                                          decrypted_level)]
-        .UpdateMax(header->packet_number);
-  } else {
-    largest_packet_number_.UpdateMax(header->packet_number);
-  }
-
-  if (!visitor_->OnPacketHeader(*header)) {
-    // The visitor suppresses further processing of the packet.
-    return true;
-  }
-
-  if (packet.length() > kMaxIncomingPacketSize) {
-    set_detailed_error("Packet too large.");
-    return RaiseError(QUIC_PACKET_TOO_LARGE);
-  }
-
-  // Handle the payload.
-  if (!ProcessFrameData(&reader, *header)) {
-    QUICHE_DCHECK_NE(QUIC_NO_ERROR,
-                     error_);  // ProcessFrameData sets the error.
-    QUICHE_DCHECK_NE("", detailed_error_);
-    QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
-                       << detailed_error_;
-    return false;
-  }
-
-  visitor_->OnPacketComplete();
-  return true;
-}
-
-bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader,
-                                          const QuicPacketHeader& header) {
-  QuicPublicResetPacket packet(
-      GetServerConnectionIdAsRecipient(header, perspective_));
-
-  std::unique_ptr<CryptoHandshakeMessage> reset(
-      CryptoFramer::ParseMessage(reader->ReadRemainingPayload()));
-  if (!reset) {
-    set_detailed_error("Unable to read reset message.");
-    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
-    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
-  }
-  if (reset->tag() != kPRST) {
-    set_detailed_error("Incorrect message tag.");
-    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
-    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
-  }
-
-  if (reset->GetUint64(kRNON, &packet.nonce_proof) != QUIC_NO_ERROR) {
-    set_detailed_error("Unable to read nonce proof.");
-    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
-    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
-  }
-  // TODO(satyamshekhar): validate nonce to protect against DoS.
-
-  absl::string_view address;
-  if (reset->GetStringPiece(kCADR, &address)) {
-    QuicSocketAddressCoder address_coder;
-    if (address_coder.Decode(address.data(), address.length())) {
-      packet.client_address =
-          QuicSocketAddress(address_coder.ip(), address_coder.port());
-    }
-  }
-
-  absl::string_view endpoint_id;
-  if (perspective_ == Perspective::IS_CLIENT &&
-      reset->GetStringPiece(kEPID, &endpoint_id)) {
-    packet.endpoint_id = std::string(endpoint_id);
-    packet.endpoint_id += '\0';
-  }
-
-  visitor_->OnPublicResetPacket(packet);
-  return true;
-}
-
-bool QuicFramer::IsIetfStatelessResetPacket(
-    const QuicPacketHeader& header) const {
-  QUIC_BUG_IF(quic_bug_12975_3, header.has_possible_stateless_reset_token &&
-                                    perspective_ != Perspective::IS_CLIENT)
-      << "has_possible_stateless_reset_token can only be true at client side.";
-  return header.form == IETF_QUIC_SHORT_HEADER_PACKET &&
-         header.has_possible_stateless_reset_token &&
-         visitor_->IsValidStatelessResetToken(
-             header.possible_stateless_reset_token);
-}
-
-bool QuicFramer::HasEncrypterOfEncryptionLevel(EncryptionLevel level) const {
-  return encrypter_[level] != nullptr;
-}
-
-bool QuicFramer::HasDecrypterOfEncryptionLevel(EncryptionLevel level) const {
-  return decrypter_[level] != nullptr;
-}
-
-bool QuicFramer::HasAnEncrypterForSpace(PacketNumberSpace space) const {
-  switch (space) {
-    case INITIAL_DATA:
-      return HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL);
-    case HANDSHAKE_DATA:
-      return HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE);
-    case APPLICATION_DATA:
-      return HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT) ||
-             HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    case NUM_PACKET_NUMBER_SPACES:
-      break;
-  }
-  QUIC_BUG(quic_bug_10850_55)
-      << ENDPOINT
-      << "Try to send data of space: " << PacketNumberSpaceToString(space);
-  return false;
-}
-
-EncryptionLevel QuicFramer::GetEncryptionLevelToSendApplicationData() const {
-  if (!HasAnEncrypterForSpace(APPLICATION_DATA)) {
-    QUIC_BUG(quic_bug_12975_4)
-        << "Tried to get encryption level to send application data with no "
-           "encrypter available.";
-    return NUM_ENCRYPTION_LEVELS;
-  }
-  if (HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
-    return ENCRYPTION_FORWARD_SECURE;
-  }
-  QUICHE_DCHECK(HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT));
-  return ENCRYPTION_ZERO_RTT;
-}
-
-bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
-                                    QuicDataWriter* writer,
-                                    size_t* length_field_offset) {
-  if (version().HasIetfInvariantHeader()) {
-    return AppendIetfPacketHeader(header, writer, length_field_offset);
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Appending header: " << header;
-  uint8_t public_flags = 0;
-  if (header.reset_flag) {
-    public_flags |= PACKET_PUBLIC_FLAGS_RST;
-  }
-  if (header.version_flag) {
-    public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
-  }
-
-  public_flags |= GetPacketNumberFlags(header.packet_number_length)
-                  << kPublicHeaderSequenceNumberShift;
-
-  if (header.nonce != nullptr) {
-    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
-    public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
-  }
-
-  QuicConnectionId server_connection_id =
-      GetServerConnectionIdAsSender(header, perspective_);
-  QuicConnectionIdIncluded server_connection_id_included =
-      GetServerConnectionIdIncludedAsSender(header, perspective_);
-  QUICHE_DCHECK_EQ(CONNECTION_ID_ABSENT,
-                   GetClientConnectionIdIncludedAsSender(header, perspective_))
-      << ENDPOINT << ParsedQuicVersionToString(version_)
-      << " invalid header: " << header;
-
-  switch (server_connection_id_included) {
-    case CONNECTION_ID_ABSENT:
-      if (!writer->WriteUInt8(public_flags |
-                              PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
-        return false;
-      }
-      break;
-    case CONNECTION_ID_PRESENT:
-      QUIC_BUG_IF(quic_bug_12975_5,
-                  !QuicUtils::IsConnectionIdValidForVersion(
-                      server_connection_id, transport_version()))
-          << "AppendPacketHeader: attempted to use connection ID "
-          << server_connection_id << " which is invalid with version "
-          << version();
-
-      public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
-      if (perspective_ == Perspective::IS_CLIENT) {
-        public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
-      }
-      if (!writer->WriteUInt8(public_flags) ||
-          !writer->WriteConnectionId(server_connection_id)) {
-        return false;
-      }
-      break;
-  }
-  last_serialized_server_connection_id_ = server_connection_id;
-
-  if (header.version_flag) {
-    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
-    QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
-    if (!writer->WriteUInt32(version_label)) {
-      return false;
-    }
-
-    QUIC_DVLOG(1) << ENDPOINT << "label = '"
-                  << QuicVersionLabelToString(version_label) << "'";
-  }
-
-  if (header.nonce != nullptr &&
-      !writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
-    return false;
-  }
-
-  if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
-                          writer)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicFramer::AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
-                                          QuicDataWriter* writer) {
-  uint8_t type = 0;
-  if (header.version_flag) {
-    type = static_cast<uint8_t>(
-        FLAGS_LONG_HEADER | FLAGS_FIXED_BIT |
-        LongHeaderTypeToOnWireValue(header.long_packet_type, version_) |
-        PacketNumberLengthToOnWireValue(header.packet_number_length));
-  } else {
-    type = static_cast<uint8_t>(
-        FLAGS_FIXED_BIT | (current_key_phase_bit_ ? FLAGS_KEY_PHASE_BIT : 0) |
-        PacketNumberLengthToOnWireValue(header.packet_number_length));
-  }
-  return writer->WriteUInt8(type);
-}
-
-bool QuicFramer::AppendIetfPacketHeader(const QuicPacketHeader& header,
-                                        QuicDataWriter* writer,
-                                        size_t* length_field_offset) {
-  QUIC_DVLOG(1) << ENDPOINT << "Appending IETF header: " << header;
-  QuicConnectionId server_connection_id =
-      GetServerConnectionIdAsSender(header, perspective_);
-  QUIC_BUG_IF(quic_bug_12975_6, !QuicUtils::IsConnectionIdValidForVersion(
-                                    server_connection_id, transport_version()))
-      << "AppendIetfPacketHeader: attempted to use connection ID "
-      << server_connection_id << " which is invalid with version " << version();
-  if (!AppendIetfHeaderTypeByte(header, writer)) {
-    return false;
-  }
-
-  if (header.version_flag) {
-    QUICHE_DCHECK_NE(VERSION_NEGOTIATION, header.long_packet_type)
-        << "QuicFramer::AppendIetfPacketHeader does not support sending "
-           "version negotiation packets, use "
-           "QuicFramer::BuildVersionNegotiationPacket instead "
-        << header;
-    // Append version for long header.
-    QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
-    if (!writer->WriteUInt32(version_label)) {
-      return false;
-    }
-  }
-
-  // Append connection ID.
-  if (!AppendIetfConnectionIds(
-          header.version_flag, version_.HasLengthPrefixedConnectionIds(),
-          header.destination_connection_id_included != CONNECTION_ID_ABSENT
-              ? header.destination_connection_id
-              : EmptyQuicConnectionId(),
-          header.source_connection_id_included != CONNECTION_ID_ABSENT
-              ? header.source_connection_id
-              : EmptyQuicConnectionId(),
-          writer)) {
-    return false;
-  }
-
-  last_serialized_server_connection_id_ = server_connection_id;
-  if (version_.SupportsClientConnectionIds()) {
-    last_serialized_client_connection_id_ =
-        GetClientConnectionIdAsSender(header, perspective_);
-  }
-
-  // TODO(b/141924462) Remove this QUIC_BUG once we do support sending RETRY.
-  QUIC_BUG_IF(quic_bug_12975_7,
-              header.version_flag && header.long_packet_type == RETRY)
-      << "Sending IETF RETRY packets is not currently supported " << header;
-
-  if (QuicVersionHasLongHeaderLengths(transport_version()) &&
-      header.version_flag) {
-    if (header.long_packet_type == INITIAL) {
-      QUICHE_DCHECK_NE(VARIABLE_LENGTH_INTEGER_LENGTH_0,
-                       header.retry_token_length_length)
-          << ENDPOINT << ParsedQuicVersionToString(version_)
-          << " bad retry token length length in header: " << header;
-      // Write retry token length.
-      if (!writer->WriteVarInt62(header.retry_token.length(),
-                                 header.retry_token_length_length)) {
-        return false;
-      }
-      // Write retry token.
-      if (!header.retry_token.empty() &&
-          !writer->WriteStringPiece(header.retry_token)) {
-        return false;
-      }
-    }
-    if (length_field_offset != nullptr) {
-      *length_field_offset = writer->length();
-    }
-    // Add fake length to reserve two bytes to add length in later.
-    writer->WriteVarInt62(256);
-  } else if (length_field_offset != nullptr) {
-    *length_field_offset = 0;
-  }
-
-  // Append packet number.
-  if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
-                          writer)) {
-    return false;
-  }
-  last_written_packet_number_length_ = header.packet_number_length;
-
-  if (!header.version_flag) {
-    return true;
-  }
-
-  if (header.nonce != nullptr) {
-    QUICHE_DCHECK(header.version_flag);
-    QUICHE_DCHECK_EQ(ZERO_RTT_PROTECTED, header.long_packet_type);
-    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
-    if (!writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
-    uint32_t time_delta_us) {
-  // The new time_delta might have wrapped to the next epoch, or it
-  // might have reverse wrapped to the previous epoch, or it might
-  // remain in the same epoch. Select the time closest to the previous
-  // time.
-  //
-  // epoch_delta is the delta between epochs. A delta is 4 bytes of
-  // microseconds.
-  const uint64_t epoch_delta = UINT64_C(1) << 32;
-  uint64_t epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1);
-  // Wrapping is safe here because a wrapped value will not be ClosestTo below.
-  uint64_t prev_epoch = epoch - epoch_delta;
-  uint64_t next_epoch = epoch + epoch_delta;
-
-  uint64_t time = ClosestTo(
-      last_timestamp_.ToMicroseconds(), epoch + time_delta_us,
-      ClosestTo(last_timestamp_.ToMicroseconds(), prev_epoch + time_delta_us,
-                next_epoch + time_delta_us));
-
-  return QuicTime::Delta::FromMicroseconds(time);
-}
-
-uint64_t QuicFramer::CalculatePacketNumberFromWire(
-    QuicPacketNumberLength packet_number_length,
-    QuicPacketNumber base_packet_number, uint64_t packet_number) const {
-  // The new packet number might have wrapped to the next epoch, or
-  // it might have reverse wrapped to the previous epoch, or it might
-  // remain in the same epoch.  Select the packet number closest to the
-  // next expected packet number, the previous packet number plus 1.
-
-  // epoch_delta is the delta between epochs the packet number was serialized
-  // with, so the correct value is likely the same epoch as the last sequence
-  // number or an adjacent epoch.
-  if (!base_packet_number.IsInitialized()) {
-    return packet_number;
-  }
-  const uint64_t epoch_delta = UINT64_C(1) << (8 * packet_number_length);
-  uint64_t next_packet_number = base_packet_number.ToUint64() + 1;
-  uint64_t epoch = base_packet_number.ToUint64() & ~(epoch_delta - 1);
-  uint64_t prev_epoch = epoch - epoch_delta;
-  uint64_t next_epoch = epoch + epoch_delta;
-
-  return ClosestTo(next_packet_number, epoch + packet_number,
-                   ClosestTo(next_packet_number, prev_epoch + packet_number,
-                             next_epoch + packet_number));
-}
-
-bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
-                                     bool packet_has_ietf_packet_header,
-                                     QuicPacketHeader* header) {
-  if (packet_has_ietf_packet_header) {
-    return ProcessIetfPacketHeader(reader, header);
-  }
-  uint8_t public_flags;
-  if (!reader->ReadBytes(&public_flags, 1)) {
-    set_detailed_error("Unable to read public flags.");
-    return false;
-  }
-
-  header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
-  header->version_flag = (public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
-
-  if (validate_flags_ && !header->version_flag &&
-      public_flags > PACKET_PUBLIC_FLAGS_MAX) {
-    set_detailed_error("Illegal public flags value.");
-    return false;
-  }
-
-  if (header->reset_flag && header->version_flag) {
-    set_detailed_error("Got version flag in reset packet");
-    return false;
-  }
-
-  QuicConnectionId* header_connection_id = &header->destination_connection_id;
-  QuicConnectionIdIncluded* header_connection_id_included =
-      &header->destination_connection_id_included;
-  if (perspective_ == Perspective::IS_CLIENT) {
-    header_connection_id = &header->source_connection_id;
-    header_connection_id_included = &header->source_connection_id_included;
-  }
-  switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) {
-    case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID:
-      if (!reader->ReadConnectionId(header_connection_id,
-                                    kQuicDefaultConnectionIdLength)) {
-        set_detailed_error("Unable to read ConnectionId.");
-        return false;
-      }
-      *header_connection_id_included = CONNECTION_ID_PRESENT;
-      break;
-    case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
-      *header_connection_id_included = CONNECTION_ID_ABSENT;
-      *header_connection_id = last_serialized_server_connection_id_;
-      break;
-  }
-
-  header->packet_number_length = ReadSequenceNumberLength(
-      public_flags >> kPublicHeaderSequenceNumberShift);
-
-  // Read the version only if the packet is from the client.
-  // version flag from the server means version negotiation packet.
-  if (header->version_flag && perspective_ == Perspective::IS_SERVER) {
-    QuicVersionLabel version_label;
-    if (!ProcessVersionLabel(reader, &version_label)) {
-      set_detailed_error("Unable to read protocol version.");
-      return false;
-    }
-    // If the version from the new packet is the same as the version of this
-    // framer, then the public flags should be set to something we understand.
-    // If not, this raises an error.
-    ParsedQuicVersion version = ParseQuicVersionLabel(version_label);
-    if (version == version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
-      set_detailed_error("Illegal public flags value.");
-      return false;
-    }
-    header->version = version;
-  }
-
-  // A nonce should only be present in packets from the server to the client,
-  // which are neither version negotiation nor public reset packets.
-  if (public_flags & PACKET_PUBLIC_FLAGS_NONCE &&
-      !(public_flags & PACKET_PUBLIC_FLAGS_VERSION) &&
-      !(public_flags & PACKET_PUBLIC_FLAGS_RST) &&
-      // The nonce flag from a client is ignored and is assumed to be an older
-      // client indicating an eight-byte connection ID.
-      perspective_ == Perspective::IS_CLIENT) {
-    if (!reader->ReadBytes(reinterpret_cast<uint8_t*>(last_nonce_.data()),
-                           last_nonce_.size())) {
-      set_detailed_error("Unable to read nonce.");
-      return false;
-    }
-    header->nonce = &last_nonce_;
-  } else {
-    header->nonce = nullptr;
-  }
-
-  return true;
-}
-
-// static
-QuicPacketNumberLength QuicFramer::GetMinPacketNumberLength(
-    QuicPacketNumber packet_number) {
-  QUICHE_DCHECK(packet_number.IsInitialized());
-  if (packet_number < QuicPacketNumber(1 << (PACKET_1BYTE_PACKET_NUMBER * 8))) {
-    return PACKET_1BYTE_PACKET_NUMBER;
-  } else if (packet_number <
-             QuicPacketNumber(1 << (PACKET_2BYTE_PACKET_NUMBER * 8))) {
-    return PACKET_2BYTE_PACKET_NUMBER;
-  } else if (packet_number <
-             QuicPacketNumber(UINT64_C(1)
-                              << (PACKET_4BYTE_PACKET_NUMBER * 8))) {
-    return PACKET_4BYTE_PACKET_NUMBER;
-  } else {
-    return PACKET_6BYTE_PACKET_NUMBER;
-  }
-}
-
-// static
-uint8_t QuicFramer::GetPacketNumberFlags(
-    QuicPacketNumberLength packet_number_length) {
-  switch (packet_number_length) {
-    case PACKET_1BYTE_PACKET_NUMBER:
-      return PACKET_FLAGS_1BYTE_PACKET;
-    case PACKET_2BYTE_PACKET_NUMBER:
-      return PACKET_FLAGS_2BYTE_PACKET;
-    case PACKET_4BYTE_PACKET_NUMBER:
-      return PACKET_FLAGS_4BYTE_PACKET;
-    case PACKET_6BYTE_PACKET_NUMBER:
-    case PACKET_8BYTE_PACKET_NUMBER:
-      return PACKET_FLAGS_8BYTE_PACKET;
-    default:
-      QUIC_BUG(quic_bug_10850_56) << "Unreachable case statement.";
-      return PACKET_FLAGS_8BYTE_PACKET;
-  }
-}
-
-// static
-QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
-    const QuicAckFrame& frame) {
-  AckFrameInfo new_ack_info;
-  if (frame.packets.Empty()) {
-    return new_ack_info;
-  }
-  // The first block is the last interval. It isn't encoded with the gap-length
-  // encoding, so skip it.
-  new_ack_info.first_block_length = frame.packets.LastIntervalLength();
-  auto itr = frame.packets.rbegin();
-  QuicPacketNumber previous_start = itr->min();
-  new_ack_info.max_block_length = itr->Length();
-  ++itr;
-
-  // Don't do any more work after getting information for 256 ACK blocks; any
-  // more can't be encoded anyway.
-  for (; itr != frame.packets.rend() &&
-         new_ack_info.num_ack_blocks < std::numeric_limits<uint8_t>::max();
-       previous_start = itr->min(), ++itr) {
-    const auto& interval = *itr;
-    const QuicPacketCount total_gap = previous_start - interval.max();
-    new_ack_info.num_ack_blocks +=
-        (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
-        std::numeric_limits<uint8_t>::max();
-    new_ack_info.max_block_length =
-        std::max(new_ack_info.max_block_length, interval.Length());
-  }
-  return new_ack_info;
-}
-
-bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
-                                              QuicPacketHeader* header) {
-  QuicPacketNumber base_packet_number;
-  if (supports_multiple_packet_number_spaces_) {
-    PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
-    if (pn_space == NUM_PACKET_NUMBER_SPACES) {
-      set_detailed_error("Unable to determine packet number space.");
-      return RaiseError(QUIC_INVALID_PACKET_HEADER);
-    }
-    base_packet_number = largest_decrypted_packet_numbers_[pn_space];
-  } else {
-    base_packet_number = largest_packet_number_;
-  }
-  uint64_t full_packet_number;
-  if (!ProcessAndCalculatePacketNumber(
-          encrypted_reader, header->packet_number_length, base_packet_number,
-          &full_packet_number)) {
-    set_detailed_error("Unable to read packet number.");
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-
-  if (!IsValidFullPacketNumber(full_packet_number, version())) {
-    set_detailed_error("packet numbers cannot be 0.");
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-  header->packet_number = QuicPacketNumber(full_packet_number);
-
-  if (!visitor_->OnUnauthenticatedHeader(*header)) {
-    set_detailed_error(
-        "Visitor asked to stop processing of unauthenticated header.");
-    return false;
-  }
-  // The function we are in is called because the framer believes that it is
-  // processing a packet that uses the non-IETF (i.e. Google QUIC) packet header
-  // type. Usually, the framer makes that decision based on the framer's
-  // version, but when the framer is used with Perspective::IS_SERVER, then
-  // before version negotiation is complete (specifically, before
-  // InferPacketHeaderTypeFromVersion is called), this decision is made based on
-  // the type byte of the packet.
-  //
-  // If the framer's version KnowsWhichDecrypterToUse, then that version expects
-  // to use the IETF packet header type. If that's the case and we're in this
-  // function, then the packet received is invalid: the framer was expecting an
-  // IETF packet header and didn't get one.
-  if (version().KnowsWhichDecrypterToUse()) {
-    set_detailed_error("Invalid public header type for expected version.");
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessIetfHeaderTypeByte(QuicDataReader* reader,
-                                           QuicPacketHeader* header) {
-  uint8_t type;
-  if (!reader->ReadBytes(&type, 1)) {
-    set_detailed_error("Unable to read first byte.");
-    return false;
-  }
-  header->type_byte = type;
-  // Determine whether this is a long or short header.
-  header->form = GetIetfPacketHeaderFormat(type);
-  if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
-    // Version is always present in long headers.
-    header->version_flag = true;
-    // In versions that do not support client connection IDs, we mark the
-    // corresponding connection ID as absent.
-    header->destination_connection_id_included =
-        (perspective_ == Perspective::IS_SERVER ||
-         version_.SupportsClientConnectionIds())
-            ? CONNECTION_ID_PRESENT
-            : CONNECTION_ID_ABSENT;
-    header->source_connection_id_included =
-        (perspective_ == Perspective::IS_CLIENT ||
-         version_.SupportsClientConnectionIds())
-            ? CONNECTION_ID_PRESENT
-            : CONNECTION_ID_ABSENT;
-    // Read version tag.
-    QuicVersionLabel version_label;
-    if (!ProcessVersionLabel(reader, &version_label)) {
-      set_detailed_error("Unable to read protocol version.");
-      return false;
-    }
-    if (!version_label) {
-      // Version label is 0 indicating this is a version negotiation packet.
-      header->long_packet_type = VERSION_NEGOTIATION;
-    } else {
-      header->version = ParseQuicVersionLabel(version_label);
-      if (header->version.IsKnown()) {
-        if (!(type & FLAGS_FIXED_BIT)) {
-          set_detailed_error("Fixed bit is 0 in long header.");
-          return false;
-        }
-        header->long_packet_type = GetLongHeaderType(type, header->version);
-        switch (header->long_packet_type) {
-          case INVALID_PACKET_TYPE:
-            set_detailed_error("Illegal long header type value.");
-            return false;
-          case RETRY:
-            if (!version().SupportsRetry()) {
-              set_detailed_error("RETRY not supported in this version.");
-              return false;
-            }
-            if (perspective_ == Perspective::IS_SERVER) {
-              set_detailed_error("Client-initiated RETRY is invalid.");
-              return false;
-            }
-            break;
-          default:
-            if (!header->version.HasHeaderProtection()) {
-              header->packet_number_length =
-                  GetLongHeaderPacketNumberLength(type);
-            }
-            break;
-        }
-      }
-    }
-
-    QUIC_DVLOG(1) << ENDPOINT << "Received IETF long header: "
-                  << QuicUtils::QuicLongHeaderTypetoString(
-                         header->long_packet_type);
-    return true;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "Received IETF short header";
-  // Version is not present in short headers.
-  header->version_flag = false;
-  // In versions that do not support client connection IDs, the client will not
-  // receive destination connection IDs.
-  header->destination_connection_id_included =
-      (perspective_ == Perspective::IS_SERVER ||
-       version_.SupportsClientConnectionIds())
-          ? CONNECTION_ID_PRESENT
-          : CONNECTION_ID_ABSENT;
-  header->source_connection_id_included = CONNECTION_ID_ABSENT;
-  if (!(type & FLAGS_FIXED_BIT)) {
-    set_detailed_error("Fixed bit is 0 in short header.");
-    return false;
-  }
-  if (!version_.HasHeaderProtection()) {
-    header->packet_number_length = GetShortHeaderPacketNumberLength(type);
-  }
-  QUIC_DVLOG(1) << "packet_number_length = " << header->packet_number_length;
-  return true;
-}
-
-// static
-bool QuicFramer::ProcessVersionLabel(QuicDataReader* reader,
-                                     QuicVersionLabel* version_label) {
-  if (!reader->ReadUInt32(version_label)) {
-    return false;
-  }
-  return true;
-}
-
-// static
-bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
-    QuicDataReader* reader, ParsedQuicVersion version, Perspective perspective,
-    bool should_update_expected_server_connection_id_length,
-    uint8_t* expected_server_connection_id_length,
-    uint8_t* destination_connection_id_length,
-    uint8_t* source_connection_id_length, std::string* detailed_error) {
-  uint8_t connection_id_lengths_byte;
-  if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
-    *detailed_error = "Unable to read ConnectionId length.";
-    return false;
-  }
-  uint8_t dcil =
-      (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
-  if (dcil != 0) {
-    dcil += kConnectionIdLengthAdjustment;
-  }
-  uint8_t scil = connection_id_lengths_byte & kSourceConnectionIdLengthMask;
-  if (scil != 0) {
-    scil += kConnectionIdLengthAdjustment;
-  }
-  if (should_update_expected_server_connection_id_length) {
-    uint8_t server_connection_id_length =
-        perspective == Perspective::IS_SERVER ? dcil : scil;
-    if (*expected_server_connection_id_length != server_connection_id_length) {
-      QUIC_DVLOG(1) << "Updating expected_server_connection_id_length: "
-                    << static_cast<int>(*expected_server_connection_id_length)
-                    << " -> " << static_cast<int>(server_connection_id_length);
-      *expected_server_connection_id_length = server_connection_id_length;
-    }
-  }
-  if (!should_update_expected_server_connection_id_length &&
-      (dcil != *destination_connection_id_length ||
-       scil != *source_connection_id_length) &&
-      version.IsKnown() && !version.AllowsVariableLengthConnectionIds()) {
-    QUIC_DVLOG(1) << "dcil: " << static_cast<uint32_t>(dcil)
-                  << ", scil: " << static_cast<uint32_t>(scil);
-    *detailed_error = "Invalid ConnectionId length.";
-    return false;
-  }
-  *destination_connection_id_length = dcil;
-  *source_connection_id_length = scil;
-  return true;
-}
-
-bool QuicFramer::ValidateReceivedConnectionIds(const QuicPacketHeader& header) {
-  bool skip_server_connection_id_validation =
-      perspective_ == Perspective::IS_CLIENT &&
-      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
-  if (!skip_server_connection_id_validation &&
-      !QuicUtils::IsConnectionIdValidForVersion(
-          GetServerConnectionIdAsRecipient(header, perspective_),
-          transport_version())) {
-    set_detailed_error("Received server connection ID with invalid length.");
-    return false;
-  }
-
-  bool skip_client_connection_id_validation =
-      perspective_ == Perspective::IS_SERVER &&
-      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
-  if (!skip_client_connection_id_validation &&
-      version_.SupportsClientConnectionIds() &&
-      !QuicUtils::IsConnectionIdValidForVersion(
-          GetClientConnectionIdAsRecipient(header, perspective_),
-          transport_version())) {
-    set_detailed_error("Received client connection ID with invalid length.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessIetfPacketHeader(QuicDataReader* reader,
-                                         QuicPacketHeader* header) {
-  if (version_.HasLengthPrefixedConnectionIds()) {
-    uint8_t expected_destination_connection_id_length =
-        perspective_ == Perspective::IS_CLIENT
-            ? expected_client_connection_id_length_
-            : expected_server_connection_id_length_;
-    QuicVersionLabel version_label;
-    bool has_length_prefix;
-    std::string detailed_error;
-    QuicErrorCode parse_result = QuicFramer::ParsePublicHeader(
-        reader, expected_destination_connection_id_length,
-        version_.HasIetfInvariantHeader(), &header->type_byte, &header->form,
-        &header->version_flag, &has_length_prefix, &version_label,
-        &header->version, &header->destination_connection_id,
-        &header->source_connection_id, &header->long_packet_type,
-        &header->retry_token_length_length, &header->retry_token,
-        &detailed_error);
-    if (parse_result != QUIC_NO_ERROR) {
-      set_detailed_error(detailed_error);
-      return false;
-    }
-    header->destination_connection_id_included = CONNECTION_ID_PRESENT;
-    header->source_connection_id_included =
-        header->version_flag ? CONNECTION_ID_PRESENT : CONNECTION_ID_ABSENT;
-
-    if (!ValidateReceivedConnectionIds(*header)) {
-      return false;
-    }
-
-    if (header->version_flag &&
-        header->long_packet_type != VERSION_NEGOTIATION &&
-        !(header->type_byte & FLAGS_FIXED_BIT)) {
-      set_detailed_error("Fixed bit is 0 in long header.");
-      return false;
-    }
-    if (!header->version_flag && !(header->type_byte & FLAGS_FIXED_BIT)) {
-      set_detailed_error("Fixed bit is 0 in short header.");
-      return false;
-    }
-    if (!header->version_flag) {
-      if (!version_.HasHeaderProtection()) {
-        header->packet_number_length =
-            GetShortHeaderPacketNumberLength(header->type_byte);
-      }
-      return true;
-    }
-    if (header->long_packet_type == RETRY) {
-      if (!version().SupportsRetry()) {
-        set_detailed_error("RETRY not supported in this version.");
-        return false;
-      }
-      if (perspective_ == Perspective::IS_SERVER) {
-        set_detailed_error("Client-initiated RETRY is invalid.");
-        return false;
-      }
-      return true;
-    }
-    if (header->version.IsKnown() && !header->version.HasHeaderProtection()) {
-      header->packet_number_length =
-          GetLongHeaderPacketNumberLength(header->type_byte);
-    }
-
-    return true;
-  }
-
-  if (!ProcessIetfHeaderTypeByte(reader, header)) {
-    return false;
-  }
-
-  uint8_t destination_connection_id_length =
-      header->destination_connection_id_included == CONNECTION_ID_PRESENT
-          ? (perspective_ == Perspective::IS_SERVER
-                 ? expected_server_connection_id_length_
-                 : expected_client_connection_id_length_)
-          : 0;
-  uint8_t source_connection_id_length =
-      header->source_connection_id_included == CONNECTION_ID_PRESENT
-          ? (perspective_ == Perspective::IS_CLIENT
-                 ? expected_server_connection_id_length_
-                 : expected_client_connection_id_length_)
-          : 0;
-  if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
-    if (!ProcessAndValidateIetfConnectionIdLength(
-            reader, header->version, perspective_,
-            /*should_update_expected_server_connection_id_length=*/false,
-            &expected_server_connection_id_length_,
-            &destination_connection_id_length, &source_connection_id_length,
-            &detailed_error_)) {
-      return false;
-    }
-  }
-
-  // Read connection ID.
-  if (!reader->ReadConnectionId(&header->destination_connection_id,
-                                destination_connection_id_length)) {
-    set_detailed_error("Unable to read destination connection ID.");
-    return false;
-  }
-
-  if (!reader->ReadConnectionId(&header->source_connection_id,
-                                source_connection_id_length)) {
-    set_detailed_error("Unable to read source connection ID.");
-    return false;
-  }
-
-  if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
-    if (!header->source_connection_id.IsEmpty()) {
-      QUICHE_DCHECK(!version_.SupportsClientConnectionIds());
-      set_detailed_error("Client connection ID not supported in this version.");
-      return false;
-    }
-  }
-
-  return ValidateReceivedConnectionIds(*header);
-}
-
-bool QuicFramer::ProcessAndCalculatePacketNumber(
-    QuicDataReader* reader, QuicPacketNumberLength packet_number_length,
-    QuicPacketNumber base_packet_number, uint64_t* packet_number) {
-  uint64_t wire_packet_number;
-  if (!reader->ReadBytesToUInt64(packet_number_length, &wire_packet_number)) {
-    return false;
-  }
-
-  // TODO(ianswett): Explore the usefulness of trying multiple packet numbers
-  // in case the first guess is incorrect.
-  *packet_number = CalculatePacketNumberFromWire(
-      packet_number_length, base_packet_number, wire_packet_number);
-  return true;
-}
-
-bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
-                                  const QuicPacketHeader& header) {
-  QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
-      << "IETF QUIC Framing negotiated but attempting to process frames as "
-         "non-IETF QUIC.";
-  if (reader->IsDoneReading()) {
-    set_detailed_error("Packet has no frames.");
-    return RaiseError(QUIC_MISSING_PAYLOAD);
-  }
-  QUIC_DVLOG(2) << ENDPOINT << "Processing packet with header " << header;
-  while (!reader->IsDoneReading()) {
-    uint8_t frame_type;
-    if (!reader->ReadBytes(&frame_type, 1)) {
-      set_detailed_error("Unable to read frame type.");
-      return RaiseError(QUIC_INVALID_FRAME_DATA);
-    }
-    const uint8_t special_mask = version_.HasIetfInvariantHeader()
-                                     ? kQuicFrameTypeSpecialMask
-                                     : kQuicFrameTypeBrokenMask;
-    if (frame_type & special_mask) {
-      // Stream Frame
-      if (frame_type & kQuicFrameTypeStreamMask) {
-        QuicStreamFrame frame;
-        if (!ProcessStreamFrame(reader, frame_type, &frame)) {
-          return RaiseError(QUIC_INVALID_STREAM_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing stream frame " << frame;
-        if (!visitor_->OnStreamFrame(frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      // Ack Frame
-      if (frame_type & kQuicFrameTypeAckMask) {
-        if (!ProcessAckFrame(reader, frame_type)) {
-          return RaiseError(QUIC_INVALID_ACK_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing ACK frame";
-        continue;
-      }
-
-      // This was a special frame type that did not match any
-      // of the known ones. Error.
-      set_detailed_error("Illegal frame type.");
-      QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
-                         << static_cast<int>(frame_type);
-      return RaiseError(QUIC_INVALID_FRAME_DATA);
-    }
-
-    switch (frame_type) {
-      case PADDING_FRAME: {
-        QuicPaddingFrame frame;
-        ProcessPaddingFrame(reader, &frame);
-        QUIC_DVLOG(2) << ENDPOINT << "Processing padding frame " << frame;
-        if (!visitor_->OnPaddingFrame(frame)) {
-          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      case RST_STREAM_FRAME: {
-        QuicRstStreamFrame frame;
-        if (!ProcessRstStreamFrame(reader, &frame)) {
-          return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing reset stream frame " << frame;
-        if (!visitor_->OnRstStreamFrame(frame)) {
-          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      case CONNECTION_CLOSE_FRAME: {
-        QuicConnectionCloseFrame frame;
-        if (!ProcessConnectionCloseFrame(reader, &frame)) {
-          return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
-        }
-
-        QUIC_DVLOG(2) << ENDPOINT << "Processing connection close frame "
-                      << frame;
-        if (!visitor_->OnConnectionCloseFrame(frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      case GOAWAY_FRAME: {
-        QuicGoAwayFrame goaway_frame;
-        if (!ProcessGoAwayFrame(reader, &goaway_frame)) {
-          return RaiseError(QUIC_INVALID_GOAWAY_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing go away frame "
-                      << goaway_frame;
-        if (!visitor_->OnGoAwayFrame(goaway_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      case WINDOW_UPDATE_FRAME: {
-        QuicWindowUpdateFrame window_update_frame;
-        if (!ProcessWindowUpdateFrame(reader, &window_update_frame)) {
-          return RaiseError(QUIC_INVALID_WINDOW_UPDATE_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing window update frame "
-                      << window_update_frame;
-        if (!visitor_->OnWindowUpdateFrame(window_update_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      case BLOCKED_FRAME: {
-        QuicBlockedFrame blocked_frame;
-        if (!ProcessBlockedFrame(reader, &blocked_frame)) {
-          return RaiseError(QUIC_INVALID_BLOCKED_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing blocked frame "
-                      << blocked_frame;
-        if (!visitor_->OnBlockedFrame(blocked_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-
-      case STOP_WAITING_FRAME: {
-        QuicStopWaitingFrame stop_waiting_frame;
-        if (!ProcessStopWaitingFrame(reader, header, &stop_waiting_frame)) {
-          return RaiseError(QUIC_INVALID_STOP_WAITING_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing stop waiting frame "
-                      << stop_waiting_frame;
-        if (!visitor_->OnStopWaitingFrame(stop_waiting_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        continue;
-      }
-      case PING_FRAME: {
-        // Ping has no payload.
-        QuicPingFrame ping_frame;
-        if (!visitor_->OnPingFrame(ping_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing ping frame " << ping_frame;
-        continue;
-      }
-      case IETF_EXTENSION_MESSAGE_NO_LENGTH:
-        ABSL_FALLTHROUGH_INTENDED;
-      case IETF_EXTENSION_MESSAGE: {
-        QuicMessageFrame message_frame;
-        if (!ProcessMessageFrame(reader,
-                                 frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH,
-                                 &message_frame)) {
-          return RaiseError(QUIC_INVALID_MESSAGE_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing message frame "
-                      << message_frame;
-        if (!visitor_->OnMessageFrame(message_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        break;
-      }
-      case CRYPTO_FRAME: {
-        if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
-          set_detailed_error("Illegal frame type.");
-          return RaiseError(QUIC_INVALID_FRAME_DATA);
-        }
-        QuicCryptoFrame frame;
-        if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
-          return RaiseError(QUIC_INVALID_FRAME_DATA);
-        }
-        QUIC_DVLOG(2) << ENDPOINT << "Processing crypto frame " << frame;
-        if (!visitor_->OnCryptoFrame(frame)) {
-          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        break;
-      }
-      case HANDSHAKE_DONE_FRAME: {
-        // HANDSHAKE_DONE has no payload.
-        QuicHandshakeDoneFrame handshake_done_frame;
-        QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
-                      << handshake_done_frame;
-        if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
-          QUIC_DVLOG(1) << ENDPOINT
-                        << "Visitor asked to stop further processing.";
-          // Returning true since there was no parsing error.
-          return true;
-        }
-        break;
-      }
-
-      default:
-        set_detailed_error("Illegal frame type.");
-        QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
-                           << static_cast<int>(frame_type);
-        return RaiseError(QUIC_INVALID_FRAME_DATA);
-    }
-  }
-
-  return true;
-}
-
-// static
-bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
-    uint64_t frame_type, EncryptionLevel level) {
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-    case ENCRYPTION_HANDSHAKE:
-      return frame_type == IETF_CRYPTO || frame_type == IETF_ACK ||
-             frame_type == IETF_ACK_ECN ||
-             frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
-             frame_type == IETF_PING || frame_type == IETF_PADDING ||
-             frame_type == IETF_CONNECTION_CLOSE;
-    case ENCRYPTION_ZERO_RTT:
-      return !(frame_type == IETF_ACK || frame_type == IETF_ACK_ECN ||
-               frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
-               frame_type == IETF_CRYPTO || frame_type == IETF_HANDSHAKE_DONE ||
-               frame_type == IETF_NEW_TOKEN ||
-               frame_type == IETF_PATH_RESPONSE ||
-               frame_type == IETF_RETIRE_CONNECTION_ID);
-    case ENCRYPTION_FORWARD_SECURE:
-      return true;
-    default:
-      QUIC_BUG(quic_bug_10850_57) << "Unknown encryption level: " << level;
-  }
-  return false;
-}
-
-bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader,
-                                      const QuicPacketHeader& header,
-                                      EncryptionLevel decrypted_level) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version))
-      << "Attempt to process frames as IETF frames but version ("
-      << version_.transport_version << ") does not support IETF Framing.";
-
-  if (reader->IsDoneReading()) {
-    set_detailed_error("Packet has no frames.");
-    return RaiseError(QUIC_MISSING_PAYLOAD);
-  }
-
-  QUIC_DVLOG(2) << ENDPOINT << "Processing IETF packet with header " << header;
-  while (!reader->IsDoneReading()) {
-    uint64_t frame_type;
-    // Will be the number of bytes into which frame_type was encoded.
-    size_t encoded_bytes = reader->BytesRemaining();
-    if (!reader->ReadVarInt62(&frame_type)) {
-      set_detailed_error("Unable to read frame type.");
-      return RaiseError(QUIC_INVALID_FRAME_DATA);
-    }
-    if (!IsIetfFrameTypeExpectedForEncryptionLevel(frame_type,
-                                                   decrypted_level)) {
-      set_detailed_error(absl::StrCat(
-          "IETF frame type ",
-          QuicIetfFrameTypeString(static_cast<QuicIetfFrameType>(frame_type)),
-          " is unexpected at encryption level ",
-          EncryptionLevelToString(decrypted_level)));
-      return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
-    }
-    previously_received_frame_type_ = current_received_frame_type_;
-    current_received_frame_type_ = frame_type;
-
-    // Is now the number of bytes into which the frame type was encoded.
-    encoded_bytes -= reader->BytesRemaining();
-
-    // Check that the frame type is minimally encoded.
-    if (encoded_bytes !=
-        static_cast<size_t>(QuicDataWriter::GetVarInt62Len(frame_type))) {
-      // The frame type was not minimally encoded.
-      set_detailed_error("Frame type not minimally encoded.");
-      return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
-    }
-
-    if (IS_IETF_STREAM_FRAME(frame_type)) {
-      QuicStreamFrame frame;
-      if (!ProcessIetfStreamFrame(reader, frame_type, &frame)) {
-        return RaiseError(QUIC_INVALID_STREAM_DATA);
-      }
-      QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream frame " << frame;
-      if (!visitor_->OnStreamFrame(frame)) {
-        QUIC_DVLOG(1) << ENDPOINT
-                      << "Visitor asked to stop further processing.";
-        // Returning true since there was no parsing error.
-        return true;
-      }
-    } else {
-      switch (frame_type) {
-        case IETF_PADDING: {
-          QuicPaddingFrame frame;
-          ProcessPaddingFrame(reader, &frame);
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF padding frame "
-                        << frame;
-          if (!visitor_->OnPaddingFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_RST_STREAM: {
-          QuicRstStreamFrame frame;
-          if (!ProcessIetfResetStreamFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF reset stream frame "
-                        << frame;
-          if (!visitor_->OnRstStreamFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_APPLICATION_CLOSE:
-        case IETF_CONNECTION_CLOSE: {
-          QuicConnectionCloseFrame frame;
-          if (!ProcessIetfConnectionCloseFrame(
-                  reader,
-                  (frame_type == IETF_CONNECTION_CLOSE)
-                      ? IETF_QUIC_TRANSPORT_CONNECTION_CLOSE
-                      : IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
-                  &frame)) {
-            return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF connection close frame "
-                        << frame;
-          if (!visitor_->OnConnectionCloseFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_MAX_DATA: {
-          QuicWindowUpdateFrame frame;
-          if (!ProcessMaxDataFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_MAX_DATA_FRAME_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max data frame "
-                        << frame;
-          if (!visitor_->OnWindowUpdateFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_MAX_STREAM_DATA: {
-          QuicWindowUpdateFrame frame;
-          if (!ProcessMaxStreamDataFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max stream data frame "
-                        << frame;
-          if (!visitor_->OnWindowUpdateFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_MAX_STREAMS_BIDIRECTIONAL:
-        case IETF_MAX_STREAMS_UNIDIRECTIONAL: {
-          QuicMaxStreamsFrame frame;
-          if (!ProcessMaxStreamsFrame(reader, &frame, frame_type)) {
-            return RaiseError(QUIC_MAX_STREAMS_DATA);
-          }
-          QUIC_CODE_COUNT_N(quic_max_streams_received, 1, 2);
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max streams frame "
-                        << frame;
-          if (!visitor_->OnMaxStreamsFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_PING: {
-          // Ping has no payload.
-          QuicPingFrame ping_frame;
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ping frame "
-                        << ping_frame;
-          if (!visitor_->OnPingFrame(ping_frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_DATA_BLOCKED: {
-          QuicBlockedFrame frame;
-          if (!ProcessDataBlockedFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_BLOCKED_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF blocked frame "
-                        << frame;
-          if (!visitor_->OnBlockedFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_STREAM_DATA_BLOCKED: {
-          QuicBlockedFrame frame;
-          if (!ProcessStreamDataBlockedFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_STREAM_BLOCKED_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream blocked frame "
-                        << frame;
-          if (!visitor_->OnBlockedFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_STREAMS_BLOCKED_UNIDIRECTIONAL:
-        case IETF_STREAMS_BLOCKED_BIDIRECTIONAL: {
-          QuicStreamsBlockedFrame frame;
-          if (!ProcessStreamsBlockedFrame(reader, &frame, frame_type)) {
-            return RaiseError(QUIC_STREAMS_BLOCKED_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF streams blocked frame "
-                        << frame;
-          if (!visitor_->OnStreamsBlockedFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_NEW_CONNECTION_ID: {
-          QuicNewConnectionIdFrame frame;
-          if (!ProcessNewConnectionIdFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT
-                        << "Processing IETF new connection ID frame " << frame;
-          if (!visitor_->OnNewConnectionIdFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_RETIRE_CONNECTION_ID: {
-          QuicRetireConnectionIdFrame frame;
-          if (!ProcessRetireConnectionIdFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT
-                        << "Processing IETF retire connection ID frame "
-                        << frame;
-          if (!visitor_->OnRetireConnectionIdFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_NEW_TOKEN: {
-          QuicNewTokenFrame frame;
-          if (!ProcessNewTokenFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_NEW_TOKEN);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF new token frame "
-                        << frame;
-          if (!visitor_->OnNewTokenFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_STOP_SENDING: {
-          QuicStopSendingFrame frame;
-          if (!ProcessStopSendingFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stop sending frame "
-                        << frame;
-          if (!visitor_->OnStopSendingFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_ACK_RECEIVE_TIMESTAMPS:
-          if (!process_timestamps_) {
-            set_detailed_error("Unsupported frame type.");
-            QUIC_DLOG(WARNING)
-                << ENDPOINT << "IETF_ACK_RECEIVE_TIMESTAMPS not supported";
-            return RaiseError(QUIC_INVALID_FRAME_DATA);
-          }
-          ABSL_FALLTHROUGH_INTENDED;
-        case IETF_ACK_ECN:
-        case IETF_ACK: {
-          QuicAckFrame frame;
-          if (!ProcessIetfAckFrame(reader, frame_type, &frame)) {
-            return RaiseError(QUIC_INVALID_ACK_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ACK frame " << frame;
-          break;
-        }
-        case IETF_PATH_CHALLENGE: {
-          QuicPathChallengeFrame frame;
-          if (!ProcessPathChallengeFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_PATH_CHALLENGE_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path challenge frame "
-                        << frame;
-          if (!visitor_->OnPathChallengeFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_PATH_RESPONSE: {
-          QuicPathResponseFrame frame;
-          if (!ProcessPathResponseFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_PATH_RESPONSE_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path response frame "
-                        << frame;
-          if (!visitor_->OnPathResponseFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_EXTENSION_MESSAGE_NO_LENGTH_V99:
-          ABSL_FALLTHROUGH_INTENDED;
-        case IETF_EXTENSION_MESSAGE_V99: {
-          QuicMessageFrame message_frame;
-          if (!ProcessMessageFrame(
-                  reader, frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH_V99,
-                  &message_frame)) {
-            return RaiseError(QUIC_INVALID_MESSAGE_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF message frame "
-                        << message_frame;
-          if (!visitor_->OnMessageFrame(message_frame)) {
-            QUIC_DVLOG(1) << ENDPOINT
-                          << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_CRYPTO: {
-          QuicCryptoFrame frame;
-          if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
-            return RaiseError(QUIC_INVALID_FRAME_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF crypto frame " << frame;
-          if (!visitor_->OnCryptoFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        case IETF_HANDSHAKE_DONE: {
-          // HANDSHAKE_DONE has no payload.
-          QuicHandshakeDoneFrame handshake_done_frame;
-          if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
-            QUIC_DVLOG(1) << ENDPOINT
-                          << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
-                        << handshake_done_frame;
-          break;
-        }
-        case IETF_ACK_FREQUENCY: {
-          QuicAckFrequencyFrame frame;
-          if (!ProcessAckFrequencyFrame(reader, &frame)) {
-            return RaiseError(QUIC_INVALID_FRAME_DATA);
-          }
-          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ack frequency frame "
-                        << frame;
-          if (!visitor_->OnAckFrequencyFrame(frame)) {
-            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
-            // Returning true since there was no parsing error.
-            return true;
-          }
-          break;
-        }
-        default:
-          set_detailed_error("Illegal frame type.");
-          QUIC_DLOG(WARNING)
-              << ENDPOINT
-              << "Illegal frame type: " << static_cast<int>(frame_type);
-          return RaiseError(QUIC_INVALID_FRAME_DATA);
-      }
-    }
-  }
-  return true;
-}
-
-namespace {
-// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
-inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
-  return (1u << num_bits) - 1;
-}
-
-// Extract |num_bits| from |flags| offset by |offset|.
-uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
-  return (flags >> offset) & GetMaskFromNumBits(num_bits);
-}
-
-// Extract the bit at position |offset| from |flags| as a bool.
-bool ExtractBit(uint8_t flags, uint8_t offset) {
-  return ((flags >> offset) & GetMaskFromNumBits(1)) != 0;
-}
-
-// Set |num_bits|, offset by |offset| to |val| in |flags|.
-void SetBits(uint8_t* flags, uint8_t val, uint8_t num_bits, uint8_t offset) {
-  QUICHE_DCHECK_LE(val, GetMaskFromNumBits(num_bits));
-  *flags |= val << offset;
-}
-
-// Set the bit at position |offset| to |val| in |flags|.
-void SetBit(uint8_t* flags, bool val, uint8_t offset) {
-  SetBits(flags, val ? 1 : 0, 1, offset);
-}
-}  // namespace
-
-bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type,
-                                    QuicStreamFrame* frame) {
-  uint8_t stream_flags = frame_type;
-
-  uint8_t stream_id_length = 0;
-  uint8_t offset_length = 4;
-  bool has_data_length = true;
-  stream_flags &= ~kQuicFrameTypeStreamMask;
-
-  // Read from right to left: StreamID, Offset, Data Length, Fin.
-  stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
-  stream_flags >>= kQuicStreamIdShift;
-
-  offset_length = (stream_flags & kQuicStreamOffsetMask);
-  // There is no encoding for 1 byte, only 0 and 2 through 8.
-  if (offset_length > 0) {
-    offset_length += 1;
-  }
-  stream_flags >>= kQuicStreamShift;
-
-  has_data_length =
-      (stream_flags & kQuicStreamDataLengthMask) == kQuicStreamDataLengthMask;
-  stream_flags >>= kQuicStreamDataLengthShift;
-
-  frame->fin = (stream_flags & kQuicStreamFinMask) == kQuicStreamFinShift;
-
-  uint64_t stream_id;
-  if (!reader->ReadBytesToUInt64(stream_id_length, &stream_id)) {
-    set_detailed_error("Unable to read stream_id.");
-    return false;
-  }
-  frame->stream_id = static_cast<QuicStreamId>(stream_id);
-
-  if (!reader->ReadBytesToUInt64(offset_length, &frame->offset)) {
-    set_detailed_error("Unable to read offset.");
-    return false;
-  }
-
-  // TODO(ianswett): Don't use absl::string_view as an intermediary.
-  absl::string_view data;
-  if (has_data_length) {
-    if (!reader->ReadStringPiece16(&data)) {
-      set_detailed_error("Unable to read frame data.");
-      return false;
-    }
-  } else {
-    if (!reader->ReadStringPiece(&data, reader->BytesRemaining())) {
-      set_detailed_error("Unable to read frame data.");
-      return false;
-    }
-  }
-  frame->data_buffer = data.data();
-  frame->data_length = static_cast<uint16_t>(data.length());
-
-  return true;
-}
-
-bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader,
-                                        uint8_t frame_type,
-                                        QuicStreamFrame* frame) {
-  // Read stream id from the frame. It's always present.
-  if (!ReadUint32FromVarint62(reader, IETF_STREAM, &frame->stream_id)) {
-    return false;
-  }
-
-  // If we have a data offset, read it. If not, set to 0.
-  if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
-    if (!reader->ReadVarInt62(&frame->offset)) {
-      set_detailed_error("Unable to read stream data offset.");
-      return false;
-    }
-  } else {
-    // no offset in the frame, ensure it's 0 in the Frame.
-    frame->offset = 0;
-  }
-
-  // If we have a data length, read it. If not, set to 0.
-  if (frame_type & IETF_STREAM_FRAME_LEN_BIT) {
-    uint64_t length;
-    if (!reader->ReadVarInt62(&length)) {
-      set_detailed_error("Unable to read stream data length.");
-      return false;
-    }
-    if (length > std::numeric_limits<decltype(frame->data_length)>::max()) {
-      set_detailed_error("Stream data length is too large.");
-      return false;
-    }
-    frame->data_length = length;
-  } else {
-    // no length in the frame, it is the number of bytes remaining in the
-    // packet.
-    frame->data_length = reader->BytesRemaining();
-  }
-
-  if (frame_type & IETF_STREAM_FRAME_FIN_BIT) {
-    frame->fin = true;
-  } else {
-    frame->fin = false;
-  }
-
-  // TODO(ianswett): Don't use absl::string_view as an intermediary.
-  absl::string_view data;
-  if (!reader->ReadStringPiece(&data, frame->data_length)) {
-    set_detailed_error("Unable to read frame data.");
-    return false;
-  }
-  frame->data_buffer = data.data();
-  QUICHE_DCHECK_EQ(frame->data_length, data.length());
-
-  return true;
-}
-
-bool QuicFramer::ProcessCryptoFrame(QuicDataReader* reader,
-                                    EncryptionLevel encryption_level,
-                                    QuicCryptoFrame* frame) {
-  frame->level = encryption_level;
-  if (!reader->ReadVarInt62(&frame->offset)) {
-    set_detailed_error("Unable to read crypto data offset.");
-    return false;
-  }
-  uint64_t len;
-  if (!reader->ReadVarInt62(&len) ||
-      len > std::numeric_limits<QuicPacketLength>::max()) {
-    set_detailed_error("Invalid data length.");
-    return false;
-  }
-  frame->data_length = len;
-
-  // TODO(ianswett): Don't use absl::string_view as an intermediary.
-  absl::string_view data;
-  if (!reader->ReadStringPiece(&data, frame->data_length)) {
-    set_detailed_error("Unable to read frame data.");
-    return false;
-  }
-  frame->data_buffer = data.data();
-  return true;
-}
-
-bool QuicFramer::ProcessAckFrequencyFrame(QuicDataReader* reader,
-                                          QuicAckFrequencyFrame* frame) {
-  if (!reader->ReadVarInt62(&frame->sequence_number)) {
-    set_detailed_error("Unable to read sequence number.");
-    return false;
-  }
-
-  if (!reader->ReadVarInt62(&frame->packet_tolerance)) {
-    set_detailed_error("Unable to read packet tolerance.");
-    return false;
-  }
-  if (frame->packet_tolerance == 0) {
-    set_detailed_error("Invalid packet tolerance.");
-    return false;
-  }
-  uint64_t max_ack_delay_us;
-  if (!reader->ReadVarInt62(&max_ack_delay_us)) {
-    set_detailed_error("Unable to read max_ack_delay_us.");
-    return false;
-  }
-  constexpr uint64_t kMaxAckDelayUsBound = 1u << 24;
-  if (max_ack_delay_us > kMaxAckDelayUsBound) {
-    set_detailed_error("Invalid max_ack_delay_us.");
-    return false;
-  }
-  frame->max_ack_delay = QuicTime::Delta::FromMicroseconds(max_ack_delay_us);
-
-  uint8_t ignore_order;
-  if (!reader->ReadUInt8(&ignore_order)) {
-    set_detailed_error("Unable to read ignore_order.");
-    return false;
-  }
-  if (ignore_order > 1) {
-    set_detailed_error("Invalid ignore_order.");
-    return false;
-  }
-  frame->ignore_order = ignore_order;
-
-  return true;
-}
-
-bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
-  const bool has_ack_blocks =
-      ExtractBit(frame_type, kQuicHasMultipleAckBlocksOffset);
-  uint8_t num_ack_blocks = 0;
-  uint8_t num_received_packets = 0;
-
-  // Determine the two lengths from the frame type: largest acked length,
-  // ack block length.
-  const QuicPacketNumberLength ack_block_length =
-      ReadAckPacketNumberLength(ExtractBits(
-          frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset));
-  const QuicPacketNumberLength largest_acked_length =
-      ReadAckPacketNumberLength(ExtractBits(
-          frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset));
-
-  uint64_t largest_acked;
-  if (!reader->ReadBytesToUInt64(largest_acked_length, &largest_acked)) {
-    set_detailed_error("Unable to read largest acked.");
-    return false;
-  }
-
-  if (largest_acked < first_sending_packet_number_.ToUint64()) {
-    // Connection always sends packet starting from kFirstSendingPacketNumber >
-    // 0, peer has observed an unsent packet.
-    set_detailed_error("Largest acked is 0.");
-    return false;
-  }
-
-  uint64_t ack_delay_time_us;
-  if (!reader->ReadUFloat16(&ack_delay_time_us)) {
-    set_detailed_error("Unable to read ack delay time.");
-    return false;
-  }
-
-  if (!visitor_->OnAckFrameStart(
-          QuicPacketNumber(largest_acked),
-          ack_delay_time_us == kUFloat16MaxValue
-              ? QuicTime::Delta::Infinite()
-              : QuicTime::Delta::FromMicroseconds(ack_delay_time_us))) {
-    // The visitor suppresses further processing of the packet. Although this is
-    // not a parsing error, returns false as this is in middle of processing an
-    // ack frame,
-    set_detailed_error("Visitor suppresses further processing of ack frame.");
-    return false;
-  }
-
-  if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) {
-    set_detailed_error("Unable to read num of ack blocks.");
-    return false;
-  }
-
-  uint64_t first_block_length;
-  if (!reader->ReadBytesToUInt64(ack_block_length, &first_block_length)) {
-    set_detailed_error("Unable to read first ack block length.");
-    return false;
-  }
-
-  if (first_block_length == 0) {
-    set_detailed_error("First block length is zero.");
-    return false;
-  }
-  bool first_ack_block_underflow = first_block_length > largest_acked + 1;
-  if (first_block_length + first_sending_packet_number_.ToUint64() >
-      largest_acked + 1) {
-    first_ack_block_underflow = true;
-  }
-  if (first_ack_block_underflow) {
-    set_detailed_error(absl::StrCat("Underflow with first ack block length ",
-                                    first_block_length, " largest acked is ",
-                                    largest_acked, ".")
-                           .c_str());
-    return false;
-  }
-
-  uint64_t first_received = largest_acked + 1 - first_block_length;
-  if (!visitor_->OnAckRange(QuicPacketNumber(first_received),
-                            QuicPacketNumber(largest_acked + 1))) {
-    // The visitor suppresses further processing of the packet. Although
-    // this is not a parsing error, returns false as this is in middle
-    // of processing an ack frame,
-    set_detailed_error("Visitor suppresses further processing of ack frame.");
-    return false;
-  }
-
-  if (num_ack_blocks > 0) {
-    for (size_t i = 0; i < num_ack_blocks; ++i) {
-      uint8_t gap = 0;
-      if (!reader->ReadUInt8(&gap)) {
-        set_detailed_error("Unable to read gap to next ack block.");
-        return false;
-      }
-      uint64_t current_block_length;
-      if (!reader->ReadBytesToUInt64(ack_block_length, &current_block_length)) {
-        set_detailed_error("Unable to ack block length.");
-        return false;
-      }
-      bool ack_block_underflow = first_received < gap + current_block_length;
-      if (first_received < gap + current_block_length +
-                               first_sending_packet_number_.ToUint64()) {
-        ack_block_underflow = true;
-      }
-      if (ack_block_underflow) {
-        set_detailed_error(absl::StrCat("Underflow with ack block length ",
-                                        current_block_length,
-                                        ", end of block is ",
-                                        first_received - gap, ".")
-                               .c_str());
-        return false;
-      }
-
-      first_received -= (gap + current_block_length);
-      if (current_block_length > 0) {
-        if (!visitor_->OnAckRange(
-                QuicPacketNumber(first_received),
-                QuicPacketNumber(first_received) + current_block_length)) {
-          // The visitor suppresses further processing of the packet. Although
-          // this is not a parsing error, returns false as this is in middle
-          // of processing an ack frame,
-          set_detailed_error(
-              "Visitor suppresses further processing of ack frame.");
-          return false;
-        }
-      }
-    }
-  }
-
-  if (!reader->ReadUInt8(&num_received_packets)) {
-    set_detailed_error("Unable to read num received packets.");
-    return false;
-  }
-
-  if (!ProcessTimestampsInAckFrame(num_received_packets,
-                                   QuicPacketNumber(largest_acked), reader)) {
-    return false;
-  }
-
-  // Done processing the ACK frame.
-  if (!visitor_->OnAckFrameEnd(QuicPacketNumber(first_received))) {
-    set_detailed_error(
-        "Error occurs when visitor finishes processing the ACK frame.");
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
-                                             QuicPacketNumber largest_acked,
-                                             QuicDataReader* reader) {
-  if (num_received_packets == 0) {
-    return true;
-  }
-  uint8_t delta_from_largest_observed;
-  if (!reader->ReadUInt8(&delta_from_largest_observed)) {
-    set_detailed_error("Unable to read sequence delta in received packets.");
-    return false;
-  }
-
-  if (largest_acked.ToUint64() <= delta_from_largest_observed) {
-    set_detailed_error(
-        absl::StrCat("delta_from_largest_observed too high: ",
-                     delta_from_largest_observed,
-                     ", largest_acked: ", largest_acked.ToUint64())
-            .c_str());
-    return false;
-  }
-
-  // Time delta from the framer creation.
-  uint32_t time_delta_us;
-  if (!reader->ReadUInt32(&time_delta_us)) {
-    set_detailed_error("Unable to read time delta in received packets.");
-    return false;
-  }
-
-  QuicPacketNumber seq_num = largest_acked - delta_from_largest_observed;
-  if (process_timestamps_) {
-    last_timestamp_ = CalculateTimestampFromWire(time_delta_us);
-
-    visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
-  }
-
-  for (uint8_t i = 1; i < num_received_packets; ++i) {
-    if (!reader->ReadUInt8(&delta_from_largest_observed)) {
-      set_detailed_error("Unable to read sequence delta in received packets.");
-      return false;
-    }
-    if (largest_acked.ToUint64() <= delta_from_largest_observed) {
-      set_detailed_error(
-          absl::StrCat("delta_from_largest_observed too high: ",
-                       delta_from_largest_observed,
-                       ", largest_acked: ", largest_acked.ToUint64())
-              .c_str());
-      return false;
-    }
-    seq_num = largest_acked - delta_from_largest_observed;
-
-    // Time delta from the previous timestamp.
-    uint64_t incremental_time_delta_us;
-    if (!reader->ReadUFloat16(&incremental_time_delta_us)) {
-      set_detailed_error(
-          "Unable to read incremental time delta in received packets.");
-      return false;
-    }
-
-    if (process_timestamps_) {
-      last_timestamp_ = last_timestamp_ + QuicTime::Delta::FromMicroseconds(
-                                              incremental_time_delta_us);
-      visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
-    }
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessIetfAckFrame(QuicDataReader* reader,
-                                     uint64_t frame_type,
-                                     QuicAckFrame* ack_frame) {
-  uint64_t largest_acked;
-  if (!reader->ReadVarInt62(&largest_acked)) {
-    set_detailed_error("Unable to read largest acked.");
-    return false;
-  }
-  if (largest_acked < first_sending_packet_number_.ToUint64()) {
-    // Connection always sends packet starting from kFirstSendingPacketNumber >
-    // 0, peer has observed an unsent packet.
-    set_detailed_error("Largest acked is 0.");
-    return false;
-  }
-  ack_frame->largest_acked = static_cast<QuicPacketNumber>(largest_acked);
-  uint64_t ack_delay_time_in_us;
-  if (!reader->ReadVarInt62(&ack_delay_time_in_us)) {
-    set_detailed_error("Unable to read ack delay time.");
-    return false;
-  }
-
-  if (ack_delay_time_in_us >= (kVarInt62MaxValue >> peer_ack_delay_exponent_)) {
-    ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
-  } else {
-    ack_delay_time_in_us = (ack_delay_time_in_us << peer_ack_delay_exponent_);
-    ack_frame->ack_delay_time =
-        QuicTime::Delta::FromMicroseconds(ack_delay_time_in_us);
-  }
-  if (!visitor_->OnAckFrameStart(QuicPacketNumber(largest_acked),
-                                 ack_frame->ack_delay_time)) {
-    // The visitor suppresses further processing of the packet. Although this is
-    // not a parsing error, returns false as this is in middle of processing an
-    // ACK frame.
-    set_detailed_error("Visitor suppresses further processing of ACK frame.");
-    return false;
-  }
-
-  // Get number of ACK blocks from the packet.
-  uint64_t ack_block_count;
-  if (!reader->ReadVarInt62(&ack_block_count)) {
-    set_detailed_error("Unable to read ack block count.");
-    return false;
-  }
-  // There always is a first ACK block, which is the (number of packets being
-  // acked)-1, up to and including the packet at largest_acked. Therefore if the
-  // value is 0, then only largest is acked. If it is 1, then largest-1,
-  // largest] are acked, etc
-  uint64_t ack_block_value;
-  if (!reader->ReadVarInt62(&ack_block_value)) {
-    set_detailed_error("Unable to read first ack block length.");
-    return false;
-  }
-  // Calculate the packets being acked in the first block.
-  //  +1 because AddRange implementation requires [low,high)
-  uint64_t block_high = largest_acked + 1;
-  uint64_t block_low = largest_acked - ack_block_value;
-
-  // ack_block_value is the number of packets preceding the
-  // largest_acked packet which are in the block being acked. Thus,
-  // its maximum value is largest_acked-1. Test this, reporting an
-  // error if the value is wrong.
-  if (ack_block_value + first_sending_packet_number_.ToUint64() >
-      largest_acked) {
-    set_detailed_error(absl::StrCat("Underflow with first ack block length ",
-                                    ack_block_value + 1, " largest acked is ",
-                                    largest_acked, ".")
-                           .c_str());
-    return false;
-  }
-
-  if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
-                            QuicPacketNumber(block_high))) {
-    // The visitor suppresses further processing of the packet. Although
-    // this is not a parsing error, returns false as this is in middle
-    // of processing an ACK frame.
-    set_detailed_error("Visitor suppresses further processing of ACK frame.");
-    return false;
-  }
-
-  while (ack_block_count != 0) {
-    uint64_t gap_block_value;
-    // Get the sizes of the gap and ack blocks,
-    if (!reader->ReadVarInt62(&gap_block_value)) {
-      set_detailed_error("Unable to read gap block value.");
-      return false;
-    }
-    // It's an error if the gap is larger than the space from packet
-    // number 0 to the start of the block that's just been acked, PLUS
-    // there must be space for at least 1 packet to be acked. For
-    // example, if block_low is 10 and gap_block_value is 9, it means
-    // the gap block is 10 packets long, leaving no room for a packet
-    // to be acked. Thus, gap_block_value+2 can not be larger than
-    // block_low.
-    // The test is written this way to detect wrap-arounds.
-    if ((gap_block_value + 2) > block_low) {
-      set_detailed_error(
-          absl::StrCat("Underflow with gap block length ", gap_block_value + 1,
-                       " previous ack block start is ", block_low, ".")
-              .c_str());
-      return false;
-    }
-
-    // Adjust block_high to be the top of the next ack block.
-    // There is a gap of |gap_block_value| packets between the bottom
-    // of ack block N and top of block N+1.  Note that gap_block_value
-    // is he size of the gap minus 1 (per the QUIC protocol), and
-    // block_high is the packet number of the first packet of the gap
-    // (per the implementation of OnAckRange/AddAckRange, below).
-    block_high = block_low - 1 - gap_block_value;
-
-    if (!reader->ReadVarInt62(&ack_block_value)) {
-      set_detailed_error("Unable to read ack block value.");
-      return false;
-    }
-    if (ack_block_value + first_sending_packet_number_.ToUint64() >
-        (block_high - 1)) {
-      set_detailed_error(
-          absl::StrCat("Underflow with ack block length ", ack_block_value + 1,
-                       " latest ack block end is ", block_high - 1, ".")
-              .c_str());
-      return false;
-    }
-    // Calculate the low end of the new nth ack block. The +1 is
-    // because the encoded value is the blocksize-1.
-    block_low = block_high - 1 - ack_block_value;
-    if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
-                              QuicPacketNumber(block_high))) {
-      // The visitor suppresses further processing of the packet. Although
-      // this is not a parsing error, returns false as this is in middle
-      // of processing an ACK frame.
-      set_detailed_error("Visitor suppresses further processing of ACK frame.");
-      return false;
-    }
-
-    // Another one done.
-    ack_block_count--;
-  }
-
-  if (frame_type == IETF_ACK_RECEIVE_TIMESTAMPS) {
-    QUICHE_DCHECK(process_timestamps_);
-    if (!ProcessIetfTimestampsInAckFrame(ack_frame->largest_acked, reader)) {
-      return false;
-    }
-  } else if (frame_type == IETF_ACK_ECN) {
-    ack_frame->ecn_counters_populated = true;
-    if (!reader->ReadVarInt62(&ack_frame->ect_0_count)) {
-      set_detailed_error("Unable to read ack ect_0_count.");
-      return false;
-    }
-    if (!reader->ReadVarInt62(&ack_frame->ect_1_count)) {
-      set_detailed_error("Unable to read ack ect_1_count.");
-      return false;
-    }
-    if (!reader->ReadVarInt62(&ack_frame->ecn_ce_count)) {
-      set_detailed_error("Unable to read ack ecn_ce_count.");
-      return false;
-    }
-  } else {
-    ack_frame->ecn_counters_populated = false;
-    ack_frame->ect_0_count = 0;
-    ack_frame->ect_1_count = 0;
-    ack_frame->ecn_ce_count = 0;
-  }
-  // TODO(fayang): Report ECN counts to visitor when they are actually used.
-  if (!visitor_->OnAckFrameEnd(QuicPacketNumber(block_low))) {
-    set_detailed_error(
-        "Error occurs when visitor finishes processing the ACK frame.");
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicFramer::ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
-                                                 QuicDataReader* reader) {
-  uint64_t timestamp_range_count;
-  if (!reader->ReadVarInt62(&timestamp_range_count)) {
-    set_detailed_error("Unable to read receive timestamp range count.");
-    return false;
-  }
-  if (timestamp_range_count == 0) {
-    return true;
-  }
-
-  QuicPacketNumber packet_number = largest_acked;
-
-  // Iterate through all timestamp ranges, each of which represents a block of
-  // contiguous packets for which receive timestamps are being reported. Each
-  // range is of the form:
-  //
-  // Timestamp Range {
-  //    Gap (i),
-  //    Timestamp Delta Count (i),
-  //    Timestamp Delta (i) ...,
-  //  }
-  for (uint64_t i = 0; i < timestamp_range_count; i++) {
-    uint64_t gap;
-    if (!reader->ReadVarInt62(&gap)) {
-      set_detailed_error("Unable to read receive timestamp gap.");
-      return false;
-    }
-    if (packet_number.ToUint64() < gap) {
-      set_detailed_error("Receive timestamp gap too high.");
-      return false;
-    }
-    packet_number = packet_number - gap;
-    uint64_t timestamp_count;
-    if (!reader->ReadVarInt62(&timestamp_count)) {
-      set_detailed_error("Unable to read receive timestamp count.");
-      return false;
-    }
-    if (packet_number.ToUint64() < timestamp_count) {
-      set_detailed_error("Receive timestamp count too high.");
-      return false;
-    }
-    for (uint64_t j = 0; j < timestamp_count; j++) {
-      uint64_t timestamp_delta;
-      if (!reader->ReadVarInt62(&timestamp_delta)) {
-        set_detailed_error("Unable to read receive timestamp delta.");
-        return false;
-      }
-      // The first timestamp delta is relative to framer creation time; whereas
-      // subsequent deltas are relative to the previous delta in decreasing
-      // packet order.
-      timestamp_delta = timestamp_delta << receive_timestamps_exponent_;
-      if (i == 0 && j == 0) {
-        last_timestamp_ = QuicTime::Delta::FromMicroseconds(timestamp_delta);
-      } else {
-        last_timestamp_ = last_timestamp_ -
-                          QuicTime::Delta::FromMicroseconds(timestamp_delta);
-        if (last_timestamp_ < QuicTime::Delta::Zero()) {
-          set_detailed_error("Receive timestamp delta too high.");
-          return false;
-        }
-      }
-      visitor_->OnAckTimestamp(packet_number, creation_time_ + last_timestamp_);
-      packet_number--;
-    }
-    packet_number--;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessStopWaitingFrame(QuicDataReader* reader,
-                                         const QuicPacketHeader& header,
-                                         QuicStopWaitingFrame* stop_waiting) {
-  uint64_t least_unacked_delta;
-  if (!reader->ReadBytesToUInt64(header.packet_number_length,
-                                 &least_unacked_delta)) {
-    set_detailed_error("Unable to read least unacked delta.");
-    return false;
-  }
-  if (header.packet_number.ToUint64() <= least_unacked_delta) {
-    set_detailed_error("Invalid unacked delta.");
-    return false;
-  }
-  stop_waiting->least_unacked = header.packet_number - least_unacked_delta;
-
-  return true;
-}
-
-bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
-                                       QuicRstStreamFrame* frame) {
-  if (!reader->ReadUInt32(&frame->stream_id)) {
-    set_detailed_error("Unable to read stream_id.");
-    return false;
-  }
-
-  if (!reader->ReadUInt64(&frame->byte_offset)) {
-    set_detailed_error("Unable to read rst stream sent byte offset.");
-    return false;
-  }
-
-  uint32_t error_code;
-  if (!reader->ReadUInt32(&error_code)) {
-    set_detailed_error("Unable to read rst stream error code.");
-    return false;
-  }
-
-  if (error_code >= QUIC_STREAM_LAST_ERROR) {
-    // Ignore invalid stream error code if any.
-    error_code = QUIC_STREAM_LAST_ERROR;
-  }
-
-  frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
-
-  return true;
-}
-
-bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
-                                             QuicConnectionCloseFrame* frame) {
-  uint32_t error_code;
-  frame->close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
-
-  if (!reader->ReadUInt32(&error_code)) {
-    set_detailed_error("Unable to read connection close error code.");
-    return false;
-  }
-
-  // For Google QUIC connection closes, |wire_error_code| and |quic_error_code|
-  // must have the same value.
-  frame->wire_error_code = error_code;
-  frame->quic_error_code = static_cast<QuicErrorCode>(error_code);
-
-  absl::string_view error_details;
-  if (!reader->ReadStringPiece16(&error_details)) {
-    set_detailed_error("Unable to read connection close error details.");
-    return false;
-  }
-  frame->error_details = std::string(error_details);
-
-  return true;
-}
-
-bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
-                                    QuicGoAwayFrame* frame) {
-  uint32_t error_code;
-  if (!reader->ReadUInt32(&error_code)) {
-    set_detailed_error("Unable to read go away error code.");
-    return false;
-  }
-
-  frame->error_code = static_cast<QuicErrorCode>(error_code);
-
-  uint32_t stream_id;
-  if (!reader->ReadUInt32(&stream_id)) {
-    set_detailed_error("Unable to read last good stream id.");
-    return false;
-  }
-  frame->last_good_stream_id = static_cast<QuicStreamId>(stream_id);
-
-  absl::string_view reason_phrase;
-  if (!reader->ReadStringPiece16(&reason_phrase)) {
-    set_detailed_error("Unable to read goaway reason.");
-    return false;
-  }
-  frame->reason_phrase = std::string(reason_phrase);
-
-  return true;
-}
-
-bool QuicFramer::ProcessWindowUpdateFrame(QuicDataReader* reader,
-                                          QuicWindowUpdateFrame* frame) {
-  if (!reader->ReadUInt32(&frame->stream_id)) {
-    set_detailed_error("Unable to read stream_id.");
-    return false;
-  }
-
-  if (!reader->ReadUInt64(&frame->max_data)) {
-    set_detailed_error("Unable to read window byte_offset.");
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicFramer::ProcessBlockedFrame(QuicDataReader* reader,
-                                     QuicBlockedFrame* frame) {
-  QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
-      << "Attempt to process non-IETF QUIC frames in an IETF QUIC version.";
-
-  if (!reader->ReadUInt32(&frame->stream_id)) {
-    set_detailed_error("Unable to read stream_id.");
-    return false;
-  }
-
-  return true;
-}
-
-void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader,
-                                     QuicPaddingFrame* frame) {
-  // Type byte has been read.
-  frame->num_padding_bytes = 1;
-  uint8_t next_byte;
-  while (!reader->IsDoneReading() && reader->PeekByte() == 0x00) {
-    reader->ReadBytes(&next_byte, 1);
-    QUICHE_DCHECK_EQ(0x00, next_byte);
-    ++frame->num_padding_bytes;
-  }
-}
-
-bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader,
-                                     bool no_message_length,
-                                     QuicMessageFrame* frame) {
-  if (no_message_length) {
-    absl::string_view remaining(reader->ReadRemainingPayload());
-    frame->data = remaining.data();
-    frame->message_length = remaining.length();
-    return true;
-  }
-
-  uint64_t message_length;
-  if (!reader->ReadVarInt62(&message_length)) {
-    set_detailed_error("Unable to read message length");
-    return false;
-  }
-
-  absl::string_view message_piece;
-  if (!reader->ReadStringPiece(&message_piece, message_length)) {
-    set_detailed_error("Unable to read message data");
-    return false;
-  }
-
-  frame->data = message_piece.data();
-  frame->message_length = message_length;
-
-  return true;
-}
-
-// static
-absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket(
-    QuicTransportVersion version, const QuicEncryptedPacket& encrypted,
-    QuicConnectionIdLength destination_connection_id_length,
-    QuicConnectionIdLength source_connection_id_length, bool includes_version,
-    bool includes_diversification_nonce,
-    QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    uint64_t retry_token_length,
-    QuicVariableLengthIntegerLength length_length) {
-  // TODO(ianswett): This is identical to QuicData::AssociatedData.
-  return absl::string_view(
-      encrypted.data(),
-      GetStartOfEncryptedData(version, destination_connection_id_length,
-                              source_connection_id_length, includes_version,
-                              includes_diversification_nonce,
-                              packet_number_length, retry_token_length_length,
-                              retry_token_length, length_length));
-}
-
-void QuicFramer::SetDecrypter(EncryptionLevel level,
-                              std::unique_ptr<QuicDecrypter> decrypter) {
-  QUICHE_DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
-  QUICHE_DCHECK_GE(level, decrypter_level_);
-  QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
-  QUIC_DVLOG(1) << ENDPOINT << "Setting decrypter from level "
-                << decrypter_level_ << " to " << level;
-  decrypter_[decrypter_level_] = nullptr;
-  decrypter_[level] = std::move(decrypter);
-  decrypter_level_ = level;
-}
-
-void QuicFramer::SetAlternativeDecrypter(
-    EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
-    bool latch_once_used) {
-  QUICHE_DCHECK_NE(level, decrypter_level_);
-  QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
-  QUIC_DVLOG(1) << ENDPOINT << "Setting alternative decrypter from level "
-                << alternative_decrypter_level_ << " to " << level;
-  if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
-    decrypter_[alternative_decrypter_level_] = nullptr;
-  }
-  decrypter_[level] = std::move(decrypter);
-  alternative_decrypter_level_ = level;
-  alternative_decrypter_latch_ = latch_once_used;
-}
-
-void QuicFramer::InstallDecrypter(EncryptionLevel level,
-                                  std::unique_ptr<QuicDecrypter> decrypter) {
-  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
-  QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level " << level;
-  decrypter_[level] = std::move(decrypter);
-}
-
-void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
-  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
-  QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level " << level;
-  decrypter_[level] = nullptr;
-}
-
-void QuicFramer::SetKeyUpdateSupportForConnection(bool enabled) {
-  QUIC_DVLOG(1) << ENDPOINT << "SetKeyUpdateSupportForConnection: " << enabled;
-  support_key_update_for_connection_ = enabled;
-}
-
-void QuicFramer::DiscardPreviousOneRttKeys() {
-  QUICHE_DCHECK(support_key_update_for_connection_);
-  QUIC_DVLOG(1) << ENDPOINT << "Discarding previous set of 1-RTT keys";
-  previous_decrypter_ = nullptr;
-}
-
-bool QuicFramer::DoKeyUpdate(KeyUpdateReason reason) {
-  QUICHE_DCHECK(support_key_update_for_connection_);
-  if (!next_decrypter_) {
-    // If key update is locally initiated, next decrypter might not be created
-    // yet.
-    next_decrypter_ = visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-  }
-  std::unique_ptr<QuicEncrypter> next_encrypter =
-      visitor_->CreateCurrentOneRttEncrypter();
-  if (!next_decrypter_ || !next_encrypter) {
-    QUIC_BUG(quic_bug_10850_58) << "Failed to create next crypters";
-    return false;
-  }
-  key_update_performed_ = true;
-  current_key_phase_bit_ = !current_key_phase_bit_;
-  QUIC_DLOG(INFO) << ENDPOINT << "DoKeyUpdate: new current_key_phase_bit_="
-                  << current_key_phase_bit_;
-  current_key_phase_first_received_packet_number_.Clear();
-  previous_decrypter_ = std::move(decrypter_[ENCRYPTION_FORWARD_SECURE]);
-  decrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_decrypter_);
-  encrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_encrypter);
-  switch (reason) {
-    case KeyUpdateReason::kInvalid:
-      QUIC_CODE_COUNT(quic_key_update_invalid);
-      break;
-    case KeyUpdateReason::kRemote:
-      QUIC_CODE_COUNT(quic_key_update_remote);
-      break;
-    case KeyUpdateReason::kLocalForTests:
-      QUIC_CODE_COUNT(quic_key_update_local_for_tests);
-      break;
-    case KeyUpdateReason::kLocalForInteropRunner:
-      QUIC_CODE_COUNT(quic_key_update_local_for_interop_runner);
-      break;
-    case KeyUpdateReason::kLocalAeadConfidentialityLimit:
-      QUIC_CODE_COUNT(quic_key_update_local_aead_confidentiality_limit);
-      break;
-    case KeyUpdateReason::kLocalKeyUpdateLimitOverride:
-      QUIC_CODE_COUNT(quic_key_update_local_limit_override);
-      break;
-  }
-  visitor_->OnKeyUpdate(reason);
-  return true;
-}
-
-QuicPacketCount QuicFramer::PotentialPeerKeyUpdateAttemptCount() const {
-  return potential_peer_key_update_attempt_count_;
-}
-
-const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const {
-  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
-  return decrypter_[level].get();
-}
-
-const QuicDecrypter* QuicFramer::decrypter() const {
-  return decrypter_[decrypter_level_].get();
-}
-
-const QuicDecrypter* QuicFramer::alternative_decrypter() const {
-  if (alternative_decrypter_level_ == NUM_ENCRYPTION_LEVELS) {
-    return nullptr;
-  }
-  return decrypter_[alternative_decrypter_level_].get();
-}
-
-void QuicFramer::SetEncrypter(EncryptionLevel level,
-                              std::unique_ptr<QuicEncrypter> encrypter) {
-  QUICHE_DCHECK_GE(level, 0);
-  QUICHE_DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
-  QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level " << level;
-  encrypter_[level] = std::move(encrypter);
-}
-
-void QuicFramer::RemoveEncrypter(EncryptionLevel level) {
-  QUIC_DVLOG(1) << ENDPOINT << "Removing encrypter of " << level;
-  encrypter_[level] = nullptr;
-}
-
-void QuicFramer::SetInitialObfuscators(QuicConnectionId connection_id) {
-  CrypterPair crypters;
-  CryptoUtils::CreateInitialObfuscators(perspective_, version_, connection_id,
-                                        &crypters);
-  encrypter_[ENCRYPTION_INITIAL] = std::move(crypters.encrypter);
-  decrypter_[ENCRYPTION_INITIAL] = std::move(crypters.decrypter);
-}
-
-size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
-                                  QuicPacketNumber packet_number, size_t ad_len,
-                                  size_t total_len, size_t buffer_len,
-                                  char* buffer) {
-  QUICHE_DCHECK(packet_number.IsInitialized());
-  if (encrypter_[level] == nullptr) {
-    QUIC_BUG(quic_bug_10850_59)
-        << ENDPOINT
-        << "Attempted to encrypt in place without encrypter at level " << level;
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-
-  size_t output_length = 0;
-  if (!encrypter_[level]->EncryptPacket(
-          packet_number.ToUint64(),
-          absl::string_view(buffer, ad_len),  // Associated data
-          absl::string_view(buffer + ad_len,
-                            total_len - ad_len),  // Plaintext
-          buffer + ad_len,                        // Destination buffer
-          &output_length, buffer_len - ad_len)) {
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-  if (version_.HasHeaderProtection() &&
-      !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
-    QUIC_DLOG(ERROR) << "Applying header protection failed.";
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-
-  return ad_len + output_length;
-}
-
-namespace {
-
-const size_t kHPSampleLen = 16;
-
-constexpr bool IsLongHeader(uint8_t type_byte) {
-  return (type_byte & FLAGS_LONG_HEADER) != 0;
-}
-
-}  // namespace
-
-bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, char* buffer,
-                                       size_t buffer_len, size_t ad_len) {
-  QuicDataReader buffer_reader(buffer, buffer_len);
-  QuicDataWriter buffer_writer(buffer_len, buffer);
-  // The sample starts 4 bytes after the start of the packet number.
-  if (ad_len < last_written_packet_number_length_) {
-    return false;
-  }
-  size_t pn_offset = ad_len - last_written_packet_number_length_;
-  // Sample the ciphertext and generate the mask to use for header protection.
-  size_t sample_offset = pn_offset + 4;
-  QuicDataReader sample_reader(buffer, buffer_len);
-  absl::string_view sample;
-  if (!sample_reader.Seek(sample_offset) ||
-      !sample_reader.ReadStringPiece(&sample, kHPSampleLen)) {
-    QUIC_BUG(quic_bug_10850_60)
-        << "Not enough bytes to sample: sample_offset " << sample_offset
-        << ", sample len: " << kHPSampleLen << ", buffer len: " << buffer_len;
-    return false;
-  }
-
-  if (encrypter_[level] == nullptr) {
-    QUIC_BUG(quic_bug_12975_8)
-        << ENDPOINT
-        << "Attempted to apply header protection without encrypter at level "
-        << level << " using " << version_;
-    return false;
-  }
-
-  std::string mask = encrypter_[level]->GenerateHeaderProtectionMask(sample);
-  if (mask.empty()) {
-    QUIC_BUG(quic_bug_10850_61) << "Unable to generate header protection mask.";
-    return false;
-  }
-  QuicDataReader mask_reader(mask.data(), mask.size());
-
-  // Apply the mask to the 4 or 5 least significant bits of the first byte.
-  uint8_t bitmask = 0x1f;
-  uint8_t type_byte;
-  if (!buffer_reader.ReadUInt8(&type_byte)) {
-    return false;
-  }
-  QuicLongHeaderType header_type;
-  if (IsLongHeader(type_byte)) {
-    bitmask = 0x0f;
-    header_type = GetLongHeaderType(type_byte, version_);
-    if (header_type == INVALID_PACKET_TYPE) {
-      return false;
-    }
-  }
-  uint8_t mask_byte;
-  if (!mask_reader.ReadUInt8(&mask_byte) ||
-      !buffer_writer.WriteUInt8(type_byte ^ (mask_byte & bitmask))) {
-    return false;
-  }
-
-  // Adjust |pn_offset| to account for the diversification nonce.
-  if (IsLongHeader(type_byte) && header_type == ZERO_RTT_PROTECTED &&
-      perspective_ == Perspective::IS_SERVER &&
-      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-    if (pn_offset <= kDiversificationNonceSize) {
-      QUIC_BUG(quic_bug_10850_62)
-          << "Expected diversification nonce, but not enough bytes";
-      return false;
-    }
-    pn_offset -= kDiversificationNonceSize;
-  }
-  // Advance the reader and writer to the packet number. Both the reader and
-  // writer have each read/written one byte.
-  if (!buffer_writer.Seek(pn_offset - 1) ||
-      !buffer_reader.Seek(pn_offset - 1)) {
-    return false;
-  }
-  // Apply the rest of the mask to the packet number.
-  for (size_t i = 0; i < last_written_packet_number_length_; ++i) {
-    uint8_t buffer_byte;
-    uint8_t mask_byte;
-    if (!mask_reader.ReadUInt8(&mask_byte) ||
-        !buffer_reader.ReadUInt8(&buffer_byte) ||
-        !buffer_writer.WriteUInt8(buffer_byte ^ mask_byte)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader,
-                                        const QuicEncryptedPacket& packet,
-                                        QuicPacketHeader* header,
-                                        uint64_t* full_packet_number,
-                                        std::vector<char>* associated_data) {
-  EncryptionLevel expected_decryption_level = GetEncryptionLevel(*header);
-  QuicDecrypter* decrypter = decrypter_[expected_decryption_level].get();
-  if (decrypter == nullptr) {
-    QUIC_DVLOG(1)
-        << ENDPOINT
-        << "No decrypter available for removing header protection at level "
-        << expected_decryption_level;
-    return false;
-  }
-
-  bool has_diversification_nonce =
-      header->form == IETF_QUIC_LONG_HEADER_PACKET &&
-      header->long_packet_type == ZERO_RTT_PROTECTED &&
-      perspective_ == Perspective::IS_CLIENT &&
-      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO;
-
-  // Read a sample from the ciphertext and compute the mask to use for header
-  // protection.
-  absl::string_view remaining_packet = reader->PeekRemainingPayload();
-  QuicDataReader sample_reader(remaining_packet);
-
-  // The sample starts 4 bytes after the start of the packet number.
-  absl::string_view pn;
-  if (!sample_reader.ReadStringPiece(&pn, 4)) {
-    QUIC_DVLOG(1) << "Not enough data to sample";
-    return false;
-  }
-  if (has_diversification_nonce) {
-    // In Google QUIC, the diversification nonce comes between the packet number
-    // and the sample.
-    if (!sample_reader.Seek(kDiversificationNonceSize)) {
-      QUIC_DVLOG(1) << "No diversification nonce to skip over";
-      return false;
-    }
-  }
-  std::string mask = decrypter->GenerateHeaderProtectionMask(&sample_reader);
-  QuicDataReader mask_reader(mask.data(), mask.size());
-  if (mask.empty()) {
-    QUIC_DVLOG(1) << "Failed to compute mask";
-    return false;
-  }
-
-  // Unmask the rest of the type byte.
-  uint8_t bitmask = 0x1f;
-  if (IsLongHeader(header->type_byte)) {
-    bitmask = 0x0f;
-  }
-  uint8_t mask_byte;
-  if (!mask_reader.ReadUInt8(&mask_byte)) {
-    QUIC_DVLOG(1) << "No first byte to read from mask";
-    return false;
-  }
-  header->type_byte ^= (mask_byte & bitmask);
-
-  // Compute the packet number length.
-  header->packet_number_length =
-      static_cast<QuicPacketNumberLength>((header->type_byte & 0x03) + 1);
-
-  char pn_buffer[IETF_MAX_PACKET_NUMBER_LENGTH] = {};
-  QuicDataWriter pn_writer(ABSL_ARRAYSIZE(pn_buffer), pn_buffer);
-
-  // Read the (protected) packet number from the reader and unmask the packet
-  // number.
-  for (size_t i = 0; i < header->packet_number_length; ++i) {
-    uint8_t protected_pn_byte, mask_byte;
-    if (!mask_reader.ReadUInt8(&mask_byte) ||
-        !reader->ReadUInt8(&protected_pn_byte) ||
-        !pn_writer.WriteUInt8(protected_pn_byte ^ mask_byte)) {
-      QUIC_DVLOG(1) << "Failed to unmask packet number";
-      return false;
-    }
-  }
-  QuicDataReader packet_number_reader(pn_writer.data(), pn_writer.length());
-  QuicPacketNumber base_packet_number;
-  if (supports_multiple_packet_number_spaces_) {
-    PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
-    if (pn_space == NUM_PACKET_NUMBER_SPACES) {
-      return false;
-    }
-    base_packet_number = largest_decrypted_packet_numbers_[pn_space];
-  } else {
-    base_packet_number = largest_packet_number_;
-  }
-  if (!ProcessAndCalculatePacketNumber(
-          &packet_number_reader, header->packet_number_length,
-          base_packet_number, full_packet_number)) {
-    return false;
-  }
-
-  // Get the associated data, and apply the same unmasking operations to it.
-  absl::string_view ad = GetAssociatedDataFromEncryptedPacket(
-      version_.transport_version, packet,
-      GetIncludedDestinationConnectionIdLength(*header),
-      GetIncludedSourceConnectionIdLength(*header), header->version_flag,
-      has_diversification_nonce, header->packet_number_length,
-      header->retry_token_length_length, header->retry_token.length(),
-      header->length_length);
-  *associated_data = std::vector<char>(ad.begin(), ad.end());
-  QuicDataWriter ad_writer(associated_data->size(), associated_data->data());
-
-  // Apply the unmasked type byte and packet number to |associated_data|.
-  if (!ad_writer.WriteUInt8(header->type_byte)) {
-    return false;
-  }
-  // Put the packet number at the end of the AD, or if there's a diversification
-  // nonce, before that (which is at the end of the AD).
-  size_t seek_len = ad_writer.remaining() - header->packet_number_length;
-  if (has_diversification_nonce) {
-    seek_len -= kDiversificationNonceSize;
-  }
-  if (!ad_writer.Seek(seek_len) ||
-      !ad_writer.WriteBytes(pn_writer.data(), pn_writer.length())) {
-    QUIC_DVLOG(1) << "Failed to apply unmasking operations to AD";
-    return false;
-  }
-
-  return true;
-}
-
-size_t QuicFramer::EncryptPayload(EncryptionLevel level,
-                                  QuicPacketNumber packet_number,
-                                  const QuicPacket& packet, char* buffer,
-                                  size_t buffer_len) {
-  QUICHE_DCHECK(packet_number.IsInitialized());
-  if (encrypter_[level] == nullptr) {
-    QUIC_BUG(quic_bug_10850_63)
-        << ENDPOINT << "Attempted to encrypt without encrypter at level "
-        << level;
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-
-  absl::string_view associated_data =
-      packet.AssociatedData(version_.transport_version);
-  // Copy in the header, because the encrypter only populates the encrypted
-  // plaintext content.
-  const size_t ad_len = associated_data.length();
-  if (packet.length() < ad_len) {
-    QUIC_BUG(quic_bug_10850_64)
-        << ENDPOINT << "packet is shorter than associated data length. version:"
-        << version() << ", packet length:" << packet.length()
-        << ", associated data length:" << ad_len;
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-  memmove(buffer, associated_data.data(), ad_len);
-  // Encrypt the plaintext into the buffer.
-  size_t output_length = 0;
-  if (!encrypter_[level]->EncryptPacket(
-          packet_number.ToUint64(), associated_data,
-          packet.Plaintext(version_.transport_version), buffer + ad_len,
-          &output_length, buffer_len - ad_len)) {
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-  if (version_.HasHeaderProtection() &&
-      !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
-    QUIC_DLOG(ERROR) << "Applying header protection failed.";
-    RaiseError(QUIC_ENCRYPTION_FAILURE);
-    return 0;
-  }
-
-  return ad_len + output_length;
-}
-
-size_t QuicFramer::GetCiphertextSize(EncryptionLevel level,
-                                     size_t plaintext_size) const {
-  if (encrypter_[level] == nullptr) {
-    QUIC_BUG(quic_bug_10850_65)
-        << ENDPOINT
-        << "Attempted to get ciphertext size without encrypter at level "
-        << level << " using " << version_;
-    return plaintext_size;
-  }
-  return encrypter_[level]->GetCiphertextSize(plaintext_size);
-}
-
-size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
-  // In order to keep the code simple, we don't have the current encryption
-  // level to hand. Both the NullEncrypter and AES-GCM have a tag length of 12.
-  size_t min_plaintext_size = ciphertext_size;
-
-  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
-    if (encrypter_[i] != nullptr) {
-      size_t size = encrypter_[i]->GetMaxPlaintextSize(ciphertext_size);
-      if (size < min_plaintext_size) {
-        min_plaintext_size = size;
-      }
-    }
-  }
-
-  return min_plaintext_size;
-}
-
-QuicPacketCount QuicFramer::GetOneRttEncrypterConfidentialityLimit() const {
-  if (!encrypter_[ENCRYPTION_FORWARD_SECURE]) {
-    QUIC_BUG(quic_bug_10850_66) << "1-RTT encrypter not set";
-    return 0;
-  }
-  return encrypter_[ENCRYPTION_FORWARD_SECURE]->GetConfidentialityLimit();
-}
-
-bool QuicFramer::DecryptPayload(size_t udp_packet_length,
-                                absl::string_view encrypted,
-                                absl::string_view associated_data,
-                                const QuicPacketHeader& header,
-                                char* decrypted_buffer, size_t buffer_length,
-                                size_t* decrypted_length,
-                                EncryptionLevel* decrypted_level) {
-  if (!EncryptionLevelIsValid(decrypter_level_)) {
-    QUIC_BUG(quic_bug_10850_67)
-        << "Attempted to decrypt with bad decrypter_level_";
-    return false;
-  }
-  EncryptionLevel level = decrypter_level_;
-  QuicDecrypter* decrypter = decrypter_[level].get();
-  QuicDecrypter* alternative_decrypter = nullptr;
-  bool key_phase_parsed = false;
-  bool key_phase;
-  bool attempt_key_update = false;
-  if (version().KnowsWhichDecrypterToUse()) {
-    if (header.form == GOOGLE_QUIC_PACKET) {
-      QUIC_BUG(quic_bug_10850_68)
-          << "Attempted to decrypt GOOGLE_QUIC_PACKET with a version that "
-             "knows which decrypter to use";
-      return false;
-    }
-    level = GetEncryptionLevel(header);
-    if (!EncryptionLevelIsValid(level)) {
-      QUIC_BUG(quic_bug_10850_69) << "Attempted to decrypt with bad level";
-      return false;
-    }
-    decrypter = decrypter_[level].get();
-    if (decrypter == nullptr) {
-      return false;
-    }
-    if (level == ENCRYPTION_ZERO_RTT &&
-        perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) {
-      decrypter->SetDiversificationNonce(*header.nonce);
-    }
-    if (support_key_update_for_connection_ &&
-        header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
-      QUICHE_DCHECK(version().UsesTls());
-      QUICHE_DCHECK_EQ(level, ENCRYPTION_FORWARD_SECURE);
-      key_phase = (header.type_byte & FLAGS_KEY_PHASE_BIT) != 0;
-      key_phase_parsed = true;
-      QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
-                    << " received key_phase=" << key_phase
-                    << " current_key_phase_bit_=" << current_key_phase_bit_;
-      if (key_phase != current_key_phase_bit_) {
-        if ((current_key_phase_first_received_packet_number_.IsInitialized() &&
-             header.packet_number >
-                 current_key_phase_first_received_packet_number_) ||
-            (!current_key_phase_first_received_packet_number_.IsInitialized() &&
-             !key_update_performed_)) {
-          if (!next_decrypter_) {
-            next_decrypter_ =
-                visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-            if (!next_decrypter_) {
-              QUIC_BUG(quic_bug_10850_70) << "Failed to create next_decrypter";
-              return false;
-            }
-          }
-          QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
-                        << " attempt_key_update=true";
-          attempt_key_update = true;
-          potential_peer_key_update_attempt_count_++;
-          decrypter = next_decrypter_.get();
-        } else {
-          if (previous_decrypter_) {
-            QUIC_DVLOG(1) << ENDPOINT
-                          << "trying previous_decrypter_ for packet "
-                          << header.packet_number;
-            decrypter = previous_decrypter_.get();
-          } else {
-            QUIC_DVLOG(1) << ENDPOINT << "dropping packet "
-                          << header.packet_number << " with old key phase";
-            return false;
-          }
-        }
-      }
-    }
-  } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
-    if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
-      QUIC_BUG(quic_bug_10850_71)
-          << "Attempted to decrypt with bad alternative_decrypter_level_";
-      return false;
-    }
-    alternative_decrypter = decrypter_[alternative_decrypter_level_].get();
-  }
-
-  if (decrypter == nullptr) {
-    QUIC_BUG(quic_bug_10850_72)
-        << "Attempting to decrypt without decrypter, encryption level:" << level
-        << " version:" << version();
-    return false;
-  }
-
-  bool success = decrypter->DecryptPacket(
-      header.packet_number.ToUint64(), associated_data, encrypted,
-      decrypted_buffer, decrypted_length, buffer_length);
-  if (success) {
-    visitor_->OnDecryptedPacket(udp_packet_length, level);
-    if (level == ENCRYPTION_ZERO_RTT &&
-        current_key_phase_first_received_packet_number_.IsInitialized() &&
-        header.packet_number >
-            current_key_phase_first_received_packet_number_) {
-      set_detailed_error(absl::StrCat(
-          "Decrypted a 0-RTT packet with a packet number ",
-          header.packet_number.ToString(),
-          " which is higher than a 1-RTT packet number ",
-          current_key_phase_first_received_packet_number_.ToString()));
-      return RaiseError(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
-    }
-    *decrypted_level = level;
-    potential_peer_key_update_attempt_count_ = 0;
-    if (attempt_key_update) {
-      if (!DoKeyUpdate(KeyUpdateReason::kRemote)) {
-        set_detailed_error("Key update failed due to internal error");
-        return RaiseError(QUIC_INTERNAL_ERROR);
-      }
-      QUICHE_DCHECK_EQ(current_key_phase_bit_, key_phase);
-    }
-    if (key_phase_parsed &&
-        !current_key_phase_first_received_packet_number_.IsInitialized() &&
-        key_phase == current_key_phase_bit_) {
-      // Set packet number for current key phase if it hasn't been initialized
-      // yet. This is set outside of attempt_key_update since the key update
-      // may have been initiated locally, and in that case we don't know yet
-      // which packet number from the remote side to use until we receive a
-      // packet with that phase.
-      QUIC_DVLOG(1) << ENDPOINT
-                    << "current_key_phase_first_received_packet_number_ = "
-                    << header.packet_number;
-      current_key_phase_first_received_packet_number_ = header.packet_number;
-      visitor_->OnDecryptedFirstPacketInKeyPhase();
-    }
-  } else if (alternative_decrypter != nullptr) {
-    if (header.nonce != nullptr) {
-      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-      alternative_decrypter->SetDiversificationNonce(*header.nonce);
-    }
-    bool try_alternative_decryption = true;
-    if (alternative_decrypter_level_ == ENCRYPTION_ZERO_RTT) {
-      if (perspective_ == Perspective::IS_CLIENT) {
-        if (header.nonce == nullptr) {
-          // Can not use INITIAL decryption without a diversification nonce.
-          try_alternative_decryption = false;
-        }
-      } else {
-        QUICHE_DCHECK(header.nonce == nullptr);
-      }
-    }
-
-    if (try_alternative_decryption) {
-      success = alternative_decrypter->DecryptPacket(
-          header.packet_number.ToUint64(), associated_data, encrypted,
-          decrypted_buffer, decrypted_length, buffer_length);
-    }
-    if (success) {
-      visitor_->OnDecryptedPacket(udp_packet_length,
-                                  alternative_decrypter_level_);
-      *decrypted_level = decrypter_level_;
-      if (alternative_decrypter_latch_) {
-        if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
-          QUIC_BUG(quic_bug_10850_73)
-              << "Attempted to latch alternate decrypter with bad "
-                 "alternative_decrypter_level_";
-          return false;
-        }
-        // Switch to the alternative decrypter and latch so that we cannot
-        // switch back.
-        decrypter_level_ = alternative_decrypter_level_;
-        alternative_decrypter_level_ = NUM_ENCRYPTION_LEVELS;
-      } else {
-        // Switch the alternative decrypter so that we use it first next time.
-        EncryptionLevel level = alternative_decrypter_level_;
-        alternative_decrypter_level_ = decrypter_level_;
-        decrypter_level_ = level;
-      }
-    }
-  }
-
-  if (!success) {
-    QUIC_DVLOG(1) << ENDPOINT << "DecryptPacket failed for: " << header;
-    return false;
-  }
-
-  return true;
-}
-
-size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) {
-  // Type byte, largest_acked, and delay_time are straight-forward.
-  size_t ack_frame_size = kQuicFrameTypeSize;
-  QuicPacketNumber largest_acked = LargestAcked(frame);
-  ack_frame_size += QuicDataWriter::GetVarInt62Len(largest_acked.ToUint64());
-  uint64_t ack_delay_time_us;
-  ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
-  ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
-  ack_frame_size += QuicDataWriter::GetVarInt62Len(ack_delay_time_us);
-
-  if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
-    QUIC_BUG(quic_bug_10850_74) << "Malformed ack frame";
-    // ACK frame serialization will fail and connection will be closed.
-    return ack_frame_size;
-  }
-
-  // Ack block count.
-  ack_frame_size +=
-      QuicDataWriter::GetVarInt62Len(frame.packets.NumIntervals() - 1);
-
-  // First Ack range.
-  auto iter = frame.packets.rbegin();
-  ack_frame_size += QuicDataWriter::GetVarInt62Len(iter->Length() - 1);
-  QuicPacketNumber previous_smallest = iter->min();
-  ++iter;
-
-  // Ack blocks.
-  for (; iter != frame.packets.rend(); ++iter) {
-    const uint64_t gap = previous_smallest - iter->max() - 1;
-    const uint64_t ack_range = iter->Length() - 1;
-    ack_frame_size += (QuicDataWriter::GetVarInt62Len(gap) +
-                       QuicDataWriter::GetVarInt62Len(ack_range));
-    previous_smallest = iter->min();
-  }
-
-  if (UseIetfAckWithReceiveTimestamp(frame)) {
-    ack_frame_size += GetIetfAckFrameTimestampSize(frame);
-  } else if (frame.ecn_counters_populated &&
-             (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
-    // ECN counts.
-    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_0_count);
-    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_1_count);
-    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count);
-  }
-
-  return ack_frame_size;
-}
-
-size_t QuicFramer::GetIetfAckFrameTimestampSize(const QuicAckFrame& ack) {
-  QUICHE_DCHECK(!ack.received_packet_times.empty());
-  std::string detailed_error;
-  absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
-      GetAckTimestampRanges(ack, detailed_error);
-  if (!detailed_error.empty()) {
-    return 0;
-  }
-
-  int64_t size =
-      FrameAckTimestampRanges(ack, timestamp_ranges, /*writer=*/nullptr);
-  return std::max<int64_t>(0, size);
-}
-
-size_t QuicFramer::GetAckFrameSize(
-    const QuicAckFrame& ack, QuicPacketNumberLength /*packet_number_length*/) {
-  QUICHE_DCHECK(!ack.packets.Empty());
-  size_t ack_size = 0;
-
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    return GetIetfAckFrameSize(ack);
-  }
-  AckFrameInfo ack_info = GetAckFrameInfo(ack);
-  QuicPacketNumberLength ack_block_length =
-      GetMinPacketNumberLength(QuicPacketNumber(ack_info.max_block_length));
-
-  ack_size = GetMinAckFrameSize(version_.transport_version, ack,
-                                local_ack_delay_exponent_,
-                                UseIetfAckWithReceiveTimestamp(ack));
-  // First ack block length.
-  ack_size += ack_block_length;
-  if (ack_info.num_ack_blocks != 0) {
-    ack_size += kNumberOfAckBlocksSize;
-    ack_size += std::min(ack_info.num_ack_blocks, kMaxAckBlocks) *
-                (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
-  }
-
-  // Include timestamps.
-  if (process_timestamps_) {
-    ack_size += GetAckFrameTimeStampSize(ack);
-  }
-
-  return ack_size;
-}
-
-size_t QuicFramer::GetAckFrameTimeStampSize(const QuicAckFrame& ack) {
-  if (ack.received_packet_times.empty()) {
-    return 0;
-  }
-
-  return kQuicNumTimestampsLength + kQuicFirstTimestampLength +
-         (kQuicTimestampLength + kQuicTimestampPacketNumberGapLength) *
-             (ack.received_packet_times.size() - 1);
-}
-
-size_t QuicFramer::ComputeFrameLength(
-    const QuicFrame& frame, bool last_frame_in_packet,
-    QuicPacketNumberLength packet_number_length) {
-  switch (frame.type) {
-    case STREAM_FRAME:
-      return GetMinStreamFrameSize(
-                 version_.transport_version, frame.stream_frame.stream_id,
-                 frame.stream_frame.offset, last_frame_in_packet,
-                 frame.stream_frame.data_length) +
-             frame.stream_frame.data_length;
-    case CRYPTO_FRAME:
-      return GetMinCryptoFrameSize(frame.crypto_frame->offset,
-                                   frame.crypto_frame->data_length) +
-             frame.crypto_frame->data_length;
-    case ACK_FRAME: {
-      return GetAckFrameSize(*frame.ack_frame, packet_number_length);
-    }
-    case STOP_WAITING_FRAME:
-      return GetStopWaitingFrameSize(packet_number_length);
-    case MTU_DISCOVERY_FRAME:
-      // MTU discovery frames are serialized as ping frames.
-      return kQuicFrameTypeSize;
-    case MESSAGE_FRAME:
-      return GetMessageFrameSize(version_.transport_version,
-                                 last_frame_in_packet,
-                                 frame.message_frame->message_length);
-    case PADDING_FRAME:
-      QUICHE_DCHECK(false);
-      return 0;
-    default:
-      return GetRetransmittableControlFrameSize(version_.transport_version,
-                                                frame);
-  }
-}
-
-bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
-                                bool last_frame_in_packet,
-                                QuicDataWriter* writer) {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    return AppendIetfFrameType(frame, last_frame_in_packet, writer);
-  }
-  uint8_t type_byte = 0;
-  switch (frame.type) {
-    case STREAM_FRAME:
-      type_byte =
-          GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
-      break;
-    case ACK_FRAME:
-      return true;
-    case MTU_DISCOVERY_FRAME:
-      type_byte = static_cast<uint8_t>(PING_FRAME);
-      break;
-    case NEW_CONNECTION_ID_FRAME:
-      set_detailed_error(
-          "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case RETIRE_CONNECTION_ID_FRAME:
-      set_detailed_error(
-          "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case NEW_TOKEN_FRAME:
-      set_detailed_error(
-          "Attempt to append NEW_TOKEN frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case MAX_STREAMS_FRAME:
-      set_detailed_error(
-          "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case STREAMS_BLOCKED_FRAME:
-      set_detailed_error(
-          "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case PATH_RESPONSE_FRAME:
-      set_detailed_error(
-          "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case PATH_CHALLENGE_FRAME:
-      set_detailed_error(
-          "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case STOP_SENDING_FRAME:
-      set_detailed_error(
-          "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case MESSAGE_FRAME:
-      return true;
-
-    default:
-      type_byte = static_cast<uint8_t>(frame.type);
-      break;
-  }
-
-  return writer->WriteUInt8(type_byte);
-}
-
-bool QuicFramer::AppendIetfFrameType(const QuicFrame& frame,
-                                     bool last_frame_in_packet,
-                                     QuicDataWriter* writer) {
-  uint8_t type_byte = 0;
-  switch (frame.type) {
-    case PADDING_FRAME:
-      type_byte = IETF_PADDING;
-      break;
-    case RST_STREAM_FRAME:
-      type_byte = IETF_RST_STREAM;
-      break;
-    case CONNECTION_CLOSE_FRAME:
-      switch (frame.connection_close_frame->close_type) {
-        case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
-          type_byte = IETF_APPLICATION_CLOSE;
-          break;
-        case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
-          type_byte = IETF_CONNECTION_CLOSE;
-          break;
-        default:
-          set_detailed_error(absl::StrCat(
-              "Invalid QuicConnectionCloseFrame type: ",
-              static_cast<int>(frame.connection_close_frame->close_type)));
-          return RaiseError(QUIC_INTERNAL_ERROR);
-      }
-      break;
-    case GOAWAY_FRAME:
-      set_detailed_error(
-          "Attempt to create non-IETF QUIC GOAWAY frame in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case WINDOW_UPDATE_FRAME:
-      // Depending on whether there is a stream ID or not, will be either a
-      // MAX_STREAM_DATA frame or a MAX_DATA frame.
-      if (frame.window_update_frame.stream_id ==
-          QuicUtils::GetInvalidStreamId(transport_version())) {
-        type_byte = IETF_MAX_DATA;
-      } else {
-        type_byte = IETF_MAX_STREAM_DATA;
-      }
-      break;
-    case BLOCKED_FRAME:
-      if (frame.blocked_frame.stream_id ==
-          QuicUtils::GetInvalidStreamId(transport_version())) {
-        type_byte = IETF_DATA_BLOCKED;
-      } else {
-        type_byte = IETF_STREAM_DATA_BLOCKED;
-      }
-      break;
-    case STOP_WAITING_FRAME:
-      set_detailed_error(
-          "Attempt to append type byte of STOP WAITING frame in IETF QUIC.");
-      return RaiseError(QUIC_INTERNAL_ERROR);
-    case PING_FRAME:
-      type_byte = IETF_PING;
-      break;
-    case STREAM_FRAME:
-      type_byte =
-          GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
-      break;
-    case ACK_FRAME:
-      // Do nothing here, AppendIetfAckFrameAndTypeByte() will put the type byte
-      // in the buffer.
-      return true;
-    case MTU_DISCOVERY_FRAME:
-      // The path MTU discovery frame is encoded as a PING frame on the wire.
-      type_byte = IETF_PING;
-      break;
-    case NEW_CONNECTION_ID_FRAME:
-      type_byte = IETF_NEW_CONNECTION_ID;
-      break;
-    case RETIRE_CONNECTION_ID_FRAME:
-      type_byte = IETF_RETIRE_CONNECTION_ID;
-      break;
-    case NEW_TOKEN_FRAME:
-      type_byte = IETF_NEW_TOKEN;
-      break;
-    case MAX_STREAMS_FRAME:
-      if (frame.max_streams_frame.unidirectional) {
-        type_byte = IETF_MAX_STREAMS_UNIDIRECTIONAL;
-      } else {
-        type_byte = IETF_MAX_STREAMS_BIDIRECTIONAL;
-      }
-      break;
-    case STREAMS_BLOCKED_FRAME:
-      if (frame.streams_blocked_frame.unidirectional) {
-        type_byte = IETF_STREAMS_BLOCKED_UNIDIRECTIONAL;
-      } else {
-        type_byte = IETF_STREAMS_BLOCKED_BIDIRECTIONAL;
-      }
-      break;
-    case PATH_RESPONSE_FRAME:
-      type_byte = IETF_PATH_RESPONSE;
-      break;
-    case PATH_CHALLENGE_FRAME:
-      type_byte = IETF_PATH_CHALLENGE;
-      break;
-    case STOP_SENDING_FRAME:
-      type_byte = IETF_STOP_SENDING;
-      break;
-    case MESSAGE_FRAME:
-      return true;
-    case CRYPTO_FRAME:
-      type_byte = IETF_CRYPTO;
-      break;
-    case HANDSHAKE_DONE_FRAME:
-      type_byte = IETF_HANDSHAKE_DONE;
-      break;
-    case ACK_FREQUENCY_FRAME:
-      type_byte = IETF_ACK_FREQUENCY;
-      break;
-    default:
-      QUIC_BUG(quic_bug_10850_75)
-          << "Attempt to generate a frame type for an unsupported value: "
-          << frame.type;
-      return false;
-  }
-  return writer->WriteVarInt62(type_byte);
-}
-
-// static
-bool QuicFramer::AppendPacketNumber(QuicPacketNumberLength packet_number_length,
-                                    QuicPacketNumber packet_number,
-                                    QuicDataWriter* writer) {
-  QUICHE_DCHECK(packet_number.IsInitialized());
-  if (!IsValidPacketNumberLength(packet_number_length)) {
-    QUIC_BUG(quic_bug_10850_76)
-        << "Invalid packet_number_length: " << packet_number_length;
-    return false;
-  }
-  return writer->WriteBytesToUInt64(packet_number_length,
-                                    packet_number.ToUint64());
-}
-
-// static
-bool QuicFramer::AppendStreamId(size_t stream_id_length, QuicStreamId stream_id,
-                                QuicDataWriter* writer) {
-  if (stream_id_length == 0 || stream_id_length > 4) {
-    QUIC_BUG(quic_bug_10850_77)
-        << "Invalid stream_id_length: " << stream_id_length;
-    return false;
-  }
-  return writer->WriteBytesToUInt64(stream_id_length, stream_id);
-}
-
-// static
-bool QuicFramer::AppendStreamOffset(size_t offset_length,
-                                    QuicStreamOffset offset,
-                                    QuicDataWriter* writer) {
-  if (offset_length == 1 || offset_length > 8) {
-    QUIC_BUG(quic_bug_10850_78)
-        << "Invalid stream_offset_length: " << offset_length;
-    return false;
-  }
-
-  return writer->WriteBytesToUInt64(offset_length, offset);
-}
-
-// static
-bool QuicFramer::AppendAckBlock(uint8_t gap,
-                                QuicPacketNumberLength length_length,
-                                uint64_t length, QuicDataWriter* writer) {
-  if (length == 0) {
-    if (!IsValidPacketNumberLength(length_length)) {
-      QUIC_BUG(quic_bug_10850_79)
-          << "Invalid packet_number_length: " << length_length;
-      return false;
-    }
-    return writer->WriteUInt8(gap) &&
-           writer->WriteBytesToUInt64(length_length, length);
-  }
-  return writer->WriteUInt8(gap) &&
-         AppendPacketNumber(length_length, QuicPacketNumber(length), writer);
-}
-
-bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
-                                   bool no_stream_frame_length,
-                                   QuicDataWriter* writer) {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    return AppendIetfStreamFrame(frame, no_stream_frame_length, writer);
-  }
-  if (!AppendStreamId(GetStreamIdSize(frame.stream_id), frame.stream_id,
-                      writer)) {
-    QUIC_BUG(quic_bug_10850_80) << "Writing stream id size failed.";
-    return false;
-  }
-  if (!AppendStreamOffset(GetStreamOffsetSize(frame.offset), frame.offset,
-                          writer)) {
-    QUIC_BUG(quic_bug_10850_81) << "Writing offset size failed.";
-    return false;
-  }
-  if (!no_stream_frame_length) {
-    static_assert(
-        std::numeric_limits<decltype(frame.data_length)>::max() <=
-            std::numeric_limits<uint16_t>::max(),
-        "If frame.data_length can hold more than a uint16_t than we need to "
-        "check that frame.data_length <= std::numeric_limits<uint16_t>::max()");
-    if (!writer->WriteUInt16(static_cast<uint16_t>(frame.data_length))) {
-      QUIC_BUG(quic_bug_10850_82) << "Writing stream frame length failed";
-      return false;
-    }
-  }
-
-  if (data_producer_ != nullptr) {
-    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
-    if (frame.data_length == 0) {
-      return true;
-    }
-    if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
-                                        frame.data_length,
-                                        writer) != WRITE_SUCCESS) {
-      QUIC_BUG(quic_bug_10850_83) << "Writing frame data failed.";
-      return false;
-    }
-    return true;
-  }
-
-  if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
-    QUIC_BUG(quic_bug_10850_84) << "Writing frame data failed.";
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendNewTokenFrame(const QuicNewTokenFrame& frame,
-                                     QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.token.length()))) {
-    set_detailed_error("Writing token length failed.");
-    return false;
-  }
-  if (!writer->WriteBytes(frame.token.data(), frame.token.length())) {
-    set_detailed_error("Writing token buffer failed.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessNewTokenFrame(QuicDataReader* reader,
-                                      QuicNewTokenFrame* frame) {
-  uint64_t length;
-  if (!reader->ReadVarInt62(&length)) {
-    set_detailed_error("Unable to read new token length.");
-    return false;
-  }
-  if (length > kMaxNewTokenTokenLength) {
-    set_detailed_error("Token length larger than maximum.");
-    return false;
-  }
-
-  // TODO(ianswett): Don't use absl::string_view as an intermediary.
-  absl::string_view data;
-  if (!reader->ReadStringPiece(&data, length)) {
-    set_detailed_error("Unable to read new token data.");
-    return false;
-  }
-  frame->token = std::string(data);
-  return true;
-}
-
-// Add a new ietf-format stream frame.
-// Bits controlling whether there is a frame-length and frame-offset
-// are in the QuicStreamFrame.
-bool QuicFramer::AppendIetfStreamFrame(const QuicStreamFrame& frame,
-                                       bool last_frame_in_packet,
-                                       QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
-    set_detailed_error("Writing stream id failed.");
-    return false;
-  }
-
-  if (frame.offset != 0) {
-    if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
-      set_detailed_error("Writing data offset failed.");
-      return false;
-    }
-  }
-
-  if (!last_frame_in_packet) {
-    if (!writer->WriteVarInt62(frame.data_length)) {
-      set_detailed_error("Writing data length failed.");
-      return false;
-    }
-  }
-
-  if (frame.data_length == 0) {
-    return true;
-  }
-  if (data_producer_ == nullptr) {
-    if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
-      set_detailed_error("Writing frame data failed.");
-      return false;
-    }
-  } else {
-    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
-
-    if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
-                                        frame.data_length,
-                                        writer) != WRITE_SUCCESS) {
-      set_detailed_error("Writing frame data from producer failed.");
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicFramer::AppendCryptoFrame(const QuicCryptoFrame& frame,
-                                   QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
-    set_detailed_error("Writing data offset failed.");
-    return false;
-  }
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.data_length))) {
-    set_detailed_error("Writing data length failed.");
-    return false;
-  }
-  if (data_producer_ == nullptr) {
-    if (frame.data_buffer == nullptr ||
-        !writer->WriteBytes(frame.data_buffer, frame.data_length)) {
-      set_detailed_error("Writing frame data failed.");
-      return false;
-    }
-  } else {
-    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
-    if (!data_producer_->WriteCryptoData(frame.level, frame.offset,
-                                         frame.data_length, writer)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicFramer::AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
-                                         QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.sequence_number)) {
-    set_detailed_error("Writing sequence number failed.");
-    return false;
-  }
-  if (!writer->WriteVarInt62(frame.packet_tolerance)) {
-    set_detailed_error("Writing packet tolerance failed.");
-    return false;
-  }
-  if (!writer->WriteVarInt62(
-          static_cast<uint64_t>(frame.max_ack_delay.ToMicroseconds()))) {
-    set_detailed_error("Writing max_ack_delay_us failed.");
-    return false;
-  }
-  if (!writer->WriteUInt8(static_cast<uint8_t>(frame.ignore_order))) {
-    set_detailed_error("Writing ignore_order failed.");
-    return false;
-  }
-
-  return true;
-}
-
-void QuicFramer::set_version(const ParsedQuicVersion version) {
-  QUICHE_DCHECK(IsSupportedVersion(version))
-      << ParsedQuicVersionToString(version);
-  version_ = version;
-}
-
-bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
-                                           QuicDataWriter* writer) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return AppendIetfAckFrameAndTypeByte(frame, writer);
-  }
-
-  const AckFrameInfo new_ack_info = GetAckFrameInfo(frame);
-  QuicPacketNumber largest_acked = LargestAcked(frame);
-  QuicPacketNumberLength largest_acked_length =
-      GetMinPacketNumberLength(largest_acked);
-  QuicPacketNumberLength ack_block_length =
-      GetMinPacketNumberLength(QuicPacketNumber(new_ack_info.max_block_length));
-  // Calculate available bytes for timestamps and ack blocks.
-  int32_t available_timestamp_and_ack_block_bytes =
-      writer->capacity() - writer->length() - ack_block_length -
-      GetMinAckFrameSize(version_.transport_version, frame,
-                         local_ack_delay_exponent_,
-                         UseIetfAckWithReceiveTimestamp(frame)) -
-      (new_ack_info.num_ack_blocks != 0 ? kNumberOfAckBlocksSize : 0);
-  QUICHE_DCHECK_LE(0, available_timestamp_and_ack_block_bytes);
-
-  uint8_t type_byte = 0;
-  SetBit(&type_byte, new_ack_info.num_ack_blocks != 0,
-         kQuicHasMultipleAckBlocksOffset);
-
-  SetBits(&type_byte, GetPacketNumberFlags(largest_acked_length),
-          kQuicSequenceNumberLengthNumBits, kLargestAckedOffset);
-
-  SetBits(&type_byte, GetPacketNumberFlags(ack_block_length),
-          kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset);
-
-  type_byte |= kQuicFrameTypeAckMask;
-
-  if (!writer->WriteUInt8(type_byte)) {
-    return false;
-  }
-
-  size_t max_num_ack_blocks = available_timestamp_and_ack_block_bytes /
-                              (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
-
-  // Number of ack blocks.
-  size_t num_ack_blocks =
-      std::min(new_ack_info.num_ack_blocks, max_num_ack_blocks);
-  if (num_ack_blocks > std::numeric_limits<uint8_t>::max()) {
-    num_ack_blocks = std::numeric_limits<uint8_t>::max();
-  }
-
-  // Largest acked.
-  if (!AppendPacketNumber(largest_acked_length, largest_acked, writer)) {
-    return false;
-  }
-
-  // Largest acked delta time.
-  uint64_t ack_delay_time_us = kUFloat16MaxValue;
-  if (!frame.ack_delay_time.IsInfinite()) {
-    QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
-    ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
-  }
-  if (!writer->WriteUFloat16(ack_delay_time_us)) {
-    return false;
-  }
-
-  if (num_ack_blocks > 0) {
-    if (!writer->WriteBytes(&num_ack_blocks, 1)) {
-      return false;
-    }
-  }
-
-  // First ack block length.
-  if (!AppendPacketNumber(ack_block_length,
-                          QuicPacketNumber(new_ack_info.first_block_length),
-                          writer)) {
-    return false;
-  }
-
-  // Ack blocks.
-  if (num_ack_blocks > 0) {
-    size_t num_ack_blocks_written = 0;
-    // Append, in descending order from the largest ACKed packet, a series of
-    // ACK blocks that represents the successfully acknoweldged packets. Each
-    // appended gap/block length represents a descending delta from the previous
-    // block. i.e.:
-    // |--- length ---|--- gap ---|--- length ---|--- gap ---|--- largest ---|
-    // For gaps larger than can be represented by a single encoded gap, a 0
-    // length gap of the maximum is used, i.e.:
-    // |--- length ---|--- gap ---|- 0 -|--- gap ---|--- largest ---|
-    auto itr = frame.packets.rbegin();
-    QuicPacketNumber previous_start = itr->min();
-    ++itr;
-
-    for (;
-         itr != frame.packets.rend() && num_ack_blocks_written < num_ack_blocks;
-         previous_start = itr->min(), ++itr) {
-      const auto& interval = *itr;
-      const uint64_t total_gap = previous_start - interval.max();
-      const size_t num_encoded_gaps =
-          (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
-          std::numeric_limits<uint8_t>::max();
-
-      // Append empty ACK blocks because the gap is longer than a single gap.
-      for (size_t i = 1;
-           i < num_encoded_gaps && num_ack_blocks_written < num_ack_blocks;
-           ++i) {
-        if (!AppendAckBlock(std::numeric_limits<uint8_t>::max(),
-                            ack_block_length, 0, writer)) {
-          return false;
-        }
-        ++num_ack_blocks_written;
-      }
-      if (num_ack_blocks_written >= num_ack_blocks) {
-        if (QUIC_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
-          QUIC_BUG(quic_bug_10850_85)
-              << "Wrote " << num_ack_blocks_written << ", expected to write "
-              << num_ack_blocks;
-        }
-        break;
-      }
-
-      const uint8_t last_gap =
-          total_gap -
-          (num_encoded_gaps - 1) * std::numeric_limits<uint8_t>::max();
-      // Append the final ACK block with a non-empty size.
-      if (!AppendAckBlock(last_gap, ack_block_length, interval.Length(),
-                          writer)) {
-        return false;
-      }
-      ++num_ack_blocks_written;
-    }
-    QUICHE_DCHECK_EQ(num_ack_blocks, num_ack_blocks_written);
-  }
-  // Timestamps.
-  // If we don't process timestamps or if we don't have enough available space
-  // to append all the timestamps, don't append any of them.
-  if (process_timestamps_ && writer->capacity() - writer->length() >=
-                                 GetAckFrameTimeStampSize(frame)) {
-    if (!AppendTimestampsToAckFrame(frame, writer)) {
-      return false;
-    }
-  } else {
-    uint8_t num_received_packets = 0;
-    if (!writer->WriteBytes(&num_received_packets, 1)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame,
-                                            QuicDataWriter* writer) {
-  QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
-                   frame.received_packet_times.size());
-  // num_received_packets is only 1 byte.
-  if (frame.received_packet_times.size() >
-      std::numeric_limits<uint8_t>::max()) {
-    return false;
-  }
-
-  uint8_t num_received_packets = frame.received_packet_times.size();
-  if (!writer->WriteBytes(&num_received_packets, 1)) {
-    return false;
-  }
-  if (num_received_packets == 0) {
-    return true;
-  }
-
-  auto it = frame.received_packet_times.begin();
-  QuicPacketNumber packet_number = it->first;
-  uint64_t delta_from_largest_observed = LargestAcked(frame) - packet_number;
-
-  QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
-                   delta_from_largest_observed);
-  if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
-    return false;
-  }
-
-  if (!writer->WriteUInt8(delta_from_largest_observed)) {
-    return false;
-  }
-
-  // Use the lowest 4 bytes of the time delta from the creation_time_.
-  const uint64_t time_epoch_delta_us = UINT64_C(1) << 32;
-  uint32_t time_delta_us =
-      static_cast<uint32_t>((it->second - creation_time_).ToMicroseconds() &
-                            (time_epoch_delta_us - 1));
-  if (!writer->WriteUInt32(time_delta_us)) {
-    return false;
-  }
-
-  QuicTime prev_time = it->second;
-
-  for (++it; it != frame.received_packet_times.end(); ++it) {
-    packet_number = it->first;
-    delta_from_largest_observed = LargestAcked(frame) - packet_number;
-
-    if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
-      return false;
-    }
-
-    if (!writer->WriteUInt8(delta_from_largest_observed)) {
-      return false;
-    }
-
-    uint64_t frame_time_delta_us = (it->second - prev_time).ToMicroseconds();
-    prev_time = it->second;
-    if (!writer->WriteUFloat16(frame_time_delta_us)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-absl::InlinedVector<QuicFramer::AckTimestampRange, 2>
-QuicFramer::GetAckTimestampRanges(const QuicAckFrame& frame,
-                                  std::string& detailed_error) const {
-  detailed_error = "";
-  if (frame.received_packet_times.empty()) {
-    return {};
-  }
-
-  absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges;
-
-  for (size_t r = 0; r < std::min<size_t>(max_receive_timestamps_per_ack_,
-                                          frame.received_packet_times.size());
-       ++r) {
-    const size_t i = frame.received_packet_times.size() - 1 - r;
-    const QuicPacketNumber packet_number = frame.received_packet_times[i].first;
-    const QuicTime receive_timestamp = frame.received_packet_times[i].second;
-
-    if (timestamp_ranges.empty()) {
-      if (receive_timestamp < creation_time_ ||
-          LargestAcked(frame) < packet_number) {
-        detailed_error =
-            "The first packet is either received earlier than framer creation "
-            "time, or larger than largest acked packet.";
-        QUIC_BUG(quic_framer_ack_ts_first_packet_bad)
-            << detailed_error << " receive_timestamp:" << receive_timestamp
-            << ", framer_creation_time:" << creation_time_
-            << ", packet_number:" << packet_number
-            << ", largest_acked:" << LargestAcked(frame);
-        return {};
-      }
-      timestamp_ranges.push_back(AckTimestampRange());
-      timestamp_ranges.back().gap = LargestAcked(frame) - packet_number;
-      timestamp_ranges.back().range_begin = i;
-      timestamp_ranges.back().range_end = i;
-      continue;
-    }
-
-    const size_t prev_i = timestamp_ranges.back().range_end;
-    const QuicPacketNumber prev_packet_number =
-        frame.received_packet_times[prev_i].first;
-    const QuicTime prev_receive_timestamp =
-        frame.received_packet_times[prev_i].second;
-
-    QUIC_DVLOG(3) << "prev_packet_number:" << prev_packet_number
-                  << ", packet_number:" << packet_number;
-    if (prev_receive_timestamp < receive_timestamp ||
-        prev_packet_number <= packet_number) {
-      detailed_error = "Packet number and/or receive time not in order.";
-      QUIC_BUG(quic_framer_ack_ts_packet_out_of_order)
-          << detailed_error << " packet_number:" << packet_number
-          << ", receive_timestamp:" << receive_timestamp
-          << ", prev_packet_number:" << prev_packet_number
-          << ", prev_receive_timestamp:" << prev_receive_timestamp;
-      return {};
-    }
-
-    if (prev_packet_number == packet_number + 1) {
-      timestamp_ranges.back().range_end = i;
-    } else {
-      timestamp_ranges.push_back(AckTimestampRange());
-      timestamp_ranges.back().gap = prev_packet_number - 2 - packet_number;
-      timestamp_ranges.back().range_begin = i;
-      timestamp_ranges.back().range_end = i;
-    }
-  }
-
-  return timestamp_ranges;
-}
-
-int64_t QuicFramer::FrameAckTimestampRanges(
-    const QuicAckFrame& frame,
-    const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
-    QuicDataWriter* writer) const {
-  int64_t size = 0;
-  auto maybe_write_var_int62 = [&](uint64_t value) {
-    size += QuicDataWriter::GetVarInt62Len(value);
-    if (writer != nullptr && !writer->WriteVarInt62(value)) {
-      return false;
-    }
-    return true;
-  };
-
-  if (!maybe_write_var_int62(timestamp_ranges.size())) {
-    return -1;
-  }
-
-  // |effective_prev_time| is the exponent-encoded timestamp of the previous
-  // packet.
-  absl::optional<QuicTime> effective_prev_time;
-  for (const AckTimestampRange& range : timestamp_ranges) {
-    QUIC_DVLOG(3) << "Range: gap:" << range.gap << ", beg:" << range.range_begin
-                  << ", end:" << range.range_end;
-    if (!maybe_write_var_int62(range.gap)) {
-      return -1;
-    }
-
-    if (!maybe_write_var_int62(range.range_begin - range.range_end + 1)) {
-      return -1;
-    }
-
-    for (int64_t i = range.range_begin; i >= range.range_end; --i) {
-      const QuicTime receive_timestamp = frame.received_packet_times[i].second;
-      uint64_t time_delta;
-      if (effective_prev_time.has_value()) {
-        time_delta =
-            (*effective_prev_time - receive_timestamp).ToMicroseconds();
-        QUIC_DVLOG(3) << "time_delta:" << time_delta
-                      << ", exponent:" << receive_timestamps_exponent_
-                      << ", effective_prev_time:" << *effective_prev_time
-                      << ", recv_time:" << receive_timestamp;
-        time_delta = time_delta >> receive_timestamps_exponent_;
-        effective_prev_time = effective_prev_time.value() -
-                              QuicTime::Delta::FromMicroseconds(
-                                  time_delta << receive_timestamps_exponent_);
-      } else {
-        // The first delta is from framer creation to the current receive
-        // timestamp (forward in time), whereas in the common case subsequent
-        // deltas move backwards in time.
-        time_delta = (receive_timestamp - creation_time_).ToMicroseconds();
-        QUIC_DVLOG(3) << "First time_delta:" << time_delta
-                      << ", exponent:" << receive_timestamps_exponent_
-                      << ", recv_time:" << receive_timestamp
-                      << ", creation_time:" << creation_time_;
-        // Round up the first exponent-encoded time delta so that the next
-        // receive timestamp is guaranteed to be decreasing.
-        time_delta = ((time_delta - 1) >> receive_timestamps_exponent_) + 1;
-        effective_prev_time =
-            creation_time_ + QuicTime::Delta::FromMicroseconds(
-                                 time_delta << receive_timestamps_exponent_);
-      }
-
-      if (!maybe_write_var_int62(time_delta)) {
-        return -1;
-      }
-    }
-  }
-
-  return size;
-}
-
-bool QuicFramer::AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
-                                                QuicDataWriter* writer) {
-  QUICHE_DCHECK(!frame.received_packet_times.empty());
-  std::string detailed_error;
-  const absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
-      GetAckTimestampRanges(frame, detailed_error);
-  if (!detailed_error.empty()) {
-    set_detailed_error(std::move(detailed_error));
-    return false;
-  }
-
-  // Compute the size first using a null writer.
-  int64_t size =
-      FrameAckTimestampRanges(frame, timestamp_ranges, /*writer=*/nullptr);
-  if (size > static_cast<int64_t>(writer->capacity() - writer->length())) {
-    QUIC_DVLOG(1) << "Insufficient room to write IETF ack receive timestamps. "
-                     "size_remain:"
-                  << (writer->capacity() - writer->length())
-                  << ", size_needed:" << size;
-    // Write a Timestamp Range Count of 0.
-    return writer->WriteVarInt62(0);
-  }
-
-  return FrameAckTimestampRanges(frame, timestamp_ranges, writer) > 0;
-}
-
-bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
-                                        const QuicStopWaitingFrame& frame,
-                                        QuicDataWriter* writer) {
-  QUICHE_DCHECK(!version_.HasIetfInvariantHeader());
-  QUICHE_DCHECK(frame.least_unacked.IsInitialized());
-  QUICHE_DCHECK_GE(header.packet_number, frame.least_unacked);
-  const uint64_t least_unacked_delta =
-      header.packet_number - frame.least_unacked;
-  const uint64_t length_shift = header.packet_number_length * 8;
-
-  if (least_unacked_delta >> length_shift > 0) {
-    QUIC_BUG(quic_bug_10850_86)
-        << "packet_number_length " << header.packet_number_length
-        << " is too small for least_unacked_delta: " << least_unacked_delta
-        << " packet_number:" << header.packet_number
-        << " least_unacked:" << frame.least_unacked
-        << " version:" << version_.transport_version;
-    return false;
-  }
-  if (least_unacked_delta == 0) {
-    return writer->WriteBytesToUInt64(header.packet_number_length,
-                                      least_unacked_delta);
-  }
-  if (!AppendPacketNumber(header.packet_number_length,
-                          QuicPacketNumber(least_unacked_delta), writer)) {
-    QUIC_BUG(quic_bug_10850_87)
-        << " seq failed: " << header.packet_number_length;
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
-                                               QuicDataWriter* writer) {
-  uint8_t type = IETF_ACK;
-  uint64_t ecn_size = 0;
-  if (UseIetfAckWithReceiveTimestamp(frame)) {
-    type = IETF_ACK_RECEIVE_TIMESTAMPS;
-  } else if (frame.ecn_counters_populated &&
-             (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
-    // Change frame type to ACK_ECN if any ECN count is available.
-    type = IETF_ACK_ECN;
-    ecn_size = (QuicDataWriter::GetVarInt62Len(frame.ect_0_count) +
-                QuicDataWriter::GetVarInt62Len(frame.ect_1_count) +
-                QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count));
-  }
-
-  if (!writer->WriteVarInt62(type)) {
-    set_detailed_error("No room for frame-type");
-    return false;
-  }
-
-  QuicPacketNumber largest_acked = LargestAcked(frame);
-  if (!writer->WriteVarInt62(largest_acked.ToUint64())) {
-    set_detailed_error("No room for largest-acked in ack frame");
-    return false;
-  }
-
-  uint64_t ack_delay_time_us = kVarInt62MaxValue;
-  if (!frame.ack_delay_time.IsInfinite()) {
-    QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
-    ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
-    ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
-  }
-
-  if (!writer->WriteVarInt62(ack_delay_time_us)) {
-    set_detailed_error("No room for ack-delay in ack frame");
-    return false;
-  }
-
-  if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
-    QUIC_BUG(quic_bug_10850_88) << "Malformed ack frame: " << frame;
-    set_detailed_error("Malformed ack frame");
-    return false;
-  }
-
-  // Latch ack_block_count for potential truncation.
-  const uint64_t ack_block_count = frame.packets.NumIntervals() - 1;
-  QuicDataWriter count_writer(QuicDataWriter::GetVarInt62Len(ack_block_count),
-                              writer->data() + writer->length());
-  if (!writer->WriteVarInt62(ack_block_count)) {
-    set_detailed_error("No room for ack block count in ack frame");
-    return false;
-  }
-  auto iter = frame.packets.rbegin();
-  if (!writer->WriteVarInt62(iter->Length() - 1)) {
-    set_detailed_error("No room for first ack block in ack frame");
-    return false;
-  }
-  QuicPacketNumber previous_smallest = iter->min();
-  ++iter;
-  // Append remaining ACK blocks.
-  uint64_t appended_ack_blocks = 0;
-  for (; iter != frame.packets.rend(); ++iter) {
-    const uint64_t gap = previous_smallest - iter->max() - 1;
-    const uint64_t ack_range = iter->Length() - 1;
-
-    if (type == IETF_ACK_RECEIVE_TIMESTAMPS &&
-        writer->remaining() <
-            static_cast<size_t>(QuicDataWriter::GetVarInt62Len(gap) +
-                                QuicDataWriter::GetVarInt62Len(ack_range) +
-                                QuicDataWriter::GetVarInt62Len(0))) {
-      // If we write this ACK range we won't have space for a timestamp range
-      // count of 0.
-      break;
-    } else if (writer->remaining() < ecn_size ||
-               writer->remaining() - ecn_size <
-                   static_cast<size_t>(
-                       QuicDataWriter::GetVarInt62Len(gap) +
-                       QuicDataWriter::GetVarInt62Len(ack_range))) {
-      // ACK range does not fit, truncate it.
-      break;
-    }
-    const bool success =
-        writer->WriteVarInt62(gap) && writer->WriteVarInt62(ack_range);
-    QUICHE_DCHECK(success);
-    previous_smallest = iter->min();
-    ++appended_ack_blocks;
-  }
-
-  if (appended_ack_blocks < ack_block_count) {
-    // Truncation is needed, rewrite the ack block count.
-    if (QuicDataWriter::GetVarInt62Len(appended_ack_blocks) !=
-            QuicDataWriter::GetVarInt62Len(ack_block_count) ||
-        !count_writer.WriteVarInt62(appended_ack_blocks)) {
-      // This should never happen as ack_block_count is limited by
-      // max_ack_ranges_.
-      QUIC_BUG(quic_bug_10850_89)
-          << "Ack frame truncation fails. ack_block_count: " << ack_block_count
-          << ", appended count: " << appended_ack_blocks;
-      set_detailed_error("ACK frame truncation fails");
-      return false;
-    }
-    QUIC_DLOG(INFO) << ENDPOINT << "ACK ranges get truncated from "
-                    << ack_block_count << " to " << appended_ack_blocks;
-  }
-
-  if (type == IETF_ACK_ECN) {
-    // Encode the ECN counts.
-    if (!writer->WriteVarInt62(frame.ect_0_count)) {
-      set_detailed_error("No room for ect_0_count in ack frame");
-      return false;
-    }
-    if (!writer->WriteVarInt62(frame.ect_1_count)) {
-      set_detailed_error("No room for ect_1_count in ack frame");
-      return false;
-    }
-    if (!writer->WriteVarInt62(frame.ecn_ce_count)) {
-      set_detailed_error("No room for ecn_ce_count in ack frame");
-      return false;
-    }
-  }
-
-  if (type == IETF_ACK_RECEIVE_TIMESTAMPS) {
-    if (!AppendIetfTimestampsToAckFrame(frame, writer)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
-                                      QuicDataWriter* writer) {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    return AppendIetfResetStreamFrame(frame, writer);
-  }
-  if (!writer->WriteUInt32(frame.stream_id)) {
-    return false;
-  }
-
-  if (!writer->WriteUInt64(frame.byte_offset)) {
-    return false;
-  }
-
-  uint32_t error_code = static_cast<uint32_t>(frame.error_code);
-  if (!writer->WriteUInt32(error_code)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicFramer::AppendConnectionCloseFrame(
-    const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    return AppendIetfConnectionCloseFrame(frame, writer);
-  }
-  uint32_t error_code = static_cast<uint32_t>(frame.wire_error_code);
-  if (!writer->WriteUInt32(error_code)) {
-    return false;
-  }
-  if (!writer->WriteStringPiece16(TruncateErrorString(frame.error_details))) {
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendGoAwayFrame(const QuicGoAwayFrame& frame,
-                                   QuicDataWriter* writer) {
-  uint32_t error_code = static_cast<uint32_t>(frame.error_code);
-  if (!writer->WriteUInt32(error_code)) {
-    return false;
-  }
-  uint32_t stream_id = static_cast<uint32_t>(frame.last_good_stream_id);
-  if (!writer->WriteUInt32(stream_id)) {
-    return false;
-  }
-  if (!writer->WriteStringPiece16(TruncateErrorString(frame.reason_phrase))) {
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
-                                         QuicDataWriter* writer) {
-  uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
-  if (!writer->WriteUInt32(stream_id)) {
-    return false;
-  }
-  if (!writer->WriteUInt64(frame.max_data)) {
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendBlockedFrame(const QuicBlockedFrame& frame,
-                                    QuicDataWriter* writer) {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    if (frame.stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
-      return AppendDataBlockedFrame(frame, writer);
-    }
-    return AppendStreamDataBlockedFrame(frame, writer);
-  }
-  uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
-  if (!writer->WriteUInt32(stream_id)) {
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame,
-                                    QuicDataWriter* writer) {
-  if (frame.num_padding_bytes == 0) {
-    return false;
-  }
-  if (frame.num_padding_bytes < 0) {
-    QUIC_BUG_IF(quic_bug_12975_9, frame.num_padding_bytes != -1);
-    writer->WritePadding();
-    return true;
-  }
-  // Please note, num_padding_bytes includes type byte which has been written.
-  return writer->WritePaddingBytes(frame.num_padding_bytes - 1);
-}
-
-bool QuicFramer::AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
-                                               bool last_frame_in_packet,
-                                               QuicDataWriter* writer) {
-  uint8_t type_byte;
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH_V99
-                                     : IETF_EXTENSION_MESSAGE_V99;
-  } else {
-    type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH
-                                     : IETF_EXTENSION_MESSAGE;
-  }
-  if (!writer->WriteUInt8(type_byte)) {
-    return false;
-  }
-  if (!last_frame_in_packet && !writer->WriteVarInt62(frame.message_length)) {
-    return false;
-  }
-  for (const auto& slice : frame.message_data) {
-    if (!writer->WriteBytes(slice.data(), slice.length())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicFramer::RaiseError(QuicErrorCode error) {
-  QUIC_DLOG(INFO) << ENDPOINT << "Error: " << QuicErrorCodeToString(error)
-                  << " detail: " << detailed_error_;
-  set_error(error);
-  if (visitor_) {
-    visitor_->OnError(this);
-  }
-  return false;
-}
-
-bool QuicFramer::IsVersionNegotiation(
-    const QuicPacketHeader& header, bool packet_has_ietf_packet_header) const {
-  if (!packet_has_ietf_packet_header &&
-      perspective_ == Perspective::IS_CLIENT) {
-    return header.version_flag;
-  }
-  if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
-    return false;
-  }
-  return header.long_packet_type == VERSION_NEGOTIATION;
-}
-
-bool QuicFramer::AppendIetfConnectionCloseFrame(
-    const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
-  if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
-      frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
-    QUIC_BUG(quic_bug_10850_90)
-        << "Invalid close_type for writing IETF CONNECTION CLOSE.";
-    set_detailed_error("Invalid close_type for writing IETF CONNECTION CLOSE.");
-    return false;
-  }
-
-  if (!writer->WriteVarInt62(frame.wire_error_code)) {
-    set_detailed_error("Can not write connection close frame error code");
-    return false;
-  }
-
-  if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
-    // Write the frame-type of the frame causing the error only
-    // if it's a CONNECTION_CLOSE/Transport.
-    if (!writer->WriteVarInt62(frame.transport_close_frame_type)) {
-      set_detailed_error("Writing frame type failed.");
-      return false;
-    }
-  }
-
-  // There may be additional error information available in the extracted error
-  // code. Encode the error information in the reason phrase and serialize the
-  // result.
-  std::string final_error_string =
-      GenerateErrorString(frame.error_details, frame.quic_error_code);
-  if (!writer->WriteStringPieceVarInt62(
-          TruncateErrorString(final_error_string))) {
-    set_detailed_error("Can not write connection close phrase");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessIetfConnectionCloseFrame(
-    QuicDataReader* reader, QuicConnectionCloseType type,
-    QuicConnectionCloseFrame* frame) {
-  frame->close_type = type;
-
-  uint64_t error_code;
-  if (!reader->ReadVarInt62(&error_code)) {
-    set_detailed_error("Unable to read connection close error code.");
-    return false;
-  }
-
-  frame->wire_error_code = error_code;
-
-  if (type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
-    // The frame-type of the frame causing the error is present only
-    // if it's a CONNECTION_CLOSE/Transport.
-    if (!reader->ReadVarInt62(&frame->transport_close_frame_type)) {
-      set_detailed_error("Unable to read connection close frame type.");
-      return false;
-    }
-  }
-
-  uint64_t phrase_length;
-  if (!reader->ReadVarInt62(&phrase_length)) {
-    set_detailed_error("Unable to read connection close error details.");
-    return false;
-  }
-
-  absl::string_view phrase;
-  if (!reader->ReadStringPiece(&phrase, static_cast<size_t>(phrase_length))) {
-    set_detailed_error("Unable to read connection close error details.");
-    return false;
-  }
-  frame->error_details = std::string(phrase);
-
-  // The frame may have an extracted error code in it. Look for it and
-  // extract it. If it's not present, MaybeExtract will return
-  // QUIC_IETF_GQUIC_ERROR_MISSING.
-  MaybeExtractQuicErrorCode(frame);
-  return true;
-}
-
-// IETF Quic Path Challenge/Response frames.
-bool QuicFramer::ProcessPathChallengeFrame(QuicDataReader* reader,
-                                           QuicPathChallengeFrame* frame) {
-  if (!reader->ReadBytes(frame->data_buffer.data(),
-                         frame->data_buffer.size())) {
-    set_detailed_error("Can not read path challenge data.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessPathResponseFrame(QuicDataReader* reader,
-                                          QuicPathResponseFrame* frame) {
-  if (!reader->ReadBytes(frame->data_buffer.data(),
-                         frame->data_buffer.size())) {
-    set_detailed_error("Can not read path response data.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
-                                          QuicDataWriter* writer) {
-  if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
-    set_detailed_error("Writing Path Challenge data failed.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendPathResponseFrame(const QuicPathResponseFrame& frame,
-                                         QuicDataWriter* writer) {
-  if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
-    set_detailed_error("Writing Path Response data failed.");
-    return false;
-  }
-  return true;
-}
-
-// Add a new ietf-format stream reset frame.
-// General format is
-//    stream id
-//    application error code
-//    final offset
-bool QuicFramer::AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
-                                            QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
-    set_detailed_error("Writing reset-stream stream id failed.");
-    return false;
-  }
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.ietf_error_code))) {
-    set_detailed_error("Writing reset-stream error code failed.");
-    return false;
-  }
-  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.byte_offset))) {
-    set_detailed_error("Writing reset-stream final-offset failed.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessIetfResetStreamFrame(QuicDataReader* reader,
-                                             QuicRstStreamFrame* frame) {
-  // Get Stream ID from frame. ReadVarIntStreamID returns false
-  // if either A) there is a read error or B) the resulting value of
-  // the Stream ID is larger than the maximum allowed value.
-  if (!ReadUint32FromVarint62(reader, IETF_RST_STREAM, &frame->stream_id)) {
-    return false;
-  }
-
-  if (!reader->ReadVarInt62(&frame->ietf_error_code)) {
-    set_detailed_error("Unable to read rst stream error code.");
-    return false;
-  }
-
-  frame->error_code =
-      IetfResetStreamErrorCodeToRstStreamErrorCode(frame->ietf_error_code);
-
-  if (!reader->ReadVarInt62(&frame->byte_offset)) {
-    set_detailed_error("Unable to read rst stream sent byte offset.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessStopSendingFrame(
-    QuicDataReader* reader, QuicStopSendingFrame* stop_sending_frame) {
-  if (!ReadUint32FromVarint62(reader, IETF_STOP_SENDING,
-                              &stop_sending_frame->stream_id)) {
-    return false;
-  }
-
-  if (!reader->ReadVarInt62(&stop_sending_frame->ietf_error_code)) {
-    set_detailed_error("Unable to read stop sending application error code.");
-    return false;
-  }
-
-  stop_sending_frame->error_code = IetfResetStreamErrorCodeToRstStreamErrorCode(
-      stop_sending_frame->ietf_error_code);
-  return true;
-}
-
-bool QuicFramer::AppendStopSendingFrame(
-    const QuicStopSendingFrame& stop_sending_frame, QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
-    set_detailed_error("Can not write stop sending stream id");
-    return false;
-  }
-  if (!writer->WriteVarInt62(
-          static_cast<uint64_t>(stop_sending_frame.ietf_error_code))) {
-    set_detailed_error("Can not write application error code");
-    return false;
-  }
-  return true;
-}
-
-// Append/process IETF-Format MAX_DATA Frame
-bool QuicFramer::AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
-                                    QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.max_data)) {
-    set_detailed_error("Can not write MAX_DATA byte-offset");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessMaxDataFrame(QuicDataReader* reader,
-                                     QuicWindowUpdateFrame* frame) {
-  frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
-  if (!reader->ReadVarInt62(&frame->max_data)) {
-    set_detailed_error("Can not read MAX_DATA byte-offset");
-    return false;
-  }
-  return true;
-}
-
-// Append/process IETF-Format MAX_STREAM_DATA Frame
-bool QuicFramer::AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
-                                          QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.stream_id)) {
-    set_detailed_error("Can not write MAX_STREAM_DATA stream id");
-    return false;
-  }
-  if (!writer->WriteVarInt62(frame.max_data)) {
-    set_detailed_error("Can not write MAX_STREAM_DATA byte-offset");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessMaxStreamDataFrame(QuicDataReader* reader,
-                                           QuicWindowUpdateFrame* frame) {
-  if (!ReadUint32FromVarint62(reader, IETF_MAX_STREAM_DATA,
-                              &frame->stream_id)) {
-    return false;
-  }
-  if (!reader->ReadVarInt62(&frame->max_data)) {
-    set_detailed_error("Can not read MAX_STREAM_DATA byte-count");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
-                                       QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.stream_count)) {
-    set_detailed_error("Can not write MAX_STREAMS stream count");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessMaxStreamsFrame(QuicDataReader* reader,
-                                        QuicMaxStreamsFrame* frame,
-                                        uint64_t frame_type) {
-  if (!ReadUint32FromVarint62(reader,
-                              static_cast<QuicIetfFrameType>(frame_type),
-                              &frame->stream_count)) {
-    return false;
-  }
-  frame->unidirectional = (frame_type == IETF_MAX_STREAMS_UNIDIRECTIONAL);
-  return true;
-}
-
-bool QuicFramer::AppendDataBlockedFrame(const QuicBlockedFrame& frame,
-                                        QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.offset)) {
-    set_detailed_error("Can not write blocked offset.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessDataBlockedFrame(QuicDataReader* reader,
-                                         QuicBlockedFrame* frame) {
-  // Indicates that it is a BLOCKED frame (as opposed to STREAM_BLOCKED).
-  frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
-  if (!reader->ReadVarInt62(&frame->offset)) {
-    set_detailed_error("Can not read blocked offset.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
-                                              QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.stream_id)) {
-    set_detailed_error("Can not write stream blocked stream id.");
-    return false;
-  }
-  if (!writer->WriteVarInt62(frame.offset)) {
-    set_detailed_error("Can not write stream blocked offset.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessStreamDataBlockedFrame(QuicDataReader* reader,
-                                               QuicBlockedFrame* frame) {
-  if (!ReadUint32FromVarint62(reader, IETF_STREAM_DATA_BLOCKED,
-                              &frame->stream_id)) {
-    return false;
-  }
-  if (!reader->ReadVarInt62(&frame->offset)) {
-    set_detailed_error("Can not read stream blocked offset.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
-                                           QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.stream_count)) {
-    set_detailed_error("Can not write STREAMS_BLOCKED stream count");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessStreamsBlockedFrame(QuicDataReader* reader,
-                                            QuicStreamsBlockedFrame* frame,
-                                            uint64_t frame_type) {
-  if (!ReadUint32FromVarint62(reader,
-                              static_cast<QuicIetfFrameType>(frame_type),
-                              &frame->stream_count)) {
-    return false;
-  }
-  if (frame->stream_count > QuicUtils::GetMaxStreamCount()) {
-    // If stream count is such that the resulting stream ID would exceed our
-    // implementation limit, generate an error.
-    set_detailed_error(
-        "STREAMS_BLOCKED stream count exceeds implementation limit.");
-    return false;
-  }
-  frame->unidirectional = (frame_type == IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
-  return true;
-}
-
-bool QuicFramer::AppendNewConnectionIdFrame(
-    const QuicNewConnectionIdFrame& frame, QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.sequence_number)) {
-    set_detailed_error("Can not write New Connection ID sequence number");
-    return false;
-  }
-  if (!writer->WriteVarInt62(frame.retire_prior_to)) {
-    set_detailed_error("Can not write New Connection ID retire_prior_to");
-    return false;
-  }
-  if (!writer->WriteLengthPrefixedConnectionId(frame.connection_id)) {
-    set_detailed_error("Can not write New Connection ID frame connection ID");
-    return false;
-  }
-
-  if (!writer->WriteBytes(
-          static_cast<const void*>(&frame.stateless_reset_token),
-          sizeof(frame.stateless_reset_token))) {
-    set_detailed_error("Can not write New Connection ID Reset Token");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessNewConnectionIdFrame(QuicDataReader* reader,
-                                             QuicNewConnectionIdFrame* frame) {
-  if (!reader->ReadVarInt62(&frame->sequence_number)) {
-    set_detailed_error(
-        "Unable to read new connection ID frame sequence number.");
-    return false;
-  }
-
-  if (!reader->ReadVarInt62(&frame->retire_prior_to)) {
-    set_detailed_error(
-        "Unable to read new connection ID frame retire_prior_to.");
-    return false;
-  }
-  if (frame->retire_prior_to > frame->sequence_number) {
-    set_detailed_error("Retire_prior_to > sequence_number.");
-    return false;
-  }
-
-  if (!reader->ReadLengthPrefixedConnectionId(&frame->connection_id)) {
-    set_detailed_error("Unable to read new connection ID frame connection id.");
-    return false;
-  }
-
-  if (!QuicUtils::IsConnectionIdValidForVersion(frame->connection_id,
-                                                transport_version())) {
-    set_detailed_error("Invalid new connection ID length for version.");
-    return false;
-  }
-
-  if (!reader->ReadBytes(&frame->stateless_reset_token,
-                         sizeof(frame->stateless_reset_token))) {
-    set_detailed_error("Can not read new connection ID frame reset token.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::AppendRetireConnectionIdFrame(
-    const QuicRetireConnectionIdFrame& frame, QuicDataWriter* writer) {
-  if (!writer->WriteVarInt62(frame.sequence_number)) {
-    set_detailed_error("Can not write Retire Connection ID sequence number");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ProcessRetireConnectionIdFrame(
-    QuicDataReader* reader, QuicRetireConnectionIdFrame* frame) {
-  if (!reader->ReadVarInt62(&frame->sequence_number)) {
-    set_detailed_error(
-        "Unable to read retire connection ID frame sequence number.");
-    return false;
-  }
-  return true;
-}
-
-bool QuicFramer::ReadUint32FromVarint62(QuicDataReader* reader,
-                                        QuicIetfFrameType type,
-                                        QuicStreamId* id) {
-  uint64_t temp_uint64;
-  if (!reader->ReadVarInt62(&temp_uint64)) {
-    set_detailed_error("Unable to read " + QuicIetfFrameTypeString(type) +
-                       " frame stream id/count.");
-    return false;
-  }
-  if (temp_uint64 > kMaxQuicStreamId) {
-    set_detailed_error("Stream id/count of " + QuicIetfFrameTypeString(type) +
-                       "frame is too large.");
-    return false;
-  }
-  *id = static_cast<uint32_t>(temp_uint64);
-  return true;
-}
-
-uint8_t QuicFramer::GetStreamFrameTypeByte(const QuicStreamFrame& frame,
-                                           bool last_frame_in_packet) const {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    return GetIetfStreamFrameTypeByte(frame, last_frame_in_packet);
-  }
-  uint8_t type_byte = 0;
-  // Fin bit.
-  type_byte |= frame.fin ? kQuicStreamFinMask : 0;
-
-  // Data Length bit.
-  type_byte <<= kQuicStreamDataLengthShift;
-  type_byte |= last_frame_in_packet ? 0 : kQuicStreamDataLengthMask;
-
-  // Offset 3 bits.
-  type_byte <<= kQuicStreamShift;
-  const size_t offset_len = GetStreamOffsetSize(frame.offset);
-  if (offset_len > 0) {
-    type_byte |= offset_len - 1;
-  }
-
-  // stream id 2 bits.
-  type_byte <<= kQuicStreamIdShift;
-  type_byte |= GetStreamIdSize(frame.stream_id) - 1;
-  type_byte |= kQuicFrameTypeStreamMask;  // Set Stream Frame Type to 1.
-
-  return type_byte;
-}
-
-uint8_t QuicFramer::GetIetfStreamFrameTypeByte(
-    const QuicStreamFrame& frame, bool last_frame_in_packet) const {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
-  uint8_t type_byte = IETF_STREAM;
-  if (!last_frame_in_packet) {
-    type_byte |= IETF_STREAM_FRAME_LEN_BIT;
-  }
-  if (frame.offset != 0) {
-    type_byte |= IETF_STREAM_FRAME_OFF_BIT;
-  }
-  if (frame.fin) {
-    type_byte |= IETF_STREAM_FRAME_FIN_BIT;
-  }
-  return type_byte;
-}
-
-void QuicFramer::InferPacketHeaderTypeFromVersion() {
-  // This function should only be called when server connection negotiates the
-  // version.
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
-  QUICHE_DCHECK(!infer_packet_header_type_from_version_);
-  infer_packet_header_type_from_version_ = true;
-}
-
-void QuicFramer::EnableMultiplePacketNumberSpacesSupport() {
-  if (supports_multiple_packet_number_spaces_) {
-    QUIC_BUG(quic_bug_10850_91)
-        << "Multiple packet number spaces has already been enabled";
-    return;
-  }
-  if (largest_packet_number_.IsInitialized()) {
-    QUIC_BUG(quic_bug_10850_92)
-        << "Try to enable multiple packet number spaces support after any "
-           "packet has been received.";
-    return;
-  }
-
-  supports_multiple_packet_number_spaces_ = true;
-}
-
-// static
-QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher(
-    const QuicEncryptedPacket& packet,
-    uint8_t expected_destination_connection_id_length,
-    PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
-    bool* version_present, bool* has_length_prefix,
-    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
-    QuicConnectionId* destination_connection_id,
-    QuicConnectionId* source_connection_id,
-    absl::optional<absl::string_view>* retry_token,
-    std::string* detailed_error) {
-  QuicDataReader reader(packet.data(), packet.length());
-  if (reader.IsDoneReading()) {
-    *detailed_error = "Unable to read first byte.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-  const uint8_t first_byte = reader.PeekByte();
-  if ((first_byte & FLAGS_LONG_HEADER) == 0 &&
-      (first_byte & FLAGS_FIXED_BIT) == 0 &&
-      (first_byte & FLAGS_DEMULTIPLEXING_BIT) == 0) {
-    // All versions of Google QUIC up to and including Q043 set
-    // FLAGS_DEMULTIPLEXING_BIT to one on all client-to-server packets. Q044
-    // and Q045 were never default-enabled in production. All subsequent
-    // versions of Google QUIC (starting with Q046) require FLAGS_FIXED_BIT to
-    // be set to one on all packets. All versions of IETF QUIC (since
-    // draft-ietf-quic-transport-17 which was earlier than the first IETF QUIC
-    // version that was deployed in production by any implementation) also
-    // require FLAGS_FIXED_BIT to be set to one on all packets. If a packet
-    // has the FLAGS_LONG_HEADER bit set to one, it could be a first flight
-    // from an unknown future version that allows the other two bits to be set
-    // to zero. Based on this, packets that have all three of those bits set
-    // to zero are known to be invalid.
-    *detailed_error = "Invalid flags.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-  const bool ietf_format = QuicUtils::IsIetfPacketHeader(first_byte);
-  uint8_t unused_first_byte;
-  QuicVariableLengthIntegerLength retry_token_length_length;
-  absl::string_view maybe_retry_token;
-  QuicErrorCode error_code = ParsePublicHeader(
-      &reader, expected_destination_connection_id_length, ietf_format,
-      &unused_first_byte, format, version_present, has_length_prefix,
-      version_label, parsed_version, destination_connection_id,
-      source_connection_id, long_packet_type, &retry_token_length_length,
-      &maybe_retry_token, detailed_error);
-  if (retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
-    *retry_token = maybe_retry_token;
-  } else {
-    retry_token->reset();
-  }
-  return error_code;
-}
-
-// static
-QuicErrorCode QuicFramer::ParsePublicHeaderGoogleQuic(
-    QuicDataReader* reader, uint8_t* first_byte, PacketHeaderFormat* format,
-    bool* version_present, QuicVersionLabel* version_label,
-    ParsedQuicVersion* parsed_version,
-    QuicConnectionId* destination_connection_id, std::string* detailed_error) {
-  *format = GOOGLE_QUIC_PACKET;
-  *version_present = (*first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
-  uint8_t destination_connection_id_length = 0;
-  if ((*first_byte & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) != 0) {
-    destination_connection_id_length = kQuicDefaultConnectionIdLength;
-  }
-  if (!reader->ReadConnectionId(destination_connection_id,
-                                destination_connection_id_length)) {
-    *detailed_error = "Unable to read ConnectionId.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-  if (*version_present) {
-    if (!ProcessVersionLabel(reader, version_label)) {
-      *detailed_error = "Unable to read protocol version.";
-      return QUIC_INVALID_PACKET_HEADER;
-    }
-    *parsed_version = ParseQuicVersionLabel(*version_label);
-  }
-  return QUIC_NO_ERROR;
-}
-
-namespace {
-
-const QuicVersionLabel kProxVersionLabel = 0x50524F58;  // "PROX"
-
-inline bool PacketHasLengthPrefixedConnectionIds(
-    const QuicDataReader& reader, ParsedQuicVersion parsed_version,
-    QuicVersionLabel version_label, uint8_t first_byte) {
-  if (parsed_version.IsKnown()) {
-    return parsed_version.HasLengthPrefixedConnectionIds();
-  }
-
-  // Received unsupported version, check known old unsupported versions.
-  if (QuicVersionLabelUses4BitConnectionIdLength(version_label)) {
-    return false;
-  }
-
-  // Received unknown version, check connection ID length byte.
-  if (reader.IsDoneReading()) {
-    // This check is required to safely peek the connection ID length byte.
-    return true;
-  }
-  const uint8_t connection_id_length_byte = reader.PeekByte();
-
-  // Check for packets produced by older versions of
-  // QuicFramer::WriteClientVersionNegotiationProbePacket
-  if (first_byte == 0xc0 && (connection_id_length_byte & 0x0f) == 0 &&
-      connection_id_length_byte >= 0x50 && version_label == 0xcabadaba) {
-    return false;
-  }
-
-  // Check for munged packets with version tag PROX.
-  if ((connection_id_length_byte & 0x0f) == 0 &&
-      connection_id_length_byte >= 0x20 && version_label == kProxVersionLabel) {
-    return false;
-  }
-
-  return true;
-}
-
-inline bool ParseLongHeaderConnectionIds(
-    QuicDataReader& reader, bool has_length_prefix,
-    QuicVersionLabel version_label, QuicConnectionId& destination_connection_id,
-    QuicConnectionId& source_connection_id, std::string& detailed_error) {
-  if (has_length_prefix) {
-    if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
-      detailed_error = "Unable to read destination connection ID.";
-      return false;
-    }
-    if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
-      if (version_label == kProxVersionLabel) {
-        // The "PROX" version does not follow the length-prefixed invariants,
-        // and can therefore attempt to read a payload byte and interpret it
-        // as the source connection ID length, which could fail to parse.
-        // In that scenario we keep the source connection ID empty but mark
-        // parsing as successful.
-        return true;
-      }
-      detailed_error = "Unable to read source connection ID.";
-      return false;
-    }
-  } else {
-    // Parse connection ID lengths.
-    uint8_t connection_id_lengths_byte;
-    if (!reader.ReadUInt8(&connection_id_lengths_byte)) {
-      detailed_error = "Unable to read connection ID lengths.";
-      return false;
-    }
-    uint8_t destination_connection_id_length =
-        (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
-    if (destination_connection_id_length != 0) {
-      destination_connection_id_length += kConnectionIdLengthAdjustment;
-    }
-    uint8_t source_connection_id_length =
-        connection_id_lengths_byte & kSourceConnectionIdLengthMask;
-    if (source_connection_id_length != 0) {
-      source_connection_id_length += kConnectionIdLengthAdjustment;
-    }
-
-    // Read destination connection ID.
-    if (!reader.ReadConnectionId(&destination_connection_id,
-                                 destination_connection_id_length)) {
-      detailed_error = "Unable to read destination connection ID.";
-      return false;
-    }
-
-    // Read source connection ID.
-    if (!reader.ReadConnectionId(&source_connection_id,
-                                 source_connection_id_length)) {
-      detailed_error = "Unable to read source connection ID.";
-      return false;
-    }
-  }
-  return true;
-}
-
-}  // namespace
-
-// static
-QuicErrorCode QuicFramer::ParsePublicHeader(
-    QuicDataReader* reader, uint8_t expected_destination_connection_id_length,
-    bool ietf_format, uint8_t* first_byte, PacketHeaderFormat* format,
-    bool* version_present, bool* has_length_prefix,
-    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
-    QuicConnectionId* destination_connection_id,
-    QuicConnectionId* source_connection_id,
-    QuicLongHeaderType* long_packet_type,
-    QuicVariableLengthIntegerLength* retry_token_length_length,
-    absl::string_view* retry_token, std::string* detailed_error) {
-  *version_present = false;
-  *has_length_prefix = false;
-  *version_label = 0;
-  *parsed_version = UnsupportedQuicVersion();
-  *source_connection_id = EmptyQuicConnectionId();
-  *long_packet_type = INVALID_PACKET_TYPE;
-  *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  *retry_token = absl::string_view();
-  *detailed_error = "";
-
-  if (!reader->ReadUInt8(first_byte)) {
-    *detailed_error = "Unable to read first byte.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-
-  if (!ietf_format) {
-    return ParsePublicHeaderGoogleQuic(
-        reader, first_byte, format, version_present, version_label,
-        parsed_version, destination_connection_id, detailed_error);
-  }
-
-  *format = GetIetfPacketHeaderFormat(*first_byte);
-
-  if (*format == IETF_QUIC_SHORT_HEADER_PACKET) {
-    // Read destination connection ID using
-    // expected_destination_connection_id_length to determine its length.
-    if (!reader->ReadConnectionId(destination_connection_id,
-                                  expected_destination_connection_id_length)) {
-      *detailed_error = "Unable to read destination connection ID.";
-      return QUIC_INVALID_PACKET_HEADER;
-    }
-    return QUIC_NO_ERROR;
-  }
-
-  QUICHE_DCHECK_EQ(IETF_QUIC_LONG_HEADER_PACKET, *format);
-  *version_present = true;
-  if (!ProcessVersionLabel(reader, version_label)) {
-    *detailed_error = "Unable to read protocol version.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-
-  if (*version_label == 0) {
-    *long_packet_type = VERSION_NEGOTIATION;
-  }
-
-  // Parse version.
-  *parsed_version = ParseQuicVersionLabel(*version_label);
-
-  // Figure out which IETF QUIC invariants this packet follows.
-  *has_length_prefix = PacketHasLengthPrefixedConnectionIds(
-      *reader, *parsed_version, *version_label, *first_byte);
-
-  // Parse connection IDs.
-  if (!ParseLongHeaderConnectionIds(*reader, *has_length_prefix, *version_label,
-                                    *destination_connection_id,
-                                    *source_connection_id, *detailed_error)) {
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-
-  if (!parsed_version->IsKnown()) {
-    // Skip parsing of long packet type and retry token for unknown versions.
-    return QUIC_NO_ERROR;
-  }
-
-  // Parse long packet type.
-  *long_packet_type = GetLongHeaderType(*first_byte, *parsed_version);
-
-  switch (*long_packet_type) {
-    case INVALID_PACKET_TYPE:
-      *detailed_error = "Unable to parse long packet type.";
-      return QUIC_INVALID_PACKET_HEADER;
-    case INITIAL:
-      if (!parsed_version->SupportsRetry()) {
-        // Retry token is only present on initial packets for some versions.
-        return QUIC_NO_ERROR;
-      }
-      break;
-    default:
-      return QUIC_NO_ERROR;
-  }
-
-  *retry_token_length_length = reader->PeekVarInt62Length();
-  uint64_t retry_token_length;
-  if (!reader->ReadVarInt62(&retry_token_length)) {
-    *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-    *detailed_error = "Unable to read retry token length.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-
-  if (!reader->ReadStringPiece(retry_token, retry_token_length)) {
-    *detailed_error = "Unable to read retry token.";
-    return QUIC_INVALID_PACKET_HEADER;
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-// static
-bool QuicFramer::WriteClientVersionNegotiationProbePacket(
-    char* packet_bytes, QuicByteCount packet_length,
-    const char* destination_connection_id_bytes,
-    uint8_t destination_connection_id_length) {
-  if (packet_bytes == nullptr) {
-    QUIC_BUG(quic_bug_10850_93) << "Invalid packet_bytes";
-    return false;
-  }
-  if (packet_length < kMinPacketSizeForVersionNegotiation ||
-      packet_length > 65535) {
-    QUIC_BUG(quic_bug_10850_94) << "Invalid packet_length";
-    return false;
-  }
-  if (destination_connection_id_length > kQuicMaxConnectionId4BitLength ||
-      destination_connection_id_length < kQuicDefaultConnectionIdLength) {
-    QUIC_BUG(quic_bug_10850_95) << "Invalid connection_id_length";
-    return false;
-  }
-  // clang-format off
-  const unsigned char packet_start_bytes[] = {
-    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
-    0xc0,
-    // Version, part of the IETF space reserved for negotiation.
-    // This intentionally differs from QuicVersionReservedForNegotiation()
-    // to allow differentiating them over the wire.
-    0xca, 0xba, 0xda, 0xda,
-  };
-  // clang-format on
-  static_assert(sizeof(packet_start_bytes) == 5, "bad packet_start_bytes size");
-  QuicDataWriter writer(packet_length, packet_bytes);
-  if (!writer.WriteBytes(packet_start_bytes, sizeof(packet_start_bytes))) {
-    QUIC_BUG(quic_bug_10850_96) << "Failed to write packet start";
-    return false;
-  }
-
-  QuicConnectionId destination_connection_id(destination_connection_id_bytes,
-                                             destination_connection_id_length);
-  if (!AppendIetfConnectionIds(
-          /*version_flag=*/true, /*use_length_prefix=*/true,
-          destination_connection_id, EmptyQuicConnectionId(), &writer)) {
-    QUIC_BUG(quic_bug_10850_97) << "Failed to write connection IDs";
-    return false;
-  }
-  // Add 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
-  // not parse with any known version. The zeroes make sure that packet numbers,
-  // retry token lengths and payload lengths are parsed as zero, and if the
-  // zeroes are treated as padding frames, 0xff is known to not parse as a
-  // valid frame type.
-  if (!writer.WriteUInt64(0) ||
-      !writer.WriteUInt64(std::numeric_limits<uint64_t>::max())) {
-    QUIC_BUG(quic_bug_10850_98) << "Failed to write 18 bytes";
-    return false;
-  }
-  // Make sure the polite greeting below is padded to a 16-byte boundary to
-  // make it easier to read in tcpdump.
-  while (writer.length() % 16 != 0) {
-    if (!writer.WriteUInt8(0)) {
-      QUIC_BUG(quic_bug_10850_99) << "Failed to write padding byte";
-      return false;
-    }
-  }
-  // Add a polite greeting in case a human sees this in tcpdump.
-  static const char polite_greeting[] =
-      "This packet only exists to trigger IETF QUIC version negotiation. "
-      "Please respond with a Version Negotiation packet indicating what "
-      "versions you support. Thank you and have a nice day.";
-  if (!writer.WriteBytes(polite_greeting, sizeof(polite_greeting))) {
-    QUIC_BUG(quic_bug_10850_100) << "Failed to write polite greeting";
-    return false;
-  }
-  // Fill the rest of the packet with zeroes.
-  writer.WritePadding();
-  QUICHE_DCHECK_EQ(0u, writer.remaining());
-  return true;
-}
-
-// static
-bool QuicFramer::ParseServerVersionNegotiationProbeResponse(
-    const char* packet_bytes, QuicByteCount packet_length,
-    char* source_connection_id_bytes, uint8_t* source_connection_id_length_out,
-    std::string* detailed_error) {
-  if (detailed_error == nullptr) {
-    QUIC_BUG(quic_bug_10850_101) << "Invalid error_details";
-    return false;
-  }
-  *detailed_error = "";
-  if (packet_bytes == nullptr) {
-    *detailed_error = "Invalid packet_bytes";
-    return false;
-  }
-  if (packet_length < 6) {
-    *detailed_error = "Invalid packet_length";
-    return false;
-  }
-  if (source_connection_id_bytes == nullptr) {
-    *detailed_error = "Invalid source_connection_id_bytes";
-    return false;
-  }
-  if (source_connection_id_length_out == nullptr) {
-    *detailed_error = "Invalid source_connection_id_length_out";
-    return false;
-  }
-  QuicDataReader reader(packet_bytes, packet_length);
-  uint8_t type_byte = 0;
-  if (!reader.ReadUInt8(&type_byte)) {
-    *detailed_error = "Failed to read type byte";
-    return false;
-  }
-  if ((type_byte & 0x80) == 0) {
-    *detailed_error = "Packet does not have long header";
-    return false;
-  }
-  uint32_t version = 0;
-  if (!reader.ReadUInt32(&version)) {
-    *detailed_error = "Failed to read version";
-    return false;
-  }
-  if (version != 0) {
-    *detailed_error = "Packet is not a version negotiation packet";
-    return false;
-  }
-
-  QuicConnectionId destination_connection_id, source_connection_id;
-  if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
-    *detailed_error = "Failed to read destination connection ID";
-    return false;
-  }
-  if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
-    *detailed_error = "Failed to read source connection ID";
-    return false;
-  }
-
-  if (destination_connection_id.length() != 0) {
-    *detailed_error = "Received unexpected destination connection ID length";
-    return false;
-  }
-  if (*source_connection_id_length_out < source_connection_id.length()) {
-    *detailed_error =
-        absl::StrCat("*source_connection_id_length_out too small ",
-                     static_cast<int>(*source_connection_id_length_out), " < ",
-                     static_cast<int>(source_connection_id.length()));
-    return false;
-  }
-
-  memcpy(source_connection_id_bytes, source_connection_id.data(),
-         source_connection_id.length());
-  *source_connection_id_length_out = source_connection_id.length();
-
-  return true;
-}
-
-// Look for and parse the error code from the "<quic_error_code>:" text that
-// may be present at the start of the CONNECTION_CLOSE error details string.
-// This text, inserted by the peer if it's using Google's QUIC implementation,
-// contains additional error information that narrows down the exact error.  If
-// the string is not found, or is not properly formed, it returns
-// ErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING
-void MaybeExtractQuicErrorCode(QuicConnectionCloseFrame* frame) {
-  std::vector<absl::string_view> ed = absl::StrSplit(frame->error_details, ':');
-  uint64_t extracted_error_code;
-  if (ed.size() < 2 || !quiche::QuicheTextUtils::IsAllDigits(ed[0]) ||
-      !absl::SimpleAtoi(ed[0], &extracted_error_code)) {
-    if (frame->close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
-        frame->wire_error_code == NO_IETF_QUIC_ERROR) {
-      frame->quic_error_code = QUIC_NO_ERROR;
-    } else {
-      frame->quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
-    }
-    return;
-  }
-  // Return the error code (numeric) and the error details string without the
-  // error code prefix. Note that Split returns everything up to, but not
-  // including, the split character, so the length of ed[0] is just the number
-  // of digits in the error number. In removing the prefix, 1 is added to the
-  // length to account for the :
-  absl::string_view x = absl::string_view(frame->error_details);
-  x.remove_prefix(ed[0].length() + 1);
-  frame->error_details = std::string(x);
-  frame->quic_error_code = static_cast<QuicErrorCode>(extracted_error_code);
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
deleted file mode 100644
index 306f049..0000000
--- a/quic/core/quic_framer.h
+++ /dev/null
@@ -1,1265 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_FRAMER_H_
-#define QUICHE_QUIC_CORE_QUIC_FRAMER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicFramerPeer;
-}  // namespace test
-
-class QuicDataReader;
-class QuicDataWriter;
-class QuicFramer;
-class QuicStreamFrameDataProducer;
-
-// Number of bytes reserved for the frame type preceding each frame.
-const size_t kQuicFrameTypeSize = 1;
-// Number of bytes reserved for error code.
-const size_t kQuicErrorCodeSize = 4;
-// Number of bytes reserved to denote the length of error details field.
-const size_t kQuicErrorDetailsLengthSize = 2;
-
-// Maximum number of bytes reserved for stream id.
-const size_t kQuicMaxStreamIdSize = 4;
-// Maximum number of bytes reserved for byte offset in stream frame.
-const size_t kQuicMaxStreamOffsetSize = 8;
-// Number of bytes reserved to store payload length in stream frame.
-const size_t kQuicStreamPayloadLengthSize = 2;
-// Number of bytes to reserve for IQ Error codes (for the Connection Close,
-// Application Close, and Reset Stream frames).
-const size_t kQuicIetfQuicErrorCodeSize = 2;
-// Minimum size of the IETF QUIC Error Phrase's length field
-const size_t kIetfQuicMinErrorPhraseLengthSize = 1;
-
-// Size in bytes reserved for the delta time of the largest observed
-// packet number in ack frames.
-const size_t kQuicDeltaTimeLargestObservedSize = 2;
-// Size in bytes reserved for the number of received packets with timestamps.
-const size_t kQuicNumTimestampsSize = 1;
-// Size in bytes reserved for the number of missing packets in ack frames.
-const size_t kNumberOfNackRangesSize = 1;
-// Size in bytes reserved for the number of ack blocks in ack frames.
-const size_t kNumberOfAckBlocksSize = 1;
-// Maximum number of missing packet ranges that can fit within an ack frame.
-const size_t kMaxNackRanges = (1 << (kNumberOfNackRangesSize * 8)) - 1;
-// Maximum number of ack blocks that can fit within an ack frame.
-const size_t kMaxAckBlocks = (1 << (kNumberOfAckBlocksSize * 8)) - 1;
-
-// This class receives callbacks from the framer when packets
-// are processed.
-class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
- public:
-  virtual ~QuicFramerVisitorInterface() {}
-
-  // Called if an error is detected in the QUIC protocol.
-  virtual void OnError(QuicFramer* framer) = 0;
-
-  // Called only when |perspective_| is IS_SERVER and the framer gets a
-  // packet with version flag true and the version on the packet doesn't match
-  // |quic_version_|. The visitor should return true after it updates the
-  // version of the |framer_| to |received_version| or false to stop processing
-  // this packet.
-  virtual bool OnProtocolVersionMismatch(
-      ParsedQuicVersion received_version) = 0;
-
-  // Called when a new packet has been received, before it
-  // has been validated or processed.
-  virtual void OnPacket() = 0;
-
-  // Called when a public reset packet has been parsed but has not yet
-  // been validated.
-  virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) = 0;
-
-  // Called only when |perspective_| is IS_CLIENT and a version negotiation
-  // packet has been parsed.
-  virtual void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& packet) = 0;
-
-  // Called only when |perspective_| is IS_CLIENT and a retry packet has been
-  // parsed. |new_connection_id| contains the value of the Source Connection
-  // ID field, and |retry_token| contains the value of the Retry Token field.
-  // On versions where UsesTls() is false,
-  // |original_connection_id| contains the value of the Original Destination
-  // Connection ID field, and both |retry_integrity_tag| and
-  // |retry_without_tag| are empty.
-  // On versions where UsesTls() is true,
-  // |original_connection_id| is empty, |retry_integrity_tag| contains the
-  // value of the Retry Integrity Tag field, and |retry_without_tag| contains
-  // the entire RETRY packet except the Retry Integrity Tag field.
-  virtual void OnRetryPacket(QuicConnectionId original_connection_id,
-                             QuicConnectionId new_connection_id,
-                             absl::string_view retry_token,
-                             absl::string_view retry_integrity_tag,
-                             absl::string_view retry_without_tag) = 0;
-
-  // Called when all fields except packet number has been parsed, but has not
-  // been authenticated. If it returns false, framing for this packet will
-  // cease.
-  virtual bool OnUnauthenticatedPublicHeader(
-      const QuicPacketHeader& header) = 0;
-
-  // Called when the unauthenticated portion of the header has been parsed.
-  // If OnUnauthenticatedHeader returns false, framing for this packet will
-  // cease.
-  virtual bool OnUnauthenticatedHeader(const QuicPacketHeader& header) = 0;
-
-  // Called when a packet has been decrypted. |length| is the packet length,
-  // and |level| is the encryption level of the packet.
-  virtual void OnDecryptedPacket(size_t length, EncryptionLevel level) = 0;
-
-  // Called when the complete header of a packet had been parsed.
-  // If OnPacketHeader returns false, framing for this packet will cease.
-  virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0;
-
-  // Called when the packet being processed contains multiple IETF QUIC packets,
-  // which is due to there being more data after what is covered by the length
-  // field. |packet| contains the remaining data which can be processed.
-  // Note that this is called when the framer parses the length field, before
-  // it attempts to decrypt the first payload. It is the visitor's
-  // responsibility to buffer the packet and call ProcessPacket on it
-  // after the framer is done parsing the current payload. |packet| does not
-  // own its internal buffer, the visitor should make a copy of it.
-  virtual void OnCoalescedPacket(const QuicEncryptedPacket& packet) = 0;
-
-  // Called when the packet being processed failed to decrypt.
-  // |has_decryption_key| indicates whether the framer knew which decryption
-  // key to use for this packet and already had a suitable key.
-  virtual void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
-                                     EncryptionLevel decryption_level,
-                                     bool has_decryption_key) = 0;
-
-  // Called when a StreamFrame has been parsed.
-  virtual bool OnStreamFrame(const QuicStreamFrame& frame) = 0;
-
-  // Called when a CRYPTO frame has been parsed.
-  virtual bool OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
-
-  // Called when largest acked of an AckFrame has been parsed.
-  virtual bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                               QuicTime::Delta ack_delay_time) = 0;
-
-  // Called when ack range [start, end) of an AckFrame has been parsed.
-  virtual bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) = 0;
-
-  // Called when a timestamp in the AckFrame has been parsed.
-  virtual bool OnAckTimestamp(QuicPacketNumber packet_number,
-                              QuicTime timestamp) = 0;
-
-  // Called after the last ack range in an AckFrame has been parsed.
-  // |start| is the starting value of the last ack range.
-  virtual bool OnAckFrameEnd(QuicPacketNumber start) = 0;
-
-  // Called when a StopWaitingFrame has been parsed.
-  virtual bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) = 0;
-
-  // Called when a QuicPaddingFrame has been parsed.
-  virtual bool OnPaddingFrame(const QuicPaddingFrame& frame) = 0;
-
-  // Called when a PingFrame has been parsed.
-  virtual bool OnPingFrame(const QuicPingFrame& frame) = 0;
-
-  // Called when a RstStreamFrame has been parsed.
-  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) = 0;
-
-  // Called when a ConnectionCloseFrame, of any type, has been parsed.
-  virtual bool OnConnectionCloseFrame(
-      const QuicConnectionCloseFrame& frame) = 0;
-
-  // Called when a StopSendingFrame has been parsed.
-  virtual bool OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
-
-  // Called when a PathChallengeFrame has been parsed.
-  virtual bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) = 0;
-
-  // Called when a PathResponseFrame has been parsed.
-  virtual bool OnPathResponseFrame(const QuicPathResponseFrame& frame) = 0;
-
-  // Called when a GoAwayFrame has been parsed.
-  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) = 0;
-
-  // Called when a WindowUpdateFrame has been parsed.
-  virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
-
-  // Called when a BlockedFrame has been parsed.
-  virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
-
-  // Called when a NewConnectionIdFrame has been parsed.
-  virtual bool OnNewConnectionIdFrame(
-      const QuicNewConnectionIdFrame& frame) = 0;
-
-  // Called when a RetireConnectionIdFrame has been parsed.
-  virtual bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) = 0;
-
-  // Called when a NewTokenFrame has been parsed.
-  virtual bool OnNewTokenFrame(const QuicNewTokenFrame& frame) = 0;
-
-  // Called when a message frame has been parsed.
-  virtual bool OnMessageFrame(const QuicMessageFrame& frame) = 0;
-
-  // Called when a handshake done frame has been parsed.
-  virtual bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) = 0;
-
-  // Called when an AckFrequencyFrame has been parsed.
-  virtual bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) = 0;
-
-  // Called when a packet has been completely processed.
-  virtual void OnPacketComplete() = 0;
-
-  // Called to check whether |token| is a valid stateless reset token.
-  virtual bool IsValidStatelessResetToken(
-      const StatelessResetToken& token) const = 0;
-
-  // Called when an IETF stateless reset packet has been parsed and validated
-  // with the stateless reset token.
-  virtual void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& packet) = 0;
-
-  // Called when an IETF MaxStreams frame has been parsed.
-  virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
-
-  // Called when an IETF StreamsBlocked frame has been parsed.
-  virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
-
-  // Called when a Key Phase Update has been initiated. This is called for both
-  // locally and peer initiated key updates. If the key update was locally
-  // initiated, this does not indicate the peer has received the key update yet.
-  virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
-
-  // Called on the first decrypted packet in each key phase (including the
-  // first key phase.)
-  virtual void OnDecryptedFirstPacketInKeyPhase() = 0;
-
-  // Called when the framer needs to generate a decrypter for the next key
-  // phase. Each call should generate the key for phase n+1.
-  virtual std::unique_ptr<QuicDecrypter>
-  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
-
-  // Called when the framer needs to generate an encrypter. The key corresponds
-  // to the key phase of the last decrypter returned by
-  // AdvanceKeysAndCreateCurrentOneRttDecrypter().
-  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
-};
-
-// Class for parsing and constructing QUIC packets.  It has a
-// QuicFramerVisitorInterface that is called when packets are parsed.
-class QUIC_EXPORT_PRIVATE QuicFramer {
- public:
-  // Constructs a new framer that installs a kNULL QuicEncrypter and
-  // QuicDecrypter for level ENCRYPTION_INITIAL. |supported_versions| specifies
-  // the list of supported QUIC versions. |quic_version_| is set to the maximum
-  // version in |supported_versions|.
-  QuicFramer(const ParsedQuicVersionVector& supported_versions,
-             QuicTime creation_time,
-             Perspective perspective,
-             uint8_t expected_server_connection_id_length);
-  QuicFramer(const QuicFramer&) = delete;
-  QuicFramer& operator=(const QuicFramer&) = delete;
-
-  virtual ~QuicFramer();
-
-  // Returns true if |version| is a supported transport version.
-  bool IsSupportedTransportVersion(const QuicTransportVersion version) const;
-
-  // Returns true if |version| is a supported protocol version.
-  bool IsSupportedVersion(const ParsedQuicVersion version) const;
-
-  // Set callbacks to be called from the framer.  A visitor must be set, or
-  // else the framer will likely crash.  It is acceptable for the visitor
-  // to do nothing.  If this is called multiple times, only the last visitor
-  // will be used.
-  void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; }
-
-  const ParsedQuicVersionVector& supported_versions() const {
-    return supported_versions_;
-  }
-
-  QuicTransportVersion transport_version() const {
-    return version_.transport_version;
-  }
-
-  ParsedQuicVersion version() const { return version_; }
-
-  void set_version(const ParsedQuicVersion version);
-
-  // Does not QUICHE_DCHECK for supported version. Used by tests to set
-  // unsupported version to trigger version negotiation.
-  void set_version_for_tests(const ParsedQuicVersion version) {
-    version_ = version;
-  }
-
-  QuicErrorCode error() const { return error_; }
-
-  // Allows enabling or disabling of timestamp processing and serialization.
-  // TODO(ianswett): Remove the const once timestamps are negotiated via
-  // transport params.
-  void set_process_timestamps(bool process_timestamps) const {
-    process_timestamps_ = process_timestamps;
-  }
-
-  // Sets the max number of receive timestamps to send per ACK frame.
-  // TODO(wub): Remove the const once timestamps are negotiated via
-  // transport params.
-  void set_max_receive_timestamps_per_ack(uint32_t max_timestamps) const {
-    max_receive_timestamps_per_ack_ = max_timestamps;
-  }
-
-  // Sets the exponent to use when writing/reading ACK receive timestamps.
-  void set_receive_timestamps_exponent(uint32_t exponent) const {
-    receive_timestamps_exponent_ = exponent;
-  }
-
-  // Pass a UDP packet into the framer for parsing.
-  // Return true if the packet was processed successfully. |packet| must be a
-  // single, complete UDP packet (not a frame of a packet).  This packet
-  // might be null padded past the end of the payload, which will be correctly
-  // ignored.
-  bool ProcessPacket(const QuicEncryptedPacket& packet);
-
-  // Whether we are in the middle of a call to this->ProcessPacket.
-  bool is_processing_packet() const { return is_processing_packet_; }
-
-  // Largest size in bytes of all stream frame fields without the payload.
-  static size_t GetMinStreamFrameSize(QuicTransportVersion version,
-                                      QuicStreamId stream_id,
-                                      QuicStreamOffset offset,
-                                      bool last_frame_in_packet,
-                                      size_t data_length);
-  // Returns the overhead of framing a CRYPTO frame with the specific offset and
-  // data length provided, but not counting the size of the data payload.
-  static size_t GetMinCryptoFrameSize(QuicStreamOffset offset,
-                                      QuicPacketLength data_length);
-  static size_t GetMessageFrameSize(QuicTransportVersion version,
-                                    bool last_frame_in_packet,
-                                    QuicByteCount length);
-  // Size in bytes of all ack frame fields without the missing packets or ack
-  // blocks.
-  static size_t GetMinAckFrameSize(QuicTransportVersion version,
-                                   const QuicAckFrame& ack_frame,
-                                   uint32_t local_ack_delay_exponent,
-                                   bool use_ietf_ack_with_receive_timestamp);
-  // Size in bytes of a stop waiting frame.
-  static size_t GetStopWaitingFrameSize(
-      QuicPacketNumberLength packet_number_length);
-  // Size in bytes of all reset stream frame fields.
-  static size_t GetRstStreamFrameSize(QuicTransportVersion version,
-                                      const QuicRstStreamFrame& frame);
-  // Size in bytes of all ack frenquency frame fields.
-  static size_t GetAckFrequencyFrameSize(const QuicAckFrequencyFrame& frame);
-  // Size in bytes of all connection close frame fields, including the error
-  // details.
-  static size_t GetConnectionCloseFrameSize(
-      QuicTransportVersion version,
-      const QuicConnectionCloseFrame& frame);
-  // Size in bytes of all GoAway frame fields without the reason phrase.
-  static size_t GetMinGoAwayFrameSize();
-  // Size in bytes of all WindowUpdate frame fields.
-  // For version 99, determines whether a MAX DATA or MAX STREAM DATA frame will
-  // be generated and calculates the appropriate size.
-  static size_t GetWindowUpdateFrameSize(QuicTransportVersion version,
-                                         const QuicWindowUpdateFrame& frame);
-  // Size in bytes of all MaxStreams frame fields.
-  static size_t GetMaxStreamsFrameSize(QuicTransportVersion version,
-                                       const QuicMaxStreamsFrame& frame);
-  // Size in bytes of all StreamsBlocked frame fields.
-  static size_t GetStreamsBlockedFrameSize(
-      QuicTransportVersion version,
-      const QuicStreamsBlockedFrame& frame);
-  // Size in bytes of all Blocked frame fields.
-  static size_t GetBlockedFrameSize(QuicTransportVersion version,
-                                    const QuicBlockedFrame& frame);
-  // Size in bytes of PathChallenge frame.
-  static size_t GetPathChallengeFrameSize(const QuicPathChallengeFrame& frame);
-  // Size in bytes of PathResponse frame.
-  static size_t GetPathResponseFrameSize(const QuicPathResponseFrame& frame);
-  // Size in bytes required to serialize the stream id.
-  static size_t GetStreamIdSize(QuicStreamId stream_id);
-  // Size in bytes required to serialize the stream offset.
-  static size_t GetStreamOffsetSize(QuicStreamOffset offset);
-  // Size in bytes for a serialized new connection id frame
-  static size_t GetNewConnectionIdFrameSize(
-      const QuicNewConnectionIdFrame& frame);
-
-  // Size in bytes for a serialized retire connection id frame
-  static size_t GetRetireConnectionIdFrameSize(
-      const QuicRetireConnectionIdFrame& frame);
-
-  // Size in bytes for a serialized new token frame
-  static size_t GetNewTokenFrameSize(const QuicNewTokenFrame& frame);
-
-  // Size in bytes required for a serialized stop sending frame.
-  static size_t GetStopSendingFrameSize(const QuicStopSendingFrame& frame);
-
-  // Size in bytes required for a serialized retransmittable control |frame|.
-  static size_t GetRetransmittableControlFrameSize(QuicTransportVersion version,
-                                                   const QuicFrame& frame);
-
-  // Returns the number of bytes added to the packet for the specified frame,
-  // and 0 if the frame doesn't fit.  Includes the header size for the first
-  // frame.
-  size_t GetSerializedFrameLength(const QuicFrame& frame,
-                                  size_t free_bytes,
-                                  bool first_frame_in_packet,
-                                  bool last_frame_in_packet,
-                                  QuicPacketNumberLength packet_number_length);
-
-  // Returns the associated data from the encrypted packet |encrypted| as a
-  // stringpiece.
-  static absl::string_view GetAssociatedDataFromEncryptedPacket(
-      QuicTransportVersion version,
-      const QuicEncryptedPacket& encrypted,
-      QuicConnectionIdLength destination_connection_id_length,
-      QuicConnectionIdLength source_connection_id_length,
-      bool includes_version,
-      bool includes_diversification_nonce,
-      QuicPacketNumberLength packet_number_length,
-      QuicVariableLengthIntegerLength retry_token_length_length,
-      uint64_t retry_token_length,
-      QuicVariableLengthIntegerLength length_length);
-
-  // Parses the unencrypted fields in a QUIC header using |reader| as input,
-  // stores the result in the other parameters.
-  // |expected_destination_connection_id_length| is only used for short headers.
-  static QuicErrorCode ParsePublicHeader(
-      QuicDataReader* reader,
-      uint8_t expected_destination_connection_id_length,
-      bool ietf_format,
-      uint8_t* first_byte,
-      PacketHeaderFormat* format,
-      bool* version_present,
-      bool* has_length_prefix,
-      QuicVersionLabel* version_label,
-      ParsedQuicVersion* parsed_version,
-      QuicConnectionId* destination_connection_id,
-      QuicConnectionId* source_connection_id,
-      QuicLongHeaderType* long_packet_type,
-      QuicVariableLengthIntegerLength* retry_token_length_length,
-      absl::string_view* retry_token,
-      std::string* detailed_error);
-
-  // Parses the unencrypted fields in |packet| and stores them in the other
-  // parameters. This can only be called on the server.
-  // |expected_destination_connection_id_length| is only used for short headers.
-  static QuicErrorCode ParsePublicHeaderDispatcher(
-      const QuicEncryptedPacket& packet,
-      uint8_t expected_destination_connection_id_length,
-      PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
-      bool* version_present, bool* has_length_prefix,
-      QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
-      QuicConnectionId* destination_connection_id,
-      QuicConnectionId* source_connection_id,
-      absl::optional<absl::string_view>* retry_token,
-      std::string* detailed_error);
-
-  // Serializes a packet containing |frames| into |buffer|.
-  // Returns the length of the packet, which must not be longer than
-  // |packet_length|.  Returns 0 if it fails to serialize.
-  size_t BuildDataPacket(const QuicPacketHeader& header,
-                         const QuicFrames& frames,
-                         char* buffer,
-                         size_t packet_length,
-                         EncryptionLevel level);
-
-  // Returns a new public reset packet.
-  static std::unique_ptr<QuicEncryptedPacket> BuildPublicResetPacket(
-      const QuicPublicResetPacket& packet);
-
-  // Returns the minimal stateless reset packet length.
-  static size_t GetMinStatelessResetPacketLength();
-
-  // Returns a new IETF stateless reset packet.
-  static std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
-      QuicConnectionId connection_id,
-      size_t received_packet_length,
-      StatelessResetToken stateless_reset_token);
-
-  // Returns a new version negotiation packet.
-  static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
-      QuicConnectionId server_connection_id,
-      QuicConnectionId client_connection_id,
-      bool ietf_quic,
-      bool use_length_prefix,
-      const ParsedQuicVersionVector& versions);
-
-  // Returns a new IETF version negotiation packet.
-  static std::unique_ptr<QuicEncryptedPacket> BuildIetfVersionNegotiationPacket(
-      bool use_length_prefix,
-      QuicConnectionId server_connection_id,
-      QuicConnectionId client_connection_id,
-      const ParsedQuicVersionVector& versions);
-
-  // If header.version_flag is set, the version in the
-  // packet will be set -- but it will be set from version_ not
-  // header.versions.
-  bool AppendPacketHeader(const QuicPacketHeader& header,
-                          QuicDataWriter* writer,
-                          size_t* length_field_offset);
-  bool AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
-                                QuicDataWriter* writer);
-  bool AppendIetfPacketHeader(const QuicPacketHeader& header,
-                              QuicDataWriter* writer,
-                              size_t* length_field_offset);
-  bool WriteIetfLongHeaderLength(const QuicPacketHeader& header,
-                                 QuicDataWriter* writer,
-                                 size_t length_field_offset,
-                                 EncryptionLevel level);
-  bool AppendTypeByte(const QuicFrame& frame,
-                      bool last_frame_in_packet,
-                      QuicDataWriter* writer);
-  bool AppendIetfFrameType(const QuicFrame& frame,
-                           bool last_frame_in_packet,
-                           QuicDataWriter* writer);
-  size_t AppendIetfFrames(const QuicFrames& frames, QuicDataWriter* writer);
-  bool AppendStreamFrame(const QuicStreamFrame& frame,
-                         bool no_stream_frame_length, QuicDataWriter* writer);
-  bool AppendCryptoFrame(const QuicCryptoFrame& frame, QuicDataWriter* writer);
-  bool AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
-                               QuicDataWriter* writer);
-
-  // SetDecrypter sets the primary decrypter, replacing any that already exists.
-  // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
-  // This is intended for cases where one knows that future packets will be
-  // using the new decrypter and the previous decrypter is now obsolete. |level|
-  // indicates the encryption level of the new decrypter.
-  void SetDecrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicDecrypter> decrypter);
-
-  // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
-  // future packets. |level| indicates the encryption level of the decrypter. If
-  // |latch_once_used| is true, then the first time that the decrypter is
-  // successful it will replace the primary decrypter.  Otherwise both
-  // decrypters will remain active and the primary decrypter will be the one
-  // last used.
-  void SetAlternativeDecrypter(EncryptionLevel level,
-                               std::unique_ptr<QuicDecrypter> decrypter,
-                               bool latch_once_used);
-
-  void InstallDecrypter(EncryptionLevel level,
-                        std::unique_ptr<QuicDecrypter> decrypter);
-  void RemoveDecrypter(EncryptionLevel level);
-
-  // Enables key update support.
-  void SetKeyUpdateSupportForConnection(bool enabled);
-  // Discard the decrypter for the previous key phase.
-  void DiscardPreviousOneRttKeys();
-  // Update the key phase.
-  bool DoKeyUpdate(KeyUpdateReason reason);
-  // Returns the count of packets received that appeared to attempt a key
-  // update but failed decryption which have been received since the last
-  // successfully decrypted packet.
-  QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
-
-  const QuicDecrypter* GetDecrypter(EncryptionLevel level) const;
-  const QuicDecrypter* decrypter() const;
-  const QuicDecrypter* alternative_decrypter() const;
-
-  // Changes the encrypter used for level |level| to |encrypter|.
-  void SetEncrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicEncrypter> encrypter);
-
-  // Called to remove encrypter of encryption |level|.
-  void RemoveEncrypter(EncryptionLevel level);
-
-  // Sets the encrypter and decrypter for the ENCRYPTION_INITIAL level.
-  void SetInitialObfuscators(QuicConnectionId connection_id);
-
-  // Encrypts a payload in |buffer|.  |ad_len| is the length of the associated
-  // data. |total_len| is the length of the associated data plus plaintext.
-  // |buffer_len| is the full length of the allocated buffer.
-  size_t EncryptInPlace(EncryptionLevel level,
-                        QuicPacketNumber packet_number,
-                        size_t ad_len,
-                        size_t total_len,
-                        size_t buffer_len,
-                        char* buffer);
-
-  // Returns the length of the data encrypted into |buffer| if |buffer_len| is
-  // long enough, and otherwise 0.
-  size_t EncryptPayload(EncryptionLevel level,
-                        QuicPacketNumber packet_number,
-                        const QuicPacket& packet,
-                        char* buffer,
-                        size_t buffer_len);
-
-  // Returns the length of the ciphertext that would be generated by encrypting
-  // to plaintext of size |plaintext_size| at the given level.
-  size_t GetCiphertextSize(EncryptionLevel level, size_t plaintext_size) const;
-
-  // Returns the maximum length of plaintext that can be encrypted
-  // to ciphertext no larger than |ciphertext_size|.
-  size_t GetMaxPlaintextSize(size_t ciphertext_size);
-
-  // Returns the maximum number of packets that can be safely encrypted with
-  // the active AEAD. 1-RTT keys must be set before calling this method.
-  QuicPacketCount GetOneRttEncrypterConfidentialityLimit() const;
-
-  const std::string& detailed_error() { return detailed_error_; }
-
-  // The minimum packet number length required to represent |packet_number|.
-  static QuicPacketNumberLength GetMinPacketNumberLength(
-      QuicPacketNumber packet_number);
-
-  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
-    supported_versions_ = versions;
-    version_ = versions[0];
-  }
-
-  // Tell framer to infer packet header type from version_.
-  void InferPacketHeaderTypeFromVersion();
-
-  // Returns true if |header| is considered as an stateless reset packet.
-  bool IsIetfStatelessResetPacket(const QuicPacketHeader& header) const;
-
-  // Returns true if encrypter of |level| is available.
-  bool HasEncrypterOfEncryptionLevel(EncryptionLevel level) const;
-  // Returns true if decrypter of |level| is available.
-  bool HasDecrypterOfEncryptionLevel(EncryptionLevel level) const;
-
-  // Returns true if an encrypter of |space| is available.
-  bool HasAnEncrypterForSpace(PacketNumberSpace space) const;
-
-  // Returns the encryption level to send application data. This should be only
-  // called with available encrypter for application data.
-  EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
-
-  void set_validate_flags(bool value) { validate_flags_ = value; }
-
-  Perspective perspective() const { return perspective_; }
-
-  QuicStreamFrameDataProducer* data_producer() const { return data_producer_; }
-
-  void set_data_producer(QuicStreamFrameDataProducer* data_producer) {
-    data_producer_ = data_producer;
-  }
-
-  QuicTime creation_time() const { return creation_time_; }
-
-  QuicPacketNumber first_sending_packet_number() const {
-    return first_sending_packet_number_;
-  }
-
-  uint64_t current_received_frame_type() const {
-    return current_received_frame_type_;
-  }
-
-  uint64_t previously_received_frame_type() const {
-    return previously_received_frame_type_;
-  }
-
-  // The connection ID length the framer expects on incoming IETF short headers
-  // on the server.
-  uint8_t GetExpectedServerConnectionIdLength() {
-    return expected_server_connection_id_length_;
-  }
-
-  // Change the expected destination connection ID length for short headers on
-  // the client.
-  void SetExpectedClientConnectionIdLength(
-      uint8_t expected_client_connection_id_length) {
-    expected_client_connection_id_length_ =
-        expected_client_connection_id_length;
-  }
-
-  void EnableMultiplePacketNumberSpacesSupport();
-
-  // Writes an array of bytes that, if sent as a UDP datagram, will trigger
-  // IETF QUIC Version Negotiation on servers. The bytes will be written to
-  // |packet_bytes|, which must point to |packet_length| bytes of memory.
-  // |packet_length| must be in the range [1200, 65535].
-  // |destination_connection_id_bytes| will be sent as the destination
-  // connection ID, and must point to |destination_connection_id_length| bytes
-  // of memory. |destination_connection_id_length| must be in the range [8,18].
-  // When targeting Google servers, it is recommended to use a
-  // |destination_connection_id_length| of 8.
-  static bool WriteClientVersionNegotiationProbePacket(
-      char* packet_bytes,
-      QuicByteCount packet_length,
-      const char* destination_connection_id_bytes,
-      uint8_t destination_connection_id_length);
-
-  // Parses a packet which a QUIC server sent in response to a packet sent by
-  // WriteClientVersionNegotiationProbePacket. |packet_bytes| must point to
-  // |packet_length| bytes in memory which represent the response.
-  // |packet_length| must be greater or equal to 6. This method will fill in
-  // |source_connection_id_bytes| which must point to at least
-  // |*source_connection_id_length_out| bytes in memory.
-  // |*source_connection_id_length_out| must be at least 18.
-  // |*source_connection_id_length_out| will contain the length of the received
-  // source connection ID, which on success will match the contents of the
-  // destination connection ID passed in to
-  // WriteClientVersionNegotiationProbePacket. In the case of a failure,
-  // |detailed_error| will be filled in with an explanation of what failed.
-  static bool ParseServerVersionNegotiationProbeResponse(
-      const char* packet_bytes,
-      QuicByteCount packet_length,
-      char* source_connection_id_bytes,
-      uint8_t* source_connection_id_length_out,
-      std::string* detailed_error);
-
-  void set_local_ack_delay_exponent(uint32_t exponent) {
-    local_ack_delay_exponent_ = exponent;
-  }
-  uint32_t local_ack_delay_exponent() const {
-    return local_ack_delay_exponent_;
-  }
-
-  void set_peer_ack_delay_exponent(uint32_t exponent) {
-    peer_ack_delay_exponent_ = exponent;
-  }
-  uint32_t peer_ack_delay_exponent() const { return peer_ack_delay_exponent_; }
-
-  void set_drop_incoming_retry_packets(bool drop_incoming_retry_packets) {
-    drop_incoming_retry_packets_ = drop_incoming_retry_packets;
-  }
-
- private:
-  friend class test::QuicFramerPeer;
-
-  using NackRangeMap = std::map<QuicPacketNumber, uint8_t>;
-
-  // AckTimestampRange is a data structure derived from a QuicAckFrame. It is
-  // used to serialize timestamps in a IETF_ACK_RECEIVE_TIMESTAMPS frame.
-  struct QUIC_EXPORT_PRIVATE AckTimestampRange {
-    QuicPacketCount gap;
-    // |range_begin| and |range_end| are index(es) in
-    // QuicAckFrame.received_packet_times, representing a continuous range of
-    // packet numbers in descending order. |range_begin| >= |range_end|.
-    int64_t range_begin;  // Inclusive
-    int64_t range_end;    // Inclusive
-  };
-  absl::InlinedVector<AckTimestampRange, 2> GetAckTimestampRanges(
-      const QuicAckFrame& frame, std::string& detailed_error) const;
-  int64_t FrameAckTimestampRanges(
-      const QuicAckFrame& frame,
-      const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
-      QuicDataWriter* writer) const;
-
-  struct QUIC_EXPORT_PRIVATE AckFrameInfo {
-    AckFrameInfo();
-    AckFrameInfo(const AckFrameInfo& other);
-    ~AckFrameInfo();
-
-    // The maximum ack block length.
-    QuicPacketCount max_block_length;
-    // Length of first ack block.
-    QuicPacketCount first_block_length;
-    // Number of ACK blocks needed for the ACK frame.
-    size_t num_ack_blocks;
-  };
-
-  // Applies header protection to an IETF QUIC packet header in |buffer| using
-  // the encrypter for level |level|. The buffer has |buffer_len| bytes of data,
-  // with the first protected packet bytes starting at |ad_len|.
-  bool ApplyHeaderProtection(EncryptionLevel level,
-                             char* buffer,
-                             size_t buffer_len,
-                             size_t ad_len);
-
-  // Removes header protection from an IETF QUIC packet header.
-  //
-  // The packet number from the header is read from |reader|, where the packet
-  // number is the next contents in |reader|. |reader| is only advanced by the
-  // length of the packet number, but it is also used to peek the sample needed
-  // for removing header protection.
-  //
-  // Properties needed for removing header protection are read from |header|.
-  // The packet number length and type byte are written to |header|.
-  //
-  // The packet number, after removing header protection and decoding it, is
-  // written to |full_packet_number|. Finally, the header, with header
-  // protection removed, is written to |associated_data| to be used in packet
-  // decryption. |packet| is used in computing the asociated data.
-  bool RemoveHeaderProtection(QuicDataReader* reader,
-                              const QuicEncryptedPacket& packet,
-                              QuicPacketHeader* header,
-                              uint64_t* full_packet_number,
-                              std::vector<char>* associated_data);
-
-  bool ProcessDataPacket(QuicDataReader* reader,
-                         QuicPacketHeader* header,
-                         const QuicEncryptedPacket& packet,
-                         char* decrypted_buffer,
-                         size_t buffer_length);
-
-  bool ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
-                             QuicPacketHeader* header,
-                             const QuicEncryptedPacket& packet,
-                             char* decrypted_buffer,
-                             size_t buffer_length);
-
-  bool ProcessPublicResetPacket(QuicDataReader* reader,
-                                const QuicPacketHeader& header);
-
-  bool ProcessVersionNegotiationPacket(QuicDataReader* reader,
-                                       const QuicPacketHeader& header);
-
-  bool ProcessRetryPacket(QuicDataReader* reader,
-                          const QuicPacketHeader& header);
-
-  void MaybeProcessCoalescedPacket(const QuicDataReader& encrypted_reader,
-                                   uint64_t remaining_bytes_length,
-                                   const QuicPacketHeader& header);
-
-  bool MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
-                              QuicPacketHeader* header);
-
-  bool ProcessPublicHeader(QuicDataReader* reader,
-                           bool packet_has_ietf_packet_header,
-                           QuicPacketHeader* header);
-
-  // Processes the unauthenticated portion of the header into |header| from
-  // the current QuicDataReader.  Returns true on success, false on failure.
-  bool ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
-                                    QuicPacketHeader* header);
-
-  // Processes the version label in the packet header.
-  static bool ProcessVersionLabel(QuicDataReader* reader,
-                                  QuicVersionLabel* version_label);
-
-  // Validates and updates |destination_connection_id_length| and
-  // |source_connection_id_length|. When
-  // |should_update_expected_server_connection_id_length| is true, length
-  // validation is disabled and |expected_server_connection_id_length| is set
-  // to the appropriate length.
-  // TODO(b/133873272) refactor this method.
-  static bool ProcessAndValidateIetfConnectionIdLength(
-      QuicDataReader* reader,
-      ParsedQuicVersion version,
-      Perspective perspective,
-      bool should_update_expected_server_connection_id_length,
-      uint8_t* expected_server_connection_id_length,
-      uint8_t* destination_connection_id_length,
-      uint8_t* source_connection_id_length,
-      std::string* detailed_error);
-
-  bool ProcessIetfHeaderTypeByte(QuicDataReader* reader,
-                                 QuicPacketHeader* header);
-  bool ProcessIetfPacketHeader(QuicDataReader* reader,
-                               QuicPacketHeader* header);
-
-  // First processes possibly truncated packet number. Calculates the full
-  // packet number from the truncated one and the last seen packet number, and
-  // stores it to |packet_number|.
-  bool ProcessAndCalculatePacketNumber(
-      QuicDataReader* reader,
-      QuicPacketNumberLength packet_number_length,
-      QuicPacketNumber base_packet_number,
-      uint64_t* packet_number);
-  bool ProcessFrameData(QuicDataReader* reader, const QuicPacketHeader& header);
-
-  static bool IsIetfFrameTypeExpectedForEncryptionLevel(uint64_t frame_type,
-                                                        EncryptionLevel level);
-
-  bool ProcessIetfFrameData(QuicDataReader* reader,
-                            const QuicPacketHeader& header,
-                            EncryptionLevel decrypted_level);
-  bool ProcessStreamFrame(QuicDataReader* reader,
-                          uint8_t frame_type,
-                          QuicStreamFrame* frame);
-  bool ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type);
-  bool ProcessTimestampsInAckFrame(uint8_t num_received_packets,
-                                   QuicPacketNumber largest_acked,
-                                   QuicDataReader* reader);
-  bool ProcessIetfAckFrame(QuicDataReader* reader,
-                           uint64_t frame_type,
-                           QuicAckFrame* ack_frame);
-  bool ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
-                                       QuicDataReader* reader);
-  bool ProcessStopWaitingFrame(QuicDataReader* reader,
-                               const QuicPacketHeader& header,
-                               QuicStopWaitingFrame* stop_waiting);
-  bool ProcessRstStreamFrame(QuicDataReader* reader, QuicRstStreamFrame* frame);
-  bool ProcessConnectionCloseFrame(QuicDataReader* reader,
-                                   QuicConnectionCloseFrame* frame);
-  bool ProcessGoAwayFrame(QuicDataReader* reader, QuicGoAwayFrame* frame);
-  bool ProcessWindowUpdateFrame(QuicDataReader* reader,
-                                QuicWindowUpdateFrame* frame);
-  bool ProcessBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
-  void ProcessPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame);
-  bool ProcessMessageFrame(QuicDataReader* reader,
-                           bool no_message_length,
-                           QuicMessageFrame* frame);
-
-  bool DecryptPayload(size_t udp_packet_length,
-                      absl::string_view encrypted,
-                      absl::string_view associated_data,
-                      const QuicPacketHeader& header,
-                      char* decrypted_buffer,
-                      size_t buffer_length,
-                      size_t* decrypted_length,
-                      EncryptionLevel* decrypted_level);
-
-  // Returns the full packet number from the truncated
-  // wire format version and the last seen packet number.
-  uint64_t CalculatePacketNumberFromWire(
-      QuicPacketNumberLength packet_number_length,
-      QuicPacketNumber base_packet_number,
-      uint64_t packet_number) const;
-
-  // Returns the QuicTime::Delta corresponding to the time from when the framer
-  // was created.
-  const QuicTime::Delta CalculateTimestampFromWire(uint32_t time_delta_us);
-
-  // Computes the wire size in bytes of time stamps in |ack|.
-  size_t GetAckFrameTimeStampSize(const QuicAckFrame& ack);
-  size_t GetIetfAckFrameTimestampSize(const QuicAckFrame& ack);
-
-  // Computes the wire size in bytes of the |ack| frame.
-  size_t GetAckFrameSize(const QuicAckFrame& ack,
-                         QuicPacketNumberLength packet_number_length);
-  // Computes the wire-size, in bytes, of the |frame| ack frame, for IETF Quic.
-  size_t GetIetfAckFrameSize(const QuicAckFrame& frame);
-
-  // Computes the wire size in bytes of the |ack| frame.
-  size_t GetAckFrameSize(const QuicAckFrame& ack);
-
-  // Computes the wire size in bytes of the payload of |frame|.
-  size_t ComputeFrameLength(const QuicFrame& frame,
-                            bool last_frame_in_packet,
-                            QuicPacketNumberLength packet_number_length);
-
-  static bool AppendPacketNumber(QuicPacketNumberLength packet_number_length,
-                                 QuicPacketNumber packet_number,
-                                 QuicDataWriter* writer);
-  static bool AppendStreamId(size_t stream_id_length,
-                             QuicStreamId stream_id,
-                             QuicDataWriter* writer);
-  static bool AppendStreamOffset(size_t offset_length,
-                                 QuicStreamOffset offset,
-                                 QuicDataWriter* writer);
-
-  // Appends a single ACK block to |writer| and returns true if the block was
-  // successfully appended.
-  static bool AppendAckBlock(uint8_t gap,
-                             QuicPacketNumberLength length_length,
-                             uint64_t length,
-                             QuicDataWriter* writer);
-
-  static uint8_t GetPacketNumberFlags(
-      QuicPacketNumberLength packet_number_length);
-
-  static AckFrameInfo GetAckFrameInfo(const QuicAckFrame& frame);
-
-  static QuicErrorCode ParsePublicHeaderGoogleQuic(
-      QuicDataReader* reader,
-      uint8_t* first_byte,
-      PacketHeaderFormat* format,
-      bool* version_present,
-      QuicVersionLabel* version_label,
-      ParsedQuicVersion* parsed_version,
-      QuicConnectionId* destination_connection_id,
-      std::string* detailed_error);
-
-  bool ValidateReceivedConnectionIds(const QuicPacketHeader& header);
-
-  // The Append* methods attempt to write the provided header or frame using the
-  // |writer|, and return true if successful.
-
-  bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
-                                 QuicDataWriter* writer);
-  bool AppendTimestampsToAckFrame(const QuicAckFrame& frame,
-                                  QuicDataWriter* writer);
-
-  // Append IETF format ACK frame.
-  //
-  // AppendIetfAckFrameAndTypeByte adds the IETF type byte and the body
-  // of the frame.
-  bool AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
-                                     QuicDataWriter* writer);
-  bool AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
-                                      QuicDataWriter* writer);
-
-  bool AppendStopWaitingFrame(const QuicPacketHeader& header,
-                              const QuicStopWaitingFrame& frame,
-                              QuicDataWriter* writer);
-  bool AppendRstStreamFrame(const QuicRstStreamFrame& frame,
-                            QuicDataWriter* writer);
-  bool AppendConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
-                                  QuicDataWriter* writer);
-  bool AppendGoAwayFrame(const QuicGoAwayFrame& frame, QuicDataWriter* writer);
-  bool AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
-                               QuicDataWriter* writer);
-  bool AppendBlockedFrame(const QuicBlockedFrame& frame,
-                          QuicDataWriter* writer);
-  bool AppendPaddingFrame(const QuicPaddingFrame& frame,
-                          QuicDataWriter* writer);
-  bool AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
-                                     bool last_frame_in_packet,
-                                     QuicDataWriter* writer);
-
-  // IETF frame processing methods.
-  bool ProcessIetfStreamFrame(QuicDataReader* reader,
-                              uint8_t frame_type,
-                              QuicStreamFrame* frame);
-  bool ProcessIetfConnectionCloseFrame(QuicDataReader* reader,
-                                       QuicConnectionCloseType type,
-                                       QuicConnectionCloseFrame* frame);
-  bool ProcessPathChallengeFrame(QuicDataReader* reader,
-                                 QuicPathChallengeFrame* frame);
-  bool ProcessPathResponseFrame(QuicDataReader* reader,
-                                QuicPathResponseFrame* frame);
-  bool ProcessIetfResetStreamFrame(QuicDataReader* reader,
-                                   QuicRstStreamFrame* frame);
-  bool ProcessStopSendingFrame(QuicDataReader* reader,
-                               QuicStopSendingFrame* stop_sending_frame);
-  bool ProcessCryptoFrame(QuicDataReader* reader,
-                          EncryptionLevel encryption_level,
-                          QuicCryptoFrame* frame);
-  bool ProcessAckFrequencyFrame(QuicDataReader* reader,
-                                QuicAckFrequencyFrame* frame);
-  // IETF frame appending methods.  All methods append the type byte as well.
-  bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
-                             bool last_frame_in_packet,
-                             QuicDataWriter* writer);
-  bool AppendIetfConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
-                                      QuicDataWriter* writer);
-  bool AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
-                                QuicDataWriter* writer);
-  bool AppendPathResponseFrame(const QuicPathResponseFrame& frame,
-                               QuicDataWriter* writer);
-  bool AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
-                                  QuicDataWriter* writer);
-  bool AppendStopSendingFrame(const QuicStopSendingFrame& stop_sending_frame,
-                              QuicDataWriter* writer);
-
-  // Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
-  bool AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
-                          QuicDataWriter* writer);
-  bool AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
-                                QuicDataWriter* writer);
-  bool ProcessMaxDataFrame(QuicDataReader* reader,
-                           QuicWindowUpdateFrame* frame);
-  bool ProcessMaxStreamDataFrame(QuicDataReader* reader,
-                                 QuicWindowUpdateFrame* frame);
-
-  bool AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
-                             QuicDataWriter* writer);
-  bool ProcessMaxStreamsFrame(QuicDataReader* reader,
-                              QuicMaxStreamsFrame* frame,
-                              uint64_t frame_type);
-
-  bool AppendDataBlockedFrame(const QuicBlockedFrame& frame,
-                              QuicDataWriter* writer);
-  bool ProcessDataBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
-
-  bool AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
-                                    QuicDataWriter* writer);
-  bool ProcessStreamDataBlockedFrame(QuicDataReader* reader,
-                                     QuicBlockedFrame* frame);
-
-  bool AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
-                                 QuicDataWriter* writer);
-  bool ProcessStreamsBlockedFrame(QuicDataReader* reader,
-                                  QuicStreamsBlockedFrame* frame,
-                                  uint64_t frame_type);
-
-  bool AppendNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
-                                  QuicDataWriter* writer);
-  bool ProcessNewConnectionIdFrame(QuicDataReader* reader,
-                                   QuicNewConnectionIdFrame* frame);
-  bool AppendRetireConnectionIdFrame(const QuicRetireConnectionIdFrame& frame,
-                                     QuicDataWriter* writer);
-  bool ProcessRetireConnectionIdFrame(QuicDataReader* reader,
-                                      QuicRetireConnectionIdFrame* frame);
-
-  bool AppendNewTokenFrame(const QuicNewTokenFrame& frame,
-                           QuicDataWriter* writer);
-  bool ProcessNewTokenFrame(QuicDataReader* reader, QuicNewTokenFrame* frame);
-
-  bool RaiseError(QuicErrorCode error);
-
-  // Returns true if |header| indicates a version negotiation packet.
-  bool IsVersionNegotiation(const QuicPacketHeader& header,
-                            bool packet_has_ietf_packet_header) const;
-
-  // Calculates and returns type byte of stream frame.
-  uint8_t GetStreamFrameTypeByte(const QuicStreamFrame& frame,
-                                 bool last_frame_in_packet) const;
-  uint8_t GetIetfStreamFrameTypeByte(const QuicStreamFrame& frame,
-                                     bool last_frame_in_packet) const;
-
-  void set_error(QuicErrorCode error) { error_ = error; }
-
-  void set_detailed_error(const char* error) { detailed_error_ = error; }
-  void set_detailed_error(std::string error) { detailed_error_ = error; }
-
-  // Returns false if the reading fails.
-  bool ReadUint32FromVarint62(QuicDataReader* reader,
-                              QuicIetfFrameType type,
-                              QuicStreamId* id);
-
-  bool ProcessPacketInternal(const QuicEncryptedPacket& packet);
-
-  // Determine whether the given QuicAckFrame should be serialized with a
-  // IETF_ACK_RECEIVE_TIMESTAMPS frame type.
-  bool UseIetfAckWithReceiveTimestamp(const QuicAckFrame& frame) const {
-    return VersionHasIetfQuicFrames(version_.transport_version) &&
-           process_timestamps_ &&
-           std::min<uint64_t>(max_receive_timestamps_per_ack_,
-                              frame.received_packet_times.size()) > 0;
-  }
-
-  std::string detailed_error_;
-  QuicFramerVisitorInterface* visitor_;
-  QuicErrorCode error_;
-  // Updated by ProcessPacketHeader when it succeeds decrypting a larger packet.
-  QuicPacketNumber largest_packet_number_;
-  // Largest successfully decrypted packet number per packet number space. Only
-  // used when supports_multiple_packet_number_spaces_ is true.
-  QuicPacketNumber largest_decrypted_packet_numbers_[NUM_PACKET_NUMBER_SPACES];
-  // Last server connection ID seen on the wire.
-  QuicConnectionId last_serialized_server_connection_id_;
-  // Last client connection ID seen on the wire.
-  QuicConnectionId last_serialized_client_connection_id_;
-  // Version of the protocol being used.
-  ParsedQuicVersion version_;
-  // This vector contains QUIC versions which we currently support.
-  // This should be ordered such that the highest supported version is the first
-  // element, with subsequent elements in descending order (versions can be
-  // skipped as necessary).
-  ParsedQuicVersionVector supported_versions_;
-  // Decrypters used to decrypt packets during parsing.
-  std::unique_ptr<QuicDecrypter> decrypter_[NUM_ENCRYPTION_LEVELS];
-  // The encryption level of the primary decrypter to use in |decrypter_|.
-  EncryptionLevel decrypter_level_;
-  // The encryption level of the alternative decrypter to use in |decrypter_|.
-  // When set to NUM_ENCRYPTION_LEVELS, indicates that there is no alternative
-  // decrypter.
-  EncryptionLevel alternative_decrypter_level_;
-  // |alternative_decrypter_latch_| is true if, when the decrypter at
-  // |alternative_decrypter_level_| successfully decrypts a packet, we should
-  // install it as the only decrypter.
-  bool alternative_decrypter_latch_;
-  // Encrypters used to encrypt packets via EncryptPayload().
-  std::unique_ptr<QuicEncrypter> encrypter_[NUM_ENCRYPTION_LEVELS];
-  // Tracks if the framer is being used by the entity that received the
-  // connection or the entity that initiated it.
-  Perspective perspective_;
-  // If false, skip validation that the public flags are set to legal values.
-  bool validate_flags_;
-  // The diversification nonce from the last received packet.
-  DiversificationNonce last_nonce_;
-  // If true, send and process timestamps in the ACK frame.
-  // TODO(ianswett): Remove the mutables once set_process_timestamps and
-  // set_receive_timestamp_exponent_ aren't const.
-  mutable bool process_timestamps_;
-  // The max number of receive timestamps to send per ACK frame.
-  mutable uint32_t max_receive_timestamps_per_ack_;
-  // The exponent to use when writing/reading ACK receive timestamps.
-  mutable uint32_t receive_timestamps_exponent_;
-  // The creation time of the connection, used to calculate timestamps.
-  QuicTime creation_time_;
-  // The last timestamp received if process_timestamps_ is true.
-  QuicTime::Delta last_timestamp_;
-
-  // Whether IETF QUIC Key Update is supported on this connection.
-  bool support_key_update_for_connection_;
-  // The value of the current key phase bit, which is toggled when the keys are
-  // changed.
-  bool current_key_phase_bit_;
-  // Whether we have performed a key update at least once.
-  bool key_update_performed_ = false;
-  // Tracks the first packet received in the current key phase. Will be
-  // uninitialized before the first one-RTT packet has been received or after a
-  // locally initiated key update but before the first packet from the peer in
-  // the new key phase is received.
-  QuicPacketNumber current_key_phase_first_received_packet_number_;
-  // Counts the number of packets received that might have been failed key
-  // update attempts. Reset to zero every time a packet is successfully
-  // decrypted.
-  QuicPacketCount potential_peer_key_update_attempt_count_;
-  // Decrypter for the previous key phase. Will be null if in the first key
-  // phase or previous keys have been discarded.
-  std::unique_ptr<QuicDecrypter> previous_decrypter_;
-  // Decrypter for the next key phase. May be null if next keys haven't been
-  // generated yet.
-  std::unique_ptr<QuicDecrypter> next_decrypter_;
-
-  // If this is a framer of a connection, this is the packet number of first
-  // sending packet. If this is a framer of a framer of dispatcher, this is the
-  // packet number of sent packets (for those which have packet number).
-  const QuicPacketNumber first_sending_packet_number_;
-
-  // If not null, framer asks data_producer_ to write stream frame data. Not
-  // owned. TODO(fayang): Consider add data producer to framer's constructor.
-  QuicStreamFrameDataProducer* data_producer_;
-
-  // Whether we are in the middle of a call to this->ProcessPacket.
-  bool is_processing_packet_ = false;
-
-  // If true, framer infers packet header type (IETF/GQUIC) from version_.
-  // Otherwise, framer infers packet header type from first byte of a received
-  // packet.
-  bool infer_packet_header_type_from_version_;
-
-  // IETF short headers contain a destination connection ID but do not
-  // encode its length. These variables contains the length we expect to read.
-  // This is also used to validate the long header destination connection ID
-  // lengths in older versions of QUIC.
-  uint8_t expected_server_connection_id_length_;
-  uint8_t expected_client_connection_id_length_;
-
-  // Indicates whether this framer supports multiple packet number spaces.
-  bool supports_multiple_packet_number_spaces_;
-
-  // Indicates whether received RETRY packets should be dropped.
-  bool drop_incoming_retry_packets_ = false;
-
-  // The length in bytes of the last packet number written to an IETF-framed
-  // packet.
-  size_t last_written_packet_number_length_;
-
-  // The amount to shift the ack timestamp in ACK frames. The default is 3.
-  // Local_ is the amount this node shifts timestamps in ACK frames it
-  // generates. it is sent to the peer in a transport parameter negotiation.
-  // Peer_ is the amount the peer shifts timestamps when it sends ACK frames to
-  // this node. This node "unshifts" by this amount. The value is received from
-  // the peer in the transport parameter negotiation. IETF QUIC only.
-  uint32_t peer_ack_delay_exponent_;
-  uint32_t local_ack_delay_exponent_;
-
-  // The type of received IETF frame currently being processed.  0 when not
-  // processing a frame or when processing Google QUIC frames.  Used to populate
-  // the Transport Connection Close when there is an error during frame
-  // processing.
-  uint64_t current_received_frame_type_;
-
-  // TODO(haoyuewang) Remove this debug utility.
-  // The type of the IETF frame preceding the frame currently being processed. 0
-  // when not processing a frame or only 1 frame has been processed.
-  uint64_t previously_received_frame_type_;
-};
-
-// Look for and parse the error code from the "<quic_error_code>:" text that
-// may be present at the start of the CONNECTION_CLOSE error details string.
-// This text, inserted by the peer if it's using Google's QUIC implementation,
-// contains additional error information that narrows down the exact error. The
-// extracted error code and (possibly updated) error_details string are returned
-// in |*frame|. If an error code is not found in the error details, then
-// frame->quic_error_code is set to
-// QuicErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING.  If there is an error code in
-// the string then it is removed from the string.
-QUIC_EXPORT_PRIVATE void MaybeExtractQuicErrorCode(
-    QuicConnectionCloseFrame* frame);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_FRAMER_H_
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
deleted file mode 100644
index 40692cd..0000000
--- a/quic/core/quic_framer_test.cc
+++ /dev/null
@@ -1,16373 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_framer.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-using testing::ContainerEq;
-using testing::Return;
-
-namespace quic {
-namespace test {
-namespace {
-
-const uint64_t kEpoch = UINT64_C(1) << 32;
-const uint64_t kMask = kEpoch - 1;
-
-const StatelessResetToken kTestStatelessResetToken{
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
-
-// Use fields in which each byte is distinct to ensure that every byte is
-// framed correctly. The values are otherwise arbitrary.
-QuicConnectionId FramerTestConnectionId() {
-  return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
-}
-
-QuicConnectionId FramerTestConnectionIdPlusOne() {
-  return TestConnectionId(UINT64_C(0xFEDCBA9876543211));
-}
-
-QuicConnectionId FramerTestConnectionIdNineBytes() {
-  uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
-                                    0x54, 0x32, 0x10, 0x42};
-  return QuicConnectionId(reinterpret_cast<char*>(connection_id_bytes),
-                          sizeof(connection_id_bytes));
-}
-
-const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
-const QuicPacketNumber kSmallLargestObserved =
-    QuicPacketNumber(UINT16_C(0x1234));
-const QuicPacketNumber kSmallMissingPacket = QuicPacketNumber(UINT16_C(0x1233));
-const QuicPacketNumber kLeastUnacked = QuicPacketNumber(UINT64_C(0x012345670));
-const QuicStreamId kStreamId = UINT64_C(0x01020304);
-// Note that the high 4 bits of the stream offset must be less than 0x40
-// in order to ensure that the value can be encoded using VarInt62 encoding.
-const QuicStreamOffset kStreamOffset = UINT64_C(0x3A98FEDC32107654);
-const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789);
-
-// In testing that we can ack the full range of packets...
-// This is the largest packet number that can be represented in IETF QUIC
-// varint62 format.
-const QuicPacketNumber kLargestIetfLargestObserved =
-    QuicPacketNumber(UINT64_C(0x3fffffffffffffff));
-// Encodings for the two bits in a VarInt62 that
-// describe the length of the VarInt61. For binary packet
-// formats in this file, the convention is to code the
-// first byte as
-//   kVarInt62FourBytes + 0x<value_in_that_byte>
-const uint8_t kVarInt62OneByte = 0x00;
-const uint8_t kVarInt62TwoBytes = 0x40;
-const uint8_t kVarInt62FourBytes = 0x80;
-const uint8_t kVarInt62EightBytes = 0xc0;
-
-class TestEncrypter : public QuicEncrypter {
- public:
-  ~TestEncrypter() override {}
-  bool SetKey(absl::string_view /*key*/) override { return true; }
-  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
-    return true;
-  }
-  bool SetIV(absl::string_view /*iv*/) override { return true; }
-  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
-    return true;
-  }
-  bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
-                     absl::string_view plaintext, char* output,
-                     size_t* output_length,
-                     size_t /*max_output_length*/) override {
-    packet_number_ = QuicPacketNumber(packet_number);
-    associated_data_ = std::string(associated_data);
-    plaintext_ = std::string(plaintext);
-    memcpy(output, plaintext.data(), plaintext.length());
-    *output_length = plaintext.length();
-    return true;
-  }
-  std::string GenerateHeaderProtectionMask(
-      absl::string_view /*sample*/) override {
-    return std::string(5, 0);
-  }
-  size_t GetKeySize() const override { return 0; }
-  size_t GetNoncePrefixSize() const override { return 0; }
-  size_t GetIVSize() const override { return 0; }
-  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
-    return ciphertext_size;
-  }
-  size_t GetCiphertextSize(size_t plaintext_size) const override {
-    return plaintext_size;
-  }
-  QuicPacketCount GetConfidentialityLimit() const override {
-    return std::numeric_limits<QuicPacketCount>::max();
-  }
-  absl::string_view GetKey() const override { return absl::string_view(); }
-  absl::string_view GetNoncePrefix() const override {
-    return absl::string_view();
-  }
-
-  QuicPacketNumber packet_number_;
-  std::string associated_data_;
-  std::string plaintext_;
-};
-
-class TestDecrypter : public QuicDecrypter {
- public:
-  ~TestDecrypter() override {}
-  bool SetKey(absl::string_view /*key*/) override { return true; }
-  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
-    return true;
-  }
-  bool SetIV(absl::string_view /*iv*/) override { return true; }
-  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
-    return true;
-  }
-  bool SetPreliminaryKey(absl::string_view /*key*/) override {
-    QUIC_BUG(quic_bug_10486_1) << "should not be called";
-    return false;
-  }
-  bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
-    return true;
-  }
-  bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
-                     absl::string_view ciphertext, char* output,
-                     size_t* output_length,
-                     size_t /*max_output_length*/) override {
-    packet_number_ = QuicPacketNumber(packet_number);
-    associated_data_ = std::string(associated_data);
-    ciphertext_ = std::string(ciphertext);
-    memcpy(output, ciphertext.data(), ciphertext.length());
-    *output_length = ciphertext.length();
-    return true;
-  }
-  std::string GenerateHeaderProtectionMask(
-      QuicDataReader* /*sample_reader*/) override {
-    return std::string(5, 0);
-  }
-  size_t GetKeySize() const override { return 0; }
-  size_t GetNoncePrefixSize() const override { return 0; }
-  size_t GetIVSize() const override { return 0; }
-  absl::string_view GetKey() const override { return absl::string_view(); }
-  absl::string_view GetNoncePrefix() const override {
-    return absl::string_view();
-  }
-  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
-  uint32_t cipher_id() const override { return 0xFFFFFFF2; }
-  QuicPacketCount GetIntegrityLimit() const override {
-    return std::numeric_limits<QuicPacketCount>::max();
-  }
-  QuicPacketNumber packet_number_;
-  std::string associated_data_;
-  std::string ciphertext_;
-};
-
-std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase(
-    const QuicPacket& packet, uint8_t tag, bool phase) {
-  std::string packet_data = std::string(packet.AsStringPiece());
-  if (phase) {
-    packet_data[0] |= FLAGS_KEY_PHASE_BIT;
-  } else {
-    packet_data[0] &= ~FLAGS_KEY_PHASE_BIT;
-  }
-
-  TaggingEncrypter crypter(tag);
-  const size_t packet_size = crypter.GetCiphertextSize(packet_data.size());
-  char* buffer = new char[packet_size];
-  size_t buf_len = 0;
-  if (!crypter.EncryptPacket(0, absl::string_view(), packet_data, buffer,
-                             &buf_len, packet_size)) {
-    delete[] buffer;
-    return nullptr;
-  }
-
-  return std::make_unique<QuicEncryptedPacket>(buffer, buf_len,
-                                               /*owns_buffer=*/true);
-}
-
-class TestQuicVisitor : public QuicFramerVisitorInterface {
- public:
-  TestQuicVisitor()
-      : error_count_(0),
-        version_mismatch_(0),
-        packet_count_(0),
-        frame_count_(0),
-        complete_packets_(0),
-        derive_next_key_count_(0),
-        decrypted_first_packet_in_key_phase_count_(0),
-        accept_packet_(true),
-        accept_public_header_(true) {}
-
-  ~TestQuicVisitor() override {}
-
-  void OnError(QuicFramer* f) override {
-    QUIC_DLOG(INFO) << "QuicFramer Error: " << QuicErrorCodeToString(f->error())
-                    << " (" << f->error() << ")";
-    ++error_count_;
-  }
-
-  void OnPacket() override {}
-
-  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
-    public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-  }
-
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& packet) override {
-    version_negotiation_packet_ =
-        std::make_unique<QuicVersionNegotiationPacket>((packet));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-  }
-
-  void OnRetryPacket(QuicConnectionId original_connection_id,
-                     QuicConnectionId new_connection_id,
-                     absl::string_view retry_token,
-                     absl::string_view retry_integrity_tag,
-                     absl::string_view retry_without_tag) override {
-    on_retry_packet_called_ = true;
-    retry_original_connection_id_ =
-        std::make_unique<QuicConnectionId>(original_connection_id);
-    retry_new_connection_id_ =
-        std::make_unique<QuicConnectionId>(new_connection_id);
-    retry_token_ = std::make_unique<std::string>(std::string(retry_token));
-    retry_token_integrity_tag_ =
-        std::make_unique<std::string>(std::string(retry_integrity_tag));
-    retry_without_tag_ =
-        std::make_unique<std::string>(std::string(retry_without_tag));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-  }
-
-  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
-    QUIC_DLOG(INFO) << "QuicFramer Version Mismatch, version: "
-                    << received_version;
-    ++version_mismatch_;
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return false;
-  }
-
-  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
-    header_ = std::make_unique<QuicPacketHeader>((header));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return accept_public_header_;
-  }
-
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return true;
-  }
-
-  void OnDecryptedPacket(size_t /*length*/,
-                         EncryptionLevel /*level*/) override {
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-  }
-
-  bool OnPacketHeader(const QuicPacketHeader& header) override {
-    ++packet_count_;
-    header_ = std::make_unique<QuicPacketHeader>((header));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return accept_packet_;
-  }
-
-  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
-    coalesced_packets_.push_back(packet.Clone());
-  }
-
-  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
-                             EncryptionLevel decryption_level,
-                             bool has_decryption_key) override {
-    undecryptable_packets_.push_back(packet.Clone());
-    undecryptable_decryption_levels_.push_back(decryption_level);
-    undecryptable_has_decryption_keys_.push_back(has_decryption_key);
-  }
-
-  bool OnStreamFrame(const QuicStreamFrame& frame) override {
-    ++frame_count_;
-    // Save a copy of the data so it is valid after the packet is processed.
-    std::string* string_data =
-        new std::string(frame.data_buffer, frame.data_length);
-    stream_data_.push_back(absl::WrapUnique(string_data));
-    stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
-        frame.stream_id, frame.fin, frame.offset, *string_data));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      // Low order bits of type encode flags, ignore them for this test.
-      EXPECT_TRUE(IS_IETF_STREAM_FRAME(framer_->current_received_frame_type()));
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
-    ++frame_count_;
-    // Save a copy of the data so it is valid after the packet is processed.
-    std::string* string_data =
-        new std::string(frame.data_buffer, frame.data_length);
-    crypto_data_.push_back(absl::WrapUnique(string_data));
-    crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
-        frame.level, frame.offset, *string_data));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_EQ(IETF_CRYPTO, framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta ack_delay_time) override {
-    ++frame_count_;
-    QuicAckFrame ack_frame;
-    ack_frame.largest_acked = largest_acked;
-    ack_frame.ack_delay_time = ack_delay_time;
-    ack_frames_.push_back(std::make_unique<QuicAckFrame>(ack_frame));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
-                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
-                  IETF_ACK_RECEIVE_TIMESTAMPS ==
-                      framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
-    QUICHE_DCHECK(!ack_frames_.empty());
-    ack_frames_[ack_frames_.size() - 1]->packets.AddRange(start, end);
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
-                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
-                  IETF_ACK_RECEIVE_TIMESTAMPS ==
-                      framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnAckTimestamp(QuicPacketNumber packet_number,
-                      QuicTime timestamp) override {
-    ack_frames_[ack_frames_.size() - 1]->received_packet_times.push_back(
-        std::make_pair(packet_number, timestamp));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
-                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
-                  IETF_ACK_RECEIVE_TIMESTAMPS ==
-                      framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
-
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
-    ++frame_count_;
-    stop_waiting_frames_.push_back(
-        std::make_unique<QuicStopWaitingFrame>(frame));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return true;
-  }
-
-  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
-    padding_frames_.push_back(std::make_unique<QuicPaddingFrame>(frame));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_EQ(IETF_PADDING, framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnPingFrame(const QuicPingFrame& frame) override {
-    ++frame_count_;
-    ping_frames_.push_back(std::make_unique<QuicPingFrame>(frame));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_EQ(IETF_PING, framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnMessageFrame(const QuicMessageFrame& frame) override {
-    ++frame_count_;
-    message_frames_.push_back(
-        std::make_unique<QuicMessageFrame>(frame.data, frame.message_length));
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_TRUE(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 ==
-                      framer_->current_received_frame_type() ||
-                  IETF_EXTENSION_MESSAGE_V99 ==
-                      framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
-    ++frame_count_;
-    handshake_done_frames_.push_back(
-        std::make_unique<QuicHandshakeDoneFrame>(frame));
-    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
-    EXPECT_EQ(IETF_HANDSHAKE_DONE, framer_->current_received_frame_type());
-    return true;
-  }
-
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
-    ++frame_count_;
-    ack_frequency_frames_.emplace_back(
-        std::make_unique<QuicAckFrequencyFrame>(frame));
-    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
-    EXPECT_EQ(IETF_ACK_FREQUENCY, framer_->current_received_frame_type());
-    return true;
-  }
-
-  void OnPacketComplete() override { ++complete_packets_; }
-
-  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
-    rst_stream_frame_ = frame;
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_EQ(IETF_RST_STREAM, framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
-    connection_close_frame_ = frame;
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_NE(GOOGLE_QUIC_CONNECTION_CLOSE, frame.close_type);
-      if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
-        EXPECT_EQ(IETF_CONNECTION_CLOSE,
-                  framer_->current_received_frame_type());
-      } else {
-        EXPECT_EQ(IETF_APPLICATION_CLOSE,
-                  framer_->current_received_frame_type());
-      }
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
-    stop_sending_frame_ = frame;
-    EXPECT_EQ(IETF_STOP_SENDING, framer_->current_received_frame_type());
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    return true;
-  }
-
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
-    path_challenge_frame_ = frame;
-    EXPECT_EQ(IETF_PATH_CHALLENGE, framer_->current_received_frame_type());
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    return true;
-  }
-
-  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
-    path_response_frame_ = frame;
-    EXPECT_EQ(IETF_PATH_RESPONSE, framer_->current_received_frame_type());
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    return true;
-  }
-
-  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
-    goaway_frame_ = frame;
-    EXPECT_FALSE(VersionHasIetfQuicFrames(transport_version_));
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return true;
-  }
-
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
-    max_streams_frame_ = frame;
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    EXPECT_TRUE(IETF_MAX_STREAMS_UNIDIRECTIONAL ==
-                    framer_->current_received_frame_type() ||
-                IETF_MAX_STREAMS_BIDIRECTIONAL ==
-                    framer_->current_received_frame_type());
-    return true;
-  }
-
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
-    streams_blocked_frame_ = frame;
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    EXPECT_TRUE(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL ==
-                    framer_->current_received_frame_type() ||
-                IETF_STREAMS_BLOCKED_BIDIRECTIONAL ==
-                    framer_->current_received_frame_type());
-    return true;
-  }
-
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
-    window_update_frame_ = frame;
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_TRUE(IETF_MAX_DATA == framer_->current_received_frame_type() ||
-                  IETF_MAX_STREAM_DATA ==
-                      framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
-    blocked_frame_ = frame;
-    if (VersionHasIetfQuicFrames(transport_version_)) {
-      EXPECT_TRUE(IETF_DATA_BLOCKED == framer_->current_received_frame_type() ||
-                  IETF_STREAM_DATA_BLOCKED ==
-                      framer_->current_received_frame_type());
-    } else {
-      EXPECT_EQ(0u, framer_->current_received_frame_type());
-    }
-    return true;
-  }
-
-  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
-    new_connection_id_ = frame;
-    EXPECT_EQ(IETF_NEW_CONNECTION_ID, framer_->current_received_frame_type());
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    return true;
-  }
-
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) override {
-    EXPECT_EQ(IETF_RETIRE_CONNECTION_ID,
-              framer_->current_received_frame_type());
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    retire_connection_id_ = frame;
-    return true;
-  }
-
-  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
-    new_token_ = frame;
-    EXPECT_EQ(IETF_NEW_TOKEN, framer_->current_received_frame_type());
-    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
-    return true;
-  }
-
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& token) const override {
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-    return token == kTestStatelessResetToken;
-  }
-
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& packet) override {
-    stateless_reset_packet_ =
-        std::make_unique<QuicIetfStatelessResetPacket>(packet);
-    EXPECT_EQ(0u, framer_->current_received_frame_type());
-  }
-
-  void OnKeyUpdate(KeyUpdateReason reason) override {
-    key_update_reasons_.push_back(reason);
-  }
-
-  void OnDecryptedFirstPacketInKeyPhase() override {
-    decrypted_first_packet_in_key_phase_count_++;
-  }
-
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    derive_next_key_count_++;
-    return std::make_unique<StrictTaggingDecrypter>(derive_next_key_count_);
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return std::make_unique<TaggingEncrypter>(derive_next_key_count_);
-  }
-
-  void set_framer(QuicFramer* framer) {
-    framer_ = framer;
-    transport_version_ = framer->transport_version();
-  }
-
-  size_t key_update_count() const { return key_update_reasons_.size(); }
-
-  // Counters from the visitor_ callbacks.
-  int error_count_;
-  int version_mismatch_;
-  int packet_count_;
-  int frame_count_;
-  int complete_packets_;
-  std::vector<KeyUpdateReason> key_update_reasons_;
-  int derive_next_key_count_;
-  int decrypted_first_packet_in_key_phase_count_;
-  bool accept_packet_;
-  bool accept_public_header_;
-
-  std::unique_ptr<QuicPacketHeader> header_;
-  std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
-  std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
-  std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
-  std::unique_ptr<QuicConnectionId> retry_original_connection_id_;
-  std::unique_ptr<QuicConnectionId> retry_new_connection_id_;
-  std::unique_ptr<std::string> retry_token_;
-  std::unique_ptr<std::string> retry_token_integrity_tag_;
-  std::unique_ptr<std::string> retry_without_tag_;
-  bool on_retry_packet_called_ = false;
-  std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
-  std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
-  std::vector<std::unique_ptr<QuicAckFrame>> ack_frames_;
-  std::vector<std::unique_ptr<QuicStopWaitingFrame>> stop_waiting_frames_;
-  std::vector<std::unique_ptr<QuicPaddingFrame>> padding_frames_;
-  std::vector<std::unique_ptr<QuicPingFrame>> ping_frames_;
-  std::vector<std::unique_ptr<QuicMessageFrame>> message_frames_;
-  std::vector<std::unique_ptr<QuicHandshakeDoneFrame>> handshake_done_frames_;
-  std::vector<std::unique_ptr<QuicAckFrequencyFrame>> ack_frequency_frames_;
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> coalesced_packets_;
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
-  std::vector<EncryptionLevel> undecryptable_decryption_levels_;
-  std::vector<bool> undecryptable_has_decryption_keys_;
-  QuicRstStreamFrame rst_stream_frame_;
-  QuicConnectionCloseFrame connection_close_frame_;
-  QuicStopSendingFrame stop_sending_frame_;
-  QuicGoAwayFrame goaway_frame_;
-  QuicPathChallengeFrame path_challenge_frame_;
-  QuicPathResponseFrame path_response_frame_;
-  QuicWindowUpdateFrame window_update_frame_;
-  QuicBlockedFrame blocked_frame_;
-  QuicStreamsBlockedFrame streams_blocked_frame_;
-  QuicMaxStreamsFrame max_streams_frame_;
-  QuicNewConnectionIdFrame new_connection_id_;
-  QuicRetireConnectionIdFrame retire_connection_id_;
-  QuicNewTokenFrame new_token_;
-  std::vector<std::unique_ptr<std::string>> stream_data_;
-  std::vector<std::unique_ptr<std::string>> crypto_data_;
-  QuicTransportVersion transport_version_;
-  QuicFramer* framer_;
-};
-
-// Simple struct for defining a packet's content, and associated
-// parse error.
-struct PacketFragment {
-  std::string error_if_missing;
-  std::vector<unsigned char> fragment;
-};
-
-using PacketFragments = std::vector<struct PacketFragment>;
-
-class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  QuicFramerTest()
-      : encrypter_(new test::TestEncrypter()),
-        decrypter_(new test::TestDecrypter()),
-        version_(GetParam()),
-        start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
-        framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER,
-                kQuicDefaultConnectionIdLength) {
-    framer_.set_version(version_);
-    if (framer_.version().KnowsWhichDecrypterToUse()) {
-      framer_.InstallDecrypter(ENCRYPTION_INITIAL,
-                               std::unique_ptr<QuicDecrypter>(decrypter_));
-    } else {
-      framer_.SetDecrypter(ENCRYPTION_INITIAL,
-                           std::unique_ptr<QuicDecrypter>(decrypter_));
-    }
-    framer_.SetEncrypter(ENCRYPTION_INITIAL,
-                         std::unique_ptr<QuicEncrypter>(encrypter_));
-
-    framer_.set_visitor(&visitor_);
-    framer_.InferPacketHeaderTypeFromVersion();
-    visitor_.set_framer(&framer_);
-  }
-
-  void SetDecrypterLevel(EncryptionLevel level) {
-    if (!framer_.version().KnowsWhichDecrypterToUse()) {
-      return;
-    }
-    decrypter_ = new TestDecrypter();
-    framer_.InstallDecrypter(level, std::unique_ptr<QuicDecrypter>(decrypter_));
-  }
-
-  // Helper function to get unsigned char representation of the handshake
-  // protocol byte at position |pos| of the current QUIC version number.
-  unsigned char GetQuicVersionByte(int pos) {
-    return (CreateQuicVersionLabel(version_) >> 8 * (3 - pos)) & 0xff;
-  }
-
-  // Helper functions to take a v1 long header packet and make it v2. These are
-  // not needed for short header packets, but if sent, this function will exit
-  // cleanly. It needs to be called twice for coalesced packets (see references
-  // to length_of_first_coalesced_packet below for examples of how to do this).
-  inline void ReviseFirstByteByVersion(unsigned char packet_ietf[]) {
-    if (version_.UsesV2PacketTypes() && (packet_ietf[0] >= 0x80)) {
-      packet_ietf[0] = (packet_ietf[0] + 0x10) | 0xc0;
-    }
-  }
-  inline void ReviseFirstByteByVersion(PacketFragments& packet_ietf) {
-    ReviseFirstByteByVersion(&packet_ietf[0].fragment[0]);
-  }
-
-  bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
-    if (packet_number != encrypter_->packet_number_) {
-      QUIC_LOG(ERROR) << "Encrypted incorrect packet number.  expected "
-                      << packet_number
-                      << " actual: " << encrypter_->packet_number_;
-      return false;
-    }
-    if (packet->AssociatedData(framer_.transport_version()) !=
-        encrypter_->associated_data_) {
-      QUIC_LOG(ERROR) << "Encrypted incorrect associated data.  expected "
-                      << packet->AssociatedData(framer_.transport_version())
-                      << " actual: " << encrypter_->associated_data_;
-      return false;
-    }
-    if (packet->Plaintext(framer_.transport_version()) !=
-        encrypter_->plaintext_) {
-      QUIC_LOG(ERROR) << "Encrypted incorrect plaintext data.  expected "
-                      << packet->Plaintext(framer_.transport_version())
-                      << " actual: " << encrypter_->plaintext_;
-      return false;
-    }
-    return true;
-  }
-
-  bool CheckDecryption(const QuicEncryptedPacket& encrypted,
-                       bool includes_version,
-                       bool includes_diversification_nonce,
-                       QuicConnectionIdLength destination_connection_id_length,
-                       QuicConnectionIdLength source_connection_id_length) {
-    return CheckDecryption(
-        encrypted, includes_version, includes_diversification_nonce,
-        destination_connection_id_length, source_connection_id_length,
-        VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-  }
-
-  bool CheckDecryption(
-      const QuicEncryptedPacket& encrypted, bool includes_version,
-      bool includes_diversification_nonce,
-      QuicConnectionIdLength destination_connection_id_length,
-      QuicConnectionIdLength source_connection_id_length,
-      QuicVariableLengthIntegerLength retry_token_length_length,
-      size_t retry_token_length,
-      QuicVariableLengthIntegerLength length_length) {
-    if (visitor_.header_->packet_number != decrypter_->packet_number_) {
-      QUIC_LOG(ERROR) << "Decrypted incorrect packet number.  expected "
-                      << visitor_.header_->packet_number
-                      << " actual: " << decrypter_->packet_number_;
-      return false;
-    }
-    absl::string_view associated_data =
-        QuicFramer::GetAssociatedDataFromEncryptedPacket(
-            framer_.transport_version(), encrypted,
-            destination_connection_id_length, source_connection_id_length,
-            includes_version, includes_diversification_nonce,
-            PACKET_4BYTE_PACKET_NUMBER, retry_token_length_length,
-            retry_token_length, length_length);
-    if (associated_data != decrypter_->associated_data_) {
-      QUIC_LOG(ERROR) << "Decrypted incorrect associated data.  expected "
-                      << absl::BytesToHexString(associated_data) << " actual: "
-                      << absl::BytesToHexString(decrypter_->associated_data_);
-      return false;
-    }
-    absl::string_view ciphertext(
-        encrypted.AsStringPiece().substr(GetStartOfEncryptedData(
-            framer_.transport_version(), destination_connection_id_length,
-            source_connection_id_length, includes_version,
-            includes_diversification_nonce, PACKET_4BYTE_PACKET_NUMBER,
-            retry_token_length_length, retry_token_length, length_length)));
-    if (ciphertext != decrypter_->ciphertext_) {
-      QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data.  expected "
-                      << absl::BytesToHexString(ciphertext) << " actual: "
-                      << absl::BytesToHexString(decrypter_->ciphertext_)
-                      << " associated data: "
-                      << absl::BytesToHexString(associated_data);
-      return false;
-    }
-    return true;
-  }
-
-  char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
-
-  // Creates a new QuicEncryptedPacket by concatenating the various
-  // packet fragments in |fragments|.
-  std::unique_ptr<QuicEncryptedPacket> AssemblePacketFromFragments(
-      const PacketFragments& fragments) {
-    char* buffer = new char[kMaxOutgoingPacketSize + 1];
-    size_t len = 0;
-    for (const auto& fragment : fragments) {
-      memcpy(buffer + len, fragment.fragment.data(), fragment.fragment.size());
-      len += fragment.fragment.size();
-    }
-    return std::make_unique<QuicEncryptedPacket>(buffer, len, true);
-  }
-
-  void CheckFramingBoundaries(const PacketFragments& fragments,
-                              QuicErrorCode error_code) {
-    std::unique_ptr<QuicEncryptedPacket> packet(
-        AssemblePacketFromFragments(fragments));
-    // Check all the various prefixes of |packet| for the expected
-    // parse error and error code.
-    for (size_t i = 0; i < packet->length(); ++i) {
-      std::string expected_error;
-      size_t len = 0;
-      for (const auto& fragment : fragments) {
-        len += fragment.fragment.size();
-        if (i < len) {
-          expected_error = fragment.error_if_missing;
-          break;
-        }
-      }
-
-      if (expected_error.empty()) continue;
-
-      CheckProcessingFails(*packet, i, expected_error, error_code);
-    }
-  }
-
-  void CheckProcessingFails(const QuicEncryptedPacket& packet, size_t len,
-                            std::string expected_error,
-                            QuicErrorCode error_code) {
-    QuicEncryptedPacket encrypted(packet.data(), len, false);
-    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
-    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
-    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
-  }
-
-  void CheckProcessingFails(unsigned char* packet, size_t len,
-                            std::string expected_error,
-                            QuicErrorCode error_code) {
-    QuicEncryptedPacket encrypted(AsChars(packet), len, false);
-    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
-    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
-    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
-  }
-
-  // Checks if the supplied string matches data in the supplied StreamFrame.
-  void CheckStreamFrameData(std::string str, QuicStreamFrame* frame) {
-    EXPECT_EQ(str, std::string(frame->data_buffer, frame->data_length));
-  }
-
-  void CheckCalculatePacketNumber(uint64_t expected_packet_number,
-                                  QuicPacketNumber last_packet_number) {
-    uint64_t wire_packet_number = expected_packet_number & kMask;
-    EXPECT_EQ(expected_packet_number,
-              QuicFramerPeer::CalculatePacketNumberFromWire(
-                  &framer_, PACKET_4BYTE_PACKET_NUMBER, last_packet_number,
-                  wire_packet_number))
-        << "last_packet_number: " << last_packet_number
-        << " wire_packet_number: " << wire_packet_number;
-  }
-
-  std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
-                                              const QuicFrames& frames) {
-    return BuildUnsizedDataPacket(&framer_, header, frames);
-  }
-
-  std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
-                                              const QuicFrames& frames,
-                                              size_t packet_size) {
-    return BuildUnsizedDataPacket(&framer_, header, frames, packet_size);
-  }
-
-  // N starts at 1.
-  QuicStreamId GetNthStreamid(QuicTransportVersion transport_version,
-                              Perspective perspective, bool bidirectional,
-                              int n) {
-    if (bidirectional) {
-      return QuicUtils::GetFirstBidirectionalStreamId(transport_version,
-                                                      perspective) +
-             ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
-    }
-    // Unidirectional
-    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version,
-                                                     perspective) +
-           ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
-  }
-
-  QuicTime CreationTimePlus(uint64_t offset_us) {
-    return framer_.creation_time() +
-           QuicTime::Delta::FromMicroseconds(offset_us);
-  }
-
-  test::TestEncrypter* encrypter_;
-  test::TestDecrypter* decrypter_;
-  ParsedQuicVersion version_;
-  QuicTime start_;
-  QuicFramer framer_;
-  test::TestQuicVisitor visitor_;
-  quiche::SimpleBufferAllocator allocator_;
-};
-
-// Multiple test cases of QuicFramerTest use byte arrays to define packets for
-// testing, and these byte arrays contain the QUIC version. This macro explodes
-// the 32-bit version into four bytes in network order. Since it uses methods of
-// QuicFramerTest, it is only valid to use this in a QuicFramerTest.
-#define QUIC_VERSION_BYTES                                             \
-  GetQuicVersionByte(0), GetQuicVersionByte(1), GetQuicVersionByte(2), \
-      GetQuicVersionByte(3)
-
-// Run all framer tests with all supported versions of QUIC.
-INSTANTIATE_TEST_SUITE_P(QuicFramerTests, QuicFramerTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
-  // A few quick manual sanity checks.
-  CheckCalculatePacketNumber(UINT64_C(1), QuicPacketNumber());
-  CheckCalculatePacketNumber(kEpoch + 1, QuicPacketNumber(kMask));
-  CheckCalculatePacketNumber(kEpoch, QuicPacketNumber(kMask));
-  for (uint64_t j = 0; j < 10; j++) {
-    CheckCalculatePacketNumber(j, QuicPacketNumber());
-    CheckCalculatePacketNumber(kEpoch - 1 - j, QuicPacketNumber());
-  }
-
-  // Cases where the last number was close to the start of the range.
-  for (QuicPacketNumber last = QuicPacketNumber(1); last < QuicPacketNumber(10);
-       last++) {
-    // Small numbers should not wrap (even if they're out of order).
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(j, last);
-    }
-
-    // Large numbers should not wrap either (because we're near 0 already).
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(kEpoch - 1 - j, last);
-    }
-  }
-}
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
-  // Cases where the last number was close to the end of the range
-  for (uint64_t i = 0; i < 10; i++) {
-    QuicPacketNumber last = QuicPacketNumber(kEpoch - i);
-
-    // Small numbers should wrap.
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(kEpoch + j, last);
-    }
-
-    // Large numbers should not (even if they're out of order).
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(kEpoch - 1 - j, last);
-    }
-  }
-}
-
-// Next check where we're in a non-zero epoch to verify we handle
-// reverse wrapping, too.
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearPrevEpoch) {
-  const uint64_t prev_epoch = 1 * kEpoch;
-  const uint64_t cur_epoch = 2 * kEpoch;
-  // Cases where the last number was close to the start of the range
-  for (uint64_t i = 0; i < 10; i++) {
-    QuicPacketNumber last = QuicPacketNumber(cur_epoch + i);
-    // Small number should not wrap (even if they're out of order).
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(cur_epoch + j, last);
-    }
-
-    // But large numbers should reverse wrap.
-    for (uint64_t j = 0; j < 10; j++) {
-      uint64_t num = kEpoch - 1 - j;
-      CheckCalculatePacketNumber(prev_epoch + num, last);
-    }
-  }
-}
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextEpoch) {
-  const uint64_t cur_epoch = 2 * kEpoch;
-  const uint64_t next_epoch = 3 * kEpoch;
-  // Cases where the last number was close to the end of the range
-  for (uint64_t i = 0; i < 10; i++) {
-    QuicPacketNumber last = QuicPacketNumber(next_epoch - 1 - i);
-
-    // Small numbers should wrap.
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(next_epoch + j, last);
-    }
-
-    // but large numbers should not (even if they're out of order).
-    for (uint64_t j = 0; j < 10; j++) {
-      uint64_t num = kEpoch - 1 - j;
-      CheckCalculatePacketNumber(cur_epoch + num, last);
-    }
-  }
-}
-
-TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextMax) {
-  const uint64_t max_number = std::numeric_limits<uint64_t>::max();
-  const uint64_t max_epoch = max_number & ~kMask;
-
-  // Cases where the last number was close to the end of the range
-  for (uint64_t i = 0; i < 10; i++) {
-    // Subtract 1, because the expected next packet number is 1 more than the
-    // last packet number.
-    QuicPacketNumber last = QuicPacketNumber(max_number - i - 1);
-
-    // Small numbers should not wrap, because they have nowhere to go.
-    for (uint64_t j = 0; j < 10; j++) {
-      CheckCalculatePacketNumber(max_epoch + j, last);
-    }
-
-    // Large numbers should not wrap either.
-    for (uint64_t j = 0; j < 10; j++) {
-      uint64_t num = kEpoch - 1 - j;
-      CheckCalculatePacketNumber(max_epoch + num, last);
-    }
-  }
-}
-
-TEST_P(QuicFramerTest, EmptyPacket) {
-  char packet[] = {0x00};
-  QuicEncryptedPacket encrypted(packet, 0, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-}
-
-TEST_P(QuicFramerTest, LargePacket) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[kMaxIncomingPacketSize + 1] = {
-    // public flags (8 byte connection_id)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x78, 0x56, 0x34, 0x12,
-    // private flags
-    0x00,
-  };
-  unsigned char packet46[kMaxIncomingPacketSize + 1] = {
-    // type (short header 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x78, 0x56, 0x34, 0x12,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  const size_t header_size = GetPacketHeaderSize(
-      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-
-  memset(p + header_size, 0, kMaxIncomingPacketSize - header_size);
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
-  ASSERT_TRUE(visitor_.header_.get());
-  // Make sure we've parsed the packet header, so we can send an error.
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  // Make sure the correct error is propagated.
-  EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_TOO_LARGE));
-  EXPECT_EQ("Packet too large.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, PacketHeader) {
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"Unable to read public flags.",
-       {0x28}},
-      // connection_id
-      {"Unable to read ConnectionId.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments = packet;
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_FALSE(visitor_.header_->version_flag);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-
-  PacketHeaderFormat format;
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  bool version_flag;
-  QuicConnectionId destination_connection_id, source_connection_id;
-  QuicVersionLabel version_label;
-  std::string detailed_error;
-  bool use_length_prefix;
-  absl::optional<absl::string_view> retry_token;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
-      *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  EXPECT_FALSE(retry_token.has_value());
-  EXPECT_FALSE(use_length_prefix);
-  EXPECT_THAT(error_code, IsQuicNoError());
-  EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
-  EXPECT_FALSE(version_flag);
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
-  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
-  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-}
-
-TEST_P(QuicFramerTest, LongPacketHeader) {
-  // clang-format off
-  PacketFragments packet46 = {
-    // type (long header with packet type ZERO_RTT)
-    {"Unable to read first byte.",
-     {0xD3}},
-    // version tag
-    {"Unable to read protocol version.",
-     {QUIC_VERSION_BYTES}},
-    // connection_id length
-    {"Unable to read ConnectionId length.",
-     {0x50}},
-    // connection_id
-    {"Unable to read destination connection ID.",
-     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-    // packet number
-    {"Unable to read packet number.",
-     {0x12, 0x34, 0x56, 0x78}},
-  };
-  // clang-format on
-
-  if (!framer_.version().HasIetfInvariantHeader() ||
-      QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    return;
-  }
-
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet46));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_TRUE(visitor_.header_->version_flag);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
-
-  PacketHeaderFormat format;
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  bool version_flag;
-  QuicConnectionId destination_connection_id, source_connection_id;
-  QuicVersionLabel version_label;
-  std::string detailed_error;
-  bool use_length_prefix;
-  absl::optional<absl::string_view> retry_token;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
-      *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  EXPECT_THAT(error_code, IsQuicNoError());
-  EXPECT_EQ("", detailed_error);
-  EXPECT_FALSE(retry_token.has_value());
-  EXPECT_FALSE(use_length_prefix);
-  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-  EXPECT_TRUE(version_flag);
-  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
-  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
-  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-}
-
-TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    // This test requires an IETF long header.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (long header with packet type ZERO_RTT_PROTECTED and
-    // 4-byte packet number)
-    0xD3,
-    // version
-    QUIC_VERSION_BYTES,
-    // connection ID lengths
-    0x55,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frame
-    0x00,
-  };
-  unsigned char packet49[] = {
-    // public flags (long header with packet type ZERO_RTT_PROTECTED and
-    // 4-byte packet number)
-    0xD3,
-    // version
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length
-    0x08,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    ReviseFirstByteByVersion(packet49);
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  bool version_flag = false;
-  QuicConnectionId destination_connection_id, source_connection_id;
-  QuicVersionLabel version_label = 0;
-  std::string detailed_error = "";
-  bool use_length_prefix;
-  absl::optional<absl::string_view> retry_token;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
-      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  EXPECT_THAT(error_code, IsQuicNoError());
-  EXPECT_FALSE(retry_token.has_value());
-  EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
-            use_length_prefix);
-  EXPECT_EQ("", detailed_error);
-  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-  EXPECT_TRUE(version_flag);
-  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
-  EXPECT_EQ(FramerTestConnectionIdPlusOne(), source_connection_id);
-}
-
-TEST_P(QuicFramerTest, AllZeroPacketParsingFails) {
-  unsigned char packet[1200] = {};
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  bool version_flag = false;
-  QuicConnectionId destination_connection_id, source_connection_id;
-  QuicVersionLabel version_label = 0;
-  std::string detailed_error = "";
-  bool use_length_prefix;
-  absl::optional<absl::string_view> retry_token;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
-      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_flag, &use_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  EXPECT_EQ(error_code, QUIC_INVALID_PACKET_HEADER);
-  EXPECT_EQ(detailed_error, "Invalid flags.");
-}
-
-TEST_P(QuicFramerTest, ParsePublicHeader) {
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (version included, 8-byte connection ID,
-    // 4-byte packet number)
-    0x29,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // version
-    QUIC_VERSION_BYTES,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-    // padding frame
-    0x00,
-  };
-  unsigned char packet46[] = {
-      // public flags (long header with packet type HANDSHAKE and
-      // 4-byte packet number)
-      0xE3,
-      // version
-      QUIC_VERSION_BYTES,
-      // connection ID lengths
-      0x50,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // long header packet length
-      0x05,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // padding frame
-      0x00,
-  };
-  unsigned char packet49[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length
-    0x00,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    ReviseFirstByteByVersion(packet49);
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_length = ABSL_ARRAYSIZE(packet46);
-  }
-
-  uint8_t first_byte = 0x33;
-  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
-  bool version_present = false, has_length_prefix = false;
-  QuicVersionLabel version_label = 0;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
-                   source_connection_id = EmptyQuicConnectionId();
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_4;
-  absl::string_view retry_token;
-  std::string detailed_error = "foobar";
-
-  QuicDataReader reader(AsChars(p), p_length);
-  const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
-      &reader, kQuicDefaultConnectionIdLength,
-      /*ietf_format=*/
-      framer_.version().HasIetfInvariantHeader(), &first_byte, &format,
-      &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &long_packet_type,
-      &retry_token_length_length, &retry_token, &detailed_error);
-  EXPECT_THAT(parse_error, IsQuicNoError());
-  EXPECT_EQ("", detailed_error);
-  EXPECT_EQ(p[0], first_byte);
-  EXPECT_TRUE(version_present);
-  EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
-            has_length_prefix);
-  EXPECT_EQ(CreateQuicVersionLabel(framer_.version()), version_label);
-  EXPECT_EQ(framer_.version(), parsed_version);
-  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
-  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
-  EXPECT_EQ(absl::string_view(), retry_token);
-  if (framer_.version().HasIetfInvariantHeader()) {
-    EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-    EXPECT_EQ(HANDSHAKE, long_packet_type);
-  } else {
-    EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
-  }
-}
-
-TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) {
-  if (!framer_.version().HasLengthPrefixedConnectionIds()) {
-    return;
-  }
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    'P', 'R', 'O', 'X',
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length (bogus)
-    0xEE,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-
-  uint8_t first_byte = 0x33;
-  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
-  bool version_present = false, has_length_prefix = false;
-  QuicVersionLabel version_label = 0;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
-                   source_connection_id = EmptyQuicConnectionId();
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_4;
-  absl::string_view retry_token;
-  std::string detailed_error = "foobar";
-
-  QuicDataReader reader(AsChars(p), p_length);
-  const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
-      &reader, kQuicDefaultConnectionIdLength,
-      /*ietf_format=*/true, &first_byte, &format, &version_present,
-      &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &long_packet_type,
-      &retry_token_length_length, &retry_token, &detailed_error);
-  EXPECT_THAT(parse_error, IsQuicNoError());
-  EXPECT_EQ("", detailed_error);
-  EXPECT_EQ(p[0], first_byte);
-  EXPECT_TRUE(version_present);
-  EXPECT_TRUE(has_length_prefix);
-  EXPECT_EQ(0x50524F58u, version_label);  // "PROX"
-  EXPECT_EQ(UnsupportedQuicVersion(), parsed_version);
-  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
-  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
-  EXPECT_EQ(absl::string_view(), retry_token);
-  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-}
-
-TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToClient) {
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
-                                                      TestConnectionId(0x33));
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  framer_.SetExpectedClientConnectionIdLength(kQuicDefaultConnectionIdLength);
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x13, 0x37, 0x42, 0x33,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  EXPECT_EQ("", framer_.detailed_error());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-}
-
-// In short header packets from client to server, the client connection ID
-// is omitted, but the framer adds it to the header struct using its
-// last serialized client connection ID. This test ensures that this
-// mechanism behaves as expected.
-TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToServer) {
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicFramerPeer::SetLastSerializedClientConnectionId(&framer_,
-                                                      TestConnectionId(0x33));
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x13, 0x37, 0x42, 0x33,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  EXPECT_EQ("", framer_.detailed_error());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
-                                                      FramerTestConnectionId());
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (0 byte connection_id)
-      {"Unable to read public flags.",
-       {0x20}},
-      // connection_id
-      // packet number
-      {"Unable to read packet number.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-
-  PacketFragments packet46 = {
-        // type (short header, 4 byte packet number)
-        {"Unable to read first byte.",
-         {0x43}},
-        // connection_id
-        // packet number
-        {"Unable to read packet number.",
-         {0x12, 0x34, 0x56, 0x78}},
-   };
-
-  PacketFragments packet_hp = {
-        // type (short header, 4 byte packet number)
-        {"Unable to read first byte.",
-         {0x43}},
-        // connection_id
-        // packet number
-        {"",
-         {0x12, 0x34, 0x56, 0x78}},
-   };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasHeaderProtection()
-          ? packet_hp
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_FALSE(visitor_.header_->version_flag);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (0 byte connection_id)
-      {"Unable to read public flags.",
-       {0x29}},
-      // connection_id
-      {"Unable to read ConnectionId.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // version tag
-      {"Unable to read protocol version.",
-       {QUIC_VERSION_BYTES}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-
-  PacketFragments packet46 = {
-      // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
-      // packet number)
-      {"Unable to read first byte.",
-       {0xD3}},
-      // version tag
-      {"Unable to read protocol version.",
-       {QUIC_VERSION_BYTES}},
-      // connection_id length
-      {"Unable to read ConnectionId length.",
-       {0x50}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-
-  PacketFragments packet49 = {
-      // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
-      // packet number)
-      {"Unable to read first byte.",
-       {0xD3}},
-      // version tag
-      {"Unable to read protocol version.",
-       {QUIC_VERSION_BYTES}},
-      // destination connection ID length
-      {"Unable to read destination connection ID.",
-       {0x08}},
-      // destination connection ID
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // source connection ID length
-      {"Unable to read source connection ID.",
-       {0x00}},
-      // long header packet length
-      {"Unable to read long header payload length.",
-       {0x04}},
-      // packet number
-      {"Long header payload length longer than packet.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-  // clang-format on
-
-  ReviseFirstByteByVersion(packet49);
-  PacketFragments& fragments =
-      framer_.version().HasLongHeaderLengths()
-          ? packet49
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_TRUE(visitor_.header_->version_flag);
-  EXPECT_EQ(GetParam(), visitor_.header_->version);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id and 4 byte packet number)
-      {"Unable to read public flags.",
-       {0x28}},
-      // connection_id
-      {"Unable to read ConnectionId.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"Unable to read first byte.",
-       {0x43}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-
-  PacketFragments packet_hp = {
-      // type (short header, 4 byte packet number)
-      {"Unable to read first byte.",
-       {0x43}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasHeaderProtection()
-          ? packet_hp
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_FALSE(visitor_.header_->version_flag);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id and 2 byte packet number)
-      {"Unable to read public flags.",
-       {0x18}},
-      // connection_id
-      {"Unable to read ConnectionId.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x56, 0x78}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 2 byte packet number)
-      {"Unable to read first byte.",
-       {0x41}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x56, 0x78}},
-  };
-
-  PacketFragments packet_hp = {
-      // type (short header, 2 byte packet number)
-      {"Unable to read first byte.",
-       {0x41}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x56, 0x78}},
-      // padding
-      {"", {0x00, 0x00}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasHeaderProtection()
-          ? packet_hp
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  if (framer_.version().HasHeaderProtection()) {
-    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-    EXPECT_THAT(framer_.error(), IsQuicNoError());
-  } else {
-    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  }
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_FALSE(visitor_.header_->version_flag);
-  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id and 1 byte packet number)
-      {"Unable to read public flags.",
-       {0x08}},
-      // connection_id
-      {"Unable to read ConnectionId.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x78}},
-  };
-
-  PacketFragments packet46 = {
-      // type (8 byte connection_id and 1 byte packet number)
-      {"Unable to read first byte.",
-       {0x40}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x78}},
-  };
-
-  PacketFragments packet_hp = {
-      // type (8 byte connection_id and 1 byte packet number)
-      {"Unable to read first byte.",
-       {0x40}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x78}},
-      // padding
-      {"", {0x00, 0x00, 0x00}},
-  };
-
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasHeaderProtection()
-          ? packet_hp
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  if (framer_.version().HasHeaderProtection()) {
-    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-    EXPECT_THAT(framer_.error(), IsQuicNoError());
-  } else {
-    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  }
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_FALSE(visitor_.header_->version_flag);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // Test the case when a packet is received from the past and future packet
-  // numbers are still calculated relative to the largest received packet.
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber - 2;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  QuicEncryptedPacket encrypted(data->data(), data->length(), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber - 2, visitor_.header_->packet_number);
-
-  // Receive a 1 byte packet number.
-  header.packet_number = kPacketNumber;
-  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  QuicEncryptedPacket encrypted1(data->data(), data->length(), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted1));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  // Process a 2 byte packet number 256 packets ago.
-  header.packet_number = kPacketNumber - 256;
-  header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  QuicEncryptedPacket encrypted2(data->data(), data->length(), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted2));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber - 256, visitor_.header_->packet_number);
-
-  // Process another 1 byte packet number and ensure it works.
-  header.packet_number = kPacketNumber - 1;
-  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  QuicEncryptedPacket encrypted3(data->data(), data->length(), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted3));
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_->destination_connection_id);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber - 1, visitor_.header_->packet_number);
-}
-
-TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags: includes nonce flag
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // nonce
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[] = {
-    // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
-    // number.
-    0xD0,
-    // version tag
-    QUIC_VERSION_BYTES,
-    // connection_id length
-    0x05,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x78,
-    // nonce
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-
-    // frame type (padding)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet49[] = {
-    // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
-    // number.
-    0xD0,
-    // version tag
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x00,
-    // source connection ID length
-    0x08,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x26,
-    // packet number
-    0x78,
-    // nonce
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-
-    // frame type (padding)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
-    return;
-  }
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    p = packet49;
-    p_size = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  ASSERT_TRUE(visitor_.header_->nonce != nullptr);
-  for (char i = 0; i < 32; ++i) {
-    EXPECT_EQ(i, (*visitor_.header_->nonce)[static_cast<size_t>(i)]);
-  }
-  EXPECT_EQ(1u, visitor_.padding_frames_.size());
-  EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes);
-}
-
-TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id, version flag and an unknown flag)
-    0x29,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // version tag
-    'Q', '0', '0', '0',
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[] = {
-    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
-    0xD3,
-    // version tag
-    'Q', '0', '0', '0',
-    // connection_id length
-    0x50,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet49[] = {
-    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
-    0xD3,
-    // version tag
-    'Q', '0', '0', '0',
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length
-    0x00,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    p = packet49;
-    p_size = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(0, visitor_.frame_count_);
-  EXPECT_EQ(1, visitor_.version_mismatch_);
-}
-
-TEST_P(QuicFramerTest, PaddingFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // paddings
-    0x00, 0x00,
-    // frame type (stream frame with fin)
-    0xFF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-    // paddings
-    0x00, 0x00,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // paddings
-    0x00, 0x00,
-    // frame type (stream frame with fin)
-    0xFF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-    // paddings
-    0x00, 0x00,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // paddings
-    0x00, 0x00,
-    // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
-    0x08 | 0x01 | 0x02 | 0x04,
-
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // offset
-    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    kVarInt62OneByte + 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-    // paddings
-    0x00, 0x00,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  EXPECT_EQ(2u, visitor_.padding_frames_.size());
-  EXPECT_EQ(2, visitor_.padding_frames_[0]->num_padding_bytes);
-  EXPECT_EQ(2, visitor_.padding_frames_[1]->num_padding_bytes);
-  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-}
-
-TEST_P(QuicFramerTest, StreamFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFF}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFF}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
-      {"",
-       { 0x08 | 0x01 | 0x02 | 0x04 }},
-      // stream id
-      {"Unable to read IETF_STREAM frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read stream data offset.",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Unable to read stream data length.",
-       {kVarInt62OneByte + 0x0c}},
-      // data
-      {"Unable to read frame data.",
-       { 'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-// Test an empty (no data) stream frame.
-TEST_P(QuicFramerTest, EmptyStreamFrame) {
-  // Only the IETF QUIC spec explicitly says that empty
-  // stream frames are supported.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
-      {"",
-       { 0x08 | 0x01 | 0x02 | 0x04 }},
-      // stream id
-      {"Unable to read IETF_STREAM frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read stream data offset.",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Unable to read stream data length.",
-       {kVarInt62OneByte + 0x00}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  EXPECT_EQ(visitor_.stream_frames_[0].get()->data_length, 0u);
-
-  CheckFramingBoundaries(packet, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, MissingDiversificationNonce) {
-  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
-    // TLS does not use diversification nonces.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  decrypter_ = new test::TestDecrypter();
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(
-        ENCRYPTION_INITIAL,
-        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::unique_ptr<QuicDecrypter>(decrypter_));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
-                                                 Perspective::IS_CLIENT));
-    framer_.SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
-  }
-
-  // clang-format off
-  unsigned char packet[] = {
-        // public flags (8 byte connection_id)
-        0x28,
-        // connection_id
-        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
-        // packet number
-        0x12, 0x34, 0x56, 0x78,
-        // padding frame
-        0x00,
-    };
-
-  unsigned char packet46[] = {
-        // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
-        0xD3,
-        // version tag
-        QUIC_VERSION_BYTES,
-        // connection_id length
-        0x05,
-        // connection_id
-        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
-        // packet number
-        0x12, 0x34, 0x56, 0x78,
-        // padding frame
-        0x00,
-    };
-
-  unsigned char packet49[] = {
-        // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
-        0xD3,
-        // version tag
-        QUIC_VERSION_BYTES,
-        // destination connection ID length
-        0x00,
-        // source connection ID length
-        0x08,
-        // source connection ID
-        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
-        // IETF long header payload length
-        0x05,
-        // packet number
-        0x12, 0x34, 0x56, 0x78,
-        // padding frame
-        0x00,
-    };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_length = ABSL_ARRAYSIZE(packet46);
-  }
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  if (framer_.version().HasHeaderProtection()) {
-    EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-    EXPECT_EQ("Unable to decrypt ENCRYPTION_ZERO_RTT header protection.",
-              framer_.detailed_error());
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    // Cannot read diversification nonce.
-    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-    EXPECT_EQ("Unable to read nonce.", framer_.detailed_error());
-  } else {
-    EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-  }
-}
-
-TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
-  if (framer_.version().HasIetfInvariantHeader()) {
-    // This test is nonsensical for IETF Quic.
-    return;
-  }
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFE}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments = packet;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFD}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x03, 0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (stream frame with fin)
-       {"",
-        {0xFD}},
-       // stream id
-       {"Unable to read stream_id.",
-        {0x03, 0x04}},
-       // offset
-       {"Unable to read offset.",
-        {0x3A, 0x98, 0xFE, 0xDC,
-         0x32, 0x10, 0x76, 0x54}},
-       {"Unable to read frame data.",
-        {
-          // data length
-          0x00, 0x0c,
-          // data
-          'h',  'e',  'l',  'l',
-          'o',  ' ',  'w',  'o',
-          'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
-      {"",
-       {0x08 | 0x01 | 0x02 | 0x04}},
-      // stream id
-      {"Unable to read IETF_STREAM frame stream id/count.",
-       {kVarInt62TwoBytes + 0x03, 0x04}},
-      // offset
-      {"Unable to read stream data offset.",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Unable to read stream data length.",
-       {kVarInt62OneByte + 0x0c}},
-      // data
-      {"Unable to read frame data.",
-       { 'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  // Stream ID should be the last 2 bytes of kStreamId.
-  EXPECT_EQ(0x0000FFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFC}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFC}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
-      {"",
-       {0x08 | 0x01 | 0x02 | 0x04}},
-      // stream id
-      {"Unable to read IETF_STREAM frame stream id/count.",
-       {kVarInt62OneByte + 0x04}},
-      // offset
-      {"Unable to read stream data offset.",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Unable to read stream data length.",
-       {kVarInt62OneByte + 0x0c}},
-      // data
-      {"Unable to read frame data.",
-       { 'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  // Stream ID should be the last 1 byte of kStreamId.
-  EXPECT_EQ(0x000000FF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, StreamFrameWithVersion) {
-  // If IETF frames are in use then we must also have the IETF
-  // header invariants.
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    QUICHE_DCHECK(framer_.version().HasIetfInvariantHeader());
-  }
-
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (version, 8 byte connection_id)
-      {"",
-       {0x29}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // version tag
-      {"",
-       {QUIC_VERSION_BYTES}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFE}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet46 = {
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      {"",
-       {0xD3}},
-      // version tag
-      {"",
-       {QUIC_VERSION_BYTES}},
-      // connection_id length
-      {"",
-       {0x50}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFE}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x02, 0x03, 0x04}},
-      // offset
-      {"Unable to read offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Unable to read frame data.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet49 = {
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      {"",
-       {0xD3}},
-      // version tag
-      {"",
-       {QUIC_VERSION_BYTES}},
-      // destination connection ID length
-      {"",
-       {0x08}},
-      // destination connection ID
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // source connection ID length
-      {"",
-       {0x00}},
-      // long header packet length
-      {"",
-       {0x1E}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stream frame with fin)
-      {"",
-       {0xFE}},
-      // stream id
-      {"Long header payload length longer than packet.",
-       {0x02, 0x03, 0x04}},
-      // offset
-      {"Long header payload length longer than packet.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      {"Long header payload length longer than packet.",
-       {
-         // data length
-         0x00, 0x0c,
-         // data
-         'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet_ietf = {
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      {"",
-       {0xD3}},
-      // version tag
-      {"",
-       {QUIC_VERSION_BYTES}},
-      // destination connection ID length
-      {"",
-       {0x08}},
-      // destination connection ID
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // source connection ID length
-      {"",
-       {0x00}},
-      // long header packet length
-      {"",
-       {0x1E}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      {"",
-       {0x08 | 0x01 | 0x02 | 0x04}},
-      // stream id
-      {"Long header payload length longer than packet.",
-       {kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04}},
-      // offset
-      {"Long header payload length longer than packet.",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Long header payload length longer than packet.",
-       {kVarInt62OneByte + 0x0c}},
-      // data
-      {"Long header payload length longer than packet.",
-       { 'h',  'e',  'l',  'l',
-         'o',  ' ',  'w',  'o',
-         'r',  'l',  'd',  '!'}},
-  };
-  // clang-format on
-
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  size_t retry_token_length = 0;
-  QuicVariableLengthIntegerLength length_length =
-      QuicVersionHasLongHeaderLengths(framer_.transport_version())
-          ? VARIABLE_LENGTH_INTEGER_LENGTH_1
-          : VARIABLE_LENGTH_INTEGER_LENGTH_0;
-
-  ReviseFirstByteByVersion(packet_ietf);
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasLongHeaderLengths()
-                 ? packet49
-                 : (framer_.version().HasIetfInvariantHeader() ? packet46
-                                                               : packet));
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID,
-      retry_token_length_length, retry_token_length, length_length));
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  CheckFramingBoundaries(fragments, framer_.version().HasLongHeaderLengths()
-                                        ? QUIC_INVALID_PACKET_HEADER
-                                        : QUIC_INVALID_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, RejectPacket) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  visitor_.accept_packet_ = false;
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x28,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (stream frame with fin)
-      0xFF,
-      // stream id
-      0x01, 0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (STREAM Frame with FIN, LEN, and OFFSET bits set)
-      0x10 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-  QuicEncryptedPacket encrypted(AsChars(p),
-                                framer_.version().HasIetfInvariantHeader()
-                                    ? ABSL_ARRAYSIZE(packet46)
-                                    : ABSL_ARRAYSIZE(packet),
-                                false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(0u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-}
-
-TEST_P(QuicFramerTest, RejectPublicHeader) {
-  visitor_.accept_public_header_ = false;
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 1 byte packet number)
-    0x40,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x01,
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(
-      framer_.version().HasIetfInvariantHeader() ? AsChars(packet46)
-                                                 : AsChars(packet),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet),
-      false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_FALSE(visitor_.header_->packet_number.IsInitialized());
-}
-
-TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x2C}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (ack frame)
-      // (one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       {0x45}},
-      // largest acked
-      {"Unable to read largest acked.",
-       {0x12, 0x34}},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       {0x00, 0x00}},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       {0x12, 0x34}},
-      // num timestamps.
-      {"Unable to read num received packets.",
-       {0x00}}
-  };
-
-  PacketFragments packet46 = {
-      // type (short packet, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (ack frame)
-      // (one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       {0x45}},
-      // largest acked
-      {"Unable to read largest acked.",
-       {0x12, 0x34}},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       {0x00, 0x00}},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       {0x12, 0x34}},
-      // num timestamps.
-      {"Unable to read num received packets.",
-       {0x00}}
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short packet, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK)
-       // (one ack block, 2 byte largest observed, 2 byte block length)
-       // IETF-Quic ignores the bit-fields in the ack type, all of
-       // that information is encoded elsewhere in the frame.
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62TwoBytes  + 0x12, 0x34}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-      // Ack block count (0 -- no blocks after the first)
-      {"Unable to read ack block count.",
-       {kVarInt62OneByte + 0x00}},
-       // first ack block length - 1.
-       // IETF Quic defines the ack block's value as the "number of
-       // packets that preceed the largest packet number in the block"
-       // which for the 1st ack block is the largest acked field,
-       // above. This means that if we are acking just packet 0x1234
-       // then the 1st ack block will be 0.
-       {"Unable to read first ack block length.",
-        {kVarInt62TwoBytes + 0x12, 0x33}}
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
-  ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-// This test checks that the ack frame processor correctly identifies
-// and handles the case where the first ack block is larger than the
-// largest_acked packet.
-TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x2C}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (ack frame)
-      // (one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       {0x45}},
-      // largest acked
-      {"Unable to read largest acked.",
-       {0x12, 0x34}},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       {0x00, 0x00}},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       {0x88, 0x88}},
-      // num timestamps.
-      {"Underflow with first ack block length 34952 largest acked is 4660.",
-       {0x00}}
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (ack frame)
-      // (one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       {0x45}},
-      // largest acked
-      {"Unable to read largest acked.",
-       {0x12, 0x34}},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       {0x00, 0x00}},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       {0x88, 0x88}},
-      // num timestamps.
-      {"Underflow with first ack block length 34952 largest acked is 4660.",
-       {0x00}}
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62TwoBytes  + 0x12, 0x34}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Ack block count (0 -- no blocks after the first)
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 0x00}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62TwoBytes + 0x28, 0x88}}
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-// This test checks that the ack frame processor correctly identifies
-// and handles the case where the third ack block's gap is larger than the
-// available space in the ack range.
-TEST_P(QuicFramerTest, ThirdAckBlockUnderflowGap) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Test originally written for development of IETF QUIC. The test may
-    // also apply to Google QUIC. If so, the test should be extended to
-    // include Google QUIC (frame formats, etc). See b/141858819.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK frame)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62OneByte  + 63}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Ack block count (2 -- 2 blocks after the first)
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 0x02}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62OneByte + 13}},  // Ack 14 packets, range 50..63 (inclusive)
-
-       {"Unable to read gap block value.",
-        {kVarInt62OneByte + 9}},  // Gap 10 packets, 40..49 (inclusive)
-       {"Unable to read ack block value.",
-        {kVarInt62OneByte + 9}},  // Ack 10 packets, 30..39 (inclusive)
-       {"Unable to read gap block value.",
-        {kVarInt62OneByte + 29}},  // A gap of 30 packets (0..29 inclusive)
-                                   // should be too big, leaving no room
-                                   // for the ack.
-       {"Underflow with gap block length 30 previous ack block start is 30.",
-        {kVarInt62OneByte + 10}},  // Don't care
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(
-      framer_.detailed_error(),
-      "Underflow with gap block length 30 previous ack block start is 30.");
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// This test checks that the ack frame processor correctly identifies
-// and handles the case where the third ack block's length is larger than the
-// available space in the ack range.
-TEST_P(QuicFramerTest, ThirdAckBlockUnderflowAck) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Test originally written for development of IETF QUIC. The test may
-    // also apply to Google QUIC. If so, the test should be extended to
-    // include Google QUIC (frame formats, etc). See b/141858819.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK frame)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62OneByte  + 63}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Ack block count (2 -- 2 blocks after the first)
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 0x02}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62OneByte + 13}},  // only 50 packet numbers "left"
-
-       {"Unable to read gap block value.",
-        {kVarInt62OneByte + 10}},  // Only 40 packet numbers left
-       {"Unable to read ack block value.",
-        {kVarInt62OneByte + 10}},  // only 30 packet numbers left.
-       {"Unable to read gap block value.",
-        {kVarInt62OneByte + 1}},  // Gap is OK, 29 packet numbers left
-      {"Unable to read ack block value.",
-        {kVarInt62OneByte + 30}},  // Use up all 30, should be an error
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(framer_.detailed_error(),
-            "Underflow with ack block length 31 latest ack block end is 25.");
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// Tests a variety of ack block wrap scenarios. For example, if the
-// N-1th block causes packet 0 to be acked, then a gap would wrap
-// around to 0x3fffffff ffffffff... Make sure we detect this
-// condition.
-TEST_P(QuicFramerTest, AckBlockUnderflowGapWrap) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Test originally written for development of IETF QUIC. The test may
-    // also apply to Google QUIC. If so, the test should be extended to
-    // include Google QUIC (frame formats, etc). See b/141858819.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK frame)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62OneByte  + 10}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Ack block count (1 -- 1 blocks after the first)
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 1}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62OneByte + 9}},  // Ack packets 1..10 (inclusive)
-
-       {"Unable to read gap block value.",
-        {kVarInt62OneByte + 1}},  // Gap of 2 packets (-1...0), should wrap
-       {"Underflow with gap block length 2 previous ack block start is 1.",
-        {kVarInt62OneByte + 9}},  // irrelevant
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(framer_.detailed_error(),
-            "Underflow with gap block length 2 previous ack block start is 1.");
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// As AckBlockUnderflowGapWrap, but in this test, it's the ack
-// component of the ack-block that causes the wrap, not the gap.
-TEST_P(QuicFramerTest, AckBlockUnderflowAckWrap) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Test originally written for development of IETF QUIC. The test may
-    // also apply to Google QUIC. If so, the test should be extended to
-    // include Google QUIC (frame formats, etc). See b/141858819.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK frame)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62OneByte  + 10}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Ack block count (1 -- 1 blocks after the first)
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 1}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62OneByte + 6}},  // Ack packets 4..10 (inclusive)
-
-       {"Unable to read gap block value.",
-        {kVarInt62OneByte + 1}},  // Gap of 2 packets (2..3)
-       {"Unable to read ack block value.",
-        {kVarInt62OneByte + 9}},  // Should wrap.
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(framer_.detailed_error(),
-            "Underflow with ack block length 10 latest ack block end is 1.");
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
-}
-
-// An ack block that acks the entire range, 1...0x3fffffffffffffff
-TEST_P(QuicFramerTest, AckBlockAcksEverything) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Test originally written for development of IETF QUIC. The test may
-    // also apply to Google QUIC. If so, the test should be extended to
-    // include Google QUIC (frame formats, etc). See b/141858819.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-       // frame type (IETF_ACK frame)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62EightBytes  + 0x3f, 0xff, 0xff, 0xff,
-         0xff, 0xff, 0xff, 0xff}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Ack block count No additional blocks
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 0}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62EightBytes  + 0x3f, 0xff, 0xff, 0xff,
-         0xff, 0xff, 0xff, 0xfe}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.ack_frames_.size());
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(1u, frame.packets.NumIntervals());
-  EXPECT_EQ(kLargestIetfLargestObserved, LargestAcked(frame));
-  EXPECT_EQ(kLargestIetfLargestObserved.ToUint64(),
-            frame.packets.NumPacketsSlow());
-}
-
-// This test looks for a malformed ack where
-//  - There is a largest-acked value (that is, the frame is acking
-//    something,
-//  - But the length of the first ack block is 0 saying that no frames
-//    are being acked with the largest-acked value or there are no
-//    additional ack blocks.
-//
-TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Not applicable to version 99 -- first ack block contains the
-    // number of packets that preceed the largest_acked packet.
-    // A value of 0 means no packets preceed --- that the block's
-    // length is 1. Therefore the condition that this test checks can
-    // not arise.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       { 0x2C }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (ack frame)
-      // (more than one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       { 0x65 }},
-      // largest acked
-      {"Unable to read largest acked.",
-       { 0x12, 0x34 }},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       { 0x00, 0x00 }},
-      // num ack blocks ranges.
-      {"Unable to read num of ack blocks.",
-       { 0x01 }},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       { 0x00, 0x00 }},
-      // gap to next block.
-      { "First block length is zero.",
-        { 0x01 }},
-      // ack block length.
-      { "First block length is zero.",
-        { 0x0e, 0xaf }},
-      // Number of timestamps.
-      { "First block length is zero.",
-        { 0x00 }},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (ack frame)
-      // (more than one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       { 0x65 }},
-      // largest acked
-      {"Unable to read largest acked.",
-       { 0x12, 0x34 }},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       { 0x00, 0x00 }},
-      // num ack blocks ranges.
-      {"Unable to read num of ack blocks.",
-       { 0x01 }},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       { 0x00, 0x00 }},
-      // gap to next block.
-      { "First block length is zero.",
-        { 0x01 }},
-      // ack block length.
-      { "First block length is zero.",
-        { 0x0e, 0xaf }},
-      // Number of timestamps.
-      { "First block length is zero.",
-        { 0x00 }},
-  };
-
-  // clang-format on
-  PacketFragments& fragments =
-      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_ACK_DATA));
-
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x2C}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (ack frame)
-      // (one ack block, 4 byte largest observed, 2 byte block length)
-      {"",
-       {0x49}},
-      // largest acked
-      {"Unable to read largest acked.",
-       {0x12, 0x34, 0x56, 0x78}},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       {0x00, 0x00}},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       {0x12, 0x34}},
-      // num timestamps.
-      {"Unable to read num received packets.",
-       {0x00}}
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x56, 0x78, 0x9A, 0xBC}},
-      // frame type (ack frame)
-      // (one ack block, 4 byte largest observed, 2 byte block length)
-      {"",
-       {0x49}},
-      // largest acked
-      {"Unable to read largest acked.",
-       {0x12, 0x34, 0x56, 0x78}},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       {0x00, 0x00}},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       {0x12, 0x34}},
-      // num timestamps.
-      {"Unable to read num received packets.",
-       {0x00}}
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x56, 0x78, 0x9A, 0xBC}},
-       // frame type (IETF_ACK frame)
-       {"",
-        {0x02}},
-       // largest acked
-       {"Unable to read largest acked.",
-        {kVarInt62FourBytes  + 0x12, 0x34, 0x56, 0x78}},
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        {kVarInt62OneByte + 0x00}},
-       // Number of ack blocks after first
-       {"Unable to read ack block count.",
-        {kVarInt62OneByte + 0x00}},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        {kVarInt62TwoBytes  + 0x12, 0x33}}
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(kPacketNumber, LargestAcked(frame));
-  ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
-}
-
-// Tests ability to handle multiple ackblocks after the first ack
-// block. Non-version-99 tests include multiple timestamps as well.
-TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       { 0x2C }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (ack frame)
-      // (more than one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       { 0x65 }},
-      // largest acked
-      {"Unable to read largest acked.",
-       { 0x12, 0x34 }},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       { 0x00, 0x00 }},
-      // num ack blocks ranges.
-      {"Unable to read num of ack blocks.",
-       { 0x04 }},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       { 0x00, 0x01 }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0x01 }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x0e, 0xaf }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0xff }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x00, 0x00 }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0x91 }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x01, 0xea }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0x05 }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x00, 0x04 }},
-      // Number of timestamps.
-      { "Unable to read num received packets.",
-        { 0x02 }},
-      // Delta from largest observed.
-      { "Unable to read sequence delta in received packets.",
-        { 0x01 }},
-      // Delta time.
-      { "Unable to read time delta in received packets.",
-        { 0x76, 0x54, 0x32, 0x10 }},
-      // Delta from largest observed.
-      { "Unable to read sequence delta in received packets.",
-        { 0x02 }},
-      // Delta time.
-      { "Unable to read incremental time delta in received packets.",
-        { 0x32, 0x10 }},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (ack frame)
-      // (more than one ack block, 2 byte largest observed, 2 byte block length)
-      {"",
-       { 0x65 }},
-      // largest acked
-      {"Unable to read largest acked.",
-       { 0x12, 0x34 }},
-      // Zero delta time.
-      {"Unable to read ack delay time.",
-       { 0x00, 0x00 }},
-      // num ack blocks ranges.
-      {"Unable to read num of ack blocks.",
-       { 0x04 }},
-      // first ack block length.
-      {"Unable to read first ack block length.",
-       { 0x00, 0x01 }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0x01 }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x0e, 0xaf }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0xff }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x00, 0x00 }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0x91 }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x01, 0xea }},
-      // gap to next block.
-      { "Unable to read gap to next ack block.",
-        { 0x05 }},
-      // ack block length.
-      { "Unable to ack block length.",
-        { 0x00, 0x04 }},
-      // Number of timestamps.
-      { "Unable to read num received packets.",
-        { 0x02 }},
-      // Delta from largest observed.
-      { "Unable to read sequence delta in received packets.",
-        { 0x01 }},
-      // Delta time.
-      { "Unable to read time delta in received packets.",
-        { 0x76, 0x54, 0x32, 0x10 }},
-      // Delta from largest observed.
-      { "Unable to read sequence delta in received packets.",
-        { 0x02 }},
-      // Delta time.
-      { "Unable to read incremental time delta in received packets.",
-        { 0x32, 0x10 }},
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      {"",
-       { 0x22 }},
-       // largest acked
-       {"Unable to read largest acked.",
-        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        { kVarInt62OneByte + 0x00 }},
-       // number of additional ack blocks
-       {"Unable to read ack block count.",
-        { kVarInt62OneByte + 0x03 }},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
-
-       // Additional ACK Block #1
-       // gap to next block.
-       { "Unable to read gap block value.",
-         { kVarInt62OneByte + 0x00 }},   // gap of 1 packet
-       // ack block length.
-       { "Unable to read ack block value.",
-         { kVarInt62TwoBytes + 0x0e, 0xae }},   // 3759
-
-       // pre-version-99 test includes an ack block of 0 length. this
-       // can not happen in version 99. ergo the second block is not
-       // present in the v99 test and the gap length of the next block
-       // is the sum of the two gaps in the pre-version-99 tests.
-       // Additional ACK Block #2
-       // gap to next block.
-       { "Unable to read gap block value.",
-         { kVarInt62TwoBytes + 0x01, 0x8f }},  // Gap is 400 (0x190) pkts
-       // ack block length.
-       { "Unable to read ack block value.",
-         { kVarInt62TwoBytes + 0x01, 0xe9 }},  // block is 389 (x1ea) pkts
-
-       // Additional ACK Block #3
-       // gap to next block.
-       { "Unable to read gap block value.",
-         { kVarInt62OneByte + 0x04 }},   // Gap is 5 packets.
-       // ack block length.
-       { "Unable to read ack block value.",
-         { kVarInt62OneByte + 0x03 }},   // block is 3 packets.
-
-       // Receive Timestamps.
-       { "Unable to read receive timestamp range count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x02 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62FourBytes + 0x36, 0x54, 0x32, 0x10 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x32, 0x10 }},
-  };
-
-  // clang-format on
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-
-  framer_.set_process_timestamps(true);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
-  ASSERT_EQ(4254u, frame.packets.NumPacketsSlow());
-  EXPECT_EQ(4u, frame.packets.NumIntervals());
-  EXPECT_EQ(2u, frame.received_packet_times.size());
-}
-
-TEST_P(QuicFramerTest, AckFrameMultipleReceiveTimestampRanges) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      {"",
-       { 0x22 }},
-       // largest acked
-       {"Unable to read largest acked.",
-        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        { kVarInt62OneByte + 0x00 }},
-       // number of additional ack blocks
-       {"Unable to read ack block count.",
-        { kVarInt62OneByte + 0x00 }},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
-
-       // Receive Timestamps.
-       { "Unable to read receive timestamp range count.",
-         { kVarInt62OneByte + 0x03 }},
-
-       // Timestamp range 1 (three packets).
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x02 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x03 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62FourBytes + 0x29, 0xff, 0xff, 0xff}},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x11, 0x11 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62OneByte + 0x01}},
-
-       // Timestamp range 2 (one packet).
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x05 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x10, 0x00 }},
-
-       // Timestamp range 3 (two packets).
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x08 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x02 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62OneByte + 0x10 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x01, 0x00 }},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-
-  framer_.set_process_timestamps(true);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  // Timestamp Range 1.
-                  {LargestAcked(frame) - 2, CreationTimePlus(0x29ffffff)},
-                  {LargestAcked(frame) - 3, CreationTimePlus(0x29ffeeee)},
-                  {LargestAcked(frame) - 4, CreationTimePlus(0x29ffeeed)},
-                  // Timestamp Range 2.
-                  {LargestAcked(frame) - 11, CreationTimePlus(0x29ffdeed)},
-                  // Timestamp Range 3.
-                  {LargestAcked(frame) - 21, CreationTimePlus(0x29ffdedd)},
-                  {LargestAcked(frame) - 22, CreationTimePlus(0x29ffdddd)},
-              }));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampWithExponent) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      {"",
-       { 0x22 }},
-       // largest acked
-       {"Unable to read largest acked.",
-        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        { kVarInt62OneByte + 0x00 }},
-       // number of additional ack blocks
-       {"Unable to read ack block count.",
-        { kVarInt62OneByte + 0x00 }},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
-
-       // Receive Timestamps.
-       { "Unable to read receive timestamp range count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x00 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x03 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x29, 0xff}},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x11, 0x11 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62OneByte + 0x01}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-
-  framer_.set_receive_timestamps_exponent(3);
-  framer_.set_process_timestamps(true);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  // Timestamp Range 1.
-                  {LargestAcked(frame), CreationTimePlus(0x29ff << 3)},
-                  {LargestAcked(frame) - 1, CreationTimePlus(0x18ee << 3)},
-                  {LargestAcked(frame) - 2, CreationTimePlus(0x18ed << 3)},
-              }));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampGapTooHigh) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      {"",
-       { 0x22 }},
-       // largest acked
-       {"Unable to read largest acked.",
-        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        { kVarInt62OneByte + 0x00 }},
-       // number of additional ack blocks
-       {"Unable to read ack block count.",
-        { kVarInt62OneByte + 0x00 }},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
-
-       // Receive Timestamps.
-       { "Unable to read receive timestamp range count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x79 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x29, 0xff}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-
-  framer_.set_process_timestamps(true);
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
-                               "Receive timestamp gap too high."));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampCountTooHigh) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      {"",
-       { 0x22 }},
-       // largest acked
-       {"Unable to read largest acked.",
-        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        { kVarInt62OneByte + 0x00 }},
-       // number of additional ack blocks
-       {"Unable to read ack block count.",
-        { kVarInt62OneByte + 0x00 }},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
-
-       // Receive Timestamps.
-       { "Unable to read receive timestamp range count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x02 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62OneByte + 0x02 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62OneByte + 0x0a}},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62OneByte + 0x0b}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-
-  framer_.set_process_timestamps(true);
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
-                               "Receive timestamp delta too high."));
-}
-
-TEST_P(QuicFramerTest, AckFrameReceiveTimestampDeltaTooHigh) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       { 0x43 }},
-      // connection_id
-      {"",
-       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
-      // packet number
-      {"",
-       { 0x12, 0x34, 0x56, 0x78 }},
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      {"",
-       { 0x22 }},
-       // largest acked
-       {"Unable to read largest acked.",
-        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
-       // Zero delta time.
-       {"Unable to read ack delay time.",
-        { kVarInt62OneByte + 0x00 }},
-       // number of additional ack blocks
-       {"Unable to read ack block count.",
-        { kVarInt62OneByte + 0x00 }},
-       // first ack block length.
-       {"Unable to read first ack block length.",
-        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
-
-       // Receive Timestamps.
-       { "Unable to read receive timestamp range count.",
-         { kVarInt62OneByte + 0x01 }},
-       { "Unable to read receive timestamp gap.",
-         { kVarInt62OneByte + 0x02 }},
-       { "Unable to read receive timestamp count.",
-         { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77 }},
-       { "Unable to read receive timestamp delta.",
-         { kVarInt62TwoBytes + 0x29, 0xff}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-
-  framer_.set_process_timestamps(true);
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
-                               "Receive timestamp count too high."));
-}
-
-TEST_P(QuicFramerTest, AckFrameTimeStampDeltaTooHigh) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x28,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 1 byte largest observed, 1 byte block length)
-      0x40,
-      // largest acked
-      0x01,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x01,
-      // num timestamps.
-      0x01,
-      // Delta from largest observed.
-      0x01,
-      // Delta time.
-      0x10, 0x32, 0x54, 0x76,
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 1 byte largest observed, 1 byte block length)
-      0x40,
-      // largest acked
-      0x01,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x01,
-      // num timestamps.
-      0x01,
-      // Delta from largest observed.
-      0x01,
-      // Delta time.
-      0x10, 0x32, 0x54, 0x76,
-  };
-  // clang-format on
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // ACK Timestamp is not a feature of IETF QUIC.
-    return;
-  }
-  QuicEncryptedPacket encrypted(
-      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
-      ABSL_ARRAYSIZE(packet), false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
-                               "delta_from_largest_observed too high"));
-}
-
-TEST_P(QuicFramerTest, AckFrameTimeStampSecondDeltaTooHigh) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x28,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 1 byte largest observed, 1 byte block length)
-      0x40,
-      // largest acked
-      0x03,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x03,
-      // num timestamps.
-      0x02,
-      // Delta from largest observed.
-      0x01,
-      // Delta time.
-      0x10, 0x32, 0x54, 0x76,
-      // Delta from largest observed.
-      0x03,
-      // Delta time.
-      0x10, 0x32,
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 1 byte largest observed, 1 byte block length)
-      0x40,
-      // largest acked
-      0x03,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x03,
-      // num timestamps.
-      0x02,
-      // Delta from largest observed.
-      0x01,
-      // Delta time.
-      0x10, 0x32, 0x54, 0x76,
-      // Delta from largest observed.
-      0x03,
-      // Delta time.
-      0x10, 0x32,
-  };
-  // clang-format on
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // ACK Timestamp is not a feature of IETF QUIC.
-    return;
-  }
-  QuicEncryptedPacket encrypted(
-      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
-      ABSL_ARRAYSIZE(packet), false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
-                               "delta_from_largest_observed too high"));
-}
-
-TEST_P(QuicFramerTest, NewStopWaitingFrame) {
-  if (VersionHasIetfQuicFrames(version_.transport_version)) {
-    // The Stop Waiting frame is not in IETF QUIC
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x2C}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stop waiting frame)
-      {"",
-       {0x06}},
-      // least packet number awaiting an ack, delta from packet number.
-      {"Unable to read least unacked delta.",
-        {0x00, 0x00, 0x00, 0x08}}
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (stop waiting frame)
-      {"",
-       {0x06}},
-      // least packet number awaiting an ack, delta from packet number.
-      {"Unable to read least unacked delta.",
-        {0x00, 0x00, 0x00, 0x08}}
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
-  const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
-  EXPECT_EQ(kLeastUnacked, frame.least_unacked);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_STOP_WAITING_DATA);
-}
-
-TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
-  // The Stop Waiting frame is not in IETF QUIC
-  if (VersionHasIetfQuicFrames(version_.transport_version) &&
-      framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-    // frame type (stop waiting frame)
-    0x06,
-    // least packet number awaiting an ack, delta from packet number.
-    0x13, 0x34, 0x56, 0x78,
-    0x9A, 0xA8,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-    // frame type (stop waiting frame)
-    0x06,
-    // least packet number awaiting an ack, delta from packet number.
-    0x57, 0x78, 0x9A, 0xA8,
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(
-      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet),
-      false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_STOP_WAITING_DATA));
-  EXPECT_EQ("Invalid unacked delta.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, RstStreamFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (rst stream frame)
-      {"",
-       {0x01}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // sent byte offset
-      {"Unable to read rst stream sent byte offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // error code QUIC_STREAM_CANCELLED
-      {"Unable to read rst stream error code.",
-       {0x00, 0x00, 0x00, 0x06}}
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (rst stream frame)
-      {"",
-       {0x01}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // sent byte offset
-      {"Unable to read rst stream sent byte offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // error code QUIC_STREAM_CANCELLED
-      {"Unable to read rst stream error code.",
-       {0x00, 0x00, 0x00, 0x06}}
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_RST_STREAM frame)
-      {"",
-       {0x04}},
-      // stream id
-      {"Unable to read IETF_RST_STREAM frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      // application error code H3_REQUEST_CANCELLED gets translated to
-      // QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED.
-      {"Unable to read rst stream error code.",
-       {kVarInt62TwoBytes + 0x01, 0x0c}},
-      // Final Offset
-      {"Unable to read rst stream sent byte offset.",
-       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}}
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id);
-  EXPECT_EQ(QUIC_STREAM_CANCELLED, visitor_.rst_stream_frame_.error_code);
-  EXPECT_EQ(kStreamOffset, visitor_.rst_stream_frame_.byte_offset);
-  CheckFramingBoundaries(fragments, QUIC_INVALID_RST_STREAM_DATA);
-}
-
-TEST_P(QuicFramerTest, ConnectionCloseFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (connection close frame)
-      {"",
-       {0x02}},
-      // error code
-      {"Unable to read connection close error code.",
-       {0x00, 0x00, 0x00, 0x11}},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (connection close frame)
-      {"",
-       {0x02}},
-      // error code
-      {"Unable to read connection close error code.",
-       {0x00, 0x00, 0x00, 0x11}},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF Transport CONNECTION_CLOSE frame)
-      {"",
-       {0x1c}},
-      // error code
-      {"Unable to read connection close error code.",
-       {kVarInt62TwoBytes + 0x00, 0x11}},
-      {"Unable to read connection close frame type.",
-       {kVarInt62TwoBytes + 0x12, 0x34 }},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         kVarInt62OneByte + 0x11,
-         // error details with QuicErrorCode serialized
-         '1',  '1',  '5',  ':',
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0x11u, static_cast<unsigned>(
-                       visitor_.connection_close_frame_.wire_error_code));
-  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    EXPECT_EQ(0x1234u,
-              visitor_.connection_close_frame_.transport_close_frame_type);
-    EXPECT_EQ(115u, visitor_.connection_close_frame_.quic_error_code);
-  } else {
-    // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
-    // same value.
-    EXPECT_EQ(0x11u, static_cast<unsigned>(
-                         visitor_.connection_close_frame_.quic_error_code));
-  }
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-TEST_P(QuicFramerTest, ConnectionCloseFrameWithUnknownErrorCode) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (connection close frame)
-      {"",
-       {0x02}},
-      // error code larger than QUIC_LAST_ERROR
-      {"Unable to read connection close error code.",
-       {0x00, 0x00, 0xC0, 0xDE}},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (connection close frame)
-      {"",
-       {0x02}},
-      // error code larger than QUIC_LAST_ERROR
-      {"Unable to read connection close error code.",
-       {0x00, 0x00, 0xC0, 0xDE}},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF Transport CONNECTION_CLOSE frame)
-      {"",
-       {0x1c}},
-      // error code
-      {"Unable to read connection close error code.",
-       {kVarInt62FourBytes + 0x00, 0x00, 0xC0, 0xDE}},
-      {"Unable to read connection close frame type.",
-       {kVarInt62TwoBytes + 0x12, 0x34 }},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         kVarInt62OneByte + 0x11,
-         // error details with QuicErrorCode larger than QUIC_LAST_ERROR
-         '8',  '4',  '9',  ':',
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    EXPECT_EQ(0x1234u,
-              visitor_.connection_close_frame_.transport_close_frame_type);
-    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
-    EXPECT_EQ(849u, visitor_.connection_close_frame_.quic_error_code);
-  } else {
-    // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
-    // same value.
-    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
-    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.quic_error_code);
-  }
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-// As above, but checks that for Google-QUIC, if there happens
-// to be an ErrorCode string at the start of the details, it is
-// NOT extracted/parsed/folded/spindled/and/mutilated.
-TEST_P(QuicFramerTest, ConnectionCloseFrameWithExtractedInfoIgnoreGCuic) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet = {
-    // public flags (8 byte connection_id)
-    {"",
-     {0x28}},
-    // connection_id
-    {"",
-     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-    // packet number
-    {"",
-     {0x12, 0x34, 0x56, 0x78}},
-    // frame type (connection close frame)
-    {"",
-     {0x02}},
-    // error code
-    {"Unable to read connection close error code.",
-     {0x00, 0x00, 0x00, 0x11}},
-    {"Unable to read connection close error details.",
-     {
-       // error details length
-       0x0, 0x13,
-       // error details
-      '1',  '7',  '7',  '6',
-      '7',  ':',  'b',  'e',
-      'c',  'a',  'u',  's',
-      'e',  ' ',  'I',  ' ',
-      'c',  'a',  'n'}
-    }
-  };
-
-  PacketFragments packet46 = {
-    // type (short header, 4 byte packet number)
-    {"",
-     {0x43}},
-    // connection_id
-    {"",
-     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-    // packet number
-    {"",
-     {0x12, 0x34, 0x56, 0x78}},
-    // frame type (connection close frame)
-    {"",
-     {0x02}},
-    // error code
-    {"Unable to read connection close error code.",
-     {0x00, 0x00, 0x00, 0x11}},
-    {"Unable to read connection close error details.",
-     {
-       // error details length
-       0x0, 0x13,
-       // error details
-      '1',  '7',  '7',  '6',
-      '7',  ':',  'b',  'e',
-      'c',  'a',  'u',  's',
-      'e',  ' ',  'I',  ' ',
-      'c',  'a',  'n'}
-    }
-  };
-
-  PacketFragments packet_ietf = {
-    // type (short header, 4 byte packet number)
-    {"",
-     {0x43}},
-    // connection_id
-    {"",
-     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-    // packet number
-    {"",
-     {0x12, 0x34, 0x56, 0x78}},
-    // frame type (IETF Transport CONNECTION_CLOSE frame)
-    {"",
-     {0x1c}},
-    // error code
-    {"Unable to read connection close error code.",
-     {kVarInt62OneByte + 0x11}},
-    {"Unable to read connection close frame type.",
-     {kVarInt62TwoBytes + 0x12, 0x34 }},
-    {"Unable to read connection close error details.",
-     {
-       // error details length
-       kVarInt62OneByte + 0x13,
-       // error details
-      '1',  '7',  '7',  '6',
-      '7',  ':',  'b',  'e',
-      'c',  'a',  'u',  's',
-      'e',  ' ',  'I',  ' ',
-      'c',  'a',  'n'}
-    }
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0x11u, static_cast<unsigned>(
-                       visitor_.connection_close_frame_.wire_error_code));
-
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    EXPECT_EQ(0x1234u,
-              visitor_.connection_close_frame_.transport_close_frame_type);
-    EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
-    EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-  } else {
-    EXPECT_EQ(0x11u, visitor_.connection_close_frame_.quic_error_code);
-    // Error code is not prepended in GQUIC, so it is not removed and should
-    // remain in the reason phrase.
-    EXPECT_EQ("17767:because I can",
-              visitor_.connection_close_frame_.error_details);
-  }
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-// Test the CONNECTION_CLOSE/Application variant.
-TEST_P(QuicFramerTest, ApplicationCloseFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only in IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_CONNECTION_CLOSE/Application frame)
-      {"",
-       {0x1d}},
-      // error code
-      {"Unable to read connection close error code.",
-       {kVarInt62TwoBytes + 0x00, 0x11}},
-      {"Unable to read connection close error details.",
-       {
-         // error details length
-         kVarInt62OneByte + 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
-  EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
-            visitor_.connection_close_frame_.close_type);
-  EXPECT_EQ(122u, visitor_.connection_close_frame_.quic_error_code);
-  EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
-  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-// Check that we can extract an error code from an application close.
-TEST_P(QuicFramerTest, ApplicationCloseFrameExtract) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only in IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_CONNECTION_CLOSE/Application frame)
-      {"",
-       {0x1d}},
-      // error code
-      {"Unable to read connection close error code.",
-       {kVarInt62OneByte + 0x11}},
-      {"Unable to read connection close error details.",
-       {
-       // error details length
-       kVarInt62OneByte + 0x13,
-       // error details
-       '1',  '7',  '7',  '6',
-       '7',  ':',  'b',  'e',
-       'c',  'a',  'u',  's',
-       'e',  ' ',  'I',  ' ',
-       'c',  'a',  'n'}
-      }
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
-  EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
-            visitor_.connection_close_frame_.close_type);
-  EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
-  EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
-  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
-}
-
-TEST_P(QuicFramerTest, GoAwayFrame) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is not in IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (go away frame)
-      {"",
-       {0x03}},
-      // error code
-      {"Unable to read go away error code.",
-       {0x00, 0x00, 0x00, 0x09}},
-      // stream id
-      {"Unable to read last good stream id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // stream id
-      {"Unable to read goaway reason.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (go away frame)
-      {"",
-       {0x03}},
-      // error code
-      {"Unable to read go away error code.",
-       {0x00, 0x00, 0x00, 0x09}},
-      // stream id
-      {"Unable to read last good stream id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // stream id
-      {"Unable to read goaway reason.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
-  EXPECT_EQ(0x9u, visitor_.goaway_frame_.error_code);
-  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
-}
-
-TEST_P(QuicFramerTest, GoAwayFrameWithUnknownErrorCode) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is not in IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (go away frame)
-      {"",
-       {0x03}},
-      // error code larger than QUIC_LAST_ERROR
-      {"Unable to read go away error code.",
-       {0x00, 0x00, 0xC0, 0xDE}},
-      // stream id
-      {"Unable to read last good stream id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // stream id
-      {"Unable to read goaway reason.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (go away frame)
-      {"",
-       {0x03}},
-      // error code larger than QUIC_LAST_ERROR
-      {"Unable to read go away error code.",
-       {0x00, 0x00, 0xC0, 0xDE}},
-      // stream id
-      {"Unable to read last good stream id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // stream id
-      {"Unable to read goaway reason.",
-       {
-         // error details length
-         0x0, 0x0d,
-         // error details
-         'b',  'e',  'c',  'a',
-         'u',  's',  'e',  ' ',
-         'I',  ' ',  'c',  'a',
-         'n'}
-      }
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
-  EXPECT_EQ(0xC0DE, visitor_.goaway_frame_.error_code);
-  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
-}
-
-TEST_P(QuicFramerTest, WindowUpdateFrame) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is not in IETF QUIC, see MaxDataFrame and MaxStreamDataFrame
-    // for IETF QUIC equivalents.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (window update frame)
-      {"",
-       {0x04}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // byte offset
-      {"Unable to read window byte_offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (window update frame)
-      {"",
-       {0x04}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-      // byte offset
-      {"Unable to read window byte_offset.",
-       {0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-  };
-
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
-  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_WINDOW_UPDATE_DATA);
-}
-
-TEST_P(QuicFramerTest, MaxDataFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is available only in IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_MAX_DATA frame)
-      {"",
-       {0x10}},
-      // byte offset
-      {"Can not read MAX_DATA byte-offset",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(QuicUtils::GetInvalidStreamId(framer_.transport_version()),
-            visitor_.window_update_frame_.stream_id);
-  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_DATA_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, MaxStreamDataFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame available only in IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_MAX_STREAM_DATA frame)
-      {"",
-       {0x11}},
-      // stream id
-      {"Unable to read IETF_MAX_STREAM_DATA frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      // byte offset
-      {"Can not read MAX_STREAM_DATA byte-count",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
-  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, BlockedFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (8 byte connection_id)
-      {"",
-       {0x28}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (blocked frame)
-      {"",
-       {0x05}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-  };
-
-  PacketFragments packet46 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (blocked frame)
-      {"",
-       {0x05}},
-      // stream id
-      {"Unable to read stream_id.",
-       {0x01, 0x02, 0x03, 0x04}},
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_STREAM_BLOCKED frame)
-      {"",
-       {0x15}},
-      // stream id
-      {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      // Offset
-      {"Can not read stream blocked offset.",
-       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? packet_ietf
-          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
-  } else {
-    EXPECT_EQ(0u, visitor_.blocked_frame_.offset);
-  }
-  EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
-
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_BLOCKED_DATA);
-  } else {
-    CheckFramingBoundaries(fragments, QUIC_INVALID_BLOCKED_DATA);
-  }
-}
-
-TEST_P(QuicFramerTest, PingFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-     // public flags (8 byte connection_id)
-     0x28,
-     // connection_id
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-     // packet number
-     0x12, 0x34, 0x56, 0x78,
-
-     // frame type (ping frame)
-     0x07,
-    };
-
-  unsigned char packet46[] = {
-     // type (short header, 4 byte packet number)
-     0x43,
-     // connection_id
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-     // packet number
-     0x12, 0x34, 0x56, 0x78,
-
-     // frame type
-     0x07,
-    };
-
-  unsigned char packet_ietf[] = {
-     // type (short header, 4 byte packet number)
-     0x43,
-     // connection_id
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-     // packet number
-     0x12, 0x34, 0x56, 0x78,
-
-     // frame type (IETF_PING frame)
-     0x01,
-    };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(
-      AsChars(VersionHasIetfQuicFrames(framer_.transport_version())
-                  ? packet_ietf
-                  : (framer_.version().HasIetfInvariantHeader() ? packet46
-                                                                : packet)),
-      VersionHasIetfQuicFrames(framer_.transport_version())
-          ? ABSL_ARRAYSIZE(packet_ietf)
-          : (framer_.version().HasIetfInvariantHeader()
-                 ? ABSL_ARRAYSIZE(packet46)
-                 : ABSL_ARRAYSIZE(packet)),
-      false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(1u, visitor_.ping_frames_.size());
-
-  // No need to check the PING frame boundaries because it has no payload.
-}
-
-TEST_P(QuicFramerTest, HandshakeDoneFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-     // type (short header, 4 byte packet number)
-     0x43,
-     // connection_id
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-     // packet number
-     0x12, 0x34, 0x56, 0x78,
-
-     // frame type (Handshake done frame)
-     0x1e,
-    };
-  // clang-format on
-
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(1u, visitor_.handshake_done_frames_.size());
-}
-
-TEST_P(QuicFramerTest, ParseAckFrequencyFrame) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-     // type (short header, 4 byte packet number)
-     0x43,
-     // connection_id
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-     // packet number
-     0x12, 0x34, 0x56, 0x78,
-
-     // ack frequency frame type (which needs two bytes as it is > 0x3F)
-     0x40, 0xAF,
-     // sequence_number
-     0x11,
-     // packet_tolerance
-     0x02,
-     // max_ack_delay_us = 2'5000 us
-     0x80, 0x00, 0x61, 0xA8,
-     // ignore_order
-     0x01
-  };
-  // clang-format on
-
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(1u, visitor_.ack_frequency_frames_.size());
-  const auto& frame = visitor_.ack_frequency_frames_.front();
-  EXPECT_EQ(17u, frame->sequence_number);
-  EXPECT_EQ(2u, frame->packet_tolerance);
-  EXPECT_EQ(2'5000u, frame->max_ack_delay.ToMicroseconds());
-  EXPECT_EQ(true, frame->ignore_order);
-}
-
-TEST_P(QuicFramerTest, MessageFrame) {
-  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet46 = {
-       // type (short header, 4 byte packet number)
-       {"",
-        {0x43}},
-       // connection_id
-       {"",
-        {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-       // packet number
-       {"",
-        {0x12, 0x34, 0x56, 0x78}},
-       // message frame type.
-       {"",
-        { 0x21 }},
-       // message length
-       {"Unable to read message length",
-        {0x07}},
-       // message data
-       {"Unable to read message data",
-        {'m', 'e', 's', 's', 'a', 'g', 'e'}},
-        // message frame no length.
-        {"",
-         { 0x20 }},
-        // message data
-        {{},
-         {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
-   };
-  PacketFragments packet_ietf = {
-       // type (short header, 4 byte packet number)
-       {"",
-        {0x43}},
-       // connection_id
-       {"",
-        {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-       // packet number
-       {"",
-        {0x12, 0x34, 0x56, 0x78}},
-       // message frame type.
-       {"",
-        { 0x31 }},
-       // message length
-       {"Unable to read message length",
-        {0x07}},
-       // message data
-       {"Unable to read message data",
-        {'m', 'e', 's', 's', 'a', 'g', 'e'}},
-        // message frame no length.
-        {"",
-         { 0x30 }},
-        // message data
-        {{},
-         {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
-   };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    encrypted = AssemblePacketFromFragments(packet_ietf);
-  } else {
-    encrypted = AssemblePacketFromFragments(packet46);
-  }
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  ASSERT_EQ(2u, visitor_.message_frames_.size());
-  EXPECT_EQ(7u, visitor_.message_frames_[0]->message_length);
-  EXPECT_EQ(8u, visitor_.message_frames_[1]->message_length);
-
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MESSAGE_DATA);
-  } else {
-    CheckFramingBoundaries(packet46, QUIC_INVALID_MESSAGE_DATA);
-  }
-}
-
-TEST_P(QuicFramerTest, PublicResetPacketV33) {
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (public reset, 8 byte connection_id)
-      {"",
-       {0x0A}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      {"Unable to read reset message.",
-       {
-         // message tag (kPRST)
-         'P', 'R', 'S', 'T',
-         // num_entries (2) + padding
-         0x02, 0x00, 0x00, 0x00,
-         // tag kRNON
-         'R', 'N', 'O', 'N',
-         // end offset 8
-         0x08, 0x00, 0x00, 0x00,
-         // tag kRSEQ
-         'R', 'S', 'E', 'Q',
-         // end offset 16
-         0x10, 0x00, 0x00, 0x00,
-         // nonce proof
-         0x89, 0x67, 0x45, 0x23,
-         0x01, 0xEF, 0xCD, 0xAB,
-         // rejected packet number
-         0xBC, 0x9A, 0x78, 0x56,
-         0x34, 0x12, 0x00, 0x00,
-       }
-      }
-  };
-  // clang-format on
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  ASSERT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.public_reset_packet_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.public_reset_packet_->connection_id);
-  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
-  EXPECT_EQ(
-      IpAddressFamily::IP_UNSPEC,
-      visitor_.public_reset_packet_->client_address.host().address_family());
-
-  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
-}
-
-TEST_P(QuicFramerTest, PublicResetPacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (public reset, 8 byte connection_id)
-      {"",
-       {0x0E}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      {"Unable to read reset message.",
-       {
-         // message tag (kPRST)
-         'P', 'R', 'S', 'T',
-         // num_entries (2) + padding
-         0x02, 0x00, 0x00, 0x00,
-         // tag kRNON
-         'R', 'N', 'O', 'N',
-         // end offset 8
-         0x08, 0x00, 0x00, 0x00,
-         // tag kRSEQ
-         'R', 'S', 'E', 'Q',
-         // end offset 16
-         0x10, 0x00, 0x00, 0x00,
-         // nonce proof
-         0x89, 0x67, 0x45, 0x23,
-         0x01, 0xEF, 0xCD, 0xAB,
-         // rejected packet number
-         0xBC, 0x9A, 0x78, 0x56,
-         0x34, 0x12, 0x00, 0x00,
-       }
-      }
-  };
-  // clang-format on
-
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  ASSERT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.public_reset_packet_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.public_reset_packet_->connection_id);
-  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
-  EXPECT_EQ(
-      IpAddressFamily::IP_UNSPEC,
-      visitor_.public_reset_packet_->client_address.host().address_family());
-
-  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
-}
-
-TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (public reset, 8 byte connection_id)
-    0x0A,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // message tag (kPRST)
-    'P', 'R', 'S', 'T',
-    // num_entries (2) + padding
-    0x02, 0x00, 0x00, 0x00,
-    // tag kRNON
-    'R', 'N', 'O', 'N',
-    // end offset 8
-    0x08, 0x00, 0x00, 0x00,
-    // tag kRSEQ
-    'R', 'S', 'E', 'Q',
-    // end offset 16
-    0x10, 0x00, 0x00, 0x00,
-    // nonce proof
-    0x89, 0x67, 0x45, 0x23,
-    0x01, 0xEF, 0xCD, 0xAB,
-    // rejected packet number
-    0xBC, 0x9A, 0x78, 0x56,
-    0x34, 0x12, 0x00, 0x00,
-    // trailing junk
-    'j', 'u', 'n', 'k',
-  };
-  // clang-format on
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  ASSERT_THAT(framer_.error(), IsError(QUIC_INVALID_PUBLIC_RST_PACKET));
-  EXPECT_EQ("Unable to read reset message.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (public reset, 8 byte connection_id)
-      {"",
-       {0x0A}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      {"Unable to read reset message.",
-       {
-         // message tag (kPRST)
-         'P', 'R', 'S', 'T',
-         // num_entries (2) + padding
-         0x03, 0x00, 0x00, 0x00,
-         // tag kRNON
-         'R', 'N', 'O', 'N',
-         // end offset 8
-         0x08, 0x00, 0x00, 0x00,
-         // tag kRSEQ
-         'R', 'S', 'E', 'Q',
-         // end offset 16
-         0x10, 0x00, 0x00, 0x00,
-         // tag kCADR
-         'C', 'A', 'D', 'R',
-         // end offset 24
-         0x18, 0x00, 0x00, 0x00,
-         // nonce proof
-         0x89, 0x67, 0x45, 0x23,
-         0x01, 0xEF, 0xCD, 0xAB,
-         // rejected packet number
-         0xBC, 0x9A, 0x78, 0x56,
-         0x34, 0x12, 0x00, 0x00,
-         // client address: 4.31.198.44:443
-         0x02, 0x00,
-         0x04, 0x1F, 0xC6, 0x2C,
-         0xBB, 0x01,
-       }
-      }
-  };
-  // clang-format on
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  ASSERT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.public_reset_packet_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.public_reset_packet_->connection_id);
-  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
-  EXPECT_EQ("4.31.198.44",
-            visitor_.public_reset_packet_->client_address.host().ToString());
-  EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
-
-  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
-}
-
-TEST_P(QuicFramerTest, IetfStatelessResetPacket) {
-  // clang-format off
-  unsigned char packet[] = {
-      // type (short packet, 1 byte packet number)
-      0x50,
-      // Random bytes
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      // stateless reset token
-      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-  };
-  // clang-format on
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
-                                                      TestConnectionId(0x33));
-  decrypter_ = new test::TestDecrypter();
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(
-        ENCRYPTION_INITIAL,
-        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::unique_ptr<QuicDecrypter>(decrypter_));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
-                                                 Perspective::IS_CLIENT));
-    framer_.SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
-  }
-  // This packet cannot be decrypted because diversification nonce is missing.
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  ASSERT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.stateless_reset_packet_.get());
-  EXPECT_EQ(kTestStatelessResetToken,
-            visitor_.stateless_reset_packet_->stateless_reset_token);
-}
-
-TEST_P(QuicFramerTest, IetfStatelessResetPacketInvalidStatelessResetToken) {
-  // clang-format off
-  unsigned char packet[] = {
-      // type (short packet, 1 byte packet number)
-      0x50,
-      // Random bytes
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
-      // stateless reset token
-      0xB6, 0x69, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  // clang-format on
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
-                                                      TestConnectionId(0x33));
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  decrypter_ = new test::TestDecrypter();
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(
-        ENCRYPTION_INITIAL,
-        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::unique_ptr<QuicDecrypter>(decrypter_));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
-                                                 Perspective::IS_CLIENT));
-    framer_.SetAlternativeDecrypter(
-        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
-  }
-  // This packet cannot be decrypted because diversification nonce is missing.
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-  ASSERT_FALSE(visitor_.stateless_reset_packet_);
-}
-
-TEST_P(QuicFramerTest, VersionNegotiationPacketClient) {
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (version, 8 byte connection_id)
-      {"",
-       {0x29}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // version tag
-      {"Unable to read supported version in negotiation.",
-       {QUIC_VERSION_BYTES,
-        'Q', '2', '.', '0'}},
-  };
-
-  PacketFragments packet46 = {
-      // type (long header)
-      {"",
-       {0x8F}},
-      // version tag
-      {"",
-       {0x00, 0x00, 0x00, 0x00}},
-      {"",
-       {0x05}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // Supported versions
-      {"Unable to read supported version in negotiation.",
-       {QUIC_VERSION_BYTES,
-        'Q', '2', '.', '0'}},
-  };
-
-  PacketFragments packet49 = {
-      // type (long header)
-      {"",
-       {0x8F}},
-      // version tag
-      {"",
-       {0x00, 0x00, 0x00, 0x00}},
-      {"",
-       {0x08}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      {"",
-       {0x00}},
-      // Supported versions
-      {"Unable to read supported version in negotiation.",
-       {QUIC_VERSION_BYTES,
-        'Q', '2', '.', '0'}},
-  };
-  // clang-format on
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  PacketFragments& fragments =
-      framer_.version().HasLongHeaderLengths()     ? packet49
-      : framer_.version().HasIetfInvariantHeader() ? packet46
-                                                   : packet;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  ASSERT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
-  EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
-  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
-
-  // Remove the last version from the packet so that every truncated
-  // version of the packet is invalid, otherwise checking boundaries
-  // is annoyingly complicated.
-  for (size_t i = 0; i < 4; ++i) {
-    fragments.back().fragment.pop_back();
-  }
-  CheckFramingBoundaries(fragments, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-}
-
-TEST_P(QuicFramerTest, VersionNegotiationPacketServer) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (long header with all ignored bits set)
-      0xFF,
-      // version
-      0x00, 0x00, 0x00, 0x00,
-      // connection ID lengths
-      0x50,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // supported versions
-      QUIC_VERSION_BYTES,
-      'Q', '2', '.', '0',
-  };
-  unsigned char packet2[] = {
-      // public flags (long header with all ignored bits set)
-      0xFF,
-      // version
-      0x00, 0x00, 0x00, 0x00,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // source connection ID length
-      0x00,
-      // supported versions
-      QUIC_VERSION_BYTES,
-      'Q', '2', '.', '0',
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLengthPrefixedConnectionIds()) {
-    p = packet2;
-    p_length = ABSL_ARRAYSIZE(packet2);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(),
-              IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
-  EXPECT_EQ("Server received version negotiation packet.",
-            framer_.detailed_error());
-  EXPECT_FALSE(visitor_.version_negotiation_packet_.get());
-}
-
-TEST_P(QuicFramerTest, OldVersionNegotiationPacket) {
-  // clang-format off
-  PacketFragments packet = {
-      // public flags (version, 8 byte connection_id)
-      {"",
-       {0x2D}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // version tag
-      {"Unable to read supported version in negotiation.",
-       {QUIC_VERSION_BYTES,
-        'Q', '2', '.', '0'}},
-  };
-  // clang-format on
-
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  ASSERT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
-  EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
-  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
-
-  // Remove the last version from the packet so that every truncated
-  // version of the packet is invalid, otherwise checking boundaries
-  // is annoyingly complicated.
-  for (size_t i = 0; i < 4; ++i) {
-    packet.back().fragment.pop_back();
-  }
-  CheckFramingBoundaries(packet, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
-}
-
-TEST_P(QuicFramerTest, ParseIetfRetryPacket) {
-  if (!framer_.version().SupportsRetry()) {
-    return;
-  }
-  // IETF RETRY is only sent from client to server.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (long header with packet type RETRY and ODCIL=8)
-      0xF5,
-      // version
-      QUIC_VERSION_BYTES,
-      // connection ID lengths
-      0x05,
-      // source connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // original destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // retry token
-      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
-      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
-  };
-  unsigned char packet49[] = {
-      // public flags (long header with packet type RETRY)
-      0xF0,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x00,
-      // source connection ID length
-      0x08,
-      // source connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // original destination connection ID length
-      0x08,
-      // original destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // retry token
-      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
-      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
-  };
-  unsigned char packet_with_tag[] = {
-      // public flags (long header with packet type RETRY)
-      0xF0,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x00,
-      // source connection ID length
-      0x08,
-      // source connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // retry token
-      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
-      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
-      // retry token integrity tag
-      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().UsesTls()) {
-    ReviseFirstByteByVersion(packet_with_tag);
-    p = packet_with_tag;
-    p_length = ABSL_ARRAYSIZE(packet_with_tag);
-  } else if (framer_.version().HasLongHeaderLengths()) {
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  }
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_TRUE(visitor_.on_retry_packet_called_);
-  ASSERT_TRUE(visitor_.retry_new_connection_id_.get());
-  ASSERT_TRUE(visitor_.retry_token_.get());
-
-  if (framer_.version().UsesTls()) {
-    ASSERT_TRUE(visitor_.retry_token_integrity_tag_.get());
-    static const unsigned char expected_integrity_tag[16] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    };
-    quiche::test::CompareCharArraysWithHexError(
-        "retry integrity tag", visitor_.retry_token_integrity_tag_->data(),
-        visitor_.retry_token_integrity_tag_->length(),
-        reinterpret_cast<const char*>(expected_integrity_tag),
-        ABSL_ARRAYSIZE(expected_integrity_tag));
-    ASSERT_TRUE(visitor_.retry_without_tag_.get());
-    quiche::test::CompareCharArraysWithHexError(
-        "retry without tag", visitor_.retry_without_tag_->data(),
-        visitor_.retry_without_tag_->length(),
-        reinterpret_cast<const char*>(packet_with_tag), 35);
-  } else {
-    ASSERT_TRUE(visitor_.retry_original_connection_id_.get());
-    EXPECT_EQ(FramerTestConnectionId(),
-              *visitor_.retry_original_connection_id_.get());
-  }
-
-  EXPECT_EQ(FramerTestConnectionIdPlusOne(),
-            *visitor_.retry_new_connection_id_.get());
-  EXPECT_EQ("Hello this is RETRY!", *visitor_.retry_token_.get());
-
-  // IETF RETRY is only sent from client to server, the rest of this test
-  // ensures that the server correctly drops them without acting on them.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Reset our visitor state to default settings.
-  visitor_.retry_original_connection_id_.reset();
-  visitor_.retry_new_connection_id_.reset();
-  visitor_.retry_token_.reset();
-  visitor_.retry_token_integrity_tag_.reset();
-  visitor_.retry_without_tag_.reset();
-  visitor_.on_retry_packet_called_ = false;
-
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-  EXPECT_EQ("Client-initiated RETRY is invalid.", framer_.detailed_error());
-
-  EXPECT_FALSE(visitor_.on_retry_packet_called_);
-  EXPECT_FALSE(visitor_.retry_new_connection_id_.get());
-  EXPECT_FALSE(visitor_.retry_token_.get());
-  EXPECT_FALSE(visitor_.retry_token_integrity_tag_.get());
-  EXPECT_FALSE(visitor_.retry_without_tag_.get());
-}
-
-TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // clang-format off
-  unsigned char packet[kMaxOutgoingPacketSize] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[kMaxOutgoingPacketSize] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  uint64_t header_size = GetPacketHeaderSize(
-      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
-                               absl::string_view("hello world!"));
-  QuicPaddingFrame padding_frame(2);
-  QuicFrames frames = {QuicFrame(padding_frame), QuicFrame(stream_frame),
-                       QuicFrame(padding_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // paddings
-    0x00, 0x00,
-    // frame type (stream frame with fin)
-    0xFF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-    // paddings
-    0x00, 0x00,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // paddings
-    0x00, 0x00,
-    // frame type (stream frame with fin)
-    0xFF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-    // paddings
-    0x00, 0x00,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // paddings
-    0x00, 0x00,
-    // frame type (IETF_STREAM with FIN, LEN, and OFFSET bits set)
-    0x08 | 0x01 | 0x02 | 0x04,
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // offset
-    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    kVarInt62OneByte + 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-    // paddings
-    0x00, 0x00,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // clang-format off
-  unsigned char packet[kMaxOutgoingPacketSize] = {
-    // public flags (8 byte connection_id and 4 byte packet number)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[kMaxOutgoingPacketSize] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  uint64_t header_size = GetPacketHeaderSize(
-      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // clang-format off
-  unsigned char packet[kMaxOutgoingPacketSize] = {
-    // public flags (8 byte connection_id and 2 byte packet number)
-    0x1C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[kMaxOutgoingPacketSize] = {
-    // type (short header, 2 byte packet number)
-    0x41,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
-    // type (short header, 2 byte packet number)
-    0x41,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x56, 0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  uint64_t header_size = GetPacketHeaderSize(
-      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // clang-format off
-  unsigned char packet[kMaxOutgoingPacketSize] = {
-    // public flags (8 byte connection_id and 1 byte packet number)
-    0x0C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[kMaxOutgoingPacketSize] = {
-    // type (short header, 1 byte packet number)
-    0x40,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
-    // type (short header, 1 byte packet number)
-    0x40,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x78,
-
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  uint64_t header_size = GetPacketHeaderSize(
-      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildStreamFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-
-  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
-                               absl::string_view("hello world!"));
-
-  QuicFrames frames = {QuicFrame(stream_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (stream frame with fin and no length)
-    0xDF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (stream frame with fin and no length)
-    0xDF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_STREAM frame with FIN and OFFSET, no length)
-    0x08 | 0x01 | 0x04,
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // offset
-    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = true;
-  if (framer_.version().HasIetfInvariantHeader()) {
-    header.long_packet_type = ZERO_RTT_PROTECTED;
-  }
-  header.packet_number = kPacketNumber;
-  if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-
-  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
-                               absl::string_view("hello world!"));
-  QuicFrames frames = {QuicFrame(stream_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (version, 8 byte connection_id)
-      0x2D,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // version tag
-      QUIC_VERSION_BYTES,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (stream frame with fin and no length)
-      0xDF,
-      // stream id
-      0x01, 0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data
-      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
-  };
-
-  unsigned char packet46[] = {
-      // type (long header with packet type ZERO_RTT_PROTECTED)
-      0xD3,
-      // version tag
-      QUIC_VERSION_BYTES,
-      // connection_id length
-      0x50,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (stream frame with fin and no length)
-      0xDF,
-      // stream id
-      0x01, 0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data
-      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
-  };
-
-  unsigned char packet49[] = {
-      // type (long header with packet type ZERO_RTT_PROTECTED)
-      0xD3,
-      // version tag
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // length
-      0x40, 0x1D,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (stream frame with fin and no length)
-      0xDF,
-      // stream id
-      0x01, 0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data
-      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
-  };
-
-  unsigned char packet_ietf[] = {
-      // type (long header with packet type ZERO_RTT_PROTECTED)
-      0xD3,
-      // version tag
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // length
-      0x40, 0x1D,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (IETF_STREAM frame with fin and offset, no length)
-      0x08 | 0x01 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data
-      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
-  };
-  // clang-format on
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    ReviseFirstByteByVersion(packet_ietf);
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasLongHeaderLengths()) {
-    p = packet49;
-    p_size = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildCryptoFramePacket) {
-  if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  SimpleDataProducer data_producer;
-  framer_.set_data_producer(&data_producer);
-
-  absl::string_view crypto_frame_contents("hello world!");
-  QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, kStreamOffset,
-                               crypto_frame_contents.length());
-  data_producer.SaveCryptoData(ENCRYPTION_INITIAL, kStreamOffset,
-                               crypto_frame_contents);
-
-  QuicFrames frames = {QuicFrame(&crypto_frame)};
-
-  // clang-format off
-  unsigned char packet48[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (QuicFrameType CRYPTO_FRAME)
-    0x08,
-    // offset
-    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // length
-    kVarInt62OneByte + 12,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_CRYPTO frame)
-    0x06,
-    // offset
-    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // length
-    kVarInt62OneByte + 12,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-  };
-  // clang-format on
-
-  unsigned char* packet = packet48;
-  size_t packet_size = ABSL_ARRAYSIZE(packet48);
-  if (framer_.version().HasIetfQuicFrames()) {
-    packet = packet_ietf;
-    packet_size = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError("constructed packet",
-                                              data->data(), data->length(),
-                                              AsChars(packet), packet_size);
-}
-
-TEST_P(QuicFramerTest, CryptoFrame) {
-  if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    // CRYPTO frames aren't supported prior to v48.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet48 = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (QuicFrameType CRYPTO_FRAME)
-      {"",
-       {0x08}},
-      // offset
-      {"",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Invalid data length.",
-       {kVarInt62OneByte + 12}},
-      // data
-      {"Unable to read frame data.",
-       {'h',  'e',  'l',  'l',
-        'o',  ' ',  'w',  'o',
-        'r',  'l',  'd',  '!'}},
-  };
-
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_CRYPTO frame)
-      {"",
-       {0x06}},
-      // offset
-      {"",
-       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-        0x32, 0x10, 0x76, 0x54}},
-      // data length
-      {"Invalid data length.",
-       {kVarInt62OneByte + 12}},
-      // data
-      {"Unable to read frame data.",
-       {'h',  'e',  'l',  'l',
-        'o',  ' ',  'w',  'o',
-        'r',  'l',  'd',  '!'}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasIetfQuicFrames() ? packet_ietf : packet48;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-  ASSERT_EQ(1u, visitor_.crypto_frames_.size());
-  QuicCryptoFrame* frame = visitor_.crypto_frames_[0].get();
-  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, frame->level);
-  EXPECT_EQ(kStreamOffset, frame->offset);
-  EXPECT_EQ("hello world!",
-            std::string(frame->data_buffer, frame->data_length));
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
-  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (version, 8 byte connection_id)
-      0x0D,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // supported versions
-      0xDA, 0x5A, 0x3A, 0x3A,
-      QUIC_VERSION_BYTES,
-  };
-  unsigned char packet46[] = {
-      // type (long header)
-      0xC0,
-      // version tag
-      0x00, 0x00, 0x00, 0x00,
-      // connection_id length
-      0x05,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // supported versions
-      0xDA, 0x5A, 0x3A, 0x3A,
-      QUIC_VERSION_BYTES,
-  };
-  unsigned char packet49[] = {
-      // type (long header)
-      0xC0,
-      // version tag
-      0x00, 0x00, 0x00, 0x00,
-      // destination connection ID length
-      0x00,
-      // source connection ID length
-      0x08,
-      // source connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // supported versions
-      0xDA, 0x5A, 0x3A, 0x3A,
-      QUIC_VERSION_BYTES,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    p = packet49;
-    p_size = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  QuicConnectionId connection_id = FramerTestConnectionId();
-  std::unique_ptr<QuicEncryptedPacket> data(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id, EmptyQuicConnectionId(),
-          framer_.version().HasIetfInvariantHeader(),
-          framer_.version().HasLengthPrefixedConnectionIds(),
-          SupportedVersions(GetParam())));
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildVersionNegotiationPacketWithClientConnectionId) {
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-
-  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
-
-  // clang-format off
-  unsigned char packet[] = {
-      // type (long header)
-      0xC0,
-      // version tag
-      0x00, 0x00, 0x00, 0x00,
-      // client/destination connection ID
-      0x08,
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // server/source connection ID
-      0x08,
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // supported versions
-      0xDA, 0x5A, 0x3A, 0x3A,
-      QUIC_VERSION_BYTES,
-  };
-  // clang-format on
-
-  QuicConnectionId server_connection_id = FramerTestConnectionId();
-  QuicConnectionId client_connection_id = FramerTestConnectionIdPlusOne();
-  std::unique_ptr<QuicEncryptedPacket> data(
-      QuicFramer::BuildVersionNegotiationPacket(
-          server_connection_id, client_connection_id, true, true,
-          SupportedVersions(GetParam())));
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Use kSmallLargestObserved to make this test finished in a short time.
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x2C,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 2 byte largest observed, 2 byte block length)
-      0x45,
-      // largest acked
-      0x12, 0x34,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x12, 0x34,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 2 byte largest observed, 2 byte block length)
-      0x45,
-      // largest acked
-      0x12, 0x34,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x12, 0x34,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (IETF_ACK frame)
-      0x02,
-      // largest acked
-      kVarInt62TwoBytes + 0x12, 0x34,
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // Number of additional ack blocks.
-      kVarInt62OneByte + 0x00,
-      // first ack block length.
-      kVarInt62TwoBytes + 0x12, 0x33,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameMultipleRanges) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      // Timestamp Range 3.
-      {kSmallLargestObserved - 22, CreationTimePlus(0x29ffdddd)},
-      {kSmallLargestObserved - 21, CreationTimePlus(0x29ffdedd)},
-      // Timestamp Range 2.
-      {kSmallLargestObserved - 11, CreationTimePlus(0x29ffdeed)},
-      // Timestamp Range 1.
-      {kSmallLargestObserved - 4, CreationTimePlus(0x29ffeeed)},
-      {kSmallLargestObserved - 3, CreationTimePlus(0x29ffeeee)},
-      {kSmallLargestObserved - 2, CreationTimePlus(0x29ffffff)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE,
-      0xDC,
-      0xBA,
-      0x98,
-      0x76,
-      0x54,
-      0x32,
-      0x10,
-      // packet number
-      0x12,
-      0x34,
-      0x56,
-      0x78,
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      0x22,
-      // largest acked
-      kVarInt62TwoBytes + 0x12,
-      0x34,  // = 4660
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // number of additional ack blocks
-      kVarInt62OneByte + 0x00,
-      // first ack block length.
-      kVarInt62TwoBytes + 0x12,
-      0x33,
-
-      // Receive Timestamps.
-
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x03,
-
-      // Timestamp range 1 (three packets).
-      // Gap
-      kVarInt62OneByte + 0x02,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x03,
-      // Timestamp Delta
-      kVarInt62FourBytes + 0x29,
-      0xff,
-      0xff,
-      0xff,
-      // Timestamp Delta
-      kVarInt62TwoBytes + 0x11,
-      0x11,
-      // Timestamp Delta
-      kVarInt62OneByte + 0x01,
-
-      // Timestamp range 2 (one packet).
-      // Gap
-      kVarInt62OneByte + 0x05,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x01,
-      // Timestamp Delta
-      kVarInt62TwoBytes + 0x10,
-      0x00,
-
-      // Timestamp range 3 (two packets).
-      // Gap
-      kVarInt62OneByte + 0x08,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x02,
-      // Timestamp Delta
-      kVarInt62OneByte + 0x10,
-      // Timestamp Delta
-      kVarInt62TwoBytes + 0x01,
-      0x00,
-  };
-  // clang-format on
-
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameExceedsMaxTimestamps) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      // Timestamp Range 3 (not included because max receive timestamps = 4).
-      {kSmallLargestObserved - 20, CreationTimePlus(0x29ffdddd)},
-      // Timestamp Range 2.
-      {kSmallLargestObserved - 10, CreationTimePlus(0x29ffdedd)},
-      {kSmallLargestObserved - 9, CreationTimePlus(0x29ffdeed)},
-      // Timestamp Range 1.
-      {kSmallLargestObserved - 2, CreationTimePlus(0x29ffeeed)},
-      {kSmallLargestObserved - 1, CreationTimePlus(0x29ffeeee)},
-      {kSmallLargestObserved, CreationTimePlus(0x29ffffff)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE,
-      0xDC,
-      0xBA,
-      0x98,
-      0x76,
-      0x54,
-      0x32,
-      0x10,
-      // packet number
-      0x12,
-      0x34,
-      0x56,
-      0x78,
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      0x22,
-      // largest acked
-      kVarInt62TwoBytes + 0x12,
-      0x34,  // = 4660
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // number of additional ack blocks
-      kVarInt62OneByte + 0x00,
-      // first ack block length.
-      kVarInt62TwoBytes + 0x12,
-      0x33,
-
-      // Receive Timestamps.
-
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x02,
-
-      // Timestamp range 1 (three packets).
-      // Gap
-      kVarInt62OneByte + 0x00,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x03,
-      // Timestamp Delta
-      kVarInt62FourBytes + 0x29,
-      0xff,
-      0xff,
-      0xff,
-      // Timestamp Delta
-      kVarInt62TwoBytes + 0x11,
-      0x11,
-      // Timestamp Delta
-      kVarInt62OneByte + 0x01,
-
-      // Timestamp range 2 (one packet).
-      // Gap
-      kVarInt62OneByte + 0x05,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x01,
-      // Timestamp Delta
-      kVarInt62TwoBytes + 0x10,
-      0x00,
-  };
-  // clang-format on
-
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(4);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameWithExponentEncoding) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      // Timestamp Range 2.
-      {kSmallLargestObserved - 12, CreationTimePlus((0x06c00 << 3) + 0x03)},
-      {kSmallLargestObserved - 11, CreationTimePlus((0x28e00 << 3) + 0x00)},
-      // Timestamp Range 1.
-      {kSmallLargestObserved - 5, CreationTimePlus((0x29f00 << 3) + 0x00)},
-      {kSmallLargestObserved - 4, CreationTimePlus((0x29f00 << 3) + 0x01)},
-      {kSmallLargestObserved - 3, CreationTimePlus((0x29f00 << 3) + 0x02)},
-      {kSmallLargestObserved - 2, CreationTimePlus((0x29f00 << 3) + 0x03)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE,
-      0xDC,
-      0xBA,
-      0x98,
-      0x76,
-      0x54,
-      0x32,
-      0x10,
-      // packet number
-      0x12,
-      0x34,
-      0x56,
-      0x78,
-
-      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
-      0x22,
-      // largest acked
-      kVarInt62TwoBytes + 0x12,
-      0x34,  // = 4660
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // number of additional ack blocks
-      kVarInt62OneByte + 0x00,
-      // first ack block length.
-      kVarInt62TwoBytes + 0x12,
-      0x33,
-
-      // Receive Timestamps.
-
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x02,
-
-      // Timestamp range 1 (three packets).
-      // Gap
-      kVarInt62OneByte + 0x02,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x04,
-      // Timestamp Delta
-      kVarInt62FourBytes + 0x00,
-      0x02,
-      0x9f,
-      0x01,  // round up
-      // Timestamp Delta
-      kVarInt62OneByte + 0x00,
-      // Timestamp Delta
-      kVarInt62OneByte + 0x00,
-      // Timestamp Delta
-      kVarInt62OneByte + 0x01,
-
-      // Timestamp range 2 (one packet).
-      // Gap
-      kVarInt62OneByte + 0x04,
-      // Timestamp Range Count
-      kVarInt62OneByte + 0x02,
-      // Timestamp Delta
-      kVarInt62TwoBytes + 0x11,
-      0x00,
-      // Timestamp Delta
-      kVarInt62FourBytes + 0x00,
-      0x02,
-      0x21,
-      0xff,
-  };
-  // clang-format on
-
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  framer_.set_receive_timestamps_exponent(3);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildAndProcessAckReceiveTimestampsWithMultipleRanges) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
-      {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
-      {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
-      {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
-      {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
-      {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
-      {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
-                  {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
-                  {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
-                  {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
-                  {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
-                  {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
-                  {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
-              }));
-}
-
-TEST_P(QuicFramerTest,
-       BuildAndProcessAckReceiveTimestampsExceedsMaxTimestamps) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(2);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
-      {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
-      {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
-      {kSmallLargestObserved - 5, CreationTimePlus(0xabcdea125)},
-      {kSmallLargestObserved - 3, CreationTimePlus(0xabcded124)},
-      {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
-      {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
-                  {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
-              }));
-}
-
-TEST_P(QuicFramerTest,
-       BuildAndProcessAckReceiveTimestampsWithExponentNoTruncation) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  framer_.set_receive_timestamps_exponent(3);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
-      {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
-      {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
-      {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
-                  {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
-                  {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
-                  {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
-              }));
-}
-
-TEST_P(QuicFramerTest,
-       BuildAndProcessAckReceiveTimestampsWithExponentTruncation) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  framer_.set_receive_timestamps_exponent(3);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      {kSmallLargestObserved - 10, CreationTimePlus((0x1001 << 3) + 1)},
-      {kSmallLargestObserved - 9, CreationTimePlus((0x2995 << 3) - 1)},
-      {kSmallLargestObserved - 8, CreationTimePlus((0x2995 << 3) + 0)},
-      {kSmallLargestObserved - 7, CreationTimePlus((0x2995 << 3) + 1)},
-      {kSmallLargestObserved - 6, CreationTimePlus((0x2995 << 3) + 2)},
-      {kSmallLargestObserved - 3, CreationTimePlus((0x2995 << 3) + 3)},
-      {kSmallLargestObserved - 2, CreationTimePlus((0x2995 << 3) + 4)},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  {kSmallLargestObserved - 2, CreationTimePlus(0x2996 << 3)},
-                  {kSmallLargestObserved - 3, CreationTimePlus(0x2996 << 3)},
-                  {kSmallLargestObserved - 6, CreationTimePlus(0x2996 << 3)},
-                  {kSmallLargestObserved - 7, CreationTimePlus(0x2996 << 3)},
-                  {kSmallLargestObserved - 8, CreationTimePlus(0x2995 << 3)},
-                  {kSmallLargestObserved - 9, CreationTimePlus(0x2995 << 3)},
-                  {kSmallLargestObserved - 10, CreationTimePlus(0x1002 << 3)},
-              }));
-}
-
-TEST_P(QuicFramerTest, AckReceiveTimestamps) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  framer_.set_receive_timestamps_exponent(3);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Use kSmallLargestObserved to make this test finished in a short time.
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  ack_frame.received_packet_times = PacketTimeVector{
-      {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
-      {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
-      {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
-      {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_THAT(frame.received_packet_times,
-              ContainerEq(PacketTimeVector{
-                  {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
-                  {kSmallLargestObserved - 3, CreationTimePlus(0x29ff << 3)},
-                  {kSmallLargestObserved - 4, CreationTimePlus(0x29ff << 3)},
-                  {kSmallLargestObserved - 5, CreationTimePlus(0x29ff << 3)},
-              }));
-}
-
-TEST_P(QuicFramerTest, AckReceiveTimestampsPacketOutOfOrder) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  framer_.set_receive_timestamps_exponent(3);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Use kSmallLargestObserved to make this test finished in a short time.
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-
-  // The packet numbers below are out of order, this is impossible because we
-  // don't record out of order packets in received_packet_times. The test is
-  // intended to ensure this error is raised when it happens.
-  ack_frame.received_packet_times = PacketTimeVector{
-      {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
-      {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
-      {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
-      {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
-  };
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  EXPECT_QUIC_BUG(BuildDataPacket(header, frames),
-                  "Packet number and/or receive time not in order.");
-}
-
-// If there's insufficient room for IETF ack receive timestamps, don't write any
-// timestamp ranges.
-TEST_P(QuicFramerTest, IetfAckReceiveTimestampsTruncate) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8192);
-  framer_.set_receive_timestamps_exponent(3);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Use kSmallLargestObserved to make this test finished in a short time.
-  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
-  for (QuicPacketNumber i(1); i <= kSmallLargestObserved; i += 2) {
-    ack_frame.received_packet_times.push_back(
-        {i, CreationTimePlus((0x29ff << 3))});
-  }
-
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-
-  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
-  EXPECT_TRUE(frame.received_packet_times.empty());
-}
-
-// If there are too many ack ranges, they will be truncated to make room for a
-// timestamp range count of 0.
-TEST_P(QuicFramerTest, IetfAckReceiveTimestampsAckRangeTruncation) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  framer_.set_process_timestamps(true);
-  framer_.set_max_receive_timestamps_per_ack(8);
-  framer_.set_receive_timestamps_exponent(3);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame;
-  // Create a packet with just the ack.
-  ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
-                                   /*max_num_gaps=*/200,
-                                   /*largest_acked=*/kMaxIetfVarInt);
-  ack_frame.received_packet_times = PacketTimeVector{
-      {QuicPacketNumber(kMaxIetfVarInt) - 2, CreationTimePlus((0x29ff << 3))},
-  };
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-  // Build an ACK packet.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
-                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
-  ASSERT_NE(0u, encrypted_length);
-  // Now make sure we can turn our ack packet back into an ack frame.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  ASSERT_TRUE(framer_.ProcessPacket(
-      QuicEncryptedPacket(buffer, encrypted_length, false)));
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
-            LargestAcked(processed_ack_frame));
-  // Verify ACK ranges in the frame gets truncated.
-  ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
-            ack_frame.packets.NumIntervals());
-  EXPECT_EQ(158u, processed_ack_frame.packets.NumPacketsSlow());
-  EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
-            ack_frame.packets.NumIntervals());
-  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
-            processed_ack_frame.packets.Max());
-  // But the receive timestamps are not truncated because they are small.
-  EXPECT_FALSE(processed_ack_frame.received_packet_times.empty());
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(kPacketNumber);
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x2C,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 4 byte largest observed, 4 byte block length)
-      0x4A,
-      // largest acked
-      0x12, 0x34, 0x56, 0x78,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x12, 0x34, 0x56, 0x78,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (no ack blocks, 4 byte largest observed, 4 byte block length)
-      0x4A,
-      // largest acked
-      0x12, 0x34, 0x56, 0x78,
-      // Zero delta time.
-      0x00, 0x00,
-      // first ack block length.
-      0x12, 0x34, 0x56, 0x78,
-      // num timestamps.
-      0x00,
-  };
-
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (IETF_ACK frame)
-      0x02,
-      // largest acked
-      kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // Nr. of additional ack blocks
-      kVarInt62OneByte + 0x00,
-      // first ack block length.
-      kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Use kSmallLargestObserved to make this test finished in a short time.
-  QuicAckFrame ack_frame =
-      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
-                    {QuicPacketNumber(10), QuicPacketNumber(500)},
-                    {QuicPacketNumber(900), kSmallMissingPacket},
-                    {kSmallMissingPacket + 1, kSmallLargestObserved + 1}});
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x2C,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (has ack blocks, 2 byte largest observed, 2 byte block length)
-      0x65,
-      // largest acked
-      0x12, 0x34,
-      // Zero delta time.
-      0x00, 0x00,
-      // num ack blocks ranges.
-      0x04,
-      // first ack block length.
-      0x00, 0x01,
-      // gap to next block.
-      0x01,
-      // ack block length.
-      0x0e, 0xaf,
-      // gap to next block.
-      0xff,
-      // ack block length.
-      0x00, 0x00,
-      // gap to next block.
-      0x91,
-      // ack block length.
-      0x01, 0xea,
-      // gap to next block.
-      0x05,
-      // ack block length.
-      0x00, 0x04,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (ack frame)
-      // (has ack blocks, 2 byte largest observed, 2 byte block length)
-      0x65,
-      // largest acked
-      0x12, 0x34,
-      // Zero delta time.
-      0x00, 0x00,
-      // num ack blocks ranges.
-      0x04,
-      // first ack block length.
-      0x00, 0x01,
-      // gap to next block.
-      0x01,
-      // ack block length.
-      0x0e, 0xaf,
-      // gap to next block.
-      0xff,
-      // ack block length.
-      0x00, 0x00,
-      // gap to next block.
-      0x91,
-      // ack block length.
-      0x01, 0xea,
-      // gap to next block.
-      0x05,
-      // ack block length.
-      0x00, 0x04,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-
-      // frame type (IETF_ACK frame)
-      0x02,
-      // largest acked
-      kVarInt62TwoBytes + 0x12, 0x34,
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // num additional ack blocks.
-      kVarInt62OneByte + 0x03,
-      // first ack block length.
-      kVarInt62OneByte + 0x00,
-
-      // gap to next block.
-      kVarInt62OneByte + 0x00,
-      // ack block length.
-      kVarInt62TwoBytes + 0x0e, 0xae,
-
-      // gap to next block.
-      kVarInt62TwoBytes + 0x01, 0x8f,
-      // ack block length.
-      kVarInt62TwoBytes + 0x01, 0xe9,
-
-      // gap to next block.
-      kVarInt62OneByte + 0x04,
-      // ack block length.
-      kVarInt62OneByte + 0x03,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Use kSmallLargestObservedto make this test finished in a short time.
-  QuicAckFrame ack_frame;
-  ack_frame.largest_acked = kSmallLargestObserved;
-  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
-  // 300 ack blocks.
-  for (size_t i = 2; i < 2 * 300; i += 2) {
-    ack_frame.packets.Add(QuicPacketNumber(i));
-  }
-  ack_frame.packets.AddRange(QuicPacketNumber(600), kSmallLargestObserved + 1);
-
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (8 byte connection_id)
-      0x2C,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (ack frame)
-      // (has ack blocks, 2 byte largest observed, 2 byte block length)
-      0x65,
-      // largest acked
-      0x12, 0x34,
-      // Zero delta time.
-      0x00, 0x00,
-      // num ack blocks ranges.
-      0xff,
-      // first ack block length.
-      0x0f, 0xdd,
-      // 255 = 4 * 63 + 3
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet46[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (ack frame)
-      // (has ack blocks, 2 byte largest observed, 2 byte block length)
-      0x65,
-      // largest acked
-      0x12, 0x34,
-      // Zero delta time.
-      0x00, 0x00,
-      // num ack blocks ranges.
-      0xff,
-      // first ack block length.
-      0x0f, 0xdd,
-      // 255 = 4 * 63 + 3
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
-      // num timestamps.
-      0x00,
-  };
-
-  unsigned char packet_ietf[] = {
-      // type (short header, 4 byte packet number)
-      0x43,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_ACK frame)
-      0x02,
-      // largest acked
-      kVarInt62TwoBytes + 0x12, 0x34,
-      // Zero delta time.
-      kVarInt62OneByte + 0x00,
-      // num ack blocks ranges.
-      kVarInt62TwoBytes + 0x01, 0x2b,
-      // first ack block length.
-      kVarInt62TwoBytes + 0x0f, 0xdc,
-      // 255 added blocks of gap_size == 1, ack_size == 1
-#define V99AddedBLOCK kVarInt62OneByte + 0x00, kVarInt62OneByte + 0x00
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
-
-#undef V99AddedBLOCK
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicStopWaitingFrame stop_waiting_frame;
-  stop_waiting_frame.least_unacked = kLeastUnacked;
-
-  QuicFrames frames = {QuicFrame(stop_waiting_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (stop waiting frame)
-    0x06,
-    // least packet number awaiting an ack, delta from packet number.
-    0x00, 0x00, 0x00, 0x08,
-  };
-
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicRstStreamFrame rst_frame;
-  rst_frame.stream_id = kStreamId;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    rst_frame.ietf_error_code = 0x01;
-  } else {
-    rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
-  }
-  rst_frame.byte_offset = 0x0807060504030201;
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (rst stream frame)
-    0x01,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // sent byte offset
-    0x08, 0x07, 0x06, 0x05,
-    0x04, 0x03, 0x02, 0x01,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-  };
-
-  unsigned char packet46[] = {
-    // type (short packet, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (rst stream frame)
-    0x01,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // sent byte offset
-    0x08, 0x07, 0x06, 0x05,
-    0x04, 0x03, 0x02, 0x01,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short packet, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_RST_STREAM frame)
-    0x04,
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // error code
-    kVarInt62OneByte + 0x01,
-    // sent byte offset
-    kVarInt62EightBytes + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
-  };
-  // clang-format on
-
-  QuicFrames frames = {QuicFrame(&rst_frame)};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildCloseFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicConnectionCloseFrame close_frame(framer_.transport_version(),
-                                       QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
-                                       "because I can", 0x05);
-  QuicFrames frames = {QuicFrame(&close_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (connection close frame)
-    0x02,
-    // error code
-    0x00, 0x00, 0x00, 0x01,
-    // error details length
-    0x00, 0x0d,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (connection close frame)
-    0x02,
-    // error code
-    0x00, 0x00, 0x00, 0x01,
-    // error details length
-    0x00, 0x0d,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_CONNECTION_CLOSE frame)
-    0x1c,
-    // error code
-    kVarInt62OneByte + 0x01,
-    // Frame type within the CONNECTION_CLOSE frame
-    kVarInt62OneByte + 0x05,
-    // error details length
-    kVarInt62OneByte + 0x0f,
-    // error details
-    '1',  ':',  'b',  'e',
-    'c',  'a',  'u',  's',
-    'e',  ' ',  'I',  ' ',
-    'c',  'a',  'n',
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildCloseFramePacketExtendedInfo) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicConnectionCloseFrame close_frame(
-      framer_.transport_version(),
-      static_cast<QuicErrorCode>(
-          VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x01
-                                                                : 0x05060708),
-      NO_IETF_QUIC_ERROR, "because I can", 0x05);
-  // Set this so that it is "there" for both Google QUIC and IETF QUIC
-  // framing. It better not show up for Google QUIC!
-  close_frame.quic_error_code = static_cast<QuicErrorCode>(0x4567);
-
-  QuicFrames frames = {QuicFrame(&close_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (connection close frame)
-    0x02,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-    // error details length
-    0x00, 0x0d,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (connection close frame)
-    0x02,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-    // error details length
-    0x00, 0x0d,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_CONNECTION_CLOSE frame)
-    0x1c,
-    // IETF error code INTERNAL_ERROR = 0x01 corresponding to
-    // QuicErrorCode::QUIC_INTERNAL_ERROR = 0x01.
-    kVarInt62OneByte + 0x01,
-    // Frame type within the CONNECTION_CLOSE frame
-    kVarInt62OneByte + 0x05,
-    // error details length
-    kVarInt62OneByte + 0x13,
-    // error details
-    '1',  '7',  '7',  '6',
-    '7',  ':',  'b',  'e',
-    'c',  'a',  'u',  's',
-    'e',  ' ',  'I',  ' ',
-    'c',  'a',  'n'
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicConnectionCloseFrame close_frame(framer_.transport_version(),
-                                       QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
-                                       std::string(2048, 'A'), 0x05);
-  QuicFrames frames = {QuicFrame(&close_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (connection close frame)
-    0x02,
-    // error code
-    0x00, 0x00, 0x00, 0x01,
-    // error details length
-    0x01, 0x00,
-    // error details (truncated to 256 bytes)
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (connection close frame)
-    0x02,
-    // error code
-    0x00, 0x00, 0x00, 0x01,
-    // error details length
-    0x01, 0x00,
-    // error details (truncated to 256 bytes)
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_CONNECTION_CLOSE frame)
-    0x1c,
-    // error code
-    kVarInt62OneByte + 0x01,
-    // Frame type within the CONNECTION_CLOSE frame
-    kVarInt62OneByte + 0x05,
-    // error details length
-    kVarInt62TwoBytes + 0x01, 0x00,
-    // error details (truncated to 256 bytes)
-    '1',  ':',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildApplicationCloseFramePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicConnectionCloseFrame app_close_frame;
-  app_close_frame.wire_error_code = 0x11;
-  app_close_frame.error_details = "because I can";
-  app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
-
-  QuicFrames frames = {QuicFrame(&app_close_frame)};
-
-  // clang-format off
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_APPLICATION_CLOSE frame)
-    0x1d,
-    // error code
-    kVarInt62OneByte + 0x11,
-    // error details length
-    kVarInt62OneByte + 0x0f,
-    // error details, note that it includes an extended error code.
-    '0',  ':',  'b',  'e',
-    'c',  'a',  'u',  's',
-    'e',  ' ',  'I',  ' ',
-    'c',  'a',  'n',
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildTruncatedApplicationCloseFramePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicConnectionCloseFrame app_close_frame;
-  app_close_frame.wire_error_code = 0x11;
-  app_close_frame.error_details = std::string(2048, 'A');
-  app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
-  // Setting to missing ensures that if it is missing, the extended
-  // code is not added to the text message.
-  app_close_frame.quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
-
-  QuicFrames frames = {QuicFrame(&app_close_frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_APPLICATION_CLOSE frame)
-    0x1d,
-    // error code
-    kVarInt62OneByte + 0x11,
-    // error details length
-    kVarInt62TwoBytes + 0x01, 0x00,
-    // error details (truncated to 256 bytes)
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildGoAwayPacket) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for Google QUIC.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicGoAwayFrame goaway_frame;
-  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
-  goaway_frame.last_good_stream_id = kStreamId;
-  goaway_frame.reason_phrase = "because I can";
-
-  QuicFrames frames = {QuicFrame(&goaway_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (go away frame)
-    0x03,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // error details length
-    0x00, 0x0d,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (go away frame)
-    0x03,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // error details length
-    0x00, 0x0d,
-    // error details
-    'b',  'e',  'c',  'a',
-    'u',  's',  'e',  ' ',
-    'I',  ' ',  'c',  'a',
-    'n',
-  };
-
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for Google QUIC.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicGoAwayFrame goaway_frame;
-  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
-  goaway_frame.last_good_stream_id = kStreamId;
-  goaway_frame.reason_phrase = std::string(2048, 'A');
-
-  QuicFrames frames = {QuicFrame(&goaway_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (go away frame)
-    0x03,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // error details length
-    0x01, 0x00,
-    // error details (truncated to 256 bytes)
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (go away frame)
-    0x03,
-    // error code
-    0x05, 0x06, 0x07, 0x08,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // error details length
-    0x01, 0x00,
-    // error details (truncated to 256 bytes)
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicWindowUpdateFrame window_update_frame;
-  window_update_frame.stream_id = kStreamId;
-  window_update_frame.max_data = 0x1122334455667788;
-
-  QuicFrames frames = {QuicFrame(window_update_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (window update frame)
-    0x04,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // byte offset
-    0x11, 0x22, 0x33, 0x44,
-    0x55, 0x66, 0x77, 0x88,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (window update frame)
-    0x04,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // byte offset
-    0x11, 0x22, 0x33, 0x44,
-    0x55, 0x66, 0x77, 0x88,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_MAX_STREAM_DATA frame)
-    0x11,
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // byte offset
-    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
-    0x55, 0x66, 0x77, 0x88,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildMaxStreamDataPacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicWindowUpdateFrame window_update_frame;
-  window_update_frame.stream_id = kStreamId;
-  window_update_frame.max_data = 0x1122334455667788;
-
-  QuicFrames frames = {QuicFrame(window_update_frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_MAX_STREAM_DATA frame)
-    0x11,
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // byte offset
-    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
-    0x55, 0x66, 0x77, 0x88,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildMaxDataPacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicWindowUpdateFrame window_update_frame;
-  window_update_frame.stream_id =
-      QuicUtils::GetInvalidStreamId(framer_.transport_version());
-  window_update_frame.max_data = 0x1122334455667788;
-
-  QuicFrames frames = {QuicFrame(window_update_frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_MAX_DATA frame)
-    0x10,
-    // byte offset
-    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
-    0x55, 0x66, 0x77, 0x88,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildBlockedPacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicBlockedFrame blocked_frame;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // For IETF QUIC, the stream ID must be <invalid> for the frame
-    // to be a BLOCKED frame. if it's valid, it will be a
-    // STREAM_BLOCKED frame.
-    blocked_frame.stream_id =
-        QuicUtils::GetInvalidStreamId(framer_.transport_version());
-  } else {
-    blocked_frame.stream_id = kStreamId;
-  }
-  blocked_frame.offset = kStreamOffset;
-
-  QuicFrames frames = {QuicFrame(blocked_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (blocked frame)
-    0x05,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-  };
-
-  unsigned char packet46[] = {
-    // type (short packet, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (blocked frame)
-    0x05,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short packet, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_DATA_BLOCKED frame)
-    0x14,
-    // Offset
-    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
-}
-
-TEST_P(QuicFramerTest, BuildPingPacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPingFrame())};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ping frame)
-    0x07,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type
-    0x07,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_PING frame)
-    0x01,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildHandshakeDonePacket) {
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicHandshakeDoneFrame())};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (Handshake done frame)
-    0x1e,
-  };
-  // clang-format on
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildAckFrequencyPacket) {
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrequencyFrame ack_frequency_frame;
-  ack_frequency_frame.sequence_number = 3;
-  ack_frequency_frame.packet_tolerance = 5;
-  ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMicroseconds(0x3fff);
-  ack_frequency_frame.ignore_order = false;
-  QuicFrames frames = {QuicFrame(&ack_frequency_frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (Ack Frequency frame)
-    0x40, 0xaf,
-    // sequence number
-    0x03,
-    // packet tolerance
-    0x05,
-    // max_ack_delay_us
-    0x7f, 0xff,
-    // ignore_oder
-    0x00
-  };
-  // clang-format on
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildMessagePacket) {
-  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicMessageFrame frame(1, MemSliceFromString("message"));
-  QuicMessageFrame frame2(2, MemSliceFromString("message2"));
-  QuicFrames frames = {QuicFrame(&frame), QuicFrame(&frame2)};
-
-  // clang-format off
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (message frame)
-    0x21,
-    // Length
-    0x07,
-    // Message Data
-    'm', 'e', 's', 's', 'a', 'g', 'e',
-    // frame type (message frame no length)
-    0x20,
-    // Message Data
-    'm', 'e', 's', 's', 'a', 'g', 'e', '2'
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_MESSAGE frame)
-    0x31,
-    // Length
-    0x07,
-    // Message Data
-    'm', 'e', 's', 's', 'a', 'g', 'e',
-    // frame type (message frame no length)
-    0x30,
-    // Message Data
-    'm', 'e', 's', 's', 'a', 'g', 'e', '2'
-  };
-  // clang-format on
-
-  unsigned char* p = packet46;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  }
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      ABSL_ARRAYSIZE(packet46));
-}
-
-// Test that the MTU discovery packet is serialized correctly as a PING packet.
-TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicMtuDiscoveryFrame())};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ping frame)
-    0x07,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type
-    0x07,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_PING frame)
-    0x01,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  unsigned char* p = packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(p),
-      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
-                                                 : ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildPublicResetPacket) {
-  QuicPublicResetPacket reset_packet;
-  reset_packet.connection_id = FramerTestConnectionId();
-  reset_packet.nonce_proof = kNonceProof;
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (public reset, 8 byte ConnectionId)
-    0x0E,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // message tag (kPRST)
-    'P', 'R', 'S', 'T',
-    // num_entries (1) + padding
-    0x01, 0x00, 0x00, 0x00,
-    // tag kRNON
-    'R', 'N', 'O', 'N',
-    // end offset 8
-    0x08, 0x00, 0x00, 0x00,
-    // nonce proof
-    0x89, 0x67, 0x45, 0x23,
-    0x01, 0xEF, 0xCD, 0xAB,
-  };
-  // clang-format on
-
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  std::unique_ptr<QuicEncryptedPacket> data(
-      framer_.BuildPublicResetPacket(reset_packet));
-  ASSERT_TRUE(data != nullptr);
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
-  QuicPublicResetPacket reset_packet;
-  reset_packet.connection_id = FramerTestConnectionId();
-  reset_packet.nonce_proof = kNonceProof;
-  reset_packet.client_address =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), 0x1234);
-
-  // clang-format off
-  unsigned char packet[] = {
-      // public flags (public reset, 8 byte ConnectionId)
-      0x0E,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98,
-      0x76, 0x54, 0x32, 0x10,
-      // message tag (kPRST)
-      'P', 'R', 'S', 'T',
-      // num_entries (2) + padding
-      0x02, 0x00, 0x00, 0x00,
-      // tag kRNON
-      'R', 'N', 'O', 'N',
-      // end offset 8
-      0x08, 0x00, 0x00, 0x00,
-      // tag kCADR
-      'C', 'A', 'D', 'R',
-      // end offset 16
-      0x10, 0x00, 0x00, 0x00,
-      // nonce proof
-      0x89, 0x67, 0x45, 0x23,
-      0x01, 0xEF, 0xCD, 0xAB,
-      // client address
-      0x02, 0x00,
-      0x7F, 0x00, 0x00, 0x01,
-      0x34, 0x12,
-  };
-  // clang-format on
-
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  std::unique_ptr<QuicEncryptedPacket> data(
-      framer_.BuildPublicResetPacket(reset_packet));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, BuildPublicResetPacketWithEndpointId) {
-  QuicPublicResetPacket reset_packet;
-  reset_packet.connection_id = FramerTestConnectionId();
-  reset_packet.nonce_proof = kNonceProof;
-  reset_packet.endpoint_id = "FakeServerId";
-
-  // The tag value map in CryptoHandshakeMessage is a std::map, so the two tags
-  // in the packet, kRNON and kEPID, have unspecified ordering w.r.t each other.
-  // clang-format off
-  unsigned char packet_variant1[] = {
-      // public flags (public reset, 8 byte ConnectionId)
-      0x0E,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98,
-      0x76, 0x54, 0x32, 0x10,
-      // message tag (kPRST)
-      'P', 'R', 'S', 'T',
-      // num_entries (2) + padding
-      0x02, 0x00, 0x00, 0x00,
-      // tag kRNON
-      'R', 'N', 'O', 'N',
-      // end offset 8
-      0x08, 0x00, 0x00, 0x00,
-      // tag kEPID
-      'E', 'P', 'I', 'D',
-      // end offset 20
-      0x14, 0x00, 0x00, 0x00,
-      // nonce proof
-      0x89, 0x67, 0x45, 0x23,
-      0x01, 0xEF, 0xCD, 0xAB,
-      // Endpoint ID
-      'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
-  };
-  unsigned char packet_variant2[] = {
-      // public flags (public reset, 8 byte ConnectionId)
-      0x0E,
-      // connection_id
-      0xFE, 0xDC, 0xBA, 0x98,
-      0x76, 0x54, 0x32, 0x10,
-      // message tag (kPRST)
-      'P', 'R', 'S', 'T',
-      // num_entries (2) + padding
-      0x02, 0x00, 0x00, 0x00,
-      // tag kEPID
-      'E', 'P', 'I', 'D',
-      // end offset 12
-      0x0C, 0x00, 0x00, 0x00,
-      // tag kRNON
-      'R', 'N', 'O', 'N',
-      // end offset 20
-      0x14, 0x00, 0x00, 0x00,
-      // Endpoint ID
-      'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
-      // nonce proof
-      0x89, 0x67, 0x45, 0x23,
-      0x01, 0xEF, 0xCD, 0xAB,
-  };
-  // clang-format on
-
-  if (framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-
-  std::unique_ptr<QuicEncryptedPacket> data(
-      framer_.BuildPublicResetPacket(reset_packet));
-  ASSERT_TRUE(data != nullptr);
-
-  // Variant 1 ends with char 'd'. Variant 1 ends with char 0xAB.
-  if ('d' == data->data()[data->length() - 1]) {
-    quiche::test::CompareCharArraysWithHexError(
-        "constructed packet", data->data(), data->length(),
-        AsChars(packet_variant1), ABSL_ARRAYSIZE(packet_variant1));
-  } else {
-    quiche::test::CompareCharArraysWithHexError(
-        "constructed packet", data->data(), data->length(),
-        AsChars(packet_variant2), ABSL_ARRAYSIZE(packet_variant2));
-  }
-}
-
-TEST_P(QuicFramerTest, BuildIetfStatelessResetPacket) {
-  // clang-format off
-    unsigned char packet[] = {
-      // 1st byte 01XX XXXX
-      0x40,
-      // At least 4 bytes of random bytes.
-      0x00, 0x00, 0x00, 0x00,
-      // stateless reset token
-      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f
-    };
-  // clang-format on
-
-  // Build the minimal stateless reset packet.
-  std::unique_ptr<QuicEncryptedPacket> data(
-      framer_.BuildIetfStatelessResetPacket(
-          FramerTestConnectionId(),
-          QuicFramer::GetMinStatelessResetPacketLength() + 1,
-          kTestStatelessResetToken));
-  ASSERT_TRUE(data);
-  EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength(), data->length());
-  // Verify the first 2 bits are 01.
-  EXPECT_FALSE(data->data()[0] & FLAGS_LONG_HEADER);
-  EXPECT_TRUE(data->data()[0] & FLAGS_FIXED_BIT);
-  // Verify stateless reset token.
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet",
-      data->data() + data->length() - kStatelessResetTokenLength,
-      kStatelessResetTokenLength,
-      AsChars(packet) + ABSL_ARRAYSIZE(packet) - kStatelessResetTokenLength,
-      kStatelessResetTokenLength);
-
-  // Packets with length <= minimal stateless reset does not trigger stateless
-  // reset.
-  std::unique_ptr<QuicEncryptedPacket> data2(
-      framer_.BuildIetfStatelessResetPacket(
-          FramerTestConnectionId(),
-          QuicFramer::GetMinStatelessResetPacketLength(),
-          kTestStatelessResetToken));
-  ASSERT_FALSE(data2);
-
-  // Do not send stateless reset >= minimal stateless reset + 1 + max
-  // connection ID length.
-  std::unique_ptr<QuicEncryptedPacket> data3(
-      framer_.BuildIetfStatelessResetPacket(FramerTestConnectionId(), 1000,
-                                            kTestStatelessResetToken));
-  ASSERT_TRUE(data3);
-  EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength() + 1 +
-                kQuicMaxConnectionIdWithLengthPrefixLength,
-            data3->length());
-}
-
-TEST_P(QuicFramerTest, EncryptPacket) {
-  QuicPacketNumber packet_number = kPacketNumber;
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // redundancy
-    'a',  'b',  'c',  'd',
-    'e',  'f',  'g',  'h',
-    'i',  'j',  'k',  'l',
-    'm',  'n',  'o',  'p',
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // redundancy
-    'a',  'b',  'c',  'd',
-    'e',  'f',  'g',  'h',
-    'i',  'j',  'k',  'l',
-    'm',  'n',  'o',  'p',
-  };
-
-  unsigned char packet50[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // redundancy
-    'a',  'b',  'c',  'd',
-    'e',  'f',  'g',  'h',
-    'i',  'j',  'k',  'l',
-    'm',  'n',  'o',  'p',
-    'q',  'r',  's',  't',
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasHeaderProtection()) {
-    p = packet50;
-    p_size = ABSL_ARRAYSIZE(packet50);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  std::unique_ptr<QuicPacket> raw(new QuicPacket(
-      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = framer_.EncryptPayload(
-      ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
-
-  ASSERT_NE(0u, encrypted_length);
-  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
-}
-
-// Regression test for b/158014497.
-TEST_P(QuicFramerTest, EncryptEmptyPacket) {
-  auto packet = std::make_unique<QuicPacket>(
-      new char[100], 0, true, PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID,
-      /*includes_version=*/true,
-      /*includes_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0,
-      /*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = 1;
-  EXPECT_QUIC_BUG(encrypted_length = framer_.EncryptPayload(
-                      ENCRYPTION_INITIAL, kPacketNumber, *packet, buffer,
-                      kMaxOutgoingPacketSize),
-                  "packet is shorter than associated data length");
-  EXPECT_EQ(0u, encrypted_length);
-}
-
-TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketNumber packet_number = kPacketNumber;
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (version, 8 byte connection_id)
-    0x29,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // version tag
-    'Q', '.', '1', '0',
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // redundancy
-    'a',  'b',  'c',  'd',
-    'e',  'f',  'g',  'h',
-    'i',  'j',  'k',  'l',
-    'm',  'n',  'o',  'p',
-  };
-
-  unsigned char packet46[] = {
-    // type (long header with packet type ZERO_RTT_PROTECTED)
-    0xD3,
-    // version tag
-    'Q', '.', '1', '0',
-    // connection_id length
-    0x50,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // redundancy
-    'a',  'b',  'c',  'd',
-    'e',  'f',  'g',  'h',
-    'i',  'j',  'k',  'l',
-    'm',  'n',  'o',  'p',
-  };
-
-  unsigned char packet50[] = {
-    // type (long header with packet type ZERO_RTT_PROTECTED)
-    0xD3,
-    // version tag
-    'Q', '.', '1', '0',
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length
-    0x00,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // redundancy
-    'a',  'b',  'c',  'd',
-    'e',  'f',  'g',  'h',
-    'i',  'j',  'k',  'l',
-    'm',  'n',  'o',  'p',
-    'q',  'r',  's',  't',
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  // TODO(ianswett): see todo in previous test.
-  if (framer_.version().HasHeaderProtection()) {
-    p = packet50;
-    p_size = ABSL_ARRAYSIZE(packet50);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<QuicPacket> raw(new QuicPacket(
-      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length = framer_.EncryptPayload(
-      ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
-
-  ASSERT_NE(0u, encrypted_length);
-  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
-}
-
-TEST_P(QuicFramerTest, AckTruncationLargePacket) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This test is not applicable to this version; the range count is
-    // effectively unlimited
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame;
-  // Create a packet with just the ack.
-  ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  // Build an ack packet with truncation due to limit in number of nack ranges.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
-                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
-  ASSERT_NE(0u, encrypted_length);
-  // Now make sure we can turn our ack packet back into an ack frame.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  ASSERT_TRUE(framer_.ProcessPacket(
-      QuicEncryptedPacket(buffer, encrypted_length, false)));
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
-  ASSERT_EQ(256u, processed_ack_frame.packets.NumPacketsSlow());
-  EXPECT_EQ(QuicPacketNumber(90u), processed_ack_frame.packets.Min());
-  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
-}
-
-// Regression test for b/150386368.
-TEST_P(QuicFramerTest, IetfAckFrameTruncation) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame;
-  // Create a packet with just the ack.
-  ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
-                                   /*max_num_gaps=*/200,
-                                   /*largest_acked=*/kMaxIetfVarInt);
-  ack_frame.ecn_counters_populated = true;
-  ack_frame.ect_0_count = 100;
-  ack_frame.ect_1_count = 10000;
-  ack_frame.ecn_ce_count = 1000000;
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-  // Build an ACK packet.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
-                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
-  ASSERT_NE(0u, encrypted_length);
-  // Now make sure we can turn our ack packet back into an ack frame.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  ASSERT_TRUE(framer_.ProcessPacket(
-      QuicEncryptedPacket(buffer, encrypted_length, false)));
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
-            LargestAcked(processed_ack_frame));
-  // Verify ACK frame gets truncated.
-  ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
-            ack_frame.packets.NumIntervals());
-  EXPECT_EQ(157u, processed_ack_frame.packets.NumPacketsSlow());
-  EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
-            ack_frame.packets.NumIntervals());
-  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
-            processed_ack_frame.packets.Max());
-}
-
-TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This test is not applicable to this version; the range count is
-    // effectively unlimited
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // Create a packet with just the ack.
-  QuicAckFrame ack_frame;
-  ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-
-  // Build an ack packet with truncation due to limit in number of nack ranges.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> raw_ack_packet(
-      BuildDataPacket(header, frames, 500));
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
-                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
-  ASSERT_NE(0u, encrypted_length);
-  // Now make sure we can turn our ack packet back into an ack frame.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  ASSERT_TRUE(framer_.ProcessPacket(
-      QuicEncryptedPacket(buffer, encrypted_length, false)));
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
-  ASSERT_EQ(240u, processed_ack_frame.packets.NumPacketsSlow());
-  EXPECT_EQ(QuicPacketNumber(122u), processed_ack_frame.packets.Min());
-  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
-}
-
-TEST_P(QuicFramerTest, CleanTruncation) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This test is not applicable to this version; the range count is
-    // effectively unlimited
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicAckFrame ack_frame = InitAckFrame(201);
-
-  // Create a packet with just the ack.
-  QuicFrames frames = {QuicFrame(&ack_frame)};
-  if (framer_.version().HasHeaderProtection()) {
-    frames.push_back(QuicFrame(QuicPaddingFrame(12)));
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-
-  char buffer[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
-                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
-  ASSERT_NE(0u, encrypted_length);
-
-  // Now make sure we can turn our ack packet back into an ack frame.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  ASSERT_TRUE(framer_.ProcessPacket(
-      QuicEncryptedPacket(buffer, encrypted_length, false)));
-
-  // Test for clean truncation of the ack by comparing the length of the
-  // original packets to the re-serialized packets.
-  frames.clear();
-  frames.push_back(QuicFrame(visitor_.ack_frames_[0].get()));
-  if (framer_.version().HasHeaderProtection()) {
-    frames.push_back(QuicFrame(*visitor_.padding_frames_[0].get()));
-  }
-
-  size_t original_raw_length = raw_ack_packet->length();
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  raw_ack_packet = BuildDataPacket(header, frames);
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-  EXPECT_EQ(original_raw_length, raw_ack_packet->length());
-  ASSERT_TRUE(raw_ack_packet != nullptr);
-}
-
-TEST_P(QuicFramerTest, StopPacketProcessing) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (stream frame with fin)
-    0xFF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-
-    // frame type (ack frame)
-    0x40,
-    // least packet number awaiting an ack
-    0x12, 0x34, 0x56, 0x78,
-    0x9A, 0xA0,
-    // largest observed packet number
-    0x12, 0x34, 0x56, 0x78,
-    0x9A, 0xBF,
-    // num missing packets
-    0x01,
-    // missing packet
-    0x12, 0x34, 0x56, 0x78,
-    0x9A, 0xBE,
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (stream frame with fin)
-    0xFF,
-    // stream id
-    0x01, 0x02, 0x03, 0x04,
-    // offset
-    0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-
-    // frame type (ack frame)
-    0x40,
-    // least packet number awaiting an ack
-    0x12, 0x34, 0x56, 0x78,
-    0x9A, 0xA0,
-    // largest observed packet number
-    0x12, 0x34, 0x56, 0x78,
-    0x9A, 0xBF,
-    // num missing packets
-    0x01,
-    // missing packet
-    0x12, 0x34, 0x56, 0x78,
-    0x9A, 0xBE,
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_STREAM frame with fin, length, and offset bits set)
-    0x08 | 0x01 | 0x02 | 0x04,
-    // stream id
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // offset
-    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-    0x32, 0x10, 0x76, 0x54,
-    // data length
-    kVarInt62TwoBytes + 0x00, 0x0c,
-    // data
-    'h',  'e',  'l',  'l',
-    'o',  ' ',  'w',  'o',
-    'r',  'l',  'd',  '!',
-
-    // frame type (ack frame)
-    0x0d,
-    // largest observed packet number
-    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
-    // Delta time
-    kVarInt62OneByte + 0x00,
-    // Ack Block count
-    kVarInt62OneByte + 0x01,
-    // First block size (one packet)
-    kVarInt62OneByte + 0x00,
-
-    // Next gap size & ack. Missing all preceding packets
-    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
-    kVarInt62OneByte + 0x00,
-  };
-  // clang-format on
-
-  MockFramerVisitor visitor;
-  framer_.set_visitor(&visitor);
-  EXPECT_CALL(visitor, OnPacket());
-  EXPECT_CALL(visitor, OnPacketHeader(_));
-  EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false));
-  EXPECT_CALL(visitor, OnPacketComplete());
-  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)).WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnDecryptedPacket(_, _));
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-}
-
-static char kTestString[] = "At least 20 characters.";
-static QuicStreamId kTestQuicStreamId = 1;
-
-MATCHER_P(ExpectedStreamFrame, version, "") {
-  return (arg.stream_id == kTestQuicStreamId ||
-          QuicUtils::IsCryptoStreamId(version.transport_version,
-                                      arg.stream_id)) &&
-         !arg.fin && arg.offset == 0 &&
-         std::string(arg.data_buffer, arg.data_length) == kTestString;
-  // FIN is hard-coded false in ConstructEncryptedPacket.
-  // Offset 0 is hard-coded in ConstructEncryptedPacket.
-}
-
-// Verify that the packet returned by ConstructEncryptedPacket() can be properly
-// parsed by the framer.
-TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
-  // Since we are using ConstructEncryptedPacket, we have to set the framer's
-  // crypto to be Null.
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullDecrypter>(framer_.perspective()));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
-                                                 framer_.perspective()));
-  }
-  ParsedQuicVersionVector versions;
-  versions.push_back(framer_.version());
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      TestConnectionId(), EmptyQuicConnectionId(), false, false,
-      kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
-      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &versions));
-
-  MockFramerVisitor visitor;
-  framer_.set_visitor(&visitor);
-  EXPECT_CALL(visitor, OnPacket()).Times(1);
-  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
-      .Times(1)
-      .WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
-      .Times(1)
-      .WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1).WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
-  EXPECT_CALL(visitor, OnError(_)).Times(0);
-  EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
-  if (!QuicVersionUsesCryptoFrames(framer_.version().transport_version)) {
-    EXPECT_CALL(visitor, OnStreamFrame(ExpectedStreamFrame(framer_.version())))
-        .Times(1);
-  } else {
-    EXPECT_CALL(visitor, OnCryptoFrame(_)).Times(1);
-  }
-  EXPECT_CALL(visitor, OnPacketComplete()).Times(1);
-
-  EXPECT_TRUE(framer_.ProcessPacket(*packet));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-}
-
-// Verify that the packet returned by ConstructMisFramedEncryptedPacket()
-// does cause the framer to return an error.
-TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
-  // Since we are using ConstructEncryptedPacket, we have to set the framer's
-  // crypto to be Null.
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullDecrypter>(framer_.perspective()));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
-                                                 framer_.perspective()));
-  }
-  framer_.SetEncrypter(ENCRYPTION_INITIAL,
-                       std::make_unique<NullEncrypter>(framer_.perspective()));
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
-      TestConnectionId(), EmptyQuicConnectionId(), false, false,
-      kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
-      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, framer_.version(),
-      Perspective::IS_CLIENT));
-
-  MockFramerVisitor visitor;
-  framer_.set_visitor(&visitor);
-  EXPECT_CALL(visitor, OnPacket()).Times(1);
-  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
-      .Times(1)
-      .WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
-      .Times(1)
-      .WillOnce(Return(true));
-  EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1);
-  EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
-  EXPECT_CALL(visitor, OnError(_)).Times(1);
-  EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
-  EXPECT_CALL(visitor, OnPacketComplete()).Times(0);
-
-  EXPECT_FALSE(framer_.ProcessPacket(*packet));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
-}
-
-TEST_P(QuicFramerTest, IetfBlockedFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_DATA_BLOCKED)
-      {"",
-       {0x14}},
-      // blocked offset
-      {"Can not read blocked offset.",
-       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfBlockedPacket) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicBlockedFrame frame;
-  frame.stream_id = QuicUtils::GetInvalidStreamId(framer_.transport_version());
-  frame.offset = kStreamOffset;
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_DATA_BLOCKED)
-    0x14,
-    // Offset
-    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, IetfStreamBlockedFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_STREAM_DATA_BLOCKED)
-      {"",
-       {0x15}},
-      // blocked offset
-      {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      {"Can not read stream blocked offset.",
-       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
-  EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STREAM_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfStreamBlockedPacket) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicBlockedFrame frame;
-  frame.stream_id = kStreamId;
-  frame.offset = kStreamOffset;
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_STREAM_DATA_BLOCKED)
-    0x15,
-    // Stream ID
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // Offset
-    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BiDiMaxStreamsFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
-      {"",
-       {0x12}},
-      // max. streams
-      {"Unable to read IETF_MAX_STREAMS_BIDIRECTIONAL frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
-  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, UniDiMaxStreamsFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // Test runs in client mode, no connection id
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
-      {"",
-       {0x13}},
-      // max. streams
-      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
-      {"",
-       {0x13}},
-      // max. streams
-      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // Test runs in client mode, no connection id
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
-      {"",
-       {0x13}},
-      // max. streams
-      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-// The following four tests ensure that the framer can deserialize a stream
-// count that is large enough to cause the resulting stream ID to exceed the
-// current implementation limit(32 bits). The intent is that when this happens,
-// the stream limit is pegged to the maximum supported value. There are four
-// tests, for the four combinations of uni- and bi-directional, server- and
-// client- initiated.
-TEST_P(QuicFramerTest, BiDiMaxStreamsFrameTooBig) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x9A, 0xBC,
-    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
-    0x12,
-
-    // max. streams. Max stream ID allowed is 0xffffffff
-    // This encodes a count of 0x40000000, leading to stream
-    // IDs in the range 0x1 00000000 to 0x1 00000003.
-    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
-                                ABSL_ARRAYSIZE(packet_ietf), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
-}
-
-TEST_P(QuicFramerTest, ClientBiDiMaxStreamsFrameTooBig) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // Test runs in client mode, no connection id
-    // packet number
-    0x12, 0x34, 0x9A, 0xBC,
-    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
-    0x12,
-
-    // max. streams. Max stream ID allowed is 0xffffffff
-    // This encodes a count of 0x40000000, leading to stream
-    // IDs in the range 0x1 00000000 to 0x1 00000003.
-    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
-                                ABSL_ARRAYSIZE(packet_ietf), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
-}
-
-TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrameTooBig) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x9A, 0xBC,
-    // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
-    0x13,
-
-    // max. streams. Max stream ID allowed is 0xffffffff
-    // This encodes a count of 0x40000000, leading to stream
-    // IDs in the range 0x1 00000000 to 0x1 00000003.
-    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
-                                ABSL_ARRAYSIZE(packet_ietf), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-}
-
-TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrameTooBig) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // Test runs in client mode, no connection id
-    // packet number
-    0x12, 0x34, 0x9A, 0xBC,
-    // frame type (IETF_MAX_STREAMS_UNDIRECTIONAL)
-    0x13,
-
-    // max. streams. Max stream ID allowed is 0xffffffff
-    // This encodes a count of 0x40000000, leading to stream
-    // IDs in the range 0x1 00000000 to 0x1 00000003.
-    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
-                                ABSL_ARRAYSIZE(packet_ietf), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-}
-
-// Specifically test that count==0 is accepted.
-TEST_P(QuicFramerTest, MaxStreamsFrameZeroCount) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x9A, 0xBC,
-    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
-    0x12,
-    // max. streams == 0.
-    kVarInt62OneByte + 0x00
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
-                                ABSL_ARRAYSIZE(packet_ietf), false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-}
-
-TEST_P(QuicFramerTest, ServerBiDiStreamsBlockedFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
-      {"",
-       {0x13}},
-      // stream count
-      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
-       {kVarInt62OneByte + 0x00}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.max_streams_frame_.stream_count);
-  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
-}
-
-TEST_P(QuicFramerTest, BiDiStreamsBlockedFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
-      {"",
-       {0x16}},
-      // stream id
-      {"Unable to read IETF_STREAMS_BLOCKED_BIDIRECTIONAL "
-       "frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
-  EXPECT_FALSE(visitor_.streams_blocked_frame_.unidirectional);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, UniDiStreamsBlockedFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
-      {"",
-       {0x17}},
-      // stream id
-      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
-       "frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
-  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
-  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, ClientUniDiStreamsBlockedFrame) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // Test runs in client mode, no connection id
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
-      {"",
-       {0x17}},
-      // stream id
-      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
-       "frame stream id/count.",
-       {kVarInt62OneByte + 0x03}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
-  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
-  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-// Check that when we get a STREAMS_BLOCKED frame that specifies too large
-// a stream count, we reject with an appropriate error. There is no need to
-// check for different combinations of Uni/Bi directional and client/server
-// initiated; the logic does not take these into account.
-TEST_P(QuicFramerTest, StreamsBlockedFrameTooBig) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // Test runs in client mode, no connection id
-    // packet number
-    0x12, 0x34, 0x9A, 0xBC,
-    // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL)
-    0x16,
-
-    // max. streams. Max stream ID allowed is 0xffffffff
-    // This encodes a count of 0x40000000, leading to stream
-    // IDs in the range 0x1 00000000 to 0x1 00000003.
-    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
-                                ABSL_ARRAYSIZE(packet_ietf), false);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_STREAMS_BLOCKED_DATA));
-  EXPECT_EQ(framer_.detailed_error(),
-            "STREAMS_BLOCKED stream count exceeds implementation limit.");
-}
-
-// Specifically test that count==0 is accepted.
-TEST_P(QuicFramerTest, StreamsBlockedFrameZeroCount) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
-      {"",
-       {0x17}},
-      // stream id
-      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
-       "frame stream id/count.",
-       {kVarInt62OneByte + 0x00}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.streams_blocked_frame_.stream_count);
-  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildBiDiStreamsBlockedPacket) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicStreamsBlockedFrame frame;
-  frame.stream_count = 3;
-  frame.unidirectional = false;
-
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
-    0x16,
-    // Stream count
-    kVarInt62OneByte + 0x03
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildUniStreamsBlockedPacket) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicStreamsBlockedFrame frame;
-  frame.stream_count = 3;
-  frame.unidirectional = true;
-
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
-    0x17,
-    // Stream count
-    kVarInt62OneByte + 0x03
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildBiDiMaxStreamsPacket) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicMaxStreamsFrame frame;
-  frame.stream_count = 3;
-  frame.unidirectional = false;
-
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL frame)
-    0x12,
-    // Stream count
-    kVarInt62OneByte + 0x03
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, BuildUniDiMaxStreamsPacket) {
-  // This frame is only for IETF QUIC.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  // This test runs in client mode.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicMaxStreamsFrame frame;
-  frame.stream_count = 3;
-  frame.unidirectional = true;
-
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
-    0x13,
-    // Stream count
-    kVarInt62OneByte + 0x03
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, NewConnectionIdFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_NEW_CONNECTION_ID frame)
-      {"",
-       {0x18}},
-      // error code
-      {"Unable to read new connection ID frame sequence number.",
-       {kVarInt62OneByte + 0x11}},
-      {"Unable to read new connection ID frame retire_prior_to.",
-       {kVarInt62OneByte + 0x09}},
-      {"Unable to read new connection ID frame connection id.",
-       {0x08}},  // connection ID length
-      {"Unable to read new connection ID frame connection id.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
-      {"Can not read new connection ID frame reset token.",
-       {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-        0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
-  EXPECT_EQ(FramerTestConnectionIdPlusOne(),
-            visitor_.new_connection_id_.connection_id);
-  EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
-  EXPECT_EQ(0x09u, visitor_.new_connection_id_.retire_prior_to);
-  EXPECT_EQ(kTestStatelessResetToken,
-            visitor_.new_connection_id_.stateless_reset_token);
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
-}
-
-TEST_P(QuicFramerTest, NewConnectionIdFrameVariableLength) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_NEW_CONNECTION_ID frame)
-      {"",
-       {0x18}},
-      // error code
-      {"Unable to read new connection ID frame sequence number.",
-       {kVarInt62OneByte + 0x11}},
-      {"Unable to read new connection ID frame retire_prior_to.",
-       {kVarInt62OneByte + 0x0a}},
-      {"Unable to read new connection ID frame connection id.",
-       {0x09}},  // connection ID length
-      {"Unable to read new connection ID frame connection id.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
-      {"Can not read new connection ID frame reset token.",
-       {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-        0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
-  EXPECT_EQ(FramerTestConnectionIdNineBytes(),
-            visitor_.new_connection_id_.connection_id);
-  EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
-  EXPECT_EQ(0x0au, visitor_.new_connection_id_.retire_prior_to);
-  EXPECT_EQ(kTestStatelessResetToken,
-            visitor_.new_connection_id_.stateless_reset_token);
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
-}
-
-// Verifies that parsing a NEW_CONNECTION_ID frame with a length above the
-// specified maximum fails.
-TEST_P(QuicFramerTest, InvalidLongNewConnectionIdFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // The NEW_CONNECTION_ID frame is only for IETF QUIC.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_NEW_CONNECTION_ID frame)
-      {"",
-       {0x18}},
-      // error code
-      {"Unable to read new connection ID frame sequence number.",
-       {kVarInt62OneByte + 0x11}},
-      {"Unable to read new connection ID frame retire_prior_to.",
-       {kVarInt62OneByte + 0x0b}},
-      {"Unable to read new connection ID frame connection id.",
-       {0x40}},  // connection ID length
-      {"Unable to read new connection ID frame connection id.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
-        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
-        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
-        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E}},
-      {"Can not read new connection ID frame reset token.",
-       {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
-  EXPECT_EQ("Invalid new connection ID length for version.",
-            framer_.detailed_error());
-}
-
-// Verifies that parsing a NEW_CONNECTION_ID frame with an invalid
-// retire-prior-to fails.
-TEST_P(QuicFramerTest, InvalidRetirePriorToNewConnectionIdFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC only.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_NEW_CONNECTION_ID frame)
-      {"",
-       {0x18}},
-      // sequence number
-      {"Unable to read new connection ID frame sequence number.",
-       {kVarInt62OneByte + 0x11}},
-      {"Unable to read new connection ID frame retire_prior_to.",
-       {kVarInt62OneByte + 0x1b}},
-      {"Unable to read new connection ID frame connection id length.",
-       {0x08}},  // connection ID length
-      {"Unable to read new connection ID frame connection id.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
-      {"Can not read new connection ID frame reset token.",
-       {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
-  EXPECT_EQ("Retire_prior_to > sequence_number.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, BuildNewConnectionIdFramePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC only.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicNewConnectionIdFrame frame;
-  frame.sequence_number = 0x11;
-  frame.retire_prior_to = 0x0c;
-  // Use this value to force a 4-byte encoded variable length connection ID
-  // in the frame.
-  frame.connection_id = FramerTestConnectionIdPlusOne();
-  frame.stateless_reset_token = kTestStatelessResetToken;
-
-  QuicFrames frames = {QuicFrame(&frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_NEW_CONNECTION_ID frame)
-    0x18,
-    // sequence number
-    kVarInt62OneByte + 0x11,
-    // retire_prior_to
-    kVarInt62OneByte + 0x0c,
-    // new connection id length
-    0x08,
-    // new connection id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-    // stateless reset token
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, NewTokenFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC only.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_NEW_TOKEN frame)
-      {"",
-       {0x07}},
-      // Length
-      {"Unable to read new token length.",
-       {kVarInt62OneByte + 0x08}},
-      {"Unable to read new token data.",
-       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}}
-  };
-  // clang-format on
-  uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
-                                    0x04, 0x05, 0x06, 0x07};
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
-  EXPECT_EQ(sizeof(expected_token_value), visitor_.new_token_.token.length());
-  EXPECT_EQ(0, memcmp(expected_token_value, visitor_.new_token_.token.data(),
-                      sizeof(expected_token_value)));
-
-  CheckFramingBoundaries(packet, QUIC_INVALID_NEW_TOKEN);
-}
-
-TEST_P(QuicFramerTest, BuildNewTokenFramePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for IETF QUIC only.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
-                                    0x04, 0x05, 0x06, 0x07};
-
-  QuicNewTokenFrame frame(0,
-                          absl::string_view((const char*)(expected_token_value),
-                                            sizeof(expected_token_value)));
-
-  QuicFrames frames = {QuicFrame(&frame)};
-
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_NEW_TOKEN frame)
-    0x07,
-    // Length and token
-    kVarInt62OneByte + 0x08,
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet),
-      ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicFramerTest, IetfStopSendingFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Stop sending frame is IETF QUIC only.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_STOP_SENDING frame)
-      {"",
-       {0x05}},
-      // stream id
-      {"Unable to read IETF_STOP_SENDING frame stream id/count.",
-       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
-      {"Unable to read stop sending application error code.",
-       {kVarInt62FourBytes + 0x00, 0x00, 0x76, 0x54}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(kStreamId, visitor_.stop_sending_frame_.stream_id);
-  EXPECT_EQ(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE,
-            visitor_.stop_sending_frame_.error_code);
-  EXPECT_EQ(static_cast<uint64_t>(0x7654),
-            visitor_.stop_sending_frame_.ietf_error_code);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STOP_SENDING_FRAME_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfStopSendingPacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Stop sending frame is IETF QUIC only.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicStopSendingFrame frame;
-  frame.stream_id = kStreamId;
-  frame.error_code = QUIC_STREAM_ENCODER_STREAM_ERROR;
-  frame.ietf_error_code =
-      static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
-  QuicFrames frames = {QuicFrame(frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_STOP_SENDING frame)
-    0x05,
-    // Stream ID
-    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
-    // Application error code
-    kVarInt62TwoBytes + 0x02, 0x01,
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, IetfPathChallengeFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Path Challenge frame is IETF QUIC only.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_PATH_CHALLENGE)
-      {"",
-       {0x1a}},
-      // data
-      {"Can not read path challenge data.",
-       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
-            visitor_.path_challenge_frame_.data_buffer);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_CHALLENGE_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfPathChallengePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Path Challenge frame is IETF QUIC only.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicPathChallengeFrame frame;
-  frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
-  QuicFrames frames = {QuicFrame(&frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_PATH_CHALLENGE)
-    0x1a,
-    // Data
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, IetfPathResponseFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Path response frame is IETF QUIC only.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (IETF_PATH_RESPONSE)
-      {"",
-       {0x1b}},
-      // data
-      {"Can not read path response data.",
-       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
-            visitor_.path_response_frame_.data_buffer);
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_RESPONSE_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildIetfPathResponsePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Path response frame is IETF QUIC only
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicPathResponseFrame frame;
-  frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
-  QuicFrames frames = {QuicFrame(&frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_PATH_RESPONSE)
-    0x1b,
-    // Data
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, GetRetransmittableControlFrameSize) {
-  QuicRstStreamFrame rst_stream(1, 3, QUIC_STREAM_CANCELLED, 1024);
-  EXPECT_EQ(QuicFramer::GetRstStreamFrameSize(framer_.transport_version(),
-                                              rst_stream),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&rst_stream)));
-
-  std::string error_detail(2048, 'e');
-  QuicConnectionCloseFrame connection_close(framer_.transport_version(),
-                                            QUIC_NETWORK_IDLE_TIMEOUT,
-                                            NO_IETF_QUIC_ERROR, error_detail,
-                                            /*transport_close_frame_type=*/0);
-
-  EXPECT_EQ(QuicFramer::GetConnectionCloseFrameSize(framer_.transport_version(),
-                                                    connection_close),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&connection_close)));
-
-  QuicGoAwayFrame goaway(2, QUIC_PEER_GOING_AWAY, 3, error_detail);
-  EXPECT_EQ(QuicFramer::GetMinGoAwayFrameSize() + 256,
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&goaway)));
-
-  QuicWindowUpdateFrame window_update(3, 3, 1024);
-  EXPECT_EQ(QuicFramer::GetWindowUpdateFrameSize(framer_.transport_version(),
-                                                 window_update),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(window_update)));
-
-  QuicBlockedFrame blocked(4, 3, 1024);
-  EXPECT_EQ(
-      QuicFramer::GetBlockedFrameSize(framer_.transport_version(), blocked),
-      QuicFramer::GetRetransmittableControlFrameSize(
-          framer_.transport_version(), QuicFrame(blocked)));
-
-  // Following frames are IETF QUIC frames only.
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-
-  QuicNewConnectionIdFrame new_connection_id(5, TestConnectionId(), 1,
-                                             kTestStatelessResetToken, 1);
-  EXPECT_EQ(QuicFramer::GetNewConnectionIdFrameSize(new_connection_id),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&new_connection_id)));
-
-  QuicMaxStreamsFrame max_streams(6, 3, /*unidirectional=*/false);
-  EXPECT_EQ(QuicFramer::GetMaxStreamsFrameSize(framer_.transport_version(),
-                                               max_streams),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(max_streams)));
-
-  QuicStreamsBlockedFrame streams_blocked(7, 3, /*unidirectional=*/false);
-  EXPECT_EQ(QuicFramer::GetStreamsBlockedFrameSize(framer_.transport_version(),
-                                                   streams_blocked),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(streams_blocked)));
-
-  QuicPathFrameBuffer buffer = {
-      {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
-  QuicPathResponseFrame path_response_frame(8, buffer);
-  EXPECT_EQ(QuicFramer::GetPathResponseFrameSize(path_response_frame),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&path_response_frame)));
-
-  QuicPathChallengeFrame path_challenge_frame(9, buffer);
-  EXPECT_EQ(QuicFramer::GetPathChallengeFrameSize(path_challenge_frame),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&path_challenge_frame)));
-
-  QuicStopSendingFrame stop_sending_frame(10, 3, QUIC_STREAM_CANCELLED);
-  EXPECT_EQ(QuicFramer::GetStopSendingFrameSize(stop_sending_frame),
-            QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(stop_sending_frame)));
-}
-
-// A set of tests to ensure that bad frame-type encodings
-// are properly detected and handled.
-// First, four tests to see that unknown frame types generate
-// a QUIC_INVALID_FRAME_DATA error with detailed information
-// "Illegal frame type." This regardless of the encoding of the type
-// (1/2/4/8 bytes).
-// This only for version 99.
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown1Byte) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (unknown value, single-byte encoding)
-      {"",
-       {0x38}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
-  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown2Bytes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (unknown value, two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x01, 0x38}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
-  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown4Bytes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (unknown value, four-byte encoding)
-      {"",
-       {kVarInt62FourBytes + 0x01, 0x00, 0x00, 0x38}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
-  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown8Bytes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (unknown value, eight-byte encoding)
-      {"",
-       {kVarInt62EightBytes + 0x01, 0x00, 0x00, 0x01, 0x02, 0x34, 0x56, 0x38}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
-  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
-}
-
-// Three tests to check that known frame types that are not minimally
-// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
-// information "Frame type not minimally encoded."
-// Look at the frame-type encoded in 2, 4, and 8 bytes.
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2Bytes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (Blocked, two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x08}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown4Bytes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (Blocked, four-byte encoding)
-      {"",
-       {kVarInt62FourBytes + 0x00, 0x00, 0x00, 0x08}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown8Bytes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (Blocked, eight-byte encoding)
-      {"",
-       {kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-}
-
-// Tests to check that all known IETF frame types that are not minimally
-// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
-// information "Frame type not minimally encoded."
-// Just look at 2-byte encoding.
-TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2BytesAllTypes) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Only IETF QUIC encodes frame types such that this test is relevant.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-
-  // clang-format off
-  PacketFragments packets[] = {
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x00}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x01}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x02}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x03}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x04}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x05}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x06}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x07}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x08}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x09}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x0a}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x0b}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x0c}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x0d}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x0e}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x0f}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x10}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x11}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x12}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x13}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x14}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x15}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x16}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x17}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x18}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x20}}
-    },
-    {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x9A, 0xBC}},
-      // frame type (two-byte encoding)
-      {"",
-       {kVarInt62TwoBytes + 0x00, 0x21}}
-    },
-  };
-  // clang-format on
-
-  for (PacketFragments& packet : packets) {
-    std::unique_ptr<QuicEncryptedPacket> encrypted(
-        AssemblePacketFromFragments(packet));
-
-    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-
-    EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-    EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
-  }
-}
-
-TEST_P(QuicFramerTest, RetireConnectionIdFrame) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for version 99.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  PacketFragments packet_ietf = {
-      // type (short header, 4 byte packet number)
-      {"",
-       {0x43}},
-      // connection_id
-      {"",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-      // packet number
-      {"",
-       {0x12, 0x34, 0x56, 0x78}},
-      // frame type (IETF_RETIRE_CONNECTION_ID frame)
-      {"",
-       {0x19}},
-      // Sequence number
-      {"Unable to read retire connection ID frame sequence number.",
-       {kVarInt62TwoBytes + 0x11, 0x22}}
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet_ietf));
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_TRUE(CheckDecryption(
-      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
-      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
-
-  EXPECT_EQ(0u, visitor_.stream_frames_.size());
-
-  EXPECT_EQ(0x1122u, visitor_.retire_connection_id_.sequence_number);
-
-  ASSERT_EQ(0u, visitor_.ack_frames_.size());
-
-  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
-}
-
-TEST_P(QuicFramerTest, BuildRetireConnectionIdFramePacket) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // This frame is only for version 99.
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicRetireConnectionIdFrame frame;
-  frame.sequence_number = 0x1122;
-
-  QuicFrames frames = {QuicFrame(&frame)};
-
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_RETIRE_CONNECTION_ID frame)
-    0x19,
-    // sequence number
-    kVarInt62TwoBytes + 0x11, 0x22
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
-      ABSL_ARRAYSIZE(packet_ietf));
-}
-
-TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ack frame)
-    0x45,
-    // largest observed
-    0x00, 0x00,
-    // Zero delta time.
-    0x00, 0x00,
-    // first ack block length.
-    0x00, 0x00,
-    // num timestamps.
-    0x00
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ack frame)
-    0x45,
-    // largest observed
-    0x00, 0x00,
-    // Zero delta time.
-    0x00, 0x00,
-    // first ack block length.
-    0x00, 0x00,
-    // num timestamps.
-    0x00
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_ACK frame)
-    0x02,
-    // Largest acked
-    kVarInt62OneByte + 0x00,
-    // Zero delta time.
-    kVarInt62OneByte + 0x00,
-    // Ack block count 0
-    kVarInt62OneByte + 0x00,
-    // First ack block length
-    kVarInt62OneByte + 0x00,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_EQ(framer_.detailed_error(), "Largest acked is 0.");
-}
-
-TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ack frame)
-    0x45,
-    // largest observed
-    0x00, 0x02,
-    // Zero delta time.
-    0x00, 0x00,
-    // first ack block length.
-    0x00, 0x03,
-    // num timestamps.
-    0x00
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ack frame)
-    0x45,
-    // largest observed
-    0x00, 0x02,
-    // Zero delta time.
-    0x00, 0x00,
-    // first ack block length.
-    0x00, 0x03,
-    // num timestamps.
-    0x00
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_ACK frame)
-    0x02,
-    // Largest acked
-    kVarInt62OneByte + 0x02,
-    // Zero delta time.
-    kVarInt62OneByte + 0x00,
-    // Ack block count 0
-    kVarInt62OneByte + 0x00,
-    // First ack block length
-    kVarInt62OneByte + 0x02,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  EXPECT_EQ(framer_.detailed_error(),
-            "Underflow with first ack block length 3 largest acked is 2.");
-}
-
-TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) {
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ack frame)
-    0x60,
-    // largest observed
-    0x0A,
-    // Zero delta time.
-    0x00, 0x00,
-    // Num of ack blocks
-    0x02,
-    // first ack block length.
-    0x02,
-    // gap to next block
-    0x01,
-    // ack block length
-    0x01,
-    // gap to next block
-    0x01,
-    // ack block length
-    0x06,
-    // num timestamps.
-    0x00
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ack frame)
-    0x60,
-    // largest observed
-    0x0A,
-    // Zero delta time.
-    0x00, 0x00,
-    // Num of ack blocks
-    0x02,
-    // first ack block length.
-    0x02,
-    // gap to next block
-    0x01,
-    // ack block length
-    0x01,
-    // gap to next block
-    0x01,
-    // ack block length
-    0x06,
-    // num timestamps.
-    0x00
-  };
-
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_ACK frame)
-    0x02,
-    // Largest acked
-    kVarInt62OneByte + 0x0A,
-    // Zero delta time.
-    kVarInt62OneByte + 0x00,
-    // Ack block count 2
-    kVarInt62OneByte + 0x02,
-    // First ack block length
-    kVarInt62OneByte + 0x01,
-    // gap to next block length
-    kVarInt62OneByte + 0x00,
-    // ack block length
-    kVarInt62OneByte + 0x00,
-    // gap to next block length
-    kVarInt62OneByte + 0x00,
-    // ack block length
-    kVarInt62OneByte + 0x05,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_size = ABSL_ARRAYSIZE(packet);
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    p = packet_ietf;
-    p_size = ABSL_ARRAYSIZE(packet_ietf);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    EXPECT_EQ(framer_.detailed_error(),
-              "Underflow with ack block length 6 latest ack block end is 5.");
-  } else {
-    EXPECT_EQ(framer_.detailed_error(),
-              "Underflow with ack block length 6, end of block is 6.");
-  }
-}
-
-TEST_P(QuicFramerTest, CoalescedPacket) {
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  unsigned char packet_ietf[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  // clang-format on
-  const size_t first_packet_ietf_size = 46;
-  // If the first packet changes, the attempt to fix the first byte of the
-  // second packet will fail.
-  EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfQuicFrames()) {
-    ReviseFirstByteByVersion(packet_ietf);
-    ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
-    p = packet_ietf;
-    p_length = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
-  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(2u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[1]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[1]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[1]->offset);
-  CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[1].get());
-}
-
-TEST_P(QuicFramerTest, CoalescedPacketWithUdpPadding) {
-  if (!framer_.version().HasLongHeaderLengths()) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // padding
-    0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-  };
-  unsigned char packet_ietf[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-      // padding
-      0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfQuicFrames()) {
-    ReviseFirstByteByVersion(packet_ietf);
-    p = packet_ietf;
-    p_length = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  EXPECT_EQ(visitor_.coalesced_packets_.size(), 0u);
-}
-
-TEST_P(QuicFramerTest, CoalescedPacketWithDifferentVersion) {
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // garbage version
-      'G', 'A', 'B', 'G',
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  unsigned char packet_ietf[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // garbage version
-      'G', 'A', 'B', 'G',
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  // clang-format on
-  const size_t first_packet_ietf_size = 46;
-  // If the first packet changes, the attempt to fix the first byte of the
-  // second packet will fail.
-  EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfQuicFrames()) {
-    ReviseFirstByteByVersion(packet_ietf);
-    ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
-    p = packet_ietf;
-    p_length = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
-  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  // Verify version mismatch gets reported.
-  EXPECT_EQ(1, visitor_.version_mismatch_);
-}
-
-TEST_P(QuicFramerTest, UndecryptablePacketWithoutDecrypter) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  if (!framer_.version().KnowsWhichDecrypterToUse()) {
-    // We create a bad client decrypter by using initial encryption with a
-    // bogus connection ID; it should fail to decrypt everything.
-    QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
-    CrypterPair bogus_crypters;
-    CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
-                                          framer_.version(),
-                                          bogus_connection_id, &bogus_crypters);
-    // This removes all other decrypters.
-    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-                         std::move(bogus_crypters.decrypter));
-  }
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (version included, 8-byte connection ID,
-    // 4-byte packet number)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frames
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  unsigned char packet46[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // connection ID lengths
-    0x05,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frames
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  unsigned char packet49[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x00,
-    // source connection ID length
-    0x08,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x24,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frames
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    ReviseFirstByteByVersion(packet49);
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_length = ABSL_ARRAYSIZE(packet46);
-  }
-  // First attempt decryption without the handshake crypter.
-  EXPECT_FALSE(
-      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
-  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
-  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
-  quiche::test::CompareCharArraysWithHexError(
-      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
-      visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    EXPECT_EQ(ENCRYPTION_HANDSHAKE,
-              visitor_.undecryptable_decryption_levels_[0]);
-  }
-  EXPECT_FALSE(visitor_.undecryptable_has_decryption_keys_[0]);
-}
-
-TEST_P(QuicFramerTest, UndecryptablePacketWithDecrypter) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  // We create a bad client decrypter by using initial encryption with a
-  // bogus connection ID; it should fail to decrypt everything.
-  QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
-  CrypterPair bad_handshake_crypters;
-  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
-                                        framer_.version(), bogus_connection_id,
-                                        &bad_handshake_crypters);
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
-                             std::move(bad_handshake_crypters.decrypter));
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_HANDSHAKE,
-                         std::move(bad_handshake_crypters.decrypter));
-  }
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (version included, 8-byte connection ID,
-    // 4-byte packet number)
-    0x28,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frames
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  unsigned char packet46[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // connection ID lengths
-    0x05,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frames
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  unsigned char packet49[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x00,
-    // source connection ID length
-    0x08,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x24,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frames
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    ReviseFirstByteByVersion(packet49);
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  } else if (framer_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    p_length = ABSL_ARRAYSIZE(packet46);
-  }
-
-  EXPECT_FALSE(
-      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
-  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
-  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
-  quiche::test::CompareCharArraysWithHexError(
-      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
-      visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    EXPECT_EQ(ENCRYPTION_HANDSHAKE,
-              visitor_.undecryptable_decryption_levels_[0]);
-  }
-  EXPECT_EQ(framer_.version().KnowsWhichDecrypterToUse(),
-            visitor_.undecryptable_has_decryption_keys_[0]);
-}
-
-TEST_P(QuicFramerTest, UndecryptableCoalescedPacket) {
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // We create a bad client decrypter by using initial encryption with a
-  // bogus connection ID; it should fail to decrypt everything.
-  QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
-  CrypterPair bad_handshake_crypters;
-  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
-                                        framer_.version(), bogus_connection_id,
-                                        &bad_handshake_crypters);
-  framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
-                           std::move(bad_handshake_crypters.decrypter));
-  // clang-format off
-  unsigned char packet[] = {
-    // first coalesced packet
-      // public flags (long header with packet type HANDSHAKE and
-      // 4-byte packet number)
-      0xE3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  unsigned char packet_ietf[] = {
-    // first coalesced packet
-      // public flags (long header with packet type HANDSHAKE and
-      // 4-byte packet number)
-      0xE3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  // clang-format on
-  const size_t length_of_first_coalesced_packet = 46;
-  // If the first packet changes, the attempt to fix the first byte of the
-  // second packet will fail.
-  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfQuicFrames()) {
-    ReviseFirstByteByVersion(packet_ietf);
-    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
-    p = packet_ietf;
-    p_length = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
-
-  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
-  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
-  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
-  // Make sure we only receive the first undecryptable packet and not the
-  // full packet including the second coalesced packet.
-  quiche::test::CompareCharArraysWithHexError(
-      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
-      visitor_.undecryptable_packets_[0]->length(), AsChars(p),
-      length_of_first_coalesced_packet);
-  EXPECT_EQ(ENCRYPTION_HANDSHAKE, visitor_.undecryptable_decryption_levels_[0]);
-  EXPECT_TRUE(visitor_.undecryptable_has_decryption_keys_[0]);
-
-  // Make sure the second coalesced packet is parsed correctly.
-  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
-  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
-
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[0].get());
-}
-
-TEST_P(QuicFramerTest, MismatchedCoalescedPacket) {
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  unsigned char packet_ietf[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x79,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'H',  'E',  'L',  'L',
-      'O',  '_',  'W',  'O',
-      'R',  'L',  'D',  '?',
-  };
-  // clang-format on
-  const size_t length_of_first_coalesced_packet = 46;
-  // If the first packet changes, the attempt to fix the first byte of the
-  // second packet will fail.
-  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfQuicFrames()) {
-    ReviseFirstByteByVersion(packet_ietf);
-    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
-    p = packet_ietf;
-    p_length = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
-}
-
-TEST_P(QuicFramerTest, InvalidCoalescedPacket) {
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (stream frame with fin)
-      0xFE,
-      // stream id
-      0x02, 0x03, 0x04,
-      // offset
-      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
-      // data length
-      0x00, 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version would be here but we cut off the invalid coalesced header.
-  };
-  unsigned char packet_ietf[] = {
-    // first coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version
-      QUIC_VERSION_BYTES,
-      // destination connection ID length
-      0x08,
-      // destination connection ID
-      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-      // source connection ID length
-      0x00,
-      // long header packet length
-      0x1E,
-      // packet number
-      0x12, 0x34, 0x56, 0x78,
-      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
-      0x08 | 0x01 | 0x02 | 0x04,
-      // stream id
-      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
-      // offset
-      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
-      0x32, 0x10, 0x76, 0x54,
-      // data length
-      kVarInt62OneByte + 0x0c,
-      // data
-      'h',  'e',  'l',  'l',
-      'o',  ' ',  'w',  'o',
-      'r',  'l',  'd',  '!',
-    // second coalesced packet
-      // public flags (long header with packet type ZERO_RTT_PROTECTED and
-      // 4-byte packet number)
-      0xD3,
-      // version would be here but we cut off the invalid coalesced header.
-  };
-  // clang-format on
-  const size_t length_of_first_coalesced_packet = 46;
-  // If the first packet changes, the attempt to fix the first byte of the
-  // second packet will fail.
-  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasIetfQuicFrames()) {
-    ReviseFirstByteByVersion(packet_ietf);
-    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
-    p = packet_ietf;
-    p_length = ABSL_ARRAYSIZE(packet_ietf);
-  }
-
-  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
-
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  ASSERT_TRUE(visitor_.header_.get());
-
-  ASSERT_EQ(1u, visitor_.stream_frames_.size());
-  EXPECT_EQ(0u, visitor_.ack_frames_.size());
-
-  // Stream ID should be the last 3 bytes of kStreamId.
-  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
-  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
-  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
-  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
-
-  ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
-}
-
-// Some IETF implementations send an initial followed by zeroes instead of
-// padding inside the initial. We need to make sure that we still process
-// the initial correctly and ignore the zeroes.
-TEST_P(QuicFramerTest, CoalescedPacketWithZeroesRoundTrip) {
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
-      !framer_.version().UsesInitialObfuscators()) {
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  QuicConnectionId connection_id = FramerTestConnectionId();
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  CrypterPair client_crypters;
-  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
-                                        framer_.version(), connection_id,
-                                        &client_crypters);
-  framer_.SetEncrypter(ENCRYPTION_INITIAL,
-                       std::move(client_crypters.encrypter));
-
-  QuicPacketHeader header;
-  header.destination_connection_id = connection_id;
-  header.version_flag = true;
-  header.packet_number = kPacketNumber;
-  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
-  header.long_packet_type = INITIAL;
-  header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-  QuicFrames frames = {QuicFrame(QuicPingFrame()),
-                       QuicFrame(QuicPaddingFrame(3))};
-
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_NE(nullptr, data);
-
-  // Add zeroes after the valid initial packet.
-  unsigned char packet[kMaxOutgoingPacketSize] = {};
-  size_t encrypted_length =
-      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *data,
-                             AsChars(packet), ABSL_ARRAYSIZE(packet));
-  ASSERT_NE(0u, encrypted_length);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  CrypterPair server_crypters;
-  CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER,
-                                        framer_.version(), connection_id,
-                                        &server_crypters);
-  framer_.InstallDecrypter(ENCRYPTION_INITIAL,
-                           std::move(server_crypters.decrypter));
-
-  // Make sure the first long header initial packet parses correctly.
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-
-  // Make sure we discard the subsequent zeroes.
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  EXPECT_TRUE(visitor_.coalesced_packets_.empty());
-}
-
-TEST_P(QuicFramerTest, ClientReceivesWrongVersion) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-
-  // clang-format off
-  unsigned char packet[] = {
-       // public flags (long header with packet type INITIAL)
-       0xC3,
-       // version that is different from the framer's version
-       'Q', '0', '4', '3',
-       // connection ID lengths
-       0x05,
-       // source connection ID
-       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-       // packet number
-       0x01,
-       // padding frame
-       0x00,
-  };
-  // clang-format on
-
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_WRONG_VERSION));
-  EXPECT_EQ("Client received unexpected version.", framer_.detailed_error());
-}
-
-TEST_P(QuicFramerTest, PacketHeaderWithVariableLengthConnectionId) {
-  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
-                                    0x54, 0x32, 0x10, 0x42};
-  QuicConnectionId connection_id(reinterpret_cast<char*>(connection_id_bytes),
-                                 sizeof(connection_id_bytes));
-  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
-  QuicFramerPeer::SetExpectedServerConnectionIDLength(&framer_,
-                                                      connection_id.length());
-
-  // clang-format off
-  PacketFragments packet = {
-      // type (8 byte connection_id and 1 byte packet number)
-      {"Unable to read first byte.",
-       {0x40}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
-      // packet number
-      {"Unable to read packet number.",
-       {0x78}},
-  };
-
-  PacketFragments packet_with_padding = {
-      // type (8 byte connection_id and 1 byte packet number)
-      {"Unable to read first byte.",
-       {0x40}},
-      // connection_id
-      {"Unable to read destination connection ID.",
-       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
-      // packet number
-      {"",
-       {0x78}},
-      // padding
-      {"", {0x00, 0x00, 0x00}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments =
-      framer_.version().HasHeaderProtection() ? packet_with_padding : packet;
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-  if (framer_.version().HasHeaderProtection()) {
-    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-    EXPECT_THAT(framer_.error(), IsQuicNoError());
-  } else {
-    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
-  }
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(connection_id, visitor_.header_->destination_connection_id);
-  EXPECT_FALSE(visitor_.header_->reset_flag);
-  EXPECT_FALSE(visitor_.header_->version_flag);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
-  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
-
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    return;
-  }
-  framer_.EnableMultiplePacketNumberSpacesSupport();
-
-  // clang-format off
-  unsigned char long_header_packet[] = {
-       // public flags (long header with packet type ZERO_RTT_PROTECTED and
-       // 4-byte packet number)
-       0xD3,
-       // version
-       QUIC_VERSION_BYTES,
-       // destination connection ID length
-       0x50,
-       // destination connection ID
-       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-       // packet number
-       0x12, 0x34, 0x56, 0x78,
-       // padding frame
-       0x00,
-   };
-  unsigned char long_header_packet_ietf[] = {
-       // public flags (long header with packet type ZERO_RTT_PROTECTED and
-       // 4-byte packet number)
-       0xD3,
-       // version
-       QUIC_VERSION_BYTES,
-       // destination connection ID length
-       0x08,
-       // destination connection ID
-       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-       // source connection ID length
-       0x00,
-       // long header packet length
-       0x05,
-       // packet number
-       0x12, 0x34, 0x56, 0x78,
-       // padding frame
-       0x00,
-  };
-  // clang-format on
-
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                             std::make_unique<TestDecrypter>());
-    framer_.RemoveDecrypter(ENCRYPTION_INITIAL);
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_ZERO_RTT,
-                         std::make_unique<TestDecrypter>());
-  }
-  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    EXPECT_TRUE(framer_.ProcessPacket(
-        QuicEncryptedPacket(AsChars(long_header_packet),
-                            ABSL_ARRAYSIZE(long_header_packet), false)));
-  } else {
-    ReviseFirstByteByVersion(long_header_packet_ietf);
-    EXPECT_TRUE(framer_.ProcessPacket(
-        QuicEncryptedPacket(AsChars(long_header_packet_ietf),
-                            ABSL_ARRAYSIZE(long_header_packet_ietf), false)));
-  }
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  EXPECT_FALSE(
-      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
-          .IsInitialized());
-  EXPECT_FALSE(
-      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
-          .IsInitialized());
-  EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLargestDecryptedPacketNumber(
-                               &framer_, APPLICATION_DATA));
-
-  // clang-format off
-  unsigned char short_header_packet[] = {
-     // type (short header, 1 byte packet number)
-     0x40,
-     // connection_id
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-     // packet number
-     0x79,
-     // padding frame
-     0x00, 0x00, 0x00,
-  };
-  // clang-format on
-
-  QuicEncryptedPacket short_header_encrypted(
-      AsChars(short_header_packet), ABSL_ARRAYSIZE(short_header_packet), false);
-  if (framer_.version().KnowsWhichDecrypterToUse()) {
-    framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                             std::make_unique<TestDecrypter>());
-    framer_.RemoveDecrypter(ENCRYPTION_ZERO_RTT);
-  } else {
-    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-                         std::make_unique<TestDecrypter>());
-  }
-  EXPECT_TRUE(framer_.ProcessPacket(short_header_encrypted));
-
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  EXPECT_FALSE(
-      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
-          .IsInitialized());
-  EXPECT_FALSE(
-      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
-          .IsInitialized());
-  EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLargestDecryptedPacketNumber(
-                                   &framer_, APPLICATION_DATA));
-}
-
-TEST_P(QuicFramerTest, IetfRetryPacketRejected) {
-  if (!framer_.version().KnowsWhichDecrypterToUse() ||
-      framer_.version().SupportsRetry()) {
-    return;
-  }
-
-  // clang-format off
-  PacketFragments packet46 = {
-    // public flags (IETF Retry packet, 0-length original destination CID)
-    {"Unable to read first byte.",
-     {0xf0}},
-    // version tag
-    {"Unable to read protocol version.",
-     {QUIC_VERSION_BYTES}},
-    // connection_id length
-    {"RETRY not supported in this version.",
-     {0x00}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet46));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-  CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, RetryPacketRejectedWithMultiplePacketNumberSpaces) {
-  if (!framer_.version().HasIetfInvariantHeader() ||
-      framer_.version().SupportsRetry()) {
-    return;
-  }
-  framer_.EnableMultiplePacketNumberSpacesSupport();
-
-  // clang-format off
-  PacketFragments packet = {
-    // public flags (IETF Retry packet, 0-length original destination CID)
-    {"Unable to read first byte.",
-     {0xf0}},
-    // version tag
-    {"Unable to read protocol version.",
-     {QUIC_VERSION_BYTES}},
-    // connection_id length
-    {"RETRY not supported in this version.",
-     {0x00}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, ProcessPublicHeaderNoVersionInferredType) {
-  // The framer needs to have Perspective::IS_SERVER and configured to infer the
-  // packet header type from the packet (not the version). The framer's version
-  // needs to be one that uses the IETF packet format.
-  if (!framer_.version().KnowsWhichDecrypterToUse()) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-
-  // Prepare a packet that uses the Google QUIC packet header but has no version
-  // field.
-
-  // clang-format off
-  PacketFragments packet = {
-    // public flags (1-byte packet number, 8-byte connection_id, no version)
-    {"Unable to read public flags.",
-     {0x08}},
-    // connection_id
-    {"Unable to read ConnectionId.",
-     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-    // packet number
-    {"Unable to read packet number.",
-     {0x01}},
-    // padding
-    {"Invalid public header type for expected version.",
-     {0x00}},
-  };
-  // clang-format on
-
-  PacketFragments& fragments = packet;
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(fragments));
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-  EXPECT_EQ("Invalid public header type for expected version.",
-            framer_.detailed_error());
-  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, ProcessMismatchedHeaderVersion) {
-  // The framer needs to have Perspective::IS_SERVER and configured to infer the
-  // packet header type from the packet (not the version). The framer's version
-  // needs to be one that uses the IETF packet format.
-  if (!framer_.version().KnowsWhichDecrypterToUse()) {
-    return;
-  }
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-
-  // clang-format off
-  PacketFragments packet = {
-    // public flags (Google QUIC header with version present)
-    {"Unable to read public flags.",
-     {0x09}},
-    // connection_id
-    {"Unable to read ConnectionId.",
-     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
-    // version tag
-    {"Unable to read protocol version.",
-     {QUIC_VERSION_BYTES}},
-    // packet number
-    {"Unable to read packet number.",
-     {0x01}},
-  };
-  // clang-format on
-
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      AssemblePacketFromFragments(packet));
-  framer_.ProcessPacket(*encrypted);
-
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-  EXPECT_EQ("Invalid public header type for expected version.",
-            framer_.detailed_error());
-  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
-}
-
-TEST_P(QuicFramerTest, WriteClientVersionNegotiationProbePacket) {
-  // clang-format off
-  static const uint8_t expected_packet[1200] = {
-    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
-    0xc0,
-    // Version, part of the IETF space reserved for negotiation.
-    0xca, 0xba, 0xda, 0xda,
-    // Destination connection ID length 8.
-    0x08,
-    // 8-byte destination connection ID.
-    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
-    // Source connection ID length 0.
-    0x00,
-    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
-    // not parse with any known version.
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    // zeroes to pad to 16 byte boundary.
-    0x00,
-    // A polite greeting in case a human sees this in tcpdump.
-    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
-    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
-    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
-    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
-    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
-    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
-    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
-    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
-    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
-    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
-    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
-    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
-    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
-    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
-    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
-    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
-    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
-    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
-    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
-    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
-    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
-    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
-  };
-  // clang-format on
-  char packet[1200];
-  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                            0x6c, 0x7a, 0x20, 0x21};
-  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
-      packet, sizeof(packet), destination_connection_id_bytes,
-      sizeof(destination_connection_id_bytes)));
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", packet, sizeof(packet),
-      reinterpret_cast<const char*>(expected_packet), sizeof(expected_packet));
-  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
-                                sizeof(packet), false);
-  if (!framer_.version().HasLengthPrefixedConnectionIds()) {
-    // We can only parse the connection ID with a parser expecting
-    // length-prefixed connection IDs.
-    EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-    return;
-  }
-  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
-  ASSERT_TRUE(visitor_.header_.get());
-  QuicConnectionId probe_payload_connection_id(
-      reinterpret_cast<const char*>(destination_connection_id_bytes),
-      sizeof(destination_connection_id_bytes));
-  EXPECT_EQ(probe_payload_connection_id,
-            visitor_.header_.get()->destination_connection_id);
-}
-
-TEST_P(QuicFramerTest, DispatcherParseOldClientVersionNegotiationProbePacket) {
-  // clang-format off
-  static const uint8_t packet[1200] = {
-    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
-    0xc0,
-    // Version, part of the IETF space reserved for negotiation.
-    0xca, 0xba, 0xda, 0xba,
-    // Destination connection ID length 8, source connection ID length 0.
-    0x50,
-    // 8-byte destination connection ID.
-    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
-    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
-    // not parse with any known version.
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    // 2 bytes of zeroes to pad to 16 byte boundary.
-    0x00, 0x00,
-    // A polite greeting in case a human sees this in tcpdump.
-    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
-    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
-    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
-    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
-    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
-    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
-    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
-    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
-    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
-    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
-    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
-    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
-    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
-    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
-    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
-    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
-    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
-    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
-    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
-    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
-    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
-    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
-  };
-  // clang-format on
-  char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                                     0x6c, 0x7a, 0x20, 0x21};
-  QuicConnectionId expected_destination_connection_id(
-      reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
-      sizeof(expected_destination_connection_id_bytes));
-
-  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
-                                sizeof(packet));
-  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  bool version_present = false, has_length_prefix = true;
-  QuicVersionLabel version_label = 33;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  QuicConnectionId destination_connection_id = TestConnectionId(1);
-  QuicConnectionId source_connection_id = TestConnectionId(2);
-  absl::optional<absl::string_view> retry_token;
-  std::string detailed_error = "foobar";
-  QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
-      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  EXPECT_THAT(header_parse_result, IsQuicNoError());
-  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-  EXPECT_TRUE(version_present);
-  EXPECT_FALSE(has_length_prefix);
-  EXPECT_EQ(0xcabadaba, version_label);
-  EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
-  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_FALSE(retry_token.has_value());
-  EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, DispatcherParseClientVersionNegotiationProbePacket) {
-  // clang-format off
-  static const uint8_t packet[1200] = {
-    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
-    0xc0,
-    // Version, part of the IETF space reserved for negotiation.
-    0xca, 0xba, 0xda, 0xba,
-    // Destination connection ID length 8.
-    0x08,
-    // 8-byte destination connection ID.
-    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
-    // Source connection ID length 0.
-    0x00,
-    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
-    // not parse with any known version.
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    // 1 byte of zeroes to pad to 16 byte boundary.
-    0x00,
-    // A polite greeting in case a human sees this in tcpdump.
-    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
-    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
-    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
-    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
-    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
-    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
-    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
-    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
-    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
-    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
-    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
-    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
-    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
-    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
-    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
-    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
-    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
-    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
-    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
-    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
-    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
-    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
-  };
-  // clang-format on
-  char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                                     0x6c, 0x7a, 0x20, 0x21};
-  QuicConnectionId expected_destination_connection_id(
-      reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
-      sizeof(expected_destination_connection_id_bytes));
-
-  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
-                                sizeof(packet));
-  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
-  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  bool version_present = false, has_length_prefix = false;
-  QuicVersionLabel version_label = 33;
-  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
-  QuicConnectionId destination_connection_id = TestConnectionId(1);
-  QuicConnectionId source_connection_id = TestConnectionId(2);
-  absl::optional<absl::string_view> retry_token;
-  std::string detailed_error = "foobar";
-  QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
-      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-      &version_present, &has_length_prefix, &version_label, &parsed_version,
-      &destination_connection_id, &source_connection_id, &retry_token,
-      &detailed_error);
-  EXPECT_THAT(header_parse_result, IsQuicNoError());
-  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
-  EXPECT_TRUE(version_present);
-  EXPECT_TRUE(has_length_prefix);
-  EXPECT_EQ(0xcabadaba, version_label);
-  EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
-  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponse) {
-  // clang-format off
-  const uint8_t packet[] = {
-    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
-    0xc0,
-    // Version of 0, indicating version negotiation.
-    0x00, 0x00, 0x00, 0x00,
-    // Destination connection ID length 0, source connection ID length 8.
-    0x00, 0x08,
-    // 8-byte source connection ID.
-    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
-    // A few supported versions.
-    0xaa, 0xaa, 0xaa, 0xaa,
-    QUIC_VERSION_BYTES,
-  };
-  // clang-format on
-  char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21};
-  char parsed_probe_payload_bytes[255] = {};
-  uint8_t parsed_probe_payload_length = sizeof(parsed_probe_payload_bytes);
-  std::string parse_detailed_error = "";
-  EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
-      reinterpret_cast<const char*>(packet), sizeof(packet),
-      reinterpret_cast<char*>(parsed_probe_payload_bytes),
-      &parsed_probe_payload_length, &parse_detailed_error));
-  EXPECT_EQ("", parse_detailed_error);
-  quiche::test::CompareCharArraysWithHexError(
-      "parsed probe", parsed_probe_payload_bytes, parsed_probe_payload_length,
-      probe_payload_bytes, sizeof(probe_payload_bytes));
-}
-
-TEST_P(QuicFramerTest, ParseClientVersionNegotiationProbePacket) {
-  char packet[1200];
-  char input_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                                  0x6c, 0x7a, 0x20, 0x21};
-  ASSERT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
-      packet, sizeof(packet), input_destination_connection_id_bytes,
-      sizeof(input_destination_connection_id_bytes)));
-  char parsed_destination_connection_id_bytes[255] = {0};
-  uint8_t parsed_destination_connection_id_length =
-      sizeof(parsed_destination_connection_id_bytes);
-  ASSERT_TRUE(ParseClientVersionNegotiationProbePacket(
-      packet, sizeof(packet), parsed_destination_connection_id_bytes,
-      &parsed_destination_connection_id_length));
-  quiche::test::CompareCharArraysWithHexError(
-      "parsed destination connection ID",
-      parsed_destination_connection_id_bytes,
-      parsed_destination_connection_id_length,
-      input_destination_connection_id_bytes,
-      sizeof(input_destination_connection_id_bytes));
-}
-
-TEST_P(QuicFramerTest, WriteServerVersionNegotiationProbeResponse) {
-  char packet[1200];
-  size_t packet_length = sizeof(packet);
-  char input_source_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
-                                             0x6c, 0x7a, 0x20, 0x21};
-  ASSERT_TRUE(WriteServerVersionNegotiationProbeResponse(
-      packet, &packet_length, input_source_connection_id_bytes,
-      sizeof(input_source_connection_id_bytes)));
-  char parsed_source_connection_id_bytes[255] = {0};
-  uint8_t parsed_source_connection_id_length =
-      sizeof(parsed_source_connection_id_bytes);
-  std::string detailed_error;
-  ASSERT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
-      packet, packet_length, parsed_source_connection_id_bytes,
-      &parsed_source_connection_id_length, &detailed_error))
-      << detailed_error;
-  quiche::test::CompareCharArraysWithHexError(
-      "parsed destination connection ID", parsed_source_connection_id_bytes,
-      parsed_source_connection_id_length, input_source_connection_id_bytes,
-      sizeof(input_source_connection_id_bytes));
-}
-
-TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    // This test requires an IETF long header.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // connection ID lengths
-    0x50,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frame
-    0x00,
-  };
-  unsigned char packet49[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length
-    0x00,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    ReviseFirstByteByVersion(packet49);
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  }
-  const bool parse_success =
-      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
-  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
-    EXPECT_FALSE(parse_success);
-    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-    EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
-    return;
-  }
-  EXPECT_TRUE(parse_success);
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  EXPECT_EQ("", framer_.detailed_error());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_.get()->destination_connection_id);
-}
-
-TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToServer) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    // This test requires an IETF long header.
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // connection ID lengths
-    0x05,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frame
-    0x00,
-  };
-  unsigned char packet49[] = {
-    // public flags (long header with packet type HANDSHAKE and
-    // 4-byte packet number)
-    0xE3,
-    // version
-    QUIC_VERSION_BYTES,
-    // connection ID lengths
-    0x00, 0x08,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // padding frame
-    0x00,
-  };
-  // clang-format on
-  unsigned char* p = packet;
-  size_t p_length = ABSL_ARRAYSIZE(packet);
-  if (framer_.version().HasLongHeaderLengths()) {
-    ReviseFirstByteByVersion(packet49);
-    p = packet49;
-    p_length = ABSL_ARRAYSIZE(packet49);
-  }
-  const bool parse_success =
-      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
-  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
-    EXPECT_FALSE(parse_success);
-    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-    EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
-    return;
-  }
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    EXPECT_FALSE(parse_success);
-    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
-    EXPECT_EQ("Client connection ID not supported in this version.",
-              framer_.detailed_error());
-    return;
-  }
-  EXPECT_TRUE(parse_success);
-  EXPECT_THAT(framer_.error(), IsQuicNoError());
-  EXPECT_EQ("", framer_.detailed_error());
-  ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(FramerTestConnectionId(),
-            visitor_.header_.get()->source_connection_id);
-}
-
-TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthClient) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    // This test requires an IETF long header.
-    return;
-  }
-  char connection_id_lengths = 0x05;
-  QuicDataReader reader(&connection_id_lengths, 1);
-
-  bool should_update_expected_server_connection_id_length = false;
-  uint8_t expected_server_connection_id_length = 8;
-  uint8_t destination_connection_id_length = 0;
-  uint8_t source_connection_id_length = 8;
-  std::string detailed_error = "";
-
-  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
-      &reader, framer_.version(), Perspective::IS_CLIENT,
-      should_update_expected_server_connection_id_length,
-      &expected_server_connection_id_length, &destination_connection_id_length,
-      &source_connection_id_length, &detailed_error));
-  EXPECT_EQ(8, expected_server_connection_id_length);
-  EXPECT_EQ(0, destination_connection_id_length);
-  EXPECT_EQ(8, source_connection_id_length);
-  EXPECT_EQ("", detailed_error);
-
-  QuicDataReader reader2(&connection_id_lengths, 1);
-  should_update_expected_server_connection_id_length = true;
-  expected_server_connection_id_length = 33;
-  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
-      &reader2, framer_.version(), Perspective::IS_CLIENT,
-      should_update_expected_server_connection_id_length,
-      &expected_server_connection_id_length, &destination_connection_id_length,
-      &source_connection_id_length, &detailed_error));
-  EXPECT_EQ(8, expected_server_connection_id_length);
-  EXPECT_EQ(0, destination_connection_id_length);
-  EXPECT_EQ(8, source_connection_id_length);
-  EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthServer) {
-  if (!framer_.version().HasIetfInvariantHeader()) {
-    // This test requires an IETF long header.
-    return;
-  }
-  char connection_id_lengths = 0x50;
-  QuicDataReader reader(&connection_id_lengths, 1);
-
-  bool should_update_expected_server_connection_id_length = false;
-  uint8_t expected_server_connection_id_length = 8;
-  uint8_t destination_connection_id_length = 8;
-  uint8_t source_connection_id_length = 0;
-  std::string detailed_error = "";
-
-  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
-      &reader, framer_.version(), Perspective::IS_SERVER,
-      should_update_expected_server_connection_id_length,
-      &expected_server_connection_id_length, &destination_connection_id_length,
-      &source_connection_id_length, &detailed_error));
-  EXPECT_EQ(8, expected_server_connection_id_length);
-  EXPECT_EQ(8, destination_connection_id_length);
-  EXPECT_EQ(0, source_connection_id_length);
-  EXPECT_EQ("", detailed_error);
-
-  QuicDataReader reader2(&connection_id_lengths, 1);
-  should_update_expected_server_connection_id_length = true;
-  expected_server_connection_id_length = 33;
-  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
-      &reader2, framer_.version(), Perspective::IS_SERVER,
-      should_update_expected_server_connection_id_length,
-      &expected_server_connection_id_length, &destination_connection_id_length,
-      &source_connection_id_length, &detailed_error));
-  EXPECT_EQ(8, expected_server_connection_id_length);
-  EXPECT_EQ(8, destination_connection_id_length);
-  EXPECT_EQ(0, source_connection_id_length);
-  EXPECT_EQ("", detailed_error);
-}
-
-TEST_P(QuicFramerTest, TestExtendedErrorCodeParser) {
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    // Extended error codes only in IETF QUIC
-    return;
-  }
-  QuicConnectionCloseFrame frame;
-
-  frame.error_details = "this has no error code info in it";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ("this has no error code info in it", frame.error_details);
-
-  frame.error_details = "1234this does not have the colon in it";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ("1234this does not have the colon in it", frame.error_details);
-
-  frame.error_details = "1a234:this has a colon, but a malformed error number";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ("1a234:this has a colon, but a malformed error number",
-            frame.error_details);
-
-  frame.error_details = "1234:this is good";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_EQ(1234u, frame.quic_error_code);
-  EXPECT_EQ("this is good", frame.error_details);
-
-  frame.error_details =
-      "1234 :this is not good, space between last digit and colon";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ("1234 :this is not good, space between last digit and colon",
-            frame.error_details);
-
-  frame.error_details = "123456789";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(
-      frame.quic_error_code,
-      IsError(QUIC_IETF_GQUIC_ERROR_MISSING));  // Not good, all numbers, no :
-  EXPECT_EQ("123456789", frame.error_details);
-
-  frame.error_details = "1234:";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_EQ(1234u,
-            frame.quic_error_code);  // corner case.
-  EXPECT_EQ("", frame.error_details);
-
-  frame.error_details = "1234:5678";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_EQ(1234u,
-            frame.quic_error_code);  // another corner case.
-  EXPECT_EQ("5678", frame.error_details);
-
-  frame.error_details = "12345 6789:";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code,
-              IsError(QUIC_IETF_GQUIC_ERROR_MISSING));  // Not good
-  EXPECT_EQ("12345 6789:", frame.error_details);
-
-  frame.error_details = ":no numbers, is not good";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ(":no numbers, is not good", frame.error_details);
-
-  frame.error_details = "qwer:also no numbers, is not good";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ("qwer:also no numbers, is not good", frame.error_details);
-
-  frame.error_details = " 1234:this is not good, space before first digit";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
-  EXPECT_EQ(" 1234:this is not good, space before first digit",
-            frame.error_details);
-
-  frame.error_details = "1234:";
-  MaybeExtractQuicErrorCode(&frame);
-  EXPECT_EQ(1234u,
-            frame.quic_error_code);  // this is good
-  EXPECT_EQ("", frame.error_details);
-}
-
-// Regression test for crbug/1029636.
-TEST_P(QuicFramerTest, OverlyLargeAckDelay) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
-  // clang-format off
-  unsigned char packet_ietf[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_ACK frame)
-    0x02,
-    // largest acked
-    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
-    // ack delay time.
-    kVarInt62EightBytes + 0x31, 0x00, 0x00, 0x00, 0xF3, 0xA0, 0x81, 0xE0,
-    // Nr. of additional ack blocks
-    kVarInt62OneByte + 0x00,
-    // first ack block length.
-    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
-  };
-  // clang-format on
-
-  framer_.ProcessPacket(QuicEncryptedPacket(
-      AsChars(packet_ietf), ABSL_ARRAYSIZE(packet_ietf), false));
-  ASSERT_EQ(1u, visitor_.ack_frames_.size());
-  // Verify ack_delay_time is set correctly.
-  EXPECT_EQ(QuicTime::Delta::Infinite(),
-            visitor_.ack_frames_[0]->ack_delay_time);
-}
-
-TEST_P(QuicFramerTest, KeyUpdate) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  // Processed valid packet with phase=0, key=1: no key update.
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(0, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  // Processed valid packet with phase=1, key=2: key update should have
-  // occurred.
-  ASSERT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[0]);
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  // Processed another valid packet with phase=1, key=2: no key update.
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process another key update.
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 2, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  ASSERT_EQ(2u, visitor_.key_update_count());
-  EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[1]);
-  EXPECT_EQ(2, visitor_.derive_next_key_count_);
-  EXPECT_EQ(3, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterUpdate) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // Process packet N with phase 0.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(0, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+2 with phase 1.
-  header.packet_number = kPacketNumber + 2;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+1 with phase 0. (Receiving packet from previous phase
-  // after packet from new phase was received.)
-  header.packet_number = kPacketNumber + 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should decrypt and key update count should not change.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterDiscardPreviousOneRttKeys) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // Process packet N with phase 0.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(0, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+2 with phase 1.
-  header.packet_number = kPacketNumber + 2;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Discard keys for previous key phase.
-  framer_.DiscardPreviousOneRttKeys();
-
-  // Process packet N+1 with phase 0. (Receiving packet from previous phase
-  // after packet from new phase was received.)
-  header.packet_number = kPacketNumber + 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should not decrypt and key update count should not change.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdatePacketsOutOfOrder) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // Process packet N with phase 0.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(0, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+2 with phase 1.
-  header.packet_number = kPacketNumber + 2;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+1 with phase 1. (Receiving packet from new phase out of
-  // order.)
-  header.packet_number = kPacketNumber + 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should decrypt and key update count should not change.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateWrongKey) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 0, false));
-  ASSERT_TRUE(encrypted);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  // Processed valid packet with phase=0, key=1: no key update.
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(0, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-  EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 2, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet with phase=1 but key=3, should not process and should not cause key
-  // update, but next decrypter key should have been created to attempt to
-  // decode it.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-  EXPECT_EQ(1u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet with phase=1 but key=1, should not process and should not cause key
-  // update.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-  EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet with phase=0 but key=2, should not process and should not cause key
-  // update.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-  EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
-
-  header.packet_number += 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet with phase=0 and key=0, should process and reset
-  // potential_peer_key_update_attempt_count_.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-  EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
-}
-
-TEST_P(QuicFramerTest, KeyUpdateReceivedWhenNotEnabled) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 1, true));
-  ASSERT_TRUE(encrypted);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Received a packet with key phase updated even though framer hasn't had key
-  // update enabled (SetNextOneRttCrypters never called). Should fail to
-  // process.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(0u, visitor_.key_update_count());
-  EXPECT_EQ(0, visitor_.derive_next_key_count_);
-  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateLocallyInitiated) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
-  // Key update count should be updated, but haven't received packet from peer
-  // with new key phase.
-  ASSERT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(KeyUpdateReason::kLocalForTests, visitor_.key_update_reasons_[0]);
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // Process packet N with phase 1.
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, 1, true));
-  ASSERT_TRUE(encrypted);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should decrypt and key update count should not change and
-  // OnDecryptedFirstPacketInKeyPhase should have been called.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N-1 with phase 0. (Receiving packet from previous phase
-  // after packet from new phase was received.)
-  header.packet_number = kPacketNumber - 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should decrypt and key update count should not change.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+1 with phase 0 and key 1. This should not decrypt even
-  // though it's using the previous key, since the packet number is higher than
-  // a packet number received using the current key.
-  header.packet_number = kPacketNumber + 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should not decrypt and key update count should not change.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(2, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateLocallyInitiatedReceivedOldPacket) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
-  // Key update count should be updated, but haven't received packet
-  // from peer with new key phase.
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  // Process packet N with phase 0. (Receiving packet from previous phase
-  // after locally initiated key update, but before any packet from new phase
-  // was received.)
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted =
-      EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should decrypt and key update count should not change and
-  // OnDecryptedFirstPacketInKeyPhase should not have been called since the
-  // packet was from the previous key phase.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+1 with phase 1.
-  header.packet_number = kPacketNumber + 1;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should decrypt and key update count should not change, but
-  // OnDecryptedFirstPacketInKeyPhase should have been called.
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-
-  // Process packet N+2 with phase 0 and key 1. This should not decrypt even
-  // though it's using the previous key, since the packet number is higher than
-  // a packet number received using the current key.
-  header.packet_number = kPacketNumber + 2;
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  data = BuildDataPacket(header, frames);
-  ASSERT_TRUE(data != nullptr);
-  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
-  ASSERT_TRUE(encrypted);
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  // Packet should not decrypt and key update count should not change.
-  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(2, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, KeyUpdateOnFirstReceivedPacket) {
-  if (!framer_.version().UsesTls()) {
-    // Key update is only used in QUIC+TLS.
-    return;
-  }
-  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
-  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
-  // instead of TestDecrypter.
-  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
-  framer_.SetKeyUpdateSupportForConnection(true);
-
-  QuicPacketHeader header;
-  header.destination_connection_id = FramerTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = QuicPacketNumber(123);
-
-  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
-  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
-  ASSERT_TRUE(data != nullptr);
-  std::unique_ptr<QuicEncryptedPacket> encrypted(
-      EncryptPacketWithTagAndPhase(*data, /*tag=*/1, /*phase=*/true));
-  ASSERT_TRUE(encrypted);
-
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
-  // Processed valid packet with phase=1, key=1: do key update.
-  EXPECT_EQ(1u, visitor_.key_update_count());
-  EXPECT_EQ(1, visitor_.derive_next_key_count_);
-  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
-}
-
-TEST_P(QuicFramerTest, ErrorWhenUnexpectedFrameTypeEncountered) {
-  if (!VersionHasIetfQuicFrames(framer_.transport_version()) ||
-      !QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
-      !framer_.version().HasLongHeaderLengths()) {
-    return;
-  }
-  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (long header with packet type ZERO_RTT_PROTECTED and
-    // 4-byte packet number)
-    0xD3,
-    // version
-    QUIC_VERSION_BYTES,
-    // destination connection ID length
-    0x08,
-    // destination connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // source connection ID length
-    0x08,
-    // source connection ID
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
-    // long header packet length
-    0x05,
-    // packet number
-    0x12, 0x34, 0x56, 0x00,
-    // unexpected ietf ack frame type in 0-RTT packet
-    0x02,
-  };
-  // clang-format on
-
-  ReviseFirstByteByVersion(packet);
-  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
-
-  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
-
-  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
-  EXPECT_EQ(
-      "IETF frame type IETF_ACK is unexpected at encryption level "
-      "ENCRYPTION_ZERO_RTT",
-      framer_.detailed_error());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_idle_network_detector.cc b/quic/core/quic_idle_network_detector.cc
deleted file mode 100644
index fceb1e7..0000000
--- a/quic/core/quic_idle_network_detector.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_idle_network_detector.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-
-class AlarmDelegate : public QuicAlarm::DelegateWithContext {
- public:
-  explicit AlarmDelegate(QuicIdleNetworkDetector* detector,
-                         QuicConnectionContext* context)
-      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
-  AlarmDelegate(const AlarmDelegate&) = delete;
-  AlarmDelegate& operator=(const AlarmDelegate&) = delete;
-
-  void OnAlarm() override { detector_->OnAlarm(); }
-
- private:
-  QuicIdleNetworkDetector* detector_;
-};
-
-}  // namespace
-
-QuicIdleNetworkDetector::QuicIdleNetworkDetector(
-    Delegate* delegate, QuicTime now, QuicConnectionArena* arena,
-    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
-    : delegate_(delegate),
-      start_time_(now),
-      handshake_timeout_(QuicTime::Delta::Infinite()),
-      time_of_last_received_packet_(now),
-      time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
-      idle_network_timeout_(QuicTime::Delta::Infinite()),
-      alarm_(alarm_factory->CreateAlarm(
-          arena->New<AlarmDelegate>(this, context), arena)) {}
-
-void QuicIdleNetworkDetector::OnAlarm() {
-  if (handshake_timeout_.IsInfinite()) {
-    delegate_->OnIdleNetworkDetected();
-    return;
-  }
-  if (idle_network_timeout_.IsInfinite()) {
-    delegate_->OnHandshakeTimeout();
-    return;
-  }
-  if (last_network_activity_time() + idle_network_timeout_ >
-      start_time_ + handshake_timeout_) {
-    delegate_->OnHandshakeTimeout();
-    return;
-  }
-  delegate_->OnIdleNetworkDetected();
-}
-
-void QuicIdleNetworkDetector::SetTimeouts(
-    QuicTime::Delta handshake_timeout,
-    QuicTime::Delta idle_network_timeout) {
-  handshake_timeout_ = handshake_timeout;
-  idle_network_timeout_ = idle_network_timeout;
-
-  SetAlarm();
-}
-
-void QuicIdleNetworkDetector::StopDetection() {
-  alarm_->PermanentCancel();
-  handshake_timeout_ = QuicTime::Delta::Infinite();
-  idle_network_timeout_ = QuicTime::Delta::Infinite();
-  stopped_ = true;
-}
-
-void QuicIdleNetworkDetector::OnPacketSent(QuicTime now,
-                                           QuicTime::Delta pto_delay) {
-  if (time_of_first_packet_sent_after_receiving_ >
-      time_of_last_received_packet_) {
-    return;
-  }
-  time_of_first_packet_sent_after_receiving_ =
-      std::max(time_of_first_packet_sent_after_receiving_, now);
-  if (shorter_idle_timeout_on_sent_packet_) {
-    MaybeSetAlarmOnSentPacket(pto_delay);
-    return;
-  }
-
-  SetAlarm();
-}
-
-void QuicIdleNetworkDetector::OnPacketReceived(QuicTime now) {
-  time_of_last_received_packet_ = std::max(time_of_last_received_packet_, now);
-
-  SetAlarm();
-}
-
-void QuicIdleNetworkDetector::SetAlarm() {
-  if (stopped_) {
-    // TODO(wub): If this QUIC_BUG fires, it indicates a problem in the
-    // QuicConnection, which somehow called this function while disconnected.
-    // That problem needs to be fixed.
-    QUIC_BUG(quic_idle_detector_set_alarm_after_stopped)
-        << "SetAlarm called after stopped";
-    return;
-  }
-  // Set alarm to the nearer deadline.
-  QuicTime new_deadline = QuicTime::Zero();
-  if (!handshake_timeout_.IsInfinite()) {
-    new_deadline = start_time_ + handshake_timeout_;
-  }
-  if (!idle_network_timeout_.IsInfinite()) {
-    const QuicTime idle_network_deadline = GetIdleNetworkDeadline();
-    if (new_deadline.IsInitialized()) {
-      new_deadline = std::min(new_deadline, idle_network_deadline);
-    } else {
-      new_deadline = idle_network_deadline;
-    }
-  }
-  alarm_->Update(new_deadline, kAlarmGranularity);
-}
-
-void QuicIdleNetworkDetector::MaybeSetAlarmOnSentPacket(
-    QuicTime::Delta pto_delay) {
-  QUICHE_DCHECK(shorter_idle_timeout_on_sent_packet_);
-  if (!handshake_timeout_.IsInfinite() || !alarm_->IsSet()) {
-    SetAlarm();
-    return;
-  }
-  // Make sure connection will be alive for another PTO.
-  const QuicTime deadline = alarm_->deadline();
-  const QuicTime min_deadline = last_network_activity_time() + pto_delay;
-  if (deadline > min_deadline) {
-    return;
-  }
-  alarm_->Update(min_deadline, kAlarmGranularity);
-}
-
-QuicTime QuicIdleNetworkDetector::GetIdleNetworkDeadline() const {
-  if (idle_network_timeout_.IsInfinite()) {
-    return QuicTime::Zero();
-  }
-  return last_network_activity_time() + idle_network_timeout_;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_idle_network_detector.h b/quic/core/quic_idle_network_detector.h
deleted file mode 100644
index 2381c12..0000000
--- a/quic/core/quic_idle_network_detector.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
-#define QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionPeer;
-class QuicIdleNetworkDetectorTestPeer;
-}  // namespace test
-
-// QuicIdleNetworkDetector detects handshake timeout and idle network timeout.
-// Handshake timeout detection is disabled after handshake completes. Idle
-// network deadline is extended by network activity (e.g., sending or receiving
-// packets).
-class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
- public:
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // Called when handshake times out.
-    virtual void OnHandshakeTimeout() = 0;
-
-    // Called when idle network has been detected.
-    virtual void OnIdleNetworkDetected() = 0;
-  };
-
-  QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
-                          QuicConnectionArena* arena,
-                          QuicAlarmFactory* alarm_factory,
-                          QuicConnectionContext* context);
-
-  void OnAlarm();
-
-  // Called to set handshake_timeout_ and idle_network_timeout_.
-  void SetTimeouts(QuicTime::Delta handshake_timeout,
-                   QuicTime::Delta idle_network_timeout);
-
-  // Stop the detection once and for all.
-  void StopDetection();
-
-  // Called when a packet gets sent.
-  void OnPacketSent(QuicTime now, QuicTime::Delta pto_delay);
-
-  // Called when a packet gets received.
-  void OnPacketReceived(QuicTime now);
-
-  void enable_shorter_idle_timeout_on_sent_packet() {
-    shorter_idle_timeout_on_sent_packet_ = true;
-  }
-
-  QuicTime::Delta handshake_timeout() const { return handshake_timeout_; }
-
-  QuicTime time_of_last_received_packet() const {
-    return time_of_last_received_packet_;
-  }
-
-  QuicTime last_network_activity_time() const {
-    return std::max(time_of_last_received_packet_,
-                    time_of_first_packet_sent_after_receiving_);
-  }
-
-  QuicTime::Delta idle_network_timeout() const { return idle_network_timeout_; }
-
-  QuicTime GetIdleNetworkDeadline() const;
-
- private:
-  friend class test::QuicConnectionPeer;
-  friend class test::QuicIdleNetworkDetectorTestPeer;
-
-  void SetAlarm();
-
-  void MaybeSetAlarmOnSentPacket(QuicTime::Delta pto_delay);
-
-  Delegate* delegate_;  // Not owned.
-
-  // Start time of the detector, handshake deadline = start_time_ +
-  // handshake_timeout_.
-  const QuicTime start_time_;
-
-  // Handshake timeout. Infinit means handshake has completed.
-  QuicTime::Delta handshake_timeout_;
-
-  // Time that last packet is received for this connection. Initialized to
-  // start_time_.
-  QuicTime time_of_last_received_packet_;
-
-  // Time that the first packet gets sent after the received packet. idle
-  // network deadline = std::max(time_of_last_received_packet_,
-  // time_of_first_packet_sent_after_receiving_) + idle_network_timeout_.
-  // Initialized to 0.
-  QuicTime time_of_first_packet_sent_after_receiving_;
-
-  // Idle network timeout. Infinit means no idle network timeout.
-  QuicTime::Delta idle_network_timeout_;
-
-  QuicArenaScopedPtr<QuicAlarm> alarm_;
-
-  bool shorter_idle_timeout_on_sent_packet_ = false;
-
-  // Whether |StopDetection| has been called.
-  bool stopped_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
diff --git a/quic/core/quic_idle_network_detector_test.cc b/quic/core/quic_idle_network_detector_test.cc
deleted file mode 100644
index a6fd5d2..0000000
--- a/quic/core/quic_idle_network_detector_test.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_idle_network_detector.h"
-
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class QuicIdleNetworkDetectorTestPeer {
- public:
-  static QuicAlarm* GetAlarm(QuicIdleNetworkDetector* detector) {
-    return detector->alarm_.get();
-  }
-};
-
-namespace {
-
-class MockDelegate : public QuicIdleNetworkDetector::Delegate {
- public:
-  MOCK_METHOD(void, OnHandshakeTimeout, (), (override));
-  MOCK_METHOD(void, OnIdleNetworkDetected, (), (override));
-};
-
-class QuicIdleNetworkDetectorTest : public QuicTest {
- public:
-  QuicIdleNetworkDetectorTest() {
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    detector_ = std::make_unique<QuicIdleNetworkDetector>(
-        &delegate_, clock_.Now(), &arena_, &alarm_factory_,
-        /*context=*/nullptr);
-    alarm_ = static_cast<MockAlarmFactory::TestAlarm*>(
-        QuicIdleNetworkDetectorTestPeer::GetAlarm(detector_.get()));
-  }
-
- protected:
-  testing::StrictMock<MockDelegate> delegate_;
-  QuicConnectionArena arena_;
-  MockAlarmFactory alarm_factory_;
-
-  std::unique_ptr<QuicIdleNetworkDetector> detector_;
-
-  MockAlarmFactory::TestAlarm* alarm_;
-  MockClock clock_;
-};
-
-TEST_F(QuicIdleNetworkDetectorTest,
-       IdleNetworkDetectedBeforeHandshakeCompletes) {
-  EXPECT_FALSE(alarm_->IsSet());
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
-  EXPECT_TRUE(alarm_->IsSet());
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(20),
-            alarm_->deadline());
-
-  // No network activity for 20s.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
-  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
-  alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest, HandshakeTimeout) {
-  EXPECT_FALSE(alarm_->IsSet());
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
-  EXPECT_TRUE(alarm_->IsSet());
-
-  // Has network activity after 15s.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
-  detector_->OnPacketReceived(clock_.Now());
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(15),
-            alarm_->deadline());
-  // Handshake does not complete for another 15s.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
-  EXPECT_CALL(delegate_, OnHandshakeTimeout());
-  alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest,
-       IdleNetworkDetectedAfterHandshakeCompletes) {
-  EXPECT_FALSE(alarm_->IsSet());
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
-  EXPECT_TRUE(alarm_->IsSet());
-
-  // Handshake completes in 200ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
-  detector_->OnPacketReceived(clock_.Now());
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
-            alarm_->deadline());
-
-  // No network activity for 600s.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600));
-  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
-  alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest,
-       DoNotExtendIdleDeadlineOnConsecutiveSentPackets) {
-  EXPECT_FALSE(alarm_->IsSet());
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
-  EXPECT_TRUE(alarm_->IsSet());
-
-  // Handshake completes in 200ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
-  detector_->OnPacketReceived(clock_.Now());
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
-            alarm_->deadline());
-
-  // Sent packets after 200ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
-  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
-  const QuicTime packet_sent_time = clock_.Now();
-  EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
-            alarm_->deadline());
-
-  // Sent another packet after 200ms
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
-  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
-  // Verify idle network deadline does not extend.
-  EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
-            alarm_->deadline());
-
-  // No network activity for 600s.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
-                     QuicTime::Delta::FromMilliseconds(200));
-  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
-  alarm_->Fire();
-}
-
-TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
-  detector_->enable_shorter_idle_timeout_on_sent_packet();
-  detector_->SetTimeouts(
-      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
-      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(30));
-  EXPECT_TRUE(alarm_->IsSet());
-  const QuicTime deadline = alarm_->deadline();
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30), deadline);
-
-  // Send a packet after 15s and 2s PTO delay.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
-  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
-  EXPECT_TRUE(alarm_->IsSet());
-  // Verify alarm does not get extended because deadline is > PTO delay.
-  EXPECT_EQ(deadline, alarm_->deadline());
-
-  // Send another packet near timeout and 2 s PTO delay.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(14));
-  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
-  EXPECT_TRUE(alarm_->IsSet());
-  // Verify alarm does not get extended although it is shorter than PTO.
-  EXPECT_EQ(deadline, alarm_->deadline());
-
-  // Receive a packet after 1s.
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  detector_->OnPacketReceived(clock_.Now());
-  EXPECT_TRUE(alarm_->IsSet());
-  // Verify idle timeout gets extended by 30s.
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30),
-            alarm_->deadline());
-
-  // Send a packet near timeout..
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(29));
-  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
-  EXPECT_TRUE(alarm_->IsSet());
-  // Verify idle timeout gets extended by 1s.
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(2), alarm_->deadline());
-}
-
-TEST_F(QuicIdleNetworkDetectorTest, NoAlarmAfterStopped) {
-  detector_->StopDetection();
-
-  EXPECT_QUIC_BUG(
-      detector_->SetTimeouts(
-          /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
-          /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20)),
-      "SetAlarm called after stopped");
-  EXPECT_FALSE(alarm_->IsSet());
-}
-
-}  // namespace
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_interval.h b/quic/core/quic_interval.h
deleted file mode 100644
index 81a4d62..0000000
--- a/quic/core/quic_interval.h
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
-#define QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
-
-// An QuicInterval<T> is a data structure used to represent a contiguous,
-// mutable range over an ordered type T. Supported operations include testing a
-// value to see whether it is included in the QuicInterval, comparing two
-// QuicIntervals, and performing their union, intersection, and difference. For
-// the purposes of this library, an "ordered type" is any type that induces a
-// total order on its values via its less-than operator (operator<()). Examples
-// of such types are basic arithmetic types like int and double as well as class
-// types like string.
-//
-// An QuicInterval<T> is represented using the usual C++ STL convention, namely
-// as the half-open QuicInterval [min, max). A point p is considered to be
-// contained in the QuicInterval iff p >= min && p < max. One consequence of
-// this definition is that for any non-empty QuicInterval, min is contained in
-// the QuicInterval but max is not. There is no canonical representation for the
-// empty QuicInterval; rather, any QuicInterval where max <= min is regarded as
-// empty. As a consequence, two empty QuicIntervals will still compare as equal
-// despite possibly having different underlying min() or max() values. Also
-// beware of the terminology used here: the library uses the terms "min" and
-// "max" rather than "begin" and "end" as is conventional for the STL.
-//
-// T is required to be default- and copy-constructable, to have an assignment
-// operator, and the full complement of comparison operators (<, <=, ==, !=, >=,
-// >).  A difference operator (operator-()) is required if
-// QuicInterval<T>::Length is used.
-//
-// QuicInterval supports operator==. Two QuicIntervals are considered equal if
-// either they are both empty or if their corresponding min and max fields
-// compare equal. QuicInterval also provides an operator<. Unfortunately,
-// operator< is currently buggy because its behavior is inconsistent with
-// operator==: two empty ranges with different representations may be regarded
-// as equal by operator== but regarded as different by operator<. Bug 9240050
-// has been created to address this.
-//
-//
-// Examples:
-//   QuicInterval<int> r1(0, 100);  // The QuicInterval [0, 100).
-//   EXPECT_TRUE(r1.Contains(0));
-//   EXPECT_TRUE(r1.Contains(50));
-//   EXPECT_FALSE(r1.Contains(100));  // 100 is just outside the QuicInterval.
-//
-//   QuicInterval<int> r2(50, 150);  // The QuicInterval [50, 150).
-//   EXPECT_TRUE(r1.Intersects(r2));
-//   EXPECT_FALSE(r1.Contains(r2));
-//   EXPECT_TRUE(r1.IntersectWith(r2));  // Mutates r1.
-//   EXPECT_EQ(QuicInterval<int>(50, 100), r1);  // r1 is now [50, 100).
-//
-//   QuicInterval<int> r3(1000, 2000);  // The QuicInterval [1000, 2000).
-//   EXPECT_TRUE(r1.IntersectWith(r3));  // Mutates r1.
-//   EXPECT_TRUE(r1.Empty());  // Now r1 is empty.
-//   EXPECT_FALSE(r1.Contains(r1.min()));  // e.g. doesn't contain its own min.
-
-#include <stddef.h>
-#include <algorithm>
-#include <ostream>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_NO_EXPORT QuicInterval {
- private:
-  // Type trait for deriving the return type for QuicInterval::Length.  If
-  // operator-() is not defined for T, then the return type is void.  This makes
-  // the signature for Length compile so that the class can be used for such T,
-  // but code that calls Length would still generate a compilation error.
-  template <typename U>
-  class QUIC_NO_EXPORT DiffTypeOrVoid {
-   private:
-    template <typename V>
-    static auto f(const V* v) -> decltype(*v - *v);
-    template <typename V>
-    static void f(...);
-
-   public:
-    using type = typename std::decay<decltype(f<U>(nullptr))>::type;
-  };
-
- public:
-  // Construct an QuicInterval representing an empty QuicInterval.
-  QuicInterval() : min_(), max_() {}
-
-  // Construct an QuicInterval representing the QuicInterval [min, max). If min
-  // < max, the constructed object will represent the non-empty QuicInterval
-  // containing all values from min up to (but not including) max. On the other
-  // hand, if min >= max, the constructed object will represent the empty
-  // QuicInterval.
-  QuicInterval(const T& min, const T& max) : min_(min), max_(max) {}
-
-  template <typename U1,
-            typename U2,
-            typename = typename std::enable_if<
-                std::is_convertible<U1, T>::value &&
-                std::is_convertible<U2, T>::value>::type>
-  QuicInterval(U1&& min, U2&& max)
-      : min_(std::forward<U1>(min)), max_(std::forward<U2>(max)) {}
-
-  const T& min() const { return min_; }
-  const T& max() const { return max_; }
-  void SetMin(const T& t) { min_ = t; }
-  void SetMax(const T& t) { max_ = t; }
-
-  void Set(const T& min, const T& max) {
-    SetMin(min);
-    SetMax(max);
-  }
-
-  void Clear() { *this = {}; }
-
-  bool Empty() const { return min() >= max(); }
-
-  // Returns the length of this QuicInterval. The value returned is zero if
-  // Empty() is true; otherwise the value returned is max() - min().
-  typename DiffTypeOrVoid<T>::type Length() const {
-    return (Empty() ? min() : max()) - min();
-  }
-
-  // Returns true iff t >= min() && t < max().
-  bool Contains(const T& t) const { return min() <= t && max() > t; }
-
-  // Returns true iff *this and i are non-empty, and *this includes i. "*this
-  // includes i" means that for all t, if i.Contains(t) then this->Contains(t).
-  // Note the unintuitive consequence of this definition: this method always
-  // returns false when i is the empty QuicInterval.
-  bool Contains(const QuicInterval& i) const {
-    return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max();
-  }
-
-  // Returns true iff there exists some point t for which this->Contains(t) &&
-  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
-  bool Intersects(const QuicInterval& i) const {
-    return !Empty() && !i.Empty() && min() < i.max() && max() > i.min();
-  }
-
-  // Returns true iff there exists some point t for which this->Contains(t) &&
-  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
-  // Furthermore, if the intersection is non-empty and the out pointer is not
-  // null, this method stores the calculated intersection in *out.
-  bool Intersects(const QuicInterval& i, QuicInterval* out) const;
-
-  // Sets *this to be the intersection of itself with i. Returns true iff
-  // *this was modified.
-  bool IntersectWith(const QuicInterval& i);
-
-  // Returns true iff this and other have disjoint closures.  For nonempty
-  // intervals, that means there is at least one point between this and other.
-  // Roughly speaking that means the intervals don't intersect, and they are not
-  // adjacent.   Empty intervals are always separated from any other interval.
-  bool Separated(const QuicInterval& other) const {
-    if (Empty() || other.Empty())
-      return true;
-    return other.max() < min() || max() < other.min();
-  }
-
-  // Calculates the smallest QuicInterval containing both *this i, and updates
-  // *this to represent that QuicInterval, and returns true iff *this was
-  // modified.
-  bool SpanningUnion(const QuicInterval& i);
-
-  // Determines the difference between two QuicIntervals by finding all points
-  // that are contained in *this but not in i, coalesces those points into the
-  // largest possible contiguous QuicIntervals, and appends those QuicIntervals
-  // to the *difference vector. Intuitively this can be thought of as "erasing"
-  // i from *this. This will either completely erase *this (leaving nothing
-  // behind), partially erase some of *this from the left or right side (leaving
-  // some residual behind), or erase a hole in the middle of *this (leaving
-  // behind an QuicInterval on either side). Therefore, 0, 1, or 2 QuicIntervals
-  // will be appended to *difference. The method returns true iff the
-  // intersection of *this and i is non-empty. The caller owns the vector and
-  // the QuicInterval* pointers inside it. The difference vector is required to
-  // be non-null.
-  bool Difference(const QuicInterval& i,
-                  std::vector<QuicInterval*>* difference) const;
-
-  // Determines the difference between two QuicIntervals as in
-  // Difference(QuicInterval&, vector*), but stores the results directly in out
-  // parameters rather than dynamically allocating an QuicInterval* and
-  // appending it to a vector. If two results are generated, the one with the
-  // smaller value of min() will be stored in *lo and the other in *hi.
-  // Otherwise (if fewer than two results are generated), unused arguments will
-  // be set to the empty QuicInterval (it is possible that *lo will be empty and
-  // *hi non-empty). The method returns true iff the intersection of *this and i
-  // is non-empty.
-  bool Difference(const QuicInterval& i,
-                  QuicInterval* lo,
-                  QuicInterval* hi) const;
-
-  friend bool operator==(const QuicInterval& a, const QuicInterval& b) {
-    bool ae = a.Empty();
-    bool be = b.Empty();
-    if (ae && be)
-      return true;  // All empties are equal.
-    if (ae != be)
-      return false;  // Empty cannot equal nonempty.
-    return a.min() == b.min() && a.max() == b.max();
-  }
-
-  friend bool operator!=(const QuicInterval& a, const QuicInterval& b) {
-    return !(a == b);
-  }
-
-  // Defines a comparator which can be used to induce an order on QuicIntervals,
-  // so that, for example, they can be stored in an ordered container such as
-  // std::set. The ordering is arbitrary, but does provide the guarantee that,
-  // for non-empty QuicIntervals X and Y, if X contains Y, then X <= Y.
-  // TODO(kosak): The current implementation of this comparator has a problem
-  // because the ordering it induces is inconsistent with that of Equals(). In
-  // particular, this comparator does not properly consider all empty
-  // QuicIntervals equivalent. Bug 9240050 has been created to track this.
-  friend bool operator<(const QuicInterval& a, const QuicInterval& b) {
-    return a.min() < b.min() || (!(b.min() < a.min()) && b.max() < a.max());
-  }
-
- private:
-  T min_;  // Inclusive lower bound.
-  T max_;  // Exclusive upper bound.
-};
-
-// Constructs an QuicInterval by deducing the types from the function arguments.
-template <typename T>
-QuicInterval<T> MakeQuicInterval(T&& lhs, T&& rhs) {
-  return QuicInterval<T>(std::forward<T>(lhs), std::forward<T>(rhs));
-}
-
-// Note: ideally we'd use
-//   decltype(out << "[" << i.min() << ", " << i.max() << ")")
-// as return type of the function, but as of July 2017 this triggers g++
-// "sorry, unimplemented: string literal in function template signature" error.
-template <typename T>
-auto operator<<(std::ostream& out, const QuicInterval<T>& i)
-    -> decltype(out << i.min()) {
-  return out << "[" << i.min() << ", " << i.max() << ")";
-}
-
-//==============================================================================
-// Implementation details: Clients can stop reading here.
-
-template <typename T>
-bool QuicInterval<T>::Intersects(const QuicInterval& i,
-                                 QuicInterval* out) const {
-  if (!Intersects(i))
-    return false;
-  if (out != nullptr) {
-    *out = QuicInterval(std::max(min(), i.min()), std::min(max(), i.max()));
-  }
-  return true;
-}
-
-template <typename T>
-bool QuicInterval<T>::IntersectWith(const QuicInterval& i) {
-  if (Empty())
-    return false;
-  bool modified = false;
-  if (i.min() > min()) {
-    SetMin(i.min());
-    modified = true;
-  }
-  if (i.max() < max()) {
-    SetMax(i.max());
-    modified = true;
-  }
-  return modified;
-}
-
-template <typename T>
-bool QuicInterval<T>::SpanningUnion(const QuicInterval& i) {
-  if (i.Empty())
-    return false;
-  if (Empty()) {
-    *this = i;
-    return true;
-  }
-  bool modified = false;
-  if (i.min() < min()) {
-    SetMin(i.min());
-    modified = true;
-  }
-  if (i.max() > max()) {
-    SetMax(i.max());
-    modified = true;
-  }
-  return modified;
-}
-
-template <typename T>
-bool QuicInterval<T>::Difference(const QuicInterval& i,
-                                 std::vector<QuicInterval*>* difference) const {
-  if (Empty()) {
-    // <empty> - <i> = <empty>
-    return false;
-  }
-  if (i.Empty()) {
-    // <this> - <empty> = <this>
-    difference->push_back(new QuicInterval(*this));
-    return false;
-  }
-  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
-    //            [------ this ------)
-    // [------ i ------)
-    //                 [-- result ---)
-    difference->push_back(new QuicInterval(i.max(), max()));
-    return true;
-  }
-  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
-    // [------ this ------)
-    //            [------ i ------)
-    // [- result -)
-    difference->push_back(new QuicInterval(min(), i.min()));
-    return true;
-  }
-  if (min() < i.min() && max() > i.max()) {
-    // [------- this --------)
-    //      [---- i ----)
-    // [ R1 )           [ R2 )
-    // There are two results: R1 and R2.
-    difference->push_back(new QuicInterval(min(), i.min()));
-    difference->push_back(new QuicInterval(i.max(), max()));
-    return true;
-  }
-  if (min() >= i.min() && max() <= i.max()) {
-    //   [--- this ---)
-    // [------ i --------)
-    // Intersection is <this>, so difference yields the empty QuicInterval.
-    // Nothing is appended to *difference.
-    return true;
-  }
-  // No intersection. Append <this>.
-  difference->push_back(new QuicInterval(*this));
-  return false;
-}
-
-template <typename T>
-bool QuicInterval<T>::Difference(const QuicInterval& i,
-                                 QuicInterval* lo,
-                                 QuicInterval* hi) const {
-  // Initialize *lo and *hi to empty
-  *lo = {};
-  *hi = {};
-  if (Empty())
-    return false;
-  if (i.Empty()) {
-    *lo = *this;
-    return false;
-  }
-  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
-    //            [------ this ------)
-    // [------ i ------)
-    //                 [-- result ---)
-    *hi = QuicInterval(i.max(), max());
-    return true;
-  }
-  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
-    // [------ this ------)
-    //            [------ i ------)
-    // [- result -)
-    *lo = QuicInterval(min(), i.min());
-    return true;
-  }
-  if (min() < i.min() && max() > i.max()) {
-    // [------- this --------)
-    //      [---- i ----)
-    // [ R1 )           [ R2 )
-    // There are two results: R1 and R2.
-    *lo = QuicInterval(min(), i.min());
-    *hi = QuicInterval(i.max(), max());
-    return true;
-  }
-  if (min() >= i.min() && max() <= i.max()) {
-    //   [--- this ---)
-    // [------ i --------)
-    // Intersection is <this>, so difference yields the empty QuicInterval.
-    return true;
-  }
-  *lo = *this;  // No intersection.
-  return false;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
diff --git a/quic/core/quic_interval_deque.h b/quic/core/quic_interval_deque.h
deleted file mode 100644
index 274c2e3..0000000
--- a/quic/core/quic_interval_deque.h
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
-#define QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
-
-#include <algorithm>
-
-#include "absl/types/optional.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicIntervalDequePeer;
-}  // namespace test
-
-// QuicIntervalDeque<T, C> is a templated wrapper container, wrapping random
-// access data structures. The wrapper allows items to be added to the
-// underlying container with intervals associated with each item. The intervals
-// _should_ be added already sorted and represent searchable indices. The search
-// is optimized for sequential usage.
-//
-// As the intervals are to be searched sequentially the search for the next
-// interval can be achieved in O(1), by simply remembering the last interval
-// consumed. The structure also checks for an "off-by-one" use case wherein the
-// |cached_index_| is off by one index as the caller didn't call operator |++|
-// to increment the index. Other intervals can be found in O(log(n)) as they are
-// binary searchable. A use case for this structure is packet buffering: Packets
-// are sent sequentially but can sometimes needed for retransmission. The
-// packets and their payloads are added with associated intervals representing
-// data ranges they carry. When a user asks for a particular interval it's very
-// likely they are requesting the next sequential interval, receiving it in O(1)
-// time. Updating the sequential index is done automatically through the
-// |DataAt| method and its iterator operator |++|.
-//
-// The intervals are represented using the usual C++ STL convention, namely as
-// the half-open QuicInterval [min, max). A point p is considered to be
-// contained in the QuicInterval iff p >= min && p < max. One consequence of
-// this definition is that for any non-empty QuicInterval, min is contained in
-// the QuicInterval but max is not. There is no canonical representation for the
-// empty QuicInterval; and empty intervals are forbidden from being added to
-// this container as they would be unsearchable.
-//
-// The type T is required to be copy-constructable or move-constructable. The
-// type T is also expected to have an |interval()| method returning a
-// QuicInterval<std::size> for the particular value. The type C is required to
-// be a random access container supporting the methods |pop_front|, |push_back|,
-// |operator[]|, |size|, and iterator support for |std::lower_bound| eg. a
-// |deque| or |vector|.
-//
-// The QuicIntervalDeque<T, C>, like other C++ STL random access containers,
-// doesn't have any explicit support for any equality operators.
-//
-//
-// Examples with internal state:
-//
-//   // An example class to be stored inside the Interval Deque.
-//   struct IntervalVal {
-//     const int32_t val;
-//     const size_t interval_begin, interval_end;
-//     QuicInterval<size_t> interval();
-//   };
-//   typedef IntervalVal IV;
-//   QuicIntervialDeque<IntervalValue> deque;
-//
-//   // State:
-//   //   cached_index -> None
-//   //   container -> {}
-//
-//   // Add interval items
-//   deque.PushBack(IV(val: 0, interval_begin: 0, interval_end: 10));
-//   deque.PushBack(IV(val: 1, interval_begin: 20, interval_end: 25));
-//   deque.PushBack(IV(val: 2, interval_begin: 25, interval_end: 30));
-//
-//   // State:
-//   //   cached_index -> 0
-//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-//   // Look for 0 and return [0, 10). Time: O(1)
-//   auto it = deque.DataAt(0);
-//   assert(it->val == 0);
-//   it++;  // Increment and move the |cached_index_| over [0, 10) to [20, 25).
-//   assert(it->val == 1);
-//
-//   // State:
-//   //   cached_index -> 1
-//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-//   // Look for 20 and return [20, 25). Time: O(1)
-//   auto it = deque.DataAt(20); // |cached_index_| remains unchanged.
-//   assert(it->val == 1);
-//
-//   // State:
-//   //   cached_index -> 1
-//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-//   // Look for 15 and return deque.DataEnd(). Time: O(log(n))
-//   auto it = deque.DataAt(15); // |cached_index_| remains unchanged.
-//   assert(it == deque.DataEnd());
-//
-//   // Look for 25 and return [25, 30). Time: O(1) with off-by-one.
-//   auto it = deque.DataAt(25); // |cached_index_| is updated to 2.
-//   assert(it->val == 2);
-//   it++; // |cached_index_| is set to |None| as all data has been iterated.
-//
-//
-//   // State:
-//   //   cached_index -> None
-//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
-//
-//   // Look again for 0 and return [0, 10). Time: O(log(n))
-//   auto it = deque.DataAt(0);
-//
-//
-//   deque.PopFront();  // Pop -> {0, [0, 10)}
-//
-//   // State:
-//   //   cached_index -> None
-//   //   container -> {{1, [20, 25)}, {2, [25, 30)}}
-//
-//   deque.PopFront();  // Pop -> {1, [20, 25)}
-//
-//   // State:
-//   //   cached_index -> None
-//   //   container -> {{2, [25, 30)}}
-//
-//   deque.PushBack(IV(val: 3, interval_begin: 35, interval_end: 50));
-//
-//   // State:
-//   //   cached_index -> 1
-//   //   container -> {{2, [25, 30)}, {3, [35, 50)}}
-
-template <class T, class C = QUIC_NO_EXPORT quiche::QuicheCircularDeque<T>>
-class QUIC_NO_EXPORT QuicIntervalDeque {
- public:
-  class QUIC_NO_EXPORT Iterator {
-   public:
-    // Used by |std::lower_bound|
-    using iterator_category = std::forward_iterator_tag;
-    using value_type = T;
-    using difference_type = std::ptrdiff_t;
-    using pointer = T*;
-    using reference = T&;
-
-    // Every increment of the iterator will increment the |cached_index_| if
-    // |index_| is larger than the current |cached_index_|. |index_| is bounded
-    // at |deque_.size()| and any attempt to increment above that will be
-    // ignored. Once an iterator has iterated all elements the |cached_index_|
-    // will be reset.
-    Iterator(std::size_t index, QuicIntervalDeque* deque)
-        : index_(index), deque_(deque) {}
-    // Only the ++ operator attempts to update the cached index. Other operators
-    // are used by |lower_bound| to binary search and are thus private.
-    Iterator& operator++() {
-      // Don't increment when we are at the end.
-      const std::size_t container_size = deque_->container_.size();
-      if (index_ >= container_size) {
-        QUIC_BUG(quic_bug_10862_1) << "Iterator out of bounds.";
-        return *this;
-      }
-      index_++;
-      if (deque_->cached_index_.has_value()) {
-        const std::size_t cached_index = deque_->cached_index_.value();
-        // If all items are iterated then reset the |cached_index_|
-        if (index_ == container_size) {
-          deque_->cached_index_.reset();
-        } else {
-          // Otherwise the new |cached_index_| is the max of itself and |index_|
-          if (cached_index < index_) {
-            deque_->cached_index_ = index_;
-          }
-        }
-      }
-      return *this;
-    }
-    Iterator operator++(int) {
-      Iterator copy = *this;
-      ++(*this);
-      return copy;
-    }
-    reference operator*() { return deque_->container_[index_]; }
-    reference operator*() const { return deque_->container_[index_]; }
-    pointer operator->() { return &deque_->container_[index_]; }
-    bool operator==(const Iterator& rhs) const {
-      return index_ == rhs.index_ && deque_ == rhs.deque_;
-    }
-    bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
-
-   private:
-    // A set of private operators for |std::lower_bound|
-    Iterator operator+(difference_type amount) const {
-      Iterator copy = *this;
-      copy.index_ += amount;
-      QUICHE_DCHECK(copy.index_ < copy.deque_->size());
-      return copy;
-    }
-    Iterator& operator+=(difference_type amount) {
-      index_ += amount;
-      QUICHE_DCHECK(index_ < deque_->size());
-      return *this;
-    }
-    difference_type operator-(const Iterator& rhs) const {
-      return static_cast<difference_type>(index_) -
-             static_cast<difference_type>(rhs.index_);
-    }
-
-    // |index_| is the index of the item in |*deque_|.
-    std::size_t index_;
-    // |deque_| is a pointer to the container the iterator came from.
-    QuicIntervalDeque* deque_;
-
-    friend class QuicIntervalDeque;
-  };
-
-  QuicIntervalDeque();
-
-  // Adds an item to the underlying container. The |item|'s interval _should_ be
-  // strictly greater than the last interval added.
-  void PushBack(T&& item);
-  void PushBack(const T& item);
-  // Removes the front/top of the underlying container and the associated
-  // interval.
-  void PopFront();
-  // Returns an iterator to the beginning of the data. The iterator will move
-  // the |cached_index_| as the iterator moves.
-  Iterator DataBegin();
-  // Returns an iterator to the end of the data.
-  Iterator DataEnd();
-  // Returns an iterator pointing to the item in |interval_begin|. The iterator
-  // will move the |cached_index_| as the iterator moves.
-  Iterator DataAt(const std::size_t interval_begin);
-
-  // Returns the number of items contained inside the structure.
-  std::size_t Size() const;
-  // Returns whether the structure is empty.
-  bool Empty() const;
-
- private:
-  struct QUIC_NO_EXPORT IntervalCompare {
-    bool operator()(const T& item, std::size_t interval_begin) const {
-      return item.interval().max() <= interval_begin;
-    }
-  };
-
-  template <class U>
-  void PushBackUniversal(U&& item);
-
-  Iterator Search(const std::size_t interval_begin,
-                  const std::size_t begin_index,
-                  const std::size_t end_index);
-
-  // For accessing the |cached_index_|
-  friend class test::QuicIntervalDequePeer;
-
-  C container_;
-  absl::optional<std::size_t> cached_index_;
-};
-
-template <class T, class C>
-QuicIntervalDeque<T, C>::QuicIntervalDeque() {}
-
-template <class T, class C>
-void QuicIntervalDeque<T, C>::PushBack(T&& item) {
-  PushBackUniversal(std::move(item));
-}
-
-template <class T, class C>
-void QuicIntervalDeque<T, C>::PushBack(const T& item) {
-  PushBackUniversal(item);
-}
-
-template <class T, class C>
-void QuicIntervalDeque<T, C>::PopFront() {
-  if (container_.size() == 0) {
-    QUIC_BUG(quic_bug_10862_2) << "Trying to pop from an empty container.";
-    return;
-  }
-  container_.pop_front();
-  if (container_.size() == 0) {
-    cached_index_.reset();
-  }
-  if (cached_index_.value_or(0) > 0) {
-    cached_index_ = cached_index_.value() - 1;
-  }
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator
-QuicIntervalDeque<T, C>::DataBegin() {
-  return Iterator(0, this);
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataEnd() {
-  return Iterator(container_.size(), this);
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataAt(
-    const std::size_t interval_begin) {
-  // No |cached_index_| value means all items can be searched.
-  if (!cached_index_.has_value()) {
-    return Search(interval_begin, 0, container_.size());
-  }
-
-  const std::size_t cached_index = cached_index_.value();
-  QUICHE_DCHECK(cached_index < container_.size());
-
-  const QuicInterval<size_t> cached_interval =
-      container_[cached_index].interval();
-  // Does our cached index point directly to what we want?
-  if (cached_interval.Contains(interval_begin)) {
-    return Iterator(cached_index, this);
-  }
-
-  // Are we off-by-one?
-  const std::size_t next_index = cached_index + 1;
-  if (next_index < container_.size()) {
-    if (container_[next_index].interval().Contains(interval_begin)) {
-      cached_index_ = next_index;
-      return Iterator(next_index, this);
-    }
-  }
-
-  // Small optimization:
-  // Determine if we should binary search above or below the cached interval.
-  const std::size_t cached_begin = cached_interval.min();
-  bool looking_below = interval_begin < cached_begin;
-  const std::size_t lower = looking_below ? 0 : cached_index + 1;
-  const std::size_t upper = looking_below ? cached_index : container_.size();
-  Iterator ret = Search(interval_begin, lower, upper);
-  if (ret == DataEnd()) {
-    return ret;
-  }
-  // Update the |cached_index_| to point to the higher index.
-  if (!looking_below) {
-    cached_index_ = ret.index_;
-  }
-  return ret;
-}
-
-template <class T, class C>
-std::size_t QuicIntervalDeque<T, C>::Size() const {
-  return container_.size();
-}
-
-template <class T, class C>
-bool QuicIntervalDeque<T, C>::Empty() const {
-  return container_.size() == 0;
-}
-
-template <class T, class C>
-template <class U>
-void QuicIntervalDeque<T, C>::PushBackUniversal(U&& item) {
-  QuicInterval<std::size_t> interval = item.interval();
-  // Adding an empty interval is a bug.
-  if (interval.Empty()) {
-    QUIC_BUG(quic_bug_10862_3)
-        << "Trying to save empty interval to quiche::QuicheCircularDeque.";
-    return;
-  }
-  container_.push_back(std::forward<U>(item));
-  if (!cached_index_.has_value()) {
-    cached_index_ = container_.size() - 1;
-  }
-}
-
-template <class T, class C>
-typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::Search(
-    const std::size_t interval_begin,
-    const std::size_t begin_index,
-    const std::size_t end_index) {
-  auto begin = container_.begin() + begin_index;
-  auto end = container_.begin() + end_index;
-  auto res = std::lower_bound(begin, end, interval_begin, IntervalCompare());
-  // Just because we run |lower_bound| and it didn't return |container_.end()|
-  // doesn't mean we found our desired interval.
-  if (res != end && res->interval().Contains(interval_begin)) {
-    return Iterator(std::distance(begin, res) + begin_index, this);
-  }
-  return DataEnd();
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
diff --git a/quic/core/quic_interval_deque_test.cc b/quic/core/quic_interval_deque_test.cc
deleted file mode 100644
index 71a69cc..0000000
--- a/quic/core/quic_interval_deque_test.cc
+++ /dev/null
@@ -1,360 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_interval_deque.h"
-#include <cstdint>
-#include <ostream>
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_interval_deque_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const int32_t kSize = 100;
-const std::size_t kIntervalStep = 10;
-
-}  // namespace
-
-struct TestIntervalItem {
-  int32_t val;
-  std::size_t interval_start, interval_end;
-  QuicInterval<std::size_t> interval() const {
-    return QuicInterval<std::size_t>(interval_start, interval_end);
-  }
-  TestIntervalItem(int32_t val,
-                   std::size_t interval_start,
-                   std::size_t interval_end)
-      : val(val), interval_start(interval_start), interval_end(interval_end) {}
-};
-
-using QID = QuicIntervalDeque<TestIntervalItem>;
-
-class QuicIntervalDequeTest : public QuicTest {
- public:
-  QuicIntervalDequeTest() {
-    // Add items with intervals of |kIntervalStep| size.
-    for (int32_t i = 0; i < kSize; ++i) {
-      const std::size_t interval_begin = kIntervalStep * i;
-      const std::size_t interval_end = interval_begin + kIntervalStep;
-      qid_.PushBack(TestIntervalItem(i, interval_begin, interval_end));
-    }
-  }
-
-  QID qid_;
-};
-
-// The goal of this test is to show insertion/push_back, iteration, and and
-// deletion/pop_front from the container.
-TEST_F(QuicIntervalDequeTest, InsertRemoveSize) {
-  QID qid;
-
-  EXPECT_EQ(qid.Size(), std::size_t(0));
-  qid.PushBack(TestIntervalItem(0, 0, 10));
-  EXPECT_EQ(qid.Size(), std::size_t(1));
-  qid.PushBack(TestIntervalItem(1, 10, 20));
-  EXPECT_EQ(qid.Size(), std::size_t(2));
-  qid.PushBack(TestIntervalItem(2, 20, 30));
-  EXPECT_EQ(qid.Size(), std::size_t(3));
-  qid.PushBack(TestIntervalItem(3, 30, 40));
-  EXPECT_EQ(qid.Size(), std::size_t(4));
-
-  // Advance the index all the way...
-  int32_t i = 0;
-  for (auto it = qid.DataAt(0); it != qid.DataEnd(); ++it, ++i) {
-    const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
-    EXPECT_EQ(index, i);
-    EXPECT_EQ(it->val, i);
-  }
-  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
-  EXPECT_EQ(index, -1);
-
-  qid.PopFront();
-  EXPECT_EQ(qid.Size(), std::size_t(3));
-  qid.PopFront();
-  EXPECT_EQ(qid.Size(), std::size_t(2));
-  qid.PopFront();
-  EXPECT_EQ(qid.Size(), std::size_t(1));
-  qid.PopFront();
-  EXPECT_EQ(qid.Size(), std::size_t(0));
-
-  EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show how the |DataAt| method can move the |cached_index| as the
-// iterator moves through the data.
-TEST_F(QuicIntervalDequeTest, InsertIterateWhole) {
-  // The write index should point to the beginning of the container.
-  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(cached_index, 0);
-
-  auto it = qid_.DataBegin();
-  auto end = qid_.DataEnd();
-  for (int32_t i = 0; i < kSize; ++i, ++it) {
-    EXPECT_EQ(it->val, i);
-    const std::size_t current_iteraval_begin = i * kIntervalStep;
-    // The |DataAt| method should find the correct interval.
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    EXPECT_EQ(i, lookup->val);
-    // Make sure the index hasn't changed just from using |DataAt|
-    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_before, i);
-    // This increment should move the index forward.
-    lookup++;
-    // Check that the index has changed.
-    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
-    EXPECT_EQ(index_after, after_i);
-    EXPECT_NE(it, end);
-  }
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show how the |DataAt| method can move the |cached_index| using
-// the off-by-one logic.
-TEST_F(QuicIntervalDequeTest, OffByOne) {
-  // The write index should point to the beginning of the container.
-  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(cached_index, 0);
-
-  auto it = qid_.DataBegin();
-  auto end = qid_.DataEnd();
-  for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
-    EXPECT_EQ(it->val, i);
-    const int32_t off_by_one_i = i + 1;
-    const std::size_t current_iteraval_begin = off_by_one_i * kIntervalStep;
-    // Make sure the index has changed just from using |DataAt|
-    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_before, i);
-    // The |DataAt| method should find the correct interval.
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    EXPECT_EQ(off_by_one_i, lookup->val);
-    // Check that the index has changed.
-    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    const int32_t after_i = off_by_one_i == kSize ? -1 : off_by_one_i;
-    EXPECT_EQ(index_after, after_i);
-    EXPECT_NE(it, end);
-  }
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show modify the structure with a live iterator.
-TEST_F(QuicIntervalDequeTest, IteratorInvalidation) {
-  // The write index should point to the beginning of the container.
-  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(cached_index, 0);
-
-  const std::size_t iteraval_begin = (kSize - 1) * kIntervalStep;
-  auto lookup = qid_.DataAt(iteraval_begin);
-  EXPECT_EQ((*lookup).val, (kSize - 1));
-  qid_.PopFront();
-  EXPECT_QUIC_BUG(lookup++, "Iterator out of bounds.");
-  auto lookup_end = qid_.DataAt(iteraval_begin + kIntervalStep);
-  EXPECT_EQ(lookup_end, qid_.DataEnd());
-}
-
-// The goal of this test is the same as |InsertIterateWhole| but to
-// skip certain intervals and show the |cached_index| is updated properly.
-TEST_F(QuicIntervalDequeTest, InsertIterateSkip) {
-  // The write index should point to the beginning of the container.
-  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(cached_index, 0);
-
-  const std::size_t step = 4;
-  for (int32_t i = 0; i < kSize; i += 4) {
-    if (i != 0) {
-      const int32_t before_i = (i - (step - 1));
-      EXPECT_EQ(QuicIntervalDequePeer::GetCachedIndex(&qid_), before_i);
-    }
-    const std::size_t current_iteraval_begin = i * kIntervalStep;
-    // The |DataAt| method should find the correct interval.
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    EXPECT_EQ(i, lookup->val);
-    // Make sure the index _has_ changed just from using |DataAt| since we're
-    // skipping data.
-    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_before, i);
-    // This increment should move the index forward.
-    lookup++;
-    // Check that the index has changed.
-    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
-    EXPECT_EQ(index_after, after_i);
-  }
-}
-
-// The goal of this test is the same as |InsertIterateWhole| but it has
-// |PopFront| calls interleaved to show the |cached_index| updates correctly.
-TEST_F(QuicIntervalDequeTest, InsertDeleteIterate) {
-  // The write index should point to the beginning of the container.
-  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(index, 0);
-
-  std::size_t limit = 0;
-  for (int32_t i = 0; limit < qid_.Size(); ++i, ++limit) {
-    // Always point to the beginning of the container.
-    auto it = qid_.DataBegin();
-    EXPECT_EQ(it->val, i);
-
-    // Get an iterator.
-    const std::size_t current_iteraval_begin = i * kIntervalStep;
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    // The index should always point to 0.
-    EXPECT_EQ(index_before, 0);
-    // This iterator increment should effect the index.
-    lookup++;
-    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_after, 1);
-    // Decrement the |temp_size| and pop from the front.
-    qid_.PopFront();
-    // Show the index has been updated to point to 0 again (from 1).
-    const int32_t index_after_pop =
-        QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_after_pop, 0);
-  }
-}
-
-// The goal of this test is to move the index to the end and then add more data
-// to show it can be reset to a valid index.
-TEST_F(QuicIntervalDequeTest, InsertIterateInsert) {
-  // The write index should point to the beginning of the container.
-  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(index, 0);
-
-  int32_t iterated_elements = 0;
-  for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
-    // Get an iterator.
-    const std::size_t current_iteraval_begin = i * kIntervalStep;
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    // The index should always point to i.
-    EXPECT_EQ(index_before, i);
-    // This iterator increment should effect the index.
-    lookup++;
-    // Show the index has been updated to point to i + 1 or -1 if at the end.
-    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
-    EXPECT_EQ(index_after, after_i);
-  }
-  const int32_t invalid_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(invalid_index, -1);
-
-  // Add more data to the container, making the index valid.
-  const std::size_t offset = qid_.Size();
-  for (int32_t i = 0; i < kSize; ++i) {
-    const std::size_t interval_begin = offset + (kIntervalStep * i);
-    const std::size_t interval_end = offset + interval_begin + kIntervalStep;
-    qid_.PushBack(TestIntervalItem(i + offset, interval_begin, interval_end));
-    const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    // Index should now be valid and equal to the size of the container before
-    // adding more items to it.
-    EXPECT_EQ(index_current, iterated_elements);
-  }
-  // Show the index is still valid and hasn't changed since the first iteration
-  // of the loop.
-  const int32_t index_after_add = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(index_after_add, iterated_elements);
-
-  // Iterate over all the data in the container and eventually reset the index
-  // as we did before.
-  for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
-    const std::size_t interval_begin = offset + (kIntervalStep * i);
-    const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_current, iterated_elements);
-    auto lookup = qid_.DataAt(interval_begin);
-    const int32_t expected_value = i + offset;
-    EXPECT_EQ(lookup->val, expected_value);
-    lookup++;
-    const int32_t after_inc =
-        (iterated_elements + 1) == (kSize * 2) ? -1 : (iterated_elements + 1);
-    const int32_t after_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(after_index, after_inc);
-  }
-  // Show the index is now invalid.
-  const int32_t invalid_index_again =
-      QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(invalid_index_again, -1);
-}
-
-// The goal of this test is to push data into the container at specific
-// intervals and show how the |DataAt| can iterate over already scanned data.
-TEST_F(QuicIntervalDequeTest, RescanData) {
-  // The write index should point to the beginning of the container.
-  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-  EXPECT_EQ(index, 0);
-
-  auto it = qid_.DataBegin();
-  auto end = qid_.DataEnd();
-  for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
-    EXPECT_EQ(it->val, i);
-    const std::size_t current_iteraval_begin = i * kIntervalStep;
-    // The |DataAt| method should find the correct interval.
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    EXPECT_EQ(i, lookup->val);
-    // Make sure the index has changed just from using |DataAt|
-    const int32_t cached_index_before =
-        QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(cached_index_before, i);
-    // Ensure the real index has changed just from using |DataAt| and the
-    // off-by-one logic
-    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    const int32_t before_i = i;
-    EXPECT_EQ(index_before, before_i);
-    // This increment should move the cached index forward.
-    lookup++;
-    // Check that the cached index has moved foward.
-    const int32_t cached_index_after =
-        QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    const int32_t after_i = (i + 1);
-    EXPECT_EQ(cached_index_after, after_i);
-    EXPECT_NE(it, end);
-  }
-
-  // Iterate over items which have been consumed before.
-  int32_t expected_index = static_cast<int32_t>(kSize - 1);
-  for (int32_t i = 0; i < kSize - 1; ++i) {
-    const std::size_t current_iteraval_begin = i * kIntervalStep;
-    // The |DataAt| method should find the correct interval.
-    auto lookup = qid_.DataAt(current_iteraval_begin);
-    EXPECT_EQ(i, lookup->val);
-    // This increment shouldn't move the index forward as the index is currently
-    // ahead.
-    lookup++;
-    // Check that the index hasn't moved foward.
-    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
-    EXPECT_EQ(index_after, expected_index);
-    EXPECT_NE(it, end);
-  }
-}
-
-// The goal of this test is to show that popping from an empty container is a
-// bug.
-TEST_F(QuicIntervalDequeTest, PopEmpty) {
-  QID qid;
-  EXPECT_TRUE(qid.Empty());
-  EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
-}
-
-// The goal of this test is to show that adding a zero-sized interval is a bug.
-TEST_F(QuicIntervalDequeTest, ZeroSizedInterval) {
-  QID qid;
-  EXPECT_QUIC_BUG(qid.PushBack(TestIntervalItem(0, 0, 0)),
-                  "Trying to save empty interval to .");
-}
-
-// The goal of this test is to show that an iterator to an empty container
-// returns |DataEnd|.
-TEST_F(QuicIntervalDequeTest, IteratorEmpty) {
-  QID qid;
-  auto it = qid.DataAt(0);
-  EXPECT_EQ(it, qid.DataEnd());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_interval_set.h b/quic/core/quic_interval_set.h
deleted file mode 100644
index d69fa71..0000000
--- a/quic/core/quic_interval_set.h
+++ /dev/null
@@ -1,896 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
-#define QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
-
-// QuicIntervalSet<T> is a data structure used to represent a sorted set of
-// non-empty, non-adjacent, and mutually disjoint intervals. Mutations to an
-// interval set preserve these properties, altering the set as needed. For
-// example, adding [2, 3) to a set containing only [1, 2) would result in the
-// set containing the single interval [1, 3).
-//
-// Supported operations include testing whether an Interval is contained in the
-// QuicIntervalSet, comparing two QuicIntervalSets, and performing
-// QuicIntervalSet union, intersection, and difference.
-//
-// QuicIntervalSet maintains the minimum number of entries needed to represent
-// the set of underlying intervals. When the QuicIntervalSet is modified (e.g.
-// due to an Add operation), other interval entries may be coalesced, removed,
-// or otherwise modified in order to maintain this invariant. The intervals are
-// maintained in sorted order, by ascending min() value.
-//
-// The reader is cautioned to beware of the terminology used here: this library
-// uses the terms "min" and "max" rather than "begin" and "end" as is
-// conventional for the STL. The terminology [min, max) refers to the half-open
-// interval which (if the interval is not empty) contains min but does not
-// contain max. An interval is considered empty if min >= max.
-//
-// T is required to be default- and copy-constructible, to have an assignment
-// operator, a difference operator (operator-()), and the full complement of
-// comparison operators (<, <=, ==, !=, >=, >). These requirements are inherited
-// from value_type.
-//
-// QuicIntervalSet has constant-time move operations.
-//
-//
-// Examples:
-//   QuicIntervalSet<int> intervals;
-//   intervals.Add(Interval<int>(10, 20));
-//   intervals.Add(Interval<int>(30, 40));
-//   // intervals contains [10,20) and [30,40).
-//   intervals.Add(Interval<int>(15, 35));
-//   // intervals has been coalesced. It now contains the single range [10,40).
-//   EXPECT_EQ(1, intervals.Size());
-//   EXPECT_TRUE(intervals.Contains(Interval<int>(10, 40)));
-//
-//   intervals.Difference(Interval<int>(10, 20));
-//   // intervals should now contain the single range [20, 40).
-//   EXPECT_EQ(1, intervals.Size());
-//   EXPECT_TRUE(intervals.Contains(Interval<int>(20, 40)));
-
-#include <stddef.h>
-#include <algorithm>
-#include <initializer_list>
-#include <set>
-#include <utility>
-#include <vector>
-
-#include <string>
-
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-template <typename T>
-class QUIC_NO_EXPORT QuicIntervalSet {
- public:
-  using value_type = QuicInterval<T>;
-
- private:
-  struct QUIC_NO_EXPORT IntervalLess {
-    using is_transparent = void;
-    bool operator()(const value_type& a, const value_type& b) const;
-    // These transparent overloads are used when we do all of our searches (via
-    // Set::lower_bound() and Set::upper_bound()), which avoids the need to
-    // construct an interval when we are looking for a point and also avoids
-    // needing to worry about comparing overlapping intervals in the overload
-    // that takes two value_types (the one just above this comment).
-    bool operator()(const value_type& a, const T& point) const;
-    bool operator()(const value_type& a, T&& point) const;
-    bool operator()(const T& point, const value_type& a) const;
-    bool operator()(T&& point, const value_type& a) const;
-  };
-
-  using Set = QuicSmallOrderedSet<value_type, IntervalLess>;
-
- public:
-  using const_iterator = typename Set::const_iterator;
-  using const_reverse_iterator = typename Set::const_reverse_iterator;
-
-  // Instantiates an empty QuicIntervalSet.
-  QuicIntervalSet() = default;
-
-  // Instantiates a QuicIntervalSet containing exactly one initial half-open
-  // interval [min, max), unless the given interval is empty, in which case the
-  // QuicIntervalSet will be empty.
-  explicit QuicIntervalSet(const value_type& interval) { Add(interval); }
-
-  // Instantiates a QuicIntervalSet containing the half-open interval [min,
-  // max).
-  QuicIntervalSet(const T& min, const T& max) { Add(min, max); }
-
-  QuicIntervalSet(std::initializer_list<value_type> il) { assign(il); }
-
-  // Clears this QuicIntervalSet.
-  void Clear() { intervals_.clear(); }
-
-  // Returns the number of disjoint intervals contained in this QuicIntervalSet.
-  size_t Size() const { return intervals_.size(); }
-
-  // Returns the smallest interval that contains all intervals in this
-  // QuicIntervalSet, or the empty interval if the set is empty.
-  value_type SpanningInterval() const;
-
-  // Adds "interval" to this QuicIntervalSet. Adding the empty interval has no
-  // effect.
-  void Add(const value_type& interval);
-
-  // Adds the interval [min, max) to this QuicIntervalSet. Adding the empty
-  // interval has no effect.
-  void Add(const T& min, const T& max) { Add(value_type(min, max)); }
-
-  // Same semantics as Add(const value_type&), but optimized for the case where
-  // rbegin()->min() <= |interval|.min() <= rbegin()->max().
-  void AddOptimizedForAppend(const value_type& interval) {
-    if (Empty()) {
-      Add(interval);
-      return;
-    }
-
-    const_reverse_iterator last_interval = intervals_.rbegin();
-
-    // If interval.min() is outside of [last_interval->min, last_interval->max],
-    // we can not simply extend last_interval->max.
-    if (interval.min() < last_interval->min() ||
-        interval.min() > last_interval->max()) {
-      Add(interval);
-      return;
-    }
-
-    if (interval.max() <= last_interval->max()) {
-      // interval is fully contained by last_interval.
-      return;
-    }
-
-    // Extend last_interval.max to interval.max, in place.
-    //
-    // Set does not allow in-place updates due to the potential of violating its
-    // ordering requirements. But we know setting the max of the last interval
-    // is safe w.r.t set ordering and other invariants of QuicIntervalSet, so we
-    // force an in-place update for performance.
-    const_cast<value_type*>(&(*last_interval))->SetMax(interval.max());
-  }
-
-  // Same semantics as Add(const T&, const T&), but optimized for the case where
-  // rbegin()->max() == |min|.
-  void AddOptimizedForAppend(const T& min, const T& max) {
-    AddOptimizedForAppend(value_type(min, max));
-  }
-
-  // TODO(wub): Similar to AddOptimizedForAppend, we can also have a
-  // AddOptimizedForPrepend if there is a use case.
-
-  // Remove the first interval.
-  // REQUIRES: !Empty()
-  void PopFront() {
-    QUICHE_DCHECK(!Empty());
-    intervals_.erase(intervals_.begin());
-  }
-
-  // Trim all values that are smaller than |value|. Which means
-  // a) If all values in an interval is smaller than |value|, the entire
-  //    interval is removed.
-  // b) If some but not all values in an interval is smaller than |value|, the
-  //    min of that interval is raised to |value|.
-  // Returns true if some intervals are trimmed.
-  bool TrimLessThan(const T& value) {
-    // Number of intervals that are fully or partially trimmed.
-    size_t num_intervals_trimmed = 0;
-
-    while (!intervals_.empty()) {
-      const_iterator first_interval = intervals_.begin();
-      if (first_interval->min() >= value) {
-        break;
-      }
-
-      ++num_intervals_trimmed;
-
-      if (first_interval->max() <= value) {
-        // a) Trim the entire interval.
-        intervals_.erase(first_interval);
-        continue;
-      }
-
-      // b) Trim a prefix of the interval.
-      //
-      // Set does not allow in-place updates due to the potential of violating
-      // its ordering requirements. But increasing the min of the first interval
-      // will not break the ordering, hence the const_cast.
-      const_cast<value_type*>(&(*first_interval))->SetMin(value);
-      break;
-    }
-
-    return num_intervals_trimmed != 0;
-  }
-
-  // Returns true if this QuicIntervalSet is empty.
-  bool Empty() const { return intervals_.empty(); }
-
-  // Returns true if any interval in this QuicIntervalSet contains the indicated
-  // value.
-  bool Contains(const T& value) const;
-
-  // Returns true if there is some interval in this QuicIntervalSet that wholly
-  // contains the given interval. An interval O "wholly contains" a non-empty
-  // interval I if O.Contains(p) is true for every p in I. This is the same
-  // definition used by value_type::Contains(). This method returns false on
-  // the empty interval, due to a (perhaps unintuitive) convention inherited
-  // from value_type.
-  // Example:
-  //   Assume an QuicIntervalSet containing the entries { [10,20), [30,40) }.
-  //   Contains(Interval(15, 16)) returns true, because [10,20) contains
-  //   [15,16). However, Contains(Interval(15, 35)) returns false.
-  bool Contains(const value_type& interval) const;
-
-  // Returns true if for each interval in "other", there is some (possibly
-  // different) interval in this QuicIntervalSet which wholly contains it. See
-  // Contains(const value_type& interval) for the meaning of "wholly contains".
-  // Perhaps unintuitively, this method returns false if "other" is the empty
-  // set. The algorithmic complexity of this method is O(other.Size() *
-  // log(this->Size())). The method could be rewritten to run in O(other.Size()
-  // + this->Size()), and this alternative could be implemented as a free
-  // function using the public API.
-  bool Contains(const QuicIntervalSet<T>& other) const;
-
-  // Returns true if there is some interval in this QuicIntervalSet that wholly
-  // contains the interval [min, max). See Contains(const value_type&).
-  bool Contains(const T& min, const T& max) const {
-    return Contains(value_type(min, max));
-  }
-
-  // Returns true if for some interval in "other", there is some interval in
-  // this QuicIntervalSet that intersects with it. See value_type::Intersects()
-  // for the definition of interval intersection.  Runs in time O(n+m) where n
-  // is the number of intervals in this and m is the number of intervals in
-  // other.
-  bool Intersects(const QuicIntervalSet& other) const;
-
-  // Returns an iterator to the value_type in the QuicIntervalSet that contains
-  // the given value. In other words, returns an iterator to the unique interval
-  // [min, max) in the QuicIntervalSet that has the property min <= value < max.
-  // If there is no such interval, this method returns end().
-  const_iterator Find(const T& value) const;
-
-  // Returns an iterator to the value_type in the QuicIntervalSet that wholly
-  // contains the given interval. In other words, returns an iterator to the
-  // unique interval outer in the QuicIntervalSet that has the property that
-  // outer.Contains(interval). If there is no such interval, or if interval is
-  // empty, returns end().
-  const_iterator Find(const value_type& interval) const;
-
-  // Returns an iterator to the value_type in the QuicIntervalSet that wholly
-  // contains [min, max). In other words, returns an iterator to the unique
-  // interval outer in the QuicIntervalSet that has the property that
-  // outer.Contains(Interval<T>(min, max)). If there is no such interval, or if
-  // interval is empty, returns end().
-  const_iterator Find(const T& min, const T& max) const {
-    return Find(value_type(min, max));
-  }
-
-  // Returns an iterator pointing to the first value_type which contains or
-  // goes after the given value.
-  //
-  // Example:
-  //   [10, 20)  [30, 40)
-  //   ^                    LowerBound(10)
-  //   ^                    LowerBound(15)
-  //             ^          LowerBound(20)
-  //             ^          LowerBound(25)
-  const_iterator LowerBound(const T& value) const;
-
-  // Returns an iterator pointing to the first value_type which goes after
-  // the given value.
-  //
-  // Example:
-  //   [10, 20)  [30, 40)
-  //             ^          UpperBound(10)
-  //             ^          UpperBound(15)
-  //             ^          UpperBound(20)
-  //             ^          UpperBound(25)
-  const_iterator UpperBound(const T& value) const;
-
-  // Returns true if every value within the passed interval is not Contained
-  // within the QuicIntervalSet.
-  // Note that empty intervals are always considered disjoint from the
-  // QuicIntervalSet (even though the QuicIntervalSet doesn't `Contain` them).
-  bool IsDisjoint(const value_type& interval) const;
-
-  // Merges all the values contained in "other" into this QuicIntervalSet.
-  //
-  // Performance: Let n == Size() and m = other.Size().  Union() runs in O(m)
-  // Set operations, so that if Set is a tree, it runs in time O(m log(n+m)) and
-  // if Set is a flat_set it runs in time O(m(n+m)).  In principle, for the
-  // flat_set, we should be able to make this run in time O(n+m).
-  //
-  // TODO(bradleybear): Make Union() run in time O(n+m) for flat_set.  This may
-  // require an additional template parameter to indicate that the Set is a
-  // linear-time data structure instead of a log-time data structure.
-  void Union(const QuicIntervalSet& other);
-
-  // Modifies this QuicIntervalSet so that it contains only those values that
-  // are currently present both in *this and in the QuicIntervalSet "other".
-  void Intersection(const QuicIntervalSet& other);
-
-  // Mutates this QuicIntervalSet so that it contains only those values that are
-  // currently in *this but not in "interval".
-  void Difference(const value_type& interval);
-
-  // Mutates this QuicIntervalSet so that it contains only those values that are
-  // currently in *this but not in the interval [min, max).
-  void Difference(const T& min, const T& max);
-
-  // Mutates this QuicIntervalSet so that it contains only those values that are
-  // currently in *this but not in the QuicIntervalSet "other".  Runs in time
-  // O(n+m) where n is this->Size(), m is other.Size(), regardless of whether
-  // the Set is a flat_set or a std::set.
-  void Difference(const QuicIntervalSet& other);
-
-  // Mutates this QuicIntervalSet so that it contains only those values that are
-  // in [min, max) but not currently in *this.
-  void Complement(const T& min, const T& max);
-
-  // QuicIntervalSet's begin() iterator. The invariants of QuicIntervalSet
-  // guarantee that for each entry e in the set, e.min() < e.max() (because the
-  // entries are non-empty) and for each entry f that appears later in the set,
-  // e.max() < f.min() (because the entries are ordered, pairwise-disjoint, and
-  // non-adjacent). Modifications to this QuicIntervalSet invalidate these
-  // iterators.
-  const_iterator begin() const { return intervals_.begin(); }
-
-  // QuicIntervalSet's end() iterator.
-  const_iterator end() const { return intervals_.end(); }
-
-  // QuicIntervalSet's rbegin() and rend() iterators. Iterator invalidation
-  // semantics are the same as those for begin() / end().
-  const_reverse_iterator rbegin() const { return intervals_.rbegin(); }
-
-  const_reverse_iterator rend() const { return intervals_.rend(); }
-
-  template <typename Iter>
-  void assign(Iter first, Iter last) {
-    Clear();
-    for (; first != last; ++first)
-      Add(*first);
-  }
-
-  void assign(std::initializer_list<value_type> il) {
-    assign(il.begin(), il.end());
-  }
-
-  // Returns a human-readable representation of this set. This will typically be
-  // (though is not guaranteed to be) of the form
-  //   "[a1, b1) [a2, b2) ... [an, bn)"
-  // where the intervals are in the same order as given by traversal from
-  // begin() to end(). This representation is intended for human consumption;
-  // computer programs should not rely on the output being in exactly this form.
-  std::string ToString() const;
-
-  QuicIntervalSet& operator=(std::initializer_list<value_type> il) {
-    assign(il.begin(), il.end());
-    return *this;
-  }
-
-  friend bool operator==(const QuicIntervalSet& a, const QuicIntervalSet& b) {
-    return a.Size() == b.Size() &&
-           std::equal(a.begin(), a.end(), b.begin(), NonemptyIntervalEq());
-  }
-
-  friend bool operator!=(const QuicIntervalSet& a, const QuicIntervalSet& b) {
-    return !(a == b);
-  }
-
- private:
-  // Simple member-wise equality, since all intervals are non-empty.
-  struct QUIC_NO_EXPORT NonemptyIntervalEq {
-    bool operator()(const value_type& a, const value_type& b) const {
-      return a.min() == b.min() && a.max() == b.max();
-    }
-  };
-
-  // Returns true if this set is valid (i.e. all intervals in it are non-empty,
-  // non-adjacent, and mutually disjoint). Currently this is used as an
-  // integrity check by the Intersection() and Difference() methods, but is only
-  // invoked for debug builds (via QUICHE_DCHECK).
-  bool Valid() const;
-
-  // Finds the first interval that potentially intersects 'other'.
-  const_iterator FindIntersectionCandidate(const QuicIntervalSet& other) const;
-
-  // Finds the first interval that potentially intersects 'interval'.  More
-  // precisely, return an interator it pointing at the last interval J such that
-  // interval <= J.  If all the intervals are > J then return begin().
-  const_iterator FindIntersectionCandidate(const value_type& interval) const;
-
-  // Helper for Intersection() and Difference(): Finds the next pair of
-  // intervals from 'x' and 'y' that intersect. 'mine' is an iterator
-  // over x->intervals_. 'theirs' is an iterator over y.intervals_. 'mine'
-  // and 'theirs' are advanced until an intersecting pair is found.
-  // Non-intersecting intervals (aka "holes") from x->intervals_ can be
-  // optionally erased by "on_hole". "on_hole" must return an iterator to the
-  // first element in 'x' after the hole, or x->intervals_.end() if no elements
-  // exist after the hole.
-  template <typename X, typename Func>
-  static bool FindNextIntersectingPairImpl(X* x,
-                                           const QuicIntervalSet& y,
-                                           const_iterator* mine,
-                                           const_iterator* theirs,
-                                           Func on_hole);
-
-  // The variant of the above method that doesn't mutate this QuicIntervalSet.
-  bool FindNextIntersectingPair(const QuicIntervalSet& other,
-                                const_iterator* mine,
-                                const_iterator* theirs) const {
-    return FindNextIntersectingPairImpl(
-        this, other, mine, theirs,
-        [](const QuicIntervalSet*, const_iterator, const_iterator end) {
-          return end;
-        });
-  }
-
-  // The variant of the above method that mutates this QuicIntervalSet by
-  // erasing holes.
-  bool FindNextIntersectingPairAndEraseHoles(const QuicIntervalSet& other,
-                                             const_iterator* mine,
-                                             const_iterator* theirs) {
-    return FindNextIntersectingPairImpl(
-        this, other, mine, theirs,
-        [](QuicIntervalSet* x, const_iterator from, const_iterator to) {
-          return x->intervals_.erase(from, to);
-        });
-  }
-
-  // The representation for the intervals. The intervals in this set are
-  // non-empty, pairwise-disjoint, non-adjacent and ordered in ascending order
-  // by min().
-  Set intervals_;
-};
-
-template <typename T>
-auto operator<<(std::ostream& out, const QuicIntervalSet<T>& seq)
-    -> decltype(out << *seq.begin()) {
-  out << "{";
-  for (const auto& interval : seq) {
-    out << " " << interval;
-  }
-  out << " }";
-
-  return out;
-}
-
-//==============================================================================
-// Implementation details: Clients can stop reading here.
-
-template <typename T>
-typename QuicIntervalSet<T>::value_type QuicIntervalSet<T>::SpanningInterval()
-    const {
-  value_type result;
-  if (!intervals_.empty()) {
-    result.SetMin(intervals_.begin()->min());
-    result.SetMax(intervals_.rbegin()->max());
-  }
-  return result;
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Add(const value_type& interval) {
-  if (interval.Empty())
-    return;
-  const_iterator it = intervals_.lower_bound(interval.min());
-  value_type the_union = interval;
-  if (it != intervals_.begin()) {
-    --it;
-    if (it->Separated(the_union)) {
-      ++it;
-    }
-  }
-  // Don't erase the elements one at a time, since that will produce quadratic
-  // work on a flat_set, and apparently an extra log-factor of work for a
-  // tree-based set.  Instead identify the first and last intervals that need to
-  // be erased, and call erase only once.
-  const_iterator start = it;
-  while (it != intervals_.end() && !it->Separated(the_union)) {
-    the_union.SpanningUnion(*it);
-    ++it;
-  }
-  intervals_.erase(start, it);
-  intervals_.insert(the_union);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Contains(const T& value) const {
-  // Find the first interval with min() > value, then move back one step
-  const_iterator it = intervals_.upper_bound(value);
-  if (it == intervals_.begin())
-    return false;
-  --it;
-  return it->Contains(value);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Contains(const value_type& interval) const {
-  // Find the first interval with min() > value, then move back one step.
-  const_iterator it = intervals_.upper_bound(interval.min());
-  if (it == intervals_.begin())
-    return false;
-  --it;
-  return it->Contains(interval);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Contains(const QuicIntervalSet<T>& other) const {
-  if (!SpanningInterval().Contains(other.SpanningInterval())) {
-    return false;
-  }
-
-  for (const_iterator i = other.begin(); i != other.end(); ++i) {
-    // If we don't contain the interval, can return false now.
-    if (!Contains(*i)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// This method finds the interval that Contains() "value", if such an interval
-// exists in the QuicIntervalSet. The way this is done is to locate the
-// "candidate interval", the only interval that could *possibly* contain value,
-// and test it using Contains(). The candidate interval is the interval with the
-// largest min() having min() <= value.
-//
-// Another detail involves the choice of which Set method to use to try to find
-// the candidate interval. The most appropriate entry point is
-// Set::upper_bound(), which finds the least interval with a min > the
-// value. The semantics of upper_bound() are slightly different from what we
-// want (namely, to find the greatest interval which is <= the probe interval)
-// but they are close enough; the interval found by upper_bound() will always be
-// one step past the interval we are looking for (if it exists) or at begin()
-// (if it does not). Getting to the proper interval is a simple matter of
-// decrementing the iterator.
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
-    const T& value) const {
-  const_iterator it = intervals_.upper_bound(value);
-  if (it == intervals_.begin())
-    return intervals_.end();
-  --it;
-  if (it->Contains(value))
-    return it;
-  else
-    return intervals_.end();
-}
-
-// This method finds the interval that Contains() the interval "probe", if such
-// an interval exists in the QuicIntervalSet. The way this is done is to locate
-// the "candidate interval", the only interval that could *possibly* contain
-// "probe", and test it using Contains().  We use the same algorithm as for
-// Find(value), except that instead of checking that the value is contained, we
-// check that the probe is contained.
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
-    const value_type& probe) const {
-  const_iterator it = intervals_.upper_bound(probe.min());
-  if (it == intervals_.begin())
-    return intervals_.end();
-  --it;
-  if (it->Contains(probe))
-    return it;
-  else
-    return intervals_.end();
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::LowerBound(
-    const T& value) const {
-  const_iterator it = intervals_.lower_bound(value);
-  if (it == intervals_.begin()) {
-    return it;
-  }
-
-  // The previous intervals_.lower_bound() checking is essentially based on
-  // interval.min(), so we need to check whether the `value` is contained in
-  // the previous interval.
-  --it;
-  if (it->Contains(value)) {
-    return it;
-  } else {
-    return ++it;
-  }
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::UpperBound(
-    const T& value) const {
-  return intervals_.upper_bound(value);
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::IsDisjoint(const value_type& interval) const {
-  if (interval.Empty())
-    return true;
-  // Find the first interval with min() > interval.min()
-  const_iterator it = intervals_.upper_bound(interval.min());
-  if (it != intervals_.end() && interval.max() > it->min())
-    return false;
-  if (it == intervals_.begin())
-    return true;
-  --it;
-  return it->max() <= interval.min();
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Union(const QuicIntervalSet& other) {
-  for (const value_type& interval : other.intervals_) {
-    Add(interval);
-  }
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator
-QuicIntervalSet<T>::FindIntersectionCandidate(
-    const QuicIntervalSet& other) const {
-  return FindIntersectionCandidate(*other.intervals_.begin());
-}
-
-template <typename T>
-typename QuicIntervalSet<T>::const_iterator
-QuicIntervalSet<T>::FindIntersectionCandidate(
-    const value_type& interval) const {
-  // Use upper_bound to efficiently find the first interval in intervals_
-  // where min() is greater than interval.min().  If the result
-  // isn't the beginning of intervals_ then move backwards one interval since
-  // the interval before it is the first candidate where max() may be
-  // greater than interval.min().
-  // In other words, no interval before that can possibly intersect with any
-  // of other.intervals_.
-  const_iterator mine = intervals_.upper_bound(interval.min());
-  if (mine != intervals_.begin()) {
-    --mine;
-  }
-  return mine;
-}
-
-template <typename T>
-template <typename X, typename Func>
-bool QuicIntervalSet<T>::FindNextIntersectingPairImpl(X* x,
-                                                      const QuicIntervalSet& y,
-                                                      const_iterator* mine,
-                                                      const_iterator* theirs,
-                                                      Func on_hole) {
-  QUICHE_CHECK(x != nullptr);
-  if ((*mine == x->intervals_.end()) || (*theirs == y.intervals_.end())) {
-    return false;
-  }
-  while (!(**mine).Intersects(**theirs)) {
-    const_iterator erase_first = *mine;
-    // Skip over intervals in 'mine' that don't reach 'theirs'.
-    while (*mine != x->intervals_.end() && (**mine).max() <= (**theirs).min()) {
-      ++(*mine);
-    }
-    *mine = on_hole(x, erase_first, *mine);
-    // We're done if the end of intervals_ is reached.
-    if (*mine == x->intervals_.end()) {
-      return false;
-    }
-    // Skip over intervals 'theirs' that don't reach 'mine'.
-    while (*theirs != y.intervals_.end() &&
-           (**theirs).max() <= (**mine).min()) {
-      ++(*theirs);
-    }
-    // If the end of other.intervals_ is reached, we're done.
-    if (*theirs == y.intervals_.end()) {
-      on_hole(x, *mine, x->intervals_.end());
-      return false;
-    }
-  }
-  return true;
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Intersection(const QuicIntervalSet& other) {
-  if (!SpanningInterval().Intersects(other.SpanningInterval())) {
-    intervals_.clear();
-    return;
-  }
-
-  const_iterator mine = FindIntersectionCandidate(other);
-  // Remove any intervals that cannot possibly intersect with other.intervals_.
-  mine = intervals_.erase(intervals_.begin(), mine);
-  const_iterator theirs = other.FindIntersectionCandidate(*this);
-
-  while (FindNextIntersectingPairAndEraseHoles(other, &mine, &theirs)) {
-    // OK, *mine and *theirs intersect.  Now, we find the largest
-    // span of intervals in other (starting at theirs) - say [a..b]
-    // - that intersect *mine, and we replace *mine with (*mine
-    // intersect x) for all x in [a..b] Note that subsequent
-    // intervals in this can't intersect any intervals in [a..b) --
-    // they may only intersect b or subsequent intervals in other.
-    value_type i(*mine);
-    intervals_.erase(mine);
-    mine = intervals_.end();
-    value_type intersection;
-    while (theirs != other.intervals_.end() &&
-           i.Intersects(*theirs, &intersection)) {
-      std::pair<const_iterator, bool> ins = intervals_.insert(intersection);
-      QUICHE_DCHECK(ins.second);
-      mine = ins.first;
-      ++theirs;
-    }
-    QUICHE_DCHECK(mine != intervals_.end());
-    --theirs;
-    ++mine;
-  }
-  QUICHE_DCHECK(Valid());
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Intersects(const QuicIntervalSet& other) const {
-  // Don't bother to handle nonoverlapping spanning intervals as a special case.
-  // This code runs in time O(n+m), as guaranteed, even for that case .
-  // Handling the nonoverlapping spanning intervals as a special case doesn't
-  // improve the asymptotics but does make the code more complex.
-  auto mine = intervals_.begin();
-  auto theirs = other.intervals_.begin();
-  while (mine != intervals_.end() && theirs != other.intervals_.end()) {
-    if (mine->Intersects(*theirs))
-      return true;
-    else if (*mine < *theirs)
-      ++mine;
-    else
-      ++theirs;
-  }
-  return false;
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Difference(const value_type& interval) {
-  if (!SpanningInterval().Intersects(interval)) {
-    return;
-  }
-  Difference(QuicIntervalSet<T>(interval));
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Difference(const T& min, const T& max) {
-  Difference(value_type(min, max));
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Difference(const QuicIntervalSet& other) {
-  // In order to avoid quadratic-time when using a flat set, we don't try to
-  // update intervals_ in place.  Instead we build up a new result_, always
-  // inserting at the end which is O(1) time per insertion.  Since the number of
-  // elements in the result is O(Size() + other.Size()), the cost for all the
-  // insertions is also O(Size() + other.Size()).
-  //
-  // We look at all the elements of intervals_, so that's O(Size()).
-  //
-  // We also look at all the elements of other.intervals_, for O(other.Size()).
-  if (Empty())
-    return;
-  Set result;
-  const_iterator mine = intervals_.begin();
-  value_type myinterval = *mine;
-  const_iterator theirs = other.intervals_.begin();
-  while (mine != intervals_.end()) {
-    // Loop invariants:
-    //   myinterval is nonempty.
-    //   mine points at a range that is a suffix of myinterval.
-    QUICHE_DCHECK(!myinterval.Empty());
-    QUICHE_DCHECK(myinterval.max() == mine->max());
-
-    // There are 3 cases.
-    //  myinterval is completely before theirs (treat theirs==end() as if it is
-    //  infinity).
-    //    --> consume myinterval into result.
-    //  myinterval is completely after theirs
-    //    --> theirs can no longer affect us, so ++theirs.
-    //  myinterval touches theirs with a prefix of myinterval not touching
-    //  *theirs.
-    //    --> consume the prefix of myinterval into the result.
-    //  myinterval touches theirs, with the first element of myinterval in
-    //  *theirs.
-    //    -> reduce myinterval
-    if (theirs == other.intervals_.end() || myinterval.max() <= theirs->min()) {
-      // Keep all of my_interval.
-      result.insert(result.end(), myinterval);
-      myinterval.Clear();
-    } else if (theirs->max() <= myinterval.min()) {
-      ++theirs;
-    } else if (myinterval.min() < theirs->min()) {
-      // Keep a nonempty prefix of my interval.
-      result.insert(result.end(), value_type(myinterval.min(), theirs->min()));
-      myinterval.SetMin(theirs->max());
-    } else {
-      // myinterval starts at or after *theirs, chop down myinterval.
-      myinterval.SetMin(theirs->max());
-    }
-    // if myinterval became empty, find the next interval
-    if (myinterval.Empty()) {
-      ++mine;
-      if (mine != intervals_.end()) {
-        myinterval = *mine;
-      }
-    }
-  }
-  std::swap(result, intervals_);
-  QUICHE_DCHECK(Valid());
-}
-
-template <typename T>
-void QuicIntervalSet<T>::Complement(const T& min, const T& max) {
-  QuicIntervalSet<T> span(min, max);
-  span.Difference(*this);
-  intervals_.swap(span.intervals_);
-}
-
-template <typename T>
-std::string QuicIntervalSet<T>::ToString() const {
-  std::ostringstream os;
-  os << *this;
-  return os.str();
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::Valid() const {
-  const_iterator prev = end();
-  for (const_iterator it = begin(); it != end(); ++it) {
-    // invalid or empty interval.
-    if (it->min() >= it->max())
-      return false;
-    // Not sorted, not disjoint, or adjacent.
-    if (prev != end() && prev->max() >= it->min())
-      return false;
-    prev = it;
-  }
-  return true;
-}
-
-// This comparator orders intervals first by ascending min().  The Set never
-// contains overlapping intervals, so that suffices.
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
-                                                  const value_type& b) const {
-  // This overload is probably used only by Set::insert().
-  return a.min() < b.min();
-}
-
-// It appears that the Set::lower_bound(T) method uses only two overloads of the
-// comparison operator that take a T as the second argument..  In contrast
-// Set::upper_bound(T) uses the two overloads that take T as the first argument.
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
-                                                  const T& point) const {
-  // Compare an interval to a point.
-  return a.min() < point;
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
-                                                  T&& point) const {
-  // Compare an interval to a point
-  return a.min() < point;
-}
-
-// It appears that the Set::upper_bound(T) method uses only the next two
-// overloads of the comparison operator.
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(const T& point,
-                                                  const value_type& a) const {
-  // Compare an interval to a point.
-  return point < a.min();
-}
-
-template <typename T>
-bool QuicIntervalSet<T>::IntervalLess::operator()(T&& point,
-                                                  const value_type& a) const {
-  // Compare an interval to a point.
-  return point < a.min();
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
diff --git a/quic/core/quic_interval_set_test.cc b/quic/core/quic_interval_set_test.cc
deleted file mode 100644
index 14db466..0000000
--- a/quic/core/quic_interval_set_test.cc
+++ /dev/null
@@ -1,1071 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_interval_set.h"
-
-#include <stdarg.h>
-
-#include <algorithm>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <string>
-#include <vector>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAreArray;
-
-class QuicIntervalSetTest : public QuicTest {
- protected:
-  virtual void SetUp() {
-    // Initialize two QuicIntervalSets for union, intersection, and difference
-    // tests
-    is.Add(100, 200);
-    is.Add(300, 400);
-    is.Add(500, 600);
-    is.Add(700, 800);
-    is.Add(900, 1000);
-    is.Add(1100, 1200);
-    is.Add(1300, 1400);
-    is.Add(1500, 1600);
-    is.Add(1700, 1800);
-    is.Add(1900, 2000);
-    is.Add(2100, 2200);
-
-    // Lots of different cases:
-    other.Add(50, 70);      // disjoint, at the beginning
-    other.Add(2250, 2270);  // disjoint, at the end
-    other.Add(650, 670);    // disjoint, in the middle
-    other.Add(350, 360);    // included
-    other.Add(370, 380);    // also included (two at once)
-    other.Add(470, 530);    // overlaps low end
-    other.Add(770, 830);    // overlaps high end
-    other.Add(870, 900);    // meets at low end
-    other.Add(1200, 1230);  // meets at high end
-    other.Add(1270, 1830);  // overlaps multiple ranges
-  }
-
-  virtual void TearDown() {
-    is.Clear();
-    EXPECT_TRUE(is.Empty());
-    other.Clear();
-    EXPECT_TRUE(other.Empty());
-  }
-  QuicIntervalSet<int> is;
-  QuicIntervalSet<int> other;
-};
-
-TEST_F(QuicIntervalSetTest, IsDisjoint) {
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 99)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 100)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 299)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 407)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(405, 499)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(2300, 2300)));
-  EXPECT_TRUE(
-      is.IsDisjoint(QuicInterval<int>(2300, std::numeric_limits<int>::max())));
-  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(100, 105)));
-  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(199, 300)));
-  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 450)));
-  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(299, 400)));
-  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 2000)));
-  EXPECT_FALSE(
-      is.IsDisjoint(QuicInterval<int>(2199, std::numeric_limits<int>::max())));
-  // Empty intervals.
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(90, 90)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 100)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 90)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(150, 150)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
-  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 300)));
-}
-
-// Base helper method for verifying the contents of an interval set.
-// Returns true iff <is> contains <count> intervals whose successive
-// endpoints match the sequence of args in <ap>:
-static bool VA_Check(const QuicIntervalSet<int>& is, int count, va_list ap) {
-  std::vector<QuicInterval<int>> intervals(is.begin(), is.end());
-  if (count != static_cast<int>(intervals.size())) {
-    QUIC_LOG(ERROR) << "Expected " << count << " intervals, got "
-                    << intervals.size() << ": " << is;
-    return false;
-  }
-  if (count != static_cast<int>(is.Size())) {
-    QUIC_LOG(ERROR) << "Expected " << count << " intervals, got Size "
-                    << is.Size() << ": " << is;
-    return false;
-  }
-  bool result = true;
-  for (int i = 0; i < count; i++) {
-    int min = va_arg(ap, int);
-    int max = va_arg(ap, int);
-    if (min != intervals[i].min() || max != intervals[i].max()) {
-      QUIC_LOG(ERROR) << "Expected: [" << min << ", " << max << ") got "
-                      << intervals[i] << " in " << is;
-      result = false;
-    }
-  }
-  return result;
-}
-
-static bool Check(const QuicIntervalSet<int>& is, int count, ...) {
-  va_list ap;
-  va_start(ap, count);
-  const bool result = VA_Check(is, count, ap);
-  va_end(ap);
-  return result;
-}
-
-// Some helper functions for testing Contains and Find, which are logically the
-// same.
-static void TestContainsAndFind(const QuicIntervalSet<int>& is, int value) {
-  EXPECT_TRUE(is.Contains(value)) << "Set does not contain " << value;
-  auto it = is.Find(value);
-  EXPECT_NE(it, is.end()) << "No iterator to interval containing " << value;
-  EXPECT_TRUE(it->Contains(value)) << "Iterator does not contain " << value;
-}
-
-static void TestContainsAndFind(const QuicIntervalSet<int>& is,
-                                int min,
-                                int max) {
-  EXPECT_TRUE(is.Contains(min, max))
-      << "Set does not contain interval with min " << min << "and max " << max;
-  auto it = is.Find(min, max);
-  EXPECT_NE(it, is.end()) << "No iterator to interval with min " << min
-                          << "and max " << max;
-  EXPECT_TRUE(it->Contains(QuicInterval<int>(min, max)))
-      << "Iterator does not contain interval with min " << min << "and max "
-      << max;
-}
-
-static void TestNotContainsAndFind(const QuicIntervalSet<int>& is, int value) {
-  EXPECT_FALSE(is.Contains(value)) << "Set contains " << value;
-  auto it = is.Find(value);
-  EXPECT_EQ(it, is.end()) << "There is iterator to interval containing "
-                          << value;
-}
-
-static void TestNotContainsAndFind(const QuicIntervalSet<int>& is,
-                                   int min,
-                                   int max) {
-  EXPECT_FALSE(is.Contains(min, max))
-      << "Set contains interval with min " << min << "and max " << max;
-  auto it = is.Find(min, max);
-  EXPECT_EQ(it, is.end()) << "There is iterator to interval with min " << min
-                          << "and max " << max;
-}
-
-TEST_F(QuicIntervalSetTest, AddInterval) {
-  QuicIntervalSet<int> s;
-  s.Add(QuicInterval<int>(0, 10));
-  EXPECT_TRUE(Check(s, 1, 0, 10));
-}
-
-TEST_F(QuicIntervalSetTest, DecrementIterator) {
-  auto it = is.end();
-  EXPECT_NE(it, is.begin());
-  --it;
-  EXPECT_EQ(*it, QuicInterval<int>(2100, 2200));
-  ++it;
-  EXPECT_EQ(it, is.end());
-}
-
-TEST_F(QuicIntervalSetTest, AddOptimizedForAppend) {
-  QuicIntervalSet<int> empty_one, empty_two;
-  empty_one.AddOptimizedForAppend(QuicInterval<int>(0, 99));
-  EXPECT_TRUE(Check(empty_one, 1, 0, 99));
-
-  empty_two.AddOptimizedForAppend(1, 50);
-  EXPECT_TRUE(Check(empty_two, 1, 1, 50));
-
-  QuicIntervalSet<int> iset;
-  iset.AddOptimizedForAppend(100, 150);
-  iset.AddOptimizedForAppend(200, 250);
-  EXPECT_TRUE(Check(iset, 2, 100, 150, 200, 250));
-
-  iset.AddOptimizedForAppend(199, 200);
-  EXPECT_TRUE(Check(iset, 2, 100, 150, 199, 250));
-
-  iset.AddOptimizedForAppend(251, 260);
-  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
-
-  iset.AddOptimizedForAppend(252, 260);
-  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
-
-  iset.AddOptimizedForAppend(252, 300);
-  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 300));
-
-  iset.AddOptimizedForAppend(300, 350);
-  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 350));
-}
-
-TEST_F(QuicIntervalSetTest, PopFront) {
-  QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
-  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
-
-  iset.PopFront();
-  EXPECT_TRUE(Check(iset, 2, 400, 500, 700, 800));
-
-  iset.PopFront();
-  EXPECT_TRUE(Check(iset, 1, 700, 800));
-
-  iset.PopFront();
-  EXPECT_TRUE(iset.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, TrimLessThan) {
-  QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
-  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
-
-  EXPECT_FALSE(iset.TrimLessThan(99));
-  EXPECT_FALSE(iset.TrimLessThan(100));
-  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
-
-  EXPECT_TRUE(iset.TrimLessThan(101));
-  EXPECT_TRUE(Check(iset, 3, 101, 200, 400, 500, 700, 800));
-
-  EXPECT_TRUE(iset.TrimLessThan(199));
-  EXPECT_TRUE(Check(iset, 3, 199, 200, 400, 500, 700, 800));
-
-  EXPECT_TRUE(iset.TrimLessThan(450));
-  EXPECT_TRUE(Check(iset, 2, 450, 500, 700, 800));
-
-  EXPECT_TRUE(iset.TrimLessThan(500));
-  EXPECT_TRUE(Check(iset, 1, 700, 800));
-
-  EXPECT_TRUE(iset.TrimLessThan(801));
-  EXPECT_TRUE(iset.Empty());
-
-  EXPECT_FALSE(iset.TrimLessThan(900));
-  EXPECT_TRUE(iset.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetBasic) {
-  // Test Add, Get, Contains and Find
-  QuicIntervalSet<int> iset;
-  EXPECT_TRUE(iset.Empty());
-  EXPECT_EQ(0u, iset.Size());
-  iset.Add(100, 200);
-  EXPECT_FALSE(iset.Empty());
-  EXPECT_EQ(1u, iset.Size());
-  iset.Add(100, 150);
-  iset.Add(150, 200);
-  iset.Add(130, 170);
-  iset.Add(90, 150);
-  iset.Add(170, 220);
-  iset.Add(300, 400);
-  iset.Add(250, 450);
-  EXPECT_FALSE(iset.Empty());
-  EXPECT_EQ(2u, iset.Size());
-  EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
-
-  // Test two intervals with a.max == b.min, that will just join up.
-  iset.Clear();
-  iset.Add(100, 200);
-  iset.Add(200, 300);
-  EXPECT_FALSE(iset.Empty());
-  EXPECT_EQ(1u, iset.Size());
-  EXPECT_TRUE(Check(iset, 1, 100, 300));
-
-  // Test adding two sets together.
-  iset.Clear();
-  QuicIntervalSet<int> iset_add;
-  iset.Add(100, 200);
-  iset.Add(100, 150);
-  iset.Add(150, 200);
-  iset.Add(130, 170);
-  iset_add.Add(90, 150);
-  iset_add.Add(170, 220);
-  iset_add.Add(300, 400);
-  iset_add.Add(250, 450);
-
-  iset.Union(iset_add);
-  EXPECT_FALSE(iset.Empty());
-  EXPECT_EQ(2u, iset.Size());
-  EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
-
-  // Test begin()/end(), and rbegin()/rend()
-  // to iterate over intervals.
-  {
-    std::vector<QuicInterval<int>> expected(iset.begin(), iset.end());
-
-    std::vector<QuicInterval<int>> actual1;
-    std::copy(iset.begin(), iset.end(), back_inserter(actual1));
-    ASSERT_EQ(expected.size(), actual1.size());
-
-    std::vector<QuicInterval<int>> actual2;
-    std::copy(iset.begin(), iset.end(), back_inserter(actual2));
-    ASSERT_EQ(expected.size(), actual2.size());
-
-    for (size_t i = 0; i < expected.size(); i++) {
-      EXPECT_EQ(expected[i].min(), actual1[i].min());
-      EXPECT_EQ(expected[i].max(), actual1[i].max());
-
-      EXPECT_EQ(expected[i].min(), actual2[i].min());
-      EXPECT_EQ(expected[i].max(), actual2[i].max());
-    }
-
-    // Ensure that the rbegin()/rend() iterators correctly yield the intervals
-    // in reverse order.
-    EXPECT_THAT(std::vector<QuicInterval<int>>(iset.rbegin(), iset.rend()),
-                ElementsAreArray(expected.rbegin(), expected.rend()));
-  }
-
-  TestNotContainsAndFind(iset, 89);
-  TestContainsAndFind(iset, 90);
-  TestContainsAndFind(iset, 120);
-  TestContainsAndFind(iset, 219);
-  TestNotContainsAndFind(iset, 220);
-  TestNotContainsAndFind(iset, 235);
-  TestNotContainsAndFind(iset, 249);
-  TestContainsAndFind(iset, 250);
-  TestContainsAndFind(iset, 300);
-  TestContainsAndFind(iset, 449);
-  TestNotContainsAndFind(iset, 450);
-  TestNotContainsAndFind(iset, 451);
-
-  TestNotContainsAndFind(iset, 50, 60);
-  TestNotContainsAndFind(iset, 50, 90);
-  TestNotContainsAndFind(iset, 50, 200);
-  TestNotContainsAndFind(iset, 90, 90);
-  TestContainsAndFind(iset, 90, 200);
-  TestContainsAndFind(iset, 100, 200);
-  TestContainsAndFind(iset, 100, 220);
-  TestNotContainsAndFind(iset, 100, 221);
-  TestNotContainsAndFind(iset, 220, 220);
-  TestNotContainsAndFind(iset, 240, 300);
-  TestContainsAndFind(iset, 250, 300);
-  TestContainsAndFind(iset, 260, 300);
-  TestContainsAndFind(iset, 300, 450);
-  TestNotContainsAndFind(iset, 300, 451);
-
-  QuicIntervalSet<int> iset_contains;
-  iset_contains.Add(50, 90);
-  EXPECT_FALSE(iset.Contains(iset_contains));
-  iset_contains.Clear();
-
-  iset_contains.Add(90, 200);
-  EXPECT_TRUE(iset.Contains(iset_contains));
-  iset_contains.Add(100, 200);
-  EXPECT_TRUE(iset.Contains(iset_contains));
-  iset_contains.Add(100, 220);
-  EXPECT_TRUE(iset.Contains(iset_contains));
-  iset_contains.Add(250, 300);
-  EXPECT_TRUE(iset.Contains(iset_contains));
-  iset_contains.Add(300, 450);
-  EXPECT_TRUE(iset.Contains(iset_contains));
-  iset_contains.Add(300, 451);
-  EXPECT_FALSE(iset.Contains(iset_contains));
-  EXPECT_FALSE(iset.Contains(QuicInterval<int>()));
-  EXPECT_FALSE(iset.Contains(QuicIntervalSet<int>()));
-
-  // Check the case where the query set isn't contained, but the spanning
-  // intervals do overlap.
-  QuicIntervalSet<int> i2({{220, 230}});
-  EXPECT_FALSE(iset.Contains(i2));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetContainsEmpty) {
-  const QuicIntervalSet<int> empty;
-  const QuicIntervalSet<int> other_empty;
-  const QuicIntervalSet<int> non_empty({{10, 20}, {40, 50}});
-  EXPECT_FALSE(empty.Contains(empty));
-  EXPECT_FALSE(empty.Contains(other_empty));
-  EXPECT_FALSE(empty.Contains(non_empty));
-  EXPECT_FALSE(non_empty.Contains(empty));
-}
-
-TEST_F(QuicIntervalSetTest, Equality) {
-  QuicIntervalSet<int> is_copy = is;
-  EXPECT_EQ(is, is);
-  EXPECT_EQ(is, is_copy);
-  EXPECT_NE(is, other);
-  EXPECT_NE(is, QuicIntervalSet<int>());
-  EXPECT_EQ(QuicIntervalSet<int>(), QuicIntervalSet<int>());
-}
-
-TEST_F(QuicIntervalSetTest, LowerAndUpperBound) {
-  QuicIntervalSet<int> intervals;
-  intervals.Add(10, 20);
-  intervals.Add(30, 40);
-
-  //   [10, 20)  [30, 40)  end
-  //   ^                        LowerBound(5)
-  //   ^                        LowerBound(10)
-  //   ^                        LowerBound(15)
-  //             ^              LowerBound(20)
-  //             ^              LowerBound(25)
-  //             ^              LowerBound(30)
-  //             ^              LowerBound(35)
-  //                       ^    LowerBound(40)
-  //                       ^    LowerBound(50)
-  EXPECT_EQ(intervals.LowerBound(5)->min(), 10);
-  EXPECT_EQ(intervals.LowerBound(10)->min(), 10);
-  EXPECT_EQ(intervals.LowerBound(15)->min(), 10);
-  EXPECT_EQ(intervals.LowerBound(20)->min(), 30);
-  EXPECT_EQ(intervals.LowerBound(25)->min(), 30);
-  EXPECT_EQ(intervals.LowerBound(30)->min(), 30);
-  EXPECT_EQ(intervals.LowerBound(35)->min(), 30);
-  EXPECT_EQ(intervals.LowerBound(40), intervals.end());
-  EXPECT_EQ(intervals.LowerBound(50), intervals.end());
-
-  //   [10, 20)  [30, 40)  end
-  //   ^                        UpperBound(5)
-  //             ^              UpperBound(10)
-  //             ^              UpperBound(15)
-  //             ^              UpperBound(20)
-  //             ^              UpperBound(25)
-  //                       ^    UpperBound(30)
-  //                       ^    UpperBound(35)
-  //                       ^    UpperBound(40)
-  //                       ^    UpperBound(50)
-  EXPECT_EQ(intervals.UpperBound(5)->min(), 10);
-  EXPECT_EQ(intervals.UpperBound(10)->min(), 30);
-  EXPECT_EQ(intervals.UpperBound(15)->min(), 30);
-  EXPECT_EQ(intervals.UpperBound(20)->min(), 30);
-  EXPECT_EQ(intervals.UpperBound(25)->min(), 30);
-  EXPECT_EQ(intervals.UpperBound(30), intervals.end());
-  EXPECT_EQ(intervals.UpperBound(35), intervals.end());
-  EXPECT_EQ(intervals.UpperBound(40), intervals.end());
-  EXPECT_EQ(intervals.UpperBound(50), intervals.end());
-}
-
-TEST_F(QuicIntervalSetTest, SpanningInterval) {
-  // Spanning interval of an empty set is empty:
-  {
-    QuicIntervalSet<int> iset;
-    const QuicInterval<int>& ival = iset.SpanningInterval();
-    EXPECT_TRUE(ival.Empty());
-  }
-
-  // Spanning interval of a set with one interval is that interval:
-  {
-    QuicIntervalSet<int> iset;
-    iset.Add(100, 200);
-    const QuicInterval<int>& ival = iset.SpanningInterval();
-    EXPECT_EQ(100, ival.min());
-    EXPECT_EQ(200, ival.max());
-  }
-
-  // Spanning interval of a set with multiple elements is determined
-  // by the endpoints of the first and last element:
-  {
-    const QuicInterval<int>& ival = is.SpanningInterval();
-    EXPECT_EQ(100, ival.min());
-    EXPECT_EQ(2200, ival.max());
-  }
-  {
-    const QuicInterval<int>& ival = other.SpanningInterval();
-    EXPECT_EQ(50, ival.min());
-    EXPECT_EQ(2270, ival.max());
-  }
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetUnion) {
-  is.Union(other);
-  EXPECT_TRUE(Check(is, 12, 50, 70, 100, 200, 300, 400, 470, 600, 650, 670, 700,
-                    830, 870, 1000, 1100, 1230, 1270, 1830, 1900, 2000, 2100,
-                    2200, 2250, 2270));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersection) {
-  EXPECT_TRUE(is.Intersects(other));
-  EXPECT_TRUE(other.Intersects(is));
-  is.Intersection(other);
-  EXPECT_TRUE(Check(is, 7, 350, 360, 370, 380, 500, 530, 770, 800, 1300, 1400,
-                    1500, 1600, 1700, 1800));
-  EXPECT_TRUE(is.Intersects(other));
-  EXPECT_TRUE(other.Intersects(is));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionBothEmpty) {
-  QuicIntervalSet<std::string> mine, theirs;
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyMine) {
-  QuicIntervalSet<std::string> mine;
-  QuicIntervalSet<std::string> theirs("a", "b");
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyTheirs) {
-  QuicIntervalSet<std::string> mine("a", "b");
-  QuicIntervalSet<std::string> theirs;
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBeforeMine) {
-  QuicIntervalSet<std::string> mine("y", "z");
-  QuicIntervalSet<std::string> theirs;
-  theirs.Add("a", "b");
-  theirs.Add("c", "d");
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBeforeTheirs) {
-  QuicIntervalSet<std::string> mine;
-  mine.Add("a", "b");
-  mine.Add("c", "d");
-  QuicIntervalSet<std::string> theirs("y", "z");
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest,
-       QuicIntervalSetIntersectionTheirsBeforeMineInt64Singletons) {
-  QuicIntervalSet<int64_t> mine({{10, 15}});
-  QuicIntervalSet<int64_t> theirs({{-20, -5}});
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest,
-       QuicIntervalSetIntersectionMineBeforeTheirsIntSingletons) {
-  QuicIntervalSet<int> mine({{10, 15}});
-  QuicIntervalSet<int> theirs({{90, 95}});
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBetweenMine) {
-  QuicIntervalSet<int64_t> mine({{0, 5}, {40, 50}});
-  QuicIntervalSet<int64_t> theirs({{10, 15}});
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBetweenTheirs) {
-  QuicIntervalSet<int> mine({{20, 25}});
-  QuicIntervalSet<int> theirs({{10, 15}, {30, 32}});
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionAlternatingIntervals) {
-  QuicIntervalSet<int> mine, theirs;
-  mine.Add(10, 20);
-  mine.Add(40, 50);
-  mine.Add(60, 70);
-  theirs.Add(25, 39);
-  theirs.Add(55, 59);
-  theirs.Add(75, 79);
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(mine.Empty());
-  EXPECT_FALSE(mine.Intersects(theirs));
-  EXPECT_FALSE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest,
-       QuicIntervalSetIntersectionAdjacentAlternatingNonIntersectingIntervals) {
-  // Make sure that intersection with adjacent interval set is empty.
-  const QuicIntervalSet<int> x1({{0, 10}});
-  const QuicIntervalSet<int> y1({{-50, 0}, {10, 95}});
-
-  QuicIntervalSet<int> result1 = x1;
-  result1.Intersection(y1);
-  EXPECT_TRUE(result1.Empty()) << result1;
-
-  const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
-  const QuicIntervalSet<int16_t> y2(
-      {{-50, -40}, {-2, 0}, {10, 20}, {32, 40}, {90, 95}});
-
-  QuicIntervalSet<int16_t> result2 = x2;
-  result2.Intersection(y2);
-  EXPECT_TRUE(result2.Empty()) << result2;
-
-  const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
-  const QuicIntervalSet<int64_t> y3({{-10, -1}, {10, 95}});
-
-  QuicIntervalSet<int64_t> result3 = x3;
-  result3.Intersection(y3);
-  EXPECT_TRUE(result3.Empty()) << result3;
-}
-
-TEST_F(QuicIntervalSetTest,
-       QuicIntervalSetIntersectionAlternatingIntersectingIntervals) {
-  const QuicIntervalSet<int> x1({{0, 10}});
-  const QuicIntervalSet<int> y1({{-50, 1}, {9, 95}});
-  const QuicIntervalSet<int> expected_result1({{0, 1}, {9, 10}});
-
-  QuicIntervalSet<int> result1 = x1;
-  result1.Intersection(y1);
-  EXPECT_EQ(result1, expected_result1);
-
-  const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
-  const QuicIntervalSet<int16_t> y2(
-      {{-50, -40}, {-2, 2}, {9, 21}, {32, 41}, {85, 95}});
-  const QuicIntervalSet<int16_t> expected_result2(
-      {{0, 2}, {9, 10}, {20, 21}, {40, 41}, {85, 90}});
-
-  QuicIntervalSet<int16_t> result2 = x2;
-  result2.Intersection(y2);
-  EXPECT_EQ(result2, expected_result2);
-
-  const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
-  const QuicIntervalSet<int64_t> y3({{-10, 3}, {4, 95}});
-  const QuicIntervalSet<int64_t> expected_result3({{-1, 3}, {4, 10}});
-
-  QuicIntervalSet<int64_t> result3 = x3;
-  result3.Intersection(y3);
-  EXPECT_EQ(result3, expected_result3);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionIdentical) {
-  QuicIntervalSet<int> copy(is);
-  EXPECT_TRUE(copy.Intersects(is));
-  EXPECT_TRUE(is.Intersects(copy));
-  is.Intersection(copy);
-  EXPECT_EQ(copy, is);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSuperset) {
-  QuicIntervalSet<int> mine(-1, 10000);
-  EXPECT_TRUE(mine.Intersects(is));
-  EXPECT_TRUE(is.Intersects(mine));
-  mine.Intersection(is);
-  EXPECT_EQ(is, mine);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSubset) {
-  QuicIntervalSet<int> copy(is);
-  QuicIntervalSet<int> theirs(-1, 10000);
-  EXPECT_TRUE(copy.Intersects(theirs));
-  EXPECT_TRUE(theirs.Intersects(copy));
-  is.Intersection(theirs);
-  EXPECT_EQ(copy, is);
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionLargeSet) {
-  QuicIntervalSet<int> mine, theirs;
-  // mine: [0, 9), [10, 19), ..., [990, 999)
-  for (int i = 0; i < 1000; i += 10) {
-    mine.Add(i, i + 9);
-  }
-
-  theirs.Add(500, 520);
-  theirs.Add(535, 545);
-  theirs.Add(801, 809);
-  EXPECT_TRUE(mine.Intersects(theirs));
-  EXPECT_TRUE(theirs.Intersects(mine));
-  mine.Intersection(theirs);
-  EXPECT_TRUE(Check(mine, 5, 500, 509, 510, 519, 535, 539, 540, 545, 801, 809));
-  EXPECT_TRUE(mine.Intersects(theirs));
-  EXPECT_TRUE(theirs.Intersects(mine));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifference) {
-  is.Difference(other);
-  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
-                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
-  QuicIntervalSet<int> copy = is;
-  is.Difference(copy);
-  EXPECT_TRUE(is.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleBounds) {
-  std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
-  for (const QuicInterval<int>& ival : ivals) {
-    is.Difference(ival.min(), ival.max());
-  }
-  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
-                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleInterval) {
-  std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
-  for (const QuicInterval<int>& ival : ivals) {
-    is.Difference(ival);
-  }
-  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
-                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceAlternatingIntervals) {
-  QuicIntervalSet<int> mine, theirs;
-  mine.Add(10, 20);
-  mine.Add(40, 50);
-  mine.Add(60, 70);
-  theirs.Add(25, 39);
-  theirs.Add(55, 59);
-  theirs.Add(75, 79);
-
-  mine.Difference(theirs);
-  EXPECT_TRUE(Check(mine, 3, 10, 20, 40, 50, 60, 70));
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyMine) {
-  QuicIntervalSet<std::string> mine, theirs;
-  theirs.Add("a", "b");
-
-  mine.Difference(theirs);
-  EXPECT_TRUE(mine.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyTheirs) {
-  QuicIntervalSet<std::string> mine, theirs;
-  mine.Add("a", "b");
-
-  mine.Difference(theirs);
-  EXPECT_EQ(1u, mine.Size());
-  EXPECT_EQ("a", mine.begin()->min());
-  EXPECT_EQ("b", mine.begin()->max());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceTheirsBeforeMine) {
-  QuicIntervalSet<std::string> mine, theirs;
-  mine.Add("y", "z");
-  theirs.Add("a", "b");
-
-  mine.Difference(theirs);
-  EXPECT_EQ(1u, mine.Size());
-  EXPECT_EQ("y", mine.begin()->min());
-  EXPECT_EQ("z", mine.begin()->max());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceMineBeforeTheirs) {
-  QuicIntervalSet<std::string> mine, theirs;
-  mine.Add("a", "b");
-  theirs.Add("y", "z");
-
-  mine.Difference(theirs);
-  EXPECT_EQ(1u, mine.Size());
-  EXPECT_EQ("a", mine.begin()->min());
-  EXPECT_EQ("b", mine.begin()->max());
-}
-
-TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceIdentical) {
-  QuicIntervalSet<std::string> mine;
-  mine.Add("a", "b");
-  mine.Add("c", "d");
-  QuicIntervalSet<std::string> theirs(mine);
-
-  mine.Difference(theirs);
-  EXPECT_TRUE(mine.Empty());
-}
-
-TEST_F(QuicIntervalSetTest, EmptyComplement) {
-  // The complement of an empty set is the input interval:
-  QuicIntervalSet<int> iset;
-  iset.Complement(100, 200);
-  EXPECT_TRUE(Check(iset, 1, 100, 200));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, OuterCovering) {
-  QuicIntervalSet<int> iset;
-  // First add a bunch of disjoint ranges
-  iset.Add(100, 150);
-  iset.Add(200, 250);
-  iset.Add(300, 350);
-  iset.Add(400, 450);
-  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
-  // Now add a big range that covers all of these ranges
-  iset.Add(0, 500);
-  EXPECT_TRUE(Check(iset, 1, 0, 500));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, InnerCovering) {
-  QuicIntervalSet<int> iset;
-  // First add a bunch of disjoint ranges
-  iset.Add(100, 150);
-  iset.Add(200, 250);
-  iset.Add(300, 350);
-  iset.Add(400, 450);
-  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
-  // Now add a big range that partially covers the left and right most ranges.
-  iset.Add(125, 425);
-  EXPECT_TRUE(Check(iset, 1, 100, 450));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, LeftCovering) {
-  QuicIntervalSet<int> iset;
-  // First add a bunch of disjoint ranges
-  iset.Add(100, 150);
-  iset.Add(200, 250);
-  iset.Add(300, 350);
-  iset.Add(400, 450);
-  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
-  // Now add a big range that partially covers the left most range.
-  iset.Add(125, 500);
-  EXPECT_TRUE(Check(iset, 1, 100, 500));
-}
-
-TEST(QuicIntervalSetMultipleCompactionTest, RightCovering) {
-  QuicIntervalSet<int> iset;
-  // First add a bunch of disjoint ranges
-  iset.Add(100, 150);
-  iset.Add(200, 250);
-  iset.Add(300, 350);
-  iset.Add(400, 450);
-  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
-  // Now add a big range that partially covers the right most range.
-  iset.Add(0, 425);
-  EXPECT_TRUE(Check(iset, 1, 0, 450));
-}
-
-// Helper method for testing and verifying the results of a one-interval
-// completement case.
-static bool CheckOneComplement(int add_min,
-                               int add_max,
-                               int comp_min,
-                               int comp_max,
-                               int count,
-                               ...) {
-  QuicIntervalSet<int> iset;
-  iset.Add(add_min, add_max);
-  iset.Complement(comp_min, comp_max);
-  bool result = true;
-  va_list ap;
-  va_start(ap, count);
-  if (!VA_Check(iset, count, ap)) {
-    result = false;
-  }
-  va_end(ap);
-  return result;
-}
-
-TEST_F(QuicIntervalSetTest, SingleIntervalComplement) {
-  // Verify the complement of a set with one interval (i):
-  //                     |-----   i  -----|
-  // |----- args -----|
-  EXPECT_TRUE(CheckOneComplement(0, 10, 50, 150, 1, 50, 150));
-
-  //          |-----   i  -----|
-  //    |----- args -----|
-  EXPECT_TRUE(CheckOneComplement(50, 150, 0, 100, 1, 0, 50));
-
-  //    |-----   i  -----|
-  //    |----- args -----|
-  EXPECT_TRUE(CheckOneComplement(50, 150, 50, 150, 0));
-
-  //    |----------   i  ----------|
-  //        |----- args -----|
-  EXPECT_TRUE(CheckOneComplement(50, 500, 100, 300, 0));
-
-  //        |----- i -----|
-  //    |---------- args  ----------|
-  EXPECT_TRUE(CheckOneComplement(50, 500, 0, 800, 2, 0, 50, 500, 800));
-
-  //    |-----   i  -----|
-  //          |----- args -----|
-  EXPECT_TRUE(CheckOneComplement(50, 150, 100, 300, 1, 150, 300));
-
-  //    |-----   i  -----|
-  //                        |----- args -----|
-  EXPECT_TRUE(CheckOneComplement(50, 150, 200, 300, 1, 200, 300));
-}
-
-// Helper method that copies <iset> and takes its complement,
-// returning false if Check succeeds.
-static bool CheckComplement(const QuicIntervalSet<int>& iset,
-                            int comp_min,
-                            int comp_max,
-                            int count,
-                            ...) {
-  QuicIntervalSet<int> iset_copy = iset;
-  iset_copy.Complement(comp_min, comp_max);
-  bool result = true;
-  va_list ap;
-  va_start(ap, count);
-  if (!VA_Check(iset_copy, count, ap)) {
-    result = false;
-  }
-  va_end(ap);
-  return result;
-}
-
-TEST_F(QuicIntervalSetTest, MultiIntervalComplement) {
-  // Initialize a small test set:
-  QuicIntervalSet<int> iset;
-  iset.Add(100, 200);
-  iset.Add(300, 400);
-  iset.Add(500, 600);
-
-  //                     |-----   i  -----|
-  // |----- comp -----|
-  EXPECT_TRUE(CheckComplement(iset, 0, 50, 1, 0, 50));
-
-  //          |-----   i  -----|
-  //    |----- comp -----|
-  EXPECT_TRUE(CheckComplement(iset, 0, 200, 1, 0, 100));
-  EXPECT_TRUE(CheckComplement(iset, 0, 220, 2, 0, 100, 200, 220));
-
-  //    |-----   i  -----|
-  //    |----- comp -----|
-  EXPECT_TRUE(CheckComplement(iset, 100, 600, 2, 200, 300, 400, 500));
-
-  //    |----------   i  ----------|
-  //        |----- comp -----|
-  EXPECT_TRUE(CheckComplement(iset, 300, 400, 0));
-  EXPECT_TRUE(CheckComplement(iset, 250, 400, 1, 250, 300));
-  EXPECT_TRUE(CheckComplement(iset, 300, 450, 1, 400, 450));
-  EXPECT_TRUE(CheckComplement(iset, 250, 450, 2, 250, 300, 400, 450));
-
-  //        |----- i -----|
-  //    |---------- comp  ----------|
-  EXPECT_TRUE(
-      CheckComplement(iset, 0, 700, 4, 0, 100, 200, 300, 400, 500, 600, 700));
-
-  //    |-----   i  -----|
-  //          |----- comp -----|
-  EXPECT_TRUE(CheckComplement(iset, 400, 700, 2, 400, 500, 600, 700));
-  EXPECT_TRUE(CheckComplement(iset, 350, 700, 2, 400, 500, 600, 700));
-
-  //    |-----   i  -----|
-  //                        |----- comp -----|
-  EXPECT_TRUE(CheckComplement(iset, 700, 800, 1, 700, 800));
-}
-
-// Verifies ToString, operator<< don't assert.
-TEST_F(QuicIntervalSetTest, ToString) {
-  QuicIntervalSet<int> iset;
-  iset.Add(300, 400);
-  iset.Add(100, 200);
-  iset.Add(500, 600);
-  EXPECT_TRUE(!iset.ToString().empty());
-  QUIC_VLOG(2) << iset;
-  // Order and format of ToString() output is guaranteed.
-  EXPECT_EQ("{ [100, 200) [300, 400) [500, 600) }", iset.ToString());
-  EXPECT_EQ("{ [1, 2) }", QuicIntervalSet<int>(1, 2).ToString());
-  EXPECT_EQ("{ }", QuicIntervalSet<int>().ToString());
-}
-
-TEST_F(QuicIntervalSetTest, ConstructionDiscardsEmptyInterval) {
-  EXPECT_TRUE(QuicIntervalSet<int>(QuicInterval<int>(2, 2)).Empty());
-  EXPECT_TRUE(QuicIntervalSet<int>(2, 2).Empty());
-  EXPECT_FALSE(QuicIntervalSet<int>(QuicInterval<int>(2, 3)).Empty());
-  EXPECT_FALSE(QuicIntervalSet<int>(2, 3).Empty());
-}
-
-TEST_F(QuicIntervalSetTest, Swap) {
-  QuicIntervalSet<int> a, b;
-  a.Add(300, 400);
-  b.Add(100, 200);
-  b.Add(500, 600);
-  std::swap(a, b);
-  EXPECT_TRUE(Check(a, 2, 100, 200, 500, 600));
-  EXPECT_TRUE(Check(b, 1, 300, 400));
-  std::swap(a, b);
-  EXPECT_TRUE(Check(a, 1, 300, 400));
-  EXPECT_TRUE(Check(b, 2, 100, 200, 500, 600));
-}
-
-TEST_F(QuicIntervalSetTest, OutputReturnsOstreamRef) {
-  std::stringstream ss;
-  const QuicIntervalSet<int> v(QuicInterval<int>(1, 2));
-  auto return_type_is_a_ref = [](std::ostream&) {};
-  return_type_is_a_ref(ss << v);
-}
-
-struct NotOstreamable {
-  bool operator<(const NotOstreamable&) const { return false; }
-  bool operator>(const NotOstreamable&) const { return false; }
-  bool operator!=(const NotOstreamable&) const { return false; }
-  bool operator>=(const NotOstreamable&) const { return true; }
-  bool operator<=(const NotOstreamable&) const { return true; }
-  bool operator==(const NotOstreamable&) const { return true; }
-};
-
-TEST_F(QuicIntervalSetTest, IntervalOfTypeWithNoOstreamSupport) {
-  const NotOstreamable v;
-  const QuicIntervalSet<NotOstreamable> d(QuicInterval<NotOstreamable>(v, v));
-  // EXPECT_EQ builds a string representation of d. If d::operator<<()
-  // would be defined then this test would not compile because NotOstreamable
-  // objects lack the operator<<() support.
-  EXPECT_EQ(d, d);
-}
-
-class QuicIntervalSetInitTest : public QuicTest {
- protected:
-  const std::vector<QuicInterval<int>> intervals_{{0, 1}, {2, 4}};
-};
-
-TEST_F(QuicIntervalSetInitTest, DirectInit) {
-  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
-  QuicIntervalSet<int> s(il);
-  EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, CopyInit) {
-  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
-  QuicIntervalSet<int> s = il;
-  EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, AssignIterPair) {
-  QuicIntervalSet<int> s(0, 1000);  // Make sure assign clears.
-  s.assign(intervals_.begin(), intervals_.end());
-  EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, AssignInitList) {
-  QuicIntervalSet<int> s(0, 1000);  // Make sure assign clears.
-  s.assign({{0, 1}, {2, 3}, {3, 4}});
-  EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, AssignmentInitList) {
-  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
-  QuicIntervalSet<int> s;
-  s = il;
-  EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-TEST_F(QuicIntervalSetInitTest, BracedInitThenBracedAssign) {
-  QuicIntervalSet<int> s{{0, 1}, {2, 3}, {3, 4}};
-  s = {{0, 1}, {2, 4}};
-  EXPECT_THAT(s, ElementsAreArray(intervals_));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_interval_test.cc b/quic/core/quic_interval_test.cc
deleted file mode 100644
index 4ec9fa6..0000000
--- a/quic/core/quic_interval_test.cc
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_interval.h"
-
-#include <sstream>
-#include <string>
-#include <type_traits>
-#include <utility>
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-template <typename ForwardIterator>
-void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
-  while (begin != end) {
-    auto temp = begin;
-    ++begin;
-    delete *temp;
-  }
-}
-
-template <typename T>
-void STLDeleteElements(T* container) {
-  if (!container)
-    return;
-  STLDeleteContainerPointers(container->begin(), container->end());
-  container->clear();
-}
-
-class ConstructorListener {
- public:
-  ConstructorListener(int* copy_construct_counter, int* move_construct_counter)
-      : copy_construct_counter_(copy_construct_counter),
-        move_construct_counter_(move_construct_counter) {
-    *copy_construct_counter_ = 0;
-    *move_construct_counter_ = 0;
-  }
-  ConstructorListener(const ConstructorListener& other) {
-    copy_construct_counter_ = other.copy_construct_counter_;
-    move_construct_counter_ = other.move_construct_counter_;
-    ++*copy_construct_counter_;
-  }
-  ConstructorListener(ConstructorListener&& other) {
-    copy_construct_counter_ = other.copy_construct_counter_;
-    move_construct_counter_ = other.move_construct_counter_;
-    ++*move_construct_counter_;
-  }
-  bool operator<(const ConstructorListener&) { return false; }
-  bool operator>(const ConstructorListener&) { return false; }
-  bool operator<=(const ConstructorListener&) { return true; }
-  bool operator>=(const ConstructorListener&) { return true; }
-  bool operator==(const ConstructorListener&) { return true; }
-
- private:
-  int* copy_construct_counter_;
-  int* move_construct_counter_;
-};
-
-TEST(QuicIntervalConstructorTest, Move) {
-  int object1_copy_count, object1_move_count;
-  ConstructorListener object1(&object1_copy_count, &object1_move_count);
-  int object2_copy_count, object2_move_count;
-  ConstructorListener object2(&object2_copy_count, &object2_move_count);
-
-  QuicInterval<ConstructorListener> interval(object1, std::move(object2));
-  EXPECT_EQ(1, object1_copy_count);
-  EXPECT_EQ(0, object1_move_count);
-  EXPECT_EQ(0, object2_copy_count);
-  EXPECT_EQ(1, object2_move_count);
-}
-
-TEST(QuicIntervalConstructorTest, ImplicitConversion) {
-  struct WrappedInt {
-    WrappedInt(int value) : value(value) {}
-    bool operator<(const WrappedInt& other) { return value < other.value; }
-    bool operator>(const WrappedInt& other) { return value > other.value; }
-    bool operator<=(const WrappedInt& other) { return value <= other.value; }
-    bool operator>=(const WrappedInt& other) { return value >= other.value; }
-    bool operator==(const WrappedInt& other) { return value == other.value; }
-    int value;
-  };
-
-  static_assert(std::is_convertible<int, WrappedInt>::value, "");
-  static_assert(
-      std::is_constructible<QuicInterval<WrappedInt>, int, int>::value, "");
-
-  QuicInterval<WrappedInt> i(10, 20);
-  EXPECT_EQ(10, i.min().value);
-  EXPECT_EQ(20, i.max().value);
-}
-
-class QuicIntervalTest : public QuicTest {
- protected:
-  // Test intersection between the two intervals i1 and i2.  Tries
-  // i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff
-  // changes_i1 is true, and the same for changes_i2.  The resulting
-  // intersection should be result.
-  void TestIntersect(const QuicInterval<int64_t>& i1,
-                     const QuicInterval<int64_t>& i2,
-                     bool changes_i1,
-                     bool changes_i2,
-                     const QuicInterval<int64_t>& result) {
-    QuicInterval<int64_t> i;
-    i = i1;
-    EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i == result);
-    i = i2;
-    EXPECT_TRUE(i.IntersectWith(i1) == changes_i2 && i == result);
-  }
-};
-
-TEST_F(QuicIntervalTest, ConstructorsCopyAndClear) {
-  QuicInterval<int32_t> empty;
-  EXPECT_TRUE(empty.Empty());
-
-  QuicInterval<int32_t> d2(0, 100);
-  EXPECT_EQ(0, d2.min());
-  EXPECT_EQ(100, d2.max());
-  EXPECT_EQ(QuicInterval<int32_t>(0, 100), d2);
-  EXPECT_NE(QuicInterval<int32_t>(0, 99), d2);
-
-  empty = d2;
-  EXPECT_EQ(0, d2.min());
-  EXPECT_EQ(100, d2.max());
-  EXPECT_TRUE(empty == d2);
-  EXPECT_EQ(empty, d2);
-  EXPECT_TRUE(d2 == empty);
-  EXPECT_EQ(d2, empty);
-
-  QuicInterval<int32_t> max_less_than_min(40, 20);
-  EXPECT_TRUE(max_less_than_min.Empty());
-  EXPECT_EQ(40, max_less_than_min.min());
-  EXPECT_EQ(20, max_less_than_min.max());
-
-  QuicInterval<int> d3(10, 20);
-  d3.Clear();
-  EXPECT_TRUE(d3.Empty());
-}
-
-TEST_F(QuicIntervalTest, MakeQuicInterval) {
-  static_assert(
-      std::is_same<QuicInterval<int>, decltype(MakeQuicInterval(0, 3))>::value,
-      "Type is deduced incorrectly.");
-  static_assert(std::is_same<QuicInterval<double>,
-                             decltype(MakeQuicInterval(0., 3.))>::value,
-                "Type is deduced incorrectly.");
-
-  EXPECT_EQ(MakeQuicInterval(0., 3.), QuicInterval<double>(0, 3));
-}
-
-TEST_F(QuicIntervalTest, GettersSetters) {
-  QuicInterval<int32_t> d1(100, 200);
-
-  // SetMin:
-  d1.SetMin(30);
-  EXPECT_EQ(30, d1.min());
-  EXPECT_EQ(200, d1.max());
-
-  // SetMax:
-  d1.SetMax(220);
-  EXPECT_EQ(30, d1.min());
-  EXPECT_EQ(220, d1.max());
-
-  // Set:
-  d1.Clear();
-  d1.Set(30, 220);
-  EXPECT_EQ(30, d1.min());
-  EXPECT_EQ(220, d1.max());
-
-  // SpanningUnion:
-  QuicInterval<int32_t> d2;
-  EXPECT_TRUE(!d1.SpanningUnion(d2));
-  EXPECT_EQ(30, d1.min());
-  EXPECT_EQ(220, d1.max());
-
-  EXPECT_TRUE(d2.SpanningUnion(d1));
-  EXPECT_EQ(30, d2.min());
-  EXPECT_EQ(220, d2.max());
-
-  d2.SetMin(40);
-  d2.SetMax(100);
-  EXPECT_TRUE(!d1.SpanningUnion(d2));
-  EXPECT_EQ(30, d1.min());
-  EXPECT_EQ(220, d1.max());
-
-  d2.SetMin(20);
-  d2.SetMax(100);
-  EXPECT_TRUE(d1.SpanningUnion(d2));
-  EXPECT_EQ(20, d1.min());
-  EXPECT_EQ(220, d1.max());
-
-  d2.SetMin(50);
-  d2.SetMax(300);
-  EXPECT_TRUE(d1.SpanningUnion(d2));
-  EXPECT_EQ(20, d1.min());
-  EXPECT_EQ(300, d1.max());
-
-  d2.SetMin(0);
-  d2.SetMax(500);
-  EXPECT_TRUE(d1.SpanningUnion(d2));
-  EXPECT_EQ(0, d1.min());
-  EXPECT_EQ(500, d1.max());
-
-  d2.SetMin(100);
-  d2.SetMax(0);
-  EXPECT_TRUE(!d1.SpanningUnion(d2));
-  EXPECT_EQ(0, d1.min());
-  EXPECT_EQ(500, d1.max());
-  EXPECT_TRUE(d2.SpanningUnion(d1));
-  EXPECT_EQ(0, d2.min());
-  EXPECT_EQ(500, d2.max());
-}
-
-TEST_F(QuicIntervalTest, CoveringOps) {
-  const QuicInterval<int64_t> empty;
-  const QuicInterval<int64_t> d(100, 200);
-  const QuicInterval<int64_t> d1(0, 50);
-  const QuicInterval<int64_t> d2(50, 110);
-  const QuicInterval<int64_t> d3(110, 180);
-  const QuicInterval<int64_t> d4(180, 220);
-  const QuicInterval<int64_t> d5(220, 300);
-  const QuicInterval<int64_t> d6(100, 150);
-  const QuicInterval<int64_t> d7(150, 200);
-  const QuicInterval<int64_t> d8(0, 300);
-
-  // Intersection:
-  EXPECT_TRUE(d.Intersects(d));
-  EXPECT_TRUE(!empty.Intersects(d) && !d.Intersects(empty));
-  EXPECT_TRUE(!d.Intersects(d1) && !d1.Intersects(d));
-  EXPECT_TRUE(d.Intersects(d2) && d2.Intersects(d));
-  EXPECT_TRUE(d.Intersects(d3) && d3.Intersects(d));
-  EXPECT_TRUE(d.Intersects(d4) && d4.Intersects(d));
-  EXPECT_TRUE(!d.Intersects(d5) && !d5.Intersects(d));
-  EXPECT_TRUE(d.Intersects(d6) && d6.Intersects(d));
-  EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d));
-  EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d));
-
-  QuicInterval<int64_t> i;
-  EXPECT_TRUE(d.Intersects(d, &i) && d == i);
-  EXPECT_TRUE(!empty.Intersects(d, nullptr) && !d.Intersects(empty, nullptr));
-  EXPECT_TRUE(!d.Intersects(d1, nullptr) && !d1.Intersects(d, nullptr));
-  EXPECT_TRUE(d.Intersects(d2, &i) && i == QuicInterval<int64_t>(100, 110));
-  EXPECT_TRUE(d2.Intersects(d, &i) && i == QuicInterval<int64_t>(100, 110));
-  EXPECT_TRUE(d.Intersects(d3, &i) && i == d3);
-  EXPECT_TRUE(d3.Intersects(d, &i) && i == d3);
-  EXPECT_TRUE(d.Intersects(d4, &i) && i == QuicInterval<int64_t>(180, 200));
-  EXPECT_TRUE(d4.Intersects(d, &i) && i == QuicInterval<int64_t>(180, 200));
-  EXPECT_TRUE(!d.Intersects(d5, nullptr) && !d5.Intersects(d, nullptr));
-  EXPECT_TRUE(d.Intersects(d6, &i) && i == d6);
-  EXPECT_TRUE(d6.Intersects(d, &i) && i == d6);
-  EXPECT_TRUE(d.Intersects(d7, &i) && i == d7);
-  EXPECT_TRUE(d7.Intersects(d, &i) && i == d7);
-  EXPECT_TRUE(d.Intersects(d8, &i) && i == d);
-  EXPECT_TRUE(d8.Intersects(d, &i) && i == d);
-
-  // Test IntersectsWith().
-  // Arguments are TestIntersect(i1, i2, changes_i1, changes_i2, result).
-  TestIntersect(empty, d, false, true, empty);
-  TestIntersect(d, d1, true, true, empty);
-  TestIntersect(d1, d2, true, true, empty);
-  TestIntersect(d, d2, true, true, QuicInterval<int64_t>(100, 110));
-  TestIntersect(d8, d, true, false, d);
-  TestIntersect(d8, d1, true, false, d1);
-  TestIntersect(d8, d5, true, false, d5);
-
-  // Contains:
-  EXPECT_TRUE(!empty.Contains(d) && !d.Contains(empty));
-  EXPECT_TRUE(d.Contains(d));
-  EXPECT_TRUE(!d.Contains(d1) && !d1.Contains(d));
-  EXPECT_TRUE(!d.Contains(d2) && !d2.Contains(d));
-  EXPECT_TRUE(d.Contains(d3) && !d3.Contains(d));
-  EXPECT_TRUE(!d.Contains(d4) && !d4.Contains(d));
-  EXPECT_TRUE(!d.Contains(d5) && !d5.Contains(d));
-  EXPECT_TRUE(d.Contains(d6) && !d6.Contains(d));
-  EXPECT_TRUE(d.Contains(d7) && !d7.Contains(d));
-  EXPECT_TRUE(!d.Contains(d8) && d8.Contains(d));
-
-  EXPECT_TRUE(d.Contains(100));
-  EXPECT_TRUE(!d.Contains(200));
-  EXPECT_TRUE(d.Contains(150));
-  EXPECT_TRUE(!d.Contains(99));
-  EXPECT_TRUE(!d.Contains(201));
-
-  // Difference:
-  std::vector<QuicInterval<int64_t>*> diff;
-
-  EXPECT_TRUE(!d.Difference(empty, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(100, diff[0]->min());
-  EXPECT_EQ(200, diff[0]->max());
-  STLDeleteElements(&diff);
-  EXPECT_TRUE(!empty.Difference(d, &diff) && diff.empty());
-
-  EXPECT_TRUE(d.Difference(d, &diff) && diff.empty());
-  EXPECT_TRUE(!d.Difference(d1, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(100, diff[0]->min());
-  EXPECT_EQ(200, diff[0]->max());
-  STLDeleteElements(&diff);
-
-  QuicInterval<int64_t> lo;
-  QuicInterval<int64_t> hi;
-
-  EXPECT_TRUE(d.Difference(d2, &lo, &hi));
-  EXPECT_TRUE(lo.Empty());
-  EXPECT_EQ(110, hi.min());
-  EXPECT_EQ(200, hi.max());
-  EXPECT_TRUE(d.Difference(d2, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(110, diff[0]->min());
-  EXPECT_EQ(200, diff[0]->max());
-  STLDeleteElements(&diff);
-
-  EXPECT_TRUE(d.Difference(d3, &lo, &hi));
-  EXPECT_EQ(100, lo.min());
-  EXPECT_EQ(110, lo.max());
-  EXPECT_EQ(180, hi.min());
-  EXPECT_EQ(200, hi.max());
-  EXPECT_TRUE(d.Difference(d3, &diff));
-  EXPECT_EQ(2u, diff.size());
-  EXPECT_EQ(100, diff[0]->min());
-  EXPECT_EQ(110, diff[0]->max());
-  EXPECT_EQ(180, diff[1]->min());
-  EXPECT_EQ(200, diff[1]->max());
-  STLDeleteElements(&diff);
-
-  EXPECT_TRUE(d.Difference(d4, &lo, &hi));
-  EXPECT_EQ(100, lo.min());
-  EXPECT_EQ(180, lo.max());
-  EXPECT_TRUE(hi.Empty());
-  EXPECT_TRUE(d.Difference(d4, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(100, diff[0]->min());
-  EXPECT_EQ(180, diff[0]->max());
-  STLDeleteElements(&diff);
-
-  EXPECT_FALSE(d.Difference(d5, &lo, &hi));
-  EXPECT_EQ(100, lo.min());
-  EXPECT_EQ(200, lo.max());
-  EXPECT_TRUE(hi.Empty());
-  EXPECT_FALSE(d.Difference(d5, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(100, diff[0]->min());
-  EXPECT_EQ(200, diff[0]->max());
-  STLDeleteElements(&diff);
-
-  EXPECT_TRUE(d.Difference(d6, &lo, &hi));
-  EXPECT_TRUE(lo.Empty());
-  EXPECT_EQ(150, hi.min());
-  EXPECT_EQ(200, hi.max());
-  EXPECT_TRUE(d.Difference(d6, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(150, diff[0]->min());
-  EXPECT_EQ(200, diff[0]->max());
-  STLDeleteElements(&diff);
-
-  EXPECT_TRUE(d.Difference(d7, &lo, &hi));
-  EXPECT_EQ(100, lo.min());
-  EXPECT_EQ(150, lo.max());
-  EXPECT_TRUE(hi.Empty());
-  EXPECT_TRUE(d.Difference(d7, &diff));
-  EXPECT_EQ(1u, diff.size());
-  EXPECT_EQ(100, diff[0]->min());
-  EXPECT_EQ(150, diff[0]->max());
-  STLDeleteElements(&diff);
-
-  EXPECT_TRUE(d.Difference(d8, &lo, &hi));
-  EXPECT_TRUE(lo.Empty());
-  EXPECT_TRUE(hi.Empty());
-  EXPECT_TRUE(d.Difference(d8, &diff) && diff.empty());
-}
-
-TEST_F(QuicIntervalTest, Separated) {
-  using QI = QuicInterval<int>;
-  EXPECT_FALSE(QI(100, 200).Separated(QI(100, 200)));
-  EXPECT_FALSE(QI(100, 200).Separated(QI(200, 300)));
-  EXPECT_TRUE(QI(100, 200).Separated(QI(201, 300)));
-  EXPECT_FALSE(QI(100, 200).Separated(QI(0, 100)));
-  EXPECT_TRUE(QI(100, 200).Separated(QI(0, 99)));
-  EXPECT_FALSE(QI(100, 200).Separated(QI(150, 170)));
-  EXPECT_FALSE(QI(150, 170).Separated(QI(100, 200)));
-  EXPECT_FALSE(QI(100, 200).Separated(QI(150, 250)));
-  EXPECT_FALSE(QI(150, 250).Separated(QI(100, 200)));
-}
-
-TEST_F(QuicIntervalTest, Length) {
-  const QuicInterval<int> empty1;
-  const QuicInterval<int> empty2(1, 1);
-  const QuicInterval<int> empty3(1, 0);
-  const QuicInterval<QuicTime> empty4(
-      QuicTime::Zero() + QuicTime::Delta::FromSeconds(1), QuicTime::Zero());
-  const QuicInterval<int> d1(1, 2);
-  const QuicInterval<int> d2(0, 50);
-  const QuicInterval<QuicTime> d3(
-      QuicTime::Zero(), QuicTime::Zero() + QuicTime::Delta::FromSeconds(1));
-  const QuicInterval<QuicTime> d4(
-      QuicTime::Zero() + QuicTime::Delta::FromSeconds(3600),
-      QuicTime::Zero() + QuicTime::Delta::FromSeconds(5400));
-
-  EXPECT_EQ(0, empty1.Length());
-  EXPECT_EQ(0, empty2.Length());
-  EXPECT_EQ(0, empty3.Length());
-  EXPECT_EQ(QuicTime::Delta::Zero(), empty4.Length());
-  EXPECT_EQ(1, d1.Length());
-  EXPECT_EQ(50, d2.Length());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(1), d3.Length());
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(1800), d4.Length());
-}
-
-TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOperatorMinus) {
-  // QuicInterval<T> should work even if T does not support operator-().  We
-  // just can't call QuicInterval<T>::Length() for such types.
-  const QuicInterval<std::string> d1("a", "b");
-  const QuicInterval<std::pair<int, int>> d2({1, 2}, {4, 3});
-  EXPECT_EQ("a", d1.min());
-  EXPECT_EQ("b", d1.max());
-  EXPECT_EQ(std::make_pair(1, 2), d2.min());
-  EXPECT_EQ(std::make_pair(4, 3), d2.max());
-}
-
-struct NoEquals {
-  NoEquals(int v) : value(v) {}  // NOLINT
-  int value;
-  bool operator<(const NoEquals& other) const { return value < other.value; }
-};
-
-TEST_F(QuicIntervalTest, OrderedComparisonForTypeWithoutEquals) {
-  const QuicInterval<NoEquals> d1(0, 4);
-  const QuicInterval<NoEquals> d2(0, 3);
-  const QuicInterval<NoEquals> d3(1, 4);
-  const QuicInterval<NoEquals> d4(1, 5);
-  const QuicInterval<NoEquals> d6(0, 4);
-  EXPECT_TRUE(d1 < d2);
-  EXPECT_TRUE(d1 < d3);
-  EXPECT_TRUE(d1 < d4);
-  EXPECT_FALSE(d1 < d6);
-}
-
-TEST_F(QuicIntervalTest, OutputReturnsOstreamRef) {
-  std::stringstream ss;
-  const QuicInterval<int> v(1, 2);
-  // If (ss << v) were to return a value, it wouldn't match the signature of
-  // return_type_is_a_ref() function.
-  auto return_type_is_a_ref = [](std::ostream&) {};
-  return_type_is_a_ref(ss << v);
-}
-
-struct NotOstreamable {
-  bool operator<(const NotOstreamable&) const { return false; }
-  bool operator>=(const NotOstreamable&) const { return true; }
-  bool operator==(const NotOstreamable&) const { return true; }
-};
-
-TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOstreamSupport) {
-  const NotOstreamable v;
-  const QuicInterval<NotOstreamable> d(v, v);
-  // EXPECT_EQ builds a string representation of d. If d::operator<<() would be
-  // defined then this test would not compile because NotOstreamable objects
-  // lack the operator<<() support.
-  EXPECT_EQ(d, d);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_legacy_version_encapsulator.cc b/quic/core/quic_legacy_version_encapsulator.cc
deleted file mode 100644
index 11d2293..0000000
--- a/quic/core/quic_legacy_version_encapsulator.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_legacy_version_encapsulator.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
-    QuicPacketBuffer packet_buffer)
-    : packet_buffer_(packet_buffer) {}
-
-QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}
-
-// static
-QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
-    absl::string_view sni) {
-  // The number 52 is the sum of:
-  // - Flags (1 byte)
-  // - Server Connection ID (8 bytes)
-  // - Version (4 bytes)
-  // - Packet Number (1 byte)
-  // - Message Authentication Hash (12 bytes)
-  // - Frame Type (1 byte)
-  // - Stream ID (1 byte)
-  // - ClientHello tag (4 bytes)
-  // - ClientHello num tags (2 bytes)
-  // - Padding (2 bytes)
-  // - SNI tag (4 bytes)
-  // - SNI end offset (4 bytes)
-  // - QLVE tag (4 bytes)
-  // - QLVE end offset (4 bytes)
-  return 52 + sni.length();
-}
-
-QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
-  return packet_buffer_;
-}
-
-void QuicLegacyVersionEncapsulator::OnSerializedPacket(
-    SerializedPacket serialized_packet) {
-  if (encrypted_length_ != 0) {
-    unrecoverable_failure_encountered_ = true;
-    QUIC_BUG(quic_bug_10615_1) << "OnSerializedPacket called twice";
-    return;
-  }
-  if (serialized_packet.encrypted_length == 0) {
-    unrecoverable_failure_encountered_ = true;
-    QUIC_BUG(quic_bug_10615_2) << "OnSerializedPacket called with empty packet";
-    return;
-  }
-  encrypted_length_ = serialized_packet.encrypted_length;
-}
-
-void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
-    QuicErrorCode error,
-    const std::string& error_details) {
-  unrecoverable_failure_encountered_ = true;
-  QUIC_BUG(quic_bug_10615_3) << "QuicLegacyVersionEncapsulator received error "
-                             << error << ": " << error_details;
-}
-
-bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
-    HasRetransmittableData /*retransmittable*/,
-    IsHandshake /*handshake*/) {
-  return true;
-}
-
-const QuicFrames
-QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
-  // We do not want to ever include any ACKs here, return an empty array.
-  return QuicFrames();
-}
-
-SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate(
-    bool /*is_mtu_discovery*/,
-    EncryptionLevel /*encryption_level*/) {
-  return SEND_TO_WRITER;
-}
-
-// static
-QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
-    absl::string_view sni,
-    absl::string_view inner_packet,
-    const QuicConnectionId& server_connection_id,
-    QuicTime creation_time,
-    QuicByteCount outer_max_packet_length,
-    char* out) {
-  if (outer_max_packet_length > kMaxOutgoingPacketSize) {
-    outer_max_packet_length = kMaxOutgoingPacketSize;
-  }
-  CryptoHandshakeMessage outer_chlo;
-  outer_chlo.set_tag(kCHLO);
-  outer_chlo.SetStringPiece(kSNI, sni);
-  outer_chlo.SetStringPiece(kQLVE, inner_packet);
-  const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
-  QUICHE_DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
-  QUICHE_DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
-  QuicStreamFrame outer_stream_frame(
-      QuicUtils::GetCryptoStreamId(
-          LegacyVersionForEncapsulation().transport_version),
-      /*fin=*/false,
-      /*offset=*/0, serialized_outer_chlo.AsStringPiece());
-  QuicFramer outer_framer(
-      ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
-      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
-  outer_framer.SetInitialObfuscators(server_connection_id);
-  char outer_encrypted_packet[kMaxOutgoingPacketSize];
-  QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
-  QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
-  QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
-                                  &creator_delegate);
-  outer_creator.SetMaxPacketLength(outer_max_packet_length);
-  outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
-  outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
-  if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
-                                         NOT_RETRANSMISSION)) {
-    QUIC_BUG(quic_bug_10615_4)
-        << "Failed to add Legacy Version Encapsulation stream frame "
-           "(max packet length is "
-        << outer_creator.max_packet_length() << ") " << outer_stream_frame;
-    return 0;
-  }
-  outer_creator.FlushCurrentPacket();
-  const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
-  if (creator_delegate.unrecoverable_failure_encountered_ ||
-      encrypted_length == 0) {
-    QUIC_BUG(quic_bug_10615_5)
-        << "Failed to perform Legacy Version Encapsulation of "
-        << inner_packet.length() << " bytes";
-    return 0;
-  }
-  if (encrypted_length > kMaxOutgoingPacketSize) {
-    QUIC_BUG(quic_bug_10615_6)
-        << "Legacy Version Encapsulation outer creator generated a "
-           "packet with unexpected length "
-        << encrypted_length;
-    return 0;
-  }
-
-  QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
-                  << inner_packet.length() << " bytes to " << encrypted_length;
-
-  // Replace our current packet with the encapsulated one.
-  memcpy(out, outer_encrypted_packet, encrypted_length);
-  return encrypted_length;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_legacy_version_encapsulator.h b/quic/core/quic_legacy_version_encapsulator.h
deleted file mode 100644
index 1d528fe..0000000
--- a/quic/core/quic_legacy_version_encapsulator.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QuicLegacyVersionEncapsulator is responsible for encapsulation of packets
-// using Legacy Version Encapsulation.
-
-class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator
-    : public QuicPacketCreator::DelegateInterface {
- public:
-  // Encapsulates |inner_packet| into a new encapsulated packet that uses a
-  // CHLO of version LegacyVersionForEncapsulation() with server name |sni|
-  // exposed and using |server_connection_id|. The packet will be padded up to
-  // |outer_max_packet_length| bytes if necessary. On failure, returns 0. On
-  // success, returns the length of the outer encapsulated packet, and copies
-  // the contents of the encapsulated packet to |out|. |out| must point to a
-  // valid memory buffer capable of holding kMaxOutgoingPacketSize bytes.
-  static QuicPacketLength Encapsulate(
-      absl::string_view sni,
-      absl::string_view inner_packet,
-      const QuicConnectionId& server_connection_id,
-      QuicTime creation_time,
-      QuicByteCount outer_max_packet_length,
-      char* out);
-
-  // Returns the number of bytes of minimum overhead caused by Legacy Version
-  // Encapsulation, based on the length of the provided server name |sni|.
-  // The overhead may be higher due to extra padding added.
-  static QuicByteCount GetMinimumOverhead(absl::string_view sni);
-
-  // Overrides for QuicPacketCreator::DelegateInterface.
-  QuicPacketBuffer GetPacketBuffer() override;
-  void OnSerializedPacket(SerializedPacket serialized_packet) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            const std::string& error_details) override;
-  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
-                            IsHandshake handshake) override;
-  const QuicFrames MaybeBundleAckOpportunistically() override;
-  SerializedPacketFate GetSerializedPacketFate(
-      bool is_mtu_discovery,
-      EncryptionLevel encryption_level) override;
-
-  ~QuicLegacyVersionEncapsulator() override;
-
- private:
-  explicit QuicLegacyVersionEncapsulator(QuicPacketBuffer packet_buffer);
-
-  // Disallow copy, move and assignment.
-  QuicLegacyVersionEncapsulator(const QuicLegacyVersionEncapsulator&) = delete;
-  QuicLegacyVersionEncapsulator(QuicLegacyVersionEncapsulator&&) = delete;
-  QuicLegacyVersionEncapsulator& operator=(
-      const QuicLegacyVersionEncapsulator&) = delete;
-  QuicLegacyVersionEncapsulator& operator=(QuicLegacyVersionEncapsulator&&) =
-      delete;
-
-  QuicPacketBuffer packet_buffer_;
-  QuicPacketLength encrypted_length_ = 0;
-  bool unrecoverable_failure_encountered_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
diff --git a/quic/core/quic_legacy_version_encapsulator_test.cc b/quic/core/quic_legacy_version_encapsulator_test.cc
deleted file mode 100644
index b0e11a3..0000000
--- a/quic/core/quic_legacy_version_encapsulator_test.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_legacy_version_encapsulator.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicLegacyVersionEncapsulatorTest
-    : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicLegacyVersionEncapsulatorTest()
-      : version_(GetParam()),
-        sni_("test.example.org"),
-        server_connection_id_(TestConnectionId()),
-        outer_max_packet_length_(kMaxOutgoingPacketSize),
-        encapsulated_length_(0) {}
-
-  void Encapsulate(const std::string& inner_packet) {
-    encapsulated_length_ = QuicLegacyVersionEncapsulator::Encapsulate(
-        sni_, inner_packet, server_connection_id_, QuicTime::Zero(),
-        outer_max_packet_length_, outer_buffer_);
-  }
-
-  void CheckEncapsulation() {
-    ASSERT_NE(encapsulated_length_, 0u);
-    ASSERT_EQ(encapsulated_length_, outer_max_packet_length_);
-    // Verify that the encapsulated packet parses as encapsulated.
-    PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
-    QuicLongHeaderType long_packet_type;
-    bool version_present;
-    bool has_length_prefix;
-    QuicVersionLabel version_label;
-    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-    QuicConnectionId destination_connection_id, source_connection_id;
-    absl::optional<absl::string_view> retry_token;
-    std::string detailed_error;
-    const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-        QuicEncryptedPacket(outer_buffer_, encapsulated_length_),
-        kQuicDefaultConnectionIdLength, &format, &long_packet_type,
-        &version_present, &has_length_prefix, &version_label, &parsed_version,
-        &destination_connection_id, &source_connection_id, &retry_token,
-        &detailed_error);
-    ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
-    EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
-    EXPECT_TRUE(version_present);
-    EXPECT_FALSE(has_length_prefix);
-    EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
-    EXPECT_EQ(destination_connection_id, server_connection_id_);
-    EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
-    EXPECT_FALSE(retry_token.has_value());
-    EXPECT_TRUE(detailed_error.empty());
-  }
-
-  QuicByteCount Overhead() {
-    return QuicLegacyVersionEncapsulator::GetMinimumOverhead(sni_);
-  }
-
-  ParsedQuicVersion version_;
-  std::string sni_;
-  QuicConnectionId server_connection_id_;
-  QuicByteCount outer_max_packet_length_;
-  char outer_buffer_[kMaxOutgoingPacketSize];
-  QuicPacketLength encapsulated_length_;
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicLegacyVersionEncapsulatorTests,
-                         QuicLegacyVersionEncapsulatorTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, Simple) {
-  Encapsulate("TEST_INNER_PACKET");
-  CheckEncapsulation();
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, TooBig) {
-  std::string inner_packet(kMaxOutgoingPacketSize, '?');
-  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
-  ASSERT_EQ(encapsulated_length_, 0u);
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, BarelyFits) {
-  QuicByteCount inner_size = kMaxOutgoingPacketSize - Overhead();
-  std::string inner_packet(inner_size, '?');
-  Encapsulate(inner_packet);
-  CheckEncapsulation();
-}
-
-TEST_P(QuicLegacyVersionEncapsulatorTest, DoesNotQuiteFit) {
-  QuicByteCount inner_size = 1 + kMaxOutgoingPacketSize - Overhead();
-  std::string inner_packet(inner_size, '?');
-  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
-  ASSERT_EQ(encapsulated_length_, 0u);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_linux_socket_utils.cc b/quic/core/quic_linux_socket_utils.cc
deleted file mode 100644
index 888b658..0000000
--- a/quic/core/quic_linux_socket_utils.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_linux_socket_utils.h"
-
-#include <linux/net_tstamp.h>
-#include <netinet/in.h>
-#include <cstdint>
-
-#include "quic/core/quic_syscall_wrapper.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-QuicMsgHdr::QuicMsgHdr(const char* buffer,
-                       size_t buf_len,
-                       const QuicSocketAddress& peer_address,
-                       char* cbuf,
-                       size_t cbuf_size)
-    : iov_{const_cast<char*>(buffer), buf_len},
-      cbuf_(cbuf),
-      cbuf_size_(cbuf_size),
-      cmsg_(nullptr) {
-  // Only support unconnected sockets.
-  QUICHE_DCHECK(peer_address.IsInitialized());
-
-  raw_peer_address_ = peer_address.generic_address();
-  hdr_.msg_name = &raw_peer_address_;
-  hdr_.msg_namelen = raw_peer_address_.ss_family == AF_INET
-                         ? sizeof(sockaddr_in)
-                         : sizeof(sockaddr_in6);
-
-  hdr_.msg_iov = &iov_;
-  hdr_.msg_iovlen = 1;
-  hdr_.msg_flags = 0;
-
-  hdr_.msg_control = nullptr;
-  hdr_.msg_controllen = 0;
-}
-
-void QuicMsgHdr::SetIpInNextCmsg(const QuicIpAddress& self_address) {
-  if (!self_address.IsInitialized()) {
-    return;
-  }
-
-  if (self_address.IsIPv4()) {
-    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
-        self_address, GetNextCmsgData<in_pktinfo>(IPPROTO_IP, IP_PKTINFO));
-  } else {
-    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
-        self_address, GetNextCmsgData<in6_pktinfo>(IPPROTO_IPV6, IPV6_PKTINFO));
-  }
-}
-
-void* QuicMsgHdr::GetNextCmsgDataInternal(int cmsg_level,
-                                          int cmsg_type,
-                                          size_t data_size) {
-  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
-  // return nullptr.
-  hdr_.msg_controllen += CMSG_SPACE(data_size);
-  QUICHE_DCHECK_LE(hdr_.msg_controllen, cbuf_size_);
-
-  if (cmsg_ == nullptr) {
-    QUICHE_DCHECK_EQ(nullptr, hdr_.msg_control);
-    memset(cbuf_, 0, cbuf_size_);
-    hdr_.msg_control = cbuf_;
-    cmsg_ = CMSG_FIRSTHDR(&hdr_);
-  } else {
-    QUICHE_DCHECK_NE(nullptr, hdr_.msg_control);
-    cmsg_ = CMSG_NXTHDR(&hdr_, cmsg_);
-  }
-
-  QUICHE_DCHECK_NE(nullptr, cmsg_) << "Insufficient control buffer space";
-
-  cmsg_->cmsg_len = CMSG_LEN(data_size);
-  cmsg_->cmsg_level = cmsg_level;
-  cmsg_->cmsg_type = cmsg_type;
-
-  return CMSG_DATA(cmsg_);
-}
-
-void QuicMMsgHdr::InitOneHeader(int i, const BufferedWrite& buffered_write) {
-  mmsghdr* mhdr = GetMMsgHdr(i);
-  msghdr* hdr = &mhdr->msg_hdr;
-  iovec* iov = GetIov(i);
-
-  iov->iov_base = const_cast<char*>(buffered_write.buffer);
-  iov->iov_len = buffered_write.buf_len;
-  hdr->msg_iov = iov;
-  hdr->msg_iovlen = 1;
-  hdr->msg_control = nullptr;
-  hdr->msg_controllen = 0;
-
-  // Only support unconnected sockets.
-  QUICHE_DCHECK(buffered_write.peer_address.IsInitialized());
-
-  sockaddr_storage* peer_address_storage = GetPeerAddressStorage(i);
-  *peer_address_storage = buffered_write.peer_address.generic_address();
-  hdr->msg_name = peer_address_storage;
-  hdr->msg_namelen = peer_address_storage->ss_family == AF_INET
-                         ? sizeof(sockaddr_in)
-                         : sizeof(sockaddr_in6);
-}
-
-void QuicMMsgHdr::SetIpInNextCmsg(int i, const QuicIpAddress& self_address) {
-  if (!self_address.IsInitialized()) {
-    return;
-  }
-
-  if (self_address.IsIPv4()) {
-    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
-        self_address, GetNextCmsgData<in_pktinfo>(i, IPPROTO_IP, IP_PKTINFO));
-  } else {
-    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
-        self_address,
-        GetNextCmsgData<in6_pktinfo>(i, IPPROTO_IPV6, IPV6_PKTINFO));
-  }
-}
-
-void* QuicMMsgHdr::GetNextCmsgDataInternal(int i,
-                                           int cmsg_level,
-                                           int cmsg_type,
-                                           size_t data_size) {
-  mmsghdr* mhdr = GetMMsgHdr(i);
-  msghdr* hdr = &mhdr->msg_hdr;
-  cmsghdr*& cmsg = *GetCmsgHdr(i);
-
-  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
-  // return nullptr.
-  hdr->msg_controllen += CMSG_SPACE(data_size);
-  QUICHE_DCHECK_LE(hdr->msg_controllen, cbuf_size_);
-
-  if (cmsg == nullptr) {
-    QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
-    hdr->msg_control = GetCbuf(i);
-    cmsg = CMSG_FIRSTHDR(hdr);
-  } else {
-    QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
-    cmsg = CMSG_NXTHDR(hdr, cmsg);
-  }
-
-  QUICHE_DCHECK_NE(nullptr, cmsg) << "Insufficient control buffer space";
-
-  cmsg->cmsg_len = CMSG_LEN(data_size);
-  cmsg->cmsg_level = cmsg_level;
-  cmsg->cmsg_type = cmsg_type;
-
-  return CMSG_DATA(cmsg);
-}
-
-int QuicMMsgHdr::num_bytes_sent(int num_packets_sent) {
-  QUICHE_DCHECK_LE(0, num_packets_sent);
-  QUICHE_DCHECK_LE(num_packets_sent, num_msgs_);
-
-  int bytes_sent = 0;
-  iovec* iov = GetIov(0);
-  for (int i = 0; i < num_packets_sent; ++i) {
-    bytes_sent += iov[i].iov_len;
-  }
-  return bytes_sent;
-}
-
-// static
-int QuicLinuxSocketUtils::GetUDPSegmentSize(int fd) {
-  int optval;
-  socklen_t optlen = sizeof(optval);
-  int rc = getsockopt(fd, SOL_UDP, UDP_SEGMENT, &optval, &optlen);
-  if (rc < 0) {
-    QUIC_LOG_EVERY_N_SEC(INFO, 10)
-        << "getsockopt(UDP_SEGMENT) failed: " << strerror(errno);
-    return -1;
-  }
-  QUIC_LOG_EVERY_N_SEC(INFO, 10)
-      << "getsockopt(UDP_SEGMENT) returned segment size: " << optval;
-  return optval;
-}
-
-// static
-bool QuicLinuxSocketUtils::EnableReleaseTime(int fd, clockid_t clockid) {
-  // TODO(wub): Change to sock_txtime once it is available in linux/net_tstamp.h
-  struct LinuxSockTxTime {
-    clockid_t clockid; /* reference clockid */
-    uint32_t flags;    /* flags defined by enum txtime_flags */
-  };
-
-  LinuxSockTxTime so_txtime_val{clockid, 0};
-
-  if (setsockopt(fd, SOL_SOCKET, SO_TXTIME, &so_txtime_val,
-                 sizeof(so_txtime_val)) != 0) {
-    QUIC_LOG_EVERY_N_SEC(INFO, 10)
-        << "setsockopt(SOL_SOCKET,SO_TXTIME) failed: " << strerror(errno);
-    return false;
-  }
-
-  return true;
-}
-
-// static
-bool QuicLinuxSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) {
-  if (hdr->msg_controllen > 0) {
-    struct cmsghdr* cmsg;
-    for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
-         cmsg = CMSG_NXTHDR(hdr, cmsg)) {
-      if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
-          (cmsg->cmsg_level == IPPROTO_IPV6 &&
-           cmsg->cmsg_type == IPV6_HOPLIMIT)) {
-        *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg)));
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-// static
-void QuicLinuxSocketUtils::SetIpInfoInCmsgData(
-    const QuicIpAddress& self_address,
-    void* cmsg_data) {
-  QUICHE_DCHECK(self_address.IsInitialized());
-  const std::string& address_str = self_address.ToPackedString();
-  if (self_address.IsIPv4()) {
-    in_pktinfo* pktinfo = static_cast<in_pktinfo*>(cmsg_data);
-    pktinfo->ipi_ifindex = 0;
-    memcpy(&pktinfo->ipi_spec_dst, address_str.c_str(), address_str.length());
-  } else if (self_address.IsIPv6()) {
-    in6_pktinfo* pktinfo = static_cast<in6_pktinfo*>(cmsg_data);
-    memcpy(&pktinfo->ipi6_addr, address_str.c_str(), address_str.length());
-  } else {
-    QUIC_BUG(quic_bug_10598_1) << "Unrecognized IPAddress";
-  }
-}
-
-// static
-size_t QuicLinuxSocketUtils::SetIpInfoInCmsg(const QuicIpAddress& self_address,
-                                             cmsghdr* cmsg) {
-  std::string address_string;
-  if (self_address.IsIPv4()) {
-    cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
-    cmsg->cmsg_level = IPPROTO_IP;
-    cmsg->cmsg_type = IP_PKTINFO;
-    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
-    memset(pktinfo, 0, sizeof(in_pktinfo));
-    pktinfo->ipi_ifindex = 0;
-    address_string = self_address.ToPackedString();
-    memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
-           address_string.length());
-    return sizeof(in_pktinfo);
-  } else if (self_address.IsIPv6()) {
-    cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
-    cmsg->cmsg_level = IPPROTO_IPV6;
-    cmsg->cmsg_type = IPV6_PKTINFO;
-    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
-    memset(pktinfo, 0, sizeof(in6_pktinfo));
-    address_string = self_address.ToPackedString();
-    memcpy(&pktinfo->ipi6_addr, address_string.c_str(),
-           address_string.length());
-    return sizeof(in6_pktinfo);
-  } else {
-    QUIC_BUG(quic_bug_10598_2) << "Unrecognized IPAddress";
-    return 0;
-  }
-}
-
-// static
-WriteResult QuicLinuxSocketUtils::WritePacket(int fd, const QuicMsgHdr& hdr) {
-  int rc;
-  do {
-    rc = GetGlobalSyscallWrapper()->Sendmsg(fd, hdr.hdr(), 0);
-  } while (rc < 0 && errno == EINTR);
-  if (rc >= 0) {
-    return WriteResult(WRITE_STATUS_OK, rc);
-  }
-  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
-                         ? WRITE_STATUS_BLOCKED
-                         : WRITE_STATUS_ERROR,
-                     errno);
-}
-
-// static
-WriteResult QuicLinuxSocketUtils::WriteMultiplePackets(int fd,
-                                                       QuicMMsgHdr* mhdr,
-                                                       int* num_packets_sent) {
-  *num_packets_sent = 0;
-
-  if (mhdr->num_msgs() <= 0) {
-    return WriteResult(WRITE_STATUS_ERROR, EINVAL);
-  }
-
-  int rc;
-  do {
-    rc = GetGlobalSyscallWrapper()->Sendmmsg(fd, mhdr->mhdr(), mhdr->num_msgs(),
-                                             0);
-  } while (rc < 0 && errno == EINTR);
-
-  if (rc > 0) {
-    *num_packets_sent = rc;
-
-    return WriteResult(WRITE_STATUS_OK, mhdr->num_bytes_sent(rc));
-  } else if (rc == 0) {
-    QUIC_BUG(quic_bug_10598_3)
-        << "sendmmsg returned 0, returning WRITE_STATUS_ERROR. errno: "
-        << errno;
-    errno = EIO;
-  }
-
-  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
-                         ? WRITE_STATUS_BLOCKED
-                         : WRITE_STATUS_ERROR,
-                     errno);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_linux_socket_utils.h b/quic/core/quic_linux_socket_utils.h
deleted file mode 100644
index 5bbd875..0000000
--- a/quic/core/quic_linux_socket_utils.h
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
-
-#include <errno.h>
-#include <stddef.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <deque>
-#include <functional>
-#include <iterator>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-#ifndef SOL_UDP
-#define SOL_UDP 17
-#endif
-
-#ifndef UDP_SEGMENT
-#define UDP_SEGMENT 103
-#endif
-
-#ifndef UDP_MAX_SEGMENTS
-#define UDP_MAX_SEGMENTS (1 << 6UL)
-#endif
-
-#ifndef SO_TXTIME
-#define SO_TXTIME 61
-#endif
-
-namespace quic {
-
-const int kCmsgSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
-const int kCmsgSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
-// kCmsgSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
-const int kCmsgSpaceForIp = (kCmsgSpaceForIpv4 < kCmsgSpaceForIpv6)
-                                ? kCmsgSpaceForIpv6
-                                : kCmsgSpaceForIpv4;
-
-const int kCmsgSpaceForSegmentSize = CMSG_SPACE(sizeof(uint16_t));
-
-const int kCmsgSpaceForTxTime = CMSG_SPACE(sizeof(uint64_t));
-
-const int kCmsgSpaceForTTL = CMSG_SPACE(sizeof(int));
-
-// QuicMsgHdr is used to build msghdr objects that can be used send packets via
-// ::sendmsg.
-//
-// Example:
-//   // cbuf holds control messages(cmsgs). The size is determined from what
-//   // cmsgs will be set for this msghdr.
-//   char cbuf[kCmsgSpaceForIp + kCmsgSpaceForSegmentSize];
-//   QuicMsgHdr hdr(packet_buf, packet_buf_len, peer_addr, cbuf, sizeof(cbuf));
-//
-//   // Set IP in cmsgs.
-//   hdr.SetIpInNextCmsg(self_addr);
-//
-//   // Set GSO size in cmsgs.
-//   *hdr.GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = 1200;
-//
-//   QuicLinuxSocketUtils::WritePacket(fd, hdr);
-class QUIC_EXPORT_PRIVATE QuicMsgHdr {
- public:
-  QuicMsgHdr(const char* buffer,
-             size_t buf_len,
-             const QuicSocketAddress& peer_address,
-             char* cbuf,
-             size_t cbuf_size);
-
-  // Set IP info in the next cmsg. Both IPv4 and IPv6 are supported.
-  void SetIpInNextCmsg(const QuicIpAddress& self_address);
-
-  template <typename DataType>
-  DataType* GetNextCmsgData(int cmsg_level, int cmsg_type) {
-    return reinterpret_cast<DataType*>(
-        GetNextCmsgDataInternal(cmsg_level, cmsg_type, sizeof(DataType)));
-  }
-
-  const msghdr* hdr() const { return &hdr_; }
-
- protected:
-  void* GetNextCmsgDataInternal(int cmsg_level,
-                                int cmsg_type,
-                                size_t data_size);
-
-  msghdr hdr_;
-  iovec iov_;
-  sockaddr_storage raw_peer_address_;
-  char* cbuf_;
-  const size_t cbuf_size_;
-  // The last cmsg populated so far. nullptr means nothing has been populated.
-  cmsghdr* cmsg_;
-};
-
-// BufferedWrite holds all information needed to send a packet.
-struct QUIC_EXPORT_PRIVATE BufferedWrite {
-  BufferedWrite(const char* buffer,
-                size_t buf_len,
-                const QuicIpAddress& self_address,
-                const QuicSocketAddress& peer_address)
-      : BufferedWrite(buffer,
-                      buf_len,
-                      self_address,
-                      peer_address,
-                      std::unique_ptr<PerPacketOptions>(),
-                      /*release_time=*/0) {}
-
-  BufferedWrite(const char* buffer,
-                size_t buf_len,
-                const QuicIpAddress& self_address,
-                const QuicSocketAddress& peer_address,
-                std::unique_ptr<PerPacketOptions> options,
-                uint64_t release_time)
-      : buffer(buffer),
-        buf_len(buf_len),
-        self_address(self_address),
-        peer_address(peer_address),
-        options(std::move(options)),
-        release_time(release_time) {}
-
-  const char* buffer;  // Not owned.
-  size_t buf_len;
-  QuicIpAddress self_address;
-  QuicSocketAddress peer_address;
-  std::unique_ptr<PerPacketOptions> options;
-
-  // The release time according to the owning packet writer's clock, which is
-  // often not a QuicClock. Calculated from packet writer's Now() and the
-  // release time delay in |options|.
-  // 0 means it can be sent at the same time as the previous packet in a batch,
-  // or can be sent Now() if this is the first packet of a batch.
-  uint64_t release_time;
-};
-
-// QuicMMsgHdr is used to build mmsghdr objects that can be used to send
-// multiple packets at once via ::sendmmsg.
-//
-// Example:
-//   quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-//   ... (Populate buffered_writes) ...
-//
-//   QuicMMsgHdr mhdr(
-//       buffered_writes.begin(), buffered_writes.end(), kCmsgSpaceForIp,
-//       [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
-//         mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
-//       });
-//
-//   int num_packets_sent;
-//   QuicSocketUtils::WriteMultiplePackets(fd, &mhdr, &num_packets_sent);
-class QUIC_EXPORT_PRIVATE QuicMMsgHdr {
- public:
-  using ControlBufferInitializer = std::function<
-      void(QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)>;
-  template <typename IteratorT>
-  QuicMMsgHdr(const IteratorT& first,
-              const IteratorT& last,
-              size_t cbuf_size,
-              ControlBufferInitializer cbuf_initializer)
-      : num_msgs_(std::distance(first, last)), cbuf_size_(cbuf_size) {
-    static_assert(
-        std::is_same<typename std::iterator_traits<IteratorT>::value_type,
-                     BufferedWrite>::value,
-        "Must iterate over a collection of BufferedWrite.");
-
-    QUICHE_DCHECK_LE(0, num_msgs_);
-    if (num_msgs_ == 0) {
-      return;
-    }
-
-    storage_.reset(new char[StorageSize()]);
-    memset(&storage_[0], 0, StorageSize());
-
-    int i = -1;
-    for (auto it = first; it != last; ++it) {
-      ++i;
-
-      InitOneHeader(i, *it);
-      if (cbuf_initializer) {
-        cbuf_initializer(this, i, *it);
-      }
-    }
-  }
-
-  void SetIpInNextCmsg(int i, const QuicIpAddress& self_address);
-
-  template <typename DataType>
-  DataType* GetNextCmsgData(int i, int cmsg_level, int cmsg_type) {
-    return reinterpret_cast<DataType*>(
-        GetNextCmsgDataInternal(i, cmsg_level, cmsg_type, sizeof(DataType)));
-  }
-
-  mmsghdr* mhdr() { return GetMMsgHdr(0); }
-
-  int num_msgs() const { return num_msgs_; }
-
-  // Get the total number of bytes in the first |num_packets_sent| packets.
-  int num_bytes_sent(int num_packets_sent);
-
- protected:
-  void InitOneHeader(int i, const BufferedWrite& buffered_write);
-
-  void* GetNextCmsgDataInternal(int i,
-                                int cmsg_level,
-                                int cmsg_type,
-                                size_t data_size);
-
-  size_t StorageSize() const {
-    return num_msgs_ *
-           (sizeof(mmsghdr) + sizeof(iovec) + sizeof(sockaddr_storage) +
-            sizeof(cmsghdr*) + cbuf_size_);
-  }
-
-  mmsghdr* GetMMsgHdr(int i) {
-    auto* first = reinterpret_cast<mmsghdr*>(&storage_[0]);
-    return &first[i];
-  }
-
-  iovec* GetIov(int i) {
-    auto* first = reinterpret_cast<iovec*>(GetMMsgHdr(num_msgs_));
-    return &first[i];
-  }
-
-  sockaddr_storage* GetPeerAddressStorage(int i) {
-    auto* first = reinterpret_cast<sockaddr_storage*>(GetIov(num_msgs_));
-    return &first[i];
-  }
-
-  cmsghdr** GetCmsgHdr(int i) {
-    auto* first = reinterpret_cast<cmsghdr**>(GetPeerAddressStorage(num_msgs_));
-    return &first[i];
-  }
-
-  char* GetCbuf(int i) {
-    auto* first = reinterpret_cast<char*>(GetCmsgHdr(num_msgs_));
-    return &first[i * cbuf_size_];
-  }
-
-  const int num_msgs_;
-  // Size of cmsg buffer for each message.
-  const size_t cbuf_size_;
-  // storage_ holds the memory of
-  // |num_msgs_| mmsghdr
-  // |num_msgs_| iovec
-  // |num_msgs_| sockaddr_storage, for peer addresses
-  // |num_msgs_| cmsghdr*
-  // |num_msgs_| cbuf, each of size cbuf_size
-  std::unique_ptr<char[]> storage_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicLinuxSocketUtils {
- public:
-  // Return the UDP segment size of |fd|, 0 means segment size has not been set
-  // on this socket. If GSO is not supported, return -1.
-  static int GetUDPSegmentSize(int fd);
-
-  // Enable release time on |fd|.
-  static bool EnableReleaseTime(int fd, clockid_t clockid);
-
-  // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
-  // value and return true. Otherwise it will return false.
-  static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);
-
-  // Set IP(self_address) in |cmsg_data|. Does not touch other fields in the
-  // containing cmsghdr.
-  static void SetIpInfoInCmsgData(const QuicIpAddress& self_address,
-                                  void* cmsg_data);
-
-  // A helper for WritePacket which fills in the cmsg with the supplied self
-  // address.
-  // Returns the length of the packet info structure used.
-  static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
-                                cmsghdr* cmsg);
-
-  // Writes the packet in |hdr| to the socket, using ::sendmsg.
-  static WriteResult WritePacket(int fd, const QuicMsgHdr& hdr);
-
-  // Writes the packets in |mhdr| to the socket, using ::sendmmsg if available.
-  static WriteResult WriteMultiplePackets(int fd,
-                                          QuicMMsgHdr* mhdr,
-                                          int* num_packets_sent);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
diff --git a/quic/core/quic_linux_socket_utils_test.cc b/quic/core/quic_linux_socket_utils_test.cc
deleted file mode 100644
index 588c2be..0000000
--- a/quic/core/quic_linux_socket_utils_test.cc
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_linux_socket_utils.h"
-
-#include <netinet/in.h>
-#include <stdint.h>
-#include <cstddef>
-#include <sstream>
-#include <vector>
-
-#include <string>
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_mock_syscall_wrapper.h"
-#include "common/quiche_circular_deque.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicLinuxSocketUtilsTest : public QuicTest {
- protected:
-  WriteResult TestWriteMultiplePackets(
-      int fd,
-      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& first,
-      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& last,
-      int* num_packets_sent) {
-    QuicMMsgHdr mhdr(
-        first, last, kCmsgSpaceForIp,
-        [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
-          mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
-        });
-
-    WriteResult res =
-        QuicLinuxSocketUtils::WriteMultiplePackets(fd, &mhdr, num_packets_sent);
-    return res;
-  }
-
-  MockQuicSyscallWrapper mock_syscalls_;
-  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
-};
-
-void CheckIpAndTtlInCbuf(msghdr* hdr,
-                         const void* cbuf,
-                         const QuicIpAddress& self_addr,
-                         int ttl) {
-  const bool is_ipv4 = self_addr.IsIPv4();
-  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
-
-  EXPECT_EQ(cbuf, hdr->msg_control);
-  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
-
-  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
-  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
-                                    : CMSG_LEN(sizeof(in6_pktinfo)));
-  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
-  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
-
-  const std::string& self_addr_str = self_addr.ToPackedString();
-  if (is_ipv4) {
-    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
-    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
-                        self_addr_str.length()));
-  } else {
-    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
-    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
-                        self_addr_str.length()));
-  }
-
-  cmsg = CMSG_NXTHDR(hdr, cmsg);
-  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
-  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
-  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_TTL : IPV6_HOPLIMIT);
-  EXPECT_EQ(ttl, *reinterpret_cast<int*>(CMSG_DATA(cmsg)));
-
-  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
-}
-
-void CheckMsghdrWithoutCbuf(const msghdr* hdr,
-                            const void* buffer,
-                            size_t buf_len,
-                            const QuicSocketAddress& peer_addr) {
-  EXPECT_EQ(
-      peer_addr.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
-      hdr->msg_namelen);
-  sockaddr_storage peer_generic_addr = peer_addr.generic_address();
-  EXPECT_EQ(0, memcmp(hdr->msg_name, &peer_generic_addr, hdr->msg_namelen));
-  EXPECT_EQ(1u, hdr->msg_iovlen);
-  EXPECT_EQ(buffer, hdr->msg_iov->iov_base);
-  EXPECT_EQ(buf_len, hdr->msg_iov->iov_len);
-  EXPECT_EQ(0, hdr->msg_flags);
-  EXPECT_EQ(nullptr, hdr->msg_control);
-  EXPECT_EQ(0u, hdr->msg_controllen);
-}
-
-void CheckIpAndGsoSizeInCbuf(msghdr* hdr,
-                             const void* cbuf,
-                             const QuicIpAddress& self_addr,
-                             uint16_t gso_size) {
-  const bool is_ipv4 = self_addr.IsIPv4();
-  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
-
-  EXPECT_EQ(cbuf, hdr->msg_control);
-  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
-
-  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
-  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
-                                    : CMSG_LEN(sizeof(in6_pktinfo)));
-  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
-  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
-
-  const std::string& self_addr_str = self_addr.ToPackedString();
-  if (is_ipv4) {
-    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
-    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
-                        self_addr_str.length()));
-  } else {
-    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
-    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
-                        self_addr_str.length()));
-  }
-
-  cmsg = CMSG_NXTHDR(hdr, cmsg);
-  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(uint16_t)));
-  EXPECT_EQ(cmsg->cmsg_level, SOL_UDP);
-  EXPECT_EQ(cmsg->cmsg_type, UDP_SEGMENT);
-  EXPECT_EQ(gso_size, *reinterpret_cast<uint16_t*>(CMSG_DATA(cmsg)));
-
-  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, QuicMsgHdr) {
-  QuicSocketAddress peer_addr(QuicIpAddress::Loopback4(), 1234);
-  char packet_buf[1024];
-
-  QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, nullptr, 0);
-  CheckMsghdrWithoutCbuf(quic_hdr.hdr(), packet_buf, sizeof(packet_buf),
-                         peer_addr);
-
-  for (bool is_ipv4 : {true, false}) {
-    QuicIpAddress self_addr =
-        is_ipv4 ? QuicIpAddress::Loopback4() : QuicIpAddress::Loopback6();
-    char cbuf[kCmsgSpaceForIp + kCmsgSpaceForTTL];
-    QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, cbuf,
-                        sizeof(cbuf));
-    msghdr* hdr = const_cast<msghdr*>(quic_hdr.hdr());
-
-    EXPECT_EQ(nullptr, hdr->msg_control);
-    EXPECT_EQ(0u, hdr->msg_controllen);
-
-    quic_hdr.SetIpInNextCmsg(self_addr);
-    EXPECT_EQ(cbuf, hdr->msg_control);
-    const size_t ip_cmsg_space =
-        is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
-    EXPECT_EQ(ip_cmsg_space, hdr->msg_controllen);
-
-    if (is_ipv4) {
-      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IP, IP_TTL) = 32;
-    } else {
-      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IPV6, IPV6_HOPLIMIT) = 32;
-    }
-
-    CheckIpAndTtlInCbuf(hdr, cbuf, self_addr, 32);
-  }
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, QuicMMsgHdr) {
-  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-  char packet_buf1[1024];
-  char packet_buf2[512];
-  buffered_writes.emplace_back(
-      packet_buf1, sizeof(packet_buf1), QuicIpAddress::Loopback4(),
-      QuicSocketAddress(QuicIpAddress::Loopback4(), 4));
-  buffered_writes.emplace_back(
-      packet_buf2, sizeof(packet_buf2), QuicIpAddress::Loopback6(),
-      QuicSocketAddress(QuicIpAddress::Loopback6(), 6));
-
-  QuicMMsgHdr quic_mhdr_without_cbuf(buffered_writes.begin(),
-                                     buffered_writes.end(), 0, nullptr);
-  for (size_t i = 0; i < buffered_writes.size(); ++i) {
-    const BufferedWrite& bw = buffered_writes[i];
-    CheckMsghdrWithoutCbuf(&quic_mhdr_without_cbuf.mhdr()[i].msg_hdr, bw.buffer,
-                           bw.buf_len, bw.peer_address);
-  }
-
-  QuicMMsgHdr quic_mhdr_with_cbuf(
-      buffered_writes.begin(), buffered_writes.end(),
-      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize,
-      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
-        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
-        *mhdr->GetNextCmsgData<uint16_t>(i, SOL_UDP, UDP_SEGMENT) = 1300;
-      });
-  for (size_t i = 0; i < buffered_writes.size(); ++i) {
-    const BufferedWrite& bw = buffered_writes[i];
-    msghdr* hdr = &quic_mhdr_with_cbuf.mhdr()[i].msg_hdr;
-    CheckIpAndGsoSizeInCbuf(hdr, hdr->msg_control, bw.self_address, 1300);
-  }
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_NoPacketsToSend) {
-  int num_packets_sent;
-  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-
-  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _)).Times(0);
-
-  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL),
-            TestWriteMultiplePackets(1, buffered_writes.begin(),
-                                     buffered_writes.end(), &num_packets_sent));
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteBlocked) {
-  int num_packets_sent;
-  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
-                               QuicSocketAddress(QuicIpAddress::Any4(), 0));
-
-  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
-      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
-                          unsigned int /*vlen*/, int /*flags*/) {
-        errno = EWOULDBLOCK;
-        return -1;
-      }));
-
-  EXPECT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
-            TestWriteMultiplePackets(1, buffered_writes.begin(),
-                                     buffered_writes.end(), &num_packets_sent));
-  EXPECT_EQ(0, num_packets_sent);
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteError) {
-  int num_packets_sent;
-  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
-                               QuicSocketAddress(QuicIpAddress::Any4(), 0));
-
-  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
-      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
-                          unsigned int /*vlen*/, int /*flags*/) {
-        errno = EPERM;
-        return -1;
-      }));
-
-  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM),
-            TestWriteMultiplePackets(1, buffered_writes.begin(),
-                                     buffered_writes.end(), &num_packets_sent));
-  EXPECT_EQ(0, num_packets_sent);
-}
-
-TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteSuccess) {
-  int num_packets_sent;
-  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
-  const int kNumBufferedWrites = 10;
-  static_assert(kNumBufferedWrites < 256, "Must be less than 256");
-  std::vector<std::string> buffer_holder;
-  for (int i = 0; i < kNumBufferedWrites; ++i) {
-    size_t buf_len = (i + 1) * 2;
-    std::ostringstream buffer_ostream;
-    while (buffer_ostream.str().length() < buf_len) {
-      buffer_ostream << i;
-    }
-    buffer_holder.push_back(buffer_ostream.str().substr(0, buf_len - 1) + '$');
-
-    buffered_writes.emplace_back(buffer_holder.back().data(), buf_len,
-                                 QuicIpAddress(),
-                                 QuicSocketAddress(QuicIpAddress::Any4(), 0));
-
-    // Leave the first self_address uninitialized.
-    if (i != 0) {
-      ASSERT_TRUE(buffered_writes.back().self_address.FromString("127.0.0.1"));
-    }
-
-    std::ostringstream peer_ip_ostream;
-    QuicIpAddress peer_ip_address;
-    peer_ip_ostream << "127.0.1." << i + 1;
-    ASSERT_TRUE(peer_ip_address.FromString(peer_ip_ostream.str()));
-    buffered_writes.back().peer_address =
-        QuicSocketAddress(peer_ip_address, i + 1);
-  }
-
-  InSequence s;
-
-  for (int expected_num_packets_sent : {1, 2, 3, 10}) {
-    SCOPED_TRACE(testing::Message()
-                 << "expected_num_packets_sent=" << expected_num_packets_sent);
-    EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
-        .WillOnce(Invoke(
-            [&](int /*fd*/, mmsghdr* msgvec, unsigned int vlen, int /*flags*/) {
-              EXPECT_LE(static_cast<unsigned int>(expected_num_packets_sent),
-                        vlen);
-              for (unsigned int i = 0; i < vlen; ++i) {
-                const BufferedWrite& buffered_write = buffered_writes[i];
-                const msghdr& hdr = msgvec[i].msg_hdr;
-                EXPECT_EQ(1u, hdr.msg_iovlen);
-                EXPECT_EQ(buffered_write.buffer, hdr.msg_iov->iov_base);
-                EXPECT_EQ(buffered_write.buf_len, hdr.msg_iov->iov_len);
-                sockaddr_storage expected_peer_address =
-                    buffered_write.peer_address.generic_address();
-                EXPECT_EQ(0, memcmp(&expected_peer_address, hdr.msg_name,
-                                    sizeof(sockaddr_storage)));
-                EXPECT_EQ(buffered_write.self_address.IsInitialized(),
-                          hdr.msg_control != nullptr);
-              }
-              return expected_num_packets_sent;
-            }))
-        .RetiresOnSaturation();
-
-    int expected_bytes_written = 0;
-    for (auto it = buffered_writes.cbegin();
-         it != buffered_writes.cbegin() + expected_num_packets_sent; ++it) {
-      expected_bytes_written += it->buf_len;
-    }
-
-    EXPECT_EQ(
-        WriteResult(WRITE_STATUS_OK, expected_bytes_written),
-        TestWriteMultiplePackets(1, buffered_writes.cbegin(),
-                                 buffered_writes.cend(), &num_packets_sent));
-    EXPECT_EQ(expected_num_packets_sent, num_packets_sent);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_lru_cache.h b/quic/core/quic_lru_cache.h
deleted file mode 100644
index 44024b6..0000000
--- a/quic/core/quic_lru_cache.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
-#define QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
-
-#include <memory>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-// A LRU cache that maps from type Key to Value* in QUIC.
-// This cache CANNOT be shared by multiple threads (even with locks) because
-// Value* returned by Lookup() can be invalid if the entry is evicted by other
-// threads.
-template <class K, class V, class Hash = std::hash<K>,
-          class Eq = std::equal_to<K>>
-class QUIC_NO_EXPORT QuicLRUCache {
- private:
-  using HashMapType =
-      typename quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq>;
-
- public:
-  // The iterator, if valid, points to std::pair<K, std::unique_ptr<V>>.
-  using iterator = typename HashMapType::iterator;
-  using const_iterator = typename HashMapType::const_iterator;
-  using reverse_iterator = typename HashMapType::reverse_iterator;
-  using const_reverse_iterator = typename HashMapType::const_reverse_iterator;
-
-  explicit QuicLRUCache(size_t capacity) : capacity_(capacity) {}
-  QuicLRUCache(const QuicLRUCache&) = delete;
-  QuicLRUCache& operator=(const QuicLRUCache&) = delete;
-
-  iterator begin() { return cache_.begin(); }
-  const_iterator begin() const { return cache_.begin(); }
-
-  iterator end() { return cache_.end(); }
-  const_iterator end() const { return cache_.end(); }
-
-  reverse_iterator rbegin() { return cache_.rbegin(); }
-  const_reverse_iterator rbegin() const { return cache_.rbegin(); }
-
-  reverse_iterator rend() { return cache_.rend(); }
-  const_reverse_iterator rend() const { return cache_.rend(); }
-
-  // Inserts one unit of |key|, |value| pair to the cache. Cache takes ownership
-  // of inserted |value|.
-  void Insert(const K& key, std::unique_ptr<V> value) {
-    auto it = cache_.find(key);
-    if (it != cache_.end()) {
-      cache_.erase(it);
-    }
-    cache_.emplace(key, std::move(value));
-
-    if (cache_.size() > capacity_) {
-      cache_.pop_front();
-    }
-    QUICHE_DCHECK_LE(cache_.size(), capacity_);
-  }
-
-  iterator Lookup(const K& key) {
-    auto iter = cache_.find(key);
-    if (iter == cache_.end()) {
-      return iter;
-    }
-
-    std::unique_ptr<V> value = std::move(iter->second);
-    cache_.erase(iter);
-    auto result = cache_.emplace(key, std::move(value));
-    QUICHE_DCHECK(result.second);
-    return result.first;
-  }
-
-  iterator Erase(iterator iter) { return cache_.erase(iter); }
-
-  // Removes all entries from the cache.
-  void Clear() { cache_.clear(); }
-
-  // Returns maximum size of the cache.
-  size_t MaxSize() const { return capacity_; }
-
-  // Returns current size of the cache.
-  size_t Size() const { return cache_.size(); }
-
- private:
-  quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq> cache_;
-  const size_t capacity_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
diff --git a/quic/core/quic_lru_cache_test.cc b/quic/core/quic_lru_cache_test.cc
deleted file mode 100644
index 8c6b5b8..0000000
--- a/quic/core/quic_lru_cache_test.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_lru_cache.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct CachedItem {
-  explicit CachedItem(uint32_t new_value) : value(new_value) {}
-
-  uint32_t value;
-};
-
-TEST(QuicLRUCacheTest, InsertAndLookup) {
-  QuicLRUCache<int, CachedItem> cache(5);
-  EXPECT_EQ(cache.end(), cache.Lookup(1));
-  EXPECT_EQ(0u, cache.Size());
-  EXPECT_EQ(5u, cache.MaxSize());
-
-  // Check that item 1 was properly inserted.
-  std::unique_ptr<CachedItem> item1(new CachedItem(11));
-  cache.Insert(1, std::move(item1));
-  EXPECT_EQ(1u, cache.Size());
-  EXPECT_EQ(11u, cache.Lookup(1)->second->value);
-
-  // Check that item 2 overrides item 1.
-  std::unique_ptr<CachedItem> item2(new CachedItem(12));
-  cache.Insert(1, std::move(item2));
-  EXPECT_EQ(1u, cache.Size());
-  EXPECT_EQ(12u, cache.Lookup(1)->second->value);
-
-  std::unique_ptr<CachedItem> item3(new CachedItem(13));
-  cache.Insert(3, std::move(item3));
-  EXPECT_EQ(2u, cache.Size());
-  auto iter = cache.Lookup(3);
-  ASSERT_NE(cache.end(), iter);
-  EXPECT_EQ(13u, iter->second->value);
-  cache.Erase(iter);
-  ASSERT_EQ(cache.end(), cache.Lookup(3));
-  EXPECT_EQ(1u, cache.Size());
-
-  // No memory leakage.
-  cache.Clear();
-  EXPECT_EQ(0u, cache.Size());
-}
-
-TEST(QuicLRUCacheTest, Eviction) {
-  QuicLRUCache<int, CachedItem> cache(3);
-
-  for (size_t i = 1; i <= 4; ++i) {
-    std::unique_ptr<CachedItem> item(new CachedItem(10 + i));
-    cache.Insert(i, std::move(item));
-  }
-
-  EXPECT_EQ(3u, cache.Size());
-  EXPECT_EQ(3u, cache.MaxSize());
-
-  // Make sure item 1 is evicted.
-  EXPECT_EQ(cache.end(), cache.Lookup(1));
-  EXPECT_EQ(14u, cache.Lookup(4)->second->value);
-
-  EXPECT_EQ(12u, cache.Lookup(2)->second->value);
-  std::unique_ptr<CachedItem> item5(new CachedItem(15));
-  cache.Insert(5, std::move(item5));
-  // Make sure item 3 is evicted.
-  EXPECT_EQ(cache.end(), cache.Lookup(3));
-  EXPECT_EQ(15u, cache.Lookup(5)->second->value);
-
-  // No memory leakage.
-  cache.Clear();
-  EXPECT_EQ(0u, cache.Size());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_mtu_discovery.cc b/quic/core/quic_mtu_discovery.cc
deleted file mode 100644
index 056a4bd..0000000
--- a/quic/core/quic_mtu_discovery.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_mtu_discovery.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-QuicConnectionMtuDiscoverer::QuicConnectionMtuDiscoverer(
-    QuicPacketCount packets_between_probes_base,
-    QuicPacketNumber next_probe_at)
-    : packets_between_probes_(packets_between_probes_base),
-      next_probe_at_(next_probe_at) {}
-
-void QuicConnectionMtuDiscoverer::Enable(
-    QuicByteCount max_packet_length,
-    QuicByteCount target_max_packet_length) {
-  QUICHE_DCHECK(!IsEnabled());
-
-  if (target_max_packet_length <= max_packet_length) {
-    QUIC_DVLOG(1) << "MtuDiscoverer not enabled. target_max_packet_length:"
-                  << target_max_packet_length
-                  << " <= max_packet_length:" << max_packet_length;
-    return;
-  }
-
-  min_probe_length_ = max_packet_length;
-  max_probe_length_ = target_max_packet_length;
-  QUICHE_DCHECK(IsEnabled());
-
-  QUIC_DVLOG(1) << "MtuDiscoverer enabled. min:" << min_probe_length_
-                << ", max:" << max_probe_length_
-                << ", next:" << next_probe_packet_length();
-}
-
-void QuicConnectionMtuDiscoverer::Disable() {
-  *this = QuicConnectionMtuDiscoverer(packets_between_probes_, next_probe_at_);
-}
-
-bool QuicConnectionMtuDiscoverer::IsEnabled() const {
-  return min_probe_length_ < max_probe_length_;
-}
-
-bool QuicConnectionMtuDiscoverer::ShouldProbeMtu(
-    QuicPacketNumber largest_sent_packet) const {
-  if (!IsEnabled()) {
-    return false;
-  }
-
-  if (remaining_probe_count_ == 0) {
-    QUIC_DVLOG(1)
-        << "ShouldProbeMtu returns false because max probe count reached";
-    return false;
-  }
-
-  if (largest_sent_packet < next_probe_at_) {
-    QUIC_DVLOG(1) << "ShouldProbeMtu returns false because not enough packets "
-                     "sent since last probe. largest_sent_packet:"
-                  << largest_sent_packet
-                  << ", next_probe_at_:" << next_probe_at_;
-    return false;
-  }
-
-  QUIC_DVLOG(1) << "ShouldProbeMtu returns true. largest_sent_packet:"
-                << largest_sent_packet;
-  return true;
-}
-
-QuicPacketLength QuicConnectionMtuDiscoverer::GetUpdatedMtuProbeSize(
-    QuicPacketNumber largest_sent_packet) {
-  QUICHE_DCHECK(ShouldProbeMtu(largest_sent_packet));
-
-  QuicPacketLength probe_packet_length = next_probe_packet_length();
-  if (probe_packet_length == last_probe_length_) {
-    // The next probe packet is as big as the previous one. Assuming the
-    // previous one exceeded MTU, we need to decrease the probe packet length.
-    max_probe_length_ = probe_packet_length;
-  } else {
-    QUICHE_DCHECK_GT(probe_packet_length, last_probe_length_);
-  }
-  last_probe_length_ = next_probe_packet_length();
-
-  packets_between_probes_ *= 2;
-  next_probe_at_ = largest_sent_packet + packets_between_probes_ + 1;
-  if (remaining_probe_count_ > 0) {
-    --remaining_probe_count_;
-  }
-
-  QUIC_DVLOG(1) << "GetUpdatedMtuProbeSize: probe_packet_length:"
-                << last_probe_length_
-                << ", New packets_between_probes_:" << packets_between_probes_
-                << ", next_probe_at_:" << next_probe_at_
-                << ", remaining_probe_count_:" << remaining_probe_count_;
-  QUICHE_DCHECK(!ShouldProbeMtu(largest_sent_packet));
-  return last_probe_length_;
-}
-
-QuicPacketLength QuicConnectionMtuDiscoverer::next_probe_packet_length() const {
-  QUICHE_DCHECK_NE(min_probe_length_, 0);
-  QUICHE_DCHECK_NE(max_probe_length_, 0);
-  QUICHE_DCHECK_GE(max_probe_length_, min_probe_length_);
-
-  const QuicPacketLength normal_next_probe_length =
-      (min_probe_length_ + max_probe_length_ + 1) / 2;
-
-  if (remaining_probe_count_ == 1 &&
-      normal_next_probe_length > last_probe_length_) {
-    // If the previous probe succeeded, and there is only one last probe to
-    // send, use |max_probe_length_| for the last probe.
-    return max_probe_length_;
-  }
-  return normal_next_probe_length;
-}
-
-void QuicConnectionMtuDiscoverer::OnMaxPacketLengthUpdated(
-    QuicByteCount old_value,
-    QuicByteCount new_value) {
-  if (!IsEnabled() || new_value <= old_value) {
-    return;
-  }
-
-  QUICHE_DCHECK_EQ(old_value, min_probe_length_);
-  min_probe_length_ = new_value;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicConnectionMtuDiscoverer& d) {
-  os << "{ min_probe_length_:" << d.min_probe_length_
-     << " max_probe_length_:" << d.max_probe_length_
-     << " last_probe_length_:" << d.last_probe_length_
-     << " remaining_probe_count_:" << d.remaining_probe_count_
-     << " packets_between_probes_:" << d.packets_between_probes_
-     << " next_probe_at_:" << d.next_probe_at_ << " }";
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_mtu_discovery.h b/quic/core/quic_mtu_discovery.h
deleted file mode 100644
index dddd33d..0000000
--- a/quic/core/quic_mtu_discovery.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
-#define QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
-
-#include <iostream>
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-// The initial number of packets between MTU probes.  After each attempt the
-// number is doubled.
-const QuicPacketCount kPacketsBetweenMtuProbesBase = 100;
-
-// The number of MTU probes that get sent before giving up.
-const size_t kMtuDiscoveryAttempts = 3;
-
-// Ensure that exponential back-off does not result in an integer overflow.
-// The number of packets can be potentially capped, but that is not useful at
-// current kMtuDiscoveryAttempts value, and hence is not implemented at present.
-static_assert(kMtuDiscoveryAttempts + 8 < 8 * sizeof(QuicPacketNumber),
-              "The number of MTU discovery attempts is too high");
-static_assert(kPacketsBetweenMtuProbesBase < (1 << 8),
-              "The initial number of packets between MTU probes is too high");
-
-// The increased packet size targeted when doing path MTU discovery.
-const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1400;
-const QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1380;
-
-static_assert(kMtuDiscoveryTargetPacketSizeLow <= kMaxOutgoingPacketSize,
-              "MTU discovery target is too large");
-static_assert(kMtuDiscoveryTargetPacketSizeHigh <= kMaxOutgoingPacketSize,
-              "MTU discovery target is too large");
-
-static_assert(kMtuDiscoveryTargetPacketSizeLow > kDefaultMaxPacketSize,
-              "MTU discovery target does not exceed the default packet size");
-static_assert(kMtuDiscoveryTargetPacketSizeHigh > kDefaultMaxPacketSize,
-              "MTU discovery target does not exceed the default packet size");
-
-// QuicConnectionMtuDiscoverer is a MTU discovery controller, it answers two
-// questions:
-// 1) Probe scheduling: Whether a connection should send a MTU probe packet
-//    right now.
-// 2) MTU search stradegy: When it is time to send, what should be the size of
-//    the probing packet.
-// Note the discoverer does not actually send or process probing packets.
-//
-// Unit tests are in QuicConnectionTest.MtuDiscovery*.
-class QUIC_EXPORT_PRIVATE QuicConnectionMtuDiscoverer {
- public:
-  // Construct a discoverer in the disabled state.
-  QuicConnectionMtuDiscoverer() = default;
-
-  // Construct a discoverer in the disabled state, with the given parameters.
-  QuicConnectionMtuDiscoverer(QuicPacketCount packets_between_probes_base,
-                              QuicPacketNumber next_probe_at);
-
-  // Enable the discoverer by setting the probe target.
-  // max_packet_length: The max packet length currently used.
-  // target_max_packet_length: The target max packet length to probe.
-  void Enable(QuicByteCount max_packet_length,
-              QuicByteCount target_max_packet_length);
-
-  // Disable the discoverer by unsetting the probe target.
-  void Disable();
-
-  // Whether a MTU probe packet should be sent right now.
-  // Always return false if disabled.
-  bool ShouldProbeMtu(QuicPacketNumber largest_sent_packet) const;
-
-  // Called immediately before a probing packet is sent, to get the size of the
-  // packet.
-  // REQUIRES: ShouldProbeMtu(largest_sent_packet) == true.
-  QuicPacketLength GetUpdatedMtuProbeSize(QuicPacketNumber largest_sent_packet);
-
-  // Called after the max packet length is updated, which is triggered by a ack
-  // of a probing packet.
-  void OnMaxPacketLengthUpdated(QuicByteCount old_value,
-                                QuicByteCount new_value);
-
-  QuicPacketCount packets_between_probes() const {
-    return packets_between_probes_;
-  }
-
-  QuicPacketNumber next_probe_at() const { return next_probe_at_; }
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicConnectionMtuDiscoverer& d);
-
- private:
-  bool IsEnabled() const;
-  QuicPacketLength next_probe_packet_length() const;
-
-  QuicPacketLength min_probe_length_ = 0;
-  QuicPacketLength max_probe_length_ = 0;
-
-  QuicPacketLength last_probe_length_ = 0;
-
-  uint16_t remaining_probe_count_ = kMtuDiscoveryAttempts;
-
-  // The number of packets between MTU probes.
-  QuicPacketCount packets_between_probes_ = kPacketsBetweenMtuProbesBase;
-
-  // The packet number of the packet after which the next MTU probe will be
-  // sent.
-  QuicPacketNumber next_probe_at_ =
-      QuicPacketNumber(kPacketsBetweenMtuProbesBase);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
diff --git a/quic/core/quic_network_blackhole_detector.cc b/quic/core/quic_network_blackhole_detector.cc
deleted file mode 100644
index 2d9fc2d..0000000
--- a/quic/core/quic_network_blackhole_detector.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_network_blackhole_detector.h"
-
-#include "quic/core/quic_constants.h"
-
-namespace quic {
-
-namespace {
-
-class AlarmDelegate : public QuicAlarm::DelegateWithContext {
- public:
-  explicit AlarmDelegate(QuicNetworkBlackholeDetector* detector,
-                         QuicConnectionContext* context)
-      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
-  AlarmDelegate(const AlarmDelegate&) = delete;
-  AlarmDelegate& operator=(const AlarmDelegate&) = delete;
-
-  void OnAlarm() override { detector_->OnAlarm(); }
-
- private:
-  QuicNetworkBlackholeDetector* detector_;
-};
-
-}  // namespace
-
-QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(
-    Delegate* delegate, QuicConnectionArena* arena,
-    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
-    : delegate_(delegate),
-      alarm_(alarm_factory->CreateAlarm(
-          arena->New<AlarmDelegate>(this, context), arena)) {}
-
-void QuicNetworkBlackholeDetector::OnAlarm() {
-  QuicTime next_deadline = GetEarliestDeadline();
-  if (!next_deadline.IsInitialized()) {
-    QUIC_BUG(quic_bug_10328_1) << "BlackholeDetector alarm fired unexpectedly";
-    return;
-  }
-
-  QUIC_DVLOG(1) << "BlackholeDetector alarm firing. next_deadline:"
-                << next_deadline
-                << ", path_degrading_deadline_:" << path_degrading_deadline_
-                << ", path_mtu_reduction_deadline_:"
-                << path_mtu_reduction_deadline_
-                << ", blackhole_deadline_:" << blackhole_deadline_;
-  if (path_degrading_deadline_ == next_deadline) {
-    path_degrading_deadline_ = QuicTime::Zero();
-    delegate_->OnPathDegradingDetected();
-  }
-
-  if (path_mtu_reduction_deadline_ == next_deadline) {
-    path_mtu_reduction_deadline_ = QuicTime::Zero();
-    delegate_->OnPathMtuReductionDetected();
-  }
-
-  if (blackhole_deadline_ == next_deadline) {
-    blackhole_deadline_ = QuicTime::Zero();
-    delegate_->OnBlackholeDetected();
-  }
-
-  UpdateAlarm();
-}
-
-void QuicNetworkBlackholeDetector::StopDetection(bool permanent) {
-  if (permanent) {
-    alarm_->PermanentCancel();
-  } else {
-    alarm_->Cancel();
-  }
-  path_degrading_deadline_ = QuicTime::Zero();
-  blackhole_deadline_ = QuicTime::Zero();
-  path_mtu_reduction_deadline_ = QuicTime::Zero();
-}
-
-void QuicNetworkBlackholeDetector::RestartDetection(
-    QuicTime path_degrading_deadline,
-    QuicTime blackhole_deadline,
-    QuicTime path_mtu_reduction_deadline) {
-  path_degrading_deadline_ = path_degrading_deadline;
-  blackhole_deadline_ = blackhole_deadline;
-  path_mtu_reduction_deadline_ = path_mtu_reduction_deadline;
-
-  QUIC_BUG_IF(quic_bug_12708_1, blackhole_deadline_.IsInitialized() &&
-                                    blackhole_deadline_ != GetLastDeadline())
-      << "Blackhole detection deadline should be the last deadline.";
-
-  UpdateAlarm();
-}
-
-QuicTime QuicNetworkBlackholeDetector::GetEarliestDeadline() const {
-  QuicTime result = QuicTime::Zero();
-  for (QuicTime t : {path_degrading_deadline_, blackhole_deadline_,
-                     path_mtu_reduction_deadline_}) {
-    if (!t.IsInitialized()) {
-      continue;
-    }
-
-    if (!result.IsInitialized() || t < result) {
-      result = t;
-    }
-  }
-
-  return result;
-}
-
-QuicTime QuicNetworkBlackholeDetector::GetLastDeadline() const {
-  return std::max({path_degrading_deadline_, blackhole_deadline_,
-                   path_mtu_reduction_deadline_});
-}
-
-void QuicNetworkBlackholeDetector::UpdateAlarm() const {
-  // If called after OnBlackholeDetected(), the alarm may have been permanently
-  // cancelled and is not safe to be armed again.
-  if (alarm_->IsPermanentlyCancelled()) {
-    return;
-  }
-
-  QuicTime next_deadline = GetEarliestDeadline();
-
-  QUIC_DVLOG(1) << "Updating alarm. next_deadline:" << next_deadline
-                << ", path_degrading_deadline_:" << path_degrading_deadline_
-                << ", path_mtu_reduction_deadline_:"
-                << path_mtu_reduction_deadline_
-                << ", blackhole_deadline_:" << blackhole_deadline_;
-
-  alarm_->Update(next_deadline, kAlarmGranularity);
-}
-
-bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
-  return alarm_->IsSet();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_network_blackhole_detector.h b/quic/core/quic_network_blackhole_detector.h
deleted file mode 100644
index db52e8f..0000000
--- a/quic/core/quic_network_blackhole_detector.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
-#define QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionPeer;
-class QuicNetworkBlackholeDetectorPeer;
-}  // namespace test
-
-// QuicNetworkBlackholeDetector can detect path degrading and/or network
-// blackhole. If both detections are in progress, detector will be in path
-// degrading detection mode. After reporting path degrading detected, detector
-// switches to blackhole detection mode. So blackhole detection deadline must
-// be later than path degrading deadline.
-class QUIC_EXPORT_PRIVATE QuicNetworkBlackholeDetector {
- public:
-  class QUIC_EXPORT_PRIVATE Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // Called when the path degrading alarm fires.
-    virtual void OnPathDegradingDetected() = 0;
-
-    // Called when the path blackhole alarm fires.
-    virtual void OnBlackholeDetected() = 0;
-
-    // Called when the path mtu reduction alarm fires.
-    virtual void OnPathMtuReductionDetected() = 0;
-  };
-
-  QuicNetworkBlackholeDetector(Delegate* delegate, QuicConnectionArena* arena,
-                               QuicAlarmFactory* alarm_factory,
-                               QuicConnectionContext* context);
-
-  // Called to stop all detections. If |permanent|, the alarm will be cancelled
-  // permanently and future calls to RestartDetection will be no-op.
-  void StopDetection(bool permanent);
-
-  // Called to restart path degrading, path mtu reduction and blackhole
-  // detections. Please note, if |blackhole_deadline| is set, it must be the
-  // furthest in the future of all deadlines.
-  void RestartDetection(QuicTime path_degrading_deadline,
-                        QuicTime blackhole_deadline,
-                        QuicTime path_mtu_reduction_deadline);
-
-  // Called when |alarm_| fires.
-  void OnAlarm();
-
-  // Returns true if |alarm_| is set.
-  bool IsDetectionInProgress() const;
-
- private:
-  friend class test::QuicConnectionPeer;
-  friend class test::QuicNetworkBlackholeDetectorPeer;
-
-  QuicTime GetEarliestDeadline() const;
-  QuicTime GetLastDeadline() const;
-
-  // Update alarm to the next deadline.
-  void UpdateAlarm() const;
-
-  Delegate* delegate_;  // Not owned.
-
-  // Time that Delegate::OnPathDegrading will be called. 0 means no path
-  // degrading detection is in progress.
-  QuicTime path_degrading_deadline_ = QuicTime::Zero();
-  // Time that Delegate::OnBlackholeDetected will be called. 0 means no
-  // blackhole detection is in progress.
-  QuicTime blackhole_deadline_ = QuicTime::Zero();
-  // Time that Delegate::OnPathMtuReductionDetected will be called. 0 means no
-  // path mtu reduction detection is in progress.
-  QuicTime path_mtu_reduction_deadline_ = QuicTime::Zero();
-
-  QuicArenaScopedPtr<QuicAlarm> alarm_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
diff --git a/quic/core/quic_network_blackhole_detector_test.cc b/quic/core/quic_network_blackhole_detector_test.cc
deleted file mode 100644
index 764ee9a..0000000
--- a/quic/core/quic_network_blackhole_detector_test.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_network_blackhole_detector.h"
-
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-class QuicNetworkBlackholeDetectorPeer {
- public:
-  static QuicAlarm* GetAlarm(QuicNetworkBlackholeDetector* detector) {
-    return detector->alarm_.get();
-  }
-};
-
-namespace {
-class MockDelegate : public QuicNetworkBlackholeDetector::Delegate {
- public:
-  MOCK_METHOD(void, OnPathDegradingDetected, (), (override));
-  MOCK_METHOD(void, OnBlackholeDetected, (), (override));
-  MOCK_METHOD(void, OnPathMtuReductionDetected, (), (override));
-};
-
-const size_t kPathDegradingDelayInSeconds = 5;
-const size_t kPathMtuReductionDelayInSeconds = 7;
-const size_t kBlackholeDelayInSeconds = 10;
-
-class QuicNetworkBlackholeDetectorTest : public QuicTest {
- public:
-  QuicNetworkBlackholeDetectorTest()
-      : detector_(&delegate_, &arena_, &alarm_factory_, /*context=*/nullptr),
-        alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
-            QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_))),
-        path_degrading_delay_(
-            QuicTime::Delta::FromSeconds(kPathDegradingDelayInSeconds)),
-        path_mtu_reduction_delay_(
-            QuicTime::Delta::FromSeconds(kPathMtuReductionDelayInSeconds)),
-        blackhole_delay_(
-            QuicTime::Delta::FromSeconds(kBlackholeDelayInSeconds)) {
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-
- protected:
-  void RestartDetection() {
-    detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
-                               clock_.Now() + blackhole_delay_,
-                               clock_.Now() + path_mtu_reduction_delay_);
-  }
-
-  testing::StrictMock<MockDelegate> delegate_;
-  QuicConnectionArena arena_;
-  MockAlarmFactory alarm_factory_;
-
-  QuicNetworkBlackholeDetector detector_;
-
-  MockAlarmFactory::TestAlarm* alarm_;
-  MockClock clock_;
-  const QuicTime::Delta path_degrading_delay_;
-  const QuicTime::Delta path_mtu_reduction_delay_;
-  const QuicTime::Delta blackhole_delay_;
-};
-
-TEST_F(QuicNetworkBlackholeDetectorTest, StartAndFire) {
-  EXPECT_FALSE(detector_.IsDetectionInProgress());
-
-  RestartDetection();
-  EXPECT_TRUE(detector_.IsDetectionInProgress());
-  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-
-  // Fire path degrading alarm.
-  clock_.AdvanceTime(path_degrading_delay_);
-  EXPECT_CALL(delegate_, OnPathDegradingDetected());
-  alarm_->Fire();
-
-  // Verify path mtu reduction detection is still in progress.
-  EXPECT_TRUE(detector_.IsDetectionInProgress());
-  EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
-            alarm_->deadline());
-
-  // Fire path mtu reduction detection alarm.
-  clock_.AdvanceTime(path_mtu_reduction_delay_ - path_degrading_delay_);
-  EXPECT_CALL(delegate_, OnPathMtuReductionDetected());
-  alarm_->Fire();
-
-  // Verify blackhole detection is still in progress.
-  EXPECT_TRUE(detector_.IsDetectionInProgress());
-  EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_mtu_reduction_delay_,
-            alarm_->deadline());
-
-  // Fire blackhole detection alarm.
-  clock_.AdvanceTime(blackhole_delay_ - path_mtu_reduction_delay_);
-  EXPECT_CALL(delegate_, OnBlackholeDetected());
-  alarm_->Fire();
-  EXPECT_FALSE(detector_.IsDetectionInProgress());
-}
-
-TEST_F(QuicNetworkBlackholeDetectorTest, RestartAndStop) {
-  RestartDetection();
-
-  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  RestartDetection();
-  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-
-  detector_.StopDetection(/*permanent=*/false);
-  EXPECT_FALSE(detector_.IsDetectionInProgress());
-}
-
-TEST_F(QuicNetworkBlackholeDetectorTest, PathDegradingFiresAndRestart) {
-  EXPECT_FALSE(detector_.IsDetectionInProgress());
-  RestartDetection();
-  EXPECT_TRUE(detector_.IsDetectionInProgress());
-  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-
-  // Fire path degrading alarm.
-  clock_.AdvanceTime(path_degrading_delay_);
-  EXPECT_CALL(delegate_, OnPathDegradingDetected());
-  alarm_->Fire();
-
-  // Verify path mtu reduction detection is still in progress.
-  EXPECT_TRUE(detector_.IsDetectionInProgress());
-  EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
-            alarm_->deadline());
-
-  // After 100ms, restart detections on forward progress.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  RestartDetection();
-  // Verify alarm is armed based on path degrading deadline.
-  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
-}
-
-}  // namespace
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_one_block_arena.h b/quic/core/quic_one_block_arena.h
deleted file mode 100644
index 02aae87..0000000
--- a/quic/core/quic_one_block_arena.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// An arena that consists of a single inlined block of |ArenaSize|. Useful to
-// avoid repeated calls to malloc/new and to improve memory locality.
-// QUICHE_DCHECK's if an allocation out of the arena ever fails in debug builds;
-// falls back to heap allocation in release builds.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
-#define QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_arena_scoped_ptr.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-template <uint32_t ArenaSize>
-class QUIC_EXPORT_PRIVATE QuicOneBlockArena {
-  static const uint32_t kMaxAlign = 8;
-
- public:
-  QuicOneBlockArena() : offset_(0) {}
-  QuicOneBlockArena(const QuicOneBlockArena&) = delete;
-  QuicOneBlockArena& operator=(const QuicOneBlockArena&) = delete;
-
-  // Instantiates an object of type |T| with |args|. |args| are perfectly
-  // forwarded to |T|'s constructor. The returned pointer's lifetime is
-  // controlled by QuicArenaScopedPtr.
-  template <typename T, typename... Args>
-  QuicArenaScopedPtr<T> New(Args&&... args) {
-    QUICHE_DCHECK_LT(AlignedSize<T>(), ArenaSize)
-        << "Object is too large for the arena.";
-    static_assert(alignof(T) > 1,
-                  "Objects added to the arena must be at least 2B aligned.");
-    if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
-      QUIC_BUG(quic_bug_10593_1)
-          << "Ran out of space in QuicOneBlockArena at " << this
-          << ", max size was " << ArenaSize << ", failing request was "
-          << AlignedSize<T>() << ", end of arena was " << offset_;
-      return QuicArenaScopedPtr<T>(new T(std::forward<Args>(args)...));
-    }
-
-    void* buf = &storage_[offset_];
-    new (buf) T(std::forward<Args>(args)...);
-    offset_ += AlignedSize<T>();
-    return QuicArenaScopedPtr<T>(buf,
-                                 QuicArenaScopedPtr<T>::ConstructFrom::kArena);
-  }
-
- private:
-  // Returns the size of |T| aligned up to |kMaxAlign|.
-  template <typename T>
-  static inline uint32_t AlignedSize() {
-    return ((sizeof(T) + (kMaxAlign - 1)) / kMaxAlign) * kMaxAlign;
-  }
-
-  // Actual storage.
-  // Subtle/annoying: the value '8' must be coded explicitly into the alignment
-  // declaration for MSVC.
-  alignas(8) char storage_[ArenaSize];
-  // Current offset into the storage.
-  uint32_t offset_;
-};
-
-// QuicConnections currently use around 1KB of polymorphic types which would
-// ordinarily be on the heap. Instead, store them inline in an arena.
-using QuicConnectionArena = QuicOneBlockArena<1152>;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
diff --git a/quic/core/quic_one_block_arena_test.cc b/quic/core/quic_one_block_arena_test.cc
deleted file mode 100644
index 181ab3f..0000000
--- a/quic/core/quic_one_block_arena_test.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_one_block_arena.h"
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace {
-
-static const uint32_t kMaxAlign = 8;
-
-struct TestObject {
-  uint32_t value;
-};
-
-class QuicOneBlockArenaTest : public QuicTest {};
-
-TEST_F(QuicOneBlockArenaTest, AllocateSuccess) {
-  QuicOneBlockArena<1024> arena;
-  QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
-  EXPECT_TRUE(ptr.is_from_arena());
-}
-
-TEST_F(QuicOneBlockArenaTest, Exhaust) {
-  QuicOneBlockArena<1024> arena;
-  for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
-    QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
-    EXPECT_TRUE(ptr.is_from_arena());
-  }
-  QuicArenaScopedPtr<TestObject> ptr;
-  EXPECT_QUIC_BUG(ptr = arena.New<TestObject>(),
-                  "Ran out of space in QuicOneBlockArena");
-  EXPECT_FALSE(ptr.is_from_arena());
-}
-
-TEST_F(QuicOneBlockArenaTest, NoOverlaps) {
-  QuicOneBlockArena<1024> arena;
-  std::vector<QuicArenaScopedPtr<TestObject>> objects;
-  QuicIntervalSet<uintptr_t> used;
-  for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
-    QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
-    EXPECT_TRUE(ptr.is_from_arena());
-
-    uintptr_t begin = reinterpret_cast<uintptr_t>(ptr.get());
-    uintptr_t end = begin + sizeof(TestObject);
-    EXPECT_FALSE(used.Contains(begin));
-    EXPECT_FALSE(used.Contains(end - 1));
-    used.Add(begin, end);
-  }
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
deleted file mode 100644
index 05ec64a..0000000
--- a/quic/core/quic_packet_creator.cc
+++ /dev/null
@@ -1,2306 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_creator.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/frames/quic_path_challenge_frame.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_chaos_protector.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "common/print_elements.h"
-
-namespace quic {
-namespace {
-
-QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-      return INITIAL;
-    case ENCRYPTION_HANDSHAKE:
-      return HANDSHAKE;
-    case ENCRYPTION_ZERO_RTT:
-      return ZERO_RTT_PROTECTED;
-    case ENCRYPTION_FORWARD_SECURE:
-      QUIC_BUG(quic_bug_12398_1)
-          << "Try to derive long header type for packet with encryption level: "
-          << level;
-      return INVALID_PACKET_TYPE;
-    default:
-      QUIC_BUG(quic_bug_10752_1) << level;
-      return INVALID_PACKET_TYPE;
-  }
-}
-
-void LogCoalesceStreamFrameStatus(bool success) {
-  QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
-                      "Success rate of coalesing stream frames attempt.");
-}
-
-// ScopedPacketContextSwitcher saves |packet|'s states and change states
-// during its construction. When the switcher goes out of scope, it restores
-// saved states.
-class ScopedPacketContextSwitcher {
- public:
-  ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
-                              QuicPacketNumberLength packet_number_length,
-                              EncryptionLevel encryption_level,
-                              SerializedPacket* packet)
-
-      : saved_packet_number_(packet->packet_number),
-        saved_packet_number_length_(packet->packet_number_length),
-        saved_encryption_level_(packet->encryption_level),
-        packet_(packet) {
-    packet_->packet_number = packet_number,
-    packet_->packet_number_length = packet_number_length;
-    packet_->encryption_level = encryption_level;
-  }
-
-  ~ScopedPacketContextSwitcher() {
-    packet_->packet_number = saved_packet_number_;
-    packet_->packet_number_length = saved_packet_number_length_;
-    packet_->encryption_level = saved_encryption_level_;
-  }
-
- private:
-  const QuicPacketNumber saved_packet_number_;
-  const QuicPacketNumberLength saved_packet_number_length_;
-  const EncryptionLevel saved_encryption_level_;
-  SerializedPacket* packet_;
-};
-
-}  // namespace
-
-#define ENDPOINT \
-  (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
-                                     QuicFramer* framer,
-                                     DelegateInterface* delegate)
-    : QuicPacketCreator(server_connection_id,
-                        framer,
-                        QuicRandom::GetInstance(),
-                        delegate) {}
-
-QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
-                                     QuicFramer* framer, QuicRandom* random,
-                                     DelegateInterface* delegate)
-    : delegate_(delegate),
-      debug_delegate_(nullptr),
-      framer_(framer),
-      random_(random),
-      send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
-      have_diversification_nonce_(false),
-      max_packet_length_(0),
-      server_connection_id_included_(CONNECTION_ID_PRESENT),
-      packet_size_(0),
-      server_connection_id_(server_connection_id),
-      client_connection_id_(EmptyQuicConnectionId()),
-      packet_(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false,
-              false),
-      pending_padding_bytes_(0),
-      needs_full_padding_(false),
-      next_transmission_type_(NOT_RETRANSMISSION),
-      flusher_attached_(false),
-      fully_pad_crypto_handshake_packets_(true),
-      latched_hard_max_packet_length_(0),
-      max_datagram_frame_size_(0),
-      chaos_protection_enabled_(
-          GetQuicFlag(FLAGS_quic_enable_chaos_protection) &&
-          framer->perspective() == Perspective::IS_CLIENT) {
-  SetMaxPacketLength(kDefaultMaxPacketSize);
-  if (!framer_->version().UsesTls()) {
-    // QUIC+TLS negotiates the maximum datagram frame size via the
-    // IETF QUIC max_datagram_frame_size transport parameter.
-    // QUIC_CRYPTO however does not negotiate this so we set its value here.
-    SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-  }
-}
-
-QuicPacketCreator::~QuicPacketCreator() {
-  DeleteFrames(&packet_.retransmittable_frames);
-}
-
-void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
-                                     std::unique_ptr<QuicEncrypter> encrypter) {
-  framer_->SetEncrypter(level, std::move(encrypter));
-  max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
-}
-
-bool QuicPacketCreator::CanSetMaxPacketLength() const {
-  // |max_packet_length_| should not be changed mid-packet.
-  return queued_frames_.empty();
-}
-
-void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
-  QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
-
-  // Avoid recomputing |max_plaintext_size_| if the length does not actually
-  // change.
-  if (length == max_packet_length_) {
-    return;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Updating packet creator max packet length from "
-                << max_packet_length_ << " to " << length;
-
-  max_packet_length_ = length;
-  max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
-  QUIC_BUG_IF(quic_bug_12398_2, max_plaintext_size_ - PacketHeaderSize() <
-                                    MinPlaintextPacketSize(framer_->version()))
-      << ENDPOINT << "Attempted to set max packet length too small";
-}
-
-void QuicPacketCreator::SetMaxDatagramFrameSize(
-    QuicByteCount max_datagram_frame_size) {
-  constexpr QuicByteCount upper_bound =
-      std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
-                              std::numeric_limits<size_t>::max());
-  if (max_datagram_frame_size > upper_bound) {
-    // A value of |max_datagram_frame_size| that is equal or greater than
-    // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
-    // We therefore clamp the value here to allow us to safely cast
-    // |max_datagram_frame_size_| to QuicPacketLength or size_t.
-    max_datagram_frame_size = upper_bound;
-  }
-  max_datagram_frame_size_ = max_datagram_frame_size;
-}
-
-void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
-  QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
-  if (length > max_packet_length_) {
-    QUIC_BUG(quic_bug_10752_2)
-        << ENDPOINT
-        << "Try to increase max_packet_length_ in "
-           "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
-    return;
-  }
-  if (framer_->GetMaxPlaintextSize(length) <
-      PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
-    // Please note: this would not guarantee to fit next packet if the size of
-    // packet header increases (e.g., encryption level changes).
-    QUIC_DLOG(INFO) << ENDPOINT << length
-                    << " is too small to fit packet header";
-    RemoveSoftMaxPacketLength();
-    return;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Setting soft max packet length to: " << length;
-  latched_hard_max_packet_length_ = max_packet_length_;
-  max_packet_length_ = length;
-  max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
-}
-
-// Stops serializing version of the protocol in packets sent after this call.
-// A packet that is already open might send kQuicVersionSize bytes less than the
-// maximum packet size if we stop sending version before it is serialized.
-void QuicPacketCreator::StopSendingVersion() {
-  QUICHE_DCHECK(send_version_in_packet_) << ENDPOINT;
-  QUICHE_DCHECK(!version().HasIetfInvariantHeader()) << ENDPOINT;
-  send_version_in_packet_ = false;
-  if (packet_size_ > 0) {
-    QUICHE_DCHECK_LT(kQuicVersionSize, packet_size_) << ENDPOINT;
-    packet_size_ -= kQuicVersionSize;
-  }
-}
-
-void QuicPacketCreator::SetDiversificationNonce(
-    const DiversificationNonce& nonce) {
-  QUICHE_DCHECK(!have_diversification_nonce_) << ENDPOINT;
-  have_diversification_nonce_ = true;
-  diversification_nonce_ = nonce;
-}
-
-void QuicPacketCreator::UpdatePacketNumberLength(
-    QuicPacketNumber least_packet_awaited_by_peer,
-    QuicPacketCount max_packets_in_flight) {
-  if (!queued_frames_.empty()) {
-    // Don't change creator state if there are frames queued.
-    QUIC_BUG(quic_bug_10752_3)
-        << ENDPOINT << "Called UpdatePacketNumberLength with "
-        << queued_frames_.size()
-        << " queued_frames.  First frame type:" << queued_frames_.front().type
-        << " last frame type:" << queued_frames_.back().type;
-    return;
-  }
-
-  const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
-  QUICHE_DCHECK_LE(least_packet_awaited_by_peer, next_packet_number)
-      << ENDPOINT;
-  const uint64_t current_delta =
-      next_packet_number - least_packet_awaited_by_peer;
-  const uint64_t delta = std::max(current_delta, max_packets_in_flight);
-  const QuicPacketNumberLength packet_number_length =
-      QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
-  if (packet_.packet_number_length == packet_number_length) {
-    return;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Updating packet number length from "
-                << static_cast<int>(packet_.packet_number_length) << " to "
-                << static_cast<int>(packet_number_length)
-                << ", least_packet_awaited_by_peer: "
-                << least_packet_awaited_by_peer
-                << " max_packets_in_flight: " << max_packets_in_flight
-                << " next_packet_number: " << next_packet_number;
-  packet_.packet_number_length = packet_number_length;
-}
-
-void QuicPacketCreator::SkipNPacketNumbers(
-    QuicPacketCount count,
-    QuicPacketNumber least_packet_awaited_by_peer,
-    QuicPacketCount max_packets_in_flight) {
-  if (!queued_frames_.empty()) {
-    // Don't change creator state if there are frames queued.
-    QUIC_BUG(quic_bug_10752_4)
-        << ENDPOINT << "Called SkipNPacketNumbers with "
-        << queued_frames_.size()
-        << " queued_frames.  First frame type:" << queued_frames_.front().type
-        << " last frame type:" << queued_frames_.back().type;
-    return;
-  }
-  if (packet_.packet_number > packet_.packet_number + count) {
-    // Skipping count packet numbers causes packet number wrapping around,
-    // reject it.
-    QUIC_LOG(WARNING) << ENDPOINT << "Skipping " << count
-                      << " packet numbers causes packet number wrapping "
-                         "around, least_packet_awaited_by_peer: "
-                      << least_packet_awaited_by_peer
-                      << " packet_number:" << packet_.packet_number;
-    return;
-  }
-  packet_.packet_number += count;
-  // Packet number changes, update packet number length if necessary.
-  UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
-}
-
-bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
-    EncryptionLevel level,
-    size_t write_length,
-    QuicStreamOffset offset,
-    bool needs_full_padding,
-    TransmissionType transmission_type,
-    QuicFrame* frame) {
-  QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoDataToFillCurrentPacket " << level
-                << " write_length " << write_length << " offset " << offset
-                << (needs_full_padding ? " needs_full_padding" : "") << " "
-                << transmission_type;
-  if (!CreateCryptoFrame(level, write_length, offset, frame)) {
-    return false;
-  }
-  // When crypto data was sent in stream frames, ConsumeData is called with
-  // |needs_full_padding = true|. Keep the same behavior here when sending
-  // crypto frames.
-  //
-  // TODO(nharper): Check what the IETF drafts say about padding out initial
-  // messages and change this as appropriate.
-  if (needs_full_padding) {
-    needs_full_padding_ = true;
-  }
-  return AddFrame(*frame, transmission_type);
-}
-
-bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
-    QuicStreamId id,
-    size_t data_size,
-    QuicStreamOffset offset,
-    bool fin,
-    bool needs_full_padding,
-    TransmissionType transmission_type,
-    QuicFrame* frame) {
-  if (!HasRoomForStreamFrame(id, offset, data_size)) {
-    return false;
-  }
-  CreateStreamFrame(id, data_size, offset, fin, frame);
-  // Explicitly disallow multi-packet CHLOs.
-  if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
-      StreamFrameIsClientHello(frame->stream_frame) &&
-      frame->stream_frame.data_length < data_size) {
-    const std::string error_details =
-        "Client hello won't fit in a single packet.";
-    QUIC_BUG(quic_bug_10752_5)
-        << ENDPOINT << error_details << " Constructed stream frame length: "
-        << frame->stream_frame.data_length << " CHLO length: " << data_size;
-    delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
-    return false;
-  }
-  if (!AddFrame(*frame, transmission_type)) {
-    // Fails if we try to write unencrypted stream data.
-    return false;
-  }
-  if (needs_full_padding) {
-    needs_full_padding_ = true;
-  }
-
-  return true;
-}
-
-bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
-                                              QuicStreamOffset offset,
-                                              size_t data_size) {
-  const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
-      framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
-      data_size);
-  if (BytesFree() > min_stream_frame_size) {
-    return true;
-  }
-  if (!RemoveSoftMaxPacketLength()) {
-    return false;
-  }
-  return BytesFree() > min_stream_frame_size;
-}
-
-bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
-  const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
-      framer_->transport_version(), /*last_frame_in_packet=*/true, length);
-  if (static_cast<QuicByteCount>(message_frame_size) >
-      max_datagram_frame_size_) {
-    return false;
-  }
-  if (BytesFree() >= message_frame_size) {
-    return true;
-  }
-  if (!RemoveSoftMaxPacketLength()) {
-    return false;
-  }
-  return BytesFree() >= message_frame_size;
-}
-
-// static
-size_t QuicPacketCreator::StreamFramePacketOverhead(
-    QuicTransportVersion version,
-    QuicConnectionIdLength destination_connection_id_length,
-    QuicConnectionIdLength source_connection_id_length,
-    bool include_version,
-    bool include_diversification_nonce,
-    QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    QuicVariableLengthIntegerLength length_length,
-    QuicStreamOffset offset) {
-  return GetPacketHeaderSize(version, destination_connection_id_length,
-                             source_connection_id_length, include_version,
-                             include_diversification_nonce,
-                             packet_number_length, retry_token_length_length, 0,
-                             length_length) +
-
-         // Assumes a packet with a single stream frame, which omits the length,
-         // causing the data length argument to be ignored.
-         QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
-                                           kMaxOutgoingPacketSize /* unused */);
-}
-
-void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
-                                          size_t data_size,
-                                          QuicStreamOffset offset,
-                                          bool fin,
-                                          QuicFrame* frame) {
-  // Make sure max_packet_length_ is greater than the largest possible overhead
-  // or max_packet_length_ is set to the soft limit.
-  QUICHE_DCHECK(
-      max_packet_length_ >
-          StreamFramePacketOverhead(
-              framer_->transport_version(), GetDestinationConnectionIdLength(),
-              GetSourceConnectionIdLength(), kIncludeVersion,
-              IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
-              GetRetryTokenLengthLength(), GetLengthLength(), offset) ||
-      latched_hard_max_packet_length_ > 0)
-      << ENDPOINT;
-
-  QUIC_BUG_IF(quic_bug_12398_3, !HasRoomForStreamFrame(id, offset, data_size))
-      << ENDPOINT << "No room for Stream frame, BytesFree: " << BytesFree()
-      << " MinStreamFrameSize: "
-      << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
-                                           offset, true, data_size);
-
-  QUIC_BUG_IF(quic_bug_12398_4, data_size == 0 && !fin)
-      << ENDPOINT << "Creating a stream frame for stream ID:" << id
-      << " with no data or fin.";
-  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
-      framer_->transport_version(), id, offset,
-      /* last_frame_in_packet= */ true, data_size);
-  size_t bytes_consumed =
-      std::min<size_t>(BytesFree() - min_frame_size, data_size);
-
-  bool set_fin = fin && bytes_consumed == data_size;  // Last frame.
-  *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
-}
-
-bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
-                                          size_t write_length,
-                                          QuicStreamOffset offset,
-                                          QuicFrame* frame) {
-  const size_t min_frame_size =
-      QuicFramer::GetMinCryptoFrameSize(write_length, offset);
-  if (BytesFree() <= min_frame_size &&
-      (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
-    return false;
-  }
-  size_t max_write_length = BytesFree() - min_frame_size;
-  size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
-  *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
-  return true;
-}
-
-void QuicPacketCreator::FlushCurrentPacket() {
-  if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
-    return;
-  }
-
-  ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
-  QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
-
-  if (external_buffer.buffer == nullptr) {
-    external_buffer.buffer = stack_buffer;
-    external_buffer.release_buffer = nullptr;
-  }
-
-  QUICHE_DCHECK_EQ(nullptr, packet_.encrypted_buffer) << ENDPOINT;
-  if (!SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize,
-                       /*allow_padding=*/true)) {
-    return;
-  }
-  OnSerializedPacket();
-}
-
-void QuicPacketCreator::OnSerializedPacket() {
-  QUIC_BUG_IF(quic_bug_12398_5, packet_.encrypted_buffer == nullptr)
-      << ENDPOINT;
-
-  SerializedPacket packet(std::move(packet_));
-  ClearPacket();
-  RemoveSoftMaxPacketLength();
-  delegate_->OnSerializedPacket(std::move(packet));
-}
-
-void QuicPacketCreator::ClearPacket() {
-  packet_.has_ack = false;
-  packet_.has_stop_waiting = false;
-  packet_.has_crypto_handshake = NOT_HANDSHAKE;
-  packet_.transmission_type = NOT_RETRANSMISSION;
-  packet_.encrypted_buffer = nullptr;
-  packet_.encrypted_length = 0;
-  packet_.has_ack_frequency = false;
-  packet_.has_message = false;
-  packet_.fate = SEND_TO_WRITER;
-  QUIC_BUG_IF(quic_bug_12398_6, packet_.release_encrypted_buffer != nullptr)
-      << ENDPOINT << "packet_.release_encrypted_buffer should be empty";
-  packet_.release_encrypted_buffer = nullptr;
-  QUICHE_DCHECK(packet_.retransmittable_frames.empty()) << ENDPOINT;
-  QUICHE_DCHECK(packet_.nonretransmittable_frames.empty()) << ENDPOINT;
-  packet_.largest_acked.Clear();
-  needs_full_padding_ = false;
-}
-
-size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
-    const SerializedPacket& packet,
-    size_t padding_size,
-    char* buffer,
-    size_t buffer_len) {
-  QUIC_BUG_IF(quic_bug_12398_7, packet.encryption_level != ENCRYPTION_INITIAL);
-  QUIC_BUG_IF(quic_bug_12398_8, packet.nonretransmittable_frames.empty() &&
-                                    packet.retransmittable_frames.empty())
-      << ENDPOINT
-      << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
-         "packet";
-
-  if (close_connection_if_fail_to_serialzie_coalesced_packet_ &&
-      HasPendingFrames()) {
-    QUIC_BUG(quic_packet_creator_unexpected_queued_frames)
-        << "Unexpected queued frames: " << GetPendingFramesInfo();
-    return 0;
-  }
-
-  ScopedPacketContextSwitcher switcher(
-      packet.packet_number -
-          1,  // -1 because serialize packet increase packet number.
-      packet.packet_number_length, packet.encryption_level, &packet_);
-  for (const QuicFrame& frame : packet.nonretransmittable_frames) {
-    if (!AddFrame(frame, packet.transmission_type)) {
-      QUIC_BUG(quic_bug_10752_6)
-          << ENDPOINT << "Failed to serialize frame: " << frame;
-      return 0;
-    }
-  }
-  for (const QuicFrame& frame : packet.retransmittable_frames) {
-    if (!AddFrame(frame, packet.transmission_type)) {
-      QUIC_BUG(quic_bug_10752_7)
-          << ENDPOINT << "Failed to serialize frame: " << frame;
-      return 0;
-    }
-  }
-  // Add necessary padding.
-  if (padding_size > 0) {
-    QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
-    if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
-                  packet.transmission_type)) {
-      QUIC_BUG(quic_bug_10752_8)
-          << ENDPOINT << "Failed to add padding of size " << padding_size
-          << " when serializing ENCRYPTION_INITIAL "
-             "packet in coalesced packet";
-      return 0;
-    }
-  }
-
-  if (close_connection_if_fail_to_serialzie_coalesced_packet_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(
-        quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 1, 2);
-  }
-
-  if (!SerializePacket(
-          QuicOwnedPacketBuffer(buffer, nullptr), buffer_len,
-          /*allow_padding=*/
-          !close_connection_if_fail_to_serialzie_coalesced_packet_)) {
-    return 0;
-  }
-  const size_t encrypted_length = packet_.encrypted_length;
-  // Clear frames in packet_. No need to DeleteFrames since frames are owned by
-  // initial_packet.
-  packet_.retransmittable_frames.clear();
-  packet_.nonretransmittable_frames.clear();
-  ClearPacket();
-  return encrypted_length;
-}
-
-void QuicPacketCreator::CreateAndSerializeStreamFrame(
-    QuicStreamId id,
-    size_t write_length,
-    QuicStreamOffset iov_offset,
-    QuicStreamOffset stream_offset,
-    bool fin,
-    TransmissionType transmission_type,
-    size_t* num_bytes_consumed) {
-  // TODO(b/167222597): consider using ScopedSerializationFailureHandler.
-  QUICHE_DCHECK(queued_frames_.empty()) << ENDPOINT;
-  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
-      << ENDPOINT;
-  // Write out the packet header
-  QuicPacketHeader header;
-  FillPacketHeader(&header);
-  packet_.fate = delegate_->GetSerializedPacketFate(
-      /*is_mtu_discovery=*/false, packet_.encryption_level);
-  QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
-                << ": " << SerializedPacketFateToString(packet_.fate) << " of "
-                << EncryptionLevelToString(packet_.encryption_level);
-
-  ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
-  QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
-
-  if (packet_buffer.buffer == nullptr) {
-    packet_buffer.buffer = stack_buffer;
-    packet_buffer.release_buffer = nullptr;
-  }
-
-  char* encrypted_buffer = packet_buffer.buffer;
-
-  QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
-  size_t length_field_offset = 0;
-  if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
-    QUIC_BUG(quic_bug_10752_9) << ENDPOINT << "AppendPacketHeader failed";
-    return;
-  }
-
-  // Create a Stream frame with the remaining space.
-  QUIC_BUG_IF(quic_bug_12398_9, iov_offset == write_length && !fin)
-      << ENDPOINT << "Creating a stream frame with no data or fin.";
-  const size_t remaining_data_size = write_length - iov_offset;
-  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
-      framer_->transport_version(), id, stream_offset,
-      /* last_frame_in_packet= */ true, remaining_data_size);
-  size_t available_size =
-      max_plaintext_size_ - writer.length() - min_frame_size;
-  size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
-  size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
-  bool needs_padding = false;
-  if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
-    needs_padding = true;
-    // Recalculate sizes with the stream frame not being marked as the last
-    // frame in the packet.
-    min_frame_size = QuicFramer::GetMinStreamFrameSize(
-        framer_->transport_version(), id, stream_offset,
-        /* last_frame_in_packet= */ false, remaining_data_size);
-    available_size = max_plaintext_size_ - writer.length() - min_frame_size;
-    bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
-    plaintext_bytes_written = min_frame_size + bytes_consumed;
-  }
-
-  const bool set_fin = fin && (bytes_consumed == remaining_data_size);
-  QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
-
-  QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
-
-  // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
-  // into one method that takes a QuicStreamFrame, if warranted.
-  bool omit_frame_length = !needs_padding;
-  if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
-    QUIC_BUG(quic_bug_10752_10) << ENDPOINT << "AppendTypeByte failed";
-    return;
-  }
-  if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
-    QUIC_BUG(quic_bug_10752_11) << ENDPOINT << "AppendStreamFrame failed";
-    return;
-  }
-  if (needs_padding &&
-      plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
-      !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
-                                plaintext_bytes_written)) {
-    QUIC_BUG(quic_bug_10752_12) << ENDPOINT << "Unable to add padding bytes";
-    return;
-  }
-
-  if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
-                                          packet_.encryption_level)) {
-    return;
-  }
-
-  packet_.transmission_type = transmission_type;
-
-  QUICHE_DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
-                packet_.encryption_level == ENCRYPTION_ZERO_RTT)
-      << ENDPOINT << packet_.encryption_level;
-  size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.packet_number,
-      GetStartOfEncryptedData(framer_->transport_version(), header),
-      writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
-  if (encrypted_length == 0) {
-    QUIC_BUG(quic_bug_10752_13)
-        << ENDPOINT << "Failed to encrypt packet number "
-        << header.packet_number;
-    return;
-  }
-  // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
-  // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
-  *num_bytes_consumed = bytes_consumed;
-  packet_size_ = 0;
-  packet_.encrypted_buffer = encrypted_buffer;
-  packet_.encrypted_length = encrypted_length;
-
-  packet_buffer.buffer = nullptr;
-  packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
-
-  packet_.retransmittable_frames.push_back(QuicFrame(frame));
-  OnSerializedPacket();
-}
-
-bool QuicPacketCreator::HasPendingFrames() const {
-  return !queued_frames_.empty();
-}
-
-std::string QuicPacketCreator::GetPendingFramesInfo() const {
-  return QuicFramesToString(queued_frames_);
-}
-
-bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
-  return !packet_.retransmittable_frames.empty();
-}
-
-bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
-  for (const auto& frame : packet_.retransmittable_frames) {
-    if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
-      return true;
-    }
-  }
-  return false;
-}
-
-size_t QuicPacketCreator::ExpansionOnNewFrame() const {
-  // If the last frame in the packet is a message frame, then it will expand to
-  // include the varint message length when a new frame is added.
-  if (queued_frames_.empty()) {
-    return 0;
-  }
-  return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
-                                          framer_->transport_version());
-}
-
-// static
-size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
-    const QuicFrame& last_frame,
-    QuicTransportVersion version) {
-  if (last_frame.type == MESSAGE_FRAME) {
-    return QuicDataWriter::GetVarInt62Len(
-        last_frame.message_frame->message_length);
-  }
-  if (last_frame.type != STREAM_FRAME) {
-    return 0;
-  }
-  if (VersionHasIetfQuicFrames(version)) {
-    return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
-  }
-  return kQuicStreamPayloadLengthSize;
-}
-
-size_t QuicPacketCreator::BytesFree() const {
-  return max_plaintext_size_ -
-         std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
-}
-
-size_t QuicPacketCreator::PacketSize() const {
-  return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
-}
-
-bool QuicPacketCreator::AddPaddedSavedFrame(
-    const QuicFrame& frame,
-    TransmissionType transmission_type) {
-  if (AddFrame(frame, transmission_type)) {
-    needs_full_padding_ = true;
-    return true;
-  }
-  return false;
-}
-
-absl::optional<size_t>
-QuicPacketCreator::MaybeBuildDataPacketWithChaosProtection(
-    const QuicPacketHeader& header,
-    char* buffer) {
-  if (!chaos_protection_enabled_ ||
-      packet_.encryption_level != ENCRYPTION_INITIAL ||
-      !framer_->version().UsesCryptoFrames() || queued_frames_.size() != 2u ||
-      queued_frames_[0].type != CRYPTO_FRAME ||
-      queued_frames_[1].type != PADDING_FRAME ||
-      // Do not perform chaos protection if we do not have a known number of
-      // padding bytes to work with.
-      queued_frames_[1].padding_frame.num_padding_bytes <= 0 ||
-      // Chaos protection relies on the framer using a crypto data producer,
-      // which is always the case in practice.
-      framer_->data_producer() == nullptr) {
-    return absl::nullopt;
-  }
-  const QuicCryptoFrame& crypto_frame = *queued_frames_[0].crypto_frame;
-  if (packet_.encryption_level != crypto_frame.level) {
-    QUIC_BUG(chaos frame level)
-        << ENDPOINT << packet_.encryption_level << " != " << crypto_frame.level;
-    return absl::nullopt;
-  }
-  QuicChaosProtector chaos_protector(
-      crypto_frame, queued_frames_[1].padding_frame.num_padding_bytes,
-      packet_size_, framer_, random_);
-  return chaos_protector.BuildDataPacket(header, buffer);
-}
-
-bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
-                                        size_t encrypted_buffer_len,
-                                        bool allow_padding) {
-  if (packet_.encrypted_buffer != nullptr) {
-    const std::string error_details =
-        "Packet's encrypted buffer is not empty before serialization";
-    QUIC_BUG(quic_bug_10752_14) << ENDPOINT << error_details;
-    delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
-                                    error_details);
-    return false;
-  }
-  ScopedSerializationFailureHandler handler(this);
-
-  QUICHE_DCHECK_LT(0u, encrypted_buffer_len) << ENDPOINT;
-  QUIC_BUG_IF(quic_bug_12398_10,
-              queued_frames_.empty() && pending_padding_bytes_ == 0)
-      << ENDPOINT << "Attempt to serialize empty packet";
-  QuicPacketHeader header;
-  // FillPacketHeader increments packet_number_.
-  FillPacketHeader(&header);
-  if (delegate_ != nullptr) {
-    packet_.fate = delegate_->GetSerializedPacketFate(
-        /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
-                                                          MTU_DISCOVERY_FRAME),
-        packet_.encryption_level);
-    QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
-                  << ": " << SerializedPacketFateToString(packet_.fate)
-                  << " of "
-                  << EncryptionLevelToString(packet_.encryption_level);
-  }
-
-  if (allow_padding) {
-    MaybeAddPadding();
-  }
-
-  QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
-                << QuicFramesToString(queued_frames_) << " at encryption_level "
-                << packet_.encryption_level
-                << ", allow_padding:" << allow_padding;
-
-  if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
-    // TODO(fayang): Use QUIC_MISSING_WRITE_KEYS for serialization failures due
-    // to missing keys.
-    QUIC_BUG(quic_bug_10752_15)
-        << ENDPOINT << "Attempting to serialize " << header
-        << QuicFramesToString(queued_frames_) << " at missing encryption_level "
-        << packet_.encryption_level << " using " << framer_->version();
-    return false;
-  }
-
-  QUICHE_DCHECK_GE(max_plaintext_size_, packet_size_) << ENDPOINT;
-  // Use the packet_size_ instead of the buffer size to ensure smaller
-  // packet sizes are properly used.
-
-  size_t length;
-  absl::optional<size_t> length_with_chaos_protection =
-      MaybeBuildDataPacketWithChaosProtection(header, encrypted_buffer.buffer);
-  if (length_with_chaos_protection.has_value()) {
-    length = length_with_chaos_protection.value();
-  } else {
-    length = framer_->BuildDataPacket(header, queued_frames_,
-                                      encrypted_buffer.buffer, packet_size_,
-                                      packet_.encryption_level);
-  }
-
-  if (length == 0) {
-    QUIC_BUG(quic_bug_10752_16)
-        << ENDPOINT << "Failed to serialize "
-        << QuicFramesToString(queued_frames_)
-        << " at encryption_level: " << packet_.encryption_level
-        << ", needs_full_padding_: " << needs_full_padding_
-        << ", pending_padding_bytes_: " << pending_padding_bytes_
-        << ", latched_hard_max_packet_length_: "
-        << latched_hard_max_packet_length_
-        << ", max_packet_length_: " << max_packet_length_
-        << ", header: " << header;
-    return false;
-  }
-
-  // ACK Frames will be truncated due to length only if they're the only frame
-  // in the packet, and if packet_size_ was set to max_plaintext_size_. If
-  // truncation due to length occurred, then GetSerializedFrameLength will have
-  // returned all bytes free.
-  bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
-                                      queued_frames_.size() == 1 &&
-                                      queued_frames_.back().type == ACK_FRAME;
-  // Because of possible truncation, we can't be confident that our
-  // packet size calculation worked correctly.
-  if (!possibly_truncated_by_length) {
-    QUICHE_DCHECK_EQ(packet_size_, length) << ENDPOINT;
-  }
-  const size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.packet_number,
-      GetStartOfEncryptedData(framer_->transport_version(), header), length,
-      encrypted_buffer_len, encrypted_buffer.buffer);
-  if (encrypted_length == 0) {
-    QUIC_BUG(quic_bug_10752_17)
-        << ENDPOINT << "Failed to encrypt packet number "
-        << packet_.packet_number;
-    return false;
-  }
-
-  packet_size_ = 0;
-  packet_.encrypted_buffer = encrypted_buffer.buffer;
-  packet_.encrypted_length = encrypted_length;
-
-  encrypted_buffer.buffer = nullptr;
-  packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
-  return true;
-}
-
-std::unique_ptr<SerializedPacket>
-QuicPacketCreator::SerializeConnectivityProbingPacket() {
-  QUIC_BUG_IF(quic_bug_12398_11,
-              VersionHasIetfQuicFrames(framer_->transport_version()))
-      << ENDPOINT
-      << "Must not be version 99 to serialize padded ping connectivity probe";
-  RemoveSoftMaxPacketLength();
-  QuicPacketHeader header;
-  // FillPacketHeader increments packet_number_.
-  FillPacketHeader(&header);
-
-  QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
-                << header;
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  size_t length = BuildConnectivityProbingPacket(
-      header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
-  QUICHE_DCHECK(length) << ENDPOINT;
-
-  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
-      << ENDPOINT;
-  const size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.packet_number,
-      GetStartOfEncryptedData(framer_->transport_version(), header), length,
-      kMaxOutgoingPacketSize, buffer.get());
-  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
-
-  std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
-      header.packet_number, header.packet_number_length, buffer.release(),
-      encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
-
-  serialize_packet->release_encrypted_buffer = [](const char* p) {
-    delete[] p;
-  };
-  serialize_packet->encryption_level = packet_.encryption_level;
-  serialize_packet->transmission_type = NOT_RETRANSMISSION;
-
-  return serialize_packet;
-}
-
-std::unique_ptr<SerializedPacket>
-QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
-    const QuicPathFrameBuffer& payload) {
-  QUIC_BUG_IF(quic_bug_12398_12,
-              !VersionHasIetfQuicFrames(framer_->transport_version()))
-      << ENDPOINT
-      << "Must be version 99 to serialize path challenge connectivity probe, "
-         "is version "
-      << framer_->transport_version();
-  RemoveSoftMaxPacketLength();
-  QuicPacketHeader header;
-  // FillPacketHeader increments packet_number_.
-  FillPacketHeader(&header);
-
-  QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  size_t length =
-      BuildPaddedPathChallengePacket(header, buffer.get(), max_plaintext_size_,
-                                     payload, packet_.encryption_level);
-  QUICHE_DCHECK(length) << ENDPOINT;
-
-  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
-      << ENDPOINT;
-  const size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.packet_number,
-      GetStartOfEncryptedData(framer_->transport_version(), header), length,
-      kMaxOutgoingPacketSize, buffer.get());
-  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
-
-  std::unique_ptr<SerializedPacket> serialize_packet(
-      new SerializedPacket(header.packet_number, header.packet_number_length,
-                           buffer.release(), encrypted_length,
-                           /*has_ack=*/false, /*has_stop_waiting=*/false));
-
-  serialize_packet->release_encrypted_buffer = [](const char* p) {
-    delete[] p;
-  };
-  serialize_packet->encryption_level = packet_.encryption_level;
-  serialize_packet->transmission_type = NOT_RETRANSMISSION;
-
-  return serialize_packet;
-}
-
-std::unique_ptr<SerializedPacket>
-QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
-    const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
-    const bool is_padded) {
-  QUIC_BUG_IF(quic_bug_12398_13,
-              !VersionHasIetfQuicFrames(framer_->transport_version()))
-      << ENDPOINT
-      << "Must be version 99 to serialize path response connectivity probe, is "
-         "version "
-      << framer_->transport_version();
-  RemoveSoftMaxPacketLength();
-  QuicPacketHeader header;
-  // FillPacketHeader increments packet_number_.
-  FillPacketHeader(&header);
-
-  QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  size_t length =
-      BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
-                              payloads, is_padded, packet_.encryption_level);
-  QUICHE_DCHECK(length) << ENDPOINT;
-
-  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
-      << ENDPOINT;
-  const size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.packet_number,
-      GetStartOfEncryptedData(framer_->transport_version(), header), length,
-      kMaxOutgoingPacketSize, buffer.get());
-  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
-
-  std::unique_ptr<SerializedPacket> serialize_packet(
-      new SerializedPacket(header.packet_number, header.packet_number_length,
-                           buffer.release(), encrypted_length,
-                           /*has_ack=*/false, /*has_stop_waiting=*/false));
-
-  serialize_packet->release_encrypted_buffer = [](const char* p) {
-    delete[] p;
-  };
-  serialize_packet->encryption_level = packet_.encryption_level;
-  serialize_packet->transmission_type = NOT_RETRANSMISSION;
-
-  return serialize_packet;
-}
-
-size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
-    const QuicPacketHeader& header,
-    char* buffer,
-    size_t packet_length,
-    const QuicPathFrameBuffer& payload,
-    EncryptionLevel level) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
-      << ENDPOINT;
-  QuicFrames frames;
-
-  // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
-  QuicPathChallengeFrame path_challenge_frame(0, payload);
-  frames.push_back(QuicFrame(&path_challenge_frame));
-
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
-  }
-
-  // Add padding to the rest of the packet in order to assess Path MTU
-  // characteristics.
-  QuicPaddingFrame padding_frame;
-  frames.push_back(QuicFrame(padding_frame));
-
-  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
-}
-
-size_t QuicPacketCreator::BuildPathResponsePacket(
-    const QuicPacketHeader& header,
-    char* buffer,
-    size_t packet_length,
-    const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
-    const bool is_padded,
-    EncryptionLevel level) {
-  if (payloads.empty()) {
-    QUIC_BUG(quic_bug_12398_14)
-        << ENDPOINT
-        << "Attempt to generate connectivity response with no request payloads";
-    return 0;
-  }
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
-      << ENDPOINT;
-
-  std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
-  for (const QuicPathFrameBuffer& payload : payloads) {
-    // Note that the control frame ID can be 0 since this is not retransmitted.
-    path_response_frames.push_back(
-        std::make_unique<QuicPathResponseFrame>(0, payload));
-  }
-
-  QuicFrames frames;
-  for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
-       path_response_frames) {
-    frames.push_back(QuicFrame(path_response_frame.get()));
-    if (debug_delegate_ != nullptr) {
-      debug_delegate_->OnFrameAddedToPacket(
-          QuicFrame(path_response_frame.get()));
-    }
-  }
-
-  if (is_padded) {
-    // Add padding to the rest of the packet in order to assess Path MTU
-    // characteristics.
-    QuicPaddingFrame padding_frame;
-    frames.push_back(QuicFrame(padding_frame));
-  }
-
-  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
-}
-
-size_t QuicPacketCreator::BuildConnectivityProbingPacket(
-    const QuicPacketHeader& header,
-    char* buffer,
-    size_t packet_length,
-    EncryptionLevel level) {
-  QuicFrames frames;
-
-  // Write a PING frame, which has no data payload.
-  QuicPingFrame ping_frame;
-  frames.push_back(QuicFrame(ping_frame));
-
-  // Add padding to the rest of the packet.
-  QuicPaddingFrame padding_frame;
-  frames.push_back(QuicFrame(padding_frame));
-
-  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
-}
-
-size_t QuicPacketCreator::SerializeCoalescedPacket(
-    const QuicCoalescedPacket& coalesced,
-    char* buffer,
-    size_t buffer_len) {
-  if (HasPendingFrames()) {
-    QUIC_BUG(quic_bug_10752_18)
-        << ENDPOINT << "Try to serialize coalesced packet with pending frames";
-    return 0;
-  }
-  RemoveSoftMaxPacketLength();
-  QUIC_BUG_IF(quic_bug_12398_15, coalesced.length() == 0)
-      << ENDPOINT << "Attempt to serialize empty coalesced packet";
-  size_t packet_length = 0;
-  size_t initial_length = 0;
-  size_t padding_size = 0;
-  if (coalesced.initial_packet() != nullptr) {
-    // Padding coalesced packet containing initial packet to full.
-    padding_size = coalesced.max_packet_length() - coalesced.length();
-    if (framer_->perspective() == Perspective::IS_SERVER &&
-        QuicUtils::ContainsFrameType(
-            coalesced.initial_packet()->retransmittable_frames,
-            CONNECTION_CLOSE_FRAME)) {
-      // Do not pad server initial connection close packet.
-      padding_size = 0;
-    }
-    initial_length = ReserializeInitialPacketInCoalescedPacket(
-        *coalesced.initial_packet(), padding_size, buffer, buffer_len);
-    if (initial_length == 0) {
-      QUIC_BUG(quic_bug_10752_19)
-          << ENDPOINT
-          << "Failed to reserialize ENCRYPTION_INITIAL packet in "
-             "coalesced packet";
-      return 0;
-    }
-    QUIC_BUG_IF(quic_reserialize_initial_packet_unexpected_size,
-                coalesced.initial_packet()->encrypted_length + padding_size !=
-                    initial_length)
-        << "Reserialize initial packet in coalescer has unexpected size, "
-           "original_length: "
-        << coalesced.initial_packet()->encrypted_length
-        << ", coalesced.max_packet_length: " << coalesced.max_packet_length()
-        << ", coalesced.length: " << coalesced.length()
-        << ", padding_size: " << padding_size
-        << ", serialized_length: " << initial_length
-        << ", retransmittable frames: "
-        << QuicFramesToString(
-               coalesced.initial_packet()->retransmittable_frames)
-        << ", nonretransmittable frames: "
-        << QuicFramesToString(
-               coalesced.initial_packet()->nonretransmittable_frames);
-    buffer += initial_length;
-    buffer_len -= initial_length;
-    packet_length += initial_length;
-  }
-  size_t length_copied = 0;
-  if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
-    QUIC_BUG(quic_serialize_coalesced_packet_copy_failure)
-        << "SerializeCoalescedPacket failed. buffer_len:" << buffer_len
-        << ", initial_length:" << initial_length
-        << ", padding_size: " << padding_size
-        << ", length_copied:" << length_copied
-        << ", coalesced.length:" << coalesced.length()
-        << ", coalesced.max_packet_length:" << coalesced.max_packet_length()
-        << ", coalesced.packet_lengths:"
-        << absl::StrJoin(coalesced.packet_lengths(), ":");
-    return 0;
-  }
-  packet_length += length_copied;
-  QUIC_DVLOG(1) << ENDPOINT
-                << "Successfully serialized coalesced packet of length: "
-                << packet_length;
-  return packet_length;
-}
-
-// TODO(b/74062209): Make this a public method of framer?
-SerializedPacket QuicPacketCreator::NoPacket() {
-  return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
-                          nullptr, 0, false, false);
-}
-
-QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
-  if (framer_->perspective() == Perspective::IS_SERVER) {
-    return client_connection_id_;
-  }
-  return server_connection_id_;
-}
-
-QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
-  if (framer_->perspective() == Perspective::IS_CLIENT) {
-    return client_connection_id_;
-  }
-  return server_connection_id_;
-}
-
-QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
-    const {
-  // In versions that do not support client connection IDs, the destination
-  // connection ID is only sent from client to server.
-  return (framer_->perspective() == Perspective::IS_CLIENT ||
-          framer_->version().SupportsClientConnectionIds())
-             ? CONNECTION_ID_PRESENT
-             : CONNECTION_ID_ABSENT;
-}
-
-QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
-    const {
-  // Long header packets sent by server include source connection ID.
-  // Ones sent by the client only include source connection ID if the version
-  // supports client connection IDs.
-  if (HasIetfLongHeader() &&
-      (framer_->perspective() == Perspective::IS_SERVER ||
-       framer_->version().SupportsClientConnectionIds())) {
-    return CONNECTION_ID_PRESENT;
-  }
-  if (framer_->perspective() == Perspective::IS_SERVER) {
-    return server_connection_id_included_;
-  }
-  return CONNECTION_ID_ABSENT;
-}
-
-QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
-    const {
-  QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
-                                                         transport_version()))
-      << ENDPOINT;
-  return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
-             ? static_cast<QuicConnectionIdLength>(
-                   GetDestinationConnectionId().length())
-             : PACKET_0BYTE_CONNECTION_ID;
-}
-
-QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
-  QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
-                                                         transport_version()))
-      << ENDPOINT;
-  return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
-             ? static_cast<QuicConnectionIdLength>(
-                   GetSourceConnectionId().length())
-             : PACKET_0BYTE_CONNECTION_ID;
-}
-
-QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
-  if (HasIetfLongHeader() &&
-      !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
-    return PACKET_4BYTE_PACKET_NUMBER;
-  }
-  return packet_.packet_number_length;
-}
-
-size_t QuicPacketCreator::PacketHeaderSize() const {
-  return GetPacketHeaderSize(
-      framer_->transport_version(), GetDestinationConnectionIdLength(),
-      GetSourceConnectionIdLength(), IncludeVersionInHeader(),
-      IncludeNonceInPublicHeader(), GetPacketNumberLength(),
-      GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
-}
-
-QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
-    const {
-  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
-      HasIetfLongHeader() &&
-      EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
-    return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
-  }
-  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-}
-
-absl::string_view QuicPacketCreator::GetRetryToken() const {
-  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
-      HasIetfLongHeader() &&
-      EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
-    return retry_token_;
-  }
-  return absl::string_view();
-}
-
-void QuicPacketCreator::SetRetryToken(absl::string_view retry_token) {
-  retry_token_ = std::string(retry_token);
-}
-
-bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
-    const QuicFrame& frame) {
-  QUIC_BUG_IF(quic_bug_12398_16, IsControlFrame(frame.type) &&
-                                     !GetControlFrameId(frame) &&
-                                     frame.type != PING_FRAME)
-      << ENDPOINT
-      << "Adding a control frame with no control frame id: " << frame;
-  QUICHE_DCHECK(QuicUtils::IsRetransmittableFrame(frame.type))
-      << ENDPOINT << frame;
-  MaybeBundleAckOpportunistically();
-  if (HasPendingFrames()) {
-    if (AddFrame(frame, next_transmission_type_)) {
-      // There is pending frames and current frame fits.
-      return true;
-    }
-  }
-  QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
-  if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
-      !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
-                                       NOT_HANDSHAKE)) {
-    // Do not check congestion window for ping or connection close frames.
-    return false;
-  }
-  const bool success = AddFrame(frame, next_transmission_type_);
-  QUIC_BUG_IF(quic_bug_10752_20, !success)
-      << ENDPOINT << "Failed to add frame:" << frame
-      << " transmission_type:" << next_transmission_type_;
-  return success;
-}
-
-QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
-                                                size_t write_length,
-                                                QuicStreamOffset offset,
-                                                StreamSendingState state) {
-  QUIC_BUG_IF(quic_bug_10752_21, !flusher_attached_)
-      << ENDPOINT
-      << "Packet flusher is not attached when "
-         "generator tries to write stream data.";
-  bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
-  MaybeBundleAckOpportunistically();
-  bool fin = state != NO_FIN;
-  QUIC_BUG_IF(quic_bug_12398_17, has_handshake && fin)
-      << ENDPOINT << "Handshake packets should never send a fin";
-  // To make reasoning about crypto frames easier, we don't combine them with
-  // other retransmittable frames in a single packet.
-  if (has_handshake && HasPendingRetransmittableFrames()) {
-    FlushCurrentPacket();
-  }
-
-  size_t total_bytes_consumed = 0;
-  bool fin_consumed = false;
-
-  if (!HasRoomForStreamFrame(id, offset, write_length)) {
-    FlushCurrentPacket();
-  }
-
-  if (!fin && (write_length == 0)) {
-    QUIC_BUG(quic_bug_10752_22)
-        << ENDPOINT << "Attempt to consume empty data without FIN.";
-    return QuicConsumedData(0, false);
-  }
-  // We determine if we can enter the fast path before executing
-  // the slow path loop.
-  bool run_fast_path =
-      !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
-      write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
-      latched_hard_max_packet_length_ == 0;
-
-  while (!run_fast_path &&
-         (has_handshake || delegate_->ShouldGeneratePacket(
-                               HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
-    QuicFrame frame;
-    bool needs_full_padding =
-        has_handshake && fully_pad_crypto_handshake_packets_;
-
-    if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
-                                        offset + total_bytes_consumed, fin,
-                                        needs_full_padding,
-                                        next_transmission_type_, &frame)) {
-      // The creator is always flushed if there's not enough room for a new
-      // stream frame before ConsumeData, so ConsumeData should always succeed.
-      QUIC_BUG(quic_bug_10752_23)
-          << ENDPOINT << "Failed to ConsumeData, stream:" << id;
-      return QuicConsumedData(0, false);
-    }
-
-    // A stream frame is created and added.
-    size_t bytes_consumed = frame.stream_frame.data_length;
-    total_bytes_consumed += bytes_consumed;
-    fin_consumed = fin && total_bytes_consumed == write_length;
-    if (fin_consumed && state == FIN_AND_PADDING) {
-      AddRandomPadding();
-    }
-    QUICHE_DCHECK(total_bytes_consumed == write_length ||
-                  (bytes_consumed > 0 && HasPendingFrames()))
-        << ENDPOINT;
-
-    if (total_bytes_consumed == write_length) {
-      // We're done writing the data. Exit the loop.
-      // We don't make this a precondition because we could have 0 bytes of data
-      // if we're simply writing a fin.
-      break;
-    }
-    FlushCurrentPacket();
-
-    run_fast_path =
-        !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
-        write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
-        latched_hard_max_packet_length_ == 0;
-  }
-
-  if (run_fast_path) {
-    return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
-                               total_bytes_consumed);
-  }
-
-  // Don't allow the handshake to be bundled with other retransmittable frames.
-  if (has_handshake) {
-    FlushCurrentPacket();
-  }
-
-  return QuicConsumedData(total_bytes_consumed, fin_consumed);
-}
-
-QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
-    QuicStreamId id,
-    size_t write_length,
-    QuicStreamOffset offset,
-    bool fin,
-    size_t total_bytes_consumed) {
-  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
-      << ENDPOINT;
-  if (AttemptingToSendUnencryptedStreamData()) {
-    return QuicConsumedData(total_bytes_consumed,
-                            fin && (total_bytes_consumed == write_length));
-  }
-
-  while (total_bytes_consumed < write_length &&
-         delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
-                                         NOT_HANDSHAKE)) {
-    // Serialize and encrypt the packet.
-    size_t bytes_consumed = 0;
-    CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
-                                  offset + total_bytes_consumed, fin,
-                                  next_transmission_type_, &bytes_consumed);
-    if (bytes_consumed == 0) {
-      const std::string error_details =
-          "Failed in CreateAndSerializeStreamFrame.";
-      QUIC_BUG(quic_bug_10752_24) << ENDPOINT << error_details;
-      delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
-                                      error_details);
-      break;
-    }
-    total_bytes_consumed += bytes_consumed;
-  }
-
-  return QuicConsumedData(total_bytes_consumed,
-                          fin && (total_bytes_consumed == write_length));
-}
-
-size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
-                                            size_t write_length,
-                                            QuicStreamOffset offset) {
-  QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoData " << level << " write_length "
-                << write_length << " offset " << offset;
-  QUIC_BUG_IF(quic_bug_10752_25, !flusher_attached_)
-      << ENDPOINT
-      << "Packet flusher is not attached when "
-         "generator tries to write crypto data.";
-  MaybeBundleAckOpportunistically();
-  // To make reasoning about crypto frames easier, we don't combine them with
-  // other retransmittable frames in a single packet.
-  // TODO(nharper): Once we have separate packet number spaces, everything
-  // should be driven by encryption level, and we should stop flushing in this
-  // spot.
-  if (HasPendingRetransmittableFrames()) {
-    FlushCurrentPacket();
-  }
-
-  size_t total_bytes_consumed = 0;
-
-  while (
-      total_bytes_consumed < write_length &&
-      delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
-    QuicFrame frame;
-    if (!ConsumeCryptoDataToFillCurrentPacket(
-            level, write_length - total_bytes_consumed,
-            offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
-            next_transmission_type_, &frame)) {
-      // The only pending data in the packet is non-retransmittable frames.
-      // I'm assuming here that they won't occupy so much of the packet that a
-      // CRYPTO frame won't fit.
-      QUIC_BUG_IF(quic_bug_10752_26, !HasSoftMaxPacketLength()) << absl::StrCat(
-          ENDPOINT, "Failed to ConsumeCryptoData at level ", level,
-          ", pending_frames: ", GetPendingFramesInfo(),
-          ", has_soft_max_packet_length: ", HasSoftMaxPacketLength(),
-          ", max_packet_length: ", max_packet_length_, ", transmission_type: ",
-          TransmissionTypeToString(next_transmission_type_),
-          ", packet_number: ", packet_number().ToString());
-      return 0;
-    }
-    total_bytes_consumed += frame.crypto_frame->data_length;
-    FlushCurrentPacket();
-  }
-
-  // Don't allow the handshake to be bundled with other retransmittable frames.
-  FlushCurrentPacket();
-
-  return total_bytes_consumed;
-}
-
-void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
-  // MTU discovery frames must be sent by themselves.
-  if (!CanSetMaxPacketLength()) {
-    QUIC_BUG(quic_bug_10752_27)
-        << ENDPOINT
-        << "MTU discovery packets should only be sent when no other "
-        << "frames needs to be sent.";
-    return;
-  }
-  const QuicByteCount current_mtu = max_packet_length();
-
-  // The MTU discovery frame is allocated on the stack, since it is going to be
-  // serialized within this function.
-  QuicMtuDiscoveryFrame mtu_discovery_frame;
-  QuicFrame frame(mtu_discovery_frame);
-
-  // Send the probe packet with the new length.
-  SetMaxPacketLength(target_mtu);
-  const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
-  FlushCurrentPacket();
-  // The only reason AddFrame can fail is that the packet is too full to fit in
-  // a ping.  This is not possible for any sane MTU.
-  QUIC_BUG_IF(quic_bug_10752_28, !success)
-      << ENDPOINT << "Failed to send path MTU target_mtu:" << target_mtu
-      << " transmission_type:" << next_transmission_type_;
-
-  // Reset the packet length back.
-  SetMaxPacketLength(current_mtu);
-}
-
-void QuicPacketCreator::MaybeBundleAckOpportunistically() {
-  if (has_ack()) {
-    // Ack already queued, nothing to do.
-    return;
-  }
-  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                       NOT_HANDSHAKE)) {
-    return;
-  }
-  const bool flushed =
-      FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
-  QUIC_BUG_IF(quic_bug_10752_29, !flushed)
-      << ENDPOINT << "Failed to flush ACK frame. encryption_level:"
-      << packet_.encryption_level;
-}
-
-bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
-  QUIC_BUG_IF(quic_bug_10752_30, !flusher_attached_)
-      << ENDPOINT
-      << "Packet flusher is not attached when "
-         "generator tries to send ACK frame.";
-  // MaybeBundleAckOpportunistically could be called nestedly when sending a
-  // control frame causing another control frame to be sent.
-  QUIC_BUG_IF(quic_bug_12398_18, !frames.empty() && has_ack())
-      << ENDPOINT << "Trying to flush " << quiche::PrintElements(frames)
-      << " when there is ACK queued";
-  for (const auto& frame : frames) {
-    QUICHE_DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME)
-        << ENDPOINT;
-    if (HasPendingFrames()) {
-      if (AddFrame(frame, next_transmission_type_)) {
-        // There is pending frames and current frame fits.
-        continue;
-      }
-    }
-    QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
-    // There is no pending frames, consult the delegate whether a packet can be
-    // generated.
-    if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                         NOT_HANDSHAKE)) {
-      return false;
-    }
-    const bool success = AddFrame(frame, next_transmission_type_);
-    QUIC_BUG_IF(quic_bug_10752_31, !success)
-        << ENDPOINT << "Failed to flush " << frame;
-  }
-  return true;
-}
-
-void QuicPacketCreator::AddRandomPadding() {
-  AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
-}
-
-void QuicPacketCreator::AttachPacketFlusher() {
-  flusher_attached_ = true;
-  if (!write_start_packet_number_.IsInitialized()) {
-    write_start_packet_number_ = NextSendingPacketNumber();
-  }
-}
-
-void QuicPacketCreator::Flush() {
-  FlushCurrentPacket();
-  SendRemainingPendingPadding();
-  flusher_attached_ = false;
-  if (GetQuicFlag(FLAGS_quic_export_write_path_stats_at_server)) {
-    if (!write_start_packet_number_.IsInitialized()) {
-      QUIC_BUG(quic_bug_10752_32)
-          << ENDPOINT << "write_start_packet_number is not initialized";
-      return;
-    }
-    QUIC_SERVER_HISTOGRAM_COUNTS(
-        "quic_server_num_written_packets_per_write",
-        NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
-        "Number of QUIC packets written per write operation");
-  }
-  write_start_packet_number_.Clear();
-}
-
-void QuicPacketCreator::SendRemainingPendingPadding() {
-  while (
-      pending_padding_bytes() > 0 && !HasPendingFrames() &&
-      delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
-    FlushCurrentPacket();
-  }
-}
-
-void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
-  if (length == 0) {
-    SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
-  } else {
-    SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
-  }
-}
-
-void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
-  next_transmission_type_ = type;
-}
-
-MessageStatus QuicPacketCreator::AddMessageFrame(
-    QuicMessageId message_id, absl::Span<quiche::QuicheMemSlice> message) {
-  QUIC_BUG_IF(quic_bug_10752_33, !flusher_attached_)
-      << ENDPOINT
-      << "Packet flusher is not attached when "
-         "generator tries to add message frame.";
-  MaybeBundleAckOpportunistically();
-  const QuicByteCount message_length = MemSliceSpanTotalSize(message);
-  if (message_length > GetCurrentLargestMessagePayload()) {
-    return MESSAGE_STATUS_TOO_LARGE;
-  }
-  if (!HasRoomForMessageFrame(message_length)) {
-    FlushCurrentPacket();
-  }
-  QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
-  const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
-  if (!success) {
-    QUIC_BUG(quic_bug_10752_34)
-        << ENDPOINT << "Failed to send message " << message_id;
-    delete frame;
-    return MESSAGE_STATUS_INTERNAL_ERROR;
-  }
-  QUICHE_DCHECK_EQ(MemSliceSpanTotalSize(message),
-                   0u);  // Ensure the old slices are empty.
-  return MESSAGE_STATUS_SUCCESS;
-}
-
-QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
-  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
-      HasIetfLongHeader()) {
-    QuicLongHeaderType long_header_type =
-        EncryptionlevelToLongHeaderType(packet_.encryption_level);
-    if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
-        long_header_type == HANDSHAKE) {
-      return VARIABLE_LENGTH_INTEGER_LENGTH_2;
-    }
-  }
-  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-}
-
-void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
-  header->destination_connection_id = GetDestinationConnectionId();
-  header->destination_connection_id_included =
-      GetDestinationConnectionIdIncluded();
-  header->source_connection_id = GetSourceConnectionId();
-  header->source_connection_id_included = GetSourceConnectionIdIncluded();
-  header->reset_flag = false;
-  header->version_flag = IncludeVersionInHeader();
-  if (IncludeNonceInPublicHeader()) {
-    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective())
-        << ENDPOINT;
-    header->nonce = &diversification_nonce_;
-  } else {
-    header->nonce = nullptr;
-  }
-  packet_.packet_number = NextSendingPacketNumber();
-  header->packet_number = packet_.packet_number;
-  header->packet_number_length = GetPacketNumberLength();
-  header->retry_token_length_length = GetRetryTokenLengthLength();
-  header->retry_token = GetRetryToken();
-  header->length_length = GetLengthLength();
-  header->remaining_packet_length = 0;
-  if (!HasIetfLongHeader()) {
-    return;
-  }
-  header->long_packet_type =
-      EncryptionlevelToLongHeaderType(packet_.encryption_level);
-}
-
-size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
-  size_t serialized_frame_length = framer_->GetSerializedFrameLength(
-      frame, BytesFree(), queued_frames_.empty(),
-      /* last_frame_in_packet= */ true, GetPacketNumberLength());
-  if (!framer_->version().HasHeaderProtection() ||
-      serialized_frame_length == 0) {
-    return serialized_frame_length;
-  }
-  // Calculate frame bytes and bytes free with this frame added.
-  const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
-                             ExpansionOnNewFrame() + serialized_frame_length;
-  if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
-    // No extra bytes is needed.
-    return serialized_frame_length;
-  }
-  if (BytesFree() < serialized_frame_length) {
-    QUIC_BUG(quic_bug_10752_35) << ENDPOINT << "Frame does not fit: " << frame;
-    return 0;
-  }
-  // Please note bytes_free does not take |frame|'s expansion into account.
-  size_t bytes_free = BytesFree() - serialized_frame_length;
-  // Extra bytes needed (this is NOT padding needed) should be at least 1
-  // padding + expansion.
-  const size_t extra_bytes_needed = std::max(
-      1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
-      MinPlaintextPacketSize(framer_->version()) - frame_bytes);
-  if (bytes_free < extra_bytes_needed) {
-    // This frame does not fit.
-    return 0;
-  }
-  return serialized_frame_length;
-}
-
-bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
-                                 TransmissionType transmission_type) {
-  QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
-                << transmission_type << ": " << frame;
-  if (frame.type == STREAM_FRAME &&
-      !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
-                                   frame.stream_frame.stream_id) &&
-      AttemptingToSendUnencryptedStreamData()) {
-    return false;
-  }
-
-  // Sanity check to ensure we don't send frames at the wrong encryption level.
-  QUICHE_DCHECK(
-      packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
-      packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
-      (frame.type != GOAWAY_FRAME && frame.type != WINDOW_UPDATE_FRAME &&
-       frame.type != HANDSHAKE_DONE_FRAME &&
-       frame.type != NEW_CONNECTION_ID_FRAME &&
-       frame.type != MAX_STREAMS_FRAME && frame.type != STREAMS_BLOCKED_FRAME &&
-       frame.type != PATH_RESPONSE_FRAME &&
-       frame.type != PATH_CHALLENGE_FRAME && frame.type != STOP_SENDING_FRAME &&
-       frame.type != MESSAGE_FRAME && frame.type != NEW_TOKEN_FRAME &&
-       frame.type != RETIRE_CONNECTION_ID_FRAME &&
-       frame.type != ACK_FREQUENCY_FRAME))
-      << ENDPOINT << frame.type << " not allowed at "
-      << packet_.encryption_level;
-
-  if (frame.type == STREAM_FRAME) {
-    if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
-      LogCoalesceStreamFrameStatus(true);
-      return true;
-    } else {
-      LogCoalesceStreamFrameStatus(false);
-    }
-  }
-
-  // If this is an ACK frame, validate that it is non-empty and that
-  // largest_acked matches the max packet number.
-  QUICHE_DCHECK(frame.type != ACK_FRAME || (!frame.ack_frame->packets.Empty() &&
-                                            frame.ack_frame->packets.Max() ==
-                                                frame.ack_frame->largest_acked))
-      << ENDPOINT << "Invalid ACK frame: " << frame;
-
-  size_t frame_len = GetSerializedFrameLength(frame);
-  if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
-    // Remove soft max_packet_length and retry.
-    frame_len = GetSerializedFrameLength(frame);
-  }
-  if (frame_len == 0) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Flushing because current open packet is full when adding "
-                  << frame;
-    FlushCurrentPacket();
-    return false;
-  }
-  if (queued_frames_.empty()) {
-    packet_size_ = PacketHeaderSize();
-  }
-  QUICHE_DCHECK_LT(0u, packet_size_) << ENDPOINT;
-
-  packet_size_ += ExpansionOnNewFrame() + frame_len;
-
-  if (QuicUtils::IsRetransmittableFrame(frame.type)) {
-    packet_.retransmittable_frames.push_back(frame);
-    queued_frames_.push_back(frame);
-    if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
-      packet_.has_crypto_handshake = IS_HANDSHAKE;
-    }
-  } else {
-    if (frame.type == PADDING_FRAME &&
-        frame.padding_frame.num_padding_bytes == -1) {
-      // Populate the actual length of full padding frame, such that one can
-      // know how much padding is actually added.
-      packet_.nonretransmittable_frames.push_back(
-          QuicFrame(QuicPaddingFrame(frame_len)));
-    } else {
-      packet_.nonretransmittable_frames.push_back(frame);
-    }
-    queued_frames_.push_back(frame);
-  }
-
-  if (frame.type == ACK_FRAME) {
-    packet_.has_ack = true;
-    packet_.largest_acked = LargestAcked(*frame.ack_frame);
-  } else if (frame.type == STOP_WAITING_FRAME) {
-    packet_.has_stop_waiting = true;
-  } else if (frame.type == ACK_FREQUENCY_FRAME) {
-    packet_.has_ack_frequency = true;
-  } else if (frame.type == MESSAGE_FRAME) {
-    packet_.has_message = true;
-  }
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnFrameAddedToPacket(frame);
-  }
-
-  // Packet transmission type is determined by the last added retransmittable
-  // frame.
-  if (QuicUtils::IsRetransmittableFrame(frame.type)) {
-    packet_.transmission_type = transmission_type;
-  }
-  return true;
-}
-
-void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
-  if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
-    return;
-  }
-  const size_t frame_bytes = PacketSize() - PacketHeaderSize();
-  if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
-    return;
-  }
-  const QuicByteCount min_header_protection_padding =
-      std::max(1 + ExpansionOnNewFrame(),
-               MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
-      ExpansionOnNewFrame();
-  // Update pending_padding_bytes_.
-  pending_padding_bytes_ =
-      std::max(pending_padding_bytes_, min_header_protection_padding);
-}
-
-bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
-  if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
-    return false;
-  }
-  QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
-  if (candidate->stream_id != frame.stream_id ||
-      candidate->offset + candidate->data_length != frame.offset ||
-      frame.data_length > BytesFree()) {
-    return false;
-  }
-  candidate->data_length += frame.data_length;
-  candidate->fin = frame.fin;
-
-  // The back of retransmittable frames must be the same as the original
-  // queued frames' back.
-  QUICHE_DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME)
-      << ENDPOINT;
-  QuicStreamFrame* retransmittable =
-      &packet_.retransmittable_frames.back().stream_frame;
-  QUICHE_DCHECK_EQ(retransmittable->stream_id, frame.stream_id) << ENDPOINT;
-  QUICHE_DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
-                   frame.offset)
-      << ENDPOINT;
-  retransmittable->data_length = candidate->data_length;
-  retransmittable->fin = candidate->fin;
-  packet_size_ += frame.data_length;
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnStreamFrameCoalesced(*candidate);
-  }
-  return true;
-}
-
-bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
-  if (latched_hard_max_packet_length_ == 0) {
-    return false;
-  }
-  if (!CanSetMaxPacketLength()) {
-    return false;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Restoring max packet length to: "
-                << latched_hard_max_packet_length_;
-  SetMaxPacketLength(latched_hard_max_packet_length_);
-  // Reset latched_max_packet_length_.
-  latched_hard_max_packet_length_ = 0;
-  return true;
-}
-
-void QuicPacketCreator::MaybeAddPadding() {
-  // The current packet should have no padding bytes because padding is only
-  // added when this method is called just before the packet is serialized.
-  if (BytesFree() == 0) {
-    // Don't pad full packets.
-    return;
-  }
-
-  if (packet_.transmission_type == PROBING_RETRANSMISSION) {
-    needs_full_padding_ = true;
-  }
-
-  if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
-    // Do not add full padding if the packet is going to be coalesced or
-    // encapsulated.
-    needs_full_padding_ = false;
-  }
-
-  // Header protection requires a minimum plaintext packet size.
-  MaybeAddExtraPaddingForHeaderProtection();
-
-  QUIC_DVLOG(3) << "MaybeAddPadding for " << packet_.packet_number
-                << ": transmission_type:" << packet_.transmission_type
-                << ", fate:" << packet_.fate
-                << ", needs_full_padding_:" << needs_full_padding_
-                << ", pending_padding_bytes_:" << pending_padding_bytes_
-                << ", BytesFree:" << BytesFree();
-
-  if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
-    // Do not need padding.
-    return;
-  }
-
-  int padding_bytes = -1;
-  if (!needs_full_padding_) {
-    padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
-    pending_padding_bytes_ -= padding_bytes;
-  }
-
-  bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
-                          packet_.transmission_type);
-  QUIC_BUG_IF(quic_bug_10752_36, !success)
-      << ENDPOINT << "Failed to add padding_bytes: " << padding_bytes
-      << " transmission_type: " << packet_.transmission_type;
-}
-
-bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
-  return have_diversification_nonce_ &&
-         packet_.encryption_level == ENCRYPTION_ZERO_RTT;
-}
-
-bool QuicPacketCreator::IncludeVersionInHeader() const {
-  if (version().HasIetfInvariantHeader()) {
-    return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
-  }
-  return send_version_in_packet_;
-}
-
-void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
-  pending_padding_bytes_ += size;
-  QUIC_DVLOG(3) << "After AddPendingPadding(" << size
-                << "), pending_padding_bytes_:" << pending_padding_bytes_;
-}
-
-bool QuicPacketCreator::StreamFrameIsClientHello(
-    const QuicStreamFrame& frame) const {
-  if (framer_->perspective() == Perspective::IS_SERVER ||
-      !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
-                                   frame.stream_id)) {
-    return false;
-  }
-  // The ClientHello is always sent with INITIAL encryption.
-  return packet_.encryption_level == ENCRYPTION_INITIAL;
-}
-
-void QuicPacketCreator::SetServerConnectionIdIncluded(
-    QuicConnectionIdIncluded server_connection_id_included) {
-  QUICHE_DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
-                server_connection_id_included == CONNECTION_ID_ABSENT)
-      << ENDPOINT;
-  QUICHE_DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
-                server_connection_id_included != CONNECTION_ID_ABSENT)
-      << ENDPOINT;
-  server_connection_id_included_ = server_connection_id_included;
-}
-
-void QuicPacketCreator::SetServerConnectionId(
-    QuicConnectionId server_connection_id) {
-  server_connection_id_ = server_connection_id;
-}
-
-void QuicPacketCreator::SetClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  QUICHE_DCHECK(client_connection_id.IsEmpty() ||
-                framer_->version().SupportsClientConnectionIds())
-      << ENDPOINT;
-  client_connection_id_ = client_connection_id;
-}
-
-QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
-  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
-    return 0;
-  }
-  const size_t packet_header_size = GetPacketHeaderSize(
-      framer_->transport_version(), GetDestinationConnectionIdLength(),
-      GetSourceConnectionIdLength(), IncludeVersionInHeader(),
-      IncludeNonceInPublicHeader(), GetPacketNumberLength(),
-      // No Retry token on packets containing application data.
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
-  // This is the largest possible message payload when the length field is
-  // omitted.
-  size_t max_plaintext_size =
-      latched_hard_max_packet_length_ == 0
-          ? max_plaintext_size_
-          : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
-  size_t largest_frame =
-      max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
-  if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
-    largest_frame = static_cast<size_t>(max_datagram_frame_size_);
-  }
-  return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
-}
-
-QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
-  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
-    return 0;
-  }
-  // QUIC Crypto server packets may include a diversification nonce.
-  const bool may_include_nonce =
-      framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
-      framer_->perspective() == Perspective::IS_SERVER;
-  // IETF QUIC long headers include a length on client 0RTT packets.
-  QuicVariableLengthIntegerLength length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  if (framer_->perspective() == Perspective::IS_CLIENT) {
-    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-  if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
-    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  }
-  const size_t packet_header_size = GetPacketHeaderSize(
-      framer_->transport_version(), GetDestinationConnectionIdLength(),
-      // Assume CID lengths don't change, but version may be present.
-      GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
-      PACKET_4BYTE_PACKET_NUMBER,
-      // No Retry token on packets containing application data.
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
-  // This is the largest possible message payload when the length field is
-  // omitted.
-  size_t max_plaintext_size =
-      latched_hard_max_packet_length_ == 0
-          ? max_plaintext_size_
-          : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
-  size_t largest_frame =
-      max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
-  if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
-    largest_frame = static_cast<size_t>(max_datagram_frame_size_);
-  }
-  const QuicPacketLength largest_payload =
-      largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
-  // This must always be less than or equal to GetCurrentLargestMessagePayload.
-  QUICHE_DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload())
-      << ENDPOINT;
-  return largest_payload;
-}
-
-bool QuicPacketCreator::AttemptingToSendUnencryptedStreamData() {
-  if (packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
-      packet_.encryption_level == ENCRYPTION_FORWARD_SECURE) {
-    return false;
-  }
-  const std::string error_details =
-      absl::StrCat("Cannot send stream data with level: ",
-                   EncryptionLevelToString(packet_.encryption_level));
-  QUIC_BUG(quic_bug_10752_37) << ENDPOINT << error_details;
-  delegate_->OnUnrecoverableError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA,
-                                  error_details);
-  return true;
-}
-
-bool QuicPacketCreator::HasIetfLongHeader() const {
-  return version().HasIetfInvariantHeader() &&
-         packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
-}
-
-// static
-size_t QuicPacketCreator::MinPlaintextPacketSize(
-    const ParsedQuicVersion& version) {
-  if (!version.HasHeaderProtection()) {
-    return 0;
-  }
-  // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
-  // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
-  // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
-  // numbers could be as small as 1 byte, but the sample starts 4 bytes after
-  // the packet number, at least 3 bytes of plaintext are needed to make sure
-  // that there is enough ciphertext to sample.
-  //
-  // Google QUIC crypto uses different AEAD algorithms - in particular the auth
-  // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
-  // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
-  // ciphertext to sample.
-  //
-  // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
-  // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
-  // determined based on the handshake protocol used). However, even when TLS
-  // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
-  // test crypters) which also only use 12 byte tags.
-  //
-  // TODO(nharper): Set this based on the handshake protocol in use.
-  return 7;
-}
-
-QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
-  if (!packet_number().IsInitialized()) {
-    return framer_->first_sending_packet_number();
-  }
-  return packet_number() + 1;
-}
-
-bool QuicPacketCreator::PacketFlusherAttached() const {
-  return flusher_attached_;
-}
-
-bool QuicPacketCreator::HasSoftMaxPacketLength() const {
-  return latched_hard_max_packet_length_ != 0;
-}
-
-void QuicPacketCreator::SetDefaultPeerAddress(QuicSocketAddress address) {
-  if (!packet_.peer_address.IsInitialized()) {
-    packet_.peer_address = address;
-    return;
-  }
-  if (packet_.peer_address != address) {
-    FlushCurrentPacket();
-    packet_.peer_address = address;
-  }
-}
-
-#define ENDPOINT2                                                          \
-  (creator_->framer_->perspective() == Perspective::IS_SERVER ? "Server: " \
-                                                              : "Client: ")
-
-QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
-    QuicPacketCreator* creator,
-    QuicSocketAddress address,
-    bool update_connection_id)
-    : ScopedPeerAddressContext(creator,
-                               address,
-                               EmptyQuicConnectionId(),
-                               EmptyQuicConnectionId(),
-                               update_connection_id) {}
-
-QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
-    QuicPacketCreator* creator,
-    QuicSocketAddress address,
-    const QuicConnectionId& client_connection_id,
-    const QuicConnectionId& server_connection_id,
-    bool update_connection_id)
-    : creator_(creator),
-      old_peer_address_(creator_->packet_.peer_address),
-      old_client_connection_id_(creator_->GetClientConnectionId()),
-      old_server_connection_id_(creator_->GetServerConnectionId()),
-      update_connection_id_(update_connection_id) {
-  QUIC_BUG_IF(quic_bug_12398_19, !old_peer_address_.IsInitialized())
-      << ENDPOINT2
-      << "Context is used before serialized packet's peer address is "
-         "initialized.";
-  creator_->SetDefaultPeerAddress(address);
-  if (update_connection_id_) {
-    // Flush current packet if connection ID length changes.
-    if (address == old_peer_address_ &&
-        ((client_connection_id.length() !=
-          old_client_connection_id_.length()) ||
-         (server_connection_id.length() !=
-          old_server_connection_id_.length()))) {
-      creator_->FlushCurrentPacket();
-    }
-    creator_->SetClientConnectionId(client_connection_id);
-    creator_->SetServerConnectionId(server_connection_id);
-  }
-}
-
-QuicPacketCreator::ScopedPeerAddressContext::~ScopedPeerAddressContext() {
-  creator_->SetDefaultPeerAddress(old_peer_address_);
-  if (update_connection_id_) {
-    creator_->SetClientConnectionId(old_client_connection_id_);
-    creator_->SetServerConnectionId(old_server_connection_id_);
-  }
-}
-
-QuicPacketCreator::ScopedSerializationFailureHandler::
-    ScopedSerializationFailureHandler(QuicPacketCreator* creator)
-    : creator_(creator) {}
-
-QuicPacketCreator::ScopedSerializationFailureHandler::
-    ~ScopedSerializationFailureHandler() {
-  if (creator_ == nullptr) {
-    return;
-  }
-  // Always clear queued_frames_.
-  creator_->queued_frames_.clear();
-
-  if (creator_->packet_.encrypted_buffer == nullptr) {
-    const std::string error_details = "Failed to SerializePacket.";
-    QUIC_BUG(quic_bug_10752_38) << ENDPOINT2 << error_details;
-    creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
-                                              error_details);
-  }
-}
-
-#undef ENDPOINT2
-
-void QuicPacketCreator::set_encryption_level(EncryptionLevel level) {
-  QUICHE_DCHECK(level == packet_.encryption_level || !HasPendingFrames())
-      << ENDPOINT << "Cannot update encryption level from "
-      << packet_.encryption_level << " to " << level
-      << " when we already have pending frames: "
-      << QuicFramesToString(queued_frames_);
-  packet_.encryption_level = level;
-}
-
-void QuicPacketCreator::AddPathChallengeFrame(
-    const QuicPathFrameBuffer& payload) {
-  // TODO(danzh) Unify similar checks at several entry points into one in
-  // AddFrame(). Sort out test helper functions and peer class that don't
-  // enforce this check.
-  QUIC_BUG_IF(quic_bug_10752_39, !flusher_attached_)
-      << ENDPOINT
-      << "Packet flusher is not attached when "
-         "generator tries to write stream data.";
-  // Write a PATH_CHALLENGE frame, which has a random 8-byte payload.
-  auto path_challenge_frame = new QuicPathChallengeFrame(0, payload);
-  QuicFrame frame(path_challenge_frame);
-  if (AddPaddedFrameWithRetry(frame)) {
-    return;
-  }
-  // Fail silently if the probing packet cannot be written, path validation
-  // initiator will retry sending automatically.
-  // TODO(danzh) This will consume retry budget, if it causes performance
-  // regression, consider to notify the caller about the sending failure and let
-  // the caller to decide if it worth retrying.
-  QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now";
-  delete path_challenge_frame;
-}
-
-bool QuicPacketCreator::AddPathResponseFrame(
-    const QuicPathFrameBuffer& data_buffer) {
-  auto path_response =
-      new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
-  QuicFrame frame(path_response);
-  if (AddPaddedFrameWithRetry(frame)) {
-    return true;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
-  delete path_response;
-  return false;
-}
-
-bool QuicPacketCreator::AddPaddedFrameWithRetry(const QuicFrame& frame) {
-  if (HasPendingFrames()) {
-    if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) {
-      // Frame is queued.
-      return true;
-    }
-  }
-  // Frame was not queued but queued frames were flushed.
-  QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
-  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                       NOT_HANDSHAKE)) {
-    return false;
-  }
-  bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION);
-  QUIC_BUG_IF(quic_bug_12398_20, !success) << ENDPOINT;
-  return true;
-}
-
-bool QuicPacketCreator::HasRetryToken() const {
-  return !retry_token_.empty();
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h
deleted file mode 100644
index 183bf2b..0000000
--- a/quic/core/quic_packet_creator.h
+++ /dev/null
@@ -1,732 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Responsible for creating packets on behalf of a QuicConnection.
-// Packets are serialized just-in-time. Stream data and control frames will be
-// requested from the Connection just-in-time. Frames are accumulated into
-// "current" packet until no more frames can fit, then current packet gets
-// serialized and passed to connection via OnSerializedPacket().
-//
-// Whether a packet should be serialized is determined by whether delegate is
-// writable. If the Delegate is not writable, then no operations will cause
-// a packet to be serialized.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
-
-#include <cstddef>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_coalesced_packet.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace test {
-class QuicPacketCreatorPeer;
-}
-
-class QUIC_EXPORT_PRIVATE QuicPacketCreator {
- public:
-  // A delegate interface for further processing serialized packet.
-  class QUIC_EXPORT_PRIVATE DelegateInterface {
-   public:
-    virtual ~DelegateInterface() {}
-    // Get a buffer of kMaxOutgoingPacketSize bytes to serialize the next
-    // packet. If the return value's buffer is nullptr, QuicPacketCreator will
-    // serialize on a stack buffer.
-    virtual QuicPacketBuffer GetPacketBuffer() = 0;
-    // Called when a packet is serialized. Delegate take the ownership of
-    // |serialized_packet|.
-    virtual void OnSerializedPacket(SerializedPacket serialized_packet) = 0;
-
-    // Called when an unrecoverable error is encountered.
-    virtual void OnUnrecoverableError(QuicErrorCode error,
-                                      const std::string& error_details) = 0;
-
-    // Consults delegate whether a packet should be generated.
-    virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
-                                      IsHandshake handshake) = 0;
-    // Called when there is data to be sent. Retrieves updated ACK frame from
-    // the delegate.
-    virtual const QuicFrames MaybeBundleAckOpportunistically() = 0;
-
-    // Returns the packet fate for serialized packets which will be handed over
-    // to delegate via OnSerializedPacket(). Called when a packet is about to be
-    // serialized.
-    virtual SerializedPacketFate GetSerializedPacketFate(
-        bool is_mtu_discovery,
-        EncryptionLevel encryption_level) = 0;
-  };
-
-  // Interface which gets callbacks from the QuicPacketCreator at interesting
-  // points.  Implementations must not mutate the state of the creator
-  // as a result of these callbacks.
-  class QUIC_EXPORT_PRIVATE DebugDelegate {
-   public:
-    virtual ~DebugDelegate() {}
-
-    // Called when a frame has been added to the current packet.
-    virtual void OnFrameAddedToPacket(const QuicFrame& /*frame*/) {}
-
-    // Called when a stream frame is coalesced with an existing stream frame.
-    // |frame| is the new stream frame.
-    virtual void OnStreamFrameCoalesced(const QuicStreamFrame& /*frame*/) {}
-  };
-
-  // Set the peer address and connection IDs with which the serialized packet
-  // will be sent to during the scope of this object. Upon exiting the scope,
-  // the original peer address and connection IDs are restored.
-  class QUIC_EXPORT_PRIVATE ScopedPeerAddressContext {
-   public:
-    ScopedPeerAddressContext(QuicPacketCreator* creator,
-                             QuicSocketAddress address,
-                             bool update_connection_id);
-
-    ScopedPeerAddressContext(QuicPacketCreator* creator,
-                             QuicSocketAddress address,
-                             const QuicConnectionId& client_connection_id,
-                             const QuicConnectionId& server_connection_id,
-                             bool update_connection_id);
-    ~ScopedPeerAddressContext();
-
-   private:
-    QuicPacketCreator* creator_;
-    QuicSocketAddress old_peer_address_;
-    QuicConnectionId old_client_connection_id_;
-    QuicConnectionId old_server_connection_id_;
-    bool update_connection_id_;
-  };
-
-  QuicPacketCreator(QuicConnectionId server_connection_id,
-                    QuicFramer* framer,
-                    DelegateInterface* delegate);
-  QuicPacketCreator(QuicConnectionId server_connection_id,
-                    QuicFramer* framer,
-                    QuicRandom* random,
-                    DelegateInterface* delegate);
-  QuicPacketCreator(const QuicPacketCreator&) = delete;
-  QuicPacketCreator& operator=(const QuicPacketCreator&) = delete;
-
-  ~QuicPacketCreator();
-
-  // Makes the framer not serialize the protocol version in sent packets.
-  void StopSendingVersion();
-
-  // SetDiversificationNonce sets the nonce that will be sent in each public
-  // header of packets encrypted at the initial encryption level. Should only
-  // be called by servers.
-  void SetDiversificationNonce(const DiversificationNonce& nonce);
-
-  // Update the packet number length to use in future packets as soon as it
-  // can be safely changed.
-  // TODO(fayang): Directly set packet number length instead of compute it in
-  // creator.
-  void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
-                                QuicPacketCount max_packets_in_flight);
-
-  // Skip |count| packet numbers.
-  void SkipNPacketNumbers(QuicPacketCount count,
-                          QuicPacketNumber least_packet_awaited_by_peer,
-                          QuicPacketCount max_packets_in_flight);
-
-  // The overhead the framing will add for a packet with one frame.
-  static size_t StreamFramePacketOverhead(
-      QuicTransportVersion version,
-      QuicConnectionIdLength destination_connection_id_length,
-      QuicConnectionIdLength source_connection_id_length,
-      bool include_version,
-      bool include_diversification_nonce,
-      QuicPacketNumberLength packet_number_length,
-      QuicVariableLengthIntegerLength retry_token_length_length,
-      QuicVariableLengthIntegerLength length_length,
-      QuicStreamOffset offset);
-
-  // Returns false and flushes all pending frames if current open packet is
-  // full.
-  // If current packet is not full, creates a stream frame that fits into the
-  // open packet and adds it to the packet.
-  bool ConsumeDataToFillCurrentPacket(QuicStreamId id,
-                                      size_t data_size,
-                                      QuicStreamOffset offset,
-                                      bool fin,
-                                      bool needs_full_padding,
-                                      TransmissionType transmission_type,
-                                      QuicFrame* frame);
-
-  // Creates a CRYPTO frame that fits into the current packet (which must be
-  // empty) and adds it to the packet.
-  bool ConsumeCryptoDataToFillCurrentPacket(EncryptionLevel level,
-                                            size_t write_length,
-                                            QuicStreamOffset offset,
-                                            bool needs_full_padding,
-                                            TransmissionType transmission_type,
-                                            QuicFrame* frame);
-
-  // Returns true if current open packet can accommodate more stream frames of
-  // stream |id| at |offset| and data length |data_size|, false otherwise.
-  // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
-  bool HasRoomForStreamFrame(QuicStreamId id,
-                             QuicStreamOffset offset,
-                             size_t data_size);
-
-  // Returns true if current open packet can accommodate a message frame of
-  // |length|.
-  // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
-  bool HasRoomForMessageFrame(QuicByteCount length);
-
-  // Serializes all added frames into a single packet and invokes the delegate_
-  // to further process the SerializedPacket.
-  void FlushCurrentPacket();
-
-  // Optimized method to create a QuicStreamFrame and serialize it. Adds the
-  // QuicStreamFrame to the returned SerializedPacket.  Sets
-  // |num_bytes_consumed| to the number of bytes consumed to create the
-  // QuicStreamFrame.
-  void CreateAndSerializeStreamFrame(QuicStreamId id,
-                                     size_t write_length,
-                                     QuicStreamOffset iov_offset,
-                                     QuicStreamOffset stream_offset,
-                                     bool fin,
-                                     TransmissionType transmission_type,
-                                     size_t* num_bytes_consumed);
-
-  // Returns true if there are frames pending to be serialized.
-  bool HasPendingFrames() const;
-
-  // TODO(haoyuewang) Remove this debug utility.
-  // Returns the information of pending frames as a string.
-  std::string GetPendingFramesInfo() const;
-
-  // Returns true if there are retransmittable frames pending to be serialized.
-  bool HasPendingRetransmittableFrames() const;
-
-  // Returns true if there are stream frames for |id| pending to be serialized.
-  bool HasPendingStreamFramesOfStream(QuicStreamId id) const;
-
-  // Returns the number of bytes which are available to be used by additional
-  // frames in the packet.  Since stream frames are slightly smaller when they
-  // are the last frame in a packet, this method will return a different
-  // value than max_packet_size - PacketSize(), in this case.
-  size_t BytesFree() const;
-
-  // Returns the number of bytes that the packet will expand by if a new frame
-  // is added to the packet. If the last frame was a stream frame, it will
-  // expand slightly when a new frame is added, and this method returns the
-  // amount of expected expansion.
-  size_t ExpansionOnNewFrame() const;
-
-  // Returns the number of bytes that the packet will expand by when a new frame
-  // is going to be added. |last_frame| is the last frame of the packet.
-  static size_t ExpansionOnNewFrameWithLastFrame(const QuicFrame& last_frame,
-                                                 QuicTransportVersion version);
-
-  // Returns the number of bytes in the current packet, including the header,
-  // if serialized with the current frames.  Adding a frame to the packet
-  // may change the serialized length of existing frames, as per the comment
-  // in BytesFree.
-  size_t PacketSize() const;
-
-  // Tries to add |frame| to the packet creator's list of frames to be
-  // serialized. If the frame does not fit into the current packet, flushes the
-  // packet and returns false.
-  bool AddFrame(const QuicFrame& frame, TransmissionType transmission_type);
-
-  // Identical to AddSavedFrame, but allows the frame to be padded.
-  bool AddPaddedSavedFrame(const QuicFrame& frame,
-                           TransmissionType transmission_type);
-
-  // Creates a connectivity probing packet for versions prior to version 99.
-  std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket();
-
-  // Create connectivity probing request and response packets using PATH
-  // CHALLENGE and PATH RESPONSE frames, respectively, for version 99/IETF QUIC.
-  // SerializePathChallengeConnectivityProbingPacket will pad the packet to be
-  // MTU bytes long.
-  std::unique_ptr<SerializedPacket>
-  SerializePathChallengeConnectivityProbingPacket(
-      const QuicPathFrameBuffer& payload);
-
-  // If |is_padded| is true then SerializePathResponseConnectivityProbingPacket
-  // will pad the packet to be MTU bytes long, else it will not pad the packet.
-  // |payloads| is cleared.
-  std::unique_ptr<SerializedPacket>
-  SerializePathResponseConnectivityProbingPacket(
-      const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
-      const bool is_padded);
-
-  // Add PATH_RESPONSE to current packet, flush before or afterwards if needed.
-  bool AddPathResponseFrame(const QuicPathFrameBuffer& data_buffer);
-
-  // Add PATH_CHALLENGE to current packet, flush before or afterwards if needed.
-  // This is a best effort adding. It may fail becasue of delegate state, but
-  // it's okay because of path validation retry mechanism.
-  void AddPathChallengeFrame(const QuicPathFrameBuffer& payload);
-
-  // Returns a dummy packet that is valid but contains no useful information.
-  static SerializedPacket NoPacket();
-
-  // Returns the server connection ID to send over the wire.
-  const QuicConnectionId& GetServerConnectionId() const {
-    return server_connection_id_;
-  }
-
-  // Returns the client connection ID to send over the wire.
-  const QuicConnectionId& GetClientConnectionId() const {
-    return client_connection_id_;
-  }
-
-  // Returns the destination connection ID to send over the wire.
-  QuicConnectionId GetDestinationConnectionId() const;
-
-  // Returns the source connection ID to send over the wire.
-  QuicConnectionId GetSourceConnectionId() const;
-
-  // Returns length of destination connection ID to send over the wire.
-  QuicConnectionIdLength GetDestinationConnectionIdLength() const;
-
-  // Returns length of source connection ID to send over the wire.
-  QuicConnectionIdLength GetSourceConnectionIdLength() const;
-
-  // Sets whether the server connection ID should be sent over the wire.
-  void SetServerConnectionIdIncluded(
-      QuicConnectionIdIncluded server_connection_id_included);
-
-  // Update the server connection ID used in outgoing packets.
-  void SetServerConnectionId(QuicConnectionId server_connection_id);
-
-  // Update the client connection ID used in outgoing packets.
-  void SetClientConnectionId(QuicConnectionId client_connection_id);
-
-  // Sets the encryption level that will be applied to new packets.
-  void set_encryption_level(EncryptionLevel level);
-  EncryptionLevel encryption_level() { return packet_.encryption_level; }
-
-  // Sets whether initial packets are protected with chaos.
-  void set_chaos_protection_enabled(bool chaos_protection_enabled) {
-    chaos_protection_enabled_ = chaos_protection_enabled;
-  }
-
-  // packet number of the last created packet, or 0 if no packets have been
-  // created.
-  QuicPacketNumber packet_number() const { return packet_.packet_number; }
-
-  QuicByteCount max_packet_length() const { return max_packet_length_; }
-
-  bool has_ack() const { return packet_.has_ack; }
-
-  bool has_stop_waiting() const { return packet_.has_stop_waiting; }
-
-  // Sets the encrypter to use for the encryption level and updates the max
-  // plaintext size.
-  void SetEncrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicEncrypter> encrypter);
-
-  // Indicates whether the packet creator is in a state where it can change
-  // current maximum packet length.
-  bool CanSetMaxPacketLength() const;
-
-  // Sets the maximum packet length.
-  void SetMaxPacketLength(QuicByteCount length);
-
-  // Sets the maximum DATAGRAM/MESSAGE frame size we can send.
-  void SetMaxDatagramFrameSize(QuicByteCount max_datagram_frame_size);
-
-  // Set a soft maximum packet length in the creator. If a packet cannot be
-  // successfully created, creator will remove the soft limit and use the actual
-  // max packet length.
-  void SetSoftMaxPacketLength(QuicByteCount length);
-
-  // Increases pending_padding_bytes by |size|. Pending padding will be sent by
-  // MaybeAddPadding().
-  void AddPendingPadding(QuicByteCount size);
-
-  // Sets the retry token to be sent over the wire in IETF Initial packets.
-  void SetRetryToken(absl::string_view retry_token);
-
-  // Consumes retransmittable control |frame|. Returns true if the frame is
-  // successfully consumed. Returns false otherwise.
-  bool ConsumeRetransmittableControlFrame(const QuicFrame& frame);
-
-  // Given some data, may consume part or all of it and pass it to the
-  // packet creator to be serialized into packets. If not in batch
-  // mode, these packets will also be sent during this call.
-  // When |state| is FIN_AND_PADDING, random padding of size [1, 256] will be
-  // added after stream frames. If current constructed packet cannot
-  // accommodate, the padding will overflow to the next packet(s).
-  QuicConsumedData ConsumeData(QuicStreamId id,
-                               size_t write_length,
-                               QuicStreamOffset offset,
-                               StreamSendingState state);
-
-  // Sends as many data only packets as allowed by the send algorithm and the
-  // available iov.
-  // This path does not support padding, or bundling pending frames.
-  // In case we access this method from ConsumeData, total_bytes_consumed
-  // keeps track of how many bytes have already been consumed.
-  QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
-                                       size_t write_length,
-                                       QuicStreamOffset offset,
-                                       bool fin,
-                                       size_t total_bytes_consumed);
-
-  // Consumes data for CRYPTO frames sent at |level| starting at |offset| for a
-  // total of |write_length| bytes, and returns the number of bytes consumed.
-  // The data is passed into the packet creator and serialized into one or more
-  // packets.
-  size_t ConsumeCryptoData(EncryptionLevel level,
-                           size_t write_length,
-                           QuicStreamOffset offset);
-
-  // Generates an MTU discovery packet of specified size.
-  void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);
-
-  // Called when there is data to be sent, Retrieves updated ACK frame from
-  // delegate_ and flushes it.
-  void MaybeBundleAckOpportunistically();
-
-  // Called to flush ACK and STOP_WAITING frames, returns false if the flush
-  // fails.
-  bool FlushAckFrame(const QuicFrames& frames);
-
-  // Adds a random amount of padding (between 1 to 256 bytes).
-  void AddRandomPadding();
-
-  // Attaches packet flusher.
-  void AttachPacketFlusher();
-
-  // Flushes everything, including current open packet and pending padding.
-  void Flush();
-
-  // Sends remaining pending padding.
-  // Pending paddings should only be sent when there is nothing else to send.
-  void SendRemainingPendingPadding();
-
-  // Set the minimum number of bytes for the server connection id length;
-  void SetServerConnectionIdLength(uint32_t length);
-
-  // Set transmission type of next constructed packets.
-  void SetTransmissionType(TransmissionType type);
-
-  // Tries to add a message frame containing |message| and returns the status.
-  MessageStatus AddMessageFrame(QuicMessageId message_id,
-                                absl::Span<quiche::QuicheMemSlice> message);
-
-  // Returns the largest payload that will fit into a single MESSAGE frame.
-  QuicPacketLength GetCurrentLargestMessagePayload() const;
-  // Returns the largest payload that will fit into a single MESSAGE frame at
-  // any point during the connection.  This assumes the version and
-  // connection ID lengths do not change.
-  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
-  // Packet number of next created packet.
-  QuicPacketNumber NextSendingPacketNumber() const;
-
-  void set_debug_delegate(DebugDelegate* debug_delegate) {
-    debug_delegate_ = debug_delegate;
-  }
-
-  QuicByteCount pending_padding_bytes() const { return pending_padding_bytes_; }
-
-  ParsedQuicVersion version() const { return framer_->version(); }
-
-  QuicTransportVersion transport_version() const {
-    return framer_->transport_version();
-  }
-
-  // Returns the minimum size that the plaintext of a packet must be.
-  static size_t MinPlaintextPacketSize(const ParsedQuicVersion& version);
-
-  // Indicates whether packet flusher is currently attached.
-  bool PacketFlusherAttached() const;
-
-  void set_fully_pad_crypto_handshake_packets(bool new_value) {
-    fully_pad_crypto_handshake_packets_ = new_value;
-  }
-
-  bool fully_pad_crypto_handshake_packets() const {
-    return fully_pad_crypto_handshake_packets_;
-  }
-
-  // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also
-  // fills the packet with padding.
-  size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header,
-                                        char* buffer,
-                                        size_t packet_length,
-                                        const QuicPathFrameBuffer& payload,
-                                        EncryptionLevel level);
-
-  // Serialize a probing response packet that uses IETF QUIC's PATH RESPONSE
-  // frame. Also fills the packet with padding if |is_padded| is
-  // true. |payloads| is always emptied, even if the packet can not be
-  // successfully built.
-  size_t BuildPathResponsePacket(
-      const QuicPacketHeader& header,
-      char* buffer,
-      size_t packet_length,
-      const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
-      const bool is_padded,
-      EncryptionLevel level);
-
-  // Serializes a probing packet, which is a padded PING packet. Returns the
-  // length of the packet. Returns 0 if it fails to serialize.
-  size_t BuildConnectivityProbingPacket(const QuicPacketHeader& header,
-                                        char* buffer,
-                                        size_t packet_length,
-                                        EncryptionLevel level);
-
-  // Serializes |coalesced| to provided |buffer|, returns coalesced packet
-  // length if serialization succeeds. Otherwise, returns 0.
-  size_t SerializeCoalescedPacket(const QuicCoalescedPacket& coalesced,
-                                  char* buffer,
-                                  size_t buffer_len);
-
-  // Returns true if max_packet_length_ is currently a soft value.
-  bool HasSoftMaxPacketLength() const;
-
-  // Use this address to sent to the peer from now on. If this address is
-  // different from the current one, flush all the queue frames first.
-  void SetDefaultPeerAddress(QuicSocketAddress address);
-
-  // Return true if retry_token_ is not empty.
-  bool HasRetryToken() const;
-
-  const QuicSocketAddress& peer_address() const { return packet_.peer_address; }
-
-  bool close_connection_if_fail_to_serialzie_coalesced_packet() const {
-    return close_connection_if_fail_to_serialzie_coalesced_packet_;
-  }
-
- private:
-  friend class test::QuicPacketCreatorPeer;
-
-  // Used to 1) clear queued_frames_, 2) report unrecoverable error (if
-  // serialization fails) upon exiting the scope.
-  class QUIC_EXPORT_PRIVATE ScopedSerializationFailureHandler {
-   public:
-    explicit ScopedSerializationFailureHandler(QuicPacketCreator* creator);
-    ~ScopedSerializationFailureHandler();
-
-   private:
-    QuicPacketCreator* creator_;  // Unowned.
-  };
-
-  // Attempts to build a data packet with chaos protection. If this packet isn't
-  // supposed to be protected or if serialization fails then absl::nullopt is
-  // returned. Otherwise returns the serialized length.
-  absl::optional<size_t> MaybeBuildDataPacketWithChaosProtection(
-      const QuicPacketHeader& header,
-      char* buffer);
-
-  // Creates a stream frame which fits into the current open packet. If
-  // |data_size| is 0 and fin is true, the expected behavior is to consume
-  // the fin.
-  void CreateStreamFrame(QuicStreamId id,
-                         size_t data_size,
-                         QuicStreamOffset offset,
-                         bool fin,
-                         QuicFrame* frame);
-
-  // Creates a CRYPTO frame which fits into the current open packet. Returns
-  // false if there isn't enough room in the current open packet for a CRYPTO
-  // frame, and true if there is.
-  bool CreateCryptoFrame(EncryptionLevel level,
-                         size_t write_length,
-                         QuicStreamOffset offset,
-                         QuicFrame* frame);
-
-  void FillPacketHeader(QuicPacketHeader* header);
-
-  // Adds a padding frame to the current packet (if there is space) when (1)
-  // current packet needs full padding or (2) there are pending paddings.
-  void MaybeAddPadding();
-
-  // Serializes all frames which have been added and adds any which should be
-  // retransmitted to packet_.retransmittable_frames. All frames must fit into
-  // a single packet. Returns true on success, otherwise, returns false.
-  // Fails if |encrypted_buffer| is not large enough for the encrypted packet.
-  //
-  // Padding may be added if |allow_padding|. Currently, the only case where it
-  // is disallowed is reserializing a coalesced initial packet.
-  ABSL_MUST_USE_RESULT bool SerializePacket(
-      QuicOwnedPacketBuffer encrypted_buffer, size_t encrypted_buffer_len,
-      bool allow_padding);
-
-  // Called after a new SerialiedPacket is created to call the delegate's
-  // OnSerializedPacket and reset state.
-  void OnSerializedPacket();
-
-  // Clears all fields of packet_ that should be cleared between serializations.
-  void ClearPacket();
-
-  // Re-serialzes frames of ENCRYPTION_INITIAL packet in coalesced packet with
-  // the original packet's packet number and packet number length.
-  // |padding_size| indicates the size of necessary padding. Returns 0 if
-  // serialization fails.
-  size_t ReserializeInitialPacketInCoalescedPacket(
-      const SerializedPacket& packet,
-      size_t padding_size,
-      char* buffer,
-      size_t buffer_len);
-
-  // Tries to coalesce |frame| with the back of |queued_frames_|.
-  // Returns true on success.
-  bool MaybeCoalesceStreamFrame(const QuicStreamFrame& frame);
-
-  // Called to remove the soft max_packet_length and restores
-  // latched_hard_max_packet_length_ if the packet cannot accommodate a single
-  // frame. Returns true if the soft limit is successfully removed. Returns
-  // false if either there is no current soft limit or there are queued frames
-  // (such that the packet length cannot be changed).
-  bool RemoveSoftMaxPacketLength();
-
-  // Returns true if a diversification nonce should be included in the current
-  // packet's header.
-  bool IncludeNonceInPublicHeader() const;
-
-  // Returns true if version should be included in current packet's header.
-  bool IncludeVersionInHeader() const;
-
-  // Returns length of packet number to send over the wire.
-  // packet_.packet_number_length should never be read directly, use this
-  // function instead.
-  QuicPacketNumberLength GetPacketNumberLength() const;
-
-  // Returns the size in bytes of the packet header.
-  size_t PacketHeaderSize() const;
-
-  // Returns whether the destination connection ID is sent over the wire.
-  QuicConnectionIdIncluded GetDestinationConnectionIdIncluded() const;
-
-  // Returns whether the source connection ID is sent over the wire.
-  QuicConnectionIdIncluded GetSourceConnectionIdIncluded() const;
-
-  // Returns length of the retry token variable length integer to send over the
-  // wire. Is non-zero for v99 IETF Initial packets.
-  QuicVariableLengthIntegerLength GetRetryTokenLengthLength() const;
-
-  // Returns the retry token to send over the wire, only sent in
-  // v99 IETF Initial packets.
-  absl::string_view GetRetryToken() const;
-
-  // Returns length of the length variable length integer to send over the
-  // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets.
-  QuicVariableLengthIntegerLength GetLengthLength() const;
-
-  // Returns true if |frame| is a ClientHello.
-  bool StreamFrameIsClientHello(const QuicStreamFrame& frame) const;
-
-  // Returns true if packet under construction has IETF long header.
-  bool HasIetfLongHeader() const;
-
-  // Get serialized frame length. Returns 0 if the frame does not fit into
-  // current packet.
-  size_t GetSerializedFrameLength(const QuicFrame& frame);
-
-  // Add extra padding to pending_padding_bytes_ to meet minimum plaintext
-  // packet size required for header protection.
-  void MaybeAddExtraPaddingForHeaderProtection();
-
-  // Returns true and close connection if it attempts to send unencrypted data.
-  bool AttemptingToSendUnencryptedStreamData();
-
-  // Add the given frame to the current packet with full padding. If the current
-  // packet doesn't have enough space, flush once and try again. Return false if
-  // fail to add.
-  bool AddPaddedFrameWithRetry(const QuicFrame& frame);
-
-  // Does not own these delegates or the framer.
-  DelegateInterface* delegate_;
-  DebugDelegate* debug_delegate_;
-  QuicFramer* framer_;
-  QuicRandom* random_;
-
-  // Controls whether version should be included while serializing the packet.
-  // send_version_in_packet_ should never be read directly, use
-  // IncludeVersionInHeader() instead.
-  bool send_version_in_packet_;
-  // If true, then |diversification_nonce_| will be included in the header of
-  // all packets created at the initial encryption level.
-  bool have_diversification_nonce_;
-  DiversificationNonce diversification_nonce_;
-  // Maximum length including headers and encryption (UDP payload length.)
-  QuicByteCount max_packet_length_;
-  size_t max_plaintext_size_;
-  // Whether the server_connection_id is sent over the wire.
-  QuicConnectionIdIncluded server_connection_id_included_;
-
-  // Frames to be added to the next SerializedPacket
-  QuicFrames queued_frames_;
-
-  // Serialization size of header + frames. If there is no queued frames,
-  // packet_size_ is 0.
-  // TODO(ianswett): Move packet_size_ into SerializedPacket once
-  // QuicEncryptedPacket has been flattened into SerializedPacket.
-  size_t packet_size_;
-  QuicConnectionId server_connection_id_;
-  QuicConnectionId client_connection_id_;
-
-  // Packet used to invoke OnSerializedPacket.
-  SerializedPacket packet_;
-
-  // Retry token to send over the wire in v99 IETF Initial packets.
-  std::string retry_token_;
-
-  // Pending padding bytes to send. Pending padding bytes will be sent in next
-  // packet(s) (after all other frames) if current constructed packet does not
-  // have room to send all of them.
-  QuicByteCount pending_padding_bytes_;
-
-  // Indicates whether current constructed packet needs full padding to max
-  // packet size. Please note, full padding does not consume pending padding
-  // bytes.
-  bool needs_full_padding_;
-
-  // Transmission type of the next serialized packet.
-  TransmissionType next_transmission_type_;
-
-  // True if packet flusher is currently attached.
-  bool flusher_attached_;
-
-  // Whether crypto handshake packets should be fully padded.
-  bool fully_pad_crypto_handshake_packets_;
-
-  // Packet number of the first packet of a write operation. This gets set
-  // when the out-most flusher attaches and gets cleared when the out-most
-  // flusher detaches.
-  QuicPacketNumber write_start_packet_number_;
-
-  // If not 0, this latches the actual max_packet_length when
-  // SetSoftMaxPacketLength is called and max_packet_length_ gets
-  // set to a soft value.
-  QuicByteCount latched_hard_max_packet_length_;
-
-  // The maximum length of a MESSAGE/DATAGRAM frame that our peer is willing to
-  // accept. There is no limit for QUIC_CRYPTO connections, but QUIC+TLS
-  // negotiates this during the handshake.
-  QuicByteCount max_datagram_frame_size_;
-
-  // Whether to attempt protecting initial packets with chaos.
-  bool chaos_protection_enabled_;
-
-  const bool close_connection_if_fail_to_serialzie_coalesced_packet_ =
-      GetQuicReloadableFlag(
-          quic_close_connection_if_fail_to_serialzie_coalesced_packet2);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
deleted file mode 100644
index f038e33..0000000
--- a/quic/core/quic_packet_creator_test.cc
+++ /dev/null
@@ -1,3937 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_creator.h"
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_packet_creator_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "common/simple_buffer_allocator.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using ::testing::_;
-using ::testing::AtLeast;
-using ::testing::DoAll;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::SaveArg;
-using ::testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
-// Use fields in which each byte is distinct to ensure that every byte is
-// framed correctly. The values are otherwise arbitrary.
-QuicConnectionId CreateTestConnectionId() {
-  return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
-}
-
-// Run tests with combinations of {ParsedQuicVersion,
-// ToggleVersionSerialization}.
-struct TestParams {
-  TestParams(ParsedQuicVersion version, bool version_serialization)
-      : version(version), version_serialization(version_serialization) {}
-
-  ParsedQuicVersion version;
-  bool version_serialization;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(ParsedQuicVersionToString(p.version), "_",
-                      (p.version_serialization ? "Include" : "No"), "Version");
-}
-
-// Constructs various test permutations.
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
-  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
-    params.push_back(TestParams(all_supported_versions[i], true));
-    params.push_back(TestParams(all_supported_versions[i], false));
-  }
-  return params;
-}
-
-class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
- public:
-  ~MockDebugDelegate() override = default;
-
-  MOCK_METHOD(void, OnFrameAddedToPacket, (const QuicFrame& frame), (override));
-
-  MOCK_METHOD(void,
-              OnStreamFrameCoalesced,
-              (const QuicStreamFrame& frame),
-              (override));
-};
-
-class TestPacketCreator : public QuicPacketCreator {
- public:
-  TestPacketCreator(QuicConnectionId connection_id,
-                    QuicFramer* framer,
-                    DelegateInterface* delegate,
-                    SimpleDataProducer* producer)
-      : QuicPacketCreator(connection_id, framer, delegate),
-        producer_(producer),
-        version_(framer->version()) {}
-
-  bool ConsumeDataToFillCurrentPacket(QuicStreamId id, absl::string_view data,
-                                      QuicStreamOffset offset, bool fin,
-                                      bool needs_full_padding,
-                                      TransmissionType transmission_type,
-                                      QuicFrame* frame) {
-    // Save data before data is consumed.
-    if (!data.empty()) {
-      producer_->SaveStreamData(id, data);
-    }
-    return QuicPacketCreator::ConsumeDataToFillCurrentPacket(
-        id, data.length(), offset, fin, needs_full_padding, transmission_type,
-        frame);
-  }
-
-  void StopSendingVersion() {
-    if (version_.HasIetfInvariantHeader()) {
-      set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-      return;
-    }
-    QuicPacketCreator::StopSendingVersion();
-  }
-
-  SimpleDataProducer* producer_;
-  ParsedQuicVersion version_;
-};
-
-class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
- public:
-  void ClearSerializedPacketForTests(SerializedPacket /*serialized_packet*/) {
-    // serialized packet self-clears on destruction.
-  }
-
-  void SaveSerializedPacket(SerializedPacket serialized_packet) {
-    serialized_packet_.reset(CopySerializedPacket(
-        serialized_packet, &allocator_, /*copy_buffer=*/true));
-  }
-
-  void DeleteSerializedPacket() { serialized_packet_ = nullptr; }
-
- protected:
-  QuicPacketCreatorTest()
-      : connection_id_(TestConnectionId(2)),
-        server_framer_(SupportedVersions(GetParam().version),
-                       QuicTime::Zero(),
-                       Perspective::IS_SERVER,
-                       connection_id_.length()),
-        client_framer_(SupportedVersions(GetParam().version),
-                       QuicTime::Zero(),
-                       Perspective::IS_CLIENT,
-                       connection_id_.length()),
-        data_("foo"),
-        creator_(connection_id_, &client_framer_, &delegate_, &producer_) {
-    EXPECT_CALL(delegate_, GetPacketBuffer())
-        .WillRepeatedly(Return(QuicPacketBuffer()));
-    EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
-        .WillRepeatedly(Return(SEND_TO_WRITER));
-    creator_.SetEncrypter(ENCRYPTION_INITIAL, std::make_unique<NullEncrypter>(
-                                                  Perspective::IS_CLIENT));
-    creator_.SetEncrypter(ENCRYPTION_HANDSHAKE, std::make_unique<NullEncrypter>(
-                                                    Perspective::IS_CLIENT));
-    creator_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
-                                                   Perspective::IS_CLIENT));
-    creator_.SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-    client_framer_.set_visitor(&framer_visitor_);
-    server_framer_.set_visitor(&framer_visitor_);
-    client_framer_.set_data_producer(&producer_);
-    if (server_framer_.version().KnowsWhichDecrypterToUse()) {
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_INITIAL,
-          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_ZERO_RTT,
-          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_HANDSHAKE,
-          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-      server_framer_.InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-    } else {
-      server_framer_.SetDecrypter(
-          ENCRYPTION_INITIAL,
-          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-    }
-  }
-
-  ~QuicPacketCreatorTest() override {}
-
-  SerializedPacket SerializeAllFrames(const QuicFrames& frames) {
-    SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
-        &creator_, frames, buffer_, kMaxOutgoingPacketSize);
-    EXPECT_EQ(QuicPacketCreatorPeer::GetEncryptionLevel(&creator_),
-              packet.encryption_level);
-    return packet;
-  }
-
-  void ProcessPacket(const SerializedPacket& packet) {
-    QuicEncryptedPacket encrypted_packet(packet.encrypted_buffer,
-                                         packet.encrypted_length);
-    server_framer_.ProcessPacket(encrypted_packet);
-  }
-
-  void CheckStreamFrame(const QuicFrame& frame,
-                        QuicStreamId stream_id,
-                        const std::string& data,
-                        QuicStreamOffset offset,
-                        bool fin) {
-    EXPECT_EQ(STREAM_FRAME, frame.type);
-    EXPECT_EQ(stream_id, frame.stream_frame.stream_id);
-    char buf[kMaxOutgoingPacketSize];
-    QuicDataWriter writer(kMaxOutgoingPacketSize, buf, quiche::HOST_BYTE_ORDER);
-    if (frame.stream_frame.data_length > 0) {
-      producer_.WriteStreamData(stream_id, frame.stream_frame.offset,
-                                frame.stream_frame.data_length, &writer);
-    }
-    EXPECT_EQ(data, absl::string_view(buf, frame.stream_frame.data_length));
-    EXPECT_EQ(offset, frame.stream_frame.offset);
-    EXPECT_EQ(fin, frame.stream_frame.fin);
-  }
-
-  // Returns the number of bytes consumed by the header of packet, including
-  // the version.
-  size_t GetPacketHeaderOverhead(QuicTransportVersion version) {
-    return GetPacketHeaderSize(
-        version, creator_.GetDestinationConnectionIdLength(),
-        creator_.GetSourceConnectionIdLength(),
-        QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-        !kIncludeDiversificationNonce,
-        QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-        QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
-        QuicPacketCreatorPeer::GetLengthLength(&creator_));
-  }
-
-  // Returns the number of bytes of overhead that will be added to a packet
-  // of maximum length.
-  size_t GetEncryptionOverhead() {
-    return creator_.max_packet_length() -
-           client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
-  }
-
-  // Returns the number of bytes consumed by the non-data fields of a stream
-  // frame, assuming it is the last frame in the packet
-  size_t GetStreamFrameOverhead(QuicTransportVersion version) {
-    return QuicFramer::GetMinStreamFrameSize(
-        version, GetNthClientInitiatedStreamId(1), kOffset, true,
-        /* data_length= */ 0);
-  }
-
-  bool IsDefaultTestConfiguration() {
-    TestParams p = GetParam();
-    return p.version == AllSupportedVersions()[0] && p.version_serialization;
-  }
-
-  QuicStreamId GetNthClientInitiatedStreamId(int n) const {
-    return QuicUtils::GetFirstBidirectionalStreamId(
-               creator_.transport_version(), Perspective::IS_CLIENT) +
-           n * 2;
-  }
-
-  void TestChaosProtection(bool enabled);
-
-  static constexpr QuicStreamOffset kOffset = 0u;
-
-  char buffer_[kMaxOutgoingPacketSize];
-  QuicConnectionId connection_id_;
-  QuicFrames frames_;
-  QuicFramer server_framer_;
-  QuicFramer client_framer_;
-  StrictMock<MockFramerVisitor> framer_visitor_;
-  StrictMock<MockPacketCreatorDelegate> delegate_;
-  std::string data_;
-  TestPacketCreator creator_;
-  std::unique_ptr<SerializedPacket> serialized_packet_;
-  SimpleDataProducer producer_;
-  quiche::SimpleBufferAllocator allocator_;
-};
-
-// Run all packet creator tests with all supported versions of QUIC, and with
-// and without version in the packet header, as well as doing a run for each
-// length of truncated connection id.
-INSTANTIATE_TEST_SUITE_P(QuicPacketCreatorTests,
-                         QuicPacketCreatorTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicPacketCreatorTest, SerializeFrames) {
-  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    EncryptionLevel level = static_cast<EncryptionLevel>(i);
-    creator_.set_encryption_level(level);
-    if (level != ENCRYPTION_ZERO_RTT) {
-      frames_.push_back(QuicFrame(new QuicAckFrame(InitAckFrame(1))));
-    }
-    QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-        client_framer_.transport_version(), Perspective::IS_CLIENT);
-    if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
-      frames_.push_back(QuicFrame(
-          QuicStreamFrame(stream_id, false, 0u, absl::string_view())));
-    }
-    SerializedPacket serialized = SerializeAllFrames(frames_);
-    EXPECT_EQ(level, serialized.encryption_level);
-    if (level != ENCRYPTION_ZERO_RTT) {
-      delete frames_[0].ack_frame;
-    }
-    frames_.clear();
-
-    {
-      InSequence s;
-      EXPECT_CALL(framer_visitor_, OnPacket());
-      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-      if (level != ENCRYPTION_ZERO_RTT) {
-        EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
-            .WillOnce(Return(true));
-        EXPECT_CALL(framer_visitor_,
-                    OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
-            .WillOnce(Return(true));
-        EXPECT_CALL(framer_visitor_, OnAckFrameEnd(QuicPacketNumber(1)))
-            .WillOnce(Return(true));
-      }
-      if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
-        EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-      }
-      if (client_framer_.version().HasHeaderProtection()) {
-        EXPECT_CALL(framer_visitor_, OnPaddingFrame(_))
-            .Times(testing::AnyNumber());
-      }
-      EXPECT_CALL(framer_visitor_, OnPacketComplete());
-    }
-    ProcessPacket(serialized);
-  }
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
-  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
-      creator_.transport_version(), QUIC_NO_ERROR, NO_IETF_QUIC_ERROR, "error",
-      /*transport_close_frame_type=*/0);
-
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame));
-  SerializedPacket serialized = SerializeAllFrames(frames);
-  EXPECT_EQ(ENCRYPTION_INITIAL, serialized.encryption_level);
-  ASSERT_EQ(QuicPacketNumber(1u), serialized.packet_number);
-  ASSERT_EQ(QuicPacketNumber(1u), creator_.packet_number());
-
-  InSequence s;
-  EXPECT_CALL(framer_visitor_, OnPacket());
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-  EXPECT_CALL(framer_visitor_, OnConnectionCloseFrame(_));
-  EXPECT_CALL(framer_visitor_, OnPacketComplete());
-
-  ProcessPacket(serialized);
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeCryptoDataToFillCurrentPacket) {
-  std::string data = "crypto data";
-  QuicFrame frame;
-  ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
-      ENCRYPTION_INITIAL, data.length(), 0,
-      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
-  EXPECT_EQ(frame.crypto_frame->data_length, data.length());
-  EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataToFillCurrentPacket) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  QuicFrame frame;
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  const std::string data("test");
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
-  size_t consumed = frame.stream_frame.data_length;
-  EXPECT_EQ(4u, consumed);
-  CheckStreamFrame(frame, stream_id, "test", 0u, false);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  QuicFrame frame;
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  const std::string data("test");
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, data, 0u, true, false, NOT_RETRANSMISSION, &frame));
-  size_t consumed = frame.stream_frame.data_length;
-  EXPECT_EQ(4u, consumed);
-  CheckStreamFrame(frame, stream_id, "test", 0u, true);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  QuicFrame frame;
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, {}, 0u, true, false, NOT_RETRANSMISSION, &frame));
-  size_t consumed = frame.stream_frame.data_length;
-  EXPECT_EQ(0u, consumed);
-  CheckStreamFrame(frame, stream_id, std::string(), 0u, true);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(absl::StartsWith(creator_.GetPendingFramesInfo(),
-                               "type { STREAM_FRAME }"));
-}
-
-TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  const size_t overhead =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      GetEncryptionOverhead();
-  for (size_t i = overhead + QuicPacketCreator::MinPlaintextPacketSize(
-                                 client_framer_.version());
-       i < overhead + 100; ++i) {
-    SCOPED_TRACE(i);
-    creator_.SetMaxPacketLength(i);
-    const bool should_have_room =
-        i >
-        overhead + GetStreamFrameOverhead(client_framer_.transport_version());
-    ASSERT_EQ(should_have_room,
-              creator_.HasRoomForStreamFrame(GetNthClientInitiatedStreamId(1),
-                                             kOffset, /* data_size=*/0xffff));
-    if (should_have_room) {
-      QuicFrame frame;
-      const std::string data("testdata");
-      EXPECT_CALL(delegate_, OnSerializedPacket(_))
-          .WillRepeatedly(Invoke(
-              this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
-      ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-          GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
-          NOT_RETRANSMISSION, &frame));
-      size_t bytes_consumed = frame.stream_frame.data_length;
-      EXPECT_LT(0u, bytes_consumed);
-      creator_.FlushCurrentPacket();
-    }
-  }
-}
-
-TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  // Compute the total overhead for a single frame in packet.
-  const size_t overhead =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      GetEncryptionOverhead() +
-      GetStreamFrameOverhead(client_framer_.transport_version());
-  size_t capacity = kDefaultMaxPacketSize - overhead;
-  // Now, test various sizes around this size.
-  for (int delta = -5; delta <= 5; ++delta) {
-    std::string data(capacity + delta, 'A');
-    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
-    QuicFrame frame;
-    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-        GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
-        NOT_RETRANSMISSION, &frame));
-
-    // BytesFree() returns bytes available for the next frame, which will
-    // be two bytes smaller since the stream frame would need to be grown.
-    EXPECT_EQ(2u, creator_.ExpansionOnNewFrame());
-    size_t expected_bytes_free = bytes_free < 3 ? 0 : bytes_free - 2;
-    EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-    creator_.FlushCurrentPacket();
-    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-    DeleteSerializedPacket();
-  }
-}
-
-TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
-  // This test serializes crypto payloads slightly larger than a packet, which
-  // Causes the multi-packet ClientHello check to fail.
-  SetQuicFlag(FLAGS_quic_enforce_single_packet_chlo, false);
-  // Compute the total overhead for a single frame in packet.
-  size_t overhead =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      GetEncryptionOverhead();
-  if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-    overhead +=
-        QuicFramer::GetMinCryptoFrameSize(kOffset, kMaxOutgoingPacketSize);
-  } else {
-    overhead += GetStreamFrameOverhead(client_framer_.transport_version());
-  }
-  ASSERT_GT(kMaxOutgoingPacketSize, overhead);
-  size_t capacity = kDefaultMaxPacketSize - overhead;
-  // Now, test various sizes around this size.
-  for (int delta = -5; delta <= 5; ++delta) {
-    SCOPED_TRACE(delta);
-    std::string data(capacity + delta, 'A');
-    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
-
-    QuicFrame frame;
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillRepeatedly(
-            Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-    if (client_framer_.version().CanSendCoalescedPackets()) {
-      EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
-          .WillRepeatedly(Return(COALESCE));
-    }
-    if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-      ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-          QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
-          data, kOffset, false, true, NOT_RETRANSMISSION, &frame));
-      size_t bytes_consumed = frame.stream_frame.data_length;
-      EXPECT_LT(0u, bytes_consumed);
-    } else {
-      producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
-      ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
-          ENCRYPTION_INITIAL, data.length(), kOffset,
-          /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
-      size_t bytes_consumed = frame.crypto_frame->data_length;
-      EXPECT_LT(0u, bytes_consumed);
-    }
-    creator_.FlushCurrentPacket();
-    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-    // If there is not enough space in the packet to fit a padding frame
-    // (1 byte) and to expand the stream frame (another 2 bytes) the packet
-    // will not be padded.
-    // Padding is skipped when we try to send coalesced packets.
-    if ((bytes_free < 3 &&
-         !QuicVersionUsesCryptoFrames(client_framer_.transport_version())) ||
-        client_framer_.version().CanSendCoalescedPackets()) {
-      EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
-                serialized_packet_->encrypted_length);
-    } else {
-      EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
-    }
-    DeleteSerializedPacket();
-  }
-}
-
-TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  // Compute the total overhead for a single frame in packet.
-  const size_t overhead =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      GetEncryptionOverhead() +
-      GetStreamFrameOverhead(client_framer_.transport_version());
-  ASSERT_GT(kDefaultMaxPacketSize, overhead);
-  size_t capacity = kDefaultMaxPacketSize - overhead;
-  // Now, test various sizes around this size.
-  for (int delta = -5; delta <= 5; ++delta) {
-    std::string data(capacity + delta, 'A');
-    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
-
-    QuicFrame frame;
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-        GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
-        NOT_RETRANSMISSION, &frame));
-    size_t bytes_consumed = frame.stream_frame.data_length;
-    EXPECT_LT(0u, bytes_consumed);
-    creator_.FlushCurrentPacket();
-    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-    if (bytes_free > 0) {
-      EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
-                serialized_packet_->encrypted_length);
-    } else {
-      EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
-    }
-    DeleteSerializedPacket();
-  }
-}
-
-// Test that the path challenge connectivity probing packet is serialized
-// correctly as a padded PATH CHALLENGE packet.
-TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = CreateTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  MockRandom randomizer;
-  QuicPathFrameBuffer payload;
-  randomizer.RandBytes(payload.data(), payload.size());
-
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // Path Challenge Frame type (IETF_PATH_CHALLENGE)
-    0x1a,
-    // 8 "random" bytes, MockRandom makes lots of r's
-    'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r',
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-
-  size_t length = creator_.BuildPaddedPathChallengePacket(
-      header, buffer.get(), ABSL_ARRAYSIZE(packet), payload,
-      ENCRYPTION_INITIAL);
-  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
-
-  // Payload has the random bytes that were generated. Copy them into packet,
-  // above, before checking that the generated packet is correct.
-  EXPECT_EQ(kQuicPathFrameBufferSize, payload.size());
-
-  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
-                  header);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data.data(), data.length(),
-      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildConnectivityProbingPacket) {
-  QuicPacketHeader header;
-  header.destination_connection_id = CreateTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-
-  // clang-format off
-  unsigned char packet[] = {
-    // public flags (8 byte connection_id)
-    0x2C,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (ping frame)
-    0x07,
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet46[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type
-    0x07,
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-
-  unsigned char packet99[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // frame type (IETF_PING frame)
-    0x01,
-    // frame type (padding frame)
-    0x00,
-    0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  unsigned char* p = packet;
-  size_t packet_size = ABSL_ARRAYSIZE(packet);
-  if (creator_.version().HasIetfQuicFrames()) {
-    p = packet99;
-    packet_size = ABSL_ARRAYSIZE(packet99);
-  } else if (creator_.version().HasIetfInvariantHeader()) {
-    p = packet46;
-    packet_size = ABSL_ARRAYSIZE(packet46);
-  }
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-
-  size_t length = creator_.BuildConnectivityProbingPacket(
-      header, buffer.get(), packet_size, ENCRYPTION_INITIAL);
-
-  EXPECT_NE(0u, length);
-  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
-                  header);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data.data(), data.length(),
-      reinterpret_cast<char*>(p), packet_size);
-}
-
-// Several tests that the path response connectivity probing packet is
-// serialized correctly as either a padded and unpadded PATH RESPONSE
-// packet. Also generates packets with 1 and 3 PATH_RESPONSES in them to
-// exercised the single- and multiple- payload cases.
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponseUnpadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = CreateTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  QuicPathFrameBuffer payload0 = {
-      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
-
-  // Build 1 PATH RESPONSE, not padded
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // Path Response Frame type (IETF_PATH_RESPONSE)
-    0x1b,
-    // 8 "random" bytes
-    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-  };
-  // clang-format on
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  size_t length = creator_.BuildPathResponsePacket(
-      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
-      /*is_padded=*/false, ENCRYPTION_INITIAL);
-  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
-  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
-                  header);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data.data(), data.length(),
-      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponsePadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = CreateTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  QuicPathFrameBuffer payload0 = {
-      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
-
-  // Build 1 PATH RESPONSE, padded
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // Path Response Frame type (IETF_PATH_RESPONSE)
-    0x1b,
-    // 8 "random" bytes
-    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-    // Padding type and pad
-    0x00, 0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  size_t length = creator_.BuildPathResponsePacket(
-      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
-      /*is_padded=*/true, ENCRYPTION_INITIAL);
-  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
-  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
-                  header);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data.data(), data.length(),
-      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesUnpadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = CreateTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  QuicPathFrameBuffer payload0 = {
-      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
-  QuicPathFrameBuffer payload1 = {
-      {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
-  QuicPathFrameBuffer payload2 = {
-      {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
-
-  // Build one packet with 3 PATH RESPONSES, no padding
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // 3 path response frames (IETF_PATH_RESPONSE type byte and payload)
-    0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-    0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-    0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
-  };
-  // clang-format on
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  payloads.push_back(payload1);
-  payloads.push_back(payload2);
-  size_t length = creator_.BuildPathResponsePacket(
-      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
-      /*is_padded=*/false, ENCRYPTION_INITIAL);
-  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
-  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
-                  header);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data.data(), data.length(),
-      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    // This frame is only for IETF QUIC.
-    return;
-  }
-
-  QuicPacketHeader header;
-  header.destination_connection_id = CreateTestConnectionId();
-  header.reset_flag = false;
-  header.version_flag = false;
-  header.packet_number = kPacketNumber;
-  QuicPathFrameBuffer payload0 = {
-      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
-  QuicPathFrameBuffer payload1 = {
-      {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
-  QuicPathFrameBuffer payload2 = {
-      {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
-
-  // Build one packet with 3 PATH RESPONSES, with padding
-  // clang-format off
-  unsigned char packet[] = {
-    // type (short header, 4 byte packet number)
-    0x43,
-    // connection_id
-    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-    // packet number
-    0x12, 0x34, 0x56, 0x78,
-
-    // 3 path response frames (IETF_PATH_RESPONSE byte and payload)
-    0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-    0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
-    0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
-    // Padding
-    0x00, 0x00, 0x00, 0x00, 0x00
-  };
-  // clang-format on
-
-  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  payloads.push_back(payload1);
-  payloads.push_back(payload2);
-  size_t length = creator_.BuildPathResponsePacket(
-      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
-      /*is_padded=*/true, ENCRYPTION_INITIAL);
-  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
-  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
-                  header);
-
-  quiche::test::CompareCharArraysWithHexError(
-      "constructed packet", data.data(), data.length(),
-      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  std::unique_ptr<SerializedPacket> encrypted;
-  if (VersionHasIetfQuicFrames(creator_.transport_version())) {
-    QuicPathFrameBuffer payload = {
-        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
-    encrypted =
-        creator_.SerializePathChallengeConnectivityProbingPacket(payload);
-  } else {
-    encrypted = creator_.SerializeConnectivityProbingPacket();
-  }
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    if (VersionHasIetfQuicFrames(creator_.transport_version())) {
-      EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    } else {
-      EXPECT_CALL(framer_visitor_, OnPingFrame(_));
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    }
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathChallengeConnectivityProbingPacket(payload));
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload0 = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest,
-       SerializePathResponseProbePacket1PayloadUnPadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload0 = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload0 = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-  QuicPathFrameBuffer payload1 = {
-      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  payloads.push_back(payload1);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
-    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest,
-       SerializePathResponseProbePacket2PayloadsUnPadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload0 = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-  QuicPathFrameBuffer payload1 = {
-      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  payloads.push_back(payload1);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload0 = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-  QuicPathFrameBuffer payload1 = {
-      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
-  QuicPathFrameBuffer payload2 = {
-      {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  payloads.push_back(payload1);
-  payloads.push_back(payload2);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
-    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest,
-       SerializePathResponseProbePacket3PayloadsUnpadded) {
-  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
-    return;
-  }
-  QuicPathFrameBuffer payload0 = {
-      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
-  QuicPathFrameBuffer payload1 = {
-      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
-  QuicPathFrameBuffer payload2 = {
-      {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
-  payloads.push_back(payload0);
-  payloads.push_back(payload1);
-  payloads.push_back(payload2);
-
-  std::unique_ptr<SerializedPacket> encrypted(
-      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
-  InSequence s;
-  EXPECT_CALL(framer_visitor_, OnPacket());
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-  EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
-  EXPECT_CALL(framer_visitor_, OnPacketComplete());
-
-  server_framer_.ProcessPacket(QuicEncryptedPacket(
-      encrypted->encrypted_buffer, encrypted->encrypted_length));
-}
-
-TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
-  if (creator_.version().HasIetfInvariantHeader() &&
-      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
-    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
-              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  } else {
-    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
-              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-  }
-
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64);
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
-                                    10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256);
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
-                                    10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256);
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
-                                    10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_,
-                                         UINT64_C(64) * 256 * 256 * 256 * 256);
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
-                                    10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
-  if (creator_.version().HasIetfInvariantHeader() &&
-      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
-    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
-              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  } else {
-    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
-              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-  }
-
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
-                                    10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
-                                    10000 * 256 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
-                                    10000 * 256 * 256 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  creator_.UpdatePacketNumberLength(
-      QuicPacketNumber(1),
-      UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
-  EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, SkipNPacketNumbers) {
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
-  if (creator_.version().HasIetfInvariantHeader() &&
-      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
-    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
-              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  } else {
-    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
-              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-  }
-  creator_.SkipNPacketNumbers(63, QuicPacketNumber(2),
-                              10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(QuicPacketNumber(64), creator_.packet_number());
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  creator_.SkipNPacketNumbers(64 * 255, QuicPacketNumber(2),
-                              10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(QuicPacketNumber(64 * 256), creator_.packet_number());
-  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-
-  creator_.SkipNPacketNumbers(64 * 256 * 255, QuicPacketNumber(2),
-                              10000 / kDefaultMaxPacketSize);
-  EXPECT_EQ(QuicPacketNumber(64 * 256 * 256), creator_.packet_number());
-  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
-            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeFrame) {
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  std::string data("test data");
-  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-    QuicStreamFrame stream_frame(
-        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
-        /*fin=*/false, 0u, absl::string_view());
-    frames_.push_back(QuicFrame(stream_frame));
-  } else {
-    producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
-    frames_.push_back(
-        QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
-  }
-  SerializedPacket serialized = SerializeAllFrames(frames_);
-
-  QuicPacketHeader header;
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
-        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
-    if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-      EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
-    } else {
-      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-    }
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  ProcessPacket(serialized);
-  EXPECT_EQ(GetParam().version_serialization, header.version_flag);
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeFrameShortData) {
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  std::string data("Hello World!");
-  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-    QuicStreamFrame stream_frame(
-        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
-        /*fin=*/false, 0u, absl::string_view());
-    frames_.push_back(QuicFrame(stream_frame));
-  } else {
-    producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
-    frames_.push_back(
-        QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
-  }
-  SerializedPacket serialized = SerializeAllFrames(frames_);
-
-  QuicPacketHeader header;
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
-        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
-    if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-      EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
-    } else {
-      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-    }
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  ProcessPacket(serialized);
-  EXPECT_EQ(GetParam().version_serialization, header.version_flag);
-}
-
-void QuicPacketCreatorTest::TestChaosProtection(bool enabled) {
-  if (!GetParam().version.UsesCryptoFrames()) {
-    return;
-  }
-  MockRandom mock_random(2);
-  QuicPacketCreatorPeer::SetRandom(&creator_, &mock_random);
-  creator_.set_chaos_protection_enabled(enabled);
-  std::string data("ChAoS_ThEoRy!");
-  producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
-  frames_.push_back(
-      QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
-  frames_.push_back(QuicFrame(QuicPaddingFrame(33)));
-  SerializedPacket serialized = SerializeAllFrames(frames_);
-  EXPECT_CALL(framer_visitor_, OnPacket());
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-  if (enabled) {
-    EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(AtLeast(2));
-    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(AtLeast(2));
-    EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(AtLeast(1));
-  } else {
-    EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(1);
-    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(1);
-    EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(0);
-  }
-  EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  ProcessPacket(serialized);
-}
-
-TEST_P(QuicPacketCreatorTest, ChaosProtectionEnabled) {
-  TestChaosProtection(/*enabled=*/true);
-}
-
-TEST_P(QuicPacketCreatorTest, ChaosProtectionDisabled) {
-  TestChaosProtection(/*enabled=*/false);
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  // A string larger than fits into a frame.
-  QuicFrame frame;
-  size_t payload_length = creator_.max_packet_length();
-  const std::string too_long_payload(payload_length, 'a');
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, too_long_payload, 0u, true, false, NOT_RETRANSMISSION,
-      &frame));
-  size_t consumed = frame.stream_frame.data_length;
-  // The entire payload could not be consumed.
-  EXPECT_GT(payload_length, consumed);
-  creator_.FlushCurrentPacket();
-  DeleteSerializedPacket();
-}
-
-TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  const size_t max_plaintext_size =
-      client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-    stream_id =
-        QuicUtils::GetCryptoStreamId(client_framer_.transport_version());
-  }
-  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
-  EXPECT_EQ(max_plaintext_size -
-                GetPacketHeaderSize(
-                    client_framer_.transport_version(),
-                    creator_.GetDestinationConnectionIdLength(),
-                    creator_.GetSourceConnectionIdLength(),
-                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-                    !kIncludeDiversificationNonce,
-                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
-                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
-            creator_.BytesFree());
-  StrictMock<MockDebugDelegate> debug;
-  creator_.set_debug_delegate(&debug);
-
-  // Add a variety of frame types and then a padding frame.
-  QuicAckFrame ack_frame(InitAckFrame(10u));
-  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
-
-  QuicFrame frame;
-  const std::string data("test");
-  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
-  size_t consumed = frame.stream_frame.data_length;
-  EXPECT_EQ(4u, consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id));
-
-  QuicPaddingFrame padding_frame;
-  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(padding_frame), NOT_RETRANSMISSION));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_EQ(0u, creator_.BytesFree());
-
-  // Packet is full. Creator will flush.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  EXPECT_FALSE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
-
-  // Ensure the packet is successfully created.
-  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
-  const QuicFrames& retransmittable =
-      serialized_packet_->retransmittable_frames;
-  ASSERT_EQ(1u, retransmittable.size());
-  EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
-  EXPECT_TRUE(serialized_packet_->has_ack);
-  EXPECT_EQ(QuicPacketNumber(10u), serialized_packet_->largest_acked);
-  DeleteSerializedPacket();
-
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
-  EXPECT_EQ(max_plaintext_size -
-                GetPacketHeaderSize(
-                    client_framer_.transport_version(),
-                    creator_.GetDestinationConnectionIdLength(),
-                    creator_.GetSourceConnectionIdLength(),
-                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-                    !kIncludeDiversificationNonce,
-                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
-                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
-            creator_.BytesFree());
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  EXPECT_FALSE(creator_.HasPendingFrames());
-
-  const std::string data("test");
-  producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  size_t num_bytes_consumed;
-  StrictMock<MockDebugDelegate> debug;
-  creator_.set_debug_delegate(&debug);
-  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
-  creator_.CreateAndSerializeStreamFrame(
-      GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true,
-      NOT_RETRANSMISSION, &num_bytes_consumed);
-  EXPECT_EQ(4u, num_bytes_consumed);
-
-  // Ensure the packet is successfully created.
-  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
-  const QuicFrames& retransmittable =
-      serialized_packet_->retransmittable_frames;
-  ASSERT_EQ(1u, retransmittable.size());
-  EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
-  DeleteSerializedPacket();
-
-  EXPECT_FALSE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeStreamFrameWithPadding) {
-  // Regression test to check that CreateAndSerializeStreamFrame uses a
-  // correctly formatted stream frame header when appending padding.
-
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  EXPECT_FALSE(creator_.HasPendingFrames());
-
-  // Send one byte of stream data.
-  const std::string data("a");
-  producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  size_t num_bytes_consumed;
-  creator_.CreateAndSerializeStreamFrame(
-      GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true,
-      NOT_RETRANSMISSION, &num_bytes_consumed);
-  EXPECT_EQ(1u, num_bytes_consumed);
-
-  // Check that a packet is created.
-  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-    if (client_framer_.version().HasHeaderProtection()) {
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    }
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  ProcessPacket(*serialized_packet_);
-}
-
-TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration()) {
-    return;
-  }
-
-  creator_.set_encryption_level(ENCRYPTION_INITIAL);
-  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
-  QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
-                               /*fin=*/false, 0u, absl::string_view());
-  EXPECT_QUIC_BUG(
-      creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
-      "Cannot send stream data with level: ENCRYPTION_INITIAL");
-}
-
-TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration()) {
-    return;
-  }
-
-  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
-  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
-  QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
-                               /*fin=*/false, 0u, absl::string_view());
-  EXPECT_QUIC_BUG(
-      creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
-      "Cannot send stream data with level: ENCRYPTION_HANDSHAKE");
-}
-
-TEST_P(QuicPacketCreatorTest, ChloTooLarge) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (!IsDefaultTestConfiguration()) {
-    return;
-  }
-
-  // This test only matters when the crypto handshake is sent in stream frames.
-  // TODO(b/128596274): Re-enable when this check is supported for CRYPTO
-  // frames.
-  if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-    return;
-  }
-
-  CryptoHandshakeMessage message;
-  message.set_tag(kCHLO);
-  message.set_minimum_size(kMaxOutgoingPacketSize);
-  CryptoFramer framer;
-  std::unique_ptr<QuicData> message_data;
-  message_data = framer.ConstructHandshakeMessage(message);
-
-  QuicFrame frame;
-  EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _));
-  EXPECT_QUIC_BUG(
-      creator_.ConsumeDataToFillCurrentPacket(
-          QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
-          absl::string_view(message_data->data(), message_data->length()), 0u,
-          false, false, NOT_RETRANSMISSION, &frame),
-      "Client hello won't fit in a single packet.");
-}
-
-TEST_P(QuicPacketCreatorTest, PendingPadding) {
-  EXPECT_EQ(0u, creator_.pending_padding_bytes());
-  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes * 10);
-  EXPECT_EQ(kMaxNumRandomPaddingBytes * 10, creator_.pending_padding_bytes());
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  // Flush all paddings.
-  while (creator_.pending_padding_bytes() > 0) {
-    creator_.FlushCurrentPacket();
-    {
-      InSequence s;
-      EXPECT_CALL(framer_visitor_, OnPacket());
-      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-      EXPECT_CALL(framer_visitor_, OnPacketComplete());
-    }
-    // Packet only contains padding.
-    ProcessPacket(*serialized_packet_);
-  }
-  EXPECT_EQ(0u, creator_.pending_padding_bytes());
-}
-
-TEST_P(QuicPacketCreatorTest, FullPaddingDoesNotConsumePendingPadding) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
-  QuicFrame frame;
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  const std::string data("test");
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, data, 0u, false,
-      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  creator_.FlushCurrentPacket();
-  EXPECT_EQ(kMaxNumRandomPaddingBytes, creator_.pending_padding_bytes());
-}
-
-TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  const QuicByteCount kStreamFramePayloadSize = 100u;
-  // Set the packet size be enough for one stream frame with 0 stream offset +
-  // 1.
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  size_t length =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      GetEncryptionOverhead() +
-      QuicFramer::GetMinStreamFrameSize(
-          client_framer_.transport_version(), stream_id, 0,
-          /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
-      kStreamFramePayloadSize + 1;
-  creator_.SetMaxPacketLength(length);
-  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
-  QuicByteCount pending_padding_bytes = creator_.pending_padding_bytes();
-  QuicFrame frame;
-  char buf[kStreamFramePayloadSize + 1] = {};
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  // Send stream frame of size kStreamFramePayloadSize.
-  creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, absl::string_view(buf, kStreamFramePayloadSize), 0u, false,
-      false, NOT_RETRANSMISSION, &frame);
-  creator_.FlushCurrentPacket();
-  // 1 byte padding is sent.
-  EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
-  // Send stream frame of size kStreamFramePayloadSize + 1.
-  creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, absl::string_view(buf, kStreamFramePayloadSize + 1),
-      kStreamFramePayloadSize, false, false, NOT_RETRANSMISSION, &frame);
-  // No padding is sent.
-  creator_.FlushCurrentPacket();
-  EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
-  // Flush all paddings.
-  while (creator_.pending_padding_bytes() > 0) {
-    creator_.FlushCurrentPacket();
-  }
-  EXPECT_EQ(0u, creator_.pending_padding_bytes());
-}
-
-TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  char* buffer = new char[kMaxOutgoingPacketSize];
-  QuicPacketBuffer external_buffer = {buffer,
-                                      [](const char* p) { delete[] p; }};
-  EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(external_buffer));
-
-  QuicFrame frame;
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  const std::string data("test");
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, data, 0u, false,
-      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke([&external_buffer](SerializedPacket serialized_packet) {
-        EXPECT_EQ(external_buffer.buffer, serialized_packet.encrypted_buffer);
-      }));
-  creator_.FlushCurrentPacket();
-}
-
-// Test for error found in
-// https://bugs.chromium.org/p/chromium/issues/detail?id=859949 where a gap
-// length that crosses an IETF VarInt length boundary would cause a
-// failure. While this test is not applicable to versions other than version 99,
-// it should still work. Hence, it is not made version-specific.
-TEST_P(QuicPacketCreatorTest, IetfAckGapErrorRegression) {
-  QuicAckFrame ack_frame =
-      InitAckFrame({{QuicPacketNumber(60), QuicPacketNumber(61)},
-                    {QuicPacketNumber(125), QuicPacketNumber(126)}});
-  frames_.push_back(QuicFrame(&ack_frame));
-  SerializeAllFrames(frames_);
-}
-
-TEST_P(QuicPacketCreatorTest, AddMessageFrame) {
-  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
-    return;
-  }
-  if (client_framer_.version().UsesTls()) {
-    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-  }
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .Times(3)
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
-  // Verify that there is enough room for the largest message payload.
-  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
-      creator_.GetCurrentLargestMessagePayload()));
-  std::string large_message(creator_.GetCurrentLargestMessagePayload(), 'a');
-  QuicMessageFrame* message_frame =
-      new QuicMessageFrame(1, MemSliceFromString(large_message));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(message_frame), NOT_RETRANSMISSION));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  creator_.FlushCurrentPacket();
-
-  QuicMessageFrame* frame2 =
-      new QuicMessageFrame(2, MemSliceFromString("message"));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame2), NOT_RETRANSMISSION));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  // Verify if a new frame is added, 1 byte message length will be added.
-  EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
-  QuicMessageFrame* frame3 =
-      new QuicMessageFrame(3, MemSliceFromString("message2"));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame3), NOT_RETRANSMISSION));
-  EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
-  creator_.FlushCurrentPacket();
-
-  QuicFrame frame;
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  const std::string data("test");
-  EXPECT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
-  QuicMessageFrame* frame4 =
-      new QuicMessageFrame(4, MemSliceFromString("message"));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame4), NOT_RETRANSMISSION));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  // Verify there is not enough room for largest payload.
-  EXPECT_FALSE(creator_.HasRoomForMessageFrame(
-      creator_.GetCurrentLargestMessagePayload()));
-  // Add largest message will causes the flush of the stream frame.
-  QuicMessageFrame frame5(5, MemSliceFromString(large_message));
-  EXPECT_FALSE(creator_.AddFrame(QuicFrame(&frame5), NOT_RETRANSMISSION));
-  EXPECT_FALSE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) {
-  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
-    return;
-  }
-  if (client_framer_.version().UsesTls()) {
-    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-  }
-  std::string message_data(kDefaultMaxPacketSize, 'a');
-  // Test all possible encryption levels of message frames.
-  for (EncryptionLevel level :
-       {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
-    creator_.set_encryption_level(level);
-    // Test all possible sizes of message frames.
-    for (size_t message_size = 0;
-         message_size <= creator_.GetCurrentLargestMessagePayload();
-         ++message_size) {
-      QuicMessageFrame* frame =
-          new QuicMessageFrame(0, MemSliceFromString(absl::string_view(
-                                      message_data.data(), message_size)));
-      EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION));
-      EXPECT_TRUE(creator_.HasPendingFrames());
-
-      size_t expansion_bytes = message_size >= 64 ? 2 : 1;
-      EXPECT_EQ(expansion_bytes, creator_.ExpansionOnNewFrame());
-      // Verify BytesFree returns bytes available for the next frame, which
-      // should subtract the message length.
-      size_t expected_bytes_free =
-          creator_.GetCurrentLargestMessagePayload() - message_size <
-                  expansion_bytes
-              ? 0
-              : creator_.GetCurrentLargestMessagePayload() - expansion_bytes -
-                    message_size;
-      EXPECT_EQ(expected_bytes_free, creator_.BytesFree());
-      EXPECT_LE(creator_.GetGuaranteedLargestMessagePayload(),
-                creator_.GetCurrentLargestMessagePayload());
-      EXPECT_CALL(delegate_, OnSerializedPacket(_))
-          .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-      creator_.FlushCurrentPacket();
-      ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-      DeleteSerializedPacket();
-    }
-  }
-}
-
-TEST_P(QuicPacketCreatorTest, GetGuaranteedLargestMessagePayload) {
-  ParsedQuicVersion version = GetParam().version;
-  if (!version.SupportsMessageFrames()) {
-    return;
-  }
-  if (version.UsesTls()) {
-    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-  }
-  QuicPacketLength expected_largest_payload = 1219;
-  if (version.HasLongHeaderLengths()) {
-    expected_largest_payload -= 2;
-  }
-  if (version.HasLengthPrefixedConnectionIds()) {
-    expected_largest_payload -= 1;
-  }
-  EXPECT_EQ(expected_largest_payload,
-            creator_.GetGuaranteedLargestMessagePayload());
-  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
-      creator_.GetGuaranteedLargestMessagePayload()));
-
-  // Now test whether SetMaxDatagramFrameSize works.
-  creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
-                                   kQuicFrameTypeSize);
-  EXPECT_EQ(expected_largest_payload,
-            creator_.GetGuaranteedLargestMessagePayload());
-  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
-      creator_.GetGuaranteedLargestMessagePayload()));
-
-  creator_.SetMaxDatagramFrameSize(expected_largest_payload +
-                                   kQuicFrameTypeSize);
-  EXPECT_EQ(expected_largest_payload,
-            creator_.GetGuaranteedLargestMessagePayload());
-  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
-      creator_.GetGuaranteedLargestMessagePayload()));
-
-  creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
-                                   kQuicFrameTypeSize);
-  EXPECT_EQ(expected_largest_payload - 1,
-            creator_.GetGuaranteedLargestMessagePayload());
-  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
-      creator_.GetGuaranteedLargestMessagePayload()));
-
-  constexpr QuicPacketLength kFrameSizeLimit = 1000;
-  constexpr QuicPacketLength kPayloadSizeLimit =
-      kFrameSizeLimit - kQuicFrameTypeSize;
-  creator_.SetMaxDatagramFrameSize(kFrameSizeLimit);
-  EXPECT_EQ(creator_.GetGuaranteedLargestMessagePayload(), kPayloadSizeLimit);
-  EXPECT_TRUE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit));
-  EXPECT_FALSE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit + 1));
-}
-
-TEST_P(QuicPacketCreatorTest, GetCurrentLargestMessagePayload) {
-  ParsedQuicVersion version = GetParam().version;
-  if (!version.SupportsMessageFrames()) {
-    return;
-  }
-  if (version.UsesTls()) {
-    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-  }
-  QuicPacketLength expected_largest_payload = 1219;
-  if (version.SendsVariableLengthPacketNumberInLongHeader()) {
-    expected_largest_payload += 3;
-  }
-  if (version.HasLongHeaderLengths()) {
-    expected_largest_payload -= 2;
-  }
-  if (version.HasLengthPrefixedConnectionIds()) {
-    expected_largest_payload -= 1;
-  }
-  EXPECT_EQ(expected_largest_payload,
-            creator_.GetCurrentLargestMessagePayload());
-
-  // Now test whether SetMaxDatagramFrameSize works.
-  creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
-                                   kQuicFrameTypeSize);
-  EXPECT_EQ(expected_largest_payload,
-            creator_.GetCurrentLargestMessagePayload());
-
-  creator_.SetMaxDatagramFrameSize(expected_largest_payload +
-                                   kQuicFrameTypeSize);
-  EXPECT_EQ(expected_largest_payload,
-            creator_.GetCurrentLargestMessagePayload());
-
-  creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
-                                   kQuicFrameTypeSize);
-  EXPECT_EQ(expected_largest_payload - 1,
-            creator_.GetCurrentLargestMessagePayload());
-}
-
-TEST_P(QuicPacketCreatorTest, PacketTransmissionType) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-
-  QuicAckFrame temp_ack_frame = InitAckFrame(1);
-  QuicFrame ack_frame(&temp_ack_frame);
-  ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(ack_frame.type));
-
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  QuicFrame stream_frame(QuicStreamFrame(stream_id,
-                                         /*fin=*/false, 0u,
-                                         absl::string_view()));
-  ASSERT_TRUE(QuicUtils::IsRetransmittableFrame(stream_frame.type));
-
-  QuicFrame padding_frame{QuicPaddingFrame()};
-  ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(padding_frame.type));
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-
-  EXPECT_TRUE(creator_.AddFrame(ack_frame, LOSS_RETRANSMISSION));
-  ASSERT_EQ(serialized_packet_, nullptr);
-
-  EXPECT_TRUE(creator_.AddFrame(stream_frame, RTO_RETRANSMISSION));
-  ASSERT_EQ(serialized_packet_, nullptr);
-
-  EXPECT_TRUE(creator_.AddFrame(padding_frame, TLP_RETRANSMISSION));
-  creator_.FlushCurrentPacket();
-  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
-
-  // The last retransmittable frame on packet is a stream frame, the packet's
-  // transmission type should be the same as the stream frame's.
-  EXPECT_EQ(serialized_packet_->transmission_type, RTO_RETRANSMISSION);
-  DeleteSerializedPacket();
-}
-
-TEST_P(QuicPacketCreatorTest, RetryToken) {
-  if (!GetParam().version_serialization ||
-      !QuicVersionHasLongHeaderLengths(client_framer_.transport_version())) {
-    return;
-  }
-
-  char retry_token_bytes[] = {1, 2,  3,  4,  5,  6,  7,  8,
-                              9, 10, 11, 12, 13, 14, 15, 16};
-
-  creator_.SetRetryToken(
-      std::string(retry_token_bytes, sizeof(retry_token_bytes)));
-
-  frames_.push_back(QuicFrame(QuicPingFrame()));
-  SerializedPacket serialized = SerializeAllFrames(frames_);
-
-  QuicPacketHeader header;
-  {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
-        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
-    EXPECT_CALL(framer_visitor_, OnPingFrame(_));
-    if (client_framer_.version().HasHeaderProtection()) {
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    }
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  }
-  ProcessPacket(serialized);
-  ASSERT_TRUE(header.version_flag);
-  ASSERT_EQ(header.long_packet_type, INITIAL);
-  ASSERT_EQ(header.retry_token.length(), sizeof(retry_token_bytes));
-  quiche::test::CompareCharArraysWithHexError(
-      "retry token", header.retry_token.data(), header.retry_token.length(),
-      retry_token_bytes, sizeof(retry_token_bytes));
-}
-
-TEST_P(QuicPacketCreatorTest, GetConnectionId) {
-  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
-  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
-}
-
-TEST_P(QuicPacketCreatorTest, ClientConnectionId) {
-  if (!client_framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
-  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
-  creator_.SetClientConnectionId(TestConnectionId(0x33));
-  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
-  EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
-}
-
-TEST_P(QuicPacketCreatorTest, CoalesceStreamFrames) {
-  InSequence s;
-  if (!GetParam().version_serialization) {
-    creator_.StopSendingVersion();
-  }
-  const size_t max_plaintext_size =
-      client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  QuicStreamId stream_id1 = QuicUtils::GetFirstBidirectionalStreamId(
-      client_framer_.transport_version(), Perspective::IS_CLIENT);
-  QuicStreamId stream_id2 = GetNthClientInitiatedStreamId(1);
-  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id1));
-  EXPECT_EQ(max_plaintext_size -
-                GetPacketHeaderSize(
-                    client_framer_.transport_version(),
-                    creator_.GetDestinationConnectionIdLength(),
-                    creator_.GetSourceConnectionIdLength(),
-                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-                    !kIncludeDiversificationNonce,
-                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
-                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
-            creator_.BytesFree());
-  StrictMock<MockDebugDelegate> debug;
-  creator_.set_debug_delegate(&debug);
-
-  QuicFrame frame;
-  const std::string data1("test");
-  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id1, data1, 0u, false, false, NOT_RETRANSMISSION, &frame));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id1));
-
-  const std::string data2("coalesce");
-  // frame will be coalesced with the first frame.
-  const auto previous_size = creator_.PacketSize();
-  QuicStreamFrame target(stream_id1, true, 0, data1.length() + data2.length());
-  EXPECT_CALL(debug, OnStreamFrameCoalesced(target));
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id1, data2, 4u, true, false, NOT_RETRANSMISSION, &frame));
-  EXPECT_EQ(frame.stream_frame.data_length,
-            creator_.PacketSize() - previous_size);
-
-  // frame is for another stream, so it won't be coalesced.
-  const auto length = creator_.BytesFree() - 10u;
-  const std::string data3(length, 'x');
-  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id2, data3, 0u, false, false, NOT_RETRANSMISSION, &frame));
-  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id2));
-
-  // The packet doesn't have enough free bytes for all data, but will still be
-  // able to consume and coalesce part of them.
-  EXPECT_CALL(debug, OnStreamFrameCoalesced(_));
-  const std::string data4("somerandomdata");
-  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-      stream_id2, data4, length, false, false, NOT_RETRANSMISSION, &frame));
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  creator_.FlushCurrentPacket();
-  EXPECT_CALL(framer_visitor_, OnPacket());
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-  // The packet should only have 2 stream frames.
-  EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-  EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-  EXPECT_CALL(framer_visitor_, OnPacketComplete());
-  ProcessPacket(*serialized_packet_);
-}
-
-TEST_P(QuicPacketCreatorTest, SaveNonRetransmittableFrames) {
-  QuicAckFrame ack_frame(InitAckFrame(1));
-  frames_.push_back(QuicFrame(&ack_frame));
-  frames_.push_back(QuicFrame(QuicPaddingFrame(-1)));
-  SerializedPacket serialized = SerializeAllFrames(frames_);
-  ASSERT_EQ(2u, serialized.nonretransmittable_frames.size());
-  EXPECT_EQ(ACK_FRAME, serialized.nonretransmittable_frames[0].type);
-  EXPECT_EQ(PADDING_FRAME, serialized.nonretransmittable_frames[1].type);
-  // Verify full padding frame is translated to a padding frame with actual
-  // bytes of padding.
-  EXPECT_LT(
-      0,
-      serialized.nonretransmittable_frames[1].padding_frame.num_padding_bytes);
-  frames_.clear();
-
-  // Serialize another packet with the same frames.
-  SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
-      &creator_, serialized.nonretransmittable_frames, buffer_,
-      kMaxOutgoingPacketSize);
-  // Verify the packet length of both packets are equal.
-  EXPECT_EQ(serialized.encrypted_length, packet.encrypted_length);
-}
-
-TEST_P(QuicPacketCreatorTest, SerializeCoalescedPacket) {
-  QuicCoalescedPacket coalesced;
-  quiche::SimpleBufferAllocator allocator;
-  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
-  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
-  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    EncryptionLevel level = static_cast<EncryptionLevel>(i);
-    creator_.set_encryption_level(level);
-    QuicAckFrame ack_frame(InitAckFrame(1));
-    if (level != ENCRYPTION_ZERO_RTT) {
-      frames_.push_back(QuicFrame(&ack_frame));
-    }
-    if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
-      frames_.push_back(
-          QuicFrame(QuicStreamFrame(1, false, 0u, absl::string_view())));
-    }
-    SerializedPacket serialized = SerializeAllFrames(frames_);
-    EXPECT_EQ(level, serialized.encryption_level);
-    frames_.clear();
-    ASSERT_TRUE(coalesced.MaybeCoalescePacket(serialized, self_address,
-                                              peer_address, &allocator,
-                                              creator_.max_packet_length()));
-  }
-  char buffer[kMaxOutgoingPacketSize];
-  size_t coalesced_length = creator_.SerializeCoalescedPacket(
-      coalesced, buffer, kMaxOutgoingPacketSize);
-  // Verify packet is padded to full.
-  ASSERT_EQ(coalesced.max_packet_length(), coalesced_length);
-  if (!QuicVersionHasLongHeaderLengths(server_framer_.transport_version())) {
-    return;
-  }
-  // Verify packet process.
-  std::unique_ptr<QuicEncryptedPacket> packets[NUM_ENCRYPTION_LEVELS];
-  packets[ENCRYPTION_INITIAL] =
-      std::make_unique<QuicEncryptedPacket>(buffer, coalesced_length);
-  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    InSequence s;
-    EXPECT_CALL(framer_visitor_, OnPacket());
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-    if (i < ENCRYPTION_FORWARD_SECURE) {
-      // Save coalesced packet.
-      EXPECT_CALL(framer_visitor_, OnCoalescedPacket(_))
-          .WillOnce(Invoke([i, &packets](const QuicEncryptedPacket& packet) {
-            packets[i + 1] = packet.Clone();
-          }));
-    }
-    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-    if (i != ENCRYPTION_ZERO_RTT) {
-      EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
-          .WillOnce(Return(true));
-      EXPECT_CALL(framer_visitor_,
-                  OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
-          .WillOnce(Return(true));
-      EXPECT_CALL(framer_visitor_, OnAckFrameEnd(_)).WillOnce(Return(true));
-    }
-    if (i == ENCRYPTION_INITIAL) {
-      // Verify padding is added.
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    } else if (i != ENCRYPTION_ZERO_RTT) {
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(testing::AtMost(1));
-    }
-    if (i != ENCRYPTION_INITIAL && i != ENCRYPTION_HANDSHAKE) {
-      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
-    }
-    if (i == ENCRYPTION_ZERO_RTT) {
-      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
-    }
-    EXPECT_CALL(framer_visitor_, OnPacketComplete());
-
-    server_framer_.ProcessPacket(*packets[i]);
-  }
-}
-
-TEST_P(QuicPacketCreatorTest, SoftMaxPacketLength) {
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  QuicByteCount previous_max_packet_length = creator_.max_packet_length();
-  const size_t overhead =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
-      GetEncryptionOverhead();
-  // Make sure a length which cannot accommodate header (includes header
-  // protection minimal length) gets rejected.
-  creator_.SetSoftMaxPacketLength(overhead - 1);
-  EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
-
-  creator_.SetSoftMaxPacketLength(overhead);
-  EXPECT_EQ(overhead, creator_.max_packet_length());
-
-  // Verify creator has room for stream frame because max_packet_length_ gets
-  // restored.
-  ASSERT_TRUE(creator_.HasRoomForStreamFrame(
-      GetNthClientInitiatedStreamId(1), kMaxIetfVarInt,
-      std::numeric_limits<uint32_t>::max()));
-  EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
-
-  // Same for message frame.
-  if (VersionSupportsMessageFrames(client_framer_.transport_version())) {
-    creator_.SetSoftMaxPacketLength(overhead);
-    if (client_framer_.version().UsesTls()) {
-      creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-    }
-    // Verify GetCurrentLargestMessagePayload is based on the actual
-    // max_packet_length.
-    EXPECT_LT(1u, creator_.GetCurrentLargestMessagePayload());
-    EXPECT_EQ(overhead, creator_.max_packet_length());
-    ASSERT_TRUE(creator_.HasRoomForMessageFrame(
-        creator_.GetCurrentLargestMessagePayload()));
-    EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
-  }
-
-  // Verify creator can consume crypto data because max_packet_length_ gets
-  // restored.
-  creator_.SetSoftMaxPacketLength(overhead);
-  EXPECT_EQ(overhead, creator_.max_packet_length());
-  const std::string data = "crypto data";
-  QuicFrame frame;
-  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
-    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
-        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), data,
-        kOffset, false, true, NOT_RETRANSMISSION, &frame));
-    size_t bytes_consumed = frame.stream_frame.data_length;
-    EXPECT_LT(0u, bytes_consumed);
-  } else {
-    producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
-    ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
-        ENCRYPTION_INITIAL, data.length(), kOffset,
-        /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
-    size_t bytes_consumed = frame.crypto_frame->data_length;
-    EXPECT_LT(0u, bytes_consumed);
-  }
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
-  creator_.FlushCurrentPacket();
-
-  // Verify ACK frame can be consumed.
-  creator_.SetSoftMaxPacketLength(overhead);
-  EXPECT_EQ(overhead, creator_.max_packet_length());
-  QuicAckFrame ack_frame(InitAckFrame(10u));
-  EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-}
-
-TEST_P(QuicPacketCreatorTest,
-       ChangingEncryptionLevelRemovesSoftMaxPacketLength) {
-  if (!client_framer_.version().CanSendCoalescedPackets()) {
-    return;
-  }
-  // First set encryption level to forward secure which has the shortest header.
-  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-  const QuicByteCount previous_max_packet_length = creator_.max_packet_length();
-  const size_t min_acceptable_packet_size =
-      GetPacketHeaderOverhead(client_framer_.transport_version()) +
-      QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
-      GetEncryptionOverhead();
-  // Then set the soft max packet length to the lowest allowed value.
-  creator_.SetSoftMaxPacketLength(min_acceptable_packet_size);
-  // Make sure that the low value was accepted.
-  EXPECT_EQ(creator_.max_packet_length(), min_acceptable_packet_size);
-  // Now set the encryption level to handshake which increases the header size.
-  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
-  // Make sure that adding a frame removes the the soft max packet length.
-  QuicAckFrame ack_frame(InitAckFrame(1));
-  frames_.push_back(QuicFrame(&ack_frame));
-  SerializedPacket serialized = SerializeAllFrames(frames_);
-  EXPECT_EQ(serialized.encryption_level, ENCRYPTION_HANDSHAKE);
-  EXPECT_EQ(creator_.max_packet_length(), previous_max_packet_length);
-}
-
-class MockDelegate : public QuicPacketCreator::DelegateInterface {
- public:
-  MockDelegate() {}
-  MockDelegate(const MockDelegate&) = delete;
-  MockDelegate& operator=(const MockDelegate&) = delete;
-  ~MockDelegate() override {}
-
-  MOCK_METHOD(bool,
-              ShouldGeneratePacket,
-              (HasRetransmittableData retransmittable, IsHandshake handshake),
-              (override));
-  MOCK_METHOD(const QuicFrames,
-              MaybeBundleAckOpportunistically,
-              (),
-              (override));
-  MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
-  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
-  MOCK_METHOD(void,
-              OnUnrecoverableError,
-              (QuicErrorCode, const std::string&),
-              (override));
-  MOCK_METHOD(SerializedPacketFate,
-              GetSerializedPacketFate,
-              (bool, EncryptionLevel),
-              (override));
-
-  void SetCanWriteAnything() {
-    EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true));
-    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
-        .WillRepeatedly(Return(true));
-  }
-
-  void SetCanNotWrite() {
-    EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
-        .WillRepeatedly(Return(false));
-    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
-        .WillRepeatedly(Return(false));
-  }
-
-  // Use this when only ack frames should be allowed to be written.
-  void SetCanWriteOnlyNonRetransmittable() {
-    EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
-        .WillRepeatedly(Return(false));
-    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
-        .WillRepeatedly(Return(true));
-  }
-};
-
-// Simple struct for describing the contents of a packet.
-// Useful in conjunction with a SimpleQuicFrame for validating that a packet
-// contains the expected frames.
-struct PacketContents {
-  PacketContents()
-      : num_ack_frames(0),
-        num_connection_close_frames(0),
-        num_goaway_frames(0),
-        num_rst_stream_frames(0),
-        num_stop_waiting_frames(0),
-        num_stream_frames(0),
-        num_crypto_frames(0),
-        num_ping_frames(0),
-        num_mtu_discovery_frames(0),
-        num_padding_frames(0) {}
-
-  size_t num_ack_frames;
-  size_t num_connection_close_frames;
-  size_t num_goaway_frames;
-  size_t num_rst_stream_frames;
-  size_t num_stop_waiting_frames;
-  size_t num_stream_frames;
-  size_t num_crypto_frames;
-  size_t num_ping_frames;
-  size_t num_mtu_discovery_frames;
-  size_t num_padding_frames;
-};
-
-class MultiplePacketsTestPacketCreator : public QuicPacketCreator {
- public:
-  MultiplePacketsTestPacketCreator(
-      QuicConnectionId connection_id,
-      QuicFramer* framer,
-      QuicRandom* random_generator,
-      QuicPacketCreator::DelegateInterface* delegate,
-      SimpleDataProducer* producer)
-      : QuicPacketCreator(connection_id, framer, random_generator, delegate),
-        ack_frame_(InitAckFrame(1)),
-        delegate_(static_cast<MockDelegate*>(delegate)),
-        producer_(producer) {}
-
-  bool ConsumeRetransmittableControlFrame(const QuicFrame& frame,
-                                          bool bundle_ack) {
-    if (!has_ack()) {
-      QuicFrames frames;
-      if (bundle_ack) {
-        frames.push_back(QuicFrame(&ack_frame_));
-      }
-      if (delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                          NOT_HANDSHAKE)) {
-        EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically())
-            .WillOnce(Return(frames));
-      }
-    }
-    return QuicPacketCreator::ConsumeRetransmittableControlFrame(frame);
-  }
-
-  QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
-                                       absl::string_view data) {
-    // Save data before data is consumed.
-    if (!data.empty()) {
-      producer_->SaveStreamData(id, data);
-    }
-    return QuicPacketCreator::ConsumeDataFastPath(id, data.length(),
-                                                  /* offset = */ 0,
-                                                  /* fin = */ true, 0);
-  }
-
-  QuicConsumedData ConsumeData(QuicStreamId id, absl::string_view data,
-                               QuicStreamOffset offset,
-                               StreamSendingState state) {
-    // Save data before data is consumed.
-    if (!data.empty()) {
-      producer_->SaveStreamData(id, data);
-    }
-    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                                      NOT_HANDSHAKE)) {
-      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
-    }
-    return QuicPacketCreator::ConsumeData(id, data.length(), offset, state);
-  }
-
-  MessageStatus AddMessageFrame(QuicMessageId message_id,
-                                quiche::QuicheMemSlice message) {
-    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                                      NOT_HANDSHAKE)) {
-      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
-    }
-    return QuicPacketCreator::AddMessageFrame(message_id,
-                                              absl::MakeSpan(&message, 1));
-  }
-
-  size_t ConsumeCryptoData(EncryptionLevel level,
-                           absl::string_view data,
-                           QuicStreamOffset offset) {
-    producer_->SaveCryptoData(level, offset, data);
-    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                                      NOT_HANDSHAKE)) {
-      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
-    }
-    return QuicPacketCreator::ConsumeCryptoData(level, data.length(), offset);
-  }
-
-  QuicAckFrame ack_frame_;
-  MockDelegate* delegate_;
-  SimpleDataProducer* producer_;
-};
-
-class QuicPacketCreatorMultiplePacketsTest : public QuicTest {
- public:
-  QuicPacketCreatorMultiplePacketsTest()
-      : framer_(AllSupportedVersions(),
-                QuicTime::Zero(),
-                Perspective::IS_CLIENT,
-                kQuicDefaultConnectionIdLength),
-        creator_(TestConnectionId(),
-                 &framer_,
-                 &random_creator_,
-                 &delegate_,
-                 &producer_),
-        ack_frame_(InitAckFrame(1)) {
-    EXPECT_CALL(delegate_, GetPacketBuffer())
-        .WillRepeatedly(Return(QuicPacketBuffer()));
-    EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
-        .WillRepeatedly(Return(SEND_TO_WRITER));
-    creator_.SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
-    framer_.set_data_producer(&producer_);
-    if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) {
-      simple_framer_.framer()->InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
-    }
-    creator_.AttachPacketFlusher();
-  }
-
-  ~QuicPacketCreatorMultiplePacketsTest() override {}
-
-  void SavePacket(SerializedPacket packet) {
-    QUICHE_DCHECK(packet.release_encrypted_buffer == nullptr);
-    packet.encrypted_buffer = CopyBuffer(packet);
-    packet.release_encrypted_buffer = [](const char* p) { delete[] p; };
-    packets_.push_back(std::move(packet));
-  }
-
- protected:
-  QuicRstStreamFrame* CreateRstStreamFrame() {
-    return new QuicRstStreamFrame(1, 1, QUIC_STREAM_NO_ERROR, 0);
-  }
-
-  QuicGoAwayFrame* CreateGoAwayFrame() {
-    return new QuicGoAwayFrame(2, QUIC_NO_ERROR, 1, std::string());
-  }
-
-  void CheckPacketContains(const PacketContents& contents,
-                           size_t packet_index) {
-    ASSERT_GT(packets_.size(), packet_index);
-    const SerializedPacket& packet = packets_[packet_index];
-    size_t num_retransmittable_frames =
-        contents.num_connection_close_frames + contents.num_goaway_frames +
-        contents.num_rst_stream_frames + contents.num_stream_frames +
-        contents.num_crypto_frames + contents.num_ping_frames;
-    size_t num_frames =
-        contents.num_ack_frames + contents.num_stop_waiting_frames +
-        contents.num_mtu_discovery_frames + contents.num_padding_frames +
-        num_retransmittable_frames;
-
-    if (num_retransmittable_frames == 0) {
-      ASSERT_TRUE(packet.retransmittable_frames.empty());
-    } else {
-      ASSERT_FALSE(packet.retransmittable_frames.empty());
-      EXPECT_EQ(num_retransmittable_frames,
-                packet.retransmittable_frames.size());
-    }
-
-    ASSERT_TRUE(packet.encrypted_buffer != nullptr);
-    ASSERT_TRUE(simple_framer_.ProcessPacket(
-        QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
-    size_t num_padding_frames = 0;
-    if (contents.num_padding_frames == 0) {
-      num_padding_frames = simple_framer_.padding_frames().size();
-    }
-    EXPECT_EQ(num_frames + num_padding_frames, simple_framer_.num_frames());
-    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
-    EXPECT_EQ(contents.num_connection_close_frames,
-              simple_framer_.connection_close_frames().size());
-    EXPECT_EQ(contents.num_goaway_frames,
-              simple_framer_.goaway_frames().size());
-    EXPECT_EQ(contents.num_rst_stream_frames,
-              simple_framer_.rst_stream_frames().size());
-    EXPECT_EQ(contents.num_stream_frames,
-              simple_framer_.stream_frames().size());
-    EXPECT_EQ(contents.num_crypto_frames,
-              simple_framer_.crypto_frames().size());
-    EXPECT_EQ(contents.num_stop_waiting_frames,
-              simple_framer_.stop_waiting_frames().size());
-    if (contents.num_padding_frames != 0) {
-      EXPECT_EQ(contents.num_padding_frames,
-                simple_framer_.padding_frames().size());
-    }
-
-    // From the receiver's perspective, MTU discovery frames are ping frames.
-    EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames,
-              simple_framer_.ping_frames().size());
-  }
-
-  void CheckPacketHasSingleStreamFrame(size_t packet_index) {
-    ASSERT_GT(packets_.size(), packet_index);
-    const SerializedPacket& packet = packets_[packet_index];
-    ASSERT_FALSE(packet.retransmittable_frames.empty());
-    EXPECT_EQ(1u, packet.retransmittable_frames.size());
-    ASSERT_TRUE(packet.encrypted_buffer != nullptr);
-    ASSERT_TRUE(simple_framer_.ProcessPacket(
-        QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
-    EXPECT_EQ(1u, simple_framer_.num_frames());
-    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
-  }
-
-  void CheckAllPacketsHaveSingleStreamFrame() {
-    for (size_t i = 0; i < packets_.size(); i++) {
-      CheckPacketHasSingleStreamFrame(i);
-    }
-  }
-
-  QuicFramer framer_;
-  MockRandom random_creator_;
-  StrictMock<MockDelegate> delegate_;
-  MultiplePacketsTestPacketCreator creator_;
-  SimpleQuicFramer simple_framer_;
-  std::vector<SerializedPacket> packets_;
-  QuicAckFrame ack_frame_;
-  struct iovec iov_;
-  quiche::SimpleBufferAllocator allocator_;
-
- private:
-  std::unique_ptr<char[]> data_array_;
-  SimpleDataProducer producer_;
-};
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_NotWritable) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/false);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-  delete rst_frame;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       WrongEncryptionLevelForStreamDataFastPath) {
-  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
-  delegate_.SetCanWriteAnything();
-  const std::string data(10000, '?');
-  EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
-  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
-  EXPECT_QUIC_BUG(creator_.ConsumeDataFastPath(
-                      QuicUtils::GetFirstBidirectionalStreamId(
-                          framer_.transport_version(), Perspective::IS_CLIENT),
-                      data),
-                  "");
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_OnlyAckWritable) {
-  delegate_.SetCanWriteOnlyNonRetransmittable();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/false);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-  delete rst_frame;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       AddControlFrame_WritableAndShouldNotFlush) {
-  delegate_.SetCanWriteAnything();
-
-  creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
-                                              /*bundle_ack=*/false);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       AddControlFrame_NotWritableBatchThenFlush) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/false);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-  delete rst_frame;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       AddControlFrame_WritableAndShouldFlush) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
-                                              /*bundle_ack=*/false);
-  creator_.Flush();
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_rst_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeCryptoData) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  std::string data = "crypto data";
-  size_t consumed_bytes =
-      creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  creator_.Flush();
-  EXPECT_EQ(data.length(), consumed_bytes);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_crypto_frames = 1;
-  contents.num_padding_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConsumeCryptoDataCheckShouldGeneratePacket) {
-  delegate_.SetCanNotWrite();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
-  std::string data = "crypto data";
-  size_t consumed_bytes =
-      creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  creator_.Flush();
-  EXPECT_EQ(0u, consumed_bytes);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) {
-  delegate_.SetCanNotWrite();
-
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, FIN);
-  EXPECT_EQ(0u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConsumeData_WritableAndShouldNotFlush) {
-  delegate_.SetCanWriteAnything();
-
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConsumeData_WritableAndShouldFlush) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, FIN);
-  creator_.Flush();
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-// Test the behavior of ConsumeData when the data consumed is for the crypto
-// handshake stream.  Ensure that the packet is always sent and padded even if
-// the creator operates in batch mode.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_Handshake) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  const std::string data = "foo bar";
-  size_t consumed_bytes = 0;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    consumed_bytes = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  } else {
-    consumed_bytes =
-        creator_
-            .ConsumeData(
-                QuicUtils::GetCryptoStreamId(framer_.transport_version()), data,
-                0, NO_FIN)
-            .bytes_consumed;
-  }
-  EXPECT_EQ(7u, consumed_bytes);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    contents.num_crypto_frames = 1;
-  } else {
-    contents.num_stream_frames = 1;
-  }
-  contents.num_padding_frames = 1;
-  CheckPacketContains(contents, 0);
-
-  ASSERT_EQ(1u, packets_.size());
-  ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length());
-  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
-}
-
-// Test the behavior of ConsumeData when the data is for the crypto handshake
-// stream, but padding is disabled.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConsumeData_Handshake_PaddingDisabled) {
-  creator_.set_fully_pad_crypto_handshake_packets(false);
-
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  const std::string data = "foo";
-  size_t bytes_consumed = 0;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    bytes_consumed = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  } else {
-    bytes_consumed =
-        creator_
-            .ConsumeData(
-                QuicUtils::GetCryptoStreamId(framer_.transport_version()), data,
-                0, NO_FIN)
-            .bytes_consumed;
-  }
-  EXPECT_EQ(3u, bytes_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    contents.num_crypto_frames = 1;
-  } else {
-    contents.num_stream_frames = 1;
-  }
-  contents.num_padding_frames = 0;
-  CheckPacketContains(contents, 0);
-
-  ASSERT_EQ(1u, packets_.size());
-
-  // Packet is not fully padded, but we want to future packets to be larger.
-  ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length());
-  size_t expected_packet_length = 27;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    // The framing of CRYPTO frames is slightly different than that of stream
-    // frames, so the expected packet length differs slightly.
-    expected_packet_length = 28;
-  }
-  if (framer_.version().HasHeaderProtection()) {
-    expected_packet_length = 29;
-  }
-  EXPECT_EQ(expected_packet_length, packets_[0].encrypted_length);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_EmptyData) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_QUIC_BUG(creator_.ConsumeData(
-                      QuicUtils::QuicUtils::GetFirstBidirectionalStreamId(
-                          framer_.transport_version(), Perspective::IS_CLIENT),
-                      {}, 0, NO_FIN),
-                  "Attempt to consume empty data without FIN.");
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
-  delegate_.SetCanWriteAnything();
-
-  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
-                           framer_.transport_version(), Perspective::IS_CLIENT),
-                       "foo", 0, FIN);
-  QuicConsumedData consumed = creator_.ConsumeData(3, "quux", 3, NO_FIN);
-  EXPECT_EQ(4u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_BatchOperations) {
-  delegate_.SetCanWriteAnything();
-
-  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
-                           framer_.transport_version(), Perspective::IS_CLIENT),
-                       "foo", 0, NO_FIN);
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "quux", 3, FIN);
-  EXPECT_EQ(4u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  // Now both frames will be flushed out.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  creator_.Flush();
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConsumeData_FramesPreviouslyQueued) {
-  // Set the packet size be enough for two stream frames with 0 stream offset,
-  // but not enough for a stream frame of 0 offset and one with non-zero offset.
-  size_t length =
-      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
-      GetPacketHeaderSize(
-          framer_.transport_version(),
-          creator_.GetDestinationConnectionIdLength(),
-          creator_.GetSourceConnectionIdLength(),
-          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-          !kIncludeDiversificationNonce,
-          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
-          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
-      // Add an extra 3 bytes for the payload and 1 byte so
-      // BytesFree is larger than the GetMinStreamFrameSize.
-      QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0,
-                                        false, 3) +
-      3 +
-      QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, true,
-                                        1) +
-      1;
-  creator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  {
-    InSequence dummy;
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(
-            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(
-            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  }
-  // Queue enough data to prevent a stream frame with a non-zero offset from
-  // fitting.
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, NO_FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  // This frame will not fit with the existing frame, causing the queued frame
-  // to be serialized, and it will be added to a new open packet.
-  consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "bar", 3, FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  creator_.FlushCurrentPacket();
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-  CheckPacketContains(contents, 1);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataFastPath) {
-  delegate_.SetCanWriteAnything();
-  creator_.SetTransmissionType(LOSS_RETRANSMISSION);
-
-  const std::string data(10000, '?');
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeDataFastPath(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data);
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-  EXPECT_FALSE(packets_.empty());
-  SerializedPacket& packet = packets_.back();
-  EXPECT_TRUE(!packet.retransmittable_frames.empty());
-  EXPECT_EQ(LOSS_RETRANSMISSION, packet.transmission_type);
-  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-  const QuicStreamFrame& stream_frame =
-      packet.retransmittable_frames.front().stream_frame;
-  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLarge) {
-  delegate_.SetCanWriteAnything();
-
-  const std::string data(10000, '?');
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data, 0, FIN);
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-  EXPECT_FALSE(packets_.empty());
-  SerializedPacket& packet = packets_.back();
-  EXPECT_TRUE(!packet.retransmittable_frames.empty());
-  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-  const QuicStreamFrame& stream_frame =
-      packet.retransmittable_frames.front().stream_frame;
-  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckFalse) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool success =
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/true);
-  EXPECT_FALSE(success);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  delegate_.SetCanWriteAnything();
-
-  creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                              /*bundle_ack=*/false);
-
-  const std::string data(10000, '?');
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
-                                              /*bundle_ack=*/true);
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data, 0, FIN);
-  creator_.Flush();
-
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  EXPECT_FALSE(packets_.empty());
-  SerializedPacket& packet = packets_.back();
-  EXPECT_TRUE(!packet.retransmittable_frames.empty());
-  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-  const QuicStreamFrame& stream_frame =
-      packet.retransmittable_frames.front().stream_frame;
-  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckTrue) {
-  delegate_.SetCanNotWrite();
-  delegate_.SetCanWriteAnything();
-
-  const std::string data(10000, '?');
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data, 0, FIN);
-  creator_.Flush();
-
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  EXPECT_FALSE(packets_.empty());
-  SerializedPacket& packet = packets_.back();
-  EXPECT_TRUE(!packet.retransmittable_frames.empty());
-  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-  const QuicStreamFrame& stream_frame =
-      packet.retransmittable_frames.front().stream_frame;
-  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/true);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3));
-
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_TRUE(
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/false));
-  // Send some data and a control frame
-  creator_.ConsumeData(3, "quux", 0, NO_FIN);
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()),
-                                                /*bundle_ack=*/false);
-  }
-  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(3));
-
-  // All five frames will be flushed out in a single packet.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  creator_.Flush();
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3));
-
-  PacketContents contents;
-  // ACK will be flushed by connection.
-  contents.num_ack_frames = 0;
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    contents.num_goaway_frames = 1;
-  } else {
-    contents.num_goaway_frames = 0;
-  }
-  contents.num_rst_stream_frames = 1;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations2) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool success =
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/true);
-  EXPECT_FALSE(success);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  delegate_.SetCanWriteAnything();
-
-  {
-    InSequence dummy;
-    // All five frames will be flushed out in a single packet
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(
-            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(
-            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  }
-  EXPECT_TRUE(
-      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                  /*bundle_ack=*/false));
-  // Send enough data to exceed one packet
-  size_t data_len = kDefaultMaxPacketSize + 100;
-  const std::string data(data_len, '?');
-  QuicConsumedData consumed = creator_.ConsumeData(3, data, 0, FIN);
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()),
-                                                /*bundle_ack=*/false);
-  }
-
-  creator_.Flush();
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // The first packet should have the queued data and part of the stream data.
-  PacketContents contents;
-  // ACK will be sent by connection.
-  contents.num_ack_frames = 0;
-  contents.num_rst_stream_frames = 1;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-
-  // The second should have the remainder of the stream data.
-  PacketContents contents2;
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    contents2.num_goaway_frames = 1;
-  } else {
-    contents2.num_goaway_frames = 0;
-  }
-  contents2.num_stream_frames = 1;
-  CheckPacketContains(contents2, 1);
-}
-
-// Regression test of b/120493795.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, PacketTransmissionType) {
-  delegate_.SetCanWriteAnything();
-
-  // The first ConsumeData will fill the packet without flush.
-  creator_.SetTransmissionType(LOSS_RETRANSMISSION);
-
-  size_t data_len = 1224;
-  const std::string data(data_len, '?');
-  QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId(
-      framer_.transport_version(), Perspective::IS_CLIENT);
-  QuicConsumedData consumed = creator_.ConsumeData(stream1_id, data, 0, NO_FIN);
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  ASSERT_EQ(0u, creator_.BytesFree())
-      << "Test setup failed: Please increase data_len to "
-      << data_len + creator_.BytesFree() << " bytes.";
-
-  // The second ConsumeData can not be added to the packet and will flush.
-  creator_.SetTransmissionType(NOT_RETRANSMISSION);
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  QuicStreamId stream2_id = stream1_id + 4;
-
-  consumed = creator_.ConsumeData(stream2_id, data, 0, NO_FIN);
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-
-  // Ensure the packet is successfully created.
-  ASSERT_EQ(1u, packets_.size());
-  ASSERT_TRUE(packets_[0].encrypted_buffer);
-  ASSERT_EQ(1u, packets_[0].retransmittable_frames.size());
-  EXPECT_EQ(stream1_id,
-            packets_[0].retransmittable_frames[0].stream_frame.stream_id);
-
-  // Since the second frame was not added, the packet's transmission type
-  // should be the first frame's type.
-  EXPECT_EQ(packets_[0].transmission_type, LOSS_RETRANSMISSION);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, TestConnectionIdLength) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  creator_.SetServerConnectionIdLength(0);
-  EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
-            creator_.GetDestinationConnectionIdLength());
-
-  for (size_t i = 1; i < 10; i++) {
-    creator_.SetServerConnectionIdLength(i);
-    if (framer_.version().HasIetfInvariantHeader()) {
-      EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
-                creator_.GetDestinationConnectionIdLength());
-    } else {
-      EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID,
-                creator_.GetDestinationConnectionIdLength());
-    }
-  }
-}
-
-// Test whether SetMaxPacketLength() works in the situation when the queue is
-// empty, and we send three packets worth of data.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Initial) {
-  delegate_.SetCanWriteAnything();
-
-  // Send enough data for three packets.
-  size_t data_len = 3 * kDefaultMaxPacketSize + 1;
-  size_t packet_len = kDefaultMaxPacketSize + 100;
-  ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
-  creator_.SetMaxPacketLength(packet_len);
-  EXPECT_EQ(packet_len, creator_.max_packet_length());
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .Times(3)
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  const std::string data(data_len, '?');
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data,
-      /*offset=*/0, FIN);
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // We expect three packets, and first two of them have to be of packet_len
-  // size.  We check multiple packets (instead of just one) because we want to
-  // ensure that |max_packet_length_| does not get changed incorrectly by the
-  // creator after first packet is serialized.
-  ASSERT_EQ(3u, packets_.size());
-  EXPECT_EQ(packet_len, packets_[0].encrypted_length);
-  EXPECT_EQ(packet_len, packets_[1].encrypted_length);
-  CheckAllPacketsHaveSingleStreamFrame();
-}
-
-// Test whether SetMaxPacketLength() works in the situation when we first write
-// data, then change packet size, then write data again.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Middle) {
-  delegate_.SetCanWriteAnything();
-
-  // We send enough data to overflow default packet length, but not the altered
-  // one.
-  size_t data_len = kDefaultMaxPacketSize;
-  size_t packet_len = kDefaultMaxPacketSize + 100;
-  ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
-
-  // We expect to see three packets in total.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .Times(3)
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  // Send two packets before packet size change.
-  const std::string data(data_len, '?');
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data,
-      /*offset=*/0, NO_FIN);
-  creator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // Make sure we already have two packets.
-  ASSERT_EQ(2u, packets_.size());
-
-  // Increase packet size.
-  creator_.SetMaxPacketLength(packet_len);
-  EXPECT_EQ(packet_len, creator_.max_packet_length());
-
-  // Send a packet after packet size change.
-  creator_.AttachPacketFlusher();
-  consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data, data_len, FIN);
-  creator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // We expect first data chunk to get fragmented, but the second one to fit
-  // into a single packet.
-  ASSERT_EQ(3u, packets_.size());
-  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
-  EXPECT_LE(kDefaultMaxPacketSize, packets_[2].encrypted_length);
-  CheckAllPacketsHaveSingleStreamFrame();
-}
-
-// Test whether SetMaxPacketLength() works correctly when we force the change of
-// the packet size in the middle of the batched packet.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       SetMaxPacketLength_MidpacketFlush) {
-  delegate_.SetCanWriteAnything();
-
-  size_t first_write_len = kDefaultMaxPacketSize / 2;
-  size_t packet_len = kDefaultMaxPacketSize + 100;
-  size_t second_write_len = packet_len + 1;
-  ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
-
-  // First send half of the packet worth of data.  We are in the batch mode, so
-  // should not cause packet serialization.
-  const std::string first_write(first_write_len, '?');
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      first_write,
-      /*offset=*/0, NO_FIN);
-  EXPECT_EQ(first_write_len, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  // Make sure we have no packets so far.
-  ASSERT_EQ(0u, packets_.size());
-
-  // Expect a packet to be flushed.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  // Increase packet size after flushing all frames.
-  // Ensure it's immediately enacted.
-  creator_.FlushCurrentPacket();
-  creator_.SetMaxPacketLength(packet_len);
-  EXPECT_EQ(packet_len, creator_.max_packet_length());
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // We expect to see exactly one packet serialized after that, because we send
-  // a value somewhat exceeding new max packet size, and the tail data does not
-  // get serialized because we are still in the batch mode.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  // Send a more than a packet worth of data to the same stream.  This should
-  // trigger serialization of one packet, and queue another one.
-  const std::string second_write(second_write_len, '?');
-  consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      second_write,
-      /*offset=*/first_write_len, FIN);
-  EXPECT_EQ(second_write_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  // We expect the first packet to be underfilled, and the second packet be up
-  // to the new max packet size.
-  ASSERT_EQ(2u, packets_.size());
-  EXPECT_GT(kDefaultMaxPacketSize, packets_[0].encrypted_length);
-  EXPECT_EQ(packet_len, packets_[1].encrypted_length);
-
-  CheckAllPacketsHaveSingleStreamFrame();
-}
-
-// Test sending a connectivity probing packet.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       GenerateConnectivityProbingPacket) {
-  delegate_.SetCanWriteAnything();
-
-  std::unique_ptr<SerializedPacket> probing_packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    QuicPathFrameBuffer payload = {
-        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
-    probing_packet =
-        creator_.SerializePathChallengeConnectivityProbingPacket(payload);
-  } else {
-    probing_packet = creator_.SerializeConnectivityProbingPacket();
-  }
-
-  ASSERT_TRUE(simple_framer_.ProcessPacket(QuicEncryptedPacket(
-      probing_packet->encrypted_buffer, probing_packet->encrypted_length)));
-
-  EXPECT_EQ(2u, simple_framer_.num_frames());
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    EXPECT_EQ(1u, simple_framer_.path_challenge_frames().size());
-  } else {
-    EXPECT_EQ(1u, simple_framer_.ping_frames().size());
-  }
-  EXPECT_EQ(1u, simple_framer_.padding_frames().size());
-}
-
-// Test sending an MTU probe, without any surrounding data.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       GenerateMtuDiscoveryPacket_Simple) {
-  delegate_.SetCanWriteAnything();
-
-  const size_t target_mtu = kDefaultMaxPacketSize + 100;
-  static_assert(target_mtu < kMaxOutgoingPacketSize,
-                "The MTU probe used by the test exceeds maximum packet size");
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  creator_.GenerateMtuDiscoveryPacket(target_mtu);
-
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-  ASSERT_EQ(1u, packets_.size());
-  EXPECT_EQ(target_mtu, packets_[0].encrypted_length);
-
-  PacketContents contents;
-  contents.num_mtu_discovery_frames = 1;
-  contents.num_padding_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-// Test sending an MTU probe.  Surround it with data, to ensure that it resets
-// the MTU to the value before the probe was sent.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       GenerateMtuDiscoveryPacket_SurroundedByData) {
-  delegate_.SetCanWriteAnything();
-
-  const size_t target_mtu = kDefaultMaxPacketSize + 100;
-  static_assert(target_mtu < kMaxOutgoingPacketSize,
-                "The MTU probe used by the test exceeds maximum packet size");
-
-  // Send enough data so it would always cause two packets to be sent.
-  const size_t data_len = target_mtu + 1;
-
-  // Send a total of five packets: two packets before the probe, the probe
-  // itself, and two packets after the probe.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .Times(5)
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  // Send data before the MTU probe.
-  const std::string data(data_len, '?');
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data,
-      /*offset=*/0, NO_FIN);
-  creator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // Send the MTU probe.
-  creator_.GenerateMtuDiscoveryPacket(target_mtu);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  // Send data after the MTU probe.
-  creator_.AttachPacketFlusher();
-  consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      data,
-      /*offset=*/data_len, FIN);
-  creator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  ASSERT_EQ(5u, packets_.size());
-  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
-  EXPECT_EQ(target_mtu, packets_[2].encrypted_length);
-  EXPECT_EQ(kDefaultMaxPacketSize, packets_[3].encrypted_length);
-
-  PacketContents probe_contents;
-  probe_contents.num_mtu_discovery_frames = 1;
-  probe_contents.num_padding_frames = 1;
-
-  CheckPacketHasSingleStreamFrame(0);
-  CheckPacketHasSingleStreamFrame(1);
-  CheckPacketContains(probe_contents, 2);
-  CheckPacketHasSingleStreamFrame(3);
-  CheckPacketHasSingleStreamFrame(4);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, DontCrashOnInvalidStopWaiting) {
-  if (VersionSupportsMessageFrames(framer_.transport_version())) {
-    return;
-  }
-  // Test added to ensure the creator does not crash when an invalid frame is
-  // added.  Because this is an indication of internal programming errors,
-  // DFATALs are expected.
-  // A 1 byte packet number length can't encode a gap of 1000.
-  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1000);
-
-  delegate_.SetCanNotWrite();
-  delegate_.SetCanWriteAnything();
-
-  // This will not serialize any packets, because of the invalid frame.
-  EXPECT_CALL(delegate_,
-              OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, _));
-  EXPECT_QUIC_BUG(creator_.Flush(),
-                  "packet_number_length 1 is too small "
-                  "for least_unacked_delta: 1001");
-}
-
-// Regression test for b/31486443.
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       ConnectionCloseFrameLargerThanPacketSize) {
-  delegate_.SetCanWriteAnything();
-  char buf[2000] = {};
-  absl::string_view error_details(buf, 2000);
-  const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR;
-
-  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
-      framer_.transport_version(), kQuicErrorCode, NO_IETF_QUIC_ERROR,
-      std::string(error_details),
-      /*transport_close_frame_type=*/0);
-  creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame),
-                                              /*bundle_ack=*/false);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       RandomPaddingAfterFinSingleStreamSinglePacket) {
-  const QuicByteCount kStreamFramePayloadSize = 100u;
-  char buf[kStreamFramePayloadSize] = {};
-  const QuicStreamId kDataStreamId = 5;
-  // Set the packet size be enough for one stream frame with 0 stream offset and
-  // max size of random padding.
-  size_t length =
-      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
-      GetPacketHeaderSize(
-          framer_.transport_version(),
-          creator_.GetDestinationConnectionIdLength(),
-          creator_.GetSourceConnectionIdLength(),
-          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-          !kIncludeDiversificationNonce,
-          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
-          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
-      QuicFramer::GetMinStreamFrameSize(
-          framer_.transport_version(), kDataStreamId, 0,
-          /*last_frame_in_packet=*/false,
-          kStreamFramePayloadSize + kMaxNumRandomPaddingBytes) +
-      kStreamFramePayloadSize + kMaxNumRandomPaddingBytes;
-  creator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 0,
-      FIN_AND_PADDING);
-  creator_.Flush();
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  EXPECT_EQ(1u, packets_.size());
-  PacketContents contents;
-  // The packet has both stream and padding frames.
-  contents.num_padding_frames = 1;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       RandomPaddingAfterFinSingleStreamMultiplePackets) {
-  const QuicByteCount kStreamFramePayloadSize = 100u;
-  char buf[kStreamFramePayloadSize] = {};
-  const QuicStreamId kDataStreamId = 5;
-  // Set the packet size be enough for one stream frame with 0 stream offset +
-  // 1. One or more packets will accommodate.
-  size_t length =
-      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
-      GetPacketHeaderSize(
-          framer_.transport_version(),
-          creator_.GetDestinationConnectionIdLength(),
-          creator_.GetSourceConnectionIdLength(),
-          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-          !kIncludeDiversificationNonce,
-          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
-          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
-      QuicFramer::GetMinStreamFrameSize(
-          framer_.transport_version(), kDataStreamId, 0,
-          /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
-      kStreamFramePayloadSize + 1;
-  creator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 0,
-      FIN_AND_PADDING);
-  creator_.Flush();
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  EXPECT_LE(1u, packets_.size());
-  PacketContents contents;
-  // The first packet has both stream and padding frames.
-  contents.num_stream_frames = 1;
-  contents.num_padding_frames = 1;
-  CheckPacketContains(contents, 0);
-
-  for (size_t i = 1; i < packets_.size(); ++i) {
-    // Following packets only have paddings.
-    contents.num_stream_frames = 0;
-    contents.num_padding_frames = 1;
-    CheckPacketContains(contents, i);
-  }
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       RandomPaddingAfterFinMultipleStreamsMultiplePackets) {
-  const QuicByteCount kStreamFramePayloadSize = 100u;
-  char buf[kStreamFramePayloadSize] = {};
-  const QuicStreamId kDataStreamId1 = 5;
-  const QuicStreamId kDataStreamId2 = 6;
-  // Set the packet size be enough for first frame with 0 stream offset + second
-  // frame + 1 byte payload. two or more packets will accommodate.
-  size_t length =
-      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
-      GetPacketHeaderSize(
-          framer_.transport_version(),
-          creator_.GetDestinationConnectionIdLength(),
-          creator_.GetSourceConnectionIdLength(),
-          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
-          !kIncludeDiversificationNonce,
-          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
-          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
-          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
-      QuicFramer::GetMinStreamFrameSize(
-          framer_.transport_version(), kDataStreamId1, 0,
-          /*last_frame_in_packet=*/false, kStreamFramePayloadSize) +
-      kStreamFramePayloadSize +
-      QuicFramer::GetMinStreamFrameSize(framer_.transport_version(),
-                                        kDataStreamId1, 0,
-                                        /*last_frame_in_packet=*/false, 1) +
-      1;
-  creator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      kDataStreamId1, absl::string_view(buf, kStreamFramePayloadSize), 0,
-      FIN_AND_PADDING);
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  consumed = creator_.ConsumeData(
-      kDataStreamId2, absl::string_view(buf, kStreamFramePayloadSize), 0,
-      FIN_AND_PADDING);
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  creator_.Flush();
-  EXPECT_FALSE(creator_.HasPendingFrames());
-  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
-
-  EXPECT_LE(2u, packets_.size());
-  PacketContents contents;
-  // The first packet has two stream frames.
-  contents.num_stream_frames = 2;
-  CheckPacketContains(contents, 0);
-
-  // The second packet has one stream frame and padding frames.
-  contents.num_stream_frames = 1;
-  contents.num_padding_frames = 1;
-  CheckPacketContains(contents, 1);
-
-  for (size_t i = 2; i < packets_.size(); ++i) {
-    // Following packets only have paddings.
-    contents.num_stream_frames = 0;
-    contents.num_padding_frames = 1;
-    CheckPacketContains(contents, i);
-  }
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, AddMessageFrame) {
-  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
-    return;
-  }
-  if (framer_.version().UsesTls()) {
-    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
-  }
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-
-  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
-                           framer_.transport_version(), Perspective::IS_CLIENT),
-                       "foo", 0, FIN);
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
-            creator_.AddMessageFrame(1, MemSliceFromString("message")));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  // Add a message which causes the flush of current packet.
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
-            creator_.AddMessageFrame(
-                2, MemSliceFromString(std::string(
-                       creator_.GetCurrentLargestMessagePayload(), 'a'))));
-  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
-
-  // Failed to send messages which cannot fit into one packet.
-  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
-            creator_.AddMessageFrame(
-                3, MemSliceFromString(std::string(
-                       creator_.GetCurrentLargestMessagePayload() + 10, 'a'))));
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ConnectionId) {
-  creator_.SetServerConnectionId(TestConnectionId(0x1337));
-  EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId());
-  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  creator_.SetClientConnectionId(TestConnectionId(0x33));
-  EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId());
-  EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
-}
-
-// Regresstion test for b/159812345.
-TEST_F(QuicPacketCreatorMultiplePacketsTest, ExtraPaddingNeeded) {
-  if (!framer_.version().HasHeaderProtection()) {
-    return;
-  }
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(
-          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
-  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
-                           framer_.transport_version(), Perspective::IS_CLIENT),
-                       "a", 0, FIN);
-  creator_.Flush();
-  ASSERT_FALSE(packets_[0].nonretransmittable_frames.empty());
-  QuicFrame padding = packets_[0].nonretransmittable_frames[0];
-  // Verify stream frame expansion is excluded.
-  padding.padding_frame.num_padding_bytes = 3;
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       PeerAddressContextWithSameAddress) {
-  QuicConnectionId client_connection_id = TestConnectionId(1);
-  QuicConnectionId server_connection_id = TestConnectionId(2);
-  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
-  creator_.SetDefaultPeerAddress(peer_addr);
-  creator_.SetClientConnectionId(client_connection_id);
-  creator_.SetServerConnectionId(server_connection_id);
-  // Send some stream data.
-  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
-      .WillRepeatedly(Return(true));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, NO_FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  {
-    // Set the same address via context which should not trigger flush.
-    QuicPacketCreator::ScopedPeerAddressContext context(
-        &creator_, peer_addr, client_connection_id, server_connection_id,
-        /*update_connection_id=*/true);
-    ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
-    ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
-    EXPECT_TRUE(creator_.HasPendingFrames());
-    // Queue another STREAM_FRAME.
-    QuicConsumedData consumed = creator_.ConsumeData(
-        QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
-                                                 Perspective::IS_CLIENT),
-        "foo", 0, FIN);
-    EXPECT_EQ(3u, consumed.bytes_consumed);
-  }
-  // After exiting the scope, the last queued frame should be flushed.
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke([=](SerializedPacket packet) {
-        EXPECT_EQ(peer_addr, packet.peer_address);
-        ASSERT_EQ(2u, packet.retransmittable_frames.size());
-        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.back().type);
-      }));
-  creator_.FlushCurrentPacket();
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       PeerAddressContextWithDifferentAddress) {
-  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
-  creator_.SetDefaultPeerAddress(peer_addr);
-  // Send some stream data.
-  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
-      .WillRepeatedly(Return(true));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, NO_FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-
-  QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke([=](SerializedPacket packet) {
-        EXPECT_EQ(peer_addr, packet.peer_address);
-        ASSERT_EQ(1u, packet.retransmittable_frames.size());
-        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-      }))
-      .WillOnce(Invoke([=](SerializedPacket packet) {
-        EXPECT_EQ(peer_addr1, packet.peer_address);
-        ASSERT_EQ(1u, packet.retransmittable_frames.size());
-        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-      }));
-  EXPECT_TRUE(creator_.HasPendingFrames());
-  {
-    QuicConnectionId client_connection_id = TestConnectionId(1);
-    QuicConnectionId server_connection_id = TestConnectionId(2);
-    // Set a different address via context which should trigger flush.
-    QuicPacketCreator::ScopedPeerAddressContext context(
-        &creator_, peer_addr1, client_connection_id, server_connection_id,
-        /*update_connection_id=*/true);
-    ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
-    ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
-    EXPECT_FALSE(creator_.HasPendingFrames());
-    // Queue another STREAM_FRAME.
-    QuicConsumedData consumed = creator_.ConsumeData(
-        QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
-                                                 Perspective::IS_CLIENT),
-        "foo", 0, FIN);
-    EXPECT_EQ(3u, consumed.bytes_consumed);
-    EXPECT_TRUE(creator_.HasPendingFrames());
-  }
-  // After exiting the scope, the last queued frame should be flushed.
-  EXPECT_FALSE(creator_.HasPendingFrames());
-}
-
-TEST_F(QuicPacketCreatorMultiplePacketsTest,
-       NestedPeerAddressContextWithDifferentAddress) {
-  QuicConnectionId client_connection_id1 = creator_.GetClientConnectionId();
-  QuicConnectionId server_connection_id1 = creator_.GetServerConnectionId();
-  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
-  creator_.SetDefaultPeerAddress(peer_addr);
-  QuicPacketCreator::ScopedPeerAddressContext context(
-      &creator_, peer_addr, client_connection_id1, server_connection_id1,
-      /*update_connection_id=*/true);
-  ASSERT_EQ(client_connection_id1, creator_.GetClientConnectionId());
-  ASSERT_EQ(server_connection_id1, creator_.GetServerConnectionId());
-
-  // Send some stream data.
-  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
-      .WillRepeatedly(Return(true));
-  QuicConsumedData consumed = creator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      "foo", 0, NO_FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(creator_.HasPendingFrames());
-
-  QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke([=](SerializedPacket packet) {
-        EXPECT_EQ(peer_addr, packet.peer_address);
-        ASSERT_EQ(1u, packet.retransmittable_frames.size());
-        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-
-        QuicConnectionId client_connection_id2 = TestConnectionId(3);
-        QuicConnectionId server_connection_id2 = TestConnectionId(4);
-        // Set up another context with a different address.
-        QuicPacketCreator::ScopedPeerAddressContext context(
-            &creator_, peer_addr1, client_connection_id2, server_connection_id2,
-            /*update_connection_id=*/true);
-        ASSERT_EQ(client_connection_id2, creator_.GetClientConnectionId());
-        ASSERT_EQ(server_connection_id2, creator_.GetServerConnectionId());
-        EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
-            .WillRepeatedly(Return(true));
-        QuicConsumedData consumed = creator_.ConsumeData(
-            QuicUtils::GetFirstBidirectionalStreamId(
-                creator_.transport_version(), Perspective::IS_CLIENT),
-            "foo", 0, NO_FIN);
-        EXPECT_EQ(3u, consumed.bytes_consumed);
-        EXPECT_TRUE(creator_.HasPendingFrames());
-        // This should trigger another OnSerializedPacket() with the 2nd
-        // address.
-        creator_.FlushCurrentPacket();
-      }))
-      .WillOnce(Invoke([=](SerializedPacket packet) {
-        EXPECT_EQ(peer_addr1, packet.peer_address);
-        ASSERT_EQ(1u, packet.retransmittable_frames.size());
-        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
-      }));
-  creator_.FlushCurrentPacket();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_packet_number.cc b/quic/core/quic_packet_number.cc
deleted file mode 100644
index b2821b4..0000000
--- a/quic/core/quic_packet_number.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_number.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-void QuicPacketNumber::Clear() {
-  packet_number_ = UninitializedPacketNumber();
-}
-
-void QuicPacketNumber::UpdateMax(QuicPacketNumber new_value) {
-  if (!new_value.IsInitialized()) {
-    return;
-  }
-  if (!IsInitialized()) {
-    packet_number_ = new_value.ToUint64();
-  } else {
-    packet_number_ = std::max(packet_number_, new_value.ToUint64());
-  }
-}
-
-uint64_t QuicPacketNumber::Hash() const {
-  QUICHE_DCHECK(IsInitialized());
-  return packet_number_;
-}
-
-uint64_t QuicPacketNumber::ToUint64() const {
-  QUICHE_DCHECK(IsInitialized());
-  return packet_number_;
-}
-
-bool QuicPacketNumber::IsInitialized() const {
-  return packet_number_ != UninitializedPacketNumber();
-}
-
-QuicPacketNumber& QuicPacketNumber::operator++() {
-#ifndef NDEBUG
-  QUICHE_DCHECK(IsInitialized());
-  QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
-#endif
-  packet_number_++;
-  return *this;
-}
-
-QuicPacketNumber QuicPacketNumber::operator++(int) {
-#ifndef NDEBUG
-  QUICHE_DCHECK(IsInitialized());
-  QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
-#endif
-  QuicPacketNumber previous(*this);
-  packet_number_++;
-  return previous;
-}
-
-QuicPacketNumber& QuicPacketNumber::operator--() {
-#ifndef NDEBUG
-  QUICHE_DCHECK(IsInitialized());
-  QUICHE_DCHECK_GE(ToUint64(), 1UL);
-#endif
-  packet_number_--;
-  return *this;
-}
-
-QuicPacketNumber QuicPacketNumber::operator--(int) {
-#ifndef NDEBUG
-  QUICHE_DCHECK(IsInitialized());
-  QUICHE_DCHECK_GE(ToUint64(), 1UL);
-#endif
-  QuicPacketNumber previous(*this);
-  packet_number_--;
-  return previous;
-}
-
-QuicPacketNumber& QuicPacketNumber::operator+=(uint64_t delta) {
-#ifndef NDEBUG
-  QUICHE_DCHECK(IsInitialized());
-  QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - ToUint64(), delta);
-#endif
-  packet_number_ += delta;
-  return *this;
-}
-
-QuicPacketNumber& QuicPacketNumber::operator-=(uint64_t delta) {
-#ifndef NDEBUG
-  QUICHE_DCHECK(IsInitialized());
-  QUICHE_DCHECK_GE(ToUint64(), delta);
-#endif
-  packet_number_ -= delta;
-  return *this;
-}
-
-std::string QuicPacketNumber::ToString() const {
-  if (!IsInitialized()) {
-    return "uninitialized";
-  }
-  return absl::StrCat(ToUint64());
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicPacketNumber& p) {
-  os << p.ToString();
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_packet_number.h b/quic/core/quic_packet_number.h
deleted file mode 100644
index affd714..0000000
--- a/quic/core/quic_packet_number.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
-
-#include <limits>
-#include <ostream>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// QuicPacketNumber can either initialized or uninitialized. An initialized
-// packet number is simply an ordinal number. A sentinel value is used to
-// represent an uninitialized packet number.
-class QUIC_EXPORT_PRIVATE QuicPacketNumber {
- public:
-  // Construct an uninitialized packet number.
-  constexpr QuicPacketNumber() : packet_number_(UninitializedPacketNumber()) {}
-
-  // Construct a packet number from uint64_t. |packet_number| cannot equal the
-  // sentinel value.
-  explicit constexpr QuicPacketNumber(uint64_t packet_number)
-      : packet_number_(packet_number) {
-    QUICHE_DCHECK_NE(UninitializedPacketNumber(), packet_number)
-        << "Use default constructor for uninitialized packet number";
-  }
-
-  // The sentinel value representing an uninitialized packet number.
-  static constexpr uint64_t UninitializedPacketNumber() {
-    return std::numeric_limits<uint64_t>::max();
-  }
-
-  // Packet number becomes uninitialized after calling this function.
-  void Clear();
-
-  // Updates this packet number to be |new_value| if it is greater than current
-  // value.
-  void UpdateMax(QuicPacketNumber new_value);
-
-  // REQUIRES: IsInitialized() == true.
-  uint64_t Hash() const;
-
-  // Converts packet number to uint64_t.
-  // REQUIRES: IsInitialized() == true.
-  uint64_t ToUint64() const;
-
-  // Returns true if packet number is considered initialized.
-  bool IsInitialized() const;
-
-  // REQUIRES: IsInitialized() == true && ToUint64() <
-  // numeric_limits<uint64_t>::max() - 1.
-  QuicPacketNumber& operator++();
-  QuicPacketNumber operator++(int);
-  // REQUIRES: IsInitialized() == true && ToUint64() >= 1.
-  QuicPacketNumber& operator--();
-  QuicPacketNumber operator--(int);
-
-  // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
-  // ToUint64() > |delta|.
-  QuicPacketNumber& operator+=(uint64_t delta);
-  // REQUIRES: IsInitialized() == true && ToUint64() >= |delta|.
-  QuicPacketNumber& operator-=(uint64_t delta);
-
-  // Human-readable representation suitable for logging.
-  std::string ToString() const;
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPacketNumber& p);
-
- private:
-  // All following operators REQUIRE operands.Initialized() == true.
-  friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
-  friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
-  friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
-  friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
-  friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
-  friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
-
-  // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() > |delta|.
-  friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
-                                           uint64_t delta);
-  // REQUIRES: lhs.ToUint64() >= |delta|.
-  friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
-                                           uint64_t delta);
-  // REQUIRES: lhs >= rhs.
-  friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
-
-  uint64_t packet_number_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicPacketNumberHash {
- public:
-  uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
-    return packet_number.Hash();
-  }
-};
-
-inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ == rhs.packet_number_;
-}
-
-inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ != rhs.packet_number_;
-}
-
-inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ < rhs.packet_number_;
-}
-
-inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ <= rhs.packet_number_;
-}
-
-inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ > rhs.packet_number_;
-}
-
-inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ >= rhs.packet_number_;
-}
-
-inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
-#ifndef NDEBUG
-  QUICHE_DCHECK(lhs.IsInitialized());
-  QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - lhs.ToUint64(),
-                   delta);
-#endif
-  return QuicPacketNumber(lhs.packet_number_ + delta);
-}
-
-inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
-#ifndef NDEBUG
-  QUICHE_DCHECK(lhs.IsInitialized());
-  QUICHE_DCHECK_GE(lhs.ToUint64(), delta);
-#endif
-  return QuicPacketNumber(lhs.packet_number_ - delta);
-}
-
-inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
-  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
-      << lhs << " vs. " << rhs;
-  return lhs.packet_number_ - rhs.packet_number_;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
diff --git a/quic/core/quic_packet_number_test.cc b/quic/core/quic_packet_number_test.cc
deleted file mode 100644
index b696025..0000000
--- a/quic/core/quic_packet_number_test.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_number.h"
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-TEST(QuicPacketNumberTest, BasicTest) {
-  QuicPacketNumber num;
-  EXPECT_FALSE(num.IsInitialized());
-
-  QuicPacketNumber num2(10);
-  EXPECT_TRUE(num2.IsInitialized());
-  EXPECT_EQ(10u, num2.ToUint64());
-  EXPECT_EQ(10u, num2.Hash());
-  num2.UpdateMax(num);
-  EXPECT_EQ(10u, num2.ToUint64());
-  num2.UpdateMax(QuicPacketNumber(9));
-  EXPECT_EQ(10u, num2.ToUint64());
-  num2.UpdateMax(QuicPacketNumber(11));
-  EXPECT_EQ(11u, num2.ToUint64());
-  num2.Clear();
-  EXPECT_FALSE(num2.IsInitialized());
-  num2.UpdateMax(QuicPacketNumber(9));
-  EXPECT_EQ(9u, num2.ToUint64());
-
-  QuicPacketNumber num4(0);
-  EXPECT_TRUE(num4.IsInitialized());
-  EXPECT_EQ(0u, num4.ToUint64());
-  EXPECT_EQ(0u, num4.Hash());
-  num4.Clear();
-  EXPECT_FALSE(num4.IsInitialized());
-}
-
-TEST(QuicPacketNumberTest, Operators) {
-  QuicPacketNumber num(100);
-  EXPECT_EQ(QuicPacketNumber(100), num++);
-  EXPECT_EQ(QuicPacketNumber(101), num);
-  EXPECT_EQ(QuicPacketNumber(101), num--);
-  EXPECT_EQ(QuicPacketNumber(100), num);
-
-  EXPECT_EQ(QuicPacketNumber(101), ++num);
-  EXPECT_EQ(QuicPacketNumber(100), --num);
-
-  QuicPacketNumber num3(0);
-  EXPECT_EQ(QuicPacketNumber(0), num3++);
-  EXPECT_EQ(QuicPacketNumber(1), num3);
-  EXPECT_EQ(QuicPacketNumber(2), ++num3);
-
-  EXPECT_EQ(QuicPacketNumber(2), num3--);
-  EXPECT_EQ(QuicPacketNumber(1), num3);
-  EXPECT_EQ(QuicPacketNumber(0), --num3);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/core/quic_packet_reader.cc b/quic/core/quic_packet_reader.cc
deleted file mode 100644
index 3a8a9b4..0000000
--- a/quic/core/quic_packet_reader.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_reader.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_process_packet_interface.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-QuicPacketReader::QuicPacketReader()
-    : read_buffers_(kNumPacketsPerReadMmsgCall),
-      read_results_(kNumPacketsPerReadMmsgCall) {
-  QUICHE_DCHECK_EQ(read_buffers_.size(), read_results_.size());
-  for (size_t i = 0; i < read_results_.size(); ++i) {
-    read_results_[i].packet_buffer.buffer = read_buffers_[i].packet_buffer;
-    read_results_[i].packet_buffer.buffer_len =
-        sizeof(read_buffers_[i].packet_buffer);
-
-    read_results_[i].control_buffer.buffer = read_buffers_[i].control_buffer;
-    read_results_[i].control_buffer.buffer_len =
-        sizeof(read_buffers_[i].control_buffer);
-  }
-}
-
-QuicPacketReader::~QuicPacketReader() = default;
-
-bool QuicPacketReader::ReadAndDispatchPackets(
-    int fd,
-    int port,
-    const QuicClock& clock,
-    ProcessPacketInterface* processor,
-    QuicPacketCount* /*packets_dropped*/) {
-  // Reset all read_results for reuse.
-  for (size_t i = 0; i < read_results_.size(); ++i) {
-    read_results_[i].Reset(
-        /*packet_buffer_length=*/sizeof(read_buffers_[i].packet_buffer));
-  }
-
-  // Use clock.Now() as the packet receipt time, the time between packet
-  // arriving at the host and now is considered part of the network delay.
-  QuicTime now = clock.Now();
-
-  size_t packets_read = socket_api_.ReadMultiplePackets(
-      fd,
-      BitMask64(QuicUdpPacketInfoBit::DROPPED_PACKETS,
-                QuicUdpPacketInfoBit::PEER_ADDRESS,
-                QuicUdpPacketInfoBit::V4_SELF_IP,
-                QuicUdpPacketInfoBit::V6_SELF_IP,
-                QuicUdpPacketInfoBit::RECV_TIMESTAMP, QuicUdpPacketInfoBit::TTL,
-                QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER),
-      &read_results_);
-  for (size_t i = 0; i < packets_read; ++i) {
-    auto& result = read_results_[i];
-    if (!result.ok) {
-      QUIC_CODE_COUNT(quic_packet_reader_read_failure);
-      continue;
-    }
-
-    if (!result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
-      QUIC_BUG(quic_bug_10329_1) << "Unable to get peer socket address.";
-      continue;
-    }
-
-    QuicSocketAddress peer_address =
-        result.packet_info.peer_address().Normalized();
-
-    QuicIpAddress self_ip = GetSelfIpFromPacketInfo(
-        result.packet_info, peer_address.host().IsIPv6());
-    if (!self_ip.IsInitialized()) {
-      QUIC_BUG(quic_bug_10329_2) << "Unable to get self IP address.";
-      continue;
-    }
-
-    bool has_ttl = result.packet_info.HasValue(QuicUdpPacketInfoBit::TTL);
-    int ttl = has_ttl ? result.packet_info.ttl() : 0;
-    if (!has_ttl) {
-      QUIC_CODE_COUNT(quic_packet_reader_no_ttl);
-    }
-
-    char* headers = nullptr;
-    size_t headers_length = 0;
-    if (result.packet_info.HasValue(
-            QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
-      headers = result.packet_info.google_packet_headers().buffer;
-      headers_length = result.packet_info.google_packet_headers().buffer_len;
-    } else {
-      QUIC_CODE_COUNT(quic_packet_reader_no_google_packet_header);
-    }
-
-    QuicReceivedPacket packet(
-        result.packet_buffer.buffer, result.packet_buffer.buffer_len, now,
-        /*owns_buffer=*/false, ttl, has_ttl, headers, headers_length,
-        /*owns_header_buffer=*/false);
-
-    QuicSocketAddress self_address(self_ip, port);
-    processor->ProcessPacket(self_address, peer_address, packet);
-  }
-
-  // We may not have read all of the packets available on the socket.
-  return packets_read == kNumPacketsPerReadMmsgCall;
-}
-
-// static
-QuicIpAddress QuicPacketReader::GetSelfIpFromPacketInfo(
-    const QuicUdpPacketInfo& packet_info,
-    bool prefer_v6_ip) {
-  if (prefer_v6_ip) {
-    if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
-      return packet_info.self_v6_ip();
-    }
-    if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
-      return packet_info.self_v4_ip();
-    }
-  } else {
-    if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
-      return packet_info.self_v4_ip();
-    }
-    if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
-      return packet_info.self_v6_ip();
-    }
-  }
-  return QuicIpAddress();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_packet_reader.h b/quic/core/quic_packet_reader.h
deleted file mode 100644
index 1c93722..0000000
--- a/quic/core/quic_packet_reader.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A class to read incoming QUIC packets from the UDP socket.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
-
-#include "absl/base/optimization.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_process_packet_interface.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Read in larger batches to minimize recvmmsg overhead.
-const int kNumPacketsPerReadMmsgCall = 16;
-
-class QUIC_EXPORT_PRIVATE QuicPacketReader {
- public:
-  QuicPacketReader();
-  QuicPacketReader(const QuicPacketReader&) = delete;
-  QuicPacketReader& operator=(const QuicPacketReader&) = delete;
-
-  virtual ~QuicPacketReader();
-
-  // Reads a number of packets from the given fd, and then passes them off to
-  // the PacketProcessInterface.  Returns true if there may be additional
-  // packets available on the socket.
-  // Populates |packets_dropped| if it is non-null and the socket is configured
-  // to track dropped packets and some packets are read.
-  // If the socket has timestamping enabled, the per packet timestamps will be
-  // passed to the processor. Otherwise, |clock| will be used.
-  virtual bool ReadAndDispatchPackets(int fd,
-                                      int port,
-                                      const QuicClock& clock,
-                                      ProcessPacketInterface* processor,
-                                      QuicPacketCount* packets_dropped);
-
- private:
-  // Return the self ip from |packet_info|.
-  // For dual stack sockets, |packet_info| may contain both a v4 and a v6 ip, in
-  // that case, |prefer_v6_ip| is used to determine which one is used as the
-  // return value. If neither v4 nor v6 ip exists, return an uninitialized ip.
-  static QuicIpAddress GetSelfIpFromPacketInfo(
-      const QuicUdpPacketInfo& packet_info,
-      bool prefer_v6_ip);
-
-  struct QUIC_EXPORT_PRIVATE ReadBuffer {
-    ABSL_CACHELINE_ALIGNED char
-        control_buffer[kDefaultUdpPacketControlBufferSize];  // For ancillary
-                                                             // data.
-    ABSL_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize];
-  };
-
-  QuicUdpSocketApi socket_api_;
-  std::vector<ReadBuffer> read_buffers_;
-  QuicUdpSocketApi::ReadPacketResults read_results_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
diff --git a/quic/core/quic_packet_writer.h b/quic/core/quic_packet_writer.h
deleted file mode 100644
index 78b576a..0000000
--- a/quic/core/quic_packet_writer.h
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
-
-#include <cstddef>
-#include <utility>
-
-#include "absl/types/optional.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-struct WriteResult;
-
-struct QUIC_EXPORT_PRIVATE PerPacketOptions {
-  virtual ~PerPacketOptions() {}
-
-  // Returns a heap-allocated copy of |this|.
-  //
-  // The subclass implementation of this method should look like this:
-  //   return std::make_unique<MyAwesomePerPacketOptions>(*this);
-  //
-  // This method is declared pure virtual in order to ensure the subclasses
-  // would not forget to override it.
-  virtual std::unique_ptr<PerPacketOptions> Clone() const = 0;
-
-  // Specifies ideal release time delay for this packet.
-  QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
-  // Whether it is allowed to send this packet without |release_time_delay|.
-  bool allow_burst = false;
-};
-
-// An interface between writers and the entity managing the
-// socket (in our case the QuicDispatcher).  This allows the Dispatcher to
-// control writes, and manage any writers who end up write blocked.
-// A concrete writer works in one of the two modes:
-// - PassThrough mode. This is the default mode. Caller calls WritePacket with
-//   caller-allocated packet buffer. Unless the writer is blocked, each call to
-//   WritePacket triggers a write using the underlying socket API.
-//
-// - Batch mode. In this mode, a call to WritePacket may not cause a packet to
-//   be sent using the underlying socket API. Instead, multiple packets are
-//   saved in the writer's internal buffer until they are flushed. The flush can
-//   be explicit, by calling Flush, or implicit, e.g. by calling
-//   WritePacket when the internal buffer is near full.
-//
-// Buffer management:
-// In Batch mode, a writer manages an internal buffer, which is large enough to
-// hold multiple packets' data. If the caller calls WritePacket with a
-// caller-allocated packet buffer, the writer will memcpy the buffer into the
-// internal buffer. Caller can also avoid this memcpy by:
-// 1. Call GetNextWriteLocation to get a pointer P into the internal buffer.
-// 2. Serialize the packet directly to P.
-// 3. Call WritePacket with P as the |buffer|.
-class QUIC_EXPORT_PRIVATE QuicPacketWriter {
- public:
-  virtual ~QuicPacketWriter() {}
-
-  // PassThrough mode:
-  // Sends the packet out to the peer, with some optional per-packet options.
-  // If the write succeeded, the result's status is WRITE_STATUS_OK and
-  // bytes_written is populated. If the write failed, the result's status is
-  // WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and error_code is populated.
-  //
-  // Batch mode:
-  // If the writer is blocked, return WRITE_STATUS_BLOCKED immediately.
-  // If the packet can be batched with other buffered packets, save the packet
-  // to the internal buffer.
-  // If the packet can not be batched, or the internal buffer is near full after
-  // it is buffered, the internal buffer is flushed to free up space.
-  // Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) on success. When
-  // <bytes_flushed> is zero, it means the packet is buffered and not flushed.
-  // Return WRITE_STATUS_BLOCKED if the packet is not buffered and the socket is
-  // blocked while flushing.
-  // Otherwise return an error status.
-  //
-  // Options must be either null, or created for the particular QuicPacketWriter
-  // implementation. Options may be ignored, depending on the implementation.
-  //
-  // Some comment about memory management if |buffer| was previously acquired
-  // by a call to "GetNextWriteLocation()":
-  //
-  // a) When WRITE_STATUS_OK is returned, the caller expects the writer owns the
-  // packet buffers and they will be released when the write finishes.
-  //
-  // b) When this function returns any status >= WRITE_STATUS_ERROR, the caller
-  // expects the writer releases the buffer (if needed) before the function
-  // returns.
-  //
-  // c) When WRITE_STATUS_BLOCKED is returned, the caller makes a copy of the
-  // buffer and will retry after unblock, so if |payload| is allocated from
-  // GetNextWriteLocation(), it
-  //    1) needs to be released before return, and
-  //    2) the content of |payload| should not change after return.
-  //
-  // d) When WRITE_STATUS_BLOCKED_DATA_BUFFERED is returned, the caller expects
-  // 1) the writer owns the packet buffers, and 2) the writer will re-send the
-  // packet when it unblocks.
-  virtual WriteResult WritePacket(const char* buffer,
-                                  size_t buf_len,
-                                  const QuicIpAddress& self_address,
-                                  const QuicSocketAddress& peer_address,
-                                  PerPacketOptions* options) = 0;
-
-  // Returns true if the network socket is not writable.
-  virtual bool IsWriteBlocked() const = 0;
-
-  // Records that the socket has become writable, for example when an EPOLLOUT
-  // is received or an asynchronous write completes.
-  virtual void SetWritable() = 0;
-
-  // The error code used by the writer to indicate that the write failed due to
-  // supplied packet being too big.  This is equivalent to returning
-  // WRITE_STATUS_MSG_TOO_BIG as a status.
-  virtual absl::optional<int> MessageTooBigErrorCode() const = 0;
-
-  // Returns the maximum size of the packet which can be written using this
-  // writer for the supplied peer address.  This size may actually exceed the
-  // size of a valid QUIC packet.
-  virtual QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& peer_address) const = 0;
-
-  // Returns true if the socket supports release timestamp.
-  virtual bool SupportsReleaseTime() const = 0;
-
-  // True=Batch mode. False=PassThrough mode.
-  virtual bool IsBatchMode() const = 0;
-
-  // PassThrough mode: Return {nullptr, nullptr}
-  //
-  // Batch mode:
-  // Return the QuicPacketBuffer for the next packet. A minimum of
-  // kMaxOutgoingPacketSize is guaranteed to be available from the returned
-  // address. If the internal buffer does not have enough space,
-  // {nullptr, nullptr} is returned. All arguments should be identical to the
-  // follow-up call to |WritePacket|, they are here to allow advanced packet
-  // memory management in packet writers, e.g. one packet buffer pool per
-  // |peer_address|.
-  //
-  // If QuicPacketBuffer.release_buffer is !nullptr, it should be called iff
-  // the caller does not call WritePacket for the returned buffer.
-  virtual QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& self_address,
-      const QuicSocketAddress& peer_address) = 0;
-
-  // PassThrough mode: Return WriteResult(WRITE_STATUS_OK, 0).
-  //
-  // Batch mode:
-  // Try send all buffered packets.
-  // - Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered
-  //   packets were sent successfully.
-  // - Return WRITE_STATUS_BLOCKED if the underlying socket is blocked while
-  //   sending. Some packets may have been sent, packets not sent will stay in
-  //   the internal buffer.
-  // - Return a status >= WRITE_STATUS_ERROR if an error was encuontered while
-  //   sending. As this is not a re-tryable error, any batched packets which
-  //   were on memory acquired via GetNextWriteLocation() should be released and
-  //   the batch should be dropped.
-  virtual WriteResult Flush() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
diff --git a/quic/core/quic_packet_writer_wrapper.cc b/quic/core/quic_packet_writer_wrapper.cc
deleted file mode 100644
index 62ec0cf..0000000
--- a/quic/core/quic_packet_writer_wrapper.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-QuicPacketWriterWrapper::QuicPacketWriterWrapper() = default;
-
-QuicPacketWriterWrapper::~QuicPacketWriterWrapper() {
-  unset_writer();
-}
-
-WriteResult QuicPacketWriterWrapper::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  return writer_->WritePacket(buffer, buf_len, self_address, peer_address,
-                              options);
-}
-
-bool QuicPacketWriterWrapper::IsWriteBlocked() const {
-  return writer_->IsWriteBlocked();
-}
-
-void QuicPacketWriterWrapper::SetWritable() {
-  writer_->SetWritable();
-}
-
-absl::optional<int> QuicPacketWriterWrapper::MessageTooBigErrorCode() const {
-  return writer_->MessageTooBigErrorCode();
-}
-
-QuicByteCount QuicPacketWriterWrapper::GetMaxPacketSize(
-    const QuicSocketAddress& peer_address) const {
-  return writer_->GetMaxPacketSize(peer_address);
-}
-
-bool QuicPacketWriterWrapper::SupportsReleaseTime() const {
-  return writer_->SupportsReleaseTime();
-}
-
-bool QuicPacketWriterWrapper::IsBatchMode() const {
-  return writer_->IsBatchMode();
-}
-
-QuicPacketBuffer QuicPacketWriterWrapper::GetNextWriteLocation(
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address) {
-  return writer_->GetNextWriteLocation(self_address, peer_address);
-}
-
-WriteResult QuicPacketWriterWrapper::Flush() {
-  return writer_->Flush();
-}
-
-void QuicPacketWriterWrapper::set_writer(QuicPacketWriter* writer) {
-  unset_writer();
-  writer_ = writer;
-  owns_writer_ = true;
-}
-
-void QuicPacketWriterWrapper::set_non_owning_writer(QuicPacketWriter* writer) {
-  unset_writer();
-  writer_ = writer;
-  owns_writer_ = false;
-}
-
-void QuicPacketWriterWrapper::unset_writer() {
-  if (owns_writer_) {
-    delete writer_;
-  }
-
-  owns_writer_ = false;
-  writer_ = nullptr;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_packet_writer_wrapper.h b/quic/core/quic_packet_writer_wrapper.h
deleted file mode 100644
index a7f2d01..0000000
--- a/quic/core/quic_packet_writer_wrapper.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "quic/core/quic_packet_writer.h"
-
-namespace quic {
-
-// Wraps a writer object to allow dynamically extending functionality. Use
-// cases: replace writer while dispatcher and connections hold on to the
-// wrapper; mix in monitoring; mix in mocks in unit tests.
-class QUIC_NO_EXPORT QuicPacketWriterWrapper : public QuicPacketWriter {
- public:
-  QuicPacketWriterWrapper();
-  QuicPacketWriterWrapper(const QuicPacketWriterWrapper&) = delete;
-  QuicPacketWriterWrapper& operator=(const QuicPacketWriterWrapper&) = delete;
-  ~QuicPacketWriterWrapper() override;
-
-  // Default implementation of the QuicPacketWriter interface. Passes everything
-  // to |writer_|.
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-  bool IsWriteBlocked() const override;
-  void SetWritable() override;
-  absl::optional<int> MessageTooBigErrorCode() const override;
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& peer_address) const override;
-  bool SupportsReleaseTime() const override;
-  bool IsBatchMode() const override;
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& self_address,
-      const QuicSocketAddress& peer_address) override;
-  WriteResult Flush() override;
-
-  // Takes ownership of |writer|.
-  void set_writer(QuicPacketWriter* writer);
-
-  // Does not take ownership of |writer|.
-  void set_non_owning_writer(QuicPacketWriter* writer);
-
-  virtual void set_peer_address(const QuicSocketAddress& /*peer_address*/) {}
-
-  QuicPacketWriter* writer() { return writer_; }
-
- private:
-  void unset_writer();
-
-  QuicPacketWriter* writer_ = nullptr;
-  bool owns_writer_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc
deleted file mode 100644
index 91840f8..0000000
--- a/quic/core/quic_packets.cc
+++ /dev/null
@@ -1,596 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packets.h"
-
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicConnectionId GetServerConnectionIdAsRecipient(
-    const QuicPacketHeader& header,
-    Perspective perspective) {
-  if (perspective == Perspective::IS_SERVER) {
-    return header.destination_connection_id;
-  }
-  return header.source_connection_id;
-}
-
-QuicConnectionId GetClientConnectionIdAsRecipient(
-    const QuicPacketHeader& header,
-    Perspective perspective) {
-  if (perspective == Perspective::IS_CLIENT) {
-    return header.destination_connection_id;
-  }
-  return header.source_connection_id;
-}
-
-QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
-                                               Perspective perspective) {
-  if (perspective == Perspective::IS_CLIENT) {
-    return header.destination_connection_id;
-  }
-  return header.source_connection_id;
-}
-
-QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
-    const QuicPacketHeader& header,
-    Perspective perspective) {
-  if (perspective == Perspective::IS_CLIENT) {
-    return header.destination_connection_id_included;
-  }
-  return header.source_connection_id_included;
-}
-
-QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
-                                               Perspective perspective) {
-  if (perspective == Perspective::IS_CLIENT) {
-    return header.source_connection_id;
-  }
-  return header.destination_connection_id;
-}
-
-QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
-    const QuicPacketHeader& header,
-    Perspective perspective) {
-  if (perspective == Perspective::IS_CLIENT) {
-    return header.source_connection_id_included;
-  }
-  return header.destination_connection_id_included;
-}
-
-QuicConnectionIdLength GetIncludedConnectionIdLength(
-    QuicConnectionId connection_id,
-    QuicConnectionIdIncluded connection_id_included) {
-  QUICHE_DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
-                connection_id_included == CONNECTION_ID_ABSENT);
-  return connection_id_included == CONNECTION_ID_PRESENT
-             ? static_cast<QuicConnectionIdLength>(connection_id.length())
-             : PACKET_0BYTE_CONNECTION_ID;
-}
-
-QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(
-    const QuicPacketHeader& header) {
-  return GetIncludedConnectionIdLength(
-      header.destination_connection_id,
-      header.destination_connection_id_included);
-}
-
-QuicConnectionIdLength GetIncludedSourceConnectionIdLength(
-    const QuicPacketHeader& header) {
-  return GetIncludedConnectionIdLength(header.source_connection_id,
-                                       header.source_connection_id_included);
-}
-
-size_t GetPacketHeaderSize(QuicTransportVersion version,
-                           const QuicPacketHeader& header) {
-  return GetPacketHeaderSize(
-      version, GetIncludedDestinationConnectionIdLength(header),
-      GetIncludedSourceConnectionIdLength(header), header.version_flag,
-      header.nonce != nullptr, header.packet_number_length,
-      header.retry_token_length_length, header.retry_token.length(),
-      header.length_length);
-}
-
-size_t GetPacketHeaderSize(
-    QuicTransportVersion version,
-    QuicConnectionIdLength destination_connection_id_length,
-    QuicConnectionIdLength source_connection_id_length,
-    bool include_version,
-    bool include_diversification_nonce,
-    QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length) {
-  if (VersionHasIetfInvariantHeader(version)) {
-    if (include_version) {
-      // Long header.
-      size_t size = kPacketHeaderTypeSize + kConnectionIdLengthSize +
-                    destination_connection_id_length +
-                    source_connection_id_length + packet_number_length +
-                    kQuicVersionSize;
-      if (include_diversification_nonce) {
-        size += kDiversificationNonceSize;
-      }
-      if (VersionHasLengthPrefixedConnectionIds(version)) {
-        size += kConnectionIdLengthSize;
-      }
-      QUICHE_DCHECK(
-          QuicVersionHasLongHeaderLengths(version) ||
-          retry_token_length_length + retry_token_length + length_length == 0);
-      if (QuicVersionHasLongHeaderLengths(version)) {
-        size += retry_token_length_length + retry_token_length + length_length;
-      }
-      return size;
-    }
-    // Short header.
-    return kPacketHeaderTypeSize + destination_connection_id_length +
-           packet_number_length;
-  }
-  // Google QUIC versions <= 43 can only carry one connection ID.
-  QUICHE_DCHECK(destination_connection_id_length == 0 ||
-                source_connection_id_length == 0);
-  return kPublicFlagsSize + destination_connection_id_length +
-         source_connection_id_length +
-         (include_version ? kQuicVersionSize : 0) + packet_number_length +
-         (include_diversification_nonce ? kDiversificationNonceSize : 0);
-}
-
-size_t GetStartOfEncryptedData(QuicTransportVersion version,
-                               const QuicPacketHeader& header) {
-  return GetPacketHeaderSize(version, header);
-}
-
-size_t GetStartOfEncryptedData(
-    QuicTransportVersion version,
-    QuicConnectionIdLength destination_connection_id_length,
-    QuicConnectionIdLength source_connection_id_length,
-    bool include_version,
-    bool include_diversification_nonce,
-    QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length) {
-  // Encryption starts before private flags.
-  return GetPacketHeaderSize(
-      version, destination_connection_id_length, source_connection_id_length,
-      include_version, include_diversification_nonce, packet_number_length,
-      retry_token_length_length, retry_token_length, length_length);
-}
-
-QuicPacketHeader::QuicPacketHeader()
-    : destination_connection_id(EmptyQuicConnectionId()),
-      destination_connection_id_included(CONNECTION_ID_PRESENT),
-      source_connection_id(EmptyQuicConnectionId()),
-      source_connection_id_included(CONNECTION_ID_ABSENT),
-      reset_flag(false),
-      version_flag(false),
-      has_possible_stateless_reset_token(false),
-      packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
-      version(UnsupportedQuicVersion()),
-      nonce(nullptr),
-      form(GOOGLE_QUIC_PACKET),
-      long_packet_type(INITIAL),
-      possible_stateless_reset_token({}),
-      retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
-      retry_token(absl::string_view()),
-      length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
-      remaining_packet_length(0) {}
-
-QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
-
-QuicPacketHeader::~QuicPacketHeader() {}
-
-QuicPacketHeader& QuicPacketHeader::operator=(const QuicPacketHeader& other) =
-    default;
-
-QuicPublicResetPacket::QuicPublicResetPacket()
-    : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
-
-QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
-    : connection_id(connection_id), nonce_proof(0) {}
-
-QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
-    : connection_id(EmptyQuicConnectionId()) {}
-
-QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
-    QuicConnectionId connection_id)
-    : connection_id(connection_id) {}
-
-QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
-    const QuicVersionNegotiationPacket& other) = default;
-
-QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
-
-QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
-    : stateless_reset_token({}) {}
-
-QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
-    const QuicPacketHeader& header,
-    StatelessResetToken token)
-    : header(header), stateless_reset_token(token) {}
-
-QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
-    const QuicIetfStatelessResetPacket& other) = default;
-
-QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
-
-std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
-  os << "{ destination_connection_id: " << header.destination_connection_id
-     << " ("
-     << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
-             ? "present"
-             : "absent")
-     << "), source_connection_id: " << header.source_connection_id << " ("
-     << (header.source_connection_id_included == CONNECTION_ID_PRESENT
-             ? "present"
-             : "absent")
-     << "), packet_number_length: "
-     << static_cast<int>(header.packet_number_length)
-     << ", reset_flag: " << header.reset_flag
-     << ", version_flag: " << header.version_flag;
-  if (header.version_flag) {
-    os << ", version: " << ParsedQuicVersionToString(header.version);
-    if (header.long_packet_type != INVALID_PACKET_TYPE) {
-      os << ", long_packet_type: "
-         << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
-    }
-    if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
-      os << ", retry_token_length_length: "
-         << static_cast<int>(header.retry_token_length_length);
-    }
-    if (header.retry_token.length() != 0) {
-      os << ", retry_token_length: " << header.retry_token.length();
-    }
-    if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
-      os << ", length_length: " << static_cast<int>(header.length_length);
-    }
-    if (header.remaining_packet_length != 0) {
-      os << ", remaining_packet_length: " << header.remaining_packet_length;
-    }
-  }
-  if (header.nonce != nullptr) {
-    os << ", diversification_nonce: "
-       << absl::BytesToHexString(
-              absl::string_view(header.nonce->data(), header.nonce->size()));
-  }
-  os << ", packet_number: " << header.packet_number << " }\n";
-  return os;
-}
-
-QuicData::QuicData(const char* buffer, size_t length)
-    : buffer_(buffer), length_(length), owns_buffer_(false) {}
-
-QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
-    : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
-
-QuicData::QuicData(absl::string_view packet_data)
-    : buffer_(packet_data.data()),
-      length_(packet_data.length()),
-      owns_buffer_(false) {}
-
-QuicData::~QuicData() {
-  if (owns_buffer_) {
-    delete[] const_cast<char*>(buffer_);
-  }
-}
-
-QuicPacket::QuicPacket(
-    char* buffer,
-    size_t length,
-    bool owns_buffer,
-    QuicConnectionIdLength destination_connection_id_length,
-    QuicConnectionIdLength source_connection_id_length,
-    bool includes_version,
-    bool includes_diversification_nonce,
-    QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length)
-    : QuicData(buffer, length, owns_buffer),
-      buffer_(buffer),
-      destination_connection_id_length_(destination_connection_id_length),
-      source_connection_id_length_(source_connection_id_length),
-      includes_version_(includes_version),
-      includes_diversification_nonce_(includes_diversification_nonce),
-      packet_number_length_(packet_number_length),
-      retry_token_length_length_(retry_token_length_length),
-      retry_token_length_(retry_token_length),
-      length_length_(length_length) {}
-
-QuicPacket::QuicPacket(QuicTransportVersion /*version*/,
-                       char* buffer,
-                       size_t length,
-                       bool owns_buffer,
-                       const QuicPacketHeader& header)
-    : QuicPacket(buffer,
-                 length,
-                 owns_buffer,
-                 GetIncludedDestinationConnectionIdLength(header),
-                 GetIncludedSourceConnectionIdLength(header),
-                 header.version_flag,
-                 header.nonce != nullptr,
-                 header.packet_number_length,
-                 header.retry_token_length_length,
-                 header.retry_token.length(),
-                 header.length_length) {}
-
-QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
-    : QuicData(buffer, length) {}
-
-QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
-                                         size_t length,
-                                         bool owns_buffer)
-    : QuicData(buffer, length, owns_buffer) {}
-
-QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data)
-    : QuicData(data) {}
-
-std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
-  char* buffer = new char[this->length()];
-  memcpy(buffer, this->data(), this->length());
-  return std::make_unique<QuicEncryptedPacket>(buffer, this->length(), true);
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
-  os << s.length() << "-byte data";
-  return os;
-}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
-                                       size_t length,
-                                       QuicTime receipt_time)
-    : QuicReceivedPacket(buffer,
-                         length,
-                         receipt_time,
-                         false /* owns_buffer */) {}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
-                                       size_t length,
-                                       QuicTime receipt_time,
-                                       bool owns_buffer)
-    : QuicReceivedPacket(buffer,
-                         length,
-                         receipt_time,
-                         owns_buffer,
-                         0 /* ttl */,
-                         true /* ttl_valid */) {}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
-                                       size_t length,
-                                       QuicTime receipt_time,
-                                       bool owns_buffer,
-                                       int ttl,
-                                       bool ttl_valid)
-    : quic::QuicReceivedPacket(buffer,
-                               length,
-                               receipt_time,
-                               owns_buffer,
-                               ttl,
-                               ttl_valid,
-                               nullptr /* packet_headers */,
-                               0 /* headers_length */,
-                               false /* owns_header_buffer */) {}
-
-QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
-                                       size_t length,
-                                       QuicTime receipt_time,
-                                       bool owns_buffer,
-                                       int ttl,
-                                       bool ttl_valid,
-                                       char* packet_headers,
-                                       size_t headers_length,
-                                       bool owns_header_buffer)
-    : QuicEncryptedPacket(buffer, length, owns_buffer),
-      receipt_time_(receipt_time),
-      ttl_(ttl_valid ? ttl : -1),
-      packet_headers_(packet_headers),
-      headers_length_(headers_length),
-      owns_header_buffer_(owns_header_buffer) {}
-
-QuicReceivedPacket::~QuicReceivedPacket() {
-  if (owns_header_buffer_) {
-    delete[] static_cast<char*>(packet_headers_);
-  }
-}
-
-std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
-  char* buffer = new char[this->length()];
-  memcpy(buffer, this->data(), this->length());
-  if (this->packet_headers()) {
-    char* headers_buffer = new char[this->headers_length()];
-    memcpy(headers_buffer, this->packet_headers(), this->headers_length());
-    return std::make_unique<QuicReceivedPacket>(
-        buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
-        headers_buffer, this->headers_length(), true);
-  }
-
-  return std::make_unique<QuicReceivedPacket>(
-      buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
-  os << s.length() << "-byte data";
-  return os;
-}
-
-absl::string_view QuicPacket::AssociatedData(
-    QuicTransportVersion version) const {
-  return absl::string_view(
-      data(),
-      GetStartOfEncryptedData(version, destination_connection_id_length_,
-                              source_connection_id_length_, includes_version_,
-                              includes_diversification_nonce_,
-                              packet_number_length_, retry_token_length_length_,
-                              retry_token_length_, length_length_));
-}
-
-absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const {
-  const size_t start_of_encrypted_data = GetStartOfEncryptedData(
-      version, destination_connection_id_length_, source_connection_id_length_,
-      includes_version_, includes_diversification_nonce_, packet_number_length_,
-      retry_token_length_length_, retry_token_length_, length_length_);
-  return absl::string_view(data() + start_of_encrypted_data,
-                           length() - start_of_encrypted_data);
-}
-
-SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
-                                   QuicPacketNumberLength packet_number_length,
-                                   const char* encrypted_buffer,
-                                   QuicPacketLength encrypted_length,
-                                   bool has_ack,
-                                   bool has_stop_waiting)
-    : encrypted_buffer(encrypted_buffer),
-      encrypted_length(encrypted_length),
-      has_crypto_handshake(NOT_HANDSHAKE),
-      packet_number(packet_number),
-      packet_number_length(packet_number_length),
-      encryption_level(ENCRYPTION_INITIAL),
-      has_ack(has_ack),
-      has_stop_waiting(has_stop_waiting),
-      transmission_type(NOT_RETRANSMISSION),
-      has_ack_frame_copy(false),
-      has_ack_frequency(false),
-      has_message(false),
-      fate(SEND_TO_WRITER) {}
-
-SerializedPacket::SerializedPacket(SerializedPacket&& other)
-    : has_crypto_handshake(other.has_crypto_handshake),
-      packet_number(other.packet_number),
-      packet_number_length(other.packet_number_length),
-      encryption_level(other.encryption_level),
-      has_ack(other.has_ack),
-      has_stop_waiting(other.has_stop_waiting),
-      transmission_type(other.transmission_type),
-      largest_acked(other.largest_acked),
-      has_ack_frame_copy(other.has_ack_frame_copy),
-      has_ack_frequency(other.has_ack_frequency),
-      has_message(other.has_message),
-      fate(other.fate),
-      peer_address(other.peer_address) {
-  if (this != &other) {
-    if (release_encrypted_buffer && encrypted_buffer != nullptr) {
-      release_encrypted_buffer(encrypted_buffer);
-    }
-    encrypted_buffer = other.encrypted_buffer;
-    encrypted_length = other.encrypted_length;
-    release_encrypted_buffer = std::move(other.release_encrypted_buffer);
-    other.release_encrypted_buffer = nullptr;
-
-    retransmittable_frames.swap(other.retransmittable_frames);
-    nonretransmittable_frames.swap(other.nonretransmittable_frames);
-  }
-}
-
-SerializedPacket::~SerializedPacket() {
-  if (release_encrypted_buffer && encrypted_buffer != nullptr) {
-    release_encrypted_buffer(encrypted_buffer);
-  }
-
-  if (!retransmittable_frames.empty()) {
-    DeleteFrames(&retransmittable_frames);
-  }
-  for (auto& frame : nonretransmittable_frames) {
-    if (!has_ack_frame_copy && frame.type == ACK_FRAME) {
-      // Do not delete ack frame if the packet does not own a copy of it.
-      continue;
-    }
-    DeleteFrame(&frame);
-  }
-}
-
-SerializedPacket* CopySerializedPacket(const SerializedPacket& serialized,
-                                       quiche::QuicheBufferAllocator* allocator,
-                                       bool copy_buffer) {
-  SerializedPacket* copy = new SerializedPacket(
-      serialized.packet_number, serialized.packet_number_length,
-      serialized.encrypted_buffer, serialized.encrypted_length,
-      serialized.has_ack, serialized.has_stop_waiting);
-  copy->has_crypto_handshake = serialized.has_crypto_handshake;
-  copy->encryption_level = serialized.encryption_level;
-  copy->transmission_type = serialized.transmission_type;
-  copy->largest_acked = serialized.largest_acked;
-  copy->has_ack_frequency = serialized.has_ack_frequency;
-  copy->has_message = serialized.has_message;
-  copy->fate = serialized.fate;
-  copy->peer_address = serialized.peer_address;
-
-  if (copy_buffer) {
-    copy->encrypted_buffer = CopyBuffer(serialized);
-    copy->release_encrypted_buffer = [](const char* p) { delete[] p; };
-  }
-  // Copy underlying frames.
-  copy->retransmittable_frames =
-      CopyQuicFrames(allocator, serialized.retransmittable_frames);
-  QUICHE_DCHECK(copy->nonretransmittable_frames.empty());
-  for (const auto& frame : serialized.nonretransmittable_frames) {
-    if (frame.type == ACK_FRAME) {
-      copy->has_ack_frame_copy = true;
-    }
-    copy->nonretransmittable_frames.push_back(CopyQuicFrame(allocator, frame));
-  }
-  return copy;
-}
-
-char* CopyBuffer(const SerializedPacket& packet) {
-  return CopyBuffer(packet.encrypted_buffer, packet.encrypted_length);
-}
-
-char* CopyBuffer(const char* encrypted_buffer,
-                 QuicPacketLength encrypted_length) {
-  char* dst_buffer = new char[encrypted_length];
-  memcpy(dst_buffer, encrypted_buffer, encrypted_length);
-  return dst_buffer;
-}
-
-ReceivedPacketInfo::ReceivedPacketInfo(const QuicSocketAddress& self_address,
-                                       const QuicSocketAddress& peer_address,
-                                       const QuicReceivedPacket& packet)
-    : self_address(self_address),
-      peer_address(peer_address),
-      packet(packet),
-      form(GOOGLE_QUIC_PACKET),
-      long_packet_type(INVALID_PACKET_TYPE),
-      version_flag(false),
-      use_length_prefix(false),
-      version_label(0),
-      version(ParsedQuicVersion::Unsupported()),
-      destination_connection_id(EmptyQuicConnectionId()),
-      source_connection_id(EmptyQuicConnectionId()) {}
-
-ReceivedPacketInfo::~ReceivedPacketInfo() {}
-
-std::string ReceivedPacketInfo::ToString() const {
-  std::string output =
-      absl::StrCat("{ self_address: ", self_address.ToString(),
-                   ", peer_address: ", peer_address.ToString(),
-                   ", packet_length: ", packet.length(),
-                   ", header_format: ", form, ", version_flag: ", version_flag);
-  if (version_flag) {
-    absl::StrAppend(&output, ", version: ", ParsedQuicVersionToString(version));
-  }
-  absl::StrAppend(
-      &output,
-      ", destination_connection_id: ", destination_connection_id.ToString(),
-      ", source_connection_id: ", source_connection_id.ToString(), " }\n");
-  return output;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const ReceivedPacketInfo& packet_info) {
-  os << packet_info.ToString();
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_packets.h b/quic/core/quic_packets.h
deleted file mode 100644
index c373327..0000000
--- a/quic/core/quic_packets.h
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKETS_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKETS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_ack_listener_interface.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class QuicPacket;
-struct QuicPacketHeader;
-
-// Returns the destination connection ID of |header| when |perspective| is
-// server, and the source connection ID when |perspective| is client.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetServerConnectionIdAsRecipient(const QuicPacketHeader& header,
-                                 Perspective perspective);
-
-// Returns the destination connection ID of |header| when |perspective| is
-// client, and the source connection ID when |perspective| is server.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetClientConnectionIdAsRecipient(const QuicPacketHeader& header,
-                                 Perspective perspective);
-
-// Returns the destination connection ID of |header| when |perspective| is
-// client, and the source connection ID when |perspective| is server.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetServerConnectionIdAsSender(const QuicPacketHeader& header,
-                              Perspective perspective);
-
-// Returns the destination connection ID included of |header| when |perspective|
-// is client, and the source connection ID included when |perspective| is
-// server.
-QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
-GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
-                                      Perspective perspective);
-
-// Returns the destination connection ID of |header| when |perspective| is
-// server, and the source connection ID when |perspective| is client.
-QUIC_EXPORT_PRIVATE QuicConnectionId
-GetClientConnectionIdAsSender(const QuicPacketHeader& header,
-                              Perspective perspective);
-
-// Returns the destination connection ID included of |header| when |perspective|
-// is server, and the source connection ID included when |perspective| is
-// client.
-QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
-GetClientConnectionIdIncludedAsSender(const QuicPacketHeader& header,
-                                      Perspective perspective);
-
-// Number of connection ID bytes that are actually included over the wire.
-QUIC_EXPORT_PRIVATE QuicConnectionIdLength
-GetIncludedConnectionIdLength(QuicConnectionId connection_id,
-                              QuicConnectionIdIncluded connection_id_included);
-
-// Number of destination connection ID bytes that are actually included over the
-// wire for this particular header.
-QUIC_EXPORT_PRIVATE QuicConnectionIdLength
-GetIncludedDestinationConnectionIdLength(const QuicPacketHeader& header);
-
-// Number of source connection ID bytes that are actually included over the
-// wire for this particular header.
-QUIC_EXPORT_PRIVATE QuicConnectionIdLength
-GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header);
-
-// Size in bytes of the data packet header.
-QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version,
-                                               const QuicPacketHeader& header);
-
-QUIC_EXPORT_PRIVATE size_t
-GetPacketHeaderSize(QuicTransportVersion version,
-                    QuicConnectionIdLength destination_connection_id_length,
-                    QuicConnectionIdLength source_connection_id_length,
-                    bool include_version,
-                    bool include_diversification_nonce,
-                    QuicPacketNumberLength packet_number_length,
-                    QuicVariableLengthIntegerLength retry_token_length_length,
-                    QuicByteCount retry_token_length,
-                    QuicVariableLengthIntegerLength length_length);
-
-// Index of the first byte in a QUIC packet of encrypted data.
-QUIC_EXPORT_PRIVATE size_t
-GetStartOfEncryptedData(QuicTransportVersion version,
-                        const QuicPacketHeader& header);
-
-QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
-    QuicTransportVersion version,
-    QuicConnectionIdLength destination_connection_id_length,
-    QuicConnectionIdLength source_connection_id_length,
-    bool include_version,
-    bool include_diversification_nonce,
-    QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length);
-
-struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
-  QuicPacketHeader();
-  QuicPacketHeader(const QuicPacketHeader& other);
-  ~QuicPacketHeader();
-
-  QuicPacketHeader& operator=(const QuicPacketHeader& other);
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPacketHeader& header);
-
-  // Universal header. All QuicPacket headers will have a connection_id and
-  // public flags.
-  QuicConnectionId destination_connection_id;
-  QuicConnectionIdIncluded destination_connection_id_included;
-  QuicConnectionId source_connection_id;
-  QuicConnectionIdIncluded source_connection_id_included;
-  // This is only used for Google QUIC.
-  bool reset_flag;
-  // For Google QUIC, version flag in packets from the server means version
-  // negotiation packet. For IETF QUIC, version flag means long header.
-  bool version_flag;
-  // Indicates whether |possible_stateless_reset_token| contains a valid value
-  // parsed from the packet buffer. IETF QUIC only, always false for GQUIC.
-  bool has_possible_stateless_reset_token;
-  QuicPacketNumberLength packet_number_length;
-  uint8_t type_byte;
-  ParsedQuicVersion version;
-  // nonce contains an optional, 32-byte nonce value. If not included in the
-  // packet, |nonce| will be empty.
-  DiversificationNonce* nonce;
-  QuicPacketNumber packet_number;
-  // Format of this header.
-  PacketHeaderFormat form;
-  // Short packet type is reflected in packet_number_length.
-  QuicLongHeaderType long_packet_type;
-  // Only valid if |has_possible_stateless_reset_token| is true.
-  // Stores last 16 bytes of a this packet, used to check whether this packet is
-  // a stateless reset packet on decryption failure.
-  StatelessResetToken possible_stateless_reset_token;
-  // Length of the retry token length variable length integer field,
-  // carried only by v99 IETF Initial packets.
-  QuicVariableLengthIntegerLength retry_token_length_length;
-  // Retry token, carried only by v99 IETF Initial packets.
-  absl::string_view retry_token;
-  // Length of the length variable length integer field,
-  // carried only by v99 IETF Initial, 0-RTT and Handshake packets.
-  QuicVariableLengthIntegerLength length_length;
-  // Length of the packet number and payload, carried only by v99 IETF Initial,
-  // 0-RTT and Handshake packets. Also includes the length of the
-  // diversification nonce in server to client 0-RTT packets.
-  QuicByteCount remaining_packet_length;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
-  QuicPublicResetPacket();
-  explicit QuicPublicResetPacket(QuicConnectionId connection_id);
-
-  QuicConnectionId connection_id;
-  QuicPublicResetNonceProof nonce_proof;
-  QuicSocketAddress client_address;
-  // An arbitrary string to identify an endpoint. Used by clients to
-  // differentiate traffic from Google servers vs Non-google servers.
-  // Will not be used if empty().
-  std::string endpoint_id;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
-  QuicVersionNegotiationPacket();
-  explicit QuicVersionNegotiationPacket(QuicConnectionId connection_id);
-  QuicVersionNegotiationPacket(const QuicVersionNegotiationPacket& other);
-  ~QuicVersionNegotiationPacket();
-
-  QuicConnectionId connection_id;
-  ParsedQuicVersionVector versions;
-};
-
-struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket {
-  QuicIetfStatelessResetPacket();
-  QuicIetfStatelessResetPacket(const QuicPacketHeader& header,
-                               StatelessResetToken token);
-  QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other);
-  ~QuicIetfStatelessResetPacket();
-
-  QuicPacketHeader header;
-  StatelessResetToken stateless_reset_token;
-};
-
-class QUIC_EXPORT_PRIVATE QuicData {
- public:
-  // Creates a QuicData from a buffer and length. Does not own the buffer.
-  QuicData(const char* buffer, size_t length);
-  // Creates a QuicData from a buffer and length,
-  // optionally taking ownership of the buffer.
-  QuicData(const char* buffer, size_t length, bool owns_buffer);
-  // Creates a QuicData from a absl::string_view. Does not own the
-  // buffer.
-  QuicData(absl::string_view data);
-  QuicData(const QuicData&) = delete;
-  QuicData& operator=(const QuicData&) = delete;
-  virtual ~QuicData();
-
-  absl::string_view AsStringPiece() const {
-    return absl::string_view(data(), length());
-  }
-
-  const char* data() const { return buffer_; }
-  size_t length() const { return length_; }
-
- private:
-  const char* buffer_;
-  size_t length_;
-  bool owns_buffer_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
- public:
-  QuicPacket(char* buffer,
-             size_t length,
-             bool owns_buffer,
-             QuicConnectionIdLength destination_connection_id_length,
-             QuicConnectionIdLength source_connection_id_length,
-             bool includes_version,
-             bool includes_diversification_nonce,
-             QuicPacketNumberLength packet_number_length,
-             QuicVariableLengthIntegerLength retry_token_length_length,
-             QuicByteCount retry_token_length,
-             QuicVariableLengthIntegerLength length_length);
-  QuicPacket(QuicTransportVersion version,
-             char* buffer,
-             size_t length,
-             bool owns_buffer,
-             const QuicPacketHeader& header);
-  QuicPacket(const QuicPacket&) = delete;
-  QuicPacket& operator=(const QuicPacket&) = delete;
-
-  absl::string_view AssociatedData(QuicTransportVersion version) const;
-  absl::string_view Plaintext(QuicTransportVersion version) const;
-
-  char* mutable_data() { return buffer_; }
-
- private:
-  char* buffer_;
-  const QuicConnectionIdLength destination_connection_id_length_;
-  const QuicConnectionIdLength source_connection_id_length_;
-  const bool includes_version_;
-  const bool includes_diversification_nonce_;
-  const QuicPacketNumberLength packet_number_length_;
-  const QuicVariableLengthIntegerLength retry_token_length_length_;
-  const QuicByteCount retry_token_length_;
-  const QuicVariableLengthIntegerLength length_length_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
- public:
-  // Creates a QuicEncryptedPacket from a buffer and length.
-  // Does not own the buffer.
-  QuicEncryptedPacket(const char* buffer, size_t length);
-  // Creates a QuicEncryptedPacket from a buffer and length,
-  // optionally taking ownership of the buffer.
-  QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer);
-  // Creates a QuicEncryptedPacket from a absl::string_view.
-  // Does not own the buffer.
-  QuicEncryptedPacket(absl::string_view data);
-
-  QuicEncryptedPacket(const QuicEncryptedPacket&) = delete;
-  QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete;
-
-  // Clones the packet into a new packet which owns the buffer.
-  std::unique_ptr<QuicEncryptedPacket> Clone() const;
-
-  // By default, gtest prints the raw bytes of an object. The bool data
-  // member (in the base class QuicData) causes this object to have padding
-  // bytes, which causes the default gtest object printer to read
-  // uninitialize memory. So we need to teach gtest how to print this object.
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicEncryptedPacket& s);
-};
-
-// A received encrypted QUIC packet, with a recorded time of receipt.
-class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
- public:
-  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time);
-  QuicReceivedPacket(const char* buffer,
-                     size_t length,
-                     QuicTime receipt_time,
-                     bool owns_buffer);
-  QuicReceivedPacket(const char* buffer,
-                     size_t length,
-                     QuicTime receipt_time,
-                     bool owns_buffer,
-                     int ttl,
-                     bool ttl_valid);
-  QuicReceivedPacket(const char* buffer,
-                     size_t length,
-                     QuicTime receipt_time,
-                     bool owns_buffer,
-                     int ttl,
-                     bool ttl_valid,
-                     char* packet_headers,
-                     size_t headers_length,
-                     bool owns_header_buffer);
-  ~QuicReceivedPacket();
-  QuicReceivedPacket(const QuicReceivedPacket&) = delete;
-  QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete;
-
-  // Clones the packet into a new packet which owns the buffer.
-  std::unique_ptr<QuicReceivedPacket> Clone() const;
-
-  // Returns the time at which the packet was received.
-  QuicTime receipt_time() const { return receipt_time_; }
-
-  // This is the TTL of the packet, assuming ttl_vaild_ is true.
-  int ttl() const { return ttl_; }
-
-  // Start of packet headers.
-  char* packet_headers() const { return packet_headers_; }
-
-  // Length of packet headers.
-  int headers_length() const { return headers_length_; }
-
-  // By default, gtest prints the raw bytes of an object. The bool data
-  // member (in the base class QuicData) causes this object to have padding
-  // bytes, which causes the default gtest object printer to read
-  // uninitialize memory. So we need to teach gtest how to print this object.
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicReceivedPacket& s);
-
- private:
-  const QuicTime receipt_time_;
-  int ttl_;
-  // Points to the start of packet headers.
-  char* packet_headers_;
-  // Length of packet headers.
-  int headers_length_;
-  // Whether owns the buffer for packet headers.
-  bool owns_header_buffer_;
-};
-
-// SerializedPacket contains information of a serialized(encrypted) packet.
-//
-// WARNING:
-//
-//   If you add a member field to this class, please make sure it is properly
-//   copied in |CopySerializedPacket|.
-//
-struct QUIC_EXPORT_PRIVATE SerializedPacket {
-  SerializedPacket(QuicPacketNumber packet_number,
-                   QuicPacketNumberLength packet_number_length,
-                   const char* encrypted_buffer,
-                   QuicPacketLength encrypted_length,
-                   bool has_ack,
-                   bool has_stop_waiting);
-
-  // Copy constructor & assignment are deleted. Use |CopySerializedPacket| to
-  // make a copy.
-  SerializedPacket(const SerializedPacket& other) = delete;
-  SerializedPacket& operator=(const SerializedPacket& other) = delete;
-  SerializedPacket(SerializedPacket&& other);
-  ~SerializedPacket();
-
-  // TODO(wub): replace |encrypted_buffer|+|release_encrypted_buffer| by a
-  // QuicOwnedPacketBuffer.
-  // Not owned if |release_encrypted_buffer| is nullptr. Otherwise it is
-  // released by |release_encrypted_buffer| on destruction.
-  const char* encrypted_buffer;
-  QuicPacketLength encrypted_length;
-  std::function<void(const char*)> release_encrypted_buffer;
-
-  QuicFrames retransmittable_frames;
-  QuicFrames nonretransmittable_frames;
-  IsHandshake has_crypto_handshake;
-  QuicPacketNumber packet_number;
-  QuicPacketNumberLength packet_number_length;
-  EncryptionLevel encryption_level;
-  // TODO(fayang): Remove has_ack and has_stop_waiting.
-  bool has_ack;
-  bool has_stop_waiting;
-  TransmissionType transmission_type;
-  // The largest acked of the AckFrame in this packet if has_ack is true,
-  // 0 otherwise.
-  QuicPacketNumber largest_acked;
-  // Indicates whether this packet has a copy of ack frame in
-  // nonretransmittable_frames.
-  bool has_ack_frame_copy;
-  bool has_ack_frequency;
-  bool has_message;
-  SerializedPacketFate fate;
-  QuicSocketAddress peer_address;
-};
-
-// Make a copy of |serialized| (including the underlying frames). |copy_buffer|
-// indicates whether the encrypted buffer should be copied.
-QUIC_EXPORT_PRIVATE SerializedPacket* CopySerializedPacket(
-    const SerializedPacket& serialized,
-    quiche::QuicheBufferAllocator* allocator, bool copy_buffer);
-
-// Allocates a new char[] of size |packet.encrypted_length| and copies in
-// |packet.encrypted_buffer|.
-QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
-// Allocates a new char[] of size |encrypted_length| and copies in
-// |encrypted_buffer|.
-QUIC_EXPORT_PRIVATE char* CopyBuffer(const char* encrypted_buffer,
-                                     QuicPacketLength encrypted_length);
-
-// Context for an incoming packet.
-struct QUIC_EXPORT_PRIVATE QuicPerPacketContext {
-  virtual ~QuicPerPacketContext() {}
-};
-
-// ReceivedPacketInfo comprises information obtained by parsing the unencrypted
-// bytes of a received packet.
-struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
-  ReceivedPacketInfo(const QuicSocketAddress& self_address,
-                     const QuicSocketAddress& peer_address,
-                     const QuicReceivedPacket& packet);
-  ReceivedPacketInfo(const ReceivedPacketInfo& other) = default;
-
-  ~ReceivedPacketInfo();
-
-  std::string ToString() const;
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const ReceivedPacketInfo& packet_info);
-
-  const QuicSocketAddress& self_address;
-  const QuicSocketAddress& peer_address;
-  const QuicReceivedPacket& packet;
-
-  PacketHeaderFormat form;
-  // This is only used if the form is IETF_QUIC_LONG_HEADER_PACKET.
-  QuicLongHeaderType long_packet_type;
-  bool version_flag;
-  bool use_length_prefix;
-  QuicVersionLabel version_label;
-  ParsedQuicVersion version;
-  QuicConnectionId destination_connection_id;
-  QuicConnectionId source_connection_id;
-  absl::optional<absl::string_view> retry_token;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKETS_H_
diff --git a/quic/core/quic_packets_test.cc b/quic/core/quic_packets_test.cc
deleted file mode 100644
index 7568d22..0000000
--- a/quic/core/quic_packets_test.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_packets.h"
-
-#include "absl/memory/memory.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-QuicPacketHeader CreateFakePacketHeader() {
-  QuicPacketHeader header;
-  header.destination_connection_id = TestConnectionId(1);
-  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
-  header.source_connection_id = TestConnectionId(2);
-  header.source_connection_id_included = CONNECTION_ID_ABSENT;
-  return header;
-}
-
-class QuicPacketsTest : public QuicTest {};
-
-TEST_F(QuicPacketsTest, GetServerConnectionIdAsRecipient) {
-  QuicPacketHeader header = CreateFakePacketHeader();
-  EXPECT_EQ(TestConnectionId(1),
-            GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
-  EXPECT_EQ(TestConnectionId(2),
-            GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetServerConnectionIdAsSender) {
-  QuicPacketHeader header = CreateFakePacketHeader();
-  EXPECT_EQ(TestConnectionId(2),
-            GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
-  EXPECT_EQ(TestConnectionId(1),
-            GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetServerConnectionIdIncludedAsSender) {
-  QuicPacketHeader header = CreateFakePacketHeader();
-  EXPECT_EQ(CONNECTION_ID_ABSENT, GetServerConnectionIdIncludedAsSender(
-                                      header, Perspective::IS_SERVER));
-  EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
-                                       header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetClientConnectionIdIncludedAsSender) {
-  QuicPacketHeader header = CreateFakePacketHeader();
-  EXPECT_EQ(CONNECTION_ID_PRESENT, GetClientConnectionIdIncludedAsSender(
-                                       header, Perspective::IS_SERVER));
-  EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
-                                      header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetClientConnectionIdAsRecipient) {
-  QuicPacketHeader header = CreateFakePacketHeader();
-  EXPECT_EQ(TestConnectionId(2),
-            GetClientConnectionIdAsRecipient(header, Perspective::IS_SERVER));
-  EXPECT_EQ(TestConnectionId(1),
-            GetClientConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, GetClientConnectionIdAsSender) {
-  QuicPacketHeader header = CreateFakePacketHeader();
-  EXPECT_EQ(TestConnectionId(1),
-            GetClientConnectionIdAsSender(header, Perspective::IS_SERVER));
-  EXPECT_EQ(TestConnectionId(2),
-            GetClientConnectionIdAsSender(header, Perspective::IS_CLIENT));
-}
-
-TEST_F(QuicPacketsTest, CopySerializedPacket) {
-  std::string buffer(1000, 'a');
-  quiche::SimpleBufferAllocator allocator;
-  SerializedPacket packet(QuicPacketNumber(1), PACKET_1BYTE_PACKET_NUMBER,
-                          buffer.data(), buffer.length(), /*has_ack=*/false,
-                          /*has_stop_waiting=*/false);
-  packet.retransmittable_frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
-  packet.retransmittable_frames.push_back(QuicFrame(QuicStreamFrame()));
-
-  QuicAckFrame ack_frame(InitAckFrame(1));
-  packet.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
-  packet.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-
-  std::unique_ptr<SerializedPacket> copy = absl::WrapUnique<SerializedPacket>(
-      CopySerializedPacket(packet, &allocator, /*copy_buffer=*/true));
-  EXPECT_EQ(quic::QuicPacketNumber(1), copy->packet_number);
-  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, copy->packet_number_length);
-  ASSERT_EQ(2u, copy->retransmittable_frames.size());
-  EXPECT_EQ(WINDOW_UPDATE_FRAME, copy->retransmittable_frames[0].type);
-  EXPECT_EQ(STREAM_FRAME, copy->retransmittable_frames[1].type);
-
-  ASSERT_EQ(2u, copy->nonretransmittable_frames.size());
-  EXPECT_EQ(ACK_FRAME, copy->nonretransmittable_frames[0].type);
-  EXPECT_EQ(PADDING_FRAME, copy->nonretransmittable_frames[1].type);
-  EXPECT_EQ(1000u, copy->encrypted_length);
-  quiche::test::CompareCharArraysWithHexError(
-      "encrypted_buffer", copy->encrypted_buffer, copy->encrypted_length,
-      packet.encrypted_buffer, packet.encrypted_length);
-
-  std::unique_ptr<SerializedPacket> copy2 = absl::WrapUnique<SerializedPacket>(
-      CopySerializedPacket(packet, &allocator, /*copy_buffer=*/false));
-  EXPECT_EQ(packet.encrypted_buffer, copy2->encrypted_buffer);
-  EXPECT_EQ(1000u, copy2->encrypted_length);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_path_validator.cc b/quic/core/quic_path_validator.cc
deleted file mode 100644
index 658dfef..0000000
--- a/quic/core/quic_path_validator.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_path_validator.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class RetryAlarmDelegate : public QuicAlarm::DelegateWithContext {
- public:
-  explicit RetryAlarmDelegate(QuicPathValidator* path_validator,
-                              QuicConnectionContext* context)
-      : QuicAlarm::DelegateWithContext(context),
-        path_validator_(path_validator) {}
-  RetryAlarmDelegate(const RetryAlarmDelegate&) = delete;
-  RetryAlarmDelegate& operator=(const RetryAlarmDelegate&) = delete;
-
-  void OnAlarm() override { path_validator_->OnRetryTimeout(); }
-
- private:
-  QuicPathValidator* path_validator_;
-};
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicPathValidationContext& context) {
-  return os << " from " << context.self_address_ << " to "
-            << context.peer_address_;
-}
-
-QuicPathValidator::QuicPathValidator(QuicAlarmFactory* alarm_factory,
-                                     QuicConnectionArena* arena,
-                                     SendDelegate* send_delegate,
-                                     QuicRandom* random,
-                                     QuicConnectionContext* context)
-    : send_delegate_(send_delegate),
-      random_(random),
-      retry_timer_(alarm_factory->CreateAlarm(
-          arena->New<RetryAlarmDelegate>(this, context), arena)),
-      retry_count_(0u) {}
-
-void QuicPathValidator::OnPathResponse(const QuicPathFrameBuffer& probing_data,
-                                       QuicSocketAddress self_address) {
-  if (!HasPendingPathValidation()) {
-    return;
-  }
-
-  QUIC_DVLOG(1) << "Match PATH_RESPONSE received on " << self_address;
-  QUIC_BUG_IF(quic_bug_12402_1, !path_context_->self_address().IsInitialized())
-      << "Self address should have been known by now";
-  if (self_address != path_context_->self_address()) {
-    QUIC_DVLOG(1) << "Expect the response to be received on "
-                  << path_context_->self_address();
-    return;
-  }
-  // This iterates at most 3 times.
-  if (std::find(probing_data_.begin(), probing_data_.end(), probing_data) !=
-      probing_data_.end()) {
-    result_delegate_->OnPathValidationSuccess(std::move(path_context_));
-    ResetPathValidation();
-  } else {
-    QUIC_DVLOG(1) << "PATH_RESPONSE with payload " << probing_data.data()
-                  << " doesn't match the probing data.";
-  }
-}
-
-void QuicPathValidator::StartPathValidation(
-    std::unique_ptr<QuicPathValidationContext> context,
-    std::unique_ptr<ResultDelegate> result_delegate) {
-  QUICHE_DCHECK(context);
-  QUIC_DLOG(INFO) << "Start validating path " << *context
-                  << " via writer: " << context->WriterToUse();
-  if (path_context_ != nullptr) {
-    QUIC_BUG(quic_bug_10876_1)
-        << "There is an on-going validation on path " << *path_context_;
-    ResetPathValidation();
-  }
-
-  path_context_ = std::move(context);
-  result_delegate_ = std::move(result_delegate);
-  SendPathChallengeAndSetAlarm();
-}
-
-void QuicPathValidator::ResetPathValidation() {
-  path_context_ = nullptr;
-  result_delegate_ = nullptr;
-  retry_timer_->Cancel();
-  retry_count_ = 0;
-}
-
-void QuicPathValidator::CancelPathValidation() {
-  if (path_context_ == nullptr) {
-    return;
-  }
-  QUIC_DVLOG(1) << "Cancel validation on path" << *path_context_;
-  result_delegate_->OnPathValidationFailure(std::move(path_context_));
-  ResetPathValidation();
-}
-
-bool QuicPathValidator::HasPendingPathValidation() const {
-  return path_context_ != nullptr;
-}
-
-QuicPathValidationContext* QuicPathValidator::GetContext() const {
-  return path_context_.get();
-}
-
-const QuicPathFrameBuffer& QuicPathValidator::GeneratePathChallengePayload() {
-  probing_data_.push_back(QuicPathFrameBuffer());
-  random_->RandBytes(probing_data_.back().data(), sizeof(QuicPathFrameBuffer));
-  return probing_data_.back();
-}
-
-void QuicPathValidator::OnRetryTimeout() {
-  ++retry_count_;
-  if (retry_count_ > kMaxRetryTimes) {
-    CancelPathValidation();
-    return;
-  }
-  QUIC_DVLOG(1) << "Send another PATH_CHALLENGE on path " << *path_context_;
-  SendPathChallengeAndSetAlarm();
-}
-
-void QuicPathValidator::SendPathChallengeAndSetAlarm() {
-  bool should_continue = send_delegate_->SendPathChallenge(
-      GeneratePathChallengePayload(), path_context_->self_address(),
-      path_context_->peer_address(), path_context_->effective_peer_address(),
-      path_context_->WriterToUse());
-
-  if (!should_continue) {
-    // The delegate doesn't want to continue the path validation.
-    CancelPathValidation();
-    return;
-  }
-  retry_timer_->Set(send_delegate_->GetRetryTimeout(
-      path_context_->peer_address(), path_context_->WriterToUse()));
-}
-
-bool QuicPathValidator::IsValidatingPeerAddress(
-    const QuicSocketAddress& effective_peer_address) {
-  return path_context_ != nullptr &&
-         path_context_->effective_peer_address() == effective_peer_address;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_path_validator.h b/quic/core/quic_path_validator.h
deleted file mode 100644
index 9fe2cef..0000000
--- a/quic/core/quic_path_validator.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
-
-#include <ostream>
-
-#include "absl/container/inlined_vector.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_arena_scoped_ptr.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_one_block_arena.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-namespace test {
-class QuicPathValidatorPeer;
-}
-
-class QuicConnection;
-
-// Interface to provide the information of the path to be validated.
-class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
- public:
-  QuicPathValidationContext(const QuicSocketAddress& self_address,
-                            const QuicSocketAddress& peer_address)
-      : self_address_(self_address),
-        peer_address_(peer_address),
-        effective_peer_address_(peer_address) {}
-
-  QuicPathValidationContext(const QuicSocketAddress& self_address,
-                            const QuicSocketAddress& peer_address,
-                            const QuicSocketAddress& effective_peer_address)
-      : self_address_(self_address),
-        peer_address_(peer_address),
-        effective_peer_address_(effective_peer_address) {}
-
-  virtual ~QuicPathValidationContext() = default;
-
-  virtual QuicPacketWriter* WriterToUse() = 0;
-
-  const QuicSocketAddress& self_address() const { return self_address_; }
-  const QuicSocketAddress& peer_address() const { return peer_address_; }
-  const QuicSocketAddress& effective_peer_address() const {
-    return effective_peer_address_;
-  }
-
- private:
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPathValidationContext& context);
-
-  QuicSocketAddress self_address_;
-  // The address to send PATH_CHALLENGE.
-  QuicSocketAddress peer_address_;
-  // The actual peer address which is different from |peer_address_| if the peer
-  // is behind a proxy.
-  QuicSocketAddress effective_peer_address_;
-};
-
-// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
-// declaring a path validation failure.
-class QUIC_EXPORT_PRIVATE QuicPathValidator {
- public:
-  static const uint16_t kMaxRetryTimes = 2;
-
-  // Used to write PATH_CHALLENGE on the path to be validated and to get retry
-  // timeout.
-  class QUIC_EXPORT_PRIVATE SendDelegate {
-   public:
-    virtual ~SendDelegate() = default;
-
-    // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
-    // path information. Return false if the delegate doesn't want to continue
-    // the validation.
-    virtual bool SendPathChallenge(
-        const QuicPathFrameBuffer& data_buffer,
-        const QuicSocketAddress& self_address,
-        const QuicSocketAddress& peer_address,
-        const QuicSocketAddress& effective_peer_address,
-        QuicPacketWriter* writer) = 0;
-    // Return the time to retry sending PATH_CHALLENGE again based on given peer
-    // address and writer.
-    virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
-                                     QuicPacketWriter* writer) const = 0;
-  };
-
-  // Handles the validation result.
-  // TODO(danzh) consider to simplify this interface and its life time to
-  // outlive a validation.
-  class QUIC_EXPORT_PRIVATE ResultDelegate {
-   public:
-    virtual ~ResultDelegate() = default;
-
-    virtual void OnPathValidationSuccess(
-        std::unique_ptr<QuicPathValidationContext> context) = 0;
-
-    virtual void OnPathValidationFailure(
-        std::unique_ptr<QuicPathValidationContext> context) = 0;
-  };
-
-  QuicPathValidator(QuicAlarmFactory* alarm_factory, QuicConnectionArena* arena,
-                    SendDelegate* delegate, QuicRandom* random,
-                    QuicConnectionContext* context);
-
-  // Send PATH_CHALLENGE and start the retry timer.
-  void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
-                           std::unique_ptr<ResultDelegate> result_delegate);
-
-  // Called when a PATH_RESPONSE frame has been received. Matches the received
-  // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
-  // frames and the self address on which it was sent.
-  void OnPathResponse(const QuicPathFrameBuffer& probing_data,
-                      QuicSocketAddress self_address);
-
-  // Cancel the retry timer and reset the path and result delegate.
-  void CancelPathValidation();
-
-  bool HasPendingPathValidation() const;
-
-  QuicPathValidationContext* GetContext() const;
-
-  // Send another PATH_CHALLENGE on the same path. After retrying
-  // |kMaxRetryTimes| times, fail the current path validation.
-  void OnRetryTimeout();
-
-  bool IsValidatingPeerAddress(const QuicSocketAddress& effective_peer_address);
-
- private:
-  friend class test::QuicPathValidatorPeer;
-
-  // Return the payload to be used in the next PATH_CHALLENGE frame.
-  const QuicPathFrameBuffer& GeneratePathChallengePayload();
-
-  void SendPathChallengeAndSetAlarm();
-
-  void ResetPathValidation();
-
-  // Has at most 3 entries due to validation timeout.
-  absl::InlinedVector<QuicPathFrameBuffer, 3> probing_data_;
-  SendDelegate* send_delegate_;
-  QuicRandom* random_;
-  std::unique_ptr<QuicPathValidationContext> path_context_;
-  std::unique_ptr<ResultDelegate> result_delegate_;
-  QuicArenaScopedPtr<QuicAlarm> retry_timer_;
-  size_t retry_count_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
diff --git a/quic/core/quic_path_validator_test.cc b/quic/core/quic_path_validator_test.cc
deleted file mode 100644
index 28e1259..0000000
--- a/quic/core/quic_path_validator_test.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_path_validator.h"
-
-#include <memory>
-
-#include "quic/core/frames/quic_path_challenge_frame.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_path_validator_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-
-using testing::_;
-using testing::Invoke;
-using testing::Return;
-
-namespace quic {
-namespace test {
-
-class MockSendDelegate : public QuicPathValidator::SendDelegate {
- public:
-  // Send a PATH_CHALLENGE frame using given path information and populate
-  // |data_buffer| with the frame payload. Return true if the validator should
-  // move forward in validation, i.e. arm the retry timer.
-  MOCK_METHOD(bool,
-              SendPathChallenge,
-              (const QuicPathFrameBuffer&,
-               const QuicSocketAddress&,
-               const QuicSocketAddress&,
-               const QuicSocketAddress&,
-               QuicPacketWriter*),
-              (override));
-
-  MOCK_METHOD(QuicTime,
-              GetRetryTimeout,
-              (const QuicSocketAddress&, QuicPacketWriter*),
-              (const, override));
-};
-
-class QuicPathValidatorTest : public QuicTest {
- public:
-  QuicPathValidatorTest()
-      : path_validator_(&alarm_factory_, &arena_, &send_delegate_, &random_,
-                        /*context=*/nullptr),
-        context_(new MockQuicPathValidationContext(
-            self_address_, peer_address_, effective_peer_address_, &writer_)),
-        result_delegate_(
-            new testing::StrictMock<MockQuicPathValidationResultDelegate>()) {
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-    ON_CALL(send_delegate_, GetRetryTimeout(_, _))
-        .WillByDefault(
-            Return(clock_.ApproximateNow() +
-                   3 * QuicTime::Delta::FromMilliseconds(kInitialRttMs)));
-  }
-
- protected:
-  quic::test::MockAlarmFactory alarm_factory_;
-  MockSendDelegate send_delegate_;
-  MockRandom random_;
-  MockClock clock_;
-  QuicConnectionArena arena_;
-  QuicPathValidator path_validator_;
-  QuicSocketAddress self_address_{QuicIpAddress::Any4(), 443};
-  QuicSocketAddress peer_address_{QuicIpAddress::Loopback4(), 443};
-  QuicSocketAddress effective_peer_address_{QuicIpAddress::Loopback4(), 12345};
-  MockPacketWriter writer_;
-  MockQuicPathValidationContext* context_;
-  MockQuicPathValidationResultDelegate* result_delegate_;
-};
-
-TEST_F(QuicPathValidatorTest, PathValidationSuccessOnFirstRound) {
-  QuicPathFrameBuffer challenge_data;
-  EXPECT_CALL(send_delegate_,
-              SendPathChallenge(_, self_address_, peer_address_,
-                                effective_peer_address_, &writer_))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, QuicPacketWriter*) {
-        memcpy(challenge_data.data(), payload.data(), payload.size());
-        return true;
-      }));
-  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
-  path_validator_.StartPathValidation(
-      std::unique_ptr<QuicPathValidationContext>(context_),
-      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-  EXPECT_TRUE(path_validator_.HasPendingPathValidation());
-  EXPECT_TRUE(path_validator_.IsValidatingPeerAddress(effective_peer_address_));
-  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
-      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
-        EXPECT_EQ(context.get(), context_);
-      }));
-  path_validator_.OnPathResponse(challenge_data, self_address_);
-  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-}
-
-TEST_F(QuicPathValidatorTest, RespondWithDifferentSelfAddress) {
-  QuicPathFrameBuffer challenge_data;
-  EXPECT_CALL(send_delegate_,
-              SendPathChallenge(_, self_address_, peer_address_,
-                                effective_peer_address_, &writer_))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer payload,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, QuicPacketWriter*) {
-        memcpy(challenge_data.data(), payload.data(), payload.size());
-        return true;
-      }));
-  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
-  path_validator_.StartPathValidation(
-      std::unique_ptr<QuicPathValidationContext>(context_),
-      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
-  // Reception of a PATH_RESPONSE on a different self address should be ignored.
-  const QuicSocketAddress kAlternativeSelfAddress(QuicIpAddress::Any6(), 54321);
-  EXPECT_NE(kAlternativeSelfAddress, self_address_);
-  path_validator_.OnPathResponse(challenge_data, kAlternativeSelfAddress);
-
-  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
-      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
-        EXPECT_EQ(context->self_address(), self_address_);
-      }));
-  path_validator_.OnPathResponse(challenge_data, self_address_);
-}
-
-TEST_F(QuicPathValidatorTest, RespondAfter1stRetry) {
-  QuicPathFrameBuffer challenge_data;
-  EXPECT_CALL(send_delegate_,
-              SendPathChallenge(_, self_address_, peer_address_,
-                                effective_peer_address_, &writer_))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, QuicPacketWriter*) {
-        // Store up the 1st PATH_CHALLANGE payload.
-        memcpy(challenge_data.data(), payload.data(), payload.size());
-        return true;
-      }))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, QuicPacketWriter*) {
-        EXPECT_NE(payload, challenge_data);
-        return true;
-      }));
-  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
-      .Times(2u);
-  path_validator_.StartPathValidation(
-      std::unique_ptr<QuicPathValidationContext>(context_),
-      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-  random_.ChangeValue();
-  alarm_factory_.FireAlarm(
-      QuicPathValidatorPeer::retry_timer(&path_validator_));
-
-  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
-  // Respond to the 1st PATH_CHALLENGE should complete the validation.
-  path_validator_.OnPathResponse(challenge_data, self_address_);
-  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-}
-
-TEST_F(QuicPathValidatorTest, RespondToRetryChallenge) {
-  QuicPathFrameBuffer challenge_data;
-  EXPECT_CALL(send_delegate_,
-              SendPathChallenge(_, self_address_, peer_address_,
-                                effective_peer_address_, &writer_))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, QuicPacketWriter*) {
-        memcpy(challenge_data.data(), payload.data(), payload.size());
-        return true;
-      }))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, QuicPacketWriter*) {
-        EXPECT_NE(challenge_data, payload);
-        memcpy(challenge_data.data(), payload.data(), payload.size());
-        return true;
-      }));
-  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
-      .Times(2u);
-  path_validator_.StartPathValidation(
-      std::unique_ptr<QuicPathValidationContext>(context_),
-      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-  random_.ChangeValue();
-  alarm_factory_.FireAlarm(
-      QuicPathValidatorPeer::retry_timer(&path_validator_));
-
-  // Respond to the 2nd PATH_CHALLENGE should complete the validation.
-  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
-  path_validator_.OnPathResponse(challenge_data, self_address_);
-  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-}
-
-TEST_F(QuicPathValidatorTest, ValidationTimeOut) {
-  EXPECT_CALL(send_delegate_,
-              SendPathChallenge(_, self_address_, peer_address_,
-                                effective_peer_address_, &writer_))
-      .Times(3u)
-      .WillRepeatedly(Return(true));
-  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
-      .Times(3u);
-  path_validator_.StartPathValidation(
-      std::unique_ptr<QuicPathValidationContext>(context_),
-      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-
-  QuicPathFrameBuffer challenge_data;
-  memset(challenge_data.data(), 'a', challenge_data.size());
-  // Reception of a PATH_RESPONSE with different payload should be ignored.
-  path_validator_.OnPathResponse(challenge_data, self_address_);
-
-  // Retry 3 times. The 3rd time should fail the validation.
-  EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_))
-      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
-        EXPECT_EQ(context_, context.get());
-      }));
-  for (size_t i = 0; i <= QuicPathValidator::kMaxRetryTimes; ++i) {
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
-    alarm_factory_.FireAlarm(
-        QuicPathValidatorPeer::retry_timer(&path_validator_));
-  }
-}
-
-TEST_F(QuicPathValidatorTest, SendPathChallengeError) {
-  EXPECT_CALL(send_delegate_,
-              SendPathChallenge(_, self_address_, peer_address_,
-                                effective_peer_address_, &writer_))
-      .WillOnce(Invoke([&](const QuicPathFrameBuffer&, const QuicSocketAddress&,
-                           const QuicSocketAddress&, const QuicSocketAddress&,
-                           QuicPacketWriter*) {
-        // Abandon this validation in the call stack shouldn't cause crash and
-        // should cancel the alarm.
-        path_validator_.CancelPathValidation();
-        return false;
-      }));
-  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
-      .Times(0u);
-  EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_));
-  path_validator_.StartPathValidation(
-      std::unique_ptr<QuicPathValidationContext>(context_),
-      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
-  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
-  EXPECT_FALSE(QuicPathValidatorPeer::retry_timer(&path_validator_)->IsSet());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_process_packet_interface.h b/quic/core/quic_process_packet_interface.h
deleted file mode 100644
index cbe257f..0000000
--- a/quic/core/quic_process_packet_interface.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
-#define QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// A class to process each incoming packet.
-class QUIC_NO_EXPORT ProcessPacketInterface {
- public:
-  virtual ~ProcessPacketInterface() {}
-  virtual void ProcessPacket(const QuicSocketAddress& self_address,
-                             const QuicSocketAddress& peer_address,
-                             const QuicReceivedPacket& packet) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
diff --git a/quic/core/quic_received_packet_manager.cc b/quic/core/quic_received_packet_manager.cc
deleted file mode 100644
index c4e7333..0000000
--- a/quic/core/quic_received_packet_manager.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_received_packet_manager.h"
-
-#include <algorithm>
-#include <limits>
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace {
-
-// The maximum number of packets to ack immediately after a missing packet for
-// fast retransmission to kick in at the sender.  This limit is created to
-// reduce the number of acks sent that have no benefit for fast retransmission.
-// Set to the number of nacks needed for fast retransmit plus one for protection
-// against an ack loss
-const size_t kMaxPacketsAfterNewMissing = 4;
-
-// One eighth RTT delay when doing ack decimation.
-const float kShortAckDecimationDelay = 0.125;
-}  // namespace
-
-QuicReceivedPacketManager::QuicReceivedPacketManager()
-    : QuicReceivedPacketManager(nullptr) {}
-
-QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
-    : ack_frame_updated_(false),
-      max_ack_ranges_(0),
-      time_largest_observed_(QuicTime::Zero()),
-      save_timestamps_(false),
-      save_timestamps_for_in_order_packets_(false),
-      stats_(stats),
-      num_retransmittable_packets_received_since_last_ack_sent_(0),
-      min_received_before_ack_decimation_(kMinReceivedBeforeAckDecimation),
-      ack_frequency_(kDefaultRetransmittablePacketsBeforeAck),
-      ack_decimation_delay_(kAckDecimationDelay),
-      unlimited_ack_decimation_(false),
-      one_immediate_ack_(false),
-      ignore_order_(false),
-      local_max_ack_delay_(
-          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
-      ack_timeout_(QuicTime::Zero()),
-      time_of_previous_received_packet_(QuicTime::Zero()),
-      was_last_packet_missing_(false),
-      last_ack_frequency_frame_sequence_number_(-1) {}
-
-QuicReceivedPacketManager::~QuicReceivedPacketManager() {}
-
-void QuicReceivedPacketManager::SetFromConfig(const QuicConfig& config,
-                                              Perspective perspective) {
-  if (config.HasClientSentConnectionOption(kAKD3, perspective)) {
-    ack_decimation_delay_ = kShortAckDecimationDelay;
-  }
-  if (config.HasClientSentConnectionOption(kAKDU, perspective)) {
-    unlimited_ack_decimation_ = true;
-  }
-  if (config.HasClientSentConnectionOption(k1ACK, perspective)) {
-    one_immediate_ack_ = true;
-  }
-}
-
-void QuicReceivedPacketManager::RecordPacketReceived(
-    const QuicPacketHeader& header,
-    QuicTime receipt_time) {
-  const QuicPacketNumber packet_number = header.packet_number;
-  QUICHE_DCHECK(IsAwaitingPacket(packet_number))
-      << " packet_number:" << packet_number;
-  was_last_packet_missing_ = IsMissing(packet_number);
-  if (!ack_frame_updated_) {
-    ack_frame_.received_packet_times.clear();
-  }
-  ack_frame_updated_ = true;
-
-  // Whether |packet_number| is received out of order.
-  bool packet_reordered = false;
-  if (LargestAcked(ack_frame_).IsInitialized() &&
-      LargestAcked(ack_frame_) > packet_number) {
-    // Record how out of order stats.
-    packet_reordered = true;
-    ++stats_->packets_reordered;
-    stats_->max_sequence_reordering =
-        std::max(stats_->max_sequence_reordering,
-                 LargestAcked(ack_frame_) - packet_number);
-    int64_t reordering_time_us =
-        (receipt_time - time_largest_observed_).ToMicroseconds();
-    stats_->max_time_reordering_us =
-        std::max(stats_->max_time_reordering_us, reordering_time_us);
-  }
-  if (!LargestAcked(ack_frame_).IsInitialized() ||
-      packet_number > LargestAcked(ack_frame_)) {
-    ack_frame_.largest_acked = packet_number;
-    time_largest_observed_ = receipt_time;
-  }
-  ack_frame_.packets.Add(packet_number);
-
-  if (save_timestamps_) {
-    // The timestamp format only handles packets in time order.
-    if (save_timestamps_for_in_order_packets_ && packet_reordered) {
-      QUIC_DLOG(WARNING) << "Not saving receive timestamp for packet "
-                         << packet_number;
-    } else if (!ack_frame_.received_packet_times.empty() &&
-               ack_frame_.received_packet_times.back().second > receipt_time) {
-      QUIC_LOG(WARNING)
-          << "Receive time went backwards from: "
-          << ack_frame_.received_packet_times.back().second.ToDebuggingValue()
-          << " to " << receipt_time.ToDebuggingValue();
-    } else {
-      ack_frame_.received_packet_times.push_back(
-          std::make_pair(packet_number, receipt_time));
-    }
-  }
-
-  if (least_received_packet_number_.IsInitialized()) {
-    least_received_packet_number_ =
-        std::min(least_received_packet_number_, packet_number);
-  } else {
-    least_received_packet_number_ = packet_number;
-  }
-}
-
-bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
-  return LargestAcked(ack_frame_).IsInitialized() &&
-         packet_number < LargestAcked(ack_frame_) &&
-         !ack_frame_.packets.Contains(packet_number);
-}
-
-bool QuicReceivedPacketManager::IsAwaitingPacket(
-    QuicPacketNumber packet_number) const {
-  return quic::IsAwaitingPacket(ack_frame_, packet_number,
-                                peer_least_packet_awaiting_ack_);
-}
-
-const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame(
-    QuicTime approximate_now) {
-  if (time_largest_observed_ == QuicTime::Zero()) {
-    // We have received no packets.
-    ack_frame_.ack_delay_time = QuicTime::Delta::Infinite();
-  } else {
-    // Ensure the delta is zero if approximate now is "in the past".
-    ack_frame_.ack_delay_time = approximate_now < time_largest_observed_
-                                    ? QuicTime::Delta::Zero()
-                                    : approximate_now - time_largest_observed_;
-  }
-  while (max_ack_ranges_ > 0 &&
-         ack_frame_.packets.NumIntervals() > max_ack_ranges_) {
-    ack_frame_.packets.RemoveSmallestInterval();
-  }
-  // Clear all packet times if any are too far from largest observed.
-  // It's expected this is extremely rare.
-  for (auto it = ack_frame_.received_packet_times.begin();
-       it != ack_frame_.received_packet_times.end();) {
-    if (LargestAcked(ack_frame_) - it->first >=
-        std::numeric_limits<uint8_t>::max()) {
-      it = ack_frame_.received_packet_times.erase(it);
-    } else {
-      ++it;
-    }
-  }
-
-#if QUIC_FRAME_DEBUG
-  QuicFrame frame = QuicFrame(&ack_frame_);
-  frame.delete_forbidden = true;
-  return frame;
-#else  // QUIC_FRAME_DEBUG
-  return QuicFrame(&ack_frame_);
-#endif  // QUIC_FRAME_DEBUG
-}
-
-void QuicReceivedPacketManager::DontWaitForPacketsBefore(
-    QuicPacketNumber least_unacked) {
-  if (!least_unacked.IsInitialized()) {
-    return;
-  }
-  // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks.
-  QUICHE_DCHECK(!peer_least_packet_awaiting_ack_.IsInitialized() ||
-                peer_least_packet_awaiting_ack_ <= least_unacked);
-  if (!peer_least_packet_awaiting_ack_.IsInitialized() ||
-      least_unacked > peer_least_packet_awaiting_ack_) {
-    peer_least_packet_awaiting_ack_ = least_unacked;
-    bool packets_updated = ack_frame_.packets.RemoveUpTo(least_unacked);
-    if (packets_updated) {
-      // Ack frame gets updated because packets set is updated because of stop
-      // waiting frame.
-      ack_frame_updated_ = true;
-    }
-  }
-  QUICHE_DCHECK(ack_frame_.packets.Empty() ||
-                !peer_least_packet_awaiting_ack_.IsInitialized() ||
-                ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_);
-}
-
-QuicTime::Delta QuicReceivedPacketManager::GetMaxAckDelay(
-    QuicPacketNumber last_received_packet_number,
-    const RttStats& rtt_stats) const {
-  if (AckFrequencyFrameReceived() ||
-      last_received_packet_number < PeerFirstSendingPacketNumber() +
-                                        min_received_before_ack_decimation_) {
-    return local_max_ack_delay_;
-  }
-
-  // Wait for the minimum of the ack decimation delay or the delayed ack time
-  // before sending an ack.
-  QuicTime::Delta ack_delay = std::min(
-      local_max_ack_delay_, rtt_stats.min_rtt() * ack_decimation_delay_);
-  return std::max(ack_delay, kAlarmGranularity);
-}
-
-void QuicReceivedPacketManager::MaybeUpdateAckFrequency(
-    QuicPacketNumber last_received_packet_number) {
-  if (AckFrequencyFrameReceived()) {
-    // Skip Ack Decimation below after receiving an AckFrequencyFrame from the
-    // other end point.
-    return;
-  }
-  if (last_received_packet_number <
-      PeerFirstSendingPacketNumber() + min_received_before_ack_decimation_) {
-    return;
-  }
-  ack_frequency_ = unlimited_ack_decimation_
-                       ? std::numeric_limits<size_t>::max()
-                       : kMaxRetransmittablePacketsBeforeAck;
-}
-
-void QuicReceivedPacketManager::MaybeUpdateAckTimeout(
-    bool should_last_packet_instigate_acks,
-    QuicPacketNumber last_received_packet_number,
-    QuicTime last_packet_receipt_time, QuicTime now,
-    const RttStats* rtt_stats) {
-  if (!ack_frame_updated_) {
-    // ACK frame has not been updated, nothing to do.
-    return;
-  }
-
-  if (!ignore_order_ && was_last_packet_missing_ &&
-      last_sent_largest_acked_.IsInitialized() &&
-      last_received_packet_number < last_sent_largest_acked_) {
-    // Only ack immediately if an ACK frame was sent with a larger largest acked
-    // than the newly received packet number.
-    ack_timeout_ = now;
-    return;
-  }
-
-  if (!should_last_packet_instigate_acks) {
-    return;
-  }
-
-  ++num_retransmittable_packets_received_since_last_ack_sent_;
-
-  MaybeUpdateAckFrequency(last_received_packet_number);
-  if (num_retransmittable_packets_received_since_last_ack_sent_ >=
-      ack_frequency_) {
-    ack_timeout_ = now;
-    return;
-  }
-
-  if (!ignore_order_ && HasNewMissingPackets()) {
-    ack_timeout_ = now;
-    return;
-  }
-
-  QuicTime ack_timeout_base = now;
-  const bool quic_update_ack_timeout_on_receipt_time =
-      GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time);
-  if (quic_update_ack_timeout_on_receipt_time) {
-    if (last_packet_receipt_time <= now) {
-      QUIC_CODE_COUNT(quic_update_ack_timeout_on_receipt_time);
-      ack_timeout_base = last_packet_receipt_time;
-    } else {
-      QUIC_CODE_COUNT(quic_update_ack_timeout_on_now);
-      ack_timeout_base = now;
-    }
-  }
-  QuicTime updated_ack_time =
-      ack_timeout_base +
-      GetMaxAckDelay(last_received_packet_number, *rtt_stats);
-  if (quic_update_ack_timeout_on_receipt_time) {
-    updated_ack_time = std::max(now, updated_ack_time);
-  }
-  if (!ack_timeout_.IsInitialized() || ack_timeout_ > updated_ack_time) {
-    ack_timeout_ = updated_ack_time;
-  }
-}
-
-void QuicReceivedPacketManager::ResetAckStates() {
-  ack_frame_updated_ = false;
-  ack_timeout_ = QuicTime::Zero();
-  num_retransmittable_packets_received_since_last_ack_sent_ = 0;
-  last_sent_largest_acked_ = LargestAcked(ack_frame_);
-}
-
-bool QuicReceivedPacketManager::HasMissingPackets() const {
-  if (ack_frame_.packets.Empty()) {
-    return false;
-  }
-  if (ack_frame_.packets.NumIntervals() > 1) {
-    return true;
-  }
-  return peer_least_packet_awaiting_ack_.IsInitialized() &&
-         ack_frame_.packets.Min() > peer_least_packet_awaiting_ack_;
-}
-
-bool QuicReceivedPacketManager::HasNewMissingPackets() const {
-  if (one_immediate_ack_) {
-    return HasMissingPackets() && ack_frame_.packets.LastIntervalLength() == 1;
-  }
-  return HasMissingPackets() &&
-         ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing;
-}
-
-bool QuicReceivedPacketManager::ack_frame_updated() const {
-  return ack_frame_updated_;
-}
-
-QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const {
-  return LargestAcked(ack_frame_);
-}
-
-QuicPacketNumber QuicReceivedPacketManager::PeerFirstSendingPacketNumber()
-    const {
-  if (!least_received_packet_number_.IsInitialized()) {
-    QUIC_BUG(quic_bug_10849_1) << "No packets have been received yet";
-    return QuicPacketNumber(1);
-  }
-  return least_received_packet_number_;
-}
-
-bool QuicReceivedPacketManager::IsAckFrameEmpty() const {
-  return ack_frame_.packets.Empty();
-}
-
-void QuicReceivedPacketManager::OnAckFrequencyFrame(
-    const QuicAckFrequencyFrame& frame) {
-  int64_t new_sequence_number = frame.sequence_number;
-  if (new_sequence_number <= last_ack_frequency_frame_sequence_number_) {
-    // Ignore old ACK_FREQUENCY frames.
-    return;
-  }
-  last_ack_frequency_frame_sequence_number_ = new_sequence_number;
-  ack_frequency_ = frame.packet_tolerance;
-  local_max_ack_delay_ = frame.max_ack_delay;
-  ignore_order_ = frame.ignore_order;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_received_packet_manager.h b/quic/core/quic_received_packet_manager.h
deleted file mode 100644
index 7d8edf8..0000000
--- a/quic/core/quic_received_packet_manager.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
-
-#include <cstddef>
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class RttStats;
-
-namespace test {
-class QuicConnectionPeer;
-class QuicReceivedPacketManagerPeer;
-class UberReceivedPacketManagerPeer;
-}  // namespace test
-
-struct QuicConnectionStats;
-
-// Records all received packets by a connection.
-class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
- public:
-  QuicReceivedPacketManager();
-  explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
-  QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete;
-  QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) =
-      delete;
-  virtual ~QuicReceivedPacketManager();
-
-  void SetFromConfig(const QuicConfig& config, Perspective perspective);
-
-  // Updates the internal state concerning which packets have been received.
-  // header: the packet header.
-  // timestamp: the arrival time of the packet.
-  virtual void RecordPacketReceived(const QuicPacketHeader& header,
-                                    QuicTime receipt_time);
-
-  // Checks whether |packet_number| is missing and less than largest observed.
-  virtual bool IsMissing(QuicPacketNumber packet_number);
-
-  // Checks if we're still waiting for the packet with |packet_number|.
-  virtual bool IsAwaitingPacket(QuicPacketNumber packet_number) const;
-
-  // Retrieves a frame containing a QuicAckFrame.  The ack frame may not be
-  // changed outside QuicReceivedPacketManager and must be serialized before
-  // another packet is received, or it will change.
-  const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now);
-
-  // Deletes all missing packets before least unacked. The connection won't
-  // process any packets with packet number before |least_unacked| that it
-  // received after this call.
-  void DontWaitForPacketsBefore(QuicPacketNumber least_unacked);
-
-  // Called to update ack_timeout_ to the time when an ACK needs to be sent. A
-  // caller can decide whether and when to send an ACK by retrieving
-  // ack_timeout_. If ack_timeout_ is not initialized, no ACK needs to be sent.
-  // Otherwise, ACK needs to be sent by the specified time.
-  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
-                             QuicPacketNumber last_received_packet_number,
-                             QuicTime last_packet_receipt_time, QuicTime now,
-                             const RttStats* rtt_stats);
-
-  // Resets ACK related states, called after an ACK is successfully sent.
-  void ResetAckStates();
-
-  // Returns true if there are any missing packets.
-  bool HasMissingPackets() const;
-
-  // Returns true when there are new missing packets to be reported within 3
-  // packets of the largest observed.
-  virtual bool HasNewMissingPackets() const;
-
-  QuicPacketNumber peer_least_packet_awaiting_ack() const {
-    return peer_least_packet_awaiting_ack_;
-  }
-
-  virtual bool ack_frame_updated() const;
-
-  QuicPacketNumber GetLargestObserved() const;
-
-  // Returns peer first sending packet number to our best knowledge. Considers
-  // least_received_packet_number_ as peer first sending packet number. Please
-  // note, this function should only be called when at least one packet has been
-  // received.
-  QuicPacketNumber PeerFirstSendingPacketNumber() const;
-
-  // Returns true if ack frame is empty.
-  bool IsAckFrameEmpty() const;
-
-  void set_connection_stats(QuicConnectionStats* stats) { stats_ = stats; }
-
-  // For logging purposes.
-  const QuicAckFrame& ack_frame() const { return ack_frame_; }
-
-  void set_max_ack_ranges(size_t max_ack_ranges) {
-    max_ack_ranges_ = max_ack_ranges;
-  }
-
-  void set_save_timestamps(bool save_timestamps, bool in_order_packets_only) {
-    save_timestamps_ = save_timestamps;
-    save_timestamps_for_in_order_packets_ = in_order_packets_only;
-  }
-
-  size_t min_received_before_ack_decimation() const {
-    return min_received_before_ack_decimation_;
-  }
-  void set_min_received_before_ack_decimation(size_t new_value) {
-    min_received_before_ack_decimation_ = new_value;
-  }
-
-  void set_ack_frequency(size_t new_value) {
-    QUICHE_DCHECK_GT(new_value, 0u);
-    ack_frequency_ = new_value;
-  }
-
-  void set_local_max_ack_delay(QuicTime::Delta local_max_ack_delay) {
-    local_max_ack_delay_ = local_max_ack_delay;
-  }
-
-  QuicTime ack_timeout() const { return ack_timeout_; }
-
-  void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
-
- private:
-  friend class test::QuicConnectionPeer;
-  friend class test::QuicReceivedPacketManagerPeer;
-  friend class test::UberReceivedPacketManagerPeer;
-
-  // Sets ack_timeout_ to |time| if ack_timeout_ is not initialized or > time.
-  void MaybeUpdateAckTimeoutTo(QuicTime time);
-
-  // Maybe update ack_frequency_ when condition meets.
-  void MaybeUpdateAckFrequency(QuicPacketNumber last_received_packet_number);
-
-  QuicTime::Delta GetMaxAckDelay(QuicPacketNumber last_received_packet_number,
-                                 const RttStats& rtt_stats) const;
-
-  bool AckFrequencyFrameReceived() const {
-    return last_ack_frequency_frame_sequence_number_ >= 0;
-  }
-
-  // Least packet number of the the packet sent by the peer for which it
-  // hasn't received an ack.
-  QuicPacketNumber peer_least_packet_awaiting_ack_;
-
-  // Received packet information used to produce acks.
-  QuicAckFrame ack_frame_;
-
-  // True if |ack_frame_| has been updated since UpdateReceivedPacketInfo was
-  // last called.
-  bool ack_frame_updated_;
-
-  // Maximum number of ack ranges allowed to be stored in the ack frame.
-  size_t max_ack_ranges_;
-
-  // The time we received the largest_observed packet number, or zero if
-  // no packet numbers have been received since UpdateReceivedPacketInfo.
-  // Needed for calculating ack_delay_time.
-  QuicTime time_largest_observed_;
-
-  // If true, save timestamps in the ack_frame_.
-  bool save_timestamps_;
-
-  // If true and |save_timestamps_|, only save timestamps for packets that are
-  // received in order.
-  bool save_timestamps_for_in_order_packets_;
-
-  // Least packet number received from peer.
-  QuicPacketNumber least_received_packet_number_;
-
-  QuicConnectionStats* stats_;
-
-  // How many retransmittable packets have arrived without sending an ack.
-  QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_;
-  // Ack decimation will start happening after this many packets are received.
-  size_t min_received_before_ack_decimation_;
-  // Ack every n-th packet.
-  size_t ack_frequency_;
-  // The max delay in fraction of min_rtt to use when sending decimated acks.
-  float ack_decimation_delay_;
-  // When true, removes ack decimation's max number of packets(10) before
-  // sending an ack.
-  bool unlimited_ack_decimation_;
-  // When true, only send 1 immediate ACK when reordering is detected.
-  bool one_immediate_ack_;
-  // When true, do not ack immediately upon observation of packet reordering.
-  bool ignore_order_;
-
-  // The local node's maximum ack delay time. This is the maximum amount of
-  // time to wait before sending an acknowledgement.
-  QuicTime::Delta local_max_ack_delay_;
-  // Time that an ACK needs to be sent. 0 means no ACK is pending. Used when
-  // decide_when_to_send_acks_ is true.
-  QuicTime ack_timeout_;
-
-  // The time the previous ack-instigating packet was received and processed.
-  QuicTime time_of_previous_received_packet_;
-  // Whether the most recent packet was missing before it was received.
-  bool was_last_packet_missing_;
-
-  // Last sent largest acked, which gets updated when ACK was successfully sent.
-  QuicPacketNumber last_sent_largest_acked_;
-
-  // The sequence number of the last received AckFrequencyFrame. Negative if
-  // none received.
-  int64_t last_ack_frequency_frame_sequence_number_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
diff --git a/quic/core/quic_received_packet_manager_test.cc b/quic/core/quic_received_packet_manager_test.cc
deleted file mode 100644
index 0bb6160..0000000
--- a/quic/core/quic_received_packet_manager_test.cc
+++ /dev/null
@@ -1,691 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_received_packet_manager.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <ostream>
-#include <vector>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class QuicReceivedPacketManagerPeer {
- public:
-  static void SetOneImmediateAck(QuicReceivedPacketManager* manager,
-                                 bool one_immediate_ack) {
-    manager->one_immediate_ack_ = one_immediate_ack;
-  }
-
-  static void SetAckDecimationDelay(QuicReceivedPacketManager* manager,
-                                    float ack_decimation_delay) {
-    manager->ack_decimation_delay_ = ack_decimation_delay;
-  }
-};
-
-namespace {
-
-const bool kInstigateAck = true;
-const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
-const QuicTime::Delta kDelayedAckTime =
-    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-class QuicReceivedPacketManagerTest : public QuicTest {
- protected:
-  QuicReceivedPacketManagerTest() : received_manager_(&stats_) {
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
-    received_manager_.set_save_timestamps(true, false);
-  }
-
-  void RecordPacketReceipt(uint64_t packet_number) {
-    RecordPacketReceipt(packet_number, QuicTime::Zero());
-  }
-
-  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
-    QuicPacketHeader header;
-    header.packet_number = QuicPacketNumber(packet_number);
-    received_manager_.RecordPacketReceived(header, receipt_time);
-  }
-
-  bool HasPendingAck() {
-    return received_manager_.ack_timeout().IsInitialized();
-  }
-
-  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
-                             uint64_t last_received_packet_number) {
-    received_manager_.MaybeUpdateAckTimeout(
-        should_last_packet_instigate_acks,
-        QuicPacketNumber(last_received_packet_number),
-        /*last_packet_receipt_time=*/clock_.ApproximateNow(),
-        /*now=*/clock_.ApproximateNow(), &rtt_stats_);
-  }
-
-  void CheckAckTimeout(QuicTime time) {
-    QUICHE_DCHECK(HasPendingAck());
-    QUICHE_DCHECK_EQ(received_manager_.ack_timeout(), time);
-    if (time <= clock_.ApproximateNow()) {
-      // ACK timeout expires, send an ACK.
-      received_manager_.ResetAckStates();
-      QUICHE_DCHECK(!HasPendingAck());
-    }
-  }
-
-  MockClock clock_;
-  RttStats rtt_stats_;
-  QuicConnectionStats stats_;
-  QuicReceivedPacketManager received_manager_;
-};
-
-TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
-  QuicPacketHeader header;
-  header.packet_number = QuicPacketNumber(2u);
-  received_manager_.RecordPacketReceived(header, QuicTime::Zero());
-  header.packet_number = QuicPacketNumber(7u);
-  received_manager_.RecordPacketReceived(header, QuicTime::Zero());
-  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
-  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
-  received_manager_.DontWaitForPacketsBefore(QuicPacketNumber(4));
-  EXPECT_FALSE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
-  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
-}
-
-TEST_F(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
-  QuicPacketHeader header;
-  header.packet_number = QuicPacketNumber(2u);
-  QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  received_manager_.RecordPacketReceived(header, two_ms);
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-
-  QuicFrame ack = received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
-  received_manager_.ResetAckStates();
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  // When UpdateReceivedPacketInfo with a time earlier than the time of the
-  // largest observed packet, make sure that the delta is 0, not negative.
-  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
-  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
-  QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
-  ack = received_manager_.GetUpdatedAckFrame(four_ms);
-  received_manager_.ResetAckStates();
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  // When UpdateReceivedPacketInfo after not having received a new packet,
-  // the delta should still be accurate.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
-            ack.ack_frame->ack_delay_time);
-  // And received packet times won't have change.
-  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
-  header.packet_number = QuicPacketNumber(999u);
-  received_manager_.RecordPacketReceived(header, two_ms);
-  header.packet_number = QuicPacketNumber(4u);
-  received_manager_.RecordPacketReceived(header, two_ms);
-  header.packet_number = QuicPacketNumber(1000u);
-  received_manager_.RecordPacketReceived(header, two_ms);
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-  ack = received_manager_.GetUpdatedAckFrame(two_ms);
-  received_manager_.ResetAckStates();
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  // UpdateReceivedPacketInfo should discard any times which can't be
-  // expressed on the wire.
-  EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  RecordPacketReceipt(1);
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-  RecordPacketReceipt(6);
-  RecordPacketReceipt(2,
-                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-
-  EXPECT_EQ(4u, stats_.max_sequence_reordering);
-  EXPECT_EQ(1000, stats_.max_time_reordering_us);
-  EXPECT_EQ(1u, stats_.packets_reordered);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, LimitAckRanges) {
-  received_manager_.set_max_ack_ranges(10);
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  for (int i = 0; i < 100; ++i) {
-    RecordPacketReceipt(1 + 2 * i);
-    EXPECT_TRUE(received_manager_.ack_frame_updated());
-    received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
-    EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
-    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
-              received_manager_.ack_frame().packets.Max());
-    for (int j = 0; j < std::min(10, i + 1); ++j) {
-      ASSERT_GE(i, j);
-      EXPECT_TRUE(received_manager_.ack_frame().packets.Contains(
-          QuicPacketNumber(1 + (i - j) * 2)));
-      if (i > j) {
-        EXPECT_FALSE(received_manager_.ack_frame().packets.Contains(
-            QuicPacketNumber((i - j) * 2)));
-      }
-    }
-  }
-}
-
-TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  RecordPacketReceipt(1, QuicTime::Zero());
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-  EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
-  RecordPacketReceipt(2,
-                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-  RecordPacketReceipt(3, QuicTime::Zero());
-  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderPackets) {
-  received_manager_.set_save_timestamps(true, true);
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  RecordPacketReceipt(1, QuicTime::Zero());
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-  EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
-  RecordPacketReceipt(4,
-                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-
-  RecordPacketReceipt(3,
-                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(3));
-  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, HasMissingPackets) {
-  EXPECT_QUIC_BUG(received_manager_.PeerFirstSendingPacketNumber(),
-                  "No packets have been received yet");
-  RecordPacketReceipt(4, QuicTime::Zero());
-  EXPECT_EQ(QuicPacketNumber(4),
-            received_manager_.PeerFirstSendingPacketNumber());
-  EXPECT_FALSE(received_manager_.HasMissingPackets());
-  RecordPacketReceipt(3, QuicTime::Zero());
-  EXPECT_FALSE(received_manager_.HasMissingPackets());
-  EXPECT_EQ(QuicPacketNumber(3),
-            received_manager_.PeerFirstSendingPacketNumber());
-  RecordPacketReceipt(1, QuicTime::Zero());
-  EXPECT_EQ(QuicPacketNumber(1),
-            received_manager_.PeerFirstSendingPacketNumber());
-  EXPECT_TRUE(received_manager_.HasMissingPackets());
-  RecordPacketReceipt(2, QuicTime::Zero());
-  EXPECT_EQ(QuicPacketNumber(1),
-            received_manager_.PeerFirstSendingPacketNumber());
-  EXPECT_FALSE(received_manager_.HasMissingPackets());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(3, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 3);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(5, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 5);
-  // Immediate ack is sent.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(6, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 6);
-  // Immediate ack is scheduled, because 4 is still missing.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 2);
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 1);
-  // Should ack immediately, since this fills the last hole.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(7, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 7);
-  // Immediate ack is scheduled, because 4 is still missing.
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent1Ack) {
-  QuicReceivedPacketManagerPeer::SetOneImmediateAck(&received_manager_, true);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(3, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 3);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(5, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 5);
-  // Immediate ack is sent.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(6, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 6);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 2);
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 1);
-  // Should ack immediately, since this fills the last hole.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(7, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 7);
-  // Delayed ack is scheduled, even though 4 is still missing.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 2);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 1);
-  EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, AckReceiptCausesAckSend) {
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 1);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 2);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(3, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 3);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-  clock_.AdvanceTime(kDelayedAckTime);
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(4, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 4);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(5, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 5);
-  EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, AckSentEveryNthPacket) {
-  EXPECT_FALSE(HasPendingAck());
-  received_manager_.set_ack_frequency(3);
-
-  // Receives packets 1 - 39.
-  for (size_t i = 1; i <= 39; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 3 == 0) {
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-}
-
-TEST_F(QuicReceivedPacketManagerTest, AckDecimationReducesAcks) {
-  EXPECT_FALSE(HasPendingAck());
-
-  // Start ack decimation from 10th packet.
-  received_manager_.set_min_received_before_ack_decimation(10);
-
-  // Receives packets 1 - 29.
-  for (size_t i = 1; i <= 29; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i <= 10) {
-      // For packets 1-10, ack every 2 packets.
-      if (i % 2 == 0) {
-        CheckAckTimeout(clock_.ApproximateNow());
-      } else {
-        CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-      }
-      continue;
-    }
-    // ack at 20.
-    if (i == 20) {
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
-    }
-  }
-
-  // We now receive the 30th packet, and so we send an ack.
-  RecordPacketReceipt(30, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 30);
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimation) {
-  EXPECT_FALSE(HasPendingAck());
-  // The ack time should be based on min_rtt * 1/4, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
-  // Process all the packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // The 10th received packet causes an ack to be sent.
-  for (uint64_t i = 1; i < 10; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationMin1ms) {
-  EXPECT_FALSE(HasPendingAck());
-  // Seed the min_rtt with a kAlarmGranularity signal.
-  rtt_stats_.UpdateRtt(kAlarmGranularity, QuicTime::Delta::Zero(),
-                       clock_.ApproximateNow());
-  // The ack time should be based on kAlarmGranularity, since the RTT is 1ms.
-  QuicTime ack_time = clock_.ApproximateNow() + kAlarmGranularity;
-
-  // Process all the packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // The 10th received packet causes an ack to be sent.
-  for (uint64_t i = 1; i < 10; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
-       SendDelayedAckDecimationUnlimitedAggregation) {
-  EXPECT_FALSE(HasPendingAck());
-  QuicConfig config;
-  QuicTagVector connection_options;
-  // No limit on the number of packets received before sending an ack.
-  connection_options.push_back(kAKDU);
-  config.SetConnectionOptionsToSend(connection_options);
-  received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
-
-  // The ack time should be based on min_rtt/4, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
-  // Process all the initial packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // 18 packets will not cause an ack to be sent.  19 will because when
-  // stop waiting frames are in use, we ack every 20 packets no matter what.
-  for (int i = 1; i <= 18; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(ack_time);
-}
-
-TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
-  EXPECT_FALSE(HasPendingAck());
-  QuicReceivedPacketManagerPeer::SetAckDecimationDelay(&received_manager_,
-                                                       0.125);
-
-  // The ack time should be based on min_rtt/8, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
-
-  // Process all the packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // The 10th received packet causes an ack to be sent.
-  for (uint64_t i = 1; i < 10; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
-       UpdateMaxAckDelayAndAckFrequencyFromAckFrequencyFrame) {
-  EXPECT_FALSE(HasPendingAck());
-
-  QuicAckFrequencyFrame frame;
-  frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(10);
-  frame.packet_tolerance = 5;
-  received_manager_.OnAckFrequencyFrame(frame);
-
-  for (int i = 1; i <= 50; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % frame.packet_tolerance == 0) {
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + frame.max_ack_delay);
-    }
-  }
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
-       DisableOutOfOrderAckByIgnoreOrderFromAckFrequencyFrame) {
-  EXPECT_FALSE(HasPendingAck());
-
-  QuicAckFrequencyFrame frame;
-  frame.max_ack_delay = kDelayedAckTime;
-  frame.packet_tolerance = 2;
-  frame.ignore_order = true;
-  received_manager_.OnAckFrequencyFrame(frame);
-
-  RecordPacketReceipt(4, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 4);
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-  RecordPacketReceipt(5, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 5);
-  // Immediate ack is sent as this is the 2nd packet of every two packets.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(3, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 3);
-  // Don't ack as ignore_order is set by AckFrequencyFrame.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 2);
-  // Immediate ack is sent as this is the 2nd packet of every two packets.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 1);
-  // Don't ack as ignore_order is set by AckFrequencyFrame.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
-       DisableMissingPaketsAckByIgnoreOrderFromAckFrequencyFrame) {
-  EXPECT_FALSE(HasPendingAck());
-  QuicConfig config;
-  config.SetConnectionOptionsToSend({kAFFE});
-  received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
-
-  QuicAckFrequencyFrame frame;
-  frame.max_ack_delay = kDelayedAckTime;
-  frame.packet_tolerance = 2;
-  frame.ignore_order = true;
-  received_manager_.OnAckFrequencyFrame(frame);
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 1);
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 2);
-  // Immediate ack is sent as this is the 2nd packet of every two packets.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(4, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 4);
-  // Don't ack even if packet 3 is newly missing as ignore_order is set by
-  // AckFrequencyFrame.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(5, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 5);
-  // Immediate ack is sent as this is the 2nd packet of every two packets.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(7, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 7);
-  // Don't ack even if packet 6 is newly missing as ignore_order is set by
-  // AckFrequencyFrame.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
-       AckDecimationDisabledWhenAckFrequencyFrameIsReceived) {
-  EXPECT_FALSE(HasPendingAck());
-
-  QuicAckFrequencyFrame frame;
-  frame.max_ack_delay = kDelayedAckTime;
-  frame.packet_tolerance = 3;
-  frame.ignore_order = true;
-  received_manager_.OnAckFrequencyFrame(frame);
-
-  // Process all the packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  uint64_t FiftyPacketsAfterAckDecimation = kFirstDecimatedPacket + 50;
-  for (uint64_t i = 1; i < FiftyPacketsAfterAckDecimation; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 3 == 0) {
-      // Ack every 3 packets as decimation is disabled.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      // Ack at default delay as decimation is disabled.
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-}
-
-TEST_F(QuicReceivedPacketManagerTest, UpdateAckTimeoutOnPacketReceiptTime) {
-  EXPECT_FALSE(HasPendingAck());
-
-  // Received packets 3 and 4.
-  QuicTime packet_receipt_time3 = clock_.ApproximateNow();
-  // Packet 3 gets processed after 10ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  RecordPacketReceipt(3, packet_receipt_time3);
-  received_manager_.MaybeUpdateAckTimeout(
-      kInstigateAck, QuicPacketNumber(3),
-      /*last_packet_receipt_time=*/packet_receipt_time3,
-      clock_.ApproximateNow(), &rtt_stats_);
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    // Make sure ACK timeout is based on receipt time.
-    CheckAckTimeout(packet_receipt_time3 + kDelayedAckTime);
-  } else {
-    // Make sure ACK timeout is based on now.
-    CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-  }
-
-  RecordPacketReceipt(4, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 4);
-  // Immediate ack is sent.
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(QuicReceivedPacketManagerTest,
-       UpdateAckTimeoutOnPacketReceiptTimeLongerQueuingTime) {
-  EXPECT_FALSE(HasPendingAck());
-
-  // Received packets 3 and 4.
-  QuicTime packet_receipt_time3 = clock_.ApproximateNow();
-  // Packet 3 gets processed after 100ms.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  RecordPacketReceipt(3, packet_receipt_time3);
-  received_manager_.MaybeUpdateAckTimeout(
-      kInstigateAck, QuicPacketNumber(3),
-      /*last_packet_receipt_time=*/packet_receipt_time3,
-      clock_.ApproximateNow(), &rtt_stats_);
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    // Given 100ms > ack delay, verify immediate ACK.
-    CheckAckTimeout(clock_.ApproximateNow());
-  } else {
-    // Make sure ACK timeout is based on now.
-    CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc
deleted file mode 100644
index 6fabf5b..0000000
--- a/quic/core/quic_sent_packet_manager.cc
+++ /dev/null
@@ -1,1872 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_sent_packet_manager.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <string>
-
-#include "quic/core/congestion_control/general_loss_algorithm.h"
-#include "quic/core/congestion_control/pacing_sender.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/print_elements.h"
-
-namespace quic {
-
-namespace {
-static const int64_t kDefaultRetransmissionTimeMs = 500;
-static const int64_t kMaxRetransmissionTimeMs = 60000;
-// Maximum number of exponential backoffs used for RTO timeouts.
-static const size_t kMaxRetransmissions = 10;
-// Maximum number of packets retransmitted upon an RTO.
-static const size_t kMaxRetransmissionsOnTimeout = 2;
-// The path degrading delay is the sum of this number of consecutive RTO delays.
-const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
-
-// Ensure the handshake timer isnt't faster than 10ms.
-// This limits the tenth retransmitted packet to 10s after the initial CHLO.
-static const int64_t kMinHandshakeTimeoutMs = 10;
-
-// Sends up to two tail loss probes before firing an RTO,
-// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
-static const size_t kDefaultMaxTailLossProbes = 2;
-
-// Returns true of retransmissions of the specified type should retransmit
-// the frames directly (as opposed to resulting in a loss notification).
-inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
-  return transmission_type == HANDSHAKE_RETRANSMISSION ||
-         transmission_type == TLP_RETRANSMISSION ||
-         transmission_type == PROBING_RETRANSMISSION ||
-         transmission_type == RTO_RETRANSMISSION ||
-         transmission_type == PTO_RETRANSMISSION;
-}
-
-// If pacing rate is accurate, > 2 burst token is not likely to help first ACK
-// to arrive earlier, and overly large burst token could cause incast packet
-// losses.
-static const uint32_t kConservativeUnpacedBurst = 2;
-
-}  // namespace
-
-#define ENDPOINT                                                         \
-  (unacked_packets_.perspective() == Perspective::IS_SERVER ? "Server: " \
-                                                            : "Client: ")
-
-QuicSentPacketManager::QuicSentPacketManager(
-    Perspective perspective, const QuicClock* clock, QuicRandom* random,
-    QuicConnectionStats* stats, CongestionControlType congestion_control_type)
-    : unacked_packets_(perspective),
-      clock_(clock),
-      random_(random),
-      stats_(stats),
-      debug_delegate_(nullptr),
-      network_change_visitor_(nullptr),
-      initial_congestion_window_(kInitialCongestionWindow),
-      loss_algorithm_(&uber_loss_algorithm_),
-      consecutive_rto_count_(0),
-      consecutive_tlp_count_(0),
-      consecutive_crypto_retransmission_count_(0),
-      pending_timer_transmission_count_(0),
-      max_tail_loss_probes_(kDefaultMaxTailLossProbes),
-      max_rto_packets_(kMaxRetransmissionsOnTimeout),
-      using_pacing_(false),
-      use_new_rto_(false),
-      conservative_handshake_retransmits_(false),
-      min_tlp_timeout_(
-          QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
-      min_rto_timeout_(
-          QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
-      largest_mtu_acked_(0),
-      handshake_finished_(false),
-      peer_max_ack_delay_(
-          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
-      rtt_updated_(false),
-      acked_packets_iter_(last_ack_frame_.packets.rbegin()),
-      pto_enabled_(GetQuicRestartFlag(quic_default_on_pto2)),
-      max_probe_packets_per_pto_(2),
-      consecutive_pto_count_(0),
-      handshake_mode_disabled_(false),
-      skip_packet_number_for_pto_(false),
-      always_include_max_ack_delay_for_pto_timeout_(true),
-      pto_exponential_backoff_start_point_(0),
-      pto_rttvar_multiplier_(4),
-      num_tlp_timeout_ptos_(0),
-      handshake_packet_acked_(false),
-      zero_rtt_packet_acked_(false),
-      one_rtt_packet_acked_(false),
-      first_pto_srtt_multiplier_(0),
-      use_standard_deviation_for_pto_(false),
-      pto_multiplier_without_rtt_samples_(3),
-      num_ptos_for_path_degrading_(0),
-      ignore_pings_(false),
-      ignore_ack_delay_(false) {
-  SetSendAlgorithm(congestion_control_type);
-  if (pto_enabled_) {
-    QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 1, 2);
-    // TODO(fayang): change the default values when deprecating
-    // quic_default_on_pto2.
-    // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
-    // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
-    // last in flight packet.
-    max_probe_packets_per_pto_ = 1;
-    skip_packet_number_for_pto_ = true;
-    first_pto_srtt_multiplier_ = 1.5;
-    pto_rttvar_multiplier_ = 2;
-  }
-}
-
-QuicSentPacketManager::~QuicSentPacketManager() {}
-
-void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
-  const Perspective perspective = unacked_packets_.perspective();
-  if (config.HasReceivedInitialRoundTripTimeUs() &&
-      config.ReceivedInitialRoundTripTimeUs() > 0) {
-    if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
-      SetInitialRtt(QuicTime::Delta::FromMicroseconds(
-                        config.ReceivedInitialRoundTripTimeUs()),
-                    /*trusted=*/false);
-    }
-  } else if (config.HasInitialRoundTripTimeUsToSend() &&
-             config.GetInitialRoundTripTimeUsToSend() > 0) {
-    SetInitialRtt(QuicTime::Delta::FromMicroseconds(
-                      config.GetInitialRoundTripTimeUsToSend()),
-                  /*trusted=*/false);
-  }
-  if (config.HasReceivedMaxAckDelayMs()) {
-    peer_max_ack_delay_ =
-        QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
-  }
-  if (GetQuicReloadableFlag(quic_can_send_ack_frequency) &&
-      perspective == Perspective::IS_SERVER) {
-    if (config.HasReceivedMinAckDelayMs()) {
-      peer_min_ack_delay_ =
-          QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs());
-    }
-    if (config.HasClientSentConnectionOption(kAFF1, perspective)) {
-      use_smoothed_rtt_in_ack_delay_ = true;
-    }
-  }
-  if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
-    ignore_ack_delay_ = true;
-  }
-  if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
-    // Set the minimum to the alarm granularity.
-    min_tlp_timeout_ = kAlarmGranularity;
-  }
-  if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
-    // Set the minimum to the alarm granularity.
-    min_rto_timeout_ = kAlarmGranularity;
-  }
-
-  if (!GetQuicRestartFlag(quic_default_on_pto2)) {
-    if (config.HasClientSentConnectionOption(k2PTO, perspective)) {
-      pto_enabled_ = true;
-    }
-    if (config.HasClientSentConnectionOption(k1PTO, perspective)) {
-      pto_enabled_ = true;
-      max_probe_packets_per_pto_ = 1;
-    }
-
-    if (config.HasClientSentConnectionOption(kPTOS, perspective)) {
-      if (!pto_enabled_) {
-        QUIC_PEER_BUG(quic_peer_bug_12552_1)
-            << "PTO is not enabled when receiving PTOS connection option.";
-        pto_enabled_ = true;
-        max_probe_packets_per_pto_ = 1;
-      }
-      skip_packet_number_for_pto_ = true;
-    }
-    if (pto_enabled_) {
-      if (config.HasClientSentConnectionOption(kPTOA, perspective)) {
-        always_include_max_ack_delay_for_pto_timeout_ = false;
-      }
-      if (config.HasClientSentConnectionOption(kPEB1, perspective)) {
-        StartExponentialBackoffAfterNthPto(1);
-      }
-      if (config.HasClientSentConnectionOption(kPEB2, perspective)) {
-        StartExponentialBackoffAfterNthPto(2);
-      }
-      if (config.HasClientSentConnectionOption(kPVS1, perspective)) {
-        pto_rttvar_multiplier_ = 2;
-      }
-      if (config.HasClientSentConnectionOption(kPAG1, perspective)) {
-        QUIC_CODE_COUNT(one_aggressive_pto);
-        num_tlp_timeout_ptos_ = 1;
-      }
-      if (config.HasClientSentConnectionOption(kPAG2, perspective)) {
-        QUIC_CODE_COUNT(two_aggressive_ptos);
-        num_tlp_timeout_ptos_ = 2;
-      }
-      if (config.HasClientSentConnectionOption(kPLE1, perspective)) {
-        first_pto_srtt_multiplier_ = 0.5;
-      } else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
-        first_pto_srtt_multiplier_ = 1.5;
-      }
-      if (config.HasClientSentConnectionOption(kAPTO, perspective)) {
-        pto_multiplier_without_rtt_samples_ = 1.5;
-      }
-      if (config.HasClientSentConnectionOption(kPSDA, perspective)) {
-        use_standard_deviation_for_pto_ = true;
-        rtt_stats_.EnableStandardDeviationCalculation();
-      }
-    }
-  }
-
-  if (pto_enabled_) {
-    if (config.HasClientRequestedIndependentOption(kPDP1, perspective)) {
-      num_ptos_for_path_degrading_ = 1;
-    }
-    if (config.HasClientRequestedIndependentOption(kPDP2, perspective)) {
-      num_ptos_for_path_degrading_ = 2;
-    }
-    if (config.HasClientRequestedIndependentOption(kPDP3, perspective)) {
-      num_ptos_for_path_degrading_ = 3;
-    }
-    if (config.HasClientRequestedIndependentOption(kPDP4, perspective)) {
-      num_ptos_for_path_degrading_ = 4;
-    }
-    if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
-      num_ptos_for_path_degrading_ = 5;
-    }
-  }
-
-  // Configure congestion control.
-  if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
-    SetSendAlgorithm(kBBR);
-  }
-  if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
-      config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
-    SetSendAlgorithm(kBBRv2);
-  }
-
-  if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
-    SetSendAlgorithm(kRenoBytes);
-  } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
-             (GetQuicReloadableFlag(quic_default_to_bbr) &&
-              config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
-    SetSendAlgorithm(kCubicBytes);
-  }
-
-  // Initial window.
-  if (GetQuicReloadableFlag(quic_unified_iw_options)) {
-    if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 1, 4);
-      initial_congestion_window_ = 3;
-      send_algorithm_->SetInitialCongestionWindowInPackets(3);
-    }
-    if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 2, 4);
-      initial_congestion_window_ = 10;
-      send_algorithm_->SetInitialCongestionWindowInPackets(10);
-    }
-    if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 3, 4);
-      initial_congestion_window_ = 20;
-      send_algorithm_->SetInitialCongestionWindowInPackets(20);
-    }
-    if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
-      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 4, 4);
-      initial_congestion_window_ = 50;
-      send_algorithm_->SetInitialCongestionWindowInPackets(50);
-    }
-  }
-  if (config.HasClientRequestedIndependentOption(kBWS5, perspective)) {
-    initial_congestion_window_ = 10;
-    send_algorithm_->SetInitialCongestionWindowInPackets(10);
-  }
-
-  if (config.HasClientRequestedIndependentOption(kIGNP, perspective)) {
-    ignore_pings_ = true;
-  }
-
-  using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
-
-  if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
-    max_tail_loss_probes_ = 0;
-  }
-  if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
-    max_tail_loss_probes_ = 1;
-  }
-  if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
-    max_rto_packets_ = 1;
-  }
-  if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
-    use_new_rto_ = true;
-  }
-  // Configure loss detection.
-  if (config.HasClientRequestedIndependentOption(kILD0, perspective)) {
-    uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
-    uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
-  }
-  if (config.HasClientRequestedIndependentOption(kILD1, perspective)) {
-    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
-    uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
-  }
-  if (config.HasClientRequestedIndependentOption(kILD2, perspective)) {
-    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
-    uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
-  }
-  if (config.HasClientRequestedIndependentOption(kILD3, perspective)) {
-    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
-    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
-  }
-  if (config.HasClientRequestedIndependentOption(kILD4, perspective)) {
-    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
-    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
-    uber_loss_algorithm_.EnableAdaptiveTimeThreshold();
-  }
-  if (config.HasClientRequestedIndependentOption(kRUNT, perspective)) {
-    uber_loss_algorithm_.DisablePacketThresholdForRuntPackets();
-  }
-  if (config.HasClientSentConnectionOption(kCONH, perspective)) {
-    conservative_handshake_retransmits_ = true;
-  }
-  send_algorithm_->SetFromConfig(config, perspective);
-  loss_algorithm_->SetFromConfig(config, perspective);
-
-  if (network_change_visitor_ != nullptr) {
-    network_change_visitor_->OnCongestionChange();
-  }
-
-  if (debug_delegate_ != nullptr) {
-    DebugDelegate::SendParameters parameters;
-    parameters.congestion_control_type =
-        send_algorithm_->GetCongestionControlType();
-    parameters.use_pacing = using_pacing_;
-    parameters.initial_congestion_window = initial_congestion_window_;
-    debug_delegate_->OnConfigProcessed(parameters);
-  }
-}
-
-void QuicSentPacketManager::ApplyConnectionOptions(
-    const QuicTagVector& connection_options) {
-  absl::optional<CongestionControlType> cc_type;
-  if (ContainsQuicTag(connection_options, kB2ON)) {
-    cc_type = kBBRv2;
-  } else if (ContainsQuicTag(connection_options, kTBBR)) {
-    cc_type = kBBR;
-  } else if (ContainsQuicTag(connection_options, kRENO)) {
-    cc_type = kRenoBytes;
-  } else if (ContainsQuicTag(connection_options, kQBIC)) {
-    cc_type = kCubicBytes;
-  }
-
-  if (cc_type.has_value()) {
-    SetSendAlgorithm(*cc_type);
-  }
-
-  send_algorithm_->ApplyConnectionOptions(connection_options);
-}
-
-void QuicSentPacketManager::ResumeConnectionState(
-    const CachedNetworkParameters& cached_network_params,
-    bool max_bandwidth_resumption) {
-  QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
-      max_bandwidth_resumption
-          ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
-          : cached_network_params.bandwidth_estimate_bytes_per_second());
-  QuicTime::Delta rtt =
-      QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
-  // This calls the old AdjustNetworkParameters interface, and fills certain
-  // fields in SendAlgorithmInterface::NetworkParams
-  // (e.g., quic_bbr_fix_pacing_rate) using GFE flags.
-  SendAlgorithmInterface::NetworkParams params(
-      bandwidth, rtt, /*allow_cwnd_to_decrease = */ false);
-  // The rtt is trusted because it's a min_rtt measured from a previous
-  // connection with the same network path between client and server.
-  params.is_rtt_trusted = true;
-  AdjustNetworkParameters(params);
-}
-
-void QuicSentPacketManager::AdjustNetworkParameters(
-    const SendAlgorithmInterface::NetworkParams& params) {
-  if (params.burst_token != 0) {
-    if (using_pacing_) {
-      QUIC_RELOADABLE_FLAG_COUNT(quic_set_burst_token);
-      int old_burst_size = pacing_sender_.initial_burst_size();
-      pacing_sender_.SetBurstTokens(params.burst_token);
-      if (debug_delegate_ != nullptr) {
-        debug_delegate_->OnAdjustBurstSize(old_burst_size,
-                                           pacing_sender_.initial_burst_size());
-      }
-    }
-    return;
-  }
-  const QuicBandwidth& bandwidth = params.bandwidth;
-  const QuicTime::Delta& rtt = params.rtt;
-
-  if (use_lower_min_irtt()) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 2, 2);
-    if (!rtt.IsZero()) {
-      if (params.is_rtt_trusted) {
-        // Always set initial rtt if it's trusted.
-        SetInitialRtt(rtt, /*trusted=*/true);
-      } else if (rtt_stats_.initial_rtt() ==
-                 QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
-        // Only set initial rtt if we are using the default. This avoids
-        // overwriting a trusted initial rtt by an untrusted one.
-        SetInitialRtt(rtt, /*trusted=*/false);
-      }
-    }
-  } else {
-    if (!rtt.IsZero()) {
-      SetInitialRtt(rtt, /*trusted=*/false);
-    }
-  }
-  const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
-  if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
-      !bandwidth.IsZero()) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
-    pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
-  }
-  send_algorithm_->AdjustNetworkParameters(params);
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnAdjustNetworkParameters(
-        bandwidth, rtt.IsZero() ? rtt_stats_.MinOrInitialRtt() : rtt, old_cwnd,
-        send_algorithm_->GetCongestionWindow());
-  }
-}
-
-void QuicSentPacketManager::SetLossDetectionTuner(
-    std::unique_ptr<LossDetectionTunerInterface> tuner) {
-  uber_loss_algorithm_.SetLossDetectionTuner(std::move(tuner));
-}
-
-void QuicSentPacketManager::OnConfigNegotiated() {
-  loss_algorithm_->OnConfigNegotiated();
-}
-
-void QuicSentPacketManager::OnConnectionClosed() {
-  loss_algorithm_->OnConnectionClosed();
-}
-
-void QuicSentPacketManager::SetHandshakeConfirmed() {
-  if (!handshake_finished_) {
-    handshake_finished_ = true;
-    NeuterHandshakePackets();
-  }
-}
-
-void QuicSentPacketManager::PostProcessNewlyAckedPackets(
-    QuicPacketNumber ack_packet_number,
-    EncryptionLevel ack_decrypted_level,
-    const QuicAckFrame& ack_frame,
-    QuicTime ack_receive_time,
-    bool rtt_updated,
-    QuicByteCount prior_bytes_in_flight) {
-  unacked_packets_.NotifyAggregatedStreamFrameAcked(
-      last_ack_frame_.ack_delay_time);
-  InvokeLossDetection(ack_receive_time);
-  // Ignore losses in RTO mode.
-  if (consecutive_rto_count_ > 0 && !use_new_rto_) {
-    packets_lost_.clear();
-  }
-  MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
-                             ack_receive_time);
-  unacked_packets_.RemoveObsoletePackets();
-
-  sustained_bandwidth_recorder_.RecordEstimate(
-      send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
-      send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
-      rtt_stats_.smoothed_rtt());
-
-  // Anytime we are making forward progress and have a new RTT estimate, reset
-  // the backoff counters.
-  if (rtt_updated) {
-    if (consecutive_rto_count_ > 0) {
-      // If the ack acknowledges data sent prior to the RTO,
-      // the RTO was spurious.
-      if (LargestAcked(ack_frame) < first_rto_transmission_) {
-        // Replace SRTT with latest_rtt and increase the variance to prevent
-        // a spurious RTO from happening again.
-        rtt_stats_.ExpireSmoothedMetrics();
-      } else {
-        if (!use_new_rto_) {
-          send_algorithm_->OnRetransmissionTimeout(true);
-        }
-      }
-    }
-    // Records the max consecutive RTO or PTO before forward progress has been
-    // made.
-    if (consecutive_rto_count_ >
-        stats_->max_consecutive_rto_with_forward_progress) {
-      stats_->max_consecutive_rto_with_forward_progress =
-          consecutive_rto_count_;
-    } else if (consecutive_pto_count_ >
-               stats_->max_consecutive_rto_with_forward_progress) {
-      stats_->max_consecutive_rto_with_forward_progress =
-          consecutive_pto_count_;
-    }
-    // Reset all retransmit counters any time a new packet is acked.
-    consecutive_rto_count_ = 0;
-    consecutive_tlp_count_ = 0;
-    consecutive_pto_count_ = 0;
-    consecutive_crypto_retransmission_count_ = 0;
-  }
-
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnIncomingAck(
-        ack_packet_number, ack_decrypted_level, ack_frame, ack_receive_time,
-        LargestAcked(ack_frame), rtt_updated, GetLeastUnacked());
-  }
-  // Remove packets below least unacked from all_packets_acked_ and
-  // last_ack_frame_.
-  last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
-  last_ack_frame_.received_packet_times.clear();
-}
-
-void QuicSentPacketManager::MaybeInvokeCongestionEvent(
-    bool rtt_updated,
-    QuicByteCount prior_in_flight,
-    QuicTime event_time) {
-  if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
-    return;
-  }
-  const bool overshooting_detected =
-      stats_->overshooting_detected_with_network_parameters_adjusted;
-  if (using_pacing_) {
-    pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
-                                     packets_acked_, packets_lost_);
-  } else {
-    send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
-                                       packets_acked_, packets_lost_);
-  }
-  if (debug_delegate_ != nullptr && !overshooting_detected &&
-      stats_->overshooting_detected_with_network_parameters_adjusted) {
-    debug_delegate_->OnOvershootingDetected();
-  }
-  packets_acked_.clear();
-  packets_lost_.clear();
-  if (network_change_visitor_ != nullptr) {
-    network_change_visitor_->OnCongestionChange();
-  }
-}
-
-void QuicSentPacketManager::MarkInitialPacketsForRetransmission() {
-  if (unacked_packets_.empty()) {
-    return;
-  }
-  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
-  for (; packet_number <= largest_sent_packet; ++packet_number) {
-    QuicTransmissionInfo* transmission_info =
-        unacked_packets_.GetMutableTransmissionInfo(packet_number);
-    if (transmission_info->encryption_level == ENCRYPTION_INITIAL) {
-      if (transmission_info->in_flight) {
-        unacked_packets_.RemoveFromInFlight(transmission_info);
-      }
-      if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
-        MarkForRetransmission(packet_number, ALL_INITIAL_RETRANSMISSION);
-      }
-    }
-  }
-}
-
-void QuicSentPacketManager::MarkZeroRttPacketsForRetransmission() {
-  if (unacked_packets_.empty()) {
-    return;
-  }
-  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
-  for (; packet_number <= largest_sent_packet; ++packet_number) {
-    QuicTransmissionInfo* transmission_info =
-        unacked_packets_.GetMutableTransmissionInfo(packet_number);
-    if (transmission_info->encryption_level == ENCRYPTION_ZERO_RTT) {
-      if (transmission_info->in_flight) {
-        // Remove 0-RTT packets and packets of the wrong version from flight,
-        // because neither can be processed by the peer.
-        unacked_packets_.RemoveFromInFlight(transmission_info);
-      }
-      if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
-        MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION);
-      }
-    }
-  }
-}
-
-void QuicSentPacketManager::NeuterUnencryptedPackets() {
-  for (QuicPacketNumber packet_number :
-       unacked_packets_.NeuterUnencryptedPackets()) {
-    send_algorithm_->OnPacketNeutered(packet_number);
-  }
-  if (handshake_mode_disabled_) {
-    consecutive_pto_count_ = 0;
-    uber_loss_algorithm_.ResetLossDetection(INITIAL_DATA);
-  }
-}
-
-void QuicSentPacketManager::NeuterHandshakePackets() {
-  for (QuicPacketNumber packet_number :
-       unacked_packets_.NeuterHandshakePackets()) {
-    send_algorithm_->OnPacketNeutered(packet_number);
-  }
-  if (handshake_mode_disabled_) {
-    consecutive_pto_count_ = 0;
-    uber_loss_algorithm_.ResetLossDetection(HANDSHAKE_DATA);
-  }
-}
-
-bool QuicSentPacketManager::ShouldAddMaxAckDelay(
-    PacketNumberSpace space) const {
-  QUICHE_DCHECK(pto_enabled_);
-  if (supports_multiple_packet_number_spaces() && space != APPLICATION_DATA) {
-    // When the PTO is armed for Initial or Handshake packet number spaces,
-    // the max_ack_delay is 0.
-    return false;
-  }
-  if (always_include_max_ack_delay_for_pto_timeout_) {
-    return true;
-  }
-  if (!unacked_packets_
-           .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
-           .IsInitialized() ||
-      unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-          APPLICATION_DATA) <
-          FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation - 1) {
-    // Peer is doing TCP style acking. Expect an immediate ACK if more than 1
-    // packet are outstanding.
-    if (unacked_packets_.packets_in_flight() >=
-        kDefaultRetransmittablePacketsBeforeAck) {
-      return false;
-    }
-  } else if (unacked_packets_.packets_in_flight() >=
-             kMaxRetransmittablePacketsBeforeAck) {
-    // Peer is doing ack decimation. Expect an immediate ACK if >= 10
-    // packets are outstanding.
-    return false;
-  }
-  if (skip_packet_number_for_pto_ && consecutive_pto_count_ > 0) {
-    // An immediate ACK is expected when doing PTOS. Please note, this will miss
-    // cases when PTO fires and turns out to be spurious.
-    return false;
-  }
-  return true;
-}
-
-QuicTime QuicSentPacketManager::GetEarliestPacketSentTimeForPto(
-    PacketNumberSpace* packet_number_space) const {
-  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
-  QuicTime earliest_sent_time = QuicTime::Zero();
-  for (int8_t i = 0; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-    const QuicTime sent_time = unacked_packets_.GetLastInFlightPacketSentTime(
-        static_cast<PacketNumberSpace>(i));
-    if (!handshake_finished_ && i == APPLICATION_DATA) {
-      // Do not arm PTO for application data until handshake gets confirmed.
-      continue;
-    }
-    if (!sent_time.IsInitialized() || (earliest_sent_time.IsInitialized() &&
-                                       earliest_sent_time <= sent_time)) {
-      continue;
-    }
-    earliest_sent_time = sent_time;
-    *packet_number_space = static_cast<PacketNumberSpace>(i);
-  }
-
-  return earliest_sent_time;
-}
-
-void QuicSentPacketManager::MarkForRetransmission(
-    QuicPacketNumber packet_number,
-    TransmissionType transmission_type) {
-  QuicTransmissionInfo* transmission_info =
-      unacked_packets_.GetMutableTransmissionInfo(packet_number);
-  // A previous RTO retransmission may cause connection close; packets without
-  // retransmittable frames can be marked for loss retransmissions.
-  QUIC_BUG_IF(quic_bug_12552_2, transmission_type != LOSS_RETRANSMISSION &&
-                                    transmission_type != RTO_RETRANSMISSION &&
-                                    !unacked_packets_.HasRetransmittableFrames(
-                                        *transmission_info))
-      << "packet number " << packet_number
-      << " transmission_type: " << transmission_type << " transmission_info "
-      << transmission_info->DebugString();
-  // Handshake packets should never be sent as probing retransmissions.
-  QUICHE_DCHECK(!transmission_info->has_crypto_handshake ||
-                transmission_type != PROBING_RETRANSMISSION);
-  if (ShouldForceRetransmission(transmission_type)) {
-    const bool retransmitted = unacked_packets_.RetransmitFrames(
-        QuicFrames(transmission_info->retransmittable_frames),
-        transmission_type);
-    if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
-      QUIC_RESTART_FLAG_COUNT(quic_set_packet_state_if_all_data_retransmitted);
-      if (!retransmitted) {
-        // Do not set packet state if the data is not fully retransmitted.
-        // This should only happen if packet payload size decreases which can be
-        // caused by:
-        // 1) connection tries to opportunistically retransmit data
-        // when sending a packet of a different packet number space, or
-        // 2) path MTU decreases, or
-        // 3) packet header size increases (e.g., packet number length
-        // increases).
-        QUIC_CODE_COUNT(quic_retransmit_frames_failed);
-        return;
-      }
-      QUIC_CODE_COUNT(quic_retransmit_frames_succeeded);
-    }
-  } else {
-    unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
-
-    if (!transmission_info->retransmittable_frames.empty()) {
-      if (transmission_type == LOSS_RETRANSMISSION) {
-        // Record the first packet sent after loss, which allows to wait 1
-        // more RTT before giving up on this lost packet.
-        transmission_info->first_sent_after_loss =
-            unacked_packets_.largest_sent_packet() + 1;
-      } else {
-        // Clear the recorded first packet sent after loss when version or
-        // encryption changes.
-        transmission_info->first_sent_after_loss.Clear();
-      }
-    }
-  }
-
-  // Get the latest transmission_info here as it can be invalidated after
-  // HandleRetransmission adding new sent packets into unacked_packets_.
-  transmission_info =
-      unacked_packets_.GetMutableTransmissionInfo(packet_number);
-
-  // Update packet state according to transmission type.
-  transmission_info->state =
-      QuicUtils::RetransmissionTypeToPacketState(transmission_type);
-}
-
-void QuicSentPacketManager::RecordOneSpuriousRetransmission(
-    const QuicTransmissionInfo& info) {
-  stats_->bytes_spuriously_retransmitted += info.bytes_sent;
-  ++stats_->packets_spuriously_retransmitted;
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
-                                                    info.bytes_sent);
-  }
-}
-
-void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
-                                              QuicTransmissionInfo* info,
-                                              QuicTime ack_receive_time,
-                                              QuicTime::Delta ack_delay_time,
-                                              QuicTime receive_timestamp) {
-  if (info->has_ack_frequency) {
-    for (const auto& frame : info->retransmittable_frames) {
-      if (frame.type == ACK_FREQUENCY_FRAME) {
-        OnAckFrequencyFrameAcked(*frame.ack_frequency_frame);
-      }
-    }
-  }
-  // Try to aggregate acked stream frames if acked packet is not a
-  // retransmission.
-  if (info->transmission_type == NOT_RETRANSMISSION) {
-    unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
-                                                    receive_timestamp);
-  } else {
-    unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
-    const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
-        *info, ack_delay_time, receive_timestamp);
-    if (!new_data_acked && info->transmission_type != NOT_RETRANSMISSION) {
-      // Record as a spurious retransmission if this packet is a
-      // retransmission and no new data gets acked.
-      QUIC_DVLOG(1) << "Detect spurious retransmitted packet " << packet_number
-                    << " transmission type: " << info->transmission_type;
-      RecordOneSpuriousRetransmission(*info);
-    }
-  }
-  if (info->state == LOST) {
-    // Record as a spurious loss as a packet previously declared lost gets
-    // acked.
-    const PacketNumberSpace packet_number_space =
-        unacked_packets_.GetPacketNumberSpace(info->encryption_level);
-    const QuicPacketNumber previous_largest_acked =
-        supports_multiple_packet_number_spaces()
-            ? unacked_packets_.GetLargestAckedOfPacketNumberSpace(
-                  packet_number_space)
-            : unacked_packets_.largest_acked();
-    QUIC_DVLOG(1) << "Packet " << packet_number
-                  << " was detected lost spuriously, "
-                     "previous_largest_acked: "
-                  << previous_largest_acked;
-    loss_algorithm_->SpuriousLossDetected(unacked_packets_, rtt_stats_,
-                                          ack_receive_time, packet_number,
-                                          previous_largest_acked);
-    ++stats_->packet_spuriously_detected_lost;
-  }
-
-  if (network_change_visitor_ != nullptr &&
-      info->bytes_sent > largest_mtu_acked_) {
-    largest_mtu_acked_ = info->bytes_sent;
-    network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
-  }
-  unacked_packets_.RemoveFromInFlight(info);
-  unacked_packets_.RemoveRetransmittability(info);
-  info->state = ACKED;
-}
-
-bool QuicSentPacketManager::CanSendAckFrequency() const {
-  return !peer_min_ack_delay_.IsInfinite() && handshake_finished_;
-}
-
-QuicAckFrequencyFrame QuicSentPacketManager::GetUpdatedAckFrequencyFrame()
-    const {
-  QuicAckFrequencyFrame frame;
-  if (!CanSendAckFrequency()) {
-    QUIC_BUG(quic_bug_10750_1)
-        << "New AckFrequencyFrame is created while it shouldn't.";
-    return frame;
-  }
-
-  QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 1, 3);
-  frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck;
-  auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt()
-                                            : rtt_stats_.MinOrInitialRtt();
-  frame.max_ack_delay = rtt * kAckDecimationDelay;
-  frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
-  // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to
-  // 5 ms on the client side.
-  frame.max_ack_delay =
-      std::max(frame.max_ack_delay,
-               QuicTime::Delta::FromMilliseconds(kDefaultMinAckDelayTimeMs));
-  return frame;
-}
-
-bool QuicSentPacketManager::OnPacketSent(
-    SerializedPacket* mutable_packet,
-    QuicTime sent_time,
-    TransmissionType transmission_type,
-    HasRetransmittableData has_retransmittable_data,
-    bool measure_rtt) {
-  const SerializedPacket& packet = *mutable_packet;
-  QuicPacketNumber packet_number = packet.packet_number;
-  QUICHE_DCHECK_LE(FirstSendingPacketNumber(), packet_number);
-  QUICHE_DCHECK(!unacked_packets_.IsUnacked(packet_number));
-  QUIC_BUG_IF(quic_bug_10750_2, packet.encrypted_length == 0)
-      << "Cannot send empty packets.";
-  if (pending_timer_transmission_count_ > 0) {
-    --pending_timer_transmission_count_;
-  }
-
-  bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
-  if (ignore_pings_ && mutable_packet->retransmittable_frames.size() == 1 &&
-      mutable_packet->retransmittable_frames[0].type == PING_FRAME) {
-    // Dot not use PING only packet for RTT measure or congestion control.
-    in_flight = false;
-    measure_rtt = false;
-  }
-  if (using_pacing_) {
-    pacing_sender_.OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
-                                packet_number, packet.encrypted_length,
-                                has_retransmittable_data);
-  } else {
-    send_algorithm_->OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
-                                  packet_number, packet.encrypted_length,
-                                  has_retransmittable_data);
-  }
-
-  // Deallocate message data in QuicMessageFrame immediately after packet
-  // sent.
-  if (packet.has_message) {
-    for (auto& frame : mutable_packet->retransmittable_frames) {
-      if (frame.type == MESSAGE_FRAME) {
-        frame.message_frame->message_data.clear();
-        frame.message_frame->message_length = 0;
-      }
-    }
-  }
-
-  if (packet.has_ack_frequency) {
-    for (const auto& frame : packet.retransmittable_frames) {
-      if (frame.type == ACK_FREQUENCY_FRAME) {
-        OnAckFrequencyFrameSent(*frame.ack_frequency_frame);
-      }
-    }
-  }
-  unacked_packets_.AddSentPacket(mutable_packet, transmission_type, sent_time,
-                                 in_flight, measure_rtt);
-  // Reset the retransmission timer anytime a pending packet is sent.
-  return in_flight;
-}
-
-QuicSentPacketManager::RetransmissionTimeoutMode
-QuicSentPacketManager::OnRetransmissionTimeout() {
-  QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
-                (handshake_mode_disabled_ && !handshake_finished_));
-  QUICHE_DCHECK_EQ(0u, pending_timer_transmission_count_);
-  // Handshake retransmission, timer based loss detection, TLP, and RTO are
-  // implemented with a single alarm. The handshake alarm is set when the
-  // handshake has not completed, the loss alarm is set when the loss detection
-  // algorithm says to, and the TLP and  RTO alarms are set after that.
-  // The TLP alarm is always set to run for under an RTO.
-  switch (GetRetransmissionMode()) {
-    case HANDSHAKE_MODE:
-      QUICHE_DCHECK(!handshake_mode_disabled_);
-      ++stats_->crypto_retransmit_count;
-      RetransmitCryptoPackets();
-      return HANDSHAKE_MODE;
-    case LOSS_MODE: {
-      ++stats_->loss_timeout_count;
-      QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
-      const QuicTime now = clock_->Now();
-      InvokeLossDetection(now);
-      MaybeInvokeCongestionEvent(false, prior_in_flight, now);
-      return LOSS_MODE;
-    }
-    case TLP_MODE:
-      ++stats_->tlp_count;
-      ++consecutive_tlp_count_;
-      pending_timer_transmission_count_ = 1;
-      // TLPs prefer sending new data instead of retransmitting data, so
-      // give the connection a chance to write before completing the TLP.
-      return TLP_MODE;
-    case RTO_MODE:
-      ++stats_->rto_count;
-      RetransmitRtoPackets();
-      return RTO_MODE;
-    case PTO_MODE:
-      QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
-      ++stats_->pto_count;
-      if (handshake_mode_disabled_ && !handshake_finished_) {
-        ++stats_->crypto_retransmit_count;
-      }
-      ++consecutive_pto_count_;
-      pending_timer_transmission_count_ = max_probe_packets_per_pto_;
-      return PTO_MODE;
-  }
-  QUIC_BUG(quic_bug_10750_3)
-      << "Unknown retransmission mode " << GetRetransmissionMode();
-  return GetRetransmissionMode();
-}
-
-void QuicSentPacketManager::RetransmitCryptoPackets() {
-  QUICHE_DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
-  ++consecutive_crypto_retransmission_count_;
-  bool packet_retransmitted = false;
-  std::vector<QuicPacketNumber> crypto_retransmissions;
-  if (!unacked_packets_.empty()) {
-    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-    QuicPacketNumber largest_sent_packet =
-        unacked_packets_.largest_sent_packet();
-    for (; packet_number <= largest_sent_packet; ++packet_number) {
-      QuicTransmissionInfo* transmission_info =
-          unacked_packets_.GetMutableTransmissionInfo(packet_number);
-      // Only retransmit frames which are in flight, and therefore have been
-      // sent.
-      if (!transmission_info->in_flight ||
-          transmission_info->state != OUTSTANDING ||
-          !transmission_info->has_crypto_handshake ||
-          !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
-        continue;
-      }
-      packet_retransmitted = true;
-      crypto_retransmissions.push_back(packet_number);
-      ++pending_timer_transmission_count_;
-    }
-  }
-  QUICHE_DCHECK(packet_retransmitted)
-      << "No crypto packets found to retransmit.";
-  for (QuicPacketNumber retransmission : crypto_retransmissions) {
-    MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
-  }
-}
-
-bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
-  QUICHE_DCHECK(!pto_enabled_);
-  if (pending_timer_transmission_count_ == 0) {
-    return false;
-  }
-  if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
-    return false;
-  }
-  return true;
-}
-
-bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
-  if (!unacked_packets_.empty()) {
-    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-    QuicPacketNumber largest_sent_packet =
-        unacked_packets_.largest_sent_packet();
-    for (; packet_number <= largest_sent_packet; ++packet_number) {
-      QuicTransmissionInfo* transmission_info =
-          unacked_packets_.GetMutableTransmissionInfo(packet_number);
-      // Only retransmit frames which are in flight, and therefore have been
-      // sent.
-      if (!transmission_info->in_flight ||
-          transmission_info->state != OUTSTANDING ||
-          !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
-        continue;
-      }
-      MarkForRetransmission(packet_number, type);
-      return true;
-    }
-  }
-  QUIC_DVLOG(1)
-      << "No retransmittable packets, so RetransmitOldestPacket failed.";
-  return false;
-}
-
-void QuicSentPacketManager::RetransmitRtoPackets() {
-  QUICHE_DCHECK(!pto_enabled_);
-  QUIC_BUG_IF(quic_bug_12552_3, pending_timer_transmission_count_ > 0)
-      << "Retransmissions already queued:" << pending_timer_transmission_count_;
-  // Mark two packets for retransmission.
-  std::vector<QuicPacketNumber> retransmissions;
-  if (!unacked_packets_.empty()) {
-    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-    QuicPacketNumber largest_sent_packet =
-        unacked_packets_.largest_sent_packet();
-    for (; packet_number <= largest_sent_packet; ++packet_number) {
-      QuicTransmissionInfo* transmission_info =
-          unacked_packets_.GetMutableTransmissionInfo(packet_number);
-      if (transmission_info->state == OUTSTANDING &&
-          unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
-          pending_timer_transmission_count_ < max_rto_packets_) {
-        QUICHE_DCHECK(transmission_info->in_flight);
-        retransmissions.push_back(packet_number);
-        ++pending_timer_transmission_count_;
-      }
-    }
-  }
-  if (pending_timer_transmission_count_ > 0) {
-    if (consecutive_rto_count_ == 0) {
-      first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
-    }
-    ++consecutive_rto_count_;
-  }
-  for (QuicPacketNumber retransmission : retransmissions) {
-    MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
-  }
-  if (retransmissions.empty()) {
-    QUIC_BUG_IF(quic_bug_12552_4, pending_timer_transmission_count_ != 0);
-    // No packets to be RTO retransmitted, raise up a credit to allow
-    // connection to send.
-    QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
-    pending_timer_transmission_count_ = 1;
-  }
-}
-
-void QuicSentPacketManager::MaybeSendProbePackets() {
-  if (pending_timer_transmission_count_ == 0) {
-    return;
-  }
-  PacketNumberSpace packet_number_space;
-  if (supports_multiple_packet_number_spaces()) {
-    // Find out the packet number space to send probe packets.
-    if (!GetEarliestPacketSentTimeForPto(&packet_number_space)
-             .IsInitialized()) {
-      QUIC_BUG_IF(quic_earliest_sent_time_not_initialized,
-                  unacked_packets_.perspective() == Perspective::IS_SERVER)
-          << "earliest_sent_time not initialized when trying to send PTO "
-             "retransmissions";
-      return;
-    }
-  }
-  std::vector<QuicPacketNumber> probing_packets;
-  if (!unacked_packets_.empty()) {
-    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-    QuicPacketNumber largest_sent_packet =
-        unacked_packets_.largest_sent_packet();
-    for (; packet_number <= largest_sent_packet; ++packet_number) {
-      QuicTransmissionInfo* transmission_info =
-          unacked_packets_.GetMutableTransmissionInfo(packet_number);
-      if (transmission_info->state == OUTSTANDING &&
-          unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
-          (!supports_multiple_packet_number_spaces() ||
-           unacked_packets_.GetPacketNumberSpace(
-               transmission_info->encryption_level) == packet_number_space)) {
-        QUICHE_DCHECK(transmission_info->in_flight);
-        probing_packets.push_back(packet_number);
-        if (probing_packets.size() == pending_timer_transmission_count_) {
-          break;
-        }
-      }
-    }
-  }
-
-  for (QuicPacketNumber retransmission : probing_packets) {
-    QUIC_DVLOG(1) << ENDPOINT << "Marking " << retransmission
-                  << " for probing retransmission";
-    MarkForRetransmission(retransmission, PTO_RETRANSMISSION);
-  }
-  // It is possible that there is not enough outstanding data for probing.
-}
-
-void QuicSentPacketManager::AdjustPendingTimerTransmissions() {
-  if (pending_timer_transmission_count_ < max_probe_packets_per_pto_) {
-    // There are packets sent already, clear credit.
-    pending_timer_transmission_count_ = 0;
-    return;
-  }
-  // No packet gets sent, leave 1 credit to allow data to be write eventually.
-  pending_timer_transmission_count_ = 1;
-}
-
-void QuicSentPacketManager::EnableIetfPtoAndLossDetection() {
-  if (pto_enabled_) {
-    QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 2, 2);
-    // Disable handshake mode.
-    handshake_mode_disabled_ = true;
-    return;
-  }
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    QUIC_BUG(pto_not_enabled)
-        << "PTO is not enabled while quic_default_on_pto2 is true";
-    return;
-  }
-  pto_enabled_ = true;
-  handshake_mode_disabled_ = true;
-  // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
-  // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
-  // last in flight packet.
-  max_probe_packets_per_pto_ = 1;
-  skip_packet_number_for_pto_ = true;
-  first_pto_srtt_multiplier_ = 1.5;
-  pto_rttvar_multiplier_ = 2;
-}
-
-void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(
-    size_t exponential_backoff_start_point) {
-  pto_exponential_backoff_start_point_ = exponential_backoff_start_point;
-}
-
-void QuicSentPacketManager::RetransmitDataOfSpaceIfAny(
-    PacketNumberSpace space) {
-  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
-  if (!unacked_packets_.GetLastInFlightPacketSentTime(space).IsInitialized()) {
-    // No in flight data of space.
-    return;
-  }
-  if (unacked_packets_.empty()) {
-    return;
-  }
-  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
-  for (; packet_number <= largest_sent_packet; ++packet_number) {
-    QuicTransmissionInfo* transmission_info =
-        unacked_packets_.GetMutableTransmissionInfo(packet_number);
-    if (transmission_info->state == OUTSTANDING &&
-        unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
-        unacked_packets_.GetPacketNumberSpace(
-            transmission_info->encryption_level) == space) {
-      QUICHE_DCHECK(transmission_info->in_flight);
-      if (pending_timer_transmission_count_ == 0) {
-        pending_timer_transmission_count_ = 1;
-      }
-      MarkForRetransmission(packet_number, PTO_RETRANSMISSION);
-      return;
-    }
-  }
-}
-
-QuicSentPacketManager::RetransmissionTimeoutMode
-QuicSentPacketManager::GetRetransmissionMode() const {
-  QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
-                (handshake_mode_disabled_ && !handshake_finished_));
-  if (!handshake_mode_disabled_ && !handshake_finished_ &&
-      unacked_packets_.HasPendingCryptoPackets()) {
-    return HANDSHAKE_MODE;
-  }
-  if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
-    return LOSS_MODE;
-  }
-  if (pto_enabled_) {
-    return PTO_MODE;
-  }
-  if (consecutive_tlp_count_ < max_tail_loss_probes_) {
-    if (unacked_packets_.HasUnackedRetransmittableFrames()) {
-      return TLP_MODE;
-    }
-  }
-  return RTO_MODE;
-}
-
-void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
-  if (!packets_acked_.empty()) {
-    QUICHE_DCHECK_LE(packets_acked_.front().packet_number,
-                     packets_acked_.back().packet_number);
-    largest_newly_acked_ = packets_acked_.back().packet_number;
-  }
-  LossDetectionInterface::DetectionStats detection_stats =
-      loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
-                                    largest_newly_acked_, packets_acked_,
-                                    &packets_lost_);
-
-  if (detection_stats.sent_packets_max_sequence_reordering >
-      stats_->sent_packets_max_sequence_reordering) {
-    stats_->sent_packets_max_sequence_reordering =
-        detection_stats.sent_packets_max_sequence_reordering;
-  }
-
-  stats_->sent_packets_num_borderline_time_reorderings +=
-      detection_stats.sent_packets_num_borderline_time_reorderings;
-
-  stats_->total_loss_detection_response_time +=
-      detection_stats.total_loss_detection_response_time;
-
-  for (const LostPacket& packet : packets_lost_) {
-    QuicTransmissionInfo* info =
-        unacked_packets_.GetMutableTransmissionInfo(packet.packet_number);
-    ++stats_->packets_lost;
-    if (debug_delegate_ != nullptr) {
-      debug_delegate_->OnPacketLoss(packet.packet_number,
-                                    info->encryption_level, LOSS_RETRANSMISSION,
-                                    time);
-    }
-    unacked_packets_.RemoveFromInFlight(info);
-
-    MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
-  }
-}
-
-bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
-                                           QuicTime::Delta ack_delay_time,
-                                           QuicTime ack_receive_time) {
-  // We rely on ack_delay_time to compute an RTT estimate, so we
-  // only update rtt when the largest observed gets acked and the acked packet
-  // is not useless.
-  if (!unacked_packets_.IsUnacked(largest_acked)) {
-    return false;
-  }
-  // We calculate the RTT based on the highest ACKed packet number, the lower
-  // packet numbers will include the ACK aggregation delay.
-  const QuicTransmissionInfo& transmission_info =
-      unacked_packets_.GetTransmissionInfo(largest_acked);
-  // Ensure the packet has a valid sent time.
-  if (transmission_info.sent_time == QuicTime::Zero()) {
-    QUIC_BUG(quic_bug_10750_4)
-        << "Acked packet has zero sent time, largest_acked:" << largest_acked;
-    return false;
-  }
-  if (transmission_info.state == NOT_CONTRIBUTING_RTT) {
-    return false;
-  }
-  if (transmission_info.sent_time > ack_receive_time) {
-    QUIC_CODE_COUNT(quic_receive_acked_before_sending);
-  }
-
-  QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
-  const bool min_rtt_available = !rtt_stats_.min_rtt().IsZero();
-  rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
-
-  if (!min_rtt_available && !rtt_stats_.min_rtt().IsZero()) {
-    loss_algorithm_->OnMinRttAvailable();
-  }
-
-  return true;
-}
-
-QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
-  // The TLP logic is entirely contained within QuicSentPacketManager, so the
-  // send algorithm does not need to be consulted.
-  if (pending_timer_transmission_count_ > 0) {
-    return QuicTime::Delta::Zero();
-  }
-
-  if (using_pacing_) {
-    return pacing_sender_.TimeUntilSend(now,
-                                        unacked_packets_.bytes_in_flight());
-  }
-
-  return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
-             ? QuicTime::Delta::Zero()
-             : QuicTime::Delta::Infinite();
-}
-
-const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
-  if (!unacked_packets_.HasInFlightPackets() &&
-      PeerCompletedAddressValidation()) {
-    return QuicTime::Zero();
-  }
-  if (pending_timer_transmission_count_ > 0) {
-    // Do not set the timer if there is any credit left.
-    return QuicTime::Zero();
-  }
-  PacketNumberSpace packet_number_space;
-  if (!simplify_set_retransmission_alarm_ &&
-      supports_multiple_packet_number_spaces() &&
-      unacked_packets_.perspective() == Perspective::IS_SERVER &&
-      !GetEarliestPacketSentTimeForPto(&packet_number_space).IsInitialized()) {
-    // Do not set the timer on the server side if the only in flight packets are
-    // half RTT data.
-    return QuicTime::Zero();
-  }
-  switch (GetRetransmissionMode()) {
-    case HANDSHAKE_MODE:
-      return unacked_packets_.GetLastCryptoPacketSentTime() +
-             GetCryptoRetransmissionDelay();
-    case LOSS_MODE:
-      return loss_algorithm_->GetLossTimeout();
-    case TLP_MODE: {
-      QUICHE_DCHECK(!pto_enabled_);
-      // TODO(ianswett): When CWND is available, it would be preferable to
-      // set the timer based on the earliest retransmittable packet.
-      // Base the updated timer on the send time of the last packet.
-      const QuicTime sent_time =
-          unacked_packets_.GetLastInFlightPacketSentTime();
-      const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
-      // Ensure the TLP timer never gets set to a time in the past.
-      return std::max(clock_->ApproximateNow(), tlp_time);
-    }
-    case RTO_MODE: {
-      QUICHE_DCHECK(!pto_enabled_);
-      // The RTO is based on the first outstanding packet.
-      const QuicTime sent_time =
-          unacked_packets_.GetLastInFlightPacketSentTime();
-      QuicTime rto_time = sent_time + GetRetransmissionDelay();
-      // Wait for TLP packets to be acked before an RTO fires.
-      QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
-      return std::max(tlp_time, rto_time);
-    }
-    case PTO_MODE: {
-      if (!supports_multiple_packet_number_spaces()) {
-        if (first_pto_srtt_multiplier_ > 0 &&
-            unacked_packets_.HasInFlightPackets() &&
-            consecutive_pto_count_ == 0) {
-          // Arm 1st PTO with earliest in flight sent time, and make sure at
-          // least first_pto_srtt_multiplier_ * RTT has been passed since last
-          // in flight packet.
-          return std::max(
-              clock_->ApproximateNow(),
-              std::max(unacked_packets_.GetFirstInFlightTransmissionInfo()
-                               ->sent_time +
-                           GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES),
-                       unacked_packets_.GetLastInFlightPacketSentTime() +
-                           first_pto_srtt_multiplier_ *
-                               rtt_stats_.SmoothedOrInitialRtt()));
-        }
-        // Ensure PTO never gets set to a time in the past.
-        return std::max(clock_->ApproximateNow(),
-                        unacked_packets_.GetLastInFlightPacketSentTime() +
-                            GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES));
-      }
-
-      PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES;
-      // earliest_right_edge is the earliest sent time of the last in flight
-      // packet of all packet number spaces.
-      QuicTime earliest_right_edge =
-          GetEarliestPacketSentTimeForPto(&packet_number_space);
-      if (!earliest_right_edge.IsInitialized()) {
-        // Arm PTO from now if there is no in flight packets.
-        earliest_right_edge = clock_->ApproximateNow();
-      }
-      if (first_pto_srtt_multiplier_ > 0 &&
-          packet_number_space == APPLICATION_DATA &&
-          consecutive_pto_count_ == 0) {
-        const QuicTransmissionInfo* first_application_info =
-            unacked_packets_.GetFirstInFlightTransmissionInfoOfSpace(
-                APPLICATION_DATA);
-        if (first_application_info != nullptr) {
-          // Arm 1st PTO with earliest in flight sent time, and make sure at
-          // least first_pto_srtt_multiplier_ * RTT has been passed since last
-          // in flight packet. Only do this for application data.
-          return std::max(
-              clock_->ApproximateNow(),
-              std::max(
-                  first_application_info->sent_time +
-                      GetProbeTimeoutDelay(packet_number_space),
-                  earliest_right_edge + first_pto_srtt_multiplier_ *
-                                            rtt_stats_.SmoothedOrInitialRtt()));
-        }
-      }
-      return std::max(
-          clock_->ApproximateNow(),
-          earliest_right_edge + GetProbeTimeoutDelay(packet_number_space));
-    }
-  }
-  QUICHE_DCHECK(false);
-  return QuicTime::Zero();
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
-  if (num_ptos_for_path_degrading_ > 0) {
-    return num_ptos_for_path_degrading_ * GetPtoDelay();
-  }
-  return GetNConsecutiveRetransmissionTimeoutDelay(
-      max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
-    int8_t num_rtos_for_blackhole_detection) const {
-  return GetNConsecutiveRetransmissionTimeoutDelay(
-      max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
-}
-
-QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
-    int8_t num_rtos_for_blackhole_detection) const {
-  return GetNetworkBlackholeDelay(num_rtos_for_blackhole_detection / 2);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
-    const {
-  // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
-  // because crypto handshake messages don't incur a delayed ack time.
-  QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
-  int64_t delay_ms;
-  if (conservative_handshake_retransmits_) {
-    // Using the delayed ack time directly could cause conservative handshake
-    // retransmissions to actually be more aggressive than the default.
-    delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
-                        static_cast<int64_t>(2 * srtt.ToMilliseconds()));
-  } else {
-    delay_ms = std::max(kMinHandshakeTimeoutMs,
-                        static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
-  }
-  return QuicTime::Delta::FromMilliseconds(
-      delay_ms << consecutive_crypto_retransmission_count_);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
-  QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
-  if (!unacked_packets_.HasMultipleInFlightPackets()) {
-    // This expression really should be using the delayed ack time, but in TCP
-    // MinRTO was traditionally set to 2x the delayed ack timer and this
-    // expression assumed QUIC did the same.
-    return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
-  }
-  return std::max(min_tlp_timeout_, 2 * srtt);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
-  QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
-  if (rtt_stats_.smoothed_rtt().IsZero()) {
-    // We are in the initial state, use default timeout values.
-    retransmission_delay =
-        QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
-  } else {
-    retransmission_delay =
-        rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
-    if (retransmission_delay < min_rto_timeout_) {
-      retransmission_delay = min_rto_timeout_;
-    }
-  }
-
-  // Calculate exponential back off.
-  retransmission_delay =
-      retransmission_delay *
-      (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
-
-  if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
-    return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
-  }
-  return retransmission_delay;
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay(
-    PacketNumberSpace space) const {
-  QUICHE_DCHECK(pto_enabled_);
-  if (rtt_stats_.smoothed_rtt().IsZero()) {
-    // Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack.
-    QUIC_BUG_IF(quic_bug_12552_6, rtt_stats_.initial_rtt().IsZero());
-    return std::max(
-               pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(),
-               QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
-           (1 << consecutive_pto_count_);
-  }
-  const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
-                                      ? rtt_stats_.GetStandardOrMeanDeviation()
-                                      : rtt_stats_.mean_deviation();
-  QuicTime::Delta pto_delay =
-      rtt_stats_.smoothed_rtt() +
-      std::max(pto_rttvar_multiplier_ * rtt_var, kAlarmGranularity) +
-      (ShouldAddMaxAckDelay(space) ? peer_max_ack_delay_
-                                   : QuicTime::Delta::Zero());
-  pto_delay =
-      pto_delay * (1 << (consecutive_pto_count_ -
-                         std::min(consecutive_pto_count_,
-                                  pto_exponential_backoff_start_point_)));
-  if (consecutive_pto_count_ < num_tlp_timeout_ptos_) {
-    // Make first n PTOs similar to TLPs.
-    if (pto_delay > 2 * rtt_stats_.smoothed_rtt()) {
-      QUIC_CODE_COUNT(quic_delayed_pto);
-      pto_delay = std::max(kAlarmGranularity, 2 * rtt_stats_.smoothed_rtt());
-    } else {
-      QUIC_CODE_COUNT(quic_faster_pto);
-    }
-  }
-  return pto_delay;
-}
-
-QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
-  if (send_algorithm_->GetCongestionControlType() == kBBR ||
-      send_algorithm_->GetCongestionControlType() == kBBRv2) {
-    return stats_->slowstart_duration.GetTotalElapsedTime(
-        clock_->ApproximateNow());
-  }
-  return QuicTime::Delta::Infinite();
-}
-
-QuicByteCount QuicSentPacketManager::GetAvailableCongestionWindowInBytes()
-    const {
-  QuicByteCount congestion_window = GetCongestionWindowInBytes();
-  QuicByteCount bytes_in_flight = GetBytesInFlight();
-  return congestion_window - std::min(congestion_window, bytes_in_flight);
-}
-
-std::string QuicSentPacketManager::GetDebugState() const {
-  return send_algorithm_->GetDebugState();
-}
-
-void QuicSentPacketManager::SetSendAlgorithm(
-    CongestionControlType congestion_control_type) {
-  if (send_algorithm_ &&
-      send_algorithm_->GetCongestionControlType() == congestion_control_type) {
-    return;
-  }
-
-  SetSendAlgorithm(SendAlgorithmInterface::Create(
-      clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
-      stats_, initial_congestion_window_, send_algorithm_.get()));
-}
-
-void QuicSentPacketManager::SetSendAlgorithm(
-    SendAlgorithmInterface* send_algorithm) {
-  send_algorithm_.reset(send_algorithm);
-  pacing_sender_.set_sender(send_algorithm);
-}
-
-std::unique_ptr<SendAlgorithmInterface>
-QuicSentPacketManager::OnConnectionMigration(bool reset_send_algorithm) {
-  consecutive_rto_count_ = 0;
-  consecutive_tlp_count_ = 0;
-  consecutive_pto_count_ = 0;
-  rtt_stats_.OnConnectionMigration();
-  if (!reset_send_algorithm) {
-    send_algorithm_->OnConnectionMigration();
-    return nullptr;
-  }
-
-  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
-      std::move(send_algorithm_);
-  SetSendAlgorithm(old_send_algorithm->GetCongestionControlType());
-  // Treat all in flight packets sent to the old peer address as lost and
-  // retransmit them.
-  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
-  for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
-       ++it, ++packet_number) {
-    if (it->in_flight) {
-      // Proactively retransmit any packet which is in flight on the old path.
-      // As a result, these packets will not contribute to congestion control.
-      unacked_packets_.RemoveFromInFlight(packet_number);
-      // Retransmitting these packets with PATH_CHANGE_RETRANSMISSION will mark
-      // them as useless, thus not contributing to RTT stats.
-      if (unacked_packets_.HasRetransmittableFrames(packet_number)) {
-        MarkForRetransmission(packet_number, PATH_RETRANSMISSION);
-        QUICHE_DCHECK_EQ(it->state, NOT_CONTRIBUTING_RTT);
-      }
-    }
-    it->state = NOT_CONTRIBUTING_RTT;
-  }
-  return old_send_algorithm;
-}
-
-void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
-                                            QuicTime::Delta ack_delay_time,
-                                            QuicTime ack_receive_time) {
-  QUICHE_DCHECK(packets_acked_.empty());
-  QUICHE_DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
-  // Ignore peer_max_ack_delay and use received ack_delay during
-  // handshake when supporting multiple packet number spaces.
-  if (!supports_multiple_packet_number_spaces() || handshake_finished_) {
-    if (ack_delay_time > peer_max_ack_delay()) {
-      ack_delay_time = peer_max_ack_delay();
-    }
-    if (ignore_ack_delay_) {
-      ack_delay_time = QuicTime::Delta::Zero();
-    }
-  }
-  rtt_updated_ =
-      MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
-  last_ack_frame_.ack_delay_time = ack_delay_time;
-  acked_packets_iter_ = last_ack_frame_.packets.rbegin();
-}
-
-void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
-                                       QuicPacketNumber end) {
-  if (!last_ack_frame_.largest_acked.IsInitialized() ||
-      end > last_ack_frame_.largest_acked + 1) {
-    // Largest acked increases.
-    unacked_packets_.IncreaseLargestAcked(end - 1);
-    last_ack_frame_.largest_acked = end - 1;
-  }
-  // Drop ack ranges which ack packets below least_unacked.
-  QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
-  if (least_unacked.IsInitialized() && end <= least_unacked) {
-    return;
-  }
-  start = std::max(start, least_unacked);
-  do {
-    QuicPacketNumber newly_acked_start = start;
-    if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
-      newly_acked_start = std::max(start, acked_packets_iter_->max());
-    }
-    for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
-         --acked) {
-      // Check if end is above the current range. If so add newly acked packets
-      // in descending order.
-      packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
-      if (acked == FirstSendingPacketNumber()) {
-        break;
-      }
-    }
-    if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
-        start > acked_packets_iter_->min()) {
-      // Finish adding all newly acked packets.
-      return;
-    }
-    end = std::min(end, acked_packets_iter_->min());
-    ++acked_packets_iter_;
-  } while (start < end);
-}
-
-void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
-                                           QuicTime timestamp) {
-  last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
-  for (AckedPacket& packet : packets_acked_) {
-    if (packet.packet_number == packet_number) {
-      packet.receive_timestamp = timestamp;
-      return;
-    }
-  }
-}
-
-AckResult QuicSentPacketManager::OnAckFrameEnd(
-    QuicTime ack_receive_time,
-    QuicPacketNumber ack_packet_number,
-    EncryptionLevel ack_decrypted_level) {
-  QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
-  // Reverse packets_acked_ so that it is in ascending order.
-  std::reverse(packets_acked_.begin(), packets_acked_.end());
-  for (AckedPacket& acked_packet : packets_acked_) {
-    QuicTransmissionInfo* info =
-        unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
-    if (!QuicUtils::IsAckable(info->state)) {
-      if (info->state == ACKED) {
-        QUIC_BUG(quic_bug_10750_5)
-            << "Trying to ack an already acked packet: "
-            << acked_packet.packet_number
-            << ", last_ack_frame_: " << last_ack_frame_
-            << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
-            << ", packets_acked_: " << quiche::PrintElements(packets_acked_);
-      } else {
-        QUIC_PEER_BUG(quic_peer_bug_10750_6)
-            << "Received " << ack_decrypted_level
-            << " ack for unackable packet: " << acked_packet.packet_number
-            << " with state: "
-            << QuicUtils::SentPacketStateToString(info->state);
-        if (supports_multiple_packet_number_spaces()) {
-          if (info->state == NEVER_SENT) {
-            return UNSENT_PACKETS_ACKED;
-          }
-          return UNACKABLE_PACKETS_ACKED;
-        }
-      }
-      continue;
-    }
-    QUIC_DVLOG(1) << ENDPOINT << "Got an " << ack_decrypted_level
-                  << " ack for packet " << acked_packet.packet_number
-                  << " , state: "
-                  << QuicUtils::SentPacketStateToString(info->state);
-    const PacketNumberSpace packet_number_space =
-        unacked_packets_.GetPacketNumberSpace(info->encryption_level);
-    if (supports_multiple_packet_number_spaces() &&
-        QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
-            packet_number_space) {
-      return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
-    }
-    last_ack_frame_.packets.Add(acked_packet.packet_number);
-    if (info->encryption_level == ENCRYPTION_HANDSHAKE) {
-      handshake_packet_acked_ = true;
-    } else if (info->encryption_level == ENCRYPTION_ZERO_RTT) {
-      zero_rtt_packet_acked_ = true;
-    } else if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
-      one_rtt_packet_acked_ = true;
-    }
-    largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
-    if (supports_multiple_packet_number_spaces()) {
-      largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
-          info->largest_acked);
-    }
-    // If data is associated with the most recent transmission of this
-    // packet, then inform the caller.
-    if (info->in_flight) {
-      acked_packet.bytes_acked = info->bytes_sent;
-    } else {
-      // Unackable packets are skipped earlier.
-      largest_newly_acked_ = acked_packet.packet_number;
-    }
-    unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
-        packet_number_space, acked_packet.packet_number);
-    MarkPacketHandled(acked_packet.packet_number, info, ack_receive_time,
-                      last_ack_frame_.ack_delay_time,
-                      acked_packet.receive_timestamp);
-  }
-  const bool acked_new_packet = !packets_acked_.empty();
-  PostProcessNewlyAckedPackets(ack_packet_number, ack_decrypted_level,
-                               last_ack_frame_, ack_receive_time, rtt_updated_,
-                               prior_bytes_in_flight);
-
-  return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
-}
-
-void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
-  debug_delegate_ = debug_delegate;
-}
-
-void QuicSentPacketManager::OnApplicationLimited() {
-  if (using_pacing_) {
-    pacing_sender_.OnApplicationLimited();
-  }
-  send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
-  if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnApplicationLimited();
-  }
-}
-
-NextReleaseTimeResult QuicSentPacketManager::GetNextReleaseTime() const {
-  if (!using_pacing_) {
-    return {QuicTime::Zero(), false};
-  }
-
-  return pacing_sender_.GetNextReleaseTime();
-}
-
-void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt, bool trusted) {
-  const QuicTime::Delta min_rtt = QuicTime::Delta::FromMicroseconds(
-      trusted ? kMinTrustedInitialRoundTripTimeUs
-              : kMinUntrustedInitialRoundTripTimeUs);
-  QuicTime::Delta max_rtt =
-      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
-  rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
-}
-
-void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
-  EnableIetfPtoAndLossDetection();
-  unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
-}
-
-QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
-    EncryptionLevel decrypted_packet_level) const {
-  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
-  return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
-      QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
-}
-
-QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer(
-    EncryptionLevel encryption_level) const {
-  QuicPacketNumber largest_acked;
-  if (supports_multiple_packet_number_spaces()) {
-    largest_acked = GetLargestAckedPacket(encryption_level);
-  } else {
-    largest_acked = GetLargestObserved();
-  }
-  if (!largest_acked.IsInitialized()) {
-    // If no packets have been acked, return the first sent packet to ensure
-    // we use a large enough packet number length.
-    return FirstSendingPacketNumber();
-  }
-  QuicPacketNumber least_awaited = largest_acked + 1;
-  QuicPacketNumber least_unacked = GetLeastUnacked();
-  if (least_unacked.IsInitialized() && least_unacked < least_awaited) {
-    least_awaited = least_unacked;
-  }
-  return least_awaited;
-}
-
-QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
-    EncryptionLevel decrypted_packet_level) const {
-  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
-  return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
-      decrypted_packet_level)];
-}
-
-QuicTime::Delta
-QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
-    int num_timeouts) const {
-  QuicTime::Delta total_delay = QuicTime::Delta::Zero();
-  const QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
-  int num_tlps =
-      std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
-  num_timeouts -= num_tlps;
-  if (num_tlps > 0) {
-    const QuicTime::Delta tlp_delay =
-        std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
-                               ? min_tlp_timeout_
-                               : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
-    total_delay = total_delay + num_tlps * tlp_delay;
-  }
-  if (num_timeouts == 0) {
-    return total_delay;
-  }
-
-  const QuicTime::Delta retransmission_delay =
-      rtt_stats_.smoothed_rtt().IsZero()
-          ? QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs)
-          : std::max(srtt + 4 * rtt_stats_.mean_deviation(), min_rto_timeout_);
-  total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
-  return total_delay;
-}
-
-bool QuicSentPacketManager::PeerCompletedAddressValidation() const {
-  if (unacked_packets_.perspective() == Perspective::IS_SERVER ||
-      !handshake_mode_disabled_) {
-    return true;
-  }
-
-  // To avoid handshake deadlock due to anti-amplification limit, client needs
-  // to set PTO timer until server successfully processed any HANDSHAKE packet.
-  return handshake_finished_ || handshake_packet_acked_;
-}
-
-bool QuicSentPacketManager::IsLessThanThreePTOs(QuicTime::Delta timeout) const {
-  return timeout < 3 * GetPtoDelay();
-}
-
-QuicTime::Delta QuicSentPacketManager::GetPtoDelay() const {
-  return pto_enabled_ ? GetProbeTimeoutDelay(APPLICATION_DATA)
-                      : GetRetransmissionDelay();
-}
-
-void QuicSentPacketManager::OnAckFrequencyFrameSent(
-    const QuicAckFrequencyFrame& ack_frequency_frame) {
-  in_use_sent_ack_delays_.emplace_back(ack_frequency_frame.max_ack_delay,
-                                       ack_frequency_frame.sequence_number);
-  if (ack_frequency_frame.max_ack_delay > peer_max_ack_delay_) {
-    peer_max_ack_delay_ = ack_frequency_frame.max_ack_delay;
-  }
-}
-
-void QuicSentPacketManager::OnAckFrequencyFrameAcked(
-    const QuicAckFrequencyFrame& ack_frequency_frame) {
-  int stale_entry_count = 0;
-  for (auto it = in_use_sent_ack_delays_.cbegin();
-       it != in_use_sent_ack_delays_.cend(); ++it) {
-    if (it->second < ack_frequency_frame.sequence_number) {
-      ++stale_entry_count;
-    } else {
-      break;
-    }
-  }
-  if (stale_entry_count > 0) {
-    in_use_sent_ack_delays_.pop_front_n(stale_entry_count);
-  }
-  if (in_use_sent_ack_delays_.empty()) {
-    QUIC_BUG(quic_bug_10750_7) << "in_use_sent_ack_delays_ is empty.";
-    return;
-  }
-  peer_max_ack_delay_ = std::max_element(in_use_sent_ack_delays_.cbegin(),
-                                         in_use_sent_ack_delays_.cend())
-                            ->first;
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h
deleted file mode 100644
index f31cc1c..0000000
--- a/quic/core/quic_sent_packet_manager.h
+++ /dev/null
@@ -1,784 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "quic/core/congestion_control/pacing_sender.h"
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/congestion_control/uber_loss_algorithm.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_unacked_packet_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicConnectionPeer;
-class QuicSentPacketManagerPeer;
-}  // namespace test
-
-class QuicClock;
-class QuicConfig;
-struct QuicConnectionStats;
-
-// Class which tracks the set of packets sent on a QUIC connection and contains
-// a send algorithm to decide when to send new packets.  It keeps track of any
-// retransmittable data associated with each packet. If a packet is
-// retransmitted, it will keep track of each version of a packet so that if a
-// previous transmission is acked, the data will not be retransmitted.
-class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
- public:
-  // Interface which gets callbacks from the QuicSentPacketManager at
-  // interesting points.  Implementations must not mutate the state of
-  // the packet manager or connection as a result of these callbacks.
-  class QUIC_EXPORT_PRIVATE DebugDelegate {
-   public:
-    struct QUIC_EXPORT_PRIVATE SendParameters {
-      CongestionControlType congestion_control_type;
-      bool use_pacing;
-      QuicPacketCount initial_congestion_window;
-    };
-
-    virtual ~DebugDelegate() {}
-
-    // Called when a spurious retransmission is detected.
-    virtual void OnSpuriousPacketRetransmission(
-        TransmissionType /*transmission_type*/,
-        QuicByteCount /*byte_size*/) {}
-
-    virtual void OnIncomingAck(QuicPacketNumber /*ack_packet_number*/,
-                               EncryptionLevel /*ack_decrypted_level*/,
-                               const QuicAckFrame& /*ack_frame*/,
-                               QuicTime /*ack_receive_time*/,
-                               QuicPacketNumber /*largest_observed*/,
-                               bool /*rtt_updated*/,
-                               QuicPacketNumber /*least_unacked_sent_packet*/) {
-    }
-
-    virtual void OnPacketLoss(QuicPacketNumber /*lost_packet_number*/,
-                              EncryptionLevel /*encryption_level*/,
-                              TransmissionType /*transmission_type*/,
-                              QuicTime /*detection_time*/) {}
-
-    virtual void OnApplicationLimited() {}
-
-    virtual void OnAdjustNetworkParameters(QuicBandwidth /*bandwidth*/,
-                                           QuicTime::Delta /*rtt*/,
-                                           QuicByteCount /*old_cwnd*/,
-                                           QuicByteCount /*new_cwnd*/) {}
-
-    virtual void OnAdjustBurstSize(int /*old_burst_size*/,
-                                   int /*new_burst_size*/) {}
-
-    virtual void OnOvershootingDetected() {}
-
-    virtual void OnConfigProcessed(const SendParameters& /*parameters*/) {}
-  };
-
-  // Interface which gets callbacks from the QuicSentPacketManager when
-  // network-related state changes. Implementations must not mutate the
-  // state of the packet manager as a result of these callbacks.
-  class QUIC_EXPORT_PRIVATE NetworkChangeVisitor {
-   public:
-    virtual ~NetworkChangeVisitor() {}
-
-    // Called when congestion window or RTT may have changed.
-    virtual void OnCongestionChange() = 0;
-
-    // Called when the Path MTU may have increased.
-    virtual void OnPathMtuIncreased(QuicPacketLength packet_size) = 0;
-  };
-
-  // The retransmission timer is a single timer which switches modes depending
-  // upon connection state.
-  enum RetransmissionTimeoutMode {
-    // A conventional TCP style RTO.
-    RTO_MODE,
-    // A tail loss probe.  By default, QUIC sends up to two before RTOing.
-    TLP_MODE,
-    // Retransmission of handshake packets prior to handshake completion.
-    HANDSHAKE_MODE,
-    // Re-invoke the loss detection when a packet is not acked before the
-    // loss detection algorithm expects.
-    LOSS_MODE,
-    // A probe timeout. At least one probe packet must be sent when timer
-    // expires.
-    PTO_MODE,
-  };
-
-  QuicSentPacketManager(Perspective perspective,
-                        const QuicClock* clock,
-                        QuicRandom* random,
-                        QuicConnectionStats* stats,
-                        CongestionControlType congestion_control_type);
-  QuicSentPacketManager(const QuicSentPacketManager&) = delete;
-  QuicSentPacketManager& operator=(const QuicSentPacketManager&) = delete;
-  virtual ~QuicSentPacketManager();
-
-  virtual void SetFromConfig(const QuicConfig& config);
-
-  void ReserveUnackedPacketsInitialCapacity(int initial_capacity) {
-    unacked_packets_.ReserveInitialCapacity(initial_capacity);
-  }
-
-  void ApplyConnectionOptions(const QuicTagVector& connection_options);
-
-  // Pass the CachedNetworkParameters to the send algorithm.
-  void ResumeConnectionState(
-      const CachedNetworkParameters& cached_network_params,
-      bool max_bandwidth_resumption);
-
-  void SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
-    pacing_sender_.set_max_pacing_rate(max_pacing_rate);
-  }
-
-  QuicBandwidth MaxPacingRate() const {
-    return pacing_sender_.max_pacing_rate();
-  }
-
-  // Called to mark the handshake state complete, and all handshake packets are
-  // neutered.
-  // TODO(fayang): Rename this function to OnHandshakeComplete.
-  void SetHandshakeConfirmed();
-
-  // Requests retransmission of all unacked 0-RTT packets.
-  // Only 0-RTT encrypted packets will be retransmitted. This can happen,
-  // for example, when a CHLO has been rejected and the previously encrypted
-  // data needs to be encrypted with a new key.
-  void MarkZeroRttPacketsForRetransmission();
-
-  // Request retransmission of all unacked INITIAL packets.
-  void MarkInitialPacketsForRetransmission();
-
-  // Notify the sent packet manager of an external network measurement or
-  // prediction for either |bandwidth| or |rtt|; either can be empty.
-  void AdjustNetworkParameters(
-      const SendAlgorithmInterface::NetworkParams& params);
-
-  void SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface> tuner);
-  void OnConfigNegotiated();
-  void OnConnectionClosed();
-
-  // Retransmits the oldest pending packet there is still a tail loss probe
-  // pending.  Invoked after OnRetransmissionTimeout.
-  bool MaybeRetransmitTailLossProbe();
-
-  // Retransmits the oldest pending packet.
-  bool MaybeRetransmitOldestPacket(TransmissionType type);
-
-  // Removes the retransmittable frames from all unencrypted packets to ensure
-  // they don't get retransmitted.
-  void NeuterUnencryptedPackets();
-
-  // Returns true if there's outstanding crypto data.
-  bool HasUnackedCryptoPackets() const {
-    return unacked_packets_.HasPendingCryptoPackets();
-  }
-
-  // Returns true if there are packets in flight expecting to be acknowledged.
-  bool HasInFlightPackets() const {
-    return unacked_packets_.HasInFlightPackets();
-  }
-
-  // Returns the smallest packet number of a serialized packet which has not
-  // been acked by the peer.
-  QuicPacketNumber GetLeastUnacked() const {
-    return unacked_packets_.GetLeastUnacked();
-  }
-
-  // Called when we have sent bytes to the peer.  This informs the manager both
-  // the number of bytes sent and if they were retransmitted and if this packet
-  // is used for rtt measuring.  Returns true if the sender should reset the
-  // retransmission timer.
-  bool OnPacketSent(SerializedPacket* mutable_packet,
-                    QuicTime sent_time,
-                    TransmissionType transmission_type,
-                    HasRetransmittableData has_retransmittable_data,
-                    bool measure_rtt);
-
-  bool CanSendAckFrequency() const;
-
-  QuicAckFrequencyFrame GetUpdatedAckFrequencyFrame() const;
-
-  // Called when the retransmission timer expires and returns the retransmission
-  // mode.
-  RetransmissionTimeoutMode OnRetransmissionTimeout();
-
-  // Calculate the time until we can send the next packet to the wire.
-  // Note 1: When kUnknownWaitTime is returned, there is no need to poll
-  // TimeUntilSend again until we receive an OnIncomingAckFrame event.
-  // Note 2: Send algorithms may or may not use |retransmit| in their
-  // calculations.
-  QuicTime::Delta TimeUntilSend(QuicTime now) const;
-
-  // Returns the current delay for the retransmission timer, which may send
-  // either a tail loss probe or do a full RTO.  Returns QuicTime::Zero() if
-  // there are no retransmittable packets.
-  const QuicTime GetRetransmissionTime() const;
-
-  // Returns the current delay for the path degrading timer, which is used to
-  // notify the session that this connection is degrading.
-  const QuicTime::Delta GetPathDegradingDelay() const;
-
-  // Returns the current delay for detecting network blackhole.
-  const QuicTime::Delta GetNetworkBlackholeDelay(
-      int8_t num_rtos_for_blackhole_detection) const;
-
-  // Returns the delay before reducing max packet size. This delay is guranteed
-  // to be smaller than the network blackhole delay.
-  QuicTime::Delta GetMtuReductionDelay(
-      int8_t num_rtos_for_blackhole_detection) const;
-
-  const RttStats* GetRttStats() const { return &rtt_stats_; }
-
-  void SetRttStats(const RttStats& rtt_stats) {
-    rtt_stats_.CloneFrom(rtt_stats);
-  }
-
-  // Returns the estimated bandwidth calculated by the congestion algorithm.
-  QuicBandwidth BandwidthEstimate() const {
-    return send_algorithm_->BandwidthEstimate();
-  }
-
-  const QuicSustainedBandwidthRecorder* SustainedBandwidthRecorder() const {
-    return &sustained_bandwidth_recorder_;
-  }
-
-  // Returns the size of the current congestion window in number of
-  // kDefaultTCPMSS-sized segments. Note, this is not the *available* window.
-  // Some send algorithms may not use a congestion window and will return 0.
-  QuicPacketCount GetCongestionWindowInTcpMss() const {
-    return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS;
-  }
-
-  // Returns the number of packets of length |max_packet_length| which fit in
-  // the current congestion window. More packets may end up in flight if the
-  // congestion window has been recently reduced, of if non-full packets are
-  // sent.
-  QuicPacketCount EstimateMaxPacketsInFlight(
-      QuicByteCount max_packet_length) const {
-    return send_algorithm_->GetCongestionWindow() / max_packet_length;
-  }
-
-  // Returns the size of the current congestion window size in bytes.
-  QuicByteCount GetCongestionWindowInBytes() const {
-    return send_algorithm_->GetCongestionWindow();
-  }
-
-  // Returns the difference between current congestion window and bytes in
-  // flight. Returns 0 if bytes in flight is bigger than the current congestion
-  // window.
-  QuicByteCount GetAvailableCongestionWindowInBytes() const;
-
-  QuicBandwidth GetPacingRate() const {
-    return send_algorithm_->PacingRate(GetBytesInFlight());
-  }
-
-  // Returns the size of the slow start congestion window in nume of 1460 byte
-  // TCP segments, aka ssthresh.  Some send algorithms do not define a slow
-  // start threshold and will return 0.
-  QuicPacketCount GetSlowStartThresholdInTcpMss() const {
-    return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS;
-  }
-
-  // Return the total time spent in slow start so far. If the sender is
-  // currently in slow start, the return value will include the duration between
-  // the most recent entry to slow start and now.
-  //
-  // Only implemented for BBR. Return QuicTime::Delta::Infinite() for other
-  // congestion controllers.
-  QuicTime::Delta GetSlowStartDuration() const;
-
-  // Returns debugging information about the state of the congestion controller.
-  std::string GetDebugState() const;
-
-  // Returns the number of bytes that are considered in-flight, i.e. not lost or
-  // acknowledged.
-  QuicByteCount GetBytesInFlight() const {
-    return unacked_packets_.bytes_in_flight();
-  }
-
-  // Called when peer address changes. Must be called IFF the address change is
-  // not NAT rebinding. If reset_send_algorithm is true, switch to a new send
-  // algorithm object and retransmit all the in-flight packets. Return the send
-  // algorithm object used on the previous path.
-  std::unique_ptr<SendAlgorithmInterface> OnConnectionMigration(
-      bool reset_send_algorithm);
-
-  // Called when an ack frame is initially parsed.
-  void OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta ack_delay_time,
-                       QuicTime ack_receive_time);
-
-  // Called when ack range [start, end) is received. Populates packets_acked_
-  // with newly acked packets.
-  void OnAckRange(QuicPacketNumber start, QuicPacketNumber end);
-
-  // Called when a timestamp is processed.  If it's present in packets_acked_,
-  // the timestamp field is set.  Otherwise, the timestamp is ignored.
-  void OnAckTimestamp(QuicPacketNumber packet_number, QuicTime timestamp);
-
-  // Called when an ack frame is parsed completely.
-  AckResult OnAckFrameEnd(QuicTime ack_receive_time,
-                          QuicPacketNumber ack_packet_number,
-                          EncryptionLevel ack_decrypted_level);
-
-  void EnableMultiplePacketNumberSpacesSupport();
-
-  void SetDebugDelegate(DebugDelegate* debug_delegate);
-
-  void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity) {
-    pacing_sender_.set_alarm_granularity(alarm_granularity);
-  }
-
-  QuicPacketNumber GetLargestObserved() const {
-    return unacked_packets_.largest_acked();
-  }
-
-  QuicPacketNumber GetLargestAckedPacket(
-      EncryptionLevel decrypted_packet_level) const;
-
-  QuicPacketNumber GetLargestSentPacket() const {
-    return unacked_packets_.largest_sent_packet();
-  }
-
-  // Returns the lowest of the largest acknowledged packet and the least
-  // unacked packet. This is designed to be used when computing the packet
-  // number length to send.
-  QuicPacketNumber GetLeastPacketAwaitedByPeer(
-      EncryptionLevel encryption_level) const;
-
-  QuicPacketNumber GetLargestPacketPeerKnowsIsAcked(
-      EncryptionLevel decrypted_packet_level) const;
-
-  void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor) {
-    QUICHE_DCHECK(!network_change_visitor_);
-    QUICHE_DCHECK(visitor);
-    network_change_visitor_ = visitor;
-  }
-
-  bool InSlowStart() const { return send_algorithm_->InSlowStart(); }
-
-  size_t GetConsecutiveRtoCount() const { return consecutive_rto_count_; }
-
-  size_t GetConsecutiveTlpCount() const { return consecutive_tlp_count_; }
-
-  size_t GetConsecutivePtoCount() const { return consecutive_pto_count_; }
-
-  void OnApplicationLimited();
-
-  const SendAlgorithmInterface* GetSendAlgorithm() const {
-    return send_algorithm_.get();
-  }
-
-  void SetSessionNotifier(SessionNotifierInterface* session_notifier) {
-    unacked_packets_.SetSessionNotifier(session_notifier);
-  }
-
-  NextReleaseTimeResult GetNextReleaseTime() const;
-
-  QuicPacketCount initial_congestion_window() const {
-    return initial_congestion_window_;
-  }
-
-  QuicPacketNumber largest_packet_peer_knows_is_acked() const {
-    QUICHE_DCHECK(!supports_multiple_packet_number_spaces());
-    return largest_packet_peer_knows_is_acked_;
-  }
-
-  size_t pending_timer_transmission_count() const {
-    return pending_timer_transmission_count_;
-  }
-
-  QuicTime::Delta peer_max_ack_delay() const { return peer_max_ack_delay_; }
-
-  void set_peer_max_ack_delay(QuicTime::Delta peer_max_ack_delay) {
-    // The delayed ack time should never be more than one half the min RTO time.
-    QUICHE_DCHECK_LE(peer_max_ack_delay, (min_rto_timeout_ * 0.5));
-    peer_max_ack_delay_ = peer_max_ack_delay;
-  }
-
-  const QuicUnackedPacketMap& unacked_packets() const {
-    return unacked_packets_;
-  }
-
-  const UberLossAlgorithm* uber_loss_algorithm() const {
-    return &uber_loss_algorithm_;
-  }
-
-  // Sets the send algorithm to the given congestion control type and points the
-  // pacing sender at |send_algorithm_|. Can be called any number of times.
-  void SetSendAlgorithm(CongestionControlType congestion_control_type);
-
-  // Sets the send algorithm to |send_algorithm| and points the pacing sender at
-  // |send_algorithm_|. Takes ownership of |send_algorithm|. Can be called any
-  // number of times.
-  // Setting the send algorithm once the connection is underway is dangerous.
-  void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm);
-
-  // Sends up to max_probe_packets_per_pto_ probe packets.
-  void MaybeSendProbePackets();
-
-  // Called to adjust pending_timer_transmission_count_ accordingly.
-  void AdjustPendingTimerTransmissions();
-
-  // Called to disable HANDSHAKE_MODE, and only PTO and LOSS modes are used.
-  // Also enable IETF loss detection.
-  void EnableIetfPtoAndLossDetection();
-
-  // Called to set the start point of doing exponential backoff when calculating
-  // PTO timeout.
-  void StartExponentialBackoffAfterNthPto(
-      size_t exponential_backoff_start_point);
-
-  // Called to retransmit in flight packet of |space| if any.
-  void RetransmitDataOfSpaceIfAny(PacketNumberSpace space);
-
-  // Returns true if |timeout| is less than 3 * RTO/PTO delay.
-  bool IsLessThanThreePTOs(QuicTime::Delta timeout) const;
-
-  // Returns current PTO delay.
-  QuicTime::Delta GetPtoDelay() const;
-
-  bool supports_multiple_packet_number_spaces() const {
-    return unacked_packets_.supports_multiple_packet_number_spaces();
-  }
-
-  bool pto_enabled() const { return pto_enabled_; }
-
-  bool handshake_mode_disabled() const { return handshake_mode_disabled_; }
-
-  bool skip_packet_number_for_pto() const {
-    return skip_packet_number_for_pto_;
-  }
-
-  bool zero_rtt_packet_acked() const { return zero_rtt_packet_acked_; }
-
-  bool one_rtt_packet_acked() const { return one_rtt_packet_acked_; }
-
-  void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); }
-
-  // Gets the earliest in flight packet sent time to calculate PTO. Also
-  // updates |packet_number_space| if a PTO timer should be armed.
-  QuicTime GetEarliestPacketSentTimeForPto(
-      PacketNumberSpace* packet_number_space) const;
-
-  void set_num_ptos_for_path_degrading(int num_ptos_for_path_degrading) {
-    num_ptos_for_path_degrading_ = num_ptos_for_path_degrading;
-  }
-
-  // Sets the initial RTT of the connection. The inital RTT is clamped to
-  // - A maximum of kMaxInitialRoundTripTimeUs.
-  // - A minimum of kMinTrustedInitialRoundTripTimeUs if |trusted|, or
-  // kMinUntrustedInitialRoundTripTimeUs if not |trusted|.
-  void SetInitialRtt(QuicTime::Delta rtt, bool trusted);
-
-  bool use_lower_min_irtt() const { return use_lower_min_irtt_; }
-
-  bool simplify_set_retransmission_alarm() const {
-    return simplify_set_retransmission_alarm_;
-  }
-
- private:
-  friend class test::QuicConnectionPeer;
-  friend class test::QuicSentPacketManagerPeer;
-
-  // Returns the current retransmission mode.
-  RetransmissionTimeoutMode GetRetransmissionMode() const;
-
-  // Retransmits all crypto stream packets.
-  void RetransmitCryptoPackets();
-
-  // Retransmits two packets for an RTO and removes any non-retransmittable
-  // packets from flight.
-  void RetransmitRtoPackets();
-
-  // Returns the timeout for retransmitting crypto handshake packets.
-  const QuicTime::Delta GetCryptoRetransmissionDelay() const;
-
-  // Calls GetTailLossProbeDelay() with values from the current state of this
-  // packet manager as its params.
-  const QuicTime::Delta GetTailLossProbeDelay() const;
-
-  // Calls GetRetransmissionDelay() with values from the current state of this
-  // packet manager as its params.
-  const QuicTime::Delta GetRetransmissionDelay() const;
-
-  // Returns the probe timeout.
-  const QuicTime::Delta GetProbeTimeoutDelay(PacketNumberSpace space) const;
-
-  // Update the RTT if the ack is for the largest acked packet number.
-  // Returns true if the rtt was updated.
-  bool MaybeUpdateRTT(QuicPacketNumber largest_acked,
-                      QuicTime::Delta ack_delay_time,
-                      QuicTime ack_receive_time);
-
-  // Invokes the loss detection algorithm and loses and retransmits packets if
-  // necessary.
-  void InvokeLossDetection(QuicTime time);
-
-  // Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
-  // or pending losses.  Clears pending acks and pending losses afterwards.
-  // |prior_in_flight| is the number of bytes in flight before the losses or
-  // acks, |event_time| is normally the timestamp of the ack packet which caused
-  // the event, although it can be the time at which loss detection was
-  // triggered.
-  void MaybeInvokeCongestionEvent(bool rtt_updated,
-                                  QuicByteCount prior_in_flight,
-                                  QuicTime event_time);
-
-  // Removes the retransmittability and in flight properties from the packet at
-  // |info| due to receipt by the peer.
-  void MarkPacketHandled(QuicPacketNumber packet_number,
-                         QuicTransmissionInfo* info,
-                         QuicTime ack_receive_time,
-                         QuicTime::Delta ack_delay_time,
-                         QuicTime receive_timestamp);
-
-  // Request that |packet_number| be retransmitted after the other pending
-  // retransmissions.  Does not add it to the retransmissions if it's already
-  // a pending retransmission. Do not reuse iterator of the underlying
-  // unacked_packets_ after calling this function as it can be invalidated.
-  void MarkForRetransmission(QuicPacketNumber packet_number,
-                             TransmissionType transmission_type);
-
-  // Called after packets have been marked handled with last received ack frame.
-  void PostProcessNewlyAckedPackets(QuicPacketNumber ack_packet_number,
-                                    EncryptionLevel ack_decrypted_level,
-                                    const QuicAckFrame& ack_frame,
-                                    QuicTime ack_receive_time,
-                                    bool rtt_updated,
-                                    QuicByteCount prior_bytes_in_flight);
-
-  // Notify observers that packet with QuicTransmissionInfo |info| is a spurious
-  // retransmission. It is caller's responsibility to guarantee the packet with
-  // QuicTransmissionInfo |info| is a spurious retransmission before calling
-  // this function.
-  void RecordOneSpuriousRetransmission(const QuicTransmissionInfo& info);
-
-  // Called when handshake is confirmed to remove the retransmittable frames
-  // from all packets of HANDSHAKE_DATA packet number space to ensure they don't
-  // get retransmitted and will eventually be removed from unacked packets map.
-  void NeuterHandshakePackets();
-
-  // Indicates whether including peer_max_ack_delay_ when calculating PTO
-  // timeout.
-  bool ShouldAddMaxAckDelay(PacketNumberSpace space) const;
-
-  // A helper function to return total delay of |num_timeouts| retransmission
-  // timeout with TLP and RTO mode.
-  QuicTime::Delta GetNConsecutiveRetransmissionTimeoutDelay(
-      int num_timeouts) const;
-
-  // Returns true if peer has finished address validation, such that
-  // retransmission timer is not armed if there is no packets in flight.
-  bool PeerCompletedAddressValidation() const;
-
-  // Called when an AckFrequencyFrame is sent.
-  void OnAckFrequencyFrameSent(
-      const QuicAckFrequencyFrame& ack_frequency_frame);
-
-  // Called when an AckFrequencyFrame is acked.
-  void OnAckFrequencyFrameAcked(
-      const QuicAckFrequencyFrame& ack_frequency_frame);
-
-  // Newly serialized retransmittable packets are added to this map, which
-  // contains owning pointers to any contained frames.  If a packet is
-  // retransmitted, this map will contain entries for both the old and the new
-  // packet. The old packet's retransmittable frames entry will be nullptr,
-  // while the new packet's entry will contain the frames to retransmit.
-  // If the old packet is acked before the new packet, then the old entry will
-  // be removed from the map and the new entry's retransmittable frames will be
-  // set to nullptr.
-  QuicUnackedPacketMap unacked_packets_;
-
-  const QuicClock* clock_;
-  QuicRandom* random_;
-  QuicConnectionStats* stats_;
-
-  DebugDelegate* debug_delegate_;
-  NetworkChangeVisitor* network_change_visitor_;
-  QuicPacketCount initial_congestion_window_;
-  RttStats rtt_stats_;
-  std::unique_ptr<SendAlgorithmInterface> send_algorithm_;
-  // Not owned. Always points to |uber_loss_algorithm_| outside of tests.
-  LossDetectionInterface* loss_algorithm_;
-  UberLossAlgorithm uber_loss_algorithm_;
-
-  // Tracks the first RTO packet.  If any packet before that packet gets acked,
-  // it indicates the RTO was spurious and should be reversed(F-RTO).
-  QuicPacketNumber first_rto_transmission_;
-  // Number of times the RTO timer has fired in a row without receiving an ack.
-  size_t consecutive_rto_count_;
-  // Number of times the tail loss probe has been sent.
-  size_t consecutive_tlp_count_;
-  // Number of times the crypto handshake has been retransmitted.
-  size_t consecutive_crypto_retransmission_count_;
-  // Number of pending transmissions of TLP, RTO, or crypto packets.
-  size_t pending_timer_transmission_count_;
-  // Maximum number of tail loss probes to send before firing an RTO.
-  size_t max_tail_loss_probes_;
-  // Maximum number of packets to send upon RTO.
-  QuicPacketCount max_rto_packets_;
-  // If true, send the TLP at 0.5 RTT.
-  bool using_pacing_;
-  // If true, use the new RTO with loss based CWND reduction instead of the send
-  // algorithms's OnRetransmissionTimeout to reduce the congestion window.
-  bool use_new_rto_;
-  // If true, use a more conservative handshake retransmission policy.
-  bool conservative_handshake_retransmits_;
-  // The minimum TLP timeout.
-  QuicTime::Delta min_tlp_timeout_;
-  // The minimum RTO.
-  QuicTime::Delta min_rto_timeout_;
-
-  // Vectors packets acked and lost as a result of the last congestion event.
-  AckedPacketVector packets_acked_;
-  LostPacketVector packets_lost_;
-  // Largest newly acknowledged packet.
-  QuicPacketNumber largest_newly_acked_;
-  // Largest packet in bytes ever acknowledged.
-  QuicPacketLength largest_mtu_acked_;
-
-  // Replaces certain calls to |send_algorithm_| when |using_pacing_| is true.
-  // Calls into |send_algorithm_| for the underlying congestion control.
-  PacingSender pacing_sender_;
-
-  // Indicates whether handshake is finished. This is purely used to determine
-  // retransmission mode. DONOT use this to infer handshake state.
-  bool handshake_finished_;
-
-  // Records bandwidth from server to client in normal operation, over periods
-  // of time with no loss events.
-  QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
-
-  // The largest acked value that was sent in an ack, which has then been acked.
-  QuicPacketNumber largest_packet_peer_knows_is_acked_;
-  // The largest acked value that was sent in an ack, which has then been acked
-  // for per packet number space. Only used when connection supports multiple
-  // packet number spaces.
-  QuicPacketNumber
-      largest_packets_peer_knows_is_acked_[NUM_PACKET_NUMBER_SPACES];
-
-  // The maximum ACK delay time that the peer might uses. Initialized to be the
-  // same as local_max_ack_delay_, may be changed via transport parameter
-  // negotiation or subsequently by AckFrequencyFrame.
-  QuicTime::Delta peer_max_ack_delay_;
-
-  // Peer sends min_ack_delay in TransportParameter to advertise its support for
-  // AckFrequencyFrame.
-  QuicTime::Delta peer_min_ack_delay_ = QuicTime::Delta::Infinite();
-
-  // Use smoothed RTT for computing max_ack_delay in AckFrequency frame.
-  bool use_smoothed_rtt_in_ack_delay_ = false;
-
-  // The history of outstanding max_ack_delays sent to peer. Outstanding means
-  // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or
-  // an unacked AckFrequencyFrame after that.
-  quiche::QuicheCircularDeque<
-      std::pair<QuicTime::Delta, /*sequence_number=*/uint64_t>>
-      in_use_sent_ack_delays_;
-
-  // Latest received ack frame.
-  QuicAckFrame last_ack_frame_;
-
-  // Record whether RTT gets updated by last largest acked..
-  bool rtt_updated_;
-
-  // A reverse iterator of last_ack_frame_.packets. This is reset in
-  // OnAckRangeStart, and gradually moves in OnAckRange..
-  PacketNumberQueue::const_reverse_iterator acked_packets_iter_;
-
-  // Indicates whether PTO mode has been enabled. PTO mode unifies TLP and RTO
-  // modes.
-  bool pto_enabled_;
-
-  // Maximum number of probes to send when PTO fires.
-  size_t max_probe_packets_per_pto_;
-
-  // Number of times the PTO timer has fired in a row without receiving an ack.
-  size_t consecutive_pto_count_;
-
-  // True if HANDSHAKE mode has been disabled.
-  bool handshake_mode_disabled_;
-
-  // If true, skip packet number before sending the last PTO retransmission.
-  bool skip_packet_number_for_pto_;
-
-  // If true, always include peer_max_ack_delay_ when calculating PTO timeout.
-  bool always_include_max_ack_delay_for_pto_timeout_;
-
-  // When calculating PTO timeout, the start point of doing exponential backoff.
-  // For example, 0 : always do exponential backoff. n : do exponential backoff
-  // since nth PTO.
-  size_t pto_exponential_backoff_start_point_;
-
-  // The multiplier of rttvar when calculating PTO timeout.
-  int pto_rttvar_multiplier_;
-
-  // Number of PTOs similar to TLPs.
-  size_t num_tlp_timeout_ptos_;
-
-  // True if any ENCRYPTION_HANDSHAKE packet gets acknowledged.
-  bool handshake_packet_acked_;
-
-  // True if any 0-RTT packet gets acknowledged.
-  bool zero_rtt_packet_acked_;
-
-  // True if any 1-RTT packet gets acknowledged.
-  bool one_rtt_packet_acked_;
-
-  // If > 0, arm the 1st PTO with max of earliest in flight sent time + PTO
-  // delay and multiplier * srtt from last in flight packet.
-  float first_pto_srtt_multiplier_;
-
-  // If true, use standard deviation (instead of mean deviation) when
-  // calculating PTO timeout.
-  bool use_standard_deviation_for_pto_;
-
-  // The multiplier for caculating PTO timeout before any RTT sample is
-  // available.
-  float pto_multiplier_without_rtt_samples_;
-
-  // The number of PTOs needed for path degrading alarm. If equals to 0, the
-  // traditional path degrading mechanism will be used.
-  int num_ptos_for_path_degrading_;
-
-  // If true, do not use PING only packets for RTT measurement or congestion
-  // control.
-  bool ignore_pings_;
-
-  // Whether to ignore the ack_delay in received ACKs.
-  bool ignore_ack_delay_;
-
-  // Latched value of --quic_use_lower_min_for_trusted_irtt.
-  bool use_lower_min_irtt_ =
-      GetQuicReloadableFlag(quic_use_lower_min_for_trusted_irtt);
-
-  const bool simplify_set_retransmission_alarm_ =
-      GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc
deleted file mode 100644
index 6a33fda..0000000
--- a/quic/core/quic_sent_packet_manager_test.cc
+++ /dev/null
@@ -1,4744 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_sent_packet_manager.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::IsEmpty;
-using testing::Not;
-using testing::Pointwise;
-using testing::Return;
-using testing::StrictMock;
-using testing::WithArgs;
-
-namespace quic {
-namespace test {
-namespace {
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-// Stream ID for data sent in CreatePacket().
-const QuicStreamId kStreamId = 7;
-
-// Matcher to check that the packet number matches the second argument.
-MATCHER(PacketNumberEq, "") {
-  return std::get<0>(arg).packet_number == QuicPacketNumber(std::get<1>(arg));
-}
-
-class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
- public:
-  MOCK_METHOD(void, OnSpuriousPacketRetransmission,
-              (TransmissionType transmission_type, QuicByteCount byte_size),
-              (override));
-  MOCK_METHOD(void, OnPacketLoss,
-              (QuicPacketNumber lost_packet_number,
-               EncryptionLevel encryption_level,
-               TransmissionType transmission_type, QuicTime detection_time),
-              (override));
-};
-
-class QuicSentPacketManagerTest : public QuicTest {
- public:
-  bool RetransmitCryptoPacket(uint64_t packet_number) {
-    EXPECT_CALL(
-        *send_algorithm_,
-        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
-                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
-    SerializedPacket packet(CreatePacket(packet_number, false));
-    packet.retransmittable_frames.push_back(
-        QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
-    packet.has_crypto_handshake = IS_HANDSHAKE;
-    manager_.OnPacketSent(&packet, clock_.Now(), HANDSHAKE_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA, true);
-    return true;
-  }
-
-  bool RetransmitDataPacket(uint64_t packet_number, TransmissionType type,
-                            EncryptionLevel level) {
-    EXPECT_CALL(
-        *send_algorithm_,
-        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
-                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
-    SerializedPacket packet(CreatePacket(packet_number, true));
-    packet.encryption_level = level;
-    manager_.OnPacketSent(&packet, clock_.Now(), type, HAS_RETRANSMITTABLE_DATA,
-                          true);
-    return true;
-  }
-
-  bool RetransmitDataPacket(uint64_t packet_number, TransmissionType type) {
-    return RetransmitDataPacket(packet_number, type, ENCRYPTION_INITIAL);
-  }
-
- protected:
-  const CongestionControlType kInitialCongestionControlType = kCubicBytes;
-  QuicSentPacketManagerTest()
-      : manager_(Perspective::IS_SERVER, &clock_, QuicRandom::GetInstance(),
-                 &stats_, kInitialCongestionControlType),
-        send_algorithm_(new StrictMock<MockSendAlgorithm>),
-        network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
-    QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
-    // Disable tail loss probes for most tests.
-    QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
-    // Advance the time 1s so the send times are never QuicTime::Zero.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
-    manager_.SetNetworkChangeVisitor(network_change_visitor_.get());
-    manager_.SetSessionNotifier(&notifier_);
-
-    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
-        .WillRepeatedly(Return(kInitialCongestionControlType));
-    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
-        .Times(AnyNumber())
-        .WillRepeatedly(Return(QuicBandwidth::Zero()));
-    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
-    EXPECT_CALL(*network_change_visitor_, OnPathMtuIncreased(1000))
-        .Times(AnyNumber());
-    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
-    EXPECT_CALL(notifier_, HasUnackedCryptoData())
-        .WillRepeatedly(Return(false));
-    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_)).Times(AnyNumber());
-    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillRepeatedly(Return(true));
-  }
-
-  ~QuicSentPacketManagerTest() override {}
-
-  QuicByteCount BytesInFlight() { return manager_.GetBytesInFlight(); }
-  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
-    if (num_packets == 0) {
-      EXPECT_TRUE(manager_.unacked_packets().empty());
-      EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
-                        &manager_));
-      return;
-    }
-
-    EXPECT_FALSE(manager_.unacked_packets().empty());
-    EXPECT_EQ(QuicPacketNumber(packets[0]), manager_.GetLeastUnacked());
-    for (size_t i = 0; i < num_packets; ++i) {
-      EXPECT_TRUE(
-          manager_.unacked_packets().IsUnacked(QuicPacketNumber(packets[i])))
-          << packets[i];
-    }
-  }
-
-  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
-    EXPECT_EQ(
-        num_packets,
-        QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
-    for (size_t i = 0; i < num_packets; ++i) {
-      EXPECT_TRUE(QuicSentPacketManagerPeer::HasRetransmittableFrames(
-          &manager_, packets[i]))
-          << " packets[" << i << "]:" << packets[i];
-    }
-  }
-
-  void ExpectAck(uint64_t largest_observed) {
-    EXPECT_CALL(
-        *send_algorithm_,
-        // Ensure the AckedPacketVector argument contains largest_observed.
-        OnCongestionEvent(true, _, _,
-                          Pointwise(PacketNumberEq(), {largest_observed}),
-                          IsEmpty()));
-    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  }
-
-  void ExpectUpdatedRtt(uint64_t /*largest_observed*/) {
-    EXPECT_CALL(*send_algorithm_,
-                OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty()));
-    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  }
-
-  void ExpectAckAndLoss(bool rtt_updated, uint64_t largest_observed,
-                        uint64_t lost_packet) {
-    EXPECT_CALL(
-        *send_algorithm_,
-        OnCongestionEvent(rtt_updated, _, _,
-                          Pointwise(PacketNumberEq(), {largest_observed}),
-                          Pointwise(PacketNumberEq(), {lost_packet})));
-    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  }
-
-  // |packets_acked| and |packets_lost| should be in packet number order.
-  void ExpectAcksAndLosses(bool rtt_updated, uint64_t* packets_acked,
-                           size_t num_packets_acked, uint64_t* packets_lost,
-                           size_t num_packets_lost) {
-    std::vector<QuicPacketNumber> ack_vector;
-    for (size_t i = 0; i < num_packets_acked; ++i) {
-      ack_vector.push_back(QuicPacketNumber(packets_acked[i]));
-    }
-    std::vector<QuicPacketNumber> lost_vector;
-    for (size_t i = 0; i < num_packets_lost; ++i) {
-      lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
-    }
-    EXPECT_CALL(*send_algorithm_,
-                OnCongestionEvent(rtt_updated, _, _,
-                                  Pointwise(PacketNumberEq(), ack_vector),
-                                  Pointwise(PacketNumberEq(), lost_vector)));
-    EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
-        .Times(AnyNumber());
-  }
-
-  void RetransmitAndSendPacket(uint64_t old_packet_number,
-                               uint64_t new_packet_number) {
-    RetransmitAndSendPacket(old_packet_number, new_packet_number,
-                            TLP_RETRANSMISSION);
-  }
-
-  void RetransmitAndSendPacket(uint64_t old_packet_number,
-                               uint64_t new_packet_number,
-                               TransmissionType transmission_type) {
-    bool is_lost = false;
-    if (transmission_type == HANDSHAKE_RETRANSMISSION ||
-        transmission_type == TLP_RETRANSMISSION ||
-        transmission_type == RTO_RETRANSMISSION ||
-        transmission_type == PROBING_RETRANSMISSION) {
-      EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-          .WillOnce(WithArgs<1>(
-              Invoke([this, new_packet_number](TransmissionType type) {
-                return RetransmitDataPacket(new_packet_number, type);
-              })));
-    } else {
-      EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
-      is_lost = true;
-    }
-    QuicSentPacketManagerPeer::MarkForRetransmission(
-        &manager_, old_packet_number, transmission_type);
-    if (!is_lost) {
-      return;
-    }
-    EXPECT_CALL(
-        *send_algorithm_,
-        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
-                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
-    SerializedPacket packet(CreatePacket(new_packet_number, true));
-    manager_.OnPacketSent(&packet, clock_.Now(), transmission_type,
-                          HAS_RETRANSMITTABLE_DATA, true);
-  }
-
-  SerializedPacket CreateDataPacket(uint64_t packet_number) {
-    return CreatePacket(packet_number, true);
-  }
-
-  SerializedPacket CreatePacket(uint64_t packet_number, bool retransmittable) {
-    SerializedPacket packet(QuicPacketNumber(packet_number),
-                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
-    if (retransmittable) {
-      packet.retransmittable_frames.push_back(
-          QuicFrame(QuicStreamFrame(kStreamId, false, 0, absl::string_view())));
-    }
-    return packet;
-  }
-
-  SerializedPacket CreatePingPacket(uint64_t packet_number) {
-    SerializedPacket packet(QuicPacketNumber(packet_number),
-                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
-    packet.retransmittable_frames.push_back(QuicFrame(QuicPingFrame()));
-    return packet;
-  }
-
-  void SendDataPacket(uint64_t packet_number) {
-    SendDataPacket(packet_number, ENCRYPTION_INITIAL);
-  }
-
-  void SendDataPacket(uint64_t packet_number,
-                      EncryptionLevel encryption_level) {
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(),
-                             QuicPacketNumber(packet_number), _, _));
-    SerializedPacket packet(CreateDataPacket(packet_number));
-    packet.encryption_level = encryption_level;
-    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA, true);
-  }
-
-  void SendPingPacket(uint64_t packet_number,
-                      EncryptionLevel encryption_level) {
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(),
-                             QuicPacketNumber(packet_number), _, _));
-    SerializedPacket packet(CreatePingPacket(packet_number));
-    packet.encryption_level = encryption_level;
-    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA, true);
-  }
-
-  void SendCryptoPacket(uint64_t packet_number) {
-    EXPECT_CALL(
-        *send_algorithm_,
-        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
-                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
-    SerializedPacket packet(CreatePacket(packet_number, false));
-    packet.retransmittable_frames.push_back(
-        QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
-    packet.has_crypto_handshake = IS_HANDSHAKE;
-    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA, true);
-    EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(true));
-  }
-
-  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked) {
-    SendAckPacket(packet_number, largest_acked, ENCRYPTION_INITIAL);
-  }
-
-  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked,
-                     EncryptionLevel level) {
-    EXPECT_CALL(
-        *send_algorithm_,
-        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
-                     kDefaultLength, NO_RETRANSMITTABLE_DATA));
-    SerializedPacket packet(CreatePacket(packet_number, false));
-    packet.largest_acked = QuicPacketNumber(largest_acked);
-    packet.encryption_level = level;
-    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                          NO_RETRANSMITTABLE_DATA, true);
-  }
-
-  void EnablePto(QuicTag tag) {
-    QuicConfig config;
-    QuicTagVector options;
-    options.push_back(tag);
-    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-    manager_.SetFromConfig(config);
-    EXPECT_TRUE(manager_.pto_enabled());
-  }
-
-  int GetPtoRttvarMultiplier() {
-    if (GetQuicRestartFlag(quic_default_on_pto2) ||
-        manager_.handshake_mode_disabled()) {
-      return 2;
-    }
-    return 4;
-  }
-
-  quiche::SimpleBufferAllocator allocator_;
-  QuicSentPacketManager manager_;
-  MockClock clock_;
-  QuicConnectionStats stats_;
-  MockSendAlgorithm* send_algorithm_;
-  std::unique_ptr<MockNetworkChangeVisitor> network_change_visitor_;
-  StrictMock<MockSessionNotifier> notifier_;
-};
-
-TEST_F(QuicSentPacketManagerTest, IsUnacked) {
-  VerifyUnackedPackets(nullptr, 0);
-  SendDataPacket(1);
-
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  uint64_t retransmittable[] = {1};
-  VerifyRetransmittablePackets(retransmittable,
-                               ABSL_ARRAYSIZE(retransmittable));
-}
-
-TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-
-  EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
-  uint64_t unacked[] = {1, 2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  std::vector<uint64_t> retransmittable = {1, 2};
-  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-
-  // Ack 2 but not 1.
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  // Packet 1 is unacked, pending, but not retransmittable.
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  EXPECT_TRUE(manager_.HasInFlightPackets());
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
-  SendDataPacket(1);
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(2, type);
-      })));
-  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
-                                                   TLP_RETRANSMISSION);
-  // Ack 1.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  uint64_t unacked[] = {2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  // We do not know packet 2 is a spurious retransmission until it gets acked.
-  VerifyRetransmittablePackets(nullptr, 0);
-  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
-  SendDataPacket(1);
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).WillRepeatedly(Return(true));
-  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
-                                                   TLP_RETRANSMISSION);
-
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
-  clock_.AdvanceTime(rtt);
-
-  // Ack 1 but not 2.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  // 2 remains unacked, but no packets have retransmittable data.
-  uint64_t unacked[] = {2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  EXPECT_TRUE(manager_.HasInFlightPackets());
-  VerifyRetransmittablePackets(nullptr, 0);
-  // Ack 2 causes 2 be considered as spurious retransmission.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-
-  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
-  clock_.AdvanceTime(rtt);
-
-  // First, ACK packet 1 which makes packet 2 non-retransmittable.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  SendDataPacket(3);
-  SendDataPacket(4);
-  SendDataPacket(5);
-  clock_.AdvanceTime(rtt);
-
-  // Next, NACK packet 2 three times.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
-  ExpectAckAndLoss(true, 3, 2);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-
-  ExpectAck(4);
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_INITIAL));
-
-  ExpectAck(5);
-  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
-                                   ENCRYPTION_INITIAL));
-
-  uint64_t unacked[] = {2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  EXPECT_FALSE(manager_.HasInFlightPackets());
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  // Verify that the retransmission alarm would not fire,
-  // since there is no retransmittable data outstanding.
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       DISABLED_RetransmitTwiceThenAckPreviousBeforeSend) {
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-
-  // Fire the RTO, which will mark 2 for retransmission (but will not send it).
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.OnRetransmissionTimeout();
-
-  // Ack 1 but not 2, before 2 is able to be sent.
-  // Since 1 has been retransmitted, it has already been lost, and so the
-  // send algorithm is not informed that it has been ACK'd.
-  ExpectUpdatedRtt(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
-  uint64_t unacked[] = {2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  EXPECT_FALSE(manager_.HasInFlightPackets());
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  // Verify that the retransmission alarm would not fire,
-  // since there is no retransmittable data outstanding.
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
-  StrictMock<MockDebugDelegate> debug_delegate;
-  EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(TLP_RETRANSMISSION,
-                                                             kDefaultLength))
-      .Times(1);
-  manager_.SetDebugDelegate(&debug_delegate);
-
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-  RetransmitAndSendPacket(2, 3);
-  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
-  clock_.AdvanceTime(rtt);
-
-  // Ack 1 but not 2 or 3.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  // Frames in packets 2 and 3 are acked.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_))
-      .Times(2)
-      .WillRepeatedly(Return(false));
-
-  // 2 and 3 remain unacked, but no packets have retransmittable data.
-  uint64_t unacked[] = {2, 3};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  EXPECT_TRUE(manager_.HasInFlightPackets());
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  // Ensure packet 2 is lost when 4 is sent and 3 and 4 are acked.
-  SendDataPacket(4);
-  // No new data gets acked in packet 3.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
-      .WillOnce(Return(false))
-      .WillRepeatedly(Return(true));
-  uint64_t acked[] = {3, 4};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-
-  uint64_t unacked2[] = {2};
-  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
-  EXPECT_TRUE(manager_.HasInFlightPackets());
-
-  SendDataPacket(5);
-  ExpectAckAndLoss(true, 5, 2);
-  EXPECT_CALL(debug_delegate,
-              OnPacketLoss(QuicPacketNumber(2), _, LOSS_RETRANSMISSION, _));
-  // Frames in all packets are acked.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  // Notify session that stream frame in packet 2 gets lost although it is
-  // not outstanding.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_INITIAL));
-
-  uint64_t unacked3[] = {2};
-  VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
-  EXPECT_FALSE(manager_.HasInFlightPackets());
-  // Spurious retransmission is detected when packet 3 gets acked. We cannot
-  // know packet 2 is a spurious until it gets acked.
-  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
-  EXPECT_EQ(1u, stats_.packets_lost);
-  EXPECT_LT(0.0, stats_.total_loss_detection_response_time);
-  EXPECT_LE(1u, stats_.sent_packets_max_sequence_reordering);
-}
-
-TEST_F(QuicSentPacketManagerTest, AckOriginalTransmission) {
-  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
-  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
-
-  SendDataPacket(1);
-  RetransmitAndSendPacket(1, 2);
-
-  // Ack original transmission, but that wasn't lost via fast retransmit,
-  // so no call on OnSpuriousRetransmission is expected.
-  {
-    ExpectAck(1);
-    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                             clock_.Now());
-    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-    EXPECT_EQ(PACKETS_NEWLY_ACKED,
-              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                     ENCRYPTION_INITIAL));
-  }
-
-  SendDataPacket(3);
-  SendDataPacket(4);
-  // Ack 4, which causes 3 to be retransmitted.
-  {
-    ExpectAck(4);
-    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                             clock_.Now());
-    manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
-    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-    EXPECT_EQ(PACKETS_NEWLY_ACKED,
-              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                     ENCRYPTION_INITIAL));
-    RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
-  }
-
-  // Ack 3, which causes SpuriousRetransmitDetected to be called.
-  {
-    uint64_t acked[] = {3};
-    ExpectAcksAndLosses(false, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    EXPECT_CALL(*loss_algorithm,
-                SpuriousLossDetected(_, _, _, QuicPacketNumber(3),
-                                     QuicPacketNumber(4)));
-    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                             clock_.Now());
-    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
-    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-    EXPECT_EQ(0u, stats_.packet_spuriously_detected_lost);
-    EXPECT_EQ(PACKETS_NEWLY_ACKED,
-              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                     ENCRYPTION_INITIAL));
-    EXPECT_EQ(1u, stats_.packet_spuriously_detected_lost);
-    // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
-    // 5 will cause 5 be considered as a spurious retransmission as no new
-    // data gets acked.
-    ExpectAck(5);
-    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
-    manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
-                             clock_.Now());
-    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
-    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-    EXPECT_EQ(PACKETS_NEWLY_ACKED,
-              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
-                                     ENCRYPTION_INITIAL));
-  }
-}
-
-TEST_F(QuicSentPacketManagerTest, GetLeastUnacked) {
-  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
-  SendDataPacket(1);
-  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
-}
-
-TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
-  EXPECT_FALSE(manager_.largest_packet_peer_knows_is_acked().IsInitialized());
-  SendDataPacket(1);
-  SendAckPacket(2, 1);
-
-  // Now ack the ack and expect an RTT update.
-  uint64_t acked[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(2),
-                           QuicTime::Delta::FromMilliseconds(5), clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicPacketNumber(1), manager_.largest_packet_peer_knows_is_acked());
-
-  SendAckPacket(3, 3);
-
-  // Now ack the ack and expect only an RTT update.
-  uint64_t acked2[] = {3};
-  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicPacketNumber(3u),
-            manager_.largest_packet_peer_knows_is_acked());
-}
-
-TEST_F(QuicSentPacketManagerTest, Rtt) {
-  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(20);
-  SendDataPacket(1);
-  clock_.AdvanceTime(expected_rtt);
-
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) {
-  // Expect that the RTT is equal to the local time elapsed, since the
-  // ack_delay_time is larger than the local time elapsed
-  // and is hence invalid.
-  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
-  SendDataPacket(1);
-  clock_.AdvanceTime(expected_rtt);
-
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1),
-                           QuicTime::Delta::FromMilliseconds(11), clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
-  // Expect that the RTT is equal to the local time elapsed, since the
-  // ack_delay_time is infinite, and is hence invalid.
-  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
-  SendDataPacket(1);
-  clock_.AdvanceTime(expected_rtt);
-
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttWithDeltaExceedingLimit) {
-  // Initialize min and smoothed rtt to 10ms.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  QuicTime::Delta send_delta = QuicTime::Delta::FromMilliseconds(100);
-  QuicTime::Delta ack_delay =
-      QuicTime::Delta::FromMilliseconds(5) + manager_.peer_max_ack_delay();
-  ASSERT_GT(send_delta - rtt_stats->min_rtt(), ack_delay);
-  SendDataPacket(1);
-  clock_.AdvanceTime(send_delta);
-
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), ack_delay, clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-
-  QuicTime::Delta expected_rtt_sample =
-      send_delta - manager_.peer_max_ack_delay();
-  EXPECT_EQ(expected_rtt_sample, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
-  // Expect that the RTT is the time between send and receive since the
-  // ack_delay_time is zero.
-  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
-  SendDataPacket(1);
-  clock_.AdvanceTime(expected_rtt);
-
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Zero(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-
-  // Send 1 packet.
-  SendDataPacket(1);
-
-  // The first tail loss probe retransmits 1 packet.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(2, type);
-      })));
-  manager_.MaybeRetransmitTailLossProbe();
-
-  // The second tail loss probe retransmits 1 packet.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type);
-      })));
-  manager_.MaybeRetransmitTailLossProbe();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
-  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
-  // Ack the third and ensure the first two are still pending.
-  ExpectAck(3);
-
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  EXPECT_TRUE(manager_.HasInFlightPackets());
-
-  // Acking two more packets will lose both of them due to nacks.
-  SendDataPacket(4);
-  SendDataPacket(5);
-  uint64_t acked[] = {4, 5};
-  uint64_t lost[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
-                      ABSL_ARRAYSIZE(lost));
-  // Frames in all packets are acked.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  // Notify session that stream frame in packets 1 and 2 get lost although
-  // they are not outstanding.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-
-  EXPECT_FALSE(manager_.HasInFlightPackets());
-  EXPECT_EQ(2u, stats_.tlp_count);
-  EXPECT_EQ(0u, stats_.rto_count);
-}
-
-TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-
-  // Send 100 packets.
-  const size_t kNumSentPackets = 100;
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-  QuicTime rto_packet_time = clock_.Now();
-  // Advance the time.
-  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
-
-  // The first tail loss probe retransmits 1 packet.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(101, type);
-      })));
-  manager_.MaybeRetransmitTailLossProbe();
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
-  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
-
-  // The second tail loss probe retransmits 1 packet.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(102, type);
-      })));
-  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
-  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
-  // Ensure the RTO is set based on the correct packet.
-  rto_packet_time = clock_.Now();
-  EXPECT_EQ(rto_packet_time + QuicTime::Delta::FromMilliseconds(500),
-            manager_.GetRetransmissionTime());
-
-  // Advance the time enough to ensure all packets are RTO'd.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(103, type);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(104, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(2u, stats_.tlp_count);
-  EXPECT_EQ(1u, stats_.rto_count);
-  EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
-  // There are 2 RTO retransmissions.
-  EXPECT_EQ(104 * kDefaultLength, manager_.GetBytesInFlight());
-  QuicPacketNumber largest_acked = QuicPacketNumber(103);
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(
-                  true, _, _, Pointwise(PacketNumberEq(), {largest_acked}), _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  // Although frames in packet 3 gets acked, it would be kept for another
-  // RTT.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
-  // Packets [1, 102] are lost, although stream frame in packet 3 is not
-  // outstanding.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(102);
-  manager_.OnAckFrameStart(QuicPacketNumber(103), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(103), QuicPacketNumber(104));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  // All packets before 103 should be lost.
-  // Packet 104 is still in flight.
-  EXPECT_EQ(1000u, manager_.GetBytesInFlight());
-  EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
-}
-
-TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
-  // Send 2 crypto packets and 3 data packets.
-  const size_t kNumSentCryptoPackets = 2;
-  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
-    SendCryptoPacket(i);
-  }
-  const size_t kNumSentDataPackets = 3;
-  for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
-    SendDataPacket(kNumSentCryptoPackets + i);
-  }
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-  EXPECT_EQ(5 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // The first retransmits 2 packets.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(6); }))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(7); }));
-  manager_.OnRetransmissionTimeout();
-  // Expect all 4 handshake packets to be in flight and 3 data packets.
-  EXPECT_EQ(7 * kDefaultLength, manager_.GetBytesInFlight());
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // The second retransmits 2 packets.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(8); }))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(9); }));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(9 * kDefaultLength, manager_.GetBytesInFlight());
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // Now ack the two crypto packets and the speculatively encrypted request,
-  // and ensure the first four crypto packets get abandoned, but not lost.
-  // Crypto packets remain in flight, so any that aren't acked will be lost.
-  uint64_t acked[] = {3, 4, 5, 8, 9};
-  uint64_t lost[] = {1, 2, 6};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
-                      ABSL_ARRAYSIZE(lost));
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(3);
-  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
-  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
-}
-
-TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
-  // Send 1 crypto packet.
-  SendCryptoPacket(1);
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // Retransmit the crypto packet as 2.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
-  manager_.OnRetransmissionTimeout();
-
-  // Retransmit the crypto packet as 3.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
-  manager_.OnRetransmissionTimeout();
-
-  // Now ack the second crypto packet, and ensure the first gets removed, but
-  // the third does not.
-  uint64_t acked[] = {2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
-  uint64_t unacked[] = {1, 3};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-}
-
-TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
-  // Send 2 crypto packets and 1 data packet.
-  const size_t kNumSentCryptoPackets = 2;
-  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
-    SendCryptoPacket(i);
-  }
-  SendDataPacket(3);
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // Retransmit 2 crypto packets, but not the serialized packet.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(5); }));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       CryptoHandshakeRetransmissionThenNeuterAndAck) {
-  // Send 1 crypto packet.
-  SendCryptoPacket(1);
-
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // Retransmit the crypto packet as 2.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // Retransmit the crypto packet as 3.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
-  // Now neuter all unacked unencrypted packets, which occurs when the
-  // connection goes forward secure.
-  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.NeuterUnencryptedPackets();
-  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
-  uint64_t unacked[] = {1, 2, 3};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
-  EXPECT_FALSE(manager_.HasInFlightPackets());
-
-  // Ensure both packets get discarded when packet 2 is acked.
-  uint64_t acked[] = {3};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  VerifyUnackedPackets(nullptr, 0);
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  StrictMock<MockDebugDelegate> debug_delegate;
-  manager_.SetDebugDelegate(&debug_delegate);
-
-  // Send 100 packets.
-  const size_t kNumSentPackets = 100;
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-
-  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(101, type);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(102, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Ack a retransmission.
-  // Ensure no packets are lost.
-  QuicPacketNumber largest_acked = QuicPacketNumber(102);
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(true, _, _,
-                                Pointwise(PacketNumberEq(), {largest_acked}),
-                                /*lost_packets=*/IsEmpty()));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  // RTO's use loss detection instead of immediately declaring retransmitted
-  // packets lost.
-  for (int i = 1; i <= 99; ++i) {
-    EXPECT_CALL(debug_delegate,
-                OnPacketLoss(QuicPacketNumber(i), _, LOSS_RETRANSMISSION, _));
-  }
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
-  // Packets [1, 99] are considered as lost, although stream frame in packet
-  // 2 is not outstanding.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
-  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionTimeoutOnePacket) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  // Set the 1RTO connection option.
-  QuicConfig client_config;
-  QuicTagVector options;
-  options.push_back(k1RTO);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  manager_.SetFromConfig(client_config);
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
-  StrictMock<MockDebugDelegate> debug_delegate;
-  manager_.SetDebugDelegate(&debug_delegate);
-
-  // Send 100 packets.
-  const size_t kNumSentPackets = 100;
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-
-  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(1)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(101, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(101 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
-TEST_F(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector options;
-  options.push_back(kNRTO);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  manager_.SetFromConfig(client_config);
-  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
-  // Send 100 packets.
-  const size_t kNumSentPackets = 100;
-  for (size_t i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-
-  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(101, type);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(102, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Ack a retransmission and expect no call to OnRetransmissionTimeout.
-  // This will include packets in the lost packet map.
-  QuicPacketNumber largest_acked = QuicPacketNumber(102);
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(true, _, _,
-                                Pointwise(PacketNumberEq(), {largest_acked}),
-                                /*lost_packets=*/Not(IsEmpty())));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
-  // Packets [1, 99] are considered as lost, although stream frame in packet
-  // 2 is not outstanding.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
-  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  // Send 1 packet.
-  SendDataPacket(1);
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(2, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Rto a second time.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // The original packet and newest should be outstanding.
-  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
-TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  // Send 1 packet.
-  SendDataPacket(1);
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(2, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Rto a second time.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  ExpectAck(3);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Zero(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // The first two packets should still be outstanding.
-  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTime) {
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
-  QuicTime crypto_packet_send_time = clock_.Now();
-  SendCryptoPacket(1);
-
-  // Check the min.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
-            manager_.GetRetransmissionTime());
-
-  // Test with a standard smoothed RTT.
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
-
-  QuicTime::Delta srtt = rtt_stats->initial_rtt();
-  QuicTime expected_time = clock_.Now() + 1.5 * srtt;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
-  // Retransmit the packet by invoking the retransmission timeout.
-  clock_.AdvanceTime(1.5 * srtt);
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
-  // When session decides what to write, crypto_packet_send_time gets updated.
-  crypto_packet_send_time = clock_.Now();
-  manager_.OnRetransmissionTimeout();
-
-  // The retransmission time should now be twice as far in the future.
-  expected_time = crypto_packet_send_time + srtt * 2 * 1.5;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
-  // Retransmit the packet for the 2nd time.
-  clock_.AdvanceTime(2 * 1.5 * srtt);
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
-  // When session decides what to write, crypto_packet_send_time gets updated.
-  crypto_packet_send_time = clock_.Now();
-  manager_.OnRetransmissionTimeout();
-
-  // Verify exponential backoff of the retransmission timeout.
-  expected_time = crypto_packet_send_time + srtt * 4 * 1.5;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       GetConservativeTransmissionTimeCryptoHandshake) {
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kCONH);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  // Calling SetFromConfig requires mocking out some send algorithm methods.
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
-  QuicTime crypto_packet_send_time = clock_.Now();
-  SendCryptoPacket(1);
-
-  // Check the min.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(25),
-            manager_.GetRetransmissionTime());
-
-  // Test with a standard smoothed RTT.
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
-
-  QuicTime::Delta srtt = rtt_stats->initial_rtt();
-  QuicTime expected_time = clock_.Now() + 2 * srtt;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
-  // Retransmit the packet by invoking the retransmission timeout.
-  clock_.AdvanceTime(2 * srtt);
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
-  crypto_packet_send_time = clock_.Now();
-  manager_.OnRetransmissionTimeout();
-
-  // The retransmission time should now be twice as far in the future.
-  expected_time = crypto_packet_send_time + srtt * 2 * 2;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-  SendDataPacket(1);
-  SendDataPacket(2);
-
-  // Check the min.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
-            manager_.GetRetransmissionTime());
-
-  // Test with a standard smoothed RTT.
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
-  QuicTime::Delta srtt = rtt_stats->initial_rtt();
-  QuicTime::Delta expected_tlp_delay = 2 * srtt;
-  QuicTime expected_time = clock_.Now() + expected_tlp_delay;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
-  // Retransmit the packet by invoking the retransmission timeout.
-  clock_.AdvanceTime(expected_tlp_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type);
-      })));
-  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
-  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
-  expected_time = clock_.Now() + expected_tlp_delay;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  SendDataPacket(1);
-  SendDataPacket(2);
-  SendDataPacket(3);
-  SendDataPacket(4);
-
-  QuicTime::Delta expected_rto_delay =
-      rtt_stats->smoothed_rtt() + 4 * rtt_stats->mean_deviation();
-  QuicTime expected_time = clock_.Now() + expected_rto_delay;
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
-  // Retransmit the packet by invoking the retransmission timeout.
-  clock_.AdvanceTime(expected_rto_delay);
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(5, type);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(6, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  // All previous packets are inflight, plus two rto retransmissions.
-  EXPECT_EQ(6 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // The delay should double the second time.
-  expected_time = clock_.Now() + expected_rto_delay + expected_rto_delay;
-  // Once we always base the timer on the right edge, leaving the older packets
-  // in flight doesn't change the timeout.
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
-  // Ack a packet before the first RTO and ensure the RTO timeout returns to the
-  // original value and OnRetransmissionTimeout is not called or reverted.
-  uint64_t acked[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(4 * kDefaultLength, manager_.GetBytesInFlight());
-
-  // Wait 2RTTs from now for the RTO, since it's the max of the RTO time
-  // and the TLP time.  In production, there would always be two TLP's first.
-  // Since retransmission was spurious, smoothed_rtt_ is expired, and replaced
-  // by the latest RTT sample of 500ms.
-  expected_time = clock_.Now() + QuicTime::Delta::FromMilliseconds(1000);
-  // Once we always base the timer on the right edge, leaving the older packets
-  // in flight doesn't change the timeout.
-  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  SendDataPacket(1);
-  // Provide a 1ms RTT sample.
-  const_cast<RttStats*>(manager_.GetRttStats())
-      ->UpdateRtt(QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::Zero(),
-                  QuicTime::Zero());
-  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(200);
-
-  // If the delay is smaller than the min, ensure it exponentially backs off
-  // from the min.
-  for (int i = 0; i < 5; ++i) {
-    EXPECT_EQ(delay,
-              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-    delay = delay + delay;
-    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-        .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
-          return RetransmitDataPacket(i + 2, type);
-        })));
-    manager_.OnRetransmissionTimeout();
-  }
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  SendDataPacket(1);
-  // Provide a 60s RTT sample.
-  const_cast<RttStats*>(manager_.GetRttStats())
-      ->UpdateRtt(QuicTime::Delta::FromSeconds(60), QuicTime::Delta::Zero(),
-                  QuicTime::Zero());
-
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
-            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  SendDataPacket(1);
-  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500);
-
-  // Delay should back off exponentially.
-  for (int i = 0; i < 5; ++i) {
-    EXPECT_EQ(delay,
-              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-    delay = delay + delay;
-    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-        .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
-          return RetransmitDataPacket(i + 2, type);
-        })));
-    manager_.OnRetransmissionTimeout();
-  }
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionDelay) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  const int64_t kRttMs = 250;
-  const int64_t kDeviationMs = 5;
-
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
-                       QuicTime::Delta::Zero(), clock_.Now());
-
-  // Initial value is to set the median deviation to half of the initial rtt,
-  // the median in then multiplied by a factor of 4 and finally the smoothed rtt
-  // is added which is the initial rtt.
-  QuicTime::Delta expected_delay =
-      QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
-  EXPECT_EQ(expected_delay,
-            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-
-  for (int i = 0; i < 100; ++i) {
-    // Run to make sure that we converge.
-    rtt_stats->UpdateRtt(
-        QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
-        QuicTime::Delta::Zero(), clock_.Now());
-    rtt_stats->UpdateRtt(
-        QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
-        QuicTime::Delta::Zero(), clock_.Now());
-  }
-  expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
-
-  EXPECT_NEAR(kRttMs, rtt_stats->smoothed_rtt().ToMilliseconds(), 1);
-  EXPECT_NEAR(expected_delay.ToMilliseconds(),
-              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
-                  .ToMilliseconds(),
-              1);
-}
-
-TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
-  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
-  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
-
-  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
-      .WillRepeatedly(Return(QuicTime::Zero()));
-  SendDataPacket(1);
-  SendDataPacket(2);
-
-  // Handle an ack which causes the loss algorithm to be evaluated and
-  // set the loss timeout.
-  ExpectAck(2);
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
-      .WillRepeatedly(Return(timeout));
-  EXPECT_EQ(timeout, manager_.GetRetransmissionTime());
-
-  // Fire the retransmission timeout and ensure the loss detection algorithm
-  // is invoked.
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  manager_.OnRetransmissionTimeout();
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateIetfLossDetectionFromOptions) {
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kILD0);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       NegotiateIetfLossDetectionOneFourthRttFromOptions) {
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kILD1);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       NegotiateIetfLossDetectionAdaptiveReorderingThreshold) {
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kILD2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       NegotiateIetfLossDetectionAdaptiveReorderingThreshold2) {
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kILD3);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       NegotiateIetfLossDetectionAdaptiveReorderingAndTimeThreshold) {
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kILD4);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_EQ(kDefaultLossDelayShift,
-            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
-  QuicConfig config;
-  QuicTagVector options;
-
-  options.push_back(kRENO);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                            ->GetCongestionControlType());
-
-  options.clear();
-  options.push_back(kTBBR);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                      ->GetCongestionControlType());
-
-  options.clear();
-  options.push_back(kBYTE);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                             ->GetCongestionControlType());
-  options.clear();
-  options.push_back(kRENO);
-  options.push_back(kBYTE);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                            ->GetCongestionControlType());
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
-  QuicConfig config;
-  QuicTagVector options;
-
-  // No change if the server receives client options.
-  const SendAlgorithmInterface* mock_sender =
-      QuicSentPacketManagerPeer::GetSendAlgorithm(manager_);
-  options.push_back(kRENO);
-  config.SetClientConnectionOptions(options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(mock_sender, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_));
-
-  // Change the congestion control on the client with client options.
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                            ->GetCongestionControlType());
-
-  options.clear();
-  options.push_back(kTBBR);
-  config.SetClientConnectionOptions(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                      ->GetCongestionControlType());
-
-  options.clear();
-  options.push_back(kBYTE);
-  config.SetClientConnectionOptions(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                             ->GetCongestionControlType());
-
-  options.clear();
-  options.push_back(kRENO);
-  options.push_back(kBYTE);
-  config.SetClientConnectionOptions(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
-                            ->GetCongestionControlType());
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtServer) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector options;
-
-  options.push_back(kMAD2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillOnce(Return(10 * kDefaultTCPMSS));
-  manager_.SetFromConfig(config);
-  // Set the initial RTT to 1us.
-  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
-      QuicTime::Delta::FromMicroseconds(1));
-  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
-            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-
-  // Send two packets, and the TLP should be 1ms.
-  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
-  SendDataPacket(1);
-  SendDataPacket(2);
-  EXPECT_EQ(expected_tlp_delay,
-            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtClient) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector options;
-
-  options.push_back(kMAD2);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillOnce(Return(10 * kDefaultTCPMSS));
-  manager_.SetFromConfig(client_config);
-  // Set the initial RTT to 1us.
-  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
-      QuicTime::Delta::FromMicroseconds(1));
-  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
-            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-  // Send two packets, and the TLP should be 1ms.
-  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
-  SendDataPacket(1);
-  SendDataPacket(2);
-  EXPECT_EQ(expected_tlp_delay,
-            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtServer) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector options;
-
-  options.push_back(kMAD3);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(config);
-  // Provide one RTT measurement, because otherwise we use the default of 500ms.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
-  EXPECT_EQ(expected_rto_delay,
-            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
-  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
-  EXPECT_EQ(expected_tlp_delay,
-            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtClient) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector options;
-
-  options.push_back(kMAD3);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(client_config);
-  // Provide one RTT measurement, because otherwise we use the default of 500ms.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
-  EXPECT_EQ(expected_rto_delay,
-            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
-  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
-  EXPECT_EQ(expected_tlp_delay,
-            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtServer) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector options;
-
-  options.push_back(kNTLP);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtClient) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector options;
-
-  options.push_back(kNTLP);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(client_config);
-  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtServer) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig config;
-  QuicTagVector options;
-
-  options.push_back(k1TLP);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(config);
-  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtClient) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicConfig client_config;
-  QuicTagVector options;
-
-  options.push_back(k1TLP);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(client_config);
-  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtServer) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-  QuicConfig config;
-  QuicTagVector options;
-
-  options.push_back(kNRTO);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtClient) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-  QuicConfig client_config;
-  QuicTagVector options;
-
-  options.push_back(kNRTO);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  manager_.SetFromConfig(client_config);
-  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
-  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(325);
-  EXPECT_NE(initial_rtt, manager_.GetRttStats()->smoothed_rtt());
-
-  QuicConfig config;
-  config.SetInitialRoundTripTimeUsToSend(initial_rtt.ToMicroseconds());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.GetRttStats()->smoothed_rtt());
-  EXPECT_EQ(initial_rtt, manager_.GetRttStats()->initial_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, ResumeConnectionState) {
-  // The sent packet manager should use the RTT from CachedNetworkParameters if
-  // it is provided.
-  const QuicTime::Delta kRtt = QuicTime::Delta::FromMilliseconds(123);
-  CachedNetworkParameters cached_network_params;
-  cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds());
-
-  SendAlgorithmInterface::NetworkParams params;
-  params.bandwidth = QuicBandwidth::Zero();
-  params.allow_cwnd_to_decrease = false;
-  params.rtt = kRtt;
-  params.is_rtt_trusted = true;
-
-  EXPECT_CALL(*send_algorithm_, AdjustNetworkParameters(params));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .Times(testing::AnyNumber());
-  manager_.ResumeConnectionState(cached_network_params, false);
-  EXPECT_EQ(kRtt, manager_.GetRttStats()->initial_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) {
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
-  rtt_stats->set_initial_rtt(default_init_rtt * 2);
-  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
-
-  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
-  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
-  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
-  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
-
-  EXPECT_CALL(*send_algorithm_, OnConnectionMigration());
-  EXPECT_EQ(nullptr,
-            manager_.OnConnectionMigration(/*reset_send_algorithm=*/false));
-
-  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
-  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
-  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
-}
-
-// Tests that ResetCongestionControlUponPeerAddressChange() resets send
-// algorithm and RTT. And unACK'ed packets are handled correctly.
-TEST_F(QuicSentPacketManagerTest,
-       ConnectionMigrationUnspecifiedChangeResetSendAlgorithm) {
-  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
-  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
-
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
-  rtt_stats->set_initial_rtt(default_init_rtt * 2);
-  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
-
-  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
-  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
-  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
-  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-
-  RttStats old_rtt_stats;
-  old_rtt_stats.CloneFrom(*manager_.GetRttStats());
-
-  // Packet1 will be mark for retransmission upon migration.
-  EXPECT_CALL(notifier_, OnFrameLost(_));
-  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
-      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
-
-  EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
-  EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
-            manager_.GetSendAlgorithm()->GetCongestionControlType());
-  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
-  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
-  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
-  // Packets sent earlier shouldn't be regarded as in flight.
-  EXPECT_EQ(0u, BytesInFlight());
-
-  // Replace the new send algorithm with the mock object.
-  manager_.SetSendAlgorithm(old_send_algorithm.release());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  // Application retransmit the data as LOSS_RETRANSMISSION.
-  RetransmitDataPacket(2, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kDefaultLength, BytesInFlight());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  // Receiving an ACK for packet1 20s later shouldn't update the RTT, and
-  // shouldn't be treated as spurious retransmission.
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, kDefaultLength, _, _, _))
-      .WillOnce(testing::WithArg<3>(
-          Invoke([](const AckedPacketVector& acked_packets) {
-            EXPECT_EQ(1u, acked_packets.size());
-            EXPECT_EQ(QuicPacketNumber(1), acked_packets[0].packet_number);
-            // The bytes in packet1 shouldn't contribute to congestion control.
-            EXPECT_EQ(0u, acked_packets[0].bytes_acked);
-          })));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
-  // Receiving an ACK for packet2 should update RTT and congestion control.
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _))
-      .WillOnce(testing::WithArg<3>(
-          Invoke([](const AckedPacketVector& acked_packets) {
-            EXPECT_EQ(1u, acked_packets.size());
-            EXPECT_EQ(QuicPacketNumber(2), acked_packets[0].packet_number);
-            // The bytes in packet2 should contribute to congestion control.
-            EXPECT_EQ(kDefaultLength, acked_packets[0].bytes_acked);
-          })));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(0u, BytesInFlight());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-            manager_.GetRttStats()->latest_rtt());
-
-  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
-  // Trigger loss timeout and mark packet3 for retransmission.
-  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
-      .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
-        packet_lost->emplace_back(QuicPacketNumber(3u), kDefaultLength);
-        return LossDetectionInterface::DetectionStats();
-      })));
-  EXPECT_CALL(notifier_, OnFrameLost(_));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(false, kDefaultLength, _, _, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(0u, BytesInFlight());
-
-  // Migrate again with unACK'ed but not in-flight packet.
-  // Packet3 shouldn't be marked for retransmission again as it is not in
-  // flight.
-  old_send_algorithm =
-      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
-
-  EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
-  EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
-            manager_.GetSendAlgorithm()->GetCongestionControlType());
-  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
-  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
-  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
-  EXPECT_EQ(0u, BytesInFlight());
-  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
-  manager_.SetSendAlgorithm(old_send_algorithm.release());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
-  // Receiving an ACK for packet3 shouldn't update RTT. Though packet 3 was
-  // marked lost, this spurious retransmission shouldn't be reported to the loss
-  // algorithm.
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(0u, BytesInFlight());
-  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
-  SendDataPacket(4, ENCRYPTION_FORWARD_SECURE);
-  // Trigger loss timeout and mark packet4 for retransmission.
-  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
-      .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
-      .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
-        packet_lost->emplace_back(QuicPacketNumber(4u), kDefaultLength);
-        return LossDetectionInterface::DetectionStats();
-      })));
-  EXPECT_CALL(notifier_, OnFrameLost(_));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(false, kDefaultLength, _, _, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(0u, BytesInFlight());
-
-  // Application retransmit the data as LOSS_RETRANSMISSION.
-  RetransmitDataPacket(5, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(kDefaultLength, BytesInFlight());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
-  // Receiving an ACK for packet4 should update RTT, but not bytes in flight.
-  // This spurious retransmission should be reported to the loss algorithm.
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(kDefaultLength, BytesInFlight());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30),
-            manager_.GetRttStats()->latest_rtt());
-
-  // Migrate again with in-flight packet5 whose retransmittable frames are all
-  // ACKed. Packet5 should be marked for retransmission but nothing to
-  // retransmit.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillOnce(Return(false));
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(0u);
-  old_send_algorithm =
-      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
-  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
-  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
-  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
-  EXPECT_EQ(0u, BytesInFlight());
-  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-
-  manager_.SetSendAlgorithm(old_send_algorithm.release());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  // Receiving an ACK for packet5 shouldn't update RTT. Though packet 5 was
-  // marked for retransmission, this spurious retransmission shouldn't be
-  // reported to the loss algorithm.
-  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
-  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(0u, BytesInFlight());
-  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
-}
-
-TEST_F(QuicSentPacketManagerTest, PathMtuIncreased) {
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, BytesInFlight(), QuicPacketNumber(1), _, _));
-  SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
-                          nullptr, kDefaultLength + 100, false, false);
-  manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, true);
-
-  // Ack the large packet and expect the path MTU to increase.
-  ExpectAck(1);
-  EXPECT_CALL(*network_change_visitor_,
-              OnPathMtuIncreased(kDefaultLength + 100));
-  QuicAckFrame ack_frame = InitAckFrame(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, OnAckRangeSlowPath) {
-  // Send packets 1 - 20.
-  for (size_t i = 1; i <= 20; ++i) {
-    SendDataPacket(i);
-  }
-  // Ack [5, 7), [10, 12), [15, 17).
-  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
-  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
-  ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
-                      ABSL_ARRAYSIZE(lost1));
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
-  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
-  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
-  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
-  // Make sure empty range does not harm.
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // Ack [4, 8), [9, 13), [14, 21).
-  uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
-  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21));
-  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, TolerateReneging) {
-  // Send packets 1 - 20.
-  for (size_t i = 1; i <= 20; ++i) {
-    SendDataPacket(i);
-  }
-  // Ack [5, 7), [10, 12), [15, 17).
-  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
-  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
-  ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
-                      ABSL_ARRAYSIZE(lost1));
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
-  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
-  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
-  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // Making sure reneged ACK does not harm. Ack [4, 8), [9, 13).
-  uint64_t acked2[] = {4, 7, 9, 12};
-  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(12), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicPacketNumber(16), manager_.GetLargestObserved());
-}
-
-TEST_F(QuicSentPacketManagerTest, MultiplePacketNumberSpaces) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  const QuicUnackedPacketMap* unacked_packets =
-      QuicSentPacketManagerPeer::GetUnackedPacketMap(&manager_);
-  EXPECT_FALSE(
-      unacked_packets
-          ->GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
-          .IsInitialized());
-  EXPECT_FALSE(
-      manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL).IsInitialized());
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_FALSE(
-      unacked_packets
-          ->GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
-          .IsInitialized());
-  // Ack packet 1.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicPacketNumber(1),
-            manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL));
-  EXPECT_FALSE(
-      manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE).IsInitialized());
-  // Send packets 2 and 3.
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_EQ(QuicPacketNumber(3),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                HANDSHAKE_DATA));
-  EXPECT_FALSE(
-      unacked_packets
-          ->GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
-          .IsInitialized());
-  // Ack packet 2.
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_HANDSHAKE));
-  EXPECT_EQ(QuicPacketNumber(2),
-            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
-  EXPECT_FALSE(
-      manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
-  // Ack packet 3.
-  ExpectAck(3);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_HANDSHAKE));
-  EXPECT_EQ(QuicPacketNumber(3),
-            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
-  EXPECT_FALSE(
-      manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
-  // Send packets 4 and 5.
-  SendDataPacket(4, ENCRYPTION_ZERO_RTT);
-  SendDataPacket(5, ENCRYPTION_ZERO_RTT);
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_EQ(QuicPacketNumber(3),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                HANDSHAKE_DATA));
-  EXPECT_EQ(QuicPacketNumber(5),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                APPLICATION_DATA));
-  // Ack packet 5.
-  ExpectAck(5);
-  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(QuicPacketNumber(3),
-            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
-  EXPECT_EQ(QuicPacketNumber(5),
-            manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
-  EXPECT_EQ(QuicPacketNumber(5),
-            manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
-
-  // Send packets 6 - 8.
-  SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
-  SendDataPacket(7, ENCRYPTION_FORWARD_SECURE);
-  SendDataPacket(8, ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_EQ(QuicPacketNumber(3),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                HANDSHAKE_DATA));
-  EXPECT_EQ(QuicPacketNumber(8),
-            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
-                APPLICATION_DATA));
-  // Ack all packets.
-  uint64_t acked[] = {4, 6, 7, 8};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(8), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(9));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(5),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(QuicPacketNumber(3),
-            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
-  EXPECT_EQ(QuicPacketNumber(8),
-            manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
-  EXPECT_EQ(QuicPacketNumber(8),
-            manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
-}
-
-TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  // Send packets 2 and 3.
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-
-  // ACK packets 2 and 3 in the wrong packet number space.
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace2) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  // Send packets 2 and 3.
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-
-  // ACK packet 1 in the wrong packet number space.
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_HANDSHAKE));
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       ToleratePacketsGetAckedInWrongPacketNumberSpace) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  // Ack packet 1.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // Send packets 2 and 3.
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-
-  // Packet 1 gets acked in the wrong packet number space. Since packet 1 has
-  // been acked in the correct packet number space, tolerate it.
-  uint64_t acked[] = {2, 3};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_HANDSHAKE));
-}
-
-// Regression test for b/133771183.
-TEST_F(QuicSentPacketManagerTest, PacketInLimbo) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-  // Send SHLO.
-  SendCryptoPacket(1);
-  // Send data packet.
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-  // Send Ack Packet.
-  SendAckPacket(3, 1, ENCRYPTION_FORWARD_SECURE);
-  // Retransmit SHLO.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }));
-  manager_.OnRetransmissionTimeout();
-
-  // Successfully decrypt a forward secure packet.
-  manager_.SetHandshakeConfirmed();
-  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
-  // Send Ack packet.
-  SendAckPacket(5, 2, ENCRYPTION_FORWARD_SECURE);
-
-  // Retransmission alarm fires.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeRetransmitTailLossProbe();
-
-  // Received Ack of packets 1, 3 and 4.
-  uint64_t acked[] = {1, 3, 4};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  uint64_t acked2[] = {5, 6};
-  uint64_t loss[] = {2};
-  // Verify packet 2 is detected lost.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
-  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), loss,
-                      ABSL_ARRAYSIZE(loss));
-  manager_.OnAckFrameStart(QuicPacketNumber(6), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(7));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, RtoFiresNoPacketToRetransmit) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  // Send 10 packets.
-  for (size_t i = 1; i <= 10; ++i) {
-    SendDataPacket(i);
-  }
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(11, type);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(12, type);
-      })));
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(1u, stats_.rto_count);
-  EXPECT_EQ(0u, manager_.pending_timer_transmission_count());
-
-  // RTO fires again, but there is no packet to be RTO retransmitted.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(2u, stats_.rto_count);
-  // Verify a credit is raised up.
-  EXPECT_EQ(1u, manager_.pending_timer_transmission_count());
-}
-
-TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
-  EnablePto(k2PTO);
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  QuicTime packet1_sent_time = clock_.Now();
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set based on sent time of packet 2.
-  QuicTime deadline = clock_.Now() + expected_pto_delay;
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    // Verify PTO is set based on left edge.
-    deadline = packet1_sent_time + expected_pto_delay;
-  }
-  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
-  EXPECT_EQ(0u, stats_.pto_count);
-
-  // Invoke PTO.
-  clock_.AdvanceTime(deadline - clock_.Now());
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-  EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
-
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-          return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-        })));
-  } else {
-    // Verify two probe packets get sent.
-    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-        .Times(2)
-        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-          return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-        })))
-        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-          return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
-        })));
-  }
-  manager_.MaybeSendProbePackets();
-  // Verify PTO period gets set to twice the current value.
-  QuicTime sent_time = clock_.Now();
-  EXPECT_EQ(sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Received ACK for packets 1 and 2.
-  uint64_t acked[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-  expected_pto_delay =
-      rtt_stats->SmoothedOrInitialRtt() +
-      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
-               QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-  // Verify PTO is correctly re-armed based on sent time of packet 4.
-  EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
-  EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
-}
-
-TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
-  EnablePto(k1PTO);
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  QuicTime packet1_sent_time = clock_.Now();
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-  // Verify PTO period is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  QuicTime deadline = clock_.Now() + expected_pto_delay;
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    // Verify PTO is set based on left edge.
-    deadline = packet1_sent_time + expected_pto_delay;
-  }
-  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
-
-  // Invoke PTO.
-  clock_.AdvanceTime(deadline - clock_.Now());
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-
-  // Verify one probe packet gets sent.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-}
-
-TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeClient) {
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  // Send CHLO.
-  SendCryptoPacket(1);
-  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
-  // Ack packet 1.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(0u, manager_.GetBytesInFlight());
-  // Verify retransmission timeout is not zero because handshake is not
-  // confirmed although there is no in flight packet.
-  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
-  // Fire PTO.
-  EXPECT_EQ(QuicSentPacketManager::PTO_MODE,
-            manager_.OnRetransmissionTimeout());
-  // Send handshake packet.
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  // Ack packet 2.
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_HANDSHAKE));
-  // Verify retransmission timeout is zero because server has successfully
-  // processed HANDSHAKE packet.
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeServer) {
-  manager_.EnableIetfPtoAndLossDetection();
-  // Send SHLO.
-  SendCryptoPacket(1);
-  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
-  // Ack packet 1.
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(0u, manager_.GetBytesInFlight());
-  // Verify retransmission timeout is not set on server side because there is
-  // nothing in flight.
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, PtoTimeoutIncludesMaxAckDelay) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EnablePto(k1PTO);
-  // Use PTOS and PTOA.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPTOA);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  QuicTime packet1_sent_time = clock_.Now();
-  // Verify PTO is correctly set and ack delay is included.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set based on sent time of packet 2 but ack delay is
-  // not included as an immediate ACK is expected.
-  expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
-                                                kDefaultDelayedAckTimeMs);
-  QuicTime deadline = clock_.Now() + expected_pto_delay;
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    deadline = packet1_sent_time + expected_pto_delay;
-  }
-  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
-  EXPECT_EQ(0u, stats_.pto_count);
-
-  // Invoke PTO.
-  clock_.AdvanceTime(deadline - clock_.Now());
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-
-  // Verify 1 probe packets get sent and packet number gets skipped.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify PTO period gets set to twice the current value. Also, ack delay is
-  // not included.
-  QuicTime sent_time = clock_.Now();
-  EXPECT_EQ(sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Received ACK for packets 1 and 2.
-  uint64_t acked[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-  expected_pto_delay =
-      rtt_stats->SmoothedOrInitialRtt() +
-      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
-               QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-  // Verify PTO is correctly re-armed based on sent time of packet 4. Because of
-  // PTOS turns out to be spurious, ACK delay is included.
-  EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
-
-  // Received ACK for packets 4.
-  ExpectAck(4);
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
-                                   ENCRYPTION_FORWARD_SECURE));
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-  // Send more packets, such that peer will do ack decimation.
-  std::vector<uint64_t> acked2;
-  for (size_t i = 5; i <= 100; ++i) {
-    SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
-    acked2.push_back(i);
-  }
-  // Received ACK for all sent packets.
-  ExpectAcksAndLosses(true, &acked2[0], acked2.size(), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(100), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(101));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(100),
-                                   ENCRYPTION_FORWARD_SECURE));
-
-  expected_pto_delay =
-      rtt_stats->SmoothedOrInitialRtt() +
-      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
-               QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  for (size_t i = 101; i < 110; i++) {
-    SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
-    // Verify PTO timeout includes ACK delay as there are less than 10 packets
-    // outstanding.
-    EXPECT_EQ(clock_.Now() + expected_pto_delay,
-              manager_.GetRetransmissionTime());
-  }
-  expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
-                                                kDefaultDelayedAckTimeMs);
-  SendDataPacket(110, ENCRYPTION_FORWARD_SECURE);
-  // Verify ACK delay is excluded.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, StartExponentialBackoffSince2ndPto) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EnablePto(k2PTO);
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPEB2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  QuicTime packet1_sent_time = clock_.Now();
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set based on sent time of packet 2.
-  QuicTime deadline = clock_.Now() + expected_pto_delay;
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    // Verify PTO is set based on left edge.
-    deadline = packet1_sent_time + expected_pto_delay;
-  }
-  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
-  EXPECT_EQ(0u, stats_.pto_count);
-
-  // Invoke PTO.
-  clock_.AdvanceTime(deadline - clock_.Now());
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-
-  // Verify two probe packets get sent.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify no exponential backoff.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke 2nd PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(2u, stats_.pto_count);
-
-  // Verify two probe packets get sent.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify still no exponential backoff.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke 3rd PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(3u, stats_.pto_count);
-
-  // Verify two probe packets get sent.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(7, type, ENCRYPTION_FORWARD_SECURE);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(8, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify exponential backoff starts.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Invoke 4th PTO.
-  clock_.AdvanceTime(expected_pto_delay * 2);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(4u, stats_.pto_count);
-
-  // Verify two probe packets get sent.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .Times(2)
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(9, type, ENCRYPTION_FORWARD_SECURE);
-      })))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(10, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify exponential backoff continues.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, PtoTimeoutRttVarMultiple) {
-  EnablePto(k1PTO);
-  // Use 2 * rttvar
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPVS1);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set based on 2 times rtt var.
-  QuicTime::Delta expected_pto_delay =
-      srtt + 2 * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-// Regression test for b/143962153
-TEST_F(QuicSentPacketManagerTest, RtoNotInFlightPacket) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-  // Send SHLO.
-  QuicStreamFrame crypto_frame(1, false, 0, absl::string_view());
-  SendCryptoPacket(1);
-  // Send data packet.
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-
-  // Successfully decrypt a forward secure packet.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
-  manager_.SetHandshakeConfirmed();
-
-  // 1st TLP.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeRetransmitTailLossProbe();
-
-  // 2nd TLP.
-  manager_.OnRetransmissionTimeout();
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeRetransmitTailLossProbe();
-
-  // RTO retransmits SHLO although it is not in flight.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<0>(Invoke([&crypto_frame](const QuicFrames& frames) {
-        EXPECT_EQ(1u, frames.size());
-        EXPECT_NE(crypto_frame, frames[0].stream_frame);
-        return true;
-      })));
-  manager_.OnRetransmissionTimeout();
-}
-
-TEST_F(QuicSentPacketManagerTest, Aggressive1Pto) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EnablePto(k1PTO);
-  // Let the first PTO be aggressive.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPAG1);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay = 2 * srtt;
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-
-  // Verify 1 probe packets get sent and packet number gets skipped.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-
-  // Verify PTO period gets set correctly.
-  QuicTime sent_time = clock_.Now();
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, Aggressive2Ptos) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EnablePto(k1PTO);
-  // Let the first PTO be aggressive.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPAG2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay = 2 * srtt;
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-
-  // Verify 1 probe packets get sent and packet number gets skipped.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-
-  // Verify PTO period gets set correctly.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke 2nd PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(2u, stats_.pto_count);
-
-  // Verify 1 probe packets get sent and packet number gets skipped.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-  // Verify PTO period gets set correctly.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, IW10ForUpAndDown) {
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kBWS5);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*send_algorithm_, SetInitialCongestionWindowInPackets(10));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_EQ(10u, manager_.initial_congestion_window());
-}
-
-TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EnablePto(k1PTO);
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::Zero();
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard initial key and send packet 2 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.NeuterUnencryptedPackets();
-
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  // Verify PTO is correctly set based on sent time of packet 2.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-  EXPECT_EQ(1u, stats_.crypto_retransmit_count);
-
-  // Verify probe packet gets sent.
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_HANDSHAKE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify PTO period gets set to twice the current value.
-  const QuicTime packet3_sent_time = clock_.Now();
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 4 in application data with 0-RTT.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(4, ENCRYPTION_ZERO_RTT);
-  const QuicTime packet4_sent_time = clock_.Now();
-  // Verify PTO timeout is still based on packet 3.
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 5 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(5, ENCRYPTION_HANDSHAKE);
-  const QuicTime packet5_sent_time = clock_.Now();
-  // Verify PTO timeout is now based on packet 5 because packet 4 should be
-  // ignored.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 6 in 1-RTT.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO timeout is now based on packet 5.
-  EXPECT_EQ(packet5_sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 7 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  const QuicTime packet7_sent_time = clock_.Now();
-  SendDataPacket(7, ENCRYPTION_HANDSHAKE);
-
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation();
-  // Verify PTO timeout is now based on packet 7.
-  EXPECT_EQ(packet7_sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Neuter handshake key.
-  manager_.SetHandshakeConfirmed();
-  // Forward progress has been made, verify PTO counter gets reset. PTO timeout
-  // is armed by left edge.
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(packet4_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EnablePto(k1PTO);
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  const QuicTime packet1_sent_time = clock_.Now();
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::Zero();
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 2 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  const QuicTime packet2_sent_time = clock_.Now();
-  // Verify PTO timeout is still based on packet 1.
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard initial keys.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.NeuterUnencryptedPackets();
-
-  // Send packet 3 in 1-RTT.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO timeout is based on packet 2.
-  const QuicTime packet3_sent_time = clock_.Now();
-  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 4 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
-  // Verify PTO timeout is based on packet 4 as application data is ignored.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard handshake keys.
-  manager_.SetHandshakeConfirmed();
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  // Verify PTO timeout is now based on packet 3 as handshake is
-  // complete/confirmed.
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
-  EnablePto(k1PTO);
-  // Use PTOS and PLE1.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPLE1);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  const QuicTime packet1_sent_time = clock_.Now();
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is still based on packet 1.
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-  EXPECT_EQ(0u, stats_.pto_count);
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify PTO period gets set to twice the current value and based on packet3.
-  QuicTime packet3_sent_time = clock_.Now();
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Received ACK for packets 1 and 2.
-  uint64_t acked[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-  expected_pto_delay =
-      rtt_stats->SmoothedOrInitialRtt() +
-      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
-               QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-  // Verify PTO is correctly re-armed based on sent time of packet 4.
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
-  EnablePto(k1PTO);
-  // Use PTOS and PLE2.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPLE2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  const QuicTime packet1_sent_time = clock_.Now();
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Sent a packet 10ms before PTO expiring.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
-      expected_pto_delay.ToMilliseconds() - 10));
-  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO expands to packet 2 sent time + 1.5 * srtt.
-  expected_pto_delay = 1.5 * rtt_stats->smoothed_rtt();
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-  EXPECT_EQ(0u, stats_.pto_count);
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
-  EXPECT_EQ(1u, stats_.pto_count);
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
-      })));
-  manager_.MaybeSendProbePackets();
-  // Verify PTO period gets set to twice the expected value and based on
-  // packet3 (right edge).
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  QuicTime packet3_sent_time = clock_.Now();
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
-            manager_.GetRetransmissionTime());
-
-  // Received ACK for packets 1 and 2.
-  uint64_t acked[] = {1, 2};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-  expected_pto_delay =
-      rtt_stats->SmoothedOrInitialRtt() +
-      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
-               QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-  // Verify PTO is correctly re-armed based on sent time of packet 3 (left
-  // edge).
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutUsingStandardDeviation) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  EnablePto(k1PTO);
-  // Use PTOS and PSDA.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPSDA);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(75),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO is correctly set using standard deviation.
-  QuicTime::Delta expected_pto_delay =
-      srtt +
-      GetPtoRttvarMultiplier() * rtt_stats->GetStandardOrMeanDeviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       ComputingProbeTimeoutByLeftEdgeMultiplePacketNumberSpaces) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EnablePto(k1PTO);
-  // Use PTOS and PLE1.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPLE1);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  const QuicTime packet1_sent_time = clock_.Now();
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::Zero();
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 2 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  const QuicTime packet2_sent_time = clock_.Now();
-  // Verify PTO timeout is still based on packet 1.
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard initial keys.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.NeuterUnencryptedPackets();
-
-  // Send packet 3 in 1-RTT.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO timeout is based on packet 2.
-  const QuicTime packet3_sent_time = clock_.Now();
-  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 4 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
-  // Verify PTO timeout is based on packet 4 as application data is ignored.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard handshake keys.
-  manager_.SetHandshakeConfirmed();
-  // Verify PTO timeout is now based on packet 3 as handshake is
-  // complete/confirmed.
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO timeout is still based on packet 3.
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       ComputingProbeTimeoutByLeftEdge2MultiplePacketNumberSpaces) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EnablePto(k1PTO);
-  // Use PTOS and PLE2.
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kPTOS);
-  options.push_back(kPLE2);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  const QuicTime packet1_sent_time = clock_.Now();
-  // Verify PTO is correctly set.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::Zero();
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 2 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  const QuicTime packet2_sent_time = clock_.Now();
-  // Verify PTO timeout is still based on packet 1.
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard initial keys.
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.NeuterUnencryptedPackets();
-
-  // Send packet 3 in 1-RTT.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO timeout is based on packet 2.
-  const QuicTime packet3_sent_time = clock_.Now();
-  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 4 in handshake.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
-  // Verify PTO timeout is based on packet 4 as application data is ignored.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Discard handshake keys.
-  manager_.SetHandshakeConfirmed();
-  // Verify PTO timeout is now based on packet 3 as handshake is
-  // complete/confirmed.
-  expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Send packet 5 10ms before PTO expiring.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
-      expected_pto_delay.ToMilliseconds() - 10));
-  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
-  // Verify PTO timeout expands to packet 5 sent time + 1.5 * srtt.
-  EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->smoothed_rtt(),
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, SetHandshakeConfirmed) {
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
-      .WillOnce(
-          Invoke([](const QuicFrame& /*frame*/, QuicTime::Delta ack_delay_time,
-                    QuicTime receive_timestamp) {
-            EXPECT_TRUE(ack_delay_time.IsZero());
-            EXPECT_EQ(receive_timestamp, QuicTime::Zero());
-            return true;
-          }));
-
-  EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(2))).Times(1);
-  manager_.SetHandshakeConfirmed();
-}
-
-// Regresstion test for b/148841700.
-TEST_F(QuicSentPacketManagerTest, NeuterUnencryptedPackets) {
-  SendCryptoPacket(1);
-  SendPingPacket(2, ENCRYPTION_INITIAL);
-  // Crypto data has been discarded but ping does not.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
-      .Times(2)
-      .WillOnce(Return(false))
-      .WillOnce(Return(true));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-
-  EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(1))).Times(1);
-  manager_.NeuterUnencryptedPackets();
-}
-
-TEST_F(QuicSentPacketManagerTest, MarkInitialPacketsForRetransmission) {
-  SendCryptoPacket(1);
-  SendPingPacket(2, ENCRYPTION_HANDSHAKE);
-  // Only the INITIAL packet will be retransmitted.
-  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
-  manager_.MarkInitialPacketsForRetransmission();
-}
-
-TEST_F(QuicSentPacketManagerTest, NoPacketThresholdDetectionForRuntPackets) {
-  EXPECT_TRUE(
-      QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kRUNT);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  EXPECT_FALSE(
-      QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelay) {
-  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-  // Before RTT sample is available.
-  // 2 TLPs + 2 RTOs.
-  QuicTime::Delta expected_delay = QuicTime::Delta::Zero();
-  for (size_t i = 0; i < 2; ++i) {
-    QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
-    expected_delay =
-        expected_delay +
-        QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
-  }
-  for (size_t i = 0; i < 2; ++i) {
-    QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
-    expected_delay =
-        expected_delay +
-        QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
-  }
-  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
-
-  expected_delay = QuicTime::Delta::Zero();
-  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 0);
-  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 0);
-
-  // After RTT sample is available.
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  // 2 TLPs + 2 RTOs.
-  for (size_t i = 0; i < 2; ++i) {
-    QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
-    expected_delay =
-        expected_delay +
-        QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
-  }
-  for (size_t i = 0; i < 2; ++i) {
-    QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
-    expected_delay =
-        expected_delay +
-        QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
-  }
-  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing2PTO) {
-  QuicConfig client_config;
-  QuicTagVector options;
-  options.push_back(k1PTO);
-  QuicTagVector client_options;
-  client_options.push_back(kPDP2);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  client_config.SetClientConnectionOptions(client_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(client_config);
-  EXPECT_TRUE(manager_.pto_enabled());
-  QuicTime::Delta expected_delay = 2 * manager_.GetPtoDelay();
-  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing1PTO) {
-  QuicConfig client_config;
-  QuicTagVector options;
-  options.push_back(k1PTO);
-  QuicTagVector client_options;
-  client_options.push_back(kPDP1);
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  client_config.SetConnectionOptionsToSend(options);
-  client_config.SetClientConnectionOptions(client_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(client_config);
-  EXPECT_TRUE(manager_.pto_enabled());
-  QuicTime::Delta expected_delay = 1 * manager_.GetPtoDelay();
-  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
-}
-
-TEST_F(QuicSentPacketManagerTest, ClientsIgnorePings) {
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  QuicConfig client_config;
-  QuicTagVector options;
-  QuicTagVector client_options;
-  client_options.push_back(kIGNP);
-  client_config.SetConnectionOptionsToSend(options);
-  client_config.SetClientConnectionOptions(client_options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(client_config);
-
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
-  SendPingPacket(1, ENCRYPTION_INITIAL);
-  // Verify PING only packet is not considered in flight.
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-  SendDataPacket(2, ENCRYPTION_INITIAL);
-  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
-
-  uint64_t acked[] = {1};
-  ExpectAcksAndLosses(/*rtt_updated=*/false, acked, ABSL_ARRAYSIZE(acked),
-                      nullptr, 0);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  // Verify no RTT samples for PING only packet.
-  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
-
-  ExpectAck(2);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
-}
-
-// Regression test for b/154050235.
-TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kInitialRttMs),
-            rtt_stats->initial_rtt());
-  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
-
-  SendCryptoPacket(1);
-  QuicTime::Delta expected_pto_delay =
-      QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
-  manager_.MaybeSendProbePackets();
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    manager_.AdjustPendingTimerTransmissions();
-  }
-  // Verify exponential backoff of the PTO timeout.
-  EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  // Assume client provided a tiny initial RTT.
-  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMicroseconds(1));
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1), rtt_stats->initial_rtt());
-  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
-
-  SendCryptoPacket(1);
-  QuicTime::Delta expected_pto_delay = QuicTime::Delta::FromMilliseconds(10);
-  // Verify kMinHandshakeTimeoutMs is respected.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(
-          WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
-  manager_.MaybeSendProbePackets();
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    manager_.AdjustPendingTimerTransmissions();
-  }
-  // Verify exponential backoff of the PTO timeout.
-  EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, HandshakeAckCausesInitialKeyDropping) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
-  // Send INITIAL packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  QuicTime::Delta expected_pto_delay =
-      QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-  // Send HANDSHAKE ack.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendAckPacket(2, /*largest_acked=*/1, ENCRYPTION_HANDSHAKE);
-  // Sending HANDSHAKE packet causes dropping of INITIAL key.
-  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  manager_.NeuterUnencryptedPackets();
-  // There is no in flight packets.
-  EXPECT_FALSE(manager_.HasInFlightPackets());
-  // Verify PTO timer gets rearmed from now because of anti-amplification.
-  EXPECT_EQ(clock_.Now() + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Invoke PTO.
-  clock_.AdvanceTime(expected_pto_delay);
-  manager_.OnRetransmissionTimeout();
-  // Verify nothing to probe (and connection will send PING for current
-  // encryption level).
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
-  manager_.MaybeSendProbePackets();
-}
-
-// Regression test for b/156487311
-TEST_F(QuicSentPacketManagerTest, ClearLastInflightPacketsSentTime) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
-  // Send INITIAL 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  // Send HANDSHAKE 2.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
-  const QuicTime packet2_sent_time = clock_.Now();
-
-  // Send half RTT 5.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
-
-  // Received ACK for INITIAL 1.
-  ExpectAck(1);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  const QuicTime::Delta pto_delay =
-      rtt_stats->smoothed_rtt() +
-      GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::Zero();
-  // Verify PTO is armed based on handshake data.
-  EXPECT_EQ(packet2_sent_time + pto_delay, manager_.GetRetransmissionTime());
-}
-
-// Regression test for b/157895910.
-TEST_F(QuicSentPacketManagerTest, EarliestSentTimeNotInitializedWhenPtoFires) {
-  if (GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm)) {
-    return;
-  }
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
-  // Send INITIAL 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-
-  // Send HANDSHAKE packets.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
-
-  // Send half RTT packet.
-  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
-
-  // Received ACK for INITIAL packet 1.
-  ExpectAck(1);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-
-  // Received ACK for HANDSHAKE packets.
-  uint64_t acked[] = {2, 3, 4};
-  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(5));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
-                                   ENCRYPTION_HANDSHAKE));
-  // Verify PTO will not be armed.
-  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
-                       QuicTime::Delta::Zero(), QuicTime::Zero());
-  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
-  // Send packet 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  QuicTime packet1_sent_time = clock_.Now();
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  // Send packets 2 and 3.
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-  QuicTime packet2_sent_time = clock_.Now();
-  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
-  // Verify PTO is correctly set based on packet 1.
-  QuicTime::Delta expected_pto_delay =
-      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
-      QuicTime::Delta::Zero();
-  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Assume connection is going to send INITIAL ACK.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(4, type, ENCRYPTION_INITIAL);
-      })));
-  manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
-  // Verify PTO is re-armed based on packet 2.
-  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-
-  // Connection is going to send another INITIAL ACK.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
-      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
-        return RetransmitDataPacket(5, type, ENCRYPTION_INITIAL);
-      })));
-  manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
-  // Verify PTO does not change.
-  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       AggressivePtoBeforeAnyRttSamplesAreAvailable) {
-  if (GetQuicRestartFlag(quic_default_on_pto2)) {
-    return;
-  }
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  EXPECT_CALL(*send_algorithm_, PacingRate(_))
-      .WillRepeatedly(Return(QuicBandwidth::Zero()));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kAPTO);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  manager_.SetFromConfig(config);
-
-  // Send INITIAL 1.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  // Verify retransmission timeout is expected.
-  EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(),
-            manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, SendPathChallengeAndGetAck) {
-  QuicPacketNumber packet_number(1);
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, BytesInFlight(), packet_number, _, _));
-  SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER, nullptr,
-                          kDefaultLength, false, false);
-  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  packet.nonretransmittable_frames.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
-  packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                        NO_RETRANSMITTABLE_DATA, false);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, _, _,
-                                Pointwise(PacketNumberEq(), {1}), IsEmpty()));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-
-  // Get ACK for the packet.
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_FORWARD_SECURE));
-}
-
-SerializedPacket MakePacketWithAckFrequencyFrame(
-    int packet_number, int ack_frequency_sequence_number,
-    QuicTime::Delta max_ack_delay) {
-  auto* ack_frequency_frame = new QuicAckFrequencyFrame();
-  ack_frequency_frame->max_ack_delay = max_ack_delay;
-  ack_frequency_frame->sequence_number = ack_frequency_sequence_number;
-  SerializedPacket packet(QuicPacketNumber(packet_number),
-                          PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                          /*has_ack=*/false,
-                          /*has_stop_waiting=*/false);
-  packet.retransmittable_frames.push_back(QuicFrame(ack_frequency_frame));
-  packet.has_ack_frequency = true;
-  packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  return packet;
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       PeerMaxAckDelayUpdatedFromAckFrequencyFrameOneAtATime) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
-      .Times(AnyNumber());
-
-  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
-  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
-  auto plus_1_ms_delay = initial_peer_max_ack_delay + one_ms;
-  auto minus_1_ms_delay = initial_peer_max_ack_delay - one_ms;
-
-  // Send and Ack frame1.
-  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1,
-      plus_1_ms_delay);
-  // Higher on the fly max_ack_delay changes peer_max_ack_delay.
-  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
-
-  // Send and Ack frame2.
-  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2,
-      minus_1_ms_delay);
-  // Lower on the fly max_ack_delay does not change peer_max_ack_delay.
-  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), minus_1_ms_delay);
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       PeerMaxAckDelayUpdatedFromInOrderAckFrequencyFrames) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
-      .Times(AnyNumber());
-
-  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
-  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
-  auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
-  auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
-  auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
-  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_1_ms);
-  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
-  SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
-
-  // Send frame1, farme2, frame3.
-  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
-  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
-  manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
-
-  // Ack frame1, farme2, frame3.
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
-}
-
-TEST_F(QuicSentPacketManagerTest,
-       PeerMaxAckDelayUpdatedFromOutOfOrderAckedAckFrequencyFrames) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
-      .Times(AnyNumber());
-
-  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
-  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
-  auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
-  auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
-  auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
-  auto extra_4_ms = initial_peer_max_ack_delay + 4 * one_ms;
-  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_4_ms);
-  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
-  SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
-  SerializedPacket packet4 = MakePacketWithAckFrequencyFrame(
-      /*packet_number=*/4, /*ack_frequency_sequence_number=*/4, extra_1_ms);
-
-  // Send frame1, farme2, frame3, frame4.
-  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  manager_.OnPacketSent(&packet4, clock_.Now(), NOT_RETRANSMISSION,
-                        NO_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_4_ms);
-
-  // Ack frame3.
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
-  // Acking frame1 do not affect peer_max_ack_delay after frame3 is acked.
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
-  // Acking frame2 do not affect peer_max_ack_delay after frame3 is acked.
-  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
-  // Acking frame4 updates peer_max_ack_delay.
-  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(5));
-  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                         ENCRYPTION_FORWARD_SECURE);
-  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
-}
-
-TEST_F(QuicSentPacketManagerTest, ClearDataInMessageFrameAfterPacketSent) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-
-  QuicMessageFrame* message_frame = nullptr;
-  {
-    quiche::QuicheMemSlice slice(quiche::QuicheBuffer(&allocator_, 1024));
-    message_frame = new QuicMessageFrame(/*message_id=*/1, std::move(slice));
-    EXPECT_FALSE(message_frame->message_data.empty());
-    EXPECT_EQ(message_frame->message_length, 1024);
-
-    SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
-                            /*encrypted_buffer=*/nullptr, kDefaultLength,
-                            /*has_ack=*/false,
-                            /*has_stop_waiting*/ false);
-    packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
-    packet.retransmittable_frames.push_back(QuicFrame(message_frame));
-    packet.has_message = true;
-    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
-  }
-
-  EXPECT_TRUE(message_frame->message_data.empty());
-  EXPECT_EQ(message_frame->message_length, 0);
-}
-
-TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrame) {
-  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
-  manager_.SetFromConfig(config);
-  manager_.SetHandshakeConfirmed();
-
-  // Set up RTTs.
-  auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
-                       /*ack_delay=*/QuicTime::Delta::Zero(),
-                       /*now=*/QuicTime::Zero());
-  // Make sure srtt and min_rtt are different.
-  rtt_stats->UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(160),
-      /*ack_delay=*/QuicTime::Delta::Zero(),
-      /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
-
-  auto frame = manager_.GetUpdatedAckFrequencyFrame();
-  EXPECT_EQ(frame.max_ack_delay,
-            std::max(rtt_stats->min_rtt() * 0.25,
-                     QuicTime::Delta::FromMilliseconds(1u)));
-  EXPECT_EQ(frame.packet_tolerance, 10u);
-}
-
-TEST_F(QuicSentPacketManagerTest, SmoothedRttIgnoreAckDelay) {
-  QuicConfig config;
-  QuicTagVector options;
-  options.push_back(kMAD0);
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-  manager_.SetFromConfig(config);
-
-  SendDataPacket(1);
-  // Ack 1.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1),
-                           QuicTime::Delta::FromMilliseconds(100),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  // Verify that ack_delay is ignored in the first measurement.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
-            manager_.GetRttStats()->latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
-            manager_.GetRttStats()->smoothed_rtt());
-
-  SendDataPacket(2);
-  // Ack 2.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2),
-                           QuicTime::Delta::FromMilliseconds(100),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
-            manager_.GetRttStats()->latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
-            manager_.GetRttStats()->smoothed_rtt());
-
-  SendDataPacket(3);
-  // Ack 3.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
-  ExpectAck(3);
-  manager_.OnAckFrameStart(QuicPacketNumber(3),
-                           QuicTime::Delta::FromMilliseconds(50), clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
-            manager_.GetRttStats()->latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
-            manager_.GetRttStats()->smoothed_rtt());
-
-  SendDataPacket(4);
-  // Ack 4.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
-  ExpectAck(4);
-  manager_.OnAckFrameStart(QuicPacketNumber(4),
-                           QuicTime::Delta::FromMilliseconds(300),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
-                                   ENCRYPTION_INITIAL));
-  // Verify that large erroneous ack_delay does not change Smoothed RTT.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
-            manager_.GetRttStats()->latest_rtt());
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
-            manager_.GetRttStats()->smoothed_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, IgnorePeerMaxAckDelayDuringHandshake) {
-  manager_.EnableMultiplePacketNumberSpacesSupport();
-  // 100ms RTT.
-  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(100);
-
-  // Server sends INITIAL 1 and HANDSHAKE 2.
-  SendDataPacket(1, ENCRYPTION_INITIAL);
-  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
-
-  // Receive client ACK for INITIAL 1 after one RTT.
-  clock_.AdvanceTime(kTestRTT);
-  ExpectAck(1);
-  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
-                           clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
-                                   ENCRYPTION_INITIAL));
-  EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
-
-  // Assume the cert verification on client takes 50ms, such that the HANDSHAKE
-  // packet is queued for 50ms.
-  const QuicTime::Delta queuing_delay = QuicTime::Delta::FromMilliseconds(50);
-  clock_.AdvanceTime(queuing_delay);
-  // Ack 2.
-  ExpectAck(2);
-  manager_.OnAckFrameStart(QuicPacketNumber(2), queuing_delay, clock_.Now());
-  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
-  EXPECT_EQ(PACKETS_NEWLY_ACKED,
-            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
-                                   ENCRYPTION_HANDSHAKE));
-  EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
-}
-
-TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrameWithSRTT) {
-  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
-  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
-  QuicConfig config;
-  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
-  QuicTagVector quic_tag_vector;
-  quic_tag_vector.push_back(kAFF1);  // SRTT enabling tag.
-  QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
-  manager_.SetFromConfig(config);
-  manager_.SetHandshakeConfirmed();
-
-  // Set up RTTs.
-  auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
-                       /*ack_delay=*/QuicTime::Delta::Zero(),
-                       /*now=*/QuicTime::Zero());
-  // Make sure srtt and min_rtt are different.
-  rtt_stats->UpdateRtt(
-      QuicTime::Delta::FromMilliseconds(160),
-      /*ack_delay=*/QuicTime::Delta::Zero(),
-      /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
-
-  auto frame = manager_.GetUpdatedAckFrequencyFrame();
-  EXPECT_EQ(frame.max_ack_delay,
-            std::max(rtt_stats->SmoothedOrInitialRtt() * 0.25,
-                     QuicTime::Delta::FromMilliseconds(1u)));
-}
-
-TEST_F(QuicSentPacketManagerTest, SetInitialRtt) {
-  // Upper bounds.
-  manager_.SetInitialRtt(
-      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs + 1), false);
-  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
-            kMaxInitialRoundTripTimeUs);
-
-  manager_.SetInitialRtt(
-      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs + 1), true);
-  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
-            kMaxInitialRoundTripTimeUs);
-
-  EXPECT_GT(kMinUntrustedInitialRoundTripTimeUs,
-            kMinTrustedInitialRoundTripTimeUs);
-
-  // Lower bounds for untrusted rtt.
-  manager_.SetInitialRtt(QuicTime::Delta::FromMicroseconds(
-                             kMinUntrustedInitialRoundTripTimeUs - 1),
-                         false);
-  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
-            kMinUntrustedInitialRoundTripTimeUs);
-
-  // Lower bounds for trusted rtt.
-  manager_.SetInitialRtt(QuicTime::Delta::FromMicroseconds(
-                             kMinUntrustedInitialRoundTripTimeUs - 1),
-                         true);
-  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
-            kMinUntrustedInitialRoundTripTimeUs - 1);
-
-  manager_.SetInitialRtt(
-      QuicTime::Delta::FromMicroseconds(kMinTrustedInitialRoundTripTimeUs - 1),
-      true);
-  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
-            kMinTrustedInitialRoundTripTimeUs);
-}
-
-TEST_F(QuicSentPacketManagerTest, GetAvailableCongestionWindow) {
-  SendDataPacket(1);
-  EXPECT_EQ(kDefaultLength, manager_.GetBytesInFlight());
-
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillOnce(Return(kDefaultLength + 10));
-  EXPECT_EQ(10u, manager_.GetAvailableCongestionWindowInBytes());
-
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillOnce(Return(kDefaultLength));
-  EXPECT_EQ(0u, manager_.GetAvailableCongestionWindowInBytes());
-
-  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
-      .WillOnce(Return(kDefaultLength - 10));
-  EXPECT_EQ(0u, manager_.GetAvailableCongestionWindowInBytes());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_server_id.cc b/quic/core/quic_server_id.cc
deleted file mode 100644
index 0c03451..0000000
--- a/quic/core/quic_server_id.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_server_id.h"
-
-#include <string>
-#include <tuple>
-
-namespace quic {
-
-QuicServerId::QuicServerId() : QuicServerId("", 0, false) {}
-
-QuicServerId::QuicServerId(const std::string& host, uint16_t port)
-    : QuicServerId(host, port, false) {}
-
-QuicServerId::QuicServerId(const std::string& host,
-                           uint16_t port,
-                           bool privacy_mode_enabled)
-    : host_(host), port_(port), privacy_mode_enabled_(privacy_mode_enabled) {}
-
-QuicServerId::~QuicServerId() {}
-
-bool QuicServerId::operator<(const QuicServerId& other) const {
-  return std::tie(port_, host_, privacy_mode_enabled_) <
-         std::tie(other.port_, other.host_, other.privacy_mode_enabled_);
-}
-
-bool QuicServerId::operator==(const QuicServerId& other) const {
-  return privacy_mode_enabled_ == other.privacy_mode_enabled_ &&
-         host_ == other.host_ && port_ == other.port_;
-}
-
-bool QuicServerId::operator!=(const QuicServerId& other) const {
-  return !(*this == other);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_server_id.h b/quic/core/quic_server_id.h
deleted file mode 100644
index 17c30db..0000000
--- a/quic/core/quic_server_id.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
-#define QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
-
-#include <cstdint>
-#include <string>
-
-#include "absl/hash/hash.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The id used to identify sessions. Includes the hostname, port, scheme and
-// privacy_mode.
-class QUIC_EXPORT_PRIVATE QuicServerId {
- public:
-  QuicServerId();
-  QuicServerId(const std::string& host, uint16_t port);
-  QuicServerId(const std::string& host,
-               uint16_t port,
-               bool privacy_mode_enabled);
-  ~QuicServerId();
-
-  // Needed to be an element of an ordered container.
-  bool operator<(const QuicServerId& other) const;
-  bool operator==(const QuicServerId& other) const;
-
-  bool operator!=(const QuicServerId& other) const;
-
-  const std::string& host() const { return host_; }
-
-  uint16_t port() const { return port_; }
-
-  bool privacy_mode_enabled() const { return privacy_mode_enabled_; }
-
- private:
-  std::string host_;
-  uint16_t port_;
-  bool privacy_mode_enabled_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicServerIdHash {
- public:
-  size_t operator()(const quic::QuicServerId& server_id) const noexcept {
-    return absl::HashOf(server_id.host(), server_id.port(),
-                        server_id.privacy_mode_enabled());
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
diff --git a/quic/core/quic_server_id_test.cc b/quic/core/quic_server_id_test.cc
deleted file mode 100644
index 1ad425a..0000000
--- a/quic/core/quic_server_id_test.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_server_id.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-
-namespace {
-
-class QuicServerIdTest : public QuicTest {};
-
-TEST_F(QuicServerIdTest, Constructor) {
-  QuicServerId google_server_id("google.com", 10, false);
-  EXPECT_EQ("google.com", google_server_id.host());
-  EXPECT_EQ(10, google_server_id.port());
-  EXPECT_FALSE(google_server_id.privacy_mode_enabled());
-
-  QuicServerId private_server_id("mail.google.com", 12, true);
-  EXPECT_EQ("mail.google.com", private_server_id.host());
-  EXPECT_EQ(12, private_server_id.port());
-  EXPECT_TRUE(private_server_id.privacy_mode_enabled());
-}
-
-TEST_F(QuicServerIdTest, LessThan) {
-  QuicServerId a_10_https("a.com", 10, false);
-  QuicServerId a_11_https("a.com", 11, false);
-  QuicServerId b_10_https("b.com", 10, false);
-  QuicServerId b_11_https("b.com", 11, false);
-
-  QuicServerId a_10_https_private("a.com", 10, true);
-  QuicServerId a_11_https_private("a.com", 11, true);
-  QuicServerId b_10_https_private("b.com", 10, true);
-  QuicServerId b_11_https_private("b.com", 11, true);
-
-  // Test combinations of host, port, and privacy being same on left and
-  // right side of less than.
-  EXPECT_FALSE(a_10_https < a_10_https);
-  EXPECT_TRUE(a_10_https < a_10_https_private);
-  EXPECT_FALSE(a_10_https_private < a_10_https);
-  EXPECT_FALSE(a_10_https_private < a_10_https_private);
-
-  // Test with either host, port or https being different on left and right side
-  // of less than.
-  bool left_privacy;
-  bool right_privacy;
-  for (int i = 0; i < 4; i++) {
-    left_privacy = (i / 2 == 0);
-    right_privacy = (i % 2 == 0);
-    QuicServerId a_10_https_left_private("a.com", 10, left_privacy);
-    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
-    QuicServerId a_11_https_left_private("a.com", 11, left_privacy);
-    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
-
-    QuicServerId b_10_https_left_private("b.com", 10, left_privacy);
-    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
-    QuicServerId b_11_https_left_private("b.com", 11, left_privacy);
-    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
-
-    EXPECT_TRUE(a_10_https_left_private < a_11_https_right_private);
-    EXPECT_TRUE(a_10_https_left_private < b_10_https_right_private);
-    EXPECT_TRUE(a_10_https_left_private < b_11_https_right_private);
-    EXPECT_FALSE(a_11_https_left_private < a_10_https_right_private);
-    EXPECT_FALSE(a_11_https_left_private < b_10_https_right_private);
-    EXPECT_TRUE(a_11_https_left_private < b_11_https_right_private);
-    EXPECT_FALSE(b_10_https_left_private < a_10_https_right_private);
-    EXPECT_TRUE(b_10_https_left_private < a_11_https_right_private);
-    EXPECT_TRUE(b_10_https_left_private < b_11_https_right_private);
-    EXPECT_FALSE(b_11_https_left_private < a_10_https_right_private);
-    EXPECT_FALSE(b_11_https_left_private < a_11_https_right_private);
-    EXPECT_FALSE(b_11_https_left_private < b_10_https_right_private);
-  }
-}
-
-TEST_F(QuicServerIdTest, Equals) {
-  bool left_privacy;
-  bool right_privacy;
-  for (int i = 0; i < 2; i++) {
-    left_privacy = right_privacy = (i == 0);
-    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
-    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
-    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
-    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
-
-    EXPECT_NE(a_10_https_right_private, a_11_https_right_private);
-    EXPECT_NE(a_10_https_right_private, b_10_https_right_private);
-    EXPECT_NE(a_10_https_right_private, b_11_https_right_private);
-
-    QuicServerId new_a_10_https_left_private("a.com", 10, left_privacy);
-    QuicServerId new_a_11_https_left_private("a.com", 11, left_privacy);
-    QuicServerId new_b_10_https_left_private("b.com", 10, left_privacy);
-    QuicServerId new_b_11_https_left_private("b.com", 11, left_privacy);
-
-    EXPECT_EQ(new_a_10_https_left_private, a_10_https_right_private);
-    EXPECT_EQ(new_a_11_https_left_private, a_11_https_right_private);
-    EXPECT_EQ(new_b_10_https_left_private, b_10_https_right_private);
-    EXPECT_EQ(new_b_11_https_left_private, b_11_https_right_private);
-  }
-
-  for (int i = 0; i < 2; i++) {
-    right_privacy = (i == 0);
-    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
-    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
-    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
-    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
-
-    QuicServerId new_a_10_https_left_private("a.com", 10, false);
-
-    EXPECT_NE(new_a_10_https_left_private, a_11_https_right_private);
-    EXPECT_NE(new_a_10_https_left_private, b_10_https_right_private);
-    EXPECT_NE(new_a_10_https_left_private, b_11_https_right_private);
-  }
-  QuicServerId a_10_https_private("a.com", 10, true);
-  QuicServerId new_a_10_https_no_private("a.com", 10, false);
-  EXPECT_NE(new_a_10_https_no_private, a_10_https_private);
-}
-
-}  // namespace
-
-}  // namespace quic
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
deleted file mode 100644
index 73de6fb..0000000
--- a/quic/core/quic_session.cc
+++ /dev/null
@@ -1,2669 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_session.h"
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_context.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "common/quiche_text_utils.h"
-
-using spdy::SpdyPriority;
-
-namespace quic {
-
-namespace {
-
-class ClosedStreamsCleanUpDelegate : public QuicAlarm::Delegate {
- public:
-  explicit ClosedStreamsCleanUpDelegate(QuicSession* session)
-      : session_(session) {}
-  ClosedStreamsCleanUpDelegate(const ClosedStreamsCleanUpDelegate&) = delete;
-  ClosedStreamsCleanUpDelegate& operator=(const ClosedStreamsCleanUpDelegate&) =
-      delete;
-
-  QuicConnectionContext* GetConnectionContext() override {
-    return (session_->connection() == nullptr)
-               ? nullptr
-               : session_->connection()->context();
-  }
-
-  void OnAlarm() override { session_->CleanUpClosedStreams(); }
-
- private:
-  QuicSession* session_;
-};
-
-}  // namespace
-
-#define ENDPOINT \
-  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QuicSession::QuicSession(
-    QuicConnection* connection, Visitor* owner, const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicStreamCount num_expected_unidirectional_static_streams)
-    : QuicSession(connection, owner, config, supported_versions,
-                  num_expected_unidirectional_static_streams, nullptr) {}
-
-QuicSession::QuicSession(
-    QuicConnection* connection, Visitor* owner, const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicStreamCount num_expected_unidirectional_static_streams,
-    std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
-    : connection_(connection),
-      perspective_(connection->perspective()),
-      visitor_(owner),
-      write_blocked_streams_(connection->transport_version()),
-      config_(config),
-      stream_id_manager_(perspective(), connection->transport_version(),
-                         kDefaultMaxStreamsPerConnection,
-                         config_.GetMaxBidirectionalStreamsToSend()),
-      ietf_streamid_manager_(perspective(), connection->version(), this, 0,
-                             num_expected_unidirectional_static_streams,
-                             config_.GetMaxBidirectionalStreamsToSend(),
-                             config_.GetMaxUnidirectionalStreamsToSend() +
-                                 num_expected_unidirectional_static_streams),
-      num_draining_streams_(0),
-      num_outgoing_draining_streams_(0),
-      num_static_streams_(0),
-      num_zombie_streams_(0),
-      flow_controller_(
-          this, QuicUtils::GetInvalidStreamId(connection->transport_version()),
-          /*is_connection_flow_controller*/ true,
-          connection->version().AllowsLowFlowControlLimits()
-              ? 0
-              : kMinimumFlowControlSendWindow,
-          config_.GetInitialSessionFlowControlWindowToSend(),
-          kSessionReceiveWindowLimit, perspective() == Perspective::IS_SERVER,
-          nullptr),
-      currently_writing_stream_id_(0),
-      transport_goaway_sent_(false),
-      transport_goaway_received_(false),
-      control_frame_manager_(this),
-      last_message_id_(0),
-      datagram_queue_(this, std::move(datagram_observer)),
-      closed_streams_clean_up_alarm_(nullptr),
-      supported_versions_(supported_versions),
-      is_configured_(false),
-      was_zero_rtt_rejected_(false),
-      liveness_testing_in_progress_(false) {
-  closed_streams_clean_up_alarm_ =
-      absl::WrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
-          new ClosedStreamsCleanUpDelegate(this)));
-  if (perspective() == Perspective::IS_SERVER &&
-      connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
-    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
-  }
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    config_.SetMaxUnidirectionalStreamsToSend(
-        config_.GetMaxUnidirectionalStreamsToSend() +
-        num_expected_unidirectional_static_streams);
-  }
-}
-
-void QuicSession::Initialize() {
-  connection_->set_visitor(this);
-  connection_->SetSessionNotifier(this);
-  connection_->SetDataProducer(this);
-  connection_->SetUnackedMapInitialCapacity();
-  connection_->SetFromConfig(config_);
-  if (perspective_ == Perspective::IS_CLIENT) {
-    if (config_.HasClientRequestedIndependentOption(kAFFE, perspective_) &&
-        version().HasIetfQuicFrames()) {
-      connection_->set_can_receive_ack_frequency_frame();
-      config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
-    }
-    if (config_.HasClientRequestedIndependentOption(kNBPE, perspective_)) {
-      permutes_tls_extensions_ = false;
-    }
-  }
-
-  connection_->CreateConnectionIdManager();
-
-  // On the server side, version negotiation has been done by the dispatcher,
-  // and the server session is created with the right version.
-  if (perspective() == Perspective::IS_SERVER) {
-    connection_->OnSuccessfulVersionNegotiation();
-  }
-
-  if (QuicVersionUsesCryptoFrames(transport_version())) {
-    return;
-  }
-
-  QUICHE_DCHECK_EQ(QuicUtils::GetCryptoStreamId(transport_version()),
-                   GetMutableCryptoStream()->id());
-}
-
-QuicSession::~QuicSession() {
-  if (closed_streams_clean_up_alarm_ != nullptr) {
-    closed_streams_clean_up_alarm_->PermanentCancel();
-  }
-}
-
-PendingStream* QuicSession::PendingStreamOnStreamFrame(
-    const QuicStreamFrame& frame) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  QuicStreamId stream_id = frame.stream_id;
-
-  PendingStream* pending = GetOrCreatePendingStream(stream_id);
-
-  if (!pending) {
-    if (frame.fin) {
-      QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
-      OnFinalByteOffsetReceived(stream_id, final_byte_offset);
-    }
-    return nullptr;
-  }
-
-  pending->OnStreamFrame(frame);
-  if (!connection()->connected()) {
-    return nullptr;
-  }
-  return pending;
-}
-
-void QuicSession::MaybeProcessPendingStream(PendingStream* pending) {
-  QUICHE_DCHECK(pending != nullptr);
-  QuicStreamId stream_id = pending->id();
-  absl::optional<QuicResetStreamError> stop_sending_error_code =
-      pending->GetStopSendingErrorCode();
-  QuicStream* stream = ProcessPendingStream(pending);
-  if (stream != nullptr) {
-    // The pending stream should now be in the scope of normal streams.
-    QUICHE_DCHECK(IsClosedStream(stream_id) || IsOpenStream(stream_id))
-        << "Stream " << stream_id << " not created";
-    pending_stream_map_.erase(stream_id);
-    if (stop_sending_error_code) {
-      stream->OnStopSending(*stop_sending_error_code);
-      if (!connection()->connected()) {
-        return;
-      }
-    }
-    stream->OnStreamCreatedFromPendingStream();
-    return;
-  }
-  // At this point, none of the bytes has been successfully consumed by the
-  // application layer. We should close the pending stream even if it is
-  // bidirectionl as no application will be able to write in a bidirectional
-  // stream with zero byte as input.
-  if (pending->sequencer()->IsClosed()) {
-    ClosePendingStream(stream_id);
-  }
-}
-
-void QuicSession::PendingStreamOnWindowUpdateFrame(
-    const QuicWindowUpdateFrame& frame) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
-  if (pending) {
-    pending->OnWindowUpdateFrame(frame);
-  }
-}
-
-void QuicSession::PendingStreamOnStopSendingFrame(
-    const QuicStopSendingFrame& frame) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
-  if (pending) {
-    pending->OnStopSending(frame.error());
-  }
-}
-
-void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
-  QuicStreamId stream_id = frame.stream_id;
-  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (ShouldProcessFrameByPendingStream(STREAM_FRAME, stream_id)) {
-    PendingStream* pending = PendingStreamOnStreamFrame(frame);
-    if (pending != nullptr && ShouldProcessPendingStreamImmediately()) {
-      MaybeProcessPendingStream(pending);
-    }
-    return;
-  }
-
-  QuicStream* stream = GetOrCreateStream(stream_id);
-
-  if (!stream) {
-    // The stream no longer exists, but we may still be interested in the
-    // final stream byte offset sent by the peer. A frame with a FIN can give
-    // us this offset.
-    if (frame.fin) {
-      QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
-      OnFinalByteOffsetReceived(stream_id, final_byte_offset);
-    }
-    return;
-  }
-  stream->OnStreamFrame(frame);
-}
-
-void QuicSession::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  GetMutableCryptoStream()->OnCryptoFrame(frame);
-}
-
-void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
-  // STOP_SENDING is in IETF QUIC only.
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
-  QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
-
-  QuicStreamId stream_id = frame.stream_id;
-  // If Stream ID is invalid then close the connection.
-  // TODO(ianswett): This check is redundant to checks for IsClosedStream,
-  // but removing it requires removing multiple QUICHE_DCHECKs.
-  // TODO(ianswett): Multiple QUIC_DVLOGs could be QUIC_PEER_BUGs.
-  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Received STOP_SENDING with invalid stream_id: "
-                  << stream_id << " Closing connection";
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for an invalid stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  // If stream_id is READ_UNIDIRECTIONAL, close the connection.
-  if (QuicUtils::GetStreamType(stream_id, perspective(),
-                               IsIncomingStream(stream_id),
-                               version()) == READ_UNIDIRECTIONAL) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Received STOP_SENDING for a read-only stream_id: "
-                  << stream_id << ".";
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for a read-only stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (visitor_) {
-    visitor_->OnStopSendingReceived(frame);
-  }
-  if (ShouldProcessFrameByPendingStream(STOP_SENDING_FRAME, stream_id)) {
-    PendingStreamOnStopSendingFrame(frame);
-    return;
-  }
-
-  QuicStream* stream = GetOrCreateStream(stream_id);
-  if (!stream) {
-    // Errors are handled by GetOrCreateStream.
-    return;
-  }
-
-  stream->OnStopSending(frame.error());
-}
-
-void QuicSession::OnPacketDecrypted(EncryptionLevel level) {
-  GetMutableCryptoStream()->OnPacketDecrypted(level);
-  if (liveness_testing_in_progress_) {
-    liveness_testing_in_progress_ = false;
-    OnCanCreateNewOutgoingStream(/*unidirectional=*/false);
-  }
-}
-
-void QuicSession::OnOneRttPacketAcknowledged() {
-  GetMutableCryptoStream()->OnOneRttPacketAcknowledged();
-}
-
-void QuicSession::OnHandshakePacketSent() {
-  GetMutableCryptoStream()->OnHandshakePacketSent();
-}
-
-std::unique_ptr<QuicDecrypter>
-QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  return GetMutableCryptoStream()->AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() {
-  return GetMutableCryptoStream()->CreateCurrentOneRttEncrypter();
-}
-
-void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
-  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
-  QuicStreamId stream_id = frame.stream_id;
-
-  PendingStream* pending = GetOrCreatePendingStream(stream_id);
-
-  if (!pending) {
-    HandleRstOnValidNonexistentStream(frame);
-    return;
-  }
-
-  pending->OnRstStreamFrame(frame);
-  // At this point, none of the bytes has been consumed by the application
-  // layer. It is safe to close the pending stream even if it is bidirectionl as
-  // no application will be able to write in a bidirectional stream with zero
-  // byte as input.
-  ClosePendingStream(stream_id);
-}
-
-void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
-  QuicStreamId stream_id = frame.stream_id;
-  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version()) &&
-      QuicUtils::GetStreamType(stream_id, perspective(),
-                               IsIncomingStream(stream_id),
-                               version()) == WRITE_UNIDIRECTIONAL) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Received RESET_STREAM for a write-only stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (visitor_) {
-    visitor_->OnRstStreamReceived(frame);
-  }
-
-  if (ShouldProcessFrameByPendingStream(RST_STREAM_FRAME, stream_id)) {
-    PendingStreamOnRstStream(frame);
-    return;
-  }
-
-  QuicStream* stream = GetOrCreateStream(stream_id);
-
-  if (!stream) {
-    HandleRstOnValidNonexistentStream(frame);
-    return;  // Errors are handled by GetOrCreateStream.
-  }
-  stream->OnStreamReset(frame);
-}
-
-void QuicSession::OnGoAway(const QuicGoAwayFrame& /*frame*/) {
-  QUIC_BUG_IF(quic_bug_12435_1, version().UsesHttp3())
-      << "gQUIC GOAWAY received on version " << version();
-
-  transport_goaway_received_ = true;
-}
-
-void QuicSession::OnMessageReceived(absl::string_view message) {
-  QUIC_DVLOG(1) << ENDPOINT << "Received message of length "
-                << message.length();
-  QUIC_DVLOG(2) << ENDPOINT << "Contents of message of length "
-                << message.length() << ":" << std::endl
-                << quiche::QuicheTextUtils::HexDump(message);
-}
-
-void QuicSession::OnHandshakeDoneReceived() {
-  QUIC_DVLOG(1) << ENDPOINT << "OnHandshakeDoneReceived";
-  GetMutableCryptoStream()->OnHandshakeDoneReceived();
-}
-
-void QuicSession::OnNewTokenReceived(absl::string_view token) {
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-  GetMutableCryptoStream()->OnNewTokenReceived(token);
-}
-
-// static
-void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
-                                                ConnectionCloseSource source) {
-  if (error != QUIC_NO_ERROR) {
-    if (source == ConnectionCloseSource::FROM_SELF) {
-      QUIC_SERVER_HISTOGRAM_ENUM(
-          "quic_server_connection_close_errors", error, QUIC_LAST_ERROR,
-          "QuicErrorCode for server-closed connections.");
-    } else {
-      QUIC_SERVER_HISTOGRAM_ENUM(
-          "quic_client_connection_close_errors", error, QUIC_LAST_ERROR,
-          "QuicErrorCode for client-closed connections.");
-    }
-  }
-}
-
-void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                                     ConnectionCloseSource source) {
-  QUICHE_DCHECK(!connection_->connected());
-  if (perspective() == Perspective::IS_SERVER) {
-    RecordConnectionCloseAtServer(frame.quic_error_code, source);
-  }
-
-  if (on_closed_frame_.quic_error_code == QUIC_NO_ERROR) {
-    // Save all of the connection close information
-    on_closed_frame_ = frame;
-  }
-
-  GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
-
-  PerformActionOnActiveStreams([this, frame, source](QuicStream* stream) {
-    QuicStreamId id = stream->id();
-    stream->OnConnectionClosed(frame.quic_error_code, source);
-    auto it = stream_map_.find(id);
-    if (it != stream_map_.end()) {
-      QUIC_BUG_IF(quic_bug_12435_2, !it->second->IsZombie())
-          << ENDPOINT << "Non-zombie stream " << id
-          << " failed to close under OnConnectionClosed";
-    }
-    return true;
-  });
-
-  closed_streams_clean_up_alarm_->Cancel();
-
-  if (visitor_) {
-    visitor_->OnConnectionClosed(connection_->GetOneActiveServerConnectionId(),
-                                 frame.quic_error_code, frame.error_details,
-                                 source);
-  }
-}
-
-void QuicSession::OnWriteBlocked() {
-  if (!connection_->connected()) {
-    return;
-  }
-  if (visitor_) {
-    visitor_->OnWriteBlocked(connection_);
-  }
-}
-
-void QuicSession::OnSuccessfulVersionNegotiation(
-    const ParsedQuicVersion& /*version*/) {}
-
-void QuicSession::OnPacketReceived(const QuicSocketAddress& /*self_address*/,
-                                   const QuicSocketAddress& peer_address,
-                                   bool is_connectivity_probe) {
-  if (is_connectivity_probe && perspective() == Perspective::IS_SERVER) {
-    // Server only sends back a connectivity probe after received a
-    // connectivity probe from a new peer address.
-      connection_->SendConnectivityProbingPacket(nullptr, peer_address);
-  }
-}
-
-void QuicSession::OnPathDegrading() {}
-
-void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
-
-bool QuicSession::AllowSelfAddressChange() const { return false; }
-
-void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
-  // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
-  // assume that it still exists.
-  QuicStreamId stream_id = frame.stream_id;
-  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
-    // This is a window update that applies to the connection, rather than an
-    // individual stream.
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Received connection level flow control window "
-                     "update with max data: "
-                  << frame.max_data;
-    flow_controller_.UpdateSendWindowOffset(frame.max_data);
-    return;
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version()) &&
-      QuicUtils::GetStreamType(stream_id, perspective(),
-                               IsIncomingStream(stream_id),
-                               version()) == READ_UNIDIRECTIONAL) {
-    connection()->CloseConnection(
-        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
-        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (ShouldProcessFrameByPendingStream(WINDOW_UPDATE_FRAME, stream_id)) {
-    PendingStreamOnWindowUpdateFrame(frame);
-    return;
-  }
-
-  QuicStream* stream = GetOrCreateStream(stream_id);
-  if (stream != nullptr) {
-    stream->OnWindowUpdateFrame(frame);
-  }
-}
-
-void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
-  // TODO(rjshade): Compare our flow control receive windows for specified
-  //                streams: if we have a large window then maybe something
-  //                had gone wrong with the flow control accounting.
-  QUIC_DLOG(INFO) << ENDPOINT << "Received BLOCKED frame with stream id: "
-                  << frame.stream_id;
-}
-
-bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
-                                            uint64_t previous_bytes_written,
-                                            bool previous_fin_sent) {
-  if (  // Stream should not be closed.
-      !stream->write_side_closed() &&
-      // Not connection flow control blocked.
-      !flow_controller_.IsBlocked() &&
-      // Detect lack of forward progress.
-      previous_bytes_written == stream->stream_bytes_written() &&
-      previous_fin_sent == stream->fin_sent()) {
-    stream->set_busy_counter(stream->busy_counter() + 1);
-    QUIC_DVLOG(1) << ENDPOINT << "Suspected busy loop on stream id "
-                  << stream->id() << " stream_bytes_written "
-                  << stream->stream_bytes_written() << " fin "
-                  << stream->fin_sent() << " count " << stream->busy_counter();
-    // Wait a few iterations before firing, the exact count is
-    // arbitrary, more than a few to cover a few test-only false
-    // positives.
-    if (stream->busy_counter() > 20) {
-      QUIC_LOG(ERROR) << ENDPOINT << "Detected busy loop on stream id "
-                      << stream->id() << " stream_bytes_written "
-                      << stream->stream_bytes_written() << " fin "
-                      << stream->fin_sent();
-      return false;
-    }
-  } else {
-    stream->set_busy_counter(0);
-  }
-  return true;
-}
-
-bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const {
-  if (!stream->write_side_closed() && stream->HasBufferedData() &&
-      !stream->IsFlowControlBlocked() &&
-      !write_blocked_streams_.IsStreamBlocked(stream->id())) {
-    QUIC_DLOG(ERROR) << ENDPOINT << "stream " << stream->id()
-                     << " has buffered " << stream->BufferedDataBytes()
-                     << " bytes, and is not flow control blocked, "
-                        "but it is not in the write block list.";
-    return false;
-  }
-  return true;
-}
-
-void QuicSession::OnCanWrite() {
-  if (connection_->framer().is_processing_packet()) {
-    // Do not write data in the middle of packet processing because rest
-    // frames in the packet may change the data to write. For example, lost
-    // data could be acknowledged. Also, connection is going to emit
-    // OnCanWrite signal post packet processing.
-    QUIC_BUG(session_write_mid_packet_processing)
-        << ENDPOINT << "Try to write mid packet processing.";
-    return;
-  }
-  if (!RetransmitLostData()) {
-    // Cannot finish retransmitting lost data, connection is write blocked.
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Cannot finish retransmitting lost data, connection is "
-                     "write blocked.";
-    return;
-  }
-  // We limit the number of writes to the number of pending streams. If more
-  // streams become pending, WillingAndAbleToWrite will be true, which will
-  // cause the connection to request resumption before yielding to other
-  // connections.
-  // If we are connection level flow control blocked, then only allow the
-  // crypto and headers streams to try writing as all other streams will be
-  // blocked.
-  size_t num_writes = flow_controller_.IsBlocked()
-                          ? write_blocked_streams_.NumBlockedSpecialStreams()
-                          : write_blocked_streams_.NumBlockedStreams();
-  if (num_writes == 0 && !control_frame_manager_.WillingToWrite() &&
-      datagram_queue_.empty() &&
-      (!QuicVersionUsesCryptoFrames(transport_version()) ||
-       !GetCryptoStream()->HasBufferedCryptoFrames())) {
-    return;
-  }
-
-  QuicConnection::ScopedPacketFlusher flusher(connection_);
-  if (QuicVersionUsesCryptoFrames(transport_version())) {
-    QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
-    if (crypto_stream->HasBufferedCryptoFrames()) {
-      crypto_stream->WriteBufferedCryptoFrames();
-    }
-    if (crypto_stream->HasBufferedCryptoFrames()) {
-      // Cannot finish writing buffered crypto frames, connection is write
-      // blocked.
-      return;
-    }
-  }
-  if (control_frame_manager_.WillingToWrite()) {
-    control_frame_manager_.OnCanWrite();
-  }
-  // TODO(b/147146815): this makes all datagrams go before stream data.  We
-  // should have a better priority scheme for this.
-  if (!datagram_queue_.empty()) {
-    size_t written = datagram_queue_.SendDatagrams();
-    QUIC_DVLOG(1) << ENDPOINT << "Sent " << written << " datagrams";
-    if (!datagram_queue_.empty()) {
-      return;
-    }
-  }
-  std::vector<QuicStreamId> last_writing_stream_ids;
-  for (size_t i = 0; i < num_writes; ++i) {
-    if (!(write_blocked_streams_.HasWriteBlockedSpecialStream() ||
-          write_blocked_streams_.HasWriteBlockedDataStreams())) {
-      // Writing one stream removed another!? Something's broken.
-      QUIC_BUG(quic_bug_10866_1)
-          << "WriteBlockedStream is missing, num_writes: " << num_writes
-          << ", finished_writes: " << i
-          << ", connected: " << connection_->connected()
-          << ", connection level flow control blocked: "
-          << flow_controller_.IsBlocked();
-      for (QuicStreamId id : last_writing_stream_ids) {
-        QUIC_LOG(WARNING) << "last_writing_stream_id: " << id;
-      }
-      connection_->CloseConnection(QUIC_INTERNAL_ERROR,
-                                   "WriteBlockedStream is missing",
-                                   ConnectionCloseBehavior::SILENT_CLOSE);
-      return;
-    }
-    if (!CanWriteStreamData()) {
-      return;
-    }
-    currently_writing_stream_id_ = write_blocked_streams_.PopFront();
-    last_writing_stream_ids.push_back(currently_writing_stream_id_);
-    QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
-                  << currently_writing_stream_id_ << " from write-blocked list";
-    QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_);
-    if (stream != nullptr && !stream->IsFlowControlBlocked()) {
-      // If the stream can't write all bytes it'll re-add itself to the blocked
-      // list.
-      uint64_t previous_bytes_written = stream->stream_bytes_written();
-      bool previous_fin_sent = stream->fin_sent();
-      QUIC_DVLOG(1) << ENDPOINT << "stream " << stream->id()
-                    << " bytes_written " << previous_bytes_written << " fin "
-                    << previous_fin_sent;
-      stream->OnCanWrite();
-      QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
-      QUICHE_DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written,
-                                              previous_fin_sent));
-    }
-    currently_writing_stream_id_ = 0;
-  }
-}
-
-bool QuicSession::SendProbingData() {
-  if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
-          PROBING_RETRANSMISSION)) {
-    return true;
-  }
-  return false;
-}
-
-bool QuicSession::WillingAndAbleToWrite() const {
-  // Schedule a write when:
-  // 1) control frame manager has pending or new control frames, or
-  // 2) any stream has pending retransmissions, or
-  // 3) If the crypto or headers streams are blocked, or
-  // 4) connection is not flow control blocked and there are write blocked
-  // streams.
-  if (QuicVersionUsesCryptoFrames(transport_version())) {
-    if (HasPendingHandshake()) {
-      return true;
-    }
-    if (!IsEncryptionEstablished()) {
-      return false;
-    }
-  }
-  if (control_frame_manager_.WillingToWrite() ||
-      !streams_with_pending_retransmission_.empty()) {
-    return true;
-  }
-  if (flow_controller_.IsBlocked()) {
-    if (VersionUsesHttp3(transport_version())) {
-      return false;
-    }
-    // Crypto and headers streams are not blocked by connection level flow
-    // control.
-    return write_blocked_streams_.HasWriteBlockedSpecialStream();
-  }
-  return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
-         write_blocked_streams_.HasWriteBlockedDataStreams();
-}
-
-std::string QuicSession::GetStreamsInfoForLogging() const {
-  std::string info = absl::StrCat(
-      "num_active_streams: ", GetNumActiveStreams(),
-      ", num_pending_streams: ", pending_streams_size(),
-      ", num_outgoing_draining_streams: ", num_outgoing_draining_streams(),
-      " ");
-  // Log info for up to 5 streams.
-  size_t i = 5;
-  for (const auto& it : stream_map_) {
-    if (it.second->is_static()) {
-      continue;
-    }
-    // Calculate the stream creation delay.
-    const QuicTime::Delta delay =
-        connection_->clock()->ApproximateNow() - it.second->creation_time();
-    absl::StrAppend(
-        &info, "{", it.second->id(), ":", delay.ToDebuggingValue(), ";",
-        it.second->stream_bytes_written(), ",", it.second->fin_sent(), ",",
-        it.second->HasBufferedData(), ",", it.second->fin_buffered(), ";",
-        it.second->stream_bytes_read(), ",", it.second->fin_received(), "}");
-    --i;
-    if (i == 0) {
-      break;
-    }
-  }
-  return info;
-}
-
-bool QuicSession::HasPendingHandshake() const {
-  if (QuicVersionUsesCryptoFrames(transport_version())) {
-    return GetCryptoStream()->HasPendingCryptoRetransmission() ||
-           GetCryptoStream()->HasBufferedCryptoFrames();
-  }
-  return streams_with_pending_retransmission_.contains(
-             QuicUtils::GetCryptoStreamId(transport_version())) ||
-         write_blocked_streams_.IsStreamBlocked(
-             QuicUtils::GetCryptoStreamId(transport_version()));
-}
-
-void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
-                                   const QuicSocketAddress& peer_address,
-                                   const QuicReceivedPacket& packet) {
-  QuicConnectionContextSwitcher cs(connection_->context());
-  connection_->ProcessUdpPacket(self_address, peer_address, packet);
-}
-
-QuicConsumedData QuicSession::WritevData(QuicStreamId id, size_t write_length,
-                                         QuicStreamOffset offset,
-                                         StreamSendingState state,
-                                         TransmissionType type,
-                                         EncryptionLevel level) {
-  QUICHE_DCHECK(connection_->connected())
-      << ENDPOINT << "Try to write stream data when connection is closed.";
-  if (!IsEncryptionEstablished() &&
-      !QuicUtils::IsCryptoStreamId(transport_version(), id)) {
-    // Do not let streams write without encryption. The calling stream will end
-    // up write blocked until OnCanWrite is next called.
-    if (was_zero_rtt_rejected_ && !OneRttKeysAvailable()) {
-      QUICHE_DCHECK(version().UsesTls() &&
-                    perspective() == Perspective::IS_CLIENT);
-      QUIC_DLOG(INFO) << ENDPOINT
-                      << "Suppress the write while 0-RTT gets rejected and "
-                         "1-RTT keys are not available. Version: "
-                      << ParsedQuicVersionToString(version());
-    } else if (version().UsesTls() || perspective() == Perspective::IS_SERVER) {
-      QUIC_BUG(quic_bug_10866_2)
-          << ENDPOINT << "Try to send data of stream " << id
-          << " before encryption is established. Version: "
-          << ParsedQuicVersionToString(version());
-    } else {
-      // In QUIC crypto, this could happen when the client sends full CHLO and
-      // 0-RTT request, then receives an inchoate REJ and sends an inchoate
-      // CHLO. The client then gets the ACK of the inchoate CHLO or the client
-      // gets the full REJ and needs to verify the proof (before it sends the
-      // full CHLO), such that there is no outstanding crypto data.
-      // Retransmission alarm fires in TLP mode which tries to retransmit the
-      // 0-RTT request (without encryption).
-      QUIC_DLOG(INFO) << ENDPOINT << "Try to send data of stream " << id
-                      << " before encryption is established.";
-    }
-    return QuicConsumedData(0, false);
-  }
-
-  SetTransmissionType(type);
-  QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
-
-  QuicConsumedData data =
-      connection_->SendStreamData(id, write_length, offset, state);
-  if (type == NOT_RETRANSMISSION) {
-    // This is new stream data.
-    write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
-  }
-
-  return data;
-}
-
-size_t QuicSession::SendCryptoData(EncryptionLevel level, size_t write_length,
-                                   QuicStreamOffset offset,
-                                   TransmissionType type) {
-  QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
-  if (!connection()->framer().HasEncrypterOfEncryptionLevel(level)) {
-    const std::string error_details = absl::StrCat(
-        "Try to send crypto data with missing keys of encryption level: ",
-        EncryptionLevelToString(level));
-    QUIC_BUG(quic_bug_10866_3) << ENDPOINT << error_details;
-    connection()->CloseConnection(
-        QUIC_MISSING_WRITE_KEYS, error_details,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return 0;
-  }
-  SetTransmissionType(type);
-  QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
-  const auto bytes_consumed =
-      connection_->SendCryptoData(level, write_length, offset);
-  return bytes_consumed;
-}
-
-void QuicSession::OnControlFrameManagerError(QuicErrorCode error_code,
-                                             std::string error_details) {
-  connection_->CloseConnection(
-      error_code, error_details,
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-bool QuicSession::WriteControlFrame(const QuicFrame& frame,
-                                    TransmissionType type) {
-  QUICHE_DCHECK(connection()->connected())
-      << ENDPOINT << "Try to write control frames when connection is closed.";
-  if (!IsEncryptionEstablished()) {
-    // Suppress the write before encryption gets established.
-    return false;
-  }
-  SetTransmissionType(type);
-  QuicConnection::ScopedEncryptionLevelContext context(
-      connection(), GetEncryptionLevelToSendApplicationData());
-  return connection_->SendControlFrame(frame);
-}
-
-void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) {
-  QuicStream* stream = GetStream(id);
-  if (stream != nullptr && stream->is_static()) {
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Try to reset a static stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  if (stream != nullptr) {
-    stream->Reset(error);
-    return;
-  }
-
-  QuicConnection::ScopedPacketFlusher flusher(connection());
-  MaybeSendStopSendingFrame(id, QuicResetStreamError::FromInternal(error));
-  MaybeSendRstStreamFrame(id, QuicResetStreamError::FromInternal(error), 0);
-}
-
-void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
-                                          QuicResetStreamError error,
-                                          QuicStreamOffset bytes_written) {
-  if (!connection()->connected()) {
-    return;
-  }
-  if (!VersionHasIetfQuicFrames(transport_version()) ||
-      QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
-                               version()) != READ_UNIDIRECTIONAL) {
-    control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
-  }
-
-  connection_->OnStreamReset(id, error.internal_code());
-}
-
-void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
-                                            QuicResetStreamError error) {
-  if (!connection()->connected()) {
-    return;
-  }
-  if (VersionHasIetfQuicFrames(transport_version()) &&
-      QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
-                               version()) != WRITE_UNIDIRECTIONAL) {
-    control_frame_manager_.WriteOrBufferStopSending(error, id);
-  }
-}
-
-void QuicSession::SendGoAway(QuicErrorCode error_code,
-                             const std::string& reason) {
-  // GOAWAY frame is not supported in IETF QUIC.
-  QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
-  if (!IsEncryptionEstablished()) {
-    QUIC_CODE_COUNT(quic_goaway_before_encryption_established);
-    connection_->CloseConnection(
-        error_code, reason,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  if (transport_goaway_sent_) {
-    return;
-  }
-  transport_goaway_sent_ = true;
-
-  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
-  control_frame_manager_.WriteOrBufferGoAway(
-      error_code,
-      QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
-          transport_version()),
-      reason);
-}
-
-void QuicSession::SendBlocked(QuicStreamId id) {
-  control_frame_manager_.WriteOrBufferBlocked(id);
-}
-
-void QuicSession::SendWindowUpdate(QuicStreamId id,
-                                   QuicStreamOffset byte_offset) {
-  control_frame_manager_.WriteOrBufferWindowUpdate(id, byte_offset);
-}
-
-void QuicSession::OnStreamError(QuicErrorCode error_code,
-                                std::string error_details) {
-  connection_->CloseConnection(
-      error_code, error_details,
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicSession::OnStreamError(QuicErrorCode error_code,
-                                QuicIetfTransportErrorCodes ietf_error,
-                                std::string error_details) {
-  connection_->CloseConnection(
-      error_code, ietf_error, error_details,
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
-                                 bool unidirectional) {
-  if (!is_configured_) {
-    QUIC_BUG(quic_bug_10866_5)
-        << "Try to send max streams before config negotiated.";
-    return;
-  }
-  control_frame_manager_.WriteOrBufferMaxStreams(stream_count, unidirectional);
-}
-
-void QuicSession::InsertLocallyClosedStreamsHighestOffset(
-    const QuicStreamId id, QuicStreamOffset offset) {
-  locally_closed_streams_highest_offset_[id] = offset;
-}
-
-void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
-  QUIC_DVLOG(1) << ENDPOINT << "Closing stream: " << stream_id;
-  StreamMap::iterator it = stream_map_.find(stream_id);
-  if (it == stream_map_.end()) {
-    QUIC_BUG(quic_bug_10866_6)
-        << ENDPOINT << "Stream is already closed: " << stream_id;
-    return;
-  }
-  QuicStream* stream = it->second.get();
-  StreamType type = stream->type();
-
-  const bool stream_waiting_for_acks = stream->IsWaitingForAcks();
-  if (stream_waiting_for_acks) {
-    // The stream needs to be kept alive because it's waiting for acks.
-    ++num_zombie_streams_;
-  } else {
-    closed_streams_.push_back(std::move(it->second));
-    stream_map_.erase(it);
-    // Do not retransmit data of a closed stream.
-    streams_with_pending_retransmission_.erase(stream_id);
-    if (!closed_streams_clean_up_alarm_->IsSet()) {
-      closed_streams_clean_up_alarm_->Set(
-          connection_->clock()->ApproximateNow());
-    }
-    QUIC_BUG_IF(
-        364846171_1,
-        connection_->packet_creator().HasPendingStreamFramesOfStream(stream_id))
-        << "Stream " << stream_id
-        << " gets closed while there are pending frames.";
-  }
-
-  if (!stream->HasReceivedFinalOffset()) {
-    // If we haven't received a FIN or RST for this stream, we need to keep
-    // track of the how many bytes the stream's flow controller believes it has
-    // received, for accurate connection level flow control accounting.
-    // If this is an outgoing stream, it is technically open from peer's
-    // perspective. Do not inform stream Id manager yet.
-    QUICHE_DCHECK(!stream->was_draining());
-    InsertLocallyClosedStreamsHighestOffset(
-        stream_id, stream->highest_received_byte_offset());
-    return;
-  }
-
-  const bool stream_was_draining = stream->was_draining();
-  QUIC_DVLOG_IF(1, stream_was_draining)
-      << ENDPOINT << "Stream " << stream_id << " was draining";
-  if (stream_was_draining) {
-    QUIC_BUG_IF(quic_bug_12435_4, num_draining_streams_ == 0);
-    --num_draining_streams_;
-    if (!IsIncomingStream(stream_id)) {
-      QUIC_BUG_IF(quic_bug_12435_5, num_outgoing_draining_streams_ == 0);
-      --num_outgoing_draining_streams_;
-    }
-    // Stream Id manager has been informed with draining streams.
-    return;
-  }
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    stream_id_manager_.OnStreamClosed(
-        /*is_incoming=*/IsIncomingStream(stream_id));
-  }
-  if (!connection_->connected()) {
-    return;
-  }
-  if (IsIncomingStream(stream_id)) {
-    // Stream Id manager is only interested in peer initiated stream IDs.
-    if (VersionHasIetfQuicFrames(transport_version())) {
-      ietf_streamid_manager_.OnStreamClosed(stream_id);
-    }
-    return;
-  }
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    OnCanCreateNewOutgoingStream(type != BIDIRECTIONAL);
-  }
-}
-
-void QuicSession::ClosePendingStream(QuicStreamId stream_id) {
-  QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
-  pending_stream_map_.erase(stream_id);
-  if (connection_->connected()) {
-    ietf_streamid_manager_.OnStreamClosed(stream_id);
-  }
-}
-
-bool QuicSession::ShouldProcessFrameByPendingStream(QuicFrameType type,
-                                                    QuicStreamId id) const {
-  return UsesPendingStreamForFrame(type, id) &&
-         stream_map_.find(id) == stream_map_.end();
-}
-
-void QuicSession::OnFinalByteOffsetReceived(
-    QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
-  auto it = locally_closed_streams_highest_offset_.find(stream_id);
-  if (it == locally_closed_streams_highest_offset_.end()) {
-    return;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "Received final byte offset "
-                << final_byte_offset << " for stream " << stream_id;
-  QuicByteCount offset_diff = final_byte_offset - it->second;
-  if (flow_controller_.UpdateHighestReceivedOffset(
-          flow_controller_.highest_received_byte_offset() + offset_diff)) {
-    // If the final offset violates flow control, close the connection now.
-    if (flow_controller_.FlowControlViolation()) {
-      connection_->CloseConnection(
-          QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-          "Connection level flow control violation",
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return;
-    }
-  }
-
-  flow_controller_.AddBytesConsumed(offset_diff);
-  locally_closed_streams_highest_offset_.erase(it);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    stream_id_manager_.OnStreamClosed(
-        /*is_incoming=*/IsIncomingStream(stream_id));
-  }
-  if (IsIncomingStream(stream_id)) {
-    if (VersionHasIetfQuicFrames(transport_version())) {
-      ietf_streamid_manager_.OnStreamClosed(stream_id);
-    }
-  } else if (!VersionHasIetfQuicFrames(transport_version())) {
-    OnCanCreateNewOutgoingStream(false);
-  }
-}
-
-bool QuicSession::IsEncryptionEstablished() const {
-  if (GetCryptoStream() == nullptr) {
-    return false;
-  }
-  return GetCryptoStream()->encryption_established();
-}
-
-bool QuicSession::OneRttKeysAvailable() const {
-  if (GetCryptoStream() == nullptr) {
-    return false;
-  }
-  return GetCryptoStream()->one_rtt_keys_available();
-}
-
-void QuicSession::OnConfigNegotiated() {
-  // In versions with TLS, the configs will be set twice if 0-RTT is available.
-  // In the second config setting, 1-RTT keys are guaranteed to be available.
-  if (version().UsesTls() && is_configured_ &&
-      connection_->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
-    QUIC_BUG(quic_bug_12435_6)
-        << ENDPOINT
-        << "1-RTT keys missing when config is negotiated for the second time.";
-    connection_->CloseConnection(
-        QUIC_INTERNAL_ERROR,
-        "1-RTT keys missing when config is negotiated for the second time.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "OnConfigNegotiated";
-  connection_->SetFromConfig(config_);
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    uint32_t max_streams = 0;
-    if (config_.HasReceivedMaxBidirectionalStreams()) {
-      max_streams = config_.ReceivedMaxBidirectionalStreams();
-    }
-    if (was_zero_rtt_rejected_ &&
-        max_streams <
-            ietf_streamid_manager_.outgoing_bidirectional_stream_count()) {
-      connection_->CloseConnection(
-          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
-          absl::StrCat(
-              "Server rejected 0-RTT, aborting because new bidirectional "
-              "initial stream limit ",
-              max_streams, " is less than current open streams: ",
-              ietf_streamid_manager_.outgoing_bidirectional_stream_count()),
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return;
-    }
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Setting Bidirectional outgoing_max_streams_ to "
-                  << max_streams;
-    if (perspective_ == Perspective::IS_CLIENT &&
-        max_streams <
-            ietf_streamid_manager_.max_outgoing_bidirectional_streams()) {
-      connection_->CloseConnection(
-          was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
-                                 : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
-          absl::StrCat(
-              was_zero_rtt_rejected_
-                  ? "Server rejected 0-RTT, aborting because "
-                  : "",
-              "new bidirectional limit ", max_streams,
-              " decreases the current limit: ",
-              ietf_streamid_manager_.max_outgoing_bidirectional_streams()),
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return;
-    }
-    if (ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
-            max_streams)) {
-      OnCanCreateNewOutgoingStream(/*unidirectional = */ false);
-    }
-
-    max_streams = 0;
-    if (config_.HasReceivedMaxUnidirectionalStreams()) {
-      max_streams = config_.ReceivedMaxUnidirectionalStreams();
-    }
-
-    if (was_zero_rtt_rejected_ &&
-        max_streams <
-            ietf_streamid_manager_.outgoing_unidirectional_stream_count()) {
-      connection_->CloseConnection(
-          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
-          absl::StrCat(
-              "Server rejected 0-RTT, aborting because new unidirectional "
-              "initial stream limit ",
-              max_streams, " is less than current open streams: ",
-              ietf_streamid_manager_.outgoing_unidirectional_stream_count()),
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return;
-    }
-
-    if (max_streams <
-        ietf_streamid_manager_.max_outgoing_unidirectional_streams()) {
-      connection_->CloseConnection(
-          was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
-                                 : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
-          absl::StrCat(
-              was_zero_rtt_rejected_
-                  ? "Server rejected 0-RTT, aborting because "
-                  : "",
-              "new unidirectional limit ", max_streams,
-              " decreases the current limit: ",
-              ietf_streamid_manager_.max_outgoing_unidirectional_streams()),
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return;
-    }
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Setting Unidirectional outgoing_max_streams_ to "
-                  << max_streams;
-    if (ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
-            max_streams)) {
-      OnCanCreateNewOutgoingStream(/*unidirectional = */ true);
-    }
-  } else {
-    uint32_t max_streams = 0;
-    if (config_.HasReceivedMaxBidirectionalStreams()) {
-      max_streams = config_.ReceivedMaxBidirectionalStreams();
-    }
-    QUIC_DVLOG(1) << ENDPOINT << "Setting max_open_outgoing_streams_ to "
-                  << max_streams;
-    if (was_zero_rtt_rejected_ &&
-        max_streams < stream_id_manager_.num_open_outgoing_streams()) {
-      connection_->CloseConnection(
-          QUIC_INTERNAL_ERROR,
-          absl::StrCat(
-              "Server rejected 0-RTT, aborting because new stream limit ",
-              max_streams, " is less than current open streams: ",
-              stream_id_manager_.num_open_outgoing_streams()),
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return;
-    }
-    stream_id_manager_.set_max_open_outgoing_streams(max_streams);
-  }
-
-  if (perspective() == Perspective::IS_SERVER) {
-    if (config_.HasReceivedConnectionOptions()) {
-      // The following variations change the initial receive flow control
-      // window sizes.
-      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW6)) {
-        AdjustInitialFlowControlWindows(64 * 1024);
-      }
-      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW7)) {
-        AdjustInitialFlowControlWindows(128 * 1024);
-      }
-      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW8)) {
-        AdjustInitialFlowControlWindows(256 * 1024);
-      }
-      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW9)) {
-        AdjustInitialFlowControlWindows(512 * 1024);
-      }
-      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFWA)) {
-        AdjustInitialFlowControlWindows(1024 * 1024);
-      }
-    }
-
-    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
-        config_.GetMaxBidirectionalStreamsToSend());
-    ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
-        config_.GetMaxUnidirectionalStreamsToSend());
-  } else {
-    // A small number of additional incoming streams beyond the limit should be
-    // allowed. This helps avoid early connection termination when FIN/RSTs for
-    // old streams are lost or arrive out of order.
-    // Use a minimum number of additional streams, or a percentage increase,
-    // whichever is larger.
-    uint32_t max_incoming_streams_to_send =
-        config_.GetMaxBidirectionalStreamsToSend();
-    uint32_t max_incoming_streams =
-        std::max(max_incoming_streams_to_send + kMaxStreamsMinimumIncrement,
-                 static_cast<uint32_t>(max_incoming_streams_to_send *
-                                       kMaxStreamsMultiplier));
-    stream_id_manager_.set_max_open_incoming_streams(max_incoming_streams);
-  }
-
-  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
-    // When using IETF-style TLS transport parameters, inform existing streams
-    // of new flow-control limits.
-    if (config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
-      OnNewStreamOutgoingBidirectionalFlowControlWindow(
-          config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
-    }
-    if (config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
-      OnNewStreamIncomingBidirectionalFlowControlWindow(
-          config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
-    }
-    if (config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
-      OnNewStreamUnidirectionalFlowControlWindow(
-          config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
-    }
-  } else {  // The version uses Google QUIC Crypto.
-    if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
-      // Streams which were created before the SHLO was received (0-RTT
-      // requests) are now informed of the peer's initial flow control window.
-      OnNewStreamFlowControlWindow(
-          config_.ReceivedInitialStreamFlowControlWindowBytes());
-    }
-  }
-
-  if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) {
-    OnNewSessionFlowControlWindow(
-        config_.ReceivedInitialSessionFlowControlWindowBytes());
-  }
-
-  is_configured_ = true;
-  connection()->OnConfigNegotiated();
-
-  // Ask flow controllers to try again since the config could have unblocked us.
-  // Or if this session is configured on TLS enabled QUIC versions,
-  // attempt to retransmit 0-RTT data if there's any.
-  // TODO(fayang): consider removing this OnCanWrite call.
-  if (!connection_->framer().is_processing_packet() &&
-      (connection_->version().AllowsLowFlowControlLimits() ||
-       version().UsesTls())) {
-    QUIC_CODE_COUNT(quic_session_on_can_write_on_config_negotiated);
-    OnCanWrite();
-  }
-}
-
-absl::optional<std::string> QuicSession::OnAlpsData(
-    const uint8_t* /*alps_data*/, size_t /*alps_length*/) {
-  return absl::nullopt;
-}
-
-void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) {
-  const float session_window_multiplier =
-      config_.GetInitialStreamFlowControlWindowToSend()
-          ? static_cast<float>(
-                config_.GetInitialSessionFlowControlWindowToSend()) /
-                config_.GetInitialStreamFlowControlWindowToSend()
-          : 1.5;
-
-  QUIC_DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window;
-  config_.SetInitialStreamFlowControlWindowToSend(stream_window);
-
-  size_t session_window = session_window_multiplier * stream_window;
-  QUIC_DVLOG(1) << ENDPOINT << "Set session receive window to "
-                << session_window;
-  config_.SetInitialSessionFlowControlWindowToSend(session_window);
-  flow_controller_.UpdateReceiveWindowSize(session_window);
-  // Inform all existing streams about the new window.
-  for (auto const& kv : stream_map_) {
-    kv.second->UpdateReceiveWindowSize(stream_window);
-  }
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    GetMutableCryptoStream()->UpdateReceiveWindowSize(stream_window);
-  }
-}
-
-void QuicSession::HandleFrameOnNonexistentOutgoingStream(
-    QuicStreamId stream_id) {
-  QUICHE_DCHECK(!IsClosedStream(stream_id));
-  // Received a frame for a locally-created stream that is not currently
-  // active. This is an error.
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    connection()->CloseConnection(
-        QUIC_HTTP_STREAM_WRONG_DIRECTION, "Data for nonexistent stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  connection()->CloseConnection(
-      QUIC_INVALID_STREAM_ID, "Data for nonexistent stream",
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicSession::HandleRstOnValidNonexistentStream(
-    const QuicRstStreamFrame& frame) {
-  // If the stream is neither originally in active streams nor created in
-  // GetOrCreateStream(), it could be a closed stream in which case its
-  // final received byte offset need to be updated.
-  if (IsClosedStream(frame.stream_id)) {
-    // The RST frame contains the final byte offset for the stream: we can now
-    // update the connection level flow controller if needed.
-    OnFinalByteOffsetReceived(frame.stream_id, frame.byte_offset);
-  }
-}
-
-void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
-  QUICHE_DCHECK(version().UsesQuicCrypto());
-  QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamFlowControlWindow " << new_window;
-  if (new_window < kMinimumFlowControlSendWindow) {
-    QUIC_LOG_FIRST_N(ERROR, 1)
-        << "Peer sent us an invalid stream flow control send window: "
-        << new_window << ", below minimum: " << kMinimumFlowControlSendWindow;
-    connection_->CloseConnection(
-        QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  // Inform all existing streams about the new window.
-  for (auto const& kv : stream_map_) {
-    QUIC_DVLOG(1) << ENDPOINT << "Informing stream " << kv.first
-                  << " of new stream flow control window " << new_window;
-    if (!kv.second->MaybeConfigSendWindowOffset(
-            new_window, /* was_zero_rtt_rejected = */ false)) {
-      return;
-    }
-  }
-  if (!QuicVersionUsesCryptoFrames(transport_version())) {
-    QUIC_DVLOG(1)
-        << ENDPOINT
-        << "Informing crypto stream of new stream flow control window "
-        << new_window;
-    GetMutableCryptoStream()->MaybeConfigSendWindowOffset(
-        new_window, /* was_zero_rtt_rejected = */ false);
-  }
-}
-
-void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
-    QuicStreamOffset new_window) {
-  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
-  QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamUnidirectionalFlowControlWindow "
-                << new_window;
-  // Inform all existing outgoing unidirectional streams about the new window.
-  for (auto const& kv : stream_map_) {
-    const QuicStreamId id = kv.first;
-    if (!version().HasIetfQuicFrames()) {
-      if (kv.second->type() == BIDIRECTIONAL) {
-        continue;
-      }
-    } else {
-      if (QuicUtils::IsBidirectionalStreamId(id, version())) {
-        continue;
-      }
-    }
-    if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
-                                       perspective())) {
-      continue;
-    }
-    QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id
-                  << " of new stream flow control window " << new_window;
-    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
-                                                was_zero_rtt_rejected_)) {
-      return;
-    }
-  }
-}
-
-void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
-    QuicStreamOffset new_window) {
-  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
-  QUIC_DVLOG(1) << ENDPOINT
-                << "OnNewStreamOutgoingBidirectionalFlowControlWindow "
-                << new_window;
-  // Inform all existing outgoing bidirectional streams about the new window.
-  for (auto const& kv : stream_map_) {
-    const QuicStreamId id = kv.first;
-    if (!version().HasIetfQuicFrames()) {
-      if (kv.second->type() != BIDIRECTIONAL) {
-        continue;
-      }
-    } else {
-      if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
-        continue;
-      }
-    }
-    if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
-                                       perspective())) {
-      continue;
-    }
-    QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream "
-                  << id << " of new stream flow control window " << new_window;
-    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
-                                                was_zero_rtt_rejected_)) {
-      return;
-    }
-  }
-}
-
-void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
-    QuicStreamOffset new_window) {
-  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
-  QUIC_DVLOG(1) << ENDPOINT
-                << "OnNewStreamIncomingBidirectionalFlowControlWindow "
-                << new_window;
-  // Inform all existing incoming bidirectional streams about the new window.
-  for (auto const& kv : stream_map_) {
-    const QuicStreamId id = kv.first;
-    if (!version().HasIetfQuicFrames()) {
-      if (kv.second->type() != BIDIRECTIONAL) {
-        continue;
-      }
-    } else {
-      if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
-        continue;
-      }
-    }
-    if (QuicUtils::IsOutgoingStreamId(connection_->version(), id,
-                                      perspective())) {
-      continue;
-    }
-    QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream "
-                  << id << " of new stream flow control window " << new_window;
-    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
-                                                was_zero_rtt_rejected_)) {
-      return;
-    }
-  }
-}
-
-void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
-  QUIC_DVLOG(1) << ENDPOINT << "OnNewSessionFlowControlWindow " << new_window;
-
-  if (was_zero_rtt_rejected_ && new_window < flow_controller_.bytes_sent()) {
-    std::string error_details = absl::StrCat(
-        "Server rejected 0-RTT. Aborting because the client received session "
-        "flow control send window: ",
-        new_window,
-        ", which is below currently used: ", flow_controller_.bytes_sent());
-    QUIC_LOG(ERROR) << error_details;
-    connection_->CloseConnection(
-        QUIC_ZERO_RTT_UNRETRANSMITTABLE, error_details,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  if (!connection_->version().AllowsLowFlowControlLimits() &&
-      new_window < kMinimumFlowControlSendWindow) {
-    std::string error_details = absl::StrCat(
-        "Peer sent us an invalid session flow control send window: ",
-        new_window, ", below minimum: ", kMinimumFlowControlSendWindow);
-    QUIC_LOG_FIRST_N(ERROR, 1) << error_details;
-    connection_->CloseConnection(
-        QUIC_FLOW_CONTROL_INVALID_WINDOW, error_details,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  if (perspective_ == Perspective::IS_CLIENT &&
-      new_window < flow_controller_.send_window_offset()) {
-    // The client receives a lower limit than remembered, violating
-    // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
-    std::string error_details = absl::StrCat(
-        was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
-                               : "",
-        "new session max data ", new_window,
-        " decreases current limit: ", flow_controller_.send_window_offset());
-    QUIC_LOG(ERROR) << error_details;
-    connection_->CloseConnection(
-        was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
-                               : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
-        error_details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  flow_controller_.UpdateSendWindowOffset(new_window);
-}
-
-bool QuicSession::OnNewDecryptionKeyAvailable(
-    EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
-    bool set_alternative_decrypter, bool latch_once_used) {
-  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
-      !connection()->framer().HasEncrypterOfEncryptionLevel(
-          QuicUtils::GetEncryptionLevel(
-              QuicUtils::GetPacketNumberSpace(level)))) {
-    // This should never happen because connection should never decrypt a packet
-    // while an ACK for it cannot be encrypted.
-    return false;
-  }
-  if (connection()->version().KnowsWhichDecrypterToUse()) {
-    connection()->InstallDecrypter(level, std::move(decrypter));
-    return true;
-  }
-  if (set_alternative_decrypter) {
-    connection()->SetAlternativeDecrypter(level, std::move(decrypter),
-                                          latch_once_used);
-    return true;
-  }
-  connection()->SetDecrypter(level, std::move(decrypter));
-  return true;
-}
-
-void QuicSession::OnNewEncryptionKeyAvailable(
-    EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
-  connection()->SetEncrypter(level, std::move(encrypter));
-  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
-    return;
-  }
-
-  bool reset_encryption_level = false;
-  if (IsEncryptionEstablished() && level == ENCRYPTION_HANDSHAKE) {
-    // ENCRYPTION_HANDSHAKE keys are only used for the handshake. If
-    // ENCRYPTION_ZERO_RTT keys exist, it is possible for a client to send
-    // stream data, which must not be sent at the ENCRYPTION_HANDSHAKE level.
-    // Therefore, we avoid setting the default encryption level to
-    // ENCRYPTION_HANDSHAKE.
-    reset_encryption_level = true;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
-  connection()->SetDefaultEncryptionLevel(level);
-  if (reset_encryption_level) {
-    connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  }
-  QUIC_BUG_IF(quic_bug_12435_7,
-              IsEncryptionEstablished() &&
-                  (connection()->encryption_level() == ENCRYPTION_INITIAL ||
-                   connection()->encryption_level() == ENCRYPTION_HANDSHAKE))
-      << "Encryption is established, but the encryption level " << level
-      << " does not support sending stream data";
-}
-
-void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
-  QUICHE_DCHECK_EQ(PROTOCOL_QUIC_CRYPTO,
-                   connection_->version().handshake_protocol);
-  QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
-  connection()->SetDefaultEncryptionLevel(level);
-
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-      break;
-    case ENCRYPTION_ZERO_RTT:
-      if (perspective() == Perspective::IS_CLIENT) {
-        // Retransmit old 0-RTT data (if any) with the new 0-RTT keys, since
-        // they can't be decrypted by the server.
-        connection_->MarkZeroRttPacketsForRetransmission(0);
-        if (!connection_->framer().is_processing_packet()) {
-          // TODO(fayang): consider removing this OnCanWrite call.
-          // Given any streams blocked by encryption a chance to write.
-          QUIC_CODE_COUNT(
-              quic_session_on_can_write_set_default_encryption_level);
-          OnCanWrite();
-        }
-      }
-      break;
-    case ENCRYPTION_HANDSHAKE:
-      break;
-    case ENCRYPTION_FORWARD_SECURE:
-      QUIC_BUG_IF(quic_bug_12435_8, !config_.negotiated())
-          << ENDPOINT << "Handshake confirmed without parameter negotiation.";
-      connection()->mutable_stats().handshake_completion_time =
-          connection()->clock()->ApproximateNow();
-      break;
-    default:
-      QUIC_BUG(quic_bug_10866_7) << "Unknown encryption level: " << level;
-  }
-}
-
-void QuicSession::OnTlsHandshakeComplete() {
-  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, connection_->version().handshake_protocol);
-  QUIC_BUG_IF(quic_bug_12435_9,
-              !GetCryptoStream()->crypto_negotiated_params().cipher_suite)
-      << ENDPOINT << "Handshake completes without cipher suite negotiation.";
-  QUIC_BUG_IF(quic_bug_12435_10, !config_.negotiated())
-      << ENDPOINT << "Handshake completes without parameter negotiation.";
-  connection()->mutable_stats().handshake_completion_time =
-      connection()->clock()->ApproximateNow();
-  if (connection()->version().UsesTls() &&
-      perspective_ == Perspective::IS_SERVER) {
-    // Server sends HANDSHAKE_DONE to signal confirmation of the handshake
-    // to the client.
-    control_frame_manager_.WriteOrBufferHandshakeDone();
-    if (connection()->version().HasIetfQuicFrames()) {
-      MaybeSendAddressToken();
-    }
-  }
-}
-
-bool QuicSession::MaybeSendAddressToken() {
-  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER &&
-                connection()->version().HasIetfQuicFrames());
-  absl::optional<CachedNetworkParameters> cached_network_params =
-      GenerateCachedNetworkParameters();
-
-  std::string address_token = GetCryptoStream()->GetAddressToken(
-      cached_network_params.has_value() ? &cached_network_params.value()
-                                        : nullptr);
-  if (address_token.empty()) {
-    return false;
-  }
-  const size_t buf_len = address_token.length() + 1;
-  auto buffer = std::make_unique<char[]>(buf_len);
-  QuicDataWriter writer(buf_len, buffer.get());
-  // Add |kAddressTokenPrefix| for token sent in NEW_TOKEN frame.
-  writer.WriteUInt8(kAddressTokenPrefix);
-  writer.WriteBytes(address_token.data(), address_token.length());
-  control_frame_manager_.WriteOrBufferNewToken(
-      absl::string_view(buffer.get(), buf_len));
-  if (cached_network_params.has_value()) {
-    connection()->OnSendConnectionState(*cached_network_params);
-  }
-  return true;
-}
-
-void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
-  if (!connection()->version().KnowsWhichDecrypterToUse()) {
-    return;
-  }
-  connection()->RemoveDecrypter(level);
-}
-
-void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
-  QUIC_DLOG(INFO) << ENDPOINT << "Discarding " << level << " keys";
-  if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
-    connection()->RemoveEncrypter(level);
-  }
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-      NeuterUnencryptedData();
-      break;
-    case ENCRYPTION_HANDSHAKE:
-      NeuterHandshakeData();
-      break;
-    case ENCRYPTION_ZERO_RTT:
-      break;
-    case ENCRYPTION_FORWARD_SECURE:
-      QUIC_BUG(quic_bug_10866_8)
-          << ENDPOINT << "Discarding 1-RTT keys is not allowed";
-      break;
-    default:
-      QUIC_BUG(quic_bug_10866_9)
-          << ENDPOINT
-          << "Cannot discard keys for unknown encryption level: " << level;
-  }
-}
-
-void QuicSession::NeuterHandshakeData() {
-  GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(
-      ENCRYPTION_HANDSHAKE);
-  connection()->OnHandshakeComplete();
-}
-
-void QuicSession::OnZeroRttRejected(int reason) {
-  was_zero_rtt_rejected_ = true;
-  connection_->MarkZeroRttPacketsForRetransmission(reason);
-  if (connection_->encryption_level() == ENCRYPTION_FORWARD_SECURE) {
-    QUIC_BUG(quic_bug_10866_10)
-        << "1-RTT keys already available when 0-RTT is rejected.";
-    connection_->CloseConnection(
-        QUIC_INTERNAL_ERROR,
-        "1-RTT keys already available when 0-RTT is rejected.",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  }
-}
-
-bool QuicSession::FillTransportParameters(TransportParameters* params) {
-  if (version().UsesTls()) {
-    if (perspective() == Perspective::IS_SERVER) {
-      config_.SetOriginalConnectionIdToSend(
-          connection_->GetOriginalDestinationConnectionId());
-      config_.SetInitialSourceConnectionIdToSend(connection_->connection_id());
-    } else {
-      config_.SetInitialSourceConnectionIdToSend(
-          connection_->client_connection_id());
-    }
-  }
-  return config_.FillTransportParameters(params);
-}
-
-QuicErrorCode QuicSession::ProcessTransportParameters(
-    const TransportParameters& params, bool is_resumption,
-    std::string* error_details) {
-  return config_.ProcessTransportParameters(params, is_resumption,
-                                            error_details);
-}
-
-void QuicSession::OnHandshakeCallbackDone() {
-  if (!connection_->connected()) {
-    return;
-  }
-
-  if (!connection()->is_processing_packet()) {
-    connection()->MaybeProcessUndecryptablePackets();
-  }
-}
-
-bool QuicSession::PacketFlusherAttached() const {
-  QUICHE_DCHECK(connection_->connected());
-  return connection()->packet_creator().PacketFlusherAttached();
-}
-
-void QuicSession::OnCryptoHandshakeMessageSent(
-    const CryptoHandshakeMessage& /*message*/) {}
-
-void QuicSession::OnCryptoHandshakeMessageReceived(
-    const CryptoHandshakeMessage& /*message*/) {}
-
-void QuicSession::RegisterStreamPriority(
-    QuicStreamId id, bool is_static,
-    const spdy::SpdyStreamPrecedence& precedence) {
-  write_blocked_streams()->RegisterStream(id, is_static, precedence);
-}
-
-void QuicSession::UnregisterStreamPriority(QuicStreamId id, bool is_static) {
-  write_blocked_streams()->UnregisterStream(id, is_static);
-}
-
-void QuicSession::UpdateStreamPriority(
-    QuicStreamId id, const spdy::SpdyStreamPrecedence& new_precedence) {
-  write_blocked_streams()->UpdateStreamPriority(id, new_precedence);
-}
-
-QuicConfig* QuicSession::config() { return &config_; }
-
-void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
-  QuicStreamId stream_id = stream->id();
-  bool is_static = stream->is_static();
-  QUIC_DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size()
-                << ". activating stream " << stream_id;
-  QUICHE_DCHECK(!stream_map_.contains(stream_id));
-  stream_map_[stream_id] = std::move(stream);
-  if (is_static) {
-    ++num_static_streams_;
-    return;
-  }
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // Do not inform stream ID manager of static streams.
-    stream_id_manager_.ActivateStream(
-        /*is_incoming=*/IsIncomingStream(stream_id));
-  }
-}
-
-QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.GetNextOutgoingBidirectionalStreamId();
-  }
-  return stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.GetNextOutgoingUnidirectionalStreamId();
-  }
-  return stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
-  if (liveness_testing_in_progress_) {
-    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective());
-    return false;
-  }
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    if (!stream_id_manager_.CanOpenNextOutgoingStream()) {
-      return false;
-    }
-  } else {
-    if (!ietf_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) {
-      if (is_configured_) {
-        // Send STREAM_BLOCKED after config negotiated.
-        control_frame_manager_.WriteOrBufferStreamsBlocked(
-            ietf_streamid_manager_.max_outgoing_bidirectional_streams(),
-            /*unidirectional=*/false);
-      }
-      return false;
-    }
-  }
-  if (perspective() == Perspective::IS_CLIENT &&
-      connection_->MaybeTestLiveness()) {
-    // Now is relatively close to the idle timeout having the risk that requests
-    // could be discarded at the server.
-    liveness_testing_in_progress_ = true;
-    return false;
-  }
-  return true;
-}
-
-bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return stream_id_manager_.CanOpenNextOutgoingStream();
-  }
-  if (ietf_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) {
-    return true;
-  }
-  if (is_configured_) {
-    // Send STREAM_BLOCKED after config negotiated.
-    control_frame_manager_.WriteOrBufferStreamsBlocked(
-        ietf_streamid_manager_.max_outgoing_unidirectional_streams(),
-        /*unidirectional=*/true);
-  }
-  return false;
-}
-
-QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams()
-    const {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
-  return ietf_streamid_manager_.advertised_max_incoming_bidirectional_streams();
-}
-
-QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
-  QUICHE_DCHECK(!pending_stream_map_.contains(stream_id));
-  if (QuicUtils::IsCryptoStreamId(transport_version(), stream_id)) {
-    return GetMutableCryptoStream();
-  }
-
-  StreamMap::iterator it = stream_map_.find(stream_id);
-  if (it != stream_map_.end()) {
-    return it->second->IsZombie() ? nullptr : it->second.get();
-  }
-
-  if (IsClosedStream(stream_id)) {
-    return nullptr;
-  }
-
-  if (!IsIncomingStream(stream_id)) {
-    HandleFrameOnNonexistentOutgoingStream(stream_id);
-    return nullptr;
-  }
-
-  // TODO(fkastenholz): If we are creating a new stream and we have sent a
-  // goaway, we should ignore the stream creation. Need to add code to A) test
-  // if goaway was sent ("if (transport_goaway_sent_)") and B) reject stream
-  // creation ("return nullptr")
-
-  if (!MaybeIncreaseLargestPeerStreamId(stream_id)) {
-    return nullptr;
-  }
-
-  if (!VersionHasIetfQuicFrames(transport_version()) &&
-      !stream_id_manager_.CanOpenIncomingStream()) {
-    // Refuse to open the stream.
-    ResetStream(stream_id, QUIC_REFUSED_STREAM);
-    return nullptr;
-  }
-
-  return CreateIncomingStream(stream_id);
-}
-
-void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) {
-  QUICHE_DCHECK(stream_map_.contains(stream_id));
-  QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    ietf_streamid_manager_.OnStreamClosed(stream_id);
-  } else {
-    stream_id_manager_.OnStreamClosed(
-        /*is_incoming=*/IsIncomingStream(stream_id));
-  }
-  ++num_draining_streams_;
-  if (!IsIncomingStream(stream_id)) {
-    ++num_outgoing_draining_streams_;
-    if (!VersionHasIetfQuicFrames(transport_version())) {
-      OnCanCreateNewOutgoingStream(unidirectional);
-    }
-  }
-}
-
-bool QuicSession::MaybeIncreaseLargestPeerStreamId(
-    const QuicStreamId stream_id) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    std::string error_details;
-    if (ietf_streamid_manager_.MaybeIncreaseLargestPeerStreamId(
-            stream_id, &error_details)) {
-      return true;
-    }
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, error_details,
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  if (!stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id)) {
-    connection()->CloseConnection(
-        QUIC_TOO_MANY_AVAILABLE_STREAMS,
-        absl::StrCat(stream_id, " exceeds available streams ",
-                     stream_id_manager_.MaxAvailableStreams()),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return false;
-  }
-  return true;
-}
-
-bool QuicSession::ShouldYield(QuicStreamId stream_id) {
-  if (stream_id == currently_writing_stream_id_) {
-    return false;
-  }
-  return write_blocked_streams()->ShouldYield(stream_id);
-}
-
-PendingStream* QuicSession::GetOrCreatePendingStream(QuicStreamId stream_id) {
-  auto it = pending_stream_map_.find(stream_id);
-  if (it != pending_stream_map_.end()) {
-    return it->second.get();
-  }
-
-  if (IsClosedStream(stream_id) ||
-      !MaybeIncreaseLargestPeerStreamId(stream_id)) {
-    return nullptr;
-  }
-
-  auto pending = std::make_unique<PendingStream>(stream_id, this);
-  PendingStream* unowned_pending = pending.get();
-  pending_stream_map_[stream_id] = std::move(pending);
-  return unowned_pending;
-}
-
-void QuicSession::set_largest_peer_created_stream_id(
-    QuicStreamId largest_peer_created_stream_id) {
-  QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
-  stream_id_manager_.set_largest_peer_created_stream_id(
-      largest_peer_created_stream_id);
-}
-
-QuicStreamId QuicSession::GetLargestPeerCreatedStreamId(
-    bool unidirectional) const {
-  // This method is only used in IETF QUIC.
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
-  return ietf_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional);
-}
-
-void QuicSession::DeleteConnection() {
-  if (connection_) {
-    delete connection_;
-    connection_ = nullptr;
-  }
-}
-
-bool QuicSession::MaybeSetStreamPriority(
-    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
-  auto active_stream = stream_map_.find(stream_id);
-  if (active_stream != stream_map_.end()) {
-    active_stream->second->SetPriority(precedence);
-    return true;
-  }
-
-  return false;
-}
-
-bool QuicSession::IsClosedStream(QuicStreamId id) {
-  QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
-  if (IsOpenStream(id)) {
-    // Stream is active
-    return false;
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return !ietf_streamid_manager_.IsAvailableStream(id);
-  }
-
-  return !stream_id_manager_.IsAvailableStream(id);
-}
-
-bool QuicSession::IsOpenStream(QuicStreamId id) {
-  QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
-  const StreamMap::iterator it = stream_map_.find(id);
-  if (it != stream_map_.end()) {
-    return !it->second->IsZombie();
-  }
-  if (pending_stream_map_.contains(id) ||
-      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
-    // Stream is active
-    return true;
-  }
-  return false;
-}
-
-bool QuicSession::IsStaticStream(QuicStreamId id) const {
-  auto it = stream_map_.find(id);
-  if (it == stream_map_.end()) {
-    return false;
-  }
-  return it->second->is_static();
-}
-
-size_t QuicSession::GetNumActiveStreams() const {
-  QUICHE_DCHECK_GE(
-      static_cast<QuicStreamCount>(stream_map_.size()),
-      num_static_streams_ + num_draining_streams_ + num_zombie_streams_);
-  return stream_map_.size() - num_draining_streams_ - num_static_streams_ -
-         num_zombie_streams_;
-}
-
-void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
-  if (GetOrCreateStream(id) == nullptr) {
-    QUIC_BUG(quic_bug_10866_11)
-        << "Marking unknown stream " << id << " blocked.";
-    QUIC_LOG_FIRST_N(ERROR, 2) << QuicStackTrace();
-  }
-
-  QUIC_DVLOG(1) << ENDPOINT << "Adding stream " << id
-                << " to write-blocked list";
-
-  write_blocked_streams_.AddStream(id);
-}
-
-bool QuicSession::HasDataToWrite() const {
-  return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
-         write_blocked_streams_.HasWriteBlockedDataStreams() ||
-         connection_->HasQueuedData() ||
-         !streams_with_pending_retransmission_.empty() ||
-         control_frame_manager_.WillingToWrite();
-}
-
-void QuicSession::OnAckNeedsRetransmittableFrame() {
-  flow_controller_.SendWindowUpdate();
-}
-
-void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) {
-  control_frame_manager_.WriteOrBufferAckFrequency(frame);
-}
-
-void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) {
-  // Count NEW_CONNECTION_ID frames sent to client.
-  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 1, 6);
-  control_frame_manager_.WriteOrBufferNewConnectionId(
-      frame.connection_id, frame.sequence_number, frame.retire_prior_to,
-      frame.stateless_reset_token);
-}
-
-void QuicSession::SendRetireConnectionId(uint64_t sequence_number) {
-  // Count RETIRE_CONNECTION_ID frames sent to client.
-  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 2, 6);
-  control_frame_manager_.WriteOrBufferRetireConnectionId(sequence_number);
-}
-
-void QuicSession::OnServerConnectionIdIssued(
-    const QuicConnectionId& server_connection_id) {
-  if (visitor_) {
-    visitor_->OnNewConnectionIdSent(
-        connection_->GetOneActiveServerConnectionId(), server_connection_id);
-  }
-}
-
-void QuicSession::OnServerConnectionIdRetired(
-    const QuicConnectionId& server_connection_id) {
-  if (visitor_) {
-    visitor_->OnConnectionIdRetired(server_connection_id);
-  }
-}
-
-bool QuicSession::IsConnectionFlowControlBlocked() const {
-  return flow_controller_.IsBlocked();
-}
-
-bool QuicSession::IsStreamFlowControlBlocked() {
-  for (auto const& kv : stream_map_) {
-    if (kv.second->IsFlowControlBlocked()) {
-      return true;
-    }
-  }
-  if (!QuicVersionUsesCryptoFrames(transport_version()) &&
-      GetMutableCryptoStream()->IsFlowControlBlocked()) {
-    return true;
-  }
-  return false;
-}
-
-size_t QuicSession::MaxAvailableBidirectionalStreams() const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
-  }
-  return stream_id_manager_.MaxAvailableStreams();
-}
-
-size_t QuicSession::MaxAvailableUnidirectionalStreams() const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
-  }
-  return stream_id_manager_.MaxAvailableStreams();
-}
-
-bool QuicSession::IsIncomingStream(QuicStreamId id) const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return !QuicUtils::IsOutgoingStreamId(version(), id, perspective_);
-  }
-  return stream_id_manager_.IsIncomingStream(id);
-}
-
-void QuicSession::MaybeCloseZombieStream(QuicStreamId id) {
-  auto it = stream_map_.find(id);
-  if (it == stream_map_.end()) {
-    return;
-  }
-  --num_zombie_streams_;
-  closed_streams_.push_back(std::move(it->second));
-  stream_map_.erase(it);
-
-  if (!closed_streams_clean_up_alarm_->IsSet()) {
-    closed_streams_clean_up_alarm_->Set(connection_->clock()->ApproximateNow());
-  }
-  // Do not retransmit data of a closed stream.
-  streams_with_pending_retransmission_.erase(id);
-  QUIC_BUG_IF(364846171_2,
-              connection_->packet_creator().HasPendingStreamFramesOfStream(id))
-      << "Stream " << id << " gets closed while there are pending frames.";
-}
-
-QuicStream* QuicSession::GetStream(QuicStreamId id) const {
-  auto active_stream = stream_map_.find(id);
-  if (active_stream != stream_map_.end()) {
-    return active_stream->second.get();
-  }
-
-  if (QuicUtils::IsCryptoStreamId(transport_version(), id)) {
-    return const_cast<QuicCryptoStream*>(GetCryptoStream());
-  }
-
-  return nullptr;
-}
-
-QuicStream* QuicSession::GetActiveStream(QuicStreamId id) const {
-  auto stream = stream_map_.find(id);
-  if (stream != stream_map_.end() && !stream->second->is_static()) {
-    return stream->second.get();
-  }
-  return nullptr;
-}
-
-bool QuicSession::OnFrameAcked(const QuicFrame& frame,
-                               QuicTime::Delta ack_delay_time,
-                               QuicTime receive_timestamp) {
-  if (frame.type == MESSAGE_FRAME) {
-    OnMessageAcked(frame.message_frame->message_id, receive_timestamp);
-    return true;
-  }
-  if (frame.type == CRYPTO_FRAME) {
-    return GetMutableCryptoStream()->OnCryptoFrameAcked(*frame.crypto_frame,
-                                                        ack_delay_time);
-  }
-  if (frame.type != STREAM_FRAME) {
-    return control_frame_manager_.OnControlFrameAcked(frame);
-  }
-  bool new_stream_data_acked = false;
-  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
-  // Stream can already be reset when sent frame gets acked.
-  if (stream != nullptr) {
-    QuicByteCount newly_acked_length = 0;
-    new_stream_data_acked = stream->OnStreamFrameAcked(
-        frame.stream_frame.offset, frame.stream_frame.data_length,
-        frame.stream_frame.fin, ack_delay_time, receive_timestamp,
-        &newly_acked_length);
-    if (!stream->HasPendingRetransmission()) {
-      streams_with_pending_retransmission_.erase(stream->id());
-    }
-  }
-  return new_stream_data_acked;
-}
-
-void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
-  QuicStream* stream = GetStream(frame.stream_id);
-  if (stream == nullptr) {
-    QUIC_BUG(quic_bug_10866_12)
-        << "Stream: " << frame.stream_id << " is closed when " << frame
-        << " is retransmitted.";
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR, "Attempt to retransmit frame of a closed stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length,
-                                     frame.fin);
-}
-
-void QuicSession::OnFrameLost(const QuicFrame& frame) {
-  if (frame.type == MESSAGE_FRAME) {
-    OnMessageLost(frame.message_frame->message_id);
-    return;
-  }
-  if (frame.type == CRYPTO_FRAME) {
-    GetMutableCryptoStream()->OnCryptoFrameLost(frame.crypto_frame);
-    return;
-  }
-  if (frame.type != STREAM_FRAME) {
-    control_frame_manager_.OnControlFrameLost(frame);
-    return;
-  }
-  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
-  if (stream == nullptr) {
-    return;
-  }
-  stream->OnStreamFrameLost(frame.stream_frame.offset,
-                            frame.stream_frame.data_length,
-                            frame.stream_frame.fin);
-  if (stream->HasPendingRetransmission() &&
-      !streams_with_pending_retransmission_.contains(
-          frame.stream_frame.stream_id)) {
-    streams_with_pending_retransmission_.insert(
-        std::make_pair(frame.stream_frame.stream_id, true));
-  }
-}
-
-bool QuicSession::RetransmitFrames(const QuicFrames& frames,
-                                   TransmissionType type) {
-  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
-  for (const QuicFrame& frame : frames) {
-    if (frame.type == MESSAGE_FRAME) {
-      // Do not retransmit MESSAGE frames.
-      continue;
-    }
-    if (frame.type == CRYPTO_FRAME) {
-      const bool data_retransmitted =
-          GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type);
-      if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted) &&
-          !data_retransmitted) {
-        return false;
-      }
-      continue;
-    }
-    if (frame.type != STREAM_FRAME) {
-      if (!control_frame_manager_.RetransmitControlFrame(frame, type)) {
-        return false;
-      }
-      continue;
-    }
-    QuicStream* stream = GetStream(frame.stream_frame.stream_id);
-    if (stream != nullptr &&
-        !stream->RetransmitStreamData(frame.stream_frame.offset,
-                                      frame.stream_frame.data_length,
-                                      frame.stream_frame.fin, type)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const {
-  if (frame.type == MESSAGE_FRAME) {
-    return false;
-  }
-  if (frame.type == CRYPTO_FRAME) {
-    return GetCryptoStream()->IsFrameOutstanding(
-        frame.crypto_frame->level, frame.crypto_frame->offset,
-        frame.crypto_frame->data_length);
-  }
-  if (frame.type != STREAM_FRAME) {
-    return control_frame_manager_.IsControlFrameOutstanding(frame);
-  }
-  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
-  return stream != nullptr &&
-         stream->IsStreamFrameOutstanding(frame.stream_frame.offset,
-                                          frame.stream_frame.data_length,
-                                          frame.stream_frame.fin);
-}
-
-bool QuicSession::HasUnackedCryptoData() const {
-  const QuicCryptoStream* crypto_stream = GetCryptoStream();
-  return crypto_stream->IsWaitingForAcks() || crypto_stream->HasBufferedData();
-}
-
-bool QuicSession::HasUnackedStreamData() const {
-  for (const auto& it : stream_map_) {
-    if (it.second->IsWaitingForAcks()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-HandshakeState QuicSession::GetHandshakeState() const {
-  return GetCryptoStream()->GetHandshakeState();
-}
-
-WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
-                                                   QuicStreamOffset offset,
-                                                   QuicByteCount data_length,
-                                                   QuicDataWriter* writer) {
-  QuicStream* stream = GetStream(id);
-  if (stream == nullptr) {
-    // This causes the connection to be closed because of failed to serialize
-    // packet.
-    QUIC_BUG(quic_bug_10866_13)
-        << "Stream " << id << " does not exist when trying to write data."
-        << " version:" << transport_version();
-    return STREAM_MISSING;
-  }
-  if (stream->WriteStreamData(offset, data_length, writer)) {
-    return WRITE_SUCCESS;
-  }
-  return WRITE_FAILED;
-}
-
-bool QuicSession::WriteCryptoData(EncryptionLevel level,
-                                  QuicStreamOffset offset,
-                                  QuicByteCount data_length,
-                                  QuicDataWriter* writer) {
-  return GetMutableCryptoStream()->WriteCryptoFrame(level, offset, data_length,
-                                                    writer);
-}
-
-StatelessResetToken QuicSession::GetStatelessResetToken() const {
-  return QuicUtils::GenerateStatelessResetToken(connection_->connection_id());
-}
-
-bool QuicSession::CanWriteStreamData() const {
-  // Don't write stream data if there are queued data packets.
-  if (connection_->HasQueuedPackets()) {
-    return false;
-  }
-  // Immediately write handshake data.
-  if (HasPendingHandshake()) {
-    return true;
-  }
-  return connection_->CanWrite(HAS_RETRANSMITTABLE_DATA);
-}
-
-bool QuicSession::RetransmitLostData() {
-  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
-  // Retransmit crypto data first.
-  bool uses_crypto_frames = QuicVersionUsesCryptoFrames(transport_version());
-  QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
-  if (uses_crypto_frames && crypto_stream->HasPendingCryptoRetransmission()) {
-    crypto_stream->WritePendingCryptoRetransmission();
-  }
-  // Retransmit crypto data in stream 1 frames (version < 47).
-  if (!uses_crypto_frames &&
-      streams_with_pending_retransmission_.contains(
-          QuicUtils::GetCryptoStreamId(transport_version()))) {
-    // Retransmit crypto data first.
-    QuicStream* crypto_stream =
-        GetStream(QuicUtils::GetCryptoStreamId(transport_version()));
-    crypto_stream->OnCanWrite();
-    QUICHE_DCHECK(CheckStreamWriteBlocked(crypto_stream));
-    if (crypto_stream->HasPendingRetransmission()) {
-      // Connection is write blocked.
-      return false;
-    } else {
-      streams_with_pending_retransmission_.erase(
-          QuicUtils::GetCryptoStreamId(transport_version()));
-    }
-  }
-  if (control_frame_manager_.HasPendingRetransmission()) {
-    control_frame_manager_.OnCanWrite();
-    if (control_frame_manager_.HasPendingRetransmission()) {
-      return false;
-    }
-  }
-  while (!streams_with_pending_retransmission_.empty()) {
-    if (!CanWriteStreamData()) {
-      break;
-    }
-    // Retransmit lost data on headers and data streams.
-    const QuicStreamId id = streams_with_pending_retransmission_.begin()->first;
-    QuicStream* stream = GetStream(id);
-    if (stream != nullptr) {
-      stream->OnCanWrite();
-      QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
-      if (stream->HasPendingRetransmission()) {
-        // Connection is write blocked.
-        break;
-      } else if (!streams_with_pending_retransmission_.empty() &&
-                 streams_with_pending_retransmission_.begin()->first == id) {
-        // Retransmit lost data may cause connection close. If this stream
-        // has not yet sent fin, a RST_STREAM will be sent and it will be
-        // removed from streams_with_pending_retransmission_.
-        streams_with_pending_retransmission_.pop_front();
-      }
-    } else {
-      QUIC_BUG(quic_bug_10866_14)
-          << "Try to retransmit data of a closed stream";
-      streams_with_pending_retransmission_.pop_front();
-    }
-  }
-
-  return streams_with_pending_retransmission_.empty();
-}
-
-void QuicSession::NeuterUnencryptedData() {
-  QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
-  crypto_stream->NeuterUnencryptedStreamData();
-  if (!crypto_stream->HasPendingRetransmission() &&
-      !QuicVersionUsesCryptoFrames(transport_version())) {
-    streams_with_pending_retransmission_.erase(
-        QuicUtils::GetCryptoStreamId(transport_version()));
-  }
-  connection_->NeuterUnencryptedPackets();
-}
-
-void QuicSession::SetTransmissionType(TransmissionType type) {
-  connection_->SetTransmissionType(type);
-}
-
-MessageResult QuicSession::SendMessage(
-    absl::Span<quiche::QuicheMemSlice> message) {
-  return SendMessage(message, /*flush=*/false);
-}
-
-MessageResult QuicSession::SendMessage(quiche::QuicheMemSlice message) {
-  return SendMessage(absl::MakeSpan(&message, 1), /*flush=*/false);
-}
-
-MessageResult QuicSession::SendMessage(
-    absl::Span<quiche::QuicheMemSlice> message, bool flush) {
-  QUICHE_DCHECK(connection_->connected())
-      << ENDPOINT << "Try to write messages when connection is closed.";
-  if (!IsEncryptionEstablished()) {
-    return {MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0};
-  }
-  QuicConnection::ScopedEncryptionLevelContext context(
-      connection(), GetEncryptionLevelToSendApplicationData());
-  MessageStatus result =
-      connection_->SendMessage(last_message_id_ + 1, message, flush);
-  if (result == MESSAGE_STATUS_SUCCESS) {
-    return {result, ++last_message_id_};
-  }
-  return {result, 0};
-}
-
-void QuicSession::OnMessageAcked(QuicMessageId message_id,
-                                 QuicTime /*receive_timestamp*/) {
-  QUIC_DVLOG(1) << ENDPOINT << "message " << message_id << " gets acked.";
-}
-
-void QuicSession::OnMessageLost(QuicMessageId message_id) {
-  QUIC_DVLOG(1) << ENDPOINT << "message " << message_id
-                << " is considered lost";
-}
-
-void QuicSession::CleanUpClosedStreams() { closed_streams_.clear(); }
-
-QuicPacketLength QuicSession::GetCurrentLargestMessagePayload() const {
-  return connection_->GetCurrentLargestMessagePayload();
-}
-
-QuicPacketLength QuicSession::GetGuaranteedLargestMessagePayload() const {
-  return connection_->GetGuaranteedLargestMessagePayload();
-}
-
-QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.next_outgoing_bidirectional_stream_id();
-  }
-  return stream_id_manager_.next_outgoing_stream_id();
-}
-
-QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.next_outgoing_unidirectional_stream_id();
-  }
-  return stream_id_manager_.next_outgoing_stream_id();
-}
-
-bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
-  const bool allow_new_streams =
-      frame.unidirectional
-          ? ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
-                frame.stream_count)
-          : ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
-                frame.stream_count);
-  if (allow_new_streams) {
-    OnCanCreateNewOutgoingStream(frame.unidirectional);
-  }
-
-  return true;
-}
-
-bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) {
-  std::string error_details;
-  if (ietf_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) {
-    return true;
-  }
-  connection_->CloseConnection(
-      QUIC_STREAMS_BLOCKED_ERROR, error_details,
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  return false;
-}
-
-size_t QuicSession::max_open_incoming_bidirectional_streams() const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
-  }
-  return stream_id_manager_.max_open_incoming_streams();
-}
-
-size_t QuicSession::max_open_incoming_unidirectional_streams() const {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
-  }
-  return stream_id_manager_.max_open_incoming_streams();
-}
-
-std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn(
-    const std::vector<absl::string_view>& alpns) const {
-  const std::string alpn = AlpnForVersion(connection()->version());
-  return std::find(alpns.cbegin(), alpns.cend(), alpn);
-}
-
-void QuicSession::OnAlpnSelected(absl::string_view alpn) {
-  QUIC_DLOG(INFO) << (perspective() == Perspective::IS_SERVER ? "Server: "
-                                                              : "Client: ")
-                  << "ALPN selected: " << alpn;
-}
-
-void QuicSession::NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level) {
-  GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(level);
-}
-
-void QuicSession::PerformActionOnActiveStreams(
-    std::function<bool(QuicStream*)> action) {
-  std::vector<QuicStream*> active_streams;
-  for (const auto& it : stream_map_) {
-    if (!it.second->is_static() && !it.second->IsZombie()) {
-      active_streams.push_back(it.second.get());
-    }
-  }
-
-  for (QuicStream* stream : active_streams) {
-    if (!action(stream)) {
-      return;
-    }
-  }
-}
-
-void QuicSession::PerformActionOnActiveStreams(
-    std::function<bool(QuicStream*)> action) const {
-  for (const auto& it : stream_map_) {
-    if (!it.second->is_static() && !it.second->IsZombie() &&
-        !action(it.second.get())) {
-      return;
-    }
-  }
-}
-
-EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const {
-  return connection_->framer().GetEncryptionLevelToSendApplicationData();
-}
-
-void QuicSession::ProcessAllPendingStreams() {
-  std::vector<PendingStream*> pending_streams;
-  pending_streams.reserve(pending_stream_map_.size());
-  for (auto it = pending_stream_map_.cbegin(); it != pending_stream_map_.cend();
-       ++it) {
-    pending_streams.push_back(it->second.get());
-  }
-  for (auto* pending_stream : pending_streams) {
-    MaybeProcessPendingStream(pending_stream);
-    if (!connection()->connected()) {
-      return;
-    }
-  }
-}
-
-void QuicSession::ValidatePath(
-    std::unique_ptr<QuicPathValidationContext> context,
-    std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
-  connection_->ValidatePath(std::move(context), std::move(result_delegate));
-}
-
-bool QuicSession::HasPendingPathValidation() const {
-  return connection_->HasPendingPathValidation();
-}
-
-bool QuicSession::MigratePath(const QuicSocketAddress& self_address,
-                              const QuicSocketAddress& peer_address,
-                              QuicPacketWriter* writer, bool owns_writer) {
-  return connection_->MigratePath(self_address, peer_address, writer,
-                                  owns_writer);
-}
-
-bool QuicSession::ValidateToken(absl::string_view token) {
-  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
-  if (GetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet)) {
-    return false;
-  }
-  if (token.empty() || token[0] != kAddressTokenPrefix) {
-    // Validate the prefix for token received in NEW_TOKEN frame.
-    return false;
-  }
-  const bool valid = GetCryptoStream()->ValidateAddressToken(
-      absl::string_view(token.data() + 1, token.length() - 1));
-  if (valid) {
-    const CachedNetworkParameters* cached_network_params =
-        GetCryptoStream()->PreviousCachedNetworkParams();
-    if (cached_network_params != nullptr &&
-        cached_network_params->timestamp() > 0) {
-      connection()->OnReceiveConnectionState(*cached_network_params);
-    }
-  }
-  return valid;
-}
-
-#undef ENDPOINT  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
deleted file mode 100644
index 9fa9d1e..0000000
--- a/quic/core/quic_session.h
+++ /dev/null
@@ -1,1020 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A QuicSession, which demuxes a single connection to individual streams.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SESSION_H_
-#define QUICHE_QUIC_CORE_QUIC_SESSION_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-#include "quic/core/crypto/tls_connection.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/frames/quic_stop_sending_frame.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/core/handshaker_delegate_interface.h"
-#include "quic/core/legacy_quic_stream_id_manager.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_control_frame_manager.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_datagram_queue.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/core/stream_delegate_interface.h"
-#include "quic/core/uber_quic_stream_id_manager.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class QuicCryptoStream;
-class QuicFlowController;
-class QuicStream;
-class QuicStreamIdManager;
-
-namespace test {
-class QuicSessionPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicSession
-    : public QuicConnectionVisitorInterface,
-      public SessionNotifierInterface,
-      public QuicStreamFrameDataProducer,
-      public QuicStreamIdManager::DelegateInterface,
-      public HandshakerDelegateInterface,
-      public StreamDelegateInterface,
-      public QuicControlFrameManager::DelegateInterface {
- public:
-  // An interface from the session to the entity owning the session.
-  // This lets the session notify its owner (the Dispatcher) when the connection
-  // is closed, blocked, or added/removed from the time-wait list.
-  class QUIC_EXPORT_PRIVATE Visitor {
-   public:
-    virtual ~Visitor() {}
-
-    // Called when the connection is closed after the streams have been closed.
-    virtual void OnConnectionClosed(QuicConnectionId server_connection_id,
-                                    QuicErrorCode error,
-                                    const std::string& error_details,
-                                    ConnectionCloseSource source) = 0;
-
-    // Called when the session has become write blocked.
-    virtual void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) = 0;
-
-    // Called when the session receives reset on a stream from the peer.
-    virtual void OnRstStreamReceived(const QuicRstStreamFrame& frame) = 0;
-
-    // Called when the session receives a STOP_SENDING for a stream from the
-    // peer.
-    virtual void OnStopSendingReceived(const QuicStopSendingFrame& frame) = 0;
-
-    // Called when a NewConnectionId frame has been sent.
-    virtual void OnNewConnectionIdSent(
-        const QuicConnectionId& server_connection_id,
-        const QuicConnectionId& new_connection_id) = 0;
-
-    // Called when a ConnectionId has been retired.
-    virtual void OnConnectionIdRetired(
-        const QuicConnectionId& server_connection_id) = 0;
-  };
-
-  // Does not take ownership of |connection| or |visitor|.
-  QuicSession(QuicConnection* connection, Visitor* owner,
-              const QuicConfig& config,
-              const ParsedQuicVersionVector& supported_versions,
-              QuicStreamCount num_expected_unidirectional_static_streams);
-  QuicSession(QuicConnection* connection, Visitor* owner,
-              const QuicConfig& config,
-              const ParsedQuicVersionVector& supported_versions,
-              QuicStreamCount num_expected_unidirectional_static_streams,
-              std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
-  QuicSession(const QuicSession&) = delete;
-  QuicSession& operator=(const QuicSession&) = delete;
-
-  ~QuicSession() override;
-
-  virtual void Initialize();
-
-  // Return the reserved crypto stream as a constant pointer.
-  virtual const QuicCryptoStream* GetCryptoStream() const = 0;
-
-  // QuicConnectionVisitorInterface methods:
-  void OnStreamFrame(const QuicStreamFrame& frame) override;
-  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  void OnRstStream(const QuicRstStreamFrame& frame) override;
-  void OnGoAway(const QuicGoAwayFrame& frame) override;
-  void OnMessageReceived(absl::string_view message) override;
-  void OnHandshakeDoneReceived() override;
-  void OnNewTokenReceived(absl::string_view token) override;
-  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
-  void OnBlockedFrame(const QuicBlockedFrame& frame) override;
-  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                          ConnectionCloseSource source) override;
-  void OnWriteBlocked() override;
-  void OnSuccessfulVersionNegotiation(
-      const ParsedQuicVersion& version) override;
-  void OnPacketReceived(const QuicSocketAddress& self_address,
-                        const QuicSocketAddress& peer_address,
-                        bool is_connectivity_probe) override;
-  void OnCanWrite() override;
-  bool SendProbingData() override;
-  bool ValidateStatelessReset(
-      const quic::QuicSocketAddress& /*self_address*/,
-      const quic::QuicSocketAddress& /*peer_address*/) override {
-    return true;
-  }
-  void OnCongestionWindowChange(QuicTime /*now*/) override {}
-  void OnConnectionMigration(AddressChangeType /*type*/) override {}
-  // Adds a connection level WINDOW_UPDATE frame.
-  void OnAckNeedsRetransmittableFrame() override;
-  void SendAckFrequency(const QuicAckFrequencyFrame& frame) override;
-  void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
-  void SendRetireConnectionId(uint64_t sequence_number) override;
-  void OnServerConnectionIdIssued(
-      const QuicConnectionId& server_connection_id) override;
-  void OnServerConnectionIdRetired(
-      const QuicConnectionId& server_connection_id) override;
-  bool WillingAndAbleToWrite() const override;
-  std::string GetStreamsInfoForLogging() const override;
-  void OnPathDegrading() override;
-  void OnForwardProgressMadeAfterPathDegrading() override;
-  bool AllowSelfAddressChange() const override;
-  HandshakeState GetHandshakeState() const override;
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
-  void OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
-  void OnPacketDecrypted(EncryptionLevel level) override;
-  void OnOneRttPacketAcknowledged() override;
-  void OnHandshakePacketSent() override;
-  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-  void BeforeConnectionCloseSent() override {}
-  bool ValidateToken(absl::string_view token) override;
-  bool MaybeSendAddressToken() override;
-  bool IsKnownServerAddress(
-      const QuicSocketAddress& /*address*/) const override {
-    return false;
-  }
-
-  // QuicStreamFrameDataProducer
-  WriteStreamDataResult WriteStreamData(QuicStreamId id,
-                                        QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        QuicDataWriter* writer) override;
-  bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset,
-                       QuicByteCount data_length,
-                       QuicDataWriter* writer) override;
-
-  // SessionNotifierInterface methods:
-  bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time,
-                    QuicTime receive_timestamp) override;
-  void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override;
-  void OnFrameLost(const QuicFrame& frame) override;
-  bool RetransmitFrames(const QuicFrames& frames,
-                        TransmissionType type) override;
-  bool IsFrameOutstanding(const QuicFrame& frame) const override;
-  bool HasUnackedCryptoData() const override;
-  bool HasUnackedStreamData() const override;
-
-  void SendMaxStreams(QuicStreamCount stream_count,
-                      bool unidirectional) override;
-  // The default implementation does nothing. Subclasses should override if
-  // for example they queue up stream requests.
-  virtual void OnCanCreateNewOutgoingStream(bool /*unidirectional*/) {}
-
-  // Called on every incoming packet. Passes |packet| through to |connection_|.
-  virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
-                                const QuicSocketAddress& peer_address,
-                                const QuicReceivedPacket& packet);
-
-  // Sends |message| as a QUIC DATAGRAM frame (QUIC MESSAGE frame in gQUIC).
-  // See <https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram> for
-  // more details.
-  //
-  // Returns a MessageResult struct which includes the status of the write
-  // operation and a message ID.  The message ID (not sent on the wire) can be
-  // used to track the message; OnMessageAcked and OnMessageLost are called when
-  // a specific message gets acked or lost.
-  //
-  // If the write operation is successful, all of the slices in |message| are
-  // consumed, leaving them empty.  If MESSAGE_STATUS_INTERNAL_ERROR is
-  // returned, the slices in question may or may not be consumed; it is no
-  // longer safe to access those.  For all other status codes, |message| is kept
-  // intact.
-  //
-  // Note that SendMessage will fail with status = MESSAGE_STATUS_BLOCKED
-  // if the connection is congestion control blocked or the underlying socket is
-  // write blocked. In this case the caller can retry sending message again when
-  // connection becomes available, for example after getting OnCanWrite()
-  // callback.
-  //
-  // SendMessage flushes the current packet even it is not full; if the
-  // application needs to bundle other data in the same packet, consider using
-  // QuicConnection::ScopedPacketFlusher around the relevant write operations.
-  MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message);
-
-  // Same as above SendMessage, except caller can specify if the given |message|
-  // should be flushed even if the underlying connection is deemed unwritable.
-  MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message,
-                            bool flush);
-
-  // Single-slice version of SendMessage().  Unlike the version above, this
-  // version always takes ownership of the slice.
-  MessageResult SendMessage(quiche::QuicheMemSlice message);
-
-  // Called when message with |message_id| gets acked.
-  virtual void OnMessageAcked(QuicMessageId message_id,
-                              QuicTime receive_timestamp);
-
-  // Called when message with |message_id| is considered as lost.
-  virtual void OnMessageLost(QuicMessageId message_id);
-
-  // QuicControlFrameManager::DelegateInterface
-  // Close the connection on error.
-  void OnControlFrameManagerError(QuicErrorCode error_code,
-                                  std::string error_details) override;
-  // Called by control frame manager when it wants to write control frames to
-  // the peer. Returns true if |frame| is consumed, false otherwise. The frame
-  // will be sent in specified transmission |type|.
-  bool WriteControlFrame(const QuicFrame& frame,
-                         TransmissionType type) override;
-
-  // Called to send RST_STREAM (and STOP_SENDING) and close stream. If stream
-  // |id| does not exist, just send RST_STREAM (and STOP_SENDING).
-  virtual void ResetStream(QuicStreamId id, QuicRstStreamErrorCode error);
-
-  // Called when the session wants to go away and not accept any new streams.
-  virtual void SendGoAway(QuicErrorCode error_code, const std::string& reason);
-
-  // Sends a BLOCKED frame.
-  virtual void SendBlocked(QuicStreamId id);
-
-  // Sends a WINDOW_UPDATE frame.
-  virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
-
-  // Called by stream |stream_id| when it gets closed.
-  virtual void OnStreamClosed(QuicStreamId stream_id);
-
-  // Returns true if outgoing packets will be encrypted, even if the server
-  // hasn't confirmed the handshake yet.
-  virtual bool IsEncryptionEstablished() const;
-
-  // Returns true if 1RTT keys are available.
-  bool OneRttKeysAvailable() const;
-
-  // Called by the QuicCryptoStream when a new QuicConfig has been negotiated.
-  virtual void OnConfigNegotiated();
-
-  // Called by the TLS handshaker when ALPS data is received.
-  // Returns an error message if an error has occurred, or nullopt otherwise.
-  virtual absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
-                                                 size_t alps_length);
-
-  // From HandshakerDelegateInterface
-  bool OnNewDecryptionKeyAvailable(EncryptionLevel level,
-                                   std::unique_ptr<QuicDecrypter> decrypter,
-                                   bool set_alternative_decrypter,
-                                   bool latch_once_used) override;
-  void OnNewEncryptionKeyAvailable(
-      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
-  void SetDefaultEncryptionLevel(EncryptionLevel level) override;
-  void OnTlsHandshakeComplete() override;
-  void DiscardOldDecryptionKey(EncryptionLevel level) override;
-  void DiscardOldEncryptionKey(EncryptionLevel level) override;
-  void NeuterUnencryptedData() override;
-  void NeuterHandshakeData() override;
-  void OnZeroRttRejected(int reason) override;
-  bool FillTransportParameters(TransportParameters* params) override;
-  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
-                                           bool is_resumption,
-                                           std::string* error_details) override;
-  void OnHandshakeCallbackDone() override;
-  bool PacketFlusherAttached() const override;
-  ParsedQuicVersion parsed_version() const override { return version(); }
-
-  // Implement StreamDelegateInterface.
-  void OnStreamError(QuicErrorCode error_code,
-                     std::string error_details) override;
-  void OnStreamError(QuicErrorCode error_code,
-                     QuicIetfTransportErrorCodes ietf_error,
-                     std::string error_details) override;
-  // Sets priority in the write blocked list.
-  void RegisterStreamPriority(
-      QuicStreamId id, bool is_static,
-      const spdy::SpdyStreamPrecedence& precedence) override;
-  // Clears priority from the write blocked list.
-  void UnregisterStreamPriority(QuicStreamId id, bool is_static) override;
-  // Updates priority on the write blocked list.
-  void UpdateStreamPriority(
-      QuicStreamId id,
-      const spdy::SpdyStreamPrecedence& new_precedence) override;
-
-  // Called by streams when they want to write data to the peer.
-  // Returns a pair with the number of bytes consumed from data, and a boolean
-  // indicating if the fin bit was consumed.  This does not indicate the data
-  // has been sent on the wire: it may have been turned into a packet and queued
-  // if the socket was unexpectedly blocked.
-  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
-                              QuicStreamOffset offset, StreamSendingState state,
-                              TransmissionType type,
-                              EncryptionLevel level) override;
-
-  size_t SendCryptoData(EncryptionLevel level, size_t write_length,
-                        QuicStreamOffset offset,
-                        TransmissionType type) override;
-
-  // Called by the QuicCryptoStream when a handshake message is sent.
-  virtual void OnCryptoHandshakeMessageSent(
-      const CryptoHandshakeMessage& message);
-
-  // Called by the QuicCryptoStream when a handshake message is received.
-  virtual void OnCryptoHandshakeMessageReceived(
-      const CryptoHandshakeMessage& message);
-
-  // Returns mutable config for this session. Returned config is owned
-  // by QuicSession.
-  QuicConfig* config();
-
-  // Returns true if the stream existed previously and has been closed.
-  // Returns false if the stream is still active or if the stream has
-  // not yet been created.
-  bool IsClosedStream(QuicStreamId id);
-
-  QuicConnection* connection() { return connection_; }
-  const QuicConnection* connection() const { return connection_; }
-  const QuicSocketAddress& peer_address() const {
-    return connection_->peer_address();
-  }
-  const QuicSocketAddress& self_address() const {
-    return connection_->self_address();
-  }
-  QuicConnectionId connection_id() const {
-    return connection_->connection_id();
-  }
-
-  // Returns the number of currently open streams, excluding static streams, and
-  // never counting unfinished streams.
-  size_t GetNumActiveStreams() const;
-
-  // Add the stream to the session's write-blocked list because it is blocked by
-  // connection-level flow control but not by its own stream-level flow control.
-  // The stream will be given a chance to write when a connection-level
-  // WINDOW_UPDATE arrives.
-  virtual void MarkConnectionLevelWriteBlocked(QuicStreamId id);
-
-  // Called to close zombie stream |id|.
-  void MaybeCloseZombieStream(QuicStreamId id);
-
-  // Returns true if there is pending handshake data in the crypto stream.
-  // TODO(ianswett): Make this private or remove.
-  bool HasPendingHandshake() const;
-
-  // Returns true if the session has data to be sent, either queued in the
-  // connection, or in a write-blocked stream.
-  bool HasDataToWrite() const;
-
-  // Initiates a path validation on the path described in the given context,
-  // asynchronously calls |result_delegate| upon success or failure.
-  // The initiator should extend QuicPathValidationContext to provide the writer
-  // and ResultDelegate to react upon the validation result.
-  // Example implementations of these for path validation for connection
-  // migration could be:
-  //  class QUIC_EXPORT_PRIVATE PathMigrationContext
-  //      : public QuicPathValidationContext {
-  //   public:
-  //    PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
-  //                         const QuicSocketAddress& self_address,
-  //                         const QuicSocketAddress& peer_address)
-  //        : QuicPathValidationContext(self_address, peer_address),
-  //          alternative_writer_(std::move(writer)) {}
-  //
-  //    QuicPacketWriter* WriterToUse() override {
-  //         return alternative_writer_.get();
-  //    }
-  //
-  //    QuicPacketWriter* ReleaseWriter() {
-  //         return alternative_writer_.release();
-  //    }
-  //
-  //   private:
-  //    std::unique_ptr<QuicPacketWriter> alternative_writer_;
-  //  };
-  //
-  //  class PathMigrationValidationResultDelegate
-  //      : public QuicPathValidator::ResultDelegate {
-  //   public:
-  //    PathMigrationValidationResultDelegate(QuicConnection* connection)
-  //        : QuicPathValidator::ResultDelegate(), connection_(connection) {}
-  //
-  //    void OnPathValidationSuccess(
-  //        std::unique_ptr<QuicPathValidationContext> context) override {
-  //    // Do some work to prepare for migration.
-  //    // ...
-  //
-  //    // Actually migrate to the validated path.
-  //    auto migration_context = std::unique_ptr<PathMigrationContext>(
-  //        static_cast<PathMigrationContext*>(context.release()));
-  //    connection_->MigratePath(migration_context->self_address(),
-  //                          migration_context->peer_address(),
-  //                          migration_context->ReleaseWriter(),
-  //                          /*owns_writer=*/true);
-  //
-  //    // Post-migration actions
-  //    // ...
-  //  }
-  //
-  //    void OnPathValidationFailure(
-  //        std::unique_ptr<QuicPathValidationContext> /*context*/) override {
-  //    // Handle validation failure.
-  //  }
-  //
-  //   private:
-  //    QuicConnection* connection_;
-  //  };
-  void ValidatePath(
-      std::unique_ptr<QuicPathValidationContext> context,
-      std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
-
-  // Return true if there is a path being validated.
-  bool HasPendingPathValidation() const;
-
-  // Switch to the path described in |context| without validating the path.
-  bool MigratePath(const QuicSocketAddress& self_address,
-                   const QuicSocketAddress& peer_address,
-                   QuicPacketWriter* writer, bool owns_writer);
-
-  // Returns the largest payload that will fit into a single MESSAGE frame.
-  // Because overhead can vary during a connection, this method should be
-  // checked for every message.
-  QuicPacketLength GetCurrentLargestMessagePayload() const;
-
-  // Returns the largest payload that will fit into a single MESSAGE frame at
-  // any point during the connection.  This assumes the version and
-  // connection ID lengths do not change.
-  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
-  bool transport_goaway_sent() const { return transport_goaway_sent_; }
-
-  bool transport_goaway_received() const { return transport_goaway_received_; }
-
-  // Returns the Google QUIC error code
-  QuicErrorCode error() const { return on_closed_frame_.quic_error_code; }
-  const std::string& error_details() const {
-    return on_closed_frame_.error_details;
-  }
-  uint64_t transport_close_frame_type() const {
-    return on_closed_frame_.transport_close_frame_type;
-  }
-  QuicConnectionCloseType close_type() const {
-    return on_closed_frame_.close_type;
-  }
-
-  Perspective perspective() const { return perspective_; }
-
-  QuicFlowController* flow_controller() { return &flow_controller_; }
-
-  // Returns true if connection is flow controller blocked.
-  bool IsConnectionFlowControlBlocked() const;
-
-  // Returns true if any stream is flow controller blocked.
-  bool IsStreamFlowControlBlocked();
-
-  size_t max_open_incoming_bidirectional_streams() const;
-  size_t max_open_incoming_unidirectional_streams() const;
-
-  size_t MaxAvailableBidirectionalStreams() const;
-  size_t MaxAvailableUnidirectionalStreams() const;
-
-  // Returns existing stream with id = |stream_id|. If no
-  // such stream exists, and |stream_id| is a peer-created stream id,
-  // then a new stream is created and returned. In all other cases, nullptr is
-  // returned.
-  // Caller does not own the returned stream.
-  QuicStream* GetOrCreateStream(const QuicStreamId stream_id);
-
-  // Mark a stream as draining.
-  void StreamDraining(QuicStreamId id, bool unidirectional);
-
-  // Returns true if this stream should yield writes to another blocked stream.
-  virtual bool ShouldYield(QuicStreamId stream_id);
-
-  // Clean up closed_streams_.
-  void CleanUpClosedStreams();
-
-  const ParsedQuicVersionVector& supported_versions() const {
-    return supported_versions_;
-  }
-
-  QuicStreamId next_outgoing_bidirectional_stream_id() const;
-  QuicStreamId next_outgoing_unidirectional_stream_id() const;
-
-  // Return true if given stream is peer initiated.
-  bool IsIncomingStream(QuicStreamId id) const;
-
-  // Record errors when a connection is closed at the server side, should only
-  // be called from server's perspective.
-  // Noop if |error| is QUIC_NO_ERROR.
-  static void RecordConnectionCloseAtServer(QuicErrorCode error,
-                                            ConnectionCloseSource source);
-
-  QuicTransportVersion transport_version() const {
-    return connection_->transport_version();
-  }
-
-  ParsedQuicVersion version() const { return connection_->version(); }
-
-  bool is_configured() const { return is_configured_; }
-
-  // Called to neuter crypto data of encryption |level|.
-  void NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level);
-
-  // Returns the ALPN values to negotiate on this session.
-  virtual std::vector<std::string> GetAlpnsToOffer() const {
-    // TODO(vasilvv): this currently sets HTTP/3 by default.  Switch all
-    // non-HTTP applications to appropriate ALPNs.
-    return std::vector<std::string>({AlpnForVersion(connection()->version())});
-  }
-
-  // Provided a list of ALPNs offered by the client, selects an ALPN from the
-  // list, or alpns.end() if none of the ALPNs are acceptable.
-  virtual std::vector<absl::string_view>::const_iterator SelectAlpn(
-      const std::vector<absl::string_view>& alpns) const;
-
-  // Called when the ALPN of the connection is established for a connection that
-  // uses TLS handshake.
-  virtual void OnAlpnSelected(absl::string_view alpn);
-
-  // Called on clients by the crypto handshaker to provide application state
-  // necessary for sending application data in 0-RTT. The state provided here is
-  // the same state that was provided to the crypto handshaker in
-  // QuicCryptoStream::SetServerApplicationStateForResumption on a previous
-  // connection. Application protocols that require state to be carried over
-  // from the previous connection to support 0-RTT data must implement this
-  // method to ingest this state. For example, an HTTP/3 QuicSession would
-  // implement this function to process the remembered server SETTINGS and apply
-  // those SETTINGS to 0-RTT data. This function returns true if the application
-  // state has been successfully processed, and false if there was an error
-  // processing the cached state and the connection should be closed.
-  virtual bool ResumeApplicationState(ApplicationState* /*cached_state*/) {
-    return true;
-  }
-
-  // Does actual work of sending RESET_STREAM, if the stream type allows.
-  // Also informs the connection so that pending stream frames can be flushed.
-  virtual void MaybeSendRstStreamFrame(QuicStreamId id,
-                                       QuicResetStreamError error,
-                                       QuicStreamOffset bytes_written);
-
-  // Sends a STOP_SENDING frame if the stream type allows.
-  virtual void MaybeSendStopSendingFrame(QuicStreamId id,
-                                         QuicResetStreamError error);
-
-  // Returns the encryption level to send application data.
-  EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
-
-  const absl::optional<std::string> user_agent_id() const {
-    return user_agent_id_;
-  }
-
-  // TODO(wub): remove saving user-agent to QuicSession.
-  void SetUserAgentId(std::string user_agent_id) {
-    user_agent_id_ = std::move(user_agent_id);
-    connection()->OnUserAgentIdKnown(user_agent_id_.value());
-  }
-
-  void SetSourceAddressTokenToSend(absl::string_view token) {
-    connection()->SetSourceAddressTokenToSend(token);
-  }
-
-  const QuicClock* GetClock() const {
-    return connection()->helper()->GetClock();
-  }
-
-  bool liveness_testing_in_progress() const {
-    return liveness_testing_in_progress_;
-  }
-
-  bool permutes_tls_extensions() const { return permutes_tls_extensions_; }
-
-  virtual QuicSSLConfig GetSSLConfig() const { return QuicSSLConfig(); }
-
-  // Latched value of flag --quic_tls_server_support_client_cert.
-  bool support_client_cert() const { return support_client_cert_; }
-
-  // Try converting all pending streams to normal streams.
-  void ProcessAllPendingStreams();
-
-  const ParsedQuicVersionVector& client_original_supported_versions() const {
-    QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-    return client_original_supported_versions_;
-  }
-  void set_client_original_supported_versions(
-      const ParsedQuicVersionVector& client_original_supported_versions) {
-    QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
-    client_original_supported_versions_ = client_original_supported_versions;
-  }
-
- protected:
-  using StreamMap =
-      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
-
-  using PendingStreamMap =
-      absl::flat_hash_map<QuicStreamId, std::unique_ptr<PendingStream>>;
-
-  using ClosedStreams = std::vector<std::unique_ptr<QuicStream>>;
-
-  using ZombieStreamMap =
-      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
-
-  // Creates a new stream to handle a peer-initiated stream.
-  // Caller does not own the returned stream.
-  // Returns nullptr and does error handling if the stream can not be created.
-  virtual QuicStream* CreateIncomingStream(QuicStreamId id) = 0;
-  virtual QuicStream* CreateIncomingStream(PendingStream* pending) = 0;
-
-  // Return the reserved crypto stream.
-  virtual QuicCryptoStream* GetMutableCryptoStream() = 0;
-
-  // Adds |stream| to the stream map.
-  virtual void ActivateStream(std::unique_ptr<QuicStream> stream);
-
-  // Set transmission type of next sending packets.
-  void SetTransmissionType(TransmissionType type);
-
-  // Returns the stream ID for a new outgoing bidirectional/unidirectional
-  // stream, and increments the underlying counter.
-  QuicStreamId GetNextOutgoingBidirectionalStreamId();
-  QuicStreamId GetNextOutgoingUnidirectionalStreamId();
-
-  // Indicates whether the next outgoing bidirectional/unidirectional stream ID
-  // can be allocated or not. The test for version-99/IETF QUIC is whether it
-  // will exceed the maximum-stream-id or not. For non-version-99 (Google) QUIC
-  // it checks whether the next stream would exceed the limit on the number of
-  // open streams.
-  bool CanOpenNextOutgoingBidirectionalStream();
-  bool CanOpenNextOutgoingUnidirectionalStream();
-
-  // Returns the maximum bidirectional streams parameter sent with the handshake
-  // as a transport parameter, or in the most recent MAX_STREAMS frame.
-  QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const;
-
-  // When a stream is closed locally, it may not yet know how many bytes the
-  // peer sent on that stream.
-  // When this data arrives (via stream frame w. FIN, trailing headers, or RST)
-  // this method is called, and correctly updates the connection level flow
-  // controller.
-  virtual void OnFinalByteOffsetReceived(QuicStreamId id,
-                                         QuicStreamOffset final_byte_offset);
-
-  // Returns true if a frame with the given type and id can be prcoessed by a
-  // PendingStream. However, the frame will always be processed by a QuicStream
-  // if one exists with the given stream_id.
-  virtual bool UsesPendingStreamForFrame(QuicFrameType /*type*/,
-                                         QuicStreamId /*stream_id*/) const {
-    return false;
-  }
-
-  // Returns true if a pending stream should be converted to a real stream after
-  // a corresponding STREAM_FRAME is received.
-  virtual bool ShouldProcessPendingStreamImmediately() const { return true; }
-
-  spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId stream_id) const {
-    return write_blocked_streams_.GetSpdyPriorityofStream(stream_id);
-  }
-
-  size_t pending_streams_size() const { return pending_stream_map_.size(); }
-
-  ClosedStreams* closed_streams() { return &closed_streams_; }
-
-  void set_largest_peer_created_stream_id(
-      QuicStreamId largest_peer_created_stream_id);
-
-  QuicWriteBlockedList* write_blocked_streams() {
-    return &write_blocked_streams_;
-  }
-
-  // Returns true if the stream is still active.
-  bool IsOpenStream(QuicStreamId id);
-
-  // Returns true if the stream is a static stream.
-  bool IsStaticStream(QuicStreamId id) const;
-
-  // Close connection when receive a frame for a locally-created nonexistent
-  // stream.
-  // Prerequisite: IsClosedStream(stream_id) == false
-  // Server session might need to override this method to allow server push
-  // stream to be promised before creating an active stream.
-  virtual void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id);
-
-  virtual bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id);
-
-  void InsertLocallyClosedStreamsHighestOffset(const QuicStreamId id,
-                                               QuicStreamOffset offset);
-  // If stream is a locally closed stream, this RST will update FIN offset.
-  // Otherwise stream is a preserved stream and the behavior of it depends on
-  // derived class's own implementation.
-  virtual void HandleRstOnValidNonexistentStream(
-      const QuicRstStreamFrame& frame);
-
-  // Returns a stateless reset token which will be included in the public reset
-  // packet.
-  virtual StatelessResetToken GetStatelessResetToken() const;
-
-  QuicControlFrameManager& control_frame_manager() {
-    return control_frame_manager_;
-  }
-
-  const LegacyQuicStreamIdManager& stream_id_manager() const {
-    return stream_id_manager_;
-  }
-
-  QuicDatagramQueue* datagram_queue() { return &datagram_queue_; }
-
-  size_t num_static_streams() const { return num_static_streams_; }
-
-  size_t num_zombie_streams() const { return num_zombie_streams_; }
-
-  bool was_zero_rtt_rejected() const { return was_zero_rtt_rejected_; }
-
-  size_t num_outgoing_draining_streams() const {
-    return num_outgoing_draining_streams_;
-  }
-
-  size_t num_draining_streams() const { return num_draining_streams_; }
-
-  // Processes the stream type information of |pending| depending on
-  // different kinds of sessions' own rules. If the pending stream has been
-  // converted to a normal stream, returns a pointer to the new stream;
-  // otherwise, returns nullptr.
-  virtual QuicStream* ProcessPendingStream(PendingStream* /*pending*/) {
-    return nullptr;
-  }
-
-  // Called by applications to perform |action| on active streams.
-  // Stream iteration will be stopped if action returns false.
-  void PerformActionOnActiveStreams(std::function<bool(QuicStream*)> action);
-  void PerformActionOnActiveStreams(
-      std::function<bool(QuicStream*)> action) const;
-
-  // Return the largest peer created stream id depending on directionality
-  // indicated by |unidirectional|.
-  QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
-
-  // Deletes the connection and sets it to nullptr, so calling it mulitiple
-  // times is safe.
-  void DeleteConnection();
-
-  // Call SetPriority() on stream id |id| and return true if stream is active.
-  bool MaybeSetStreamPriority(QuicStreamId stream_id,
-                              const spdy::SpdyStreamPrecedence& precedence);
-
-  void SetLossDetectionTuner(
-      std::unique_ptr<LossDetectionTunerInterface> tuner) {
-    connection()->SetLossDetectionTuner(std::move(tuner));
-  }
-
-  // Find stream with |id|, returns nullptr if the stream does not exist or
-  // closed. static streams and zombie streams are not considered active
-  // streams.
-  QuicStream* GetActiveStream(QuicStreamId id) const;
-
-  const UberQuicStreamIdManager& ietf_streamid_manager() const {
-    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
-    return ietf_streamid_manager_;
-  }
-
-  // Only called at a server session. Generate a CachedNetworkParameters that
-  // can be sent to the client as part of the address token, based on the latest
-  // bandwidth/rtt information. If return absl::nullopt, address token will not
-  // contain the CachedNetworkParameters.
-  virtual absl::optional<CachedNetworkParameters>
-  GenerateCachedNetworkParameters() const {
-    return absl::nullopt;
-  }
-
- private:
-  friend class test::QuicSessionPeer;
-
-  // Called in OnConfigNegotiated when we receive a new stream level flow
-  // control window in a negotiated config. Closes the connection if invalid.
-  void OnNewStreamFlowControlWindow(QuicStreamOffset new_window);
-
-  // Called in OnConfigNegotiated when we receive a new unidirectional stream
-  // flow control window in a negotiated config.
-  void OnNewStreamUnidirectionalFlowControlWindow(QuicStreamOffset new_window);
-
-  // Called in OnConfigNegotiated when we receive a new outgoing bidirectional
-  // stream flow control window in a negotiated config.
-  void OnNewStreamOutgoingBidirectionalFlowControlWindow(
-      QuicStreamOffset new_window);
-
-  // Called in OnConfigNegotiated when we receive a new incoming bidirectional
-  // stream flow control window in a negotiated config.
-  void OnNewStreamIncomingBidirectionalFlowControlWindow(
-      QuicStreamOffset new_window);
-
-  // Called in OnConfigNegotiated when we receive a new connection level flow
-  // control window in a negotiated config. Closes the connection if invalid.
-  void OnNewSessionFlowControlWindow(QuicStreamOffset new_window);
-
-  // Debug helper for |OnCanWrite()|, check that OnStreamWrite() makes
-  // forward progress.  Returns false if busy loop detected.
-  bool CheckStreamNotBusyLooping(QuicStream* stream,
-                                 uint64_t previous_bytes_written,
-                                 bool previous_fin_sent);
-
-  // Debug helper for OnCanWrite. Check that after QuicStream::OnCanWrite(),
-  // if stream has buffered data and is not stream level flow control blocked,
-  // it has to be in the write blocked list.
-  bool CheckStreamWriteBlocked(QuicStream* stream) const;
-
-  // Called in OnConfigNegotiated for Finch trials to measure performance of
-  // starting with larger flow control receive windows.
-  void AdjustInitialFlowControlWindows(size_t stream_window);
-
-  // Find stream with |id|, returns nullptr if the stream does not exist or
-  // closed.
-  QuicStream* GetStream(QuicStreamId id) const;
-
-  // Can return NULL, e.g., if the stream has been closed before.
-  PendingStream* GetOrCreatePendingStream(QuicStreamId stream_id);
-
-  // Let streams and control frame managers retransmit lost data, returns true
-  // if all lost data is retransmitted. Returns false otherwise.
-  bool RetransmitLostData();
-
-  // Returns true if stream data should be written.
-  bool CanWriteStreamData() const;
-
-  // Closes the pending stream |stream_id| before it has been created.
-  void ClosePendingStream(QuicStreamId stream_id);
-
-  // Whether the frame with given type and id should be feed to a pending
-  // stream.
-  bool ShouldProcessFrameByPendingStream(QuicFrameType type,
-                                         QuicStreamId id) const;
-
-  // Process the pending stream if possible.
-  void MaybeProcessPendingStream(PendingStream* pending);
-
-  // Creates or gets pending stream, feeds it with |frame|, and returns the
-  // pending stream. Can return NULL, e.g., if the stream ID is invalid.
-  PendingStream* PendingStreamOnStreamFrame(const QuicStreamFrame& frame);
-
-  // Creates or gets pending strea, feed it with |frame|, and closes the pending
-  // stream.
-  void PendingStreamOnRstStream(const QuicRstStreamFrame& frame);
-
-  // Creates or gets pending stream, feeds it with |frame|, and records the
-  // max_data in the pending stream.
-  void PendingStreamOnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
-
-  // Creates or gets pending stream, feeds it with |frame|, and records the
-  // ietf_error_code in the pending stream.
-  void PendingStreamOnStopSendingFrame(const QuicStopSendingFrame& frame);
-
-  // Keep track of highest received byte offset of locally closed streams, while
-  // waiting for a definitive final highest offset from the peer.
-  absl::flat_hash_map<QuicStreamId, QuicStreamOffset>
-      locally_closed_streams_highest_offset_;
-
-  QuicConnection* connection_;
-
-  // Store perspective on QuicSession during the constructor as it may be needed
-  // during our destructor when connection_ may have already been destroyed.
-  Perspective perspective_;
-
-  // May be null.
-  Visitor* visitor_;
-
-  // A list of streams which need to write more data.  Stream register
-  // themselves in their constructor, and unregisterm themselves in their
-  // destructors, so the write blocked list must outlive all streams.
-  QuicWriteBlockedList write_blocked_streams_;
-
-  ClosedStreams closed_streams_;
-
-  QuicConfig config_;
-
-  // Map from StreamId to pointers to streams. Owns the streams.
-  StreamMap stream_map_;
-
-  // Map from StreamId to PendingStreams for peer-created unidirectional streams
-  // which are waiting for the first byte of payload to arrive.
-  PendingStreamMap pending_stream_map_;
-
-  // TODO(fayang): Consider moving LegacyQuicStreamIdManager into
-  // UberQuicStreamIdManager.
-  // Manages stream IDs for Google QUIC.
-  LegacyQuicStreamIdManager stream_id_manager_;
-
-  // Manages stream IDs for version99/IETF QUIC
-  UberQuicStreamIdManager ietf_streamid_manager_;
-
-  // A counter for streams which have sent and received FIN but waiting for
-  // application to consume data.
-  size_t num_draining_streams_;
-
-  // A counter for self initiated streams which have sent and received FIN but
-  // waiting for application to consume data.
-  size_t num_outgoing_draining_streams_;
-
-  // A counter for static streams which are in stream_map_.
-  size_t num_static_streams_;
-
-  // A counter for streams which have done reading and writing, but are waiting
-  // for acks.
-  size_t num_zombie_streams_;
-
-  // Received information for a connection close.
-  QuicConnectionCloseFrame on_closed_frame_;
-
-  // Used for connection-level flow control.
-  QuicFlowController flow_controller_;
-
-  // The stream id which was last popped in OnCanWrite, or 0, if not under the
-  // call stack of OnCanWrite.
-  QuicStreamId currently_writing_stream_id_;
-
-  // Whether a transport layer GOAWAY frame has been sent.
-  // Such a frame only exists in Google QUIC, therefore |transport_goaway_sent_|
-  // is always false when using IETF QUIC.
-  bool transport_goaway_sent_;
-
-  // Whether a transport layer GOAWAY frame has been received.
-  // Such a frame only exists in Google QUIC, therefore
-  // |transport_goaway_received_| is always false when using IETF QUIC.
-  bool transport_goaway_received_;
-
-  QuicControlFrameManager control_frame_manager_;
-
-  // Id of latest successfully sent message.
-  QuicMessageId last_message_id_;
-
-  // The buffer used to queue the DATAGRAM frames.
-  QuicDatagramQueue datagram_queue_;
-
-  // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
-  // is not used here.
-  // List of streams with pending retransmissions.
-  quiche::QuicheLinkedHashMap<QuicStreamId, bool>
-      streams_with_pending_retransmission_;
-
-  // Clean up closed_streams_ when this alarm fires.
-  std::unique_ptr<QuicAlarm> closed_streams_clean_up_alarm_;
-
-  // Supported version list used by the crypto handshake only. Please note, this
-  // list may be a superset of the connection framer's supported versions.
-  ParsedQuicVersionVector supported_versions_;
-
-  // Only non-empty on the client after receiving a version negotiation packet,
-  // contains the configured versions from the original session before version
-  // negotiation was received.
-  ParsedQuicVersionVector client_original_supported_versions_;
-
-  absl::optional<std::string> user_agent_id_;
-
-  // Initialized to false. Set to true when the session has been properly
-  // configured and is ready for general operation.
-  bool is_configured_;
-
-  // Whether the session has received a 0-RTT rejection (QUIC+TLS only).
-  bool was_zero_rtt_rejected_;
-
-  // This indicates a liveness testing is in progress, and push back the
-  // creation of new outgoing bidirectional streams.
-  bool liveness_testing_in_progress_;
-
-  // Whether BoringSSL randomizes the order of TLS extensions.
-  bool permutes_tls_extensions_ = true;
-
-  const bool support_client_cert_ =
-      GetQuicRestartFlag(quic_tls_server_support_client_cert);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_SESSION_H_
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
deleted file mode 100644
index ee751dc..0000000
--- a/quic/core/quic_session_test.cc
+++ /dev/null
@@ -1,3093 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_session.h"
-
-#include <cstdint>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/frames/quic_max_streams_frame.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_mem_slice_storage.h"
-
-using spdy::kV3HighestPriority;
-using spdy::SpdyPriority;
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtLeast;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::NiceMock;
-using ::testing::Return;
-using ::testing::StrictMock;
-using ::testing::WithArg;
-
-namespace quic {
-namespace test {
-namespace {
-
-class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
- public:
-  explicit TestCryptoStream(QuicSession* session)
-      : QuicCryptoStream(session),
-        QuicCryptoHandshaker(this, session),
-        encryption_established_(false),
-        one_rtt_keys_available_(false),
-        params_(new QuicCryptoNegotiatedParameters) {
-    // Simulate a negotiated cipher_suite with a fake value.
-    params_->cipher_suite = 1;
-  }
-
-  void EstablishZeroRttEncryption() {
-    encryption_established_ = true;
-    session()->connection()->SetEncrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::make_unique<NullEncrypter>(session()->perspective()));
-  }
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
-    encryption_established_ = true;
-    one_rtt_keys_available_ = true;
-    QuicErrorCode error;
-    std::string error_details;
-    session()->config()->SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    session()->config()->SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-    if (session()->version().UsesTls()) {
-      if (session()->perspective() == Perspective::IS_CLIENT) {
-        session()->config()->SetOriginalConnectionIdToSend(
-            session()->connection()->connection_id());
-        session()->config()->SetInitialSourceConnectionIdToSend(
-            session()->connection()->connection_id());
-      } else {
-        session()->config()->SetInitialSourceConnectionIdToSend(
-            session()->connection()->client_connection_id());
-      }
-      TransportParameters transport_parameters;
-      EXPECT_TRUE(
-          session()->config()->FillTransportParameters(&transport_parameters));
-      error = session()->config()->ProcessTransportParameters(
-          transport_parameters, /* is_resumption = */ false, &error_details);
-    } else {
-      CryptoHandshakeMessage msg;
-      session()->config()->ToHandshakeMessage(&msg, transport_version());
-      error =
-          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
-    }
-    EXPECT_THAT(error, IsQuicNoError());
-    session()->OnNewEncryptionKeyAvailable(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(session()->perspective()));
-    session()->OnConfigNegotiated();
-    if (session()->connection()->version().handshake_protocol ==
-        PROTOCOL_TLS1_3) {
-      session()->OnTlsHandshakeComplete();
-    } else {
-      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    }
-    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-  }
-
-  // QuicCryptoStream implementation
-  ssl_early_data_reason_t EarlyDataReason() const override {
-    return ssl_early_data_unknown;
-  }
-  bool encryption_established() const override {
-    return encryption_established_;
-  }
-  bool one_rtt_keys_available() const override {
-    return one_rtt_keys_available_;
-  }
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override {
-    return *params_;
-  }
-  CryptoMessageParser* crypto_message_parser() override {
-    return QuicCryptoHandshaker::crypto_message_parser();
-  }
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnHandshakeDoneReceived() override {}
-  void OnNewTokenReceived(absl::string_view /*token*/) override {}
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_parameters*/)
-      const override {
-    return "";
-  }
-  bool ValidateAddressToken(absl::string_view /*token*/) const override {
-    return true;
-  }
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
-    return nullptr;
-  }
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters /*cached_network_params*/) override {}
-  HandshakeState GetHandshakeState() const override {
-    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
-  }
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
-              AdvanceKeysAndCreateCurrentOneRttDecrypter,
-              (),
-              (override));
-  MOCK_METHOD(std::unique_ptr<QuicEncrypter>,
-              CreateCurrentOneRttEncrypter,
-              (),
-              (override));
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-  bool HasPendingCryptoRetransmission() const override { return false; }
-
-  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-
-  void OnConnectionClosed(QuicErrorCode /*error*/,
-                          ConnectionCloseSource /*source*/) override {}
-
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    return false;
-  }
-
-  SSL* GetSsl() const override { return nullptr; }
-
- private:
-  using QuicCryptoStream::session;
-
-  bool encryption_established_;
-  bool one_rtt_keys_available_;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-};
-
-class TestStream : public QuicStream {
- public:
-  TestStream(QuicStreamId id, QuicSession* session, StreamType type)
-      : TestStream(id, session, /*is_static=*/false, type) {}
-
-  TestStream(QuicStreamId id,
-             QuicSession* session,
-             bool is_static,
-             StreamType type)
-      : QuicStream(id, session, is_static, type) {}
-
-  TestStream(PendingStream* pending, QuicSession* session)
-      : QuicStream(pending, session, /*is_static=*/false) {}
-
-  using QuicStream::CloseWriteSide;
-  using QuicStream::WriteMemSlices;
-
-  void OnDataAvailable() override {}
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-  MOCK_METHOD(bool,
-              RetransmitStreamData,
-              (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
-              (override));
-
-  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
-};
-
-class TestSession : public QuicSession {
- public:
-  explicit TestSession(QuicConnection* connection,
-                       MockQuicSessionVisitor* session_visitor)
-      : QuicSession(connection,
-                    session_visitor,
-                    DefaultQuicConfig(),
-                    CurrentSupportedVersions(),
-                    /*num_expected_unidirectional_static_streams = */ 0),
-        crypto_stream_(this),
-        writev_consumes_all_data_(false),
-        uses_pending_streams_(false),
-        num_incoming_streams_created_(0) {
-    Initialize();
-    this->connection()->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection->perspective()));
-    if (this->connection()->version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(this->connection());
-    }
-  }
-
-  ~TestSession() override { DeleteConnection(); }
-
-  TestCryptoStream* GetMutableCryptoStream() override {
-    return &crypto_stream_;
-  }
-
-  const TestCryptoStream* GetCryptoStream() const override {
-    return &crypto_stream_;
-  }
-
-  TestStream* CreateOutgoingBidirectionalStream() {
-    QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
-    if (id ==
-        QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
-      return nullptr;
-    }
-    TestStream* stream = new TestStream(id, this, BIDIRECTIONAL);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  TestStream* CreateOutgoingUnidirectionalStream() {
-    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
-                                        this, WRITE_UNIDIRECTIONAL);
-    ActivateStream(absl::WrapUnique(stream));
-    return stream;
-  }
-
-  TestStream* CreateIncomingStream(QuicStreamId id) override {
-    // Enforce the limit on the number of open streams.
-    if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
-        stream_id_manager().num_open_incoming_streams() + 1 >
-            max_open_incoming_bidirectional_streams()) {
-      // No need to do this test for version 99; it's done by
-      // QuicSession::GetOrCreateStream.
-      connection()->CloseConnection(
-          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
-          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return nullptr;
-    }
-
-    TestStream* stream = new TestStream(
-        id, this,
-        DetermineStreamType(id, connection()->version(), perspective(),
-                            /*is_incoming=*/true, BIDIRECTIONAL));
-    ActivateStream(absl::WrapUnique(stream));
-    ++num_incoming_streams_created_;
-    return stream;
-  }
-
-  TestStream* CreateIncomingStream(PendingStream* pending) override {
-    TestStream* stream = new TestStream(pending, this);
-    ActivateStream(absl::WrapUnique(stream));
-    ++num_incoming_streams_created_;
-    return stream;
-  }
-
-  // QuicSession doesn't do anything in this method. So it's overridden here to
-  // test that the session handles pending streams correctly in terms of
-  // receiving stream frames.
-  QuicStream* ProcessPendingStream(PendingStream* pending) override {
-    if (pending->is_bidirectional()) {
-      return CreateIncomingStream(pending);
-    }
-    struct iovec iov;
-    if (pending->sequencer()->GetReadableRegion(&iov)) {
-      // Create TestStream once the first byte is received.
-      return CreateIncomingStream(pending);
-    }
-    return nullptr;
-  }
-
-  bool IsClosedStream(QuicStreamId id) {
-    return QuicSession::IsClosedStream(id);
-  }
-
-  QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
-    return QuicSession::GetOrCreateStream(stream_id);
-  }
-
-  bool ShouldKeepConnectionAlive() const override {
-    return GetNumActiveStreams() > 0;
-  }
-
-  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
-                              QuicStreamOffset offset, StreamSendingState state,
-                              TransmissionType type,
-                              EncryptionLevel level) override {
-    bool fin = state != NO_FIN;
-    QuicConsumedData consumed(write_length, fin);
-    if (!writev_consumes_all_data_) {
-      consumed =
-          QuicSession::WritevData(id, write_length, offset, state, type, level);
-    }
-    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
-        id, consumed.bytes_consumed);
-    return consumed;
-  }
-
-  MOCK_METHOD(void,
-              OnCanCreateNewOutgoingStream,
-              (bool unidirectional),
-              (override));
-
-  void set_writev_consumes_all_data(bool val) {
-    writev_consumes_all_data_ = val;
-  }
-
-  QuicConsumedData SendStreamData(QuicStream* stream) {
-    if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
-                                     stream->id()) &&
-        this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
-      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-    }
-    QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
-    QuicConsumedData consumed =
-        WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
-                   GetEncryptionLevelToSendApplicationData());
-    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
-        consumed.bytes_consumed);
-    return consumed;
-  }
-
-  const QuicFrame& save_frame() { return save_frame_; }
-
-  bool SaveFrame(const QuicFrame& frame) {
-    save_frame_ = frame;
-    DeleteFrame(&const_cast<QuicFrame&>(frame));
-    return true;
-  }
-
-  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
-    QUICHE_DCHECK(writev_consumes_all_data_);
-    return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
-                      GetEncryptionLevelToSendApplicationData());
-  }
-
-  bool UsesPendingStreamForFrame(QuicFrameType type,
-                                 QuicStreamId stream_id) const override {
-    if (!uses_pending_streams_) {
-      return false;
-    }
-    // Uses pending stream for STREAM/RST_STREAM frames with unidirectional read
-    // stream and uses pending stream for
-    // STREAM/RST_STREAM/STOP_SENDING/WINDOW_UPDATE frames with bidirectional
-    // stream.
-    bool is_incoming_stream = IsIncomingStream(stream_id);
-    StreamType stream_type = QuicUtils::GetStreamType(
-        stream_id, perspective(), is_incoming_stream, version());
-    switch (type) {
-      case STREAM_FRAME:
-        ABSL_FALLTHROUGH_INTENDED;
-      case RST_STREAM_FRAME:
-        return is_incoming_stream;
-      case STOP_SENDING_FRAME:
-        ABSL_FALLTHROUGH_INTENDED;
-      case WINDOW_UPDATE_FRAME:
-        return stream_type == BIDIRECTIONAL;
-      default:
-        return false;
-    }
-  }
-
-  bool ShouldProcessPendingStreamImmediately() const override {
-    return process_pending_stream_immediately_;
-  }
-
-  void set_uses_pending_streams(bool uses_pending_streams) {
-    uses_pending_streams_ = uses_pending_streams;
-  }
-
-  void set_process_pending_stream_immediately(
-      bool process_pending_stream_immediately) {
-    process_pending_stream_immediately_ = process_pending_stream_immediately;
-  }
-
-  int num_incoming_streams_created() const {
-    return num_incoming_streams_created_;
-  }
-
-  using QuicSession::ActivateStream;
-  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
-  using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
-  using QuicSession::closed_streams;
-  using QuicSession::GetNextOutgoingBidirectionalStreamId;
-  using QuicSession::GetNextOutgoingUnidirectionalStreamId;
-
- private:
-  StrictMock<TestCryptoStream> crypto_stream_;
-
-  bool writev_consumes_all_data_;
-  bool uses_pending_streams_;
-  bool process_pending_stream_immediately_ = true;
-  QuicFrame save_frame_;
-  int num_incoming_streams_created_;
-};
-
-class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  QuicSessionTestBase(Perspective perspective, bool configure_session)
-      : connection_(
-            new StrictMock<MockQuicConnection>(&helper_,
-                                               &alarm_factory_,
-                                               perspective,
-                                               SupportedVersions(GetParam()))),
-        session_(connection_, &session_visitor_),
-        configure_session_(configure_session) {
-    session_.config()->SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    session_.config()->SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-
-    if (configure_session) {
-      if (VersionHasIetfQuicFrames(transport_version())) {
-        EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
-        EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(true)).Times(1);
-      }
-      QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
-          session_.config(), kDefaultMaxStreamsPerConnection);
-      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
-          session_.config(), kDefaultMaxStreamsPerConnection);
-      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-          session_.config(), kMinimumFlowControlSendWindow);
-      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-          session_.config(), kMinimumFlowControlSendWindow);
-      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-          session_.config(), kMinimumFlowControlSendWindow);
-      QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-          session_.config(), kMinimumFlowControlSendWindow);
-      connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-      session_.OnConfigNegotiated();
-    }
-    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
-        .Times(testing::AnyNumber());
-    testing::Mock::VerifyAndClearExpectations(&session_);
-  }
-
-  ~QuicSessionTestBase() {
-    if (configure_session_) {
-      EXPECT_TRUE(session_.is_configured());
-    }
-  }
-
-  void CheckClosedStreams() {
-    QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-        connection_->transport_version(), Perspective::IS_CLIENT);
-    if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-      first_stream_id =
-          QuicUtils::GetCryptoStreamId(connection_->transport_version());
-    }
-    for (QuicStreamId i = first_stream_id; i < 100; i++) {
-      if (closed_streams_.find(i) == closed_streams_.end()) {
-        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
-      } else {
-        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
-      }
-    }
-  }
-
-  void CloseStream(QuicStreamId id) {
-    if (VersionHasIetfQuicFrames(transport_version())) {
-      if (QuicUtils::GetStreamType(
-              id, session_.perspective(), session_.IsIncomingStream(id),
-              connection_->version()) == READ_UNIDIRECTIONAL) {
-        // Verify STOP_SENDING but no RESET_STREAM is sent for
-        // READ_UNIDIRECTIONAL streams.
-        EXPECT_CALL(*connection_, SendControlFrame(_))
-            .Times(1)
-            .WillOnce(Invoke(&ClearControlFrame));
-        EXPECT_CALL(*connection_, OnStreamReset(id, _)).Times(1);
-      } else if (QuicUtils::GetStreamType(
-                     id, session_.perspective(), session_.IsIncomingStream(id),
-                     connection_->version()) == WRITE_UNIDIRECTIONAL) {
-        // Verify RESET_STREAM but not STOP_SENDING is sent for write-only
-        // stream.
-        EXPECT_CALL(*connection_, SendControlFrame(_))
-            .Times(1)
-            .WillOnce(Invoke(&ClearControlFrame));
-        EXPECT_CALL(*connection_, OnStreamReset(id, _));
-      } else {
-        // Verify RESET_STREAM and STOP_SENDING are sent for BIDIRECTIONAL
-        // streams.
-        EXPECT_CALL(*connection_, SendControlFrame(_))
-            .Times(2)
-            .WillRepeatedly(Invoke(&ClearControlFrame));
-        EXPECT_CALL(*connection_, OnStreamReset(id, _));
-      }
-    } else {
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .WillOnce(Invoke(&ClearControlFrame));
-      EXPECT_CALL(*connection_, OnStreamReset(id, _));
-    }
-    session_.ResetStream(id, QUIC_STREAM_CANCELLED);
-    closed_streams_.insert(id);
-  }
-
-  void CompleteHandshake() {
-    CryptoHandshakeMessage msg;
-    if (connection_->version().UsesTls() &&
-        connection_->perspective() == Perspective::IS_SERVER) {
-      // HANDSHAKE_DONE frame.
-      EXPECT_CALL(*connection_, SendControlFrame(_))
-          .WillOnce(Invoke(&ClearControlFrame));
-    }
-    session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
-  }
-
-  QuicTransportVersion transport_version() const {
-    return connection_->transport_version();
-  }
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return QuicUtils::GetFirstBidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_CLIENT) +
-           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
-  }
-
-  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
-    return QuicUtils::GetFirstUnidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_CLIENT) +
-           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
-  }
-
-  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
-    return QuicUtils::GetFirstBidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_SERVER) +
-           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
-  }
-
-  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
-    return QuicUtils::GetFirstUnidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_SERVER) +
-           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
-  }
-
-  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
-                               Perspective perspective,
-                               bool bidirectional) {
-    // Calculate and build up stream ID rather than use
-    // GetFirst... because tests that rely on this method
-    // needs to do the stream count where #1 is 0/1/2/3, and not
-    // take into account that stream 0 is special.
-    QuicStreamId id =
-        ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
-    if (!bidirectional) {
-      id |= 0x2;
-    }
-    if (perspective == Perspective::IS_SERVER) {
-      id |= 0x1;
-    }
-    return id;
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  NiceMock<MockQuicSessionVisitor> session_visitor_;
-  StrictMock<MockQuicConnection>* connection_;
-  TestSession session_;
-  std::set<QuicStreamId> closed_streams_;
-  bool configure_session_;
-};
-
-class QuicSessionTestServer : public QuicSessionTestBase {
- public:
-  // CheckMultiPathResponse validates that a written packet
-  // contains both expected path responses.
-  WriteResult CheckMultiPathResponse(const char* buffer,
-                                     size_t buf_len,
-                                     const QuicIpAddress& /*self_address*/,
-                                     const QuicSocketAddress& /*peer_address*/,
-                                     PerPacketOptions* /*options*/) {
-    QuicEncryptedPacket packet(buffer, buf_len);
-    {
-      InSequence s;
-      EXPECT_CALL(framer_visitor_, OnPacket());
-      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
-      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
-      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
-      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
-      EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
-          .WillOnce(
-              WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
-                EXPECT_EQ(path_frame_buffer1_, frame.data_buffer);
-                return true;
-              })));
-      EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
-          .WillOnce(
-              WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
-                EXPECT_EQ(path_frame_buffer2_, frame.data_buffer);
-                return true;
-              })));
-      EXPECT_CALL(framer_visitor_, OnPacketComplete());
-    }
-    client_framer_.ProcessPacket(packet);
-    return WriteResult(WRITE_STATUS_OK, 0);
-  }
-
- protected:
-  QuicSessionTestServer()
-      : QuicSessionTestBase(Perspective::IS_SERVER, /*configure_session=*/true),
-        path_frame_buffer1_({0, 1, 2, 3, 4, 5, 6, 7}),
-        path_frame_buffer2_({8, 9, 10, 11, 12, 13, 14, 15}),
-        client_framer_(SupportedVersions(GetParam()),
-                       QuicTime::Zero(),
-                       Perspective::IS_CLIENT,
-                       kQuicDefaultConnectionIdLength) {
-    client_framer_.set_visitor(&framer_visitor_);
-    client_framer_.SetInitialObfuscators(TestConnectionId());
-    if (client_framer_.version().KnowsWhichDecrypterToUse()) {
-      client_framer_.InstallDecrypter(
-          ENCRYPTION_FORWARD_SECURE,
-          std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
-    }
-  }
-
-  QuicPathFrameBuffer path_frame_buffer1_;
-  QuicPathFrameBuffer path_frame_buffer2_;
-  StrictMock<MockFramerVisitor> framer_visitor_;
-  // Framer used to process packets sent by server.
-  QuicFramer client_framer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicSessionTestServer,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSessionTestServer, PeerAddress) {
-  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
-            session_.peer_address());
-}
-
-TEST_P(QuicSessionTestServer, SelfAddress) {
-  EXPECT_TRUE(session_.self_address().IsInitialized());
-}
-
-TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) {
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  connection_->CloseConnection(QUIC_NO_ERROR, "Everything is fine.",
-                               ConnectionCloseBehavior::SILENT_CLOSE);
-  ASSERT_FALSE(connection_->connected());
-
-  EXPECT_CALL(session_visitor_, OnWriteBlocked(_)).Times(0);
-  session_.OnWriteBlocked();
-}
-
-TEST_P(QuicSessionTestServer, OneRttKeysAvailable) {
-  EXPECT_FALSE(session_.OneRttKeysAvailable());
-  CompleteHandshake();
-  EXPECT_TRUE(session_.OneRttKeysAvailable());
-}
-
-TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
-  // Ensure that no streams are initially closed.
-  QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      connection_->transport_version(), Perspective::IS_CLIENT);
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    first_stream_id =
-        QuicUtils::GetCryptoStreamId(connection_->transport_version());
-  }
-  for (QuicStreamId i = first_stream_id; i < 100; i++) {
-    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
-  }
-}
-
-TEST_P(QuicSessionTestServer, AvailableBidirectionalStreams) {
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedBidirectionalId(3)) != nullptr);
-  // Smaller bidirectional streams should be available.
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedBidirectionalId(1)));
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedBidirectionalId(2)));
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
-}
-
-TEST_P(QuicSessionTestServer, AvailableUnidirectionalStreams) {
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedUnidirectionalId(3)) != nullptr);
-  // Smaller unidirectional streams should be available.
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedUnidirectionalId(1)));
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedUnidirectionalId(2)));
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedUnidirectionalId(2)) != nullptr);
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthClientInitiatedUnidirectionalId(1)) != nullptr);
-}
-
-TEST_P(QuicSessionTestServer, MaxAvailableBidirectionalStreams) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_EQ(session_.max_open_incoming_bidirectional_streams(),
-              session_.MaxAvailableBidirectionalStreams());
-  } else {
-    // The protocol specification requires that there can be at least 10 times
-    // as many available streams as the connection's maximum open streams.
-    EXPECT_EQ(session_.max_open_incoming_bidirectional_streams() *
-                  kMaxAvailableStreamsMultiplier,
-              session_.MaxAvailableBidirectionalStreams());
-  }
-}
-
-TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_EQ(session_.max_open_incoming_unidirectional_streams(),
-              session_.MaxAvailableUnidirectionalStreams());
-  } else {
-    // The protocol specification requires that there can be at least 10 times
-    // as many available streams as the connection's maximum open streams.
-    EXPECT_EQ(session_.max_open_incoming_unidirectional_streams() *
-                  kMaxAvailableStreamsMultiplier,
-              session_.MaxAvailableUnidirectionalStreams());
-  }
-}
-
-TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
-  CompleteHandshake();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
-
-  CheckClosedStreams();
-  CloseStream(GetNthServerInitiatedBidirectionalId(0));
-  CheckClosedStreams();
-  CloseStream(GetNthServerInitiatedBidirectionalId(1));
-  CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
-  CompleteHandshake();
-  TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
-  EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
-  TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
-  EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(1), stream4->id());
-
-  CheckClosedStreams();
-  CloseStream(GetNthServerInitiatedUnidirectionalId(0));
-  CheckClosedStreams();
-  CloseStream(GetNthServerInitiatedUnidirectionalId(1));
-  CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
-  CompleteHandshake();
-  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
-  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
-  session_.GetOrCreateStream(stream_id1);
-  session_.GetOrCreateStream(stream_id2);
-
-  CheckClosedStreams();
-  CloseStream(stream_id1);
-  CheckClosedStreams();
-  CloseStream(stream_id2);
-  // Create a stream, and make another available.
-  QuicStream* stream3 = session_.GetOrCreateStream(
-      stream_id2 +
-      2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
-  CheckClosedStreams();
-  // Close one, but make sure the other is still not closed
-  CloseStream(stream3->id());
-  CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
-  CompleteHandshake();
-  QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
-  QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
-  session_.GetOrCreateStream(stream_id1);
-  session_.GetOrCreateStream(stream_id2);
-
-  CheckClosedStreams();
-  CloseStream(stream_id1);
-  CheckClosedStreams();
-  CloseStream(stream_id2);
-  // Create a stream, and make another available.
-  QuicStream* stream3 = session_.GetOrCreateStream(
-      stream_id2 +
-      2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
-  CheckClosedStreams();
-  // Close one, but make sure the other is still not closed
-  CloseStream(stream3->id());
-  CheckClosedStreams();
-}
-
-TEST_P(QuicSessionTestServer, MaximumAvailableOpenedBidirectionalStreams) {
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  session_.GetOrCreateStream(stream_id);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_NE(nullptr,
-            session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(
-                session_.max_open_incoming_bidirectional_streams() - 1)));
-}
-
-TEST_P(QuicSessionTestServer, MaximumAvailableOpenedUnidirectionalStreams) {
-  QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
-  session_.GetOrCreateStream(stream_id);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_NE(nullptr,
-            session_.GetOrCreateStream(GetNthClientInitiatedUnidirectionalId(
-                session_.max_open_incoming_unidirectional_streams() - 1)));
-}
-
-TEST_P(QuicSessionTestServer, TooManyAvailableBidirectionalStreams) {
-  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
-  QuicStreamId stream_id2;
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
-  // A stream ID which is too large to create.
-  stream_id2 = GetNthClientInitiatedBidirectionalId(
-      session_.MaxAvailableBidirectionalStreams() + 2);
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // IETF QUIC terminates the connection with invalid stream id
-    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
-  } else {
-    // other versions terminate the connection with
-    // QUIC_TOO_MANY_AVAILABLE_STREAMS.
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
-  }
-  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
-}
-
-TEST_P(QuicSessionTestServer, TooManyAvailableUnidirectionalStreams) {
-  QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
-  QuicStreamId stream_id2;
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
-  // A stream ID which is too large to create.
-  stream_id2 = GetNthClientInitiatedUnidirectionalId(
-      session_.MaxAvailableUnidirectionalStreams() + 2);
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // IETF QUIC terminates the connection with invalid stream id
-    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
-  } else {
-    // other versions terminate the connection with
-    // QUIC_TOO_MANY_AVAILABLE_STREAMS.
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
-  }
-  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
-}
-
-TEST_P(QuicSessionTestServer, ManyAvailableBidirectionalStreams) {
-  // When max_open_streams_ is 200, should be able to create 200 streams
-  // out-of-order, that is, creating the one with the largest stream ID first.
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
-    // Smaller limit on unidirectional streams to help detect crossed wires.
-    QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 50);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
-  }
-  // Create a stream at the start of the range.
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-
-  // Create the largest stream ID of a threatened total of 200 streams.
-  // GetNth... starts at 0, so for 200 streams, get the 199th.
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(
-                         GetNthClientInitiatedBidirectionalId(199)));
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // If IETF QUIC, check to make sure that creating bidirectional
-    // streams does not mess up the unidirectional streams.
-    stream_id = GetNthClientInitiatedUnidirectionalId(0);
-    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-    // Now try to get the last possible unidirectional stream.
-    EXPECT_NE(nullptr, session_.GetOrCreateStream(
-                           GetNthClientInitiatedUnidirectionalId(49)));
-    // and this should fail because it exceeds the unidirectional limit
-    // (but not the bi-)
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_INVALID_STREAM_ID,
-                        "Stream id 798 would exceed stream count limit 50",
-                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
-        .Times(1);
-    EXPECT_EQ(nullptr, session_.GetOrCreateStream(
-                           GetNthClientInitiatedUnidirectionalId(199)));
-  }
-}
-
-TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) {
-  // When max_open_streams_ is 200, should be able to create 200 streams
-  // out-of-order, that is, creating the one with the largest stream ID first.
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 200);
-    // Smaller limit on unidirectional streams to help detect crossed wires.
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 50);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
-  }
-  // Create one stream.
-  QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-
-  // Create the largest stream ID of a threatened total of 200 streams.
-  // GetNth... starts at 0, so for 200 streams, get the 199th.
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_NE(nullptr, session_.GetOrCreateStream(
-                         GetNthClientInitiatedUnidirectionalId(199)));
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // If IETF QUIC, check to make sure that creating unidirectional
-    // streams does not mess up the bidirectional streams.
-    stream_id = GetNthClientInitiatedBidirectionalId(0);
-    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
-    // Now try to get the last possible bidirectional stream.
-    EXPECT_NE(nullptr, session_.GetOrCreateStream(
-                           GetNthClientInitiatedBidirectionalId(49)));
-    // and this should fail because it exceeds the bnidirectional limit
-    // (but not the uni-)
-    std::string error_detail;
-    if (QuicVersionUsesCryptoFrames(transport_version())) {
-      error_detail = "Stream id 796 would exceed stream count limit 50";
-    } else {
-      error_detail = "Stream id 800 would exceed stream count limit 50";
-    }
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_INVALID_STREAM_ID, error_detail,
-                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
-        .Times(1);
-    EXPECT_EQ(nullptr, session_.GetOrCreateStream(
-                           GetNthClientInitiatedBidirectionalId(199)));
-  }
-}
-
-TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
-  CompleteHandshake();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId closed_stream_id = stream2->id();
-  // Close the stream.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
-  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-  std::string msg =
-      absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
-  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
-                  msg);
-}
-
-TEST_P(QuicSessionTestServer, OnCanWrite) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  InSequence s;
-
-  // Reregister, to test the loop limit.
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  // 2 will get called a second time as it didn't finish its block
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
-    session_.SendStreamData(stream6);
-  }));
-  // 4 will not get called, as we exceeded the loop limit.
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, TestBatchedWrites) {
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.set_writev_consumes_all_data(true);
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  // With two sessions blocked, we should get two write calls.  They should both
-  // go to the first stream as it will only write 6k and mark itself blocked
-  // again.
-  InSequence s;
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  session_.OnCanWrite();
-
-  // We should get one more call for stream2, at which point it has used its
-  // write quota and we move over to stream 4.
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendLargeFakeData(stream4, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  }));
-  session_.OnCanWrite();
-
-  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
-  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
-  // will cede back to 4.
-  stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  EXPECT_CALL(*stream4, OnCanWrite())
-      .WillOnce(Invoke([this, stream4, stream6]() {
-        session_.SendLargeFakeData(stream4, 6000);
-        session_.MarkConnectionLevelWriteBlocked(stream4->id());
-        session_.MarkConnectionLevelWriteBlocked(stream6->id());
-      }));
-  EXPECT_CALL(*stream6, OnCanWrite())
-      .WillOnce(Invoke([this, stream4, stream6]() {
-        session_.SendStreamData(stream6);
-        session_.SendLargeFakeData(stream4, 6000);
-      }));
-  session_.OnCanWrite();
-
-  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
-  // cede and 2 should resume.
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendLargeFakeData(stream4, 12000);
-    session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  }));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendLargeFakeData(stream2, 6000);
-    session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  }));
-  session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
-  // Encryption needs to be established before data can be sent.
-  CompleteHandshake();
-  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
-      QuicConnectionPeer::GetWriter(session_.connection()));
-
-  // Drive congestion control manually.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
-      .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
-  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-  }));
-  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
-    session_.SendStreamData(stream6);
-  }));
-
-  // Expect that we only send one packet, the writes from different streams
-  // should be bundled together.
-  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  InSequence s;
-
-  // Drive congestion control manually.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
-    session_.SendStreamData(stream6);
-  }));
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
-  // stream4->OnCanWrite is not called.
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // Still congestion-control blocked.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // stream4->OnCanWrite is called once the connection stops being
-  // congestion-control blocked.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-  }));
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
-  CompleteHandshake();
-  // Drive congestion control manually in order to ensure that
-  // application-limited signaling is handled correctly.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
-  // Drive packet writer manually.
-  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
-      QuicConnectionPeer::GetWriter(session_.connection()));
-  EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-
-  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, SendStreamsBlocked) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
-    ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
-    session_.GetNextOutgoingBidirectionalStreamId();
-  }
-  // Next checking causes STREAMS_BLOCKED to be sent.
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke([](const QuicFrame& frame) {
-        EXPECT_FALSE(frame.streams_blocked_frame.unidirectional);
-        EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-                  frame.streams_blocked_frame.stream_count);
-        ClearControlFrame(frame);
-        return true;
-      }));
-  EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
-
-  for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
-    ASSERT_TRUE(session_.CanOpenNextOutgoingUnidirectionalStream());
-    session_.GetNextOutgoingUnidirectionalStreamId();
-  }
-  // Next checking causes STREAM_BLOCKED to be sent.
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke([](const QuicFrame& frame) {
-        EXPECT_TRUE(frame.streams_blocked_frame.unidirectional);
-        EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-                  frame.streams_blocked_frame.stream_count);
-        ClearControlFrame(frame);
-        return true;
-      }));
-  EXPECT_FALSE(session_.CanOpenNextOutgoingUnidirectionalStream());
-}
-
-TEST_P(QuicSessionTestServer, BufferedHandshake) {
-  // This test is testing behavior of crypto stream flow control, but when
-  // CRYPTO frames are used, there is no flow control for the crypto handshake.
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  session_.set_writev_consumes_all_data(true);
-  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
-
-  // Test that blocking other streams does not change our status.
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  EXPECT_FALSE(session_.HasPendingHandshake());
-
-  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream3->id());
-  EXPECT_FALSE(session_.HasPendingHandshake());
-
-  // Blocking (due to buffering of) the Crypto stream is detected.
-  session_.MarkConnectionLevelWriteBlocked(
-      QuicUtils::GetCryptoStreamId(connection_->transport_version()));
-  EXPECT_TRUE(session_.HasPendingHandshake());
-
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  EXPECT_TRUE(session_.HasPendingHandshake());
-
-  InSequence s;
-  // Force most streams to re-register, which is common scenario when we block
-  // the Crypto stream, and only the crypto stream can "really" write.
-
-  // Due to prioritization, we *should* be asked to write the crypto stream
-  // first.
-  // Don't re-register the crypto stream (which signals complete writing).
-  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-  EXPECT_CALL(*crypto_stream, OnCanWrite());
-
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
-    session_.SendStreamData(stream3);
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-    session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  }));
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  CloseStream(stream6->id());
-
-  InSequence s;
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
-    session_.SendStreamData(stream2);
-  }));
-  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
-    session_.SendStreamData(stream4);
-  }));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
-  // Drive congestion control manually in order to ensure that
-  // application-limited signaling is handled correctly.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
-
-  // Ensure connection level flow control blockage.
-  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
-  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
-  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-
-  // Mark the crypto and headers streams as write blocked, we expect them to be
-  // allowed to write later.
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    session_.MarkConnectionLevelWriteBlocked(
-        QuicUtils::GetCryptoStreamId(connection_->transport_version()));
-  }
-
-  // Create a data stream, and although it is write blocked we never expect it
-  // to be allowed to write as we are connection level flow control blocked.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  session_.MarkConnectionLevelWriteBlocked(stream->id());
-  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
-
-  // The crypto and headers streams should be called even though we are
-  // connection flow control blocked.
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-    EXPECT_CALL(*crypto_stream, OnCanWrite());
-  }
-
-  // After the crypto and header streams perform a write, the connection will be
-  // blocked by the flow control, hence it should become application-limited.
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, SendGoAway) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
-    return;
-  }
-  CompleteHandshake();
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
-      QuicConnectionPeer::GetWriter(session_.connection()));
-  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-  EXPECT_TRUE(session_.transport_goaway_sent());
-
-  const QuicStreamId kTestStreamId = 5u;
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  EXPECT_CALL(*connection_,
-              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
-      .Times(0);
-  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
-}
-
-TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
-  CompleteHandshake();
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
-    return;
-  }
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-  EXPECT_TRUE(session_.transport_goaway_sent());
-  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
-}
-
-TEST_P(QuicSessionTestServer, InvalidGoAway) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
-    return;
-  }
-  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
-                          session_.next_outgoing_bidirectional_stream_id(), "");
-  session_.OnGoAway(go_away);
-}
-
-// Test that server session will send a connectivity probe in response to a
-// connectivity probe on the same path.
-TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  QuicSocketAddress old_peer_address =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
-  EXPECT_EQ(old_peer_address, session_.peer_address());
-
-  QuicSocketAddress new_peer_address =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
-
-  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
-      QuicConnectionPeer::GetWriter(session_.connection()));
-  EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
-    EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _))
-        .WillOnce(
-            Invoke(connection_,
-                   &MockQuicConnection::ReallySendConnectivityProbingPacket));
-  session_.OnPacketReceived(session_.self_address(), new_peer_address,
-                            /*is_connectivity_probe=*/true);
-  EXPECT_EQ(old_peer_address, session_.peer_address());
-}
-
-TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
-  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
-            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
-  CompleteHandshake();
-  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
-            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
-}
-
-TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
-  if (VersionUsesHttp3(connection_->transport_version())) {
-    // The test relies on headers stream, which no longer exists in IETF QUIC.
-    return;
-  }
-  QuicStreamId headers_stream_id =
-      QuicUtils::GetHeadersStreamId(connection_->transport_version());
-  std::unique_ptr<TestStream> fake_headers_stream =
-      std::make_unique<TestStream>(headers_stream_id, &session_,
-                                   /*is_static*/ true, BIDIRECTIONAL);
-  QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream));
-  // Send two bytes of payload.
-  QuicStreamFrame data1(headers_stream_id, true, 0, absl::string_view("HT"));
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
-  // Send two bytes of payload.
-  QuicStreamFrame data1(
-      QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
-      absl::string_view("HT"));
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
-  // Send two bytes of payload.
-  QuicRstStreamFrame rst1(
-      kInvalidControlFrameId,
-      QuicUtils::GetInvalidStreamId(connection_->transport_version()),
-      QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
-                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-  session_.OnRstStream(rst1);
-}
-
-TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
-  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
-    // This test requires Google QUIC crypto because it assumes streams start
-    // off unblocked.
-    return;
-  }
-  // Test that if a stream is flow control blocked, then on receipt of the SHLO
-  // containing a suitable send window offset, the stream becomes unblocked.
-
-  // Ensure that Writev consumes all the data it is given (simulate no socket
-  // blocking).
-  session_.set_writev_consumes_all_data(true);
-  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
-
-  // Create a stream, and send enough data to make it flow control blocked.
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  std::string body(kMinimumFlowControlSendWindow, '.');
-  EXPECT_FALSE(stream2->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
-  stream2->WriteOrBufferData(body, false, nullptr);
-  EXPECT_TRUE(stream2->IsFlowControlBlocked());
-  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
-  // Now complete the crypto handshake, resulting in an increased flow control
-  // send window.
-  CompleteHandshake();
-  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
-  // Stream is now unblocked.
-  EXPECT_FALSE(stream2->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
-  CompleteHandshake();
-  // Test that when we receive an out of order stream RST we correctly adjust
-  // our connection level flow control receive window.
-  // On close, the stream should mark as consumed all bytes between the highest
-  // byte consumed so far and the final byte offset from the RST frame.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
-  const QuicStreamOffset kByteOffset =
-      1 + kInitialSessionFlowControlWindowForTest / 2;
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(2)
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
-                               QUIC_STREAM_CANCELLED, kByteOffset);
-  session_.OnRstStream(rst_frame);
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // The test requires the stream to be fully closed in both directions. For
-    // IETF QUIC, the RST_STREAM only closes one side.
-    QuicStopSendingFrame frame(kInvalidControlFrameId, stream->id(),
-                               QUIC_STREAM_CANCELLED);
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-    session_.OnStopSendingFrame(frame);
-  }
-  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
-  CompleteHandshake();
-  // Test the situation where we receive a FIN on a stream, and before we fully
-  // consume all the data from the sequencer buffer we locally RST the stream.
-  // The bytes between highest consumed byte, and the final byte offset that we
-  // determined when the FIN arrived, should be marked as consumed at the
-  // connection level flow controller when the stream is reset.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
-  const QuicStreamOffset kByteOffset =
-      kInitialSessionFlowControlWindowForTest / 2 - 1;
-  QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
-  session_.OnStreamFrame(frame);
-  EXPECT_TRUE(connection_->connected());
-
-  EXPECT_EQ(0u, session_.flow_controller()->bytes_consumed());
-  EXPECT_EQ(kByteOffset + frame.data_length,
-            stream->highest_received_byte_offset());
-
-  // Reset stream locally.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  stream->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_EQ(kByteOffset + frame.data_length,
-            session_.flow_controller()->bytes_consumed());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
-  CompleteHandshake();
-  // Test that when we RST the stream (and tear down stream state), and then
-  // receive a FIN from the peer, we correctly adjust our connection level flow
-  // control receive window.
-
-  // Connection starts with some non-zero highest received byte offset,
-  // due to other active streams.
-  const uint64_t kInitialConnectionBytesConsumed = 567;
-  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
-  EXPECT_LT(kInitialConnectionBytesConsumed,
-            kInitialConnectionHighestReceivedOffset);
-  session_.flow_controller()->UpdateHighestReceivedOffset(
-      kInitialConnectionHighestReceivedOffset);
-  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
-
-  // Reset our stream: this results in the stream being closed locally.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  stream->Reset(QUIC_STREAM_CANCELLED);
-
-  // Now receive a response from the peer with a FIN. We should handle this by
-  // adjusting the connection level flow control receive window to take into
-  // account the total number of bytes sent by the peer.
-  const QuicStreamOffset kByteOffset = 5678;
-  std::string body = "hello";
-  QuicStreamFrame frame(stream->id(), true, kByteOffset,
-                        absl::string_view(body));
-  session_.OnStreamFrame(frame);
-
-  QuicStreamOffset total_stream_bytes_sent_by_peer =
-      kByteOffset + body.length();
-  EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
-            session_.flow_controller()->bytes_consumed());
-  EXPECT_EQ(
-      kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
-      session_.flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
-  CompleteHandshake();
-  // Test that when we RST the stream (and tear down stream state), and then
-  // receive a RST from the peer, we correctly adjust our connection level flow
-  // control receive window.
-
-  // Connection starts with some non-zero highest received byte offset,
-  // due to other active streams.
-  const uint64_t kInitialConnectionBytesConsumed = 567;
-  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
-  EXPECT_LT(kInitialConnectionBytesConsumed,
-            kInitialConnectionHighestReceivedOffset);
-  session_.flow_controller()->UpdateHighestReceivedOffset(
-      kInitialConnectionHighestReceivedOffset);
-  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
-
-  // Reset our stream: this results in the stream being closed locally.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  stream->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
-
-  // Now receive a RST from the peer. We should handle this by adjusting the
-  // connection level flow control receive window to take into account the total
-  // number of bytes sent by the peer.
-  const QuicStreamOffset kByteOffset = 5678;
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
-                               QUIC_STREAM_CANCELLED, kByteOffset);
-  session_.OnRstStream(rst_frame);
-
-  EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
-            session_.flow_controller()->bytes_consumed());
-  EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
-            session_.flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
-  // Test that receipt of an invalid (< default) stream flow control window from
-  // the peer results in the connection being torn down.
-  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
-  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
-                                                            kInvalidWindow);
-
-  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
-  } else {
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  }
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-}
-
-// Test negotiation of custom server initial flow control window.
-TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
-  QuicTagVector copt;
-  copt.push_back(kIFW7);
-  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
-
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
-                             session_.flow_controller()));
-}
-
-TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
-  CompleteHandshake();
-  // Test that if we receive a stream RST with a highest byte offset that
-  // violates flow control, that we close the connection.
-  const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
-      .Times(2);
-
-  // Check that stream frame + FIN results in connection close.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  stream->Reset(QUIC_STREAM_CANCELLED);
-  QuicStreamFrame frame(stream->id(), true, kLargeOffset, absl::string_view());
-  session_.OnStreamFrame(frame);
-
-  // Check that RST results in connection close.
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
-                               QUIC_STREAM_CANCELLED, kLargeOffset);
-  session_.OnRstStream(rst_frame);
-}
-
-TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
-  CompleteHandshake();
-  // If a buggy/malicious peer creates too many streams that are not ended
-  // with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the
-  // connection is closed.
-  const QuicStreamId kMaxStreams = 5;
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
-                                                            kMaxStreams);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
-  }
-  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
-  const QuicStreamId kFinalStreamId =
-      GetNthClientInitiatedBidirectionalId(kMaxStreams);
-  // Create kMaxStreams data streams, and close them all without receiving a
-  // FIN or a RST_STREAM from the client.
-  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
-       i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
-    QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
-    session_.OnStreamFrame(data1);
-    CloseStream(i);
-  }
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(
-        *connection_,
-        CloseConnection(QUIC_INVALID_STREAM_ID,
-                        "Stream id 20 would exceed stream count limit 5", _));
-  } else {
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-    EXPECT_CALL(*connection_,
-                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
-        .Times(1);
-  }
-  // Create one more data streams to exceed limit of open stream.
-  QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-}
-
-TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) {
-  // Verify that a draining stream (which has received a FIN but not consumed
-  // it) does not count against the open quota (because it is closed from the
-  // protocol point of view).
-  CompleteHandshake();
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId stream_id = stream->id();
-  QuicStreamFrame data1(stream_id, true, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
-  }
-  session_.StreamDraining(stream_id, /*unidirectional=*/false);
-}
-
-TEST_P(QuicSessionTestServer, NoPendingStreams) {
-  session_.set_uses_pending_streams(false);
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_EQ(1, session_.num_incoming_streams_created());
-
-  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data2);
-  EXPECT_EQ(1, session_.num_incoming_streams_created());
-}
-
-TEST_P(QuicSessionTestServer, PendingStreams) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  session_.set_uses_pending_streams(true);
-  session_.set_process_pending_stream_immediately(true);
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data2);
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(1, session_.num_incoming_streams_created());
-}
-
-TEST_P(QuicSessionTestServer, BufferAllIncomingStreams) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  session_.set_uses_pending_streams(true);
-  session_.set_process_pending_stream_immediately(false);
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  // Read unidirectional stream is still buffered when the first byte arrives.
-  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data2);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  // Bidirectional stream is buffered.
-  QuicStreamId bidirectional_stream_id =
-      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
-                                               Perspective::IS_CLIENT);
-  QuicStreamFrame data3(bidirectional_stream_id, false, 0,
-                        absl::string_view("HT"));
-  session_.OnStreamFrame(data3);
-  EXPECT_TRUE(
-      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  session_.ProcessAllPendingStreams();
-  // Both bidirectional and read-unidirectional streams are unbuffered.
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_FALSE(
-      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
-  EXPECT_EQ(2, session_.num_incoming_streams_created());
-}
-
-TEST_P(QuicSessionTestServer, RstPendingStreams) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  session_.set_uses_pending_streams(true);
-  session_.set_process_pending_stream_immediately(false);
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  QuicRstStreamFrame rst1(kInvalidControlFrameId, stream_id,
-                          QUIC_ERROR_PROCESSING_STREAM, 12);
-  session_.OnRstStream(rst1);
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data2);
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  session_.ProcessAllPendingStreams();
-  // Bidirectional stream is buffered.
-  QuicStreamId bidirectional_stream_id =
-      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
-                                               Perspective::IS_CLIENT);
-  QuicStreamFrame data3(bidirectional_stream_id, false, 0,
-                        absl::string_view("HT"));
-  session_.OnStreamFrame(data3);
-  EXPECT_TRUE(
-      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  // Bidirectional pending stream is removed after RST_STREAM is received.
-  QuicRstStreamFrame rst2(kInvalidControlFrameId, bidirectional_stream_id,
-                          QUIC_ERROR_PROCESSING_STREAM, 12);
-  session_.OnRstStream(rst2);
-  EXPECT_FALSE(
-      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-}
-
-TEST_P(QuicSessionTestServer, OnFinPendingStreams) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  session_.set_uses_pending_streams(true);
-  session_.set_process_pending_stream_immediately(true);
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data(stream_id, true, 0, "");
-  session_.OnStreamFrame(data);
-
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-
-  session_.set_process_pending_stream_immediately(false);
-  // Bidirectional pending stream remains after Fin is received.
-  // Bidirectional stream is buffered.
-  QuicStreamId bidirectional_stream_id =
-      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
-                                               Perspective::IS_CLIENT);
-  QuicStreamFrame data2(bidirectional_stream_id, true, 0,
-                        absl::string_view("HT"));
-  session_.OnStreamFrame(data2);
-  EXPECT_TRUE(
-      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  session_.ProcessAllPendingStreams();
-  EXPECT_FALSE(
-      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
-  EXPECT_EQ(1, session_.num_incoming_streams_created());
-  QuicStream* bidirectional_stream =
-      QuicSessionPeer::GetStream(&session_, bidirectional_stream_id);
-  EXPECT_TRUE(bidirectional_stream->fin_received());
-}
-
-TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnWindowUpdate) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  session_.set_uses_pending_streams(true);
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
-                                            0);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(
-          QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
-          "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
-  session_.OnWindowUpdateFrame(window_update_frame);
-}
-
-TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnWindowUpdate) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  session_.set_uses_pending_streams(true);
-  session_.set_process_pending_stream_immediately(false);
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data);
-  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
-                                            kDefaultFlowControlSendWindow * 2);
-  session_.OnWindowUpdateFrame(window_update_frame);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  session_.ProcessAllPendingStreams();
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(1, session_.num_incoming_streams_created());
-  QuicStream* bidirectional_stream =
-      QuicSessionPeer::GetStream(&session_, stream_id);
-  QuicByteCount send_window =
-      QuicStreamPeer::SendWindowSize(bidirectional_stream);
-  EXPECT_EQ(send_window, kDefaultFlowControlSendWindow * 2);
-}
-
-TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnStopSending) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  session_.set_uses_pending_streams(true);
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
-  session_.OnStreamFrame(data1);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-  QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
-                                          QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_STREAM_ID,
-                      "Received STOP_SENDING for a read-only stream", _));
-  session_.OnStopSendingFrame(stop_sending_frame);
-}
-
-TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnStopSending) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-
-  session_.set_uses_pending_streams(true);
-  session_.set_process_pending_stream_immediately(false);
-  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      transport_version(), Perspective::IS_CLIENT);
-  QuicStreamFrame data(stream_id, true, 0, absl::string_view("HT"));
-  session_.OnStreamFrame(data);
-  QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
-                                          QUIC_STREAM_CANCELLED);
-  session_.OnStopSendingFrame(stop_sending_frame);
-  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(0, session_.num_incoming_streams_created());
-
-  EXPECT_CALL(*connection_, OnStreamReset(stream_id, _));
-  session_.ProcessAllPendingStreams();
-  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
-  EXPECT_EQ(1, session_.num_incoming_streams_created());
-  QuicStream* bidirectional_stream =
-      QuicSessionPeer::GetStream(&session_, stream_id);
-  EXPECT_TRUE(bidirectional_stream->write_side_closed());
-}
-
-TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
-  // Verify that a draining stream (which has received a FIN but not consumed
-  // it) does not count against the open quota (because it is closed from the
-  // protocol point of view).
-  CompleteHandshake();
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are
-    // not enough streams to create the next one.
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-  } else {
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  }
-  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
-  const QuicStreamId kMaxStreams = 5;
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
-                                                            kMaxStreams);
-  } else {
-    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
-  }
-
-  // Create kMaxStreams + 1 data streams, and mark them draining.
-  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
-  const QuicStreamId kFinalStreamId =
-      GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1);
-  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
-       i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
-    QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
-    session_.OnStreamFrame(data1);
-    EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-    session_.StreamDraining(i, /*unidirectional=*/false);
-    EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
-  }
-}
-
-class QuicSessionTestClient : public QuicSessionTestBase {
- protected:
-  QuicSessionTestClient()
-      : QuicSessionTestBase(Perspective::IS_CLIENT,
-                            /*configure_session=*/true) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicSessionTestClient,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSessionTestClient, AvailableBidirectionalStreamsClient) {
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
-  // Smaller bidirectional streams should be available.
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthServerInitiatedBidirectionalId(0)));
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthServerInitiatedBidirectionalId(1)));
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
-  // And 5 should be not available.
-  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedBidirectionalId(1)));
-}
-
-TEST_P(QuicSessionTestClient, InvalidSessionFlowControlWindowInHandshake) {
-  // Test that receipt of an invalid (< default for gQUIC, < current for TLS)
-  // session flow control window from the peer results in the connection being
-  // torn down.
-  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
-  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
-                                                             kInvalidWindow);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(connection_->version().AllowsLowFlowControlLimits()
-                          ? QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED
-                          : QUIC_FLOW_CONTROL_INVALID_WINDOW,
-                      _, _));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, InvalidBidiStreamLimitInHandshake) {
-  // IETF QUIC only feature.
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
-      session_.config(), kDefaultMaxStreamsPerConnection - 1);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, InvalidUniStreamLimitInHandshake) {
-  // IETF QUIC only feature.
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
-      session_.config(), kDefaultMaxStreamsPerConnection - 1);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, InvalidStreamFlowControlWindowInHandshake) {
-  // IETF QUIC only feature.
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  session_.CreateOutgoingBidirectionalStream();
-  session_.CreateOutgoingBidirectionalStream();
-  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-      session_.config(), kMinimumFlowControlSendWindow - 1);
-
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
-      .WillOnce(
-          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
-  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
-
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  session_.OnConfigNegotiated();
-}
-
-TEST_P(QuicSessionTestClient, OnMaxStreamFrame) {
-  if (!VersionUsesHttp3(transport_version())) {
-    return;
-  }
-  QuicMaxStreamsFrame frame;
-  frame.unidirectional = false;
-  frame.stream_count = 120;
-  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
-  session_.OnMaxStreamsFrame(frame);
-
-  QuicMaxStreamsFrame frame2;
-  frame2.unidirectional = false;
-  frame2.stream_count = 110;
-  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
-  session_.OnMaxStreamsFrame(frame2);
-}
-
-TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) {
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedUnidirectionalId(2)) != nullptr);
-  // Smaller unidirectional streams should be available.
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthServerInitiatedUnidirectionalId(0)));
-  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthServerInitiatedUnidirectionalId(1)));
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedUnidirectionalId(0)) != nullptr);
-  ASSERT_TRUE(session_.GetOrCreateStream(
-                  GetNthServerInitiatedUnidirectionalId(1)) != nullptr);
-  // And 5 should be not available.
-  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
-      &session_, GetNthClientInitiatedUnidirectionalId(1)));
-}
-
-TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
-  CompleteHandshake();
-  // Verify that an incoming FIN is recorded in a stream object even if the read
-  // side has been closed.  This prevents an entry from being made in
-  // locally_closed_streams_highest_offset_ (which will never be deleted).
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId stream_id = stream->id();
-
-  // Close the read side manually.
-  QuicStreamPeer::CloseReadSide(stream);
-
-  // Receive a stream data frame with FIN.
-  QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
-  session_.OnStreamFrame(frame);
-  EXPECT_TRUE(stream->fin_received());
-
-  // Reset stream locally.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  stream->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
-
-  EXPECT_TRUE(connection_->connected());
-  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
-  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
-
-  // The stream is not waiting for the arrival of the peer's final offset as it
-  // was received with the FIN earlier.
-  EXPECT_EQ(
-      0u,
-      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
-}
-
-TEST_P(QuicSessionTestClient, IncomingStreamWithClientInitiatedStreamId) {
-  const QuicErrorCode expected_error =
-      VersionHasIetfQuicFrames(transport_version())
-          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
-          : QUIC_INVALID_STREAM_ID;
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(expected_error, "Data for nonexistent stream",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
-  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(1),
-                        /* fin = */ false, /* offset = */ 0,
-                        absl::string_view("foo"));
-  session_.OnStreamFrame(frame);
-}
-
-TEST_P(QuicSessionTestClient, MinAckDelaySetOnTheClientQuicConfig) {
-  if (!session_.version().HasIetfQuicFrames()) {
-    return;
-  }
-  session_.config()->SetClientConnectionOptions({kAFFE});
-  session_.Initialize();
-  ASSERT_EQ(session_.config()->GetMinAckDelayToSendMs(),
-            kDefaultMinAckDelayTimeMs);
-  ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame());
-}
-
-TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) {
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
-  QuicTime deadline = QuicConnectionPeer::GetIdleNetworkDeadline(connection_);
-  ASSERT_TRUE(deadline.IsInitialized());
-  QuicTime::Delta timeout = deadline - helper_.GetClock()->ApproximateNow();
-  // Advance time to very close idle timeout.
-  connection_->AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
-  // Verify creation of new stream gets pushed back and connectivity probing
-  // packet gets sent.
-  EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _)).Times(1);
-  EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
-
-  // New packet gets received, idle deadline gets extended.
-  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false));
-  QuicConnectionPeer::GetIdleNetworkDetector(connection_)
-      .OnPacketReceived(helper_.GetClock()->ApproximateNow());
-  session_.OnPacketDecrypted(ENCRYPTION_FORWARD_SECURE);
-
-  EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
-}
-
-TEST_P(QuicSessionTestServer, ZombieStreams) {
-  CompleteHandshake();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
-  EXPECT_TRUE(stream2->IsWaitingForAcks());
-
-  CloseStream(stream2->id());
-  ASSERT_EQ(1u, session_.closed_streams()->size());
-  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
-  session_.MaybeCloseZombieStream(stream2->id());
-  EXPECT_EQ(1u, session_.closed_streams()->size());
-  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
-}
-
-TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
-  CompleteHandshake();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
-  EXPECT_TRUE(stream2->IsWaitingForAcks());
-
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
-  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
-  stream2->Reset(quic::QUIC_STREAM_CANCELLED);
-
-  QuicRstStreamFrame rst1(kInvalidControlFrameId, stream2->id(),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
-  }
-  session_.OnRstStream(rst1);
-}
-
-// Regression test of b/71548958.
-TEST_P(QuicSessionTestServer, TestZombieStreams) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  std::string body(100, '.');
-  stream2->WriteOrBufferData(body, false, nullptr);
-  EXPECT_TRUE(stream2->IsWaitingForAcks());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
-
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  // Just for the RST_STREAM
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(*connection_,
-                OnStreamReset(stream2->id(), QUIC_STREAM_CANCELLED));
-  } else {
-    EXPECT_CALL(*connection_,
-                OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  stream2->OnStreamReset(rst_frame);
-
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // The test requires the stream to be fully closed in both directions. For
-    // IETF QUIC, the RST_STREAM only closes one side.
-    QuicStopSendingFrame frame(kInvalidControlFrameId, stream2->id(),
-                               QUIC_STREAM_CANCELLED);
-    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-    session_.OnStopSendingFrame(frame);
-  }
-  ASSERT_EQ(1u, session_.closed_streams()->size());
-  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
-
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // Once for the RST_STREAM, once for the STOP_SENDING
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .Times(2)
-        .WillRepeatedly(Invoke(&ClearControlFrame));
-  } else {
-    // Just for the RST_STREAM
-    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-  }
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
-  stream4->WriteOrBufferData(body, false, nullptr);
-  // Note well: Reset() actually closes the stream in both directions. For
-  // GOOGLE QUIC it sends a RST_STREAM (which does a 2-way close), for IETF
-  // QUIC it sends both a RST_STREAM and a STOP_SENDING (each of which
-  // closes in only one direction).
-  stream4->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_EQ(2u, session_.closed_streams()->size());
-}
-
-TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
-  CompleteHandshake();
-  InSequence s;
-
-  // Drive congestion control manually.
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-
-  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-
-  QuicStreamFrame frame1;
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    frame1 = QuicStreamFrame(
-        QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
-        0, 1300);
-  }
-  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
-  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
-
-  // Lost data on cryption stream, streams 2 and 4.
-  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
-        .WillOnce(Return(true));
-  }
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
-  session_.OnFrameLost(QuicFrame(frame3));
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    session_.OnFrameLost(QuicFrame(frame1));
-  } else {
-    QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
-    session_.OnFrameLost(QuicFrame(&crypto_frame));
-  }
-  session_.OnFrameLost(QuicFrame(frame2));
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // Mark streams 2 and 4 write blocked.
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-
-  // Lost data is retransmitted before new data, and retransmissions for crypto
-  // stream go first.
-  // Do not check congestion window when crypto stream has lost data.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    EXPECT_CALL(*crypto_stream, OnCanWrite());
-    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
-        .WillOnce(Return(false));
-  }
-  // Check congestion window for non crypto streams.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, OnCanWrite());
-  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
-  // Connection is blocked.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
-
-  session_.OnCanWrite();
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  // Unblock connection.
-  // Stream 2 retransmits lost data.
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  // Stream 2 sends new data.
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, OnCanWrite());
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
-  CompleteHandshake();
-  InSequence s;
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-
-  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
-  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
-  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
-
-  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
-  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
-  session_.OnFrameLost(QuicFrame(frame3));
-  session_.OnFrameLost(QuicFrame(frame2));
-  session_.OnFrameLost(QuicFrame(frame1));
-
-  session_.MarkConnectionLevelWriteBlocked(stream2->id());
-  session_.MarkConnectionLevelWriteBlocked(stream4->id());
-  session_.MarkConnectionLevelWriteBlocked(stream6->id());
-
-  // Reset stream 4 locally.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
-  stream4->Reset(QUIC_STREAM_CANCELLED);
-
-  // Verify stream 4 is removed from streams with lost data list.
-  EXPECT_CALL(*stream6, OnCanWrite());
-  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*stream6, OnCanWrite());
-  session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, RetransmitFrames) {
-  CompleteHandshake();
-  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
-  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
-  InSequence s;
-
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
-  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  session_.SendWindowUpdate(stream2->id(), 9);
-
-  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
-  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
-  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
-  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame1));
-  frames.push_back(QuicFrame(window_update));
-  frames.push_back(QuicFrame(frame2));
-  frames.push_back(QuicFrame(frame3));
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-
-  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillOnce(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
-  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
-}
-
-// Regression test of b/110082001.
-TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
-  CompleteHandshake();
-  // This test mimics the scenario when a dynamic stream retransmits lost data
-  // and causes connection close.
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamFrame frame(stream->id(), false, 0, 9);
-
-  EXPECT_CALL(*stream, HasPendingRetransmission())
-      .Times(2)
-      .WillOnce(Return(true))
-      .WillOnce(Return(false));
-  session_.OnFrameLost(QuicFrame(frame));
-  // Retransmit stream data causes connection close. Stream has not sent fin
-  // yet, so an RST is sent.
-  EXPECT_CALL(*stream, OnCanWrite()).WillOnce(Invoke([this, stream]() {
-    session_.ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
-  }));
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    // Once for the RST_STREAM, once for the STOP_SENDING
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .Times(2)
-        .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame));
-  } else {
-    // Just for the RST_STREAM
-    EXPECT_CALL(*connection_, SendControlFrame(_))
-        .WillOnce(Invoke(&session_, &TestSession::SaveFrame));
-  }
-  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
-  session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, SendMessage) {
-  // Cannot send message when encryption is not established.
-  EXPECT_FALSE(session_.OneRttKeysAvailable());
-  EXPECT_EQ(MessageResult(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0),
-            session_.SendMessage(MemSliceFromString("")));
-
-  CompleteHandshake();
-  EXPECT_TRUE(session_.OneRttKeysAvailable());
-
-  EXPECT_CALL(*connection_, SendMessage(1, _, false))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-  EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
-            session_.SendMessage(MemSliceFromString("")));
-  // Verify message_id increases.
-  EXPECT_CALL(*connection_, SendMessage(2, _, false))
-      .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
-  EXPECT_EQ(MessageResult(MESSAGE_STATUS_TOO_LARGE, 0),
-            session_.SendMessage(MemSliceFromString("")));
-  // Verify unsent message does not consume a message_id.
-  EXPECT_CALL(*connection_, SendMessage(2, _, false))
-      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
-  EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 2),
-            session_.SendMessage(MemSliceFromString("")));
-
-  QuicMessageFrame frame(1);
-  QuicMessageFrame frame2(2);
-  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
-  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
-
-  // Lost message 2.
-  session_.OnMessageLost(2);
-  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
-
-  // message 1 gets acked.
-  session_.OnMessageAcked(1, QuicTime::Zero());
-  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
-}
-
-// Regression test of b/115323618.
-TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
-  CompleteHandshake();
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  std::string body(100, '.');
-  QuicStreamPeer::CloseReadSide(stream2);
-  stream2->WriteOrBufferData(body, true, nullptr);
-  EXPECT_TRUE(stream2->IsWaitingForAcks());
-  // Verify stream2 is a zombie streams.
-  auto& stream_map = QuicSessionPeer::stream_map(&session_);
-  ASSERT_TRUE(stream_map.contains(stream2->id()));
-  auto* stream = stream_map.find(stream2->id())->second.get();
-  EXPECT_TRUE(stream->IsZombie());
-
-  QuicStreamFrame frame(stream2->id(), true, 0, 100);
-  EXPECT_CALL(*stream2, HasPendingRetransmission())
-      .WillRepeatedly(Return(true));
-  session_.OnFrameLost(QuicFrame(frame));
-
-  // Reset stream2 locally.
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
-  stream2->Reset(QUIC_STREAM_CANCELLED);
-
-  // Verify stream 2 gets closed.
-  EXPECT_TRUE(session_.IsClosedStream(stream2->id()));
-  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
-  session_.OnCanWrite();
-}
-
-TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
-  CompleteHandshake();
-  EXPECT_FALSE(
-      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
-
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_FALSE(stream2->IsWaitingForAcks());
-
-  CloseStream(stream2->id());
-  EXPECT_EQ(1u, session_.closed_streams()->size());
-  EXPECT_TRUE(
-      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
-
-  alarm_factory_.FireAlarm(
-      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_));
-  EXPECT_TRUE(session_.closed_streams()->empty());
-}
-
-TEST_P(QuicSessionTestServer, WriteUnidirectionalStream) {
-  session_.set_writev_consumes_all_data(true);
-  TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
-                                       &session_, WRITE_UNIDIRECTIONAL);
-  session_.ActivateStream(absl::WrapUnique(stream4));
-  std::string body(100, '.');
-  stream4->WriteOrBufferData(body, false, nullptr);
-  stream4->WriteOrBufferData(body, true, nullptr);
-  auto& stream_map = QuicSessionPeer::stream_map(&session_);
-  ASSERT_TRUE(stream_map.contains(stream4->id()));
-  auto* stream = stream_map.find(stream4->id())->second.get();
-  EXPECT_TRUE(stream->IsZombie());
-}
-
-TEST_P(QuicSessionTestServer, ReceivedDataOnWriteUnidirectionalStream) {
-  TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
-                                       &session_, WRITE_UNIDIRECTIONAL);
-  session_.ActivateStream(absl::WrapUnique(stream4));
-
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _))
-      .Times(1);
-  QuicStreamFrame stream_frame(GetNthServerInitiatedUnidirectionalId(1), false,
-                               0, 2);
-  session_.OnStreamFrame(stream_frame);
-}
-
-TEST_P(QuicSessionTestServer, ReadUnidirectionalStream) {
-  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
-                                       &session_, READ_UNIDIRECTIONAL);
-  session_.ActivateStream(absl::WrapUnique(stream4));
-  EXPECT_FALSE(stream4->IsWaitingForAcks());
-  // Discard all incoming data.
-  stream4->StopReading();
-
-  std::string data(100, '.');
-  QuicStreamFrame stream_frame(GetNthClientInitiatedUnidirectionalId(1), false,
-                               0, data);
-  stream4->OnStreamFrame(stream_frame);
-  EXPECT_TRUE(session_.closed_streams()->empty());
-
-  QuicStreamFrame stream_frame2(GetNthClientInitiatedUnidirectionalId(1), true,
-                                100, data);
-  stream4->OnStreamFrame(stream_frame2);
-  EXPECT_EQ(1u, session_.closed_streams()->size());
-}
-
-TEST_P(QuicSessionTestServer, WriteOrBufferDataOnReadUnidirectionalStream) {
-  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
-                                       &session_, READ_UNIDIRECTIONAL);
-  session_.ActivateStream(absl::WrapUnique(stream4));
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
-      .Times(1);
-  std::string body(100, '.');
-  stream4->WriteOrBufferData(body, false, nullptr);
-}
-
-TEST_P(QuicSessionTestServer, WritevDataOnReadUnidirectionalStream) {
-  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
-                                       &session_, READ_UNIDIRECTIONAL);
-  session_.ActivateStream(absl::WrapUnique(stream4));
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
-      .Times(1);
-  std::string body(100, '.');
-  struct iovec iov = {const_cast<char*>(body.data()), body.length()};
-  quiche::QuicheMemSliceStorage storage(
-      &iov, 1, session_.connection()->helper()->GetStreamSendBufferAllocator(),
-      1024);
-  stream4->WriteMemSlices(storage.ToSpan(), false);
-}
-
-TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) {
-  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
-                                       &session_, READ_UNIDIRECTIONAL);
-  session_.ActivateStream(absl::WrapUnique(stream4));
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(
-                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
-      .Times(1);
-  std::string data(1024, 'a');
-  std::vector<quiche::QuicheMemSlice> buffers;
-  buffers.push_back(MemSliceFromString(data));
-  buffers.push_back(MemSliceFromString(data));
-  stream4->WriteMemSlices(absl::MakeSpan(buffers), false);
-}
-
-// Test code that tests that an incoming stream frame with a new (not previously
-// seen) stream id is acceptable. The ID must not be larger than has been
-// advertised. It may be equal to what has been advertised.  These tests
-// invoke QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId by calling
-// QuicSession::OnStreamFrame in order to check that all the steps are connected
-// properly and that nothing in the call path interferes with the check.
-// First test make sure that streams with ids below the limit are accepted.
-TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // Applicable only to IETF QUIC
-    return;
-  }
-  QuicStreamId bidirectional_stream_id = StreamCountToId(
-      QuicSessionPeer::ietf_streamid_manager(&session_)
-              ->advertised_max_incoming_bidirectional_streams() -
-          1,
-      Perspective::IS_CLIENT,
-      /*bidirectional=*/true);
-
-  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
-                                             "Random String");
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStreamFrame(bidirectional_stream_frame);
-
-  QuicStreamId unidirectional_stream_id = StreamCountToId(
-      QuicSessionPeer::ietf_streamid_manager(&session_)
-              ->advertised_max_incoming_unidirectional_streams() -
-          1,
-      Perspective::IS_CLIENT,
-      /*bidirectional=*/false);
-  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
-                                              0, "Random String");
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStreamFrame(unidirectional_stream_frame);
-}
-
-// Accept a stream with an ID that equals the limit.
-TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // Applicable only to IETF QUIC
-    return;
-  }
-  QuicStreamId bidirectional_stream_id =
-      StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
-                          ->advertised_max_incoming_bidirectional_streams(),
-                      Perspective::IS_CLIENT, /*bidirectional=*/true);
-  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
-                                             "Random String");
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStreamFrame(bidirectional_stream_frame);
-
-  QuicStreamId unidirectional_stream_id =
-      StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
-                          ->advertised_max_incoming_unidirectional_streams(),
-                      Perspective::IS_CLIENT, /*bidirectional=*/false);
-  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
-                                              0, "Random String");
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStreamFrame(unidirectional_stream_frame);
-}
-
-// Close the connection if the id exceeds the limit.
-TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // Applicable only to IETF QUIC
-    return;
-  }
-
-  QuicStreamId bidirectional_stream_id = StreamCountToId(
-      QuicSessionPeer::ietf_streamid_manager(&session_)
-              ->advertised_max_incoming_bidirectional_streams() +
-          1,
-      Perspective::IS_CLIENT, /*bidirectional=*/true);
-  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
-                                             "Random String");
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_STREAM_ID,
-                      "Stream id 400 would exceed stream count limit 100", _));
-  session_.OnStreamFrame(bidirectional_stream_frame);
-
-  QuicStreamId unidirectional_stream_id = StreamCountToId(
-      QuicSessionPeer::ietf_streamid_manager(&session_)
-              ->advertised_max_incoming_unidirectional_streams() +
-          1,
-      Perspective::IS_CLIENT, /*bidirectional=*/false);
-  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
-                                              0, "Random String");
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_STREAM_ID,
-                      "Stream id 402 would exceed stream count limit 100", _));
-  session_.OnStreamFrame(unidirectional_stream_frame);
-}
-
-// Checks that invalid stream ids are handled.
-TEST_P(QuicSessionTestServer, OnStopSendingInvalidStreamId) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  // Check that "invalid" stream ids are rejected.
-  QuicStopSendingFrame frame(1, -1, QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_STREAM_ID,
-                      "Received STOP_SENDING for an invalid stream", _));
-  session_.OnStopSendingFrame(frame);
-}
-
-TEST_P(QuicSessionTestServer, OnStopSendingReadUnidirectional) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  // It's illegal to send STOP_SENDING with a stream ID that is read-only.
-  QuicStopSendingFrame frame(1, GetNthClientInitiatedUnidirectionalId(1),
-                             QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(QUIC_INVALID_STREAM_ID,
-                      "Received STOP_SENDING for a read-only stream", _));
-  session_.OnStopSendingFrame(frame);
-}
-
-// Static streams ignore STOP_SENDING.
-TEST_P(QuicSessionTestServer, OnStopSendingStaticStreams) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  QuicStreamId stream_id = 0;
-  std::unique_ptr<TestStream> fake_static_stream = std::make_unique<TestStream>(
-      stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
-  QuicSessionPeer::ActivateStream(&session_, std::move(fake_static_stream));
-  // Check that a stream id in the static stream map is ignored.
-  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_STREAM_ID,
-                              "Received STOP_SENDING for a static stream", _));
-  session_.OnStopSendingFrame(frame);
-}
-
-// If stream is write closed, do not send a RESET_STREAM frame.
-TEST_P(QuicSessionTestServer, OnStopSendingForWriteClosedStream) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId stream_id = stream->id();
-  QuicStreamPeer::SetFinSent(stream);
-  stream->CloseWriteSide();
-  EXPECT_TRUE(stream->write_side_closed());
-  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStopSendingFrame(frame);
-}
-
-// If stream is closed, return true and do not close the connection.
-TEST_P(QuicSessionTestServer, OnStopSendingClosedStream) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  CompleteHandshake();
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamId stream_id = stream->id();
-  CloseStream(stream_id);
-  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStopSendingFrame(frame);
-}
-
-// If stream id is a nonexistent local stream, return false and close the
-// connection.
-TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentLocalStream) {
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-
-  QuicStopSendingFrame frame(1, GetNthServerInitiatedBidirectionalId(123456),
-                             QUIC_STREAM_CANCELLED);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_STREAM_WRONG_DIRECTION,
-                                            "Data for nonexistent stream", _))
-      .Times(1);
-  session_.OnStopSendingFrame(frame);
-}
-
-// If a STOP_SENDING is received for a peer initiated stream, the new stream
-// will be created.
-TEST_P(QuicSessionTestServer, OnStopSendingNewStream) {
-  CompleteHandshake();
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-  QuicStopSendingFrame frame(1, GetNthClientInitiatedBidirectionalId(1),
-                             QUIC_STREAM_CANCELLED);
-
-  // A Rst will be sent as a response for STOP_SENDING.
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
-  session_.OnStopSendingFrame(frame);
-
-  QuicStream* stream =
-      session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(1));
-  EXPECT_TRUE(stream);
-  EXPECT_TRUE(stream->write_side_closed());
-}
-
-// For a valid stream, ensure that all works
-TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
-  CompleteHandshake();
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // Applicable only to IETF QUIC
-    return;
-  }
-
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-
-  // Ensure that the stream starts out open in both directions.
-  EXPECT_FALSE(stream->write_side_closed());
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
-
-  QuicStreamId stream_id = stream->id();
-  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
-  // Expect a reset to come back out.
-  EXPECT_CALL(*connection_, SendControlFrame(_));
-  EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_STREAM_CANCELLED));
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  session_.OnStopSendingFrame(frame);
-
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
-  EXPECT_TRUE(stream->write_side_closed());
-}
-
-TEST_P(QuicSessionTestServer, WriteBufferedCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    return;
-  }
-  std::string data(1350, 'a');
-  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
-  // Only consumed 1000 bytes.
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
-      .WillOnce(Return(1000));
-  crypto_stream->WriteCryptoData(ENCRYPTION_INITIAL, data);
-  EXPECT_TRUE(session_.HasPendingHandshake());
-  EXPECT_TRUE(session_.WillingAndAbleToWrite());
-
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
-  connection_->SetEncrypter(
-      ENCRYPTION_ZERO_RTT,
-      std::make_unique<NullEncrypter>(connection_->perspective()));
-  crypto_stream->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
-
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
-      .WillOnce(Return(350));
-  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
-      .WillOnce(Return(1350));
-  session_.OnCanWrite();
-  EXPECT_FALSE(session_.HasPendingHandshake());
-  EXPECT_FALSE(session_.WillingAndAbleToWrite());
-}
-
-// Regression test for
-// https://bugs.chromium.org/p/chromium/issues/detail?id=1002119
-TEST_P(QuicSessionTestServer, StreamFrameReceivedAfterFin) {
-  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
-  QuicStreamFrame frame(stream->id(), true, 0, ",");
-  session_.OnStreamFrame(frame);
-
-  QuicStreamFrame frame1(stream->id(), false, 1, ",");
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET, _, _));
-  session_.OnStreamFrame(frame1);
-}
-
-TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) {
-  CompleteHandshake();
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    return;
-  }
-
-  QuicStreamId read_only = GetNthClientInitiatedUnidirectionalId(0);
-
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(1)
-      .WillOnce(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
-  session_.ResetStream(read_only, QUIC_STREAM_CANCELLED);
-
-  QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0);
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(1)
-      .WillOnce(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(write_only, _));
-  session_.ResetStream(write_only, QUIC_STREAM_CANCELLED);
-
-  QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0);
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(2)
-      .WillRepeatedly(Invoke(&ClearControlFrame));
-  EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _));
-  session_.ResetStream(bidirectional, QUIC_STREAM_CANCELLED);
-}
-
-TEST_P(QuicSessionTestServer, DecryptionKeyAvailableBeforeEncryptionKey) {
-  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
-    return;
-  }
-  ASSERT_FALSE(connection_->framer().HasEncrypterOfEncryptionLevel(
-      ENCRYPTION_HANDSHAKE));
-  EXPECT_FALSE(session_.OnNewDecryptionKeyAvailable(
-      ENCRYPTION_HANDSHAKE, /*decrypter=*/nullptr,
-      /*set_alternative_decrypter=*/false, /*latch_once_used=*/false));
-}
-
-TEST_P(QuicSessionTestServer, IncomingStreamWithServerInitiatedStreamId) {
-  const QuicErrorCode expected_error =
-      VersionHasIetfQuicFrames(transport_version())
-          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
-          : QUIC_INVALID_STREAM_ID;
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(expected_error, "Data for nonexistent stream",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
-
-  QuicStreamFrame frame(GetNthServerInitiatedBidirectionalId(1),
-                        /* fin = */ false, /* offset = */ 0,
-                        absl::string_view("foo"));
-  session_.OnStreamFrame(frame);
-}
-
-// A client test class that can be used when the automatic configuration is not
-// desired.
-class QuicSessionTestClientUnconfigured : public QuicSessionTestBase {
- protected:
-  QuicSessionTestClientUnconfigured()
-      : QuicSessionTestBase(Perspective::IS_CLIENT,
-                            /*configure_session=*/false) {}
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicSessionTestClientUnconfigured,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSessionTestClientUnconfigured, StreamInitiallyBlockedThenUnblocked) {
-  if (!connection_->version().AllowsLowFlowControlLimits()) {
-    return;
-  }
-  // Create a stream before negotiating the config and verify it starts off
-  // blocked.
-  QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(&session_, 10);
-  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
-  EXPECT_TRUE(stream2->IsFlowControlBlocked());
-  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
-
-  // Negotiate the config with higher received limits.
-  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-      session_.config(), kMinimumFlowControlSendWindow);
-  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-      session_.config(), kMinimumFlowControlSendWindow);
-  session_.OnConfigNegotiated();
-
-  // Stream is now unblocked.
-  EXPECT_FALSE(stream2->IsFlowControlBlocked());
-  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
-  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_socket_address_coder.cc b/quic/core/quic_socket_address_coder.cc
deleted file mode 100644
index 60d0e3c..0000000
--- a/quic/core/quic_socket_address_coder.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_socket_address_coder.h"
-
-#include <cstring>
-#include <string>
-#include <vector>
-
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quic {
-
-namespace {
-
-// For convenience, the values of these constants match the values of AF_INET
-// and AF_INET6 on Linux.
-const uint16_t kIPv4 = 2;
-const uint16_t kIPv6 = 10;
-
-}  // namespace
-
-QuicSocketAddressCoder::QuicSocketAddressCoder() {}
-
-QuicSocketAddressCoder::QuicSocketAddressCoder(const QuicSocketAddress& address)
-    : address_(address) {}
-
-QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
-
-std::string QuicSocketAddressCoder::Encode() const {
-  std::string serialized;
-  uint16_t address_family;
-  switch (address_.host().address_family()) {
-    case IpAddressFamily::IP_V4:
-      address_family = kIPv4;
-      break;
-    case IpAddressFamily::IP_V6:
-      address_family = kIPv6;
-      break;
-    default:
-      return serialized;
-  }
-  serialized.append(reinterpret_cast<const char*>(&address_family),
-                    sizeof(address_family));
-  serialized.append(address_.host().ToPackedString());
-  uint16_t port = address_.port();
-  serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
-  return serialized;
-}
-
-bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
-  uint16_t address_family;
-  if (length < sizeof(address_family)) {
-    return false;
-  }
-  memcpy(&address_family, data, sizeof(address_family));
-  data += sizeof(address_family);
-  length -= sizeof(address_family);
-
-  size_t ip_length;
-  switch (address_family) {
-    case kIPv4:
-      ip_length = QuicIpAddress::kIPv4AddressSize;
-      break;
-    case kIPv6:
-      ip_length = QuicIpAddress::kIPv6AddressSize;
-      break;
-    default:
-      return false;
-  }
-  if (length < ip_length) {
-    return false;
-  }
-  std::vector<uint8_t> ip(ip_length);
-  memcpy(&ip[0], data, ip_length);
-  data += ip_length;
-  length -= ip_length;
-
-  uint16_t port;
-  if (length != sizeof(port)) {
-    return false;
-  }
-  memcpy(&port, data, length);
-
-  QuicIpAddress ip_address;
-  ip_address.FromPackedString(reinterpret_cast<const char*>(&ip[0]), ip_length);
-  address_ = QuicSocketAddress(ip_address, port);
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_socket_address_coder.h b/quic/core/quic_socket_address_coder.h
deleted file mode 100644
index d66663c..0000000
--- a/quic/core/quic_socket_address_coder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
-#define QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
-
-#include <cstdint>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Serializes and parses a socket address (IP address and port), to be used in
-// the kCADR tag in the ServerHello handshake message and the Public Reset
-// packet.
-class QUIC_EXPORT_PRIVATE QuicSocketAddressCoder {
- public:
-  QuicSocketAddressCoder();
-  explicit QuicSocketAddressCoder(const QuicSocketAddress& address);
-  QuicSocketAddressCoder(const QuicSocketAddressCoder&) = delete;
-  QuicSocketAddressCoder& operator=(const QuicSocketAddressCoder&) = delete;
-  ~QuicSocketAddressCoder();
-
-  std::string Encode() const;
-
-  bool Decode(const char* data, size_t length);
-
-  QuicIpAddress ip() const { return address_.host(); }
-
-  uint16_t port() const { return address_.port(); }
-
- private:
-  QuicSocketAddress address_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
diff --git a/quic/core/quic_socket_address_coder_test.cc b/quic/core/quic_socket_address_coder_test.cc
deleted file mode 100644
index 6a8adad..0000000
--- a/quic/core/quic_socket_address_coder_test.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_socket_address_coder.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicSocketAddressCoderTest : public QuicTest {};
-
-TEST_F(QuicSocketAddressCoderTest, EncodeIPv4) {
-  QuicIpAddress ip;
-  ip.FromString("4.31.198.44");
-  QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x1234));
-  std::string serialized = coder.Encode();
-  std::string expected("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
-  EXPECT_EQ(expected, serialized);
-}
-
-TEST_F(QuicSocketAddressCoderTest, EncodeIPv6) {
-  QuicIpAddress ip;
-  ip.FromString("2001:700:300:1800::f");
-  QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x5678));
-  std::string serialized = coder.Encode();
-  std::string expected(
-      "\x0a\x00"
-      "\x20\x01\x07\x00\x03\x00\x18\x00"
-      "\x00\x00\x00\x00\x00\x00\x00\x0f"
-      "\x78\x56",
-      20);
-  EXPECT_EQ(expected, serialized);
-}
-
-TEST_F(QuicSocketAddressCoderTest, DecodeIPv4) {
-  std::string serialized("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
-  QuicSocketAddressCoder coder;
-  ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-  EXPECT_EQ(IpAddressFamily::IP_V4, coder.ip().address_family());
-  std::string expected_addr("\x04\x1f\xc6\x2c");
-  EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
-  EXPECT_EQ(0x1234, coder.port());
-}
-
-TEST_F(QuicSocketAddressCoderTest, DecodeIPv6) {
-  std::string serialized(
-      "\x0a\x00"
-      "\x20\x01\x07\x00\x03\x00\x18\x00"
-      "\x00\x00\x00\x00\x00\x00\x00\x0f"
-      "\x78\x56",
-      20);
-  QuicSocketAddressCoder coder;
-  ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-  EXPECT_EQ(IpAddressFamily::IP_V6, coder.ip().address_family());
-  std::string expected_addr(
-      "\x20\x01\x07\x00\x03\x00\x18\x00"
-      "\x00\x00\x00\x00\x00\x00\x00\x0f",
-      16);
-  EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
-  EXPECT_EQ(0x5678, coder.port());
-}
-
-TEST_F(QuicSocketAddressCoderTest, DecodeBad) {
-  std::string serialized(
-      "\x0a\x00"
-      "\x20\x01\x07\x00\x03\x00\x18\x00"
-      "\x00\x00\x00\x00\x00\x00\x00\x0f"
-      "\x78\x56",
-      20);
-  QuicSocketAddressCoder coder;
-  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-  // Append junk.
-  serialized.push_back('\0');
-  EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
-  // Undo.
-  serialized.resize(20);
-  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-
-  // Set an unknown address family.
-  serialized[0] = '\x03';
-  EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
-  // Undo.
-  serialized[0] = '\x0a';
-  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
-
-  // Truncate.
-  size_t len = serialized.length();
-  for (size_t i = 0; i < len; i++) {
-    ASSERT_FALSE(serialized.empty());
-    serialized.erase(serialized.length() - 1);
-    EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
-  }
-  EXPECT_TRUE(serialized.empty());
-}
-
-TEST_F(QuicSocketAddressCoderTest, EncodeAndDecode) {
-  struct {
-    const char* ip_literal;
-    uint16_t port;
-  } test_case[] = {
-      {"93.184.216.119", 0x1234},
-      {"199.204.44.194", 80},
-      {"149.20.4.69", 443},
-      {"127.0.0.1", 8080},
-      {"2001:700:300:1800::", 0x5678},
-      {"::1", 65534},
-  };
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_case); i++) {
-    QuicIpAddress ip;
-    ASSERT_TRUE(ip.FromString(test_case[i].ip_literal));
-    QuicSocketAddressCoder encoder(QuicSocketAddress(ip, test_case[i].port));
-    std::string serialized = encoder.Encode();
-
-    QuicSocketAddressCoder decoder;
-    ASSERT_TRUE(decoder.Decode(serialized.data(), serialized.length()));
-    EXPECT_EQ(encoder.ip(), decoder.ip());
-    EXPECT_EQ(encoder.port(), decoder.port());
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc
deleted file mode 100644
index a1d482a..0000000
--- a/quic/core/quic_stream.cc
+++ /dev/null
@@ -1,1459 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream.h"
-
-#include <limits>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-using spdy::SpdyPriority;
-
-namespace quic {
-
-#define ENDPOINT \
-  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-namespace {
-
-QuicByteCount DefaultFlowControlWindow(ParsedQuicVersion version) {
-  if (!version.AllowsLowFlowControlLimits()) {
-    return kDefaultFlowControlSendWindow;
-  }
-  return 0;
-}
-
-QuicByteCount GetInitialStreamFlowControlWindowToSend(QuicSession* session,
-                                                      QuicStreamId stream_id) {
-  ParsedQuicVersion version = session->connection()->version();
-  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
-    return session->config()->GetInitialStreamFlowControlWindowToSend();
-  }
-
-  // Unidirectional streams (v99 only).
-  if (VersionHasIetfQuicFrames(version.transport_version) &&
-      !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
-    return session->config()
-        ->GetInitialMaxStreamDataBytesUnidirectionalToSend();
-  }
-
-  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
-                                    session->perspective())) {
-    return session->config()
-        ->GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend();
-  }
-
-  return session->config()
-      ->GetInitialMaxStreamDataBytesIncomingBidirectionalToSend();
-}
-
-QuicByteCount GetReceivedFlowControlWindow(QuicSession* session,
-                                           QuicStreamId stream_id) {
-  ParsedQuicVersion version = session->connection()->version();
-  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
-    if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) {
-      return session->config()->ReceivedInitialStreamFlowControlWindowBytes();
-    }
-
-    return DefaultFlowControlWindow(version);
-  }
-
-  // Unidirectional streams (v99 only).
-  if (VersionHasIetfQuicFrames(version.transport_version) &&
-      !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
-    if (session->config()
-            ->HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
-      return session->config()
-          ->ReceivedInitialMaxStreamDataBytesUnidirectional();
-    }
-
-    return DefaultFlowControlWindow(version);
-  }
-
-  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
-                                    session->perspective())) {
-    if (session->config()
-            ->HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
-      return session->config()
-          ->ReceivedInitialMaxStreamDataBytesOutgoingBidirectional();
-    }
-
-    return DefaultFlowControlWindow(version);
-  }
-
-  if (session->config()
-          ->HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
-    return session->config()
-        ->ReceivedInitialMaxStreamDataBytesIncomingBidirectional();
-  }
-
-  return DefaultFlowControlWindow(version);
-}
-
-}  // namespace
-
-// static
-const SpdyPriority QuicStream::kDefaultPriority;
-
-// static
-const int QuicStream::kDefaultUrgency;
-
-PendingStream::PendingStream(QuicStreamId id, QuicSession* session)
-    : id_(id),
-      version_(session->version()),
-      stream_delegate_(session),
-      stream_bytes_read_(0),
-      fin_received_(false),
-      is_bidirectional_(QuicUtils::GetStreamType(id, session->perspective(),
-                                                 /*peer_initiated = */ true,
-                                                 session->version()) ==
-                        BIDIRECTIONAL),
-      connection_flow_controller_(session->flow_controller()),
-      flow_controller_(session, id,
-                       /*is_connection_flow_controller*/ false,
-                       GetReceivedFlowControlWindow(session, id),
-                       GetInitialStreamFlowControlWindowToSend(session, id),
-                       kStreamReceiveWindowLimit,
-                       session->flow_controller()->auto_tune_receive_window(),
-                       session->flow_controller()),
-      sequencer_(this) {}
-
-void PendingStream::OnDataAvailable() {
-  // Data should be kept in the sequencer so that
-  // QuicSession::ProcessPendingStream() can read it.
-}
-
-void PendingStream::OnFinRead() { QUICHE_DCHECK(sequencer_.IsClosed()); }
-
-void PendingStream::AddBytesConsumed(QuicByteCount bytes) {
-  // It will be called when the metadata of the stream is consumed.
-  flow_controller_.AddBytesConsumed(bytes);
-  connection_flow_controller_->AddBytesConsumed(bytes);
-}
-
-void PendingStream::ResetWithError(QuicResetStreamError /*error*/) {
-  // Currently PendingStream is only read-unidirectional. It shouldn't send
-  // Reset.
-  QUIC_NOTREACHED();
-}
-
-void PendingStream::OnUnrecoverableError(QuicErrorCode error,
-                                         const std::string& details) {
-  stream_delegate_->OnStreamError(error, details);
-}
-
-void PendingStream::OnUnrecoverableError(QuicErrorCode error,
-                                         QuicIetfTransportErrorCodes ietf_error,
-                                         const std::string& details) {
-  stream_delegate_->OnStreamError(error, ietf_error, details);
-}
-
-QuicStreamId PendingStream::id() const { return id_; }
-
-ParsedQuicVersion PendingStream::version() const { return version_; }
-
-void PendingStream::OnStreamFrame(const QuicStreamFrame& frame) {
-  QUICHE_DCHECK_EQ(frame.stream_id, id_);
-
-  bool is_stream_too_long =
-      (frame.offset > kMaxStreamLength) ||
-      (kMaxStreamLength - frame.offset < frame.data_length);
-  if (is_stream_too_long) {
-    // Close connection if stream becomes too long.
-    QUIC_PEER_BUG(quic_peer_bug_12570_1)
-        << "Receive stream frame reaches max stream length. frame offset "
-        << frame.offset << " length " << frame.data_length;
-    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
-                         "Peer sends more data than allowed on this stream.");
-    return;
-  }
-
-  if (frame.offset + frame.data_length > sequencer_.close_offset()) {
-    OnUnrecoverableError(
-        QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
-        absl::StrCat(
-            "Stream ", id_,
-            " received data with offset: ", frame.offset + frame.data_length,
-            ", which is beyond close offset: ", sequencer()->close_offset()));
-    return;
-  }
-
-  if (frame.fin) {
-    fin_received_ = true;
-  }
-
-  // This count includes duplicate data received.
-  QuicByteCount frame_payload_size = frame.data_length;
-  stream_bytes_read_ += frame_payload_size;
-
-  // Flow control is interested in tracking highest received offset.
-  // Only interested in received frames that carry data.
-  if (frame_payload_size > 0 &&
-      MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
-    // As the highest received offset has changed, check to see if this is a
-    // violation of flow control.
-    if (flow_controller_.FlowControlViolation() ||
-        connection_flow_controller_->FlowControlViolation()) {
-      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-                           "Flow control violation after increasing offset");
-      return;
-    }
-  }
-
-  sequencer_.OnStreamFrame(frame);
-}
-
-void PendingStream::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
-  QUICHE_DCHECK_EQ(frame.stream_id, id_);
-
-  if (frame.byte_offset > kMaxStreamLength) {
-    // Peer are not suppose to write bytes more than maxium allowed.
-    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
-                         "Reset frame stream offset overflow.");
-    return;
-  }
-
-  const QuicStreamOffset kMaxOffset =
-      std::numeric_limits<QuicStreamOffset>::max();
-  if (sequencer()->close_offset() != kMaxOffset &&
-      frame.byte_offset != sequencer()->close_offset()) {
-    OnUnrecoverableError(
-        QUIC_STREAM_MULTIPLE_OFFSET,
-        absl::StrCat("Stream ", id_,
-                     " received new final offset: ", frame.byte_offset,
-                     ", which is different from close offset: ",
-                     sequencer()->close_offset()));
-    return;
-  }
-
-  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
-  if (flow_controller_.FlowControlViolation() ||
-      connection_flow_controller_->FlowControlViolation()) {
-    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-                         "Flow control violation after increasing offset");
-    return;
-  }
-}
-
-void PendingStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
-  QUICHE_DCHECK(is_bidirectional_);
-  flow_controller_.UpdateSendWindowOffset(frame.max_data);
-}
-
-bool PendingStream::MaybeIncreaseHighestReceivedOffset(
-    QuicStreamOffset new_offset) {
-  uint64_t increment =
-      new_offset - flow_controller_.highest_received_byte_offset();
-  if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
-    return false;
-  }
-
-  // If |new_offset| increased the stream flow controller's highest received
-  // offset, increase the connection flow controller's value by the incremental
-  // difference.
-  connection_flow_controller_->UpdateHighestReceivedOffset(
-      connection_flow_controller_->highest_received_byte_offset() + increment);
-  return true;
-}
-
-void PendingStream::OnStopSending(
-    QuicResetStreamError stop_sending_error_code) {
-  if (!stop_sending_error_code_) {
-    stop_sending_error_code_ = stop_sending_error_code;
-  }
-}
-
-void PendingStream::MarkConsumed(QuicByteCount num_bytes) {
-  sequencer_.MarkConsumed(num_bytes);
-}
-
-void PendingStream::StopReading() {
-  QUIC_DVLOG(1) << "Stop reading from pending stream " << id();
-  sequencer_.StopReading();
-}
-
-QuicStream::QuicStream(PendingStream* pending, QuicSession* session,
-                       bool is_static)
-    : QuicStream(pending->id_, session, std::move(pending->sequencer_),
-                 is_static,
-                 QuicUtils::GetStreamType(pending->id_, session->perspective(),
-                                          /*peer_initiated = */ true,
-                                          session->version()),
-                 pending->stream_bytes_read_, pending->fin_received_,
-                 std::move(pending->flow_controller_),
-                 pending->connection_flow_controller_) {
-  QUICHE_DCHECK(session->version().HasIetfQuicFrames());
-  sequencer_.set_stream(this);
-}
-
-namespace {
-
-absl::optional<QuicFlowController> FlowController(QuicStreamId id,
-                                                  QuicSession* session,
-                                                  StreamType type) {
-  if (type == CRYPTO) {
-    // The only QuicStream with a StreamType of CRYPTO is QuicCryptoStream, when
-    // it is using crypto frames instead of stream frames. The QuicCryptoStream
-    // doesn't have any flow control in that case, so we don't create a
-    // QuicFlowController for it.
-    return absl::nullopt;
-  }
-  return QuicFlowController(
-      session, id,
-      /*is_connection_flow_controller*/ false,
-      GetReceivedFlowControlWindow(session, id),
-      GetInitialStreamFlowControlWindowToSend(session, id),
-      kStreamReceiveWindowLimit,
-      session->flow_controller()->auto_tune_receive_window(),
-      session->flow_controller());
-}
-
-}  // namespace
-
-QuicStream::QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
-                       StreamType type)
-    : QuicStream(id, session, QuicStreamSequencer(this), is_static, type, 0,
-                 false, FlowController(id, session, type),
-                 session->flow_controller()) {}
-
-QuicStream::QuicStream(QuicStreamId id, QuicSession* session,
-                       QuicStreamSequencer sequencer, bool is_static,
-                       StreamType type, uint64_t stream_bytes_read,
-                       bool fin_received,
-                       absl::optional<QuicFlowController> flow_controller,
-                       QuicFlowController* connection_flow_controller)
-    : sequencer_(std::move(sequencer)),
-      id_(id),
-      session_(session),
-      stream_delegate_(session),
-      precedence_(CalculateDefaultPriority(session)),
-      stream_bytes_read_(stream_bytes_read),
-      stream_error_(QuicResetStreamError::NoError()),
-      connection_error_(QUIC_NO_ERROR),
-      read_side_closed_(false),
-      write_side_closed_(false),
-      write_side_data_recvd_state_notified_(false),
-      fin_buffered_(false),
-      fin_sent_(false),
-      fin_outstanding_(false),
-      fin_lost_(false),
-      fin_received_(fin_received),
-      rst_sent_(false),
-      rst_received_(false),
-      stop_sending_sent_(false),
-      flow_controller_(std::move(flow_controller)),
-      connection_flow_controller_(connection_flow_controller),
-      stream_contributes_to_connection_flow_control_(true),
-      busy_counter_(0),
-      add_random_padding_after_fin_(false),
-      send_buffer_(
-          session->connection()->helper()->GetStreamSendBufferAllocator()),
-      buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
-      is_static_(is_static),
-      deadline_(QuicTime::Zero()),
-      was_draining_(false),
-      type_(VersionHasIetfQuicFrames(session->transport_version()) &&
-                    type != CRYPTO
-                ? QuicUtils::GetStreamType(id_, session->perspective(),
-                                           session->IsIncomingStream(id_),
-                                           session->version())
-                : type),
-      creation_time_(session->connection()->clock()->ApproximateNow()),
-      perspective_(session->perspective()) {
-  if (type_ == WRITE_UNIDIRECTIONAL) {
-    fin_received_ = true;
-    CloseReadSide();
-  } else if (type_ == READ_UNIDIRECTIONAL) {
-    fin_sent_ = true;
-    CloseWriteSide();
-  }
-  if (type_ != CRYPTO) {
-    stream_delegate_->RegisterStreamPriority(id, is_static_, precedence_);
-  }
-}
-
-QuicStream::~QuicStream() {
-  if (session_ != nullptr && IsWaitingForAcks()) {
-    QUIC_DVLOG(1)
-        << ENDPOINT << "Stream " << id_
-        << " gets destroyed while waiting for acks. stream_bytes_outstanding = "
-        << send_buffer_.stream_bytes_outstanding()
-        << ", fin_outstanding: " << fin_outstanding_;
-  }
-  if (stream_delegate_ != nullptr && type_ != CRYPTO) {
-    stream_delegate_->UnregisterStreamPriority(id(), is_static_);
-  }
-}
-
-void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
-  QUICHE_DCHECK_EQ(frame.stream_id, id_);
-
-  QUICHE_DCHECK(!(read_side_closed_ && write_side_closed_));
-
-  if (frame.fin && is_static_) {
-    OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
-                         "Attempt to close a static stream");
-    return;
-  }
-
-  if (type_ == WRITE_UNIDIRECTIONAL) {
-    OnUnrecoverableError(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
-                         "Data received on write unidirectional stream");
-    return;
-  }
-
-  bool is_stream_too_long =
-      (frame.offset > kMaxStreamLength) ||
-      (kMaxStreamLength - frame.offset < frame.data_length);
-  if (is_stream_too_long) {
-    // Close connection if stream becomes too long.
-    QUIC_PEER_BUG(quic_peer_bug_10586_1)
-        << "Receive stream frame on stream " << id_
-        << " reaches max stream length. frame offset " << frame.offset
-        << " length " << frame.data_length << ". " << sequencer_.DebugString();
-    OnUnrecoverableError(
-        QUIC_STREAM_LENGTH_OVERFLOW,
-        absl::StrCat("Peer sends more data than allowed on stream ", id_,
-                     ". frame: offset = ", frame.offset, ", length = ",
-                     frame.data_length, ". ", sequencer_.DebugString()));
-    return;
-  }
-
-  if (frame.offset + frame.data_length > sequencer_.close_offset()) {
-    OnUnrecoverableError(
-        QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
-        absl::StrCat(
-            "Stream ", id_,
-            " received data with offset: ", frame.offset + frame.data_length,
-            ", which is beyond close offset: ", sequencer_.close_offset()));
-    return;
-  }
-
-  if (frame.fin && !fin_received_) {
-    fin_received_ = true;
-    if (fin_sent_) {
-      QUICHE_DCHECK(!was_draining_);
-      session_->StreamDraining(id_,
-                               /*unidirectional=*/type_ != BIDIRECTIONAL);
-      was_draining_ = true;
-    }
-  }
-
-  if (read_side_closed_) {
-    QUIC_DLOG(INFO)
-        << ENDPOINT << "Stream " << frame.stream_id
-        << " is closed for reading. Ignoring newly received stream data.";
-    // The subclass does not want to read data:  blackhole the data.
-    return;
-  }
-
-  // This count includes duplicate data received.
-  QuicByteCount frame_payload_size = frame.data_length;
-  stream_bytes_read_ += frame_payload_size;
-
-  // Flow control is interested in tracking highest received offset.
-  // Only interested in received frames that carry data.
-  if (frame_payload_size > 0 &&
-      MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
-    // As the highest received offset has changed, check to see if this is a
-    // violation of flow control.
-    QUIC_BUG_IF(quic_bug_12570_2, !flow_controller_.has_value())
-        << ENDPOINT << "OnStreamFrame called on stream without flow control";
-    if ((flow_controller_.has_value() &&
-         flow_controller_->FlowControlViolation()) ||
-        connection_flow_controller_->FlowControlViolation()) {
-      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-                           "Flow control violation after increasing offset");
-      return;
-    }
-  }
-
-  sequencer_.OnStreamFrame(frame);
-}
-
-bool QuicStream::OnStopSending(QuicResetStreamError error) {
-  // Do not reset the stream if all data has been sent and acknowledged.
-  if (write_side_closed() && !IsWaitingForAcks()) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Ignoring STOP_SENDING for a write closed stream, id: "
-                  << id_;
-    return false;
-  }
-
-  if (is_static_) {
-    QUIC_DVLOG(1) << ENDPOINT
-                  << "Received STOP_SENDING for a static stream, id: " << id_
-                  << " Closing connection";
-    OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
-                         "Received STOP_SENDING for a static stream");
-    return false;
-  }
-
-  stream_error_ = error;
-  MaybeSendRstStream(error);
-  return true;
-}
-
-int QuicStream::num_frames_received() const {
-  return sequencer_.num_frames_received();
-}
-
-int QuicStream::num_duplicate_frames_received() const {
-  return sequencer_.num_duplicate_frames_received();
-}
-
-void QuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
-  rst_received_ = true;
-  if (frame.byte_offset > kMaxStreamLength) {
-    // Peer are not suppose to write bytes more than maxium allowed.
-    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
-                         "Reset frame stream offset overflow.");
-    return;
-  }
-
-  const QuicStreamOffset kMaxOffset =
-      std::numeric_limits<QuicStreamOffset>::max();
-  if (sequencer()->close_offset() != kMaxOffset &&
-      frame.byte_offset != sequencer()->close_offset()) {
-    OnUnrecoverableError(
-        QUIC_STREAM_MULTIPLE_OFFSET,
-        absl::StrCat("Stream ", id_,
-                     " received new final offset: ", frame.byte_offset,
-                     ", which is different from close offset: ",
-                     sequencer_.close_offset()));
-    return;
-  }
-
-  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
-  QUIC_BUG_IF(quic_bug_12570_3, !flow_controller_.has_value())
-      << ENDPOINT << "OnStreamReset called on stream without flow control";
-  if ((flow_controller_.has_value() &&
-       flow_controller_->FlowControlViolation()) ||
-      connection_flow_controller_->FlowControlViolation()) {
-    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
-                         "Flow control violation after increasing offset");
-    return;
-  }
-
-  stream_error_ = frame.error();
-  // Google QUIC closes both sides of the stream in response to a
-  // RESET_STREAM, IETF QUIC closes only the read side.
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    CloseWriteSide();
-  }
-  CloseReadSide();
-}
-
-void QuicStream::OnConnectionClosed(QuicErrorCode error,
-                                    ConnectionCloseSource /*source*/) {
-  if (read_side_closed_ && write_side_closed_) {
-    return;
-  }
-  if (error != QUIC_NO_ERROR) {
-    stream_error_ =
-        QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECTION_ERROR);
-    connection_error_ = error;
-  }
-
-  CloseWriteSide();
-  CloseReadSide();
-}
-
-void QuicStream::OnFinRead() {
-  QUICHE_DCHECK(sequencer_.IsClosed());
-  // OnFinRead can be called due to a FIN flag in a headers block, so there may
-  // have been no OnStreamFrame call with a FIN in the frame.
-  fin_received_ = true;
-  // If fin_sent_ is true, then CloseWriteSide has already been called, and the
-  // stream will be destroyed by CloseReadSide, so don't need to call
-  // StreamDraining.
-  CloseReadSide();
-}
-
-void QuicStream::SetFinSent() {
-  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
-  fin_sent_ = true;
-}
-
-void QuicStream::Reset(QuicRstStreamErrorCode error) {
-  ResetWithError(QuicResetStreamError::FromInternal(error));
-}
-
-void QuicStream::ResetWithError(QuicResetStreamError error) {
-  stream_error_ = error;
-  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-  MaybeSendStopSending(error);
-  MaybeSendRstStream(error);
-
-  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
-    session()->MaybeCloseZombieStream(id_);
-  }
-}
-
-void QuicStream::ResetWriteSide(QuicResetStreamError error) {
-  stream_error_ = error;
-  MaybeSendRstStream(error);
-
-  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
-    session()->MaybeCloseZombieStream(id_);
-  }
-}
-
-void QuicStream::SendStopSending(QuicResetStreamError error) {
-  stream_error_ = error;
-  MaybeSendStopSending(error);
-
-  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
-    session()->MaybeCloseZombieStream(id_);
-  }
-}
-
-void QuicStream::OnUnrecoverableError(QuicErrorCode error,
-                                      const std::string& details) {
-  stream_delegate_->OnStreamError(error, details);
-}
-
-void QuicStream::OnUnrecoverableError(QuicErrorCode error,
-                                      QuicIetfTransportErrorCodes ietf_error,
-                                      const std::string& details) {
-  stream_delegate_->OnStreamError(error, ietf_error, details);
-}
-
-const spdy::SpdyStreamPrecedence& QuicStream::precedence() const {
-  return precedence_;
-}
-
-void QuicStream::SetPriority(const spdy::SpdyStreamPrecedence& precedence) {
-  precedence_ = precedence;
-
-  MaybeSendPriorityUpdateFrame();
-
-  stream_delegate_->UpdateStreamPriority(id(), precedence);
-}
-
-void QuicStream::WriteOrBufferData(
-    absl::string_view data, bool fin,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  QUIC_BUG_IF(quic_bug_12570_4,
-              QuicUtils::IsCryptoStreamId(transport_version(), id_))
-      << ENDPOINT
-      << "WriteOrBufferData is used to send application data, use "
-         "WriteOrBufferDataAtLevel to send crypto data.";
-  return WriteOrBufferDataAtLevel(
-      data, fin, session()->GetEncryptionLevelToSendApplicationData(),
-      ack_listener);
-}
-
-void QuicStream::WriteOrBufferDataAtLevel(
-    absl::string_view data, bool fin, EncryptionLevel level,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  if (data.empty() && !fin) {
-    QUIC_BUG(quic_bug_10586_2) << "data.empty() && !fin";
-    return;
-  }
-
-  if (fin_buffered_) {
-    QUIC_BUG(quic_bug_10586_3) << "Fin already buffered";
-    return;
-  }
-  if (write_side_closed_) {
-    QUIC_DLOG(ERROR) << ENDPOINT
-                     << "Attempt to write when the write side is closed";
-    if (type_ == READ_UNIDIRECTIONAL) {
-      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
-                           "Try to send data on read unidirectional stream");
-    }
-    return;
-  }
-
-  fin_buffered_ = fin;
-
-  bool had_buffered_data = HasBufferedData();
-  // Do not respect buffered data upper limit as WriteOrBufferData guarantees
-  // all data to be consumed.
-  if (data.length() > 0) {
-    QuicStreamOffset offset = send_buffer_.stream_offset();
-    if (kMaxStreamLength - offset < data.length()) {
-      QUIC_BUG(quic_bug_10586_4) << "Write too many data via stream " << id_;
-      OnUnrecoverableError(
-          QUIC_STREAM_LENGTH_OVERFLOW,
-          absl::StrCat("Write too many data via stream ", id_));
-      return;
-    }
-    send_buffer_.SaveStreamData(data);
-    OnDataBuffered(offset, data.length(), ack_listener);
-  }
-  if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
-    // Write data if there is no buffered data before.
-    WriteBufferedData(level);
-  }
-}
-
-void QuicStream::OnCanWrite() {
-  if (HasDeadlinePassed()) {
-    OnDeadlinePassed();
-    return;
-  }
-  if (HasPendingRetransmission()) {
-    WritePendingRetransmission();
-    // Exit early to allow other streams to write pending retransmissions if
-    // any.
-    return;
-  }
-
-  if (write_side_closed_) {
-    QUIC_DLOG(ERROR)
-        << ENDPOINT << "Stream " << id()
-        << " attempting to write new data when the write side is closed";
-    return;
-  }
-  if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) {
-    WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
-  }
-  if (!fin_buffered_ && !fin_sent_ && CanWriteNewData()) {
-    // Notify upper layer to write new data when buffered data size is below
-    // low water mark.
-    OnCanWriteNewData();
-  }
-}
-
-void QuicStream::MaybeSendBlocked() {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_5)
-        << ENDPOINT << "MaybeSendBlocked called on stream without flow control";
-    return;
-  }
-  if (flow_controller_->ShouldSendBlocked()) {
-    session_->SendBlocked(id_);
-  }
-  if (!stream_contributes_to_connection_flow_control_) {
-    return;
-  }
-  if (connection_flow_controller_->ShouldSendBlocked()) {
-    session_->SendBlocked(QuicUtils::GetInvalidStreamId(transport_version()));
-  }
-  // If the stream is blocked by connection-level flow control but not by
-  // stream-level flow control, add the stream to the write blocked list so that
-  // the stream will be given a chance to write when a connection-level
-  // WINDOW_UPDATE arrives.
-  if (connection_flow_controller_->IsBlocked() &&
-      !flow_controller_->IsBlocked()) {
-    session_->MarkConnectionLevelWriteBlocked(id());
-  }
-}
-
-QuicConsumedData QuicStream::WriteMemSlice(quiche::QuicheMemSlice span,
-                                           bool fin) {
-  return WriteMemSlices(absl::MakeSpan(&span, 1), fin);
-}
-
-QuicConsumedData QuicStream::WriteMemSlices(
-    absl::Span<quiche::QuicheMemSlice> span, bool fin) {
-  QuicConsumedData consumed_data(0, false);
-  if (span.empty() && !fin) {
-    QUIC_BUG(quic_bug_10586_6) << "span.empty() && !fin";
-    return consumed_data;
-  }
-
-  if (fin_buffered_) {
-    QUIC_BUG(quic_bug_10586_7) << "Fin already buffered";
-    return consumed_data;
-  }
-
-  if (write_side_closed_) {
-    QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id()
-                     << " attempting to write when the write side is closed";
-    if (type_ == READ_UNIDIRECTIONAL) {
-      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
-                           "Try to send data on read unidirectional stream");
-    }
-    return consumed_data;
-  }
-
-  bool had_buffered_data = HasBufferedData();
-  if (CanWriteNewData() || span.empty()) {
-    consumed_data.fin_consumed = fin;
-    if (!span.empty()) {
-      // Buffer all data if buffered data size is below limit.
-      QuicStreamOffset offset = send_buffer_.stream_offset();
-      consumed_data.bytes_consumed = send_buffer_.SaveMemSliceSpan(span);
-      if (offset > send_buffer_.stream_offset() ||
-          kMaxStreamLength < send_buffer_.stream_offset()) {
-        QUIC_BUG(quic_bug_10586_8) << "Write too many data via stream " << id_;
-        OnUnrecoverableError(
-            QUIC_STREAM_LENGTH_OVERFLOW,
-            absl::StrCat("Write too many data via stream ", id_));
-        return consumed_data;
-      }
-      OnDataBuffered(offset, consumed_data.bytes_consumed, nullptr);
-    }
-  }
-  fin_buffered_ = consumed_data.fin_consumed;
-
-  if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
-    // Write data if there is no buffered data before.
-    WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
-  }
-
-  return consumed_data;
-}
-
-bool QuicStream::HasPendingRetransmission() const {
-  return send_buffer_.HasPendingRetransmission() || fin_lost_;
-}
-
-bool QuicStream::IsStreamFrameOutstanding(QuicStreamOffset offset,
-                                          QuicByteCount data_length,
-                                          bool fin) const {
-  return send_buffer_.IsStreamDataOutstanding(offset, data_length) ||
-         (fin && fin_outstanding_);
-}
-
-void QuicStream::CloseReadSide() {
-  if (read_side_closed_) {
-    return;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Done reading from stream " << id();
-
-  read_side_closed_ = true;
-  sequencer_.ReleaseBuffer();
-
-  if (write_side_closed_) {
-    QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
-    session_->OnStreamClosed(id());
-    OnClose();
-  }
-}
-
-void QuicStream::CloseWriteSide() {
-  if (write_side_closed_) {
-    return;
-  }
-  QUIC_DVLOG(1) << ENDPOINT << "Done writing to stream " << id();
-
-  write_side_closed_ = true;
-  if (read_side_closed_) {
-    QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
-    session_->OnStreamClosed(id());
-    OnClose();
-  }
-}
-
-void QuicStream::MaybeSendStopSending(QuicResetStreamError error) {
-  if (stop_sending_sent_) {
-    return;
-  }
-
-  if (!session()->version().UsesHttp3() && !error.ok()) {
-    // In gQUIC, RST with error closes both read and write side.
-    return;
-  }
-
-  if (session()->version().UsesHttp3()) {
-    session()->MaybeSendStopSendingFrame(id(), error);
-  } else {
-    QUICHE_DCHECK_EQ(QUIC_STREAM_NO_ERROR, error.internal_code());
-    session()->MaybeSendRstStreamFrame(id(), QuicResetStreamError::NoError(),
-                                       stream_bytes_written());
-  }
-  stop_sending_sent_ = true;
-  CloseReadSide();
-}
-
-void QuicStream::MaybeSendRstStream(QuicResetStreamError error) {
-  if (rst_sent_) {
-    return;
-  }
-
-  if (!session()->version().UsesHttp3()) {
-    QUIC_BUG_IF(quic_bug_12570_5, error.ok());
-    stop_sending_sent_ = true;
-    CloseReadSide();
-  }
-  session()->MaybeSendRstStreamFrame(id(), error, stream_bytes_written());
-  rst_sent_ = true;
-  CloseWriteSide();
-}
-
-bool QuicStream::HasBufferedData() const {
-  QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
-  return send_buffer_.stream_offset() > stream_bytes_written();
-}
-
-ParsedQuicVersion QuicStream::version() const { return session_->version(); }
-
-QuicTransportVersion QuicStream::transport_version() const {
-  return session_->transport_version();
-}
-
-HandshakeProtocol QuicStream::handshake_protocol() const {
-  return session_->connection()->version().handshake_protocol;
-}
-
-void QuicStream::StopReading() {
-  QUIC_DVLOG(1) << ENDPOINT << "Stop reading from stream " << id();
-  sequencer_.StopReading();
-}
-
-void QuicStream::OnClose() {
-  QUICHE_DCHECK(read_side_closed_ && write_side_closed_);
-
-  if (!fin_sent_ && !rst_sent_) {
-    QUIC_BUG_IF(quic_bug_12570_6, session()->connection()->connected() &&
-                                      session()->version().UsesHttp3())
-        << "The stream should've already sent RST in response to "
-           "STOP_SENDING";
-    // For flow control accounting, tell the peer how many bytes have been
-    // written on this stream before termination. Done here if needed, using a
-    // RST_STREAM frame.
-    MaybeSendRstStream(QUIC_RST_ACKNOWLEDGEMENT);
-    session_->MaybeCloseZombieStream(id_);
-  }
-
-  if (!flow_controller_.has_value() ||
-      flow_controller_->FlowControlViolation() ||
-      connection_flow_controller_->FlowControlViolation()) {
-    return;
-  }
-  // The stream is being closed and will not process any further incoming bytes.
-  // As there may be more bytes in flight, to ensure that both endpoints have
-  // the same connection level flow control state, mark all unreceived or
-  // buffered bytes as consumed.
-  QuicByteCount bytes_to_consume =
-      flow_controller_->highest_received_byte_offset() -
-      flow_controller_->bytes_consumed();
-  AddBytesConsumed(bytes_to_consume);
-}
-
-void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
-  if (type_ == READ_UNIDIRECTIONAL) {
-    OnUnrecoverableError(
-        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
-        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.");
-    return;
-  }
-
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_9)
-        << ENDPOINT
-        << "OnWindowUpdateFrame called on stream without flow control";
-    return;
-  }
-
-  if (flow_controller_->UpdateSendWindowOffset(frame.max_data)) {
-    // Let session unblock this stream.
-    session_->MarkConnectionLevelWriteBlocked(id_);
-  }
-}
-
-bool QuicStream::MaybeIncreaseHighestReceivedOffset(
-    QuicStreamOffset new_offset) {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_10)
-        << ENDPOINT
-        << "MaybeIncreaseHighestReceivedOffset called on stream without "
-           "flow control";
-    return false;
-  }
-  uint64_t increment =
-      new_offset - flow_controller_->highest_received_byte_offset();
-  if (!flow_controller_->UpdateHighestReceivedOffset(new_offset)) {
-    return false;
-  }
-
-  // If |new_offset| increased the stream flow controller's highest received
-  // offset, increase the connection flow controller's value by the incremental
-  // difference.
-  if (stream_contributes_to_connection_flow_control_) {
-    connection_flow_controller_->UpdateHighestReceivedOffset(
-        connection_flow_controller_->highest_received_byte_offset() +
-        increment);
-  }
-  return true;
-}
-
-void QuicStream::AddBytesSent(QuicByteCount bytes) {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_11)
-        << ENDPOINT << "AddBytesSent called on stream without flow control";
-    return;
-  }
-  flow_controller_->AddBytesSent(bytes);
-  if (stream_contributes_to_connection_flow_control_) {
-    connection_flow_controller_->AddBytesSent(bytes);
-  }
-}
-
-void QuicStream::AddBytesConsumed(QuicByteCount bytes) {
-  if (type_ == CRYPTO) {
-    // A stream with type CRYPTO has no flow control, so there's nothing this
-    // function needs to do. This function still gets called by the
-    // QuicStreamSequencers used by QuicCryptoStream.
-    return;
-  }
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_12570_7)
-        << ENDPOINT
-        << "AddBytesConsumed called on non-crypto stream without flow control";
-    return;
-  }
-  // Only adjust stream level flow controller if still reading.
-  if (!read_side_closed_) {
-    flow_controller_->AddBytesConsumed(bytes);
-  }
-
-  if (stream_contributes_to_connection_flow_control_) {
-    connection_flow_controller_->AddBytesConsumed(bytes);
-  }
-}
-
-bool QuicStream::MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
-                                             bool was_zero_rtt_rejected) {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_12)
-        << ENDPOINT
-        << "ConfigSendWindowOffset called on stream without flow control";
-    return false;
-  }
-
-  // The validation code below is for QUIC with TLS only.
-  if (new_offset < flow_controller_->send_window_offset()) {
-    QUICHE_DCHECK(session()->version().UsesTls());
-    if (was_zero_rtt_rejected && new_offset < flow_controller_->bytes_sent()) {
-      // The client is given flow control window lower than what's written in
-      // 0-RTT. This QUIC implementation is unable to retransmit them.
-      QUIC_BUG_IF(quic_bug_12570_8, perspective_ == Perspective::IS_SERVER)
-          << "Server streams' flow control should never be configured twice.";
-      OnUnrecoverableError(
-          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
-          absl::StrCat(
-              "Server rejected 0-RTT, aborting because new stream max data ",
-              new_offset, " for stream ", id_, " is less than currently used: ",
-              flow_controller_->bytes_sent()));
-      return false;
-    } else if (session()->version().AllowsLowFlowControlLimits()) {
-      // In IETF QUIC, if the client receives flow control limit lower than what
-      // was resumed from 0-RTT, depending on 0-RTT status, it's either the
-      // peer's fault or our implementation's fault.
-      QUIC_BUG_IF(quic_bug_12570_9, perspective_ == Perspective::IS_SERVER)
-          << "Server streams' flow control should never be configured twice.";
-      OnUnrecoverableError(
-          was_zero_rtt_rejected ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
-                                : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
-          absl::StrCat(
-              was_zero_rtt_rejected ? "Server rejected 0-RTT, aborting because "
-                                    : "",
-              "new stream max data ", new_offset, " decreases current limit: ",
-              flow_controller_->send_window_offset()));
-      return false;
-    }
-  }
-
-  if (flow_controller_->UpdateSendWindowOffset(new_offset)) {
-    // Let session unblock this stream.
-    session_->MarkConnectionLevelWriteBlocked(id_);
-  }
-  return true;
-}
-
-void QuicStream::AddRandomPaddingAfterFin() {
-  add_random_padding_after_fin_ = true;
-}
-
-bool QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
-                                    QuicByteCount data_length, bool fin_acked,
-                                    QuicTime::Delta /*ack_delay_time*/,
-                                    QuicTime /*receive_timestamp*/,
-                                    QuicByteCount* newly_acked_length) {
-  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Acking "
-                << "[" << offset << ", " << offset + data_length << "]"
-                << " fin = " << fin_acked;
-  *newly_acked_length = 0;
-  if (!send_buffer_.OnStreamDataAcked(offset, data_length,
-                                      newly_acked_length)) {
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent data.");
-    return false;
-  }
-  if (!fin_sent_ && fin_acked) {
-    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent fin.");
-    return false;
-  }
-  // Indicates whether ack listener's OnPacketAcked should be called.
-  const bool new_data_acked =
-      *newly_acked_length > 0 || (fin_acked && fin_outstanding_);
-  if (fin_acked) {
-    fin_outstanding_ = false;
-    fin_lost_ = false;
-  }
-  if (!IsWaitingForAcks() && write_side_closed_ &&
-      !write_side_data_recvd_state_notified_) {
-    OnWriteSideInDataRecvdState();
-    write_side_data_recvd_state_notified_ = true;
-  }
-  if (!IsWaitingForAcks() && read_side_closed_ && write_side_closed_) {
-    session_->MaybeCloseZombieStream(id_);
-  }
-  return new_data_acked;
-}
-
-void QuicStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
-                                            QuicByteCount data_length,
-                                            bool fin_retransmitted) {
-  send_buffer_.OnStreamDataRetransmitted(offset, data_length);
-  if (fin_retransmitted) {
-    fin_lost_ = false;
-  }
-}
-
-void QuicStream::OnStreamFrameLost(QuicStreamOffset offset,
-                                   QuicByteCount data_length, bool fin_lost) {
-  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Losting "
-                << "[" << offset << ", " << offset + data_length << "]"
-                << " fin = " << fin_lost;
-  if (data_length > 0) {
-    send_buffer_.OnStreamDataLost(offset, data_length);
-  }
-  if (fin_lost && fin_outstanding_) {
-    fin_lost_ = true;
-  }
-}
-
-bool QuicStream::RetransmitStreamData(QuicStreamOffset offset,
-                                      QuicByteCount data_length, bool fin,
-                                      TransmissionType type) {
-  QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
-                type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
-  if (HasDeadlinePassed()) {
-    OnDeadlinePassed();
-    return true;
-  }
-  QuicIntervalSet<QuicStreamOffset> retransmission(offset,
-                                                   offset + data_length);
-  retransmission.Difference(bytes_acked());
-  bool retransmit_fin = fin && fin_outstanding_;
-  if (retransmission.Empty() && !retransmit_fin) {
-    return true;
-  }
-  QuicConsumedData consumed(0, false);
-  for (const auto& interval : retransmission) {
-    QuicStreamOffset retransmission_offset = interval.min();
-    QuicByteCount retransmission_length = interval.max() - interval.min();
-    const bool can_bundle_fin =
-        retransmit_fin && (retransmission_offset + retransmission_length ==
-                           stream_bytes_written());
-    consumed = stream_delegate_->WritevData(
-        id_, retransmission_length, retransmission_offset,
-        can_bundle_fin ? FIN : NO_FIN, type,
-        session()->GetEncryptionLevelToSendApplicationData());
-    QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
-                  << " is forced to retransmit stream data ["
-                  << retransmission_offset << ", "
-                  << retransmission_offset + retransmission_length
-                  << ") and fin: " << can_bundle_fin
-                  << ", consumed: " << consumed;
-    OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
-                               consumed.fin_consumed);
-    if (can_bundle_fin) {
-      retransmit_fin = !consumed.fin_consumed;
-    }
-    if (consumed.bytes_consumed < retransmission_length ||
-        (can_bundle_fin && !consumed.fin_consumed)) {
-      // Connection is write blocked.
-      return false;
-    }
-  }
-  if (retransmit_fin) {
-    QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
-                  << " retransmits fin only frame.";
-    consumed = stream_delegate_->WritevData(
-        id_, 0, stream_bytes_written(), FIN, type,
-        session()->GetEncryptionLevelToSendApplicationData());
-    if (!consumed.fin_consumed) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicStream::IsWaitingForAcks() const {
-  return (!rst_sent_ || stream_error_.ok()) &&
-         (send_buffer_.stream_bytes_outstanding() || fin_outstanding_);
-}
-
-QuicByteCount QuicStream::ReadableBytes() const {
-  return sequencer_.ReadableBytes();
-}
-
-bool QuicStream::WriteStreamData(QuicStreamOffset offset,
-                                 QuicByteCount data_length,
-                                 QuicDataWriter* writer) {
-  QUICHE_DCHECK_LT(0u, data_length);
-  QUIC_DVLOG(2) << ENDPOINT << "Write stream " << id_ << " data from offset "
-                << offset << " length " << data_length;
-  return send_buffer_.WriteStreamData(offset, data_length, writer);
-}
-
-void QuicStream::WriteBufferedData(EncryptionLevel level) {
-  QUICHE_DCHECK(!write_side_closed_ && (HasBufferedData() || fin_buffered_));
-
-  if (session_->ShouldYield(id())) {
-    session_->MarkConnectionLevelWriteBlocked(id());
-    return;
-  }
-
-  // Size of buffered data.
-  QuicByteCount write_length = BufferedDataBytes();
-
-  // A FIN with zero data payload should not be flow control blocked.
-  bool fin_with_zero_data = (fin_buffered_ && write_length == 0);
-
-  bool fin = fin_buffered_;
-
-  // How much data flow control permits to be written.
-  QuicByteCount send_window;
-  if (flow_controller_.has_value()) {
-    send_window = flow_controller_->SendWindowSize();
-  } else {
-    send_window = std::numeric_limits<QuicByteCount>::max();
-    QUIC_BUG(quic_bug_10586_13)
-        << ENDPOINT
-        << "WriteBufferedData called on stream without flow control";
-  }
-  if (stream_contributes_to_connection_flow_control_) {
-    send_window =
-        std::min(send_window, connection_flow_controller_->SendWindowSize());
-  }
-
-  if (send_window == 0 && !fin_with_zero_data) {
-    // Quick return if nothing can be sent.
-    MaybeSendBlocked();
-    return;
-  }
-
-  if (write_length > send_window) {
-    // Don't send the FIN unless all the data will be sent.
-    fin = false;
-
-    // Writing more data would be a violation of flow control.
-    write_length = send_window;
-    QUIC_DVLOG(1) << "stream " << id() << " shortens write length to "
-                  << write_length << " due to flow control";
-  }
-
-  StreamSendingState state = fin ? FIN : NO_FIN;
-  if (fin && add_random_padding_after_fin_) {
-    state = FIN_AND_PADDING;
-  }
-  QuicConsumedData consumed_data =
-      stream_delegate_->WritevData(id(), write_length, stream_bytes_written(),
-                                   state, NOT_RETRANSMISSION, level);
-
-  OnStreamDataConsumed(consumed_data.bytes_consumed);
-
-  AddBytesSent(consumed_data.bytes_consumed);
-  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " sends "
-                << stream_bytes_written() << " bytes "
-                << " and has buffered data " << BufferedDataBytes() << " bytes."
-                << " fin is sent: " << consumed_data.fin_consumed
-                << " fin is buffered: " << fin_buffered_;
-
-  // The write may have generated a write error causing this stream to be
-  // closed. If so, simply return without marking the stream write blocked.
-  if (write_side_closed_) {
-    return;
-  }
-
-  if (consumed_data.bytes_consumed == write_length) {
-    if (!fin_with_zero_data) {
-      MaybeSendBlocked();
-    }
-    if (fin && consumed_data.fin_consumed) {
-      QUICHE_DCHECK(!fin_sent_);
-      fin_sent_ = true;
-      fin_outstanding_ = true;
-      if (fin_received_) {
-        QUICHE_DCHECK(!was_draining_);
-        session_->StreamDraining(id_,
-                                 /*unidirectional=*/type_ != BIDIRECTIONAL);
-        was_draining_ = true;
-      }
-      CloseWriteSide();
-    } else if (fin && !consumed_data.fin_consumed) {
-      session_->MarkConnectionLevelWriteBlocked(id());
-    }
-  } else {
-    session_->MarkConnectionLevelWriteBlocked(id());
-  }
-  if (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed) {
-    busy_counter_ = 0;
-  }
-}
-
-uint64_t QuicStream::BufferedDataBytes() const {
-  QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
-  return send_buffer_.stream_offset() - stream_bytes_written();
-}
-
-bool QuicStream::CanWriteNewData() const {
-  return BufferedDataBytes() < buffered_data_threshold_;
-}
-
-bool QuicStream::CanWriteNewDataAfterData(QuicByteCount length) const {
-  return (BufferedDataBytes() + length) < buffered_data_threshold_;
-}
-
-uint64_t QuicStream::stream_bytes_written() const {
-  return send_buffer_.stream_bytes_written();
-}
-
-const QuicIntervalSet<QuicStreamOffset>& QuicStream::bytes_acked() const {
-  return send_buffer_.bytes_acked();
-}
-
-void QuicStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
-  send_buffer_.OnStreamDataConsumed(bytes_consumed);
-}
-
-void QuicStream::WritePendingRetransmission() {
-  while (HasPendingRetransmission()) {
-    QuicConsumedData consumed(0, false);
-    if (!send_buffer_.HasPendingRetransmission()) {
-      QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
-                    << " retransmits fin only frame.";
-      consumed = stream_delegate_->WritevData(
-          id_, 0, stream_bytes_written(), FIN, LOSS_RETRANSMISSION,
-          session()->GetEncryptionLevelToSendApplicationData());
-      fin_lost_ = !consumed.fin_consumed;
-      if (fin_lost_) {
-        // Connection is write blocked.
-        return;
-      }
-    } else {
-      StreamPendingRetransmission pending =
-          send_buffer_.NextPendingRetransmission();
-      // Determine whether the lost fin can be bundled with the data.
-      const bool can_bundle_fin =
-          fin_lost_ &&
-          (pending.offset + pending.length == stream_bytes_written());
-      consumed = stream_delegate_->WritevData(
-          id_, pending.length, pending.offset, can_bundle_fin ? FIN : NO_FIN,
-          LOSS_RETRANSMISSION,
-          session()->GetEncryptionLevelToSendApplicationData());
-      QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
-                    << " tries to retransmit stream data [" << pending.offset
-                    << ", " << pending.offset + pending.length
-                    << ") and fin: " << can_bundle_fin
-                    << ", consumed: " << consumed;
-      OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
-                                 consumed.fin_consumed);
-      if (consumed.bytes_consumed < pending.length ||
-          (can_bundle_fin && !consumed.fin_consumed)) {
-        // Connection is write blocked.
-        return;
-      }
-    }
-  }
-}
-
-bool QuicStream::MaybeSetTtl(QuicTime::Delta ttl) {
-  if (is_static_) {
-    QUIC_BUG(quic_bug_10586_14) << "Cannot set TTL of a static stream.";
-    return false;
-  }
-  if (deadline_.IsInitialized()) {
-    QUIC_DLOG(WARNING) << "Deadline has already been set.";
-    return false;
-  }
-  QuicTime now = session()->connection()->clock()->ApproximateNow();
-  deadline_ = now + ttl;
-  return true;
-}
-
-bool QuicStream::HasDeadlinePassed() const {
-  if (!deadline_.IsInitialized()) {
-    // No deadline has been set.
-    return false;
-  }
-  QuicTime now = session()->connection()->clock()->ApproximateNow();
-  if (now < deadline_) {
-    return false;
-  }
-  // TTL expired.
-  QUIC_DVLOG(1) << "stream " << id() << " deadline has passed";
-  return true;
-}
-
-void QuicStream::OnDeadlinePassed() { Reset(QUIC_STREAM_TTL_EXPIRED); }
-
-bool QuicStream::IsFlowControlBlocked() const {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_15)
-        << "Trying to access non-existent flow controller.";
-    return false;
-  }
-  return flow_controller_->IsBlocked();
-}
-
-QuicStreamOffset QuicStream::highest_received_byte_offset() const {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_16)
-        << "Trying to access non-existent flow controller.";
-    return 0;
-  }
-  return flow_controller_->highest_received_byte_offset();
-}
-
-void QuicStream::UpdateReceiveWindowSize(QuicStreamOffset size) {
-  if (!flow_controller_.has_value()) {
-    QUIC_BUG(quic_bug_10586_17)
-        << "Trying to access non-existent flow controller.";
-    return;
-  }
-  flow_controller_->UpdateReceiveWindowSize(size);
-}
-
-// static
-spdy::SpdyStreamPrecedence QuicStream::CalculateDefaultPriority(
-    const QuicSession* session) {
-  return spdy::SpdyStreamPrecedence(
-      VersionUsesHttp3(session->transport_version())
-          ? kDefaultUrgency
-          : QuicStream::kDefaultPriority);
-}
-
-absl::optional<QuicByteCount> QuicStream::GetSendWindow() const {
-  return flow_controller_.has_value()
-             ? absl::optional<QuicByteCount>(flow_controller_->SendWindowSize())
-             : absl::nullopt;
-}
-
-absl::optional<QuicByteCount> QuicStream::GetReceiveWindow() const {
-  return flow_controller_.has_value()
-             ? absl::optional<QuicByteCount>(
-                   flow_controller_->receive_window_size())
-             : absl::nullopt;
-}
-
-void QuicStream::OnStreamCreatedFromPendingStream() {
-  sequencer()->SetUnblocked();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h
deleted file mode 100644
index 0547e74..0000000
--- a/quic/core/quic_stream.h
+++ /dev/null
@@ -1,626 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The base class for client/server QUIC streams.
-
-// It does not contain the entire interface needed by an application to interact
-// with a QUIC stream.  Some parts of the interface must be obtained by
-// accessing the owning session object.  A subclass of QuicStream
-// connects the object and the application that generates and consumes the data
-// of the stream.
-
-// The QuicStream object has a dependent QuicStreamSequencer object,
-// which is given the stream frames as they arrive, and provides stream data in
-// order by invoking ProcessRawData().
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/core/stream_delegate_interface.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/platform/api/quiche_reference_counted.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamPeer;
-}  // namespace test
-
-class QuicSession;
-class QuicStream;
-
-// Buffers frames for a stream until the first byte of that frame arrives.
-class QUIC_EXPORT_PRIVATE PendingStream
-    : public QuicStreamSequencer::StreamInterface {
- public:
-  PendingStream(QuicStreamId id, QuicSession* session);
-  PendingStream(const PendingStream&) = delete;
-  PendingStream(PendingStream&&) = default;
-  ~PendingStream() override = default;
-
-  // QuicStreamSequencer::StreamInterface
-  void OnDataAvailable() override;
-  void OnFinRead() override;
-  void AddBytesConsumed(QuicByteCount bytes) override;
-  void ResetWithError(QuicResetStreamError error) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            const std::string& details) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            QuicIetfTransportErrorCodes ietf_error,
-                            const std::string& details) override;
-  QuicStreamId id() const override;
-  ParsedQuicVersion version() const override;
-
-  // Buffers the contents of |frame|. Frame must have a non-zero offset.
-  // If the data violates flow control, the connection will be closed.
-  void OnStreamFrame(const QuicStreamFrame& frame);
-
-  bool is_bidirectional() const { return is_bidirectional_; }
-
-  // Stores the final byte offset from |frame|.
-  // If the final offset violates flow control, the connection will be closed.
-  void OnRstStreamFrame(const QuicRstStreamFrame& frame);
-
-  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
-
-  void OnStopSending(QuicResetStreamError stop_sending_error_code);
-
-  // The error code received from QuicStopSendingFrame (if any).
-  const absl::optional<QuicResetStreamError>& GetStopSendingErrorCode() const {
-    return stop_sending_error_code_;
-  }
-
-  // Returns the number of bytes read on this stream.
-  uint64_t stream_bytes_read() { return stream_bytes_read_; }
-
-  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
-
-  void MarkConsumed(QuicByteCount num_bytes);
-
-  // Tells the sequencer to ignore all incoming data itself and not call
-  // OnDataAvailable().
-  void StopReading();
-
- private:
-  friend class QuicStream;
-
-  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
-
-  // ID of this stream.
-  QuicStreamId id_;
-
-  // QUIC version being used by this stream.
-  ParsedQuicVersion version_;
-
-  // |stream_delegate_| must outlive this stream.
-  StreamDelegateInterface* stream_delegate_;
-
-  // Bytes read refers to payload bytes only: they do not include framing,
-  // encryption overhead etc.
-  uint64_t stream_bytes_read_;
-
-  // True if a frame containing a fin has been received.
-  bool fin_received_;
-
-  // True if this pending stream is backing a bidirectional stream.
-  bool is_bidirectional_;
-
-  // Connection-level flow controller. Owned by the session.
-  QuicFlowController* connection_flow_controller_;
-  // Stream-level flow controller.
-  QuicFlowController flow_controller_;
-  // Stores the buffered frames.
-  QuicStreamSequencer sequencer_;
-  // The error code received from QuicStopSendingFrame (if any).
-  absl::optional<QuicResetStreamError> stop_sending_error_code_;
-};
-
-class QUIC_EXPORT_PRIVATE QuicStream
-    : public QuicStreamSequencer::StreamInterface {
- public:
-  // Default priority for Google QUIC.
-  // This is somewhat arbitrary.  It's possible, but unlikely, we will either
-  // fail to set a priority client-side, or cancel a stream before stripping the
-  // priority from the wire server-side.  In either case, start out with a
-  // priority in the middle in case of Google QUIC.
-  static const spdy::SpdyPriority kDefaultPriority = 3;
-  static_assert(kDefaultPriority ==
-                    (spdy::kV3LowestPriority + spdy::kV3HighestPriority) / 2,
-                "Unexpected value of kDefaultPriority");
-
-  // Creates a new stream with stream_id |id| associated with |session|. If
-  // |is_static| is true, then the stream will be given precedence
-  // over other streams when determing what streams should write next.
-  // |type| indicates whether the stream is bidirectional, read unidirectional
-  // or write unidirectional.
-  // TODO(fayang): Remove |type| when IETF stream ID numbering fully kicks in.
-  QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
-             StreamType type);
-  QuicStream(PendingStream* pending, QuicSession* session, bool is_static);
-  QuicStream(const QuicStream&) = delete;
-  QuicStream& operator=(const QuicStream&) = delete;
-
-  virtual ~QuicStream();
-
-  // Default priority for IETF QUIC, defined by the priority extension at
-  // https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html#urgency.
-  static const int kDefaultUrgency = 3;
-
-  // QuicStreamSequencer::StreamInterface implementation.
-  QuicStreamId id() const override { return id_; }
-  ParsedQuicVersion version() const override;
-  // Called by the stream subclass after it has consumed the final incoming
-  // data.
-  void OnFinRead() override;
-
-  // Called by the subclass or the sequencer to reset the stream from this
-  // end.
-  void ResetWithError(QuicResetStreamError error) override;
-  // Convenience wrapper for the method above.
-  // TODO(b/200606367): switch all calls to using QuicResetStreamError
-  // interface.
-  void Reset(QuicRstStreamErrorCode error);
-
-  // Reset() sends both RESET_STREAM and STOP_SENDING; the two methods below
-  // allow to send only one of those.
-  void ResetWriteSide(QuicResetStreamError error);
-  void SendStopSending(QuicResetStreamError error);
-
-  // Called by the subclass or the sequencer to close the entire connection from
-  // this end.
-  void OnUnrecoverableError(QuicErrorCode error,
-                            const std::string& details) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            QuicIetfTransportErrorCodes ietf_error,
-                            const std::string& details) override;
-
-  // Called by the session when a (potentially duplicate) stream frame has been
-  // received for this stream.
-  virtual void OnStreamFrame(const QuicStreamFrame& frame);
-
-  // Called by the session when the connection becomes writeable to allow the
-  // stream to write any pending data.
-  virtual void OnCanWrite();
-
-  // Called by the session when the endpoint receives a RST_STREAM from the
-  // peer.
-  virtual void OnStreamReset(const QuicRstStreamFrame& frame);
-
-  // Called by the session when the endpoint receives or sends a connection
-  // close, and should immediately close the stream.
-  virtual void OnConnectionClosed(QuicErrorCode error,
-                                  ConnectionCloseSource source);
-
-  const spdy::SpdyStreamPrecedence& precedence() const;
-
-  // Send PRIORITY_UPDATE frame if application protocol supports it.
-  virtual void MaybeSendPriorityUpdateFrame() {}
-
-  // Sets |priority_| to priority.  This should only be called before bytes are
-  // written to the server.  For a server stream, this is called when a
-  // PRIORITY_UPDATE frame is received.  This calls
-  // MaybeSendPriorityUpdateFrame(), which for a client stream might send a
-  // PRIORITY_UPDATE frame.
-  void SetPriority(const spdy::SpdyStreamPrecedence& precedence);
-
-  // Returns true if this stream is still waiting for acks of sent data.
-  // This will return false if all data has been acked, or if the stream
-  // is no longer interested in data being acked (which happens when
-  // a stream is reset because of an error).
-  bool IsWaitingForAcks() const;
-
-  // Number of bytes available to read.
-  QuicByteCount ReadableBytes() const;
-
-  QuicRstStreamErrorCode stream_error() const {
-    return stream_error_.internal_code();
-  }
-  QuicErrorCode connection_error() const { return connection_error_; }
-
-  bool reading_stopped() const {
-    return sequencer_.ignore_read_data() || read_side_closed_;
-  }
-  bool write_side_closed() const { return write_side_closed_; }
-  bool read_side_closed() const { return read_side_closed_; }
-
-  bool IsZombie() const {
-    return read_side_closed_ && write_side_closed_ && IsWaitingForAcks();
-  }
-
-  bool rst_received() const { return rst_received_; }
-  bool rst_sent() const { return rst_sent_; }
-  bool fin_received() const { return fin_received_; }
-  bool fin_sent() const { return fin_sent_; }
-  bool fin_outstanding() const { return fin_outstanding_; }
-  bool fin_lost() const { return fin_lost_; }
-
-  uint64_t BufferedDataBytes() const;
-
-  uint64_t stream_bytes_read() const { return stream_bytes_read_; }
-  uint64_t stream_bytes_written() const;
-
-  size_t busy_counter() const { return busy_counter_; }
-  void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }
-
-  // Adjust the flow control window according to new offset in |frame|.
-  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
-
-  int num_frames_received() const;
-  int num_duplicate_frames_received() const;
-
-  // Flow controller related methods.
-  bool IsFlowControlBlocked() const;
-  QuicStreamOffset highest_received_byte_offset() const;
-  void UpdateReceiveWindowSize(QuicStreamOffset size);
-
-  // Called when endpoint receives a frame which could increase the highest
-  // offset.
-  // Returns true if the highest offset did increase.
-  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
-
-  // Set the flow controller's send window offset from session config.
-  // |was_zero_rtt_rejected| is true if this config is from a rejected IETF QUIC
-  // 0-RTT attempt. Closes the connection and returns false if |new_offset| is
-  // not valid.
-  bool MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
-                                   bool was_zero_rtt_rejected);
-
-  // Returns true if the stream has received either a RST_STREAM or a FIN -
-  // either of which gives a definitive number of bytes which the peer has
-  // sent. If this is not true on deletion of the stream object, the session
-  // must keep track of the stream's byte offset until a definitive final value
-  // arrives.
-  bool HasReceivedFinalOffset() const { return fin_received_ || rst_received_; }
-
-  // Returns true if the stream has queued data waiting to write.
-  bool HasBufferedData() const;
-
-  // Returns the version of QUIC being used for this stream.
-  QuicTransportVersion transport_version() const;
-
-  // Returns the crypto handshake protocol that was used on this stream's
-  // connection.
-  HandshakeProtocol handshake_protocol() const;
-
-  // Sets the sequencer to consume all incoming data itself and not call
-  // OnDataAvailable().
-  // When the FIN is received, the stream will be notified automatically (via
-  // OnFinRead()) (which may happen during the call of StopReading()).
-  // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
-  // stop sending stream-level flow-control updates when this end sends FIN.
-  virtual void StopReading();
-
-  // Sends as much of |data| to the connection on the application encryption
-  // level as the connection will consume, and then buffers any remaining data
-  // in the send buffer. If fin is true: if it is immediately passed on to the
-  // session, write_side_closed() becomes true, otherwise fin_buffered_ becomes
-  // true.
-  void WriteOrBufferData(
-      absl::string_view data, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  // Sends |data| to connection with specified |level|.
-  void WriteOrBufferDataAtLevel(
-      absl::string_view data, bool fin, EncryptionLevel level,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  // Adds random padding after the fin is consumed for this stream.
-  void AddRandomPaddingAfterFin();
-
-  // Write |data_length| of data starts at |offset| from send buffer.
-  bool WriteStreamData(QuicStreamOffset offset, QuicByteCount data_length,
-                       QuicDataWriter* writer);
-
-  // Called when data [offset, offset + data_length) is acked. |fin_acked|
-  // indicates whether the fin is acked. Returns true and updates
-  // |newly_acked_length| if any new stream data (including fin) gets acked.
-  virtual bool OnStreamFrameAcked(QuicStreamOffset offset,
-                                  QuicByteCount data_length, bool fin_acked,
-                                  QuicTime::Delta ack_delay_time,
-                                  QuicTime receive_timestamp,
-                                  QuicByteCount* newly_acked_length);
-
-  // Called when data [offset, offset + data_length) was retransmitted.
-  // |fin_retransmitted| indicates whether fin was retransmitted.
-  virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
-                                          QuicByteCount data_length,
-                                          bool fin_retransmitted);
-
-  // Called when data [offset, offset + data_length) is considered as lost.
-  // |fin_lost| indicates whether the fin is considered as lost.
-  virtual void OnStreamFrameLost(QuicStreamOffset offset,
-                                 QuicByteCount data_length, bool fin_lost);
-
-  // Called to retransmit outstanding portion in data [offset, offset +
-  // data_length) and |fin| with Transmission |type|.
-  // Returns true if all data gets retransmitted.
-  virtual bool RetransmitStreamData(QuicStreamOffset offset,
-                                    QuicByteCount data_length, bool fin,
-                                    TransmissionType type);
-
-  // Sets deadline of this stream to be now + |ttl|, returns true if the setting
-  // succeeds.
-  bool MaybeSetTtl(QuicTime::Delta ttl);
-
-  // Commits data into the stream write buffer, and potentially sends it over
-  // the wire.  This method has all-or-nothing semantics: if the write buffer is
-  // not full, all of the memslices in |span| are moved into it; otherwise,
-  // nothing happens.
-  QuicConsumedData WriteMemSlices(absl::Span<quiche::QuicheMemSlice> span,
-                                  bool fin);
-  QuicConsumedData WriteMemSlice(quiche::QuicheMemSlice span, bool fin);
-
-  // Returns true if any stream data is lost (including fin) and needs to be
-  // retransmitted.
-  virtual bool HasPendingRetransmission() const;
-
-  // Returns true if any portion of data [offset, offset + data_length) is
-  // outstanding or fin is outstanding (if |fin| is true). Returns false
-  // otherwise.
-  bool IsStreamFrameOutstanding(QuicStreamOffset offset,
-                                QuicByteCount data_length, bool fin) const;
-
-  StreamType type() const { return type_; }
-
-  // Handle received StopSending frame. Returns true if the processing finishes
-  // gracefully.
-  virtual bool OnStopSending(QuicResetStreamError error);
-
-  // Returns true if the stream is static.
-  bool is_static() const { return is_static_; }
-
-  bool was_draining() const { return was_draining_; }
-
-  static spdy::SpdyStreamPrecedence CalculateDefaultPriority(
-      const QuicSession* session);
-
-  QuicTime creation_time() const { return creation_time_; }
-
-  bool fin_buffered() const { return fin_buffered_; }
-
-  // True if buffered data in send buffer is below buffered_data_threshold_.
-  bool CanWriteNewData() const;
-
-  // Called immediately after the stream is created from a pending stream,
-  // indicating it can start processing data.
-  void OnStreamCreatedFromPendingStream();
-
- protected:
-  // Called when data of [offset, offset + data_length] is buffered in send
-  // buffer.
-  virtual void OnDataBuffered(
-      QuicStreamOffset /*offset*/, QuicByteCount /*data_length*/,
-      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
-      /*ack_listener*/) {}
-
-  // Called just before the object is destroyed.
-  // The object should not be accessed after OnClose is called.
-  // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
-  // a RST_STREAM has been sent.
-  virtual void OnClose();
-
-  // True if buffered data in send buffer is still below
-  // buffered_data_threshold_ even after writing |length| bytes.
-  bool CanWriteNewDataAfterData(QuicByteCount length) const;
-
-  // Called when upper layer can write new data.
-  virtual void OnCanWriteNewData() {}
-
-  // Called when |bytes_consumed| bytes has been consumed.
-  virtual void OnStreamDataConsumed(QuicByteCount bytes_consumed);
-
-  // Called by the stream sequencer as bytes are consumed from the buffer.
-  // If the receive window has dropped below the threshold, then send a
-  // WINDOW_UPDATE frame.
-  void AddBytesConsumed(QuicByteCount bytes) override;
-
-  // Writes pending retransmissions if any.
-  virtual void WritePendingRetransmission();
-
-  // This is called when stream tries to retransmit data after deadline_. Make
-  // this virtual so that subclasses can implement their own logics.
-  virtual void OnDeadlinePassed();
-
-  // Called to set fin_sent_. This is only used by Google QUIC while body is
-  // empty.
-  void SetFinSent();
-
-  // Send STOP_SENDING if it hasn't been sent yet.
-  void MaybeSendStopSending(QuicResetStreamError error);
-
-  // Send RESET_STREAM if it hasn't been sent yet.
-  void MaybeSendRstStream(QuicResetStreamError error);
-
-  // Convenience warppers for two methods above.
-  void MaybeSendRstStream(QuicRstStreamErrorCode error) {
-    MaybeSendRstStream(QuicResetStreamError::FromInternal(error));
-  }
-  void MaybeSendStopSending(QuicRstStreamErrorCode error) {
-    MaybeSendStopSending(QuicResetStreamError::FromInternal(error));
-  }
-
-  // Close the write side of the socket.  Further writes will fail.
-  // Can be called by the subclass or internally.
-  // Does not send a FIN.  May cause the stream to be closed.
-  virtual void CloseWriteSide();
-
-  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
-  void set_stream_error(QuicResetStreamError error) { stream_error_ = error; }
-
-  StreamDelegateInterface* stream_delegate() { return stream_delegate_; }
-
-  const QuicSession* session() const { return session_; }
-  QuicSession* session() { return session_; }
-
-  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
-  QuicStreamSequencer* sequencer() { return &sequencer_; }
-
-  void DisableConnectionFlowControlForThisStream() {
-    stream_contributes_to_connection_flow_control_ = false;
-  }
-
-  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;
-
-  const QuicStreamSendBuffer& send_buffer() const { return send_buffer_; }
-
-  QuicStreamSendBuffer& send_buffer() { return send_buffer_; }
-
-  // Called when the write side of the stream is closed, and all of the outgoing
-  // data has been acknowledged.  This corresponds to the "Data Recvd" state of
-  // RFC 9000.
-  virtual void OnWriteSideInDataRecvdState() {}
-
-  // Return the current flow control send window in bytes.
-  absl::optional<QuicByteCount> GetSendWindow() const;
-  absl::optional<QuicByteCount> GetReceiveWindow() const;
-
- private:
-  friend class test::QuicStreamPeer;
-  friend class QuicStreamUtils;
-
-  QuicStream(QuicStreamId id, QuicSession* session,
-             QuicStreamSequencer sequencer, bool is_static, StreamType type,
-             uint64_t stream_bytes_read, bool fin_received,
-             absl::optional<QuicFlowController> flow_controller,
-             QuicFlowController* connection_flow_controller);
-
-  // Calls MaybeSendBlocked on the stream's flow controller and the connection
-  // level flow controller.  If the stream is flow control blocked by the
-  // connection-level flow controller but not by the stream-level flow
-  // controller, marks this stream as connection-level write blocked.
-  void MaybeSendBlocked();
-
-  // Write buffered data (in send buffer) at |level|.
-  void WriteBufferedData(EncryptionLevel level);
-
-  // Close the read side of the stream.  May cause the stream to be closed.
-  void CloseReadSide();
-
-  // Called when bytes are sent to the peer.
-  void AddBytesSent(QuicByteCount bytes);
-
-  // Returns true if deadline_ has passed.
-  bool HasDeadlinePassed() const;
-
-  QuicStreamSequencer sequencer_;
-  QuicStreamId id_;
-  // Pointer to the owning QuicSession object.
-  // TODO(b/136274541): Remove session pointer from streams.
-  QuicSession* session_;
-  StreamDelegateInterface* stream_delegate_;
-  // The precedence of the stream, once parsed.
-  spdy::SpdyStreamPrecedence precedence_;
-  // Bytes read refers to payload bytes only: they do not include framing,
-  // encryption overhead etc.
-  uint64_t stream_bytes_read_;
-
-  // Stream error code received from a RstStreamFrame or error code sent by the
-  // visitor or sequencer in the RstStreamFrame.
-  QuicResetStreamError stream_error_;
-  // Connection error code due to which the stream was closed. |stream_error_|
-  // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
-  // should check |connection_error_|.
-  QuicErrorCode connection_error_;
-
-  // True if the read side is closed and further frames should be rejected.
-  bool read_side_closed_;
-  // True if the write side is closed, and further writes should fail.
-  bool write_side_closed_;
-
-  // True if OnWriteSideInDataRecvdState() has already been called.
-  bool write_side_data_recvd_state_notified_;
-
-  // True if the subclass has written a FIN with WriteOrBufferData, but it was
-  // buffered in queued_data_ rather than being sent to the session.
-  bool fin_buffered_;
-  // True if a FIN has been sent to the session.
-  bool fin_sent_;
-  // True if a FIN is waiting to be acked.
-  bool fin_outstanding_;
-  // True if a FIN is lost.
-  bool fin_lost_;
-
-  // True if this stream has received (and the sequencer has accepted) a
-  // StreamFrame with the FIN set.
-  bool fin_received_;
-
-  // True if an RST_STREAM has been sent to the session.
-  // In combination with fin_sent_, used to ensure that a FIN and/or a
-  // RST_STREAM is always sent to terminate the stream.
-  bool rst_sent_;
-
-  // True if this stream has received a RST_STREAM frame.
-  bool rst_received_;
-
-  // True if the stream has sent STOP_SENDING to the session.
-  bool stop_sending_sent_;
-
-  absl::optional<QuicFlowController> flow_controller_;
-
-  // The connection level flow controller. Not owned.
-  QuicFlowController* connection_flow_controller_;
-
-  // Special streams, such as the crypto and headers streams, do not respect
-  // connection level flow control limits (but are stream level flow control
-  // limited).
-  bool stream_contributes_to_connection_flow_control_;
-
-  // A counter incremented when OnCanWrite() is called and no progress is made.
-  // For debugging only.
-  size_t busy_counter_;
-
-  // Indicates whether paddings will be added after the fin is consumed for this
-  // stream.
-  bool add_random_padding_after_fin_;
-
-  // Send buffer of this stream. Send buffer is cleaned up when data gets acked
-  // or discarded.
-  QuicStreamSendBuffer send_buffer_;
-
-  // Latched value of quic_buffered_data_threshold.
-  const QuicByteCount buffered_data_threshold_;
-
-  // If true, then this stream has precedence over other streams for write
-  // scheduling.
-  const bool is_static_;
-
-  // If initialized, reset this stream at this deadline.
-  QuicTime deadline_;
-
-  // True if this stream has entered draining state.
-  bool was_draining_;
-
-  // Indicates whether this stream is bidirectional, read unidirectional or
-  // write unidirectional.
-  const StreamType type_;
-
-  // Creation time of this stream, as reported by the QuicClock.
-  const QuicTime creation_time_;
-
-  Perspective perspective_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_H_
diff --git a/quic/core/quic_stream_frame_data_producer.h b/quic/core/quic_stream_frame_data_producer.h
deleted file mode 100644
index edcc84b..0000000
--- a/quic/core/quic_stream_frame_data_producer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicDataWriter;
-
-// Pure virtual class to retrieve stream data.
-class QUIC_EXPORT_PRIVATE QuicStreamFrameDataProducer {
- public:
-  virtual ~QuicStreamFrameDataProducer() {}
-
-  // Let |writer| write |data_length| data with |offset| of stream |id|. The
-  // write fails when either stream is closed or corresponding data is failed to
-  // be retrieved. This method allows writing a single stream frame from data
-  // that spans multiple buffers.
-  virtual WriteStreamDataResult WriteStreamData(QuicStreamId id,
-                                                QuicStreamOffset offset,
-                                                QuicByteCount data_length,
-                                                QuicDataWriter* writer) = 0;
-
-  // Writes the data for a CRYPTO frame to |writer| for a frame at encryption
-  // level |level| starting at offset |offset| for |data_length| bytes. Returns
-  // whether writing the data was successful.
-  virtual bool WriteCryptoData(EncryptionLevel level,
-                               QuicStreamOffset offset,
-                               QuicByteCount data_length,
-                               QuicDataWriter* writer) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
diff --git a/quic/core/quic_stream_id_manager.cc b/quic/core/quic_stream_id_manager.cc
deleted file mode 100644
index 40aa3d0..0000000
--- a/quic/core/quic_stream_id_manager.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/core/quic_stream_id_manager.h"
-
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-#define ENDPOINT \
-  (perspective_ == Perspective::IS_SERVER ? " Server: " : " Client: ")
-
-QuicStreamIdManager::QuicStreamIdManager(
-    DelegateInterface* delegate,
-    bool unidirectional,
-    Perspective perspective,
-    ParsedQuicVersion version,
-    QuicStreamCount max_allowed_outgoing_streams,
-    QuicStreamCount max_allowed_incoming_streams)
-    : delegate_(delegate),
-      unidirectional_(unidirectional),
-      perspective_(perspective),
-      version_(version),
-      outgoing_max_streams_(max_allowed_outgoing_streams),
-      next_outgoing_stream_id_(GetFirstOutgoingStreamId()),
-      outgoing_stream_count_(0),
-      incoming_actual_max_streams_(max_allowed_incoming_streams),
-      incoming_advertised_max_streams_(max_allowed_incoming_streams),
-      incoming_initial_max_open_streams_(max_allowed_incoming_streams),
-      incoming_stream_count_(0),
-      largest_peer_created_stream_id_(
-          QuicUtils::GetInvalidStreamId(version.transport_version)) {}
-
-QuicStreamIdManager::~QuicStreamIdManager() {}
-
-bool QuicStreamIdManager::OnStreamsBlockedFrame(
-    const QuicStreamsBlockedFrame& frame,
-    std::string* error_details) {
-  QUICHE_DCHECK_EQ(frame.unidirectional, unidirectional_);
-  if (frame.stream_count > incoming_advertised_max_streams_) {
-    // Peer thinks it can send more streams that we've told it.
-    *error_details = absl::StrCat(
-        "StreamsBlockedFrame's stream count ", frame.stream_count,
-        " exceeds incoming max stream ", incoming_advertised_max_streams_);
-    return false;
-  }
-  QUICHE_DCHECK_LE(incoming_advertised_max_streams_,
-                   incoming_actual_max_streams_);
-  if (incoming_advertised_max_streams_ == incoming_actual_max_streams_) {
-    // We have told peer about current max.
-    return true;
-  }
-  if (frame.stream_count < incoming_actual_max_streams_) {
-    // Peer thinks it's blocked on a stream count that is less than our current
-    // max. Inform the peer of the correct stream count.
-    SendMaxStreamsFrame();
-  }
-  return true;
-}
-
-bool QuicStreamIdManager::MaybeAllowNewOutgoingStreams(
-    QuicStreamCount max_open_streams) {
-  if (max_open_streams <= outgoing_max_streams_) {
-    // Only update the stream count if it would increase the limit.
-    return false;
-  }
-
-  // This implementation only supports 32 bit Stream IDs, so limit max streams
-  // if it would exceed the max 32 bits can express.
-  outgoing_max_streams_ =
-      std::min(max_open_streams, QuicUtils::GetMaxStreamCount());
-
-  return true;
-}
-
-void QuicStreamIdManager::SetMaxOpenIncomingStreams(
-    QuicStreamCount max_open_streams) {
-  QUIC_BUG_IF(quic_bug_12413_1, incoming_stream_count_ > 0)
-      << "non-zero incoming stream count " << incoming_stream_count_
-      << " when setting max incoming stream to " << max_open_streams;
-  QUIC_DLOG_IF(WARNING, incoming_initial_max_open_streams_ != max_open_streams)
-      << absl::StrCat(unidirectional_ ? "unidirectional " : "bidirectional: ",
-                      "incoming stream limit changed from ",
-                      incoming_initial_max_open_streams_, " to ",
-                      max_open_streams);
-  incoming_actual_max_streams_ = max_open_streams;
-  incoming_advertised_max_streams_ = max_open_streams;
-  incoming_initial_max_open_streams_ = max_open_streams;
-}
-
-void QuicStreamIdManager::MaybeSendMaxStreamsFrame() {
-  int divisor = GetQuicFlag(FLAGS_quic_max_streams_window_divisor);
-
-  if (divisor > 0) {
-    if ((incoming_advertised_max_streams_ - incoming_stream_count_) >
-        (incoming_initial_max_open_streams_ / divisor)) {
-      // window too large, no advertisement
-      return;
-    }
-  }
-  SendMaxStreamsFrame();
-}
-
-void QuicStreamIdManager::SendMaxStreamsFrame() {
-  QUIC_BUG_IF(quic_bug_12413_2,
-              incoming_advertised_max_streams_ >= incoming_actual_max_streams_);
-  incoming_advertised_max_streams_ = incoming_actual_max_streams_;
-  delegate_->SendMaxStreams(incoming_advertised_max_streams_, unidirectional_);
-}
-
-void QuicStreamIdManager::OnStreamClosed(QuicStreamId stream_id) {
-  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
-                   unidirectional_);
-  if (QuicUtils::IsOutgoingStreamId(version_, stream_id, perspective_)) {
-    // Nothing to do for outgoing streams.
-    return;
-  }
-  // If the stream is inbound, we can increase the actual stream limit and maybe
-  // advertise the new limit to the peer.
-  if (incoming_actual_max_streams_ == QuicUtils::GetMaxStreamCount()) {
-    // Reached the maximum stream id value that the implementation
-    // supports. Nothing can be done here.
-    return;
-  }
-  // One stream closed, and another one can be opened.
-  incoming_actual_max_streams_++;
-  MaybeSendMaxStreamsFrame();
-}
-
-QuicStreamId QuicStreamIdManager::GetNextOutgoingStreamId() {
-  QUIC_BUG_IF(quic_bug_12413_3, outgoing_stream_count_ >= outgoing_max_streams_)
-      << "Attempt to allocate a new outgoing stream that would exceed the "
-         "limit ("
-      << outgoing_max_streams_ << ")";
-  QuicStreamId id = next_outgoing_stream_id_;
-  next_outgoing_stream_id_ +=
-      QuicUtils::StreamIdDelta(version_.transport_version);
-  outgoing_stream_count_++;
-  return id;
-}
-
-bool QuicStreamIdManager::CanOpenNextOutgoingStream() const {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
-  return outgoing_stream_count_ < outgoing_max_streams_;
-}
-
-bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
-    const QuicStreamId stream_id,
-    std::string* error_details) {
-  // |stream_id| must be an incoming stream of the right directionality.
-  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
-                   unidirectional_);
-  QUICHE_DCHECK_NE(QuicUtils::IsServerInitiatedStreamId(
-                       version_.transport_version, stream_id),
-                   perspective_ == Perspective::IS_SERVER);
-  if (available_streams_.erase(stream_id) == 1) {
-    // stream_id is available.
-    return true;
-  }
-
-  if (largest_peer_created_stream_id_ !=
-      QuicUtils::GetInvalidStreamId(version_.transport_version)) {
-    QUICHE_DCHECK_GT(stream_id, largest_peer_created_stream_id_);
-  }
-
-  // Calculate increment of incoming_stream_count_ by creating stream_id.
-  const QuicStreamCount delta =
-      QuicUtils::StreamIdDelta(version_.transport_version);
-  const QuicStreamId least_new_stream_id =
-      largest_peer_created_stream_id_ ==
-              QuicUtils::GetInvalidStreamId(version_.transport_version)
-          ? GetFirstIncomingStreamId()
-          : largest_peer_created_stream_id_ + delta;
-  const QuicStreamCount stream_count_increment =
-      (stream_id - least_new_stream_id) / delta + 1;
-
-  if (incoming_stream_count_ + stream_count_increment >
-      incoming_advertised_max_streams_) {
-    QUIC_DLOG(INFO) << ENDPOINT
-                    << "Failed to create a new incoming stream with id:"
-                    << stream_id << ", reaching MAX_STREAMS limit: "
-                    << incoming_advertised_max_streams_ << ".";
-    *error_details = absl::StrCat("Stream id ", stream_id,
-                                  " would exceed stream count limit ",
-                                  incoming_advertised_max_streams_);
-    return false;
-  }
-
-  for (QuicStreamId id = least_new_stream_id; id < stream_id; id += delta) {
-    available_streams_.insert(id);
-  }
-  incoming_stream_count_ += stream_count_increment;
-  largest_peer_created_stream_id_ = stream_id;
-  return true;
-}
-
-bool QuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
-  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(id, version_),
-                   unidirectional_);
-  if (QuicUtils::IsOutgoingStreamId(version_, id, perspective_)) {
-    // Stream IDs under next_ougoing_stream_id_ are either open or previously
-    // open but now closed.
-    return id >= next_outgoing_stream_id_;
-  }
-  // For peer created streams, we also need to consider available streams.
-  return largest_peer_created_stream_id_ ==
-             QuicUtils::GetInvalidStreamId(version_.transport_version) ||
-         id > largest_peer_created_stream_id_ ||
-         available_streams_.contains(id);
-}
-
-QuicStreamId QuicStreamIdManager::GetFirstOutgoingStreamId() const {
-  return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
-                                 version_.transport_version, perspective_)
-                           : QuicUtils::GetFirstBidirectionalStreamId(
-                                 version_.transport_version, perspective_);
-}
-
-QuicStreamId QuicStreamIdManager::GetFirstIncomingStreamId() const {
-  return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
-                                 version_.transport_version,
-                                 QuicUtils::InvertPerspective(perspective_))
-                           : QuicUtils::GetFirstBidirectionalStreamId(
-                                 version_.transport_version,
-                                 QuicUtils::InvertPerspective(perspective_));
-}
-
-QuicStreamCount QuicStreamIdManager::available_incoming_streams() const {
-  return incoming_advertised_max_streams_ - incoming_stream_count_;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_stream_id_manager.h b/quic/core/quic_stream_id_manager.h
deleted file mode 100644
index 4261f43..0000000
--- a/quic/core/quic_stream_id_manager.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
-
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace test {
-class QuicSessionPeer;
-class QuicStreamIdManagerPeer;
-}  // namespace test
-
-// This class manages the stream ids for IETF QUIC.
-class QUIC_EXPORT_PRIVATE QuicStreamIdManager {
- public:
-  class QUIC_EXPORT_PRIVATE DelegateInterface {
-   public:
-    virtual ~DelegateInterface() = default;
-
-    // Send a MAX_STREAMS frame.
-    virtual void SendMaxStreams(QuicStreamCount stream_count,
-                                bool unidirectional) = 0;
-  };
-
-  QuicStreamIdManager(DelegateInterface* delegate,
-                      bool unidirectional,
-                      Perspective perspective,
-                      ParsedQuicVersion version,
-                      QuicStreamCount max_allowed_outgoing_streams,
-                      QuicStreamCount max_allowed_incoming_streams);
-
-  ~QuicStreamIdManager();
-
-  // Generate a string suitable for sending to the log/etc to show current state
-  // of the stream ID manager.
-  std::string DebugString() const {
-    return absl::StrCat(
-        " { unidirectional_: ", unidirectional_,
-        ", perspective: ", perspective_,
-        ", outgoing_max_streams_: ", outgoing_max_streams_,
-        ", next_outgoing_stream_id_: ", next_outgoing_stream_id_,
-        ", outgoing_stream_count_: ", outgoing_stream_count_,
-        ", incoming_actual_max_streams_: ", incoming_actual_max_streams_,
-        ", incoming_advertised_max_streams_: ",
-        incoming_advertised_max_streams_,
-        ", incoming_stream_count_: ", incoming_stream_count_,
-        ", available_streams_.size(): ", available_streams_.size(),
-        ", largest_peer_created_stream_id_: ", largest_peer_created_stream_id_,
-        " }");
-  }
-
-  // Processes the STREAMS_BLOCKED frame. If error is encountered, populates
-  // |error_details| and returns false.
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
-                             std::string* error_details);
-
-  // Returns whether the next outgoing stream ID can be allocated or not.
-  bool CanOpenNextOutgoingStream() const;
-
-  // Generate and send a MAX_STREAMS frame.
-  void SendMaxStreamsFrame();
-
-  // Invoked to deal with releasing a stream. Does nothing if the stream is
-  // outgoing. If the stream is incoming, the number of streams that the peer
-  // can open will be updated and a MAX_STREAMS frame, informing the peer of
-  // the additional streams, may be sent.
-  void OnStreamClosed(QuicStreamId stream_id);
-
-  // Returns the next outgoing stream id. Applications must call
-  // CanOpenNextOutgoingStream() first.
-  QuicStreamId GetNextOutgoingStreamId();
-
-  void SetMaxOpenIncomingStreams(QuicStreamCount max_open_streams);
-
-  // Called on |max_open_streams| outgoing streams can be created because of 1)
-  // config negotiated or 2) MAX_STREAMS received. Returns true if new
-  // streams can be created.
-  bool MaybeAllowNewOutgoingStreams(QuicStreamCount max_open_streams);
-
-  // Checks if the incoming stream ID exceeds the MAX_STREAMS limit.  If the
-  // limit is exceeded, populates |error_detials| and returns false.
-  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id,
-                                        std::string* error_details);
-
-  // Returns true if |id| is still available.
-  bool IsAvailableStream(QuicStreamId id) const;
-
-  QuicStreamCount incoming_initial_max_open_streams() const {
-    return incoming_initial_max_open_streams_;
-  }
-
-  QuicStreamId next_outgoing_stream_id() const {
-    return next_outgoing_stream_id_;
-  }
-
-  // Number of streams that the peer believes that it can still create.
-  QuicStreamCount available_incoming_streams() const;
-
-  QuicStreamId largest_peer_created_stream_id() const {
-    return largest_peer_created_stream_id_;
-  }
-
-  QuicStreamCount outgoing_max_streams() const { return outgoing_max_streams_; }
-  QuicStreamCount incoming_actual_max_streams() const {
-    return incoming_actual_max_streams_;
-  }
-  QuicStreamCount incoming_advertised_max_streams() const {
-    return incoming_advertised_max_streams_;
-  }
-  QuicStreamCount outgoing_stream_count() const {
-    return outgoing_stream_count_;
-  }
-
- private:
-  friend class test::QuicSessionPeer;
-  friend class test::QuicStreamIdManagerPeer;
-
-  // Check whether the MAX_STREAMS window has opened up enough and, if so,
-  // generate and send a MAX_STREAMS frame.
-  void MaybeSendMaxStreamsFrame();
-
-  // Get what should be the first incoming/outgoing stream ID that
-  // this stream id manager will manage, taking into account directionality and
-  // client/server perspective.
-  QuicStreamId GetFirstOutgoingStreamId() const;
-  QuicStreamId GetFirstIncomingStreamId() const;
-
-  // Back reference to the session containing this Stream ID Manager.
-  DelegateInterface* delegate_;
-
-  // Whether this stream id manager is for unidrectional (true) or bidirectional
-  // (false) streams.
-  const bool unidirectional_;
-
-  // Is this manager a client or a server.
-  const Perspective perspective_;
-
-  // QUIC version used for this manager.
-  const ParsedQuicVersion version_;
-
-  // The number of streams that this node can initiate.
-  // This limit is first set when config is negotiated, but may be updated upon
-  // receiving MAX_STREAMS frame.
-  QuicStreamCount outgoing_max_streams_;
-
-  // The ID to use for the next outgoing stream.
-  QuicStreamId next_outgoing_stream_id_;
-
-  // The number of outgoing streams that have ever been opened, including those
-  // that have been closed. This number must never be larger than
-  // outgoing_max_streams_.
-  QuicStreamCount outgoing_stream_count_;
-
-  // FOR INCOMING STREAMS
-
-  // The actual maximum number of streams that can be opened by the peer.
-  QuicStreamCount incoming_actual_max_streams_;
-  // Max incoming stream number that has been advertised to the peer and is <=
-  // incoming_actual_max_streams_. It is set to incoming_actual_max_streams_
-  // when a MAX_STREAMS is sent.
-  QuicStreamCount incoming_advertised_max_streams_;
-
-  // Initial maximum on the number of open streams allowed.
-  QuicStreamCount incoming_initial_max_open_streams_;
-
-  // The number of streams that have been created, including open ones and
-  // closed ones.
-  QuicStreamCount incoming_stream_count_;
-
-  // Set of stream ids that are less than the largest stream id that has been
-  // received, but are nonetheless available to be created.
-  absl::flat_hash_set<QuicStreamId> available_streams_;
-
-  QuicStreamId largest_peer_created_stream_id_;
-};
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quic/core/quic_stream_id_manager_test.cc b/quic/core/quic_stream_id_manager_test.cc
deleted file mode 100644
index 47ba76f..0000000
--- a/quic/core/quic_stream_id_manager_test.cc
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/core/quic_stream_id_manager.h"
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QuicStreamIdManager::DelegateInterface {
- public:
-  MOCK_METHOD(void,
-              SendMaxStreams,
-              (QuicStreamCount stream_count, bool unidirectional),
-              (override));
-};
-
-struct TestParams {
-  TestParams(ParsedQuicVersion version,
-             Perspective perspective,
-             bool is_unidirectional)
-      : version(version),
-        perspective(perspective),
-        is_unidirectional(is_unidirectional) {}
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-  bool is_unidirectional;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(p.version), "_",
-      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"),
-      (p.is_unidirectional ? "Unidirectional" : "Bidirectional"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (!version.HasIetfQuicFrames()) {
-      continue;
-    }
-    for (Perspective perspective :
-         {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
-      for (bool is_unidirectional : {true, false}) {
-        params.push_back(TestParams(version, perspective, is_unidirectional));
-      }
-    }
-  }
-  return params;
-}
-
-class QuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
- protected:
-  QuicStreamIdManagerTest()
-      : stream_id_manager_(&delegate_,
-                           IsUnidirectional(),
-                           perspective(),
-                           GetParam().version,
-                           0,
-                           kDefaultMaxStreamsPerConnection) {
-    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
-  }
-
-  QuicTransportVersion transport_version() const {
-    return GetParam().version.transport_version;
-  }
-
-  // Returns the stream ID for the Nth incoming stream (created by the peer)
-  // of the corresponding directionality of this manager.
-  QuicStreamId GetNthIncomingStreamId(int n) {
-    return QuicUtils::StreamIdDelta(transport_version()) * n +
-           (IsUnidirectional()
-                ? QuicUtils::GetFirstUnidirectionalStreamId(
-                      transport_version(),
-                      QuicUtils::InvertPerspective(perspective()))
-                : QuicUtils::GetFirstBidirectionalStreamId(
-                      transport_version(),
-                      QuicUtils::InvertPerspective(perspective())));
-  }
-
-  bool IsUnidirectional() { return GetParam().is_unidirectional; }
-  Perspective perspective() { return GetParam().perspective; }
-
-  StrictMock<MockDelegate> delegate_;
-  QuicStreamIdManager stream_id_manager_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicStreamIdManagerTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicStreamIdManagerTest, Initialization) {
-  EXPECT_EQ(0u, stream_id_manager_.outgoing_max_streams());
-
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_.incoming_actual_max_streams());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_.incoming_advertised_max_streams());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_.incoming_initial_max_open_streams());
-}
-
-// This test checks that the stream advertisement window is set to 1
-// if the number of stream ids is 1. This is a special case in the code.
-TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsWindowForSingleStream) {
-  stream_id_manager_.SetMaxOpenIncomingStreams(1);
-  EXPECT_EQ(1u, stream_id_manager_.incoming_initial_max_open_streams());
-  EXPECT_EQ(1u, stream_id_manager_.incoming_actual_max_streams());
-}
-
-TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
-  QuicStreamCount implementation_max = QuicUtils::GetMaxStreamCount();
-  // Ensure that the limit is less than the implementation maximum.
-  EXPECT_LT(stream_id_manager_.outgoing_max_streams(), implementation_max);
-
-  EXPECT_TRUE(
-      stream_id_manager_.MaybeAllowNewOutgoingStreams(implementation_max + 1));
-  // Should be pegged at the max.
-  EXPECT_EQ(implementation_max, stream_id_manager_.outgoing_max_streams());
-}
-
-// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
-// the count most recently advertised in a MAX_STREAMS frame.
-TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedOk) {
-  QuicStreamCount stream_count =
-      stream_id_manager_.incoming_initial_max_open_streams();
-  QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidirectional());
-  // We have notified peer about current max.
-  EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()))
-      .Times(0);
-  std::string error_details;
-  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-}
-
-// Check the case of the stream count in a STREAMS_BLOCKED frame is equal to the
-// count most recently advertised in a MAX_STREAMS frame. No MAX_STREAMS
-// should be generated.
-TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedNoOp) {
-  QuicStreamCount stream_count =
-      stream_id_manager_.incoming_initial_max_open_streams();
-  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
-  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
-}
-
-// Check the case of the stream count in a STREAMS_BLOCKED frame is greater than
-// the count most recently advertised in a MAX_STREAMS frame. Expect a
-// connection close with an error.
-TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedTooBig) {
-  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
-  QuicStreamCount stream_count =
-      stream_id_manager_.incoming_initial_max_open_streams() + 1;
-  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
-  std::string error_details;
-  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-  EXPECT_EQ(
-      error_details,
-      "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
-}
-
-// Same basic tests as above, but calls
-// QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId directly, avoiding the
-// call chain. The intent is that if there is a problem, the following tests
-// will point to either the stream ID manager or the call chain. They also
-// provide specific, small scale, tests of a public QuicStreamIdManager method.
-// First test make sure that streams with ids below the limit are accepted.
-TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidBelowLimit) {
-  QuicStreamId stream_id = GetNthIncomingStreamId(
-      stream_id_manager_.incoming_actual_max_streams() - 2);
-  EXPECT_TRUE(
-      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
-}
-
-// Accept a stream with an ID that equals the limit.
-TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidAtLimit) {
-  QuicStreamId stream_id = GetNthIncomingStreamId(
-      stream_id_manager_.incoming_actual_max_streams() - 1);
-  EXPECT_TRUE(
-      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
-}
-
-// Close the connection if the id exceeds the limit.
-TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdInValidAboveLimit) {
-  QuicStreamId stream_id =
-      GetNthIncomingStreamId(stream_id_manager_.incoming_actual_max_streams());
-  std::string error_details;
-  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
-      stream_id, &error_details));
-  EXPECT_EQ(error_details,
-            absl::StrCat("Stream id ", stream_id,
-                         " would exceed stream count limit 100"));
-}
-
-TEST_P(QuicStreamIdManagerTest, OnStreamsBlockedFrame) {
-  // Get the current maximum allowed incoming stream count.
-  QuicStreamCount advertised_stream_count =
-      stream_id_manager_.incoming_advertised_max_streams();
-
-  QuicStreamsBlockedFrame frame;
-
-  frame.unidirectional = IsUnidirectional();
-
-  // If the peer is saying it's blocked on the stream count that
-  // we've advertised, it's a noop since the peer has the correct information.
-  frame.stream_count = advertised_stream_count;
-  std::string error_details;
-  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-
-  // If the peer is saying it's blocked on a stream count that is larger
-  // than what we've advertised, the connection should get closed.
-  frame.stream_count = advertised_stream_count + 1;
-  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-  EXPECT_EQ(
-      error_details,
-      "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
-
-  // If the peer is saying it's blocked on a count that is less than
-  // our actual count, we send a MAX_STREAMS frame and update
-  // the advertised value.
-  // First, need to bump up the actual max so there is room for the MAX
-  // STREAMS frame to send a larger ID.
-  QuicStreamCount actual_stream_count =
-      stream_id_manager_.incoming_actual_max_streams();
-
-  // Closing a stream will result in the ability to initiate one more
-  // stream
-  stream_id_manager_.OnStreamClosed(
-      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_));
-  EXPECT_EQ(actual_stream_count + 1u,
-            stream_id_manager_.incoming_actual_max_streams());
-  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
-            stream_id_manager_.incoming_advertised_max_streams() + 1u);
-
-  // Now simulate receiving a STREAMS_BLOCKED frame...
-  // Changing the actual maximum, above, forces a MAX_STREAMS frame to be
-  // sent, so the logic for that (SendMaxStreamsFrame(), etc) is tested.
-
-  // The STREAMS_BLOCKED frame contains the previous advertised count,
-  // not the one that the peer would have received as a result of the
-  // MAX_STREAMS sent earler.
-  frame.stream_count = advertised_stream_count;
-
-  EXPECT_CALL(delegate_,
-              SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
-                             IsUnidirectional()));
-
-  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-  // Check that the saved frame is correct.
-  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
-            stream_id_manager_.incoming_advertised_max_streams());
-}
-
-TEST_P(QuicStreamIdManagerTest, GetNextOutgoingStream) {
-  // Number of streams we can open and the first one we should get when
-  // opening...
-  size_t number_of_streams = kDefaultMaxStreamsPerConnection;
-
-  EXPECT_TRUE(
-      stream_id_manager_.MaybeAllowNewOutgoingStreams(number_of_streams));
-
-  QuicStreamId stream_id = IsUnidirectional()
-                               ? QuicUtils::GetFirstUnidirectionalStreamId(
-                                     transport_version(), perspective())
-                               : QuicUtils::GetFirstBidirectionalStreamId(
-                                     transport_version(), perspective());
-
-  EXPECT_EQ(number_of_streams, stream_id_manager_.outgoing_max_streams());
-  while (number_of_streams) {
-    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
-    EXPECT_EQ(stream_id, stream_id_manager_.GetNextOutgoingStreamId());
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-    number_of_streams--;
-  }
-
-  // If we try to check that the next outgoing stream id is available it should
-  // fail.
-  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
-
-  // If we try to get the next id (above the limit), it should cause a quic-bug.
-  EXPECT_QUIC_BUG(
-      stream_id_manager_.GetNextOutgoingStreamId(),
-      "Attempt to allocate a new outgoing stream that would exceed the limit");
-}
-
-TEST_P(QuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
-  QuicStreamId max_stream_id = GetNthIncomingStreamId(
-      stream_id_manager_.incoming_actual_max_streams() - 1);
-  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(max_stream_id,
-                                                                  nullptr));
-
-  QuicStreamId first_stream_id = GetNthIncomingStreamId(0);
-  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
-      first_stream_id, nullptr));
-  // A bad stream ID results in a closed connection.
-  std::string error_details;
-  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
-      max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
-      &error_details));
-  EXPECT_EQ(error_details,
-            absl::StrCat(
-                "Stream id ",
-                max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
-                " would exceed stream count limit 100"));
-}
-
-TEST_P(QuicStreamIdManagerTest, MaxStreamsWindow) {
-  // Open and then close a number of streams to get close to the threshold of
-  // sending a MAX_STREAM_FRAME.
-  int stream_count = stream_id_manager_.incoming_initial_max_open_streams() /
-                         GetQuicFlag(FLAGS_quic_max_streams_window_divisor) -
-                     1;
-
-  // Should not get a control-frame transmission since the peer should have
-  // "plenty" of stream IDs to use.
-  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
-
-  // Get the first incoming stream ID to try and allocate.
-  QuicStreamId stream_id = GetNthIncomingStreamId(0);
-  size_t old_available_incoming_streams =
-      stream_id_manager_.available_incoming_streams();
-  auto i = stream_count;
-  while (i) {
-    EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id,
-                                                                    nullptr));
-
-    // This node should think that the peer believes it has one fewer
-    // stream it can create.
-    old_available_incoming_streams--;
-    EXPECT_EQ(old_available_incoming_streams,
-              stream_id_manager_.available_incoming_streams());
-
-    i--;
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-  }
-
-  // Now close them, still should get no MAX_STREAMS
-  stream_id = GetNthIncomingStreamId(0);
-  QuicStreamCount expected_actual_max =
-      stream_id_manager_.incoming_actual_max_streams();
-  QuicStreamCount expected_advertised_max_streams =
-      stream_id_manager_.incoming_advertised_max_streams();
-  while (stream_count) {
-    stream_id_manager_.OnStreamClosed(stream_id);
-    stream_count--;
-    stream_id += QuicUtils::StreamIdDelta(transport_version());
-    expected_actual_max++;
-    EXPECT_EQ(expected_actual_max,
-              stream_id_manager_.incoming_actual_max_streams());
-    // Advertised maximum should remain the same.
-    EXPECT_EQ(expected_advertised_max_streams,
-              stream_id_manager_.incoming_advertised_max_streams());
-  }
-
-  // This should not change.
-  EXPECT_EQ(old_available_incoming_streams,
-            stream_id_manager_.available_incoming_streams());
-
-  // Now whenever we close a stream we should get a MAX_STREAMS frame.
-  // Above code closed all the open streams, so we have to open/close
-  //  EXPECT_CALL(delegate_,
-  //  SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
-  //  IsUnidirectional()));
-  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidirectional()));
-  EXPECT_TRUE(
-      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
-  stream_id_manager_.OnStreamClosed(stream_id);
-}
-
-TEST_P(QuicStreamIdManagerTest, StreamsBlockedEdgeConditions) {
-  QuicStreamsBlockedFrame frame;
-  frame.unidirectional = IsUnidirectional();
-
-  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
-  // when max_allowed_incoming_streams is 0.
-  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
-  stream_id_manager_.SetMaxOpenIncomingStreams(0);
-  frame.stream_count = 0;
-  std::string error_details;
-  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-
-  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
-  // MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
-  EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidirectional()));
-  QuicStreamIdManagerPeer::set_incoming_actual_max_streams(&stream_id_manager_,
-                                                           123);
-  frame.stream_count = 0;
-  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
-}
-
-// Test that a MAX_STREAMS frame is generated when half the stream ids become
-// available. This has a useful side effect of testing that when streams are
-// closed, the number of available stream ids increases.
-TEST_P(QuicStreamIdManagerTest, MaxStreamsSlidingWindow) {
-  QuicStreamCount first_advert =
-      stream_id_manager_.incoming_advertised_max_streams();
-
-  // Open/close enough streams to shrink the window without causing a MAX
-  // STREAMS to be generated. The loop
-  // will make that many stream IDs available, so the last CloseStream should
-  // cause a MAX STREAMS frame to be generated.
-  int i =
-      static_cast<int>(stream_id_manager_.incoming_initial_max_open_streams() /
-                       GetQuicFlag(FLAGS_quic_max_streams_window_divisor));
-  QuicStreamId id =
-      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_);
-  EXPECT_CALL(delegate_, SendMaxStreams(first_advert + i, IsUnidirectional()));
-  while (i) {
-    EXPECT_TRUE(
-        stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id, nullptr));
-    stream_id_manager_.OnStreamClosed(id);
-    i--;
-    id += QuicUtils::StreamIdDelta(transport_version());
-  }
-}
-
-TEST_P(QuicStreamIdManagerTest, NewStreamDoesNotExceedLimit) {
-  EXPECT_TRUE(stream_id_manager_.MaybeAllowNewOutgoingStreams(100));
-
-  size_t stream_count = stream_id_manager_.outgoing_max_streams();
-  EXPECT_NE(0u, stream_count);
-
-  while (stream_count) {
-    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
-    stream_id_manager_.GetNextOutgoingStreamId();
-    stream_count--;
-  }
-
-  EXPECT_EQ(stream_id_manager_.outgoing_stream_count(),
-            stream_id_manager_.outgoing_max_streams());
-  // Create another, it should fail.
-  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
-}
-
-TEST_P(QuicStreamIdManagerTest, AvailableStreams) {
-  stream_id_manager_.MaybeIncreaseLargestPeerStreamId(GetNthIncomingStreamId(3),
-                                                      nullptr);
-
-  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(1)));
-  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(2)));
-  EXPECT_FALSE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(3)));
-  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(4)));
-}
-
-// Tests that if MaybeIncreaseLargestPeerStreamId is given an extremely
-// large stream ID (larger than the limit) it is rejected.
-// This is a regression for Chromium bugs 909987 and 910040
-TEST_P(QuicStreamIdManagerTest, ExtremeMaybeIncreaseLargestPeerStreamId) {
-  QuicStreamId too_big_stream_id = GetNthIncomingStreamId(
-      stream_id_manager_.incoming_actual_max_streams() + 20);
-
-  std::string error_details;
-  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
-      too_big_stream_id, &error_details));
-  EXPECT_EQ(error_details,
-            absl::StrCat("Stream id ", too_big_stream_id,
-                         " would exceed stream count limit 100"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_stream_send_buffer.cc b/quic/core/quic_stream_send_buffer.cc
deleted file mode 100644
index f901486..0000000
--- a/quic/core/quic_stream_send_buffer.cc
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_send_buffer.h"
-
-#include <algorithm>
-
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-namespace quic {
-
-namespace {
-
-struct CompareOffset {
-  bool operator()(const BufferedSlice& slice, QuicStreamOffset offset) const {
-    return slice.offset + slice.slice.length() < offset;
-  }
-};
-
-}  // namespace
-
-BufferedSlice::BufferedSlice(quiche::QuicheMemSlice mem_slice,
-                             QuicStreamOffset offset)
-    : slice(std::move(mem_slice)), offset(offset) {}
-
-BufferedSlice::BufferedSlice(BufferedSlice&& other) = default;
-
-BufferedSlice& BufferedSlice::operator=(BufferedSlice&& other) = default;
-
-BufferedSlice::~BufferedSlice() {}
-
-QuicInterval<std::size_t> BufferedSlice::interval() const {
-  const std::size_t length = slice.length();
-  return QuicInterval<std::size_t>(offset, offset + length);
-}
-
-bool StreamPendingRetransmission::operator==(
-    const StreamPendingRetransmission& other) const {
-  return offset == other.offset && length == other.length;
-}
-
-QuicStreamSendBuffer::QuicStreamSendBuffer(
-    quiche::QuicheBufferAllocator* allocator)
-    : current_end_offset_(0),
-      stream_offset_(0),
-      allocator_(allocator),
-      stream_bytes_written_(0),
-      stream_bytes_outstanding_(0),
-      write_index_(-1) {}
-
-QuicStreamSendBuffer::~QuicStreamSendBuffer() {}
-
-void QuicStreamSendBuffer::SaveStreamData(absl::string_view data) {
-  QUICHE_DCHECK(!data.empty());
-
-  // Latch the maximum data slice size.
-  const QuicByteCount max_data_slice_size =
-      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size);
-  while (!data.empty()) {
-    auto slice_len = std::min<absl::string_view::size_type>(
-        data.length(), max_data_slice_size);
-    auto buffer =
-        quiche::QuicheBuffer::Copy(allocator_, data.substr(0, slice_len));
-    SaveMemSlice(quiche::QuicheMemSlice(std::move(buffer)));
-
-    data = data.substr(slice_len);
-  }
-}
-
-void QuicStreamSendBuffer::SaveMemSlice(quiche::QuicheMemSlice slice) {
-  QUIC_DVLOG(2) << "Save slice offset " << stream_offset_ << " length "
-                << slice.length();
-  if (slice.empty()) {
-    QUIC_BUG(quic_bug_10853_1) << "Try to save empty MemSlice to send buffer.";
-    return;
-  }
-  size_t length = slice.length();
-  // Need to start the offsets at the right interval.
-  if (interval_deque_.Empty()) {
-    const QuicStreamOffset end = stream_offset_ + length;
-    current_end_offset_ = std::max(current_end_offset_, end);
-  }
-  BufferedSlice bs = BufferedSlice(std::move(slice), stream_offset_);
-  interval_deque_.PushBack(std::move(bs));
-  stream_offset_ += length;
-}
-
-QuicByteCount QuicStreamSendBuffer::SaveMemSliceSpan(
-    absl::Span<quiche::QuicheMemSlice> span) {
-  QuicByteCount total = 0;
-  for (quiche::QuicheMemSlice& slice : span) {
-    if (slice.length() == 0) {
-      // Skip empty slices.
-      continue;
-    }
-    total += slice.length();
-    SaveMemSlice(std::move(slice));
-  }
-  return total;
-}
-
-void QuicStreamSendBuffer::OnStreamDataConsumed(size_t bytes_consumed) {
-  stream_bytes_written_ += bytes_consumed;
-  stream_bytes_outstanding_ += bytes_consumed;
-}
-
-bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
-                                           QuicByteCount data_length,
-                                           QuicDataWriter* writer) {
-  QUIC_BUG_IF(quic_bug_12823_1, current_end_offset_ < offset)
-      << "Tried to write data out of sequence. last_offset_end:"
-      << current_end_offset_ << ", offset:" << offset;
-  // The iterator returned from |interval_deque_| will automatically advance
-  // the internal write index for the QuicIntervalDeque. The incrementing is
-  // done in operator++.
-  for (auto slice_it = interval_deque_.DataAt(offset);
-       slice_it != interval_deque_.DataEnd(); ++slice_it) {
-    if (data_length == 0 || offset < slice_it->offset) {
-      break;
-    }
-
-    QuicByteCount slice_offset = offset - slice_it->offset;
-    QuicByteCount available_bytes_in_slice =
-        slice_it->slice.length() - slice_offset;
-    QuicByteCount copy_length = std::min(data_length, available_bytes_in_slice);
-    if (!writer->WriteBytes(slice_it->slice.data() + slice_offset,
-                            copy_length)) {
-      QUIC_BUG(quic_bug_10853_2) << "Writer fails to write.";
-      return false;
-    }
-    offset += copy_length;
-    data_length -= copy_length;
-    const QuicStreamOffset new_end =
-        slice_it->offset + slice_it->slice.length();
-    current_end_offset_ = std::max(current_end_offset_, new_end);
-  }
-  return data_length == 0;
-}
-
-bool QuicStreamSendBuffer::OnStreamDataAcked(
-    QuicStreamOffset offset,
-    QuicByteCount data_length,
-    QuicByteCount* newly_acked_length) {
-  *newly_acked_length = 0;
-  if (data_length == 0) {
-    return true;
-  }
-  if (bytes_acked_.Empty() || offset >= bytes_acked_.rbegin()->max() ||
-      bytes_acked_.IsDisjoint(
-          QuicInterval<QuicStreamOffset>(offset, offset + data_length))) {
-    // Optimization for the typical case, when all data is newly acked.
-    if (stream_bytes_outstanding_ < data_length) {
-      return false;
-    }
-    bytes_acked_.AddOptimizedForAppend(offset, offset + data_length);
-    *newly_acked_length = data_length;
-    stream_bytes_outstanding_ -= data_length;
-    pending_retransmissions_.Difference(offset, offset + data_length);
-    if (!FreeMemSlices(offset, offset + data_length)) {
-      return false;
-    }
-    CleanUpBufferedSlices();
-    return true;
-  }
-  // Exit if no new data gets acked.
-  if (bytes_acked_.Contains(offset, offset + data_length)) {
-    return true;
-  }
-  // Execute the slow path if newly acked data fill in existing holes.
-  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
-  newly_acked.Difference(bytes_acked_);
-  for (const auto& interval : newly_acked) {
-    *newly_acked_length += (interval.max() - interval.min());
-  }
-  if (stream_bytes_outstanding_ < *newly_acked_length) {
-    return false;
-  }
-  stream_bytes_outstanding_ -= *newly_acked_length;
-  bytes_acked_.Add(offset, offset + data_length);
-  pending_retransmissions_.Difference(offset, offset + data_length);
-  if (newly_acked.Empty()) {
-    return true;
-  }
-  if (!FreeMemSlices(newly_acked.begin()->min(), newly_acked.rbegin()->max())) {
-    return false;
-  }
-  CleanUpBufferedSlices();
-  return true;
-}
-
-void QuicStreamSendBuffer::OnStreamDataLost(QuicStreamOffset offset,
-                                            QuicByteCount data_length) {
-  if (data_length == 0) {
-    return;
-  }
-  QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
-  bytes_lost.Difference(bytes_acked_);
-  if (bytes_lost.Empty()) {
-    return;
-  }
-  for (const auto& lost : bytes_lost) {
-    pending_retransmissions_.Add(lost.min(), lost.max());
-  }
-}
-
-void QuicStreamSendBuffer::OnStreamDataRetransmitted(
-    QuicStreamOffset offset,
-    QuicByteCount data_length) {
-  if (data_length == 0) {
-    return;
-  }
-  pending_retransmissions_.Difference(offset, offset + data_length);
-}
-
-bool QuicStreamSendBuffer::HasPendingRetransmission() const {
-  return !pending_retransmissions_.Empty();
-}
-
-StreamPendingRetransmission QuicStreamSendBuffer::NextPendingRetransmission()
-    const {
-  if (HasPendingRetransmission()) {
-    const auto pending = pending_retransmissions_.begin();
-    return {pending->min(), pending->max() - pending->min()};
-  }
-  QUIC_BUG(quic_bug_10853_3)
-      << "NextPendingRetransmission is called unexpected with no "
-         "pending retransmissions.";
-  return {0, 0};
-}
-
-bool QuicStreamSendBuffer::FreeMemSlices(QuicStreamOffset start,
-                                         QuicStreamOffset end) {
-  auto it = interval_deque_.DataBegin();
-  if (it == interval_deque_.DataEnd() || it->slice.empty()) {
-    QUIC_BUG(quic_bug_10853_4)
-        << "Trying to ack stream data [" << start << ", " << end << "), "
-        << (it == interval_deque_.DataEnd()
-                ? "and there is no outstanding data."
-                : "and the first slice is empty.");
-    return false;
-  }
-  if (!it->interval().Contains(start)) {
-    // Slow path that not the earliest outstanding data gets acked.
-    it = std::lower_bound(interval_deque_.DataBegin(),
-                          interval_deque_.DataEnd(), start, CompareOffset());
-  }
-  if (it == interval_deque_.DataEnd() || it->slice.empty()) {
-    QUIC_BUG(quic_bug_10853_5)
-        << "Offset " << start << " with iterator offset: " << it->offset
-        << (it == interval_deque_.DataEnd() ? " does not exist."
-                                            : " has already been acked.");
-    return false;
-  }
-  for (; it != interval_deque_.DataEnd(); ++it) {
-    if (it->offset >= end) {
-      break;
-    }
-    if (!it->slice.empty() &&
-        bytes_acked_.Contains(it->offset, it->offset + it->slice.length())) {
-      it->slice.Reset();
-    }
-  }
-  return true;
-}
-
-void QuicStreamSendBuffer::CleanUpBufferedSlices() {
-  while (!interval_deque_.Empty() &&
-         interval_deque_.DataBegin()->slice.empty()) {
-    QUIC_BUG_IF(quic_bug_12823_2,
-                interval_deque_.DataBegin()->offset > current_end_offset_)
-        << "Fail to pop front from interval_deque_. Front element contained "
-           "a slice whose data has not all be written. Front offset "
-        << interval_deque_.DataBegin()->offset << " length "
-        << interval_deque_.DataBegin()->slice.length();
-    interval_deque_.PopFront();
-  }
-}
-
-bool QuicStreamSendBuffer::IsStreamDataOutstanding(
-    QuicStreamOffset offset,
-    QuicByteCount data_length) const {
-  return data_length > 0 &&
-         !bytes_acked_.Contains(offset, offset + data_length);
-}
-
-size_t QuicStreamSendBuffer::size() const {
-  return interval_deque_.Size();
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_stream_send_buffer.h b/quic/core/quic_stream_send_buffer.h
deleted file mode 100644
index e972ac0..0000000
--- a/quic/core/quic_stream_send_buffer.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
-
-#include "absl/types/span.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_interval_deque.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamSendBufferPeer;
-class QuicStreamPeer;
-}  // namespace test
-
-class QuicDataWriter;
-
-// BufferedSlice comprises information of a piece of stream data stored in
-// contiguous memory space. Please note, BufferedSlice is constructed when
-// stream data is saved in send buffer and is removed when stream data is fully
-// acked. It is move-only.
-struct QUIC_EXPORT_PRIVATE BufferedSlice {
-  BufferedSlice(quiche::QuicheMemSlice mem_slice, QuicStreamOffset offset);
-  BufferedSlice(BufferedSlice&& other);
-  BufferedSlice& operator=(BufferedSlice&& other);
-
-  BufferedSlice(const BufferedSlice& other) = delete;
-  BufferedSlice& operator=(const BufferedSlice& other) = delete;
-  ~BufferedSlice();
-
-  // Return an interval representing the offset and length.
-  QuicInterval<std::size_t> interval() const;
-
-  // Stream data of this data slice.
-  quiche::QuicheMemSlice slice;
-  // Location of this data slice in the stream.
-  QuicStreamOffset offset;
-};
-
-struct QUIC_EXPORT_PRIVATE StreamPendingRetransmission {
-  constexpr StreamPendingRetransmission(QuicStreamOffset offset,
-                                        QuicByteCount length)
-      : offset(offset), length(length) {}
-
-  // Starting offset of this pending retransmission.
-  QuicStreamOffset offset;
-  // Length of this pending retransmission.
-  QuicByteCount length;
-
-  bool operator==(const StreamPendingRetransmission& other) const;
-};
-
-// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
-// are added to the tail of the list. Data slices are removed from the head of
-// the list when they get fully acked. Stream data can be retrieved and acked
-// across slice boundaries.
-class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
- public:
-  explicit QuicStreamSendBuffer(quiche::QuicheBufferAllocator* allocator);
-  QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
-  QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
-  ~QuicStreamSendBuffer();
-
-  // Save |data| to send buffer.
-  void SaveStreamData(absl::string_view data);
-
-  // Save |slice| to send buffer.
-  void SaveMemSlice(quiche::QuicheMemSlice slice);
-
-  // Save all slices in |span| to send buffer. Return total bytes saved.
-  QuicByteCount SaveMemSliceSpan(absl::Span<quiche::QuicheMemSlice> span);
-
-  // Called when |bytes_consumed| bytes has been consumed by the stream.
-  void OnStreamDataConsumed(size_t bytes_consumed);
-
-  // Write |data_length| of data starts at |offset|.
-  bool WriteStreamData(QuicStreamOffset offset,
-                       QuicByteCount data_length,
-                       QuicDataWriter* writer);
-
-  // Called when data [offset, offset + data_length) is acked or removed as
-  // stream is canceled. Removes fully acked data slice from send buffer. Set
-  // |newly_acked_length|. Returns false if trying to ack unsent data.
-  bool OnStreamDataAcked(QuicStreamOffset offset,
-                         QuicByteCount data_length,
-                         QuicByteCount* newly_acked_length);
-
-  // Called when data [offset, offset + data_length) is considered as lost.
-  void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
-
-  // Called when data [offset, offset + length) was retransmitted.
-  void OnStreamDataRetransmitted(QuicStreamOffset offset,
-                                 QuicByteCount data_length);
-
-  // Returns true if there is pending retransmissions.
-  bool HasPendingRetransmission() const;
-
-  // Returns next pending retransmissions.
-  StreamPendingRetransmission NextPendingRetransmission() const;
-
-  // Returns true if data [offset, offset + data_length) is outstanding and
-  // waiting to be acked. Returns false otherwise.
-  bool IsStreamDataOutstanding(QuicStreamOffset offset,
-                               QuicByteCount data_length) const;
-
-  // Number of data slices in send buffer.
-  size_t size() const;
-
-  QuicStreamOffset stream_offset() const { return stream_offset_; }
-
-  uint64_t stream_bytes_written() const { return stream_bytes_written_; }
-
-  uint64_t stream_bytes_outstanding() const {
-    return stream_bytes_outstanding_;
-  }
-
-  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const {
-    return bytes_acked_;
-  }
-
-  const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const {
-    return pending_retransmissions_;
-  }
-
- private:
-  friend class test::QuicStreamSendBufferPeer;
-  friend class test::QuicStreamPeer;
-
-  // Called when data within offset [start, end) gets acked. Frees fully
-  // acked buffered slices if any. Returns false if the corresponding data does
-  // not exist or has been acked.
-  bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
-
-  // Cleanup empty slices in order from buffered_slices_.
-  void CleanUpBufferedSlices();
-
-  // |current_end_offset_| stores the end offset of the current slice to ensure
-  // data isn't being written out of order when using the |interval_deque_|.
-  QuicStreamOffset current_end_offset_;
-  QuicIntervalDeque<BufferedSlice> interval_deque_;
-
-  // Offset of next inserted byte.
-  QuicStreamOffset stream_offset_;
-
-  quiche::QuicheBufferAllocator* allocator_;
-
-  // Bytes that have been consumed by the stream.
-  uint64_t stream_bytes_written_;
-
-  // Bytes that have been consumed and are waiting to be acked.
-  uint64_t stream_bytes_outstanding_;
-
-  // Offsets of data that has been acked.
-  QuicIntervalSet<QuicStreamOffset> bytes_acked_;
-
-  // Data considered as lost and needs to be retransmitted.
-  QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
-
-  // Index of slice which contains data waiting to be written for the first
-  // time. -1 if send buffer is empty or all data has been written.
-  int32_t write_index_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
diff --git a/quic/core/quic_stream_send_buffer_test.cc b/quic/core/quic_stream_send_buffer_test.cc
deleted file mode 100644
index 599ebf4..0000000
--- a/quic/core/quic_stream_send_buffer_test.cc
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_send_buffer.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicStreamSendBufferTest : public QuicTest {
- public:
-  QuicStreamSendBufferTest() : send_buffer_(&allocator_) {
-    EXPECT_EQ(0u, send_buffer_.size());
-    EXPECT_EQ(0u, send_buffer_.stream_bytes_written());
-    EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding());
-    // The stream offset should be 0 since nothing is written.
-    EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-
-    std::string data1 = absl::StrCat(
-        std::string(1536, 'a'), std::string(256, 'b'), std::string(256, 'c'));
-
-    quiche::QuicheBuffer buffer1(&allocator_, 1024);
-    memset(buffer1.data(), 'c', buffer1.size());
-    quiche::QuicheMemSlice slice1(std::move(buffer1));
-
-    quiche::QuicheBuffer buffer2(&allocator_, 768);
-    memset(buffer2.data(), 'd', buffer2.size());
-    quiche::QuicheMemSlice slice2(std::move(buffer2));
-
-    // `data` will be split into two BufferedSlices.
-    SetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size, 1024);
-    send_buffer_.SaveStreamData(data1);
-
-    send_buffer_.SaveMemSlice(std::move(slice1));
-    EXPECT_TRUE(slice1.empty());
-    send_buffer_.SaveMemSlice(std::move(slice2));
-    EXPECT_TRUE(slice2.empty());
-
-    EXPECT_EQ(4u, send_buffer_.size());
-    // At this point, `send_buffer_.interval_deque_` looks like this:
-    // BufferedSlice1: 'a' * 1024
-    // BufferedSlice2: 'a' * 512 + 'b' * 256 + 'c' * 256
-    // BufferedSlice3: 'c' * 1024
-    // BufferedSlice4: 'd' * 768
-  }
-
-  void WriteAllData() {
-    // Write all data.
-    char buf[4000];
-    QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
-    send_buffer_.WriteStreamData(0, 3840u, &writer);
-
-    send_buffer_.OnStreamDataConsumed(3840u);
-    EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
-    EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
-  }
-
-  quiche::SimpleBufferAllocator allocator_;
-  QuicStreamSendBuffer send_buffer_;
-};
-
-TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
-  char buf[4000];
-  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
-  std::string copy1(1024, 'a');
-  std::string copy2 =
-      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
-  std::string copy3(1024, 'c');
-  std::string copy4(768, 'd');
-
-  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
-  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 1024, &writer));
-  EXPECT_EQ(copy2, absl::string_view(buf + 1024, 1024));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer));
-  EXPECT_EQ(copy3, absl::string_view(buf + 2048, 1024));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer));
-  EXPECT_EQ(copy4, absl::string_view(buf + 3072, 768));
-
-  // Test data piece across boundries.
-  QuicDataWriter writer2(4000, buf, quiche::HOST_BYTE_ORDER);
-  std::string copy5 =
-      std::string(536, 'a') + std::string(256, 'b') + std::string(232, 'c');
-  ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2));
-  EXPECT_EQ(copy5, absl::string_view(buf, 1024));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2));
-  std::string copy6 = std::string(572, 'c') + std::string(452, 'd');
-  EXPECT_EQ(copy6, absl::string_view(buf + 1024, 1024));
-
-  // Invalid data copy.
-  QuicDataWriter writer3(4000, buf, quiche::HOST_BYTE_ORDER);
-  EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
-  EXPECT_QUIC_BUG(send_buffer_.WriteStreamData(0, 4000, &writer3),
-                  "Writer fails to write.");
-
-  send_buffer_.OnStreamDataConsumed(3840);
-  EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
-  EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
-}
-
-// Regression test for b/143491027.
-TEST_F(QuicStreamSendBufferTest,
-       WriteStreamDataContainsBothRetransmissionAndNewData) {
-  std::string copy1(1024, 'a');
-  std::string copy2 =
-      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
-  std::string copy3 = std::string(1024, 'c') + std::string(100, 'd');
-  char buf[6000];
-  QuicDataWriter writer(6000, buf, quiche::HOST_BYTE_ORDER);
-  // Write more than one slice.
-  EXPECT_EQ(0, QuicStreamSendBufferPeer::write_index(&send_buffer_));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
-  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
-  EXPECT_EQ(1, QuicStreamSendBufferPeer::write_index(&send_buffer_));
-
-  // Retransmit the first frame and also send new data.
-  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 2048, &writer));
-  EXPECT_EQ(copy1 + copy2, absl::string_view(buf + 1024, 2048));
-
-  // Write new data.
-  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 50, &writer));
-  EXPECT_EQ(std::string(50, 'c'), absl::string_view(buf + 1024 + 2048, 50));
-  EXPECT_EQ(3072u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1124, &writer));
-  EXPECT_EQ(copy3, absl::string_view(buf + 1024 + 2048 + 50, 1124));
-  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-}
-
-TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
-  WriteAllData();
-
-  QuicByteCount newly_acked_length;
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1024, 1024, &newly_acked_length));
-  EXPECT_EQ(1024u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2048, 1024, &newly_acked_length));
-  EXPECT_EQ(1024u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
-  EXPECT_EQ(1024u, newly_acked_length);
-
-  // Send buffer is cleaned up in order.
-  EXPECT_EQ(1u, send_buffer_.size());
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3072, 768, &newly_acked_length));
-  EXPECT_EQ(768u, newly_acked_length);
-  EXPECT_EQ(0u, send_buffer_.size());
-}
-
-TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
-  WriteAllData();
-
-  QuicByteCount newly_acked_length;
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2024, 576, &newly_acked_length));
-  EXPECT_EQ(576u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
-  EXPECT_EQ(1000u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1000, 1024, &newly_acked_length));
-  EXPECT_EQ(1024u, newly_acked_length);
-  // Send buffer is cleaned up in order.
-  EXPECT_EQ(2u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2600, 1024, &newly_acked_length));
-  EXPECT_EQ(1024u, newly_acked_length);
-  EXPECT_EQ(1u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3624, 216, &newly_acked_length));
-  EXPECT_EQ(216u, newly_acked_length);
-  EXPECT_EQ(0u, send_buffer_.size());
-}
-
-TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
-  WriteAllData();
-  QuicByteCount newly_acked_length;
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(100, 1500, &newly_acked_length));
-  EXPECT_EQ(1500u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 500, &newly_acked_length));
-  EXPECT_EQ(500u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 2600, &newly_acked_length));
-  EXPECT_EQ(600u, newly_acked_length);
-  // Send buffer is cleaned up in order.
-  EXPECT_EQ(2u, send_buffer_.size());
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2200, 1640, &newly_acked_length));
-  EXPECT_EQ(1240u, newly_acked_length);
-  EXPECT_EQ(0u, send_buffer_.size());
-
-  EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
-}
-
-TEST_F(QuicStreamSendBufferTest, AckStreamDataOutOfOrder) {
-  WriteAllData();
-  QuicByteCount newly_acked_length;
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 1000, &newly_acked_length));
-  EXPECT_EQ(1000u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1200, 1000, &newly_acked_length));
-  EXPECT_EQ(700u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-  // Slice 2 gets fully acked.
-  EXPECT_EQ(2816u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 1840, &newly_acked_length));
-  EXPECT_EQ(1640u, newly_acked_length);
-  EXPECT_EQ(4u, send_buffer_.size());
-  // Slices 3 and 4 get fully acked.
-  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
-  EXPECT_EQ(500u, newly_acked_length);
-  EXPECT_EQ(0u, send_buffer_.size());
-  EXPECT_EQ(0u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
-}
-
-TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
-  WriteAllData();
-  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
-  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
-  // Lost data [0, 1200).
-  send_buffer_.OnStreamDataLost(0, 1200);
-  // Lost data [1500, 2000).
-  send_buffer_.OnStreamDataLost(1500, 500);
-  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
-
-  EXPECT_EQ(StreamPendingRetransmission(0, 1200),
-            send_buffer_.NextPendingRetransmission());
-  // Retransmit data [0, 500).
-  send_buffer_.OnStreamDataRetransmitted(0, 500);
-  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 500));
-  EXPECT_EQ(StreamPendingRetransmission(500, 700),
-            send_buffer_.NextPendingRetransmission());
-  // Ack data [500, 1200).
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 700, &newly_acked_length));
-  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(500, 700));
-  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
-  EXPECT_EQ(StreamPendingRetransmission(1500, 500),
-            send_buffer_.NextPendingRetransmission());
-  // Retransmit data [1500, 2000).
-  send_buffer_.OnStreamDataRetransmitted(1500, 500);
-  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
-
-  // Lost [200, 800).
-  send_buffer_.OnStreamDataLost(200, 600);
-  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
-  // Verify [200, 500) is considered as lost, as [500, 800) has been acked.
-  EXPECT_EQ(StreamPendingRetransmission(200, 300),
-            send_buffer_.NextPendingRetransmission());
-
-  // Verify 0 length data is not outstanding.
-  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(100, 0));
-  // Verify partially acked data is outstanding.
-  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(400, 800));
-}
-
-TEST_F(QuicStreamSendBufferTest, EndOffset) {
-  char buf[4000];
-  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
-
-  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
-  // Last offset we've seen is 1024
-  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-
-  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 512, &writer));
-  // Last offset is now 2048 as that's the end of the next slice.
-  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-  send_buffer_.OnStreamDataConsumed(1024);
-
-  // If data in 1st slice gets ACK'ed, it shouldn't change the indexed slice
-  QuicByteCount newly_acked_length;
-  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
-  // Last offset is still 2048.
-  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-
-  ASSERT_TRUE(
-      send_buffer_.WriteStreamData(1024 + 512, 3840 - 1024 - 512, &writer));
-
-  // Last offset is end offset of last slice.
-  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-  quiche::QuicheBuffer buffer(&allocator_, 60);
-  memset(buffer.data(), 'e', buffer.size());
-  quiche::QuicheMemSlice slice(std::move(buffer));
-  send_buffer_.SaveMemSlice(std::move(slice));
-
-  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
-}
-
-TEST_F(QuicStreamSendBufferTest, SaveMemSliceSpan) {
-  quiche::SimpleBufferAllocator allocator;
-  QuicStreamSendBuffer send_buffer(&allocator);
-
-  std::string data(1024, 'a');
-  std::vector<quiche::QuicheMemSlice> buffers;
-  for (size_t i = 0; i < 10; ++i) {
-    buffers.push_back(MemSliceFromString(data));
-  }
-
-  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
-  EXPECT_EQ(10u, send_buffer.size());
-}
-
-TEST_F(QuicStreamSendBufferTest, SaveEmptyMemSliceSpan) {
-  quiche::SimpleBufferAllocator allocator;
-  QuicStreamSendBuffer send_buffer(&allocator);
-
-  std::string data(1024, 'a');
-  std::vector<quiche::QuicheMemSlice> buffers;
-  for (size_t i = 0; i < 10; ++i) {
-    buffers.push_back(MemSliceFromString(data));
-  }
-
-  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
-  // Verify the empty slice does not get saved.
-  EXPECT_EQ(10u, send_buffer.size());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_stream_sequencer.cc b/quic/core/quic_stream_sequencer.cc
deleted file mode 100644
index 72211c7..0000000
--- a/quic/core/quic_stream_sequencer.cc
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_stream_sequencer_buffer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-QuicStreamSequencer::QuicStreamSequencer(StreamInterface* quic_stream)
-    : stream_(quic_stream),
-      buffered_frames_(kStreamReceiveWindowLimit),
-      highest_offset_(0),
-      close_offset_(std::numeric_limits<QuicStreamOffset>::max()),
-      blocked_(false),
-      num_frames_received_(0),
-      num_duplicate_frames_received_(0),
-      ignore_read_data_(false),
-      level_triggered_(false) {}
-
-QuicStreamSequencer::~QuicStreamSequencer() {
-  if (stream_ == nullptr) {
-    QUIC_BUG(quic_bug_10858_1) << "Double free'ing QuicStreamSequencer at "
-                               << this << ". " << QuicStackTrace();
-  }
-  stream_ = nullptr;
-}
-
-void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
-  QUICHE_DCHECK_LE(frame.offset + frame.data_length, close_offset_);
-  ++num_frames_received_;
-  const QuicStreamOffset byte_offset = frame.offset;
-  const size_t data_len = frame.data_length;
-
-  if (frame.fin &&
-      (!CloseStreamAtOffset(frame.offset + data_len) || data_len == 0)) {
-    return;
-  }
-  if (stream_->version().HasIetfQuicFrames() && data_len == 0) {
-    QUICHE_DCHECK(!frame.fin);
-    // Ignore empty frame with no fin.
-    return;
-  }
-  OnFrameData(byte_offset, data_len, frame.data_buffer);
-}
-
-void QuicStreamSequencer::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  ++num_frames_received_;
-  if (frame.data_length == 0) {
-    // Ignore empty crypto frame.
-    return;
-  }
-  OnFrameData(frame.offset, frame.data_length, frame.data_buffer);
-}
-
-void QuicStreamSequencer::OnFrameData(QuicStreamOffset byte_offset,
-                                      size_t data_len,
-                                      const char* data_buffer) {
-  highest_offset_ = std::max(highest_offset_, byte_offset + data_len);
-  const size_t previous_readable_bytes = buffered_frames_.ReadableBytes();
-  size_t bytes_written;
-  std::string error_details;
-  QuicErrorCode result = buffered_frames_.OnStreamData(
-      byte_offset, absl::string_view(data_buffer, data_len), &bytes_written,
-      &error_details);
-  if (result != QUIC_NO_ERROR) {
-    std::string details =
-        absl::StrCat("Stream ", stream_->id(), ": ",
-                     QuicErrorCodeToString(result), ": ", error_details);
-    QUIC_LOG_FIRST_N(WARNING, 50) << QuicErrorCodeToString(result);
-    QUIC_LOG_FIRST_N(WARNING, 50) << details;
-    stream_->OnUnrecoverableError(result, details);
-    return;
-  }
-
-  if (bytes_written == 0) {
-    ++num_duplicate_frames_received_;
-    // Silently ignore duplicates.
-    return;
-  }
-
-  if (blocked_) {
-    return;
-  }
-
-  if (level_triggered_) {
-    if (buffered_frames_.ReadableBytes() > previous_readable_bytes) {
-      // Readable bytes has changed, let stream decide if to inform application
-      // or not.
-      if (ignore_read_data_) {
-        FlushBufferedFrames();
-      } else {
-        stream_->OnDataAvailable();
-      }
-    }
-    return;
-  }
-  const bool stream_unblocked =
-      previous_readable_bytes == 0 && buffered_frames_.ReadableBytes() > 0;
-  if (stream_unblocked) {
-    if (ignore_read_data_) {
-      FlushBufferedFrames();
-    } else {
-      stream_->OnDataAvailable();
-    }
-  }
-}
-
-bool QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
-  const QuicStreamOffset kMaxOffset =
-      std::numeric_limits<QuicStreamOffset>::max();
-
-  // If there is a scheduled close, the new offset should match it.
-  if (close_offset_ != kMaxOffset && offset != close_offset_) {
-    stream_->OnUnrecoverableError(
-        QUIC_STREAM_SEQUENCER_INVALID_STATE,
-        absl::StrCat(
-            "Stream ", stream_->id(), " received new final offset: ", offset,
-            ", which is different from close offset: ", close_offset_));
-    return false;
-  }
-
-  // The final offset should be no less than the highest offset that is
-  // received.
-  if (offset < highest_offset_) {
-    stream_->OnUnrecoverableError(
-        QUIC_STREAM_SEQUENCER_INVALID_STATE,
-        absl::StrCat(
-            "Stream ", stream_->id(), " received fin with offset: ", offset,
-            ", which reduces current highest offset: ", highest_offset_));
-    return false;
-  }
-
-  close_offset_ = offset;
-
-  MaybeCloseStream();
-  return true;
-}
-
-void QuicStreamSequencer::MaybeCloseStream() {
-  if (blocked_ || !IsClosed()) {
-    return;
-  }
-
-  QUIC_DVLOG(1) << "Passing up termination, as we've processed "
-                << buffered_frames_.BytesConsumed() << " of " << close_offset_
-                << " bytes.";
-  // This will cause the stream to consume the FIN.
-  // Technically it's an error if |num_bytes_consumed| isn't exactly
-  // equal to |close_offset|, but error handling seems silly at this point.
-  if (ignore_read_data_) {
-    // The sequencer is discarding stream data and must notify the stream on
-    // receipt of a FIN because the consumer won't.
-    stream_->OnFinRead();
-  } else {
-    stream_->OnDataAvailable();
-  }
-  buffered_frames_.Clear();
-}
-
-int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
-  QUICHE_DCHECK(!blocked_);
-  return buffered_frames_.GetReadableRegions(iov, iov_len);
-}
-
-bool QuicStreamSequencer::GetReadableRegion(iovec* iov) const {
-  QUICHE_DCHECK(!blocked_);
-  return buffered_frames_.GetReadableRegion(iov);
-}
-
-bool QuicStreamSequencer::PeekRegion(QuicStreamOffset offset,
-                                     iovec* iov) const {
-  QUICHE_DCHECK(!blocked_);
-  return buffered_frames_.PeekRegion(offset, iov);
-}
-
-void QuicStreamSequencer::Read(std::string* buffer) {
-  QUICHE_DCHECK(!blocked_);
-  buffer->resize(buffer->size() + ReadableBytes());
-  iovec iov;
-  iov.iov_len = ReadableBytes();
-  iov.iov_base = &(*buffer)[buffer->size() - iov.iov_len];
-  Readv(&iov, 1);
-}
-
-size_t QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
-  QUICHE_DCHECK(!blocked_);
-  std::string error_details;
-  size_t bytes_read;
-  QuicErrorCode read_error =
-      buffered_frames_.Readv(iov, iov_len, &bytes_read, &error_details);
-  if (read_error != QUIC_NO_ERROR) {
-    std::string details =
-        absl::StrCat("Stream ", stream_->id(), ": ", error_details);
-    stream_->OnUnrecoverableError(read_error, details);
-    return bytes_read;
-  }
-
-  stream_->AddBytesConsumed(bytes_read);
-  return bytes_read;
-}
-
-bool QuicStreamSequencer::HasBytesToRead() const {
-  return buffered_frames_.HasBytesToRead();
-}
-
-size_t QuicStreamSequencer::ReadableBytes() const {
-  return buffered_frames_.ReadableBytes();
-}
-
-bool QuicStreamSequencer::IsClosed() const {
-  return buffered_frames_.BytesConsumed() >= close_offset_;
-}
-
-void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
-  QUICHE_DCHECK(!blocked_);
-  bool result = buffered_frames_.MarkConsumed(num_bytes_consumed);
-  if (!result) {
-    QUIC_BUG(quic_bug_10858_2)
-        << "Invalid argument to MarkConsumed."
-        << " expect to consume: " << num_bytes_consumed
-        << ", but not enough bytes available. " << DebugString();
-    stream_->ResetWithError(
-        QuicResetStreamError::FromInternal(QUIC_ERROR_PROCESSING_STREAM));
-    return;
-  }
-  stream_->AddBytesConsumed(num_bytes_consumed);
-}
-
-void QuicStreamSequencer::SetBlockedUntilFlush() {
-  blocked_ = true;
-}
-
-void QuicStreamSequencer::SetUnblocked() {
-  blocked_ = false;
-  if (IsClosed() || HasBytesToRead()) {
-    stream_->OnDataAvailable();
-  }
-}
-
-void QuicStreamSequencer::StopReading() {
-  if (ignore_read_data_) {
-    return;
-  }
-  ignore_read_data_ = true;
-  FlushBufferedFrames();
-}
-
-void QuicStreamSequencer::ReleaseBuffer() {
-  buffered_frames_.ReleaseWholeBuffer();
-}
-
-void QuicStreamSequencer::ReleaseBufferIfEmpty() {
-  if (buffered_frames_.Empty()) {
-    buffered_frames_.ReleaseWholeBuffer();
-  }
-}
-
-void QuicStreamSequencer::FlushBufferedFrames() {
-  QUICHE_DCHECK(ignore_read_data_);
-  size_t bytes_flushed = buffered_frames_.FlushBufferedFrames();
-  QUIC_DVLOG(1) << "Flushing buffered data at offset "
-                << buffered_frames_.BytesConsumed() << " length "
-                << bytes_flushed << " for stream " << stream_->id();
-  stream_->AddBytesConsumed(bytes_flushed);
-  MaybeCloseStream();
-}
-
-size_t QuicStreamSequencer::NumBytesBuffered() const {
-  return buffered_frames_.BytesBuffered();
-}
-
-QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
-  return buffered_frames_.BytesConsumed();
-}
-
-const std::string QuicStreamSequencer::DebugString() const {
-  // clang-format off
-  return absl::StrCat("QuicStreamSequencer:",
-                "\n  bytes buffered: ", NumBytesBuffered(),
-                "\n  bytes consumed: ", NumBytesConsumed(),
-                "\n  has bytes to read: ", HasBytesToRead() ? "true" : "false",
-                "\n  frames received: ", num_frames_received(),
-                "\n  close offset bytes: ", close_offset_,
-                "\n  is closed: ", IsClosed() ? "true" : "false");
-  // clang-format on
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_stream_sequencer.h b/quic/core/quic_stream_sequencer.h
deleted file mode 100644
index fe96f25..0000000
--- a/quic/core/quic_stream_sequencer.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
-
-#include <cstddef>
-#include <map>
-#include <string>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_sequencer_buffer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamSequencerPeer;
-}  // namespace test
-
-// Buffers frames until we have something which can be passed
-// up to the next layer.
-class QUIC_EXPORT_PRIVATE QuicStreamSequencer {
- public:
-  // Interface that thie Sequencer uses to communicate with the Stream.
-  class QUIC_EXPORT_PRIVATE StreamInterface {
-   public:
-    virtual ~StreamInterface() = default;
-
-    // Called when new data is available to be read from the sequencer.
-    virtual void OnDataAvailable() = 0;
-    // Called when the end of the stream has been read.
-    virtual void OnFinRead() = 0;
-    // Called when bytes have been consumed from the sequencer.
-    virtual void AddBytesConsumed(QuicByteCount bytes) = 0;
-    // Called when an error has occurred which should result in the stream
-    // being reset.
-    virtual void ResetWithError(QuicResetStreamError error) = 0;
-    // Called when an error has occurred which should result in the connection
-    // being closed.
-    virtual void OnUnrecoverableError(QuicErrorCode error,
-                                      const std::string& details) = 0;
-    // Called when an error has occurred which should result in the connection
-    // being closed, specifying the wire error code |ietf_error| explicitly.
-    virtual void OnUnrecoverableError(QuicErrorCode error,
-                                      QuicIetfTransportErrorCodes ietf_error,
-                                      const std::string& details) = 0;
-    // Returns the stream id of this stream.
-    virtual QuicStreamId id() const = 0;
-
-    // Returns the QUIC version being used by this stream.
-    virtual ParsedQuicVersion version() const = 0;
-  };
-
-  explicit QuicStreamSequencer(StreamInterface* quic_stream);
-  QuicStreamSequencer(const QuicStreamSequencer&) = delete;
-  QuicStreamSequencer(QuicStreamSequencer&&) = default;
-  QuicStreamSequencer& operator=(const QuicStreamSequencer&) = delete;
-  QuicStreamSequencer& operator=(QuicStreamSequencer&&) = default;
-  virtual ~QuicStreamSequencer();
-
-  // If the frame is the next one we need in order to process in-order data,
-  // ProcessData will be immediately called on the stream until all buffered
-  // data is processed or the stream fails to consume data.  Any unconsumed
-  // data will be buffered. If the frame is not the next in line, it will be
-  // buffered.
-  void OnStreamFrame(const QuicStreamFrame& frame);
-
-  // If the frame is the next one we need in order to process in-order data,
-  // ProcessData will be immediately called on the crypto stream until all
-  // buffered data is processed or the crypto stream fails to consume data. Any
-  // unconsumed data will be buffered. If the frame is not the next in line, it
-  // will be buffered.
-  void OnCryptoFrame(const QuicCryptoFrame& frame);
-
-  // Once data is buffered, it's up to the stream to read it when the stream
-  // can handle more data.  The following three functions make that possible.
-
-  // Fills in up to iov_len iovecs with the next readable regions.  Returns the
-  // number of iovs used.  Non-destructive of the underlying data.
-  int GetReadableRegions(iovec* iov, size_t iov_len) const;
-
-  // Fills in one iovec with the next readable region.  Returns false if there
-  // is no readable region available.
-  bool GetReadableRegion(iovec* iov) const;
-
-  // Fills in one iovec with the region starting at |offset| and returns true.
-  // Returns false if no readable region is available, either because data has
-  // not been received yet or has already been consumed.
-  bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
-
-  // Copies the data into the iov_len buffers provided.  Returns the number of
-  // bytes read.  Any buffered data no longer in use will be released.
-  // TODO(rch): remove this method and instead implement it as a helper method
-  // based on GetReadableRegions and MarkConsumed.
-  size_t Readv(const struct iovec* iov, size_t iov_len);
-
-  // Consumes |num_bytes| data.  Used in conjunction with |GetReadableRegions|
-  // to do zero-copy reads.
-  void MarkConsumed(size_t num_bytes);
-
-  // Appends all of the readable data to |buffer| and marks all of the appended
-  // data as consumed.
-  void Read(std::string* buffer);
-
-  // Returns true if the sequncer has bytes available for reading.
-  bool HasBytesToRead() const;
-
-  // Number of bytes available to read.
-  size_t ReadableBytes() const;
-
-  // Returns true if the sequencer has delivered the fin.
-  bool IsClosed() const;
-
-  // Calls |OnDataAvailable| on |stream_| if there is buffered data that can
-  // be processed, and causes |OnDataAvailable| to be called as new data
-  // arrives.
-  void SetUnblocked();
-
-  // Blocks processing of frames until |SetUnblocked| is called.
-  void SetBlockedUntilFlush();
-
-  // Sets the sequencer to discard all incoming data itself and not call
-  // |stream_->OnDataAvailable()|.  |stream_->OnFinRead()| will be called
-  // automatically when the FIN is consumed (which may be immediately).
-  void StopReading();
-
-  // Free the memory of underlying buffer.
-  void ReleaseBuffer();
-
-  // Free the memory of underlying buffer when no bytes remain in it.
-  void ReleaseBufferIfEmpty();
-
-  // Number of bytes in the buffer right now.
-  size_t NumBytesBuffered() const;
-
-  // Number of bytes has been consumed.
-  QuicStreamOffset NumBytesConsumed() const;
-
-  QuicStreamOffset close_offset() const { return close_offset_; }
-
-  int num_frames_received() const { return num_frames_received_; }
-
-  int num_duplicate_frames_received() const {
-    return num_duplicate_frames_received_;
-  }
-
-  bool ignore_read_data() const { return ignore_read_data_; }
-
-  void set_level_triggered(bool level_triggered) {
-    level_triggered_ = level_triggered;
-  }
-
-  bool level_triggered() const { return level_triggered_; }
-
-  void set_stream(StreamInterface* stream) { stream_ = stream; }
-
-  // Returns string describing internal state.
-  const std::string DebugString() const;
-
- private:
-  friend class test::QuicStreamSequencerPeer;
-
-  // Deletes and records as consumed any buffered data that is now in-sequence.
-  // (To be called only after StopReading has been called.)
-  void FlushBufferedFrames();
-
-  // Wait until we've seen 'offset' bytes, and then terminate the stream.
-  // Returns true if |stream_| is still available to receive data, and false if
-  // |stream_| is reset.
-  bool CloseStreamAtOffset(QuicStreamOffset offset);
-
-  // If we've received a FIN and have processed all remaining data, then inform
-  // the stream of FIN, and clear buffers.
-  void MaybeCloseStream();
-
-  // Shared implementation between OnStreamFrame and OnCryptoFrame.
-  void OnFrameData(QuicStreamOffset byte_offset,
-                   size_t data_len,
-                   const char* data_buffer);
-
-  // The stream which owns this sequencer.
-  StreamInterface* stream_;
-
-  // Stores received data in offset order.
-  QuicStreamSequencerBuffer buffered_frames_;
-
-  // The highest offset that is received so far.
-  QuicStreamOffset highest_offset_;
-
-  // The offset, if any, we got a stream termination for.  When this many bytes
-  // have been processed, the sequencer will be closed.
-  QuicStreamOffset close_offset_;
-
-  // If true, the sequencer is blocked from passing data to the stream and will
-  // buffer all new incoming data until FlushBufferedFrames is called.
-  bool blocked_;
-
-  // Count of the number of frames received.
-  int num_frames_received_;
-
-  // Count of the number of duplicate frames received.
-  int num_duplicate_frames_received_;
-
-  // If true, all incoming data will be discarded.
-  bool ignore_read_data_;
-
-  // If false, only call OnDataAvailable() when it becomes newly unblocked.
-  // Otherwise, call OnDataAvailable() when number of readable bytes changes.
-  bool level_triggered_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
diff --git a/quic/core/quic_stream_sequencer_buffer.cc b/quic/core/quic_stream_sequencer_buffer.cc
deleted file mode 100644
index a4c02f3..0000000
--- a/quic/core/quic_stream_sequencer_buffer.cc
+++ /dev/null
@@ -1,546 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer_buffer.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_interval.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace {
-
-size_t CalculateBlockCount(size_t max_capacity_bytes) {
-  return (max_capacity_bytes + QuicStreamSequencerBuffer::kBlockSizeBytes - 1) /
-         QuicStreamSequencerBuffer::kBlockSizeBytes;
-}
-
-// Upper limit of how many gaps allowed in buffer, which ensures a reasonable
-// number of iterations needed to find the right gap to fill when a frame
-// arrives.
-const size_t kMaxNumDataIntervalsAllowed = 2 * kMaxPacketGap;
-
-// Number of blocks allocated initially.
-constexpr size_t kInitialBlockCount = 8u;
-
-// How fast block pointers container grow in size.
-// Choose 4 to reduce the amount of reallocation.
-constexpr int kBlocksGrowthFactor = 4;
-
-}  // namespace
-
-QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes)
-    : max_buffer_capacity_bytes_(max_capacity_bytes),
-      max_blocks_count_(CalculateBlockCount(max_capacity_bytes)),
-      current_blocks_count_(0u),
-      total_bytes_read_(0),
-      blocks_(nullptr) {
-  QUICHE_DCHECK_GE(max_blocks_count_, kInitialBlockCount);
-  Clear();
-}
-
-QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() {
-  Clear();
-}
-
-void QuicStreamSequencerBuffer::Clear() {
-  if (blocks_ != nullptr) {
-    for (size_t i = 0; i < current_blocks_count_; ++i) {
-      if (blocks_[i] != nullptr) {
-        RetireBlock(i);
-      }
-    }
-  }
-  num_bytes_buffered_ = 0;
-  bytes_received_.Clear();
-  bytes_received_.Add(0, total_bytes_read_);
-}
-
-bool QuicStreamSequencerBuffer::RetireBlock(size_t index) {
-  if (blocks_[index] == nullptr) {
-    QUIC_BUG(quic_bug_10610_1) << "Try to retire block twice";
-    return false;
-  }
-  delete blocks_[index];
-  blocks_[index] = nullptr;
-  QUIC_DVLOG(1) << "Retired block with index: " << index;
-  return true;
-}
-
-void QuicStreamSequencerBuffer::MaybeAddMoreBlocks(
-    QuicStreamOffset next_expected_byte) {
-  if (current_blocks_count_ == max_blocks_count_) {
-    return;
-  }
-  QuicStreamOffset last_byte = next_expected_byte - 1;
-  size_t num_of_blocks_needed;
-  // As long as last_byte does not wrap around, its index plus one blocks are
-  // needed. Otherwise, block_count_ blocks are needed.
-  if (last_byte < max_buffer_capacity_bytes_) {
-    num_of_blocks_needed =
-        std::max(GetBlockIndex(last_byte) + 1, kInitialBlockCount);
-  } else {
-    num_of_blocks_needed = max_blocks_count_;
-  }
-  if (current_blocks_count_ >= num_of_blocks_needed) {
-    return;
-  }
-  size_t new_block_count = kBlocksGrowthFactor * current_blocks_count_;
-  new_block_count = std::min(std::max(new_block_count, num_of_blocks_needed),
-                             max_blocks_count_);
-  auto new_blocks = std::make_unique<BufferBlock*[]>(new_block_count);
-  if (blocks_ != nullptr) {
-    memcpy(new_blocks.get(), blocks_.get(),
-           current_blocks_count_ * sizeof(BufferBlock*));
-  }
-  blocks_ = std::move(new_blocks);
-  current_blocks_count_ = new_block_count;
-}
-
-QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
-    QuicStreamOffset starting_offset,
-    absl::string_view data,
-    size_t* const bytes_buffered,
-    std::string* error_details) {
-  *bytes_buffered = 0;
-  size_t size = data.size();
-  if (size == 0) {
-    *error_details = "Received empty stream frame without FIN.";
-    return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
-  }
-  // Write beyond the current range this buffer is covering.
-  if (starting_offset + size > total_bytes_read_ + max_buffer_capacity_bytes_ ||
-      starting_offset + size < starting_offset) {
-    *error_details = "Received data beyond available range.";
-    return QUIC_INTERNAL_ERROR;
-  }
-
-  if (bytes_received_.Empty() ||
-      starting_offset >= bytes_received_.rbegin()->max() ||
-      bytes_received_.IsDisjoint(QuicInterval<QuicStreamOffset>(
-          starting_offset, starting_offset + size))) {
-    // Optimization for the typical case, when all data is newly received.
-    bytes_received_.AddOptimizedForAppend(starting_offset,
-                                          starting_offset + size);
-    if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
-      // This frame is going to create more intervals than allowed. Stop
-      // processing.
-      *error_details = "Too many data intervals received for this stream.";
-      return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
-    }
-    MaybeAddMoreBlocks(starting_offset + size);
-
-    size_t bytes_copy = 0;
-    if (!CopyStreamData(starting_offset, data, &bytes_copy, error_details)) {
-      return QUIC_STREAM_SEQUENCER_INVALID_STATE;
-    }
-    *bytes_buffered += bytes_copy;
-    num_bytes_buffered_ += *bytes_buffered;
-    return QUIC_NO_ERROR;
-  }
-  // Slow path, received data overlaps with received data.
-  QuicIntervalSet<QuicStreamOffset> newly_received(starting_offset,
-                                                   starting_offset + size);
-  newly_received.Difference(bytes_received_);
-  if (newly_received.Empty()) {
-    return QUIC_NO_ERROR;
-  }
-  bytes_received_.Add(starting_offset, starting_offset + size);
-  if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
-    // This frame is going to create more intervals than allowed. Stop
-    // processing.
-    *error_details = "Too many data intervals received for this stream.";
-    return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
-  }
-  MaybeAddMoreBlocks(starting_offset + size);
-  for (const auto& interval : newly_received) {
-    const QuicStreamOffset copy_offset = interval.min();
-    const QuicByteCount copy_length = interval.max() - interval.min();
-    size_t bytes_copy = 0;
-    if (!CopyStreamData(copy_offset,
-                        data.substr(copy_offset - starting_offset, copy_length),
-                        &bytes_copy, error_details)) {
-      return QUIC_STREAM_SEQUENCER_INVALID_STATE;
-    }
-    *bytes_buffered += bytes_copy;
-  }
-  num_bytes_buffered_ += *bytes_buffered;
-  return QUIC_NO_ERROR;
-}
-
-bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset,
-                                               absl::string_view data,
-                                               size_t* bytes_copy,
-                                               std::string* error_details) {
-  *bytes_copy = 0;
-  size_t source_remaining = data.size();
-  if (source_remaining == 0) {
-    return true;
-  }
-  const char* source = data.data();
-  // Write data block by block. If corresponding block has not created yet,
-  // create it first.
-  // Stop when all data are written or reaches the logical end of the buffer.
-  while (source_remaining > 0) {
-    const size_t write_block_num = GetBlockIndex(offset);
-    const size_t write_block_offset = GetInBlockOffset(offset);
-    size_t current_blocks_count = current_blocks_count_;
-    QUICHE_DCHECK_GT(current_blocks_count, write_block_num);
-
-    size_t block_capacity = GetBlockCapacity(write_block_num);
-    size_t bytes_avail = block_capacity - write_block_offset;
-
-    // If this write meets the upper boundary of the buffer,
-    // reduce the available free bytes.
-    if (offset + bytes_avail > total_bytes_read_ + max_buffer_capacity_bytes_) {
-      bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset;
-    }
-
-    if (write_block_num >= current_blocks_count) {
-      *error_details = absl::StrCat(
-          "QuicStreamSequencerBuffer error: OnStreamData() exceed array bounds."
-          "write offset = ",
-          offset, " write_block_num = ", write_block_num,
-          " current_blocks_count_ = ", current_blocks_count);
-      return false;
-    }
-    if (blocks_ == nullptr) {
-      *error_details =
-          "QuicStreamSequencerBuffer error: OnStreamData() blocks_ is null";
-      return false;
-    }
-    if (blocks_[write_block_num] == nullptr) {
-      // TODO(danzh): Investigate if using a freelist would improve performance.
-      // Same as RetireBlock().
-      blocks_[write_block_num] = new BufferBlock();
-    }
-
-    const size_t bytes_to_copy =
-        std::min<size_t>(bytes_avail, source_remaining);
-    char* dest = blocks_[write_block_num]->buffer + write_block_offset;
-    QUIC_DVLOG(1) << "Write at offset: " << offset
-                  << " length: " << bytes_to_copy;
-
-    if (dest == nullptr || source == nullptr) {
-      *error_details = absl::StrCat(
-          "QuicStreamSequencerBuffer error: OnStreamData()"
-          " dest == nullptr: ",
-          (dest == nullptr), " source == nullptr: ", (source == nullptr),
-          " Writing at offset ", offset,
-          " Received frames: ", ReceivedFramesDebugString(),
-          " total_bytes_read_ = ", total_bytes_read_);
-      return false;
-    }
-    memcpy(dest, source, bytes_to_copy);
-    source += bytes_to_copy;
-    source_remaining -= bytes_to_copy;
-    offset += bytes_to_copy;
-    *bytes_copy += bytes_to_copy;
-  }
-  return true;
-}
-
-QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov,
-                                               size_t dest_count,
-                                               size_t* bytes_read,
-                                               std::string* error_details) {
-  *bytes_read = 0;
-  for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
-    char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
-    QUICHE_DCHECK(dest != nullptr);
-    size_t dest_remaining = dest_iov[i].iov_len;
-    while (dest_remaining > 0 && ReadableBytes() > 0) {
-      size_t block_idx = NextBlockToRead();
-      size_t start_offset_in_block = ReadOffset();
-      size_t block_capacity = GetBlockCapacity(block_idx);
-      size_t bytes_available_in_block = std::min<size_t>(
-          ReadableBytes(), block_capacity - start_offset_in_block);
-      size_t bytes_to_copy =
-          std::min<size_t>(bytes_available_in_block, dest_remaining);
-      QUICHE_DCHECK_GT(bytes_to_copy, 0u);
-      if (blocks_[block_idx] == nullptr || dest == nullptr) {
-        *error_details = absl::StrCat(
-            "QuicStreamSequencerBuffer error:"
-            " Readv() dest == nullptr: ",
-            (dest == nullptr), " blocks_[", block_idx,
-            "] == nullptr: ", (blocks_[block_idx] == nullptr),
-            " Received frames: ", ReceivedFramesDebugString(),
-            " total_bytes_read_ = ", total_bytes_read_);
-        return QUIC_STREAM_SEQUENCER_INVALID_STATE;
-      }
-      memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
-             bytes_to_copy);
-      dest += bytes_to_copy;
-      dest_remaining -= bytes_to_copy;
-      num_bytes_buffered_ -= bytes_to_copy;
-      total_bytes_read_ += bytes_to_copy;
-      *bytes_read += bytes_to_copy;
-
-      // Retire the block if all the data is read out and no other data is
-      // stored in this block.
-      // In case of failing to retire a block which is ready to retire, return
-      // immediately.
-      if (bytes_to_copy == bytes_available_in_block) {
-        bool retire_successfully = RetireBlockIfEmpty(block_idx);
-        if (!retire_successfully) {
-          *error_details = absl::StrCat(
-              "QuicStreamSequencerBuffer error: fail to retire block ",
-              block_idx,
-              " as the block is already released, total_bytes_read_ = ",
-              total_bytes_read_,
-              " Received frames: ", ReceivedFramesDebugString());
-          return QUIC_STREAM_SEQUENCER_INVALID_STATE;
-        }
-      }
-    }
-  }
-
-  return QUIC_NO_ERROR;
-}
-
-int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
-                                                  int iov_len) const {
-  QUICHE_DCHECK(iov != nullptr);
-  QUICHE_DCHECK_GT(iov_len, 0);
-
-  if (ReadableBytes() == 0) {
-    iov[0].iov_base = nullptr;
-    iov[0].iov_len = 0;
-    return 0;
-  }
-
-  size_t start_block_idx = NextBlockToRead();
-  QuicStreamOffset readable_offset_end = FirstMissingByte() - 1;
-  QUICHE_DCHECK_GE(readable_offset_end + 1, total_bytes_read_);
-  size_t end_block_offset = GetInBlockOffset(readable_offset_end);
-  size_t end_block_idx = GetBlockIndex(readable_offset_end);
-
-  // If readable region is within one block, deal with it seperately.
-  if (start_block_idx == end_block_idx && ReadOffset() <= end_block_offset) {
-    iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
-    iov[0].iov_len = ReadableBytes();
-    QUIC_DVLOG(1) << "Got only a single block with index: " << start_block_idx;
-    return 1;
-  }
-
-  // Get first block
-  iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
-  iov[0].iov_len = GetBlockCapacity(start_block_idx) - ReadOffset();
-  QUIC_DVLOG(1) << "Got first block " << start_block_idx << " with len "
-                << iov[0].iov_len;
-  QUICHE_DCHECK_GT(readable_offset_end + 1, total_bytes_read_ + iov[0].iov_len)
-      << "there should be more available data";
-
-  // Get readable regions of the rest blocks till either 2nd to last block
-  // before gap is met or |iov| is filled. For these blocks, one whole block is
-  // a region.
-  int iov_used = 1;
-  size_t block_idx = (start_block_idx + iov_used) % max_blocks_count_;
-  while (block_idx != end_block_idx && iov_used < iov_len) {
-    QUICHE_DCHECK(nullptr != blocks_[block_idx]);
-    iov[iov_used].iov_base = blocks_[block_idx]->buffer;
-    iov[iov_used].iov_len = GetBlockCapacity(block_idx);
-    QUIC_DVLOG(1) << "Got block with index: " << block_idx;
-    ++iov_used;
-    block_idx = (start_block_idx + iov_used) % max_blocks_count_;
-  }
-
-  // Deal with last block if |iov| can hold more.
-  if (iov_used < iov_len) {
-    QUICHE_DCHECK(nullptr != blocks_[block_idx]);
-    iov[iov_used].iov_base = blocks_[end_block_idx]->buffer;
-    iov[iov_used].iov_len = end_block_offset + 1;
-    QUIC_DVLOG(1) << "Got last block with index: " << end_block_idx;
-    ++iov_used;
-  }
-  return iov_used;
-}
-
-bool QuicStreamSequencerBuffer::GetReadableRegion(iovec* iov) const {
-  return GetReadableRegions(iov, 1) == 1;
-}
-
-bool QuicStreamSequencerBuffer::PeekRegion(QuicStreamOffset offset,
-                                           iovec* iov) const {
-  QUICHE_DCHECK(iov);
-
-  if (offset < total_bytes_read_) {
-    // Data at |offset| has already been consumed.
-    return false;
-  }
-
-  if (offset >= FirstMissingByte()) {
-    // Data at |offset| has not been received yet.
-    return false;
-  }
-
-  // Beginning of region.
-  size_t block_idx = GetBlockIndex(offset);
-  size_t block_offset = GetInBlockOffset(offset);
-  iov->iov_base = blocks_[block_idx]->buffer + block_offset;
-
-  // Determine if entire block has been received.
-  size_t end_block_idx = GetBlockIndex(FirstMissingByte());
-  if (block_idx == end_block_idx) {
-    // Only read part of block before FirstMissingByte().
-    iov->iov_len = GetInBlockOffset(FirstMissingByte()) - block_offset;
-  } else {
-    // Read entire block.
-    iov->iov_len = GetBlockCapacity(block_idx) - block_offset;
-  }
-
-  return true;
-}
-
-bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_consumed) {
-  if (bytes_consumed > ReadableBytes()) {
-    return false;
-  }
-  size_t bytes_to_consume = bytes_consumed;
-  while (bytes_to_consume > 0) {
-    size_t block_idx = NextBlockToRead();
-    size_t offset_in_block = ReadOffset();
-    size_t bytes_available = std::min<size_t>(
-        ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block);
-    size_t bytes_read = std::min<size_t>(bytes_to_consume, bytes_available);
-    total_bytes_read_ += bytes_read;
-    num_bytes_buffered_ -= bytes_read;
-    bytes_to_consume -= bytes_read;
-    // If advanced to the end of current block and end of buffer hasn't wrapped
-    // to this block yet.
-    if (bytes_available == bytes_read) {
-      RetireBlockIfEmpty(block_idx);
-    }
-  }
-
-  return true;
-}
-
-size_t QuicStreamSequencerBuffer::FlushBufferedFrames() {
-  size_t prev_total_bytes_read = total_bytes_read_;
-  total_bytes_read_ = NextExpectedByte();
-  Clear();
-  return total_bytes_read_ - prev_total_bytes_read;
-}
-
-void QuicStreamSequencerBuffer::ReleaseWholeBuffer() {
-  Clear();
-  current_blocks_count_ = 0;
-  blocks_.reset(nullptr);
-}
-
-size_t QuicStreamSequencerBuffer::ReadableBytes() const {
-  return FirstMissingByte() - total_bytes_read_;
-}
-
-bool QuicStreamSequencerBuffer::HasBytesToRead() const {
-  return ReadableBytes() > 0;
-}
-
-QuicStreamOffset QuicStreamSequencerBuffer::BytesConsumed() const {
-  return total_bytes_read_;
-}
-
-size_t QuicStreamSequencerBuffer::BytesBuffered() const {
-  return num_bytes_buffered_;
-}
-
-size_t QuicStreamSequencerBuffer::GetBlockIndex(QuicStreamOffset offset) const {
-  return (offset % max_buffer_capacity_bytes_) / kBlockSizeBytes;
-}
-
-size_t QuicStreamSequencerBuffer::GetInBlockOffset(
-    QuicStreamOffset offset) const {
-  return (offset % max_buffer_capacity_bytes_) % kBlockSizeBytes;
-}
-
-size_t QuicStreamSequencerBuffer::ReadOffset() const {
-  return GetInBlockOffset(total_bytes_read_);
-}
-
-size_t QuicStreamSequencerBuffer::NextBlockToRead() const {
-  return GetBlockIndex(total_bytes_read_);
-}
-
-bool QuicStreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) {
-  QUICHE_DCHECK(ReadableBytes() == 0 ||
-                GetInBlockOffset(total_bytes_read_) == 0)
-      << "RetireBlockIfEmpty() should only be called when advancing to next "
-      << "block or a gap has been reached.";
-  // If the whole buffer becomes empty, the last piece of data has been read.
-  if (Empty()) {
-    return RetireBlock(block_index);
-  }
-
-  // Check where the logical end of this buffer is.
-  // Not empty if the end of circular buffer has been wrapped to this block.
-  if (GetBlockIndex(NextExpectedByte() - 1) == block_index) {
-    return true;
-  }
-
-  // Read index remains in this block, which means a gap has been reached.
-  if (NextBlockToRead() == block_index) {
-    if (bytes_received_.Size() > 1) {
-      auto it = bytes_received_.begin();
-      ++it;
-      if (GetBlockIndex(it->min()) == block_index) {
-        // Do not retire the block if next data interval is in this block.
-        return true;
-      }
-    } else {
-      QUIC_BUG(quic_bug_10610_2) << "Read stopped at where it shouldn't.";
-      return false;
-    }
-  }
-  return RetireBlock(block_index);
-}
-
-bool QuicStreamSequencerBuffer::Empty() const {
-  return bytes_received_.Empty() ||
-         (bytes_received_.Size() == 1 && total_bytes_read_ > 0 &&
-          bytes_received_.begin()->max() == total_bytes_read_);
-}
-
-size_t QuicStreamSequencerBuffer::GetBlockCapacity(size_t block_index) const {
-  if ((block_index + 1) == max_blocks_count_) {
-    size_t result = max_buffer_capacity_bytes_ % kBlockSizeBytes;
-    if (result == 0) {  // whole block
-      result = kBlockSizeBytes;
-    }
-    return result;
-  } else {
-    return kBlockSizeBytes;
-  }
-}
-
-std::string QuicStreamSequencerBuffer::ReceivedFramesDebugString() const {
-  return bytes_received_.ToString();
-}
-
-QuicStreamOffset QuicStreamSequencerBuffer::FirstMissingByte() const {
-  if (bytes_received_.Empty() || bytes_received_.begin()->min() > 0) {
-    // Offset 0 is not received yet.
-    return 0;
-  }
-  return bytes_received_.begin()->max();
-}
-
-QuicStreamOffset QuicStreamSequencerBuffer::NextExpectedByte() const {
-  if (bytes_received_.Empty()) {
-    return 0;
-  }
-  return bytes_received_.rbegin()->max();
-}
-
-}  //  namespace quic
diff --git a/quic/core/quic_stream_sequencer_buffer.h b/quic/core/quic_stream_sequencer_buffer.h
deleted file mode 100644
index 18869f6..0000000
--- a/quic/core/quic_stream_sequencer_buffer.h
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
-#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
-
-// QuicStreamSequencerBuffer is a circular stream buffer with random write and
-// in-sequence read. It consists of a vector of pointers pointing
-// to memory blocks created as needed and an interval set recording received
-// data.
-// - Data are written in with offset indicating where it should be in the
-// stream, and the buffer grown as needed (up to the maximum buffer capacity),
-// without expensive copying (extra blocks are allocated).
-// - Data can be read from the buffer if there is no gap before it,
-// and the buffer shrinks as the data are consumed.
-// - An upper limit on the number of blocks in the buffer provides an upper
-//   bound on memory use.
-//
-// This class is thread-unsafe.
-//
-// QuicStreamSequencerBuffer maintains a concept of the readable region, which
-// contains all written data that has not been read.
-// It promises stability of the underlying memory addresses in the readable
-// region, so pointers into it can be maintained, and the offset of a pointer
-// from the start of the read region can be calculated.
-//
-// Expected Use:
-//  QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024);
-//  std::string source(1024, 'a');
-//  absl::string_view string_piece(source.data(), source.size());
-//  size_t written = 0;
-//  buffer.OnStreamData(800, string_piece, GetEpollClockNow(), &written);
-//  source = std::string{800, 'b'};
-//  absl::string_view string_piece1(source.data(), 800);
-//  // Try to write to [1, 801), but should fail due to overlapping,
-//  // res should be QUIC_INVALID_STREAM_DATA
-//  auto res = buffer.OnStreamData(1, string_piece1, &written));
-//  // write to [0, 800), res should be QUIC_NO_ERROR
-//  auto res = buffer.OnStreamData(0, string_piece1, GetEpollClockNow(),
-//                                  &written);
-//
-//  // Read into a iovec array with total capacity of 120 bytes.
-//  char dest[120];
-//  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40},
-//                  iovec{dest + 80, 40}};
-//  size_t read = buffer.Readv(iovecs, 3);
-//
-//  // Get single readable region.
-//  iovec iov;
-//  buffer.GetReadableRegion(iov);
-//
-//  // Get readable regions from [256, 1024) and consume some of it.
-//  iovec iovs[2];
-//  int iov_count = buffer.GetReadableRegions(iovs, 2);
-//  // Consume some bytes in iovs, returning number of bytes having been
-//  consumed.
-//  size_t consumed = consume_iovs(iovs, iov_count);
-//  buffer.MarkConsumed(consumed);
-
-#include <cstddef>
-#include <functional>
-#include <list>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_iovec.h"
-
-namespace quic {
-
-namespace test {
-class QuicStreamSequencerBufferPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
- public:
-  // Size of blocks used by this buffer.
-  // Choose 8K to make block large enough to hold multiple frames, each of
-  // which could be up to 1.5 KB.
-  static const size_t kBlockSizeBytes = 8 * 1024;  // 8KB
-
-  // The basic storage block used by this buffer.
-  struct QUIC_EXPORT_PRIVATE BufferBlock {
-    char buffer[kBlockSizeBytes];
-  };
-
-  explicit QuicStreamSequencerBuffer(size_t max_capacity_bytes);
-  QuicStreamSequencerBuffer(const QuicStreamSequencerBuffer&) = delete;
-  QuicStreamSequencerBuffer(QuicStreamSequencerBuffer&&) = default;
-  QuicStreamSequencerBuffer& operator=(const QuicStreamSequencerBuffer&) =
-      delete;
-  QuicStreamSequencerBuffer& operator=(QuicStreamSequencerBuffer&&) = default;
-  ~QuicStreamSequencerBuffer();
-
-  // Free the space used to buffer data.
-  void Clear();
-
-  // Returns true if there is nothing to read in this buffer.
-  bool Empty() const;
-
-  // Called to buffer new data received for this stream.  If the data was
-  // successfully buffered, returns QUIC_NO_ERROR and stores the number of
-  // bytes buffered in |bytes_buffered|. Returns an error otherwise.
-  QuicErrorCode OnStreamData(QuicStreamOffset offset,
-                             absl::string_view data,
-                             size_t* bytes_buffered,
-                             std::string* error_details);
-
-  // Reads from this buffer into given iovec array, up to number of iov_len
-  // iovec objects and returns the number of bytes read.
-  QuicErrorCode Readv(const struct iovec* dest_iov,
-                      size_t dest_count,
-                      size_t* bytes_read,
-                      std::string* error_details);
-
-  // Returns the readable region of valid data in iovec format. The readable
-  // region is the buffer region where there is valid data not yet read by
-  // client.
-  // Returns the number of iovec entries in |iov| which were populated.
-  // If the region is empty, one iovec entry with 0 length
-  // is returned, and the function returns 0. If there are more readable
-  // regions than |iov_size|, the function only processes the first
-  // |iov_size| of them.
-  int GetReadableRegions(struct iovec* iov, int iov_len) const;
-
-  // Fills in one iovec with data from the next readable region.
-  // Returns false if there is no readable region available.
-  bool GetReadableRegion(iovec* iov) const;
-
-  // Returns true and sets |*iov| to point to a region starting at |offset|.
-  // Returns false if no data can be read at |offset|, which can be because data
-  // has not been received yet or it is already consumed.
-  // Does not consume data.
-  bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
-
-  // Called after GetReadableRegions() to free up |bytes_consumed| space if
-  // these bytes are processed.
-  // Pre-requisite: bytes_consumed <= available bytes to read.
-  bool MarkConsumed(size_t bytes_consumed);
-
-  // Deletes and records as consumed any buffered data and clear the buffer.
-  // (To be called only after sequencer's StopReading has been called.)
-  size_t FlushBufferedFrames();
-
-  // Free the memory of buffered data.
-  void ReleaseWholeBuffer();
-
-  // Whether there are bytes can be read out.
-  bool HasBytesToRead() const;
-
-  // Count how many bytes have been consumed (read out of buffer).
-  QuicStreamOffset BytesConsumed() const;
-
-  // Count how many bytes are in buffer at this moment.
-  size_t BytesBuffered() const;
-
-  // Returns number of bytes available to be read out.
-  size_t ReadableBytes() const;
-
- private:
-  friend class test::QuicStreamSequencerBufferPeer;
-
-  // Copies |data| to blocks_, sets |bytes_copy|. Returns true if the copy is
-  // successful. Otherwise, sets |error_details| and returns false.
-  bool CopyStreamData(QuicStreamOffset offset,
-                      absl::string_view data,
-                      size_t* bytes_copy,
-                      std::string* error_details);
-
-  // Dispose the given buffer block.
-  // After calling this method, blocks_[index] is set to nullptr
-  // in order to indicate that no memory set is allocated for that block.
-  // Returns true on success, false otherwise.
-  bool RetireBlock(size_t index);
-
-  // Should only be called after the indexed block is read till the end of the
-  // block or missing data has been reached.
-  // If the block at |block_index| contains no buffered data, the block
-  // should be retired.
-  // Returns true on success, or false otherwise.
-  bool RetireBlockIfEmpty(size_t block_index);
-
-  // Calculate the capacity of block at specified index.
-  // Return value should be either kBlockSizeBytes for non-trailing blocks and
-  // max_buffer_capacity % kBlockSizeBytes for trailing block.
-  size_t GetBlockCapacity(size_t index) const;
-
-  // Does not check if offset is within reasonable range.
-  size_t GetBlockIndex(QuicStreamOffset offset) const;
-
-  // Given an offset in the stream, return the offset from the beginning of the
-  // block which contains this data.
-  size_t GetInBlockOffset(QuicStreamOffset offset) const;
-
-  // Get offset relative to index 0 in logical 1st block to start next read.
-  size_t ReadOffset() const;
-
-  // Get the index of the logical 1st block to start next read.
-  size_t NextBlockToRead() const;
-
-  // Returns offset of first missing byte.
-  QuicStreamOffset FirstMissingByte() const;
-
-  // Returns offset of highest received byte + 1.
-  QuicStreamOffset NextExpectedByte() const;
-
-  // Return all received frames as a string.
-  std::string ReceivedFramesDebugString() const;
-
-  // Resize blocks_ if more blocks are needed to accomodate bytes before
-  // next_expected_byte.
-  void MaybeAddMoreBlocks(QuicStreamOffset next_expected_byte);
-
-  // The maximum total capacity of this buffer in byte, as constructed.
-  size_t max_buffer_capacity_bytes_;
-
-  // Number of blocks this buffer would have when it reaches full capacity,
-  // i.e., maximal number of blocks in blocks_.
-  size_t max_blocks_count_;
-
-  // Number of blocks this buffer currently has.
-  size_t current_blocks_count_;
-
-  // Number of bytes read out of buffer.
-  QuicStreamOffset total_bytes_read_;
-
-  // An ordered, variable-length list of blocks, with the length limited
-  // such that the number of blocks never exceeds max_blocks_count_.
-  // Each list entry can hold up to kBlockSizeBytes bytes.
-  std::unique_ptr<BufferBlock*[]> blocks_;
-
-  // Number of bytes in buffer.
-  size_t num_bytes_buffered_;
-
-  // Currently received data.
-  QuicIntervalSet<QuicStreamOffset> bytes_received_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
diff --git a/quic/core/quic_stream_sequencer_buffer_test.cc b/quic/core/quic_stream_sequencer_buffer_test.cc
deleted file mode 100644
index 52b3956..0000000
--- a/quic/core/quic_stream_sequencer_buffer_test.cc
+++ /dev/null
@@ -1,1139 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer_buffer.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-absl::string_view IovecToStringPiece(iovec iov) {
-  return absl::string_view(reinterpret_cast<const char*>(iov.iov_base),
-                           iov.iov_len);
-}
-
-char GetCharFromIOVecs(size_t offset, iovec iov[], size_t count) {
-  size_t start_offset = 0;
-  for (size_t i = 0; i < count; i++) {
-    if (iov[i].iov_len == 0) {
-      continue;
-    }
-    size_t end_offset = start_offset + iov[i].iov_len - 1;
-    if (offset >= start_offset && offset <= end_offset) {
-      const char* buf = reinterpret_cast<const char*>(iov[i].iov_base);
-      return buf[offset - start_offset];
-    }
-    start_offset += iov[i].iov_len;
-  }
-  QUIC_LOG(ERROR) << "Could not locate char at offset " << offset << " in "
-                  << count << " iovecs";
-  for (size_t i = 0; i < count; ++i) {
-    QUIC_LOG(ERROR) << "  iov[" << i << "].iov_len = " << iov[i].iov_len;
-  }
-  return '\0';
-}
-
-const size_t kMaxNumGapsAllowed = 2 * kMaxPacketGap;
-
-static const size_t kBlockSizeBytes =
-    QuicStreamSequencerBuffer::kBlockSizeBytes;
-using BufferBlock = QuicStreamSequencerBuffer::BufferBlock;
-
-namespace {
-
-class QuicStreamSequencerBufferTest : public QuicTest {
- public:
-  void SetUp() override { Initialize(); }
-
-  void ResetMaxCapacityBytes(size_t max_capacity_bytes) {
-    max_capacity_bytes_ = max_capacity_bytes;
-    Initialize();
-  }
-
- protected:
-  void Initialize() {
-    buffer_ =
-        std::make_unique<QuicStreamSequencerBuffer>((max_capacity_bytes_));
-    helper_ = std::make_unique<QuicStreamSequencerBufferPeer>((buffer_.get()));
-  }
-
-  // Use 8.5 here to make sure that the buffer has more than
-  // QuicStreamSequencerBuffer::kInitialBlockCount block and its end doesn't
-  // align with the end of a block in order to test all the offset calculation.
-  size_t max_capacity_bytes_ = 8.5 * kBlockSizeBytes;
-
-  std::unique_ptr<QuicStreamSequencerBuffer> buffer_;
-  std::unique_ptr<QuicStreamSequencerBufferPeer> helper_;
-  size_t written_ = 0;
-  std::string error_details_;
-};
-
-TEST_F(QuicStreamSequencerBufferTest, InitializeWithMaxRecvWindowSize) {
-  ResetMaxCapacityBytes(16 * 1024 * 1024);  // 16MB
-  EXPECT_EQ(2 * 1024u,                      // 16MB / 8KB = 2K
-            helper_->max_blocks_count());
-  EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
-  EXPECT_TRUE(helper_->CheckInitialState());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, InitializationWithDifferentSizes) {
-  const size_t kCapacity = 16 * QuicStreamSequencerBuffer::kBlockSizeBytes;
-  ResetMaxCapacityBytes(kCapacity);
-  EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
-  EXPECT_TRUE(helper_->CheckInitialState());
-
-  const size_t kCapacity1 = 32 * QuicStreamSequencerBuffer::kBlockSizeBytes;
-  ResetMaxCapacityBytes(kCapacity1);
-  EXPECT_EQ(kCapacity1, helper_->max_buffer_capacity());
-  EXPECT_TRUE(helper_->CheckInitialState());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ClearOnEmpty) {
-  buffer_->Clear();
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamData0length) {
-  QuicErrorCode error =
-      buffer_->OnStreamData(800, "", &written_, &error_details_);
-  EXPECT_THAT(error, IsError(QUIC_EMPTY_STREAM_FRAME_NO_FIN));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithinBlock) {
-  EXPECT_FALSE(helper_->IsBufferAllocated());
-  std::string source(1024, 'a');
-  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
-              IsQuicNoError());
-  BufferBlock* block_ptr = helper_->GetBlock(0);
-  for (size_t i = 0; i < source.size(); ++i) {
-    ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
-  }
-  EXPECT_EQ(2, helper_->IntervalSize());
-  EXPECT_EQ(0u, helper_->ReadableBytes());
-  EXPECT_EQ(1u, helper_->bytes_received().Size());
-  EXPECT_EQ(800u, helper_->bytes_received().begin()->min());
-  EXPECT_EQ(1824u, helper_->bytes_received().begin()->max());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-  EXPECT_TRUE(helper_->IsBufferAllocated());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, Move) {
-  EXPECT_FALSE(helper_->IsBufferAllocated());
-  std::string source(1024, 'a');
-  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
-              IsQuicNoError());
-  BufferBlock* block_ptr = helper_->GetBlock(0);
-  for (size_t i = 0; i < source.size(); ++i) {
-    ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
-  }
-
-  QuicStreamSequencerBuffer buffer2(std::move(*buffer_));
-  QuicStreamSequencerBufferPeer helper2(&buffer2);
-
-  EXPECT_FALSE(helper_->IsBufferAllocated());
-
-  EXPECT_EQ(2, helper2.IntervalSize());
-  EXPECT_EQ(0u, helper2.ReadableBytes());
-  EXPECT_EQ(1u, helper2.bytes_received().Size());
-  EXPECT_EQ(800u, helper2.bytes_received().begin()->min());
-  EXPECT_EQ(1824u, helper2.bytes_received().begin()->max());
-  EXPECT_TRUE(helper2.CheckBufferInvariants());
-  EXPECT_TRUE(helper2.IsBufferAllocated());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, DISABLED_OnStreamDataInvalidSource) {
-  // Pass in an invalid source, expects to return error.
-  absl::string_view source;
-  source = absl::string_view(nullptr, 1024);
-  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
-              IsError(QUIC_STREAM_SEQUENCER_INVALID_STATE));
-  EXPECT_EQ(0u, error_details_.find(absl::StrCat(
-                    "QuicStreamSequencerBuffer error: OnStreamData() "
-                    "dest == nullptr: ",
-                    false, " source == nullptr: ", true)));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithOverlap) {
-  std::string source(1024, 'a');
-  // Write something into [800, 1824)
-  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
-              IsQuicNoError());
-  // Try to write to [0, 1024) and [1024, 2048).
-  EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_THAT(buffer_->OnStreamData(1024, source, &written_, &error_details_),
-              IsQuicNoError());
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
-       OnStreamDataOverlapAndDuplicateCornerCases) {
-  std::string source(1024, 'a');
-  // Write something into [800, 1824)
-  buffer_->OnStreamData(800, source, &written_, &error_details_);
-  source = std::string(800, 'b');
-  std::string one_byte = "c";
-  // Write [1, 801).
-  EXPECT_THAT(buffer_->OnStreamData(1, source, &written_, &error_details_),
-              IsQuicNoError());
-  // Write [0, 800).
-  EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
-              IsQuicNoError());
-  // Write [1823, 1824).
-  EXPECT_THAT(buffer_->OnStreamData(1823, one_byte, &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(0u, written_);
-  // write one byte to [1824, 1825)
-  EXPECT_THAT(buffer_->OnStreamData(1824, one_byte, &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithoutOverlap) {
-  std::string source(1024, 'a');
-  // Write something into [800, 1824).
-  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
-              IsQuicNoError());
-  source = std::string(100, 'b');
-  // Write something into [kBlockSizeBytes * 2 - 20, kBlockSizeBytes * 2 + 80).
-  EXPECT_THAT(buffer_->OnStreamData(kBlockSizeBytes * 2 - 20, source, &written_,
-                                    &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(3, helper_->IntervalSize());
-  EXPECT_EQ(1024u + 100u, buffer_->BytesBuffered());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInLongStreamWithOverlap) {
-  // Assume a stream has already buffered almost 4GB.
-  uint64_t total_bytes_read = pow(2, 32) - 1;
-  helper_->set_total_bytes_read(total_bytes_read);
-  helper_->AddBytesReceived(0, total_bytes_read);
-
-  // Three new out of order frames arrive.
-  const size_t kBytesToWrite = 100;
-  std::string source(kBytesToWrite, 'a');
-  // Frame [2^32 + 500, 2^32 + 600).
-  QuicStreamOffset offset = pow(2, 32) + 500;
-  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(2, helper_->IntervalSize());
-
-  // Frame [2^32 + 700, 2^32 + 800).
-  offset = pow(2, 32) + 700;
-  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(3, helper_->IntervalSize());
-
-  // Another frame [2^32 + 300, 2^32 + 400).
-  offset = pow(2, 32) + 300;
-  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(4, helper_->IntervalSize());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEnd) {
-  // Write 50 bytes to the end.
-  const size_t kBytesToWrite = 50;
-  std::string source(kBytesToWrite, 'a');
-  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
-                                    &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(50u, buffer_->BytesBuffered());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEndCorner) {
-  // Write 1 byte to the end.
-  const size_t kBytesToWrite = 1;
-  std::string source(kBytesToWrite, 'a');
-  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
-                                    &written_, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(1u, buffer_->BytesBuffered());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, OnStreamDataBeyondCapacity) {
-  std::string source(60, 'a');
-  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - 50, source, &written_,
-                                    &error_details_),
-              IsError(QUIC_INTERNAL_ERROR));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-
-  source = "b";
-  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
-                                    &error_details_),
-              IsError(QUIC_INTERNAL_ERROR));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-
-  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ * 1000, source,
-                                    &written_, &error_details_),
-              IsError(QUIC_INTERNAL_ERROR));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-
-  // Disallow current_gap != gaps_.end()
-  EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-1), source,
-                                    &written_, &error_details_),
-              IsError(QUIC_INTERNAL_ERROR));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-
-  // Disallow offset + size overflow
-  source = "bbb";
-  EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-2), source,
-                                    &written_, &error_details_),
-              IsError(QUIC_INTERNAL_ERROR));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-  EXPECT_EQ(0u, buffer_->BytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, Readv100Bytes) {
-  std::string source(1024, 'a');
-  // Write something into [kBlockSizeBytes, kBlockSizeBytes + 1024).
-  buffer_->OnStreamData(kBlockSizeBytes, source, &written_, &error_details_);
-  EXPECT_FALSE(buffer_->HasBytesToRead());
-  source = std::string(100, 'b');
-  // Write something into [0, 100).
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  EXPECT_TRUE(buffer_->HasBytesToRead());
-  // Read into a iovec array with total capacity of 120 bytes.
-  char dest[120];
-  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
-              IsQuicNoError());
-  QUIC_LOG(ERROR) << error_details_;
-  EXPECT_EQ(100u, read);
-  EXPECT_EQ(100u, buffer_->BytesConsumed());
-  EXPECT_EQ(source, absl::string_view(dest, read));
-  // The first block should be released as its data has been read out.
-  EXPECT_EQ(nullptr, helper_->GetBlock(0));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossBlocks) {
-  std::string source(kBlockSizeBytes + 50, 'a');
-  // Write 1st block to full and extand 50 bytes to next block.
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  EXPECT_EQ(source.size(), helper_->ReadableBytes());
-  // Iteratively read 512 bytes from buffer_-> Overwrite dest[] each time.
-  char dest[512];
-  while (helper_->ReadableBytes()) {
-    std::fill(dest, dest + 512, 0);
-    iovec iovecs[2]{iovec{dest, 256}, iovec{dest + 256, 256}};
-    size_t read;
-    EXPECT_THAT(buffer_->Readv(iovecs, 2, &read, &error_details_),
-                IsQuicNoError());
-  }
-  // The last read only reads the rest 50 bytes in 2nd block.
-  EXPECT_EQ(std::string(50, 'a'), std::string(dest, 50));
-  EXPECT_EQ(0, dest[50]) << "Dest[50] shouln't be filled.";
-  EXPECT_EQ(source.size(), buffer_->BytesConsumed());
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ClearAfterRead) {
-  std::string source(kBlockSizeBytes + 50, 'a');
-  // Write 1st block to full with 'a'.
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  // Read first 512 bytes from buffer to make space at the beginning.
-  char dest[512]{0};
-  const iovec iov{dest, 512};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
-  // Clear() should make buffer empty while preserving BytesConsumed()
-  buffer_->Clear();
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
-       OnStreamDataAcrossLastBlockAndFillCapacity) {
-  std::string source(kBlockSizeBytes + 50, 'a');
-  // Write 1st block to full with 'a'.
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  // Read first 512 bytes from buffer to make space at the beginning.
-  char dest[512]{0};
-  const iovec iov{dest, 512};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
-  EXPECT_EQ(source.size(), written_);
-
-  // Write more than half block size of bytes in the last block with 'b', which
-  // will wrap to the beginning and reaches the full capacity.
-  source = std::string(0.5 * kBlockSizeBytes + 512, 'b');
-  EXPECT_THAT(buffer_->OnStreamData(2 * kBlockSizeBytes, source, &written_,
-                                    &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(source.size(), written_);
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
-       OnStreamDataAcrossLastBlockAndExceedCapacity) {
-  std::string source(kBlockSizeBytes + 50, 'a');
-  // Write 1st block to full.
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  // Read first 512 bytes from buffer to make space at the beginning.
-  char dest[512]{0};
-  const iovec iov{dest, 512};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
-
-  // Try to write from [max_capacity_bytes_ - 0.5 * kBlockSizeBytes,
-  // max_capacity_bytes_ +  512 + 1). But last bytes exceeds current capacity.
-  source = std::string(0.5 * kBlockSizeBytes + 512 + 1, 'b');
-  EXPECT_THAT(buffer_->OnStreamData(8 * kBlockSizeBytes, source, &written_,
-                                    &error_details_),
-              IsError(QUIC_INTERNAL_ERROR));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossLastBlock) {
-  // Write to full capacity and read out 512 bytes at beginning and continue
-  // appending 256 bytes.
-  std::string source(max_capacity_bytes_, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[512]{0};
-  const iovec iov{dest, 512};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
-  source = std::string(256, 'b');
-  buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
-                        &error_details_);
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-
-  // Read all data out.
-  std::unique_ptr<char[]> dest1{new char[max_capacity_bytes_]};
-  dest1[0] = 0;
-  const iovec iov1{dest1.get(), max_capacity_bytes_};
-  EXPECT_THAT(buffer_->Readv(&iov1, 1, &read, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(max_capacity_bytes_ - 512 + 256, read);
-  EXPECT_EQ(max_capacity_bytes_ + 256, buffer_->BytesConsumed());
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReadvEmpty) {
-  char dest[512]{0};
-  iovec iov{dest, 512};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
-  EXPECT_EQ(0u, read);
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsEmpty) {
-  iovec iovs[2];
-  int iov_count = buffer_->GetReadableRegions(iovs, 2);
-  EXPECT_EQ(0, iov_count);
-  EXPECT_EQ(nullptr, iovs[iov_count].iov_base);
-  EXPECT_EQ(0u, iovs[iov_count].iov_len);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, ReleaseWholeBuffer) {
-  // Tests that buffer is not deallocated unless ReleaseWholeBuffer() is called.
-  std::string source(100, 'b');
-  // Write something into [0, 100).
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  EXPECT_TRUE(buffer_->HasBytesToRead());
-  char dest[120];
-  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
-  size_t read;
-  EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
-              IsQuicNoError());
-  EXPECT_EQ(100u, read);
-  EXPECT_EQ(100u, buffer_->BytesConsumed());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-  EXPECT_TRUE(helper_->IsBufferAllocated());
-  buffer_->ReleaseWholeBuffer();
-  EXPECT_FALSE(helper_->IsBufferAllocated());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsBlockedByGap) {
-  // Write into [1, 1024).
-  std::string source(1023, 'a');
-  buffer_->OnStreamData(1, source, &written_, &error_details_);
-  // Try to get readable regions, but none is there.
-  iovec iovs[2];
-  int iov_count = buffer_->GetReadableRegions(iovs, 2);
-  EXPECT_EQ(0, iov_count);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsTillEndOfBlock) {
-  // Write first block to full with [0, 256) 'a' and the rest 'b' then read out
-  // [0, 256)
-  std::string source(kBlockSizeBytes, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[256];
-  helper_->Read(dest, 256);
-  // Get readable region from [256, 1024)
-  iovec iovs[2];
-  int iov_count = buffer_->GetReadableRegions(iovs, 2);
-  EXPECT_EQ(1, iov_count);
-  EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'),
-            IovecToStringPiece(iovs[0]));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsWithinOneBlock) {
-  // Write into [0, 1024) and then read out [0, 256)
-  std::string source(1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[256];
-  helper_->Read(dest, 256);
-  // Get readable region from [256, 1024)
-  iovec iovs[2];
-  int iov_count = buffer_->GetReadableRegions(iovs, 2);
-  EXPECT_EQ(1, iov_count);
-  EXPECT_EQ(std::string(1024 - 256, 'a'), IovecToStringPiece(iovs[0]));
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
-       GetReadableRegionsAcrossBlockWithLongIOV) {
-  // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
-  std::string source(2 * kBlockSizeBytes + 1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[1024];
-  helper_->Read(dest, 1024);
-
-  iovec iovs[4];
-  int iov_count = buffer_->GetReadableRegions(iovs, 4);
-  EXPECT_EQ(3, iov_count);
-  EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
-  EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
-  EXPECT_EQ(1024u, iovs[2].iov_len);
-}
-
-TEST_F(QuicStreamSequencerBufferTest,
-       GetReadableRegionsWithMultipleIOVsAcrossEnd) {
-  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
-  // and then append 1024 + 512 bytes.
-  std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[1024];
-  helper_->Read(dest, 1024);
-  // Write across the end.
-  source = std::string(1024 + 512, 'b');
-  buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
-                        &error_details_);
-  // Use short iovec's.
-  iovec iovs[2];
-  int iov_count = buffer_->GetReadableRegions(iovs, 2);
-  EXPECT_EQ(2, iov_count);
-  EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
-  EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
-  // Use long iovec's and wrap the end of buffer.
-  iovec iovs1[11];
-  EXPECT_EQ(10, buffer_->GetReadableRegions(iovs1, 11));
-  EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[8].iov_len);
-  EXPECT_EQ(512u, iovs1[9].iov_len);
-  EXPECT_EQ(std::string(512, 'b'), IovecToStringPiece(iovs1[9]));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionEmpty) {
-  iovec iov;
-  EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
-  EXPECT_EQ(nullptr, iov.iov_base);
-  EXPECT_EQ(0u, iov.iov_len);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionBeforeGap) {
-  // Write into [1, 1024).
-  std::string source(1023, 'a');
-  buffer_->OnStreamData(1, source, &written_, &error_details_);
-  // GetReadableRegion should return false because range  [0,1) hasn't been
-  // filled yet.
-  iovec iov;
-  EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillEndOfBlock) {
-  // Write into [0, kBlockSizeBytes + 1) and then read out [0, 256)
-  std::string source(kBlockSizeBytes + 1, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[256];
-  helper_->Read(dest, 256);
-  // Get readable region from [256, 1024)
-  iovec iov;
-  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
-  EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'), IovecToStringPiece(iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillGap) {
-  // Write into [0, kBlockSizeBytes - 1) and then read out [0, 256)
-  std::string source(kBlockSizeBytes - 1, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[256];
-  helper_->Read(dest, 256);
-  // Get readable region from [256, 1023)
-  iovec iov;
-  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
-  EXPECT_EQ(std::string(kBlockSizeBytes - 1 - 256, 'a'),
-            IovecToStringPiece(iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekEmptyBuffer) {
-  iovec iov;
-  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(1, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(100, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekSingleBlock) {
-  std::string source(kBlockSizeBytes, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-
-  iovec iov;
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source, IovecToStringPiece(iov));
-
-  // Peeking again gives the same result.
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source, IovecToStringPiece(iov));
-
-  // Peek at a different offset.
-  EXPECT_TRUE(buffer_->PeekRegion(100, &iov));
-  EXPECT_EQ(absl::string_view(source).substr(100), IovecToStringPiece(iov));
-
-  // Peeking at or after FirstMissingByte() returns false.
-  EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes + 1, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekTwoWritesInSingleBlock) {
-  const size_t length1 = 1024;
-  std::string source1(length1, 'a');
-  buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
-  iovec iov;
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source1, IovecToStringPiece(iov));
-
-  // The second frame goes into the same block.
-  const size_t length2 = 800;
-  std::string source2(length2, 'b');
-  buffer_->OnStreamData(length1, source2, &written_, &error_details_);
-
-  EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
-  EXPECT_EQ(source2, IovecToStringPiece(iov));
-
-  // Peek with an offset inside the first write.
-  const QuicStreamOffset offset1 = 500;
-  EXPECT_TRUE(buffer_->PeekRegion(offset1, &iov));
-  EXPECT_EQ(absl::string_view(source1).substr(offset1),
-            IovecToStringPiece(iov).substr(0, length1 - offset1));
-  EXPECT_EQ(absl::string_view(source2),
-            IovecToStringPiece(iov).substr(length1 - offset1));
-
-  // Peek with an offset inside the second write.
-  const QuicStreamOffset offset2 = 1500;
-  EXPECT_TRUE(buffer_->PeekRegion(offset2, &iov));
-  EXPECT_EQ(absl::string_view(source2).substr(offset2 - length1),
-            IovecToStringPiece(iov));
-
-  // Peeking at or after FirstMissingByte() returns false.
-  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekBufferWithMultipleBlocks) {
-  const size_t length1 = 1024;
-  std::string source1(length1, 'a');
-  buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
-  iovec iov;
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source1, IovecToStringPiece(iov));
-
-  const size_t length2 = kBlockSizeBytes + 2;
-  std::string source2(length2, 'b');
-  buffer_->OnStreamData(length1, source2, &written_, &error_details_);
-
-  // Peek with offset 0 returns the entire block.
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(kBlockSizeBytes, iov.iov_len);
-  EXPECT_EQ(source1, IovecToStringPiece(iov).substr(0, length1));
-  EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
-            IovecToStringPiece(iov).substr(length1));
-
-  EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
-  EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
-            IovecToStringPiece(iov));
-
-  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
-  EXPECT_EQ(absl::string_view(source2).substr(kBlockSizeBytes - length1),
-            IovecToStringPiece(iov));
-
-  // Peeking at or after FirstMissingByte() returns false.
-  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekAfterConsumed) {
-  std::string source1(kBlockSizeBytes, 'a');
-  buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
-  iovec iov;
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source1, IovecToStringPiece(iov));
-
-  // Consume some data.
-  EXPECT_TRUE(buffer_->MarkConsumed(1024));
-
-  // Peeking into consumed data fails.
-  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
-
-  EXPECT_TRUE(buffer_->PeekRegion(1024, &iov));
-  EXPECT_EQ(absl::string_view(source1).substr(1024), IovecToStringPiece(iov));
-
-  EXPECT_TRUE(buffer_->PeekRegion(1500, &iov));
-  EXPECT_EQ(absl::string_view(source1).substr(1500), IovecToStringPiece(iov));
-
-  // Consume rest of block.
-  EXPECT_TRUE(buffer_->MarkConsumed(kBlockSizeBytes - 1024));
-
-  // Read new data.
-  std::string source2(300, 'b');
-  buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
-
-  // Peek into new data.
-  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
-  EXPECT_EQ(source2, IovecToStringPiece(iov));
-
-  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes + 128, &iov));
-  EXPECT_EQ(absl::string_view(source2).substr(128), IovecToStringPiece(iov));
-
-  // Peeking into consumed data still fails.
-  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(1024, &iov));
-  EXPECT_FALSE(buffer_->PeekRegion(1500, &iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, PeekContinously) {
-  std::string source1(kBlockSizeBytes, 'a');
-  buffer_->OnStreamData(0, source1, &written_, &error_details_);
-
-  iovec iov;
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source1, IovecToStringPiece(iov));
-
-  std::string source2(kBlockSizeBytes, 'b');
-  buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
-
-  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
-  EXPECT_EQ(source2, IovecToStringPiece(iov));
-
-  // First block is still there.
-  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
-  EXPECT_EQ(source1, IovecToStringPiece(iov));
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedInOneBlock) {
-  // Write into [0, 1024) and then read out [0, 256)
-  std::string source(1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[256];
-  helper_->Read(dest, 256);
-
-  EXPECT_TRUE(buffer_->MarkConsumed(512));
-  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
-  EXPECT_EQ(256u, helper_->ReadableBytes());
-  buffer_->MarkConsumed(256);
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedNotEnoughBytes) {
-  // Write into [0, 1024) and then read out [0, 256)
-  std::string source(1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[256];
-  helper_->Read(dest, 256);
-
-  // Consume 1st 512 bytes
-  EXPECT_TRUE(buffer_->MarkConsumed(512));
-  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
-  EXPECT_EQ(256u, helper_->ReadableBytes());
-  // Try to consume one bytes more than available. Should return false.
-  EXPECT_FALSE(buffer_->MarkConsumed(257));
-  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
-  iovec iov;
-  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossBlock) {
-  // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
-  std::string source(2 * kBlockSizeBytes + 1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[1024];
-  helper_->Read(dest, 1024);
-
-  buffer_->MarkConsumed(2 * kBlockSizeBytes);
-  EXPECT_EQ(source.size(), buffer_->BytesConsumed());
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossEnd) {
-  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
-  // and then append 1024 + 512 bytes.
-  std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[1024];
-  helper_->Read(dest, 1024);
-  source = std::string(1024 + 512, 'b');
-  buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
-                        &error_details_);
-  EXPECT_EQ(1024u, buffer_->BytesConsumed());
-
-  // Consume to the end of 8th block.
-  buffer_->MarkConsumed(8 * kBlockSizeBytes - 1024);
-  EXPECT_EQ(8 * kBlockSizeBytes, buffer_->BytesConsumed());
-  // Consume across the physical end of buffer
-  buffer_->MarkConsumed(0.5 * kBlockSizeBytes + 500);
-  EXPECT_EQ(max_capacity_bytes_ + 500, buffer_->BytesConsumed());
-  EXPECT_EQ(12u, helper_->ReadableBytes());
-  // Consume to the logical end of buffer
-  buffer_->MarkConsumed(12);
-  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, FlushBufferedFrames) {
-  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024).
-  std::string source(max_capacity_bytes_ - 1024, 'a');
-  buffer_->OnStreamData(0, source, &written_, &error_details_);
-  char dest[1024];
-  helper_->Read(dest, 1024);
-  EXPECT_EQ(1024u, buffer_->BytesConsumed());
-  // Write [1024, 512) to the physical beginning.
-  source = std::string(512, 'b');
-  buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
-                        &error_details_);
-  EXPECT_EQ(512u, written_);
-  EXPECT_EQ(max_capacity_bytes_ - 1024 + 512, buffer_->FlushBufferedFrames());
-  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
-  EXPECT_TRUE(buffer_->Empty());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-  // Clear buffer at this point should still preserve BytesConsumed().
-  buffer_->Clear();
-  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
-  EXPECT_TRUE(helper_->CheckBufferInvariants());
-}
-
-TEST_F(QuicStreamSequencerBufferTest, TooManyGaps) {
-  // Make sure max capacity is large enough that it is possible to have more
-  // than |kMaxNumGapsAllowed| number of gaps.
-  max_capacity_bytes_ = 3 * kBlockSizeBytes;
-  // Feed buffer with 1-byte discontiguous frames. e.g. [1,2), [3,4), [5,6)...
-  for (QuicStreamOffset begin = 1; begin <= max_capacity_bytes_; begin += 2) {
-    QuicErrorCode rs =
-        buffer_->OnStreamData(begin, "a", &written_, &error_details_);
-
-    QuicStreamOffset last_straw = 2 * kMaxNumGapsAllowed - 1;
-    if (begin == last_straw) {
-      EXPECT_THAT(rs, IsError(QUIC_TOO_MANY_STREAM_DATA_INTERVALS));
-      EXPECT_EQ("Too many data intervals received for this stream.",
-                error_details_);
-      break;
-    }
-  }
-}
-
-class QuicStreamSequencerBufferRandomIOTest
-    : public QuicStreamSequencerBufferTest {
- public:
-  using OffsetSizePair = std::pair<QuicStreamOffset, size_t>;
-
-  void SetUp() override {
-    // Test against a larger capacity then above tests. Also make sure the last
-    // block is partially available to use.
-    max_capacity_bytes_ = 8.25 * kBlockSizeBytes;
-    // Stream to be buffered should be larger than the capacity to test wrap
-    // around.
-    bytes_to_buffer_ = 2 * max_capacity_bytes_;
-    Initialize();
-
-    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
-    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
-    rng_.set_seed(seed);
-  }
-
-  // Create an out-of-order source stream with given size to populate
-  // shuffled_buf_.
-  void CreateSourceAndShuffle(size_t max_chunk_size_bytes) {
-    max_chunk_size_bytes_ = max_chunk_size_bytes;
-    std::unique_ptr<OffsetSizePair[]> chopped_stream(
-        new OffsetSizePair[bytes_to_buffer_]);
-
-    // Split stream into small chunks with random length. chopped_stream will be
-    // populated with segmented stream chunks.
-    size_t start_chopping_offset = 0;
-    size_t iterations = 0;
-    while (start_chopping_offset < bytes_to_buffer_) {
-      size_t max_chunk = std::min<size_t>(
-          max_chunk_size_bytes_, bytes_to_buffer_ - start_chopping_offset);
-      size_t chunk_size = rng_.RandUint64() % max_chunk + 1;
-      chopped_stream[iterations] =
-          OffsetSizePair(start_chopping_offset, chunk_size);
-      start_chopping_offset += chunk_size;
-      ++iterations;
-    }
-    QUICHE_DCHECK(start_chopping_offset == bytes_to_buffer_);
-    size_t chunk_num = iterations;
-
-    // Randomly change the sequence of in-ordered OffsetSizePairs to make a
-    // out-of-order array of OffsetSizePairs.
-    for (int i = chunk_num - 1; i >= 0; --i) {
-      size_t random_idx = rng_.RandUint64() % (i + 1);
-      QUIC_DVLOG(1) << "chunk offset " << chopped_stream[random_idx].first
-                    << " size " << chopped_stream[random_idx].second;
-      shuffled_buf_.push_front(chopped_stream[random_idx]);
-      chopped_stream[random_idx] = chopped_stream[i];
-    }
-  }
-
-  // Write the currently first chunk of data in the out-of-order stream into
-  // QuicStreamSequencerBuffer. If current chuck cannot be written into buffer
-  // because it goes beyond current capacity, move it to the end of
-  // shuffled_buf_ and write it later.
-  void WriteNextChunkToBuffer() {
-    OffsetSizePair& chunk = shuffled_buf_.front();
-    QuicStreamOffset offset = chunk.first;
-    const size_t num_to_write = chunk.second;
-    std::unique_ptr<char[]> write_buf{new char[max_chunk_size_bytes_]};
-    for (size_t i = 0; i < num_to_write; ++i) {
-      write_buf[i] = (offset + i) % 256;
-    }
-    absl::string_view string_piece_w(write_buf.get(), num_to_write);
-    auto result = buffer_->OnStreamData(offset, string_piece_w, &written_,
-                                        &error_details_);
-    if (result == QUIC_NO_ERROR) {
-      shuffled_buf_.pop_front();
-      total_bytes_written_ += num_to_write;
-    } else {
-      // This chunk offset exceeds window size.
-      shuffled_buf_.push_back(chunk);
-      shuffled_buf_.pop_front();
-    }
-    QUIC_DVLOG(1) << " write at offset: " << offset
-                  << " len to write: " << num_to_write
-                  << " write result: " << result
-                  << " left over: " << shuffled_buf_.size();
-  }
-
- protected:
-  std::list<OffsetSizePair> shuffled_buf_;
-  size_t max_chunk_size_bytes_;
-  QuicStreamOffset bytes_to_buffer_;
-  size_t total_bytes_written_ = 0;
-  size_t total_bytes_read_ = 0;
-  SimpleRandom rng_;
-};
-
-TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndReadv) {
-  // Set kMaxReadSize larger than kBlockSizeBytes to test both small and large
-  // read.
-  const size_t kMaxReadSize = kBlockSizeBytes * 2;
-  // kNumReads is larger than 1 to test how multiple read destinations work.
-  const size_t kNumReads = 2;
-  // Since write and read operation have equal possibility to be called. Bytes
-  // to be written into and read out of should roughly the same.
-  const size_t kMaxWriteSize = kNumReads * kMaxReadSize;
-  size_t iterations = 0;
-
-  CreateSourceAndShuffle(kMaxWriteSize);
-
-  while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
-         iterations <= 2 * bytes_to_buffer_) {
-    uint8_t next_action =
-        shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
-    QUIC_DVLOG(1) << "iteration: " << iterations;
-    switch (next_action) {
-      case 0: {  // write
-        WriteNextChunkToBuffer();
-        ASSERT_TRUE(helper_->CheckBufferInvariants());
-        break;
-      }
-      case 1: {  // readv
-        std::unique_ptr<char[][kMaxReadSize]> read_buf{
-            new char[kNumReads][kMaxReadSize]};
-        iovec dest_iov[kNumReads];
-        size_t num_to_read = 0;
-        for (size_t i = 0; i < kNumReads; ++i) {
-          dest_iov[i].iov_base =
-              reinterpret_cast<void*>(const_cast<char*>(read_buf[i]));
-          dest_iov[i].iov_len = rng_.RandUint64() % kMaxReadSize;
-          num_to_read += dest_iov[i].iov_len;
-        }
-        size_t actually_read;
-        EXPECT_THAT(buffer_->Readv(dest_iov, kNumReads, &actually_read,
-                                   &error_details_),
-                    IsQuicNoError());
-        ASSERT_LE(actually_read, num_to_read);
-        QUIC_DVLOG(1) << " read from offset: " << total_bytes_read_
-                      << " size: " << num_to_read
-                      << " actual read: " << actually_read;
-        for (size_t i = 0; i < actually_read; ++i) {
-          char ch = (i + total_bytes_read_) % 256;
-          ASSERT_EQ(ch, GetCharFromIOVecs(i, dest_iov, kNumReads))
-              << " at iteration " << iterations;
-        }
-        total_bytes_read_ += actually_read;
-        ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
-        ASSERT_TRUE(helper_->CheckBufferInvariants());
-        break;
-      }
-    }
-    ++iterations;
-    ASSERT_LE(total_bytes_read_, total_bytes_written_);
-  }
-  EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
-  EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
-      << "iterations: " << iterations;
-  EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
-}
-
-TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndConsumeInPlace) {
-  // The value 4 is chosen such that the max write size is no larger than the
-  // maximum buffer capacity.
-  const size_t kMaxNumReads = 4;
-  // Adjust write amount be roughly equal to that GetReadableRegions() can get.
-  const size_t kMaxWriteSize = kMaxNumReads * kBlockSizeBytes;
-  ASSERT_LE(kMaxWriteSize, max_capacity_bytes_);
-  size_t iterations = 0;
-
-  CreateSourceAndShuffle(kMaxWriteSize);
-
-  while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
-         iterations <= 2 * bytes_to_buffer_) {
-    uint8_t next_action =
-        shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
-    QUIC_DVLOG(1) << "iteration: " << iterations;
-    switch (next_action) {
-      case 0: {  // write
-        WriteNextChunkToBuffer();
-        ASSERT_TRUE(helper_->CheckBufferInvariants());
-        break;
-      }
-      case 1: {  // GetReadableRegions and then MarkConsumed
-        size_t num_read = rng_.RandUint64() % kMaxNumReads + 1;
-        iovec dest_iov[kMaxNumReads];
-        ASSERT_TRUE(helper_->CheckBufferInvariants());
-        size_t actually_num_read =
-            buffer_->GetReadableRegions(dest_iov, num_read);
-        ASSERT_LE(actually_num_read, num_read);
-        size_t avail_bytes = 0;
-        for (size_t i = 0; i < actually_num_read; ++i) {
-          avail_bytes += dest_iov[i].iov_len;
-        }
-        // process random number of bytes (check the value of each byte).
-        size_t bytes_to_process = rng_.RandUint64() % (avail_bytes + 1);
-        size_t bytes_processed = 0;
-        for (size_t i = 0; i < actually_num_read; ++i) {
-          size_t bytes_in_block = std::min<size_t>(
-              bytes_to_process - bytes_processed, dest_iov[i].iov_len);
-          if (bytes_in_block == 0) {
-            break;
-          }
-          for (size_t j = 0; j < bytes_in_block; ++j) {
-            ASSERT_LE(bytes_processed, bytes_to_process);
-            char char_expected =
-                (buffer_->BytesConsumed() + bytes_processed) % 256;
-            ASSERT_EQ(char_expected,
-                      reinterpret_cast<const char*>(dest_iov[i].iov_base)[j])
-                << " at iteration " << iterations;
-            ++bytes_processed;
-          }
-        }
-
-        buffer_->MarkConsumed(bytes_processed);
-
-        QUIC_DVLOG(1) << "iteration " << iterations << ": try to get "
-                      << num_read << " readable regions, actually get "
-                      << actually_num_read
-                      << " from offset: " << total_bytes_read_
-                      << "\nprocesse bytes: " << bytes_processed;
-        total_bytes_read_ += bytes_processed;
-        ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
-        ASSERT_TRUE(helper_->CheckBufferInvariants());
-        break;
-      }
-    }
-    ++iterations;
-    ASSERT_LE(total_bytes_read_, total_bytes_written_);
-  }
-  EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
-  EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
-      << "iterations: " << iterations;
-  EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
-}
-
-TEST_F(QuicStreamSequencerBufferTest, GrowBlockSizeOnDemand) {
-  max_capacity_bytes_ = 1024 * kBlockSizeBytes;
-  std::string source_of_one_block(kBlockSizeBytes, 'a');
-  Initialize();
-
-  ASSERT_EQ(helper_->current_blocks_count(), 0u);
-
-  // A minimum of 8 blocks are allocated
-  buffer_->OnStreamData(0, source_of_one_block, &written_, &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 8u);
-
-  // Number of blocks doesn't grow if the data is within the capacity.
-  buffer_->OnStreamData(kBlockSizeBytes * 7, source_of_one_block, &written_,
-                        &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 8u);
-
-  // Number of blocks grows by a factor of 4 normally.
-  buffer_->OnStreamData(kBlockSizeBytes * 8, "a", &written_, &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 32u);
-
-  // Number of blocks grow to the demanded size of 140 instead of 128 since
-  // that's not enough.
-  buffer_->OnStreamData(kBlockSizeBytes * 139, source_of_one_block, &written_,
-                        &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 140u);
-
-  // Number of blocks grows by a factor of 4 normally.
-  buffer_->OnStreamData(kBlockSizeBytes * 140, source_of_one_block, &written_,
-                        &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 560u);
-
-  // max_capacity_bytes is reached and number of blocks is capped.
-  buffer_->OnStreamData(kBlockSizeBytes * 560, source_of_one_block, &written_,
-                        &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 1024u);
-
-  // max_capacity_bytes is reached and number of blocks is capped.
-  buffer_->OnStreamData(kBlockSizeBytes * 1025, source_of_one_block, &written_,
-                        &error_details_);
-  ASSERT_EQ(helper_->current_blocks_count(), 1024u);
-}
-
-}  // anonymous namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/core/quic_stream_sequencer_test.cc b/quic/core/quic_stream_sequencer_test.cc
deleted file mode 100644
index 0a15e96..0000000
--- a/quic/core/quic_stream_sequencer_test.cc
+++ /dev/null
@@ -1,781 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream_sequencer.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::InSequence;
-
-namespace quic {
-namespace test {
-
-class MockStream : public QuicStreamSequencer::StreamInterface {
- public:
-  MOCK_METHOD(void, OnFinRead, (), (override));
-  MOCK_METHOD(void, OnDataAvailable, (), (override));
-  MOCK_METHOD(void,
-              OnUnrecoverableError,
-              (QuicErrorCode error, const std::string& details),
-              (override));
-  MOCK_METHOD(void,
-              OnUnrecoverableError,
-              (QuicErrorCode error,
-               QuicIetfTransportErrorCodes ietf_error,
-               const std::string& details),
-              (override));
-  MOCK_METHOD(void, ResetWithError, (QuicResetStreamError error), (override));
-  MOCK_METHOD(void, AddBytesConsumed, (QuicByteCount bytes), (override));
-
-  QuicStreamId id() const override { return 1; }
-  ParsedQuicVersion version() const override {
-    return CurrentSupportedVersions()[0];
-  }
-};
-
-namespace {
-
-static const char kPayload[] =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-class QuicStreamSequencerTest : public QuicTest {
- public:
-  void ConsumeData(size_t num_bytes) {
-    char buffer[1024];
-    ASSERT_GT(ABSL_ARRAYSIZE(buffer), num_bytes);
-    struct iovec iov;
-    iov.iov_base = buffer;
-    iov.iov_len = num_bytes;
-    ASSERT_EQ(num_bytes, sequencer_->Readv(&iov, 1));
-  }
-
- protected:
-  QuicStreamSequencerTest()
-      : stream_(), sequencer_(new QuicStreamSequencer(&stream_)) {}
-
-  // Verify that the data in first region match with the expected[0].
-  bool VerifyReadableRegion(const std::vector<std::string>& expected) {
-    return VerifyReadableRegion(*sequencer_, expected);
-  }
-
-  // Verify that the data in each of currently readable regions match with each
-  // item given in |expected|.
-  bool VerifyReadableRegions(const std::vector<std::string>& expected) {
-    return VerifyReadableRegions(*sequencer_, expected);
-  }
-
-  bool VerifyIovecs(iovec* iovecs,
-                    size_t num_iovecs,
-                    const std::vector<std::string>& expected) {
-    return VerifyIovecs(*sequencer_, iovecs, num_iovecs, expected);
-  }
-
-  bool VerifyReadableRegion(const QuicStreamSequencer& sequencer,
-                            const std::vector<std::string>& expected) {
-    iovec iovecs[1];
-    if (sequencer.GetReadableRegions(iovecs, 1)) {
-      return (VerifyIovecs(sequencer, iovecs, 1,
-                           std::vector<std::string>{expected[0]}));
-    }
-    return false;
-  }
-
-  // Verify that the data in each of currently readable regions match with each
-  // item given in |expected|.
-  bool VerifyReadableRegions(const QuicStreamSequencer& sequencer,
-                             const std::vector<std::string>& expected) {
-    iovec iovecs[5];
-    size_t num_iovecs =
-        sequencer.GetReadableRegions(iovecs, ABSL_ARRAYSIZE(iovecs));
-    return VerifyReadableRegion(sequencer, expected) &&
-           VerifyIovecs(sequencer, iovecs, num_iovecs, expected);
-  }
-
-  bool VerifyIovecs(const QuicStreamSequencer& /*sequencer*/,
-                    iovec* iovecs,
-                    size_t num_iovecs,
-                    const std::vector<std::string>& expected) {
-    int start_position = 0;
-    for (size_t i = 0; i < num_iovecs; ++i) {
-      if (!VerifyIovec(iovecs[i],
-                       expected[0].substr(start_position, iovecs[i].iov_len))) {
-        return false;
-      }
-      start_position += iovecs[i].iov_len;
-    }
-    return true;
-  }
-
-  bool VerifyIovec(const iovec& iovec, absl::string_view expected) {
-    if (iovec.iov_len != expected.length()) {
-      QUIC_LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs "
-                      << expected.length();
-      return false;
-    }
-    if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
-      QUIC_LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base)
-                      << " vs " << expected;
-      return false;
-    }
-    return true;
-  }
-
-  void OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
-    QuicStreamFrame frame;
-    frame.stream_id = 1;
-    frame.offset = byte_offset;
-    frame.data_buffer = data;
-    frame.data_length = strlen(data);
-    frame.fin = true;
-    sequencer_->OnStreamFrame(frame);
-  }
-
-  void OnFrame(QuicStreamOffset byte_offset, const char* data) {
-    QuicStreamFrame frame;
-    frame.stream_id = 1;
-    frame.offset = byte_offset;
-    frame.data_buffer = data;
-    frame.data_length = strlen(data);
-    frame.fin = false;
-    sequencer_->OnStreamFrame(frame);
-  }
-
-  size_t NumBufferedBytes() {
-    return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get());
-  }
-
-  testing::StrictMock<MockStream> stream_;
-  std::unique_ptr<QuicStreamSequencer> sequencer_;
-};
-
-// TODO(rch): reorder these tests so they build on each other.
-
-TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-
-  OnFrame(0, "abc");
-
-  EXPECT_EQ(0u, NumBufferedBytes());
-  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-  // Ignore this - it matches a past packet number and we should not see it
-  // again.
-  OnFrame(0, "def");
-  EXPECT_EQ(0u, NumBufferedBytes());
-}
-
-TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-
-  OnFrame(0, "abc");
-  EXPECT_EQ(3u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-
-  // Ignore this - it matches a buffered frame.
-  // Right now there's no checking that the payload is consistent.
-  OnFrame(0, "def");
-  EXPECT_EQ(3u, NumBufferedBytes());
-}
-
-TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-
-  OnFrame(0, "abc");
-  EXPECT_EQ(0u, NumBufferedBytes());
-  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
-  sequencer_->SetBlockedUntilFlush();
-
-  OnFrame(0, "abc");
-  EXPECT_EQ(3u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-  sequencer_->SetUnblocked();
-  EXPECT_EQ(0u, NumBufferedBytes());
-  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-  EXPECT_FALSE(sequencer_->IsClosed());
-  OnFinFrame(3, "def");
-  EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
-  sequencer_->SetBlockedUntilFlush();
-
-  OnFinFrame(0, "abc");
-  EXPECT_EQ(3u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-  EXPECT_FALSE(sequencer_->IsClosed());
-  sequencer_->SetUnblocked();
-  EXPECT_TRUE(sequencer_->IsClosed());
-  EXPECT_EQ(0u, NumBufferedBytes());
-  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, EmptyFrame) {
-  if (!stream_.version().HasIetfQuicFrames()) {
-    EXPECT_CALL(stream_,
-                OnUnrecoverableError(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _));
-  }
-  OnFrame(0, "");
-  EXPECT_EQ(0u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-  OnFinFrame(0, "");
-  EXPECT_EQ(0u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
-  EXPECT_CALL(stream_, AddBytesConsumed(2));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(2);
-  }));
-
-  OnFrame(0, "abc");
-  EXPECT_EQ(1u, NumBufferedBytes());
-  EXPECT_EQ(2u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-
-  OnFrame(0, "abc");
-  EXPECT_EQ(3u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
-  OnFrame(3, "abc");
-  EXPECT_EQ(3u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-}
-
-TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
-  // Buffer the first
-  OnFrame(6, "ghi");
-  EXPECT_EQ(3u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
-  // Buffer the second
-  OnFrame(3, "def");
-  EXPECT_EQ(6u, NumBufferedBytes());
-  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
-
-  EXPECT_CALL(stream_, AddBytesConsumed(9));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(9);
-  }));
-
-  // Now process all of them at once.
-  OnFrame(0, "abc");
-  EXPECT_EQ(9u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-
-  EXPECT_EQ(0u, NumBufferedBytes());
-}
-
-TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
-  InSequence s;
-
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  OnFinFrame(0, "abc");
-
-  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-}
-
-TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
-  OnFinFrame(6, "");
-  EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
-  OnFrame(3, "def");
-  EXPECT_CALL(stream_, AddBytesConsumed(6));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(6);
-  }));
-  EXPECT_FALSE(sequencer_->IsClosed());
-  OnFrame(0, "abc");
-  EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
-  OnFinFrame(3, "");
-  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
-    ConsumeData(3);
-  }));
-  EXPECT_FALSE(sequencer_->IsClosed());
-  OnFrame(0, "abc");
-  EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
-  char buffer[3];
-
-  OnFinFrame(3, "");
-  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
-  EXPECT_FALSE(sequencer_->IsClosed());
-
-  EXPECT_CALL(stream_, OnDataAvailable());
-  OnFrame(0, "abc");
-
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  iovec iov = {&buffer[0], 3};
-  int bytes_read = sequencer_->Readv(&iov, 1);
-  EXPECT_EQ(3, bytes_read);
-  EXPECT_TRUE(sequencer_->IsClosed());
-}
-
-TEST_F(QuicStreamSequencerTest, MultipleOffsets) {
-  OnFinFrame(3, "");
-  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
-
-  EXPECT_CALL(stream_, OnUnrecoverableError(
-                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
-                           "Stream 1 received new final offset: 1, which is "
-                           "different from close offset: 3"));
-  OnFinFrame(1, "");
-}
-
-class QuicSequencerRandomTest : public QuicStreamSequencerTest {
- public:
-  using Frame = std::pair<int, std::string>;
-  using FrameList = std::vector<Frame>;
-
-  void CreateFrames() {
-    int payload_size = ABSL_ARRAYSIZE(kPayload) - 1;
-    int remaining_payload = payload_size;
-    while (remaining_payload != 0) {
-      int size = std::min(OneToN(6), remaining_payload);
-      int index = payload_size - remaining_payload;
-      list_.push_back(
-          std::make_pair(index, std::string(kPayload + index, size)));
-      remaining_payload -= size;
-    }
-  }
-
-  QuicSequencerRandomTest() {
-    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
-    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
-    random_.set_seed(seed);
-
-    CreateFrames();
-  }
-
-  int OneToN(int n) { return random_.RandUint64() % n + 1; }
-
-  void ReadAvailableData() {
-    // Read all available data
-    char output[ABSL_ARRAYSIZE(kPayload) + 1];
-    iovec iov;
-    iov.iov_base = output;
-    iov.iov_len = ABSL_ARRAYSIZE(output);
-    int bytes_read = sequencer_->Readv(&iov, 1);
-    EXPECT_NE(0, bytes_read);
-    output_.append(output, bytes_read);
-  }
-
-  std::string output_;
-  // Data which peek at using GetReadableRegion if we back up.
-  std::string peeked_;
-  SimpleRandom random_;
-  FrameList list_;
-};
-
-// All frames are processed as soon as we have sequential data.
-// Infinite buffering, so all frames are acked right away.
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
-  EXPECT_CALL(stream_, OnDataAvailable())
-      .Times(AnyNumber())
-      .WillRepeatedly(
-          Invoke(this, &QuicSequencerRandomTest::ReadAvailableData));
-  QuicByteCount total_bytes_consumed = 0;
-  EXPECT_CALL(stream_, AddBytesConsumed(_))
-      .Times(AnyNumber())
-      .WillRepeatedly(
-          testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
-            total_bytes_consumed += bytes;
-          }));
-
-  while (!list_.empty()) {
-    int index = OneToN(list_.size()) - 1;
-    QUIC_LOG(ERROR) << "Sending index " << index << " " << list_[index].second;
-    OnFrame(list_[index].first, list_[index].second.data());
-
-    list_.erase(list_.begin() + index);
-  }
-
-  ASSERT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, output_.size());
-  EXPECT_EQ(kPayload, output_);
-  EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
-}
-
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
-  char buffer[10];
-  iovec iov[2];
-  iov[0].iov_base = &buffer[0];
-  iov[0].iov_len = 5;
-  iov[1].iov_base = &buffer[5];
-  iov[1].iov_len = 5;
-
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber());
-  QuicByteCount total_bytes_consumed = 0;
-  EXPECT_CALL(stream_, AddBytesConsumed(_))
-      .Times(AnyNumber())
-      .WillRepeatedly(
-          testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
-            total_bytes_consumed += bytes;
-          }));
-
-  while (output_.size() != ABSL_ARRAYSIZE(kPayload) - 1) {
-    if (!list_.empty() && OneToN(2) == 1) {  // Send data
-      int index = OneToN(list_.size()) - 1;
-      OnFrame(list_[index].first, list_[index].second.data());
-      list_.erase(list_.begin() + index);
-    } else {  // Read data
-      bool has_bytes = sequencer_->HasBytesToRead();
-      iovec peek_iov[20];
-      int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20);
-      if (has_bytes) {
-        ASSERT_LT(0, iovs_peeked);
-        ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov));
-      } else {
-        ASSERT_EQ(0, iovs_peeked);
-        ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov));
-      }
-      int total_bytes_to_peek = ABSL_ARRAYSIZE(buffer);
-      for (int i = 0; i < iovs_peeked; ++i) {
-        int bytes_to_peek =
-            std::min<int>(peek_iov[i].iov_len, total_bytes_to_peek);
-        peeked_.append(static_cast<char*>(peek_iov[i].iov_base), bytes_to_peek);
-        total_bytes_to_peek -= bytes_to_peek;
-        if (total_bytes_to_peek == 0) {
-          break;
-        }
-      }
-      int bytes_read = sequencer_->Readv(iov, 2);
-      output_.append(buffer, bytes_read);
-      ASSERT_EQ(output_.size(), peeked_.size());
-    }
-  }
-  EXPECT_EQ(std::string(kPayload), output_);
-  EXPECT_EQ(std::string(kPayload), peeked_);
-  EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
-}
-
-// Same as above, just using a different method for reading.
-TEST_F(QuicStreamSequencerTest, MarkConsumed) {
-  InSequence s;
-  EXPECT_CALL(stream_, OnDataAvailable());
-
-  OnFrame(0, "abc");
-  OnFrame(3, "def");
-  OnFrame(6, "ghi");
-
-  // abcdefghi buffered.
-  EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
-
-  // Peek into the data.
-  std::vector<std::string> expected = {"abcdefghi"};
-  ASSERT_TRUE(VerifyReadableRegions(expected));
-
-  // Consume 1 byte.
-  EXPECT_CALL(stream_, AddBytesConsumed(1));
-  sequencer_->MarkConsumed(1);
-  // Verify data.
-  std::vector<std::string> expected2 = {"bcdefghi"};
-  ASSERT_TRUE(VerifyReadableRegions(expected2));
-  EXPECT_EQ(8u, sequencer_->NumBytesBuffered());
-
-  // Consume 2 bytes.
-  EXPECT_CALL(stream_, AddBytesConsumed(2));
-  sequencer_->MarkConsumed(2);
-  // Verify data.
-  std::vector<std::string> expected3 = {"defghi"};
-  ASSERT_TRUE(VerifyReadableRegions(expected3));
-  EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
-
-  // Consume 5 bytes.
-  EXPECT_CALL(stream_, AddBytesConsumed(5));
-  sequencer_->MarkConsumed(5);
-  // Verify data.
-  std::vector<std::string> expected4{"i"};
-  ASSERT_TRUE(VerifyReadableRegions(expected4));
-  EXPECT_EQ(1u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-
-  OnFrame(0, "abc");
-  OnFrame(9, "jklmnopqrstuvwxyz");
-
-  // Peek into the data.  Only the first chunk should be readable because of the
-  // missing data.
-  std::vector<std::string> expected{"abc"};
-  ASSERT_TRUE(VerifyReadableRegions(expected));
-
-  // Now, attempt to mark consumed more data than was readable and expect the
-  // stream to be closed.
-  EXPECT_CALL(stream_, ResetWithError(QuicResetStreamError::FromInternal(
-                           QUIC_ERROR_PROCESSING_STREAM)));
-  EXPECT_QUIC_BUG(sequencer_->MarkConsumed(4),
-                  "Invalid argument to MarkConsumed."
-                  " expect to consume: 4, but not enough bytes available.");
-}
-
-TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
-  InSequence s;
-  EXPECT_CALL(stream_, OnDataAvailable());
-
-  OnFrame(0, "abc");
-  OnFrame(3, "def");
-  // Missing packet: 6, ghi.
-  OnFrame(9, "jkl");
-
-  std::vector<std::string> expected = {"abcdef"};
-  ASSERT_TRUE(VerifyReadableRegions(expected));
-
-  EXPECT_CALL(stream_, AddBytesConsumed(6));
-  sequencer_->MarkConsumed(6);
-}
-
-TEST_F(QuicStreamSequencerTest, Move) {
-  InSequence s;
-  EXPECT_CALL(stream_, OnDataAvailable());
-
-  OnFrame(0, "abc");
-  OnFrame(3, "def");
-  OnFrame(6, "ghi");
-
-  // abcdefghi buffered.
-  EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
-
-  // Peek into the data.
-  std::vector<std::string> expected = {"abcdefghi"};
-  ASSERT_TRUE(VerifyReadableRegions(expected));
-
-  QuicStreamSequencer sequencer2(std::move(*sequencer_));
-  ASSERT_TRUE(VerifyReadableRegions(sequencer2, expected));
-}
-
-TEST_F(QuicStreamSequencerTest, OverlappingFramesReceived) {
-  // The peer should never send us non-identical stream frames which contain
-  // overlapping byte ranges - if they do, we close the connection.
-  QuicStreamId id = 1;
-
-  QuicStreamFrame frame1(id, false, 1, absl::string_view("hello"));
-  sequencer_->OnStreamFrame(frame1);
-
-  QuicStreamFrame frame2(id, false, 2, absl::string_view("hello"));
-  EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_OVERLAPPING_STREAM_DATA, _))
-      .Times(0);
-  sequencer_->OnStreamFrame(frame2);
-}
-
-TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) {
-  QuicStreamId id = 1;
-  const std::string data(1000, '.');
-
-  // Received [0, 1000).
-  QuicStreamFrame frame1(id, false, 0, data);
-  EXPECT_CALL(stream_, OnDataAvailable());
-  sequencer_->OnStreamFrame(frame1);
-  // Consume [0, 500).
-  EXPECT_CALL(stream_, AddBytesConsumed(500));
-  QuicStreamSequencerTest::ConsumeData(500);
-  EXPECT_EQ(500u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(500u, sequencer_->NumBytesBuffered());
-
-  // Received [500, 1500).
-  QuicStreamFrame frame2(id, false, 500, data);
-  // Do not call OnDataAvailable as there are readable bytes left in the buffer.
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
-  sequencer_->OnStreamFrame(frame2);
-  // Consume [1000, 1500).
-  EXPECT_CALL(stream_, AddBytesConsumed(1000));
-  QuicStreamSequencerTest::ConsumeData(1000);
-  EXPECT_EQ(1500u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-
-  // Received [1498, 1503).
-  QuicStreamFrame frame3(id, false, 1498, absl::string_view("hello"));
-  EXPECT_CALL(stream_, OnDataAvailable());
-  sequencer_->OnStreamFrame(frame3);
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  QuicStreamSequencerTest::ConsumeData(3);
-  EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-
-  // Received [1000, 1005).
-  QuicStreamFrame frame4(id, false, 1000, absl::string_view("hello"));
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
-  sequencer_->OnStreamFrame(frame4);
-  EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
-  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, OnDataAvailableWhenReadableBytesIncrease) {
-  sequencer_->set_level_triggered(true);
-  QuicStreamId id = 1;
-
-  // Received [0, 5).
-  QuicStreamFrame frame1(id, false, 0, "hello");
-  EXPECT_CALL(stream_, OnDataAvailable());
-  sequencer_->OnStreamFrame(frame1);
-  EXPECT_EQ(5u, sequencer_->NumBytesBuffered());
-
-  // Without consuming the buffer bytes, continue receiving [5, 11).
-  QuicStreamFrame frame2(id, false, 5, " world");
-  // OnDataAvailable should still be called because there are more data to read.
-  EXPECT_CALL(stream_, OnDataAvailable());
-  sequencer_->OnStreamFrame(frame2);
-  EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
-
-  // Without consuming the buffer bytes, continue receiving [12, 13).
-  QuicStreamFrame frame3(id, false, 5, "a");
-  // OnDataAvailable shouldn't be called becasue there are still only 11 bytes
-  // available.
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
-  sequencer_->OnStreamFrame(frame3);
-  EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, ReadSingleFrame) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-  OnFrame(0u, "abc");
-  std::string actual;
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  sequencer_->Read(&actual);
-  EXPECT_EQ("abc", actual);
-  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, ReadMultipleFramesWithMissingFrame) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-  OnFrame(0u, "abc");
-  OnFrame(3u, "def");
-  OnFrame(6u, "ghi");
-  OnFrame(10u, "xyz");  // Byte 9 is missing.
-  std::string actual;
-  EXPECT_CALL(stream_, AddBytesConsumed(9));
-  sequencer_->Read(&actual);
-  EXPECT_EQ("abcdefghi", actual);
-  EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, ReadAndAppendToString) {
-  EXPECT_CALL(stream_, OnDataAvailable());
-  OnFrame(0u, "def");
-  OnFrame(3u, "ghi");
-  std::string actual = "abc";
-  EXPECT_CALL(stream_, AddBytesConsumed(6));
-  sequencer_->Read(&actual);
-  EXPECT_EQ("abcdefghi", actual);
-  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
-}
-
-TEST_F(QuicStreamSequencerTest, StopReading) {
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
-  EXPECT_CALL(stream_, OnFinRead());
-
-  EXPECT_CALL(stream_, AddBytesConsumed(0));
-  sequencer_->StopReading();
-
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  OnFrame(0u, "abc");
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  OnFrame(3u, "def");
-  EXPECT_CALL(stream_, AddBytesConsumed(3));
-  OnFinFrame(6u, "ghi");
-}
-
-TEST_F(QuicStreamSequencerTest, StopReadingWithLevelTriggered) {
-  EXPECT_CALL(stream_, AddBytesConsumed(0));
-  EXPECT_CALL(stream_, AddBytesConsumed(3)).Times(3);
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
-  EXPECT_CALL(stream_, OnFinRead());
-
-  sequencer_->set_level_triggered(true);
-  sequencer_->StopReading();
-
-  OnFrame(0u, "abc");
-  OnFrame(3u, "def");
-  OnFinFrame(6u, "ghi");
-}
-
-// Regression test for https://crbug.com/992486.
-TEST_F(QuicStreamSequencerTest, CorruptFinFrames) {
-  EXPECT_CALL(stream_, OnUnrecoverableError(
-                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
-                           "Stream 1 received new final offset: 1, which is "
-                           "different from close offset: 2"));
-
-  OnFinFrame(2u, "");
-  OnFinFrame(0u, "a");
-  EXPECT_FALSE(sequencer_->HasBytesToRead());
-}
-
-// Regression test for crbug.com/1015693
-TEST_F(QuicStreamSequencerTest, ReceiveFinLessThanHighestOffset) {
-  EXPECT_CALL(stream_, OnDataAvailable()).Times(1);
-  EXPECT_CALL(stream_, OnUnrecoverableError(
-                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
-                           "Stream 1 received fin with offset: 0, which "
-                           "reduces current highest offset: 3"));
-  OnFrame(0u, "abc");
-  OnFinFrame(0u, "");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_stream_test.cc b/quic/core/quic_stream_test.cc
deleted file mode 100644
index a1c0560..0000000
--- a/quic/core/quic_stream_test.cc
+++ /dev/null
@@ -1,1738 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_rst_stream_frame.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/quiche_mem_slice_storage.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Invoke;
-using testing::InvokeWithoutArgs;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-const char kData1[] = "FooAndBar";
-const char kData2[] = "EepAndBaz";
-const QuicByteCount kDataLen = 9;
-
-class TestStream : public QuicStream {
- public:
-  TestStream(QuicStreamId id, QuicSession* session, StreamType type)
-      : QuicStream(id, session, /*is_static=*/false, type) {
-    sequencer()->set_level_triggered(true);
-  }
-
-  TestStream(PendingStream* pending, QuicSession* session, bool is_static)
-      : QuicStream(pending, session, is_static) {}
-
-  MOCK_METHOD(void, OnDataAvailable, (), (override));
-
-  MOCK_METHOD(void, OnCanWriteNewData, (), (override));
-
-  MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
-
-  using QuicStream::CanWriteNewData;
-  using QuicStream::CanWriteNewDataAfterData;
-  using QuicStream::CloseWriteSide;
-  using QuicStream::fin_buffered;
-  using QuicStream::MaybeSendStopSending;
-  using QuicStream::OnClose;
-  using QuicStream::WriteMemSlices;
-  using QuicStream::WriteOrBufferData;
-
- private:
-  std::string data_;
-};
-
-class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  QuicStreamTest()
-      : zero_(QuicTime::Delta::Zero()),
-        supported_versions_(AllSupportedVersions()) {}
-
-  void Initialize(Perspective perspective = Perspective::IS_SERVER) {
-    ParsedQuicVersionVector version_vector;
-    version_vector.push_back(GetParam());
-    connection_ = new StrictMock<MockQuicConnection>(
-        &helper_, &alarm_factory_, perspective, version_vector);
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
-    session_->Initialize();
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-        session_->config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
-    session_->OnConfigNegotiated();
-
-    stream_ = new StrictMock<TestStream>(kTestStreamId, session_.get(),
-                                         BIDIRECTIONAL);
-    EXPECT_NE(nullptr, stream_);
-    // session_ now owns stream_.
-    session_->ActivateStream(absl::WrapUnique(stream_));
-    // Ignore resetting when session_ is terminated.
-    EXPECT_CALL(*session_, MaybeSendStopSendingFrame(kTestStreamId, _))
-        .Times(AnyNumber());
-    EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _))
-        .Times(AnyNumber());
-    write_blocked_list_ =
-        QuicSessionPeer::GetWriteBlockedStreams(session_.get());
-  }
-
-  bool fin_sent() { return stream_->fin_sent(); }
-  bool rst_sent() { return stream_->rst_sent(); }
-
-  bool HasWriteBlockedStreams() {
-    return write_blocked_list_->HasWriteBlockedSpecialStream() ||
-           write_blocked_list_->HasWriteBlockedDataStreams();
-  }
-
-  QuicConsumedData CloseStreamOnWriteError(
-      QuicStreamId id, QuicByteCount /*write_length*/,
-      QuicStreamOffset /*offset*/, StreamSendingState /*state*/,
-      TransmissionType /*type*/, absl::optional<EncryptionLevel> /*level*/) {
-    session_->ResetStream(id, QUIC_STREAM_CANCELLED);
-    return QuicConsumedData(1, false);
-  }
-
-  bool ClearResetStreamFrame(const QuicFrame& frame) {
-    EXPECT_EQ(RST_STREAM_FRAME, frame.type);
-    DeleteFrame(&const_cast<QuicFrame&>(frame));
-    return true;
-  }
-
-  bool ClearStopSendingFrame(const QuicFrame& frame) {
-    EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
-    DeleteFrame(&const_cast<QuicFrame&>(frame));
-    return true;
-  }
-
- protected:
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnection* connection_;
-  std::unique_ptr<MockQuicSession> session_;
-  StrictMock<TestStream>* stream_;
-  QuicWriteBlockedList* write_blocked_list_;
-  QuicTime::Delta zero_;
-  ParsedQuicVersionVector supported_versions_;
-  QuicStreamId kTestStreamId =
-      GetNthClientInitiatedBidirectionalStreamId(GetParam().transport_version,
-                                                 1);
-  const QuicStreamId kTestPendingStreamId =
-      GetNthClientInitiatedUnidirectionalStreamId(GetParam().transport_version,
-                                                  1);
-};
-
-INSTANTIATE_TEST_SUITE_P(QuicStreamTests, QuicStreamTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-using PendingStreamTest = QuicStreamTest;
-
-INSTANTIATE_TEST_SUITE_P(PendingStreamTests, PendingStreamTest,
-                         ::testing::ValuesIn(CurrentSupportedHttp3Versions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(PendingStreamTest, PendingStreamStaticness) {
-  Initialize();
-
-  PendingStream pending(kTestPendingStreamId, session_.get());
-  TestStream stream(&pending, session_.get(), false);
-  EXPECT_FALSE(stream.is_static());
-
-  PendingStream pending2(kTestPendingStreamId + 4, session_.get());
-  TestStream stream2(&pending2, session_.get(), true);
-  EXPECT_TRUE(stream2.is_static());
-}
-
-TEST_P(PendingStreamTest, PendingStreamType) {
-  Initialize();
-
-  PendingStream pending(kTestPendingStreamId, session_.get());
-  TestStream stream(&pending, session_.get(), false);
-  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
-}
-
-TEST_P(PendingStreamTest, PendingStreamTypeOnClient) {
-  Initialize(Perspective::IS_CLIENT);
-
-  QuicStreamId server_initiated_pending_stream_id =
-      GetNthServerInitiatedUnidirectionalStreamId(session_->transport_version(),
-                                                  1);
-  PendingStream pending(server_initiated_pending_stream_id, session_.get());
-  TestStream stream(&pending, session_.get(), false);
-  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
-}
-
-TEST_P(PendingStreamTest, PendingStreamTooMuchData) {
-  Initialize();
-
-  PendingStream pending(kTestPendingStreamId, session_.get());
-  // Receive a stream frame that violates flow control: the byte offset is
-  // higher than the receive window offset.
-  QuicStreamFrame frame(kTestPendingStreamId, false,
-                        kInitialSessionFlowControlWindowForTest + 1, ".");
-
-  // Stream should not accept the frame, and the connection should be closed.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  pending.OnStreamFrame(frame);
-}
-
-TEST_P(PendingStreamTest, PendingStreamTooMuchDataInRstStream) {
-  Initialize();
-
-  PendingStream pending1(kTestPendingStreamId, session_.get());
-  // Receive a rst stream frame that violates flow control: the byte offset is
-  // higher than the receive window offset.
-  QuicRstStreamFrame frame1(kInvalidControlFrameId, kTestPendingStreamId,
-                            QUIC_STREAM_CANCELLED,
-                            kInitialSessionFlowControlWindowForTest + 1);
-
-  // Pending stream should not accept the frame, and the connection should be
-  // closed.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  pending1.OnRstStreamFrame(frame1);
-
-  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      session_->transport_version(), Perspective::IS_CLIENT);
-  PendingStream pending2(bidirection_stream_id, session_.get());
-  // Receive a rst stream frame that violates flow control: the byte offset is
-  // higher than the receive window offset.
-  QuicRstStreamFrame frame2(kInvalidControlFrameId, bidirection_stream_id,
-                            QUIC_STREAM_CANCELLED,
-                            kInitialSessionFlowControlWindowForTest + 1);
-  // Bidirectional Pending stream should not accept the frame, and the
-  // connection should be closed.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  pending2.OnRstStreamFrame(frame2);
-}
-
-TEST_P(PendingStreamTest, PendingStreamRstStream) {
-  Initialize();
-
-  PendingStream pending(kTestPendingStreamId, session_.get());
-  QuicStreamOffset final_byte_offset = 7;
-  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestPendingStreamId,
-                           QUIC_STREAM_CANCELLED, final_byte_offset);
-
-  // Pending stream should accept the frame and not close the connection.
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  pending.OnRstStreamFrame(frame);
-}
-
-TEST_P(PendingStreamTest, PendingStreamWindowUpdate) {
-  Initialize();
-
-  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      session_->transport_version(), Perspective::IS_CLIENT);
-  PendingStream pending(bidirection_stream_id, session_.get());
-  QuicWindowUpdateFrame frame(kInvalidControlFrameId, bidirection_stream_id,
-                              kDefaultFlowControlSendWindow * 2);
-  pending.OnWindowUpdateFrame(frame);
-  TestStream stream(&pending, session_.get(), false);
-
-  EXPECT_EQ(QuicStreamPeer::SendWindowSize(&stream),
-            kDefaultFlowControlSendWindow * 2);
-}
-
-TEST_P(PendingStreamTest, PendingStreamStopSending) {
-  Initialize();
-
-  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-      session_->transport_version(), Perspective::IS_CLIENT);
-  PendingStream pending(bidirection_stream_id, session_.get());
-  QuicResetStreamError error =
-      QuicResetStreamError::FromInternal(QUIC_STREAM_INTERNAL_ERROR);
-  pending.OnStopSending(error);
-  EXPECT_TRUE(pending.GetStopSendingErrorCode());
-  auto actual_error = *pending.GetStopSendingErrorCode();
-  EXPECT_EQ(actual_error, error);
-}
-
-TEST_P(PendingStreamTest, FromPendingStream) {
-  Initialize();
-
-  PendingStream pending(kTestPendingStreamId, session_.get());
-
-  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
-  pending.OnStreamFrame(frame);
-  pending.OnStreamFrame(frame);
-  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
-  pending.OnStreamFrame(frame2);
-
-  TestStream stream(&pending, session_.get(), false);
-  EXPECT_EQ(3, stream.num_frames_received());
-  EXPECT_EQ(3u, stream.stream_bytes_read());
-  EXPECT_EQ(1, stream.num_duplicate_frames_received());
-  EXPECT_EQ(true, stream.fin_received());
-  EXPECT_EQ(frame2.offset + 1, stream.highest_received_byte_offset());
-  EXPECT_EQ(frame2.offset + 1,
-            session_->flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(PendingStreamTest, FromPendingStreamThenData) {
-  Initialize();
-
-  PendingStream pending(kTestPendingStreamId, session_.get());
-
-  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
-  pending.OnStreamFrame(frame);
-
-  auto stream = new TestStream(&pending, session_.get(), false);
-  session_->ActivateStream(absl::WrapUnique(stream));
-
-  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
-  stream->OnStreamFrame(frame2);
-
-  EXPECT_EQ(2, stream->num_frames_received());
-  EXPECT_EQ(2u, stream->stream_bytes_read());
-  EXPECT_EQ(true, stream->fin_received());
-  EXPECT_EQ(frame2.offset + 1, stream->highest_received_byte_offset());
-  EXPECT_EQ(frame2.offset + 1,
-            session_->flow_controller()->highest_received_byte_offset());
-}
-
-TEST_P(QuicStreamTest, WriteAllData) {
-  Initialize();
-
-  QuicByteCount length =
-      1 + QuicPacketCreator::StreamFramePacketOverhead(
-              connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
-              PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-              !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
-  connection_->SetMaxPacketLength(length);
-
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_FALSE(HasWriteBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, NoBlockingIfNoDataOrFin) {
-  Initialize();
-
-  // Write no data and no fin.  If we consume nothing we should not be write
-  // blocked.
-  EXPECT_QUIC_BUG(
-      stream_->WriteOrBufferData(absl::string_view(), false, nullptr), "");
-  EXPECT_FALSE(HasWriteBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, BlockIfOnlySomeDataConsumed) {
-  Initialize();
-
-  // Write some data and no fin.  If we consume some but not all of the data,
-  // we should be write blocked a not all the data was consumed.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
-  EXPECT_EQ(1u, stream_->BufferedDataBytes());
-}
-
-TEST_P(QuicStreamTest, BlockIfFinNotConsumedWithData) {
-  Initialize();
-
-  // Write some data and no fin.  If we consume all the data but not the fin,
-  // we should be write blocked because the fin was not consumed.
-  // (This should never actually happen as the fin should be sent out with the
-  // last data)
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, BlockIfSoloFinNotConsumed) {
-  Initialize();
-
-  // Write no data and a fin.  If we consume nothing we should be write blocked,
-  // as the fin was not consumed.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(Return(QuicConsumedData(0, false)));
-  stream_->WriteOrBufferData(absl::string_view(), true, nullptr);
-  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, CloseOnPartialWrite) {
-  Initialize();
-
-  // Write some data and no fin. However, while writing the data
-  // close the stream and verify that MarkConnectionLevelWriteBlocked does not
-  // crash with an unknown stream.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(Invoke(this, &QuicStreamTest::CloseStreamOnWriteError));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
-  ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, WriteOrBufferData) {
-  Initialize();
-
-  EXPECT_FALSE(HasWriteBlockedStreams());
-  QuicByteCount length =
-      1 + QuicPacketCreator::StreamFramePacketOverhead(
-              connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
-              PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-              !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
-  connection_->SetMaxPacketLength(length);
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(1u, stream_->BufferedDataBytes());
-  EXPECT_TRUE(HasWriteBlockedStreams());
-
-  // Queue a bytes_consumed write.
-  stream_->WriteOrBufferData(kData2, false, nullptr);
-  EXPECT_EQ(10u, stream_->BufferedDataBytes());
-  // Make sure we get the tail of the first write followed by the bytes_consumed
-  InSequence s;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1,
-                                     NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  EXPECT_CALL(*stream_, OnCanWriteNewData());
-  stream_->OnCanWrite();
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-
-  // And finally the end of the bytes_consumed.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2,
-                                     NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  EXPECT_CALL(*stream_, OnCanWriteNewData());
-  stream_->OnCanWrite();
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, WriteOrBufferDataReachStreamLimit) {
-  Initialize();
-  std::string data("aaaaa");
-  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
-                                        stream_);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
-  EXPECT_QUIC_BUG(stream_->WriteOrBufferData("a", false, nullptr),
-                  "Write too many data via stream");
-}
-
-TEST_P(QuicStreamTest, ConnectionCloseAfterStreamClose) {
-  Initialize();
-
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  if (VersionHasIetfQuicFrames(session_->transport_version())) {
-    // Create and inject a STOP SENDING frame to complete the close
-    // of the stream. This is only needed for version 99/IETF QUIC.
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
-                                      QUIC_STREAM_CANCELLED);
-    session_->OnStopSendingFrame(stop_sending);
-  }
-  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
-  EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
-  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
-                              ConnectionCloseSource::FROM_SELF);
-  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
-  EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
-}
-
-TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
-  // For flow control accounting, a stream must send either a FIN or a RST frame
-  // before termination.
-  // Test that if no FIN has been sent, we send a RST.
-
-  Initialize();
-  EXPECT_FALSE(fin_sent());
-  EXPECT_FALSE(rst_sent());
-
-  // Write some data, with no FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 1), false, nullptr);
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_FALSE(fin_sent());
-  EXPECT_FALSE(rst_sent());
-
-  // Now close the stream, and expect that we send a RST.
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _));
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  if (VersionHasIetfQuicFrames(session_->transport_version())) {
-    // Create and inject a STOP SENDING frame to complete the close
-    // of the stream. This is only needed for version 99/IETF QUIC.
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
-                                      QUIC_STREAM_CANCELLED);
-    session_->OnStopSendingFrame(stop_sending);
-  }
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_FALSE(fin_sent());
-  EXPECT_TRUE(rst_sent());
-}
-
-TEST_P(QuicStreamTest, RstNotSentIfFinSent) {
-  // For flow control accounting, a stream must send either a FIN or a RST frame
-  // before termination.
-  // Test that if a FIN has been sent, we don't also send a RST.
-
-  Initialize();
-  EXPECT_FALSE(fin_sent());
-  EXPECT_FALSE(rst_sent());
-
-  // Write some data, with FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 1u, 0u, FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 1), true, nullptr);
-  EXPECT_TRUE(fin_sent());
-  EXPECT_FALSE(rst_sent());
-
-  // Now close the stream, and expect that we do not send a RST.
-  QuicStreamPeer::CloseReadSide(stream_);
-  stream_->CloseWriteSide();
-  EXPECT_TRUE(fin_sent());
-  EXPECT_FALSE(rst_sent());
-}
-
-TEST_P(QuicStreamTest, OnlySendOneRst) {
-  // For flow control accounting, a stream must send either a FIN or a RST frame
-  // before termination.
-  // Test that if a stream sends a RST, it doesn't send an additional RST during
-  // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
-
-  Initialize();
-  EXPECT_FALSE(fin_sent());
-  EXPECT_FALSE(rst_sent());
-
-  // Reset the stream.
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)).Times(1);
-  stream_->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_FALSE(fin_sent());
-  EXPECT_TRUE(rst_sent());
-
-  // Now close the stream (any further resets being sent would break the
-  // expectation above).
-  QuicStreamPeer::CloseReadSide(stream_);
-  stream_->CloseWriteSide();
-  EXPECT_FALSE(fin_sent());
-  EXPECT_TRUE(rst_sent());
-}
-
-TEST_P(QuicStreamTest, StreamFlowControlMultipleWindowUpdates) {
-  Initialize();
-
-  // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
-  // want to make sure we latch the largest offset we see.
-
-  // Initially should be default.
-  EXPECT_EQ(kMinimumFlowControlSendWindow,
-            QuicStreamPeer::SendWindowOffset(stream_));
-
-  // Check a single WINDOW_UPDATE results in correct offset.
-  QuicWindowUpdateFrame window_update_1(kInvalidControlFrameId, stream_->id(),
-                                        kMinimumFlowControlSendWindow + 5);
-  stream_->OnWindowUpdateFrame(window_update_1);
-  EXPECT_EQ(window_update_1.max_data,
-            QuicStreamPeer::SendWindowOffset(stream_));
-
-  // Now send a few more WINDOW_UPDATES and make sure that only the largest is
-  // remembered.
-  QuicWindowUpdateFrame window_update_2(kInvalidControlFrameId, stream_->id(),
-                                        1);
-  QuicWindowUpdateFrame window_update_3(kInvalidControlFrameId, stream_->id(),
-                                        kMinimumFlowControlSendWindow + 10);
-  QuicWindowUpdateFrame window_update_4(kInvalidControlFrameId, stream_->id(),
-                                        5678);
-  stream_->OnWindowUpdateFrame(window_update_2);
-  stream_->OnWindowUpdateFrame(window_update_3);
-  stream_->OnWindowUpdateFrame(window_update_4);
-  EXPECT_EQ(window_update_3.max_data,
-            QuicStreamPeer::SendWindowOffset(stream_));
-}
-
-TEST_P(QuicStreamTest, FrameStats) {
-  Initialize();
-
-  EXPECT_EQ(0, stream_->num_frames_received());
-  EXPECT_EQ(0, stream_->num_duplicate_frames_received());
-  QuicStreamFrame frame(stream_->id(), false, 0, ".");
-  EXPECT_CALL(*stream_, OnDataAvailable()).Times(2);
-  stream_->OnStreamFrame(frame);
-  EXPECT_EQ(1, stream_->num_frames_received());
-  EXPECT_EQ(0, stream_->num_duplicate_frames_received());
-  stream_->OnStreamFrame(frame);
-  EXPECT_EQ(2, stream_->num_frames_received());
-  EXPECT_EQ(1, stream_->num_duplicate_frames_received());
-  QuicStreamFrame frame2(stream_->id(), false, 1, "abc");
-  stream_->OnStreamFrame(frame2);
-}
-
-// Verify that when we receive a packet which violates flow control (i.e. sends
-// too much data on the stream) that the stream sequencer never sees this frame,
-// as we check for violation and close the connection early.
-TEST_P(QuicStreamTest, StreamSequencerNeverSeesPacketsViolatingFlowControl) {
-  Initialize();
-
-  // Receive a stream frame that violates flow control: the byte offset is
-  // higher than the receive window offset.
-  QuicStreamFrame frame(stream_->id(), false,
-                        kInitialSessionFlowControlWindowForTest + 1, ".");
-  EXPECT_GT(frame.offset, QuicStreamPeer::ReceiveWindowOffset(stream_));
-
-  // Stream should not accept the frame, and the connection should be closed.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  stream_->OnStreamFrame(frame);
-}
-
-// Verify that after the consumer calls StopReading(), the stream still sends
-// flow control updates.
-TEST_P(QuicStreamTest, StopReadingSendsFlowControl) {
-  Initialize();
-
-  stream_->StopReading();
-
-  // Connection should not get terminated due to flow control errors.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
-      .Times(0);
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(AtLeast(1))
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-
-  std::string data(1000, 'x');
-  for (QuicStreamOffset offset = 0;
-       offset < 2 * kInitialStreamFlowControlWindowForTest;
-       offset += data.length()) {
-    QuicStreamFrame frame(stream_->id(), false, offset, data);
-    stream_->OnStreamFrame(frame);
-  }
-  EXPECT_LT(kInitialStreamFlowControlWindowForTest,
-            QuicStreamPeer::ReceiveWindowOffset(stream_));
-}
-
-TEST_P(QuicStreamTest, FinalByteOffsetFromFin) {
-  Initialize();
-
-  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-
-  QuicStreamFrame stream_frame_no_fin(stream_->id(), false, 1234, ".");
-  stream_->OnStreamFrame(stream_frame_no_fin);
-  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-
-  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
-  stream_->OnStreamFrame(stream_frame_with_fin);
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, FinalByteOffsetFromRst) {
-  Initialize();
-
-  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, InvalidFinalByteOffsetFromRst) {
-  Initialize();
-
-  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 0xFFFFFFFFFFFF);
-  // Stream should not accept the frame, and the connection should be closed.
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
-  stream_->OnStreamReset(rst_frame);
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) {
-  // When receiving Trailers, an empty stream frame is created with the FIN set,
-  // and is passed to OnStreamFrame. The Trailers may be sent in advance of
-  // queued body bytes being sent, and thus the final byte offset may exceed
-  // current flow control limits. Flow control should only be concerned with
-  // data that has actually been sent/received, so verify that flow control
-  // ignores such a stream frame.
-  Initialize();
-
-  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
-  const QuicStreamOffset kByteOffsetExceedingFlowControlWindow =
-      kInitialSessionFlowControlWindowForTest + 1;
-  const QuicStreamOffset current_stream_flow_control_offset =
-      QuicStreamPeer::ReceiveWindowOffset(stream_);
-  const QuicStreamOffset current_connection_flow_control_offset =
-      QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller());
-  ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
-            current_stream_flow_control_offset);
-  ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
-            current_connection_flow_control_offset);
-  QuicStreamFrame zero_length_stream_frame_with_fin(
-      stream_->id(), /*fin=*/true, kByteOffsetExceedingFlowControlWindow,
-      absl::string_view());
-  EXPECT_EQ(0, zero_length_stream_frame_with_fin.data_length);
-
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  stream_->OnStreamFrame(zero_length_stream_frame_with_fin);
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-
-  // The flow control receive offset values should not have changed.
-  EXPECT_EQ(current_stream_flow_control_offset,
-            QuicStreamPeer::ReceiveWindowOffset(stream_));
-  EXPECT_EQ(
-      current_connection_flow_control_offset,
-      QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller()));
-}
-
-TEST_P(QuicStreamTest, OnStreamResetOffsetOverflow) {
-  Initialize();
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, kMaxStreamLength + 1);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
-  stream_->OnStreamReset(rst_frame);
-}
-
-TEST_P(QuicStreamTest, OnStreamFrameUpperLimit) {
-  Initialize();
-
-  // Modify receive window offset and sequencer buffer total_bytes_read_ to
-  // avoid flow control violation.
-  QuicStreamPeer::SetReceiveWindowOffset(stream_, kMaxStreamLength + 5u);
-  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
-                                                 kMaxStreamLength + 5u);
-  QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
-      QuicStreamPeer::sequencer(stream_), kMaxStreamLength - 10u);
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
-      .Times(0);
-  QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength - 1, ".");
-  stream_->OnStreamFrame(stream_frame);
-  QuicStreamFrame stream_frame2(stream_->id(), true, kMaxStreamLength, "");
-  stream_->OnStreamFrame(stream_frame2);
-}
-
-TEST_P(QuicStreamTest, StreamTooLong) {
-  Initialize();
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
-      .Times(1);
-  QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength, ".");
-  EXPECT_QUIC_PEER_BUG(
-      stream_->OnStreamFrame(stream_frame),
-      absl::StrCat("Receive stream frame on stream ", stream_->id(),
-                   " reaches max stream length"));
-}
-
-TEST_P(QuicStreamTest, SetDrainingIncomingOutgoing) {
-  // Don't have incoming data consumed.
-  Initialize();
-
-  // Incoming data with FIN.
-  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
-  stream_->OnStreamFrame(stream_frame_with_fin);
-  // The FIN has been received but not consumed.
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_FALSE(stream_->reading_stopped());
-
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Outgoing data with FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
-  EXPECT_TRUE(stream_->write_side_closed());
-
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) {
-  // Don't have incoming data consumed.
-  Initialize();
-
-  // Outgoing data with FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
-  EXPECT_TRUE(stream_->write_side_closed());
-
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Incoming data with FIN.
-  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
-  stream_->OnStreamFrame(stream_frame_with_fin);
-  // The FIN has been received but not consumed.
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_FALSE(stream_->reading_stopped());
-
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicStreamTest, EarlyResponseFinHandling) {
-  // Verify that if the server completes the response before reading the end of
-  // the request, the received FIN is recorded.
-
-  Initialize();
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-
-  // Receive data for the request.
-  EXPECT_CALL(*stream_, OnDataAvailable()).Times(1);
-  QuicStreamFrame frame1(stream_->id(), false, 0, "Start");
-  stream_->OnStreamFrame(frame1);
-  // When QuicSimpleServerStream sends the response, it calls
-  // QuicStream::CloseReadSide() first.
-  QuicStreamPeer::CloseReadSide(stream_);
-  // Send data and FIN for the response.
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
-  // Receive remaining data and FIN for the request.
-  QuicStreamFrame frame2(stream_->id(), true, 0, "End");
-  stream_->OnStreamFrame(frame2);
-  EXPECT_TRUE(stream_->fin_received());
-  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
-}
-
-TEST_P(QuicStreamTest, StreamWaitsForAcks) {
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  // Stream is not waiting for acks initially.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-
-  // Send kData1.
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(9u, newly_acked_length);
-  // Stream is not waiting for acks as all sent data is acked.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // Send kData2.
-  stream_->WriteOrBufferData(kData2, false, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Send FIN.
-  stream_->WriteOrBufferData("", true, nullptr);
-  // Fin only frame is not stored in send buffer.
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // kData2 is retransmitted.
-  stream_->OnStreamFrameRetransmitted(9, 9, false);
-
-  // kData2 is acked.
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(9u, newly_acked_length);
-  // Stream is waiting for acks as FIN is not acked.
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // FIN is acked.
-  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(0u, newly_acked_length);
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-}
-
-TEST_P(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  // Send data.
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData("", true, nullptr);
-  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(9u, newly_acked_length);
-  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(9u, newly_acked_length);
-  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(9u, newly_acked_length);
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  // FIN is not acked yet.
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(0u, newly_acked_length);
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, CancelStream) {
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Cancel stream.
-  stream_->MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
-  // stream still waits for acks as the error code is QUIC_STREAM_NO_ERROR, and
-  // data is going to be retransmitted.
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_CALL(*connection_,
-              OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .Times(AtLeast(1))
-      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        session_->ReallyMaybeSendRstStreamFrame(
-            stream_->id(), QUIC_STREAM_CANCELLED,
-            stream_->stream_bytes_written());
-      }));
-
-  stream_->Reset(QUIC_STREAM_CANCELLED);
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Stream stops waiting for acks as data is not going to be retransmitted.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
-  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
-    // In IETF QUIC, receiving a RESET_STREAM will only close the read side. The
-    // stream itself is not closed and will not send reset.
-    return;
-  }
-
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  // RST_STREAM received.
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 9);
-
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          stream_->id(),
-          QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
-  stream_->OnStreamReset(rst_frame);
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Stream stops waiting for acks as it does not finish sending and rst is
-  // sent.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  stream_->WriteOrBufferData(kData1, true, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-
-  // RST_STREAM received.
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  // Stream still waits for acks as it finishes sending and has unacked data.
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-}
-
-TEST_P(QuicStreamTest, ConnectionClosed) {
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          stream_->id(),
-          QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
-  QuicConnectionPeer::SetConnectionClose(connection_);
-  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
-                              ConnectionCloseSource::FROM_SELF);
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Stream stops waiting for acks as connection is going to close.
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, CanWriteNewDataAfterData) {
-  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
-  Initialize();
-  EXPECT_TRUE(stream_->CanWriteNewDataAfterData(99));
-  EXPECT_FALSE(stream_->CanWriteNewDataAfterData(100));
-}
-
-TEST_P(QuicStreamTest, WriteBufferedData) {
-  // Set buffered data low water mark to be 100.
-  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
-
-  Initialize();
-  std::string data(1024, 'a');
-  EXPECT_TRUE(stream_->CanWriteNewData());
-
-  // Testing WriteOrBufferData.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->WriteOrBufferData(data, false, nullptr);
-  stream_->WriteOrBufferData(data, false, nullptr);
-  stream_->WriteOrBufferData(data, false, nullptr);
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-
-  // Verify all data is saved.
-  EXPECT_EQ(3 * data.length() - 100, stream_->BufferedDataBytes());
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  // Buffered data size > threshold, do not ask upper layer for more data.
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
-  stream_->OnCanWrite();
-  EXPECT_EQ(3 * data.length() - 200, stream_->BufferedDataBytes());
-  EXPECT_FALSE(stream_->CanWriteNewData());
-
-  // Send buffered data to make buffered data size < threshold.
-  QuicByteCount data_to_write =
-      3 * data.length() - 200 -
-      GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
-        return session_->ConsumeData(stream_->id(), data_to_write, 200u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  // Buffered data size < threshold, ask upper layer for more data.
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
-  stream_->OnCanWrite();
-  EXPECT_EQ(static_cast<uint64_t>(
-                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
-            stream_->BufferedDataBytes());
-  EXPECT_TRUE(stream_->CanWriteNewData());
-
-  // Flush all buffered data.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
-  stream_->OnCanWrite();
-  EXPECT_EQ(0u, stream_->BufferedDataBytes());
-  EXPECT_FALSE(stream_->HasBufferedData());
-  EXPECT_TRUE(stream_->CanWriteNewData());
-
-  // Testing Writev.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Return(QuicConsumedData(0, false)));
-  struct iovec iov = {const_cast<char*>(data.data()), data.length()};
-  quiche::QuicheMemSliceStorage storage(
-      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
-      1024);
-  QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
-
-  // There is no buffered data before, all data should be consumed without
-  // respecting buffered data upper limit.
-  EXPECT_EQ(data.length(), consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
-  EXPECT_FALSE(stream_->CanWriteNewData());
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
-  quiche::QuicheMemSliceStorage storage2(
-      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
-      1024);
-  consumed = stream_->WriteMemSlices(storage2.ToSpan(), false);
-  // No Data can be consumed as buffered data is beyond upper limit.
-  EXPECT_EQ(0u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
-
-  data_to_write =
-      data.length() - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
-        return session_->ConsumeData(stream_->id(), data_to_write, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
-  stream_->OnCanWrite();
-  EXPECT_EQ(static_cast<uint64_t>(
-                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
-            stream_->BufferedDataBytes());
-  EXPECT_TRUE(stream_->CanWriteNewData());
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
-  // All data can be consumed as buffered data is below upper limit.
-  quiche::QuicheMemSliceStorage storage3(
-      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
-      1024);
-  consumed = stream_->WriteMemSlices(storage3.ToSpan(), false);
-  EXPECT_EQ(data.length(), consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_EQ(data.length() + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
-            stream_->BufferedDataBytes());
-  EXPECT_FALSE(stream_->CanWriteNewData());
-}
-
-TEST_P(QuicStreamTest, WritevDataReachStreamLimit) {
-  Initialize();
-  std::string data("aaaaa");
-  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
-                                        stream_);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  struct iovec iov = {const_cast<char*>(data.data()), 5u};
-  quiche::QuicheMemSliceStorage storage(
-      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
-      1024);
-  QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
-  EXPECT_EQ(data.length(), consumed.bytes_consumed);
-  struct iovec iov2 = {const_cast<char*>(data.data()), 1u};
-  quiche::QuicheMemSliceStorage storage2(
-      &iov2, 1,
-      session_->connection()->helper()->GetStreamSendBufferAllocator(), 1024);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
-  EXPECT_QUIC_BUG(stream_->WriteMemSlices(storage2.ToSpan(), false),
-                  "Write too many data via stream");
-}
-
-TEST_P(QuicStreamTest, WriteMemSlices) {
-  // Set buffered data low water mark to be 100.
-  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
-
-  Initialize();
-  constexpr QuicByteCount kDataSize = 1024;
-  quiche::QuicheBufferAllocator* allocator =
-      connection_->helper()->GetStreamSendBufferAllocator();
-  std::vector<quiche::QuicheMemSlice> vector1;
-  vector1.push_back(
-      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
-  vector1.push_back(
-      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
-  std::vector<quiche::QuicheMemSlice> vector2;
-  vector2.push_back(
-      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
-  vector2.push_back(
-      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
-  absl::Span<quiche::QuicheMemSlice> span1(vector1);
-  absl::Span<quiche::QuicheMemSlice> span2(vector2);
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  // There is no buffered data before, all data should be consumed.
-  QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
-  EXPECT_EQ(2048u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
-  EXPECT_FALSE(stream_->fin_buffered());
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
-  // No Data can be consumed as buffered data is beyond upper limit.
-  consumed = stream_->WriteMemSlices(span2, true);
-  EXPECT_EQ(0u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
-  EXPECT_FALSE(stream_->fin_buffered());
-
-  QuicByteCount data_to_write =
-      2 * kDataSize - 100 - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
-        return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
-  stream_->OnCanWrite();
-  EXPECT_EQ(static_cast<uint64_t>(
-                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
-            stream_->BufferedDataBytes());
-  // Try to write slices2 again.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
-  consumed = stream_->WriteMemSlices(span2, true);
-  EXPECT_EQ(2048u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_EQ(2 * kDataSize + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
-            stream_->BufferedDataBytes());
-  EXPECT_TRUE(stream_->fin_buffered());
-
-  // Flush all buffered data.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->OnCanWrite();
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
-  EXPECT_FALSE(stream_->HasBufferedData());
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
-  Initialize();
-  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_);
-  std::vector<std::pair<char*, size_t>> buffers;
-  quiche::QuicheMemSlice slice1 = MemSliceFromString("12345");
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  // There is no buffered data before, all data should be consumed.
-  QuicConsumedData consumed = stream_->WriteMemSlice(std::move(slice1), false);
-  EXPECT_EQ(5u, consumed.bytes_consumed);
-
-  quiche::QuicheMemSlice slice2 = MemSliceFromString("6");
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
-  EXPECT_QUIC_BUG(stream_->WriteMemSlice(std::move(slice2), false),
-                  "Write too many data via stream");
-}
-
-TEST_P(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
-  Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-
-  // Send [0, 27) and fin.
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData(kData1, true, nullptr);
-  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-  // Ack [0, 9), [5, 22) and [18, 26)
-  // Verify [0, 9) 9 bytes are acked.
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(9u, newly_acked_length);
-  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Verify [9, 22) 13 bytes are acked.
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(13u, newly_acked_length);
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  // Verify [22, 26) 4 bytes are acked.
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(4u, newly_acked_length);
-  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-
-  // Ack [0, 27). Verify [26, 27) 1 byte is acked.
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(1u, newly_acked_length);
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_TRUE(stream_->IsWaitingForAcks());
-  EXPECT_TRUE(session_->HasUnackedStreamData());
-
-  // Ack Fin.
-  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState()).Times(1);
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(0u, newly_acked_length);
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-
-  // Ack [10, 27) and fin. No new data is acked.
-  EXPECT_FALSE(
-      stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
-                                  QuicTime::Zero(), &newly_acked_length));
-  EXPECT_EQ(0u, newly_acked_length);
-  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
-  EXPECT_FALSE(stream_->IsWaitingForAcks());
-  EXPECT_FALSE(session_->HasUnackedStreamData());
-}
-
-TEST_P(QuicStreamTest, OnStreamFrameLost) {
-  Initialize();
-
-  // Send [0, 9).
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  EXPECT_FALSE(stream_->HasBufferedData());
-  EXPECT_TRUE(stream_->IsStreamFrameOutstanding(0, 9, false));
-
-  // Try to send [9, 27), but connection is blocked.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Return(QuicConsumedData(0, false)));
-  stream_->WriteOrBufferData(kData2, false, nullptr);
-  stream_->WriteOrBufferData(kData2, false, nullptr);
-  EXPECT_TRUE(stream_->HasBufferedData());
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-
-  // Lost [0, 9). When stream gets a chance to write, only lost data is
-  // transmitted.
-  stream_->OnStreamFrameLost(0, 9, false);
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
-  stream_->OnCanWrite();
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-  EXPECT_TRUE(stream_->HasBufferedData());
-
-  // This OnCanWrite causes [9, 27) to be sent.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->OnCanWrite();
-  EXPECT_FALSE(stream_->HasBufferedData());
-
-  // Send a fin only frame.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->WriteOrBufferData("", true, nullptr);
-
-  // Lost [9, 27) and fin.
-  stream_->OnStreamFrameLost(9, 18, false);
-  stream_->OnStreamFrameLost(27, 0, true);
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-
-  // Ack [9, 18).
-  QuicByteCount newly_acked_length = 0;
-  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
-                                          QuicTime::Zero(),
-                                          &newly_acked_length));
-  EXPECT_EQ(9u, newly_acked_length);
-  EXPECT_FALSE(stream_->IsStreamFrameOutstanding(9, 3, false));
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-  // This OnCanWrite causes [18, 27) and fin to be retransmitted. Verify fin can
-  // be bundled with data.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 9u, 18u, FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  stream_->OnCanWrite();
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-  // Lost [9, 18) again, but it is not considered as lost because kData2
-  // has been acked.
-  stream_->OnStreamFrameLost(9, 9, false);
-  EXPECT_FALSE(stream_->HasPendingRetransmission());
-  EXPECT_TRUE(stream_->IsStreamFrameOutstanding(27, 0, true));
-}
-
-TEST_P(QuicStreamTest, CannotBundleLostFin) {
-  Initialize();
-
-  // Send [0, 18) and fin.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData(kData2, true, nullptr);
-
-  // Lost [0, 9) and fin.
-  stream_->OnStreamFrameLost(0, 9, false);
-  stream_->OnStreamFrameLost(18, 0, true);
-
-  // Retransmit lost data. Verify [0, 9) and fin are retransmitted in two
-  // frames.
-  InSequence s;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillOnce(Return(QuicConsumedData(0, true)));
-  stream_->OnCanWrite();
-}
-
-TEST_P(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
-  Initialize();
-
-  // Set the config to a small value so that a newly created stream has small
-  // send flow control window.
-  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
-                                                            100);
-  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-      session_->config(), 100);
-  auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
-                                   GetParam().transport_version, 2),
-                               session_.get(), BIDIRECTIONAL);
-  session_->ActivateStream(absl::WrapUnique(stream));
-
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
-  std::string data(1024, '.');
-  stream->WriteOrBufferData(data, false, nullptr);
-  EXPECT_FALSE(HasWriteBlockedStreams());
-
-  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
-                                      1234);
-
-  stream->OnWindowUpdateFrame(window_update);
-  // Verify stream is marked connection level write blocked.
-  EXPECT_TRUE(HasWriteBlockedStreams());
-  EXPECT_TRUE(stream->HasBufferedData());
-}
-
-// Regression test for b/73282665.
-TEST_P(QuicStreamTest,
-       MarkConnectionLevelWriteBlockedOnWindowUpdateFrameWithNoBufferedData) {
-  Initialize();
-
-  // Set the config to a small value so that a newly created stream has small
-  // send flow control window.
-  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
-                                                            100);
-  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-      session_->config(), 100);
-  auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
-                                   GetParam().transport_version, 2),
-                               session_.get(), BIDIRECTIONAL);
-  session_->ActivateStream(absl::WrapUnique(stream));
-
-  std::string data(100, '.');
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*session_, WriteControlFrame(_, _))
-      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
-  stream->WriteOrBufferData(data, false, nullptr);
-  EXPECT_FALSE(HasWriteBlockedStreams());
-
-  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
-                                      120);
-  stream->OnWindowUpdateFrame(window_update);
-  EXPECT_FALSE(stream->HasBufferedData());
-  // Verify stream is marked as blocked although there is no buffered data.
-  EXPECT_TRUE(HasWriteBlockedStreams());
-}
-
-TEST_P(QuicStreamTest, RetransmitStreamData) {
-  Initialize();
-  InSequence s;
-
-  // Send [0, 18) with fin.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
-      .Times(2)
-      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  stream_->WriteOrBufferData(kData1, false, nullptr);
-  stream_->WriteOrBufferData(kData1, true, nullptr);
-  // Ack [10, 13).
-  QuicByteCount newly_acked_length = 0;
-  stream_->OnStreamFrameAcked(10, 3, false, QuicTime::Delta::Zero(),
-                              QuicTime::Zero(), &newly_acked_length);
-  EXPECT_EQ(3u, newly_acked_length);
-  // Retransmit [0, 18) with fin, and only [0, 8) is consumed.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
-      .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN,
-                                     NOT_RETRANSMISSION, absl::nullopt);
-      }));
-  EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
-
-  // Retransmit [0, 18) with fin, and all is consumed.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 5, 13, FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_TRUE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
-
-  // Retransmit [0, 8) with fin, and all is consumed.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 8, 0, NO_FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 0, 18, FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_TRUE(stream_->RetransmitStreamData(0, 8, true, PTO_RETRANSMISSION));
-}
-
-TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresRetransmitLostData) {
-  Initialize();
-
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  std::string body(200, 'a');
-  stream_->WriteOrBufferData(body, true, nullptr);
-
-  // Set TTL to be 1 s.
-  QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
-  ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
-  // Verify data gets retransmitted because TTL does not expire.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 100, 0, NO_FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_TRUE(stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION));
-  stream_->OnStreamFrameLost(100, 100, true);
-  EXPECT_TRUE(stream_->HasPendingRetransmission());
-
-  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  // Verify stream gets reset because TTL expires.
-  if (session_->version().UsesHttp3()) {
-    EXPECT_CALL(*session_,
-                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
-                                                 QUIC_STREAM_TTL_EXPIRED)))
-        .Times(1);
-  }
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
-      .Times(1);
-  stream_->OnCanWrite();
-}
-
-TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresEarlyRetransmitData) {
-  Initialize();
-
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
-      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  std::string body(200, 'a');
-  stream_->WriteOrBufferData(body, true, nullptr);
-
-  // Set TTL to be 1 s.
-  QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
-  ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
-
-  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  // Verify stream gets reset because TTL expires.
-  if (session_->version().UsesHttp3()) {
-    EXPECT_CALL(*session_,
-                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
-                                                 QUIC_STREAM_TTL_EXPIRED)))
-        .Times(1);
-  }
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
-      .Times(1);
-  stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION);
-}
-
-// Test that OnStreamReset does one-way (read) closes if version 99, two way
-// (read and write) if not version 99.
-TEST_P(QuicStreamTest, OnStreamResetReadOrReadWrite) {
-  Initialize();
-  EXPECT_FALSE(stream_->write_side_closed());
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    // Version 99/IETF QUIC should close just the read side.
-    EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
-    EXPECT_FALSE(stream_->write_side_closed());
-  } else {
-    // Google QUIC should close both sides of the stream.
-    EXPECT_TRUE(stream_->write_side_closed());
-    EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
-  }
-}
-
-TEST_P(QuicStreamTest, WindowUpdateForReadOnlyStream) {
-  Initialize();
-
-  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
-      connection_->transport_version(), Perspective::IS_CLIENT);
-  TestStream stream(stream_id, session_.get(), READ_UNIDIRECTIONAL);
-  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
-                                            0);
-  EXPECT_CALL(
-      *connection_,
-      CloseConnection(
-          QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
-          "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
-  stream.OnWindowUpdateFrame(window_update_frame);
-}
-
-TEST_P(QuicStreamTest, RstStreamFrameChangesCloseOffset) {
-  Initialize();
-
-  QuicStreamFrame stream_frame(stream_->id(), true, 0, "abc");
-  EXPECT_CALL(*stream_, OnDataAvailable());
-  stream_->OnStreamFrame(stream_frame);
-  QuicRstStreamFrame rst(kInvalidControlFrameId, stream_->id(),
-                         QUIC_STREAM_CANCELLED, 0u);
-
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_MULTIPLE_OFFSET, _, _));
-  stream_->OnStreamReset(rst);
-}
-
-// Regression test for b/176073284.
-TEST_P(QuicStreamTest, EmptyStreamFrameWithNoFin) {
-  Initialize();
-  QuicStreamFrame empty_stream_frame(stream_->id(), false, 0, "");
-  if (stream_->version().HasIetfQuicFrames()) {
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _))
-        .Times(0);
-  } else {
-    EXPECT_CALL(*connection_,
-                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _));
-  }
-  EXPECT_CALL(*stream_, OnDataAvailable()).Times(0);
-  stream_->OnStreamFrame(empty_stream_frame);
-}
-
-TEST_P(QuicStreamTest, SendRstWithCustomIetfCode) {
-  Initialize();
-  QuicResetStreamError error(QUIC_STREAM_CANCELLED, 0x1234abcd);
-  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, error, _))
-      .Times(1);
-  stream_->ResetWithError(error);
-  EXPECT_TRUE(rst_sent());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_sustained_bandwidth_recorder.cc b/quic/core/quic_sustained_bandwidth_recorder.cc
deleted file mode 100644
index 178c4c6..0000000
--- a/quic/core/quic_sustained_bandwidth_recorder.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-QuicSustainedBandwidthRecorder::QuicSustainedBandwidthRecorder()
-    : has_estimate_(false),
-      is_recording_(false),
-      bandwidth_estimate_recorded_during_slow_start_(false),
-      bandwidth_estimate_(QuicBandwidth::Zero()),
-      max_bandwidth_estimate_(QuicBandwidth::Zero()),
-      max_bandwidth_timestamp_(0),
-      start_time_(QuicTime::Zero()) {}
-
-void QuicSustainedBandwidthRecorder::RecordEstimate(bool in_recovery,
-                                                    bool in_slow_start,
-                                                    QuicBandwidth bandwidth,
-                                                    QuicTime estimate_time,
-                                                    QuicWallTime wall_time,
-                                                    QuicTime::Delta srtt) {
-  if (in_recovery) {
-    is_recording_ = false;
-    QUIC_DVLOG(1) << "Stopped recording at: "
-                  << estimate_time.ToDebuggingValue();
-    return;
-  }
-
-  if (!is_recording_) {
-    // This is the first estimate of a new recording period.
-    start_time_ = estimate_time;
-    is_recording_ = true;
-    QUIC_DVLOG(1) << "Started recording at: " << start_time_.ToDebuggingValue();
-    return;
-  }
-
-  // If we have been recording for at least 3 * srtt, then record the latest
-  // bandwidth estimate as a valid sustained bandwidth estimate.
-  if (estimate_time - start_time_ >= 3 * srtt) {
-    has_estimate_ = true;
-    bandwidth_estimate_recorded_during_slow_start_ = in_slow_start;
-    bandwidth_estimate_ = bandwidth;
-    QUIC_DVLOG(1) << "New sustained bandwidth estimate (KBytes/s): "
-                  << bandwidth_estimate_.ToKBytesPerSecond();
-  }
-
-  // Check for an increase in max bandwidth.
-  if (bandwidth > max_bandwidth_estimate_) {
-    max_bandwidth_estimate_ = bandwidth;
-    max_bandwidth_timestamp_ = wall_time.ToUNIXSeconds();
-    QUIC_DVLOG(1) << "New max bandwidth estimate (KBytes/s): "
-                  << max_bandwidth_estimate_.ToKBytesPerSecond();
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_sustained_bandwidth_recorder.h b/quic/core/quic_sustained_bandwidth_recorder.h
deleted file mode 100644
index f1fdfeb..0000000
--- a/quic/core/quic_sustained_bandwidth_recorder.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
-#define QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-namespace test {
-class QuicSustainedBandwidthRecorderPeer;
-}  // namespace test
-
-// This class keeps track of a sustained bandwidth estimate to ultimately send
-// to the client in a server config update message. A sustained bandwidth
-// estimate is only marked as valid if the QuicSustainedBandwidthRecorder has
-// been given uninterrupted reliable estimates over a certain period of time.
-class QUIC_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
- public:
-  QuicSustainedBandwidthRecorder();
-  QuicSustainedBandwidthRecorder(const QuicSustainedBandwidthRecorder&) =
-      delete;
-  QuicSustainedBandwidthRecorder& operator=(
-      const QuicSustainedBandwidthRecorder&) = delete;
-
-  // As long as |in_recovery| is consistently false, multiple calls to this
-  // method over a 3 * srtt period results in storage of a valid sustained
-  // bandwidth estimate.
-  // |time_now| is used as a max bandwidth timestamp if needed.
-  void RecordEstimate(bool in_recovery,
-                      bool in_slow_start,
-                      QuicBandwidth bandwidth,
-                      QuicTime estimate_time,
-                      QuicWallTime wall_time,
-                      QuicTime::Delta srtt);
-
-  bool HasEstimate() const { return has_estimate_; }
-
-  QuicBandwidth BandwidthEstimate() const {
-    QUICHE_DCHECK(has_estimate_);
-    return bandwidth_estimate_;
-  }
-
-  QuicBandwidth MaxBandwidthEstimate() const {
-    QUICHE_DCHECK(has_estimate_);
-    return max_bandwidth_estimate_;
-  }
-
-  int64_t MaxBandwidthTimestamp() const {
-    QUICHE_DCHECK(has_estimate_);
-    return max_bandwidth_timestamp_;
-  }
-
-  bool EstimateRecordedDuringSlowStart() const {
-    QUICHE_DCHECK(has_estimate_);
-    return bandwidth_estimate_recorded_during_slow_start_;
-  }
-
- private:
-  friend class test::QuicSustainedBandwidthRecorderPeer;
-
-  // True if we have been able to calculate sustained bandwidth, over at least
-  // one recording period (3 * rtt).
-  bool has_estimate_;
-
-  // True if the last call to RecordEstimate had a reliable estimate.
-  bool is_recording_;
-
-  // True if the current sustained bandwidth estimate was generated while in
-  // slow start.
-  bool bandwidth_estimate_recorded_during_slow_start_;
-
-  // The latest sustained bandwidth estimate.
-  QuicBandwidth bandwidth_estimate_;
-
-  // The maximum sustained bandwidth seen over the lifetime of the connection.
-  QuicBandwidth max_bandwidth_estimate_;
-
-  // Timestamp indicating when the max_bandwidth_estimate_ was seen.
-  int64_t max_bandwidth_timestamp_;
-
-  // Timestamp marking the beginning of the latest recording period.
-  QuicTime start_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
diff --git a/quic/core/quic_sustained_bandwidth_recorder_test.cc b/quic/core/quic_sustained_bandwidth_recorder_test.cc
deleted file mode 100644
index 1231ee1..0000000
--- a/quic/core/quic_sustained_bandwidth_recorder_test.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-
-#include "quic/core/quic_bandwidth.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicSustainedBandwidthRecorderTest : public QuicTest {};
-
-TEST_F(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) {
-  QuicSustainedBandwidthRecorder recorder;
-  EXPECT_FALSE(recorder.HasEstimate());
-
-  QuicTime estimate_time = QuicTime::Zero();
-  QuicWallTime wall_time = QuicWallTime::Zero();
-  QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
-  const int kBandwidthBitsPerSecond = 12345678;
-  QuicBandwidth bandwidth =
-      QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
-
-  bool in_recovery = false;
-  bool in_slow_start = false;
-
-  // This triggers recording, but should not yield a valid estimate yet.
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  EXPECT_FALSE(recorder.HasEstimate());
-
-  // Send a second reading, again this should not result in a valid estimate,
-  // as not enough time has passed.
-  estimate_time = estimate_time + srtt;
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  EXPECT_FALSE(recorder.HasEstimate());
-
-  // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
-  estimate_time = estimate_time + srtt;
-  estimate_time = estimate_time + srtt;
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  EXPECT_TRUE(recorder.HasEstimate());
-  EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
-  EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
-
-  // Resetting, and sending a different estimate will only change output after
-  // a further 3 * kSRTT has passed.
-  QuicBandwidth second_bandwidth =
-      QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond);
-  // Reset the recorder by passing in a measurement while in recovery.
-  in_recovery = true;
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  in_recovery = false;
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
-
-  estimate_time = estimate_time + 3 * srtt;
-  const int64_t kSeconds = 556677;
-  QuicWallTime second_bandwidth_wall_time =
-      QuicWallTime::FromUNIXSeconds(kSeconds);
-  recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth,
-                          estimate_time, second_bandwidth_wall_time, srtt);
-  EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth);
-  EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
-  EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
-
-  // Reset again, this time recording a lower bandwidth than before.
-  QuicBandwidth third_bandwidth =
-      QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond);
-  // Reset the recorder by passing in an unreliable measurement.
-  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
-                          estimate_time, wall_time, srtt);
-  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
-                          estimate_time, wall_time, srtt);
-  EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
-
-  estimate_time = estimate_time + 3 * srtt;
-  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
-                          estimate_time, wall_time, srtt);
-  EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
-
-  // Max bandwidth should not have changed.
-  EXPECT_LT(third_bandwidth, second_bandwidth);
-  EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth);
-  EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
-}
-
-TEST_F(QuicSustainedBandwidthRecorderTest, SlowStart) {
-  // Verify that slow start status is correctly recorded.
-  QuicSustainedBandwidthRecorder recorder;
-  EXPECT_FALSE(recorder.HasEstimate());
-
-  QuicTime estimate_time = QuicTime::Zero();
-  QuicWallTime wall_time = QuicWallTime::Zero();
-  QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
-  const int kBandwidthBitsPerSecond = 12345678;
-  QuicBandwidth bandwidth =
-      QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
-
-  bool in_recovery = false;
-  bool in_slow_start = true;
-
-  // This triggers recording, but should not yield a valid estimate yet.
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-
-  // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
-  estimate_time = estimate_time + 3 * srtt;
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  EXPECT_TRUE(recorder.HasEstimate());
-  EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart());
-
-  // Now send another estimate, this time not in slow start.
-  estimate_time = estimate_time + 3 * srtt;
-  in_slow_start = false;
-  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
-                          wall_time, srtt);
-  EXPECT_TRUE(recorder.HasEstimate());
-  EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_syscall_wrapper.cc b/quic/core/quic_syscall_wrapper.cc
deleted file mode 100644
index a98331f..0000000
--- a/quic/core/quic_syscall_wrapper.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_syscall_wrapper.h"
-
-#include <atomic>
-#include <cerrno>
-
-namespace quic {
-namespace {
-std::atomic<QuicSyscallWrapper*> global_syscall_wrapper(new QuicSyscallWrapper);
-}  // namespace
-
-ssize_t QuicSyscallWrapper::Sendmsg(int sockfd, const msghdr* msg, int flags) {
-  return ::sendmsg(sockfd, msg, flags);
-}
-
-int QuicSyscallWrapper::Sendmmsg(int sockfd,
-                                 mmsghdr* msgvec,
-                                 unsigned int vlen,
-                                 int flags) {
-#if defined(__linux__) && !defined(__ANDROID__)
-  return ::sendmmsg(sockfd, msgvec, vlen, flags);
-#else
-  errno = ENOSYS;
-  return -1;
-#endif
-}
-
-QuicSyscallWrapper* GetGlobalSyscallWrapper() {
-  return global_syscall_wrapper.load();
-}
-
-void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper) {
-  global_syscall_wrapper.store(wrapper);
-}
-
-ScopedGlobalSyscallWrapperOverride::ScopedGlobalSyscallWrapperOverride(
-    QuicSyscallWrapper* wrapper_in_scope)
-    : original_wrapper_(GetGlobalSyscallWrapper()) {
-  SetGlobalSyscallWrapper(wrapper_in_scope);
-}
-
-ScopedGlobalSyscallWrapperOverride::~ScopedGlobalSyscallWrapperOverride() {
-  SetGlobalSyscallWrapper(original_wrapper_);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_syscall_wrapper.h b/quic/core/quic_syscall_wrapper.h
deleted file mode 100644
index 5b99d0a..0000000
--- a/quic/core/quic_syscall_wrapper.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
-
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include "quic/platform/api/quic_export.h"
-
-struct mmsghdr;
-namespace quic {
-
-// QuicSyscallWrapper is a pass-through proxy to the real syscalls.
-class QUIC_EXPORT_PRIVATE QuicSyscallWrapper {
- public:
-  virtual ~QuicSyscallWrapper() = default;
-
-  virtual ssize_t Sendmsg(int sockfd, const msghdr* msg, int flags);
-
-  virtual int Sendmmsg(int sockfd,
-                       mmsghdr* msgvec,
-                       unsigned int vlen,
-                       int flags);
-};
-
-// A global instance of QuicSyscallWrapper, used by some socket util functions.
-QuicSyscallWrapper* GetGlobalSyscallWrapper();
-
-// Change the global QuicSyscallWrapper to |wrapper|, for testing.
-void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper);
-
-// ScopedGlobalSyscallWrapperOverride changes the global QuicSyscallWrapper
-// during its lifetime, for testing.
-class QUIC_EXPORT_PRIVATE ScopedGlobalSyscallWrapperOverride {
- public:
-  explicit ScopedGlobalSyscallWrapperOverride(
-      QuicSyscallWrapper* wrapper_in_scope);
-  ~ScopedGlobalSyscallWrapperOverride();
-
- private:
-  QuicSyscallWrapper* original_wrapper_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
diff --git a/quic/core/quic_tag.cc b/quic/core/quic_tag.cc
deleted file mode 100644
index b5f64f1..0000000
--- a/quic/core/quic_tag.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_tag.h"
-
-#include <algorithm>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_split.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-bool FindMutualQuicTag(const QuicTagVector& our_tags,
-                       const QuicTagVector& their_tags,
-                       QuicTag* out_result,
-                       size_t* out_index) {
-  const size_t num_our_tags = our_tags.size();
-  const size_t num_their_tags = their_tags.size();
-  for (size_t i = 0; i < num_our_tags; i++) {
-    for (size_t j = 0; j < num_their_tags; j++) {
-      if (our_tags[i] == their_tags[j]) {
-        *out_result = our_tags[i];
-        if (out_index != nullptr) {
-          *out_index = j;
-        }
-        return true;
-      }
-    }
-  }
-
-  return false;
-}
-
-std::string QuicTagToString(QuicTag tag) {
-  if (tag == 0) {
-    return "0";
-  }
-  char chars[sizeof tag];
-  bool ascii = true;
-  const QuicTag orig_tag = tag;
-
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) {
-    chars[i] = static_cast<char>(tag);
-    if ((chars[i] == 0 || chars[i] == '\xff') &&
-        i == ABSL_ARRAYSIZE(chars) - 1) {
-      chars[i] = ' ';
-    }
-    if (!isprint(static_cast<unsigned char>(chars[i]))) {
-      ascii = false;
-      break;
-    }
-    tag >>= 8;
-  }
-
-  if (ascii) {
-    return std::string(chars, sizeof(chars));
-  }
-
-  return absl::BytesToHexString(absl::string_view(
-      reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
-}
-
-uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
-  return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
-         static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
-}
-
-bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
-  return std::find(tag_vector.begin(), tag_vector.end(), tag) !=
-         tag_vector.end();
-}
-
-QuicTag ParseQuicTag(absl::string_view tag_string) {
-  quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
-  std::string tag_bytes;
-  if (tag_string.length() == 8) {
-    tag_bytes = absl::HexStringToBytes(tag_string);
-    tag_string = tag_bytes;
-  }
-  QuicTag tag = 0;
-  // Iterate over every character from right to left.
-  for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) {
-    // The cast here is required on platforms where char is signed.
-    unsigned char token_char = static_cast<unsigned char>(*it);
-    tag <<= 8;
-    tag |= token_char;
-  }
-  return tag;
-}
-
-QuicTagVector ParseQuicTagVector(absl::string_view tags_string) {
-  QuicTagVector tag_vector;
-  quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tags_string);
-  if (!tags_string.empty()) {
-    std::vector<absl::string_view> tag_strings =
-        absl::StrSplit(tags_string, ',');
-    for (absl::string_view tag_string : tag_strings) {
-      tag_vector.push_back(ParseQuicTag(tag_string));
-    }
-  }
-  return tag_vector;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_tag.h b/quic/core/quic_tag.h
deleted file mode 100644
index 1dfc754..0000000
--- a/quic/core/quic_tag.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TAG_H_
-#define QUICHE_QUIC_CORE_QUIC_TAG_H_
-
-#include <cstdint>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A QuicTag is a 32-bit used as identifiers in the QUIC handshake.  The use of
-// a uint32_t seeks to provide a balance between the tyranny of magic number
-// registries and the verbosity of strings. As far as the wire protocol is
-// concerned, these are opaque, 32-bit values.
-//
-// Tags will often be referred to by their ASCII equivalent, e.g. EXMP. This is
-// just a mnemonic for the value 0x504d5845 (little-endian version of the ASCII
-// string E X M P).
-using QuicTag = uint32_t;
-using QuicTagValueMap = std::map<QuicTag, std::string>;
-using QuicTagVector = std::vector<QuicTag>;
-
-// MakeQuicTag returns a value given the four bytes. For example:
-//   MakeQuicTag('C', 'H', 'L', 'O');
-QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(uint8_t a, uint8_t b, uint8_t c,
-                                        uint8_t d);
-
-// Returns true if |tag_vector| contains |tag|.
-QUIC_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
-                                         QuicTag tag);
-
-// Sets |out_result| to the first tag in |our_tags| that is also in |their_tags|
-// and returns true. If there is no intersection it returns false.
-//
-// If |out_index| is non-nullptr and a match is found then the index of that
-// match in |their_tags| is written to |out_index|.
-QUIC_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
-                                           const QuicTagVector& their_tags,
-                                           QuicTag* out_result,
-                                           size_t* out_index);
-
-// A utility function that converts a tag to a string. It will try to maintain
-// the human friendly name if possible (i.e. kABCD -> "ABCD"), or will just
-// treat it as a number if not.
-QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
-
-// Utility function that converts a string of the form "ABCD" to its
-// corresponding QuicTag. Note that tags that are less than four characters
-// long are right-padded with zeroes. Tags that contain non-ASCII characters
-// are represented as 8-character-long hexadecimal strings.
-QUIC_EXPORT_PRIVATE QuicTag ParseQuicTag(absl::string_view tag_string);
-
-// Utility function that converts a string of the form "ABCD,EFGH" to a vector
-// of the form {kABCD,kEFGH}. Note the caveats on ParseQuicTag.
-QUIC_EXPORT_PRIVATE QuicTagVector
-ParseQuicTagVector(absl::string_view tags_string);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TAG_H_
diff --git a/quic/core/quic_tag_test.cc b/quic/core/quic_tag_test.cc
deleted file mode 100644
index 71617f3..0000000
--- a/quic/core/quic_tag_test.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_tag.h"
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicTagTest : public QuicTest {};
-
-TEST_F(QuicTagTest, TagToString) {
-  EXPECT_EQ("SCFG", QuicTagToString(kSCFG));
-  EXPECT_EQ("SNO ", QuicTagToString(kServerNonceTag));
-  EXPECT_EQ("CRT ", QuicTagToString(kCertificateTag));
-  EXPECT_EQ("CHLO", QuicTagToString(MakeQuicTag('C', 'H', 'L', 'O')));
-  // A tag that contains a non-printing character will be printed as hex.
-  EXPECT_EQ("43484c1f", QuicTagToString(MakeQuicTag('C', 'H', 'L', '\x1f')));
-}
-
-TEST_F(QuicTagTest, MakeQuicTag) {
-  QuicTag tag = MakeQuicTag('A', 'B', 'C', 'D');
-  char bytes[4];
-  memcpy(bytes, &tag, 4);
-  EXPECT_EQ('A', bytes[0]);
-  EXPECT_EQ('B', bytes[1]);
-  EXPECT_EQ('C', bytes[2]);
-  EXPECT_EQ('D', bytes[3]);
-}
-
-TEST_F(QuicTagTest, ParseQuicTag) {
-  QuicTag tag_abcd = MakeQuicTag('A', 'B', 'C', 'D');
-  EXPECT_EQ(ParseQuicTag("ABCD"), tag_abcd);
-  EXPECT_EQ(ParseQuicTag("ABCDE"), tag_abcd);
-  QuicTag tag_efgh = MakeQuicTag('E', 'F', 'G', 'H');
-  EXPECT_EQ(ParseQuicTag("EFGH"), tag_efgh);
-  QuicTag tag_ijk = MakeQuicTag('I', 'J', 'K', 0);
-  EXPECT_EQ(ParseQuicTag("IJK"), tag_ijk);
-  QuicTag tag_l = MakeQuicTag('L', 0, 0, 0);
-  EXPECT_EQ(ParseQuicTag("L"), tag_l);
-  QuicTag tag_hex = MakeQuicTag('M', 'N', 'O', static_cast<char>(255));
-  EXPECT_EQ(ParseQuicTag("4d4e4fff"), tag_hex);
-  EXPECT_EQ(ParseQuicTag("4D4E4FFF"), tag_hex);
-  QuicTag tag_with_numbers = MakeQuicTag('P', 'Q', '1', '2');
-  EXPECT_EQ(ParseQuicTag("PQ12"), tag_with_numbers);
-  QuicTag tag_with_custom_chars = MakeQuicTag('r', '$', '_', '7');
-  EXPECT_EQ(ParseQuicTag("r$_7"), tag_with_custom_chars);
-  QuicTag tag_zero = 0;
-  EXPECT_EQ(ParseQuicTag(""), tag_zero);
-  QuicTagVector tag_vector;
-  EXPECT_EQ(ParseQuicTagVector(""), tag_vector);
-  EXPECT_EQ(ParseQuicTagVector(" "), tag_vector);
-  tag_vector.push_back(tag_abcd);
-  EXPECT_EQ(ParseQuicTagVector("ABCD"), tag_vector);
-  tag_vector.push_back(tag_efgh);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH"), tag_vector);
-  tag_vector.push_back(tag_ijk);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK"), tag_vector);
-  tag_vector.push_back(tag_l);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L"), tag_vector);
-  tag_vector.push_back(tag_hex);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff"), tag_vector);
-  tag_vector.push_back(tag_with_numbers);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12"), tag_vector);
-  tag_vector.push_back(tag_with_custom_chars);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7"),
-            tag_vector);
-  tag_vector.push_back(tag_zero);
-  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7,"),
-            tag_vector);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_time.cc b/quic/core/quic_time.cc
deleted file mode 100644
index 08e0906..0000000
--- a/quic/core/quic_time.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time.h"
-
-#include <cinttypes>
-#include <cstdlib>
-#include <limits>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-std::string QuicTime::Delta::ToDebuggingValue() const {
-  constexpr int64_t kMillisecondInMicroseconds = 1000;
-  constexpr int64_t kSecondInMicroseconds = 1000 * kMillisecondInMicroseconds;
-
-  int64_t absolute_value = std::abs(time_offset_);
-
-  // For debugging purposes, always display the value with the highest precision
-  // available.
-  if (absolute_value >= kSecondInMicroseconds &&
-      absolute_value % kSecondInMicroseconds == 0) {
-    return absl::StrCat(time_offset_ / kSecondInMicroseconds, "s");
-  }
-  if (absolute_value >= kMillisecondInMicroseconds &&
-      absolute_value % kMillisecondInMicroseconds == 0) {
-    return absl::StrCat(time_offset_ / kMillisecondInMicroseconds, "ms");
-  }
-  return absl::StrCat(time_offset_, "us");
-}
-
-uint64_t QuicWallTime::ToUNIXSeconds() const {
-  return microseconds_ / 1000000;
-}
-
-uint64_t QuicWallTime::ToUNIXMicroseconds() const {
-  return microseconds_;
-}
-
-bool QuicWallTime::IsAfter(QuicWallTime other) const {
-  return microseconds_ > other.microseconds_;
-}
-
-bool QuicWallTime::IsBefore(QuicWallTime other) const {
-  return microseconds_ < other.microseconds_;
-}
-
-bool QuicWallTime::IsZero() const {
-  return microseconds_ == 0;
-}
-
-QuicTime::Delta QuicWallTime::AbsoluteDifference(QuicWallTime other) const {
-  uint64_t d;
-
-  if (microseconds_ > other.microseconds_) {
-    d = microseconds_ - other.microseconds_;
-  } else {
-    d = other.microseconds_ - microseconds_;
-  }
-
-  if (d > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
-    d = std::numeric_limits<int64_t>::max();
-  }
-  return QuicTime::Delta::FromMicroseconds(d);
-}
-
-QuicWallTime QuicWallTime::Add(QuicTime::Delta delta) const {
-  uint64_t microseconds = microseconds_ + delta.ToMicroseconds();
-  if (microseconds < microseconds_) {
-    microseconds = std::numeric_limits<uint64_t>::max();
-  }
-  return QuicWallTime(microseconds);
-}
-
-// TODO(ianswett) Test this.
-QuicWallTime QuicWallTime::Subtract(QuicTime::Delta delta) const {
-  uint64_t microseconds = microseconds_ - delta.ToMicroseconds();
-  if (microseconds > microseconds_) {
-    microseconds = 0;
-  }
-  return QuicWallTime(microseconds);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_time.h b/quic/core/quic_time.h
deleted file mode 100644
index a5fc3ab..0000000
--- a/quic/core/quic_time.h
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// QuicTime represents one point in time, stored in microsecond resolution.
-// QuicTime is monotonically increasing, even across system clock adjustments.
-// The epoch (time 0) of QuicTime is unspecified.
-//
-// This implementation wraps a int64_t of usec since the epoch.  While
-// the epoch is the Unix epoch, do not depend on this fact because other
-// implementations, like Chrome's, do NOT have the same epoch.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TIME_H_
-#define QUICHE_QUIC_CORE_QUIC_TIME_H_
-
-#include <cmath>
-#include <cstdint>
-#include <limits>
-#include <ostream>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-
-// TODO(vasilvv): replace with ABSL_MUST_USE_RESULT once we're using absl.
-#if defined(__clang__)
-#define QUIC_TIME_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#else
-#define QUIC_TIME_WARN_UNUSED_RESULT
-#endif /* defined(__clang__) */
-
-namespace quic {
-
-class QuicClock;
-
-// A QuicTime is a purely relative time. QuicTime values from different clocks
-// cannot be compared to each other. If you need an absolute time, see
-// QuicWallTime, below.
-class QUIC_EXPORT_PRIVATE QuicTime {
- public:
-  // A QuicTime::Delta represents the signed difference between two points in
-  // time, stored in microsecond resolution.
-  class QUIC_EXPORT_PRIVATE Delta {
-   public:
-    // Create a object with an offset of 0.
-    static constexpr Delta Zero() { return Delta(0); }
-
-    // Create a object with infinite offset time.
-    static constexpr Delta Infinite() { return Delta(kQuicInfiniteTimeUs); }
-
-    // Converts a number of seconds to a time offset.
-    static constexpr Delta FromSeconds(int64_t secs) {
-      return Delta(secs * 1000 * 1000);
-    }
-
-    // Converts a number of milliseconds to a time offset.
-    static constexpr Delta FromMilliseconds(int64_t ms) {
-      return Delta(ms * 1000);
-    }
-
-    // Converts a number of microseconds to a time offset.
-    static constexpr Delta FromMicroseconds(int64_t us) { return Delta(us); }
-
-    // Converts the time offset to a rounded number of seconds.
-    int64_t ToSeconds() const { return time_offset_ / 1000 / 1000; }
-
-    // Converts the time offset to a rounded number of milliseconds.
-    int64_t ToMilliseconds() const { return time_offset_ / 1000; }
-
-    // Converts the time offset to a rounded number of microseconds.
-    int64_t ToMicroseconds() const { return time_offset_; }
-
-    bool IsZero() const { return time_offset_ == 0; }
-
-    bool IsInfinite() const { return time_offset_ == kQuicInfiniteTimeUs; }
-
-    std::string ToDebuggingValue() const;
-
-   private:
-    friend inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs);
-    friend inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs);
-    friend inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs);
-    friend inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs);
-
-    friend inline QuicTime::Delta operator+(QuicTime::Delta lhs,
-                                            QuicTime::Delta rhs);
-    friend inline QuicTime::Delta operator-(QuicTime::Delta lhs,
-                                            QuicTime::Delta rhs);
-    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs);
-    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs);
-
-    friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
-    friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
-    friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
-
-    static const int64_t kQuicInfiniteTimeUs =
-        std::numeric_limits<int64_t>::max();
-
-    explicit constexpr Delta(int64_t time_offset) : time_offset_(time_offset) {}
-
-    int64_t time_offset_;
-    friend class QuicTime;
-  };
-
-  // Creates a new QuicTime with an internal value of 0.  IsInitialized()
-  // will return false for these times.
-  static constexpr QuicTime Zero() { return QuicTime(0); }
-
-  // Creates a new QuicTime with an infinite time.
-  static constexpr QuicTime Infinite() {
-    return QuicTime(Delta::kQuicInfiniteTimeUs);
-  }
-
-  QuicTime(const QuicTime& other) = default;
-
-  QuicTime& operator=(const QuicTime& other) {
-    time_ = other.time_;
-    return *this;
-  }
-
-  // Produce the internal value to be used when logging.  This value
-  // represents the number of microseconds since some epoch.  It may
-  // be the UNIX epoch on some platforms.  On others, it may
-  // be a CPU ticks based value.
-  int64_t ToDebuggingValue() const { return time_; }
-
-  bool IsInitialized() const { return 0 != time_; }
-
- private:
-  friend class QuicClock;
-
-  friend inline bool operator==(QuicTime lhs, QuicTime rhs);
-  friend inline bool operator<(QuicTime lhs, QuicTime rhs);
-  friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
-  friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
-  friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
-
-  explicit constexpr QuicTime(int64_t time) : time_(time) {}
-
-  int64_t time_;
-};
-
-// A QuicWallTime represents an absolute time that is globally consistent. In
-// practice, clock-skew means that comparing values from different machines
-// requires some flexibility.
-class QUIC_EXPORT_PRIVATE QuicWallTime {
- public:
-  // FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
-  // since the UNIX epoch.
-  static constexpr QuicWallTime FromUNIXSeconds(uint64_t seconds) {
-    return QuicWallTime(seconds * 1000000);
-  }
-
-  static constexpr QuicWallTime FromUNIXMicroseconds(uint64_t microseconds) {
-    return QuicWallTime(microseconds);
-  }
-
-  // Zero returns a QuicWallTime set to zero. IsZero will return true for this
-  // value.
-  static constexpr QuicWallTime Zero() { return QuicWallTime(0); }
-
-  // Returns the number of seconds since the UNIX epoch.
-  uint64_t ToUNIXSeconds() const;
-  // Returns the number of microseconds since the UNIX epoch.
-  uint64_t ToUNIXMicroseconds() const;
-
-  bool IsAfter(QuicWallTime other) const;
-  bool IsBefore(QuicWallTime other) const;
-
-  // IsZero returns true if this object is the result of calling |Zero|.
-  bool IsZero() const;
-
-  // AbsoluteDifference returns the absolute value of the time difference
-  // between |this| and |other|.
-  QuicTime::Delta AbsoluteDifference(QuicWallTime other) const;
-
-  // Add returns a new QuicWallTime that represents the time of |this| plus
-  // |delta|.
-  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime Add(QuicTime::Delta delta) const;
-
-  // Subtract returns a new QuicWallTime that represents the time of |this|
-  // minus |delta|.
-  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime
-  Subtract(QuicTime::Delta delta) const;
-
-  bool operator==(const QuicWallTime& other) const {
-    return microseconds_ == other.microseconds_;
-  }
-
-  QuicTime::Delta operator-(const QuicWallTime& rhs) const {
-    return QuicTime::Delta::FromMicroseconds(microseconds_ - rhs.microseconds_);
-  }
-
- private:
-  explicit constexpr QuicWallTime(uint64_t microseconds)
-      : microseconds_(microseconds) {}
-
-  uint64_t microseconds_;
-};
-
-// Non-member relational operators for QuicTime::Delta.
-inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return lhs.time_offset_ == rhs.time_offset_;
-}
-inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return !(lhs == rhs);
-}
-inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return lhs.time_offset_ < rhs.time_offset_;
-}
-inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return rhs < lhs;
-}
-inline bool operator<=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return !(rhs < lhs);
-}
-inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return !(lhs < rhs);
-}
-inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs) {
-  return QuicTime::Delta(lhs.time_offset_ << rhs);
-}
-inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs) {
-  return QuicTime::Delta(lhs.time_offset_ >> rhs);
-}
-
-// Non-member relational operators for QuicTime.
-inline bool operator==(QuicTime lhs, QuicTime rhs) {
-  return lhs.time_ == rhs.time_;
-}
-inline bool operator!=(QuicTime lhs, QuicTime rhs) {
-  return !(lhs == rhs);
-}
-inline bool operator<(QuicTime lhs, QuicTime rhs) {
-  return lhs.time_ < rhs.time_;
-}
-inline bool operator>(QuicTime lhs, QuicTime rhs) {
-  return rhs < lhs;
-}
-inline bool operator<=(QuicTime lhs, QuicTime rhs) {
-  return !(rhs < lhs);
-}
-inline bool operator>=(QuicTime lhs, QuicTime rhs) {
-  return !(lhs < rhs);
-}
-
-// Override stream output operator for gtest or QUICHE_CHECK macros.
-inline std::ostream& operator<<(std::ostream& output, const QuicTime t) {
-  output << t.ToDebuggingValue();
-  return output;
-}
-
-// Non-member arithmetic operators for QuicTime::Delta.
-inline QuicTime::Delta operator+(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return QuicTime::Delta(lhs.time_offset_ + rhs.time_offset_);
-}
-inline QuicTime::Delta operator-(QuicTime::Delta lhs, QuicTime::Delta rhs) {
-  return QuicTime::Delta(lhs.time_offset_ - rhs.time_offset_);
-}
-inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs) {
-  return QuicTime::Delta(lhs.time_offset_ * rhs);
-}
-inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs) {
-  return QuicTime::Delta(static_cast<int64_t>(
-      std::llround(static_cast<double>(lhs.time_offset_) * rhs)));
-}
-inline QuicTime::Delta operator*(int lhs, QuicTime::Delta rhs) {
-  return rhs * lhs;
-}
-inline QuicTime::Delta operator*(double lhs, QuicTime::Delta rhs) {
-  return rhs * lhs;
-}
-
-// Non-member arithmetic operators for QuicTime and QuicTime::Delta.
-inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs) {
-  return QuicTime(lhs.time_ + rhs.time_offset_);
-}
-inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs) {
-  return QuicTime(lhs.time_ - rhs.time_offset_);
-}
-inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs) {
-  return QuicTime::Delta(lhs.time_ - rhs.time_);
-}
-
-// Override stream output operator for gtest.
-inline std::ostream& operator<<(std::ostream& output,
-                                const QuicTime::Delta delta) {
-  output << delta.ToDebuggingValue();
-  return output;
-}
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TIME_H_
diff --git a/quic/core/quic_time_accumulator.h b/quic/core/quic_time_accumulator.h
deleted file mode 100644
index 8680cb6..0000000
--- a/quic/core/quic_time_accumulator.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// QuicTimeAccumulator accumulates elapsed times between Start(s) and Stop(s).
-class QUIC_EXPORT_PRIVATE QuicTimeAccumulator {
-  // TODO(wub): Switch to a data member called kNotRunningSentinel after c++17.
-  static constexpr QuicTime NotRunningSentinel() {
-    return QuicTime::Infinite();
-  }
-
- public:
-  // True if Started and not Stopped.
-  bool IsRunning() const { return last_start_time_ != NotRunningSentinel(); }
-
-  void Start(QuicTime now) {
-    QUICHE_DCHECK(!IsRunning());
-    last_start_time_ = now;
-    QUICHE_DCHECK(IsRunning());
-  }
-
-  void Stop(QuicTime now) {
-    QUICHE_DCHECK(IsRunning());
-    if (now > last_start_time_) {
-      total_elapsed_ = total_elapsed_ + (now - last_start_time_);
-    }
-    last_start_time_ = NotRunningSentinel();
-    QUICHE_DCHECK(!IsRunning());
-  }
-
-  // Get total elapsed time between COMPLETED Start/Stop pairs.
-  QuicTime::Delta GetTotalElapsedTime() const { return total_elapsed_; }
-
-  // Get total elapsed time between COMPLETED Start/Stop pairs, plus, if it is
-  // running, the elapsed time between |last_start_time_| and |now|.
-  QuicTime::Delta GetTotalElapsedTime(QuicTime now) const {
-    if (!IsRunning()) {
-      return total_elapsed_;
-    }
-    if (now <= last_start_time_) {
-      return total_elapsed_;
-    }
-    return total_elapsed_ + (now - last_start_time_);
-  }
-
- private:
-  //
-  //                                       |last_start_time_|
-  //                                         |
-  //                                         V
-  // Start => Stop  =>  Start => Stop  =>  Start
-  // |           |      |           |
-  // |___________|  +   |___________|  =   |total_elapsed_|
-  QuicTime::Delta total_elapsed_ = QuicTime::Delta::Zero();
-  QuicTime last_start_time_ = NotRunningSentinel();
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
diff --git a/quic/core/quic_time_accumulator_test.cc b/quic/core/quic_time_accumulator_test.cc
deleted file mode 100644
index 3598006..0000000
--- a/quic/core/quic_time_accumulator_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-TEST(QuicTimeAccumulator, DefaultConstruct) {
-  MockClock clock;
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicTimeAccumulator acc;
-  EXPECT_FALSE(acc.IsRunning());
-
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
-}
-
-TEST(QuicTimeAccumulator, StartStop) {
-  MockClock clock;
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicTimeAccumulator acc;
-  acc.Start(clock.Now());
-  EXPECT_TRUE(acc.IsRunning());
-
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  acc.Stop(clock.Now());
-  EXPECT_FALSE(acc.IsRunning());
-
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-            acc.GetTotalElapsedTime(clock.Now()));
-
-  acc.Start(clock.Now());
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(15),
-            acc.GetTotalElapsedTime(clock.Now()));
-
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
-            acc.GetTotalElapsedTime(clock.Now()));
-
-  acc.Stop(clock.Now());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
-            acc.GetTotalElapsedTime(clock.Now()));
-}
-
-TEST(QuicTimeAccumulator, ClockStepBackwards) {
-  MockClock clock;
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-
-  QuicTimeAccumulator acc;
-  acc.Start(clock.Now());
-
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-10));
-  acc.Stop(clock.Now());
-  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
-
-  acc.Start(clock.Now());
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(50));
-  acc.Stop(clock.Now());
-
-  acc.Start(clock.Now());
-  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-80));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), acc.GetTotalElapsedTime());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
-            acc.GetTotalElapsedTime(clock.Now()));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_time_test.cc b/quic/core/quic_time_test.cc
deleted file mode 100644
index e5bb285..0000000
--- a/quic/core/quic_time_test.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class QuicTimeDeltaTest : public QuicTest {};
-
-TEST_F(QuicTimeDeltaTest, Zero) {
-  EXPECT_TRUE(QuicTime::Delta::Zero().IsZero());
-  EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
-  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsZero());
-}
-
-TEST_F(QuicTimeDeltaTest, Infinite) {
-  EXPECT_TRUE(QuicTime::Delta::Infinite().IsInfinite());
-  EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
-  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsInfinite());
-}
-
-TEST_F(QuicTimeDeltaTest, FromTo) {
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
-            QuicTime::Delta::FromMicroseconds(1000));
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
-            QuicTime::Delta::FromMilliseconds(1000));
-  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
-            QuicTime::Delta::FromMicroseconds(1000000));
-
-  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
-  EXPECT_EQ(2, QuicTime::Delta::FromMilliseconds(2000).ToSeconds());
-  EXPECT_EQ(1000, QuicTime::Delta::FromMilliseconds(1).ToMicroseconds());
-  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2000).ToMicroseconds(),
-            QuicTime::Delta::FromSeconds(2).ToMicroseconds());
-}
-
-TEST_F(QuicTimeDeltaTest, Add) {
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
-            QuicTime::Delta::Zero() + QuicTime::Delta::FromMilliseconds(2));
-}
-
-TEST_F(QuicTimeDeltaTest, Subtract) {
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1000),
-            QuicTime::Delta::FromMilliseconds(2) -
-                QuicTime::Delta::FromMilliseconds(1));
-}
-
-TEST_F(QuicTimeDeltaTest, Multiply) {
-  int i = 2;
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
-            QuicTime::Delta::FromMilliseconds(2) * i);
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
-            i * QuicTime::Delta::FromMilliseconds(2));
-  double d = 2;
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
-            QuicTime::Delta::FromMilliseconds(2) * d);
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
-            d * QuicTime::Delta::FromMilliseconds(2));
-
-  // Ensure we are rounding correctly within a single-bit level of precision.
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(5),
-            QuicTime::Delta::FromMicroseconds(9) * 0.5);
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
-            QuicTime::Delta::FromMicroseconds(12) * 0.2);
-}
-
-TEST_F(QuicTimeDeltaTest, Max) {
-  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
-            std::max(QuicTime::Delta::FromMicroseconds(1000),
-                     QuicTime::Delta::FromMicroseconds(2000)));
-}
-
-TEST_F(QuicTimeDeltaTest, NotEqual) {
-  EXPECT_TRUE(QuicTime::Delta::FromSeconds(0) !=
-              QuicTime::Delta::FromSeconds(1));
-  EXPECT_FALSE(QuicTime::Delta::FromSeconds(0) !=
-               QuicTime::Delta::FromSeconds(0));
-}
-
-TEST_F(QuicTimeDeltaTest, DebuggingValue) {
-  const QuicTime::Delta one_us = QuicTime::Delta::FromMicroseconds(1);
-  const QuicTime::Delta one_ms = QuicTime::Delta::FromMilliseconds(1);
-  const QuicTime::Delta one_s = QuicTime::Delta::FromSeconds(1);
-
-  EXPECT_EQ("1s", one_s.ToDebuggingValue());
-  EXPECT_EQ("3s", (3 * one_s).ToDebuggingValue());
-  EXPECT_EQ("1ms", one_ms.ToDebuggingValue());
-  EXPECT_EQ("3ms", (3 * one_ms).ToDebuggingValue());
-  EXPECT_EQ("1us", one_us.ToDebuggingValue());
-  EXPECT_EQ("3us", (3 * one_us).ToDebuggingValue());
-
-  EXPECT_EQ("3001us", (3 * one_ms + one_us).ToDebuggingValue());
-  EXPECT_EQ("3001ms", (3 * one_s + one_ms).ToDebuggingValue());
-  EXPECT_EQ("3000001us", (3 * one_s + one_us).ToDebuggingValue());
-}
-
-class QuicTimeTest : public QuicTest {
- protected:
-  MockClock clock_;
-};
-
-TEST_F(QuicTimeTest, Initialized) {
-  EXPECT_FALSE(QuicTime::Zero().IsInitialized());
-  EXPECT_TRUE((QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1))
-                  .IsInitialized());
-}
-
-TEST_F(QuicTimeTest, CopyConstruct) {
-  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
-  EXPECT_NE(time_1, QuicTime(QuicTime::Zero()));
-  EXPECT_EQ(time_1, QuicTime(time_1));
-}
-
-TEST_F(QuicTimeTest, CopyAssignment) {
-  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
-  QuicTime time_2 = QuicTime::Zero();
-  EXPECT_NE(time_1, time_2);
-  time_2 = time_1;
-  EXPECT_EQ(time_1, time_2);
-}
-
-TEST_F(QuicTimeTest, Add) {
-  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
-  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-
-  QuicTime::Delta diff = time_2 - time_1;
-
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), diff);
-  EXPECT_EQ(1000, diff.ToMicroseconds());
-  EXPECT_EQ(1, diff.ToMilliseconds());
-}
-
-TEST_F(QuicTimeTest, Subtract) {
-  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
-  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), time_2 - time_1);
-}
-
-TEST_F(QuicTimeTest, SubtractDelta) {
-  QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-  EXPECT_EQ(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1),
-            time - QuicTime::Delta::FromMilliseconds(1));
-}
-
-TEST_F(QuicTimeTest, Max) {
-  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
-  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-
-  EXPECT_EQ(time_2, std::max(time_1, time_2));
-}
-
-TEST_F(QuicTimeTest, MockClock) {
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-
-  QuicTime now = clock_.ApproximateNow();
-  QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1000);
-
-  EXPECT_EQ(now, time);
-
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  now = clock_.ApproximateNow();
-
-  EXPECT_NE(now, time);
-
-  time = time + QuicTime::Delta::FromMilliseconds(1);
-  EXPECT_EQ(now, time);
-}
-
-TEST_F(QuicTimeTest, LE) {
-  const QuicTime zero = QuicTime::Zero();
-  const QuicTime one = zero + QuicTime::Delta::FromSeconds(1);
-  EXPECT_TRUE(zero <= zero);
-  EXPECT_TRUE(zero <= one);
-  EXPECT_TRUE(one <= one);
-  EXPECT_FALSE(one <= zero);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_time_wait_list_manager.cc b/quic/core/quic_time_wait_list_manager.cc
deleted file mode 100644
index da01d2a..0000000
--- a/quic/core/quic_time_wait_list_manager.cc
+++ /dev/null
@@ -1,503 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time_wait_list_manager.h"
-
-#include <errno.h>
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-// A very simple alarm that just informs the QuicTimeWaitListManager to clean
-// up old connection_ids. This alarm should be cancelled and deleted before
-// the QuicTimeWaitListManager is deleted.
-class ConnectionIdCleanUpAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit ConnectionIdCleanUpAlarm(
-      QuicTimeWaitListManager* time_wait_list_manager)
-      : time_wait_list_manager_(time_wait_list_manager) {}
-  ConnectionIdCleanUpAlarm(const ConnectionIdCleanUpAlarm&) = delete;
-  ConnectionIdCleanUpAlarm& operator=(const ConnectionIdCleanUpAlarm&) = delete;
-
-  void OnAlarm() override {
-    time_wait_list_manager_->CleanUpOldConnectionIds();
-  }
-
- private:
-  // Not owned.
-  QuicTimeWaitListManager* time_wait_list_manager_;
-};
-
-TimeWaitConnectionInfo::TimeWaitConnectionInfo(
-    bool ietf_quic,
-    std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
-    std::vector<QuicConnectionId> active_connection_ids)
-    : TimeWaitConnectionInfo(ietf_quic,
-                             termination_packets,
-                             std::move(active_connection_ids),
-                             QuicTime::Delta::Zero()) {}
-
-TimeWaitConnectionInfo::TimeWaitConnectionInfo(
-    bool ietf_quic,
-    std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
-    std::vector<QuicConnectionId> active_connection_ids,
-    QuicTime::Delta srtt)
-    : ietf_quic(ietf_quic),
-      active_connection_ids(std::move(active_connection_ids)),
-      srtt(srtt) {
-  if (termination_packets != nullptr) {
-    this->termination_packets.swap(*termination_packets);
-  }
-}
-
-QuicTimeWaitListManager::QuicTimeWaitListManager(
-    QuicPacketWriter* writer,
-    Visitor* visitor,
-    const QuicClock* clock,
-    QuicAlarmFactory* alarm_factory)
-    : time_wait_period_(QuicTime::Delta::FromSeconds(
-          GetQuicFlag(FLAGS_quic_time_wait_list_seconds))),
-      connection_id_clean_up_alarm_(
-          alarm_factory->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
-      clock_(clock),
-      writer_(writer),
-      visitor_(visitor) {
-  SetConnectionIdCleanUpAlarm();
-}
-
-QuicTimeWaitListManager::~QuicTimeWaitListManager() {
-  connection_id_clean_up_alarm_->Cancel();
-}
-
-QuicTimeWaitListManager::ConnectionIdMap::iterator
-QuicTimeWaitListManager::FindConnectionIdDataInMap(
-    const QuicConnectionId& connection_id) {
-  auto it = indirect_connection_id_map_.find(connection_id);
-  if (it == indirect_connection_id_map_.end()) {
-    return connection_id_map_.end();
-  }
-  return connection_id_map_.find(it->second);
-}
-
-void QuicTimeWaitListManager::AddConnectionIdDataToMap(
-    const QuicConnectionId& canonical_connection_id,
-    int num_packets,
-    TimeWaitAction action,
-    TimeWaitConnectionInfo info) {
-  for (const auto& cid : info.active_connection_ids) {
-    indirect_connection_id_map_[cid] = canonical_connection_id;
-  }
-  ConnectionIdData data(num_packets, clock_->ApproximateNow(), action,
-                        std::move(info));
-  connection_id_map_.emplace(
-      std::make_pair(canonical_connection_id, std::move(data)));
-}
-
-void QuicTimeWaitListManager::RemoveConnectionDataFromMap(
-    ConnectionIdMap::iterator it) {
-  for (const auto& cid : it->second.info.active_connection_ids) {
-    indirect_connection_id_map_.erase(cid);
-  }
-  connection_id_map_.erase(it);
-}
-
-void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
-    TimeWaitAction action,
-    TimeWaitConnectionInfo info) {
-  QUICHE_DCHECK(!info.active_connection_ids.empty());
-  const QuicConnectionId& canonical_connection_id =
-      info.active_connection_ids.front();
-  QUICHE_DCHECK(action != SEND_TERMINATION_PACKETS ||
-                !info.termination_packets.empty());
-  QUICHE_DCHECK(action != DO_NOTHING || info.ietf_quic);
-  int num_packets = 0;
-  auto it = FindConnectionIdDataInMap(canonical_connection_id);
-  const bool new_connection_id = it == connection_id_map_.end();
-  if (!new_connection_id) {  // Replace record if it is reinserted.
-    num_packets = it->second.num_packets;
-    RemoveConnectionDataFromMap(it);
-  }
-  TrimTimeWaitListIfNeeded();
-  int64_t max_connections =
-      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
-  QUICHE_DCHECK(connection_id_map_.empty() ||
-                num_connections() < static_cast<size_t>(max_connections));
-  if (new_connection_id) {
-    for (const auto& cid : info.active_connection_ids) {
-      visitor_->OnConnectionAddedToTimeWaitList(cid);
-    }
-  }
-  AddConnectionIdDataToMap(canonical_connection_id, num_packets, action,
-                           std::move(info));
-}
-
-bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
-    QuicConnectionId connection_id) const {
-  return indirect_connection_id_map_.contains(connection_id);
-}
-
-void QuicTimeWaitListManager::OnBlockedWriterCanWrite() {
-  writer_->SetWritable();
-  while (!pending_packets_queue_.empty()) {
-    QueuedPacket* queued_packet = pending_packets_queue_.front().get();
-    if (!WriteToWire(queued_packet)) {
-      return;
-    }
-    pending_packets_queue_.pop_front();
-  }
-}
-
-void QuicTimeWaitListManager::ProcessPacket(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    QuicConnectionId connection_id,
-    PacketHeaderFormat header_format,
-    size_t received_packet_length,
-    std::unique_ptr<QuicPerPacketContext> packet_context) {
-  QUICHE_DCHECK(IsConnectionIdInTimeWait(connection_id));
-  // TODO(satyamshekhar): Think about handling packets from different peer
-  // addresses.
-  auto it = FindConnectionIdDataInMap(connection_id);
-  QUICHE_DCHECK(it != connection_id_map_.end());
-  // Increment the received packet count.
-  ConnectionIdData* connection_data = &it->second;
-  ++(connection_data->num_packets);
-  const QuicTime now = clock_->ApproximateNow();
-  QuicTime::Delta delta = QuicTime::Delta::Zero();
-  if (now > connection_data->time_added) {
-    delta = now - connection_data->time_added;
-  }
-  OnPacketReceivedForKnownConnection(connection_data->num_packets, delta,
-                                     connection_data->info.srtt);
-
-  if (!ShouldSendResponse(connection_data->num_packets)) {
-    QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
-                    << "throttled";
-    return;
-  }
-
-  QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
-                  << "header format=" << header_format
-                  << " ietf=" << connection_data->info.ietf_quic
-                  << ", action=" << connection_data->action
-                  << ", number termination packets="
-                  << connection_data->info.termination_packets.size();
-  switch (connection_data->action) {
-    case SEND_TERMINATION_PACKETS:
-      if (connection_data->info.termination_packets.empty()) {
-        QUIC_BUG(quic_bug_10608_1) << "There are no termination packets.";
-        return;
-      }
-      switch (header_format) {
-        case IETF_QUIC_LONG_HEADER_PACKET:
-          if (!connection_data->info.ietf_quic) {
-            QUIC_CODE_COUNT(quic_received_long_header_packet_for_gquic);
-          }
-          break;
-        case IETF_QUIC_SHORT_HEADER_PACKET:
-          if (!connection_data->info.ietf_quic) {
-            QUIC_CODE_COUNT(quic_received_short_header_packet_for_gquic);
-          }
-          // Send stateless reset in response to short header packets.
-          SendPublicReset(self_address, peer_address, connection_id,
-                          connection_data->info.ietf_quic,
-                          received_packet_length, std::move(packet_context));
-          return;
-        case GOOGLE_QUIC_PACKET:
-          if (connection_data->info.ietf_quic) {
-            QUIC_CODE_COUNT(quic_received_gquic_packet_for_ietf_quic);
-          }
-          break;
-      }
-
-      for (const auto& packet : connection_data->info.termination_packets) {
-        SendOrQueuePacket(std::make_unique<QueuedPacket>(
-                              self_address, peer_address, packet->Clone()),
-                          packet_context.get());
-      }
-      return;
-
-    case SEND_CONNECTION_CLOSE_PACKETS:
-      if (connection_data->info.termination_packets.empty()) {
-        QUIC_BUG(quic_bug_10608_2) << "There are no termination packets.";
-        return;
-      }
-      for (const auto& packet : connection_data->info.termination_packets) {
-        SendOrQueuePacket(std::make_unique<QueuedPacket>(
-                              self_address, peer_address, packet->Clone()),
-                          packet_context.get());
-      }
-      return;
-
-    case SEND_STATELESS_RESET:
-      if (header_format == IETF_QUIC_LONG_HEADER_PACKET) {
-        QUIC_CODE_COUNT(quic_stateless_reset_long_header_packet);
-      }
-      SendPublicReset(self_address, peer_address, connection_id,
-                      connection_data->info.ietf_quic, received_packet_length,
-                      std::move(packet_context));
-      return;
-    case DO_NOTHING:
-      QUIC_CODE_COUNT(quic_time_wait_list_do_nothing);
-      QUICHE_DCHECK(connection_data->info.ietf_quic);
-  }
-}
-
-void QuicTimeWaitListManager::SendVersionNegotiationPacket(
-    QuicConnectionId server_connection_id,
-    QuicConnectionId client_connection_id,
-    bool ietf_quic,
-    bool use_length_prefix,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    std::unique_ptr<QuicPerPacketContext> packet_context) {
-  std::unique_ptr<QuicEncryptedPacket> version_packet =
-      QuicFramer::BuildVersionNegotiationPacket(
-          server_connection_id, client_connection_id, ietf_quic,
-          use_length_prefix, supported_versions);
-  QUIC_DVLOG(2) << "Dispatcher sending version negotiation packet {"
-                << ParsedQuicVersionVectorToString(supported_versions) << "}, "
-                << (ietf_quic ? "" : "!") << "ietf_quic, "
-                << (use_length_prefix ? "" : "!")
-                << "use_length_prefix:" << std::endl
-                << quiche::QuicheTextUtils::HexDump(absl::string_view(
-                       version_packet->data(), version_packet->length()));
-  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
-                                                   std::move(version_packet)),
-                    packet_context.get());
-}
-
-// Returns true if the number of packets received for this connection_id is a
-// power of 2 to throttle the number of public reset packets we send to a peer.
-bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) {
-  return (received_packet_count & (received_packet_count - 1)) == 0;
-}
-
-void QuicTimeWaitListManager::SendPublicReset(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    QuicConnectionId connection_id,
-    bool ietf_quic,
-    size_t received_packet_length,
-    std::unique_ptr<QuicPerPacketContext> packet_context) {
-  if (ietf_quic) {
-    std::unique_ptr<QuicEncryptedPacket> ietf_reset_packet =
-        BuildIetfStatelessResetPacket(connection_id, received_packet_length);
-    if (ietf_reset_packet == nullptr) {
-      // This could happen when trying to reject a short header packet of
-      // a connection which is in the time wait list (and with no termination
-      // packet).
-      return;
-    }
-    QUIC_DVLOG(2) << "Dispatcher sending IETF reset packet for "
-                  << connection_id << std::endl
-                  << quiche::QuicheTextUtils::HexDump(
-                         absl::string_view(ietf_reset_packet->data(),
-                                           ietf_reset_packet->length()));
-    SendOrQueuePacket(
-        std::make_unique<QueuedPacket>(self_address, peer_address,
-                                       std::move(ietf_reset_packet)),
-        packet_context.get());
-    return;
-  }
-  // Google QUIC public resets donot elicit resets in response.
-  QuicPublicResetPacket packet;
-  packet.connection_id = connection_id;
-  // TODO(satyamshekhar): generate a valid nonce for this connection_id.
-  packet.nonce_proof = 1010101;
-  // TODO(wub): This is wrong for proxied sessions. Fix it.
-  packet.client_address = peer_address;
-  GetEndpointId(&packet.endpoint_id);
-  // Takes ownership of the packet.
-  std::unique_ptr<QuicEncryptedPacket> reset_packet = BuildPublicReset(packet);
-  QUIC_DVLOG(2) << "Dispatcher sending reset packet for " << connection_id
-                << std::endl
-                << quiche::QuicheTextUtils::HexDump(absl::string_view(
-                       reset_packet->data(), reset_packet->length()));
-  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
-                                                   std::move(reset_packet)),
-                    packet_context.get());
-}
-
-void QuicTimeWaitListManager::SendPacket(const QuicSocketAddress& self_address,
-                                         const QuicSocketAddress& peer_address,
-                                         const QuicEncryptedPacket& packet) {
-  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
-                                                   packet.Clone()),
-                    nullptr);
-}
-
-std::unique_ptr<QuicEncryptedPacket> QuicTimeWaitListManager::BuildPublicReset(
-    const QuicPublicResetPacket& packet) {
-  return QuicFramer::BuildPublicResetPacket(packet);
-}
-
-std::unique_ptr<QuicEncryptedPacket>
-QuicTimeWaitListManager::BuildIetfStatelessResetPacket(
-    QuicConnectionId connection_id,
-    size_t received_packet_length) {
-  return QuicFramer::BuildIetfStatelessResetPacket(
-      connection_id, received_packet_length,
-      GetStatelessResetToken(connection_id));
-}
-
-// Either sends the packet and deletes it or makes pending queue the
-// owner of the packet.
-bool QuicTimeWaitListManager::SendOrQueuePacket(
-    std::unique_ptr<QueuedPacket> packet,
-    const QuicPerPacketContext* /*packet_context*/) {
-  if (packet == nullptr) {
-    QUIC_LOG(ERROR) << "Tried to send or queue a null packet";
-    return true;
-  }
-  if (pending_packets_queue_.size() >=
-      GetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets)) {
-    // There are too many pending packets.
-    QUIC_CODE_COUNT(quic_too_many_pending_packets_in_time_wait);
-    return true;
-  }
-  if (WriteToWire(packet.get())) {
-    // Allow the packet to be deleted upon leaving this function.
-    return true;
-  }
-  pending_packets_queue_.push_back(std::move(packet));
-  return false;
-}
-
-bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
-  if (writer_->IsWriteBlocked()) {
-    visitor_->OnWriteBlocked(this);
-    return false;
-  }
-  WriteResult result = writer_->WritePacket(
-      queued_packet->packet()->data(), queued_packet->packet()->length(),
-      queued_packet->self_address().host(), queued_packet->peer_address(),
-      nullptr);
-
-  // If using a batch writer and the packet is buffered, flush it.
-  if (writer_->IsBatchMode() && result.status == WRITE_STATUS_OK &&
-      result.bytes_written == 0) {
-    result = writer_->Flush();
-  }
-
-  if (IsWriteBlockedStatus(result.status)) {
-    // If blocked and unbuffered, return false to retry sending.
-    QUICHE_DCHECK(writer_->IsWriteBlocked());
-    visitor_->OnWriteBlocked(this);
-    return result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
-  } else if (IsWriteError(result.status)) {
-    QUIC_LOG_FIRST_N(WARNING, 1)
-        << "Received unknown error while sending termination packet to "
-        << queued_packet->peer_address().ToString() << ": "
-        << strerror(result.error_code);
-  }
-  return true;
-}
-
-void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() {
-  QuicTime::Delta next_alarm_interval = QuicTime::Delta::Zero();
-  if (!connection_id_map_.empty()) {
-    QuicTime oldest_connection_id =
-        connection_id_map_.begin()->second.time_added;
-    QuicTime now = clock_->ApproximateNow();
-    if (now - oldest_connection_id < time_wait_period_) {
-      next_alarm_interval = oldest_connection_id + time_wait_period_ - now;
-    } else {
-      QUIC_LOG(ERROR)
-          << "ConnectionId lingered for longer than time_wait_period_";
-    }
-  } else {
-    // No connection_ids added so none will expire before time_wait_period_.
-    next_alarm_interval = time_wait_period_;
-  }
-
-  connection_id_clean_up_alarm_->Update(
-      clock_->ApproximateNow() + next_alarm_interval, QuicTime::Delta::Zero());
-}
-
-bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
-    QuicTime expiration_time) {
-  if (connection_id_map_.empty()) {
-    return false;
-  }
-  auto it = connection_id_map_.begin();
-  QuicTime oldest_connection_id_time = it->second.time_added;
-  if (oldest_connection_id_time > expiration_time) {
-    // Too recent, don't retire.
-    return false;
-  }
-  // This connection_id has lived its age, retire it now.
-  QUIC_DLOG(INFO) << "Connection " << it->first
-                  << " expired from time wait list";
-  RemoveConnectionDataFromMap(it);
-  if (expiration_time == QuicTime::Infinite()) {
-    QUIC_CODE_COUNT(quic_time_wait_list_trim_full);
-  } else {
-    QUIC_CODE_COUNT(quic_time_wait_list_expire_connections);
-  }
-  return true;
-}
-
-void QuicTimeWaitListManager::CleanUpOldConnectionIds() {
-  QuicTime now = clock_->ApproximateNow();
-  QuicTime expiration = now - time_wait_period_;
-
-  while (MaybeExpireOldestConnection(expiration)) {
-  }
-
-  SetConnectionIdCleanUpAlarm();
-}
-
-void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
-  const int64_t kMaxConnections =
-      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
-  if (kMaxConnections < 0) {
-    return;
-  }
-  while (!connection_id_map_.empty() &&
-         num_connections() >= static_cast<size_t>(kMaxConnections)) {
-    MaybeExpireOldestConnection(QuicTime::Infinite());
-  }
-}
-
-QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
-    int num_packets,
-    QuicTime time_added,
-    TimeWaitAction action,
-    TimeWaitConnectionInfo info)
-    : num_packets(num_packets),
-      time_added(time_added),
-      action(action),
-      info(std::move(info)) {}
-
-QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
-    ConnectionIdData&& other) = default;
-
-QuicTimeWaitListManager::ConnectionIdData::~ConnectionIdData() = default;
-
-StatelessResetToken QuicTimeWaitListManager::GetStatelessResetToken(
-    QuicConnectionId connection_id) const {
-  return QuicUtils::GenerateStatelessResetToken(connection_id);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_time_wait_list_manager.h b/quic/core/quic_time_wait_list_manager.h
deleted file mode 100644
index a084484..0000000
--- a/quic/core/quic_time_wait_list_manager.h
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Handles packets for connection_ids in time wait state by discarding the
-// packet and sending the peers termination packets with exponential backoff.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_blocked_writer_interface.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-namespace test {
-class QuicDispatcherPeer;
-class QuicTimeWaitListManagerPeer;
-}  // namespace test
-
-// TimeWaitConnectionInfo comprises information of a connection which is in the
-// time wait list.
-struct QUIC_NO_EXPORT TimeWaitConnectionInfo {
-  TimeWaitConnectionInfo(
-      bool ietf_quic,
-      std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
-      std::vector<QuicConnectionId> active_connection_ids);
-  TimeWaitConnectionInfo(
-      bool ietf_quic,
-      std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
-      std::vector<QuicConnectionId> active_connection_ids,
-      QuicTime::Delta srtt);
-
-  TimeWaitConnectionInfo(const TimeWaitConnectionInfo& other) = delete;
-  TimeWaitConnectionInfo(TimeWaitConnectionInfo&& other) = default;
-
-  ~TimeWaitConnectionInfo() = default;
-
-  bool ietf_quic;
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  std::vector<QuicConnectionId> active_connection_ids;
-  QuicTime::Delta srtt;
-};
-
-// Maintains a list of all connection_ids that have been recently closed. A
-// connection_id lives in this state for time_wait_period_. All packets received
-// for connection_ids in this state are handed over to the
-// QuicTimeWaitListManager by the QuicDispatcher.  Decides whether to send a
-// public reset packet, a copy of the previously sent connection close packet,
-// or nothing to the peer which sent a packet with the connection_id in time
-// wait state.  After the connection_id expires its time wait period, a new
-// connection/session will be created if a packet is received for this
-// connection_id.
-class QUIC_NO_EXPORT QuicTimeWaitListManager
-    : public QuicBlockedWriterInterface {
- public:
-  // Specifies what the time wait list manager should do when processing packets
-  // of a time wait connection.
-  enum TimeWaitAction : uint8_t {
-    // Send specified termination packets, error if termination packet is
-    // unavailable.
-    SEND_TERMINATION_PACKETS,
-    // The same as SEND_TERMINATION_PACKETS except that the corresponding
-    // termination packets are provided by the connection.
-    SEND_CONNECTION_CLOSE_PACKETS,
-    // Send stateless reset (public reset for GQUIC).
-    SEND_STATELESS_RESET,
-
-    DO_NOTHING,
-  };
-
-  class QUIC_NO_EXPORT Visitor : public QuicSession::Visitor {
-   public:
-    // Called after the given connection is added to the time-wait list.
-    virtual void OnConnectionAddedToTimeWaitList(
-        QuicConnectionId connection_id) = 0;
-  };
-
-  // writer - the entity that writes to the socket. (Owned by the caller)
-  // visitor - the entity that manages blocked writers. (Owned by the caller)
-  // clock - provide a clock (Owned by the caller)
-  // alarm_factory - used to run clean up alarms. (Owned by the caller)
-  QuicTimeWaitListManager(QuicPacketWriter* writer,
-                          Visitor* visitor,
-                          const QuicClock* clock,
-                          QuicAlarmFactory* alarm_factory);
-  QuicTimeWaitListManager(const QuicTimeWaitListManager&) = delete;
-  QuicTimeWaitListManager& operator=(const QuicTimeWaitListManager&) = delete;
-  ~QuicTimeWaitListManager() override;
-
-  // Adds the connection IDs in info to time wait state for time_wait_period_.
-  // If |info|.termination_packets are provided, copies of these packets will be
-  // sent when a packet with one of these connection IDs is processed. Any
-  // termination packets will be move from |info|.termination_packets and will
-  // become owned by the manager. |action| specifies what the time wait list
-  // manager should do when processing packets of the connection.
-  virtual void AddConnectionIdToTimeWait(TimeWaitAction action,
-                                         TimeWaitConnectionInfo info);
-
-  // Returns true if the connection_id is in time wait state, false otherwise.
-  // Packets received for this connection_id should not lead to creation of new
-  // QuicSessions.
-  bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) const;
-
-  // Called when a packet is received for a connection_id that is in time wait
-  // state. Sends a public reset packet to the peer which sent this
-  // connection_id. Sending of the public reset packet is throttled by using
-  // exponential back off. QUICHE_DCHECKs for the connection_id to be in time
-  // wait state. virtual to override in tests.
-  // TODO(fayang): change ProcessPacket and SendPublicReset to take
-  // ReceivedPacketInfo.
-  virtual void ProcessPacket(
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address,
-      QuicConnectionId connection_id,
-      PacketHeaderFormat header_format,
-      size_t received_packet_length,
-      std::unique_ptr<QuicPerPacketContext> packet_context);
-
-  // Called by the dispatcher when the underlying socket becomes writable again,
-  // since we might need to send pending public reset packets which we didn't
-  // send because the underlying socket was write blocked.
-  void OnBlockedWriterCanWrite() override;
-
-  bool IsWriterBlocked() const override {
-    return writer_ != nullptr && writer_->IsWriteBlocked();
-  }
-
-  // Used to delete connection_id entries that have outlived their time wait
-  // period.
-  void CleanUpOldConnectionIds();
-
-  // If necessary, trims the oldest connections from the time-wait list until
-  // the size is under the configured maximum.
-  void TrimTimeWaitListIfNeeded();
-
-  // The number of connections on the time-wait list.
-  size_t num_connections() const { return connection_id_map_.size(); }
-
-  // Sends a version negotiation packet for |server_connection_id| and
-  // |client_connection_id| announcing support for |supported_versions| to
-  // |peer_address| from |self_address|.
-  virtual void SendVersionNegotiationPacket(
-      QuicConnectionId server_connection_id,
-      QuicConnectionId client_connection_id,
-      bool ietf_quic,
-      bool use_length_prefix,
-      const ParsedQuicVersionVector& supported_versions,
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address,
-      std::unique_ptr<QuicPerPacketContext> packet_context);
-
-  // Creates a public reset packet and sends it or queues it to be sent later.
-  virtual void SendPublicReset(
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address,
-      QuicConnectionId connection_id,
-      bool ietf_quic,
-      size_t received_packet_length,
-      std::unique_ptr<QuicPerPacketContext> packet_context);
-
-  // Called to send |packet|.
-  virtual void SendPacket(const QuicSocketAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          const QuicEncryptedPacket& packet);
-
-  // Return a non-owning pointer to the packet writer.
-  QuicPacketWriter* writer() { return writer_; }
-
- protected:
-  virtual std::unique_ptr<QuicEncryptedPacket> BuildPublicReset(
-      const QuicPublicResetPacket& packet);
-
-  virtual void GetEndpointId(std::string* /*endpoint_id*/) {}
-
-  // Returns a stateless reset token which will be included in the public reset
-  // packet.
-  virtual StatelessResetToken GetStatelessResetToken(
-      QuicConnectionId connection_id) const;
-
-  // Internal structure to store pending termination packets.
-  class QUIC_NO_EXPORT QueuedPacket {
-   public:
-    QueuedPacket(const QuicSocketAddress& self_address,
-                 const QuicSocketAddress& peer_address,
-                 std::unique_ptr<QuicEncryptedPacket> packet)
-        : self_address_(self_address),
-          peer_address_(peer_address),
-          packet_(std::move(packet)) {}
-    QueuedPacket(const QueuedPacket&) = delete;
-    QueuedPacket& operator=(const QueuedPacket&) = delete;
-
-    const QuicSocketAddress& self_address() const { return self_address_; }
-    const QuicSocketAddress& peer_address() const { return peer_address_; }
-    QuicEncryptedPacket* packet() { return packet_.get(); }
-
-   private:
-    // Server address on which a packet was received for a connection_id in
-    // time wait state.
-    const QuicSocketAddress self_address_;
-    // Address of the peer to send this packet to.
-    const QuicSocketAddress peer_address_;
-    // The pending termination packet that is to be sent to the peer.
-    std::unique_ptr<QuicEncryptedPacket> packet_;
-  };
-
-  // Called right after |packet| is serialized. Either sends the packet and
-  // deletes it or makes pending_packets_queue_ the owner of the packet.
-  // Subclasses overriding this method should call this class's base
-  // implementation at the end of the override.
-  // Return true if |packet| is sent, false if it is queued.
-  virtual bool SendOrQueuePacket(std::unique_ptr<QueuedPacket> packet,
-                                 const QuicPerPacketContext* packet_context);
-
-  const quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>&
-  pending_packets_queue() const {
-    return pending_packets_queue_;
-  }
-
- private:
-  friend class test::QuicDispatcherPeer;
-  friend class test::QuicTimeWaitListManagerPeer;
-
-  // Decides if a packet should be sent for this connection_id based on the
-  // number of received packets.
-  bool ShouldSendResponse(int received_packet_count);
-
-  // Sends the packet out. Returns true if the packet was successfully consumed.
-  // If the writer got blocked and did not buffer the packet, we'll need to keep
-  // the packet and retry sending. In case of all other errors we drop the
-  // packet.
-  bool WriteToWire(QueuedPacket* packet);
-
-  // Register the alarm server to wake up at appropriate time.
-  void SetConnectionIdCleanUpAlarm();
-
-  // Removes the oldest connection from the time-wait list if it was added prior
-  // to "expiration_time".  To unconditionally remove the oldest connection, use
-  // a QuicTime::Delta:Infinity().  This function modifies the
-  // connection_id_map_.  If you plan to call this function in a loop, any
-  // iterators that you hold before the call to this function may be invalid
-  // afterward.  Returns true if the oldest connection was expired.  Returns
-  // false if the map is empty or the oldest connection has not expired.
-  bool MaybeExpireOldestConnection(QuicTime expiration_time);
-
-  // Called when a packet is received for a connection in this time wait list.
-  virtual void OnPacketReceivedForKnownConnection(
-      int /*num_packets*/,
-      QuicTime::Delta /*delta*/,
-      QuicTime::Delta /*srtt*/) const {}
-
-  std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
-      QuicConnectionId connection_id,
-      size_t received_packet_length);
-
-  // A map from a recently closed connection_id to the number of packets
-  // received after the termination of the connection bound to the
-  // connection_id.
-  struct QUIC_NO_EXPORT ConnectionIdData {
-    ConnectionIdData(int num_packets,
-                     QuicTime time_added,
-                     TimeWaitAction action,
-                     TimeWaitConnectionInfo info);
-
-    ConnectionIdData(const ConnectionIdData& other) = delete;
-    ConnectionIdData(ConnectionIdData&& other);
-
-    ~ConnectionIdData();
-
-    int num_packets;
-    QuicTime time_added;
-    TimeWaitAction action;
-    TimeWaitConnectionInfo info;
-  };
-
-  // QuicheLinkedHashMap allows lookup by ConnectionId
-  // and traversal in add order.
-  using ConnectionIdMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
-                                                      ConnectionIdData,
-                                                      QuicConnectionIdHash>;
-  // Do not use find/emplace/erase on this map directly. Use
-  // FindConnectionIdDataInMap, AddConnectionIdDateToMap,
-  // RemoveConnectionDataFromMap instead.
-  ConnectionIdMap connection_id_map_;
-
-  // TODO(haoyuewang) Consider making connection_id_map_ a map of shared pointer
-  // and remove the indirect map.
-  // A connection can have multiple unretired ConnectionIds when it is closed.
-  // These Ids have the same ConnectionIdData entry in connection_id_map_. To
-  // find the entry, look up the cannoical ConnectionId in
-  // indirect_connection_id_map_ first, and look up connection_id_map_ with the
-  // cannoical ConnectionId.
-  absl::flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>
-      indirect_connection_id_map_;
-
-  // Find an iterator for the given connection_id. Returns
-  // connection_id_map_.end() if none found.
-  ConnectionIdMap::iterator FindConnectionIdDataInMap(
-      const QuicConnectionId& connection_id);
-  // Inserts a ConnectionIdData entry to connection_id_map_.
-  void AddConnectionIdDataToMap(const QuicConnectionId& canonical_connection_id,
-                                int num_packets,
-                                TimeWaitAction action,
-                                TimeWaitConnectionInfo info);
-  // Removes a ConnectionIdData entry in connection_id_map_.
-  void RemoveConnectionDataFromMap(ConnectionIdMap::iterator it);
-
-  // Pending termination packets that need to be sent out to the peer when we
-  // are given a chance to write by the dispatcher.
-  quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>
-      pending_packets_queue_;
-
-  // Time period for which connection_ids should remain in time wait state.
-  const QuicTime::Delta time_wait_period_;
-
-  // Alarm to clean up connection_ids that have out lived their duration in
-  // time wait state.
-  std::unique_ptr<QuicAlarm> connection_id_clean_up_alarm_;
-
-  // Clock to efficiently measure approximate time.
-  const QuicClock* clock_;
-
-  // Interface that writes given buffer to the socket.
-  QuicPacketWriter* writer_;
-
-  // Interface that manages blocked writers.
-  Visitor* visitor_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/quic/core/quic_time_wait_list_manager_test.cc b/quic/core/quic_time_wait_list_manager_test.cc
deleted file mode 100644
index fcfdbbb..0000000
--- a/quic/core/quic_time_wait_list_manager_test.cc
+++ /dev/null
@@ -1,788 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_time_wait_list_manager.h"
-
-#include <cerrno>
-#include <memory>
-#include <ostream>
-#include <utility>
-
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_time_wait_list_manager_peer.h"
-
-using testing::_;
-using testing::Args;
-using testing::Assign;
-using testing::DoAll;
-using testing::Matcher;
-using testing::NiceMock;
-using testing::Return;
-using testing::ReturnPointee;
-using testing::StrictMock;
-using testing::Truly;
-
-namespace quic {
-namespace test {
-namespace {
-
-const size_t kTestPacketSize = 100;
-
-class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
- public:
-  FramerVisitorCapturingPublicReset(QuicConnectionId connection_id)
-      : connection_id_(connection_id) {}
-  ~FramerVisitorCapturingPublicReset() override = default;
-
-  void OnPublicResetPacket(const QuicPublicResetPacket& public_reset) override {
-    public_reset_packet_ = public_reset;
-  }
-
-  const QuicPublicResetPacket public_reset_packet() {
-    return public_reset_packet_;
-  }
-
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& token) const override {
-    return token == QuicUtils::GenerateStatelessResetToken(connection_id_);
-  }
-
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& packet) override {
-    stateless_reset_packet_ = packet;
-  }
-
-  const QuicIetfStatelessResetPacket stateless_reset_packet() {
-    return stateless_reset_packet_;
-  }
-
- private:
-  QuicPublicResetPacket public_reset_packet_;
-  QuicIetfStatelessResetPacket stateless_reset_packet_;
-  QuicConnectionId connection_id_;
-};
-
-class MockAlarmFactory;
-class MockAlarm : public QuicAlarm {
- public:
-  explicit MockAlarm(QuicArenaScopedPtr<Delegate> delegate,
-                     int alarm_index,
-                     MockAlarmFactory* factory)
-      : QuicAlarm(std::move(delegate)),
-        alarm_index_(alarm_index),
-        factory_(factory) {}
-  virtual ~MockAlarm() {}
-
-  void SetImpl() override;
-  void CancelImpl() override;
-
- private:
-  int alarm_index_;
-  MockAlarmFactory* factory_;
-};
-
-class MockAlarmFactory : public QuicAlarmFactory {
- public:
-  ~MockAlarmFactory() override {}
-
-  // Creates a new platform-specific alarm which will be configured to notify
-  // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
-  // Caller takes ownership of the new alarm, which will not yet be "set" to
-  // fire.
-  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
-    return new MockAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate),
-                         alarm_index_++, this);
-  }
-  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-      QuicConnectionArena* arena) override {
-    if (arena != nullptr) {
-      return arena->New<MockAlarm>(std::move(delegate), alarm_index_++, this);
-    }
-    return QuicArenaScopedPtr<MockAlarm>(
-        new MockAlarm(std::move(delegate), alarm_index_++, this));
-  }
-  MOCK_METHOD(void, OnAlarmSet, (int, QuicTime), ());
-  MOCK_METHOD(void, OnAlarmCancelled, (int), ());
-
- private:
-  int alarm_index_ = 0;
-};
-
-void MockAlarm::SetImpl() {
-  factory_->OnAlarmSet(alarm_index_, deadline());
-}
-
-void MockAlarm::CancelImpl() {
-  factory_->OnAlarmCancelled(alarm_index_);
-}
-
-class QuicTimeWaitListManagerTest : public QuicTest {
- protected:
-  QuicTimeWaitListManagerTest()
-      : time_wait_list_manager_(&writer_, &visitor_, &clock_, &alarm_factory_),
-        connection_id_(TestConnectionId(45)),
-        peer_address_(TestPeerIPAddress(), kTestPort),
-        writer_is_blocked_(false) {}
-
-  ~QuicTimeWaitListManagerTest() override = default;
-
-  void SetUp() override {
-    EXPECT_CALL(writer_, IsWriteBlocked())
-        .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
-  }
-
-  void AddConnectionId(QuicConnectionId connection_id,
-                       QuicTimeWaitListManager::TimeWaitAction action) {
-    AddConnectionId(connection_id, QuicVersionMax(), action, nullptr);
-  }
-
-  void AddStatelessConnectionId(QuicConnectionId connection_id) {
-    std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-    termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
-        new QuicEncryptedPacket(nullptr, 0, false)));
-    time_wait_list_manager_.AddConnectionIdToTimeWait(
-        QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
-        TimeWaitConnectionInfo(false, &termination_packets, {connection_id}));
-  }
-
-  void AddConnectionId(
-      QuicConnectionId connection_id,
-      ParsedQuicVersion version,
-      QuicTimeWaitListManager::TimeWaitAction action,
-      std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
-    time_wait_list_manager_.AddConnectionIdToTimeWait(
-        action, TimeWaitConnectionInfo(version.HasIetfInvariantHeader(),
-                                       packets, {connection_id}));
-  }
-
-  bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
-    return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
-  }
-
-  void ProcessPacket(QuicConnectionId connection_id) {
-    time_wait_list_manager_.ProcessPacket(
-        self_address_, peer_address_, connection_id, GOOGLE_QUIC_PACKET,
-        kTestPacketSize, std::make_unique<QuicPerPacketContext>());
-  }
-
-  QuicEncryptedPacket* ConstructEncryptedPacket(
-      QuicConnectionId destination_connection_id,
-      QuicConnectionId source_connection_id,
-      uint64_t packet_number) {
-    return quic::test::ConstructEncryptedPacket(destination_connection_id,
-                                                source_connection_id, false,
-                                                false, packet_number, "data");
-  }
-
-  MockClock clock_;
-  MockAlarmFactory alarm_factory_;
-  NiceMock<MockPacketWriter> writer_;
-  StrictMock<MockQuicSessionVisitor> visitor_;
-  QuicTimeWaitListManager time_wait_list_manager_;
-  QuicConnectionId connection_id_;
-  QuicSocketAddress self_address_;
-  QuicSocketAddress peer_address_;
-  bool writer_is_blocked_;
-};
-
-bool ValidPublicResetPacketPredicate(
-    QuicConnectionId expected_connection_id,
-    const std::tuple<const char*, int>& packet_buffer) {
-  FramerVisitorCapturingPublicReset visitor(expected_connection_id);
-  QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
-                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
-  framer.set_visitor(&visitor);
-  QuicEncryptedPacket encrypted(std::get<0>(packet_buffer),
-                                std::get<1>(packet_buffer));
-  framer.ProcessPacket(encrypted);
-  QuicPublicResetPacket packet = visitor.public_reset_packet();
-  bool public_reset_is_valid =
-      expected_connection_id == packet.connection_id &&
-      TestPeerIPAddress() == packet.client_address.host() &&
-      kTestPort == packet.client_address.port();
-
-  QuicIetfStatelessResetPacket stateless_reset =
-      visitor.stateless_reset_packet();
-
-  StatelessResetToken expected_stateless_reset_token =
-      QuicUtils::GenerateStatelessResetToken(expected_connection_id);
-
-  bool stateless_reset_is_valid =
-      stateless_reset.stateless_reset_token == expected_stateless_reset_token;
-
-  return public_reset_is_valid || stateless_reset_is_valid;
-}
-
-Matcher<const std::tuple<const char*, int>> PublicResetPacketEq(
-    QuicConnectionId connection_id) {
-  return Truly(
-      [connection_id](const std::tuple<const char*, int> packet_buffer) {
-        return ValidPublicResetPacketPredicate(connection_id, packet_buffer);
-      });
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
-  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
-  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
-  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  AddStatelessConnectionId(connection_id_);
-  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
-          /*use_length_prefix=*/false, AllSupportedVersions()));
-  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
-                                   peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  time_wait_list_manager_.SendVersionNegotiationPacket(
-      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
-      /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
-      peer_address_, std::make_unique<QuicPerPacketContext>());
-  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
-       SendIetfVersionNegotiationPacketWithoutLengthPrefix) {
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
-          /*use_length_prefix=*/false, AllSupportedVersions()));
-  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
-                                   peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  time_wait_list_manager_.SendVersionNegotiationPacket(
-      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
-      /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
-      peer_address_, std::make_unique<QuicPerPacketContext>());
-  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendIetfVersionNegotiationPacket) {
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
-          /*use_length_prefix=*/true, AllSupportedVersions()));
-  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
-                                   peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  time_wait_list_manager_.SendVersionNegotiationPacket(
-      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
-      /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
-      peer_address_, std::make_unique<QuicPerPacketContext>());
-  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
-       SendIetfVersionNegotiationPacketWithClientConnectionId) {
-  std::unique_ptr<QuicEncryptedPacket> packet(
-      QuicFramer::BuildVersionNegotiationPacket(
-          connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
-          /*use_length_prefix=*/true, AllSupportedVersions()));
-  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
-                                   peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  time_wait_list_manager_.SendVersionNegotiationPacket(
-      connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
-      /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
-      peer_address_, std::make_unique<QuicPerPacketContext>());
-  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
-  const size_t kConnectionCloseLength = 100;
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-  AddConnectionId(connection_id_, QuicVersionMax(),
-                  QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
-                  &termination_packets);
-  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
-                                   self_address_.host(), peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
-  const size_t kConnectionCloseLength = 100;
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-  AddConnectionId(connection_id_, QuicVersionMax(),
-                  QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
-                  &termination_packets);
-  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
-                                   self_address_.host(), peer_address_, _))
-      .Times(2)
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  AddConnectionId(connection_id_,
-                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-
-  ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  AddConnectionId(connection_id_,
-                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
-  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-  for (int packet_number = 1; packet_number < 101; ++packet_number) {
-    if ((packet_number & (packet_number - 1)) == 0) {
-      EXPECT_CALL(writer_, WritePacket(_, _, _, _, _))
-          .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-    }
-    ProcessPacket(connection_id_);
-    // Send public reset with exponential back off.
-    if ((packet_number & (packet_number - 1)) == 0) {
-      EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
-          &time_wait_list_manager_, packet_number));
-    } else {
-      EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
-          &time_wait_list_manager_, packet_number));
-    }
-  }
-}
-
-TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  AddStatelessConnectionId(connection_id_);
-
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  ProcessPacket(connection_id_);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
-  const size_t kConnectionIdCount = 100;
-  const size_t kOldConnectionIdCount = 31;
-
-  // Add connection_ids such that their expiry time is time_wait_period_.
-  for (uint64_t conn_id = 1; conn_id <= kOldConnectionIdCount; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
-    AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
-  }
-  EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
-
-  // Add remaining connection_ids such that their add time is
-  // 2 * time_wait_period_.
-  const QuicTime::Delta time_wait_period =
-      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
-  clock_.AdvanceTime(time_wait_period);
-  for (uint64_t conn_id = kOldConnectionIdCount + 1;
-       conn_id <= kConnectionIdCount; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
-    AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
-  }
-  EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
-
-  QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
-  // Now set the current time as time_wait_period + offset usecs.
-  clock_.AdvanceTime(offset);
-  // After all the old connection_ids are cleaned up, check the next alarm
-  // interval.
-  QuicTime next_alarm_time = clock_.Now() + time_wait_period - offset;
-  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
-
-  time_wait_list_manager_.CleanUpOldConnectionIds();
-  for (uint64_t conn_id = 1; conn_id <= kConnectionIdCount; ++conn_id) {
-    QuicConnectionId connection_id = TestConnectionId(conn_id);
-    EXPECT_EQ(conn_id > kOldConnectionIdCount,
-              IsConnectionIdInTimeWait(connection_id))
-        << "kOldConnectionIdCount: " << kOldConnectionIdCount
-        << " connection_id: " << connection_id;
-  }
-  EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
-            time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
-       CleanUpOldConnectionIdsForMultipleConnectionIdsPerConnection) {
-  connection_id_ = TestConnectionId(7);
-  const size_t kConnectionCloseLength = 100;
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-
-  // Add a CONNECTION_CLOSE termination packet.
-  std::vector<QuicConnectionId> active_connection_ids{connection_id_,
-                                                      TestConnectionId(8)};
-  time_wait_list_manager_.AddConnectionIdToTimeWait(
-      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
-      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
-                             active_connection_ids, QuicTime::Delta::Zero()));
-
-  EXPECT_TRUE(
-      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
-  EXPECT_TRUE(
-      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
-
-  // Remove these IDs.
-  const QuicTime::Delta time_wait_period =
-      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
-  clock_.AdvanceTime(time_wait_period);
-  time_wait_list_manager_.CleanUpOldConnectionIds();
-
-  EXPECT_FALSE(
-      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
-  EXPECT_FALSE(
-      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
-  QuicConnectionId connection_id = TestConnectionId(1);
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
-  AddConnectionId(connection_id, QuicTimeWaitListManager::SEND_STATELESS_RESET);
-  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
-  // Let first write through.
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
-  ProcessPacket(connection_id);
-
-  // write block for the next packet.
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
-      .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
-                      Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
-  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
-  ProcessPacket(connection_id);
-  // 3rd packet. No public reset should be sent;
-  ProcessPacket(connection_id);
-
-  // write packet should not be called since we are write blocked but the
-  // should be queued.
-  QuicConnectionId other_connection_id = TestConnectionId(2);
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
-  AddConnectionId(other_connection_id,
-                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
-  std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
-      other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
-  EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
-  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
-  ProcessPacket(other_connection_id);
-  EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
-
-  // Now expect all the write blocked public reset packets to be sent again.
-  writer_is_blocked_ = false;
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
-  time_wait_list_manager_.OnBlockedWriterCanWrite();
-}
-
-TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
-  // Add connection_ids such that their expiry time is time_wait_period_.
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
-  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-  const size_t kConnectionCloseLength = 100;
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-  AddConnectionId(connection_id_, QuicVersionMax(),
-                  QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
-                  &termination_packets);
-  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
-  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-
-  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
-                                   self_address_.host(), peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  ProcessPacket(connection_id_);
-
-  const QuicTime::Delta time_wait_period =
-      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
-
-  QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
-  clock_.AdvanceTime(offset + time_wait_period);
-  // Now set the current time as time_wait_period + offset usecs.
-  QuicTime next_alarm_time = clock_.Now() + time_wait_period;
-  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
-
-  time_wait_list_manager_.CleanUpOldConnectionIds();
-  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
-  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
-  // Simple randomization: the values of connection_ids are randomly swapped.
-  // If the container is broken, the test will be 50% flaky.
-  const uint64_t conn_id1 = QuicRandom::GetInstance()->RandUint64() % 2;
-  const QuicConnectionId connection_id1 = TestConnectionId(conn_id1);
-  const QuicConnectionId connection_id2 = TestConnectionId(1 - conn_id1);
-
-  // 1 will hash lower than 2, but we add it later. They should come out in the
-  // add order, not hash order.
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
-  AddConnectionId(connection_id1, QuicTimeWaitListManager::DO_NOTHING);
-  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(10));
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
-  AddConnectionId(connection_id2, QuicTimeWaitListManager::DO_NOTHING);
-  EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
-
-  const QuicTime::Delta time_wait_period =
-      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
-  clock_.AdvanceTime(time_wait_period - QuicTime::Delta::FromMicroseconds(9));
-
-  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, _));
-
-  time_wait_list_manager_.CleanUpOldConnectionIds();
-  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
-  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
-  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-}
-
-TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
-  // Basically, shut off time-based eviction.
-  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
-  SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 5);
-
-  uint64_t current_conn_id = 0;
-  const int64_t kMaxConnections =
-      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
-  // Add exactly the maximum number of connections
-  for (int64_t i = 0; i < kMaxConnections; ++i) {
-    ++current_conn_id;
-    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
-    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
-    EXPECT_CALL(visitor_,
-                OnConnectionAddedToTimeWaitList(current_connection_id));
-    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
-    EXPECT_EQ(current_conn_id, time_wait_list_manager_.num_connections());
-    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
-  }
-
-  // Now keep adding.  Since we're already at the max, every new connection-id
-  // will evict the oldest one.
-  for (int64_t i = 0; i < kMaxConnections; ++i) {
-    ++current_conn_id;
-    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
-    const QuicConnectionId id_to_evict =
-        TestConnectionId(current_conn_id - kMaxConnections);
-    EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
-    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
-    EXPECT_CALL(visitor_,
-                OnConnectionAddedToTimeWaitList(current_connection_id));
-    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
-    EXPECT_EQ(static_cast<size_t>(kMaxConnections),
-              time_wait_list_manager_.num_connections());
-    EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
-    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
-  }
-}
-
-TEST_F(QuicTimeWaitListManagerTest, ZeroMaxConnections) {
-  // Basically, shut off time-based eviction.
-  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
-  // Keep time wait list empty.
-  SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 0);
-
-  uint64_t current_conn_id = 0;
-  // Add exactly the maximum number of connections
-  for (int64_t i = 0; i < 10; ++i) {
-    ++current_conn_id;
-    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
-    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
-    EXPECT_CALL(visitor_,
-                OnConnectionAddedToTimeWaitList(current_connection_id));
-    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
-    // Verify time wait list always has 1 connection.
-    EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
-    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
-  }
-}
-
-// Regression test for b/116200989.
-TEST_F(QuicTimeWaitListManagerTest,
-       SendStatelessResetInResponseToShortHeaders) {
-  // This test mimics a scenario where an ENCRYPTION_INITIAL connection close is
-  // added as termination packet for an IETF connection ID. However, a short
-  // header packet is received later.
-  const size_t kConnectionCloseLength = 100;
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-  time_wait_list_manager_.AddConnectionIdToTimeWait(
-      QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
-      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
-                             {connection_id_}));
-
-  // Termination packet is not encrypted, instead, send stateless reset.
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
-  // Processes IETF short header packet.
-  time_wait_list_manager_.ProcessPacket(
-      self_address_, peer_address_, connection_id_,
-      IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
-      std::make_unique<QuicPerPacketContext>());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
-       SendConnectionClosePacketsInResponseToShortHeaders) {
-  const size_t kConnectionCloseLength = 100;
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-  // Add a CONNECTION_CLOSE termination packet.
-  time_wait_list_manager_.AddConnectionIdToTimeWait(
-      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
-      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
-                             {connection_id_}));
-  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
-                                   self_address_.host(), peer_address_, _))
-      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
-
-  // Processes IETF short header packet.
-  time_wait_list_manager_.ProcessPacket(
-      self_address_, peer_address_, connection_id_,
-      IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
-      std::make_unique<QuicPerPacketContext>());
-}
-
-TEST_F(QuicTimeWaitListManagerTest,
-       SendConnectionClosePacketsForMultipleConnectionIds) {
-  connection_id_ = TestConnectionId(7);
-  const size_t kConnectionCloseLength = 100;
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
-  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
-  termination_packets.push_back(
-      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
-          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
-
-  // Add a CONNECTION_CLOSE termination packet.
-  std::vector<QuicConnectionId> active_connection_ids{connection_id_,
-                                                      TestConnectionId(8)};
-  time_wait_list_manager_.AddConnectionIdToTimeWait(
-      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
-      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
-                             active_connection_ids, QuicTime::Delta::Zero()));
-
-  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
-                                   self_address_.host(), peer_address_, _))
-      .Times(2)
-      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
-  // Processes IETF short header packet.
-  for (auto const& cid : active_connection_ids) {
-    time_wait_list_manager_.ProcessPacket(
-        self_address_, peer_address_, cid, IETF_QUIC_SHORT_HEADER_PACKET,
-        kTestPacketSize, std::make_unique<QuicPerPacketContext>());
-  }
-}
-
-// Regression test for b/184053898.
-TEST_F(QuicTimeWaitListManagerTest, DonotCrashOnNullStatelessReset) {
-  // Received a packet with length <
-  // QuicFramer::GetMinStatelessResetPacketLength(), and this will result in a
-  // null stateless reset.
-  time_wait_list_manager_.SendPublicReset(
-      self_address_, peer_address_, TestConnectionId(1),
-      /*ietf_quic=*/true,
-      /*received_packet_length=*/
-      QuicFramer::GetMinStatelessResetPacketLength() - 1,
-      /*packet_context=*/nullptr);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, SendOrQueueNullPacket) {
-  QuicTimeWaitListManagerPeer::SendOrQueuePacket(&time_wait_list_manager_,
-                                                 nullptr, nullptr);
-}
-
-TEST_F(QuicTimeWaitListManagerTest, TooManyPendingPackets) {
-  SetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets, 5);
-  const size_t kNumOfUnProcessablePackets = 2048;
-  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_))
-      .Times(testing::AnyNumber());
-  // Write block for the next packets.
-  EXPECT_CALL(writer_,
-              WritePacket(_, _, self_address_.host(), peer_address_, _))
-      .With(Args<0, 1>(PublicResetPacketEq(TestConnectionId(1))))
-      .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
-                      Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
-  for (size_t i = 0; i < kNumOfUnProcessablePackets; ++i) {
-    time_wait_list_manager_.SendPublicReset(
-        self_address_, peer_address_, TestConnectionId(1),
-        /*ietf_quic=*/true,
-        /*received_packet_length=*/
-        QuicFramer::GetMinStatelessResetPacketLength() + 1,
-        /*packet_context=*/nullptr);
-  }
-  // Verify pending packet queue size is limited.
-  EXPECT_EQ(5u, QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
-                    &time_wait_list_manager_));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_trace_visitor.cc b/quic/core/quic_trace_visitor.cc
deleted file mode 100644
index 20a8d43..0000000
--- a/quic/core/quic_trace_visitor.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_trace_visitor.h"
-
-#include <string>
-
-#include "quic/core/quic_types.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-quic_trace::EncryptionLevel EncryptionLevelToProto(EncryptionLevel level) {
-  switch (level) {
-    case ENCRYPTION_INITIAL:
-      return quic_trace::ENCRYPTION_INITIAL;
-    case ENCRYPTION_HANDSHAKE:
-      return quic_trace::ENCRYPTION_HANDSHAKE;
-    case ENCRYPTION_ZERO_RTT:
-      return quic_trace::ENCRYPTION_0RTT;
-    case ENCRYPTION_FORWARD_SECURE:
-      return quic_trace::ENCRYPTION_1RTT;
-    case NUM_ENCRYPTION_LEVELS:
-      QUIC_BUG(quic_bug_10284_1) << "Invalid encryption level specified";
-      return quic_trace::ENCRYPTION_UNKNOWN;
-  }
-}
-
-QuicTraceVisitor::QuicTraceVisitor(const QuicConnection* connection)
-    : connection_(connection),
-      start_time_(connection_->clock()->ApproximateNow()) {
-  std::string binary_connection_id(connection->connection_id().data(),
-                                   connection->connection_id().length());
-  // We assume that the connection ID in gQUIC is equivalent to the
-  // server-chosen client-selected ID.
-  switch (connection->perspective()) {
-    case Perspective::IS_CLIENT:
-      trace_.set_destination_connection_id(binary_connection_id);
-      break;
-    case Perspective::IS_SERVER:
-      trace_.set_source_connection_id(binary_connection_id);
-      break;
-  }
-}
-
-void QuicTraceVisitor::OnPacketSent(
-    QuicPacketNumber packet_number,
-    QuicPacketLength packet_length,
-    bool /*has_crypto_handshake*/,
-    TransmissionType /*transmission_type*/,
-    EncryptionLevel encryption_level,
-    const QuicFrames& retransmittable_frames,
-    const QuicFrames& /*nonretransmittable_frames*/,
-    QuicTime sent_time) {
-  quic_trace::Event* event = trace_.add_events();
-  event->set_event_type(quic_trace::PACKET_SENT);
-  event->set_time_us(ConvertTimestampToRecordedFormat(sent_time));
-  event->set_packet_number(packet_number.ToUint64());
-  event->set_packet_size(packet_length);
-  event->set_encryption_level(EncryptionLevelToProto(encryption_level));
-
-  for (const QuicFrame& frame : retransmittable_frames) {
-    switch (frame.type) {
-      case STREAM_FRAME:
-      case RST_STREAM_FRAME:
-      case CONNECTION_CLOSE_FRAME:
-      case WINDOW_UPDATE_FRAME:
-      case BLOCKED_FRAME:
-      case PING_FRAME:
-      case HANDSHAKE_DONE_FRAME:
-      case ACK_FREQUENCY_FRAME:
-        PopulateFrameInfo(frame, event->add_frames());
-        break;
-
-      case PADDING_FRAME:
-      case MTU_DISCOVERY_FRAME:
-      case STOP_WAITING_FRAME:
-      case ACK_FRAME:
-        QUIC_BUG(quic_bug_12732_1)
-            << "Frames of type are not retransmittable and are not supposed "
-               "to be in retransmittable_frames";
-        break;
-
-      // New IETF frames, not used in current gQUIC version.
-      case NEW_CONNECTION_ID_FRAME:
-      case RETIRE_CONNECTION_ID_FRAME:
-      case MAX_STREAMS_FRAME:
-      case STREAMS_BLOCKED_FRAME:
-      case PATH_RESPONSE_FRAME:
-      case PATH_CHALLENGE_FRAME:
-      case STOP_SENDING_FRAME:
-      case MESSAGE_FRAME:
-      case CRYPTO_FRAME:
-      case NEW_TOKEN_FRAME:
-        break;
-
-      // Ignore gQUIC-specific frames.
-      case GOAWAY_FRAME:
-        break;
-
-      case NUM_FRAME_TYPES:
-        QUIC_BUG(quic_bug_10284_2) << "Unknown frame type encountered";
-        break;
-    }
-  }
-
-  // Output PCC DebugState on packet sent for analysis.
-  if (connection_->sent_packet_manager()
-          .GetSendAlgorithm()
-          ->GetCongestionControlType() == kPCC) {
-    PopulateTransportState(event->mutable_transport_state());
-  }
-}
-
-void QuicTraceVisitor::PopulateFrameInfo(const QuicFrame& frame,
-                                         quic_trace::Frame* frame_record) {
-  switch (frame.type) {
-    case STREAM_FRAME: {
-      frame_record->set_frame_type(quic_trace::STREAM);
-
-      quic_trace::StreamFrameInfo* info =
-          frame_record->mutable_stream_frame_info();
-      info->set_stream_id(frame.stream_frame.stream_id);
-      info->set_fin(frame.stream_frame.fin);
-      info->set_offset(frame.stream_frame.offset);
-      info->set_length(frame.stream_frame.data_length);
-      break;
-    }
-
-    case ACK_FRAME: {
-      frame_record->set_frame_type(quic_trace::ACK);
-
-      quic_trace::AckInfo* info = frame_record->mutable_ack_info();
-      info->set_ack_delay_us(frame.ack_frame->ack_delay_time.ToMicroseconds());
-      for (const auto& interval : frame.ack_frame->packets) {
-        quic_trace::AckBlock* block = info->add_acked_packets();
-        // We record intervals as [a, b], whereas the in-memory representation
-        // we currently use is [a, b).
-        block->set_first_packet(interval.min().ToUint64());
-        block->set_last_packet(interval.max().ToUint64() - 1);
-      }
-      break;
-    }
-
-    case RST_STREAM_FRAME: {
-      frame_record->set_frame_type(quic_trace::RESET_STREAM);
-
-      quic_trace::ResetStreamInfo* info =
-          frame_record->mutable_reset_stream_info();
-      info->set_stream_id(frame.rst_stream_frame->stream_id);
-      info->set_final_offset(frame.rst_stream_frame->byte_offset);
-      info->set_application_error_code(frame.rst_stream_frame->error_code);
-      break;
-    }
-
-    case CONNECTION_CLOSE_FRAME: {
-      frame_record->set_frame_type(quic_trace::CONNECTION_CLOSE);
-
-      quic_trace::CloseInfo* info = frame_record->mutable_close_info();
-      info->set_error_code(frame.connection_close_frame->quic_error_code);
-      info->set_reason_phrase(frame.connection_close_frame->error_details);
-      info->set_close_type(static_cast<quic_trace::CloseType>(
-          frame.connection_close_frame->close_type));
-      info->set_transport_close_frame_type(
-          frame.connection_close_frame->transport_close_frame_type);
-      break;
-    }
-
-    case GOAWAY_FRAME:
-      // Do not bother logging this since the frame in question is
-      // gQUIC-specific.
-      break;
-
-    case WINDOW_UPDATE_FRAME: {
-      bool is_connection = frame.window_update_frame.stream_id == 0;
-      frame_record->set_frame_type(is_connection ? quic_trace::MAX_DATA
-                                                 : quic_trace::MAX_STREAM_DATA);
-
-      quic_trace::FlowControlInfo* info =
-          frame_record->mutable_flow_control_info();
-      info->set_max_data(frame.window_update_frame.max_data);
-      if (!is_connection) {
-        info->set_stream_id(frame.window_update_frame.stream_id);
-      }
-      break;
-    }
-
-    case BLOCKED_FRAME: {
-      bool is_connection = frame.blocked_frame.stream_id == 0;
-      frame_record->set_frame_type(is_connection ? quic_trace::BLOCKED
-                                                 : quic_trace::STREAM_BLOCKED);
-
-      quic_trace::FlowControlInfo* info =
-          frame_record->mutable_flow_control_info();
-      if (!is_connection) {
-        info->set_stream_id(frame.window_update_frame.stream_id);
-      }
-      break;
-    }
-
-    case PING_FRAME:
-    case MTU_DISCOVERY_FRAME:
-    case HANDSHAKE_DONE_FRAME:
-      frame_record->set_frame_type(quic_trace::PING);
-      break;
-
-    case PADDING_FRAME:
-      frame_record->set_frame_type(quic_trace::PADDING);
-      break;
-
-    case STOP_WAITING_FRAME:
-      // We're going to pretend those do not exist.
-      break;
-
-    // New IETF frames, not used in current gQUIC version.
-    case NEW_CONNECTION_ID_FRAME:
-    case RETIRE_CONNECTION_ID_FRAME:
-    case MAX_STREAMS_FRAME:
-    case STREAMS_BLOCKED_FRAME:
-    case PATH_RESPONSE_FRAME:
-    case PATH_CHALLENGE_FRAME:
-    case STOP_SENDING_FRAME:
-    case MESSAGE_FRAME:
-    case CRYPTO_FRAME:
-    case NEW_TOKEN_FRAME:
-    case ACK_FREQUENCY_FRAME:
-      break;
-
-    case NUM_FRAME_TYPES:
-      QUIC_BUG(quic_bug_10284_3) << "Unknown frame type encountered";
-      break;
-  }
-}
-
-void QuicTraceVisitor::OnIncomingAck(
-    QuicPacketNumber /*ack_packet_number*/,
-    EncryptionLevel ack_decrypted_level,
-    const QuicAckFrame& ack_frame,
-    QuicTime ack_receive_time,
-    QuicPacketNumber /*largest_observed*/,
-    bool /*rtt_updated*/,
-    QuicPacketNumber /*least_unacked_sent_packet*/) {
-  quic_trace::Event* event = trace_.add_events();
-  event->set_time_us(ConvertTimestampToRecordedFormat(ack_receive_time));
-  event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
-  event->set_event_type(quic_trace::PACKET_RECEIVED);
-  event->set_encryption_level(EncryptionLevelToProto(ack_decrypted_level));
-
-  // TODO(vasilvv): consider removing this copy.
-  QuicAckFrame copy_of_ack = ack_frame;
-  PopulateFrameInfo(QuicFrame(&copy_of_ack), event->add_frames());
-  PopulateTransportState(event->mutable_transport_state());
-}
-
-void QuicTraceVisitor::OnPacketLoss(QuicPacketNumber lost_packet_number,
-                                    EncryptionLevel encryption_level,
-                                    TransmissionType /*transmission_type*/,
-                                    QuicTime detection_time) {
-  quic_trace::Event* event = trace_.add_events();
-  event->set_time_us(ConvertTimestampToRecordedFormat(detection_time));
-  event->set_event_type(quic_trace::PACKET_LOST);
-  event->set_packet_number(lost_packet_number.ToUint64());
-  PopulateTransportState(event->mutable_transport_state());
-  event->set_encryption_level(EncryptionLevelToProto(encryption_level));
-}
-
-void QuicTraceVisitor::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
-                                           const QuicTime& receive_time) {
-  quic_trace::Event* event = trace_.add_events();
-  event->set_time_us(ConvertTimestampToRecordedFormat(receive_time));
-  event->set_event_type(quic_trace::PACKET_RECEIVED);
-  event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
-
-  PopulateFrameInfo(QuicFrame(frame), event->add_frames());
-}
-
-void QuicTraceVisitor::OnSuccessfulVersionNegotiation(
-    const ParsedQuicVersion& version) {
-  uint32_t tag =
-      quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version));
-  std::string binary_tag(reinterpret_cast<const char*>(&tag), sizeof(tag));
-  trace_.set_protocol_version(binary_tag);
-}
-
-void QuicTraceVisitor::OnApplicationLimited() {
-  quic_trace::Event* event = trace_.add_events();
-  event->set_time_us(
-      ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
-  event->set_event_type(quic_trace::APPLICATION_LIMITED);
-}
-
-void QuicTraceVisitor::OnAdjustNetworkParameters(QuicBandwidth bandwidth,
-                                                 QuicTime::Delta rtt,
-                                                 QuicByteCount /*old_cwnd*/,
-                                                 QuicByteCount /*new_cwnd*/) {
-  quic_trace::Event* event = trace_.add_events();
-  event->set_time_us(
-      ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
-  event->set_event_type(quic_trace::EXTERNAL_PARAMETERS);
-
-  quic_trace::ExternalNetworkParameters* parameters =
-      event->mutable_external_network_parameters();
-  if (!bandwidth.IsZero()) {
-    parameters->set_bandwidth_bps(bandwidth.ToBitsPerSecond());
-  }
-  if (!rtt.IsZero()) {
-    parameters->set_rtt_us(rtt.ToMicroseconds());
-  }
-}
-
-uint64_t QuicTraceVisitor::ConvertTimestampToRecordedFormat(
-    QuicTime timestamp) {
-  if (timestamp < start_time_) {
-    QUIC_BUG(quic_bug_10284_4)
-        << "Timestamp went back in time while recording a trace";
-    return 0;
-  }
-
-  return (timestamp - start_time_).ToMicroseconds();
-}
-
-void QuicTraceVisitor::PopulateTransportState(
-    quic_trace::TransportState* state) {
-  const RttStats* rtt_stats = connection_->sent_packet_manager().GetRttStats();
-  state->set_min_rtt_us(rtt_stats->min_rtt().ToMicroseconds());
-  state->set_smoothed_rtt_us(rtt_stats->smoothed_rtt().ToMicroseconds());
-  state->set_last_rtt_us(rtt_stats->latest_rtt().ToMicroseconds());
-
-  state->set_cwnd_bytes(
-      connection_->sent_packet_manager().GetCongestionWindowInBytes());
-  QuicByteCount in_flight =
-      connection_->sent_packet_manager().GetBytesInFlight();
-  state->set_in_flight_bytes(in_flight);
-  state->set_pacing_rate_bps(connection_->sent_packet_manager()
-                                 .GetSendAlgorithm()
-                                 ->PacingRate(in_flight)
-                                 .ToBitsPerSecond());
-
-  if (connection_->sent_packet_manager()
-          .GetSendAlgorithm()
-          ->GetCongestionControlType() == kPCC) {
-    state->set_congestion_control_state(
-        connection_->sent_packet_manager().GetSendAlgorithm()->GetDebugState());
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_trace_visitor.h b/quic/core/quic_trace_visitor.h
deleted file mode 100644
index 47d543a..0000000
--- a/quic/core/quic_trace_visitor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
-#define QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
-
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_types.h"
-#include "third_party/quic_trace/lib/quic_trace.pb.h"
-
-namespace quic {
-
-// Records a QUIC trace protocol buffer for a QuicConnection.  It's the
-// responsibility of the user of this visitor to process or store the resulting
-// trace, which can be accessed via trace().
-class QUIC_NO_EXPORT QuicTraceVisitor : public QuicConnectionDebugVisitor {
- public:
-  explicit QuicTraceVisitor(const QuicConnection* connection);
-
-  void OnPacketSent(QuicPacketNumber packet_number,
-                    QuicPacketLength packet_length,
-                    bool has_crypto_handshake,
-                    TransmissionType transmission_type,
-                    EncryptionLevel encryption_level,
-                    const QuicFrames& retransmittable_frames,
-                    const QuicFrames& nonretransmittable_frames,
-                    QuicTime sent_time) override;
-
-  void OnIncomingAck(QuicPacketNumber ack_packet_number,
-                     EncryptionLevel ack_decrypted_level,
-                     const QuicAckFrame& ack_frame,
-                     QuicTime ack_receive_time,
-                     QuicPacketNumber largest_observed,
-                     bool rtt_updated,
-                     QuicPacketNumber least_unacked_sent_packet) override;
-
-  void OnPacketLoss(QuicPacketNumber lost_packet_number,
-                    EncryptionLevel encryption_level,
-                    TransmissionType transmission_type,
-                    QuicTime detection_time) override;
-
-  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
-                           const QuicTime& receive_time) override;
-
-  void OnSuccessfulVersionNegotiation(
-      const ParsedQuicVersion& version) override;
-
-  void OnApplicationLimited() override;
-
-  void OnAdjustNetworkParameters(QuicBandwidth bandwidth,
-                                 QuicTime::Delta rtt,
-                                 QuicByteCount old_cwnd,
-                                 QuicByteCount new_cwnd) override;
-
-  // Returns a mutable pointer to the trace.  The trace is owned by the
-  // visitor, but can be moved using Swap() method after the connection is
-  // finished.
-  quic_trace::Trace* trace() { return &trace_; }
-
- private:
-  // Converts QuicTime into a microsecond delta w.r.t. the beginning of the
-  // connection.
-  uint64_t ConvertTimestampToRecordedFormat(QuicTime timestamp);
-  // Populates a quic_trace::Frame message from |frame|.
-  void PopulateFrameInfo(const QuicFrame& frame,
-                         quic_trace::Frame* frame_record);
-  // Populates a quic_trace::TransportState message from the associated
-  // connection.
-  void PopulateTransportState(quic_trace::TransportState* state);
-
-  quic_trace::Trace trace_;
-  const QuicConnection* connection_;
-  const QuicTime start_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
diff --git a/quic/core/quic_trace_visitor_test.cc b/quic/core/quic_trace_visitor_test.cc
deleted file mode 100644
index 4deec7c..0000000
--- a/quic/core/quic_trace_visitor_test.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_trace_visitor.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/quic_endpoint.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace {
-
-const QuicByteCount kTransferSize = 1000 * kMaxOutgoingPacketSize;
-const QuicByteCount kTestStreamNumber = 3;
-const QuicTime::Delta kDelay = QuicTime::Delta::FromMilliseconds(20);
-
-// The trace for this test is generated using a simulator transfer.
-class QuicTraceVisitorTest : public QuicTest {
- public:
-  QuicTraceVisitorTest() {
-    QuicConnectionId connection_id = test::TestConnectionId();
-    simulator::Simulator simulator;
-    simulator::QuicEndpoint client(&simulator, "Client", "Server",
-                                   Perspective::IS_CLIENT, connection_id);
-    simulator::QuicEndpoint server(&simulator, "Server", "Client",
-                                   Perspective::IS_SERVER, connection_id);
-
-    const QuicBandwidth kBandwidth = QuicBandwidth::FromKBitsPerSecond(1000);
-    const QuicByteCount kBdp = kBandwidth * (2 * kDelay);
-
-    // Create parameters such that some loss is observed.
-    simulator::Switch network_switch(&simulator, "Switch", 8, 0.5 * kBdp);
-    simulator::SymmetricLink client_link(&client, network_switch.port(1),
-                                         2 * kBandwidth, kDelay);
-    simulator::SymmetricLink server_link(&server, network_switch.port(2),
-                                         kBandwidth, kDelay);
-
-    QuicTraceVisitor visitor(client.connection());
-    client.connection()->set_debug_visitor(&visitor);
-
-    // Transfer about a megabyte worth of data from client to server.
-    const QuicTime::Delta kDeadline =
-        3 * kBandwidth.TransferTime(kTransferSize);
-    client.AddBytesToTransfer(kTransferSize);
-    bool simulator_result = simulator.RunUntilOrTimeout(
-        [&]() { return server.bytes_received() >= kTransferSize; }, kDeadline);
-    QUICHE_CHECK(simulator_result);
-
-    // Save the trace and ensure some loss was observed.
-    trace_.Swap(visitor.trace());
-    QUICHE_CHECK_NE(0u, client.connection()->GetStats().packets_retransmitted);
-    packets_sent_ = client.connection()->GetStats().packets_sent;
-  }
-
-  std::vector<quic_trace::Event> AllEventsWithType(
-      quic_trace::EventType event_type) {
-    std::vector<quic_trace::Event> result;
-    for (const auto& event : trace_.events()) {
-      if (event.event_type() == event_type) {
-        result.push_back(event);
-      }
-    }
-    return result;
-  }
-
- protected:
-  quic_trace::Trace trace_;
-  QuicPacketCount packets_sent_;
-};
-
-TEST_F(QuicTraceVisitorTest, ConnectionId) {
-  char expected_cid[] = {0, 0, 0, 0, 0, 0, 0, 42};
-  EXPECT_EQ(std::string(expected_cid, sizeof(expected_cid)),
-            trace_.destination_connection_id());
-}
-
-TEST_F(QuicTraceVisitorTest, Version) {
-  std::string version = trace_.protocol_version();
-  ASSERT_EQ(4u, version.size());
-  // Ensure version isn't all-zeroes.
-  EXPECT_TRUE(version[0] != 0 || version[1] != 0 || version[2] != 0 ||
-              version[3] != 0);
-}
-
-// Check that basic metadata about sent packets is recorded.
-TEST_F(QuicTraceVisitorTest, SentPacket) {
-  auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
-  EXPECT_EQ(packets_sent_, sent_packets.size());
-  ASSERT_GT(sent_packets.size(), 0u);
-
-  EXPECT_EQ(sent_packets[0].packet_size(), kDefaultMaxPacketSize);
-  EXPECT_EQ(sent_packets[0].packet_number(), 1u);
-}
-
-// Ensure that every stream frame that was sent is recorded.
-TEST_F(QuicTraceVisitorTest, SentStream) {
-  auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
-
-  QuicIntervalSet<QuicStreamOffset> offsets;
-  for (const quic_trace::Event& packet : sent_packets) {
-    for (const quic_trace::Frame& frame : packet.frames()) {
-      if (frame.frame_type() != quic_trace::STREAM) {
-        continue;
-      }
-
-      const quic_trace::StreamFrameInfo& info = frame.stream_frame_info();
-      if (info.stream_id() != kTestStreamNumber) {
-        continue;
-      }
-
-      ASSERT_GT(info.length(), 0u);
-      offsets.Add(info.offset(), info.offset() + info.length());
-    }
-  }
-
-  ASSERT_EQ(1u, offsets.Size());
-  EXPECT_EQ(0u, offsets.begin()->min());
-  EXPECT_EQ(kTransferSize, offsets.rbegin()->max());
-}
-
-// Ensure that all packets are either acknowledged or lost.
-TEST_F(QuicTraceVisitorTest, AckPackets) {
-  QuicIntervalSet<QuicPacketNumber> packets;
-  for (const quic_trace::Event& packet : trace_.events()) {
-    if (packet.event_type() == quic_trace::PACKET_RECEIVED) {
-      for (const quic_trace::Frame& frame : packet.frames()) {
-        if (frame.frame_type() != quic_trace::ACK) {
-          continue;
-        }
-
-        const quic_trace::AckInfo& info = frame.ack_info();
-        for (const auto& block : info.acked_packets()) {
-          packets.Add(QuicPacketNumber(block.first_packet()),
-                      QuicPacketNumber(block.last_packet()) + 1);
-        }
-      }
-    }
-    if (packet.event_type() == quic_trace::PACKET_LOST) {
-      packets.Add(QuicPacketNumber(packet.packet_number()),
-                  QuicPacketNumber(packet.packet_number()) + 1);
-    }
-  }
-
-  ASSERT_EQ(1u, packets.Size());
-  EXPECT_EQ(QuicPacketNumber(1u), packets.begin()->min());
-  // We leave some room (20 packets) for the packets which did not receive
-  // conclusive status at the end of simulation.
-  EXPECT_GT(packets.rbegin()->max(), QuicPacketNumber(packets_sent_ - 20));
-}
-
-TEST_F(QuicTraceVisitorTest, TransportState) {
-  auto acks = AllEventsWithType(quic_trace::PACKET_RECEIVED);
-  ASSERT_EQ(1, acks[0].frames_size());
-  ASSERT_EQ(quic_trace::ACK, acks[0].frames(0).frame_type());
-
-  // Check that min-RTT at the end is a reasonable approximation.
-  EXPECT_LE((4 * kDelay).ToMicroseconds() * 1.,
-            acks.rbegin()->transport_state().min_rtt_us());
-  EXPECT_GE((4 * kDelay).ToMicroseconds() * 1.25,
-            acks.rbegin()->transport_state().min_rtt_us());
-}
-
-TEST_F(QuicTraceVisitorTest, EncryptionLevels) {
-  for (const auto& event : trace_.events()) {
-    switch (event.event_type()) {
-      case quic_trace::PACKET_SENT:
-      case quic_trace::PACKET_RECEIVED:
-      case quic_trace::PACKET_LOST:
-        ASSERT_TRUE(event.has_encryption_level());
-        ASSERT_NE(event.encryption_level(), quic_trace::ENCRYPTION_UNKNOWN);
-        break;
-
-      default:
-        break;
-    }
-  }
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/core/quic_transmission_info.cc b/quic/core/quic_transmission_info.cc
deleted file mode 100644
index 9ec0f39..0000000
--- a/quic/core/quic_transmission_info.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_transmission_info.h"
-#include "absl/strings/str_cat.h"
-
-namespace quic {
-
-QuicTransmissionInfo::QuicTransmissionInfo()
-    : sent_time(QuicTime::Zero()),
-      bytes_sent(0),
-      encryption_level(ENCRYPTION_INITIAL),
-      transmission_type(NOT_RETRANSMISSION),
-      in_flight(false),
-      state(OUTSTANDING),
-      has_crypto_handshake(false),
-      has_ack_frequency(false) {}
-
-QuicTransmissionInfo::QuicTransmissionInfo(EncryptionLevel level,
-                                           TransmissionType transmission_type,
-                                           QuicTime sent_time,
-                                           QuicPacketLength bytes_sent,
-                                           bool has_crypto_handshake,
-                                           bool has_ack_frequency)
-    : sent_time(sent_time),
-      bytes_sent(bytes_sent),
-      encryption_level(level),
-      transmission_type(transmission_type),
-      in_flight(false),
-      state(OUTSTANDING),
-      has_crypto_handshake(has_crypto_handshake),
-      has_ack_frequency(has_ack_frequency) {}
-
-QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) =
-    default;
-
-QuicTransmissionInfo::~QuicTransmissionInfo() {}
-
-std::string QuicTransmissionInfo::DebugString() const {
-  return absl::StrCat(
-      "{sent_time: ", sent_time.ToDebuggingValue(),
-      ", bytes_sent: ", bytes_sent,
-      ", encryption_level: ", EncryptionLevelToString(encryption_level),
-      ", transmission_type: ", TransmissionTypeToString(transmission_type),
-      ", in_flight: ", in_flight, ", state: ", state,
-      ", has_crypto_handshake: ", has_crypto_handshake,
-      ", has_ack_frequency: ", has_ack_frequency,
-      ", first_sent_after_loss: ", first_sent_after_loss.ToString(),
-      ", largest_acked: ", largest_acked.ToString(),
-      ", retransmittable_frames: ", QuicFramesToString(retransmittable_frames),
-      "}");
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_transmission_info.h b/quic/core/quic_transmission_info.h
deleted file mode 100644
index bc0f5f7..0000000
--- a/quic/core/quic_transmission_info.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
-#define QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
-
-#include <list>
-
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_ack_listener_interface.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Stores details of a single sent packet.
-struct QUIC_EXPORT_PRIVATE QuicTransmissionInfo {
-  // Used by STL when assigning into a map.
-  QuicTransmissionInfo();
-
-  // Constructs a Transmission with a new all_transmissions set
-  // containing |packet_number|.
-  QuicTransmissionInfo(EncryptionLevel level,
-                       TransmissionType transmission_type,
-                       QuicTime sent_time,
-                       QuicPacketLength bytes_sent,
-                       bool has_crypto_handshake,
-                       bool has_ack_frequency);
-
-  QuicTransmissionInfo(const QuicTransmissionInfo& other);
-
-  ~QuicTransmissionInfo();
-
-  std::string DebugString() const;
-
-  QuicFrames retransmittable_frames;
-  QuicTime sent_time;
-  QuicPacketLength bytes_sent;
-  EncryptionLevel encryption_level;
-  // Reason why this packet was transmitted.
-  TransmissionType transmission_type;
-  // In flight packets have not been abandoned or lost.
-  bool in_flight;
-  // State of this packet.
-  SentPacketState state;
-  // True if the packet contains stream data from the crypto stream.
-  bool has_crypto_handshake;
-  // True if the packet contains ack frequency frame.
-  bool has_ack_frequency;
-  // Records the first sent packet after this packet was detected lost. Zero if
-  // this packet has not been detected lost. This is used to keep lost packet
-  // for another RTT (for potential spurious loss detection)
-  QuicPacketNumber first_sent_after_loss;
-  // The largest_acked in the ack frame, if the packet contains an ack.
-  QuicPacketNumber largest_acked;
-};
-// TODO(ianswett): Add static_assert when size of this struct is reduced below
-// 64 bytes.
-// NOTE(vlovich): Existing static_assert removed because padding differences on
-// 64-bit iOS resulted in an 88-byte struct that is greater than the 84-byte
-// limit on other platforms.  Removing per ianswett's request.
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc
deleted file mode 100644
index 7120670..0000000
--- a/quic/core/quic_types.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_types.h"
-
-#include <cstdint>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_error_codes.h"
-#include "common/print_elements.h"
-
-namespace quic {
-
-static_assert(sizeof(StatelessResetToken) == kStatelessResetTokenLength,
-              "bad size");
-
-std::ostream& operator<<(std::ostream& os, const QuicConsumedData& s) {
-  os << "bytes_consumed: " << s.bytes_consumed
-     << " fin_consumed: " << s.fin_consumed;
-  return os;
-}
-
-std::string PerspectiveToString(Perspective perspective) {
-  if (perspective == Perspective::IS_SERVER) {
-    return "IS_SERVER";
-  }
-  if (perspective == Perspective::IS_CLIENT) {
-    return "IS_CLIENT";
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(perspective), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const Perspective& perspective) {
-  os << PerspectiveToString(perspective);
-  return os;
-}
-
-std::string ConnectionCloseSourceToString(
-    ConnectionCloseSource connection_close_source) {
-  if (connection_close_source == ConnectionCloseSource::FROM_PEER) {
-    return "FROM_PEER";
-  }
-  if (connection_close_source == ConnectionCloseSource::FROM_SELF) {
-    return "FROM_SELF";
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(connection_close_source),
-                      ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const ConnectionCloseSource& connection_close_source) {
-  os << ConnectionCloseSourceToString(connection_close_source);
-  return os;
-}
-
-std::string ConnectionCloseBehaviorToString(
-    ConnectionCloseBehavior connection_close_behavior) {
-  if (connection_close_behavior == ConnectionCloseBehavior::SILENT_CLOSE) {
-    return "SILENT_CLOSE";
-  }
-  if (connection_close_behavior ==
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET) {
-    return "SEND_CONNECTION_CLOSE_PACKET";
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(connection_close_behavior),
-                      ")");
-}
-
-std::ostream& operator<<(
-    std::ostream& os,
-    const ConnectionCloseBehavior& connection_close_behavior) {
-  os << ConnectionCloseBehaviorToString(connection_close_behavior);
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const AckedPacket& acked_packet) {
-  os << "{ packet_number: " << acked_packet.packet_number
-     << ", bytes_acked: " << acked_packet.bytes_acked << ", receive_timestamp: "
-     << acked_packet.receive_timestamp.ToDebuggingValue() << "} ";
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const LostPacket& lost_packet) {
-  os << "{ packet_number: " << lost_packet.packet_number
-     << ", bytes_lost: " << lost_packet.bytes_lost << "} ";
-  return os;
-}
-
-std::string HistogramEnumString(WriteStatus enum_value) {
-  switch (enum_value) {
-    case WRITE_STATUS_OK:
-      return "OK";
-    case WRITE_STATUS_BLOCKED:
-      return "BLOCKED";
-    case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
-      return "BLOCKED_DATA_BUFFERED";
-    case WRITE_STATUS_ERROR:
-      return "ERROR";
-    case WRITE_STATUS_MSG_TOO_BIG:
-      return "MSG_TOO_BIG";
-    case WRITE_STATUS_FAILED_TO_COALESCE_PACKET:
-      return "WRITE_STATUS_FAILED_TO_COALESCE_PACKET";
-    case WRITE_STATUS_NUM_VALUES:
-      return "NUM_VALUES";
-  }
-  QUIC_DLOG(ERROR) << "Invalid WriteStatus value: "
-                   << static_cast<int16_t>(enum_value);
-  return "<invalid>";
-}
-
-std::ostream& operator<<(std::ostream& os, const WriteStatus& status) {
-  os << HistogramEnumString(status);
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os, const WriteResult& s) {
-  os << "{ status: " << s.status;
-  if (s.status == WRITE_STATUS_OK) {
-    os << ", bytes_written: " << s.bytes_written;
-  } else {
-    os << ", error_code: " << s.error_code;
-  }
-  os << " }";
-  return os;
-}
-
-MessageResult::MessageResult(MessageStatus status, QuicMessageId message_id)
-    : status(status), message_id(message_id) {}
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x;
-
-std::string QuicFrameTypeToString(QuicFrameType t) {
-  switch (t) {
-    RETURN_STRING_LITERAL(PADDING_FRAME)
-    RETURN_STRING_LITERAL(RST_STREAM_FRAME)
-    RETURN_STRING_LITERAL(CONNECTION_CLOSE_FRAME)
-    RETURN_STRING_LITERAL(GOAWAY_FRAME)
-    RETURN_STRING_LITERAL(WINDOW_UPDATE_FRAME)
-    RETURN_STRING_LITERAL(BLOCKED_FRAME)
-    RETURN_STRING_LITERAL(STOP_WAITING_FRAME)
-    RETURN_STRING_LITERAL(PING_FRAME)
-    RETURN_STRING_LITERAL(CRYPTO_FRAME)
-    RETURN_STRING_LITERAL(HANDSHAKE_DONE_FRAME)
-    RETURN_STRING_LITERAL(STREAM_FRAME)
-    RETURN_STRING_LITERAL(ACK_FRAME)
-    RETURN_STRING_LITERAL(MTU_DISCOVERY_FRAME)
-    RETURN_STRING_LITERAL(NEW_CONNECTION_ID_FRAME)
-    RETURN_STRING_LITERAL(MAX_STREAMS_FRAME)
-    RETURN_STRING_LITERAL(STREAMS_BLOCKED_FRAME)
-    RETURN_STRING_LITERAL(PATH_RESPONSE_FRAME)
-    RETURN_STRING_LITERAL(PATH_CHALLENGE_FRAME)
-    RETURN_STRING_LITERAL(STOP_SENDING_FRAME)
-    RETURN_STRING_LITERAL(MESSAGE_FRAME)
-    RETURN_STRING_LITERAL(NEW_TOKEN_FRAME)
-    RETURN_STRING_LITERAL(RETIRE_CONNECTION_ID_FRAME)
-    RETURN_STRING_LITERAL(ACK_FREQUENCY_FRAME)
-    RETURN_STRING_LITERAL(NUM_FRAME_TYPES)
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(t), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicFrameType& t) {
-  os << QuicFrameTypeToString(t);
-  return os;
-}
-
-std::string QuicIetfFrameTypeString(QuicIetfFrameType t) {
-  if (IS_IETF_STREAM_FRAME(t)) {
-    return "IETF_STREAM";
-  }
-
-  switch (t) {
-    RETURN_STRING_LITERAL(IETF_PADDING);
-    RETURN_STRING_LITERAL(IETF_PING);
-    RETURN_STRING_LITERAL(IETF_ACK);
-    RETURN_STRING_LITERAL(IETF_ACK_ECN);
-    RETURN_STRING_LITERAL(IETF_RST_STREAM);
-    RETURN_STRING_LITERAL(IETF_STOP_SENDING);
-    RETURN_STRING_LITERAL(IETF_CRYPTO);
-    RETURN_STRING_LITERAL(IETF_NEW_TOKEN);
-    RETURN_STRING_LITERAL(IETF_MAX_DATA);
-    RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA);
-    RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL);
-    RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL);
-    RETURN_STRING_LITERAL(IETF_DATA_BLOCKED);
-    RETURN_STRING_LITERAL(IETF_STREAM_DATA_BLOCKED);
-    RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL);
-    RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
-    RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID);
-    RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID);
-    RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE);
-    RETURN_STRING_LITERAL(IETF_PATH_RESPONSE);
-    RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE);
-    RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE);
-    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH);
-    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE);
-    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99);
-    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_V99);
-    default:
-      return absl::StrCat("Private value (", t, ")");
-  }
-}
-std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) {
-  os << QuicIetfFrameTypeString(c);
-  return os;
-}
-
-std::string TransmissionTypeToString(TransmissionType transmission_type) {
-  switch (transmission_type) {
-    RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
-    RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
-    RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
-    RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
-    RETURN_STRING_LITERAL(RTO_RETRANSMISSION);
-    RETURN_STRING_LITERAL(TLP_RETRANSMISSION);
-    RETURN_STRING_LITERAL(PTO_RETRANSMISSION);
-    RETURN_STRING_LITERAL(PROBING_RETRANSMISSION);
-    RETURN_STRING_LITERAL(PATH_RETRANSMISSION);
-    RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
-    default:
-      // Some varz rely on this behavior for statistic collection.
-      if (transmission_type == LAST_TRANSMISSION_TYPE + 1) {
-        return "INVALID_TRANSMISSION_TYPE";
-      }
-      return absl::StrCat("Unknown(", static_cast<int>(transmission_type), ")");
-  }
-}
-
-std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
-  os << TransmissionTypeToString(transmission_type);
-  return os;
-}
-
-std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
-  switch (format) {
-    RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
-    RETURN_STRING_LITERAL(IETF_QUIC_SHORT_HEADER_PACKET);
-    RETURN_STRING_LITERAL(GOOGLE_QUIC_PACKET);
-    default:
-      return absl::StrCat("Unknown (", static_cast<int>(format), ")");
-  }
-}
-
-std::string QuicLongHeaderTypeToString(QuicLongHeaderType type) {
-  switch (type) {
-    RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
-    RETURN_STRING_LITERAL(INITIAL);
-    RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
-    RETURN_STRING_LITERAL(HANDSHAKE);
-    RETURN_STRING_LITERAL(RETRY);
-    RETURN_STRING_LITERAL(INVALID_PACKET_TYPE);
-    default:
-      return absl::StrCat("Unknown (", static_cast<int>(type), ")");
-  }
-}
-
-std::string MessageStatusToString(MessageStatus message_status) {
-  switch (message_status) {
-    RETURN_STRING_LITERAL(MESSAGE_STATUS_SUCCESS);
-    RETURN_STRING_LITERAL(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED);
-    RETURN_STRING_LITERAL(MESSAGE_STATUS_UNSUPPORTED);
-    RETURN_STRING_LITERAL(MESSAGE_STATUS_BLOCKED);
-    RETURN_STRING_LITERAL(MESSAGE_STATUS_TOO_LARGE);
-    RETURN_STRING_LITERAL(MESSAGE_STATUS_INTERNAL_ERROR);
-    default:
-      return absl::StrCat("Unknown(", static_cast<int>(message_status), ")");
-  }
-}
-
-std::string MessageResultToString(MessageResult message_result) {
-  if (message_result.status != MESSAGE_STATUS_SUCCESS) {
-    return absl::StrCat("{", MessageStatusToString(message_result.status), "}");
-  }
-  return absl::StrCat("{MESSAGE_STATUS_SUCCESS,id=", message_result.message_id,
-                      "}");
-}
-
-std::ostream& operator<<(std::ostream& os, const MessageResult& mr) {
-  os << MessageResultToString(mr);
-  return os;
-}
-
-std::string PacketNumberSpaceToString(PacketNumberSpace packet_number_space) {
-  switch (packet_number_space) {
-    RETURN_STRING_LITERAL(INITIAL_DATA);
-    RETURN_STRING_LITERAL(HANDSHAKE_DATA);
-    RETURN_STRING_LITERAL(APPLICATION_DATA);
-    default:
-      return absl::StrCat("Unknown(", static_cast<int>(packet_number_space),
-                          ")");
-  }
-}
-
-std::string SerializedPacketFateToString(SerializedPacketFate fate) {
-  switch (fate) {
-    RETURN_STRING_LITERAL(DISCARD);
-    RETURN_STRING_LITERAL(COALESCE);
-    RETURN_STRING_LITERAL(BUFFER);
-    RETURN_STRING_LITERAL(SEND_TO_WRITER);
-    RETURN_STRING_LITERAL(LEGACY_VERSION_ENCAPSULATE);
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
-  os << SerializedPacketFateToString(fate);
-  return os;
-}
-
-std::string EncryptionLevelToString(EncryptionLevel level) {
-  switch (level) {
-    RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
-    RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
-    RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
-    RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
-    default:
-      return absl::StrCat("Unknown(", static_cast<int>(level), ")");
-  }
-}
-
-std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
-  os << EncryptionLevelToString(level);
-  return os;
-}
-
-absl::string_view ClientCertModeToString(ClientCertMode mode) {
-#define RETURN_REASON_LITERAL(x) \
-  case ClientCertMode::x:        \
-    return #x
-  switch (mode) {
-    RETURN_REASON_LITERAL(kNone);
-    RETURN_REASON_LITERAL(kRequest);
-    RETURN_REASON_LITERAL(kRequire);
-    default:
-      return "<invalid>";
-  }
-#undef RETURN_REASON_LITERAL
-}
-
-std::ostream& operator<<(std::ostream& os, ClientCertMode mode) {
-  os << ClientCertModeToString(mode);
-  return os;
-}
-
-std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
-  switch (type) {
-    RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
-    RETURN_STRING_LITERAL(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE);
-    RETURN_STRING_LITERAL(IETF_QUIC_APPLICATION_CONNECTION_CLOSE);
-    default:
-      return absl::StrCat("Unknown(", static_cast<int>(type), ")");
-  }
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicConnectionCloseType type) {
-  os << QuicConnectionCloseTypeString(type);
-  return os;
-}
-
-std::string AddressChangeTypeToString(AddressChangeType type) {
-  using IntType = typename std::underlying_type<AddressChangeType>::type;
-  switch (type) {
-    RETURN_STRING_LITERAL(NO_CHANGE);
-    RETURN_STRING_LITERAL(PORT_CHANGE);
-    RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
-    RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
-    RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
-    RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
-    RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
-    default:
-      return absl::StrCat("Unknown(", static_cast<IntType>(type), ")");
-  }
-}
-
-std::ostream& operator<<(std::ostream& os, AddressChangeType type) {
-  os << AddressChangeTypeToString(type);
-  return os;
-}
-
-std::string KeyUpdateReasonString(KeyUpdateReason reason) {
-#define RETURN_REASON_LITERAL(x) \
-  case KeyUpdateReason::x:       \
-    return #x
-  switch (reason) {
-    RETURN_REASON_LITERAL(kInvalid);
-    RETURN_REASON_LITERAL(kRemote);
-    RETURN_REASON_LITERAL(kLocalForTests);
-    RETURN_REASON_LITERAL(kLocalForInteropRunner);
-    RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit);
-    RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride);
-    default:
-      return absl::StrCat("Unknown(", static_cast<int>(reason), ")");
-  }
-#undef RETURN_REASON_LITERAL
-}
-
-std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) {
-  os << KeyUpdateReasonString(reason);
-  return os;
-}
-
-bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
-  return a.sni == b.sni && a.uaid == b.uaid && a.alpns == b.alpns &&
-         a.legacy_version_encapsulation_inner_packet ==
-             b.legacy_version_encapsulation_inner_packet &&
-         a.retry_token == b.retry_token &&
-         a.resumption_attempted == b.resumption_attempted &&
-         a.early_data_attempted == b.early_data_attempted;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const ParsedClientHello& parsed_chlo) {
-  os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
-     << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
-     << ", len(retry_token):" << parsed_chlo.retry_token.size()
-     << ", len(inner_packet):"
-     << parsed_chlo.legacy_version_encapsulation_inner_packet.size() << " }";
-  return os;
-}
-
-#undef RETURN_STRING_LITERAL  // undef for jumbo builds
-
-}  // namespace quic
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h
deleted file mode 100644
index a437c9a..0000000
--- a/quic/core/quic_types.h
+++ /dev/null
@@ -1,891 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_TYPES_H_
-#define QUICHE_QUIC_CORE_QUIC_TYPES_H_
-
-#include <array>
-#include <cstddef>
-#include <cstdint>
-#include <map>
-#include <ostream>
-#include <vector>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_time.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-using QuicPacketLength = uint16_t;
-using QuicControlFrameId = uint32_t;
-using QuicMessageId = uint32_t;
-
-// TODO(b/181256914) replace QuicDatagramStreamId with QuicStreamId once we
-// remove support for draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-using QuicDatagramStreamId = uint64_t;
-using QuicDatagramContextId = uint64_t;
-// Note that for draft-ietf-masque-h3-datagram-00, we represent the flow ID as a
-// QuicDatagramStreamId.
-
-// IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned
-// 62-bit numbers. However, we have decided to only support up to 2^32-1 streams
-// in order to reduce the size of data structures such as QuicStreamFrame
-// and QuicTransmissionInfo, as that allows them to fit in cache lines and has
-// visible perfomance impact.
-using QuicStreamId = uint32_t;
-
-// Count of stream IDs. Used in MAX_STREAMS and STREAMS_BLOCKED frames.
-using QuicStreamCount = QuicStreamId;
-
-using QuicByteCount = uint64_t;
-using QuicPacketCount = uint64_t;
-using QuicPublicResetNonceProof = uint64_t;
-using QuicStreamOffset = uint64_t;
-using DiversificationNonce = std::array<char, 32>;
-using PacketTimeVector = std::vector<std::pair<QuicPacketNumber, QuicTime>>;
-
-enum : size_t { kStatelessResetTokenLength = 16 };
-using StatelessResetToken = std::array<char, kStatelessResetTokenLength>;
-
-// WebTransport session IDs are stream IDs.
-using WebTransportSessionId = uint64_t;
-// WebTransport stream reset codes are 8-bit.
-using WebTransportStreamError = uint8_t;
-// WebTransport session error codes are 32-bit.
-using WebTransportSessionError = uint32_t;
-
-enum : size_t { kQuicPathFrameBufferSize = 8 };
-using QuicPathFrameBuffer = std::array<uint8_t, kQuicPathFrameBufferSize>;
-
-// The connection id sequence number specifies the order that connection
-// ids must be used in. This is also the sequence number carried in
-// the IETF QUIC NEW_CONNECTION_ID and RETIRE_CONNECTION_ID frames.
-using QuicConnectionIdSequenceNumber = uint64_t;
-
-// A custom data that represents application-specific settings.
-// In HTTP/3 for example, it includes the encoded SETTINGS.
-using ApplicationState = std::vector<uint8_t>;
-
-// A struct for functions which consume data payloads and fins.
-struct QUIC_EXPORT_PRIVATE QuicConsumedData {
-  constexpr QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
-      : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {}
-
-  // By default, gtest prints the raw bytes of an object. The bool data
-  // member causes this object to have padding bytes, which causes the
-  // default gtest object printer to read uninitialize memory. So we need
-  // to teach gtest how to print this object.
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
-      std::ostream& os, const QuicConsumedData& s);
-
-  // How many bytes were consumed.
-  size_t bytes_consumed;
-
-  // True if an incoming fin was consumed.
-  bool fin_consumed;
-};
-
-// QuicAsyncStatus enumerates the possible results of an asynchronous
-// operation.
-enum QuicAsyncStatus {
-  QUIC_SUCCESS = 0,
-  QUIC_FAILURE = 1,
-  // QUIC_PENDING results from an operation that will occur asynchronously. When
-  // the operation is complete, a callback's |Run| method will be called.
-  QUIC_PENDING = 2,
-};
-
-// TODO(wtc): see if WriteStatus can be replaced by QuicAsyncStatus.
-enum WriteStatus : int16_t {
-  WRITE_STATUS_OK,
-  // Write is blocked, caller needs to retry.
-  WRITE_STATUS_BLOCKED,
-  // Write is blocked but the packet data is buffered, caller should not retry.
-  WRITE_STATUS_BLOCKED_DATA_BUFFERED,
-  // To make the IsWriteError(WriteStatus) function work properly:
-  // - Non-errors MUST be added before WRITE_STATUS_ERROR.
-  // - Errors MUST be added after WRITE_STATUS_ERROR.
-  WRITE_STATUS_ERROR,
-  WRITE_STATUS_MSG_TOO_BIG,
-  WRITE_STATUS_FAILED_TO_COALESCE_PACKET,
-  WRITE_STATUS_NUM_VALUES,
-};
-
-std::string HistogramEnumString(WriteStatus enum_value);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const WriteStatus& status);
-
-inline std::string HistogramEnumDescription(WriteStatus /*dummy*/) {
-  return "status";
-}
-
-inline bool IsWriteBlockedStatus(WriteStatus status) {
-  return status == WRITE_STATUS_BLOCKED ||
-         status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
-}
-
-inline bool IsWriteError(WriteStatus status) {
-  return status >= WRITE_STATUS_ERROR;
-}
-
-// A struct used to return the result of write calls including either the number
-// of bytes written or the error code, depending upon the status.
-struct QUIC_EXPORT_PRIVATE WriteResult {
-  constexpr WriteResult(WriteStatus status, int bytes_written_or_error_code)
-      : status(status), bytes_written(bytes_written_or_error_code) {}
-
-  constexpr WriteResult() : WriteResult(WRITE_STATUS_ERROR, 0) {}
-
-  bool operator==(const WriteResult& other) const {
-    if (status != other.status) {
-      return false;
-    }
-    switch (status) {
-      case WRITE_STATUS_OK:
-        return bytes_written == other.bytes_written;
-      case WRITE_STATUS_BLOCKED:
-      case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
-        return true;
-      default:
-        return error_code == other.error_code;
-    }
-  }
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
-                                                      const WriteResult& s);
-
-  WriteStatus status;
-  // Number of packets dropped as a result of this write.
-  // Only used by batch writers. Otherwise always 0.
-  uint16_t dropped_packets = 0;
-  // The delta between a packet's ideal and actual send time:
-  //     actual_send_time = ideal_send_time + send_time_offset
-  //                      = (now + release_time_delay) + send_time_offset
-  // Only valid if |status| is WRITE_STATUS_OK.
-  QuicTime::Delta send_time_offset = QuicTime::Delta::Zero();
-  // TODO(wub): In some cases, WRITE_STATUS_ERROR may set an error_code and
-  // WRITE_STATUS_BLOCKED_DATA_BUFFERED may set bytes_written. This may need
-  // some cleaning up so that perhaps both values can be set and valid.
-  union {
-    int bytes_written;  // only valid when status is WRITE_STATUS_OK
-    int error_code;     // only valid when status is WRITE_STATUS_ERROR
-  };
-};
-
-enum TransmissionType : int8_t {
-  NOT_RETRANSMISSION,
-  FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
-  HANDSHAKE_RETRANSMISSION,     // Retransmits due to handshake timeouts.
-  ALL_ZERO_RTT_RETRANSMISSION,  // Retransmits all packets encrypted with 0-RTT
-                                // key.
-  LOSS_RETRANSMISSION,          // Retransmits due to loss detection.
-  RTO_RETRANSMISSION,           // Retransmits due to retransmit time out.
-  TLP_RETRANSMISSION,           // Tail loss probes.
-  PTO_RETRANSMISSION,           // Retransmission due to probe timeout.
-  PROBING_RETRANSMISSION,       // Retransmission in order to probe bandwidth.
-  PATH_RETRANSMISSION,          // Retransmission proactively due to underlying
-                                // network change.
-  ALL_INITIAL_RETRANSMISSION,   // Retransmit all packets encrypted with INITIAL
-                                // key.
-  LAST_TRANSMISSION_TYPE = ALL_INITIAL_RETRANSMISSION,
-};
-
-QUIC_EXPORT_PRIVATE std::string TransmissionTypeToString(
-    TransmissionType transmission_type);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, TransmissionType transmission_type);
-
-enum HasRetransmittableData : uint8_t {
-  NO_RETRANSMITTABLE_DATA,
-  HAS_RETRANSMITTABLE_DATA,
-};
-
-enum IsHandshake : uint8_t { NOT_HANDSHAKE, IS_HANDSHAKE };
-
-enum class Perspective : uint8_t { IS_SERVER, IS_CLIENT };
-
-QUIC_EXPORT_PRIVATE std::string PerspectiveToString(Perspective perspective);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const Perspective& perspective);
-
-// Describes whether a ConnectionClose was originated by the peer.
-enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
-
-QUIC_EXPORT_PRIVATE std::string ConnectionCloseSourceToString(
-    ConnectionCloseSource connection_close_source);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const ConnectionCloseSource& connection_close_source);
-
-// Should a connection be closed silently or not.
-enum class ConnectionCloseBehavior {
-  SILENT_CLOSE,
-  SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED,
-  SEND_CONNECTION_CLOSE_PACKET
-};
-
-QUIC_EXPORT_PRIVATE std::string ConnectionCloseBehaviorToString(
-    ConnectionCloseBehavior connection_close_behavior);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const ConnectionCloseBehavior& connection_close_behavior);
-
-enum QuicFrameType : uint8_t {
-  // Regular frame types. The values set here cannot change without the
-  // introduction of a new QUIC version.
-  PADDING_FRAME = 0,
-  RST_STREAM_FRAME = 1,
-  CONNECTION_CLOSE_FRAME = 2,
-  GOAWAY_FRAME = 3,
-  WINDOW_UPDATE_FRAME = 4,
-  BLOCKED_FRAME = 5,
-  STOP_WAITING_FRAME = 6,
-  PING_FRAME = 7,
-  CRYPTO_FRAME = 8,
-  // TODO(b/157935330): stop hard coding this when deprecate T050.
-  HANDSHAKE_DONE_FRAME = 9,
-
-  // STREAM and ACK frames are special frames. They are encoded differently on
-  // the wire and their values do not need to be stable.
-  STREAM_FRAME,
-  ACK_FRAME,
-  // The path MTU discovery frame is encoded as a PING frame on the wire.
-  MTU_DISCOVERY_FRAME,
-
-  // These are for IETF-specific frames for which there is no mapping
-  // from Google QUIC frames. These are valid/allowed if and only if IETF-
-  // QUIC has been negotiated. Values are not important, they are not
-  // the values that are in the packets (see QuicIetfFrameType, below).
-  NEW_CONNECTION_ID_FRAME,
-  MAX_STREAMS_FRAME,
-  STREAMS_BLOCKED_FRAME,
-  PATH_RESPONSE_FRAME,
-  PATH_CHALLENGE_FRAME,
-  STOP_SENDING_FRAME,
-  MESSAGE_FRAME,
-  NEW_TOKEN_FRAME,
-  RETIRE_CONNECTION_ID_FRAME,
-  ACK_FREQUENCY_FRAME,
-
-  NUM_FRAME_TYPES
-};
-
-// Human-readable string suitable for logging.
-QUIC_EXPORT_PRIVATE std::string QuicFrameTypeToString(QuicFrameType t);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const QuicFrameType& t);
-
-// Ietf frame types. These are defined in the IETF QUIC Specification.
-// Explicit values are given in the enum so that we can be sure that
-// the symbol will map to the correct stream type.
-// All types are defined here, even if we have not yet implmented the
-// quic/core/stream/.... stuff needed.
-// Note: The protocol specifies that frame types are varint-62 encoded,
-// further stating that the shortest encoding must be used.  The current set of
-// frame types all have values less than 0x40 (64) so can be encoded in a single
-// byte, with the two most significant bits being 0. Thus, the following
-// enumerations are valid as both the numeric values of frame types AND their
-// encodings.
-enum QuicIetfFrameType : uint64_t {
-  IETF_PADDING = 0x00,
-  IETF_PING = 0x01,
-  IETF_ACK = 0x02,
-  IETF_ACK_ECN = 0x03,
-  IETF_RST_STREAM = 0x04,
-  IETF_STOP_SENDING = 0x05,
-  IETF_CRYPTO = 0x06,
-  IETF_NEW_TOKEN = 0x07,
-  // the low-3 bits of the stream frame type value are actually flags
-  // declaring what parts of the frame are/are-not present, as well as
-  // some other control information. The code would then do something
-  // along the lines of "if ((frame_type & 0xf8) == 0x08)" to determine
-  // whether the frame is a stream frame or not, and then examine each
-  // bit specifically when/as needed.
-  IETF_STREAM = 0x08,
-  // 0x09 through 0x0f are various flag settings of the IETF_STREAM frame.
-  IETF_MAX_DATA = 0x10,
-  IETF_MAX_STREAM_DATA = 0x11,
-  IETF_MAX_STREAMS_BIDIRECTIONAL = 0x12,
-  IETF_MAX_STREAMS_UNIDIRECTIONAL = 0x13,
-  IETF_DATA_BLOCKED = 0x14,
-  IETF_STREAM_DATA_BLOCKED = 0x15,
-  IETF_STREAMS_BLOCKED_BIDIRECTIONAL = 0x16,
-  IETF_STREAMS_BLOCKED_UNIDIRECTIONAL = 0x17,
-  IETF_NEW_CONNECTION_ID = 0x18,
-  IETF_RETIRE_CONNECTION_ID = 0x19,
-  IETF_PATH_CHALLENGE = 0x1a,
-  IETF_PATH_RESPONSE = 0x1b,
-  // Both of the following are "Connection Close" frames,
-  // the first signals transport-layer errors, the second application-layer
-  // errors.
-  IETF_CONNECTION_CLOSE = 0x1c,
-  IETF_APPLICATION_CLOSE = 0x1d,
-
-  IETF_HANDSHAKE_DONE = 0x1e,
-
-  // The MESSAGE frame type has not yet been fully standardized.
-  // QUIC versions starting with 46 and before 99 use 0x20-0x21.
-  // IETF QUIC (v99) uses 0x30-0x31, see draft-pauly-quic-datagram.
-  IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20,
-  IETF_EXTENSION_MESSAGE = 0x21,
-  IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30,
-  IETF_EXTENSION_MESSAGE_V99 = 0x31,
-
-  // An QUIC extension frame for sender control of acknowledgement delays
-  IETF_ACK_FREQUENCY = 0xaf,
-
-  // A QUIC extension frame which augments the IETF_ACK frame definition with
-  // packet receive timestamps.
-  // TODO(ianswett): Determine a proper value to replace this temporary value.
-  IETF_ACK_RECEIVE_TIMESTAMPS = 0x22,
-};
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const QuicIetfFrameType& c);
-QUIC_EXPORT_PRIVATE std::string QuicIetfFrameTypeString(QuicIetfFrameType t);
-
-// Masks for the bits that indicate the frame is a Stream frame vs the
-// bits used as flags.
-#define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8
-#define IETF_STREAM_FRAME_FLAG_MASK 0x07
-#define IS_IETF_STREAM_FRAME(_stype_) \
-  (((_stype_)&IETF_STREAM_FRAME_TYPE_MASK) == IETF_STREAM)
-
-// These are the values encoded in the low-order 3 bits of the
-// IETF_STREAMx frame type.
-#define IETF_STREAM_FRAME_FIN_BIT 0x01
-#define IETF_STREAM_FRAME_LEN_BIT 0x02
-#define IETF_STREAM_FRAME_OFF_BIT 0x04
-
-enum QuicVariableLengthIntegerLength : uint8_t {
-  // Length zero means the variable length integer is not present.
-  VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0,
-  VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1,
-  VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2,
-  VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4,
-  VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8,
-
-  // By default we write the IETF long header length using the 2-byte encoding
-  // of variable length integers, even when the length is below 64, which allows
-  // us to fill in the length before knowing what the length actually is.
-  kQuicDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2,
-};
-
-enum QuicPacketNumberLength : uint8_t {
-  PACKET_1BYTE_PACKET_NUMBER = 1,
-  PACKET_2BYTE_PACKET_NUMBER = 2,
-  PACKET_3BYTE_PACKET_NUMBER = 3,  // Used in versions 45+.
-  PACKET_4BYTE_PACKET_NUMBER = 4,
-  IETF_MAX_PACKET_NUMBER_LENGTH = 4,
-  // TODO(b/145819870): Remove 6 and 8 when we remove Q043 since these values
-  // are not representable with later versions.
-  PACKET_6BYTE_PACKET_NUMBER = 6,
-  PACKET_8BYTE_PACKET_NUMBER = 8
-};
-
-// Used to indicate a QuicSequenceNumberLength using two flag bits.
-enum QuicPacketNumberLengthFlags {
-  PACKET_FLAGS_1BYTE_PACKET = 0,           // 00
-  PACKET_FLAGS_2BYTE_PACKET = 1,           // 01
-  PACKET_FLAGS_4BYTE_PACKET = 1 << 1,      // 10
-  PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1,  // 11
-};
-
-// The public flags are specified in one byte.
-enum QuicPacketPublicFlags {
-  PACKET_PUBLIC_FLAGS_NONE = 0,
-
-  // Bit 0: Does the packet header contains version info?
-  PACKET_PUBLIC_FLAGS_VERSION = 1 << 0,
-
-  // Bit 1: Is this packet a public reset packet?
-  PACKET_PUBLIC_FLAGS_RST = 1 << 1,
-
-  // Bit 2: indicates the header includes a nonce.
-  PACKET_PUBLIC_FLAGS_NONCE = 1 << 2,
-
-  // Bit 3: indicates whether a ConnectionID is included.
-  PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID = 0,
-  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID = 1 << 3,
-
-  // Deprecated version 32 and earlier used two bits to indicate an 8-byte
-  // connection ID. We send this from the client because of some broken
-  // middleboxes that are still checking this bit.
-  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD = 1 << 3 | 1 << 2,
-
-  // Bits 4 and 5 describe the packet number length as follows:
-  // --00----: 1 byte
-  // --01----: 2 bytes
-  // --10----: 4 bytes
-  // --11----: 6 bytes
-  PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4,
-  PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4,
-  PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4,
-  PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4,
-
-  // Reserved, unimplemented flags:
-
-  // Bit 7: indicates the presence of a second flags byte.
-  PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7,
-
-  // All bits set (bits 6 and 7 are not currently used): 00111111
-  PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1,
-};
-
-// The private flags are specified in one byte.
-enum QuicPacketPrivateFlags {
-  PACKET_PRIVATE_FLAGS_NONE = 0,
-
-  // Bit 0: Does this packet contain an entropy bit?
-  PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 0,
-
-  // (bits 1-7 are not used): 00000001
-  PACKET_PRIVATE_FLAGS_MAX = (1 << 1) - 1
-};
-
-// Defines for all types of congestion control algorithms that can be used in
-// QUIC. Note that this is separate from the congestion feedback type -
-// some congestion control algorithms may use the same feedback type
-// (Reno and Cubic are the classic example for that).
-enum CongestionControlType {
-  kCubicBytes,
-  kRenoBytes,
-  kBBR,
-  kPCC,
-  kGoogCC,
-  kBBRv2,
-};
-
-// EncryptionLevel enumerates the stages of encryption that a QUIC connection
-// progresses through. When retransmitting a packet, the encryption level needs
-// to be specified so that it is retransmitted at a level which the peer can
-// understand.
-enum EncryptionLevel : int8_t {
-  ENCRYPTION_INITIAL = 0,
-  ENCRYPTION_HANDSHAKE = 1,
-  ENCRYPTION_ZERO_RTT = 2,
-  ENCRYPTION_FORWARD_SECURE = 3,
-
-  NUM_ENCRYPTION_LEVELS,
-};
-
-inline bool EncryptionLevelIsValid(EncryptionLevel level) {
-  return ENCRYPTION_INITIAL <= level && level < NUM_ENCRYPTION_LEVELS;
-}
-
-QUIC_EXPORT_PRIVATE std::string EncryptionLevelToString(EncryptionLevel level);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             EncryptionLevel level);
-
-// Enumeration of whether a server endpoint will request a client certificate,
-// and whether that endpoint requires a valid client certificate to establish a
-// connection.
-enum class ClientCertMode : uint8_t {
-  kNone,     // Do not request a client certificate.  Default server behavior.
-  kRequest,  // Request a certificate, but allow unauthenticated connections.
-  kRequire,  // Require clients to provide a valid certificate.
-};
-
-QUIC_EXPORT_PRIVATE absl::string_view ClientCertModeToString(
-    ClientCertMode mode);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             ClientCertMode mode);
-
-enum AddressChangeType : uint8_t {
-  // IP address and port remain unchanged.
-  NO_CHANGE,
-  // Port changed, but IP address remains unchanged.
-  PORT_CHANGE,
-  // IPv4 address changed, but within the /24 subnet (port may have changed.)
-  IPV4_SUBNET_CHANGE,
-  // IPv4 address changed, excluding /24 subnet change (port may have changed.)
-  IPV4_TO_IPV4_CHANGE,
-  // IP address change from an IPv4 to an IPv6 address (port may have changed.)
-  IPV4_TO_IPV6_CHANGE,
-  // IP address change from an IPv6 to an IPv4 address (port may have changed.)
-  IPV6_TO_IPV4_CHANGE,
-  // IP address change from an IPv6 to an IPv6 address (port may have changed.)
-  IPV6_TO_IPV6_CHANGE,
-};
-
-QUIC_EXPORT_PRIVATE std::string AddressChangeTypeToString(
-    AddressChangeType type);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             AddressChangeType type);
-
-enum StreamSendingState {
-  // Sender has more data to send on this stream.
-  NO_FIN,
-  // Sender is done sending on this stream.
-  FIN,
-  // Sender is done sending on this stream and random padding needs to be
-  // appended after all stream frames.
-  FIN_AND_PADDING,
-};
-
-enum SentPacketState : uint8_t {
-  // The packet is in flight and waiting to be acked.
-  OUTSTANDING,
-  FIRST_PACKET_STATE = OUTSTANDING,
-  // The packet was never sent.
-  NEVER_SENT,
-  // The packet has been acked.
-  ACKED,
-  // This packet is not expected to be acked.
-  UNACKABLE,
-  // This packet has been delivered or unneeded.
-  NEUTERED,
-
-  // States below are corresponding to retransmission types in TransmissionType.
-
-  // This packet has been retransmitted when retransmission timer fires in
-  // HANDSHAKE mode.
-  HANDSHAKE_RETRANSMITTED,
-  // This packet is considered as lost, this is used for LOST_RETRANSMISSION.
-  LOST,
-  // This packet has been retransmitted when TLP fires.
-  TLP_RETRANSMITTED,
-  // This packet has been retransmitted when RTO fires.
-  RTO_RETRANSMITTED,
-  // This packet has been retransmitted when PTO fires.
-  PTO_RETRANSMITTED,
-  // This packet has been retransmitted for probing purpose.
-  PROBE_RETRANSMITTED,
-  // This packet is sent on a different path or is a PING only packet.
-  // Do not update RTT stats and congestion control if the packet is the
-  // largest_acked of an incoming ACK.
-  NOT_CONTRIBUTING_RTT,
-  LAST_PACKET_STATE = NOT_CONTRIBUTING_RTT,
-};
-
-enum PacketHeaderFormat : uint8_t {
-  IETF_QUIC_LONG_HEADER_PACKET,
-  IETF_QUIC_SHORT_HEADER_PACKET,
-  GOOGLE_QUIC_PACKET,
-};
-
-QUIC_EXPORT_PRIVATE std::string PacketHeaderFormatToString(
-    PacketHeaderFormat format);
-
-// Information about a newly acknowledged packet.
-struct QUIC_EXPORT_PRIVATE AckedPacket {
-  constexpr AckedPacket(QuicPacketNumber packet_number,
-                        QuicPacketLength bytes_acked,
-                        QuicTime receive_timestamp)
-      : packet_number(packet_number),
-        bytes_acked(bytes_acked),
-        receive_timestamp(receive_timestamp) {}
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os, const AckedPacket& acked_packet);
-
-  QuicPacketNumber packet_number;
-  // Number of bytes sent in the packet that was acknowledged.
-  QuicPacketLength bytes_acked;
-  // The time |packet_number| was received by the peer, according to the
-  // optional timestamp the peer included in the ACK frame which acknowledged
-  // |packet_number|. Zero if no timestamp was available for this packet.
-  QuicTime receive_timestamp;
-};
-
-// A vector of acked packets.
-using AckedPacketVector = absl::InlinedVector<AckedPacket, 2>;
-
-// Information about a newly lost packet.
-struct QUIC_EXPORT_PRIVATE LostPacket {
-  LostPacket(QuicPacketNumber packet_number, QuicPacketLength bytes_lost)
-      : packet_number(packet_number), bytes_lost(bytes_lost) {}
-
-  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os, const LostPacket& lost_packet);
-
-  QuicPacketNumber packet_number;
-  // Number of bytes sent in the packet that was lost.
-  QuicPacketLength bytes_lost;
-};
-
-// A vector of lost packets.
-using LostPacketVector = absl::InlinedVector<LostPacket, 2>;
-
-// Please note, this value cannot used directly for packet serialization.
-enum QuicLongHeaderType : uint8_t {
-  VERSION_NEGOTIATION,
-  INITIAL,
-  ZERO_RTT_PROTECTED,
-  HANDSHAKE,
-  RETRY,
-
-  INVALID_PACKET_TYPE,
-};
-
-QUIC_EXPORT_PRIVATE std::string QuicLongHeaderTypeToString(
-    QuicLongHeaderType type);
-
-enum QuicPacketHeaderTypeFlags : uint8_t {
-  // Bit 2: Key phase bit for IETF QUIC short header packets.
-  FLAGS_KEY_PHASE_BIT = 1 << 2,
-  // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this
-  // bit to 0, allowing to distinguish Google QUIC packets from short header
-  // packets.
-  FLAGS_DEMULTIPLEXING_BIT = 1 << 3,
-  // Bits 4 and 5: Reserved bits for short header.
-  FLAGS_SHORT_HEADER_RESERVED_1 = 1 << 4,
-  FLAGS_SHORT_HEADER_RESERVED_2 = 1 << 5,
-  // Bit 6: the 'QUIC' bit.
-  FLAGS_FIXED_BIT = 1 << 6,
-  // Bit 7: Indicates the header is long or short header.
-  FLAGS_LONG_HEADER = 1 << 7,
-};
-
-enum MessageStatus {
-  MESSAGE_STATUS_SUCCESS,
-  MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED,  // Failed to send message because
-                                              // encryption is not established
-                                              // yet.
-  MESSAGE_STATUS_UNSUPPORTED,  // Failed to send message because MESSAGE frame
-                               // is not supported by the connection.
-  MESSAGE_STATUS_BLOCKED,      // Failed to send message because connection is
-                           // congestion control blocked or underlying socket is
-                           // write blocked.
-  MESSAGE_STATUS_TOO_LARGE,  // Failed to send message because the message is
-                             // too large to fit into a single packet.
-  MESSAGE_STATUS_INTERNAL_ERROR,  // Failed to send message because connection
-                                  // reaches an invalid state.
-};
-
-QUIC_EXPORT_PRIVATE std::string MessageStatusToString(
-    MessageStatus message_status);
-
-// Used to return the result of SendMessage calls
-struct QUIC_EXPORT_PRIVATE MessageResult {
-  MessageResult(MessageStatus status, QuicMessageId message_id);
-
-  bool operator==(const MessageResult& other) const {
-    return status == other.status && message_id == other.message_id;
-  }
-
-  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
-                                                      const MessageResult& mr);
-
-  MessageStatus status;
-  // Only valid when status is MESSAGE_STATUS_SUCCESS.
-  QuicMessageId message_id;
-};
-
-QUIC_EXPORT_PRIVATE std::string MessageResultToString(
-    MessageResult message_result);
-
-enum WriteStreamDataResult {
-  WRITE_SUCCESS,
-  STREAM_MISSING,  // Trying to write data of a nonexistent stream (e.g.
-                   // closed).
-  WRITE_FAILED,    // Trying to write nonexistent data of a stream
-};
-
-enum StreamType : uint8_t {
-  // Bidirectional streams allow for data to be sent in both directions.
-  BIDIRECTIONAL,
-
-  // Unidirectional streams carry data in one direction only.
-  WRITE_UNIDIRECTIONAL,
-  READ_UNIDIRECTIONAL,
-  // Not actually a stream type. Used only by QuicCryptoStream when it uses
-  // CRYPTO frames and isn't actually a QuicStream.
-  CRYPTO,
-};
-
-// A packet number space is the context in which a packet can be processed and
-// acknowledged.
-enum PacketNumberSpace : uint8_t {
-  INITIAL_DATA = 0,  // Only used in IETF QUIC.
-  HANDSHAKE_DATA = 1,
-  APPLICATION_DATA = 2,
-
-  NUM_PACKET_NUMBER_SPACES,
-};
-
-QUIC_EXPORT_PRIVATE std::string PacketNumberSpaceToString(
-    PacketNumberSpace packet_number_space);
-
-// Used to return the result of processing a received ACK frame.
-enum AckResult {
-  PACKETS_NEWLY_ACKED,
-  NO_PACKETS_NEWLY_ACKED,
-  UNSENT_PACKETS_ACKED,     // Peer acks unsent packets.
-  UNACKABLE_PACKETS_ACKED,  // Peer acks packets that are not expected to be
-                            // acked. For example, encryption is reestablished,
-                            // and all sent encrypted packets cannot be
-                            // decrypted by the peer. Version gets negotiated,
-                            // and all sent packets in the different version
-                            // cannot be processed by the peer.
-  PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
-};
-
-// Indicates the fate of a serialized packet in WritePacket().
-enum SerializedPacketFate : uint8_t {
-  DISCARD,                     // Discard the packet.
-  COALESCE,                    // Try to coalesce packet.
-  BUFFER,                      // Buffer packet in buffered_packets_.
-  SEND_TO_WRITER,              // Send packet to writer.
-  LEGACY_VERSION_ENCAPSULATE,  // Perform Legacy Version Encapsulation on this
-                               // packet.
-};
-
-QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString(
-    SerializedPacketFate fate);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const SerializedPacketFate fate);
-
-// There are three different forms of CONNECTION_CLOSE.
-enum QuicConnectionCloseType {
-  GOOGLE_QUIC_CONNECTION_CLOSE = 0,
-  IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1,
-  IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const QuicConnectionCloseType type);
-
-QUIC_EXPORT_PRIVATE std::string QuicConnectionCloseTypeString(
-    QuicConnectionCloseType type);
-
-// Indicate handshake state of a connection.
-enum HandshakeState {
-  // Initial state.
-  HANDSHAKE_START,
-  // Only used in IETF QUIC with TLS handshake. State proceeds to
-  // HANDSHAKE_PROCESSED after a packet of HANDSHAKE packet number space
-  // gets successfully processed, and the initial key can be dropped.
-  HANDSHAKE_PROCESSED,
-  // In QUIC crypto, state proceeds to HANDSHAKE_COMPLETE if client receives
-  // SHLO or server successfully processes an ENCRYPTION_FORWARD_SECURE
-  // packet, such that the handshake packets can be neutered. In IETF QUIC
-  // with TLS handshake, state proceeds to HANDSHAKE_COMPLETE once the client
-  // has both 1-RTT send and receive keys.
-  HANDSHAKE_COMPLETE,
-  // Only used in IETF QUIC with TLS handshake. State proceeds to
-  // HANDSHAKE_CONFIRMED if 1) a client receives HANDSHAKE_DONE frame or
-  // acknowledgment for 1-RTT packet or 2) server has
-  // 1-RTT send and receive keys.
-  HANDSHAKE_CONFIRMED,
-};
-
-struct QUIC_NO_EXPORT NextReleaseTimeResult {
-  // The ideal release time of the packet being sent.
-  QuicTime release_time;
-  // Whether it is allowed to send the packet before release_time.
-  bool allow_burst;
-};
-
-// QuicPacketBuffer bundles a buffer and a function that releases it. Note
-// it does not assume ownership of buffer, i.e. it doesn't release the buffer on
-// destruction.
-struct QUIC_NO_EXPORT QuicPacketBuffer {
-  QuicPacketBuffer() = default;
-
-  QuicPacketBuffer(char* buffer,
-                   std::function<void(const char*)> release_buffer)
-      : buffer(buffer), release_buffer(std::move(release_buffer)) {}
-
-  char* buffer = nullptr;
-  std::function<void(const char*)> release_buffer;
-};
-
-// QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership.
-struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer {
-  QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete;
-  QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete;
-
-  QuicOwnedPacketBuffer(char* buffer,
-                        std::function<void(const char*)> release_buffer)
-      : QuicPacketBuffer(buffer, std::move(release_buffer)) {}
-
-  QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer)
-      : QuicPacketBuffer(std::move(owned_buffer)) {
-    // |owned_buffer| does not own a buffer any more.
-    owned_buffer.buffer = nullptr;
-  }
-
-  explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer)
-      : QuicPacketBuffer(std::move(packet_buffer)) {}
-
-  ~QuicOwnedPacketBuffer() {
-    if (release_buffer != nullptr && buffer != nullptr) {
-      release_buffer(buffer);
-    }
-  }
-};
-
-// These values must remain stable as they are uploaded to UMA histograms.
-enum class KeyUpdateReason {
-  kInvalid = 0,
-  kRemote = 1,
-  kLocalForTests = 2,
-  kLocalForInteropRunner = 3,
-  kLocalAeadConfidentialityLimit = 4,
-  kLocalKeyUpdateLimitOverride = 5,
-  kMaxValue = kLocalKeyUpdateLimitOverride,
-};
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const KeyUpdateReason reason);
-
-QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason);
-
-// QuicSSLConfig contains configurations to be applied on a SSL object, which
-// overrides the configurations in SSL_CTX.
-struct QUIC_NO_EXPORT QuicSSLConfig {
-  // Whether TLS early data should be enabled. If not set, default to enabled.
-  absl::optional<bool> early_data_enabled;
-  // Whether TLS session tickets are supported. If not set, default to
-  // supported.
-  absl::optional<bool> disable_ticket_support;
-  // If set, used to configure the SSL object with
-  // SSL_set_signing_algorithm_prefs.
-  absl::optional<absl::InlinedVector<uint16_t, 8>> signing_algorithm_prefs;
-  // Client certificate mode for mTLS support. Only used at server side.
-  ClientCertMode client_cert_mode = ClientCertMode::kNone;
-};
-
-// QuicDelayedSSLConfig contains a subset of SSL config that can be applied
-// after BoringSSL's early select certificate callback. This overwrites all SSL
-// configs applied before cert selection.
-struct QUIC_NO_EXPORT QuicDelayedSSLConfig {
-  // Client certificate mode for mTLS support. Only used at server side.
-  // absl::nullopt means do not change client certificate mode.
-  absl::optional<ClientCertMode> client_cert_mode;
-};
-
-// ParsedClientHello contains client hello information extracted from a fully
-// received client hello.
-struct QUIC_NO_EXPORT ParsedClientHello {
-  std::string sni;                 // QUIC crypto and TLS.
-  std::string uaid;                // QUIC crypto only.
-  std::vector<std::string> alpns;  // QUIC crypto and TLS.
-  std::string legacy_version_encapsulation_inner_packet;  // QUIC crypto only.
-  // The unvalidated retry token from the last received packet of a potentially
-  // multi-packet client hello. TLS only.
-  std::string retry_token;
-  bool resumption_attempted = false;  // TLS only.
-  bool early_data_attempted = false;  // TLS only.
-};
-
-QUIC_EXPORT_PRIVATE bool operator==(const ParsedClientHello& a,
-                                    const ParsedClientHello& b);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const ParsedClientHello& parsed_chlo);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_TYPES_H_
diff --git a/quic/core/quic_udp_socket.h b/quic/core/quic_udp_socket.h
deleted file mode 100644
index 534273c..0000000
--- a/quic/core/quic_udp_socket.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
-#define QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include <type_traits>
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-#if defined(_WIN32)
-using QuicUdpSocketFd = SOCKET;
-const QuicUdpSocketFd kQuicInvalidSocketFd = INVALID_SOCKET;
-#else
-using QuicUdpSocketFd = int;
-const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
-#endif
-
-const size_t kDefaultUdpPacketControlBufferSize = 512;
-
-enum class QuicUdpPacketInfoBit : uint8_t {
-  DROPPED_PACKETS = 0,   // Read
-  V4_SELF_IP,            // Read
-  V6_SELF_IP,            // Read
-  PEER_ADDRESS,          // Read & Write
-  RECV_TIMESTAMP,        // Read
-  TTL,                   // Read & Write
-  GOOGLE_PACKET_HEADER,  // Read
-  NUM_BITS,
-};
-static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
-                  BitMask64::NumBits(),
-              "BitMask64 not wide enough to hold all bits.");
-
-// BufferSpan points to an unowned buffer, copying this structure only copies
-// the pointer and length, not the buffer itself.
-struct QUIC_EXPORT_PRIVATE BufferSpan {
-  BufferSpan(char* buffer, size_t buffer_len)
-      : buffer(buffer), buffer_len(buffer_len) {}
-
-  BufferSpan() = default;
-  BufferSpan(const BufferSpan& other) = default;
-  BufferSpan& operator=(const BufferSpan& other) = default;
-
-  char* buffer = nullptr;
-  size_t buffer_len = 0;
-};
-
-// QuicUdpPacketInfo contains per-packet information used for sending and
-// receiving.
-class QUIC_EXPORT_PRIVATE QuicUdpPacketInfo {
- public:
-  BitMask64 bitmask() const { return bitmask_; }
-
-  void Reset() { bitmask_.ClearAll(); }
-
-  bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
-
-  QuicPacketCount dropped_packets() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
-    return dropped_packets_;
-  }
-
-  void SetDroppedPackets(QuicPacketCount dropped_packets) {
-    dropped_packets_ = dropped_packets;
-    bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
-  }
-
-  const QuicIpAddress& self_v4_ip() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
-    return self_v4_ip_;
-  }
-
-  void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
-    self_v4_ip_ = self_v4_ip;
-    bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
-  }
-
-  const QuicIpAddress& self_v6_ip() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
-    return self_v6_ip_;
-  }
-
-  void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
-    self_v6_ip_ = self_v6_ip;
-    bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
-  }
-
-  void SetSelfIp(QuicIpAddress self_ip) {
-    if (self_ip.IsIPv4()) {
-      SetSelfV4Ip(self_ip);
-    } else {
-      SetSelfV6Ip(self_ip);
-    }
-  }
-
-  const QuicSocketAddress& peer_address() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
-    return peer_address_;
-  }
-
-  void SetPeerAddress(QuicSocketAddress peer_address) {
-    peer_address_ = peer_address;
-    bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
-  }
-
-  QuicWallTime receive_timestamp() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
-    return receive_timestamp_;
-  }
-
-  void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
-    receive_timestamp_ = receive_timestamp;
-    bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
-  }
-
-  int ttl() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
-    return ttl_;
-  }
-
-  void SetTtl(int ttl) {
-    ttl_ = ttl;
-    bitmask_.Set(QuicUdpPacketInfoBit::TTL);
-  }
-
-  BufferSpan google_packet_headers() const {
-    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER));
-    return google_packet_headers_;
-  }
-
-  void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
-    google_packet_headers_ = google_packet_headers;
-    bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
-  }
-
- private:
-  BitMask64 bitmask_;
-  QuicPacketCount dropped_packets_;
-  QuicIpAddress self_v4_ip_;
-  QuicIpAddress self_v6_ip_;
-  QuicSocketAddress peer_address_;
-  QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
-  int ttl_;
-  BufferSpan google_packet_headers_;
-};
-
-// QuicUdpSocketApi provides a minimal set of apis for sending and receiving
-// udp packets. The low level udp socket apis differ between kernels and kernel
-// versions, the goal of QuicUdpSocketApi is to hide such differences.
-// We use non-static functions because it is easier to be mocked in tests when
-// needed.
-class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
- public:
-  // Creates a non-blocking udp socket, sets the receive/send buffer and enable
-  // receiving of self ip addresses on read.
-  // If address_family == AF_INET6 and ipv6_only is true, receiving of IPv4 self
-  // addresses is disabled. This is only necessary for IPv6 sockets on iOS - all
-  // other platforms can ignore this parameter. Return kQuicInvalidSocketFd if
-  // failed.
-  QuicUdpSocketFd Create(int address_family,
-                         int receive_buffer_size,
-                         int send_buffer_size,
-                         bool ipv6_only = false);
-
-  // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
-  void Destroy(QuicUdpSocketFd fd);
-
-  // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
-  // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
-  // to get the bound random port.
-  bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
-
-  // Enable receiving of various per-packet information. Return true if the
-  // corresponding information can be received on read.
-  bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
-  bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
-  bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
-  bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
-
-  // Wait for |fd| to become readable, up to |timeout|.
-  // Return true if |fd| is readable upon return.
-  bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
-
-  struct QUIC_EXPORT_PRIVATE ReadPacketResult {
-    bool ok = false;
-    QuicUdpPacketInfo packet_info;
-    BufferSpan packet_buffer;
-    BufferSpan control_buffer;
-
-    void Reset(size_t packet_buffer_length) {
-      ok = false;
-      packet_info.Reset();
-      packet_buffer.buffer_len = packet_buffer_length;
-    }
-  };
-  // Read a packet from |fd|:
-  // packet_info_interested: Bitmask indicating what information caller wants to
-  //                         receive into |result->packet_info|.
-  // result->packet_info:    Received per packet information.
-  // result->packet_buffer:  The packet buffer, to be filled with packet data.
-  //                         |result->packet_buffer.buffer_len| is set to the
-  //                         packet length on a successful return.
-  // result->control_buffer: The control buffer, used by ReadPacket internally.
-  //                         It is recommended to be
-  //                         |kDefaultUdpPacketControlBufferSize| bytes.
-  // result->ok:             True iff a packet is successfully received.
-  //
-  // If |*result| is reused for subsequent ReadPacket() calls, caller needs to
-  // call result->Reset() before each ReadPacket().
-  void ReadPacket(QuicUdpSocketFd fd,
-                  BitMask64 packet_info_interested,
-                  ReadPacketResult* result);
-
-  using ReadPacketResults = std::vector<ReadPacketResult>;
-  // Read up to |results->size()| packets from |fd|. The meaning of each element
-  // in |*results| has been documented on top of |ReadPacket|.
-  // Return the number of elements populated into |*results|, note it is
-  // possible for some of the populated elements to have ok=false.
-  size_t ReadMultiplePackets(QuicUdpSocketFd fd,
-                             BitMask64 packet_info_interested,
-                             ReadPacketResults* results);
-
-  // Write a packet to |fd|.
-  // packet_buffer, packet_buffer_len:  The packet buffer to write.
-  // packet_info:                       The per packet information to set.
-  WriteResult WritePacket(QuicUdpSocketFd fd,
-                          const char* packet_buffer,
-                          size_t packet_buffer_len,
-                          const QuicUdpPacketInfo& packet_info);
-
- protected:
-  bool SetupSocket(QuicUdpSocketFd fd,
-                   int address_family,
-                   int receive_buffer_size,
-                   int send_buffer_size,
-                   bool ipv6_only);
-  bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
-  bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
diff --git a/quic/core/quic_udp_socket_posix.cc b/quic/core/quic_udp_socket_posix.cc
deleted file mode 100644
index eef582b..0000000
--- a/quic/core/quic_udp_socket_posix.cc
+++ /dev/null
@@ -1,639 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_udp_socket_platform_api.h"
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#if defined(__APPLE__) && !defined(__APPLE_USE_RFC_3542)
-#error "__APPLE_USE_RFC_3542 needs to be defined."
-#endif
-
-#if defined(__linux__)
-#include <alloca.h>
-// For SO_TIMESTAMPING.
-#include <linux/net_tstamp.h>
-#endif
-
-#if defined(__linux__) && !defined(__ANDROID__)
-#define QUIC_UDP_SOCKET_SUPPORT_TTL 1
-#endif
-
-namespace quic {
-namespace {
-
-#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
-#define QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING 1
-// This is the structure that SO_TIMESTAMPING fills into the cmsg header.
-// It is well-defined, but does not have a definition in a public header.
-// See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
-// for more information.
-struct LinuxSoTimestamping {
-  // The converted system time of the timestamp.
-  struct timespec systime;
-  // Deprecated; serves only as padding.
-  struct timespec hwtimetrans;
-  // The raw hardware timestamp.
-  struct timespec hwtimeraw;
-};
-const size_t kCmsgSpaceForRecvTimestamp =
-    CMSG_SPACE(sizeof(LinuxSoTimestamping));
-#else
-const size_t kCmsgSpaceForRecvTimestamp = 0;
-#endif
-
-const size_t kMinCmsgSpaceForRead =
-    CMSG_SPACE(sizeof(uint32_t))       // Dropped packet count
-    + CMSG_SPACE(sizeof(in_pktinfo))   // V4 Self IP
-    + CMSG_SPACE(sizeof(in6_pktinfo))  // V6 Self IP
-    + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int))  // TTL
-    + kCmsgSpaceForGooglePacketHeader;
-
-QuicUdpSocketFd CreateNonblockingSocket(int address_family) {
-#if defined(__linux__) && defined(SOCK_NONBLOCK)
-
-  // Create a nonblocking socket directly.
-  int fd = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-  if (fd < 0) {
-    QUIC_LOG_FIRST_N(ERROR, 100)
-        << "socket() failed with address_family=" << address_family << ": "
-        << strerror(errno);
-    return kQuicInvalidSocketFd;
-  }
-#else
-  // Create a socket and use fcntl to set it to nonblocking.
-  // This implementation is used when building for iOS, OSX and old versions of
-  // Linux (< 2.6.27) and old versions of Android (< API 21).
-  int fd = socket(address_family, SOCK_DGRAM, IPPROTO_UDP);
-  if (fd < 0) {
-    QUIC_LOG_FIRST_N(ERROR, 100)
-        << "socket() failed with address_family=" << address_family << ": "
-        << strerror(errno);
-    return kQuicInvalidSocketFd;
-  }
-  int current_flags = fcntl(fd, F_GETFL, 0);
-  if (current_flags == -1) {
-    QUIC_LOG_FIRST_N(ERROR, 100)
-        << "failed to get current socket flags: " << strerror(errno);
-    close(fd);
-    return kQuicInvalidSocketFd;
-  }
-
-  int rc = fcntl(fd, F_SETFL, current_flags | O_NONBLOCK);
-  if (rc == -1) {
-    QUIC_LOG_FIRST_N(ERROR, 100)
-        << "failed to set socket to non-blocking: " << strerror(errno);
-    close(fd);
-    return kQuicInvalidSocketFd;
-  }
-#endif
-
-  SetGoogleSocketOptions(fd);
-  return fd;
-}  // End CreateNonblockingSocket
-
-void SetV4SelfIpInControlMessage(const QuicIpAddress& self_address,
-                                 cmsghdr* cmsg) {
-  QUICHE_DCHECK(self_address.IsIPv4());
-  in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
-  memset(pktinfo, 0, sizeof(in_pktinfo));
-  pktinfo->ipi_ifindex = 0;
-  std::string address_string = self_address.ToPackedString();
-  memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
-         address_string.length());
-}
-
-void SetV6SelfIpInControlMessage(const QuicIpAddress& self_address,
-                                 cmsghdr* cmsg) {
-  QUICHE_DCHECK(self_address.IsIPv6());
-  in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
-  memset(pktinfo, 0, sizeof(in6_pktinfo));
-  std::string address_string = self_address.ToPackedString();
-  memcpy(&pktinfo->ipi6_addr, address_string.c_str(), address_string.length());
-}
-
-void PopulatePacketInfoFromControlMessage(struct cmsghdr* cmsg,
-                                          QuicUdpPacketInfo* packet_info,
-                                          BitMask64 packet_info_interested) {
-#if defined(__linux__) && defined(SO_RXQ_OVFL)
-  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) {
-    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::DROPPED_PACKETS)) {
-      packet_info->SetDroppedPackets(
-          *(reinterpret_cast<uint32_t*> CMSG_DATA(cmsg)));
-    }
-    return;
-  }
-#endif
-
-#if defined(QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING)
-  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
-    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP)) {
-      LinuxSoTimestamping* linux_ts =
-          reinterpret_cast<LinuxSoTimestamping*>(CMSG_DATA(cmsg));
-      timespec* ts = &linux_ts->systime;
-      int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
-                     (static_cast<int64_t>(ts->tv_nsec) / 1000);
-      packet_info->SetReceiveTimestamp(
-          QuicWallTime::FromUNIXMicroseconds(usec));
-    }
-    return;
-  }
-#endif
-
-  if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
-    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V6_SELF_IP)) {
-      const in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
-      const char* addr_data = reinterpret_cast<const char*>(&info->ipi6_addr);
-      int addr_len = sizeof(in6_addr);
-      QuicIpAddress self_v6_ip;
-      if (self_v6_ip.FromPackedString(addr_data, addr_len)) {
-        packet_info->SetSelfV6Ip(self_v6_ip);
-      } else {
-        QUIC_BUG(quic_bug_10751_1) << "QuicIpAddress::FromPackedString failed";
-      }
-    }
-    return;
-  }
-
-  if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
-    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V4_SELF_IP)) {
-      const in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
-      const char* addr_data = reinterpret_cast<const char*>(&info->ipi_addr);
-      int addr_len = sizeof(in_addr);
-      QuicIpAddress self_v4_ip;
-      if (self_v4_ip.FromPackedString(addr_data, addr_len)) {
-        packet_info->SetSelfV4Ip(self_v4_ip);
-      } else {
-        QUIC_BUG(quic_bug_10751_2) << "QuicIpAddress::FromPackedString failed";
-      }
-    }
-    return;
-  }
-
-  if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
-      (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT)) {
-    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::TTL)) {
-      packet_info->SetTtl(*(reinterpret_cast<int*>(CMSG_DATA(cmsg))));
-    }
-    return;
-  }
-
-  if (packet_info_interested.IsSet(
-          QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
-    BufferSpan google_packet_headers;
-    if (GetGooglePacketHeadersFromControlMessage(
-            cmsg, &google_packet_headers.buffer,
-            &google_packet_headers.buffer_len)) {
-      packet_info->SetGooglePacketHeaders(google_packet_headers);
-    }
-  }
-}
-
-bool NextCmsg(msghdr* hdr,
-              char* control_buffer,
-              size_t control_buffer_len,
-              int cmsg_level,
-              int cmsg_type,
-              size_t data_size,
-              cmsghdr** cmsg /*in, out*/) {
-  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
-  // return nullptr.
-  hdr->msg_controllen += CMSG_SPACE(data_size);
-  if (hdr->msg_controllen > control_buffer_len) {
-    return false;
-  }
-
-  if ((*cmsg) == nullptr) {
-    QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
-    memset(control_buffer, 0, control_buffer_len);
-    hdr->msg_control = control_buffer;
-    (*cmsg) = CMSG_FIRSTHDR(hdr);
-  } else {
-    QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
-    (*cmsg) = CMSG_NXTHDR(hdr, (*cmsg));
-  }
-
-  if (nullptr == (*cmsg)) {
-    return false;
-  }
-
-  (*cmsg)->cmsg_len = CMSG_LEN(data_size);
-  (*cmsg)->cmsg_level = cmsg_level;
-  (*cmsg)->cmsg_type = cmsg_type;
-
-  return true;
-}
-}  // namespace
-
-QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
-                                         int receive_buffer_size,
-                                         int send_buffer_size,
-                                         bool ipv6_only) {
-  // QUICHE_DCHECK here so the program exits early(before reading packets) in
-  // debug mode. This should have been a static_assert, however it can't be done
-  // on ios/osx because CMSG_SPACE isn't a constant expression there.
-  QUICHE_DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
-  QuicUdpSocketFd fd = CreateNonblockingSocket(address_family);
-
-  if (fd == kQuicInvalidSocketFd) {
-    return kQuicInvalidSocketFd;
-  }
-
-  if (!SetupSocket(fd, address_family, receive_buffer_size, send_buffer_size,
-                   ipv6_only)) {
-    Destroy(fd);
-    return kQuicInvalidSocketFd;
-  }
-
-  return fd;
-}
-
-bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd,
-                                   int address_family,
-                                   int receive_buffer_size,
-                                   int send_buffer_size,
-                                   bool ipv6_only) {
-  // Receive buffer size.
-  if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_buffer_size,
-                 sizeof(receive_buffer_size)) != 0) {
-    QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket recv size";
-    return false;
-  }
-
-  // Send buffer size.
-  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_buffer_size,
-                 sizeof(send_buffer_size)) != 0) {
-    QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket send size";
-    return false;
-  }
-
-  if (!(address_family == AF_INET6 && ipv6_only)) {
-    if (!EnableReceiveSelfIpAddressForV4(fd)) {
-      QUIC_LOG_FIRST_N(ERROR, 100)
-          << "Failed to enable receiving of self v4 ip";
-      return false;
-    }
-  }
-
-  if (address_family == AF_INET6) {
-    if (!EnableReceiveSelfIpAddressForV6(fd)) {
-      QUIC_LOG_FIRST_N(ERROR, 100)
-          << "Failed to enable receiving of self v6 ip";
-      return false;
-    }
-  }
-
-  return true;
-}
-
-void QuicUdpSocketApi::Destroy(QuicUdpSocketFd fd) {
-  if (fd != kQuicInvalidSocketFd) {
-    close(fd);
-  }
-}
-
-bool QuicUdpSocketApi::Bind(QuicUdpSocketFd fd, QuicSocketAddress address) {
-  sockaddr_storage addr = address.generic_address();
-  int addr_len =
-      address.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
-  return 0 == bind(fd, reinterpret_cast<sockaddr*>(&addr), addr_len);
-}
-
-bool QuicUdpSocketApi::EnableDroppedPacketCount(QuicUdpSocketFd fd) {
-#if defined(__linux__) && defined(SO_RXQ_OVFL)
-  int get_overflow = 1;
-  return 0 == setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
-                         sizeof(get_overflow));
-#else
-  (void)fd;
-  return false;
-#endif
-}
-
-bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd) {
-  int get_self_ip = 1;
-  return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_self_ip,
-                         sizeof(get_self_ip));
-}
-
-bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd) {
-  int get_self_ip = 1;
-  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_self_ip,
-                         sizeof(get_self_ip));
-}
-
-bool QuicUdpSocketApi::EnableReceiveTimestamp(QuicUdpSocketFd fd) {
-#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
-  int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
-  return 0 == setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
-                         sizeof(timestamping));
-#else
-  (void)fd;
-  return false;
-#endif
-}
-
-bool QuicUdpSocketApi::EnableReceiveTtlForV4(QuicUdpSocketFd fd) {
-#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
-  int get_ttl = 1;
-  return 0 == setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &get_ttl, sizeof(get_ttl));
-#else
-  (void)fd;
-  return false;
-#endif
-}
-
-bool QuicUdpSocketApi::EnableReceiveTtlForV6(QuicUdpSocketFd fd) {
-#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
-  int get_ttl = 1;
-  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &get_ttl,
-                         sizeof(get_ttl));
-#else
-  (void)fd;
-  return false;
-#endif
-}
-
-bool QuicUdpSocketApi::WaitUntilReadable(QuicUdpSocketFd fd,
-                                         QuicTime::Delta timeout) {
-  fd_set read_fds;
-  FD_ZERO(&read_fds);
-  FD_SET(fd, &read_fds);
-
-  timeval select_timeout;
-  select_timeout.tv_sec = timeout.ToSeconds();
-  select_timeout.tv_usec = timeout.ToMicroseconds() % 1000000;
-
-  return 1 == select(1 + fd, &read_fds, nullptr, nullptr, &select_timeout);
-}
-
-void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
-                                  BitMask64 packet_info_interested,
-                                  ReadPacketResult* result) {
-  result->ok = false;
-  BufferSpan& packet_buffer = result->packet_buffer;
-  BufferSpan& control_buffer = result->control_buffer;
-  QuicUdpPacketInfo* packet_info = &result->packet_info;
-
-  QUICHE_DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
-
-  struct iovec iov = {packet_buffer.buffer, packet_buffer.buffer_len};
-  struct sockaddr_storage raw_peer_address;
-
-  if (control_buffer.buffer_len > 0) {
-    reinterpret_cast<struct cmsghdr*>(control_buffer.buffer)->cmsg_len =
-        control_buffer.buffer_len;
-  }
-
-  msghdr hdr;
-  hdr.msg_name = &raw_peer_address;
-  hdr.msg_namelen = sizeof(raw_peer_address);
-  hdr.msg_iov = &iov;
-  hdr.msg_iovlen = 1;
-  hdr.msg_flags = 0;
-  hdr.msg_control = control_buffer.buffer;
-  hdr.msg_controllen = control_buffer.buffer_len;
-
-#if defined(__linux__)
-  // If MSG_TRUNC is set on Linux, recvmsg will return the real packet size even
-  // if |packet_buffer| is too small to receive it.
-  int flags = MSG_TRUNC;
-#else
-  int flags = 0;
-#endif
-
-  int bytes_read = recvmsg(fd, &hdr, flags);
-  if (bytes_read < 0) {
-    const int error_num = errno;
-    if (error_num != EAGAIN) {
-      QUIC_LOG_FIRST_N(ERROR, 100)
-          << "Error reading packet: " << strerror(error_num);
-    }
-    return;
-  }
-
-  if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
-    QUIC_BUG(quic_bug_10751_3)
-        << "Control buffer too small. size:" << control_buffer.buffer_len;
-    return;
-  }
-
-  if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC) ||
-      // Normally "bytes_read > packet_buffer.buffer_len" implies the MSG_TRUNC
-      // bit is set, but it is not the case if tested with config=android_arm64.
-      static_cast<size_t>(bytes_read) > packet_buffer.buffer_len) {
-    QUIC_LOG_FIRST_N(WARNING, 100)
-        << "Received truncated QUIC packet: buffer size:"
-        << packet_buffer.buffer_len << " packet size:" << bytes_read;
-    return;
-  }
-
-  packet_buffer.buffer_len = bytes_read;
-  if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
-    packet_info->SetPeerAddress(QuicSocketAddress(raw_peer_address));
-  }
-
-  if (hdr.msg_controllen > 0) {
-    for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
-         cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
-      BitMask64 prior_bitmask = packet_info->bitmask();
-      PopulatePacketInfoFromControlMessage(cmsg, packet_info,
-                                           packet_info_interested);
-      if (packet_info->bitmask() == prior_bitmask) {
-        QUIC_DLOG(INFO) << "Ignored cmsg_level:" << cmsg->cmsg_level
-                        << ", cmsg_type:" << cmsg->cmsg_type;
-      }
-    }
-  }
-
-  result->ok = true;
-}
-
-size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
-                                             BitMask64 packet_info_interested,
-                                             ReadPacketResults* results) {
-#if defined(__linux__) && !defined(__ANDROID__)
-  // Use recvmmsg.
-  size_t hdrs_size = sizeof(mmsghdr) * results->size();
-  mmsghdr* hdrs = static_cast<mmsghdr*>(alloca(hdrs_size));
-  memset(hdrs, 0, hdrs_size);
-
-  struct TempPerPacketData {
-    iovec iov;
-    sockaddr_storage raw_peer_address;
-  };
-  TempPerPacketData* packet_data_array = static_cast<TempPerPacketData*>(
-      alloca(sizeof(TempPerPacketData) * results->size()));
-
-  for (size_t i = 0; i < results->size(); ++i) {
-    (*results)[i].ok = false;
-
-    msghdr* hdr = &hdrs[i].msg_hdr;
-    TempPerPacketData* packet_data = &packet_data_array[i];
-    packet_data->iov.iov_base = (*results)[i].packet_buffer.buffer;
-    packet_data->iov.iov_len = (*results)[i].packet_buffer.buffer_len;
-
-    hdr->msg_name = &packet_data->raw_peer_address;
-    hdr->msg_namelen = sizeof(sockaddr_storage);
-    hdr->msg_iov = &packet_data->iov;
-    hdr->msg_iovlen = 1;
-    hdr->msg_flags = 0;
-    hdr->msg_control = (*results)[i].control_buffer.buffer;
-    hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
-
-    QUICHE_DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
-  }
-  // If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
-  // |hdrs[i].msg_len| even if packet buffer is too small to receive it.
-  int packets_read = recvmmsg(fd, hdrs, results->size(), MSG_TRUNC, nullptr);
-  if (packets_read <= 0) {
-    const int error_num = errno;
-    if (error_num != EAGAIN) {
-      QUIC_LOG_FIRST_N(ERROR, 100)
-          << "Error reading packets: " << strerror(error_num);
-    }
-    return 0;
-  }
-
-  for (int i = 0; i < packets_read; ++i) {
-    if (hdrs[i].msg_len == 0) {
-      continue;
-    }
-
-    msghdr& hdr = hdrs[i].msg_hdr;
-    if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
-      QUIC_BUG(quic_bug_10751_4) << "Control buffer too small. size:"
-                                 << (*results)[i].control_buffer.buffer_len
-                                 << ", need:" << hdr.msg_controllen;
-      continue;
-    }
-
-    if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC)) {
-      QUIC_LOG_FIRST_N(WARNING, 100)
-          << "Received truncated QUIC packet: buffer size:"
-          << (*results)[i].packet_buffer.buffer_len
-          << " packet size:" << hdrs[i].msg_len;
-      continue;
-    }
-
-    (*results)[i].ok = true;
-    (*results)[i].packet_buffer.buffer_len = hdrs[i].msg_len;
-
-    QuicUdpPacketInfo* packet_info = &(*results)[i].packet_info;
-    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
-      packet_info->SetPeerAddress(
-          QuicSocketAddress(packet_data_array[i].raw_peer_address));
-    }
-
-    if (hdr.msg_controllen > 0) {
-      for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
-           cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
-        PopulatePacketInfoFromControlMessage(cmsg, packet_info,
-                                             packet_info_interested);
-      }
-    }
-  }
-  return packets_read;
-#else
-  size_t num_packets = 0;
-  for (ReadPacketResult& result : *results) {
-    result.ok = false;
-  }
-  for (ReadPacketResult& result : *results) {
-    errno = 0;
-    ReadPacket(fd, packet_info_interested, &result);
-    if (!result.ok && errno == EAGAIN) {
-      break;
-    }
-    ++num_packets;
-  }
-  return num_packets;
-#endif
-}
-
-WriteResult QuicUdpSocketApi::WritePacket(
-    QuicUdpSocketFd fd,
-    const char* packet_buffer,
-    size_t packet_buffer_len,
-    const QuicUdpPacketInfo& packet_info) {
-  if (!packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
-    return WriteResult(WRITE_STATUS_ERROR, EINVAL);
-  }
-
-  char control_buffer[512];
-  sockaddr_storage raw_peer_address =
-      packet_info.peer_address().generic_address();
-  iovec iov = {const_cast<char*>(packet_buffer), packet_buffer_len};
-
-  msghdr hdr;
-  hdr.msg_name = &raw_peer_address;
-  hdr.msg_namelen = packet_info.peer_address().host().IsIPv4()
-                        ? sizeof(sockaddr_in)
-                        : sizeof(sockaddr_in6);
-  hdr.msg_iov = &iov;
-  hdr.msg_iovlen = 1;
-  hdr.msg_flags = 0;
-  hdr.msg_control = nullptr;
-  hdr.msg_controllen = 0;
-
-  cmsghdr* cmsg = nullptr;
-
-  // Set self IP.
-  if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP) &&
-      packet_info.self_v4_ip().IsInitialized()) {
-    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IP,
-                  IP_PKTINFO, sizeof(in_pktinfo), &cmsg)) {
-      QUIC_LOG_FIRST_N(ERROR, 100)
-          << "Not enough buffer to set self v4 ip address.";
-      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
-    }
-    SetV4SelfIpInControlMessage(packet_info.self_v4_ip(), cmsg);
-  } else if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP) &&
-             packet_info.self_v6_ip().IsInitialized()) {
-    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IPV6,
-                  IPV6_PKTINFO, sizeof(in6_pktinfo), &cmsg)) {
-      QUIC_LOG_FIRST_N(ERROR, 100)
-          << "Not enough buffer to set self v6 ip address.";
-      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
-    }
-    SetV6SelfIpInControlMessage(packet_info.self_v6_ip(), cmsg);
-  }
-
-#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
-  // Set ttl.
-  if (packet_info.HasValue(QuicUdpPacketInfoBit::TTL)) {
-    int cmsg_level =
-        packet_info.peer_address().host().IsIPv4() ? IPPROTO_IP : IPPROTO_IPV6;
-    int cmsg_type =
-        packet_info.peer_address().host().IsIPv4() ? IP_TTL : IPV6_HOPLIMIT;
-    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), cmsg_level,
-                  cmsg_type, sizeof(int), &cmsg)) {
-      QUIC_LOG_FIRST_N(ERROR, 100) << "Not enough buffer to set ttl.";
-      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
-    }
-    *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = packet_info.ttl();
-  }
-#endif
-
-  int rc;
-  do {
-    rc = sendmsg(fd, &hdr, 0);
-  } while (rc < 0 && errno == EINTR);
-  if (rc >= 0) {
-    return WriteResult(WRITE_STATUS_OK, rc);
-  }
-  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
-                         ? WRITE_STATUS_BLOCKED
-                         : WRITE_STATUS_ERROR,
-                     errno);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_unacked_packet_map.cc b/quic/core/quic_unacked_packet_map.cc
deleted file mode 100644
index 1c6f303..0000000
--- a/quic/core/quic_unacked_packet_map.cc
+++ /dev/null
@@ -1,658 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_unacked_packet_map.h"
-
-#include <cstddef>
-#include <limits>
-#include <type_traits>
-
-#include "absl/container/inlined_vector.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-
-namespace quic {
-
-namespace {
-bool WillStreamFrameLengthSumWrapAround(QuicPacketLength lhs,
-                                        QuicPacketLength rhs) {
-  static_assert(
-      std::is_unsigned<QuicPacketLength>::value,
-      "This function assumes QuicPacketLength is an unsigned integer type.");
-  return std::numeric_limits<QuicPacketLength>::max() - lhs < rhs;
-}
-
-enum QuicFrameTypeBitfield : uint32_t {
-  kInvalidFrameBitfield = 0,
-  kPaddingFrameBitfield = 1,
-  kRstStreamFrameBitfield = 1 << 1,
-  kConnectionCloseFrameBitfield = 1 << 2,
-  kGoawayFrameBitfield = 1 << 3,
-  kWindowUpdateFrameBitfield = 1 << 4,
-  kBlockedFrameBitfield = 1 << 5,
-  kStopWaitingFrameBitfield = 1 << 6,
-  kPingFrameBitfield = 1 << 7,
-  kCryptoFrameBitfield = 1 << 8,
-  kHandshakeDoneFrameBitfield = 1 << 9,
-  kStreamFrameBitfield = 1 << 10,
-  kAckFrameBitfield = 1 << 11,
-  kMtuDiscoveryFrameBitfield = 1 << 12,
-  kNewConnectionIdFrameBitfield = 1 << 13,
-  kMaxStreamsFrameBitfield = 1 << 14,
-  kStreamsBlockedFrameBitfield = 1 << 15,
-  kPathResponseFrameBitfield = 1 << 16,
-  kPathChallengeFrameBitfield = 1 << 17,
-  kStopSendingFrameBitfield = 1 << 18,
-  kMessageFrameBitfield = 1 << 19,
-  kNewTokenFrameBitfield = 1 << 20,
-  kRetireConnectionIdFrameBitfield = 1 << 21,
-  kAckFrequencyFrameBitfield = 1 << 22,
-};
-
-QuicFrameTypeBitfield GetFrameTypeBitfield(QuicFrameType type) {
-  switch (type) {
-    case PADDING_FRAME:
-      return kPaddingFrameBitfield;
-    case RST_STREAM_FRAME:
-      return kRstStreamFrameBitfield;
-    case CONNECTION_CLOSE_FRAME:
-      return kConnectionCloseFrameBitfield;
-    case GOAWAY_FRAME:
-      return kGoawayFrameBitfield;
-    case WINDOW_UPDATE_FRAME:
-      return kWindowUpdateFrameBitfield;
-    case BLOCKED_FRAME:
-      return kBlockedFrameBitfield;
-    case STOP_WAITING_FRAME:
-      return kStopWaitingFrameBitfield;
-    case PING_FRAME:
-      return kPingFrameBitfield;
-    case CRYPTO_FRAME:
-      return kCryptoFrameBitfield;
-    case HANDSHAKE_DONE_FRAME:
-      return kHandshakeDoneFrameBitfield;
-    case STREAM_FRAME:
-      return kStreamFrameBitfield;
-    case ACK_FRAME:
-      return kAckFrameBitfield;
-    case MTU_DISCOVERY_FRAME:
-      return kMtuDiscoveryFrameBitfield;
-    case NEW_CONNECTION_ID_FRAME:
-      return kNewConnectionIdFrameBitfield;
-    case MAX_STREAMS_FRAME:
-      return kMaxStreamsFrameBitfield;
-    case STREAMS_BLOCKED_FRAME:
-      return kStreamsBlockedFrameBitfield;
-    case PATH_RESPONSE_FRAME:
-      return kPathResponseFrameBitfield;
-    case PATH_CHALLENGE_FRAME:
-      return kPathChallengeFrameBitfield;
-    case STOP_SENDING_FRAME:
-      return kStopSendingFrameBitfield;
-    case MESSAGE_FRAME:
-      return kMessageFrameBitfield;
-    case NEW_TOKEN_FRAME:
-      return kNewTokenFrameBitfield;
-    case RETIRE_CONNECTION_ID_FRAME:
-      return kRetireConnectionIdFrameBitfield;
-    case ACK_FREQUENCY_FRAME:
-      return kAckFrequencyFrameBitfield;
-    case NUM_FRAME_TYPES:
-      QUIC_BUG(quic_bug_10518_1) << "Unexpected frame type";
-      return kInvalidFrameBitfield;
-  }
-  QUIC_BUG(quic_bug_10518_2) << "Unexpected frame type";
-  return kInvalidFrameBitfield;
-}
-
-}  // namespace
-
-QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective)
-    : perspective_(perspective),
-      least_unacked_(FirstSendingPacketNumber()),
-      bytes_in_flight_(0),
-      bytes_in_flight_per_packet_number_space_{0, 0, 0},
-      packets_in_flight_(0),
-      last_inflight_packet_sent_time_(QuicTime::Zero()),
-      last_inflight_packets_sent_time_{{QuicTime::Zero()},
-                                       {QuicTime::Zero()},
-                                       {QuicTime::Zero()}},
-      last_crypto_packet_sent_time_(QuicTime::Zero()),
-      session_notifier_(nullptr),
-      supports_multiple_packet_number_spaces_(false) {
-}
-
-QuicUnackedPacketMap::~QuicUnackedPacketMap() {
-  for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
-    DeleteFrames(&(transmission_info.retransmittable_frames));
-  }
-}
-
-void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet,
-                                         TransmissionType transmission_type,
-                                         QuicTime sent_time,
-                                         bool set_in_flight,
-                                         bool measure_rtt) {
-  const SerializedPacket& packet = *mutable_packet;
-  QuicPacketNumber packet_number = packet.packet_number;
-  QuicPacketLength bytes_sent = packet.encrypted_length;
-  QUIC_BUG_IF(quic_bug_12645_1, largest_sent_packet_.IsInitialized() &&
-                                    largest_sent_packet_ >= packet_number)
-      << "largest_sent_packet_: " << largest_sent_packet_
-      << ", packet_number: " << packet_number;
-  QUICHE_DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
-  while (least_unacked_ + unacked_packets_.size() < packet_number) {
-    unacked_packets_.push_back(QuicTransmissionInfo());
-    unacked_packets_.back().state = NEVER_SENT;
-  }
-
-  const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE;
-  QuicTransmissionInfo info(packet.encryption_level, transmission_type,
-                            sent_time, bytes_sent, has_crypto_handshake,
-                            packet.has_ack_frequency);
-  info.largest_acked = packet.largest_acked;
-  largest_sent_largest_acked_.UpdateMax(packet.largest_acked);
-
-  if (!measure_rtt) {
-    QUIC_BUG_IF(quic_bug_12645_2, set_in_flight)
-        << "Packet " << mutable_packet->packet_number << ", transmission type "
-        << TransmissionTypeToString(mutable_packet->transmission_type)
-        << ", retransmittable frames: "
-        << QuicFramesToString(mutable_packet->retransmittable_frames)
-        << ", nonretransmittable_frames: "
-        << QuicFramesToString(mutable_packet->nonretransmittable_frames);
-    info.state = NOT_CONTRIBUTING_RTT;
-  }
-
-  largest_sent_packet_ = packet_number;
-  if (set_in_flight) {
-    const PacketNumberSpace packet_number_space =
-        GetPacketNumberSpace(info.encryption_level);
-    bytes_in_flight_ += bytes_sent;
-    bytes_in_flight_per_packet_number_space_[packet_number_space] += bytes_sent;
-    ++packets_in_flight_;
-    info.in_flight = true;
-    largest_sent_retransmittable_packets_[packet_number_space] = packet_number;
-    last_inflight_packet_sent_time_ = sent_time;
-    last_inflight_packets_sent_time_[packet_number_space] = sent_time;
-  }
-  unacked_packets_.push_back(std::move(info));
-  // Swap the retransmittable frames to avoid allocations.
-  // TODO(ianswett): Could use emplace_back when Chromium can.
-  if (has_crypto_handshake) {
-    last_crypto_packet_sent_time_ = sent_time;
-  }
-
-  mutable_packet->retransmittable_frames.swap(
-      unacked_packets_.back().retransmittable_frames);
-}
-
-void QuicUnackedPacketMap::RemoveObsoletePackets() {
-  while (!unacked_packets_.empty()) {
-    if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) {
-      break;
-    }
-    DeleteFrames(&unacked_packets_.front().retransmittable_frames);
-    unacked_packets_.pop_front();
-    ++least_unacked_;
-  }
-}
-
-bool QuicUnackedPacketMap::HasRetransmittableFrames(
-    QuicPacketNumber packet_number) const {
-  QUICHE_DCHECK_GE(packet_number, least_unacked_);
-  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
-  return HasRetransmittableFrames(
-      unacked_packets_[packet_number - least_unacked_]);
-}
-
-bool QuicUnackedPacketMap::HasRetransmittableFrames(
-    const QuicTransmissionInfo& info) const {
-  if (!QuicUtils::IsAckable(info.state)) {
-    return false;
-  }
-
-  for (const auto& frame : info.retransmittable_frames) {
-    if (session_notifier_->IsFrameOutstanding(frame)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void QuicUnackedPacketMap::RemoveRetransmittability(
-    QuicTransmissionInfo* info) {
-  DeleteFrames(&info->retransmittable_frames);
-  info->first_sent_after_loss.Clear();
-}
-
-void QuicUnackedPacketMap::RemoveRetransmittability(
-    QuicPacketNumber packet_number) {
-  QUICHE_DCHECK_GE(packet_number, least_unacked_);
-  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
-  QuicTransmissionInfo* info =
-      &unacked_packets_[packet_number - least_unacked_];
-  RemoveRetransmittability(info);
-}
-
-void QuicUnackedPacketMap::IncreaseLargestAcked(
-    QuicPacketNumber largest_acked) {
-  QUICHE_DCHECK(!largest_acked_.IsInitialized() ||
-                largest_acked_ <= largest_acked);
-  largest_acked_ = largest_acked;
-}
-
-void QuicUnackedPacketMap::MaybeUpdateLargestAckedOfPacketNumberSpace(
-    PacketNumberSpace packet_number_space,
-    QuicPacketNumber packet_number) {
-  largest_acked_packets_[packet_number_space].UpdateMax(packet_number);
-}
-
-bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
-    QuicPacketNumber packet_number,
-    const QuicTransmissionInfo& info) const {
-  // Packet can be used for RTT measurement if it may yet be acked as the
-  // largest observed packet by the receiver.
-  return QuicUtils::IsAckable(info.state) &&
-         (!largest_acked_.IsInitialized() || packet_number > largest_acked_) &&
-         info.state != NOT_CONTRIBUTING_RTT;
-}
-
-bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
-    const QuicTransmissionInfo& info) const {
-  // Packet contributes to congestion control if it is considered inflight.
-  return info.in_flight;
-}
-
-bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
-    const QuicTransmissionInfo& info) const {
-  // Wait for 1 RTT before giving up on the lost packet.
-  return info.first_sent_after_loss.IsInitialized() &&
-         (!largest_acked_.IsInitialized() ||
-          info.first_sent_after_loss > largest_acked_);
-}
-
-bool QuicUnackedPacketMap::IsPacketUseless(
-    QuicPacketNumber packet_number,
-    const QuicTransmissionInfo& info) const {
-  return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
-         !IsPacketUsefulForCongestionControl(info) &&
-         !IsPacketUsefulForRetransmittableData(info);
-}
-
-bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
-  if (packet_number < least_unacked_ ||
-      packet_number >= least_unacked_ + unacked_packets_.size()) {
-    return false;
-  }
-  return !IsPacketUseless(packet_number,
-                          unacked_packets_[packet_number - least_unacked_]);
-}
-
-void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
-  if (info->in_flight) {
-    QUIC_BUG_IF(quic_bug_12645_3, bytes_in_flight_ < info->bytes_sent);
-    QUIC_BUG_IF(quic_bug_12645_4, packets_in_flight_ == 0);
-    bytes_in_flight_ -= info->bytes_sent;
-    --packets_in_flight_;
-
-    const PacketNumberSpace packet_number_space =
-        GetPacketNumberSpace(info->encryption_level);
-    if (bytes_in_flight_per_packet_number_space_[packet_number_space] <
-        info->bytes_sent) {
-      QUIC_BUG(quic_bug_10518_3)
-          << "bytes_in_flight: "
-          << bytes_in_flight_per_packet_number_space_[packet_number_space]
-          << " is smaller than bytes_sent: " << info->bytes_sent
-          << " for packet number space: "
-          << PacketNumberSpaceToString(packet_number_space);
-      bytes_in_flight_per_packet_number_space_[packet_number_space] = 0;
-    } else {
-      bytes_in_flight_per_packet_number_space_[packet_number_space] -=
-          info->bytes_sent;
-    }
-    if (bytes_in_flight_per_packet_number_space_[packet_number_space] == 0) {
-      last_inflight_packets_sent_time_[packet_number_space] = QuicTime::Zero();
-    }
-
-    info->in_flight = false;
-  }
-}
-
-void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
-  QUICHE_DCHECK_GE(packet_number, least_unacked_);
-  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
-  QuicTransmissionInfo* info =
-      &unacked_packets_[packet_number - least_unacked_];
-  RemoveFromInFlight(info);
-}
-
-absl::InlinedVector<QuicPacketNumber, 2>
-QuicUnackedPacketMap::NeuterUnencryptedPackets() {
-  absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
-  QuicPacketNumber packet_number = GetLeastUnacked();
-  for (QuicUnackedPacketMap::iterator it = begin(); it != end();
-       ++it, ++packet_number) {
-    if (!it->retransmittable_frames.empty() &&
-        it->encryption_level == ENCRYPTION_INITIAL) {
-      QUIC_DVLOG(2) << "Neutering unencrypted packet " << packet_number;
-      // Once the connection swithes to forward secure, no unencrypted packets
-      // will be sent. The data has been abandoned in the cryto stream. Remove
-      // it from in flight.
-      RemoveFromInFlight(packet_number);
-      it->state = NEUTERED;
-      neutered_packets.push_back(packet_number);
-      // Notify session that the data has been delivered (but do not notify
-      // send algorithm).
-      // TODO(b/148868195): use NotifyFramesNeutered.
-      NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
-      QUICHE_DCHECK(!HasRetransmittableFrames(*it));
-    }
-  }
-  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_ ||
-                last_inflight_packets_sent_time_[INITIAL_DATA] ==
-                    QuicTime::Zero());
-  return neutered_packets;
-}
-
-absl::InlinedVector<QuicPacketNumber, 2>
-QuicUnackedPacketMap::NeuterHandshakePackets() {
-  absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
-  QuicPacketNumber packet_number = GetLeastUnacked();
-  for (QuicUnackedPacketMap::iterator it = begin(); it != end();
-       ++it, ++packet_number) {
-    if (!it->retransmittable_frames.empty() &&
-        GetPacketNumberSpace(it->encryption_level) == HANDSHAKE_DATA) {
-      QUIC_DVLOG(2) << "Neutering handshake packet " << packet_number;
-      RemoveFromInFlight(packet_number);
-      // Notify session that the data has been delivered (but do not notify
-      // send algorithm).
-      it->state = NEUTERED;
-      neutered_packets.push_back(packet_number);
-      // TODO(b/148868195): use NotifyFramesNeutered.
-      NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
-    }
-  }
-  QUICHE_DCHECK(!supports_multiple_packet_number_spaces() ||
-                last_inflight_packets_sent_time_[HANDSHAKE_DATA] ==
-                    QuicTime::Zero());
-  return neutered_packets;
-}
-
-bool QuicUnackedPacketMap::HasInFlightPackets() const {
-  return bytes_in_flight_ > 0;
-}
-
-const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
-    QuicPacketNumber packet_number) const {
-  return unacked_packets_[packet_number - least_unacked_];
-}
-
-QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo(
-    QuicPacketNumber packet_number) {
-  return &unacked_packets_[packet_number - least_unacked_];
-}
-
-QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const {
-  return last_inflight_packet_sent_time_;
-}
-
-QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const {
-  return last_crypto_packet_sent_time_;
-}
-
-size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
-  size_t unacked_packet_count = 0;
-  QuicPacketNumber packet_number = least_unacked_;
-  for (auto it = begin(); it != end(); ++it, ++packet_number) {
-    if (!IsPacketUseless(packet_number, *it)) {
-      ++unacked_packet_count;
-    }
-  }
-  return unacked_packet_count;
-}
-
-bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
-  if (bytes_in_flight_ > kDefaultTCPMSS) {
-    return true;
-  }
-  size_t num_in_flight = 0;
-  for (auto it = rbegin(); it != rend(); ++it) {
-    if (it->in_flight) {
-      ++num_in_flight;
-    }
-    if (num_in_flight > 1) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
-  return session_notifier_->HasUnackedCryptoData();
-}
-
-bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
-  for (auto it = rbegin(); it != rend(); ++it) {
-    if (it->in_flight && HasRetransmittableFrames(*it)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
-  return least_unacked_;
-}
-
-void QuicUnackedPacketMap::SetSessionNotifier(
-    SessionNotifierInterface* session_notifier) {
-  session_notifier_ = session_notifier;
-}
-
-bool QuicUnackedPacketMap::NotifyFramesAcked(const QuicTransmissionInfo& info,
-                                             QuicTime::Delta ack_delay,
-                                             QuicTime receive_timestamp) {
-  if (session_notifier_ == nullptr) {
-    return false;
-  }
-  bool new_data_acked = false;
-  for (const QuicFrame& frame : info.retransmittable_frames) {
-    if (session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp)) {
-      new_data_acked = true;
-    }
-  }
-  return new_data_acked;
-}
-
-void QuicUnackedPacketMap::NotifyFramesLost(const QuicTransmissionInfo& info,
-                                            TransmissionType /*type*/) {
-  for (const QuicFrame& frame : info.retransmittable_frames) {
-    session_notifier_->OnFrameLost(frame);
-  }
-}
-
-bool QuicUnackedPacketMap::RetransmitFrames(const QuicFrames& frames,
-                                            TransmissionType type) {
-  return session_notifier_->RetransmitFrames(frames, type);
-}
-
-void QuicUnackedPacketMap::MaybeAggregateAckedStreamFrame(
-    const QuicTransmissionInfo& info,
-    QuicTime::Delta ack_delay,
-    QuicTime receive_timestamp) {
-  if (session_notifier_ == nullptr) {
-    return;
-  }
-  for (const auto& frame : info.retransmittable_frames) {
-    // Determine whether acked stream frame can be aggregated.
-    const bool can_aggregate =
-        frame.type == STREAM_FRAME &&
-        frame.stream_frame.stream_id == aggregated_stream_frame_.stream_id &&
-        frame.stream_frame.offset == aggregated_stream_frame_.offset +
-                                         aggregated_stream_frame_.data_length &&
-        // We would like to increment aggregated_stream_frame_.data_length by
-        // frame.stream_frame.data_length, so we need to make sure their sum is
-        // representable by QuicPacketLength, which is the type of the former.
-        !WillStreamFrameLengthSumWrapAround(
-            aggregated_stream_frame_.data_length,
-            frame.stream_frame.data_length);
-
-    if (can_aggregate) {
-      // Aggregate stream frame.
-      aggregated_stream_frame_.data_length += frame.stream_frame.data_length;
-      aggregated_stream_frame_.fin = frame.stream_frame.fin;
-      if (aggregated_stream_frame_.fin) {
-        // Notify session notifier aggregated stream frame gets acked if fin is
-        // acked.
-        NotifyAggregatedStreamFrameAcked(ack_delay);
-      }
-      continue;
-    }
-
-    NotifyAggregatedStreamFrameAcked(ack_delay);
-    if (frame.type != STREAM_FRAME || frame.stream_frame.fin) {
-      session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp);
-      continue;
-    }
-
-    // Delay notifying session notifier stream frame gets acked in case it can
-    // be aggregated with following acked ones.
-    aggregated_stream_frame_.stream_id = frame.stream_frame.stream_id;
-    aggregated_stream_frame_.offset = frame.stream_frame.offset;
-    aggregated_stream_frame_.data_length = frame.stream_frame.data_length;
-    aggregated_stream_frame_.fin = frame.stream_frame.fin;
-  }
-}
-
-void QuicUnackedPacketMap::NotifyAggregatedStreamFrameAcked(
-    QuicTime::Delta ack_delay) {
-  if (aggregated_stream_frame_.stream_id == static_cast<QuicStreamId>(-1) ||
-      session_notifier_ == nullptr) {
-    // Aggregated stream frame is empty.
-    return;
-  }
-  // Note: there is no receive_timestamp for an aggregated stream frame.  The
-  // frames that are aggregated may not have been received at the same time.
-  session_notifier_->OnFrameAcked(QuicFrame(aggregated_stream_frame_),
-                                  ack_delay,
-                                  /*receive_timestamp=*/QuicTime::Zero());
-  // Clear aggregated stream frame.
-  aggregated_stream_frame_.stream_id = -1;
-}
-
-PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
-    QuicPacketNumber packet_number) const {
-  return GetPacketNumberSpace(
-      GetTransmissionInfo(packet_number).encryption_level);
-}
-
-PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
-    EncryptionLevel encryption_level) const {
-  if (supports_multiple_packet_number_spaces_) {
-    return QuicUtils::GetPacketNumberSpace(encryption_level);
-  }
-  if (perspective_ == Perspective::IS_CLIENT) {
-    return encryption_level == ENCRYPTION_INITIAL ? HANDSHAKE_DATA
-                                                  : APPLICATION_DATA;
-  }
-  return encryption_level == ENCRYPTION_FORWARD_SECURE ? APPLICATION_DATA
-                                                       : HANDSHAKE_DATA;
-}
-
-QuicPacketNumber QuicUnackedPacketMap::GetLargestAckedOfPacketNumberSpace(
-    PacketNumberSpace packet_number_space) const {
-  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
-    QUIC_BUG(quic_bug_10518_4)
-        << "Invalid packet number space: " << packet_number_space;
-    return QuicPacketNumber();
-  }
-  return largest_acked_packets_[packet_number_space];
-}
-
-QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime(
-    PacketNumberSpace packet_number_space) const {
-  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
-    QUIC_BUG(quic_bug_10518_5)
-        << "Invalid packet number space: " << packet_number_space;
-    return QuicTime::Zero();
-  }
-  return last_inflight_packets_sent_time_[packet_number_space];
-}
-
-QuicPacketNumber
-QuicUnackedPacketMap::GetLargestSentRetransmittableOfPacketNumberSpace(
-    PacketNumberSpace packet_number_space) const {
-  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
-    QUIC_BUG(quic_bug_10518_6)
-        << "Invalid packet number space: " << packet_number_space;
-    return QuicPacketNumber();
-  }
-  return largest_sent_retransmittable_packets_[packet_number_space];
-}
-
-const QuicTransmissionInfo*
-QuicUnackedPacketMap::GetFirstInFlightTransmissionInfo() const {
-  QUICHE_DCHECK(HasInFlightPackets());
-  for (auto it = begin(); it != end(); ++it) {
-    if (it->in_flight) {
-      return &(*it);
-    }
-  }
-  QUICHE_DCHECK(false);
-  return nullptr;
-}
-
-const QuicTransmissionInfo*
-QuicUnackedPacketMap::GetFirstInFlightTransmissionInfoOfSpace(
-    PacketNumberSpace packet_number_space) const {
-  // TODO(fayang): Optimize this part if arm 1st PTO with first in flight sent
-  // time works.
-  for (auto it = begin(); it != end(); ++it) {
-    if (it->in_flight &&
-        GetPacketNumberSpace(it->encryption_level) == packet_number_space) {
-      return &(*it);
-    }
-  }
-  return nullptr;
-}
-
-void QuicUnackedPacketMap::EnableMultiplePacketNumberSpacesSupport() {
-  if (supports_multiple_packet_number_spaces_) {
-    QUIC_BUG(quic_bug_10518_7)
-        << "Multiple packet number spaces has already been enabled";
-    return;
-  }
-  if (largest_sent_packet_.IsInitialized()) {
-    QUIC_BUG(quic_bug_10518_8)
-        << "Try to enable multiple packet number spaces support after any "
-           "packet has been sent.";
-    return;
-  }
-
-  supports_multiple_packet_number_spaces_ = true;
-}
-
-int32_t QuicUnackedPacketMap::GetLastPacketContent() const {
-  if (empty()) {
-    // Use -1 to distinguish with packets with no retransmittable frames nor
-    // acks.
-    return -1;
-  }
-  int32_t content = 0;
-  const QuicTransmissionInfo& last_packet = unacked_packets_.back();
-  for (const auto& frame : last_packet.retransmittable_frames) {
-    content |= GetFrameTypeBitfield(frame.type);
-  }
-  if (last_packet.largest_acked.IsInitialized()) {
-    content |= GetFrameTypeBitfield(ACK_FRAME);
-  }
-  return content;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_unacked_packet_map.h b/quic/core/quic_unacked_packet_map.h
deleted file mode 100644
index 885dfb9..0000000
--- a/quic/core/quic_unacked_packet_map.h
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
-#define QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-
-namespace test {
-class QuicUnackedPacketMapPeer;
-}  // namespace test
-
-// Class which tracks unacked packets for three purposes:
-// 1) Track retransmittable data, including multiple transmissions of frames.
-// 2) Track packets and bytes in flight for congestion control.
-// 3) Track sent time of packets to provide RTT measurements from acks.
-class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
- public:
-  QuicUnackedPacketMap(Perspective perspective);
-  QuicUnackedPacketMap(const QuicUnackedPacketMap&) = delete;
-  QuicUnackedPacketMap& operator=(const QuicUnackedPacketMap&) = delete;
-  ~QuicUnackedPacketMap();
-
-  // Adds |mutable_packet| to the map and marks it as sent at |sent_time|.
-  // Marks the packet as in flight if |set_in_flight| is true.
-  // Packets marked as in flight are expected to be marked as missing when they
-  // don't arrive, indicating the need for retransmission.
-  // Any retransmittible_frames in |mutable_packet| are swapped from
-  // |mutable_packet| into the QuicTransmissionInfo.
-  void AddSentPacket(SerializedPacket* mutable_packet,
-                     TransmissionType transmission_type,
-                     QuicTime sent_time,
-                     bool set_in_flight,
-                     bool measure_rtt);
-
-  // Returns true if the packet |packet_number| is unacked.
-  bool IsUnacked(QuicPacketNumber packet_number) const;
-
-  // Notifies session_notifier that frames have been acked. Returns true if any
-  // new data gets acked, returns false otherwise.
-  bool NotifyFramesAcked(const QuicTransmissionInfo& info,
-                         QuicTime::Delta ack_delay,
-                         QuicTime receive_timestamp);
-
-  // Notifies session_notifier that frames in |info| are considered as lost.
-  void NotifyFramesLost(const QuicTransmissionInfo& info,
-                        TransmissionType type);
-
-  // Notifies session_notifier to retransmit frames with |transmission_type|.
-  // Returns true if all data gets retransmitted.
-  bool RetransmitFrames(const QuicFrames& frames, TransmissionType type);
-
-  // Marks |info| as no longer in flight.
-  void RemoveFromInFlight(QuicTransmissionInfo* info);
-
-  // Marks |packet_number| as no longer in flight.
-  void RemoveFromInFlight(QuicPacketNumber packet_number);
-
-  // Called to neuter all unencrypted packets to ensure they do not get
-  // retransmitted. Returns a vector of neutered packet numbers.
-  absl::InlinedVector<QuicPacketNumber, 2> NeuterUnencryptedPackets();
-
-  // Called to neuter packets in handshake packet number space to ensure they do
-  // not get retransmitted. Returns a vector of neutered packet numbers.
-  // TODO(fayang): Consider to combine this with NeuterUnencryptedPackets.
-  absl::InlinedVector<QuicPacketNumber, 2> NeuterHandshakePackets();
-
-  // Returns true if |packet_number| has retransmittable frames. This will
-  // return false if all frames of this packet are either non-retransmittable or
-  // have been acked.
-  bool HasRetransmittableFrames(QuicPacketNumber packet_number) const;
-
-  // Returns true if |info| has retransmittable frames. This will return false
-  // if all frames of this packet are either non-retransmittable or have been
-  // acked.
-  bool HasRetransmittableFrames(const QuicTransmissionInfo& info) const;
-
-  // Returns true if there are any unacked packets which have retransmittable
-  // frames.
-  bool HasUnackedRetransmittableFrames() const;
-
-  // Returns true if there are no packets present in the unacked packet map.
-  bool empty() const { return unacked_packets_.empty(); }
-
-  // Returns the largest packet number that has been sent.
-  QuicPacketNumber largest_sent_packet() const { return largest_sent_packet_; }
-
-  QuicPacketNumber largest_sent_largest_acked() const {
-    return largest_sent_largest_acked_;
-  }
-
-  // Returns the largest packet number that has been acked.
-  QuicPacketNumber largest_acked() const { return largest_acked_; }
-
-  // Returns the sum of bytes from all packets in flight.
-  QuicByteCount bytes_in_flight() const { return bytes_in_flight_; }
-  QuicPacketCount packets_in_flight() const { return packets_in_flight_; }
-
-  // Returns the smallest packet number of a serialized packet which has not
-  // been acked by the peer.  If there are no unacked packets, returns 0.
-  QuicPacketNumber GetLeastUnacked() const;
-
-  using const_iterator =
-      quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_iterator;
-  using const_reverse_iterator =
-      quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_reverse_iterator;
-  using iterator = quiche::QuicheCircularDeque<QuicTransmissionInfo>::iterator;
-
-  const_iterator begin() const { return unacked_packets_.begin(); }
-  const_iterator end() const { return unacked_packets_.end(); }
-  const_reverse_iterator rbegin() const { return unacked_packets_.rbegin(); }
-  const_reverse_iterator rend() const { return unacked_packets_.rend(); }
-  iterator begin() { return unacked_packets_.begin(); }
-  iterator end() { return unacked_packets_.end(); }
-
-  // Returns true if there are unacked packets that are in flight.
-  bool HasInFlightPackets() const;
-
-  // Returns the QuicTransmissionInfo associated with |packet_number|, which
-  // must be unacked.
-  const QuicTransmissionInfo& GetTransmissionInfo(
-      QuicPacketNumber packet_number) const;
-
-  // Returns mutable QuicTransmissionInfo associated with |packet_number|, which
-  // must be unacked.
-  QuicTransmissionInfo* GetMutableTransmissionInfo(
-      QuicPacketNumber packet_number);
-
-  // Returns the time that the last unacked packet was sent.
-  QuicTime GetLastInFlightPacketSentTime() const;
-
-  // Returns the time that the last unacked crypto packet was sent.
-  QuicTime GetLastCryptoPacketSentTime() const;
-
-  // Returns the number of unacked packets.
-  size_t GetNumUnackedPacketsDebugOnly() const;
-
-  // Returns true if there are multiple packets in flight.
-  // TODO(fayang): Remove this method and use packets_in_flight_ instead.
-  bool HasMultipleInFlightPackets() const;
-
-  // Returns true if there are any pending crypto packets.
-  bool HasPendingCryptoPackets() const;
-
-  // Returns true if there is any unacked non-crypto stream data.
-  bool HasUnackedStreamData() const {
-    return session_notifier_->HasUnackedStreamData();
-  }
-
-  // Removes any retransmittable frames from this transmission or an associated
-  // transmission.  It removes now useless transmissions, and disconnects any
-  // other packets from other transmissions.
-  void RemoveRetransmittability(QuicTransmissionInfo* info);
-
-  // Looks up the QuicTransmissionInfo by |packet_number| and calls
-  // RemoveRetransmittability.
-  void RemoveRetransmittability(QuicPacketNumber packet_number);
-
-  // Increases the largest acked.  Any packets less or equal to
-  // |largest_acked| are discarded if they are only for the RTT purposes.
-  void IncreaseLargestAcked(QuicPacketNumber largest_acked);
-
-  // Called when |packet_number| gets acked. Maybe increase the largest acked of
-  // |packet_number_space|.
-  void MaybeUpdateLargestAckedOfPacketNumberSpace(
-      PacketNumberSpace packet_number_space,
-      QuicPacketNumber packet_number);
-
-  // Remove any packets no longer needed for retransmission, congestion, or
-  // RTT measurement purposes.
-  void RemoveObsoletePackets();
-
-  // Try to aggregate acked contiguous stream frames. For noncontiguous stream
-  // frames or control frames, notify the session notifier they get acked
-  // immediately.
-  void MaybeAggregateAckedStreamFrame(const QuicTransmissionInfo& info,
-                                      QuicTime::Delta ack_delay,
-                                      QuicTime receive_timestamp);
-
-  // Notify the session notifier of any stream data aggregated in
-  // aggregated_stream_frame_.  No effect if the stream frame has an invalid
-  // stream id.
-  void NotifyAggregatedStreamFrameAcked(QuicTime::Delta ack_delay);
-
-  // Returns packet number space that |packet_number| belongs to. Please use
-  // GetPacketNumberSpace(EncryptionLevel) whenever encryption level is
-  // available.
-  PacketNumberSpace GetPacketNumberSpace(QuicPacketNumber packet_number) const;
-
-  // Returns packet number space of |encryption_level|.
-  PacketNumberSpace GetPacketNumberSpace(
-      EncryptionLevel encryption_level) const;
-
-  // Returns largest acked packet number of |packet_number_space|.
-  QuicPacketNumber GetLargestAckedOfPacketNumberSpace(
-      PacketNumberSpace packet_number_space) const;
-
-  // Returns largest sent retransmittable packet number of
-  // |packet_number_space|.
-  QuicPacketNumber GetLargestSentRetransmittableOfPacketNumberSpace(
-      PacketNumberSpace packet_number_space) const;
-
-  // Returns largest sent packet number of |encryption_level|.
-  QuicPacketNumber GetLargestSentPacketOfPacketNumberSpace(
-      EncryptionLevel encryption_level) const;
-
-  // Returns last in flight packet sent time of |packet_number_space|.
-  QuicTime GetLastInFlightPacketSentTime(
-      PacketNumberSpace packet_number_space) const;
-
-  // Returns TransmissionInfo of the first in flight packet.
-  const QuicTransmissionInfo* GetFirstInFlightTransmissionInfo() const;
-
-  // Returns TransmissionInfo of first in flight packet in
-  // |packet_number_space|.
-  const QuicTransmissionInfo* GetFirstInFlightTransmissionInfoOfSpace(
-      PacketNumberSpace packet_number_space) const;
-
-  void SetSessionNotifier(SessionNotifierInterface* session_notifier);
-
-  void EnableMultiplePacketNumberSpacesSupport();
-
-  // Returns a bitfield of retransmittable frames of last packet in
-  // unacked_packets_. For example, if the packet contains STREAM_FRAME, content
-  // & (1 << STREAM_FRAME) would be set. Returns max uint32_t if
-  // unacked_packets_ is empty.
-  int32_t GetLastPacketContent() const;
-
-  Perspective perspective() const { return perspective_; }
-
-  bool supports_multiple_packet_number_spaces() const {
-    return supports_multiple_packet_number_spaces_;
-  }
-
-  void ReserveInitialCapacity(size_t initial_capacity) {
-    unacked_packets_.reserve(initial_capacity);
-  }
-
-  std::string DebugString() const {
-    return absl::StrCat(
-        "{size: ", unacked_packets_.size(),
-        ", least_unacked: ", least_unacked_.ToString(),
-        ", largest_sent_packet: ", largest_sent_packet_.ToString(),
-        ", largest_acked: ", largest_acked_.ToString(),
-        ", bytes_in_flight: ", bytes_in_flight_,
-        ", packets_in_flight: ", packets_in_flight_, "}");
-  }
-
- private:
-  friend class test::QuicUnackedPacketMapPeer;
-
-  // Returns true if packet may be useful for an RTT measurement.
-  bool IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number,
-                                     const QuicTransmissionInfo& info) const;
-
-  // Returns true if packet may be useful for congestion control purposes.
-  bool IsPacketUsefulForCongestionControl(
-      const QuicTransmissionInfo& info) const;
-
-  // Returns true if packet may be associated with retransmittable data
-  // directly or through retransmissions.
-  bool IsPacketUsefulForRetransmittableData(
-      const QuicTransmissionInfo& info) const;
-
-  // Returns true if the packet no longer has a purpose in the map.
-  bool IsPacketUseless(QuicPacketNumber packet_number,
-                       const QuicTransmissionInfo& info) const;
-
-  const Perspective perspective_;
-
-  QuicPacketNumber largest_sent_packet_;
-  // The largest sent packet we expect to receive an ack for per packet number
-  // space.
-  QuicPacketNumber
-      largest_sent_retransmittable_packets_[NUM_PACKET_NUMBER_SPACES];
-  // The largest sent largest_acked in an ACK frame.
-  QuicPacketNumber largest_sent_largest_acked_;
-  // The largest received largest_acked from an ACK frame.
-  QuicPacketNumber largest_acked_;
-  // The largest received largest_acked from ACK frame per packet number space.
-  QuicPacketNumber largest_acked_packets_[NUM_PACKET_NUMBER_SPACES];
-
-  // Newly serialized retransmittable packets are added to this map, which
-  // contains owning pointers to any contained frames.  If a packet is
-  // retransmitted, this map will contain entries for both the old and the new
-  // packet. The old packet's retransmittable frames entry will be nullptr,
-  // while the new packet's entry will contain the frames to retransmit.
-  // If the old packet is acked before the new packet, then the old entry will
-  // be removed from the map and the new entry's retransmittable frames will be
-  // set to nullptr.
-  quiche::QuicheCircularDeque<QuicTransmissionInfo> unacked_packets_;
-
-  // The packet at the 0th index of unacked_packets_.
-  QuicPacketNumber least_unacked_;
-
-  QuicByteCount bytes_in_flight_;
-  // Bytes in flight per packet number space.
-  QuicByteCount
-      bytes_in_flight_per_packet_number_space_[NUM_PACKET_NUMBER_SPACES];
-  QuicPacketCount packets_in_flight_;
-
-  // Time that the last inflight packet was sent.
-  QuicTime last_inflight_packet_sent_time_;
-  // Time that the last in flight packet was sent per packet number space.
-  QuicTime last_inflight_packets_sent_time_[NUM_PACKET_NUMBER_SPACES];
-
-  // Time that the last unacked crypto packet was sent.
-  QuicTime last_crypto_packet_sent_time_;
-
-  // Aggregates acked stream data across multiple acked sent packets to save CPU
-  // by reducing the number of calls to the session notifier.
-  QuicStreamFrame aggregated_stream_frame_;
-
-  // Receives notifications of frames being retransmitted or acknowledged.
-  SessionNotifierInterface* session_notifier_;
-
-  // If true, supports multiple packet number spaces.
-  bool supports_multiple_packet_number_spaces_;
-
-  // Latched value of the quic_simple_inflight_time flag.
-  bool simple_inflight_time_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
diff --git a/quic/core/quic_unacked_packet_map_test.cc b/quic/core/quic_unacked_packet_map_test.cc
deleted file mode 100644
index 909ebe2..0000000
--- a/quic/core/quic_unacked_packet_map_test.cc
+++ /dev/null
@@ -1,699 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_unacked_packet_map.h"
-#include <cstddef>
-#include <limits>
-
-#include "absl/base/macros.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_transmission_info.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-using testing::_;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Default packet length.
-const uint32_t kDefaultLength = 1000;
-
-class QuicUnackedPacketMapTest : public QuicTestWithParam<Perspective> {
- protected:
-  QuicUnackedPacketMapTest()
-      : unacked_packets_(GetParam()),
-        now_(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1000)) {
-    unacked_packets_.SetSessionNotifier(&notifier_);
-    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
-    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_))
-        .Times(testing::AnyNumber());
-  }
-
-  ~QuicUnackedPacketMapTest() override {}
-
-  SerializedPacket CreateRetransmittablePacket(uint64_t packet_number) {
-    return CreateRetransmittablePacketForStream(
-        packet_number, QuicUtils::GetFirstBidirectionalStreamId(
-                           CurrentSupportedVersions()[0].transport_version,
-                           Perspective::IS_CLIENT));
-  }
-
-  SerializedPacket CreateRetransmittablePacketForStream(
-      uint64_t packet_number,
-      QuicStreamId stream_id) {
-    SerializedPacket packet(QuicPacketNumber(packet_number),
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
-    QuicStreamFrame frame;
-    frame.stream_id = stream_id;
-    packet.retransmittable_frames.push_back(QuicFrame(frame));
-    return packet;
-  }
-
-  SerializedPacket CreateNonRetransmittablePacket(uint64_t packet_number) {
-    return SerializedPacket(QuicPacketNumber(packet_number),
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
-  }
-
-  void VerifyInFlightPackets(uint64_t* packets, size_t num_packets) {
-    unacked_packets_.RemoveObsoletePackets();
-    if (num_packets == 0) {
-      EXPECT_FALSE(unacked_packets_.HasInFlightPackets());
-      EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
-      return;
-    }
-    if (num_packets == 1) {
-      EXPECT_TRUE(unacked_packets_.HasInFlightPackets());
-      EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
-      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[0])));
-      EXPECT_TRUE(
-          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[0]))
-              .in_flight);
-    }
-    for (size_t i = 0; i < num_packets; ++i) {
-      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])));
-      EXPECT_TRUE(
-          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[i]))
-              .in_flight);
-    }
-    size_t in_flight_count = 0;
-    for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
-         ++it) {
-      if (it->in_flight) {
-        ++in_flight_count;
-      }
-    }
-    EXPECT_EQ(num_packets, in_flight_count);
-  }
-
-  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
-    unacked_packets_.RemoveObsoletePackets();
-    if (num_packets == 0) {
-      EXPECT_TRUE(unacked_packets_.empty());
-      EXPECT_FALSE(unacked_packets_.HasUnackedRetransmittableFrames());
-      return;
-    }
-    EXPECT_FALSE(unacked_packets_.empty());
-    for (size_t i = 0; i < num_packets; ++i) {
-      EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])))
-          << packets[i];
-    }
-    EXPECT_EQ(num_packets, unacked_packets_.GetNumUnackedPacketsDebugOnly());
-  }
-
-  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
-    unacked_packets_.RemoveObsoletePackets();
-    size_t num_retransmittable_packets = 0;
-    for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
-         ++it) {
-      if (unacked_packets_.HasRetransmittableFrames(*it)) {
-        ++num_retransmittable_packets;
-      }
-    }
-    EXPECT_EQ(num_packets, num_retransmittable_packets);
-    for (size_t i = 0; i < num_packets; ++i) {
-      EXPECT_TRUE(unacked_packets_.HasRetransmittableFrames(
-          QuicPacketNumber(packets[i])))
-          << " packets[" << i << "]:" << packets[i];
-    }
-  }
-
-  void UpdatePacketState(uint64_t packet_number, SentPacketState state) {
-    unacked_packets_
-        .GetMutableTransmissionInfo(QuicPacketNumber(packet_number))
-        ->state = state;
-  }
-
-  void RetransmitAndSendPacket(uint64_t old_packet_number,
-                               uint64_t new_packet_number,
-                               TransmissionType transmission_type) {
-    QUICHE_DCHECK(unacked_packets_.HasRetransmittableFrames(
-        QuicPacketNumber(old_packet_number)));
-    QuicTransmissionInfo* info = unacked_packets_.GetMutableTransmissionInfo(
-        QuicPacketNumber(old_packet_number));
-    QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
-        CurrentSupportedVersions()[0].transport_version,
-        Perspective::IS_CLIENT);
-    for (const auto& frame : info->retransmittable_frames) {
-      if (frame.type == STREAM_FRAME) {
-        stream_id = frame.stream_frame.stream_id;
-        break;
-      }
-    }
-    UpdatePacketState(
-        old_packet_number,
-        QuicUtils::RetransmissionTypeToPacketState(transmission_type));
-    info->first_sent_after_loss = QuicPacketNumber(new_packet_number);
-    SerializedPacket packet(
-        CreateRetransmittablePacketForStream(new_packet_number, stream_id));
-    unacked_packets_.AddSentPacket(&packet, transmission_type, now_, true,
-                                   true);
-  }
-  QuicUnackedPacketMap unacked_packets_;
-  QuicTime now_;
-  StrictMock<MockSessionNotifier> notifier_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicUnackedPacketMapTest,
-                         ::testing::ValuesIn({Perspective::IS_CLIENT,
-                                              Perspective::IS_SERVER}),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicUnackedPacketMapTest, RttOnly) {
-  // Acks are only tracked for RTT measurement purposes.
-  SerializedPacket packet(CreateNonRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, false,
-                                 true);
-
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(nullptr, 0);
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
-  VerifyUnackedPackets(nullptr, 0);
-  VerifyInFlightPackets(nullptr, 0);
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
-  // Simulate a retransmittable packet being sent and acked.
-  SerializedPacket packet(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
-
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(unacked, ABSL_ARRAYSIZE(unacked));
-
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
-  VerifyUnackedPackets(nullptr, 0);
-  VerifyInFlightPackets(nullptr, 0);
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, StopRetransmission) {
-  const QuicStreamId stream_id = 2;
-  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
-
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  uint64_t retransmittable[] = {1};
-  VerifyRetransmittablePackets(retransmittable,
-                               ABSL_ARRAYSIZE(retransmittable));
-
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
-  const QuicStreamId stream_id = 2;
-  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
-
-  uint64_t unacked[] = {1};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  uint64_t retransmittable[] = {1};
-  VerifyRetransmittablePackets(retransmittable,
-                               ABSL_ARRAYSIZE(retransmittable));
-
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(retransmittable,
-                               ABSL_ARRAYSIZE(retransmittable));
-}
-
-TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
-  const QuicStreamId stream_id = 2;
-  SerializedPacket packet1(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
-
-  uint64_t unacked[] = {1, 2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  std::vector<uint64_t> retransmittable = {1, 2};
-  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
-
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmittedPacket) {
-  // Simulate a retransmittable packet being sent, retransmitted, and the first
-  // transmission being acked.
-  SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
-
-  uint64_t unacked[] = {1, 2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  std::vector<uint64_t> retransmittable = {1, 2};
-  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
-
-  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  uint64_t unacked2[] = {1};
-  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
-  VerifyInFlightPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
-  VerifyRetransmittablePackets(nullptr, 0);
-
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
-  VerifyUnackedPackets(nullptr, 0);
-  VerifyInFlightPackets(nullptr, 0);
-  VerifyRetransmittablePackets(nullptr, 0);
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
-  // Simulate a retransmittable packet being sent and retransmitted twice.
-  SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  SerializedPacket packet2(CreateRetransmittablePacket(2));
-  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
-                                 true);
-
-  uint64_t unacked[] = {1, 2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  uint64_t retransmittable[] = {1, 2};
-  VerifyRetransmittablePackets(retransmittable,
-                               ABSL_ARRAYSIZE(retransmittable));
-
-  // Early retransmit 1 as 3 and send new data as 4.
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
-  RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
-  SerializedPacket packet4(CreateRetransmittablePacket(4));
-  unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
-                                 true);
-
-  uint64_t unacked2[] = {1, 3, 4};
-  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
-  uint64_t pending2[] = {3, 4};
-  VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
-  std::vector<uint64_t> retransmittable2 = {1, 3, 4};
-  VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
-
-  // Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked.
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(4));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(4));
-  RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
-  SerializedPacket packet6(CreateRetransmittablePacket(6));
-  unacked_packets_.AddSentPacket(&packet6, NOT_RETRANSMISSION, now_, true,
-                                 true);
-
-  std::vector<uint64_t> unacked3 = {3, 5, 6};
-  std::vector<uint64_t> retransmittable3 = {3, 5, 6};
-  VerifyUnackedPackets(&unacked3[0], unacked3.size());
-  VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
-  uint64_t pending3[] = {3, 5, 6};
-  VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
-
-  // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed.
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(6));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(6));
-  RetransmitAndSendPacket(5, 7, LOSS_RETRANSMISSION);
-
-  std::vector<uint64_t> unacked4 = {3, 5, 7};
-  std::vector<uint64_t> retransmittable4 = {3, 5, 7};
-  VerifyUnackedPackets(&unacked4[0], unacked4.size());
-  VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
-  uint64_t pending4[] = {3, 5, 7};
-  VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
-
-  // Remove the older two transmissions from in flight.
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
-  uint64_t pending5[] = {7};
-  VerifyInFlightPackets(pending5, ABSL_ARRAYSIZE(pending5));
-}
-
-TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) {
-  // Simulate a retransmittable packet being sent and retransmitted twice.
-  SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  SerializedPacket packet2(CreateRetransmittablePacket(2));
-  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
-                                 true);
-
-  uint64_t unacked[] = {1, 2};
-  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
-  uint64_t retransmittable[] = {1, 2};
-  VerifyRetransmittablePackets(retransmittable,
-                               ABSL_ARRAYSIZE(retransmittable));
-
-  // Early retransmit 1 as 3.
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
-  RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
-
-  uint64_t unacked2[] = {1, 3};
-  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
-  uint64_t pending2[] = {3};
-  VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
-  std::vector<uint64_t> retransmittable2 = {1, 3};
-  VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
-
-  // TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
-  RetransmitAndSendPacket(3, 4, TLP_RETRANSMISSION);
-  SerializedPacket packet5(CreateRetransmittablePacket(5));
-  unacked_packets_.AddSentPacket(&packet5, NOT_RETRANSMISSION, now_, true,
-                                 true);
-
-  uint64_t unacked3[] = {1, 3, 4, 5};
-  VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
-  uint64_t pending3[] = {3, 4, 5};
-  VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
-  std::vector<uint64_t> retransmittable3 = {1, 3, 4, 5};
-  VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
-
-  // Early retransmit 4 as 6 and ensure in flight packet 3 is removed.
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(5));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
-  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(5));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
-  RetransmitAndSendPacket(4, 6, LOSS_RETRANSMISSION);
-
-  std::vector<uint64_t> unacked4 = {4, 6};
-  VerifyUnackedPackets(&unacked4[0], unacked4.size());
-  uint64_t pending4[] = {6};
-  VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
-  std::vector<uint64_t> retransmittable4 = {4, 6};
-  VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
-}
-
-TEST_P(QuicUnackedPacketMapTest, SendWithGap) {
-  // Simulate a retransmittable packet being sent, retransmitted, and the first
-  // transmission being acked.
-  SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  SerializedPacket packet3(CreateRetransmittablePacket(3));
-  unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
-
-  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.GetLeastUnacked());
-  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(1)));
-  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(2)));
-  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(3)));
-  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(4)));
-  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(5)));
-  EXPECT_EQ(QuicPacketNumber(5u), unacked_packets_.largest_sent_packet());
-}
-
-TEST_P(QuicUnackedPacketMapTest, AggregateContiguousAckedStreamFrames) {
-  testing::InSequence s;
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
-  unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
-
-  QuicTransmissionInfo info1;
-  QuicStreamFrame stream_frame1(3, false, 0, 100);
-  info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
-
-  QuicTransmissionInfo info2;
-  QuicStreamFrame stream_frame2(3, false, 100, 100);
-  info2.retransmittable_frames.push_back(QuicFrame(stream_frame2));
-
-  QuicTransmissionInfo info3;
-  QuicStreamFrame stream_frame3(3, false, 200, 100);
-  info3.retransmittable_frames.push_back(QuicFrame(stream_frame3));
-
-  QuicTransmissionInfo info4;
-  QuicStreamFrame stream_frame4(3, true, 300, 0);
-  info4.retransmittable_frames.push_back(QuicFrame(stream_frame4));
-
-  // Verify stream frames are aggregated.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
-  unacked_packets_.MaybeAggregateAckedStreamFrame(
-      info1, QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
-  unacked_packets_.MaybeAggregateAckedStreamFrame(
-      info2, QuicTime::Delta::Zero(), QuicTime::Zero());
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
-  unacked_packets_.MaybeAggregateAckedStreamFrame(
-      info3, QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  // Verify aggregated stream frame gets acked since fin is acked.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
-  unacked_packets_.MaybeAggregateAckedStreamFrame(
-      info4, QuicTime::Delta::Zero(), QuicTime::Zero());
-}
-
-// Regression test for b/112930090.
-TEST_P(QuicUnackedPacketMapTest, CannotAggregateIfDataLengthOverflow) {
-  QuicByteCount kMaxAggregatedDataLength =
-      std::numeric_limits<decltype(QuicStreamFrame().data_length)>::max();
-  QuicStreamId stream_id = 2;
-
-  // acked_stream_length=512 covers the case where a frame will cause the
-  // aggregated frame length to be exactly 64K.
-  // acked_stream_length=1300 covers the case where a frame will cause the
-  // aggregated frame length to exceed 64K.
-  for (const QuicPacketLength acked_stream_length : {512, 1300}) {
-    ++stream_id;
-    QuicStreamOffset offset = 0;
-    // Expected length of the aggregated stream frame.
-    QuicByteCount aggregated_data_length = 0;
-
-    while (offset < 1e6) {
-      QuicTransmissionInfo info;
-      QuicStreamFrame stream_frame(stream_id, false, offset,
-                                   acked_stream_length);
-      info.retransmittable_frames.push_back(QuicFrame(stream_frame));
-
-      const QuicStreamFrame& aggregated_stream_frame =
-          QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(unacked_packets_);
-      if (aggregated_stream_frame.data_length + acked_stream_length <=
-          kMaxAggregatedDataLength) {
-        // Verify the acked stream frame can be aggregated.
-        EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
-        unacked_packets_.MaybeAggregateAckedStreamFrame(
-            info, QuicTime::Delta::Zero(), QuicTime::Zero());
-        aggregated_data_length += acked_stream_length;
-        testing::Mock::VerifyAndClearExpectations(&notifier_);
-      } else {
-        // Verify the acked stream frame cannot be aggregated because
-        // data_length is overflow.
-        EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
-        unacked_packets_.MaybeAggregateAckedStreamFrame(
-            info, QuicTime::Delta::Zero(), QuicTime::Zero());
-        aggregated_data_length = acked_stream_length;
-        testing::Mock::VerifyAndClearExpectations(&notifier_);
-      }
-
-      EXPECT_EQ(aggregated_data_length, aggregated_stream_frame.data_length);
-      offset += acked_stream_length;
-    }
-
-    // Ack the last frame of the stream.
-    QuicTransmissionInfo info;
-    QuicStreamFrame stream_frame(stream_id, true, offset, acked_stream_length);
-    info.retransmittable_frames.push_back(QuicFrame(stream_frame));
-    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
-    unacked_packets_.MaybeAggregateAckedStreamFrame(
-        info, QuicTime::Delta::Zero(), QuicTime::Zero());
-    testing::Mock::VerifyAndClearExpectations(&notifier_);
-  }
-}
-
-TEST_P(QuicUnackedPacketMapTest, CannotAggregateAckedControlFrames) {
-  testing::InSequence s;
-  QuicWindowUpdateFrame window_update(1, 5, 100);
-  QuicStreamFrame stream_frame1(3, false, 0, 100);
-  QuicStreamFrame stream_frame2(3, false, 100, 100);
-  QuicBlockedFrame blocked(2, 5);
-  QuicGoAwayFrame go_away(3, QUIC_PEER_GOING_AWAY, 5, "Going away.");
-
-  QuicTransmissionInfo info1;
-  info1.retransmittable_frames.push_back(QuicFrame(window_update));
-  info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
-  info1.retransmittable_frames.push_back(QuicFrame(stream_frame2));
-
-  QuicTransmissionInfo info2;
-  info2.retransmittable_frames.push_back(QuicFrame(blocked));
-  info2.retransmittable_frames.push_back(QuicFrame(&go_away));
-
-  // Verify 2 contiguous stream frames are aggregated.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
-  unacked_packets_.MaybeAggregateAckedStreamFrame(
-      info1, QuicTime::Delta::Zero(), QuicTime::Zero());
-  // Verify aggregated stream frame gets acked.
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(3);
-  unacked_packets_.MaybeAggregateAckedStreamFrame(
-      info2, QuicTime::Delta::Zero(), QuicTime::Zero());
-
-  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
-  unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
-}
-
-TEST_P(QuicUnackedPacketMapTest, LargestSentPacketMultiplePacketNumberSpaces) {
-  unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
-  EXPECT_FALSE(
-      unacked_packets_
-          .GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
-          .IsInitialized());
-  // Send packet 1.
-  SerializedPacket packet1(CreateRetransmittablePacket(1));
-  packet1.encryption_level = ENCRYPTION_INITIAL;
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.largest_sent_packet());
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_FALSE(
-      unacked_packets_
-          .GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
-          .IsInitialized());
-  // Send packet 2.
-  SerializedPacket packet2(CreateRetransmittablePacket(2));
-  packet2.encryption_level = ENCRYPTION_HANDSHAKE;
-  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  EXPECT_EQ(QuicPacketNumber(2u), unacked_packets_.largest_sent_packet());
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_EQ(QuicPacketNumber(2),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                HANDSHAKE_DATA));
-  EXPECT_FALSE(
-      unacked_packets_
-          .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
-          .IsInitialized());
-  // Send packet 3.
-  SerializedPacket packet3(CreateRetransmittablePacket(3));
-  packet3.encryption_level = ENCRYPTION_ZERO_RTT;
-  unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  EXPECT_EQ(QuicPacketNumber(3u), unacked_packets_.largest_sent_packet());
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_EQ(QuicPacketNumber(2),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                HANDSHAKE_DATA));
-  EXPECT_EQ(QuicPacketNumber(3),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                APPLICATION_DATA));
-  // Verify forward secure belongs to the same packet number space as encryption
-  // zero rtt.
-  EXPECT_EQ(QuicPacketNumber(3),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                APPLICATION_DATA));
-
-  // Send packet 4.
-  SerializedPacket packet4(CreateRetransmittablePacket(4));
-  packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
-  unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  EXPECT_EQ(QuicPacketNumber(4u), unacked_packets_.largest_sent_packet());
-  EXPECT_EQ(QuicPacketNumber(1),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                INITIAL_DATA));
-  EXPECT_EQ(QuicPacketNumber(2),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                HANDSHAKE_DATA));
-  EXPECT_EQ(QuicPacketNumber(4),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                APPLICATION_DATA));
-  // Verify forward secure belongs to the same packet number space as encryption
-  // zero rtt.
-  EXPECT_EQ(QuicPacketNumber(4),
-            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
-                APPLICATION_DATA));
-  EXPECT_TRUE(unacked_packets_.GetLastPacketContent() & (1 << STREAM_FRAME));
-  EXPECT_FALSE(unacked_packets_.GetLastPacketContent() & (1 << ACK_FRAME));
-}
-
-TEST_P(QuicUnackedPacketMapTest, ReserveInitialCapacityTest) {
-  QuicUnackedPacketMap unacked_packets(GetParam());
-  ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 0u);
-  unacked_packets.ReserveInitialCapacity(16);
-  QuicStreamId stream_id(1);
-  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets.AddSentPacket(&packet, TransmissionType::NOT_RETRANSMISSION,
-                                now_, true, true);
-  ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 16u);
-}
-
-TEST_P(QuicUnackedPacketMapTest, DebugString) {
-  EXPECT_EQ(unacked_packets_.DebugString(),
-            "{size: 0, least_unacked: 1, largest_sent_packet: uninitialized, "
-            "largest_acked: uninitialized, bytes_in_flight: 0, "
-            "packets_in_flight: 0}");
-
-  SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  EXPECT_EQ(
-      unacked_packets_.DebugString(),
-      "{size: 1, least_unacked: 1, largest_sent_packet: 1, largest_acked: "
-      "uninitialized, bytes_in_flight: 1000, packets_in_flight: 1}");
-
-  SerializedPacket packet2(CreateRetransmittablePacket(2));
-  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
-                                 true);
-  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
-  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
-  unacked_packets_.RemoveObsoletePackets();
-  EXPECT_EQ(
-      unacked_packets_.DebugString(),
-      "{size: 1, least_unacked: 2, largest_sent_packet: 2, largest_acked: 1, "
-      "bytes_in_flight: 1000, packets_in_flight: 1}");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc
deleted file mode 100644
index 94d35eb..0000000
--- a/quic/core/quic_utils.cc
+++ /dev/null
@@ -1,690 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_utils.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <limits>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/base/optimization.h"
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace {
-
-// We know that >= GCC 4.8 and Clang have a __uint128_t intrinsic. Other
-// compilers don't necessarily, notably MSVC.
-#if defined(__x86_64__) &&                                         \
-    ((defined(__GNUC__) &&                                         \
-      (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
-     defined(__clang__))
-#define QUIC_UTIL_HAS_UINT128 1
-#endif
-
-#ifdef QUIC_UTIL_HAS_UINT128
-absl::uint128 IncrementalHashFast(absl::uint128 uhash, absl::string_view data) {
-  // This code ends up faster than the naive implementation for 2 reasons:
-  // 1. absl::uint128 is sufficiently complicated that the compiler
-  //    cannot transform the multiplication by kPrime into a shift-multiply-add;
-  //    it has go through all of the instructions for a 128-bit multiply.
-  // 2. Because there are so fewer instructions (around 13), the hot loop fits
-  //    nicely in the instruction queue of many Intel CPUs.
-  // kPrime = 309485009821345068724781371
-  static const absl::uint128 kPrime =
-      (static_cast<absl::uint128>(16777216) << 64) + 315;
-  auto hi = absl::Uint128High64(uhash);
-  auto lo = absl::Uint128Low64(uhash);
-  absl::uint128 xhash = (static_cast<absl::uint128>(hi) << 64) + lo;
-  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
-  for (size_t i = 0; i < data.length(); ++i) {
-    xhash = (xhash ^ static_cast<uint32_t>(octets[i])) * kPrime;
-  }
-  return absl::MakeUint128(absl::Uint128High64(xhash),
-                           absl::Uint128Low64(xhash));
-}
-#endif
-
-#ifndef QUIC_UTIL_HAS_UINT128
-// Slow implementation of IncrementalHash. In practice, only used by Chromium.
-absl::uint128 IncrementalHashSlow(absl::uint128 hash, absl::string_view data) {
-  // kPrime = 309485009821345068724781371
-  static const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
-  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
-  for (size_t i = 0; i < data.length(); ++i) {
-    hash = hash ^ absl::MakeUint128(0, octets[i]);
-    hash = hash * kPrime;
-  }
-  return hash;
-}
-#endif
-
-absl::uint128 IncrementalHash(absl::uint128 hash, absl::string_view data) {
-#ifdef QUIC_UTIL_HAS_UINT128
-  return IncrementalHashFast(hash, data);
-#else
-  return IncrementalHashSlow(hash, data);
-#endif
-}
-
-}  // namespace
-
-// static
-uint64_t QuicUtils::FNV1a_64_Hash(absl::string_view data) {
-  static const uint64_t kOffset = UINT64_C(14695981039346656037);
-  static const uint64_t kPrime = UINT64_C(1099511628211);
-
-  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
-
-  uint64_t hash = kOffset;
-
-  for (size_t i = 0; i < data.length(); ++i) {
-    hash = hash ^ octets[i];
-    hash = hash * kPrime;
-  }
-
-  return hash;
-}
-
-// static
-absl::uint128 QuicUtils::FNV1a_128_Hash(absl::string_view data) {
-  return FNV1a_128_Hash_Three(data, absl::string_view(), absl::string_view());
-}
-
-// static
-absl::uint128 QuicUtils::FNV1a_128_Hash_Two(absl::string_view data1,
-                                            absl::string_view data2) {
-  return FNV1a_128_Hash_Three(data1, data2, absl::string_view());
-}
-
-// static
-absl::uint128 QuicUtils::FNV1a_128_Hash_Three(absl::string_view data1,
-                                              absl::string_view data2,
-                                              absl::string_view data3) {
-  // The two constants are defined as part of the hash algorithm.
-  // see http://www.isthe.com/chongo/tech/comp/fnv/
-  // kOffset = 144066263297769815596495629667062367629
-  const absl::uint128 kOffset = absl::MakeUint128(
-      UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
-
-  absl::uint128 hash = IncrementalHash(kOffset, data1);
-  if (data2.empty()) {
-    return hash;
-  }
-
-  hash = IncrementalHash(hash, data2);
-  if (data3.empty()) {
-    return hash;
-  }
-  return IncrementalHash(hash, data3);
-}
-
-// static
-void QuicUtils::SerializeUint128Short(absl::uint128 v, uint8_t* out) {
-  const uint64_t lo = absl::Uint128Low64(v);
-  const uint64_t hi = absl::Uint128High64(v);
-  // This assumes that the system is little-endian.
-  memcpy(out, &lo, sizeof(lo));
-  memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
-}
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x;
-
-std::string QuicUtils::AddressChangeTypeToString(AddressChangeType type) {
-  switch (type) {
-    RETURN_STRING_LITERAL(NO_CHANGE);
-    RETURN_STRING_LITERAL(PORT_CHANGE);
-    RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
-    RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
-    RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
-    RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
-    RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
-  }
-  return "INVALID_ADDRESS_CHANGE_TYPE";
-}
-
-const char* QuicUtils::SentPacketStateToString(SentPacketState state) {
-  switch (state) {
-    RETURN_STRING_LITERAL(OUTSTANDING);
-    RETURN_STRING_LITERAL(NEVER_SENT);
-    RETURN_STRING_LITERAL(ACKED);
-    RETURN_STRING_LITERAL(UNACKABLE);
-    RETURN_STRING_LITERAL(NEUTERED);
-    RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMITTED);
-    RETURN_STRING_LITERAL(LOST);
-    RETURN_STRING_LITERAL(TLP_RETRANSMITTED);
-    RETURN_STRING_LITERAL(RTO_RETRANSMITTED);
-    RETURN_STRING_LITERAL(PTO_RETRANSMITTED);
-    RETURN_STRING_LITERAL(PROBE_RETRANSMITTED);
-    RETURN_STRING_LITERAL(NOT_CONTRIBUTING_RTT);
-  }
-  return "INVALID_SENT_PACKET_STATE";
-}
-
-// static
-const char* QuicUtils::QuicLongHeaderTypetoString(QuicLongHeaderType type) {
-  switch (type) {
-    RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
-    RETURN_STRING_LITERAL(INITIAL);
-    RETURN_STRING_LITERAL(RETRY);
-    RETURN_STRING_LITERAL(HANDSHAKE);
-    RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
-    default:
-      return "INVALID_PACKET_TYPE";
-  }
-}
-
-// static
-const char* QuicUtils::AckResultToString(AckResult result) {
-  switch (result) {
-    RETURN_STRING_LITERAL(PACKETS_NEWLY_ACKED);
-    RETURN_STRING_LITERAL(NO_PACKETS_NEWLY_ACKED);
-    RETURN_STRING_LITERAL(UNSENT_PACKETS_ACKED);
-    RETURN_STRING_LITERAL(UNACKABLE_PACKETS_ACKED);
-    RETURN_STRING_LITERAL(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE);
-  }
-  return "INVALID_ACK_RESULT";
-}
-
-// static
-AddressChangeType QuicUtils::DetermineAddressChangeType(
-    const QuicSocketAddress& old_address,
-    const QuicSocketAddress& new_address) {
-  if (!old_address.IsInitialized() || !new_address.IsInitialized() ||
-      old_address == new_address) {
-    return NO_CHANGE;
-  }
-
-  if (old_address.host() == new_address.host()) {
-    return PORT_CHANGE;
-  }
-
-  bool old_ip_is_ipv4 = old_address.host().IsIPv4() ? true : false;
-  bool migrating_ip_is_ipv4 = new_address.host().IsIPv4() ? true : false;
-  if (old_ip_is_ipv4 && !migrating_ip_is_ipv4) {
-    return IPV4_TO_IPV6_CHANGE;
-  }
-
-  if (!old_ip_is_ipv4) {
-    return migrating_ip_is_ipv4 ? IPV6_TO_IPV4_CHANGE : IPV6_TO_IPV6_CHANGE;
-  }
-
-  const int kSubnetMaskLength = 24;
-  if (old_address.host().InSameSubnet(new_address.host(), kSubnetMaskLength)) {
-    // Subnet part does not change (here, we use /24), which is considered to be
-    // caused by NATs.
-    return IPV4_SUBNET_CHANGE;
-  }
-
-  return IPV4_TO_IPV4_CHANGE;
-}
-
-// static
-bool QuicUtils::IsAckable(SentPacketState state) {
-  return state != NEVER_SENT && state != ACKED && state != UNACKABLE;
-}
-
-// static
-bool QuicUtils::IsRetransmittableFrame(QuicFrameType type) {
-  switch (type) {
-    case ACK_FRAME:
-    case PADDING_FRAME:
-    case STOP_WAITING_FRAME:
-    case MTU_DISCOVERY_FRAME:
-    case PATH_CHALLENGE_FRAME:
-    case PATH_RESPONSE_FRAME:
-      return false;
-    default:
-      return true;
-  }
-}
-
-// static
-bool QuicUtils::IsHandshakeFrame(const QuicFrame& frame,
-                                 QuicTransportVersion transport_version) {
-  if (!QuicVersionUsesCryptoFrames(transport_version)) {
-    return frame.type == STREAM_FRAME &&
-           frame.stream_frame.stream_id == GetCryptoStreamId(transport_version);
-  } else {
-    return frame.type == CRYPTO_FRAME;
-  }
-}
-
-// static
-bool QuicUtils::ContainsFrameType(const QuicFrames& frames,
-                                  QuicFrameType type) {
-  for (const QuicFrame& frame : frames) {
-    if (frame.type == type) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// static
-SentPacketState QuicUtils::RetransmissionTypeToPacketState(
-    TransmissionType retransmission_type) {
-  switch (retransmission_type) {
-    case ALL_ZERO_RTT_RETRANSMISSION:
-      return UNACKABLE;
-    case HANDSHAKE_RETRANSMISSION:
-      return HANDSHAKE_RETRANSMITTED;
-    case LOSS_RETRANSMISSION:
-      return LOST;
-    case TLP_RETRANSMISSION:
-      return TLP_RETRANSMITTED;
-    case RTO_RETRANSMISSION:
-      return RTO_RETRANSMITTED;
-    case PTO_RETRANSMISSION:
-      return PTO_RETRANSMITTED;
-    case PROBING_RETRANSMISSION:
-      return PROBE_RETRANSMITTED;
-    case PATH_RETRANSMISSION:
-      return NOT_CONTRIBUTING_RTT;
-    case ALL_INITIAL_RETRANSMISSION:
-      return UNACKABLE;
-    default:
-      QUIC_BUG(quic_bug_10839_2)
-          << retransmission_type << " is not a retransmission_type";
-      return UNACKABLE;
-  }
-}
-
-// static
-bool QuicUtils::IsIetfPacketHeader(uint8_t first_byte) {
-  return (first_byte & FLAGS_LONG_HEADER) || (first_byte & FLAGS_FIXED_BIT) ||
-         !(first_byte & FLAGS_DEMULTIPLEXING_BIT);
-}
-
-// static
-bool QuicUtils::IsIetfPacketShortHeader(uint8_t first_byte) {
-  return IsIetfPacketHeader(first_byte) && !(first_byte & FLAGS_LONG_HEADER);
-}
-
-// static
-QuicStreamId QuicUtils::GetInvalidStreamId(QuicTransportVersion version) {
-  return VersionHasIetfQuicFrames(version)
-             ? std::numeric_limits<QuicStreamId>::max()
-             : 0;
-}
-
-// static
-QuicStreamId QuicUtils::GetCryptoStreamId(QuicTransportVersion version) {
-  QUIC_BUG_IF(quic_bug_12982_1, QuicVersionUsesCryptoFrames(version))
-      << "CRYPTO data aren't in stream frames; they have no stream ID.";
-  return QuicVersionUsesCryptoFrames(version) ? GetInvalidStreamId(version) : 1;
-}
-
-// static
-bool QuicUtils::IsCryptoStreamId(QuicTransportVersion version,
-                                 QuicStreamId stream_id) {
-  if (QuicVersionUsesCryptoFrames(version)) {
-    return false;
-  }
-  return stream_id == GetCryptoStreamId(version);
-}
-
-// static
-QuicStreamId QuicUtils::GetHeadersStreamId(QuicTransportVersion version) {
-  QUICHE_DCHECK(!VersionUsesHttp3(version));
-  return GetFirstBidirectionalStreamId(version, Perspective::IS_CLIENT);
-}
-
-// static
-bool QuicUtils::IsClientInitiatedStreamId(QuicTransportVersion version,
-                                          QuicStreamId id) {
-  if (id == GetInvalidStreamId(version)) {
-    return false;
-  }
-  return VersionHasIetfQuicFrames(version) ? id % 2 == 0 : id % 2 != 0;
-}
-
-// static
-bool QuicUtils::IsServerInitiatedStreamId(QuicTransportVersion version,
-                                          QuicStreamId id) {
-  if (id == GetInvalidStreamId(version)) {
-    return false;
-  }
-  return VersionHasIetfQuicFrames(version) ? id % 2 != 0 : id % 2 == 0;
-}
-
-// static
-bool QuicUtils::IsOutgoingStreamId(ParsedQuicVersion version,
-                                   QuicStreamId id,
-                                   Perspective perspective) {
-  // Streams are outgoing streams, iff:
-  // - we are the server and the stream is server-initiated
-  // - we are the client and the stream is client-initiated.
-  const bool perspective_is_server = perspective == Perspective::IS_SERVER;
-  const bool stream_is_server =
-      QuicUtils::IsServerInitiatedStreamId(version.transport_version, id);
-  return perspective_is_server == stream_is_server;
-}
-
-// static
-bool QuicUtils::IsBidirectionalStreamId(QuicStreamId id,
-                                        ParsedQuicVersion version) {
-  QUICHE_DCHECK(version.HasIetfQuicFrames());
-  return id % 4 < 2;
-}
-
-// static
-StreamType QuicUtils::GetStreamType(QuicStreamId id,
-                                    Perspective perspective,
-                                    bool peer_initiated,
-                                    ParsedQuicVersion version) {
-  QUICHE_DCHECK(version.HasIetfQuicFrames());
-  if (IsBidirectionalStreamId(id, version)) {
-    return BIDIRECTIONAL;
-  }
-
-  if (peer_initiated) {
-    if (perspective == Perspective::IS_SERVER) {
-      QUICHE_DCHECK_EQ(2u, id % 4);
-    } else {
-      QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
-      QUICHE_DCHECK_EQ(3u, id % 4);
-    }
-    return READ_UNIDIRECTIONAL;
-  }
-
-  if (perspective == Perspective::IS_SERVER) {
-    QUICHE_DCHECK_EQ(3u, id % 4);
-  } else {
-    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
-    QUICHE_DCHECK_EQ(2u, id % 4);
-  }
-  return WRITE_UNIDIRECTIONAL;
-}
-
-// static
-QuicStreamId QuicUtils::StreamIdDelta(QuicTransportVersion version) {
-  return VersionHasIetfQuicFrames(version) ? 4 : 2;
-}
-
-// static
-QuicStreamId QuicUtils::GetFirstBidirectionalStreamId(
-    QuicTransportVersion version,
-    Perspective perspective) {
-  if (VersionHasIetfQuicFrames(version)) {
-    return perspective == Perspective::IS_CLIENT ? 0 : 1;
-  } else if (QuicVersionUsesCryptoFrames(version)) {
-    return perspective == Perspective::IS_CLIENT ? 1 : 2;
-  }
-  return perspective == Perspective::IS_CLIENT ? 3 : 2;
-}
-
-// static
-QuicStreamId QuicUtils::GetFirstUnidirectionalStreamId(
-    QuicTransportVersion version,
-    Perspective perspective) {
-  if (VersionHasIetfQuicFrames(version)) {
-    return perspective == Perspective::IS_CLIENT ? 2 : 3;
-  } else if (QuicVersionUsesCryptoFrames(version)) {
-    return perspective == Perspective::IS_CLIENT ? 1 : 2;
-  }
-  return perspective == Perspective::IS_CLIENT ? 3 : 2;
-}
-
-// static
-QuicStreamId QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
-    QuicTransportVersion version) {
-  if (VersionHasIetfQuicFrames(version)) {
-    // Client initiated bidirectional streams have stream IDs divisible by 4.
-    return std::numeric_limits<QuicStreamId>::max() - 3;
-  }
-
-  // Client initiated bidirectional streams have odd stream IDs.
-  return std::numeric_limits<QuicStreamId>::max();
-}
-
-// static
-QuicConnectionId QuicUtils::CreateReplacementConnectionId(
-    const QuicConnectionId& connection_id) {
-  return CreateReplacementConnectionId(connection_id,
-                                       kQuicDefaultConnectionIdLength);
-}
-
-// static
-QuicConnectionId QuicUtils::CreateReplacementConnectionId(
-    const QuicConnectionId& connection_id,
-    uint8_t expected_connection_id_length) {
-  if (expected_connection_id_length == 0) {
-    return EmptyQuicConnectionId();
-  }
-  const uint64_t connection_id_hash64 = FNV1a_64_Hash(
-      absl::string_view(connection_id.data(), connection_id.length()));
-  if (expected_connection_id_length <= sizeof(uint64_t)) {
-    return QuicConnectionId(
-        reinterpret_cast<const char*>(&connection_id_hash64),
-        expected_connection_id_length);
-  }
-  char new_connection_id_data[255] = {};
-  const absl::uint128 connection_id_hash128 = FNV1a_128_Hash(
-      absl::string_view(connection_id.data(), connection_id.length()));
-  static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <=
-                    sizeof(new_connection_id_data),
-                "bad size");
-  memcpy(new_connection_id_data, &connection_id_hash64,
-         sizeof(connection_id_hash64));
-  memcpy(new_connection_id_data + sizeof(connection_id_hash64),
-         &connection_id_hash128, sizeof(connection_id_hash128));
-  return QuicConnectionId(new_connection_id_data,
-                          expected_connection_id_length);
-}
-
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId() {
-  return CreateRandomConnectionId(kQuicDefaultConnectionIdLength,
-                                  QuicRandom::GetInstance());
-}
-
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId(QuicRandom* random) {
-  return CreateRandomConnectionId(kQuicDefaultConnectionIdLength, random);
-}
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId(
-    uint8_t connection_id_length) {
-  return CreateRandomConnectionId(connection_id_length,
-                                  QuicRandom::GetInstance());
-}
-
-// static
-QuicConnectionId QuicUtils::CreateRandomConnectionId(
-    uint8_t connection_id_length,
-    QuicRandom* random) {
-  QuicConnectionId connection_id;
-  connection_id.set_length(connection_id_length);
-  if (connection_id.length() > 0) {
-    random->RandBytes(connection_id.mutable_data(), connection_id.length());
-  }
-  return connection_id;
-}
-
-// static
-QuicConnectionId QuicUtils::CreateZeroConnectionId(
-    QuicTransportVersion version) {
-  if (!VersionAllowsVariableLengthConnectionIds(version)) {
-    char connection_id_bytes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-    return QuicConnectionId(static_cast<char*>(connection_id_bytes),
-                            ABSL_ARRAYSIZE(connection_id_bytes));
-  }
-  return EmptyQuicConnectionId();
-}
-
-// static
-bool QuicUtils::IsConnectionIdLengthValidForVersion(
-    size_t connection_id_length,
-    QuicTransportVersion transport_version) {
-  // No version of QUIC can support lengths that do not fit in an uint8_t.
-  if (connection_id_length >
-      static_cast<size_t>(std::numeric_limits<uint8_t>::max())) {
-    return false;
-  }
-
-  if (transport_version == QUIC_VERSION_UNSUPPORTED ||
-      transport_version == QUIC_VERSION_RESERVED_FOR_NEGOTIATION) {
-    // Unknown versions could allow connection ID lengths up to 255.
-    return true;
-  }
-
-  const uint8_t connection_id_length8 =
-      static_cast<uint8_t>(connection_id_length);
-  // Versions that do not support variable lengths only support length 8.
-  if (!VersionAllowsVariableLengthConnectionIds(transport_version)) {
-    return connection_id_length8 == kQuicDefaultConnectionIdLength;
-  }
-  // Versions that do support variable length but do not have length-prefixed
-  // connection IDs use the 4-bit connection ID length encoding which can
-  // only encode values 0 and 4-18.
-  if (!VersionHasLengthPrefixedConnectionIds(transport_version)) {
-    return connection_id_length8 == 0 ||
-           (connection_id_length8 >= 4 &&
-            connection_id_length8 <= kQuicMaxConnectionId4BitLength);
-  }
-  return connection_id_length8 <= kQuicMaxConnectionIdWithLengthPrefixLength;
-}
-
-// static
-bool QuicUtils::IsConnectionIdValidForVersion(
-    QuicConnectionId connection_id,
-    QuicTransportVersion transport_version) {
-  return IsConnectionIdLengthValidForVersion(connection_id.length(),
-                                             transport_version);
-}
-
-StatelessResetToken QuicUtils::GenerateStatelessResetToken(
-    QuicConnectionId connection_id) {
-  static_assert(sizeof(absl::uint128) == sizeof(StatelessResetToken),
-                "bad size");
-  static_assert(alignof(absl::uint128) >= alignof(StatelessResetToken),
-                "bad alignment");
-  absl::uint128 hash = FNV1a_128_Hash(
-      absl::string_view(connection_id.data(), connection_id.length()));
-  return *reinterpret_cast<StatelessResetToken*>(&hash);
-}
-
-// static
-QuicStreamCount QuicUtils::GetMaxStreamCount() {
-  return (kMaxQuicStreamCount >> 2) + 1;
-}
-
-// static
-PacketNumberSpace QuicUtils::GetPacketNumberSpace(
-    EncryptionLevel encryption_level) {
-  switch (encryption_level) {
-    case ENCRYPTION_INITIAL:
-      return INITIAL_DATA;
-    case ENCRYPTION_HANDSHAKE:
-      return HANDSHAKE_DATA;
-    case ENCRYPTION_ZERO_RTT:
-    case ENCRYPTION_FORWARD_SECURE:
-      return APPLICATION_DATA;
-    default:
-      QUIC_BUG(quic_bug_10839_3)
-          << "Try to get packet number space of encryption level: "
-          << encryption_level;
-      return NUM_PACKET_NUMBER_SPACES;
-  }
-}
-
-// static
-EncryptionLevel QuicUtils::GetEncryptionLevel(
-    PacketNumberSpace packet_number_space) {
-  switch (packet_number_space) {
-    case INITIAL_DATA:
-      return ENCRYPTION_INITIAL;
-    case HANDSHAKE_DATA:
-      return ENCRYPTION_HANDSHAKE;
-    case APPLICATION_DATA:
-      return ENCRYPTION_FORWARD_SECURE;
-    default:
-      QUICHE_DCHECK(false);
-      return NUM_ENCRYPTION_LEVELS;
-  }
-}
-
-// static
-bool QuicUtils::IsProbingFrame(QuicFrameType type) {
-  switch (type) {
-    case PATH_CHALLENGE_FRAME:
-    case PATH_RESPONSE_FRAME:
-    case NEW_CONNECTION_ID_FRAME:
-    case PADDING_FRAME:
-      return true;
-    default:
-      return false;
-  }
-}
-
-// static
-bool QuicUtils::IsAckElicitingFrame(QuicFrameType type) {
-  switch (type) {
-    case PADDING_FRAME:
-    case STOP_WAITING_FRAME:
-    case ACK_FRAME:
-    case CONNECTION_CLOSE_FRAME:
-      return false;
-    default:
-      return true;
-  }
-}
-
-// static
-bool QuicUtils::AreStatelessResetTokensEqual(
-    const StatelessResetToken& token1,
-    const StatelessResetToken& token2) {
-  char byte = 0;
-  for (size_t i = 0; i < kStatelessResetTokenLength; i++) {
-    // This avoids compiler optimizations that could make us stop comparing
-    // after we find a byte that doesn't match.
-    byte |= (token1[i] ^ token2[i]);
-  }
-  return byte == 0;
-}
-
-bool IsValidWebTransportSessionId(WebTransportSessionId id,
-                                  ParsedQuicVersion version) {
-  QUICHE_DCHECK(version.UsesHttp3());
-  return (id <= std::numeric_limits<QuicStreamId>::max()) &&
-         QuicUtils::IsBidirectionalStreamId(id, version) &&
-         QuicUtils::IsClientInitiatedStreamId(version.transport_version, id);
-}
-
-QuicByteCount MemSliceSpanTotalSize(absl::Span<quiche::QuicheMemSlice> span) {
-  QuicByteCount total = 0;
-  for (const quiche::QuicheMemSlice& slice : span) {
-    total += slice.length();
-  }
-  return total;
-}
-
-std::string RawSha256(absl::string_view input) {
-  std::string raw_hash;
-  raw_hash.resize(SHA256_DIGEST_LENGTH);
-  SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(),
-         reinterpret_cast<uint8_t*>(&raw_hash[0]));
-  return raw_hash;
-}
-
-#undef RETURN_STRING_LITERAL  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_utils.h b/quic/core/quic_utils.h
deleted file mode 100644
index ea03236..0000000
--- a/quic/core/quic_utils.h
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_UTILS_H_
-#define QUICHE_QUIC_CORE_QUIC_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <sstream>
-#include <string>
-#include <type_traits>
-
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QuicUtils {
- public:
-  QuicUtils() = delete;
-
-  // Returns the 64 bit FNV1a hash of the data.  See
-  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
-  static uint64_t FNV1a_64_Hash(absl::string_view data);
-
-  // Returns the 128 bit FNV1a hash of the data.  See
-  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
-  static absl::uint128 FNV1a_128_Hash(absl::string_view data);
-
-  // Returns the 128 bit FNV1a hash of the two sequences of data.  See
-  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
-  static absl::uint128 FNV1a_128_Hash_Two(absl::string_view data1,
-                                          absl::string_view data2);
-
-  // Returns the 128 bit FNV1a hash of the three sequences of data.  See
-  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
-  static absl::uint128 FNV1a_128_Hash_Three(absl::string_view data1,
-                                            absl::string_view data2,
-                                            absl::string_view data3);
-
-  // SerializeUint128 writes the first 96 bits of |v| in little-endian form
-  // to |out|.
-  static void SerializeUint128Short(absl::uint128 v, uint8_t* out);
-
-  // Returns AddressChangeType as a string.
-  static std::string AddressChangeTypeToString(AddressChangeType type);
-
-  // Returns SentPacketState as a char*.
-  static const char* SentPacketStateToString(SentPacketState state);
-
-  // Returns QuicLongHeaderType as a char*.
-  static const char* QuicLongHeaderTypetoString(QuicLongHeaderType type);
-
-  // Returns AckResult as a char*.
-  static const char* AckResultToString(AckResult result);
-
-  // Determines and returns change type of address change from |old_address| to
-  // |new_address|.
-  static AddressChangeType DetermineAddressChangeType(
-      const QuicSocketAddress& old_address,
-      const QuicSocketAddress& new_address);
-
-  // Returns the opposite Perspective of the |perspective| passed in.
-  static constexpr Perspective InvertPerspective(Perspective perspective) {
-    return perspective == Perspective::IS_CLIENT ? Perspective::IS_SERVER
-                                                 : Perspective::IS_CLIENT;
-  }
-
-  // Returns true if a packet is ackable. A packet is unackable if it can never
-  // be acked. Occurs when a packet is never sent, after it is acknowledged
-  // once, or if it's a crypto packet we never expect to receive an ack for.
-  static bool IsAckable(SentPacketState state);
-
-  // Returns true if frame with |type| is retransmittable. A retransmittable
-  // frame should be retransmitted if it is detected as lost.
-  static bool IsRetransmittableFrame(QuicFrameType type);
-
-  // Returns true if |frame| is a handshake frame in version |version|.
-  static bool IsHandshakeFrame(const QuicFrame& frame,
-                               QuicTransportVersion transport_version);
-
-  // Return true if any frame in |frames| is of |type|.
-  static bool ContainsFrameType(const QuicFrames& frames, QuicFrameType type);
-
-  // Returns packet state corresponding to |retransmission_type|.
-  static SentPacketState RetransmissionTypeToPacketState(
-      TransmissionType retransmission_type);
-
-  // Returns true if header with |first_byte| is considered as an IETF QUIC
-  // packet header. This only works on the server.
-  static bool IsIetfPacketHeader(uint8_t first_byte);
-
-  // Returns true if header with |first_byte| is considered as an IETF QUIC
-  // short packet header.
-  static bool IsIetfPacketShortHeader(uint8_t first_byte);
-
-  // Returns ID to denote an invalid stream of |version|.
-  static QuicStreamId GetInvalidStreamId(QuicTransportVersion version);
-
-  // Returns crypto stream ID of |version|.
-  static QuicStreamId GetCryptoStreamId(QuicTransportVersion version);
-
-  // Returns whether |id| is the stream ID for the crypto stream. If |version|
-  // is a version where crypto data doesn't go over stream frames, this function
-  // will always return false.
-  static bool IsCryptoStreamId(QuicTransportVersion version, QuicStreamId id);
-
-  // Returns headers stream ID of |version|.
-  static QuicStreamId GetHeadersStreamId(QuicTransportVersion version);
-
-  // Returns true if |id| is considered as client initiated stream ID.
-  static bool IsClientInitiatedStreamId(QuicTransportVersion version,
-                                        QuicStreamId id);
-
-  // Returns true if |id| is considered as server initiated stream ID.
-  static bool IsServerInitiatedStreamId(QuicTransportVersion version,
-                                        QuicStreamId id);
-
-  // Returns true if the stream ID represents a stream initiated by the
-  // provided perspective.
-  static bool IsOutgoingStreamId(ParsedQuicVersion version,
-                                 QuicStreamId id,
-                                 Perspective perspective);
-
-  // Returns true if |id| is considered as bidirectional stream ID. Only used in
-  // v99.
-  static bool IsBidirectionalStreamId(QuicStreamId id,
-                                      ParsedQuicVersion version);
-
-  // Returns stream type.  Either |perspective| or |peer_initiated| would be
-  // enough together with |id|.  This method enforces that the three parameters
-  // are consistent.  Only used in v99.
-  static StreamType GetStreamType(QuicStreamId id,
-                                  Perspective perspective,
-                                  bool peer_initiated,
-                                  ParsedQuicVersion version);
-
-  // Returns the delta between consecutive stream IDs of the same type.
-  static QuicStreamId StreamIdDelta(QuicTransportVersion version);
-
-  // Returns the first initiated bidirectional stream ID of |perspective|.
-  static QuicStreamId GetFirstBidirectionalStreamId(
-      QuicTransportVersion version,
-      Perspective perspective);
-
-  // Returns the first initiated unidirectional stream ID of |perspective|.
-  static QuicStreamId GetFirstUnidirectionalStreamId(
-      QuicTransportVersion version,
-      Perspective perspective);
-
-  // Returns the largest possible client initiated bidirectional stream ID.
-  static QuicStreamId GetMaxClientInitiatedBidirectionalStreamId(
-      QuicTransportVersion version);
-
-  // Generates a connection ID of length |expected_connection_id_length|
-  // derived from |connection_id|.
-  // This is guaranteed to be deterministic (calling this method with two
-  // connection IDs that are equal is guaranteed to produce the same result).
-  static QuicConnectionId CreateReplacementConnectionId(
-      const QuicConnectionId& connection_id,
-      uint8_t expected_connection_id_length);
-
-  // Generates a 64bit connection ID derived from |connection_id|.
-  // This is guaranteed to be deterministic (calling this method with two
-  // connection IDs that are equal is guaranteed to produce the same result).
-  static QuicConnectionId CreateReplacementConnectionId(
-      const QuicConnectionId& connection_id);
-
-  // Generates a random 64bit connection ID.
-  static QuicConnectionId CreateRandomConnectionId();
-
-  // Generates a random 64bit connection ID using the provided QuicRandom.
-  static QuicConnectionId CreateRandomConnectionId(QuicRandom* random);
-
-  // Generates a random connection ID of the given length.
-  static QuicConnectionId CreateRandomConnectionId(
-      uint8_t connection_id_length);
-
-  // Generates a random connection ID of the given length using the provided
-  // QuicRandom.
-  static QuicConnectionId CreateRandomConnectionId(uint8_t connection_id_length,
-                                                   QuicRandom* random);
-
-  // Returns true if the connection ID length is valid for this QUIC version.
-  static bool IsConnectionIdLengthValidForVersion(
-      size_t connection_id_length,
-      QuicTransportVersion transport_version);
-
-  // Returns true if the connection ID is valid for this QUIC version.
-  static bool IsConnectionIdValidForVersion(
-      QuicConnectionId connection_id,
-      QuicTransportVersion transport_version);
-
-  // Returns a connection ID suitable for QUIC use-cases that do not need the
-  // connection ID for multiplexing. If the version allows variable lengths,
-  // a connection of length zero is returned, otherwise 64bits set to zero.
-  static QuicConnectionId CreateZeroConnectionId(QuicTransportVersion version);
-
-  // Generates a 128bit stateless reset token based on a connection ID.
-  static StatelessResetToken GenerateStatelessResetToken(
-      QuicConnectionId connection_id);
-
-  // Determines packet number space from |encryption_level|.
-  static PacketNumberSpace GetPacketNumberSpace(
-      EncryptionLevel encryption_level);
-
-  // Determines encryption level to send packets in |packet_number_space|.
-  static EncryptionLevel GetEncryptionLevel(
-      PacketNumberSpace packet_number_space);
-
-  // Get the maximum value for a V99/IETF QUIC stream count. If a count
-  // exceeds this value, it will result in a stream ID that exceeds the
-  // implementation limit on stream ID size.
-  static QuicStreamCount GetMaxStreamCount();
-
-  // Return true if this frame is an IETF probing frame.
-  static bool IsProbingFrame(QuicFrameType type);
-
-  // Return true if the two stateless reset tokens are equal. Performs the
-  // comparison in constant time.
-  static bool AreStatelessResetTokensEqual(const StatelessResetToken& token1,
-                                           const StatelessResetToken& token2);
-
-  // Return ture if this frame is an ack-eliciting frame.
-  static bool IsAckElicitingFrame(QuicFrameType type);
-};
-
-// Returns true if the specific ID is a valid WebTransport session ID that our
-// implementation can process.
-bool IsValidWebTransportSessionId(WebTransportSessionId id,
-                                  ParsedQuicVersion transport_version);
-
-QuicByteCount MemSliceSpanTotalSize(absl::Span<quiche::QuicheMemSlice> span);
-
-// Computes a SHA-256 hash and returns the raw bytes of the hash.
-QUIC_EXPORT_PRIVATE std::string RawSha256(absl::string_view input);
-
-template <typename Mask>
-class QUIC_EXPORT_PRIVATE BitMask {
- public:
-  // explicit to prevent (incorrect) usage like "BitMask bitmask = 0;".
-  template <typename... Bits>
-  explicit BitMask(Bits... bits) {
-    mask_ = MakeMask(bits...);
-  }
-
-  BitMask() = default;
-  BitMask(const BitMask& other) = default;
-  BitMask& operator=(const BitMask& other) = default;
-
-  template <typename... Bits>
-  void Set(Bits... bits) {
-    mask_ |= MakeMask(bits...);
-  }
-
-  template <typename Bit>
-  bool IsSet(Bit bit) const {
-    return (MakeMask(bit) & mask_) != 0;
-  }
-
-  void ClearAll() { mask_ = 0; }
-
-  static constexpr size_t NumBits() { return 8 * sizeof(Mask); }
-
-  friend bool operator==(const BitMask& lhs, const BitMask& rhs) {
-    return lhs.mask_ == rhs.mask_;
-  }
-
-  std::string DebugString() const {
-    std::ostringstream oss;
-    oss << "0x" << std::hex << mask_;
-    return oss.str();
-  }
-
- private:
-  template <typename Bit>
-  static std::enable_if_t<std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
-    using IntType = typename std::underlying_type<Bit>::type;
-    return Mask(1) << static_cast<IntType>(bit);
-  }
-
-  template <typename Bit>
-  static std::enable_if_t<!std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
-    return Mask(1) << bit;
-  }
-
-  template <typename Bit, typename... Bits>
-  static Mask MakeMask(Bit first_bit, Bits... other_bits) {
-    return MakeMask(first_bit) | MakeMask(other_bits...);
-  }
-
-  Mask mask_ = 0;
-};
-
-using BitMask64 = BitMask<uint64_t>;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_UTILS_H_
diff --git a/quic/core/quic_utils_test.cc b/quic/core/quic_utils_test.cc
deleted file mode 100644
index a026330..0000000
--- a/quic/core/quic_utils_test.cc
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_utils.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/numeric/int128.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicUtilsTest : public QuicTest {};
-
-TEST_F(QuicUtilsTest, DetermineAddressChangeType) {
-  const std::string kIPv4String1 = "1.2.3.4";
-  const std::string kIPv4String2 = "1.2.3.5";
-  const std::string kIPv4String3 = "1.1.3.5";
-  const std::string kIPv6String1 = "2001:700:300:1800::f";
-  const std::string kIPv6String2 = "2001:700:300:1800:1:1:1:f";
-  QuicSocketAddress old_address;
-  QuicSocketAddress new_address;
-  QuicIpAddress address;
-
-  EXPECT_EQ(NO_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-  ASSERT_TRUE(address.FromString(kIPv4String1));
-  old_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(NO_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-  new_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(NO_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
-  new_address = QuicSocketAddress(address, 5678);
-  EXPECT_EQ(PORT_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-  ASSERT_TRUE(address.FromString(kIPv6String1));
-  old_address = QuicSocketAddress(address, 1234);
-  new_address = QuicSocketAddress(address, 5678);
-  EXPECT_EQ(PORT_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
-  ASSERT_TRUE(address.FromString(kIPv4String1));
-  old_address = QuicSocketAddress(address, 1234);
-  ASSERT_TRUE(address.FromString(kIPv6String1));
-  new_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(IPV4_TO_IPV6_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
-  old_address = QuicSocketAddress(address, 1234);
-  ASSERT_TRUE(address.FromString(kIPv4String1));
-  new_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
-  ASSERT_TRUE(address.FromString(kIPv6String2));
-  new_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(IPV6_TO_IPV6_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-
-  ASSERT_TRUE(address.FromString(kIPv4String1));
-  old_address = QuicSocketAddress(address, 1234);
-  ASSERT_TRUE(address.FromString(kIPv4String2));
-  new_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(IPV4_SUBNET_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-  ASSERT_TRUE(address.FromString(kIPv4String3));
-  new_address = QuicSocketAddress(address, 1234);
-  EXPECT_EQ(IPV4_TO_IPV4_CHANGE,
-            QuicUtils::DetermineAddressChangeType(old_address, new_address));
-}
-
-absl::uint128 IncrementalHashReference(const void* data, size_t len) {
-  // The two constants are defined as part of the hash algorithm.
-  // see http://www.isthe.com/chongo/tech/comp/fnv/
-  // hash = 144066263297769815596495629667062367629
-  absl::uint128 hash = absl::MakeUint128(UINT64_C(7809847782465536322),
-                                         UINT64_C(7113472399480571277));
-  // kPrime = 309485009821345068724781371
-  const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
-  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
-  for (size_t i = 0; i < len; ++i) {
-    hash = hash ^ absl::MakeUint128(0, octets[i]);
-    hash = hash * kPrime;
-  }
-  return hash;
-}
-
-TEST_F(QuicUtilsTest, ReferenceTest) {
-  std::vector<uint8_t> data(32);
-  for (size_t i = 0; i < data.size(); ++i) {
-    data[i] = i % 255;
-  }
-  EXPECT_EQ(IncrementalHashReference(data.data(), data.size()),
-            QuicUtils::FNV1a_128_Hash(absl::string_view(
-                reinterpret_cast<const char*>(data.data()), data.size())));
-}
-
-TEST_F(QuicUtilsTest, IsUnackable) {
-  for (size_t i = FIRST_PACKET_STATE; i <= LAST_PACKET_STATE; ++i) {
-    if (i == NEVER_SENT || i == ACKED || i == UNACKABLE) {
-      EXPECT_FALSE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
-    } else {
-      EXPECT_TRUE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
-    }
-  }
-}
-
-TEST_F(QuicUtilsTest, RetransmissionTypeToPacketState) {
-  for (size_t i = FIRST_TRANSMISSION_TYPE; i <= LAST_TRANSMISSION_TYPE; ++i) {
-    if (i == NOT_RETRANSMISSION) {
-      continue;
-    }
-    SentPacketState state = QuicUtils::RetransmissionTypeToPacketState(
-        static_cast<TransmissionType>(i));
-    if (i == HANDSHAKE_RETRANSMISSION) {
-      EXPECT_EQ(HANDSHAKE_RETRANSMITTED, state);
-    } else if (i == LOSS_RETRANSMISSION) {
-      EXPECT_EQ(LOST, state);
-    } else if (i == ALL_ZERO_RTT_RETRANSMISSION) {
-      EXPECT_EQ(UNACKABLE, state);
-    } else if (i == TLP_RETRANSMISSION) {
-      EXPECT_EQ(TLP_RETRANSMITTED, state);
-    } else if (i == RTO_RETRANSMISSION) {
-      EXPECT_EQ(RTO_RETRANSMITTED, state);
-    } else if (i == PTO_RETRANSMISSION) {
-      EXPECT_EQ(PTO_RETRANSMITTED, state);
-    } else if (i == PROBING_RETRANSMISSION) {
-      EXPECT_EQ(PROBE_RETRANSMITTED, state);
-    } else if (i == PATH_RETRANSMISSION) {
-      EXPECT_EQ(NOT_CONTRIBUTING_RTT, state);
-    } else if (i == ALL_INITIAL_RETRANSMISSION) {
-      EXPECT_EQ(UNACKABLE, state);
-    } else {
-      QUICHE_DCHECK(false)
-          << "No corresponding packet state according to transmission type: "
-          << i;
-    }
-  }
-}
-
-TEST_F(QuicUtilsTest, IsIetfPacketHeader) {
-  // IETF QUIC short header
-  uint8_t first_byte = 0;
-  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
-  EXPECT_TRUE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-
-  // IETF QUIC long header
-  first_byte |= (FLAGS_LONG_HEADER | FLAGS_DEMULTIPLEXING_BIT);
-  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
-  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-
-  // IETF QUIC long header, version negotiation.
-  first_byte = 0;
-  first_byte |= FLAGS_LONG_HEADER;
-  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
-  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-
-  // GQUIC
-  first_byte = 0;
-  first_byte |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
-  EXPECT_FALSE(QuicUtils::IsIetfPacketHeader(first_byte));
-  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
-}
-
-TEST_F(QuicUtilsTest, ReplacementConnectionIdIsDeterministic) {
-  // Verify that two equal connection IDs get the same replacement.
-  QuicConnectionId connection_id64a = TestConnectionId(33);
-  QuicConnectionId connection_id64b = TestConnectionId(33);
-  EXPECT_EQ(connection_id64a, connection_id64b);
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a),
-            QuicUtils::CreateReplacementConnectionId(connection_id64b));
-  QuicConnectionId connection_id72a = TestConnectionIdNineBytesLong(42);
-  QuicConnectionId connection_id72b = TestConnectionIdNineBytesLong(42);
-  EXPECT_EQ(connection_id72a, connection_id72b);
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a),
-            QuicUtils::CreateReplacementConnectionId(connection_id72b));
-  // Test variant with custom length.
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 7),
-            QuicUtils::CreateReplacementConnectionId(connection_id64b, 7));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 9),
-            QuicUtils::CreateReplacementConnectionId(connection_id64b, 9));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 16),
-            QuicUtils::CreateReplacementConnectionId(connection_id64b, 16));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 7),
-            QuicUtils::CreateReplacementConnectionId(connection_id72b, 7));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 9),
-            QuicUtils::CreateReplacementConnectionId(connection_id72b, 9));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 16),
-            QuicUtils::CreateReplacementConnectionId(connection_id72b, 16));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 32),
-            QuicUtils::CreateReplacementConnectionId(connection_id72b, 32));
-  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 255),
-            QuicUtils::CreateReplacementConnectionId(connection_id72b, 255));
-}
-
-TEST_F(QuicUtilsTest, ReplacementConnectionIdLengthIsCorrect) {
-  // Verify that all lengths get replaced by kQuicDefaultConnectionIdLength.
-  const char connection_id_bytes[255] = {};
-  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
-    QuicConnectionId connection_id(connection_id_bytes, i);
-    QuicConnectionId replacement_connection_id =
-        QuicUtils::CreateReplacementConnectionId(connection_id);
-    EXPECT_EQ(kQuicDefaultConnectionIdLength,
-              replacement_connection_id.length());
-    // Test variant with custom length.
-    QuicConnectionId replacement_connection_id7 =
-        QuicUtils::CreateReplacementConnectionId(connection_id, 7);
-    EXPECT_EQ(7, replacement_connection_id7.length());
-    QuicConnectionId replacement_connection_id9 =
-        QuicUtils::CreateReplacementConnectionId(connection_id, 9);
-    EXPECT_EQ(9, replacement_connection_id9.length());
-    QuicConnectionId replacement_connection_id16 =
-        QuicUtils::CreateReplacementConnectionId(connection_id, 16);
-    EXPECT_EQ(16, replacement_connection_id16.length());
-    QuicConnectionId replacement_connection_id32 =
-        QuicUtils::CreateReplacementConnectionId(connection_id, 32);
-    EXPECT_EQ(32, replacement_connection_id32.length());
-    QuicConnectionId replacement_connection_id255 =
-        QuicUtils::CreateReplacementConnectionId(connection_id, 255);
-    EXPECT_EQ(255, replacement_connection_id255.length());
-  }
-}
-
-TEST_F(QuicUtilsTest, ReplacementConnectionIdHasEntropy) {
-  // Make sure all these test connection IDs have different replacements.
-  for (uint64_t i = 0; i < 256; ++i) {
-    QuicConnectionId connection_id_i = TestConnectionId(i);
-    EXPECT_NE(connection_id_i,
-              QuicUtils::CreateReplacementConnectionId(connection_id_i));
-    for (uint64_t j = i + 1; j <= 256; ++j) {
-      QuicConnectionId connection_id_j = TestConnectionId(j);
-      EXPECT_NE(connection_id_i, connection_id_j);
-      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i),
-                QuicUtils::CreateReplacementConnectionId(connection_id_j));
-      // Test variant with custom length.
-      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 7),
-                QuicUtils::CreateReplacementConnectionId(connection_id_j, 7));
-      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 9),
-                QuicUtils::CreateReplacementConnectionId(connection_id_j, 9));
-      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 16),
-                QuicUtils::CreateReplacementConnectionId(connection_id_j, 16));
-      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 32),
-                QuicUtils::CreateReplacementConnectionId(connection_id_j, 32));
-      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 255),
-                QuicUtils::CreateReplacementConnectionId(connection_id_j, 255));
-    }
-  }
-}
-
-TEST_F(QuicUtilsTest, RandomConnectionId) {
-  MockRandom random(33);
-  QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(&random);
-  EXPECT_EQ(connection_id.length(), sizeof(uint64_t));
-  char connection_id_bytes[sizeof(uint64_t)];
-  random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
-  EXPECT_EQ(connection_id,
-            QuicConnectionId(static_cast<char*>(connection_id_bytes),
-                             ABSL_ARRAYSIZE(connection_id_bytes)));
-  EXPECT_NE(connection_id, EmptyQuicConnectionId());
-  EXPECT_NE(connection_id, TestConnectionId());
-  EXPECT_NE(connection_id, TestConnectionId(1));
-  EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
-  EXPECT_EQ(QuicUtils::CreateRandomConnectionId().length(),
-            kQuicDefaultConnectionIdLength);
-}
-
-TEST_F(QuicUtilsTest, RandomConnectionIdVariableLength) {
-  MockRandom random(1337);
-  const uint8_t connection_id_length = 9;
-  QuicConnectionId connection_id =
-      QuicUtils::CreateRandomConnectionId(connection_id_length, &random);
-  EXPECT_EQ(connection_id.length(), connection_id_length);
-  char connection_id_bytes[connection_id_length];
-  random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
-  EXPECT_EQ(connection_id,
-            QuicConnectionId(static_cast<char*>(connection_id_bytes),
-                             ABSL_ARRAYSIZE(connection_id_bytes)));
-  EXPECT_NE(connection_id, EmptyQuicConnectionId());
-  EXPECT_NE(connection_id, TestConnectionId());
-  EXPECT_NE(connection_id, TestConnectionId(1));
-  EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
-  EXPECT_EQ(QuicUtils::CreateRandomConnectionId(connection_id_length).length(),
-            connection_id_length);
-}
-
-TEST_F(QuicUtilsTest, VariableLengthConnectionId) {
-  EXPECT_FALSE(VersionAllowsVariableLengthConnectionIds(QUIC_VERSION_43));
-  EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
-      QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43), QUIC_VERSION_43));
-  EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
-      QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50), QUIC_VERSION_50));
-  EXPECT_NE(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43),
-            EmptyQuicConnectionId());
-  EXPECT_EQ(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50),
-            EmptyQuicConnectionId());
-  EXPECT_FALSE(QuicUtils::IsConnectionIdValidForVersion(EmptyQuicConnectionId(),
-                                                        QUIC_VERSION_43));
-}
-
-TEST_F(QuicUtilsTest, StatelessResetToken) {
-  QuicConnectionId connection_id1a = test::TestConnectionId(1);
-  QuicConnectionId connection_id1b = test::TestConnectionId(1);
-  QuicConnectionId connection_id2 = test::TestConnectionId(2);
-  StatelessResetToken token1a =
-      QuicUtils::GenerateStatelessResetToken(connection_id1a);
-  StatelessResetToken token1b =
-      QuicUtils::GenerateStatelessResetToken(connection_id1b);
-  StatelessResetToken token2 =
-      QuicUtils::GenerateStatelessResetToken(connection_id2);
-  EXPECT_EQ(token1a, token1b);
-  EXPECT_NE(token1a, token2);
-  EXPECT_TRUE(QuicUtils::AreStatelessResetTokensEqual(token1a, token1b));
-  EXPECT_FALSE(QuicUtils::AreStatelessResetTokensEqual(token1a, token2));
-}
-
-enum class TestEnumClassBit : uint8_t {
-  BIT_ZERO = 0,
-  BIT_ONE,
-  BIT_TWO,
-};
-
-enum TestEnumBit {
-  TEST_BIT_0 = 0,
-  TEST_BIT_1,
-  TEST_BIT_2,
-};
-
-TEST(QuicBitMaskTest, EnumClass) {
-  BitMask64 mask(TestEnumClassBit::BIT_ZERO, TestEnumClassBit::BIT_TWO);
-  EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
-  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
-  EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_TWO));
-
-  mask.ClearAll();
-  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
-  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
-  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_TWO));
-}
-
-TEST(QuicBitMaskTest, Enum) {
-  BitMask64 mask(TEST_BIT_1, TEST_BIT_2);
-  EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
-  EXPECT_TRUE(mask.IsSet(TEST_BIT_1));
-  EXPECT_TRUE(mask.IsSet(TEST_BIT_2));
-
-  mask.ClearAll();
-  EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
-  EXPECT_FALSE(mask.IsSet(TEST_BIT_1));
-  EXPECT_FALSE(mask.IsSet(TEST_BIT_2));
-}
-
-TEST(QuicBitMaskTest, Integer) {
-  BitMask64 mask(1, 3);
-  mask.Set(3);
-  mask.Set(5, 7, 9);
-  EXPECT_FALSE(mask.IsSet(0));
-  EXPECT_TRUE(mask.IsSet(1));
-  EXPECT_FALSE(mask.IsSet(2));
-  EXPECT_TRUE(mask.IsSet(3));
-  EXPECT_FALSE(mask.IsSet(4));
-  EXPECT_TRUE(mask.IsSet(5));
-  EXPECT_FALSE(mask.IsSet(6));
-  EXPECT_TRUE(mask.IsSet(7));
-  EXPECT_FALSE(mask.IsSet(8));
-  EXPECT_TRUE(mask.IsSet(9));
-}
-
-TEST(QuicBitMaskTest, NumBits) {
-  EXPECT_EQ(64u, BitMask64::NumBits());
-  EXPECT_EQ(32u, BitMask<uint32_t>::NumBits());
-}
-
-TEST(QuicBitMaskTest, Constructor) {
-  BitMask64 empty_mask;
-  for (size_t bit = 0; bit < empty_mask.NumBits(); ++bit) {
-    EXPECT_FALSE(empty_mask.IsSet(bit));
-  }
-
-  BitMask64 mask(1, 3);
-  BitMask64 mask2 = mask;
-  BitMask64 mask3(mask2);
-
-  for (size_t bit = 0; bit < mask.NumBits(); ++bit) {
-    EXPECT_EQ(mask.IsSet(bit), mask2.IsSet(bit));
-    EXPECT_EQ(mask.IsSet(bit), mask3.IsSet(bit));
-  }
-
-  EXPECT_TRUE(std::is_trivially_copyable<BitMask64>::value);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_version_manager.cc b/quic/core/quic_version_manager.cc
deleted file mode 100644
index 1309456..0000000
--- a/quic/core/quic_version_manager.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_version_manager.h"
-
-#include <algorithm>
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicVersionManager::QuicVersionManager(
-    ParsedQuicVersionVector supported_versions)
-    : allowed_supported_versions_(std::move(supported_versions)) {}
-
-QuicVersionManager::~QuicVersionManager() {}
-
-const ParsedQuicVersionVector& QuicVersionManager::GetSupportedVersions() {
-  MaybeRefilterSupportedVersions();
-  return filtered_supported_versions_;
-}
-
-const ParsedQuicVersionVector&
-QuicVersionManager::GetSupportedVersionsWithOnlyHttp3() {
-  MaybeRefilterSupportedVersions();
-  return filtered_supported_versions_with_http3_;
-}
-
-const std::vector<std::string>& QuicVersionManager::GetSupportedAlpns() {
-  MaybeRefilterSupportedVersions();
-  return filtered_supported_alpns_;
-}
-
-void QuicVersionManager::MaybeRefilterSupportedVersions() {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  if (enable_version_2_draft_01_ !=
-          GetQuicReloadableFlag(quic_enable_version_2_draft_01) ||
-      disable_version_rfcv1_ !=
-          GetQuicReloadableFlag(quic_disable_version_rfcv1) ||
-      disable_version_draft_29_ !=
-          GetQuicReloadableFlag(quic_disable_version_draft_29) ||
-      disable_version_q050_ !=
-          GetQuicReloadableFlag(quic_disable_version_q050) ||
-      disable_version_q046_ !=
-          GetQuicReloadableFlag(quic_disable_version_q046) ||
-      disable_version_q043_ !=
-          GetQuicReloadableFlag(quic_disable_version_q043)) {
-    enable_version_2_draft_01_ =
-        GetQuicReloadableFlag(quic_enable_version_2_draft_01);
-    disable_version_rfcv1_ = GetQuicReloadableFlag(quic_disable_version_rfcv1);
-    disable_version_draft_29_ =
-        GetQuicReloadableFlag(quic_disable_version_draft_29);
-    disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
-    disable_version_q046_ = GetQuicReloadableFlag(quic_disable_version_q046);
-    disable_version_q043_ = GetQuicReloadableFlag(quic_disable_version_q043);
-
-    RefilterSupportedVersions();
-  }
-}
-
-void QuicVersionManager::RefilterSupportedVersions() {
-  filtered_supported_versions_ =
-      FilterSupportedVersions(allowed_supported_versions_);
-  filtered_supported_versions_with_http3_.clear();
-  filtered_transport_versions_.clear();
-  filtered_supported_alpns_.clear();
-  for (const ParsedQuicVersion& version : filtered_supported_versions_) {
-    auto transport_version = version.transport_version;
-    if (std::find(filtered_transport_versions_.begin(),
-                  filtered_transport_versions_.end(),
-                  transport_version) == filtered_transport_versions_.end()) {
-      filtered_transport_versions_.push_back(transport_version);
-    }
-    if (version.UsesHttp3()) {
-      filtered_supported_versions_with_http3_.push_back(version);
-    }
-    if (std::find(filtered_supported_alpns_.begin(),
-                  filtered_supported_alpns_.end(),
-                  AlpnForVersion(version)) == filtered_supported_alpns_.end()) {
-      filtered_supported_alpns_.emplace_back(AlpnForVersion(version));
-    }
-  }
-}
-
-void QuicVersionManager::AddCustomAlpn(const std::string& alpn) {
-  filtered_supported_alpns_.push_back(alpn);
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
deleted file mode 100644
index 44e134a..0000000
--- a/quic/core/quic_version_manager.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
-#define QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Used to generate filtered supported versions based on flags.
-class QUIC_EXPORT_PRIVATE QuicVersionManager {
- public:
-  // |supported_versions| should be sorted in the order of preference (typically
-  // highest supported version to the lowest supported version).
-  explicit QuicVersionManager(ParsedQuicVersionVector supported_versions);
-  virtual ~QuicVersionManager();
-
-  // Returns currently supported QUIC versions. This vector has the same order
-  // as the versions passed to the constructor.
-  const ParsedQuicVersionVector& GetSupportedVersions();
-
-  // Returns currently supported versions using HTTP/3.
-  const ParsedQuicVersionVector& GetSupportedVersionsWithOnlyHttp3();
-
-  // Returns the list of supported ALPNs, based on the current supported
-  // versions and any custom additions by subclasses.
-  const std::vector<std::string>& GetSupportedAlpns();
-
- protected:
-  // If the value of any reloadable flag is different from the cached value,
-  // re-filter |filtered_supported_versions_| and update the cached flag values.
-  // Otherwise, does nothing.
-  // TODO(dschinazi): Make private when deprecating
-  // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
-  void MaybeRefilterSupportedVersions();
-
-  // Refilters filtered_supported_versions_.
-  virtual void RefilterSupportedVersions();
-
-  // RefilterSupportedVersions() must be called before calling this method.
-  // TODO(dschinazi): Remove when deprecating
-  // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
-  const QuicTransportVersionVector& filtered_transport_versions() const {
-    return filtered_transport_versions_;
-  }
-
-  // Subclasses may add custom ALPNs to the supported list by overriding
-  // RefilterSupportedVersions() to first call
-  // QuicVersionManager::RefilterSupportedVersions() then AddCustomAlpn().
-  // Must not be called elsewhere.
-  void AddCustomAlpn(const std::string& alpn);
-
- private:
-  // Cached value of reloadable flags.
-  // quic_enable_version_2_draft_01 flag
-  bool enable_version_2_draft_01_ = false;
-  // quic_disable_version_rfcv1 flag
-  bool disable_version_rfcv1_ = true;
-  // quic_disable_version_draft_29 flag
-  bool disable_version_draft_29_ = true;
-  // quic_disable_version_q050 flag
-  bool disable_version_q050_ = true;
-  // quic_disable_version_q046 flag
-  bool disable_version_q046_ = true;
-  // quic_disable_version_q043 flag
-  bool disable_version_q043_ = true;
-
-  // The list of versions that may be supported.
-  const ParsedQuicVersionVector allowed_supported_versions_;
-
-  // The following vectors are calculated from reloadable flags by
-  // RefilterSupportedVersions().  It is performed lazily when first needed, and
-  // after that, since the calculation is relatively expensive, only if the flag
-  // values change.
-
-  // This vector contains QUIC versions which are currently supported based on
-  // flags.
-  ParsedQuicVersionVector filtered_supported_versions_;
-  // Currently supported versions using HTTP/3.
-  ParsedQuicVersionVector filtered_supported_versions_with_http3_;
-  // This vector contains the transport versions from
-  // |filtered_supported_versions_|. No guarantees are made that the same
-  // transport version isn't repeated.
-  QuicTransportVersionVector filtered_transport_versions_;
-  // Contains the list of ALPNs corresponding to filtered_supported_versions_
-  // with custom ALPNs added.
-  std::vector<std::string> filtered_supported_alpns_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
deleted file mode 100644
index cc45cd4..0000000
--- a/quic/core/quic_version_manager_test.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_version_manager.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-
-using ::testing::ElementsAre;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicVersionManagerTest : public QuicTest {};
-
-TEST_F(QuicVersionManagerTest, QuicVersionManager) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    QuicEnableVersion(version);
-  }
-  QuicDisableVersion(ParsedQuicVersion::V2Draft01());
-  QuicDisableVersion(ParsedQuicVersion::RFCv1());
-  QuicDisableVersion(ParsedQuicVersion::Draft29());
-  QuicVersionManager manager(AllSupportedVersions());
-
-  ParsedQuicVersionVector expected_parsed_versions;
-  expected_parsed_versions.push_back(ParsedQuicVersion::Q050());
-  expected_parsed_versions.push_back(ParsedQuicVersion::Q046());
-  expected_parsed_versions.push_back(ParsedQuicVersion::Q043());
-
-  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-
-  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
-            manager.GetSupportedVersions());
-  EXPECT_TRUE(manager.GetSupportedVersionsWithOnlyHttp3().empty());
-  EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-Q050", "h3-Q046", "h3-Q043"));
-
-  QuicEnableVersion(ParsedQuicVersion::Draft29());
-  expected_parsed_versions.insert(expected_parsed_versions.begin(),
-                                  ParsedQuicVersion::Draft29());
-  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
-            manager.GetSupportedVersions());
-  EXPECT_EQ(1u, manager.GetSupportedVersionsWithOnlyHttp3().size());
-  EXPECT_EQ(CurrentSupportedHttp3Versions(),
-            manager.GetSupportedVersionsWithOnlyHttp3());
-  EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
-
-  QuicEnableVersion(ParsedQuicVersion::RFCv1());
-  expected_parsed_versions.insert(expected_parsed_versions.begin(),
-                                  ParsedQuicVersion::RFCv1());
-  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
-            manager.GetSupportedVersions());
-  EXPECT_EQ(2u, manager.GetSupportedVersionsWithOnlyHttp3().size());
-  EXPECT_EQ(CurrentSupportedHttp3Versions(),
-            manager.GetSupportedVersionsWithOnlyHttp3());
-  EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
-
-  QuicEnableVersion(ParsedQuicVersion::V2Draft01());
-  expected_parsed_versions.insert(expected_parsed_versions.begin(),
-                                  ParsedQuicVersion::V2Draft01());
-  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
-            manager.GetSupportedVersions());
-  EXPECT_EQ(3u, manager.GetSupportedVersionsWithOnlyHttp3().size());
-  EXPECT_EQ(CurrentSupportedHttp3Versions(),
-            manager.GetSupportedVersionsWithOnlyHttp3());
-  EXPECT_THAT(
-      manager.GetSupportedAlpns(),
-      ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
deleted file mode 100644
index a0957fa..0000000
--- a/quic/core/quic_versions.cc
+++ /dev/null
@@ -1,667 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_versions.h"
-
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_endian.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
-  QuicVersionLabel result;
-  if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
-    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
-  } else {
-    result = MakeVersionLabel(0xd1, 0x57, 0x38, 0x3f);
-  }
-  result &= 0xf0f0f0f0;
-  result |= 0x0a0a0a0a;
-  return result;
-}
-
-void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  const bool enable = should_enable;
-  const bool disable = !should_enable;
-  if (version == ParsedQuicVersion::V2Draft01()) {
-    SetQuicReloadableFlag(quic_enable_version_2_draft_01, enable);
-  } else if (version == ParsedQuicVersion::RFCv1()) {
-    SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
-  } else if (version == ParsedQuicVersion::Draft29()) {
-    SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
-  } else if (version == ParsedQuicVersion::Q050()) {
-    SetQuicReloadableFlag(quic_disable_version_q050, disable);
-  } else if (version == ParsedQuicVersion::Q046()) {
-    SetQuicReloadableFlag(quic_disable_version_q046, disable);
-  } else if (version == ParsedQuicVersion::Q043()) {
-    SetQuicReloadableFlag(quic_disable_version_q043, disable);
-  } else {
-    QUIC_BUG(quic_bug_10589_1)
-        << "Cannot " << (enable ? "en" : "dis") << "able version " << version;
-  }
-}
-
-}  // namespace
-
-bool ParsedQuicVersion::IsKnown() const {
-  QUICHE_DCHECK(ParsedQuicVersionIsValid(handshake_protocol, transport_version))
-      << QuicVersionToString(transport_version) << " "
-      << HandshakeProtocolToString(handshake_protocol);
-  return transport_version != QUIC_VERSION_UNSUPPORTED;
-}
-
-bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
-  QUICHE_DCHECK(IsKnown());
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::UsesInitialObfuscators() const {
-  QUICHE_DCHECK(IsKnown());
-  // Initial obfuscators were added in version 50.
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
-  QUICHE_DCHECK(IsKnown());
-  // Low flow-control limits are used for all IETF versions.
-  return UsesHttp3();
-}
-
-bool ParsedQuicVersion::HasHeaderProtection() const {
-  QUICHE_DCHECK(IsKnown());
-  // Header protection was added in version 50.
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::SupportsRetry() const {
-  QUICHE_DCHECK(IsKnown());
-  // Retry was added in version 47.
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::SendsVariableLengthPacketNumberInLongHeader() const {
-  QUICHE_DCHECK(IsKnown());
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::AllowsVariableLengthConnectionIds() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionAllowsVariableLengthConnectionIds(transport_version);
-}
-
-bool ParsedQuicVersion::SupportsClientConnectionIds() const {
-  QUICHE_DCHECK(IsKnown());
-  // Client connection IDs were added in version 49.
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionHasLengthPrefixedConnectionIds(transport_version);
-}
-
-bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
-  QUICHE_DCHECK(IsKnown());
-  // The anti-amplification limit is used for all IETF versions.
-  return UsesHttp3();
-}
-
-bool ParsedQuicVersion::CanSendCoalescedPackets() const {
-  QUICHE_DCHECK(IsKnown());
-  return HasLongHeaderLengths() && UsesTls();
-}
-
-bool ParsedQuicVersion::SupportsGoogleAltSvcFormat() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionSupportsGoogleAltSvcFormat(transport_version);
-}
-
-bool ParsedQuicVersion::HasIetfInvariantHeader() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionHasIetfInvariantHeader(transport_version);
-}
-
-bool ParsedQuicVersion::SupportsMessageFrames() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionSupportsMessageFrames(transport_version);
-}
-
-bool ParsedQuicVersion::UsesHttp3() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionUsesHttp3(transport_version);
-}
-
-bool ParsedQuicVersion::HasLongHeaderLengths() const {
-  QUICHE_DCHECK(IsKnown());
-  return QuicVersionHasLongHeaderLengths(transport_version);
-}
-
-bool ParsedQuicVersion::UsesCryptoFrames() const {
-  QUICHE_DCHECK(IsKnown());
-  return QuicVersionUsesCryptoFrames(transport_version);
-}
-
-bool ParsedQuicVersion::HasIetfQuicFrames() const {
-  QUICHE_DCHECK(IsKnown());
-  return VersionHasIetfQuicFrames(transport_version);
-}
-
-bool ParsedQuicVersion::UsesLegacyTlsExtension() const {
-  QUICHE_DCHECK(IsKnown());
-  return UsesTls() && transport_version <= QUIC_VERSION_IETF_DRAFT_29;
-}
-
-bool ParsedQuicVersion::UsesTls() const {
-  QUICHE_DCHECK(IsKnown());
-  return handshake_protocol == PROTOCOL_TLS1_3;
-}
-
-bool ParsedQuicVersion::UsesQuicCrypto() const {
-  QUICHE_DCHECK(IsKnown());
-  return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
-}
-
-bool ParsedQuicVersion::UsesV2PacketTypes() const {
-  QUICHE_DCHECK(IsKnown());
-  return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
-}
-
-bool ParsedQuicVersion::AlpnDeferToRFCv1() const {
-  QUICHE_DCHECK(IsKnown());
-  return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
-}
-
-bool VersionHasLengthPrefixedConnectionIds(
-    QuicTransportVersion transport_version) {
-  QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
-  // Length-prefixed connection IDs were added in version 49.
-  return transport_version > QUIC_VERSION_46;
-}
-
-std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
-  os << ParsedQuicVersionToString(version);
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const ParsedQuicVersionVector& versions) {
-  os << ParsedQuicVersionVectorToString(versions);
-  return os;
-}
-
-QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
-  return MakeQuicTag(d, c, b, a);
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicVersionLabelVector& version_labels) {
-  os << QuicVersionLabelVectorToString(version_labels);
-  return os;
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const QuicTransportVersionVector& transport_versions) {
-  os << QuicTransportVersionVectorToString(transport_versions);
-  return os;
-}
-
-QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  if (parsed_version == ParsedQuicVersion::V2Draft01()) {
-    return MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4);
-  } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
-    return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
-  } else if (parsed_version == ParsedQuicVersion::Draft29()) {
-    return MakeVersionLabel(0xff, 0x00, 0x00, 29);
-  } else if (parsed_version == ParsedQuicVersion::Q050()) {
-    return MakeVersionLabel('Q', '0', '5', '0');
-  } else if (parsed_version == ParsedQuicVersion::Q046()) {
-    return MakeVersionLabel('Q', '0', '4', '6');
-  } else if (parsed_version == ParsedQuicVersion::Q043()) {
-    return MakeVersionLabel('Q', '0', '4', '3');
-  } else if (parsed_version == ParsedQuicVersion::ReservedForNegotiation()) {
-    return CreateRandomVersionLabelForNegotiation();
-  }
-  QUIC_BUG(quic_bug_10589_2)
-      << "Unsupported version "
-      << QuicVersionToString(parsed_version.transport_version) << " "
-      << HandshakeProtocolToString(parsed_version.handshake_protocol);
-  return 0;
-}
-
-QuicVersionLabelVector CreateQuicVersionLabelVector(
-    const ParsedQuicVersionVector& versions) {
-  QuicVersionLabelVector out;
-  out.reserve(versions.size());
-  for (const auto& version : versions) {
-    out.push_back(CreateQuicVersionLabel(version));
-  }
-  return out;
-}
-
-ParsedQuicVersionVector AllSupportedVersionsWithQuicCrypto() {
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-      versions.push_back(version);
-    }
-  }
-  QUIC_BUG_IF(quic_bug_10589_3, versions.empty())
-      << "No version with QUIC crypto found.";
-  return versions;
-}
-
-ParsedQuicVersionVector CurrentSupportedVersionsWithQuicCrypto() {
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
-    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-      versions.push_back(version);
-    }
-  }
-  QUIC_BUG_IF(quic_bug_10589_4, versions.empty())
-      << "No version with QUIC crypto found.";
-  return versions;
-}
-
-ParsedQuicVersionVector AllSupportedVersionsWithTls() {
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version.UsesTls()) {
-      versions.push_back(version);
-    }
-  }
-  QUIC_BUG_IF(quic_bug_10589_5, versions.empty())
-      << "No version with TLS handshake found.";
-  return versions;
-}
-
-ParsedQuicVersionVector CurrentSupportedVersionsWithTls() {
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
-    if (version.UsesTls()) {
-      versions.push_back(version);
-    }
-  }
-  QUIC_BUG_IF(quic_bug_10589_6, versions.empty())
-      << "No version with TLS handshake found.";
-  return versions;
-}
-
-ParsedQuicVersionVector CurrentSupportedHttp3Versions() {
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
-    if (version.UsesHttp3()) {
-      versions.push_back(version);
-    }
-  }
-  QUIC_BUG_IF(no_version_uses_http3, versions.empty())
-      << "No version speaking Http3 found.";
-  return versions;
-}
-
-ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version_label == CreateQuicVersionLabel(version)) {
-      return version;
-    }
-  }
-  // Reading from the client so this should not be considered an ERROR.
-  QUIC_DLOG(INFO) << "Unsupported QuicVersionLabel version: "
-                  << QuicVersionLabelToString(version_label);
-  return UnsupportedQuicVersion();
-}
-
-ParsedQuicVersionVector ParseQuicVersionLabelVector(
-    const QuicVersionLabelVector& version_labels) {
-  ParsedQuicVersionVector parsed_versions;
-  for (const QuicVersionLabel& version_label : version_labels) {
-    ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
-    if (parsed_version.IsKnown()) {
-      parsed_versions.push_back(parsed_version);
-    }
-  }
-  return parsed_versions;
-}
-
-ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
-  if (version_string.empty()) {
-    return UnsupportedQuicVersion();
-  }
-  const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
-  for (const ParsedQuicVersion& version : supported_versions) {
-    if (version_string == ParsedQuicVersionToString(version) ||
-        (version_string == AlpnForVersion(version) &&
-         !version.AlpnDeferToRFCv1()) ||
-        (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
-         version_string == QuicVersionToString(version.transport_version))) {
-      return version;
-    }
-  }
-  for (const ParsedQuicVersion& version : supported_versions) {
-    if (version.UsesHttp3() &&
-        version_string ==
-            QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
-      return version;
-    }
-  }
-  int quic_version_number = 0;
-  if (absl::SimpleAtoi(version_string, &quic_version_number) &&
-      quic_version_number > 0) {
-    QuicTransportVersion transport_version =
-        static_cast<QuicTransportVersion>(quic_version_number);
-    if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
-      return UnsupportedQuicVersion();
-    }
-    ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
-    if (std::find(supported_versions.begin(), supported_versions.end(),
-                  version) != supported_versions.end()) {
-      return version;
-    }
-    return UnsupportedQuicVersion();
-  }
-  // Reading from the client so this should not be considered an ERROR.
-  QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
-                  << "\".";
-  return UnsupportedQuicVersion();
-}
-
-ParsedQuicVersionVector ParseQuicVersionVectorString(
-    absl::string_view versions_string) {
-  ParsedQuicVersionVector versions;
-  std::vector<absl::string_view> version_strings =
-      absl::StrSplit(versions_string, ',');
-  for (absl::string_view version_string : version_strings) {
-    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
-        &version_string);
-    ParsedQuicVersion version = ParseQuicVersionString(version_string);
-    if (!version.IsKnown() || std::find(versions.begin(), versions.end(),
-                                        version) != versions.end()) {
-      continue;
-    }
-    versions.push_back(version);
-  }
-  return versions;
-}
-
-QuicTransportVersionVector AllSupportedTransportVersions() {
-  QuicTransportVersionVector transport_versions;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (std::find(transport_versions.begin(), transport_versions.end(),
-                  version.transport_version) == transport_versions.end()) {
-      transport_versions.push_back(version.transport_version);
-    }
-  }
-  return transport_versions;
-}
-
-ParsedQuicVersionVector AllSupportedVersions() {
-  constexpr auto supported_versions = SupportedVersions();
-  return ParsedQuicVersionVector(supported_versions.begin(),
-                                 supported_versions.end());
-}
-
-ParsedQuicVersionVector CurrentSupportedVersions() {
-  return FilterSupportedVersions(AllSupportedVersions());
-}
-
-ParsedQuicVersionVector FilterSupportedVersions(
-    ParsedQuicVersionVector versions) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  ParsedQuicVersionVector filtered_versions;
-  filtered_versions.reserve(versions.size());
-  for (const ParsedQuicVersion& version : versions) {
-    if (version == ParsedQuicVersion::V2Draft01()) {
-      if (GetQuicReloadableFlag(quic_enable_version_2_draft_01)) {
-        filtered_versions.push_back(version);
-      }
-    } else if (version == ParsedQuicVersion::RFCv1()) {
-      if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
-        filtered_versions.push_back(version);
-      }
-    } else if (version == ParsedQuicVersion::Draft29()) {
-      if (!GetQuicReloadableFlag(quic_disable_version_draft_29)) {
-        filtered_versions.push_back(version);
-      }
-    } else if (version == ParsedQuicVersion::Q050()) {
-      if (!GetQuicReloadableFlag(quic_disable_version_q050)) {
-        filtered_versions.push_back(version);
-      }
-    } else if (version == ParsedQuicVersion::Q046()) {
-      if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
-        filtered_versions.push_back(version);
-      }
-    } else if (version == ParsedQuicVersion::Q043()) {
-      if (!GetQuicReloadableFlag(quic_disable_version_q043)) {
-        filtered_versions.push_back(version);
-      }
-    } else {
-      QUIC_BUG(quic_bug_10589_7)
-          << "QUIC version " << version << " has no flag protection";
-      filtered_versions.push_back(version);
-    }
-  }
-  return filtered_versions;
-}
-
-ParsedQuicVersionVector ParsedVersionOfIndex(
-    const ParsedQuicVersionVector& versions, int index) {
-  ParsedQuicVersionVector version;
-  int version_count = versions.size();
-  if (index >= 0 && index < version_count) {
-    version.push_back(versions[index]);
-  } else {
-    version.push_back(UnsupportedQuicVersion());
-  }
-  return version;
-}
-
-std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
-  return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
-}
-
-ParsedQuicVersion ParseQuicVersionLabelString(
-    absl::string_view version_label_string) {
-  const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
-  for (const ParsedQuicVersion& version : supported_versions) {
-    if (version_label_string ==
-        QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
-      return version;
-    }
-  }
-  return UnsupportedQuicVersion();
-}
-
-std::string QuicVersionLabelVectorToString(
-    const QuicVersionLabelVector& version_labels, const std::string& separator,
-    size_t skip_after_nth_version) {
-  std::string result;
-  for (size_t i = 0; i < version_labels.size(); ++i) {
-    if (i != 0) {
-      result.append(separator);
-    }
-
-    if (i > skip_after_nth_version) {
-      result.append("...");
-      break;
-    }
-    result.append(QuicVersionLabelToString(version_labels[i]));
-  }
-  return result;
-}
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x
-
-std::string QuicVersionToString(QuicTransportVersion transport_version) {
-  switch (transport_version) {
-    RETURN_STRING_LITERAL(QUIC_VERSION_43);
-    RETURN_STRING_LITERAL(QUIC_VERSION_46);
-    RETURN_STRING_LITERAL(QUIC_VERSION_50);
-    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
-    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
-    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_2_DRAFT_01);
-    RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
-    RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
-  }
-  return absl::StrCat("QUIC_VERSION_UNKNOWN(",
-                      static_cast<int>(transport_version), ")");
-}
-
-std::string HandshakeProtocolToString(HandshakeProtocol handshake_protocol) {
-  switch (handshake_protocol) {
-    RETURN_STRING_LITERAL(PROTOCOL_UNSUPPORTED);
-    RETURN_STRING_LITERAL(PROTOCOL_QUIC_CRYPTO);
-    RETURN_STRING_LITERAL(PROTOCOL_TLS1_3);
-  }
-  return absl::StrCat("PROTOCOL_UNKNOWN(", static_cast<int>(handshake_protocol),
-                      ")");
-}
-
-std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  if (version == UnsupportedQuicVersion()) {
-    return "0";
-  } else if (version == ParsedQuicVersion::V2Draft01()) {
-    QUICHE_DCHECK(version.UsesHttp3());
-    return "v2draft01";
-  } else if (version == ParsedQuicVersion::RFCv1()) {
-    QUICHE_DCHECK(version.UsesHttp3());
-    return "RFCv1";
-  } else if (version == ParsedQuicVersion::Draft29()) {
-    QUICHE_DCHECK(version.UsesHttp3());
-    return "draft29";
-  }
-
-  return QuicVersionLabelToString(CreateQuicVersionLabel(version));
-}
-
-std::string QuicTransportVersionVectorToString(
-    const QuicTransportVersionVector& versions) {
-  std::string result = "";
-  for (size_t i = 0; i < versions.size(); ++i) {
-    if (i != 0) {
-      result.append(",");
-    }
-    result.append(QuicVersionToString(versions[i]));
-  }
-  return result;
-}
-
-std::string ParsedQuicVersionVectorToString(
-    const ParsedQuicVersionVector& versions, const std::string& separator,
-    size_t skip_after_nth_version) {
-  std::string result;
-  for (size_t i = 0; i < versions.size(); ++i) {
-    if (i != 0) {
-      result.append(separator);
-    }
-    if (i > skip_after_nth_version) {
-      result.append("...");
-      break;
-    }
-    result.append(ParsedQuicVersionToString(versions[i]));
-  }
-  return result;
-}
-
-bool VersionSupportsGoogleAltSvcFormat(QuicTransportVersion transport_version) {
-  return transport_version <= QUIC_VERSION_46;
-}
-
-bool VersionAllowsVariableLengthConnectionIds(
-    QuicTransportVersion transport_version) {
-  QUICHE_DCHECK_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
-  return transport_version > QUIC_VERSION_46;
-}
-
-bool QuicVersionLabelUses4BitConnectionIdLength(
-    QuicVersionLabel version_label) {
-  // As we deprecate old versions, we still need the ability to send valid
-  // version negotiation packets for those versions. This function keeps track
-  // of the versions that ever supported the 4bit connection ID length encoding
-  // that we know about. Google QUIC 43 and earlier used a different encoding,
-  // and Google QUIC 49 and later use the new length prefixed encoding.
-  // Similarly, only IETF drafts 11 to 21 used this encoding.
-
-  // Check Q044, Q045, Q046, Q047 and Q048.
-  for (uint8_t c = '4'; c <= '8'; ++c) {
-    if (version_label == MakeVersionLabel('Q', '0', '4', c)) {
-      return true;
-    }
-  }
-  // Check T048.
-  if (version_label == MakeVersionLabel('T', '0', '4', '8')) {
-    return true;
-  }
-  // Check IETF draft versions in [11,21].
-  for (uint8_t draft_number = 11; draft_number <= 21; ++draft_number) {
-    if (version_label == MakeVersionLabel(0xff, 0x00, 0x00, draft_number)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-ParsedQuicVersion UnsupportedQuicVersion() {
-  return ParsedQuicVersion::Unsupported();
-}
-
-ParsedQuicVersion QuicVersionReservedForNegotiation() {
-  return ParsedQuicVersion::ReservedForNegotiation();
-}
-
-ParsedQuicVersion LegacyVersionForEncapsulation() {
-  return ParsedQuicVersion::Q043();
-}
-
-std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
-  if (parsed_version == ParsedQuicVersion::V2Draft01()) {
-    return "h3";
-  } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
-    return "h3";
-  } else if (parsed_version == ParsedQuicVersion::Draft29()) {
-    return "h3-29";
-  }
-  return "h3-" + ParsedQuicVersionToString(parsed_version);
-}
-
-void QuicVersionInitializeSupportForIetfDraft() {
-  // Enable necessary flags.
-}
-
-void QuicEnableVersion(const ParsedQuicVersion& version) {
-  SetVersionFlag(version, /*should_enable=*/true);
-}
-
-void QuicDisableVersion(const ParsedQuicVersion& version) {
-  SetVersionFlag(version, /*should_enable=*/false);
-}
-
-bool QuicVersionIsEnabled(const ParsedQuicVersion& version) {
-  ParsedQuicVersionVector current = CurrentSupportedVersions();
-  return std::find(current.begin(), current.end(), version) != current.end();
-}
-
-#undef RETURN_STRING_LITERAL  // undef for jumbo builds
-}  // namespace quic
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
deleted file mode 100644
index 59bf753..0000000
--- a/quic/core/quic_versions.h
+++ /dev/null
@@ -1,652 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Definitions and utility functions related to handling of QUIC versions.
-//
-// QUIC versions are encoded over the wire as an opaque 32bit field. The wire
-// encoding is represented in memory as a QuicVersionLabel type (which is an
-// alias to uint32_t). Conceptual versions are represented in memory as
-// ParsedQuicVersion.
-//
-// We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
-//
-// All GoogleQUIC versions use a wire encoding that matches the following regex
-// when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
-// type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
-// handshake), and the two digits at the end contain the numeric value of
-// the transport version used.
-//
-// All IETF QUIC versions use the wire encoding described in:
-// https://tools.ietf.org/html/draft-ietf-quic-transport
-
-#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
-#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_tag.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The list of existing QUIC transport versions. Note that QUIC versions are
-// sent over the wire as an encoding of ParsedQuicVersion, which requires a
-// QUIC transport version and handshake protocol. For transport versions of the
-// form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
-// guaranteed to match the name. Older deprecated transport versions are
-// documented in comments below.
-enum QuicTransportVersion {
-  // Special case to indicate unknown/unsupported QUIC version.
-  QUIC_VERSION_UNSUPPORTED = 0,
-
-  // Version 1 was the first version of QUIC that supported versioning.
-  // Version 2 decoupled versioning of non-cryptographic parameters from the
-  //           SCFG.
-  // Version 3 moved public flags into the beginning of the packet.
-  // Version 4 added support for variable-length connection IDs.
-  // Version 5 made specifying FEC groups optional.
-  // Version 6 introduced variable-length packet numbers.
-  // Version 7 introduced a lower-overhead encoding for stream frames.
-  // Version 8 made salt length equal to digest length for the RSA-PSS
-  //           signatures.
-  // Version 9 added stream priority.
-  // Version 10 redid the frame type numbering.
-  // Version 11 reduced the length of null encryption authentication tag
-  //            from 16 to 12 bytes.
-  // Version 12 made the sequence numbers in the ACK frames variable-sized.
-  // Version 13 added the dedicated header stream.
-  // Version 14 added byte_offset to RST_STREAM frame.
-  // Version 15 added a list of packets recovered using FEC to the ACK frame.
-  // Version 16 added STOP_WAITING frame.
-  // Version 17 added per-stream flow control.
-  // Version 18 added PING frame.
-  // Version 19 added connection-level flow control
-  // Version 20 allowed to set stream- and connection-level flow control windows
-  //            to different values.
-  // Version 21 made header and crypto streams flow-controlled.
-  // Version 22 added support for SCUP (server config update) messages.
-  // Version 23 added timestamps into the ACK frame.
-  // Version 24 added SPDY/4 header compression.
-  // Version 25 added support for SPDY/4 header keys and removed error_details
-  //            from RST_STREAM frame.
-  // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
-  // Version 27 added a nonce into SHLO.
-  // Version 28 allowed receiver to refuse creating a requested stream.
-  // Version 29 added support for QUIC_STREAM_NO_ERROR.
-  // Version 30 added server-side support for certificate transparency.
-  // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
-  //            the server.
-  // Version 32 removed FEC-related fields from wire format.
-  // Version 33 added diversification nonces.
-  // Version 34 removed entropy bits from packets and ACK frames, removed
-  //            private flag from packet header and changed the ACK format to
-  //            specify ranges of packets acknowledged rather than missing
-  //            ranges.
-  // Version 35 allows endpoints to independently set stream limit.
-  // Version 36 added support for forced head-of-line blocking experiments.
-  // Version 37 added perspective into null encryption.
-  // Version 38 switched to IETF padding frame format and support for NSTP (no
-  //            stop waiting frame) connection option.
-
-  // Version 39 writes integers and floating numbers in big endian, stops acking
-  // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do
-  // not contain retransmittable frames.
-
-  // Version 40 was an attempt to convert QUIC to IETF frame format; it was
-  //            never shipped due to a bug.
-  // Version 41 was a bugfix for version 40.  The working group changed the wire
-  //            format before it shipped, which caused it to be never shipped
-  //            and all the changes from it to be reverted.  No changes from v40
-  //            or v41 are present in subsequent versions.
-  // Version 42 allowed receiving overlapping stream data.
-
-  QUIC_VERSION_43 = 43,  // PRIORITY frames are sent by client and accepted by
-                         // server.
-  // Version 44 used IETF header format from draft-ietf-quic-invariants-05.
-
-  // Version 45 added MESSAGE frame.
-
-  QUIC_VERSION_46 = 46,  // Use IETF draft-17 header format with demultiplexing
-                         // bit.
-  // Version 47 added variable-length QUIC server connection IDs.
-  // Version 48 added CRYPTO frames for the handshake.
-  // Version 49 added client connection IDs, long header lengths, and the IETF
-  // header format from draft-ietf-quic-invariants-06
-  QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
-  // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
-  // Number 70 used to represent draft-ietf-quic-transport-25.
-  // Number 71 used to represent draft-ietf-quic-transport-27.
-  // Number 72 used to represent draft-ietf-quic-transport-28.
-  QUIC_VERSION_IETF_DRAFT_29 = 73,    // draft-ietf-quic-transport-29.
-  QUIC_VERSION_IETF_RFC_V1 = 80,      // RFC 9000.
-  QUIC_VERSION_IETF_2_DRAFT_01 = 81,  // draft-ietf-quic-v2-01.
-  // Version 99 was a dumping ground for IETF QUIC changes which were not yet
-  // ready for production between 2018-02 and 2020-02.
-
-  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
-  // which is part of a range reserved by the IETF for version negotiation
-  // testing (see the "Versions" section of draft-ietf-quic-transport).
-  // This version is intentionally meant to never be supported to trigger
-  // version negotiation when proposed by clients and to prevent client
-  // ossification when sent by servers.
-  QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
-};
-
-// Helper function which translates from a QuicTransportVersion to a string.
-// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
-QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
-    QuicTransportVersion transport_version);
-
-// The crypto handshake protocols that can be used with QUIC.
-// We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
-// PROTOCOL_TLS1_3.
-enum HandshakeProtocol {
-  PROTOCOL_UNSUPPORTED,
-  PROTOCOL_QUIC_CRYPTO,
-  PROTOCOL_TLS1_3,
-};
-
-// Helper function which translates from a HandshakeProtocol to a string.
-QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString(
-    HandshakeProtocol handshake_protocol);
-
-// Returns whether |transport_version| uses CRYPTO frames for the handshake
-// instead of stream 1.
-QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames(
-    QuicTransportVersion transport_version) {
-  // CRYPTO frames were added in version 48.
-  return transport_version > QUIC_VERSION_46;
-}
-
-// Returns whether this combination of handshake protocol and transport
-// version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT
-// allowed as TLS requires crypto frames which v43 does not support. Note that
-// UnsupportedQuicVersion is a valid version.
-QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
-    HandshakeProtocol handshake_protocol,
-    QuicTransportVersion transport_version) {
-  bool transport_version_is_valid = false;
-  constexpr QuicTransportVersion valid_transport_versions[] = {
-      QUIC_VERSION_IETF_2_DRAFT_01,
-      QUIC_VERSION_IETF_RFC_V1,
-      QUIC_VERSION_IETF_DRAFT_29,
-      QUIC_VERSION_50,
-      QUIC_VERSION_46,
-      QUIC_VERSION_43,
-      QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
-      QUIC_VERSION_UNSUPPORTED,
-  };
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
-    if (transport_version == valid_transport_versions[i]) {
-      transport_version_is_valid = true;
-      break;
-    }
-  }
-  if (!transport_version_is_valid) {
-    return false;
-  }
-  switch (handshake_protocol) {
-    case PROTOCOL_UNSUPPORTED:
-      return transport_version == QUIC_VERSION_UNSUPPORTED;
-    case PROTOCOL_QUIC_CRYPTO:
-      return transport_version != QUIC_VERSION_UNSUPPORTED &&
-             transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
-             transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
-             transport_version != QUIC_VERSION_IETF_RFC_V1 &&
-             transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
-    case PROTOCOL_TLS1_3:
-      return transport_version != QUIC_VERSION_UNSUPPORTED &&
-             transport_version != QUIC_VERSION_50 &&
-             QuicVersionUsesCryptoFrames(transport_version);
-  }
-  return false;
-}
-
-// A parsed QUIC version label which determines that handshake protocol
-// and the transport version.
-struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
-  HandshakeProtocol handshake_protocol;
-  QuicTransportVersion transport_version;
-
-  constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
-                              QuicTransportVersion transport_version)
-      : handshake_protocol(handshake_protocol),
-        transport_version(transport_version) {
-    QUICHE_DCHECK(
-        ParsedQuicVersionIsValid(handshake_protocol, transport_version))
-        << QuicVersionToString(transport_version) << " "
-        << HandshakeProtocolToString(handshake_protocol);
-  }
-
-  constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
-      : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}
-
-  ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
-    QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
-                                           other.transport_version))
-        << QuicVersionToString(other.transport_version) << " "
-        << HandshakeProtocolToString(other.handshake_protocol);
-    if (this != &other) {
-      handshake_protocol = other.handshake_protocol;
-      transport_version = other.transport_version;
-    }
-    return *this;
-  }
-
-  bool operator==(const ParsedQuicVersion& other) const {
-    return handshake_protocol == other.handshake_protocol &&
-           transport_version == other.transport_version;
-  }
-
-  bool operator!=(const ParsedQuicVersion& other) const {
-    return handshake_protocol != other.handshake_protocol ||
-           transport_version != other.transport_version;
-  }
-
-  static constexpr ParsedQuicVersion V2Draft01() {
-    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
-  }
-
-  static constexpr ParsedQuicVersion RFCv1() {
-    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
-  }
-
-  static constexpr ParsedQuicVersion Draft29() {
-    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
-  }
-
-  static constexpr ParsedQuicVersion Q050() {
-    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
-  }
-
-  static constexpr ParsedQuicVersion Q046() {
-    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
-  }
-
-  static constexpr ParsedQuicVersion Q043() {
-    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
-  }
-
-  static constexpr ParsedQuicVersion Unsupported() {
-    return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
-  }
-
-  static constexpr ParsedQuicVersion ReservedForNegotiation() {
-    return ParsedQuicVersion(PROTOCOL_TLS1_3,
-                             QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
-  }
-
-  // Returns whether our codebase understands this version. This should only be
-  // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
-  // version is valid, IsKnown returns whether the version is not
-  // UnsupportedQuicVersion.
-  bool IsKnown() const;
-
-  bool KnowsWhichDecrypterToUse() const;
-
-  // Returns whether this version uses keys derived from the Connection ID for
-  // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
-  bool UsesInitialObfuscators() const;
-
-  // Indicates that this QUIC version does not have an enforced minimum value
-  // for flow control values negotiated during the handshake.
-  bool AllowsLowFlowControlLimits() const;
-
-  // Returns whether header protection is used in this version of QUIC.
-  bool HasHeaderProtection() const;
-
-  // Returns whether this version supports IETF RETRY packets.
-  bool SupportsRetry() const;
-
-  // Returns true if this version sends variable length packet number in long
-  // header.
-  bool SendsVariableLengthPacketNumberInLongHeader() const;
-
-  // Returns whether this version allows server connection ID lengths
-  // that are not 64 bits.
-  bool AllowsVariableLengthConnectionIds() const;
-
-  // Returns whether this version supports client connection ID.
-  bool SupportsClientConnectionIds() const;
-
-  // Returns whether this version supports long header 8-bit encoded
-  // connection ID lengths as described in draft-ietf-quic-invariants-06 and
-  // draft-ietf-quic-transport-22.
-  bool HasLengthPrefixedConnectionIds() const;
-
-  // Returns whether this version supports IETF style anti-amplification limit,
-  // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
-  // times received bytes until address can be validated.
-  bool SupportsAntiAmplificationLimit() const;
-
-  // Returns true if this version can send coalesced packets.
-  bool CanSendCoalescedPackets() const;
-
-  // Returns true if this version supports the old Google-style Alt-Svc
-  // advertisement format.
-  bool SupportsGoogleAltSvcFormat() const;
-
-  // Returns true if |transport_version| uses IETF invariant headers.
-  bool HasIetfInvariantHeader() const;
-
-  // Returns true if |transport_version| supports MESSAGE frames.
-  bool SupportsMessageFrames() const;
-
-  // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
-  // Notable changes are:
-  // * Headers stream no longer exists.
-  // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
-  // * PUSH_PROMISE is moved to request stream.
-  // * Unidirectional streams will have their first byte as a stream type.
-  // * HEADERS frames are compressed using QPACK.
-  // * DATA frame has frame headers.
-  // * GOAWAY is moved to HTTP layer.
-  bool UsesHttp3() const;
-
-  // Returns whether the transport_version supports the variable length integer
-  // length field as defined by IETF QUIC draft-13 and later.
-  bool HasLongHeaderLengths() const;
-
-  // Returns whether |transport_version| uses CRYPTO frames for the handshake
-  // instead of stream 1.
-  bool UsesCryptoFrames() const;
-
-  // Returns whether |transport_version| makes use of IETF QUIC
-  // frames or not.
-  bool HasIetfQuicFrames() const;
-
-  // Returns whether this version uses the legacy TLS extension codepoint.
-  bool UsesLegacyTlsExtension() const;
-
-  // Returns whether this version uses PROTOCOL_TLS1_3.
-  bool UsesTls() const;
-
-  // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
-  bool UsesQuicCrypto() const;
-
-  // Returns whether this version uses the QUICv2 Long Header Packet Types.
-  bool UsesV2PacketTypes() const;
-
-  // Returns true if this shares ALPN codes with RFCv1, and endpoints should
-  // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
-  // RFCv1.
-  bool AlpnDeferToRFCv1() const;
-};
-
-QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
-
-QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
-
-// Outer version used when encapsulating other packets using the Legacy Version
-// Encapsulation feature.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                             const ParsedQuicVersion& version);
-
-using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const ParsedQuicVersionVector& versions);
-
-// Representation of the on-the-wire QUIC version number. Will be written/read
-// to the wire in network-byte-order.
-using QuicVersionLabel = uint32_t;
-using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
-
-// Constructs a version label from the 4 bytes such that the on-the-wire
-// order will be: d, c, b, a.
-QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
-                                                      uint8_t c, uint8_t d);
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const QuicVersionLabelVector& version_labels);
-
-// This vector contains all crypto handshake protocols that are supported.
-constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
-  return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
-}
-
-constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
-  return {
-      ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
-      ParsedQuicVersion::Draft29(),   ParsedQuicVersion::Q050(),
-      ParsedQuicVersion::Q046(),      ParsedQuicVersion::Q043(),
-  };
-}
-
-using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
-
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-    std::ostream& os, const QuicTransportVersionVector& transport_versions);
-
-// Returns a vector of supported QUIC versions.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
-
-// Returns a vector of supported QUIC versions, with any versions disabled by
-// flags excluded.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
-
-// Returns a vector of QUIC versions from |versions| which exclude any versions
-// which are disabled by flags.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-FilterSupportedVersions(ParsedQuicVersionVector versions);
-
-// Returns a subset of AllSupportedVersions() with
-// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
-// Deprecated; only to be used in components that do not yet support
-// PROTOCOL_TLS1_3.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-AllSupportedVersionsWithQuicCrypto();
-
-// Returns a subset of CurrentSupportedVersions() with
-// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-CurrentSupportedVersionsWithQuicCrypto();
-
-// Returns a subset of AllSupportedVersions() with
-// handshake_protocol == PROTOCOL_TLS1_3, in the same order.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls();
-
-// Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
-// PROTOCOL_TLS1_3.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls();
-
-// Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
-// layer.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions();
-
-// Returns QUIC version of |index| in result of |versions|. Returns
-// UnsupportedQuicVersion() if |index| is out of bounds.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
-
-// QuicVersionLabel is written to and read from the wire, but we prefer to use
-// the more readable ParsedQuicVersion at other levels.
-// Helper function which translates from a QuicVersionLabel to a
-// ParsedQuicVersion.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion
-ParseQuicVersionLabel(QuicVersionLabel version_label);
-
-// Helper function that translates from a QuicVersionLabelVector to a
-// ParsedQuicVersionVector.
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);
-
-// Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
-// ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
-// supports parsing numbers such as "46".
-QUIC_EXPORT_PRIVATE ParsedQuicVersion
-ParseQuicVersionString(absl::string_view version_string);
-
-// Parses a comma-separated list of QUIC version strings. Supports parsing by
-// label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
-// For example: "h3-29,Q050,46".
-QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
-ParseQuicVersionVectorString(absl::string_view versions_string);
-
-// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
-// QuicVersionLabel is written to and read from the wire, but we prefer to use
-// the more readable ParsedQuicVersion at other levels.
-// Helper function which translates from a ParsedQuicVersion to a
-// QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
-QUIC_EXPORT_PRIVATE QuicVersionLabel
-CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
-
-// Constructs a QuicVersionLabelVector from the provided
-// ParsedQuicVersionVector.
-QUIC_EXPORT_PRIVATE QuicVersionLabelVector
-CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
-
-// Helper function which translates from a QuicVersionLabel to a string.
-QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
-    QuicVersionLabel version_label);
-
-// Helper function which translates from a QuicVersionLabel string to a
-// ParsedQuicVersion. The version label string must be of the form returned
-// by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
-// "51303433" (the hex encoding of the Q064 version label). Returns
-// the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
-// otherwise.
-QUIC_EXPORT_PRIVATE ParsedQuicVersion
-ParseQuicVersionLabelString(absl::string_view version_label_string);
-
-// Returns |separator|-separated list of string representations of
-// QuicVersionLabel values in the supplied |version_labels| vector. The values
-// after the (0-based) |skip_after_nth_version|'th are skipped.
-QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
-    const QuicVersionLabelVector& version_labels, const std::string& separator,
-    size_t skip_after_nth_version);
-
-// Returns comma separated list of string representations of QuicVersionLabel
-// values in the supplied |version_labels| vector.
-QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
-    const QuicVersionLabelVector& version_labels) {
-  return QuicVersionLabelVectorToString(version_labels, ",",
-                                        std::numeric_limits<size_t>::max());
-}
-
-// Helper function which translates from a ParsedQuicVersion to a string.
-// Returns strings corresponding to the on-the-wire tag.
-QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
-    ParsedQuicVersion version);
-
-// Returns a vector of supported QUIC transport versions. DEPRECATED, use
-// AllSupportedVersions instead.
-QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
-
-// Returns comma separated list of string representations of
-// QuicTransportVersion enum values in the supplied |versions| vector.
-QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
-    const QuicTransportVersionVector& versions);
-
-// Returns comma separated list of string representations of ParsedQuicVersion
-// values in the supplied |versions| vector.
-QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
-    const ParsedQuicVersionVector& versions);
-
-// Returns |separator|-separated list of string representations of
-// ParsedQuicVersion values in the supplied |versions| vector. The values after
-// the (0-based) |skip_after_nth_version|'th are skipped.
-QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
-    const ParsedQuicVersionVector& versions, const std::string& separator,
-    size_t skip_after_nth_version);
-
-// Returns comma separated list of string representations of ParsedQuicVersion
-// values in the supplied |versions| vector.
-QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
-    const ParsedQuicVersionVector& versions) {
-  return ParsedQuicVersionVectorToString(versions, ",",
-                                         std::numeric_limits<size_t>::max());
-}
-
-// Returns true if |transport_version| uses IETF invariant headers.
-QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader(
-    QuicTransportVersion transport_version) {
-  return transport_version > QUIC_VERSION_43;
-}
-
-// Returns true if |transport_version| supports MESSAGE frames.
-QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames(
-    QuicTransportVersion transport_version) {
-  // MESSAGE frames were added in version 45.
-  return transport_version > QUIC_VERSION_43;
-}
-
-// If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
-// Notable changes are:
-// * Headers stream no longer exists.
-// * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
-// * PUSH_PROMISE is moved to request stream.
-// * Unidirectional streams will have their first byte as a stream type.
-// * HEADERS frames are compressed using QPACK.
-// * DATA frame has frame headers.
-// * GOAWAY is moved to HTTP layer.
-QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
-    QuicTransportVersion transport_version) {
-  return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
-}
-
-// Returns whether the transport_version supports the variable length integer
-// length field as defined by IETF QUIC draft-13 and later.
-QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths(
-    QuicTransportVersion transport_version) {
-  // Long header lengths were added in version 49.
-  return transport_version > QUIC_VERSION_46;
-}
-
-// Returns whether |transport_version| makes use of IETF QUIC
-// frames or not.
-QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
-    QuicTransportVersion transport_version) {
-  return VersionUsesHttp3(transport_version);
-}
-
-// Returns whether this version supports long header 8-bit encoded
-// connection ID lengths as described in draft-ietf-quic-invariants-06 and
-// draft-ietf-quic-transport-22.
-QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds(
-    QuicTransportVersion transport_version);
-
-// Returns true if this version supports the old Google-style Alt-Svc
-// advertisement format.
-QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat(
-    QuicTransportVersion transport_version);
-
-// Returns whether this version allows server connection ID lengths that are
-// not 64 bits.
-QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds(
-    QuicTransportVersion transport_version);
-
-// Returns whether this version label supports long header 4-bit encoded
-// connection ID lengths as described in draft-ietf-quic-invariants-05 and
-// draft-ietf-quic-transport-21.
-QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength(
-    QuicVersionLabel version_label);
-
-// Returns the ALPN string to use in TLS for this version of QUIC.
-QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
-    ParsedQuicVersion parsed_version);
-
-// Initializes support for the provided IETF draft version by setting the
-// correct flags.
-QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();
-
-// Configures the flags required to enable support for this version of QUIC.
-QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);
-
-// Configures the flags required to disable support for this version of QUIC.
-QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);
-
-// Returns whether support for this version of QUIC is currently enabled.
-QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
deleted file mode 100644
index 8d420ac..0000000
--- a/quic/core/quic_versions_test.cc
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_versions.h"
-
-#include "absl/base/macros.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mock_log.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
-  EXPECT_QUIC_BUG(
-      CreateQuicVersionLabel(UnsupportedQuicVersion()),
-      "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
-}
-
-TEST(QuicVersionsTest, KnownAndValid) {
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_TRUE(version.IsKnown());
-    EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
-                                         version.transport_version));
-  }
-  ParsedQuicVersion unsupported = UnsupportedQuicVersion();
-  EXPECT_FALSE(unsupported.IsKnown());
-  EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
-                                       unsupported.transport_version));
-  ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
-  EXPECT_TRUE(reserved.IsKnown());
-  EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
-                                       reserved.transport_version));
-  // Check that invalid combinations are not valid.
-  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_43));
-  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
-                                        QUIC_VERSION_IETF_DRAFT_29));
-  // Check that deprecated versions are not valid.
-  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
-                                        static_cast<QuicTransportVersion>(33)));
-  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
-                                        static_cast<QuicTransportVersion>(99)));
-  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
-                                        static_cast<QuicTransportVersion>(99)));
-}
-
-TEST(QuicVersionsTest, Features) {
-  ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
-  ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
-
-  EXPECT_TRUE(parsed_version_q043.IsKnown());
-  EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
-  EXPECT_FALSE(parsed_version_q043.UsesInitialObfuscators());
-  EXPECT_FALSE(parsed_version_q043.AllowsLowFlowControlLimits());
-  EXPECT_FALSE(parsed_version_q043.HasHeaderProtection());
-  EXPECT_FALSE(parsed_version_q043.SupportsRetry());
-  EXPECT_FALSE(
-      parsed_version_q043.SendsVariableLengthPacketNumberInLongHeader());
-  EXPECT_FALSE(parsed_version_q043.AllowsVariableLengthConnectionIds());
-  EXPECT_FALSE(parsed_version_q043.SupportsClientConnectionIds());
-  EXPECT_FALSE(parsed_version_q043.HasLengthPrefixedConnectionIds());
-  EXPECT_FALSE(parsed_version_q043.SupportsAntiAmplificationLimit());
-  EXPECT_FALSE(parsed_version_q043.CanSendCoalescedPackets());
-  EXPECT_TRUE(parsed_version_q043.SupportsGoogleAltSvcFormat());
-  EXPECT_FALSE(parsed_version_q043.HasIetfInvariantHeader());
-  EXPECT_FALSE(parsed_version_q043.SupportsMessageFrames());
-  EXPECT_FALSE(parsed_version_q043.UsesHttp3());
-  EXPECT_FALSE(parsed_version_q043.HasLongHeaderLengths());
-  EXPECT_FALSE(parsed_version_q043.UsesCryptoFrames());
-  EXPECT_FALSE(parsed_version_q043.HasIetfQuicFrames());
-  EXPECT_FALSE(parsed_version_q043.UsesTls());
-  EXPECT_TRUE(parsed_version_q043.UsesQuicCrypto());
-
-  EXPECT_TRUE(parsed_version_draft_29.IsKnown());
-  EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
-  EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
-  EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
-  EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
-  EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
-  EXPECT_TRUE(
-      parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
-  EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
-  EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
-  EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
-  EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
-  EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
-  EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
-  EXPECT_TRUE(parsed_version_draft_29.HasIetfInvariantHeader());
-  EXPECT_TRUE(parsed_version_draft_29.SupportsMessageFrames());
-  EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
-  EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
-  EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
-  EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
-  EXPECT_TRUE(parsed_version_draft_29.UsesTls());
-  EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionLabel) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  EXPECT_EQ(ParsedQuicVersion::Q043(),
-            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
-  EXPECT_EQ(ParsedQuicVersion::Q046(),
-            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
-  EXPECT_EQ(ParsedQuicVersion::Q050(),
-            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
-  EXPECT_EQ(ParsedQuicVersion::Draft29(),
-            ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
-  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
-            ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
-  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
-            ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
-  EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
-                                     ParsedQuicVersion::RFCv1(),
-                                     ParsedQuicVersion::Draft29()}),
-            ParseQuicVersionLabelVector(QuicVersionLabelVector{
-                MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
-                MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
-                MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
-                MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
-
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
-  }
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionString) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
-  EXPECT_EQ(ParsedQuicVersion::Q046(),
-            ParseQuicVersionString("QUIC_VERSION_46"));
-  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
-  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
-  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
-  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
-  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
-
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
-
-  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
-  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
-  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
-
-  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
-  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
-
-  // QUICv2 will never be the result for "h3".
-
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_EQ(version,
-              ParseQuicVersionString(ParsedQuicVersionToString(version)));
-    EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
-                           CreateQuicVersionLabel(version))));
-    if (!version.AlpnDeferToRFCv1()) {
-      EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
-    }
-  }
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
-  ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
-  ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
-  ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
-
-  EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
-
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
-              ElementsAre(version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
-              ElementsAre(version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
-              ElementsAre(version_q050, version_draft_29));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
-              ElementsAre(version_draft_29, version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
-              ElementsAre(version_draft_29, version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
-              ElementsAre(version_draft_29, version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
-              ElementsAre(version_q050, version_draft_29));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
-              ElementsAre(version_draft_29, version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
-              ElementsAre(version_q050, version_draft_29));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
-              ElementsAre(version_draft_29, version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
-              ElementsAre(version_q050, version_q046));
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
-              ElementsAre(version_q046, version_q050));
-
-  // Regression test for https://crbug.com/1044952.
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
-              ElementsAre(version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
-              ElementsAre(version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
-              ElementsAre(version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString(
-                  "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
-              ElementsAre(version_q050));
-  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
-              ElementsAre(version_q050, version_draft_29));
-
-  EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
-  EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
-  EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
-              ElementsAre(version_draft_29));
-}
-
-// Do not use MakeVersionLabel() to generate expectations, because
-// CreateQuicVersionLabel() uses MakeVersionLabel() internally,
-// in case it has a bug.
-TEST(QuicVersionsTest, CreateQuicVersionLabel) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  EXPECT_EQ(0x51303433u, CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
-  EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
-  EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
-  EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
-  EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
-  EXPECT_EQ(0x709a50c4u,
-            CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));
-
-  // Make sure the negotiation reserved version is in the IETF reserved space.
-  EXPECT_EQ(
-      0xda5a3a3au & 0x0f0f0f0f,
-      CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
-          0x0f0f0f0f);
-
-  // Make sure that disabling randomness works.
-  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
-  EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
-                             ParsedQuicVersion::ReservedForNegotiation()));
-}
-
-TEST(QuicVersionsTest, QuicVersionLabelToString) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  EXPECT_EQ("Q043", QuicVersionLabelToString(
-                        CreateQuicVersionLabel(ParsedQuicVersion::Q043())));
-  EXPECT_EQ("Q046", QuicVersionLabelToString(
-                        CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
-  EXPECT_EQ("Q050", QuicVersionLabelToString(
-                        CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
-  EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
-                            ParsedQuicVersion::Draft29())));
-  EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
-                            ParsedQuicVersion::RFCv1())));
-  EXPECT_EQ("709a50c4", QuicVersionLabelToString(CreateQuicVersionLabel(
-                            ParsedQuicVersion::V2Draft01())));
-
-  QuicVersionLabelVector version_labels = {
-      MakeVersionLabel('Q', '0', '3', '5'),
-      MakeVersionLabel('T', '0', '3', '8'),
-      MakeVersionLabel(0xff, 0, 0, 7),
-  };
-
-  EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
-  EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
-  EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
-
-  EXPECT_EQ("Q035,T038,ff000007",
-            QuicVersionLabelVectorToString(version_labels));
-  EXPECT_EQ("Q035:T038:ff000007",
-            QuicVersionLabelVectorToString(version_labels, ":", 2));
-  EXPECT_EQ("Q035|T038|...",
-            QuicVersionLabelVectorToString(version_labels, "|", 1));
-
-  std::ostringstream os;
-  os << version_labels;
-  EXPECT_EQ("Q035,T038,ff000007", os.str());
-}
-
-TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  // Explicitly test known QUIC version label strings.
-  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionLabelString("Q043"));
-  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
-  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
-  EXPECT_EQ(ParsedQuicVersion::Draft29(),
-            ParseQuicVersionLabelString("ff00001d"));
-  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
-            ParseQuicVersionLabelString("00000001"));
-  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
-            ParseQuicVersionLabelString("709a50c4"));
-
-  // Sanity check that a variety of other serialization formats are ignored.
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
-  EXPECT_EQ(UnsupportedQuicVersion(),
-            ParseQuicVersionLabelString("QUIC_VERSION_46"));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
-  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
-
-  // Test round-trips between QuicVersionLabelToString and
-  // ParseQuicVersionLabelString.
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
-                           CreateQuicVersionLabel(version))));
-  }
-}
-
-TEST(QuicVersionsTest, QuicVersionToString) {
-  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
-            QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
-
-  QuicTransportVersion single_version[] = {QUIC_VERSION_43};
-  QuicTransportVersionVector versions_vector;
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
-    versions_vector.push_back(single_version[i]);
-  }
-  EXPECT_EQ("QUIC_VERSION_43",
-            QuicTransportVersionVectorToString(versions_vector));
-
-  QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
-                                              QUIC_VERSION_43};
-  versions_vector.clear();
-  for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
-    versions_vector.push_back(multiple_versions[i]);
-  }
-  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43",
-            QuicTransportVersionVectorToString(versions_vector));
-
-  // Make sure that all supported versions are present in QuicVersionToString.
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
-              QuicVersionToString(version.transport_version));
-  }
-
-  std::ostringstream os;
-  os << versions_vector;
-  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
-}
-
-TEST(QuicVersionsTest, ParsedQuicVersionToString) {
-  EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
-  EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
-  EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
-  EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
-  EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
-  EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
-  EXPECT_EQ("v2draft01",
-            ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));
-
-  ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
-  EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
-
-  versions_vector = {ParsedQuicVersion::Unsupported(),
-                     ParsedQuicVersion::Q043()};
-  EXPECT_EQ("0,Q043", ParsedQuicVersionVectorToString(versions_vector));
-  EXPECT_EQ("0:Q043", ParsedQuicVersionVectorToString(versions_vector, ":",
-                                                      versions_vector.size()));
-  EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
-
-  // Make sure that all supported versions are present in
-  // ParsedQuicVersionToString.
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_NE("0", ParsedQuicVersionToString(version));
-  }
-
-  std::ostringstream os;
-  os << versions_vector;
-  EXPECT_EQ("0,Q043", os.str());
-}
-
-TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    QuicEnableVersion(version);
-  }
-  ParsedQuicVersionVector expected_parsed_versions;
-  for (const ParsedQuicVersion& version : SupportedVersions()) {
-    expected_parsed_versions.push_back(version);
-  }
-  EXPECT_EQ(expected_parsed_versions,
-            FilterSupportedVersions(AllSupportedVersions()));
-  EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
-}
-
-TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    QuicEnableVersion(version);
-  }
-  QuicDisableVersion(AllSupportedVersions().front());
-  ParsedQuicVersionVector expected_parsed_versions;
-  for (const ParsedQuicVersion& version : SupportedVersions()) {
-    expected_parsed_versions.push_back(version);
-  }
-  expected_parsed_versions.erase(expected_parsed_versions.begin());
-  EXPECT_EQ(expected_parsed_versions,
-            FilterSupportedVersions(AllSupportedVersions()));
-}
-
-TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
-  ParsedQuicVersionVector all_versions = AllSupportedVersions();
-  int version_count = all_versions.size();
-  for (int i = -5; i <= version_count + 1; ++i) {
-    ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
-    if (i >= 0 && i < version_count) {
-      EXPECT_EQ(all_versions[i], index[0]);
-    } else {
-      EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
-    }
-  }
-}
-
-// This test may appear to be so simplistic as to be unnecessary,
-// yet a typo was made in doing the #defines and it was caught
-// only in some test far removed from here... Better safe than sorry.
-TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  EXPECT_EQ(QUIC_VERSION_43, 43);
-  EXPECT_EQ(QUIC_VERSION_46, 46);
-  EXPECT_EQ(QUIC_VERSION_50, 50);
-  EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
-  EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
-  EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
-}
-
-TEST(QuicVersionsTest, AlpnForVersion) {
-  static_assert(SupportedVersions().size() == 6u,
-                "Supported versions out of sync");
-  EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
-  EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
-  EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
-  EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
-  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
-  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
-}
-
-TEST(QuicVersionsTest, QuicVersionEnabling) {
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    QuicFlagSaver flag_saver;
-    QuicDisableVersion(version);
-    EXPECT_FALSE(QuicVersionIsEnabled(version));
-    QuicEnableVersion(version);
-    EXPECT_TRUE(QuicVersionIsEnabled(version));
-  }
-}
-
-TEST(QuicVersionsTest, ReservedForNegotiation) {
-  EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
-            QuicVersionReservedForNegotiation().transport_version);
-  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
-  }
-}
-
-TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
-  size_t index = 0;
-  for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
-    for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
-      QuicTransportVersion transport_version =
-          static_cast<QuicTransportVersion>(trans_vers);
-      SCOPED_TRACE(index);
-      if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
-        ParsedQuicVersion version = SupportedVersions()[index];
-        EXPECT_EQ(version,
-                  ParsedQuicVersion(handshake_protocol, transport_version));
-        index++;
-      }
-    }
-  }
-  EXPECT_EQ(SupportedVersions().size(), index);
-}
-
-TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
-  for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
-    ParsedQuicVersion version1 = SupportedVersions()[index1];
-    for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
-         ++index2) {
-      ParsedQuicVersion version2 = SupportedVersions()[index2];
-      EXPECT_NE(version1, version2) << version1 << " " << version2;
-      EXPECT_NE(CreateQuicVersionLabel(version1),
-                CreateQuicVersionLabel(version2))
-          << version1 << " " << version2;
-      // The one pair where ALPNs are the same.
-      if ((version1 != ParsedQuicVersion::V2Draft01()) &&
-          (version2 != ParsedQuicVersion::RFCv1())) {
-        EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
-            << version1 << " " << version2;
-      }
-    }
-  }
-}
-
-TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
-  ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
-  ParsedQuicVersionVector all_current_supported_versions =
-      CurrentSupportedVersions();
-  for (auto& version : all_current_supported_versions) {
-    bool version_is_h3 = false;
-    for (auto& h3_version : h3_versions) {
-      if (version == h3_version) {
-        EXPECT_TRUE(version.UsesHttp3());
-        version_is_h3 = true;
-        break;
-      }
-    }
-    if (!version_is_h3) {
-      EXPECT_FALSE(version.UsesHttp3());
-    }
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/quic_write_blocked_list.cc b/quic/core/quic_write_blocked_list.cc
deleted file mode 100644
index 084241d..0000000
--- a/quic/core/quic_write_blocked_list.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_write_blocked_list.h"
-
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-QuicWriteBlockedList::QuicWriteBlockedList(QuicTransportVersion version)
-    : priority_write_scheduler_(QuicVersionUsesCryptoFrames(version)
-                                    ? std::numeric_limits<QuicStreamId>::max()
-                                    : 0),
-      last_priority_popped_(0) {
-  memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_));
-  memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_));
-}
-
-QuicWriteBlockedList::~QuicWriteBlockedList() {}
-
-bool QuicWriteBlockedList::ShouldYield(QuicStreamId id) const {
-  for (const auto& stream : static_stream_collection_) {
-    if (stream.id == id) {
-      // Static streams should never yield to data streams, or to lower
-      // priority static stream.
-      return false;
-    }
-    if (stream.is_blocked) {
-      return true;  // All data streams yield to static streams.
-    }
-  }
-
-  return priority_write_scheduler_.ShouldYield(id);
-}
-
-QuicStreamId QuicWriteBlockedList::PopFront() {
-  QuicStreamId static_stream_id;
-  if (static_stream_collection_.UnblockFirstBlocked(&static_stream_id)) {
-    return static_stream_id;
-  }
-
-  const auto id_and_precedence =
-      priority_write_scheduler_.PopNextReadyStreamAndPrecedence();
-  const QuicStreamId id = std::get<0>(id_and_precedence);
-  const spdy::SpdyPriority priority =
-      std::get<1>(id_and_precedence).spdy3_priority();
-
-  if (!priority_write_scheduler_.HasReadyStreams()) {
-    // If no streams are blocked, don't bother latching.  This stream will be
-    // the first popped for its priority anyway.
-    batch_write_stream_id_[priority] = 0;
-    last_priority_popped_ = priority;
-  } else if (batch_write_stream_id_[priority] != id) {
-    // If newly latching this batch write stream, let it write 16k.
-    batch_write_stream_id_[priority] = id;
-    bytes_left_for_batch_write_[priority] = 16000;
-    last_priority_popped_ = priority;
-  }
-
-  return id;
-}
-
-void QuicWriteBlockedList::RegisterStream(
-    QuicStreamId stream_id,
-    bool is_static_stream,
-    const spdy::SpdyStreamPrecedence& precedence) {
-  QUICHE_DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id))
-      << "stream " << stream_id << " already registered";
-  QUICHE_DCHECK(precedence.is_spdy3_priority());
-  if (is_static_stream) {
-    static_stream_collection_.Register(stream_id);
-    return;
-  }
-
-  priority_write_scheduler_.RegisterStream(stream_id, precedence);
-}
-
-void QuicWriteBlockedList::UnregisterStream(QuicStreamId stream_id,
-                                            bool is_static) {
-  if (is_static) {
-    static_stream_collection_.Unregister(stream_id);
-    return;
-  }
-  priority_write_scheduler_.UnregisterStream(stream_id);
-}
-
-void QuicWriteBlockedList::UpdateStreamPriority(
-    QuicStreamId stream_id,
-    const spdy::SpdyStreamPrecedence& new_precedence) {
-  QUICHE_DCHECK(!static_stream_collection_.IsRegistered(stream_id));
-  QUICHE_DCHECK(new_precedence.is_spdy3_priority());
-  priority_write_scheduler_.UpdateStreamPrecedence(stream_id, new_precedence);
-}
-
-void QuicWriteBlockedList::UpdateBytesForStream(QuicStreamId stream_id,
-                                                size_t bytes) {
-  if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
-    // If this was the last data stream popped by PopFront, update the
-    // bytes remaining in its batch write.
-    bytes_left_for_batch_write_[last_priority_popped_] -=
-        std::min(bytes_left_for_batch_write_[last_priority_popped_], bytes);
-  }
-}
-
-void QuicWriteBlockedList::AddStream(QuicStreamId stream_id) {
-  if (static_stream_collection_.SetBlocked(stream_id)) {
-    return;
-  }
-
-  bool push_front =
-      stream_id == batch_write_stream_id_[last_priority_popped_] &&
-      bytes_left_for_batch_write_[last_priority_popped_] > 0;
-  priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
-}
-
-bool QuicWriteBlockedList::IsStreamBlocked(QuicStreamId stream_id) const {
-  for (const auto& stream : static_stream_collection_) {
-    if (stream.id == stream_id) {
-      return stream.is_blocked;
-    }
-  }
-
-  return priority_write_scheduler_.IsStreamReady(stream_id);
-}
-
-void QuicWriteBlockedList::StaticStreamCollection::Register(QuicStreamId id) {
-  QUICHE_DCHECK(!IsRegistered(id));
-  streams_.push_back({id, false});
-}
-
-bool QuicWriteBlockedList::StaticStreamCollection::IsRegistered(
-    QuicStreamId id) const {
-  for (const auto& stream : streams_) {
-    if (stream.id == id) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void QuicWriteBlockedList::StaticStreamCollection::Unregister(QuicStreamId id) {
-  for (auto it = streams_.begin(); it != streams_.end(); ++it) {
-    if (it->id == id) {
-      if (it->is_blocked) {
-        --num_blocked_;
-      }
-      streams_.erase(it);
-      return;
-    }
-  }
-  QUICHE_DCHECK(false) << "Erasing a non-exist stream with id " << id;
-}
-
-bool QuicWriteBlockedList::StaticStreamCollection::SetBlocked(QuicStreamId id) {
-  for (auto& stream : streams_) {
-    if (stream.id == id) {
-      if (!stream.is_blocked) {
-        stream.is_blocked = true;
-        ++num_blocked_;
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicWriteBlockedList::StaticStreamCollection::UnblockFirstBlocked(
-    QuicStreamId* id) {
-  for (auto& stream : streams_) {
-    if (stream.is_blocked) {
-      --num_blocked_;
-      stream.is_blocked = false;
-      *id = stream.id;
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_write_blocked_list.h b/quic/core/quic_write_blocked_list.h
deleted file mode 100644
index 54441e7..0000000
--- a/quic/core/quic_write_blocked_list.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
-#define QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <utility>
-
-#include "absl/container/inlined_vector.h"
-#include "http2/core/priority_write_scheduler.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-// Keeps tracks of the QUIC streams that have data to write, sorted by
-// priority.  QUIC stream priority order is:
-// Crypto stream > Headers stream > Data streams by requested priority.
-class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
- public:
-  explicit QuicWriteBlockedList(QuicTransportVersion version);
-  QuicWriteBlockedList(const QuicWriteBlockedList&) = delete;
-  QuicWriteBlockedList& operator=(const QuicWriteBlockedList&) = delete;
-  ~QuicWriteBlockedList();
-
-  bool HasWriteBlockedDataStreams() const {
-    return priority_write_scheduler_.HasReadyStreams();
-  }
-
-  bool HasWriteBlockedSpecialStream() const {
-    return static_stream_collection_.num_blocked() > 0;
-  }
-
-  size_t NumBlockedSpecialStreams() const {
-    return static_stream_collection_.num_blocked();
-  }
-
-  size_t NumBlockedStreams() const {
-    return NumBlockedSpecialStreams() +
-           priority_write_scheduler_.NumReadyStreams();
-  }
-
-  bool ShouldYield(QuicStreamId id) const;
-
-  spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId id) const {
-    return priority_write_scheduler_.GetStreamPrecedence(id).spdy3_priority();
-  }
-
-  // Pops the highest priority stream, special casing crypto and headers
-  // streams. Latches the most recently popped data stream for batch writing
-  // purposes.
-  QuicStreamId PopFront();
-
-  void RegisterStream(QuicStreamId stream_id,
-                      bool is_static_stream,
-                      const spdy::SpdyStreamPrecedence& precedence);
-
-  void UnregisterStream(QuicStreamId stream_id, bool is_static);
-
-  void UpdateStreamPriority(QuicStreamId stream_id,
-                            const spdy::SpdyStreamPrecedence& new_precedence);
-
-  void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes);
-
-  // Pushes a stream to the back of the list for its priority level *unless* it
-  // is latched for doing batched writes in which case it goes to the front of
-  // the list for its priority level.
-  // Headers and crypto streams are special cased to always resume first.
-  void AddStream(QuicStreamId stream_id);
-
-  // Returns true if stream with |stream_id| is write blocked.
-  bool IsStreamBlocked(QuicStreamId stream_id) const;
-
- private:
-  http2::PriorityWriteScheduler<QuicStreamId> priority_write_scheduler_;
-
-  // If performing batch writes, this will be the stream ID of the stream doing
-  // batch writes for this priority level.  We will allow this stream to write
-  // until it has written kBatchWriteSize bytes, it has no more data to write,
-  // or a higher priority stream preempts.
-  QuicStreamId batch_write_stream_id_[spdy::kV3LowestPriority + 1];
-  // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
-  // priority.  This is decremented with each write the stream does until it is
-  // done with its batch write.
-  size_t bytes_left_for_batch_write_[spdy::kV3LowestPriority + 1];
-  // Tracks the last priority popped for UpdateBytesForStream.
-  spdy::SpdyPriority last_priority_popped_;
-
-  // A StaticStreamCollection is a vector of <QuicStreamId, bool> pairs plus a
-  // eagerly-computed number of blocked static streams.
-  class QUIC_EXPORT_PRIVATE StaticStreamCollection {
-   public:
-    struct QUIC_EXPORT_PRIVATE StreamIdBlockedPair {
-      QuicStreamId id;
-      bool is_blocked;
-    };
-
-    // Optimized for the typical case of 2 static streams per session.
-    using StreamsVector = absl::InlinedVector<StreamIdBlockedPair, 2>;
-
-    StreamsVector::const_iterator begin() const { return streams_.cbegin(); }
-
-    StreamsVector::const_iterator end() const { return streams_.cend(); }
-
-    size_t num_blocked() const { return num_blocked_; }
-
-    // Add |id| to the collection in unblocked state.
-    void Register(QuicStreamId id);
-
-    // True if |id| is in the collection, regardless of its state.
-    bool IsRegistered(QuicStreamId id) const;
-
-    // Remove |id| from the collection, if it is in the blocked state, reduce
-    // |num_blocked_| by 1.
-    void Unregister(QuicStreamId id);
-
-    // Set |id| to be blocked. If |id| is not already blocked, increase
-    // |num_blocked_| by 1.
-    // Return true if |id| is in the collection.
-    bool SetBlocked(QuicStreamId id);
-
-    // Unblock the first blocked stream in the collection.
-    // If no stream is blocked, return false. Otherwise return true, set *id to
-    // the unblocked stream id and reduce |num_blocked_| by 1.
-    bool UnblockFirstBlocked(QuicStreamId* id);
-
-   private:
-    size_t num_blocked_ = 0;
-    StreamsVector streams_;
-  };
-
-  StaticStreamCollection static_stream_collection_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
diff --git a/quic/core/quic_write_blocked_list_test.cc b/quic/core/quic_write_blocked_list_test.cc
deleted file mode 100644
index 7cf7797..0000000
--- a/quic/core/quic_write_blocked_list_test.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/quic_write_blocked_list.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using spdy::kHttp2DefaultStreamWeight;
-using spdy::kV3HighestPriority;
-using spdy::kV3LowestPriority;
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicWriteBlockedListTest : public QuicTestWithParam<bool> {
- public:
-  QuicWriteBlockedListTest()
-      : write_blocked_list_(AllSupportedVersions()[0].transport_version) {}
-
- protected:
-  QuicWriteBlockedList write_blocked_list_;
-};
-
-TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
-  /*
-       0
-       |
-       23
-       |
-       17
-       |
-       40
-  */
-  // Mark streams blocked in roughly reverse priority order, and
-  // verify that streams are sorted.
-  write_blocked_list_.RegisterStream(
-      40, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
-  write_blocked_list_.RegisterStream(
-      23, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(
-      17, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(
-      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(
-      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
-  write_blocked_list_.AddStream(40);
-  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(40));
-  write_blocked_list_.AddStream(23);
-  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(23));
-  write_blocked_list_.AddStream(17);
-  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(17));
-  write_blocked_list_.AddStream(3);
-  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(3));
-  write_blocked_list_.AddStream(1);
-  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(1));
-
-  EXPECT_EQ(5u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedSpecialStreams());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
-  // The Crypto stream is highest priority.
-  EXPECT_EQ(1u, write_blocked_list_.PopFront());
-  EXPECT_EQ(1u, write_blocked_list_.NumBlockedSpecialStreams());
-  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(1));
-  // Followed by the Headers stream.
-  EXPECT_EQ(3u, write_blocked_list_.PopFront());
-  EXPECT_EQ(0u, write_blocked_list_.NumBlockedSpecialStreams());
-  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(3));
-  // Streams with same priority are popped in the order they were inserted.
-  EXPECT_EQ(23u, write_blocked_list_.PopFront());
-  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(23));
-  EXPECT_EQ(17u, write_blocked_list_.PopFront());
-  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(17));
-  // Low priority stream appears last.
-  EXPECT_EQ(40u, write_blocked_list_.PopFront());
-  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(40));
-
-  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
-}
-
-TEST_F(QuicWriteBlockedListTest, CryptoStream) {
-  write_blocked_list_.RegisterStream(
-      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.AddStream(1);
-
-  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
-  EXPECT_EQ(1u, write_blocked_list_.PopFront());
-  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
-}
-
-TEST_F(QuicWriteBlockedListTest, HeadersStream) {
-  write_blocked_list_.RegisterStream(
-      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.AddStream(3);
-
-  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
-  EXPECT_EQ(3u, write_blocked_list_.PopFront());
-  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
-}
-
-TEST_F(QuicWriteBlockedListTest, VerifyHeadersStream) {
-  write_blocked_list_.RegisterStream(
-      5, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(
-      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.AddStream(5);
-  write_blocked_list_.AddStream(3);
-
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
-  // In newer QUIC versions, there is a headers stream which is
-  // higher priority than data streams.
-  EXPECT_EQ(3u, write_blocked_list_.PopFront());
-  EXPECT_EQ(5u, write_blocked_list_.PopFront());
-  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
-}
-
-TEST_F(QuicWriteBlockedListTest, NoDuplicateEntries) {
-  // Test that QuicWriteBlockedList doesn't allow duplicate entries.
-  // Try to add a stream to the write blocked list multiple times at the same
-  // priority.
-  const QuicStreamId kBlockedId = 3 + 2;
-    write_blocked_list_.RegisterStream(
-        kBlockedId, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.AddStream(kBlockedId);
-  write_blocked_list_.AddStream(kBlockedId);
-  write_blocked_list_.AddStream(kBlockedId);
-
-  // This should only result in one blocked stream being added.
-  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
-
-  // There should only be one stream to pop off the front.
-  EXPECT_EQ(kBlockedId, write_blocked_list_.PopFront());
-  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
-}
-
-TEST_F(QuicWriteBlockedListTest, BatchingWrites) {
-  const QuicStreamId id1 = 3 + 2;
-  const QuicStreamId id2 = id1 + 2;
-  const QuicStreamId id3 = id2 + 2;
-  write_blocked_list_.RegisterStream(
-      id1, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
-  write_blocked_list_.RegisterStream(
-      id2, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
-  write_blocked_list_.RegisterStream(
-      id3, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
-  write_blocked_list_.AddStream(id1);
-  write_blocked_list_.AddStream(id2);
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-
-  // The first stream we push back should stay at the front until 16k is
-  // written.
-  EXPECT_EQ(id1, write_blocked_list_.PopFront());
-  write_blocked_list_.UpdateBytesForStream(id1, 15999);
-  write_blocked_list_.AddStream(id1);
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_EQ(id1, write_blocked_list_.PopFront());
-
-  // Once 16k is written the first stream will yield to the next.
-  write_blocked_list_.UpdateBytesForStream(id1, 1);
-  write_blocked_list_.AddStream(id1);
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_EQ(id2, write_blocked_list_.PopFront());
-
-  // Set the new stream to have written all but one byte.
-  write_blocked_list_.UpdateBytesForStream(id2, 15999);
-  write_blocked_list_.AddStream(id2);
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-
-  // Ensure higher priority streams are popped first.
-  write_blocked_list_.AddStream(id3);
-  EXPECT_EQ(id3, write_blocked_list_.PopFront());
-
-  // Higher priority streams will always be popped first, even if using their
-  // byte quota
-  write_blocked_list_.UpdateBytesForStream(id3, 20000);
-  write_blocked_list_.AddStream(id3);
-  EXPECT_EQ(id3, write_blocked_list_.PopFront());
-
-  // Once the higher priority stream is out of the way, id2 will resume its 16k
-  // write, with only 1 byte remaining of its guaranteed write allocation.
-  EXPECT_EQ(id2, write_blocked_list_.PopFront());
-  write_blocked_list_.UpdateBytesForStream(id2, 1);
-  write_blocked_list_.AddStream(id2);
-  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
-  EXPECT_EQ(id1, write_blocked_list_.PopFront());
-}
-
-TEST_F(QuicWriteBlockedListTest, Ceding) {
-  /*
-       0
-       |
-       15
-       |
-       16
-       |
-       5
-       |
-       4
-       |
-       7
-  */
-  write_blocked_list_.RegisterStream(
-      15, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(
-      16, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(5, false, spdy::SpdyStreamPrecedence(5));
-  write_blocked_list_.RegisterStream(4, false, spdy::SpdyStreamPrecedence(5));
-  write_blocked_list_.RegisterStream(7, false, spdy::SpdyStreamPrecedence(7));
-  write_blocked_list_.RegisterStream(
-      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-  write_blocked_list_.RegisterStream(
-      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
-
-  // When nothing is on the list, nothing yields.
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
-
-  write_blocked_list_.AddStream(5);
-  // 5 should not yield to itself.
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
-  // 4 and 7 are equal or lower priority and should yield to 5.
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(4));
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(7));
-  // 15, headers and crypto should preempt 5.
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(15));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-
-  // Block a high priority stream.
-  write_blocked_list_.AddStream(15);
-  // 16 should yield (same priority) but headers and crypto will still not.
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-
-  // Block the headers stream.  All streams but crypto and headers should yield.
-  write_blocked_list_.AddStream(3);
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-
-  // Block the crypto stream.  All streams but crypto should yield.
-  write_blocked_list_.AddStream(1);
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
-  EXPECT_TRUE(write_blocked_list_.ShouldYield(3));
-  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/session_notifier_interface.h b/quic/core/session_notifier_interface.h
deleted file mode 100644
index a3c29ed..0000000
--- a/quic/core/session_notifier_interface.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
-#define QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
-
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-// Pure virtual class to be notified when a packet containing a frame is acked
-// or lost.
-class QUIC_EXPORT_PRIVATE SessionNotifierInterface {
- public:
-  virtual ~SessionNotifierInterface() {}
-
-  // Called when |frame| is acked. Returns true if any new data gets acked,
-  // returns false otherwise.
-  virtual bool OnFrameAcked(const QuicFrame& frame,
-                            QuicTime::Delta ack_delay_time,
-                            QuicTime receive_timestamp) = 0;
-
-  // Called when |frame| is retransmitted.
-  virtual void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) = 0;
-
-  // Called when |frame| is considered as lost.
-  virtual void OnFrameLost(const QuicFrame& frame) = 0;
-
-  // Called to retransmit |frames| with transmission |type|. Returns true if all
-  // data gets retransmitted.
-  virtual bool RetransmitFrames(const QuicFrames& frames,
-                                TransmissionType type) = 0;
-
-  // Returns true if |frame| is outstanding and waiting to be acked.
-  virtual bool IsFrameOutstanding(const QuicFrame& frame) const = 0;
-
-  // Returns true if crypto stream is waiting for acks.
-  virtual bool HasUnackedCryptoData() const = 0;
-
-  // Returns true if any stream is waiting for acks.
-  virtual bool HasUnackedStreamData() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
diff --git a/quic/core/stream_delegate_interface.h b/quic/core/stream_delegate_interface.h
deleted file mode 100644
index 02b195e..0000000
--- a/quic/core/stream_delegate_interface.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
-#define QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
-
-#include <cstddef>
-#include "absl/types/optional.h"
-#include "quic/core/quic_types.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-class QuicStream;
-
-// Pure virtual class to get notified when particular QuicStream events
-// occurred.
-class QUIC_EXPORT_PRIVATE StreamDelegateInterface {
- public:
-  virtual ~StreamDelegateInterface() {}
-
-  // Called when the stream has encountered errors that it can't handle.
-  virtual void OnStreamError(QuicErrorCode error_code,
-                             std::string error_details) = 0;
-  // Called when the stream has encountered errors that it can't handle,
-  // specifying the wire error code |ietf_error| explicitly.
-  virtual void OnStreamError(QuicErrorCode error_code,
-                             QuicIetfTransportErrorCodes ietf_error,
-                             std::string error_details) = 0;
-  // Called when the stream needs to write data at specified |level| and
-  // transmission |type|.
-  virtual QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
-                                      QuicStreamOffset offset,
-                                      StreamSendingState state,
-                                      TransmissionType type,
-                                      EncryptionLevel level) = 0;
-  // Called to write crypto data.
-  virtual size_t SendCryptoData(EncryptionLevel level,
-                                size_t write_length,
-                                QuicStreamOffset offset,
-                                TransmissionType type) = 0;
-  // Called on stream creation.
-  virtual void RegisterStreamPriority(
-      QuicStreamId id,
-      bool is_static,
-      const spdy::SpdyStreamPrecedence& precedence) = 0;
-  // Called on stream destruction to clear priority.
-  virtual void UnregisterStreamPriority(QuicStreamId id, bool is_static) = 0;
-  // Called by the stream on SetPriority to update priority.
-  virtual void UpdateStreamPriority(
-      QuicStreamId id,
-      const spdy::SpdyStreamPrecedence& new_precedence) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
diff --git a/quic/core/tls_chlo_extractor.cc b/quic/core/tls_chlo_extractor.cc
deleted file mode 100644
index 3a2df79..0000000
--- a/quic/core/tls_chlo_extractor.cc
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_chlo_extractor.h"
-#include <cstring>
-#include <memory>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/frames/quic_crypto_frame.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-bool HasExtension(const SSL_CLIENT_HELLO* client_hello, uint16_t extension) {
-  const uint8_t* unused_extension_bytes;
-  size_t unused_extension_len;
-  return 1 == SSL_early_callback_ctx_extension_get(client_hello, extension,
-                                                   &unused_extension_bytes,
-                                                   &unused_extension_len);
-}
-}  // namespace
-
-TlsChloExtractor::TlsChloExtractor()
-    : crypto_stream_sequencer_(this),
-      state_(State::kInitial),
-      parsed_crypto_frame_in_this_packet_(false) {}
-
-TlsChloExtractor::TlsChloExtractor(TlsChloExtractor&& other)
-    : TlsChloExtractor() {
-  *this = std::move(other);
-}
-
-TlsChloExtractor& TlsChloExtractor::operator=(TlsChloExtractor&& other) {
-  framer_ = std::move(other.framer_);
-  if (framer_) {
-    framer_->set_visitor(this);
-  }
-  crypto_stream_sequencer_ = std::move(other.crypto_stream_sequencer_);
-  crypto_stream_sequencer_.set_stream(this);
-  ssl_ = std::move(other.ssl_);
-  if (ssl_) {
-    std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
-    int ex_data_index = shared_handles.second;
-    const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
-    QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
-  }
-  state_ = other.state_;
-  error_details_ = std::move(other.error_details_);
-  parsed_crypto_frame_in_this_packet_ =
-      other.parsed_crypto_frame_in_this_packet_;
-  alpns_ = std::move(other.alpns_);
-  server_name_ = std::move(other.server_name_);
-  return *this;
-}
-
-void TlsChloExtractor::IngestPacket(const ParsedQuicVersion& version,
-                                    const QuicReceivedPacket& packet) {
-  if (state_ == State::kUnrecoverableFailure) {
-    QUIC_DLOG(ERROR) << "Not ingesting packet after unrecoverable error";
-    return;
-  }
-  if (version == UnsupportedQuicVersion()) {
-    QUIC_DLOG(ERROR) << "Not ingesting packet with unsupported version";
-    return;
-  }
-  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
-    QUIC_DLOG(ERROR) << "Not ingesting packet with non-TLS version " << version;
-    return;
-  }
-  if (framer_) {
-    // This is not the first packet we have ingested, check if version matches.
-    if (!framer_->IsSupportedVersion(version)) {
-      QUIC_DLOG(ERROR)
-          << "Not ingesting packet with version mismatch, expected "
-          << framer_->version() << ", got " << version;
-      return;
-    }
-  } else {
-    // This is the first packet we have ingested, setup parser.
-    framer_ = std::make_unique<QuicFramer>(
-        ParsedQuicVersionVector{version}, QuicTime::Zero(),
-        Perspective::IS_SERVER, /*expected_server_connection_id_length=*/0);
-    // Note that expected_server_connection_id_length only matters for short
-    // headers and we explicitly drop those so we can pass any value here.
-    framer_->set_visitor(this);
-  }
-
-  // When the framer parses |packet|, if it sees a CRYPTO frame it will call
-  // OnCryptoFrame below and that will set parsed_crypto_frame_in_this_packet_
-  // to true.
-  parsed_crypto_frame_in_this_packet_ = false;
-  const bool parse_success = framer_->ProcessPacket(packet);
-  if (state_ == State::kInitial && parsed_crypto_frame_in_this_packet_) {
-    // If we parsed a CRYPTO frame but didn't advance the state from initial,
-    // then it means that we will need more packets to reassemble the full CHLO,
-    // so we advance the state here. This can happen when the first packet
-    // received is not the first one in the crypto stream. This allows us to
-    // differentiate our state between single-packet CHLO and multi-packet CHLO.
-    state_ = State::kParsedPartialChloFragment;
-  }
-
-  if (!parse_success) {
-    // This could be due to the packet being non-initial for example.
-    QUIC_DLOG(ERROR) << "Failed to process packet";
-    return;
-  }
-}
-
-// This is called when the framer parsed the unencrypted parts of the header.
-bool TlsChloExtractor::OnUnauthenticatedPublicHeader(
-    const QuicPacketHeader& header) {
-  if (header.form != IETF_QUIC_LONG_HEADER_PACKET) {
-    QUIC_DLOG(ERROR) << "Not parsing non-long-header packet " << header;
-    return false;
-  }
-  if (header.long_packet_type != INITIAL) {
-    QUIC_DLOG(ERROR) << "Not parsing non-initial packet " << header;
-    return false;
-  }
-  // QuicFramer is constructed without knowledge of the server's connection ID
-  // so it needs to be set up here in order to decrypt the packet.
-  framer_->SetInitialObfuscators(header.destination_connection_id);
-  return true;
-}
-
-// This is called by the framer if it detects a change in version during
-// parsing.
-bool TlsChloExtractor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
-  // This should never be called because we already check versions in
-  // IngestPacket.
-  QUIC_BUG(quic_bug_10855_1) << "Unexpected version mismatch, expected "
-                             << framer_->version() << ", got " << version;
-  return false;
-}
-
-// This is called by the QuicStreamSequencer if it encounters an unrecoverable
-// error that will prevent it from reassembling the crypto stream data.
-void TlsChloExtractor::OnUnrecoverableError(QuicErrorCode error,
-                                            const std::string& details) {
-  HandleUnrecoverableError(absl::StrCat(
-      "Crypto stream error ", QuicErrorCodeToString(error), ": ", details));
-}
-
-void TlsChloExtractor::OnUnrecoverableError(
-    QuicErrorCode error,
-    QuicIetfTransportErrorCodes ietf_error,
-    const std::string& details) {
-  HandleUnrecoverableError(absl::StrCat(
-      "Crypto stream error ", QuicErrorCodeToString(error), "(",
-      QuicIetfTransportErrorCodeString(ietf_error), "): ", details));
-}
-
-// This is called by the framer if it sees a CRYPTO frame during parsing.
-bool TlsChloExtractor::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  if (frame.level != ENCRYPTION_INITIAL) {
-    // Since we drop non-INITIAL packets in OnUnauthenticatedPublicHeader,
-    // we should never receive any CRYPTO frames at other encryption levels.
-    QUIC_BUG(quic_bug_10855_2) << "Parsed bad-level CRYPTO frame " << frame;
-    return false;
-  }
-  // parsed_crypto_frame_in_this_packet_ is checked in IngestPacket to allow
-  // advancing our state to track the difference between single-packet CHLO
-  // and multi-packet CHLO.
-  parsed_crypto_frame_in_this_packet_ = true;
-  crypto_stream_sequencer_.OnCryptoFrame(frame);
-  return true;
-}
-
-// Called by the QuicStreamSequencer when it receives a CRYPTO frame that
-// advances the amount of contiguous data we now have starting from offset 0.
-void TlsChloExtractor::OnDataAvailable() {
-  // Lazily set up BoringSSL handle.
-  SetupSslHandle();
-
-  // Get data from the stream sequencer and pass it to BoringSSL.
-  struct iovec iov;
-  while (crypto_stream_sequencer_.GetReadableRegion(&iov)) {
-    const int rv = SSL_provide_quic_data(
-        ssl_.get(), ssl_encryption_initial,
-        reinterpret_cast<const uint8_t*>(iov.iov_base), iov.iov_len);
-    if (rv != 1) {
-      HandleUnrecoverableError("SSL_provide_quic_data failed");
-      return;
-    }
-    crypto_stream_sequencer_.MarkConsumed(iov.iov_len);
-  }
-
-  // Instruct BoringSSL to attempt parsing a full CHLO from the provided data.
-  // We ignore the return value since we know the handshake is going to fail
-  // because we explicitly cancel processing once we've parsed the CHLO.
-  (void)SSL_do_handshake(ssl_.get());
-}
-
-// static
-TlsChloExtractor* TlsChloExtractor::GetInstanceFromSSL(SSL* ssl) {
-  std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
-  int ex_data_index = shared_handles.second;
-  return reinterpret_cast<TlsChloExtractor*>(
-      SSL_get_ex_data(ssl, ex_data_index));
-}
-
-// static
-int TlsChloExtractor::SetReadSecretCallback(
-    SSL* ssl,
-    enum ssl_encryption_level_t /*level*/,
-    const SSL_CIPHER* /*cipher*/,
-    const uint8_t* /*secret*/,
-    size_t /*secret_length*/) {
-  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetReadSecretCallback");
-  return 0;
-}
-
-// static
-int TlsChloExtractor::SetWriteSecretCallback(
-    SSL* ssl,
-    enum ssl_encryption_level_t /*level*/,
-    const SSL_CIPHER* /*cipher*/,
-    const uint8_t* /*secret*/,
-    size_t /*secret_length*/) {
-  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetWriteSecretCallback");
-  return 0;
-}
-
-// static
-int TlsChloExtractor::WriteMessageCallback(
-    SSL* ssl,
-    enum ssl_encryption_level_t /*level*/,
-    const uint8_t* /*data*/,
-    size_t /*len*/) {
-  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("WriteMessageCallback");
-  return 0;
-}
-
-// static
-int TlsChloExtractor::FlushFlightCallback(SSL* ssl) {
-  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("FlushFlightCallback");
-  return 0;
-}
-
-void TlsChloExtractor::HandleUnexpectedCallback(
-    const std::string& callback_name) {
-  std::string error_details =
-      absl::StrCat("Unexpected callback ", callback_name);
-  QUIC_BUG(quic_bug_10855_3) << error_details;
-  HandleUnrecoverableError(error_details);
-}
-
-// static
-int TlsChloExtractor::SendAlertCallback(SSL* ssl,
-                                        enum ssl_encryption_level_t /*level*/,
-                                        uint8_t desc) {
-  GetInstanceFromSSL(ssl)->SendAlert(desc);
-  return 0;
-}
-
-void TlsChloExtractor::SendAlert(uint8_t tls_alert_value) {
-  if (tls_alert_value == SSL3_AD_HANDSHAKE_FAILURE && HasParsedFullChlo()) {
-    // This is the most common scenario. Since we return an error from
-    // SelectCertCallback in order to cancel further processing, BoringSSL will
-    // try to send this alert to tell the client that the handshake failed.
-    return;
-  }
-  HandleUnrecoverableError(absl::StrCat(
-      "BoringSSL attempted to send alert ", static_cast<int>(tls_alert_value),
-      " ", SSL_alert_desc_string_long(tls_alert_value)));
-}
-
-// static
-enum ssl_select_cert_result_t TlsChloExtractor::SelectCertCallback(
-    const SSL_CLIENT_HELLO* client_hello) {
-  GetInstanceFromSSL(client_hello->ssl)->HandleParsedChlo(client_hello);
-  // Always return an error to cancel any further processing in BoringSSL.
-  return ssl_select_cert_error;
-}
-
-// Extracts the server name and ALPN from the parsed ClientHello.
-void TlsChloExtractor::HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello) {
-  const char* server_name =
-      SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name);
-  if (server_name) {
-    server_name_ = std::string(server_name);
-  }
-
-  resumption_attempted_ =
-      HasExtension(client_hello, TLSEXT_TYPE_pre_shared_key);
-  early_data_attempted_ = HasExtension(client_hello, TLSEXT_TYPE_early_data);
-
-  const uint8_t* alpn_data;
-  size_t alpn_len;
-  int rv = SSL_early_callback_ctx_extension_get(
-      client_hello, TLSEXT_TYPE_application_layer_protocol_negotiation,
-      &alpn_data, &alpn_len);
-  if (rv == 1) {
-    QuicDataReader alpns_reader(reinterpret_cast<const char*>(alpn_data),
-                                alpn_len);
-    absl::string_view alpns_payload;
-    if (!alpns_reader.ReadStringPiece16(&alpns_payload)) {
-      HandleUnrecoverableError("Failed to read alpns_payload");
-      return;
-    }
-    QuicDataReader alpns_payload_reader(alpns_payload);
-    while (!alpns_payload_reader.IsDoneReading()) {
-      absl::string_view alpn_payload;
-      if (!alpns_payload_reader.ReadStringPiece8(&alpn_payload)) {
-        HandleUnrecoverableError("Failed to read alpn_payload");
-        return;
-      }
-      alpns_.emplace_back(std::string(alpn_payload));
-    }
-  }
-
-  // Update our state now that we've parsed a full CHLO.
-  if (state_ == State::kInitial) {
-    state_ = State::kParsedFullSinglePacketChlo;
-  } else if (state_ == State::kParsedPartialChloFragment) {
-    state_ = State::kParsedFullMultiPacketChlo;
-  } else {
-    QUIC_BUG(quic_bug_10855_4)
-        << "Unexpected state on successful parse " << StateToString(state_);
-  }
-}
-
-// static
-std::pair<SSL_CTX*, int> TlsChloExtractor::GetSharedSslHandles() {
-  // Use a lambda to benefit from C++11 guarantee that static variables are
-  // initialized lazily in a thread-safe manner. |shared_handles| is therefore
-  // guaranteed to be initialized exactly once and never destructed.
-  static std::pair<SSL_CTX*, int>* shared_handles = []() {
-    CRYPTO_library_init();
-    SSL_CTX* ssl_ctx = SSL_CTX_new(TLS_with_buffers_method());
-    SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
-    SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
-    static const SSL_QUIC_METHOD kQuicCallbacks{
-        TlsChloExtractor::SetReadSecretCallback,
-        TlsChloExtractor::SetWriteSecretCallback,
-        TlsChloExtractor::WriteMessageCallback,
-        TlsChloExtractor::FlushFlightCallback,
-        TlsChloExtractor::SendAlertCallback};
-    SSL_CTX_set_quic_method(ssl_ctx, &kQuicCallbacks);
-    SSL_CTX_set_select_certificate_cb(ssl_ctx,
-                                      TlsChloExtractor::SelectCertCallback);
-    int ex_data_index =
-        SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
-    return new std::pair<SSL_CTX*, int>(ssl_ctx, ex_data_index);
-  }();
-  return *shared_handles;
-}
-
-// Sets up the per-instance SSL handle needed by BoringSSL.
-void TlsChloExtractor::SetupSslHandle() {
-  if (ssl_) {
-    // Handles have already been set up.
-    return;
-  }
-
-  std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
-  SSL_CTX* ssl_ctx = shared_handles.first;
-  int ex_data_index = shared_handles.second;
-
-  ssl_ = bssl::UniquePtr<SSL>(SSL_new(ssl_ctx));
-  const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
-  QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
-  SSL_set_accept_state(ssl_.get());
-
-  // Make sure we use the right TLS extension codepoint.
-  int use_legacy_extension = 0;
-  if (framer_->version().UsesLegacyTlsExtension()) {
-    use_legacy_extension = 1;
-  }
-  SSL_set_quic_use_legacy_codepoint(ssl_.get(), use_legacy_extension);
-}
-
-// Called by other methods to record any unrecoverable failures they experience.
-void TlsChloExtractor::HandleUnrecoverableError(
-    const std::string& error_details) {
-  if (HasParsedFullChlo()) {
-    // Ignore errors if we've parsed everything successfully.
-    QUIC_DLOG(ERROR) << "Ignoring error: " << error_details;
-    return;
-  }
-  QUIC_DLOG(ERROR) << "Handling error: " << error_details;
-
-  state_ = State::kUnrecoverableFailure;
-
-  if (error_details_.empty()) {
-    error_details_ = error_details;
-  } else {
-    error_details_ = absl::StrCat(error_details_, "; ", error_details);
-  }
-}
-
-// static
-std::string TlsChloExtractor::StateToString(State state) {
-  switch (state) {
-    case State::kInitial:
-      return "Initial";
-    case State::kParsedFullSinglePacketChlo:
-      return "ParsedFullSinglePacketChlo";
-    case State::kParsedFullMultiPacketChlo:
-      return "ParsedFullMultiPacketChlo";
-    case State::kParsedPartialChloFragment:
-      return "ParsedPartialChloFragment";
-    case State::kUnrecoverableFailure:
-      return "UnrecoverableFailure";
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(state), ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
-                         const TlsChloExtractor::State& state) {
-  os << TlsChloExtractor::StateToString(state);
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/core/tls_chlo_extractor.h b/quic/core/tls_chlo_extractor.h
deleted file mode 100644
index 29296dd..0000000
--- a/quic/core/tls_chlo_extractor.h
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
-#define QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Utility class that allows extracting information from a QUIC-TLS Client
-// Hello. This class creates a QuicFramer to parse the packet, and implements
-// QuicFramerVisitorInterface to access the frames parsed by the QuicFramer. It
-// then uses a QuicStreamSequencer to reassemble the contents of the crypto
-// stream, and implements QuicStreamSequencer::StreamInterface to access the
-// reassembled data.
-class QUIC_NO_EXPORT TlsChloExtractor
-    : public QuicFramerVisitorInterface,
-      public QuicStreamSequencer::StreamInterface {
- public:
-  TlsChloExtractor();
-  TlsChloExtractor(const TlsChloExtractor&) = delete;
-  TlsChloExtractor(TlsChloExtractor&&);
-  TlsChloExtractor& operator=(const TlsChloExtractor&) = delete;
-  TlsChloExtractor& operator=(TlsChloExtractor&&);
-
-  enum class State : uint8_t {
-    kInitial = 0,
-    kParsedFullSinglePacketChlo = 1,
-    kParsedFullMultiPacketChlo = 2,
-    kParsedPartialChloFragment = 3,
-    kUnrecoverableFailure = 4,
-  };
-
-  State state() const { return state_; }
-  std::vector<std::string> alpns() const { return alpns_; }
-  std::string server_name() const { return server_name_; }
-  bool resumption_attempted() const { return resumption_attempted_; }
-  bool early_data_attempted() const { return early_data_attempted_; }
-
-  // Converts |state| to a human-readable string suitable for logging.
-  static std::string StateToString(State state);
-
-  // Ingests |packet| and attempts to parse out the CHLO.
-  void IngestPacket(const ParsedQuicVersion& version,
-                    const QuicReceivedPacket& packet);
-
-  // Returns whether the ingested packets have allowed parsing a complete CHLO.
-  bool HasParsedFullChlo() const {
-    return state_ == State::kParsedFullSinglePacketChlo ||
-           state_ == State::kParsedFullMultiPacketChlo;
-  }
-
-  // Methods from QuicFramerVisitorInterface.
-  void OnError(QuicFramer* /*framer*/) override {}
-  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
-  void OnPacket() override {}
-  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& /*packet*/) override {}
-  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
-                     QuicConnectionId /*new_connection_id*/,
-                     absl::string_view /*retry_token*/,
-                     absl::string_view /*retry_integrity_tag*/,
-                     absl::string_view /*retry_without_tag*/) override {}
-  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
-    return true;
-  }
-  void OnDecryptedPacket(size_t /*packet_length*/,
-                         EncryptionLevel /*level*/) override {}
-  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
-    return true;
-  }
-  void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {}
-  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
-                             EncryptionLevel /*decryption_level*/,
-                             bool /*has_decryption_key*/) override {}
-  bool OnStreamFrame(const QuicStreamFrame& /*frame*/) override { return true; }
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  bool OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
-                       QuicTime::Delta /*ack_delay_time*/) override {
-    return true;
-  }
-  bool OnAckRange(QuicPacketNumber /*start*/,
-                  QuicPacketNumber /*end*/) override {
-    return true;
-  }
-  bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
-                      QuicTime /*timestamp*/) override {
-    return true;
-  }
-  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnPingFrame(const QuicPingFrame& /*frame*/) override { return true; }
-  bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnConnectionCloseFrame(
-      const QuicConnectionCloseFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnNewConnectionIdFrame(
-      const QuicNewConnectionIdFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) override { return true; }
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnStreamsBlockedFrame(
-      const QuicStreamsBlockedFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnPaddingFrame(const QuicPaddingFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnMessageFrame(const QuicMessageFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) override {
-    return true;
-  }
-  void OnPacketComplete() override {}
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& /*token*/) const override {
-    return true;
-  }
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& /*packet*/) override {}
-  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
-  void OnDecryptedFirstPacketInKeyPhase() override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-
-  // Methods from QuicStreamSequencer::StreamInterface.
-  void OnDataAvailable() override;
-  void OnFinRead() override {}
-  void AddBytesConsumed(QuicByteCount /*bytes*/) override {}
-  void ResetWithError(QuicResetStreamError /*error*/) override {}
-  void OnUnrecoverableError(QuicErrorCode error,
-                            const std::string& details) override;
-  void OnUnrecoverableError(QuicErrorCode error,
-                            QuicIetfTransportErrorCodes ietf_error,
-                            const std::string& details) override;
-  QuicStreamId id() const override { return 0; }
-  ParsedQuicVersion version() const override { return framer_->version(); }
-
- private:
-  // Parses the length of the CHLO message by looking at the first four bytes.
-  // Returns whether we have received enough data to parse the full CHLO now.
-  bool MaybeAttemptToParseChloLength();
-  // Parses the full CHLO message if enough data has been received.
-  void AttemptToParseFullChlo();
-  // Moves to the failed state and records the error details.
-  void HandleUnrecoverableError(const std::string& error_details);
-  // Lazily sets up shared SSL handles if needed.
-  static std::pair<SSL_CTX*, int> GetSharedSslHandles();
-  // Lazily sets up the per-instance SSL handle if needed.
-  void SetupSslHandle();
-  // Extract the TlsChloExtractor instance from |ssl|.
-  static TlsChloExtractor* GetInstanceFromSSL(SSL* ssl);
-
-  // BoringSSL static TLS callbacks.
-  static enum ssl_select_cert_result_t SelectCertCallback(
-      const SSL_CLIENT_HELLO* client_hello);
-  static int SetReadSecretCallback(SSL* ssl,
-                                   enum ssl_encryption_level_t level,
-                                   const SSL_CIPHER* cipher,
-                                   const uint8_t* secret,
-                                   size_t secret_length);
-  static int SetWriteSecretCallback(SSL* ssl,
-                                    enum ssl_encryption_level_t level,
-                                    const SSL_CIPHER* cipher,
-                                    const uint8_t* secret,
-                                    size_t secret_length);
-  static int WriteMessageCallback(SSL* ssl,
-                                  enum ssl_encryption_level_t level,
-                                  const uint8_t* data,
-                                  size_t len);
-  static int FlushFlightCallback(SSL* ssl);
-  static int SendAlertCallback(SSL* ssl,
-                               enum ssl_encryption_level_t level,
-                               uint8_t desc);
-
-  // Called by SelectCertCallback.
-  void HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello);
-  // Called by callbacks that should never be called.
-  void HandleUnexpectedCallback(const std::string& callback_name);
-  // Called by SendAlertCallback.
-  void SendAlert(uint8_t tls_alert_value);
-
-  // Used to parse received packets to extract single frames.
-  std::unique_ptr<QuicFramer> framer_;
-  // Used to reassemble the crypto stream from received CRYPTO frames.
-  QuicStreamSequencer crypto_stream_sequencer_;
-  // BoringSSL handle required to parse the CHLO.
-  bssl::UniquePtr<SSL> ssl_;
-  // State of this TlsChloExtractor.
-  State state_;
-  // Detail string that can be logged in the presence of unrecoverable errors.
-  std::string error_details_;
-  // Whether a CRYPTO frame was parsed in this packet.
-  bool parsed_crypto_frame_in_this_packet_;
-  // Array of ALPNs parsed from the CHLO.
-  std::vector<std::string> alpns_;
-  // SNI parsed from the CHLO.
-  std::string server_name_;
-  // Whether resumption is attempted from the CHLO, indicated by the
-  // 'pre_shared_key' TLS extension.
-  bool resumption_attempted_ = false;
-  // Whether early data is attempted from the CHLO, indicated by the
-  // 'early_data' TLS extension.
-  bool early_data_attempted_ = false;
-};
-
-// Convenience method to facilitate logging TlsChloExtractor::State.
-QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
-                                        const TlsChloExtractor::State& state);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
diff --git a/quic/core/tls_chlo_extractor_test.cc b/quic/core/tls_chlo_extractor_test.cc
deleted file mode 100644
index 8a2ce09..0000000
--- a/quic/core/tls_chlo_extractor_test.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_chlo_extractor.h"
-
-#include <memory>
-
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/first_flight.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::AnyNumber;
-
-class TlsChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
- protected:
-  TlsChloExtractorTest() : version_(GetParam()), server_id_(TestServerId()) {}
-
-  void Initialize() { packets_ = GetFirstFlightOfPackets(version_, config_); }
-  void Initialize(std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
-    packets_ = GetFirstFlightOfPackets(version_, config_, TestConnectionId(),
-                                       EmptyQuicConnectionId(),
-                                       std::move(crypto_config));
-  }
-
-  // Perform a full handshake in order to insert a SSL_SESSION into
-  // crypto_config->session_cache(), which can be used by a TLS resumption.
-  void PerformFullHandshake(QuicCryptoClientConfig* crypto_config) const {
-    ASSERT_NE(crypto_config->session_cache(), nullptr);
-    MockQuicConnectionHelper client_helper, server_helper;
-    MockAlarmFactory alarm_factory;
-    ParsedQuicVersionVector supported_versions = {version_};
-    PacketSavingConnection* client_connection =
-        new PacketSavingConnection(&client_helper, &alarm_factory,
-                                   Perspective::IS_CLIENT, supported_versions);
-    // Advance the time, because timers do not like uninitialized times.
-    client_connection->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    QuicClientPushPromiseIndex push_promise_index;
-    QuicSpdyClientSession client_session(config_, supported_versions,
-                                         client_connection, server_id_,
-                                         crypto_config, &push_promise_index);
-    client_session.Initialize();
-
-    std::unique_ptr<QuicCryptoServerConfig> server_crypto_config =
-        crypto_test_utils::CryptoServerConfigForTesting();
-    QuicConfig server_config;
-
-    EXPECT_CALL(*client_connection, SendCryptoData(_, _, _)).Times(AnyNumber());
-    client_session.GetMutableCryptoStream()->CryptoConnect();
-
-    crypto_test_utils::HandshakeWithFakeServer(
-        &server_config, server_crypto_config.get(), &server_helper,
-        &alarm_factory, client_connection,
-        client_session.GetMutableCryptoStream(),
-        AlpnForVersion(client_connection->version()));
-
-    // For some reason, the test client can not receive the server settings and
-    // the SSL_SESSION will not be inserted to client's session_cache. We create
-    // a dummy settings and call SetServerApplicationStateForResumption manually
-    // to ensure the SSL_SESSION is cached.
-    // TODO(wub): Fix crypto_test_utils::HandshakeWithFakeServer to make sure a
-    // SSL_SESSION is cached at the client, and remove the rest of the function.
-    SettingsFrame server_settings;
-    server_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
-        kDefaultQpackMaxDynamicTableCapacity;
-    std::unique_ptr<char[]> buffer;
-    uint64_t length =
-        HttpEncoder::SerializeSettingsFrame(server_settings, &buffer);
-    client_session.GetMutableCryptoStream()
-        ->SetServerApplicationStateForResumption(
-            std::make_unique<ApplicationState>(buffer.get(),
-                                               buffer.get() + length));
-  }
-
-  void IngestPackets() {
-    for (const std::unique_ptr<QuicReceivedPacket>& packet : packets_) {
-      ReceivedPacketInfo packet_info(
-          QuicSocketAddress(TestPeerIPAddress(), kTestPort),
-          QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packet);
-      std::string detailed_error;
-      absl::optional<absl::string_view> retry_token;
-      const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-          *packet, /*expected_destination_connection_id_length=*/0,
-          &packet_info.form, &packet_info.long_packet_type,
-          &packet_info.version_flag, &packet_info.use_length_prefix,
-          &packet_info.version_label, &packet_info.version,
-          &packet_info.destination_connection_id,
-          &packet_info.source_connection_id, &retry_token, &detailed_error);
-      ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
-      tls_chlo_extractor_.IngestPacket(packet_info.version, packet_info.packet);
-    }
-    packets_.clear();
-  }
-
-  void ValidateChloDetails() {
-    EXPECT_TRUE(tls_chlo_extractor_.HasParsedFullChlo());
-    std::vector<std::string> alpns = tls_chlo_extractor_.alpns();
-    ASSERT_EQ(alpns.size(), 1u);
-    EXPECT_EQ(alpns[0], AlpnForVersion(version_));
-    EXPECT_EQ(tls_chlo_extractor_.server_name(), TestHostname());
-  }
-
-  void IncreaseSizeOfChlo() {
-    // Add a 2000-byte custom parameter to increase the length of the CHLO.
-    constexpr auto kCustomParameterId =
-        static_cast<TransportParameters::TransportParameterId>(0xff33);
-    std::string kCustomParameterValue(2000, '-');
-    config_.custom_transport_parameters_to_send()[kCustomParameterId] =
-        kCustomParameterValue;
-  }
-
-  ParsedQuicVersion version_;
-  QuicServerId server_id_;
-  TlsChloExtractor tls_chlo_extractor_;
-  QuicConfig config_;
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TlsChloExtractorTests,
-                         TlsChloExtractorTest,
-                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(TlsChloExtractorTest, Simple) {
-  Initialize();
-  EXPECT_EQ(packets_.size(), 1u);
-  IngestPackets();
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
-  EXPECT_FALSE(tls_chlo_extractor_.resumption_attempted());
-  EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
-}
-
-TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ResumptionOnly) {
-  auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
-      crypto_test_utils::ProofVerifierForTesting(),
-      std::make_unique<SimpleSessionCache>());
-  PerformFullHandshake(crypto_client_config.get());
-
-  SSL_CTX_set_early_data_enabled(crypto_client_config->ssl_ctx(), 0);
-  Initialize(std::move(crypto_client_config));
-  EXPECT_GE(packets_.size(), 1u);
-  IngestPackets();
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
-  EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
-  EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
-}
-
-TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ZeroRtt) {
-  auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
-      crypto_test_utils::ProofVerifierForTesting(),
-      std::make_unique<SimpleSessionCache>());
-  PerformFullHandshake(crypto_client_config.get());
-
-  IncreaseSizeOfChlo();
-  Initialize(std::move(crypto_client_config));
-  EXPECT_GE(packets_.size(), 1u);
-  IngestPackets();
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-  EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
-  EXPECT_TRUE(tls_chlo_extractor_.early_data_attempted());
-}
-
-TEST_P(TlsChloExtractorTest, MultiPacket) {
-  IncreaseSizeOfChlo();
-  Initialize();
-  EXPECT_EQ(packets_.size(), 2u);
-  IngestPackets();
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-}
-
-TEST_P(TlsChloExtractorTest, MultiPacketReordered) {
-  IncreaseSizeOfChlo();
-  Initialize();
-  ASSERT_EQ(packets_.size(), 2u);
-  // Artifically reorder both packets.
-  std::swap(packets_[0], packets_[1]);
-  IngestPackets();
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-}
-
-TEST_P(TlsChloExtractorTest, MoveAssignment) {
-  Initialize();
-  EXPECT_EQ(packets_.size(), 1u);
-  TlsChloExtractor other_extractor;
-  tls_chlo_extractor_ = std::move(other_extractor);
-  IngestPackets();
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
-}
-
-TEST_P(TlsChloExtractorTest, MoveAssignmentBetweenPackets) {
-  IncreaseSizeOfChlo();
-  Initialize();
-  ASSERT_EQ(packets_.size(), 2u);
-  TlsChloExtractor other_extractor;
-
-  // Have |other_extractor| parse the first packet.
-  ReceivedPacketInfo packet_info(
-      QuicSocketAddress(TestPeerIPAddress(), kTestPort),
-      QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packets_[0]);
-  std::string detailed_error;
-  absl::optional<absl::string_view> retry_token;
-  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-      *packets_[0], /*expected_destination_connection_id_length=*/0,
-      &packet_info.form, &packet_info.long_packet_type,
-      &packet_info.version_flag, &packet_info.use_length_prefix,
-      &packet_info.version_label, &packet_info.version,
-      &packet_info.destination_connection_id, &packet_info.source_connection_id,
-      &retry_token, &detailed_error);
-  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
-  other_extractor.IngestPacket(packet_info.version, packet_info.packet);
-  // Remove the first packet from the list.
-  packets_.erase(packets_.begin());
-  EXPECT_EQ(packets_.size(), 1u);
-
-  // Move the extractor.
-  tls_chlo_extractor_ = std::move(other_extractor);
-
-  // Have |tls_chlo_extractor_| parse the second packet.
-  IngestPackets();
-
-  ValidateChloDetails();
-  EXPECT_EQ(tls_chlo_extractor_.state(),
-            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
deleted file mode 100644
index 9fdfe12..0000000
--- a/quic/core/tls_client_handshaker.cc
+++ /dev/null
@@ -1,649 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_client_handshaker.h"
-
-#include <cstring>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-TlsClientHandshaker::TlsClientHandshaker(
-    const QuicServerId& server_id,
-    QuicCryptoStream* stream,
-    QuicSession* session,
-    std::unique_ptr<ProofVerifyContext> verify_context,
-    QuicCryptoClientConfig* crypto_config,
-    QuicCryptoClientStream::ProofHandler* proof_handler,
-    bool has_application_state)
-    : TlsHandshaker(stream, session),
-      session_(session),
-      server_id_(server_id),
-      proof_verifier_(crypto_config->proof_verifier()),
-      verify_context_(std::move(verify_context)),
-      proof_handler_(proof_handler),
-      session_cache_(crypto_config->session_cache()),
-      user_agent_id_(crypto_config->user_agent_id()),
-      pre_shared_key_(crypto_config->pre_shared_key()),
-      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
-      has_application_state_(has_application_state),
-      tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()) {
-  if (crypto_config->tls_signature_algorithms().has_value()) {
-    SSL_set1_sigalgs_list(ssl(),
-                          crypto_config->tls_signature_algorithms()->c_str());
-  }
-  if (crypto_config->proof_source() != nullptr) {
-    const ClientProofSource::CertAndKey* cert_and_key =
-        crypto_config->proof_source()->GetCertAndKey(server_id.host());
-    if (cert_and_key != nullptr) {
-      QUIC_DVLOG(1) << "Setting client cert and key for " << server_id.host();
-      tls_connection_.SetCertChain(cert_and_key->chain->ToCryptoBuffers().value,
-                                   cert_and_key->private_key.private_key());
-    }
-  }
-}
-
-TlsClientHandshaker::~TlsClientHandshaker() {}
-
-bool TlsClientHandshaker::CryptoConnect() {
-  if (!pre_shared_key_.empty()) {
-    // TODO(b/154162689) add PSK support to QUIC+TLS.
-    std::string error_details =
-        "QUIC client pre-shared keys not yet supported with TLS";
-    QUIC_BUG(quic_bug_10576_1) << error_details;
-    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
-    return false;
-  }
-
-  // Make sure we use the right TLS extension codepoint.
-  int use_legacy_extension = 0;
-  if (session()->version().UsesLegacyTlsExtension()) {
-    use_legacy_extension = 1;
-  }
-  SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
-
-  // TODO(b/193650832) Add SetFromConfig to QUIC handshakers and remove reliance
-  // on session pointer.
-  const bool permutes_tls_extensions = session()->permutes_tls_extensions();
-  if (!permutes_tls_extensions) {
-    QUIC_DLOG(INFO) << "Disabling TLS extension permutation";
-  }
-#if BORINGSSL_API_VERSION >= 16
-  // Ask BoringSSL to randomize the order of TLS extensions.
-  SSL_set_permute_extensions(ssl(), permutes_tls_extensions);
-#endif  // BORINGSSL_API_VERSION
-
-  // Set the SNI to send, if any.
-  SSL_set_connect_state(ssl());
-  if (QUIC_DLOG_INFO_IS_ON() &&
-      !QuicHostnameUtils::IsValidSNI(server_id_.host())) {
-    QUIC_DLOG(INFO) << "Client configured with invalid hostname \""
-                    << server_id_.host() << "\", not sending as SNI";
-  }
-  if (!server_id_.host().empty() &&
-      (QuicHostnameUtils::IsValidSNI(server_id_.host()) ||
-       allow_invalid_sni_for_tests_) &&
-      SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
-    return false;
-  }
-
-  if (!SetAlpn()) {
-    CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
-    return false;
-  }
-
-  // Set the Transport Parameters to send in the ClientHello
-  if (!SetTransportParameters()) {
-    CloseConnection(QUIC_HANDSHAKE_FAILED,
-                    "Client failed to set Transport Parameters");
-    return false;
-  }
-
-  // Set a session to resume, if there is one.
-  if (session_cache_) {
-    cached_state_ = session_cache_->Lookup(
-        server_id_, session()->GetClock()->WallNow(), SSL_get_SSL_CTX(ssl()));
-  }
-  if (cached_state_) {
-    SSL_set_session(ssl(), cached_state_->tls_session.get());
-    if (!cached_state_->token.empty()) {
-      session()->SetSourceAddressTokenToSend(cached_state_->token);
-    }
-  }
-
-  // Start the handshake.
-  AdvanceHandshake();
-  return session()->connection()->connected();
-}
-
-bool TlsClientHandshaker::PrepareZeroRttConfig(
-    QuicResumptionState* cached_state) {
-  std::string error_details;
-  if (!cached_state->transport_params ||
-      handshaker_delegate()->ProcessTransportParameters(
-          *(cached_state->transport_params),
-          /*is_resumption = */ true, &error_details) != QUIC_NO_ERROR) {
-    QUIC_BUG(quic_bug_10576_2)
-        << "Unable to parse cached transport parameters.";
-    CloseConnection(QUIC_HANDSHAKE_FAILED,
-                    "Client failed to parse cached Transport Parameters.");
-    return false;
-  }
-
-  session()->connection()->OnTransportParametersResumed(
-      *(cached_state->transport_params));
-  session()->OnConfigNegotiated();
-
-  if (has_application_state_) {
-    if (!cached_state->application_state ||
-        !session()->ResumeApplicationState(
-            cached_state->application_state.get())) {
-      QUIC_BUG(quic_bug_10576_3) << "Unable to parse cached application state.";
-      CloseConnection(QUIC_HANDSHAKE_FAILED,
-                      "Client failed to parse cached application state.");
-      return false;
-    }
-  }
-  return true;
-}
-
-static bool IsValidAlpn(const std::string& alpn_string) {
-  return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
-}
-
-bool TlsClientHandshaker::SetAlpn() {
-  std::vector<std::string> alpns = session()->GetAlpnsToOffer();
-  if (alpns.empty()) {
-    if (allow_empty_alpn_for_tests_) {
-      return true;
-    }
-
-    QUIC_BUG(quic_bug_10576_4) << "ALPN missing";
-    return false;
-  }
-  if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
-    QUIC_BUG(quic_bug_10576_5) << "ALPN too long";
-    return false;
-  }
-
-  // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
-  // strings.
-  uint8_t alpn[1024];
-  QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
-  bool success = true;
-  for (const std::string& alpn_string : alpns) {
-    success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
-              alpn_writer.WriteStringPiece(alpn_string);
-  }
-  success =
-      success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
-  if (!success) {
-    QUIC_BUG(quic_bug_10576_6)
-        << "Failed to set ALPN: "
-        << quiche::QuicheTextUtils::HexDump(
-               absl::string_view(alpn_writer.data(), alpn_writer.length()));
-    return false;
-  }
-
-  // Enable ALPS only for versions that use HTTP/3 frames.
-  for (const std::string& alpn_string : alpns) {
-    for (const ParsedQuicVersion& version : session()->supported_versions()) {
-      if (!version.UsesHttp3() || AlpnForVersion(version) != alpn_string) {
-        continue;
-      }
-      if (SSL_add_application_settings(
-              ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
-              alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
-        QUIC_BUG(quic_bug_10576_7) << "Failed to enable ALPS.";
-        return false;
-      }
-      break;
-    }
-  }
-
-  QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
-  return true;
-}
-
-bool TlsClientHandshaker::SetTransportParameters() {
-  TransportParameters params;
-  params.perspective = Perspective::IS_CLIENT;
-  params.legacy_version_information =
-      TransportParameters::LegacyVersionInformation();
-  params.legacy_version_information.value().version =
-      CreateQuicVersionLabel(session()->supported_versions().front());
-  params.version_information = TransportParameters::VersionInformation();
-  const QuicVersionLabel version = CreateQuicVersionLabel(session()->version());
-  params.version_information.value().chosen_version = version;
-  params.version_information.value().other_versions.push_back(version);
-
-  if (!handshaker_delegate()->FillTransportParameters(&params)) {
-    return false;
-  }
-
-  // Notify QuicConnectionDebugVisitor.
-  session()->connection()->OnTransportParametersSent(params);
-
-  std::vector<uint8_t> param_bytes;
-  return SerializeTransportParameters(session()->connection()->version(),
-                                      params, &param_bytes) &&
-         SSL_set_quic_transport_params(ssl(), param_bytes.data(),
-                                       param_bytes.size()) == 1;
-}
-
-bool TlsClientHandshaker::ProcessTransportParameters(
-    std::string* error_details) {
-  received_transport_params_ = std::make_unique<TransportParameters>();
-  const uint8_t* param_bytes;
-  size_t param_bytes_len;
-  SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
-  if (param_bytes_len == 0) {
-    *error_details = "Server's transport parameters are missing";
-    return false;
-  }
-  std::string parse_error_details;
-  if (!ParseTransportParameters(
-          session()->connection()->version(), Perspective::IS_SERVER,
-          param_bytes, param_bytes_len, received_transport_params_.get(),
-          &parse_error_details)) {
-    QUICHE_DCHECK(!parse_error_details.empty());
-    *error_details =
-        "Unable to parse server's transport parameters: " + parse_error_details;
-    return false;
-  }
-
-  // Notify QuicConnectionDebugVisitor.
-  session()->connection()->OnTransportParametersReceived(
-      *received_transport_params_);
-
-  if (received_transport_params_->legacy_version_information.has_value()) {
-    if (received_transport_params_->legacy_version_information.value()
-            .version !=
-        CreateQuicVersionLabel(session()->connection()->version())) {
-      *error_details = "Version mismatch detected";
-      return false;
-    }
-    if (CryptoUtils::ValidateServerHelloVersions(
-            received_transport_params_->legacy_version_information.value()
-                .supported_versions,
-            session()->connection()->server_supported_versions(),
-            error_details) != QUIC_NO_ERROR) {
-      QUICHE_DCHECK(!error_details->empty());
-      return false;
-    }
-  }
-  if (received_transport_params_->version_information.has_value()) {
-    if (!CryptoUtils::ValidateChosenVersion(
-            received_transport_params_->version_information.value()
-                .chosen_version,
-            session()->version(), error_details)) {
-      QUICHE_DCHECK(!error_details->empty());
-      return false;
-    }
-    if (!CryptoUtils::CryptoUtils::ValidateServerVersions(
-            received_transport_params_->version_information.value()
-                .other_versions,
-            session()->version(),
-            session()->client_original_supported_versions(), error_details)) {
-      QUICHE_DCHECK(!error_details->empty());
-      return false;
-    }
-  }
-
-  if (handshaker_delegate()->ProcessTransportParameters(
-          *received_transport_params_, /* is_resumption = */ false,
-          error_details) != QUIC_NO_ERROR) {
-    QUICHE_DCHECK(!error_details->empty());
-    return false;
-  }
-
-  session()->OnConfigNegotiated();
-  if (is_connection_closed()) {
-    *error_details =
-        "Session closed the connection when parsing negotiated config.";
-    return false;
-  }
-  return true;
-}
-
-int TlsClientHandshaker::num_sent_client_hellos() const {
-  return 0;
-}
-
-bool TlsClientHandshaker::IsResumption() const {
-  QUIC_BUG_IF(quic_bug_12736_1, !one_rtt_keys_available());
-  return SSL_session_reused(ssl()) == 1;
-}
-
-bool TlsClientHandshaker::EarlyDataAccepted() const {
-  QUIC_BUG_IF(quic_bug_12736_2, !one_rtt_keys_available());
-  return SSL_early_data_accepted(ssl()) == 1;
-}
-
-ssl_early_data_reason_t TlsClientHandshaker::EarlyDataReason() const {
-  return TlsHandshaker::EarlyDataReason();
-}
-
-bool TlsClientHandshaker::ReceivedInchoateReject() const {
-  QUIC_BUG_IF(quic_bug_12736_3, !one_rtt_keys_available());
-  // REJ messages are a QUIC crypto feature, so TLS always returns false.
-  return false;
-}
-
-int TlsClientHandshaker::num_scup_messages_received() const {
-  // SCUP messages aren't sent or received when using the TLS handshake.
-  return 0;
-}
-
-std::string TlsClientHandshaker::chlo_hash() const {
-  return "";
-}
-
-bool TlsClientHandshaker::ExportKeyingMaterial(absl::string_view label,
-                                               absl::string_view context,
-                                               size_t result_len,
-                                               std::string* result) {
-  return ExportKeyingMaterialForLabel(label, context, result_len, result);
-}
-
-bool TlsClientHandshaker::encryption_established() const {
-  return encryption_established_;
-}
-
-bool TlsClientHandshaker::one_rtt_keys_available() const {
-  return state_ >= HANDSHAKE_COMPLETE;
-}
-
-const QuicCryptoNegotiatedParameters&
-TlsClientHandshaker::crypto_negotiated_params() const {
-  return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
-  return TlsHandshaker::crypto_message_parser();
-}
-
-HandshakeState TlsClientHandshaker::GetHandshakeState() const {
-  return state_;
-}
-
-size_t TlsClientHandshaker::BufferSizeLimitForLevel(
-    EncryptionLevel level) const {
-  return TlsHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter>
-TlsClientHandshaker::CreateCurrentOneRttEncrypter() {
-  return TlsHandshaker::CreateCurrentOneRttEncrypter();
-}
-
-void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
-  OnHandshakeConfirmed();
-}
-
-void TlsClientHandshaker::OnHandshakePacketSent() {
-  if (initial_keys_dropped_) {
-    return;
-  }
-  initial_keys_dropped_ = true;
-  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
-}
-
-void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode error,
-                                             ConnectionCloseSource source) {
-  TlsHandshaker::OnConnectionClosed(error, source);
-}
-
-void TlsClientHandshaker::OnHandshakeDoneReceived() {
-  if (!one_rtt_keys_available()) {
-    CloseConnection(QUIC_HANDSHAKE_FAILED,
-                    "Unexpected handshake done received");
-    return;
-  }
-  OnHandshakeConfirmed();
-}
-
-void TlsClientHandshaker::OnNewTokenReceived(absl::string_view token) {
-  if (token.empty()) {
-    return;
-  }
-  if (session_cache_ != nullptr) {
-    session_cache_->OnNewTokenReceived(server_id_, token);
-  }
-}
-
-void TlsClientHandshaker::SetWriteSecret(
-    EncryptionLevel level,
-    const SSL_CIPHER* cipher,
-    const std::vector<uint8_t>& write_secret) {
-  if (is_connection_closed()) {
-    return;
-  }
-  if (level == ENCRYPTION_FORWARD_SECURE || level == ENCRYPTION_ZERO_RTT) {
-    encryption_established_ = true;
-  }
-  TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
-  if (level == ENCRYPTION_FORWARD_SECURE) {
-    handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT);
-  }
-}
-
-void TlsClientHandshaker::OnHandshakeConfirmed() {
-  QUICHE_DCHECK(one_rtt_keys_available());
-  if (state_ >= HANDSHAKE_CONFIRMED) {
-    return;
-  }
-  state_ = HANDSHAKE_CONFIRMED;
-  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
-  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
-}
-
-QuicAsyncStatus TlsClientHandshaker::VerifyCertChain(
-    const std::vector<std::string>& certs,
-    std::string* error_details,
-    std::unique_ptr<ProofVerifyDetails>* details,
-    uint8_t* out_alert,
-    std::unique_ptr<ProofVerifierCallback> callback) {
-  const uint8_t* ocsp_response_raw;
-  size_t ocsp_response_len;
-  SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
-  std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
-                            ocsp_response_len);
-  const uint8_t* sct_list_raw;
-  size_t sct_list_len;
-  SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
-  std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
-                       sct_list_len);
-
-  return proof_verifier_->VerifyCertChain(
-      server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list,
-      verify_context_.get(), error_details, details, out_alert,
-      std::move(callback));
-}
-
-void TlsClientHandshaker::OnProofVerifyDetailsAvailable(
-    const ProofVerifyDetails& verify_details) {
-  proof_handler_->OnProofVerifyDetailsAvailable(verify_details);
-}
-
-void TlsClientHandshaker::FinishHandshake() {
-  FillNegotiatedParams();
-
-  QUICHE_CHECK(!SSL_in_early_data(ssl()));
-
-  QUIC_LOG(INFO) << "Client: handshake finished";
-
-  std::string error_details;
-  if (!ProcessTransportParameters(&error_details)) {
-    QUICHE_DCHECK(!error_details.empty());
-    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
-    return;
-  }
-
-  const uint8_t* alpn_data = nullptr;
-  unsigned alpn_length = 0;
-  SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
-
-  if (alpn_length == 0) {
-    QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
-    // TODO(b/130164908) this should send no_application_protocol
-    // instead of QUIC_HANDSHAKE_FAILED.
-    CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
-    return;
-  }
-
-  std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
-                                   alpn_length);
-  std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
-  if (std::find(offered_alpns.begin(), offered_alpns.end(),
-                received_alpn_string) == offered_alpns.end()) {
-    QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
-                    << received_alpn_string;
-    // TODO(b/130164908) this should send no_application_protocol
-    // instead of QUIC_HANDSHAKE_FAILED.
-    CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
-    return;
-  }
-  session()->OnAlpnSelected(received_alpn_string);
-  QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
-                  << "'";
-
-  // Parse ALPS extension.
-  const uint8_t* alps_data;
-  size_t alps_length;
-  SSL_get0_peer_application_settings(ssl(), &alps_data, &alps_length);
-  if (alps_length > 0) {
-    auto error = session()->OnAlpsData(alps_data, alps_length);
-    if (error) {
-      // Calling CloseConnection() is safe even in case OnAlpsData() has
-      // already closed the connection.
-      CloseConnection(
-          QUIC_HANDSHAKE_FAILED,
-          absl::StrCat("Error processing ALPS data: ", error.value()));
-      return;
-    }
-  }
-
-  state_ = HANDSHAKE_COMPLETE;
-  handshaker_delegate()->OnTlsHandshakeComplete();
-}
-
-void TlsClientHandshaker::OnEnterEarlyData() {
-  QUICHE_DCHECK(SSL_in_early_data(ssl()));
-
-  // TODO(wub): It might be unnecessary to FillNegotiatedParams() at this time,
-  // because we fill it again when handshake completes.
-  FillNegotiatedParams();
-
-  // If we're attempting a 0-RTT handshake, then we need to let the transport
-  // and application know what state to apply to early data.
-  PrepareZeroRttConfig(cached_state_.get());
-}
-
-void TlsClientHandshaker::FillNegotiatedParams() {
-  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
-  if (cipher) {
-    crypto_negotiated_params_->cipher_suite =
-        SSL_CIPHER_get_protocol_id(cipher);
-  }
-  crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
-  crypto_negotiated_params_->peer_signature_algorithm =
-      SSL_get_peer_signature_algorithm(ssl());
-}
-
-void TlsClientHandshaker::ProcessPostHandshakeMessage() {
-  int rv = SSL_process_quic_post_handshake(ssl());
-  if (rv != 1) {
-    CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
-  }
-}
-
-bool TlsClientHandshaker::ShouldCloseConnectionOnUnexpectedError(
-    int ssl_error) {
-  if (ssl_error != SSL_ERROR_EARLY_DATA_REJECTED) {
-    return true;
-  }
-  HandleZeroRttReject();
-  return false;
-}
-
-void TlsClientHandshaker::HandleZeroRttReject() {
-  QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server";
-  QUICHE_DCHECK(session_cache_);
-  // Disable encrytion to block outgoing data until 1-RTT keys are available.
-  encryption_established_ = false;
-  handshaker_delegate()->OnZeroRttRejected(EarlyDataReason());
-  SSL_reset_early_data_reject(ssl());
-  session_cache_->ClearEarlyData(server_id_);
-  AdvanceHandshake();
-}
-
-void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
-  if (!received_transport_params_) {
-    QUIC_BUG(quic_bug_10576_8) << "Transport parameters isn't received";
-    return;
-  }
-  if (session_cache_ == nullptr) {
-    QUIC_DVLOG(1) << "No session cache, not inserting a session";
-    return;
-  }
-  if (has_application_state_ && !received_application_state_) {
-    // Application state is not received yet. cache the sessions.
-    if (cached_tls_sessions_[0] != nullptr) {
-      cached_tls_sessions_[1] = std::move(cached_tls_sessions_[0]);
-    }
-    cached_tls_sessions_[0] = std::move(session);
-    return;
-  }
-  session_cache_->Insert(server_id_, std::move(session),
-                         *received_transport_params_,
-                         received_application_state_.get());
-}
-
-void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
-                                       absl::string_view data) {
-  if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
-    state_ = HANDSHAKE_PROCESSED;
-  }
-  TlsHandshaker::WriteMessage(level, data);
-}
-
-void TlsClientHandshaker::SetServerApplicationStateForResumption(
-    std::unique_ptr<ApplicationState> application_state) {
-  QUICHE_DCHECK(one_rtt_keys_available());
-  received_application_state_ = std::move(application_state);
-  // At least one tls session is cached before application state is received. So
-  // insert now.
-  if (session_cache_ != nullptr && cached_tls_sessions_[0] != nullptr) {
-    if (cached_tls_sessions_[1] != nullptr) {
-      // Insert the older session first.
-      session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[1]),
-                             *received_transport_params_,
-                             received_application_state_.get());
-    }
-    session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[0]),
-                           *received_transport_params_,
-                           received_application_state_.get());
-  }
-}
-
-}  // namespace quic
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h
deleted file mode 100644
index 3551b32..0000000
--- a/quic/core/tls_client_handshaker.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/tls_client_connection.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/tls_handshaker.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
-// TLS 1.3 for the crypto handshake protocol.
-class QUIC_EXPORT_PRIVATE TlsClientHandshaker
-    : public TlsHandshaker,
-      public QuicCryptoClientStream::HandshakerInterface,
-      public TlsClientConnection::Delegate {
- public:
-  // |crypto_config| must outlive TlsClientHandshaker.
-  TlsClientHandshaker(const QuicServerId& server_id,
-                      QuicCryptoStream* stream,
-                      QuicSession* session,
-                      std::unique_ptr<ProofVerifyContext> verify_context,
-                      QuicCryptoClientConfig* crypto_config,
-                      QuicCryptoClientStream::ProofHandler* proof_handler,
-                      bool has_application_state);
-  TlsClientHandshaker(const TlsClientHandshaker&) = delete;
-  TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete;
-
-  ~TlsClientHandshaker() override;
-
-  // From QuicCryptoClientStream::HandshakerInterface
-  bool CryptoConnect() override;
-  int num_sent_client_hellos() const override;
-  bool IsResumption() const override;
-  bool EarlyDataAccepted() const override;
-  ssl_early_data_reason_t EarlyDataReason() const override;
-  bool ReceivedInchoateReject() const override;
-  int num_scup_messages_received() const override;
-  std::string chlo_hash() const override;
-  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
-                            size_t result_len, std::string* result) override;
-
-  // From QuicCryptoClientStream::HandshakerInterface and TlsHandshaker
-  bool encryption_established() const override;
-  bool one_rtt_keys_available() const override;
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override;
-  CryptoMessageParser* crypto_message_parser() override;
-  HandshakeState GetHandshakeState() const override;
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-  void OnOneRttPacketAcknowledged() override;
-  void OnHandshakePacketSent() override;
-  void OnConnectionClosed(QuicErrorCode error,
-                          ConnectionCloseSource source) override;
-  void OnHandshakeDoneReceived() override;
-  void OnNewTokenReceived(absl::string_view token) override;
-  void SetWriteSecret(EncryptionLevel level,
-                      const SSL_CIPHER* cipher,
-                      const std::vector<uint8_t>& write_secret) override;
-
-  // Override to drop initial keys if trying to write ENCRYPTION_HANDSHAKE data.
-  void WriteMessage(EncryptionLevel level, absl::string_view data) override;
-
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> application_state) override;
-
-  void AllowEmptyAlpnForTests() { allow_empty_alpn_for_tests_ = true; }
-  void AllowInvalidSNIForTests() { allow_invalid_sni_for_tests_ = true; }
-
-  // Make the SSL object from BoringSSL publicly accessible.
-  using TlsHandshaker::ssl;
-
- protected:
-  const TlsConnection* tls_connection() const override {
-    return &tls_connection_;
-  }
-
-  void FinishHandshake() override;
-  void OnEnterEarlyData() override;
-  void FillNegotiatedParams();
-  void ProcessPostHandshakeMessage() override;
-  bool ShouldCloseConnectionOnUnexpectedError(int ssl_error) override;
-  QuicAsyncStatus VerifyCertChain(
-      const std::vector<std::string>& certs,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) override;
-  void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& verify_details) override;
-
-  // TlsClientConnection::Delegate implementation:
-  TlsConnection::Delegate* ConnectionDelegate() override { return this; }
-
- private:
-  bool SetAlpn();
-  bool SetTransportParameters();
-  bool ProcessTransportParameters(std::string* error_details);
-  void HandleZeroRttReject();
-
-  // Called when server completes handshake (i.e., either handshake done is
-  // received or 1-RTT packet gets acknowledged).
-  void OnHandshakeConfirmed();
-
-  void InsertSession(bssl::UniquePtr<SSL_SESSION> session) override;
-
-  bool PrepareZeroRttConfig(QuicResumptionState* cached_state);
-
-  QuicSession* session() { return session_; }
-  QuicSession* session_;
-
-  QuicServerId server_id_;
-
-  // Objects used for verifying the server's certificate chain.
-  // |proof_verifier_| is owned by the caller of TlsHandshaker's constructor.
-  ProofVerifier* proof_verifier_;
-  std::unique_ptr<ProofVerifyContext> verify_context_;
-
-  // Unowned pointer to the proof handler which has the
-  // OnProofVerifyDetailsAvailable callback to use for notifying the result of
-  // certificate verification.
-  QuicCryptoClientStream::ProofHandler* proof_handler_;
-
-  // Used for session resumption. |session_cache_| is owned by the
-  // QuicCryptoClientConfig passed into TlsClientHandshaker's constructor.
-  SessionCache* session_cache_;
-
-  std::string user_agent_id_;
-
-  // Pre-shared key used during the handshake.
-  std::string pre_shared_key_;
-
-  HandshakeState state_ = HANDSHAKE_START;
-  bool encryption_established_ = false;
-  bool initial_keys_dropped_ = false;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      crypto_negotiated_params_;
-
-  bool allow_empty_alpn_for_tests_ = false;
-  bool allow_invalid_sni_for_tests_ = false;
-
-  const bool has_application_state_;
-  // Contains the state for performing a resumption, if one is attempted. This
-  // will always be non-null if a 0-RTT resumption is attempted.
-  std::unique_ptr<QuicResumptionState> cached_state_;
-
-  TlsClientConnection tls_connection_;
-
-  // If |has_application_state_|, stores the tls session tickets before
-  // application state is received. The latest one is put in the front.
-  bssl::UniquePtr<SSL_SESSION> cached_tls_sessions_[2] = {};
-
-  std::unique_ptr<TransportParameters> received_transport_params_ = nullptr;
-  std::unique_ptr<ApplicationState> received_application_state_ = nullptr;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
diff --git a/quic/core/tls_client_handshaker_test.cc b/quic/core/tls_client_handshaker_test.cc
deleted file mode 100644
index 4bbb4ed..0000000
--- a/quic/core/tls_client_handshaker_test.cc
+++ /dev/null
@@ -1,712 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-using testing::_;
-
-namespace quic {
-namespace test {
-namespace {
-
-constexpr char kServerHostname[] = "test.example.com";
-constexpr uint16_t kServerPort = 443;
-
-// TestProofVerifier wraps ProofVerifierForTesting, except for VerifyCertChain
-// which, if TestProofVerifier is active, always returns QUIC_PENDING. (If this
-// test proof verifier is not active, it delegates VerifyCertChain to the
-// ProofVerifierForTesting.) The pending VerifyCertChain operation can be
-// completed by calling InvokePendingCallback. This allows for testing
-// asynchronous VerifyCertChain operations.
-class TestProofVerifier : public ProofVerifier {
- public:
-  TestProofVerifier()
-      : verifier_(crypto_test_utils::ProofVerifierForTesting()) {}
-
-  QuicAsyncStatus VerifyProof(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::string& server_config,
-      QuicTransportVersion quic_version,
-      absl::string_view chlo_hash,
-      const std::vector<std::string>& certs,
-      const std::string& cert_sct,
-      const std::string& signature,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      std::unique_ptr<ProofVerifierCallback> callback) override {
-    return verifier_->VerifyProof(
-        hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
-        signature, context, error_details, details, std::move(callback));
-  }
-
-  QuicAsyncStatus VerifyCertChain(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::vector<std::string>& certs,
-      const std::string& ocsp_response,
-      const std::string& cert_sct,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) override {
-    if (!active_) {
-      return verifier_->VerifyCertChain(
-          hostname, port, certs, ocsp_response, cert_sct, context,
-          error_details, details, out_alert, std::move(callback));
-    }
-    pending_ops_.push_back(std::make_unique<VerifyChainPendingOp>(
-        hostname, port, certs, ocsp_response, cert_sct, context, error_details,
-        details, out_alert, std::move(callback), verifier_.get()));
-    return QUIC_PENDING;
-  }
-
-  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
-    return nullptr;
-  }
-
-  void Activate() { active_ = true; }
-
-  size_t NumPendingCallbacks() const { return pending_ops_.size(); }
-
-  void InvokePendingCallback(size_t n) {
-    ASSERT_GT(NumPendingCallbacks(), n);
-    pending_ops_[n]->Run();
-    auto it = pending_ops_.begin() + n;
-    pending_ops_.erase(it);
-  }
-
- private:
-  // Implementation of ProofVerifierCallback that fails if the callback is ever
-  // run.
-  class FailingProofVerifierCallback : public ProofVerifierCallback {
-   public:
-    void Run(bool /*ok*/,
-             const std::string& /*error_details*/,
-             std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
-      FAIL();
-    }
-  };
-
-  class VerifyChainPendingOp {
-   public:
-    VerifyChainPendingOp(const std::string& hostname,
-                         const uint16_t port,
-                         const std::vector<std::string>& certs,
-                         const std::string& ocsp_response,
-                         const std::string& cert_sct,
-                         const ProofVerifyContext* context,
-                         std::string* error_details,
-                         std::unique_ptr<ProofVerifyDetails>* details,
-                         uint8_t* out_alert,
-                         std::unique_ptr<ProofVerifierCallback> callback,
-                         ProofVerifier* delegate)
-        : hostname_(hostname),
-          port_(port),
-          certs_(certs),
-          ocsp_response_(ocsp_response),
-          cert_sct_(cert_sct),
-          context_(context),
-          error_details_(error_details),
-          details_(details),
-          out_alert_(out_alert),
-          callback_(std::move(callback)),
-          delegate_(delegate) {}
-
-    void Run() {
-      // TestProofVerifier depends on crypto_test_utils::ProofVerifierForTesting
-      // running synchronously. It passes a FailingProofVerifierCallback and
-      // runs the original callback after asserting that the verification ran
-      // synchronously.
-      QuicAsyncStatus status = delegate_->VerifyCertChain(
-          hostname_, port_, certs_, ocsp_response_, cert_sct_, context_,
-          error_details_, details_, out_alert_,
-          std::make_unique<FailingProofVerifierCallback>());
-      ASSERT_NE(status, QUIC_PENDING);
-      callback_->Run(status == QUIC_SUCCESS, *error_details_, details_);
-    }
-
-   private:
-    std::string hostname_;
-    const uint16_t port_;
-    std::vector<std::string> certs_;
-    std::string ocsp_response_;
-    std::string cert_sct_;
-    const ProofVerifyContext* context_;
-    std::string* error_details_;
-    std::unique_ptr<ProofVerifyDetails>* details_;
-    uint8_t* out_alert_;
-    std::unique_ptr<ProofVerifierCallback> callback_;
-    ProofVerifier* delegate_;
-  };
-
-  std::unique_ptr<ProofVerifier> verifier_;
-  bool active_ = false;
-  std::vector<std::unique_ptr<VerifyChainPendingOp>> pending_ops_;
-};
-
-class TlsClientHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  TlsClientHandshakerTest()
-      : supported_versions_({GetParam()}),
-        server_id_(kServerHostname, kServerPort, false),
-        server_compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
-    crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
-        std::make_unique<TestProofVerifier>(),
-        std::make_unique<test::SimpleSessionCache>());
-    server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
-    CreateConnection();
-  }
-
-  void CreateSession() {
-    session_ = std::make_unique<TestQuicSpdyClientSession>(
-        connection_, DefaultQuicConfig(), supported_versions_, server_id_,
-        crypto_config_.get());
-    EXPECT_CALL(*session_, GetAlpnsToOffer())
-        .WillRepeatedly(testing::Return(std::vector<std::string>(
-            {AlpnForVersion(connection_->version())})));
-  }
-
-  void CreateConnection() {
-    connection_ =
-        new PacketSavingConnection(&client_helper_, &alarm_factory_,
-                                   Perspective::IS_CLIENT, supported_versions_);
-    // Advance the time, because timers do not like uninitialized times.
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    CreateSession();
-  }
-
-  void CompleteCryptoHandshake() {
-    CompleteCryptoHandshakeWithServerALPN(
-        AlpnForVersion(connection_->version()));
-  }
-
-  void CompleteCryptoHandshakeWithServerALPN(const std::string& alpn) {
-    EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
-        .Times(testing::AnyNumber());
-    stream()->CryptoConnect();
-    QuicConfig config;
-    crypto_test_utils::HandshakeWithFakeServer(
-        &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
-        connection_, stream(), alpn);
-  }
-
-  QuicCryptoClientStream* stream() {
-    return session_->GetMutableCryptoStream();
-  }
-
-  QuicCryptoServerStreamBase* server_stream() {
-    return server_session_->GetMutableCryptoStream();
-  }
-
-  // Initializes a fake server, and all its associated state, for testing.
-  void InitializeFakeServer() {
-    TestQuicSpdyServerSession* server_session = nullptr;
-    CreateServerSessionForTest(
-        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
-        &server_helper_, &alarm_factory_, server_crypto_config_.get(),
-        &server_compressed_certs_cache_, &server_connection_, &server_session);
-    server_session_.reset(server_session);
-    std::string alpn = AlpnForVersion(connection_->version());
-    EXPECT_CALL(*server_session_, SelectAlpn(_))
-        .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
-          return std::find(alpns.cbegin(), alpns.cend(), alpn);
-        });
-  }
-
-  MockQuicConnectionHelper server_helper_;
-  MockQuicConnectionHelper client_helper_;
-  MockAlarmFactory alarm_factory_;
-  PacketSavingConnection* connection_;
-  ParsedQuicVersionVector supported_versions_;
-  std::unique_ptr<TestQuicSpdyClientSession> session_;
-  QuicServerId server_id_;
-  CryptoHandshakeMessage message_;
-  std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
-
-  // Server state.
-  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
-  PacketSavingConnection* server_connection_;
-  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
-  QuicCompressedCertsCache server_compressed_certs_cache_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TlsHandshakerTests,
-                         TlsClientHandshakerTest,
-                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(TlsClientHandshakerTest, NotInitiallyConnected) {
-  EXPECT_FALSE(stream()->encryption_established());
-  EXPECT_FALSE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, ConnectedAfterHandshake) {
-  CompleteCryptoHandshake();
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-}
-
-TEST_P(TlsClientHandshakerTest, ConnectionClosedOnTlsError) {
-  // Have client send ClientHello.
-  stream()->CryptoConnect();
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
-
-  // Send a zero-length ServerHello from server to client.
-  char bogus_handshake_message[] = {
-      // Handshake struct (RFC 8446 appendix B.3)
-      2,        // HandshakeType server_hello
-      0, 0, 0,  // uint24 length
-  };
-  stream()->crypto_message_parser()->ProcessInput(
-      absl::string_view(bogus_handshake_message,
-                        ABSL_ARRAYSIZE(bogus_handshake_message)),
-      ENCRYPTION_INITIAL);
-
-  EXPECT_FALSE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, ProofVerifyDetailsAvailableAfterHandshake) {
-  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
-  stream()->CryptoConnect();
-  QuicConfig config;
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
-      connection_, stream(), AlpnForVersion(connection_->version()));
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, HandshakeWithAsyncProofVerifier) {
-  InitializeFakeServer();
-
-  // Enable TestProofVerifier to capture call to VerifyCertChain and run it
-  // asynchronously.
-  TestProofVerifier* proof_verifier =
-      static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
-  proof_verifier->Activate();
-
-  stream()->CryptoConnect();
-  // Exchange handshake messages.
-  std::pair<size_t, size_t> moved_message_counts =
-      crypto_test_utils::AdvanceHandshake(
-          connection_, stream(), 0, server_connection_, server_stream(), 0);
-
-  ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
-  proof_verifier->InvokePendingCallback(0);
-
-  // Exchange more handshake messages.
-  crypto_test_utils::AdvanceHandshake(
-      connection_, stream(), moved_message_counts.first, server_connection_,
-      server_stream(), moved_message_counts.second);
-
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsClientHandshakerTest, Resumption) {
-  // Disable 0-RTT on the server so that we're only testing 1-RTT resumption:
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection
-  CreateConnection();
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_TRUE(stream()->IsResumption());
-}
-
-TEST_P(TlsClientHandshakerTest, ResumptionRejection) {
-  // Disable 0-RTT on the server before the first connection so the client
-  // doesn't attempt a 0-RTT resumption, only a 1-RTT resumption.
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection, but disable resumption on the server.
-  SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
-  CreateConnection();
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-  EXPECT_FALSE(stream()->EarlyDataAccepted());
-  EXPECT_EQ(stream()->EarlyDataReason(),
-            ssl_early_data_unsupported_for_session);
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRttResumption) {
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection
-  CreateConnection();
-  // OnConfigNegotiated should be called twice - once when processing saved
-  // 0-RTT transport parameters, and then again when receiving transport
-  // parameters from the server.
-  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
-      .Times(testing::AnyNumber());
-  // Start the second handshake and confirm we have keys before receiving any
-  // messages from the server.
-  stream()->CryptoConnect();
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_NE(stream()->crypto_negotiated_params().cipher_suite, 0);
-  EXPECT_NE(stream()->crypto_negotiated_params().key_exchange_group, 0);
-  EXPECT_NE(stream()->crypto_negotiated_params().peer_signature_algorithm, 0);
-  // Finish the handshake with the server.
-  QuicConfig config;
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
-      connection_, stream(), AlpnForVersion(connection_->version()));
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_TRUE(stream()->IsResumption());
-  EXPECT_TRUE(stream()->EarlyDataAccepted());
-  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_accepted);
-}
-
-// Regression test for b/186438140.
-TEST_P(TlsClientHandshakerTest, ZeroRttResumptionWithAyncProofVerifier) {
-  // Finish establishing the first connection, so the second connection can
-  // resume.
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection.
-  CreateConnection();
-  InitializeFakeServer();
-  EXPECT_CALL(*session_, OnConfigNegotiated());
-  EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
-      .Times(testing::AnyNumber());
-  // Enable TestProofVerifier to capture the call to VerifyCertChain and run it
-  // asynchronously.
-  TestProofVerifier* proof_verifier =
-      static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
-  proof_verifier->Activate();
-  // Start the second handshake.
-  stream()->CryptoConnect();
-
-  ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
-
-  // Advance the handshake with the server. Since cert verification has not
-  // finished yet, client cannot derive HANDSHAKE and 1-RTT keys.
-  crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
-                                      server_connection_, server_stream(), 0);
-
-  EXPECT_FALSE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-
-  // Finish cert verification after receiving packets from server.
-  proof_verifier->InvokePendingCallback(0);
-
-  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
-  // Verify client has derived HANDSHAKE key.
-  EXPECT_NE(nullptr,
-            QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_HANDSHAKE));
-
-  // Ideally, we should also verify that the process_undecryptable_packets_alarm
-  // is set and processing the undecryptable packets can advance the handshake
-  // to completion. Unfortunately, the test facilities used in this test does
-  // not support queuing and processing undecryptable packets.
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRttRejection) {
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection, but disable 0-RTT on the server.
-  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
-  CreateConnection();
-
-  // OnConfigNegotiated should be called twice - once when processing saved
-  // 0-RTT transport parameters, and then again when receiving transport
-  // parameters from the server.
-  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
-
-  // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
-  // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
-  // packet retransmission.
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
-  if (VersionUsesHttp3(session_->transport_version())) {
-    EXPECT_CALL(*connection_,
-                OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
-  }
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
-  if (VersionUsesHttp3(session_->transport_version())) {
-    // TODO(b/158027651): change transmission type to
-    // ALL_ZERO_RTT_RETRANSMISSION.
-    EXPECT_CALL(*connection_,
-                OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
-  }
-
-  CompleteCryptoHandshake();
-
-  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
-  EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_TRUE(stream()->IsResumption());
-  EXPECT_FALSE(stream()->EarlyDataAccepted());
-  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_peer_declined);
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRttAndResumptionRejection) {
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection, but disable resumption on the server.
-  SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
-  CreateConnection();
-
-  // OnConfigNegotiated should be called twice - once when processing saved
-  // 0-RTT transport parameters, and then again when receiving transport
-  // parameters from the server.
-  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
-
-  // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
-  // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
-  // packet retransmission.
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
-  if (VersionUsesHttp3(session_->transport_version())) {
-    EXPECT_CALL(*connection_,
-                OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
-  }
-  EXPECT_CALL(*connection_,
-              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
-  if (VersionUsesHttp3(session_->transport_version())) {
-    // TODO(b/158027651): change transmission type to
-    // ALL_ZERO_RTT_RETRANSMISSION.
-    EXPECT_CALL(*connection_,
-                OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
-  }
-
-  CompleteCryptoHandshake();
-
-  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
-  EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-  EXPECT_FALSE(stream()->EarlyDataAccepted());
-  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_session_not_resumed);
-}
-
-TEST_P(TlsClientHandshakerTest, ClientSendsNoSNI) {
-  // Reconfigure client to sent an empty server hostname. The crypto config also
-  // needs to be recreated to use a FakeProofVerifier since the server's cert
-  // won't match the empty hostname.
-  server_id_ = QuicServerId("", 443);
-  crypto_config_.reset(new QuicCryptoClientConfig(
-      std::make_unique<FakeProofVerifier>(), nullptr));
-  CreateConnection();
-  InitializeFakeServer();
-
-  stream()->CryptoConnect();
-  crypto_test_utils::CommunicateHandshakeMessages(
-      connection_, stream(), server_connection_, server_stream());
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-
-  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
-}
-
-TEST_P(TlsClientHandshakerTest, ClientSendingTooManyALPNs) {
-  std::string long_alpn(250, 'A');
-  EXPECT_CALL(*session_, GetAlpnsToOffer())
-      .WillOnce(testing::Return(std::vector<std::string>({
-          long_alpn + "1",
-          long_alpn + "2",
-          long_alpn + "3",
-          long_alpn + "4",
-          long_alpn + "5",
-          long_alpn + "6",
-          long_alpn + "7",
-          long_alpn + "8",
-      })));
-  EXPECT_QUIC_BUG(stream()->CryptoConnect(), "Failed to set ALPN");
-}
-
-TEST_P(TlsClientHandshakerTest, ServerRequiresCustomALPN) {
-  InitializeFakeServer();
-  const std::string kTestAlpn = "An ALPN That Client Did Not Offer";
-  EXPECT_CALL(*server_session_, SelectAlpn(_))
-      .WillOnce([kTestAlpn](const std::vector<absl::string_view>& alpns) {
-        return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
-      });
-
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED,
-                              static_cast<QuicIetfTransportErrorCodes>(
-                                  CRYPTO_ERROR_FIRST + 120),
-                              "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
-                              "no application protocol",
-                              _));
-
-  stream()->CryptoConnect();
-  crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
-                                      server_connection_, server_stream(), 0);
-
-  EXPECT_FALSE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->encryption_established());
-}
-
-TEST_P(TlsClientHandshakerTest, ZeroRTTNotAttemptedOnALPNChange) {
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->IsResumption());
-
-  // Create a second connection
-  CreateConnection();
-  // Override the ALPN to send on the second connection.
-  const std::string kTestAlpn = "Test ALPN";
-  EXPECT_CALL(*session_, GetAlpnsToOffer())
-      .WillRepeatedly(testing::Return(std::vector<std::string>({kTestAlpn})));
-  // OnConfigNegotiated should only be called once: when transport parameters
-  // are received from the server.
-  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(1);
-
-  CompleteCryptoHandshakeWithServerALPN(kTestAlpn);
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-  EXPECT_FALSE(stream()->EarlyDataAccepted());
-  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_alpn_mismatch);
-}
-
-TEST_P(TlsClientHandshakerTest, InvalidSNI) {
-  // Test that a client will skip sending SNI if configured to send an invalid
-  // hostname. In this case, the inclusion of '!' is invalid.
-  server_id_ = QuicServerId("invalid!.example.com", 443);
-  crypto_config_.reset(new QuicCryptoClientConfig(
-      std::make_unique<FakeProofVerifier>(), nullptr));
-  CreateConnection();
-  InitializeFakeServer();
-
-  stream()->CryptoConnect();
-  crypto_test_utils::CommunicateHandshakeMessages(
-      connection_, stream(), server_connection_, server_stream());
-
-  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
-  EXPECT_TRUE(stream()->encryption_established());
-  EXPECT_TRUE(stream()->one_rtt_keys_available());
-
-  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
-}
-
-TEST_P(TlsClientHandshakerTest, BadTransportParams) {
-  if (!connection_->version().UsesHttp3()) {
-    return;
-  }
-  // Finish establishing the first connection:
-  CompleteCryptoHandshake();
-
-  // Create a second connection
-  CreateConnection();
-
-  stream()->CryptoConnect();
-  auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            id_manager->max_outgoing_bidirectional_streams());
-  QuicConfig config;
-  config.SetMaxBidirectionalStreamsToSend(
-      config.GetMaxBidirectionalStreamsToSend() - 1);
-
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED, _, _))
-      .WillOnce(testing::Invoke(connection_,
-                                &MockQuicConnection::ReallyCloseConnection));
-  // Close connection will be called again in the handshaker, but this will be
-  // no-op as the connection is already closed.
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
-  crypto_test_utils::HandshakeWithFakeServer(
-      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
-      connection_, stream(), AlpnForVersion(connection_->version()));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc
deleted file mode 100644
index 2eee1cc..0000000
--- a/quic/core/tls_handshaker.cc
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_handshaker.h"
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/crypto.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_stack_trace.h"
-
-namespace quic {
-
-#define ENDPOINT (SSL_is_server(ssl()) ? "TlsServer: " : "TlsClient: ")
-
-TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
-    TlsHandshaker* parent)
-    : parent_(parent) {}
-
-TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
-
-void TlsHandshaker::ProofVerifierCallbackImpl::Run(
-    bool ok, const std::string& /*error_details*/,
-    std::unique_ptr<ProofVerifyDetails>* details) {
-  if (parent_ == nullptr) {
-    return;
-  }
-
-  parent_->verify_details_ = std::move(*details);
-  parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
-  parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ);
-  parent_->proof_verify_callback_ = nullptr;
-  if (parent_->verify_details_) {
-    parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_);
-  }
-  parent_->AdvanceHandshake();
-}
-
-void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
-
-TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
-    : stream_(stream), handshaker_delegate_(session) {}
-
-TlsHandshaker::~TlsHandshaker() {
-  if (proof_verify_callback_) {
-    proof_verify_callback_->Cancel();
-  }
-}
-
-bool TlsHandshaker::ProcessInput(absl::string_view input,
-                                 EncryptionLevel level) {
-  if (parser_error_ != QUIC_NO_ERROR) {
-    return false;
-  }
-  // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
-  // encryption level BoringSSL expects matches the encryption level that we
-  // just received input at. If they mismatch, should ProcessInput return true
-  // or false? If data is for a future encryption level, it should be queued for
-  // later?
-  if (SSL_provide_quic_data(ssl(), TlsConnection::BoringEncryptionLevel(level),
-                            reinterpret_cast<const uint8_t*>(input.data()),
-                            input.size()) != 1) {
-    // SSL_provide_quic_data can fail for 3 reasons:
-    // - API misuse (calling it before SSL_set_custom_quic_method, which we
-    //   call in the TlsHandshaker c'tor)
-    // - Memory exhaustion when appending data to its buffer
-    // - Data provided at the wrong encryption level
-    //
-    // Of these, the only sensible error to handle is data provided at the wrong
-    // encryption level.
-    //
-    // Note: the error provided below has a good-sounding enum value, although
-    // it doesn't match the description as it's a QUIC Crypto specific error.
-    parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
-    parser_error_detail_ = "TLS stack failed to receive data";
-    return false;
-  }
-  AdvanceHandshake();
-  return true;
-}
-
-void TlsHandshaker::AdvanceHandshake() {
-  if (is_connection_closed_) {
-    return;
-  }
-  if (GetHandshakeState() >= HANDSHAKE_COMPLETE) {
-    ProcessPostHandshakeMessage();
-    return;
-  }
-
-  QUICHE_BUG_IF(
-      quic_tls_server_async_done_no_flusher,
-      SSL_is_server(ssl()) && !handshaker_delegate_->PacketFlusherAttached())
-      << "is_server:" << SSL_is_server(ssl());
-
-  QUIC_VLOG(1) << ENDPOINT << "Continuing handshake";
-  int rv = SSL_do_handshake(ssl());
-
-  // If SSL_do_handshake return success(1) and we are in early data, it is
-  // possible that we have provided ServerHello to BoringSSL but it hasn't been
-  // processed. Retry SSL_do_handshake once will advance the handshake more in
-  // that case. If there are no unprocessed ServerHello, the retry will return a
-  // non-positive number.
-  if (rv == 1 && SSL_in_early_data(ssl())) {
-    OnEnterEarlyData();
-    rv = SSL_do_handshake(ssl());
-    QUIC_VLOG(1) << ENDPOINT
-                 << "SSL_do_handshake returned when entering early data. After "
-                 << "retry, rv=" << rv
-                 << ", SSL_in_early_data=" << SSL_in_early_data(ssl());
-    // The retry should either
-    // - Return <= 0 if the handshake is still pending, likely still in early
-    //   data.
-    // - Return 1 if the handshake has _actually_ finished. i.e.
-    //   SSL_in_early_data should be false.
-    //
-    // In either case, it should not both return 1 and stay in early data.
-    if (rv == 1 && SSL_in_early_data(ssl()) && !is_connection_closed_) {
-      QUIC_BUG(quic_handshaker_stay_in_early_data)
-          << "The original and the retry of SSL_do_handshake both returned "
-             "success and in early data";
-      CloseConnection(QUIC_HANDSHAKE_FAILED,
-                      "TLS handshake failed: Still in early data after retry");
-      return;
-    }
-  }
-
-  if (rv == 1) {
-    FinishHandshake();
-    return;
-  }
-  int ssl_error = SSL_get_error(ssl(), rv);
-  if (ssl_error == expected_ssl_error_) {
-    return;
-  }
-  if (ShouldCloseConnectionOnUnexpectedError(ssl_error) &&
-      !is_connection_closed_) {
-    QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
-                 << ssl_error;
-    ERR_print_errors_fp(stderr);
-    CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed");
-  }
-}
-
-void TlsHandshaker::CloseConnection(QuicErrorCode error,
-                                    const std::string& reason_phrase) {
-  QUICHE_DCHECK(!reason_phrase.empty());
-  stream()->OnUnrecoverableError(error, reason_phrase);
-  is_connection_closed_ = true;
-}
-
-void TlsHandshaker::CloseConnection(QuicErrorCode error,
-                                    QuicIetfTransportErrorCodes ietf_error,
-                                    const std::string& reason_phrase) {
-  QUICHE_DCHECK(!reason_phrase.empty());
-  stream()->OnUnrecoverableError(error, ietf_error, reason_phrase);
-  is_connection_closed_ = true;
-}
-
-void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
-                                       ConnectionCloseSource /*source*/) {
-  is_connection_closed_ = true;
-}
-
-bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) {
-  return true;
-}
-
-size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
-  return SSL_quic_max_handshake_flight_len(
-      ssl(), TlsConnection::BoringEncryptionLevel(level));
-}
-
-ssl_early_data_reason_t TlsHandshaker::EarlyDataReason() const {
-  return SSL_get_early_data_reason(ssl());
-}
-
-const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
-  return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
-}
-
-enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
-  if (verify_result_ != ssl_verify_retry ||
-      expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
-    enum ssl_verify_result_t result = verify_result_;
-    verify_result_ = ssl_verify_retry;
-    *out_alert = cert_verify_tls_alert_;
-    return result;
-  }
-  const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
-  if (cert_chain == nullptr) {
-    *out_alert = SSL_AD_INTERNAL_ERROR;
-    return ssl_verify_invalid;
-  }
-  // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
-  std::vector<std::string> certs;
-  for (CRYPTO_BUFFER* cert : cert_chain) {
-    certs.push_back(
-        std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
-                    CRYPTO_BUFFER_len(cert)));
-  }
-  QUIC_DVLOG(1) << "VerifyCert: peer cert_chain length: " << certs.size();
-
-  ProofVerifierCallbackImpl* proof_verify_callback =
-      new ProofVerifierCallbackImpl(this);
-
-  cert_verify_tls_alert_ = *out_alert;
-  QuicAsyncStatus verify_result = VerifyCertChain(
-      certs, &cert_verify_error_details_, &verify_details_,
-      &cert_verify_tls_alert_,
-      std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
-  switch (verify_result) {
-    case QUIC_SUCCESS:
-      if (verify_details_) {
-        OnProofVerifyDetailsAvailable(*verify_details_);
-      }
-      return ssl_verify_ok;
-    case QUIC_PENDING:
-      proof_verify_callback_ = proof_verify_callback;
-      set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY);
-      return ssl_verify_retry;
-    case QUIC_FAILURE:
-    default:
-      *out_alert = cert_verify_tls_alert_;
-      QUIC_LOG(INFO) << "Cert chain verification failed: "
-                     << cert_verify_error_details_;
-      return ssl_verify_invalid;
-  }
-}
-
-void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
-                                   const SSL_CIPHER* cipher,
-                                   const std::vector<uint8_t>& write_secret) {
-  QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
-  std::unique_ptr<QuicEncrypter> encrypter =
-      QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
-  const EVP_MD* prf = Prf(cipher);
-  CryptoUtils::SetKeyAndIV(prf, write_secret,
-                           handshaker_delegate_->parsed_version(),
-                           encrypter.get());
-  std::vector<uint8_t> header_protection_key =
-      CryptoUtils::GenerateHeaderProtectionKey(
-          prf, write_secret, handshaker_delegate_->parsed_version(),
-          encrypter->GetKeySize());
-  encrypter->SetHeaderProtectionKey(
-      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
-                        header_protection_key.size()));
-  if (level == ENCRYPTION_FORWARD_SECURE) {
-    QUICHE_DCHECK(latest_write_secret_.empty());
-    latest_write_secret_ = write_secret;
-    one_rtt_write_header_protection_key_ = header_protection_key;
-  }
-  handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
-                                                    std::move(encrypter));
-}
-
-bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
-                                  const SSL_CIPHER* cipher,
-                                  const std::vector<uint8_t>& read_secret) {
-  QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level;
-  std::unique_ptr<QuicDecrypter> decrypter =
-      QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
-  const EVP_MD* prf = Prf(cipher);
-  CryptoUtils::SetKeyAndIV(prf, read_secret,
-                           handshaker_delegate_->parsed_version(),
-                           decrypter.get());
-  std::vector<uint8_t> header_protection_key =
-      CryptoUtils::GenerateHeaderProtectionKey(
-          prf, read_secret, handshaker_delegate_->parsed_version(),
-          decrypter->GetKeySize());
-  decrypter->SetHeaderProtectionKey(
-      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
-                        header_protection_key.size()));
-  if (level == ENCRYPTION_FORWARD_SECURE) {
-    QUICHE_DCHECK(latest_read_secret_.empty());
-    latest_read_secret_ = read_secret;
-    one_rtt_read_header_protection_key_ = header_protection_key;
-  }
-  return handshaker_delegate_->OnNewDecryptionKeyAvailable(
-      level, std::move(decrypter),
-      /*set_alternative_decrypter=*/false,
-      /*latch_once_used=*/false);
-}
-
-std::unique_ptr<QuicDecrypter>
-TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  if (latest_read_secret_.empty() || latest_write_secret_.empty() ||
-      one_rtt_read_header_protection_key_.empty() ||
-      one_rtt_write_header_protection_key_.empty()) {
-    std::string error_details = "1-RTT secret(s) not set yet.";
-    QUIC_BUG(quic_bug_10312_1) << error_details;
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details);
-    return nullptr;
-  }
-  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
-  const EVP_MD* prf = Prf(cipher);
-  latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
-      prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
-  latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
-      prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
-
-  std::unique_ptr<QuicDecrypter> decrypter =
-      QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
-  CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
-                           handshaker_delegate_->parsed_version(),
-                           decrypter.get());
-  decrypter->SetHeaderProtectionKey(absl::string_view(
-      reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
-      one_rtt_read_header_protection_key_.size()));
-
-  return decrypter;
-}
-
-std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
-  if (latest_write_secret_.empty() ||
-      one_rtt_write_header_protection_key_.empty()) {
-    std::string error_details = "1-RTT write secret not set yet.";
-    QUIC_BUG(quic_bug_10312_2) << error_details;
-    CloseConnection(QUIC_INTERNAL_ERROR, error_details);
-    return nullptr;
-  }
-  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
-  std::unique_ptr<QuicEncrypter> encrypter =
-      QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
-  CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
-                           handshaker_delegate_->parsed_version(),
-                           encrypter.get());
-  encrypter->SetHeaderProtectionKey(absl::string_view(
-      reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
-      one_rtt_write_header_protection_key_.size()));
-  return encrypter;
-}
-
-bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
-                                                 absl::string_view context,
-                                                 size_t result_len,
-                                                 std::string* result) {
-  if (result == nullptr) {
-    return false;
-  }
-  result->resize(result_len);
-  return SSL_export_keying_material(
-             ssl(), reinterpret_cast<uint8_t*>(&*result->begin()), result_len,
-             label.data(), label.size(),
-             reinterpret_cast<const uint8_t*>(context.data()), context.size(),
-             !context.empty()) == 1;
-}
-
-void TlsHandshaker::WriteMessage(EncryptionLevel level,
-                                 absl::string_view data) {
-  stream_->WriteCryptoData(level, data);
-}
-
-void TlsHandshaker::FlushFlight() {}
-
-void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
-  std::string error_details = absl::StrCat(
-      "TLS handshake failure (", EncryptionLevelToString(level), ") ",
-      static_cast<int>(desc), ": ", SSL_alert_desc_string_long(desc));
-  QUIC_DLOG(ERROR) << error_details;
-  CloseConnection(
-      TlsAlertToQuicErrorCode(desc),
-      static_cast<QuicIetfTransportErrorCodes>(CRYPTO_ERROR_FIRST + desc),
-      error_details);
-}
-
-}  // namespace quic
diff --git a/quic/core/tls_handshaker.h b/quic/core/tls_handshaker.h
deleted file mode 100644
index 9509e81..0000000
--- a/quic/core/tls_handshaker.h
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/base.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_message_parser.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/tls_connection.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-class QuicCryptoStream;
-
-// Base class for TlsClientHandshaker and TlsServerHandshaker. TlsHandshaker
-// provides functionality common to both the client and server, such as moving
-// messages between the TLS stack and the QUIC crypto stream, and handling
-// derivation of secrets.
-class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate,
-                                          public CryptoMessageParser {
- public:
-  // TlsHandshaker does not take ownership of any of its arguments; they must
-  // outlive the TlsHandshaker.
-  TlsHandshaker(QuicCryptoStream* stream, QuicSession* session);
-  TlsHandshaker(const TlsHandshaker&) = delete;
-  TlsHandshaker& operator=(const TlsHandshaker&) = delete;
-
-  ~TlsHandshaker() override;
-
-  // From CryptoMessageParser
-  bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
-  size_t InputBytesRemaining() const override { return 0; }
-  QuicErrorCode error() const override { return parser_error_; }
-  const std::string& error_detail() const override {
-    return parser_error_detail_;
-  }
-
-  // The following methods provide implementations to subclasses of
-  // TlsHandshaker which use them to implement methods of QuicCryptoStream.
-  CryptoMessageParser* crypto_message_parser() { return this; }
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
-  ssl_early_data_reason_t EarlyDataReason() const;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter();
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter();
-  virtual HandshakeState GetHandshakeState() const = 0;
-  bool ExportKeyingMaterialForLabel(absl::string_view label,
-                                    absl::string_view context,
-                                    size_t result_len, std::string* result);
-
- protected:
-  // Called when a new message is received on the crypto stream and is available
-  // for the TLS stack to read.
-  virtual void AdvanceHandshake();
-
-  void CloseConnection(QuicErrorCode error, const std::string& reason_phrase);
-  // Closes the connection, specifying the wire error code |ietf_error|
-  // explicitly.
-  void CloseConnection(QuicErrorCode error,
-                       QuicIetfTransportErrorCodes ietf_error,
-                       const std::string& reason_phrase);
-
-  void OnConnectionClosed(QuicErrorCode error, ConnectionCloseSource source);
-
-  bool is_connection_closed() const { return is_connection_closed_; }
-
-  // Called when |SSL_do_handshake| returns 1, indicating that the handshake has
-  // finished. Note that a handshake only finishes once, entering early data
-  // does not count.
-  virtual void FinishHandshake() = 0;
-
-  // Called when |SSL_do_handshake| returns 1 and the connection is in early
-  // data. In that case, |AdvanceHandshake| will call |OnEnterEarlyData| and
-  // retry |SSL_do_handshake| once.
-  virtual void OnEnterEarlyData() {
-    // By default, do nothing but check the preconditions.
-    QUICHE_DCHECK(SSL_in_early_data(ssl()));
-  }
-
-  // Called when a handshake message is received after the handshake is
-  // complete.
-  virtual void ProcessPostHandshakeMessage() = 0;
-
-  // Called when an unexpected error code is received from |SSL_get_error|. If a
-  // subclass can expect more than just a single error (as provided by
-  // |set_expected_ssl_error|), it can override this method to handle that case.
-  virtual bool ShouldCloseConnectionOnUnexpectedError(int ssl_error);
-
-  void set_expected_ssl_error(int ssl_error) {
-    expected_ssl_error_ = ssl_error;
-  }
-  int expected_ssl_error() const { return expected_ssl_error_; }
-
-  // Called to verify a cert chain. This can be implemented as a simple wrapper
-  // around ProofVerifier, which optionally gathers additional arguments to pass
-  // into their VerifyCertChain method. This class retains a non-owning pointer
-  // to |callback|; the callback must live until this function returns
-  // QUIC_SUCCESS or QUIC_FAILURE, or until the callback is run.
-  //
-  // If certificate verification fails, |*out_alert| may be set to a TLS alert
-  // that will be sent when closing the connection; it defaults to
-  // certificate_unknown. Implementations of VerifyCertChain may retain the
-  // |out_alert| pointer while performing an async operation.
-  virtual QuicAsyncStatus VerifyCertChain(
-      const std::vector<std::string>& certs,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) = 0;
-  // Called when certificate verification is completed.
-  virtual void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& verify_details) = 0;
-
-  // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
-  const EVP_MD* Prf(const SSL_CIPHER* cipher);
-
-  virtual const TlsConnection* tls_connection() const = 0;
-
-  SSL* ssl() const { return tls_connection()->ssl(); }
-
-  QuicCryptoStream* stream() { return stream_; }
-  HandshakerDelegateInterface* handshaker_delegate() {
-    return handshaker_delegate_;
-  }
-
-  enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override;
-
-  // SetWriteSecret provides the encryption secret used to encrypt messages at
-  // encryption level |level|. The secret provided here is the one from the TLS
-  // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
-  // traffic secrets and application traffic secrets. The provided write secret
-  // must be used with the provided cipher suite |cipher|.
-  void SetWriteSecret(EncryptionLevel level,
-                      const SSL_CIPHER* cipher,
-                      const std::vector<uint8_t>& write_secret) override;
-
-  // SetReadSecret is similar to SetWriteSecret, except that it is used for
-  // decrypting messages. SetReadSecret at a particular level is always called
-  // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT, where
-  // the EncryptionLevel for SetWriteSecret is ENCRYPTION_FORWARD_SECURE.
-  bool SetReadSecret(EncryptionLevel level,
-                     const SSL_CIPHER* cipher,
-                     const std::vector<uint8_t>& read_secret) override;
-
-  // WriteMessage is called when there is |data| from the TLS stack ready for
-  // the QUIC stack to write in a crypto frame. The data must be transmitted at
-  // encryption level |level|.
-  void WriteMessage(EncryptionLevel level, absl::string_view data) override;
-
-  // FlushFlight is called to signal that the current flight of
-  // messages have all been written (via calls to WriteMessage) and can be
-  // flushed to the underlying transport.
-  void FlushFlight() override;
-
-  // SendAlert causes this TlsHandshaker to close the QUIC connection with an
-  // error code corresponding to the TLS alert description |desc|.
-  void SendAlert(EncryptionLevel level, uint8_t desc) override;
-
-  // Informational callback from BoringSSL. Subclasses can override it to do
-  // logging, tracing, etc.
-  // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
-  void InfoCallback(int /*type*/, int /*value*/) override {}
-
- private:
-  // ProofVerifierCallbackImpl handles the result of an asynchronous certificate
-  // verification operation.
-  class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
-      : public ProofVerifierCallback {
-   public:
-    explicit ProofVerifierCallbackImpl(TlsHandshaker* parent);
-    ~ProofVerifierCallbackImpl() override;
-
-    // ProofVerifierCallback interface.
-    void Run(bool ok,
-             const std::string& error_details,
-             std::unique_ptr<ProofVerifyDetails>* details) override;
-
-    // If called, Cancel causes the pending callback to be a no-op.
-    void Cancel();
-
-   private:
-    // Non-owning pointer to the TlsHandshaker responsible for this callback.
-    // |parent_| must be valid for the life of this callback or until |Cancel|
-    // is called.
-    TlsHandshaker* parent_;
-  };
-
-  // ProofVerifierCallback used for async certificate verification. Ownership of
-  // this object is transferred to |VerifyCertChain|;
-  ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr;
-  std::unique_ptr<ProofVerifyDetails> verify_details_;
-  enum ssl_verify_result_t verify_result_ = ssl_verify_retry;
-  uint8_t cert_verify_tls_alert_ = SSL_AD_CERTIFICATE_UNKNOWN;
-  std::string cert_verify_error_details_;
-
-  int expected_ssl_error_ = SSL_ERROR_WANT_READ;
-  bool is_connection_closed_ = false;
-
-  QuicCryptoStream* stream_;
-  HandshakerDelegateInterface* handshaker_delegate_;
-
-  QuicErrorCode parser_error_ = QUIC_NO_ERROR;
-  std::string parser_error_detail_;
-
-  // The most recently derived 1-RTT read and write secrets, which are updated
-  // on each key update.
-  std::vector<uint8_t> latest_read_secret_;
-  std::vector<uint8_t> latest_write_secret_;
-  // 1-RTT header protection keys, which are not changed during key update.
-  std::vector<uint8_t> one_rtt_read_header_protection_key_;
-  std::vector<uint8_t> one_rtt_write_header_protection_key_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
deleted file mode 100644
index f959a76..0000000
--- a/quic/core/tls_server_handshaker.cc
+++ /dev/null
@@ -1,1173 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_server_handshaker.h"
-
-#include <memory>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/http_frames.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_hostname_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-#define RECORD_LATENCY_IN_US(stat_name, latency, comment)                   \
-  do {                                                                      \
-    const int64_t latency_in_us = (latency).ToMicroseconds();               \
-    QUIC_DVLOG(1) << "Recording " stat_name ": " << latency_in_us;          \
-    QUIC_SERVER_HISTOGRAM_COUNTS(stat_name, latency_in_us, 1, 10000000, 50, \
-                                 comment);                                  \
-  } while (0)
-
-namespace quic {
-
-namespace {
-
-// Default port for HTTP/3.
-uint16_t kDefaultPort = 443;
-
-}  // namespace
-
-TlsServerHandshaker::DefaultProofSourceHandle::DefaultProofSourceHandle(
-    TlsServerHandshaker* handshaker,
-    ProofSource* proof_source)
-    : handshaker_(handshaker), proof_source_(proof_source) {}
-
-TlsServerHandshaker::DefaultProofSourceHandle::~DefaultProofSourceHandle() {
-  CloseHandle();
-}
-
-void TlsServerHandshaker::DefaultProofSourceHandle::CloseHandle() {
-  QUIC_DVLOG(1) << "CloseHandle. is_signature_pending="
-                << (signature_callback_ != nullptr);
-  if (signature_callback_) {
-    signature_callback_->Cancel();
-    signature_callback_ = nullptr;
-  }
-}
-
-QuicAsyncStatus
-TlsServerHandshaker::DefaultProofSourceHandle::SelectCertificate(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    absl::string_view /*ssl_capabilities*/,
-    const std::string& hostname,
-    absl::string_view /*client_hello*/,
-    const std::string& /*alpn*/,
-    absl::optional<std::string> /*alps*/,
-    const std::vector<uint8_t>& /*quic_transport_params*/,
-    const absl::optional<std::vector<uint8_t>>& /*early_data_context*/,
-    const QuicSSLConfig& /*ssl_config*/) {
-  if (!handshaker_ || !proof_source_) {
-    QUIC_BUG(quic_bug_10341_1)
-        << "SelectCertificate called on a detached handle";
-    return QUIC_FAILURE;
-  }
-
-  bool cert_matched_sni;
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
-      proof_source_->GetCertChain(server_address, client_address, hostname,
-                                  &cert_matched_sni);
-
-  handshaker_->OnSelectCertificateDone(
-      /*ok=*/true, /*is_sync=*/true, chain.get(),
-      /*handshake_hints=*/absl::string_view(),
-      /*ticket_encryption_key=*/absl::string_view(), cert_matched_sni,
-      QuicDelayedSSLConfig());
-  if (!handshaker_->select_cert_status().has_value()) {
-    QUIC_BUG(quic_bug_12423_1)
-        << "select_cert_status() has no value after a synchronous select cert";
-    // Return success to continue the handshake.
-    return QUIC_SUCCESS;
-  }
-  return handshaker_->select_cert_status().value();
-}
-
-QuicAsyncStatus TlsServerHandshaker::DefaultProofSourceHandle::ComputeSignature(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    const std::string& hostname,
-    uint16_t signature_algorithm,
-    absl::string_view in,
-    size_t max_signature_size) {
-  if (!handshaker_ || !proof_source_) {
-    QUIC_BUG(quic_bug_10341_2)
-        << "ComputeSignature called on a detached handle";
-    return QUIC_FAILURE;
-  }
-
-  if (signature_callback_) {
-    QUIC_BUG(quic_bug_10341_3) << "ComputeSignature called while pending";
-    return QUIC_FAILURE;
-  }
-
-  signature_callback_ = new DefaultSignatureCallback(this);
-  proof_source_->ComputeTlsSignature(
-      server_address, client_address, hostname, signature_algorithm, in,
-      std::unique_ptr<DefaultSignatureCallback>(signature_callback_));
-
-  if (signature_callback_) {
-    QUIC_DVLOG(1) << "ComputeTlsSignature is pending";
-    signature_callback_->set_is_sync(false);
-    return QUIC_PENDING;
-  }
-
-  bool success = handshaker_->HasValidSignature(max_signature_size);
-  QUIC_DVLOG(1) << "ComputeTlsSignature completed synchronously. success:"
-                << success;
-  // OnComputeSignatureDone should have been called by signature_callback_->Run.
-  return success ? QUIC_SUCCESS : QUIC_FAILURE;
-}
-
-TlsServerHandshaker::DecryptCallback::DecryptCallback(
-    TlsServerHandshaker* handshaker)
-    : handshaker_(handshaker) {}
-
-void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) {
-  if (handshaker_ == nullptr) {
-    // The callback was cancelled before we could run.
-    return;
-  }
-
-  TlsServerHandshaker* handshaker = handshaker_;
-  handshaker_ = nullptr;
-
-  handshaker->decrypted_session_ticket_ = std::move(plaintext);
-  const bool is_async =
-      (handshaker->expected_ssl_error() == SSL_ERROR_PENDING_TICKET);
-
-  absl::optional<QuicConnectionContextSwitcher> context_switcher;
-
-  if (is_async) {
-    context_switcher.emplace(handshaker->connection_context());
-  }
-  QUIC_TRACESTRING(
-      absl::StrCat("TLS ticket decryption done. len(decrypted_ticket):",
-                   handshaker->decrypted_session_ticket_.size()));
-
-  // DecryptCallback::Run could be called synchronously. When that happens, we
-  // are currently in the middle of a call to AdvanceHandshake.
-  // (AdvanceHandshake called SSL_do_handshake, which through some layers
-  // called SessionTicketOpen, which called TicketCrypter::Decrypt, which
-  // synchronously called this function.) In that case, the handshake will
-  // continue to be processed when this function returns.
-  //
-  // When this callback is called asynchronously (i.e. the ticket decryption
-  // is pending), TlsServerHandshaker is not actively processing handshake
-  // messages. We need to have it resume processing handshake messages by
-  // calling AdvanceHandshake.
-  if (is_async) {
-    handshaker->AdvanceHandshakeFromCallback();
-  }
-
-  handshaker->ticket_decryption_callback_ = nullptr;
-}
-
-void TlsServerHandshaker::DecryptCallback::Cancel() {
-  QUICHE_DCHECK(handshaker_);
-  handshaker_ = nullptr;
-}
-
-TlsServerHandshaker::TlsServerHandshaker(
-    QuicSession* session, const QuicCryptoServerConfig* crypto_config)
-    : TlsHandshaker(this, session),
-      QuicCryptoServerStreamBase(session),
-      proof_source_(crypto_config->proof_source()),
-      pre_shared_key_(crypto_config->pre_shared_key()),
-      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
-      tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()),
-      crypto_config_(crypto_config) {
-  QUIC_DVLOG(1) << "TlsServerHandshaker: support_client_cert:"
-                << session->support_client_cert()
-                << ", client_cert_mode initial value: " << client_cert_mode();
-
-  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3,
-                   session->connection()->version().handshake_protocol);
-
-  // Configure the SSL to be a server.
-  SSL_set_accept_state(ssl());
-
-  // Make sure we use the right TLS extension codepoint.
-  int use_legacy_extension = 0;
-  if (session->version().UsesLegacyTlsExtension()) {
-    use_legacy_extension = 1;
-  }
-  SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
-
-  if (session->connection()->context()->tracer) {
-    tls_connection_.EnableInfoCallback();
-  }
-
-  if (no_select_cert_if_disconnected_) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 1, 2);
-  }
-}
-
-TlsServerHandshaker::~TlsServerHandshaker() { CancelOutstandingCallbacks(); }
-
-void TlsServerHandshaker::CancelOutstandingCallbacks() {
-  if (proof_source_handle_) {
-    proof_source_handle_->CloseHandle();
-  }
-  if (ticket_decryption_callback_) {
-    ticket_decryption_callback_->Cancel();
-    ticket_decryption_callback_ = nullptr;
-  }
-}
-
-void TlsServerHandshaker::InfoCallback(int type, int value) {
-  QuicConnectionTracer* tracer =
-      session()->connection()->context()->tracer.get();
-
-  if (tracer == nullptr) {
-    return;
-  }
-
-  if (type & SSL_CB_LOOP) {
-    tracer->PrintString(
-        absl::StrCat("SSL:ACCEPT_LOOP:", SSL_state_string_long(ssl())));
-  } else if (type & SSL_CB_ALERT) {
-    const char* prefix =
-        (type & SSL_CB_READ) ? "SSL:READ_ALERT:" : "SSL:WRITE_ALERT:";
-    tracer->PrintString(absl::StrCat(prefix, SSL_alert_type_string_long(value),
-                                     ":", SSL_alert_desc_string_long(value)));
-  } else if (type & SSL_CB_EXIT) {
-    const char* prefix =
-        (value == 1) ? "SSL:ACCEPT_EXIT_OK:" : "SSL:ACCEPT_EXIT_FAIL:";
-    tracer->PrintString(absl::StrCat(prefix, SSL_state_string_long(ssl())));
-  } else if (type & SSL_CB_HANDSHAKE_START) {
-    tracer->PrintString(
-        absl::StrCat("SSL:HANDSHAKE_START:", SSL_state_string_long(ssl())));
-  } else if (type & SSL_CB_HANDSHAKE_DONE) {
-    tracer->PrintString(
-        absl::StrCat("SSL:HANDSHAKE_DONE:", SSL_state_string_long(ssl())));
-  } else {
-    QUIC_DLOG(INFO) << "Unknown event type " << type << ": "
-                    << SSL_state_string_long(ssl());
-    tracer->PrintString(
-        absl::StrCat("SSL:unknown:", value, ":", SSL_state_string_long(ssl())));
-  }
-}
-
-std::unique_ptr<ProofSourceHandle>
-TlsServerHandshaker::MaybeCreateProofSourceHandle() {
-  return std::make_unique<DefaultProofSourceHandle>(this, proof_source_);
-}
-
-bool TlsServerHandshaker::GetBase64SHA256ClientChannelID(
-    std::string* /*output*/) const {
-  // Channel ID is not supported when TLS is used in QUIC.
-  return false;
-}
-
-void TlsServerHandshaker::SendServerConfigUpdate(
-    const CachedNetworkParameters* /*cached_network_params*/) {
-  // SCUP messages aren't supported when using the TLS handshake.
-}
-
-bool TlsServerHandshaker::DisableResumption() {
-  if (!can_disable_resumption_ || !session()->connection()->connected()) {
-    return false;
-  }
-  tls_connection_.DisableTicketSupport();
-  return true;
-}
-
-bool TlsServerHandshaker::IsZeroRtt() const {
-  return SSL_early_data_accepted(ssl());
-}
-
-bool TlsServerHandshaker::IsResumption() const {
-  return SSL_session_reused(ssl());
-}
-
-bool TlsServerHandshaker::ResumptionAttempted() const {
-  return ticket_received_;
-}
-
-bool TlsServerHandshaker::EarlyDataAttempted() const {
-  QUIC_BUG_IF(quic_tls_early_data_attempted_too_early,
-              !select_cert_status_.has_value())
-      << "EarlyDataAttempted must be called after EarlySelectCertCallback is "
-         "started";
-  return early_data_attempted_;
-}
-
-int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
-  // SCUP messages aren't supported when using the TLS handshake.
-  return 0;
-}
-
-const CachedNetworkParameters*
-TlsServerHandshaker::PreviousCachedNetworkParams() const {
-  return last_received_cached_network_params_.get();
-}
-
-void TlsServerHandshaker::SetPreviousCachedNetworkParams(
-    CachedNetworkParameters cached_network_params) {
-  last_received_cached_network_params_ =
-      std::make_unique<CachedNetworkParameters>(cached_network_params);
-}
-
-void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) {
-  if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
-    state_ = HANDSHAKE_PROCESSED;
-    handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
-    handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
-  }
-}
-
-void TlsServerHandshaker::OnHandshakeDoneReceived() {
-  QUICHE_DCHECK(false);
-}
-
-void TlsServerHandshaker::OnNewTokenReceived(absl::string_view /*token*/) {
-  QUICHE_DCHECK(false);
-}
-
-std::string TlsServerHandshaker::GetAddressToken(
-    const CachedNetworkParameters* cached_network_params) const {
-  SourceAddressTokens empty_previous_tokens;
-  const QuicConnection* connection = session()->connection();
-  return crypto_config_->NewSourceAddressToken(
-      crypto_config_->source_address_token_boxer(), empty_previous_tokens,
-      connection->effective_peer_address().host(),
-      connection->random_generator(), connection->clock()->WallNow(),
-      cached_network_params);
-}
-
-bool TlsServerHandshaker::ValidateAddressToken(absl::string_view token) const {
-  SourceAddressTokens tokens;
-  HandshakeFailureReason reason = crypto_config_->ParseSourceAddressToken(
-      crypto_config_->source_address_token_boxer(), token, tokens);
-  if (reason != HANDSHAKE_OK) {
-    QUIC_DLOG(WARNING) << "Failed to parse source address token: "
-                       << CryptoUtils::HandshakeFailureReasonToString(reason);
-    return false;
-  }
-  auto cached_network_params = std::make_unique<CachedNetworkParameters>();
-  reason = crypto_config_->ValidateSourceAddressTokens(
-      tokens, session()->connection()->effective_peer_address().host(),
-      session()->connection()->clock()->WallNow(), cached_network_params.get());
-  if (reason != HANDSHAKE_OK) {
-    QUIC_DLOG(WARNING) << "Failed to validate source address token: "
-                       << CryptoUtils::HandshakeFailureReasonToString(reason);
-    return false;
-  }
-
-  last_received_cached_network_params_ = std::move(cached_network_params);
-  return true;
-}
-
-bool TlsServerHandshaker::ShouldSendExpectCTHeader() const {
-  return false;
-}
-
-bool TlsServerHandshaker::DidCertMatchSni() const { return cert_matched_sni_; }
-
-const ProofSource::Details* TlsServerHandshaker::ProofSourceDetails() const {
-  return proof_source_details_.get();
-}
-
-bool TlsServerHandshaker::ExportKeyingMaterial(absl::string_view label,
-                                               absl::string_view context,
-                                               size_t result_len,
-                                               std::string* result) {
-  return ExportKeyingMaterialForLabel(label, context, result_len, result);
-}
-
-void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode error,
-                                             ConnectionCloseSource source) {
-  TlsHandshaker::OnConnectionClosed(error, source);
-}
-
-ssl_early_data_reason_t TlsServerHandshaker::EarlyDataReason() const {
-  return TlsHandshaker::EarlyDataReason();
-}
-
-bool TlsServerHandshaker::encryption_established() const {
-  return encryption_established_;
-}
-
-bool TlsServerHandshaker::one_rtt_keys_available() const {
-  return state_ == HANDSHAKE_CONFIRMED;
-}
-
-const QuicCryptoNegotiatedParameters&
-TlsServerHandshaker::crypto_negotiated_params() const {
-  return *crypto_negotiated_params_;
-}
-
-CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
-  return TlsHandshaker::crypto_message_parser();
-}
-
-HandshakeState TlsServerHandshaker::GetHandshakeState() const {
-  return state_;
-}
-
-void TlsServerHandshaker::SetServerApplicationStateForResumption(
-    std::unique_ptr<ApplicationState> state) {
-  application_state_ = std::move(state);
-}
-
-size_t TlsServerHandshaker::BufferSizeLimitForLevel(
-    EncryptionLevel level) const {
-  return TlsHandshaker::BufferSizeLimitForLevel(level);
-}
-
-std::unique_ptr<QuicDecrypter>
-TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
-  return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
-}
-
-std::unique_ptr<QuicEncrypter>
-TlsServerHandshaker::CreateCurrentOneRttEncrypter() {
-  return TlsHandshaker::CreateCurrentOneRttEncrypter();
-}
-
-void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
-
-void TlsServerHandshaker::AdvanceHandshakeFromCallback() {
-  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
-
-  AdvanceHandshake();
-  if (!is_connection_closed()) {
-    handshaker_delegate()->OnHandshakeCallbackDone();
-  }
-}
-
-bool TlsServerHandshaker::ProcessTransportParameters(
-    const SSL_CLIENT_HELLO* client_hello,
-    std::string* error_details) {
-  TransportParameters client_params;
-  const uint8_t* client_params_bytes;
-  size_t params_bytes_len;
-
-  // Make sure we use the right TLS extension codepoint.
-  uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters_standard;
-  if (session()->version().UsesLegacyTlsExtension()) {
-    extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
-  }
-  // When using early select cert callback, SSL_get_peer_quic_transport_params
-  // can not be used to retrieve the client's transport parameters, but we can
-  // use SSL_early_callback_ctx_extension_get to do that.
-  if (!SSL_early_callback_ctx_extension_get(client_hello, extension_type,
-                                            &client_params_bytes,
-                                            &params_bytes_len)) {
-    params_bytes_len = 0;
-  }
-
-  if (params_bytes_len == 0) {
-    *error_details = "Client's transport parameters are missing";
-    return false;
-  }
-  std::string parse_error_details;
-  if (!ParseTransportParameters(session()->connection()->version(),
-                                Perspective::IS_CLIENT, client_params_bytes,
-                                params_bytes_len, &client_params,
-                                &parse_error_details)) {
-    QUICHE_DCHECK(!parse_error_details.empty());
-    *error_details =
-        "Unable to parse client's transport parameters: " + parse_error_details;
-    return false;
-  }
-
-  // Notify QuicConnectionDebugVisitor.
-  session()->connection()->OnTransportParametersReceived(client_params);
-
-  if (client_params.legacy_version_information.has_value() &&
-      CryptoUtils::ValidateClientHelloVersion(
-          client_params.legacy_version_information.value().version,
-          session()->connection()->version(), session()->supported_versions(),
-          error_details) != QUIC_NO_ERROR) {
-    return false;
-  }
-
-  if (client_params.version_information.has_value() &&
-      !CryptoUtils::ValidateChosenVersion(
-          client_params.version_information.value().chosen_version,
-          session()->version(), error_details)) {
-    QUICHE_DCHECK(!error_details->empty());
-    return false;
-  }
-
-  if (handshaker_delegate()->ProcessTransportParameters(
-          client_params, /* is_resumption = */ false, error_details) !=
-      QUIC_NO_ERROR) {
-    return false;
-  }
-
-  ProcessAdditionalTransportParameters(client_params);
-
-  return true;
-}
-
-TlsServerHandshaker::SetTransportParametersResult
-TlsServerHandshaker::SetTransportParameters() {
-  SetTransportParametersResult result;
-  QUICHE_DCHECK(!result.success);
-
-  TransportParameters server_params;
-  server_params.perspective = Perspective::IS_SERVER;
-  server_params.legacy_version_information =
-      TransportParameters::LegacyVersionInformation();
-  server_params.legacy_version_information.value().supported_versions =
-      CreateQuicVersionLabelVector(session()->supported_versions());
-  server_params.legacy_version_information.value().version =
-      CreateQuicVersionLabel(session()->connection()->version());
-  server_params.version_information = TransportParameters::VersionInformation();
-  server_params.version_information.value().chosen_version =
-      CreateQuicVersionLabel(session()->version());
-  server_params.version_information.value().other_versions =
-      CreateQuicVersionLabelVector(session()->supported_versions());
-
-  if (!handshaker_delegate()->FillTransportParameters(&server_params)) {
-    return result;
-  }
-
-  // Notify QuicConnectionDebugVisitor.
-  session()->connection()->OnTransportParametersSent(server_params);
-
-  {  // Ensure |server_params_bytes| is not accessed out of the scope.
-    std::vector<uint8_t> server_params_bytes;
-    if (!SerializeTransportParameters(session()->connection()->version(),
-                                      server_params, &server_params_bytes) ||
-        SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
-                                      server_params_bytes.size()) != 1) {
-      return result;
-    }
-    result.quic_transport_params = std::move(server_params_bytes);
-  }
-
-  if (application_state_) {
-    std::vector<uint8_t> early_data_context;
-    if (!SerializeTransportParametersForTicket(
-            server_params, *application_state_, &early_data_context)) {
-      QUIC_BUG(quic_bug_10341_4)
-          << "Failed to serialize Transport Parameters for ticket.";
-      result.early_data_context = std::vector<uint8_t>();
-      return result;
-    }
-    SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
-                                    early_data_context.size());
-    result.early_data_context = std::move(early_data_context);
-    application_state_.reset(nullptr);
-  }
-  result.success = true;
-  return result;
-}
-
-void TlsServerHandshaker::SetWriteSecret(
-    EncryptionLevel level,
-    const SSL_CIPHER* cipher,
-    const std::vector<uint8_t>& write_secret) {
-  if (is_connection_closed()) {
-    return;
-  }
-  if (level == ENCRYPTION_FORWARD_SECURE) {
-    encryption_established_ = true;
-    // Fill crypto_negotiated_params_:
-    const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
-    if (cipher) {
-      crypto_negotiated_params_->cipher_suite =
-          SSL_CIPHER_get_protocol_id(cipher);
-    }
-    crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
-  }
-  TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
-}
-
-std::string TlsServerHandshaker::GetAcceptChValueForHostname(
-    const std::string& /*hostname*/) const {
-  return {};
-}
-
-void TlsServerHandshaker::FinishHandshake() {
-  QUICHE_DCHECK(!SSL_in_early_data(ssl()));
-
-  if (!valid_alpn_received_) {
-    QUIC_DLOG(ERROR)
-        << "Server: handshake finished without receiving a known ALPN";
-    // TODO(b/130164908) this should send no_application_protocol
-    // instead of QUIC_HANDSHAKE_FAILED.
-    CloseConnection(QUIC_HANDSHAKE_FAILED,
-                    "Server did not receive a known ALPN");
-    return;
-  }
-
-  ssl_early_data_reason_t reason_code = EarlyDataReason();
-  QUIC_DLOG(INFO) << "Server: handshake finished. Early data reason "
-                  << reason_code << " ("
-                  << CryptoUtils::EarlyDataReasonToString(reason_code) << ")";
-  state_ = HANDSHAKE_CONFIRMED;
-
-  handshaker_delegate()->OnTlsHandshakeComplete();
-  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
-  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
-  // ENCRYPTION_ZERO_RTT decryption key is not discarded here as "Servers MAY
-  // temporarily retain 0-RTT keys to allow decrypting reordered packets
-  // without requiring their contents to be retransmitted with 1-RTT keys."
-  // It is expected that QuicConnection will discard the key at an
-  // appropriate time.
-}
-
-QuicAsyncStatus TlsServerHandshaker::VerifyCertChain(
-    const std::vector<std::string>& /*certs*/,
-    std::string* /*error_details*/,
-    std::unique_ptr<ProofVerifyDetails>* /*details*/,
-    uint8_t* /*out_alert*/,
-    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
-  if (!session()->support_client_cert()) {
-    QUIC_BUG(quic_bug_10341_5)
-        << "Client certificates are not yet supported on the server";
-    return QUIC_FAILURE;
-  }
-
-  QUIC_RESTART_FLAG_COUNT_N(quic_tls_server_support_client_cert, 2, 2);
-  QUIC_DVLOG(1) << "VerifyCertChain returning success";
-
-  // No real verification here. A subclass can override this function to verify
-  // the client cert if needed.
-  return QUIC_SUCCESS;
-}
-
-void TlsServerHandshaker::OnProofVerifyDetailsAvailable(
-    const ProofVerifyDetails& /*verify_details*/) {}
-
-ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
-    uint8_t* out,
-    size_t* out_len,
-    size_t max_out,
-    uint16_t sig_alg,
-    absl::string_view in) {
-  QUICHE_DCHECK_EQ(expected_ssl_error(), SSL_ERROR_WANT_READ);
-
-  QuicAsyncStatus status = proof_source_handle_->ComputeSignature(
-      session()->connection()->self_address(),
-      session()->connection()->peer_address(), crypto_negotiated_params_->sni,
-      sig_alg, in, max_out);
-  if (status == QUIC_PENDING) {
-    set_expected_ssl_error(SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
-    if (async_op_timer_.has_value()) {
-      QUIC_CODE_COUNT(
-          quic_tls_server_computing_signature_while_another_op_pending);
-    }
-    async_op_timer_ = QuicTimeAccumulator();
-    async_op_timer_->Start(now());
-  }
-  return PrivateKeyComplete(out, out_len, max_out);
-}
-
-ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
-    uint8_t* out,
-    size_t* out_len,
-    size_t max_out) {
-  if (expected_ssl_error() == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
-    return ssl_private_key_retry;
-  }
-
-  const bool success = HasValidSignature(max_out);
-  QuicConnectionStats::TlsServerOperationStats compute_signature_stats;
-  compute_signature_stats.success = success;
-  if (async_op_timer_.has_value()) {
-    async_op_timer_->Stop(now());
-    compute_signature_stats.async_latency =
-        async_op_timer_->GetTotalElapsedTime();
-    async_op_timer_.reset();
-    RECORD_LATENCY_IN_US("tls_server_async_compute_signature_latency_us",
-                         compute_signature_stats.async_latency,
-                         "Async compute signature latency in microseconds");
-  }
-  connection_stats().tls_server_compute_signature_stats =
-      std::move(compute_signature_stats);
-
-  if (!success) {
-    return ssl_private_key_failure;
-  }
-  *out_len = cert_verify_sig_.size();
-  memcpy(out, cert_verify_sig_.data(), *out_len);
-  cert_verify_sig_.clear();
-  cert_verify_sig_.shrink_to_fit();
-  return ssl_private_key_success;
-}
-
-void TlsServerHandshaker::OnComputeSignatureDone(
-    bool ok,
-    bool is_sync,
-    std::string signature,
-    std::unique_ptr<ProofSource::Details> details) {
-  QUIC_DVLOG(1) << "OnComputeSignatureDone. ok:" << ok
-                << ", is_sync:" << is_sync
-                << ", len(signature):" << signature.size();
-  absl::optional<QuicConnectionContextSwitcher> context_switcher;
-
-  if (!is_sync) {
-    context_switcher.emplace(connection_context());
-  }
-
-  QUIC_TRACESTRING(absl::StrCat("TLS compute signature done. ok:", ok,
-                                ", len(signature):", signature.size()));
-
-  if (ok) {
-    cert_verify_sig_ = std::move(signature);
-    proof_source_details_ = std::move(details);
-  }
-  const int last_expected_ssl_error = expected_ssl_error();
-  set_expected_ssl_error(SSL_ERROR_WANT_READ);
-  if (!is_sync) {
-    QUICHE_DCHECK_EQ(last_expected_ssl_error,
-                     SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
-    AdvanceHandshakeFromCallback();
-  }
-}
-
-bool TlsServerHandshaker::HasValidSignature(size_t max_signature_size) const {
-  return !cert_verify_sig_.empty() &&
-         cert_verify_sig_.size() <= max_signature_size;
-}
-
-size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
-  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
-  return proof_source_->GetTicketCrypter()->MaxOverhead();
-}
-
-int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
-                                           size_t* out_len,
-                                           size_t max_out_len,
-                                           absl::string_view in) {
-  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
-  std::vector<uint8_t> ticket =
-      proof_source_->GetTicketCrypter()->Encrypt(in, ticket_encryption_key_);
-  if (max_out_len < ticket.size()) {
-    QUIC_BUG(quic_bug_12423_2)
-        << "TicketCrypter returned " << ticket.size()
-        << " bytes of ciphertext, which is larger than its max overhead of "
-        << max_out_len;
-    return 0;  // failure
-  }
-  *out_len = ticket.size();
-  memcpy(out, ticket.data(), ticket.size());
-  QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_sealed);
-  return 1;  // success
-}
-
-ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
-    uint8_t* out,
-    size_t* out_len,
-    size_t max_out_len,
-    absl::string_view in) {
-  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
-
-  if (ignore_ticket_open_) {
-    // SetIgnoreTicketOpen has been called. Typically this means the caller is
-    // using handshake hints and expect the hints to contain ticket decryption
-    // results.
-    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_1);
-    return ssl_ticket_aead_ignore_ticket;
-  }
-
-  if (!ticket_decryption_callback_) {
-    ticket_decryption_callback_ = new DecryptCallback(this);
-    proof_source_->GetTicketCrypter()->Decrypt(
-        in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
-
-    // Decrypt can run the callback synchronously. In that case, the callback
-    // will clear the ticket_decryption_callback_ pointer, and instead of
-    // returning ssl_ticket_aead_retry, we should continue processing to
-    // return the decrypted ticket.
-    //
-    // If the callback is not run synchronously, return ssl_ticket_aead_retry
-    // and when the callback is complete this function will be run again to
-    // return the result.
-    if (ticket_decryption_callback_) {
-      QUICHE_DCHECK(!ticket_decryption_callback_->IsDone());
-      set_expected_ssl_error(SSL_ERROR_PENDING_TICKET);
-      if (async_op_timer_.has_value()) {
-        QUIC_CODE_COUNT(
-            quic_tls_server_decrypting_ticket_while_another_op_pending);
-      }
-      async_op_timer_ = QuicTimeAccumulator();
-      async_op_timer_->Start(now());
-    }
-  }
-
-  // If the async ticket decryption is pending, either started by this
-  // SessionTicketOpen call or one that happened earlier, return
-  // ssl_ticket_aead_retry.
-  if (ticket_decryption_callback_ && !ticket_decryption_callback_->IsDone()) {
-    return ssl_ticket_aead_retry;
-  }
-
-  ssl_ticket_aead_result_t result =
-      FinalizeSessionTicketOpen(out, out_len, max_out_len);
-
-  QuicConnectionStats::TlsServerOperationStats decrypt_ticket_stats;
-  decrypt_ticket_stats.success = (result == ssl_ticket_aead_success);
-  if (async_op_timer_.has_value()) {
-    async_op_timer_->Stop(now());
-    decrypt_ticket_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
-    async_op_timer_.reset();
-    RECORD_LATENCY_IN_US("tls_server_async_decrypt_ticket_latency_us",
-                         decrypt_ticket_stats.async_latency,
-                         "Async decrypt ticket latency in microseconds");
-  }
-  connection_stats().tls_server_decrypt_ticket_stats =
-      std::move(decrypt_ticket_stats);
-
-  return result;
-}
-
-ssl_ticket_aead_result_t TlsServerHandshaker::FinalizeSessionTicketOpen(
-    uint8_t* out,
-    size_t* out_len,
-    size_t max_out_len) {
-  ticket_decryption_callback_ = nullptr;
-  set_expected_ssl_error(SSL_ERROR_WANT_READ);
-  if (decrypted_session_ticket_.empty()) {
-    QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
-    // Ticket decryption failed. Ignore the ticket.
-    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_2);
-    return ssl_ticket_aead_ignore_ticket;
-  }
-  if (max_out_len < decrypted_session_ticket_.size()) {
-    return ssl_ticket_aead_error;
-  }
-  memcpy(out, decrypted_session_ticket_.data(),
-         decrypted_session_ticket_.size());
-  *out_len = decrypted_session_ticket_.size();
-
-  QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_opened);
-  return ssl_ticket_aead_success;
-}
-
-ssl_select_cert_result_t TlsServerHandshaker::EarlySelectCertCallback(
-    const SSL_CLIENT_HELLO* client_hello) {
-  // EarlySelectCertCallback can be called twice from BoringSSL: If the first
-  // call returns ssl_select_cert_retry, when cert selection completes,
-  // SSL_do_handshake will call it again.
-
-  if (select_cert_status_.has_value()) {
-    // This is the second call, return the result directly.
-    QUIC_DVLOG(1) << "EarlySelectCertCallback called to continue handshake, "
-                     "returning directly. success:"
-                  << (select_cert_status_.value() == QUIC_SUCCESS);
-    return (select_cert_status_.value() == QUIC_SUCCESS)
-               ? ssl_select_cert_success
-               : ssl_select_cert_error;
-  }
-
-  // This is the first call.
-  select_cert_status_ = QUIC_PENDING;
-  proof_source_handle_ = MaybeCreateProofSourceHandle();
-
-  if (!pre_shared_key_.empty()) {
-    // TODO(b/154162689) add PSK support to QUIC+TLS.
-    QUIC_BUG(quic_bug_10341_6)
-        << "QUIC server pre-shared keys not yet supported with TLS";
-    return ssl_select_cert_error;
-  }
-
-  {
-    const uint8_t* unused_extension_bytes;
-    size_t unused_extension_len;
-    ticket_received_ = SSL_early_callback_ctx_extension_get(
-        client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes,
-        &unused_extension_len);
-
-    early_data_attempted_ = SSL_early_callback_ctx_extension_get(
-        client_hello, TLSEXT_TYPE_early_data, &unused_extension_bytes,
-        &unused_extension_len);
-  }
-
-  // This callback is called very early by Boring SSL, most of the SSL_get_foo
-  // function do not work at this point, but SSL_get_servername does.
-  const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
-  if (hostname) {
-    crypto_negotiated_params_->sni =
-        QuicHostnameUtils::NormalizeHostname(hostname);
-    if (!ValidateHostname(hostname)) {
-      return ssl_select_cert_error;
-    }
-    if (hostname != crypto_negotiated_params_->sni) {
-      QUIC_CODE_COUNT(quic_tls_server_hostname_diff);
-      QUIC_LOG_EVERY_N_SEC(WARNING, 300)
-          << "Raw and normalized hostnames differ, but both are valid SNIs. "
-             "raw hostname:"
-          << hostname << ", normalized:" << crypto_negotiated_params_->sni;
-    } else {
-      QUIC_CODE_COUNT(quic_tls_server_hostname_same);
-    }
-  } else {
-    QUIC_LOG(INFO) << "No hostname indicated in SNI";
-  }
-
-  std::string error_details;
-  if (!ProcessTransportParameters(client_hello, &error_details)) {
-    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
-    return ssl_select_cert_error;
-  }
-  OverrideQuicConfigDefaults(session()->config());
-  session()->OnConfigNegotiated();
-
-  auto set_transport_params_result = SetTransportParameters();
-  if (!set_transport_params_result.success) {
-    QUIC_LOG(ERROR) << "Failed to set transport parameters";
-    return ssl_select_cert_error;
-  }
-
-  bssl::UniquePtr<uint8_t> ssl_capabilities;
-  size_t ssl_capabilities_len = 0;
-  absl::string_view ssl_capabilities_view;
-
-  absl::optional<std::string> alps;
-
-  if (CryptoUtils::GetSSLCapabilities(ssl(), &ssl_capabilities,
-                                      &ssl_capabilities_len)) {
-    ssl_capabilities_view =
-        absl::string_view(reinterpret_cast<const char*>(ssl_capabilities.get()),
-                          ssl_capabilities_len);
-  }
-
-  // Enable ALPS for the session's ALPN.
-  SetApplicationSettingsResult alps_result =
-      SetApplicationSettings(AlpnForVersion(session()->version()));
-  if (!alps_result.success) {
-    return ssl_select_cert_error;
-  }
-  alps =
-      alps_result.alps_length > 0
-          ? std::string(alps_result.alps_buffer.get(), alps_result.alps_length)
-          : std::string();
-
-  if (no_select_cert_if_disconnected_ &&
-      !session()->connection()->connected()) {
-    QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 2, 2);
-    select_cert_status_ = QUIC_FAILURE;
-    return ssl_select_cert_error;
-  }
-
-  can_disable_resumption_ = false;
-  const QuicAsyncStatus status = proof_source_handle_->SelectCertificate(
-      session()->connection()->self_address().Normalized(),
-      session()->connection()->peer_address().Normalized(),
-      ssl_capabilities_view, crypto_negotiated_params_->sni,
-      absl::string_view(
-          reinterpret_cast<const char*>(client_hello->client_hello),
-          client_hello->client_hello_len),
-      AlpnForVersion(session()->version()), std::move(alps),
-      set_transport_params_result.quic_transport_params,
-      set_transport_params_result.early_data_context,
-      tls_connection_.ssl_config());
-
-  QUICHE_DCHECK_EQ(status, select_cert_status().value());
-
-  if (status == QUIC_PENDING) {
-    set_expected_ssl_error(SSL_ERROR_PENDING_CERTIFICATE);
-    if (async_op_timer_.has_value()) {
-      QUIC_CODE_COUNT(quic_tls_server_selecting_cert_while_another_op_pending);
-    }
-    async_op_timer_ = QuicTimeAccumulator();
-    async_op_timer_->Start(now());
-    return ssl_select_cert_retry;
-  }
-
-  if (status == QUIC_FAILURE) {
-    return ssl_select_cert_error;
-  }
-
-  return ssl_select_cert_success;
-}
-
-void TlsServerHandshaker::OnSelectCertificateDone(
-    bool ok, bool is_sync, const ProofSource::Chain* chain,
-    absl::string_view handshake_hints, absl::string_view ticket_encryption_key,
-    bool cert_matched_sni, QuicDelayedSSLConfig delayed_ssl_config) {
-  QUIC_DVLOG(1) << "OnSelectCertificateDone. ok:" << ok
-                << ", is_sync:" << is_sync
-                << ", len(handshake_hints):" << handshake_hints.size()
-                << ", len(ticket_encryption_key):"
-                << ticket_encryption_key.size();
-  absl::optional<QuicConnectionContextSwitcher> context_switcher;
-  if (!is_sync) {
-    context_switcher.emplace(connection_context());
-  }
-
-  QUIC_TRACESTRING(absl::StrCat(
-      "TLS select certificate done: ok:", ok,
-      ", certs_found:", (chain != nullptr && !chain->certs.empty()),
-      ", len(handshake_hints):", handshake_hints.size(),
-      ", len(ticket_encryption_key):", ticket_encryption_key.size()));
-
-  ticket_encryption_key_ = std::string(ticket_encryption_key);
-  select_cert_status_ = QUIC_FAILURE;
-  cert_matched_sni_ = cert_matched_sni;
-  if (session()->support_client_cert()) {
-    if (delayed_ssl_config.client_cert_mode.has_value()) {
-      tls_connection_.SetClientCertMode(*delayed_ssl_config.client_cert_mode);
-      QUIC_DVLOG(1) << "client_cert_mode after cert selection: "
-                    << client_cert_mode();
-    }
-  }
-  if (ok) {
-    if (chain && !chain->certs.empty()) {
-      tls_connection_.SetCertChain(chain->ToCryptoBuffers().value);
-      if (!handshake_hints.empty() &&
-          !SSL_set_handshake_hints(
-              ssl(), reinterpret_cast<const uint8_t*>(handshake_hints.data()),
-              handshake_hints.size())) {
-        // If |SSL_set_handshake_hints| fails, the ssl() object will remain
-        // intact, it is as if we didn't call it. The handshaker will
-        // continue to compute signature/decrypt ticket as normal.
-        QUIC_CODE_COUNT(quic_tls_server_set_handshake_hints_failed);
-        QUIC_DVLOG(1) << "SSL_set_handshake_hints failed";
-      }
-      select_cert_status_ = QUIC_SUCCESS;
-    } else {
-      QUIC_DLOG(ERROR) << "No certs provided for host '"
-                       << crypto_negotiated_params_->sni << "', server_address:"
-                       << session()->connection()->self_address()
-                       << ", client_address:"
-                       << session()->connection()->peer_address();
-    }
-  }
-
-  QuicConnectionStats::TlsServerOperationStats select_cert_stats;
-  select_cert_stats.success = (select_cert_status_ == QUIC_SUCCESS);
-  QUICHE_DCHECK_NE(is_sync, async_op_timer_.has_value());
-  if (async_op_timer_.has_value()) {
-    async_op_timer_->Stop(now());
-    select_cert_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
-    async_op_timer_.reset();
-    RECORD_LATENCY_IN_US("tls_server_async_select_cert_latency_us",
-                         select_cert_stats.async_latency,
-                         "Async select cert latency in microseconds");
-  }
-  connection_stats().tls_server_select_cert_stats =
-      std::move(select_cert_stats);
-
-  const int last_expected_ssl_error = expected_ssl_error();
-  set_expected_ssl_error(SSL_ERROR_WANT_READ);
-  if (!is_sync) {
-    QUICHE_DCHECK_EQ(last_expected_ssl_error, SSL_ERROR_PENDING_CERTIFICATE);
-    AdvanceHandshakeFromCallback();
-  }
-}
-
-bool TlsServerHandshaker::WillNotCallComputeSignature() const {
-  return SSL_can_release_private_key(ssl());
-}
-
-bool TlsServerHandshaker::ValidateHostname(const std::string& hostname) const {
-  if (!QuicHostnameUtils::IsValidSNI(hostname)) {
-    // TODO(b/151676147): Include this error string in the CONNECTION_CLOSE
-    // frame.
-    QUIC_DLOG(ERROR) << "Invalid SNI provided: \"" << hostname << "\"";
-    return false;
-  }
-  return true;
-}
-
-int TlsServerHandshaker::TlsExtServernameCallback(int* /*out_alert*/) {
-  // SSL_TLSEXT_ERR_OK causes the server_name extension to be acked in
-  // ServerHello.
-  return SSL_TLSEXT_ERR_OK;
-}
-
-int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
-                                    uint8_t* out_len,
-                                    const uint8_t* in,
-                                    unsigned in_len) {
-  // |in| contains a sequence of 1-byte-length-prefixed values.
-  *out_len = 0;
-  *out = nullptr;
-  if (in_len == 0) {
-    QUIC_DLOG(ERROR) << "No ALPN provided by client";
-    return SSL_TLSEXT_ERR_NOACK;
-  }
-
-  CBS all_alpns;
-  CBS_init(&all_alpns, in, in_len);
-
-  std::vector<absl::string_view> alpns;
-  while (CBS_len(&all_alpns) > 0) {
-    CBS alpn;
-    if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
-      QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
-      return SSL_TLSEXT_ERR_NOACK;
-    }
-
-    const size_t alpn_length = CBS_len(&alpn);
-    if (alpn_length == 0) {
-      QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
-      return SSL_TLSEXT_ERR_NOACK;
-    }
-
-    alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
-                       alpn_length);
-  }
-
-  // TODO(wub): Remove QuicSession::SelectAlpn. QuicSessions should know the
-  // ALPN on construction.
-  auto selected_alpn = session()->SelectAlpn(alpns);
-  if (selected_alpn == alpns.end()) {
-    QUIC_DLOG(ERROR) << "No known ALPN provided by client";
-    return SSL_TLSEXT_ERR_NOACK;
-  }
-
-  session()->OnAlpnSelected(*selected_alpn);
-  valid_alpn_received_ = true;
-  *out_len = selected_alpn->size();
-  *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
-  return SSL_TLSEXT_ERR_OK;
-}
-
-TlsServerHandshaker::SetApplicationSettingsResult
-TlsServerHandshaker::SetApplicationSettings(absl::string_view alpn) {
-  TlsServerHandshaker::SetApplicationSettingsResult result;
-  const uint8_t* alps_data = nullptr;
-
-  const std::string& hostname = crypto_negotiated_params_->sni;
-  std::string accept_ch_value = GetAcceptChValueForHostname(hostname);
-  std::string origin = absl::StrCat("https://", hostname);
-  uint16_t port = session()->self_address().port();
-  if (port != kDefaultPort) {
-    // This should be rare in production, but useful for test servers.
-    QUIC_CODE_COUNT(quic_server_alps_non_default_port);
-    absl::StrAppend(&origin, ":", port);
-  }
-
-  if (!accept_ch_value.empty()) {
-    AcceptChFrame frame{{{std::move(origin), std::move(accept_ch_value)}}};
-    result.alps_length =
-        HttpEncoder::SerializeAcceptChFrame(frame, &result.alps_buffer);
-    alps_data = reinterpret_cast<const uint8_t*>(result.alps_buffer.get());
-  }
-
-  if (SSL_add_application_settings(
-          ssl(), reinterpret_cast<const uint8_t*>(alpn.data()), alpn.size(),
-          alps_data, result.alps_length) != 1) {
-    QUIC_DLOG(ERROR) << "Failed to enable ALPS";
-    result.success = false;
-  } else {
-    result.success = true;
-  }
-  return result;
-}
-
-SSL* TlsServerHandshaker::GetSsl() const { return ssl(); }
-
-}  // namespace quic
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
deleted file mode 100644
index b5764a5..0000000
--- a/quic/core/tls_server_handshaker.h
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
-#define QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/tls_server_connection.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_time_accumulator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/tls_handshaker.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_flag_utils.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-// An implementation of QuicCryptoServerStreamBase which uses
-// TLS 1.3 for the crypto handshake protocol.
-class QUIC_EXPORT_PRIVATE TlsServerHandshaker
-    : public TlsHandshaker,
-      public TlsServerConnection::Delegate,
-      public ProofSourceHandleCallback,
-      public QuicCryptoServerStreamBase {
- public:
-  // |crypto_config| must outlive TlsServerHandshaker.
-  TlsServerHandshaker(QuicSession* session,
-                      const QuicCryptoServerConfig* crypto_config);
-  TlsServerHandshaker(const TlsServerHandshaker&) = delete;
-  TlsServerHandshaker& operator=(const TlsServerHandshaker&) = delete;
-
-  ~TlsServerHandshaker() override;
-
-  // From QuicCryptoServerStreamBase
-  void CancelOutstandingCallbacks() override;
-  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
-  void SendServerConfigUpdate(
-      const CachedNetworkParameters* cached_network_params) override;
-  bool DisableResumption() override;
-  bool IsZeroRtt() const override;
-  bool IsResumption() const override;
-  bool ResumptionAttempted() const override;
-  // Must be called after EarlySelectCertCallback is started.
-  bool EarlyDataAttempted() const override;
-  int NumServerConfigUpdateMessagesSent() const override;
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters cached_network_params) override;
-  void OnPacketDecrypted(EncryptionLevel level) override;
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnConnectionClosed(QuicErrorCode error,
-                          ConnectionCloseSource source) override;
-  void OnHandshakeDoneReceived() override;
-  std::string GetAddressToken(
-      const CachedNetworkParameters* cached_network_params) const override;
-  bool ValidateAddressToken(absl::string_view token) const override;
-  void OnNewTokenReceived(absl::string_view token) override;
-  bool ShouldSendExpectCTHeader() const override;
-  bool DidCertMatchSni() const override;
-  const ProofSource::Details* ProofSourceDetails() const override;
-  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
-                            size_t result_len, std::string* result) override;
-  SSL* GetSsl() const override;
-
-  // From QuicCryptoServerStreamBase and TlsHandshaker
-  ssl_early_data_reason_t EarlyDataReason() const override;
-  bool encryption_established() const override;
-  bool one_rtt_keys_available() const override;
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override;
-  CryptoMessageParser* crypto_message_parser() override;
-  HandshakeState GetHandshakeState() const override;
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> state) override;
-  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override;
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
-  void SetWriteSecret(EncryptionLevel level,
-                      const SSL_CIPHER* cipher,
-                      const std::vector<uint8_t>& write_secret) override;
-
-  // Called with normalized SNI hostname as |hostname|.  Return value will be
-  // sent in an ACCEPT_CH frame in the TLS ALPS extension, unless empty.
-  virtual std::string GetAcceptChValueForHostname(
-      const std::string& hostname) const;
-
-  // Get the ClientCertMode that is currently in effect on this handshaker.
-  ClientCertMode client_cert_mode() const {
-    return tls_connection_.ssl_config().client_cert_mode;
-  }
-
- protected:
-  // Override for tracing.
-  void InfoCallback(int type, int value) override;
-
-  // Creates a proof source handle for selecting cert and computing signature.
-  virtual std::unique_ptr<ProofSourceHandle> MaybeCreateProofSourceHandle();
-
-  // Hook to allow the server to override parts of the QuicConfig based on SNI
-  // before we generate transport parameters.
-  virtual void OverrideQuicConfigDefaults(QuicConfig* config);
-
-  virtual bool ValidateHostname(const std::string& hostname) const;
-
-  const TlsConnection* tls_connection() const override {
-    return &tls_connection_;
-  }
-
-  virtual void ProcessAdditionalTransportParameters(
-      const TransportParameters& /*params*/) {}
-
-  // Called when a potentially async operation is done and the done callback
-  // needs to advance the handshake.
-  void AdvanceHandshakeFromCallback();
-
-  // TlsHandshaker implementation:
-  void FinishHandshake() override;
-  void ProcessPostHandshakeMessage() override {}
-  QuicAsyncStatus VerifyCertChain(
-      const std::vector<std::string>& certs,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) override;
-  void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& verify_details) override;
-
-  // TlsServerConnection::Delegate implementation:
-  // Used to select certificates and process transport parameters.
-  ssl_select_cert_result_t EarlySelectCertCallback(
-      const SSL_CLIENT_HELLO* client_hello) override;
-  int TlsExtServernameCallback(int* out_alert) override;
-  int SelectAlpn(const uint8_t** out,
-                 uint8_t* out_len,
-                 const uint8_t* in,
-                 unsigned in_len) override;
-  ssl_private_key_result_t PrivateKeySign(uint8_t* out,
-                                          size_t* out_len,
-                                          size_t max_out,
-                                          uint16_t sig_alg,
-                                          absl::string_view in) override;
-  ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
-                                              size_t* out_len,
-                                              size_t max_out) override;
-  size_t SessionTicketMaxOverhead() override;
-  int SessionTicketSeal(uint8_t* out,
-                        size_t* out_len,
-                        size_t max_out_len,
-                        absl::string_view in) override;
-  ssl_ticket_aead_result_t SessionTicketOpen(uint8_t* out,
-                                             size_t* out_len,
-                                             size_t max_out_len,
-                                             absl::string_view in) override;
-  // Called when ticket_decryption_callback_ is done to determine a final
-  // decryption result.
-  ssl_ticket_aead_result_t FinalizeSessionTicketOpen(uint8_t* out,
-                                                     size_t* out_len,
-                                                     size_t max_out_len);
-  TlsConnection::Delegate* ConnectionDelegate() override { return this; }
-
-  // The status of cert selection. nullopt means it hasn't started.
-  const absl::optional<QuicAsyncStatus>& select_cert_status() const {
-    return select_cert_status_;
-  }
-  // Whether |cert_verify_sig_| contains a valid signature.
-  // NOTE: BoringSSL queries the result of a async signature operation using
-  // PrivateKeyComplete(), a successful PrivateKeyComplete() will clear the
-  // content of |cert_verify_sig_|, this function should not be called after
-  // that.
-  bool HasValidSignature(size_t max_signature_size) const;
-
-  // ProofSourceHandleCallback implementation:
-  void OnSelectCertificateDone(
-      bool ok, bool is_sync, const ProofSource::Chain* chain,
-      absl::string_view handshake_hints,
-      absl::string_view ticket_encryption_key, bool cert_matched_sni,
-      QuicDelayedSSLConfig delayed_ssl_config) override;
-
-  void OnComputeSignatureDone(
-      bool ok,
-      bool is_sync,
-      std::string signature,
-      std::unique_ptr<ProofSource::Details> details) override;
-
-  void set_encryption_established(bool encryption_established) {
-    encryption_established_ = encryption_established;
-  }
-
-  bool WillNotCallComputeSignature() const override;
-
-  void SetIgnoreTicketOpen(bool value) { ignore_ticket_open_ = value; }
-
- private:
-  class QUIC_EXPORT_PRIVATE DecryptCallback
-      : public ProofSource::DecryptCallback {
-   public:
-    explicit DecryptCallback(TlsServerHandshaker* handshaker);
-    void Run(std::vector<uint8_t> plaintext) override;
-
-    // If called, Cancel causes the pending callback to be a no-op.
-    void Cancel();
-
-    // Return true if either
-    // - Cancel() has been called.
-    // - Run() has been called, or is in the middle of it.
-    bool IsDone() const { return handshaker_ == nullptr; }
-
-   private:
-    TlsServerHandshaker* handshaker_;
-  };
-
-  // DefaultProofSourceHandle delegates all operations to the shared proof
-  // source.
-  class QUIC_EXPORT_PRIVATE DefaultProofSourceHandle
-      : public ProofSourceHandle {
-   public:
-    DefaultProofSourceHandle(TlsServerHandshaker* handshaker,
-                             ProofSource* proof_source);
-
-    ~DefaultProofSourceHandle() override;
-
-    // Close the handle. Cancel the pending signature operation, if any.
-    void CloseHandle() override;
-
-    // Delegates to proof_source_->GetCertChain.
-    // Returns QUIC_SUCCESS or QUIC_FAILURE. Never returns QUIC_PENDING.
-    QuicAsyncStatus SelectCertificate(
-        const QuicSocketAddress& server_address,
-        const QuicSocketAddress& client_address,
-        absl::string_view ssl_capabilities,
-        const std::string& hostname,
-        absl::string_view client_hello,
-        const std::string& alpn,
-        absl::optional<std::string> alps,
-        const std::vector<uint8_t>& quic_transport_params,
-        const absl::optional<std::vector<uint8_t>>& early_data_context,
-        const QuicSSLConfig& ssl_config) override;
-
-    // Delegates to proof_source_->ComputeTlsSignature.
-    // Returns QUIC_SUCCESS, QUIC_FAILURE or QUIC_PENDING.
-    QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
-                                     const QuicSocketAddress& client_address,
-                                     const std::string& hostname,
-                                     uint16_t signature_algorithm,
-                                     absl::string_view in,
-                                     size_t max_signature_size) override;
-
-   protected:
-    ProofSourceHandleCallback* callback() override { return handshaker_; }
-
-   private:
-    class QUIC_EXPORT_PRIVATE DefaultSignatureCallback
-        : public ProofSource::SignatureCallback {
-     public:
-      explicit DefaultSignatureCallback(DefaultProofSourceHandle* handle)
-          : handle_(handle) {}
-
-      void Run(bool ok,
-               std::string signature,
-               std::unique_ptr<ProofSource::Details> details) override {
-        if (handle_ == nullptr) {
-          // Operation has been canceled, or Run has been called.
-          return;
-        }
-
-        DefaultProofSourceHandle* handle = handle_;
-        handle_ = nullptr;
-
-        handle->signature_callback_ = nullptr;
-        if (handle->handshaker_ != nullptr) {
-          handle->handshaker_->OnComputeSignatureDone(
-              ok, is_sync_, std::move(signature), std::move(details));
-        }
-      }
-
-      // If called, Cancel causes the pending callback to be a no-op.
-      void Cancel() { handle_ = nullptr; }
-
-      void set_is_sync(bool is_sync) { is_sync_ = is_sync; }
-
-     private:
-      DefaultProofSourceHandle* handle_;
-      // Set to false if handle_->ComputeSignature returns QUIC_PENDING.
-      bool is_sync_ = true;
-    };
-
-    // Not nullptr on construction. Set to nullptr when cancelled.
-    TlsServerHandshaker* handshaker_;  // Not owned.
-    ProofSource* proof_source_;        // Not owned.
-    DefaultSignatureCallback* signature_callback_ = nullptr;
-  };
-
-  struct QUIC_NO_EXPORT SetTransportParametersResult {
-    bool success = false;
-    // Empty vector if QUIC transport params are not set successfully.
-    std::vector<uint8_t> quic_transport_params;
-    // absl::nullopt if there is no application state to begin with.
-    // Empty vector if application state is not set successfully.
-    absl::optional<std::vector<uint8_t>> early_data_context;
-  };
-
-  SetTransportParametersResult SetTransportParameters();
-  bool ProcessTransportParameters(const SSL_CLIENT_HELLO* client_hello,
-                                  std::string* error_details);
-
-  struct QUIC_NO_EXPORT SetApplicationSettingsResult {
-    bool success = false;
-    std::unique_ptr<char[]> alps_buffer;
-    size_t alps_length = 0;
-  };
-  SetApplicationSettingsResult SetApplicationSettings(absl::string_view alpn);
-
-  QuicConnectionStats& connection_stats() {
-    return session()->connection()->mutable_stats();
-  }
-  QuicTime now() const { return session()->GetClock()->Now(); }
-
-  QuicConnectionContext* connection_context() {
-    return session()->connection()->context();
-  }
-
-  std::unique_ptr<ProofSourceHandle> proof_source_handle_;
-  ProofSource* proof_source_;
-
-  // State to handle potentially asynchronous session ticket decryption.
-  // |ticket_decryption_callback_| points to the non-owned callback that was
-  // passed to ProofSource::TicketCrypter::Decrypt but hasn't finished running
-  // yet.
-  DecryptCallback* ticket_decryption_callback_ = nullptr;
-  // |decrypted_session_ticket_| contains the decrypted session ticket after the
-  // callback has run but before it is passed to BoringSSL.
-  std::vector<uint8_t> decrypted_session_ticket_;
-  // |ticket_received_| tracks whether we received a resumption ticket from the
-  // client. It does not matter whether we were able to decrypt said ticket or
-  // if we actually resumed a session with it - the presence of this ticket
-  // indicates that the client attempted a resumption.
-  bool ticket_received_ = false;
-
-  // True if the "early_data" extension is in the client hello.
-  bool early_data_attempted_ = false;
-
-  // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
-  bool ignore_ticket_open_ = false;
-
-  // nullopt means select cert hasn't started.
-  absl::optional<QuicAsyncStatus> select_cert_status_;
-
-  std::string cert_verify_sig_;
-  std::unique_ptr<ProofSource::Details> proof_source_details_;
-
-  // Count the duration of the current async operation, if any.
-  absl::optional<QuicTimeAccumulator> async_op_timer_;
-
-  std::unique_ptr<ApplicationState> application_state_;
-
-  // Pre-shared key used during the handshake.
-  std::string pre_shared_key_;
-
-  // (optional) Key to use for encrypting TLS resumption tickets.
-  std::string ticket_encryption_key_;
-
-  HandshakeState state_ = HANDSHAKE_START;
-  bool encryption_established_ = false;
-  bool valid_alpn_received_ = false;
-  bool can_disable_resumption_ = true;
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
-      crypto_negotiated_params_;
-  TlsServerConnection tls_connection_;
-  const QuicCryptoServerConfig* crypto_config_;  // Unowned.
-  // The last received CachedNetworkParameters from a validated address token.
-  mutable std::unique_ptr<CachedNetworkParameters>
-      last_received_cached_network_params_;
-
-  bool cert_matched_sni_ = false;
-  const bool no_select_cert_if_disconnected_ =
-      GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected);
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
diff --git a/quic/core/tls_server_handshaker_test.cc b/quic/core/tls_server_handshaker_test.cc
deleted file mode 100644
index 0d46ef8..0000000
--- a/quic/core/tls_server_handshaker_test.cc
+++ /dev/null
@@ -1,1080 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/tls_server_handshaker.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/certificate_util.h"
-#include "quic/core/crypto/client_proof_source.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_client_handshaker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/failing_proof_source.h"
-#include "quic/test_tools/fake_proof_source.h"
-#include "quic/test_tools/fake_proof_source_handle.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_session_cache.h"
-#include "quic/test_tools/test_certificates.h"
-#include "quic/test_tools/test_ticket_crypter.h"
-
-namespace quic {
-class QuicConnection;
-class QuicStream;
-}  // namespace quic
-
-using testing::_;
-using testing::NiceMock;
-using testing::Return;
-
-namespace quic {
-namespace test {
-
-namespace {
-
-const char kServerHostname[] = "test.example.com";
-const uint16_t kServerPort = 443;
-
-struct TestParams {
-  ParsedQuicVersion version;
-  bool disable_resumption;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(p.version), "_",
-      (p.disable_resumption ? "ResumptionDisabled" : "ResumptionEnabled"));
-}
-
-// Constructs test permutations.
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (const auto& version : AllSupportedVersionsWithTls()) {
-    for (bool disable_resumption : {false, true}) {
-      params.push_back(TestParams{version, disable_resumption});
-    }
-  }
-  return params;
-}
-
-class TestTlsServerHandshaker : public TlsServerHandshaker {
- public:
-  TestTlsServerHandshaker(QuicSession* session,
-                          const QuicCryptoServerConfig* crypto_config)
-      : TlsServerHandshaker(session, crypto_config),
-        proof_source_(crypto_config->proof_source()) {
-    ON_CALL(*this, MaybeCreateProofSourceHandle())
-        .WillByDefault(testing::Invoke(
-            this, &TestTlsServerHandshaker::RealMaybeCreateProofSourceHandle));
-
-    ON_CALL(*this, OverrideQuicConfigDefaults(_))
-        .WillByDefault(testing::Invoke(
-            this, &TestTlsServerHandshaker::RealOverrideQuicConfigDefaults));
-  }
-
-  MOCK_METHOD(std::unique_ptr<ProofSourceHandle>,
-              MaybeCreateProofSourceHandle,
-              (),
-              (override));
-
-  MOCK_METHOD(void, OverrideQuicConfigDefaults, (QuicConfig * config),
-              (override));
-
-  void SetupProofSourceHandle(
-      FakeProofSourceHandle::Action select_cert_action,
-      FakeProofSourceHandle::Action compute_signature_action,
-      QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig()) {
-    EXPECT_CALL(*this, MaybeCreateProofSourceHandle())
-        .WillOnce(
-            testing::Invoke([this, select_cert_action, compute_signature_action,
-                             dealyed_ssl_config]() {
-              auto handle = std::make_unique<FakeProofSourceHandle>(
-                  proof_source_, this, select_cert_action,
-                  compute_signature_action, dealyed_ssl_config);
-              fake_proof_source_handle_ = handle.get();
-              return handle;
-            }));
-  }
-
-  FakeProofSourceHandle* fake_proof_source_handle() {
-    return fake_proof_source_handle_;
-  }
-
-  bool received_client_cert() const { return received_client_cert_; }
-
-  using TlsServerHandshaker::AdvanceHandshake;
-  using TlsServerHandshaker::expected_ssl_error;
-
- protected:
-  QuicAsyncStatus VerifyCertChain(
-      const std::vector<std::string>& certs, std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details, uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) override {
-    received_client_cert_ = true;
-    return TlsServerHandshaker::VerifyCertChain(certs, error_details, details,
-                                                out_alert, std::move(callback));
-  }
-
- private:
-  std::unique_ptr<ProofSourceHandle> RealMaybeCreateProofSourceHandle() {
-    return TlsServerHandshaker::MaybeCreateProofSourceHandle();
-  }
-
-  void RealOverrideQuicConfigDefaults(QuicConfig* config) {
-    return TlsServerHandshaker::OverrideQuicConfigDefaults(config);
-  }
-
-  // Owned by TlsServerHandshaker.
-  FakeProofSourceHandle* fake_proof_source_handle_ = nullptr;
-  ProofSource* proof_source_ = nullptr;
-  bool received_client_cert_ = false;
-};
-
-class TlsServerHandshakerTestSession : public TestQuicSpdyServerSession {
- public:
-  using TestQuicSpdyServerSession::TestQuicSpdyServerSession;
-
-  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* /*compressed_certs_cache*/) override {
-    if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
-      return std::make_unique<NiceMock<TestTlsServerHandshaker>>(this,
-                                                                 crypto_config);
-    }
-
-    QUICHE_CHECK(false) << "Unsupported handshake protocol: "
-                        << connection()->version().handshake_protocol;
-    return nullptr;
-  }
-};
-
-class TlsServerHandshakerTest : public QuicTestWithParam<TestParams> {
- public:
-  TlsServerHandshakerTest()
-      : server_compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
-        server_id_(kServerHostname, kServerPort, false),
-        supported_versions_({GetParam().version}) {
-    SetQuicFlag(FLAGS_quic_disable_server_tls_resumption,
-                GetParam().disable_resumption);
-    client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
-        crypto_test_utils::ProofVerifierForTesting(),
-        std::make_unique<test::SimpleSessionCache>());
-    InitializeServerConfig();
-    InitializeServer();
-    InitializeFakeClient();
-  }
-
-  ~TlsServerHandshakerTest() override {
-    // Ensure that anything that might reference |helpers_| is destroyed before
-    // |helpers_| is destroyed.
-    server_session_.reset();
-    client_session_.reset();
-    helpers_.clear();
-    alarm_factories_.clear();
-  }
-
-  void InitializeServerConfig() {
-    auto ticket_crypter = std::make_unique<TestTicketCrypter>();
-    ticket_crypter_ = ticket_crypter.get();
-    auto proof_source = std::make_unique<FakeProofSource>();
-    proof_source_ = proof_source.get();
-    proof_source_->SetTicketCrypter(std::move(ticket_crypter));
-    server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
-        QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-        std::move(proof_source), KeyExchangeSource::Default());
-  }
-
-  void InitializeServerConfigWithFailingProofSource() {
-    server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
-        QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-        std::make_unique<FailingProofSource>(), KeyExchangeSource::Default());
-  }
-
-  void CreateTlsServerHandshakerTestSession(MockQuicConnectionHelper* helper,
-                                            MockAlarmFactory* alarm_factory) {
-    server_connection_ = new PacketSavingConnection(
-        helper, alarm_factory, Perspective::IS_SERVER,
-        ParsedVersionOfIndex(supported_versions_, 0));
-
-    TlsServerHandshakerTestSession* server_session =
-        new TlsServerHandshakerTestSession(
-            server_connection_, DefaultQuicConfig(), supported_versions_,
-            server_crypto_config_.get(), &server_compressed_certs_cache_);
-    server_session->set_client_cert_mode(initial_client_cert_mode_);
-    server_session->Initialize();
-
-    // We advance the clock initially because the default time is zero and the
-    // strike register worries that we've just overflowed a uint32_t time.
-    server_connection_->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
-
-    QUICHE_CHECK(server_session);
-    server_session_.reset(server_session);
-  }
-
-  void InitializeServerWithFakeProofSourceHandle() {
-    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
-    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
-    CreateTlsServerHandshakerTestSession(helpers_.back().get(),
-                                         alarm_factories_.back().get());
-    server_handshaker_ = static_cast<NiceMock<TestTlsServerHandshaker>*>(
-        server_session_->GetMutableCryptoStream());
-    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
-        .Times(testing::AnyNumber());
-    EXPECT_CALL(*server_session_, SelectAlpn(_))
-        .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
-          return std::find(
-              alpns.cbegin(), alpns.cend(),
-              AlpnForVersion(server_session_->connection()->version()));
-        });
-    crypto_test_utils::SetupCryptoServerConfigForTest(
-        server_connection_->clock(), server_connection_->random_generator(),
-        server_crypto_config_.get());
-  }
-
-  // Initializes the crypto server stream state for testing.  May be
-  // called multiple times.
-  void InitializeServer() {
-    TestQuicSpdyServerSession* server_session = nullptr;
-    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
-    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
-    CreateServerSessionForTest(
-        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
-        helpers_.back().get(), alarm_factories_.back().get(),
-        server_crypto_config_.get(), &server_compressed_certs_cache_,
-        &server_connection_, &server_session);
-    QUICHE_CHECK(server_session);
-    server_session_.reset(server_session);
-    server_handshaker_ = nullptr;
-    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
-        .Times(testing::AnyNumber());
-    EXPECT_CALL(*server_session_, SelectAlpn(_))
-        .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
-          return std::find(
-              alpns.cbegin(), alpns.cend(),
-              AlpnForVersion(server_session_->connection()->version()));
-        });
-    crypto_test_utils::SetupCryptoServerConfigForTest(
-        server_connection_->clock(), server_connection_->random_generator(),
-        server_crypto_config_.get());
-  }
-
-  QuicCryptoServerStreamBase* server_stream() {
-    return server_session_->GetMutableCryptoStream();
-  }
-
-  QuicCryptoClientStream* client_stream() {
-    return client_session_->GetMutableCryptoStream();
-  }
-
-  // Initializes a fake client, and all its associated state, for
-  // testing.  May be called multiple times.
-  void InitializeFakeClient() {
-    TestQuicSpdyClientSession* client_session = nullptr;
-    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
-    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
-    CreateClientSessionForTest(
-        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
-        helpers_.back().get(), alarm_factories_.back().get(),
-        client_crypto_config_.get(), &client_connection_, &client_session);
-    const std::string default_alpn =
-        AlpnForVersion(client_connection_->version());
-    ON_CALL(*client_session, GetAlpnsToOffer())
-        .WillByDefault(Return(std::vector<std::string>({default_alpn})));
-    QUICHE_CHECK(client_session);
-    client_session_.reset(client_session);
-    moved_messages_counts_ = {0, 0};
-  }
-
-  void CompleteCryptoHandshake() {
-    while (!client_stream()->one_rtt_keys_available() ||
-           !server_stream()->one_rtt_keys_available()) {
-      auto previous_moved_messages_counts = moved_messages_counts_;
-      AdvanceHandshakeWithFakeClient();
-      // Check that the handshake has made forward progress
-      ASSERT_NE(previous_moved_messages_counts, moved_messages_counts_);
-    }
-  }
-
-  // Performs a single round of handshake message-exchange between the
-  // client and server.
-  void AdvanceHandshakeWithFakeClient() {
-    QUICHE_CHECK(server_connection_);
-    QUICHE_CHECK(client_session_ != nullptr);
-
-    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
-    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
-        .Times(testing::AnyNumber());
-    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
-    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
-    // Call CryptoConnect if we haven't moved any client messages yet.
-    if (moved_messages_counts_.first == 0) {
-      client_stream()->CryptoConnect();
-    }
-    moved_messages_counts_ = crypto_test_utils::AdvanceHandshake(
-        client_connection_, client_stream(), moved_messages_counts_.first,
-        server_connection_, server_stream(), moved_messages_counts_.second);
-  }
-
-  void ExpectHandshakeSuccessful() {
-    EXPECT_TRUE(client_stream()->one_rtt_keys_available());
-    EXPECT_TRUE(client_stream()->encryption_established());
-    EXPECT_TRUE(server_stream()->one_rtt_keys_available());
-    EXPECT_TRUE(server_stream()->encryption_established());
-    EXPECT_EQ(HANDSHAKE_COMPLETE, client_stream()->GetHandshakeState());
-    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_stream()->GetHandshakeState());
-
-    const auto& client_crypto_params =
-        client_stream()->crypto_negotiated_params();
-    const auto& server_crypto_params =
-        server_stream()->crypto_negotiated_params();
-    // The TLS params should be filled in on the client.
-    EXPECT_NE(0, client_crypto_params.cipher_suite);
-    EXPECT_NE(0, client_crypto_params.key_exchange_group);
-    EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
-
-    // The cipher suite and key exchange group should match on the client and
-    // server.
-    EXPECT_EQ(client_crypto_params.cipher_suite,
-              server_crypto_params.cipher_suite);
-    EXPECT_EQ(client_crypto_params.key_exchange_group,
-              server_crypto_params.key_exchange_group);
-    // We don't support client certs on the server (yet), so the server
-    // shouldn't have a peer signature algorithm to report.
-    EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
-  }
-
-  // Should only be called when using FakeProofSourceHandle.
-  FakeProofSourceHandle::SelectCertArgs last_select_cert_args() const {
-    QUICHE_CHECK(server_handshaker_ &&
-                 server_handshaker_->fake_proof_source_handle());
-    QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
-                      ->all_select_cert_args()
-                      .empty());
-    return server_handshaker_->fake_proof_source_handle()
-        ->all_select_cert_args()
-        .back();
-  }
-
-  // Should only be called when using FakeProofSourceHandle.
-  FakeProofSourceHandle::ComputeSignatureArgs last_compute_signature_args()
-      const {
-    QUICHE_CHECK(server_handshaker_ &&
-                 server_handshaker_->fake_proof_source_handle());
-    QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
-                      ->all_compute_signature_args()
-                      .empty());
-    return server_handshaker_->fake_proof_source_handle()
-        ->all_compute_signature_args()
-        .back();
-  }
-
- protected:
-  // Setup the client to send a (self-signed) client cert to the server, if
-  // requested. InitializeFakeClient() must be called after this to take effect.
-  bool SetupClientCert() {
-    auto client_proof_source = std::make_unique<DefaultClientProofSource>();
-
-    CertificatePrivateKey client_cert_key(
-        MakeKeyPairForSelfSignedCertificate());
-
-    CertificateOptions options;
-    options.subject = "CN=subject";
-    options.serial_number = 0x12345678;
-    options.validity_start = {2020, 1, 1, 0, 0, 0};
-    options.validity_end = {2049, 12, 31, 0, 0, 0};
-    std::string der_cert =
-        CreateSelfSignedCertificate(*client_cert_key.private_key(), options);
-
-    quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
-        client_cert_chain(new ClientProofSource::Chain({der_cert}));
-
-    if (!client_proof_source->AddCertAndKey({"*"}, client_cert_chain,
-                                            std::move(client_cert_key))) {
-      return false;
-    }
-
-    client_crypto_config_->set_proof_source(std::move(client_proof_source));
-    return true;
-  }
-
-  // Every connection gets its own MockQuicConnectionHelper and
-  // MockAlarmFactory, tracked separately from the server and client state so
-  // their lifetimes persist through the whole test.
-  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
-  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
-
-  // Server state.
-  PacketSavingConnection* server_connection_;
-  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
-  // Only set when initialized with InitializeServerWithFakeProofSourceHandle.
-  NiceMock<TestTlsServerHandshaker>* server_handshaker_ = nullptr;
-  TestTicketCrypter* ticket_crypter_;  // owned by proof_source_
-  FakeProofSource* proof_source_;      // owned by server_crypto_config_
-  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
-  QuicCompressedCertsCache server_compressed_certs_cache_;
-  QuicServerId server_id_;
-  ClientCertMode initial_client_cert_mode_ = ClientCertMode::kNone;
-
-  // Client state.
-  PacketSavingConnection* client_connection_;
-  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
-  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
-
-  crypto_test_utils::FakeClientOptions client_options_;
-  // How many handshake messages have been moved from client to server and
-  // server to client.
-  std::pair<size_t, size_t> moved_messages_counts_ = {0, 0};
-
-  // Which QUIC versions the client and server support.
-  ParsedQuicVersionVector supported_versions_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TlsServerHandshakerTests,
-                         TlsServerHandshakerTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(TlsServerHandshakerTest, NotInitiallyConected) {
-  EXPECT_FALSE(server_stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsServerHandshakerTest, ConnectedAfterTlsHandshake) {
-  CompleteCryptoHandshake();
-  EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
-  ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertSuccess) {
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
-  // Start handshake.
-  AdvanceHandshakeWithFakeClient();
-
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
-  CompleteCryptoHandshake();
-
-  ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertFailure) {
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::FAIL_ASYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  // Start handshake.
-  AdvanceHandshakeWithFakeClient();
-
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
-  // Check that the server didn't send any handshake messages, because it failed
-  // to handshake.
-  EXPECT_EQ(moved_messages_counts_.second, 0u);
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertAndSignature) {
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_ASYNC);
-
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
-  // Start handshake.
-  AdvanceHandshakeWithFakeClient();
-
-  // A select cert operation is now pending.
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  EXPECT_EQ(server_handshaker_->expected_ssl_error(),
-            SSL_ERROR_PENDING_CERTIFICATE);
-
-  // Complete the pending select cert. It should advance the handshake to
-  // compute a signature, which will also be saved as a pending operation.
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
-  // A compute signature operation is now pending.
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  EXPECT_EQ(server_handshaker_->expected_ssl_error(),
-            SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
-
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
-  CompleteCryptoHandshake();
-
-  ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSignature) {
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
-  // asynchronously.
-  proof_source_->Activate();
-
-  // Start handshake.
-  AdvanceHandshakeWithFakeClient();
-
-  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
-  proof_source_->InvokePendingCallback(0);
-
-  CompleteCryptoHandshake();
-
-  ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, CancelPendingSelectCert) {
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
-  // Start handshake.
-  AdvanceHandshakeWithFakeClient();
-
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  server_handshaker_->CancelOutstandingCallbacks();
-  ASSERT_FALSE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  // CompletePendingOperation should be noop.
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-}
-
-TEST_P(TlsServerHandshakerTest, CancelPendingSignature) {
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
-  // asynchronously.
-  proof_source_->Activate();
-
-  // Start handshake.
-  AdvanceHandshakeWithFakeClient();
-
-  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
-  server_session_ = nullptr;
-
-  proof_source_->InvokePendingCallback(0);
-}
-
-TEST_P(TlsServerHandshakerTest, ExtractSNI) {
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
-            "test.example.com");
-}
-
-TEST_P(TlsServerHandshakerTest, HostnameForCertSelectionAndComputeSignature) {
-  // Client uses upper case letters in hostname. It is considered valid by
-  // QuicHostnameUtils::IsValidSNI, but it should be normalized for cert
-  // selection.
-  server_id_ = QuicServerId("tEsT.EXAMPLE.CoM", kServerPort, false);
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
-            "test.example.com");
-
-  EXPECT_EQ(last_select_cert_args().hostname, "test.example.com");
-  EXPECT_EQ(last_compute_signature_args().hostname, "test.example.com");
-}
-
-TEST_P(TlsServerHandshakerTest, SSLConfigForCertSelection) {
-  InitializeServerWithFakeProofSourceHandle();
-
-  // Disable early data.
-  server_session_->set_early_data_enabled(false);
-
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  EXPECT_FALSE(last_select_cert_args().ssl_config.early_data_enabled);
-}
-
-TEST_P(TlsServerHandshakerTest, ConnectionClosedOnTlsError) {
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
-
-  // Send a zero-length ClientHello from client to server.
-  char bogus_handshake_message[] = {
-      // Handshake struct (RFC 8446 appendix B.3)
-      1,        // HandshakeType client_hello
-      0, 0, 0,  // uint24 length
-  };
-
-  // Install a packet flusher such that the packets generated by
-  // |server_connection_| in response to this handshake message are more likely
-  // to be coalesced and/or batched in the writer.
-  //
-  // This is required by TlsServerHandshaker because without the flusher, it
-  // tends to generate many small, uncoalesced packets, one per
-  // TlsHandshaker::WriteMessage.
-  QuicConnection::ScopedPacketFlusher flusher(server_connection_);
-  server_stream()->crypto_message_parser()->ProcessInput(
-      absl::string_view(bogus_handshake_message,
-                        ABSL_ARRAYSIZE(bogus_handshake_message)),
-      ENCRYPTION_INITIAL);
-
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsServerHandshakerTest, ClientSendingBadALPN) {
-  const std::string kTestBadClientAlpn = "bad-client-alpn";
-  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
-      .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
-
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED,
-                              static_cast<QuicIetfTransportErrorCodes>(
-                                  CRYPTO_ERROR_FIRST + 120),
-                              "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
-                              "no application protocol",
-                              _));
-
-  AdvanceHandshakeWithFakeClient();
-
-  EXPECT_FALSE(client_stream()->one_rtt_keys_available());
-  EXPECT_FALSE(client_stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-  EXPECT_FALSE(server_stream()->encryption_established());
-}
-
-TEST_P(TlsServerHandshakerTest, CustomALPNNegotiation) {
-  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
-
-  const std::string kTestAlpn = "A Custom ALPN Value";
-  const std::vector<std::string> kTestAlpns(
-      {"foo", "bar", kTestAlpn, "something else"});
-  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
-      .WillRepeatedly(Return(kTestAlpns));
-  EXPECT_CALL(*server_session_, SelectAlpn(_))
-      .WillOnce(
-          [kTestAlpn, kTestAlpns](const std::vector<absl::string_view>& alpns) {
-            EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns));
-            return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
-          });
-  EXPECT_CALL(*client_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
-  EXPECT_CALL(*server_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsServerHandshakerTest, RejectInvalidSNI) {
-  server_id_ = QuicServerId("invalid!.example.com", kServerPort, false);
-  InitializeFakeClient();
-  static_cast<TlsClientHandshaker*>(
-      QuicCryptoClientStreamPeer::GetHandshaker(client_stream()))
-      ->AllowInvalidSNIForTests();
-
-  // Run the handshake and expect it to fail.
-  AdvanceHandshakeWithFakeClient();
-  EXPECT_FALSE(server_stream()->encryption_established());
-  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
-}
-
-TEST_P(TlsServerHandshakerTest, Resumption) {
-  // Do the first handshake
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_FALSE(client_stream()->IsResumption());
-  EXPECT_FALSE(server_stream()->IsResumption());
-  EXPECT_FALSE(server_stream()->ResumptionAttempted());
-
-  // Now do another handshake
-  InitializeServer();
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
-  EXPECT_NE(server_stream()->IsResumption(), GetParam().disable_resumption);
-  EXPECT_NE(server_stream()->ResumptionAttempted(),
-            GetParam().disable_resumption);
-}
-
-TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) {
-  // Do the first handshake
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  ticket_crypter_->SetRunCallbacksAsync(true);
-  // Now do another handshake
-  InitializeServer();
-  InitializeFakeClient();
-
-  AdvanceHandshakeWithFakeClient();
-  if (GetParam().disable_resumption) {
-    ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 0u);
-    return;
-  }
-  // Test that the DecryptCallback will be run asynchronously, and then run it.
-  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
-  ticket_crypter_->RunPendingCallback(0);
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_TRUE(client_stream()->IsResumption());
-  EXPECT_TRUE(server_stream()->IsResumption());
-  EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_P(TlsServerHandshakerTest, AdvanceHandshakeDuringAsyncDecryptCallback) {
-  if (GetParam().disable_resumption) {
-    return;
-  }
-
-  // Do the first handshake
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  ticket_crypter_->SetRunCallbacksAsync(true);
-  // Now do another handshake
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-  InitializeFakeClient();
-
-  AdvanceHandshakeWithFakeClient();
-
-  // Ensure an async DecryptCallback is now pending.
-  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
-
-  {
-    QuicConnection::ScopedPacketFlusher flusher(server_connection_);
-    server_handshaker_->AdvanceHandshake();
-  }
-
-  // This will delete |server_handshaker_|.
-  server_session_ = nullptr;
-
-  ticket_crypter_->RunPendingCallback(0);  // Should not crash.
-}
-
-TEST_P(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) {
-  if (GetParam().disable_resumption) {
-    return;
-  }
-
-  // Do the first handshake
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  ticket_crypter_->set_fail_decrypt(true);
-  // Now do another handshake
-  InitializeServer();
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_FALSE(client_stream()->IsResumption());
-  EXPECT_FALSE(server_stream()->IsResumption());
-  EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_P(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) {
-  if (GetParam().disable_resumption) {
-    return;
-  }
-
-  // Do the first handshake
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  ticket_crypter_->set_fail_decrypt(true);
-  ticket_crypter_->SetRunCallbacksAsync(true);
-  // Now do another handshake
-  InitializeServer();
-  InitializeFakeClient();
-
-  AdvanceHandshakeWithFakeClient();
-  // Test that the DecryptCallback will be run asynchronously, and then run it.
-  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
-  ticket_crypter_->RunPendingCallback(0);
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_FALSE(client_stream()->IsResumption());
-  EXPECT_FALSE(server_stream()->IsResumption());
-  EXPECT_TRUE(server_stream()->ResumptionAttempted());
-}
-
-TEST_P(TlsServerHandshakerTest, HandshakeFailsWithFailingProofSource) {
-  InitializeServerConfigWithFailingProofSource();
-  InitializeServer();
-  InitializeFakeClient();
-
-  // Attempt handshake.
-  AdvanceHandshakeWithFakeClient();
-  // Check that the server didn't send any handshake messages, because it failed
-  // to handshake.
-  EXPECT_EQ(moved_messages_counts_.second, 0u);
-}
-
-TEST_P(TlsServerHandshakerTest, ZeroRttResumption) {
-  std::vector<uint8_t> application_state = {0, 1, 2, 3};
-
-  // Do the first handshake
-  server_stream()->SetServerApplicationStateForResumption(
-      std::make_unique<ApplicationState>(application_state));
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_FALSE(client_stream()->IsResumption());
-  EXPECT_FALSE(server_stream()->IsZeroRtt());
-
-  // Now do another handshake
-  InitializeServer();
-  server_stream()->SetServerApplicationStateForResumption(
-      std::make_unique<ApplicationState>(application_state));
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
-  EXPECT_NE(server_stream()->IsZeroRtt(), GetParam().disable_resumption);
-}
-
-TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) {
-  std::vector<uint8_t> original_application_state = {1, 2};
-  std::vector<uint8_t> new_application_state = {3, 4};
-
-  // Do the first handshake
-  server_stream()->SetServerApplicationStateForResumption(
-      std::make_unique<ApplicationState>(original_application_state));
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_FALSE(client_stream()->IsResumption());
-  EXPECT_FALSE(server_stream()->IsZeroRtt());
-
-  // Do another handshake, but change the application state
-  InitializeServer();
-  server_stream()->SetServerApplicationStateForResumption(
-      std::make_unique<ApplicationState>(new_application_state));
-  InitializeFakeClient();
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
-  EXPECT_FALSE(server_stream()->IsZeroRtt());
-}
-
-TEST_P(TlsServerHandshakerTest, RequestClientCert) {
-  ASSERT_TRUE(SetupClientCert());
-  InitializeFakeClient();
-
-  initial_client_cert_mode_ = ClientCertMode::kRequest;
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
-    EXPECT_TRUE(server_handshaker_->received_client_cert());
-  } else {
-    EXPECT_FALSE(server_handshaker_->received_client_cert());
-  }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
-  ASSERT_TRUE(SetupClientCert());
-  InitializeFakeClient();
-
-  QuicDelayedSSLConfig delayed_ssl_config;
-  delayed_ssl_config.client_cert_mode = ClientCertMode::kRequest;
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      delayed_ssl_config);
-
-  AdvanceHandshakeWithFakeClient();
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
-    EXPECT_TRUE(server_handshaker_->received_client_cert());
-  } else {
-    EXPECT_FALSE(server_handshaker_->received_client_cert());
-  }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestClientCert_NoCert) {
-  initial_client_cert_mode_ = ClientCertMode::kRequest;
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  EXPECT_FALSE(server_handshaker_->received_client_cert());
-}
-
-TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
-  ASSERT_TRUE(SetupClientCert());
-  InitializeFakeClient();
-
-  initial_client_cert_mode_ = ClientCertMode::kRequire;
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-
-  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
-    EXPECT_TRUE(server_handshaker_->received_client_cert());
-  } else {
-    EXPECT_FALSE(server_handshaker_->received_client_cert());
-  }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
-  ASSERT_TRUE(SetupClientCert());
-  InitializeFakeClient();
-
-  QuicDelayedSSLConfig delayed_ssl_config;
-  delayed_ssl_config.client_cert_mode = ClientCertMode::kRequire;
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      delayed_ssl_config);
-
-  AdvanceHandshakeWithFakeClient();
-  ASSERT_TRUE(
-      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
-  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
-
-  CompleteCryptoHandshake();
-  ExpectHandshakeSuccessful();
-  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
-    EXPECT_TRUE(server_handshaker_->received_client_cert());
-  } else {
-    EXPECT_FALSE(server_handshaker_->received_client_cert());
-  }
-}
-
-TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert_NoCert) {
-  initial_client_cert_mode_ = ClientCertMode::kRequire;
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          DELEGATE_SYNC);
-
-  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
-    EXPECT_CALL(*server_connection_,
-                CloseConnection(QUIC_TLS_CERTIFICATE_REQUIRED, _, _, _));
-  }
-  AdvanceHandshakeWithFakeClient();
-  AdvanceHandshakeWithFakeClient();
-  EXPECT_FALSE(server_handshaker_->received_client_cert());
-}
-
-TEST_P(TlsServerHandshakerTest, CloseConnectionBeforeSelectCert) {
-  InitializeServerWithFakeProofSourceHandle();
-  server_handshaker_->SetupProofSourceHandle(
-      /*select_cert_action=*/FakeProofSourceHandle::Action::
-          FAIL_SYNC_DO_NOT_CHECK_CLOSED,
-      /*compute_signature_action=*/FakeProofSourceHandle::Action::
-          FAIL_SYNC_DO_NOT_CHECK_CLOSED);
-
-  EXPECT_CALL(*server_handshaker_, OverrideQuicConfigDefaults(_))
-      .WillOnce(testing::Invoke([](QuicConfig* config) {
-        QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(config,
-                                                            /*max_streams=*/0);
-      }));
-
-  EXPECT_CALL(*server_connection_,
-              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _))
-      .WillOnce(testing::Invoke(
-          [this](QuicErrorCode error, const std::string& details,
-                 ConnectionCloseBehavior connection_close_behavior) {
-            server_connection_->ReallyCloseConnection(
-                error, details, connection_close_behavior);
-            ASSERT_FALSE(server_connection_->connected());
-          }));
-
-  AdvanceHandshakeWithFakeClient();
-  if (!GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected)) {
-    // SelectCertificate is called when flag is false.
-    EXPECT_FALSE(server_handshaker_->fake_proof_source_handle()
-                     ->all_select_cert_args()
-                     .empty());
-    return;
-  }
-
-  EXPECT_TRUE(server_handshaker_->fake_proof_source_handle()
-                  ->all_select_cert_args()
-                  .empty());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/uber_quic_stream_id_manager.cc b/quic/core/uber_quic_stream_id_manager.cc
deleted file mode 100644
index 4cf55bc..0000000
--- a/quic/core/uber_quic_stream_id_manager.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/uber_quic_stream_id_manager.h"
-
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-UberQuicStreamIdManager::UberQuicStreamIdManager(
-    Perspective perspective,
-    ParsedQuicVersion version,
-    QuicStreamIdManager::DelegateInterface* delegate,
-    QuicStreamCount max_open_outgoing_bidirectional_streams,
-    QuicStreamCount max_open_outgoing_unidirectional_streams,
-    QuicStreamCount max_open_incoming_bidirectional_streams,
-    QuicStreamCount max_open_incoming_unidirectional_streams)
-    : version_(version),
-      bidirectional_stream_id_manager_(delegate,
-                                       /*unidirectional=*/false,
-                                       perspective,
-                                       version,
-                                       max_open_outgoing_bidirectional_streams,
-                                       max_open_incoming_bidirectional_streams),
-      unidirectional_stream_id_manager_(
-          delegate,
-          /*unidirectional=*/true,
-          perspective,
-          version,
-          max_open_outgoing_unidirectional_streams,
-          max_open_incoming_unidirectional_streams) {}
-
-bool UberQuicStreamIdManager::MaybeAllowNewOutgoingBidirectionalStreams(
-    QuicStreamCount max_open_streams) {
-  return bidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
-      max_open_streams);
-}
-bool UberQuicStreamIdManager::MaybeAllowNewOutgoingUnidirectionalStreams(
-    QuicStreamCount max_open_streams) {
-  return unidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
-      max_open_streams);
-}
-void UberQuicStreamIdManager::SetMaxOpenIncomingBidirectionalStreams(
-    QuicStreamCount max_open_streams) {
-  bidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
-}
-void UberQuicStreamIdManager::SetMaxOpenIncomingUnidirectionalStreams(
-    QuicStreamCount max_open_streams) {
-  unidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
-}
-
-bool UberQuicStreamIdManager::CanOpenNextOutgoingBidirectionalStream() const {
-  return bidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
-}
-
-bool UberQuicStreamIdManager::CanOpenNextOutgoingUnidirectionalStream() const {
-  return unidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
-}
-
-QuicStreamId UberQuicStreamIdManager::GetNextOutgoingBidirectionalStreamId() {
-  return bidirectional_stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-QuicStreamId UberQuicStreamIdManager::GetNextOutgoingUnidirectionalStreamId() {
-  return unidirectional_stream_id_manager_.GetNextOutgoingStreamId();
-}
-
-bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
-    QuicStreamId id,
-    std::string* error_details) {
-  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
-    return bidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
-        id, error_details);
-  }
-  return unidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
-      id, error_details);
-}
-
-void UberQuicStreamIdManager::OnStreamClosed(QuicStreamId id) {
-  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
-    bidirectional_stream_id_manager_.OnStreamClosed(id);
-    return;
-  }
-  unidirectional_stream_id_manager_.OnStreamClosed(id);
-}
-
-bool UberQuicStreamIdManager::OnStreamsBlockedFrame(
-    const QuicStreamsBlockedFrame& frame,
-    std::string* error_details) {
-  if (frame.unidirectional) {
-    return unidirectional_stream_id_manager_.OnStreamsBlockedFrame(
-        frame, error_details);
-  }
-  return bidirectional_stream_id_manager_.OnStreamsBlockedFrame(frame,
-                                                                error_details);
-}
-
-bool UberQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
-  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
-    return bidirectional_stream_id_manager_.IsAvailableStream(id);
-  }
-  return unidirectional_stream_id_manager_.IsAvailableStream(id);
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::GetMaxAllowdIncomingBidirectionalStreams() const {
-  return bidirectional_stream_id_manager_.incoming_initial_max_open_streams();
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::GetMaxAllowdIncomingUnidirectionalStreams() const {
-  return unidirectional_stream_id_manager_.incoming_initial_max_open_streams();
-}
-
-QuicStreamId UberQuicStreamIdManager::GetLargestPeerCreatedStreamId(
-    bool unidirectional) const {
-  if (unidirectional) {
-    return unidirectional_stream_id_manager_.largest_peer_created_stream_id();
-  }
-  return bidirectional_stream_id_manager_.largest_peer_created_stream_id();
-}
-
-QuicStreamId UberQuicStreamIdManager::next_outgoing_bidirectional_stream_id()
-    const {
-  return bidirectional_stream_id_manager_.next_outgoing_stream_id();
-}
-
-QuicStreamId UberQuicStreamIdManager::next_outgoing_unidirectional_stream_id()
-    const {
-  return unidirectional_stream_id_manager_.next_outgoing_stream_id();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_outgoing_bidirectional_streams()
-    const {
-  return bidirectional_stream_id_manager_.outgoing_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_outgoing_unidirectional_streams()
-    const {
-  return unidirectional_stream_id_manager_.outgoing_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_incoming_bidirectional_streams()
-    const {
-  return bidirectional_stream_id_manager_.incoming_actual_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::max_incoming_unidirectional_streams()
-    const {
-  return unidirectional_stream_id_manager_.incoming_actual_max_streams();
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::advertised_max_incoming_bidirectional_streams() const {
-  return bidirectional_stream_id_manager_.incoming_advertised_max_streams();
-}
-
-QuicStreamCount
-UberQuicStreamIdManager::advertised_max_incoming_unidirectional_streams()
-    const {
-  return unidirectional_stream_id_manager_.incoming_advertised_max_streams();
-}
-
-QuicStreamCount UberQuicStreamIdManager::outgoing_bidirectional_stream_count()
-    const {
-  return bidirectional_stream_id_manager_.outgoing_stream_count();
-}
-
-QuicStreamCount UberQuicStreamIdManager::outgoing_unidirectional_stream_count()
-    const {
-  return unidirectional_stream_id_manager_.outgoing_stream_count();
-}
-
-}  // namespace quic
diff --git a/quic/core/uber_quic_stream_id_manager.h b/quic/core/uber_quic_stream_id_manager.h
deleted file mode 100644
index 67ab7a0..0000000
--- a/quic/core/uber_quic_stream_id_manager.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
-#define QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
-
-#include "quic/core/quic_stream_id_manager.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-namespace test {
-class QuicSessionPeer;
-class UberQuicStreamIdManagerPeer;
-}  // namespace test
-
-class QuicSession;
-
-// This class comprises two QuicStreamIdManagers, which manage bidirectional and
-// unidirectional stream IDs, respectively.
-class QUIC_EXPORT_PRIVATE UberQuicStreamIdManager {
- public:
-  UberQuicStreamIdManager(
-      Perspective perspective,
-      ParsedQuicVersion version,
-      QuicStreamIdManager::DelegateInterface* delegate,
-      QuicStreamCount max_open_outgoing_bidirectional_streams,
-      QuicStreamCount max_open_outgoing_unidirectional_streams,
-      QuicStreamCount max_open_incoming_bidirectional_streams,
-      QuicStreamCount max_open_incoming_unidirectional_streams);
-
-  // Called on |max_open_streams| outgoing streams can be created because of 1)
-  // config negotiated or 2) MAX_STREAMS received. Returns true if new
-  // streams can be created.
-  bool MaybeAllowNewOutgoingBidirectionalStreams(
-      QuicStreamCount max_open_streams);
-  bool MaybeAllowNewOutgoingUnidirectionalStreams(
-      QuicStreamCount max_open_streams);
-
-  // Sets the limits to max_open_streams.
-  void SetMaxOpenIncomingBidirectionalStreams(QuicStreamCount max_open_streams);
-  void SetMaxOpenIncomingUnidirectionalStreams(
-      QuicStreamCount max_open_streams);
-
-  // Returns true if next outgoing bidirectional stream ID can be allocated.
-  bool CanOpenNextOutgoingBidirectionalStream() const;
-
-  // Returns true if next outgoing unidirectional stream ID can be allocated.
-  bool CanOpenNextOutgoingUnidirectionalStream() const;
-
-  // Returns the next outgoing bidirectional stream id.
-  QuicStreamId GetNextOutgoingBidirectionalStreamId();
-
-  // Returns the next outgoing unidirectional stream id.
-  QuicStreamId GetNextOutgoingUnidirectionalStreamId();
-
-  // Returns true if the incoming |id| is within the limit.
-  bool MaybeIncreaseLargestPeerStreamId(QuicStreamId id,
-                                        std::string* error_details);
-
-  // Called when |id| is released.
-  void OnStreamClosed(QuicStreamId id);
-
-  // Called when a STREAMS_BLOCKED frame is received.
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
-                             std::string* error_details);
-
-  // Returns true if |id| is still available.
-  bool IsAvailableStream(QuicStreamId id) const;
-
-  QuicStreamCount GetMaxAllowdIncomingBidirectionalStreams() const;
-
-  QuicStreamCount GetMaxAllowdIncomingUnidirectionalStreams() const;
-
-  QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
-
-  QuicStreamId next_outgoing_bidirectional_stream_id() const;
-  QuicStreamId next_outgoing_unidirectional_stream_id() const;
-
-  QuicStreamCount max_outgoing_bidirectional_streams() const;
-  QuicStreamCount max_outgoing_unidirectional_streams() const;
-
-  QuicStreamCount max_incoming_bidirectional_streams() const;
-  QuicStreamCount max_incoming_unidirectional_streams() const;
-
-  QuicStreamCount advertised_max_incoming_bidirectional_streams() const;
-  QuicStreamCount advertised_max_incoming_unidirectional_streams() const;
-
-  QuicStreamCount outgoing_bidirectional_stream_count() const;
-  QuicStreamCount outgoing_unidirectional_stream_count() const;
-
- private:
-  friend class test::QuicSessionPeer;
-  friend class test::UberQuicStreamIdManagerPeer;
-
-  ParsedQuicVersion version_;
-  // Manages stream IDs of bidirectional streams.
-  QuicStreamIdManager bidirectional_stream_id_manager_;
-
-  // Manages stream IDs of unidirectional streams.
-  QuicStreamIdManager unidirectional_stream_id_manager_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quic/core/uber_quic_stream_id_manager_test.cc b/quic/core/uber_quic_stream_id_manager_test.cc
deleted file mode 100644
index 8f2b590..0000000
--- a/quic/core/uber_quic_stream_id_manager_test.cc
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/uber_quic_stream_id_manager.h"
-
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using testing::_;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-struct TestParams {
-  explicit TestParams(ParsedQuicVersion version, Perspective perspective)
-      : version(version), perspective(perspective) {}
-
-  ParsedQuicVersion version;
-  Perspective perspective;
-};
-
-// Used by ::testing::PrintToStringParamName().
-std::string PrintToString(const TestParams& p) {
-  return absl::StrCat(
-      ParsedQuicVersionToString(p.version), "_",
-      (p.perspective == Perspective::IS_CLIENT ? "client" : "server"));
-}
-
-std::vector<TestParams> GetTestParams() {
-  std::vector<TestParams> params;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (!version.HasIetfQuicFrames()) {
-      continue;
-    }
-    params.push_back(TestParams(version, Perspective::IS_CLIENT));
-    params.push_back(TestParams(version, Perspective::IS_SERVER));
-  }
-  return params;
-}
-
-class MockDelegate : public QuicStreamIdManager::DelegateInterface {
- public:
-  MOCK_METHOD(void,
-              SendMaxStreams,
-              (QuicStreamCount stream_count, bool unidirectional),
-              (override));
-};
-
-class UberQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
- protected:
-  UberQuicStreamIdManagerTest()
-      : manager_(perspective(),
-                 version(),
-                 &delegate_,
-                 0,
-                 0,
-                 kDefaultMaxStreamsPerConnection,
-                 kDefaultMaxStreamsPerConnection) {}
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
-                                                    Perspective::IS_CLIENT) +
-           QuicUtils::StreamIdDelta(transport_version()) * n;
-  }
-
-  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
-    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
-                                                     Perspective::IS_CLIENT) +
-           QuicUtils::StreamIdDelta(transport_version()) * n;
-  }
-
-  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
-    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
-                                                    Perspective::IS_SERVER) +
-           QuicUtils::StreamIdDelta(transport_version()) * n;
-  }
-
-  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
-    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
-                                                     Perspective::IS_SERVER) +
-           QuicUtils::StreamIdDelta(transport_version()) * n;
-  }
-
-  QuicStreamId GetNthPeerInitiatedBidirectionalStreamId(int n) {
-    return ((perspective() == Perspective::IS_SERVER)
-                ? GetNthClientInitiatedBidirectionalId(n)
-                : GetNthServerInitiatedBidirectionalId(n));
-  }
-  QuicStreamId GetNthPeerInitiatedUnidirectionalStreamId(int n) {
-    return ((perspective() == Perspective::IS_SERVER)
-                ? GetNthClientInitiatedUnidirectionalId(n)
-                : GetNthServerInitiatedUnidirectionalId(n));
-  }
-  QuicStreamId GetNthSelfInitiatedBidirectionalStreamId(int n) {
-    return ((perspective() == Perspective::IS_CLIENT)
-                ? GetNthClientInitiatedBidirectionalId(n)
-                : GetNthServerInitiatedBidirectionalId(n));
-  }
-  QuicStreamId GetNthSelfInitiatedUnidirectionalStreamId(int n) {
-    return ((perspective() == Perspective::IS_CLIENT)
-                ? GetNthClientInitiatedUnidirectionalId(n)
-                : GetNthServerInitiatedUnidirectionalId(n));
-  }
-
-  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
-                               Perspective perspective,
-                               bool bidirectional) {
-    return ((bidirectional) ? QuicUtils::GetFirstBidirectionalStreamId(
-                                  transport_version(), perspective)
-                            : QuicUtils::GetFirstUnidirectionalStreamId(
-                                  transport_version(), perspective)) +
-           ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
-  }
-
-  ParsedQuicVersion version() { return GetParam().version; }
-  QuicTransportVersion transport_version() {
-    return version().transport_version;
-  }
-
-  Perspective perspective() { return GetParam().perspective; }
-
-  testing::StrictMock<MockDelegate> delegate_;
-  UberQuicStreamIdManager manager_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         UberQuicStreamIdManagerTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(UberQuicStreamIdManagerTest, Initialization) {
-  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
-            manager_.next_outgoing_bidirectional_stream_id());
-  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
-            manager_.next_outgoing_unidirectional_stream_id());
-}
-
-TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreams) {
-  const size_t kNumMaxOutgoingStream = 123;
-  // Set the uni- and bi- directional limits to different values to ensure
-  // that they are managed separately.
-  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
-      kNumMaxOutgoingStream));
-  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
-      kNumMaxOutgoingStream + 1));
-  EXPECT_EQ(kNumMaxOutgoingStream,
-            manager_.max_outgoing_bidirectional_streams());
-  EXPECT_EQ(kNumMaxOutgoingStream + 1,
-            manager_.max_outgoing_unidirectional_streams());
-  // Check that, for each directionality, we can open the correct number of
-  // streams.
-  int i = kNumMaxOutgoingStream;
-  while (i) {
-    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
-    manager_.GetNextOutgoingBidirectionalStreamId();
-    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
-    manager_.GetNextOutgoingUnidirectionalStreamId();
-    i--;
-  }
-  // One more unidirectional
-  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
-  manager_.GetNextOutgoingUnidirectionalStreamId();
-
-  // Both should be exhausted...
-  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
-  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
-}
-
-TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenIncomingStreams) {
-  const size_t kNumMaxIncomingStreams = 456;
-  manager_.SetMaxOpenIncomingUnidirectionalStreams(kNumMaxIncomingStreams);
-  // Do +1 for bidirectional to ensure that uni- and bi- get properly set.
-  manager_.SetMaxOpenIncomingBidirectionalStreams(kNumMaxIncomingStreams + 1);
-  EXPECT_EQ(kNumMaxIncomingStreams + 1,
-            manager_.GetMaxAllowdIncomingBidirectionalStreams());
-  EXPECT_EQ(kNumMaxIncomingStreams,
-            manager_.GetMaxAllowdIncomingUnidirectionalStreams());
-  EXPECT_EQ(manager_.max_incoming_bidirectional_streams(),
-            manager_.advertised_max_incoming_bidirectional_streams());
-  EXPECT_EQ(manager_.max_incoming_unidirectional_streams(),
-            manager_.advertised_max_incoming_unidirectional_streams());
-  // Make sure that we can create kNumMaxIncomingStreams incoming unidirectional
-  // streams and kNumMaxIncomingStreams+1 incoming bidirectional streams.
-  size_t i;
-  for (i = 0; i < kNumMaxIncomingStreams; i++) {
-    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-        GetNthPeerInitiatedUnidirectionalStreamId(i), nullptr));
-    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-        GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
-  }
-  // Should be able to open the next bidirectional stream
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-      GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
-
-  // We should have exhausted the counts, the next streams should fail
-  std::string error_details;
-  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
-      GetNthPeerInitiatedUnidirectionalStreamId(i), &error_details));
-  EXPECT_EQ(error_details,
-            absl::StrCat(
-                "Stream id ", GetNthPeerInitiatedUnidirectionalStreamId(i),
-                " would exceed stream count limit ", kNumMaxIncomingStreams));
-  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
-      GetNthPeerInitiatedBidirectionalStreamId(i + 1), &error_details));
-  EXPECT_EQ(error_details,
-            absl::StrCat("Stream id ",
-                         GetNthPeerInitiatedBidirectionalStreamId(i + 1),
-                         " would exceed stream count limit ",
-                         kNumMaxIncomingStreams + 1));
-}
-
-TEST_P(UberQuicStreamIdManagerTest, GetNextOutgoingStreamId) {
-  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(10));
-  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(10));
-  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
-            manager_.GetNextOutgoingBidirectionalStreamId());
-  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(1),
-            manager_.GetNextOutgoingBidirectionalStreamId());
-  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
-            manager_.GetNextOutgoingUnidirectionalStreamId());
-  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(1),
-            manager_.GetNextOutgoingUnidirectionalStreamId());
-}
-
-TEST_P(UberQuicStreamIdManagerTest, AvailableStreams) {
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-      GetNthPeerInitiatedBidirectionalStreamId(3), nullptr));
-  EXPECT_TRUE(
-      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(1)));
-  EXPECT_TRUE(
-      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(2)));
-
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-      GetNthPeerInitiatedUnidirectionalStreamId(3), nullptr));
-  EXPECT_TRUE(
-      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(1)));
-  EXPECT_TRUE(
-      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(2)));
-}
-
-TEST_P(UberQuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
-                      QuicUtils::InvertPerspective(perspective()),
-                      /* bidirectional=*/true),
-      nullptr));
-  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
-      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
-                      QuicUtils::InvertPerspective(perspective()),
-                      /* bidirectional=*/false),
-      nullptr));
-
-  std::string expected_error_details =
-      perspective() == Perspective::IS_SERVER
-          ? "Stream id 400 would exceed stream count limit 100"
-          : "Stream id 401 would exceed stream count limit 100";
-  std::string error_details;
-
-  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
-      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
-                      QuicUtils::InvertPerspective(perspective()),
-                      /* bidirectional=*/true),
-      &error_details));
-  EXPECT_EQ(expected_error_details, error_details);
-  expected_error_details =
-      perspective() == Perspective::IS_SERVER
-          ? "Stream id 402 would exceed stream count limit 100"
-          : "Stream id 403 would exceed stream count limit 100";
-
-  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
-      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
-                      QuicUtils::InvertPerspective(perspective()),
-                      /* bidirectional=*/false),
-      &error_details));
-  EXPECT_EQ(expected_error_details, error_details);
-}
-
-TEST_P(UberQuicStreamIdManagerTest, OnStreamsBlockedFrame) {
-  QuicStreamCount stream_count =
-      manager_.advertised_max_incoming_bidirectional_streams() - 1;
-
-  QuicStreamsBlockedFrame frame(kInvalidControlFrameId, stream_count,
-                                /*unidirectional=*/false);
-  EXPECT_CALL(delegate_,
-              SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
-                             frame.unidirectional))
-      .Times(0);
-  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
-
-  stream_count = manager_.advertised_max_incoming_unidirectional_streams() - 1;
-  frame.stream_count = stream_count;
-  frame.unidirectional = true;
-
-  EXPECT_CALL(delegate_,
-              SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
-                             frame.unidirectional))
-      .Times(0);
-  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
-}
-
-TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreamsPlusFrame) {
-  const size_t kNumMaxOutgoingStream = 123;
-  // Set the uni- and bi- directional limits to different values to ensure
-  // that they are managed separately.
-  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
-      kNumMaxOutgoingStream));
-  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
-      kNumMaxOutgoingStream + 1));
-  EXPECT_EQ(kNumMaxOutgoingStream,
-            manager_.max_outgoing_bidirectional_streams());
-  EXPECT_EQ(kNumMaxOutgoingStream + 1,
-            manager_.max_outgoing_unidirectional_streams());
-  // Check that, for each directionality, we can open the correct number of
-  // streams.
-  int i = kNumMaxOutgoingStream;
-  while (i) {
-    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
-    manager_.GetNextOutgoingBidirectionalStreamId();
-    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
-    manager_.GetNextOutgoingUnidirectionalStreamId();
-    i--;
-  }
-  // One more unidirectional
-  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
-  manager_.GetNextOutgoingUnidirectionalStreamId();
-
-  // Both should be exhausted...
-  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
-  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/uber_received_packet_manager.cc b/quic/core/uber_received_packet_manager.cc
deleted file mode 100644
index 62411d5..0000000
--- a/quic/core/uber_received_packet_manager.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/uber_received_packet_manager.h"
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
-    : supports_multiple_packet_number_spaces_(false) {
-  for (auto& received_packet_manager : received_packet_managers_) {
-    received_packet_manager.set_connection_stats(stats);
-  }
-}
-
-UberReceivedPacketManager::~UberReceivedPacketManager() {}
-
-void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
-                                              Perspective perspective) {
-  for (auto& received_packet_manager : received_packet_managers_) {
-    received_packet_manager.SetFromConfig(config, perspective);
-  }
-}
-
-bool UberReceivedPacketManager::IsAwaitingPacket(
-    EncryptionLevel decrypted_packet_level,
-    QuicPacketNumber packet_number) const {
-  if (!supports_multiple_packet_number_spaces_) {
-    return received_packet_managers_[0].IsAwaitingPacket(packet_number);
-  }
-  return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
-                                       decrypted_packet_level)]
-      .IsAwaitingPacket(packet_number);
-}
-
-const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
-    PacketNumberSpace packet_number_space,
-    QuicTime approximate_now) {
-  if (!supports_multiple_packet_number_spaces_) {
-    return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
-  }
-  return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
-      approximate_now);
-}
-
-void UberReceivedPacketManager::RecordPacketReceived(
-    EncryptionLevel decrypted_packet_level,
-    const QuicPacketHeader& header,
-    QuicTime receipt_time) {
-  if (!supports_multiple_packet_number_spaces_) {
-    received_packet_managers_[0].RecordPacketReceived(header, receipt_time);
-    return;
-  }
-  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
-                                decrypted_packet_level)]
-      .RecordPacketReceived(header, receipt_time);
-}
-
-void UberReceivedPacketManager::DontWaitForPacketsBefore(
-    EncryptionLevel decrypted_packet_level,
-    QuicPacketNumber least_unacked) {
-  if (!supports_multiple_packet_number_spaces_) {
-    received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
-    return;
-  }
-  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
-                                decrypted_packet_level)]
-      .DontWaitForPacketsBefore(least_unacked);
-}
-
-void UberReceivedPacketManager::MaybeUpdateAckTimeout(
-    bool should_last_packet_instigate_acks,
-    EncryptionLevel decrypted_packet_level,
-    QuicPacketNumber last_received_packet_number,
-    QuicTime last_packet_receipt_time, QuicTime now,
-    const RttStats* rtt_stats) {
-  if (!supports_multiple_packet_number_spaces_) {
-    received_packet_managers_[0].MaybeUpdateAckTimeout(
-        should_last_packet_instigate_acks, last_received_packet_number,
-        last_packet_receipt_time, now, rtt_stats);
-    return;
-  }
-  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
-                                decrypted_packet_level)]
-      .MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
-                             last_received_packet_number,
-                             last_packet_receipt_time, now, rtt_stats);
-}
-
-void UberReceivedPacketManager::ResetAckStates(
-    EncryptionLevel encryption_level) {
-  if (!supports_multiple_packet_number_spaces_) {
-    received_packet_managers_[0].ResetAckStates();
-    return;
-  }
-  received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
-      .ResetAckStates();
-  if (encryption_level == ENCRYPTION_INITIAL) {
-    // After one Initial ACK is sent, the others should be sent 'immediately'.
-    received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
-        kAlarmGranularity);
-  }
-}
-
-void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport(
-    Perspective perspective) {
-  if (supports_multiple_packet_number_spaces_) {
-    QUIC_BUG(quic_bug_10495_1)
-        << "Multiple packet number spaces has already been enabled";
-    return;
-  }
-  if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
-    QUIC_BUG(quic_bug_10495_2)
-        << "Try to enable multiple packet number spaces support after any "
-           "packet has been received.";
-    return;
-  }
-  // In IETF QUIC, the peer is expected to acknowledge packets in Initial and
-  // Handshake packets with minimal delay.
-  if (perspective == Perspective::IS_CLIENT) {
-    // Delay the first server ACK, because server ACKs are padded to
-    // full size and count towards the amplification limit.
-    received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
-        kAlarmGranularity);
-  }
-  received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay(
-      kAlarmGranularity);
-
-  supports_multiple_packet_number_spaces_ = true;
-}
-
-bool UberReceivedPacketManager::IsAckFrameUpdated() const {
-  if (!supports_multiple_packet_number_spaces_) {
-    return received_packet_managers_[0].ack_frame_updated();
-  }
-  for (const auto& received_packet_manager : received_packet_managers_) {
-    if (received_packet_manager.ack_frame_updated()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
-    EncryptionLevel decrypted_packet_level) const {
-  if (!supports_multiple_packet_number_spaces_) {
-    return received_packet_managers_[0].GetLargestObserved();
-  }
-  return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
-                                       decrypted_packet_level)]
-      .GetLargestObserved();
-}
-
-QuicTime UberReceivedPacketManager::GetAckTimeout(
-    PacketNumberSpace packet_number_space) const {
-  if (!supports_multiple_packet_number_spaces_) {
-    return received_packet_managers_[0].ack_timeout();
-  }
-  return received_packet_managers_[packet_number_space].ack_timeout();
-}
-
-QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
-  QuicTime ack_timeout = QuicTime::Zero();
-  // Returns the earliest non-zero ack timeout.
-  for (const auto& received_packet_manager : received_packet_managers_) {
-    const QuicTime timeout = received_packet_manager.ack_timeout();
-    if (!ack_timeout.IsInitialized()) {
-      ack_timeout = timeout;
-      continue;
-    }
-    if (timeout.IsInitialized()) {
-      ack_timeout = std::min(ack_timeout, timeout);
-    }
-  }
-  return ack_timeout;
-}
-
-bool UberReceivedPacketManager::IsAckFrameEmpty(
-    PacketNumberSpace packet_number_space) const {
-  if (!supports_multiple_packet_number_spaces_) {
-    return received_packet_managers_[0].IsAckFrameEmpty();
-  }
-  return received_packet_managers_[packet_number_space].IsAckFrameEmpty();
-}
-
-QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
-    const {
-  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
-  return received_packet_managers_[0].peer_least_packet_awaiting_ack();
-}
-
-size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
-  return received_packet_managers_[0].min_received_before_ack_decimation();
-}
-
-void UberReceivedPacketManager::set_min_received_before_ack_decimation(
-    size_t new_value) {
-  for (auto& received_packet_manager : received_packet_managers_) {
-    received_packet_manager.set_min_received_before_ack_decimation(new_value);
-  }
-}
-
-void UberReceivedPacketManager::set_ack_frequency(size_t new_value) {
-  for (auto& received_packet_manager : received_packet_managers_) {
-    received_packet_manager.set_ack_frequency(new_value);
-  }
-}
-
-const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
-  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
-  return received_packet_managers_[0].ack_frame();
-}
-
-const QuicAckFrame& UberReceivedPacketManager::GetAckFrame(
-    PacketNumberSpace packet_number_space) const {
-  QUICHE_DCHECK(supports_multiple_packet_number_spaces_);
-  return received_packet_managers_[packet_number_space].ack_frame();
-}
-
-void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
-  for (auto& received_packet_manager : received_packet_managers_) {
-    received_packet_manager.set_max_ack_ranges(max_ack_ranges);
-  }
-}
-
-void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
-  for (auto& received_packet_manager : received_packet_managers_) {
-    received_packet_manager.set_save_timestamps(
-        save_timestamps, supports_multiple_packet_number_spaces_);
-  }
-}
-
-void UberReceivedPacketManager::OnAckFrequencyFrame(
-    const QuicAckFrequencyFrame& frame) {
-  if (!supports_multiple_packet_number_spaces_) {
-    QUIC_BUG(quic_bug_10495_3)
-        << "Received AckFrequencyFrame when multiple packet number spaces "
-           "is not supported";
-    return;
-  }
-  received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame);
-}
-
-}  // namespace quic
diff --git a/quic/core/uber_received_packet_manager.h b/quic/core/uber_received_packet_manager.h
deleted file mode 100644
index c0c3e69..0000000
--- a/quic/core/uber_received_packet_manager.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
-#define QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
-
-#include "quic/core/frames/quic_ack_frequency_frame.h"
-#include "quic/core/quic_received_packet_manager.h"
-
-namespace quic {
-
-// This class comprises multiple received packet managers, one per packet number
-// space. Please note, if multiple packet number spaces is not supported, only
-// one received packet manager will be used.
-class QUIC_EXPORT_PRIVATE UberReceivedPacketManager {
- public:
-  explicit UberReceivedPacketManager(QuicConnectionStats* stats);
-  UberReceivedPacketManager(const UberReceivedPacketManager&) = delete;
-  UberReceivedPacketManager& operator=(const UberReceivedPacketManager&) =
-      delete;
-  virtual ~UberReceivedPacketManager();
-
-  void SetFromConfig(const QuicConfig& config, Perspective perspective);
-
-  // Checks if we are still waiting for the packet with |packet_number|.
-  bool IsAwaitingPacket(EncryptionLevel decrypted_packet_level,
-                        QuicPacketNumber packet_number) const;
-
-  // Called after a packet has been successfully decrypted and its header has
-  // been parsed.
-  void RecordPacketReceived(EncryptionLevel decrypted_packet_level,
-                            const QuicPacketHeader& header,
-                            QuicTime receipt_time);
-
-  // Retrieves a frame containing a QuicAckFrame. The ack frame must be
-  // serialized before another packet is received, or it will change.
-  const QuicFrame GetUpdatedAckFrame(PacketNumberSpace packet_number_space,
-                                     QuicTime approximate_now);
-
-  // Stop ACKing packets before |least_unacked|.
-  void DontWaitForPacketsBefore(EncryptionLevel decrypted_packet_level,
-                                QuicPacketNumber least_unacked);
-
-  // Called after header of last received packet has been successfully processed
-  // to update ACK timeout.
-  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
-                             EncryptionLevel decrypted_packet_level,
-                             QuicPacketNumber last_received_packet_number,
-                             QuicTime last_packet_receipt_time, QuicTime now,
-                             const RttStats* rtt_stats);
-
-  // Resets ACK related states, called after an ACK is successfully sent.
-  void ResetAckStates(EncryptionLevel encryption_level);
-
-  // Called to enable multiple packet number support.
-  void EnableMultiplePacketNumberSpacesSupport(Perspective perspective);
-
-  // Returns true if ACK frame has been updated since GetUpdatedAckFrame was
-  // last called.
-  bool IsAckFrameUpdated() const;
-
-  // Returns the largest received packet number.
-  QuicPacketNumber GetLargestObserved(
-      EncryptionLevel decrypted_packet_level) const;
-
-  // Returns ACK timeout of |packet_number_space|.
-  QuicTime GetAckTimeout(PacketNumberSpace packet_number_space) const;
-
-  // Get the earliest ack_timeout of all packet number spaces.
-  QuicTime GetEarliestAckTimeout() const;
-
-  // Return true if ack frame of |packet_number_space| is empty.
-  bool IsAckFrameEmpty(PacketNumberSpace packet_number_space) const;
-
-  QuicPacketNumber peer_least_packet_awaiting_ack() const;
-
-  size_t min_received_before_ack_decimation() const;
-  void set_min_received_before_ack_decimation(size_t new_value);
-
-  void set_ack_frequency(size_t new_value);
-
-  bool supports_multiple_packet_number_spaces() const {
-    return supports_multiple_packet_number_spaces_;
-  }
-
-  // For logging purposes.
-  const QuicAckFrame& ack_frame() const;
-  const QuicAckFrame& GetAckFrame(PacketNumberSpace packet_number_space) const;
-
-  void set_max_ack_ranges(size_t max_ack_ranges);
-
-  void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
-
-  void set_save_timestamps(bool save_timestamps);
-
- private:
-  friend class test::QuicConnectionPeer;
-  friend class test::UberReceivedPacketManagerPeer;
-
-  // One received packet manager per packet number space. If
-  // supports_multiple_packet_number_spaces_ is false, only the first (0 index)
-  // received_packet_manager is used.
-  QuicReceivedPacketManager received_packet_managers_[NUM_PACKET_NUMBER_SPACES];
-
-  bool supports_multiple_packet_number_spaces_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
diff --git a/quic/core/uber_received_packet_manager_test.cc b/quic/core/uber_received_packet_manager_test.cc
deleted file mode 100644
index 8ca3ae9..0000000
--- a/quic/core/uber_received_packet_manager_test.cc
+++ /dev/null
@@ -1,561 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/core/uber_received_packet_manager.h"
-
-#include <utility>
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class UberReceivedPacketManagerPeer {
- public:
-  static void SetAckDecimationDelay(UberReceivedPacketManager* manager,
-                                    float ack_decimation_delay) {
-    for (auto& received_packet_manager : manager->received_packet_managers_) {
-      received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
-    }
-  }
-};
-
-namespace {
-
-const bool kInstigateAck = true;
-const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
-const QuicTime::Delta kDelayedAckTime =
-    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-class UberReceivedPacketManagerTest : public QuicTest {
- protected:
-  UberReceivedPacketManagerTest() {
-    manager_ = std::make_unique<UberReceivedPacketManager>(&stats_);
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
-    manager_->set_save_timestamps(true);
-  }
-
-  void RecordPacketReceipt(uint64_t packet_number) {
-    RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number);
-  }
-
-  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
-    RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number, receipt_time);
-  }
-
-  void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
-                           uint64_t packet_number) {
-    RecordPacketReceipt(decrypted_packet_level, packet_number,
-                        QuicTime::Zero());
-  }
-
-  void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
-                           uint64_t packet_number,
-                           QuicTime receipt_time) {
-    QuicPacketHeader header;
-    header.packet_number = QuicPacketNumber(packet_number);
-    manager_->RecordPacketReceived(decrypted_packet_level, header,
-                                   receipt_time);
-  }
-
-  bool HasPendingAck() {
-    if (!manager_->supports_multiple_packet_number_spaces()) {
-      return manager_->GetAckTimeout(APPLICATION_DATA).IsInitialized();
-    }
-    return manager_->GetEarliestAckTimeout().IsInitialized();
-  }
-
-  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
-                             uint64_t last_received_packet_number) {
-    MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
-                          ENCRYPTION_FORWARD_SECURE,
-                          last_received_packet_number);
-  }
-
-  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
-                             EncryptionLevel decrypted_packet_level,
-                             uint64_t last_received_packet_number) {
-    manager_->MaybeUpdateAckTimeout(
-        should_last_packet_instigate_acks, decrypted_packet_level,
-        QuicPacketNumber(last_received_packet_number), clock_.ApproximateNow(),
-        clock_.ApproximateNow(), &rtt_stats_);
-  }
-
-  void CheckAckTimeout(QuicTime time) {
-    QUICHE_DCHECK(HasPendingAck());
-    if (!manager_->supports_multiple_packet_number_spaces()) {
-      QUICHE_DCHECK(manager_->GetAckTimeout(APPLICATION_DATA) == time);
-      if (time <= clock_.ApproximateNow()) {
-        // ACK timeout expires, send an ACK.
-        manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
-        QUICHE_DCHECK(!HasPendingAck());
-      }
-      return;
-    }
-    QUICHE_DCHECK(manager_->GetEarliestAckTimeout() == time);
-    // Send all expired ACKs.
-    for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
-      const QuicTime ack_timeout =
-          manager_->GetAckTimeout(static_cast<PacketNumberSpace>(i));
-      if (!ack_timeout.IsInitialized() ||
-          ack_timeout > clock_.ApproximateNow()) {
-        continue;
-      }
-      manager_->ResetAckStates(
-          QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
-    }
-  }
-
-  MockClock clock_;
-  RttStats rtt_stats_;
-  QuicConnectionStats stats_;
-  std::unique_ptr<UberReceivedPacketManager> manager_;
-};
-
-TEST_F(UberReceivedPacketManagerTest, DontWaitForPacketsBefore) {
-  EXPECT_TRUE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
-  RecordPacketReceipt(2);
-  EXPECT_FALSE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
-  RecordPacketReceipt(7);
-  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                         QuicPacketNumber(3u)));
-  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                         QuicPacketNumber(6u)));
-  manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
-                                     QuicPacketNumber(4));
-  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                          QuicPacketNumber(3u)));
-  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                         QuicPacketNumber(6u)));
-}
-
-TEST_F(UberReceivedPacketManagerTest, GetUpdatedAckFrame) {
-  QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  RecordPacketReceipt(2, two_ms);
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-
-  QuicFrame ack =
-      manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
-  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  // When UpdateReceivedPacketInfo with a time earlier than the time of the
-  // largest observed packet, make sure that the delta is 0, not negative.
-  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
-  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
-  QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
-  ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, four_ms);
-  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  // When UpdateReceivedPacketInfo after not having received a new packet,
-  // the delta should still be accurate.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
-            ack.ack_frame->ack_delay_time);
-  // And received packet times won't have change.
-  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
-
-  RecordPacketReceipt(999, two_ms);
-  RecordPacketReceipt(4, two_ms);
-  RecordPacketReceipt(1000, two_ms);
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-  ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, two_ms);
-  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  // UpdateReceivedPacketInfo should discard any times which can't be
-  // expressed on the wire.
-  EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
-}
-
-TEST_F(UberReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  RecordPacketReceipt(1);
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-  RecordPacketReceipt(6);
-  RecordPacketReceipt(2,
-                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-
-  EXPECT_EQ(4u, stats_.max_sequence_reordering);
-  EXPECT_EQ(1000, stats_.max_time_reordering_us);
-  EXPECT_EQ(1u, stats_.packets_reordered);
-}
-
-TEST_F(UberReceivedPacketManagerTest, LimitAckRanges) {
-  manager_->set_max_ack_ranges(10);
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  for (int i = 0; i < 100; ++i) {
-    RecordPacketReceipt(1 + 2 * i);
-    EXPECT_TRUE(manager_->IsAckFrameUpdated());
-    manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
-    EXPECT_GE(10u, manager_->ack_frame().packets.NumIntervals());
-    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
-              manager_->ack_frame().packets.Max());
-    for (int j = 0; j < std::min(10, i + 1); ++j) {
-      ASSERT_GE(i, j);
-      EXPECT_TRUE(manager_->ack_frame().packets.Contains(
-          QuicPacketNumber(1 + (i - j) * 2)));
-      if (i > j) {
-        EXPECT_FALSE(manager_->ack_frame().packets.Contains(
-            QuicPacketNumber((i - j) * 2)));
-      }
-    }
-  }
-}
-
-TEST_F(UberReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-  RecordPacketReceipt(1, QuicTime::Zero());
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-  EXPECT_EQ(1u, manager_->ack_frame().received_packet_times.size());
-  RecordPacketReceipt(2,
-                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
-  RecordPacketReceipt(3, QuicTime::Zero());
-  EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
-}
-
-TEST_F(UberReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(3, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 3);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 2);
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 1);
-  // Should ack immediately, since this fills the last hole.
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(4, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 4);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-}
-
-TEST_F(UberReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 2);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 1);
-  EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckReceiptCausesAckSend) {
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(1, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 1);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(2, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 2);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(3, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 3);
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-  clock_.AdvanceTime(kDelayedAckTime);
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  RecordPacketReceipt(4, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 4);
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(5, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(!kInstigateAck, 5);
-  EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckSentEveryNthPacket) {
-  EXPECT_FALSE(HasPendingAck());
-  manager_->set_ack_frequency(3);
-
-  // Receives packets 1 - 39.
-  for (size_t i = 1; i <= 39; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 3 == 0) {
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckDecimationReducesAcks) {
-  EXPECT_FALSE(HasPendingAck());
-
-  // Start ack decimation from 10th packet.
-  manager_->set_min_received_before_ack_decimation(10);
-
-  // Receives packets 1 - 29.
-  for (size_t i = 1; i <= 29; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i <= 10) {
-      // For packets 1-10, ack every 2 packets.
-      if (i % 2 == 0) {
-        CheckAckTimeout(clock_.ApproximateNow());
-      } else {
-        CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-      }
-      continue;
-    }
-    // ack at 20.
-    if (i == 20) {
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
-    }
-  }
-
-  // We now receive the 30th packet, and so we send an ack.
-  RecordPacketReceipt(30, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, 30);
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimation) {
-  EXPECT_FALSE(HasPendingAck());
-  // The ack time should be based on min_rtt * 1/4, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
-  // Process all the packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // The 10th received packet causes an ack to be sent.
-  for (uint64_t i = 1; i < 10; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(UberReceivedPacketManagerTest,
-       SendDelayedAckDecimationUnlimitedAggregation) {
-  EXPECT_FALSE(HasPendingAck());
-  QuicConfig config;
-  QuicTagVector connection_options;
-  // No limit on the number of packets received before sending an ack.
-  connection_options.push_back(kAKDU);
-  config.SetConnectionOptionsToSend(connection_options);
-  manager_->SetFromConfig(config, Perspective::IS_CLIENT);
-
-  // The ack time should be based on min_rtt/4, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
-
-  // Process all the initial packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // 18 packets will not cause an ack to be sent.  19 will because when
-  // stop waiting frames are in use, we ack every 20 packets no matter what.
-  for (int i = 1; i <= 18; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(ack_time);
-}
-
-TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
-  EXPECT_FALSE(HasPendingAck());
-  UberReceivedPacketManagerPeer::SetAckDecimationDelay(manager_.get(), 0.125);
-
-  // The ack time should be based on min_rtt/8, since it's less than the
-  // default delayed ack time.
-  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
-
-  // Process all the packets in order so there aren't missing packets.
-  uint64_t kFirstDecimatedPacket = 101;
-  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
-    RecordPacketReceipt(i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, i);
-    if (i % 2 == 0) {
-      // Ack every 2 packets by default.
-      CheckAckTimeout(clock_.ApproximateNow());
-    } else {
-      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-    }
-  }
-
-  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
-  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
-  CheckAckTimeout(ack_time);
-
-  // The 10th received packet causes an ack to be sent.
-  for (uint64_t i = 1; i < 10; ++i) {
-    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
-    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
-  }
-  CheckAckTimeout(clock_.ApproximateNow());
-}
-
-TEST_F(UberReceivedPacketManagerTest,
-       DontWaitForPacketsBeforeMultiplePacketNumberSpaces) {
-  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_CLIENT);
-  EXPECT_FALSE(
-      manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE).IsInitialized());
-  EXPECT_FALSE(
-      manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE).IsInitialized());
-  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 2);
-  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 4);
-  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
-  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 7);
-  EXPECT_EQ(QuicPacketNumber(4),
-            manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE));
-  EXPECT_EQ(QuicPacketNumber(7),
-            manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE));
-
-  EXPECT_TRUE(
-      manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
-  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                          QuicPacketNumber(3)));
-  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                         QuicPacketNumber(4)));
-
-  manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
-                                     QuicPacketNumber(5));
-  EXPECT_TRUE(
-      manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
-  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
-                                          QuicPacketNumber(4)));
-}
-
-TEST_F(UberReceivedPacketManagerTest, AckSendingDifferentPacketNumberSpaces) {
-  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
-  EXPECT_FALSE(HasPendingAck());
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-
-  RecordPacketReceipt(ENCRYPTION_INITIAL, 3);
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 3);
-  EXPECT_TRUE(HasPendingAck());
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() +
-                  QuicTime::Delta::FromMilliseconds(25));
-  // Send delayed handshake data ACK.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(25));
-  CheckAckTimeout(clock_.ApproximateNow());
-  EXPECT_FALSE(HasPendingAck());
-
-  // Second delayed ack should have a shorter delay.
-  RecordPacketReceipt(ENCRYPTION_INITIAL, 4);
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 4);
-  EXPECT_TRUE(HasPendingAck());
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() +
-                  QuicTime::Delta::FromMilliseconds(1));
-  // Send delayed handshake data ACK.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  CheckAckTimeout(clock_.ApproximateNow());
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 3);
-  EXPECT_TRUE(manager_->IsAckFrameUpdated());
-  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 3);
-  EXPECT_TRUE(HasPendingAck());
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() +
-                  QuicTime::Delta::FromMilliseconds(1));
-  // Send delayed handshake data ACK.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  CheckAckTimeout(clock_.ApproximateNow());
-  EXPECT_FALSE(HasPendingAck());
-
-  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
-  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 3);
-  EXPECT_TRUE(HasPendingAck());
-  // Delayed ack is scheduled.
-  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
-
-  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 2);
-  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 2);
-  // Application data ACK should be sent immediately.
-  CheckAckTimeout(clock_.ApproximateNow());
-  EXPECT_FALSE(HasPendingAck());
-}
-
-TEST_F(UberReceivedPacketManagerTest,
-       AckTimeoutForPreviouslyUndecryptablePackets) {
-  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
-  EXPECT_FALSE(HasPendingAck());
-  EXPECT_FALSE(manager_->IsAckFrameUpdated());
-
-  // Received undecryptable 1-RTT packet 4.
-  const QuicTime packet_receipt_time4 = clock_.ApproximateNow();
-  // 1-RTT keys become available after 10ms because HANDSHAKE 5 gets received.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 5);
-  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 5);
-  EXPECT_TRUE(HasPendingAck());
-  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 4);
-  manager_->MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE,
-                                  QuicPacketNumber(4), packet_receipt_time4,
-                                  clock_.ApproximateNow(), &rtt_stats_);
-
-  // Send delayed handshake ACK.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  CheckAckTimeout(clock_.ApproximateNow());
-
-  EXPECT_TRUE(HasPendingAck());
-  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
-    // Verify ACK delay is based on packet receipt time.
-    CheckAckTimeout(clock_.ApproximateNow() -
-                    QuicTime::Delta::FromMilliseconds(11) + kDelayedAckTime);
-  } else {
-    // Delayed ack is scheduled.
-    CheckAckTimeout(clock_.ApproximateNow() -
-                    QuicTime::Delta::FromMilliseconds(1) + kDelayedAckTime);
-  }
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/core/web_transport_interface.h b/quic/core/web_transport_interface.h
deleted file mode 100644
index 6f2941e..0000000
--- a/quic/core/web_transport_interface.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This header contains interfaces that abstract away different backing
-// protocols for WebTransport.
-
-#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
-#define QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_datagram_queue.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// Visitor that gets notified about events related to a WebTransport stream.
-class QUIC_EXPORT_PRIVATE WebTransportStreamVisitor {
- public:
-  virtual ~WebTransportStreamVisitor() {}
-
-  // Called whenever the stream has readable data available.
-  virtual void OnCanRead() = 0;
-  // Called whenever the stream is not write-blocked and can accept new data.
-  virtual void OnCanWrite() = 0;
-
-  // Called when RESET_STREAM is received for the stream.
-  virtual void OnResetStreamReceived(WebTransportStreamError error) = 0;
-  // Called when STOP_SENDING is received for the stream.
-  virtual void OnStopSendingReceived(WebTransportStreamError error) = 0;
-  // Called when the write side of the stream is closed and all of the data sent
-  // has been acknowledged ("Data Recvd" state of RFC 9000).
-  virtual void OnWriteSideInDataRecvdState() = 0;
-};
-
-// A stream (either bidirectional or unidirectional) that is contained within a
-// WebTransport session.
-class QUIC_EXPORT_PRIVATE WebTransportStream {
- public:
-  struct QUIC_EXPORT_PRIVATE ReadResult {
-    // Number of bytes actually read.
-    size_t bytes_read;
-    // Whether the FIN has been received; if true, no further data will arrive
-    // on the stream, and the stream object can be soon potentially garbage
-    // collected.
-    bool fin;
-  };
-
-  virtual ~WebTransportStream() {}
-
-  // Reads at most |buffer_size| bytes into |buffer|.
-  ABSL_MUST_USE_RESULT virtual ReadResult Read(char* buffer,
-                                               size_t buffer_size) = 0;
-  // Reads all available data and appends it to the end of |output|.
-  ABSL_MUST_USE_RESULT virtual ReadResult Read(std::string* output) = 0;
-  // Writes |data| into the stream.  Returns true on success.
-  ABSL_MUST_USE_RESULT virtual bool Write(absl::string_view data) = 0;
-  // Sends the FIN on the stream.  Returns true on success.
-  ABSL_MUST_USE_RESULT virtual bool SendFin() = 0;
-
-  // Indicates whether it is possible to write into stream right now.
-  virtual bool CanWrite() const = 0;
-  // Indicates the number of bytes that can be read from the stream.
-  virtual size_t ReadableBytes() const = 0;
-
-  // An ID that is unique within the session.  Those are not exposed to the user
-  // via the web API, but can be used internally for bookkeeping and
-  // diagnostics.
-  virtual QuicStreamId GetStreamId() const = 0;
-
-  // Resets the stream with the specified error code.
-  virtual void ResetWithUserCode(WebTransportStreamError error) = 0;
-  virtual void ResetDueToInternalError() = 0;
-  virtual void SendStopSending(WebTransportStreamError error) = 0;
-  // Called when the owning object has been garbage-collected.
-  virtual void MaybeResetDueToStreamObjectGone() = 0;
-
-  virtual WebTransportStreamVisitor* visitor() = 0;
-  virtual void SetVisitor(
-      std::unique_ptr<WebTransportStreamVisitor> visitor) = 0;
-};
-
-// Visitor that gets notified about events related to a WebTransport session.
-class QUIC_EXPORT_PRIVATE WebTransportVisitor {
- public:
-  virtual ~WebTransportVisitor() {}
-
-  // Notifies the visitor when the session is ready to exchange application
-  // data.
-  virtual void OnSessionReady(const spdy::SpdyHeaderBlock& headers) = 0;
-
-  // Notifies the visitor when the session has been closed.
-  virtual void OnSessionClosed(WebTransportSessionError error_code,
-                               const std::string& error_message) = 0;
-
-  // Notifies the visitor when a new stream has been received.  The stream in
-  // question can be retrieved using AcceptIncomingBidirectionalStream() or
-  // AcceptIncomingUnidirectionalStream().
-  virtual void OnIncomingBidirectionalStreamAvailable() = 0;
-  virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
-
-  // Notifies the visitor when a new datagram has been received.
-  virtual void OnDatagramReceived(absl::string_view datagram) = 0;
-
-  // Notifies the visitor that a new outgoing stream can now be created.
-  virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
-  virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
-};
-
-// An abstract interface for a WebTransport session.
-class QUIC_EXPORT_PRIVATE WebTransportSession {
- public:
-  virtual ~WebTransportSession() {}
-
-  // Closes the WebTransport session in question with the specified |error_code|
-  // and |error_message|.
-  virtual void CloseSession(WebTransportSessionError error_code,
-                            absl::string_view error_message) = 0;
-
-  // Return the earliest incoming stream that has been received by the session
-  // but has not been accepted.  Returns nullptr if there are no incoming
-  // streams.
-  virtual WebTransportStream* AcceptIncomingBidirectionalStream() = 0;
-  virtual WebTransportStream* AcceptIncomingUnidirectionalStream() = 0;
-
-  // Returns true if flow control allows opening a new stream.
-  virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
-  virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
-  // Opens a new WebTransport stream, or returns nullptr if that is not possible
-  // due to flow control.
-  virtual WebTransportStream* OpenOutgoingBidirectionalStream() = 0;
-  virtual WebTransportStream* OpenOutgoingUnidirectionalStream() = 0;
-
-  virtual MessageStatus SendOrQueueDatagram(
-      quiche::QuicheMemSlice datagram) = 0;
-  // Returns a conservative estimate of the largest datagram size that the
-  // session would be able to send.
-  virtual QuicByteCount GetMaxDatagramSize() const = 0;
-  // Sets the largest duration that a datagram can spend in the queue before
-  // being silently dropped.
-  virtual void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
diff --git a/quic/load_balancer/load_balancer_config.cc b/quic/load_balancer/load_balancer_config.cc
deleted file mode 100644
index a22bf3f..0000000
--- a/quic/load_balancer/load_balancer_config.cc
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_config.h"
-
-#include <memory>
-#include <string_view>
-
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-
-// Validates all non-key parts of the input.
-bool CommonValidation(const uint8_t config_id, const uint8_t server_id_len,
-                      const uint8_t nonce_len) {
-  if (config_id > 2 || server_id_len == 0 ||
-      nonce_len < kLoadBalancerMinNonceLen ||
-      nonce_len > kLoadBalancerMaxNonceLen ||
-      server_id_len >
-          (kQuicMaxConnectionIdWithLengthPrefixLength - nonce_len - 1)) {
-    QUIC_BUG(quic_bug_433862549_01)
-        << "Invalid LoadBalancerConfig "
-        << "Config ID " << static_cast<int>(config_id) << " Server ID Length "
-        << static_cast<int>(server_id_len) << " Nonce Length "
-        << static_cast<int>(nonce_len);
-    return false;
-  }
-  return true;
-}
-
-// Initialize the key in the constructor
-absl::optional<AES_KEY> BuildKey(absl::string_view key, bool encrypt) {
-  if (key.empty()) {
-    return absl::optional<AES_KEY>();
-  }
-  AES_KEY raw_key;
-  if (encrypt) {
-    if (AES_set_encrypt_key(reinterpret_cast<const uint8_t *>(key.data()),
-                            key.size() * 8, &raw_key) < 0) {
-      return absl::optional<AES_KEY>();
-    }
-  } else if (AES_set_decrypt_key(reinterpret_cast<const uint8_t *>(key.data()),
-                                 key.size() * 8, &raw_key) < 0) {
-    return absl::optional<AES_KEY>();
-  }
-  return raw_key;
-}
-
-// Functions to handle 4-pass encryption/decryption.
-// TakePlaintextFrom{Left,Right}() reads the left or right half of 'from' and
-// expands it into a full encryption block ('to') in accordance with the
-// internet-draft.
-void TakePlaintextFromLeft(uint8_t *to, uint8_t *from, uint8_t total_len,
-                           uint8_t index) {
-  uint8_t half = total_len / 2;
-  memset(to, 0, kLoadBalancerBlockSize - 1);
-  memcpy(to, from, half);
-  if (total_len % 2) {
-    to[half] = from[half] & 0xf0;
-  }
-  to[kLoadBalancerBlockSize - 1] = index;
-}
-
-void TakePlaintextFromRight(uint8_t *to, uint8_t *from, uint8_t total_len,
-                            uint8_t index) {
-  const uint8_t half = total_len / 2;
-  const uint8_t write_point = kLoadBalancerBlockSize - half;
-  const uint8_t read_point = total_len - half;
-  memset((to + 1), 0, kLoadBalancerBlockSize - 1);
-  memcpy(to + write_point, from + read_point, half);
-  if (total_len % 2) {
-    to[write_point - 1] = from[read_point - 1] & 0x0f;
-  }
-  to[0] = index;
-}
-
-// CiphertextXorWith{Left,Right}() takes the relevant end of the ciphertext in
-// 'from' and XORs it with half of the ConnectionId stored at 'to', in
-// accordance with the internet-draft.
-void CiphertextXorWithLeft(uint8_t *to, uint8_t *from, uint8_t total_len) {
-  uint8_t half = total_len / 2;
-  for (int i = 0; i < half; i++) {
-    *(to + i) ^= *(from + i);
-  }
-  if (total_len % 2) {
-    *(to + half) ^= (*(from + half) & 0xf0);
-  }
-}
-
-void CiphertextXorWithRight(uint8_t *to, uint8_t *from, uint8_t total_len) {
-  const uint8_t half = total_len / 2;
-  const uint8_t write_point = total_len - half;
-  const uint8_t read_point = kLoadBalancerBlockSize - half;
-  if (total_len % 2) {
-    *(to + write_point - 1) ^= (*(from + read_point - 1) & 0x0f);
-  }
-  for (int i = 0; i < half; i++) {
-    *(to + write_point + i) ^= *(from + read_point + i);
-  }
-}
-
-}  // namespace
-
-absl::optional<LoadBalancerConfig> LoadBalancerConfig::Create(
-    const uint8_t config_id, const uint8_t server_id_len,
-    const uint8_t nonce_len, const absl::string_view key) {
-  //  Check for valid parameters.
-  if (key.size() != kLoadBalancerKeyLen) {
-    QUIC_BUG(quic_bug_433862549_02)
-        << "Invalid LoadBalancerConfig Key Length: " << key.size();
-    return absl::optional<LoadBalancerConfig>();
-  }
-  if (!CommonValidation(config_id, server_id_len, nonce_len)) {
-    return absl::optional<LoadBalancerConfig>();
-  }
-  auto new_config =
-      LoadBalancerConfig(config_id, server_id_len, nonce_len, key);
-  if (!new_config.IsEncrypted()) {
-    // Something went wrong in assigning the key!
-    QUIC_BUG(quic_bug_433862549_03) << "Something went wrong in initializing "
-                                       "the load balancing key.";
-    return absl::optional<LoadBalancerConfig>();
-  }
-  return new_config;
-}
-
-// Creates an unencrypted config.
-absl::optional<LoadBalancerConfig> LoadBalancerConfig::CreateUnencrypted(
-    const uint8_t config_id, const uint8_t server_id_len,
-    const uint8_t nonce_len) {
-  return CommonValidation(config_id, server_id_len, nonce_len)
-             ? LoadBalancerConfig(config_id, server_id_len, nonce_len, "")
-             : absl::optional<LoadBalancerConfig>();
-}
-
-bool LoadBalancerConfig::EncryptionPass(uint8_t *target,
-                                        const uint8_t index) const {
-  uint8_t plaintext[kLoadBalancerBlockSize], ciphertext[kLoadBalancerBlockSize];
-  if (!key_.has_value() || target == nullptr) {
-    return false;
-  }
-  if (index % 2) {  // Odd indices go from left to right
-    TakePlaintextFromLeft(plaintext, target, total_len(), index);
-  } else {
-    TakePlaintextFromRight(plaintext, target, total_len(), index);
-  }
-  if (!BlockEncrypt(plaintext, ciphertext)) {
-    return false;
-  }
-  // XOR bits over the correct half.
-  if (index % 2) {
-    CiphertextXorWithRight(target, ciphertext, total_len());
-  } else {
-    CiphertextXorWithLeft(target, ciphertext, total_len());
-  }
-  return true;
-}
-
-bool LoadBalancerConfig::BlockEncrypt(
-    const uint8_t plaintext[kLoadBalancerBlockSize],
-    uint8_t ciphertext[kLoadBalancerBlockSize]) const {
-  if (!key_.has_value()) {
-    return false;
-  }
-  AES_encrypt(plaintext, ciphertext, &key_.value());
-  return true;
-}
-
-bool LoadBalancerConfig::BlockDecrypt(
-    const uint8_t ciphertext[kLoadBalancerBlockSize],
-    uint8_t plaintext[kLoadBalancerBlockSize]) const {
-  if (!block_decrypt_key_.has_value()) {
-    return false;
-  }
-  AES_decrypt(ciphertext, plaintext, &block_decrypt_key_.value());
-  return true;
-}
-
-LoadBalancerConfig::LoadBalancerConfig(const uint8_t config_id,
-                                       const uint8_t server_id_len,
-                                       const uint8_t nonce_len,
-                                       const absl::string_view key)
-    : config_id_(config_id),
-      server_id_len_(server_id_len),
-      nonce_len_(nonce_len),
-      key_(BuildKey(key, /* encrypt = */ true)),
-      block_decrypt_key_((server_id_len + nonce_len == kLoadBalancerBlockSize)
-                             ? BuildKey(key, /* encrypt = */ false)
-                             : absl::optional<AES_KEY>()) {}
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_config.h b/quic/load_balancer/load_balancer_config.h
deleted file mode 100644
index 8e952ce..0000000
--- a/quic/load_balancer/load_balancer_config.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_LOAD_BALANCER_CONFIG_H_
-#define QUICHE_QUIC_LOAD_BALANCER_CONFIG_H_
-
-#include "third_party/boringssl/src/include/openssl/aes.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-inline constexpr uint8_t kLoadBalancerKeyLen = 16;
-// Regardless of key length, the AES block size is always 16 Bytes.
-inline constexpr uint8_t kLoadBalancerBlockSize = 16;
-// The spec says nonces can be 18 bytes, but 16 lets it be a uint128.
-inline constexpr uint8_t kLoadBalancerMaxNonceLen = 16;
-inline constexpr uint8_t kLoadBalancerMinNonceLen = 4;
-
-// This the base class for QUIC-LB configuration. It contains configuration
-// elements usable by both encoders (servers) and decoders (load balancers).
-// Confusingly, it is called "LoadBalancerConfig" because it pertains to objects
-// that both servers and load balancers use to interact with each other.
-class QUIC_EXPORT_PRIVATE LoadBalancerConfig {
- public:
-  // This factory function initializes an encrypted LoadBalancerConfig and
-  // returns it in absl::optional, which is empty if the config is invalid.
-  // config_id: The first two bits of the Connection Id. Must be no larger than
-  // 2.
-  // server_id_len: Expected length of the server ids associated with this
-  // config. Must be greater than 0 and less than 16.
-  // nonce_len: Length of the nonce. Must be at least 4 and no larger than 16.
-  // Further the server_id_len + nonce_len must be no larger than 19.
-  // key: The encryption key must be 16B long.
-  static absl::optional<LoadBalancerConfig> Create(const uint8_t config_id,
-                                                   const uint8_t server_id_len,
-                                                   const uint8_t nonce_len,
-                                                   const absl::string_view key);
-
-  // Creates an unencrypted config.
-  static absl::optional<LoadBalancerConfig> CreateUnencrypted(
-      const uint8_t config_id, const uint8_t server_id_len,
-      const uint8_t nonce_len);
-
-  // Handles one pass of 4-pass encryption. Encoder and decoder use of this
-  // function varies substantially, so they are not implemented here.
-  // Returns false if the config is not encrypted.
-  ABSL_MUST_USE_RESULT bool EncryptionPass(uint8_t *target,
-                                           const uint8_t index) const;
-  // Use the key to do a block encryption, which is used both in all cases of
-  // encrypted configs. Returns false if there's no key.
-  ABSL_MUST_USE_RESULT bool BlockEncrypt(
-      const uint8_t plaintext[kLoadBalancerBlockSize],
-      uint8_t ciphertext[kLoadBalancerBlockSize]) const;
-  // Returns false if the config does not require block decryption.
-  ABSL_MUST_USE_RESULT bool BlockDecrypt(
-      const uint8_t ciphertext[kLoadBalancerBlockSize],
-      uint8_t plaintext[kLoadBalancerBlockSize]) const;
-
-  uint8_t config_id() const { return config_id_; }
-  uint8_t server_id_len() const { return server_id_len_; }
-  uint8_t nonce_len() const { return nonce_len_; }
-  uint8_t total_len() const { return server_id_len_ + nonce_len_; }
-  bool IsEncrypted() const { return key_.has_value(); }
-
- private:
-  // Constructor is private because it doesn't validate input.
-  LoadBalancerConfig(uint8_t config_id, uint8_t server_id_len,
-                     uint8_t nonce_len, absl::string_view key);
-
-  uint8_t config_id_;
-  uint8_t server_id_len_;
-  uint8_t nonce_len_;
-  // All Connection ID encryption and decryption uses the AES_encrypt function
-  // at root, so there is a single key for all of it. This is empty if the
-  // config is not encrypted.
-  absl::optional<AES_KEY> key_;
-  // The one exception is that when total_len == 16, connection ID decryption
-  // uses AES_decrypt. The bytes that comprise the key are the same, but
-  // AES_decrypt requires an AES_KEY that is initialized differently. In all
-  // other cases, block_decrypt_key_ is empty.
-  absl::optional<AES_KEY> block_decrypt_key_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_LOAD_BALANCER_CONFIG_H
diff --git a/quic/load_balancer/load_balancer_config_test.cc b/quic/load_balancer/load_balancer_config_test.cc
deleted file mode 100644
index 2b73c76..0000000
--- a/quic/load_balancer/load_balancer_config_test.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_config.h"
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-constexpr char raw_key[] = {
-    0xfd, 0xf7, 0x26, 0xa9, 0x89, 0x3e, 0xc0, 0x5c,
-    0x06, 0x32, 0xd3, 0x95, 0x66, 0x80, 0xba, 0xf0,
-};
-
-class LoadBalancerConfigTest : public QuicTest {};
-
-TEST_F(LoadBalancerConfigTest, InvalidParams) {
-  // Bogus config_id.
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(3, 4, 10).has_value()),
-      "Invalid LoadBalancerConfig Config ID 3 Server ID Length 4 "
-      "Nonce Length 10");
-  // Bad Server ID lengths.
-  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
-                                   2, 0, 10, absl::string_view(raw_key, 16))
-                                   .has_value()),
-                  "Invalid LoadBalancerConfig Config ID 2 Server ID Length 0 "
-                  "Nonce Length 10");
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 16, 4).has_value()),
-      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 16 "
-      "Nonce Length 4");
-  // Bad Nonce lengths.
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 4, 2).has_value()),
-      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 4 "
-      "Nonce Length 2");
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 1, 17).has_value()),
-      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 1 "
-      "Nonce Length 17");
-  // Bad key lengths.
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(LoadBalancerConfig::Create(2, 3, 4, "").has_value()),
-      "Invalid LoadBalancerConfig Key Length: 0");
-  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
-                                   2, 3, 4, absl::string_view(raw_key, 10))
-                                   .has_value()),
-                  "Invalid LoadBalancerConfig Key Length: 10");
-  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
-                                   0, 3, 4, absl::string_view(raw_key, 17))
-                                   .has_value()),
-                  "Invalid LoadBalancerConfig Key Length: 17");
-}
-
-TEST_F(LoadBalancerConfigTest, ValidParams) {
-  // Test valid configurations and accessors
-  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  EXPECT_EQ(config->config_id(), 0);
-  EXPECT_EQ(config->server_id_len(), 3);
-  EXPECT_EQ(config->nonce_len(), 4);
-  EXPECT_EQ(config->total_len(), 7);
-  EXPECT_FALSE(config->IsEncrypted());
-  auto config2 =
-      LoadBalancerConfig::Create(2, 6, 7, absl::string_view(raw_key, 16));
-  EXPECT_TRUE(config.has_value());
-  EXPECT_EQ(config2->config_id(), 2);
-  EXPECT_EQ(config2->server_id_len(), 6);
-  EXPECT_EQ(config2->nonce_len(), 7);
-  EXPECT_EQ(config2->total_len(), 13);
-  EXPECT_TRUE(config2->IsEncrypted());
-}
-
-// Compare EncryptionPass() results to the example in
-// draft-ietf-quic-load-balancers-12, Section 5.3.2.
-TEST_F(LoadBalancerConfigTest, TestEncryptionPassExample) {
-  auto config =
-      LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
-  EXPECT_TRUE(config.has_value());
-  EXPECT_TRUE(config->IsEncrypted());
-  std::array<uint8_t, 7> bytes = {
-      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
-  };
-  EXPECT_FALSE(config->EncryptionPass(nullptr, 0));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 1));
-  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
-                            {0x31, 0x44, 0x1a, 0x9d, 0xbc, 0x04, 0x26})));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 2));
-  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
-                            {0x4f, 0xdd, 0x0c, 0x9d, 0xbc, 0x04, 0x26})));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 3));
-  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
-                            {0x4f, 0xdd, 0x0c, 0x9b, 0xba, 0x1e, 0xe0})));
-  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 4));
-  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
-                            {0xe2, 0x3c, 0xb4, 0x2b, 0xba, 0x1e, 0xe0})));
-}
-
-TEST_F(LoadBalancerConfigTest, EncryptionPassPlaintext) {
-  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  std::array<uint8_t, 7> bytes = {
-      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
-  };
-  EXPECT_FALSE(config->EncryptionPass(bytes.data(), 1));
-}
-
-TEST_F(LoadBalancerConfigTest, InvalidBlockEncryption) {
-  uint8_t pt[kLoadBalancerBlockSize], ct[kLoadBalancerBlockSize];
-  auto pt_config = LoadBalancerConfig::CreateUnencrypted(0, 8, 8);
-  EXPECT_FALSE(pt_config->BlockEncrypt(pt, ct));
-  EXPECT_FALSE(pt_config->BlockDecrypt(ct, pt));
-  EXPECT_FALSE(pt_config->EncryptionPass(pt, 0));
-  auto small_cid_config =
-      LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
-  EXPECT_TRUE(small_cid_config->BlockEncrypt(pt, ct));
-  EXPECT_FALSE(small_cid_config->BlockDecrypt(ct, pt));
-  auto block_config =
-      LoadBalancerConfig::Create(0, 8, 8, absl::string_view(raw_key, 16));
-  EXPECT_TRUE(block_config->BlockEncrypt(pt, ct));
-  EXPECT_TRUE(block_config->BlockDecrypt(ct, pt));
-}
-
-// Block decrypt test from the Test Vector in
-// draft-ietf-quic-load-balancers-12, Appendix B.
-TEST_F(LoadBalancerConfigTest, BlockEncryptionExample) {
-  const uint8_t ptext[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
-                           0xee, 0x08, 0x0d, 0xbf, 0x48, 0xc0, 0xd1, 0xe5};
-  const uint8_t ctext[] = {0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2,
-                           0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3};
-  const char key[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
-                      0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
-  uint8_t result[sizeof(ptext)];
-  auto config = LoadBalancerConfig::Create(0, 8, 8, absl::string_view(key, 16));
-  EXPECT_TRUE(config->BlockEncrypt(ptext, result));
-  EXPECT_EQ(memcmp(result, ctext, sizeof(ctext)), 0);
-  EXPECT_TRUE(config->BlockDecrypt(ctext, result));
-  EXPECT_EQ(memcmp(result, ptext, sizeof(ptext)), 0);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_decoder.cc b/quic/load_balancer/load_balancer_decoder.cc
deleted file mode 100644
index 6d7264f..0000000
--- a/quic/load_balancer/load_balancer_decoder.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_decoder.h"
-
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-bool LoadBalancerDecoder::AddConfig(const LoadBalancerConfig& config) {
-  if (config_[config.config_id()].has_value()) {
-    return false;
-  }
-  config_[config.config_id()] = config;
-  return true;
-}
-
-void LoadBalancerDecoder::DeleteConfig(uint8_t config_id) {
-  if (config_id > 2) {
-    QUIC_BUG(quic_bug_438896865_01)
-        << "Decoder deleting config with invalid config_id "
-        << static_cast<int>(config_id);
-    return;
-  }
-  config_[config_id].reset();
-}
-
-// This is the core logic to extract a server ID given a valid config and
-// connection ID of sufficient length.
-absl::optional<LoadBalancerServerId> LoadBalancerDecoder::GetServerId(
-    const QuicConnectionId& connection_id) const {
-  absl::optional<uint8_t> config_id = GetConfigId(connection_id);
-  if (!config_id.has_value()) {
-    return absl::optional<LoadBalancerServerId>();
-  }
-  absl::optional<LoadBalancerConfig> config = config_[*config_id];
-  if (!config.has_value()) {
-    return absl::optional<LoadBalancerServerId>();
-  }
-  if (connection_id.length() < (1 + config->total_len())) {
-    // Connection ID wasn't long enough
-    return absl::optional<LoadBalancerServerId>();
-  }
-  // The first byte is complete. Finish the rest.
-  const uint8_t* data =
-      reinterpret_cast<const uint8_t*>(connection_id.data()) + 1;
-  if (!config->IsEncrypted()) {  // It's a Plaintext CID.
-    return LoadBalancerServerId::Create(
-        absl::Span<const uint8_t>(data, config->server_id_len()));
-  }
-  uint8_t result[kQuicMaxConnectionIdWithLengthPrefixLength];
-  if (config->total_len() == kLoadBalancerKeyLen) {  // single pass
-    if (!config->BlockDecrypt(data, result)) {
-      return absl::optional<LoadBalancerServerId>();
-    }
-  } else {
-    // Do 3 or 4 passes. Only 3 are necessary if the server_id is short enough
-    // to fit in the first half of the connection ID (the decoder doesn't need
-    // to extract the nonce).
-    memcpy(result, data, config->total_len());
-    uint8_t end = (config->server_id_len() > config->nonce_len()) ? 1 : 2;
-    for (uint8_t i = 4; i >= end; i--) {
-      if (!config->EncryptionPass(result, i)) {
-        return absl::optional<LoadBalancerServerId>();
-      }
-    }
-  }
-  return LoadBalancerServerId::Create(
-      absl::Span<const uint8_t>(result, config->server_id_len()));
-}
-
-absl::optional<uint8_t> LoadBalancerDecoder::GetConfigId(
-    const QuicConnectionId& connection_id) {
-  if (connection_id.IsEmpty()) {
-    return absl::optional<uint8_t>();
-  }
-  const uint8_t first_byte = connection_id.data()[0];
-  uint8_t codepoint = (first_byte >> 6);
-  if (codepoint <= 2) {
-    return codepoint;
-  }
-  return absl::optional<uint8_t>();
-}
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_decoder.h b/quic/load_balancer/load_balancer_decoder.h
deleted file mode 100644
index a2708fe..0000000
--- a/quic/load_balancer/load_balancer_decoder.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
-#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
-
-#include "quic/load_balancer/load_balancer_config.h"
-#include "quic/load_balancer/load_balancer_server_id.h"
-
-namespace quic {
-
-// Manages QUIC-LB configurations to extract a server ID from a properly
-// encoded connection ID, usually on behalf of a load balancer.
-class QUIC_EXPORT_PRIVATE LoadBalancerDecoder {
- public:
-  // Returns false if the config_id codepoint is already occupied.
-  bool AddConfig(const LoadBalancerConfig& config);
-
-  // Remove support for a config
-  void DeleteConfig(const uint8_t config_id);
-
-  // For these "Get" functions, the calling code might not know the length of
-  // the connection ID. That's OK; if not, just send at least
-  // kQuicMaxConnectionIdWithLengthPrefixLength bytes in a QuicConnectionId.
-
-  // Extract a server ID from a connection ID. If there is no config for the
-  // codepoint, the connection ID is too short, or there's a decrypt error,
-  // returns empty.
-  absl::optional<LoadBalancerServerId> GetServerId(
-      const QuicConnectionId& connection_id) const;
-
-  // Returns the config ID stored in the first two bits of |connection_id|, or
-  // empty if |connection_id| is empty.
-  static absl::optional<uint8_t> GetConfigId(
-      const QuicConnectionId& connection_id);
-
- private:
-  // Decoders can support up to 3 configs at once.
-  absl::optional<LoadBalancerConfig> config_[3];
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
diff --git a/quic/load_balancer/load_balancer_decoder_test.cc b/quic/load_balancer/load_balancer_decoder_test.cc
deleted file mode 100644
index eaeef42..0000000
--- a/quic/load_balancer/load_balancer_decoder_test.cc
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_decoder.h"
-
-#include "absl/base/macros.h"
-#include "quic/load_balancer/load_balancer_server_id.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-class LoadBalancerDecoderTest : public QuicTest {};
-
-// Convenience function to shorten the code. Does not check if |array| is long
-// enough or |length| is valid for a server ID.
-inline LoadBalancerServerId MakeServerId(const uint8_t array[],
-                                         const uint8_t length) {
-  return *LoadBalancerServerId::Create(
-      absl::Span<const uint8_t>(array, length));
-}
-
-constexpr char kRawKey[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
-                            0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
-constexpr absl::string_view kKey(kRawKey, kLoadBalancerKeyLen);
-constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
-                                 0xab, 0x65, 0xba, 0x04, 0xc3, 0x33, 0x0a};
-
-struct LoadBalancerDecoderTestCase {
-  LoadBalancerConfig config;
-  QuicConnectionId connection_id;
-  LoadBalancerServerId server_id;
-};
-
-TEST_F(LoadBalancerDecoderTest, UnencryptedConnectionIdTestVectors) {
-  const struct LoadBalancerDecoderTestCase test_vectors[2] = {
-      {
-          *LoadBalancerConfig::CreateUnencrypted(0, 3, 4),
-          QuicConnectionId({0x07, 0xed, 0x79, 0x3a, 0x80, 0x49, 0x71, 0x8a}),
-          MakeServerId(kServerId, 3),
-      },
-      {
-          *LoadBalancerConfig::CreateUnencrypted(1, 8, 5),
-          QuicConnectionId({0x4d, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f,
-                            0x5f, 0xee, 0x15, 0xda, 0x27, 0xc4}),
-          MakeServerId(kServerId, 8),
-      }};
-  for (uint8_t i = 0; i < ABSL_ARRAYSIZE(test_vectors); i++) {
-    LoadBalancerDecoder decoder;
-    EXPECT_TRUE(decoder.AddConfig(test_vectors[i].config));
-    EXPECT_EQ(decoder.GetServerId(test_vectors[i].connection_id),
-              test_vectors[i].server_id);
-  }
-}
-
-// Compare test vectors from Appendix B of draft-ietf-quic-load-balancers-12.
-TEST_F(LoadBalancerDecoderTest, DecoderTestVectors) {
-  // Try (1) the "standard" CID length of 8
-  // (2) server_id_len > nonce_len, so there is a fourth decryption pass
-  // (3) the single-pass encryption case
-  // (4) An even total length.
-  const struct LoadBalancerDecoderTestCase test_vectors[4] = {
-      {
-          *LoadBalancerConfig::Create(0, 3, 4, kKey),
-          QuicConnectionId({0x07, 0xfb, 0xfe, 0x05, 0xf7, 0x31, 0xb4, 0x25}),
-          MakeServerId(kServerId, 3),
-      },
-      {
-          *LoadBalancerConfig::Create(1, 10, 5, kKey),
-          QuicConnectionId({0x4f, 0x01, 0x09, 0x56, 0xfb, 0x5c, 0x1d, 0x4d,
-                            0x86, 0xe0, 0x10, 0x18, 0x3e, 0x0b, 0x7d, 0x1e}),
-          MakeServerId(kServerId, 10),
-      },
-      {
-          *LoadBalancerConfig::Create(2, 8, 8, kKey),
-          QuicConnectionId({0x90, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9,
-                            0xb2, 0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c,
-                            0xc3}),
-          MakeServerId(kServerId, 8),
-      },
-      {
-          *LoadBalancerConfig::Create(0, 9, 9, kKey),
-          QuicConnectionId({0x12, 0x7a, 0x28, 0x5a, 0x09, 0xf8, 0x52, 0x80,
-                            0xf4, 0xfd, 0x6a, 0xbb, 0x43, 0x4a, 0x71, 0x59,
-                            0xe4, 0xd3, 0xeb}),
-          MakeServerId(kServerId, 9),
-      },
-  };
-
-  for (uint8_t i = 0; i < ABSL_ARRAYSIZE(test_vectors); i++) {
-    LoadBalancerDecoder decoder;
-    EXPECT_TRUE(decoder.AddConfig(test_vectors[i].config));
-    EXPECT_EQ(decoder.GetServerId(test_vectors[i].connection_id),
-              test_vectors[i].server_id);
-  }
-}
-
-TEST_F(LoadBalancerDecoderTest, NoServerIdEntry) {
-  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  EXPECT_TRUE(server_id.has_value());
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
-  QuicConnectionId no_server_id_entry(
-      {0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08});
-  EXPECT_TRUE(decoder.GetServerId(no_server_id_entry).has_value());
-}
-
-TEST_F(LoadBalancerDecoderTest, InvalidConfigId) {
-  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  EXPECT_TRUE(server_id.has_value());
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
-  QuicConnectionId wrong_config_id(
-      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07});
-  EXPECT_FALSE(decoder
-                   .GetServerId(QuicConnectionId(
-                       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
-                   .has_value());
-}
-
-TEST_F(LoadBalancerDecoderTest, UnroutableCodepoint) {
-  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  EXPECT_TRUE(server_id.has_value());
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
-  EXPECT_FALSE(decoder
-                   .GetServerId(QuicConnectionId(
-                       {0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
-                   .has_value());
-}
-
-TEST_F(LoadBalancerDecoderTest, UnroutableCodepointAnyLength) {
-  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  EXPECT_TRUE(server_id.has_value());
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
-  EXPECT_FALSE(decoder.GetServerId(QuicConnectionId({0xff})).has_value());
-}
-
-TEST_F(LoadBalancerDecoderTest, ConnectionIdTooShort) {
-  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  EXPECT_TRUE(server_id.has_value());
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
-  EXPECT_FALSE(decoder
-                   .GetServerId(QuicConnectionId(
-                       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}))
-                   .has_value());
-}
-
-TEST_F(LoadBalancerDecoderTest, ConnectionIdTooLongIsOK) {
-  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
-  auto server_id_result = decoder.GetServerId(
-      QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}));
-  EXPECT_TRUE(server_id_result.has_value());
-  EXPECT_EQ(server_id_result, server_id);
-}
-
-TEST_F(LoadBalancerDecoderTest, DeleteConfigBadId) {
-  LoadBalancerDecoder decoder;
-  decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
-  decoder.DeleteConfig(0);
-  EXPECT_QUIC_BUG(decoder.DeleteConfig(3),
-                  "Decoder deleting config with invalid config_id 3");
-  EXPECT_TRUE(decoder
-                  .GetServerId(QuicConnectionId(
-                      {0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
-                  .has_value());
-}
-
-TEST_F(LoadBalancerDecoderTest, DeleteConfigGoodId) {
-  LoadBalancerDecoder decoder;
-  decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
-  decoder.DeleteConfig(2);
-  EXPECT_FALSE(decoder
-                   .GetServerId(QuicConnectionId(
-                       {0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
-                   .has_value());
-}
-
-// Create two server IDs and make sure the decoder decodes the correct one.
-TEST_F(LoadBalancerDecoderTest, TwoServerIds) {
-  auto server_id1 = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
-  EXPECT_TRUE(server_id1.has_value());
-  auto server_id2 = LoadBalancerServerId::Create({0x04, 0x05, 0x06});
-  LoadBalancerDecoder decoder;
-  EXPECT_TRUE(
-      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
-  EXPECT_EQ(decoder.GetServerId(QuicConnectionId(
-                {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07})),
-            server_id1);
-  EXPECT_EQ(decoder.GetServerId(QuicConnectionId(
-                {0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a})),
-            server_id2);
-}
-
-TEST_F(LoadBalancerDecoderTest, GetConfigId) {
-  EXPECT_FALSE(
-      LoadBalancerDecoder::GetConfigId(QuicConnectionId()).has_value());
-  for (uint8_t i = 0; i < 3; i++) {
-    auto config_id = LoadBalancerDecoder::GetConfigId(
-        QuicConnectionId({static_cast<unsigned char>(i << 6)}));
-    EXPECT_TRUE(config_id.has_value());
-    EXPECT_EQ(*config_id, i);
-  }
-  EXPECT_FALSE(
-      LoadBalancerDecoder::GetConfigId(QuicConnectionId({0xc0})).has_value());
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_encoder.cc b/quic/load_balancer/load_balancer_encoder.cc
deleted file mode 100644
index c5f0d03..0000000
--- a/quic/load_balancer/load_balancer_encoder.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_encoder.h"
-
-#include "absl/numeric/int128.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_packet_number.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/load_balancer/load_balancer_config.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-
-// Returns the number of nonces given a certain |nonce_len|.
-absl::uint128 NumberOfNonces(uint8_t nonce_len) {
-  return (static_cast<absl::uint128>(1) << (nonce_len * 8));
-}
-
-// Writes the |size| least significant bytes from |in| to |out| in host byte
-// order. Returns false if |out| does not have enough space.
-bool WriteUint128(const absl::uint128 in, uint8_t size, QuicDataWriter &out) {
-  if (out.remaining() < size) {
-    QUIC_BUG(quic_bug_435375038_05)
-        << "Call to WriteUint128() does not have enough space in |out|";
-    return false;
-  }
-  uint64_t num64 = absl::Uint128Low64(in);
-  if (size <= sizeof(num64)) {
-    out.WriteBytes(&num64, size);
-  } else {
-    out.WriteBytes(&num64, sizeof(num64));
-    num64 = absl::Uint128High64(in);
-    out.WriteBytes(&num64, size - sizeof(num64));
-  }
-  return true;
-}
-
-}  // namespace
-
-constexpr uint8_t kLoadBalancerLengthMask = 0x3f;
-constexpr uint8_t kLoadBalancerUnroutableConfigId = 0xc0;
-
-absl::optional<LoadBalancerEncoder> LoadBalancerEncoder::Create(
-    QuicRandom &random, LoadBalancerEncoderVisitorInterface *const visitor,
-    const bool len_self_encoded, const uint8_t unroutable_connection_id_len) {
-  if (unroutable_connection_id_len == 0 ||
-      unroutable_connection_id_len >
-          kQuicMaxConnectionIdWithLengthPrefixLength) {
-    QUIC_BUG(quic_bug_435375038_01)
-        << "Invalid unroutable_connection_id_len = "
-        << static_cast<int>(unroutable_connection_id_len);
-    return absl::optional<LoadBalancerEncoder>();
-  }
-  return LoadBalancerEncoder(random, visitor, len_self_encoded,
-                             unroutable_connection_id_len);
-}
-
-bool LoadBalancerEncoder::UpdateConfig(const LoadBalancerConfig &config,
-                                       const LoadBalancerServerId server_id) {
-  if (config_.has_value() && config_->config_id() == config.config_id()) {
-    QUIC_BUG(quic_bug_435375038_02)
-        << "Attempting to change config with same ID";
-    return false;
-  }
-  if (server_id.length() != config.server_id_len()) {
-    QUIC_BUG(quic_bug_435375038_03)
-        << "Server ID length " << static_cast<int>(server_id.length())
-        << " does not match configured value of "
-        << static_cast<int>(config.server_id_len());
-    return false;
-  }
-  if (visitor_ != nullptr) {
-    if (config_.has_value()) {
-      visitor_->OnConfigChanged(config_->config_id(), config.config_id());
-    } else {
-      visitor_->OnConfigAdded(config.config_id());
-    }
-  }
-  config_ = config;
-  server_id_ = server_id;
-
-  seed_ = absl::MakeUint128(random_.RandUint64(), random_.RandUint64()) %
-          NumberOfNonces(config.nonce_len());
-  num_nonces_left_ = NumberOfNonces(config.nonce_len());
-  return true;
-}
-
-void LoadBalancerEncoder::DeleteConfig() {
-  if (visitor_ != nullptr && config_.has_value()) {
-    visitor_->OnConfigDeleted(config_->config_id());
-  }
-  config_.reset();
-  server_id_.reset();
-  num_nonces_left_ = 0;
-}
-
-QuicConnectionId LoadBalancerEncoder::GenerateConnectionId() {
-  uint8_t length = (config_.has_value()) ? (config_->total_len() + 1)
-                                         : unroutable_connection_id_len_;
-  uint8_t config_id = config_.has_value() ? (config_->config_id() << 6)
-                                          : kLoadBalancerUnroutableConfigId;
-  if (config_.has_value() != server_id_.has_value()) {
-    QUIC_BUG(quic_bug_435375038_04)
-        << "Existence of config and server_id are out of sync";
-    return QuicConnectionId();
-  }
-  uint8_t first_byte;
-  // first byte
-  if (len_self_encoded_) {
-    first_byte = config_id | (length - 1);
-  } else {
-    random_.RandBytes(static_cast<void *>(&first_byte), 1);
-    first_byte = config_id | (first_byte & kLoadBalancerLengthMask);
-  }
-  if (config_id == kLoadBalancerUnroutableConfigId) {
-    return MakeUnroutableConnectionId(first_byte);
-  }
-  QuicConnectionId id;
-  id.set_length(length);
-  QuicDataWriter writer(length, id.mutable_data(), quiche::HOST_BYTE_ORDER);
-  writer.WriteUInt8(first_byte);
-  absl::uint128 next_nonce =
-      (seed_ + num_nonces_left_--) % NumberOfNonces(config_->nonce_len());
-  writer.WriteBytes(server_id_->data().data(), server_id_->length());
-  if (!WriteUint128(next_nonce, config_->nonce_len(), writer)) {
-    return QuicConnectionId();
-  }
-  uint8_t *block_start = reinterpret_cast<uint8_t *>(writer.data() + 1);
-  if (!config_->IsEncrypted()) {
-    // Fill the nonce field with a hash of the Connection ID to avoid the nonce
-    // visibly increasing by one. This would allow observers to correlate
-    // connection IDs as being sequential and likely from the same connection,
-    // not just the same server.
-    absl::uint128 nonce_hash =
-        QuicUtils::FNV1a_128_Hash(absl::string_view(writer.data(), length));
-    QuicDataWriter rewriter(config_->nonce_len(),
-                            id.mutable_data() + config_->server_id_len() + 1,
-                            quiche::HOST_BYTE_ORDER);
-    if (!WriteUint128(nonce_hash, config_->nonce_len(), rewriter)) {
-      return QuicConnectionId();
-    }
-  } else if (config_->total_len() == kLoadBalancerBlockSize) {
-    // Use one encryption pass.
-    if (!config_->BlockEncrypt(block_start, block_start)) {
-      QUIC_LOG(ERROR) << "Block encryption failed";
-      return QuicConnectionId();
-    }
-  } else {
-    for (uint8_t i = 1; i <= 4; i++) {
-      if (!config_->EncryptionPass(block_start, i)) {
-        QUIC_LOG(ERROR) << "Block encryption failed";
-        return QuicConnectionId();
-      }
-    }
-  }
-  if (num_nonces_left_ == 0) {
-    DeleteConfig();
-  }
-  return id;
-}
-
-QuicConnectionId LoadBalancerEncoder::MakeUnroutableConnectionId(
-    uint8_t first_byte) {
-  QuicConnectionId id;
-  id.set_length(unroutable_connection_id_len_);
-  id.mutable_data()[0] = first_byte;
-  random_.RandBytes(&id.mutable_data()[1], unroutable_connection_id_len_ - 1);
-  return id;
-}
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_encoder.h b/quic/load_balancer/load_balancer_encoder.h
deleted file mode 100644
index e0b4ab7..0000000
--- a/quic/load_balancer/load_balancer_encoder.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_LOAD_BALANCER_ENCODER_H_
-#define QUICHE_QUIC_LOAD_BALANCER_ENCODER_H_
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/load_balancer/load_balancer_config.h"
-#include "quic/load_balancer/load_balancer_server_id.h"
-
-namespace quic {
-
-namespace test {
-class LoadBalancerEncoderPeer;
-}
-
-// Default length of a 4-tuple connection ID.
-inline constexpr uint8_t kLoadBalancerUnroutableLen = 8;
-
-// Interface which receives notifications when the current config is updated.
-class QUIC_EXPORT_PRIVATE LoadBalancerEncoderVisitorInterface {
- public:
-  virtual ~LoadBalancerEncoderVisitorInterface() {}
-
-  // Called when a config is added where none existed.
-  //
-  // Connections that support address migration should retire unroutable
-  // connection IDs and replace them with routable ones using the new config,
-  // while avoiding sending a sudden storm of packets containing
-  // RETIRE_CONNECTION_ID and NEW_CONNECTION_ID frames.
-  virtual void OnConfigAdded(const uint8_t config_id) = 0;
-  // Called when the config is changed.
-  //
-  // Existing routable connection IDs should be retired before the decoder stops
-  // supporting that config. The timing of this event is deployment-dependent
-  // and might be tied to the arrival of a new config at the encoder.
-  virtual void OnConfigChanged(const uint8_t old_config_id,
-                               const uint8_t new_config_id) = 0;
-  // Called when a config is deleted. The encoder will generate unroutable
-  // connection IDs from now on.
-  //
-  // New connections will not be able to support address migration until a new
-  // config arrives. Existing connections can retain connection IDs that use the
-  // deleted config, which will only become unroutable once the decoder also
-  // deletes it. The time of that deletion is deployment-dependent and might be
-  // tied to the arrival of a new config at the encoder.
-  virtual void OnConfigDeleted(const uint8_t config_id) = 0;
-};
-
-// Manages QUIC-LB configurations to properly encode a given server ID in a
-// QUIC Connection ID.
-class QUIC_EXPORT_PRIVATE LoadBalancerEncoder {
- public:
-  // Returns a newly created encoder with no active config, if
-  // |unroutable_connection_id_length| is valid. |visitor| specifies an optional
-  // interface to receive callbacks when connection IDs need to be retired.
-  // If |encode_length| is true, then the first byte of any generated
-  // connection ids will encode the length. Otherwise, those bits will be
-  // random. |unroutable_connection_id_length| specifies the length of
-  // connection IDs to be generated when there is no active config. It must not
-  // be 0 and must not be larger than the RFC9000 maximum of 20.
-  static absl::optional<LoadBalancerEncoder> Create(
-      QuicRandom& random, LoadBalancerEncoderVisitorInterface* const visitor,
-      const bool len_self_encoded,
-      const uint8_t unroutable_connection_id_len = kLoadBalancerUnroutableLen);
-
-  // Attempts to replace the current config and server_id with |config| and
-  // |server_id|. If the length |server_id| does not match the server_id_length
-  // of |config| or the ID of |config| matches the ID of the current config,
-  // returns false and leaves the current config unchanged. Otherwise, returns
-  // true. When the encoder runs out of nonces, it will delete the config and
-  // begin generating unroutable connection IDs.
-  bool UpdateConfig(const LoadBalancerConfig& config,
-                    const LoadBalancerServerId server_id);
-
-  // Delete the current config and generate unroutable connection IDs from now
-  // on.
-  void DeleteConfig();
-
-  // Returns the number of additional connections IDs that can be generated with
-  // the current config, or 0 if there is no current config.
-  absl::uint128 num_nonces_left() const { return num_nonces_left_; }
-
-  // Returns true if there is an active configuration.
-  bool IsEncoding() const { return config_.has_value(); }
-  // Returns true if there is an active configuration that uses encryption.
-  bool IsEncrypted() const {
-    return config_.has_value() && config_->IsEncrypted();
-  }
-
-  // If there's an active config, generates a connection ID using it. If not,
-  // generates an unroutable connection_id. If there's an error, returns a zero-
-  // length Connection ID.
-  QuicConnectionId GenerateConnectionId();
-
- private:
-  friend class test::LoadBalancerEncoderPeer;
-
-  LoadBalancerEncoder(QuicRandom& random,
-                      LoadBalancerEncoderVisitorInterface* const visitor,
-                      const bool len_self_encoded,
-                      const uint8_t unroutable_connection_id_len)
-      : random_(random),
-        len_self_encoded_(len_self_encoded),
-        visitor_(visitor),
-        unroutable_connection_id_len_(unroutable_connection_id_len) {}
-
-  QuicConnectionId MakeUnroutableConnectionId(uint8_t first_byte);
-
-  QuicRandom& random_;
-  const bool len_self_encoded_;
-  LoadBalancerEncoderVisitorInterface* const visitor_;
-  const uint8_t unroutable_connection_id_len_;
-
-  absl::optional<LoadBalancerConfig> config_;
-  absl::uint128 seed_, num_nonces_left_ = 0;
-  absl::optional<LoadBalancerServerId> server_id_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_LOAD_BALANCER_ENCODER_H_
diff --git a/quic/load_balancer/load_balancer_encoder_test.cc b/quic/load_balancer/load_balancer_encoder_test.cc
deleted file mode 100644
index d2817f0..0000000
--- a/quic/load_balancer/load_balancer_encoder_test.cc
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_encoder.h"
-
-#include <cstdint>
-
-#include "absl/numeric/int128.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-class LoadBalancerEncoderPeer {
- public:
-  static void SetNumNoncesLeft(LoadBalancerEncoder &encoder,
-                               uint64_t nonces_remaining) {
-    encoder.num_nonces_left_ = absl::uint128(nonces_remaining);
-  }
-};
-
-namespace {
-
-class TestLoadBalancerEncoderVisitor
-    : public LoadBalancerEncoderVisitorInterface {
- public:
-  ~TestLoadBalancerEncoderVisitor() override {}
-
-  void OnConfigAdded(const uint8_t config_id) override {
-    num_adds_++;
-    current_config_id_ = config_id;
-  }
-
-  void OnConfigChanged(const uint8_t old_config_id,
-                       const uint8_t new_config_id) override {
-    num_adds_++;
-    num_deletes_++;
-    EXPECT_EQ(old_config_id, current_config_id_);
-    current_config_id_ = new_config_id;
-  }
-
-  void OnConfigDeleted(const uint8_t config_id) override {
-    EXPECT_EQ(config_id, current_config_id_);
-    current_config_id_.reset();
-    num_deletes_++;
-  }
-
-  uint32_t num_adds() const { return num_adds_; }
-  uint32_t num_deletes() const { return num_deletes_; }
-
- private:
-  uint32_t num_adds_ = 0, num_deletes_ = 0;
-  absl::optional<uint8_t> current_config_id_ = absl::optional<uint8_t>();
-};
-
-// Allows the caller to specify the exact results in 64-bit chunks.
-class TestRandom : public QuicRandom {
- public:
-  uint64_t RandUint64() override {
-    if (next_values_.empty()) {
-      return base_;
-    }
-    uint64_t value = next_values_.front();
-    next_values_.pop();
-    return value;
-  }
-
-  void RandBytes(void *data, size_t len) override {
-    size_t written = 0;
-    uint8_t *ptr = static_cast<uint8_t *>(data);
-    while (written < len) {
-      uint64_t result = RandUint64();
-      size_t to_write = (len - written > sizeof(uint64_t)) ? sizeof(uint64_t)
-                                                           : (len - written);
-      memcpy(ptr + written, &result, to_write);
-      written += to_write;
-    }
-  }
-
-  void InsecureRandBytes(void *data, size_t len) override {
-    RandBytes(data, len);
-  }
-
-  uint64_t InsecureRandUint64() override { return RandUint64(); }
-
-  void AddNextValues(uint64_t hi, uint64_t lo) {
-    next_values_.push(hi);
-    next_values_.push(lo);
-  }
-
- private:
-  std::queue<uint64_t> next_values_;
-  uint64_t base_ = 0xDEADBEEFDEADBEEF;
-};
-
-class LoadBalancerEncoderTest : public QuicTest {
- public:
-  TestRandom random_;
-};
-
-// Convenience function to shorten the code. Does not check if |array| is long
-// enough or |length| is valid for a server ID.
-LoadBalancerServerId MakeServerId(const uint8_t array[], const uint8_t length) {
-  return *LoadBalancerServerId::Create(
-      absl::Span<const uint8_t>(array, length));
-}
-
-constexpr char kRawKey[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
-                            0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
-constexpr absl::string_view kKey(kRawKey, kLoadBalancerKeyLen);
-constexpr uint64_t kNonceLow = 0xe5d1c048bf0d08ee;
-constexpr uint64_t kNonceHigh = 0x9321e7e34dde525d;
-constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
-                                 0xab, 0x65, 0xba, 0x04, 0xc3, 0x33, 0x0a};
-
-TEST_F(LoadBalancerEncoderTest, BadUnroutableLength) {
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(
-          LoadBalancerEncoder::Create(random_, nullptr, false, 0).has_value()),
-      "Invalid unroutable_connection_id_len = 0");
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(
-          LoadBalancerEncoder::Create(random_, nullptr, false, 21).has_value()),
-      "Invalid unroutable_connection_id_len = 21");
-}
-
-TEST_F(LoadBalancerEncoderTest, BadServerIdLength) {
-  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true);
-  EXPECT_TRUE(encoder.has_value());
-  // Expects a 3 byte server ID and got 4.
-  auto config = LoadBalancerConfig::CreateUnencrypted(1, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 4))),
-      "Server ID length 4 does not match configured value of 3");
-  EXPECT_FALSE(encoder->IsEncoding());
-}
-
-TEST_F(LoadBalancerEncoderTest, FailToUpdateConfigWithSameId) {
-  TestLoadBalancerEncoderVisitor visitor;
-  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
-  EXPECT_TRUE(encoder.has_value());
-  EXPECT_TRUE(encoder.has_value());
-  auto config = LoadBalancerConfig::CreateUnencrypted(1, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
-  EXPECT_EQ(visitor.num_adds(), 1u);
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3))),
-      "Attempting to change config with same ID");
-  EXPECT_EQ(visitor.num_adds(), 1u);
-}
-
-TEST_F(LoadBalancerEncoderTest, UnencryptedConnectionIdTestVectors) {
-  const uint8_t server_id_lens[] = {3, 8};
-  const uint8_t nonce_lens[] = {4, 5};
-  static_assert(sizeof(server_id_lens) == sizeof(nonce_lens));
-  const std::vector<QuicConnectionId> expected_connection_ids{
-      QuicConnectionId({0x07, 0xed, 0x79, 0x3a, 0x80, 0x49, 0x71, 0x8a}),
-      QuicConnectionId({0x4d, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
-                        0xee, 0x15, 0xda, 0x27, 0xc4}),
-  };
-  EXPECT_EQ(sizeof(server_id_lens), expected_connection_ids.size());
-  for (uint8_t i = 0; i < sizeof(server_id_lens); i++) {
-    uint8_t config_id = i % 3;
-    random_.AddNextValues(kNonceHigh, kNonceLow);
-    auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 8);
-    EXPECT_TRUE(encoder.has_value());
-    auto config = LoadBalancerConfig::CreateUnencrypted(
-        config_id, server_id_lens[i], nonce_lens[i]);
-    EXPECT_TRUE(config.has_value());
-    EXPECT_TRUE(encoder->UpdateConfig(
-        *config, MakeServerId(kServerId, server_id_lens[i])));
-    absl::uint128 nonces_left = encoder->num_nonces_left();
-    EXPECT_EQ(encoder->GenerateConnectionId(), expected_connection_ids[i]);
-    EXPECT_EQ(encoder->num_nonces_left(), nonces_left - 1);
-  }
-}
-
-// Follow example in draft-ietf-quic-load-balancers-12.
-TEST_F(LoadBalancerEncoderTest, FollowSpecExample) {
-  const uint8_t config_id = 0, server_id_len = 3, nonce_len = 4;
-  const uint8_t raw_server_id[] = {
-      0x31,
-      0x44,
-      0x1a,
-  };
-  const char raw_key[] = {
-      0xfd, 0xf7, 0x26, 0xa9, 0x89, 0x3e, 0xc0, 0x5c,
-      0x06, 0x32, 0xd3, 0x95, 0x66, 0x80, 0xba, 0xf0,
-  };
-  random_.AddNextValues(0, 0x75c2699c);
-  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 8);
-  EXPECT_TRUE(encoder.has_value());
-  auto config = LoadBalancerConfig::Create(config_id, server_id_len, nonce_len,
-                                           absl::string_view(raw_key));
-  EXPECT_TRUE(config.has_value());
-  EXPECT_TRUE(encoder->UpdateConfig(
-      *config, *LoadBalancerServerId::Create(raw_server_id)));
-  EXPECT_TRUE(encoder->IsEncoding());
-  const char raw_connection_id[] = {0x07, 0xe2, 0x3c, 0xb4,
-                                    0x2b, 0xba, 0x1e, 0xe0};
-  auto expected =
-      QuicConnectionId(raw_connection_id, 1 + server_id_len + nonce_len);
-  EXPECT_EQ(encoder->GenerateConnectionId(), expected);
-}
-
-// Compare test vectors from Appendix B of draft-ietf-quic-load-balancers-12.
-TEST_F(LoadBalancerEncoderTest, EncoderTestVectors) {
-  // Try (1) the "standard" ConnectionId length of 8
-  // (2) server_id_len > nonce_len, so there is a fourth decryption pass
-  // (3) the single-pass encryption case
-  // (4) An even total length.
-  uint8_t server_id_lens[] = {3, 10, 8, 9};
-  uint8_t nonce_lens[] = {4, 5, 8, 9};
-  static_assert(sizeof(server_id_lens) == sizeof(nonce_lens));
-  const std::vector<QuicConnectionId> expected_connection_ids{
-      QuicConnectionId({0x07, 0xfb, 0xfe, 0x05, 0xf7, 0x31, 0xb4, 0x25}),
-      QuicConnectionId({0x4f, 0x01, 0x09, 0x56, 0xfb, 0x5c, 0x1d, 0x4d, 0x86,
-                        0xe0, 0x10, 0x18, 0x3e, 0x0b, 0x7d, 0x1e}),
-      QuicConnectionId({0x90, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2,
-                        0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3}),
-      QuicConnectionId({0x12, 0x7a, 0x28, 0x5a, 0x09, 0xf8, 0x52, 0x80, 0xf4,
-                        0xfd, 0x6a, 0xbb, 0x43, 0x4a, 0x71, 0x59, 0xe4, 0xd3,
-                        0xeb}),
-  };
-  EXPECT_EQ(sizeof(server_id_lens), expected_connection_ids.size());
-  for (uint8_t i = 0; i < sizeof(server_id_lens); i++) {
-    uint8_t config_id = i % 3;
-    auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 8);
-    EXPECT_TRUE(encoder.has_value());
-    auto config = LoadBalancerConfig::Create(config_id, server_id_lens[i],
-                                             nonce_lens[i], kKey);
-    EXPECT_TRUE(config.has_value());
-    random_.AddNextValues(kNonceHigh, kNonceLow);
-    EXPECT_TRUE(encoder->UpdateConfig(
-        *config, MakeServerId(kServerId, server_id_lens[i])));
-    EXPECT_EQ(encoder->GenerateConnectionId(), expected_connection_ids[i]);
-  }
-}
-
-TEST_F(LoadBalancerEncoderTest, RunOutOfNonces) {
-  const uint8_t config_id = 0, server_id_len = 3, nonce_len = 4;
-  TestLoadBalancerEncoderVisitor visitor;
-  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true, 8);
-  EXPECT_TRUE(encoder.has_value());
-  auto config =
-      LoadBalancerConfig::Create(config_id, server_id_len, nonce_len, kKey);
-  EXPECT_TRUE(config.has_value());
-  EXPECT_TRUE(
-      encoder->UpdateConfig(*config, MakeServerId(kServerId, server_id_len)));
-  EXPECT_EQ(visitor.num_adds(), 1u);
-  LoadBalancerEncoderPeer::SetNumNoncesLeft(*encoder, 2);
-  EXPECT_EQ(encoder->num_nonces_left(), 2);
-  EXPECT_EQ(encoder->GenerateConnectionId(),
-            QuicConnectionId({0x07, 0xba, 0x7f, 0x38, 0x2f, 0x5c, 0x22, 0x1d}));
-  EXPECT_EQ(encoder->num_nonces_left(), 1);
-  encoder->GenerateConnectionId();
-  EXPECT_EQ(encoder->IsEncoding(), false);
-  // No retire_calls except for the initial UpdateConfig.
-  EXPECT_EQ(visitor.num_deletes(), 1u);
-}
-
-TEST_F(LoadBalancerEncoderTest, UnroutableConnectionId) {
-  random_.AddNextValues(0x83, kNonceHigh);
-  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, false);
-  EXPECT_TRUE(encoder.has_value());
-  EXPECT_EQ(encoder->num_nonces_left(), 0);
-  auto connection_id = encoder->GenerateConnectionId();
-  // The first byte is the config_id (0xc0) xored with (0x83 & 0x3f).
-  // The remaining bytes are random, and therefore match kNonceHigh.
-  QuicConnectionId expected({0xc3, 0x5d, 0x52, 0xde, 0x4d, 0xe3, 0xe7, 0x21});
-  EXPECT_EQ(expected, connection_id);
-}
-
-TEST_F(LoadBalancerEncoderTest, NonDefaultUnroutableConnectionIdLength) {
-  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 9);
-  EXPECT_TRUE(encoder.has_value());
-  QuicConnectionId connection_id = encoder->GenerateConnectionId();
-  EXPECT_EQ(connection_id.length(), 9);
-}
-
-TEST_F(LoadBalancerEncoderTest, DeleteConfigWhenNoConfigExists) {
-  TestLoadBalancerEncoderVisitor visitor;
-  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
-  EXPECT_TRUE(encoder.has_value());
-  encoder->DeleteConfig();
-  EXPECT_EQ(visitor.num_deletes(), 0u);
-}
-
-TEST_F(LoadBalancerEncoderTest, AddConfig) {
-  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  TestLoadBalancerEncoderVisitor visitor;
-  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
-  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
-  EXPECT_EQ(visitor.num_adds(), 1u);
-  absl::uint128 left = encoder->num_nonces_left();
-  EXPECT_EQ(left, (0x1ull << 32));
-  EXPECT_TRUE(encoder->IsEncoding());
-  EXPECT_FALSE(encoder->IsEncrypted());
-  encoder->GenerateConnectionId();
-  EXPECT_EQ(encoder->num_nonces_left(), left - 1);
-  EXPECT_EQ(visitor.num_deletes(), 0u);
-}
-
-TEST_F(LoadBalancerEncoderTest, UpdateConfig) {
-  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  TestLoadBalancerEncoderVisitor visitor;
-  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
-  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
-  config = LoadBalancerConfig::Create(1, 4, 4, kKey);
-  EXPECT_TRUE(config.has_value());
-  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 4)));
-  EXPECT_EQ(visitor.num_adds(), 2u);
-  EXPECT_EQ(visitor.num_deletes(), 1u);
-  EXPECT_TRUE(encoder->IsEncoding());
-  EXPECT_TRUE(encoder->IsEncrypted());
-}
-
-TEST_F(LoadBalancerEncoderTest, DeleteConfig) {
-  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  TestLoadBalancerEncoderVisitor visitor;
-  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
-  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
-  encoder->DeleteConfig();
-  EXPECT_EQ(visitor.num_adds(), 1u);
-  EXPECT_EQ(visitor.num_deletes(), 1u);
-  EXPECT_FALSE(encoder->IsEncoding());
-  EXPECT_FALSE(encoder->IsEncrypted());
-  EXPECT_EQ(encoder->num_nonces_left(), 0);
-}
-
-TEST_F(LoadBalancerEncoderTest, DeleteConfigNoVisitor) {
-  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
-  EXPECT_TRUE(config.has_value());
-  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true);
-  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
-  encoder->DeleteConfig();
-  EXPECT_FALSE(encoder->IsEncoding());
-  EXPECT_FALSE(encoder->IsEncrypted());
-  EXPECT_EQ(encoder->num_nonces_left(), 0);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_server_id.cc b/quic/load_balancer/load_balancer_server_id.cc
deleted file mode 100644
index 12f1135..0000000
--- a/quic/load_balancer/load_balancer_server_id.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_server_id.h"
-
-#include "absl/strings/escaping.h"
-#include "absl/types/span.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-namespace {
-
-// Helper to allow setting the const array during initialization.
-std::array<uint8_t, kLoadBalancerMaxServerIdLen> MakeArray(
-    const absl::Span<const uint8_t> data, const uint8_t length) {
-  std::array<uint8_t, kLoadBalancerMaxServerIdLen> array;
-  memcpy(array.data(), data.data(), length);
-  return array;
-}
-
-}  // namespace
-
-absl::optional<LoadBalancerServerId> LoadBalancerServerId::Create(
-    const absl::Span<const uint8_t> data) {
-  if (data.length() == 0 || data.length() > kLoadBalancerMaxServerIdLen) {
-    QUIC_BUG(quic_bug_433312504_01)
-        << "Attempted to create LoadBalancerServerId with length "
-        << data.length();
-    return absl::optional<LoadBalancerServerId>();
-  }
-  return LoadBalancerServerId(data);
-}
-
-std::string LoadBalancerServerId::ToString() const {
-  return absl::BytesToHexString(
-      absl::string_view(reinterpret_cast<const char*>(data_.data()), length_));
-}
-
-LoadBalancerServerId::LoadBalancerServerId(const absl::Span<const uint8_t> data)
-    : data_(MakeArray(data, data.length())), length_(data.length()) {}
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_server_id.h b/quic/load_balancer/load_balancer_server_id.h
deleted file mode 100644
index 3c4eb86..0000000
--- a/quic/load_balancer/load_balancer_server_id.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_LOAD_BALANCER_SERVER_ID_H_
-#define QUICHE_QUIC_LOAD_BALANCER_SERVER_ID_H_
-
-#include <array>
-
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// The maximum number of bytes in a LoadBalancerServerId.
-inline constexpr uint8_t kLoadBalancerMaxServerIdLen = 15;
-
-// LoadBalancerServerId is the globally understood identifier for a given pool
-// member. It is unique to any given QUIC-LB configuration. See
-// draft-ietf-quic-load-balancers-12.
-// Note: this has nothing to do with QuicServerID. It's an unfortunate collision
-// between an internal term for the destination identifiers for a particular
-// deployment (QuicServerID) and the object of a load balancing decision
-// (LoadBalancerServerId).
-class QUIC_EXPORT_PRIVATE LoadBalancerServerId {
- public:
-  // Copies all the bytes from |data| into a new LoadBalancerServerId.
-  static absl::optional<LoadBalancerServerId> Create(
-      const absl::Span<const uint8_t> data);
-
-  // Server IDs are opaque bytes, but defining these operators allows us to sort
-  // them into a tree and define ranges.
-  bool operator<(const LoadBalancerServerId& other) const {
-    return data() < other.data();
-  }
-  bool operator==(const LoadBalancerServerId& other) const {
-    return data() == other.data();
-  }
-
-  // Hash function to allow use as a key in unordered maps.
-  template <typename H>
-  friend H AbslHashValue(H h, const LoadBalancerServerId& server_id) {
-    return H::combine_contiguous(std::move(h), server_id.data().data(),
-                                 server_id.length());
-  }
-
-  absl::Span<const uint8_t> data() const {
-    return absl::MakeConstSpan(data_.data(), length_);
-  }
-  uint8_t length() const { return length_; }
-
-  // Returns the server ID in hex format.
-  std::string ToString() const;
-
- private:
-  // The constructor is private because it can't validate the input.
-  LoadBalancerServerId(const absl::Span<const uint8_t> data);
-
-  std::array<uint8_t, kLoadBalancerMaxServerIdLen> data_;
-  uint8_t length_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_LOAD_BALANCER_SERVER_ID_H_
diff --git a/quic/load_balancer/load_balancer_server_id_map.h b/quic/load_balancer/load_balancer_server_id_map.h
deleted file mode 100644
index 400ac68..0000000
--- a/quic/load_balancer/load_balancer_server_id_map.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
-#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/load_balancer/load_balancer_server_id.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-// This class wraps an absl::flat_hash_map which associates server IDs to an
-// arbitrary type T. It validates that all server ids are of the same fixed
-// length.
-template <typename T>
-class QUIC_EXPORT_PRIVATE LoadBalancerServerIdMap {
- public:
-  // Returns a newly created pool for server IDs of length |server_id_len|, or
-  // nullptr if |server_id_len| is invalid.
-  static std::shared_ptr<LoadBalancerServerIdMap> Create(
-      const uint8_t server_id_len);
-
-  // Returns the entry associated with |server_id|, if present. For small |T|,
-  // use Lookup. For large |T|, use LookupNoCopy.
-  absl::optional<const T> Lookup(const LoadBalancerServerId server_id) const;
-  const T* LookupNoCopy(const LoadBalancerServerId server_id) const;
-
-  // Updates the table so that |value| is associated with |server_id|. Sets
-  // QUIC_BUG if the length is incorrect for this map.
-  void AddOrReplace(const LoadBalancerServerId server_id, T value);
-
-  // Removes the entry associated with |server_id|.
-  void Erase(const LoadBalancerServerId server_id) {
-    server_id_table_.erase(server_id);
-  }
-
-  uint8_t server_id_len() const { return server_id_len_; }
-
- private:
-  LoadBalancerServerIdMap(uint8_t server_id_len)
-      : server_id_len_(server_id_len) {}
-
-  const uint8_t server_id_len_;  // All server IDs must be of this length.
-  absl::flat_hash_map<LoadBalancerServerId, T> server_id_table_;
-};
-
-template <typename T>
-std::shared_ptr<LoadBalancerServerIdMap<T>> LoadBalancerServerIdMap<T>::Create(
-    const uint8_t server_id_len) {
-  if (server_id_len == 0 || server_id_len > kLoadBalancerMaxServerIdLen) {
-    QUIC_BUG(quic_bug_434893339_01)
-        << "Tried to configure map with server ID length "
-        << static_cast<int>(server_id_len);
-    return nullptr;
-  }
-  return std::make_shared<LoadBalancerServerIdMap<T>>(
-      LoadBalancerServerIdMap(server_id_len));
-}
-
-template <typename T>
-absl::optional<const T> LoadBalancerServerIdMap<T>::Lookup(
-    const LoadBalancerServerId server_id) const {
-  if (server_id.length() != server_id_len_) {
-    QUIC_BUG(quic_bug_434893339_02)
-        << "Lookup with a " << static_cast<int>(server_id.length())
-        << " byte server ID, map requires " << static_cast<int>(server_id_len_);
-    return absl::optional<T>();
-  }
-  auto it = server_id_table_.find(server_id);
-  return (it != server_id_table_.end()) ? it->second
-                                        : absl::optional<const T>();
-}
-
-template <typename T>
-const T* LoadBalancerServerIdMap<T>::LookupNoCopy(
-    const LoadBalancerServerId server_id) const {
-  if (server_id.length() != server_id_len_) {
-    QUIC_BUG(quic_bug_434893339_02)
-        << "Lookup with a " << static_cast<int>(server_id.length())
-        << " byte server ID, map requires " << static_cast<int>(server_id_len_);
-    return nullptr;
-  }
-  auto it = server_id_table_.find(server_id);
-  return (it != server_id_table_.end()) ? &it->second : nullptr;
-}
-
-template <typename T>
-void LoadBalancerServerIdMap<T>::AddOrReplace(
-    const LoadBalancerServerId server_id, T value) {
-  if (server_id.length() == server_id_len_) {
-    server_id_table_[server_id] = value;
-  } else {
-    QUIC_BUG(quic_bug_434893339_03)
-        << "Server ID of " << static_cast<int>(server_id.length())
-        << " bytes; this map requires " << static_cast<int>(server_id_len_);
-  }
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
diff --git a/quic/load_balancer/load_balancer_server_id_map_test.cc b/quic/load_balancer/load_balancer_server_id_map_test.cc
deleted file mode 100644
index 37f6a06..0000000
--- a/quic/load_balancer/load_balancer_server_id_map_test.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_server_id_map.h"
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51};
-
-class LoadBalancerServerIdMapTest : public QuicTest {
- public:
-  const LoadBalancerServerId valid_server_id_ =
-      *LoadBalancerServerId::Create(kServerId);
-  const LoadBalancerServerId invalid_server_id_ =
-      *LoadBalancerServerId::Create(absl::Span<const uint8_t>(kServerId, 3));
-};
-
-TEST_F(LoadBalancerServerIdMapTest, CreateWithBadServerIdLength) {
-  EXPECT_QUIC_BUG(EXPECT_EQ(LoadBalancerServerIdMap<int>::Create(0), nullptr),
-                  "Tried to configure map with server ID length 0");
-  EXPECT_QUIC_BUG(EXPECT_EQ(LoadBalancerServerIdMap<int>::Create(16), nullptr),
-                  "Tried to configure map with server ID length 16");
-}
-
-TEST_F(LoadBalancerServerIdMapTest, AddOrReplaceWithBadServerIdLength) {
-  int record = 1;
-  auto pool = LoadBalancerServerIdMap<int>::Create(4);
-  EXPECT_NE(pool, nullptr);
-  EXPECT_QUIC_BUG(pool->AddOrReplace(invalid_server_id_, record),
-                  "Server ID of 3 bytes; this map requires 4");
-}
-
-TEST_F(LoadBalancerServerIdMapTest, LookupWithBadServerIdLength) {
-  int record = 1;
-  auto pool = LoadBalancerServerIdMap<int>::Create(4);
-  EXPECT_NE(pool, nullptr);
-  pool->AddOrReplace(valid_server_id_, record);
-  EXPECT_QUIC_BUG(EXPECT_FALSE(pool->Lookup(invalid_server_id_).has_value()),
-                  "Lookup with a 3 byte server ID, map requires 4");
-  EXPECT_QUIC_BUG(EXPECT_EQ(pool->LookupNoCopy(invalid_server_id_), nullptr),
-                  "Lookup with a 3 byte server ID, map requires 4");
-}
-
-TEST_F(LoadBalancerServerIdMapTest, LookupWhenEmpty) {
-  auto pool = LoadBalancerServerIdMap<int>::Create(4);
-  EXPECT_NE(pool, nullptr);
-  EXPECT_EQ(pool->LookupNoCopy(valid_server_id_), nullptr);
-  absl::optional<int> result = pool->Lookup(valid_server_id_);
-  EXPECT_FALSE(result.has_value());
-}
-
-TEST_F(LoadBalancerServerIdMapTest, AddLookup) {
-  int record1 = 1, record2 = 2;
-  auto pool = LoadBalancerServerIdMap<int>::Create(4);
-  EXPECT_NE(pool, nullptr);
-  auto other_server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03, 0x04});
-  EXPECT_TRUE(other_server_id.has_value());
-  pool->AddOrReplace(valid_server_id_, record1);
-  pool->AddOrReplace(*other_server_id, record2);
-  absl::optional<int> result = pool->Lookup(valid_server_id_);
-  EXPECT_TRUE(result.has_value());
-  EXPECT_EQ(*result, record1);
-  auto result_ptr = pool->LookupNoCopy(valid_server_id_);
-  EXPECT_NE(result_ptr, nullptr);
-  EXPECT_EQ(*result_ptr, record1);
-  result = pool->Lookup(*other_server_id);
-  EXPECT_TRUE(result.has_value());
-  EXPECT_EQ(*result, record2);
-}
-
-TEST_F(LoadBalancerServerIdMapTest, AddErase) {
-  int record = 1;
-  auto pool = LoadBalancerServerIdMap<int>::Create(4);
-  EXPECT_NE(pool, nullptr);
-  pool->AddOrReplace(valid_server_id_, record);
-  EXPECT_EQ(*pool->LookupNoCopy(valid_server_id_), record);
-  pool->Erase(valid_server_id_);
-  EXPECT_EQ(pool->LookupNoCopy(valid_server_id_), nullptr);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/load_balancer/load_balancer_server_id_test.cc b/quic/load_balancer/load_balancer_server_id_test.cc
deleted file mode 100644
index 8160830..0000000
--- a/quic/load_balancer/load_balancer_server_id_test.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/load_balancer/load_balancer_server_id.h"
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-
-#include "absl/hash/hash_testing.h"
-
-#pragma clang diagnostic pop
-
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-namespace {
-
-class LoadBalancerServerIdTest : public QuicTest {};
-
-constexpr uint8_t kRawServerId[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-                                    0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
-                                    0x0c, 0x0d, 0x0e, 0x0f};
-
-TEST_F(LoadBalancerServerIdTest, CreateReturnsNullIfTooLong) {
-  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerServerId::Create(
-                                   absl::Span<const uint8_t>(kRawServerId, 16))
-                                   .has_value()),
-                  "Attempted to create LoadBalancerServerId with length 16");
-  EXPECT_QUIC_BUG(
-      EXPECT_FALSE(LoadBalancerServerId::Create(absl::Span<const uint8_t>())
-                       .has_value()),
-      "Attempted to create LoadBalancerServerId with length 0");
-}
-
-TEST_F(LoadBalancerServerIdTest, CompareIdenticalExceptLength) {
-  auto server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
-  ASSERT_TRUE(server_id.has_value());
-  EXPECT_EQ(server_id->length(), 15);
-  auto shorter_server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
-  ASSERT_TRUE(shorter_server_id.has_value());
-  EXPECT_EQ(shorter_server_id->length(), 5);
-  // Shorter comes before longer if all bits match
-  EXPECT_TRUE(shorter_server_id < server_id);
-  EXPECT_FALSE(server_id < shorter_server_id);
-  // Different lengths are never equal.
-  EXPECT_FALSE(shorter_server_id == server_id);
-}
-
-TEST_F(LoadBalancerServerIdTest, AccessorFunctions) {
-  auto server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
-  EXPECT_TRUE(server_id.has_value());
-  EXPECT_EQ(server_id->length(), 5);
-  EXPECT_EQ(memcmp(server_id->data().data(), kRawServerId, 5), 0);
-  EXPECT_EQ(server_id->ToString(), "0001020304");
-}
-
-TEST_F(LoadBalancerServerIdTest, CompareDifferentServerIds) {
-  auto server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
-  ASSERT_TRUE(server_id.has_value());
-  auto reverse = LoadBalancerServerId::Create({0x0f, 0x0e, 0x0d, 0x0c, 0x0b});
-  ASSERT_TRUE(reverse.has_value());
-  EXPECT_TRUE(server_id < reverse);
-  auto long_server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
-  EXPECT_TRUE(long_server_id < reverse);
-}
-
-TEST_F(LoadBalancerServerIdTest, EqualityOperators) {
-  auto server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
-  ASSERT_TRUE(server_id.has_value());
-  auto shorter_server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
-  ASSERT_TRUE(shorter_server_id.has_value());
-  EXPECT_FALSE(server_id == shorter_server_id);
-  auto server_id2 = server_id;
-  EXPECT_TRUE(server_id == server_id2);
-}
-
-TEST_F(LoadBalancerServerIdTest, SupportsHash) {
-  auto server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
-  ASSERT_TRUE(server_id.has_value());
-  auto shorter_server_id =
-      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
-  ASSERT_TRUE(shorter_server_id.has_value());
-  auto different_server_id =
-      LoadBalancerServerId::Create({0x0f, 0x0e, 0x0d, 0x0c, 0x0b});
-  ASSERT_TRUE(different_server_id.has_value());
-  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
-      *server_id,
-      *shorter_server_id,
-      *different_server_id,
-  }));
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/masque/masque_client_bin.cc b/quic/masque/masque_client_bin.cc
deleted file mode 100644
index 294ba4e..0000000
--- a/quic/masque/masque_client_bin.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is reponsible for the masque_client binary. It allows testing
-// our MASQUE client code by connecting to a MASQUE proxy and then sending
-// HTTP/3 requests to web servers tunnelled over that MASQUE connection.
-// e.g.: masque_client $PROXY_HOST:$PROXY_PORT $URL1 $URL2
-
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "url/third_party/mozilla/url_parse.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/masque/masque_client_tools.h"
-#include "quic/masque/masque_encapsulated_epoll_client.h"
-#include "quic/masque/masque_epoll_client.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/platform/api/quiche_system_event_loop.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, disable_certificate_verification, false,
-    "If true, don't verify the server certificate.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
-                                "Allows setting MASQUE mode, valid values are "
-                                "open and legacy. Defaults to open.");
-
-namespace quic {
-
-namespace {
-
-int RunMasqueClient(int argc, char* argv[]) {
-  quiche::QuicheSystemEventLoop event_loop("masque_client");
-  const char* usage = "Usage: masque_client [options] <url>";
-
-  // The first non-flag argument is the URI template of the MASQUE server.
-  // All subsequent ones are interpreted as URLs to fetch via the MASQUE server.
-  // Note that the URI template expansion currently only supports string
-  // replacement of {target_host} and {target_port}, not
-  // {?target_host,target_port}.
-  std::vector<std::string> urls =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-  if (urls.empty()) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    return 1;
-  }
-
-  const bool disable_certificate_verification =
-      GetQuicFlag(FLAGS_disable_certificate_verification);
-  QuicEpollServer epoll_server;
-
-  std::string uri_template = urls[0];
-  if (!absl::StrContains(uri_template, '/')) {
-    // Allow passing in authority instead of URI template.
-    uri_template =
-        absl::StrCat("https://", uri_template, "/{target_host}/{target_port}/");
-  }
-  url::Parsed parsed_uri_template;
-  url::ParseStandardURL(uri_template.c_str(), uri_template.length(),
-                        &parsed_uri_template);
-  if (!parsed_uri_template.scheme.is_nonempty() ||
-      !parsed_uri_template.host.is_nonempty() ||
-      !parsed_uri_template.path.is_nonempty()) {
-    std::cerr << "Failed to parse MASQUE URI template \"" << urls[0] << "\""
-              << std::endl;
-    return 1;
-  }
-  std::string host = uri_template.substr(parsed_uri_template.host.begin,
-                                         parsed_uri_template.host.len);
-  std::unique_ptr<ProofVerifier> proof_verifier;
-  if (disable_certificate_verification) {
-    proof_verifier = std::make_unique<FakeProofVerifier>();
-  } else {
-    proof_verifier = CreateDefaultProofVerifier(host);
-  }
-  MasqueMode masque_mode = MasqueMode::kOpen;
-  std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
-  if (mode_string == "legacy") {
-    masque_mode = MasqueMode::kLegacy;
-  } else if (!mode_string.empty() && mode_string != "open") {
-    std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
-    return 1;
-  }
-  std::unique_ptr<MasqueEpollClient> masque_client = MasqueEpollClient::Create(
-      uri_template, masque_mode, &epoll_server, std::move(proof_verifier));
-  if (masque_client == nullptr) {
-    return 1;
-  }
-
-  std::cerr << "MASQUE is connected " << masque_client->connection_id()
-            << " in " << masque_mode << " mode" << std::endl;
-
-  for (size_t i = 1; i < urls.size(); ++i) {
-    if (!tools::SendEncapsulatedMasqueRequest(
-            masque_client.get(), &epoll_server, urls[i],
-            disable_certificate_verification)) {
-      return 1;
-    }
-  }
-
-  return 0;
-}
-
-}  // namespace
-
-}  // namespace quic
-
-int main(int argc, char* argv[]) {
-  return quic::RunMasqueClient(argc, argv);
-}
diff --git a/quic/masque/masque_client_session.cc b/quic/masque/masque_client_session.cc
deleted file mode 100644
index 884cd20..0000000
--- a/quic/masque/masque_client_session.cc
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_client_session.h"
-
-#include <string>
-
-#include "absl/algorithm/container.h"
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/str_cat.h"
-#include "url/url_canon.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_url_utils.h"
-
-namespace quic {
-
-MasqueClientSession::MasqueClientSession(
-    MasqueMode masque_mode, const std::string& uri_template,
-    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection, const QuicServerId& server_id,
-    QuicCryptoClientConfig* crypto_config,
-    QuicClientPushPromiseIndex* push_promise_index, Owner* owner)
-    : QuicSpdyClientSession(config, supported_versions, connection, server_id,
-                            crypto_config, push_promise_index),
-      masque_mode_(masque_mode),
-      uri_template_(uri_template),
-      owner_(owner),
-      compression_engine_(this) {}
-
-void MasqueClientSession::OnMessageReceived(absl::string_view message) {
-  if (masque_mode_ == MasqueMode::kLegacy) {
-    QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
-    QuicConnectionId client_connection_id, server_connection_id;
-    QuicSocketAddress target_server_address;
-    std::vector<char> packet;
-    bool version_present;
-    if (!compression_engine_.DecompressDatagram(
-            message, &client_connection_id, &server_connection_id,
-            &target_server_address, &packet, &version_present)) {
-      return;
-    }
-
-    auto connection_id_registration =
-        client_connection_id_registrations_.find(client_connection_id);
-    if (connection_id_registration ==
-        client_connection_id_registrations_.end()) {
-      QUIC_DLOG(ERROR) << "MasqueClientSession failed to dispatch "
-                       << client_connection_id;
-      return;
-    }
-    EncapsulatedClientSession* encapsulated_client_session =
-        connection_id_registration->second;
-    encapsulated_client_session->ProcessPacket(
-        absl::string_view(packet.data(), packet.size()), target_server_address);
-
-    QUIC_DVLOG(1) << "Sent " << packet.size() << " bytes to connection for "
-                  << client_connection_id;
-    return;
-  }
-  QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
-  QuicSpdySession::OnMessageReceived(message);
-}
-
-void MasqueClientSession::OnMessageAcked(QuicMessageId message_id,
-                                         QuicTime /*receive_timestamp*/) {
-  QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
-}
-
-void MasqueClientSession::OnMessageLost(QuicMessageId message_id) {
-  QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost";
-}
-
-const MasqueClientSession::ConnectUdpClientState*
-MasqueClientSession::GetOrCreateConnectUdpClientState(
-    const QuicSocketAddress& target_server_address,
-    EncapsulatedClientSession* encapsulated_client_session) {
-  for (const ConnectUdpClientState& client_state : connect_udp_client_states_) {
-    if (client_state.target_server_address() == target_server_address &&
-        client_state.encapsulated_client_session() ==
-            encapsulated_client_session) {
-      // Found existing CONNECT-UDP request.
-      return &client_state;
-    }
-  }
-  // No CONNECT-UDP request found, create a new one.
-
-  url::Parsed parsed_uri_template;
-  url::ParseStandardURL(uri_template_.c_str(), uri_template_.length(),
-                        &parsed_uri_template);
-  if (!parsed_uri_template.path.is_nonempty()) {
-    QUIC_BUG(bad URI template path)
-        << "Cannot parse path from URI template " << uri_template_;
-    return nullptr;
-  }
-  std::string path = uri_template_.substr(parsed_uri_template.path.begin,
-                                          parsed_uri_template.path.len);
-  if (parsed_uri_template.query.is_valid()) {
-    absl::StrAppend(&path, "?",
-                    uri_template_.substr(parsed_uri_template.query.begin,
-                                         parsed_uri_template.query.len));
-  }
-  absl::flat_hash_map<std::string, std::string> parameters;
-  parameters["target_host"] = target_server_address.host().ToString();
-  parameters["target_port"] = absl::StrCat(target_server_address.port());
-  std::string expanded_path;
-  absl::flat_hash_set<std::string> vars_found;
-  bool expanded =
-      quiche::ExpandURITemplate(path, parameters, &expanded_path, &vars_found);
-  if (!expanded || vars_found.find("target_host") == vars_found.end() ||
-      vars_found.find("target_port") == vars_found.end()) {
-    QUIC_DLOG(ERROR) << "Failed to expand URI template \"" << uri_template_
-                     << "\" for " << target_server_address;
-    return nullptr;
-  }
-
-  url::Component expanded_path_component(0, expanded_path.length());
-  url::RawCanonOutput<1024> canonicalized_path_output;
-  url::Component canonicalized_path_component;
-  bool canonicalized = url::CanonicalizePath(
-      expanded_path.c_str(), expanded_path_component,
-      &canonicalized_path_output, &canonicalized_path_component);
-  if (!canonicalized || !canonicalized_path_component.is_nonempty()) {
-    QUIC_DLOG(ERROR) << "Failed to canonicalize URI template \""
-                     << uri_template_ << "\" for " << target_server_address;
-    return nullptr;
-  }
-  std::string canonicalized_path(
-      canonicalized_path_output.data() + canonicalized_path_component.begin,
-      canonicalized_path_component.len);
-
-  QuicSpdyClientStream* stream = CreateOutgoingBidirectionalStream();
-  if (stream == nullptr) {
-    // Stream flow control limits prevented us from opening a new stream.
-    QUIC_DLOG(ERROR) << "Failed to open CONNECT-UDP stream";
-    return nullptr;
-  }
-
-  QuicUrl url(uri_template_);
-  std::string scheme = url.scheme();
-  std::string authority = url.HostPort();
-
-  QUIC_DLOG(INFO) << "Sending CONNECT-UDP request for " << target_server_address
-                  << " on stream " << stream->id() << " scheme=\"" << scheme
-                  << "\" authority=\"" << authority << "\" path=\""
-                  << canonicalized_path << "\"";
-
-  // Send the request.
-  spdy::Http2HeaderBlock headers;
-  headers[":method"] = "CONNECT";
-  headers[":protocol"] = "connect-udp";
-  headers[":scheme"] = scheme;
-  headers[":authority"] = authority;
-  headers[":path"] = canonicalized_path;
-  headers["connect-udp-version"] = "6";
-  if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
-    SpdyUtils::AddDatagramFlowIdHeader(&headers, stream->id());
-  }
-  size_t bytes_sent =
-      stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false);
-  if (bytes_sent == 0) {
-    QUIC_DLOG(ERROR) << "Failed to send CONNECT-UDP request";
-    return nullptr;
-  }
-
-  absl::optional<QuicDatagramContextId> context_id;
-  connect_udp_client_states_.push_back(
-      ConnectUdpClientState(stream, encapsulated_client_session, this,
-                            context_id, target_server_address));
-  return &connect_udp_client_states_.back();
-}
-
-void MasqueClientSession::SendPacket(
-    QuicConnectionId client_connection_id,
-    QuicConnectionId server_connection_id, absl::string_view packet,
-    const QuicSocketAddress& target_server_address,
-    EncapsulatedClientSession* encapsulated_client_session) {
-  if (masque_mode_ == MasqueMode::kLegacy) {
-    compression_engine_.CompressAndSendPacket(packet, client_connection_id,
-                                              server_connection_id,
-                                              target_server_address);
-    return;
-  }
-  const ConnectUdpClientState* connect_udp = GetOrCreateConnectUdpClientState(
-      target_server_address, encapsulated_client_session);
-  if (connect_udp == nullptr) {
-    QUIC_DLOG(ERROR) << "Failed to create CONNECT-UDP request";
-    return;
-  }
-
-  MessageStatus message_status = SendHttp3Datagram(
-      connect_udp->stream()->id(), connect_udp->context_id(), packet);
-
-  QUIC_DVLOG(1) << "Sent packet to " << target_server_address
-                << " compressed with stream ID " << connect_udp->stream()->id()
-                << " context ID "
-                << (connect_udp->context_id().has_value()
-                        ? absl::StrCat(connect_udp->context_id().value())
-                        : "none")
-                << " and got message status "
-                << MessageStatusToString(message_status);
-}
-
-void MasqueClientSession::RegisterConnectionId(
-    QuicConnectionId client_connection_id,
-    EncapsulatedClientSession* encapsulated_client_session) {
-  QUIC_DLOG(INFO) << "Registering " << client_connection_id
-                  << " to encapsulated client";
-  QUICHE_DCHECK(
-      client_connection_id_registrations_.find(client_connection_id) ==
-          client_connection_id_registrations_.end() ||
-      client_connection_id_registrations_[client_connection_id] ==
-          encapsulated_client_session);
-  client_connection_id_registrations_[client_connection_id] =
-      encapsulated_client_session;
-}
-
-void MasqueClientSession::UnregisterConnectionId(
-    QuicConnectionId client_connection_id,
-    EncapsulatedClientSession* encapsulated_client_session) {
-  QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
-  if (masque_mode_ == MasqueMode::kLegacy) {
-    if (client_connection_id_registrations_.find(client_connection_id) !=
-        client_connection_id_registrations_.end()) {
-      client_connection_id_registrations_.erase(client_connection_id);
-      owner_->UnregisterClientConnectionId(client_connection_id);
-      compression_engine_.UnregisterClientConnectionId(client_connection_id);
-    }
-    return;
-  }
-
-  for (auto it = connect_udp_client_states_.begin();
-       it != connect_udp_client_states_.end();) {
-    if (it->encapsulated_client_session() == encapsulated_client_session) {
-      QUIC_DLOG(INFO) << "Removing state for stream ID " << it->stream()->id()
-                      << " context ID "
-                      << (it->context_id().has_value()
-                              ? absl::StrCat(it->context_id().value())
-                              : "none");
-      auto* stream = it->stream();
-      it = connect_udp_client_states_.erase(it);
-      if (!stream->write_side_closed()) {
-        stream->Reset(QUIC_STREAM_CANCELLED);
-      }
-    } else {
-      ++it;
-    }
-  }
-}
-
-void MasqueClientSession::OnConnectionClosed(
-    const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
-  QuicSpdyClientSession::OnConnectionClosed(frame, source);
-  // Close all encapsulated sessions.
-  for (const auto& client_state : connect_udp_client_states_) {
-    client_state.encapsulated_client_session()->CloseConnection(
-        QUIC_CONNECTION_CANCELLED, "Underlying MASQUE connection was closed",
-        ConnectionCloseBehavior::SILENT_CLOSE);
-  }
-}
-
-void MasqueClientSession::OnStreamClosed(QuicStreamId stream_id) {
-  if (QuicUtils::IsBidirectionalStreamId(stream_id, version()) &&
-      QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
-    QuicSpdyClientStream* stream =
-        reinterpret_cast<QuicSpdyClientStream*>(GetActiveStream(stream_id));
-    if (stream != nullptr) {
-      QUIC_DLOG(INFO) << "Stream " << stream_id
-                      << " closed, got response headers:"
-                      << stream->response_headers().DebugString();
-    }
-  }
-  for (auto it = connect_udp_client_states_.begin();
-       it != connect_udp_client_states_.end();) {
-    if (it->stream()->id() == stream_id) {
-      QUIC_DLOG(INFO) << "Stream " << stream_id
-                      << " was closed, removing state for context ID "
-                      << (it->context_id().has_value()
-                              ? absl::StrCat(it->context_id().value())
-                              : "none");
-      auto* encapsulated_client_session = it->encapsulated_client_session();
-      it = connect_udp_client_states_.erase(it);
-      encapsulated_client_session->CloseConnection(
-          QUIC_CONNECTION_CANCELLED,
-          "Underlying MASQUE CONNECT-UDP stream was closed",
-          ConnectionCloseBehavior::SILENT_CLOSE);
-    } else {
-      ++it;
-    }
-  }
-
-  QuicSpdyClientSession::OnStreamClosed(stream_id);
-}
-
-bool MasqueClientSession::OnSettingsFrame(const SettingsFrame& frame) {
-  QUIC_DLOG(INFO) << "Received SETTINGS: " << frame;
-  if (!QuicSpdyClientSession::OnSettingsFrame(frame)) {
-    QUIC_DLOG(ERROR) << "Failed to parse received settings";
-    return false;
-  }
-  if (!SupportsH3Datagram()) {
-    QUIC_DLOG(ERROR) << "Refusing to use MASQUE without HTTP/3 Datagrams";
-    return false;
-  }
-  QUIC_DLOG(INFO) << "Using HTTP Datagram: " << http_datagram_support();
-  owner_->OnSettingsReceived();
-  return true;
-}
-
-MasqueClientSession::ConnectUdpClientState::ConnectUdpClientState(
-    QuicSpdyClientStream* stream,
-    EncapsulatedClientSession* encapsulated_client_session,
-    MasqueClientSession* masque_session,
-    absl::optional<QuicDatagramContextId> context_id,
-    const QuicSocketAddress& target_server_address)
-    : stream_(stream),
-      encapsulated_client_session_(encapsulated_client_session),
-      masque_session_(masque_session),
-      context_id_(context_id),
-      target_server_address_(target_server_address) {
-  QUICHE_DCHECK_NE(masque_session_, nullptr);
-  this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
-  this->stream()->RegisterHttp3DatagramContextId(
-      this->context_id(), DatagramFormatType::UDP_PAYLOAD,
-      /*format_additional_data=*/absl::string_view(), this);
-}
-
-MasqueClientSession::ConnectUdpClientState::~ConnectUdpClientState() {
-  if (stream() != nullptr) {
-    stream()->UnregisterHttp3DatagramContextId(context_id());
-    stream()->UnregisterHttp3DatagramRegistrationVisitor();
-  }
-}
-
-MasqueClientSession::ConnectUdpClientState::ConnectUdpClientState(
-    MasqueClientSession::ConnectUdpClientState&& other) {
-  *this = std::move(other);
-}
-
-MasqueClientSession::ConnectUdpClientState&
-MasqueClientSession::ConnectUdpClientState::operator=(
-    MasqueClientSession::ConnectUdpClientState&& other) {
-  stream_ = other.stream_;
-  encapsulated_client_session_ = other.encapsulated_client_session_;
-  masque_session_ = other.masque_session_;
-  context_id_ = other.context_id_;
-  target_server_address_ = other.target_server_address_;
-  other.stream_ = nullptr;
-  if (stream() != nullptr) {
-    stream()->MoveHttp3DatagramRegistration(this);
-    stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
-  }
-  return *this;
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnHttp3Datagram(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
-  QUICHE_DCHECK_EQ(stream_id, stream()->id());
-  QUICHE_DCHECK(context_id == context_id_);
-  encapsulated_client_session_->ProcessPacket(payload, target_server_address_);
-  QUIC_DVLOG(1) << "Sent " << payload.size()
-                << " bytes to connection for stream ID " << stream_id
-                << " context ID "
-                << (context_id.has_value() ? absl::StrCat(context_id.value())
-                                           : "none");
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnContextReceived(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  if (stream_id != stream_->id()) {
-    QUIC_BUG(MASQUE client bad datagram context registration)
-        << "Registered stream ID " << stream_id << ", expected "
-        << stream_->id();
-    return;
-  }
-  if (format_type != DatagramFormatType::UDP_PAYLOAD) {
-    QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
-                    << DatagramFormatTypeToString(format_type);
-    return;
-  }
-  if (!format_additional_data.empty()) {
-    QUIC_DLOG(ERROR)
-        << "Received non-empty format additional data for context ID "
-        << (context_id_.has_value() ? context_id_.value() : 0)
-        << " on stream ID " << stream()->id();
-    masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream_->id();
-    return;
-  }
-  // Do nothing since the client registers first and we currently ignore
-  // extensions.
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnContextClosed(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    ContextCloseCode close_code, absl::string_view close_details) {
-  if (stream_id != stream_->id()) {
-    QUIC_BUG(MASQUE client bad datagram context registration)
-        << "Closed context on stream ID " << stream_id << ", expected "
-        << stream_->id();
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected close of context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream_->id();
-    return;
-  }
-  QUIC_DLOG(INFO) << "Received datagram context close with close code "
-                  << close_code << " close details \"" << close_details
-                  << "\" on stream ID " << stream_->id() << ", closing stream";
-  masque_session_->ResetStream(stream_->id(), QUIC_STREAM_CANCELLED);
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_client_session.h b/quic/masque/masque_client_session.h
deleted file mode 100644
index f8af4af..0000000
--- a/quic/masque/masque_client_session.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
-
-#include <string>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/masque/masque_compression_engine.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// QUIC client session for connection to MASQUE proxy. This session establishes
-// a connection to a MASQUE proxy and handles sending and receiving DATAGRAM
-// frames for operation of the MASQUE protocol. Multiple end-to-end encapsulated
-// sessions can then coexist inside this session. Once these are created, they
-// need to be registered with this session.
-class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
- public:
-  // Interface meant to be implemented by the owner of the
-  // MasqueClientSession instance.
-  class QUIC_NO_EXPORT Owner {
-   public:
-    virtual ~Owner() {}
-
-    // Notifies the owner that the client connection ID is no longer in use.
-    virtual void UnregisterClientConnectionId(
-        QuicConnectionId client_connection_id) = 0;
-
-    // Notifies the owner that a settings frame has been received.
-    virtual void OnSettingsReceived() = 0;
-  };
-  // Interface meant to be implemented by encapsulated client sessions, i.e.
-  // the end-to-end QUIC client sessions that run inside MASQUE encapsulation.
-  class QUIC_NO_EXPORT EncapsulatedClientSession {
-   public:
-    virtual ~EncapsulatedClientSession() {}
-
-    // Process packet that was just decapsulated.
-    virtual void ProcessPacket(absl::string_view packet,
-                               QuicSocketAddress target_server_address) = 0;
-
-    // Close the encapsulated connection.
-    virtual void CloseConnection(
-        QuicErrorCode error,
-        const std::string& details,
-        ConnectionCloseBehavior connection_close_behavior) = 0;
-  };
-
-  // Takes ownership of |connection|, but not of |crypto_config| or
-  // |push_promise_index| or |owner|. All pointers must be non-null. Caller
-  // must ensure that |push_promise_index| and |owner| stay valid for the
-  // lifetime of the newly created MasqueClientSession.
-  MasqueClientSession(MasqueMode masque_mode, const std::string& uri_template,
-                      const QuicConfig& config,
-                      const ParsedQuicVersionVector& supported_versions,
-                      QuicConnection* connection, const QuicServerId& server_id,
-                      QuicCryptoClientConfig* crypto_config,
-                      QuicClientPushPromiseIndex* push_promise_index,
-                      Owner* owner);
-
-  // Disallow copy and assign.
-  MasqueClientSession(const MasqueClientSession&) = delete;
-  MasqueClientSession& operator=(const MasqueClientSession&) = delete;
-
-  // From QuicSession.
-  void OnMessageReceived(absl::string_view message) override;
-  void OnMessageAcked(QuicMessageId message_id,
-                      QuicTime receive_timestamp) override;
-  void OnMessageLost(QuicMessageId message_id) override;
-  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                          ConnectionCloseSource source) override;
-  void OnStreamClosed(QuicStreamId stream_id) override;
-
-  // From QuicSpdySession.
-  bool OnSettingsFrame(const SettingsFrame& frame) override;
-
-  // Send encapsulated packet.
-  void SendPacket(QuicConnectionId client_connection_id,
-                  QuicConnectionId server_connection_id,
-                  absl::string_view packet,
-                  const QuicSocketAddress& target_server_address,
-                  EncapsulatedClientSession* encapsulated_client_session);
-
-  // Register encapsulated client. This allows clients that are encapsulated
-  // within this MASQUE session to indicate they own a given client connection
-  // ID so incoming packets with that connection ID are routed back to them.
-  // Callers must not register a second different |encapsulated_client_session|
-  // with the same |client_connection_id|. Every call must be matched with a
-  // call to UnregisterConnectionId.
-  void RegisterConnectionId(
-      QuicConnectionId client_connection_id,
-      EncapsulatedClientSession* encapsulated_client_session);
-
-  // Unregister encapsulated client. |client_connection_id| must match a
-  // value previously passed to RegisterConnectionId.
-  void UnregisterConnectionId(
-      QuicConnectionId client_connection_id,
-      EncapsulatedClientSession* encapsulated_client_session);
-
- private:
-  // State that the MasqueClientSession keeps for each CONNECT-UDP request.
-  class QUIC_NO_EXPORT ConnectUdpClientState
-      : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
-        public QuicSpdyStream::Http3DatagramVisitor {
-   public:
-    // |stream| and |encapsulated_client_session| must be valid for the lifetime
-    // of the ConnectUdpClientState.
-    explicit ConnectUdpClientState(
-        QuicSpdyClientStream* stream,
-        EncapsulatedClientSession* encapsulated_client_session,
-        MasqueClientSession* masque_session,
-        absl::optional<QuicDatagramContextId> context_id,
-        const QuicSocketAddress& target_server_address);
-
-    ~ConnectUdpClientState();
-
-    // Disallow copy but allow move.
-    ConnectUdpClientState(const ConnectUdpClientState&) = delete;
-    ConnectUdpClientState(ConnectUdpClientState&&);
-    ConnectUdpClientState& operator=(const ConnectUdpClientState&) = delete;
-    ConnectUdpClientState& operator=(ConnectUdpClientState&&);
-
-    QuicSpdyClientStream* stream() const { return stream_; }
-    EncapsulatedClientSession* encapsulated_client_session() const {
-      return encapsulated_client_session_;
-    }
-    absl::optional<QuicDatagramContextId> context_id() const {
-      return context_id_;
-    }
-    const QuicSocketAddress& target_server_address() const {
-      return target_server_address_;
-    }
-
-    // From QuicSpdyStream::Http3DatagramVisitor.
-    void OnHttp3Datagram(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         absl::string_view payload) override;
-
-    // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
-    void OnContextReceived(QuicStreamId stream_id,
-                           absl::optional<QuicDatagramContextId> context_id,
-                           DatagramFormatType format_type,
-                           absl::string_view format_additional_data) override;
-    void OnContextClosed(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         ContextCloseCode close_code,
-                         absl::string_view close_details) override;
-
-   private:
-    QuicSpdyClientStream* stream_;                            // Unowned.
-    EncapsulatedClientSession* encapsulated_client_session_;  // Unowned.
-    MasqueClientSession* masque_session_;                     // Unowned.
-    absl::optional<QuicDatagramContextId> context_id_;
-    QuicSocketAddress target_server_address_;
-  };
-
-  HttpDatagramSupport LocalHttpDatagramSupport() override {
-    return HttpDatagramSupport::kDraft00And04;
-  }
-
-  const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
-      const QuicSocketAddress& target_server_address,
-      EncapsulatedClientSession* encapsulated_client_session);
-
-  MasqueMode masque_mode_;
-  std::string uri_template_;
-  std::list<ConnectUdpClientState> connect_udp_client_states_;
-  absl::flat_hash_map<QuicConnectionId,
-                      EncapsulatedClientSession*,
-                      QuicConnectionIdHash>
-      client_connection_id_registrations_;
-  Owner* owner_;  // Unowned;
-  MasqueCompressionEngine compression_engine_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
diff --git a/quic/masque/masque_client_tools.cc b/quic/masque/masque_client_tools.cc
deleted file mode 100644
index 7ab9bd4..0000000
--- a/quic/masque/masque_client_tools.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_client_tools.h"
-#include "quic/masque/masque_encapsulated_epoll_client.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "quic/tools/quic_url.h"
-
-namespace quic {
-namespace tools {
-
-bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client,
-                                   QuicEpollServer* epoll_server,
-                                   std::string url_string,
-                                   bool disable_certificate_verification) {
-  const QuicUrl url(url_string, "https");
-  std::unique_ptr<ProofVerifier> proof_verifier;
-  if (disable_certificate_verification) {
-    proof_verifier = std::make_unique<FakeProofVerifier>();
-  } else {
-    proof_verifier = CreateDefaultProofVerifier(url.host());
-  }
-
-  // Build the client, and try to connect.
-  const QuicSocketAddress addr =
-      LookupAddress(url.host(), absl::StrCat(url.port()));
-  if (!addr.IsInitialized()) {
-    QUIC_LOG(ERROR) << "Unable to resolve address: " << url.host();
-    return false;
-  }
-  const QuicServerId server_id(url.host(), url.port());
-  auto client = std::make_unique<MasqueEncapsulatedEpollClient>(
-      addr, server_id, epoll_server, std::move(proof_verifier), masque_client);
-
-  if (client == nullptr) {
-    QUIC_LOG(ERROR) << "Failed to create MasqueEncapsulatedEpollClient for "
-                    << url_string;
-    return false;
-  }
-
-  client->set_initial_max_packet_length(kMasqueMaxEncapsulatedPacketSize);
-  client->set_drop_response_body(false);
-  if (!client->Initialize()) {
-    QUIC_LOG(ERROR) << "Failed to initialize MasqueEncapsulatedEpollClient for "
-                    << url_string;
-    return false;
-  }
-
-  if (!client->Connect()) {
-    QuicErrorCode error = client->session()->error();
-    QUIC_LOG(ERROR) << "Failed to connect with client "
-                    << client->session()->connection()->client_connection_id()
-                    << " server " << client->session()->connection_id()
-                    << " to " << url.HostPort()
-                    << ". Error: " << QuicErrorCodeToString(error);
-    return false;
-  }
-
-  QUIC_LOG(INFO) << "Connected client "
-                 << client->session()->connection()->client_connection_id()
-                 << " server " << client->session()->connection_id() << " for "
-                 << url_string;
-
-  // Construct the string body from flags, if provided.
-  // TODO(dschinazi) Add support for HTTP POST and non-empty bodies.
-  const std::string body = "";
-
-  // Construct a GET or POST request for supplied URL.
-  spdy::Http2HeaderBlock header_block;
-  header_block[":method"] = "GET";
-  header_block[":scheme"] = url.scheme();
-  header_block[":authority"] = url.HostPort();
-  header_block[":path"] = url.PathParamsQuery();
-
-  // Make sure to store the response, for later output.
-  client->set_store_response(true);
-
-  // Send the MASQUE init request.
-  client->SendRequestAndWaitForResponse(header_block, body,
-                                        /*fin=*/true);
-
-  if (!client->connected()) {
-    QUIC_LOG(ERROR) << "Request for " << url_string
-                    << " caused connection failure. Error: "
-                    << QuicErrorCodeToString(client->session()->error());
-    return false;
-  }
-
-  const int response_code = client->latest_response_code();
-  if (response_code < 200 || response_code >= 300) {
-    QUIC_LOG(ERROR) << "Request for " << url_string
-                    << " failed with HTTP response code " << response_code;
-    return false;
-  }
-
-  const std::string response_body = client->latest_response_body();
-  QUIC_LOG(INFO) << "Request succeeded for " << url_string << std::endl
-                 << response_body;
-
-  return true;
-}
-
-}  // namespace tools
-}  // namespace quic
diff --git a/quic/masque/masque_client_tools.h b/quic/masque/masque_client_tools.h
deleted file mode 100644
index 30727df..0000000
--- a/quic/masque/masque_client_tools.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
-
-#include "quic/masque/masque_epoll_client.h"
-
-namespace quic {
-namespace tools {
-
-// Sends an HTTP GET request for |url_string|, proxied over the MASQUE
-// connection represented by |masque_client|. A valid and owned |epoll_server|
-// is required. |disable_certificate_verification| allows disabling verification
-// of the HTTP server's TLS certificate.
-bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client,
-                                   QuicEpollServer* epoll_server,
-                                   std::string url_string,
-                                   bool disable_certificate_verification);
-
-}  // namespace tools
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
diff --git a/quic/masque/masque_compression_engine.cc b/quic/masque/masque_compression_engine.cc
deleted file mode 100644
index 69f75c0..0000000
--- a/quic/masque/masque_compression_engine.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_compression_engine.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_buffer_allocator.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-
-namespace {
-// |kFlowId0| is used to indicate creation of a new compression context.
-const QuicDatagramStreamId kFlowId0 = 0;
-
-enum MasqueAddressFamily : uint8_t {
-  MasqueAddressFamilyIPv4 = 4,
-  MasqueAddressFamilyIPv6 = 6,
-};
-
-}  // namespace
-
-MasqueCompressionEngine::MasqueCompressionEngine(
-    QuicSpdySession* masque_session)
-    : masque_session_(masque_session),
-      next_available_flow_id_(
-          masque_session_->perspective() == Perspective::IS_CLIENT ? 0 : 1) {}
-
-QuicDatagramStreamId MasqueCompressionEngine::FindOrCreateCompressionContext(
-    QuicConnectionId client_connection_id,
-    QuicConnectionId server_connection_id,
-    const QuicSocketAddress& server_address, bool client_connection_id_present,
-    bool server_connection_id_present, bool* validated) {
-  QuicDatagramStreamId flow_id = kFlowId0;
-  *validated = false;
-  for (const auto& kv : contexts_) {
-    const MasqueCompressionContext& context = kv.second;
-    if (context.server_address != server_address) {
-      continue;
-    }
-    if (client_connection_id_present &&
-        context.client_connection_id != client_connection_id) {
-      continue;
-    }
-    if (server_connection_id_present &&
-        context.server_connection_id != server_connection_id) {
-      continue;
-    }
-
-    flow_id = kv.first;
-    QUICHE_DCHECK_NE(flow_id, kFlowId0);
-    *validated = context.validated;
-    QUIC_DVLOG(1) << "Compressing using " << (*validated ? "" : "un")
-                  << "validated flow_id " << flow_id << " to "
-                  << context.server_address << " client "
-                  << context.client_connection_id << " server "
-                  << context.server_connection_id;
-    break;
-  }
-
-  if (flow_id != kFlowId0) {
-    // Found a compression context, use it.
-    return flow_id;
-  }
-
-  // Create new compression context.
-  next_available_flow_id_ += 2;
-  flow_id = next_available_flow_id_;
-  QUIC_DVLOG(1) << "Compression assigning new flow_id " << flow_id << " to "
-                << server_address << " client " << client_connection_id
-                << " server " << server_connection_id;
-  MasqueCompressionContext context;
-  context.client_connection_id = client_connection_id;
-  context.server_connection_id = server_connection_id;
-  context.server_address = server_address;
-  contexts_[flow_id] = context;
-
-  return flow_id;
-}
-
-bool MasqueCompressionEngine::WriteCompressedPacketToSlice(
-    QuicConnectionId client_connection_id,
-    QuicConnectionId server_connection_id,
-    const QuicSocketAddress& server_address,
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, QuicDatagramStreamId flow_id,
-    bool validated, uint8_t first_byte, bool long_header,
-    QuicDataReader* reader, QuicDataWriter* writer) {
-  if (validated) {
-    QUIC_DVLOG(1) << "Compressing using validated flow_id " << flow_id;
-    if (!writer->WriteVarInt62(flow_id)) {
-      QUIC_BUG(quic_bug_10981_1) << "Failed to write flow_id";
-      return false;
-    }
-  } else {
-    QUIC_DVLOG(1) << "Compressing using unvalidated flow_id " << flow_id;
-    if (!writer->WriteVarInt62(kFlowId0)) {
-      QUIC_BUG(quic_bug_10981_2) << "Failed to write kFlowId0";
-      return false;
-    }
-    if (!writer->WriteVarInt62(flow_id)) {
-      QUIC_BUG(quic_bug_10981_3) << "Failed to write flow_id";
-      return false;
-    }
-    if (!writer->WriteLengthPrefixedConnectionId(client_connection_id)) {
-      QUIC_BUG(quic_bug_10981_4) << "Failed to write client_connection_id";
-      return false;
-    }
-    if (!writer->WriteLengthPrefixedConnectionId(server_connection_id)) {
-      QUIC_BUG(quic_bug_10981_5) << "Failed to write server_connection_id";
-      return false;
-    }
-    if (!writer->WriteUInt16(server_address.port())) {
-      QUIC_BUG(quic_bug_10981_6) << "Failed to write port";
-      return false;
-    }
-    QuicIpAddress peer_ip = server_address.host();
-    QUICHE_DCHECK(peer_ip.IsInitialized());
-    std::string peer_ip_bytes = peer_ip.ToPackedString();
-    QUICHE_DCHECK(!peer_ip_bytes.empty());
-    uint8_t address_id;
-    if (peer_ip.address_family() == IpAddressFamily::IP_V6) {
-      address_id = MasqueAddressFamilyIPv6;
-      if (peer_ip_bytes.length() != QuicIpAddress::kIPv6AddressSize) {
-        QUIC_BUG(quic_bug_10981_7) << "Bad IPv6 length " << server_address;
-        return false;
-      }
-    } else if (peer_ip.address_family() == IpAddressFamily::IP_V4) {
-      address_id = MasqueAddressFamilyIPv4;
-      if (peer_ip_bytes.length() != QuicIpAddress::kIPv4AddressSize) {
-        QUIC_BUG(quic_bug_10981_8) << "Bad IPv4 length " << server_address;
-        return false;
-      }
-    } else {
-      QUIC_BUG(quic_bug_10981_9)
-          << "Unexpected server_address " << server_address;
-      return false;
-    }
-    if (!writer->WriteUInt8(address_id)) {
-      QUIC_BUG(quic_bug_10981_10) << "Failed to write address_id";
-      return false;
-    }
-    if (!writer->WriteStringPiece(peer_ip_bytes)) {
-      QUIC_BUG(quic_bug_10981_11) << "Failed to write IP address";
-      return false;
-    }
-  }
-  if (!writer->WriteUInt8(first_byte)) {
-    QUIC_BUG(quic_bug_10981_12) << "Failed to write first_byte";
-    return false;
-  }
-  if (long_header) {
-    QuicVersionLabel version_label;
-    if (!reader->ReadUInt32(&version_label)) {
-      QUIC_DLOG(ERROR) << "Failed to read version";
-      return false;
-    }
-    if (!writer->WriteUInt32(version_label)) {
-      QUIC_BUG(quic_bug_10981_13) << "Failed to write version";
-      return false;
-    }
-    QuicConnectionId packet_destination_connection_id,
-        packet_source_connection_id;
-    if (!reader->ReadLengthPrefixedConnectionId(
-            &packet_destination_connection_id) ||
-        !reader->ReadLengthPrefixedConnectionId(&packet_source_connection_id)) {
-      QUIC_DLOG(ERROR) << "Failed to parse long header connection IDs";
-      return false;
-    }
-    if (packet_destination_connection_id != destination_connection_id) {
-      QUIC_DLOG(ERROR) << "Long header packet's destination_connection_id "
-                       << packet_destination_connection_id
-                       << " does not match expected "
-                       << destination_connection_id;
-      return false;
-    }
-    if (packet_source_connection_id != source_connection_id) {
-      QUIC_DLOG(ERROR) << "Long header packet's source_connection_id "
-                       << packet_source_connection_id
-                       << " does not match expected " << source_connection_id;
-      return false;
-    }
-  } else {
-    QuicConnectionId packet_destination_connection_id;
-    if (!reader->ReadConnectionId(&packet_destination_connection_id,
-                                  destination_connection_id.length())) {
-      QUIC_DLOG(ERROR)
-          << "Failed to read short header packet's destination_connection_id";
-      return false;
-    }
-    if (packet_destination_connection_id != destination_connection_id) {
-      QUIC_DLOG(ERROR) << "Short header packet's destination_connection_id "
-                       << packet_destination_connection_id
-                       << " does not match expected "
-                       << destination_connection_id;
-      return false;
-    }
-  }
-  absl::string_view packet_payload = reader->ReadRemainingPayload();
-  if (!writer->WriteStringPiece(packet_payload)) {
-    QUIC_BUG(quic_bug_10981_14) << "Failed to write packet_payload";
-    return false;
-  }
-  return true;
-}
-
-void MasqueCompressionEngine::CompressAndSendPacket(
-    absl::string_view packet, QuicConnectionId client_connection_id,
-    QuicConnectionId server_connection_id,
-    const QuicSocketAddress& server_address) {
-  QUIC_DVLOG(2) << "Compressing client " << client_connection_id << " server "
-                << server_connection_id << "\n"
-                << quiche::QuicheTextUtils::HexDump(packet);
-  QUICHE_DCHECK(server_address.IsInitialized());
-  if (packet.empty()) {
-    QUIC_BUG(quic_bug_10981_15) << "Tried to send empty packet";
-    return;
-  }
-  QuicDataReader reader(packet.data(), packet.length());
-  uint8_t first_byte;
-  if (!reader.ReadUInt8(&first_byte)) {
-    QUIC_BUG(quic_bug_10981_16) << "Failed to read first_byte";
-    return;
-  }
-  const bool long_header = (first_byte & FLAGS_LONG_HEADER) != 0;
-  bool client_connection_id_present = true, server_connection_id_present = true;
-  QuicConnectionId destination_connection_id, source_connection_id;
-  if (masque_session_->perspective() == Perspective::IS_SERVER) {
-    destination_connection_id = client_connection_id;
-    source_connection_id = server_connection_id;
-    if (!long_header) {
-      server_connection_id_present = false;
-    }
-  } else {
-    destination_connection_id = server_connection_id;
-    source_connection_id = client_connection_id;
-    if (!long_header) {
-      client_connection_id_present = false;
-    }
-  }
-
-  bool validated = false;
-  QuicDatagramStreamId flow_id = FindOrCreateCompressionContext(
-      client_connection_id, server_connection_id, server_address,
-      client_connection_id_present, server_connection_id_present, &validated);
-
-  size_t slice_length = packet.length() - destination_connection_id.length();
-  if (long_header) {
-    slice_length -= sizeof(uint8_t) * 2 + source_connection_id.length();
-  }
-  if (validated) {
-    slice_length += QuicDataWriter::GetVarInt62Len(flow_id);
-  } else {
-    slice_length += QuicDataWriter::GetVarInt62Len(kFlowId0) +
-                    QuicDataWriter::GetVarInt62Len(flow_id) + sizeof(uint8_t) +
-                    client_connection_id.length() + sizeof(uint8_t) +
-                    server_connection_id.length() +
-                    sizeof(server_address.port()) + sizeof(uint8_t) +
-                    server_address.host().ToPackedString().length();
-  }
-  quiche::QuicheBuffer buffer(
-      masque_session_->connection()->helper()->GetStreamSendBufferAllocator(),
-      slice_length);
-  QuicDataWriter writer(buffer.size(), buffer.data());
-
-  if (!WriteCompressedPacketToSlice(
-          client_connection_id, server_connection_id, server_address,
-          destination_connection_id, source_connection_id, flow_id, validated,
-          first_byte, long_header, &reader, &writer)) {
-    return;
-  }
-
-  MessageResult message_result =
-      masque_session_->SendMessage(quiche::QuicheMemSlice(std::move(buffer)));
-
-  QUIC_DVLOG(1) << "Sent packet compressed with flow ID " << flow_id
-                << " and got message result " << message_result;
-}
-
-bool MasqueCompressionEngine::ParseCompressionContext(
-    QuicDataReader* reader, MasqueCompressionContext* context) {
-  QuicDatagramStreamId new_flow_id;
-  if (!reader->ReadVarInt62(&new_flow_id)) {
-    QUIC_DLOG(ERROR) << "Could not read new_flow_id";
-    return false;
-  }
-  QuicConnectionId new_client_connection_id;
-  if (!reader->ReadLengthPrefixedConnectionId(&new_client_connection_id)) {
-    QUIC_DLOG(ERROR) << "Could not read new_client_connection_id";
-    return false;
-  }
-  QuicConnectionId new_server_connection_id;
-  if (!reader->ReadLengthPrefixedConnectionId(&new_server_connection_id)) {
-    QUIC_DLOG(ERROR) << "Could not read new_server_connection_id";
-    return false;
-  }
-  uint16_t port;
-  if (!reader->ReadUInt16(&port)) {
-    QUIC_DLOG(ERROR) << "Could not read port";
-    return false;
-  }
-  uint8_t address_id;
-  if (!reader->ReadUInt8(&address_id)) {
-    QUIC_DLOG(ERROR) << "Could not read address_id";
-    return false;
-  }
-  size_t ip_bytes_length;
-  if (address_id == MasqueAddressFamilyIPv6) {
-    ip_bytes_length = QuicIpAddress::kIPv6AddressSize;
-  } else if (address_id == MasqueAddressFamilyIPv4) {
-    ip_bytes_length = QuicIpAddress::kIPv4AddressSize;
-  } else {
-    QUIC_DLOG(ERROR) << "Unknown address_id " << static_cast<int>(address_id);
-    return false;
-  }
-  char ip_bytes[QuicIpAddress::kMaxAddressSize];
-  if (!reader->ReadBytes(ip_bytes, ip_bytes_length)) {
-    QUIC_DLOG(ERROR) << "Could not read IP address";
-    return false;
-  }
-  QuicIpAddress ip_address;
-  ip_address.FromPackedString(ip_bytes, ip_bytes_length);
-  if (!ip_address.IsInitialized()) {
-    QUIC_BUG(quic_bug_10981_17) << "Failed to parse IP address";
-    return false;
-  }
-  QuicSocketAddress new_server_address = QuicSocketAddress(ip_address, port);
-  auto context_pair = contexts_.find(new_flow_id);
-  if (context_pair == contexts_.end()) {
-    context->client_connection_id = new_client_connection_id;
-    context->server_connection_id = new_server_connection_id;
-    context->server_address = new_server_address;
-    context->validated = true;
-    contexts_[new_flow_id] = *context;
-    QUIC_DVLOG(1) << "Registered new flow_id " << new_flow_id << " to "
-                  << new_server_address << " client "
-                  << new_client_connection_id << " server "
-                  << new_server_connection_id;
-  } else {
-    *context = context_pair->second;
-    if (context->client_connection_id != new_client_connection_id) {
-      QUIC_LOG(ERROR)
-          << "Received incorrect context registration for existing flow_id "
-          << new_flow_id << " mismatched client "
-          << context->client_connection_id << " " << new_client_connection_id;
-      return false;
-    }
-    if (context->server_connection_id != new_server_connection_id) {
-      QUIC_LOG(ERROR)
-          << "Received incorrect context registration for existing flow_id "
-          << new_flow_id << " mismatched server "
-          << context->server_connection_id << " " << new_server_connection_id;
-      return false;
-    }
-    if (context->server_address != new_server_address) {
-      QUIC_LOG(ERROR)
-          << "Received incorrect context registration for existing flow_id "
-          << new_flow_id << " mismatched server " << context->server_address
-          << " " << new_server_address;
-      return false;
-    }
-    if (!context->validated) {
-      context->validated = true;
-      contexts_[new_flow_id] = *context;
-      QUIC_DLOG(INFO) << "Successfully validated remotely-unvalidated flow_id "
-                      << new_flow_id << " to " << new_server_address
-                      << " client " << new_client_connection_id << " server "
-                      << new_server_connection_id;
-    } else {
-      QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
-                       "remotely-unvalidated flow_id "
-                    << new_flow_id << " to " << new_server_address << " client "
-                    << new_client_connection_id << " server "
-                    << new_server_connection_id;
-    }
-  }
-  return true;
-}
-
-bool MasqueCompressionEngine::WriteDecompressedPacket(
-    QuicDataReader* reader, const MasqueCompressionContext& context,
-    std::vector<char>* packet, bool* version_present) {
-  QuicConnectionId destination_connection_id, source_connection_id;
-  if (masque_session_->perspective() == Perspective::IS_SERVER) {
-    destination_connection_id = context.server_connection_id;
-    source_connection_id = context.client_connection_id;
-  } else {
-    destination_connection_id = context.client_connection_id;
-    source_connection_id = context.server_connection_id;
-  }
-
-  size_t packet_length =
-      reader->BytesRemaining() + destination_connection_id.length();
-  uint8_t first_byte;
-  if (!reader->ReadUInt8(&first_byte)) {
-    QUIC_DLOG(ERROR) << "Failed to read first_byte";
-    return false;
-  }
-  *version_present = (first_byte & FLAGS_LONG_HEADER) != 0;
-  if (*version_present) {
-    packet_length += sizeof(uint8_t) * 2 + source_connection_id.length();
-  }
-  *packet = std::vector<char>(packet_length);
-  QuicDataWriter writer(packet->size(), packet->data());
-  if (!writer.WriteUInt8(first_byte)) {
-    QUIC_BUG(quic_bug_10981_18) << "Failed to write first_byte";
-    return false;
-  }
-  if (*version_present) {
-    QuicVersionLabel version_label;
-    if (!reader->ReadUInt32(&version_label)) {
-      QUIC_DLOG(ERROR) << "Failed to read version";
-      return false;
-    }
-    if (!writer.WriteUInt32(version_label)) {
-      QUIC_BUG(quic_bug_10981_19) << "Failed to write version";
-      return false;
-    }
-    if (!writer.WriteLengthPrefixedConnectionId(destination_connection_id)) {
-      QUIC_BUG(quic_bug_10981_20)
-          << "Failed to write long header destination_connection_id";
-      return false;
-    }
-    if (!writer.WriteLengthPrefixedConnectionId(source_connection_id)) {
-      QUIC_BUG(quic_bug_10981_21)
-          << "Failed to write long header source_connection_id";
-      return false;
-    }
-  } else {
-    if (!writer.WriteConnectionId(destination_connection_id)) {
-      QUIC_BUG(quic_bug_10981_22)
-          << "Failed to write short header destination_connection_id";
-      return false;
-    }
-  }
-  absl::string_view payload = reader->ReadRemainingPayload();
-  if (!writer.WriteStringPiece(payload)) {
-    QUIC_BUG(quic_bug_10981_23) << "Failed to write payload";
-    return false;
-  }
-  return true;
-}
-
-bool MasqueCompressionEngine::DecompressDatagram(
-    absl::string_view datagram, QuicConnectionId* client_connection_id,
-    QuicConnectionId* server_connection_id, QuicSocketAddress* server_address,
-    std::vector<char>* packet, bool* version_present) {
-  QUIC_DVLOG(1) << "Decompressing DATAGRAM frame of length "
-                << datagram.length();
-  QuicDataReader reader(datagram);
-  QuicDatagramStreamId flow_id;
-  if (!reader.ReadVarInt62(&flow_id)) {
-    QUIC_DLOG(ERROR) << "Could not read flow_id";
-    return false;
-  }
-  MasqueCompressionContext context;
-  if (flow_id == kFlowId0) {
-    if (!ParseCompressionContext(&reader, &context)) {
-      return false;
-    }
-  } else {
-    auto context_pair = contexts_.find(flow_id);
-    if (context_pair == contexts_.end()) {
-      QUIC_DLOG(ERROR) << "Received unknown flow_id " << flow_id;
-      return false;
-    }
-    context = context_pair->second;
-
-    if (!context.validated) {
-      context.validated = true;
-      contexts_[flow_id] = context;
-      QUIC_DLOG(INFO) << "Successfully validated remotely-validated flow_id "
-                      << flow_id << " to " << context.server_address
-                      << " client " << context.client_connection_id
-                      << " server " << context.server_connection_id;
-    } else {
-      QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
-                       "remotely-validated flow_id "
-                    << flow_id << " to " << context.server_address << " client "
-                    << context.client_connection_id << " server "
-                    << context.server_connection_id;
-    }
-  }
-
-  if (!WriteDecompressedPacket(&reader, context, packet, version_present)) {
-    return false;
-  }
-
-  *server_address = context.server_address;
-  *client_connection_id = context.client_connection_id;
-  *server_connection_id = context.server_connection_id;
-
-  QUIC_DVLOG(2) << "Decompressed client " << context.client_connection_id
-                << " server " << context.server_connection_id << "\n"
-                << quiche::QuicheTextUtils::HexDump(
-                       absl::string_view(packet->data(), packet->size()));
-
-  return true;
-}
-
-void MasqueCompressionEngine::UnregisterClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  std::vector<QuicDatagramStreamId> flow_ids_to_remove;
-  for (const auto& kv : contexts_) {
-    const MasqueCompressionContext& context = kv.second;
-    if (context.client_connection_id == client_connection_id) {
-      flow_ids_to_remove.push_back(kv.first);
-    }
-  }
-  for (QuicDatagramStreamId flow_id : flow_ids_to_remove) {
-    contexts_.erase(flow_id);
-  }
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_compression_engine.h b/quic/masque/masque_compression_engine.h
deleted file mode 100644
index 581b950..0000000
--- a/quic/masque/masque_compression_engine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// MASQUE compression engine used by client and servers.
-// This class allows converting QUIC packets into a compressed form suitable
-// for sending over QUIC DATAGRAM frames. It leverages a flow identifier at the
-// start of each datagram to indicate which compression context was used to
-// compress this packet, or to create new compression contexts.
-// Compression contexts contain client and server connection IDs and the
-// server's IP and port. This allows compressing that information in most
-// packets without requiring access to the cryptographic keys of the end-to-end
-// encapsulated session. When the flow identifier is 0, the DATAGRAM contains
-// all the contents of the compression context. When the flow identifier is
-// non-zero, those fields are removed so the encapsulated QUIC packet is
-// transmitted without connection IDs and reassembled by the peer on
-// decompression. This only needs to contain the HTTP server's IP address since
-// the client's IP address is not visible to the HTTP server.
-
-class QUIC_NO_EXPORT MasqueCompressionEngine {
- public:
-  // Caller must ensure that |masque_session| has a lifetime longer than the
-  // newly constructed MasqueCompressionEngine.
-  explicit MasqueCompressionEngine(QuicSpdySession* masque_session);
-
-  // Disallow copy and assign.
-  MasqueCompressionEngine(const MasqueCompressionEngine&) = delete;
-  MasqueCompressionEngine& operator=(const MasqueCompressionEngine&) = delete;
-
-  // Compresses packet and sends it in a DATAGRAM frame over a MASQUE session.
-  // When used from MASQUE client to MASQUE server, the MASQUE server will then
-  // send the packet to the provided |server_address|.
-  // When used from MASQUE server to MASQUE client, the MASQUE client will then
-  // hand off the uncompressed packet to an encapsulated session that will treat
-  // it as having come from the provided |server_address|.
-  // The connection IDs are the one used by the encapsulated |packet|.
-  void CompressAndSendPacket(absl::string_view packet,
-                             QuicConnectionId client_connection_id,
-                             QuicConnectionId server_connection_id,
-                             const QuicSocketAddress& server_address);
-
-  // Decompresses received DATAGRAM frame contents from |datagram| and places
-  // them in |packet|. Reverses the transformation from CompressAndSendPacket.
-  // The connection IDs are the one used by the encapsulated |packet|.
-  // |server_address| will be filled with the |server_address| passed to
-  // CompressAndSendPacket. |version_present| will contain whether the
-  // encapsulated |packet| contains a Version field.
-  bool DecompressDatagram(absl::string_view datagram,
-                          QuicConnectionId* client_connection_id,
-                          QuicConnectionId* server_connection_id,
-                          QuicSocketAddress* server_address,
-                          std::vector<char>* packet, bool* version_present);
-
-  // Clears all entries referencing |client_connection_id| from the
-  // compression table.
-  void UnregisterClientConnectionId(QuicConnectionId client_connection_id);
-
- private:
-  struct QUIC_NO_EXPORT MasqueCompressionContext {
-    QuicConnectionId client_connection_id;
-    QuicConnectionId server_connection_id;
-    QuicSocketAddress server_address;
-    bool validated = false;
-  };
-
-  // Finds or creates a new compression context to use during compression.
-  // |client_connection_id_present| and |server_connection_id_present| indicate
-  // whether the corresponding connection ID is present in the current packet.
-  // |validated| will contain whether the compression context that matches
-  // these arguments is currently validated or not.
-  QuicDatagramStreamId FindOrCreateCompressionContext(
-      QuicConnectionId client_connection_id,
-      QuicConnectionId server_connection_id,
-      const QuicSocketAddress& server_address,
-      bool client_connection_id_present, bool server_connection_id_present,
-      bool* validated);
-
-  // Writes compressed packet to |slice| during compression.
-  bool WriteCompressedPacketToSlice(QuicConnectionId client_connection_id,
-                                    QuicConnectionId server_connection_id,
-                                    const QuicSocketAddress& server_address,
-                                    QuicConnectionId destination_connection_id,
-                                    QuicConnectionId source_connection_id,
-                                    QuicDatagramStreamId flow_id,
-                                    bool validated, uint8_t first_byte,
-                                    bool long_header, QuicDataReader* reader,
-                                    QuicDataWriter* writer);
-
-  // Parses compression context from flow ID 0 during decompression.
-  bool ParseCompressionContext(QuicDataReader* reader,
-                               MasqueCompressionContext* context);
-
-  // Writes decompressed packet to |packet| during decompression.
-  bool WriteDecompressedPacket(QuicDataReader* reader,
-                               const MasqueCompressionContext& context,
-                               std::vector<char>* packet,
-                               bool* version_present);
-
-  QuicSpdySession* masque_session_;  // Unowned.
-  absl::flat_hash_map<QuicDatagramStreamId, MasqueCompressionContext> contexts_;
-  QuicDatagramStreamId next_available_flow_id_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
diff --git a/quic/masque/masque_dispatcher.cc b/quic/masque/masque_dispatcher.cc
deleted file mode 100644
index c14e03d..0000000
--- a/quic/masque/masque_dispatcher.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_dispatcher.h"
-#include "quic/masque/masque_server_session.h"
-
-namespace quic {
-
-MasqueDispatcher::MasqueDispatcher(
-    MasqueMode masque_mode,
-    const QuicConfig* config,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicVersionManager* version_manager,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<QuicConnectionHelperInterface> helper,
-    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-    std::unique_ptr<QuicAlarmFactory> alarm_factory,
-    MasqueServerBackend* masque_server_backend,
-    uint8_t expected_server_connection_id_length)
-    : QuicSimpleDispatcher(config,
-                           crypto_config,
-                           version_manager,
-                           std::move(helper),
-                           std::move(session_helper),
-                           std::move(alarm_factory),
-                           masque_server_backend,
-                           expected_server_connection_id_length),
-      masque_mode_(masque_mode),
-      epoll_server_(epoll_server),
-      masque_server_backend_(masque_server_backend) {}
-
-std::unique_ptr<QuicSession> MasqueDispatcher::CreateQuicSession(
-    QuicConnectionId connection_id, const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
-    const ParsedQuicVersion& version,
-    const ParsedClientHello& /*parsed_chlo*/) {
-  // The MasqueServerSession takes ownership of |connection| below.
-  QuicConnection* connection =
-      new QuicConnection(connection_id, self_address, peer_address, helper(),
-                         alarm_factory(), writer(),
-                         /*owns_writer=*/false, Perspective::IS_SERVER,
-                         ParsedQuicVersionVector{version});
-
-  auto session = std::make_unique<MasqueServerSession>(
-      masque_mode_, config(), GetSupportedVersions(), connection, this, this,
-      epoll_server_, session_helper(), crypto_config(),
-      compressed_certs_cache(), masque_server_backend_);
-  session->Initialize();
-  return session;
-}
-
-bool MasqueDispatcher::OnFailedToDispatchPacket(
-    const ReceivedPacketInfo& packet_info) {
-  auto connection_id_registration = client_connection_id_registrations_.find(
-      packet_info.destination_connection_id);
-  if (connection_id_registration == client_connection_id_registrations_.end()) {
-    QUIC_DLOG(INFO) << "MasqueDispatcher failed to dispatch " << packet_info;
-    return false;
-  }
-  MasqueServerSession* masque_server_session =
-      connection_id_registration->second;
-  masque_server_session->HandlePacketFromServer(packet_info);
-  return true;
-}
-
-void MasqueDispatcher::RegisterClientConnectionId(
-    QuicConnectionId client_connection_id,
-    MasqueServerSession* masque_server_session) {
-  QUIC_DLOG(INFO) << "Registering encapsulated " << client_connection_id
-                  << " to MASQUE session "
-                  << masque_server_session->connection_id();
-
-  // Make sure we don't try to overwrite an existing registration with a
-  // different session.
-  QUIC_BUG_IF(quic_bug_12013_1,
-              client_connection_id_registrations_.find(client_connection_id) !=
-                      client_connection_id_registrations_.end() &&
-                  client_connection_id_registrations_[client_connection_id] !=
-                      masque_server_session)
-      << "Overwriting existing registration for " << client_connection_id;
-  client_connection_id_registrations_[client_connection_id] =
-      masque_server_session;
-}
-
-void MasqueDispatcher::UnregisterClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
-  client_connection_id_registrations_.erase(client_connection_id);
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_dispatcher.h b/quic/masque/masque_dispatcher.h
deleted file mode 100644
index 35c5e0f..0000000
--- a/quic/masque/masque_dispatcher.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/masque/masque_server_backend.h"
-#include "quic/masque/masque_server_session.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-
-namespace quic {
-
-// QUIC dispatcher that handles new MASQUE connections and can proxy traffic
-// between MASQUE clients and QUIC servers.
-class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher,
-                                        public MasqueServerSession::Visitor {
- public:
-  explicit MasqueDispatcher(
-      MasqueMode masque_mode,
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      QuicEpollServer* epoll_server,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      MasqueServerBackend* masque_server_backend,
-      uint8_t expected_server_connection_id_length);
-
-  // Disallow copy and assign.
-  MasqueDispatcher(const MasqueDispatcher&) = delete;
-  MasqueDispatcher& operator=(const MasqueDispatcher&) = delete;
-
-  // From QuicSimpleDispatcher.
-  std::unique_ptr<QuicSession> CreateQuicSession(
-      QuicConnectionId connection_id, const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address, absl::string_view alpn,
-      const ParsedQuicVersion& version,
-      const quic::ParsedClientHello& parsed_chlo) override;
-
-  bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info) override;
-
-  // From MasqueServerSession::Visitor.
-  void RegisterClientConnectionId(
-      QuicConnectionId client_connection_id,
-      MasqueServerSession* masque_server_session) override;
-
-  void UnregisterClientConnectionId(
-      QuicConnectionId client_connection_id) override;
-
- private:
-  MasqueMode masque_mode_;
-  QuicEpollServer* epoll_server_;               // Unowned.
-  MasqueServerBackend* masque_server_backend_;  // Unowned.
-  // Mapping from client connection IDs to server sessions, allows routing
-  // incoming packets to the right MASQUE connection.
-  absl::flat_hash_map<QuicConnectionId,
-                      MasqueServerSession*,
-                      QuicConnectionIdHash>
-      client_connection_id_registrations_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
diff --git a/quic/masque/masque_encapsulated_client_session.cc b/quic/masque/masque_encapsulated_client_session.cc
deleted file mode 100644
index 3d557c3..0000000
--- a/quic/masque/masque_encapsulated_client_session.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_encapsulated_client_session.h"
-
-namespace quic {
-
-MasqueEncapsulatedClientSession::MasqueEncapsulatedClientSession(
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection,
-    const QuicServerId& server_id,
-    QuicCryptoClientConfig* crypto_config,
-    QuicClientPushPromiseIndex* push_promise_index,
-    MasqueClientSession* masque_client_session)
-    : QuicSpdyClientSession(config,
-                            supported_versions,
-                            connection,
-                            server_id,
-                            crypto_config,
-                            push_promise_index),
-      masque_client_session_(masque_client_session) {}
-
-void MasqueEncapsulatedClientSession::ProcessPacket(
-    absl::string_view packet,
-    QuicSocketAddress server_address) {
-  QuicTime now = connection()->clock()->ApproximateNow();
-  QuicReceivedPacket received_packet(packet.data(), packet.length(), now);
-  connection()->ProcessUdpPacket(connection()->self_address(), server_address,
-                                 received_packet);
-}
-
-void MasqueEncapsulatedClientSession::CloseConnection(
-    QuicErrorCode error,
-    const std::string& details,
-    ConnectionCloseBehavior connection_close_behavior) {
-  connection()->CloseConnection(error, details, connection_close_behavior);
-}
-
-void MasqueEncapsulatedClientSession::OnConnectionClosed(
-    const QuicConnectionCloseFrame& frame,
-    ConnectionCloseSource source) {
-  QuicSpdyClientSession::OnConnectionClosed(frame, source);
-  masque_client_session_->UnregisterConnectionId(
-      connection()->client_connection_id(), this);
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_encapsulated_client_session.h b/quic/masque/masque_encapsulated_client_session.h
deleted file mode 100644
index 0952159..0000000
--- a/quic/masque/masque_encapsulated_client_session.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
-
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/masque/masque_client_session.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// QUIC client session for QUIC encapsulated in MASQUE. This client session is
-// maintained end-to-end between the client and the web-server (the MASQUE
-// session does not have access to the cryptographic keys for the end-to-end
-// session), but its packets are sent encapsulated inside DATAGRAM frames in a
-// MASQUE session, as opposed to regular QUIC packets. Multiple encapsulated
-// sessions can coexist inside a MASQUE session.
-class QUIC_NO_EXPORT MasqueEncapsulatedClientSession
-    : public QuicSpdyClientSession,
-      public MasqueClientSession::EncapsulatedClientSession {
- public:
-  // Takes ownership of |connection|, but not of |crypto_config| or
-  // |push_promise_index| or |masque_client_session|. All pointers must be
-  // non-null. Caller must ensure that |push_promise_index| and
-  // |masque_client_session| stay valid for the lifetime of the newly created
-  // MasqueEncapsulatedClientSession.
-  MasqueEncapsulatedClientSession(
-      const QuicConfig& config,
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      const QuicServerId& server_id,
-      QuicCryptoClientConfig* crypto_config,
-      QuicClientPushPromiseIndex* push_promise_index,
-      MasqueClientSession* masque_client_session);
-
-  // Disallow copy and assign.
-  MasqueEncapsulatedClientSession(const MasqueEncapsulatedClientSession&) =
-      delete;
-  MasqueEncapsulatedClientSession& operator=(
-      const MasqueEncapsulatedClientSession&) = delete;
-
-  // From MasqueClientSession::EncapsulatedClientSession.
-  void ProcessPacket(absl::string_view packet,
-                     QuicSocketAddress server_address) override;
-  void CloseConnection(
-      QuicErrorCode error,
-      const std::string& details,
-      ConnectionCloseBehavior connection_close_behavior) override;
-
-  // From QuicSession.
-  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                          ConnectionCloseSource source) override;
-
- private:
-  MasqueClientSession* masque_client_session_;  // Unowned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
diff --git a/quic/masque/masque_encapsulated_epoll_client.cc b/quic/masque/masque_encapsulated_epoll_client.cc
deleted file mode 100644
index 047d25c..0000000
--- a/quic/masque/masque_encapsulated_epoll_client.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_encapsulated_epoll_client.h"
-#include "quic/core/quic_utils.h"
-#include "quic/masque/masque_client_session.h"
-#include "quic/masque/masque_encapsulated_client_session.h"
-#include "quic/masque/masque_epoll_client.h"
-#include "quic/masque/masque_utils.h"
-
-namespace quic {
-
-namespace {
-
-// Custom packet writer that allows getting all of a connection's outgoing
-// packets.
-class MasquePacketWriter : public QuicPacketWriter {
- public:
-  explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client)
-      : client_(client) {}
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& /*self_address*/,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* /*options*/) override {
-    QUICHE_DCHECK(peer_address.IsInitialized());
-    QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
-                  << " bytes to " << peer_address;
-    absl::string_view packet(buffer, buf_len);
-    client_->masque_client()->masque_client_session()->SendPacket(
-        client_->session()->connection()->client_connection_id(),
-        client_->session()->connection()->connection_id(), packet, peer_address,
-        client_->masque_encapsulated_client_session());
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
-  bool IsWriteBlocked() const override { return false; }
-
-  void SetWritable() override {}
-
-  absl::optional<int> MessageTooBigErrorCode() const override {
-    return EMSGSIZE;
-  }
-
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& /*peer_address*/) const override {
-    return kMasqueMaxEncapsulatedPacketSize;
-  }
-
-  bool SupportsReleaseTime() const override { return false; }
-
-  bool IsBatchMode() const override { return false; }
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& /*self_address*/,
-      const QuicSocketAddress& /*peer_address*/) override {
-    return {nullptr, nullptr};
-  }
-
-  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-
- private:
-  MasqueEncapsulatedEpollClient* client_;  // Unowned.
-};
-
-// Custom network helper that allows injecting a custom packet writer in order
-// to get all of a connection's outgoing packets.
-class MasqueClientEpollNetworkHelper : public QuicClientEpollNetworkHelper {
- public:
-  MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server,
-                                 MasqueEncapsulatedEpollClient* client)
-      : QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {}
-  QuicPacketWriter* CreateQuicPacketWriter() override {
-    return new MasquePacketWriter(client_);
-  }
-
- private:
-  MasqueEncapsulatedEpollClient* client_;  // Unowned.
-};
-
-}  // namespace
-
-MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    MasqueEpollClient* masque_client)
-    : QuicClient(
-          server_address,
-          server_id,
-          MasqueSupportedVersions(),
-          MasqueEncapsulatedConfig(),
-          epoll_server,
-          std::make_unique<MasqueClientEpollNetworkHelper>(epoll_server, this),
-          std::move(proof_verifier)),
-      masque_client_(masque_client) {}
-
-MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
-  masque_client_->masque_client_session()->UnregisterConnectionId(
-      client_connection_id_, masque_encapsulated_client_session());
-}
-
-std::unique_ptr<QuicSession>
-MasqueEncapsulatedEpollClient::CreateQuicClientSession(
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection) {
-  QUIC_DLOG(INFO) << "Creating MASQUE encapsulated session for "
-                  << connection->connection_id();
-  return std::make_unique<MasqueEncapsulatedClientSession>(
-      *config(), supported_versions, connection, server_id(), crypto_config(),
-      push_promise_index(), masque_client_->masque_client_session());
-}
-
-MasqueEncapsulatedClientSession*
-MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
-  return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
-}
-
-QuicConnectionId MasqueEncapsulatedEpollClient::GetClientConnectionId() {
-  if (client_connection_id_.IsEmpty()) {
-    client_connection_id_ = QuicUtils::CreateRandomConnectionId();
-    masque_client_->masque_client_session()->RegisterConnectionId(
-        client_connection_id_, masque_encapsulated_client_session());
-  }
-  return client_connection_id_;
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_encapsulated_epoll_client.h b/quic/masque/masque_encapsulated_epoll_client.h
deleted file mode 100644
index 70f0732..0000000
--- a/quic/masque/masque_encapsulated_epoll_client.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
-
-#include "quic/masque/masque_encapsulated_client_session.h"
-#include "quic/masque/masque_epoll_client.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_client.h"
-
-namespace quic {
-
-// QUIC client for QUIC encapsulated in MASQUE.
-class QUIC_NO_EXPORT MasqueEncapsulatedEpollClient : public QuicClient {
- public:
-  MasqueEncapsulatedEpollClient(QuicSocketAddress server_address,
-                                const QuicServerId& server_id,
-                                QuicEpollServer* epoll_server,
-                                std::unique_ptr<ProofVerifier> proof_verifier,
-                                MasqueEpollClient* masque_client);
-  ~MasqueEncapsulatedEpollClient() override;
-
-  // Disallow copy and assign.
-  MasqueEncapsulatedEpollClient(const MasqueEncapsulatedEpollClient&) = delete;
-  MasqueEncapsulatedEpollClient& operator=(
-      const MasqueEncapsulatedEpollClient&) = delete;
-
-  // From QuicClient.
-  std::unique_ptr<QuicSession> CreateQuicClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection) override;
-
-  QuicConnectionId GetClientConnectionId() override;
-
-  // MASQUE client that this client is encapsulated in.
-  MasqueEpollClient* masque_client() { return masque_client_; }
-
-  // Client session for this client.
-  MasqueEncapsulatedClientSession* masque_encapsulated_client_session();
-
- private:
-  MasqueEpollClient* masque_client_;  // Unowned.
-  QuicConnectionId client_connection_id_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
diff --git a/quic/masque/masque_epoll_client.cc b/quic/masque/masque_epoll_client.cc
deleted file mode 100644
index bfb4636..0000000
--- a/quic/masque/masque_epoll_client.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_epoll_client.h"
-
-#include <string>
-
-#include "absl/memory/memory.h"
-#include "quic/masque/masque_client_session.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/tools/quic_url.h"
-
-namespace quic {
-
-MasqueEpollClient::MasqueEpollClient(
-    QuicSocketAddress server_address, const QuicServerId& server_id,
-    MasqueMode masque_mode, QuicEpollServer* epoll_server,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    const std::string& uri_template)
-    : QuicClient(server_address, server_id, MasqueSupportedVersions(),
-                 epoll_server, std::move(proof_verifier)),
-      masque_mode_(masque_mode),
-      uri_template_(uri_template) {}
-
-std::unique_ptr<QuicSession> MasqueEpollClient::CreateQuicClientSession(
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection) {
-  QUIC_DLOG(INFO) << "Creating MASQUE session for "
-                  << connection->connection_id();
-  return std::make_unique<MasqueClientSession>(
-      masque_mode_, uri_template_, *config(), supported_versions, connection,
-      server_id(), crypto_config(), push_promise_index(), this);
-}
-
-MasqueClientSession* MasqueEpollClient::masque_client_session() {
-  return static_cast<MasqueClientSession*>(QuicClient::session());
-}
-
-QuicConnectionId MasqueEpollClient::connection_id() {
-  return masque_client_session()->connection_id();
-}
-
-std::string MasqueEpollClient::authority() const {
-  QuicUrl url(uri_template_);
-  return absl::StrCat(url.host(), ":", url.port());
-}
-
-// static
-std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
-    const std::string& uri_template, MasqueMode masque_mode,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<ProofVerifier> proof_verifier) {
-  QuicUrl url(uri_template);
-  std::string host = url.host();
-  uint16_t port = url.port();
-  // Build the masque_client, and try to connect.
-  QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
-  if (!addr.IsInitialized()) {
-    QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
-    return nullptr;
-  }
-  QuicServerId server_id(host, port);
-  // Use absl::WrapUnique(new MasqueEpollClient(...)) instead of
-  // std::make_unique<MasqueEpollClient>(...) because the constructor for
-  // MasqueEpollClient is private and therefore not accessible from make_unique.
-  auto masque_client = absl::WrapUnique(
-      new MasqueEpollClient(addr, server_id, masque_mode, epoll_server,
-                            std::move(proof_verifier), uri_template));
-
-  if (masque_client == nullptr) {
-    QUIC_LOG(ERROR) << "Failed to create masque_client";
-    return nullptr;
-  }
-
-  masque_client->set_initial_max_packet_length(kMasqueMaxOuterPacketSize);
-  masque_client->set_drop_response_body(false);
-  if (!masque_client->Initialize()) {
-    QUIC_LOG(ERROR) << "Failed to initialize masque_client";
-    return nullptr;
-  }
-  if (!masque_client->Connect()) {
-    QuicErrorCode error = masque_client->session()->error();
-    QUIC_LOG(ERROR) << "Failed to connect to " << host << ":" << port
-                    << ". Error: " << QuicErrorCodeToString(error);
-    return nullptr;
-  }
-
-  if (!masque_client->WaitUntilSettingsReceived()) {
-    QUIC_LOG(ERROR) << "Failed to receive settings";
-    return nullptr;
-  }
-
-  if (masque_client->masque_mode() == MasqueMode::kLegacy) {
-    // Construct the legacy mode init request.
-    spdy::Http2HeaderBlock header_block;
-    header_block[":method"] = "POST";
-    header_block[":scheme"] = "https";
-    header_block[":authority"] = masque_client->authority();
-    header_block[":path"] = "/.well-known/masque/init";
-    std::string body = "foo";
-
-    // Make sure to store the response, for later output.
-    masque_client->set_store_response(true);
-
-    // Send the MASQUE init command.
-    masque_client->SendRequestAndWaitForResponse(header_block, body,
-                                                 /*fin=*/true);
-
-    if (!masque_client->connected()) {
-      QUIC_LOG(ERROR)
-          << "MASQUE init request caused connection failure. Error: "
-          << QuicErrorCodeToString(masque_client->session()->error());
-      return nullptr;
-    }
-
-    const int response_code = masque_client->latest_response_code();
-    if (response_code != 200) {
-      QUIC_LOG(ERROR) << "MASQUE init request failed with HTTP response code "
-                      << response_code;
-      return nullptr;
-    }
-  }
-  return masque_client;
-}
-
-void MasqueEpollClient::OnSettingsReceived() {
-  settings_received_ = true;
-}
-
-bool MasqueEpollClient::WaitUntilSettingsReceived() {
-  while (connected() && !settings_received_) {
-    network_helper()->RunEventLoop();
-  }
-  return connected() && settings_received_;
-}
-
-void MasqueEpollClient::UnregisterClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  std::string body(client_connection_id.data(), client_connection_id.length());
-
-  // Construct a GET or POST request for supplied URL.
-  spdy::Http2HeaderBlock header_block;
-  header_block[":method"] = "POST";
-  header_block[":scheme"] = "https";
-  header_block[":authority"] = authority();
-  header_block[":path"] = "/.well-known/masque/unregister";
-
-  // Make sure to store the response, for later output.
-  set_store_response(true);
-
-  // Send the MASQUE unregister command.
-  SendRequest(header_block, body, /*fin=*/true);
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_epoll_client.h b/quic/masque/masque_epoll_client.h
deleted file mode 100644
index b6e0087..0000000
--- a/quic/masque/masque_epoll_client.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
-
-#include <string>
-
-#include "quic/masque/masque_client_session.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_client.h"
-#include "quic/tools/quic_url.h"
-
-namespace quic {
-
-// QUIC client that implements MASQUE.
-class QUIC_NO_EXPORT MasqueEpollClient : public QuicClient,
-                                         public MasqueClientSession::Owner {
- public:
-  // Constructs a MasqueEpollClient, performs a synchronous DNS lookup.
-  static std::unique_ptr<MasqueEpollClient> Create(
-      const std::string& uri_template, MasqueMode masque_mode,
-      QuicEpollServer* epoll_server,
-      std::unique_ptr<ProofVerifier> proof_verifier);
-
-  // From QuicClient.
-  std::unique_ptr<QuicSession> CreateQuicClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection) override;
-
-  // Client session for this client.
-  MasqueClientSession* masque_client_session();
-
-  // Convenience accessor for the underlying connection ID.
-  QuicConnectionId connection_id();
-
-  // From MasqueClientSession::Owner.
-  void OnSettingsReceived() override;
-  // Send a MASQUE client connection ID unregister command to the server.
-  void UnregisterClientConnectionId(
-      QuicConnectionId client_connection_id) override;
-
-  MasqueMode masque_mode() const { return masque_mode_; }
-
- private:
-  // Constructor is private, use Create() instead.
-  MasqueEpollClient(QuicSocketAddress server_address,
-                    const QuicServerId& server_id, MasqueMode masque_mode,
-                    QuicEpollServer* epoll_server,
-                    std::unique_ptr<ProofVerifier> proof_verifier,
-                    const std::string& uri_template);
-
-  // Wait synchronously until we receive the peer's settings. Returns whether
-  // they were received.
-  bool WaitUntilSettingsReceived();
-
-  std::string authority() const;
-
-  // Disallow copy and assign.
-  MasqueEpollClient(const MasqueEpollClient&) = delete;
-  MasqueEpollClient& operator=(const MasqueEpollClient&) = delete;
-
-  MasqueMode masque_mode_;
-  std::string uri_template_;
-  bool settings_received_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
diff --git a/quic/masque/masque_epoll_server.cc b/quic/masque/masque_epoll_server.cc
deleted file mode 100644
index e8a0850..0000000
--- a/quic/masque/masque_epoll_server.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_epoll_server.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/masque/masque_dispatcher.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-
-namespace quic {
-
-MasqueEpollServer::MasqueEpollServer(MasqueMode masque_mode,
-                                     MasqueServerBackend* masque_server_backend)
-    : QuicServer(CreateDefaultProofSource(),
-                 masque_server_backend,
-                 MasqueSupportedVersions()),
-      masque_mode_(masque_mode),
-      masque_server_backend_(masque_server_backend) {}
-
-QuicDispatcher* MasqueEpollServer::CreateQuicDispatcher() {
-  return new MasqueDispatcher(
-      masque_mode_, &config(), &crypto_config(), version_manager(),
-      epoll_server(),
-      std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
-                                                  QuicAllocator::BUFFER_POOL),
-      std::make_unique<QuicSimpleCryptoServerStreamHelper>(),
-      std::make_unique<QuicEpollAlarmFactory>(epoll_server()),
-      masque_server_backend_, expected_server_connection_id_length());
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_epoll_server.h b/quic/masque/masque_epoll_server.h
deleted file mode 100644
index 88161ee..0000000
--- a/quic/masque/masque_epoll_server.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
-
-#include "quic/masque/masque_server_backend.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-
-// QUIC server that implements MASQUE.
-class QUIC_NO_EXPORT MasqueEpollServer : public QuicServer {
- public:
-  explicit MasqueEpollServer(MasqueMode masque_mode,
-                             MasqueServerBackend* masque_server_backend);
-
-  // Disallow copy and assign.
-  MasqueEpollServer(const MasqueEpollServer&) = delete;
-  MasqueEpollServer& operator=(const MasqueEpollServer&) = delete;
-
-  // From QuicServer.
-  QuicDispatcher* CreateQuicDispatcher() override;
-
- private:
-  MasqueMode masque_mode_;
-  MasqueServerBackend* masque_server_backend_;  // Unowned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
diff --git a/quic/masque/masque_server_backend.cc b/quic/masque/masque_server_backend.cc
deleted file mode 100644
index 280ab5e..0000000
--- a/quic/masque/masque_server_backend.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_server_backend.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-MasqueServerBackend::MasqueServerBackend(MasqueMode masque_mode,
-                                         const std::string& server_authority,
-                                         const std::string& cache_directory)
-    : masque_mode_(masque_mode), server_authority_(server_authority) {
-  if (!cache_directory.empty()) {
-    QuicMemoryCacheBackend::InitializeBackend(cache_directory);
-  }
-}
-
-bool MasqueServerBackend::MaybeHandleMasqueRequest(
-    const spdy::Http2HeaderBlock& request_headers,
-    const std::string& request_body,
-    QuicSimpleServerBackend::RequestHandler* request_handler) {
-  auto method_pair = request_headers.find(":method");
-  if (method_pair == request_headers.end()) {
-    // Request is missing a method.
-    return false;
-  }
-  absl::string_view method = method_pair->second;
-  std::string masque_path = "";
-  if (masque_mode_ == MasqueMode::kLegacy) {
-    auto path_pair = request_headers.find(":path");
-    auto scheme_pair = request_headers.find(":scheme");
-    if (path_pair == request_headers.end() ||
-        scheme_pair == request_headers.end()) {
-      // This request is missing required headers.
-      return false;
-    }
-    absl::string_view path = path_pair->second;
-    absl::string_view scheme = scheme_pair->second;
-    if (scheme != "https" || method != "POST" || request_body.empty()) {
-      // MASQUE requests MUST be a non-empty https POST.
-      return false;
-    }
-
-    if (path.rfind("/.well-known/masque/", 0) != 0) {
-      // This request is not a MASQUE path.
-      return false;
-    }
-    masque_path = std::string(path.substr(sizeof("/.well-known/masque/") - 1));
-  } else {
-    QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
-    auto protocol_pair = request_headers.find(":protocol");
-    if (method != "CONNECT" || protocol_pair == request_headers.end() ||
-        protocol_pair->second != "connect-udp") {
-      // This is not a MASQUE request.
-      return false;
-    }
-  }
-
-  if (!server_authority_.empty()) {
-    auto authority_pair = request_headers.find(":authority");
-    if (authority_pair == request_headers.end()) {
-      // Cannot enforce missing authority.
-      return false;
-    }
-    absl::string_view authority = authority_pair->second;
-    if (server_authority_ != authority) {
-      // This request does not match server_authority.
-      return false;
-    }
-  }
-
-  auto it = backend_client_states_.find(request_handler->connection_id());
-  if (it == backend_client_states_.end()) {
-    QUIC_LOG(ERROR) << "Could not find backend client for "
-                    << masque_path << request_headers.DebugString();
-    return false;
-  }
-
-  BackendClient* backend_client = it->second.backend_client;
-
-  std::unique_ptr<QuicBackendResponse> response =
-      backend_client->HandleMasqueRequest(masque_path, request_headers,
-                                          request_body, request_handler);
-  if (response == nullptr) {
-    QUIC_LOG(ERROR) << "Backend client did not process request for "
-                    << masque_path << request_headers.DebugString();
-    return false;
-  }
-
-  QUIC_DLOG(INFO) << "Sending MASQUE response for "
-                  << request_headers.DebugString();
-
-  request_handler->OnResponseBackendComplete(response.get());
-  it->second.responses.emplace_back(std::move(response));
-
-  return true;
-}
-
-void MasqueServerBackend::FetchResponseFromBackend(
-    const spdy::Http2HeaderBlock& request_headers,
-    const std::string& request_body,
-    QuicSimpleServerBackend::RequestHandler* request_handler) {
-  if (MaybeHandleMasqueRequest(request_headers, request_body,
-                               request_handler)) {
-    // Request was handled as a MASQUE request.
-    return;
-  }
-  QUIC_DLOG(INFO) << "Fetching non-MASQUE response for "
-                  << request_headers.DebugString();
-  QuicMemoryCacheBackend::FetchResponseFromBackend(
-      request_headers, request_body, request_handler);
-}
-
-void MasqueServerBackend::CloseBackendResponseStream(
-    QuicSimpleServerBackend::RequestHandler* request_handler) {
-  QUIC_DLOG(INFO) << "Closing response stream";
-  QuicMemoryCacheBackend::CloseBackendResponseStream(request_handler);
-}
-
-void MasqueServerBackend::RegisterBackendClient(QuicConnectionId connection_id,
-                                                BackendClient* backend_client) {
-  QUIC_DLOG(INFO) << "Registering backend client for " << connection_id;
-  QUIC_BUG_IF(quic_bug_12005_1, backend_client_states_.find(connection_id) !=
-                                    backend_client_states_.end())
-      << connection_id << " already in backend clients map";
-  backend_client_states_[connection_id] =
-      BackendClientState{backend_client, {}};
-}
-
-void MasqueServerBackend::RemoveBackendClient(QuicConnectionId connection_id) {
-  QUIC_DLOG(INFO) << "Removing backend client for " << connection_id;
-  backend_client_states_.erase(connection_id);
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_server_backend.h b/quic/masque/masque_server_backend.h
deleted file mode 100644
index 4f0e10d..0000000
--- a/quic/masque/masque_server_backend.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-
-namespace quic {
-
-// QUIC server backend that understands MASQUE requests, but otherwise answers
-// HTTP queries using an in-memory cache.
-class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend {
- public:
-  // Interface meant to be implemented by the owner of the MasqueServerBackend
-  // instance.
-  class QUIC_NO_EXPORT BackendClient {
-   public:
-    virtual std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
-        const std::string& masque_path,
-        const spdy::Http2HeaderBlock& request_headers,
-        const std::string& request_body,
-        QuicSimpleServerBackend::RequestHandler* request_handler) = 0;
-    virtual ~BackendClient() = default;
-  };
-
-  explicit MasqueServerBackend(MasqueMode masque_mode,
-                               const std::string& server_authority,
-                               const std::string& cache_directory);
-
-  // Disallow copy and assign.
-  MasqueServerBackend(const MasqueServerBackend&) = delete;
-  MasqueServerBackend& operator=(const MasqueServerBackend&) = delete;
-
-  // From QuicMemoryCacheBackend.
-  void FetchResponseFromBackend(
-      const spdy::Http2HeaderBlock& request_headers,
-      const std::string& request_body,
-      QuicSimpleServerBackend::RequestHandler* request_handler) override;
-
-  void CloseBackendResponseStream(
-      QuicSimpleServerBackend::RequestHandler* request_handler) override;
-
-  // Register backend client that can handle MASQUE requests.
-  void RegisterBackendClient(QuicConnectionId connection_id,
-                             BackendClient* backend_client);
-
-  // Unregister backend client.
-  void RemoveBackendClient(QuicConnectionId connection_id);
-
- private:
-  // Handle MASQUE request.
-  bool MaybeHandleMasqueRequest(
-      const spdy::Http2HeaderBlock& request_headers,
-      const std::string& request_body,
-      QuicSimpleServerBackend::RequestHandler* request_handler);
-
-  MasqueMode masque_mode_;
-  std::string server_authority_;
-
-  struct QUIC_NO_EXPORT BackendClientState {
-    BackendClient* backend_client;
-    std::vector<std::unique_ptr<QuicBackendResponse>> responses;
-  };
-  absl::
-      flat_hash_map<QuicConnectionId, BackendClientState, QuicConnectionIdHash>
-          backend_client_states_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
diff --git a/quic/masque/masque_server_bin.cc b/quic/masque/masque_server_bin.cc
deleted file mode 100644
index 0a66938..0000000
--- a/quic/masque/masque_server_bin.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is reponsible for the masque_server binary. It allows testing
-// our MASQUE server code by creating a MASQUE proxy that relays HTTP/3
-// requests to web servers tunnelled over MASQUE connections.
-// e.g.: masque_server
-
-#include <memory>
-
-#include "quic/masque/masque_epoll_server.h"
-#include "quic/masque/masque_server_backend.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/platform/api/quiche_system_event_loop.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 9661,
-                                "The port the MASQUE server will listen on.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, cache_dir, "",
-    "Specifies the directory used during QuicHttpResponseCache "
-    "construction to seed the cache. Cache directory can be "
-    "generated using `wget -p --save-headers <url>`");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, server_authority, "",
-    "Specifies the authority over which the server will accept MASQUE "
-    "requests. Defaults to empty which allows all authorities.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
-                                "Allows setting MASQUE mode, valid values are "
-                                "open and legacy. Defaults to open.");
-
-int main(int argc, char* argv[]) {
-  quiche::QuicheSystemEventLoop event_loop("masque_server");
-  const char* usage = "Usage: masque_server [options]";
-  std::vector<std::string> non_option_args =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-  if (!non_option_args.empty()) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    return 0;
-  }
-
-  quic::MasqueMode masque_mode = quic::MasqueMode::kOpen;
-  std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
-  if (mode_string == "legacy") {
-    masque_mode = quic::MasqueMode::kLegacy;
-  } else if (!mode_string.empty() && mode_string != "open") {
-    std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
-    return 1;
-  }
-
-  auto backend = std::make_unique<quic::MasqueServerBackend>(
-      masque_mode, GetQuicFlag(FLAGS_server_authority),
-      GetQuicFlag(FLAGS_cache_dir));
-
-  auto server =
-      std::make_unique<quic::MasqueEpollServer>(masque_mode, backend.get());
-
-  if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
-          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
-    return 1;
-  }
-
-  std::cerr << "Started " << masque_mode << " MASQUE server" << std::endl;
-  server->HandleEventsForever();
-  return 0;
-}
diff --git a/quic/masque/masque_server_session.cc b/quic/masque/masque_server_session.cc
deleted file mode 100644
index 6484d8a..0000000
--- a/quic/masque/masque_server_session.cc
+++ /dev/null
@@ -1,628 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_server_session.h"
-
-#include <netdb.h>
-
-#include <cstddef>
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_url_utils.h"
-
-namespace quic {
-
-namespace {
-// RAII wrapper for QuicUdpSocketFd.
-class FdWrapper {
- public:
-  // Takes ownership of |fd| and closes the file descriptor on destruction.
-  explicit FdWrapper(int address_family) {
-    QuicUdpSocketApi socket_api;
-    fd_ =
-        socket_api.Create(address_family,
-                          /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
-                          /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
-  }
-
-  ~FdWrapper() {
-    if (fd_ == kQuicInvalidSocketFd) {
-      return;
-    }
-    QuicUdpSocketApi socket_api;
-    socket_api.Destroy(fd_);
-  }
-
-  // Hands ownership of the file descriptor to the caller.
-  QuicUdpSocketFd extract_fd() {
-    QuicUdpSocketFd fd = fd_;
-    fd_ = kQuicInvalidSocketFd;
-    return fd;
-  }
-
-  // Keeps ownership of the file descriptor.
-  QuicUdpSocketFd fd() { return fd_; }
-
-  // Disallow copy and move.
-  FdWrapper(const FdWrapper&) = delete;
-  FdWrapper(FdWrapper&&) = delete;
-  FdWrapper& operator=(const FdWrapper&) = delete;
-  FdWrapper& operator=(FdWrapper&&) = delete;
-
- private:
-  QuicUdpSocketFd fd_;
-};
-
-std::unique_ptr<QuicBackendResponse> CreateBackendErrorResponse(
-    absl::string_view status, absl::string_view error_details) {
-  spdy::Http2HeaderBlock response_headers;
-  response_headers[":status"] = status;
-  response_headers["masque-debug-info"] = error_details;
-  auto response = std::make_unique<QuicBackendResponse>();
-  response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
-  response->set_headers(std::move(response_headers));
-  return response;
-}
-
-}  // namespace
-
-MasqueServerSession::MasqueServerSession(
-    MasqueMode masque_mode, const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
-    QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    MasqueServerBackend* masque_server_backend)
-    : QuicSimpleServerSession(config, supported_versions, connection, visitor,
-                              helper, crypto_config, compressed_certs_cache,
-                              masque_server_backend),
-      masque_server_backend_(masque_server_backend),
-      owner_(owner),
-      epoll_server_(epoll_server),
-      compression_engine_(this),
-      masque_mode_(masque_mode) {
-  // Artificially increase the max packet length to 1350 to ensure we can fit
-  // QUIC packets inside DATAGRAM frames.
-  // TODO(b/181606597) Remove this workaround once we use PMTUD.
-  connection->SetMaxPacketLength(kDefaultMaxPacketSize);
-
-  masque_server_backend_->RegisterBackendClient(connection_id(), this);
-  QUICHE_DCHECK_NE(epoll_server_, nullptr);
-}
-
-void MasqueServerSession::OnMessageReceived(absl::string_view message) {
-  if (masque_mode_ == MasqueMode::kLegacy) {
-    QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
-    QuicConnectionId client_connection_id, server_connection_id;
-    QuicSocketAddress target_server_address;
-    std::vector<char> packet;
-    bool version_present;
-    if (!compression_engine_.DecompressDatagram(
-            message, &client_connection_id, &server_connection_id,
-            &target_server_address, &packet, &version_present)) {
-      return;
-    }
-
-    QUIC_DVLOG(1) << "Received packet of length " << packet.size() << " for "
-                  << target_server_address << " client "
-                  << client_connection_id;
-
-    if (version_present) {
-      if (client_connection_id.length() != kQuicDefaultConnectionIdLength) {
-        QUIC_DLOG(ERROR)
-            << "Dropping long header with invalid client_connection_id "
-            << client_connection_id;
-        return;
-      }
-      owner_->RegisterClientConnectionId(client_connection_id, this);
-    }
-
-    WriteResult write_result = connection()->writer()->WritePacket(
-        packet.data(), packet.size(), connection()->self_address().host(),
-        target_server_address, nullptr);
-    QUIC_DVLOG(1) << "Got " << write_result << " for " << packet.size()
-                  << " bytes to " << target_server_address;
-    return;
-  }
-  QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
-  QuicSpdySession::OnMessageReceived(message);
-}
-
-void MasqueServerSession::OnMessageAcked(QuicMessageId message_id,
-                                         QuicTime /*receive_timestamp*/) {
-  QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
-}
-
-void MasqueServerSession::OnMessageLost(QuicMessageId message_id) {
-  QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost";
-}
-
-void MasqueServerSession::OnConnectionClosed(
-    const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
-  QuicSimpleServerSession::OnConnectionClosed(frame, source);
-  QUIC_DLOG(INFO) << "Closing connection for " << connection_id();
-  masque_server_backend_->RemoveBackendClient(connection_id());
-  // Clearing this state will close all sockets.
-  connect_udp_server_states_.clear();
-}
-
-void MasqueServerSession::OnStreamClosed(QuicStreamId stream_id) {
-  connect_udp_server_states_.remove_if(
-      [stream_id](const ConnectUdpServerState& connect_udp) {
-        return connect_udp.stream()->id() == stream_id;
-      });
-
-  QuicSimpleServerSession::OnStreamClosed(stream_id);
-}
-
-std::unique_ptr<QuicBackendResponse> MasqueServerSession::HandleMasqueRequest(
-    const std::string& masque_path,
-    const spdy::Http2HeaderBlock& request_headers,
-    const std::string& request_body,
-    QuicSimpleServerBackend::RequestHandler* request_handler) {
-  if (masque_mode_ != MasqueMode::kLegacy) {
-    auto path_pair = request_headers.find(":path");
-    auto scheme_pair = request_headers.find(":scheme");
-    auto method_pair = request_headers.find(":method");
-    auto protocol_pair = request_headers.find(":protocol");
-    auto authority_pair = request_headers.find(":authority");
-    if (path_pair == request_headers.end()) {
-      QUIC_DLOG(ERROR) << "MASQUE request is missing :path";
-      return CreateBackendErrorResponse("400", "Missing :path");
-    }
-    if (scheme_pair == request_headers.end()) {
-      QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme";
-      return CreateBackendErrorResponse("400", "Missing :scheme");
-    }
-    if (method_pair == request_headers.end()) {
-      QUIC_DLOG(ERROR) << "MASQUE request is missing :method";
-      return CreateBackendErrorResponse("400", "Missing :method");
-    }
-    if (protocol_pair == request_headers.end()) {
-      QUIC_DLOG(ERROR) << "MASQUE request is missing :protocol";
-      return CreateBackendErrorResponse("400", "Missing :protocol");
-    }
-    if (authority_pair == request_headers.end()) {
-      QUIC_DLOG(ERROR) << "MASQUE request is missing :authority";
-      return CreateBackendErrorResponse("400", "Missing :authority");
-    }
-    absl::string_view path = path_pair->second;
-    absl::string_view scheme = scheme_pair->second;
-    absl::string_view method = method_pair->second;
-    absl::string_view protocol = protocol_pair->second;
-    absl::string_view authority = authority_pair->second;
-    if (path.empty()) {
-      QUIC_DLOG(ERROR) << "MASQUE request with empty path";
-      return CreateBackendErrorResponse("400", "Empty path");
-    }
-    if (scheme.empty()) {
-      return CreateBackendErrorResponse("400", "Empty scheme");
-    }
-    if (method != "CONNECT") {
-      QUIC_DLOG(ERROR) << "MASQUE request with bad method \"" << method << "\"";
-      return CreateBackendErrorResponse("400", "Bad method");
-    }
-    if (protocol != "connect-udp") {
-      QUIC_DLOG(ERROR) << "MASQUE request with bad protocol \"" << protocol
-                       << "\"";
-      return CreateBackendErrorResponse("400", "Bad protocol");
-    }
-    absl::optional<QuicDatagramStreamId> flow_id;
-    if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
-      flow_id = SpdyUtils::ParseDatagramFlowIdHeader(request_headers);
-      if (!flow_id.has_value()) {
-        QUIC_DLOG(ERROR)
-            << "MASQUE request with bad or missing DatagramFlowId header";
-        return CreateBackendErrorResponse(
-            "400", "Bad or missing DatagramFlowId header");
-      }
-    }
-    // Extract target host and port from path using default template.
-    std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
-    if (path_split.size() != 4 || !path_split[0].empty() ||
-        path_split[1].empty() || path_split[2].empty() ||
-        !path_split[3].empty()) {
-      QUIC_DLOG(ERROR) << "MASQUE request with bad path \"" << path << "\"";
-      return CreateBackendErrorResponse("400", "Bad path");
-    }
-    absl::optional<std::string> host = quiche::AsciiUrlDecode(path_split[1]);
-    if (!host.has_value()) {
-      QUIC_DLOG(ERROR) << "Failed to decode host \"" << path_split[1] << "\"";
-      return CreateBackendErrorResponse("500", "Failed to decode host");
-    }
-    absl::optional<std::string> port = quiche::AsciiUrlDecode(path_split[2]);
-    if (!port.has_value()) {
-      QUIC_DLOG(ERROR) << "Failed to decode port \"" << path_split[2] << "\"";
-      return CreateBackendErrorResponse("500", "Failed to decode port");
-    }
-
-    // Perform DNS resolution.
-    addrinfo hint = {};
-    hint.ai_protocol = IPPROTO_UDP;
-
-    addrinfo* info_list = nullptr;
-    int result = getaddrinfo(host.value().c_str(), port.value().c_str(), &hint,
-                             &info_list);
-    if (result != 0) {
-      QUIC_DLOG(ERROR) << "Failed to resolve " << authority << ": "
-                       << gai_strerror(result);
-      return CreateBackendErrorResponse("500", "DNS resolution failed");
-    }
-
-    QUICHE_CHECK_NE(info_list, nullptr);
-    std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(
-        info_list, freeaddrinfo);
-    QuicSocketAddress target_server_address(info_list->ai_addr,
-                                            info_list->ai_addrlen);
-    QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
-                    << request_handler->stream_id() << " flow_id="
-                    << (flow_id.has_value() ? absl::StrCat(*flow_id) : "none")
-                    << " target_server_address=\"" << target_server_address
-                    << "\"";
-
-    FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
-    if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
-      QUIC_DLOG(ERROR) << "Socket creation failed";
-      return CreateBackendErrorResponse("500", "Socket creation failed");
-    }
-    QuicSocketAddress empty_address(QuicIpAddress::Any6(), 0);
-    if (target_server_address.host().IsIPv4()) {
-      empty_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
-    }
-    QuicUdpSocketApi socket_api;
-    if (!socket_api.Bind(fd_wrapper.fd(), empty_address)) {
-      QUIC_DLOG(ERROR) << "Socket bind failed";
-      return CreateBackendErrorResponse("500", "Socket bind failed");
-    }
-    epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
-
-    absl::optional<QuicDatagramContextId> context_id;
-    QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
-        GetActiveStream(request_handler->stream_id()));
-    if (stream == nullptr) {
-      QUIC_BUG(bad masque server stream type)
-          << "Unexpected stream type for stream ID "
-          << request_handler->stream_id();
-      return CreateBackendErrorResponse("500", "Bad stream type");
-    }
-    if (flow_id.has_value()) {
-      stream->RegisterHttp3DatagramFlowId(*flow_id);
-    }
-    connect_udp_server_states_.push_back(
-        ConnectUdpServerState(stream, context_id, target_server_address,
-                              fd_wrapper.extract_fd(), this));
-
-    if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
-      // TODO(b/181256914) remove this when we drop support for
-      // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-      stream->RegisterHttp3DatagramContextId(
-          context_id, DatagramFormatType::UDP_PAYLOAD,
-          /*format_additional_data=*/absl::string_view(),
-          &connect_udp_server_states_.back());
-    }
-
-    spdy::Http2HeaderBlock response_headers;
-    response_headers[":status"] = "200";
-    if (flow_id.has_value()) {
-      SpdyUtils::AddDatagramFlowIdHeader(&response_headers, *flow_id);
-    }
-    auto response = std::make_unique<QuicBackendResponse>();
-    response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
-    response->set_headers(std::move(response_headers));
-    response->set_body("");
-
-    return response;
-  }
-
-  QUIC_DLOG(INFO) << "MasqueServerSession handling MASQUE request";
-
-  if (masque_path == "init") {
-    if (masque_initialized_) {
-      QUIC_DLOG(ERROR) << "Got second MASQUE init request";
-      return nullptr;
-    }
-    masque_initialized_ = true;
-  } else if (masque_path == "unregister") {
-    QuicConnectionId connection_id(request_body.data(), request_body.length());
-    QUIC_DLOG(INFO) << "Received MASQUE request to unregister "
-                    << connection_id;
-    owner_->UnregisterClientConnectionId(connection_id);
-    compression_engine_.UnregisterClientConnectionId(connection_id);
-  } else {
-    if (!masque_initialized_) {
-      QUIC_DLOG(ERROR) << "Got MASQUE request before init";
-      return nullptr;
-    }
-  }
-
-  // TODO(dschinazi) implement binary protocol sent in response body.
-  const std::string response_body = "";
-  spdy::Http2HeaderBlock response_headers;
-  response_headers[":status"] = "200";
-  auto response = std::make_unique<QuicBackendResponse>();
-  response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
-  response->set_headers(std::move(response_headers));
-  response->set_body(response_body);
-
-  return response;
-}
-
-void MasqueServerSession::HandlePacketFromServer(
-    const ReceivedPacketInfo& packet_info) {
-  QUIC_DVLOG(1) << "MasqueServerSession received " << packet_info;
-  if (masque_mode_ == MasqueMode::kLegacy) {
-    compression_engine_.CompressAndSendPacket(
-        packet_info.packet.AsStringPiece(),
-        packet_info.destination_connection_id, packet_info.source_connection_id,
-        packet_info.peer_address);
-    return;
-  }
-  QUIC_LOG(ERROR) << "Ignoring packet from server in " << masque_mode_
-                  << " mode";
-}
-
-void MasqueServerSession::OnRegistration(QuicEpollServer* /*eps*/,
-                                         QuicUdpSocketFd fd, int event_mask) {
-  QUIC_DVLOG(1) << "OnRegistration " << fd << " event_mask " << event_mask;
-}
-
-void MasqueServerSession::OnModification(QuicUdpSocketFd fd, int event_mask) {
-  QUIC_DVLOG(1) << "OnModification " << fd << " event_mask " << event_mask;
-}
-
-void MasqueServerSession::OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) {
-  if ((event->in_events & EPOLLIN) == 0) {
-    QUIC_DVLOG(1) << "Ignoring OnEvent fd " << fd << " event mask "
-                  << event->in_events;
-    return;
-  }
-  auto it = absl::c_find_if(connect_udp_server_states_,
-                            [fd](const ConnectUdpServerState& connect_udp) {
-                              return connect_udp.fd() == fd;
-                            });
-  if (it == connect_udp_server_states_.end()) {
-    QUIC_BUG(quic_bug_10974_1) << "Got unexpected event mask "
-                               << event->in_events << " on unknown fd " << fd;
-    return;
-  }
-  QuicSocketAddress expected_target_server_address =
-      it->target_server_address();
-  QUICHE_DCHECK(expected_target_server_address.IsInitialized());
-  QUIC_DVLOG(1) << "Received readable event on fd " << fd << " (mask "
-                << event->in_events << ") stream ID " << it->stream()->id()
-                << " server " << expected_target_server_address;
-  QuicUdpSocketApi socket_api;
-  BitMask64 packet_info_interested(QuicUdpPacketInfoBit::PEER_ADDRESS);
-  char packet_buffer[kMaxIncomingPacketSize];
-  char control_buffer[kDefaultUdpPacketControlBufferSize];
-  while (true) {
-    QuicUdpSocketApi::ReadPacketResult read_result;
-    read_result.packet_buffer = {packet_buffer, sizeof(packet_buffer)};
-    read_result.control_buffer = {control_buffer, sizeof(control_buffer)};
-    socket_api.ReadPacket(fd, packet_info_interested, &read_result);
-    if (!read_result.ok) {
-      // Most likely there is nothing left to read, break out of read loop.
-      break;
-    }
-    if (!read_result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
-      QUIC_BUG(quic_bug_10974_2)
-          << "Missing peer address when reading from fd " << fd;
-      continue;
-    }
-    if (read_result.packet_info.peer_address() !=
-        expected_target_server_address) {
-      QUIC_DLOG(ERROR) << "Ignoring UDP packet on fd " << fd
-                       << " from unexpected server address "
-                       << read_result.packet_info.peer_address()
-                       << " (expected " << expected_target_server_address
-                       << ")";
-      continue;
-    }
-    if (!connection()->connected()) {
-      QUIC_BUG(quic_bug_10974_3)
-          << "Unexpected incoming UDP packet on fd " << fd << " from "
-          << expected_target_server_address
-          << " because MASQUE connection is closed";
-      return;
-    }
-    // The packet is valid, send it to the client in a DATAGRAM frame.
-    MessageStatus message_status = it->stream()->SendHttp3Datagram(
-        it->context_id(),
-        absl::string_view(read_result.packet_buffer.buffer,
-                          read_result.packet_buffer.buffer_len));
-    QUIC_DVLOG(1) << "Sent UDP packet from " << expected_target_server_address
-                  << " of length " << read_result.packet_buffer.buffer_len
-                  << " with stream ID " << it->stream()->id()
-                  << " and got message status "
-                  << MessageStatusToString(message_status);
-  }
-}
-
-void MasqueServerSession::OnUnregistration(QuicUdpSocketFd fd, bool replaced) {
-  QUIC_DVLOG(1) << "OnUnregistration " << fd << " " << (replaced ? "" : "!")
-                << " replaced";
-}
-
-void MasqueServerSession::OnShutdown(QuicEpollServer* /*eps*/,
-                                     QuicUdpSocketFd fd) {
-  QUIC_DVLOG(1) << "OnShutdown " << fd;
-}
-
-std::string MasqueServerSession::Name() const {
-  return std::string("MasqueServerSession-") + connection_id().ToString();
-}
-
-bool MasqueServerSession::OnSettingsFrame(const SettingsFrame& frame) {
-  QUIC_DLOG(INFO) << "Received SETTINGS: " << frame;
-  if (!QuicSimpleServerSession::OnSettingsFrame(frame)) {
-    return false;
-  }
-  if (!SupportsH3Datagram()) {
-    QUIC_DLOG(ERROR) << "Refusing to use MASQUE without HTTP Datagrams";
-    return false;
-  }
-  QUIC_DLOG(INFO) << "Using HTTP Datagram: " << http_datagram_support();
-  return true;
-}
-
-MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
-    QuicSpdyStream* stream, absl::optional<QuicDatagramContextId> context_id,
-    const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
-    MasqueServerSession* masque_session)
-    : stream_(stream),
-      context_id_(context_id),
-      target_server_address_(target_server_address),
-      fd_(fd),
-      masque_session_(masque_session) {
-  QUICHE_DCHECK_NE(fd_, kQuicInvalidSocketFd);
-  QUICHE_DCHECK_NE(masque_session_, nullptr);
-  this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
-}
-
-MasqueServerSession::ConnectUdpServerState::~ConnectUdpServerState() {
-  if (stream() != nullptr) {
-    if (context_registered_) {
-      stream()->UnregisterHttp3DatagramContextId(context_id());
-    }
-    stream()->UnregisterHttp3DatagramRegistrationVisitor();
-  }
-  if (fd_ == kQuicInvalidSocketFd) {
-    return;
-  }
-  QuicUdpSocketApi socket_api;
-  QUIC_DLOG(INFO) << "Closing fd " << fd_;
-  masque_session_->epoll_server()->UnregisterFD(fd_);
-  socket_api.Destroy(fd_);
-}
-
-MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
-    MasqueServerSession::ConnectUdpServerState&& other) {
-  fd_ = kQuicInvalidSocketFd;
-  *this = std::move(other);
-}
-
-MasqueServerSession::ConnectUdpServerState&
-MasqueServerSession::ConnectUdpServerState::operator=(
-    MasqueServerSession::ConnectUdpServerState&& other) {
-  if (fd_ != kQuicInvalidSocketFd) {
-    QuicUdpSocketApi socket_api;
-    QUIC_DLOG(INFO) << "Closing fd " << fd_;
-    masque_session_->epoll_server()->UnregisterFD(fd_);
-    socket_api.Destroy(fd_);
-  }
-  stream_ = other.stream_;
-  other.stream_ = nullptr;
-  context_id_ = other.context_id_;
-  target_server_address_ = other.target_server_address_;
-  fd_ = other.fd_;
-  masque_session_ = other.masque_session_;
-  other.fd_ = kQuicInvalidSocketFd;
-  context_registered_ = other.context_registered_;
-  other.context_registered_ = false;
-  if (stream() != nullptr) {
-    stream()->MoveHttp3DatagramRegistration(this);
-    if (context_registered_) {
-      stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
-    }
-  }
-  return *this;
-}
-
-void MasqueServerSession::ConnectUdpServerState::OnHttp3Datagram(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    absl::string_view payload) {
-  QUICHE_DCHECK_EQ(stream_id, stream()->id());
-  QUICHE_DCHECK(context_id == context_id_);
-  QuicUdpSocketApi socket_api;
-  QuicUdpPacketInfo packet_info;
-  packet_info.SetPeerAddress(target_server_address_);
-  WriteResult write_result = socket_api.WritePacket(
-      fd_, payload.data(), payload.length(), packet_info);
-  QUIC_DVLOG(1) << "Wrote packet of length " << payload.length() << " to "
-                << target_server_address_ << " with result " << write_result;
-}
-
-void MasqueServerSession::ConnectUdpServerState::OnContextReceived(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    DatagramFormatType format_type, absl::string_view format_additional_data) {
-  if (stream_id != stream()->id()) {
-    QUIC_BUG(MASQUE server bad datagram context registration)
-        << "Registered stream ID " << stream_id << ", expected "
-        << stream()->id();
-    return;
-  }
-  if (format_type != DatagramFormatType::UDP_PAYLOAD) {
-    QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
-                    << DatagramFormatTypeToString(format_type);
-    return;
-  }
-  if (!format_additional_data.empty()) {
-    QUIC_DLOG(ERROR)
-        << "Received non-empty format additional data for context ID "
-        << (context_id_.has_value() ? context_id_.value() : 0)
-        << " on stream ID " << stream()->id();
-    masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-    return;
-  }
-  if (!context_received_) {
-    context_received_ = true;
-    context_id_ = context_id;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream()->id();
-    return;
-  }
-  if (context_registered_) {
-    QUIC_BUG(MASQUE server double datagram context registration)
-        << "Try to re-register stream ID " << stream_id << " context ID "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none");
-    return;
-  }
-  context_registered_ = true;
-  stream()->RegisterHttp3DatagramContextId(context_id_, format_type,
-                                           format_additional_data, this);
-}
-
-void MasqueServerSession::ConnectUdpServerState::OnContextClosed(
-    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
-    ContextCloseCode close_code, absl::string_view close_details) {
-  if (stream_id != stream()->id()) {
-    QUIC_BUG(MASQUE server bad datagram context registration)
-        << "Closed context on stream ID " << stream_id << ", expected "
-        << stream()->id();
-    return;
-  }
-  if (context_id != context_id_) {
-    QUIC_DLOG(INFO)
-        << "Ignoring unexpected close of context ID "
-        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
-        << " instead of "
-        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
-                                    : "none")
-        << " on stream ID " << stream()->id();
-    return;
-  }
-  QUIC_DLOG(INFO) << "Received datagram context close with close code "
-                  << close_code << " close details \"" << close_details
-                  << "\" on stream ID " << stream()->id() << ", closing stream";
-  masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_server_session.h b/quic/masque/masque_server_session.h
deleted file mode 100644
index b3c327f..0000000
--- a/quic/masque/masque_server_session.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/masque/masque_compression_engine.h"
-#include "quic/masque/masque_server_backend.h"
-#include "quic/masque/masque_utils.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-namespace quic {
-
-// QUIC server session for connection to MASQUE proxy.
-class QUIC_NO_EXPORT MasqueServerSession
-    : public QuicSimpleServerSession,
-      public MasqueServerBackend::BackendClient,
-      public QuicEpollCallbackInterface {
- public:
-  // Interface meant to be implemented by owner of this MasqueServerSession
-  // instance.
-  class QUIC_NO_EXPORT Visitor {
-   public:
-    virtual ~Visitor() {}
-    // Register a client connection ID as being handled by this session.
-    virtual void RegisterClientConnectionId(
-        QuicConnectionId client_connection_id,
-        MasqueServerSession* masque_server_session) = 0;
-
-    // Unregister a client connection ID.
-    virtual void UnregisterClientConnectionId(
-        QuicConnectionId client_connection_id) = 0;
-  };
-
-  explicit MasqueServerSession(
-      MasqueMode masque_mode, const QuicConfig& config,
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
-      QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      MasqueServerBackend* masque_server_backend);
-
-  // Disallow copy and assign.
-  MasqueServerSession(const MasqueServerSession&) = delete;
-  MasqueServerSession& operator=(const MasqueServerSession&) = delete;
-
-  // From QuicSession.
-  void OnMessageReceived(absl::string_view message) override;
-  void OnMessageAcked(QuicMessageId message_id,
-                      QuicTime receive_timestamp) override;
-  void OnMessageLost(QuicMessageId message_id) override;
-  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                          ConnectionCloseSource source) override;
-  void OnStreamClosed(QuicStreamId stream_id) override;
-
-  // From MasqueServerBackend::BackendClient.
-  std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
-      const std::string& masque_path,
-      const spdy::Http2HeaderBlock& request_headers,
-      const std::string& request_body,
-      QuicSimpleServerBackend::RequestHandler* request_handler) override;
-
-  // From QuicEpollCallbackInterface.
-  void OnRegistration(QuicEpollServer* eps, QuicUdpSocketFd fd,
-                      int event_mask) override;
-  void OnModification(QuicUdpSocketFd fd, int event_mask) override;
-  void OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) override;
-  void OnUnregistration(QuicUdpSocketFd fd, bool replaced) override;
-  void OnShutdown(QuicEpollServer* eps, QuicUdpSocketFd fd) override;
-  std::string Name() const override;
-
-  // Handle packet for client, meant to be called by MasqueDispatcher.
-  void HandlePacketFromServer(const ReceivedPacketInfo& packet_info);
-
-  QuicEpollServer* epoll_server() const { return epoll_server_; }
-
- private:
-  // State that the MasqueServerSession keeps for each CONNECT-UDP request.
-  class QUIC_NO_EXPORT ConnectUdpServerState
-      : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
-        public QuicSpdyStream::Http3DatagramVisitor {
-   public:
-    // ConnectUdpServerState takes ownership of |fd|. It will unregister it
-    // from |epoll_server| and close the file descriptor when destructed.
-    explicit ConnectUdpServerState(
-        QuicSpdyStream* stream,
-        absl::optional<QuicDatagramContextId> context_id,
-        const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
-        MasqueServerSession* masque_session);
-
-    ~ConnectUdpServerState();
-
-    // Disallow copy but allow move.
-    ConnectUdpServerState(const ConnectUdpServerState&) = delete;
-    ConnectUdpServerState(ConnectUdpServerState&&);
-    ConnectUdpServerState& operator=(const ConnectUdpServerState&) = delete;
-    ConnectUdpServerState& operator=(ConnectUdpServerState&&);
-
-    QuicSpdyStream* stream() const { return stream_; }
-    absl::optional<QuicDatagramContextId> context_id() const {
-      return context_id_;
-    }
-    const QuicSocketAddress& target_server_address() const {
-      return target_server_address_;
-    }
-    QuicUdpSocketFd fd() const { return fd_; }
-
-    // From QuicSpdyStream::Http3DatagramVisitor.
-    void OnHttp3Datagram(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         absl::string_view payload) override;
-
-    // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
-    void OnContextReceived(QuicStreamId stream_id,
-                           absl::optional<QuicDatagramContextId> context_id,
-                           DatagramFormatType format_type,
-                           absl::string_view format_additional_data) override;
-    void OnContextClosed(QuicStreamId stream_id,
-                         absl::optional<QuicDatagramContextId> context_id,
-                         ContextCloseCode close_code,
-                         absl::string_view close_details) override;
-
-   private:
-    QuicSpdyStream* stream_;
-    absl::optional<QuicDatagramContextId> context_id_;
-    QuicSocketAddress target_server_address_;
-    QuicUdpSocketFd fd_;                   // Owned.
-    MasqueServerSession* masque_session_;  // Unowned.
-    bool context_received_ = false;
-    bool context_registered_ = false;
-  };
-
-  // From QuicSpdySession.
-  bool OnSettingsFrame(const SettingsFrame& frame) override;
-  HttpDatagramSupport LocalHttpDatagramSupport() override {
-    return HttpDatagramSupport::kDraft00And04;
-  }
-
-  MasqueServerBackend* masque_server_backend_;  // Unowned.
-  Visitor* owner_;                              // Unowned.
-  QuicEpollServer* epoll_server_;               // Unowned.
-  MasqueCompressionEngine compression_engine_;
-  MasqueMode masque_mode_;
-  std::list<ConnectUdpServerState> connect_udp_server_states_;
-  bool masque_initialized_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
diff --git a/quic/masque/masque_utils.cc b/quic/masque/masque_utils.cc
deleted file mode 100644
index cd19602..0000000
--- a/quic/masque/masque_utils.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/masque/masque_utils.h"
-
-namespace quic {
-
-ParsedQuicVersionVector MasqueSupportedVersions() {
-  QuicVersionInitializeSupportForIetfDraft();
-  ParsedQuicVersionVector versions;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    // Use all versions that support IETF QUIC.
-    if (version.UsesHttp3()) {
-      QuicEnableVersion(version);
-      versions.push_back(version);
-    }
-  }
-  QUICHE_CHECK(!versions.empty());
-  return versions;
-}
-
-QuicConfig MasqueEncapsulatedConfig() {
-  QuicConfig config;
-  config.SetMaxPacketSizeToSend(kMasqueMaxEncapsulatedPacketSize);
-  return config;
-}
-
-std::string MasqueModeToString(MasqueMode masque_mode) {
-  switch (masque_mode) {
-    case MasqueMode::kInvalid:
-      return "Invalid";
-    case MasqueMode::kLegacy:
-      return "Legacy";
-    case MasqueMode::kOpen:
-      return "Open";
-  }
-  return absl::StrCat("Unknown(", static_cast<int>(masque_mode), ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const MasqueMode& masque_mode) {
-  os << MasqueModeToString(masque_mode);
-  return os;
-}
-
-}  // namespace quic
diff --git a/quic/masque/masque_utils.h b/quic/masque/masque_utils.h
deleted file mode 100644
index abaeda7..0000000
--- a/quic/masque/masque_utils.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-
-namespace quic {
-
-// List of QUIC versions that support MASQUE. Currently restricted to IETF QUIC.
-QUIC_NO_EXPORT ParsedQuicVersionVector MasqueSupportedVersions();
-
-// Default QuicConfig for use with MASQUE. Sets a custom max_packet_size.
-QUIC_NO_EXPORT QuicConfig MasqueEncapsulatedConfig();
-
-// Maximum packet size for encapsulated connections.
-enum : QuicByteCount {
-  kMasqueMaxEncapsulatedPacketSize = 1300,
-  kMasqueMaxOuterPacketSize = 1350,
-};
-
-// Mode that MASQUE is operating in.
-enum class MasqueMode : uint8_t {
-  kInvalid = 0,  // Should never be used.
-  kLegacy = 1,   // Legacy mode uses the legacy MASQUE protocol as documented in
-  // <https://tools.ietf.org/html/draft-schinazi-masque-protocol>. That version
-  // of MASQUE uses a custom application-protocol over HTTP/3, and also allows
-  // unauthenticated clients.
-  kOpen = 2,  // Open mode uses the MASQUE HTTP CONNECT-UDP method as documented
-  // in <https://tools.ietf.org/html/draft-ietf-masque-connect-udp>. This mode
-  // allows unauthenticated clients (a more restricted mode will be added to
-  // this enum at a later date).
-};
-
-QUIC_NO_EXPORT std::string MasqueModeToString(MasqueMode masque_mode);
-QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
-                                        const MasqueMode& masque_mode);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
diff --git a/quic/platform/api/quic_bug_tracker.h b/quic/platform/api/quic_bug_tracker.h
deleted file mode 100644
index cffa6e5..0000000
--- a/quic/platform/api/quic_bug_tracker.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
-
-#include "common/platform/api/quiche_bug_tracker.h"
-
-#define QUIC_BUG QUICHE_BUG
-#define QUIC_BUG_IF QUICHE_BUG_IF
-#define QUIC_PEER_BUG QUICHE_PEER_BUG
-#define QUIC_PEER_BUG_IF QUICHE_PEER_BUG_IF
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
diff --git a/quic/platform/api/quic_client_stats.h b/quic/platform/api/quic_client_stats.h
deleted file mode 100644
index 2f29cd9..0000000
--- a/quic/platform/api/quic_client_stats.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
-
-#include <string>
-
-#include "common/platform/api/quiche_client_stats.h"
-
-namespace quic {
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-//
-// Sample usage:
-//   // In Chrome, these values are persisted to logs. Entries should not be
-//   // renumbered and numeric values should never be reused.
-//   enum class MyEnum {
-//     FIRST_VALUE = 0,
-//     SECOND_VALUE = 1,
-//     ...
-//     FINAL_VALUE = N,
-//     COUNT
-//   };
-//   QUIC_CLIENT_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE,
-//   MyEnum::COUNT, "Number of time $foo equals to some enum value");
-//
-// Note: The value in |sample| must be strictly less than |enum_size|.
-
-#define QUIC_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
-  QUICHE_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring)
-
-//------------------------------------------------------------------------------
-// Histogram for boolean values.
-
-// Sample usage:
-//   QUIC_CLIENT_HISTOGRAM_BOOL("My.Boolean", bool,
-//   "Number of times $foo is true or false");
-#define QUIC_CLIENT_HISTOGRAM_BOOL(name, sample, docstring) \
-  QUICHE_CLIENT_HISTOGRAM_BOOL(name, sample, docstring)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The units for
-// sample and max are unspecified, but they must be the same for one histogram.
-
-// Sample usage:
-//   QUIC_CLIENT_HISTOGRAM_TIMES("Very.Long.Timing.Histogram", time_delta,
-//       QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
-//       24), 100, "Time spent in doing operation.");
-#define QUIC_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
-                                    docstring)                            \
-  QUICHE_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data.
-
-// These macros default to exponential histograms - i.e. the lengths of the
-// bucket ranges exponentially increase as the sample range increases.
-
-// All of these macros must be called with |name| as a runtime constant.
-
-// Any data outside the range here will be put in underflow and overflow
-// buckets. Min values should be >=1 as emitted 0s will still go into the
-// underflow bucket.
-
-// Sample usage:
-//   UMA_CLIENT_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100,
-//      "Counters of hitting certian code.");
-
-#define QUIC_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
-                                     docstring)                            \
-  QUICHE_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,     \
-                                 docstring)
-
-inline void QuicClientSparseHistogram(const std::string& name, int sample) {
-  quiche::QuicheClientSparseHistogram(name, sample);
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
diff --git a/quic/platform/api/quic_containers.h b/quic/platform/api/quic_containers.h
deleted file mode 100644
index 06f2251..0000000
--- a/quic/platform/api/quic_containers.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
-
-#include "common/platform/api/quiche_containers.h"
-
-namespace quic {
-
-// An ordered container optimized for small sets.
-// An implementation with O(n) mutations might be chosen
-// in case it has better memory usage and/or faster access.
-//
-// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
-template <typename Key, typename Compare = std::less<Key>>
-using QuicSmallOrderedSet = ::quiche::QuicheSmallOrderedSet<Key, Compare>;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
diff --git a/quic/platform/api/quic_default_proof_providers.h b/quic/platform/api/quic_default_proof_providers.h
deleted file mode 100644
index fd4a5cd..0000000
--- a/quic/platform/api/quic_default_proof_providers.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
-
-#include <memory>
-#include <string>
-
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "common/platform/api/quiche_default_proof_providers.h"
-
-namespace quic {
-
-// Provides a default proof verifier that can verify a cert chain for |host|.
-// The verifier has to do a good faith attempt at verifying the certificate
-// against a reasonable root store, and not just always return success.
-inline std::unique_ptr<ProofVerifier> CreateDefaultProofVerifier(
-    const std::string& host) {
-  return quiche::CreateDefaultProofVerifier(host);
-}
-
-// Provides a default proof source for CLI-based tools.  The actual certificates
-// used in the proof source should be confifgurable via command-line flags.
-inline std::unique_ptr<ProofSource> CreateDefaultProofSource() {
-  return quiche::CreateDefaultProofSource();
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/quic/platform/api/quic_epoll.h b/quic/platform/api/quic_epoll.h
deleted file mode 100644
index eb6c98a..0000000
--- a/quic/platform/api/quic_epoll.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
-
-#include "common/platform/api/quiche_epoll.h"
-
-namespace quic {
-
-using QuicEpollServer = quiche::QuicheEpollServer;
-using QuicEpollEvent = quiche::QuicheEpollEvent;
-using QuicEpollAlarmBase = quiche::QuicheEpollAlarmBase;
-using QuicEpollCallbackInterface = quiche::QuicheEpollCallbackInterface;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
diff --git a/quic/platform/api/quic_expect_bug.h b/quic/platform/api/quic_expect_bug.h
deleted file mode 100644
index 2b8ac16..0000000
--- a/quic/platform/api/quic_expect_bug.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
-
-#include "common/platform/api/quiche_expect_bug.h"
-
-#define EXPECT_QUIC_BUG EXPECT_QUICHE_BUG
-#define EXPECT_QUIC_PEER_BUG(statement, regex) \
-  EXPECT_QUICHE_PEER_BUG(statement, regex)
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
diff --git a/quic/platform/api/quic_exported_stats.h b/quic/platform/api/quic_exported_stats.h
deleted file mode 100644
index d2d0d4a..0000000
--- a/quic/platform/api/quic_exported_stats.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
-
-#include "quic/platform/api/quic_client_stats.h"
-#include "quic/platform/api/quic_server_stats.h"
-
-namespace quic {
-
-// TODO(wub): Add support for counters. Only histograms are supported for now.
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-//
-// Sample usage:
-//   // In Chrome, these values are persisted to logs. Entries should not be
-//   // renumbered and numeric values should never be reused.
-//   enum class MyEnum {
-//     FIRST_VALUE = 0,
-//     SECOND_VALUE = 1,
-//     ...
-//     FINAL_VALUE = N,
-//     COUNT
-//   };
-//   QUIC_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE, MyEnum::COUNT,
-//                       "Number of time $foo equals to some enum value");
-//
-// Note: The value in |sample| must be strictly less than |enum_size|.
-
-#define QUIC_HISTOGRAM_ENUM(name, sample, enum_size, docstring)     \
-  do {                                                              \
-    QUIC_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring); \
-    QUIC_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring); \
-  } while (0)
-
-//------------------------------------------------------------------------------
-// Histogram for boolean values.
-
-// Sample usage:
-//   QUIC_HISTOGRAM_BOOL("My.Boolean", bool,
-//                       "Number of times $foo is true or false");
-#define QUIC_HISTOGRAM_BOOL(name, sample, docstring)     \
-  do {                                                   \
-    QUIC_CLIENT_HISTOGRAM_BOOL(name, sample, docstring); \
-    QUIC_SERVER_HISTOGRAM_BOOL(name, sample, docstring); \
-  } while (0)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The units for
-// sample and max are unspecified, but they must be the same for one histogram.
-
-// Sample usage:
-//   QUIC_HISTOGRAM_TIMES("My.Timing.Histogram.InMs", time_delta,
-//       QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
-//       24), 100, "Time spent in doing operation.");
-
-#define QUIC_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring) \
-  do {                                                                        \
-    QUIC_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count,         \
-                                docstring);                                   \
-    QUIC_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count,         \
-                                docstring);                                   \
-  } while (0)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data.
-
-// These macros default to exponential histograms - i.e. the lengths of the
-// bucket ranges exponentially increase as the sample range increases.
-
-// All of these macros must be called with |name| as a runtime constant.
-
-// Sample usage:
-//   QUIC_HISTOGRAM_COUNTS("My.Histogram",
-//                         sample,    // Number of something in this event.
-//                         1000,      // Record up to 1K of something.
-//                         "Number of something.");
-
-#define QUIC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, docstring) \
-  do {                                                                         \
-    QUIC_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,         \
-                                 docstring);                                   \
-    QUIC_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,         \
-                                 docstring);                                   \
-  } while (0)
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
diff --git a/quic/platform/api/quic_flag_utils.h b/quic/platform/api/quic_flag_utils.h
deleted file mode 100644
index 63cbb91..0000000
--- a/quic/platform/api/quic_flag_utils.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
-
-#include "common/platform/api/quiche_flag_utils.h"
-
-#define QUIC_RELOADABLE_FLAG_COUNT QUICHE_RELOADABLE_FLAG_COUNT
-#define QUIC_RELOADABLE_FLAG_COUNT_N QUICHE_RELOADABLE_FLAG_COUNT_N
-
-#define QUIC_RESTART_FLAG_COUNT QUICHE_RESTART_FLAG_COUNT
-#define QUIC_RESTART_FLAG_COUNT_N QUICHE_RESTART_FLAG_COUNT_N
-
-#define QUIC_CODE_COUNT QUICHE_CODE_COUNT
-#define QUIC_CODE_COUNT_N QUICHE_CODE_COUNT_N
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
diff --git a/quic/platform/api/quic_flags.h b/quic/platform/api/quic_flags.h
deleted file mode 100644
index 762e590..0000000
--- a/quic/platform/api/quic_flags.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
-
-#include <string>
-#include <vector>
-
-#include "quiche_platform_impl/quic_flags_impl.h"
-#include "common/platform/api/quiche_flags.h"
-
-#define GetQuicReloadableFlag(flag) GetQuicheReloadableFlag(quic, flag)
-#define SetQuicReloadableFlag(flag, value) \
-  SetQuicheReloadableFlag(quic, flag, value)
-#define GetQuicRestartFlag(flag) GetQuicheRestartFlag(quic, flag)
-#define SetQuicRestartFlag(flag, value) SetQuicheRestartFlag(quic, flag, value)
-#define GetQuicFlag(flag) GetQuicheFlag(flag)
-#define SetQuicFlag(flag, value) SetQuicheFlag(flag, value)
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
diff --git a/quic/platform/api/quic_hostname_utils.h b/quic/platform/api/quic_hostname_utils.h
deleted file mode 100644
index 1c83d31..0000000
--- a/quic/platform/api/quic_hostname_utils.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
-
-#include "common/platform/api/quiche_hostname_utils.h"
-
-namespace quic {
-
-using QuicHostnameUtils = quiche::QuicheHostnameUtils;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
diff --git a/quic/platform/api/quic_ip_address.cc b/quic/platform/api/quic_ip_address.cc
deleted file mode 100644
index b2cb649..0000000
--- a/quic/platform/api/quic_ip_address.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_ip_address.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-static int ToPlatformAddressFamily(IpAddressFamily family) {
-  switch (family) {
-    case IpAddressFamily::IP_V4:
-      return AF_INET;
-    case IpAddressFamily::IP_V6:
-      return AF_INET6;
-    case IpAddressFamily::IP_UNSPEC:
-      return AF_UNSPEC;
-  }
-  QUIC_BUG(quic_bug_10126_1)
-      << "Invalid IpAddressFamily " << static_cast<int32_t>(family);
-  return AF_UNSPEC;
-}
-
-QuicIpAddress QuicIpAddress::Loopback4() {
-  QuicIpAddress result;
-  result.family_ = IpAddressFamily::IP_V4;
-  result.address_.bytes[0] = 127;
-  result.address_.bytes[1] = 0;
-  result.address_.bytes[2] = 0;
-  result.address_.bytes[3] = 1;
-  return result;
-}
-
-QuicIpAddress QuicIpAddress::Loopback6() {
-  QuicIpAddress result;
-  result.family_ = IpAddressFamily::IP_V6;
-  uint8_t* bytes = result.address_.bytes;
-  memset(bytes, 0, 15);
-  bytes[15] = 1;
-  return result;
-}
-
-QuicIpAddress QuicIpAddress::Any4() {
-  in_addr address;
-  memset(&address, 0, sizeof(address));
-  return QuicIpAddress(address);
-}
-
-QuicIpAddress QuicIpAddress::Any6() {
-  in6_addr address;
-  memset(&address, 0, sizeof(address));
-  return QuicIpAddress(address);
-}
-
-QuicIpAddress::QuicIpAddress() : family_(IpAddressFamily::IP_UNSPEC) {}
-
-QuicIpAddress::QuicIpAddress(const in_addr& ipv4_address)
-    : family_(IpAddressFamily::IP_V4) {
-  address_.v4 = ipv4_address;
-}
-QuicIpAddress::QuicIpAddress(const in6_addr& ipv6_address)
-    : family_(IpAddressFamily::IP_V6) {
-  address_.v6 = ipv6_address;
-}
-
-bool operator==(QuicIpAddress lhs, QuicIpAddress rhs) {
-  if (lhs.family_ != rhs.family_) {
-    return false;
-  }
-  switch (lhs.family_) {
-    case IpAddressFamily::IP_V4:
-      return std::equal(lhs.address_.bytes,
-                        lhs.address_.bytes + QuicIpAddress::kIPv4AddressSize,
-                        rhs.address_.bytes);
-    case IpAddressFamily::IP_V6:
-      return std::equal(lhs.address_.bytes,
-                        lhs.address_.bytes + QuicIpAddress::kIPv6AddressSize,
-                        rhs.address_.bytes);
-    case IpAddressFamily::IP_UNSPEC:
-      return true;
-  }
-  QUIC_BUG(quic_bug_10126_2)
-      << "Invalid IpAddressFamily " << static_cast<int32_t>(lhs.family_);
-  return false;
-}
-
-bool operator!=(QuicIpAddress lhs, QuicIpAddress rhs) {
-  return !(lhs == rhs);
-}
-
-bool QuicIpAddress::IsInitialized() const {
-  return family_ != IpAddressFamily::IP_UNSPEC;
-}
-
-IpAddressFamily QuicIpAddress::address_family() const {
-  return family_;
-}
-
-int QuicIpAddress::AddressFamilyToInt() const {
-  return ToPlatformAddressFamily(family_);
-}
-
-std::string QuicIpAddress::ToPackedString() const {
-  switch (family_) {
-    case IpAddressFamily::IP_V4:
-      return std::string(address_.chars, sizeof(address_.v4));
-    case IpAddressFamily::IP_V6:
-      return std::string(address_.chars, sizeof(address_.v6));
-    case IpAddressFamily::IP_UNSPEC:
-      return "";
-  }
-  QUIC_BUG(quic_bug_10126_3)
-      << "Invalid IpAddressFamily " << static_cast<int32_t>(family_);
-  return "";
-}
-
-std::string QuicIpAddress::ToString() const {
-  if (!IsInitialized()) {
-    return "";
-  }
-
-  char buffer[INET6_ADDRSTRLEN] = {0};
-  const char* result =
-      inet_ntop(AddressFamilyToInt(), address_.bytes, buffer, sizeof(buffer));
-  QUIC_BUG_IF(quic_bug_10126_4, result == nullptr)
-      << "Failed to convert an IP address to string";
-  return buffer;
-}
-
-static const uint8_t kMappedAddressPrefix[] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-};
-
-QuicIpAddress QuicIpAddress::Normalized() const {
-  if (!IsIPv6()) {
-    return *this;
-  }
-  if (!std::equal(std::begin(kMappedAddressPrefix),
-                  std::end(kMappedAddressPrefix), address_.bytes)) {
-    return *this;
-  }
-
-  in_addr result;
-  memcpy(&result, &address_.bytes[12], sizeof(result));
-  return QuicIpAddress(result);
-}
-
-QuicIpAddress QuicIpAddress::DualStacked() const {
-  if (!IsIPv4()) {
-    return *this;
-  }
-
-  QuicIpAddress result;
-  result.family_ = IpAddressFamily::IP_V6;
-  memcpy(result.address_.bytes, kMappedAddressPrefix,
-         sizeof(kMappedAddressPrefix));
-  memcpy(result.address_.bytes + 12, address_.bytes, kIPv4AddressSize);
-  return result;
-}
-
-bool QuicIpAddress::FromPackedString(const char* data, size_t length) {
-  switch (length) {
-    case kIPv4AddressSize:
-      family_ = IpAddressFamily::IP_V4;
-      break;
-    case kIPv6AddressSize:
-      family_ = IpAddressFamily::IP_V6;
-      break;
-    default:
-      return false;
-  }
-  memcpy(address_.chars, data, length);
-  return true;
-}
-
-bool QuicIpAddress::FromString(std::string str) {
-  for (IpAddressFamily family :
-       {IpAddressFamily::IP_V6, IpAddressFamily::IP_V4}) {
-    int result =
-        inet_pton(ToPlatformAddressFamily(family), str.c_str(), address_.bytes);
-    if (result > 0) {
-      family_ = family;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicIpAddress::IsIPv4() const {
-  return family_ == IpAddressFamily::IP_V4;
-}
-
-bool QuicIpAddress::IsIPv6() const {
-  return family_ == IpAddressFamily::IP_V6;
-}
-
-bool QuicIpAddress::InSameSubnet(const QuicIpAddress& other,
-                                 int subnet_length) {
-  if (!IsInitialized()) {
-    QUIC_BUG(quic_bug_10126_5)
-        << "Attempting to do subnet matching on undefined address";
-    return false;
-  }
-  if ((IsIPv4() && subnet_length > 32) || (IsIPv6() && subnet_length > 128)) {
-    QUIC_BUG(quic_bug_10126_6) << "Subnet mask is out of bounds";
-    return false;
-  }
-
-  int bytes_to_check = subnet_length / 8;
-  int bits_to_check = subnet_length % 8;
-  const uint8_t* const lhs = address_.bytes;
-  const uint8_t* const rhs = other.address_.bytes;
-  if (!std::equal(lhs, lhs + bytes_to_check, rhs)) {
-    return false;
-  }
-  if (bits_to_check == 0) {
-    return true;
-  }
-  QUICHE_DCHECK_LT(static_cast<size_t>(bytes_to_check), sizeof(address_.bytes));
-  int mask = (~0u) << (8u - bits_to_check);
-  return (lhs[bytes_to_check] & mask) == (rhs[bytes_to_check] & mask);
-}
-
-in_addr QuicIpAddress::GetIPv4() const {
-  QUICHE_DCHECK(IsIPv4());
-  return address_.v4;
-}
-
-in6_addr QuicIpAddress::GetIPv6() const {
-  QUICHE_DCHECK(IsIPv6());
-  return address_.v6;
-}
-
-}  // namespace quic
diff --git a/quic/platform/api/quic_ip_address.h b/quic/platform/api/quic_ip_address.h
deleted file mode 100644
index 26be870..0000000
--- a/quic/platform/api/quic_ip_address.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
-
-#if defined(_WIN32)
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#endif
-
-#include <ostream>
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quic {
-
-// Represents an IP address.
-class QUIC_EXPORT_PRIVATE QuicIpAddress {
- public:
-  // Sizes of IP addresses of different types, in bytes.
-  enum : size_t {
-    kIPv4AddressSize = 32 / 8,
-    kIPv6AddressSize = 128 / 8,
-    kMaxAddressSize = kIPv6AddressSize,
-  };
-
-  // TODO(fayang): Remove Loopback*() and use TestLoopback*() in tests.
-  static QuicIpAddress Loopback4();
-  static QuicIpAddress Loopback6();
-  static QuicIpAddress Any4();
-  static QuicIpAddress Any6();
-
-  QuicIpAddress();
-  QuicIpAddress(const QuicIpAddress& other) = default;
-  explicit QuicIpAddress(const in_addr& ipv4_address);
-  explicit QuicIpAddress(const in6_addr& ipv6_address);
-  QuicIpAddress& operator=(const QuicIpAddress& other) = default;
-  QuicIpAddress& operator=(QuicIpAddress&& other) = default;
-  QUIC_EXPORT_PRIVATE friend bool operator==(QuicIpAddress lhs,
-                                             QuicIpAddress rhs);
-  QUIC_EXPORT_PRIVATE friend bool operator!=(QuicIpAddress lhs,
-                                             QuicIpAddress rhs);
-
-  bool IsInitialized() const;
-  IpAddressFamily address_family() const;
-  int AddressFamilyToInt() const;
-  // Returns the address as a sequence of bytes in network-byte-order. IPv4 will
-  // be 4 bytes. IPv6 will be 16 bytes.
-  std::string ToPackedString() const;
-  // Returns string representation of the address.
-  std::string ToString() const;
-  // Normalizes the address representation with respect to IPv4 addresses, i.e,
-  // mapped IPv4 addresses ("::ffff:X.Y.Z.Q") are converted to pure IPv4
-  // addresses.  All other IPv4, IPv6, and empty values are left unchanged.
-  QuicIpAddress Normalized() const;
-  // Returns an address suitable for use in IPv6-aware contexts.  This is the
-  // opposite of NormalizeIPAddress() above.  IPv4 addresses are converted into
-  // their IPv4-mapped address equivalents (e.g. 192.0.2.1 becomes
-  // ::ffff:192.0.2.1).  IPv6 addresses are a noop (they are returned
-  // unchanged).
-  QuicIpAddress DualStacked() const;
-  bool FromPackedString(const char* data, size_t length);
-  bool FromString(std::string str);
-  bool IsIPv4() const;
-  bool IsIPv6() const;
-  bool InSameSubnet(const QuicIpAddress& other, int subnet_length);
-
-  in_addr GetIPv4() const;
-  in6_addr GetIPv6() const;
-
- private:
-  union {
-    in_addr v4;
-    in6_addr v6;
-    uint8_t bytes[kMaxAddressSize];
-    char chars[kMaxAddressSize];
-  } address_;
-  IpAddressFamily family_;
-};
-
-inline std::ostream& operator<<(std::ostream& os, const QuicIpAddress address) {
-  os << address.ToString();
-  return os;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
diff --git a/quic/platform/api/quic_ip_address_test.cc b/quic/platform/api/quic_ip_address_test.cc
deleted file mode 100644
index 3d12ed9..0000000
--- a/quic/platform/api/quic_ip_address_test.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_ip_address.h"
-
-#include <cstdint>
-
-#include "quic/platform/api/quic_ip_address_family.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QuicIpAddressTest, IPv4) {
-  QuicIpAddress ip_address;
-  EXPECT_FALSE(ip_address.IsInitialized());
-
-  EXPECT_TRUE(ip_address.FromString("127.0.52.223"));
-  EXPECT_TRUE(ip_address.IsInitialized());
-
-  EXPECT_EQ(IpAddressFamily::IP_V4, ip_address.address_family());
-  EXPECT_TRUE(ip_address.IsIPv4());
-  EXPECT_FALSE(ip_address.IsIPv6());
-
-  EXPECT_EQ("127.0.52.223", ip_address.ToString());
-  const in_addr v4_address = ip_address.GetIPv4();
-  const uint8_t* const v4_address_ptr =
-      reinterpret_cast<const uint8_t*>(&v4_address);
-  EXPECT_EQ(127u, *(v4_address_ptr + 0));
-  EXPECT_EQ(0u, *(v4_address_ptr + 1));
-  EXPECT_EQ(52u, *(v4_address_ptr + 2));
-  EXPECT_EQ(223u, *(v4_address_ptr + 3));
-}
-
-TEST(QuicIpAddressTest, IPv6) {
-  QuicIpAddress ip_address;
-  EXPECT_FALSE(ip_address.IsInitialized());
-
-  EXPECT_TRUE(ip_address.FromString("fe80::1ff:fe23:4567"));
-  EXPECT_TRUE(ip_address.IsInitialized());
-
-  EXPECT_EQ(IpAddressFamily::IP_V6, ip_address.address_family());
-  EXPECT_FALSE(ip_address.IsIPv4());
-  EXPECT_TRUE(ip_address.IsIPv6());
-
-  EXPECT_EQ("fe80::1ff:fe23:4567", ip_address.ToString());
-  const in6_addr v6_address = ip_address.GetIPv6();
-  const uint16_t* const v6_address_ptr =
-      reinterpret_cast<const uint16_t*>(&v6_address);
-  EXPECT_EQ(0x80feu, *(v6_address_ptr + 0));
-  EXPECT_EQ(0x0000u, *(v6_address_ptr + 1));
-  EXPECT_EQ(0x0000u, *(v6_address_ptr + 2));
-  EXPECT_EQ(0x0000u, *(v6_address_ptr + 3));
-  EXPECT_EQ(0x0000u, *(v6_address_ptr + 4));
-  EXPECT_EQ(0xff01u, *(v6_address_ptr + 5));
-  EXPECT_EQ(0x23feu, *(v6_address_ptr + 6));
-  EXPECT_EQ(0x6745u, *(v6_address_ptr + 7));
-
-  EXPECT_EQ(ip_address, ip_address.Normalized());
-  EXPECT_EQ(ip_address, ip_address.DualStacked());
-}
-
-TEST(QuicIpAddressTest, FromPackedString) {
-  QuicIpAddress loopback4, loopback6;
-  const char loopback4_packed[] = "\x7f\0\0\x01";
-  const char loopback6_packed[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01";
-  EXPECT_TRUE(loopback4.FromPackedString(loopback4_packed, 4));
-  EXPECT_TRUE(loopback6.FromPackedString(loopback6_packed, 16));
-  EXPECT_EQ(loopback4, QuicIpAddress::Loopback4());
-  EXPECT_EQ(loopback6, QuicIpAddress::Loopback6());
-}
-
-TEST(QuicIpAddressTest, MappedAddress) {
-  QuicIpAddress ipv4_address;
-  QuicIpAddress mapped_address;
-
-  EXPECT_TRUE(ipv4_address.FromString("127.0.0.1"));
-  EXPECT_TRUE(mapped_address.FromString("::ffff:7f00:1"));
-
-  EXPECT_EQ(mapped_address, ipv4_address.DualStacked());
-  EXPECT_EQ(ipv4_address, mapped_address.Normalized());
-}
-
-TEST(QuicIpAddressTest, Subnets) {
-  struct {
-    const char* address1;
-    const char* address2;
-    int subnet_size;
-    bool same_subnet;
-  } test_cases[] = {
-      {"127.0.0.1", "127.0.0.2", 24, true},
-      {"8.8.8.8", "127.0.0.1", 24, false},
-      {"8.8.8.8", "127.0.0.1", 16, false},
-      {"8.8.8.8", "127.0.0.1", 8, false},
-      {"8.8.8.8", "127.0.0.1", 2, false},
-      {"8.8.8.8", "127.0.0.1", 1, true},
-
-      {"127.0.0.1", "127.0.0.128", 24, true},
-      {"127.0.0.1", "127.0.0.128", 25, false},
-      {"127.0.0.1", "127.0.0.127", 25, true},
-
-      {"127.0.0.1", "127.0.0.0", 30, true},
-      {"127.0.0.1", "127.0.0.1", 30, true},
-      {"127.0.0.1", "127.0.0.2", 30, true},
-      {"127.0.0.1", "127.0.0.3", 30, true},
-      {"127.0.0.1", "127.0.0.4", 30, false},
-
-      {"127.0.0.1", "127.0.0.2", 31, false},
-      {"127.0.0.1", "127.0.0.0", 31, true},
-
-      {"::1", "fe80::1", 8, false},
-      {"::1", "fe80::1", 1, false},
-      {"::1", "fe80::1", 0, true},
-      {"fe80::1", "fe80::2", 126, true},
-      {"fe80::1", "fe80::2", 127, false},
-  };
-
-  for (const auto& test_case : test_cases) {
-    QuicIpAddress address1, address2;
-    ASSERT_TRUE(address1.FromString(test_case.address1));
-    ASSERT_TRUE(address2.FromString(test_case.address2));
-    EXPECT_EQ(test_case.same_subnet,
-              address1.InSameSubnet(address2, test_case.subnet_size))
-        << "Addresses: " << test_case.address1 << ", " << test_case.address2
-        << "; subnet: /" << test_case.subnet_size;
-  }
-}
-
-TEST(QuicIpAddress, LoopbackAddresses) {
-  QuicIpAddress loopback4;
-  QuicIpAddress loopback6;
-  ASSERT_TRUE(loopback4.FromString("127.0.0.1"));
-  ASSERT_TRUE(loopback6.FromString("::1"));
-  EXPECT_EQ(loopback4, QuicIpAddress::Loopback4());
-  EXPECT_EQ(loopback6, QuicIpAddress::Loopback6());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/platform/api/quic_logging.h b/quic/platform/api/quic_logging.h
deleted file mode 100644
index 770d408..0000000
--- a/quic/platform/api/quic_logging.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
-
-#include "common/platform/api/quiche_logging.h"
-
-// Please note following QUIC_LOG are platform dependent:
-// INFO severity can be degraded (to VLOG(1) or DVLOG(1)).
-// Some platforms may not support QUIC_LOG_FIRST_N or QUIC_LOG_EVERY_N_SEC, and
-// they would simply be translated to LOG.
-
-#define QUIC_DVLOG QUICHE_DVLOG
-#define QUIC_DVLOG_IF QUICHE_DVLOG_IF
-#define QUIC_DLOG QUICHE_DLOG
-#define QUIC_DLOG_IF QUICHE_DLOG_IF
-#define QUIC_VLOG QUICHE_VLOG
-#define QUIC_LOG QUICHE_LOG
-#define QUIC_LOG_FIRST_N QUICHE_LOG_FIRST_N
-#define QUIC_LOG_EVERY_N_SEC QUICHE_LOG_EVERY_N_SEC
-#define QUIC_LOG_IF QUICHE_LOG_IF
-
-#define QUIC_PREDICT_FALSE QUICHE_PREDICT_FALSE
-#define QUIC_PREDICT_TRUE QUICHE_PREDICT_TRUE
-
-// This is a noop in release build.
-#define QUIC_NOTREACHED QUICHE_NOTREACHED
-
-#define QUIC_PLOG QUICHE_PLOG
-
-#define QUIC_DLOG_INFO_IS_ON QUICHE_DLOG_INFO_IS_ON
-#define QUIC_LOG_INFO_IS_ON QUICHE_LOG_INFO_IS_ON
-#define QUIC_LOG_WARNING_IS_ON QUICHE_LOG_WARNING_IS_ON
-#define QUIC_LOG_ERROR_IS_ON QUICHE_LOG_ERROR_IS_ON
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
diff --git a/quic/platform/api/quic_mock_log.h b/quic/platform/api/quic_mock_log.h
deleted file mode 100644
index 3a59aaf..0000000
--- a/quic/platform/api/quic_mock_log.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
-
-#include "common/platform/api/quiche_mock_log.h"
-
-using QuicMockLog = QuicheMockLogImpl;
-
-#define CREATE_QUIC_MOCK_LOG(log) CREATE_QUICHE_MOCK_LOG(log)
-
-#define EXPECT_QUIC_LOG_CALL(log) EXPECT_QUICHE_LOG_CALL(log)
-
-#define EXPECT_QUIC_LOG_CALL_CONTAINS(log, level, content) \
-  EXPECT_QUICHE_LOG_CALL_CONTAINS(log, level, content)
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
diff --git a/quic/platform/api/quic_mutex.h b/quic/platform/api/quic_mutex.h
deleted file mode 100644
index 6e3b52a..0000000
--- a/quic/platform/api/quic_mutex.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(b/178613777): Remove this file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
-
-#include "common/platform/api/quiche_mutex.h"
-
-#define QUIC_EXCLUSIVE_LOCKS_REQUIRED QUICHE_EXCLUSIVE_LOCKS_REQUIRED
-#define QUIC_GUARDED_BY QUICHE_GUARDED_BY
-#define QUIC_LOCKABLE QUICHE_LOCKABLE
-#define QUIC_LOCKS_EXCLUDED QUICHE_LOCKS_EXCLUDED
-#define QUIC_SHARED_LOCKS_REQUIRED QUICHE_SHARED_LOCKS_REQUIRED
-#define QUIC_EXCLUSIVE_LOCK_FUNCTION QUICHE_EXCLUSIVE_LOCK_FUNCTION
-#define QUIC_UNLOCK_FUNCTION QUICHE_UNLOCK_FUNCTION
-#define QUIC_SHARED_LOCK_FUNCTION QUICHE_SHARED_LOCK_FUNCTION
-#define QUIC_SCOPED_LOCKABLE QUICHE_SCOPED_LOCKABLE
-#define QUIC_ASSERT_SHARED_LOCK QUICHE_ASSERT_SHARED_LOCK
-
-namespace quic {
-
-using QuicMutex = quiche::QuicheMutex;
-using QuicReaderMutexLock = quiche::QuicheReaderMutexLock;
-using QuicWriterMutexLock = quiche::QuicheWriterMutexLock;
-using QuicNotification = quiche::QuicheNotification;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
diff --git a/quic/platform/api/quic_server_stats.h b/quic/platform/api/quic_server_stats.h
deleted file mode 100644
index 0c5525f..0000000
--- a/quic/platform/api/quic_server_stats.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
-
-#include "common/platform/api/quiche_server_stats.h"
-
-#define QUIC_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
-  QUICHE_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring)
-
-#define QUIC_SERVER_HISTOGRAM_BOOL(name, sample, docstring) \
-  QUICHE_SERVER_HISTOGRAM_BOOL(name, sample, docstring)
-
-#define QUIC_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
-                                    docstring)                            \
-  QUICHE_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring)
-
-#define QUIC_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
-                                     docstring)                            \
-  QUICHE_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,     \
-                                 docstring)
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
diff --git a/quic/platform/api/quic_socket_address.cc b/quic/platform/api/quic_socket_address.cc
deleted file mode 100644
index f0b667c..0000000
--- a/quic/platform/api/quic_socket_address.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_socket_address.h"
-
-#include <cstring>
-#include <limits>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quic {
-
-namespace {
-
-uint32_t HashIP(const QuicIpAddress& ip) {
-  if (ip.IsIPv4()) {
-    return ip.GetIPv4().s_addr;
-  }
-  if (ip.IsIPv6()) {
-    auto v6addr = ip.GetIPv6();
-    const uint32_t* v6_as_ints =
-        reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
-    return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3];
-  }
-  return 0;
-}
-
-}  // namespace
-
-QuicSocketAddress::QuicSocketAddress(QuicIpAddress address, uint16_t port)
-    : host_(address), port_(port) {}
-
-QuicSocketAddress::QuicSocketAddress(const struct sockaddr_storage& saddr) {
-  switch (saddr.ss_family) {
-    case AF_INET: {
-      const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&saddr);
-      host_ = QuicIpAddress(v4->sin_addr);
-      port_ = ntohs(v4->sin_port);
-      break;
-    }
-    case AF_INET6: {
-      const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&saddr);
-      host_ = QuicIpAddress(v6->sin6_addr);
-      port_ = ntohs(v6->sin6_port);
-      break;
-    }
-    default:
-      QUIC_BUG(quic_bug_10075_1)
-          << "Unknown address family passed: " << saddr.ss_family;
-      break;
-  }
-}
-
-QuicSocketAddress::QuicSocketAddress(const sockaddr* saddr, socklen_t len) {
-  sockaddr_storage storage;
-  static_assert(std::numeric_limits<socklen_t>::max() >= sizeof(storage),
-                "Cannot cast sizeof(storage) to socklen_t as it does not fit");
-  if (len < static_cast<socklen_t>(sizeof(sockaddr)) ||
-      (saddr->sa_family == AF_INET &&
-       len < static_cast<socklen_t>(sizeof(sockaddr_in))) ||
-      (saddr->sa_family == AF_INET6 &&
-       len < static_cast<socklen_t>(sizeof(sockaddr_in6))) ||
-      len > static_cast<socklen_t>(sizeof(storage))) {
-    QUIC_BUG(quic_bug_10075_2) << "Socket address of invalid length provided";
-    return;
-  }
-  memcpy(&storage, saddr, len);
-  *this = QuicSocketAddress(storage);
-}
-
-bool operator==(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
-  return lhs.host_ == rhs.host_ && lhs.port_ == rhs.port_;
-}
-
-bool operator!=(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
-  return !(lhs == rhs);
-}
-
-bool QuicSocketAddress::IsInitialized() const {
-  return host_.IsInitialized();
-}
-
-std::string QuicSocketAddress::ToString() const {
-  switch (host_.address_family()) {
-    case IpAddressFamily::IP_V4:
-      return absl::StrCat(host_.ToString(), ":", port_);
-    case IpAddressFamily::IP_V6:
-      return absl::StrCat("[", host_.ToString(), "]:", port_);
-    default:
-      return "";
-  }
-}
-
-int QuicSocketAddress::FromSocket(int fd) {
-  sockaddr_storage addr;
-  socklen_t addr_len = sizeof(addr);
-  int result = getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len);
-
-  bool success = result == 0 && addr_len > 0 &&
-                 static_cast<size_t>(addr_len) <= sizeof(addr);
-  if (success) {
-    *this = QuicSocketAddress(addr);
-    return 0;
-  }
-  return -1;
-}
-
-QuicSocketAddress QuicSocketAddress::Normalized() const {
-  return QuicSocketAddress(host_.Normalized(), port_);
-}
-
-QuicIpAddress QuicSocketAddress::host() const {
-  return host_;
-}
-
-uint16_t QuicSocketAddress::port() const {
-  return port_;
-}
-
-sockaddr_storage QuicSocketAddress::generic_address() const {
-  union {
-    sockaddr_storage storage;
-    sockaddr_in v4;
-    sockaddr_in6 v6;
-  } result;
-  memset(&result.storage, 0, sizeof(result.storage));
-
-  switch (host_.address_family()) {
-    case IpAddressFamily::IP_V4:
-      result.v4.sin_family = AF_INET;
-      result.v4.sin_addr = host_.GetIPv4();
-      result.v4.sin_port = htons(port_);
-      break;
-    case IpAddressFamily::IP_V6:
-      result.v6.sin6_family = AF_INET6;
-      result.v6.sin6_addr = host_.GetIPv6();
-      result.v6.sin6_port = htons(port_);
-      break;
-    default:
-      result.storage.ss_family = AF_UNSPEC;
-      break;
-  }
-  return result.storage;
-}
-
-uint32_t QuicSocketAddress::Hash() const {
-  uint32_t value = 0;
-  value ^= HashIP(host_);
-  value ^= port_ | (port_ << 16);
-  return value;
-}
-
-}  // namespace quic
diff --git a/quic/platform/api/quic_socket_address.h b/quic/platform/api/quic_socket_address.h
deleted file mode 100644
index df6b9b7..0000000
--- a/quic/platform/api/quic_socket_address.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
-
-#include <string>
-
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// A class representing a socket endpoint address (i.e., IP address plus a
-// port) in QUIC.
-class QUIC_EXPORT_PRIVATE QuicSocketAddress {
- public:
-  QuicSocketAddress() {}
-  QuicSocketAddress(QuicIpAddress address, uint16_t port);
-  explicit QuicSocketAddress(const struct sockaddr_storage& saddr);
-  explicit QuicSocketAddress(const sockaddr* saddr, socklen_t len);
-  QuicSocketAddress(const QuicSocketAddress& other) = default;
-  QuicSocketAddress& operator=(const QuicSocketAddress& other) = default;
-  QuicSocketAddress& operator=(QuicSocketAddress&& other) = default;
-  QUIC_EXPORT_PRIVATE friend bool operator==(const QuicSocketAddress& lhs,
-                                             const QuicSocketAddress& rhs);
-  QUIC_EXPORT_PRIVATE friend bool operator!=(const QuicSocketAddress& lhs,
-                                             const QuicSocketAddress& rhs);
-
-  bool IsInitialized() const;
-  std::string ToString() const;
-  int FromSocket(int fd);
-  QuicSocketAddress Normalized() const;
-
-  QuicIpAddress host() const;
-  uint16_t port() const;
-  sockaddr_storage generic_address() const;
-
-  // Hashes this address to an uint32_t.
-  uint32_t Hash() const;
-
- private:
-  QuicIpAddress host_;
-  uint16_t port_ = 0;
-};
-
-inline std::ostream& operator<<(std::ostream& os,
-                                const QuicSocketAddress address) {
-  os << address.ToString();
-  return os;
-}
-
-class QUIC_EXPORT_PRIVATE QuicSocketAddressHash {
- public:
-  size_t operator()(QuicSocketAddress const& address) const noexcept {
-    return address.Hash();
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
diff --git a/quic/platform/api/quic_socket_address_test.cc b/quic/platform/api/quic_socket_address_test.cc
deleted file mode 100644
index 1d7737d..0000000
--- a/quic/platform/api/quic_socket_address_test.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/platform/api/quic_socket_address.h"
-
-#include <memory>
-#include <sstream>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-TEST(QuicSocketAddress, Uninitialized) {
-  QuicSocketAddress uninitialized;
-  EXPECT_FALSE(uninitialized.IsInitialized());
-}
-
-TEST(QuicSocketAddress, ExplicitConstruction) {
-  QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
-  QuicSocketAddress ipv6_address(QuicIpAddress::Loopback6(), 443);
-  EXPECT_TRUE(ipv4_address.IsInitialized());
-  EXPECT_EQ("127.0.0.1:443", ipv4_address.ToString());
-  EXPECT_EQ("[::1]:443", ipv6_address.ToString());
-  EXPECT_EQ(QuicIpAddress::Loopback4(), ipv4_address.host());
-  EXPECT_EQ(QuicIpAddress::Loopback6(), ipv6_address.host());
-  EXPECT_EQ(443, ipv4_address.port());
-}
-
-TEST(QuicSocketAddress, OutputToStream) {
-  QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
-  std::stringstream stream;
-  stream << ipv4_address;
-  EXPECT_EQ("127.0.0.1:443", stream.str());
-}
-
-TEST(QuicSocketAddress, FromSockaddrIPv4) {
-  union {
-    sockaddr_storage storage;
-    sockaddr addr;
-    sockaddr_in v4;
-  } address;
-
-  memset(&address, 0, sizeof(address));
-  address.v4.sin_family = AF_INET;
-  address.v4.sin_addr = QuicIpAddress::Loopback4().GetIPv4();
-  address.v4.sin_port = htons(443);
-  EXPECT_EQ("127.0.0.1:443",
-            QuicSocketAddress(&address.addr, sizeof(address.v4)).ToString());
-  EXPECT_EQ("127.0.0.1:443", QuicSocketAddress(address.storage).ToString());
-}
-
-TEST(QuicSocketAddress, FromSockaddrIPv6) {
-  union {
-    sockaddr_storage storage;
-    sockaddr addr;
-    sockaddr_in6 v6;
-  } address;
-
-  memset(&address, 0, sizeof(address));
-  address.v6.sin6_family = AF_INET6;
-  address.v6.sin6_addr = QuicIpAddress::Loopback6().GetIPv6();
-  address.v6.sin6_port = htons(443);
-  EXPECT_EQ("[::1]:443",
-            QuicSocketAddress(&address.addr, sizeof(address.v6)).ToString());
-  EXPECT_EQ("[::1]:443", QuicSocketAddress(address.storage).ToString());
-}
-
-TEST(QuicSocketAddres, ToSockaddrIPv4) {
-  union {
-    sockaddr_storage storage;
-    sockaddr_in v4;
-  } address;
-
-  address.storage =
-      QuicSocketAddress(QuicIpAddress::Loopback4(), 443).generic_address();
-  ASSERT_EQ(AF_INET, address.v4.sin_family);
-  EXPECT_EQ(QuicIpAddress::Loopback4(), QuicIpAddress(address.v4.sin_addr));
-  EXPECT_EQ(htons(443), address.v4.sin_port);
-}
-
-TEST(QuicSocketAddress, Normalize) {
-  QuicIpAddress dual_stacked;
-  ASSERT_TRUE(dual_stacked.FromString("::ffff:127.0.0.1"));
-  ASSERT_TRUE(dual_stacked.IsIPv6());
-  QuicSocketAddress not_normalized(dual_stacked, 443);
-  QuicSocketAddress normalized = not_normalized.Normalized();
-  EXPECT_EQ("[::ffff:127.0.0.1]:443", not_normalized.ToString());
-  EXPECT_EQ("127.0.0.1:443", normalized.ToString());
-}
-
-// TODO(vasilvv): either ensure this works on all platforms, or deprecate and
-// remove this API.
-#if defined(__linux__) && !defined(ANDROID)
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-TEST(QuicSocketAddress, FromSocket) {
-  int fd;
-  QuicSocketAddress address;
-  bool bound = false;
-  for (int port = 50000; port < 50400; port++) {
-    fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
-    ASSERT_GT(fd, 0);
-
-    address = QuicSocketAddress(QuicIpAddress::Loopback6(), port);
-    sockaddr_storage raw_address = address.generic_address();
-    int bind_result = bind(fd, reinterpret_cast<const sockaddr*>(&raw_address),
-                           sizeof(sockaddr_in6));
-
-    if (bind_result < 0 && errno == EADDRINUSE) {
-      close(fd);
-      continue;
-    }
-
-    ASSERT_EQ(0, bind_result);
-    bound = true;
-    break;
-  }
-  ASSERT_TRUE(bound);
-
-  QuicSocketAddress real_address;
-  ASSERT_EQ(0, real_address.FromSocket(fd));
-  ASSERT_TRUE(real_address.IsInitialized());
-  EXPECT_EQ(real_address, address);
-  close(fd);
-}
-#endif
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/platform/api/quic_stack_trace.h b/quic/platform/api/quic_stack_trace.h
deleted file mode 100644
index c1dd297..0000000
--- a/quic/platform/api/quic_stack_trace.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
-
-#include <string>
-
-#include "common/platform/api/quiche_stack_trace.h"
-
-namespace quic {
-
-inline std::string QuicStackTrace() { return quiche::QuicheStackTrace(); }
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
diff --git a/quic/platform/api/quic_stream_buffer_allocator.h b/quic/platform/api/quic_stream_buffer_allocator.h
deleted file mode 100644
index fb91327..0000000
--- a/quic/platform/api/quic_stream_buffer_allocator.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
-
-#include "common/platform/api/quiche_stream_buffer_allocator.h"
-
-namespace quic {
-
-using QuicStreamBufferAllocator = quiche::QuicheStreamBufferAllocator;
-}
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
diff --git a/quic/platform/api/quic_test.h b/quic/platform/api/quic_test.h
deleted file mode 100644
index 90228ee..0000000
--- a/quic/platform/api/quic_test.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
-
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_test.h"
-
-using QuicFlagSaver = QuicheFlagSaver;
-
-// Defines the base classes to be used in QUIC tests.
-using QuicTest = QuicheTest;
-template <class T>
-using QuicTestWithParam = QuicheTestWithParam<T>;
-
-// Class which needs to be instantiated in tests which use threads.
-using ScopedEnvironmentForThreads = ScopedEnvironmentForThreadsImpl;
-
-#define QUIC_TEST_DISABLED_IN_CHROME(name) QUICHE_TEST_DISABLED_IN_CHROME(name)
-
-inline std::string QuicGetTestMemoryCachePath() {
-  return QuicheGetTestMemoryCachePath();
-}
-
-#define QUIC_SLOW_TEST(test) QUICHE_SLOW_TEST(test)
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
diff --git a/quic/platform/api/quic_test_loopback.h b/quic/platform/api/quic_test_loopback.h
deleted file mode 100644
index 0e579cb..0000000
--- a/quic/platform/api/quic_test_loopback.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-#include "common/platform/api/quiche_test_loopback.h"
-
-namespace quic {
-
-// Returns the address family (IPv4 or IPv6) used to run test under.
-inline IpAddressFamily AddressFamilyUnderTest() {
-  return quiche::AddressFamilyUnderTest();
-}
-
-// Returns an IPv4 loopback address.
-inline QuicIpAddress TestLoopback4() { return quiche::TestLoopback4(); }
-
-// Returns the only IPv6 loopback address.
-inline QuicIpAddress TestLoopback6() { return quiche::TestLoopback6(); }
-
-// Returns an appropriate IPv4/Ipv6 loopback address based upon whether the
-// test's environment.
-inline QuicIpAddress TestLoopback() { return quiche::TestLoopback(); }
-
-// If address family under test is IPv4, returns an indexed IPv4 loopback
-// address. If address family under test is IPv6, the address returned is
-// platform-dependent.
-inline QuicIpAddress TestLoopback(int index) {
-  return quiche::TestLoopback(index);
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
diff --git a/quic/platform/api/quic_test_output.h b/quic/platform/api/quic_test_output.h
deleted file mode 100644
index 2774018..0000000
--- a/quic/platform/api/quic_test_output.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test_output.h"
-
-namespace quic {
-
-inline void QuicSaveTestOutput(absl::string_view filename,
-                               absl::string_view data) {
-  quiche::QuicheSaveTestOutput(filename, data);
-}
-
-inline bool QuicLoadTestOutput(absl::string_view filename, std::string* data) {
-  return quiche::QuicheLoadTestOutput(filename, data);
-}
-
-inline void QuicRecordTrace(absl::string_view identifier,
-                            absl::string_view data) {
-  quiche::QuicheRecordTrace(identifier, data);
-}
-
-}  // namespace quic
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
diff --git a/quic/platform/api/quic_testvalue.h b/quic/platform/api/quic_testvalue.h
deleted file mode 100644
index a9b68be..0000000
--- a/quic/platform/api/quic_testvalue.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(b/178613777): Remove this file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_testvalue.h"
-
-namespace quic {
-
-template <class T>
-void AdjustTestValue(absl::string_view label, T* var) {
-  quiche::AdjustTestValue(label, var);
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
diff --git a/quic/platform/api/quic_thread.h b/quic/platform/api/quic_thread.h
deleted file mode 100644
index 9b7406d..0000000
--- a/quic/platform/api/quic_thread.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
-
-#include "common/platform/api/quiche_thread.h"
-
-namespace quic {
-
-using QuicThread = quiche::QuicheThread;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
diff --git a/quic/platform/api/quic_udp_socket_platform_api.h b/quic/platform/api/quic_udp_socket_platform_api.h
deleted file mode 100644
index 5b55c1a..0000000
--- a/quic/platform/api/quic_udp_socket_platform_api.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
-
-#include "common/platform/api/quiche_udp_socket_platform_api.h"
-
-namespace quic {
-
-const size_t kCmsgSpaceForGooglePacketHeader =
-    quiche::kCmsgSpaceForGooglePacketHeader;
-
-inline bool GetGooglePacketHeadersFromControlMessage(
-    struct ::cmsghdr* cmsg,
-    char** packet_headers,
-    size_t* packet_headers_len) {
-  return quiche::GetGooglePacketHeadersFromControlMessage(cmsg, packet_headers,
-                                                          packet_headers_len);
-}
-
-inline void SetGoogleSocketOptions(int fd) {
-  quiche::SetGoogleSocketOptions(fd);
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
diff --git a/quic/qbone/bonnet/icmp_reachable.cc b/quic/qbone/bonnet/icmp_reachable.cc
deleted file mode 100644
index 8e39996..0000000
--- a/quic/qbone/bonnet/icmp_reachable.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/icmp_reachable.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "common/quiche_endian.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-constexpr int kEpollFlags = EPOLLIN | EPOLLET;
-constexpr size_t kMtu = 1280;
-
-constexpr size_t kIPv6AddrSize = sizeof(in6_addr);
-
-}  // namespace
-
-const char kUnknownSource[] = "UNKNOWN";
-const char kNoSource[] = "N/A";
-
-IcmpReachable::IcmpReachable(QuicIpAddress source,
-                             QuicIpAddress destination,
-                             absl::Duration timeout,
-                             KernelInterface* kernel,
-                             QuicEpollServer* epoll_server,
-                             StatsInterface* stats)
-    : timeout_(timeout),
-      cb_(this),
-      kernel_(kernel),
-      epoll_server_(epoll_server),
-      stats_(stats),
-      send_fd_(0),
-      recv_fd_(0) {
-  src_.sin6_family = AF_INET6;
-  dst_.sin6_family = AF_INET6;
-
-  memcpy(&src_.sin6_addr, source.ToPackedString().data(), kIPv6AddrSize);
-  memcpy(&dst_.sin6_addr, destination.ToPackedString().data(), kIPv6AddrSize);
-}
-
-IcmpReachable::~IcmpReachable() {
-  if (send_fd_ > 0) {
-    kernel_->close(send_fd_);
-  }
-  if (recv_fd_ > 0) {
-    if (!epoll_server_->ShutdownCalled()) {
-      epoll_server_->UnregisterFD(recv_fd_);
-    }
-
-    kernel_->close(recv_fd_);
-  }
-}
-
-bool IcmpReachable::Init() {
-  send_fd_ = kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW);
-  if (send_fd_ < 0) {
-    QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
-    return false;
-  }
-
-  if (kernel_->bind(send_fd_, reinterpret_cast<struct sockaddr*>(&src_),
-                    sizeof(sockaddr_in6)) < 0) {
-    QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
-    return false;
-  }
-
-  recv_fd_ =
-      kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_ICMPV6);
-  if (recv_fd_ < 0) {
-    QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
-    return false;
-  }
-
-  if (kernel_->bind(recv_fd_, reinterpret_cast<struct sockaddr*>(&src_),
-                    sizeof(sockaddr_in6)) < 0) {
-    QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
-    return false;
-  }
-
-  icmp6_filter filter;
-  ICMP6_FILTER_SETBLOCKALL(&filter);
-  ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
-  if (kernel_->setsockopt(recv_fd_, SOL_ICMPV6, ICMP6_FILTER, &filter,
-                          sizeof(filter)) < 0) {
-    QUIC_LOG(ERROR) << "Unable to set ICMP6 filter.";
-    return false;
-  }
-
-  epoll_server_->RegisterFD(recv_fd_, &cb_, kEpollFlags);
-  epoll_server_->RegisterAlarm(0, this);
-
-  QuicWriterMutexLock mu(&header_lock_);
-  icmp_header_.icmp6_type = ICMP6_ECHO_REQUEST;
-  icmp_header_.icmp6_code = 0;
-
-  QuicRandom::GetInstance()->RandBytes(&icmp_header_.icmp6_id,
-                                       sizeof(uint16_t));
-
-  return true;
-}
-
-bool IcmpReachable::OnEvent(int fd) {
-  char buffer[kMtu];
-
-  sockaddr_in6 source_addr{};
-  socklen_t source_addr_len = sizeof(source_addr);
-
-  ssize_t size = kernel_->recvfrom(fd, &buffer, kMtu, 0,
-                                   reinterpret_cast<sockaddr*>(&source_addr),
-                                   &source_addr_len);
-
-  if (size < 0) {
-    if (errno != EAGAIN && errno != EWOULDBLOCK) {
-      stats_->OnReadError(errno);
-    }
-    return false;
-  }
-
-  QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(
-      absl::string_view(buffer, size));
-
-  auto* header = reinterpret_cast<const icmp6_hdr*>(&buffer);
-  QuicWriterMutexLock mu(&header_lock_);
-  if (header->icmp6_data32[0] != icmp_header_.icmp6_data32[0]) {
-    QUIC_VLOG(2) << "Unexpected response. id: " << header->icmp6_id
-                 << " seq: " << header->icmp6_seq
-                 << " Expected id: " << icmp_header_.icmp6_id
-                 << " seq: " << icmp_header_.icmp6_seq;
-    return true;
-  }
-  end_ = absl::Now();
-  QUIC_VLOG(1) << "Received ping response in "
-               << absl::ToInt64Microseconds(end_ - start_) << "us.";
-
-  std::string source;
-  QuicIpAddress source_ip;
-  if (!source_ip.FromPackedString(
-          reinterpret_cast<char*>(&source_addr.sin6_addr), sizeof(in6_addr))) {
-    QUIC_LOG(WARNING) << "Unable to parse source address.";
-    source = kUnknownSource;
-  } else {
-    source = source_ip.ToString();
-  }
-  stats_->OnEvent({Status::REACHABLE, end_ - start_, source});
-  return true;
-}
-
-int64 /* allow-non-std-int */ IcmpReachable::OnAlarm() {
-  EpollAlarm::OnAlarm();
-
-  QuicWriterMutexLock mu(&header_lock_);
-
-  if (end_ < start_) {
-    QUIC_VLOG(1) << "Timed out on sequence: " << icmp_header_.icmp6_seq;
-    stats_->OnEvent({Status::UNREACHABLE, absl::ZeroDuration(), kNoSource});
-  }
-
-  icmp_header_.icmp6_seq++;
-  CreateIcmpPacket(src_.sin6_addr, dst_.sin6_addr, icmp_header_, "",
-                   [this](absl::string_view packet) {
-                     QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(packet);
-
-                     ssize_t size = kernel_->sendto(
-                         send_fd_, packet.data(), packet.size(), 0,
-                         reinterpret_cast<struct sockaddr*>(&dst_),
-                         sizeof(sockaddr_in6));
-
-                     if (size < packet.size()) {
-                       stats_->OnWriteError(errno);
-                     }
-                     start_ = absl::Now();
-                   });
-
-  return absl::ToUnixMicros(absl::Now() + timeout_);
-}
-
-absl::string_view IcmpReachable::StatusName(IcmpReachable::Status status) {
-  switch (status) {
-    case REACHABLE:
-      return "REACHABLE";
-    case UNREACHABLE:
-      return "UNREACHABLE";
-    default:
-      return "UNKNOWN";
-  }
-}
-
-void IcmpReachable::EpollCallback::OnEvent(int fd, QuicEpollEvent* event) {
-  bool can_read_more = reachable_->OnEvent(fd);
-  if (can_read_more) {
-    event->out_ready_mask |= EPOLLIN;
-  }
-}
-
-void IcmpReachable::EpollCallback::OnShutdown(QuicEpollServer* eps, int fd) {
-  eps->UnregisterFD(fd);
-}
-
-std::string IcmpReachable::EpollCallback::Name() const {
-  return "ICMP Reachable";
-}
-
-}  // namespace quic
diff --git a/quic/qbone/bonnet/icmp_reachable.h b/quic/qbone/bonnet/icmp_reachable.h
deleted file mode 100644
index 7faf873..0000000
--- a/quic/qbone/bonnet/icmp_reachable.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
-#define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
-
-#include <netinet/icmp6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/qbone/bonnet/icmp_reachable_interface.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-namespace quic {
-
-extern const char kUnknownSource[];
-extern const char kNoSource[];
-
-// IcmpReachable schedules itself with an EpollServer, periodically sending
-// ICMPv6 Echo Requests to the given |destination| on the interface that the
-// given |source| is bound to. Echo Requests are sent once every |timeout|.
-// On Echo Replies, timeouts, and I/O errors, the given |stats| object will
-// be called back with details of the event.
-class IcmpReachable : public IcmpReachableInterface {
- public:
-  enum Status { REACHABLE, UNREACHABLE };
-
-  struct ReachableEvent {
-    Status status;
-    absl::Duration response_time;
-    std::string source;
-  };
-
-  class StatsInterface {
-   public:
-    StatsInterface() = default;
-
-    StatsInterface(const StatsInterface&) = delete;
-    StatsInterface& operator=(const StatsInterface&) = delete;
-
-    StatsInterface(StatsInterface&&) = delete;
-    StatsInterface& operator=(StatsInterface&&) = delete;
-
-    virtual ~StatsInterface() = default;
-
-    virtual void OnEvent(ReachableEvent event) = 0;
-
-    virtual void OnReadError(int error) = 0;
-
-    virtual void OnWriteError(int error) = 0;
-  };
-
-  // |source| is the IPv6 address bound to the interface that IcmpReachable will
-  //          send Echo Requests on.
-  // |destination| is the IPv6 address of the destination of the Echo Requests.
-  // |timeout| is the duration IcmpReachable will wait between Echo Requests.
-  //           If no Echo Response is received by the next Echo Request, it will
-  //           be considered a timeout.
-  // |kernel| is not owned, but should outlive this instance.
-  // |epoll_server| is not owned, but should outlive this instance.
-  //                IcmpReachable's Init() must be called from within the Epoll
-  //                Server's thread.
-  // |stats| is not owned, but should outlive this instance. It will be called
-  //         back on Echo Replies, timeouts, and I/O errors.
-  IcmpReachable(QuicIpAddress source,
-                QuicIpAddress destination,
-                absl::Duration timeout,
-                KernelInterface* kernel,
-                QuicEpollServer* epoll_server,
-                StatsInterface* stats);
-
-  ~IcmpReachable() override;
-
-  // Initializes this reachability probe. Must be called from within the
-  // |epoll_server|'s thread.
-  bool Init() QUIC_LOCKS_EXCLUDED(header_lock_) override;
-
-  int64 /* allow-non-std-int */ OnAlarm()
-      QUIC_LOCKS_EXCLUDED(header_lock_) override;
-
-  static absl::string_view StatusName(Status status);
-
- private:
-  class EpollCallback : public QuicEpollCallbackInterface {
-   public:
-    explicit EpollCallback(IcmpReachable* reachable) : reachable_(reachable) {}
-
-    EpollCallback(const EpollCallback&) = delete;
-    EpollCallback& operator=(const EpollCallback&) = delete;
-
-    EpollCallback(EpollCallback&&) = delete;
-    EpollCallback& operator=(EpollCallback&&) = delete;
-
-    void OnRegistration(QuicEpollServer* eps,
-                        int fd,
-                        int event_mask) override{};
-
-    void OnModification(int fd, int event_mask) override{};
-
-    void OnEvent(int fd, QuicEpollEvent* event) override;
-
-    void OnUnregistration(int fd, bool replaced) override{};
-
-    void OnShutdown(QuicEpollServer* eps, int fd) override;
-
-    std::string Name() const override;
-
-   private:
-    IcmpReachable* reachable_;
-  };
-
-  bool OnEvent(int fd) QUIC_LOCKS_EXCLUDED(header_lock_);
-
-  const absl::Duration timeout_;
-
-  EpollCallback cb_;
-
-  sockaddr_in6 src_{};
-  sockaddr_in6 dst_{};
-
-  KernelInterface* kernel_;
-  QuicEpollServer* epoll_server_;
-
-  StatsInterface* stats_;
-
-  int send_fd_;
-  int recv_fd_;
-
-  QuicMutex header_lock_;
-  icmp6_hdr icmp_header_ QUIC_GUARDED_BY(header_lock_){};
-
-  absl::Time start_ = absl::InfinitePast();
-  absl::Time end_ = absl::InfinitePast();
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
diff --git a/quic/qbone/bonnet/icmp_reachable_interface.h b/quic/qbone/bonnet/icmp_reachable_interface.h
deleted file mode 100644
index f082bb6..0000000
--- a/quic/qbone/bonnet/icmp_reachable_interface.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
-
-#include "quic/platform/api/quic_epoll.h"
-
-namespace quic {
-
-class IcmpReachableInterface : public QuicEpollAlarmBase {
- public:
-  IcmpReachableInterface() = default;
-
-  IcmpReachableInterface(const IcmpReachableInterface&) = delete;
-  IcmpReachableInterface& operator=(const IcmpReachableInterface&) = delete;
-
-  IcmpReachableInterface(IcmpReachableInterface&&) = delete;
-  IcmpReachableInterface& operator=(IcmpReachableInterface&&) = delete;
-
-  // Initializes this reachability probe.
-  virtual bool Init() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
diff --git a/quic/qbone/bonnet/icmp_reachable_test.cc b/quic/qbone/bonnet/icmp_reachable_test.cc
deleted file mode 100644
index 221e5f6..0000000
--- a/quic/qbone/bonnet/icmp_reachable_test.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/icmp_reachable.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/container/node_hash_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_kernel.h"
-
-namespace quic {
-namespace {
-
-using ::testing::_;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-constexpr char kSourceAddress[] = "fe80:1:2:3:4::1";
-constexpr char kDestinationAddress[] = "fe80:4:3:2:1::1";
-
-constexpr int kFakeWriteFd = 0;
-
-icmp6_hdr GetHeaderFromPacket(const void* buf, size_t len) {
-  QUICHE_CHECK_GE(len, sizeof(ip6_hdr) + sizeof(icmp6_hdr));
-
-  auto* buffer = reinterpret_cast<const char*>(buf);
-  return *reinterpret_cast<const icmp6_hdr*>(&buffer[sizeof(ip6_hdr)]);
-}
-
-class StatsInterface : public IcmpReachable::StatsInterface {
- public:
-  void OnEvent(IcmpReachable::ReachableEvent event) override {
-    switch (event.status) {
-      case IcmpReachable::REACHABLE: {
-        reachable_count_++;
-        break;
-      }
-      case IcmpReachable::UNREACHABLE: {
-        unreachable_count_++;
-        break;
-      }
-    }
-    current_source_ = event.source;
-  }
-
-  void OnReadError(int error) override { read_errors_[error]++; }
-
-  void OnWriteError(int error) override { write_errors_[error]++; }
-
-  bool HasWriteErrors() { return !write_errors_.empty(); }
-
-  int WriteErrorCount(int error) { return write_errors_[error]; }
-
-  bool HasReadErrors() { return !read_errors_.empty(); }
-
-  int ReadErrorCount(int error) { return read_errors_[error]; }
-
-  int reachable_count() { return reachable_count_; }
-
-  int unreachable_count() { return unreachable_count_; }
-
-  std::string current_source() { return current_source_; }
-
- private:
-  int reachable_count_ = 0;
-  int unreachable_count_ = 0;
-
-  std::string current_source_{};
-
-  absl::node_hash_map<int, int> read_errors_;
-  absl::node_hash_map<int, int> write_errors_;
-};
-
-class IcmpReachableTest : public QuicTest {
- public:
-  IcmpReachableTest() {
-    QUICHE_CHECK(source_.FromString(kSourceAddress));
-    QUICHE_CHECK(destination_.FromString(kDestinationAddress));
-
-    int pipe_fds[2];
-    QUICHE_CHECK(pipe(pipe_fds) >= 0) << "pipe() failed";
-
-    read_fd_ = pipe_fds[0];
-    read_src_fd_ = pipe_fds[1];
-  }
-
-  void SetFdExpectations() {
-    InSequence seq;
-    EXPECT_CALL(kernel_, socket(_, _, _)).WillOnce(Return(kFakeWriteFd));
-    EXPECT_CALL(kernel_, bind(kFakeWriteFd, _, _)).WillOnce(Return(0));
-
-    EXPECT_CALL(kernel_, socket(_, _, _)).WillOnce(Return(read_fd_));
-    EXPECT_CALL(kernel_, bind(read_fd_, _, _)).WillOnce(Return(0));
-
-    EXPECT_CALL(kernel_, setsockopt(read_fd_, SOL_ICMPV6, ICMP6_FILTER, _, _));
-
-    EXPECT_CALL(kernel_, close(read_fd_)).WillOnce(Invoke([](int fd) {
-      return close(fd);
-    }));
-  }
-
- protected:
-  QuicIpAddress source_;
-  QuicIpAddress destination_;
-
-  int read_fd_;
-  int read_src_fd_;
-
-  StrictMock<MockKernel> kernel_;
-  QuicEpollServer epoll_server_;
-  StatsInterface stats_;
-};
-
-TEST_F(IcmpReachableTest, SendsPings) {
-  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
-                          &epoll_server_, &stats_);
-
-  SetFdExpectations();
-  ASSERT_TRUE(reachable.Init());
-
-  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
-      .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
-                          const struct sockaddr* dest_addr, socklen_t addrlen) {
-        auto icmp_header = GetHeaderFromPacket(buf, len);
-        EXPECT_EQ(icmp_header.icmp6_type, ICMP6_ECHO_REQUEST);
-        EXPECT_EQ(icmp_header.icmp6_seq, 1);
-        return len;
-      }));
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(stats_.HasWriteErrors());
-
-  epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesUnreachableEvents) {
-  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
-                          &epoll_server_, &stats_);
-
-  SetFdExpectations();
-  ASSERT_TRUE(reachable.Init());
-
-  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
-      .Times(2)
-      .WillRepeatedly(Invoke([](int sockfd, const void* buf, size_t len,
-                                int flags, const struct sockaddr* dest_addr,
-                                socklen_t addrlen) { return len; }));
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(stats_.unreachable_count(), 0);
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(stats_.HasWriteErrors());
-  EXPECT_EQ(stats_.unreachable_count(), 1);
-  EXPECT_EQ(stats_.current_source(), kNoSource);
-
-  epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesReachableEvents) {
-  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
-                          &epoll_server_, &stats_);
-
-  SetFdExpectations();
-  ASSERT_TRUE(reachable.Init());
-
-  icmp6_hdr last_request_hdr{};
-  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
-      .Times(2)
-      .WillRepeatedly(
-          Invoke([&last_request_hdr](
-                     int sockfd, const void* buf, size_t len, int flags,
-                     const struct sockaddr* dest_addr, socklen_t addrlen) {
-            last_request_hdr = GetHeaderFromPacket(buf, len);
-            return len;
-          }));
-
-  sockaddr_in6 source_addr{};
-  std::string packed_source = source_.ToPackedString();
-  memcpy(&source_addr.sin6_addr, packed_source.data(), packed_source.size());
-
-  EXPECT_CALL(kernel_, recvfrom(read_fd_, _, _, _, _, _))
-      .WillOnce(
-          Invoke([&source_addr](int sockfd, void* buf, size_t len, int flags,
-                                struct sockaddr* src_addr, socklen_t* addrlen) {
-            *reinterpret_cast<sockaddr_in6*>(src_addr) = source_addr;
-            return read(sockfd, buf, len);
-          }));
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(stats_.reachable_count(), 0);
-
-  icmp6_hdr response = last_request_hdr;
-  response.icmp6_type = ICMP6_ECHO_REPLY;
-
-  write(read_src_fd_, reinterpret_cast<const void*>(&response),
-        sizeof(icmp6_hdr));
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(stats_.HasReadErrors());
-  EXPECT_FALSE(stats_.HasWriteErrors());
-  EXPECT_EQ(stats_.reachable_count(), 1);
-  EXPECT_EQ(stats_.current_source(), source_.ToString());
-
-  epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesWriteErrors) {
-  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
-                          &epoll_server_, &stats_);
-
-  SetFdExpectations();
-  ASSERT_TRUE(reachable.Init());
-
-  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
-      .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
-                          const struct sockaddr* dest_addr, socklen_t addrlen) {
-        errno = EAGAIN;
-        return 0;
-      }));
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(stats_.WriteErrorCount(EAGAIN), 1);
-
-  epoll_server_.Shutdown();
-}
-
-TEST_F(IcmpReachableTest, HandlesReadErrors) {
-  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
-                          &epoll_server_, &stats_);
-
-  SetFdExpectations();
-  ASSERT_TRUE(reachable.Init());
-
-  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
-      .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
-                          const struct sockaddr* dest_addr,
-                          socklen_t addrlen) { return len; }));
-
-  EXPECT_CALL(kernel_, recvfrom(read_fd_, _, _, _, _, _))
-      .WillOnce(Invoke([](int sockfd, void* buf, size_t len, int flags,
-                          struct sockaddr* src_addr, socklen_t* addrlen) {
-        errno = EIO;
-        return -1;
-      }));
-
-  icmp6_hdr response{};
-
-  write(read_src_fd_, reinterpret_cast<const void*>(&response),
-        sizeof(icmp6_hdr));
-
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(stats_.reachable_count(), 0);
-  EXPECT_EQ(stats_.ReadErrorCount(EIO), 1);
-
-  epoll_server_.Shutdown();
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/bonnet/mock_icmp_reachable.h b/quic/qbone/bonnet/mock_icmp_reachable.h
deleted file mode 100644
index 02f364c..0000000
--- a/quic/qbone/bonnet/mock_icmp_reachable.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/icmp_reachable_interface.h"
-
-namespace quic {
-
-class MockIcmpReachable : public IcmpReachableInterface {
- public:
-  MOCK_METHOD(bool, Init, (), (override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
diff --git a/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h b/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
deleted file mode 100644
index c38f24d..0000000
--- a/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/tun_device_packet_exchanger.h"
-
-namespace quic {
-
-class MockPacketExchangerStatsInterface
-    : public TunDevicePacketExchanger::StatsInterface {
- public:
-  MOCK_METHOD(void, OnPacketRead, (size_t), (override));
-  MOCK_METHOD(void, OnPacketWritten, (size_t), (override));
-  MOCK_METHOD(void, OnReadError, (std::string*), (override));
-  MOCK_METHOD(void, OnWriteError, (std::string*), (override));
-
-  MOCK_METHOD(int64_t, PacketsRead, (), (const, override));
-  MOCK_METHOD(int64_t, PacketsWritten, (), (const, override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
diff --git a/quic/qbone/bonnet/mock_qbone_tunnel.h b/quic/qbone/bonnet/mock_qbone_tunnel.h
deleted file mode 100644
index 9fc7434..0000000
--- a/quic/qbone/bonnet/mock_qbone_tunnel.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/qbone_tunnel_interface.h"
-
-namespace quic {
-
-class MockQboneTunnel : public QboneTunnelInterface {
- public:
-  MockQboneTunnel() = default;
-
-  MOCK_METHOD(bool, WaitForEvents, (), (override));
-
-  MOCK_METHOD(void, Wake, (), (override));
-
-  MOCK_METHOD(void, ResetTunnel, (), (override));
-
-  MOCK_METHOD(State, Disconnect, (), (override));
-
-  MOCK_METHOD(void, OnControlRequest, (const quic::QboneClientRequest&),
-              (override));
-
-  MOCK_METHOD(void, OnControlError, (), (override));
-
-  MOCK_METHOD(bool, AwaitConnection, ());
-
-  MOCK_METHOD(std::string, StateToString, (State), (override));
-
-  MOCK_METHOD(quic::QboneClient*, client, (), (override));
-
-  MOCK_METHOD(State, state, ());
-
-  MOCK_METHOD(std::string, HealthString, ());
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
diff --git a/quic/qbone/bonnet/mock_tun_device.h b/quic/qbone/bonnet/mock_tun_device.h
deleted file mode 100644
index 056346c..0000000
--- a/quic/qbone/bonnet/mock_tun_device.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/tun_device_interface.h"
-
-namespace quic {
-
-class MockTunDevice : public TunDeviceInterface {
- public:
-  MOCK_METHOD(bool, Init, (), (override));
-
-  MOCK_METHOD(bool, Up, (), (override));
-
-  MOCK_METHOD(bool, Down, (), (override));
-
-  MOCK_METHOD(void, CloseDevice, (), (override));
-
-  MOCK_METHOD(int, GetFileDescriptor, (), (const, override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
diff --git a/quic/qbone/bonnet/mock_tun_device_controller.h b/quic/qbone/bonnet/mock_tun_device_controller.h
deleted file mode 100644
index 7773111..0000000
--- a/quic/qbone/bonnet/mock_tun_device_controller.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
-#define QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/tun_device_controller.h"
-
-namespace quic {
-
-class MockTunDeviceController : public TunDeviceController {
- public:
-  MockTunDeviceController() : TunDeviceController("", true, nullptr) {}
-
-  MOCK_METHOD(bool, UpdateAddress, (const IpRange&), (override));
-
-  MOCK_METHOD(bool, UpdateRoutes, (const IpRange&, const std::vector<IpRange>&),
-              (override));
-
-  MOCK_METHOD(QuicIpAddress, current_address, (), (override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
diff --git a/quic/qbone/bonnet/qbone_tunnel_info.cc b/quic/qbone/bonnet/qbone_tunnel_info.cc
deleted file mode 100644
index 372cd2b..0000000
--- a/quic/qbone/bonnet/qbone_tunnel_info.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/qbone_tunnel_info.h"
-
-namespace quic {
-
-QuicIpAddress QboneTunnelInfo::GetAddress() {
-  QuicIpAddress no_address;
-
-  NetlinkInterface::LinkInfo link_info{};
-  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
-    return no_address;
-  }
-
-  std::vector<NetlinkInterface::AddressInfo> addresses;
-  if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
-    return no_address;
-  }
-
-  quic::QuicIpAddress link_local_subnet;
-  if (!link_local_subnet.FromString("FE80::")) {
-    return no_address;
-  }
-
-  for (const auto& address : addresses) {
-    if (address.interface_address.IsInitialized() &&
-        !link_local_subnet.InSameSubnet(address.interface_address, 10)) {
-      return address.interface_address;
-    }
-  }
-
-  return no_address;
-}
-
-}  // namespace quic
diff --git a/quic/qbone/bonnet/qbone_tunnel_info.h b/quic/qbone/bonnet/qbone_tunnel_info.h
deleted file mode 100644
index 6ca6ae8..0000000
--- a/quic/qbone/bonnet/qbone_tunnel_info.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
-#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/netlink_interface.h"
-
-namespace quic {
-
-class QboneTunnelInfo {
- public:
-  QboneTunnelInfo(std::string ifname, NetlinkInterface* netlink)
-      : ifname_(std::move(ifname)), netlink_(netlink) {}
-
-  // Returns the current QBONE tunnel address. Callers must use IsInitialized()
-  // to ensure the returned address is valid.
-  QuicIpAddress GetAddress();
-
- private:
-  const std::string ifname_;
-  NetlinkInterface* netlink_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
diff --git a/quic/qbone/bonnet/qbone_tunnel_interface.h b/quic/qbone/bonnet/qbone_tunnel_interface.h
deleted file mode 100644
index ae19519..0000000
--- a/quic/qbone/bonnet/qbone_tunnel_interface.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
-
-#include "quic/qbone/qbone_client.h"
-
-namespace quic {
-
-// Interface for establishing bidirectional communication between a network
-// device and a QboneClient.
-class QboneTunnelInterface : public quic::QboneClientControlStream::Handler {
- public:
-  QboneTunnelInterface() = default;
-
-  QboneTunnelInterface(const QboneTunnelInterface&) = delete;
-  QboneTunnelInterface& operator=(const QboneTunnelInterface&) = delete;
-
-  QboneTunnelInterface(QboneTunnelInterface&&) = delete;
-  QboneTunnelInterface& operator=(QboneTunnelInterface&&) = delete;
-
-  enum State {
-    UNINITIALIZED,
-    IP_RANGE_REQUESTED,
-    START_REQUESTED,
-    STARTED,
-    LAME_DUCK_REQUESTED,
-    END_REQUESTED,
-    ENDED,
-    FAILED,
-  };
-
-  // Wait and handle any events which occur.
-  // Returns true if there are any outstanding requests.
-  virtual bool WaitForEvents() = 0;
-
-  // Wakes the tunnel if it is currently in WaitForEvents.
-  virtual void Wake() = 0;
-
-  // Disconnect the tunnel, resetting it to an uninitialized state. This will
-  // force ConnectIfNeeded to reconnect on the next epoll cycle.
-  virtual void ResetTunnel() = 0;
-
-  // Disconnect from the QBONE server.
-  virtual State Disconnect() = 0;
-
-  // Callback handling responses from the QBONE server.
-  void OnControlRequest(const QboneClientRequest& request) override = 0;
-
-  // Callback handling bad responses from the QBONE server. Currently, this is
-  // only called when the response is unparsable.
-  void OnControlError() override = 0;
-
-  // Returns a string value of the given state.
-  virtual std::string StateToString(State state) = 0;
-
-  virtual QboneClient* client() = 0;
-
-  virtual State state() = 0;
-
-  virtual std::string HealthString() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
diff --git a/quic/qbone/bonnet/qbone_tunnel_silo.cc b/quic/qbone/bonnet/qbone_tunnel_silo.cc
deleted file mode 100644
index 736829a..0000000
--- a/quic/qbone/bonnet/qbone_tunnel_silo.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/qbone_tunnel_silo.h"
-
-namespace quic {
-
-void QboneTunnelSilo::Run() {
-  while (ShouldRun()) {
-    tunnel_->WaitForEvents();
-  }
-
-  QUIC_LOG(INFO) << "Tunnel has disconnected in state: "
-                 << tunnel_->StateToString(tunnel_->Disconnect());
-}
-
-void QboneTunnelSilo::Quit() {
-  QUIC_LOG(INFO) << "Quit called on QboneTunnelSilo";
-  quitting_.Notify();
-  tunnel_->Wake();
-}
-
-bool QboneTunnelSilo::ShouldRun() {
-  bool post_init_shutdown_ready =
-      only_setup_tun_ &&
-      tunnel_->state() == quic::QboneTunnelInterface::STARTED;
-  return !quitting_.HasBeenNotified() && !post_init_shutdown_ready;
-}
-
-}  // namespace quic
diff --git a/quic/qbone/bonnet/qbone_tunnel_silo.h b/quic/qbone/bonnet/qbone_tunnel_silo.h
deleted file mode 100644
index cf8ce38..0000000
--- a/quic/qbone/bonnet/qbone_tunnel_silo.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
-#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
-
-#include "absl/synchronization/notification.h"
-#include "quic/platform/api/quic_thread.h"
-#include "quic/qbone/bonnet/qbone_tunnel_interface.h"
-
-namespace quic {
-
-// QboneTunnelSilo is a thread that initializes and evaluates a QboneTunnel's
-// event loop.
-class QboneTunnelSilo : public QuicThread {
- public:
-  // Does not take ownership of |tunnel|
-  explicit QboneTunnelSilo(QboneTunnelInterface* tunnel, bool only_setup_tun)
-      : QuicThread("QboneTunnelSilo"),
-        tunnel_(tunnel),
-        only_setup_tun_(only_setup_tun) {}
-
-  QboneTunnelSilo(const QboneTunnelSilo&) = delete;
-  QboneTunnelSilo& operator=(const QboneTunnelSilo&) = delete;
-
-  QboneTunnelSilo(QboneTunnelSilo&&) = delete;
-  QboneTunnelSilo& operator=(QboneTunnelSilo&&) = delete;
-
-  // Terminates the tunnel's event loop. This silo must still be joined.
-  void Quit();
-
- protected:
-  void Run() override;
-
- private:
-  bool ShouldRun();
-
-  QboneTunnelInterface* tunnel_;
-
-  absl::Notification quitting_;
-
-  const bool only_setup_tun_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
diff --git a/quic/qbone/bonnet/qbone_tunnel_silo_test.cc b/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
deleted file mode 100644
index 8327a53..0000000
--- a/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/qbone_tunnel_silo.h"
-
-#include "absl/synchronization/notification.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/mock_qbone_tunnel.h"
-
-namespace quic {
-namespace {
-
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::Return;
-
-TEST(QboneTunnelSiloTest, SiloRunsEventLoop) {
-  MockQboneTunnel mock_tunnel;
-
-  absl::Notification event_loop_run;
-  EXPECT_CALL(mock_tunnel, WaitForEvents)
-      .WillRepeatedly(Invoke([&event_loop_run]() {
-        if (!event_loop_run.HasBeenNotified()) {
-          event_loop_run.Notify();
-        }
-        return false;
-      }));
-
-  QboneTunnelSilo silo(&mock_tunnel, false);
-  silo.Start();
-
-  event_loop_run.WaitForNotification();
-
-  absl::Notification client_disconnected;
-  EXPECT_CALL(mock_tunnel, Disconnect)
-      .WillOnce(Invoke([&client_disconnected]() {
-        client_disconnected.Notify();
-        return QboneTunnelInterface::ENDED;
-      }));
-
-  silo.Quit();
-  client_disconnected.WaitForNotification();
-
-  silo.Join();
-}
-
-TEST(QboneTunnelSiloTest, SiloCanShutDownAfterInit) {
-  MockQboneTunnel mock_tunnel;
-
-  int iteration_count = 0;
-  EXPECT_CALL(mock_tunnel, WaitForEvents)
-      .WillRepeatedly(Invoke([&iteration_count]() {
-        iteration_count++;
-        return false;
-      }));
-
-  EXPECT_CALL(mock_tunnel, state)
-      .WillOnce(Return(QboneTunnelInterface::START_REQUESTED))
-      .WillOnce(Return(QboneTunnelInterface::STARTED));
-
-  absl::Notification client_disconnected;
-  EXPECT_CALL(mock_tunnel, Disconnect)
-      .WillOnce(Invoke([&client_disconnected]() {
-        client_disconnected.Notify();
-        return QboneTunnelInterface::ENDED;
-      }));
-
-  QboneTunnelSilo silo(&mock_tunnel, true);
-  silo.Start();
-
-  client_disconnected.WaitForNotification();
-  silo.Join();
-  EXPECT_THAT(iteration_count, Eq(1));
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device.cc b/quic/qbone/bonnet/tun_device.cc
deleted file mode 100644
index 3768a43..0000000
--- a/quic/qbone/bonnet/tun_device.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device.h"
-
-#include <fcntl.h>
-#include <linux/if_tun.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include "absl/cleanup/cleanup.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-ABSL_FLAG(std::string,
-          qbone_client_tun_device_path,
-          "/dev/net/tun",
-          "The path to the QBONE client's TUN device.");
-
-namespace quic {
-
-const int kInvalidFd = -1;
-
-TunTapDevice::TunTapDevice(const std::string& interface_name, int mtu,
-                           bool persist, bool setup_tun, bool is_tap,
-                           KernelInterface* kernel)
-    : interface_name_(interface_name),
-      mtu_(mtu),
-      persist_(persist),
-      setup_tun_(setup_tun),
-      is_tap_(is_tap),
-      file_descriptor_(kInvalidFd),
-      kernel_(*kernel) {}
-
-TunTapDevice::~TunTapDevice() {
-  if (!persist_) {
-    Down();
-  }
-  CloseDevice();
-}
-
-bool TunTapDevice::Init() {
-  if (interface_name_.empty() || interface_name_.size() >= IFNAMSIZ) {
-    QUIC_BUG(quic_bug_10995_1)
-        << "interface_name must be nonempty and shorter than " << IFNAMSIZ;
-    return false;
-  }
-
-  if (!OpenDevice()) {
-    return false;
-  }
-
-  if (!ConfigureInterface()) {
-    return false;
-  }
-
-  return true;
-}
-
-// TODO(pengg): might be better to use netlink socket, once we have a library to
-// use
-bool TunTapDevice::Up() {
-  if (!setup_tun_) {
-    return true;
-  }
-  struct ifreq if_request;
-  memset(&if_request, 0, sizeof(if_request));
-  // copy does not zero-terminate the result string, but we've memset the
-  // entire struct.
-  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
-  if_request.ifr_flags = IFF_UP;
-
-  return NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
-}
-
-// TODO(pengg): might be better to use netlink socket, once we have a library to
-// use
-bool TunTapDevice::Down() {
-  if (!setup_tun_) {
-    return true;
-  }
-  struct ifreq if_request;
-  memset(&if_request, 0, sizeof(if_request));
-  // copy does not zero-terminate the result string, but we've memset the
-  // entire struct.
-  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
-  if_request.ifr_flags = 0;
-
-  return NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
-}
-
-int TunTapDevice::GetFileDescriptor() const { return file_descriptor_; }
-
-bool TunTapDevice::OpenDevice() {
-  if (file_descriptor_ != kInvalidFd) {
-    CloseDevice();
-  }
-
-  struct ifreq if_request;
-  memset(&if_request, 0, sizeof(if_request));
-  // copy does not zero-terminate the result string, but we've memset the entire
-  // struct.
-  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
-
-  // Always set IFF_MULTI_QUEUE since a persistent device does not allow this
-  // flag to be flipped when re-opening it. The only way to flip this flag is to
-  // destroy the device and create a new one, but that deletes any existing
-  // routing associated with the interface, which makes the meaning of the
-  // 'persist' bit ambiguous.
-  if_request.ifr_flags = IFF_MULTI_QUEUE | IFF_NO_PI;
-  if (is_tap_) {
-    if_request.ifr_flags |= IFF_TAP;
-  } else {
-    if_request.ifr_flags |= IFF_TUN;
-  }
-
-  // When the device is running with IFF_MULTI_QUEUE set, each call to open will
-  // create a queue which can be used to read/write packets from/to the device.
-  bool successfully_opened = false;
-  auto cleanup = absl::MakeCleanup([this, &successfully_opened]() {
-    if (!successfully_opened) {
-      CloseDevice();
-    }
-  });
-
-  const std::string tun_device_path =
-      absl::GetFlag(FLAGS_qbone_client_tun_device_path);
-  int fd = kernel_.open(tun_device_path.c_str(), O_RDWR);
-  if (fd < 0) {
-    QUIC_PLOG(WARNING) << "Failed to open " << tun_device_path;
-    return successfully_opened;
-  }
-  file_descriptor_ = fd;
-  if (!CheckFeatures(fd)) {
-    return successfully_opened;
-  }
-
-  if (kernel_.ioctl(fd, TUNSETIFF, reinterpret_cast<void*>(&if_request)) != 0) {
-    QUIC_PLOG(WARNING) << "Failed to TUNSETIFF on fd(" << fd << ")";
-    return successfully_opened;
-  }
-
-  if (kernel_.ioctl(
-          fd, TUNSETPERSIST,
-          persist_ ? reinterpret_cast<void*>(&if_request) : nullptr) != 0) {
-    QUIC_PLOG(WARNING) << "Failed to TUNSETPERSIST on fd(" << fd << ")";
-    return successfully_opened;
-  }
-
-  successfully_opened = true;
-  return successfully_opened;
-}
-
-// TODO(pengg): might be better to use netlink socket, once we have a library to
-// use
-bool TunTapDevice::ConfigureInterface() {
-  if (!setup_tun_) {
-    return true;
-  }
-
-  struct ifreq if_request;
-  memset(&if_request, 0, sizeof(if_request));
-  // copy does not zero-terminate the result string, but we've memset the entire
-  // struct.
-  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
-  if_request.ifr_mtu = mtu_;
-
-  if (!NetdeviceIoctl(SIOCSIFMTU, reinterpret_cast<void*>(&if_request))) {
-    CloseDevice();
-    return false;
-  }
-
-  return true;
-}
-
-bool TunTapDevice::CheckFeatures(int tun_device_fd) {
-  unsigned int actual_features;
-  if (kernel_.ioctl(tun_device_fd, TUNGETFEATURES, &actual_features) != 0) {
-    QUIC_PLOG(WARNING) << "Failed to TUNGETFEATURES";
-    return false;
-  }
-  unsigned int required_features = IFF_TUN | IFF_NO_PI;
-  if ((required_features & actual_features) != required_features) {
-    QUIC_LOG(WARNING)
-        << "Required feature does not exist. required_features: 0x" << std::hex
-        << required_features << " vs actual_features: 0x" << std::hex
-        << actual_features;
-    return false;
-  }
-  return true;
-}
-
-bool TunTapDevice::NetdeviceIoctl(int request, void* argp) {
-  int fd = kernel_.socket(AF_INET6, SOCK_DGRAM, 0);
-  if (fd < 0) {
-    QUIC_PLOG(WARNING) << "Failed to create AF_INET6 socket.";
-    return false;
-  }
-
-  if (kernel_.ioctl(fd, request, argp) != 0) {
-    QUIC_PLOG(WARNING) << "Failed ioctl request: " << request;
-    kernel_.close(fd);
-    return false;
-  }
-  kernel_.close(fd);
-  return true;
-}
-
-void TunTapDevice::CloseDevice() {
-  if (file_descriptor_ != kInvalidFd) {
-    kernel_.close(file_descriptor_);
-    file_descriptor_ = kInvalidFd;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device.h b/quic/qbone/bonnet/tun_device.h
deleted file mode 100644
index 66c06d2..0000000
--- a/quic/qbone/bonnet/tun_device.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
-
-#include <string>
-#include <vector>
-
-#include "quic/qbone/bonnet/tun_device_interface.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-namespace quic {
-
-class TunTapDevice : public TunDeviceInterface {
- public:
-  // This represents a tun device created in the OS kernel, which is a virtual
-  // network interface that any packets sent to it can be read by a user space
-  // program that owns it. The routing rule that routes packets to this
-  // interface should be defined somewhere else.
-  //
-  // Standard read/write system calls can be used to receive/send packets
-  // from/to this interface. The file descriptor is owned by this class.
-  //
-  // If persist is set to true, the device won't be deleted even after
-  // destructing. The device will be picked up when initializing this class with
-  // the same interface_name on the next time.
-  //
-  // Persisting the device is useful if one wants to keep the routing rules
-  // since once a tun device is destroyed by the kernel, all the associated
-  // routing rules go away.
-  //
-  // The caller should own kernel and make sure it outlives this.
-  TunTapDevice(const std::string& interface_name, int mtu, bool persist,
-               bool setup_tun, bool is_tap, KernelInterface* kernel);
-
-  ~TunTapDevice() override;
-
-  // Actually creates/reopens and configures the device.
-  bool Init() override;
-
-  // Marks the interface up to start receiving packets.
-  bool Up() override;
-
-  // Marks the interface down to stop receiving packets.
-  bool Down() override;
-
-  // Closes the open file descriptor for the TUN device (if one exists).
-  // It is safe to reinitialize and reuse this TunTapDevice after calling
-  // CloseDevice.
-  void CloseDevice() override;
-
-  // Gets the file descriptor that can be used to send/receive packets.
-  // This returns -1 when the TUN device is in an invalid state.
-  int GetFileDescriptor() const override;
-
- private:
-  // Creates or reopens the tun device.
-  bool OpenDevice();
-
-  // Configure the interface.
-  bool ConfigureInterface();
-
-  // Checks if the required kernel features exists.
-  bool CheckFeatures(int tun_device_fd);
-
-  // Opens a socket and makes netdevice ioctl call
-  bool NetdeviceIoctl(int request, void* argp);
-
-  const std::string interface_name_;
-  const int mtu_;
-  const bool persist_;
-  const bool setup_tun_;
-  const bool is_tap_;
-  int file_descriptor_;
-  KernelInterface& kernel_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
diff --git a/quic/qbone/bonnet/tun_device_controller.cc b/quic/qbone/bonnet/tun_device_controller.cc
deleted file mode 100644
index dd996c5..0000000
--- a/quic/qbone/bonnet/tun_device_controller.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device_controller.h"
-
-#include <linux/rtnetlink.h>
-
-#include "absl/time/clock.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/qbone_constants.h"
-
-ABSL_FLAG(bool, qbone_tun_device_replace_default_routing_rules, true,
-          "If true, will define a rule that points packets sourced from the "
-          "qbone interface to the qbone table. This is unnecessary in "
-          "environments with no other ipv6 route.");
-
-namespace quic {
-
-bool TunDeviceController::UpdateAddress(const IpRange& desired_range) {
-  if (!setup_tun_) {
-    return true;
-  }
-
-  NetlinkInterface::LinkInfo link_info{};
-  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
-    return false;
-  }
-
-  std::vector<NetlinkInterface::AddressInfo> addresses;
-  if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
-    return false;
-  }
-
-  QuicIpAddress desired_address = desired_range.FirstAddressInRange();
-
-  for (const auto& address : addresses) {
-    if (!netlink_->ChangeLocalAddress(
-            link_info.index, NetlinkInterface::Verb::kRemove,
-            address.interface_address, address.prefix_length, 0, 0, {})) {
-      return false;
-    }
-  }
-
-  bool address_updated = netlink_->ChangeLocalAddress(
-      link_info.index, NetlinkInterface::Verb::kAdd, desired_address,
-      desired_range.prefix_length(), IFA_F_PERMANENT | IFA_F_NODAD,
-      RT_SCOPE_LINK, {});
-
-  if (address_updated) {
-    current_address_ = desired_address;
-
-    for (const auto& cb : address_update_cbs_) {
-      cb(current_address_);
-    }
-  }
-
-  return address_updated;
-}
-
-bool TunDeviceController::UpdateRoutes(
-    const IpRange& desired_range,
-    const std::vector<IpRange>& desired_routes) {
-  if (!setup_tun_) {
-    return true;
-  }
-
-  NetlinkInterface::LinkInfo link_info{};
-  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
-    QUIC_LOG(ERROR) << "Could not get link info for interface <" << ifname_
-                    << ">";
-    return false;
-  }
-
-  std::vector<NetlinkInterface::RoutingRule> routing_rules;
-  if (!netlink_->GetRouteInfo(&routing_rules)) {
-    QUIC_LOG(ERROR) << "Unable to get route info";
-    return false;
-  }
-
-  for (const auto& rule : routing_rules) {
-    if (rule.out_interface == link_info.index &&
-        rule.table == QboneConstants::kQboneRouteTableId) {
-      if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kRemove,
-                                 rule.table, rule.destination_subnet,
-                                 rule.scope, rule.preferred_source,
-                                 rule.out_interface)) {
-        QUIC_LOG(ERROR) << "Unable to remove old route to <"
-                        << rule.destination_subnet.ToString() << ">";
-        return false;
-      }
-    }
-  }
-
-  if (!UpdateRules(desired_range)) {
-    return false;
-  }
-
-  QuicIpAddress desired_address = desired_range.FirstAddressInRange();
-
-  std::vector<IpRange> routes(desired_routes.begin(), desired_routes.end());
-  routes.emplace_back(*QboneConstants::TerminatorLocalAddressRange());
-
-  for (const auto& route : routes) {
-    if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kReplace,
-                               QboneConstants::kQboneRouteTableId, route,
-                               RT_SCOPE_LINK, desired_address,
-                               link_info.index)) {
-      QUIC_LOG(ERROR) << "Unable to add route <" << route.ToString() << ">";
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool TunDeviceController::UpdateRoutesWithRetries(
-    const IpRange& desired_range,
-    const std::vector<IpRange>& desired_routes,
-    int retries) {
-  while (retries-- > 0) {
-    if (UpdateRoutes(desired_range, desired_routes)) {
-      return true;
-    }
-    absl::SleepFor(absl::Milliseconds(100));
-  }
-  return false;
-}
-
-bool TunDeviceController::UpdateRules(IpRange desired_range) {
-  if (!absl::GetFlag(FLAGS_qbone_tun_device_replace_default_routing_rules)) {
-    return true;
-  }
-
-  std::vector<NetlinkInterface::IpRule> ip_rules;
-  if (!netlink_->GetRuleInfo(&ip_rules)) {
-    QUIC_LOG(ERROR) << "Unable to get rule info";
-    return false;
-  }
-
-  for (const auto& rule : ip_rules) {
-    if (rule.table == QboneConstants::kQboneRouteTableId) {
-      if (!netlink_->ChangeRule(NetlinkInterface::Verb::kRemove,
-                                rule.table, rule.source_range)) {
-        QUIC_LOG(ERROR) << "Unable to remove old rule for table <" << rule.table
-                        << "> from source <" << rule.source_range.ToString()
-                        << ">";
-        return false;
-      }
-    }
-  }
-
-  if (!netlink_->ChangeRule(NetlinkInterface::Verb::kAdd,
-                            QboneConstants::kQboneRouteTableId,
-                            desired_range)) {
-    QUIC_LOG(ERROR) << "Unable to add rule for <" << desired_range.ToString()
-                    << ">";
-    return false;
-  }
-
-  return true;
-}
-
-QuicIpAddress TunDeviceController::current_address() {
-  return current_address_;
-}
-
-void TunDeviceController::RegisterAddressUpdateCallback(
-    const std::function<void(QuicIpAddress)>& cb) {
-  address_update_cbs_.push_back(cb);
-}
-
-}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device_controller.h b/quic/qbone/bonnet/tun_device_controller.h
deleted file mode 100644
index 612e98f..0000000
--- a/quic/qbone/bonnet/tun_device_controller.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
-
-#include "quic/qbone/bonnet/tun_device.h"
-#include "quic/qbone/platform/netlink_interface.h"
-#include "quic/qbone/qbone_control.pb.h"
-#include "quic/qbone/qbone_control_stream.h"
-
-namespace quic {
-
-// TunDeviceController consumes control stream messages from a Qbone server
-// and applies the given updates to the TUN device.
-class TunDeviceController {
- public:
-  // |ifname| is the interface name of the TUN device to be managed. This does
-  // not take ownership of |netlink|.
-  TunDeviceController(std::string ifname, bool setup_tun,
-                      NetlinkInterface* netlink)
-      : ifname_(std::move(ifname)), setup_tun_(setup_tun), netlink_(netlink) {}
-
-  TunDeviceController(const TunDeviceController&) = delete;
-  TunDeviceController& operator=(const TunDeviceController&) = delete;
-
-  TunDeviceController(TunDeviceController&&) = delete;
-  TunDeviceController& operator=(TunDeviceController&&) = delete;
-
-  virtual ~TunDeviceController() = default;
-
-  // Updates the local address of the TUN device to be the first address in the
-  // given |response.ip_range()|.
-  virtual bool UpdateAddress(const IpRange& desired_range);
-
-  // Updates the set of routes that the TUN device will provide. All current
-  // routes for the tunnel that do not exist in the |response| will be removed.
-  virtual bool UpdateRoutes(const IpRange& desired_range,
-                            const std::vector<IpRange>& desired_routes);
-
-  // Same as UpdateRoutes, but will wait and retry up to the number of times
-  // given by |retries| before giving up. This is an unpleasant workaround to
-  // deal with older kernels that aren't always able to set a route with a
-  // source address immediately after adding the address to the interface.
-  //
-  // TODO(b/179430548): Remove this once we've root-caused the underlying issue.
-  virtual bool UpdateRoutesWithRetries(
-      const IpRange& desired_range,
-      const std::vector<IpRange>& desired_routes,
-      int retries);
-
-  virtual void RegisterAddressUpdateCallback(
-      const std::function<void(QuicIpAddress)>& cb);
-
-  virtual QuicIpAddress current_address();
-
- private:
-  // Update the IP Rules, this should only be used by UpdateRoutes.
-  bool UpdateRules(IpRange desired_range);
-
-  const std::string ifname_;
-  const bool setup_tun_;
-
-  NetlinkInterface* netlink_;
-
-  QuicIpAddress current_address_;
-
-  std::vector<std::function<void(QuicIpAddress)>> address_update_cbs_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
diff --git a/quic/qbone/bonnet/tun_device_controller_test.cc b/quic/qbone/bonnet/tun_device_controller_test.cc
deleted file mode 100644
index 53e5b3c..0000000
--- a/quic/qbone/bonnet/tun_device_controller_test.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device_controller.h"
-
-#include <linux/if_addr.h>
-#include <linux/rtnetlink.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_netlink.h"
-#include "quic/qbone/qbone_constants.h"
-
-ABSL_DECLARE_FLAG(bool, qbone_tun_device_replace_default_routing_rules);
-
-namespace quic {
-namespace {
-using ::testing::Eq;
-
-constexpr int kIfindex = 42;
-constexpr char kIfname[] = "qbone0";
-
-const IpRange kIpRange = []() {
-  IpRange range;
-  QCHECK(range.FromString("2604:31c0:2::/64"));
-  return range;
-}();
-
-constexpr char kOldAddress[] = "1.2.3.4";
-constexpr int kOldPrefixLen = 24;
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-MATCHER_P(IpRangeEq, range,
-          absl::StrCat("expected IpRange to equal ", range.ToString())) {
-  return arg == range;
-}
-
-class TunDeviceControllerTest : public QuicTest {
- public:
-  TunDeviceControllerTest()
-      : controller_(kIfname, true, &netlink_),
-        link_local_range_(*QboneConstants::TerminatorLocalAddressRange()) {
-    controller_.RegisterAddressUpdateCallback(
-        [this](QuicIpAddress address) { notified_address_ = address; });
-  }
-
- protected:
-  void ExpectLinkInfo(const std::string& interface_name, int ifindex) {
-    EXPECT_CALL(netlink_, GetLinkInfo(interface_name, _))
-        .WillOnce(
-            Invoke([ifindex](absl::string_view ifname,
-                             NetlinkInterface::LinkInfo* link_info) {
-              link_info->index = ifindex;
-              return true;
-            }));
-  }
-
-  MockNetlink netlink_;
-  TunDeviceController controller_;
-  QuicIpAddress notified_address_;
-
-  IpRange link_local_range_;
-};
-
-TEST_F(TunDeviceControllerTest, AddressAppliedWhenNoneExisted) {
-  ExpectLinkInfo(kIfname, kIfindex);
-
-  EXPECT_CALL(netlink_, GetAddresses(kIfindex, _, _, _)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_,
-              ChangeLocalAddress(
-                  kIfindex, NetlinkInterface::Verb::kAdd,
-                  kIpRange.FirstAddressInRange(), kIpRange.prefix_length(),
-                  IFA_F_PERMANENT | IFA_F_NODAD, RT_SCOPE_LINK, _))
-      .WillOnce(Return(true));
-
-  EXPECT_TRUE(controller_.UpdateAddress(kIpRange));
-  EXPECT_THAT(notified_address_, Eq(kIpRange.FirstAddressInRange()));
-}
-
-TEST_F(TunDeviceControllerTest, OldAddressesAreRemoved) {
-  ExpectLinkInfo(kIfname, kIfindex);
-
-  EXPECT_CALL(netlink_, GetAddresses(kIfindex, _, _, _))
-      .WillOnce(
-          Invoke([](int interface_index, uint8_t unwanted_flags,
-                    std::vector<NetlinkInterface::AddressInfo>* addresses,
-                    int* num_ipv6_nodad_dadfailed_addresses) {
-            NetlinkInterface::AddressInfo info{};
-            info.interface_address.FromString(kOldAddress);
-            info.prefix_length = kOldPrefixLen;
-            addresses->emplace_back(info);
-            return true;
-          }));
-
-  QuicIpAddress old_address;
-  old_address.FromString(kOldAddress);
-
-  EXPECT_CALL(netlink_, ChangeLocalAddress(
-                            kIfindex, NetlinkInterface::Verb::kRemove,
-                            old_address, kOldPrefixLen, _, _, _))
-      .WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_,
-              ChangeLocalAddress(
-                  kIfindex, NetlinkInterface::Verb::kAdd,
-                  kIpRange.FirstAddressInRange(), kIpRange.prefix_length(),
-                  IFA_F_PERMANENT | IFA_F_NODAD, RT_SCOPE_LINK, _))
-      .WillOnce(Return(true));
-
-  EXPECT_TRUE(controller_.UpdateAddress(kIpRange));
-  EXPECT_THAT(notified_address_, Eq(kIpRange.FirstAddressInRange()));
-}
-
-TEST_F(TunDeviceControllerTest, UpdateRoutesRemovedOldRoutes) {
-  ExpectLinkInfo(kIfname, kIfindex);
-
-  const int num_matching_routes = 3;
-  EXPECT_CALL(netlink_, GetRouteInfo(_))
-      .WillOnce(Invoke(
-          [](std::vector<NetlinkInterface::RoutingRule>* routing_rules) {
-            NetlinkInterface::RoutingRule non_matching_route;
-            non_matching_route.table = QboneConstants::kQboneRouteTableId;
-            non_matching_route.out_interface = kIfindex + 1;
-            routing_rules->push_back(non_matching_route);
-
-            NetlinkInterface::RoutingRule matching_route;
-            matching_route.table = QboneConstants::kQboneRouteTableId;
-            matching_route.out_interface = kIfindex;
-            for (int i = 0; i < num_matching_routes; i++) {
-              routing_rules->push_back(matching_route);
-            }
-
-            NetlinkInterface::RoutingRule non_matching_table;
-            non_matching_table.table =
-                QboneConstants::kQboneRouteTableId + 1;
-            non_matching_table.out_interface = kIfindex;
-            routing_rules->push_back(non_matching_table);
-            return true;
-          }));
-
-  EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kRemove,
-                                    QboneConstants::kQboneRouteTableId, _,
-                                    _, _, kIfindex))
-      .Times(num_matching_routes)
-      .WillRepeatedly(Return(true));
-
-  EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
-                                   QboneConstants::kQboneRouteTableId,
-                                   IpRangeEq(kIpRange)))
-      .WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_,
-              ChangeRoute(NetlinkInterface::Verb::kReplace,
-                          QboneConstants::kQboneRouteTableId,
-                          IpRangeEq(link_local_range_), _, _, kIfindex))
-      .WillOnce(Return(true));
-
-  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {}));
-}
-
-TEST_F(TunDeviceControllerTest, UpdateRoutesAddsNewRoutes) {
-  ExpectLinkInfo(kIfname, kIfindex);
-
-  EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kReplace,
-                                    QboneConstants::kQboneRouteTableId,
-                                    IpRangeEq(kIpRange), _, _, kIfindex))
-      .Times(2)
-      .WillRepeatedly(Return(true))
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
-                                   QboneConstants::kQboneRouteTableId,
-                                   IpRangeEq(kIpRange)))
-      .WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_,
-              ChangeRoute(NetlinkInterface::Verb::kReplace,
-                          QboneConstants::kQboneRouteTableId,
-                          IpRangeEq(link_local_range_), _, _, kIfindex))
-      .WillOnce(Return(true));
-
-  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {kIpRange, kIpRange}));
-}
-
-TEST_F(TunDeviceControllerTest, EmptyUpdateRouteKeepsLinkLocalRoute) {
-  ExpectLinkInfo(kIfname, kIfindex);
-
-  EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
-                                   QboneConstants::kQboneRouteTableId,
-                                   IpRangeEq(kIpRange)))
-      .WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_,
-              ChangeRoute(NetlinkInterface::Verb::kReplace,
-                          QboneConstants::kQboneRouteTableId,
-                          IpRangeEq(link_local_range_), _, _, kIfindex))
-      .WillOnce(Return(true));
-
-  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {}));
-}
-
-TEST_F(TunDeviceControllerTest, DisablingRoutingRulesSkipsRuleCreation) {
-  absl::SetFlag(&FLAGS_qbone_tun_device_replace_default_routing_rules, false);
-  ExpectLinkInfo(kIfname, kIfindex);
-
-  EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
-
-  EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kReplace,
-                                    QboneConstants::kQboneRouteTableId,
-                                    IpRangeEq(kIpRange), _, _, kIfindex))
-      .Times(2)
-      .WillRepeatedly(Return(true))
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(netlink_,
-              ChangeRoute(NetlinkInterface::Verb::kReplace,
-                          QboneConstants::kQboneRouteTableId,
-                          IpRangeEq(link_local_range_), _, _, kIfindex))
-      .WillOnce(Return(true));
-
-  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {kIpRange, kIpRange}));
-}
-
-class DisabledTunDeviceControllerTest : public QuicTest {
- public:
-  DisabledTunDeviceControllerTest()
-      : controller_(kIfname, false, &netlink_),
-        link_local_range_(
-            *QboneConstants::TerminatorLocalAddressRange()) {}
-
-  StrictMock<MockNetlink> netlink_;
-  TunDeviceController controller_;
-
-  IpRange link_local_range_;
-};
-
-TEST_F(DisabledTunDeviceControllerTest, UpdateRoutesIsNop) {
-  EXPECT_THAT(controller_.UpdateRoutes(kIpRange, {}), Eq(true));
-}
-
-TEST_F(DisabledTunDeviceControllerTest, UpdateAddressIsNop) {
-  EXPECT_THAT(controller_.UpdateAddress(kIpRange), Eq(true));
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger.cc b/quic/qbone/bonnet/tun_device_packet_exchanger.cc
deleted file mode 100644
index 3381cd2..0000000
--- a/quic/qbone/bonnet/tun_device_packet_exchanger.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device_packet_exchanger.h"
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/platform/netlink_interface.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-
-TunDevicePacketExchanger::TunDevicePacketExchanger(
-    size_t mtu, KernelInterface* kernel, NetlinkInterface* netlink,
-    QbonePacketExchanger::Visitor* visitor, size_t max_pending_packets,
-    bool is_tap, StatsInterface* stats, absl::string_view ifname)
-    : QbonePacketExchanger(visitor, max_pending_packets),
-      mtu_(mtu),
-      kernel_(kernel),
-      netlink_(netlink),
-      ifname_(ifname),
-      is_tap_(is_tap),
-      stats_(stats) {
-  if (is_tap_) {
-    mtu_ += ETH_HLEN;
-  }
-}
-
-bool TunDevicePacketExchanger::WritePacket(const char* packet, size_t size,
-                                           bool* blocked, std::string* error) {
-  *blocked = false;
-  if (fd_ < 0) {
-    *error = absl::StrCat("Invalid file descriptor of the TUN device: ", fd_);
-    stats_->OnWriteError(error);
-    return false;
-  }
-
-  auto buffer = std::make_unique<QuicData>(packet, size);
-  if (is_tap_) {
-    buffer = ApplyL2Headers(*buffer);
-  }
-  int result = kernel_->write(fd_, buffer->data(), buffer->length());
-  if (result == -1) {
-    if (errno == EWOULDBLOCK || errno == EAGAIN) {
-      // The tunnel is blocked. Note that this does not mean the receive buffer
-      // of a TCP connection is filled. This simply means the TUN device itself
-      // is blocked on handing packets to the rest part of the kernel.
-      *error = absl::StrCat("Write to the TUN device was blocked: ", errno);
-      *blocked = true;
-      stats_->OnWriteError(error);
-    }
-    return false;
-  }
-  stats_->OnPacketWritten(result);
-
-  return true;
-}
-
-std::unique_ptr<QuicData> TunDevicePacketExchanger::ReadPacket(
-    bool* blocked, std::string* error) {
-  *blocked = false;
-  if (fd_ < 0) {
-    *error = absl::StrCat("Invalid file descriptor of the TUN device: ", fd_);
-    stats_->OnReadError(error);
-    return nullptr;
-  }
-  // Reading on a TUN device returns a packet at a time. If the packet is longer
-  // than the buffer, it's truncated.
-  auto read_buffer = std::make_unique<char[]>(mtu_);
-  int result = kernel_->read(fd_, read_buffer.get(), mtu_);
-  // Note that 0 means end of file, but we're talking about a TUN device - there
-  // is no end of file. Therefore 0 also indicates error.
-  if (result <= 0) {
-    if (errno == EAGAIN || errno == EWOULDBLOCK) {
-      *error = absl::StrCat("Read from the TUN device was blocked: ", errno);
-      *blocked = true;
-      stats_->OnReadError(error);
-    }
-    return nullptr;
-  }
-
-  auto buffer = std::make_unique<QuicData>(read_buffer.release(), result, true);
-  if (is_tap_) {
-    buffer = ConsumeL2Headers(*buffer);
-  }
-  if (buffer) {
-    stats_->OnPacketRead(buffer->length());
-  }
-  return buffer;
-}
-
-void TunDevicePacketExchanger::set_file_descriptor(int fd) { fd_ = fd; }
-
-const TunDevicePacketExchanger::StatsInterface*
-TunDevicePacketExchanger::stats_interface() const {
-  return stats_;
-}
-
-std::unique_ptr<QuicData> TunDevicePacketExchanger::ApplyL2Headers(
-    const QuicData& l3_packet) {
-  if (is_tap_ && !mac_initialized_) {
-    NetlinkInterface::LinkInfo link_info{};
-    if (netlink_->GetLinkInfo(ifname_, &link_info)) {
-      memcpy(tap_mac_, link_info.hardware_address, ETH_ALEN);
-      mac_initialized_ = true;
-    } else {
-      QUIC_LOG_EVERY_N_SEC(ERROR, 30)
-          << "Unable to get link info for: " << ifname_;
-    }
-  }
-
-  const auto l2_packet_size = l3_packet.length() + ETH_HLEN;
-  auto l2_buffer = std::make_unique<char[]>(l2_packet_size);
-
-  // Populate the Ethernet header
-  auto* hdr = reinterpret_cast<ethhdr*>(l2_buffer.get());
-  // Set src & dst to my own address
-  memcpy(hdr->h_dest, tap_mac_, ETH_ALEN);
-  memcpy(hdr->h_source, tap_mac_, ETH_ALEN);
-  // Assume ipv6 for now
-  // TODO(b/195113643): Support additional protocols.
-  hdr->h_proto = absl::ghtons(ETH_P_IPV6);
-
-  // Copy the l3 packet into buffer, just after the ethernet header.
-  memcpy(l2_buffer.get() + ETH_HLEN, l3_packet.data(), l3_packet.length());
-
-  return std::make_unique<QuicData>(l2_buffer.release(), l2_packet_size, true);
-}
-
-std::unique_ptr<QuicData> TunDevicePacketExchanger::ConsumeL2Headers(
-    const QuicData& l2_packet) {
-  if (l2_packet.length() < ETH_HLEN) {
-    // Packet is too short for ethernet headers. Drop it.
-    return nullptr;
-  }
-  auto* hdr = reinterpret_cast<const ethhdr*>(l2_packet.data());
-  if (hdr->h_proto != absl::ghtons(ETH_P_IPV6)) {
-    return nullptr;
-  }
-  constexpr auto kIp6PrefixLen = ETH_HLEN + sizeof(ip6_hdr);
-  constexpr auto kIcmp6PrefixLen = kIp6PrefixLen + sizeof(icmp6_hdr);
-  if (l2_packet.length() < kIp6PrefixLen) {
-    // Packet is too short to be ipv6. Drop it.
-    return nullptr;
-  }
-  auto* ip_hdr = reinterpret_cast<const ip6_hdr*>(l2_packet.data() + ETH_HLEN);
-  const bool is_icmp = ip_hdr->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV6;
-
-  bool is_neighbor_solicit = false;
-  if (is_icmp) {
-    if (l2_packet.length() < kIcmp6PrefixLen) {
-      // Packet is too short to be icmp6. Drop it.
-      return nullptr;
-    }
-    is_neighbor_solicit =
-        reinterpret_cast<const icmp6_hdr*>(l2_packet.data() + kIp6PrefixLen)
-            ->icmp6_type == ND_NEIGHBOR_SOLICIT;
-  }
-
-  if (is_neighbor_solicit) {
-    // If we've received a neighbor solicitation, craft an advertisement to
-    // respond with and write it back to the local interface.
-    auto* icmp6_payload = l2_packet.data() + kIcmp6PrefixLen;
-
-    QuicIpAddress target_address(
-        *reinterpret_cast<const in6_addr*>(icmp6_payload));
-    if (target_address != *QboneConstants::GatewayAddress()) {
-      // Only respond to solicitations for our gateway address
-      return nullptr;
-    }
-
-    // Neighbor Advertisement crafted per:
-    // https://datatracker.ietf.org/doc/html/rfc4861#section-4.4
-    //
-    // Using the Target link-layer address option defined at:
-    // https://datatracker.ietf.org/doc/html/rfc4861#section-4.6.1
-    constexpr size_t kIcmpv6OptionSize = 8;
-    const int payload_size = sizeof(in6_addr) + kIcmpv6OptionSize;
-    auto payload = std::make_unique<char[]>(payload_size);
-    // Place the solicited IPv6 address at the beginning of the response payload
-    memcpy(payload.get(), icmp6_payload, sizeof(in6_addr));
-    // Setup the Target link-layer address option:
-    //      0                   1                   2                   3
-    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    // |     Type      |    Length     |    Link-Layer Address ...
-    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    int pos = sizeof(in6_addr);
-    payload[pos++] = ND_OPT_TARGET_LINKADDR;    // Type
-    payload[pos++] = 1;                         // Length in units of 8 octets
-    memcpy(&payload[pos], tap_mac_, ETH_ALEN);  // This interfaces' MAC address
-
-    // Populate the ICMPv6 header
-    icmp6_hdr response_hdr{};
-    response_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
-    // Set the solicited bit to true
-    response_hdr.icmp6_dataun.icmp6_un_data8[0] = 64;
-    // Craft the full ICMPv6 packet and then ship it off to WritePacket
-    // to have it frame it with L2 headers and send it back to the requesting
-    // neighbor.
-    CreateIcmpPacket(ip_hdr->ip6_src, ip_hdr->ip6_src, response_hdr,
-                     absl::string_view(payload.get(), payload_size),
-                     [this](absl::string_view packet) {
-                       bool blocked;
-                       std::string error;
-                       WritePacket(packet.data(), packet.size(), &blocked,
-                                   &error);
-                     });
-    // Do not forward the neighbor solicitation through the tunnel since it's
-    // link-local.
-    return nullptr;
-  }
-
-  // If this isn't a Neighbor Solicitation, remove the L2 headers and forward
-  // it as though it were an L3 packet.
-  const auto l3_packet_size = l2_packet.length() - ETH_HLEN;
-  auto shift_buffer = std::make_unique<char[]>(l3_packet_size);
-  memcpy(shift_buffer.get(), l2_packet.data() + ETH_HLEN, l3_packet_size);
-
-  return std::make_unique<QuicData>(shift_buffer.release(), l3_packet_size,
-                                    true);
-}
-
-}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger.h b/quic/qbone/bonnet/tun_device_packet_exchanger.h
deleted file mode 100644
index 3136b42..0000000
--- a/quic/qbone/bonnet/tun_device_packet_exchanger.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
-#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
-
-#include <linux/if_ether.h>
-
-#include "quic/core/quic_packets.h"
-#include "quic/qbone/platform/kernel_interface.h"
-#include "quic/qbone/platform/netlink_interface.h"
-#include "quic/qbone/qbone_client_interface.h"
-#include "quic/qbone/qbone_packet_exchanger.h"
-
-namespace quic {
-
-class TunDevicePacketExchanger : public QbonePacketExchanger {
- public:
-  class StatsInterface {
-   public:
-    StatsInterface() = default;
-
-    StatsInterface(const StatsInterface&) = delete;
-    StatsInterface& operator=(const StatsInterface&) = delete;
-
-    StatsInterface(StatsInterface&&) = delete;
-    StatsInterface& operator=(StatsInterface&&) = delete;
-
-    virtual ~StatsInterface() = default;
-
-    virtual void OnPacketRead(size_t count) = 0;
-    virtual void OnPacketWritten(size_t count) = 0;
-    virtual void OnReadError(std::string* error) = 0;
-    virtual void OnWriteError(std::string* error) = 0;
-
-    ABSL_MUST_USE_RESULT virtual int64_t PacketsRead() const = 0;
-    ABSL_MUST_USE_RESULT virtual int64_t PacketsWritten() const = 0;
-  };
-
-  // |mtu| is the mtu of the TUN device.
-  // |kernel| is not owned but should out live objects of this class.
-  // |visitor| is not owned but should out live objects of this class.
-  // |max_pending_packets| controls the number of packets to be queued should
-  // the TUN device become blocked.
-  // |stats| is notified about packet read/write statistics. It is not owned,
-  // but should outlive objects of this class.
-  TunDevicePacketExchanger(size_t mtu, KernelInterface* kernel,
-                           NetlinkInterface* netlink,
-                           QbonePacketExchanger::Visitor* visitor,
-                           size_t max_pending_packets, bool is_tap,
-                           StatsInterface* stats, absl::string_view ifname);
-
-  void set_file_descriptor(int fd);
-
-  ABSL_MUST_USE_RESULT const StatsInterface* stats_interface() const;
-
- private:
-  // From QbonePacketExchanger.
-  std::unique_ptr<QuicData> ReadPacket(bool* blocked,
-                                       std::string* error) override;
-
-  // From QbonePacketExchanger.
-  bool WritePacket(const char* packet,
-                   size_t size,
-                   bool* blocked,
-                   std::string* error) override;
-
-  std::unique_ptr<QuicData> ApplyL2Headers(const QuicData& l3_packet);
-
-  std::unique_ptr<QuicData> ConsumeL2Headers(const QuicData& l2_packet);
-
-  int fd_ = -1;
-  size_t mtu_;
-  KernelInterface* kernel_;
-  NetlinkInterface* netlink_;
-  const std::string ifname_;
-
-  const bool is_tap_;
-  uint8_t tap_mac_[ETH_ALEN]{};
-  bool mac_initialized_ = false;
-
-  StatsInterface* stats_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc b/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
deleted file mode 100644
index 8abf9a3..0000000
--- a/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device_packet_exchanger.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h"
-#include "quic/qbone/mock_qbone_client.h"
-#include "quic/qbone/platform/mock_kernel.h"
-
-namespace quic {
-namespace {
-
-const size_t kMtu = 1000;
-const size_t kMaxPendingPackets = 5;
-const int kFd = 15;
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::StrEq;
-using ::testing::StrictMock;
-
-class MockVisitor : public QbonePacketExchanger::Visitor {
- public:
-  MOCK_METHOD(void, OnReadError, (const std::string&), (override));
-  MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
-};
-
-class TunDevicePacketExchangerTest : public QuicTest {
- protected:
-  TunDevicePacketExchangerTest()
-      : exchanger_(kMtu, &mock_kernel_, nullptr, &mock_visitor_,
-                   kMaxPendingPackets, false, &mock_stats_,
-                   absl::string_view()) {
-    exchanger_.set_file_descriptor(kFd);
-  }
-
-  ~TunDevicePacketExchangerTest() override = default;
-
-  MockKernel mock_kernel_;
-  StrictMock<MockVisitor> mock_visitor_;
-  StrictMock<MockQboneClient> mock_client_;
-  StrictMock<MockPacketExchangerStatsInterface> mock_stats_;
-  TunDevicePacketExchanger exchanger_;
-};
-
-TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsFalseOnError) {
-  std::string packet = "fake packet";
-  EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
-      .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
-        errno = ECOMM;
-        return -1;
-      }));
-
-  EXPECT_CALL(mock_visitor_, OnWriteError(_));
-  exchanger_.WritePacketToNetwork(packet.data(), packet.size());
-}
-
-TEST_F(TunDevicePacketExchangerTest,
-       WritePacketReturnFalseAndBlockedOnBlockedTunnel) {
-  std::string packet = "fake packet";
-  EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
-      .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
-        errno = EAGAIN;
-        return -1;
-      }));
-
-  EXPECT_CALL(mock_stats_, OnWriteError(_)).Times(1);
-  exchanger_.WritePacketToNetwork(packet.data(), packet.size());
-}
-
-TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsTrueOnSuccessfulWrite) {
-  std::string packet = "fake packet";
-  EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
-      .WillOnce(Invoke([packet](int fd, const void* buf, size_t count) {
-        EXPECT_THAT(reinterpret_cast<const char*>(buf), StrEq(packet));
-        return count;
-      }));
-
-  EXPECT_CALL(mock_stats_, OnPacketWritten(_)).Times(1);
-  exchanger_.WritePacketToNetwork(packet.data(), packet.size());
-}
-
-TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnError) {
-  EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
-      .WillOnce(Invoke([](int fd, void* buf, size_t count) {
-        errno = ECOMM;
-        return -1;
-      }));
-  EXPECT_CALL(mock_visitor_, OnReadError(_));
-  exchanger_.ReadAndDeliverPacket(&mock_client_);
-}
-
-TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnBlockedRead) {
-  EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
-      .WillOnce(Invoke([](int fd, void* buf, size_t count) {
-        errno = EAGAIN;
-        return -1;
-      }));
-  EXPECT_CALL(mock_stats_, OnReadError(_)).Times(1);
-  EXPECT_FALSE(exchanger_.ReadAndDeliverPacket(&mock_client_));
-}
-
-TEST_F(TunDevicePacketExchangerTest,
-       ReadPacketReturnsThePacketOnSuccessfulRead) {
-  std::string packet = "fake_packet";
-  EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
-      .WillOnce(Invoke([packet](int fd, void* buf, size_t count) {
-        memcpy(buf, packet.data(), packet.size());
-        return packet.size();
-      }));
-  EXPECT_CALL(mock_client_, ProcessPacketFromNetwork(StrEq(packet)));
-  EXPECT_CALL(mock_stats_, OnPacketRead(_)).Times(1);
-  EXPECT_TRUE(exchanger_.ReadAndDeliverPacket(&mock_client_));
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device_test.cc b/quic/qbone/bonnet/tun_device_test.cc
deleted file mode 100644
index 18b818c..0000000
--- a/quic/qbone/bonnet/tun_device_test.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/bonnet/tun_device.h"
-
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <sys/ioctl.h>
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_kernel.h"
-
-namespace quic {
-namespace {
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrEq;
-using ::testing::Unused;
-
-const char kDeviceName[] = "tun0";
-const int kSupportedFeatures =
-    IFF_TUN | IFF_TAP | IFF_MULTI_QUEUE | IFF_ONE_QUEUE | IFF_NO_PI;
-
-// Quite a bit of EXPECT_CALL().Times(AnyNumber()).WillRepeatedly() are used to
-// make sure we can correctly set common expectations and override the
-// expectation with later call to EXPECT_CALL(). ON_CALL cannot be used here
-// since when EPXECT_CALL overrides ON_CALL, it ignores the parameter matcher
-// which results in unexpected call even if ON_CALL exists.
-class TunDeviceTest : public QuicTest {
- protected:
-  void SetUp() override {
-    EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _))
-        .Times(AnyNumber())
-        .WillRepeatedly(Invoke([this](Unused, Unused, Unused) {
-          EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
-          return next_fd_++;
-        }));
-  }
-
-  // Set the expectations for calling Init().
-  void SetInitExpectations(int mtu, bool persist) {
-    EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
-        .Times(AnyNumber())
-        .WillRepeatedly(Invoke([this](Unused, Unused) {
-          EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
-          return next_fd_++;
-        }));
-    EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
-        .Times(AnyNumber())
-        .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
-          auto* actual_flags = reinterpret_cast<int*>(argp);
-          *actual_flags = kSupportedFeatures;
-          return 0;
-        }));
-    EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _))
-        .Times(AnyNumber())
-        .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
-          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
-          EXPECT_EQ(IFF_TUN | IFF_MULTI_QUEUE | IFF_NO_PI, ifr->ifr_flags);
-          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
-          return 0;
-        }));
-    EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _))
-        .Times(AnyNumber())
-        .WillRepeatedly(Invoke([persist](Unused, Unused, void* argp) {
-          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
-          if (persist) {
-            EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
-          } else {
-            EXPECT_EQ(nullptr, ifr);
-          }
-          return 0;
-        }));
-    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _))
-        .Times(AnyNumber())
-        .WillRepeatedly(Invoke([mtu](Unused, Unused, void* argp) {
-          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
-          EXPECT_EQ(mtu, ifr->ifr_mtu);
-          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
-          return 0;
-        }));
-  }
-
-  // Expect that Up() will be called. Force the call to fail when fail == true.
-  void ExpectUp(bool fail) {
-    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
-        .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
-          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
-          EXPECT_TRUE(ifr->ifr_flags & IFF_UP);
-          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
-          if (fail) {
-            return -1;
-          } else {
-            return 0;
-          }
-        }));
-  }
-
-  // Expect that Down() will be called *after* the interface is up. Force the
-  // call to fail when fail == true.
-  void ExpectDown(bool fail) {
-    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
-        .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
-          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
-          EXPECT_FALSE(ifr->ifr_flags & IFF_UP);
-          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
-          if (fail) {
-            return -1;
-          } else {
-            return 0;
-          }
-        }));
-  }
-
-  MockKernel mock_kernel_;
-  int next_fd_ = 100;
-};
-
-// A TunTapDevice can be initialized and up
-TEST_F(TunDeviceTest, BasicWorkFlow) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
-  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
-  EXPECT_TRUE(tun_device.Init());
-  EXPECT_GT(tun_device.GetFileDescriptor(), -1);
-
-  ExpectUp(/* fail = */ false);
-  EXPECT_TRUE(tun_device.Up());
-  ExpectDown(/* fail = */ false);
-}
-
-TEST_F(TunDeviceTest, FailToOpenTunDevice) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
-  EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
-      .WillOnce(Return(-1));
-  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-  ExpectDown(false);
-}
-
-TEST_F(TunDeviceTest, FailToCheckFeature) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
-  EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _)).WillOnce(Return(-1));
-  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-  ExpectDown(false);
-}
-
-TEST_F(TunDeviceTest, TooFewFeature) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
-  EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
-      .WillOnce(Invoke([](Unused, Unused, void* argp) {
-        int* actual_features = reinterpret_cast<int*>(argp);
-        *actual_features = IFF_TUN | IFF_ONE_QUEUE;
-        return 0;
-      }));
-  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-  ExpectDown(false);
-}
-
-TEST_F(TunDeviceTest, FailToSetFlag) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
-  EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _)).WillOnce(Return(-1));
-  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToPersistDevice) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
-  EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _)).WillOnce(Return(-1));
-  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToOpenSocket) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
-  EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _)).WillOnce(Return(-1));
-  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToSetMtu) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
-  EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _)).WillOnce(Return(-1));
-  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
-  EXPECT_FALSE(tun_device.Init());
-  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
-}
-
-TEST_F(TunDeviceTest, FailToUp) {
-  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
-  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
-  EXPECT_TRUE(tun_device.Init());
-  EXPECT_GT(tun_device.GetFileDescriptor(), -1);
-
-  ExpectUp(/* fail = */ true);
-  EXPECT_FALSE(tun_device.Up());
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/mock_qbone_client.h b/quic/qbone/mock_qbone_client.h
deleted file mode 100644
index 3b84d55..0000000
--- a/quic/qbone/mock_qbone_client.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
-#define QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_client_interface.h"
-
-namespace quic {
-
-class MockQboneClient : public QboneClientInterface {
- public:
-  MOCK_METHOD(void,
-              ProcessPacketFromNetwork,
-              (absl::string_view packet),
-              (override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
diff --git a/quic/qbone/mock_qbone_server_session.h b/quic/qbone/mock_qbone_server_session.h
deleted file mode 100644
index 8d4f64e..0000000
--- a/quic/qbone/mock_qbone_server_session.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
-#define QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_server_session.h"
-
-namespace quic {
-
-class MockQboneServerSession : public QboneServerSession {
- public:
-  explicit MockQboneServerSession(QuicConnection* connection)
-      : QboneServerSession(CurrentSupportedVersions(),
-                           connection,
-                           /*owner=*/nullptr,
-                           /*config=*/{},
-                           /*quic_crypto_server_config=*/nullptr,
-                           /*compressed_certs_cache=*/nullptr,
-                           /*writer=*/nullptr,
-                           /*self_ip=*/QuicIpAddress::Loopback6(),
-                           /*client_ip=*/QuicIpAddress::Loopback6(),
-                           /*client_ip_subnet_length=*/0,
-                           /*handler=*/nullptr) {}
-
-  MOCK_METHOD(bool, SendClientRequest, (const QboneClientRequest&), (override));
-
-  MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override));
-  MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
diff --git a/quic/qbone/platform/icmp_packet.cc b/quic/qbone/platform/icmp_packet.cc
deleted file mode 100644
index 0acd712..0000000
--- a/quic/qbone/platform/icmp_packet.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/icmp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/qbone/platform/internet_checksum.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace {
-
-constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
-constexpr size_t kIPv6HeaderSize = sizeof(ip6_hdr);
-constexpr size_t kICMPv6HeaderSize = sizeof(icmp6_hdr);
-constexpr size_t kIPv6MinPacketSize = 1280;
-
-// Hop limit set to 255 to satisfy:
-// https://datatracker.ietf.org/doc/html/rfc4861#section-11.2
-constexpr size_t kIcmpTtl = 255;
-constexpr size_t kICMPv6BodyMaxSize =
-    kIPv6MinPacketSize - kIPv6HeaderSize - kICMPv6HeaderSize;
-
-struct ICMPv6Packet {
-  ip6_hdr ip_header;
-  icmp6_hdr icmp_header;
-  uint8_t body[kICMPv6BodyMaxSize];
-};
-
-// pseudo header as described in RFC 2460 Section 8.1 (excluding addresses)
-struct IPv6PseudoHeader {
-  uint32_t payload_size{};
-  uint8_t zeros[3] = {0, 0, 0};
-  uint8_t next_header = IPPROTO_ICMPV6;
-};
-
-}  // namespace
-
-void CreateIcmpPacket(in6_addr src,
-                      in6_addr dst,
-                      const icmp6_hdr& icmp_header,
-                      absl::string_view body,
-                      const std::function<void(absl::string_view)>& cb) {
-  const size_t body_size = std::min(body.size(), kICMPv6BodyMaxSize);
-  const size_t payload_size = kICMPv6HeaderSize + body_size;
-
-  ICMPv6Packet icmp_packet{};
-  // Set version to 6.
-  icmp_packet.ip_header.ip6_vfc = 0x6 << 4;
-  // Set the payload size, protocol and TTL.
-  icmp_packet.ip_header.ip6_plen =
-      quiche::QuicheEndian::HostToNet16(payload_size);
-  icmp_packet.ip_header.ip6_nxt = IPPROTO_ICMPV6;
-  icmp_packet.ip_header.ip6_hops = kIcmpTtl;
-  // Set the source address to the specified self IP.
-  icmp_packet.ip_header.ip6_src = src;
-  icmp_packet.ip_header.ip6_dst = dst;
-
-  icmp_packet.icmp_header = icmp_header;
-  // Per RFC 4443 Section 2.3, set checksum field to 0 prior to computing it
-  icmp_packet.icmp_header.icmp6_cksum = 0;
-
-  IPv6PseudoHeader pseudo_header{};
-  pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);
-
-  InternetChecksum checksum;
-  // Pseudoheader.
-  checksum.Update(icmp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
-  checksum.Update(icmp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
-  checksum.Update(reinterpret_cast<char*>(&pseudo_header),
-                  sizeof(pseudo_header));
-  // ICMP header.
-  checksum.Update(reinterpret_cast<const char*>(&icmp_packet.icmp_header),
-                  sizeof(icmp_packet.icmp_header));
-  // Body.
-  checksum.Update(body.data(), body_size);
-  icmp_packet.icmp_header.icmp6_cksum = checksum.Value();
-
-  memcpy(icmp_packet.body, body.data(), body_size);
-
-  const char* packet = reinterpret_cast<char*>(&icmp_packet);
-  const size_t packet_size = offsetof(ICMPv6Packet, body) + body_size;
-
-  cb(absl::string_view(packet, packet_size));
-}
-
-}  // namespace quic
diff --git a/quic/qbone/platform/icmp_packet.h b/quic/qbone/platform/icmp_packet.h
deleted file mode 100644
index f03f78b..0000000
--- a/quic/qbone/platform/icmp_packet.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
-
-#include <netinet/icmp6.h>
-#include <netinet/in.h>
-
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// Creates an ICMPv6 packet, returning a packed string representation of the
-// packet to |cb|. The resulting packet is given to a callback because it's
-// stack allocated inside CreateIcmpPacket.
-void CreateIcmpPacket(in6_addr src,
-                      in6_addr dst,
-                      const icmp6_hdr& icmp_header,
-                      absl::string_view body,
-                      const std::function<void(absl::string_view)>& cb);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
diff --git a/quic/qbone/platform/icmp_packet_test.cc b/quic/qbone/platform/icmp_packet_test.cc
deleted file mode 100644
index 1e6a2e9..0000000
--- a/quic/qbone/platform/icmp_packet_test.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/icmp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-constexpr char kReferenceSourceAddress[] = "fe80:1:2:3:4::1";
-constexpr char kReferenceDestinationAddress[] = "fe80:4:3:2:1::1";
-
-// clang-format off
-constexpr  uint8_t kReferenceICMPMessageBody[] {
-    0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
-    0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
-};
-
-constexpr uint8_t kReferenceICMPPacket[] = {
-    // START IPv6 Header
-    // IPv6 with zero TOS and flow label.
-    0x60, 0x00, 0x00, 0x00,
-    // Payload is 64 bytes
-    0x00, 0x40,
-    // Next header is 58
-    0x3a,
-    // Hop limit is 255
-    0xFF,
-    // Source address of fe80:1:2:3:4::1
-    0xfe, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
-    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // Destination address of fe80:4:3:2:1::1
-    0xfe, 0x80, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02,
-    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // END IPv6 Header
-    // START ICMPv6 Header
-    // Echo Request, zero code
-    0x80, 0x00,
-    // Checksum
-    0xec, 0x00,
-    // Identifier
-    0xcb, 0x82,
-    // Sequence Number
-    0x00, 0x01,
-    // END ICMPv6 Header
-    // Message body
-    0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
-    0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
-};
-// clang-format on
-
-}  // namespace
-
-TEST(IcmpPacketTest, CreatedPacketMatchesReference) {
-  QuicIpAddress src;
-  ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
-  in6_addr src_addr;
-  memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));
-
-  QuicIpAddress dst;
-  ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
-  in6_addr dst_addr;
-  memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));
-
-  icmp6_hdr icmp_header{};
-  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
-  icmp_header.icmp6_id = 0x82cb;
-  icmp_header.icmp6_seq = 0x0100;
-
-  absl::string_view message_body = absl::string_view(
-      reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
-  absl::string_view expected_packet = absl::string_view(
-      reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
-  CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
-                   [&expected_packet](absl::string_view packet) {
-                     QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
-                     ASSERT_EQ(packet, expected_packet);
-                   });
-}
-
-TEST(IcmpPacketTest, NonZeroChecksumIsIgnored) {
-  QuicIpAddress src;
-  ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
-  in6_addr src_addr;
-  memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));
-
-  QuicIpAddress dst;
-  ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
-  in6_addr dst_addr;
-  memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));
-
-  icmp6_hdr icmp_header{};
-  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
-  icmp_header.icmp6_id = 0x82cb;
-  icmp_header.icmp6_seq = 0x0100;
-  // Set the checksum to a bogus value
-  icmp_header.icmp6_cksum = 0x1234;
-
-  absl::string_view message_body = absl::string_view(
-      reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
-  absl::string_view expected_packet = absl::string_view(
-      reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
-  CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
-                   [&expected_packet](absl::string_view packet) {
-                     QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
-                     ASSERT_EQ(packet, expected_packet);
-                   });
-}
-
-}  // namespace quic
diff --git a/quic/qbone/platform/internet_checksum.cc b/quic/qbone/platform/internet_checksum.cc
deleted file mode 100644
index 3290764..0000000
--- a/quic/qbone/platform/internet_checksum.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/internet_checksum.h"
-
-namespace quic {
-
-void InternetChecksum::Update(const char* data, size_t size) {
-  const char* current;
-  for (current = data; current + 1 < data + size; current += 2) {
-    accumulator_ += *reinterpret_cast<const uint16_t*>(current);
-  }
-  if (current < data + size) {
-    accumulator_ += *reinterpret_cast<const uint8_t*>(current);
-  }
-}
-
-void InternetChecksum::Update(const uint8_t* data, size_t size) {
-  Update(reinterpret_cast<const char*>(data), size);
-}
-
-uint16_t InternetChecksum::Value() const {
-  uint32_t total = accumulator_;
-  while (total & 0xffff0000u) {
-    total = (total >> 16u) + (total & 0xffffu);
-  }
-  return ~static_cast<uint16_t>(total);
-}
-
-}  // namespace quic
diff --git a/quic/qbone/platform/internet_checksum_test.cc b/quic/qbone/platform/internet_checksum_test.cc
deleted file mode 100644
index 7da04bd..0000000
--- a/quic/qbone/platform/internet_checksum_test.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/internet_checksum.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-// From the Numerical Example described in RFC 1071
-// https://tools.ietf.org/html/rfc1071#section-3
-TEST(InternetChecksumTest, MatchesRFC1071Example) {
-  uint8_t data[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7};
-
-  InternetChecksum checksum;
-  checksum.Update(data, 8);
-  uint16_t result = checksum.Value();
-  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
-  ASSERT_EQ(0x22, result_bytes[0]);
-  ASSERT_EQ(0x0d, result_bytes[1]);
-}
-
-// Same as above, except 7 bytes. Should behave as if there was an 8th byte
-// that equals 0.
-TEST(InternetChecksumTest, MatchesRFC1071ExampleWithOddByteCount) {
-  uint8_t data[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6};
-
-  InternetChecksum checksum;
-  checksum.Update(data, 7);
-  uint16_t result = checksum.Value();
-  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
-  ASSERT_EQ(0x23, result_bytes[0]);
-  ASSERT_EQ(0x04, result_bytes[1]);
-}
-
-// From the example described at:
-// http://www.cs.berkeley.edu/~kfall/EE122/lec06/tsld023.htm
-TEST(InternetChecksumTest, MatchesBerkleyExample) {
-  uint8_t data[] = {0xe3, 0x4f, 0x23, 0x96, 0x44, 0x27, 0x99, 0xf3};
-
-  InternetChecksum checksum;
-  checksum.Update(data, 8);
-  uint16_t result = checksum.Value();
-  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
-  ASSERT_EQ(0x1a, result_bytes[0]);
-  ASSERT_EQ(0xff, result_bytes[1]);
-}
-
-TEST(InternetChecksumTest, ChecksumRequiringMultipleCarriesInLittleEndian) {
-  uint8_t data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00};
-
-  // Data will accumulate to 0x0002FFFF
-  // Summing lower and upper halves gives 0x00010001
-  // Second sum of lower and upper halves gives 0x0002
-  // One's complement gives 0xfffd, or [0xfd, 0xff] in network byte order
-  InternetChecksum checksum;
-  checksum.Update(data, 8);
-  uint16_t result = checksum.Value();
-  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
-  EXPECT_EQ(0xfd, result_bytes[0]);
-  EXPECT_EQ(0xff, result_bytes[1]);
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/platform/ip_range.cc b/quic/qbone/platform/ip_range.cc
deleted file mode 100644
index 97df5cf..0000000
--- a/quic/qbone/platform/ip_range.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/ip_range.h"
-
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-namespace {
-
-constexpr size_t kIPv4Size = 32;
-constexpr size_t kIPv6Size = 128;
-
-QuicIpAddress TruncateToLength(const QuicIpAddress& input,
-                               size_t* prefix_length) {
-  QuicIpAddress output;
-  if (input.IsIPv4()) {
-    if (*prefix_length > kIPv4Size) {
-      *prefix_length = kIPv4Size;
-      return input;
-    }
-    uint32_t raw_address =
-        *reinterpret_cast<const uint32_t*>(input.ToPackedString().data());
-    raw_address = quiche::QuicheEndian::NetToHost32(raw_address);
-    raw_address &= ~0U << (kIPv4Size - *prefix_length);
-    raw_address = quiche::QuicheEndian::HostToNet32(raw_address);
-    output.FromPackedString(reinterpret_cast<const char*>(&raw_address),
-                            sizeof(raw_address));
-    return output;
-  }
-  if (input.IsIPv6()) {
-    if (*prefix_length > kIPv6Size) {
-      *prefix_length = kIPv6Size;
-      return input;
-    }
-    uint64_t raw_address[2];
-    memcpy(raw_address, input.ToPackedString().data(), sizeof(raw_address));
-    // raw_address[0] holds higher 8 bytes in big endian and raw_address[1]
-    // holds lower 8 bytes. Converting each to little endian for us to mask bits
-    // out.
-    // The endianess between raw_address[0] and raw_address[1] is handled
-    // explicitly by handling lower and higher bytes separately.
-    raw_address[0] = quiche::QuicheEndian::NetToHost64(raw_address[0]);
-    raw_address[1] = quiche::QuicheEndian::NetToHost64(raw_address[1]);
-    if (*prefix_length <= kIPv6Size / 2) {
-      raw_address[0] &= ~uint64_t{0} << (kIPv6Size / 2 - *prefix_length);
-      raw_address[1] = 0;
-    } else {
-      raw_address[1] &= ~uint64_t{0} << (kIPv6Size - *prefix_length);
-    }
-    raw_address[0] = quiche::QuicheEndian::HostToNet64(raw_address[0]);
-    raw_address[1] = quiche::QuicheEndian::HostToNet64(raw_address[1]);
-    output.FromPackedString(reinterpret_cast<const char*>(raw_address),
-                            sizeof(raw_address));
-    return output;
-  }
-  return output;
-}
-
-}  // namespace
-
-IpRange::IpRange(const QuicIpAddress& prefix, size_t prefix_length)
-    : prefix_(prefix), prefix_length_(prefix_length) {
-  prefix_ = TruncateToLength(prefix_, &prefix_length_);
-}
-
-bool IpRange::operator==(IpRange other) const {
-  return prefix_ == other.prefix_ && prefix_length_ == other.prefix_length_;
-}
-
-bool IpRange::operator!=(IpRange other) const {
-  return !(*this == other);
-}
-
-bool IpRange::FromString(const std::string& range) {
-  size_t slash_pos = range.find('/');
-  if (slash_pos == std::string::npos) {
-    return false;
-  }
-  QuicIpAddress prefix;
-  bool success = prefix.FromString(range.substr(0, slash_pos));
-  if (!success) {
-    return false;
-  }
-  uint64_t num_processed = 0;
-  size_t prefix_length = std::stoi(range.substr(slash_pos + 1), &num_processed);
-  if (num_processed + 1 + slash_pos != range.length()) {
-    return false;
-  }
-  prefix_ = TruncateToLength(prefix, &prefix_length);
-  prefix_length_ = prefix_length;
-  return true;
-}
-
-QuicIpAddress IpRange::FirstAddressInRange() const {
-  return prefix();
-}
-
-}  // namespace quic
diff --git a/quic/qbone/platform/ip_range.h b/quic/qbone/platform/ip_range.h
deleted file mode 100644
index 70efc1a..0000000
--- a/quic/qbone/platform/ip_range.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
-
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-
-namespace quic {
-
-class IpRange {
- public:
-  // Default constructor to have an uninitialized IpRange.
-  IpRange() : prefix_length_(0) {}
-
-  // prefix will be automatically truncated to prefix_length, so that any bit
-  // after prefix_length are zero.
-  IpRange(const QuicIpAddress& prefix, size_t prefix_length);
-
-  bool operator==(IpRange other) const;
-  bool operator!=(IpRange other) const;
-
-  // Parses range that looks like "10.0.0.1/8". Tailing bits will be set to zero
-  // after prefix_length. Return false if the parsing failed.
-  bool FromString(const std::string& range);
-
-  // Returns the string representation of this object.
-  std::string ToString() const {
-    if (IsInitialized()) {
-      return absl::StrCat(prefix_.ToString(), "/", prefix_length_);
-    }
-    return "(uninitialized)";
-  }
-
-  // Whether this object is initialized.
-  bool IsInitialized() const { return prefix_.IsInitialized(); }
-
-  // Returns the first available IP address in this IpRange. The resulting
-  // address will be uninitialized if there is no available address.
-  QuicIpAddress FirstAddressInRange() const;
-
-  // The address family of this IpRange.
-  IpAddressFamily address_family() const { return prefix_.address_family(); }
-
-  // The subnet's prefix address.
-  QuicIpAddress prefix() const { return prefix_; }
-
-  // The subnet's prefix length.
-  size_t prefix_length() const { return prefix_length_; }
-
- private:
-  QuicIpAddress prefix_;
-  size_t prefix_length_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
diff --git a/quic/qbone/platform/ip_range_test.cc b/quic/qbone/platform/ip_range_test.cc
deleted file mode 100644
index 1e1b001..0000000
--- a/quic/qbone/platform/ip_range_test.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/ip_range.h"
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-TEST(IpRangeTest, TruncateWorksIPv4) {
-  QuicIpAddress before_truncate;
-  before_truncate.FromString("255.255.255.255");
-  EXPECT_EQ("128.0.0.0/1", IpRange(before_truncate, 1).ToString());
-  EXPECT_EQ("192.0.0.0/2", IpRange(before_truncate, 2).ToString());
-  EXPECT_EQ("255.224.0.0/11", IpRange(before_truncate, 11).ToString());
-  EXPECT_EQ("255.255.255.224/27", IpRange(before_truncate, 27).ToString());
-  EXPECT_EQ("255.255.255.254/31", IpRange(before_truncate, 31).ToString());
-  EXPECT_EQ("255.255.255.255/32", IpRange(before_truncate, 32).ToString());
-  EXPECT_EQ("255.255.255.255/32", IpRange(before_truncate, 33).ToString());
-}
-
-TEST(IpRangeTest, TruncateWorksIPv6) {
-  QuicIpAddress before_truncate;
-  before_truncate.FromString("ffff:ffff:ffff:ffff:f903::5");
-  EXPECT_EQ("fe00::/7", IpRange(before_truncate, 7).ToString());
-  EXPECT_EQ("ffff:ffff:ffff::/48", IpRange(before_truncate, 48).ToString());
-  EXPECT_EQ("ffff:ffff:ffff:ffff::/64",
-            IpRange(before_truncate, 64).ToString());
-  EXPECT_EQ("ffff:ffff:ffff:ffff:8000::/65",
-            IpRange(before_truncate, 65).ToString());
-  EXPECT_EQ("ffff:ffff:ffff:ffff:f903::4/127",
-            IpRange(before_truncate, 127).ToString());
-}
-
-TEST(IpRangeTest, FromStringWorksIPv4) {
-  IpRange range;
-  ASSERT_TRUE(range.FromString("127.0.3.249/26"));
-  EXPECT_EQ("127.0.3.192/26", range.ToString());
-}
-
-TEST(IpRangeTest, FromStringWorksIPv6) {
-  IpRange range;
-  ASSERT_TRUE(range.FromString("ff01:8f21:77f9::/33"));
-  EXPECT_EQ("ff01:8f21::/33", range.ToString());
-}
-
-TEST(IpRangeTest, FirstAddressWorksIPv6) {
-  IpRange range;
-  ASSERT_TRUE(range.FromString("ffff:ffff::/64"));
-  QuicIpAddress first_address = range.FirstAddressInRange();
-  EXPECT_EQ("ffff:ffff::", first_address.ToString());
-}
-
-TEST(IpRangeTest, FirstAddressWorksIPv4) {
-  IpRange range;
-  ASSERT_TRUE(range.FromString("10.0.0.0/24"));
-  QuicIpAddress first_address = range.FirstAddressInRange();
-  EXPECT_EQ("10.0.0.0", first_address.ToString());
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/platform/mock_kernel.h b/quic/qbone/platform/mock_kernel.h
deleted file mode 100644
index f014b57..0000000
--- a/quic/qbone/platform/mock_kernel.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/kernel_interface.h"
-
-namespace quic {
-
-class MockKernel : public KernelInterface {
- public:
-  MockKernel() {}
-
-  MOCK_METHOD(int,
-              bind,
-              (int fd, const struct sockaddr*, socklen_t addr_len),
-              (override));
-  MOCK_METHOD(int, close, (int fd), (override));
-  MOCK_METHOD(int, ioctl, (int fd, int request, void*), (override));
-  MOCK_METHOD(int, open, (const char*, int flags), (override));
-  MOCK_METHOD(ssize_t, read, (int fd, void*, size_t count), (override));
-  MOCK_METHOD(
-      ssize_t,
-      recvfrom,
-      (int sockfd, void*, size_t len, int flags, struct sockaddr*, socklen_t*),
-      (override));
-  MOCK_METHOD(ssize_t,
-              sendmsg,
-              (int sockfd, const struct msghdr*, int flags),
-              (override));
-  MOCK_METHOD(ssize_t,
-              sendto,
-              (int sockfd,
-               const void*,
-               size_t len,
-               int flags,
-               const struct sockaddr*,
-               socklen_t addrlen),
-              (override));
-  MOCK_METHOD(int, socket, (int domain, int type, int protocol), (override));
-  MOCK_METHOD(int,
-              setsockopt,
-              (int, int, int, const void*, socklen_t),
-              (override));
-  MOCK_METHOD(ssize_t, write, (int fd, const void*, size_t count), (override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
diff --git a/quic/qbone/platform/mock_netlink.h b/quic/qbone/platform/mock_netlink.h
deleted file mode 100644
index 83077a0..0000000
--- a/quic/qbone/platform/mock_netlink.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/netlink_interface.h"
-
-namespace quic {
-
-class MockNetlink : public NetlinkInterface {
- public:
-  MOCK_METHOD(bool, GetLinkInfo, (const std::string&, LinkInfo*), (override));
-
-  MOCK_METHOD(bool,
-              GetAddresses,
-              (int, uint8_t, std::vector<AddressInfo>*, int*),
-              (override));
-
-  MOCK_METHOD(bool,
-              ChangeLocalAddress,
-              (uint32_t,
-               Verb,
-               const QuicIpAddress&,
-               uint8_t,
-               uint8_t,
-               uint8_t,
-               const std::vector<struct rtattr*>&),
-              (override));
-
-  MOCK_METHOD(bool, GetRouteInfo, (std::vector<RoutingRule>*), (override));
-
-  MOCK_METHOD(bool,
-              ChangeRoute,
-              (Verb, uint32_t, const IpRange&, uint8_t, QuicIpAddress, int32_t),
-              (override));
-
-  MOCK_METHOD(bool, GetRuleInfo, (std::vector<IpRule>*), (override));
-
-  MOCK_METHOD(bool, ChangeRule, (Verb, uint32_t, IpRange), (override));
-
-  MOCK_METHOD(bool, Send, (struct iovec*, size_t), (override));
-
-  MOCK_METHOD(bool, Recv, (uint32_t, NetlinkParserInterface*), (override));
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
diff --git a/quic/qbone/platform/netlink.cc b/quic/qbone/platform/netlink.cc
deleted file mode 100644
index 2f4bbe2..0000000
--- a/quic/qbone/platform/netlink.cc
+++ /dev/null
@@ -1,837 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/netlink.h"
-
-#include <linux/fib_rules.h>
-
-#include <utility>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/rtnetlink_message.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-
-Netlink::Netlink(KernelInterface* kernel) : kernel_(kernel) {
-  seq_ = QuicRandom::GetInstance()->RandUint64();
-}
-
-Netlink::~Netlink() {
-  CloseSocket();
-}
-
-void Netlink::ResetRecvBuf(size_t size) {
-  if (size != 0) {
-    recvbuf_ = std::make_unique<char[]>(size);
-  } else {
-    recvbuf_ = nullptr;
-  }
-  recvbuf_length_ = size;
-}
-
-bool Netlink::OpenSocket() {
-  if (socket_fd_ >= 0) {
-    return true;
-  }
-
-  socket_fd_ = kernel_->socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-
-  if (socket_fd_ < 0) {
-    QUIC_PLOG(ERROR) << "can't open netlink socket";
-    return false;
-  }
-
-  QUIC_LOG(INFO) << "Opened a new netlink socket fd = " << socket_fd_;
-
-  // bind a local address to the socket
-  sockaddr_nl myaddr;
-  memset(&myaddr, 0, sizeof(myaddr));
-  myaddr.nl_family = AF_NETLINK;
-  if (kernel_->bind(socket_fd_, reinterpret_cast<struct sockaddr*>(&myaddr),
-                    sizeof(myaddr)) < 0) {
-    QUIC_LOG(INFO) << "can't bind address to socket";
-    CloseSocket();
-    return false;
-  }
-
-  return true;
-}
-
-void Netlink::CloseSocket() {
-  if (socket_fd_ >= 0) {
-    QUIC_LOG(INFO) << "Closing netlink socket fd = " << socket_fd_;
-    kernel_->close(socket_fd_);
-  }
-  ResetRecvBuf(0);
-  socket_fd_ = -1;
-}
-
-namespace {
-
-class LinkInfoParser : public NetlinkParserInterface {
- public:
-  LinkInfoParser(std::string interface_name, Netlink::LinkInfo* link_info)
-      : interface_name_(std::move(interface_name)), link_info_(link_info) {}
-
-  void Run(struct nlmsghdr* netlink_message) override {
-    if (netlink_message->nlmsg_type != RTM_NEWLINK) {
-      QUIC_LOG(INFO) << absl::StrCat(
-          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
-          " expected: ", RTM_NEWLINK);
-      return;
-    }
-
-    struct ifinfomsg* interface_info =
-        reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
-
-    // make sure interface_info is what we asked for.
-    if (interface_info->ifi_family != AF_UNSPEC) {
-      QUIC_LOG(INFO) << absl::StrCat(
-          "Unexpected ifi_family: ", interface_info->ifi_family,
-          " expected: ", AF_UNSPEC);
-      return;
-    }
-
-    char hardware_address[kHwAddrSize];
-    size_t hardware_address_length = 0;
-    char broadcast_address[kHwAddrSize];
-    size_t broadcast_address_length = 0;
-    std::string name;
-
-    // loop through the attributes
-    struct rtattr* rta;
-    int payload_length = IFLA_PAYLOAD(netlink_message);
-    for (rta = IFLA_RTA(interface_info); RTA_OK(rta, payload_length);
-         rta = RTA_NEXT(rta, payload_length)) {
-      int attribute_length;
-      switch (rta->rta_type) {
-        case IFLA_ADDRESS: {
-          attribute_length = RTA_PAYLOAD(rta);
-          if (attribute_length > kHwAddrSize) {
-            QUIC_VLOG(2) << "IFLA_ADDRESS too long: " << attribute_length;
-            break;
-          }
-          memmove(hardware_address, RTA_DATA(rta), attribute_length);
-          hardware_address_length = attribute_length;
-          break;
-        }
-        case IFLA_BROADCAST: {
-          attribute_length = RTA_PAYLOAD(rta);
-          if (attribute_length > kHwAddrSize) {
-            QUIC_VLOG(2) << "IFLA_BROADCAST too long: " << attribute_length;
-            break;
-          }
-          memmove(broadcast_address, RTA_DATA(rta), attribute_length);
-          broadcast_address_length = attribute_length;
-          break;
-        }
-        case IFLA_IFNAME: {
-          name = std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
-                             RTA_PAYLOAD(rta));
-          // The name maybe a 0 terminated c string.
-          name = name.substr(0, name.find('\0'));
-          break;
-        }
-      }
-    }
-
-    QUIC_VLOG(2) << "interface name: " << name
-                 << ", index: " << interface_info->ifi_index;
-
-    if (name == interface_name_) {
-      link_info_->index = interface_info->ifi_index;
-      link_info_->type = interface_info->ifi_type;
-      link_info_->hardware_address_length = hardware_address_length;
-      if (hardware_address_length > 0) {
-        memmove(&link_info_->hardware_address, hardware_address,
-                hardware_address_length);
-      }
-      link_info_->broadcast_address_length = broadcast_address_length;
-      if (broadcast_address_length > 0) {
-        memmove(&link_info_->broadcast_address, broadcast_address,
-                broadcast_address_length);
-      }
-      found_link_ = true;
-    }
-  }
-
-  bool found_link() { return found_link_; }
-
- private:
-  const std::string interface_name_;
-  Netlink::LinkInfo* const link_info_;
-  bool found_link_ = false;
-};
-
-}  // namespace
-
-bool Netlink::GetLinkInfo(const std::string& interface_name,
-                          LinkInfo* link_info) {
-  auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET,
-                                  NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
-                                  seq_, getpid(), nullptr);
-
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed.";
-    return false;
-  }
-
-  // Pass the parser to the receive routine. It may be called multiple times
-  // since there may be multiple reply packets each with multiple reply
-  // messages.
-  LinkInfoParser parser(interface_name, link_info);
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "recv failed.";
-    return false;
-  }
-
-  return parser.found_link();
-}
-
-namespace {
-
-class LocalAddressParser : public NetlinkParserInterface {
- public:
-  LocalAddressParser(int interface_index,
-                     uint8_t unwanted_flags,
-                     std::vector<Netlink::AddressInfo>* local_addresses,
-                     int* num_ipv6_nodad_dadfailed_addresses)
-      : interface_index_(interface_index),
-        unwanted_flags_(unwanted_flags),
-        local_addresses_(local_addresses),
-        num_ipv6_nodad_dadfailed_addresses_(
-            num_ipv6_nodad_dadfailed_addresses) {}
-
-  void Run(struct nlmsghdr* netlink_message) override {
-    // each nlmsg contains a header and multiple address attributes.
-    if (netlink_message->nlmsg_type != RTM_NEWADDR) {
-      QUIC_LOG(INFO) << "Unexpected nlmsg_type: " << netlink_message->nlmsg_type
-                     << " expected: " << RTM_NEWADDR;
-      return;
-    }
-
-    struct ifaddrmsg* interface_address =
-        reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));
-
-    // Make sure this is for an address family we're interested in.
-    if (interface_address->ifa_family != AF_INET &&
-        interface_address->ifa_family != AF_INET6) {
-      QUIC_VLOG(2) << absl::StrCat("uninteresting ifa family: ",
-                                   interface_address->ifa_family);
-      return;
-    }
-
-    // Keep track of addresses with both 'nodad' and 'dadfailed', this really
-    // should't be possible and is likely a kernel bug.
-    if (num_ipv6_nodad_dadfailed_addresses_ != nullptr &&
-        (interface_address->ifa_flags & IFA_F_NODAD) &&
-        (interface_address->ifa_flags & IFA_F_DADFAILED)) {
-      ++(*num_ipv6_nodad_dadfailed_addresses_);
-    }
-
-    uint8_t unwanted_flags = interface_address->ifa_flags & unwanted_flags_;
-    if (unwanted_flags != 0) {
-      QUIC_VLOG(2) << absl::StrCat("unwanted ifa flags: ", unwanted_flags);
-      return;
-    }
-
-    // loop through the attributes
-    struct rtattr* rta;
-    int payload_length = IFA_PAYLOAD(netlink_message);
-    Netlink::AddressInfo address_info;
-    for (rta = IFA_RTA(interface_address); RTA_OK(rta, payload_length);
-         rta = RTA_NEXT(rta, payload_length)) {
-      // There's quite a lot of confusion in Linux over the use of IFA_LOCAL and
-      // IFA_ADDRESS (source and destination address). For broadcast links, such
-      // as Ethernet, they are identical (see <linux/if_addr.h>), but the kernel
-      // sometimes uses only one or the other. We'll return both so that the
-      // caller can decide which to use.
-      if (rta->rta_type != IFA_LOCAL && rta->rta_type != IFA_ADDRESS) {
-        QUIC_VLOG(2) << "Ignoring uninteresting rta_type: " << rta->rta_type;
-        continue;
-      }
-
-      switch (interface_address->ifa_family) {
-        case AF_INET:
-          ABSL_FALLTHROUGH_INTENDED;
-        case AF_INET6:
-          // QuicIpAddress knows how to parse ip from raw bytes as long as they
-          // are in network byte order.
-          if (RTA_PAYLOAD(rta) == sizeof(struct in_addr) ||
-              RTA_PAYLOAD(rta) == sizeof(struct in6_addr)) {
-            auto* raw_ip = reinterpret_cast<char*>(RTA_DATA(rta));
-            if (rta->rta_type == IFA_LOCAL) {
-              address_info.local_address.FromPackedString(raw_ip,
-                                                          RTA_PAYLOAD(rta));
-            } else {
-              address_info.interface_address.FromPackedString(raw_ip,
-                                                              RTA_PAYLOAD(rta));
-            }
-          }
-          break;
-        default:
-          QUIC_LOG(ERROR) << absl::StrCat("Unknown address family: ",
-                                          interface_address->ifa_family);
-      }
-    }
-
-    QUIC_VLOG(2) << "local_address: " << address_info.local_address.ToString()
-                 << " interface_address: "
-                 << address_info.interface_address.ToString()
-                 << " index: " << interface_address->ifa_index;
-    if (interface_address->ifa_index != interface_index_) {
-      return;
-    }
-
-    address_info.prefix_length = interface_address->ifa_prefixlen;
-    address_info.scope = interface_address->ifa_scope;
-    if (address_info.local_address.IsInitialized() ||
-        address_info.interface_address.IsInitialized()) {
-      local_addresses_->push_back(address_info);
-    }
-  }
-
- private:
-  const int interface_index_;
-  const uint8_t unwanted_flags_;
-  std::vector<Netlink::AddressInfo>* const local_addresses_;
-  int* const num_ipv6_nodad_dadfailed_addresses_;
-};
-
-}  // namespace
-
-bool Netlink::GetAddresses(int interface_index,
-                           uint8_t unwanted_flags,
-                           std::vector<AddressInfo>* addresses,
-                           int* num_ipv6_nodad_dadfailed_addresses) {
-  // the message doesn't contain the index, we'll have to do the filtering while
-  // parsing the reply. This is because NLM_F_MATCH, which only returns entries
-  // that matches the request criteria, is not yet implemented (see man 3
-  // netlink).
-  auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET,
-                                     NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
-                                     seq_, getpid(), nullptr);
-
-  // the send routine returns the socket to listen on.
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed.";
-    return false;
-  }
-
-  addresses->clear();
-  if (num_ipv6_nodad_dadfailed_addresses != nullptr) {
-    *num_ipv6_nodad_dadfailed_addresses = 0;
-  }
-
-  LocalAddressParser parser(interface_index, unwanted_flags, addresses,
-                            num_ipv6_nodad_dadfailed_addresses);
-  // Pass the parser to the receive routine. It may be called multiple times
-  // since there may be multiple reply packets each with multiple reply
-  // messages.
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "recv failed";
-    return false;
-  }
-  return true;
-}
-
-namespace {
-
-class UnknownParser : public NetlinkParserInterface {
- public:
-  void Run(struct nlmsghdr* netlink_message) override {
-    QUIC_LOG(INFO) << "nlmsg reply type: " << netlink_message->nlmsg_type;
-  }
-};
-
-}  // namespace
-
-bool Netlink::ChangeLocalAddress(
-    uint32_t interface_index,
-    Verb verb,
-    const QuicIpAddress& address,
-    uint8_t prefix_length,
-    uint8_t ifa_flags,
-    uint8_t ifa_scope,
-    const std::vector<struct rtattr*>& additional_attributes) {
-  if (verb == Verb::kReplace) {
-    return false;
-  }
-  auto operation = verb == Verb::kAdd ? RtnetlinkMessage::Operation::NEW
-                                      : RtnetlinkMessage::Operation::DEL;
-  uint8_t address_family;
-  if (address.address_family() == IpAddressFamily::IP_V4) {
-    address_family = AF_INET;
-  } else if (address.address_family() == IpAddressFamily::IP_V6) {
-    address_family = AF_INET6;
-  } else {
-    return false;
-  }
-
-  struct ifaddrmsg address_header = {address_family, prefix_length, ifa_flags,
-                                     ifa_scope, interface_index};
-
-  auto message = AddressMessage::New(operation, NLM_F_REQUEST | NLM_F_ACK, seq_,
-                                     getpid(), &address_header);
-
-  for (const auto& attribute : additional_attributes) {
-    if (attribute->rta_type == IFA_LOCAL) {
-      continue;
-    }
-    message.AppendAttribute(attribute->rta_type, RTA_DATA(attribute),
-                            RTA_PAYLOAD(attribute));
-  }
-
-  message.AppendAttribute(IFA_LOCAL, address.ToPackedString().c_str(),
-                          address.ToPackedString().size());
-
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed";
-    return false;
-  }
-
-  UnknownParser parser;
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "receive failed.";
-    return false;
-  }
-  return true;
-}
-
-namespace {
-
-class RoutingRuleParser : public NetlinkParserInterface {
- public:
-  explicit RoutingRuleParser(std::vector<Netlink::RoutingRule>* routing_rules)
-      : routing_rules_(routing_rules) {}
-
-  void Run(struct nlmsghdr* netlink_message) override {
-    if (netlink_message->nlmsg_type != RTM_NEWROUTE) {
-      QUIC_LOG(WARNING) << absl::StrCat(
-          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
-          " expected: ", RTM_NEWROUTE);
-      return;
-    }
-
-    auto* route = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
-    int payload_length = RTM_PAYLOAD(netlink_message);
-
-    if (route->rtm_family != AF_INET && route->rtm_family != AF_INET6) {
-      QUIC_VLOG(2) << absl::StrCat("Uninteresting family: ", route->rtm_family);
-      return;
-    }
-
-    Netlink::RoutingRule rule;
-    rule.scope = route->rtm_scope;
-    rule.table = route->rtm_table;
-
-    struct rtattr* rta;
-    for (rta = RTM_RTA(route); RTA_OK(rta, payload_length);
-         rta = RTA_NEXT(rta, payload_length)) {
-      switch (rta->rta_type) {
-        case RTA_TABLE: {
-          rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
-          break;
-        }
-        case RTA_DST: {
-          QuicIpAddress destination;
-          destination.FromPackedString(reinterpret_cast<char*> RTA_DATA(rta),
-                                       RTA_PAYLOAD(rta));
-          rule.destination_subnet = IpRange(destination, route->rtm_dst_len);
-          break;
-        }
-        case RTA_PREFSRC: {
-          QuicIpAddress preferred_source;
-          rule.preferred_source.FromPackedString(
-              reinterpret_cast<char*> RTA_DATA(rta), RTA_PAYLOAD(rta));
-          break;
-        }
-        case RTA_OIF: {
-          rule.out_interface = *reinterpret_cast<int*>(RTA_DATA(rta));
-          break;
-        }
-        default: {
-          QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
-                                       rta->rta_type);
-        }
-      }
-    }
-    routing_rules_->push_back(rule);
-  }
-
- private:
-  std::vector<Netlink::RoutingRule>* routing_rules_;
-};
-
-}  // namespace
-
-bool Netlink::GetRouteInfo(std::vector<Netlink::RoutingRule>* routing_rules) {
-  rtmsg route_message{};
-  // Only manipulate main routing table.
-  route_message.rtm_table = RT_TABLE_MAIN;
-
-  auto message = RouteMessage::New(RtnetlinkMessage::Operation::GET,
-                                   NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH,
-                                   seq_, getpid(), &route_message);
-
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed";
-    return false;
-  }
-
-  RoutingRuleParser parser(routing_rules);
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "recv failed";
-    return false;
-  }
-
-  return true;
-}
-
-bool Netlink::ChangeRoute(Netlink::Verb verb,
-                          uint32_t table,
-                          const IpRange& destination_subnet,
-                          uint8_t scope,
-                          QuicIpAddress preferred_source,
-                          int32_t interface_index) {
-  if (!destination_subnet.prefix().IsInitialized()) {
-    return false;
-  }
-  if (destination_subnet.address_family() != IpAddressFamily::IP_V4 &&
-      destination_subnet.address_family() != IpAddressFamily::IP_V6) {
-    return false;
-  }
-  if (preferred_source.IsInitialized() &&
-      preferred_source.address_family() !=
-          destination_subnet.address_family()) {
-    return false;
-  }
-
-  RtnetlinkMessage::Operation operation;
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
-  switch (verb) {
-    case Verb::kAdd:
-      operation = RtnetlinkMessage::Operation::NEW;
-      // Setting NLM_F_EXCL so that an existing entry for this subnet will fail
-      // the request. NLM_F_CREATE is necessary to indicate this is trying to
-      // create a new entry - simply having RTM_NEWROUTE is not enough even the
-      // name suggests so.
-      flags |= NLM_F_EXCL | NLM_F_CREATE;
-      break;
-    case Verb::kRemove:
-      operation = RtnetlinkMessage::Operation::DEL;
-      break;
-    case Verb::kReplace:
-      operation = RtnetlinkMessage::Operation::NEW;
-      // Setting NLM_F_REPLACE to tell the kernel that existing entry for this
-      // subnet should be replaced.
-      flags |= NLM_F_REPLACE | NLM_F_CREATE;
-      break;
-  }
-
-  struct rtmsg route_message;
-  memset(&route_message, 0, sizeof(route_message));
-  route_message.rtm_family =
-      destination_subnet.address_family() == IpAddressFamily::IP_V4 ? AF_INET
-                                                                    : AF_INET6;
-  // rtm_dst_len and rtm_src_len are actually the subnet prefix lengths. Poor
-  // naming.
-  route_message.rtm_dst_len = destination_subnet.prefix_length();
-  // 0 means no source subnet for this rule.
-  route_message.rtm_src_len = 0;
-  // Only program the main table. Other tables are intended for the kernel to
-  // manage.
-  route_message.rtm_table = RT_TABLE_MAIN;
-  // Use RTPROT_UNSPEC to match all the different protocol. Rules added by
-  // kernel have RTPROT_KERNEL. Rules added by the root user have RTPROT_STATIC
-  // instead.
-  route_message.rtm_protocol =
-      verb == Verb::kRemove ? RTPROT_UNSPEC : RTPROT_STATIC;
-  route_message.rtm_scope = scope;
-  // Only add unicast routing rule.
-  route_message.rtm_type = RTN_UNICAST;
-  auto message =
-      RouteMessage::New(operation, flags, seq_, getpid(), &route_message);
-
-  message.AppendAttribute(RTA_TABLE, &table, sizeof(table));
-
-  // RTA_OIF is the target interface for this rule.
-  message.AppendAttribute(RTA_OIF, &interface_index, sizeof(interface_index));
-  // The actual destination subnet must be truncated of all the tailing zeros.
-  message.AppendAttribute(
-      RTA_DST,
-      reinterpret_cast<const void*>(
-          destination_subnet.prefix().ToPackedString().c_str()),
-      destination_subnet.prefix().ToPackedString().size());
-  // This is the source address to use in the IP packet should this routing rule
-  // is used.
-  if (preferred_source.IsInitialized()) {
-    auto src_str = preferred_source.ToPackedString();
-    message.AppendAttribute(RTA_PREFSRC,
-                            reinterpret_cast<const void*>(src_str.c_str()),
-                            src_str.size());
-  }
-
-  if (verb != Verb::kRemove) {
-    auto gateway_str = QboneConstants::GatewayAddress()->ToPackedString();
-    message.AppendAttribute(RTA_GATEWAY,
-                            reinterpret_cast<const void*>(gateway_str.c_str()),
-                            gateway_str.size());
-  }
-
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed";
-    return false;
-  }
-
-  UnknownParser parser;
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "receive failed.";
-    return false;
-  }
-  return true;
-}
-
-namespace {
-
-class IpRuleParser : public NetlinkParserInterface {
- public:
-  explicit IpRuleParser(std::vector<Netlink::IpRule>* ip_rules)
-      : ip_rules_(ip_rules) {}
-
-  void Run(struct nlmsghdr* netlink_message) override {
-    if (netlink_message->nlmsg_type != RTM_NEWRULE) {
-      QUIC_LOG(WARNING) << absl::StrCat(
-          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
-          " expected: ", RTM_NEWRULE);
-      return;
-    }
-
-    auto* rule = reinterpret_cast<rtmsg*>(NLMSG_DATA(netlink_message));
-    int payload_length = RTM_PAYLOAD(netlink_message);
-
-    if (rule->rtm_family != AF_INET6) {
-      QUIC_LOG(ERROR) << absl::StrCat("Unexpected family: ", rule->rtm_family);
-      return;
-    }
-
-    Netlink::IpRule ip_rule;
-    ip_rule.table = rule->rtm_table;
-
-    struct rtattr* rta;
-    for (rta = RTM_RTA(rule); RTA_OK(rta, payload_length);
-         rta = RTA_NEXT(rta, payload_length)) {
-      switch (rta->rta_type) {
-        case RTA_TABLE: {
-          ip_rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
-          break;
-        }
-        case RTA_SRC: {
-          QuicIpAddress src_addr;
-          src_addr.FromPackedString(reinterpret_cast<char*>(RTA_DATA(rta)),
-                                    RTA_PAYLOAD(rta));
-          IpRange src_range(src_addr, rule->rtm_src_len);
-          ip_rule.source_range = src_range;
-          break;
-        }
-        default: {
-          QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
-                                       rta->rta_type);
-        }
-      }
-    }
-    ip_rules_->emplace_back(ip_rule);
-  }
-
- private:
-  std::vector<Netlink::IpRule>* ip_rules_;
-};
-
-}  // namespace
-
-bool Netlink::GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) {
-  rtmsg rule_message{};
-  rule_message.rtm_family = AF_INET6;
-
-  auto message = RuleMessage::New(RtnetlinkMessage::Operation::GET,
-                                  NLM_F_REQUEST | NLM_F_DUMP, seq_, getpid(),
-                                  &rule_message);
-
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed";
-    return false;
-  }
-
-  IpRuleParser parser(ip_rules);
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "receive failed.";
-    return false;
-  }
-  return true;
-}
-
-bool Netlink::ChangeRule(Verb verb, uint32_t table, IpRange source_range) {
-  RtnetlinkMessage::Operation operation;
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
-
-  rtmsg rule_message{};
-  rule_message.rtm_family = AF_INET6;
-  rule_message.rtm_protocol = RTPROT_STATIC;
-  rule_message.rtm_scope = RT_SCOPE_UNIVERSE;
-  rule_message.rtm_table = RT_TABLE_UNSPEC;
-
-  rule_message.rtm_flags |= FIB_RULE_FIND_SADDR;
-
-  switch (verb) {
-    case Verb::kAdd:
-      if (!source_range.IsInitialized()) {
-        QUIC_LOG(ERROR) << "Source range must be initialized.";
-        return false;
-      }
-      operation = RtnetlinkMessage::Operation::NEW;
-      flags |= NLM_F_EXCL | NLM_F_CREATE;
-      rule_message.rtm_type = FRA_DST;
-      rule_message.rtm_src_len = source_range.prefix_length();
-      break;
-    case Verb::kRemove:
-      operation = RtnetlinkMessage::Operation::DEL;
-      break;
-    case Verb::kReplace:
-      QUIC_LOG(ERROR) << "Unsupported verb: kReplace";
-      return false;
-  }
-  auto message =
-      RuleMessage::New(operation, flags, seq_, getpid(), &rule_message);
-
-  message.AppendAttribute(RTA_TABLE, &table, sizeof(table));
-
-  if (source_range.IsInitialized()) {
-    std::string packed_src = source_range.prefix().ToPackedString();
-    message.AppendAttribute(RTA_SRC,
-                            reinterpret_cast<const void*>(packed_src.c_str()),
-                            packed_src.size());
-  }
-
-  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
-    QUIC_LOG(ERROR) << "send failed";
-    return false;
-  }
-
-  UnknownParser parser;
-  if (!Recv(seq_++, &parser)) {
-    QUIC_LOG(ERROR) << "receive failed.";
-    return false;
-  }
-  return true;
-}
-
-bool Netlink::Send(struct iovec* iov, size_t iovlen) {
-  if (!OpenSocket()) {
-    QUIC_LOG(ERROR) << "can't open socket";
-    return false;
-  }
-
-  // an address for communicating with the kernel netlink code
-  sockaddr_nl netlink_address;
-  memset(&netlink_address, 0, sizeof(netlink_address));
-  netlink_address.nl_family = AF_NETLINK;
-  netlink_address.nl_pid = 0;     // destination is kernel
-  netlink_address.nl_groups = 0;  // no multicast
-
-  struct msghdr msg = {
-      &netlink_address, sizeof(netlink_address), iov, iovlen, nullptr, 0, 0};
-
-  if (kernel_->sendmsg(socket_fd_, &msg, 0) < 0) {
-    QUIC_LOG(ERROR) << "sendmsg failed";
-    CloseSocket();
-    return false;
-  }
-
-  return true;
-}
-
-bool Netlink::Recv(uint32_t seq, NetlinkParserInterface* parser) {
-  sockaddr_nl netlink_address;
-
-  // replies can span multiple packets
-  for (;;) {
-    socklen_t address_length = sizeof(netlink_address);
-
-    // First, call recvfrom with buffer size of 0 and MSG_PEEK | MSG_TRUNC set
-    // so that we know the size of the incoming packet before actually receiving
-    // it.
-    int next_packet_size = kernel_->recvfrom(
-        socket_fd_, recvbuf_.get(), /* len = */ 0, MSG_PEEK | MSG_TRUNC,
-        reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
-    if (next_packet_size < 0) {
-      QUIC_LOG(ERROR)
-          << "error recvfrom with MSG_PEEK | MSG_TRUNC to get packet length.";
-      CloseSocket();
-      return false;
-    }
-    QUIC_VLOG(3) << "netlink packet size: " << next_packet_size;
-    if (next_packet_size > recvbuf_length_) {
-      QUIC_VLOG(2) << "resizing recvbuf to " << next_packet_size;
-      ResetRecvBuf(next_packet_size);
-    }
-
-    // Get the packet for real.
-    memset(recvbuf_.get(), 0, recvbuf_length_);
-    int len = kernel_->recvfrom(
-        socket_fd_, recvbuf_.get(), recvbuf_length_, /* flags = */ 0,
-        reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
-    QUIC_VLOG(3) << "recvfrom returned: " << len;
-    if (len < 0) {
-      QUIC_LOG(INFO) << "can't receive netlink packet";
-      CloseSocket();
-      return false;
-    }
-
-    // there may be multiple nlmsg's in each reply packet
-    struct nlmsghdr* netlink_message;
-    for (netlink_message = reinterpret_cast<struct nlmsghdr*>(recvbuf_.get());
-         NLMSG_OK(netlink_message, len);
-         netlink_message = NLMSG_NEXT(netlink_message, len)) {
-      QUIC_VLOG(3) << "netlink_message->nlmsg_type = "
-                   << netlink_message->nlmsg_type;
-      // make sure this is to us
-      if (netlink_message->nlmsg_seq != seq) {
-        QUIC_LOG(INFO) << "netlink_message not meant for us."
-                       << " seq: " << seq
-                       << " nlmsg_seq: " << netlink_message->nlmsg_seq;
-        continue;
-      }
-
-      // done with this whole reply (not just this particular packet)
-      if (netlink_message->nlmsg_type == NLMSG_DONE) {
-        return true;
-      }
-      if (netlink_message->nlmsg_type == NLMSG_ERROR) {
-        struct nlmsgerr* err =
-            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
-        if (netlink_message->nlmsg_len <
-            NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
-          QUIC_LOG(INFO) << "netlink_message ERROR truncated";
-        } else {
-          // an ACK
-          if (err->error == 0) {
-            QUIC_VLOG(3) << "Netlink sent an ACK";
-            return true;
-          }
-          QUIC_LOG(INFO) << "netlink_message ERROR: " << err->error;
-        }
-        return false;
-      }
-
-      parser->Run(netlink_message);
-    }
-  }
-}
-
-}  // namespace quic
diff --git a/quic/qbone/platform/netlink.h b/quic/qbone/platform/netlink.h
deleted file mode 100644
index 9a5b7d9..0000000
--- a/quic/qbone/platform/netlink.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
-
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-
-#include <cstdint>
-#include <functional>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/ip_range.h"
-#include "quic/qbone/platform/kernel_interface.h"
-#include "quic/qbone/platform/netlink_interface.h"
-
-namespace quic {
-
-// A wrapper class to provide convenient methods of manipulating IP address and
-// routing table using netlink (man 7 netlink) socket. More specifically,
-// rtnetlink is used (man 7 rtnetlink).
-//
-// This class is not thread safe, but thread compatible, as long as callers can
-// make sure Send and Recv pairs are executed in sequence for a particular
-// query.
-class Netlink : public NetlinkInterface {
- public:
-  explicit Netlink(KernelInterface* kernel);
-  ~Netlink() override;
-
-  // Gets the link information for the interface referred by the given
-  // interface_name.
-  //
-  // This is a synchronous communication. That should not be a problem since the
-  // kernel should answer immediately.
-  bool GetLinkInfo(const std::string& interface_name,
-                   LinkInfo* link_info) override;
-
-  // Gets the addresses for the given interface referred by the given
-  // interface_index.
-  //
-  // This is a synchronous communication. This should not be a problem since the
-  // kernel should answer immediately.
-  bool GetAddresses(int interface_index,
-                    uint8_t unwanted_flags,
-                    std::vector<AddressInfo>* addresses,
-                    int* num_ipv6_nodad_dadfailed_addresses) override;
-
-  // Performs the given verb that modifies local addresses on the given
-  // interface_index.
-  //
-  // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
-  // with the netlink message. Note that rta_len in each RTA is used to decide
-  // the length of the payload. The caller is responsible for making sure
-  // payload bytes are accessible after the RTA header.
-  bool ChangeLocalAddress(
-      uint32_t interface_index,
-      Verb verb,
-      const QuicIpAddress& address,
-      uint8_t prefix_length,
-      uint8_t ifa_flags,
-      uint8_t ifa_scope,
-      const std::vector<struct rtattr*>& additional_attributes) override;
-
-  // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
-  // which is programmable.
-  //
-  // This is a synchronous communication. This should not be a problem since the
-  // kernel should answer immediately.
-  bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) override;
-
-  // Performs the given Verb on the matching rule in the main routing table
-  // (RT_TABLE_MAIN).
-  //
-  // preferred_source can be !IsInitialized(), in which case it will be omitted.
-  //
-  // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
-  // preferred_source, interface_index). Return true if a matching rule is
-  // found. interface_index can be 0 for wilecard.
-  //
-  // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
-  // the given destination_subnet already exists, nothing will happen and false
-  // is returned.
-  //
-  // For Verb::kReplace, rule matching is done by destination_subnet. If no
-  // matching rule is found, a new entry will be created.
-  bool ChangeRoute(Netlink::Verb verb,
-                   uint32_t table,
-                   const IpRange& destination_subnet,
-                   uint8_t scope,
-                   QuicIpAddress preferred_source,
-                   int32_t interface_index) override;
-
-  // Returns the set of all rules in the routing policy database.
-  bool GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) override;
-
-  // Performs the give verb on the matching rule in the routing policy database.
-  // When deleting a rule, the |source_range| may be unspecified, in which case
-  // the lowest priority rule from |table| will be removed. When adding a rule,
-  // the |source_address| must be specified.
-  bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) override;
-
-  // Sends a netlink message to the kernel. iov and iovlen represents an array
-  // of struct iovec to be fed into sendmsg. The caller needs to make sure the
-  // message conform to what's expected by NLMSG_* macros.
-  //
-  // This can be useful if more flexibility is needed than the provided
-  // convenient methods can provide.
-  bool Send(struct iovec* iov, size_t iovlen) override;
-
-  // Receives a netlink message from the kernel.
-  // parser will be called on the caller's stack.
-  //
-  // This can be useful if more flexibility is needed than the provided
-  // convenient methods can provide.
-  // TODO(b/69412655): vectorize this.
-  bool Recv(uint32_t seq, NetlinkParserInterface* parser) override;
-
- private:
-  // Reset the size of recvbuf_ to size. If size is 0, recvbuf_ will be nullptr.
-  void ResetRecvBuf(size_t size);
-
-  // Opens a netlink socket if not already opened.
-  bool OpenSocket();
-
-  // Closes the opened netlink socket. Noop if no netlink socket is opened.
-  void CloseSocket();
-
-  KernelInterface* kernel_;
-  int socket_fd_ = -1;
-  std::unique_ptr<char[]> recvbuf_ = nullptr;
-  size_t recvbuf_length_ = 0;
-  uint32_t seq_;  // next msg sequence number
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
diff --git a/quic/qbone/platform/netlink_interface.h b/quic/qbone/platform/netlink_interface.h
deleted file mode 100644
index 0794b1d5..0000000
--- a/quic/qbone/platform/netlink_interface.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
-
-#include <linux/rtnetlink.h>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/ip_range.h"
-
-namespace quic {
-
-constexpr int kHwAddrSize = 6;
-
-class NetlinkParserInterface {
- public:
-  virtual ~NetlinkParserInterface() {}
-  virtual void Run(struct nlmsghdr* netlink_message) = 0;
-};
-
-// An interface providing convenience methods for manipulating IP address and
-// routing table using netlink (man 7 netlink) socket.
-class NetlinkInterface {
- public:
-  virtual ~NetlinkInterface() = default;
-
-  // Link information returned from GetLinkInfo.
-  struct LinkInfo {
-    int index;
-    uint8_t type;
-    uint8_t hardware_address[kHwAddrSize];
-    uint8_t broadcast_address[kHwAddrSize];
-    size_t hardware_address_length;   // 0 if no hardware address found
-    size_t broadcast_address_length;  // 0 if no broadcast address found
-  };
-
-  // Gets the link information for the interface referred by the given
-  // interface_name.
-  virtual bool GetLinkInfo(const std::string& interface_name,
-                           LinkInfo* link_info) = 0;
-
-  // Address information reported back from GetAddresses.
-  struct AddressInfo {
-    QuicIpAddress local_address;
-    QuicIpAddress interface_address;
-    uint8_t prefix_length = 0;
-    uint8_t scope = 0;
-  };
-
-  // Gets the addresses for the given interface referred by the given
-  // interface_index.
-  virtual bool GetAddresses(int interface_index,
-                            uint8_t unwanted_flags,
-                            std::vector<AddressInfo>* addresses,
-                            int* num_ipv6_nodad_dadfailed_addresses) = 0;
-
-  enum class Verb {
-    kAdd,
-    kRemove,
-    kReplace,
-  };
-
-  // Performs the given verb that modifies local addresses on the given
-  // interface_index.
-  //
-  // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
-  // with the netlink message. Note that rta_len in each RTA is used to decide
-  // the length of the payload. The caller is responsible for making sure
-  // payload bytes are accessible after the RTA header.
-  virtual bool ChangeLocalAddress(
-      uint32_t interface_index,
-      Verb verb,
-      const QuicIpAddress& address,
-      uint8_t prefix_length,
-      uint8_t ifa_flags,
-      uint8_t ifa_scope,
-      const std::vector<struct rtattr*>& additional_attributes) = 0;
-
-  // Routing rule reported back from GetRouteInfo.
-  struct RoutingRule {
-    uint32_t table;
-    IpRange destination_subnet;
-    QuicIpAddress preferred_source;
-    uint8_t scope;
-    int out_interface;
-  };
-
-  struct IpRule {
-    uint32_t table;
-    IpRange source_range;
-  };
-
-  // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
-  // which is programmable.
-  virtual bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) = 0;
-
-  // Performs the given Verb on the matching rule in the main routing table
-  // (RT_TABLE_MAIN).
-  //
-  // preferred_source can be !IsInitialized(), in which case it will be omitted.
-  //
-  // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
-  // preferred_source, interface_index). Return true if a matching rule is
-  // found. interface_index can be 0 for wilecard.
-  //
-  // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
-  // the given destination_subnet already exists, nothing will happen and false
-  // is returned.
-  //
-  // For Verb::kReplace, rule matching is done by destination_subnet. If no
-  // matching rule is found, a new entry will be created.
-  virtual bool ChangeRoute(Verb verb,
-                           uint32_t table,
-                           const IpRange& destination_subnet,
-                           uint8_t scope,
-                           QuicIpAddress preferred_source,
-                           int32_t interface_index) = 0;
-
-  // Returns the set of all rules in the routing policy database.
-  virtual bool GetRuleInfo(std::vector<IpRule>* ip_rules) = 0;
-
-  // Performs the give verb on the matching rule in the routing policy database.
-  // When deleting a rule, the |source_range| may be unspecified, in which case
-  // the lowest priority rule from |table| will be removed. When adding a rule,
-  // the |source_address| must be specified.
-  virtual bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) = 0;
-
-  // Sends a netlink message to the kernel. iov and iovlen represents an array
-  // of struct iovec to be fed into sendmsg. The caller needs to make sure the
-  // message conform to what's expected by NLMSG_* macros.
-  //
-  // This can be useful if more flexibility is needed than the provided
-  // convenient methods can provide.
-  virtual bool Send(struct iovec* iov, size_t iovlen) = 0;
-
-  // Receives a netlink message from the kernel.
-  // parser will be called on the caller's stack.
-  //
-  // This can be useful if more flexibility is needed than the provided
-  // convenient methods can provide.
-  virtual bool Recv(uint32_t seq, NetlinkParserInterface* parser) = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
diff --git a/quic/qbone/platform/netlink_test.cc b/quic/qbone/platform/netlink_test.cc
deleted file mode 100644
index f6fe7cd..0000000
--- a/quic/qbone/platform/netlink_test.cc
+++ /dev/null
@@ -1,784 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/netlink.h"
-
-#include <utility>
-
-#include "absl/container/node_hash_set.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/platform/mock_kernel.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-namespace {
-
-using ::testing::_;
-using ::testing::Contains;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::Unused;
-
-const int kSocketFd = 101;
-
-class NetlinkTest : public QuicTest {
- protected:
-  NetlinkTest() {
-    ON_CALL(mock_kernel_, socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE))
-        .WillByDefault(Invoke([this](Unused, Unused, Unused) {
-          EXPECT_CALL(mock_kernel_, close(kSocketFd)).WillOnce(Return(0));
-          return kSocketFd;
-        }));
-  }
-
-  void ExpectNetlinkPacket(
-      uint16_t type,
-      uint16_t flags,
-      const std::function<ssize_t(void* buf, size_t len, int seq)>&
-          recv_callback,
-      const std::function<void(const void* buf, size_t len)>& send_callback =
-          nullptr) {
-    static int seq = -1;
-    InSequence s;
-
-    EXPECT_CALL(mock_kernel_, sendmsg(kSocketFd, _, _))
-        .WillOnce(Invoke([type, flags, send_callback](
-                             Unused, const struct msghdr* msg, int) {
-          EXPECT_EQ(sizeof(struct sockaddr_nl), msg->msg_namelen);
-          auto* nl_addr =
-              reinterpret_cast<const struct sockaddr_nl*>(msg->msg_name);
-          EXPECT_EQ(AF_NETLINK, nl_addr->nl_family);
-          EXPECT_EQ(0, nl_addr->nl_pid);
-          EXPECT_EQ(0, nl_addr->nl_groups);
-
-          EXPECT_GE(msg->msg_iovlen, 1);
-          EXPECT_GE(msg->msg_iov[0].iov_len, sizeof(struct nlmsghdr));
-
-          std::string buf;
-          for (int i = 0; i < msg->msg_iovlen; i++) {
-            buf.append(
-                std::string(reinterpret_cast<char*>(msg->msg_iov[i].iov_base),
-                            msg->msg_iov[i].iov_len));
-          }
-
-          auto* netlink_message =
-              reinterpret_cast<const struct nlmsghdr*>(buf.c_str());
-          EXPECT_EQ(type, netlink_message->nlmsg_type);
-          EXPECT_EQ(flags, netlink_message->nlmsg_flags);
-          EXPECT_GE(buf.size(), netlink_message->nlmsg_len);
-
-          if (send_callback != nullptr) {
-            send_callback(buf.c_str(), buf.size());
-          }
-
-          QUICHE_CHECK_EQ(seq, -1);
-          seq = netlink_message->nlmsg_seq;
-          return buf.size();
-        }));
-
-    EXPECT_CALL(mock_kernel_,
-                recvfrom(kSocketFd, _, 0, MSG_PEEK | MSG_TRUNC, _, _))
-        .WillOnce(Invoke([this, recv_callback](Unused, Unused, Unused, Unused,
-                                               struct sockaddr* src_addr,
-                                               socklen_t* addrlen) {
-          auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
-          nl_addr->nl_family = AF_NETLINK;
-          nl_addr->nl_pid = 0;     // from kernel
-          nl_addr->nl_groups = 0;  // no multicast
-
-          int ret = recv_callback(reply_packet_, sizeof(reply_packet_), seq);
-          QUICHE_CHECK_LE(ret, sizeof(reply_packet_));
-          return ret;
-        }));
-
-    EXPECT_CALL(mock_kernel_, recvfrom(kSocketFd, _, _, _, _, _))
-        .WillOnce(Invoke([recv_callback](Unused, void* buf, size_t len, Unused,
-                                         struct sockaddr* src_addr,
-                                         socklen_t* addrlen) {
-          auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
-          nl_addr->nl_family = AF_NETLINK;
-          nl_addr->nl_pid = 0;     // from kernel
-          nl_addr->nl_groups = 0;  // no multicast
-
-          int ret = recv_callback(buf, len, seq);
-          EXPECT_GE(len, ret);
-          seq = -1;
-          return ret;
-        }));
-  }
-
-  char reply_packet_[4096];
-  MockKernel mock_kernel_;
-};
-
-void AddRTA(struct nlmsghdr* netlink_message,
-            uint16_t type,
-            const void* data,
-            size_t len) {
-  auto* next_header_ptr = reinterpret_cast<char*>(netlink_message) +
-                          NLMSG_ALIGN(netlink_message->nlmsg_len);
-
-  auto* rta = reinterpret_cast<struct rtattr*>(next_header_ptr);
-  rta->rta_type = type;
-  rta->rta_len = RTA_LENGTH(len);
-  memcpy(RTA_DATA(rta), data, len);
-
-  netlink_message->nlmsg_len =
-      NLMSG_ALIGN(netlink_message->nlmsg_len) + RTA_LENGTH(len);
-}
-
-void CreateIfinfomsg(struct nlmsghdr* netlink_message,
-                     const std::string& interface_name,
-                     uint16_t type,
-                     int index,
-                     unsigned int flags,
-                     unsigned int change,
-                     uint8_t address[],
-                     int address_len,
-                     uint8_t broadcast[],
-                     int broadcast_len) {
-  auto* interface_info =
-      reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
-  interface_info->ifi_family = AF_UNSPEC;
-  interface_info->ifi_type = type;
-  interface_info->ifi_index = index;
-  interface_info->ifi_flags = flags;
-  interface_info->ifi_change = change;
-  netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
-
-  // Add address
-  AddRTA(netlink_message, IFLA_ADDRESS, address, address_len);
-
-  // Add broadcast address
-  AddRTA(netlink_message, IFLA_BROADCAST, broadcast, broadcast_len);
-
-  // Add name
-  AddRTA(netlink_message, IFLA_IFNAME, interface_name.c_str(),
-         interface_name.size());
-}
-
-struct nlmsghdr* CreateNetlinkMessage(void* buf,  // NOLINT
-                                      struct nlmsghdr* previous_netlink_message,
-                                      uint16_t type,
-                                      int seq) {
-  auto* next_header_ptr = reinterpret_cast<char*>(buf);
-  if (previous_netlink_message != nullptr) {
-    next_header_ptr = reinterpret_cast<char*>(previous_netlink_message) +
-                      NLMSG_ALIGN(previous_netlink_message->nlmsg_len);
-  }
-  auto* netlink_message = reinterpret_cast<nlmsghdr*>(next_header_ptr);
-  netlink_message->nlmsg_len = NLMSG_LENGTH(0);
-  netlink_message->nlmsg_type = type;
-  netlink_message->nlmsg_flags = NLM_F_MULTI;
-  netlink_message->nlmsg_pid = 0;  // from the kernel
-  netlink_message->nlmsg_seq = seq;
-
-  return netlink_message;
-}
-
-void CreateIfaddrmsg(struct nlmsghdr* nlm,
-                     int interface_index,
-                     unsigned char prefixlen,
-                     unsigned char flags,
-                     unsigned char scope,
-                     QuicIpAddress ip) {
-  QUICHE_CHECK(ip.IsInitialized());
-  unsigned char family;
-  switch (ip.address_family()) {
-    case IpAddressFamily::IP_V4:
-      family = AF_INET;
-      break;
-    case IpAddressFamily::IP_V6:
-      family = AF_INET6;
-      break;
-    default:
-      QUIC_BUG(quic_bug_11034_1)
-          << absl::StrCat("unexpected address family: ", ip.address_family());
-      family = AF_UNSPEC;
-  }
-  auto* msg = reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(nlm));
-  msg->ifa_family = family;
-  msg->ifa_prefixlen = prefixlen;
-  msg->ifa_flags = flags;
-  msg->ifa_scope = scope;
-  msg->ifa_index = interface_index;
-  nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-
-  // Add local address
-  AddRTA(nlm, IFA_LOCAL, ip.ToPackedString().c_str(),
-         ip.ToPackedString().size());
-}
-
-void CreateRtmsg(struct nlmsghdr* nlm,
-                 unsigned char family,
-                 unsigned char destination_length,
-                 unsigned char source_length,
-                 unsigned char tos,
-                 unsigned char table,
-                 unsigned char protocol,
-                 unsigned char scope,
-                 unsigned char type,
-                 unsigned int flags,
-                 QuicIpAddress destination,
-                 int interface_index) {
-  auto* msg = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(nlm));
-  msg->rtm_family = family;
-  msg->rtm_dst_len = destination_length;
-  msg->rtm_src_len = source_length;
-  msg->rtm_tos = tos;
-  msg->rtm_table = table;
-  msg->rtm_protocol = protocol;
-  msg->rtm_scope = scope;
-  msg->rtm_type = type;
-  msg->rtm_flags = flags;
-  nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-
-  // Add destination
-  AddRTA(nlm, RTA_DST, destination.ToPackedString().c_str(),
-         destination.ToPackedString().size());
-
-  // Add egress interface
-  AddRTA(nlm, RTA_OIF, &interface_index, sizeof(interface_index));
-}
-
-TEST_F(NetlinkTest, GetLinkInfoWorks) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  uint8_t hwaddr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
-  uint8_t bcaddr[] = {'c', 'b', 'a', 'f', 'e', 'd'};
-
-  ExpectNetlinkPacket(
-      RTM_GETLINK, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
-      [&hwaddr, &bcaddr](void* buf, size_t len, int seq) {
-        int ret = 0;
-
-        struct nlmsghdr* netlink_message =
-            CreateNetlinkMessage(buf, nullptr, RTM_NEWLINK, seq);
-        CreateIfinfomsg(netlink_message, "tun0", /* type = */ 1,
-                        /* index = */ 7,
-                        /* flags = */ 0,
-                        /* change = */ 0xFFFFFFFF, hwaddr, 6, bcaddr, 6);
-        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
-        netlink_message =
-            CreateNetlinkMessage(buf, netlink_message, NLMSG_DONE, seq);
-        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
-        return ret;
-      });
-
-  Netlink::LinkInfo link_info;
-  EXPECT_TRUE(netlink->GetLinkInfo("tun0", &link_info));
-
-  EXPECT_EQ(7, link_info.index);
-  EXPECT_EQ(1, link_info.type);
-
-  for (int i = 0; i < link_info.hardware_address_length; ++i) {
-    EXPECT_EQ(hwaddr[i], link_info.hardware_address[i]);
-  }
-  for (int i = 0; i < link_info.broadcast_address_length; ++i) {
-    EXPECT_EQ(bcaddr[i], link_info.broadcast_address[i]);
-  }
-}
-
-TEST_F(NetlinkTest, GetAddressesWorks) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  absl::node_hash_set<std::string> addresses = {
-      QuicIpAddress::Any4().ToString(), QuicIpAddress::Any6().ToString()};
-
-  ExpectNetlinkPacket(
-      RTM_GETADDR, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
-      [&addresses](void* buf, size_t len, int seq) {
-        int ret = 0;
-
-        struct nlmsghdr* nlm = nullptr;
-
-        for (const auto& address : addresses) {
-          QuicIpAddress ip;
-          ip.FromString(address);
-          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
-          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 24,
-                          /* flags = */ 0, /* scope = */ RT_SCOPE_UNIVERSE, ip);
-
-          ret += NLMSG_ALIGN(nlm->nlmsg_len);
-        }
-
-        // Create IPs with unwanted flags.
-        {
-          QuicIpAddress ip;
-          ip.FromString("10.0.0.1");
-          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
-          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
-                          /* flags = */ IFA_F_OPTIMISTIC, /* scope = */
-                          RT_SCOPE_UNIVERSE, ip);
-
-          ret += NLMSG_ALIGN(nlm->nlmsg_len);
-
-          ip.FromString("10.0.0.2");
-          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
-          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
-                          /* flags = */ IFA_F_TENTATIVE, /* scope = */
-                          RT_SCOPE_UNIVERSE, ip);
-
-          ret += NLMSG_ALIGN(nlm->nlmsg_len);
-        }
-
-        nlm = CreateNetlinkMessage(buf, nlm, NLMSG_DONE, seq);
-        ret += NLMSG_ALIGN(nlm->nlmsg_len);
-
-        return ret;
-      });
-
-  std::vector<Netlink::AddressInfo> reported_addresses;
-  int num_ipv6_nodad_dadfailed_addresses = 0;
-  EXPECT_TRUE(netlink->GetAddresses(7, IFA_F_TENTATIVE | IFA_F_OPTIMISTIC,
-                                    &reported_addresses,
-                                    &num_ipv6_nodad_dadfailed_addresses));
-
-  for (const auto& reported_address : reported_addresses) {
-    EXPECT_TRUE(reported_address.local_address.IsInitialized());
-    EXPECT_FALSE(reported_address.interface_address.IsInitialized());
-    EXPECT_THAT(addresses, Contains(reported_address.local_address.ToString()));
-    addresses.erase(reported_address.local_address.ToString());
-
-    EXPECT_EQ(24, reported_address.prefix_length);
-  }
-
-  EXPECT_TRUE(addresses.empty());
-}
-
-TEST_F(NetlinkTest, ChangeLocalAddressAdd) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  QuicIpAddress ip = QuicIpAddress::Any6();
-  ExpectNetlinkPacket(
-      RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST,
-      [](void* buf, size_t len, int seq) {
-        struct nlmsghdr* netlink_message =
-            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
-        auto* err =
-            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
-        // Ack the request
-        err->error = 0;
-        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
-        return netlink_message->nlmsg_len;
-      },
-      [ip](const void* buf, size_t len) {
-        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
-        auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
-            NLMSG_DATA(netlink_message));
-        EXPECT_EQ(19, ifa->ifa_prefixlen);
-        EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
-        EXPECT_EQ(IFA_F_PERMANENT, ifa->ifa_flags);
-        EXPECT_EQ(7, ifa->ifa_index);
-        EXPECT_EQ(AF_INET6, ifa->ifa_family);
-
-        const struct rtattr* rta;
-        int payload_length = IFA_PAYLOAD(netlink_message);
-        int num_rta = 0;
-        for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
-             rta = RTA_NEXT(rta, payload_length)) {
-          switch (rta->rta_type) {
-            case IFA_LOCAL: {
-              EXPECT_EQ(ip.ToPackedString().size(), RTA_PAYLOAD(rta));
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(ip, address);
-              break;
-            }
-            case IFA_CACHEINFO: {
-              EXPECT_EQ(sizeof(struct ifa_cacheinfo), RTA_PAYLOAD(rta));
-              const auto* cache_info =
-                  reinterpret_cast<const struct ifa_cacheinfo*>(RTA_DATA(rta));
-              EXPECT_EQ(8, cache_info->ifa_prefered);  // common_typos_disable
-              EXPECT_EQ(6, cache_info->ifa_valid);
-              EXPECT_EQ(4, cache_info->cstamp);
-              EXPECT_EQ(2, cache_info->tstamp);
-              break;
-            }
-            default:
-              EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
-          }
-          ++num_rta;
-        }
-        EXPECT_EQ(2, num_rta);
-      });
-
-  struct {
-    struct rtattr rta;
-    struct ifa_cacheinfo cache_info;
-  } additional_rta;
-
-  additional_rta.rta.rta_type = IFA_CACHEINFO;
-  additional_rta.rta.rta_len = RTA_LENGTH(sizeof(struct ifa_cacheinfo));
-  additional_rta.cache_info.ifa_prefered = 8;
-  additional_rta.cache_info.ifa_valid = 6;
-  additional_rta.cache_info.cstamp = 4;
-  additional_rta.cache_info.tstamp = 2;
-
-  EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kAdd, ip, 19,
-                                          IFA_F_PERMANENT, RT_SCOPE_UNIVERSE,
-                                          {&additional_rta.rta}));
-}
-
-TEST_F(NetlinkTest, ChangeLocalAddressRemove) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  QuicIpAddress ip = QuicIpAddress::Any4();
-  ExpectNetlinkPacket(
-      RTM_DELADDR, NLM_F_ACK | NLM_F_REQUEST,
-      [](void* buf, size_t len, int seq) {
-        struct nlmsghdr* netlink_message =
-            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
-        auto* err =
-            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
-        // Ack the request
-        err->error = 0;
-        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
-        return netlink_message->nlmsg_len;
-      },
-      [ip](const void* buf, size_t len) {
-        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
-        auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
-            NLMSG_DATA(netlink_message));
-        EXPECT_EQ(32, ifa->ifa_prefixlen);
-        EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
-        EXPECT_EQ(0, ifa->ifa_flags);
-        EXPECT_EQ(7, ifa->ifa_index);
-        EXPECT_EQ(AF_INET, ifa->ifa_family);
-
-        const struct rtattr* rta;
-        int payload_length = IFA_PAYLOAD(netlink_message);
-        int num_rta = 0;
-        for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
-             rta = RTA_NEXT(rta, payload_length)) {
-          switch (rta->rta_type) {
-            case IFA_LOCAL: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(in_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(ip, address);
-              break;
-            }
-            default:
-              EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
-          }
-          ++num_rta;
-        }
-        EXPECT_EQ(1, num_rta);
-      });
-
-  EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kRemove, ip, 32, 0,
-                                          RT_SCOPE_UNIVERSE, {}));
-}
-
-TEST_F(NetlinkTest, GetRouteInfoWorks) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  QuicIpAddress destination;
-  ASSERT_TRUE(destination.FromString("f800::2"));
-  ExpectNetlinkPacket(RTM_GETROUTE, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
-                      [destination](void* buf, size_t len, int seq) {
-                        int ret = 0;
-                        struct nlmsghdr* netlink_message = CreateNetlinkMessage(
-                            buf, nullptr, RTM_NEWROUTE, seq);
-                        CreateRtmsg(netlink_message, AF_INET6, 48, 0, 0,
-                                    RT_TABLE_MAIN, RTPROT_STATIC, RT_SCOPE_LINK,
-                                    RTN_UNICAST, 0, destination, 7);
-                        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
-                        netlink_message = CreateNetlinkMessage(
-                            buf, netlink_message, NLMSG_DONE, seq);
-                        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
-
-                        QUIC_LOG(INFO) << "ret: " << ret;
-                        return ret;
-                      });
-
-  std::vector<Netlink::RoutingRule> routing_rules;
-  EXPECT_TRUE(netlink->GetRouteInfo(&routing_rules));
-
-  ASSERT_EQ(1, routing_rules.size());
-  EXPECT_EQ(RT_SCOPE_LINK, routing_rules[0].scope);
-  EXPECT_EQ(IpRange(destination, 48).ToString(),
-            routing_rules[0].destination_subnet.ToString());
-  EXPECT_FALSE(routing_rules[0].preferred_source.IsInitialized());
-  EXPECT_EQ(7, routing_rules[0].out_interface);
-}
-
-TEST_F(NetlinkTest, ChangeRouteAdd) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  QuicIpAddress preferred_ip;
-  preferred_ip.FromString("ff80:dead:beef::1");
-  IpRange subnet;
-  subnet.FromString("ff80:dead:beef::/48");
-  int egress_interface_index = 7;
-  ExpectNetlinkPacket(
-      RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
-      [](void* buf, size_t len, int seq) {
-        struct nlmsghdr* netlink_message =
-            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
-        auto* err =
-            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
-        // Ack the request
-        err->error = 0;
-        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
-        return netlink_message->nlmsg_len;
-      },
-      [preferred_ip, subnet, egress_interface_index](const void* buf,
-                                                     size_t len) {
-        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
-        auto* rtm =
-            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
-        EXPECT_EQ(AF_INET6, rtm->rtm_family);
-        EXPECT_EQ(48, rtm->rtm_dst_len);
-        EXPECT_EQ(0, rtm->rtm_src_len);
-        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
-        EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
-        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
-        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
-
-        const struct rtattr* rta;
-        int payload_length = RTM_PAYLOAD(netlink_message);
-        int num_rta = 0;
-        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
-             rta = RTA_NEXT(rta, payload_length)) {
-          switch (rta->rta_type) {
-            case RTA_PREFSRC: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(preferred_ip, address);
-              break;
-            }
-            case RTA_GATEWAY: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
-              break;
-            }
-            case RTA_OIF: {
-              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
-              const auto* interface_index =
-                  reinterpret_cast<const int*>(RTA_DATA(rta));
-              EXPECT_EQ(egress_interface_index, *interface_index);
-              break;
-            }
-            case RTA_DST: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(subnet.ToString(),
-                        IpRange(address, rtm->rtm_dst_len).ToString());
-              break;
-            }
-            case RTA_TABLE: {
-              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
-                        QboneConstants::kQboneRouteTableId);
-              break;
-            }
-            default:
-              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
-          }
-          ++num_rta;
-        }
-        EXPECT_EQ(5, num_rta);
-      });
-  EXPECT_TRUE(netlink->ChangeRoute(
-      Netlink::Verb::kAdd, QboneConstants::kQboneRouteTableId, subnet,
-      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
-}
-
-TEST_F(NetlinkTest, ChangeRouteRemove) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  QuicIpAddress preferred_ip;
-  preferred_ip.FromString("ff80:dead:beef::1");
-  IpRange subnet;
-  subnet.FromString("ff80:dead:beef::/48");
-  int egress_interface_index = 7;
-  ExpectNetlinkPacket(
-      RTM_DELROUTE, NLM_F_ACK | NLM_F_REQUEST,
-      [](void* buf, size_t len, int seq) {
-        struct nlmsghdr* netlink_message =
-            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
-        auto* err =
-            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
-        // Ack the request
-        err->error = 0;
-        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
-        return netlink_message->nlmsg_len;
-      },
-      [preferred_ip, subnet, egress_interface_index](const void* buf,
-                                                     size_t len) {
-        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
-        auto* rtm =
-            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
-        EXPECT_EQ(AF_INET6, rtm->rtm_family);
-        EXPECT_EQ(48, rtm->rtm_dst_len);
-        EXPECT_EQ(0, rtm->rtm_src_len);
-        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
-        EXPECT_EQ(RTPROT_UNSPEC, rtm->rtm_protocol);
-        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
-        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
-
-        const struct rtattr* rta;
-        int payload_length = RTM_PAYLOAD(netlink_message);
-        int num_rta = 0;
-        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
-             rta = RTA_NEXT(rta, payload_length)) {
-          switch (rta->rta_type) {
-            case RTA_PREFSRC: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(preferred_ip, address);
-              break;
-            }
-            case RTA_OIF: {
-              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
-              const auto* interface_index =
-                  reinterpret_cast<const int*>(RTA_DATA(rta));
-              EXPECT_EQ(egress_interface_index, *interface_index);
-              break;
-            }
-            case RTA_DST: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(subnet.ToString(),
-                        IpRange(address, rtm->rtm_dst_len).ToString());
-              break;
-            }
-            case RTA_TABLE: {
-              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
-                        QboneConstants::kQboneRouteTableId);
-              break;
-            }
-            default:
-              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
-          }
-          ++num_rta;
-        }
-        EXPECT_EQ(4, num_rta);
-      });
-  EXPECT_TRUE(netlink->ChangeRoute(
-      Netlink::Verb::kRemove, QboneConstants::kQboneRouteTableId, subnet,
-      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
-}
-
-TEST_F(NetlinkTest, ChangeRouteReplace) {
-  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
-
-  QuicIpAddress preferred_ip;
-  preferred_ip.FromString("ff80:dead:beef::1");
-  IpRange subnet;
-  subnet.FromString("ff80:dead:beef::/48");
-  int egress_interface_index = 7;
-  ExpectNetlinkPacket(
-      RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
-      [](void* buf, size_t len, int seq) {
-        struct nlmsghdr* netlink_message =
-            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
-        auto* err =
-            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
-        // Ack the request
-        err->error = 0;
-        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
-        return netlink_message->nlmsg_len;
-      },
-      [preferred_ip, subnet, egress_interface_index](const void* buf,
-                                                     size_t len) {
-        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
-        auto* rtm =
-            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
-        EXPECT_EQ(AF_INET6, rtm->rtm_family);
-        EXPECT_EQ(48, rtm->rtm_dst_len);
-        EXPECT_EQ(0, rtm->rtm_src_len);
-        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
-        EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
-        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
-        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
-
-        const struct rtattr* rta;
-        int payload_length = RTM_PAYLOAD(netlink_message);
-        int num_rta = 0;
-        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
-             rta = RTA_NEXT(rta, payload_length)) {
-          switch (rta->rta_type) {
-            case RTA_PREFSRC: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(preferred_ip, address);
-              break;
-            }
-            case RTA_GATEWAY: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
-              break;
-            }
-            case RTA_OIF: {
-              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
-              const auto* interface_index =
-                  reinterpret_cast<const int*>(RTA_DATA(rta));
-              EXPECT_EQ(egress_interface_index, *interface_index);
-              break;
-            }
-            case RTA_DST: {
-              const auto* raw_address =
-                  reinterpret_cast<const char*>(RTA_DATA(rta));
-              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
-              QuicIpAddress address;
-              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
-              EXPECT_EQ(subnet.ToString(),
-                        IpRange(address, rtm->rtm_dst_len).ToString());
-              break;
-            }
-            case RTA_TABLE: {
-              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
-                        QboneConstants::kQboneRouteTableId);
-              break;
-            }
-            default:
-              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
-          }
-          ++num_rta;
-        }
-        EXPECT_EQ(5, num_rta);
-      });
-  EXPECT_TRUE(netlink->ChangeRoute(
-      Netlink::Verb::kReplace, QboneConstants::kQboneRouteTableId, subnet,
-      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/platform/rtnetlink_message.cc b/quic/qbone/platform/rtnetlink_message.cc
deleted file mode 100644
index 24709e7..0000000
--- a/quic/qbone/platform/rtnetlink_message.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/rtnetlink_message.h"
-
-#include <utility>
-
-namespace quic {
-
-RtnetlinkMessage::RtnetlinkMessage(uint16_t type,
-                                   uint16_t flags,
-                                   uint32_t seq,
-                                   uint32_t pid,
-                                   const void* payload_header,
-                                   size_t payload_header_length) {
-  auto* buf = new uint8_t[NLMSG_SPACE(payload_header_length)];
-  memset(buf, 0, NLMSG_SPACE(payload_header_length));
-
-  auto* message_header = reinterpret_cast<struct nlmsghdr*>(buf);
-  message_header->nlmsg_len = NLMSG_LENGTH(payload_header_length);
-  message_header->nlmsg_type = type;
-  message_header->nlmsg_flags = flags;
-  message_header->nlmsg_seq = seq;
-  message_header->nlmsg_pid = pid;
-
-  if (payload_header != nullptr) {
-    memcpy(NLMSG_DATA(message_header), payload_header, payload_header_length);
-  }
-  message_.push_back({buf, NLMSG_SPACE(payload_header_length)});
-}
-
-RtnetlinkMessage::~RtnetlinkMessage() {
-  for (const auto& iov : message_) {
-    delete[] reinterpret_cast<uint8_t*>(iov.iov_base);
-  }
-}
-
-void RtnetlinkMessage::AppendAttribute(uint16_t type,
-                                       const void* data,
-                                       uint16_t data_length) {
-  auto* buf = new uint8_t[RTA_SPACE(data_length)];
-  memset(buf, 0, RTA_SPACE(data_length));
-
-  auto* rta = reinterpret_cast<struct rtattr*>(buf);
-  static_assert(sizeof(uint16_t) == sizeof(rta->rta_len),
-                "struct rtattr uses unsigned short, it's no longer 16bits");
-  static_assert(sizeof(uint16_t) == sizeof(rta->rta_type),
-                "struct rtattr uses unsigned short, it's no longer 16bits");
-
-  rta->rta_len = RTA_LENGTH(data_length);
-  rta->rta_type = type;
-  memcpy(RTA_DATA(rta), data, data_length);
-
-  message_.push_back({buf, RTA_SPACE(data_length)});
-  AdjustMessageLength(rta->rta_len);
-}
-
-std::unique_ptr<struct iovec[]> RtnetlinkMessage::BuildIoVec() const {
-  auto message = std::make_unique<struct iovec[]>(message_.size());
-  int idx = 0;
-  for (const auto& vec : message_) {
-    message[idx++] = vec;
-  }
-  return message;
-}
-
-size_t RtnetlinkMessage::IoVecSize() const {
-  return message_.size();
-}
-
-void RtnetlinkMessage::AdjustMessageLength(size_t additional_data_length) {
-  MessageHeader()->nlmsg_len =
-      NLMSG_ALIGN(MessageHeader()->nlmsg_len) + additional_data_length;
-}
-
-struct nlmsghdr* RtnetlinkMessage::MessageHeader() {
-  return reinterpret_cast<struct nlmsghdr*>(message_[0].iov_base);
-}
-
-LinkMessage LinkMessage::New(RtnetlinkMessage::Operation request_operation,
-                             uint16_t flags,
-                             uint32_t seq,
-                             uint32_t pid,
-                             const struct ifinfomsg* interface_info_header) {
-  uint16_t request_type;
-  switch (request_operation) {
-    case RtnetlinkMessage::Operation::NEW:
-      request_type = RTM_NEWLINK;
-      break;
-    case RtnetlinkMessage::Operation::DEL:
-      request_type = RTM_DELLINK;
-      break;
-    case RtnetlinkMessage::Operation::GET:
-      request_type = RTM_GETLINK;
-      break;
-  }
-  bool is_get = request_type == RTM_GETLINK;
-
-  if (is_get) {
-    struct rtgenmsg g = {AF_UNSPEC};
-    return LinkMessage(request_type, flags, seq, pid, &g, sizeof(g));
-  }
-  return LinkMessage(request_type, flags, seq, pid, interface_info_header,
-                     sizeof(struct ifinfomsg));
-}
-
-AddressMessage AddressMessage::New(
-    RtnetlinkMessage::Operation request_operation,
-    uint16_t flags,
-    uint32_t seq,
-    uint32_t pid,
-    const struct ifaddrmsg* interface_address_header) {
-  uint16_t request_type;
-  switch (request_operation) {
-    case RtnetlinkMessage::Operation::NEW:
-      request_type = RTM_NEWADDR;
-      break;
-    case RtnetlinkMessage::Operation::DEL:
-      request_type = RTM_DELADDR;
-      break;
-    case RtnetlinkMessage::Operation::GET:
-      request_type = RTM_GETADDR;
-      break;
-  }
-  bool is_get = request_type == RTM_GETADDR;
-
-  if (is_get) {
-    struct rtgenmsg g = {AF_UNSPEC};
-    return AddressMessage(request_type, flags, seq, pid, &g, sizeof(g));
-  }
-  return AddressMessage(request_type, flags, seq, pid, interface_address_header,
-                        sizeof(struct ifaddrmsg));
-}
-
-RouteMessage RouteMessage::New(RtnetlinkMessage::Operation request_operation,
-                               uint16_t flags,
-                               uint32_t seq,
-                               uint32_t pid,
-                               const struct rtmsg* route_message_header) {
-  uint16_t request_type;
-  switch (request_operation) {
-    case RtnetlinkMessage::Operation::NEW:
-      request_type = RTM_NEWROUTE;
-      break;
-    case RtnetlinkMessage::Operation::DEL:
-      request_type = RTM_DELROUTE;
-      break;
-    case RtnetlinkMessage::Operation::GET:
-      request_type = RTM_GETROUTE;
-      break;
-  }
-  return RouteMessage(request_type, flags, seq, pid, route_message_header,
-                      sizeof(struct rtmsg));
-}
-
-RuleMessage RuleMessage::New(RtnetlinkMessage::Operation request_operation,
-                             uint16_t flags,
-                             uint32_t seq,
-                             uint32_t pid,
-                             const struct rtmsg* rule_message_header) {
-  uint16_t request_type;
-  switch (request_operation) {
-    case RtnetlinkMessage::Operation::NEW:
-      request_type = RTM_NEWRULE;
-      break;
-    case RtnetlinkMessage::Operation::DEL:
-      request_type = RTM_DELRULE;
-      break;
-    case RtnetlinkMessage::Operation::GET:
-      request_type = RTM_GETRULE;
-      break;
-  }
-  return RuleMessage(request_type, flags, seq, pid, rule_message_header,
-                     sizeof(rtmsg));
-}
-}  // namespace quic
diff --git a/quic/qbone/platform/rtnetlink_message.h b/quic/qbone/platform/rtnetlink_message.h
deleted file mode 100644
index e67da1b..0000000
--- a/quic/qbone/platform/rtnetlink_message.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
-
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <stdint.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <memory>
-#include <vector>
-
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// This base class is used to construct an array struct iovec that represents a
-// rtnetlink message as defined in man 7 rtnet. Padding for message header
-// alignment to conform NLMSG_* and RTA_* macros is added at the end of each
-// iovec::iov_base.
-class RtnetlinkMessage {
- public:
-  virtual ~RtnetlinkMessage();
-
-  enum class Operation {
-    NEW,
-    DEL,
-    GET,
-  };
-
-  // Appends a struct rtattr to the message. nlmsg_len and rta_len is handled
-  // properly.
-  // Override this to perform check on type.
-  virtual void AppendAttribute(uint16_t type,
-                               const void* data,
-                               uint16_t data_length);
-
-  // Builds the array of iovec that can be fed into sendmsg directly.
-  std::unique_ptr<struct iovec[]> BuildIoVec() const;
-
-  // The size of the array of iovec if BuildIovec is called.
-  size_t IoVecSize() const;
-
- protected:
-  // Subclass should add their own message header immediately after the
-  // nlmsghdr. Make this private to force the creation of such header.
-  RtnetlinkMessage(uint16_t type,
-                   uint16_t flags,
-                   uint32_t seq,
-                   uint32_t pid,
-                   const void* payload_header,
-                   size_t payload_header_length);
-
-  // Adjusts nlmsg_len in the header assuming additional_data_length is appended
-  // at the end.
-  void AdjustMessageLength(size_t additional_data_length);
-
- private:
-  // Convenient function for accessing the nlmsghdr.
-  struct nlmsghdr* MessageHeader();
-
-  std::vector<struct iovec> message_;
-};
-
-// Message for manipulating link level configuration as defined in man 7
-// rtnetlink. RTM_NEWLINK, RTM_DELLINK and RTM_GETLINK are supported.
-class LinkMessage : public RtnetlinkMessage {
- public:
-  static LinkMessage New(RtnetlinkMessage::Operation request_operation,
-                         uint16_t flags,
-                         uint32_t seq,
-                         uint32_t pid,
-                         const struct ifinfomsg* interface_info_header);
-
- private:
-  using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-// Message for manipulating address level configuration as defined in man 7
-// rtnetlink. RTM_NEWADDR, RTM_NEWADDR and RTM_GETADDR are supported.
-class AddressMessage : public RtnetlinkMessage {
- public:
-  static AddressMessage New(RtnetlinkMessage::Operation request_operation,
-                            uint16_t flags,
-                            uint32_t seq,
-                            uint32_t pid,
-                            const struct ifaddrmsg* interface_address_header);
-
- private:
-  using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-// Message for manipulating routing table as defined in man 7 rtnetlink.
-// RTM_NEWROUTE, RTM_DELROUTE and RTM_GETROUTE are supported.
-class RouteMessage : public RtnetlinkMessage {
- public:
-  static RouteMessage New(RtnetlinkMessage::Operation request_operation,
-                          uint16_t flags,
-                          uint32_t seq,
-                          uint32_t pid,
-                          const struct rtmsg* route_message_header);
-
- private:
-  using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-class RuleMessage : public RtnetlinkMessage {
- public:
-  static RuleMessage New(RtnetlinkMessage::Operation request_operation,
-                         uint16_t flags,
-                         uint32_t seq,
-                         uint32_t pid,
-                         const struct rtmsg* rule_message_header);
-
- private:
-  using RtnetlinkMessage::RtnetlinkMessage;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
diff --git a/quic/qbone/platform/rtnetlink_message_test.cc b/quic/qbone/platform/rtnetlink_message_test.cc
deleted file mode 100644
index f2d9d92..0000000
--- a/quic/qbone/platform/rtnetlink_message_test.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/rtnetlink_message.h"
-
-#include <net/if_arp.h>
-
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-using ::testing::StrEq;
-
-TEST(RtnetlinkMessageTest, LinkMessageCanBeCreatedForGetOperation) {
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
-  uint32_t seq = 42;
-  uint32_t pid = 7;
-  auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET, flags, seq,
-                                  pid, nullptr);
-
-  // No rtattr appended.
-  EXPECT_EQ(1, message.IoVecSize());
-
-  // nlmsghdr is built properly.
-  auto iov = message.BuildIoVec();
-  EXPECT_EQ(NLMSG_SPACE(sizeof(struct rtgenmsg)), iov[0].iov_len);
-  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
-  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
-  EXPECT_EQ(RTM_GETLINK, netlink_message->nlmsg_type);
-  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
-  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
-  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
-  // We actually included rtgenmsg instead of the passed in ifinfomsg since this
-  // is a GET operation.
-  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
-}
-
-TEST(RtnetlinkMessageTest, LinkMessageCanBeCreatedForNewOperation) {
-  struct ifinfomsg interface_info_header = {AF_INET, /* pad */ 0, ARPHRD_TUNNEL,
-                                            3,       0,           0xffffffff};
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
-  uint32_t seq = 42;
-  uint32_t pid = 7;
-  auto message = LinkMessage::New(RtnetlinkMessage::Operation::NEW, flags, seq,
-                                  pid, &interface_info_header);
-
-  std::string device_name = "device0";
-  message.AppendAttribute(IFLA_IFNAME, device_name.c_str(), device_name.size());
-
-  // One rtattr appended.
-  EXPECT_EQ(2, message.IoVecSize());
-
-  // nlmsghdr is built properly.
-  auto iov = message.BuildIoVec();
-  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifinfomsg))),
-            iov[0].iov_len);
-  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
-  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifinfomsg))) +
-                RTA_LENGTH(device_name.size()),
-            netlink_message->nlmsg_len);
-  EXPECT_EQ(RTM_NEWLINK, netlink_message->nlmsg_type);
-  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
-  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
-  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
-  // ifinfomsg is included properly.
-  auto* parsed_header =
-      reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
-  EXPECT_EQ(interface_info_header.ifi_family, parsed_header->ifi_family);
-  EXPECT_EQ(interface_info_header.ifi_type, parsed_header->ifi_type);
-  EXPECT_EQ(interface_info_header.ifi_index, parsed_header->ifi_index);
-  EXPECT_EQ(interface_info_header.ifi_flags, parsed_header->ifi_flags);
-  EXPECT_EQ(interface_info_header.ifi_change, parsed_header->ifi_change);
-
-  // rtattr is handled properly.
-  EXPECT_EQ(RTA_SPACE(device_name.size()), iov[1].iov_len);
-  auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
-  EXPECT_EQ(IFLA_IFNAME, rta->rta_type);
-  EXPECT_EQ(RTA_LENGTH(device_name.size()), rta->rta_len);
-  EXPECT_THAT(device_name,
-              StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
-                                RTA_PAYLOAD(rta))));
-}
-
-TEST(RtnetlinkMessageTest, AddressMessageCanBeCreatedForGetOperation) {
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
-  uint32_t seq = 42;
-  uint32_t pid = 7;
-  auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET, flags,
-                                     seq, pid, nullptr);
-
-  // No rtattr appended.
-  EXPECT_EQ(1, message.IoVecSize());
-
-  // nlmsghdr is built properly.
-  auto iov = message.BuildIoVec();
-  EXPECT_EQ(NLMSG_SPACE(sizeof(struct rtgenmsg)), iov[0].iov_len);
-  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
-  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
-  EXPECT_EQ(RTM_GETADDR, netlink_message->nlmsg_type);
-  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
-  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
-  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
-  // We actually included rtgenmsg instead of the passed in ifinfomsg since this
-  // is a GET operation.
-  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
-}
-
-TEST(RtnetlinkMessageTest, AddressMessageCanBeCreatedForNewOperation) {
-  struct ifaddrmsg interface_address_header = {AF_INET,
-                                               /* prefixlen */ 24,
-                                               /* flags */ 0,
-                                               /* scope */ RT_SCOPE_LINK,
-                                               /* index */ 4};
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
-  uint32_t seq = 42;
-  uint32_t pid = 7;
-  auto message = AddressMessage::New(RtnetlinkMessage::Operation::NEW, flags,
-                                     seq, pid, &interface_address_header);
-
-  QuicIpAddress ip;
-  QUICHE_CHECK(ip.FromString("10.0.100.3"));
-  message.AppendAttribute(IFA_ADDRESS, ip.ToPackedString().c_str(),
-                          ip.ToPackedString().size());
-
-  // One rtattr is appended.
-  EXPECT_EQ(2, message.IoVecSize());
-
-  // nlmsghdr is built properly.
-  auto iov = message.BuildIoVec();
-  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifaddrmsg))),
-            iov[0].iov_len);
-  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
-  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifaddrmsg))) +
-                RTA_LENGTH(ip.ToPackedString().size()),
-            netlink_message->nlmsg_len);
-  EXPECT_EQ(RTM_NEWADDR, netlink_message->nlmsg_type);
-  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
-  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
-  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
-  // ifaddrmsg is included properly.
-  auto* parsed_header =
-      reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));
-  EXPECT_EQ(interface_address_header.ifa_family, parsed_header->ifa_family);
-  EXPECT_EQ(interface_address_header.ifa_prefixlen,
-            parsed_header->ifa_prefixlen);
-  EXPECT_EQ(interface_address_header.ifa_flags, parsed_header->ifa_flags);
-  EXPECT_EQ(interface_address_header.ifa_scope, parsed_header->ifa_scope);
-  EXPECT_EQ(interface_address_header.ifa_index, parsed_header->ifa_index);
-
-  // rtattr is handled properly.
-  EXPECT_EQ(RTA_SPACE(ip.ToPackedString().size()), iov[1].iov_len);
-  auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
-  EXPECT_EQ(IFA_ADDRESS, rta->rta_type);
-  EXPECT_EQ(RTA_LENGTH(ip.ToPackedString().size()), rta->rta_len);
-  EXPECT_THAT(ip.ToPackedString(),
-              StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
-                                RTA_PAYLOAD(rta))));
-}
-
-TEST(RtnetlinkMessageTest, RouteMessageCanBeCreatedFromNewOperation) {
-  struct rtmsg route_message_header = {AF_INET6,
-                                       /* rtm_dst_len */ 48,
-                                       /* rtm_src_len */ 0,
-                                       /* rtm_tos */ 0,
-                                       /* rtm_table */ RT_TABLE_MAIN,
-                                       /* rtm_protocol */ RTPROT_STATIC,
-                                       /* rtm_scope */ RT_SCOPE_LINK,
-                                       /* rtm_type */ RTN_LOCAL,
-                                       /* rtm_flags */ 0};
-  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
-  uint32_t seq = 42;
-  uint32_t pid = 7;
-  auto message = RouteMessage::New(RtnetlinkMessage::Operation::NEW, flags, seq,
-                                   pid, &route_message_header);
-
-  QuicIpAddress preferred_source;
-  QUICHE_CHECK(preferred_source.FromString("ff80::1"));
-  message.AppendAttribute(RTA_PREFSRC,
-                          preferred_source.ToPackedString().c_str(),
-                          preferred_source.ToPackedString().size());
-
-  // One rtattr is appended.
-  EXPECT_EQ(2, message.IoVecSize());
-
-  // nlmsghdr is built properly
-  auto iov = message.BuildIoVec();
-  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct rtmsg))), iov[0].iov_len);
-  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
-  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct rtmsg))) +
-                RTA_LENGTH(preferred_source.ToPackedString().size()),
-            netlink_message->nlmsg_len);
-  EXPECT_EQ(RTM_NEWROUTE, netlink_message->nlmsg_type);
-  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
-  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
-  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
-
-  // rtmsg is included properly.
-  auto* parsed_header =
-      reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
-  EXPECT_EQ(route_message_header.rtm_family, parsed_header->rtm_family);
-  EXPECT_EQ(route_message_header.rtm_dst_len, parsed_header->rtm_dst_len);
-  EXPECT_EQ(route_message_header.rtm_src_len, parsed_header->rtm_src_len);
-  EXPECT_EQ(route_message_header.rtm_tos, parsed_header->rtm_tos);
-  EXPECT_EQ(route_message_header.rtm_table, parsed_header->rtm_table);
-  EXPECT_EQ(route_message_header.rtm_protocol, parsed_header->rtm_protocol);
-  EXPECT_EQ(route_message_header.rtm_scope, parsed_header->rtm_scope);
-  EXPECT_EQ(route_message_header.rtm_type, parsed_header->rtm_type);
-  EXPECT_EQ(route_message_header.rtm_flags, parsed_header->rtm_flags);
-
-  // rtattr is handled properly.
-  EXPECT_EQ(RTA_SPACE(preferred_source.ToPackedString().size()),
-            iov[1].iov_len);
-  auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
-  EXPECT_EQ(RTA_PREFSRC, rta->rta_type);
-  EXPECT_EQ(RTA_LENGTH(preferred_source.ToPackedString().size()), rta->rta_len);
-  EXPECT_THAT(preferred_source.ToPackedString(),
-              StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
-                                RTA_PAYLOAD(rta))));
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/platform/tcp_packet.cc b/quic/qbone/platform/tcp_packet.cc
deleted file mode 100644
index f4752f2..0000000
--- a/quic/qbone/platform/tcp_packet.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/tcp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/internet_checksum.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-namespace {
-
-constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
-constexpr size_t kTcpTtl = 64;
-
-struct TCPv6Packet {
-  ip6_hdr ip_header;
-  tcphdr tcp_header;
-};
-
-struct TCPv6PseudoHeader {
-  uint32_t payload_size{};
-  uint8_t zeros[3] = {0, 0, 0};
-  uint8_t next_header = IPPROTO_TCP;
-};
-
-}  // namespace
-
-void CreateTcpResetPacket(absl::string_view original_packet,
-                          const std::function<void(absl::string_view)>& cb) {
-  // By the time this method is called, original_packet should be fairly
-  // strongly validated. However, it's better to be more paranoid than not, so
-  // here are a bunch of very obvious checks.
-  if (QUIC_PREDICT_FALSE(original_packet.size() < sizeof(ip6_hdr))) {
-    return;
-  }
-  auto* ip6_header = reinterpret_cast<const ip6_hdr*>(original_packet.data());
-  if (QUIC_PREDICT_FALSE(ip6_header->ip6_vfc >> 4 != 6)) {
-    return;
-  }
-  if (QUIC_PREDICT_FALSE(ip6_header->ip6_nxt != IPPROTO_TCP)) {
-    return;
-  }
-  if (QUIC_PREDICT_FALSE(quiche::QuicheEndian::NetToHost16(
-                             ip6_header->ip6_plen) < sizeof(tcphdr))) {
-    return;
-  }
-  auto* tcp_header = reinterpret_cast<const tcphdr*>(ip6_header + 1);
-
-  // Now that the original packet has been confirmed to be well-formed, it's
-  // time to make the TCP RST packet.
-  TCPv6Packet tcp_packet{};
-
-  const size_t payload_size = sizeof(tcphdr);
-
-  // Set version to 6.
-  tcp_packet.ip_header.ip6_vfc = 0x6 << 4;
-  // Set the payload size, protocol and TTL.
-  tcp_packet.ip_header.ip6_plen =
-      quiche::QuicheEndian::HostToNet16(payload_size);
-  tcp_packet.ip_header.ip6_nxt = IPPROTO_TCP;
-  tcp_packet.ip_header.ip6_hops = kTcpTtl;
-  // Since the TCP RST is impersonating the endpoint, flip the source and
-  // destination addresses from the original packet.
-  tcp_packet.ip_header.ip6_src = ip6_header->ip6_dst;
-  tcp_packet.ip_header.ip6_dst = ip6_header->ip6_src;
-
-  // The same is true about the TCP ports
-  tcp_packet.tcp_header.dest = tcp_header->source;
-  tcp_packet.tcp_header.source = tcp_header->dest;
-
-  // There are no extensions in this header, so size is trivial
-  tcp_packet.tcp_header.doff = sizeof(tcphdr) >> 2;
-  // Checksum is 0 before it is computed
-  tcp_packet.tcp_header.check = 0;
-
-  // Per RFC 793, TCP RST comes in one of 3 flavors:
-  //
-  // * connection CLOSED
-  // * connection in non-synchronized state (LISTEN, SYN-SENT, SYN-RECEIVED)
-  // * connection in synchronized state (ESTABLISHED, FIN-WAIT-1, etc.)
-  //
-  // QBONE is acting like a firewall, so the RFC text of interest is the CLOSED
-  // state. Note, however, that it is possible for a connection to actually be
-  // in the FIN-WAIT-1 state on the remote end, but the processing logic does
-  // not change.
-  tcp_packet.tcp_header.rst = 1;
-
-  // If the incoming segment has an ACK field, the reset takes its sequence
-  // number from the ACK field of the segment,
-  if (tcp_header->ack) {
-    tcp_packet.tcp_header.seq = tcp_header->ack_seq;
-  } else {
-    // Otherwise the reset has sequence number zero and the ACK field is set to
-    // the sum of the sequence number and segment length of the incoming segment
-    tcp_packet.tcp_header.ack = 1;
-    tcp_packet.tcp_header.seq = 0;
-    tcp_packet.tcp_header.ack_seq = quiche::QuicheEndian::HostToNet32(
-        quiche::QuicheEndian::NetToHost32(tcp_header->seq) + 1);
-  }
-
-  TCPv6PseudoHeader pseudo_header{};
-  pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);
-
-  InternetChecksum checksum;
-  // Pseudoheader.
-  checksum.Update(tcp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
-  checksum.Update(tcp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
-  checksum.Update(reinterpret_cast<char*>(&pseudo_header),
-                  sizeof(pseudo_header));
-  // TCP header.
-  checksum.Update(reinterpret_cast<const char*>(&tcp_packet.tcp_header),
-                  sizeof(tcp_packet.tcp_header));
-  // There is no body.
-  tcp_packet.tcp_header.check = checksum.Value();
-
-  const char* packet = reinterpret_cast<char*>(&tcp_packet);
-
-  cb(absl::string_view(packet, sizeof(tcp_packet)));
-}
-
-}  // namespace quic
diff --git a/quic/qbone/platform/tcp_packet.h b/quic/qbone/platform/tcp_packet.h
deleted file mode 100644
index 5fd7a76..0000000
--- a/quic/qbone/platform/tcp_packet.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
-#define QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-// Creates an TCPv6 RST packet, returning a packed string representation of the
-// packet to |cb|.
-void CreateTcpResetPacket(absl::string_view original_packet,
-                          const std::function<void(absl::string_view)>& cb);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
diff --git a/quic/qbone/platform/tcp_packet_test.cc b/quic/qbone/platform/tcp_packet_test.cc
deleted file mode 100644
index 9da9cb8..0000000
--- a/quic/qbone/platform/tcp_packet_test.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/platform/tcp_packet.h"
-
-#include <netinet/ip6.h>
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace {
-
-// clang-format off
-constexpr uint8_t kReferenceTCPSYNPacket[] = {
-  // START IPv6 Header
-  // IPv6 with zero ToS and flow label
-  0x60, 0x00, 0x00, 0x00,
-  // Payload is 40 bytes
-  0x00, 0x28,
-  // Next header is TCP (6)
-  0x06,
-  // Hop limit is 64
-  0x40,
-  // Source address of ::1
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-  // Destination address of ::1
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-  // END IPv6 Header
-  // START TCPv6 Header
-  // Source port
-  0xac, 0x1e,
-  // Destination port
-  0x27, 0x0f,
-  // Sequence number
-  0x4b, 0x01, 0xe8, 0x99,
-  // Acknowledgement Sequence number,
-  0x00, 0x00, 0x00, 0x00,
-  // Offset
-  0xa0,
-  // Flags
-  0x02,
-  // Window
-  0xaa, 0xaa,
-  // Checksum
-  0x2e, 0x21,
-  // Urgent
-  0x00, 0x00,
-  // END TCPv6 Header
-  // Options
-  0x02, 0x04, 0xff, 0xc4, 0x04, 0x02, 0x08, 0x0a,
-  0x1b, 0xb8, 0x52, 0xa1, 0x00, 0x00, 0x00, 0x00,
-  0x01, 0x03, 0x03, 0x07,
-};
-
-constexpr uint8_t kReferenceTCPRSTPacket[] = {
-  // START IPv6 Header
-  // IPv6 with zero ToS and flow label
-  0x60, 0x00, 0x00, 0x00,
-  // Payload is 20 bytes
-  0x00, 0x14,
-  // Next header is TCP (6)
-  0x06,
-  // Hop limit is 64
-  0x40,
-  // Source address of ::1
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-  // Destination address of ::1
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-  // END IPv6 Header
-  // START TCPv6 Header
-  // Source port
-  0x27, 0x0f,
-  // Destination port
-  0xac, 0x1e,
-  // Sequence number
-  0x00, 0x00, 0x00, 0x00,
-  // Acknowledgement Sequence number,
-  0x4b, 0x01, 0xe8, 0x9a,
-  // Offset
-  0x50,
-  // Flags
-  0x14,
-  // Window
-  0x00, 0x00,
-  // Checksum
-  0xa9, 0x05,
-  // Urgent
-  0x00, 0x00,
-  // END TCPv6 Header
-};
-// clang-format on
-
-}  // namespace
-
-TEST(TcpPacketTest, CreatedPacketMatchesReference) {
-  absl::string_view syn =
-      absl::string_view(reinterpret_cast<const char*>(kReferenceTCPSYNPacket),
-                        sizeof(kReferenceTCPSYNPacket));
-  absl::string_view expected_packet =
-      absl::string_view(reinterpret_cast<const char*>(kReferenceTCPRSTPacket),
-                        sizeof(kReferenceTCPRSTPacket));
-  CreateTcpResetPacket(syn, [&expected_packet](absl::string_view packet) {
-    QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
-    ASSERT_EQ(packet, expected_packet);
-  });
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_client.cc b/quic/qbone/qbone_client.cc
deleted file mode 100644
index d0daf95..0000000
--- a/quic/qbone/qbone_client.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_client.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "quic/qbone/qbone_stream.h"
-
-namespace quic {
-namespace {
-std::unique_ptr<QuicClientBase::NetworkHelper> CreateNetworkHelper(
-    QuicEpollServer* epoll_server,
-    QboneClient* client) {
-  std::unique_ptr<QuicClientBase::NetworkHelper> helper =
-      std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, client);
-  quic::AdjustTestValue("QboneClient/network_helper", &helper);
-  return helper;
-}
-}  // namespace
-
-QboneClient::QboneClient(QuicSocketAddress server_address,
-                         const QuicServerId& server_id,
-                         const ParsedQuicVersionVector& supported_versions,
-                         QuicSession::Visitor* session_owner,
-                         const QuicConfig& config,
-                         QuicEpollServer* epoll_server,
-                         std::unique_ptr<ProofVerifier> proof_verifier,
-                         QbonePacketWriter* qbone_writer,
-                         QboneClientControlStream::Handler* qbone_handler)
-    : QuicClientBase(
-          server_id,
-          supported_versions,
-          config,
-          new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
-          new QuicEpollAlarmFactory(epoll_server),
-          CreateNetworkHelper(epoll_server, this),
-          std::move(proof_verifier),
-          nullptr),
-      qbone_writer_(qbone_writer),
-      qbone_handler_(qbone_handler),
-      session_owner_(session_owner) {
-  set_server_address(server_address);
-  crypto_config()->set_alpn("qbone");
-}
-
-QboneClient::~QboneClient() {
-  ResetSession();
-}
-
-QboneClientSession* QboneClient::qbone_session() {
-  return static_cast<QboneClientSession*>(QuicClientBase::session());
-}
-
-void QboneClient::ProcessPacketFromNetwork(absl::string_view packet) {
-  qbone_session()->ProcessPacketFromNetwork(packet);
-}
-
-bool QboneClient::EarlyDataAccepted() {
-  return qbone_session()->EarlyDataAccepted();
-}
-
-bool QboneClient::ReceivedInchoateReject() {
-  return qbone_session()->ReceivedInchoateReject();
-}
-
-int QboneClient::GetNumSentClientHellosFromSession() {
-  return qbone_session()->GetNumSentClientHellos();
-}
-
-int QboneClient::GetNumReceivedServerConfigUpdatesFromSession() {
-  return qbone_session()->GetNumReceivedServerConfigUpdates();
-}
-
-void QboneClient::ResendSavedData() {
-  // no op.
-}
-
-void QboneClient::ClearDataToResend() {
-  // no op.
-}
-
-bool QboneClient::HasActiveRequests() {
-  return qbone_session()->HasActiveRequests();
-}
-
-class QboneClientSessionWithConnection : public QboneClientSession {
- public:
-  using QboneClientSession::QboneClientSession;
-
-  ~QboneClientSessionWithConnection() override { DeleteConnection(); }
-};
-
-// Takes ownership of |connection|.
-std::unique_ptr<QuicSession> QboneClient::CreateQuicClientSession(
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection) {
-  return std::make_unique<QboneClientSessionWithConnection>(
-      connection, crypto_config(), session_owner(), *config(),
-      supported_versions, server_id(), qbone_writer_, qbone_handler_);
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_client.h b/quic/qbone/qbone_client.h
deleted file mode 100644
index 7aefb25..0000000
--- a/quic/qbone/qbone_client.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
-#define QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/qbone/qbone_client_interface.h"
-#include "quic/qbone/qbone_client_session.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/tools/quic_client_base.h"
-#include "quic/tools/quic_client_epoll_network_helper.h"
-
-namespace quic {
-// A QboneClient encapsulates connecting to a server via an epoll server
-// and setting up a QBONE tunnel. See the QboneTestClient in qbone_client_test
-// for usage.
-class QboneClient : public QuicClientBase, public QboneClientInterface {
- public:
-  // Note that the epoll server, QBONE writer, and handler are owned
-  // by the caller.
-  QboneClient(QuicSocketAddress server_address,
-              const QuicServerId& server_id,
-              const ParsedQuicVersionVector& supported_versions,
-              QuicSession::Visitor* session_owner,
-              const QuicConfig& config,
-              QuicEpollServer* epoll_server,
-              std::unique_ptr<ProofVerifier> proof_verifier,
-              QbonePacketWriter* qbone_writer,
-              QboneClientControlStream::Handler* qbone_handler);
-  ~QboneClient() override;
-  QboneClientSession* qbone_session();
-
-  // From QboneClientInterface. Accepts a given packet from the network and
-  // sends the packet down to the QBONE connection.
-  void ProcessPacketFromNetwork(absl::string_view packet) override;
-
-  bool EarlyDataAccepted() override;
-  bool ReceivedInchoateReject() override;
-
- protected:
-  int GetNumSentClientHellosFromSession() override;
-  int GetNumReceivedServerConfigUpdatesFromSession() override;
-
-  // This client does not resend saved data. This will be a no-op.
-  void ResendSavedData() override;
-
-  // This client does not resend saved data. This will be a no-op.
-  void ClearDataToResend() override;
-
-  // Takes ownership of |connection|.
-  std::unique_ptr<QuicSession> CreateQuicClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection) override;
-
-  QbonePacketWriter* qbone_writer() { return qbone_writer_; }
-
-  QboneClientControlStream::Handler* qbone_control_handler() {
-    return qbone_handler_;
-  }
-
-  QuicSession::Visitor* session_owner() {
-    return session_owner_;
-  }
-
-  bool HasActiveRequests() override;
-
- private:
-  QbonePacketWriter* qbone_writer_;
-  QboneClientControlStream::Handler* qbone_handler_;
-
-  QuicSession::Visitor* session_owner_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
diff --git a/quic/qbone/qbone_client_session.cc b/quic/qbone/qbone_client_session.cc
deleted file mode 100644
index 87cfb2d..0000000
--- a/quic/qbone/qbone_client_session.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_client_session.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/qbone/qbone_constants.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, qbone_client_defer_control_stream_creation, true,
-    "If true, control stream in QBONE client session is created after "
-    "encryption established.");
-
-namespace quic {
-
-QboneClientSession::QboneClientSession(
-    QuicConnection* connection,
-    QuicCryptoClientConfig* quic_crypto_client_config,
-    QuicSession::Visitor* owner,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicServerId& server_id,
-    QbonePacketWriter* writer,
-    QboneClientControlStream::Handler* handler)
-    : QboneSessionBase(connection, owner, config, supported_versions, writer),
-      server_id_(server_id),
-      quic_crypto_client_config_(quic_crypto_client_config),
-      handler_(handler) {}
-
-QboneClientSession::~QboneClientSession() {}
-
-std::unique_ptr<QuicCryptoStream> QboneClientSession::CreateCryptoStream() {
-  return std::make_unique<QuicCryptoClientStream>(
-      server_id_, this, nullptr, quic_crypto_client_config_, this,
-      /*has_application_state = */ true);
-}
-
-void QboneClientSession::CreateControlStream() {
-  if (control_stream_ != nullptr) {
-    return;
-  }
-  // Register the reserved control stream.
-  QuicStreamId next_id = GetNextOutgoingBidirectionalStreamId();
-  QUICHE_DCHECK_EQ(next_id,
-                   QboneConstants::GetControlStreamId(transport_version()));
-  auto control_stream =
-      std::make_unique<QboneClientControlStream>(this, handler_);
-  control_stream_ = control_stream.get();
-  ActivateStream(std::move(control_stream));
-}
-
-void QboneClientSession::Initialize() {
-  // Initialize must be called first, as that's what generates the crypto
-  // stream.
-  QboneSessionBase::Initialize();
-  static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream())
-      ->CryptoConnect();
-  if (!GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation)) {
-    CreateControlStream();
-  }
-}
-
-void QboneClientSession::SetDefaultEncryptionLevel(
-    quic::EncryptionLevel level) {
-  QboneSessionBase::SetDefaultEncryptionLevel(level);
-  if (GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation) &&
-      level == quic::ENCRYPTION_FORWARD_SECURE) {
-    CreateControlStream();
-  }
-}
-
-int QboneClientSession::GetNumSentClientHellos() const {
-  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
-      ->num_sent_client_hellos();
-}
-
-bool QboneClientSession::EarlyDataAccepted() const {
-  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
-      ->EarlyDataAccepted();
-}
-
-bool QboneClientSession::ReceivedInchoateReject() const {
-  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
-      ->ReceivedInchoateReject();
-}
-
-int QboneClientSession::GetNumReceivedServerConfigUpdates() const {
-  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
-      ->num_scup_messages_received();
-}
-
-bool QboneClientSession::SendServerRequest(const QboneServerRequest& request) {
-  if (!control_stream_) {
-    QUIC_BUG(quic_bug_11056_1)
-        << "Cannot send server request before control stream is created.";
-    return false;
-  }
-  return control_stream_->SendRequest(request);
-}
-
-void QboneClientSession::ProcessPacketFromNetwork(absl::string_view packet) {
-  SendPacketToPeer(packet);
-}
-
-void QboneClientSession::ProcessPacketFromPeer(absl::string_view packet) {
-  writer_->WritePacketToNetwork(packet.data(), packet.size());
-}
-
-void QboneClientSession::OnProofValid(
-    const QuicCryptoClientConfig::CachedState& cached) {}
-
-void QboneClientSession::OnProofVerifyDetailsAvailable(
-    const ProofVerifyDetails& verify_details) {}
-
-bool QboneClientSession::HasActiveRequests() const {
-  return GetNumActiveStreams() + num_draining_streams() > 0;
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_client_session.h b/quic/qbone/qbone_client_session.h
deleted file mode 100644
index 8f1b3a9..0000000
--- a/quic/qbone/qbone_client_session.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
-#define QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/qbone/qbone_control.pb.h"
-#include "quic/qbone/qbone_control_stream.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/qbone/qbone_session_base.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QboneClientSession
-    : public QboneSessionBase,
-      public QuicCryptoClientStream::ProofHandler {
- public:
-  QboneClientSession(QuicConnection* connection,
-                     QuicCryptoClientConfig* quic_crypto_client_config,
-                     QuicSession::Visitor* owner,
-                     const QuicConfig& config,
-                     const ParsedQuicVersionVector& supported_versions,
-                     const QuicServerId& server_id,
-                     QbonePacketWriter* writer,
-                     QboneClientControlStream::Handler* handler);
-  QboneClientSession(const QboneClientSession&) = delete;
-  QboneClientSession& operator=(const QboneClientSession&) = delete;
-  ~QboneClientSession() override;
-
-  // QuicSession overrides. This will initiate the crypto stream.
-  void Initialize() override;
-  // Override to create control stream at FORWARD_SECURE encryption level.
-  void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
-
-  // Returns the number of client hello messages that have been sent on the
-  // crypto stream. If the handshake has completed then this is one greater
-  // than the number of round-trips needed for the handshake.
-  int GetNumSentClientHellos() const;
-
-  // Returns true if early data (0-RTT data) was sent and the server accepted
-  // it.
-  bool EarlyDataAccepted() const;
-
-  // Returns true if the handshake was delayed one round trip by the server
-  // because the server wanted proof the client controls its source address
-  // before progressing further. In Google QUIC, this would be due to an
-  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
-  // to a Retry packet.
-  // TODO(nharper): Consider a better name for this method.
-  bool ReceivedInchoateReject() const;
-
-  int GetNumReceivedServerConfigUpdates() const;
-
-  bool SendServerRequest(const QboneServerRequest& request);
-
-  void ProcessPacketFromNetwork(absl::string_view packet) override;
-  void ProcessPacketFromPeer(absl::string_view packet) override;
-
-  // Returns true if there are active requests on this session.
-  bool HasActiveRequests() const;
-
- protected:
-  // QboneSessionBase interface implementation.
-  std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
-
-  // Instantiate QboneClientControlStream.
-  void CreateControlStream();
-
-  // ProofHandler interface implementation.
-  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
-  void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& verify_details) override;
-
-  QuicServerId server_id() { return server_id_; }
-  QuicCryptoClientConfig* crypto_client_config() {
-    return quic_crypto_client_config_;
-  }
-
- private:
-  QuicServerId server_id_;
-  // Config for QUIC crypto client stream, used by the client.
-  QuicCryptoClientConfig* quic_crypto_client_config_;
-  // Passed to the control stream.
-  QboneClientControlStream::Handler* handler_;
-  // The unowned control stream.
-  QboneClientControlStream* control_stream_ = nullptr;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
diff --git a/quic/qbone/qbone_client_test.cc b/quic/qbone/qbone_client_test.cc
deleted file mode 100644
index cd0a3b7..0000000
--- a/quic/qbone/qbone_client_test.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Sets up a dispatcher and sends requests via the QboneClient.
-
-#include "quic/qbone/qbone_client.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-#include "quic/qbone/qbone_server_session.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_server_peer.h"
-#include "quic/test_tools/server_thread.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-ParsedQuicVersionVector GetTestParams() {
-  ParsedQuicVersionVector test_versions;
-
-  // TODO(b/113130636): Make QBONE work with TLS.
-  for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
-    // QBONE requires MESSAGE frames
-    if (!version.SupportsMessageFrames()) {
-      continue;
-    }
-    test_versions.push_back(version);
-  }
-
-  return test_versions;
-}
-
-std::string TestPacketIn(const std::string& body) {
-  return PrependIPv6HeaderForTest(body, 5);
-}
-
-std::string TestPacketOut(const std::string& body) {
-  return PrependIPv6HeaderForTest(body, 4);
-}
-
-class DataSavingQbonePacketWriter : public QbonePacketWriter {
- public:
-  void WritePacketToNetwork(const char* packet, size_t size) override {
-    QuicWriterMutexLock lock(&mu_);
-    data_.push_back(std::string(packet, size));
-  }
-
-  std::vector<std::string> data() {
-    QuicWriterMutexLock lock(&mu_);
-    return data_;
-  }
-
- private:
-  QuicMutex mu_;
-  std::vector<std::string> data_;
-};
-
-// A subclass of a QBONE session that will own the connection passed in.
-class ConnectionOwningQboneServerSession : public QboneServerSession {
- public:
-  ConnectionOwningQboneServerSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      Visitor* owner,
-      const QuicConfig& config,
-      const QuicCryptoServerConfig* quic_crypto_server_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      QbonePacketWriter* writer)
-      : QboneServerSession(supported_versions,
-                           connection,
-                           owner,
-                           config,
-                           quic_crypto_server_config,
-                           compressed_certs_cache,
-                           writer,
-                           TestLoopback6(),
-                           TestLoopback6(),
-                           64,
-                           nullptr),
-        connection_(connection) {}
-
- private:
-  // Note that we don't expect the QboneServerSession or any of its parent
-  // classes to do anything with the connection_ in their destructors.
-  std::unique_ptr<QuicConnection> connection_;
-};
-
-class QuicQboneDispatcher : public QuicDispatcher {
- public:
-  QuicQboneDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      QbonePacketWriter* writer)
-      : QuicDispatcher(config,
-                       crypto_config,
-                       version_manager,
-                       std::move(helper),
-                       std::move(session_helper),
-                       std::move(alarm_factory),
-                       kQuicDefaultConnectionIdLength),
-        writer_(writer) {}
-
-  std::unique_ptr<QuicSession> CreateQuicSession(
-      QuicConnectionId id, const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address, absl::string_view alpn,
-      const ParsedQuicVersion& version,
-      const ParsedClientHello& /*parsed_chlo*/) override {
-    QUICHE_CHECK_EQ(alpn, "qbone");
-    QuicConnection* connection = new QuicConnection(
-        id, self_address, peer_address, helper(), alarm_factory(), writer(),
-        /* owns_writer= */ false, Perspective::IS_SERVER,
-        ParsedQuicVersionVector{version});
-    // The connection owning wrapper owns the connection created.
-    auto session = std::make_unique<ConnectionOwningQboneServerSession>(
-        GetSupportedVersions(), connection, this, config(), crypto_config(),
-        compressed_certs_cache(), writer_);
-    session->Initialize();
-    return session;
-  }
-
- private:
-  QbonePacketWriter* writer_;
-};
-
-class QboneTestServer : public QuicServer {
- public:
-  explicit QboneTestServer(std::unique_ptr<ProofSource> proof_source)
-      : QuicServer(std::move(proof_source), &response_cache_) {}
-  QuicDispatcher* CreateQuicDispatcher() override {
-    QuicEpollAlarmFactory alarm_factory(epoll_server());
-    return new QuicQboneDispatcher(
-        &config(), &crypto_config(), version_manager(),
-        std::unique_ptr<QuicEpollConnectionHelper>(
-            new QuicEpollConnectionHelper(epoll_server(),
-                                          QuicAllocator::BUFFER_POOL)),
-        std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
-            new QboneCryptoServerStreamHelper()),
-        std::unique_ptr<QuicEpollAlarmFactory>(
-            new QuicEpollAlarmFactory(epoll_server())),
-        &writer_);
-  }
-
-  std::vector<std::string> data() { return writer_.data(); }
-
- private:
-  quic::QuicMemoryCacheBackend response_cache_;
-  DataSavingQbonePacketWriter writer_;
-};
-
-class QboneTestClient : public QboneClient {
- public:
-  QboneTestClient(QuicSocketAddress server_address,
-                  const QuicServerId& server_id,
-                  const ParsedQuicVersionVector& supported_versions,
-                  QuicEpollServer* epoll_server,
-                  std::unique_ptr<ProofVerifier> proof_verifier)
-      : QboneClient(server_address,
-                    server_id,
-                    supported_versions,
-                    /*session_owner=*/nullptr,
-                    QuicConfig(),
-                    epoll_server,
-                    std::move(proof_verifier),
-                    &qbone_writer_,
-                    nullptr) {}
-
-  ~QboneTestClient() override {}
-
-  void SendData(const std::string& data) {
-    qbone_session()->ProcessPacketFromNetwork(data);
-  }
-
-  void WaitForWriteToFlush() {
-    while (connected() && session()->HasDataToWrite()) {
-      WaitForEvents();
-    }
-  }
-
-  // Returns true when the data size is reached or false on timeouts.
-  bool WaitForDataSize(int n, QuicTime::Delta timeout) {
-    const QuicClock* clock =
-        quic::test::QuicConnectionPeer::GetHelper(session()->connection())
-            ->GetClock();
-    const QuicTime deadline = clock->Now() + timeout;
-    while (data().size() < n) {
-      if (clock->Now() > deadline) {
-        return false;
-      }
-      WaitForEvents();
-    }
-    return true;
-  }
-
-  std::vector<std::string> data() { return qbone_writer_.data(); }
-
- private:
-  DataSavingQbonePacketWriter qbone_writer_;
-};
-
-class QboneClientTest : public QuicTestWithParam<ParsedQuicVersion> {};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QboneClientTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QboneClientTest, SendDataFromClient) {
-  auto server = new QboneTestServer(crypto_test_utils::ProofSourceForTesting());
-  QuicSocketAddress server_address(TestLoopback(), 0);
-  ServerThread server_thread(server, server_address);
-  server_thread.Initialize();
-  server_address =
-      QuicSocketAddress(server_address.host(), server_thread.GetPort());
-  server_thread.Start();
-
-  QuicEpollServer epoll_server;
-  QboneTestClient client(
-      server_address,
-      QuicServerId("test.example.com", server_address.port(), false),
-      ParsedQuicVersionVector{GetParam()}, &epoll_server,
-      crypto_test_utils::ProofVerifierForTesting());
-  ASSERT_TRUE(client.Initialize());
-  ASSERT_TRUE(client.Connect());
-  ASSERT_TRUE(client.WaitForOneRttKeysAvailable());
-  client.SendData(TestPacketIn("hello"));
-  client.SendData(TestPacketIn("world"));
-  client.WaitForWriteToFlush();
-
-  // Wait until the server has received at least two packets, timeout after 5s.
-  ASSERT_TRUE(
-      server_thread.WaitUntil([&] { return server->data().size() >= 2; },
-                              QuicTime::Delta::FromSeconds(5)));
-
-  std::string long_data(
-      QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
-
-  // Pretend the server gets data.
-  server_thread.Schedule([&server, &long_data]() {
-    EXPECT_THAT(server->data()[0], testing::Eq(TestPacketOut("hello")));
-    EXPECT_THAT(server->data()[1], testing::Eq(TestPacketOut("world")));
-    auto server_session = static_cast<QboneServerSession*>(
-        QuicDispatcherPeer::GetFirstSessionIfAny(
-            QuicServerPeer::GetDispatcher(server)));
-    server_session->ProcessPacketFromNetwork(
-        TestPacketIn("Somethingsomething"));
-    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
-    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
-  });
-  ASSERT_TRUE(client.WaitForDataSize(3, QuicTime::Delta::FromSeconds(5)));
-  EXPECT_THAT(client.data()[0],
-              testing::Eq(TestPacketOut("Somethingsomething")));
-  EXPECT_THAT(client.data()[1], testing::Eq(TestPacketOut(long_data)));
-  EXPECT_THAT(client.data()[2], testing::Eq(TestPacketOut(long_data)));
-
-  client.Disconnect();
-  server_thread.Quit();
-  server_thread.Join();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/qbone/qbone_constants.cc b/quic/qbone/qbone_constants.cc
deleted file mode 100644
index f54ebc3..0000000
--- a/quic/qbone/qbone_constants.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_constants.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-constexpr char QboneConstants::kQboneAlpn[];
-const QuicByteCount QboneConstants::kMaxQbonePacketBytes;
-const uint32_t QboneConstants::kQboneRouteTableId;
-
-QuicStreamId QboneConstants::GetControlStreamId(QuicTransportVersion version) {
-  return QuicUtils::GetFirstBidirectionalStreamId(version,
-                                                  Perspective::IS_CLIENT);
-}
-
-const QuicIpAddress* QboneConstants::TerminatorLocalAddress() {
-  static auto* terminator_address = []() {
-    auto* address = new QuicIpAddress;
-    // 0x71 0x62 0x6f 0x6e 0x65 is 'qbone' in ascii.
-    address->FromString("fe80::71:626f:6e65");
-    return address;
-  }();
-  return terminator_address;
-}
-
-const IpRange* QboneConstants::TerminatorLocalAddressRange() {
-  static auto* range =
-      new quic::IpRange(*quic::QboneConstants::TerminatorLocalAddress(), 128);
-  return range;
-}
-
-const QuicIpAddress* QboneConstants::GatewayAddress() {
-  static auto* gateway_address = []() {
-    auto* address = new QuicIpAddress;
-    address->FromString("fe80::1");
-    return address;
-  }();
-  return gateway_address;
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_constants.h b/quic/qbone/qbone_constants.h
deleted file mode 100644
index 141bb6c..0000000
--- a/quic/qbone/qbone_constants.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
-#define QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/qbone/platform/ip_range.h"
-
-namespace quic {
-
-struct QboneConstants {
-  // QBONE's ALPN
-  static constexpr char kQboneAlpn[] = "qbone";
-  // The maximum number of bytes allowed in a QBONE packet.
-  static const QuicByteCount kMaxQbonePacketBytes = 2000;
-  // The table id for QBONE's routing table. 'bone' in ascii.
-  static const uint32_t kQboneRouteTableId = 0x626F6E65;
-  // The stream ID of the control channel.
-  static QuicStreamId GetControlStreamId(QuicTransportVersion version);
-  // The link-local address of the Terminator
-  static const QuicIpAddress* TerminatorLocalAddress();
-  // The IPRange containing the TerminatorLocalAddress
-  static const IpRange* TerminatorLocalAddressRange();
-  // The gateway address to provide when configuring routes to the QBONE
-  // interface
-  static const QuicIpAddress* GatewayAddress();
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
diff --git a/quic/qbone/qbone_control_placeholder.proto b/quic/qbone/qbone_control_placeholder.proto
deleted file mode 100644
index d9b1a6a..0000000
--- a/quic/qbone/qbone_control_placeholder.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package quic;
-
-import "quic/qbone/qbone_control.proto";
-
-// These provide fields for QboneServerRequest and QboneClientRequest that are
-// used to test the control channel.  Once the control channel actually has real
-// data to pass they can be removed.
-// TODO(b/62139999): Remove this file in favor of testing actual configuration.
-
-extend QboneServerRequest {
-  optional string server_placeholder = 179838467;
-}
-
-extend QboneClientRequest {
-  optional string client_placeholder = 179838467;
-}
diff --git a/quic/qbone/qbone_control_stream.cc b/quic/qbone/qbone_control_stream.cc
deleted file mode 100644
index 61a9afe..0000000
--- a/quic/qbone/qbone_control_stream.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_control_stream.h"
-
-#include <cstdint>
-#include <limits>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/qbone/qbone_constants.h"
-
-namespace quic {
-
-namespace {
-static constexpr size_t kRequestSizeBytes = sizeof(uint16_t);
-}  // namespace
-
-QboneControlStreamBase::QboneControlStreamBase(QuicSession* session)
-    : QuicStream(
-          QboneConstants::GetControlStreamId(session->transport_version()),
-          session,
-          /*is_static=*/true,
-          BIDIRECTIONAL),
-      pending_message_size_(0) {}
-
-QboneControlStreamBase::QboneControlStreamBase(quic::PendingStream* pending,
-                                               QuicSession* session)
-    : QuicStream(pending, session, /*is_static=*/true),
-      pending_message_size_(0) {
-  QUICHE_DCHECK_EQ(pending->id(), QboneConstants::GetControlStreamId(
-                                      session->transport_version()));
-}
-
-void QboneControlStreamBase::OnDataAvailable() {
-  sequencer()->Read(&buffer_);
-  while (true) {
-    if (pending_message_size_ == 0) {
-      // Start of a message.
-      if (buffer_.size() < kRequestSizeBytes) {
-        return;
-      }
-      memcpy(&pending_message_size_, buffer_.data(), kRequestSizeBytes);
-      buffer_.erase(0, kRequestSizeBytes);
-    }
-    // Continuation of a message.
-    if (buffer_.size() < pending_message_size_) {
-      return;
-    }
-    std::string tmp = buffer_.substr(0, pending_message_size_);
-    buffer_.erase(0, pending_message_size_);
-    pending_message_size_ = 0;
-    OnMessage(tmp);
-  }
-}
-
-bool QboneControlStreamBase::SendMessage(const proto2::Message& proto) {
-  std::string tmp;
-  if (!proto.SerializeToString(&tmp)) {
-    QUIC_BUG(quic_bug_11023_1) << "Failed to serialize QboneControlRequest";
-    return false;
-  }
-  if (tmp.size() > std::numeric_limits<uint16_t>::max()) {
-    QUIC_BUG(quic_bug_11023_2)
-        << "QboneControlRequest too large: " << tmp.size() << " > "
-        << std::numeric_limits<uint16_t>::max();
-    return false;
-  }
-  uint16_t size = tmp.size();
-  char size_str[kRequestSizeBytes];
-  memcpy(size_str, &size, kRequestSizeBytes);
-  WriteOrBufferData(absl::string_view(size_str, kRequestSizeBytes), false,
-                    nullptr);
-  WriteOrBufferData(tmp, false, nullptr);
-  return true;
-}
-
-void QboneControlStreamBase::OnStreamReset(
-    const QuicRstStreamFrame& /*frame*/) {
-  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
-                                   "Attempt to reset control stream");
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_control_stream.h b/quic/qbone/qbone_control_stream.h
deleted file mode 100644
index c38697d..0000000
--- a/quic/qbone/qbone_control_stream.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
-#define QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
-
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/qbone_control.pb.h"
-
-namespace quic {
-
-class QboneSessionBase;
-
-class QUIC_EXPORT_PRIVATE QboneControlStreamBase : public QuicStream {
- public:
-  explicit QboneControlStreamBase(QuicSession* session);
-  QboneControlStreamBase(quic::PendingStream* pending, QuicSession* session);
-
-  void OnDataAvailable() override;
-
-  void OnStreamReset(const QuicRstStreamFrame& frame) override;
-
- protected:
-  virtual void OnMessage(const std::string& data) = 0;
-  bool SendMessage(const proto2::Message& proto);
-
- private:
-  uint16_t pending_message_size_;
-  std::string buffer_;
-};
-
-template <class T>
-class QUIC_EXPORT_PRIVATE QboneControlHandler {
- public:
-  virtual ~QboneControlHandler() { }
-
-  virtual void OnControlRequest(const T& request) = 0;
-  virtual void OnControlError() = 0;
-};
-
-template <class Incoming, class Outgoing>
-class QUIC_EXPORT_PRIVATE QboneControlStream : public QboneControlStreamBase {
- public:
-  using Handler = QboneControlHandler<Incoming>;
-
-  QboneControlStream(QuicSession* session, Handler* handler)
-      : QboneControlStreamBase(session), handler_(handler) {}
-  QboneControlStream(quic::PendingStream* pending, QuicSession* session,
-                     Handler* handler)
-      : QboneControlStreamBase(pending, session), handler_(handler) {}
-
-  bool SendRequest(const Outgoing& request) { return SendMessage(request); }
-
- protected:
-  void OnMessage(const std::string& data) override {
-    Incoming request;
-    if (!request.ParseFromString(data)) {
-      QUIC_LOG(ERROR) << "Failed to parse incoming request";
-      if (handler_ != nullptr) {
-        handler_->OnControlError();
-      }
-      return;
-    }
-    if (handler_ != nullptr) {
-      handler_->OnControlRequest(request);
-    }
-  }
-
- private:
-  Handler* handler_;
-};
-
-using QboneServerControlStream =
-    QboneControlStream<QboneServerRequest, QboneClientRequest>;
-using QboneClientControlStream =
-    QboneControlStream<QboneClientRequest, QboneServerRequest>;
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
diff --git a/quic/qbone/qbone_packet_exchanger.cc b/quic/qbone/qbone_packet_exchanger.cc
deleted file mode 100644
index f8acb4f..0000000
--- a/quic/qbone/qbone_packet_exchanger.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_packet_exchanger.h"
-
-#include <utility>
-
-namespace quic {
-
-bool QbonePacketExchanger::ReadAndDeliverPacket(
-    QboneClientInterface* qbone_client) {
-  bool blocked = false;
-  std::string error;
-  std::unique_ptr<QuicData> packet = ReadPacket(&blocked, &error);
-  if (packet == nullptr) {
-    if (!blocked && visitor_) {
-      visitor_->OnReadError(error);
-    }
-    return false;
-  }
-  qbone_client->ProcessPacketFromNetwork(packet->AsStringPiece());
-  return true;
-}
-
-void QbonePacketExchanger::WritePacketToNetwork(const char* packet,
-                                                size_t size) {
-  bool blocked = false;
-  std::string error;
-  if (packet_queue_.empty() && !write_blocked_) {
-    if (WritePacket(packet, size, &blocked, &error)) {
-      return;
-    }
-    if (blocked) {
-      write_blocked_ = true;
-    } else {
-      QUIC_LOG_EVERY_N_SEC(ERROR, 60) << "Packet write failed: " << error;
-      if (visitor_) {
-        visitor_->OnWriteError(error);
-      }
-    }
-  }
-
-  // Drop the packet on the floor if the queue if full.
-  if (packet_queue_.size() >= max_pending_packets_) {
-    return;
-  }
-
-  auto data_copy = new char[size];
-  memcpy(data_copy, packet, size);
-  packet_queue_.push_back(
-      std::make_unique<QuicData>(data_copy, size, /* owns_buffer = */ true));
-}
-
-void QbonePacketExchanger::SetWritable() {
-  write_blocked_ = false;
-  while (!packet_queue_.empty()) {
-    bool blocked = false;
-    std::string error;
-    if (WritePacket(packet_queue_.front()->data(),
-                    packet_queue_.front()->length(), &blocked, &error)) {
-      packet_queue_.pop_front();
-    } else {
-      if (!blocked && visitor_) {
-        visitor_->OnWriteError(error);
-      }
-      write_blocked_ = blocked;
-      return;
-    }
-  }
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_packet_exchanger.h b/quic/qbone/qbone_packet_exchanger.h
deleted file mode 100644
index ad393b8..0000000
--- a/quic/qbone/qbone_packet_exchanger.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/qbone/qbone_client_interface.h"
-#include "quic/qbone/qbone_packet_writer.h"
-
-namespace quic {
-
-// Handles reading and writing on the local network and exchange packets between
-// the local network with a QBONE connection.
-class QbonePacketExchanger : public QbonePacketWriter {
- public:
-  // The owner might want to receive notifications when read or write fails.
-  class Visitor {
-   public:
-    virtual ~Visitor() {}
-    virtual void OnReadError(const std::string& error) {}
-    virtual void OnWriteError(const std::string& error) {}
-  };
-  // Does not take ownership of visitor.
-  QbonePacketExchanger(Visitor* visitor, size_t max_pending_packets)
-      : visitor_(visitor), max_pending_packets_(max_pending_packets) {}
-
-  QbonePacketExchanger(const QbonePacketExchanger&) = delete;
-  QbonePacketExchanger& operator=(const QbonePacketExchanger&) = delete;
-
-  QbonePacketExchanger(QbonePacketExchanger&&) = delete;
-  QbonePacketExchanger& operator=(QbonePacketExchanger&&) = delete;
-
-  ~QbonePacketExchanger() = default;
-
-  // Returns true if there may be more packets to read.
-  // Implementations handles the actual raw read and delivers the packet to
-  // qbone_client.
-  bool ReadAndDeliverPacket(QboneClientInterface* qbone_client);
-
-  // From QbonePacketWriter.
-  // Writes a packet to the local network. If the write would be blocked, the
-  // packet will be queued if the queue is smaller than max_pending_packets_.
-  void WritePacketToNetwork(const char* packet, size_t size) override;
-
-  // The caller signifies that the local network is no longer blocked.
-  void SetWritable();
-
- private:
-  // The actual implementation that reads a packet from the local network.
-  // Returns the packet if one is successfully read. This might nullptr when a)
-  // there is no packet to read, b) the read failed. In the former case, blocked
-  // is set to true. error contains the error message.
-  virtual std::unique_ptr<QuicData> ReadPacket(bool* blocked,
-                                               std::string* error) = 0;
-
-  // The actual implementation that writes a packet to the local network.
-  // Returns true if the write succeeds. blocked will be set to true if the
-  // write failure is caused by the local network being blocked. error contains
-  // the error message.
-  virtual bool WritePacket(const char* packet,
-                           size_t size,
-                           bool* blocked,
-                           std::string* error) = 0;
-
-  std::list<std::unique_ptr<QuicData>> packet_queue_;
-
-  Visitor* visitor_;
-
-  // The maximum number of packets that could be queued up when writing to local
-  // network is blocked.
-  size_t max_pending_packets_;
-
-  bool write_blocked_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
diff --git a/quic/qbone/qbone_packet_exchanger_test.cc b/quic/qbone/qbone_packet_exchanger_test.cc
deleted file mode 100644
index 5db8753..0000000
--- a/quic/qbone/qbone_packet_exchanger_test.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_packet_exchanger.h"
-
-#include <utility>
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/mock_qbone_client.h"
-
-namespace quic {
-namespace {
-
-using ::testing::StrEq;
-using ::testing::StrictMock;
-
-const size_t kMaxPendingPackets = 2;
-
-class MockVisitor : public QbonePacketExchanger::Visitor {
- public:
-  MOCK_METHOD(void, OnReadError, (const std::string&), (override));
-  MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
-};
-
-class FakeQbonePacketExchanger : public QbonePacketExchanger {
- public:
-  using QbonePacketExchanger::QbonePacketExchanger;
-
-  // Adds a packet to the end of list of packets to be returned by ReadPacket.
-  // When the list is empty, ReadPacket returns nullptr to signify error as
-  // defined by QbonePacketExchanger. If SetReadError is not called or called
-  // with empty error string, ReadPacket sets blocked to true.
-  void AddPacketToBeRead(std::unique_ptr<QuicData> packet) {
-    packets_to_be_read_.push_back(std::move(packet));
-  }
-
-  // Sets the error to be returned by ReadPacket when the list of packets is
-  // empty. If error is empty string, blocked is set by ReadPacket.
-  void SetReadError(const std::string& error) { read_error_ = error; }
-
-  // Force WritePacket to fail with the given status. WritePacket returns true
-  // when blocked == true and error is empty.
-  void ForceWriteFailure(bool blocked, const std::string& error) {
-    write_blocked_ = blocked;
-    write_error_ = error;
-  }
-
-  // Packets that have been successfully written by WritePacket.
-  const std::vector<std::string>& packets_written() const {
-    return packets_written_;
-  }
-
- private:
-  // Implements QbonePacketExchanger::ReadPacket.
-  std::unique_ptr<QuicData> ReadPacket(bool* blocked,
-                                       std::string* error) override {
-    *blocked = false;
-
-    if (packets_to_be_read_.empty()) {
-      *blocked = read_error_.empty();
-      *error = read_error_;
-      return nullptr;
-    }
-
-    std::unique_ptr<QuicData> packet = std::move(packets_to_be_read_.front());
-    packets_to_be_read_.pop_front();
-    return packet;
-  }
-
-  // Implements QbonePacketExchanger::WritePacket.
-  bool WritePacket(const char* packet,
-                   size_t size,
-                   bool* blocked,
-                   std::string* error) override {
-    *blocked = false;
-
-    if (write_blocked_ || !write_error_.empty()) {
-      *blocked = write_blocked_;
-      *error = write_error_;
-      return false;
-    }
-
-    packets_written_.push_back(std::string(packet, size));
-    return true;
-  }
-
-  std::string read_error_;
-  std::list<std::unique_ptr<QuicData>> packets_to_be_read_;
-
-  std::string write_error_;
-  bool write_blocked_ = false;
-  std::vector<std::string> packets_written_;
-};
-
-TEST(QbonePacketExchangerTest,
-     ReadAndDeliverPacketDeliversPacketToQboneClient) {
-  StrictMock<MockVisitor> visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  StrictMock<MockQboneClient> client;
-
-  std::string packet = "data";
-  exchanger.AddPacketToBeRead(
-      std::make_unique<QuicData>(packet.data(), packet.length()));
-  EXPECT_CALL(client, ProcessPacketFromNetwork(StrEq("data")));
-
-  EXPECT_TRUE(exchanger.ReadAndDeliverPacket(&client));
-}
-
-TEST(QbonePacketExchangerTest,
-     ReadAndDeliverPacketNotifiesVisitorOnReadFailure) {
-  MockVisitor visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  MockQboneClient client;
-
-  // Force read error.
-  std::string io_error = "I/O error";
-  exchanger.SetReadError(io_error);
-  EXPECT_CALL(visitor, OnReadError(StrEq(io_error))).Times(1);
-
-  EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
-}
-
-TEST(QbonePacketExchangerTest,
-     ReadAndDeliverPacketDoesNotNotifyVisitorOnBlockedIO) {
-  MockVisitor visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  MockQboneClient client;
-
-  // No more packets to read.
-  EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
-}
-
-TEST(QbonePacketExchangerTest,
-     WritePacketToNetworkWritesDirectlyToNetworkWhenNotBlocked) {
-  MockVisitor visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  MockQboneClient client;
-
-  std::string packet = "data";
-  exchanger.WritePacketToNetwork(packet.data(), packet.length());
-
-  ASSERT_EQ(exchanger.packets_written().size(), 1);
-  EXPECT_THAT(exchanger.packets_written()[0], StrEq(packet));
-}
-
-TEST(QbonePacketExchangerTest,
-     WritePacketToNetworkQueuesPacketsAndProcessThemLater) {
-  MockVisitor visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  MockQboneClient client;
-
-  // Force write to be blocked so that packets are queued.
-  exchanger.ForceWriteFailure(true, "");
-  std::vector<std::string> packets = {"packet0", "packet1"};
-  for (int i = 0; i < packets.size(); i++) {
-    exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
-  }
-
-  // Nothing should have been written because of blockage.
-  ASSERT_TRUE(exchanger.packets_written().empty());
-
-  // Remove blockage and start proccessing queued packets.
-  exchanger.ForceWriteFailure(false, "");
-  exchanger.SetWritable();
-
-  // Queued packets are processed.
-  ASSERT_EQ(exchanger.packets_written().size(), 2);
-  for (int i = 0; i < packets.size(); i++) {
-    EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
-  }
-}
-
-TEST(QbonePacketExchangerTest,
-     SetWritableContinuesProcessingPacketIfPreviousCallBlocked) {
-  MockVisitor visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  MockQboneClient client;
-
-  // Force write to be blocked so that packets are queued.
-  exchanger.ForceWriteFailure(true, "");
-  std::vector<std::string> packets = {"packet0", "packet1"};
-  for (int i = 0; i < packets.size(); i++) {
-    exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
-  }
-
-  // Nothing should have been written because of blockage.
-  ASSERT_TRUE(exchanger.packets_written().empty());
-
-  // Start processing packets, but since writes are still blocked, nothing
-  // should have been written.
-  exchanger.SetWritable();
-  ASSERT_TRUE(exchanger.packets_written().empty());
-
-  // Remove blockage and start processing packets again.
-  exchanger.ForceWriteFailure(false, "");
-  exchanger.SetWritable();
-
-  ASSERT_EQ(exchanger.packets_written().size(), 2);
-  for (int i = 0; i < packets.size(); i++) {
-    EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
-  }
-}
-
-TEST(QbonePacketExchangerTest, WritePacketToNetworkDropsPacketIfQueueIfFull) {
-  std::vector<std::string> packets = {"packet0", "packet1", "packet2"};
-  size_t queue_size = packets.size() - 1;
-  MockVisitor visitor;
-  // exchanger has smaller queue than number of packets.
-  FakeQbonePacketExchanger exchanger(&visitor, queue_size);
-  MockQboneClient client;
-
-  exchanger.ForceWriteFailure(true, "");
-  for (int i = 0; i < packets.size(); i++) {
-    exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
-  }
-
-  // Blocked writes cause packets to be queued or dropped.
-  ASSERT_TRUE(exchanger.packets_written().empty());
-
-  exchanger.ForceWriteFailure(false, "");
-  exchanger.SetWritable();
-
-  ASSERT_EQ(exchanger.packets_written().size(), queue_size);
-  for (int i = 0; i < queue_size; i++) {
-    EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
-  }
-}
-
-TEST(QbonePacketExchangerTest, WriteErrorsGetNotified) {
-  MockVisitor visitor;
-  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
-  MockQboneClient client;
-  std::string packet = "data";
-
-  // Write error is delivered to visitor during WritePacketToNetwork.
-  std::string io_error = "I/O error";
-  exchanger.ForceWriteFailure(false, io_error);
-  EXPECT_CALL(visitor, OnWriteError(StrEq(io_error))).Times(1);
-  exchanger.WritePacketToNetwork(packet.data(), packet.length());
-  ASSERT_TRUE(exchanger.packets_written().empty());
-
-  // Write error is delivered to visitor during SetWritable.
-  exchanger.ForceWriteFailure(true, "");
-  exchanger.WritePacketToNetwork(packet.data(), packet.length());
-
-  std::string sys_error = "sys error";
-  exchanger.ForceWriteFailure(false, sys_error);
-  EXPECT_CALL(visitor, OnWriteError(StrEq(sys_error))).Times(1);
-  exchanger.SetWritable();
-  ASSERT_TRUE(exchanger.packets_written().empty());
-}
-
-TEST(QbonePacketExchangerTest, NullVisitorDoesntCrash) {
-  FakeQbonePacketExchanger exchanger(nullptr, kMaxPendingPackets);
-  MockQboneClient client;
-  std::string packet = "data";
-
-  // Force read error.
-  std::string io_error = "I/O error";
-  exchanger.SetReadError(io_error);
-  EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
-
-  // Force write error
-  exchanger.ForceWriteFailure(false, io_error);
-  exchanger.WritePacketToNetwork(packet.data(), packet.length());
-  EXPECT_TRUE(exchanger.packets_written().empty());
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/qbone_packet_processor.cc b/quic/qbone/qbone_packet_processor.cc
deleted file mode 100644
index e2848ed..0000000
--- a/quic/qbone/qbone_packet_processor.cc
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_packet_processor.h"
-
-#include <cstring>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_ip_address_family.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/platform/internet_checksum.h"
-#include "quic/qbone/platform/tcp_packet.h"
-#include "common/quiche_endian.h"
-
-namespace {
-
-constexpr size_t kIPv6AddressSize = 16;
-constexpr size_t kIPv6MinPacketSize = 1280;
-constexpr size_t kIcmpTtl = 64;
-constexpr size_t kICMPv6DestinationUnreachableDueToSourcePolicy = 5;
-
-}  // namespace
-
-namespace quic {
-
-const QuicIpAddress QbonePacketProcessor::kInvalidIpAddress =
-    QuicIpAddress::Any6();
-
-QbonePacketProcessor::QbonePacketProcessor(QuicIpAddress self_ip,
-                                           QuicIpAddress client_ip,
-                                           size_t client_ip_subnet_length,
-                                           OutputInterface* output,
-                                           StatsInterface* stats)
-    : client_ip_(client_ip),
-      output_(output),
-      stats_(stats),
-      filter_(new Filter) {
-  memcpy(self_ip_.s6_addr, self_ip.ToPackedString().data(), kIPv6AddressSize);
-  QUICHE_DCHECK_LE(client_ip_subnet_length, kIPv6AddressSize * 8);
-  client_ip_subnet_length_ = client_ip_subnet_length;
-
-  QUICHE_DCHECK(IpAddressFamily::IP_V6 == self_ip.address_family());
-  QUICHE_DCHECK(IpAddressFamily::IP_V6 == client_ip.address_family());
-  QUICHE_DCHECK(self_ip != kInvalidIpAddress);
-}
-
-QbonePacketProcessor::OutputInterface::~OutputInterface() {}
-QbonePacketProcessor::StatsInterface::~StatsInterface() {}
-QbonePacketProcessor::Filter::~Filter() {}
-
-QbonePacketProcessor::ProcessingResult
-QbonePacketProcessor::Filter::FilterPacket(Direction direction,
-                                           absl::string_view full_packet,
-                                           absl::string_view payload,
-                                           icmp6_hdr* icmp_header,
-                                           OutputInterface* output) {
-  return ProcessingResult::OK;
-}
-
-void QbonePacketProcessor::ProcessPacket(std::string* packet,
-                                         Direction direction) {
-  if (QUIC_PREDICT_FALSE(!IsValid())) {
-    QUIC_BUG(quic_bug_11024_1)
-        << "QuicPacketProcessor is invoked in an invalid state.";
-    stats_->OnPacketDroppedSilently(direction);
-    return;
-  }
-
-  uint8_t transport_protocol;
-  char* transport_data;
-  icmp6_hdr icmp_header;
-  memset(&icmp_header, 0, sizeof(icmp_header));
-  ProcessingResult result = ProcessIPv6HeaderAndFilter(
-      packet, direction, &transport_protocol, &transport_data, &icmp_header);
-
-  switch (result) {
-    case ProcessingResult::OK:
-      switch (direction) {
-        case Direction::FROM_OFF_NETWORK:
-          output_->SendPacketToNetwork(*packet);
-          break;
-        case Direction::FROM_NETWORK:
-          output_->SendPacketToClient(*packet);
-          break;
-      }
-      stats_->OnPacketForwarded(direction);
-      break;
-    case ProcessingResult::SILENT_DROP:
-      stats_->OnPacketDroppedSilently(direction);
-      break;
-    case ProcessingResult::DEFER:
-      stats_->OnPacketDeferred(direction);
-      break;
-    case ProcessingResult::ICMP:
-      SendIcmpResponse(&icmp_header, *packet, direction);
-      stats_->OnPacketDroppedWithIcmp(direction);
-      break;
-    case ProcessingResult::ICMP_AND_TCP_RESET:
-      SendIcmpResponse(&icmp_header, *packet, direction);
-      stats_->OnPacketDroppedWithIcmp(direction);
-      SendTcpReset(*packet, direction);
-      stats_->OnPacketDroppedWithTcpReset(direction);
-      break;
-    case ProcessingResult::TCP_RESET:
-      SendTcpReset(*packet, direction);
-      stats_->OnPacketDroppedWithTcpReset(direction);
-      break;
-  }
-}
-
-QbonePacketProcessor::ProcessingResult
-QbonePacketProcessor::ProcessIPv6HeaderAndFilter(std::string* packet,
-                                                 Direction direction,
-                                                 uint8_t* transport_protocol,
-                                                 char** transport_data,
-                                                 icmp6_hdr* icmp_header) {
-  ProcessingResult result = ProcessIPv6Header(
-      packet, direction, transport_protocol, transport_data, icmp_header);
-
-  if (result == ProcessingResult::OK) {
-    char* packet_data = &*packet->begin();
-    size_t header_size = *transport_data - packet_data;
-    // Sanity-check the bounds.
-    if (packet_data >= *transport_data || header_size > packet->size() ||
-        header_size < kIPv6HeaderSize) {
-      QUIC_BUG(quic_bug_11024_2)
-          << "Invalid pointers encountered in "
-             "QbonePacketProcessor::ProcessPacket.  Dropping the packet";
-      return ProcessingResult::SILENT_DROP;
-    }
-
-    result = filter_->FilterPacket(
-        direction, *packet,
-        absl::string_view(*transport_data, packet->size() - header_size),
-        icmp_header, output_);
-  }
-
-  // Do not send ICMP error messages in response to ICMP errors.
-  if (result == ProcessingResult::ICMP) {
-    const uint8_t* header = reinterpret_cast<const uint8_t*>(packet->data());
-
-    constexpr size_t kIPv6NextHeaderOffset = 6;
-    constexpr size_t kIcmpMessageTypeOffset = kIPv6HeaderSize + 0;
-    constexpr size_t kIcmpMessageTypeMaxError = 127;
-    if (
-        // Check size.
-        packet->size() >= (kIPv6HeaderSize + kICMPv6HeaderSize) &&
-        // Check that the packet is in fact ICMP.
-        header[kIPv6NextHeaderOffset] == IPPROTO_ICMPV6 &&
-        // Check that ICMP message type is an error.
-        header[kIcmpMessageTypeOffset] < kIcmpMessageTypeMaxError) {
-      result = ProcessingResult::SILENT_DROP;
-    }
-  }
-
-  return result;
-}
-
-QbonePacketProcessor::ProcessingResult QbonePacketProcessor::ProcessIPv6Header(
-    std::string* packet,
-    Direction direction,
-    uint8_t* transport_protocol,
-    char** transport_data,
-    icmp6_hdr* icmp_header) {
-  // Check if the packet is big enough to have IPv6 header.
-  if (packet->size() < kIPv6HeaderSize) {
-    QUIC_DVLOG(1) << "Dropped malformed packet: IPv6 header too short";
-    return ProcessingResult::SILENT_DROP;
-  }
-
-  // Check version field.
-  ip6_hdr* header = reinterpret_cast<ip6_hdr*>(&*packet->begin());
-  if (header->ip6_vfc >> 4 != 6) {
-    QUIC_DVLOG(1) << "Dropped malformed packet: IP version is not IPv6";
-    return ProcessingResult::SILENT_DROP;
-  }
-
-  // Check payload size.
-  const size_t declared_payload_size =
-      quiche::QuicheEndian::NetToHost16(header->ip6_plen);
-  const size_t actual_payload_size = packet->size() - kIPv6HeaderSize;
-  if (declared_payload_size != actual_payload_size) {
-    QUIC_DVLOG(1)
-        << "Dropped malformed packet: incorrect packet length specified";
-    return ProcessingResult::SILENT_DROP;
-  }
-
-  // Check that the address of the client is in the packet.
-  QuicIpAddress address_to_check;
-  uint8_t address_reject_code;
-  bool ip_parse_result;
-  switch (direction) {
-    case Direction::FROM_OFF_NETWORK:
-      // Expect the source IP to match the client.
-      ip_parse_result = address_to_check.FromPackedString(
-          reinterpret_cast<const char*>(&header->ip6_src),
-          sizeof(header->ip6_src));
-      address_reject_code = kICMPv6DestinationUnreachableDueToSourcePolicy;
-      break;
-    case Direction::FROM_NETWORK:
-      // Expect the destination IP to match the client.
-      ip_parse_result = address_to_check.FromPackedString(
-          reinterpret_cast<const char*>(&header->ip6_dst),
-          sizeof(header->ip6_src));
-      address_reject_code = ICMP6_DST_UNREACH_NOROUTE;
-      break;
-  }
-  QUICHE_DCHECK(ip_parse_result);
-  if (!client_ip_.InSameSubnet(address_to_check, client_ip_subnet_length_)) {
-    QUIC_DVLOG(1)
-        << "Dropped packet: source/destination address is not client's";
-    icmp_header->icmp6_type = ICMP6_DST_UNREACH;
-    icmp_header->icmp6_code = address_reject_code;
-    return ProcessingResult::ICMP;
-  }
-
-  // Check and decrement TTL.
-  if (header->ip6_hops <= 1) {
-    icmp_header->icmp6_type = ICMP6_TIME_EXCEEDED;
-    icmp_header->icmp6_code = ICMP6_TIME_EXCEED_TRANSIT;
-    return ProcessingResult::ICMP;
-  }
-  header->ip6_hops--;
-
-  // Check and extract IP headers.
-  switch (header->ip6_nxt) {
-    case IPPROTO_TCP:
-    case IPPROTO_UDP:
-    case IPPROTO_ICMPV6:
-      *transport_protocol = header->ip6_nxt;
-      *transport_data = (&*packet->begin()) + kIPv6HeaderSize;
-      break;
-    default:
-      icmp_header->icmp6_type = ICMP6_PARAM_PROB;
-      icmp_header->icmp6_code = ICMP6_PARAMPROB_NEXTHEADER;
-      return ProcessingResult::ICMP;
-  }
-
-  return ProcessingResult::OK;
-}
-
-void QbonePacketProcessor::SendIcmpResponse(icmp6_hdr* icmp_header,
-                                            absl::string_view original_packet,
-                                            Direction original_direction) {
-  in6_addr dst;
-  // TODO(b/70339814): ensure this is actually a unicast address.
-  memcpy(dst.s6_addr, &original_packet[8], kIPv6AddressSize);
-
-  CreateIcmpPacket(self_ip_, dst, *icmp_header, original_packet,
-                   [this, original_direction](absl::string_view packet) {
-                     SendResponse(original_direction, packet);
-                   });
-}
-
-void QbonePacketProcessor::SendTcpReset(absl::string_view original_packet,
-                                        Direction original_direction) {
-  CreateTcpResetPacket(original_packet,
-                       [this, original_direction](absl::string_view packet) {
-                         SendResponse(original_direction, packet);
-                       });
-}
-
-void QbonePacketProcessor::SendResponse(Direction original_direction,
-                                        absl::string_view packet) {
-  switch (original_direction) {
-    case Direction::FROM_OFF_NETWORK:
-      output_->SendPacketToClient(packet);
-      break;
-    case Direction::FROM_NETWORK:
-      output_->SendPacketToNetwork(packet);
-      break;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_packet_processor.h b/quic/qbone/qbone_packet_processor.h
deleted file mode 100644
index 551e186..0000000
--- a/quic/qbone/qbone_packet_processor.h
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_ip_address.h"
-
-namespace quic {
-
-enum : size_t {
-  kIPv6HeaderSize = 40,
-  kICMPv6HeaderSize = sizeof(icmp6_hdr),
-  kTotalICMPv6HeaderSize = kIPv6HeaderSize + kICMPv6HeaderSize,
-};
-
-// QBONE packet processor accepts packets destined in either direction
-// (client-to-network or network-to-client).  It inspects them and makes
-// decisions on whether they should be forwarded or dropped, replying with ICMP
-// messages as appropriate.
-class QbonePacketProcessor {
- public:
-  enum class Direction {
-    // Packet is going from the QBONE client into the network behind the QBONE.
-    FROM_OFF_NETWORK = 0,
-    // Packet is going from the network begin QBONE to the client.
-    FROM_NETWORK = 1
-  };
-
-  enum class ProcessingResult {
-    OK = 0,
-    SILENT_DROP = 1,
-    ICMP = 2,
-    // Equivalent to |SILENT_DROP| at the moment, but indicates that the
-    // downstream filter has buffered the packet and deferred its processing.
-    // The packet may be emitted at a later time.
-    DEFER = 3,
-    // In addition to sending an ICMP message, also send a TCP RST. This option
-    // requires the incoming packet to have been a valid TCP packet, as a TCP
-    // RST requires information from the current connection state to be
-    // well-formed.
-    ICMP_AND_TCP_RESET = 4,
-    // Send a TCP RST.
-    TCP_RESET = 5,
-  };
-
-  class OutputInterface {
-   public:
-    virtual ~OutputInterface();
-
-    virtual void SendPacketToClient(absl::string_view packet) = 0;
-    virtual void SendPacketToNetwork(absl::string_view packet) = 0;
-  };
-
-  class StatsInterface {
-   public:
-    virtual ~StatsInterface();
-
-    virtual void OnPacketForwarded(Direction direction) = 0;
-    virtual void OnPacketDroppedSilently(Direction direction) = 0;
-    virtual void OnPacketDroppedWithIcmp(Direction direction) = 0;
-    virtual void OnPacketDroppedWithTcpReset(Direction direction) = 0;
-    virtual void OnPacketDeferred(Direction direction) = 0;
-  };
-
-  // Allows to implement a custom packet filter on top of the filtering done by
-  // the packet processor itself.
-  class Filter {
-   public:
-    virtual ~Filter();
-    // The main interface function.  The following arguments are supplied:
-    // - |direction|, to indicate direction of the packet.
-    // - |full_packet|, which includes the IPv6 header and possibly the IPv6
-    //   options that were understood by the processor.
-    // - |payload|, the contents of the IPv6 packet, i.e. a TCP, a UDP or an
-    //   ICMP packet.
-    // - |icmp_header|, an output argument which allows the filter to specify
-    //   the ICMP message with which the packet is to be rejected.
-    // The method is called only on packets which were already verified as valid
-    // IPv6 packets.
-    //
-    // The implementer of this method has four options to return:
-    // - OK will cause the filter to pass the packet through
-    // - SILENT_DROP will cause the filter to drop the packet silently
-    // - ICMP will cause the filter to drop the packet and send an ICMP
-    //   response.
-    // - DEFER will cause the packet to be not forwarded; the filter is
-    //   responsible for sending (or not sending) it later using |output|.
-    //
-    // Note that |output| should not be used except in the DEFER case, as the
-    // processor will perform the necessary writes itself.
-    virtual ProcessingResult FilterPacket(Direction direction,
-                                          absl::string_view full_packet,
-                                          absl::string_view payload,
-                                          icmp6_hdr* icmp_header,
-                                          OutputInterface* output);
-
-   protected:
-    // Helper methods that allow to easily extract information that is required
-    // for filtering from the |ipv6_header| argument.  All of those assume that
-    // the header is of valid size, which is true for everything passed into
-    // FilterPacket().
-    uint8_t TransportProtocolFromHeader(absl::string_view ipv6_header) {
-      return ipv6_header[6];
-    }
-    QuicIpAddress SourceIpFromHeader(absl::string_view ipv6_header) {
-      QuicIpAddress address;
-      address.FromPackedString(&ipv6_header[8],
-                               QuicIpAddress::kIPv6AddressSize);
-      return address;
-    }
-    QuicIpAddress DestinationIpFromHeader(absl::string_view ipv6_header) {
-      QuicIpAddress address;
-      address.FromPackedString(&ipv6_header[24],
-                               QuicIpAddress::kIPv6AddressSize);
-      return address;
-    }
-  };
-
-  // |self_ip| is the IP address from which the processor will originate ICMP
-  // messages.  |client_ip| is the expected IP address of the client, used for
-  // packet validation.
-  //
-  // |output| and |stats| are the visitor interfaces used by the processor.
-  // |output| gets notified whenever the processor decides to send a packet, and
-  // |stats| gets notified about any decisions that processor makes, without a
-  // reference to which packet that decision was made about.
-  QbonePacketProcessor(QuicIpAddress self_ip,
-                       QuicIpAddress client_ip,
-                       size_t client_ip_subnet_length,
-                       OutputInterface* output,
-                       StatsInterface* stats);
-  QbonePacketProcessor(const QbonePacketProcessor&) = delete;
-  QbonePacketProcessor& operator=(const QbonePacketProcessor&) = delete;
-
-  // Accepts an IPv6 packet and handles it accordingly by either forwarding it,
-  // replying with an ICMP packet or silently dropping it.  |packet| will be
-  // modified in the process, by having the TTL field decreased.
-  void ProcessPacket(std::string* packet, Direction direction);
-
-  void set_filter(std::unique_ptr<Filter> filter) {
-    filter_ = std::move(filter);
-  }
-
-  void set_client_ip(QuicIpAddress client_ip) { client_ip_ = client_ip; }
-  void set_client_ip_subnet_length(size_t client_ip_subnet_length) {
-    client_ip_subnet_length_ = client_ip_subnet_length;
-  }
-
-  static const QuicIpAddress kInvalidIpAddress;
-
- protected:
-  // Processes the header and returns what should be done with the packet.
-  // After that, calls an external packet filter if registered.  TTL of the
-  // packet may be decreased in the process.
-  ProcessingResult ProcessIPv6HeaderAndFilter(std::string* packet,
-                                              Direction direction,
-                                              uint8_t* transport_protocol,
-                                              char** transport_data,
-                                              icmp6_hdr* icmp_header);
-
-  void SendIcmpResponse(icmp6_hdr* icmp_header,
-                        absl::string_view original_packet,
-                        Direction original_direction);
-
-  void SendTcpReset(absl::string_view original_packet,
-                    Direction original_direction);
-
-  bool IsValid() const { return client_ip_ != kInvalidIpAddress; }
-
-  // IP address of the server.  Used to send ICMP messages.
-  in6_addr self_ip_;
-  // IP address range of the VPN client.
-  QuicIpAddress client_ip_;
-  size_t client_ip_subnet_length_;
-
-  OutputInterface* output_;
-  StatsInterface* stats_;
-  std::unique_ptr<Filter> filter_;
-
- private:
-  // Performs basic sanity and permission checks on the packet, and decreases
-  // the TTL.
-  ProcessingResult ProcessIPv6Header(std::string* packet,
-                                     Direction direction,
-                                     uint8_t* transport_protocol,
-                                     char** transport_data,
-                                     icmp6_hdr* icmp_header);
-
-  void SendResponse(Direction original_direction, absl::string_view packet);
-};
-
-}  // namespace quic
-#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
diff --git a/quic/qbone/qbone_packet_processor_test.cc b/quic/qbone/qbone_packet_processor_test.cc
deleted file mode 100644
index d79400c..0000000
--- a/quic/qbone/qbone_packet_processor_test.cc
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_packet_processor.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-
-namespace quic {
-namespace {
-
-using Direction = QbonePacketProcessor::Direction;
-using ProcessingResult = QbonePacketProcessor::ProcessingResult;
-using OutputInterface = QbonePacketProcessor::OutputInterface;
-using ::testing::_;
-using ::testing::Return;
-
-// clang-format off
-static const char kReferenceClientPacketData[] = {
-    // IPv6 with zero TOS and flow label.
-    0x60, 0x00, 0x00, 0x00,
-    // Payload size is 8 bytes.
-    0x00, 0x08,
-    // Next header is UDP
-    17,
-    // TTL is 50.
-    50,
-    // IP address of the sender is fd00:0:0:1::1
-    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // IP address of the receiver is fd00:0:0:5::1
-    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // Source port 12345
-    0x30, 0x39,
-    // Destination port 443
-    0x01, 0xbb,
-    // UDP content length is zero
-    0x00, 0x00,
-    // Checksum is not actually checked in any of the tests, so we leave it as
-    // zero
-    0x00, 0x00,
-};
-
-static const char kReferenceNetworkPacketData[] = {
-    // IPv6 with zero TOS and flow label.
-    0x60, 0x00, 0x00, 0x00,
-    // Payload size is 8 bytes.
-    0x00, 0x08,
-    // Next header is UDP
-    17,
-    // TTL is 50.
-    50,
-    // IP address of the sender is fd00:0:0:5::1
-    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // IP address of the receiver is fd00:0:0:1::1
-    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // Source port 443
-    0x01, 0xbb,
-    // Destination port 12345
-    0x30, 0x39,
-    // UDP content length is zero
-    0x00, 0x00,
-    // Checksum is not actually checked in any of the tests, so we leave it as
-    // zero
-    0x00, 0x00,
-};
-
-static const char kReferenceClientSubnetPacketData[] = {
-    // IPv6 with zero TOS and flow label.
-    0x60, 0x00, 0x00, 0x00,
-    // Payload size is 8 bytes.
-    0x00, 0x08,
-    // Next header is UDP
-    17,
-    // TTL is 50.
-    50,
-    // IP address of the sender is fd00:0:0:2::1, which is within the /62 of the
-    // client.
-    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // IP address of the receiver is fd00:0:0:5::1
-    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    // Source port 12345
-    0x30, 0x39,
-    // Destination port 443
-    0x01, 0xbb,
-    // UDP content length is zero
-    0x00, 0x00,
-    // Checksum is not actually checked in any of the tests, so we leave it as
-    // zero
-    0x00, 0x00,
-};
-
-// clang-format on
-
-static const absl::string_view kReferenceClientPacket(
-    kReferenceClientPacketData,
-    arraysize(kReferenceClientPacketData));
-
-static const absl::string_view kReferenceNetworkPacket(
-    kReferenceNetworkPacketData,
-    arraysize(kReferenceNetworkPacketData));
-
-static const absl::string_view kReferenceClientSubnetPacket(
-    kReferenceClientSubnetPacketData,
-    arraysize(kReferenceClientSubnetPacketData));
-
-MATCHER_P(IsIcmpMessage,
-          icmp_type,
-          "Checks whether the argument is an ICMP message of supplied type") {
-  if (arg.size() < kTotalICMPv6HeaderSize) {
-    return false;
-  }
-
-  return arg[40] == icmp_type;
-}
-
-class MockPacketFilter : public QbonePacketProcessor::Filter {
- public:
-  MOCK_METHOD(ProcessingResult,
-              FilterPacket,
-              (Direction,
-               absl::string_view,
-               absl::string_view,
-               icmp6_hdr*,
-               OutputInterface*),
-              (override));
-};
-
-class QbonePacketProcessorTest : public QuicTest {
- protected:
-  QbonePacketProcessorTest() {
-    QUICHE_CHECK(client_ip_.FromString("fd00:0:0:1::1"));
-    QUICHE_CHECK(self_ip_.FromString("fd00:0:0:4::1"));
-    QUICHE_CHECK(network_ip_.FromString("fd00:0:0:5::1"));
-
-    processor_ = std::make_unique<QbonePacketProcessor>(
-        self_ip_, client_ip_, /*client_ip_subnet_length=*/62, &output_,
-        &stats_);
-  }
-
-  void SendPacketFromClient(absl::string_view packet) {
-    std::string packet_buffer(packet.data(), packet.size());
-    processor_->ProcessPacket(&packet_buffer, Direction::FROM_OFF_NETWORK);
-  }
-
-  void SendPacketFromNetwork(absl::string_view packet) {
-    std::string packet_buffer(packet.data(), packet.size());
-    processor_->ProcessPacket(&packet_buffer, Direction::FROM_NETWORK);
-  }
-
-  QuicIpAddress client_ip_;
-  QuicIpAddress self_ip_;
-  QuicIpAddress network_ip_;
-
-  std::unique_ptr<QbonePacketProcessor> processor_;
-  testing::StrictMock<MockPacketProcessorOutput> output_;
-  testing::StrictMock<MockPacketProcessorStats> stats_;
-};
-
-TEST_F(QbonePacketProcessorTest, EmptyPacket) {
-  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
-  SendPacketFromClient("");
-
-  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
-  SendPacketFromNetwork("");
-}
-
-TEST_F(QbonePacketProcessorTest, RandomGarbage) {
-  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
-  SendPacketFromClient(std::string(1280, 'a'));
-
-  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
-  SendPacketFromNetwork(std::string(1280, 'a'));
-}
-
-TEST_F(QbonePacketProcessorTest, RandomGarbageWithCorrectLengthFields) {
-  std::string packet(40, 'a');
-  packet[4] = 0;
-  packet[5] = 0;
-
-  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
-  EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
-  SendPacketFromClient(packet);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromClient) {
-  EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
-  EXPECT_CALL(output_, SendPacketToNetwork(_));
-  SendPacketFromClient(kReferenceClientPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromClientSubnet) {
-  EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
-  EXPECT_CALL(output_, SendPacketToNetwork(_));
-  SendPacketFromClient(kReferenceClientSubnetPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromNetwork) {
-  EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_NETWORK));
-  EXPECT_CALL(output_, SendPacketToClient(_));
-  SendPacketFromNetwork(kReferenceNetworkPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, GoodPacketFromNetworkWrongDirection) {
-  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
-  EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
-  SendPacketFromClient(kReferenceNetworkPacket);
-}
-
-TEST_F(QbonePacketProcessorTest, TtlExpired) {
-  std::string packet(kReferenceNetworkPacket);
-  packet[7] = 1;
-
-  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
-  EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_TIME_EXCEEDED)));
-  SendPacketFromNetwork(packet);
-}
-
-TEST_F(QbonePacketProcessorTest, UnknownProtocol) {
-  std::string packet(kReferenceNetworkPacket);
-  packet[6] = IPPROTO_SCTP;
-
-  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
-  EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_PARAM_PROB)));
-  SendPacketFromNetwork(packet);
-}
-
-TEST_F(QbonePacketProcessorTest, FilterFromClient) {
-  auto filter = std::make_unique<MockPacketFilter>();
-  EXPECT_CALL(*filter, FilterPacket(_, _, _, _, _))
-      .WillRepeatedly(Return(ProcessingResult::SILENT_DROP));
-  processor_->set_filter(std::move(filter));
-
-  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
-  SendPacketFromClient(kReferenceClientPacket);
-}
-
-class TestFilter : public QbonePacketProcessor::Filter {
- public:
-  TestFilter(QuicIpAddress client_ip, QuicIpAddress network_ip)
-      : client_ip_(client_ip), network_ip_(network_ip) {}
-  ProcessingResult FilterPacket(Direction direction,
-                                absl::string_view full_packet,
-                                absl::string_view payload,
-                                icmp6_hdr* icmp_header,
-                                OutputInterface* output) override {
-    EXPECT_EQ(kIPv6HeaderSize, full_packet.size() - payload.size());
-    EXPECT_EQ(IPPROTO_UDP, TransportProtocolFromHeader(full_packet));
-    EXPECT_EQ(client_ip_, SourceIpFromHeader(full_packet));
-    EXPECT_EQ(network_ip_, DestinationIpFromHeader(full_packet));
-
-    called_++;
-    return ProcessingResult::SILENT_DROP;
-  }
-
-  int called() const { return called_; }
-
- private:
-  int called_ = 0;
-
-  QuicIpAddress client_ip_;
-  QuicIpAddress network_ip_;
-};
-
-// Verify that the parameters are passed correctly into the filter, and that the
-// helper functions of the filter class work.
-TEST_F(QbonePacketProcessorTest, FilterHelperFunctions) {
-  auto filter_owned = std::make_unique<TestFilter>(client_ip_, network_ip_);
-  TestFilter* filter = filter_owned.get();
-  processor_->set_filter(std::move(filter_owned));
-
-  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
-  SendPacketFromClient(kReferenceClientPacket);
-  ASSERT_EQ(1, filter->called());
-}
-
-}  // namespace
-}  // namespace quic
diff --git a/quic/qbone/qbone_packet_processor_test_tools.cc b/quic/qbone/qbone_packet_processor_test_tools.cc
deleted file mode 100644
index 5df158d..0000000
--- a/quic/qbone/qbone_packet_processor_test_tools.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-
-#include <netinet/ip6.h>
-
-namespace quic {
-
-std::string PrependIPv6HeaderForTest(const std::string& body, int hops) {
-  ip6_hdr header;
-  memset(&header, 0, sizeof(header));
-
-  header.ip6_vfc = 6 << 4;
-  header.ip6_plen = htons(body.size());
-  header.ip6_nxt = IPPROTO_UDP;
-  header.ip6_hops = hops;
-  header.ip6_src = in6addr_loopback;
-  header.ip6_dst = in6addr_loopback;
-
-  std::string packet(sizeof(header) + body.size(), '\0');
-  memcpy(&packet[0], &header, sizeof(header));
-  memcpy(&packet[sizeof(header)], body.data(), body.size());
-  return packet;
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_packet_processor_test_tools.h b/quic/qbone/qbone_packet_processor_test_tools.h
deleted file mode 100644
index e26313b..0000000
--- a/quic/qbone/qbone_packet_processor_test_tools.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
-#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/qbone/qbone_packet_processor.h"
-
-namespace quic {
-
-class MockPacketProcessorOutput : public QbonePacketProcessor::OutputInterface {
- public:
-  MockPacketProcessorOutput() {}
-
-  MOCK_METHOD(void, SendPacketToClient, (absl::string_view), (override));
-  MOCK_METHOD(void, SendPacketToNetwork, (absl::string_view), (override));
-};
-
-class MockPacketProcessorStats : public QbonePacketProcessor::StatsInterface {
- public:
-  MockPacketProcessorStats() {}
-
-  MOCK_METHOD(void,
-              OnPacketForwarded,
-              (QbonePacketProcessor::Direction),
-              (override));
-  MOCK_METHOD(void,
-              OnPacketDroppedSilently,
-              (QbonePacketProcessor::Direction),
-              (override));
-  MOCK_METHOD(void,
-              OnPacketDroppedWithIcmp,
-              (QbonePacketProcessor::Direction),
-              (override));
-  MOCK_METHOD(void,
-              OnPacketDroppedWithTcpReset,
-              (QbonePacketProcessor::Direction),
-              (override));
-  MOCK_METHOD(void,
-              OnPacketDeferred,
-              (QbonePacketProcessor::Direction),
-              (override));
-};
-
-std::string PrependIPv6HeaderForTest(const std::string& body, int hops);
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
diff --git a/quic/qbone/qbone_server_session.cc b/quic/qbone/qbone_server_session.cc
deleted file mode 100644
index bc2d8e5..0000000
--- a/quic/qbone/qbone_server_session.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_server_session.h"
-
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/qbone/qbone_constants.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, qbone_server_defer_control_stream_creation, true,
-    "If true, control stream in QBONE server session is created after "
-    "encryption established.");
-
-namespace quic {
-
-bool QboneCryptoServerStreamHelper::CanAcceptClientHello(
-    const CryptoHandshakeMessage& chlo,
-    const QuicSocketAddress& client_address,
-    const QuicSocketAddress& peer_address,
-    const QuicSocketAddress& self_address,
-    std::string* error_details) const {
-  absl::string_view alpn;
-  chlo.GetStringPiece(quic::kALPN, &alpn);
-  if (alpn != QboneConstants::kQboneAlpn) {
-    *error_details = "ALPN-indicated protocol is not qbone";
-    return false;
-  }
-  return true;
-}
-
-QboneServerSession::QboneServerSession(
-    const quic::ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection,
-    Visitor* owner,
-    const QuicConfig& config,
-    const QuicCryptoServerConfig* quic_crypto_server_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    QbonePacketWriter* writer,
-    QuicIpAddress self_ip,
-    QuicIpAddress client_ip,
-    size_t client_ip_subnet_length,
-    QboneServerControlStream::Handler* handler)
-    : QboneSessionBase(connection, owner, config, supported_versions, writer),
-      processor_(self_ip, client_ip, client_ip_subnet_length, this, this),
-      quic_crypto_server_config_(quic_crypto_server_config),
-      compressed_certs_cache_(compressed_certs_cache),
-      handler_(handler) {}
-
-QboneServerSession::~QboneServerSession() {}
-
-std::unique_ptr<QuicCryptoStream> QboneServerSession::CreateCryptoStream() {
-  return CreateCryptoServerStream(quic_crypto_server_config_,
-                                  compressed_certs_cache_, this,
-                                  &stream_helper_);
-}
-
-void QboneServerSession::CreateControlStream() {
-  if (control_stream_ != nullptr) {
-    return;
-  }
-  // Register the reserved control stream.
-  auto control_stream =
-      std::make_unique<QboneServerControlStream>(this, handler_);
-  control_stream_ = control_stream.get();
-  ActivateStream(std::move(control_stream));
-}
-
-QuicStream* QboneServerSession::CreateControlStreamFromPendingStream(
-    PendingStream* pending) {
-  QUICHE_DCHECK(control_stream_ == nullptr);
-  // Register the reserved control stream.
-  auto control_stream =
-      std::make_unique<QboneServerControlStream>(pending, this, handler_);
-  control_stream_ = control_stream.get();
-  ActivateStream(std::move(control_stream));
-  return control_stream_;
-}
-
-void QboneServerSession::Initialize() {
-  QboneSessionBase::Initialize();
-  if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) {
-    CreateControlStream();
-  }
-}
-
-void QboneServerSession::SetDefaultEncryptionLevel(
-    quic::EncryptionLevel level) {
-  QboneSessionBase::SetDefaultEncryptionLevel(level);
-  if (GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation) &&
-      level == quic::ENCRYPTION_FORWARD_SECURE) {
-    CreateControlStream();
-  }
-}
-
-bool QboneServerSession::SendClientRequest(const QboneClientRequest& request) {
-  if (!control_stream_) {
-    QUIC_BUG(quic_bug_11026_1)
-        << "Cannot send client request before control stream is created.";
-    return false;
-  }
-  return control_stream_->SendRequest(request);
-}
-
-void QboneServerSession::ProcessPacketFromNetwork(absl::string_view packet) {
-  std::string buffer = std::string(packet);
-  processor_.ProcessPacket(&buffer,
-                           QbonePacketProcessor::Direction::FROM_NETWORK);
-}
-
-void QboneServerSession::ProcessPacketFromPeer(absl::string_view packet) {
-  std::string buffer = std::string(packet);
-  processor_.ProcessPacket(&buffer,
-                           QbonePacketProcessor::Direction::FROM_OFF_NETWORK);
-}
-
-void QboneServerSession::SendPacketToClient(absl::string_view packet) {
-  SendPacketToPeer(packet);
-}
-
-void QboneServerSession::SendPacketToNetwork(absl::string_view packet) {
-  QUICHE_DCHECK(writer_ != nullptr);
-  writer_->WritePacketToNetwork(packet.data(), packet.size());
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_server_session.h b/quic/qbone/qbone_server_session.h
deleted file mode 100644
index d206e4d..0000000
--- a/quic/qbone/qbone_server_session.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
-#define QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/qbone/qbone_control.pb.h"
-#include "quic/qbone/qbone_control_stream.h"
-#include "quic/qbone/qbone_packet_processor.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/qbone/qbone_session_base.h"
-
-namespace quic {
-
-// A helper class is used by the QuicCryptoServerStream.
-class QboneCryptoServerStreamHelper
-    : public QuicCryptoServerStreamBase::Helper {
- public:
-  // This will look for the QBONE alpn.
-  bool CanAcceptClientHello(const CryptoHandshakeMessage& chlo,
-                            const QuicSocketAddress& client_address,
-                            const QuicSocketAddress& peer_address,
-                            const QuicSocketAddress& self_address,
-                            std::string* error_details) const override;
-};
-
-class QUIC_EXPORT_PRIVATE QboneServerSession
-    : public QboneSessionBase,
-      public QbonePacketProcessor::OutputInterface,
-      public QbonePacketProcessor::StatsInterface {
- public:
-  QboneServerSession(const quic::ParsedQuicVersionVector& supported_versions,
-                     QuicConnection* connection,
-                     Visitor* owner,
-                     const QuicConfig& config,
-                     const QuicCryptoServerConfig* quic_crypto_server_config,
-                     QuicCompressedCertsCache* compressed_certs_cache,
-                     QbonePacketWriter* writer,
-                     QuicIpAddress self_ip,
-                     QuicIpAddress client_ip,
-                     size_t client_ip_subnet_length,
-                     QboneServerControlStream::Handler* handler);
-  QboneServerSession(const QboneServerSession&) = delete;
-  QboneServerSession& operator=(const QboneServerSession&) = delete;
-  ~QboneServerSession() override;
-
-  void Initialize() override;
-  // Override to create control stream at FORWARD_SECURE encryption level.
-  void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
-
-  virtual bool SendClientRequest(const QboneClientRequest& request);
-
-  void ProcessPacketFromNetwork(absl::string_view packet) override;
-  void ProcessPacketFromPeer(absl::string_view packet) override;
-
-  // QbonePacketProcessor::OutputInterface implementation.
-  void SendPacketToClient(absl::string_view packet) override;
-  void SendPacketToNetwork(absl::string_view packet) override;
-
-  // QbonePacketProcessor::StatsInterface implementation.
-  void OnPacketForwarded(QbonePacketProcessor::Direction direction) override {}
-  void OnPacketDroppedSilently(
-      QbonePacketProcessor::Direction direction) override {}
-  void OnPacketDroppedWithIcmp(
-      QbonePacketProcessor::Direction direction) override {}
-  void OnPacketDroppedWithTcpReset(
-      QbonePacketProcessor::Direction direction) override {}
-  void OnPacketDeferred(QbonePacketProcessor::Direction direction) override {}
-
- protected:
-  // QboneSessionBase interface implementation.
-  std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
-
-  // Instantiates QboneServerControlStream.
-  void CreateControlStream();
-
-  // Instantiates QboneServerControlStream from the pending stream and returns a
-  // pointer to it.
-  QuicStream* CreateControlStreamFromPendingStream(PendingStream* pending);
-
-  // The packet processor.
-  QbonePacketProcessor processor_;
-
-  // Config for QUIC crypto server stream, used by the server.
-  const QuicCryptoServerConfig* quic_crypto_server_config_;
-
- private:
-  // Used by QUIC crypto server stream to track most recently compressed certs.
-  QuicCompressedCertsCache* compressed_certs_cache_;
-  // This helper is needed when create QuicCryptoServerStream.
-  QboneCryptoServerStreamHelper stream_helper_;
-  // Passed to the control stream.
-  QboneServerControlStream::Handler* handler_;
-  // The unowned control stream.
-  QboneServerControlStream* control_stream_ = nullptr;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
diff --git a/quic/qbone/qbone_session_base.cc b/quic/qbone/qbone_session_base.cc
deleted file mode 100644
index c12ec4e..0000000
--- a/quic/qbone/qbone_session_base.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_session_base.h"
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_exported_stats.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_testvalue.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/qbone_constants.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_buffer_allocator.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, qbone_close_ephemeral_frames, true,
-    "If true, we'll call CloseStream even when we receive ephemeral frames.");
-
-namespace quic {
-
-#define ENDPOINT \
-  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
-QboneSessionBase::QboneSessionBase(
-    QuicConnection* connection,
-    Visitor* owner,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QbonePacketWriter* writer)
-    : QuicSession(connection,
-                  owner,
-                  config,
-                  supported_versions,
-                  /*num_expected_unidirectional_static_streams = */ 0) {
-  set_writer(writer);
-  const uint32_t max_streams =
-      (std::numeric_limits<uint32_t>::max() / kMaxAvailableStreamsMultiplier) -
-      1;
-  this->config()->SetMaxBidirectionalStreamsToSend(max_streams);
-  if (VersionHasIetfQuicFrames(transport_version())) {
-    this->config()->SetMaxUnidirectionalStreamsToSend(max_streams);
-  }
-}
-
-QboneSessionBase::~QboneSessionBase() {}
-
-void QboneSessionBase::Initialize() {
-  crypto_stream_ = CreateCryptoStream();
-  QuicSession::Initialize();
-}
-
-const QuicCryptoStream* QboneSessionBase::GetCryptoStream() const {
-  return crypto_stream_.get();
-}
-
-QuicCryptoStream* QboneSessionBase::GetMutableCryptoStream() {
-  return crypto_stream_.get();
-}
-
-QuicStream* QboneSessionBase::CreateOutgoingStream() {
-  return ActivateDataStream(
-      CreateDataStream(GetNextOutgoingUnidirectionalStreamId()));
-}
-
-void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) {
-  if (frame.offset == 0 && frame.fin && frame.data_length > 0) {
-    ++num_ephemeral_packets_;
-    ProcessPacketFromPeer(
-        absl::string_view(frame.data_buffer, frame.data_length));
-    flow_controller()->AddBytesConsumed(frame.data_length);
-    // TODO(b/147817422): Add a counter for how many streams were actually
-    // closed here.
-    if (GetQuicFlag(FLAGS_qbone_close_ephemeral_frames)) {
-      ResetStream(frame.stream_id, QUIC_STREAM_CANCELLED);
-    }
-    return;
-  }
-  QuicSession::OnStreamFrame(frame);
-}
-
-void QboneSessionBase::OnMessageReceived(absl::string_view message) {
-  ++num_message_packets_;
-  ProcessPacketFromPeer(message);
-}
-
-QuicStream* QboneSessionBase::CreateIncomingStream(QuicStreamId id) {
-  return ActivateDataStream(CreateDataStream(id));
-}
-
-QuicStream* QboneSessionBase::CreateIncomingStream(PendingStream* /*pending*/) {
-  QUIC_NOTREACHED();
-  return nullptr;
-}
-
-bool QboneSessionBase::ShouldKeepConnectionAlive() const {
-  // QBONE connections stay alive until they're explicitly closed.
-  return true;
-}
-
-std::unique_ptr<QuicStream> QboneSessionBase::CreateDataStream(
-    QuicStreamId id) {
-  if (!IsEncryptionEstablished()) {
-    // Encryption not active so no stream created
-    return nullptr;
-  }
-
-  if (IsIncomingStream(id)) {
-    ++num_streamed_packets_;
-    return std::make_unique<QboneReadOnlyStream>(id, this);
-  }
-
-  return std::make_unique<QboneWriteOnlyStream>(id, this);
-}
-
-QuicStream* QboneSessionBase::ActivateDataStream(
-    std::unique_ptr<QuicStream> stream) {
-  // Transfer ownership of the data stream to the session via ActivateStream().
-  QuicStream* raw = stream.get();
-  if (stream) {
-    // Make QuicSession take ownership of the stream.
-    ActivateStream(std::move(stream));
-  }
-  return raw;
-}
-
-void QboneSessionBase::SendPacketToPeer(absl::string_view packet) {
-  if (crypto_stream_ == nullptr) {
-    QUIC_BUG(quic_bug_10987_1)
-        << "Attempting to send packet before encryption established";
-    return;
-  }
-
-  if (send_packets_as_messages_) {
-    quiche::QuicheMemSlice slice(quiche::QuicheBuffer::Copy(
-        connection()->helper()->GetStreamSendBufferAllocator(), packet));
-    switch (SendMessage(absl::MakeSpan(&slice, 1), /*flush=*/true).status) {
-      case MESSAGE_STATUS_SUCCESS:
-        break;
-      case MESSAGE_STATUS_TOO_LARGE: {
-        if (packet.size() < sizeof(ip6_hdr)) {
-          QUIC_BUG(quic_bug_10987_2)
-              << "Dropped malformed packet: IPv6 header too short";
-          break;
-        }
-        auto* header = reinterpret_cast<const ip6_hdr*>(packet.begin());
-        icmp6_hdr icmp_header{};
-        icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
-        icmp_header.icmp6_mtu =
-            connection()->GetGuaranteedLargestMessagePayload();
-
-        CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
-                         [this](absl::string_view icmp_packet) {
-                           writer_->WritePacketToNetwork(icmp_packet.data(),
-                                                         icmp_packet.size());
-                         });
-        break;
-      }
-      case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED:
-        QUIC_BUG(quic_bug_10987_3)
-            << "MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED";
-        break;
-      case MESSAGE_STATUS_UNSUPPORTED:
-        QUIC_BUG(quic_bug_10987_4) << "MESSAGE_STATUS_UNSUPPORTED";
-        break;
-      case MESSAGE_STATUS_BLOCKED:
-        QUIC_BUG(quic_bug_10987_5) << "MESSAGE_STATUS_BLOCKED";
-        break;
-      case MESSAGE_STATUS_INTERNAL_ERROR:
-        QUIC_BUG(quic_bug_10987_6) << "MESSAGE_STATUS_INTERNAL_ERROR";
-        break;
-    }
-    return;
-  }
-
-  // QBONE streams are ephemeral.
-  QuicStream* stream = CreateOutgoingStream();
-  if (!stream) {
-    QUIC_BUG(quic_bug_10987_7) << "Failed to create an outgoing QBONE stream.";
-    return;
-  }
-
-  QboneWriteOnlyStream* qbone_stream =
-      static_cast<QboneWriteOnlyStream*>(stream);
-  qbone_stream->WritePacketToQuicStream(packet);
-}
-
-uint64_t QboneSessionBase::GetNumEphemeralPackets() const {
-  return num_ephemeral_packets_;
-}
-
-uint64_t QboneSessionBase::GetNumStreamedPackets() const {
-  return num_streamed_packets_;
-}
-
-uint64_t QboneSessionBase::GetNumMessagePackets() const {
-  return num_message_packets_;
-}
-
-uint64_t QboneSessionBase::GetNumFallbackToStream() const {
-  return num_fallback_to_stream_;
-}
-
-void QboneSessionBase::set_writer(QbonePacketWriter* writer) {
-  writer_ = writer;
-  quic::AdjustTestValue("quic_QbonePacketWriter", &writer_);
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_session_base.h b/quic/qbone/qbone_session_base.h
deleted file mode 100644
index 6d2c1b2..0000000
--- a/quic/qbone/qbone_session_base.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
-#define QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_session.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/qbone/qbone_packet_writer.h"
-#include "quic/qbone/qbone_stream.h"
-
-namespace quic {
-
-class QUIC_EXPORT_PRIVATE QboneSessionBase : public QuicSession {
- public:
-  QboneSessionBase(QuicConnection* connection,
-                   Visitor* owner,
-                   const QuicConfig& config,
-                   const ParsedQuicVersionVector& supported_versions,
-                   QbonePacketWriter* writer);
-  QboneSessionBase(const QboneSessionBase&) = delete;
-  QboneSessionBase& operator=(const QboneSessionBase&) = delete;
-  ~QboneSessionBase() override;
-
-  // Overrides from QuicSession.
-  // This will ensure that the crypto session is created.
-  void Initialize() override;
-  // This will check if the packet is wholly contained.
-  void OnStreamFrame(const QuicStreamFrame& frame) override;
-  // Called whenever a MESSAGE frame is received.
-  void OnMessageReceived(absl::string_view message) override;
-
-  virtual void ProcessPacketFromNetwork(absl::string_view packet) = 0;
-  virtual void ProcessPacketFromPeer(absl::string_view packet) = 0;
-
-  // Returns the number of QBONE network packets that were received
-  // that fit into a single QuicStreamFrame and elided the creation of
-  // a QboneReadOnlyStream.
-  uint64_t GetNumEphemeralPackets() const;
-
-  // Returns the number of QBONE network packets that were via
-  // multiple packets, requiring the creation of a QboneReadOnlyStream.
-  uint64_t GetNumStreamedPackets() const;
-
-  // Returns the number of QBONE network packets that were received using QUIC
-  // MESSAGE frame.
-  uint64_t GetNumMessagePackets() const;
-
-  // Returns the number of times sending a MESSAGE frame failed, and the session
-  // used an ephemeral stream instead.
-  uint64_t GetNumFallbackToStream() const;
-
-  void set_writer(QbonePacketWriter* writer);
-  void set_send_packets_as_messages(bool send_packets_as_messages) {
-    send_packets_as_messages_ = send_packets_as_messages;
-  }
-
- protected:
-  virtual std::unique_ptr<QuicCryptoStream> CreateCryptoStream() = 0;
-
-  // QuicSession interface implementation.
-  QuicCryptoStream* GetMutableCryptoStream() override;
-  const QuicCryptoStream* GetCryptoStream() const override;
-  QuicStream* CreateIncomingStream(QuicStreamId id) override;
-  QuicStream* CreateIncomingStream(PendingStream* pending) override;
-  bool ShouldKeepConnectionAlive() const override;
-
-  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id) override {
-    return true;
-  }
-
-  QuicStream* CreateOutgoingStream();
-  std::unique_ptr<QuicStream> CreateDataStream(QuicStreamId id);
-  // Activates a QuicStream.  The session takes ownership of the stream, but
-  // returns an unowned pointer to the stream for convenience.
-  QuicStream* ActivateDataStream(std::unique_ptr<QuicStream> stream);
-
-  // Accepts a given packet from the network and writes it out
-  // to the QUIC stream. This will create an ephemeral stream per
-  // packet. This function will return true if a stream was created
-  // and the packet sent. It will return false if the stream could not
-  // be created.
-  void SendPacketToPeer(absl::string_view packet);
-
-  QbonePacketWriter* writer_;
-
-  // If true, MESSAGE frames are used for short datagrams.  If false, ephemeral
-  // streams are used instead.  Note that receiving MESSAGE frames is always
-  // supported.
-  bool send_packets_as_messages_ = false;
-
- private:
-  // Used for the crypto handshake.
-  std::unique_ptr<QuicCryptoStream> crypto_stream_;
-
-  // Statistics for the packets received by the session.
-  uint64_t num_ephemeral_packets_ = 0;
-  uint64_t num_message_packets_ = 0;
-  uint64_t num_streamed_packets_ = 0;
-
-  // Number of times the connection has failed to send packets as MESSAGE frame
-  // and used streams as a fallback.
-  uint64_t num_fallback_to_stream_ = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
diff --git a/quic/qbone/qbone_session_test.cc b/quic/qbone/qbone_session_test.cc
deleted file mode 100644
index 4f87602..0000000
--- a/quic/qbone/qbone_session_test.cc
+++ /dev/null
@@ -1,642 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/qbone/platform/icmp_packet.h"
-#include "quic/qbone/qbone_client_session.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_control_placeholder.pb.h"
-#include "quic/qbone/qbone_packet_processor_test_tools.h"
-#include "quic/qbone/qbone_server_session.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using ::testing::_;
-using ::testing::Contains;
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::NiceMock;
-using ::testing::Not;
-
-std::string TestPacketIn(const std::string& body) {
-  return PrependIPv6HeaderForTest(body, 5);
-}
-
-std::string TestPacketOut(const std::string& body) {
-  return PrependIPv6HeaderForTest(body, 4);
-}
-
-ParsedQuicVersionVector GetTestParams() {
-  ParsedQuicVersionVector test_versions;
-
-  // TODO(b/113130636): Make QBONE work with TLS.
-  for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
-    // QBONE requires MESSAGE frames
-    if (!version.SupportsMessageFrames()) {
-      continue;
-    }
-    test_versions.push_back(version);
-  }
-
-  return test_versions;
-}
-
-// Used by QuicCryptoServerConfig to provide server credentials, passes
-// everything through to ProofSourceForTesting if success is true,
-// and fails otherwise.
-class IndirectionProofSource : public ProofSource {
- public:
-  explicit IndirectionProofSource(bool success) {
-    if (success) {
-      proof_source_ = crypto_test_utils::ProofSourceForTesting();
-    }
-  }
-
-  // ProofSource override.
-  void GetProof(const QuicSocketAddress& server_address,
-                const QuicSocketAddress& client_address,
-                const std::string& hostname,
-                const std::string& server_config,
-                QuicTransportVersion transport_version,
-                absl::string_view chlo_hash,
-                std::unique_ptr<Callback> callback) override {
-    if (!proof_source_) {
-      QuicCryptoProof proof;
-      quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
-          GetCertChain(server_address, client_address, hostname,
-                       &proof.cert_matched_sni);
-      callback->Run(/*ok=*/false, chain, proof, /*details=*/nullptr);
-      return;
-    }
-    proof_source_->GetProof(server_address, client_address, hostname,
-                            server_config, transport_version, chlo_hash,
-                            std::move(callback));
-  }
-
-  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, const std::string& hostname,
-      bool* cert_matched_sni) override {
-    if (!proof_source_) {
-      return quiche::QuicheReferenceCountedPointer<Chain>();
-    }
-    return proof_source_->GetCertChain(server_address, client_address, hostname,
-                                       cert_matched_sni);
-  }
-
-  void ComputeTlsSignature(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      const std::string& hostname,
-      uint16_t signature_algorithm,
-      absl::string_view in,
-      std::unique_ptr<SignatureCallback> callback) override {
-    if (!proof_source_) {
-      callback->Run(/*ok=*/true, "Signature", /*details=*/nullptr);
-      return;
-    }
-    proof_source_->ComputeTlsSignature(server_address, client_address, hostname,
-                                       signature_algorithm, in,
-                                       std::move(callback));
-  }
-
-  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
-      const override {
-    if (!proof_source_) {
-      return {};
-    }
-    return proof_source_->SupportedTlsSignatureAlgorithms();
-  }
-
-  TicketCrypter* GetTicketCrypter() override { return nullptr; }
-
- private:
-  std::unique_ptr<ProofSource> proof_source_;
-};
-
-// Used by QuicCryptoClientConfig to verify server credentials, passes
-// everything through to ProofVerifierForTesting is success is true,
-// otherwise returns a canned response of QUIC_FAILURE.
-class IndirectionProofVerifier : public ProofVerifier {
- public:
-  explicit IndirectionProofVerifier(bool success) {
-    if (success) {
-      proof_verifier_ = crypto_test_utils::ProofVerifierForTesting();
-    }
-  }
-
-  // ProofVerifier override
-  QuicAsyncStatus VerifyProof(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::string& server_config,
-      QuicTransportVersion transport_version,
-      absl::string_view chlo_hash,
-      const std::vector<std::string>& certs,
-      const std::string& cert_sct,
-      const std::string& signature,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* verify_details,
-      std::unique_ptr<ProofVerifierCallback> callback) override {
-    if (!proof_verifier_) {
-      return QUIC_FAILURE;
-    }
-    return proof_verifier_->VerifyProof(
-        hostname, port, server_config, transport_version, chlo_hash, certs,
-        cert_sct, signature, context, error_details, verify_details,
-        std::move(callback));
-  }
-
-  QuicAsyncStatus VerifyCertChain(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::vector<std::string>& certs,
-      const std::string& ocsp_response,
-      const std::string& cert_sct,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      uint8_t* out_alert,
-      std::unique_ptr<ProofVerifierCallback> callback) override {
-    if (!proof_verifier_) {
-      return QUIC_FAILURE;
-    }
-    return proof_verifier_->VerifyCertChain(
-        hostname, port, certs, ocsp_response, cert_sct, context, error_details,
-        details, out_alert, std::move(callback));
-  }
-
-  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
-    if (!proof_verifier_) {
-      return nullptr;
-    }
-    return proof_verifier_->CreateDefaultContext();
-  }
-
- private:
-  std::unique_ptr<ProofVerifier> proof_verifier_;
-};
-
-class DataSavingQbonePacketWriter : public QbonePacketWriter {
- public:
-  void WritePacketToNetwork(const char* packet, size_t size) override {
-    data_.push_back(std::string(packet, size));
-  }
-
-  const std::vector<std::string>& data() { return data_; }
-
- private:
-  std::vector<std::string> data_;
-};
-
-template <class T>
-class DataSavingQboneControlHandler : public QboneControlHandler<T> {
- public:
-  void OnControlRequest(const T& request) override { data_.push_back(request); }
-
-  void OnControlError() override { error_ = true; }
-
-  const std::vector<T>& data() { return data_; }
-  bool error() { return error_; }
-
- private:
-  std::vector<T> data_;
-  bool error_ = false;
-};
-
-// Single-threaded scheduled task runner based on a MockClock.
-//
-// Simulates asynchronous execution on a single thread by holding scheduled
-// tasks until Run() is called. Performs no synchronization, assumes that
-// Schedule() and Run() are called on the same thread.
-class FakeTaskRunner {
- public:
-  explicit FakeTaskRunner(MockQuicConnectionHelper* helper)
-      : tasks_([](const TaskType& l, const TaskType& r) {
-          // Items at a later time should run after items at an earlier time.
-          // Priority queue comparisons should return true if l appears after r.
-          return l->time() > r->time();
-        }),
-        helper_(helper) {}
-
-  // Runs all tasks in time order.  Executes tasks scheduled at
-  // the same in an arbitrary order.
-  void Run() {
-    while (!tasks_.empty()) {
-      tasks_.top()->Run();
-      tasks_.pop();
-    }
-  }
-
- private:
-  class InnerTask {
-   public:
-    InnerTask(std::function<void()> task, QuicTime time)
-        : task_(std::move(task)), time_(time) {}
-
-    void Cancel() { cancelled_ = true; }
-
-    void Run() {
-      if (!cancelled_) {
-        task_();
-      }
-    }
-
-    QuicTime time() const { return time_; }
-
-   private:
-    bool cancelled_ = false;
-    std::function<void()> task_;
-    QuicTime time_;
-  };
-
- public:
-  // Schedules a function to run immediately and advances the time.
-  void Schedule(std::function<void()> task) {
-    tasks_.push(std::shared_ptr<InnerTask>(
-        new InnerTask(std::move(task), helper_->GetClock()->Now())));
-    helper_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-  }
-
- private:
-  using TaskType = std::shared_ptr<InnerTask>;
-  std::priority_queue<TaskType,
-                      std::vector<TaskType>,
-                      std::function<bool(const TaskType&, const TaskType&)>>
-      tasks_;
-  MockQuicConnectionHelper* helper_;
-};
-
-class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  QboneSessionTest()
-      : supported_versions_({GetParam()}),
-        runner_(&helper_),
-        compressed_certs_cache_(100) {}
-
-  ~QboneSessionTest() override {
-    delete client_connection_;
-    delete server_connection_;
-  }
-
-  const MockClock* GetClock() const {
-    return static_cast<const MockClock*>(helper_.GetClock());
-  }
-
-  // The parameters are used to control whether the handshake will success or
-  // not.
-  void CreateClientAndServerSessions(bool client_handshake_success = true,
-                                     bool server_handshake_success = true,
-                                     bool send_qbone_alpn = true) {
-    // Quic crashes if packets are sent at time 0, and the clock defaults to 0.
-    helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
-    alarm_factory_ = std::make_unique<QuicEpollAlarmFactory>(&epoll_server_);
-    client_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
-    server_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
-    client_handler_ =
-        std::make_unique<DataSavingQboneControlHandler<QboneClientRequest>>();
-    server_handler_ =
-        std::make_unique<DataSavingQboneControlHandler<QboneServerRequest>>();
-    QuicSocketAddress server_address(TestLoopback(), 0);
-    QuicSocketAddress client_address;
-    if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
-      client_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
-    } else {
-      client_address = QuicSocketAddress(QuicIpAddress::Any6(), 0);
-    }
-
-    {
-      client_connection_ = new QuicConnection(
-          TestConnectionId(), client_address, server_address, &helper_,
-          alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
-          Perspective::IS_CLIENT, supported_versions_);
-      client_connection_->SetSelfAddress(client_address);
-      QuicConfig config;
-      client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
-          std::make_unique<IndirectionProofVerifier>(client_handshake_success));
-      if (send_qbone_alpn) {
-        client_crypto_config_->set_alpn("qbone");
-      }
-      client_peer_ = std::make_unique<QboneClientSession>(
-          client_connection_, client_crypto_config_.get(),
-          /*owner=*/nullptr, config, supported_versions_,
-          QuicServerId("test.example.com", 1234, false), client_writer_.get(),
-          client_handler_.get());
-    }
-
-    {
-      server_connection_ = new QuicConnection(
-          TestConnectionId(), server_address, client_address, &helper_,
-          alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
-          Perspective::IS_SERVER, supported_versions_);
-      server_connection_->SetSelfAddress(server_address);
-      QuicConfig config;
-      server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
-          QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-          std::make_unique<IndirectionProofSource>(server_handshake_success),
-          KeyExchangeSource::Default());
-      QuicCryptoServerConfig::ConfigOptions options;
-      QuicServerConfigProtobuf primary_config =
-          server_crypto_config_->GenerateConfig(QuicRandom::GetInstance(),
-                                                GetClock(), options);
-      std::unique_ptr<CryptoHandshakeMessage> message(
-          server_crypto_config_->AddConfig(primary_config,
-                                           GetClock()->WallNow()));
-
-      server_peer_ = std::make_unique<QboneServerSession>(
-          supported_versions_, server_connection_, nullptr, config,
-          server_crypto_config_.get(), &compressed_certs_cache_,
-          server_writer_.get(), TestLoopback6(), TestLoopback6(), 64,
-          server_handler_.get());
-    }
-
-    // Hook everything up!
-    MockPacketWriter* client_writer = static_cast<MockPacketWriter*>(
-        QuicConnectionPeer::GetWriter(client_peer_->connection()));
-    ON_CALL(*client_writer, WritePacket(_, _, _, _, _))
-        .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
-                                     const QuicIpAddress& self_address,
-                                     const QuicSocketAddress& peer_address,
-                                     PerPacketOptions* options) {
-          char* copy = new char[1024 * 1024];
-          memcpy(copy, buffer, buf_len);
-          runner_.Schedule([this, copy, buf_len] {
-            QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
-            server_peer_->ProcessUdpPacket(server_connection_->self_address(),
-                                           client_connection_->self_address(),
-                                           packet);
-            delete[] copy;
-          });
-          return WriteResult(WRITE_STATUS_OK, buf_len);
-        }));
-    MockPacketWriter* server_writer = static_cast<MockPacketWriter*>(
-        QuicConnectionPeer::GetWriter(server_peer_->connection()));
-    ON_CALL(*server_writer, WritePacket(_, _, _, _, _))
-        .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
-                                     const QuicIpAddress& self_address,
-                                     const QuicSocketAddress& peer_address,
-                                     PerPacketOptions* options) {
-          char* copy = new char[1024 * 1024];
-          memcpy(copy, buffer, buf_len);
-          runner_.Schedule([this, copy, buf_len] {
-            QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
-            client_peer_->ProcessUdpPacket(client_connection_->self_address(),
-                                           server_connection_->self_address(),
-                                           packet);
-            delete[] copy;
-          });
-          return WriteResult(WRITE_STATUS_OK, buf_len);
-        }));
-  }
-
-  void StartHandshake() {
-    server_peer_->Initialize();
-    client_peer_->Initialize();
-    runner_.Run();
-  }
-
-  void ExpectICMPTooBigResponse(const std::vector<std::string>& written_packets,
-                                const int mtu,
-                                const std::string& packet) {
-    auto* header = reinterpret_cast<const ip6_hdr*>(packet.data());
-    icmp6_hdr icmp_header{};
-    icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
-    icmp_header.icmp6_mtu = mtu;
-
-    std::string expected;
-    CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
-                     [&expected](absl::string_view icmp_packet) {
-                       expected = std::string(icmp_packet);
-                     });
-
-    EXPECT_THAT(written_packets, Contains(expected));
-  }
-
-  // Test handshake establishment and sending/receiving of data for two
-  // directions.
-  void TestStreamConnection(bool use_messages) {
-    ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-    ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
-    ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
-    ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
-
-    // Create an outgoing stream from the client and say hello.
-    QUIC_LOG(INFO) << "Sending client -> server";
-    client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello"));
-    client_peer_->ProcessPacketFromNetwork(TestPacketIn("world"));
-    runner_.Run();
-    // The server should see the data, the client hasn't received
-    // anything yet.
-    EXPECT_THAT(server_writer_->data(),
-                ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
-    EXPECT_TRUE(client_writer_->data().empty());
-    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
-    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-
-    // Let's pretend some service responds.
-    QUIC_LOG(INFO) << "Sending server -> client";
-    server_peer_->ProcessPacketFromNetwork(TestPacketIn("Hello Again"));
-    server_peer_->ProcessPacketFromNetwork(TestPacketIn("Again"));
-    runner_.Run();
-    EXPECT_THAT(server_writer_->data(),
-                ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
-    EXPECT_THAT(
-        client_writer_->data(),
-        ElementsAre(TestPacketOut("Hello Again"), TestPacketOut("Again")));
-    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
-    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-
-    // Try to send long payloads that are larger than the QUIC MTU but
-    // smaller than the QBONE max size.
-    // This should trigger the non-ephemeral stream code path.
-    std::string long_data(
-        QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
-    QUIC_LOG(INFO) << "Sending server -> client long data";
-    server_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
-    runner_.Run();
-    if (use_messages) {
-      ExpectICMPTooBigResponse(
-          server_writer_->data(),
-          server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
-          TestPacketOut(long_data));
-    } else {
-      EXPECT_THAT(client_writer_->data(), Contains(TestPacketOut(long_data)));
-    }
-    EXPECT_THAT(server_writer_->data(),
-                Not(Contains(TestPacketOut(long_data))));
-    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
-    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-
-    QUIC_LOG(INFO) << "Sending client -> server long data";
-    client_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
-    runner_.Run();
-    if (use_messages) {
-      ExpectICMPTooBigResponse(
-          client_writer_->data(),
-          client_peer_->connection()->GetGuaranteedLargestMessagePayload(),
-          TestPacketIn(long_data));
-    } else {
-      EXPECT_THAT(server_writer_->data(), Contains(TestPacketOut(long_data)));
-    }
-    EXPECT_FALSE(client_peer_->EarlyDataAccepted());
-    EXPECT_FALSE(client_peer_->ReceivedInchoateReject());
-    EXPECT_THAT(client_peer_->GetNumReceivedServerConfigUpdates(), Eq(0));
-
-    if (!use_messages) {
-      EXPECT_THAT(client_peer_->GetNumStreamedPackets(), Eq(1));
-      EXPECT_THAT(server_peer_->GetNumStreamedPackets(), Eq(1));
-    }
-
-    if (use_messages) {
-      EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(0));
-      EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(0));
-      EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(2));
-      EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(2));
-    } else {
-      EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(2));
-      EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(2));
-      EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(0));
-      EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(0));
-    }
-
-    // All streams are ephemeral and should be gone.
-    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
-    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-  }
-
-  // Test that client and server are not connected after handshake failure.
-  void TestDisconnectAfterFailedHandshake() {
-    EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
-    EXPECT_FALSE(client_peer_->OneRttKeysAvailable());
-
-    EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
-    EXPECT_FALSE(server_peer_->OneRttKeysAvailable());
-  }
-
- protected:
-  const ParsedQuicVersionVector supported_versions_;
-  QuicEpollServer epoll_server_;
-  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-  FakeTaskRunner runner_;
-  MockQuicConnectionHelper helper_;
-  QuicConnection* client_connection_;
-  QuicConnection* server_connection_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-
-  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
-  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
-  std::unique_ptr<DataSavingQbonePacketWriter> client_writer_;
-  std::unique_ptr<DataSavingQbonePacketWriter> server_writer_;
-  std::unique_ptr<DataSavingQboneControlHandler<QboneClientRequest>>
-      client_handler_;
-  std::unique_ptr<DataSavingQboneControlHandler<QboneServerRequest>>
-      server_handler_;
-
-  std::unique_ptr<QboneServerSession> server_peer_;
-  std::unique_ptr<QboneClientSession> client_peer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QboneSessionTest,
-                         ::testing::ValuesIn(GetTestParams()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QboneSessionTest, StreamConnection) {
-  CreateClientAndServerSessions();
-  client_peer_->set_send_packets_as_messages(false);
-  server_peer_->set_send_packets_as_messages(false);
-  StartHandshake();
-  TestStreamConnection(false);
-}
-
-TEST_P(QboneSessionTest, Messages) {
-  CreateClientAndServerSessions();
-  client_peer_->set_send_packets_as_messages(true);
-  server_peer_->set_send_packets_as_messages(true);
-  StartHandshake();
-  TestStreamConnection(true);
-}
-
-TEST_P(QboneSessionTest, ClientRejection) {
-  CreateClientAndServerSessions(false /*client_handshake_success*/,
-                                true /*server_handshake_success*/,
-                                true /*send_qbone_alpn*/);
-  StartHandshake();
-  TestDisconnectAfterFailedHandshake();
-}
-
-TEST_P(QboneSessionTest, BadAlpn) {
-  CreateClientAndServerSessions(true /*client_handshake_success*/,
-                                true /*server_handshake_success*/,
-                                false /*send_qbone_alpn*/);
-  StartHandshake();
-  TestDisconnectAfterFailedHandshake();
-}
-
-TEST_P(QboneSessionTest, ServerRejection) {
-  CreateClientAndServerSessions(true /*client_handshake_success*/,
-                                false /*server_handshake_success*/,
-                                true /*send_qbone_alpn*/);
-  StartHandshake();
-  TestDisconnectAfterFailedHandshake();
-}
-
-// Test that data streams are not created before handshake.
-TEST_P(QboneSessionTest, CannotCreateDataStreamBeforeHandshake) {
-  CreateClientAndServerSessions();
-  EXPECT_QUIC_BUG(client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
-                  "Attempting to send packet before encryption established");
-  EXPECT_QUIC_BUG(server_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
-                  "Attempting to send packet before encryption established");
-  EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
-  EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
-}
-
-TEST_P(QboneSessionTest, ControlRequests) {
-  CreateClientAndServerSessions();
-  StartHandshake();
-  EXPECT_TRUE(client_handler_->data().empty());
-  EXPECT_FALSE(client_handler_->error());
-  EXPECT_TRUE(server_handler_->data().empty());
-  EXPECT_FALSE(server_handler_->error());
-
-  QboneClientRequest client_request;
-  client_request.SetExtension(client_placeholder, "hello from the server");
-  EXPECT_TRUE(server_peer_->SendClientRequest(client_request));
-  runner_.Run();
-  ASSERT_FALSE(client_handler_->data().empty());
-  EXPECT_THAT(client_handler_->data()[0].GetExtension(client_placeholder),
-              Eq("hello from the server"));
-  EXPECT_FALSE(client_handler_->error());
-
-  QboneServerRequest server_request;
-  server_request.SetExtension(server_placeholder, "hello from the client");
-  EXPECT_TRUE(client_peer_->SendServerRequest(server_request));
-  runner_.Run();
-  ASSERT_FALSE(server_handler_->data().empty());
-  EXPECT_THAT(server_handler_->data()[0].GetExtension(server_placeholder),
-              Eq("hello from the client"));
-  EXPECT_FALSE(server_handler_->error());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/qbone/qbone_stream.cc b/quic/qbone/qbone_stream.cc
deleted file mode 100644
index 3901233..0000000
--- a/quic/qbone/qbone_stream.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_stream.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_types.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_session_base.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int, qbone_stream_ttl_secs, 3,
-                                "The QBONE Stream TTL in seconds.");
-
-namespace quic {
-
-QboneWriteOnlyStream::QboneWriteOnlyStream(QuicStreamId id,
-                                           QuicSession* session)
-    : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL) {
-  // QBONE uses a LIFO queue to try to always make progress. An individual
-  // packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
-  MaybeSetTtl(
-      QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
-}
-
-void QboneWriteOnlyStream::WritePacketToQuicStream(absl::string_view packet) {
-  // Streams are one way and ephemeral. This function should only be
-  // called once.
-  WriteOrBufferData(packet, /* fin= */ true, nullptr);
-}
-
-QboneReadOnlyStream::QboneReadOnlyStream(QuicStreamId id,
-                                         QboneSessionBase* session)
-    : QuicStream(id,
-                 session,
-                 /*is_static=*/false,
-                 READ_UNIDIRECTIONAL),
-      session_(session) {
-  // QBONE uses a LIFO queue to try to always make progress. An individual
-  // packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
-  MaybeSetTtl(
-      QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
-}
-
-void QboneReadOnlyStream::OnDataAvailable() {
-  // Read in data and buffer it, attempt to frame to see if there's a packet.
-  sequencer()->Read(&buffer_);
-  if (sequencer()->IsClosed()) {
-    session_->ProcessPacketFromPeer(buffer_);
-    OnFinRead();
-    return;
-  }
-  if (buffer_.size() > QboneConstants::kMaxQbonePacketBytes) {
-    if (!rst_sent()) {
-      Reset(QUIC_BAD_APPLICATION_PAYLOAD);
-    }
-    StopReading();
-  }
-}
-
-}  // namespace quic
diff --git a/quic/qbone/qbone_stream.h b/quic/qbone/qbone_stream.h
deleted file mode 100644
index e7ea045..0000000
--- a/quic/qbone/qbone_stream.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_STREAM_H_
-#define QUICHE_QUIC_QBONE_QBONE_STREAM_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-class QboneSessionBase;
-
-// QboneWriteOnlyStream is responsible for sending data for a single
-// packet to the other side.
-// Note that the stream will be created HalfClosed (reads will be closed).
-class QUIC_EXPORT_PRIVATE QboneWriteOnlyStream : public QuicStream {
- public:
-  QboneWriteOnlyStream(QuicStreamId id, QuicSession* session);
-
-  // QuicStream implementation. QBONE writers are ephemeral and don't
-  // read any data.
-  void OnDataAvailable() override {}
-
-  // Write a network packet over the quic stream.
-  void WritePacketToQuicStream(absl::string_view packet);
-};
-
-// QboneReadOnlyStream will be used if we find an incoming stream that
-// isn't fully contained. It will buffer the data when available and
-// attempt to parse it as a packet to send to the network when a FIN
-// is found.
-// Note that the stream will be created HalfClosed (writes will be closed).
-class QUIC_EXPORT_PRIVATE QboneReadOnlyStream : public QuicStream {
- public:
-  QboneReadOnlyStream(QuicStreamId id, QboneSessionBase* session);
-
-  ~QboneReadOnlyStream() override = default;
-
-  // QuicStream overrides.
-  // OnDataAvailable is called when there is data in the quic stream buffer.
-  // This will copy the buffer locally and attempt to parse it to write out
-  // packets to the network.
-  void OnDataAvailable() override;
-
- private:
-  std::string buffer_;
-  QboneSessionBase* session_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QBONE_QBONE_STREAM_H_
diff --git a/quic/qbone/qbone_stream_test.cc b/quic/qbone/qbone_stream_test.cc
deleted file mode 100644
index 0ec7871..0000000
--- a/quic/qbone/qbone_stream_test.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/qbone/qbone_stream.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/qbone/qbone_constants.h"
-#include "quic/qbone/qbone_session_base.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "common/simple_buffer_allocator.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-namespace {
-
-using ::testing::_;
-using ::testing::StrictMock;
-
-// MockQuicSession that does not create streams and writes data from
-// QuicStream to a string.
-class MockQuicSession : public QboneSessionBase {
- public:
-  MockQuicSession(QuicConnection* connection, const QuicConfig& config)
-      : QboneSessionBase(connection, nullptr /*visitor*/, config,
-                         CurrentSupportedVersions(), nullptr /*writer*/) {}
-
-  ~MockQuicSession() override {}
-
-  // Writes outgoing data from QuicStream to a string.
-  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
-                              QuicStreamOffset offset, StreamSendingState state,
-                              TransmissionType type,
-                              EncryptionLevel level) override {
-    if (!writable_) {
-      return QuicConsumedData(0, false);
-    }
-
-    return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN);
-  }
-
-  QboneReadOnlyStream* CreateIncomingStream(QuicStreamId id) override {
-    return nullptr;
-  }
-
-  // Called by QuicStream when they want to close stream.
-  MOCK_METHOD(void, MaybeSendRstStreamFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error,
-               QuicStreamOffset bytes_written),
-              (override));
-  MOCK_METHOD(void, MaybeSendStopSendingFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error), (override));
-
-  // Sets whether data is written to buffer, or else if this is write blocked.
-  void set_writable(bool writable) { writable_ = writable; }
-
-  // Tracks whether the stream is write blocked and its priority.
-  void RegisterReliableStream(QuicStreamId stream_id) {
-    // The priority effectively does not matter. Put all streams on the same
-    // priority.
-    write_blocked_streams()->RegisterStream(
-        stream_id,
-        /*is_static_stream=*/false,
-        /* precedence= */ spdy::SpdyStreamPrecedence(3));
-  }
-
-  // The session take ownership of the stream.
-  void ActivateReliableStream(std::unique_ptr<QuicStream> stream) {
-    ActivateStream(std::move(stream));
-  }
-
-  std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override {
-    return std::make_unique<test::MockQuicCryptoStream>(this);
-  }
-
-  MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override));
-  MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override));
-
- private:
-  // Whether data is written to write_buffer_.
-  bool writable_ = true;
-};
-
-// Packet writer that does nothing. This is required for QuicConnection but
-// isn't used for writing data.
-class DummyPacketWriter : public QuicPacketWriter {
- public:
-  DummyPacketWriter() {}
-
-  // QuicPacketWriter overrides.
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override {
-    return WriteResult(WRITE_STATUS_ERROR, 0);
-  }
-
-  bool IsWriteBlocked() const override { return false; };
-
-  void SetWritable() override {}
-
-  absl::optional<int> MessageTooBigErrorCode() const override {
-    return absl::nullopt;
-  }
-
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& peer_address) const override {
-    return 0;
-  }
-
-  bool SupportsReleaseTime() const override { return false; }
-
-  bool IsBatchMode() const override { return false; }
-
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& self_address,
-      const QuicSocketAddress& peer_address) override {
-    return {nullptr, nullptr};
-  }
-
-  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-};
-
-class QboneReadOnlyStreamTest : public ::testing::Test,
-                                public QuicConnectionHelperInterface {
- public:
-  void CreateReliableQuicStream() {
-    // Arbitrary values for QuicConnection.
-    Perspective perspective = Perspective::IS_SERVER;
-    bool owns_writer = true;
-
-    alarm_factory_ = std::make_unique<test::MockAlarmFactory>();
-
-    connection_.reset(new QuicConnection(
-        test::TestConnectionId(0), QuicSocketAddress(TestLoopback(), 0),
-        QuicSocketAddress(TestLoopback(), 0),
-        this /*QuicConnectionHelperInterface*/, alarm_factory_.get(),
-        new DummyPacketWriter(), owns_writer, perspective,
-        ParsedVersionOfIndex(CurrentSupportedVersions(), 0)));
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_.get(),
-                                                             QuicConfig());
-    session_->Initialize();
-    stream_ = new QboneReadOnlyStream(kStreamId, session_.get());
-    session_->ActivateReliableStream(
-        std::unique_ptr<QboneReadOnlyStream>(stream_));
-  }
-
-  ~QboneReadOnlyStreamTest() override {}
-
-  const QuicClock* GetClock() const override { return &clock_; }
-
-  QuicRandom* GetRandomGenerator() override {
-    return QuicRandom::GetInstance();
-  }
-
-  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override {
-    return &buffer_allocator_;
-  }
-
- protected:
-  // The QuicSession will take the ownership.
-  QboneReadOnlyStream* stream_;
-  std::unique_ptr<StrictMock<MockQuicSession>> session_;
-  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-  std::unique_ptr<QuicConnection> connection_;
-  // Used to implement the QuicConnectionHelperInterface.
-  quiche::SimpleBufferAllocator buffer_allocator_;
-  MockClock clock_;
-  const QuicStreamId kStreamId = QuicUtils::GetFirstUnidirectionalStreamId(
-      CurrentSupportedVersions()[0].transport_version, Perspective::IS_CLIENT);
-};
-
-// Read an entire string.
-TEST_F(QboneReadOnlyStreamTest, ReadDataWhole) {
-  std::string packet = "Stuff";
-  CreateReliableQuicStream();
-  QuicStreamFrame frame(kStreamId, true, 0, packet);
-  EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
-  stream_->OnStreamFrame(frame);
-}
-
-// Test buffering.
-TEST_F(QboneReadOnlyStreamTest, ReadBuffered) {
-  CreateReliableQuicStream();
-  std::string packet = "Stuf";
-  {
-    QuicStreamFrame frame(kStreamId, false, 0, packet);
-    stream_->OnStreamFrame(frame);
-  }
-  // We didn't write 5 bytes yet...
-
-  packet = "f";
-  EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
-  {
-    QuicStreamFrame frame(kStreamId, true, 4, packet);
-    stream_->OnStreamFrame(frame);
-  }
-}
-
-TEST_F(QboneReadOnlyStreamTest, ReadOutOfOrder) {
-  CreateReliableQuicStream();
-  std::string packet = "f";
-  {
-    QuicStreamFrame frame(kStreamId, true, 4, packet);
-    stream_->OnStreamFrame(frame);
-  }
-
-  packet = "S";
-  {
-    QuicStreamFrame frame(kStreamId, false, 0, packet);
-    stream_->OnStreamFrame(frame);
-  }
-
-  packet = "tuf";
-  EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
-  {
-    QuicStreamFrame frame(kStreamId, false, 1, packet);
-    stream_->OnStreamFrame(frame);
-  }
-}
-
-// Test buffering too many bytes.
-TEST_F(QboneReadOnlyStreamTest, ReadBufferedTooLarge) {
-  CreateReliableQuicStream();
-  std::string packet = "0123456789";
-  int iterations = (QboneConstants::kMaxQbonePacketBytes / packet.size()) + 2;
-  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
-                             kStreamId, QuicResetStreamError::FromInternal(
-                                            QUIC_BAD_APPLICATION_PAYLOAD)));
-  EXPECT_CALL(
-      *session_,
-      MaybeSendRstStreamFrame(
-          kStreamId,
-          QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD), _));
-  for (int i = 0; i < iterations; ++i) {
-    QuicStreamFrame frame(kStreamId, i == (iterations - 1), i * packet.size(),
-                          packet);
-    if (!stream_->reading_stopped()) {
-      stream_->OnStreamFrame(frame);
-    }
-  }
-  // We should have nothing written to the network and the stream
-  // should have stopped reading.
-  EXPECT_TRUE(stream_->reading_stopped());
-}
-
-}  // namespace
-
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_client_session.cc b/quic/quic_transport/quic_transport_client_session.cc
deleted file mode 100644
index 1a2160b..0000000
--- a/quic/quic_transport/quic_transport_client_session.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/quic_transport_client_session.h"
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-QuicTransportClientSession::QuicTransportClientSession(
-    QuicConnection* connection,
-    Visitor* owner,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    const GURL& url,
-    QuicCryptoClientConfig* crypto_config,
-    url::Origin origin,
-    WebTransportVisitor* visitor,
-    std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
-    : QuicSession(connection,
-                  owner,
-                  config,
-                  supported_versions,
-                  /*num_expected_unidirectional_static_streams*/ 0,
-                  std::move(datagram_observer)),
-      url_(url),
-      origin_(origin),
-      visitor_(visitor) {
-  for (const ParsedQuicVersion& version : supported_versions) {
-    QUIC_BUG_IF(quic_bug_12035_1, version.handshake_protocol != PROTOCOL_TLS1_3)
-        << "QuicTransport requires TLS 1.3 handshake";
-  }
-  crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
-      QuicServerId(url.host(), url.EffectiveIntPort()), this,
-      crypto_config->proof_verifier()->CreateDefaultContext(), crypto_config,
-      /*proof_handler=*/this, /*has_application_state = */ true);
-}
-
-void QuicTransportClientSession::OnAlpnSelected(absl::string_view alpn) {
-  // Defense in-depth: ensure the ALPN selected is the desired one.
-  if (alpn != QuicTransportAlpn()) {
-    QUIC_BUG(quic_bug_10881_1)
-        << "QuicTransport negotiated non-QuicTransport ALPN: " << alpn;
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR, "QuicTransport negotiated non-QuicTransport ALPN",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  alpn_received_ = true;
-}
-
-QuicStream* QuicTransportClientSession::CreateIncomingStream(QuicStreamId id) {
-  QUIC_DVLOG(1) << "Creating incoming QuicTransport stream " << id;
-  QuicTransportStream* stream = CreateStream(id);
-  if (stream->type() == BIDIRECTIONAL) {
-    incoming_bidirectional_streams_.push_back(stream);
-    visitor_->OnIncomingBidirectionalStreamAvailable();
-  } else {
-    incoming_unidirectional_streams_.push_back(stream);
-    visitor_->OnIncomingUnidirectionalStreamAvailable();
-  }
-  return stream;
-}
-
-void QuicTransportClientSession::SetDefaultEncryptionLevel(
-    EncryptionLevel level) {
-  QuicSession::SetDefaultEncryptionLevel(level);
-  if (level == ENCRYPTION_FORWARD_SECURE) {
-    SendClientIndication();
-  }
-}
-
-void QuicTransportClientSession::OnTlsHandshakeComplete() {
-  QuicSession::OnTlsHandshakeComplete();
-  SendClientIndication();
-}
-
-QuicTransportStream*
-QuicTransportClientSession::AcceptIncomingBidirectionalStream() {
-  if (incoming_bidirectional_streams_.empty()) {
-    return nullptr;
-  }
-  QuicTransportStream* stream = incoming_bidirectional_streams_.front();
-  incoming_bidirectional_streams_.pop_front();
-  return stream;
-}
-
-QuicTransportStream*
-QuicTransportClientSession::AcceptIncomingUnidirectionalStream() {
-  if (incoming_unidirectional_streams_.empty()) {
-    return nullptr;
-  }
-  QuicTransportStream* stream = incoming_unidirectional_streams_.front();
-  incoming_unidirectional_streams_.pop_front();
-  return stream;
-}
-
-QuicTransportStream*
-QuicTransportClientSession::OpenOutgoingBidirectionalStream() {
-  if (!CanOpenNextOutgoingBidirectionalStream()) {
-    QUIC_BUG(quic_bug_10881_2)
-        << "Attempted to open a stream in violation of flow control";
-    return nullptr;
-  }
-  return CreateStream(GetNextOutgoingBidirectionalStreamId());
-}
-
-QuicTransportStream*
-QuicTransportClientSession::OpenOutgoingUnidirectionalStream() {
-  if (!CanOpenNextOutgoingUnidirectionalStream()) {
-    QUIC_BUG(quic_bug_10881_3)
-        << "Attempted to open a stream in violation of flow control";
-    return nullptr;
-  }
-  return CreateStream(GetNextOutgoingUnidirectionalStreamId());
-}
-
-QuicTransportStream* QuicTransportClientSession::CreateStream(QuicStreamId id) {
-  auto stream = std::make_unique<QuicTransportStream>(id, this, this);
-  QuicTransportStream* stream_ptr = stream.get();
-  ActivateStream(std::move(stream));
-  return stream_ptr;
-}
-
-std::string QuicTransportClientSession::SerializeClientIndication() {
-  std::string serialized_origin = origin_.Serialize();
-  if (serialized_origin.size() > std::numeric_limits<uint16_t>::max()) {
-    QUIC_BUG(quic_bug_10881_4) << "Client origin too long";
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR, "Client origin too long",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return "";
-  }
-  QUIC_DLOG(INFO) << "Sending client indication with origin "
-                  << serialized_origin;
-
-  std::string path = url_.PathForRequest();
-  if (path.size() > std::numeric_limits<uint16_t>::max()) {
-    connection()->CloseConnection(
-        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, "Requested URL path too long",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return "";
-  }
-
-  constexpr size_t kPrefixSize =
-      sizeof(QuicTransportClientIndicationKeys) + sizeof(uint16_t);
-  const size_t buffer_size =
-      2 * kPrefixSize + serialized_origin.size() + path.size();
-  if (buffer_size > std::numeric_limits<uint16_t>::max()) {
-    connection()->CloseConnection(
-        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
-        "Client indication size limit exceeded",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return "";
-  }
-
-  std::string buffer;
-  buffer.resize(buffer_size);
-  QuicDataWriter writer(buffer.size(), &buffer[0]);
-  bool success =
-      writer.WriteUInt16(
-          static_cast<uint16_t>(QuicTransportClientIndicationKeys::kOrigin)) &&
-      writer.WriteUInt16(serialized_origin.size()) &&
-      writer.WriteStringPiece(serialized_origin) &&
-      writer.WriteUInt16(
-          static_cast<uint16_t>(QuicTransportClientIndicationKeys::kPath)) &&
-      writer.WriteUInt16(path.size()) && writer.WriteStringPiece(path);
-  QUIC_BUG_IF(quic_bug_10881_5, !success)
-      << "Failed to serialize client indication";
-  QUIC_BUG_IF(quic_bug_12035_2, writer.length() != buffer.length())
-      << "Serialized client indication has length different from expected";
-  return buffer;
-}
-
-void QuicTransportClientSession::SendClientIndication() {
-  if (!crypto_stream_->encryption_established()) {
-    QUIC_BUG(quic_bug_10881_6)
-        << "Client indication may only be sent once the encryption is "
-           "established.";
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR, "Attempted to send client indication unencrypted",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  if (ready_) {
-    QUIC_BUG(quic_bug_10881_7) << "Client indication may only be sent once.";
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR, "Attempted to send client indication twice",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  auto client_indication_owned = std::make_unique<ClientIndication>(
-      /*stream_id=*/GetNextOutgoingUnidirectionalStreamId(), this,
-      /*is_static=*/false, WRITE_UNIDIRECTIONAL);
-  QUIC_BUG_IF(quic_bug_12035_3,
-              client_indication_owned->id() != ClientIndicationStream())
-      << "Client indication stream is " << client_indication_owned->id()
-      << " instead of expected " << ClientIndicationStream();
-  ClientIndication* client_indication = client_indication_owned.get();
-  ActivateStream(std::move(client_indication_owned));
-
-  client_indication->WriteOrBufferData(SerializeClientIndication(),
-                                       /*fin=*/true, nullptr);
-  client_indication_sent_ = true;
-
-  // Defense in depth: never set the ready bit unless ALPN has been confirmed.
-  if (!alpn_received_) {
-    QUIC_BUG(quic_bug_10881_8)
-        << "ALPN confirmation missing after handshake complete";
-    connection()->CloseConnection(
-        QUIC_INTERNAL_ERROR,
-        "ALPN confirmation missing after handshake complete",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-
-  // Don't set the ready bit if we closed the connection due to any error
-  // beforehand.
-  if (!connection()->connected()) {
-    return;
-  }
-
-  ready_ = true;
-  visitor_->OnSessionReady(spdy::SpdyHeaderBlock());
-}
-
-void QuicTransportClientSession::OnMessageReceived(absl::string_view message) {
-  visitor_->OnDatagramReceived(message);
-}
-
-void QuicTransportClientSession::OnCanCreateNewOutgoingStream(
-    bool unidirectional) {
-  if (unidirectional) {
-    visitor_->OnCanCreateNewOutgoingUnidirectionalStream();
-  } else {
-    visitor_->OnCanCreateNewOutgoingBidirectionalStream();
-  }
-}
-
-void QuicTransportClientSession::OnProofValid(
-    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
-
-void QuicTransportClientSession::OnProofVerifyDetailsAvailable(
-    const ProofVerifyDetails& /*verify_details*/) {}
-
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_client_session.h b/quic/quic_transport/quic_transport_client_session.h
deleted file mode 100644
index f5374de..0000000
--- a/quic/quic_transport/quic_transport_client_session.h
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
-
-#include <cstdint>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_datagram_queue.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-#include "common/platform/api/quiche_mem_slice.h"
-
-namespace quic {
-
-// A client session for the QuicTransport protocol.
-class QUIC_EXPORT_PRIVATE QuicTransportClientSession
-    : public QuicSession,
-      public WebTransportSession,
-      public QuicTransportSessionInterface,
-      public QuicCryptoClientStream::ProofHandler {
- public:
-  QuicTransportClientSession(
-      QuicConnection* connection,
-      Visitor* owner,
-      const QuicConfig& config,
-      const ParsedQuicVersionVector& supported_versions,
-      const GURL& url,
-      QuicCryptoClientConfig* crypto_config,
-      url::Origin origin,
-      WebTransportVisitor* visitor,
-      std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
-
-  std::vector<std::string> GetAlpnsToOffer() const override {
-    return std::vector<std::string>({QuicTransportAlpn()});
-  }
-  void OnAlpnSelected(absl::string_view alpn) override;
-  bool alpn_received() const { return alpn_received_; }
-
-  void CryptoConnect() { crypto_stream_->CryptoConnect(); }
-
-  bool ShouldKeepConnectionAlive() const override { return true; }
-
-  QuicCryptoStream* GetMutableCryptoStream() override {
-    return crypto_stream_.get();
-  }
-  const QuicCryptoStream* GetCryptoStream() const override {
-    return crypto_stream_.get();
-  }
-
-  // Returns true once the encryption has been established and the client
-  // indication has been sent.  No application data will be read or written
-  // before the connection is ready.  Once the connection becomes ready, this
-  // method will never return false.
-  bool IsSessionReady() const override { return ready_; }
-
-  QuicStream* CreateIncomingStream(QuicStreamId id) override;
-  QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
-    QUIC_BUG(quic_bug_10890_1)
-        << "QuicTransportClientSession::CreateIncomingStream("
-           "PendingStream) not implemented";
-    return nullptr;
-  }
-
-  void SetDefaultEncryptionLevel(EncryptionLevel level) override;
-  void OnTlsHandshakeComplete() override;
-  void OnMessageReceived(absl::string_view message) override;
-
-  // Return the earliest incoming stream that has been received by the session
-  // but has not been accepted.  Returns nullptr if there are no incoming
-  // streams.
-  QuicTransportStream* AcceptIncomingBidirectionalStream() override;
-  QuicTransportStream* AcceptIncomingUnidirectionalStream() override;
-
-  bool CanOpenNextOutgoingBidirectionalStream() override {
-    return QuicSession::CanOpenNextOutgoingBidirectionalStream();
-  }
-  bool CanOpenNextOutgoingUnidirectionalStream() override {
-    return QuicSession::CanOpenNextOutgoingUnidirectionalStream();
-  }
-  QuicTransportStream* OpenOutgoingBidirectionalStream() override;
-  QuicTransportStream* OpenOutgoingUnidirectionalStream() override;
-
-  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram) override {
-    return datagram_queue()->SendOrQueueDatagram(std::move(datagram));
-  }
-  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override {
-    datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
-  }
-
-  // For unit tests.
-  using QuicSession::datagram_queue;
-
-  // QuicCryptoClientStream::ProofHandler implementation.
-  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
-  void OnProofVerifyDetailsAvailable(
-      const ProofVerifyDetails& verify_details) override;
-
-  void CloseSession(WebTransportSessionError /*error_code*/,
-                    absl::string_view error_message) override {
-    connection()->CloseConnection(
-        QUIC_NO_ERROR, std::string(error_message),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  }
-
-  QuicByteCount GetMaxDatagramSize() const override {
-    return GetGuaranteedLargestMessagePayload();
-  }
-
- protected:
-  class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
-   public:
-    using QuicStream::QuicStream;
-
-    // This method should never be called, since the stream is client-initiated
-    // unidirectional.
-    void OnDataAvailable() override {
-      QUIC_BUG(quic_bug_10890_2) << "Received data on a write-only stream";
-    }
-  };
-
-  // Creates and activates a QuicTransportStream for the given ID.
-  QuicTransportStream* CreateStream(QuicStreamId id);
-
-  // Serializes the client indication as described in
-  // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
-  std::string SerializeClientIndication();
-  // Creates the client indication stream and sends the client indication on it.
-  void SendClientIndication();
-
-  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
-
-  std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
-  GURL url_;
-  url::Origin origin_;
-  WebTransportVisitor* visitor_;  // not owned
-  bool client_indication_sent_ = false;
-  bool alpn_received_ = false;
-  bool ready_ = false;
-
-  // Contains all of the streams that has been received by the session but have
-  // not been processed by the application.
-  // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall
-  // maximum number of streams for the connection has not been exceeded. We
-  // should also limit the maximum number of streams that the consuming code
-  // has not accepted to a smaller number, by checking the size of
-  // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_|
-  // before sending MAX_STREAMS.
-  quiche::QuicheCircularDeque<QuicTransportStream*>
-      incoming_bidirectional_streams_;
-  quiche::QuicheCircularDeque<QuicTransportStream*>
-      incoming_unidirectional_streams_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
diff --git a/quic/quic_transport/quic_transport_client_session_test.cc b/quic/quic_transport/quic_transport_client_session_test.cc
deleted file mode 100644
index 90c449c..0000000
--- a/quic/quic_transport/quic_transport_client_session_test.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/quic_transport_client_session.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "url/gurl.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::ElementsAre;
-using testing::Eq;
-
-const char* kTestOrigin = "https://test-origin.test";
-url::Origin GetTestOrigin() {
-  GURL origin_url(kTestOrigin);
-  return url::Origin::Create(origin_url);
-}
-
-ParsedQuicVersionVector GetVersions() {
-  return {DefaultVersionForQuicTransport()};
-}
-
-std::string DataInStream(QuicStream* stream) {
-  QuicStreamSendBuffer& send_buffer = QuicStreamPeer::SendBuffer(stream);
-  std::string result;
-  result.resize(send_buffer.stream_offset());
-  QuicDataWriter writer(result.size(), &result[0]);
-  EXPECT_TRUE(
-      send_buffer.WriteStreamData(0, send_buffer.stream_offset(), &writer));
-  return result;
-}
-
-class QuicTransportClientSessionTest : public QuicTest {
- protected:
-  QuicTransportClientSessionTest()
-      : connection_(&helper_,
-                    &alarm_factory_,
-                    Perspective::IS_CLIENT,
-                    GetVersions()),
-        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
-    QuicEnableVersion(DefaultVersionForQuicTransport());
-    CreateSession(GetTestOrigin(), "");
-  }
-
-  void CreateSession(url::Origin origin, std::string url_suffix) {
-    session_ = std::make_unique<QuicTransportClientSession>(
-        &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
-        GURL("quic-transport://test.example.com:50000" + url_suffix),
-        &crypto_config_, origin, &visitor_, /*datagram_observer=*/nullptr);
-    session_->Initialize();
-    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
-        session_->GetMutableCryptoStream());
-  }
-
-  void Connect() {
-    session_->CryptoConnect();
-    QuicConfig server_config = DefaultQuicConfig();
-    std::unique_ptr<QuicCryptoServerConfig> crypto_config(
-        crypto_test_utils::CryptoServerConfigForTesting());
-    crypto_test_utils::HandshakeWithFakeServer(
-        &server_config, crypto_config.get(), &helper_, &alarm_factory_,
-        &connection_, crypto_stream_, QuicTransportAlpn());
-  }
-
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnectionHelper helper_;
-
-  PacketSavingConnection connection_;
-  QuicCryptoClientConfig crypto_config_;
-  MockClientVisitor visitor_;
-  std::unique_ptr<QuicTransportClientSession> session_;
-  QuicCryptoClientStream* crypto_stream_;
-};
-
-TEST_F(QuicTransportClientSessionTest, HasValidAlpn) {
-  EXPECT_THAT(session_->GetAlpnsToOffer(), ElementsAre(QuicTransportAlpn()));
-}
-
-TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) {
-  constexpr char kTestOriginClientIndication[] =
-      "\0\0"                      // key (0x0000, origin)
-      "\0\x18"                    // length
-      "https://test-origin.test"  // value
-      "\0\x01"                    // key (0x0001, path)
-      "\0\x01"                    // length
-      "/";                        // value
-
-  EXPECT_CALL(visitor_, OnSessionReady(_));
-  Connect();
-  EXPECT_TRUE(session_->IsSessionReady());
-
-  QuicStream* client_indication_stream;
-  client_indication_stream =
-      QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
-          .get();
-  ASSERT_TRUE(client_indication_stream != nullptr);
-  const std::string client_indication = DataInStream(client_indication_stream);
-  const std::string expected_client_indication{
-      kTestOriginClientIndication,
-      ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
-  EXPECT_EQ(client_indication, expected_client_indication);
-}
-
-TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
-  constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
-  constexpr char kTestOriginClientIndication[] =
-      "\0\0"                      // key (0x0000, origin)
-      "\0\x18"                    // length
-      "https://test-origin.test"  // value
-      "\0\x01"                    // key (0x0001, path)
-      "\0\x14"                    // length
-      "/foo/bar?hello=world";     // value
-
-  CreateSession(GetTestOrigin(), kSuffix);
-  Connect();
-  EXPECT_TRUE(session_->IsSessionReady());
-
-  QuicStream* client_indication_stream;
-  client_indication_stream =
-      QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
-          .get();
-  ASSERT_TRUE(client_indication_stream != nullptr);
-  const std::string client_indication = DataInStream(client_indication_stream);
-  const std::string expected_client_indication{
-      kTestOriginClientIndication,
-      ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
-  EXPECT_EQ(client_indication, expected_client_indication);
-}
-
-TEST_F(QuicTransportClientSessionTest, OriginTooLong) {
-  std::string long_string(68000, 'a');
-  GURL bad_origin_url{"https://" + long_string + ".example/"};
-  EXPECT_TRUE(bad_origin_url.is_valid());
-  CreateSession(url::Origin::Create(bad_origin_url), "");
-
-  EXPECT_QUIC_BUG(Connect(), "Client origin too long");
-}
-
-TEST_F(QuicTransportClientSessionTest, ReceiveNewStreams) {
-  Connect();
-  ASSERT_TRUE(session_->IsSessionReady());
-  ASSERT_TRUE(session_->AcceptIncomingUnidirectionalStream() == nullptr);
-
-  const QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(
-      session_->transport_version(), 0);
-  QuicStreamFrame frame(id, /*fin=*/false, /*offset=*/0, "test");
-  EXPECT_CALL(visitor_, OnIncomingUnidirectionalStreamAvailable()).Times(1);
-  session_->OnStreamFrame(frame);
-
-  QuicTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
-  ASSERT_TRUE(stream != nullptr);
-  EXPECT_EQ(stream->ReadableBytes(), 4u);
-  EXPECT_EQ(stream->id(), id);
-}
-
-TEST_F(QuicTransportClientSessionTest, ReceiveDatagram) {
-  EXPECT_CALL(visitor_, OnDatagramReceived(Eq("test")));
-  session_->OnMessageReceived("test");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_integration_test.cc b/quic/quic_transport/quic_transport_integration_test.cc
deleted file mode 100644
index 742fd46..0000000
--- a/quic/quic_transport/quic_transport_integration_test.cc
+++ /dev/null
@@ -1,417 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// An integration test that covers interactions between QuicTransport client and
-// server sessions.
-
-#include <memory>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_client_session.h"
-#include "quic/quic_transport/quic_transport_server_session.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/quic_endpoint_base.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "quic/tools/quic_transport_simple_server_session.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using simulator::QuicEndpointBase;
-using simulator::Simulator;
-using testing::_;
-using testing::Assign;
-using testing::Eq;
-
-url::Origin GetTestOrigin() {
-  constexpr char kTestOrigin[] = "https://test-origin.test";
-  GURL origin_url(kTestOrigin);
-  return url::Origin::Create(origin_url);
-}
-
-ParsedQuicVersionVector GetVersions() {
-  return {DefaultVersionForQuicTransport()};
-}
-
-class QuicTransportEndpointBase : public QuicEndpointBase {
- public:
-  QuicTransportEndpointBase(Simulator* simulator,
-                            const std::string& name,
-                            const std::string& peer_name,
-                            Perspective perspective)
-      : QuicEndpointBase(simulator, name, peer_name) {
-    QuicEnableVersion(DefaultVersionForQuicTransport());
-    connection_ = std::make_unique<QuicConnection>(
-        TestConnectionId(0x10), simulator::GetAddressFromName(name),
-        simulator::GetAddressFromName(peer_name), simulator,
-        simulator->GetAlarmFactory(), &writer_,
-        /*owns_writer=*/false, perspective, GetVersions());
-    connection_->SetSelfAddress(simulator::GetAddressFromName(name));
-  }
-};
-
-class QuicTransportClientEndpoint : public QuicTransportEndpointBase {
- public:
-  QuicTransportClientEndpoint(Simulator* simulator,
-                              const std::string& name,
-                              const std::string& peer_name,
-                              const QuicConfig& config,
-                              url::Origin origin,
-                              const std::string& path)
-      : QuicTransportEndpointBase(simulator,
-                                  name,
-                                  peer_name,
-                                  Perspective::IS_CLIENT),
-        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
-        session_(connection_.get(),
-                 nullptr,
-                 config,
-                 GetVersions(),
-                 GURL("quic-transport://test.example.com:50000" + path),
-                 &crypto_config_,
-                 origin,
-                 &visitor_,
-                 /*datagram_observer=*/nullptr) {
-    session_.Initialize();
-  }
-
-  QuicTransportClientSession* session() { return &session_; }
-  MockClientVisitor* visitor() { return &visitor_; }
-
- private:
-  QuicCryptoClientConfig crypto_config_;
-  MockClientVisitor visitor_;
-  QuicTransportClientSession session_;
-};
-
-class QuicTransportServerEndpoint : public QuicTransportEndpointBase {
- public:
-  QuicTransportServerEndpoint(Simulator* simulator,
-                              const std::string& name,
-                              const std::string& peer_name,
-                              const QuicConfig& config,
-                              std::vector<url::Origin> accepted_origins)
-      : QuicTransportEndpointBase(simulator,
-                                  name,
-                                  peer_name,
-                                  Perspective::IS_SERVER),
-        crypto_config_(QuicCryptoServerConfig::TESTING,
-                       QuicRandom::GetInstance(),
-                       crypto_test_utils::ProofSourceForTesting(),
-                       KeyExchangeSource::Default()),
-        compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
-        session_(connection_.get(),
-                 /*owns_connection=*/false,
-                 nullptr,
-                 config,
-                 GetVersions(),
-                 &crypto_config_,
-                 &compressed_certs_cache_,
-                 accepted_origins) {
-    session_.Initialize();
-  }
-
-  QuicTransportServerSession* session() { return &session_; }
-
- private:
-  QuicCryptoServerConfig crypto_config_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-  QuicTransportSimpleServerSession session_;
-};
-
-constexpr QuicBandwidth kClientBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(10000);
-constexpr QuicTime::Delta kClientPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(2);
-constexpr QuicBandwidth kServerBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(4000);
-constexpr QuicTime::Delta kServerPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(50);
-const QuicTime::Delta kTransferTime =
-    kClientBandwidth.TransferTime(kMaxOutgoingPacketSize) +
-    kServerBandwidth.TransferTime(kMaxOutgoingPacketSize);
-const QuicTime::Delta kRtt =
-    (kClientPropagationDelay + kServerPropagationDelay + kTransferTime) * 2;
-const QuicByteCount kBdp = kRtt * kServerBandwidth;
-
-constexpr QuicTime::Delta kDefaultTimeout = QuicTime::Delta::FromSeconds(3);
-
-class QuicTransportIntegrationTest : public QuicTest {
- public:
-  QuicTransportIntegrationTest()
-      : switch_(&simulator_, "Switch", 8, 2 * kBdp) {}
-
-  void CreateDefaultEndpoints(const std::string& path) {
-    client_ = std::make_unique<QuicTransportClientEndpoint>(
-        &simulator_, "Client", "Server", client_config_, GetTestOrigin(), path);
-    server_ = std::make_unique<QuicTransportServerEndpoint>(
-        &simulator_, "Server", "Client", server_config_, accepted_origins_);
-  }
-
-  void WireUpEndpoints() {
-    client_link_ = std::make_unique<simulator::SymmetricLink>(
-        client_.get(), switch_.port(1), kClientBandwidth,
-        kClientPropagationDelay);
-    server_link_ = std::make_unique<simulator::SymmetricLink>(
-        server_.get(), switch_.port(2), kServerBandwidth,
-        kServerPropagationDelay);
-  }
-
-  void RunHandshake() {
-    client_->session()->CryptoConnect();
-    bool result = simulator_.RunUntilOrTimeout(
-        [this]() {
-          return IsHandshakeDone(client_->session()) &&
-                 IsHandshakeDone(server_->session());
-        },
-        kDefaultTimeout);
-    EXPECT_TRUE(result);
-  }
-
- protected:
-  template <class Session>
-  static bool IsHandshakeDone(const Session* session) {
-    return session->IsSessionReady() || session->error() != QUIC_NO_ERROR;
-  }
-
-  QuicConfig client_config_ = DefaultQuicConfig();
-  QuicConfig server_config_ = DefaultQuicConfig();
-
-  Simulator simulator_;
-  simulator::Switch switch_;
-  std::unique_ptr<simulator::SymmetricLink> client_link_;
-  std::unique_ptr<simulator::SymmetricLink> server_link_;
-
-  std::unique_ptr<QuicTransportClientEndpoint> client_;
-  std::unique_ptr<QuicTransportServerEndpoint> server_;
-
-  std::vector<url::Origin> accepted_origins_ = {GetTestOrigin()};
-};
-
-TEST_F(QuicTransportIntegrationTest, SuccessfulHandshake) {
-  CreateDefaultEndpoints("/discard");
-  WireUpEndpoints();
-  EXPECT_CALL(*client_->visitor(), OnSessionReady(_));
-  RunHandshake();
-  EXPECT_TRUE(client_->session()->IsSessionReady());
-  EXPECT_TRUE(server_->session()->IsSessionReady());
-}
-
-TEST_F(QuicTransportIntegrationTest, OriginMismatch) {
-  accepted_origins_ = {url::Origin::Create(GURL{"https://wrong-origin.test"})};
-  CreateDefaultEndpoints("/discard");
-  WireUpEndpoints();
-  RunHandshake();
-  // Wait until the client receives CONNECTION_CLOSE.
-  simulator_.RunUntilOrTimeout(
-      [this]() { return !client_->session()->connection()->connected(); },
-      kDefaultTimeout);
-  EXPECT_TRUE(client_->session()->IsSessionReady());
-  EXPECT_FALSE(server_->session()->IsSessionReady());
-  EXPECT_FALSE(client_->session()->connection()->connected());
-  EXPECT_FALSE(server_->session()->connection()->connected());
-  EXPECT_THAT(client_->session()->error(),
-              IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
-  EXPECT_THAT(server_->session()->error(),
-              IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
-}
-
-TEST_F(QuicTransportIntegrationTest, SendOutgoingStreams) {
-  CreateDefaultEndpoints("/discard");
-  WireUpEndpoints();
-  RunHandshake();
-
-  std::vector<QuicTransportStream*> streams;
-  for (int i = 0; i < 10; i++) {
-    QuicTransportStream* stream =
-        client_->session()->OpenOutgoingUnidirectionalStream();
-    ASSERT_TRUE(stream->Write("test"));
-    streams.push_back(stream);
-  }
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() {
-        return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
-               10;
-      },
-      kDefaultTimeout));
-
-  for (QuicTransportStream* stream : streams) {
-    ASSERT_TRUE(stream->SendFin());
-  }
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() {
-        return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
-               0;
-      },
-      kDefaultTimeout));
-}
-
-TEST_F(QuicTransportIntegrationTest, EchoBidirectionalStreams) {
-  CreateDefaultEndpoints("/echo");
-  WireUpEndpoints();
-  RunHandshake();
-
-  QuicTransportStream* stream =
-      client_->session()->OpenOutgoingBidirectionalStream();
-  EXPECT_TRUE(stream->Write("Hello!"));
-
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [stream]() { return stream->ReadableBytes() == strlen("Hello!"); },
-      kDefaultTimeout));
-  std::string received;
-  WebTransportStream::ReadResult result = stream->Read(&received);
-  EXPECT_EQ(result.bytes_read, strlen("Hello!"));
-  EXPECT_FALSE(result.fin);
-  EXPECT_EQ(received, "Hello!");
-
-  EXPECT_TRUE(stream->SendFin());
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() {
-        return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
-               0;
-      },
-      kDefaultTimeout));
-}
-
-TEST_F(QuicTransportIntegrationTest, EchoUnidirectionalStreams) {
-  CreateDefaultEndpoints("/echo");
-  WireUpEndpoints();
-  RunHandshake();
-
-  // Send two streams, but only send FIN on the second one.
-  QuicTransportStream* stream1 =
-      client_->session()->OpenOutgoingUnidirectionalStream();
-  EXPECT_TRUE(stream1->Write("Stream One"));
-  QuicTransportStream* stream2 =
-      client_->session()->OpenOutgoingUnidirectionalStream();
-  EXPECT_TRUE(stream2->Write("Stream Two"));
-  EXPECT_TRUE(stream2->SendFin());
-
-  // Wait until a stream is received.
-  bool stream_received = false;
-  EXPECT_CALL(*client_->visitor(), OnIncomingUnidirectionalStreamAvailable())
-      .Times(2)
-      .WillRepeatedly(Assign(&stream_received, true));
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [&stream_received]() { return stream_received; }, kDefaultTimeout));
-
-  // Receive a reply stream and expect it to be the second one.
-  QuicTransportStream* reply =
-      client_->session()->AcceptIncomingUnidirectionalStream();
-  ASSERT_TRUE(reply != nullptr);
-  std::string buffer;
-  WebTransportStream::ReadResult result = reply->Read(&buffer);
-  EXPECT_GT(result.bytes_read, 0u);
-  EXPECT_TRUE(result.fin);
-  EXPECT_EQ(buffer, "Stream Two");
-
-  // Reset reply-related variables.
-  stream_received = false;
-  buffer = "";
-
-  // Send FIN on the first stream, and expect to receive it back.
-  EXPECT_TRUE(stream1->SendFin());
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [&stream_received]() { return stream_received; }, kDefaultTimeout));
-  reply = client_->session()->AcceptIncomingUnidirectionalStream();
-  ASSERT_TRUE(reply != nullptr);
-  result = reply->Read(&buffer);
-  EXPECT_GT(result.bytes_read, 0u);
-  EXPECT_TRUE(result.fin);
-  EXPECT_EQ(buffer, "Stream One");
-}
-
-TEST_F(QuicTransportIntegrationTest, EchoDatagram) {
-  CreateDefaultEndpoints("/echo");
-  WireUpEndpoints();
-  RunHandshake();
-
-  client_->session()->SendOrQueueDatagram(MemSliceFromString("test"));
-
-  bool datagram_received = false;
-  EXPECT_CALL(*client_->visitor(), OnDatagramReceived(Eq("test")))
-      .WillOnce(Assign(&datagram_received, true));
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [&datagram_received]() { return datagram_received; }, kDefaultTimeout));
-}
-
-// This test sets the datagram queue to an nearly-infinte queueing time, and
-// then sends 1000 datagrams.  We expect to receive most of them back, since the
-// datagrams would be paced out by the congestion controller.
-TEST_F(QuicTransportIntegrationTest, EchoALotOfDatagrams) {
-  CreateDefaultEndpoints("/echo");
-  WireUpEndpoints();
-  RunHandshake();
-
-  // Set the datagrams to effectively never expire.
-  client_->session()->SetDatagramMaxTimeInQueue(10000 * kRtt);
-  for (int i = 0; i < 1000; i++) {
-    client_->session()->SendOrQueueDatagram(MemSliceFromString(std::string(
-        client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
-  }
-
-  size_t received = 0;
-  EXPECT_CALL(*client_->visitor(), OnDatagramReceived(_))
-      .WillRepeatedly(
-          [&received](absl::string_view /*datagram*/) { received++; });
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [this]() { return client_->session()->datagram_queue()->empty(); },
-      3 * kServerBandwidth.TransferTime(1000 * kMaxOutgoingPacketSize)));
-  // Allow extra round-trips for the final flight of datagrams to arrive back.
-  simulator_.RunFor(2 * kRtt);
-
-  EXPECT_GT(received, 500u);
-  EXPECT_LT(received, 1000u);
-}
-
-TEST_F(QuicTransportIntegrationTest, OutgoingStreamFlowControlBlocked) {
-  server_config_.SetMaxUnidirectionalStreamsToSend(4);
-  CreateDefaultEndpoints("/discard");
-  WireUpEndpoints();
-  RunHandshake();
-
-  QuicTransportStream* stream;
-  // Note that since we've already used one stream for client indication, we can
-  // only send three streams at once.
-  for (int i = 0; i < 3; i++) {
-    ASSERT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
-    stream = client_->session()->OpenOutgoingUnidirectionalStream();
-    ASSERT_TRUE(stream != nullptr);
-    ASSERT_TRUE(stream->SendFin());
-  }
-  EXPECT_FALSE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
-
-  // Receiving FINs for the streams we've just opened will cause the server to
-  // let us open more streams.
-  bool can_create_new_stream = false;
-  EXPECT_CALL(*client_->visitor(), OnCanCreateNewOutgoingUnidirectionalStream())
-      .WillOnce(Assign(&can_create_new_stream, true));
-  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
-      [&can_create_new_stream]() { return can_create_new_stream; },
-      kDefaultTimeout));
-  EXPECT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_protocol.h b/quic/quic_transport/quic_transport_protocol.h
deleted file mode 100644
index 191d42c..0000000
--- a/quic/quic_transport/quic_transport_protocol.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
-
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_export.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// The ALPN used by QuicTransport.
-QUIC_EXPORT_PRIVATE inline const char* QuicTransportAlpn() {
-  return "wq-vvv-01";
-}
-
-// The stream ID on which the client indication is sent.
-QUIC_EXPORT_PRIVATE constexpr QuicStreamId ClientIndicationStream() {
-  return 2;
-}
-
-// The maximum allowed size of the client indication.
-QUIC_EXPORT_PRIVATE constexpr QuicByteCount ClientIndicationMaxSize() {
-  return 65536;
-}
-
-// The keys of the fields in the client indication.
-enum class QuicTransportClientIndicationKeys : uint16_t {
-  kOrigin = 0x0000,
-  kPath = 0x0001,
-};
-
-// Returns if the specified QUIC version can be used by QuicTransport.
-QUIC_EXPORT_PRIVATE constexpr bool IsVersionValidForQuicTransport(
-    const ParsedQuicVersion& version) {
-  return VersionSupportsMessageFrames(version.transport_version) &&
-         VersionHasIetfQuicFrames(version.transport_version) &&
-         version.handshake_protocol == PROTOCOL_TLS1_3;
-}
-
-// Returns default QUIC version used for QuicTransport.
-QUIC_EXPORT_PRIVATE inline ParsedQuicVersion DefaultVersionForQuicTransport() {
-  constexpr ParsedQuicVersion version = ParsedQuicVersion::Draft29();
-  static_assert(IsVersionValidForQuicTransport(version),
-                "Default QUIC version used by QuicTransport is invalid");
-  return version;
-}
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
diff --git a/quic/quic_transport/quic_transport_server_session.cc b/quic/quic_transport/quic_transport_server_session.cc
deleted file mode 100644
index f7c8c0f..0000000
--- a/quic/quic_transport/quic_transport_server_session.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/quic_transport_server_session.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/url_constants.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-namespace {
-class QuicTransportServerCryptoHelper
-    : public QuicCryptoServerStreamBase::Helper {
- public:
-  bool CanAcceptClientHello(const CryptoHandshakeMessage& /*message*/,
-                            const QuicSocketAddress& /*client_address*/,
-                            const QuicSocketAddress& /*peer_address*/,
-                            const QuicSocketAddress& /*self_address*/,
-                            std::string* /*error_details*/) const override {
-    return true;
-  }
-};
-
-}  // namespace
-
-QuicTransportServerSession::QuicTransportServerSession(
-    QuicConnection* connection,
-    Visitor* owner,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    ServerVisitor* visitor)
-    : QuicSession(connection,
-                  owner,
-                  config,
-                  supported_versions,
-                  /*num_expected_unidirectional_static_streams*/ 0),
-      visitor_(visitor) {
-  for (const ParsedQuicVersion& version : supported_versions) {
-    QUIC_BUG_IF(quic_bug_12025_1, version.handshake_protocol != PROTOCOL_TLS1_3)
-        << "QuicTransport requires TLS 1.3 handshake";
-  }
-
-  static QuicTransportServerCryptoHelper* helper =
-      new QuicTransportServerCryptoHelper();
-  crypto_stream_ = CreateCryptoServerStream(
-      crypto_config, compressed_certs_cache, this, helper);
-}
-
-QuicStream* QuicTransportServerSession::CreateIncomingStream(QuicStreamId id) {
-  if (id == ClientIndicationStream()) {
-    auto indication = std::make_unique<ClientIndication>(this);
-    ClientIndication* indication_ptr = indication.get();
-    ActivateStream(std::move(indication));
-    return indication_ptr;
-  }
-
-  auto stream = std::make_unique<QuicTransportStream>(id, this, this);
-  QuicTransportStream* stream_ptr = stream.get();
-  ActivateStream(std::move(stream));
-  OnIncomingDataStream(stream_ptr);
-  return stream_ptr;
-}
-
-QuicTransportServerSession::ClientIndication::ClientIndication(
-    QuicTransportServerSession* session)
-    : QuicStream(ClientIndicationStream(),
-                 session,
-                 /* is_static= */ false,
-                 StreamType::READ_UNIDIRECTIONAL),
-      session_(session) {}
-
-void QuicTransportServerSession::ClientIndication::OnDataAvailable() {
-  sequencer()->Read(&buffer_);
-  if (buffer_.size() > ClientIndicationMaxSize()) {
-    session_->connection()->CloseConnection(
-        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
-        absl::StrCat("Client indication size exceeds ",
-                     ClientIndicationMaxSize(), " bytes"),
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  if (sequencer()->IsClosed()) {
-    session_->ProcessClientIndication(buffer_);
-    OnFinRead();
-  }
-}
-
-bool QuicTransportServerSession::ClientIndicationParser::Parse() {
-  bool origin_received = false;
-  bool path_received = false;
-  while (!reader_.IsDoneReading()) {
-    uint16_t key;
-    if (!reader_.ReadUInt16(&key)) {
-      ParseError("Expected 16-bit key");
-      return false;
-    }
-
-    absl::string_view value;
-    if (!reader_.ReadStringPiece16(&value)) {
-      ParseError(absl::StrCat("Failed to read value for key ", key));
-      return false;
-    }
-
-    switch (static_cast<QuicTransportClientIndicationKeys>(key)) {
-      case QuicTransportClientIndicationKeys::kOrigin: {
-        GURL origin_url{std::string(value)};
-        if (!origin_url.is_valid()) {
-          Error("Unable to parse the specified origin");
-          return false;
-        }
-
-        url::Origin origin = url::Origin::Create(origin_url);
-        QUIC_DLOG(INFO) << "QuicTransport server received origin " << origin;
-        if (!session_->visitor_->CheckOrigin(origin)) {
-          Error("Origin check failed");
-          return false;
-        }
-        origin_received = true;
-        break;
-      }
-
-      case QuicTransportClientIndicationKeys::kPath: {
-        if (!ProcessPath(value)) {
-          return false;
-        }
-        path_received = true;
-        break;
-      }
-
-      default:
-        QUIC_DLOG(INFO) << "Unknown client indication key: " << key;
-        break;
-    }
-  }
-
-  if (!origin_received) {
-    Error("No origin received");
-    return false;
-  }
-  if (!path_received) {
-    Error("No path received");
-    return false;
-  }
-
-  return true;
-}
-
-bool QuicTransportServerSession::ClientIndicationParser::ProcessPath(
-    absl::string_view path) {
-  if (path.empty() || path[0] != '/') {
-    // https://tools.ietf.org/html/draft-vvv-webtransport-quic-01#section-3.2.2
-    Error("Path must begin with a '/'");
-    return false;
-  }
-
-  // TODO(b/145674008): use the SNI value from the handshake instead of the IP
-  // address.
-  std::string url_text =
-      absl::StrCat(url::kQuicTransportScheme, url::kStandardSchemeSeparator,
-                   session_->self_address().ToString(), path);
-  GURL url{url_text};
-  if (!url.is_valid()) {
-    Error("Invalid path specified");
-    return false;
-  }
-
-  if (!session_->visitor_->ProcessPath(url)) {
-    Error("Specified path rejected");
-    return false;
-  }
-  return true;
-}
-
-void QuicTransportServerSession::ClientIndicationParser::Error(
-    const std::string& error_message) {
-  session_->connection()->CloseConnection(
-      QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, error_message,
-      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuicTransportServerSession::ClientIndicationParser::ParseError(
-    absl::string_view error_message) {
-  Error(absl::StrCat("Failed to parse the client indication stream: ",
-                     error_message, reader_.DebugString()));
-}
-
-void QuicTransportServerSession::ProcessClientIndication(
-    absl::string_view indication) {
-  ClientIndicationParser parser(this, indication);
-  if (!parser.Parse()) {
-    return;
-  }
-  // Don't set the ready bit if we closed the connection due to any error
-  // beforehand.
-  if (!connection()->connected()) {
-    return;
-  }
-  ready_ = true;
-}
-
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_server_session.h b/quic/quic_transport/quic_transport_server_session.h
deleted file mode 100644
index 070cfdd..0000000
--- a/quic/quic_transport/quic_transport_server_session.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_session.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-// A server session for the QuicTransport protocol.
-class QUIC_EXPORT_PRIVATE QuicTransportServerSession
-    : public QuicSession,
-      public QuicTransportSessionInterface {
- public:
-  class QUIC_EXPORT_PRIVATE ServerVisitor {
-   public:
-    virtual ~ServerVisitor() {}
-
-    // Allows the server to decide whether the specified origin is allowed to
-    // connect to it.
-    virtual bool CheckOrigin(url::Origin origin) = 0;
-
-    // Indicates that the server received a path parameter from the client.  The
-    // path parameter is parsed, and can be retrived from url.path() and
-    // url.query().  If this method returns false, the connection is closed.
-    virtual bool ProcessPath(const GURL& url) = 0;
-  };
-
-  QuicTransportServerSession(QuicConnection* connection,
-                             Visitor* owner,
-                             const QuicConfig& config,
-                             const ParsedQuicVersionVector& supported_versions,
-                             const QuicCryptoServerConfig* crypto_config,
-                             QuicCompressedCertsCache* compressed_certs_cache,
-                             ServerVisitor* visitor);
-
-  std::vector<absl::string_view>::const_iterator SelectAlpn(
-      const std::vector<absl::string_view>& alpns) const override {
-    return std::find(alpns.cbegin(), alpns.cend(), QuicTransportAlpn());
-  }
-
-  bool ShouldKeepConnectionAlive() const override { return true; }
-
-  QuicCryptoServerStreamBase* GetMutableCryptoStream() override {
-    return crypto_stream_.get();
-  }
-  const QuicCryptoServerStreamBase* GetCryptoStream() const override {
-    return crypto_stream_.get();
-  }
-
-  // Returns true once the encryption has been established, the client
-  // indication has been received and the origin has been verified.  No
-  // application data will be read or written before the connection is ready.
-  // Once the connection becomes ready, this method will never return false.
-  bool IsSessionReady() const override { return ready_; }
-
-  QuicStream* CreateIncomingStream(QuicStreamId id) override;
-  QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
-    QUIC_BUG(quic_bug_10884_1)
-        << "QuicTransportServerSession::CreateIncomingStream("
-           "PendingStream) not implemented";
-    return nullptr;
-  }
-
- protected:
-  class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
-   public:
-    explicit ClientIndication(QuicTransportServerSession* session);
-    void OnDataAvailable() override;
-
-   private:
-    QuicTransportServerSession* session_;
-    std::string buffer_;
-  };
-
-  // Utility class for parsing the client indication.
-  class QUIC_EXPORT_PRIVATE ClientIndicationParser {
-   public:
-    ClientIndicationParser(QuicTransportServerSession* session,
-                           absl::string_view indication)
-        : session_(session), reader_(indication) {}
-
-    // Parses the specified indication.  Automatically closes the connection
-    // with detailed error if parsing fails.  Returns true on success, false on
-    // failure.
-    bool Parse();
-
-   private:
-    void Error(const std::string& error_message);
-    void ParseError(absl::string_view error_message);
-
-    // Processes the path portion of the client indication.
-    bool ProcessPath(absl::string_view path);
-
-    QuicTransportServerSession* session_;
-    QuicDataReader reader_;
-  };
-
-  // Parses and processes the client indication as described in
-  // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
-  void ProcessClientIndication(absl::string_view indication);
-
-  virtual void OnIncomingDataStream(QuicTransportStream* /*stream*/) {}
-
-  std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
-  bool ready_ = false;
-  ServerVisitor* visitor_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
diff --git a/quic/quic_transport/quic_transport_server_session_test.cc b/quic/quic_transport/quic_transport_server_session_test.cc
deleted file mode 100644
index 159f886..0000000
--- a/quic/quic_transport/quic_transport_server_session_test.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/quic_transport_server_session.h"
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/crypto/quic_compressed_certs_cache.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::AnyNumber;
-using testing::DoAll;
-using testing::HasSubstr;
-using testing::Return;
-using testing::SaveArg;
-
-constexpr char kTestOrigin[] = "https://test-origin.test";
-constexpr char kTestOriginClientIndication[] =
-    "\0\0"                      // key (0x0000, origin)
-    "\0\x18"                    // length
-    "https://test-origin.test"  // value
-    "\0\x01"                    // key (0x0001, path)
-    "\0\x05"                    // length
-    "/test";                    // value
-const url::Origin GetTestOrigin() {
-  return url::Origin::Create(GURL(kTestOrigin));
-}
-const std::string GetTestOriginClientIndication() {
-  return std::string(kTestOriginClientIndication,
-                     sizeof(kTestOriginClientIndication) - 1);
-}
-
-ParsedQuicVersionVector GetVersions() {
-  return {DefaultVersionForQuicTransport()};
-}
-
-class QuicTransportServerSessionTest : public QuicTest {
- public:
-  QuicTransportServerSessionTest()
-      : connection_(&helper_,
-                    &alarm_factory_,
-                    Perspective::IS_SERVER,
-                    GetVersions()),
-        crypto_config_(QuicCryptoServerConfig::TESTING,
-                       QuicRandom::GetInstance(),
-                       crypto_test_utils::ProofSourceForTesting(),
-                       KeyExchangeSource::Default()),
-        compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
-    QuicEnableVersion(DefaultVersionForQuicTransport());
-    connection_.AdvanceTime(QuicTime::Delta::FromSeconds(100000));
-    crypto_test_utils::SetupCryptoServerConfigForTest(
-        helper_.GetClock(), helper_.GetRandomGenerator(), &crypto_config_);
-    session_ = std::make_unique<QuicTransportServerSession>(
-        &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
-        &crypto_config_, &compressed_certs_cache_, &visitor_);
-    session_->Initialize();
-    crypto_stream_ = session_->GetMutableCryptoStream();
-    ON_CALL(visitor_, ProcessPath(_))
-        .WillByDefault(DoAll(SaveArg<0>(&path_), Return(true)));
-  }
-
-  void Connect() {
-    crypto_test_utils::FakeClientOptions options;
-    options.only_tls_versions = true;
-    crypto_test_utils::HandshakeWithFakeClient(
-        &helper_, &alarm_factory_, &connection_, crypto_stream_,
-        QuicServerId("test.example.com", 443), options, QuicTransportAlpn());
-  }
-
-  void ReceiveIndication(absl::string_view indication) {
-    QUIC_LOG(INFO) << "Receiving indication: "
-                   << quiche::QuicheTextUtils::HexDump(indication);
-    constexpr size_t kChunkSize = 1024;
-    // Shard the indication, since some of the tests cause it to not fit into a
-    // single frame.
-    for (size_t i = 0; i < indication.size(); i += kChunkSize) {
-      QuicStreamFrame frame(ClientIndicationStream(), /*fin=*/false, i,
-                            indication.substr(i, i + kChunkSize));
-      session_->OnStreamFrame(frame);
-    }
-    session_->OnStreamFrame(QuicStreamFrame(ClientIndicationStream(),
-                                            /*fin=*/true, indication.size(),
-                                            absl::string_view()));
-  }
-
-  void ReceiveIndicationWithPath(absl::string_view path) {
-    constexpr char kTestOriginClientIndicationPrefix[] =
-        "\0\0"                      // key (0x0000, origin)
-        "\0\x18"                    // length
-        "https://test-origin.test"  // value
-        "\0\x01";                   // key (0x0001, path)
-    std::string indication{kTestOriginClientIndicationPrefix,
-                           sizeof(kTestOriginClientIndicationPrefix) - 1};
-    indication.push_back(static_cast<char>(path.size() >> 8));
-    indication.push_back(static_cast<char>(path.size() & 0xff));
-    indication += std::string{path};
-    ReceiveIndication(indication);
-  }
-
- protected:
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnectionHelper helper_;
-
-  PacketSavingConnection connection_;
-  QuicCryptoServerConfig crypto_config_;
-  std::unique_ptr<QuicTransportServerSession> session_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-  testing::NiceMock<MockServerVisitor> visitor_;
-  QuicCryptoServerStreamBase* crypto_stream_;
-  GURL path_;
-};
-
-TEST_F(QuicTransportServerSessionTest, SuccessfulHandshake) {
-  Connect();
-
-  url::Origin origin;
-  EXPECT_CALL(visitor_, CheckOrigin(_))
-      .WillOnce(DoAll(SaveArg<0>(&origin), Return(true)));
-  ReceiveIndication(GetTestOriginClientIndication());
-  EXPECT_TRUE(session_->IsSessionReady());
-  EXPECT_EQ(origin, GetTestOrigin());
-  EXPECT_EQ(path_.path(), "/test");
-}
-
-TEST_F(QuicTransportServerSessionTest, PiecewiseClientIndication) {
-  Connect();
-  size_t i = 0;
-  for (; i < sizeof(kTestOriginClientIndication) - 2; i++) {
-    QuicStreamFrame frame(
-        ClientIndicationStream(), false, i,
-        absl::string_view(&kTestOriginClientIndication[i], 1));
-    session_->OnStreamFrame(frame);
-  }
-
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  QuicStreamFrame last_frame(
-      ClientIndicationStream(), true, i,
-      absl::string_view(&kTestOriginClientIndication[i], 1));
-  session_->OnStreamFrame(last_frame);
-  EXPECT_TRUE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, OriginRejected) {
-  Connect();
-  EXPECT_CALL(connection_,
-              CloseConnection(_, HasSubstr("Origin check failed"), _));
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(false));
-  ReceiveIndication(GetTestOriginClientIndication());
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-std::string MakeUnknownField(absl::string_view payload) {
-  std::string buffer;
-  buffer.resize(payload.size() + 4);
-  QuicDataWriter writer(buffer.size(), &buffer[0]);
-  EXPECT_TRUE(writer.WriteUInt16(0xffff));
-  EXPECT_TRUE(writer.WriteUInt16(payload.size()));
-  EXPECT_TRUE(writer.WriteStringPiece(payload));
-  EXPECT_EQ(writer.remaining(), 0u);
-  return buffer;
-}
-
-TEST_F(QuicTransportServerSessionTest, SkipUnusedFields) {
-  Connect();
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  ReceiveIndication(GetTestOriginClientIndication() +
-                    MakeUnknownField("foobar"));
-  EXPECT_TRUE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, SkipLongUnusedFields) {
-  const size_t bytes =
-      ClientIndicationMaxSize() - GetTestOriginClientIndication().size() - 4;
-  Connect();
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  ReceiveIndication(GetTestOriginClientIndication() +
-                    MakeUnknownField(std::string(bytes, 'a')));
-  EXPECT_TRUE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, ClientIndicationTooLong) {
-  Connect();
-  EXPECT_CALL(
-      connection_,
-      CloseConnection(_, HasSubstr("Client indication size exceeds"), _))
-      .Times(AnyNumber());
-  ReceiveIndication(GetTestOriginClientIndication() +
-                    MakeUnknownField(std::string(65534, 'a')));
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, NoOrigin) {
-  Connect();
-  EXPECT_CALL(connection_, CloseConnection(_, HasSubstr("No origin"), _));
-  ReceiveIndication(MakeUnknownField("foobar"));
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, EmptyClientIndication) {
-  Connect();
-  EXPECT_CALL(connection_, CloseConnection(_, HasSubstr("No origin"), _));
-  ReceiveIndication("");
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, MalformedIndicationHeader) {
-  Connect();
-  EXPECT_CALL(connection_,
-              CloseConnection(_, HasSubstr("Expected 16-bit key"), _));
-  ReceiveIndication("\xff");
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, FieldTooShort) {
-  Connect();
-  EXPECT_CALL(
-      connection_,
-      CloseConnection(_, HasSubstr("Failed to read value for key 257"), _));
-  ReceiveIndication("\x01\x01\x01\x01");
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, InvalidOrigin) {
-  const std::string kEmptyOriginIndication(4, '\0');
-  Connect();
-  EXPECT_CALL(
-      connection_,
-      CloseConnection(_, HasSubstr("Unable to parse the specified origin"), _));
-  ReceiveIndication(kEmptyOriginIndication);
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, PathWithQuery) {
-  Connect();
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  ReceiveIndicationWithPath("/test?foo=bar");
-  EXPECT_TRUE(session_->IsSessionReady());
-  EXPECT_EQ(path_.path(), "/test");
-  EXPECT_EQ(path_.query(), "foo=bar");
-}
-
-TEST_F(QuicTransportServerSessionTest, PathNormalization) {
-  Connect();
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  ReceiveIndicationWithPath("/foo/../bar");
-  EXPECT_TRUE(session_->IsSessionReady());
-  EXPECT_EQ(path_.path(), "/bar");
-}
-
-TEST_F(QuicTransportServerSessionTest, EmptyPath) {
-  Connect();
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  EXPECT_CALL(connection_,
-              CloseConnection(_, HasSubstr("Path must begin with a '/'"), _));
-  ReceiveIndicationWithPath("");
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-TEST_F(QuicTransportServerSessionTest, UnprefixedPath) {
-  Connect();
-  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
-  EXPECT_CALL(connection_,
-              CloseConnection(_, HasSubstr("Path must begin with a '/'"), _));
-  ReceiveIndicationWithPath("test");
-  EXPECT_FALSE(session_->IsSessionReady());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_session_interface.h b/quic/quic_transport/quic_transport_session_interface.h
deleted file mode 100644
index d08aa6c..0000000
--- a/quic/quic_transport/quic_transport_session_interface.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
-
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// Shared interface between QuicTransportClientSession and
-// QuicTransportServerSession.
-class QUIC_EXPORT_PRIVATE QuicTransportSessionInterface {
- public:
-  virtual ~QuicTransportSessionInterface() {}
-
-  // Indicates whether the client indication has been sent/received and the
-  // connection is thus ready to send/receive application data.  Note that the
-  // expectation for this API is that once it becomes true, it will never
-  // transition to false.
-  virtual bool IsSessionReady() const = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
diff --git a/quic/quic_transport/quic_transport_stream.cc b/quic/quic_transport/quic_transport_stream.cc
deleted file mode 100644
index a66f24c..0000000
--- a/quic/quic_transport/quic_transport_stream.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/quic_transport_stream.h"
-
-#include <sys/types.h>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-QuicTransportStream::QuicTransportStream(
-    QuicStreamId id,
-    QuicSession* session,
-    QuicTransportSessionInterface* session_interface)
-    : QuicStream(id,
-                 session,
-                 /*is_static=*/false,
-                 QuicUtils::GetStreamType(id,
-                                          session->connection()->perspective(),
-                                          session->IsIncomingStream(id),
-                                          session->version())),
-      adapter_(session, this, sequencer()),
-      session_interface_(session_interface) {}
-
-WebTransportStream::ReadResult QuicTransportStream::Read(char* buffer,
-                                                         size_t buffer_size) {
-  if (!session_interface_->IsSessionReady()) {
-    return ReadResult{0, false};
-  }
-
-  return adapter_.Read(buffer, buffer_size);
-}
-
-WebTransportStream::ReadResult QuicTransportStream::Read(std::string* output) {
-  if (!session_interface_->IsSessionReady()) {
-    return ReadResult{0, false};
-  }
-
-  return adapter_.Read(output);
-}
-
-bool QuicTransportStream::Write(absl::string_view data) {
-  if (!CanWrite()) {
-    return false;
-  }
-
-  return adapter_.Write(data);
-}
-
-bool QuicTransportStream::SendFin() {
-  if (!CanWrite()) {
-    return false;
-  }
-
-  return adapter_.SendFin();
-}
-
-bool QuicTransportStream::CanWrite() const {
-  return session_interface_->IsSessionReady() && adapter_.CanWrite();
-}
-
-size_t QuicTransportStream::ReadableBytes() const {
-  if (!session_interface_->IsSessionReady()) {
-    return 0;
-  }
-
-  return adapter_.ReadableBytes();
-}
-
-void QuicTransportStream::OnDataAvailable() {
-  adapter_.OnDataAvailable();
-}
-
-void QuicTransportStream::OnCanWriteNewData() {
-  // Ensure the origin check has been completed, as the stream can be notified
-  // about being writable before that.
-  if (!CanWrite()) {
-    return;
-  }
-  adapter_.OnCanWriteNewData();
-}
-
-}  // namespace quic
diff --git a/quic/quic_transport/quic_transport_stream.h b/quic/quic_transport/quic_transport_stream.h
deleted file mode 100644
index 5d574af..0000000
--- a/quic/quic_transport/quic_transport_stream.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
-#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
-
-#include <cstddef>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/web_transport_stream_adapter.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-
-namespace quic {
-
-// QuicTransportStream is an extension of QuicStream that provides I/O interface
-// that is safe to use in the QuicTransport context.  The interface ensures no
-// application data is processed before the client indication is processed.
-class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream,
-                                                public WebTransportStream {
- public:
-  QuicTransportStream(QuicStreamId id,
-                      QuicSession* session,
-                      QuicTransportSessionInterface* session_interface);
-
-  // Reads at most |buffer_size| bytes into |buffer| and returns the number of
-  // bytes actually read.
-  ReadResult Read(char* buffer, size_t buffer_size) override;
-  // Reads all available data and appends it to the end of |output|.
-  ReadResult Read(std::string* output) override;
-  // Writes |data| into the stream.  Returns true on success.
-  ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
-  // Sends the FIN on the stream.  Returns true on success.
-  ABSL_MUST_USE_RESULT bool SendFin() override;
-
-  // Indicates whether it is possible to write into stream right now.
-  bool CanWrite() const override;
-  // Indicates the number of bytes that can be read from the stream.
-  size_t ReadableBytes() const override;
-
-  // QuicSession method implementations.
-  void OnDataAvailable() override;
-  void OnCanWriteNewData() override;
-
-  QuicStreamId GetStreamId() const override { return id(); }
-
-  void ResetWithUserCode(WebTransportStreamError /*error*/) override {
-    adapter_.ResetWithUserCode(0);
-  }
-  void ResetDueToInternalError() override {
-    adapter_.ResetDueToInternalError();
-  }
-  void SendStopSending(WebTransportStreamError /*error*/) override {
-    adapter_.SendStopSending(0);
-  }
-  void MaybeResetDueToStreamObjectGone() override {
-    adapter_.MaybeResetDueToStreamObjectGone();
-  }
-
-  WebTransportStreamVisitor* visitor() override { return adapter_.visitor(); }
-  void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
-    adapter_.SetVisitor(std::move(visitor));
-  }
-
- protected:
-  // Hide the methods that allow writing data without checking IsSessionReady().
-  using QuicStream::WriteMemSlices;
-  using QuicStream::WriteOrBufferData;
-
-  void MaybeNotifyFinRead();
-
-  WebTransportStreamAdapter adapter_;
-  QuicTransportSessionInterface* session_interface_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
diff --git a/quic/quic_transport/quic_transport_stream_test.cc b/quic/quic_transport/quic_transport_stream_test.cc
deleted file mode 100644
index b93e0eb..0000000
--- a/quic/quic_transport/quic_transport_stream_test.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/quic_transport/quic_transport_stream.h"
-
-#include <memory>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/frames/quic_window_update_frame.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_session_interface.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/quic_transport_test_tools.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-using testing::_;
-using testing::Return;
-
-ParsedQuicVersionVector GetVersions() {
-  return {DefaultVersionForQuicTransport()};
-}
-
-class MockQuicTransportSessionInterface : public QuicTransportSessionInterface {
- public:
-  MOCK_METHOD(bool, IsSessionReady, (), (const, override));
-};
-
-class QuicTransportStreamTest : public QuicTest {
- public:
-  QuicTransportStreamTest()
-      : connection_(new MockQuicConnection(&helper_,
-                                           &alarm_factory_,
-                                           Perspective::IS_CLIENT,
-                                           GetVersions())),
-        session_(connection_) {
-    QuicEnableVersion(DefaultVersionForQuicTransport());
-    session_.Initialize();
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    stream_ = new QuicTransportStream(0, &session_, &interface_);
-    session_.ActivateStream(absl::WrapUnique(stream_));
-
-    auto visitor = std::make_unique<MockStreamVisitor>();
-    visitor_ = visitor.get();
-    stream_->SetVisitor(std::move(visitor));
-  }
-
-  void ReceiveStreamData(absl::string_view data, QuicStreamOffset offset) {
-    QuicStreamFrame frame(0, false, offset, data);
-    stream_->OnStreamFrame(frame);
-  }
-
- protected:
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnectionHelper helper_;
-
-  MockQuicConnection* connection_;  // Owned by |session_|.
-  MockQuicSession session_;
-  MockQuicTransportSessionInterface interface_;
-  QuicTransportStream* stream_;  // Owned by |session_|.
-  MockStreamVisitor* visitor_;   // Owned by |stream_|.
-};
-
-TEST_F(QuicTransportStreamTest, NotReady) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
-  ReceiveStreamData("test", 0);
-  EXPECT_EQ(stream_->ReadableBytes(), 0u);
-  EXPECT_FALSE(stream_->CanWrite());
-}
-
-TEST_F(QuicTransportStreamTest, ReadWhenNotReady) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
-  ReceiveStreamData("test", 0);
-  char buffer[4];
-  WebTransportStream::ReadResult result = stream_->Read(buffer, sizeof(buffer));
-  EXPECT_EQ(result.bytes_read, 0u);
-  EXPECT_FALSE(result.fin);
-}
-
-TEST_F(QuicTransportStreamTest, WriteWhenNotReady) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
-  EXPECT_FALSE(stream_->Write("test"));
-}
-
-TEST_F(QuicTransportStreamTest, Ready) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-  ReceiveStreamData("test", 0);
-  EXPECT_EQ(stream_->ReadableBytes(), 4u);
-  EXPECT_TRUE(stream_->CanWrite());
-  EXPECT_TRUE(stream_->Write("test"));
-}
-
-TEST_F(QuicTransportStreamTest, ReceiveData) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*visitor_, OnCanRead());
-  ReceiveStreamData("test", 0);
-
-  std::string buffer;
-  WebTransportStream::ReadResult result = stream_->Read(&buffer);
-  EXPECT_EQ(result.bytes_read, 4u);
-  EXPECT_FALSE(result.fin);
-  EXPECT_EQ(buffer, "test");
-}
-
-TEST_F(QuicTransportStreamTest, FinReadWithNoDataPending) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*visitor_, OnCanRead());
-
-  QuicStreamFrame frame(0, true, 0, "");
-  stream_->OnStreamFrame(frame);
-
-  std::string buffer;
-  WebTransportStream::ReadResult result = stream_->Read(&buffer);
-  EXPECT_EQ(result.bytes_read, 0u);
-  EXPECT_TRUE(result.fin);
-  EXPECT_EQ(buffer, "");
-}
-
-TEST_F(QuicTransportStreamTest, FinReadWithDataPending) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-
-  EXPECT_CALL(*visitor_, OnCanRead());
-  QuicStreamFrame frame(0, true, 0, "test");
-  stream_->OnStreamFrame(frame);
-
-  char buffer[2];
-  WebTransportStream::ReadResult result = stream_->Read(buffer, sizeof(buffer));
-  EXPECT_EQ(result.bytes_read, 2u);
-  EXPECT_FALSE(result.fin);
-  EXPECT_EQ(buffer[0], 't');
-  EXPECT_EQ(buffer[1], 'e');
-
-  result = stream_->Read(buffer, sizeof(buffer));
-  EXPECT_EQ(result.bytes_read, 2u);
-  EXPECT_TRUE(result.fin);
-  EXPECT_EQ(buffer[0], 's');
-  EXPECT_EQ(buffer[1], 't');
-}
-
-TEST_F(QuicTransportStreamTest, WritingTooMuchData) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-  ASSERT_TRUE(stream_->CanWrite());
-
-  std::string a_little_bit_of_data(128, 'A');
-  std::string a_lot_of_data(GetQuicFlag(FLAGS_quic_buffered_data_threshold) * 2,
-                            'a');
-
-  EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
-  EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
-  EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
-
-  EXPECT_TRUE(stream_->Write(a_lot_of_data));
-  EXPECT_FALSE(stream_->Write(a_lot_of_data));
-}
-
-TEST_F(QuicTransportStreamTest, CannotSendFinTwice) {
-  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
-  ASSERT_TRUE(stream_->CanWrite());
-
-  EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
-      .WillOnce(Return(QuicConsumedData(0, /*fin_consumed=*/true)));
-  EXPECT_TRUE(stream_->SendFin());
-  EXPECT_FALSE(stream_->CanWrite());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/bad_packet_writer.cc b/quic/test_tools/bad_packet_writer.cc
deleted file mode 100644
index dd164ba..0000000
--- a/quic/test_tools/bad_packet_writer.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/bad_packet_writer.h"
-
-namespace quic {
-namespace test {
-
-BadPacketWriter::BadPacketWriter(size_t packet_causing_write_error,
-                                 int error_code)
-    : packet_causing_write_error_(packet_causing_write_error),
-      error_code_(error_code) {}
-
-BadPacketWriter::~BadPacketWriter() {}
-
-WriteResult BadPacketWriter::WritePacket(const char* buffer,
-                                         size_t buf_len,
-                                         const QuicIpAddress& self_address,
-                                         const QuicSocketAddress& peer_address,
-                                         PerPacketOptions* options) {
-  if (error_code_ == 0 || packet_causing_write_error_ > 0) {
-    if (packet_causing_write_error_ > 0) {
-      --packet_causing_write_error_;
-    }
-    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
-                                                peer_address, options);
-  }
-  // It's time to cause write error.
-  int error_code = error_code_;
-  error_code_ = 0;
-  return WriteResult(WRITE_STATUS_ERROR, error_code);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/bad_packet_writer.h b/quic/test_tools/bad_packet_writer.h
deleted file mode 100644
index b04798d..0000000
--- a/quic/test_tools/bad_packet_writer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-namespace quic {
-
-namespace test {
-// This packet writer allows causing packet write error with specified error
-// code when writing a particular packet.
-class BadPacketWriter : public QuicPacketWriterWrapper {
- public:
-  BadPacketWriter(size_t packet_causing_write_error, int error_code);
-
-  ~BadPacketWriter() override;
-
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-
- private:
-  size_t packet_causing_write_error_;
-  int error_code_;
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc
deleted file mode 100644
index 30bf0a2..0000000
--- a/quic/test_tools/crypto_test_utils.cc
+++ /dev/null
@@ -1,862 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/crypto_test_utils.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/bn.h"
-#include "third_party/boringssl/src/include/openssl/ec.h"
-#include "third_party/boringssl/src/include/openssl/ecdsa.h"
-#include "third_party/boringssl/src/include/openssl/nid.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/channel_id.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_crypto_client_stream.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "common/test_tools/quiche_test_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace crypto_test_utils {
-
-namespace {
-
-using testing::_;
-
-// CryptoFramerVisitor is a framer visitor that records handshake messages.
-class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
- public:
-  CryptoFramerVisitor() : error_(false) {}
-
-  void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
-
-  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
-    messages_.push_back(message);
-  }
-
-  bool error() const { return error_; }
-
-  const std::vector<CryptoHandshakeMessage>& messages() const {
-    return messages_;
-  }
-
- private:
-  bool error_;
-  std::vector<CryptoHandshakeMessage> messages_;
-};
-
-// HexChar parses |c| as a hex character. If valid, it sets |*value| to the
-// value of the hex character and returns true. Otherwise it returns false.
-bool HexChar(char c, uint8_t* value) {
-  if (c >= '0' && c <= '9') {
-    *value = c - '0';
-    return true;
-  }
-  if (c >= 'a' && c <= 'f') {
-    *value = c - 'a' + 10;
-    return true;
-  }
-  if (c >= 'A' && c <= 'F') {
-    *value = c - 'A' + 10;
-    return true;
-  }
-  return false;
-}
-
-}  // anonymous namespace
-
-FakeClientOptions::FakeClientOptions() {}
-
-FakeClientOptions::~FakeClientOptions() {}
-
-namespace {
-// This class is used by GenerateFullCHLO() to extract SCID and STK from
-// REJ and to construct a full CHLO with these fields and given inchoate
-// CHLO.
-class FullChloGenerator {
- public:
-  FullChloGenerator(
-      QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
-      QuicSocketAddress client_addr, const QuicClock* clock,
-      ParsedQuicVersion version,
-      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-          signed_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      CryptoHandshakeMessage* out)
-      : crypto_config_(crypto_config),
-        server_addr_(server_addr),
-        client_addr_(client_addr),
-        clock_(clock),
-        version_(version),
-        signed_config_(signed_config),
-        compressed_certs_cache_(compressed_certs_cache),
-        out_(out),
-        params_(new QuicCryptoNegotiatedParameters) {}
-
-  class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
-   public:
-    explicit ValidateClientHelloCallback(FullChloGenerator* generator)
-        : generator_(generator) {}
-    void Run(quiche::QuicheReferenceCountedPointer<
-                 ValidateClientHelloResultCallback::Result>
-                 result,
-             std::unique_ptr<ProofSource::Details> /* details */) override {
-      generator_->ValidateClientHelloDone(std::move(result));
-    }
-
-   private:
-    FullChloGenerator* generator_;
-  };
-
-  std::unique_ptr<ValidateClientHelloCallback>
-  GetValidateClientHelloCallback() {
-    return std::make_unique<ValidateClientHelloCallback>(this);
-  }
-
- private:
-  void ValidateClientHelloDone(quiche::QuicheReferenceCountedPointer<
-                               ValidateClientHelloResultCallback::Result>
-                                   result) {
-    result_ = result;
-    crypto_config_->ProcessClientHello(
-        result_, /*reject_only=*/false, TestConnectionId(1), server_addr_,
-        client_addr_, version_, {version_}, clock_, QuicRandom::GetInstance(),
-        compressed_certs_cache_, params_, signed_config_,
-        /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
-        GetProcessClientHelloCallback());
-  }
-
-  class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
-   public:
-    explicit ProcessClientHelloCallback(FullChloGenerator* generator)
-        : generator_(generator) {}
-    void Run(QuicErrorCode error,
-             const std::string& error_details,
-             std::unique_ptr<CryptoHandshakeMessage> message,
-             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
-             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
-        override {
-      ASSERT_TRUE(message) << QuicErrorCodeToString(error) << " "
-                           << error_details;
-      generator_->ProcessClientHelloDone(std::move(message));
-    }
-
-   private:
-    FullChloGenerator* generator_;
-  };
-
-  std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
-    return std::make_unique<ProcessClientHelloCallback>(this);
-  }
-
-  void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> rej) {
-    // Verify output is a REJ.
-    EXPECT_THAT(rej->tag(), testing::Eq(kREJ));
-
-    QUIC_VLOG(1) << "Extract valid STK and SCID from\n" << rej->DebugString();
-    absl::string_view srct;
-    ASSERT_TRUE(rej->GetStringPiece(kSourceAddressTokenTag, &srct));
-
-    absl::string_view scfg;
-    ASSERT_TRUE(rej->GetStringPiece(kSCFG, &scfg));
-    std::unique_ptr<CryptoHandshakeMessage> server_config(
-        CryptoFramer::ParseMessage(scfg));
-
-    absl::string_view scid;
-    ASSERT_TRUE(server_config->GetStringPiece(kSCID, &scid));
-
-    *out_ = result_->client_hello;
-    out_->SetStringPiece(kSCID, scid);
-    out_->SetStringPiece(kSourceAddressTokenTag, srct);
-    uint64_t xlct = LeafCertHashForTesting();
-    out_->SetValue(kXLCT, xlct);
-  }
-
- protected:
-  QuicCryptoServerConfig* crypto_config_;
-  QuicSocketAddress server_addr_;
-  QuicSocketAddress client_addr_;
-  const QuicClock* clock_;
-  ParsedQuicVersion version_;
-  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
-  QuicCompressedCertsCache* compressed_certs_cache_;
-  CryptoHandshakeMessage* out_;
-
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-  quiche::QuicheReferenceCountedPointer<
-      ValidateClientHelloResultCallback::Result>
-      result_;
-};
-
-}  // namespace
-
-std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting() {
-  return std::make_unique<QuicCryptoServerConfig>(
-      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-      ProofSourceForTesting(), KeyExchangeSource::Default());
-}
-
-int HandshakeWithFakeServer(QuicConfig* server_quic_config,
-                            QuicCryptoServerConfig* crypto_config,
-                            MockQuicConnectionHelper* helper,
-                            MockAlarmFactory* alarm_factory,
-                            PacketSavingConnection* client_conn,
-                            QuicCryptoClientStreamBase* client,
-                            std::string alpn) {
-  auto* server_conn = new testing::NiceMock<PacketSavingConnection>(
-      helper, alarm_factory, Perspective::IS_SERVER,
-      ParsedVersionOfIndex(client_conn->supported_versions(), 0));
-
-  QuicCompressedCertsCache compressed_certs_cache(
-      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-  SetupCryptoServerConfigForTest(
-      server_conn->clock(), server_conn->random_generator(), crypto_config);
-
-  TestQuicSpdyServerSession server_session(
-      server_conn, *server_quic_config, client_conn->supported_versions(),
-      crypto_config, &compressed_certs_cache);
-  // Call SetServerApplicationStateForResumption so that the fake server
-  // supports 0-RTT in TLS.
-  server_session.Initialize();
-  server_session.GetMutableCryptoStream()
-      ->SetServerApplicationStateForResumption(
-          std::make_unique<ApplicationState>());
-  EXPECT_CALL(*server_session.helper(),
-              CanAcceptClientHello(testing::_, testing::_, testing::_,
-                                   testing::_, testing::_))
-      .Times(testing::AnyNumber());
-  EXPECT_CALL(*server_conn, OnCanWrite()).Times(testing::AnyNumber());
-  EXPECT_CALL(*client_conn, OnCanWrite()).Times(testing::AnyNumber());
-  EXPECT_CALL(*server_conn, SendCryptoData(_, _, _))
-      .Times(testing::AnyNumber());
-  EXPECT_CALL(server_session, SelectAlpn(_))
-      .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
-        return std::find(alpns.cbegin(), alpns.cend(), alpn);
-      });
-
-  // The client's handshake must have been started already.
-  QUICHE_CHECK_NE(0u, client_conn->encrypted_packets_.size());
-
-  CommunicateHandshakeMessages(client_conn, client, server_conn,
-                               server_session.GetMutableCryptoStream());
-  if (client_conn->connected() && server_conn->connected()) {
-    CompareClientAndServerKeys(client, server_session.GetMutableCryptoStream());
-  }
-
-  return client->num_sent_client_hellos();
-}
-
-int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
-                            MockAlarmFactory* alarm_factory,
-                            PacketSavingConnection* server_conn,
-                            QuicCryptoServerStreamBase* server,
-                            const QuicServerId& server_id,
-                            const FakeClientOptions& options,
-                            std::string alpn) {
-  // This function does not do version negotiation; read the supported versions
-  // directly from the server connection instead.
-  ParsedQuicVersionVector supported_versions =
-      server_conn->supported_versions();
-  if (options.only_tls_versions) {
-    supported_versions.erase(
-        std::remove_if(supported_versions.begin(), supported_versions.end(),
-                       [](const ParsedQuicVersion& version) {
-                         return version.handshake_protocol != PROTOCOL_TLS1_3;
-                       }),
-        supported_versions.end());
-    QUICHE_CHECK(!options.only_quic_crypto_versions);
-  } else if (options.only_quic_crypto_versions) {
-    supported_versions.erase(
-        std::remove_if(supported_versions.begin(), supported_versions.end(),
-                       [](const ParsedQuicVersion& version) {
-                         return version.handshake_protocol !=
-                                PROTOCOL_QUIC_CRYPTO;
-                       }),
-        supported_versions.end());
-  }
-  PacketSavingConnection* client_conn = new PacketSavingConnection(
-      helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
-  // Advance the time, because timers do not like uninitialized times.
-  client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-
-  QuicCryptoClientConfig crypto_config(ProofVerifierForTesting());
-  TestQuicSpdyClientSession client_session(client_conn, DefaultQuicConfig(),
-                                           supported_versions, server_id,
-                                           &crypto_config);
-
-  EXPECT_CALL(client_session, OnProofValid(testing::_))
-      .Times(testing::AnyNumber());
-  EXPECT_CALL(client_session, OnProofVerifyDetailsAvailable(testing::_))
-      .Times(testing::AnyNumber());
-  EXPECT_CALL(*client_conn, OnCanWrite()).Times(testing::AnyNumber());
-  if (!alpn.empty()) {
-    EXPECT_CALL(client_session, GetAlpnsToOffer())
-        .WillRepeatedly(testing::Return(std::vector<std::string>({alpn})));
-  } else {
-    EXPECT_CALL(client_session, GetAlpnsToOffer())
-        .WillRepeatedly(testing::Return(std::vector<std::string>(
-            {AlpnForVersion(client_conn->version())})));
-  }
-  client_session.GetMutableCryptoStream()->CryptoConnect();
-  QUICHE_CHECK_EQ(1u, client_conn->encrypted_packets_.size());
-
-  CommunicateHandshakeMessages(client_conn,
-                               client_session.GetMutableCryptoStream(),
-                               server_conn, server);
-
-  if (server->one_rtt_keys_available() && server->encryption_established()) {
-    CompareClientAndServerKeys(client_session.GetMutableCryptoStream(), server);
-  }
-
-  return client_session.GetCryptoStream()->num_sent_client_hellos();
-}
-
-void SetupCryptoServerConfigForTest(const QuicClock* clock,
-                                    QuicRandom* rand,
-                                    QuicCryptoServerConfig* crypto_config) {
-  QuicCryptoServerConfig::ConfigOptions options;
-  options.channel_id_enabled = true;
-  std::unique_ptr<CryptoHandshakeMessage> scfg =
-      crypto_config->AddDefaultConfig(rand, clock, options);
-}
-
-void SendHandshakeMessageToStream(QuicCryptoStream* stream,
-                                  const CryptoHandshakeMessage& message,
-                                  Perspective /*perspective*/) {
-  const QuicData& data = message.GetSerialized();
-  QuicSession* session = QuicStreamPeer::session(stream);
-  if (!QuicVersionUsesCryptoFrames(session->transport_version())) {
-    QuicStreamFrame frame(
-        QuicUtils::GetCryptoStreamId(session->transport_version()), false,
-        stream->crypto_bytes_read(), data.AsStringPiece());
-    stream->OnStreamFrame(frame);
-  } else {
-    EncryptionLevel level = session->connection()->last_decrypted_level();
-    QuicCryptoFrame frame(level, stream->BytesReadOnLevel(level),
-                          data.AsStringPiece());
-    stream->OnCryptoFrame(frame);
-  }
-}
-
-void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
-                                  QuicCryptoStream* client,
-                                  PacketSavingConnection* server_conn,
-                                  QuicCryptoStream* server) {
-  size_t client_i = 0, server_i = 0;
-  while (client_conn->connected() && server_conn->connected() &&
-         (!client->one_rtt_keys_available() ||
-          !server->one_rtt_keys_available())) {
-    ASSERT_GT(client_conn->encrypted_packets_.size(), client_i);
-    QUIC_LOG(INFO) << "Processing "
-                   << client_conn->encrypted_packets_.size() - client_i
-                   << " packets client->server";
-    MovePackets(client_conn, &client_i, server, server_conn,
-                Perspective::IS_SERVER);
-
-    if (client->one_rtt_keys_available() && server->one_rtt_keys_available() &&
-        server_conn->encrypted_packets_.size() == server_i) {
-      break;
-    }
-    ASSERT_GT(server_conn->encrypted_packets_.size(), server_i);
-    QUIC_LOG(INFO) << "Processing "
-                   << server_conn->encrypted_packets_.size() - server_i
-                   << " packets server->client";
-    MovePackets(server_conn, &server_i, client, client_conn,
-                Perspective::IS_CLIENT);
-  }
-}
-
-bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
-                                       QuicCryptoStream* client,
-                                       std::function<bool()> client_condition,
-                                       PacketSavingConnection* server_conn,
-                                       QuicCryptoStream* server,
-                                       std::function<bool()> server_condition) {
-  size_t client_next_packet_to_deliver =
-      client_conn->number_of_packets_delivered_;
-  size_t server_next_packet_to_deliver =
-      server_conn->number_of_packets_delivered_;
-  while (
-      client_conn->connected() && server_conn->connected() &&
-      (!client_condition() || !server_condition()) &&
-      (client_conn->encrypted_packets_.size() > client_next_packet_to_deliver ||
-       server_conn->encrypted_packets_.size() >
-           server_next_packet_to_deliver)) {
-    if (!server_condition()) {
-      QUIC_LOG(INFO) << "Processing "
-                     << client_conn->encrypted_packets_.size() -
-                            client_next_packet_to_deliver
-                     << " packets client->server";
-      MovePackets(client_conn, &client_next_packet_to_deliver, server,
-                  server_conn, Perspective::IS_SERVER);
-    }
-    if (!client_condition()) {
-      QUIC_LOG(INFO) << "Processing "
-                     << server_conn->encrypted_packets_.size() -
-                            server_next_packet_to_deliver
-                     << " packets server->client";
-      MovePackets(server_conn, &server_next_packet_to_deliver, client,
-                  client_conn, Perspective::IS_CLIENT);
-    }
-  }
-  client_conn->number_of_packets_delivered_ = client_next_packet_to_deliver;
-  server_conn->number_of_packets_delivered_ = server_next_packet_to_deliver;
-  bool result = client_condition() && server_condition();
-  if (!result) {
-    QUIC_LOG(INFO) << "CommunicateHandshakeMessagesUnti failed with state: "
-                      "client connected? "
-                   << client_conn->connected() << " server connected? "
-                   << server_conn->connected() << " client condition met? "
-                   << client_condition() << " server condition met? "
-                   << server_condition();
-  }
-  return result;
-}
-
-std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
-                                           QuicCryptoStream* client,
-                                           size_t client_i,
-                                           PacketSavingConnection* server_conn,
-                                           QuicCryptoStream* server,
-                                           size_t server_i) {
-  if (client_conn->encrypted_packets_.size() != client_i) {
-    QUIC_LOG(INFO) << "Processing "
-                   << client_conn->encrypted_packets_.size() - client_i
-                   << " packets client->server";
-    MovePackets(client_conn, &client_i, server, server_conn,
-                Perspective::IS_SERVER);
-  }
-
-  if (server_conn->encrypted_packets_.size() != server_i) {
-    QUIC_LOG(INFO) << "Processing "
-                   << server_conn->encrypted_packets_.size() - server_i
-                   << " packets server->client";
-    MovePackets(server_conn, &server_i, client, client_conn,
-                Perspective::IS_CLIENT);
-  }
-
-  return std::make_pair(client_i, server_i);
-}
-
-std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag) {
-  auto it = message.tag_value_map().find(tag);
-  if (it == message.tag_value_map().end()) {
-    return std::string();
-  }
-  return it->second;
-}
-
-uint64_t LeafCertHashForTesting() {
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
-  QuicSocketAddress server_address(QuicIpAddress::Any4(), 42);
-  QuicSocketAddress client_address(QuicIpAddress::Any4(), 43);
-  QuicCryptoProof proof;
-  std::unique_ptr<ProofSource> proof_source(ProofSourceForTesting());
-
-  class Callback : public ProofSource::Callback {
-   public:
-    Callback(bool* ok,
-             quiche::QuicheReferenceCountedPointer<ProofSource::Chain>* chain)
-        : ok_(ok), chain_(chain) {}
-
-    void Run(
-        bool ok,
-        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-        const QuicCryptoProof& /* proof */,
-        std::unique_ptr<ProofSource::Details> /* details */) override {
-      *ok_ = ok;
-      *chain_ = chain;
-    }
-
-   private:
-    bool* ok_;
-    quiche::QuicheReferenceCountedPointer<ProofSource::Chain>* chain_;
-  };
-
-  // Note: relies on the callback being invoked synchronously
-  bool ok = false;
-  proof_source->GetProof(
-      server_address, client_address, "", "",
-      AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
-      std::unique_ptr<ProofSource::Callback>(new Callback(&ok, &chain)));
-  if (!ok || chain->certs.empty()) {
-    QUICHE_DCHECK(false) << "Proof generation failed";
-    return 0;
-  }
-
-  return QuicUtils::FNV1a_64_Hash(chain->certs.at(0));
-}
-
-void FillInDummyReject(CryptoHandshakeMessage* rej) {
-  rej->set_tag(kREJ);
-
-  // Minimum SCFG that passes config validation checks.
-  // clang-format off
-  unsigned char scfg[] = {
-    // SCFG
-    0x53, 0x43, 0x46, 0x47,
-    // num entries
-    0x01, 0x00,
-    // padding
-    0x00, 0x00,
-    // EXPY
-    0x45, 0x58, 0x50, 0x59,
-    // EXPY end offset
-    0x08, 0x00, 0x00, 0x00,
-    // Value
-    '1',  '2',  '3',  '4',
-    '5',  '6',  '7',  '8'
-  };
-  // clang-format on
-  rej->SetValue(kSCFG, scfg);
-  rej->SetStringPiece(kServerNonceTag, "SERVER_NONCE");
-  int64_t ttl = 2 * 24 * 60 * 60;
-  rej->SetValue(kSTTL, ttl);
-  std::vector<QuicTag> reject_reasons;
-  reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
-  rej->SetVector(kRREJ, reject_reasons);
-}
-
-namespace {
-
-#define RETURN_STRING_LITERAL(x) \
-  case x:                        \
-    return #x
-
-std::string EncryptionLevelString(EncryptionLevel level) {
-  switch (level) {
-    RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
-    RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
-    RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
-    RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
-    default:
-      return "";
-  }
-}
-
-void CompareCrypters(const QuicEncrypter* encrypter,
-                     const QuicDecrypter* decrypter,
-                     std::string label) {
-  if (encrypter == nullptr || decrypter == nullptr) {
-    ADD_FAILURE() << "Expected non-null crypters; have " << encrypter << " and "
-                  << decrypter << " for " << label;
-    return;
-  }
-  absl::string_view encrypter_key = encrypter->GetKey();
-  absl::string_view encrypter_iv = encrypter->GetNoncePrefix();
-  absl::string_view decrypter_key = decrypter->GetKey();
-  absl::string_view decrypter_iv = decrypter->GetNoncePrefix();
-  quiche::test::CompareCharArraysWithHexError(
-      label + " key", encrypter_key.data(), encrypter_key.length(),
-      decrypter_key.data(), decrypter_key.length());
-  quiche::test::CompareCharArraysWithHexError(
-      label + " iv", encrypter_iv.data(), encrypter_iv.length(),
-      decrypter_iv.data(), decrypter_iv.length());
-}
-
-}  // namespace
-
-void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
-                                QuicCryptoServerStreamBase* server) {
-  QuicFramer* client_framer = QuicConnectionPeer::GetFramer(
-      QuicStreamPeer::session(client)->connection());
-  QuicFramer* server_framer = QuicConnectionPeer::GetFramer(
-      QuicStreamPeer::session(server)->connection());
-  for (EncryptionLevel level :
-       {ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
-    SCOPED_TRACE(EncryptionLevelString(level));
-    const QuicEncrypter* client_encrypter(
-        QuicFramerPeer::GetEncrypter(client_framer, level));
-    const QuicDecrypter* server_decrypter(
-        QuicFramerPeer::GetDecrypter(server_framer, level));
-    if (level == ENCRYPTION_FORWARD_SECURE ||
-        !((level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
-           client_encrypter == nullptr) &&
-          (level == ENCRYPTION_ZERO_RTT || server_decrypter == nullptr))) {
-      CompareCrypters(client_encrypter, server_decrypter,
-                      "client " + EncryptionLevelString(level) + " write");
-    }
-    const QuicEncrypter* server_encrypter(
-        QuicFramerPeer::GetEncrypter(server_framer, level));
-    const QuicDecrypter* client_decrypter(
-        QuicFramerPeer::GetDecrypter(client_framer, level));
-    if (level == ENCRYPTION_FORWARD_SECURE ||
-        !(server_encrypter == nullptr &&
-          (level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
-           client_decrypter == nullptr))) {
-      CompareCrypters(server_encrypter, client_decrypter,
-                      "server " + EncryptionLevelString(level) + " write");
-    }
-  }
-
-  absl::string_view client_subkey_secret =
-      client->crypto_negotiated_params().subkey_secret;
-  absl::string_view server_subkey_secret =
-      server->crypto_negotiated_params().subkey_secret;
-  quiche::test::CompareCharArraysWithHexError(
-      "subkey secret", client_subkey_secret.data(),
-      client_subkey_secret.length(), server_subkey_secret.data(),
-      server_subkey_secret.length());
-}
-
-QuicTag ParseTag(const char* tagstr) {
-  const size_t len = strlen(tagstr);
-  QUICHE_CHECK_NE(0u, len);
-
-  QuicTag tag = 0;
-
-  if (tagstr[0] == '#') {
-    QUICHE_CHECK_EQ(static_cast<size_t>(1 + 2 * 4), len);
-    tagstr++;
-
-    for (size_t i = 0; i < 8; i++) {
-      tag <<= 4;
-
-      uint8_t v = 0;
-      QUICHE_CHECK(HexChar(tagstr[i], &v));
-      tag |= v;
-    }
-
-    return tag;
-  }
-
-  QUICHE_CHECK_LE(len, 4u);
-  for (size_t i = 0; i < 4; i++) {
-    tag >>= 8;
-    if (i < len) {
-      tag |= static_cast<uint32_t>(tagstr[i]) << 24;
-    }
-  }
-
-  return tag;
-}
-
-CryptoHandshakeMessage CreateCHLO(
-    std::vector<std::pair<std::string, std::string>> tags_and_values) {
-  return CreateCHLO(tags_and_values, -1);
-}
-
-CryptoHandshakeMessage CreateCHLO(
-    std::vector<std::pair<std::string, std::string>> tags_and_values,
-    int minimum_size_bytes) {
-  CryptoHandshakeMessage msg;
-  msg.set_tag(MakeQuicTag('C', 'H', 'L', 'O'));
-
-  if (minimum_size_bytes > 0) {
-    msg.set_minimum_size(minimum_size_bytes);
-  }
-
-  for (const auto& tag_and_value : tags_and_values) {
-    const std::string& tag = tag_and_value.first;
-    const std::string& value = tag_and_value.second;
-
-    const QuicTag quic_tag = ParseTag(tag.c_str());
-
-    size_t value_len = value.length();
-    if (value_len > 0 && value[0] == '#') {
-      // This is ascii encoded hex.
-      std::string hex_value =
-          absl::HexStringToBytes(absl::string_view(&value[1]));
-      msg.SetStringPiece(quic_tag, hex_value);
-      continue;
-    }
-    msg.SetStringPiece(quic_tag, value);
-  }
-
-  // The CryptoHandshakeMessage needs to be serialized and parsed to ensure
-  // that any padding is included.
-  std::unique_ptr<QuicData> bytes =
-      CryptoFramer::ConstructHandshakeMessage(msg);
-  std::unique_ptr<CryptoHandshakeMessage> parsed(
-      CryptoFramer::ParseMessage(bytes->AsStringPiece()));
-  QUICHE_CHECK(parsed);
-
-  return *parsed;
-}
-
-void MovePackets(PacketSavingConnection* source_conn,
-                 size_t* inout_packet_index,
-                 QuicCryptoStream* dest_stream,
-                 PacketSavingConnection* dest_conn,
-                 Perspective dest_perspective) {
-  SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
-  QuicFramerPeer::SetLastSerializedServerConnectionId(framer.framer(),
-                                                      TestConnectionId());
-
-  SimpleQuicFramer null_encryption_framer(source_conn->supported_versions(),
-                                          dest_perspective);
-  QuicFramerPeer::SetLastSerializedServerConnectionId(
-      null_encryption_framer.framer(), TestConnectionId());
-
-  size_t index = *inout_packet_index;
-  for (; index < source_conn->encrypted_packets_.size(); index++) {
-    if (!dest_conn->connected()) {
-      QUIC_LOG(INFO)
-          << "Destination connection disconnected. Skipping packet at index "
-          << index;
-      continue;
-    }
-    // In order to properly test the code we need to perform encryption and
-    // decryption so that the crypters latch when expected. The crypters are in
-    // |dest_conn|, but we don't want to try and use them there. Instead we swap
-    // them into |framer|, perform the decryption with them, and then swap ther
-    // back.
-    QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
-    QuicConnectionPeer::AddBytesReceived(
-        dest_conn, source_conn->encrypted_packets_[index]->length());
-    if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
-      // The framer will be unable to decrypt zero-rtt packets sent during
-      // handshake or forward-secure packets sent after the handshake is
-      // complete. Don't treat them as handshake packets.
-      QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
-      continue;
-    }
-    QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
-
-    // Install a packet flusher such that the packets generated by |dest_conn|
-    // in response to this packet are more likely to be coalesced and/or batched
-    // in the writer.
-    QuicConnection::ScopedPacketFlusher flusher(dest_conn);
-
-    dest_conn->OnDecryptedPacket(
-        source_conn->encrypted_packets_[index]->length(),
-        framer.last_decrypted_level());
-
-    if (dest_stream->handshake_protocol() == PROTOCOL_TLS1_3) {
-      // Try to process the packet with a framer that only has the NullDecrypter
-      // for decryption. If ProcessPacket succeeds, that means the packet was
-      // encrypted with the NullEncrypter. With the TLS handshaker in use, no
-      // packets should ever be encrypted with the NullEncrypter, instead
-      // they're encrypted with an obfuscation cipher based on QUIC version and
-      // connection ID.
-      QUIC_LOG(INFO) << "Attempting to decrypt with NullDecrypter: "
-                        "expect a decryption failure on the next log line.";
-      ASSERT_FALSE(null_encryption_framer.ProcessPacket(
-          *source_conn->encrypted_packets_[index]))
-          << "No TLS packets should be encrypted with the NullEncrypter";
-    }
-
-    // Since we're using QuicFramers separate from the connections to move
-    // packets, the QuicConnection never gets notified about what level the last
-    // packet was decrypted at. This is needed by TLS to know what encryption
-    // level was used for the data it's receiving, so we plumb this information
-    // from the SimpleQuicFramer back into the connection.
-    dest_conn->OnDecryptedPacket(
-        source_conn->encrypted_packets_[index]->length(),
-        framer.last_decrypted_level());
-
-    QuicConnectionPeer::SetCurrentPacket(
-        dest_conn, source_conn->encrypted_packets_[index]->AsStringPiece());
-    for (const auto& stream_frame : framer.stream_frames()) {
-      // Ignore stream frames that are sent on other streams in the crypto
-      // event.
-      if (stream_frame->stream_id == dest_stream->id()) {
-        dest_stream->OnStreamFrame(*stream_frame);
-      }
-    }
-    for (const auto& crypto_frame : framer.crypto_frames()) {
-      dest_stream->OnCryptoFrame(*crypto_frame);
-    }
-    if (!framer.connection_close_frames().empty() && dest_conn->connected()) {
-      dest_conn->OnConnectionCloseFrame(framer.connection_close_frames()[0]);
-    }
-  }
-  *inout_packet_index = index;
-
-  QuicConnectionPeer::SetCurrentPacket(dest_conn,
-                                       absl::string_view(nullptr, 0));
-}
-
-CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
-    const QuicClock* clock,
-    QuicTransportVersion version,
-    QuicCryptoServerConfig* crypto_config) {
-  // clang-format off
-  return CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"PUBS", GenerateClientPublicValuesHex().c_str()},
-       {"NONC", GenerateClientNonceHex(clock, crypto_config).c_str()},
-       {"VER\0", QuicVersionLabelToString(
-           CreateQuicVersionLabel(
-            ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version))).c_str()}},
-      kClientHelloMinimumSize);
-  // clang-format on
-}
-
-std::string GenerateClientNonceHex(const QuicClock* clock,
-                                   QuicCryptoServerConfig* crypto_config) {
-  QuicCryptoServerConfig::ConfigOptions old_config_options;
-  QuicCryptoServerConfig::ConfigOptions new_config_options;
-  old_config_options.id = "old-config-id";
-  crypto_config->AddDefaultConfig(QuicRandom::GetInstance(), clock,
-                                  old_config_options);
-  QuicServerConfigProtobuf primary_config = crypto_config->GenerateConfig(
-      QuicRandom::GetInstance(), clock, new_config_options);
-  primary_config.set_primary_time(clock->WallNow().ToUNIXSeconds());
-  std::unique_ptr<CryptoHandshakeMessage> msg =
-      crypto_config->AddConfig(primary_config, clock->WallNow());
-  absl::string_view orbit;
-  QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
-  std::string nonce;
-  CryptoUtils::GenerateNonce(clock->WallNow(), QuicRandom::GetInstance(), orbit,
-                             &nonce);
-  return ("#" + absl::BytesToHexString(nonce));
-}
-
-std::string GenerateClientPublicValuesHex() {
-  char public_value[32];
-  memset(public_value, 42, sizeof(public_value));
-  return ("#" + absl::BytesToHexString(
-                    absl::string_view(public_value, sizeof(public_value))));
-}
-
-void GenerateFullCHLO(
-    const CryptoHandshakeMessage& inchoate_chlo,
-    QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
-    QuicSocketAddress client_addr, QuicTransportVersion transport_version,
-    const QuicClock* clock,
-    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    CryptoHandshakeMessage* out) {
-  // Pass a inchoate CHLO.
-  FullChloGenerator generator(
-      crypto_config, server_addr, client_addr, clock,
-      ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version), signed_config,
-      compressed_certs_cache, out);
-  crypto_config->ValidateClientHello(
-      inchoate_chlo, client_addr, server_addr, transport_version, clock,
-      signed_config, generator.GetValidateClientHelloCallback());
-}
-
-}  // namespace crypto_test_utils
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/crypto_test_utils.h b/quic/test_tools/crypto_test_utils.h
deleted file mode 100644
index c92eb17..0000000
--- a/quic/test_tools/crypto_test_utils.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
-
-#include <cstdarg>
-#include <cstddef>
-#include <cstdint>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-class ProofSource;
-class ProofVerifier;
-class ProofVerifyContext;
-class QuicClock;
-class QuicConfig;
-class QuicCryptoClientStream;
-class QuicCryptoServerConfig;
-class QuicCryptoServerStreamBase;
-class QuicCryptoStream;
-class QuicRandom;
-class QuicServerId;
-
-namespace test {
-
-class PacketSavingConnection;
-
-namespace crypto_test_utils {
-
-// An interface for a source of callbacks. This is used for invoking
-// callbacks asynchronously.
-//
-// Call the RunPendingCallbacks method regularly to run the callbacks from
-// this source.
-class CallbackSource {
- public:
-  virtual ~CallbackSource() {}
-
-  // Runs pending callbacks from this source. If there is no pending
-  // callback, does nothing.
-  virtual void RunPendingCallbacks() = 0;
-};
-
-// FakeClientOptions bundles together a number of options for configuring
-// HandshakeWithFakeClient.
-struct FakeClientOptions {
-  FakeClientOptions();
-  ~FakeClientOptions();
-
-  // If only_tls_versions is set, then the client will only use TLS for the
-  // crypto handshake.
-  bool only_tls_versions = false;
-
-  // If only_quic_crypto_versions is set, then the client will only use
-  // PROTOCOL_QUIC_CRYPTO for the crypto handshake.
-  bool only_quic_crypto_versions = false;
-};
-
-// Returns a QuicCryptoServerConfig that is in a reasonable configuration to
-// pass into HandshakeWithFakeServer.
-std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting();
-
-// returns: the number of client hellos that the client sent.
-int HandshakeWithFakeServer(QuicConfig* server_quic_config,
-                            QuicCryptoServerConfig* crypto_config,
-                            MockQuicConnectionHelper* helper,
-                            MockAlarmFactory* alarm_factory,
-                            PacketSavingConnection* client_conn,
-                            QuicCryptoClientStreamBase* client,
-                            std::string alpn);
-
-// returns: the number of client hellos that the client sent.
-int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
-                            MockAlarmFactory* alarm_factory,
-                            PacketSavingConnection* server_conn,
-                            QuicCryptoServerStreamBase* server,
-                            const QuicServerId& server_id,
-                            const FakeClientOptions& options,
-                            std::string alpn);
-
-// SetupCryptoServerConfigForTest configures |crypto_config|
-// with sensible defaults for testing.
-void SetupCryptoServerConfigForTest(const QuicClock* clock,
-                                    QuicRandom* rand,
-                                    QuicCryptoServerConfig* crypto_config);
-
-// Sends the handshake message |message| to stream |stream| with the perspective
-// that the message is coming from |perspective|.
-void SendHandshakeMessageToStream(QuicCryptoStream* stream,
-                                  const CryptoHandshakeMessage& message,
-                                  Perspective perspective);
-
-// CommunicateHandshakeMessages moves messages from |client| to |server| and
-// back until |clients|'s handshake has completed.
-void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
-                                  QuicCryptoStream* client,
-                                  PacketSavingConnection* server_conn,
-                                  QuicCryptoStream* server);
-
-// CommunicateHandshakeMessagesUntil:
-// 1) Moves messages from |client| to |server| until |server_condition| is met.
-// 2) Moves messages from |server| to |client| until |client_condition| is met.
-// 3) Returns true if both conditions are met.
-// 4) Returns false if either connection is closed or there is no more packet to
-// deliver before both conditions are met.
-bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
-                                       QuicCryptoStream* client,
-                                       std::function<bool()> client_condition,
-                                       PacketSavingConnection* server_conn,
-                                       QuicCryptoStream* server,
-                                       std::function<bool()> server_condition);
-
-// AdvanceHandshake attempts to moves messages from |client| to |server| and
-// |server| to |client|. Returns the number of messages moved.
-std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
-                                           QuicCryptoStream* client,
-                                           size_t client_i,
-                                           PacketSavingConnection* server_conn,
-                                           QuicCryptoStream* server,
-                                           size_t server_i);
-
-// Returns the value for the tag |tag| in the tag value map of |message|.
-std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag);
-
-// Returns a new |ProofSource| that serves up test certificates.
-std::unique_ptr<ProofSource> ProofSourceForTesting();
-
-// Returns a new |ProofVerifier| that uses the QUIC testing root CA.
-std::unique_ptr<ProofVerifier> ProofVerifierForTesting();
-
-// Returns a hash of the leaf test certificate.
-uint64_t LeafCertHashForTesting();
-
-// Returns a |ProofVerifyContext| that must be used with the verifier
-// returned by |ProofVerifierForTesting|.
-std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting();
-
-// Creates a minimal dummy reject message that will pass the client-config
-// validation tests. This will include a server config, but no certs, proof
-// source address token, or server nonce.
-void FillInDummyReject(CryptoHandshakeMessage* rej);
-
-// ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be
-// in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex
-// format). It QUICHE_CHECK fails if there's a parse error.
-QuicTag ParseTag(const char* tagstr);
-
-// Message constructs a CHLO message from a provided vector of tag/value pairs.
-// The first of each pair is the tag of a tag/value and is given as an argument
-// to |ParseTag|. The second is the value of the tag/value pair and is either a
-// hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is
-// provided then the message will be padded to this minimum size.
-//
-//   CreateCHLO(
-//       {{"NOCE", "#11223344"},
-//        {"SNI", "www.example.com"}},
-//       optional_minimum_size_bytes);
-CryptoHandshakeMessage CreateCHLO(
-    std::vector<std::pair<std::string, std::string>> tags_and_values);
-CryptoHandshakeMessage CreateCHLO(
-    std::vector<std::pair<std::string, std::string>> tags_and_values,
-    int minimum_size_bytes);
-
-// MovePackets parses crypto handshake messages from packet number
-// |*inout_packet_index| through to the last packet (or until a packet fails
-// to decrypt) and has |dest_stream| process them. |*inout_packet_index| is
-// updated with an index one greater than the last packet processed.
-void MovePackets(PacketSavingConnection* source_conn,
-                 size_t* inout_packet_index,
-                 QuicCryptoStream* dest_stream,
-                 PacketSavingConnection* dest_conn,
-                 Perspective dest_perspective);
-
-// Return an inchoate CHLO with some basic tag value pairs.
-CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
-    const QuicClock* clock,
-    QuicTransportVersion version,
-    QuicCryptoServerConfig* crypto_config);
-
-// Takes a inchoate CHLO, returns a full CHLO in |out| which can pass
-// |crypto_config|'s validation.
-void GenerateFullCHLO(
-    const CryptoHandshakeMessage& inchoate_chlo,
-    QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
-    QuicSocketAddress client_addr, QuicTransportVersion transport_version,
-    const QuicClock* clock,
-    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    CryptoHandshakeMessage* out);
-
-void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
-                                QuicCryptoServerStreamBase* server);
-
-// Return a CHLO nonce in hexadecimal.
-std::string GenerateClientNonceHex(const QuicClock* clock,
-                                   QuicCryptoServerConfig* crypto_config);
-
-// Return a CHLO PUBS in hexadecimal.
-std::string GenerateClientPublicValuesHex();
-
-}  // namespace crypto_test_utils
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
diff --git a/quic/test_tools/crypto_test_utils_test.cc b/quic/test_tools/crypto_test_utils_test.cc
deleted file mode 100644
index 18bada5..0000000
--- a/quic/test_tools/crypto_test_utils_test.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/crypto_test_utils.h"
-
-#include <utility>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/crypto_server_config_proto.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-class ShloVerifier {
- public:
-  ShloVerifier(QuicCryptoServerConfig* crypto_config,
-               QuicSocketAddress server_addr, QuicSocketAddress client_addr,
-               const QuicClock* clock,
-               quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
-                   signed_config,
-               QuicCompressedCertsCache* compressed_certs_cache,
-               ParsedQuicVersion version)
-      : crypto_config_(crypto_config),
-        server_addr_(server_addr),
-        client_addr_(client_addr),
-        clock_(clock),
-        signed_config_(signed_config),
-        compressed_certs_cache_(compressed_certs_cache),
-        params_(new QuicCryptoNegotiatedParameters),
-        version_(version) {}
-
-  class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
-   public:
-    explicit ValidateClientHelloCallback(ShloVerifier* shlo_verifier)
-        : shlo_verifier_(shlo_verifier) {}
-    void Run(quiche::QuicheReferenceCountedPointer<
-                 ValidateClientHelloResultCallback::Result>
-                 result,
-             std::unique_ptr<ProofSource::Details> /* details */) override {
-      shlo_verifier_->ValidateClientHelloDone(result);
-    }
-
-   private:
-    ShloVerifier* shlo_verifier_;
-  };
-
-  std::unique_ptr<ValidateClientHelloCallback>
-  GetValidateClientHelloCallback() {
-    return std::make_unique<ValidateClientHelloCallback>(this);
-  }
-
- private:
-  void ValidateClientHelloDone(
-      const quiche::QuicheReferenceCountedPointer<
-          ValidateClientHelloResultCallback::Result>& result) {
-    result_ = result;
-    crypto_config_->ProcessClientHello(
-        result_, /*reject_only=*/false,
-        /*connection_id=*/TestConnectionId(1), server_addr_, client_addr_,
-        version_, AllSupportedVersions(), clock_, QuicRandom::GetInstance(),
-        compressed_certs_cache_, params_, signed_config_,
-        /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
-        GetProcessClientHelloCallback());
-  }
-
-  class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
-   public:
-    explicit ProcessClientHelloCallback(ShloVerifier* shlo_verifier)
-        : shlo_verifier_(shlo_verifier) {}
-    void Run(QuicErrorCode /*error*/,
-             const std::string& /*error_details*/,
-             std::unique_ptr<CryptoHandshakeMessage> message,
-             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
-             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
-        override {
-      shlo_verifier_->ProcessClientHelloDone(std::move(message));
-    }
-
-   private:
-    ShloVerifier* shlo_verifier_;
-  };
-
-  std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
-    return std::make_unique<ProcessClientHelloCallback>(this);
-  }
-
-  void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> message) {
-    // Verify output is a SHLO.
-    EXPECT_EQ(message->tag(), kSHLO)
-        << "Fail to pass validation. Get " << message->DebugString();
-  }
-
-  QuicCryptoServerConfig* crypto_config_;
-  QuicSocketAddress server_addr_;
-  QuicSocketAddress client_addr_;
-  const QuicClock* clock_;
-  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
-  QuicCompressedCertsCache* compressed_certs_cache_;
-
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-  quiche::QuicheReferenceCountedPointer<
-      ValidateClientHelloResultCallback::Result>
-      result_;
-
-  const ParsedQuicVersion version_;
-};
-
-class CryptoTestUtilsTest : public QuicTest {};
-
-TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) {
-  MockClock clock;
-  QuicCryptoServerConfig crypto_config(
-      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-      crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
-  QuicSocketAddress server_addr(QuicIpAddress::Any4(), 5);
-  QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1);
-  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config(
-      new QuicSignedServerConfig);
-  QuicCompressedCertsCache compressed_certs_cache(
-      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
-  CryptoHandshakeMessage full_chlo;
-
-  QuicCryptoServerConfig::ConfigOptions old_config_options;
-  old_config_options.id = "old-config-id";
-  crypto_config.AddDefaultConfig(QuicRandom::GetInstance(), &clock,
-                                 old_config_options);
-  QuicCryptoServerConfig::ConfigOptions new_config_options;
-  QuicServerConfigProtobuf primary_config = crypto_config.GenerateConfig(
-      QuicRandom::GetInstance(), &clock, new_config_options);
-  primary_config.set_primary_time(clock.WallNow().ToUNIXSeconds());
-  std::unique_ptr<CryptoHandshakeMessage> msg =
-      crypto_config.AddConfig(primary_config, clock.WallNow());
-  absl::string_view orbit;
-  ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit));
-  std::string nonce;
-  CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit,
-                             &nonce);
-  std::string nonce_hex = "#" + absl::BytesToHexString(nonce);
-
-  char public_value[32];
-  memset(public_value, 42, sizeof(public_value));
-  std::string pub_hex = "#" + absl::BytesToHexString(absl::string_view(
-                                  public_value, sizeof(public_value)));
-
-  // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
-  // first one from the list of supported versions.
-  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
-  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
-      transport_version = version.transport_version;
-      break;
-    }
-  }
-  ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
-
-  CryptoHandshakeMessage inchoate_chlo = crypto_test_utils::CreateCHLO(
-      {{"PDMD", "X509"},
-       {"AEAD", "AESG"},
-       {"KEXS", "C255"},
-       {"COPT", "SREJ"},
-       {"PUBS", pub_hex},
-       {"NONC", nonce_hex},
-       {"VER\0",
-        QuicVersionLabelToString(CreateQuicVersionLabel(
-            ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version)))}},
-      kClientHelloMinimumSize);
-
-  crypto_test_utils::GenerateFullCHLO(inchoate_chlo, &crypto_config,
-                                      server_addr, client_addr,
-                                      transport_version, &clock, signed_config,
-                                      &compressed_certs_cache, &full_chlo);
-  // Verify that full_chlo can pass crypto_config's verification.
-  ShloVerifier shlo_verifier(
-      &crypto_config, server_addr, client_addr, &clock, signed_config,
-      &compressed_certs_cache,
-      ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version));
-  crypto_config.ValidateClientHello(
-      full_chlo, client_addr, server_addr, transport_version, &clock,
-      signed_config, shlo_verifier.GetValidateClientHelloCallback());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/failing_proof_source.cc b/quic/test_tools/failing_proof_source.cc
deleted file mode 100644
index 8eb13db..0000000
--- a/quic/test_tools/failing_proof_source.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/failing_proof_source.h"
-
-#include "absl/strings/string_view.h"
-
-namespace quic {
-namespace test {
-
-void FailingProofSource::GetProof(const QuicSocketAddress& /*server_address*/,
-                                  const QuicSocketAddress& /*client_address*/,
-                                  const std::string& /*hostname*/,
-                                  const std::string& /*server_config*/,
-                                  QuicTransportVersion /*transport_version*/,
-                                  absl::string_view /*chlo_hash*/,
-                                  std::unique_ptr<Callback> callback) {
-  callback->Run(false, nullptr, QuicCryptoProof(), nullptr);
-}
-
-quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
-FailingProofSource::GetCertChain(const QuicSocketAddress& /*server_address*/,
-                                 const QuicSocketAddress& /*client_address*/,
-                                 const std::string& /*hostname*/,
-                                 bool* cert_matched_sni) {
-  *cert_matched_sni = false;
-  return quiche::QuicheReferenceCountedPointer<Chain>();
-}
-
-void FailingProofSource::ComputeTlsSignature(
-    const QuicSocketAddress& /*server_address*/,
-    const QuicSocketAddress& /*client_address*/,
-    const std::string& /*hostname*/,
-    uint16_t /*signature_algorithm*/,
-    absl::string_view /*in*/,
-    std::unique_ptr<SignatureCallback> callback) {
-  callback->Run(false, "", nullptr);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/failing_proof_source.h b/quic/test_tools/failing_proof_source.h
deleted file mode 100644
index 333bdc3..0000000
--- a/quic/test_tools/failing_proof_source.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
-#define QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-class FailingProofSource : public ProofSource {
- public:
-  void GetProof(const QuicSocketAddress& server_address,
-                const QuicSocketAddress& client_address,
-                const std::string& hostname,
-                const std::string& server_config,
-                QuicTransportVersion transport_version,
-                absl::string_view chlo_hash,
-                std::unique_ptr<Callback> callback) override;
-
-  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, const std::string& hostname,
-      bool* cert_matched_sni) override;
-
-  void ComputeTlsSignature(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      const std::string& hostname,
-      uint16_t signature_algorithm,
-      absl::string_view in,
-      std::unique_ptr<SignatureCallback> callback) override;
-
-  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
-      const override {
-    return {};
-  }
-
-  TicketCrypter* GetTicketCrypter() override { return nullptr; }
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
diff --git a/quic/test_tools/fake_proof_source.cc b/quic/test_tools/fake_proof_source.cc
deleted file mode 100644
index 2f30610..0000000
--- a/quic/test_tools/fake_proof_source.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/fake_proof_source.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/crypto_test_utils.h"
-
-namespace quic {
-namespace test {
-
-FakeProofSource::FakeProofSource()
-    : delegate_(crypto_test_utils::ProofSourceForTesting()) {}
-
-FakeProofSource::~FakeProofSource() {}
-
-FakeProofSource::PendingOp::~PendingOp() = default;
-
-FakeProofSource::GetProofOp::GetProofOp(
-    const QuicSocketAddress& server_addr,
-    const QuicSocketAddress& client_address,
-    std::string hostname,
-    std::string server_config,
-    QuicTransportVersion transport_version,
-    std::string chlo_hash,
-    std::unique_ptr<ProofSource::Callback> callback,
-    ProofSource* delegate)
-    : server_address_(server_addr),
-      client_address_(client_address),
-      hostname_(std::move(hostname)),
-      server_config_(std::move(server_config)),
-      transport_version_(transport_version),
-      chlo_hash_(std::move(chlo_hash)),
-      callback_(std::move(callback)),
-      delegate_(delegate) {}
-
-FakeProofSource::GetProofOp::~GetProofOp() = default;
-
-void FakeProofSource::GetProofOp::Run() {
-  // Note: relies on the callback being invoked synchronously
-  delegate_->GetProof(server_address_, client_address_, hostname_,
-                      server_config_, transport_version_, chlo_hash_,
-                      std::move(callback_));
-}
-
-FakeProofSource::ComputeSignatureOp::ComputeSignatureOp(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    std::string hostname,
-    uint16_t sig_alg,
-    absl::string_view in,
-    std::unique_ptr<ProofSource::SignatureCallback> callback,
-    ProofSource* delegate)
-    : server_address_(server_address),
-      client_address_(client_address),
-      hostname_(std::move(hostname)),
-      sig_alg_(sig_alg),
-      in_(in),
-      callback_(std::move(callback)),
-      delegate_(delegate) {}
-
-FakeProofSource::ComputeSignatureOp::~ComputeSignatureOp() = default;
-
-void FakeProofSource::ComputeSignatureOp::Run() {
-  delegate_->ComputeTlsSignature(server_address_, client_address_, hostname_,
-                                 sig_alg_, in_, std::move(callback_));
-}
-
-void FakeProofSource::Activate() {
-  active_ = true;
-}
-
-void FakeProofSource::GetProof(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    const std::string& hostname,
-    const std::string& server_config,
-    QuicTransportVersion transport_version,
-    absl::string_view chlo_hash,
-    std::unique_ptr<ProofSource::Callback> callback) {
-  if (!active_) {
-    delegate_->GetProof(server_address, client_address, hostname, server_config,
-                        transport_version, chlo_hash, std::move(callback));
-    return;
-  }
-
-  pending_ops_.push_back(std::make_unique<GetProofOp>(
-      server_address, client_address, hostname, server_config,
-      transport_version, std::string(chlo_hash), std::move(callback),
-      delegate_.get()));
-}
-
-quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
-FakeProofSource::GetCertChain(const QuicSocketAddress& server_address,
-                              const QuicSocketAddress& client_address,
-                              const std::string& hostname,
-                              bool* cert_matched_sni) {
-  return delegate_->GetCertChain(server_address, client_address, hostname,
-                                 cert_matched_sni);
-}
-
-void FakeProofSource::ComputeTlsSignature(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    const std::string& hostname,
-    uint16_t signature_algorithm,
-    absl::string_view in,
-    std::unique_ptr<ProofSource::SignatureCallback> callback) {
-  QUIC_LOG(INFO) << "FakeProofSource::ComputeTlsSignature";
-  if (!active_) {
-    QUIC_LOG(INFO) << "Not active - directly calling delegate";
-    delegate_->ComputeTlsSignature(server_address, client_address, hostname,
-                                   signature_algorithm, in,
-                                   std::move(callback));
-    return;
-  }
-
-  QUIC_LOG(INFO) << "Adding pending op";
-  pending_ops_.push_back(std::make_unique<ComputeSignatureOp>(
-      server_address, client_address, hostname, signature_algorithm, in,
-      std::move(callback), delegate_.get()));
-}
-
-absl::InlinedVector<uint16_t, 8>
-FakeProofSource::SupportedTlsSignatureAlgorithms() const {
-  return delegate_->SupportedTlsSignatureAlgorithms();
-}
-
-ProofSource::TicketCrypter* FakeProofSource::GetTicketCrypter() {
-  if (ticket_crypter_) {
-    return ticket_crypter_.get();
-  }
-  return delegate_->GetTicketCrypter();
-}
-
-void FakeProofSource::SetTicketCrypter(
-    std::unique_ptr<TicketCrypter> ticket_crypter) {
-  ticket_crypter_ = std::move(ticket_crypter);
-}
-
-int FakeProofSource::NumPendingCallbacks() const {
-  return pending_ops_.size();
-}
-
-void FakeProofSource::InvokePendingCallback(int n) {
-  QUICHE_CHECK(NumPendingCallbacks() > n);
-
-  pending_ops_[n]->Run();
-
-  auto it = pending_ops_.begin() + n;
-  pending_ops_.erase(it);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/fake_proof_source.h b/quic/test_tools/fake_proof_source.h
deleted file mode 100644
index 256e174..0000000
--- a/quic/test_tools/fake_proof_source.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
-#define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-// Implementation of ProofSource which delegates to a ProofSourceForTesting, but
-// allows for overriding certain functionality. FakeProofSource allows
-// intercepting calls to GetProof and ComputeTlsSignature to force them to run
-// asynchronously, and allow the caller to see that the call is pending and
-// resume the operation at the caller's choosing. FakeProofSource also allows
-// the caller to replace the TicketCrypter provided by
-// FakeProofSource::GetTicketCrypter.
-class FakeProofSource : public ProofSource {
- public:
-  FakeProofSource();
-  ~FakeProofSource() override;
-
-  // Before this object is "active", all calls to GetProof will be delegated
-  // immediately.  Once "active", the async ones will be intercepted.  This
-  // distinction is necessary to ensure that GetProof can be called without
-  // interference during test case setup.
-  void Activate();
-
-  // ProofSource interface
-  void GetProof(const QuicSocketAddress& server_address,
-                const QuicSocketAddress& client_address,
-                const std::string& hostname,
-                const std::string& server_config,
-                QuicTransportVersion transport_version,
-                absl::string_view chlo_hash,
-                std::unique_ptr<ProofSource::Callback> callback) override;
-  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address, const std::string& hostname,
-      bool* cert_matched_sni) override;
-  void ComputeTlsSignature(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      const std::string& hostname,
-      uint16_t signature_algorithm,
-      absl::string_view in,
-      std::unique_ptr<ProofSource::SignatureCallback> callback) override;
-  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
-      const override;
-  TicketCrypter* GetTicketCrypter() override;
-
-  // Sets the TicketCrypter to use. If nullptr, the TicketCrypter from
-  // ProofSourceForTesting will be returned instead.
-  void SetTicketCrypter(std::unique_ptr<TicketCrypter> ticket_crypter);
-
-  // Get the number of callbacks which are pending
-  int NumPendingCallbacks() const;
-
-  // Invoke a pending callback.  The index refers to the position in
-  // pending_ops_ of the callback to be completed.
-  void InvokePendingCallback(int n);
-
- private:
-  std::unique_ptr<ProofSource> delegate_;
-  std::unique_ptr<TicketCrypter> ticket_crypter_;
-  bool active_ = false;
-
-  class PendingOp {
-   public:
-    virtual ~PendingOp();
-    virtual void Run() = 0;
-  };
-
-  class GetProofOp : public PendingOp {
-   public:
-    GetProofOp(const QuicSocketAddress& server_addr,
-               const QuicSocketAddress& client_address,
-               std::string hostname,
-               std::string server_config,
-               QuicTransportVersion transport_version,
-               std::string chlo_hash,
-               std::unique_ptr<ProofSource::Callback> callback,
-               ProofSource* delegate);
-    ~GetProofOp() override;
-
-    void Run() override;
-
-   private:
-    QuicSocketAddress server_address_;
-    QuicSocketAddress client_address_;
-    std::string hostname_;
-    std::string server_config_;
-    QuicTransportVersion transport_version_;
-    std::string chlo_hash_;
-    std::unique_ptr<ProofSource::Callback> callback_;
-    ProofSource* delegate_;
-  };
-
-  class ComputeSignatureOp : public PendingOp {
-   public:
-    ComputeSignatureOp(const QuicSocketAddress& server_address,
-                       const QuicSocketAddress& client_address,
-                       std::string hostname,
-                       uint16_t sig_alg,
-                       absl::string_view in,
-                       std::unique_ptr<ProofSource::SignatureCallback> callback,
-                       ProofSource* delegate);
-    ~ComputeSignatureOp() override;
-
-    void Run() override;
-
-   private:
-    QuicSocketAddress server_address_;
-    QuicSocketAddress client_address_;
-    std::string hostname_;
-    uint16_t sig_alg_;
-    std::string in_;
-    std::unique_ptr<ProofSource::SignatureCallback> callback_;
-    ProofSource* delegate_;
-  };
-
-  std::vector<std::unique_ptr<PendingOp>> pending_ops_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
diff --git a/quic/test_tools/fake_proof_source_handle.cc b/quic/test_tools/fake_proof_source_handle.cc
deleted file mode 100644
index 7d30bdd..0000000
--- a/quic/test_tools/fake_proof_source_handle.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/fake_proof_source_handle.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-struct QUIC_EXPORT_PRIVATE ComputeSignatureResult {
-  bool ok;
-  std::string signature;
-  std::unique_ptr<ProofSource::Details> details;
-};
-
-class QUIC_EXPORT_PRIVATE ResultSavingSignatureCallback
-    : public ProofSource::SignatureCallback {
- public:
-  explicit ResultSavingSignatureCallback(
-      absl::optional<ComputeSignatureResult>* result)
-      : result_(result) {
-    QUICHE_DCHECK(!result_->has_value());
-  }
-  void Run(bool ok,
-           std::string signature,
-           std::unique_ptr<ProofSource::Details> details) override {
-    result_->emplace(
-        ComputeSignatureResult{ok, std::move(signature), std::move(details)});
-  }
-
- private:
-  absl::optional<ComputeSignatureResult>* result_;
-};
-
-ComputeSignatureResult ComputeSignatureNow(
-    ProofSource* delegate,
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    const std::string& hostname,
-    uint16_t signature_algorithm,
-    absl::string_view in) {
-  absl::optional<ComputeSignatureResult> result;
-  delegate->ComputeTlsSignature(
-      server_address, client_address, hostname, signature_algorithm, in,
-      std::make_unique<ResultSavingSignatureCallback>(&result));
-  QUICHE_CHECK(result.has_value())
-      << "delegate->ComputeTlsSignature must computes a "
-         "signature immediately";
-  return std::move(result.value());
-}
-}  // namespace
-
-FakeProofSourceHandle::FakeProofSourceHandle(
-    ProofSource* delegate, ProofSourceHandleCallback* callback,
-    Action select_cert_action, Action compute_signature_action,
-    QuicDelayedSSLConfig dealyed_ssl_config)
-    : delegate_(delegate),
-      callback_(callback),
-      select_cert_action_(select_cert_action),
-      compute_signature_action_(compute_signature_action),
-      dealyed_ssl_config_(dealyed_ssl_config) {}
-
-void FakeProofSourceHandle::CloseHandle() {
-  select_cert_op_.reset();
-  compute_signature_op_.reset();
-  closed_ = true;
-}
-
-QuicAsyncStatus FakeProofSourceHandle::SelectCertificate(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    absl::string_view ssl_capabilities,
-    const std::string& hostname,
-    absl::string_view client_hello,
-    const std::string& alpn,
-    absl::optional<std::string> alps,
-    const std::vector<uint8_t>& quic_transport_params,
-    const absl::optional<std::vector<uint8_t>>& early_data_context,
-    const QuicSSLConfig& ssl_config) {
-  if (select_cert_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
-    QUICHE_CHECK(!closed_);
-  }
-  all_select_cert_args_.push_back(SelectCertArgs(
-      server_address, client_address, ssl_capabilities, hostname, client_hello,
-      alpn, alps, quic_transport_params, early_data_context, ssl_config));
-
-  if (select_cert_action_ == Action::DELEGATE_ASYNC ||
-      select_cert_action_ == Action::FAIL_ASYNC) {
-    select_cert_op_.emplace(delegate_, callback_, select_cert_action_,
-                            all_select_cert_args_.back(), dealyed_ssl_config_);
-    return QUIC_PENDING;
-  } else if (select_cert_action_ == Action::FAIL_SYNC ||
-             select_cert_action_ == Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
-    callback()->OnSelectCertificateDone(
-        /*ok=*/false,
-        /*is_sync=*/true, nullptr, /*handshake_hints=*/absl::string_view(),
-        /*ticket_encryption_key=*/absl::string_view(),
-        /*cert_matched_sni=*/false, dealyed_ssl_config_);
-    return QUIC_FAILURE;
-  }
-
-  QUICHE_DCHECK(select_cert_action_ == Action::DELEGATE_SYNC);
-  bool cert_matched_sni;
-  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
-      delegate_->GetCertChain(server_address, client_address, hostname,
-                              &cert_matched_sni);
-
-  bool ok = chain && !chain->certs.empty();
-  callback_->OnSelectCertificateDone(
-      ok, /*is_sync=*/true, chain.get(),
-      /*handshake_hints=*/absl::string_view(),
-      /*ticket_encryption_key=*/absl::string_view(),
-      /*cert_matched_sni=*/cert_matched_sni, dealyed_ssl_config_);
-  return ok ? QUIC_SUCCESS : QUIC_FAILURE;
-}
-
-QuicAsyncStatus FakeProofSourceHandle::ComputeSignature(
-    const QuicSocketAddress& server_address,
-    const QuicSocketAddress& client_address,
-    const std::string& hostname,
-    uint16_t signature_algorithm,
-    absl::string_view in,
-    size_t max_signature_size) {
-  if (compute_signature_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
-    QUICHE_CHECK(!closed_);
-  }
-  all_compute_signature_args_.push_back(
-      ComputeSignatureArgs(server_address, client_address, hostname,
-                           signature_algorithm, in, max_signature_size));
-
-  if (compute_signature_action_ == Action::DELEGATE_ASYNC ||
-      compute_signature_action_ == Action::FAIL_ASYNC) {
-    compute_signature_op_.emplace(delegate_, callback_,
-                                  compute_signature_action_,
-                                  all_compute_signature_args_.back());
-    return QUIC_PENDING;
-  } else if (compute_signature_action_ == Action::FAIL_SYNC ||
-             compute_signature_action_ ==
-                 Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
-    callback()->OnComputeSignatureDone(/*ok=*/false, /*is_sync=*/true,
-                                       /*signature=*/"", /*details=*/nullptr);
-    return QUIC_FAILURE;
-  }
-
-  QUICHE_DCHECK(compute_signature_action_ == Action::DELEGATE_SYNC);
-  ComputeSignatureResult result =
-      ComputeSignatureNow(delegate_, server_address, client_address, hostname,
-                          signature_algorithm, in);
-  callback_->OnComputeSignatureDone(
-      result.ok, /*is_sync=*/true, result.signature, std::move(result.details));
-  return result.ok ? QUIC_SUCCESS : QUIC_FAILURE;
-}
-
-ProofSourceHandleCallback* FakeProofSourceHandle::callback() {
-  return callback_;
-}
-
-bool FakeProofSourceHandle::HasPendingOperation() const {
-  int num_pending_operations = NumPendingOperations();
-  return num_pending_operations > 0;
-}
-
-void FakeProofSourceHandle::CompletePendingOperation() {
-  QUICHE_DCHECK_LE(NumPendingOperations(), 1);
-
-  if (select_cert_op_.has_value()) {
-    select_cert_op_->Run();
-    select_cert_op_.reset();
-  } else if (compute_signature_op_.has_value()) {
-    compute_signature_op_->Run();
-    compute_signature_op_.reset();
-  }
-}
-
-int FakeProofSourceHandle::NumPendingOperations() const {
-  return static_cast<int>(select_cert_op_.has_value()) +
-         static_cast<int>(compute_signature_op_.has_value());
-}
-
-FakeProofSourceHandle::SelectCertOperation::SelectCertOperation(
-    ProofSource* delegate, ProofSourceHandleCallback* callback, Action action,
-    SelectCertArgs args, QuicDelayedSSLConfig dealyed_ssl_config)
-    : PendingOperation(delegate, callback, action),
-      args_(std::move(args)),
-      dealyed_ssl_config_(dealyed_ssl_config) {}
-
-void FakeProofSourceHandle::SelectCertOperation::Run() {
-  if (action_ == Action::FAIL_ASYNC) {
-    callback_->OnSelectCertificateDone(
-        /*ok=*/false,
-        /*is_sync=*/false, nullptr,
-        /*handshake_hints=*/absl::string_view(),
-        /*ticket_encryption_key=*/absl::string_view(),
-        /*cert_matched_sni=*/false, dealyed_ssl_config_);
-  } else if (action_ == Action::DELEGATE_ASYNC) {
-    bool cert_matched_sni;
-    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
-        delegate_->GetCertChain(args_.server_address, args_.client_address,
-                                args_.hostname, &cert_matched_sni);
-    bool ok = chain && !chain->certs.empty();
-    callback_->OnSelectCertificateDone(
-        ok, /*is_sync=*/false, chain.get(),
-        /*handshake_hints=*/absl::string_view(),
-        /*ticket_encryption_key=*/absl::string_view(),
-        /*cert_matched_sni=*/cert_matched_sni, dealyed_ssl_config_);
-  } else {
-    QUIC_BUG(quic_bug_10139_1)
-        << "Unexpected action: " << static_cast<int>(action_);
-  }
-}
-
-FakeProofSourceHandle::ComputeSignatureOperation::ComputeSignatureOperation(
-    ProofSource* delegate,
-    ProofSourceHandleCallback* callback,
-    Action action,
-    ComputeSignatureArgs args)
-    : PendingOperation(delegate, callback, action), args_(std::move(args)) {}
-
-void FakeProofSourceHandle::ComputeSignatureOperation::Run() {
-  if (action_ == Action::FAIL_ASYNC) {
-    callback_->OnComputeSignatureDone(
-        /*ok=*/false, /*is_sync=*/false,
-        /*signature=*/"", /*details=*/nullptr);
-  } else if (action_ == Action::DELEGATE_ASYNC) {
-    ComputeSignatureResult result = ComputeSignatureNow(
-        delegate_, args_.server_address, args_.client_address, args_.hostname,
-        args_.signature_algorithm, args_.in);
-    callback_->OnComputeSignatureDone(result.ok, /*is_sync=*/false,
-                                      result.signature,
-                                      std::move(result.details));
-  } else {
-    QUIC_BUG(quic_bug_10139_2)
-        << "Unexpected action: " << static_cast<int>(action_);
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/fake_proof_source_handle.h b/quic/test_tools/fake_proof_source_handle.h
deleted file mode 100644
index bb2c60e..0000000
--- a/quic/test_tools/fake_proof_source_handle.h
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
-#define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
-
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-// FakeProofSourceHandle allows its behavior to be scripted for testing.
-class FakeProofSourceHandle : public ProofSourceHandle {
- public:
-  // What would an operation return when it is called.
-  enum class Action {
-    // Delegate the operation to |delegate_| immediately.
-    DELEGATE_SYNC = 0,
-    // Handle the operation asynchronously. Delegate the operation to
-    // |delegate_| when the caller calls CompletePendingOperation().
-    DELEGATE_ASYNC,
-    // Fail the operation immediately.
-    FAIL_SYNC,
-    // Handle the operation asynchronously. Fail the operation when the caller
-    // calls CompletePendingOperation().
-    FAIL_ASYNC,
-    // Similar to FAIL_SYNC, but do not QUICHE_CHECK(!closed_) when invoked.
-    FAIL_SYNC_DO_NOT_CHECK_CLOSED,
-  };
-
-  // |delegate| must do cert selection and signature synchronously.
-  // |dealyed_ssl_config| is the config passed to OnSelectCertificateDone.
-  FakeProofSourceHandle(
-      ProofSource* delegate, ProofSourceHandleCallback* callback,
-      Action select_cert_action, Action compute_signature_action,
-      QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig());
-
-  ~FakeProofSourceHandle() override = default;
-
-  void CloseHandle() override;
-
-  QuicAsyncStatus SelectCertificate(
-      const QuicSocketAddress& server_address,
-      const QuicSocketAddress& client_address,
-      absl::string_view ssl_capabilities,
-      const std::string& hostname,
-      absl::string_view client_hello,
-      const std::string& alpn,
-      absl::optional<std::string> alps,
-      const std::vector<uint8_t>& quic_transport_params,
-      const absl::optional<std::vector<uint8_t>>& early_data_context,
-      const QuicSSLConfig& ssl_config) override;
-
-  QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
-                                   const QuicSocketAddress& client_address,
-                                   const std::string& hostname,
-                                   uint16_t signature_algorithm,
-                                   absl::string_view in,
-                                   size_t max_signature_size) override;
-
-  ProofSourceHandleCallback* callback() override;
-
-  // Whether there's a pending operation in |this|.
-  bool HasPendingOperation() const;
-  void CompletePendingOperation();
-
-  struct SelectCertArgs {
-    SelectCertArgs(QuicSocketAddress server_address,
-                   QuicSocketAddress client_address,
-                   absl::string_view ssl_capabilities,
-                   std::string hostname,
-                   absl::string_view client_hello,
-                   std::string alpn,
-                   absl::optional<std::string> alps,
-                   std::vector<uint8_t> quic_transport_params,
-                   absl::optional<std::vector<uint8_t>> early_data_context,
-                   QuicSSLConfig ssl_config)
-        : server_address(server_address),
-          client_address(client_address),
-          ssl_capabilities(ssl_capabilities),
-          hostname(hostname),
-          client_hello(client_hello),
-          alpn(alpn),
-          alps(alps),
-          quic_transport_params(quic_transport_params),
-          early_data_context(early_data_context),
-          ssl_config(ssl_config) {}
-
-    QuicSocketAddress server_address;
-    QuicSocketAddress client_address;
-    std::string ssl_capabilities;
-    std::string hostname;
-    std::string client_hello;
-    std::string alpn;
-    absl::optional<std::string> alps;
-    std::vector<uint8_t> quic_transport_params;
-    absl::optional<std::vector<uint8_t>> early_data_context;
-    QuicSSLConfig ssl_config;
-  };
-
-  struct ComputeSignatureArgs {
-    ComputeSignatureArgs(QuicSocketAddress server_address,
-                         QuicSocketAddress client_address,
-                         std::string hostname,
-                         uint16_t signature_algorithm,
-                         absl::string_view in,
-                         size_t max_signature_size)
-        : server_address(server_address),
-          client_address(client_address),
-          hostname(hostname),
-          signature_algorithm(signature_algorithm),
-          in(in),
-          max_signature_size(max_signature_size) {}
-
-    QuicSocketAddress server_address;
-    QuicSocketAddress client_address;
-    std::string hostname;
-    uint16_t signature_algorithm;
-    std::string in;
-    size_t max_signature_size;
-  };
-
-  std::vector<SelectCertArgs> all_select_cert_args() const {
-    return all_select_cert_args_;
-  }
-
-  std::vector<ComputeSignatureArgs> all_compute_signature_args() const {
-    return all_compute_signature_args_;
-  }
-
- private:
-  class PendingOperation {
-   public:
-    PendingOperation(ProofSource* delegate,
-                     ProofSourceHandleCallback* callback,
-                     Action action)
-        : delegate_(delegate), callback_(callback), action_(action) {}
-    virtual ~PendingOperation() = default;
-    virtual void Run() = 0;
-
-   protected:
-    ProofSource* delegate_;
-    ProofSourceHandleCallback* callback_;
-    Action action_;
-  };
-
-  class SelectCertOperation : public PendingOperation {
-   public:
-    SelectCertOperation(ProofSource* delegate,
-                        ProofSourceHandleCallback* callback, Action action,
-                        SelectCertArgs args,
-                        QuicDelayedSSLConfig dealyed_ssl_config);
-
-    ~SelectCertOperation() override = default;
-
-    void Run() override;
-
-   private:
-    const SelectCertArgs args_;
-    const QuicDelayedSSLConfig dealyed_ssl_config_;
-  };
-
-  class ComputeSignatureOperation : public PendingOperation {
-   public:
-    ComputeSignatureOperation(ProofSource* delegate,
-                              ProofSourceHandleCallback* callback,
-                              Action action,
-                              ComputeSignatureArgs args);
-
-    ~ComputeSignatureOperation() override = default;
-
-    void Run() override;
-
-   private:
-    const ComputeSignatureArgs args_;
-  };
-
- private:
-  int NumPendingOperations() const;
-
-  bool closed_ = false;
-  ProofSource* delegate_;
-  ProofSourceHandleCallback* callback_;
-  // Action for the next select cert operation.
-  Action select_cert_action_ = Action::DELEGATE_SYNC;
-  // Action for the next compute signature operation.
-  Action compute_signature_action_ = Action::DELEGATE_SYNC;
-  const QuicDelayedSSLConfig dealyed_ssl_config_;
-  absl::optional<SelectCertOperation> select_cert_op_;
-  absl::optional<ComputeSignatureOperation> compute_signature_op_;
-
-  // Save all the select cert and compute signature args for tests to inspect.
-  std::vector<SelectCertArgs> all_select_cert_args_;
-  std::vector<ComputeSignatureArgs> all_compute_signature_args_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
diff --git a/quic/test_tools/first_flight.cc b/quic/test_tools/first_flight.cc
deleted file mode 100644
index ec0a5e3..0000000
--- a/quic/test_tools/first_flight.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/first_flight.h"
-
-#include <memory>
-#include <vector>
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// Utility class that creates a custom HTTP/3 session and QUIC connection in
-// order to extract the first flight of packets it sends. This is meant to only
-// be used by GetFirstFlightOfPackets() below.
-class FirstFlightExtractor : public DelegatedPacketWriter::Delegate {
- public:
-  FirstFlightExtractor(const ParsedQuicVersion& version,
-                       const QuicConfig& config,
-                       const QuicConnectionId& server_connection_id,
-                       const QuicConnectionId& client_connection_id,
-                       std::unique_ptr<QuicCryptoClientConfig> crypto_config)
-      : version_(version),
-        server_connection_id_(server_connection_id),
-        client_connection_id_(client_connection_id),
-        writer_(this),
-        config_(config),
-        crypto_config_(std::move(crypto_config)) {
-    EXPECT_NE(version_, UnsupportedQuicVersion());
-  }
-
-  FirstFlightExtractor(const ParsedQuicVersion& version,
-                       const QuicConfig& config,
-                       const QuicConnectionId& server_connection_id,
-                       const QuicConnectionId& client_connection_id)
-      : FirstFlightExtractor(
-            version, config, server_connection_id, client_connection_id,
-            std::make_unique<QuicCryptoClientConfig>(
-                crypto_test_utils::ProofVerifierForTesting())) {}
-
-  void GenerateFirstFlight() {
-    crypto_config_->set_alpn(AlpnForVersion(version_));
-    connection_ =
-        new QuicConnection(server_connection_id_,
-                           /*initial_self_address=*/QuicSocketAddress(),
-                           QuicSocketAddress(TestPeerIPAddress(), kTestPort),
-                           &connection_helper_, &alarm_factory_, &writer_,
-                           /*owns_writer=*/false, Perspective::IS_CLIENT,
-                           ParsedQuicVersionVector{version_});
-    connection_->set_client_connection_id(client_connection_id_);
-    session_ = std::make_unique<QuicSpdyClientSession>(
-        config_, ParsedQuicVersionVector{version_},
-        connection_,  // session_ takes ownership of connection_ here.
-        TestServerId(), crypto_config_.get(), &push_promise_index_);
-    session_->Initialize();
-    session_->CryptoConnect();
-  }
-
-  void OnDelegatedPacket(const char* buffer,
-                         size_t buf_len,
-                         const QuicIpAddress& /*self_client_address*/,
-                         const QuicSocketAddress& /*peer_client_address*/,
-                         PerPacketOptions* /*options*/) override {
-    packets_.emplace_back(
-        QuicReceivedPacket(buffer, buf_len,
-                           connection_helper_.GetClock()->ApproximateNow(),
-                           /*owns_buffer=*/false)
-            .Clone());
-  }
-
-  std::vector<std::unique_ptr<QuicReceivedPacket>>&& ConsumePackets() {
-    return std::move(packets_);
-  }
-
- private:
-  ParsedQuicVersion version_;
-  QuicConnectionId server_connection_id_;
-  QuicConnectionId client_connection_id_;
-  MockQuicConnectionHelper connection_helper_;
-  MockAlarmFactory alarm_factory_;
-  DelegatedPacketWriter writer_;
-  QuicConfig config_;
-  std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
-  QuicClientPushPromiseIndex push_promise_index_;
-  QuicConnection* connection_;  // Owned by session_.
-  std::unique_ptr<QuicSpdyClientSession> session_;
-  std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
-};
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version, const QuicConfig& config,
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& client_connection_id,
-    std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
-  FirstFlightExtractor first_flight_extractor(
-      version, config, server_connection_id, client_connection_id,
-      std::move(crypto_config));
-  first_flight_extractor.GenerateFirstFlight();
-  return first_flight_extractor.ConsumePackets();
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConfig& config,
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& client_connection_id) {
-  FirstFlightExtractor first_flight_extractor(
-      version, config, server_connection_id, client_connection_id);
-  first_flight_extractor.GenerateFirstFlight();
-  return first_flight_extractor.ConsumePackets();
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConfig& config,
-    const QuicConnectionId& server_connection_id) {
-  return GetFirstFlightOfPackets(version, config, server_connection_id,
-                                 EmptyQuicConnectionId());
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConfig& config) {
-  return GetFirstFlightOfPackets(version, config, TestConnectionId());
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& client_connection_id) {
-  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
-                                 server_connection_id, client_connection_id);
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConnectionId& server_connection_id) {
-  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
-                                 server_connection_id, EmptyQuicConnectionId());
-}
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version) {
-  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
-                                 TestConnectionId());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/first_flight.h b/quic/test_tools/first_flight.h
deleted file mode 100644
index 7c6123d..0000000
--- a/quic/test_tools/first_flight.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
-#define QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
-
-#include <memory>
-#include <vector>
-
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-namespace test {
-
-// Implementation of QuicPacketWriter that sends all packets to a delegate.
-class QUIC_NO_EXPORT DelegatedPacketWriter : public QuicPacketWriter {
- public:
-  class QUIC_NO_EXPORT Delegate {
-   public:
-    virtual ~Delegate() {}
-    // Note that |buffer| may be released after this call completes so overrides
-    // that want to use the data after the call is complete MUST copy it.
-    virtual void OnDelegatedPacket(const char* buffer,
-                                   size_t buf_len,
-                                   const QuicIpAddress& self_client_address,
-                                   const QuicSocketAddress& peer_client_address,
-                                   PerPacketOptions* options) = 0;
-  };
-
-  // |delegate| MUST be valid for the duration of the DelegatedPacketWriter's
-  // lifetime.
-  explicit DelegatedPacketWriter(Delegate* delegate) : delegate_(delegate) {
-    QUICHE_CHECK_NE(delegate_, nullptr);
-  }
-
-  // Overrides for QuicPacketWriter.
-  bool IsWriteBlocked() const override { return false; }
-  void SetWritable() override {}
-  absl::optional<int> MessageTooBigErrorCode() const override {
-    return absl::nullopt;
-  }
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& /*peer_address*/) const override {
-    return kMaxOutgoingPacketSize;
-  }
-  bool SupportsReleaseTime() const override { return false; }
-  bool IsBatchMode() const override { return false; }
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& /*self_address*/,
-      const QuicSocketAddress& /*peer_address*/) override {
-    return {nullptr, nullptr};
-  }
-  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_client_address,
-                          const QuicSocketAddress& peer_client_address,
-                          PerPacketOptions* options) override {
-    delegate_->OnDelegatedPacket(buffer, buf_len, self_client_address,
-                                 peer_client_address, options);
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
- private:
-  Delegate* delegate_;  // Unowned.
-};
-
-// Returns an array of packets that represent the first flight of a real
-// HTTP/3 connection. In most cases, this array will only contain one packet
-// that carries the CHLO.
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version, const QuicConfig& config,
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& client_connection_id,
-    std::unique_ptr<QuicCryptoClientConfig> crypto_config);
-
-// Below are various convenience overloads that use default values for the
-// omitted parameters:
-// |config| = DefaultQuicConfig(),
-// |server_connection_id| = TestConnectionId(),
-// |client_connection_id| = EmptyQuicConnectionId().
-// |crypto_config| =
-//     QuicCryptoClientConfig(crypto_test_utils::ProofVerifierForTesting())
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version, const QuicConfig& config,
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& client_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConfig& config,
-    const QuicConnectionId& server_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConnectionId& server_connection_id,
-    const QuicConnectionId& client_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConnectionId& server_connection_id);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version,
-    const QuicConfig& config);
-
-std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
-    const ParsedQuicVersion& version);
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
diff --git a/quic/test_tools/fuzzing/quic_framer_fuzzer.cc b/quic/test_tools/fuzzing/quic_framer_fuzzer.cc
deleted file mode 100644
index 2095ca1..0000000
--- a/quic/test_tools/fuzzing/quic_framer_fuzzer.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  quic::QuicFramer framer(quic::AllSupportedVersions(), quic::QuicTime::Zero(),
-                          quic::Perspective::IS_SERVER,
-                          quic::kQuicDefaultConnectionIdLength);
-  const char* const packet_bytes = reinterpret_cast<const char*>(data);
-
-  // Test the CryptoFramer.
-  absl::string_view crypto_input(packet_bytes, size);
-  std::unique_ptr<quic::CryptoHandshakeMessage> handshake_message(
-      quic::CryptoFramer::ParseMessage(crypto_input));
-
-  // Test the regular QuicFramer with the same input.
-  quic::test::NoOpFramerVisitor visitor;
-  framer.set_visitor(&visitor);
-  quic::QuicEncryptedPacket packet(packet_bytes, size);
-  framer.ProcessPacket(packet);
-
-  return 0;
-}
diff --git a/quic/test_tools/fuzzing/quic_framer_process_data_packet_fuzzer.cc b/quic/test_tools/fuzzing/quic_framer_process_data_packet_fuzzer.cc
deleted file mode 100644
index 0126d4b..0000000
--- a/quic/test_tools/fuzzing/quic_framer_process_data_packet_fuzzer.cc
+++ /dev/null
@@ -1,285 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <algorithm>
-#include <cstdint>
-#include <string>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_constants.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_time.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using quic::DiversificationNonce;
-using quic::EncryptionLevel;
-using quic::FirstSendingPacketNumber;
-using quic::GetPacketHeaderSize;
-using quic::kEthernetMTU;
-using quic::kQuicDefaultConnectionIdLength;
-using quic::NullDecrypter;
-using quic::NullEncrypter;
-using quic::PacketHeaderFormat;
-using quic::ParsedQuicVersion;
-using quic::ParsedQuicVersionVector;
-using quic::Perspective;
-using quic::QuicConnectionId;
-using quic::QuicDataReader;
-using quic::QuicDataWriter;
-using quic::QuicEncryptedPacket;
-using quic::QuicFramer;
-using quic::QuicFramerVisitorInterface;
-using quic::QuicLongHeaderType;
-using quic::QuicPacketHeader;
-using quic::QuicPacketNumber;
-using quic::QuicTime;
-using quic::QuicTransportVersion;
-using quic::test::NoOpFramerVisitor;
-using quic::test::QuicFramerPeer;
-
-PacketHeaderFormat ConsumePacketHeaderFormat(FuzzedDataProvider* provider,
-                                             ParsedQuicVersion version) {
-  if (!version.HasIetfInvariantHeader()) {
-    return quic::GOOGLE_QUIC_PACKET;
-  }
-  return provider->ConsumeBool() ? quic::IETF_QUIC_LONG_HEADER_PACKET
-                                 : quic::IETF_QUIC_SHORT_HEADER_PACKET;
-}
-
-ParsedQuicVersion ConsumeParsedQuicVersion(FuzzedDataProvider* provider) {
-  // TODO(wub): Add support for v49+.
-  const QuicTransportVersion transport_versions[] = {
-      quic::QUIC_VERSION_43,
-      quic::QUIC_VERSION_46,
-  };
-
-  return ParsedQuicVersion(
-      quic::PROTOCOL_QUIC_CRYPTO,
-      transport_versions[provider->ConsumeIntegralInRange<uint8_t>(
-          0, ABSL_ARRAYSIZE(transport_versions) - 1)]);
-}
-
-// QuicSelfContainedPacketHeader is a QuicPacketHeader with built-in stroage for
-// diversification nonce.
-struct QuicSelfContainedPacketHeader : public QuicPacketHeader {
-  DiversificationNonce nonce_storage;
-};
-
-// Construct a random data packet header that 1) can be successfully serialized
-// at sender, and 2) the serialzied buffer can pass the receiver framer's
-// ProcessPublicHeader and DecryptPayload functions.
-QuicSelfContainedPacketHeader ConsumeQuicPacketHeader(
-    FuzzedDataProvider* provider,
-    Perspective receiver_perspective) {
-  QuicSelfContainedPacketHeader header;
-
-  header.version = ConsumeParsedQuicVersion(provider);
-
-  header.form = ConsumePacketHeaderFormat(provider, header.version);
-
-  const std::string cid_bytes =
-      provider->ConsumeBytesAsString(kQuicDefaultConnectionIdLength);
-  if (receiver_perspective == Perspective::IS_SERVER) {
-    header.destination_connection_id =
-        QuicConnectionId(cid_bytes.c_str(), cid_bytes.size());
-    header.destination_connection_id_included = quic::CONNECTION_ID_PRESENT;
-    header.source_connection_id_included = quic::CONNECTION_ID_ABSENT;
-  } else {
-    header.source_connection_id =
-        QuicConnectionId(cid_bytes.c_str(), cid_bytes.size());
-    header.source_connection_id_included = quic::CONNECTION_ID_PRESENT;
-    header.destination_connection_id_included = quic::CONNECTION_ID_ABSENT;
-  }
-
-  header.version_flag = receiver_perspective == Perspective::IS_SERVER;
-  header.reset_flag = false;
-
-  header.packet_number =
-      QuicPacketNumber(provider->ConsumeIntegral<uint32_t>());
-  if (header.packet_number < FirstSendingPacketNumber()) {
-    header.packet_number = FirstSendingPacketNumber();
-  }
-  header.packet_number_length = quic::PACKET_4BYTE_PACKET_NUMBER;
-
-  header.remaining_packet_length = 0;
-
-  if (header.form != quic::GOOGLE_QUIC_PACKET && header.version_flag) {
-    header.long_packet_type = static_cast<QuicLongHeaderType>(
-        provider->ConsumeIntegralInRange<uint8_t>(
-            // INITIAL, ZERO_RTT_PROTECTED, or HANDSHAKE.
-            static_cast<uint8_t>(quic::INITIAL),
-            static_cast<uint8_t>(quic::HANDSHAKE)));
-  } else {
-    header.long_packet_type = quic::INVALID_PACKET_TYPE;
-  }
-
-  if (header.form == quic::IETF_QUIC_LONG_HEADER_PACKET &&
-      header.long_packet_type == quic::ZERO_RTT_PROTECTED &&
-      receiver_perspective == Perspective::IS_CLIENT &&
-      header.version.handshake_protocol == quic::PROTOCOL_QUIC_CRYPTO) {
-    for (size_t i = 0; i < header.nonce_storage.size(); ++i) {
-      header.nonce_storage[i] = provider->ConsumeIntegral<char>();
-    }
-    header.nonce = &header.nonce_storage;
-  } else {
-    header.nonce = nullptr;
-  }
-
-  return header;
-}
-
-void SetupFramer(QuicFramer* framer, QuicFramerVisitorInterface* visitor) {
-  framer->set_visitor(visitor);
-  for (EncryptionLevel level :
-       {quic::ENCRYPTION_INITIAL, quic::ENCRYPTION_HANDSHAKE,
-        quic::ENCRYPTION_ZERO_RTT, quic::ENCRYPTION_FORWARD_SECURE}) {
-    framer->SetEncrypter(
-        level, std::make_unique<NullEncrypter>(framer->perspective()));
-    if (framer->version().KnowsWhichDecrypterToUse()) {
-      framer->InstallDecrypter(
-          level, std::make_unique<NullDecrypter>(framer->perspective()));
-    }
-  }
-
-  if (!framer->version().KnowsWhichDecrypterToUse()) {
-    framer->SetDecrypter(
-        quic::ENCRYPTION_INITIAL,
-        std::make_unique<NullDecrypter>(framer->perspective()));
-  }
-}
-
-class FuzzingFramerVisitor : public NoOpFramerVisitor {
- public:
-  // Called after a successful ProcessPublicHeader.
-  bool OnUnauthenticatedPublicHeader(
-      const QuicPacketHeader& /*header*/) override {
-    ++process_public_header_success_count_;
-    return true;
-  }
-
-  // Called after a successful DecryptPayload.
-  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
-    ++decrypted_packet_count_;
-    return true;
-  }
-
-  uint64_t process_public_header_success_count_ = 0;
-  uint64_t decrypted_packet_count_ = 0;
-};
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  FuzzedDataProvider data_provider(data, size);
-
-  const QuicTime creation_time =
-      QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(
-                             data_provider.ConsumeIntegral<int32_t>());
-  Perspective receiver_perspective = data_provider.ConsumeBool()
-                                         ? Perspective::IS_CLIENT
-                                         : Perspective::IS_SERVER;
-  Perspective sender_perspective =
-      (receiver_perspective == Perspective::IS_CLIENT) ? Perspective::IS_SERVER
-                                                       : Perspective::IS_CLIENT;
-
-  QuicSelfContainedPacketHeader header =
-      ConsumeQuicPacketHeader(&data_provider, receiver_perspective);
-
-  NoOpFramerVisitor sender_framer_visitor;
-  ParsedQuicVersionVector framer_versions = {header.version};
-  QuicFramer sender_framer(framer_versions, creation_time, sender_perspective,
-                           kQuicDefaultConnectionIdLength);
-  SetupFramer(&sender_framer, &sender_framer_visitor);
-
-  FuzzingFramerVisitor receiver_framer_visitor;
-  QuicFramer receiver_framer(framer_versions, creation_time,
-                             receiver_perspective,
-                             kQuicDefaultConnectionIdLength);
-  SetupFramer(&receiver_framer, &receiver_framer_visitor);
-  if (receiver_perspective == Perspective::IS_CLIENT) {
-    QuicFramerPeer::SetLastSerializedServerConnectionId(
-        &receiver_framer, header.source_connection_id);
-  } else {
-    QuicFramerPeer::SetLastSerializedClientConnectionId(
-        &receiver_framer, header.source_connection_id);
-  }
-
-  std::array<char, kEthernetMTU> packet_buffer;
-  while (data_provider.remaining_bytes() > 16) {
-    const size_t last_remaining_bytes = data_provider.remaining_bytes();
-
-    // Get a randomized packet size.
-    uint16_t max_payload_size = static_cast<uint16_t>(
-        std::min<size_t>(data_provider.remaining_bytes(), 1350u));
-    uint16_t min_payload_size = std::min<uint16_t>(16u, max_payload_size);
-    uint16_t payload_size = data_provider.ConsumeIntegralInRange<uint16_t>(
-        min_payload_size, max_payload_size);
-
-    QUICHE_CHECK_NE(last_remaining_bytes, data_provider.remaining_bytes())
-        << "Check fail to avoid an infinite loop. ConsumeIntegralInRange("
-        << min_payload_size << ", " << max_payload_size
-        << ") did not consume any bytes. remaining_bytes:"
-        << last_remaining_bytes;
-
-    std::vector<char> payload_buffer =
-        data_provider.ConsumeBytes<char>(payload_size);
-    QUICHE_CHECK_GE(
-        packet_buffer.size(),
-        GetPacketHeaderSize(sender_framer.transport_version(), header) +
-            payload_buffer.size());
-
-    // Serialize the null-encrypted packet into |packet_buffer|.
-    QuicDataWriter writer(packet_buffer.size(), packet_buffer.data());
-    size_t length_field_offset = 0;
-    QUICHE_CHECK(sender_framer.AppendPacketHeader(header, &writer,
-                                                  &length_field_offset));
-
-    QUICHE_CHECK(
-        writer.WriteBytes(payload_buffer.data(), payload_buffer.size()));
-
-    EncryptionLevel encryption_level =
-        quic::test::HeaderToEncryptionLevel(header);
-    QUICHE_CHECK(sender_framer.WriteIetfLongHeaderLength(
-        header, &writer, length_field_offset, encryption_level));
-
-    size_t encrypted_length = sender_framer.EncryptInPlace(
-        encryption_level, header.packet_number,
-        GetStartOfEncryptedData(sender_framer.transport_version(), header),
-        writer.length(), packet_buffer.size(), packet_buffer.data());
-    QUICHE_CHECK_NE(encrypted_length, 0u);
-
-    // Use receiver's framer to process the packet. Ensure both
-    // ProcessPublicHeader and DecryptPayload were called and succeeded.
-    QuicEncryptedPacket packet(packet_buffer.data(), encrypted_length);
-    QuicDataReader reader(packet.data(), packet.length());
-
-    const uint64_t process_public_header_success_count =
-        receiver_framer_visitor.process_public_header_success_count_;
-    const uint64_t decrypted_packet_count =
-        receiver_framer_visitor.decrypted_packet_count_;
-
-    receiver_framer.ProcessPacket(packet);
-
-    QUICHE_DCHECK_EQ(
-        process_public_header_success_count + 1,
-        receiver_framer_visitor.process_public_header_success_count_)
-        << "ProcessPublicHeader failed. error:"
-        << QuicErrorCodeToString(receiver_framer.error())
-        << ", error_detail:" << receiver_framer.detailed_error()
-        << ". header:" << header;
-    QUICHE_DCHECK_EQ(decrypted_packet_count + 1,
-                     receiver_framer_visitor.decrypted_packet_count_)
-        << "Packet was not decrypted. error:"
-        << QuicErrorCodeToString(receiver_framer.error())
-        << ", error_detail:" << receiver_framer.detailed_error()
-        << ". header:" << header;
-  }
-  return 0;
-}
diff --git a/quic/test_tools/limited_mtu_test_writer.cc b/quic/test_tools/limited_mtu_test_writer.cc
deleted file mode 100644
index 5bbf7f7..0000000
--- a/quic/test_tools/limited_mtu_test_writer.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/limited_mtu_test_writer.h"
-
-namespace quic {
-namespace test {
-
-LimitedMtuTestWriter::LimitedMtuTestWriter(QuicByteCount mtu) : mtu_(mtu) {}
-
-LimitedMtuTestWriter::~LimitedMtuTestWriter() = default;
-
-WriteResult LimitedMtuTestWriter::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  if (buf_len > mtu_) {
-    // Drop the packet.
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
-  return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
-                                              peer_address, options);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/limited_mtu_test_writer.h b/quic/test_tools/limited_mtu_test_writer.h
deleted file mode 100644
index 08f659c..0000000
--- a/quic/test_tools/limited_mtu_test_writer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-namespace test {
-
-// Simulates a connection over a link with fixed MTU.  Drops packets which
-// exceed the MTU and passes the rest of them as-is.
-class LimitedMtuTestWriter : public QuicPacketWriterWrapper {
- public:
-  explicit LimitedMtuTestWriter(QuicByteCount mtu);
-  LimitedMtuTestWriter(const LimitedMtuTestWriter&) = delete;
-  LimitedMtuTestWriter& operator=(const LimitedMtuTestWriter&) = delete;
-  ~LimitedMtuTestWriter() override;
-
-  // Inherited from QuicPacketWriterWrapper.
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-
- private:
-  QuicByteCount mtu_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
diff --git a/quic/test_tools/mock_clock.cc b/quic/test_tools/mock_clock.cc
deleted file mode 100644
index 15af152..0000000
--- a/quic/test_tools/mock_clock.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-
-MockClock::MockClock() : now_(QuicTime::Zero()) {}
-
-MockClock::~MockClock() {}
-
-void MockClock::AdvanceTime(QuicTime::Delta delta) {
-  now_ = now_ + delta;
-}
-
-void MockClock::Reset() {
-  now_ = QuicTime::Zero();
-}
-
-QuicTime MockClock::Now() const {
-  return now_;
-}
-
-QuicTime MockClock::ApproximateNow() const {
-  return now_;
-}
-
-QuicWallTime MockClock::WallNow() const {
-  return QuicWallTime::FromUNIXSeconds((now_ - QuicTime::Zero()).ToSeconds());
-}
-
-}  // namespace quic
diff --git a/quic/test_tools/mock_clock.h b/quic/test_tools/mock_clock.h
deleted file mode 100644
index 2ba25a2..0000000
--- a/quic/test_tools/mock_clock.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-class MockClock : public QuicClock {
- public:
-  MockClock();
-  MockClock(const MockClock&) = delete;
-  MockClock& operator=(const MockClock&) = delete;
-  ~MockClock() override;
-
-  // QuicClock implementation:
-  QuicTime Now() const override;
-  QuicTime ApproximateNow() const override;
-  QuicWallTime WallNow() const override;
-
-  // Advances the current time by |delta|, which may be negative.
-  void AdvanceTime(QuicTime::Delta delta);
-  // Resets time back to zero.
-  void Reset();
-
- private:
-  QuicTime now_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
diff --git a/quic/test_tools/mock_quic_client_promised_info.cc b/quic/test_tools/mock_quic_client_promised_info.cc
deleted file mode 100644
index 717641b..0000000
--- a/quic/test_tools/mock_quic_client_promised_info.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_client_promised_info.h"
-
-namespace quic {
-namespace test {
-
-MockQuicClientPromisedInfo::MockQuicClientPromisedInfo(
-    QuicSpdyClientSessionBase* session,
-    QuicStreamId id,
-    std::string url)
-    : QuicClientPromisedInfo(session, id, url) {}
-
-MockQuicClientPromisedInfo::~MockQuicClientPromisedInfo() {}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/mock_quic_client_promised_info.h b/quic/test_tools/mock_quic_client_promised_info.h
deleted file mode 100644
index d40a647..0000000
--- a/quic/test_tools/mock_quic_client_promised_info.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
-
-#include <string>
-
-#include "quic/core/http/quic_client_promised_info.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicClientPromisedInfo : public QuicClientPromisedInfo {
- public:
-  MockQuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
-                             QuicStreamId id,
-                             std::string url);
-  ~MockQuicClientPromisedInfo() override;
-
-  MOCK_METHOD(QuicAsyncStatus,
-              HandleClientRequest,
-              (const spdy::SpdyHeaderBlock& headers,
-               QuicClientPushPromiseIndex::Delegate*),
-              (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/quic/test_tools/mock_quic_dispatcher.cc b/quic/test_tools/mock_quic_dispatcher.cc
deleted file mode 100644
index 3842490..0000000
--- a/quic/test_tools/mock_quic_dispatcher.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_dispatcher.h"
-
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-MockQuicDispatcher::MockQuicDispatcher(
-    const QuicConfig* config,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicVersionManager* version_manager,
-    std::unique_ptr<QuicConnectionHelperInterface> helper,
-    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-    std::unique_ptr<QuicAlarmFactory> alarm_factory,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicSimpleDispatcher(config,
-                           crypto_config,
-                           version_manager,
-                           std::move(helper),
-                           std::move(session_helper),
-                           std::move(alarm_factory),
-                           quic_simple_server_backend,
-                           kQuicDefaultConnectionIdLength) {}
-
-MockQuicDispatcher::~MockQuicDispatcher() {}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/mock_quic_dispatcher.h b/quic/test_tools/mock_quic_dispatcher.h
deleted file mode 100644
index 7d7bec5..0000000
--- a/quic/test_tools/mock_quic_dispatcher.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
-
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-#include "quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicDispatcher : public QuicSimpleDispatcher {
- public:
-  MockQuicDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      QuicSimpleServerBackend* quic_simple_server_backend);
-  MockQuicDispatcher(const MockQuicDispatcher&) = delete;
-  MockQuicDispatcher& operator=(const MockQuicDispatcher&) = delete;
-
-  ~MockQuicDispatcher() override;
-
-  MOCK_METHOD(void,
-              ProcessPacket,
-              (const QuicSocketAddress& server_address,
-               const QuicSocketAddress& client_address,
-               const QuicReceivedPacket& packet),
-              (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
diff --git a/quic/test_tools/mock_quic_session_visitor.cc b/quic/test_tools/mock_quic_session_visitor.cc
deleted file mode 100644
index 5c5db3e..0000000
--- a/quic/test_tools/mock_quic_session_visitor.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_session_visitor.h"
-
-namespace quic {
-namespace test {
-
-MockQuicSessionVisitor::MockQuicSessionVisitor() = default;
-
-MockQuicSessionVisitor::~MockQuicSessionVisitor() = default;
-
-MockQuicCryptoServerStreamHelper::MockQuicCryptoServerStreamHelper() = default;
-
-MockQuicCryptoServerStreamHelper::~MockQuicCryptoServerStreamHelper() = default;
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/mock_quic_session_visitor.h b/quic/test_tools/mock_quic_session_visitor.h
deleted file mode 100644
index 77b1763..0000000
--- a/quic/test_tools/mock_quic_session_visitor.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
-
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicSessionVisitor : public QuicTimeWaitListManager::Visitor {
- public:
-  MockQuicSessionVisitor();
-  MockQuicSessionVisitor(const MockQuicSessionVisitor&) = delete;
-  MockQuicSessionVisitor& operator=(const MockQuicSessionVisitor&) = delete;
-  ~MockQuicSessionVisitor() override;
-  MOCK_METHOD(void,
-              OnConnectionClosed,
-              (QuicConnectionId connection_id,
-               QuicErrorCode error,
-               const std::string& error_details,
-               ConnectionCloseSource source),
-              (override));
-  MOCK_METHOD(void, OnWriteBlocked, (QuicBlockedWriterInterface*), (override));
-  MOCK_METHOD(void,
-              OnRstStreamReceived,
-              (const QuicRstStreamFrame& frame),
-              (override));
-  MOCK_METHOD(void,
-              OnStopSendingReceived,
-              (const QuicStopSendingFrame& frame),
-              (override));
-  MOCK_METHOD(void,
-              OnNewConnectionIdSent,
-              (const QuicConnectionId& server_connection_id,
-               const QuicConnectionId& new_connection_id),
-              (override));
-  MOCK_METHOD(void,
-              OnConnectionIdRetired,
-              (const quic::QuicConnectionId& server_connection_id),
-              (override));
-  MOCK_METHOD(void,
-              OnConnectionAddedToTimeWaitList,
-              (QuicConnectionId connection_id),
-              (override));
-};
-
-class MockQuicCryptoServerStreamHelper
-    : public QuicCryptoServerStreamBase::Helper {
- public:
-  MockQuicCryptoServerStreamHelper();
-  MockQuicCryptoServerStreamHelper(const MockQuicCryptoServerStreamHelper&) =
-      delete;
-  MockQuicCryptoServerStreamHelper& operator=(
-      const MockQuicCryptoServerStreamHelper&) = delete;
-  ~MockQuicCryptoServerStreamHelper() override;
-  MOCK_METHOD(bool,
-              CanAcceptClientHello,
-              (const CryptoHandshakeMessage& message,
-               const QuicSocketAddress& client_address,
-               const QuicSocketAddress& peer_address,
-               const QuicSocketAddress& self_address,
-               std::string*),
-              (const, override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
diff --git a/quic/test_tools/mock_quic_spdy_client_stream.cc b/quic/test_tools/mock_quic_spdy_client_stream.cc
deleted file mode 100644
index fdaa762..0000000
--- a/quic/test_tools/mock_quic_spdy_client_stream.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_spdy_client_stream.h"
-
-namespace quic {
-namespace test {
-
-MockQuicSpdyClientStream::MockQuicSpdyClientStream(
-    QuicStreamId id,
-    QuicSpdyClientSession* session,
-    StreamType type)
-    : QuicSpdyClientStream(id, session, type) {}
-
-MockQuicSpdyClientStream::~MockQuicSpdyClientStream() {}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/mock_quic_spdy_client_stream.h b/quic/test_tools/mock_quic_spdy_client_stream.h
deleted file mode 100644
index 491f700..0000000
--- a/quic/test_tools/mock_quic_spdy_client_stream.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
-
-#include "quic/core/http/quic_header_list.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicSpdyClientStream : public QuicSpdyClientStream {
- public:
-  MockQuicSpdyClientStream(QuicStreamId id,
-                           QuicSpdyClientSession* session,
-                           StreamType type);
-  ~MockQuicSpdyClientStream() override;
-
-  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
-  MOCK_METHOD(void,
-              OnPromiseHeaderList,
-              (QuicStreamId promised_stream_id,
-               size_t frame_len,
-               const QuicHeaderList& list),
-              (override));
-  MOCK_METHOD(void, OnDataAvailable, (), (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/quic/test_tools/mock_quic_time_wait_list_manager.cc b/quic/test_tools/mock_quic_time_wait_list_manager.cc
deleted file mode 100644
index 63858c9..0000000
--- a/quic/test_tools/mock_quic_time_wait_list_manager.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_quic_time_wait_list_manager.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-MockTimeWaitListManager::MockTimeWaitListManager(
-    QuicPacketWriter* writer,
-    Visitor* visitor,
-    const QuicClock* clock,
-    QuicAlarmFactory* alarm_factory)
-    : QuicTimeWaitListManager(writer, visitor, clock, alarm_factory) {
-  // Though AddConnectionIdToTimeWait is mocked, we want to retain its
-  // functionality.
-  EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _))
-      .Times(testing::AnyNumber());
-  ON_CALL(*this, AddConnectionIdToTimeWait(_, _))
-      .WillByDefault(
-          Invoke(this, &MockTimeWaitListManager::
-                           QuicTimeWaitListManager_AddConnectionIdToTimeWait));
-}
-
-MockTimeWaitListManager::~MockTimeWaitListManager() = default;
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/mock_quic_time_wait_list_manager.h b/quic/test_tools/mock_quic_time_wait_list_manager.h
deleted file mode 100644
index 1d3cfd5..0000000
--- a/quic/test_tools/mock_quic_time_wait_list_manager.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
-
-#include "quic/core/quic_time_wait_list_manager.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockTimeWaitListManager : public QuicTimeWaitListManager {
- public:
-  MockTimeWaitListManager(QuicPacketWriter* writer,
-                          Visitor* visitor,
-                          const QuicClock* clock,
-                          QuicAlarmFactory* alarm_factory);
-  ~MockTimeWaitListManager() override;
-
-  MOCK_METHOD(void, AddConnectionIdToTimeWait,
-              (QuicTimeWaitListManager::TimeWaitAction action,
-               quic::TimeWaitConnectionInfo info),
-              (override));
-
-  void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
-      QuicTimeWaitListManager::TimeWaitAction action,
-      quic::TimeWaitConnectionInfo info) {
-    QuicTimeWaitListManager::AddConnectionIdToTimeWait(action, std::move(info));
-  }
-
-  MOCK_METHOD(void,
-              ProcessPacket,
-              (const QuicSocketAddress&,
-               const QuicSocketAddress&,
-               QuicConnectionId,
-               PacketHeaderFormat,
-               size_t,
-               std::unique_ptr<QuicPerPacketContext>),
-              (override));
-
-  MOCK_METHOD(void,
-              SendVersionNegotiationPacket,
-              (QuicConnectionId server_connection_id,
-               QuicConnectionId client_connection_id,
-               bool ietf_quic,
-               bool has_length_prefix,
-               const ParsedQuicVersionVector& supported_versions,
-               const QuicSocketAddress& server_address,
-               const QuicSocketAddress& client_address,
-               std::unique_ptr<QuicPerPacketContext> packet_context),
-              (override));
-
-  MOCK_METHOD(void,
-              SendPublicReset,
-              (const QuicSocketAddress&,
-               const QuicSocketAddress&,
-               QuicConnectionId,
-               bool,
-               size_t,
-               std::unique_ptr<QuicPerPacketContext>),
-              (override));
-
-  MOCK_METHOD(void,
-              SendPacket,
-              (const QuicSocketAddress&,
-               const QuicSocketAddress&,
-               const QuicEncryptedPacket&),
-              (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/quic/test_tools/mock_random.cc b/quic/test_tools/mock_random.cc
deleted file mode 100644
index a789cdf..0000000
--- a/quic/test_tools/mock_random.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/mock_random.h"
-
-#include <string.h>
-
-namespace quic {
-namespace test {
-
-MockRandom::MockRandom() : base_(0xDEADBEEF), increment_(0) {}
-
-MockRandom::MockRandom(uint32_t base) : base_(base), increment_(0) {}
-
-void MockRandom::RandBytes(void* data, size_t len) {
-  memset(data, increment_ + static_cast<uint8_t>('r'), len);
-}
-
-uint64_t MockRandom::RandUint64() {
-  return base_ + increment_;
-}
-
-void MockRandom::InsecureRandBytes(void* data, size_t len) {
-  RandBytes(data, len);
-}
-
-uint64_t MockRandom::InsecureRandUint64() {
-  return RandUint64();
-}
-
-void MockRandom::ChangeValue() {
-  increment_++;
-}
-
-void MockRandom::ResetBase(uint32_t base) {
-  base_ = base;
-  increment_ = 0;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/mock_random.h b/quic/test_tools/mock_random.h
deleted file mode 100644
index 8dba860..0000000
--- a/quic/test_tools/mock_random.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
-#define QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
-
-#include "quic/core/crypto/quic_random.h"
-
-namespace quic {
-namespace test {
-
-class MockRandom : public QuicRandom {
- public:
-  // Initializes base_ to 0xDEADBEEF.
-  MockRandom();
-  explicit MockRandom(uint32_t base);
-  MockRandom(const MockRandom&) = delete;
-  MockRandom& operator=(const MockRandom&) = delete;
-
-  // QuicRandom:
-  // Fills the |data| buffer with a repeating byte, initially 'r'.
-  void RandBytes(void* data, size_t len) override;
-  // Returns base + the current increment.
-  uint64_t RandUint64() override;
-
-  // InsecureRandBytes behaves equivalently to RandBytes.
-  void InsecureRandBytes(void* data, size_t len) override;
-  // InsecureRandUint64 behaves equivalently to RandUint64.
-  uint64_t InsecureRandUint64() override;
-
-  // ChangeValue increments |increment_|. This causes the value returned by
-  // |RandUint64| and the byte that |RandBytes| fills with, to change.
-  void ChangeValue();
-
-  // Sets the base to |base| and resets increment to zero.
-  void ResetBase(uint32_t base);
-
- private:
-  uint32_t base_;
-  uint8_t increment_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
diff --git a/quic/test_tools/packet_dropping_test_writer.cc b/quic/test_tools/packet_dropping_test_writer.cc
deleted file mode 100644
index 079b228..0000000
--- a/quic/test_tools/packet_dropping_test_writer.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/packet_dropping_test_writer.h"
-
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace test {
-
-// Every dropped packet must be followed by this number of succesfully written
-// packets. This is to avoid flaky test failures and timeouts, for example, in
-// case both the client and the server drop every other packet (which is
-// statistically possible even if drop percentage is less than 50%).
-const int32_t kMinSuccesfulWritesAfterPacketLoss = 2;
-
-// An alarm that is scheduled if a blocked socket is simulated to indicate
-// it's writable again.
-class WriteUnblockedAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit WriteUnblockedAlarm(PacketDroppingTestWriter* writer)
-      : writer_(writer) {}
-
-  void OnAlarm() override {
-    QUIC_DLOG(INFO) << "Unblocking socket.";
-    writer_->OnCanWrite();
-  }
-
- private:
-  PacketDroppingTestWriter* writer_;
-};
-
-// An alarm that is scheduled every time a new packet is to be written at a
-// later point.
-class DelayAlarm : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit DelayAlarm(PacketDroppingTestWriter* writer) : writer_(writer) {}
-
-  void OnAlarm() override {
-    QuicTime new_deadline = writer_->ReleaseOldPackets();
-    if (new_deadline.IsInitialized()) {
-      writer_->SetDelayAlarm(new_deadline);
-    }
-  }
-
- private:
-  PacketDroppingTestWriter* writer_;
-};
-
-PacketDroppingTestWriter::PacketDroppingTestWriter()
-    : clock_(nullptr),
-      cur_buffer_size_(0),
-      num_calls_to_write_(0),
-      // Do not require any number of successful writes before the first dropped
-      // packet.
-      num_consecutive_succesful_writes_(kMinSuccesfulWritesAfterPacketLoss),
-      fake_packet_loss_percentage_(0),
-      fake_drop_first_n_packets_(0),
-      fake_blocked_socket_percentage_(0),
-      fake_packet_reorder_percentage_(0),
-      fake_packet_delay_(QuicTime::Delta::Zero()),
-      fake_bandwidth_(QuicBandwidth::Zero()),
-      buffer_size_(0) {
-  uint64_t seed = QuicRandom::GetInstance()->RandUint64();
-  QUIC_LOG(INFO) << "Seeding packet loss with " << seed;
-  simple_random_.set_seed(seed);
-}
-
-PacketDroppingTestWriter::~PacketDroppingTestWriter() {
-  if (write_unblocked_alarm_ != nullptr) {
-    write_unblocked_alarm_->PermanentCancel();
-  }
-  if (delay_alarm_ != nullptr) {
-    delay_alarm_->PermanentCancel();
-  }
-}
-
-void PacketDroppingTestWriter::Initialize(
-    QuicConnectionHelperInterface* helper,
-    QuicAlarmFactory* alarm_factory,
-    std::unique_ptr<Delegate> on_can_write) {
-  clock_ = helper->GetClock();
-  write_unblocked_alarm_.reset(
-      alarm_factory->CreateAlarm(new WriteUnblockedAlarm(this)));
-  delay_alarm_.reset(alarm_factory->CreateAlarm(new DelayAlarm(this)));
-  on_can_write_ = std::move(on_can_write);
-}
-
-WriteResult PacketDroppingTestWriter::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  ++num_calls_to_write_;
-  ReleaseOldPackets();
-
-  QuicWriterMutexLock lock(&config_mutex_);
-  if (fake_drop_first_n_packets_ > 0 &&
-      num_calls_to_write_ <=
-          static_cast<uint64_t>(fake_drop_first_n_packets_)) {
-    QUIC_DVLOG(1) << "Dropping first " << fake_drop_first_n_packets_
-                  << " packets (packet number " << num_calls_to_write_ << ")";
-    num_consecutive_succesful_writes_ = 0;
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
-  // Drop every packet at 100%, otherwise always succeed for at least
-  // kMinSuccesfulWritesAfterPacketLoss packets between two dropped ones.
-  if (fake_packet_loss_percentage_ == 100 ||
-      (fake_packet_loss_percentage_ > 0 &&
-       num_consecutive_succesful_writes_ >=
-           kMinSuccesfulWritesAfterPacketLoss &&
-       (simple_random_.RandUint64() % 100 <
-        static_cast<uint64_t>(fake_packet_loss_percentage_)))) {
-    QUIC_DVLOG(1) << "Dropping packet " << num_calls_to_write_;
-    num_consecutive_succesful_writes_ = 0;
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  } else {
-    ++num_consecutive_succesful_writes_;
-  }
-
-  if (fake_blocked_socket_percentage_ > 0 &&
-      simple_random_.RandUint64() % 100 <
-          static_cast<uint64_t>(fake_blocked_socket_percentage_)) {
-    QUICHE_CHECK(on_can_write_ != nullptr);
-    QUIC_DVLOG(1) << "Blocking socket for packet " << num_calls_to_write_;
-    if (!write_unblocked_alarm_->IsSet()) {
-      // Set the alarm to fire immediately.
-      write_unblocked_alarm_->Set(clock_->ApproximateNow());
-    }
-
-    // Dropping this packet on retry could result in PTO timeout,
-    // make sure to avoid this.
-    num_consecutive_succesful_writes_ = 0;
-
-    return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN);
-  }
-
-  if (!fake_packet_delay_.IsZero() || !fake_bandwidth_.IsZero()) {
-    if (buffer_size_ > 0 && buf_len + cur_buffer_size_ > buffer_size_) {
-      // Drop packets which do not fit into the buffer.
-      QUIC_DVLOG(1) << "Dropping packet because the buffer is full.";
-      return WriteResult(WRITE_STATUS_OK, buf_len);
-    }
-
-    // Queue it to be sent.
-    QuicTime send_time = clock_->ApproximateNow() + fake_packet_delay_;
-    if (!fake_bandwidth_.IsZero()) {
-      // Calculate a time the bandwidth limit would impose.
-      QuicTime::Delta bandwidth_delay = QuicTime::Delta::FromMicroseconds(
-          (buf_len * kNumMicrosPerSecond) / fake_bandwidth_.ToBytesPerSecond());
-      send_time = delayed_packets_.empty()
-                      ? send_time + bandwidth_delay
-                      : delayed_packets_.back().send_time + bandwidth_delay;
-    }
-    std::unique_ptr<PerPacketOptions> delayed_options;
-    if (options != nullptr) {
-      delayed_options = options->Clone();
-    }
-    delayed_packets_.push_back(
-        DelayedWrite(buffer, buf_len, self_address, peer_address,
-                     std::move(delayed_options), send_time));
-    cur_buffer_size_ += buf_len;
-
-    // Set the alarm if it's not yet set.
-    if (!delay_alarm_->IsSet()) {
-      delay_alarm_->Set(send_time);
-    }
-
-    return WriteResult(WRITE_STATUS_OK, buf_len);
-  }
-
-  return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
-                                              peer_address, options);
-}
-
-bool PacketDroppingTestWriter::IsWriteBlocked() const {
-  if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
-    return true;
-  }
-  return QuicPacketWriterWrapper::IsWriteBlocked();
-}
-
-void PacketDroppingTestWriter::SetWritable() {
-  if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
-    write_unblocked_alarm_->Cancel();
-  }
-  QuicPacketWriterWrapper::SetWritable();
-}
-
-QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
-  if (delayed_packets_.empty()) {
-    return QuicTime::Zero();
-  }
-  QuicReaderMutexLock lock(&config_mutex_);
-  auto iter = delayed_packets_.begin();
-  // Determine if we should re-order.
-  if (delayed_packets_.size() > 1 && fake_packet_reorder_percentage_ > 0 &&
-      simple_random_.RandUint64() % 100 <
-          static_cast<uint64_t>(fake_packet_reorder_percentage_)) {
-    QUIC_DLOG(INFO) << "Reordering packets.";
-    ++iter;
-    // Swap the send times when re-ordering packets.
-    delayed_packets_.begin()->send_time = iter->send_time;
-  }
-
-  QUIC_DVLOG(1) << "Releasing packet.  " << (delayed_packets_.size() - 1)
-                << " remaining.";
-  // Grab the next one off the queue and send it.
-  QuicPacketWriterWrapper::WritePacket(
-      iter->buffer.data(), iter->buffer.length(), iter->self_address,
-      iter->peer_address, iter->options.get());
-  QUICHE_DCHECK_GE(cur_buffer_size_, iter->buffer.length());
-  cur_buffer_size_ -= iter->buffer.length();
-  delayed_packets_.erase(iter);
-
-  // If there are others, find the time for the next to be sent.
-  if (delayed_packets_.empty()) {
-    return QuicTime::Zero();
-  }
-  return delayed_packets_.begin()->send_time;
-}
-
-QuicTime PacketDroppingTestWriter::ReleaseOldPackets() {
-  while (!delayed_packets_.empty()) {
-    QuicTime next_send_time = delayed_packets_.front().send_time;
-    if (next_send_time > clock_->Now()) {
-      return next_send_time;
-    }
-    ReleaseNextPacket();
-  }
-  return QuicTime::Zero();
-}
-
-void PacketDroppingTestWriter::SetDelayAlarm(QuicTime new_deadline) {
-  delay_alarm_->Set(new_deadline);
-}
-
-void PacketDroppingTestWriter::OnCanWrite() {
-  on_can_write_->OnCanWrite();
-}
-
-PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    std::unique_ptr<PerPacketOptions> options,
-    QuicTime send_time)
-    : buffer(buffer, buf_len),
-      self_address(self_address),
-      peer_address(peer_address),
-      options(std::move(options)),
-      send_time(send_time) {}
-
-PacketDroppingTestWriter::DelayedWrite::~DelayedWrite() = default;
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/packet_dropping_test_writer.h b/quic/test_tools/packet_dropping_test_writer.h
deleted file mode 100644
index c15b5de..0000000
--- a/quic/test_tools/packet_dropping_test_writer.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
-
-#include <cstdint>
-#include <list>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/test_tools/quic_test_client.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// Simulates a connection that drops packets a configured percentage of the time
-// and has a blocked socket a configured percentage of the time.  Also provides
-// the options to delay packets and reorder packets if delay is enabled.
-class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
- public:
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-    virtual void OnCanWrite() = 0;
-  };
-
-  PacketDroppingTestWriter();
-  PacketDroppingTestWriter(const PacketDroppingTestWriter&) = delete;
-  PacketDroppingTestWriter& operator=(const PacketDroppingTestWriter&) = delete;
-
-  ~PacketDroppingTestWriter() override;
-
-  // Must be called before blocking, reordering or delaying (loss is OK). May be
-  // called after connecting if the helper is not available before.
-  // |on_can_write| will be triggered when fake-unblocking.
-  void Initialize(QuicConnectionHelperInterface* helper,
-                  QuicAlarmFactory* alarm_factory,
-                  std::unique_ptr<Delegate> on_can_write);
-
-  // QuicPacketWriter methods:
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-
-  bool IsWriteBlocked() const override;
-
-  void SetWritable() override;
-
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& /*self_address*/,
-      const QuicSocketAddress& /*peer_address*/) override {
-    // If the wrapped writer supports zero-copy, disable it, because it is not
-    // compatible with delayed writes in this class.
-    return {nullptr, nullptr};
-  }
-
-  // Writes out any packet which should have been sent by now
-  // to the contained writer and returns the time
-  // for the next delayed packet to be written.
-  QuicTime ReleaseOldPackets();
-
-  // Sets |delay_alarm_| to fire at |new_deadline|.
-  void SetDelayAlarm(QuicTime new_deadline);
-
-  void OnCanWrite();
-
-  // The percent of time a packet is simulated as being lost.
-  // If |fake_packet_loss_percentage| is 100, then all packages are lost.
-  // Otherwise actual percentage will be lower than
-  // |fake_packet_loss_percentage|, because every dropped package is followed by
-  // a minimum number of successfully written packets.
-  void set_fake_packet_loss_percentage(int32_t fake_packet_loss_percentage) {
-    QuicWriterMutexLock lock(&config_mutex_);
-    fake_packet_loss_percentage_ = fake_packet_loss_percentage;
-  }
-
-  // Simulate dropping the first n packets unconditionally.
-  // Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
-  void set_fake_drop_first_n_packets(int32_t fake_drop_first_n_packets) {
-    QuicWriterMutexLock lock(&config_mutex_);
-    fake_drop_first_n_packets_ = fake_drop_first_n_packets;
-  }
-
-  // The percent of time WritePacket will block and set WriteResult's status
-  // to WRITE_STATUS_BLOCKED.
-  void set_fake_blocked_socket_percentage(
-      int32_t fake_blocked_socket_percentage) {
-    QUICHE_DCHECK(clock_);
-    QuicWriterMutexLock lock(&config_mutex_);
-    fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
-  }
-
-  // The percent of time a packet is simulated as being reordered.
-  void set_fake_reorder_percentage(int32_t fake_packet_reorder_percentage) {
-    QUICHE_DCHECK(clock_);
-    QuicWriterMutexLock lock(&config_mutex_);
-    QUICHE_DCHECK(!fake_packet_delay_.IsZero());
-    fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
-  }
-
-  // The delay before writing this packet.
-  void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
-    QUICHE_DCHECK(clock_);
-    QuicWriterMutexLock lock(&config_mutex_);
-    fake_packet_delay_ = fake_packet_delay;
-  }
-
-  // The maximum bandwidth and buffer size of the connection.  When these are
-  // set, packets will be delayed until a connection with that bandwidth would
-  // transmit it.  Once the |buffer_size| is reached, all new packets are
-  // dropped.
-  void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
-                                         QuicByteCount buffer_size) {
-    QUICHE_DCHECK(clock_);
-    QuicWriterMutexLock lock(&config_mutex_);
-    fake_bandwidth_ = fake_bandwidth;
-    buffer_size_ = buffer_size;
-  }
-
-  // Useful for reproducing very flaky issues.
-  ABSL_ATTRIBUTE_UNUSED void set_seed(uint64_t seed) {
-    simple_random_.set_seed(seed);
-  }
-
- private:
-  // Writes out the next packet to the contained writer and returns the time
-  // for the next delayed packet to be written.
-  QuicTime ReleaseNextPacket();
-
-  // A single packet which will be sent at the supplied send_time.
-  struct DelayedWrite {
-   public:
-    DelayedWrite(const char* buffer,
-                 size_t buf_len,
-                 const QuicIpAddress& self_address,
-                 const QuicSocketAddress& peer_address,
-                 std::unique_ptr<PerPacketOptions> options,
-                 QuicTime send_time);
-    DelayedWrite(const DelayedWrite&) = delete;
-    DelayedWrite(DelayedWrite&&) = default;
-    DelayedWrite& operator=(const DelayedWrite&) = delete;
-    DelayedWrite& operator=(DelayedWrite&&) = default;
-    ~DelayedWrite();
-
-    std::string buffer;
-    QuicIpAddress self_address;
-    QuicSocketAddress peer_address;
-    std::unique_ptr<PerPacketOptions> options;
-    QuicTime send_time;
-  };
-
-  using DelayedPacketList = std::list<DelayedWrite>;
-
-  const QuicClock* clock_;
-  std::unique_ptr<QuicAlarm> write_unblocked_alarm_;
-  std::unique_ptr<QuicAlarm> delay_alarm_;
-  std::unique_ptr<Delegate> on_can_write_;
-  SimpleRandom simple_random_;
-  // Stored packets delayed by fake packet delay or bandwidth restrictions.
-  DelayedPacketList delayed_packets_;
-  QuicByteCount cur_buffer_size_;
-  uint64_t num_calls_to_write_;
-  int32_t num_consecutive_succesful_writes_;
-
-  QuicMutex config_mutex_;
-  int32_t fake_packet_loss_percentage_ QUIC_GUARDED_BY(config_mutex_);
-  int32_t fake_drop_first_n_packets_ QUIC_GUARDED_BY(config_mutex_);
-  int32_t fake_blocked_socket_percentage_ QUIC_GUARDED_BY(config_mutex_);
-  int32_t fake_packet_reorder_percentage_ QUIC_GUARDED_BY(config_mutex_);
-  QuicTime::Delta fake_packet_delay_ QUIC_GUARDED_BY(config_mutex_);
-  QuicBandwidth fake_bandwidth_ QUIC_GUARDED_BY(config_mutex_);
-  QuicByteCount buffer_size_ QUIC_GUARDED_BY(config_mutex_);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
diff --git a/quic/test_tools/packet_reordering_writer.cc b/quic/test_tools/packet_reordering_writer.cc
deleted file mode 100644
index 1b931eb..0000000
--- a/quic/test_tools/packet_reordering_writer.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/packet_reordering_writer.h"
-
-namespace quic {
-namespace test {
-
-PacketReorderingWriter::PacketReorderingWriter() = default;
-
-PacketReorderingWriter::~PacketReorderingWriter() = default;
-
-WriteResult PacketReorderingWriter::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    PerPacketOptions* options) {
-  if (!delay_next_) {
-    QUIC_VLOG(2) << "Writing a non-delayed packet";
-    WriteResult wr = QuicPacketWriterWrapper::WritePacket(
-        buffer, buf_len, self_address, peer_address, options);
-    --num_packets_to_wait_;
-    if (num_packets_to_wait_ == 0) {
-      QUIC_VLOG(2) << "Writing a delayed packet";
-      // It's time to write the delayed packet.
-      QuicPacketWriterWrapper::WritePacket(
-          delayed_data_.data(), delayed_data_.length(), delayed_self_address_,
-          delayed_peer_address_, delayed_options_.get());
-    }
-    return wr;
-  }
-  // Still have packet to wait.
-  QUICHE_DCHECK_LT(0u, num_packets_to_wait_)
-      << "Only allow one packet to be delayed";
-  delayed_data_ = std::string(buffer, buf_len);
-  delayed_self_address_ = self_address;
-  delayed_peer_address_ = peer_address;
-  if (options != nullptr) {
-    delayed_options_ = options->Clone();
-  }
-  delay_next_ = false;
-  return WriteResult(WRITE_STATUS_OK, buf_len);
-}
-
-void PacketReorderingWriter::SetDelay(size_t num_packets_to_wait) {
-  QUICHE_DCHECK_GT(num_packets_to_wait, 0u);
-  num_packets_to_wait_ = num_packets_to_wait;
-  delay_next_ = true;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/packet_reordering_writer.h b/quic/test_tools/packet_reordering_writer.h
deleted file mode 100644
index 2711a9f..0000000
--- a/quic/test_tools/packet_reordering_writer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
-#define QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
-
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-namespace quic {
-
-namespace test {
-
-// This packet writer allows delaying writing the next packet after
-// SetDelay(num_packets_to_wait)
-// is called and buffer this packet and write it after it writes next
-// |num_packets_to_wait| packets. It doesn't support delaying a packet while
-// there is already a packet delayed.
-class PacketReorderingWriter : public QuicPacketWriterWrapper {
- public:
-  PacketReorderingWriter();
-
-  ~PacketReorderingWriter() override;
-
-  WriteResult WritePacket(const char* buffer,
-                          size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-
-  void SetDelay(size_t num_packets_to_wait);
-
- private:
-  bool delay_next_ = false;
-  size_t num_packets_to_wait_ = 0;
-  std::string delayed_data_;
-  QuicIpAddress delayed_self_address_;
-  QuicSocketAddress delayed_peer_address_;
-  std::unique_ptr<PerPacketOptions> delayed_options_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
diff --git a/quic/test_tools/qpack/qpack_decoder_test_utils.cc b/quic/test_tools/qpack/qpack_decoder_test_utils.cc
deleted file mode 100644
index 37f182a..0000000
--- a/quic/test_tools/qpack/qpack_decoder_test_utils.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-void NoopEncoderStreamErrorDelegate::OnEncoderStreamError(
-    QuicErrorCode /* error_code */,
-    absl::string_view /*error_message*/) {}
-
-TestHeadersHandler::TestHeadersHandler()
-    : decoding_completed_(false), decoding_error_detected_(false) {}
-
-void TestHeadersHandler::OnHeaderDecoded(absl::string_view name,
-                                         absl::string_view value) {
-  ASSERT_FALSE(decoding_completed_);
-  ASSERT_FALSE(decoding_error_detected_);
-
-  header_list_.AppendValueOrAddHeader(name, value);
-}
-
-void TestHeadersHandler::OnDecodingCompleted() {
-  ASSERT_FALSE(decoding_completed_);
-  ASSERT_FALSE(decoding_error_detected_);
-
-  decoding_completed_ = true;
-}
-
-void TestHeadersHandler::OnDecodingErrorDetected(
-    QuicErrorCode /*error_code*/, absl::string_view error_message) {
-  ASSERT_FALSE(decoding_completed_);
-  ASSERT_FALSE(decoding_error_detected_);
-
-  decoding_error_detected_ = true;
-  error_message_.assign(error_message.data(), error_message.size());
-}
-
-spdy::Http2HeaderBlock TestHeadersHandler::ReleaseHeaderList() {
-  QUICHE_DCHECK(decoding_completed_);
-  QUICHE_DCHECK(!decoding_error_detected_);
-
-  return std::move(header_list_);
-}
-
-bool TestHeadersHandler::decoding_completed() const {
-  return decoding_completed_;
-}
-
-bool TestHeadersHandler::decoding_error_detected() const {
-  return decoding_error_detected_;
-}
-
-const std::string& TestHeadersHandler::error_message() const {
-  QUICHE_DCHECK(decoding_error_detected_);
-  return error_message_;
-}
-
-void QpackDecode(
-    uint64_t maximum_dynamic_table_capacity,
-    uint64_t maximum_blocked_streams,
-    QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate,
-    QpackStreamSenderDelegate* decoder_stream_sender_delegate,
-    QpackProgressiveDecoder::HeadersHandlerInterface* handler,
-    const FragmentSizeGenerator& fragment_size_generator,
-    absl::string_view data) {
-  QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
-                       encoder_stream_error_delegate);
-  decoder.set_qpack_stream_sender_delegate(decoder_stream_sender_delegate);
-  auto progressive_decoder =
-      decoder.CreateProgressiveDecoder(/* stream_id = */ 1, handler);
-  while (!data.empty()) {
-    size_t fragment_size = std::min(fragment_size_generator(), data.size());
-    progressive_decoder->Decode(data.substr(0, fragment_size));
-    data = data.substr(fragment_size);
-  }
-  progressive_decoder->EndHeaderBlock();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/qpack/qpack_decoder_test_utils.h b/quic/test_tools/qpack/qpack_decoder_test_utils.h
deleted file mode 100644
index b6bff78..0000000
--- a/quic/test_tools/qpack/qpack_decoder_test_utils.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/qpack/qpack_progressive_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-namespace test {
-
-// QpackDecoder::EncoderStreamErrorDelegate implementation that does nothing.
-class NoopEncoderStreamErrorDelegate
-    : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
-  ~NoopEncoderStreamErrorDelegate() override = default;
-
-  void OnEncoderStreamError(QuicErrorCode error_code,
-                            absl::string_view error_message) override;
-};
-
-// Mock QpackDecoder::EncoderStreamErrorDelegate implementation.
-class MockEncoderStreamErrorDelegate
-    : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
-  ~MockEncoderStreamErrorDelegate() override = default;
-
-  MOCK_METHOD(void,
-              OnEncoderStreamError,
-              (QuicErrorCode error_code, absl::string_view error_message),
-              (override));
-};
-
-// HeadersHandlerInterface implementation that collects decoded headers
-// into a Http2HeaderBlock.
-class TestHeadersHandler
-    : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
-  TestHeadersHandler();
-  ~TestHeadersHandler() override = default;
-
-  // HeadersHandlerInterface implementation:
-  void OnHeaderDecoded(absl::string_view name,
-                       absl::string_view value) override;
-  void OnDecodingCompleted() override;
-  void OnDecodingErrorDetected(QuicErrorCode error_code,
-                               absl::string_view error_message) override;
-
-  // Release decoded header list.  Must only be called if decoding is complete
-  // and no errors have been detected.
-  spdy::Http2HeaderBlock ReleaseHeaderList();
-
-  bool decoding_completed() const;
-  bool decoding_error_detected() const;
-  const std::string& error_message() const;
-
- private:
-  spdy::Http2HeaderBlock header_list_;
-  bool decoding_completed_;
-  bool decoding_error_detected_;
-  std::string error_message_;
-};
-
-class MockHeadersHandler
-    : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
-  MockHeadersHandler() = default;
-  MockHeadersHandler(const MockHeadersHandler&) = delete;
-  MockHeadersHandler& operator=(const MockHeadersHandler&) = delete;
-  ~MockHeadersHandler() override = default;
-
-  MOCK_METHOD(void,
-              OnHeaderDecoded,
-              (absl::string_view name, absl::string_view value),
-              (override));
-  MOCK_METHOD(void, OnDecodingCompleted, (), (override));
-  MOCK_METHOD(void, OnDecodingErrorDetected,
-              (QuicErrorCode error_code, absl::string_view error_message),
-              (override));
-};
-
-class NoOpHeadersHandler
-    : public QpackProgressiveDecoder::HeadersHandlerInterface {
- public:
-  ~NoOpHeadersHandler() override = default;
-
-  void OnHeaderDecoded(absl::string_view /*name*/,
-                       absl::string_view /*value*/) override {}
-  void OnDecodingCompleted() override {}
-  void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
-                               absl::string_view /*error_message*/) override {}
-};
-
-void QpackDecode(
-    uint64_t maximum_dynamic_table_capacity,
-    uint64_t maximum_blocked_streams,
-    QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate,
-    QpackStreamSenderDelegate* decoder_stream_sender_delegate,
-    QpackProgressiveDecoder::HeadersHandlerInterface* handler,
-    const FragmentSizeGenerator& fragment_size_generator,
-    absl::string_view data);
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
diff --git a/quic/test_tools/qpack/qpack_encoder_peer.cc b/quic/test_tools/qpack/qpack_encoder_peer.cc
deleted file mode 100644
index cc5f010..0000000
--- a/quic/test_tools/qpack/qpack_encoder_peer.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_encoder_peer.h"
-
-#include "quic/core/qpack/qpack_encoder.h"
-
-namespace quic {
-namespace test {
-
-// static
-QpackEncoderHeaderTable* QpackEncoderPeer::header_table(QpackEncoder* encoder) {
-  return &encoder->header_table_;
-}
-
-// static
-uint64_t QpackEncoderPeer::maximum_blocked_streams(
-    const QpackEncoder* encoder) {
-  return encoder->maximum_blocked_streams_;
-}
-
-// static
-uint64_t QpackEncoderPeer::smallest_blocking_index(
-    const QpackEncoder* encoder) {
-  return encoder->blocking_manager_.smallest_blocking_index();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/qpack/qpack_encoder_test_utils.cc b/quic/test_tools/qpack/qpack_encoder_test_utils.cc
deleted file mode 100644
index 20be113..0000000
--- a/quic/test_tools/qpack/qpack_encoder_test_utils.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_encoder_test_utils.h"
-
-#include "absl/strings/string_view.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-
-namespace quic {
-namespace test {
-
-void NoopDecoderStreamErrorDelegate::OnDecoderStreamError(
-    QuicErrorCode /*error_code*/,
-    absl::string_view /*error_message*/) {}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/qpack/qpack_encoder_test_utils.h b/quic/test_tools/qpack/qpack_encoder_test_utils.h
deleted file mode 100644
index ec58c3f..0000000
--- a/quic/test_tools/qpack/qpack_encoder_test_utils.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_encoder.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-namespace test {
-
-// QpackEncoder::DecoderStreamErrorDelegate implementation that does nothing.
-class NoopDecoderStreamErrorDelegate
-    : public QpackEncoder::DecoderStreamErrorDelegate {
- public:
-  ~NoopDecoderStreamErrorDelegate() override = default;
-
-  void OnDecoderStreamError(QuicErrorCode error_code,
-                            absl::string_view error_message) override;
-};
-
-// Mock QpackEncoder::DecoderStreamErrorDelegate implementation.
-class MockDecoderStreamErrorDelegate
-    : public QpackEncoder::DecoderStreamErrorDelegate {
- public:
-  ~MockDecoderStreamErrorDelegate() override = default;
-
-  MOCK_METHOD(void,
-              OnDecoderStreamError,
-              (QuicErrorCode error_code, absl::string_view error_message),
-              (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
diff --git a/quic/test_tools/qpack/qpack_offline_decoder.cc b/quic/test_tools/qpack/qpack_offline_decoder.cc
deleted file mode 100644
index a7ea1be..0000000
--- a/quic/test_tools/qpack/qpack_offline_decoder.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Decoder to test QPACK Offline Interop corpus
-//
-// See https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop for
-// description of test data format.
-//
-// Example usage
-//
-//  cd $TEST_DATA
-//  git clone https://github.com/qpackers/qifs.git
-//  TEST_ENCODED_DATA=$TEST_DATA/qifs/encoded/qpack-06
-//  TEST_QIF_DATA=$TEST_DATA/qifs/qifs
-//  $BIN/qpack_offline_decoder \
-//      $TEST_ENCODED_DATA/f5/fb-req.qifencoded.4096.100.0 \
-//      $TEST_QIF_DATA/fb-req.qif
-//      $TEST_ENCODED_DATA/h2o/fb-req-hq.out.512.0.1 \
-//      $TEST_QIF_DATA/fb-req-hq.qif
-//      $TEST_ENCODED_DATA/ls-qpack/fb-resp-hq.out.0.0.0 \
-//      $TEST_QIF_DATA/fb-resp-hq.qif
-//      $TEST_ENCODED_DATA/proxygen/netbsd.qif.proxygen.out.4096.0.0 \
-//      $TEST_QIF_DATA/netbsd.qif
-//
-
-#include "quic/test_tools/qpack/qpack_offline_decoder.h"
-
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/match.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "common/platform/api/quiche_file_utils.h"
-#include "common/quiche_endian.h"
-
-namespace quic {
-
-QpackOfflineDecoder::QpackOfflineDecoder()
-    : encoder_stream_error_detected_(false) {}
-
-bool QpackOfflineDecoder::DecodeAndVerifyOfflineData(
-    absl::string_view input_filename,
-    absl::string_view expected_headers_filename) {
-  if (!ParseInputFilename(input_filename)) {
-    QUIC_LOG(ERROR) << "Error parsing input filename " << input_filename;
-    return false;
-  }
-
-  if (!DecodeHeaderBlocksFromFile(input_filename)) {
-    QUIC_LOG(ERROR) << "Error decoding header blocks in " << input_filename;
-    return false;
-  }
-
-  if (!VerifyDecodedHeaderLists(expected_headers_filename)) {
-    QUIC_LOG(ERROR) << "Header lists decoded from " << input_filename
-                    << " to not match expected headers parsed from "
-                    << expected_headers_filename;
-    return false;
-  }
-
-  return true;
-}
-
-void QpackOfflineDecoder::OnEncoderStreamError(
-    QuicErrorCode error_code, absl::string_view error_message) {
-  QUIC_LOG(ERROR) << "Encoder stream error: "
-                  << QuicErrorCodeToString(error_code) << " " << error_message;
-  encoder_stream_error_detected_ = true;
-}
-
-bool QpackOfflineDecoder::ParseInputFilename(absl::string_view input_filename) {
-  std::vector<absl::string_view> pieces = absl::StrSplit(input_filename, '.');
-
-  if (pieces.size() < 3) {
-    QUIC_LOG(ERROR) << "Not enough fields in input filename " << input_filename;
-    return false;
-  }
-
-  auto piece_it = pieces.rbegin();
-
-  // Acknowledgement mode: 1 for immediate, 0 for none.
-  if (*piece_it != "0" && *piece_it != "1") {
-    QUIC_LOG(ERROR)
-        << "Header acknowledgement field must be 0 or 1 in input filename "
-        << input_filename;
-    return false;
-  }
-
-  ++piece_it;
-
-  // Maximum allowed number of blocked streams.
-  uint64_t max_blocked_streams = 0;
-  if (!absl::SimpleAtoi(*piece_it, &max_blocked_streams)) {
-    QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it
-                    << "\" as an integer.";
-    return false;
-  }
-
-  ++piece_it;
-
-  // Maximum Dynamic Table Capacity in bytes
-  uint64_t maximum_dynamic_table_capacity = 0;
-  if (!absl::SimpleAtoi(*piece_it, &maximum_dynamic_table_capacity)) {
-    QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it
-                    << "\" as an integer.";
-    return false;
-  }
-  qpack_decoder_ = std::make_unique<QpackDecoder>(
-      maximum_dynamic_table_capacity, max_blocked_streams, this);
-  qpack_decoder_->set_qpack_stream_sender_delegate(
-      &decoder_stream_sender_delegate_);
-
-  // The initial dynamic table capacity is zero according to
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#eviction.
-  // However, for historical reasons, offline interop encoders use
-  // |maximum_dynamic_table_capacity| as initial capacity.
-  qpack_decoder_->OnSetDynamicTableCapacity(maximum_dynamic_table_capacity);
-
-  return true;
-}
-
-bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile(
-    absl::string_view input_filename) {
-  // Store data in |input_data_storage|; use a absl::string_view to
-  // efficiently keep track of remaining portion yet to be decoded.
-  absl::optional<std::string> input_data_storage =
-      quiche::ReadFileContents(input_filename);
-  QUICHE_DCHECK(input_data_storage.has_value());
-  absl::string_view input_data(*input_data_storage);
-
-  while (!input_data.empty()) {
-    // Parse stream_id and length.
-    if (input_data.size() < sizeof(uint64_t) + sizeof(uint32_t)) {
-      QUIC_LOG(ERROR) << "Unexpected end of input file.";
-      return false;
-    }
-
-    uint64_t stream_id = quiche::QuicheEndian::NetToHost64(
-        *reinterpret_cast<const uint64_t*>(input_data.data()));
-    input_data = input_data.substr(sizeof(uint64_t));
-
-    uint32_t length = quiche::QuicheEndian::NetToHost32(
-        *reinterpret_cast<const uint32_t*>(input_data.data()));
-    input_data = input_data.substr(sizeof(uint32_t));
-
-    if (input_data.size() < length) {
-      QUIC_LOG(ERROR) << "Unexpected end of input file.";
-      return false;
-    }
-
-    // Parse data.
-    absl::string_view data = input_data.substr(0, length);
-    input_data = input_data.substr(length);
-
-    // Process data.
-    if (stream_id == 0) {
-      qpack_decoder_->encoder_stream_receiver()->Decode(data);
-
-      if (encoder_stream_error_detected_) {
-        QUIC_LOG(ERROR) << "Error detected on encoder stream.";
-        return false;
-      }
-    } else {
-      auto headers_handler = std::make_unique<test::TestHeadersHandler>();
-      auto progressive_decoder = qpack_decoder_->CreateProgressiveDecoder(
-          stream_id, headers_handler.get());
-
-      progressive_decoder->Decode(data);
-      progressive_decoder->EndHeaderBlock();
-
-      if (headers_handler->decoding_error_detected()) {
-        QUIC_LOG(ERROR) << "Sync decoding error on stream " << stream_id << ": "
-                        << headers_handler->error_message();
-        return false;
-      }
-
-      decoders_.push_back({std::move(headers_handler),
-                           std::move(progressive_decoder), stream_id});
-    }
-
-    // Move decoded header lists from TestHeadersHandlers and append them to
-    // |decoded_header_lists_| while preserving the order in |decoders_|.
-    while (!decoders_.empty() &&
-           decoders_.front().headers_handler->decoding_completed()) {
-      Decoder* decoder = &decoders_.front();
-
-      if (decoder->headers_handler->decoding_error_detected()) {
-        QUIC_LOG(ERROR) << "Async decoding error on stream "
-                        << decoder->stream_id << ": "
-                        << decoder->headers_handler->error_message();
-        return false;
-      }
-
-      if (!decoder->headers_handler->decoding_completed()) {
-        QUIC_LOG(ERROR) << "Decoding incomplete after reading entire"
-                           " file, on stream "
-                        << decoder->stream_id;
-        return false;
-      }
-
-      decoded_header_lists_.push_back(
-          decoder->headers_handler->ReleaseHeaderList());
-      decoders_.pop_front();
-    }
-  }
-
-  if (!decoders_.empty()) {
-    QUICHE_DCHECK(!decoders_.front().headers_handler->decoding_completed());
-
-    QUIC_LOG(ERROR) << "Blocked decoding uncomplete after reading entire"
-                       " file, on stream "
-                    << decoders_.front().stream_id;
-    return false;
-  }
-
-  return true;
-}
-
-bool QpackOfflineDecoder::VerifyDecodedHeaderLists(
-    absl::string_view expected_headers_filename) {
-  // Store data in |expected_headers_data_storage|; use a
-  // absl::string_view to efficiently keep track of remaining portion
-  // yet to be decoded.
-  absl::optional<std::string> expected_headers_data_storage =
-      quiche::ReadFileContents(expected_headers_filename);
-  QUICHE_DCHECK(expected_headers_data_storage.has_value());
-  absl::string_view expected_headers_data(*expected_headers_data_storage);
-
-  while (!decoded_header_lists_.empty()) {
-    spdy::Http2HeaderBlock decoded_header_list =
-        std::move(decoded_header_lists_.front());
-    decoded_header_lists_.pop_front();
-
-    spdy::Http2HeaderBlock expected_header_list;
-    if (!ReadNextExpectedHeaderList(&expected_headers_data,
-                                    &expected_header_list)) {
-      QUIC_LOG(ERROR)
-          << "Error parsing expected header list to match next decoded "
-             "header list.";
-      return false;
-    }
-
-    if (!CompareHeaderBlocks(std::move(decoded_header_list),
-                             std::move(expected_header_list))) {
-      QUIC_LOG(ERROR) << "Decoded header does not match expected header.";
-      return false;
-    }
-  }
-
-  if (!expected_headers_data.empty()) {
-    QUIC_LOG(ERROR)
-        << "Not enough encoded header lists to match expected ones.";
-    return false;
-  }
-
-  return true;
-}
-
-bool QpackOfflineDecoder::ReadNextExpectedHeaderList(
-    absl::string_view* expected_headers_data,
-    spdy::Http2HeaderBlock* expected_header_list) {
-  while (true) {
-    absl::string_view::size_type endline = expected_headers_data->find('\n');
-
-    // Even last header list must be followed by an empty line.
-    if (endline == absl::string_view::npos) {
-      QUIC_LOG(ERROR) << "Unexpected end of expected header list file.";
-      return false;
-    }
-
-    if (endline == 0) {
-      // Empty line indicates end of header list.
-      *expected_headers_data = expected_headers_data->substr(1);
-      return true;
-    }
-
-    absl::string_view header_field = expected_headers_data->substr(0, endline);
-    std::vector<absl::string_view> pieces = absl::StrSplit(header_field, '\t');
-
-    if (pieces.size() != 2) {
-      QUIC_LOG(ERROR) << "Header key and value must be separated by TAB.";
-      return false;
-    }
-
-    expected_header_list->AppendValueOrAddHeader(pieces[0], pieces[1]);
-
-    *expected_headers_data = expected_headers_data->substr(endline + 1);
-  }
-}
-
-bool QpackOfflineDecoder::CompareHeaderBlocks(
-    spdy::Http2HeaderBlock decoded_header_list,
-    spdy::Http2HeaderBlock expected_header_list) {
-  if (decoded_header_list == expected_header_list) {
-    return true;
-  }
-
-  // The h2o decoder reshuffles the "content-length" header and pseudo-headers,
-  // see
-  // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md.
-  // Remove such headers one by one if they match.
-  const char* kContentLength = "content-length";
-  const char* kPseudoHeaderPrefix = ":";
-  for (spdy::Http2HeaderBlock::iterator decoded_it =
-           decoded_header_list.begin();
-       decoded_it != decoded_header_list.end();) {
-    const absl::string_view key = decoded_it->first;
-    if (key != kContentLength && !absl::StartsWith(key, kPseudoHeaderPrefix)) {
-      ++decoded_it;
-      continue;
-    }
-    spdy::Http2HeaderBlock::iterator expected_it =
-        expected_header_list.find(key);
-    if (expected_it == expected_header_list.end() ||
-        decoded_it->second != expected_it->second) {
-      ++decoded_it;
-      continue;
-    }
-    // SpdyHeaderBlock does not support erasing by iterator, only by key.
-    ++decoded_it;
-    expected_header_list.erase(key);
-    // This will invalidate |key|.
-    decoded_header_list.erase(key);
-  }
-
-  return decoded_header_list == expected_header_list;
-}
-
-}  // namespace quic
diff --git a/quic/test_tools/qpack/qpack_offline_decoder.h b/quic/test_tools/qpack/qpack_offline_decoder.h
deleted file mode 100644
index 11dec69..0000000
--- a/quic/test_tools/qpack/qpack_offline_decoder.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
-
-#include <list>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_decoder.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// A decoder to read encoded data from a file, decode it, and compare to
-// a list of expected header lists read from another file.  File format is
-// described at
-// https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop.
-class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate {
- public:
-  QpackOfflineDecoder();
-  ~QpackOfflineDecoder() override = default;
-
-  // Read encoded header blocks and encoder stream data from |input_filename|
-  // and decode them, read expected header lists from
-  // |expected_headers_filename|, and compare decoded header lists to expected
-  // ones.  Returns true if there is an equal number of them and the
-  // corresponding ones match, false otherwise.
-  bool DecodeAndVerifyOfflineData(absl::string_view input_filename,
-                                  absl::string_view expected_headers_filename);
-
-  // QpackDecoder::EncoderStreamErrorDelegate implementation:
-  void OnEncoderStreamError(QuicErrorCode error_code,
-                            absl::string_view error_message) override;
-
- private:
-  // Data structure to hold TestHeadersHandler and QpackProgressiveDecoder until
-  // decoding of a header header block (and all preceding header blocks) is
-  // complete.
-  struct Decoder {
-    std::unique_ptr<test::TestHeadersHandler> headers_handler;
-    std::unique_ptr<QpackProgressiveDecoder> progressive_decoder;
-    uint64_t stream_id;
-  };
-
-  // Parse decoder parameters from |input_filename| and set up |qpack_decoder_|
-  // accordingly.
-  bool ParseInputFilename(absl::string_view input_filename);
-
-  // Read encoded header blocks and encoder stream data from |input_filename|,
-  // pass them to |qpack_decoder_| for decoding, and add decoded header lists to
-  // |decoded_header_lists_|.
-  bool DecodeHeaderBlocksFromFile(absl::string_view input_filename);
-
-  // Read expected header lists from |expected_headers_filename| and verify
-  // decoded header lists in |decoded_header_lists_| against them.
-  bool VerifyDecodedHeaderLists(absl::string_view expected_headers_filename);
-
-  // Parse next header list from |*expected_headers_data| into
-  // |*expected_header_list|, removing consumed data from the beginning of
-  // |*expected_headers_data|.  Returns true on success, false if parsing fails.
-  bool ReadNextExpectedHeaderList(absl::string_view* expected_headers_data,
-                                  spdy::Http2HeaderBlock* expected_header_list);
-
-  // Compare two header lists.  Allow for different orders of certain headers as
-  // described at
-  // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md.
-  bool CompareHeaderBlocks(spdy::Http2HeaderBlock decoded_header_list,
-                           spdy::Http2HeaderBlock expected_header_list);
-
-  bool encoder_stream_error_detected_;
-  test::NoopQpackStreamSenderDelegate decoder_stream_sender_delegate_;
-  std::unique_ptr<QpackDecoder> qpack_decoder_;
-
-  // Objects necessary for decoding, one list element for each header block.
-  std::list<Decoder> decoders_;
-
-  // Decoded header lists.
-  std::list<spdy::Http2HeaderBlock> decoded_header_lists_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
diff --git a/quic/test_tools/qpack/qpack_test_utils.cc b/quic/test_tools/qpack/qpack_test_utils.cc
deleted file mode 100644
index a453504..0000000
--- a/quic/test_tools/qpack/qpack_test_utils.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/qpack/qpack_test_utils.h"
-
-#include <limits>
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-namespace test {
-
-FragmentSizeGenerator FragmentModeToFragmentSizeGenerator(
-    FragmentMode fragment_mode) {
-  switch (fragment_mode) {
-    case FragmentMode::kSingleChunk:
-      return []() { return std::numeric_limits<size_t>::max(); };
-    case FragmentMode::kOctetByOctet:
-      return []() { return 1; };
-  }
-  QUIC_BUG(quic_bug_10259_1)
-      << "Unknown FragmentMode " << static_cast<int>(fragment_mode);
-  return []() { return 0; };
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/qpack/qpack_test_utils.h b/quic/test_tools/qpack/qpack_test_utils.h
deleted file mode 100644
index 2230fbe..0000000
--- a/quic/test_tools/qpack/qpack_test_utils.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
-
-#include <cstddef>
-#include <functional>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/qpack/qpack_stream_sender_delegate.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-// Called repeatedly to determine the size of each fragment when encoding or
-// decoding.  Must return a positive value.
-using FragmentSizeGenerator = std::function<size_t()>;
-
-enum class FragmentMode {
-  kSingleChunk,
-  kOctetByOctet,
-};
-
-FragmentSizeGenerator FragmentModeToFragmentSizeGenerator(
-    FragmentMode fragment_mode);
-
-// Mock QpackUnidirectionalStreamSenderDelegate implementation.
-class MockQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
- public:
-  ~MockQpackStreamSenderDelegate() override = default;
-
-  MOCK_METHOD(void, WriteStreamData, (absl::string_view data), (override));
-  MOCK_METHOD(uint64_t, NumBytesBuffered, (), (const, override));
-};
-
-class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
- public:
-  ~NoopQpackStreamSenderDelegate() override = default;
-
-  void WriteStreamData(absl::string_view /*data*/) override {}
-
-  uint64_t NumBytesBuffered() const override { return 0; }
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
diff --git a/quic/test_tools/quic_buffered_packet_store_peer.cc b/quic/test_tools/quic_buffered_packet_store_peer.cc
deleted file mode 100644
index 9b3c040..0000000
--- a/quic/test_tools/quic_buffered_packet_store_peer.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_buffered_packet_store_peer.h"
-
-#include "quic/core/quic_buffered_packet_store.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicAlarm* QuicBufferedPacketStorePeer::expiration_alarm(
-    QuicBufferedPacketStore* store) {
-  return store->expiration_alarm_.get();
-}
-
-// static
-void QuicBufferedPacketStorePeer::set_clock(QuicBufferedPacketStore* store,
-                                            const QuicClock* clock) {
-  store->clock_ = clock;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_buffered_packet_store_peer.h b/quic/test_tools/quic_buffered_packet_store_peer.h
deleted file mode 100644
index fddac0a..0000000
--- a/quic/test_tools/quic_buffered_packet_store_peer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
-
-#include <memory>
-
-#include "quic/core/quic_alarm.h"
-#include "quic/core/quic_clock.h"
-
-namespace quic {
-
-class QuicBufferedPacketStore;
-
-namespace test {
-
-class QuicBufferedPacketStorePeer {
- public:
-  QuicBufferedPacketStorePeer() = delete;
-
-  static QuicAlarm* expiration_alarm(QuicBufferedPacketStore* store);
-
-  static void set_clock(QuicBufferedPacketStore* store, const QuicClock* clock);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
diff --git a/quic/test_tools/quic_client_peer.cc b/quic/test_tools/quic_client_peer.cc
deleted file mode 100644
index c80a0b5..0000000
--- a/quic/test_tools/quic_client_peer.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_client_peer.h"
-
-#include "quic/tools/quic_client.h"
-
-namespace quic {
-namespace test {
-
-// static
-bool QuicClientPeer::CreateUDPSocketAndBind(QuicClient* client) {
-  return client->network_helper()->CreateUDPSocketAndBind(
-      client->server_address(), client->bind_to_address(),
-      client->local_port());
-}
-
-// static
-void QuicClientPeer::CleanUpUDPSocket(QuicClient* client, int fd) {
-  client->epoll_network_helper()->CleanUpUDPSocket(fd);
-}
-
-// static
-void QuicClientPeer::SetClientPort(QuicClient* client, int port) {
-  client->epoll_network_helper()->SetClientPort(port);
-}
-
-// static
-void QuicClientPeer::SetWriter(QuicClient* client, QuicPacketWriter* writer) {
-  client->set_writer(writer);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_client_promised_info_peer.cc b/quic/test_tools/quic_client_promised_info_peer.cc
deleted file mode 100644
index cf14d0f..0000000
--- a/quic/test_tools/quic_client_promised_info_peer.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_client_promised_info_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicAlarm* QuicClientPromisedInfoPeer::GetAlarm(
-    QuicClientPromisedInfo* promised_stream) {
-  return promised_stream->cleanup_alarm_.get();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_client_promised_info_peer.h b/quic/test_tools/quic_client_promised_info_peer.h
deleted file mode 100644
index 15ae6bb..0000000
--- a/quic/test_tools/quic_client_promised_info_peer.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
-
-#include "quic/core/http/quic_client_promised_info.h"
-
-namespace quic {
-namespace test {
-
-class QuicClientPromisedInfoPeer {
- public:
-  QuicClientPromisedInfoPeer() = delete;
-
-  static QuicAlarm* GetAlarm(QuicClientPromisedInfo* promised_stream);
-};
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
diff --git a/quic/test_tools/quic_client_session_cache_peer.h b/quic/test_tools/quic_client_session_cache_peer.h
deleted file mode 100644
index 227a48d..0000000
--- a/quic/test_tools/quic_client_session_cache_peer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
-
-#include "quic/core/crypto/quic_client_session_cache.h"
-
-namespace quic {
-namespace test {
-
-class QuicClientSessionCachePeer {
- public:
-  static std::string GetToken(QuicClientSessionCache* cache,
-                              const QuicServerId& server_id) {
-    auto iter = cache->cache_.Lookup(server_id);
-    if (iter == cache->cache_.end()) {
-      return {};
-    }
-    return iter->second->token;
-  }
-
-  static bool HasEntry(QuicClientSessionCache* cache,
-                       const QuicServerId& server_id) {
-    return cache->cache_.Lookup(server_id) != cache->cache_.end();
-  }
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
diff --git a/quic/test_tools/quic_coalesced_packet_peer.cc b/quic/test_tools/quic_coalesced_packet_peer.cc
deleted file mode 100644
index efd1900..0000000
--- a/quic/test_tools/quic_coalesced_packet_peer.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_coalesced_packet_peer.h"
-
-namespace quic {
-namespace test {
-
-//  static
-void QuicCoalescedPacketPeer::SetMaxPacketLength(
-    QuicCoalescedPacket& coalesced_packet, QuicPacketLength length) {
-  coalesced_packet.max_packet_length_ = length;
-}
-
-//  static
-std::string* QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
-    QuicCoalescedPacket& coalesced_packet, EncryptionLevel encryption_level) {
-  return &coalesced_packet.encrypted_buffers_[encryption_level];
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_coalesced_packet_peer.h b/quic/test_tools/quic_coalesced_packet_peer.h
deleted file mode 100644
index 908cf09..0000000
--- a/quic/test_tools/quic_coalesced_packet_peer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_COALESCED_PACKET_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_COALESCED_PACKET_PEER_H_
-
-#include "quic/core/quic_coalesced_packet.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-namespace test {
-
-class QuicCoalescedPacketPeer {
- public:
-  static void SetMaxPacketLength(QuicCoalescedPacket& coalesced_packet,
-                                 QuicPacketLength length);
-
-  static std::string* GetMutableEncryptedBuffer(
-      QuicCoalescedPacket& coalesced_packet, EncryptionLevel encryption_level);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_COALESCED_PACKET_PEER_H_
diff --git a/quic/test_tools/quic_config_peer.cc b/quic/test_tools/quic_config_peer.cc
deleted file mode 100644
index 243216b..0000000
--- a/quic/test_tools/quic_config_peer.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_config_peer.h"
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
-    QuicConfig* config,
-    uint32_t window_bytes) {
-  config->initial_stream_flow_control_window_bytes_.SetReceivedValue(
-      window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-    QuicConfig* config,
-    uint32_t window_bytes) {
-  config->initial_max_stream_data_bytes_incoming_bidirectional_
-      .SetReceivedValue(window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-    QuicConfig* config,
-    uint32_t window_bytes) {
-  config->initial_max_stream_data_bytes_outgoing_bidirectional_
-      .SetReceivedValue(window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-    QuicConfig* config,
-    uint32_t window_bytes) {
-  config->initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
-      window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-    QuicConfig* config,
-    uint32_t window_bytes) {
-  config->initial_session_flow_control_window_bytes_.SetReceivedValue(
-      window_bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedConnectionOptions(
-    QuicConfig* config,
-    const QuicTagVector& options) {
-  config->connection_options_.SetReceivedValues(options);
-}
-
-// static
-void QuicConfigPeer::SetReceivedBytesForConnectionId(QuicConfig* config,
-                                                     uint32_t bytes) {
-  QUICHE_DCHECK(bytes == 0 || bytes == 8);
-  config->bytes_for_connection_id_.SetReceivedValue(bytes);
-}
-
-// static
-void QuicConfigPeer::SetReceivedDisableConnectionMigration(QuicConfig* config) {
-  config->connection_migration_disabled_.SetReceivedValue(1);
-}
-
-// static
-void QuicConfigPeer::SetReceivedMaxBidirectionalStreams(QuicConfig* config,
-                                                        uint32_t max_streams) {
-  config->max_bidirectional_streams_.SetReceivedValue(max_streams);
-}
-// static
-void QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(QuicConfig* config,
-                                                         uint32_t max_streams) {
-  config->max_unidirectional_streams_.SetReceivedValue(max_streams);
-}
-
-// static
-void QuicConfigPeer::SetConnectionOptionsToSend(QuicConfig* config,
-                                                const QuicTagVector& options) {
-  config->SetConnectionOptionsToSend(options);
-}
-
-// static
-void QuicConfigPeer::SetReceivedStatelessResetToken(
-    QuicConfig* config,
-    const StatelessResetToken& token) {
-  config->stateless_reset_token_.SetReceivedValue(token);
-}
-
-// static
-void QuicConfigPeer::SetReceivedMaxPacketSize(QuicConfig* config,
-                                              uint32_t max_udp_payload_size) {
-  config->max_udp_payload_size_.SetReceivedValue(max_udp_payload_size);
-}
-
-// static
-void QuicConfigPeer::SetReceivedMinAckDelayMs(QuicConfig* config,
-                                              uint32_t min_ack_delay_ms) {
-  config->min_ack_delay_ms_.SetReceivedValue(min_ack_delay_ms);
-}
-
-// static
-void QuicConfigPeer::SetNegotiated(QuicConfig* config, bool negotiated) {
-  config->negotiated_ = negotiated;
-}
-
-// static
-void QuicConfigPeer::SetReceivedOriginalConnectionId(
-    QuicConfig* config,
-    const QuicConnectionId& original_destination_connection_id) {
-  config->received_original_destination_connection_id_ =
-      original_destination_connection_id;
-}
-
-// static
-void QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-    QuicConfig* config,
-    const QuicConnectionId& initial_source_connection_id) {
-  config->received_initial_source_connection_id_ = initial_source_connection_id;
-}
-
-// static
-void QuicConfigPeer::SetReceivedRetrySourceConnectionId(
-    QuicConfig* config,
-    const QuicConnectionId& retry_source_connection_id) {
-  config->received_retry_source_connection_id_ = retry_source_connection_id;
-}
-
-// static
-void QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
-    QuicConfig* config,
-    uint64_t max_datagram_frame_size) {
-  config->max_datagram_frame_size_.SetReceivedValue(max_datagram_frame_size);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_config_peer.h b/quic/test_tools/quic_config_peer.h
deleted file mode 100644
index 6ffc5ae..0000000
--- a/quic/test_tools/quic_config_peer.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicConfig;
-
-namespace test {
-
-class QuicConfigPeer {
- public:
-  QuicConfigPeer() = delete;
-
-  static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config,
-                                                        uint32_t window_bytes);
-
-  static void SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-      QuicConfig* config,
-      uint32_t window_bytes);
-
-  static void SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-      QuicConfig* config,
-      uint32_t window_bytes);
-
-  static void SetReceivedInitialMaxStreamDataBytesUnidirectional(
-      QuicConfig* config,
-      uint32_t window_bytes);
-
-  static void SetReceivedInitialSessionFlowControlWindow(QuicConfig* config,
-                                                         uint32_t window_bytes);
-
-  static void SetReceivedConnectionOptions(QuicConfig* config,
-                                           const QuicTagVector& options);
-
-  static void SetReceivedBytesForConnectionId(QuicConfig* config,
-                                              uint32_t bytes);
-
-  static void SetReceivedDisableConnectionMigration(QuicConfig* config);
-
-  static void SetReceivedMaxBidirectionalStreams(QuicConfig* config,
-                                                 uint32_t max_streams);
-  static void SetReceivedMaxUnidirectionalStreams(QuicConfig* config,
-                                                  uint32_t max_streams);
-
-  static void SetConnectionOptionsToSend(QuicConfig* config,
-                                         const QuicTagVector& options);
-
-  static void SetReceivedStatelessResetToken(QuicConfig* config,
-                                             const StatelessResetToken& token);
-
-  static void SetReceivedMaxPacketSize(QuicConfig* config,
-                                       uint32_t max_udp_payload_size);
-
-  static void SetReceivedMinAckDelayMs(QuicConfig* config,
-                                       uint32_t min_ack_delay_ms);
-
-  static void SetNegotiated(QuicConfig* config, bool negotiated);
-
-  static void SetReceivedOriginalConnectionId(
-      QuicConfig* config,
-      const QuicConnectionId& original_destination_connection_id);
-
-  static void SetReceivedInitialSourceConnectionId(
-      QuicConfig* config,
-      const QuicConnectionId& initial_source_connection_id);
-
-  static void SetReceivedRetrySourceConnectionId(
-      QuicConfig* config,
-      const QuicConnectionId& retry_source_connection_id);
-
-  static void SetReceivedMaxDatagramFrameSize(QuicConfig* config,
-                                              uint64_t max_datagram_frame_size);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
diff --git a/quic/test_tools/quic_connection_id_manager_peer.h b/quic/test_tools/quic_connection_id_manager_peer.h
deleted file mode 100644
index ab749ed..0000000
--- a/quic/test_tools/quic_connection_id_manager_peer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
-
-#include "quic/core/quic_connection_id_manager.h"
-
-namespace quic {
-namespace test {
-
-class QuicConnectionIdManagerPeer {
- public:
-  static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
-      QuicPeerIssuedConnectionIdManager* manager) {
-    return manager->retire_connection_id_alarm_.get();
-  }
-
-  static QuicAlarm* GetRetireSelfIssuedConnectionIdAlarm(
-      QuicSelfIssuedConnectionIdManager* manager) {
-    return manager->retire_connection_id_alarm_.get();
-  }
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc
deleted file mode 100644
index 5e60a84..0000000
--- a/quic/test_tools/quic_connection_peer.cc
+++ /dev/null
@@ -1,550 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_connection_peer.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_received_packet_manager.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/test_tools/quic_connection_id_manager_peer.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicConnectionPeer::SetSendAlgorithm(
-    QuicConnection* connection,
-    SendAlgorithmInterface* send_algorithm) {
-  GetSentPacketManager(connection)->SetSendAlgorithm(send_algorithm);
-}
-
-// static
-void QuicConnectionPeer::SetLossAlgorithm(
-    QuicConnection* connection,
-    LossDetectionInterface* loss_algorithm) {
-  GetSentPacketManager(connection)->loss_algorithm_ = loss_algorithm;
-}
-
-// static
-void QuicConnectionPeer::PopulateStopWaitingFrame(
-    QuicConnection* connection,
-    QuicStopWaitingFrame* stop_waiting) {
-  connection->PopulateStopWaitingFrame(stop_waiting);
-}
-
-// static
-QuicPacketCreator* QuicConnectionPeer::GetPacketCreator(
-    QuicConnection* connection) {
-  return &connection->packet_creator_;
-}
-
-// static
-QuicSentPacketManager* QuicConnectionPeer::GetSentPacketManager(
-    QuicConnection* connection) {
-  return &connection->sent_packet_manager_;
-}
-
-// static
-QuicTime::Delta QuicConnectionPeer::GetNetworkTimeout(
-    QuicConnection* connection) {
-  return connection->idle_network_detector_.idle_network_timeout_;
-}
-
-// static
-QuicTime::Delta QuicConnectionPeer::GetHandshakeTimeout(
-    QuicConnection* connection) {
-  return connection->idle_network_detector_.handshake_timeout_;
-}
-
-// static
-void QuicConnectionPeer::SetPerspective(QuicConnection* connection,
-                                        Perspective perspective) {
-  connection->perspective_ = perspective;
-  QuicFramerPeer::SetPerspective(&connection->framer_, perspective);
-}
-
-// static
-void QuicConnectionPeer::SetSelfAddress(QuicConnection* connection,
-                                        const QuicSocketAddress& self_address) {
-  connection->default_path_.self_address = self_address;
-}
-
-// static
-void QuicConnectionPeer::SetPeerAddress(QuicConnection* connection,
-                                        const QuicSocketAddress& peer_address) {
-  connection->UpdatePeerAddress(peer_address);
-}
-
-// static
-void QuicConnectionPeer::SetDirectPeerAddress(
-    QuicConnection* connection,
-    const QuicSocketAddress& direct_peer_address) {
-  connection->direct_peer_address_ = direct_peer_address;
-}
-
-// static
-void QuicConnectionPeer::SetEffectivePeerAddress(
-    QuicConnection* connection,
-    const QuicSocketAddress& effective_peer_address) {
-  connection->default_path_.peer_address = effective_peer_address;
-}
-
-// static
-void QuicConnectionPeer::SwapCrypters(QuicConnection* connection,
-                                      QuicFramer* framer) {
-  QuicFramerPeer::SwapCrypters(framer, &connection->framer_);
-}
-
-// static
-void QuicConnectionPeer::SetCurrentPacket(QuicConnection* connection,
-                                          absl::string_view current_packet) {
-  connection->current_packet_data_ = current_packet.data();
-  connection->last_size_ = current_packet.size();
-}
-
-// static
-QuicConnectionHelperInterface* QuicConnectionPeer::GetHelper(
-    QuicConnection* connection) {
-  return connection->helper_;
-}
-
-// static
-QuicAlarmFactory* QuicConnectionPeer::GetAlarmFactory(
-    QuicConnection* connection) {
-  return connection->alarm_factory_;
-}
-
-// static
-QuicFramer* QuicConnectionPeer::GetFramer(QuicConnection* connection) {
-  return &connection->framer_;
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
-  return connection->ack_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
-  return connection->ping_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetRetransmissionAlarm(
-    QuicConnection* connection) {
-  return connection->retransmission_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetSendAlarm(QuicConnection* connection) {
-  return connection->send_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetMtuDiscoveryAlarm(
-    QuicConnection* connection) {
-  return connection->mtu_discovery_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(
-    QuicConnection* connection) {
-  return connection->process_undecryptable_packets_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(
-    QuicConnection* connection) {
-  return connection->discard_previous_one_rtt_keys_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(
-    QuicConnection* connection) {
-  return connection->discard_zero_rtt_decryption_keys_alarm_.get();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(
-    QuicConnection* connection) {
-  if (connection->peer_issued_cid_manager_ == nullptr) {
-    return nullptr;
-  }
-  return QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
-      connection->peer_issued_cid_manager_.get());
-}
-// static
-QuicAlarm* QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(
-    QuicConnection* connection) {
-  if (connection->self_issued_cid_manager_ == nullptr) {
-    return nullptr;
-  }
-  return QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
-      connection->self_issued_cid_manager_.get());
-}
-
-// static
-QuicPacketWriter* QuicConnectionPeer::GetWriter(QuicConnection* connection) {
-  return connection->writer_;
-}
-
-// static
-void QuicConnectionPeer::SetWriter(QuicConnection* connection,
-                                   QuicPacketWriter* writer,
-                                   bool owns_writer) {
-  if (connection->owns_writer_) {
-    delete connection->writer_;
-  }
-  connection->writer_ = writer;
-  connection->owns_writer_ = owns_writer;
-}
-
-// static
-void QuicConnectionPeer::TearDownLocalConnectionState(
-    QuicConnection* connection) {
-  connection->connected_ = false;
-}
-
-// static
-QuicEncryptedPacket* QuicConnectionPeer::GetConnectionClosePacket(
-    QuicConnection* connection) {
-  if (connection->termination_packets_ == nullptr ||
-      connection->termination_packets_->empty()) {
-    return nullptr;
-  }
-  return (*connection->termination_packets_)[0].get();
-}
-
-// static
-QuicPacketHeader* QuicConnectionPeer::GetLastHeader(
-    QuicConnection* connection) {
-  return &connection->last_header_;
-}
-
-// static
-QuicConnectionStats* QuicConnectionPeer::GetStats(QuicConnection* connection) {
-  return &connection->stats_;
-}
-
-// static
-QuicPacketCount QuicConnectionPeer::GetPacketsBetweenMtuProbes(
-    QuicConnection* connection) {
-  return connection->mtu_discoverer_.packets_between_probes();
-}
-
-// static
-void QuicConnectionPeer::ReInitializeMtuDiscoverer(
-    QuicConnection* connection,
-    QuicPacketCount packets_between_probes_base,
-    QuicPacketNumber next_probe_at) {
-  connection->mtu_discoverer_ =
-      QuicConnectionMtuDiscoverer(packets_between_probes_base, next_probe_at);
-}
-
-// static
-void QuicConnectionPeer::SetAckDecimationDelay(QuicConnection* connection,
-                                               float ack_decimation_delay) {
-  for (auto& received_packet_manager :
-       connection->uber_received_packet_manager_.received_packet_managers_) {
-    received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
-  }
-}
-
-// static
-bool QuicConnectionPeer::HasRetransmittableFrames(QuicConnection* connection,
-                                                  uint64_t packet_number) {
-  return QuicSentPacketManagerPeer::HasRetransmittableFrames(
-      GetSentPacketManager(connection), packet_number);
-}
-
-// static
-bool QuicConnectionPeer::GetNoStopWaitingFrames(QuicConnection* connection) {
-  return connection->no_stop_waiting_frames_;
-}
-
-// static
-void QuicConnectionPeer::SetNoStopWaitingFrames(QuicConnection* connection,
-                                                bool no_stop_waiting_frames) {
-  connection->no_stop_waiting_frames_ = no_stop_waiting_frames;
-}
-
-// static
-void QuicConnectionPeer::SetMaxTrackedPackets(
-    QuicConnection* connection,
-    QuicPacketCount max_tracked_packets) {
-  connection->max_tracked_packets_ = max_tracked_packets;
-}
-
-// static
-void QuicConnectionPeer::SetNegotiatedVersion(QuicConnection* connection) {
-  connection->version_negotiated_ = true;
-  if (connection->perspective() == Perspective::IS_SERVER &&
-      !QuicFramerPeer::infer_packet_header_type_from_version(
-          &connection->framer_)) {
-    connection->framer_.InferPacketHeaderTypeFromVersion();
-  }
-}
-
-// static
-void QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
-    QuicConnection* connection,
-    size_t new_value) {
-  connection->max_consecutive_num_packets_with_no_retransmittable_frames_ =
-      new_value;
-}
-
-// static
-bool QuicConnectionPeer::SupportsReleaseTime(QuicConnection* connection) {
-  return connection->supports_release_time_;
-}
-
-// static
-QuicConnection::PacketContent QuicConnectionPeer::GetCurrentPacketContent(
-    QuicConnection* connection) {
-  return connection->current_packet_content_;
-}
-
-// static
-void QuicConnectionPeer::SetLastHeaderFormat(QuicConnection* connection,
-                                             PacketHeaderFormat format) {
-  connection->last_header_.form = format;
-}
-
-// static
-void QuicConnectionPeer::AddBytesReceived(QuicConnection* connection,
-                                          size_t length) {
-  if (connection->EnforceAntiAmplificationLimit()) {
-    connection->default_path_.bytes_received_before_address_validation +=
-        length;
-  }
-}
-
-// static
-void QuicConnectionPeer::SetAddressValidated(QuicConnection* connection) {
-  connection->default_path_.validated = true;
-}
-
-// static
-void QuicConnectionPeer::SendConnectionClosePacket(
-    QuicConnection* connection,
-    QuicIetfTransportErrorCodes ietf_error,
-    QuicErrorCode error,
-    const std::string& details) {
-  connection->SendConnectionClosePacket(error, ietf_error, details);
-}
-
-// static
-size_t QuicConnectionPeer::GetNumEncryptionLevels(QuicConnection* connection) {
-  size_t count = 0;
-  for (EncryptionLevel level :
-       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
-        ENCRYPTION_FORWARD_SECURE}) {
-    if (connection->framer_.HasEncrypterOfEncryptionLevel(level)) {
-      ++count;
-    }
-  }
-  return count;
-}
-
-// static
-QuicNetworkBlackholeDetector& QuicConnectionPeer::GetBlackholeDetector(
-    QuicConnection* connection) {
-  return connection->blackhole_detector_;
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetBlackholeDetectorAlarm(
-    QuicConnection* connection) {
-  return connection->blackhole_detector_.alarm_.get();
-}
-
-// static
-QuicTime QuicConnectionPeer::GetPathDegradingDeadline(
-    QuicConnection* connection) {
-  return connection->blackhole_detector_.path_degrading_deadline_;
-}
-
-// static
-QuicTime QuicConnectionPeer::GetBlackholeDetectionDeadline(
-    QuicConnection* connection) {
-  return connection->blackhole_detector_.blackhole_deadline_;
-}
-
-// static
-QuicTime QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
-    QuicConnection* connection) {
-  return connection->blackhole_detector_.path_mtu_reduction_deadline_;
-}
-
-// static
-QuicTime QuicConnectionPeer::GetIdleNetworkDeadline(
-    QuicConnection* connection) {
-  return connection->idle_network_detector_.GetIdleNetworkDeadline();
-}
-
-// static
-QuicAlarm* QuicConnectionPeer::GetIdleNetworkDetectorAlarm(
-    QuicConnection* connection) {
-  return connection->idle_network_detector_.alarm_.get();
-}
-
-// static
-QuicIdleNetworkDetector& QuicConnectionPeer::GetIdleNetworkDetector(
-    QuicConnection* connection) {
-  return connection->idle_network_detector_;
-}
-
-// static
-void QuicConnectionPeer::SetServerConnectionId(
-    QuicConnection* connection,
-    const QuicConnectionId& server_connection_id) {
-  connection->default_path_.server_connection_id = server_connection_id;
-  connection->InstallInitialCrypters(server_connection_id);
-}
-
-// static
-size_t QuicConnectionPeer::NumUndecryptablePackets(QuicConnection* connection) {
-  return connection->undecryptable_packets_.size();
-}
-
-void QuicConnectionPeer::SetConnectionClose(QuicConnection* connection) {
-  connection->connected_ = false;
-}
-
-// static
-void QuicConnectionPeer::SendPing(QuicConnection* connection) {
-  connection->SendPingAtLevel(connection->encryption_level());
-}
-
-// static
-void QuicConnectionPeer::SetLastPacketDestinationAddress(
-    QuicConnection* connection,
-    const QuicSocketAddress& address) {
-  connection->last_received_packet_info_.destination_address = address;
-}
-
-// static
-QuicPathValidator* QuicConnectionPeer::path_validator(
-    QuicConnection* connection) {
-  return &connection->path_validator_;
-}
-
-//  static
-QuicByteCount QuicConnectionPeer::BytesSentOnAlternativePath(
-    QuicConnection* connection) {
-  return connection->alternative_path_.bytes_sent_before_address_validation;
-}
-
-//  static
-QuicByteCount QuicConnectionPeer::BytesReceivedOnAlternativePath(
-    QuicConnection* connection) {
-  return connection->alternative_path_.bytes_received_before_address_validation;
-}
-
-// static
-QuicConnectionId QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
-    const QuicConnection* connection) {
-  return connection->alternative_path_.client_connection_id;
-}
-
-// static
-QuicConnectionId QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
-    const QuicConnection* connection) {
-  return connection->alternative_path_.server_connection_id;
-}
-
-// static
-bool QuicConnectionPeer::IsAlternativePathValidated(
-    QuicConnection* connection) {
-  return connection->alternative_path_.validated;
-}
-
-// static
-bool QuicConnectionPeer::IsAlternativePath(
-    QuicConnection* connection,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address) {
-  return connection->IsAlternativePath(self_address, peer_address);
-}
-
-// static
-QuicByteCount QuicConnectionPeer::BytesReceivedBeforeAddressValidation(
-    QuicConnection* connection) {
-  return connection->default_path_.bytes_received_before_address_validation;
-}
-
-// static
-void QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(
-    QuicConnection* connection) {
-  connection->peer_issued_cid_manager_ = nullptr;
-}
-
-// static
-QuicConnection::PathState* QuicConnectionPeer::GetDefaultPath(
-    QuicConnection* connection) {
-  return &connection->default_path_;
-}
-
-// static
-QuicConnection::PathState* QuicConnectionPeer::GetAlternativePath(
-    QuicConnection* connection) {
-  return &connection->alternative_path_;
-}
-
-// static
-void QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(
-    QuicConnection* connection) {
-  connection->RetirePeerIssuedConnectionIdsNoLongerOnPath();
-}
-
-// static
-bool QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
-    const QuicConnection* connection) {
-  return connection->peer_issued_cid_manager_->HasUnusedConnectionId();
-}
-
-// static
-bool QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
-    const QuicConnection* connection) {
-  return connection->self_issued_cid_manager_->HasConnectionIdToConsume();
-}
-
-// static
-QuicSelfIssuedConnectionIdManager*
-QuicConnectionPeer::GetSelfIssuedConnectionIdManager(
-    QuicConnection* connection) {
-  return connection->self_issued_cid_manager_.get();
-}
-
-// static
-std::unique_ptr<QuicSelfIssuedConnectionIdManager>
-QuicConnectionPeer::MakeSelfIssuedConnectionIdManager(
-    QuicConnection* connection) {
-  return connection->MakeSelfIssuedConnectionIdManager();
-}
-
-// static
-void QuicConnectionPeer::SetLastDecryptedLevel(QuicConnection* connection,
-                                               EncryptionLevel level) {
-  connection->last_decrypted_packet_level_ = level;
-}
-
-// static
-QuicCoalescedPacket& QuicConnectionPeer::GetCoalescedPacket(
-    QuicConnection* connection) {
-  return connection->coalesced_packet_;
-}
-
-// static
-void QuicConnectionPeer::FlushCoalescedPacket(QuicConnection* connection) {
-  connection->FlushCoalescedPacket();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_connection_peer.h b/quic/test_tools/quic_connection_peer.h
deleted file mode 100644
index ff536c2..0000000
--- a/quic/test_tools/quic_connection_peer.h
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
-
-#include <cstddef>
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_connection_stats.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-struct QuicPacketHeader;
-class QuicAlarm;
-class QuicConnectionHelperInterface;
-class QuicConnectionVisitorInterface;
-class QuicEncryptedPacket;
-class QuicFramer;
-class QuicPacketCreator;
-class QuicPacketWriter;
-class QuicSentPacketManager;
-class SendAlgorithmInterface;
-
-namespace test {
-
-// Peer to make public a number of otherwise private QuicConnection methods.
-class QuicConnectionPeer {
- public:
-  QuicConnectionPeer() = delete;
-
-  static void SetSendAlgorithm(QuicConnection* connection,
-                               SendAlgorithmInterface* send_algorithm);
-
-  static void SetLossAlgorithm(QuicConnection* connection,
-                               LossDetectionInterface* loss_algorithm);
-
-  static void PopulateStopWaitingFrame(QuicConnection* connection,
-                                       QuicStopWaitingFrame* stop_waiting);
-
-  static QuicPacketCreator* GetPacketCreator(QuicConnection* connection);
-
-  static QuicSentPacketManager* GetSentPacketManager(
-      QuicConnection* connection);
-
-  static QuicTime::Delta GetNetworkTimeout(QuicConnection* connection);
-
-  static QuicTime::Delta GetHandshakeTimeout(QuicConnection* connection);
-
-  static void SetPerspective(QuicConnection* connection,
-                             Perspective perspective);
-
-  static void SetSelfAddress(QuicConnection* connection,
-                             const QuicSocketAddress& self_address);
-
-  static void SetPeerAddress(QuicConnection* connection,
-                             const QuicSocketAddress& peer_address);
-
-  static void SetDirectPeerAddress(
-      QuicConnection* connection,
-      const QuicSocketAddress& direct_peer_address);
-
-  static void SetEffectivePeerAddress(
-      QuicConnection* connection,
-      const QuicSocketAddress& effective_peer_address);
-
-  static void SwapCrypters(QuicConnection* connection, QuicFramer* framer);
-
-  static void SetCurrentPacket(QuicConnection* connection,
-                               absl::string_view current_packet);
-
-  static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection);
-
-  static QuicAlarmFactory* GetAlarmFactory(QuicConnection* connection);
-
-  static QuicFramer* GetFramer(QuicConnection* connection);
-
-  static QuicAlarm* GetAckAlarm(QuicConnection* connection);
-  static QuicAlarm* GetPingAlarm(QuicConnection* connection);
-  static QuicAlarm* GetRetransmissionAlarm(QuicConnection* connection);
-  static QuicAlarm* GetSendAlarm(QuicConnection* connection);
-  static QuicAlarm* GetMtuDiscoveryAlarm(QuicConnection* connection);
-  static QuicAlarm* GetProcessUndecryptablePacketsAlarm(
-      QuicConnection* connection);
-  static QuicAlarm* GetDiscardPreviousOneRttKeysAlarm(
-      QuicConnection* connection);
-  static QuicAlarm* GetDiscardZeroRttDecryptionKeysAlarm(
-      QuicConnection* connection);
-  static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
-      QuicConnection* connection);
-  static QuicAlarm* GetRetireSelfIssuedConnectionIdAlarm(
-      QuicConnection* connection);
-
-  static QuicPacketWriter* GetWriter(QuicConnection* connection);
-  // If |owns_writer| is true, takes ownership of |writer|.
-  static void SetWriter(QuicConnection* connection,
-                        QuicPacketWriter* writer,
-                        bool owns_writer);
-  static void TearDownLocalConnectionState(QuicConnection* connection);
-  static QuicEncryptedPacket* GetConnectionClosePacket(
-      QuicConnection* connection);
-
-  static QuicPacketHeader* GetLastHeader(QuicConnection* connection);
-
-  static QuicConnectionStats* GetStats(QuicConnection* connection);
-
-  static QuicPacketCount GetPacketsBetweenMtuProbes(QuicConnection* connection);
-
-  static void ReInitializeMtuDiscoverer(
-      QuicConnection* connection,
-      QuicPacketCount packets_between_probes_base,
-      QuicPacketNumber next_probe_at);
-  static void SetAckDecimationDelay(QuicConnection* connection,
-                                    float ack_decimation_delay);
-  static bool HasRetransmittableFrames(QuicConnection* connection,
-                                       uint64_t packet_number);
-  static bool GetNoStopWaitingFrames(QuicConnection* connection);
-  static void SetNoStopWaitingFrames(QuicConnection* connection,
-                                     bool no_stop_waiting_frames);
-  static void SetMaxTrackedPackets(QuicConnection* connection,
-                                   QuicPacketCount max_tracked_packets);
-  static void SetNegotiatedVersion(QuicConnection* connection);
-  static void SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
-      QuicConnection* connection,
-      size_t new_value);
-  static bool SupportsReleaseTime(QuicConnection* connection);
-  static QuicConnection::PacketContent GetCurrentPacketContent(
-      QuicConnection* connection);
-  static void SetLastHeaderFormat(QuicConnection* connection,
-                                  PacketHeaderFormat format);
-  static void AddBytesReceived(QuicConnection* connection, size_t length);
-  static void SetAddressValidated(QuicConnection* connection);
-
-  static void SendConnectionClosePacket(QuicConnection* connection,
-                                        QuicIetfTransportErrorCodes ietf_error,
-                                        QuicErrorCode error,
-                                        const std::string& details);
-
-  static size_t GetNumEncryptionLevels(QuicConnection* connection);
-
-  static QuicNetworkBlackholeDetector& GetBlackholeDetector(
-      QuicConnection* connection);
-
-  static QuicAlarm* GetBlackholeDetectorAlarm(QuicConnection* connection);
-
-  static QuicTime GetPathDegradingDeadline(QuicConnection* connection);
-
-  static QuicTime GetBlackholeDetectionDeadline(QuicConnection* connection);
-
-  static QuicTime GetPathMtuReductionDetectionDeadline(
-      QuicConnection* connection);
-
-  static QuicAlarm* GetIdleNetworkDetectorAlarm(QuicConnection* connection);
-
-  static QuicTime GetIdleNetworkDeadline(QuicConnection* connection);
-
-  static QuicIdleNetworkDetector& GetIdleNetworkDetector(
-      QuicConnection* connection);
-
-  static void SetServerConnectionId(
-      QuicConnection* connection,
-      const QuicConnectionId& server_connection_id);
-
-  static size_t NumUndecryptablePackets(QuicConnection* connection);
-
-  static void SetConnectionClose(QuicConnection* connection);
-
-  static void SendPing(QuicConnection* connection);
-
-  static void SetLastPacketDestinationAddress(QuicConnection* connection,
-                                              const QuicSocketAddress& address);
-
-  static QuicPathValidator* path_validator(QuicConnection* connection);
-
-  static QuicByteCount BytesSentOnAlternativePath(QuicConnection* connection);
-
-  static QuicByteCount BytesReceivedOnAlternativePath(
-      QuicConnection* connection);
-
-  static QuicConnectionId GetClientConnectionIdOnAlternativePath(
-      const QuicConnection* connection);
-
-  static QuicConnectionId GetServerConnectionIdOnAlternativePath(
-      const QuicConnection* connection);
-
-  static bool IsAlternativePath(QuicConnection* connection,
-                                const QuicSocketAddress& self_address,
-                                const QuicSocketAddress& peer_address);
-
-  static bool IsAlternativePathValidated(QuicConnection* connection);
-
-  static QuicByteCount BytesReceivedBeforeAddressValidation(
-      QuicConnection* connection);
-
-  static void ResetPeerIssuedConnectionIdManager(QuicConnection* connection);
-
-  static QuicConnection::PathState* GetDefaultPath(QuicConnection* connection);
-
-  static QuicConnection::PathState* GetAlternativePath(
-      QuicConnection* connection);
-
-  static void RetirePeerIssuedConnectionIdsNoLongerOnPath(
-      QuicConnection* connection);
-
-  static bool HasUnusedPeerIssuedConnectionId(const QuicConnection* connection);
-
-  static bool HasSelfIssuedConnectionIdToConsume(
-      const QuicConnection* connection);
-
-  static QuicSelfIssuedConnectionIdManager* GetSelfIssuedConnectionIdManager(
-      QuicConnection* connection);
-
-  static std::unique_ptr<QuicSelfIssuedConnectionIdManager>
-  MakeSelfIssuedConnectionIdManager(QuicConnection* connection);
-
-  static void SetLastDecryptedLevel(QuicConnection* connection,
-                                    EncryptionLevel level);
-
-  static QuicCoalescedPacket& GetCoalescedPacket(QuicConnection* connection);
-
-  static void FlushCoalescedPacket(QuicConnection* connection);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
diff --git a/quic/test_tools/quic_crypto_server_config_peer.cc b/quic/test_tools/quic_crypto_server_config_peer.cc
deleted file mode 100644
index 8027d78..0000000
--- a/quic/test_tools/quic_crypto_server_config_peer.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_crypto_server_config_peer.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfigPeer::GetPrimaryConfig() {
-  QuicReaderMutexLock locked(&server_config_->configs_lock_);
-  return quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>(
-      server_config_->primary_config_);
-}
-
-quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-QuicCryptoServerConfigPeer::GetConfig(std::string config_id) {
-  QuicReaderMutexLock locked(&server_config_->configs_lock_);
-  if (config_id == "<primary>") {
-    return quiche::QuicheReferenceCountedPointer<
-        QuicCryptoServerConfig::Config>(server_config_->primary_config_);
-  } else {
-    return server_config_->GetConfigWithScid(config_id);
-  }
-}
-
-ProofSource* QuicCryptoServerConfigPeer::GetProofSource() const {
-  return server_config_->proof_source_.get();
-}
-
-void QuicCryptoServerConfigPeer::ResetProofSource(
-    std::unique_ptr<ProofSource> proof_source) {
-  server_config_->proof_source_ = std::move(proof_source);
-}
-
-std::string QuicCryptoServerConfigPeer::NewSourceAddressToken(
-    std::string config_id,
-    SourceAddressTokens previous_tokens,
-    const QuicIpAddress& ip,
-    QuicRandom* rand,
-    QuicWallTime now,
-    CachedNetworkParameters* cached_network_params) {
-  return server_config_->NewSourceAddressToken(
-      *GetConfig(config_id)->source_address_token_boxer, previous_tokens, ip,
-      rand, now, cached_network_params);
-}
-
-HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSourceAddressTokens(
-    std::string config_id,
-    absl::string_view srct,
-    const QuicIpAddress& ip,
-    QuicWallTime now,
-    CachedNetworkParameters* cached_network_params) {
-  SourceAddressTokens tokens;
-  HandshakeFailureReason reason = server_config_->ParseSourceAddressToken(
-      *GetConfig(config_id)->source_address_token_boxer, srct, tokens);
-  if (reason != HANDSHAKE_OK) {
-    return reason;
-  }
-
-  return server_config_->ValidateSourceAddressTokens(tokens, ip, now,
-                                                     cached_network_params);
-}
-
-HandshakeFailureReason
-QuicCryptoServerConfigPeer::ValidateSingleSourceAddressToken(
-    absl::string_view token,
-    const QuicIpAddress& ip,
-    QuicWallTime now) {
-  SourceAddressTokens tokens;
-  HandshakeFailureReason parse_status = server_config_->ParseSourceAddressToken(
-      *GetPrimaryConfig()->source_address_token_boxer, token, tokens);
-  if (HANDSHAKE_OK != parse_status) {
-    return parse_status;
-  }
-  EXPECT_EQ(1, tokens.tokens_size());
-  return server_config_->ValidateSingleSourceAddressToken(tokens.tokens(0), ip,
-                                                          now);
-}
-
-void QuicCryptoServerConfigPeer::CheckConfigs(
-    std::vector<std::pair<std::string, bool>> expected_ids_and_status) {
-  QuicReaderMutexLock locked(&server_config_->configs_lock_);
-
-  ASSERT_EQ(expected_ids_and_status.size(), server_config_->configs_.size())
-      << ConfigsDebug();
-
-  for (const std::pair<const ServerConfigID,
-                       quiche::QuicheReferenceCountedPointer<
-                           QuicCryptoServerConfig::Config>>& i :
-       server_config_->configs_) {
-    bool found = false;
-    for (std::pair<ServerConfigID, bool>& j : expected_ids_and_status) {
-      if (i.first == j.first && i.second->is_primary == j.second) {
-        found = true;
-        j.first.clear();
-        break;
-      }
-    }
-
-    ASSERT_TRUE(found) << "Failed to find match for " << i.first
-                       << " in configs:\n"
-                       << ConfigsDebug();
-  }
-}
-
-// ConfigsDebug returns a std::string that contains debugging information about
-// the set of Configs loaded in |server_config_| and their status.
-std::string QuicCryptoServerConfigPeer::ConfigsDebug() {
-  if (server_config_->configs_.empty()) {
-    return "No Configs in QuicCryptoServerConfig";
-  }
-
-  std::string s;
-
-  for (const auto& i : server_config_->configs_) {
-    const quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-        config = i.second;
-    if (config->is_primary) {
-      s += "(primary) ";
-    } else {
-      s += "          ";
-    }
-    s += config->id;
-    s += "\n";
-  }
-
-  return s;
-}
-
-void QuicCryptoServerConfigPeer::SelectNewPrimaryConfig(int seconds) {
-  QuicWriterMutexLock locked(&server_config_->configs_lock_);
-  server_config_->SelectNewPrimaryConfig(
-      QuicWallTime::FromUNIXSeconds(seconds));
-}
-
-std::string QuicCryptoServerConfigPeer::CompressChain(
-    QuicCompressedCertsCache* compressed_certs_cache,
-    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-    const std::string& client_cached_cert_hashes) {
-  return QuicCryptoServerConfig::CompressChain(compressed_certs_cache, chain,
-                                               client_cached_cert_hashes);
-}
-
-uint32_t QuicCryptoServerConfigPeer::source_address_token_future_secs() {
-  return server_config_->source_address_token_future_secs_;
-}
-
-uint32_t QuicCryptoServerConfigPeer::source_address_token_lifetime_secs() {
-  return server_config_->source_address_token_lifetime_secs_;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_crypto_server_config_peer.h b/quic/test_tools/quic_crypto_server_config_peer.h
deleted file mode 100644
index 029d403..0000000
--- a/quic/test_tools/quic_crypto_server_config_peer.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-
-namespace quic {
-namespace test {
-
-// Peer for accessing otherwise private members of a QuicCryptoServerConfig.
-class QuicCryptoServerConfigPeer {
- public:
-  explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
-      : server_config_(server_config) {}
-
-  // Returns the primary config.
-  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-  GetPrimaryConfig();
-
-  // Returns the config associated with |config_id|.
-  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
-  GetConfig(std::string config_id);
-
-  // Returns a pointer to the ProofSource object.
-  ProofSource* GetProofSource() const;
-
-  // Reset the proof_source_ member.
-  void ResetProofSource(std::unique_ptr<ProofSource> proof_source);
-
-  // Generates a new valid source address token.
-  std::string NewSourceAddressToken(
-      std::string config_id,
-      SourceAddressTokens previous_tokens,
-      const QuicIpAddress& ip,
-      QuicRandom* rand,
-      QuicWallTime now,
-      CachedNetworkParameters* cached_network_params);
-
-  // Attempts to validate the tokens in |srct|.
-  HandshakeFailureReason ValidateSourceAddressTokens(
-      std::string config_id, absl::string_view srct, const QuicIpAddress& ip,
-      QuicWallTime now, CachedNetworkParameters* cached_network_params);
-
-  // Attempts to validate the single source address token in |token|.
-  HandshakeFailureReason ValidateSingleSourceAddressToken(
-      absl::string_view token,
-      const QuicIpAddress& ip,
-      QuicWallTime now);
-
-  // CheckConfigs compares the state of the Configs in |server_config_| to the
-  // description given as arguments.
-  // The first of each pair is the server config ID of a Config. The second is a
-  // boolean describing whether the config is the primary. For example:
-  //   CheckConfigs(std::vector<std::pair<ServerConfigID, bool>>());  // checks
-  //   that no Configs are loaded.
-  //
-  //   // Checks that exactly three Configs are loaded with the given IDs and
-  //   // status.
-  //   CheckConfigs(
-  //     {{"id1", false},
-  //      {"id2", true},
-  //      {"id3", false}});
-  void CheckConfigs(
-      std::vector<std::pair<ServerConfigID, bool>> expected_ids_and_status);
-
-  // ConfigsDebug returns a std::string that contains debugging information
-  // about the set of Configs loaded in |server_config_| and their status.
-  std::string ConfigsDebug()
-      QUIC_SHARED_LOCKS_REQUIRED(server_config_->configs_lock_);
-
-  void SelectNewPrimaryConfig(int seconds);
-
-  static std::string CompressChain(
-      QuicCompressedCertsCache* compressed_certs_cache,
-      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
-      const std::string& client_cached_cert_hashes);
-
-  uint32_t source_address_token_future_secs();
-
-  uint32_t source_address_token_lifetime_secs();
-
- private:
-  QuicCryptoServerConfig* server_config_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
diff --git a/quic/test_tools/quic_dispatcher_peer.cc b/quic/test_tools/quic_dispatcher_peer.cc
deleted file mode 100644
index 341d5ac..0000000
--- a/quic/test_tools/quic_dispatcher_peer.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_dispatcher_peer.h"
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicTimeWaitListManager* QuicDispatcherPeer::GetTimeWaitListManager(
-    QuicDispatcher* dispatcher) {
-  return dispatcher->time_wait_list_manager_.get();
-}
-
-// static
-void QuicDispatcherPeer::SetTimeWaitListManager(
-    QuicDispatcher* dispatcher,
-    QuicTimeWaitListManager* time_wait_list_manager) {
-  dispatcher->time_wait_list_manager_.reset(time_wait_list_manager);
-}
-
-// static
-void QuicDispatcherPeer::UseWriter(QuicDispatcher* dispatcher,
-                                   QuicPacketWriterWrapper* writer) {
-  writer->set_writer(dispatcher->writer_.release());
-  dispatcher->writer_.reset(writer);
-}
-
-// static
-QuicPacketWriter* QuicDispatcherPeer::GetWriter(QuicDispatcher* dispatcher) {
-  return dispatcher->writer_.get();
-}
-
-// static
-QuicCompressedCertsCache* QuicDispatcherPeer::GetCache(
-    QuicDispatcher* dispatcher) {
-  return dispatcher->compressed_certs_cache();
-}
-
-// static
-QuicConnectionHelperInterface* QuicDispatcherPeer::GetHelper(
-    QuicDispatcher* dispatcher) {
-  return dispatcher->helper_.get();
-}
-
-// static
-QuicAlarmFactory* QuicDispatcherPeer::GetAlarmFactory(
-    QuicDispatcher* dispatcher) {
-  return dispatcher->alarm_factory_.get();
-}
-
-// static
-QuicDispatcher::WriteBlockedList* QuicDispatcherPeer::GetWriteBlockedList(
-    QuicDispatcher* dispatcher) {
-  return &dispatcher->write_blocked_list_;
-}
-
-// static
-QuicErrorCode QuicDispatcherPeer::GetAndClearLastError(
-    QuicDispatcher* dispatcher) {
-  QuicErrorCode ret = dispatcher->last_error_;
-  dispatcher->last_error_ = QUIC_NO_ERROR;
-  return ret;
-}
-
-// static
-QuicBufferedPacketStore* QuicDispatcherPeer::GetBufferedPackets(
-    QuicDispatcher* dispatcher) {
-  return &(dispatcher->buffered_packets_);
-}
-
-// static
-void QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
-    QuicDispatcher* dispatcher,
-    size_t num_session_allowed) {
-  dispatcher->new_sessions_allowed_per_event_loop_ = num_session_allowed;
-}
-
-// static
-void QuicDispatcherPeer::SendPublicReset(
-    QuicDispatcher* dispatcher,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    QuicConnectionId connection_id,
-    bool ietf_quic,
-    size_t received_packet_length,
-    std::unique_ptr<QuicPerPacketContext> packet_context) {
-  dispatcher->time_wait_list_manager()->SendPublicReset(
-      self_address, peer_address, connection_id, ietf_quic,
-      received_packet_length, std::move(packet_context));
-}
-
-// static
-std::unique_ptr<QuicPerPacketContext> QuicDispatcherPeer::GetPerPacketContext(
-    QuicDispatcher* dispatcher) {
-  return dispatcher->GetPerPacketContext();
-}
-
-// static
-void QuicDispatcherPeer::RestorePerPacketContext(
-    QuicDispatcher* dispatcher,
-    std::unique_ptr<QuicPerPacketContext> context) {
-  dispatcher->RestorePerPacketContext(std::move(context));
-}
-
-// static
-std::string QuicDispatcherPeer::SelectAlpn(
-    QuicDispatcher* dispatcher,
-    const std::vector<std::string>& alpns) {
-  return dispatcher->SelectAlpn(alpns);
-}
-
-// static
-QuicSession* QuicDispatcherPeer::GetFirstSessionIfAny(
-    QuicDispatcher* dispatcher) {
-  if (dispatcher->reference_counted_session_map_.empty()) {
-    return nullptr;
-  }
-  return dispatcher->reference_counted_session_map_.begin()->second.get();
-}
-
-// static
-const QuicSession* QuicDispatcherPeer::FindSession(
-    const QuicDispatcher* dispatcher,
-    QuicConnectionId id) {
-  auto it = dispatcher->reference_counted_session_map_.find(id);
-  return (it == dispatcher->reference_counted_session_map_.end())
-             ? nullptr
-             : it->second.get();
-}
-
-// static
-QuicAlarm* QuicDispatcherPeer::GetClearResetAddressesAlarm(
-    QuicDispatcher* dispatcher) {
-  return dispatcher->clear_stateless_reset_addresses_alarm_.get();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_dispatcher_peer.h b/quic/test_tools/quic_dispatcher_peer.h
deleted file mode 100644
index ec83be4..0000000
--- a/quic/test_tools/quic_dispatcher_peer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
-
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_dispatcher.h"
-
-namespace quic {
-
-class QuicPacketWriterWrapper;
-
-namespace test {
-
-class QuicDispatcherPeer {
- public:
-  QuicDispatcherPeer() = delete;
-
-  static QuicTimeWaitListManager* GetTimeWaitListManager(
-      QuicDispatcher* dispatcher);
-
-  static void SetTimeWaitListManager(
-      QuicDispatcher* dispatcher,
-      QuicTimeWaitListManager* time_wait_list_manager);
-
-  // Injects |writer| into |dispatcher| as the shared writer.
-  static void UseWriter(QuicDispatcher* dispatcher,
-                        QuicPacketWriterWrapper* writer);
-
-  static QuicPacketWriter* GetWriter(QuicDispatcher* dispatcher);
-
-  static QuicCompressedCertsCache* GetCache(QuicDispatcher* dispatcher);
-
-  static QuicConnectionHelperInterface* GetHelper(QuicDispatcher* dispatcher);
-
-  static QuicAlarmFactory* GetAlarmFactory(QuicDispatcher* dispatcher);
-
-  static QuicDispatcher::WriteBlockedList* GetWriteBlockedList(
-      QuicDispatcher* dispatcher);
-
-  // Get the dispatcher's record of the last error reported to its framer
-  // visitor's OnError() method.  Then set that record to QUIC_NO_ERROR.
-  static QuicErrorCode GetAndClearLastError(QuicDispatcher* dispatcher);
-
-  static QuicBufferedPacketStore* GetBufferedPackets(
-      QuicDispatcher* dispatcher);
-
-  static void set_new_sessions_allowed_per_event_loop(
-      QuicDispatcher* dispatcher,
-      size_t num_session_allowed);
-
-  static void SendPublicReset(
-      QuicDispatcher* dispatcher,
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address,
-      QuicConnectionId connection_id,
-      bool ietf_quic,
-      size_t received_packet_length,
-      std::unique_ptr<QuicPerPacketContext> packet_context);
-
-  static std::unique_ptr<QuicPerPacketContext> GetPerPacketContext(
-      QuicDispatcher* dispatcher);
-
-  static void RestorePerPacketContext(QuicDispatcher* dispatcher,
-                                      std::unique_ptr<QuicPerPacketContext>);
-
-  static std::string SelectAlpn(QuicDispatcher* dispatcher,
-                                const std::vector<std::string>& alpns);
-
-  // Get the first session in the session map. Returns nullptr if the map is
-  // empty.
-  static QuicSession* GetFirstSessionIfAny(QuicDispatcher* dispatcher);
-
-  // Find the corresponding session if exsits.
-  static const QuicSession* FindSession(const QuicDispatcher* dispatcher,
-                                        QuicConnectionId id);
-
-  static QuicAlarm* GetClearResetAddressesAlarm(QuicDispatcher* dispatcher);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
diff --git a/quic/test_tools/quic_flow_controller_peer.cc b/quic/test_tools/quic_flow_controller_peer.cc
deleted file mode 100644
index b0c9cbc..0000000
--- a/quic/test_tools/quic_flow_controller_peer.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_flow_controller_peer.h"
-
-#include <list>
-
-#include "quic/core/quic_flow_controller.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicFlowControllerPeer::SetSendWindowOffset(
-    QuicFlowController* flow_controller,
-    QuicStreamOffset offset) {
-  flow_controller->send_window_offset_ = offset;
-}
-
-// static
-void QuicFlowControllerPeer::SetReceiveWindowOffset(
-    QuicFlowController* flow_controller,
-    QuicStreamOffset offset) {
-  flow_controller->receive_window_offset_ = offset;
-}
-
-// static
-void QuicFlowControllerPeer::SetMaxReceiveWindow(
-    QuicFlowController* flow_controller,
-    QuicByteCount window_size) {
-  flow_controller->receive_window_size_ = window_size;
-}
-
-// static
-QuicStreamOffset QuicFlowControllerPeer::SendWindowOffset(
-    QuicFlowController* flow_controller) {
-  return flow_controller->send_window_offset_;
-}
-
-// static
-QuicByteCount QuicFlowControllerPeer::SendWindowSize(
-    QuicFlowController* flow_controller) {
-  return flow_controller->SendWindowSize();
-}
-
-// static
-QuicStreamOffset QuicFlowControllerPeer::ReceiveWindowOffset(
-    QuicFlowController* flow_controller) {
-  return flow_controller->receive_window_offset_;
-}
-
-// static
-QuicByteCount QuicFlowControllerPeer::ReceiveWindowSize(
-    QuicFlowController* flow_controller) {
-  return flow_controller->receive_window_offset_ -
-         flow_controller->highest_received_byte_offset_;
-}
-
-// static
-QuicByteCount QuicFlowControllerPeer::WindowUpdateThreshold(
-    QuicFlowController* flow_controller) {
-  return flow_controller->WindowUpdateThreshold();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_flow_controller_peer.h b/quic/test_tools/quic_flow_controller_peer.h
deleted file mode 100644
index 0a95620..0000000
--- a/quic/test_tools/quic_flow_controller_peer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicFlowController;
-
-namespace test {
-
-class QuicFlowControllerPeer {
- public:
-  QuicFlowControllerPeer() = delete;
-
-  static void SetSendWindowOffset(QuicFlowController* flow_controller,
-                                  QuicStreamOffset offset);
-
-  static void SetReceiveWindowOffset(QuicFlowController* flow_controller,
-                                     QuicStreamOffset offset);
-
-  static void SetMaxReceiveWindow(QuicFlowController* flow_controller,
-                                  QuicByteCount window_size);
-
-  static QuicStreamOffset SendWindowOffset(QuicFlowController* flow_controller);
-
-  static QuicByteCount SendWindowSize(QuicFlowController* flow_controller);
-
-  static QuicStreamOffset ReceiveWindowOffset(
-      QuicFlowController* flow_controller);
-
-  static QuicByteCount ReceiveWindowSize(QuicFlowController* flow_controller);
-
-  static QuicByteCount WindowUpdateThreshold(
-      QuicFlowController* flow_controller);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
diff --git a/quic/test_tools/quic_framer_peer.cc b/quic/test_tools/quic_framer_peer.cc
deleted file mode 100644
index 8692a25..0000000
--- a/quic/test_tools/quic_framer_peer.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_framer_peer.h"
-
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-namespace test {
-
-// static
-uint64_t QuicFramerPeer::CalculatePacketNumberFromWire(
-    QuicFramer* framer,
-    QuicPacketNumberLength packet_number_length,
-    QuicPacketNumber last_packet_number,
-    uint64_t packet_number) {
-  return framer->CalculatePacketNumberFromWire(
-      packet_number_length, last_packet_number, packet_number);
-}
-
-// static
-void QuicFramerPeer::SetLastSerializedServerConnectionId(
-    QuicFramer* framer,
-    QuicConnectionId server_connection_id) {
-  framer->last_serialized_server_connection_id_ = server_connection_id;
-}
-
-// static
-void QuicFramerPeer::SetLastSerializedClientConnectionId(
-    QuicFramer* framer,
-    QuicConnectionId client_connection_id) {
-  framer->last_serialized_client_connection_id_ = client_connection_id;
-}
-
-// static
-void QuicFramerPeer::SetLastWrittenPacketNumberLength(
-    QuicFramer* framer,
-    size_t packet_number_length) {
-  framer->last_written_packet_number_length_ = packet_number_length;
-}
-
-// static
-void QuicFramerPeer::SetLargestPacketNumber(QuicFramer* framer,
-                                            QuicPacketNumber packet_number) {
-  framer->largest_packet_number_ = packet_number;
-}
-
-// static
-void QuicFramerPeer::SetPerspective(QuicFramer* framer,
-                                    Perspective perspective) {
-  framer->perspective_ = perspective;
-  framer->infer_packet_header_type_from_version_ =
-      perspective == Perspective::IS_CLIENT;
-}
-
-// static
-void QuicFramerPeer::SwapCrypters(QuicFramer* framer1, QuicFramer* framer2) {
-  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
-    framer1->encrypter_[i].swap(framer2->encrypter_[i]);
-    framer1->decrypter_[i].swap(framer2->decrypter_[i]);
-  }
-
-  EncryptionLevel framer2_level = framer2->decrypter_level_;
-  framer2->decrypter_level_ = framer1->decrypter_level_;
-  framer1->decrypter_level_ = framer2_level;
-  framer2_level = framer2->alternative_decrypter_level_;
-  framer2->alternative_decrypter_level_ = framer1->alternative_decrypter_level_;
-  framer1->alternative_decrypter_level_ = framer2_level;
-
-  const bool framer2_latch = framer2->alternative_decrypter_latch_;
-  framer2->alternative_decrypter_latch_ = framer1->alternative_decrypter_latch_;
-  framer1->alternative_decrypter_latch_ = framer2_latch;
-}
-
-// static
-QuicEncrypter* QuicFramerPeer::GetEncrypter(QuicFramer* framer,
-                                            EncryptionLevel level) {
-  return framer->encrypter_[level].get();
-}
-
-// static
-QuicDecrypter* QuicFramerPeer::GetDecrypter(QuicFramer* framer,
-                                            EncryptionLevel level) {
-  return framer->decrypter_[level].get();
-}
-
-// static
-void QuicFramerPeer::SetFirstSendingPacketNumber(QuicFramer* framer,
-                                                 uint64_t packet_number) {
-  *const_cast<QuicPacketNumber*>(&framer->first_sending_packet_number_) =
-      QuicPacketNumber(packet_number);
-}
-
-// static
-void QuicFramerPeer::SetExpectedServerConnectionIDLength(
-    QuicFramer* framer,
-    uint8_t expected_server_connection_id_length) {
-  *const_cast<uint8_t*>(&framer->expected_server_connection_id_length_) =
-      expected_server_connection_id_length;
-}
-
-// static
-QuicPacketNumber QuicFramerPeer::GetLargestDecryptedPacketNumber(
-    QuicFramer* framer,
-    PacketNumberSpace packet_number_space) {
-  return framer->largest_decrypted_packet_numbers_[packet_number_space];
-}
-
-// static
-bool QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
-    QuicDataReader* reader,
-    ParsedQuicVersion version,
-    Perspective perspective,
-    bool should_update_expected_server_connection_id_length,
-    uint8_t* expected_server_connection_id_length,
-    uint8_t* destination_connection_id_length,
-    uint8_t* source_connection_id_length,
-    std::string* detailed_error) {
-  return QuicFramer::ProcessAndValidateIetfConnectionIdLength(
-      reader, version, perspective,
-      should_update_expected_server_connection_id_length,
-      expected_server_connection_id_length, destination_connection_id_length,
-      source_connection_id_length, detailed_error);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_framer_peer.h b/quic/test_tools/quic_framer_peer.h
deleted file mode 100644
index 091a7d4..0000000
--- a/quic/test_tools/quic_framer_peer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
-
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicFramerPeer {
- public:
-  QuicFramerPeer() = delete;
-
-  static uint64_t CalculatePacketNumberFromWire(
-      QuicFramer* framer,
-      QuicPacketNumberLength packet_number_length,
-      QuicPacketNumber last_packet_number,
-      uint64_t packet_number);
-  static void SetLastSerializedServerConnectionId(
-      QuicFramer* framer,
-      QuicConnectionId server_connection_id);
-  static void SetLastSerializedClientConnectionId(
-      QuicFramer* framer,
-      QuicConnectionId client_connection_id);
-  static void SetLastWrittenPacketNumberLength(QuicFramer* framer,
-                                               size_t packet_number_length);
-  static void SetLargestPacketNumber(QuicFramer* framer,
-                                     QuicPacketNumber packet_number);
-  static void SetPerspective(QuicFramer* framer, Perspective perspective);
-
-  // SwapCrypters exchanges the state of the crypters of |framer1| with
-  // |framer2|.
-  static void SwapCrypters(QuicFramer* framer1, QuicFramer* framer2);
-
-  static QuicEncrypter* GetEncrypter(QuicFramer* framer, EncryptionLevel level);
-  static QuicDecrypter* GetDecrypter(QuicFramer* framer, EncryptionLevel level);
-
-  static void SetFirstSendingPacketNumber(QuicFramer* framer,
-                                          uint64_t packet_number);
-  static void SetExpectedServerConnectionIDLength(
-      QuicFramer* framer,
-      uint8_t expected_server_connection_id_length);
-  static QuicPacketNumber GetLargestDecryptedPacketNumber(
-      QuicFramer* framer,
-      PacketNumberSpace packet_number_space);
-
-  static bool ProcessAndValidateIetfConnectionIdLength(
-      QuicDataReader* reader,
-      ParsedQuicVersion version,
-      Perspective perspective,
-      bool should_update_expected_server_connection_id_length,
-      uint8_t* expected_server_connection_id_length,
-      uint8_t* destination_connection_id_length,
-      uint8_t* source_connection_id_length,
-      std::string* detailed_error);
-
-  static void set_current_received_frame_type(
-      QuicFramer* framer,
-      uint64_t current_received_frame_type) {
-    framer->current_received_frame_type_ = current_received_frame_type;
-  }
-
-  static bool infer_packet_header_type_from_version(QuicFramer* framer) {
-    return framer->infer_packet_header_type_from_version_;
-  }
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
diff --git a/quic/test_tools/quic_interval_deque_peer.h b/quic/test_tools/quic_interval_deque_peer.h
deleted file mode 100644
index de336e9..0000000
--- a/quic/test_tools/quic_interval_deque_peer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
-
-#include "quic/core/quic_interval_deque.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicIntervalDequePeer {
- public:
-  template <class T, class C>
-  static int32_t GetCachedIndex(QuicIntervalDeque<T, C>* interval_deque) {
-    if (!interval_deque->cached_index_.has_value()) {
-      return -1;
-    }
-    return interval_deque->cached_index_.value();
-  }
-
-  template <class T, class C>
-  static T* GetItem(QuicIntervalDeque<T, C>* interval_deque,
-                    const std::size_t index) {
-    return &interval_deque->container_[index];
-  }
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
diff --git a/quic/test_tools/quic_mock_syscall_wrapper.cc b/quic/test_tools/quic_mock_syscall_wrapper.cc
deleted file mode 100644
index 743d5c3..0000000
--- a/quic/test_tools/quic_mock_syscall_wrapper.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_mock_syscall_wrapper.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-MockQuicSyscallWrapper::MockQuicSyscallWrapper(QuicSyscallWrapper* delegate) {
-  ON_CALL(*this, Sendmsg(_, _, _))
-      .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmsg));
-
-  ON_CALL(*this, Sendmmsg(_, _, _, _))
-      .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmmsg));
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_mock_syscall_wrapper.h b/quic/test_tools/quic_mock_syscall_wrapper.h
deleted file mode 100644
index 681d1bc..0000000
--- a/quic/test_tools/quic_mock_syscall_wrapper.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
-#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
-
-#include "quic/core/quic_syscall_wrapper.h"
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class MockQuicSyscallWrapper : public QuicSyscallWrapper {
- public:
-  // Create a standard mock object.
-  MockQuicSyscallWrapper() = default;
-
-  // Create a 'mockable' object that delegates everything to |delegate| by
-  // default.
-  explicit MockQuicSyscallWrapper(QuicSyscallWrapper* delegate);
-
-  MOCK_METHOD(ssize_t,
-              Sendmsg,
-              (int sockfd, const msghdr*, int flags),
-              (override));
-
-  MOCK_METHOD(int,
-              Sendmmsg,
-              (int sockfd, mmsghdr*, unsigned int vlen, int flags),
-              (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
diff --git a/quic/test_tools/quic_packet_creator_peer.cc b/quic/test_tools/quic_packet_creator_peer.cc
deleted file mode 100644
index 8baef92..0000000
--- a/quic/test_tools/quic_packet_creator_peer.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_packet_creator_peer.h"
-
-#include "quic/core/frames/quic_frame.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-namespace test {
-
-// static
-bool QuicPacketCreatorPeer::SendVersionInPacket(QuicPacketCreator* creator) {
-  return creator->IncludeVersionInHeader();
-}
-
-// static
-void QuicPacketCreatorPeer::SetSendVersionInPacket(
-    QuicPacketCreator* creator,
-    bool send_version_in_packet) {
-  ParsedQuicVersion version = creator->framer_->version();
-  if (!VersionHasIetfQuicFrames(version.transport_version) &&
-      version.handshake_protocol != PROTOCOL_TLS1_3) {
-    creator->send_version_in_packet_ = send_version_in_packet;
-    return;
-  }
-  if (!send_version_in_packet) {
-    creator->packet_.encryption_level = ENCRYPTION_FORWARD_SECURE;
-    return;
-  }
-  QUICHE_DCHECK(creator->packet_.encryption_level < ENCRYPTION_FORWARD_SECURE);
-}
-
-// static
-void QuicPacketCreatorPeer::SetPacketNumberLength(
-    QuicPacketCreator* creator,
-    QuicPacketNumberLength packet_number_length) {
-  creator->packet_.packet_number_length = packet_number_length;
-}
-
-// static
-QuicPacketNumberLength QuicPacketCreatorPeer::GetPacketNumberLength(
-    QuicPacketCreator* creator) {
-  return creator->GetPacketNumberLength();
-}
-
-// static
-QuicVariableLengthIntegerLength
-QuicPacketCreatorPeer::GetRetryTokenLengthLength(QuicPacketCreator* creator) {
-  return creator->GetRetryTokenLengthLength();
-}
-
-// static
-QuicVariableLengthIntegerLength QuicPacketCreatorPeer::GetLengthLength(
-    QuicPacketCreator* creator) {
-  return creator->GetLengthLength();
-}
-
-void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
-                                            uint64_t s) {
-  QUICHE_DCHECK_NE(0u, s);
-  creator->packet_.packet_number = QuicPacketNumber(s);
-}
-
-void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
-                                            QuicPacketNumber num) {
-  creator->packet_.packet_number = num;
-}
-
-// static
-void QuicPacketCreatorPeer::ClearPacketNumber(QuicPacketCreator* creator) {
-  creator->packet_.packet_number.Clear();
-}
-
-// static
-void QuicPacketCreatorPeer::FillPacketHeader(QuicPacketCreator* creator,
-                                             QuicPacketHeader* header) {
-  creator->FillPacketHeader(header);
-}
-
-// static
-void QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
-                                              QuicStreamId id,
-                                              size_t data_length,
-                                              QuicStreamOffset offset,
-                                              bool fin,
-                                              QuicFrame* frame) {
-  creator->CreateStreamFrame(id, data_length, offset, fin, frame);
-}
-
-// static
-bool QuicPacketCreatorPeer::CreateCryptoFrame(QuicPacketCreator* creator,
-                                              EncryptionLevel level,
-                                              size_t write_length,
-                                              QuicStreamOffset offset,
-                                              QuicFrame* frame) {
-  return creator->CreateCryptoFrame(level, write_length, offset, frame);
-}
-
-// static
-SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames(
-    QuicPacketCreator* creator,
-    const QuicFrames& frames,
-    char* buffer,
-    size_t buffer_len) {
-  QUICHE_DCHECK(creator->queued_frames_.empty());
-  QUICHE_DCHECK(!frames.empty());
-  for (const QuicFrame& frame : frames) {
-    bool success = creator->AddFrame(frame, NOT_RETRANSMISSION);
-    QUICHE_DCHECK(success);
-  }
-  const bool success =
-      creator->SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr),
-                               buffer_len, /*allow_padding=*/true);
-  QUICHE_DCHECK(success);
-  SerializedPacket packet = std::move(creator->packet_);
-  // The caller takes ownership of the QuicEncryptedPacket.
-  creator->packet_.encrypted_buffer = nullptr;
-  return packet;
-}
-
-// static
-std::unique_ptr<SerializedPacket>
-QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
-    QuicPacketCreator* creator) {
-  return creator->SerializeConnectivityProbingPacket();
-}
-
-// static
-std::unique_ptr<SerializedPacket>
-QuicPacketCreatorPeer::SerializePathChallengeConnectivityProbingPacket(
-    QuicPacketCreator* creator,
-    const QuicPathFrameBuffer& payload) {
-  return creator->SerializePathChallengeConnectivityProbingPacket(payload);
-}
-
-// static
-EncryptionLevel QuicPacketCreatorPeer::GetEncryptionLevel(
-    QuicPacketCreator* creator) {
-  return creator->packet_.encryption_level;
-}
-
-// static
-QuicFramer* QuicPacketCreatorPeer::framer(QuicPacketCreator* creator) {
-  return creator->framer_;
-}
-
-// static
-std::string QuicPacketCreatorPeer::GetRetryToken(QuicPacketCreator* creator) {
-  return creator->retry_token_;
-}
-
-// static
-QuicFrames& QuicPacketCreatorPeer::QueuedFrames(QuicPacketCreator* creator) {
-  return creator->queued_frames_;
-}
-
-// static
-void QuicPacketCreatorPeer::SetRandom(QuicPacketCreator* creator,
-                                      QuicRandom* random) {
-  creator->random_ = random;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_packet_creator_peer.h b/quic/test_tools/quic_packet_creator_peer.h
deleted file mode 100644
index 259191d..0000000
--- a/quic/test_tools/quic_packet_creator_peer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-class QuicFramer;
-class QuicPacketCreator;
-class QuicRandom;
-
-namespace test {
-
-class QuicPacketCreatorPeer {
- public:
-  QuicPacketCreatorPeer() = delete;
-
-  static bool SendVersionInPacket(QuicPacketCreator* creator);
-
-  static void SetSendVersionInPacket(QuicPacketCreator* creator,
-                                     bool send_version_in_packet);
-  static void SetPacketNumberLength(
-      QuicPacketCreator* creator,
-      QuicPacketNumberLength packet_number_length);
-  static QuicPacketNumberLength GetPacketNumberLength(
-      QuicPacketCreator* creator);
-  static QuicVariableLengthIntegerLength GetRetryTokenLengthLength(
-      QuicPacketCreator* creator);
-  static QuicVariableLengthIntegerLength GetLengthLength(
-      QuicPacketCreator* creator);
-  static void SetPacketNumber(QuicPacketCreator* creator, uint64_t s);
-  static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber num);
-  static void ClearPacketNumber(QuicPacketCreator* creator);
-  static void FillPacketHeader(QuicPacketCreator* creator,
-                               QuicPacketHeader* header);
-  static void CreateStreamFrame(QuicPacketCreator* creator,
-                                QuicStreamId id,
-                                size_t data_length,
-                                QuicStreamOffset offset,
-                                bool fin,
-                                QuicFrame* frame);
-  static bool CreateCryptoFrame(QuicPacketCreator* creator,
-                                EncryptionLevel level,
-                                size_t write_length,
-                                QuicStreamOffset offset,
-                                QuicFrame* frame);
-  static SerializedPacket SerializeAllFrames(QuicPacketCreator* creator,
-                                             const QuicFrames& frames,
-                                             char* buffer,
-                                             size_t buffer_len);
-  static std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket(
-      QuicPacketCreator* creator);
-  static std::unique_ptr<SerializedPacket>
-  SerializePathChallengeConnectivityProbingPacket(
-      QuicPacketCreator* creator,
-      const QuicPathFrameBuffer& payload);
-
-  static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
-  static QuicFramer* framer(QuicPacketCreator* creator);
-  static std::string GetRetryToken(QuicPacketCreator* creator);
-  static QuicFrames& QueuedFrames(QuicPacketCreator* creator);
-  static void SetRandom(QuicPacketCreator* creator, QuicRandom* random);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
diff --git a/quic/test_tools/quic_path_validator_peer.cc b/quic/test_tools/quic_path_validator_peer.cc
deleted file mode 100644
index 901ca54..0000000
--- a/quic/test_tools/quic_path_validator_peer.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_path_validator_peer.h"
-
-namespace quic {
-namespace test {
-//  static
-QuicAlarm* QuicPathValidatorPeer::retry_timer(QuicPathValidator* validator) {
-  return validator->retry_timer_.get();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_path_validator_peer.h b/quic/test_tools/quic_path_validator_peer.h
deleted file mode 100644
index 2495cd3..0000000
--- a/quic/test_tools/quic_path_validator_peer.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
-
-#include "quic/core/quic_path_validator.h"
-
-namespace quic {
-namespace test {
-
-class QuicPathValidatorPeer {
- public:
-  static QuicAlarm* retry_timer(QuicPathValidator* validator);
-};
-
-}  // namespace test
-}  // namespace quic
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
diff --git a/quic/test_tools/quic_sent_packet_manager_peer.cc b/quic/test_tools/quic_sent_packet_manager_peer.cc
deleted file mode 100644
index 8689535..0000000
--- a/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sent_packet_manager.h"
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-size_t QuicSentPacketManagerPeer::GetMaxTailLossProbes(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->max_tail_loss_probes_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetMaxTailLossProbes(
-    QuicSentPacketManager* sent_packet_manager,
-    size_t max_tail_loss_probes) {
-  sent_packet_manager->max_tail_loss_probes_ = max_tail_loss_probes;
-}
-
-// static
-bool QuicSentPacketManagerPeer::GetUseNewRto(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->use_new_rto_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetPerspective(
-    QuicSentPacketManager* sent_packet_manager,
-    Perspective perspective) {
-  QuicUnackedPacketMapPeer::SetPerspective(
-      &sent_packet_manager->unacked_packets_, perspective);
-}
-
-// static
-SendAlgorithmInterface* QuicSentPacketManagerPeer::GetSendAlgorithm(
-    const QuicSentPacketManager& sent_packet_manager) {
-  return sent_packet_manager.send_algorithm_.get();
-}
-
-// static
-void QuicSentPacketManagerPeer::SetSendAlgorithm(
-    QuicSentPacketManager* sent_packet_manager,
-    SendAlgorithmInterface* send_algorithm) {
-  sent_packet_manager->SetSendAlgorithm(send_algorithm);
-}
-
-// static
-const LossDetectionInterface* QuicSentPacketManagerPeer::GetLossAlgorithm(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->loss_algorithm_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetLossAlgorithm(
-    QuicSentPacketManager* sent_packet_manager,
-    LossDetectionInterface* loss_detector) {
-  sent_packet_manager->loss_algorithm_ = loss_detector;
-}
-
-// static
-RttStats* QuicSentPacketManagerPeer::GetRttStats(
-    QuicSentPacketManager* sent_packet_manager) {
-  return &sent_packet_manager->rtt_stats_;
-}
-
-// static
-bool QuicSentPacketManagerPeer::IsRetransmission(
-    QuicSentPacketManager* sent_packet_manager,
-    uint64_t packet_number) {
-  QUICHE_DCHECK(HasRetransmittableFrames(sent_packet_manager, packet_number));
-  if (!HasRetransmittableFrames(sent_packet_manager, packet_number)) {
-    return false;
-  }
-  return sent_packet_manager->unacked_packets_
-             .GetTransmissionInfo(QuicPacketNumber(packet_number))
-             .transmission_type != NOT_RETRANSMISSION;
-}
-
-// static
-void QuicSentPacketManagerPeer::MarkForRetransmission(
-    QuicSentPacketManager* sent_packet_manager,
-    uint64_t packet_number,
-    TransmissionType transmission_type) {
-  sent_packet_manager->MarkForRetransmission(QuicPacketNumber(packet_number),
-                                             transmission_type);
-}
-
-// static
-QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
-    const QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->GetRetransmissionDelay();
-}
-
-// static
-QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
-    const QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->GetTailLossProbeDelay();
-}
-
-// static
-size_t QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
-    const QuicSentPacketManager* sent_packet_manager) {
-  size_t num_unacked_packets = 0;
-  for (auto it = sent_packet_manager->unacked_packets_.begin();
-       it != sent_packet_manager->unacked_packets_.end(); ++it) {
-    if (sent_packet_manager->unacked_packets_.HasRetransmittableFrames(*it)) {
-      ++num_unacked_packets;
-    }
-  }
-  return num_unacked_packets;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetConsecutiveRtoCount(
-    QuicSentPacketManager* sent_packet_manager,
-    size_t count) {
-  sent_packet_manager->consecutive_rto_count_ = count;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetConsecutiveTlpCount(
-    QuicSentPacketManager* sent_packet_manager,
-    size_t count) {
-  sent_packet_manager->consecutive_tlp_count_ = count;
-}
-
-// static
-QuicSustainedBandwidthRecorder& QuicSentPacketManagerPeer::GetBandwidthRecorder(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->sustained_bandwidth_recorder_;
-}
-
-// static
-bool QuicSentPacketManagerPeer::UsingPacing(
-    const QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->using_pacing_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetUsingPacing(
-    QuicSentPacketManager* sent_packet_manager,
-    bool using_pacing) {
-  sent_packet_manager->using_pacing_ = using_pacing;
-}
-
-// static
-bool QuicSentPacketManagerPeer::HasRetransmittableFrames(
-    QuicSentPacketManager* sent_packet_manager,
-    uint64_t packet_number) {
-  return sent_packet_manager->unacked_packets_.HasRetransmittableFrames(
-      QuicPacketNumber(packet_number));
-}
-
-// static
-QuicUnackedPacketMap* QuicSentPacketManagerPeer::GetUnackedPacketMap(
-    QuicSentPacketManager* sent_packet_manager) {
-  return &sent_packet_manager->unacked_packets_;
-}
-
-// static
-void QuicSentPacketManagerPeer::DisablePacerBursts(
-    QuicSentPacketManager* sent_packet_manager) {
-  sent_packet_manager->pacing_sender_.burst_tokens_ = 0;
-  sent_packet_manager->pacing_sender_.initial_burst_size_ = 0;
-}
-
-// static
-int QuicSentPacketManagerPeer::GetPacerInitialBurstSize(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->pacing_sender_.initial_burst_size_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetNextPacedPacketTime(
-    QuicSentPacketManager* sent_packet_manager,
-    QuicTime time) {
-  sent_packet_manager->pacing_sender_.ideal_next_packet_send_time_ = time;
-}
-
-// static
-int QuicSentPacketManagerPeer::GetReorderingShift(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
-      .reordering_shift();
-}
-
-// static
-bool QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
-      .use_adaptive_reordering_threshold();
-}
-
-// static
-bool QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
-      .use_adaptive_time_threshold();
-}
-
-// static
-bool QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
-      .use_packet_threshold_for_runt_packets();
-}
-
-// static
-int QuicSentPacketManagerPeer::GetNumPtosForPathDegrading(
-    QuicSentPacketManager* sent_packet_manager) {
-  return sent_packet_manager->num_ptos_for_path_degrading_;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_sent_packet_manager_peer.h b/quic/test_tools/quic_sent_packet_manager_peer.h
deleted file mode 100644
index ef0af1e..0000000
--- a/quic/test_tools/quic_sent_packet_manager_peer.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sent_packet_manager.h"
-
-namespace quic {
-
-class SendAlgorithmInterface;
-
-namespace test {
-
-class QuicSentPacketManagerPeer {
- public:
-  QuicSentPacketManagerPeer() = delete;
-
-  static size_t GetMaxTailLossProbes(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static void SetMaxTailLossProbes(QuicSentPacketManager* sent_packet_manager,
-                                   size_t max_tail_loss_probes);
-
-  static bool GetUseNewRto(QuicSentPacketManager* sent_packet_manager);
-
-  static void SetPerspective(QuicSentPacketManager* sent_packet_manager,
-                             Perspective perspective);
-
-  static SendAlgorithmInterface* GetSendAlgorithm(
-      const QuicSentPacketManager& sent_packet_manager);
-
-  static void SetSendAlgorithm(QuicSentPacketManager* sent_packet_manager,
-                               SendAlgorithmInterface* send_algorithm);
-
-  static const LossDetectionInterface* GetLossAlgorithm(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static void SetLossAlgorithm(QuicSentPacketManager* sent_packet_manager,
-                               LossDetectionInterface* loss_detector);
-
-  static RttStats* GetRttStats(QuicSentPacketManager* sent_packet_manager);
-
-  // Returns true if |packet_number| is a retransmission of a packet.
-  static bool IsRetransmission(QuicSentPacketManager* sent_packet_manager,
-                               uint64_t packet_number);
-
-  static void MarkForRetransmission(QuicSentPacketManager* sent_packet_manager,
-                                    uint64_t packet_number,
-                                    TransmissionType transmission_type);
-
-  static QuicTime::Delta GetRetransmissionDelay(
-      const QuicSentPacketManager* sent_packet_manager);
-  static QuicTime::Delta GetTailLossProbeDelay(
-      const QuicSentPacketManager* sent_packet_manager);
-
-  static size_t GetNumRetransmittablePackets(
-      const QuicSentPacketManager* sent_packet_manager);
-
-  static void SetConsecutiveRtoCount(QuicSentPacketManager* sent_packet_manager,
-                                     size_t count);
-
-  static void SetConsecutiveTlpCount(QuicSentPacketManager* sent_packet_manager,
-                                     size_t count);
-
-  static QuicSustainedBandwidthRecorder& GetBandwidthRecorder(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static void SetUsingPacing(QuicSentPacketManager* sent_packet_manager,
-                             bool using_pacing);
-
-  static bool UsingPacing(const QuicSentPacketManager* sent_packet_manager);
-
-  static bool HasRetransmittableFrames(
-      QuicSentPacketManager* sent_packet_manager,
-      uint64_t packet_number);
-
-  static QuicUnackedPacketMap* GetUnackedPacketMap(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static void DisablePacerBursts(QuicSentPacketManager* sent_packet_manager);
-
-  static int GetPacerInitialBurstSize(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static void SetNextPacedPacketTime(QuicSentPacketManager* sent_packet_manager,
-                                     QuicTime time);
-
-  static int GetReorderingShift(QuicSentPacketManager* sent_packet_manager);
-
-  static bool AdaptiveReorderingThresholdEnabled(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static bool AdaptiveTimeThresholdEnabled(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static bool UsePacketThresholdForRuntPackets(
-      QuicSentPacketManager* sent_packet_manager);
-
-  static int GetNumPtosForPathDegrading(
-      QuicSentPacketManager* sent_packet_manager);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
diff --git a/quic/test_tools/quic_server_peer.cc b/quic/test_tools/quic_server_peer.cc
deleted file mode 100644
index 925f851..0000000
--- a/quic/test_tools/quic_server_peer.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_server_peer.h"
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-namespace test {
-
-// static
-bool QuicServerPeer::SetSmallSocket(QuicServer* server) {
-  int size = 1024 * 10;
-  return setsockopt(server->fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) !=
-         -1;
-}
-
-// static
-QuicDispatcher* QuicServerPeer::GetDispatcher(QuicServer* server) {
-  return server->dispatcher_.get();
-}
-
-// static
-void QuicServerPeer::SetReader(QuicServer* server, QuicPacketReader* reader) {
-  server->packet_reader_.reset(reader);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_server_session_base_peer.h b/quic/test_tools/quic_server_session_base_peer.h
deleted file mode 100644
index d644c82..0000000
--- a/quic/test_tools/quic_server_session_base_peer.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
-
-#include "quic/core/http/quic_server_session_base.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-namespace test {
-
-class QuicServerSessionBasePeer {
- public:
-  static QuicStream* GetOrCreateStream(QuicServerSessionBase* s,
-                                       QuicStreamId id) {
-    return s->GetOrCreateStream(id);
-  }
-  static void SetCryptoStream(QuicServerSessionBase* s,
-                              QuicCryptoServerStreamBase* crypto_stream) {
-    s->crypto_stream_.reset(crypto_stream);
-  }
-  static bool IsBandwidthResumptionEnabled(QuicServerSessionBase* s) {
-    return s->bandwidth_resumption_enabled_;
-  }
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
diff --git a/quic/test_tools/quic_session_peer.cc b/quic/test_tools/quic_session_peer.cc
deleted file mode 100644
index e734a79..0000000
--- a/quic/test_tools/quic_session_peer.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_session_peer.h"
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicStreamId QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(
-    QuicSession* session) {
-  return session->GetNextOutgoingBidirectionalStreamId();
-}
-
-// static
-QuicStreamId QuicSessionPeer::GetNextOutgoingUnidirectionalStreamId(
-    QuicSession* session) {
-  return session->GetNextOutgoingUnidirectionalStreamId();
-}
-
-// static
-void QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(QuicSession* session,
-                                                           QuicStreamId id) {
-  if (VersionHasIetfQuicFrames(session->transport_version())) {
-    session->ietf_streamid_manager_.bidirectional_stream_id_manager_
-        .next_outgoing_stream_id_ = id;
-    return;
-  }
-  session->stream_id_manager_.next_outgoing_stream_id_ = id;
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenIncomingStreams(QuicSession* session,
-                                                uint32_t max_streams) {
-  if (VersionHasIetfQuicFrames(session->transport_version())) {
-    QUIC_BUG(quic_bug_10193_1)
-        << "SetmaxOpenIncomingStreams deprecated for IETF QUIC";
-    session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
-        max_streams);
-    session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
-        max_streams);
-    return;
-  }
-  session->stream_id_manager_.set_max_open_incoming_streams(max_streams);
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
-    QuicSession* session,
-    uint32_t max_streams) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
-      << "SetmaxOpenIncomingBidirectionalStreams not supported for Google "
-         "QUIC";
-  session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
-      max_streams);
-}
-// static
-void QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
-    QuicSession* session,
-    uint32_t max_streams) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
-      << "SetmaxOpenIncomingUnidirectionalStreams not supported for Google "
-         "QUIC";
-  session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
-      max_streams);
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenOutgoingStreams(QuicSession* session,
-                                                uint32_t max_streams) {
-  if (VersionHasIetfQuicFrames(session->transport_version())) {
-    QUIC_BUG(quic_bug_10193_2)
-        << "SetmaxOpenOutgoingStreams deprecated for IETF QUIC";
-    return;
-  }
-  session->stream_id_manager_.set_max_open_outgoing_streams(max_streams);
-}
-
-// static
-void QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(
-    QuicSession* session,
-    uint32_t max_streams) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
-      << "SetmaxOpenOutgoingBidirectionalStreams not supported for Google "
-         "QUIC";
-  session->ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
-      max_streams);
-}
-// static
-void QuicSessionPeer::SetMaxOpenOutgoingUnidirectionalStreams(
-    QuicSession* session,
-    uint32_t max_streams) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
-      << "SetmaxOpenOutgoingUnidirectionalStreams not supported for Google "
-         "QUIC";
-  session->ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
-      max_streams);
-}
-
-// static
-QuicCryptoStream* QuicSessionPeer::GetMutableCryptoStream(
-    QuicSession* session) {
-  return session->GetMutableCryptoStream();
-}
-
-// static
-QuicWriteBlockedList* QuicSessionPeer::GetWriteBlockedStreams(
-    QuicSession* session) {
-  return &session->write_blocked_streams_;
-}
-
-// static
-QuicStream* QuicSessionPeer::GetOrCreateStream(QuicSession* session,
-                                               QuicStreamId stream_id) {
-  return session->GetOrCreateStream(stream_id);
-}
-
-// static
-absl::flat_hash_map<QuicStreamId, QuicStreamOffset>&
-QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(QuicSession* session) {
-  return session->locally_closed_streams_highest_offset_;
-}
-
-// static
-QuicSession::StreamMap& QuicSessionPeer::stream_map(QuicSession* session) {
-  return session->stream_map_;
-}
-
-// static
-const QuicSession::ClosedStreams& QuicSessionPeer::closed_streams(
-    QuicSession* session) {
-  return *session->closed_streams();
-}
-
-// static
-void QuicSessionPeer::ActivateStream(QuicSession* session,
-                                     std::unique_ptr<QuicStream> stream) {
-  return session->ActivateStream(std::move(stream));
-}
-
-// static
-bool QuicSessionPeer::IsStreamClosed(QuicSession* session, QuicStreamId id) {
-  return session->IsClosedStream(id);
-}
-
-// static
-bool QuicSessionPeer::IsStreamCreated(QuicSession* session, QuicStreamId id) {
-  return session->stream_map_.contains(id);
-}
-
-// static
-bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) {
-  if (VersionHasIetfQuicFrames(session->transport_version())) {
-    if (id % QuicUtils::StreamIdDelta(session->transport_version()) < 2) {
-      return session->ietf_streamid_manager_.bidirectional_stream_id_manager_
-          .available_streams_.contains(id);
-    }
-    return session->ietf_streamid_manager_.unidirectional_stream_id_manager_
-        .available_streams_.contains(id);
-  }
-  return session->stream_id_manager_.available_streams_.contains(id);
-}
-
-// static
-QuicStream* QuicSessionPeer::GetStream(QuicSession* session, QuicStreamId id) {
-  return session->GetStream(id);
-}
-
-// static
-bool QuicSessionPeer::IsStreamWriteBlocked(QuicSession* session,
-                                           QuicStreamId id) {
-  return session->write_blocked_streams_.IsStreamBlocked(id);
-}
-
-// static
-QuicAlarm* QuicSessionPeer::GetCleanUpClosedStreamsAlarm(QuicSession* session) {
-  return session->closed_streams_clean_up_alarm_.get();
-}
-
-// static
-LegacyQuicStreamIdManager* QuicSessionPeer::GetStreamIdManager(
-    QuicSession* session) {
-  return &session->stream_id_manager_;
-}
-
-// static
-UberQuicStreamIdManager* QuicSessionPeer::ietf_streamid_manager(
-    QuicSession* session) {
-  return &session->ietf_streamid_manager_;
-}
-
-// static
-QuicStreamIdManager* QuicSessionPeer::ietf_bidirectional_stream_id_manager(
-    QuicSession* session) {
-  return &session->ietf_streamid_manager_.bidirectional_stream_id_manager_;
-}
-
-// static
-QuicStreamIdManager* QuicSessionPeer::ietf_unidirectional_stream_id_manager(
-    QuicSession* session) {
-  return &session->ietf_streamid_manager_.unidirectional_stream_id_manager_;
-}
-
-// static
-PendingStream* QuicSessionPeer::GetPendingStream(QuicSession* session,
-                                                 QuicStreamId stream_id) {
-  auto it = session->pending_stream_map_.find(stream_id);
-  return it == session->pending_stream_map_.end() ? nullptr : it->second.get();
-}
-
-// static
-void QuicSessionPeer::set_is_configured(QuicSession* session, bool value) {
-  session->is_configured_ = value;
-}
-
-// static
-void QuicSessionPeer::SetPerspective(QuicSession* session,
-                                     Perspective perspective) {
-  session->perspective_ = perspective;
-}
-
-// static
-size_t QuicSessionPeer::GetNumOpenDynamicStreams(QuicSession* session) {
-  size_t result = 0;
-  for (const auto& it : session->stream_map_) {
-    if (!it.second->is_static()) {
-      ++result;
-    }
-  }
-  // Exclude draining streams.
-  result -= session->num_draining_streams_;
-  // Add locally closed streams.
-  result += session->locally_closed_streams_highest_offset_.size();
-
-  return result;
-}
-
-// static
-size_t QuicSessionPeer::GetNumDrainingStreams(QuicSession* session) {
-  return session->num_draining_streams_;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_session_peer.h b/quic/test_tools/quic_session_peer.h
deleted file mode 100644
index 94f0bf5..0000000
--- a/quic/test_tools/quic_session_peer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
-
-#include <cstdint>
-#include <map>
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_session.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-class QuicCryptoStream;
-class QuicSession;
-class QuicStream;
-
-namespace test {
-
-class QuicSessionPeer {
- public:
-  QuicSessionPeer() = delete;
-
-  static QuicStreamId GetNextOutgoingBidirectionalStreamId(
-      QuicSession* session);
-  static QuicStreamId GetNextOutgoingUnidirectionalStreamId(
-      QuicSession* session);
-  static void SetNextOutgoingBidirectionalStreamId(QuicSession* session,
-                                                   QuicStreamId id);
-  // Following is only for Google-QUIC, will QUIC_BUG if called for IETF
-  // QUIC.
-  static void SetMaxOpenIncomingStreams(QuicSession* session,
-                                        uint32_t max_streams);
-  // Following two are only for IETF-QUIC, will QUIC_BUG if called for Google
-  // QUIC.
-  static void SetMaxOpenIncomingBidirectionalStreams(QuicSession* session,
-                                                     uint32_t max_streams);
-  static void SetMaxOpenIncomingUnidirectionalStreams(QuicSession* session,
-                                                      uint32_t max_streams);
-
-  static void SetMaxOpenOutgoingStreams(QuicSession* session,
-                                        uint32_t max_streams);
-  static void SetMaxOpenOutgoingBidirectionalStreams(QuicSession* session,
-                                                     uint32_t max_streams);
-  static void SetMaxOpenOutgoingUnidirectionalStreams(QuicSession* session,
-                                                      uint32_t max_streams);
-
-  static QuicCryptoStream* GetMutableCryptoStream(QuicSession* session);
-  static QuicWriteBlockedList* GetWriteBlockedStreams(QuicSession* session);
-  static QuicStream* GetOrCreateStream(QuicSession* session,
-                                       QuicStreamId stream_id);
-  static absl::flat_hash_map<QuicStreamId, QuicStreamOffset>&
-  GetLocallyClosedStreamsHighestOffset(QuicSession* session);
-  static QuicSession::StreamMap& stream_map(QuicSession* session);
-  static const QuicSession::ClosedStreams& closed_streams(QuicSession* session);
-  static void ActivateStream(QuicSession* session,
-                             std::unique_ptr<QuicStream> stream);
-
-  // Discern the state of a stream.  Exactly one of these should be true at a
-  // time for any stream id > 0 (other than the special streams 1 and 3).
-  static bool IsStreamClosed(QuicSession* session, QuicStreamId id);
-  static bool IsStreamCreated(QuicSession* session, QuicStreamId id);
-  static bool IsStreamAvailable(QuicSession* session, QuicStreamId id);
-
-  static QuicStream* GetStream(QuicSession* session, QuicStreamId id);
-  static bool IsStreamWriteBlocked(QuicSession* session, QuicStreamId id);
-  static QuicAlarm* GetCleanUpClosedStreamsAlarm(QuicSession* session);
-  static LegacyQuicStreamIdManager* GetStreamIdManager(QuicSession* session);
-  static UberQuicStreamIdManager* ietf_streamid_manager(QuicSession* session);
-  static QuicStreamIdManager* ietf_bidirectional_stream_id_manager(
-      QuicSession* session);
-  static QuicStreamIdManager* ietf_unidirectional_stream_id_manager(
-      QuicSession* session);
-  static PendingStream* GetPendingStream(QuicSession* session,
-                                         QuicStreamId stream_id);
-  static void set_is_configured(QuicSession* session, bool value);
-  static void SetPerspective(QuicSession* session, Perspective perspective);
-  static size_t GetNumOpenDynamicStreams(QuicSession* session);
-  static size_t GetNumDrainingStreams(QuicSession* session);
-  static QuicStreamId GetLargestPeerCreatedStreamId(QuicSession* session,
-                                                    bool unidirectional) {
-    return session->GetLargestPeerCreatedStreamId(unidirectional);
-  }
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
diff --git a/quic/test_tools/quic_spdy_session_peer.cc b/quic/test_tools/quic_spdy_session_peer.cc
deleted file mode 100644
index cf14ab3..0000000
--- a/quic/test_tools/quic_spdy_session_peer.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_spdy_session_peer.h"
-
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/qpack/qpack_receive_stream.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicHeadersStream* QuicSpdySessionPeer::GetHeadersStream(
-    QuicSpdySession* session) {
-  QUICHE_DCHECK(!VersionUsesHttp3(session->transport_version()));
-  return session->headers_stream();
-}
-
-void QuicSpdySessionPeer::SetHeadersStream(QuicSpdySession* session,
-                                           QuicHeadersStream* headers_stream) {
-  QUICHE_DCHECK(!VersionUsesHttp3(session->transport_version()));
-  for (auto& it : QuicSessionPeer::stream_map(session)) {
-    if (it.first ==
-        QuicUtils::GetHeadersStreamId(session->transport_version())) {
-      it.second.reset(headers_stream);
-      session->headers_stream_ = static_cast<QuicHeadersStream*>(it.second.get());
-      break;
-    }
-  }
-}
-
-// static
-spdy::SpdyFramer* QuicSpdySessionPeer::GetSpdyFramer(QuicSpdySession* session) {
-  return &session->spdy_framer_;
-}
-
-void QuicSpdySessionPeer::SetMaxInboundHeaderListSize(
-    QuicSpdySession* session, size_t max_inbound_header_size) {
-  session->set_max_inbound_header_list_size(max_inbound_header_size);
-}
-
-// static
-size_t QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
-    QuicSpdySession* session, QuicStreamId id, spdy::SpdyHeaderBlock headers,
-    bool fin, const spdy::SpdyStreamPrecedence& precedence,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  return session->WriteHeadersOnHeadersStream(
-      id, std::move(headers), fin, precedence, std::move(ack_listener));
-}
-
-// static
-QuicStreamId QuicSpdySessionPeer::GetNextOutgoingUnidirectionalStreamId(
-    QuicSpdySession* session) {
-  return session->GetNextOutgoingUnidirectionalStreamId();
-}
-
-// static
-QuicReceiveControlStream* QuicSpdySessionPeer::GetReceiveControlStream(
-    QuicSpdySession* session) {
-  return session->receive_control_stream_;
-}
-
-// static
-QuicSendControlStream* QuicSpdySessionPeer::GetSendControlStream(
-    QuicSpdySession* session) {
-  return session->send_control_stream_;
-}
-
-// static
-QpackSendStream* QuicSpdySessionPeer::GetQpackDecoderSendStream(
-    QuicSpdySession* session) {
-  return session->qpack_decoder_send_stream_;
-}
-
-// static
-QpackSendStream* QuicSpdySessionPeer::GetQpackEncoderSendStream(
-    QuicSpdySession* session) {
-  return session->qpack_encoder_send_stream_;
-}
-
-// static
-QpackReceiveStream* QuicSpdySessionPeer::GetQpackDecoderReceiveStream(
-    QuicSpdySession* session) {
-  return session->qpack_decoder_receive_stream_;
-}
-
-// static
-QpackReceiveStream* QuicSpdySessionPeer::GetQpackEncoderReceiveStream(
-    QuicSpdySession* session) {
-  return session->qpack_encoder_receive_stream_;
-}
-
-// static
-void QuicSpdySessionPeer::SetHttpDatagramSupport(
-    QuicSpdySession* session, HttpDatagramSupport http_datagram_support) {
-  session->http_datagram_support_ = http_datagram_support;
-}
-
-// static
-HttpDatagramSupport QuicSpdySessionPeer::LocalHttpDatagramSupport(
-    QuicSpdySession* session) {
-  return session->LocalHttpDatagramSupport();
-}
-
-// static
-void QuicSpdySessionPeer::EnableWebTransport(QuicSpdySession* session) {
-  QUICHE_DCHECK(session->WillNegotiateWebTransport());
-  SetHttpDatagramSupport(session, HttpDatagramSupport::kDraft04);
-  session->peer_supports_webtransport_ = true;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_spdy_session_peer.h b/quic/test_tools/quic_spdy_session_peer.h
deleted file mode 100644
index df65fc3..0000000
--- a/quic/test_tools/quic_spdy_session_peer.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
-
-#include "quic/core/http/quic_receive_control_stream.h"
-#include "quic/core/http/quic_send_control_stream.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/qpack/qpack_receive_stream.h"
-#include "quic/core/qpack/qpack_send_stream.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_write_blocked_list.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-class QuicHeadersStream;
-
-namespace test {
-
-class QuicSpdySessionPeer {
- public:
-  QuicSpdySessionPeer() = delete;
-
-  static QuicHeadersStream* GetHeadersStream(QuicSpdySession* session);
-  static void SetHeadersStream(QuicSpdySession* session,
-                               QuicHeadersStream* headers_stream);
-  static spdy::SpdyFramer* GetSpdyFramer(QuicSpdySession* session);
-  // Must be called before Initialize().
-  static void SetMaxInboundHeaderListSize(QuicSpdySession* session,
-                                          size_t max_inbound_header_size);
-  static size_t WriteHeadersOnHeadersStream(
-      QuicSpdySession* session, QuicStreamId id, spdy::SpdyHeaderBlock headers,
-      bool fin, const spdy::SpdyStreamPrecedence& precedence,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-  // |session| can't be nullptr.
-  static QuicStreamId GetNextOutgoingUnidirectionalStreamId(
-      QuicSpdySession* session);
-  static QuicReceiveControlStream* GetReceiveControlStream(
-      QuicSpdySession* session);
-  static QuicSendControlStream* GetSendControlStream(QuicSpdySession* session);
-  static QpackSendStream* GetQpackDecoderSendStream(QuicSpdySession* session);
-  static QpackSendStream* GetQpackEncoderSendStream(QuicSpdySession* session);
-  static QpackReceiveStream* GetQpackDecoderReceiveStream(
-      QuicSpdySession* session);
-  static QpackReceiveStream* GetQpackEncoderReceiveStream(
-      QuicSpdySession* session);
-  static void SetHttpDatagramSupport(QuicSpdySession* session,
-                                     HttpDatagramSupport http_datagram_support);
-  static HttpDatagramSupport LocalHttpDatagramSupport(QuicSpdySession* session);
-  static void EnableWebTransport(QuicSpdySession* session);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
diff --git a/quic/test_tools/quic_spdy_stream_peer.cc b/quic/test_tools/quic_spdy_stream_peer.cc
deleted file mode 100644
index f55e60a..0000000
--- a/quic/test_tools/quic_spdy_stream_peer.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicSpdyStreamPeer::set_ack_listener(
-    QuicSpdyStream* stream,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  stream->set_ack_listener(std::move(ack_listener));
-}
-
-// static
-const QuicIntervalSet<QuicStreamOffset>&
-QuicSpdyStreamPeer::unacked_frame_headers_offsets(QuicSpdyStream* stream) {
-  return stream->unacked_frame_headers_offsets_;
-}
-
-// static
-bool QuicSpdyStreamPeer::use_datagram_contexts(QuicSpdyStream* stream) {
-  return stream->use_datagram_contexts_;
-}
-
-// static
-bool QuicSpdyStreamPeer::OnHeadersFrameEnd(QuicSpdyStream* stream) {
-  return stream->OnHeadersFrameEnd();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_spdy_stream_peer.h b/quic/test_tools/quic_spdy_stream_peer.h
deleted file mode 100644
index 10bb4a6..0000000
--- a/quic/test_tools/quic_spdy_stream_peer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
-
-#include "quic/core/quic_ack_listener_interface.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-class QpackDecodedHeadersAccumulator;
-class QuicSpdyStream;
-
-namespace test {
-
-class QuicSpdyStreamPeer {
- public:
-  static void set_ack_listener(
-      QuicSpdyStream* stream,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-  static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets(
-      QuicSpdyStream* stream);
-  static bool use_datagram_contexts(QuicSpdyStream* stream);
-  static bool OnHeadersFrameEnd(QuicSpdyStream* stream);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
diff --git a/quic/test_tools/quic_stream_id_manager_peer.cc b/quic/test_tools/quic_stream_id_manager_peer.cc
deleted file mode 100644
index c8662a1..0000000
--- a/quic/test_tools/quic_stream_id_manager_peer.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "quic/test_tools/quic_stream_id_manager_peer.h"
-
-#include "quic/core/quic_stream_id_manager.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/uber_quic_stream_id_manager.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicStreamIdManagerPeer::set_incoming_actual_max_streams(
-    QuicStreamIdManager* stream_id_manager,
-    QuicStreamCount count) {
-  stream_id_manager->incoming_actual_max_streams_ = count;
-}
-
-// static
-void QuicStreamIdManagerPeer::set_outgoing_max_streams(
-    QuicStreamIdManager* stream_id_manager,
-    QuicStreamCount count) {
-  stream_id_manager->outgoing_max_streams_ = count;
-}
-
-// static
-QuicStreamId QuicStreamIdManagerPeer::GetFirstIncomingStreamId(
-    QuicStreamIdManager* stream_id_manager) {
-  return stream_id_manager->GetFirstIncomingStreamId();
-}
-
-// static
-bool QuicStreamIdManagerPeer::get_unidirectional(
-    QuicStreamIdManager* stream_id_manager) {
-  return stream_id_manager->unidirectional_;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_stream_id_manager_peer.h b/quic/test_tools/quic_stream_id_manager_peer.h
deleted file mode 100644
index 7c7359f..0000000
--- a/quic/test_tools/quic_stream_id_manager_peer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_ID_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_ID_MANAGER_PEER_H_
-
-#include <stddef.h>
-
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicStreamIdManager;
-class UberQuicStreamIdManager;
-
-namespace test {
-
-class QuicStreamIdManagerPeer {
- public:
-  QuicStreamIdManagerPeer() = delete;
-
-  static void set_incoming_actual_max_streams(
-      QuicStreamIdManager* stream_id_manager,
-      QuicStreamCount count);
-  static void set_outgoing_max_streams(QuicStreamIdManager* stream_id_manager,
-                                       QuicStreamCount count);
-
-  static QuicStreamId GetFirstIncomingStreamId(
-      QuicStreamIdManager* stream_id_manager);
-
-  static bool get_unidirectional(QuicStreamIdManager* stream_id_manager);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
diff --git a/quic/test_tools/quic_stream_peer.cc b/quic/test_tools/quic_stream_peer.cc
deleted file mode 100644
index c596d79..0000000
--- a/quic/test_tools/quic_stream_peer.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_peer.h"
-
-#include <list>
-
-#include "quic/core/quic_stream.h"
-#include "quic/core/quic_types.h"
-#include "quic/test_tools/quic_flow_controller_peer.h"
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicStreamPeer::SetWriteSideClosed(bool value, QuicStream* stream) {
-  stream->write_side_closed_ = value;
-}
-
-// static
-void QuicStreamPeer::SetStreamBytesWritten(
-    QuicStreamOffset stream_bytes_written,
-    QuicStream* stream) {
-  stream->send_buffer_.stream_bytes_written_ = stream_bytes_written;
-  stream->send_buffer_.stream_bytes_outstanding_ = stream_bytes_written;
-  QuicStreamSendBufferPeer::SetStreamOffset(&stream->send_buffer_,
-                                            stream_bytes_written);
-}
-
-// static
-void QuicStreamPeer::SetSendWindowOffset(QuicStream* stream,
-                                         QuicStreamOffset offset) {
-  QuicFlowControllerPeer::SetSendWindowOffset(&*stream->flow_controller_,
-                                              offset);
-}
-
-// static
-QuicByteCount QuicStreamPeer::bytes_consumed(QuicStream* stream) {
-  return stream->flow_controller_->bytes_consumed();
-}
-
-// static
-void QuicStreamPeer::SetReceiveWindowOffset(QuicStream* stream,
-                                            QuicStreamOffset offset) {
-  QuicFlowControllerPeer::SetReceiveWindowOffset(&*stream->flow_controller_,
-                                                 offset);
-}
-
-// static
-void QuicStreamPeer::SetMaxReceiveWindow(QuicStream* stream,
-                                         QuicStreamOffset size) {
-  QuicFlowControllerPeer::SetMaxReceiveWindow(&*stream->flow_controller_, size);
-}
-
-// static
-QuicByteCount QuicStreamPeer::SendWindowSize(QuicStream* stream) {
-  return stream->flow_controller_->SendWindowSize();
-}
-
-// static
-QuicStreamOffset QuicStreamPeer::ReceiveWindowOffset(QuicStream* stream) {
-  return QuicFlowControllerPeer::ReceiveWindowOffset(
-      &*stream->flow_controller_);
-}
-
-// static
-QuicByteCount QuicStreamPeer::ReceiveWindowSize(QuicStream* stream) {
-  return QuicFlowControllerPeer::ReceiveWindowSize(&*stream->flow_controller_);
-}
-
-// static
-QuicStreamOffset QuicStreamPeer::SendWindowOffset(QuicStream* stream) {
-  return stream->flow_controller_->send_window_offset();
-}
-
-// static
-bool QuicStreamPeer::read_side_closed(QuicStream* stream) {
-  return stream->read_side_closed_;
-}
-
-// static
-void QuicStreamPeer::CloseReadSide(QuicStream* stream) {
-  stream->CloseReadSide();
-}
-
-// static
-bool QuicStreamPeer::StreamContributesToConnectionFlowControl(
-    QuicStream* stream) {
-  return stream->stream_contributes_to_connection_flow_control_;
-}
-
-// static
-QuicStreamSequencer* QuicStreamPeer::sequencer(QuicStream* stream) {
-  return &(stream->sequencer_);
-}
-
-// static
-QuicSession* QuicStreamPeer::session(QuicStream* stream) {
-  return stream->session();
-}
-
-// static
-QuicStreamSendBuffer& QuicStreamPeer::SendBuffer(QuicStream* stream) {
-  return stream->send_buffer_;
-}
-
-// static
-void QuicStreamPeer::SetFinReceived(QuicStream* stream) {
-  stream->fin_received_ = true;
-}
-
-// static
-void QuicStreamPeer::SetFinSent(QuicStream* stream) {
-  stream->fin_sent_ = true;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_stream_peer.h b/quic/test_tools/quic_stream_peer.h
deleted file mode 100644
index 963570c..0000000
--- a/quic/test_tools/quic_stream_peer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-
-class QuicStream;
-class QuicSession;
-
-namespace test {
-
-class QuicStreamPeer {
- public:
-  QuicStreamPeer() = delete;
-
-  static void SetWriteSideClosed(bool value, QuicStream* stream);
-  static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written,
-                                    QuicStream* stream);
-  static void SetSendWindowOffset(QuicStream* stream, QuicStreamOffset offset);
-  static void SetReceiveWindowOffset(QuicStream* stream,
-                                     QuicStreamOffset offset);
-  static void SetMaxReceiveWindow(QuicStream* stream, QuicStreamOffset size);
-  static bool read_side_closed(QuicStream* stream);
-  static void CloseReadSide(QuicStream* stream);
-  static QuicByteCount bytes_consumed(QuicStream* stream);
-  static QuicByteCount ReceiveWindowSize(QuicStream* stream);
-  static QuicByteCount SendWindowSize(QuicStream* stream);
-  static QuicStreamOffset SendWindowOffset(QuicStream* stream);
-  static QuicStreamOffset ReceiveWindowOffset(QuicStream* stream);
-
-  static bool StreamContributesToConnectionFlowControl(QuicStream* stream);
-
-  static QuicStreamSequencer* sequencer(QuicStream* stream);
-  static QuicSession* session(QuicStream* stream);
-  static void SetFinReceived(QuicStream* stream);
-  static void SetFinSent(QuicStream* stream);
-
-  static QuicStreamSendBuffer& SendBuffer(QuicStream* stream);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
diff --git a/quic/test_tools/quic_stream_send_buffer_peer.cc b/quic/test_tools/quic_stream_send_buffer_peer.cc
deleted file mode 100644
index 528ff16..0000000
--- a/quic/test_tools/quic_stream_send_buffer_peer.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_send_buffer_peer.h"
-#include "quic/test_tools/quic_interval_deque_peer.h"
-
-namespace quic {
-
-namespace test {
-
-// static
-void QuicStreamSendBufferPeer::SetStreamOffset(
-    QuicStreamSendBuffer* send_buffer,
-    QuicStreamOffset stream_offset) {
-  send_buffer->stream_offset_ = stream_offset;
-}
-
-// static
-const BufferedSlice* QuicStreamSendBufferPeer::CurrentWriteSlice(
-    QuicStreamSendBuffer* send_buffer) {
-  auto wi = write_index(send_buffer);
-
-  if (wi == -1) {
-    return nullptr;
-  }
-  return QuicIntervalDequePeer::GetItem(&send_buffer->interval_deque_, wi);
-}
-
-QuicStreamOffset QuicStreamSendBufferPeer::EndOffset(
-    QuicStreamSendBuffer* send_buffer) {
-  return send_buffer->current_end_offset_;
-}
-
-// static
-QuicByteCount QuicStreamSendBufferPeer::TotalLength(
-    QuicStreamSendBuffer* send_buffer) {
-  QuicByteCount length = 0;
-  for (auto slice = send_buffer->interval_deque_.DataBegin();
-       slice != send_buffer->interval_deque_.DataEnd(); ++slice) {
-    length += slice->slice.length();
-  }
-  return length;
-}
-
-// static
-int32_t QuicStreamSendBufferPeer::write_index(
-    QuicStreamSendBuffer* send_buffer) {
-  return QuicIntervalDequePeer::GetCachedIndex(&send_buffer->interval_deque_);
-}
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/test_tools/quic_stream_send_buffer_peer.h b/quic/test_tools/quic_stream_send_buffer_peer.h
deleted file mode 100644
index 0f234c0..0000000
--- a/quic/test_tools/quic_stream_send_buffer_peer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
-
-#include "quic/core/quic_stream_send_buffer.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicStreamSendBufferPeer {
- public:
-  static void SetStreamOffset(QuicStreamSendBuffer* send_buffer,
-                              QuicStreamOffset stream_offset);
-
-  static const BufferedSlice* CurrentWriteSlice(
-      QuicStreamSendBuffer* send_buffer);
-
-  static QuicStreamOffset EndOffset(QuicStreamSendBuffer* send_buffer);
-
-  static QuicByteCount TotalLength(QuicStreamSendBuffer* send_buffer);
-
-  static int32_t write_index(QuicStreamSendBuffer* send_buffer);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
diff --git a/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
deleted file mode 100644
index a950f0b..0000000
--- a/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
-#include <cstddef>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-using BufferBlock = quic::QuicStreamSequencerBuffer::BufferBlock;
-
-static const size_t kBlockSizeBytes =
-    quic::QuicStreamSequencerBuffer::kBlockSizeBytes;
-
-namespace quic {
-namespace test {
-
-QuicStreamSequencerBufferPeer::QuicStreamSequencerBufferPeer(
-    QuicStreamSequencerBuffer* buffer)
-    : buffer_(buffer) {}
-
-// Read from this buffer_ into the given destination buffer_ up to the
-// size of the destination. Returns the number of bytes read. Reading from
-// an empty buffer_->returns 0.
-size_t QuicStreamSequencerBufferPeer::Read(char* dest_buffer, size_t size) {
-  iovec dest;
-  dest.iov_base = dest_buffer, dest.iov_len = size;
-  size_t bytes_read;
-  std::string error_details;
-  EXPECT_THAT(buffer_->Readv(&dest, 1, &bytes_read, &error_details),
-              IsQuicNoError());
-  return bytes_read;
-}
-
-// If buffer is empty, the blocks_ array must be empty, which means all
-// blocks are deallocated.
-bool QuicStreamSequencerBufferPeer::CheckEmptyInvariants() {
-  return !buffer_->Empty() || IsBlockArrayEmpty();
-}
-
-bool QuicStreamSequencerBufferPeer::IsBlockArrayEmpty() {
-  if (buffer_->blocks_ == nullptr) {
-    return true;
-  }
-
-  size_t count = current_blocks_count();
-  for (size_t i = 0; i < count; i++) {
-    if (buffer_->blocks_[i] != nullptr) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool QuicStreamSequencerBufferPeer::CheckInitialState() {
-  EXPECT_TRUE(buffer_->Empty() && buffer_->total_bytes_read_ == 0 &&
-              buffer_->num_bytes_buffered_ == 0);
-  return CheckBufferInvariants();
-}
-
-bool QuicStreamSequencerBufferPeer::CheckBufferInvariants() {
-  QuicStreamOffset data_span =
-      buffer_->NextExpectedByte() - buffer_->total_bytes_read_;
-  bool capacity_sane = data_span <= buffer_->max_buffer_capacity_bytes_ &&
-                       data_span >= buffer_->num_bytes_buffered_;
-  if (!capacity_sane) {
-    QUIC_LOG(ERROR) << "data span is larger than capacity.";
-    QUIC_LOG(ERROR) << "total read: " << buffer_->total_bytes_read_
-                    << " last byte: " << buffer_->NextExpectedByte();
-  }
-  bool total_read_sane =
-      buffer_->FirstMissingByte() >= buffer_->total_bytes_read_;
-  if (!total_read_sane) {
-    QUIC_LOG(ERROR) << "read across 1st gap.";
-  }
-  bool read_offset_sane = buffer_->ReadOffset() < kBlockSizeBytes;
-  if (!capacity_sane) {
-    QUIC_LOG(ERROR) << "read offset go beyond 1st block";
-  }
-  bool block_match_capacity =
-      (buffer_->max_buffer_capacity_bytes_ <=
-       buffer_->max_blocks_count_ * kBlockSizeBytes) &&
-      (buffer_->max_buffer_capacity_bytes_ >
-       (buffer_->max_blocks_count_ - 1) * kBlockSizeBytes);
-  if (!capacity_sane) {
-    QUIC_LOG(ERROR) << "block number not match capcaity.";
-  }
-  bool block_retired_when_empty = CheckEmptyInvariants();
-  if (!block_retired_when_empty) {
-    QUIC_LOG(ERROR) << "block is not retired after use.";
-  }
-  return capacity_sane && total_read_sane && read_offset_sane &&
-         block_match_capacity && block_retired_when_empty;
-}
-
-size_t QuicStreamSequencerBufferPeer::GetInBlockOffset(
-    QuicStreamOffset offset) {
-  return buffer_->GetInBlockOffset(offset);
-}
-
-BufferBlock* QuicStreamSequencerBufferPeer::GetBlock(size_t index) {
-  return buffer_->blocks_[index];
-}
-
-int QuicStreamSequencerBufferPeer::IntervalSize() {
-  if (buffer_->bytes_received_.Empty()) {
-    return 1;
-  }
-  int gap_size = buffer_->bytes_received_.Size() + 1;
-  if (buffer_->bytes_received_.Empty()) {
-    return gap_size;
-  }
-  if (buffer_->bytes_received_.begin()->min() == 0) {
-    --gap_size;
-  }
-  if (buffer_->bytes_received_.rbegin()->max() ==
-      std::numeric_limits<uint64_t>::max()) {
-    --gap_size;
-  }
-  return gap_size;
-}
-
-size_t QuicStreamSequencerBufferPeer::max_buffer_capacity() {
-  return buffer_->max_buffer_capacity_bytes_;
-}
-
-size_t QuicStreamSequencerBufferPeer::ReadableBytes() {
-  return buffer_->ReadableBytes();
-}
-
-void QuicStreamSequencerBufferPeer::set_total_bytes_read(
-    QuicStreamOffset total_bytes_read) {
-  buffer_->total_bytes_read_ = total_bytes_read;
-}
-
-void QuicStreamSequencerBufferPeer::AddBytesReceived(QuicStreamOffset offset,
-                                                     QuicByteCount length) {
-  buffer_->bytes_received_.Add(offset, offset + length);
-}
-
-bool QuicStreamSequencerBufferPeer::IsBufferAllocated() {
-  return buffer_->blocks_ != nullptr;
-}
-
-size_t QuicStreamSequencerBufferPeer::max_blocks_count() {
-  return buffer_->max_blocks_count_;
-}
-
-size_t QuicStreamSequencerBufferPeer::current_blocks_count() {
-  return buffer_->current_blocks_count_;
-}
-
-const QuicIntervalSet<QuicStreamOffset>&
-QuicStreamSequencerBufferPeer::bytes_received() {
-  return buffer_->bytes_received_;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/quic/test_tools/quic_stream_sequencer_buffer_peer.h
deleted file mode 100644
index b07f1f5..0000000
--- a/quic/test_tools/quic_stream_sequencer_buffer_peer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
-
-#include "quic/core/quic_stream_sequencer_buffer.h"
-
-namespace quic {
-
-namespace test {
-
-class QuicStreamSequencerBufferPeer {
- public:
-  explicit QuicStreamSequencerBufferPeer(QuicStreamSequencerBuffer* buffer);
-  QuicStreamSequencerBufferPeer(const QuicStreamSequencerBufferPeer&) = delete;
-  QuicStreamSequencerBufferPeer& operator=(
-      const QuicStreamSequencerBufferPeer&) = delete;
-
-  // Read from this buffer_ into the given destination buffer_ up to the
-  // size of the destination. Returns the number of bytes read. Reading from
-  // an empty buffer_->returns 0.
-  size_t Read(char* dest_buffer, size_t size);
-
-  // If buffer is empty, the blocks_ array must be empty, which means all
-  // blocks are deallocated.
-  bool CheckEmptyInvariants();
-
-  bool IsBlockArrayEmpty();
-
-  bool CheckInitialState();
-
-  bool CheckBufferInvariants();
-
-  size_t GetInBlockOffset(QuicStreamOffset offset);
-
-  QuicStreamSequencerBuffer::BufferBlock* GetBlock(size_t index);
-
-  int IntervalSize();
-
-  size_t max_buffer_capacity();
-
-  size_t ReadableBytes();
-
-  void set_total_bytes_read(QuicStreamOffset total_bytes_read);
-
-  void AddBytesReceived(QuicStreamOffset offset, QuicByteCount length);
-
-  bool IsBufferAllocated();
-
-  size_t max_blocks_count();
-
-  size_t current_blocks_count();
-
-  const QuicIntervalSet<QuicStreamOffset>& bytes_received();
-
- private:
-  QuicStreamSequencerBuffer* buffer_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
diff --git a/quic/test_tools/quic_stream_sequencer_peer.cc b/quic/test_tools/quic_stream_sequencer_peer.cc
deleted file mode 100644
index 497b290..0000000
--- a/quic/test_tools/quic_stream_sequencer_peer.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_stream_sequencer_peer.h"
-
-#include "quic/core/quic_stream_sequencer.h"
-#include "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-size_t QuicStreamSequencerPeer::GetNumBufferedBytes(
-    QuicStreamSequencer* sequencer) {
-  return sequencer->buffered_frames_.BytesBuffered();
-}
-
-// static
-QuicStreamOffset QuicStreamSequencerPeer::GetCloseOffset(
-    QuicStreamSequencer* sequencer) {
-  return sequencer->close_offset_;
-}
-
-// static
-bool QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(
-    QuicStreamSequencer* sequencer) {
-  QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
-  return buffer_peer.IsBufferAllocated();
-}
-
-// static
-void QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
-    QuicStreamSequencer* sequencer,
-    QuicStreamOffset total_bytes_read) {
-  QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
-  buffer_peer.set_total_bytes_read(total_bytes_read);
-}
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_stream_sequencer_peer.h b/quic/test_tools/quic_stream_sequencer_peer.h
deleted file mode 100644
index c36b77f..0000000
--- a/quic/test_tools/quic_stream_sequencer_peer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicStreamSequencer;
-
-namespace test {
-
-class QuicStreamSequencerPeer {
- public:
-  QuicStreamSequencerPeer() = delete;
-
-  static size_t GetNumBufferedBytes(QuicStreamSequencer* sequencer);
-
-  static QuicStreamOffset GetCloseOffset(QuicStreamSequencer* sequencer);
-
-  static bool IsUnderlyingBufferAllocated(QuicStreamSequencer* sequencer);
-
-  static void SetFrameBufferTotalBytesRead(QuicStreamSequencer* sequencer,
-                                           QuicStreamOffset total_bytes_read);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
diff --git a/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc b/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
deleted file mode 100644
index 86206c6..0000000
--- a/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_sustained_bandwidth_recorder.h"
-
-namespace quic {
-namespace test {
-
-// static
-void QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
-    QuicSustainedBandwidthRecorder* bandwidth_recorder,
-    int32_t bandwidth_estimate_kbytes_per_second) {
-  bandwidth_recorder->has_estimate_ = true;
-  bandwidth_recorder->bandwidth_estimate_ =
-      QuicBandwidth::FromKBytesPerSecond(bandwidth_estimate_kbytes_per_second);
-}
-
-// static
-void QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
-    QuicSustainedBandwidthRecorder* bandwidth_recorder,
-    int32_t max_bandwidth_estimate_kbytes_per_second,
-    int32_t max_bandwidth_timestamp) {
-  bandwidth_recorder->max_bandwidth_estimate_ =
-      QuicBandwidth::FromKBytesPerSecond(
-          max_bandwidth_estimate_kbytes_per_second);
-  bandwidth_recorder->max_bandwidth_timestamp_ = max_bandwidth_timestamp;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h b/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
deleted file mode 100644
index e128035..0000000
--- a/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
-
-#include <cstdint>
-
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicSustainedBandwidthRecorder;
-
-namespace test {
-
-class QuicSustainedBandwidthRecorderPeer {
- public:
-  QuicSustainedBandwidthRecorderPeer() = delete;
-
-  static void SetBandwidthEstimate(
-      QuicSustainedBandwidthRecorder* bandwidth_recorder,
-      int32_t bandwidth_estimate_kbytes_per_second);
-
-  static void SetMaxBandwidthEstimate(
-      QuicSustainedBandwidthRecorder* bandwidth_recorder,
-      int32_t max_bandwidth_estimate_kbytes_per_second,
-      int32_t max_bandwidth_timestamp);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
diff --git a/quic/test_tools/quic_test_backend.cc b/quic/test_tools/quic_test_backend.cc
deleted file mode 100644
index f84e93e..0000000
--- a/quic/test_tools/quic_test_backend.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_backend.h"
-
-#include <cstring>
-#include <memory>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/test_tools/web_transport_resets_backend.h"
-#include "quic/tools/web_transport_test_visitors.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-// SessionCloseVisitor implements the "/session-close" endpoint.  If the client
-// sends a unidirectional stream of format "code message" to this endpoint, it
-// will close the session with the corresponding error code and error message.
-// For instance, sending "42 test error" will cause it to be closed with code 42
-// and message "test error".
-class SessionCloseVisitor : public WebTransportVisitor {
- public:
-  SessionCloseVisitor(WebTransportSession* session) : session_(session) {}
-
-  void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
-  void OnSessionClosed(WebTransportSessionError /*error_code*/,
-                       const std::string& /*error_message*/) override {}
-
-  void OnIncomingBidirectionalStreamAvailable() override {}
-  void OnIncomingUnidirectionalStreamAvailable() override {
-    WebTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
-    if (stream == nullptr) {
-      return;
-    }
-    stream->SetVisitor(
-        std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
-            stream, [this](const std::string& data) {
-              std::pair<absl::string_view, absl::string_view> parsed =
-                  absl::StrSplit(data, absl::MaxSplits(' ', 1));
-              WebTransportSessionError error_code = 0;
-              bool success = absl::SimpleAtoi(parsed.first, &error_code);
-              QUICHE_DCHECK(success) << data;
-              session_->CloseSession(error_code, parsed.second);
-            }));
-    stream->visitor()->OnCanRead();
-  }
-
-  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
-
-  void OnCanCreateNewOutgoingBidirectionalStream() override {}
-  void OnCanCreateNewOutgoingUnidirectionalStream() override {}
-
- private:
-  WebTransportSession* session_;  // Not owned.
-};
-
-}  // namespace
-
-QuicSimpleServerBackend::WebTransportResponse
-QuicTestBackend::ProcessWebTransportRequest(
-    const spdy::Http2HeaderBlock& request_headers,
-    WebTransportSession* session) {
-  if (!SupportsWebTransport()) {
-    return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
-                                                               session);
-  }
-
-  auto path_it = request_headers.find(":path");
-  if (path_it == request_headers.end()) {
-    WebTransportResponse response;
-    response.response_headers[":status"] = "400";
-    return response;
-  }
-  absl::string_view path = path_it->second;
-  // Match any "/echo.*" pass, e.g. "/echo_foobar"
-  if (absl::StartsWith(path, "/echo")) {
-    WebTransportResponse response;
-    response.response_headers[":status"] = "200";
-    // Add response headers if the paramer has "set-header=XXX:YYY" query.
-    GURL url = GURL(absl::StrCat("https://localhost", path));
-    const std::vector<std::string>& params = absl::StrSplit(url.query(), '&');
-    for (const auto& param : params) {
-      absl::string_view param_view = param;
-      if (absl::ConsumePrefix(&param_view, "set-header=")) {
-        const std::vector<absl::string_view> header_value =
-            absl::StrSplit(param_view, ':');
-        if (header_value.size() == 2 &&
-            !absl::StartsWith(header_value[0], ":")) {
-          response.response_headers[header_value[0]] = header_value[1];
-        }
-      }
-    }
-
-    response.visitor =
-        std::make_unique<EchoWebTransportSessionVisitor>(session);
-    return response;
-  }
-  if (path == "/resets") {
-    return WebTransportResetsBackend(request_headers, session);
-  }
-  if (path == "/session-close") {
-    WebTransportResponse response;
-    response.response_headers[":status"] = "200";
-    response.visitor = std::make_unique<SessionCloseVisitor>(session);
-    return response;
-  }
-
-  WebTransportResponse response;
-  response.response_headers[":status"] = "404";
-  return response;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_test_backend.h b/quic/test_tools/quic_test_backend.h
deleted file mode 100644
index b0c0ce2..0000000
--- a/quic/test_tools/quic_test_backend.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
-
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace quic {
-namespace test {
-
-// QuicTestBackend is a QuicSimpleServer backend usable in tests.  It has extra
-// WebTransport endpoints on top of what QuicMemoryCacheBackend already
-// provides.
-class QuicTestBackend : public QuicMemoryCacheBackend {
- public:
-  WebTransportResponse ProcessWebTransportRequest(
-      const spdy::Http2HeaderBlock& request_headers,
-      WebTransportSession* session) override;
-  bool SupportsWebTransport() override { return enable_webtransport_; }
-
-  void set_enable_webtransport(bool enable_webtransport) {
-    QUICHE_DCHECK(!enable_webtransport || enable_extended_connect_);
-    enable_webtransport_ = enable_webtransport;
-  }
-
-  bool UsesDatagramContexts() override { return use_datagram_contexts_; }
-
-  void set_use_datagram_contexts(bool use_datagram_contexts) {
-    use_datagram_contexts_ = use_datagram_contexts;
-  }
-
-  bool SupportsExtendedConnect() override { return enable_extended_connect_; }
-
-  void set_enable_extended_connect(bool enable_extended_connect) {
-    enable_extended_connect_ = enable_extended_connect;
-  }
-
- private:
-  bool enable_webtransport_ = false;
-  bool use_datagram_contexts_ = false;
-  bool enable_extended_connect_ = true;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
diff --git a/quic/test_tools/quic_test_client.cc b/quic/test_tools/quic_test_client.cc
deleted file mode 100644
index f0d5981..0000000
--- a/quic/test_tools/quic_test_client.cc
+++ /dev/null
@@ -1,1010 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_client.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/x509.h"
-#include "quic/core/crypto/proof_verifier.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packet_writer_wrapper.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_stack_trace.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_client_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_spdy_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_url.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-// RecordingProofVerifier accepts any certificate chain and records the common
-// name of the leaf and then delegates the actual verification to an actual
-// verifier. If no optional verifier is provided, then VerifyProof will return
-// success.
-class RecordingProofVerifier : public ProofVerifier {
- public:
-  explicit RecordingProofVerifier(std::unique_ptr<ProofVerifier> verifier)
-      : verifier_(std::move(verifier)) {}
-
-  // ProofVerifier interface.
-  QuicAsyncStatus VerifyProof(
-      const std::string& hostname,
-      const uint16_t port,
-      const std::string& server_config,
-      QuicTransportVersion transport_version,
-      absl::string_view chlo_hash,
-      const std::vector<std::string>& certs,
-      const std::string& cert_sct,
-      const std::string& signature,
-      const ProofVerifyContext* context,
-      std::string* error_details,
-      std::unique_ptr<ProofVerifyDetails>* details,
-      std::unique_ptr<ProofVerifierCallback> callback) override {
-    QuicAsyncStatus process_certs_result = ProcessCerts(certs, cert_sct);
-    if (process_certs_result != QUIC_SUCCESS) {
-      return process_certs_result;
-    }
-
-    if (!verifier_) {
-      return QUIC_SUCCESS;
-    }
-
-    return verifier_->VerifyProof(hostname, port, server_config,
-                                  transport_version, chlo_hash, certs, cert_sct,
-                                  signature, context, error_details, details,
-                                  std::move(callback));
-  }
-
-  QuicAsyncStatus VerifyCertChain(
-      const std::string& /*hostname*/,
-      const uint16_t /*port*/,
-      const std::vector<std::string>& certs,
-      const std::string& /*ocsp_response*/,
-      const std::string& cert_sct,
-      const ProofVerifyContext* /*context*/,
-      std::string* /*error_details*/,
-      std::unique_ptr<ProofVerifyDetails>* /*details*/,
-      uint8_t* /*out_alert*/,
-      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
-    return ProcessCerts(certs, cert_sct);
-  }
-
-  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
-    return verifier_ != nullptr ? verifier_->CreateDefaultContext() : nullptr;
-  }
-
-  const std::string& common_name() const { return common_name_; }
-
-  const std::string& cert_sct() const { return cert_sct_; }
-
- private:
-  QuicAsyncStatus ProcessCerts(const std::vector<std::string>& certs,
-                               const std::string& cert_sct) {
-    common_name_.clear();
-    if (certs.empty()) {
-      return QUIC_FAILURE;
-    }
-
-    // Parse the cert into an X509 structure.
-    const uint8_t* data;
-    data = reinterpret_cast<const uint8_t*>(certs[0].data());
-    bssl::UniquePtr<X509> cert(d2i_X509(nullptr, &data, certs[0].size()));
-    if (!cert.get()) {
-      return QUIC_FAILURE;
-    }
-
-    // Extract the CN field
-    X509_NAME* subject = X509_get_subject_name(cert.get());
-    const int index = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
-    if (index < 0) {
-      return QUIC_FAILURE;
-    }
-    ASN1_STRING* name_data =
-        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, index));
-    if (name_data == nullptr) {
-      return QUIC_FAILURE;
-    }
-
-    // Convert the CN to UTF8, in case the cert represents it in a different
-    // format.
-    unsigned char* buf = nullptr;
-    const int len = ASN1_STRING_to_UTF8(&buf, name_data);
-    if (len <= 0) {
-      return QUIC_FAILURE;
-    }
-    bssl::UniquePtr<unsigned char> deleter(buf);
-
-    common_name_.assign(reinterpret_cast<const char*>(buf), len);
-    cert_sct_ = cert_sct;
-    return QUIC_SUCCESS;
-  }
-
-  std::unique_ptr<ProofVerifier> verifier_;
-  std::string common_name_;
-  std::string cert_sct_;
-};
-}  // namespace
-
-class MockableQuicClientEpollNetworkHelper
-    : public QuicClientEpollNetworkHelper {
- public:
-  using QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper;
-  ~MockableQuicClientEpollNetworkHelper() override = default;
-
-  void ProcessPacket(const QuicSocketAddress& self_address,
-                     const QuicSocketAddress& peer_address,
-                     const QuicReceivedPacket& packet) override {
-    QuicClientEpollNetworkHelper::ProcessPacket(self_address, peer_address,
-                                                packet);
-    if (track_last_incoming_packet_) {
-      last_incoming_packet_ = packet.Clone();
-    }
-  }
-
-  QuicPacketWriter* CreateQuicPacketWriter() override {
-    QuicPacketWriter* writer =
-        QuicClientEpollNetworkHelper::CreateQuicPacketWriter();
-    if (!test_writer_) {
-      return writer;
-    }
-    test_writer_->set_writer(writer);
-    return test_writer_;
-  }
-
-  const QuicReceivedPacket* last_incoming_packet() {
-    return last_incoming_packet_.get();
-  }
-
-  void set_track_last_incoming_packet(bool track) {
-    track_last_incoming_packet_ = track;
-  }
-
-  void UseWriter(QuicPacketWriterWrapper* writer) {
-    QUICHE_CHECK(test_writer_ == nullptr);
-    test_writer_ = writer;
-  }
-
-  void set_peer_address(const QuicSocketAddress& address) {
-    QUICHE_CHECK(test_writer_ != nullptr);
-    test_writer_->set_peer_address(address);
-  }
-
- private:
-  QuicPacketWriterWrapper* test_writer_ = nullptr;
-  // The last incoming packet, iff |track_last_incoming_packet_| is true.
-  std::unique_ptr<QuicReceivedPacket> last_incoming_packet_;
-  // If true, copy each packet from ProcessPacket into |last_incoming_packet_|
-  bool track_last_incoming_packet_ = false;
-};
-
-MockableQuicClient::MockableQuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicEpollServer* epoll_server)
-    : MockableQuicClient(server_address,
-                         server_id,
-                         QuicConfig(),
-                         supported_versions,
-                         epoll_server) {}
-
-MockableQuicClient::MockableQuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicEpollServer* epoll_server)
-    : MockableQuicClient(server_address,
-                         server_id,
-                         config,
-                         supported_versions,
-                         epoll_server,
-                         nullptr) {}
-
-MockableQuicClient::MockableQuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<ProofVerifier> proof_verifier)
-    : MockableQuicClient(server_address,
-                         server_id,
-                         config,
-                         supported_versions,
-                         epoll_server,
-                         std::move(proof_verifier),
-                         nullptr) {}
-
-MockableQuicClient::MockableQuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    std::unique_ptr<SessionCache> session_cache)
-    : QuicClient(
-          server_address,
-          server_id,
-          supported_versions,
-          config,
-          epoll_server,
-          std::make_unique<MockableQuicClientEpollNetworkHelper>(epoll_server,
-                                                                 this),
-          std::make_unique<RecordingProofVerifier>(std::move(proof_verifier)),
-          std::move(session_cache)),
-      override_server_connection_id_(EmptyQuicConnectionId()),
-      server_connection_id_overridden_(false),
-      override_client_connection_id_(EmptyQuicConnectionId()),
-      client_connection_id_overridden_(false) {}
-
-MockableQuicClient::~MockableQuicClient() {
-  if (connected()) {
-    Disconnect();
-  }
-}
-
-MockableQuicClientEpollNetworkHelper*
-MockableQuicClient::mockable_network_helper() {
-  return static_cast<MockableQuicClientEpollNetworkHelper*>(
-      epoll_network_helper());
-}
-
-const MockableQuicClientEpollNetworkHelper*
-MockableQuicClient::mockable_network_helper() const {
-  return static_cast<const MockableQuicClientEpollNetworkHelper*>(
-      epoll_network_helper());
-}
-
-QuicConnectionId MockableQuicClient::GenerateNewConnectionId() {
-  if (server_connection_id_overridden_) {
-    return override_server_connection_id_;
-  }
-  if (override_server_connection_id_length_ >= 0) {
-    return QuicUtils::CreateRandomConnectionId(
-        override_server_connection_id_length_);
-  }
-  return QuicClient::GenerateNewConnectionId();
-}
-
-void MockableQuicClient::UseConnectionId(
-    QuicConnectionId server_connection_id) {
-  server_connection_id_overridden_ = true;
-  override_server_connection_id_ = server_connection_id;
-}
-
-void MockableQuicClient::UseConnectionIdLength(
-    int server_connection_id_length) {
-  override_server_connection_id_length_ = server_connection_id_length;
-}
-
-QuicConnectionId MockableQuicClient::GetClientConnectionId() {
-  if (client_connection_id_overridden_) {
-    return override_client_connection_id_;
-  }
-  if (override_client_connection_id_length_ >= 0) {
-    return QuicUtils::CreateRandomConnectionId(
-        override_client_connection_id_length_);
-  }
-  return QuicClient::GetClientConnectionId();
-}
-
-void MockableQuicClient::UseClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  client_connection_id_overridden_ = true;
-  override_client_connection_id_ = client_connection_id;
-}
-
-void MockableQuicClient::UseClientConnectionIdLength(
-    int client_connection_id_length) {
-  override_client_connection_id_length_ = client_connection_id_length;
-}
-
-void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
-  mockable_network_helper()->UseWriter(writer);
-}
-
-void MockableQuicClient::set_peer_address(const QuicSocketAddress& address) {
-  mockable_network_helper()->set_peer_address(address);
-  if (client_session() != nullptr) {
-    client_session()->AddKnownServerAddress(address);
-  }
-}
-
-const QuicReceivedPacket* MockableQuicClient::last_incoming_packet() {
-  return mockable_network_helper()->last_incoming_packet();
-}
-
-void MockableQuicClient::set_track_last_incoming_packet(bool track) {
-  mockable_network_helper()->set_track_last_incoming_packet(track);
-}
-
-QuicTestClient::QuicTestClient(
-    QuicSocketAddress server_address,
-    const std::string& server_hostname,
-    const ParsedQuicVersionVector& supported_versions)
-    : QuicTestClient(server_address,
-                     server_hostname,
-                     QuicConfig(),
-                     supported_versions) {}
-
-QuicTestClient::QuicTestClient(
-    QuicSocketAddress server_address,
-    const std::string& server_hostname,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions)
-    : client_(new MockableQuicClient(
-          server_address,
-          QuicServerId(server_hostname, server_address.port(), false),
-          config,
-          supported_versions,
-          &epoll_server_)) {
-  Initialize();
-}
-
-QuicTestClient::QuicTestClient(
-    QuicSocketAddress server_address,
-    const std::string& server_hostname,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    std::unique_ptr<ProofVerifier> proof_verifier)
-    : client_(new MockableQuicClient(
-          server_address,
-          QuicServerId(server_hostname, server_address.port(), false),
-          config,
-          supported_versions,
-          &epoll_server_,
-          std::move(proof_verifier))) {
-  Initialize();
-}
-
-QuicTestClient::QuicTestClient(
-    QuicSocketAddress server_address,
-    const std::string& server_hostname,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    std::unique_ptr<SessionCache> session_cache)
-    : client_(new MockableQuicClient(
-          server_address,
-          QuicServerId(server_hostname, server_address.port(), false),
-          config,
-          supported_versions,
-          &epoll_server_,
-          std::move(proof_verifier),
-          std::move(session_cache))) {
-  Initialize();
-}
-
-QuicTestClient::QuicTestClient() = default;
-
-QuicTestClient::~QuicTestClient() {
-  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
-    stream.second->set_visitor(nullptr);
-  }
-}
-
-void QuicTestClient::Initialize() {
-  priority_ = 3;
-  connect_attempted_ = false;
-  auto_reconnect_ = false;
-  buffer_body_ = true;
-  num_requests_ = 0;
-  num_responses_ = 0;
-  ClearPerConnectionState();
-  // As chrome will generally do this, we want it to be the default when it's
-  // not overridden.
-  if (!client_->config()->HasSetBytesForConnectionIdToSend()) {
-    client_->config()->SetBytesForConnectionIdToSend(0);
-  }
-}
-
-void QuicTestClient::SetUserAgentID(const std::string& user_agent_id) {
-  client_->SetUserAgentID(user_agent_id);
-}
-
-ssize_t QuicTestClient::SendRequest(const std::string& uri) {
-  spdy::SpdyHeaderBlock headers;
-  if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
-    return 0;
-  }
-  return SendMessage(headers, "");
-}
-
-ssize_t QuicTestClient::SendRequestAndRstTogether(const std::string& uri) {
-  spdy::SpdyHeaderBlock headers;
-  if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
-    return 0;
-  }
-
-  QuicSpdyClientSession* session = client()->client_session();
-  QuicConnection::ScopedPacketFlusher flusher(session->connection());
-  ssize_t ret = SendMessage(headers, "", /*fin=*/true, /*flush=*/false);
-
-  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(
-      session->transport_version(), 0);
-  session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
-  return ret;
-}
-
-void QuicTestClient::SendRequestsAndWaitForResponses(
-    const std::vector<std::string>& url_list) {
-  for (const std::string& url : url_list) {
-    SendRequest(url);
-  }
-  while (client()->WaitForEvents()) {
-  }
-}
-
-ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
-    const spdy::SpdyHeaderBlock* headers, absl::string_view body, bool fin,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  if (headers) {
-    QuicClientPushPromiseIndex::TryHandle* handle;
-    QuicAsyncStatus rv =
-        client()->push_promise_index()->Try(*headers, this, &handle);
-    if (rv == QUIC_SUCCESS)
-      return 1;
-    if (rv == QUIC_PENDING) {
-      // May need to retry request if asynchronous rendezvous fails.
-      std::unique_ptr<spdy::SpdyHeaderBlock> new_headers(
-          new spdy::SpdyHeaderBlock(headers->Clone()));
-      push_promise_data_to_resend_ = std::make_unique<TestClientDataToResend>(
-          std::move(new_headers), body, fin, this, std::move(ack_listener));
-      return 1;
-    }
-  }
-
-  // Maybe it's better just to overload this.  it's just that we need
-  // for the GetOrCreateStream function to call something else...which
-  // is icky and complicated, but maybe not worse than this.
-  QuicSpdyClientStream* stream = GetOrCreateStream();
-  if (stream == nullptr) {
-    return 0;
-  }
-  QuicSpdyStreamPeer::set_ack_listener(stream, ack_listener);
-
-  ssize_t ret = 0;
-  if (headers != nullptr) {
-    spdy::SpdyHeaderBlock spdy_headers(headers->Clone());
-    if (spdy_headers[":authority"].as_string().empty()) {
-      spdy_headers[":authority"] = client_->server_id().host();
-    }
-    ret = stream->SendRequest(std::move(spdy_headers), body, fin);
-    ++num_requests_;
-  } else {
-    stream->WriteOrBufferBody(std::string(body), fin);
-    ret = body.length();
-  }
-  return ret;
-}
-
-ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
-                                    absl::string_view body) {
-  return SendMessage(headers, body, /*fin=*/true);
-}
-
-ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
-                                    absl::string_view body,
-                                    bool fin) {
-  return SendMessage(headers, body, fin, /*flush=*/true);
-}
-
-ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
-                                    absl::string_view body,
-                                    bool fin,
-                                    bool flush) {
-  // Always force creation of a stream for SendMessage.
-  latest_created_stream_ = nullptr;
-
-  ssize_t ret = GetOrCreateStreamAndSendRequest(&headers, body, fin, nullptr);
-
-  if (flush) {
-    WaitForWriteToFlush();
-  }
-  return ret;
-}
-
-ssize_t QuicTestClient::SendData(const std::string& data, bool last_data) {
-  return SendData(data, last_data, nullptr);
-}
-
-ssize_t QuicTestClient::SendData(
-    const std::string& data, bool last_data,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener) {
-  return GetOrCreateStreamAndSendRequest(nullptr, absl::string_view(data),
-                                         last_data, std::move(ack_listener));
-}
-
-bool QuicTestClient::response_complete() const {
-  return response_complete_;
-}
-
-int64_t QuicTestClient::response_body_size() const {
-  return response_body_size_;
-}
-
-bool QuicTestClient::buffer_body() const {
-  return buffer_body_;
-}
-
-void QuicTestClient::set_buffer_body(bool buffer_body) {
-  buffer_body_ = buffer_body;
-}
-
-const std::string& QuicTestClient::response_body() const {
-  return response_;
-}
-
-std::string QuicTestClient::SendCustomSynchronousRequest(
-    const spdy::SpdyHeaderBlock& headers,
-    const std::string& body) {
-  // Clear connection state here and only track this synchronous request.
-  ClearPerConnectionState();
-  if (SendMessage(headers, body) == 0) {
-    QUIC_DLOG(ERROR) << "Failed the request for: " << headers.DebugString();
-    // Set the response_ explicitly.  Otherwise response_ will contain the
-    // response from the previously successful request.
-    response_ = "";
-  } else {
-    WaitForResponse();
-  }
-  return response_;
-}
-
-std::string QuicTestClient::SendSynchronousRequest(const std::string& uri) {
-  spdy::SpdyHeaderBlock headers;
-  if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
-    return "";
-  }
-  return SendCustomSynchronousRequest(headers, "");
-}
-
-void QuicTestClient::SendConnectivityProbing() {
-  QuicConnection* connection = client()->client_session()->connection();
-  connection->SendConnectivityProbingPacket(connection->writer(),
-                                            connection->peer_address());
-}
-
-void QuicTestClient::SetLatestCreatedStream(QuicSpdyClientStream* stream) {
-  latest_created_stream_ = stream;
-  if (latest_created_stream_ != nullptr) {
-    open_streams_[stream->id()] = stream;
-    stream->set_visitor(this);
-  }
-}
-
-QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
-  if (!connect_attempted_ || auto_reconnect_) {
-    if (!connected()) {
-      Connect();
-    }
-    if (!connected()) {
-      return nullptr;
-    }
-  }
-  if (open_streams_.empty()) {
-    ClearPerConnectionState();
-  }
-  if (!latest_created_stream_) {
-    SetLatestCreatedStream(client_->CreateClientStream());
-    if (latest_created_stream_) {
-      latest_created_stream_->SetPriority(
-          spdy::SpdyStreamPrecedence(priority_));
-    }
-  }
-
-  return latest_created_stream_;
-}
-
-QuicErrorCode QuicTestClient::connection_error() const {
-  return client()->connection_error();
-}
-
-const std::string& QuicTestClient::cert_common_name() const {
-  return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
-      ->common_name();
-}
-
-const std::string& QuicTestClient::cert_sct() const {
-  return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
-      ->cert_sct();
-}
-
-const QuicTagValueMap& QuicTestClient::GetServerConfig() const {
-  QuicCryptoClientConfig* config = client_->crypto_config();
-  const QuicCryptoClientConfig::CachedState* state =
-      config->LookupOrCreate(client_->server_id());
-  const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig();
-  return handshake_msg->tag_value_map();
-}
-
-bool QuicTestClient::connected() const {
-  return client_->connected();
-}
-
-void QuicTestClient::Connect() {
-  if (connected()) {
-    QUIC_BUG(quic_bug_10133_1) << "Cannot connect already-connected client";
-    return;
-  }
-  if (!connect_attempted_) {
-    client_->Initialize();
-  }
-
-  // If we've been asked to override SNI, set it now
-  if (override_sni_set_) {
-    client_->set_server_id(
-        QuicServerId(override_sni_, address().port(), false));
-  }
-
-  client_->Connect();
-  connect_attempted_ = true;
-}
-
-void QuicTestClient::ResetConnection() {
-  Disconnect();
-  Connect();
-}
-
-void QuicTestClient::Disconnect() {
-  ClearPerConnectionState();
-  if (client_->initialized()) {
-    client_->Disconnect();
-  }
-  connect_attempted_ = false;
-}
-
-QuicSocketAddress QuicTestClient::local_address() const {
-  return client_->network_helper()->GetLatestClientAddress();
-}
-
-void QuicTestClient::ClearPerRequestState() {
-  stream_error_ = QUIC_STREAM_NO_ERROR;
-  response_ = "";
-  response_complete_ = false;
-  response_headers_complete_ = false;
-  preliminary_headers_.clear();
-  response_headers_.clear();
-  response_trailers_.clear();
-  bytes_read_ = 0;
-  bytes_written_ = 0;
-  response_body_size_ = 0;
-}
-
-bool QuicTestClient::HaveActiveStream() {
-  return push_promise_data_to_resend_.get() || !open_streams_.empty();
-}
-
-bool QuicTestClient::WaitUntil(int timeout_ms, std::function<bool()> trigger) {
-  int64_t timeout_us = timeout_ms * kNumMicrosPerMilli;
-  int64_t old_timeout_us = epoll_server()->timeout_in_us_for_test();
-  if (timeout_us > 0) {
-    epoll_server()->set_timeout_in_us(timeout_us);
-  }
-  const QuicClock* clock =
-      QuicConnectionPeer::GetHelper(client()->session()->connection())
-          ->GetClock();
-  QuicTime end_waiting_time =
-      clock->Now() + QuicTime::Delta::FromMicroseconds(timeout_us);
-  while (HaveActiveStream() && !(trigger && trigger()) &&
-         (timeout_us < 0 || clock->Now() < end_waiting_time)) {
-    client_->WaitForEvents();
-  }
-  ReadNextResponse();
-  if (timeout_us > 0) {
-    epoll_server()->set_timeout_in_us(old_timeout_us);
-  }
-  if (trigger && !trigger()) {
-    QUIC_VLOG(1) << "Client WaitUntil returning with trigger returning false.";
-    return false;
-  }
-  return true;
-}
-
-ssize_t QuicTestClient::Send(absl::string_view data) {
-  return SendData(std::string(data), false);
-}
-
-bool QuicTestClient::response_headers_complete() const {
-  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
-    if (stream.second->headers_decompressed()) {
-      return true;
-    }
-  }
-  return response_headers_complete_;
-}
-
-const spdy::SpdyHeaderBlock* QuicTestClient::response_headers() const {
-  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
-    if (stream.second->headers_decompressed()) {
-      response_headers_ = stream.second->response_headers().Clone();
-      break;
-    }
-  }
-  return &response_headers_;
-}
-
-const spdy::SpdyHeaderBlock* QuicTestClient::preliminary_headers() const {
-  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
-    size_t bytes_read =
-        stream.second->stream_bytes_read() + stream.second->header_bytes_read();
-    if (bytes_read > 0) {
-      preliminary_headers_ = stream.second->preliminary_headers().Clone();
-      break;
-    }
-  }
-  return &preliminary_headers_;
-}
-
-const spdy::SpdyHeaderBlock& QuicTestClient::response_trailers() const {
-  return response_trailers_;
-}
-
-int64_t QuicTestClient::response_size() const {
-  return bytes_read();
-}
-
-size_t QuicTestClient::bytes_read() const {
-  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
-    size_t bytes_read = stream.second->total_body_bytes_read() +
-                        stream.second->header_bytes_read();
-    if (bytes_read > 0) {
-      return bytes_read;
-    }
-  }
-  return bytes_read_;
-}
-
-size_t QuicTestClient::bytes_written() const {
-  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
-    size_t bytes_written = stream.second->stream_bytes_written() +
-                           stream.second->header_bytes_written();
-    if (bytes_written > 0) {
-      return bytes_written;
-    }
-  }
-  return bytes_written_;
-}
-
-void QuicTestClient::OnClose(QuicSpdyStream* stream) {
-  if (stream == nullptr) {
-    return;
-  }
-  // Always close the stream, regardless of whether it was the last stream
-  // written.
-  client()->OnClose(stream);
-  ++num_responses_;
-  if (open_streams_.find(stream->id()) == open_streams_.end()) {
-    return;
-  }
-  if (latest_created_stream_ == stream) {
-    latest_created_stream_ = nullptr;
-  }
-  QuicSpdyClientStream* client_stream =
-      static_cast<QuicSpdyClientStream*>(stream);
-  QuicStreamId id = client_stream->id();
-  closed_stream_states_.insert(std::make_pair(
-      id,
-      PerStreamState(
-          // Set response_complete to true iff stream is closed while connected.
-          client_stream->stream_error(), connected(),
-          client_stream->headers_decompressed(),
-          client_stream->response_headers(),
-          client_stream->preliminary_headers(),
-          (buffer_body() ? client_stream->data() : ""),
-          client_stream->received_trailers(),
-          // Use NumBytesConsumed to avoid counting retransmitted stream frames.
-          client_stream->total_body_bytes_read() +
-              client_stream->header_bytes_read(),
-          client_stream->stream_bytes_written() +
-              client_stream->header_bytes_written(),
-          client_stream->data().size())));
-  open_streams_.erase(id);
-}
-
-bool QuicTestClient::CheckVary(
-    const spdy::SpdyHeaderBlock& /*client_request*/,
-    const spdy::SpdyHeaderBlock& /*promise_request*/,
-    const spdy::SpdyHeaderBlock& /*promise_response*/) {
-  return true;
-}
-
-void QuicTestClient::OnRendezvousResult(QuicSpdyStream* stream) {
-  std::unique_ptr<TestClientDataToResend> data_to_resend =
-      std::move(push_promise_data_to_resend_);
-  SetLatestCreatedStream(static_cast<QuicSpdyClientStream*>(stream));
-  if (stream) {
-    stream->OnBodyAvailable();
-  } else if (data_to_resend) {
-    data_to_resend->Resend();
-  }
-}
-
-void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) {
-  client_->UseWriter(writer);
-}
-
-void QuicTestClient::UseConnectionId(QuicConnectionId server_connection_id) {
-  QUICHE_DCHECK(!connected());
-  client_->UseConnectionId(server_connection_id);
-}
-
-void QuicTestClient::UseConnectionIdLength(int server_connection_id_length) {
-  QUICHE_DCHECK(!connected());
-  client_->UseConnectionIdLength(server_connection_id_length);
-}
-
-void QuicTestClient::UseClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  QUICHE_DCHECK(!connected());
-  client_->UseClientConnectionId(client_connection_id);
-}
-
-void QuicTestClient::UseClientConnectionIdLength(
-    int client_connection_id_length) {
-  QUICHE_DCHECK(!connected());
-  client_->UseClientConnectionIdLength(client_connection_id_length);
-}
-
-bool QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
-  return client_->MigrateSocket(new_host);
-}
-
-bool QuicTestClient::MigrateSocketWithSpecifiedPort(
-    const QuicIpAddress& new_host,
-    int port) {
-  client_->set_local_port(port);
-  return client_->MigrateSocket(new_host);
-}
-
-QuicIpAddress QuicTestClient::bind_to_address() const {
-  return client_->bind_to_address();
-}
-
-void QuicTestClient::set_bind_to_address(QuicIpAddress address) {
-  client_->set_bind_to_address(address);
-}
-
-const QuicSocketAddress& QuicTestClient::address() const {
-  return client_->server_address();
-}
-
-void QuicTestClient::WaitForWriteToFlush() {
-  while (connected() && client()->session()->HasDataToWrite()) {
-    client_->WaitForEvents();
-  }
-}
-
-QuicTestClient::TestClientDataToResend::TestClientDataToResend(
-    std::unique_ptr<spdy::SpdyHeaderBlock> headers, absl::string_view body,
-    bool fin, QuicTestClient* test_client,
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener)
-    : QuicClient::QuicDataToResend(std::move(headers), body, fin),
-      test_client_(test_client),
-      ack_listener_(std::move(ack_listener)) {}
-
-QuicTestClient::TestClientDataToResend::~TestClientDataToResend() = default;
-
-void QuicTestClient::TestClientDataToResend::Resend() {
-  test_client_->GetOrCreateStreamAndSendRequest(headers_.get(), body_, fin_,
-                                                ack_listener_);
-  headers_.reset();
-}
-
-QuicTestClient::PerStreamState::PerStreamState(const PerStreamState& other)
-    : stream_error(other.stream_error),
-      response_complete(other.response_complete),
-      response_headers_complete(other.response_headers_complete),
-      response_headers(other.response_headers.Clone()),
-      preliminary_headers(other.preliminary_headers.Clone()),
-      response(other.response),
-      response_trailers(other.response_trailers.Clone()),
-      bytes_read(other.bytes_read),
-      bytes_written(other.bytes_written),
-      response_body_size(other.response_body_size) {}
-
-QuicTestClient::PerStreamState::PerStreamState(
-    QuicRstStreamErrorCode stream_error,
-    bool response_complete,
-    bool response_headers_complete,
-    const spdy::SpdyHeaderBlock& response_headers,
-    const spdy::SpdyHeaderBlock& preliminary_headers,
-    const std::string& response,
-    const spdy::SpdyHeaderBlock& response_trailers,
-    uint64_t bytes_read,
-    uint64_t bytes_written,
-    int64_t response_body_size)
-    : stream_error(stream_error),
-      response_complete(response_complete),
-      response_headers_complete(response_headers_complete),
-      response_headers(response_headers.Clone()),
-      preliminary_headers(preliminary_headers.Clone()),
-      response(response),
-      response_trailers(response_trailers.Clone()),
-      bytes_read(bytes_read),
-      bytes_written(bytes_written),
-      response_body_size(response_body_size) {}
-
-QuicTestClient::PerStreamState::~PerStreamState() = default;
-
-bool QuicTestClient::PopulateHeaderBlockFromUrl(
-    const std::string& uri,
-    spdy::SpdyHeaderBlock* headers) {
-  std::string url;
-  if (absl::StartsWith(uri, "https://") || absl::StartsWith(uri, "http://")) {
-    url = uri;
-  } else if (uri[0] == '/') {
-    url = "https://" + client_->server_id().host() + uri;
-  } else {
-    url = "https://" + uri;
-  }
-  return SpdyUtils::PopulateHeaderBlockFromUrl(url, headers);
-}
-
-void QuicTestClient::ReadNextResponse() {
-  if (closed_stream_states_.empty()) {
-    return;
-  }
-
-  PerStreamState state(closed_stream_states_.front().second);
-
-  stream_error_ = state.stream_error;
-  response_ = state.response;
-  response_complete_ = state.response_complete;
-  response_headers_complete_ = state.response_headers_complete;
-  preliminary_headers_ = state.preliminary_headers.Clone();
-  response_headers_ = state.response_headers.Clone();
-  response_trailers_ = state.response_trailers.Clone();
-  bytes_read_ = state.bytes_read;
-  bytes_written_ = state.bytes_written;
-  response_body_size_ = state.response_body_size;
-
-  closed_stream_states_.pop_front();
-}
-
-void QuicTestClient::ClearPerConnectionState() {
-  ClearPerRequestState();
-  open_streams_.clear();
-  closed_stream_states_.clear();
-  latest_created_stream_ = nullptr;
-}
-
-void QuicTestClient::WaitForDelayedAcks() {
-  // kWaitDuration is a period of time that is long enough for all delayed
-  // acks to be sent and received on the other end.
-  const QuicTime::Delta kWaitDuration =
-      4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
-  const QuicClock* clock = client()->client_session()->connection()->clock();
-
-  QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
-  while (connected() && clock->ApproximateNow() < wait_until) {
-    // This waits for up to 50 ms.
-    client()->WaitForEvents();
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_test_client.h b/quic/test_tools/quic_test_client.h
deleted file mode 100644
index b655adf..0000000
--- a/quic/test_tools/quic_test_client.h
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/tools/quic_client.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class ProofVerifier;
-class QuicPacketWriterWrapper;
-
-namespace test {
-
-class MockableQuicClientEpollNetworkHelper;
-
-// A quic client which allows mocking out reads and writes.
-class MockableQuicClient : public QuicClient {
- public:
-  MockableQuicClient(QuicSocketAddress server_address,
-                     const QuicServerId& server_id,
-                     const ParsedQuicVersionVector& supported_versions,
-                     QuicEpollServer* epoll_server);
-
-  MockableQuicClient(QuicSocketAddress server_address,
-                     const QuicServerId& server_id,
-                     const QuicConfig& config,
-                     const ParsedQuicVersionVector& supported_versions,
-                     QuicEpollServer* epoll_server);
-
-  MockableQuicClient(QuicSocketAddress server_address,
-                     const QuicServerId& server_id,
-                     const QuicConfig& config,
-                     const ParsedQuicVersionVector& supported_versions,
-                     QuicEpollServer* epoll_server,
-                     std::unique_ptr<ProofVerifier> proof_verifier);
-
-  MockableQuicClient(QuicSocketAddress server_address,
-                     const QuicServerId& server_id,
-                     const QuicConfig& config,
-                     const ParsedQuicVersionVector& supported_versions,
-                     QuicEpollServer* epoll_server,
-                     std::unique_ptr<ProofVerifier> proof_verifier,
-                     std::unique_ptr<SessionCache> session_cache);
-  MockableQuicClient(const MockableQuicClient&) = delete;
-  MockableQuicClient& operator=(const MockableQuicClient&) = delete;
-
-  ~MockableQuicClient() override;
-
-  QuicConnectionId GenerateNewConnectionId() override;
-  void UseConnectionId(QuicConnectionId server_connection_id);
-  void UseConnectionIdLength(int server_connection_id_length);
-  QuicConnectionId GetClientConnectionId() override;
-  void UseClientConnectionId(QuicConnectionId client_connection_id);
-  void UseClientConnectionIdLength(int client_connection_id_length);
-
-  void UseWriter(QuicPacketWriterWrapper* writer);
-  void set_peer_address(const QuicSocketAddress& address);
-  // The last incoming packet, iff |track_last_incoming_packet| is true.
-  const QuicReceivedPacket* last_incoming_packet();
-  // If true, copy each packet from ProcessPacket into |last_incoming_packet|
-  void set_track_last_incoming_packet(bool track);
-
-  // Casts the network helper to a MockableQuicClientEpollNetworkHelper.
-  MockableQuicClientEpollNetworkHelper* mockable_network_helper();
-  const MockableQuicClientEpollNetworkHelper* mockable_network_helper() const;
-
- private:
-  // Server connection ID to use, if server_connection_id_overridden_
-  QuicConnectionId override_server_connection_id_;
-  bool server_connection_id_overridden_;
-  int override_server_connection_id_length_ = -1;
-  // Client connection ID to use, if client_connection_id_overridden_
-  QuicConnectionId override_client_connection_id_;
-  bool client_connection_id_overridden_;
-  int override_client_connection_id_length_ = -1;
-  CachedNetworkParameters cached_network_paramaters_;
-};
-
-// A toy QUIC client used for testing.
-class QuicTestClient : public QuicSpdyStream::Visitor,
-                       public QuicClientPushPromiseIndex::Delegate {
- public:
-  QuicTestClient(QuicSocketAddress server_address,
-                 const std::string& server_hostname,
-                 const ParsedQuicVersionVector& supported_versions);
-  QuicTestClient(QuicSocketAddress server_address,
-                 const std::string& server_hostname,
-                 const QuicConfig& config,
-                 const ParsedQuicVersionVector& supported_versions);
-  QuicTestClient(QuicSocketAddress server_address,
-                 const std::string& server_hostname,
-                 const QuicConfig& config,
-                 const ParsedQuicVersionVector& supported_versions,
-                 std::unique_ptr<ProofVerifier> proof_verifier);
-  QuicTestClient(QuicSocketAddress server_address,
-                 const std::string& server_hostname,
-                 const QuicConfig& config,
-                 const ParsedQuicVersionVector& supported_versions,
-                 std::unique_ptr<ProofVerifier> proof_verifier,
-                 std::unique_ptr<SessionCache> session_cache);
-
-  ~QuicTestClient() override;
-
-  // Sets the |user_agent_id| of the |client_|.
-  void SetUserAgentID(const std::string& user_agent_id);
-
-  // Wraps data in a quic packet and sends it.
-  ssize_t SendData(const std::string& data, bool last_data);
-  // As above, but |delegate| will be notified when |data| is ACKed.
-  ssize_t SendData(
-      const std::string& data, bool last_data,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  // Clears any outstanding state and sends a simple GET of 'uri' to the
-  // server.  Returns 0 if the request failed and no bytes were written.
-  ssize_t SendRequest(const std::string& uri);
-  // Send a request R and a RST_FRAME which resets R, in the same packet.
-  ssize_t SendRequestAndRstTogether(const std::string& uri);
-  // Sends requests for all the urls and waits for the responses.  To process
-  // the individual responses as they are returned, the caller should use the
-  // set the response_listener on the client().
-  void SendRequestsAndWaitForResponses(
-      const std::vector<std::string>& url_list);
-  // Sends a request containing |headers| and |body| and returns the number of
-  // bytes sent (the size of the serialized request headers and body).
-  ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
-                      absl::string_view body);
-  // Sends a request containing |headers| and |body| with the fin bit set to
-  // |fin| and returns the number of bytes sent (the size of the serialized
-  // request headers and body).
-  ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
-                      absl::string_view body,
-                      bool fin);
-  // Sends a request containing |headers| and |body| with the fin bit set to
-  // |fin| and returns the number of bytes sent (the size of the serialized
-  // request headers and body). If |flush| is true, will wait for the message to
-  // be flushed before returning.
-  ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
-                      absl::string_view body,
-                      bool fin,
-                      bool flush);
-  // Sends a request containing |headers| and |body|, waits for the response,
-  // and returns the response body.
-  std::string SendCustomSynchronousRequest(const spdy::SpdyHeaderBlock& headers,
-                                           const std::string& body);
-  // Sends a GET request for |uri|, waits for the response, and returns the
-  // response body.
-  std::string SendSynchronousRequest(const std::string& uri);
-  void SendConnectivityProbing();
-  void Connect();
-  void ResetConnection();
-  void Disconnect();
-  QuicSocketAddress local_address() const;
-  void ClearPerRequestState();
-  bool WaitUntil(int timeout_ms, std::function<bool()> trigger);
-  ssize_t Send(absl::string_view data);
-  bool connected() const;
-  bool buffer_body() const;
-  void set_buffer_body(bool buffer_body);
-
-  // Getters for stream state. Please note, these getters are divided into two
-  // groups. 1) returns state which only get updated once a complete response
-  // is received. 2) returns state of the oldest active stream which have
-  // received partial response (if any).
-  // Group 1.
-  const spdy::SpdyHeaderBlock& response_trailers() const;
-  bool response_complete() const;
-  int64_t response_body_size() const;
-  const std::string& response_body() const;
-  // Group 2.
-  bool response_headers_complete() const;
-  const spdy::SpdyHeaderBlock* response_headers() const;
-  const spdy::SpdyHeaderBlock* preliminary_headers() const;
-  int64_t response_size() const;
-  size_t bytes_read() const;
-  size_t bytes_written() const;
-
-  // Returns once at least one complete response or a connection close has been
-  // received from the server. If responses are received for multiple (say 2)
-  // streams, next WaitForResponse will return immediately.
-  void WaitForResponse() { WaitForResponseForMs(-1); }
-
-  // Returns once some data is received on any open streams or at least one
-  // complete response is received from the server.
-  void WaitForInitialResponse() { WaitForInitialResponseForMs(-1); }
-
-  // Returns once at least one complete response or a connection close has been
-  // received from the server, or once the timeout expires.
-  // Passing in a timeout value of -1 disables the timeout. If multiple
-  // responses are received while the client is waiting, subsequent calls to
-  // this function will return immediately.
-  void WaitForResponseForMs(int timeout_ms) {
-    WaitUntil(timeout_ms, [this]() { return !closed_stream_states_.empty(); });
-    if (response_complete()) {
-      QUIC_VLOG(1) << "Client received response:"
-                   << response_headers()->DebugString() << response_body();
-    }
-  }
-
-  // Returns once some data is received on any open streams or at least one
-  // complete response is received from the server, or once the timeout
-  // expires. -1 means no timeout.
-  void WaitForInitialResponseForMs(int timeout_ms) {
-    WaitUntil(timeout_ms, [this]() { return response_size() != 0; });
-  }
-
-  // Migrate local address to <|new_host|, a random port>.
-  // Return whether the migration succeeded.
-  bool MigrateSocket(const QuicIpAddress& new_host);
-  // Migrate local address to <|new_host|, |port|>.
-  // Return whether the migration succeeded.
-  bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
-  QuicIpAddress bind_to_address() const;
-  void set_bind_to_address(QuicIpAddress address);
-  const QuicSocketAddress& address() const;
-
-  // From QuicSpdyStream::Visitor
-  void OnClose(QuicSpdyStream* stream) override;
-
-  // From QuicClientPushPromiseIndex::Delegate
-  bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
-                 const spdy::SpdyHeaderBlock& promise_request,
-                 const spdy::SpdyHeaderBlock& promise_response) override;
-  void OnRendezvousResult(QuicSpdyStream*) override;
-
-  // Configures client_ to take ownership of and use the writer.
-  // Must be called before initial connect.
-  void UseWriter(QuicPacketWriterWrapper* writer);
-  // Configures client_ to use a specific server connection ID instead of a
-  // random one.
-  void UseConnectionId(QuicConnectionId server_connection_id);
-  // Configures client_ to use a specific server connection ID length instead
-  // of the default of kQuicDefaultConnectionIdLength.
-  void UseConnectionIdLength(int server_connection_id_length);
-  // Configures client_ to use a specific client connection ID instead of an
-  // empty one.
-  void UseClientConnectionId(QuicConnectionId client_connection_id);
-  // Configures client_ to use a specific client connection ID length instead
-  // of the default of zero.
-  void UseClientConnectionIdLength(int client_connection_id_length);
-
-  // Returns nullptr if the maximum number of streams have already been created.
-  QuicSpdyClientStream* GetOrCreateStream();
-
-  // Calls GetOrCreateStream(), sends the request on the stream, and
-  // stores the request in case it needs to be resent.  If |headers| is
-  // null, only the body will be sent on the stream.
-  ssize_t GetOrCreateStreamAndSendRequest(
-      const spdy::SpdyHeaderBlock* headers, absl::string_view body, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-          ack_listener);
-
-  QuicRstStreamErrorCode stream_error() { return stream_error_; }
-  QuicErrorCode connection_error() const;
-
-  MockableQuicClient* client() { return client_.get(); }
-  const MockableQuicClient* client() const { return client_.get(); }
-
-  // cert_common_name returns the common name value of the server's certificate,
-  // or the empty std::string if no certificate was presented.
-  const std::string& cert_common_name() const;
-
-  // cert_sct returns the signed timestamp of the server's certificate,
-  // or the empty std::string if no signed timestamp was presented.
-  const std::string& cert_sct() const;
-
-  // Get the server config map.  Server config must exist.
-  const QuicTagValueMap& GetServerConfig() const;
-
-  void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; }
-
-  void set_priority(spdy::SpdyPriority priority) { priority_ = priority; }
-
-  void WaitForWriteToFlush();
-
-  QuicEpollServer* epoll_server() { return &epoll_server_; }
-
-  size_t num_requests() const { return num_requests_; }
-
-  size_t num_responses() const { return num_responses_; }
-
-  void set_server_address(const QuicSocketAddress& server_address) {
-    client_->set_server_address(server_address);
-  }
-
-  void set_peer_address(const QuicSocketAddress& address) {
-    client_->set_peer_address(address);
-  }
-
-  // Explicitly set the SNI value for this client, overriding the default
-  // behavior which extracts the SNI value from the request URL.
-  void OverrideSni(const std::string& sni) {
-    override_sni_set_ = true;
-    override_sni_ = sni;
-  }
-
-  void Initialize();
-
-  void set_client(MockableQuicClient* client) { client_.reset(client); }
-
-  // Given |uri|, populates the fields in |headers| for a simple GET
-  // request. If |uri| is a relative URL, the QuicServerId will be
-  // use to specify the authority.
-  bool PopulateHeaderBlockFromUrl(const std::string& uri,
-                                  spdy::SpdyHeaderBlock* headers);
-
-  // Waits for a period of time that is long enough to receive all delayed acks
-  // sent by peer.
-  void WaitForDelayedAcks();
-
-  QuicSpdyClientStream* latest_created_stream() {
-    return latest_created_stream_;
-  }
-
- protected:
-  QuicTestClient();
-  QuicTestClient(const QuicTestClient&) = delete;
-  QuicTestClient(const QuicTestClient&&) = delete;
-  QuicTestClient& operator=(const QuicTestClient&) = delete;
-  QuicTestClient& operator=(const QuicTestClient&&) = delete;
-
- private:
-  class TestClientDataToResend : public QuicClient::QuicDataToResend {
-   public:
-    TestClientDataToResend(
-        std::unique_ptr<spdy::SpdyHeaderBlock> headers, absl::string_view body,
-        bool fin, QuicTestClient* test_client,
-        quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-            ack_listener);
-
-    ~TestClientDataToResend() override;
-
-    void Resend() override;
-
-   protected:
-    QuicTestClient* test_client_;
-    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-        ack_listener_;
-  };
-
-  // PerStreamState of a stream is updated when it is closed.
-  struct PerStreamState {
-    PerStreamState(const PerStreamState& other);
-    PerStreamState(QuicRstStreamErrorCode stream_error,
-                   bool response_complete,
-                   bool response_headers_complete,
-                   const spdy::SpdyHeaderBlock& response_headers,
-                   const spdy::SpdyHeaderBlock& preliminary_headers,
-                   const std::string& response,
-                   const spdy::SpdyHeaderBlock& response_trailers,
-                   uint64_t bytes_read,
-                   uint64_t bytes_written,
-                   int64_t response_body_size);
-    ~PerStreamState();
-
-    QuicRstStreamErrorCode stream_error;
-    bool response_complete;
-    bool response_headers_complete;
-    spdy::SpdyHeaderBlock response_headers;
-    spdy::SpdyHeaderBlock preliminary_headers;
-    std::string response;
-    spdy::SpdyHeaderBlock response_trailers;
-    uint64_t bytes_read;
-    uint64_t bytes_written;
-    int64_t response_body_size;
-  };
-
-  bool HaveActiveStream();
-
-  // Read oldest received response and remove it from closed_stream_states_.
-  void ReadNextResponse();
-
-  // Clear open_streams_, closed_stream_states_ and reset
-  // latest_created_stream_.
-  void ClearPerConnectionState();
-
-  // Update latest_created_stream_, add |stream| to open_streams_ and starts
-  // tracking its state.
-  void SetLatestCreatedStream(QuicSpdyClientStream* stream);
-
-  QuicEpollServer epoll_server_;
-  std::unique_ptr<MockableQuicClient> client_;  // The actual client
-  QuicSpdyClientStream* latest_created_stream_;
-  std::map<QuicStreamId, QuicSpdyClientStream*> open_streams_;
-  // Received responses of closed streams.
-  quiche::QuicheLinkedHashMap<QuicStreamId, PerStreamState>
-      closed_stream_states_;
-
-  QuicRstStreamErrorCode stream_error_;
-
-  bool response_complete_;
-  bool response_headers_complete_;
-  mutable spdy::SpdyHeaderBlock preliminary_headers_;
-  mutable spdy::SpdyHeaderBlock response_headers_;
-
-  // Parsed response trailers (if present), copied from the stream in OnClose.
-  spdy::SpdyHeaderBlock response_trailers_;
-
-  spdy::SpdyPriority priority_;
-  std::string response_;
-  // bytes_read_ and bytes_written_ are updated only when stream_ is released;
-  // prefer bytes_read() and bytes_written() member functions.
-  uint64_t bytes_read_;
-  uint64_t bytes_written_;
-  // The number of HTTP body bytes received.
-  int64_t response_body_size_;
-  // True if we tried to connect already since the last call to Disconnect().
-  bool connect_attempted_;
-  // The client will auto-connect exactly once before sending data.  If
-  // something causes a connection reset, it will not automatically reconnect
-  // unless auto_reconnect_ is true.
-  bool auto_reconnect_;
-  // Should we buffer the response body? Defaults to true.
-  bool buffer_body_;
-  // For async push promise rendezvous, validation may fail in which
-  // case the request should be retried.
-  std::unique_ptr<TestClientDataToResend> push_promise_data_to_resend_;
-  // Number of requests/responses this client has sent/received.
-  size_t num_requests_;
-  size_t num_responses_;
-
-  // If set, this value is used for the connection SNI, overriding the usual
-  // logic which extracts the SNI from the request URL.
-  bool override_sni_set_ = false;
-  std::string override_sni_;
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
diff --git a/quic/test_tools/quic_test_server.cc b/quic/test_tools/quic_test_server.cc
deleted file mode 100644
index e8aee79..0000000
--- a/quic/test_tools/quic_test_server.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_server.h"
-
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-namespace quic {
-
-namespace test {
-
-class CustomStreamSession : public QuicSimpleServerSession {
- public:
-  CustomStreamSession(
-      const QuicConfig& config,
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection,
-      QuicSession::Visitor* visitor,
-      QuicCryptoServerStreamBase::Helper* helper,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      QuicTestServer::StreamFactory* stream_factory,
-      QuicTestServer::CryptoStreamFactory* crypto_stream_factory,
-      QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicSimpleServerSession(config,
-                                supported_versions,
-                                connection,
-                                visitor,
-                                helper,
-                                crypto_config,
-                                compressed_certs_cache,
-                                quic_simple_server_backend),
-        stream_factory_(stream_factory),
-        crypto_stream_factory_(crypto_stream_factory) {}
-
-  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
-    if (!ShouldCreateIncomingStream(id)) {
-      return nullptr;
-    }
-    if (stream_factory_) {
-      QuicSpdyStream* stream =
-          stream_factory_->CreateStream(id, this, server_backend());
-      ActivateStream(absl::WrapUnique(stream));
-      return stream;
-    }
-    return QuicSimpleServerSession::CreateIncomingStream(id);
-  }
-
-  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache) override {
-    if (crypto_stream_factory_) {
-      return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
-    }
-    return QuicSimpleServerSession::CreateQuicCryptoServerStream(
-        crypto_config, compressed_certs_cache);
-  }
-
- private:
-  QuicTestServer::StreamFactory* stream_factory_;               // Not owned.
-  QuicTestServer::CryptoStreamFactory* crypto_stream_factory_;  // Not owned.
-};
-
-class QuicTestDispatcher : public QuicSimpleDispatcher {
- public:
-  QuicTestDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      QuicSimpleServerBackend* quic_simple_server_backend,
-      uint8_t expected_server_connection_id_length)
-      : QuicSimpleDispatcher(config,
-                             crypto_config,
-                             version_manager,
-                             std::move(helper),
-                             std::move(session_helper),
-                             std::move(alarm_factory),
-                             quic_simple_server_backend,
-                             expected_server_connection_id_length),
-        session_factory_(nullptr),
-        stream_factory_(nullptr),
-        crypto_stream_factory_(nullptr) {}
-
-  std::unique_ptr<QuicSession> CreateQuicSession(
-      QuicConnectionId id, const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
-      const ParsedQuicVersion& version,
-      const ParsedClientHello& /*parsed_chlo*/) override {
-    QuicReaderMutexLock lock(&factory_lock_);
-    // The QuicServerSessionBase takes ownership of |connection| below.
-    QuicConnection* connection = new QuicConnection(
-        id, self_address, peer_address, helper(), alarm_factory(), writer(),
-        /* owns_writer= */ false, Perspective::IS_SERVER,
-        ParsedQuicVersionVector{version});
-
-    std::unique_ptr<QuicServerSessionBase> session;
-    if (session_factory_ == nullptr && stream_factory_ == nullptr &&
-        crypto_stream_factory_ == nullptr) {
-      session = std::make_unique<QuicSimpleServerSession>(
-          config(), GetSupportedVersions(), connection, this, session_helper(),
-          crypto_config(), compressed_certs_cache(), server_backend());
-    } else if (stream_factory_ != nullptr ||
-               crypto_stream_factory_ != nullptr) {
-      session = std::make_unique<CustomStreamSession>(
-          config(), GetSupportedVersions(), connection, this, session_helper(),
-          crypto_config(), compressed_certs_cache(), stream_factory_,
-          crypto_stream_factory_, server_backend());
-    } else {
-      session = session_factory_->CreateSession(
-          config(), connection, this, session_helper(), crypto_config(),
-          compressed_certs_cache(), server_backend());
-    }
-    if (VersionUsesHttp3(version.transport_version) &&
-        GetQuicReloadableFlag(quic_verify_request_headers_2)) {
-      QUICHE_DCHECK(session->allow_extended_connect());
-      // Do not allow extended CONNECT request if the backend doesn't support
-      // it.
-      session->set_allow_extended_connect(
-          server_backend()->SupportsExtendedConnect());
-    }
-    session->Initialize();
-    return session;
-  }
-
-  void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
-    QuicWriterMutexLock lock(&factory_lock_);
-    QUICHE_DCHECK(session_factory_ == nullptr);
-    QUICHE_DCHECK(stream_factory_ == nullptr);
-    QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
-    session_factory_ = factory;
-  }
-
-  void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
-    QuicWriterMutexLock lock(&factory_lock_);
-    QUICHE_DCHECK(session_factory_ == nullptr);
-    QUICHE_DCHECK(stream_factory_ == nullptr);
-    stream_factory_ = factory;
-  }
-
-  void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
-    QuicWriterMutexLock lock(&factory_lock_);
-    QUICHE_DCHECK(session_factory_ == nullptr);
-    QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
-    crypto_stream_factory_ = factory;
-  }
-
- private:
-  QuicMutex factory_lock_;
-  QuicTestServer::SessionFactory* session_factory_;             // Not owned.
-  QuicTestServer::StreamFactory* stream_factory_;               // Not owned.
-  QuicTestServer::CryptoStreamFactory* crypto_stream_factory_;  // Not owned.
-};
-
-QuicTestServer::QuicTestServer(
-    std::unique_ptr<ProofSource> proof_source,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicServer(std::move(proof_source), quic_simple_server_backend) {}
-
-QuicTestServer::QuicTestServer(
-    std::unique_ptr<ProofSource> proof_source,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicTestServer(std::move(proof_source),
-                     config,
-                     supported_versions,
-                     quic_simple_server_backend,
-                     kQuicDefaultConnectionIdLength) {}
-
-QuicTestServer::QuicTestServer(
-    std::unique_ptr<ProofSource> proof_source,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicSimpleServerBackend* quic_simple_server_backend,
-    uint8_t expected_server_connection_id_length)
-    : QuicServer(std::move(proof_source),
-                 config,
-                 QuicCryptoServerConfig::ConfigOptions(),
-                 supported_versions,
-                 quic_simple_server_backend,
-                 expected_server_connection_id_length) {}
-
-QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
-  return new QuicTestDispatcher(
-      &config(), &crypto_config(), version_manager(),
-      std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
-                                                  QuicAllocator::BUFFER_POOL),
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
-          new QuicSimpleCryptoServerStreamHelper()),
-      std::make_unique<QuicEpollAlarmFactory>(epoll_server()), server_backend(),
-      expected_server_connection_id_length());
-}
-
-void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
-  QUICHE_DCHECK(dispatcher());
-  static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
-}
-
-void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
-  static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
-}
-
-void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
-  static_cast<QuicTestDispatcher*>(dispatcher())
-      ->SetCryptoStreamFactory(factory);
-}
-
-///////////////////////////   TEST SESSIONS ///////////////////////////////
-
-ImmediateGoAwaySession::ImmediateGoAwaySession(
-    const QuicConfig& config,
-    QuicConnection* connection,
-    QuicSession::Visitor* visitor,
-    QuicCryptoServerStreamBase::Helper* helper,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicSimpleServerSession(config,
-                              CurrentSupportedVersions(),
-                              connection,
-                              visitor,
-                              helper,
-                              crypto_config,
-                              compressed_certs_cache,
-                              quic_simple_server_backend) {}
-
-void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
-  if (VersionUsesHttp3(transport_version())) {
-    SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
-  } else {
-    SendGoAway(QUIC_PEER_GOING_AWAY, "");
-  }
-  QuicSimpleServerSession::OnStreamFrame(frame);
-}
-
-void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) {
-  // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. It's sent in a QUIC stream
-  // and requires encryption. Thus the sending is done in
-  // OnNewEncryptionKeyAvailable().
-  if (!VersionUsesHttp3(transport_version())) {
-    SendGoAway(QUIC_PEER_GOING_AWAY, "");
-  }
-  QuicSimpleServerSession::OnCryptoFrame(frame);
-}
-
-void ImmediateGoAwaySession::OnNewEncryptionKeyAvailable(
-    EncryptionLevel level,
-    std::unique_ptr<QuicEncrypter> encrypter) {
-  QuicSimpleServerSession::OnNewEncryptionKeyAvailable(level,
-                                                       std::move(encrypter));
-  if (VersionUsesHttp3(transport_version())) {
-    if (IsEncryptionEstablished() && !goaway_sent()) {
-      SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
-    }
-  }
-}
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/test_tools/quic_test_server.h b/quic/test_tools/quic_test_server.h
deleted file mode 100644
index 0539ee0..0000000
--- a/quic/test_tools/quic_test_server.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_session.h"
-#include "quic/tools/quic_server.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_simple_server_session.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-namespace quic {
-
-namespace test {
-
-// A test server which enables easy creation of custom QuicServerSessions
-//
-// Eventually this may be extended to allow custom QuicConnections etc.
-class QuicTestServer : public QuicServer {
- public:
-  // Factory for creating QuicServerSessions.
-  class SessionFactory {
-   public:
-    virtual ~SessionFactory() {}
-
-    // Returns a new session owned by the caller.
-    virtual std::unique_ptr<QuicServerSessionBase> CreateSession(
-        const QuicConfig& config,
-        QuicConnection* connection,
-        QuicSession::Visitor* visitor,
-        QuicCryptoServerStreamBase::Helper* helper,
-        const QuicCryptoServerConfig* crypto_config,
-        QuicCompressedCertsCache* compressed_certs_cache,
-        QuicSimpleServerBackend* quic_simple_server_backend) = 0;
-  };
-
-  // Factory for creating QuicSimpleServerStreams.
-  class StreamFactory {
-   public:
-    virtual ~StreamFactory() {}
-
-    // Returns a new stream owned by the caller.
-    virtual QuicSimpleServerStream* CreateStream(
-        QuicStreamId id,
-        QuicSpdySession* session,
-        QuicSimpleServerBackend* quic_simple_server_backend) = 0;
-
-    virtual QuicSimpleServerStream* CreateStream(
-        PendingStream* pending, QuicSpdySession* session,
-        QuicSimpleServerBackend* quic_simple_server_backend) = 0;
-  };
-
-  class CryptoStreamFactory {
-   public:
-    virtual ~CryptoStreamFactory() {}
-
-    // Returns a new QuicCryptoServerStreamBase owned by the caller
-    virtual std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoStream(
-        const QuicCryptoServerConfig* crypto_config,
-        QuicServerSessionBase* session) = 0;
-  };
-
-  QuicTestServer(std::unique_ptr<ProofSource> proof_source,
-                 QuicSimpleServerBackend* quic_simple_server_backend);
-  QuicTestServer(std::unique_ptr<ProofSource> proof_source,
-                 const QuicConfig& config,
-                 const ParsedQuicVersionVector& supported_versions,
-                 QuicSimpleServerBackend* quic_simple_server_backend);
-  QuicTestServer(std::unique_ptr<ProofSource> proof_source,
-                 const QuicConfig& config,
-                 const ParsedQuicVersionVector& supported_versions,
-                 QuicSimpleServerBackend* quic_simple_server_backend,
-                 uint8_t expected_server_connection_id_length);
-
-  // Create a custom dispatcher which creates custom sessions.
-  QuicDispatcher* CreateQuicDispatcher() override;
-
-  // Sets a custom session factory, owned by the caller, for easy custom
-  // session logic. This is incompatible with setting a stream factory or a
-  // crypto stream factory.
-  void SetSessionFactory(SessionFactory* factory);
-
-  // Sets a custom stream factory, owned by the caller, for easy custom
-  // stream logic. This is incompatible with setting a session factory.
-  void SetSpdyStreamFactory(StreamFactory* factory);
-
-  // Sets a custom crypto stream factory, owned by the caller, for easy custom
-  // crypto logic.  This is incompatible with setting a session factory.
-  void SetCryptoStreamFactory(CryptoStreamFactory* factory);
-};
-
-// Useful test sessions for the QuicTestServer.
-
-// Test session which sends a GOAWAY immedaitely on creation, before crypto
-// credentials have even been established.
-class ImmediateGoAwaySession : public QuicSimpleServerSession {
- public:
-  ImmediateGoAwaySession(const QuicConfig& config,
-                         QuicConnection* connection,
-                         QuicSession::Visitor* visitor,
-                         QuicCryptoServerStreamBase::Helper* helper,
-                         const QuicCryptoServerConfig* crypto_config,
-                         QuicCompressedCertsCache* compressed_certs_cache,
-                         QuicSimpleServerBackend* quic_simple_server_backend);
-
-  // Override to send GoAway.
-  void OnStreamFrame(const QuicStreamFrame& frame) override;
-  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  void OnNewEncryptionKeyAvailable(
-      EncryptionLevel level,
-      std::unique_ptr<QuicEncrypter> encrypter) override;
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
deleted file mode 100644
index 17804a1..0000000
--- a/quic/test_tools/quic_test_utils.cc
+++ /dev/null
@@ -1,1618 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_utils.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/strings/string_view.h"
-#include "third_party/boringssl/src/include/openssl/chacha.h"
-#include "third_party/boringssl/src/include/openssl/sha.h"
-#include "quic/core/crypto/crypto_framer.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_creator.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "common/quiche_buffer_allocator.h"
-#include "common/quiche_endian.h"
-#include "common/simple_buffer_allocator.h"
-#include "spdy/core/spdy_frame_builder.h"
-
-using testing::_;
-using testing::Invoke;
-
-namespace quic {
-namespace test {
-
-QuicConnectionId TestConnectionId() {
-  // Chosen by fair dice roll.
-  // Guaranteed to be random.
-  return TestConnectionId(42);
-}
-
-QuicConnectionId TestConnectionId(uint64_t connection_number) {
-  const uint64_t connection_id64_net =
-      quiche::QuicheEndian::HostToNet64(connection_number);
-  return QuicConnectionId(reinterpret_cast<const char*>(&connection_id64_net),
-                          sizeof(connection_id64_net));
-}
-
-QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number) {
-  const uint64_t connection_number_net =
-      quiche::QuicheEndian::HostToNet64(connection_number);
-  char connection_id_bytes[9] = {};
-  static_assert(
-      sizeof(connection_id_bytes) == 1 + sizeof(connection_number_net),
-      "bad lengths");
-  memcpy(connection_id_bytes + 1, &connection_number_net,
-         sizeof(connection_number_net));
-  return QuicConnectionId(connection_id_bytes, sizeof(connection_id_bytes));
-}
-
-uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id) {
-  QUICHE_DCHECK_EQ(connection_id.length(), kQuicDefaultConnectionIdLength);
-  uint64_t connection_id64_net = 0;
-  memcpy(&connection_id64_net, connection_id.data(),
-         std::min<size_t>(static_cast<size_t>(connection_id.length()),
-                          sizeof(connection_id64_net)));
-  return quiche::QuicheEndian::NetToHost64(connection_id64_net);
-}
-
-std::vector<uint8_t> CreateStatelessResetTokenForTest() {
-  static constexpr uint8_t kStatelessResetTokenDataForTest[16] = {
-      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
-  return std::vector<uint8_t>(kStatelessResetTokenDataForTest,
-                              kStatelessResetTokenDataForTest +
-                                  sizeof(kStatelessResetTokenDataForTest));
-}
-
-std::string TestHostname() { return "test.example.com"; }
-
-QuicServerId TestServerId() {
-  return QuicServerId(TestHostname(), kTestPort);
-}
-
-QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks) {
-  QUICHE_DCHECK_GT(ack_blocks.size(), 0u);
-
-  QuicAckFrame ack;
-  QuicPacketNumber end_of_previous_block(1);
-  for (const QuicAckBlock& block : ack_blocks) {
-    QUICHE_DCHECK_GE(block.start, end_of_previous_block);
-    QUICHE_DCHECK_GT(block.limit, block.start);
-    ack.packets.AddRange(block.start, block.limit);
-    end_of_previous_block = block.limit;
-  }
-
-  ack.largest_acked = ack.packets.Max();
-
-  return ack;
-}
-
-QuicAckFrame InitAckFrame(uint64_t largest_acked) {
-  return InitAckFrame(QuicPacketNumber(largest_acked));
-}
-
-QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked) {
-  return InitAckFrame({{QuicPacketNumber(1), largest_acked + 1}});
-}
-
-QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
-                                       uint64_t least_unacked) {
-  QuicAckFrame ack;
-  ack.largest_acked = QuicPacketNumber(2 * num_ack_blocks + least_unacked);
-  // Add enough received packets to get num_ack_blocks ack blocks.
-  for (QuicPacketNumber i = QuicPacketNumber(2);
-       i < QuicPacketNumber(2 * num_ack_blocks + 1); i += 2) {
-    ack.packets.Add(i + least_unacked);
-  }
-  return ack;
-}
-
-QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size,
-                                  size_t max_num_gaps,
-                                  uint64_t largest_acked) {
-  QuicAckFrame ack;
-  ack.largest_acked = QuicPacketNumber(largest_acked);
-  ack.packets.Add(QuicPacketNumber(largest_acked));
-  for (size_t i = 0; i < max_num_gaps; ++i) {
-    if (largest_acked <= gap_size) {
-      break;
-    }
-    largest_acked -= gap_size;
-    ack.packets.Add(QuicPacketNumber(largest_acked));
-  }
-  return ack;
-}
-
-EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header) {
-  if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
-    return ENCRYPTION_FORWARD_SECURE;
-  } else if (header.form == IETF_QUIC_LONG_HEADER_PACKET) {
-    if (header.long_packet_type == HANDSHAKE) {
-      return ENCRYPTION_HANDSHAKE;
-    } else if (header.long_packet_type == ZERO_RTT_PROTECTED) {
-      return ENCRYPTION_ZERO_RTT;
-    }
-  }
-  return ENCRYPTION_INITIAL;
-}
-
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
-    QuicFramer* framer,
-    const QuicPacketHeader& header,
-    const QuicFrames& frames) {
-  const size_t max_plaintext_size =
-      framer->GetMaxPlaintextSize(kMaxOutgoingPacketSize);
-  size_t packet_size = GetPacketHeaderSize(framer->transport_version(), header);
-  for (size_t i = 0; i < frames.size(); ++i) {
-    QUICHE_DCHECK_LE(packet_size, max_plaintext_size);
-    bool first_frame = i == 0;
-    bool last_frame = i == frames.size() - 1;
-    const size_t frame_size = framer->GetSerializedFrameLength(
-        frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
-        header.packet_number_length);
-    QUICHE_DCHECK(frame_size);
-    packet_size += frame_size;
-  }
-  return BuildUnsizedDataPacket(framer, header, frames, packet_size);
-}
-
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
-    QuicFramer* framer,
-    const QuicPacketHeader& header,
-    const QuicFrames& frames,
-    size_t packet_size) {
-  char* buffer = new char[packet_size];
-  EncryptionLevel level = HeaderToEncryptionLevel(header);
-  size_t length =
-      framer->BuildDataPacket(header, frames, buffer, packet_size, level);
-
-  if (length == 0) {
-    delete[] buffer;
-    return nullptr;
-  }
-  // Re-construct the data packet with data ownership.
-  return std::make_unique<QuicPacket>(
-      buffer, length, /* owns_buffer */ true,
-      GetIncludedDestinationConnectionIdLength(header),
-      GetIncludedSourceConnectionIdLength(header), header.version_flag,
-      header.nonce != nullptr, header.packet_number_length,
-      header.retry_token_length_length, header.retry_token.length(),
-      header.length_length);
-}
-
-std::string Sha1Hash(absl::string_view data) {
-  char buffer[SHA_DIGEST_LENGTH];
-  SHA1(reinterpret_cast<const uint8_t*>(data.data()), data.size(),
-       reinterpret_cast<uint8_t*>(buffer));
-  return std::string(buffer, ABSL_ARRAYSIZE(buffer));
-}
-
-bool ClearControlFrame(const QuicFrame& frame) {
-  DeleteFrame(&const_cast<QuicFrame&>(frame));
-  return true;
-}
-
-bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
-                                           TransmissionType /*type*/) {
-  return ClearControlFrame(frame);
-}
-
-uint64_t SimpleRandom::RandUint64() {
-  uint64_t result;
-  RandBytes(&result, sizeof(result));
-  return result;
-}
-
-void SimpleRandom::RandBytes(void* data, size_t len) {
-  uint8_t* data_bytes = reinterpret_cast<uint8_t*>(data);
-  while (len > 0) {
-    const size_t buffer_left = sizeof(buffer_) - buffer_offset_;
-    const size_t to_copy = std::min(buffer_left, len);
-    memcpy(data_bytes, buffer_ + buffer_offset_, to_copy);
-    data_bytes += to_copy;
-    buffer_offset_ += to_copy;
-    len -= to_copy;
-
-    if (buffer_offset_ == sizeof(buffer_)) {
-      FillBuffer();
-    }
-  }
-}
-
-void SimpleRandom::InsecureRandBytes(void* data, size_t len) {
-  RandBytes(data, len);
-}
-
-uint64_t SimpleRandom::InsecureRandUint64() {
-  return RandUint64();
-}
-
-void SimpleRandom::FillBuffer() {
-  uint8_t nonce[12];
-  memcpy(nonce, buffer_, sizeof(nonce));
-  CRYPTO_chacha_20(buffer_, buffer_, sizeof(buffer_), key_, nonce, 0);
-  buffer_offset_ = 0;
-}
-
-void SimpleRandom::set_seed(uint64_t seed) {
-  static_assert(sizeof(key_) == SHA256_DIGEST_LENGTH, "Key has to be 256 bits");
-  SHA256(reinterpret_cast<const uint8_t*>(&seed), sizeof(seed), key_);
-
-  memset(buffer_, 0, sizeof(buffer_));
-  FillBuffer();
-}
-
-MockFramerVisitor::MockFramerVisitor() {
-  // By default, we want to accept packets.
-  ON_CALL(*this, OnProtocolVersionMismatch(_))
-      .WillByDefault(testing::Return(false));
-
-  // By default, we want to accept packets.
-  ON_CALL(*this, OnUnauthenticatedHeader(_))
-      .WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnUnauthenticatedPublicHeader(_))
-      .WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnPacketHeader(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnStreamFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnCryptoFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnStopWaitingFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnPaddingFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnPingFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnRstStreamFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnConnectionCloseFrame(_))
-      .WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnStopSendingFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnPathChallengeFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnPathResponseFrame(_)).WillByDefault(testing::Return(true));
-
-  ON_CALL(*this, OnGoAwayFrame(_)).WillByDefault(testing::Return(true));
-  ON_CALL(*this, OnMaxStreamsFrame(_)).WillByDefault(testing::Return(true));
-  ON_CALL(*this, OnStreamsBlockedFrame(_)).WillByDefault(testing::Return(true));
-}
-
-MockFramerVisitor::~MockFramerVisitor() {}
-
-bool NoOpFramerVisitor::OnProtocolVersionMismatch(
-    ParsedQuicVersion /*version*/) {
-  return false;
-}
-
-bool NoOpFramerVisitor::OnUnauthenticatedPublicHeader(
-    const QuicPacketHeader& /*header*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnUnauthenticatedHeader(
-    const QuicPacketHeader& /*header*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
-  return true;
-}
-
-void NoOpFramerVisitor::OnCoalescedPacket(
-    const QuicEncryptedPacket& /*packet*/) {}
-
-void NoOpFramerVisitor::OnUndecryptablePacket(
-    const QuicEncryptedPacket& /*packet*/,
-    EncryptionLevel /*decryption_level*/,
-    bool /*has_decryption_key*/) {}
-
-bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
-                                        QuicTime::Delta /*ack_delay_time*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
-                                   QuicPacketNumber /*end*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
-                                       QuicTime /*timestamp*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnStopWaitingFrame(
-    const QuicStopWaitingFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnConnectionCloseFrame(
-    const QuicConnectionCloseFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnNewConnectionIdFrame(
-    const QuicNewConnectionIdFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnRetireConnectionIdFrame(
-    const QuicRetireConnectionIdFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnStopSendingFrame(
-    const QuicStopSendingFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnPathChallengeFrame(
-    const QuicPathChallengeFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnPathResponseFrame(
-    const QuicPathResponseFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnMaxStreamsFrame(
-    const QuicMaxStreamsFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnStreamsBlockedFrame(
-    const QuicStreamsBlockedFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnWindowUpdateFrame(
-    const QuicWindowUpdateFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnHandshakeDoneFrame(
-    const QuicHandshakeDoneFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::OnAckFrequencyFrame(
-    const QuicAckFrequencyFrame& /*frame*/) {
-  return true;
-}
-
-bool NoOpFramerVisitor::IsValidStatelessResetToken(
-    const StatelessResetToken& /*token*/) const {
-  return false;
-}
-
-MockQuicConnectionVisitor::MockQuicConnectionVisitor() {}
-
-MockQuicConnectionVisitor::~MockQuicConnectionVisitor() {}
-
-MockQuicConnectionHelper::MockQuicConnectionHelper() {}
-
-MockQuicConnectionHelper::~MockQuicConnectionHelper() {}
-
-const QuicClock* MockQuicConnectionHelper::GetClock() const {
-  return &clock_;
-}
-
-QuicRandom* MockQuicConnectionHelper::GetRandomGenerator() {
-  return &random_generator_;
-}
-
-QuicAlarm* MockAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
-  return new MockAlarmFactory::TestAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> MockAlarmFactory::CreateAlarm(
-    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-    QuicConnectionArena* arena) {
-  if (arena != nullptr) {
-    return arena->New<TestAlarm>(std::move(delegate));
-  } else {
-    return QuicArenaScopedPtr<TestAlarm>(new TestAlarm(std::move(delegate)));
-  }
-}
-
-quiche::QuicheBufferAllocator*
-MockQuicConnectionHelper::GetStreamSendBufferAllocator() {
-  return &buffer_allocator_;
-}
-
-void MockQuicConnectionHelper::AdvanceTime(QuicTime::Delta delta) {
-  clock_.AdvanceTime(delta);
-}
-
-MockQuicConnection::MockQuicConnection(MockQuicConnectionHelper* helper,
-                                       MockAlarmFactory* alarm_factory,
-                                       Perspective perspective)
-    : MockQuicConnection(TestConnectionId(),
-                         QuicSocketAddress(TestPeerIPAddress(), kTestPort),
-                         helper,
-                         alarm_factory,
-                         perspective,
-                         ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
-
-MockQuicConnection::MockQuicConnection(QuicSocketAddress address,
-                                       MockQuicConnectionHelper* helper,
-                                       MockAlarmFactory* alarm_factory,
-                                       Perspective perspective)
-    : MockQuicConnection(TestConnectionId(),
-                         address,
-                         helper,
-                         alarm_factory,
-                         perspective,
-                         ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
-
-MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id,
-                                       MockQuicConnectionHelper* helper,
-                                       MockAlarmFactory* alarm_factory,
-                                       Perspective perspective)
-    : MockQuicConnection(connection_id,
-                         QuicSocketAddress(TestPeerIPAddress(), kTestPort),
-                         helper,
-                         alarm_factory,
-                         perspective,
-                         ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
-
-MockQuicConnection::MockQuicConnection(
-    MockQuicConnectionHelper* helper,
-    MockAlarmFactory* alarm_factory,
-    Perspective perspective,
-    const ParsedQuicVersionVector& supported_versions)
-    : MockQuicConnection(TestConnectionId(),
-                         QuicSocketAddress(TestPeerIPAddress(), kTestPort),
-                         helper,
-                         alarm_factory,
-                         perspective,
-                         supported_versions) {}
-
-MockQuicConnection::MockQuicConnection(
-    QuicConnectionId connection_id,
-    QuicSocketAddress initial_peer_address,
-    MockQuicConnectionHelper* helper,
-    MockAlarmFactory* alarm_factory,
-    Perspective perspective,
-    const ParsedQuicVersionVector& supported_versions)
-    : QuicConnection(
-          connection_id,
-          /*initial_self_address=*/QuicSocketAddress(QuicIpAddress::Any4(), 5),
-          initial_peer_address,
-          helper,
-          alarm_factory,
-          new testing::NiceMock<MockPacketWriter>(),
-          /* owns_writer= */ true,
-          perspective,
-          supported_versions) {
-  ON_CALL(*this, OnError(_))
-      .WillByDefault(
-          Invoke(this, &PacketSavingConnection::QuicConnection_OnError));
-  ON_CALL(*this, SendCryptoData(_, _, _))
-      .WillByDefault(
-          Invoke(this, &MockQuicConnection::QuicConnection_SendCryptoData));
-
-  SetSelfAddress(QuicSocketAddress(QuicIpAddress::Any4(), 5));
-}
-
-MockQuicConnection::~MockQuicConnection() {}
-
-void MockQuicConnection::AdvanceTime(QuicTime::Delta delta) {
-  static_cast<MockQuicConnectionHelper*>(helper())->AdvanceTime(delta);
-}
-
-bool MockQuicConnection::OnProtocolVersionMismatch(
-    ParsedQuicVersion /*version*/) {
-  return false;
-}
-
-PacketSavingConnection::PacketSavingConnection(MockQuicConnectionHelper* helper,
-                                               MockAlarmFactory* alarm_factory,
-                                               Perspective perspective)
-    : MockQuicConnection(helper, alarm_factory, perspective) {}
-
-PacketSavingConnection::PacketSavingConnection(
-    MockQuicConnectionHelper* helper,
-    MockAlarmFactory* alarm_factory,
-    Perspective perspective,
-    const ParsedQuicVersionVector& supported_versions)
-    : MockQuicConnection(helper,
-                         alarm_factory,
-                         perspective,
-                         supported_versions) {}
-
-PacketSavingConnection::~PacketSavingConnection() {}
-
-void PacketSavingConnection::SendOrQueuePacket(SerializedPacket packet) {
-  encrypted_packets_.push_back(std::make_unique<QuicEncryptedPacket>(
-      CopyBuffer(packet), packet.encrypted_length, true));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  // Transfer ownership of the packet to the SentPacketManager and the
-  // ack notifier to the AckNotifierManager.
-  OnPacketSent(packet.encryption_level, packet.transmission_type);
-  QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent(
-      &packet, clock_.ApproximateNow(), NOT_RETRANSMISSION,
-      HAS_RETRANSMITTABLE_DATA, true);
-}
-
-MockQuicSession::MockQuicSession(QuicConnection* connection)
-    : MockQuicSession(connection, true) {}
-
-MockQuicSession::MockQuicSession(QuicConnection* connection,
-                                 bool create_mock_crypto_stream)
-    : QuicSession(connection,
-                  nullptr,
-                  DefaultQuicConfig(),
-                  connection->supported_versions(),
-                  /*num_expected_unidirectional_static_streams = */ 0) {
-  if (create_mock_crypto_stream) {
-    crypto_stream_ = std::make_unique<MockQuicCryptoStream>(this);
-  }
-  ON_CALL(*this, WritevData(_, _, _, _, _, _))
-      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
-}
-
-MockQuicSession::~MockQuicSession() {
-  DeleteConnection();
-}
-
-QuicCryptoStream* MockQuicSession::GetMutableCryptoStream() {
-  return crypto_stream_.get();
-}
-
-const QuicCryptoStream* MockQuicSession::GetCryptoStream() const {
-  return crypto_stream_.get();
-}
-
-void MockQuicSession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
-  crypto_stream_.reset(crypto_stream);
-}
-
-QuicConsumedData MockQuicSession::ConsumeData(
-    QuicStreamId id,
-    size_t write_length,
-    QuicStreamOffset offset,
-    StreamSendingState state,
-    TransmissionType /*type*/,
-    absl::optional<EncryptionLevel> /*level*/) {
-  if (write_length > 0) {
-    auto buf = std::make_unique<char[]>(write_length);
-    QuicStream* stream = GetOrCreateStream(id);
-    QUICHE_DCHECK(stream);
-    QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
-    stream->WriteStreamData(offset, write_length, &writer);
-  } else {
-    QUICHE_DCHECK(state != NO_FIN);
-  }
-  return QuicConsumedData(write_length, state != NO_FIN);
-}
-
-MockQuicCryptoStream::MockQuicCryptoStream(QuicSession* session)
-    : QuicCryptoStream(session), params_(new QuicCryptoNegotiatedParameters) {}
-
-MockQuicCryptoStream::~MockQuicCryptoStream() {}
-
-ssl_early_data_reason_t MockQuicCryptoStream::EarlyDataReason() const {
-  return ssl_early_data_unknown;
-}
-
-bool MockQuicCryptoStream::encryption_established() const {
-  return false;
-}
-
-bool MockQuicCryptoStream::one_rtt_keys_available() const {
-  return false;
-}
-
-const QuicCryptoNegotiatedParameters&
-MockQuicCryptoStream::crypto_negotiated_params() const {
-  return *params_;
-}
-
-CryptoMessageParser* MockQuicCryptoStream::crypto_message_parser() {
-  return &crypto_framer_;
-}
-
-MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
-    : MockQuicSpdySession(connection, true) {}
-
-MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection,
-                                         bool create_mock_crypto_stream)
-    : QuicSpdySession(connection,
-                      nullptr,
-                      DefaultQuicConfig(),
-                      connection->supported_versions()) {
-  if (create_mock_crypto_stream) {
-    crypto_stream_ = std::make_unique<MockQuicCryptoStream>(this);
-  }
-
-  ON_CALL(*this, WritevData(_, _, _, _, _, _))
-      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
-
-  ON_CALL(*this, SendWindowUpdate(_, _))
-      .WillByDefault([this](QuicStreamId id, QuicStreamOffset byte_offset) {
-        return QuicSpdySession::SendWindowUpdate(id, byte_offset);
-      });
-
-  ON_CALL(*this, SendBlocked(_)).WillByDefault([this](QuicStreamId id) {
-    return QuicSpdySession::SendBlocked(id);
-  });
-
-  ON_CALL(*this, OnCongestionWindowChange(_)).WillByDefault(testing::Return());
-}
-
-MockQuicSpdySession::~MockQuicSpdySession() {
-  DeleteConnection();
-}
-
-QuicCryptoStream* MockQuicSpdySession::GetMutableCryptoStream() {
-  return crypto_stream_.get();
-}
-
-const QuicCryptoStream* MockQuicSpdySession::GetCryptoStream() const {
-  return crypto_stream_.get();
-}
-
-void MockQuicSpdySession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
-  crypto_stream_.reset(crypto_stream);
-}
-
-QuicConsumedData MockQuicSpdySession::ConsumeData(
-    QuicStreamId id,
-    size_t write_length,
-    QuicStreamOffset offset,
-    StreamSendingState state,
-    TransmissionType /*type*/,
-    absl::optional<EncryptionLevel> /*level*/) {
-  if (write_length > 0) {
-    auto buf = std::make_unique<char[]>(write_length);
-    QuicStream* stream = GetOrCreateStream(id);
-    QUICHE_DCHECK(stream);
-    QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
-    stream->WriteStreamData(offset, write_length, &writer);
-  } else {
-    QUICHE_DCHECK(state != NO_FIN);
-  }
-  return QuicConsumedData(write_length, state != NO_FIN);
-}
-
-TestQuicSpdyServerSession::TestQuicSpdyServerSession(
-    QuicConnection* connection,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache)
-    : QuicServerSessionBase(config,
-                            supported_versions,
-                            connection,
-                            &visitor_,
-                            &helper_,
-                            crypto_config,
-                            compressed_certs_cache) {
-  ON_CALL(helper_, CanAcceptClientHello(_, _, _, _, _))
-      .WillByDefault(testing::Return(true));
-}
-
-TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {
-  DeleteConnection();
-}
-
-std::unique_ptr<QuicCryptoServerStreamBase>
-TestQuicSpdyServerSession::CreateQuicCryptoServerStream(
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache) {
-  return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
-                                  &helper_);
-}
-
-QuicCryptoServerStreamBase*
-TestQuicSpdyServerSession::GetMutableCryptoStream() {
-  return QuicServerSessionBase::GetMutableCryptoStream();
-}
-
-const QuicCryptoServerStreamBase* TestQuicSpdyServerSession::GetCryptoStream()
-    const {
-  return QuicServerSessionBase::GetCryptoStream();
-}
-
-TestQuicSpdyClientSession::TestQuicSpdyClientSession(
-    QuicConnection* connection,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicServerId& server_id,
-    QuicCryptoClientConfig* crypto_config)
-    : QuicSpdyClientSessionBase(connection,
-                                &push_promise_index_,
-                                config,
-                                supported_versions) {
-  // TODO(b/153726130): Consider adding SetServerApplicationStateForResumption
-  // calls in tests and set |has_application_state| to true.
-  crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
-      server_id, this, crypto_test_utils::ProofVerifyContextForTesting(),
-      crypto_config, this, /*has_application_state = */ false);
-  Initialize();
-  ON_CALL(*this, OnConfigNegotiated())
-      .WillByDefault(
-          Invoke(this, &TestQuicSpdyClientSession::RealOnConfigNegotiated));
-}
-
-TestQuicSpdyClientSession::~TestQuicSpdyClientSession() {}
-
-bool TestQuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
-  return true;
-}
-
-QuicCryptoClientStream* TestQuicSpdyClientSession::GetMutableCryptoStream() {
-  return crypto_stream_.get();
-}
-
-const QuicCryptoClientStream* TestQuicSpdyClientSession::GetCryptoStream()
-    const {
-  return crypto_stream_.get();
-}
-
-void TestQuicSpdyClientSession::RealOnConfigNegotiated() {
-  QuicSpdyClientSessionBase::OnConfigNegotiated();
-}
-
-TestPushPromiseDelegate::TestPushPromiseDelegate(bool match)
-    : match_(match), rendezvous_fired_(false), rendezvous_stream_(nullptr) {}
-
-bool TestPushPromiseDelegate::CheckVary(
-    const spdy::SpdyHeaderBlock& /*client_request*/,
-    const spdy::SpdyHeaderBlock& /*promise_request*/,
-    const spdy::SpdyHeaderBlock& /*promise_response*/) {
-  QUIC_DVLOG(1) << "match " << match_;
-  return match_;
-}
-
-void TestPushPromiseDelegate::OnRendezvousResult(QuicSpdyStream* stream) {
-  rendezvous_fired_ = true;
-  rendezvous_stream_ = stream;
-}
-
-MockPacketWriter::MockPacketWriter() {
-  ON_CALL(*this, GetMaxPacketSize(_))
-      .WillByDefault(testing::Return(kMaxOutgoingPacketSize));
-  ON_CALL(*this, IsBatchMode()).WillByDefault(testing::Return(false));
-  ON_CALL(*this, GetNextWriteLocation(_, _))
-      .WillByDefault(testing::Return(QuicPacketBuffer()));
-  ON_CALL(*this, Flush())
-      .WillByDefault(testing::Return(WriteResult(WRITE_STATUS_OK, 0)));
-  ON_CALL(*this, SupportsReleaseTime()).WillByDefault(testing::Return(false));
-}
-
-MockPacketWriter::~MockPacketWriter() {}
-
-MockSendAlgorithm::MockSendAlgorithm() {
-  ON_CALL(*this, PacingRate(_))
-      .WillByDefault(testing::Return(QuicBandwidth::Zero()));
-  ON_CALL(*this, BandwidthEstimate())
-      .WillByDefault(testing::Return(QuicBandwidth::Zero()));
-}
-
-MockSendAlgorithm::~MockSendAlgorithm() {}
-
-MockLossAlgorithm::MockLossAlgorithm() {}
-
-MockLossAlgorithm::~MockLossAlgorithm() {}
-
-MockAckListener::MockAckListener() {}
-
-MockAckListener::~MockAckListener() {}
-
-MockNetworkChangeVisitor::MockNetworkChangeVisitor() {}
-
-MockNetworkChangeVisitor::~MockNetworkChangeVisitor() {}
-
-QuicIpAddress TestPeerIPAddress() {
-  return QuicIpAddress::Loopback4();
-}
-
-ParsedQuicVersion QuicVersionMax() {
-  return AllSupportedVersions().front();
-}
-
-ParsedQuicVersion QuicVersionMin() {
-  return AllSupportedVersions().back();
-}
-
-void DisableQuicVersionsWithTls() {
-  for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
-    QuicDisableVersion(version);
-  }
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id,
-    bool version_flag,
-    bool reset_flag,
-    uint64_t packet_number,
-    const std::string& data) {
-  return ConstructEncryptedPacket(
-      destination_connection_id, source_connection_id, version_flag, reset_flag,
-      packet_number, data, CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
-      PACKET_4BYTE_PACKET_NUMBER);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id,
-    bool version_flag,
-    bool reset_flag,
-    uint64_t packet_number,
-    const std::string& data,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length) {
-  return ConstructEncryptedPacket(
-      destination_connection_id, source_connection_id, version_flag, reset_flag,
-      packet_number, data, destination_connection_id_included,
-      source_connection_id_included, packet_number_length, nullptr);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id,
-    bool version_flag,
-    bool reset_flag,
-    uint64_t packet_number,
-    const std::string& data,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersionVector* versions) {
-  return ConstructEncryptedPacket(
-      destination_connection_id, source_connection_id, version_flag, reset_flag,
-      packet_number, data, false, destination_connection_id_included,
-      source_connection_id_included, packet_number_length, versions,
-      Perspective::IS_CLIENT);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id,
-    bool version_flag,
-    bool reset_flag,
-    uint64_t packet_number,
-    const std::string& data,
-    bool full_padding,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersionVector* versions) {
-  return ConstructEncryptedPacket(
-      destination_connection_id, source_connection_id, version_flag, reset_flag,
-      packet_number, data, full_padding, destination_connection_id_included,
-      source_connection_id_included, packet_number_length, versions,
-      Perspective::IS_CLIENT);
-}
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id,
-    bool version_flag,
-    bool reset_flag,
-    uint64_t packet_number,
-    const std::string& data,
-    bool full_padding,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersionVector* versions,
-    Perspective perspective) {
-  QuicPacketHeader header;
-  header.destination_connection_id = destination_connection_id;
-  header.destination_connection_id_included =
-      destination_connection_id_included;
-  header.source_connection_id = source_connection_id;
-  header.source_connection_id_included = source_connection_id_included;
-  header.version_flag = version_flag;
-  header.reset_flag = reset_flag;
-  header.packet_number_length = packet_number_length;
-  header.packet_number = QuicPacketNumber(packet_number);
-  ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
-  if (!versions) {
-    versions = &supported_versions;
-  }
-  EXPECT_FALSE(versions->empty());
-  ParsedQuicVersion version = (*versions)[0];
-  if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
-      version_flag) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-
-  QuicFrames frames;
-  QuicFramer framer(*versions, QuicTime::Zero(), perspective,
-                    kQuicDefaultConnectionIdLength);
-  framer.SetInitialObfuscators(destination_connection_id);
-  EncryptionLevel level =
-      header.version_flag ? ENCRYPTION_INITIAL : ENCRYPTION_FORWARD_SECURE;
-  if (level != ENCRYPTION_INITIAL) {
-    framer.SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
-  }
-  if (!QuicVersionUsesCryptoFrames(version.transport_version)) {
-    QuicFrame frame(
-        QuicStreamFrame(QuicUtils::GetCryptoStreamId(version.transport_version),
-                        false, 0, absl::string_view(data)));
-    frames.push_back(frame);
-  } else {
-    QuicFrame frame(new QuicCryptoFrame(level, 0, data));
-    frames.push_back(frame);
-  }
-  if (full_padding) {
-    frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
-  } else {
-    // We need a minimum number of bytes of encrypted payload. This will
-    // guarantee that we have at least that much. (It ignores the overhead of
-    // the stream/crypto framing, so it overpads slightly.)
-    size_t min_plaintext_size =
-        QuicPacketCreator::MinPlaintextPacketSize(version);
-    if (data.length() < min_plaintext_size) {
-      size_t padding_length = min_plaintext_size - data.length();
-      frames.push_back(QuicFrame(QuicPaddingFrame(padding_length)));
-    }
-  }
-
-  std::unique_ptr<QuicPacket> packet(
-      BuildUnsizedDataPacket(&framer, header, frames));
-  EXPECT_TRUE(packet != nullptr);
-  char* buffer = new char[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer.EncryptPayload(level, QuicPacketNumber(packet_number), *packet,
-                            buffer, kMaxOutgoingPacketSize);
-  EXPECT_NE(0u, encrypted_length);
-  DeleteFrames(&frames);
-  return new QuicEncryptedPacket(buffer, encrypted_length, true);
-}
-
-std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
-    const ParsedQuicVersion& version,
-    const QuicConnectionId& server_connection_id) {
-  QuicPacketHeader header;
-  header.destination_connection_id = server_connection_id;
-  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
-  header.source_connection_id = EmptyQuicConnectionId();
-  header.source_connection_id_included = CONNECTION_ID_PRESENT;
-  if (!version.SupportsClientConnectionIds()) {
-    header.source_connection_id_included = CONNECTION_ID_ABSENT;
-  }
-  header.version_flag = true;
-  header.reset_flag = false;
-  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
-  header.packet_number = QuicPacketNumber(33);
-  header.long_packet_type = ZERO_RTT_PROTECTED;
-  if (version.HasLongHeaderLengths()) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-
-  QuicFrames frames;
-  frames.push_back(QuicFrame(QuicPingFrame()));
-  frames.push_back(QuicFrame(QuicPaddingFrame(100)));
-  QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_CLIENT,
-                    kQuicDefaultConnectionIdLength);
-  framer.SetInitialObfuscators(server_connection_id);
-
-  framer.SetEncrypter(ENCRYPTION_ZERO_RTT,
-                      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  std::unique_ptr<QuicPacket> packet(
-      BuildUnsizedDataPacket(&framer, header, frames));
-  EXPECT_TRUE(packet != nullptr);
-  char* buffer = new char[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer.EncryptPayload(ENCRYPTION_ZERO_RTT, header.packet_number, *packet,
-                            buffer, kMaxOutgoingPacketSize);
-  EXPECT_NE(0u, encrypted_length);
-  DeleteFrames(&frames);
-  return std::make_unique<QuicEncryptedPacket>(buffer, encrypted_length,
-                                               /*owns_buffer=*/true);
-}
-
-QuicReceivedPacket* ConstructReceivedPacket(
-    const QuicEncryptedPacket& encrypted_packet,
-    QuicTime receipt_time) {
-  char* buffer = new char[encrypted_packet.length()];
-  memcpy(buffer, encrypted_packet.data(), encrypted_packet.length());
-  return new QuicReceivedPacket(buffer, encrypted_packet.length(), receipt_time,
-                                true);
-}
-
-QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id,
-    bool version_flag,
-    bool reset_flag,
-    uint64_t packet_number,
-    const std::string& data,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersion version,
-    Perspective perspective) {
-  QuicPacketHeader header;
-  header.destination_connection_id = destination_connection_id;
-  header.destination_connection_id_included =
-      destination_connection_id_included;
-  header.source_connection_id = source_connection_id;
-  header.source_connection_id_included = source_connection_id_included;
-  header.version_flag = version_flag;
-  header.reset_flag = reset_flag;
-  header.packet_number_length = packet_number_length;
-  header.packet_number = QuicPacketNumber(packet_number);
-  if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
-      version_flag) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-  QuicFrame frame(QuicStreamFrame(1, false, 0, absl::string_view(data)));
-  QuicFrames frames;
-  frames.push_back(frame);
-  QuicFramer framer({version}, QuicTime::Zero(), perspective,
-                    kQuicDefaultConnectionIdLength);
-  framer.SetInitialObfuscators(destination_connection_id);
-  EncryptionLevel level =
-      version_flag ? ENCRYPTION_INITIAL : ENCRYPTION_FORWARD_SECURE;
-  if (level != ENCRYPTION_INITIAL) {
-    framer.SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
-  }
-  // We need a minimum of 7 bytes of encrypted payload. This will guarantee that
-  // we have at least that much. (It ignores the overhead of the stream/crypto
-  // framing, so it overpads slightly.)
-  if (data.length() < 7) {
-    size_t padding_length = 7 - data.length();
-    frames.push_back(QuicFrame(QuicPaddingFrame(padding_length)));
-  }
-
-  std::unique_ptr<QuicPacket> packet(
-      BuildUnsizedDataPacket(&framer, header, frames));
-  EXPECT_TRUE(packet != nullptr);
-
-  // Now set the frame type to 0x1F, which is an invalid frame type.
-  reinterpret_cast<unsigned char*>(
-      packet->mutable_data())[GetStartOfEncryptedData(
-      framer.transport_version(),
-      GetIncludedDestinationConnectionIdLength(header),
-      GetIncludedSourceConnectionIdLength(header), version_flag,
-      false /* no diversification nonce */, packet_number_length,
-      header.retry_token_length_length, 0, header.length_length)] = 0x1F;
-
-  char* buffer = new char[kMaxOutgoingPacketSize];
-  size_t encrypted_length =
-      framer.EncryptPayload(level, QuicPacketNumber(packet_number), *packet,
-                            buffer, kMaxOutgoingPacketSize);
-  EXPECT_NE(0u, encrypted_length);
-  return new QuicEncryptedPacket(buffer, encrypted_length, true);
-}
-
-QuicConfig DefaultQuicConfig() {
-  QuicConfig config;
-  config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-      kInitialStreamFlowControlWindowForTest);
-  config.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-      kInitialStreamFlowControlWindowForTest);
-  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
-      kInitialStreamFlowControlWindowForTest);
-  config.SetInitialStreamFlowControlWindowToSend(
-      kInitialStreamFlowControlWindowForTest);
-  config.SetInitialSessionFlowControlWindowToSend(
-      kInitialSessionFlowControlWindowForTest);
-  QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
-      &config, kDefaultMaxStreamsPerConnection);
-  // Default enable NSTP.
-  // This is unnecessary for versions > 44
-  if (!config.HasClientSentConnectionOption(quic::kNSTP,
-                                            quic::Perspective::IS_CLIENT)) {
-    quic::QuicTagVector connection_options;
-    connection_options.push_back(quic::kNSTP);
-    config.SetConnectionOptionsToSend(connection_options);
-  }
-  return config;
-}
-
-ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version) {
-  ParsedQuicVersionVector versions;
-  versions.push_back(version);
-  return versions;
-}
-
-MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {}
-
-MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {}
-
-MockReceivedPacketManager::MockReceivedPacketManager(QuicConnectionStats* stats)
-    : QuicReceivedPacketManager(stats) {}
-
-MockReceivedPacketManager::~MockReceivedPacketManager() {}
-
-MockPacketCreatorDelegate::MockPacketCreatorDelegate() {}
-MockPacketCreatorDelegate::~MockPacketCreatorDelegate() {}
-
-MockSessionNotifier::MockSessionNotifier() {}
-MockSessionNotifier::~MockSessionNotifier() {}
-
-// static
-QuicCryptoClientStream::HandshakerInterface*
-QuicCryptoClientStreamPeer::GetHandshaker(QuicCryptoClientStream* stream) {
-  return stream->handshaker_.get();
-}
-
-void CreateClientSessionForTest(
-    QuicServerId server_id,
-    QuicTime::Delta connection_start_time,
-    const ParsedQuicVersionVector& supported_versions,
-    MockQuicConnectionHelper* helper,
-    MockAlarmFactory* alarm_factory,
-    QuicCryptoClientConfig* crypto_client_config,
-    PacketSavingConnection** client_connection,
-    TestQuicSpdyClientSession** client_session) {
-  QUICHE_CHECK(crypto_client_config);
-  QUICHE_CHECK(client_connection);
-  QUICHE_CHECK(client_session);
-  QUICHE_CHECK(!connection_start_time.IsZero())
-      << "Connections must start at non-zero times, otherwise the "
-      << "strike-register will be unhappy.";
-
-  QuicConfig config = DefaultQuicConfig();
-  *client_connection = new PacketSavingConnection(
-      helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
-  *client_session = new TestQuicSpdyClientSession(*client_connection, config,
-                                                  supported_versions, server_id,
-                                                  crypto_client_config);
-  (*client_connection)->AdvanceTime(connection_start_time);
-}
-
-void CreateServerSessionForTest(
-    QuicServerId /*server_id*/,
-    QuicTime::Delta connection_start_time,
-    ParsedQuicVersionVector supported_versions,
-    MockQuicConnectionHelper* helper,
-    MockAlarmFactory* alarm_factory,
-    QuicCryptoServerConfig* server_crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    PacketSavingConnection** server_connection,
-    TestQuicSpdyServerSession** server_session) {
-  QUICHE_CHECK(server_crypto_config);
-  QUICHE_CHECK(server_connection);
-  QUICHE_CHECK(server_session);
-  QUICHE_CHECK(!connection_start_time.IsZero())
-      << "Connections must start at non-zero times, otherwise the "
-      << "strike-register will be unhappy.";
-
-  *server_connection =
-      new PacketSavingConnection(helper, alarm_factory, Perspective::IS_SERVER,
-                                 ParsedVersionOfIndex(supported_versions, 0));
-  *server_session = new TestQuicSpdyServerSession(
-      *server_connection, DefaultQuicConfig(), supported_versions,
-      server_crypto_config, compressed_certs_cache);
-  (*server_session)->Initialize();
-
-  // We advance the clock initially because the default time is zero and the
-  // strike register worries that we've just overflowed a uint32_t time.
-  (*server_connection)->AdvanceTime(connection_start_time);
-}
-
-QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
-    QuicTransportVersion version,
-    int n) {
-  int num = n;
-  if (!VersionUsesHttp3(version)) {
-    num++;
-  }
-  return QuicUtils::GetFirstBidirectionalStreamId(version,
-                                                  Perspective::IS_CLIENT) +
-         QuicUtils::StreamIdDelta(version) * num;
-}
-
-QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
-    QuicTransportVersion version,
-    int n) {
-  return QuicUtils::GetFirstBidirectionalStreamId(version,
-                                                  Perspective::IS_SERVER) +
-         QuicUtils::StreamIdDelta(version) * n;
-}
-
-QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
-    QuicTransportVersion version,
-    int n) {
-  return QuicUtils::GetFirstUnidirectionalStreamId(version,
-                                                   Perspective::IS_SERVER) +
-         QuicUtils::StreamIdDelta(version) * n;
-}
-
-QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
-    QuicTransportVersion version,
-    int n) {
-  return QuicUtils::GetFirstUnidirectionalStreamId(version,
-                                                   Perspective::IS_CLIENT) +
-         QuicUtils::StreamIdDelta(version) * n;
-}
-
-StreamType DetermineStreamType(QuicStreamId id,
-                               ParsedQuicVersion version,
-                               Perspective perspective,
-                               bool is_incoming,
-                               StreamType default_type) {
-  return version.HasIetfQuicFrames()
-             ? QuicUtils::GetStreamType(id, perspective, is_incoming, version)
-             : default_type;
-}
-
-quiche::QuicheMemSlice MemSliceFromString(absl::string_view data) {
-  if (data.empty()) {
-    return quiche::QuicheMemSlice();
-  }
-
-  static quiche::SimpleBufferAllocator* allocator =
-      new quiche::SimpleBufferAllocator();
-  return quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(allocator, data));
-}
-
-bool TaggingEncrypter::EncryptPacket(uint64_t /*packet_number*/,
-                                     absl::string_view /*associated_data*/,
-                                     absl::string_view plaintext,
-                                     char* output,
-                                     size_t* output_length,
-                                     size_t max_output_length) {
-  const size_t len = plaintext.size() + kTagSize;
-  if (max_output_length < len) {
-    return false;
-  }
-  // Memmove is safe for inplace encryption.
-  memmove(output, plaintext.data(), plaintext.size());
-  output += plaintext.size();
-  memset(output, tag_, kTagSize);
-  *output_length = len;
-  return true;
-}
-
-bool TaggingDecrypter::DecryptPacket(uint64_t /*packet_number*/,
-                                     absl::string_view /*associated_data*/,
-                                     absl::string_view ciphertext,
-                                     char* output,
-                                     size_t* output_length,
-                                     size_t /*max_output_length*/) {
-  if (ciphertext.size() < kTagSize) {
-    return false;
-  }
-  if (!CheckTag(ciphertext, GetTag(ciphertext))) {
-    return false;
-  }
-  *output_length = ciphertext.size() - kTagSize;
-  memcpy(output, ciphertext.data(), *output_length);
-  return true;
-}
-
-bool TaggingDecrypter::CheckTag(absl::string_view ciphertext, uint8_t tag) {
-  for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) {
-    if (ciphertext.data()[i] != tag) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-TestPacketWriter::TestPacketWriter(ParsedQuicVersion version,
-                                   MockClock* clock,
-                                   Perspective perspective)
-    : version_(version),
-      framer_(SupportedVersions(version_),
-              QuicUtils::InvertPerspective(perspective)),
-      clock_(clock) {
-  QuicFramerPeer::SetLastSerializedServerConnectionId(framer_.framer(),
-                                                      TestConnectionId());
-  framer_.framer()->SetInitialObfuscators(TestConnectionId());
-
-  for (int i = 0; i < 128; ++i) {
-    PacketBuffer* p = new PacketBuffer();
-    packet_buffer_pool_.push_back(p);
-    packet_buffer_pool_index_[p->buffer] = p;
-    packet_buffer_free_list_.push_back(p);
-  }
-}
-
-TestPacketWriter::~TestPacketWriter() {
-  EXPECT_EQ(packet_buffer_pool_.size(), packet_buffer_free_list_.size())
-      << packet_buffer_pool_.size() - packet_buffer_free_list_.size()
-      << " out of " << packet_buffer_pool_.size()
-      << " packet buffers have been leaked.";
-  for (auto p : packet_buffer_pool_) {
-    delete p;
-  }
-}
-
-WriteResult TestPacketWriter::WritePacket(const char* buffer,
-                                          size_t buf_len,
-                                          const QuicIpAddress& self_address,
-                                          const QuicSocketAddress& peer_address,
-                                          PerPacketOptions* /*options*/) {
-  last_write_source_address_ = self_address;
-  last_write_peer_address_ = peer_address;
-  // If the buffer is allocated from the pool, return it back to the pool.
-  // Note the buffer content doesn't change.
-  if (packet_buffer_pool_index_.find(const_cast<char*>(buffer)) !=
-      packet_buffer_pool_index_.end()) {
-    FreePacketBuffer(buffer);
-  }
-
-  QuicEncryptedPacket packet(buffer, buf_len);
-  ++packets_write_attempts_;
-
-  if (packet.length() >= sizeof(final_bytes_of_last_packet_)) {
-    final_bytes_of_previous_packet_ = final_bytes_of_last_packet_;
-    memcpy(&final_bytes_of_last_packet_, packet.data() + packet.length() - 4,
-           sizeof(final_bytes_of_last_packet_));
-  }
-
-  if (use_tagging_decrypter_) {
-    if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
-      framer_.framer()->InstallDecrypter(ENCRYPTION_INITIAL,
-                                         std::make_unique<TaggingDecrypter>());
-      framer_.framer()->InstallDecrypter(ENCRYPTION_HANDSHAKE,
-                                         std::make_unique<TaggingDecrypter>());
-      framer_.framer()->InstallDecrypter(ENCRYPTION_ZERO_RTT,
-                                         std::make_unique<TaggingDecrypter>());
-      framer_.framer()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                                         std::make_unique<TaggingDecrypter>());
-    } else {
-      framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
-                                     std::make_unique<TaggingDecrypter>());
-    }
-  } else if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
-    framer_.framer()->InstallDecrypter(
-        ENCRYPTION_HANDSHAKE,
-        std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
-    framer_.framer()->InstallDecrypter(
-        ENCRYPTION_ZERO_RTT,
-        std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
-    framer_.framer()->InstallDecrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
-  }
-  EXPECT_TRUE(framer_.ProcessPacket(packet))
-      << framer_.framer()->detailed_error() << " perspective "
-      << framer_.framer()->perspective();
-  if (block_on_next_write_) {
-    write_blocked_ = true;
-    block_on_next_write_ = false;
-  }
-  if (next_packet_too_large_) {
-    next_packet_too_large_ = false;
-    return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
-  }
-  if (always_get_packet_too_large_) {
-    return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
-  }
-  if (IsWriteBlocked()) {
-    return WriteResult(is_write_blocked_data_buffered_
-                           ? WRITE_STATUS_BLOCKED_DATA_BUFFERED
-                           : WRITE_STATUS_BLOCKED,
-                       0);
-  }
-
-  if (ShouldWriteFail()) {
-    return WriteResult(WRITE_STATUS_ERROR, write_error_code_);
-  }
-
-  last_packet_size_ = packet.length();
-  last_packet_header_ = framer_.header();
-  if (!framer_.connection_close_frames().empty()) {
-    ++connection_close_packets_;
-  }
-  if (!write_pause_time_delta_.IsZero()) {
-    clock_->AdvanceTime(write_pause_time_delta_);
-  }
-  if (is_batch_mode_) {
-    bytes_buffered_ += last_packet_size_;
-    return WriteResult(WRITE_STATUS_OK, 0);
-  }
-  return WriteResult(WRITE_STATUS_OK, last_packet_size_);
-}
-
-QuicPacketBuffer TestPacketWriter::GetNextWriteLocation(
-    const QuicIpAddress& /*self_address*/,
-    const QuicSocketAddress& /*peer_address*/) {
-  return {AllocPacketBuffer(), [this](const char* p) { FreePacketBuffer(p); }};
-}
-
-WriteResult TestPacketWriter::Flush() {
-  flush_attempts_++;
-  if (block_on_next_flush_) {
-    block_on_next_flush_ = false;
-    SetWriteBlocked();
-    return WriteResult(WRITE_STATUS_BLOCKED, /*errno*/ -1);
-  }
-  if (write_should_fail_) {
-    return WriteResult(WRITE_STATUS_ERROR, /*errno*/ -1);
-  }
-  int bytes_flushed = bytes_buffered_;
-  bytes_buffered_ = 0;
-  return WriteResult(WRITE_STATUS_OK, bytes_flushed);
-}
-
-char* TestPacketWriter::AllocPacketBuffer() {
-  PacketBuffer* p = packet_buffer_free_list_.front();
-  EXPECT_FALSE(p->in_use);
-  p->in_use = true;
-  packet_buffer_free_list_.pop_front();
-  return p->buffer;
-}
-
-void TestPacketWriter::FreePacketBuffer(const char* buffer) {
-  auto iter = packet_buffer_pool_index_.find(const_cast<char*>(buffer));
-  ASSERT_TRUE(iter != packet_buffer_pool_index_.end());
-  PacketBuffer* p = iter->second;
-  ASSERT_TRUE(p->in_use);
-  p->in_use = false;
-  packet_buffer_free_list_.push_back(p);
-}
-
-bool WriteServerVersionNegotiationProbeResponse(
-    char* packet_bytes,
-    size_t* packet_length_out,
-    const char* source_connection_id_bytes,
-    uint8_t source_connection_id_length) {
-  if (packet_bytes == nullptr) {
-    QUIC_BUG(quic_bug_10256_1) << "Invalid packet_bytes";
-    return false;
-  }
-  if (packet_length_out == nullptr) {
-    QUIC_BUG(quic_bug_10256_2) << "Invalid packet_length_out";
-    return false;
-  }
-  QuicConnectionId source_connection_id(source_connection_id_bytes,
-                                        source_connection_id_length);
-  std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
-      QuicFramer::BuildVersionNegotiationPacket(
-          source_connection_id, EmptyQuicConnectionId(),
-          /*ietf_quic=*/true, /*use_length_prefix=*/true,
-          ParsedQuicVersionVector{});
-  if (!encrypted_packet) {
-    QUIC_BUG(quic_bug_10256_3) << "Failed to create version negotiation packet";
-    return false;
-  }
-  if (*packet_length_out < encrypted_packet->length()) {
-    QUIC_BUG(quic_bug_10256_4)
-        << "Invalid *packet_length_out " << *packet_length_out << " < "
-        << encrypted_packet->length();
-    return false;
-  }
-  *packet_length_out = encrypted_packet->length();
-  memcpy(packet_bytes, encrypted_packet->data(), *packet_length_out);
-  return true;
-}
-
-bool ParseClientVersionNegotiationProbePacket(
-    const char* packet_bytes,
-    size_t packet_length,
-    char* destination_connection_id_bytes,
-    uint8_t* destination_connection_id_length_out) {
-  if (packet_bytes == nullptr) {
-    QUIC_BUG(quic_bug_10256_5) << "Invalid packet_bytes";
-    return false;
-  }
-  if (packet_length < kMinPacketSizeForVersionNegotiation ||
-      packet_length > 65535) {
-    QUIC_BUG(quic_bug_10256_6) << "Invalid packet_length";
-    return false;
-  }
-  if (destination_connection_id_bytes == nullptr) {
-    QUIC_BUG(quic_bug_10256_7) << "Invalid destination_connection_id_bytes";
-    return false;
-  }
-  if (destination_connection_id_length_out == nullptr) {
-    QUIC_BUG(quic_bug_10256_8)
-        << "Invalid destination_connection_id_length_out";
-    return false;
-  }
-
-  QuicEncryptedPacket encrypted_packet(packet_bytes, packet_length);
-  PacketHeaderFormat format;
-  QuicLongHeaderType long_packet_type;
-  bool version_present, has_length_prefix;
-  QuicVersionLabel version_label;
-  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
-  QuicConnectionId destination_connection_id, source_connection_id;
-  absl::optional<absl::string_view> retry_token;
-  std::string detailed_error;
-  QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
-      encrypted_packet,
-      /*expected_destination_connection_id_length=*/0, &format,
-      &long_packet_type, &version_present, &has_length_prefix, &version_label,
-      &parsed_version, &destination_connection_id, &source_connection_id,
-      &retry_token, &detailed_error);
-  if (error != QUIC_NO_ERROR) {
-    QUIC_BUG(quic_bug_10256_9) << "Failed to parse packet: " << detailed_error;
-    return false;
-  }
-  if (!version_present) {
-    QUIC_BUG(quic_bug_10256_10) << "Packet is not a long header";
-    return false;
-  }
-  if (*destination_connection_id_length_out <
-      destination_connection_id.length()) {
-    QUIC_BUG(quic_bug_10256_11)
-        << "destination_connection_id_length_out too small";
-    return false;
-  }
-  *destination_connection_id_length_out = destination_connection_id.length();
-  memcpy(destination_connection_id_bytes, destination_connection_id.data(),
-         *destination_connection_id_length_out);
-  return true;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
deleted file mode 100644
index ab5a8e7..0000000
--- a/quic/test_tools/quic_test_utils.h
+++ /dev/null
@@ -1,2036 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Common utilities for Quic tests
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/congestion_control/loss_detection_interface.h"
-#include "quic/core/congestion_control/send_algorithm_interface.h"
-#include "quic/core/crypto/transport_parameters.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_server_session_base.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_connection_id.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_sent_packet_manager.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/mock_random.h"
-#include "quic/test_tools/quic_framer_peer.h"
-#include "quic/test_tools/simple_quic_framer.h"
-#include "common/quiche_mem_slice_storage.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-
-namespace test {
-
-// A generic predictable connection ID suited for testing.
-QuicConnectionId TestConnectionId();
-
-// A generic predictable connection ID suited for testing, generated from a
-// given number, such as an index.
-QuicConnectionId TestConnectionId(uint64_t connection_number);
-
-// A generic predictable connection ID suited for testing, generated from a
-// given number, such as an index. Guaranteed to be 9 bytes long.
-QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number);
-
-// Extracts the connection number passed to TestConnectionId().
-uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id);
-
-enum : uint16_t { kTestPort = 12345 };
-enum : uint32_t {
-  kMaxDatagramFrameSizeForTest = 1333,
-  kMaxPacketSizeForTest = 9001,
-  kInitialStreamFlowControlWindowForTest = 1024 * 1024,   // 1 MB
-  kInitialSessionFlowControlWindowForTest = 1536 * 1024,  // 1.5 MB
-};
-
-enum : uint64_t {
-  kAckDelayExponentForTest = 10,
-  kMaxAckDelayForTest = 51,  // ms
-  kActiveConnectionIdLimitForTest = 52,
-  kMinAckDelayUsForTest = 1000
-};
-
-// Create an arbitrary stateless reset token, same across multiple calls.
-std::vector<uint8_t> CreateStatelessResetTokenForTest();
-
-// A hostname useful for testing, returns "test.example.org".
-std::string TestHostname();
-
-// A server ID useful for testing, returns test.example.org:12345.
-QuicServerId TestServerId();
-
-// Returns the test peer IP address.
-QuicIpAddress TestPeerIPAddress();
-
-// Upper limit on versions we support.
-ParsedQuicVersion QuicVersionMax();
-
-// Lower limit on versions we support.
-ParsedQuicVersion QuicVersionMin();
-
-// Disables all flags that enable QUIC versions that use TLS.
-// This is only meant as a temporary measure to prevent some broken tests
-// from running with TLS.
-void DisableQuicVersionsWithTls();
-
-// Create an encrypted packet for testing.
-// If versions == nullptr, uses &AllSupportedVersions().
-// Note that the packet is encrypted with NullEncrypter, so to decrypt the
-// constructed packet, the framer must be set to use NullDecrypter.
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
-    uint64_t packet_number, const std::string& data, bool full_padding,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersionVector* versions, Perspective perspective);
-
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
-    uint64_t packet_number, const std::string& data, bool full_padding,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersionVector* versions);
-
-// Create an encrypted packet for testing.
-// If versions == nullptr, uses &AllSupportedVersions().
-// Note that the packet is encrypted with NullEncrypter, so to decrypt the
-// constructed packet, the framer must be set to use NullDecrypter.
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
-    uint64_t packet_number, const std::string& data,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length,
-    ParsedQuicVersionVector* versions);
-
-// This form assumes |versions| == nullptr.
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
-    uint64_t packet_number, const std::string& data,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length);
-
-// This form assumes |connection_id_length| == PACKET_8BYTE_CONNECTION_ID,
-// |packet_number_length| == PACKET_4BYTE_PACKET_NUMBER and
-// |versions| == nullptr.
-QuicEncryptedPacket* ConstructEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
-    uint64_t packet_number, const std::string& data);
-
-// Creates a client-to-server ZERO-RTT packet that will fail to decrypt.
-std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
-    const ParsedQuicVersion& version,
-    const QuicConnectionId& server_connection_id);
-
-// Constructs a received packet for testing. The caller must take ownership
-// of the returned pointer.
-QuicReceivedPacket* ConstructReceivedPacket(
-    const QuicEncryptedPacket& encrypted_packet, QuicTime receipt_time);
-
-// Create an encrypted packet for testing whose data portion erroneous.
-// The specific way the data portion is erroneous is not specified, but
-// it is an error that QuicFramer detects.
-// Note that the packet is encrypted with NullEncrypter, so to decrypt the
-// constructed packet, the framer must be set to use NullDecrypter.
-QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
-    QuicConnectionId destination_connection_id,
-    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
-    uint64_t packet_number, const std::string& data,
-    QuicConnectionIdIncluded destination_connection_id_included,
-    QuicConnectionIdIncluded source_connection_id_included,
-    QuicPacketNumberLength packet_number_length, ParsedQuicVersion version,
-    Perspective perspective);
-
-// Returns QuicConfig set to default values.
-QuicConfig DefaultQuicConfig();
-
-ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version);
-
-struct QuicAckBlock {
-  QuicPacketNumber start;  // Included
-  QuicPacketNumber limit;  // Excluded
-};
-
-// Testing convenience method to construct a QuicAckFrame with arbitrary ack
-// blocks. Each block is given by a (closed-open) range of packet numbers. e.g.:
-// InitAckFrame({{1, 10}})
-//   => 1 ack block acking packet numbers 1 to 9.
-//
-// InitAckFrame({{1, 2}, {3, 4}})
-//   => 2 ack blocks acking packet 1 and 3. Packet 2 is missing.
-QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks);
-
-// Testing convenience method to construct a QuicAckFrame with 1 ack block which
-// covers packet number range [1, |largest_acked| + 1).
-// Equivalent to InitAckFrame({{1, largest_acked + 1}})
-QuicAckFrame InitAckFrame(uint64_t largest_acked);
-QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked);
-
-// Testing convenience method to construct a QuicAckFrame with |num_ack_blocks|
-// ack blocks of width 1 packet, starting from |least_unacked| + 2.
-QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
-                                       uint64_t least_unacked);
-
-// Testing convenice method to construct a QuicAckFrame with |largest_acked|,
-// ack blocks of width 1 packet and |gap_size|.
-QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size, size_t max_num_gaps,
-                                  uint64_t largest_acked);
-
-// Returns the encryption level that corresponds to the header type in
-// |header|. If the header is for GOOGLE_QUIC_PACKET instead of an
-// IETF-invariants packet, this function returns ENCRYPTION_INITIAL.
-EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header);
-
-// Returns a QuicPacket that is owned by the caller, and
-// is populated with the fields in |header| and |frames|, or is nullptr if the
-// packet could not be created.
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
-    QuicFramer* framer, const QuicPacketHeader& header,
-    const QuicFrames& frames);
-// Returns a QuicPacket that is owned by the caller, and of size |packet_size|.
-std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
-    QuicFramer* framer, const QuicPacketHeader& header,
-    const QuicFrames& frames, size_t packet_size);
-
-// Compute SHA-1 hash of the supplied std::string.
-std::string Sha1Hash(absl::string_view data);
-
-// Delete |frame| and return true.
-bool ClearControlFrame(const QuicFrame& frame);
-bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
-                                           TransmissionType type);
-
-// Simple random number generator used to compute random numbers suitable
-// for pseudo-randomly dropping packets in tests.
-class SimpleRandom : public QuicRandom {
- public:
-  SimpleRandom() { set_seed(0); }
-  SimpleRandom(const SimpleRandom&) = delete;
-  SimpleRandom& operator=(const SimpleRandom&) = delete;
-  ~SimpleRandom() override {}
-
-  // Generates |len| random bytes in the |data| buffer.
-  void RandBytes(void* data, size_t len) override;
-  // Returns a random number in the range [0, kuint64max].
-  uint64_t RandUint64() override;
-
-  // InsecureRandBytes behaves equivalently to RandBytes.
-  void InsecureRandBytes(void* data, size_t len) override;
-  // InsecureRandUint64 behaves equivalently to RandUint64.
-  uint64_t InsecureRandUint64() override;
-
-  void set_seed(uint64_t seed);
-
- private:
-  uint8_t buffer_[4096];
-  size_t buffer_offset_ = 0;
-  uint8_t key_[32];
-
-  void FillBuffer();
-};
-
-class MockFramerVisitor : public QuicFramerVisitorInterface {
- public:
-  MockFramerVisitor();
-  MockFramerVisitor(const MockFramerVisitor&) = delete;
-  MockFramerVisitor& operator=(const MockFramerVisitor&) = delete;
-  ~MockFramerVisitor() override;
-
-  MOCK_METHOD(void, OnError, (QuicFramer*), (override));
-  // The constructor sets this up to return false by default.
-  MOCK_METHOD(bool, OnProtocolVersionMismatch, (ParsedQuicVersion version),
-              (override));
-  MOCK_METHOD(void, OnPacket, (), (override));
-  MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket& header),
-              (override));
-  MOCK_METHOD(void, OnVersionNegotiationPacket,
-              (const QuicVersionNegotiationPacket& packet), (override));
-  MOCK_METHOD(void, OnRetryPacket,
-              (QuicConnectionId original_connection_id,
-               QuicConnectionId new_connection_id,
-               absl::string_view retry_token,
-               absl::string_view retry_integrity_tag,
-               absl::string_view retry_without_tag),
-              (override));
-  // The constructor sets this up to return true by default.
-  MOCK_METHOD(bool, OnUnauthenticatedHeader, (const QuicPacketHeader& header),
-              (override));
-  // The constructor sets this up to return true by default.
-  MOCK_METHOD(bool, OnUnauthenticatedPublicHeader,
-              (const QuicPacketHeader& header), (override));
-  MOCK_METHOD(void, OnDecryptedPacket, (size_t length, EncryptionLevel level),
-              (override));
-  MOCK_METHOD(bool, OnPacketHeader, (const QuicPacketHeader& header),
-              (override));
-  MOCK_METHOD(void, OnCoalescedPacket, (const QuicEncryptedPacket& packet),
-              (override));
-  MOCK_METHOD(void, OnUndecryptablePacket,
-              (const QuicEncryptedPacket& packet,
-               EncryptionLevel decryption_level, bool has_decryption_key),
-              (override));
-  MOCK_METHOD(bool, OnStreamFrame, (const QuicStreamFrame& frame), (override));
-  MOCK_METHOD(bool, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
-  MOCK_METHOD(bool, OnAckFrameStart, (QuicPacketNumber, QuicTime::Delta),
-              (override));
-  MOCK_METHOD(bool, OnAckRange, (QuicPacketNumber, QuicPacketNumber),
-              (override));
-  MOCK_METHOD(bool, OnAckTimestamp, (QuicPacketNumber, QuicTime), (override));
-  MOCK_METHOD(bool, OnAckFrameEnd, (QuicPacketNumber), (override));
-  MOCK_METHOD(bool, OnStopWaitingFrame, (const QuicStopWaitingFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnPaddingFrame, (const QuicPaddingFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnPingFrame, (const QuicPingFrame& frame), (override));
-  MOCK_METHOD(bool, OnRstStreamFrame, (const QuicRstStreamFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnConnectionCloseFrame,
-              (const QuicConnectionCloseFrame& frame), (override));
-  MOCK_METHOD(bool, OnNewConnectionIdFrame,
-              (const QuicNewConnectionIdFrame& frame), (override));
-  MOCK_METHOD(bool, OnRetireConnectionIdFrame,
-              (const QuicRetireConnectionIdFrame& frame), (override));
-  MOCK_METHOD(bool, OnNewTokenFrame, (const QuicNewTokenFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnPathChallengeFrame, (const QuicPathChallengeFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnGoAwayFrame, (const QuicGoAwayFrame& frame), (override));
-  MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnStreamsBlockedFrame,
-              (const QuicStreamsBlockedFrame& frame), (override));
-  MOCK_METHOD(bool, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnBlockedFrame, (const QuicBlockedFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnMessageFrame, (const QuicMessageFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnHandshakeDoneFrame, (const QuicHandshakeDoneFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnAckFrequencyFrame, (const QuicAckFrequencyFrame& frame),
-              (override));
-  MOCK_METHOD(void, OnPacketComplete, (), (override));
-  MOCK_METHOD(bool, IsValidStatelessResetToken, (const StatelessResetToken&),
-              (const, override));
-  MOCK_METHOD(void, OnAuthenticatedIetfStatelessResetPacket,
-              (const QuicIetfStatelessResetPacket&), (override));
-  MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
-  MOCK_METHOD(void, OnDecryptedFirstPacketInKeyPhase, (), (override));
-  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
-              AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
-  MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
-              (override));
-};
-
-class NoOpFramerVisitor : public QuicFramerVisitorInterface {
- public:
-  NoOpFramerVisitor() {}
-  NoOpFramerVisitor(const NoOpFramerVisitor&) = delete;
-  NoOpFramerVisitor& operator=(const NoOpFramerVisitor&) = delete;
-
-  void OnError(QuicFramer* /*framer*/) override {}
-  void OnPacket() override {}
-  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& /*packet*/) override {}
-  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
-                     QuicConnectionId /*new_connection_id*/,
-                     absl::string_view /*retry_token*/,
-                     absl::string_view /*retry_integrity_tag*/,
-                     absl::string_view /*retry_without_tag*/) override {}
-  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
-  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
-  void OnDecryptedPacket(size_t /*length*/,
-                         EncryptionLevel /*level*/) override {}
-  bool OnPacketHeader(const QuicPacketHeader& header) override;
-  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
-  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
-                             EncryptionLevel decryption_level,
-                             bool has_decryption_key) override;
-  bool OnStreamFrame(const QuicStreamFrame& frame) override;
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta ack_delay_time) override;
-  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
-  bool OnAckTimestamp(QuicPacketNumber packet_number,
-                      QuicTime timestamp) override;
-  bool OnAckFrameEnd(QuicPacketNumber start) override;
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
-  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
-  bool OnPingFrame(const QuicPingFrame& frame) override;
-  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
-  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
-  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) override;
-  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
-  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
-  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
-  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
-  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
-  bool OnMessageFrame(const QuicMessageFrame& frame) override;
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
-  void OnPacketComplete() override {}
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& token) const override;
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& /*packet*/) override {}
-  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
-  void OnDecryptedFirstPacketInKeyPhase() override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-};
-
-class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
- public:
-  MockQuicConnectionVisitor();
-  MockQuicConnectionVisitor(const MockQuicConnectionVisitor&) = delete;
-  MockQuicConnectionVisitor& operator=(const MockQuicConnectionVisitor&) =
-      delete;
-  ~MockQuicConnectionVisitor() override;
-
-  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
-  MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
-  MOCK_METHOD(void, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
-              (override));
-  MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame& frame),
-              (override));
-  MOCK_METHOD(void, OnRstStream, (const QuicRstStreamFrame& frame), (override));
-  MOCK_METHOD(void, OnGoAway, (const QuicGoAwayFrame& frame), (override));
-  MOCK_METHOD(void, OnMessageReceived, (absl::string_view message), (override));
-  MOCK_METHOD(void, OnHandshakeDoneReceived, (), (override));
-  MOCK_METHOD(void, OnNewTokenReceived, (absl::string_view token), (override));
-  MOCK_METHOD(void, OnConnectionClosed,
-              (const QuicConnectionCloseFrame& frame,
-               ConnectionCloseSource source),
-              (override));
-  MOCK_METHOD(void, OnWriteBlocked, (), (override));
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-  MOCK_METHOD(bool, SendProbingData, (), (override));
-  MOCK_METHOD(bool, ValidateStatelessReset,
-              (const quic::QuicSocketAddress&, const quic::QuicSocketAddress&),
-              (override));
-  MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
-  MOCK_METHOD(void, OnConnectionMigration, (AddressChangeType type),
-              (override));
-  MOCK_METHOD(void, OnPathDegrading, (), (override));
-  MOCK_METHOD(void, OnForwardProgressMadeAfterPathDegrading, (), (override));
-  MOCK_METHOD(bool, WillingAndAbleToWrite, (), (const, override));
-  MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
-  MOCK_METHOD(std::string, GetStreamsInfoForLogging, (), (const, override));
-  MOCK_METHOD(void, OnSuccessfulVersionNegotiation,
-              (const ParsedQuicVersion& version), (override));
-  MOCK_METHOD(void, OnPacketReceived,
-              (const QuicSocketAddress& self_address,
-               const QuicSocketAddress& peer_address,
-               bool is_connectivity_probe),
-              (override));
-  MOCK_METHOD(void, OnAckNeedsRetransmittableFrame, (), (override));
-  MOCK_METHOD(void, SendAckFrequency, (const QuicAckFrequencyFrame& frame),
-              (override));
-  MOCK_METHOD(void, SendNewConnectionId,
-              (const QuicNewConnectionIdFrame& frame), (override));
-  MOCK_METHOD(void, SendRetireConnectionId, (uint64_t sequence_number),
-              (override));
-  MOCK_METHOD(void, OnServerConnectionIdIssued,
-              (const QuicConnectionId& server_connection_id), (override));
-  MOCK_METHOD(void, OnServerConnectionIdRetired,
-              (const QuicConnectionId& server_connection_id), (override));
-  MOCK_METHOD(bool, AllowSelfAddressChange, (), (const, override));
-  MOCK_METHOD(HandshakeState, GetHandshakeState, (), (const, override));
-  MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
-              (override));
-  MOCK_METHOD(bool, OnStreamsBlockedFrame,
-              (const QuicStreamsBlockedFrame& frame), (override));
-  MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
-              (override));
-  MOCK_METHOD(void, OnPacketDecrypted, (EncryptionLevel), (override));
-  MOCK_METHOD(void, OnOneRttPacketAcknowledged, (), (override));
-  MOCK_METHOD(void, OnHandshakePacketSent, (), (override));
-  MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
-  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
-              AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
-  MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
-              (override));
-  MOCK_METHOD(void, BeforeConnectionCloseSent, (), (override));
-  MOCK_METHOD(bool, ValidateToken, (absl::string_view), (override));
-  MOCK_METHOD(bool, MaybeSendAddressToken, (), (override));
-
-  bool IsKnownServerAddress(
-      const QuicSocketAddress& /*address*/) const override {
-    return false;
-  }
-};
-
-class MockQuicConnectionHelper : public QuicConnectionHelperInterface {
- public:
-  MockQuicConnectionHelper();
-  MockQuicConnectionHelper(const MockQuicConnectionHelper&) = delete;
-  MockQuicConnectionHelper& operator=(const MockQuicConnectionHelper&) = delete;
-  ~MockQuicConnectionHelper() override;
-  const QuicClock* GetClock() const override;
-  QuicRandom* GetRandomGenerator() override;
-  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
-  void AdvanceTime(QuicTime::Delta delta);
-
- private:
-  MockClock clock_;
-  MockRandom random_generator_;
-  quiche::SimpleBufferAllocator buffer_allocator_;
-};
-
-class MockAlarmFactory : public QuicAlarmFactory {
- public:
-  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
-  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-      QuicConnectionArena* arena) override;
-
-  // No-op alarm implementation
-  class TestAlarm : public QuicAlarm {
-   public:
-    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
-        : QuicAlarm(std::move(delegate)) {}
-
-    void SetImpl() override {}
-    void CancelImpl() override {}
-
-    using QuicAlarm::Fire;
-  };
-
-  void FireAlarm(QuicAlarm* alarm) {
-    reinterpret_cast<TestAlarm*>(alarm)->Fire();
-  }
-};
-
-class TestAlarmFactory : public QuicAlarmFactory {
- public:
-  class TestAlarm : public QuicAlarm {
-   public:
-    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
-        : QuicAlarm(std::move(delegate)) {}
-
-    void SetImpl() override {}
-    void CancelImpl() override {}
-    using QuicAlarm::Fire;
-  };
-
-  TestAlarmFactory() {}
-  TestAlarmFactory(const TestAlarmFactory&) = delete;
-  TestAlarmFactory& operator=(const TestAlarmFactory&) = delete;
-
-  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
-    return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-  }
-
-  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-      QuicConnectionArena* arena) override {
-    return arena->New<TestAlarm>(std::move(delegate));
-  }
-};
-
-class MockQuicConnection : public QuicConnection {
- public:
-  // Uses a ConnectionId of 42 and 127.0.0.1:123.
-  MockQuicConnection(MockQuicConnectionHelper* helper,
-                     MockAlarmFactory* alarm_factory, Perspective perspective);
-
-  // Uses a ConnectionId of 42.
-  MockQuicConnection(QuicSocketAddress address,
-                     MockQuicConnectionHelper* helper,
-                     MockAlarmFactory* alarm_factory, Perspective perspective);
-
-  // Uses 127.0.0.1:123.
-  MockQuicConnection(QuicConnectionId connection_id,
-                     MockQuicConnectionHelper* helper,
-                     MockAlarmFactory* alarm_factory, Perspective perspective);
-
-  // Uses a ConnectionId of 42, and 127.0.0.1:123.
-  MockQuicConnection(MockQuicConnectionHelper* helper,
-                     MockAlarmFactory* alarm_factory, Perspective perspective,
-                     const ParsedQuicVersionVector& supported_versions);
-
-  MockQuicConnection(QuicConnectionId connection_id, QuicSocketAddress address,
-                     MockQuicConnectionHelper* helper,
-                     MockAlarmFactory* alarm_factory, Perspective perspective,
-                     const ParsedQuicVersionVector& supported_versions);
-  MockQuicConnection(const MockQuicConnection&) = delete;
-  MockQuicConnection& operator=(const MockQuicConnection&) = delete;
-
-  ~MockQuicConnection() override;
-
-  // If the constructor that uses a MockQuicConnectionHelper has been used then
-  // this method
-  // will advance the time of the MockClock.
-  void AdvanceTime(QuicTime::Delta delta);
-
-  MOCK_METHOD(void, ProcessUdpPacket,
-              (const QuicSocketAddress& self_address,
-               const QuicSocketAddress& peer_address,
-               const QuicReceivedPacket& packet),
-              (override));
-  MOCK_METHOD(void, CloseConnection,
-              (QuicErrorCode error, const std::string& details,
-               ConnectionCloseBehavior connection_close_behavior),
-              (override));
-  MOCK_METHOD(void, CloseConnection,
-              (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
-               const std::string& details,
-               ConnectionCloseBehavior connection_close_behavior),
-              (override));
-  MOCK_METHOD(void, SendConnectionClosePacket,
-              (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
-               const std::string& details),
-              (override));
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-  MOCK_METHOD(bool, SendConnectivityProbingPacket,
-              (QuicPacketWriter*, const QuicSocketAddress& peer_address),
-              (override));
-
-  MOCK_METHOD(void, OnSendConnectionState, (const CachedNetworkParameters&),
-              (override));
-  MOCK_METHOD(void, ResumeConnectionState,
-              (const CachedNetworkParameters&, bool), (override));
-  MOCK_METHOD(void, SetMaxPacingRate, (QuicBandwidth), (override));
-
-  MOCK_METHOD(void, OnStreamReset, (QuicStreamId, QuicRstStreamErrorCode),
-              (override));
-  MOCK_METHOD(bool, SendControlFrame, (const QuicFrame& frame), (override));
-  MOCK_METHOD(MessageStatus, SendMessage,
-              (QuicMessageId, absl::Span<quiche::QuicheMemSlice>, bool),
-              (override));
-  MOCK_METHOD(bool, SendPathChallenge,
-              (const QuicPathFrameBuffer&, const QuicSocketAddress&,
-               const QuicSocketAddress&, const QuicSocketAddress&,
-               QuicPacketWriter*),
-              (override));
-
-  MOCK_METHOD(void, OnError, (QuicFramer*), (override));
-  void QuicConnection_OnError(QuicFramer* framer) {
-    QuicConnection::OnError(framer);
-  }
-
-  void ReallyOnCanWrite() { QuicConnection::OnCanWrite(); }
-
-  void ReallyCloseConnection(
-      QuicErrorCode error, const std::string& details,
-      ConnectionCloseBehavior connection_close_behavior) {
-    // Call the 4-param method directly instead of the 3-param method, so that
-    // it doesn't invoke the virtual 4-param method causing the mock 4-param
-    // method to trigger.
-    QuicConnection::CloseConnection(error, NO_IETF_QUIC_ERROR, details,
-                                    connection_close_behavior);
-  }
-
-  void ReallyCloseConnection4(
-      QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
-      const std::string& details,
-      ConnectionCloseBehavior connection_close_behavior) {
-    QuicConnection::CloseConnection(error, ietf_error, details,
-                                    connection_close_behavior);
-  }
-
-  void ReallySendConnectionClosePacket(QuicErrorCode error,
-                                       QuicIetfTransportErrorCodes ietf_error,
-                                       const std::string& details) {
-    QuicConnection::SendConnectionClosePacket(error, ietf_error, details);
-  }
-
-  void ReallyProcessUdpPacket(const QuicSocketAddress& self_address,
-                              const QuicSocketAddress& peer_address,
-                              const QuicReceivedPacket& packet) {
-    QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
-  }
-
-  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
-
-  bool ReallySendControlFrame(const QuicFrame& frame) {
-    return QuicConnection::SendControlFrame(frame);
-  }
-
-  bool ReallySendConnectivityProbingPacket(
-      QuicPacketWriter* probing_writer, const QuicSocketAddress& peer_address) {
-    return QuicConnection::SendConnectivityProbingPacket(probing_writer,
-                                                         peer_address);
-  }
-
-  bool ReallyOnPathResponseFrame(const QuicPathResponseFrame& frame) {
-    return QuicConnection::OnPathResponseFrame(frame);
-  }
-
-  MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame&),
-              (override));
-  MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
-              (override));
-  MOCK_METHOD(size_t, SendCryptoData,
-              (EncryptionLevel, size_t, QuicStreamOffset), (override));
-  size_t QuicConnection_SendCryptoData(EncryptionLevel level,
-                                       size_t write_length,
-                                       QuicStreamOffset offset) {
-    return QuicConnection::SendCryptoData(level, write_length, offset);
-  }
-};
-
-class PacketSavingConnection : public MockQuicConnection {
- public:
-  PacketSavingConnection(MockQuicConnectionHelper* helper,
-                         MockAlarmFactory* alarm_factory,
-                         Perspective perspective);
-
-  PacketSavingConnection(MockQuicConnectionHelper* helper,
-                         MockAlarmFactory* alarm_factory,
-                         Perspective perspective,
-                         const ParsedQuicVersionVector& supported_versions);
-  PacketSavingConnection(const PacketSavingConnection&) = delete;
-  PacketSavingConnection& operator=(const PacketSavingConnection&) = delete;
-
-  ~PacketSavingConnection() override;
-
-  void SendOrQueuePacket(SerializedPacket packet) override;
-
-  MOCK_METHOD(void, OnPacketSent, (EncryptionLevel, TransmissionType));
-
-  std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_;
-  // Number of packets in encrypted_packets that has been delivered to the peer
-  // connection.
-  size_t number_of_packets_delivered_ = 0;
-  MockClock clock_;
-};
-
-class MockQuicSession : public QuicSession {
- public:
-  // Takes ownership of |connection|.
-  MockQuicSession(QuicConnection* connection, bool create_mock_crypto_stream);
-
-  // Takes ownership of |connection|.
-  explicit MockQuicSession(QuicConnection* connection);
-  MockQuicSession(const MockQuicSession&) = delete;
-  MockQuicSession& operator=(const MockQuicSession&) = delete;
-  ~MockQuicSession() override;
-
-  QuicCryptoStream* GetMutableCryptoStream() override;
-  const QuicCryptoStream* GetCryptoStream() const override;
-  void SetCryptoStream(QuicCryptoStream* crypto_stream);
-
-  MOCK_METHOD(void, OnConnectionClosed,
-              (const QuicConnectionCloseFrame& frame,
-               ConnectionCloseSource source),
-              (override));
-  MOCK_METHOD(QuicStream*, CreateIncomingStream, (QuicStreamId id), (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
-              (override));
-  MOCK_METHOD(QuicConsumedData, WritevData,
-              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
-               StreamSendingState state, TransmissionType type,
-               EncryptionLevel level),
-              (override));
-  MOCK_METHOD(bool, WriteControlFrame,
-              (const QuicFrame& frame, TransmissionType type), (override));
-  MOCK_METHOD(void, MaybeSendRstStreamFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error,
-               QuicStreamOffset bytes_written),
-              (override));
-  MOCK_METHOD(void, MaybeSendStopSendingFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error), (override));
-
-  MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
-  MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
-  MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
-              (const std::vector<absl::string_view>&), (const, override));
-  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
-
-  using QuicSession::ActivateStream;
-
-  // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
-  // if set) has been consumed.
-  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
-                               QuicStreamOffset offset,
-                               StreamSendingState state, TransmissionType type,
-                               absl::optional<EncryptionLevel> level);
-
-  void ReallyMaybeSendRstStreamFrame(QuicStreamId id,
-                                     QuicRstStreamErrorCode error,
-                                     QuicStreamOffset bytes_written) {
-    QuicSession::MaybeSendRstStreamFrame(
-        id, QuicResetStreamError::FromInternal(error), bytes_written);
-  }
-
- private:
-  std::unique_ptr<QuicCryptoStream> crypto_stream_;
-};
-
-class MockQuicCryptoStream : public QuicCryptoStream {
- public:
-  explicit MockQuicCryptoStream(QuicSession* session);
-
-  ~MockQuicCryptoStream() override;
-
-  ssl_early_data_reason_t EarlyDataReason() const override;
-  bool encryption_established() const override;
-  bool one_rtt_keys_available() const override;
-  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
-      const override;
-  CryptoMessageParser* crypto_message_parser() override;
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnHandshakeDoneReceived() override {}
-  void OnNewTokenReceived(absl::string_view /*token*/) override {}
-  std::string GetAddressToken(
-      const CachedNetworkParameters* /*cached_network_parameters*/)
-      const override {
-    return "";
-  }
-  bool ValidateAddressToken(absl::string_view /*token*/) const override {
-    return true;
-  }
-  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
-    return nullptr;
-  }
-  void SetPreviousCachedNetworkParams(
-      CachedNetworkParameters /*cached_network_params*/) override {}
-  void OnConnectionClosed(QuicErrorCode /*error*/,
-                          ConnectionCloseSource /*source*/) override {}
-  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
-  void SetServerApplicationStateForResumption(
-      std::unique_ptr<ApplicationState> /*application_state*/) override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-  bool ExportKeyingMaterial(absl::string_view /*label*/,
-                            absl::string_view /*context*/,
-                            size_t /*result_len*/,
-                            std::string* /*result*/) override {
-    return false;
-  }
-  SSL* GetSsl() const override { return nullptr; }
-
- private:
-  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
-  CryptoFramer crypto_framer_;
-};
-
-class MockQuicSpdySession : public QuicSpdySession {
- public:
-  // Takes ownership of |connection|.
-  explicit MockQuicSpdySession(QuicConnection* connection);
-  // Takes ownership of |connection|.
-  MockQuicSpdySession(QuicConnection* connection,
-                      bool create_mock_crypto_stream);
-  MockQuicSpdySession(const MockQuicSpdySession&) = delete;
-  MockQuicSpdySession& operator=(const MockQuicSpdySession&) = delete;
-  ~MockQuicSpdySession() override;
-
-  QuicCryptoStream* GetMutableCryptoStream() override;
-  const QuicCryptoStream* GetCryptoStream() const override;
-  void SetCryptoStream(QuicCryptoStream* crypto_stream);
-
-  void ReallyOnConnectionClosed(const QuicConnectionCloseFrame& frame,
-                                ConnectionCloseSource source) {
-    QuicSession::OnConnectionClosed(frame, source);
-  }
-
-  // From QuicSession.
-  MOCK_METHOD(void, OnConnectionClosed,
-              (const QuicConnectionCloseFrame& frame,
-               ConnectionCloseSource source),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
-              (override));
-  MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
-  MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
-  MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
-  MOCK_METHOD(QuicConsumedData, WritevData,
-              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
-               StreamSendingState state, TransmissionType type,
-               EncryptionLevel level),
-              (override));
-  MOCK_METHOD(void, MaybeSendRstStreamFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error,
-               QuicStreamOffset bytes_written),
-              (override));
-  MOCK_METHOD(void, MaybeSendStopSendingFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error), (override));
-  MOCK_METHOD(void, SendWindowUpdate,
-              (QuicStreamId id, QuicStreamOffset byte_offset), (override));
-  MOCK_METHOD(void, SendBlocked, (QuicStreamId id), (override));
-  MOCK_METHOD(void, OnStreamHeadersPriority,
-              (QuicStreamId stream_id,
-               const spdy::SpdyStreamPrecedence& precedence),
-              (override));
-  MOCK_METHOD(void, OnStreamHeaderList,
-              (QuicStreamId stream_id, bool fin, size_t frame_len,
-               const QuicHeaderList& header_list),
-              (override));
-  MOCK_METHOD(void, OnPromiseHeaderList,
-              (QuicStreamId stream_id, QuicStreamId promised_stream_id,
-               size_t frame_len, const QuicHeaderList& header_list),
-              (override));
-  MOCK_METHOD(void, OnPriorityFrame,
-              (QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence),
-              (override));
-  MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
-
-  // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
-  // if set) has been consumed.
-  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
-                               QuicStreamOffset offset,
-                               StreamSendingState state, TransmissionType type,
-                               absl::optional<EncryptionLevel> level);
-
-  using QuicSession::ActivateStream;
-
- private:
-  std::unique_ptr<QuicCryptoStream> crypto_stream_;
-};
-
-class MockHttp3DebugVisitor : public Http3DebugVisitor {
- public:
-  MOCK_METHOD(void, OnControlStreamCreated, (QuicStreamId), (override));
-  MOCK_METHOD(void, OnQpackEncoderStreamCreated, (QuicStreamId), (override));
-  MOCK_METHOD(void, OnQpackDecoderStreamCreated, (QuicStreamId), (override));
-  MOCK_METHOD(void, OnPeerControlStreamCreated, (QuicStreamId), (override));
-  MOCK_METHOD(void, OnPeerQpackEncoderStreamCreated, (QuicStreamId),
-              (override));
-  MOCK_METHOD(void, OnPeerQpackDecoderStreamCreated, (QuicStreamId),
-              (override));
-
-  MOCK_METHOD(void, OnSettingsFrameReceivedViaAlps, (const SettingsFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnAcceptChFrameReceivedViaAlps, (const AcceptChFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnSettingsFrameReceived, (const SettingsFrame&),
-              (override));
-  MOCK_METHOD(void, OnGoAwayFrameReceived, (const GoAwayFrame&), (override));
-  MOCK_METHOD(void, OnMaxPushIdFrameReceived, (const MaxPushIdFrame&),
-              (override));
-  MOCK_METHOD(void, OnPriorityUpdateFrameReceived, (const PriorityUpdateFrame&),
-              (override));
-  MOCK_METHOD(void, OnAcceptChFrameReceived, (const AcceptChFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnDataFrameReceived, (QuicStreamId, QuicByteCount),
-              (override));
-  MOCK_METHOD(void, OnHeadersFrameReceived, (QuicStreamId, QuicByteCount),
-              (override));
-  MOCK_METHOD(void, OnHeadersDecoded, (QuicStreamId, QuicHeaderList),
-              (override));
-  MOCK_METHOD(void, OnUnknownFrameReceived,
-              (QuicStreamId, uint64_t, QuicByteCount), (override));
-
-  MOCK_METHOD(void, OnSettingsFrameSent, (const SettingsFrame&), (override));
-  MOCK_METHOD(void, OnGoAwayFrameSent, (QuicStreamId), (override));
-  MOCK_METHOD(void, OnPriorityUpdateFrameSent, (const PriorityUpdateFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnDataFrameSent, (QuicStreamId, QuicByteCount), (override));
-  MOCK_METHOD(void, OnHeadersFrameSent,
-              (QuicStreamId, const spdy::SpdyHeaderBlock&), (override));
-};
-
-class TestQuicSpdyServerSession : public QuicServerSessionBase {
- public:
-  // Takes ownership of |connection|.
-  TestQuicSpdyServerSession(QuicConnection* connection,
-                            const QuicConfig& config,
-                            const ParsedQuicVersionVector& supported_versions,
-                            const QuicCryptoServerConfig* crypto_config,
-                            QuicCompressedCertsCache* compressed_certs_cache);
-  TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
-  TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
-      delete;
-  ~TestQuicSpdyServerSession() override;
-
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
-              (override));
-  MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
-              (const std::vector<absl::string_view>&), (const, override));
-  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
-  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache) override;
-
-  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
-
-  const QuicCryptoServerStreamBase* GetCryptoStream() const override;
-
-  MockQuicCryptoServerStreamHelper* helper() { return &helper_; }
-
-  QuicSSLConfig GetSSLConfig() const override {
-    QuicSSLConfig ssl_config = QuicServerSessionBase::GetSSLConfig();
-    if (early_data_enabled_.has_value()) {
-      ssl_config.early_data_enabled = *early_data_enabled_;
-    }
-    if (client_cert_mode_.has_value()) {
-      ssl_config.client_cert_mode = *client_cert_mode_;
-    }
-
-    return ssl_config;
-  }
-
-  void set_early_data_enabled(bool enabled) { early_data_enabled_ = enabled; }
-
-  void set_client_cert_mode(ClientCertMode mode) {
-    if (support_client_cert()) {
-      client_cert_mode_ = mode;
-    }
-  }
-
- private:
-  MockQuicSessionVisitor visitor_;
-  MockQuicCryptoServerStreamHelper helper_;
-  // If not nullopt, override the early_data_enabled value from base class'
-  // ssl_config.
-  absl::optional<bool> early_data_enabled_;
-  // If not nullopt, override the client_cert_mode value from base class'
-  // ssl_config.
-  absl::optional<ClientCertMode> client_cert_mode_;
-};
-
-// A test implementation of QuicClientPushPromiseIndex::Delegate.
-class TestPushPromiseDelegate : public QuicClientPushPromiseIndex::Delegate {
- public:
-  // |match| sets the validation result for checking whether designated header
-  // fields match for promise request and client request.
-  explicit TestPushPromiseDelegate(bool match);
-
-  bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
-                 const spdy::SpdyHeaderBlock& promise_request,
-                 const spdy::SpdyHeaderBlock& promise_response) override;
-
-  void OnRendezvousResult(QuicSpdyStream* stream) override;
-
-  QuicSpdyStream* rendezvous_stream() { return rendezvous_stream_; }
-  bool rendezvous_fired() { return rendezvous_fired_; }
-
- private:
-  bool match_;
-  bool rendezvous_fired_;
-  QuicSpdyStream* rendezvous_stream_;
-};
-
-class TestQuicSpdyClientSession : public QuicSpdyClientSessionBase {
- public:
-  TestQuicSpdyClientSession(QuicConnection* connection,
-                            const QuicConfig& config,
-                            const ParsedQuicVersionVector& supported_versions,
-                            const QuicServerId& server_id,
-                            QuicCryptoClientConfig* crypto_config);
-  TestQuicSpdyClientSession(const TestQuicSpdyClientSession&) = delete;
-  TestQuicSpdyClientSession& operator=(const TestQuicSpdyClientSession&) =
-      delete;
-  ~TestQuicSpdyClientSession() override;
-
-  bool IsAuthorized(const std::string& authority) override;
-
-  // QuicSpdyClientSessionBase
-  MOCK_METHOD(void, OnProofValid,
-              (const QuicCryptoClientConfig::CachedState& cached), (override));
-  MOCK_METHOD(void, OnProofVerifyDetailsAvailable,
-              (const ProofVerifyDetails& verify_details), (override));
-
-  // TestQuicSpdyClientSession
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
-              (override));
-  MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
-  MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
-  MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
-  MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
-  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
-  MOCK_METHOD(void, OnConfigNegotiated, (), (override));
-
-  QuicCryptoClientStream* GetMutableCryptoStream() override;
-  const QuicCryptoClientStream* GetCryptoStream() const override;
-
-  // Override to save sent crypto handshake messages.
-  void OnCryptoHandshakeMessageSent(
-      const CryptoHandshakeMessage& message) override {
-    sent_crypto_handshake_messages_.push_back(message);
-  }
-
-  const std::vector<CryptoHandshakeMessage>& sent_crypto_handshake_messages()
-      const {
-    return sent_crypto_handshake_messages_;
-  }
-
- private:
-  // Calls the parent class's OnConfigNegotiated method. Used to set the default
-  // mock behavior for OnConfigNegotiated.
-  void RealOnConfigNegotiated();
-
-  std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
-  QuicClientPushPromiseIndex push_promise_index_;
-  std::vector<CryptoHandshakeMessage> sent_crypto_handshake_messages_;
-};
-
-class MockPacketWriter : public QuicPacketWriter {
- public:
-  MockPacketWriter();
-  MockPacketWriter(const MockPacketWriter&) = delete;
-  MockPacketWriter& operator=(const MockPacketWriter&) = delete;
-  ~MockPacketWriter() override;
-
-  MOCK_METHOD(WriteResult, WritePacket,
-              (const char*, size_t buf_len, const QuicIpAddress& self_address,
-               const QuicSocketAddress& peer_address, PerPacketOptions*),
-              (override));
-  MOCK_METHOD(bool, IsWriteBlocked, (), (const, override));
-  MOCK_METHOD(void, SetWritable, (), (override));
-  MOCK_METHOD(absl::optional<int>, MessageTooBigErrorCode, (),
-              (const, override));
-  MOCK_METHOD(QuicByteCount, GetMaxPacketSize,
-              (const QuicSocketAddress& peer_address), (const, override));
-  MOCK_METHOD(bool, SupportsReleaseTime, (), (const, override));
-  MOCK_METHOD(bool, IsBatchMode, (), (const, override));
-  MOCK_METHOD(QuicPacketBuffer, GetNextWriteLocation,
-              (const QuicIpAddress& self_address,
-               const QuicSocketAddress& peer_address),
-              (override));
-  MOCK_METHOD(WriteResult, Flush, (), (override));
-};
-
-class MockSendAlgorithm : public SendAlgorithmInterface {
- public:
-  MockSendAlgorithm();
-  MockSendAlgorithm(const MockSendAlgorithm&) = delete;
-  MockSendAlgorithm& operator=(const MockSendAlgorithm&) = delete;
-  ~MockSendAlgorithm() override;
-
-  MOCK_METHOD(void, SetFromConfig,
-              (const QuicConfig& config, Perspective perspective), (override));
-  MOCK_METHOD(void, ApplyConnectionOptions,
-              (const QuicTagVector& connection_options), (override));
-  MOCK_METHOD(void, SetInitialCongestionWindowInPackets,
-              (QuicPacketCount packets), (override));
-  MOCK_METHOD(void, OnCongestionEvent,
-              (bool rtt_updated, QuicByteCount bytes_in_flight,
-               QuicTime event_time, const AckedPacketVector& acked_packets,
-               const LostPacketVector& lost_packets),
-              (override));
-  MOCK_METHOD(void, OnPacketSent,
-              (QuicTime, QuicByteCount, QuicPacketNumber, QuicByteCount,
-               HasRetransmittableData),
-              (override));
-  MOCK_METHOD(void, OnPacketNeutered, (QuicPacketNumber), (override));
-  MOCK_METHOD(void, OnRetransmissionTimeout, (bool), (override));
-  MOCK_METHOD(void, OnConnectionMigration, (), (override));
-  MOCK_METHOD(bool, CanSend, (QuicByteCount), (override));
-  MOCK_METHOD(QuicBandwidth, PacingRate, (QuicByteCount), (const, override));
-  MOCK_METHOD(QuicBandwidth, BandwidthEstimate, (), (const, override));
-  MOCK_METHOD(bool, HasGoodBandwidthEstimateForResumption, (),
-              (const, override));
-  MOCK_METHOD(QuicByteCount, GetCongestionWindow, (), (const, override));
-  MOCK_METHOD(std::string, GetDebugState, (), (const, override));
-  MOCK_METHOD(bool, InSlowStart, (), (const, override));
-  MOCK_METHOD(bool, InRecovery, (), (const, override));
-  MOCK_METHOD(bool, ShouldSendProbingPacket, (), (const, override));
-  MOCK_METHOD(QuicByteCount, GetSlowStartThreshold, (), (const, override));
-  MOCK_METHOD(CongestionControlType, GetCongestionControlType, (),
-              (const, override));
-  MOCK_METHOD(void, AdjustNetworkParameters, (const NetworkParams&),
-              (override));
-  MOCK_METHOD(void, OnApplicationLimited, (QuicByteCount), (override));
-  MOCK_METHOD(void, PopulateConnectionStats, (QuicConnectionStats*),
-              (const, override));
-};
-
-class MockLossAlgorithm : public LossDetectionInterface {
- public:
-  MockLossAlgorithm();
-  MockLossAlgorithm(const MockLossAlgorithm&) = delete;
-  MockLossAlgorithm& operator=(const MockLossAlgorithm&) = delete;
-  ~MockLossAlgorithm() override;
-
-  MOCK_METHOD(void, SetFromConfig,
-              (const QuicConfig& config, Perspective perspective), (override));
-
-  MOCK_METHOD(DetectionStats, DetectLosses,
-              (const QuicUnackedPacketMap& unacked_packets, QuicTime time,
-               const RttStats& rtt_stats,
-               QuicPacketNumber largest_recently_acked,
-               const AckedPacketVector& packets_acked, LostPacketVector*),
-              (override));
-  MOCK_METHOD(QuicTime, GetLossTimeout, (), (const, override));
-  MOCK_METHOD(void, SpuriousLossDetected,
-              (const QuicUnackedPacketMap&, const RttStats&, QuicTime,
-               QuicPacketNumber, QuicPacketNumber),
-              (override));
-
-  MOCK_METHOD(void, OnConfigNegotiated, (), (override));
-  MOCK_METHOD(void, OnMinRttAvailable, (), (override));
-  MOCK_METHOD(void, OnUserAgentIdKnown, (), (override));
-  MOCK_METHOD(void, OnConnectionClosed, (), (override));
-  MOCK_METHOD(void, OnReorderingDetected, (), (override));
-};
-
-class MockAckListener : public QuicAckListenerInterface {
- public:
-  MockAckListener();
-  MockAckListener(const MockAckListener&) = delete;
-  MockAckListener& operator=(const MockAckListener&) = delete;
-
-  MOCK_METHOD(void, OnPacketAcked,
-              (int acked_bytes, QuicTime::Delta ack_delay_time), (override));
-
-  MOCK_METHOD(void, OnPacketRetransmitted, (int retransmitted_bytes),
-              (override));
-
- protected:
-  // Object is ref counted.
-  ~MockAckListener() override;
-};
-
-class MockNetworkChangeVisitor
-    : public QuicSentPacketManager::NetworkChangeVisitor {
- public:
-  MockNetworkChangeVisitor();
-  MockNetworkChangeVisitor(const MockNetworkChangeVisitor&) = delete;
-  MockNetworkChangeVisitor& operator=(const MockNetworkChangeVisitor&) = delete;
-  ~MockNetworkChangeVisitor() override;
-
-  MOCK_METHOD(void, OnCongestionChange, (), (override));
-  MOCK_METHOD(void, OnPathMtuIncreased, (QuicPacketLength), (override));
-};
-
-class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
- public:
-  MockQuicConnectionDebugVisitor();
-  ~MockQuicConnectionDebugVisitor() override;
-
-  MOCK_METHOD(void, OnPacketSent,
-              (QuicPacketNumber, QuicPacketLength, bool, TransmissionType,
-               EncryptionLevel, const QuicFrames&, const QuicFrames&, QuicTime),
-              (override));
-
-  MOCK_METHOD(void, OnCoalescedPacketSent, (const QuicCoalescedPacket&, size_t),
-              (override));
-
-  MOCK_METHOD(void, OnPingSent, (), (override));
-
-  MOCK_METHOD(void, OnPacketReceived,
-              (const QuicSocketAddress&, const QuicSocketAddress&,
-               const QuicEncryptedPacket&),
-              (override));
-
-  MOCK_METHOD(void, OnIncorrectConnectionId, (QuicConnectionId), (override));
-
-  MOCK_METHOD(void, OnProtocolVersionMismatch, (ParsedQuicVersion), (override));
-
-  MOCK_METHOD(void, OnPacketHeader,
-              (const QuicPacketHeader& header, QuicTime receive_time,
-               EncryptionLevel level),
-              (override));
-
-  MOCK_METHOD(void, OnSuccessfulVersionNegotiation, (const ParsedQuicVersion&),
-              (override));
-
-  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame&), (override));
-
-  MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame&), (override));
-
-  MOCK_METHOD(void, OnStopWaitingFrame, (const QuicStopWaitingFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnRstStreamFrame, (const QuicRstStreamFrame&), (override));
-
-  MOCK_METHOD(void, OnConnectionCloseFrame, (const QuicConnectionCloseFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame&), (override));
-
-  MOCK_METHOD(void, OnNewConnectionIdFrame, (const QuicNewConnectionIdFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnRetireConnectionIdFrame,
-              (const QuicRetireConnectionIdFrame&), (override));
-
-  MOCK_METHOD(void, OnNewTokenFrame, (const QuicNewTokenFrame&), (override));
-
-  MOCK_METHOD(void, OnMessageFrame, (const QuicMessageFrame&), (override));
-
-  MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnPathChallengeFrame, (const QuicPathChallengeFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnPathResponseFrame, (const QuicPathResponseFrame&),
-              (override));
-
-  MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket&),
-              (override));
-
-  MOCK_METHOD(void, OnVersionNegotiationPacket,
-              (const QuicVersionNegotiationPacket&), (override));
-
-  MOCK_METHOD(void, OnTransportParametersSent, (const TransportParameters&),
-              (override));
-
-  MOCK_METHOD(void, OnTransportParametersReceived, (const TransportParameters&),
-              (override));
-
-  MOCK_METHOD(void, OnZeroRttRejected, (int), (override));
-  MOCK_METHOD(void, OnZeroRttPacketAcked, (), (override));
-};
-
-class MockReceivedPacketManager : public QuicReceivedPacketManager {
- public:
-  explicit MockReceivedPacketManager(QuicConnectionStats* stats);
-  ~MockReceivedPacketManager() override;
-
-  MOCK_METHOD(void, RecordPacketReceived,
-              (const QuicPacketHeader& header, QuicTime receipt_time),
-              (override));
-  MOCK_METHOD(bool, IsMissing, (QuicPacketNumber packet_number), (override));
-  MOCK_METHOD(bool, IsAwaitingPacket, (QuicPacketNumber packet_number),
-              (const, override));
-  MOCK_METHOD(bool, HasNewMissingPackets, (), (const, override));
-  MOCK_METHOD(bool, ack_frame_updated, (), (const, override));
-};
-
-class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
- public:
-  MockPacketCreatorDelegate();
-  MockPacketCreatorDelegate(const MockPacketCreatorDelegate&) = delete;
-  MockPacketCreatorDelegate& operator=(const MockPacketCreatorDelegate&) =
-      delete;
-  ~MockPacketCreatorDelegate() override;
-
-  MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
-  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
-  MOCK_METHOD(void, OnUnrecoverableError, (QuicErrorCode, const std::string&),
-              (override));
-  MOCK_METHOD(bool, ShouldGeneratePacket,
-              (HasRetransmittableData retransmittable, IsHandshake handshake),
-              (override));
-  MOCK_METHOD(const QuicFrames, MaybeBundleAckOpportunistically, (),
-              (override));
-  MOCK_METHOD(SerializedPacketFate, GetSerializedPacketFate,
-              (bool, EncryptionLevel), (override));
-};
-
-class MockSessionNotifier : public SessionNotifierInterface {
- public:
-  MockSessionNotifier();
-  ~MockSessionNotifier() override;
-
-  MOCK_METHOD(bool, OnFrameAcked, (const QuicFrame&, QuicTime::Delta, QuicTime),
-              (override));
-  MOCK_METHOD(void, OnStreamFrameRetransmitted, (const QuicStreamFrame&),
-              (override));
-  MOCK_METHOD(void, OnFrameLost, (const QuicFrame&), (override));
-  MOCK_METHOD(bool, RetransmitFrames,
-              (const QuicFrames&, TransmissionType type), (override));
-  MOCK_METHOD(bool, IsFrameOutstanding, (const QuicFrame&), (const, override));
-  MOCK_METHOD(bool, HasUnackedCryptoData, (), (const, override));
-  MOCK_METHOD(bool, HasUnackedStreamData, (), (const, override));
-};
-
-class MockQuicPathValidationContext : public QuicPathValidationContext {
- public:
-  MockQuicPathValidationContext(const QuicSocketAddress& self_address,
-                                const QuicSocketAddress& peer_address,
-                                const QuicSocketAddress& effective_peer_address,
-                                QuicPacketWriter* writer)
-      : QuicPathValidationContext(self_address, peer_address,
-                                  effective_peer_address),
-        writer_(writer) {}
-  QuicPacketWriter* WriterToUse() override { return writer_; }
-
- private:
-  QuicPacketWriter* writer_;
-};
-
-class MockQuicPathValidationResultDelegate
-    : public QuicPathValidator::ResultDelegate {
- public:
-  MOCK_METHOD(void, OnPathValidationSuccess,
-              (std::unique_ptr<QuicPathValidationContext>), (override));
-
-  MOCK_METHOD(void, OnPathValidationFailure,
-              (std::unique_ptr<QuicPathValidationContext>), (override));
-};
-
-class QuicCryptoClientStreamPeer {
- public:
-  QuicCryptoClientStreamPeer() = delete;
-
-  static QuicCryptoClientStream::HandshakerInterface* GetHandshaker(
-      QuicCryptoClientStream* stream);
-};
-
-// Creates a client session for testing.
-//
-// server_id: The server id associated with this stream.
-// connection_start_time: The time to set for the connection clock.
-//   Needed for strike-register nonce verification.  The client
-//   connection_start_time should be synchronized witht the server
-//   start time, otherwise nonce verification will fail.
-// supported_versions: Set of QUIC versions this client supports.
-// helper: Pointer to the MockQuicConnectionHelper to use for the session.
-// crypto_client_config: Pointer to the crypto client config.
-// client_connection: Pointer reference for newly created
-//   connection.  This object will be owned by the
-//   client_session.
-// client_session: Pointer reference for the newly created client
-//   session.  The new object will be owned by the caller.
-void CreateClientSessionForTest(
-    QuicServerId server_id, QuicTime::Delta connection_start_time,
-    const ParsedQuicVersionVector& supported_versions,
-    MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
-    QuicCryptoClientConfig* crypto_client_config,
-    PacketSavingConnection** client_connection,
-    TestQuicSpdyClientSession** client_session);
-
-// Creates a server session for testing.
-//
-// server_id: The server id associated with this stream.
-// connection_start_time: The time to set for the connection clock.
-//   Needed for strike-register nonce verification.  The server
-//   connection_start_time should be synchronized witht the client
-//   start time, otherwise nonce verification will fail.
-// supported_versions: Set of QUIC versions this server supports.
-// helper: Pointer to the MockQuicConnectionHelper to use for the session.
-// server_crypto_config: Pointer to the crypto server config.
-// server_connection: Pointer reference for newly created
-//   connection.  This object will be owned by the
-//   server_session.
-// server_session: Pointer reference for the newly created server
-//   session.  The new object will be owned by the caller.
-void CreateServerSessionForTest(
-    QuicServerId server_id, QuicTime::Delta connection_start_time,
-    ParsedQuicVersionVector supported_versions,
-    MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
-    QuicCryptoServerConfig* server_crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    PacketSavingConnection** server_connection,
-    TestQuicSpdyServerSession** server_session);
-
-// Verifies that the relative error of |actual| with respect to |expected| is
-// no more than |margin|.
-// Please use EXPECT_APPROX_EQ, a wrapper around this function, for better error
-// report.
-template <typename T>
-void ExpectApproxEq(T expected, T actual, float relative_margin) {
-  // If |relative_margin| > 1 and T is an unsigned type, the comparison will
-  // underflow.
-  ASSERT_LE(relative_margin, 1);
-  ASSERT_GE(relative_margin, 0);
-
-  T absolute_margin = expected * relative_margin;
-
-  EXPECT_GE(expected + absolute_margin, actual) << "actual value too big";
-  EXPECT_LE(expected - absolute_margin, actual) << "actual value too small";
-}
-
-#define EXPECT_APPROX_EQ(expected, actual, relative_margin)                    \
-  do {                                                                         \
-    SCOPED_TRACE(testing::Message() << "relative_margin:" << relative_margin); \
-    quic::test::ExpectApproxEq(expected, actual, relative_margin);             \
-  } while (0)
-
-template <typename T>
-QuicHeaderList AsHeaderList(const T& container) {
-  QuicHeaderList l;
-  l.OnHeaderBlockStart();
-  size_t total_size = 0;
-  for (auto p : container) {
-    total_size += p.first.size() + p.second.size();
-    l.OnHeader(p.first, p.second);
-  }
-  l.OnHeaderBlockEnd(total_size, total_size);
-  return l;
-}
-
-// Helper functions for stream ids, to allow test logic to abstract over the
-// HTTP stream numbering scheme (i.e. whether one or two QUIC streams are used
-// per HTTP transaction).
-QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
-    QuicTransportVersion version, int n);
-QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
-    QuicTransportVersion version, int n);
-QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
-    QuicTransportVersion version, int n);
-QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
-    QuicTransportVersion version, int n);
-
-StreamType DetermineStreamType(QuicStreamId id, ParsedQuicVersion version,
-                               Perspective perspective, bool is_incoming,
-                               StreamType default_type);
-
-// Creates a MemSlice using a singleton trivial buffer allocator.  Performs a
-// copy.
-quiche::QuicheMemSlice MemSliceFromString(absl::string_view data);
-
-// Used to compare ReceivedPacketInfo.
-MATCHER_P(ReceivedPacketInfoEquals, info, "") {
-  return info.ToString() == arg.ToString();
-}
-
-MATCHER_P(ReceivedPacketInfoConnectionIdEquals, destination_connection_id, "") {
-  return arg.destination_connection_id == destination_connection_id;
-}
-
-MATCHER_P2(InRange, min, max, "") { return arg >= min && arg <= max; }
-
-// A GMock matcher that prints expected and actual QuicErrorCode strings
-// upon failure.  Example usage:
-// EXPECT_THAT(stream_->connection_error(), IsError(QUIC_INTERNAL_ERROR));
-MATCHER_P(IsError, expected,
-          absl::StrCat(negation ? "isn't equal to " : "is equal to ",
-                       QuicErrorCodeToString(expected))) {
-  *result_listener << QuicErrorCodeToString(static_cast<QuicErrorCode>(arg));
-  return arg == expected;
-}
-
-// Shorthand for IsError(QUIC_NO_ERROR).
-// Example usage: EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
-MATCHER(IsQuicNoError,
-        absl::StrCat(negation ? "isn't equal to " : "is equal to ",
-                     QuicErrorCodeToString(QUIC_NO_ERROR))) {
-  *result_listener << QuicErrorCodeToString(arg);
-  return arg == QUIC_NO_ERROR;
-}
-
-// A GMock matcher that prints expected and actual QuicRstStreamErrorCode
-// strings upon failure.  Example usage:
-// EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_INTERNAL_ERROR));
-MATCHER_P(IsStreamError, expected,
-          absl::StrCat(negation ? "isn't equal to " : "is equal to ",
-                       QuicRstStreamErrorCodeToString(expected))) {
-  *result_listener << QuicRstStreamErrorCodeToString(arg);
-  return arg == expected;
-}
-
-// Shorthand for IsStreamError(QUIC_STREAM_NO_ERROR).  Example usage:
-// EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-MATCHER(IsQuicStreamNoError,
-        absl::StrCat(negation ? "isn't equal to " : "is equal to ",
-                     QuicRstStreamErrorCodeToString(QUIC_STREAM_NO_ERROR))) {
-  *result_listener << QuicRstStreamErrorCodeToString(arg);
-  return arg == QUIC_STREAM_NO_ERROR;
-}
-
-// TaggingEncrypter appends kTagSize bytes of |tag| to the end of each message.
-class TaggingEncrypter : public QuicEncrypter {
- public:
-  explicit TaggingEncrypter(uint8_t tag) : tag_(tag) {}
-  TaggingEncrypter(const TaggingEncrypter&) = delete;
-  TaggingEncrypter& operator=(const TaggingEncrypter&) = delete;
-
-  ~TaggingEncrypter() override {}
-
-  // QuicEncrypter interface.
-  bool SetKey(absl::string_view /*key*/) override { return true; }
-
-  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
-    return true;
-  }
-
-  bool SetIV(absl::string_view /*iv*/) override { return true; }
-
-  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
-    return true;
-  }
-
-  bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
-                     absl::string_view plaintext, char* output,
-                     size_t* output_length, size_t max_output_length) override;
-
-  std::string GenerateHeaderProtectionMask(
-      absl::string_view /*sample*/) override {
-    return std::string(5, 0);
-  }
-
-  size_t GetKeySize() const override { return 0; }
-  size_t GetNoncePrefixSize() const override { return 0; }
-  size_t GetIVSize() const override { return 0; }
-
-  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
-    return ciphertext_size - kTagSize;
-  }
-
-  size_t GetCiphertextSize(size_t plaintext_size) const override {
-    return plaintext_size + kTagSize;
-  }
-
-  QuicPacketCount GetConfidentialityLimit() const override {
-    return std::numeric_limits<QuicPacketCount>::max();
-  }
-
-  absl::string_view GetKey() const override { return absl::string_view(); }
-
-  absl::string_view GetNoncePrefix() const override {
-    return absl::string_view();
-  }
-
- private:
-  enum {
-    kTagSize = 12,
-  };
-
-  const uint8_t tag_;
-};
-
-// TaggingDecrypter ensures that the final kTagSize bytes of the message all
-// have the same value and then removes them.
-class TaggingDecrypter : public QuicDecrypter {
- public:
-  ~TaggingDecrypter() override {}
-
-  // QuicDecrypter interface
-  bool SetKey(absl::string_view /*key*/) override { return true; }
-
-  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
-    return true;
-  }
-
-  bool SetIV(absl::string_view /*iv*/) override { return true; }
-
-  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
-    return true;
-  }
-
-  bool SetPreliminaryKey(absl::string_view /*key*/) override {
-    QUIC_BUG(quic_bug_10230_1) << "should not be called";
-    return false;
-  }
-
-  bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
-    return true;
-  }
-
-  bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
-                     absl::string_view ciphertext, char* output,
-                     size_t* output_length, size_t max_output_length) override;
-
-  std::string GenerateHeaderProtectionMask(
-      QuicDataReader* /*sample_reader*/) override {
-    return std::string(5, 0);
-  }
-
-  size_t GetKeySize() const override { return 0; }
-  size_t GetNoncePrefixSize() const override { return 0; }
-  size_t GetIVSize() const override { return 0; }
-  absl::string_view GetKey() const override { return absl::string_view(); }
-  absl::string_view GetNoncePrefix() const override {
-    return absl::string_view();
-  }
-  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
-  uint32_t cipher_id() const override { return 0xFFFFFFF0; }
-  QuicPacketCount GetIntegrityLimit() const override {
-    return std::numeric_limits<QuicPacketCount>::max();
-  }
-
- protected:
-  virtual uint8_t GetTag(absl::string_view ciphertext) {
-    return ciphertext.data()[ciphertext.size() - 1];
-  }
-
- private:
-  enum {
-    kTagSize = 12,
-  };
-
-  bool CheckTag(absl::string_view ciphertext, uint8_t tag);
-};
-
-// StringTaggingDecrypter ensures that the final kTagSize bytes of the message
-// match the expected value.
-class StrictTaggingDecrypter : public TaggingDecrypter {
- public:
-  explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {}
-  ~StrictTaggingDecrypter() override {}
-
-  // TaggingQuicDecrypter
-  uint8_t GetTag(absl::string_view /*ciphertext*/) override { return tag_; }
-
-  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
-  uint32_t cipher_id() const override { return 0xFFFFFFF1; }
-
- private:
-  const uint8_t tag_;
-};
-
-class TestPacketWriter : public QuicPacketWriter {
-  struct PacketBuffer {
-    ABSL_CACHELINE_ALIGNED char buffer[1500];
-    bool in_use = false;
-  };
-
- public:
-  TestPacketWriter(ParsedQuicVersion version, MockClock* clock,
-                   Perspective perspective);
-
-  TestPacketWriter(const TestPacketWriter&) = delete;
-  TestPacketWriter& operator=(const TestPacketWriter&) = delete;
-
-  ~TestPacketWriter() override;
-
-  // QuicPacketWriter interface
-  WriteResult WritePacket(const char* buffer, size_t buf_len,
-                          const QuicIpAddress& self_address,
-                          const QuicSocketAddress& peer_address,
-                          PerPacketOptions* options) override;
-
-  bool ShouldWriteFail() { return write_should_fail_; }
-
-  bool IsWriteBlocked() const override { return write_blocked_; }
-
-  absl::optional<int> MessageTooBigErrorCode() const override { return 0x1234; }
-
-  void SetWriteBlocked() { write_blocked_ = true; }
-
-  void SetWritable() override { write_blocked_ = false; }
-
-  void SetShouldWriteFail() { write_should_fail_ = true; }
-
-  void SetWriteError(int error_code) { write_error_code_ = error_code; }
-
-  QuicByteCount GetMaxPacketSize(
-      const QuicSocketAddress& /*peer_address*/) const override {
-    return max_packet_size_;
-  }
-
-  bool SupportsReleaseTime() const override { return supports_release_time_; }
-
-  bool IsBatchMode() const override { return is_batch_mode_; }
-
-  QuicPacketBuffer GetNextWriteLocation(
-      const QuicIpAddress& /*self_address*/,
-      const QuicSocketAddress& /*peer_address*/) override;
-
-  WriteResult Flush() override;
-
-  void BlockOnNextFlush() { block_on_next_flush_ = true; }
-
-  void BlockOnNextWrite() { block_on_next_write_ = true; }
-
-  void SimulateNextPacketTooLarge() { next_packet_too_large_ = true; }
-
-  void AlwaysGetPacketTooLarge() { always_get_packet_too_large_ = true; }
-
-  // Sets the amount of time that the writer should before the actual write.
-  void SetWritePauseTimeDelta(QuicTime::Delta delta) {
-    write_pause_time_delta_ = delta;
-  }
-
-  void SetBatchMode(bool new_value) { is_batch_mode_ = new_value; }
-
-  const QuicPacketHeader& header() { return framer_.header(); }
-
-  size_t frame_count() const { return framer_.num_frames(); }
-
-  const std::vector<QuicAckFrame>& ack_frames() const {
-    return framer_.ack_frames();
-  }
-
-  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
-    return framer_.stop_waiting_frames();
-  }
-
-  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
-    return framer_.connection_close_frames();
-  }
-
-  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
-    return framer_.rst_stream_frames();
-  }
-
-  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
-    return framer_.stream_frames();
-  }
-
-  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
-    return framer_.crypto_frames();
-  }
-
-  const std::vector<QuicPingFrame>& ping_frames() const {
-    return framer_.ping_frames();
-  }
-
-  const std::vector<QuicMessageFrame>& message_frames() const {
-    return framer_.message_frames();
-  }
-
-  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
-    return framer_.window_update_frames();
-  }
-
-  const std::vector<QuicPaddingFrame>& padding_frames() const {
-    return framer_.padding_frames();
-  }
-
-  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
-    return framer_.path_challenge_frames();
-  }
-
-  const std::vector<QuicPathResponseFrame>& path_response_frames() const {
-    return framer_.path_response_frames();
-  }
-
-  const QuicEncryptedPacket* coalesced_packet() const {
-    return framer_.coalesced_packet();
-  }
-
-  size_t last_packet_size() { return last_packet_size_; }
-
-  const QuicPacketHeader& last_packet_header() const {
-    return last_packet_header_;
-  }
-
-  const QuicVersionNegotiationPacket* version_negotiation_packet() {
-    return framer_.version_negotiation_packet();
-  }
-
-  void set_is_write_blocked_data_buffered(bool buffered) {
-    is_write_blocked_data_buffered_ = buffered;
-  }
-
-  void set_perspective(Perspective perspective) {
-    // We invert perspective here, because the framer needs to parse packets
-    // we send.
-    QuicFramerPeer::SetPerspective(framer_.framer(),
-                                   QuicUtils::InvertPerspective(perspective));
-    framer_.framer()->SetInitialObfuscators(TestConnectionId());
-  }
-
-  // final_bytes_of_last_packet_ returns the last four bytes of the previous
-  // packet as a little-endian, uint32_t. This is intended to be used with a
-  // TaggingEncrypter so that tests can determine which encrypter was used for
-  // a given packet.
-  uint32_t final_bytes_of_last_packet() { return final_bytes_of_last_packet_; }
-
-  // Returns the final bytes of the second to last packet.
-  uint32_t final_bytes_of_previous_packet() {
-    return final_bytes_of_previous_packet_;
-  }
-
-  void use_tagging_decrypter() { use_tagging_decrypter_ = true; }
-
-  uint32_t packets_write_attempts() const { return packets_write_attempts_; }
-
-  uint32_t flush_attempts() const { return flush_attempts_; }
-
-  uint32_t connection_close_packets() const {
-    return connection_close_packets_;
-  }
-
-  void Reset() { framer_.Reset(); }
-
-  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
-    framer_.SetSupportedVersions(versions);
-  }
-
-  void set_max_packet_size(QuicByteCount max_packet_size) {
-    max_packet_size_ = max_packet_size;
-  }
-
-  void set_supports_release_time(bool supports_release_time) {
-    supports_release_time_ = supports_release_time;
-  }
-
-  SimpleQuicFramer* framer() { return &framer_; }
-
-  const QuicIpAddress& last_write_source_address() const {
-    return last_write_source_address_;
-  }
-
-  const QuicSocketAddress& last_write_peer_address() const {
-    return last_write_peer_address_;
-  }
-
- private:
-  char* AllocPacketBuffer();
-
-  void FreePacketBuffer(const char* buffer);
-
-  ParsedQuicVersion version_;
-  SimpleQuicFramer framer_;
-  size_t last_packet_size_ = 0;
-  QuicPacketHeader last_packet_header_;
-  bool write_blocked_ = false;
-  bool write_should_fail_ = false;
-  bool block_on_next_flush_ = false;
-  bool block_on_next_write_ = false;
-  bool next_packet_too_large_ = false;
-  bool always_get_packet_too_large_ = false;
-  bool is_write_blocked_data_buffered_ = false;
-  bool is_batch_mode_ = false;
-  // Number of times Flush() was called.
-  uint32_t flush_attempts_ = 0;
-  // (Batch mode only) Number of bytes buffered in writer. It is used as the
-  // return value of a successful Flush().
-  uint32_t bytes_buffered_ = 0;
-  uint32_t final_bytes_of_last_packet_ = 0;
-  uint32_t final_bytes_of_previous_packet_ = 0;
-  bool use_tagging_decrypter_ = false;
-  uint32_t packets_write_attempts_ = 0;
-  uint32_t connection_close_packets_ = 0;
-  MockClock* clock_ = nullptr;
-  // If non-zero, the clock will pause during WritePacket for this amount of
-  // time.
-  QuicTime::Delta write_pause_time_delta_ = QuicTime::Delta::Zero();
-  QuicByteCount max_packet_size_ = kMaxOutgoingPacketSize;
-  bool supports_release_time_ = false;
-  // Used to verify writer-allocated packet buffers are properly released.
-  std::vector<PacketBuffer*> packet_buffer_pool_;
-  // Buffer address => Address of the owning PacketBuffer.
-  absl::flat_hash_map<char*, PacketBuffer*, absl::Hash<char*>>
-      packet_buffer_pool_index_;
-  // Indices in packet_buffer_pool_ that are not allocated.
-  std::list<PacketBuffer*> packet_buffer_free_list_;
-  // The soruce/peer address passed into WritePacket().
-  QuicIpAddress last_write_source_address_;
-  QuicSocketAddress last_write_peer_address_;
-  int write_error_code_{0};
-};
-
-// Parses a packet generated by
-// QuicFramer::WriteClientVersionNegotiationProbePacket.
-// |packet_bytes| must point to |packet_length| bytes in memory which represent
-// the packet. This method will fill in |destination_connection_id_bytes|
-// which must point to at least |*destination_connection_id_length_out| bytes in
-// memory. |*destination_connection_id_length_out| will contain the length of
-// the received destination connection ID, which on success will match the
-// contents of the destination connection ID passed in to
-// WriteClientVersionNegotiationProbePacket.
-bool ParseClientVersionNegotiationProbePacket(
-    const char* packet_bytes, size_t packet_length,
-    char* destination_connection_id_bytes,
-    uint8_t* destination_connection_id_length_out);
-
-// Writes an array of bytes that correspond to a QUIC version negotiation packet
-// that a QUIC server would send in response to a probe created by
-// QuicFramer::WriteClientVersionNegotiationProbePacket.
-// The bytes will be written to |packet_bytes|, which must point to
-// |*packet_length_out| bytes of memory. |*packet_length_out| will contain the
-// length of the created packet. |source_connection_id_bytes| will be sent as
-// the source connection ID, and must point to |source_connection_id_length|
-// bytes of memory.
-bool WriteServerVersionNegotiationProbeResponse(
-    char* packet_bytes, size_t* packet_length_out,
-    const char* source_connection_id_bytes,
-    uint8_t source_connection_id_length);
-
-// Implementation of Http3DatagramVisitor which saves all received datagrams.
-class SavingHttp3DatagramVisitor : public QuicSpdyStream::Http3DatagramVisitor {
- public:
-  struct SavedHttp3Datagram {
-    QuicStreamId stream_id;
-    absl::optional<QuicDatagramContextId> context_id;
-    std::string payload;
-    bool operator==(const SavedHttp3Datagram& o) const {
-      return stream_id == o.stream_id && context_id == o.context_id &&
-             payload == o.payload;
-    }
-  };
-  const std::vector<SavedHttp3Datagram>& received_h3_datagrams() const {
-    return received_h3_datagrams_;
-  }
-
-  // Override from QuicSpdyStream::Http3DatagramVisitor.
-  void OnHttp3Datagram(QuicStreamId stream_id,
-                       absl::optional<QuicDatagramContextId> context_id,
-                       absl::string_view payload) override {
-    received_h3_datagrams_.push_back(
-        SavedHttp3Datagram{stream_id, context_id, std::string(payload)});
-  }
-
- private:
-  std::vector<SavedHttp3Datagram> received_h3_datagrams_;
-};
-
-class MockHttp3DatagramRegistrationVisitor
-    : public QuicSpdyStream::Http3DatagramRegistrationVisitor {
- public:
-  MOCK_METHOD(void, OnContextReceived,
-              (QuicStreamId stream_id,
-               absl::optional<QuicDatagramContextId> context_id,
-               DatagramFormatType format_type,
-               absl::string_view format_additional_data),
-              (override));
-
-  MOCK_METHOD(void, OnContextClosed,
-              (QuicStreamId stream_id,
-               absl::optional<QuicDatagramContextId> context_id,
-               ContextCloseCode close_code, absl::string_view close_details),
-              (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
diff --git a/quic/test_tools/quic_test_utils_test.cc b/quic/test_tools/quic_test_utils_test.cc
deleted file mode 100644
index f7be77c..0000000
--- a/quic/test_tools/quic_test_utils_test.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_test_utils.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-
-class QuicTestUtilsTest : public QuicTest {};
-
-TEST_F(QuicTestUtilsTest, ConnectionId) {
-  EXPECT_NE(EmptyQuicConnectionId(), TestConnectionId());
-  EXPECT_NE(EmptyQuicConnectionId(), TestConnectionId(1));
-  EXPECT_EQ(TestConnectionId(), TestConnectionId());
-  EXPECT_EQ(TestConnectionId(33), TestConnectionId(33));
-  EXPECT_NE(TestConnectionId(0xdead), TestConnectionId(0xbeef));
-  EXPECT_EQ(0x1337u, TestConnectionIdToUInt64(TestConnectionId(0x1337)));
-  EXPECT_NE(0xdeadu, TestConnectionIdToUInt64(TestConnectionId(0xbeef)));
-}
-
-TEST_F(QuicTestUtilsTest, BasicApproxEq) {
-  EXPECT_APPROX_EQ(10, 10, 1e-6f);
-  EXPECT_APPROX_EQ(1000, 1001, 0.01f);
-  EXPECT_NONFATAL_FAILURE(EXPECT_APPROX_EQ(1000, 1100, 0.01f), "");
-
-  EXPECT_APPROX_EQ(64, 31, 0.55f);
-  EXPECT_NONFATAL_FAILURE(EXPECT_APPROX_EQ(31, 64, 0.55f), "");
-}
-
-TEST_F(QuicTestUtilsTest, QuicTimeDelta) {
-  EXPECT_APPROX_EQ(QuicTime::Delta::FromMicroseconds(1000),
-                   QuicTime::Delta::FromMicroseconds(1003), 0.01f);
-  EXPECT_NONFATAL_FAILURE(
-      EXPECT_APPROX_EQ(QuicTime::Delta::FromMicroseconds(1000),
-                       QuicTime::Delta::FromMicroseconds(1200), 0.01f),
-      "");
-}
-
-TEST_F(QuicTestUtilsTest, QuicBandwidth) {
-  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesPerSecond(1000),
-                   QuicBandwidth::FromBitsPerSecond(8005), 0.01f);
-  EXPECT_NONFATAL_FAILURE(
-      EXPECT_APPROX_EQ(QuicBandwidth::FromBytesPerSecond(1000),
-                       QuicBandwidth::FromBitsPerSecond(9005), 0.01f),
-      "");
-}
-
-// Ensure that SimpleRandom does not change its output for a fixed seed.
-TEST_F(QuicTestUtilsTest, SimpleRandomStability) {
-  SimpleRandom rng;
-  rng.set_seed(UINT64_C(0x1234567800010001));
-  EXPECT_EQ(UINT64_C(12589383305231984671), rng.RandUint64());
-  EXPECT_EQ(UINT64_C(17775425089941798664), rng.RandUint64());
-}
-
-// Ensure that the output of SimpleRandom does not depend on the size of the
-// read calls.
-TEST_F(QuicTestUtilsTest, SimpleRandomChunks) {
-  SimpleRandom rng;
-  std::string reference(16 * 1024, '\0');
-  rng.RandBytes(&reference[0], reference.size());
-
-  for (size_t chunk_size : {3, 4, 7, 4096}) {
-    rng.set_seed(0);
-    size_t chunks = reference.size() / chunk_size;
-    std::string buffer(chunks * chunk_size, '\0');
-    for (size_t i = 0; i < chunks; i++) {
-      rng.RandBytes(&buffer[i * chunk_size], chunk_size);
-    }
-    EXPECT_EQ(reference.substr(0, buffer.size()), buffer)
-        << "Failed for chunk_size = " << chunk_size;
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_time_wait_list_manager_peer.cc b/quic/test_tools/quic_time_wait_list_manager_peer.cc
deleted file mode 100644
index cbcd36e..0000000
--- a/quic/test_tools/quic_time_wait_list_manager_peer.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_time_wait_list_manager_peer.h"
-
-namespace quic {
-namespace test {
-
-bool QuicTimeWaitListManagerPeer::ShouldSendResponse(
-    QuicTimeWaitListManager* manager,
-    int received_packet_count) {
-  return manager->ShouldSendResponse(received_packet_count);
-}
-
-QuicTime::Delta QuicTimeWaitListManagerPeer::time_wait_period(
-    QuicTimeWaitListManager* manager) {
-  return manager->time_wait_period_;
-}
-
-QuicAlarm* QuicTimeWaitListManagerPeer::expiration_alarm(
-    QuicTimeWaitListManager* manager) {
-  return manager->connection_id_clean_up_alarm_.get();
-}
-
-void QuicTimeWaitListManagerPeer::set_clock(QuicTimeWaitListManager* manager,
-                                            const QuicClock* clock) {
-  manager->clock_ = clock;
-}
-
-// static
-bool QuicTimeWaitListManagerPeer::SendOrQueuePacket(
-    QuicTimeWaitListManager* manager,
-    std::unique_ptr<QuicTimeWaitListManager::QueuedPacket> packet,
-    const QuicPerPacketContext* packet_context) {
-  return manager->SendOrQueuePacket(std::move(packet), packet_context);
-}
-
-// static
-size_t QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
-    QuicTimeWaitListManager* manager) {
-  return manager->pending_packets_queue_.size();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_time_wait_list_manager_peer.h b/quic/test_tools/quic_time_wait_list_manager_peer.h
deleted file mode 100644
index a314e03..0000000
--- a/quic/test_tools/quic_time_wait_list_manager_peer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
-
-#include "quic/core/quic_time_wait_list_manager.h"
-
-namespace quic {
-namespace test {
-
-class QuicTimeWaitListManagerPeer {
- public:
-  static bool ShouldSendResponse(QuicTimeWaitListManager* manager,
-                                 int received_packet_count);
-
-  static QuicTime::Delta time_wait_period(QuicTimeWaitListManager* manager);
-
-  static QuicAlarm* expiration_alarm(QuicTimeWaitListManager* manager);
-
-  static void set_clock(QuicTimeWaitListManager* manager,
-                        const QuicClock* clock);
-
-  static bool SendOrQueuePacket(
-      QuicTimeWaitListManager* manager,
-      std::unique_ptr<QuicTimeWaitListManager::QueuedPacket> packet,
-      const QuicPerPacketContext* packet_context);
-
-  static size_t PendingPacketsQueueSize(QuicTimeWaitListManager* manager);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
diff --git a/quic/test_tools/quic_transport_test_tools.h b/quic/test_tools/quic_transport_test_tools.h
deleted file mode 100644
index 5babfd2..0000000
--- a/quic/test_tools/quic_transport_test_tools.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
-
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_server_session.h"
-
-namespace quic {
-namespace test {
-
-class MockClientVisitor : public WebTransportVisitor {
- public:
-  MOCK_METHOD(void, OnSessionReady, (const spdy::SpdyHeaderBlock&), (override));
-  MOCK_METHOD(void, OnSessionClosed,
-              (WebTransportSessionError, const std::string&), (override));
-  MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override));
-  MOCK_METHOD(void, OnIncomingUnidirectionalStreamAvailable, (), (override));
-  MOCK_METHOD(void, OnDatagramReceived, (absl::string_view), (override));
-  MOCK_METHOD(void, OnCanCreateNewOutgoingBidirectionalStream, (), (override));
-  MOCK_METHOD(void, OnCanCreateNewOutgoingUnidirectionalStream, (), (override));
-};
-
-class MockServerVisitor : public QuicTransportServerSession::ServerVisitor {
- public:
-  MOCK_METHOD(bool, CheckOrigin, (url::Origin), (override));
-  MOCK_METHOD(bool, ProcessPath, (const GURL&), (override));
-};
-
-class MockStreamVisitor : public WebTransportStreamVisitor {
- public:
-  MOCK_METHOD(void, OnCanRead, (), (override));
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-
-  MOCK_METHOD(void, OnResetStreamReceived, (WebTransportStreamError error),
-              (override));
-  MOCK_METHOD(void, OnStopSendingReceived, (WebTransportStreamError error),
-              (override));
-  MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
diff --git a/quic/test_tools/quic_unacked_packet_map_peer.cc b/quic/test_tools/quic_unacked_packet_map_peer.cc
deleted file mode 100644
index 61fda95..0000000
--- a/quic/test_tools/quic_unacked_packet_map_peer.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/quic_unacked_packet_map_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-const QuicStreamFrame& QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(
-    const QuicUnackedPacketMap& unacked_packets) {
-  return unacked_packets.aggregated_stream_frame_;
-}
-
-// static
-void QuicUnackedPacketMapPeer::SetPerspective(
-    QuicUnackedPacketMap* unacked_packets,
-    Perspective perspective) {
-  *const_cast<Perspective*>(&unacked_packets->perspective_) = perspective;
-}
-
-// static
-size_t QuicUnackedPacketMapPeer::GetCapacity(
-    const QuicUnackedPacketMap& unacked_packets) {
-  return unacked_packets.unacked_packets_.capacity();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_unacked_packet_map_peer.h b/quic/test_tools/quic_unacked_packet_map_peer.h
deleted file mode 100644
index c21bcee..0000000
--- a/quic/test_tools/quic_unacked_packet_map_peer.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
-
-#include "quic/core/quic_unacked_packet_map.h"
-
-namespace quic {
-namespace test {
-
-class QuicUnackedPacketMapPeer {
- public:
-  static const QuicStreamFrame& GetAggregatedStreamFrame(
-      const QuicUnackedPacketMap& unacked_packets);
-
-  static void SetPerspective(QuicUnackedPacketMap* unacked_packets,
-                             Perspective perspective);
-
-  static size_t GetCapacity(const QuicUnackedPacketMap& unacked_packets);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
diff --git a/quic/test_tools/rtt_stats_peer.cc b/quic/test_tools/rtt_stats_peer.cc
deleted file mode 100644
index 79325c4..0000000
--- a/quic/test_tools/rtt_stats_peer.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/rtt_stats_peer.h"
-
-namespace quic {
-namespace test {
-
-// static
-void RttStatsPeer::SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms) {
-  rtt_stats->smoothed_rtt_ = rtt_ms;
-}
-
-// static
-void RttStatsPeer::SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms) {
-  rtt_stats->min_rtt_ = rtt_ms;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/rtt_stats_peer.h b/quic/test_tools/rtt_stats_peer.h
deleted file mode 100644
index bd06ecc..0000000
--- a/quic/test_tools/rtt_stats_peer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
-
-#include "quic/core/congestion_control/rtt_stats.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-namespace test {
-
-class RttStatsPeer {
- public:
-  RttStatsPeer() = delete;
-
-  static void SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms);
-
-  static void SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
diff --git a/quic/test_tools/send_algorithm_test_utils.cc b/quic/test_tools/send_algorithm_test_utils.cc
deleted file mode 100644
index 074028a..0000000
--- a/quic/test_tools/send_algorithm_test_utils.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/send_algorithm_test_utils.h"
-
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_output.h"
-
-namespace quic {
-namespace test {
-
-bool LoadSendAlgorithmTestResult(SendAlgorithmTestResult* result) {
-  std::string test_result_file_content;
-  if (!QuicLoadTestOutput(GetSendAlgorithmTestResultFilename(),
-                          &test_result_file_content)) {
-    return false;
-  }
-  return result->ParseFromString(test_result_file_content);
-}
-
-void RecordSendAlgorithmTestResult(uint64_t random_seed,
-                                   int64_t simulated_duration_micros) {
-  SendAlgorithmTestResult result;
-  result.set_test_name(GetFullSendAlgorithmTestName());
-  result.set_random_seed(random_seed);
-  result.set_simulated_duration_micros(simulated_duration_micros);
-
-  QuicSaveTestOutput(GetSendAlgorithmTestResultFilename(),
-                     result.SerializeAsString());
-}
-
-void CompareSendAlgorithmTestResult(int64_t actual_simulated_duration_micros) {
-  SendAlgorithmTestResult expected;
-  ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
-  QUIC_LOG(INFO) << "Loaded expected test result: "
-                 << expected.ShortDebugString();
-
-  EXPECT_GE(expected.simulated_duration_micros(),
-            actual_simulated_duration_micros);
-}
-
-std::string GetFullSendAlgorithmTestName() {
-  const auto* test_info =
-      ::testing::UnitTest::GetInstance()->current_test_info();
-  const std::string type_param =
-      test_info->type_param() ? test_info->type_param() : "";
-  const std::string value_param =
-      test_info->value_param() ? test_info->value_param() : "";
-  return absl::StrCat(test_info->test_suite_name(), ".", test_info->name(), "_",
-                      type_param, "_", value_param);
-}
-
-std::string GetSendAlgorithmTestResultFilename() {
-  return GetFullSendAlgorithmTestName() + ".test_result";
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/send_algorithm_test_utils.h b/quic/test_tools/send_algorithm_test_utils.h
deleted file mode 100644
index 430e42a..0000000
--- a/quic/test_tools/send_algorithm_test_utils.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
-#define QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
-
-#include "quic/test_tools/send_algorithm_test_result.pb.h"
-
-namespace quic {
-namespace test {
-
-bool LoadSendAlgorithmTestResult(SendAlgorithmTestResult* result);
-
-void RecordSendAlgorithmTestResult(uint64_t random_seed,
-                                   int64_t simulated_duration_micros);
-
-// Load the expected test result with LoadSendAlgorithmTestResult(), and compare
-// it with the actual results provided in the arguments.
-void CompareSendAlgorithmTestResult(int64_t actual_simulated_duration_micros);
-
-std::string GetFullSendAlgorithmTestName();
-
-std::string GetSendAlgorithmTestResultFilename();
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
diff --git a/quic/test_tools/server_thread.cc b/quic/test_tools/server_thread.cc
deleted file mode 100644
index f9315677..0000000
--- a/quic/test_tools/server_thread.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/server_thread.h"
-
-#include "quic/core/quic_dispatcher.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_dispatcher_peer.h"
-#include "quic/test_tools/quic_server_peer.h"
-
-namespace quic {
-namespace test {
-
-ServerThread::ServerThread(QuicServer* server, const QuicSocketAddress& address)
-    : QuicThread("server_thread"),
-      server_(server),
-      clock_(server->epoll_server()),
-      address_(address),
-      port_(0),
-      initialized_(false) {}
-
-ServerThread::~ServerThread() = default;
-
-void ServerThread::Initialize() {
-  if (initialized_) {
-    return;
-  }
-
-  server_->CreateUDPSocketAndListen(address_);
-
-  QuicWriterMutexLock lock(&port_lock_);
-  port_ = server_->port();
-
-  initialized_ = true;
-}
-
-void ServerThread::Run() {
-  if (!initialized_) {
-    Initialize();
-  }
-
-  while (!quit_.HasBeenNotified()) {
-    if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
-      paused_.Notify();
-      resume_.WaitForNotification();
-    }
-    server_->WaitForEvents();
-    ExecuteScheduledActions();
-    MaybeNotifyOfHandshakeConfirmation();
-  }
-
-  server_->Shutdown();
-}
-
-int ServerThread::GetPort() {
-  QuicReaderMutexLock lock(&port_lock_);
-  int rc = port_;
-  return rc;
-}
-
-void ServerThread::Schedule(std::function<void()> action) {
-  QUICHE_DCHECK(!quit_.HasBeenNotified());
-  QuicWriterMutexLock lock(&scheduled_actions_lock_);
-  scheduled_actions_.push_back(std::move(action));
-}
-
-void ServerThread::WaitForCryptoHandshakeConfirmed() {
-  confirmed_.WaitForNotification();
-}
-
-bool ServerThread::WaitUntil(std::function<bool()> termination_predicate,
-                             QuicTime::Delta timeout) {
-  const QuicTime deadline = clock_.Now() + timeout;
-  while (clock_.Now() < deadline) {
-    QuicNotification done_checking;
-    bool should_terminate = false;
-    Schedule([&] {
-      should_terminate = termination_predicate();
-      done_checking.Notify();
-    });
-    done_checking.WaitForNotification();
-    if (should_terminate) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void ServerThread::Pause() {
-  QUICHE_DCHECK(!pause_.HasBeenNotified());
-  pause_.Notify();
-  paused_.WaitForNotification();
-}
-
-void ServerThread::Resume() {
-  QUICHE_DCHECK(!resume_.HasBeenNotified());
-  QUICHE_DCHECK(pause_.HasBeenNotified());
-  resume_.Notify();
-}
-
-void ServerThread::Quit() {
-  if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
-    resume_.Notify();
-  }
-  if (!quit_.HasBeenNotified()) {
-    quit_.Notify();
-  }
-}
-
-void ServerThread::MaybeNotifyOfHandshakeConfirmation() {
-  if (confirmed_.HasBeenNotified()) {
-    // Only notify once.
-    return;
-  }
-  QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server());
-  if (dispatcher->NumSessions() == 0) {
-    // Wait for a session to be created.
-    return;
-  }
-  QuicSession* session = QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
-  if (session->OneRttKeysAvailable()) {
-    confirmed_.Notify();
-  }
-}
-
-void ServerThread::ExecuteScheduledActions() {
-  quiche::QuicheCircularDeque<std::function<void()>> actions;
-  {
-    QuicWriterMutexLock lock(&scheduled_actions_lock_);
-    actions.swap(scheduled_actions_);
-  }
-  while (!actions.empty()) {
-    actions.front()();
-    actions.pop_front();
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/server_thread.h b/quic/test_tools/server_thread.h
deleted file mode 100644
index 1baa6e5..0000000
--- a/quic/test_tools/server_thread.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
-#define QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
-
-#include <memory>
-
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_epoll_clock.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_thread.h"
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-namespace test {
-
-// Simple wrapper class to run QuicServer in a dedicated thread.
-class ServerThread : public QuicThread {
- public:
-  ServerThread(QuicServer* server, const QuicSocketAddress& address);
-  ServerThread(const ServerThread&) = delete;
-  ServerThread& operator=(const ServerThread&) = delete;
-
-  ~ServerThread() override;
-
-  // Prepares the server, but does not start accepting connections. Useful for
-  // injecting mocks.
-  void Initialize();
-
-  // Runs the event loop. Will initialize if necessary.
-  void Run() override;
-
-  // Schedules the given action for execution in the event loop.
-  void Schedule(std::function<void()> action);
-
-  // Waits for the handshake to be confirmed for the first session created.
-  void WaitForCryptoHandshakeConfirmed();
-
-  // Wait until |termination_predicate| returns true in server thread, or
-  // reached |timeout|. Must be called from an external thread.
-  // Return whether the function returned after |termination_predicate| become
-  // true.
-  bool WaitUntil(std::function<bool()> termination_predicate,
-                 QuicTime::Delta timeout);
-
-  // Pauses execution of the server until Resume() is called.  May only be
-  // called once.
-  void Pause();
-
-  // Resumes execution of the server after Pause() has been called.  May only
-  // be called once.
-  void Resume();
-
-  // Stops the server from executing and shuts it down, destroying all
-  // server objects.
-  void Quit();
-
-  // Returns the underlying server.  Care must be taken to avoid data races
-  // when accessing the server.  It is always safe to access the server
-  // after calling Pause() and before calling Resume().
-  QuicServer* server() { return server_.get(); }
-
-  // Returns the port that the server is listening on.
-  int GetPort();
-
- private:
-  void MaybeNotifyOfHandshakeConfirmation();
-  void ExecuteScheduledActions();
-
-  QuicNotification
-      confirmed_;            // Notified when the first handshake is confirmed.
-  QuicNotification pause_;   // Notified when the server should pause.
-  QuicNotification paused_;  // Notitied when the server has paused
-  QuicNotification resume_;  // Notified when the server should resume.
-  QuicNotification quit_;    // Notified when the server should quit.
-
-  std::unique_ptr<QuicServer> server_;
-  QuicEpollClock clock_;
-  QuicSocketAddress address_;
-  mutable QuicMutex port_lock_;
-  int port_ QUIC_GUARDED_BY(port_lock_);
-
-  bool initialized_;
-
-  QuicMutex scheduled_actions_lock_;
-  quiche::QuicheCircularDeque<std::function<void()>> scheduled_actions_
-      QUIC_GUARDED_BY(scheduled_actions_lock_);
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
diff --git a/quic/test_tools/simple_data_producer.cc b/quic/test_tools/simple_data_producer.cc
deleted file mode 100644
index 64c0a2c..0000000
--- a/quic/test_tools/simple_data_producer.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_data_producer.h"
-
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-
-namespace quic {
-
-namespace test {
-
-SimpleDataProducer::SimpleDataProducer() {}
-
-SimpleDataProducer::~SimpleDataProducer() {}
-
-void SimpleDataProducer::SaveStreamData(QuicStreamId id,
-                                        absl::string_view data) {
-  if (data.empty()) {
-    return;
-  }
-  if (!send_buffer_map_.contains(id)) {
-    send_buffer_map_[id] = std::make_unique<QuicStreamSendBuffer>(&allocator_);
-  }
-  send_buffer_map_[id]->SaveStreamData(data);
-}
-
-void SimpleDataProducer::SaveCryptoData(EncryptionLevel level,
-                                        QuicStreamOffset offset,
-                                        absl::string_view data) {
-  auto key = std::make_pair(level, offset);
-  crypto_buffer_map_[key] = std::string(data);
-}
-
-WriteStreamDataResult SimpleDataProducer::WriteStreamData(
-    QuicStreamId id,
-    QuicStreamOffset offset,
-    QuicByteCount data_length,
-    QuicDataWriter* writer) {
-  auto iter = send_buffer_map_.find(id);
-  if (iter == send_buffer_map_.end()) {
-    return STREAM_MISSING;
-  }
-  if (iter->second->WriteStreamData(offset, data_length, writer)) {
-    return WRITE_SUCCESS;
-  }
-  return WRITE_FAILED;
-}
-
-bool SimpleDataProducer::WriteCryptoData(EncryptionLevel level,
-                                         QuicStreamOffset offset,
-                                         QuicByteCount data_length,
-                                         QuicDataWriter* writer) {
-  auto it = crypto_buffer_map_.find(std::make_pair(level, offset));
-  if (it == crypto_buffer_map_.end() || it->second.length() < data_length) {
-    return false;
-  }
-  return writer->WriteStringPiece(
-      absl::string_view(it->second.data(), data_length));
-}
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/test_tools/simple_data_producer.h b/quic/test_tools/simple_data_producer.h
deleted file mode 100644
index 9564f86..0000000
--- a/quic/test_tools/simple_data_producer.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_stream_send_buffer.h"
-#include "quic/platform/api/quic_containers.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-
-namespace test {
-
-// A simple data producer which copies stream data into a map from stream
-// id to send buffer.
-class SimpleDataProducer : public QuicStreamFrameDataProducer {
- public:
-  SimpleDataProducer();
-  ~SimpleDataProducer() override;
-
-  // Saves `data` to be provided when WriteStreamData() is called. Multiple
-  // calls to SaveStreamData() for the same stream ID append to the buffer for
-  // that stream.
-  void SaveStreamData(QuicStreamId id, absl::string_view data);
-
-  void SaveCryptoData(EncryptionLevel level,
-                      QuicStreamOffset offset,
-                      absl::string_view data);
-
-  // QuicStreamFrameDataProducer
-  WriteStreamDataResult WriteStreamData(QuicStreamId id,
-                                        QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        QuicDataWriter* writer) override;
-  bool WriteCryptoData(EncryptionLevel level,
-                       QuicStreamOffset offset,
-                       QuicByteCount data_length,
-                       QuicDataWriter* writer) override;
-
- private:
-  using SendBufferMap =
-      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStreamSendBuffer>>;
-
-  using CryptoBufferMap =
-      absl::flat_hash_map<std::pair<EncryptionLevel, QuicStreamOffset>,
-                          std::string>;
-
-  quiche::SimpleBufferAllocator allocator_;
-
-  SendBufferMap send_buffer_map_;
-
-  // |crypto_buffer_map_| stores data provided by SaveCryptoData to later write
-  // in WriteCryptoData. The level and data passed into SaveCryptoData are used
-  // as the key to identify the data when WriteCryptoData is called.
-  // WriteCryptoData will only succeed if there is data in the map for the
-  // provided level and offset, and the data in the map matches the data_length
-  // passed into WriteCryptoData.
-  //
-  // Unlike SaveStreamData/WriteStreamData which uses a map of
-  // QuicStreamSendBuffers (for each stream ID), this map provides data for
-  // specific offsets. Using a QuicStreamSendBuffer requires that all data
-  // before an offset exist, whereas this allows providing data that exists at
-  // arbitrary offsets for testing.
-  CryptoBufferMap crypto_buffer_map_;
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
diff --git a/quic/test_tools/simple_quic_framer.cc b/quic/test_tools/simple_quic_framer.cc
deleted file mode 100644
index 92363ec..0000000
--- a/quic/test_tools/simple_quic_framer.cc
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_quic_framer.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_decrypter.h"
-#include "quic/core/crypto/quic_encrypter.h"
-#include "quic/core/quic_types.h"
-
-namespace quic {
-namespace test {
-
-class SimpleFramerVisitor : public QuicFramerVisitorInterface {
- public:
-  SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {}
-  SimpleFramerVisitor(const SimpleFramerVisitor&) = delete;
-  SimpleFramerVisitor& operator=(const SimpleFramerVisitor&) = delete;
-
-  ~SimpleFramerVisitor() override {}
-
-  void OnError(QuicFramer* framer) override { error_ = framer->error(); }
-
-  bool OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) override {
-    return false;
-  }
-
-  void OnPacket() override {}
-  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
-    public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
-  }
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& packet) override {
-    version_negotiation_packet_ =
-        std::make_unique<QuicVersionNegotiationPacket>((packet));
-  }
-
-  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
-                     QuicConnectionId /*new_connection_id*/,
-                     absl::string_view /*retry_token*/,
-                     absl::string_view /*retry_integrity_tag*/,
-                     absl::string_view /*retry_without_tag*/) override {}
-
-  bool OnUnauthenticatedPublicHeader(
-      const QuicPacketHeader& /*header*/) override {
-    return true;
-  }
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
-    return true;
-  }
-  void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
-    last_decrypted_level_ = level;
-  }
-  bool OnPacketHeader(const QuicPacketHeader& header) override {
-    has_header_ = true;
-    header_ = header;
-    return true;
-  }
-
-  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
-    coalesced_packet_ = packet.Clone();
-  }
-
-  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
-                             EncryptionLevel /*decryption_level*/,
-                             bool /*has_decryption_key*/) override {}
-
-  bool OnStreamFrame(const QuicStreamFrame& frame) override {
-    // Save a copy of the data so it is valid after the packet is processed.
-    std::string* string_data =
-        new std::string(frame.data_buffer, frame.data_length);
-    stream_data_.push_back(absl::WrapUnique(string_data));
-    // TODO(ianswett): A pointer isn't necessary with emplace_back.
-    stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
-        frame.stream_id, frame.fin, frame.offset,
-        absl::string_view(*string_data)));
-    return true;
-  }
-
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
-    // Save a copy of the data so it is valid after the packet is processed.
-    std::string* string_data =
-        new std::string(frame.data_buffer, frame.data_length);
-    crypto_data_.push_back(absl::WrapUnique(string_data));
-    crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
-        frame.level, frame.offset, absl::string_view(*string_data)));
-    return true;
-  }
-
-  bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta ack_delay_time) override {
-    QuicAckFrame ack_frame;
-    ack_frame.largest_acked = largest_acked;
-    ack_frame.ack_delay_time = ack_delay_time;
-    ack_frames_.push_back(ack_frame);
-    return true;
-  }
-
-  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
-    QUICHE_DCHECK(!ack_frames_.empty());
-    ack_frames_[ack_frames_.size() - 1].packets.AddRange(start, end);
-    return true;
-  }
-
-  bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
-                      QuicTime /*timestamp*/) override {
-    return true;
-  }
-
-  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
-
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
-    stop_waiting_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
-    padding_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnPingFrame(const QuicPingFrame& frame) override {
-    ping_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
-    rst_stream_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
-    connection_close_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
-    new_connection_id_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) override {
-    retire_connection_id_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
-    new_token_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
-    stop_sending_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
-    path_challenge_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
-    path_response_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
-    goaway_frames_.push_back(frame);
-    return true;
-  }
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
-    max_streams_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
-    streams_blocked_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
-    window_update_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
-    blocked_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnMessageFrame(const QuicMessageFrame& frame) override {
-    message_frames_.emplace_back(frame.data, frame.message_length);
-    return true;
-  }
-
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
-    handshake_done_frames_.push_back(frame);
-    return true;
-  }
-
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
-    ack_frequency_frames_.push_back(frame);
-    return true;
-  }
-
-  void OnPacketComplete() override {}
-
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& /*token*/) const override {
-    return false;
-  }
-
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& packet) override {
-    stateless_reset_packet_ =
-        std::make_unique<QuicIetfStatelessResetPacket>(packet);
-  }
-
-  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
-  void OnDecryptedFirstPacketInKeyPhase() override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-
-  const QuicPacketHeader& header() const { return header_; }
-  const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; }
-  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
-    return connection_close_frames_;
-  }
-
-  const std::vector<QuicGoAwayFrame>& goaway_frames() const {
-    return goaway_frames_;
-  }
-  const std::vector<QuicMaxStreamsFrame>& max_streams_frames() const {
-    return max_streams_frames_;
-  }
-  const std::vector<QuicStreamsBlockedFrame>& streams_blocked_frames() const {
-    return streams_blocked_frames_;
-  }
-  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
-    return rst_stream_frames_;
-  }
-  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
-    return stream_frames_;
-  }
-  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
-    return crypto_frames_;
-  }
-  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
-    return stop_waiting_frames_;
-  }
-  const std::vector<QuicPingFrame>& ping_frames() const { return ping_frames_; }
-  const std::vector<QuicMessageFrame>& message_frames() const {
-    return message_frames_;
-  }
-  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
-    return window_update_frames_;
-  }
-  const std::vector<QuicPaddingFrame>& padding_frames() const {
-    return padding_frames_;
-  }
-  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
-    return path_challenge_frames_;
-  }
-  const std::vector<QuicPathResponseFrame>& path_response_frames() const {
-    return path_response_frames_;
-  }
-  const QuicVersionNegotiationPacket* version_negotiation_packet() const {
-    return version_negotiation_packet_.get();
-  }
-  EncryptionLevel last_decrypted_level() const { return last_decrypted_level_; }
-  const QuicEncryptedPacket* coalesced_packet() const {
-    return coalesced_packet_.get();
-  }
-
- private:
-  QuicErrorCode error_;
-  bool has_header_;
-  QuicPacketHeader header_;
-  std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
-  std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
-  std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
-  std::vector<QuicAckFrame> ack_frames_;
-  std::vector<QuicStopWaitingFrame> stop_waiting_frames_;
-  std::vector<QuicPaddingFrame> padding_frames_;
-  std::vector<QuicPingFrame> ping_frames_;
-  std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
-  std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
-  std::vector<QuicRstStreamFrame> rst_stream_frames_;
-  std::vector<QuicGoAwayFrame> goaway_frames_;
-  std::vector<QuicStreamsBlockedFrame> streams_blocked_frames_;
-  std::vector<QuicMaxStreamsFrame> max_streams_frames_;
-  std::vector<QuicConnectionCloseFrame> connection_close_frames_;
-  std::vector<QuicStopSendingFrame> stop_sending_frames_;
-  std::vector<QuicPathChallengeFrame> path_challenge_frames_;
-  std::vector<QuicPathResponseFrame> path_response_frames_;
-  std::vector<QuicWindowUpdateFrame> window_update_frames_;
-  std::vector<QuicBlockedFrame> blocked_frames_;
-  std::vector<QuicNewConnectionIdFrame> new_connection_id_frames_;
-  std::vector<QuicRetireConnectionIdFrame> retire_connection_id_frames_;
-  std::vector<QuicNewTokenFrame> new_token_frames_;
-  std::vector<QuicMessageFrame> message_frames_;
-  std::vector<QuicHandshakeDoneFrame> handshake_done_frames_;
-  std::vector<QuicAckFrequencyFrame> ack_frequency_frames_;
-  std::vector<std::unique_ptr<std::string>> stream_data_;
-  std::vector<std::unique_ptr<std::string>> crypto_data_;
-  EncryptionLevel last_decrypted_level_;
-  std::unique_ptr<QuicEncryptedPacket> coalesced_packet_;
-};
-
-SimpleQuicFramer::SimpleQuicFramer()
-    : framer_(AllSupportedVersions(),
-              QuicTime::Zero(),
-              Perspective::IS_SERVER,
-              kQuicDefaultConnectionIdLength) {}
-
-SimpleQuicFramer::SimpleQuicFramer(
-    const ParsedQuicVersionVector& supported_versions)
-    : framer_(supported_versions,
-              QuicTime::Zero(),
-              Perspective::IS_SERVER,
-              kQuicDefaultConnectionIdLength) {}
-
-SimpleQuicFramer::SimpleQuicFramer(
-    const ParsedQuicVersionVector& supported_versions,
-    Perspective perspective)
-    : framer_(supported_versions,
-              QuicTime::Zero(),
-              perspective,
-              kQuicDefaultConnectionIdLength) {}
-
-SimpleQuicFramer::~SimpleQuicFramer() {}
-
-bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
-  visitor_ = std::make_unique<SimpleFramerVisitor>();
-  framer_.set_visitor(visitor_.get());
-  return framer_.ProcessPacket(packet);
-}
-
-void SimpleQuicFramer::Reset() {
-  visitor_ = std::make_unique<SimpleFramerVisitor>();
-}
-
-const QuicPacketHeader& SimpleQuicFramer::header() const {
-  return visitor_->header();
-}
-
-const QuicVersionNegotiationPacket*
-SimpleQuicFramer::version_negotiation_packet() const {
-  return visitor_->version_negotiation_packet();
-}
-
-EncryptionLevel SimpleQuicFramer::last_decrypted_level() const {
-  return visitor_->last_decrypted_level();
-}
-
-QuicFramer* SimpleQuicFramer::framer() {
-  return &framer_;
-}
-
-size_t SimpleQuicFramer::num_frames() const {
-  return ack_frames().size() + goaway_frames().size() +
-         rst_stream_frames().size() + stop_waiting_frames().size() +
-         path_challenge_frames().size() + path_response_frames().size() +
-         stream_frames().size() + ping_frames().size() +
-         connection_close_frames().size() + padding_frames().size() +
-         crypto_frames().size();
-}
-
-const std::vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const {
-  return visitor_->ack_frames();
-}
-
-const std::vector<QuicStopWaitingFrame>& SimpleQuicFramer::stop_waiting_frames()
-    const {
-  return visitor_->stop_waiting_frames();
-}
-
-const std::vector<QuicPathChallengeFrame>&
-SimpleQuicFramer::path_challenge_frames() const {
-  return visitor_->path_challenge_frames();
-}
-const std::vector<QuicPathResponseFrame>&
-SimpleQuicFramer::path_response_frames() const {
-  return visitor_->path_response_frames();
-}
-
-const std::vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const {
-  return visitor_->ping_frames();
-}
-
-const std::vector<QuicMessageFrame>& SimpleQuicFramer::message_frames() const {
-  return visitor_->message_frames();
-}
-
-const std::vector<QuicWindowUpdateFrame>&
-SimpleQuicFramer::window_update_frames() const {
-  return visitor_->window_update_frames();
-}
-
-const std::vector<std::unique_ptr<QuicStreamFrame>>&
-SimpleQuicFramer::stream_frames() const {
-  return visitor_->stream_frames();
-}
-
-const std::vector<std::unique_ptr<QuicCryptoFrame>>&
-SimpleQuicFramer::crypto_frames() const {
-  return visitor_->crypto_frames();
-}
-
-const std::vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames()
-    const {
-  return visitor_->rst_stream_frames();
-}
-
-const std::vector<QuicGoAwayFrame>& SimpleQuicFramer::goaway_frames() const {
-  return visitor_->goaway_frames();
-}
-
-const std::vector<QuicConnectionCloseFrame>&
-SimpleQuicFramer::connection_close_frames() const {
-  return visitor_->connection_close_frames();
-}
-
-const std::vector<QuicPaddingFrame>& SimpleQuicFramer::padding_frames() const {
-  return visitor_->padding_frames();
-}
-
-const QuicEncryptedPacket* SimpleQuicFramer::coalesced_packet() const {
-  return visitor_->coalesced_packet();
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/simple_quic_framer.h b/quic/test_tools/simple_quic_framer.h
deleted file mode 100644
index 6801dfe..0000000
--- a/quic/test_tools/simple_quic_framer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
-
-#include <memory>
-#include <vector>
-
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packets.h"
-
-namespace quic {
-
-struct QuicAckFrame;
-
-namespace test {
-
-class SimpleFramerVisitor;
-
-// Peer to make public a number of otherwise private QuicFramer methods.
-class SimpleQuicFramer {
- public:
-  SimpleQuicFramer();
-  explicit SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions);
-  SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions,
-                   Perspective perspective);
-  SimpleQuicFramer(const SimpleQuicFramer&) = delete;
-  SimpleQuicFramer& operator=(const SimpleQuicFramer&) = delete;
-  ~SimpleQuicFramer();
-
-  bool ProcessPacket(const QuicEncryptedPacket& packet);
-  void Reset();
-
-  const QuicPacketHeader& header() const;
-  size_t num_frames() const;
-  const std::vector<QuicAckFrame>& ack_frames() const;
-  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const;
-  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const;
-  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const;
-  const std::vector<QuicPathResponseFrame>& path_response_frames() const;
-  const std::vector<QuicPingFrame>& ping_frames() const;
-  const std::vector<QuicMessageFrame>& message_frames() const;
-  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const;
-  const std::vector<QuicGoAwayFrame>& goaway_frames() const;
-  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const;
-  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const;
-  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const;
-  const std::vector<QuicPaddingFrame>& padding_frames() const;
-  const QuicVersionNegotiationPacket* version_negotiation_packet() const;
-  EncryptionLevel last_decrypted_level() const;
-  const QuicEncryptedPacket* coalesced_packet() const;
-
-  QuicFramer* framer();
-
-  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
-    framer_.SetSupportedVersions(versions);
-  }
-
- private:
-  QuicFramer framer_;
-  std::unique_ptr<SimpleFramerVisitor> visitor_;
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
diff --git a/quic/test_tools/simple_session_cache.cc b/quic/test_tools/simple_session_cache.cc
deleted file mode 100644
index b9c0436..0000000
--- a/quic/test_tools/simple_session_cache.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_session_cache.h"
-#include <memory>
-#include "quic/core/crypto/quic_crypto_client_config.h"
-
-namespace quic {
-namespace test {
-
-void SimpleSessionCache::Insert(const QuicServerId& server_id,
-                                bssl::UniquePtr<SSL_SESSION> session,
-                                const TransportParameters& params,
-                                const ApplicationState* application_state) {
-  auto it = cache_entries_.find(server_id);
-  if (it == cache_entries_.end()) {
-    it = cache_entries_.insert(std::make_pair(server_id, Entry())).first;
-  }
-  if (session != nullptr) {
-    it->second.session = std::move(session);
-  }
-  if (application_state != nullptr) {
-    it->second.application_state =
-        std::make_unique<ApplicationState>(*application_state);
-  }
-  it->second.params = std::make_unique<TransportParameters>(params);
-}
-
-std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup(
-    const QuicServerId& server_id, QuicWallTime /*now*/,
-    const SSL_CTX* /*ctx*/) {
-  auto it = cache_entries_.find(server_id);
-  if (it == cache_entries_.end()) {
-    return nullptr;
-  }
-
-  if (!it->second.session) {
-    cache_entries_.erase(it);
-    return nullptr;
-  }
-
-  auto state = std::make_unique<QuicResumptionState>();
-  state->tls_session = std::move(it->second.session);
-  if (it->second.application_state != nullptr) {
-    state->application_state =
-        std::make_unique<ApplicationState>(*it->second.application_state);
-  }
-  state->transport_params =
-      std::make_unique<TransportParameters>(*it->second.params);
-  state->token = it->second.token;
-  return state;
-}
-
-void SimpleSessionCache::ClearEarlyData(const QuicServerId& /*server_id*/) {
-  // The simple session cache only stores 1 SSL ticket per entry, so no need to
-  // do anything here.
-}
-
-void SimpleSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
-                                            absl::string_view token) {
-  auto it = cache_entries_.find(server_id);
-  if (it == cache_entries_.end()) {
-    return;
-  }
-  it->second.token = std::string(token);
-}
-
-void SimpleSessionCache::RemoveExpiredEntries(QuicWallTime /*now*/) {
-  // The simple session cache does not support removing expired entries.
-}
-
-void SimpleSessionCache::Clear() { cache_entries_.clear(); }
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/simple_session_cache.h b/quic/test_tools/simple_session_cache.h
deleted file mode 100644
index 6b4111e..0000000
--- a/quic/test_tools/simple_session_cache.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
-
-#include <memory>
-#include "quic/core/crypto/quic_crypto_client_config.h"
-#include "quic/core/crypto/transport_parameters.h"
-
-namespace quic {
-namespace test {
-
-// SimpleSessionCache provides a simple implementation of SessionCache that
-// stores only one QuicResumptionState per QuicServerId. No limit is placed on
-// the total number of entries in the cache. When Lookup is called, if a cache
-// entry exists for the provided QuicServerId, the entry will be removed from
-// the cached when it is returned.
-// TODO(fayang): Remove SimpleSessionCache by using QuicClientSessionCache.
-class SimpleSessionCache : public SessionCache {
- public:
-  SimpleSessionCache() = default;
-  ~SimpleSessionCache() override = default;
-
-  void Insert(const QuicServerId& server_id,
-              bssl::UniquePtr<SSL_SESSION> session,
-              const TransportParameters& params,
-              const ApplicationState* application_state) override;
-  std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
-                                              QuicWallTime now,
-                                              const SSL_CTX* ctx) override;
-  void ClearEarlyData(const QuicServerId& server_id) override;
-  void OnNewTokenReceived(const QuicServerId& server_id,
-                          absl::string_view token) override;
-  void RemoveExpiredEntries(QuicWallTime now) override;
-  void Clear() override;
-
- private:
-  struct Entry {
-    bssl::UniquePtr<SSL_SESSION> session;
-    std::unique_ptr<TransportParameters> params;
-    std::unique_ptr<ApplicationState> application_state;
-    std::string token;
-  };
-  std::map<QuicServerId, Entry> cache_entries_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
diff --git a/quic/test_tools/simple_session_notifier.cc b/quic/test_tools/simple_session_notifier.cc
deleted file mode 100644
index 7f67fdd..0000000
--- a/quic/test_tools/simple_session_notifier.cc
+++ /dev/null
@@ -1,766 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_session_notifier.h"
-
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/quic_test_utils.h"
-
-namespace quic {
-
-namespace test {
-
-SimpleSessionNotifier::SimpleSessionNotifier(QuicConnection* connection)
-    : last_control_frame_id_(kInvalidControlFrameId),
-      least_unacked_(1),
-      least_unsent_(1),
-      connection_(connection) {}
-
-SimpleSessionNotifier::~SimpleSessionNotifier() {
-  while (!control_frames_.empty()) {
-    DeleteFrame(&control_frames_.front());
-    control_frames_.pop_front();
-  }
-}
-
-SimpleSessionNotifier::StreamState::StreamState()
-    : bytes_total(0),
-      bytes_sent(0),
-      fin_buffered(false),
-      fin_sent(false),
-      fin_outstanding(false),
-      fin_lost(false) {}
-
-SimpleSessionNotifier::StreamState::~StreamState() {}
-
-QuicConsumedData SimpleSessionNotifier::WriteOrBufferData(
-    QuicStreamId id,
-    QuicByteCount data_length,
-    StreamSendingState state) {
-  if (!stream_map_.contains(id)) {
-    stream_map_[id] = StreamState();
-  }
-  StreamState& stream_state = stream_map_.find(id)->second;
-  const bool had_buffered_data =
-      HasBufferedStreamData() || HasBufferedControlFrames();
-  QuicStreamOffset offset = stream_state.bytes_sent;
-  QUIC_DVLOG(1) << "WriteOrBuffer stream_id: " << id << " [" << offset << ", "
-                << offset + data_length << "), fin: " << (state != NO_FIN);
-  stream_state.bytes_total += data_length;
-  stream_state.fin_buffered = state != NO_FIN;
-  if (had_buffered_data) {
-    QUIC_DLOG(WARNING) << "Connection is write blocked";
-    return {0, false};
-  }
-  const size_t length = stream_state.bytes_total - stream_state.bytes_sent;
-  connection_->SetTransmissionType(NOT_RETRANSMISSION);
-  QuicConsumedData consumed =
-      connection_->SendStreamData(id, length, stream_state.bytes_sent, state);
-  QUIC_DVLOG(1) << "consumed: " << consumed;
-  OnStreamDataConsumed(id, stream_state.bytes_sent, consumed.bytes_consumed,
-                       consumed.fin_consumed);
-  return consumed;
-}
-
-void SimpleSessionNotifier::OnStreamDataConsumed(QuicStreamId id,
-                                                 QuicStreamOffset offset,
-                                                 QuicByteCount data_length,
-                                                 bool fin) {
-  StreamState& state = stream_map_.find(id)->second;
-  if (QuicUtils::IsCryptoStreamId(connection_->transport_version(), id) &&
-      data_length > 0) {
-    crypto_bytes_transferred_[connection_->encryption_level()].Add(
-        offset, offset + data_length);
-  }
-  state.bytes_sent += data_length;
-  state.fin_sent = fin;
-  state.fin_outstanding = fin;
-}
-
-size_t SimpleSessionNotifier::WriteCryptoData(EncryptionLevel level,
-                                              QuicByteCount data_length,
-                                              QuicStreamOffset offset) {
-  crypto_state_[level].bytes_total += data_length;
-  size_t bytes_written =
-      connection_->SendCryptoData(level, data_length, offset);
-  crypto_state_[level].bytes_sent += bytes_written;
-  crypto_bytes_transferred_[level].Add(offset, offset + bytes_written);
-  return bytes_written;
-}
-
-void SimpleSessionNotifier::WriteOrBufferRstStream(
-    QuicStreamId id,
-    QuicRstStreamErrorCode error,
-    QuicStreamOffset bytes_written) {
-  QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
-  const bool had_buffered_data =
-      HasBufferedStreamData() || HasBufferedControlFrames();
-  control_frames_.emplace_back((QuicFrame(new QuicRstStreamFrame(
-      ++last_control_frame_id_, id, error, bytes_written))));
-  if (error != QUIC_STREAM_NO_ERROR) {
-    // Delete stream to avoid retransmissions.
-    stream_map_.erase(id);
-  }
-  if (had_buffered_data) {
-    QUIC_DLOG(WARNING) << "Connection is write blocked";
-    return;
-  }
-  WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::WriteOrBufferWindowUpate(
-    QuicStreamId id, QuicStreamOffset byte_offset) {
-  QUIC_DVLOG(1) << "Writing WINDOW_UPDATE";
-  const bool had_buffered_data =
-      HasBufferedStreamData() || HasBufferedControlFrames();
-  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
-  control_frames_.emplace_back(
-      (QuicFrame(QuicWindowUpdateFrame(control_frame_id, id, byte_offset))));
-  if (had_buffered_data) {
-    QUIC_DLOG(WARNING) << "Connection is write blocked";
-    return;
-  }
-  WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::WriteOrBufferPing() {
-  QUIC_DVLOG(1) << "Writing PING_FRAME";
-  const bool had_buffered_data =
-      HasBufferedStreamData() || HasBufferedControlFrames();
-  control_frames_.emplace_back(
-      (QuicFrame(QuicPingFrame(++last_control_frame_id_))));
-  if (had_buffered_data) {
-    QUIC_DLOG(WARNING) << "Connection is write blocked";
-    return;
-  }
-  WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::WriteOrBufferAckFrequency(
-    const QuicAckFrequencyFrame& ack_frequency_frame) {
-  QUIC_DVLOG(1) << "Writing ACK_FREQUENCY";
-  const bool had_buffered_data =
-      HasBufferedStreamData() || HasBufferedControlFrames();
-  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
-  control_frames_.emplace_back((
-      QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
-                                          /*sequence_number=*/control_frame_id,
-                                          ack_frequency_frame.packet_tolerance,
-                                          ack_frequency_frame.max_ack_delay))));
-  if (had_buffered_data) {
-    QUIC_DLOG(WARNING) << "Connection is write blocked";
-    return;
-  }
-  WriteBufferedControlFrames();
-}
-
-void SimpleSessionNotifier::NeuterUnencryptedData() {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
-      QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, interval.min(),
-                                   interval.max() - interval.min());
-      OnFrameAcked(QuicFrame(&crypto_frame), QuicTime::Delta::Zero(),
-                   QuicTime::Zero());
-    }
-    return;
-  }
-  for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
-    QuicStreamFrame stream_frame(
-        QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
-        interval.min(), interval.max() - interval.min());
-    OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
-                 QuicTime::Zero());
-  }
-}
-
-void SimpleSessionNotifier::OnCanWrite() {
-  if (connection_->framer().is_processing_packet()) {
-    // Do not write data in the middle of packet processing because rest
-    // frames in the packet may change the data to write. For example, lost
-    // data could be acknowledged. Also, connection is going to emit
-    // OnCanWrite signal post packet processing.
-    QUIC_BUG(simple_notifier_write_mid_packet_processing)
-        << "Try to write mid packet processing.";
-    return;
-  }
-  if (!RetransmitLostCryptoData() || !RetransmitLostControlFrames() ||
-      !RetransmitLostStreamData()) {
-    return;
-  }
-  if (!WriteBufferedCryptoData() || !WriteBufferedControlFrames()) {
-    return;
-  }
-  // Write new data.
-  for (const auto& pair : stream_map_) {
-    const auto& state = pair.second;
-    if (!StreamHasBufferedData(pair.first)) {
-      continue;
-    }
-
-    const size_t length = state.bytes_total - state.bytes_sent;
-    const bool can_bundle_fin =
-        state.fin_buffered && (state.bytes_sent + length == state.bytes_total);
-    connection_->SetTransmissionType(NOT_RETRANSMISSION);
-    QuicConnection::ScopedEncryptionLevelContext context(
-        connection_,
-        connection_->framer().GetEncryptionLevelToSendApplicationData());
-    QuicConsumedData consumed = connection_->SendStreamData(
-        pair.first, length, state.bytes_sent, can_bundle_fin ? FIN : NO_FIN);
-    QUIC_DVLOG(1) << "Tries to write stream_id: " << pair.first << " ["
-                  << state.bytes_sent << ", " << state.bytes_sent + length
-                  << "), fin: " << can_bundle_fin
-                  << ", and consumed: " << consumed;
-    OnStreamDataConsumed(pair.first, state.bytes_sent, consumed.bytes_consumed,
-                         consumed.fin_consumed);
-    if (length != consumed.bytes_consumed ||
-        (can_bundle_fin && !consumed.fin_consumed)) {
-      break;
-    }
-  }
-}
-
-void SimpleSessionNotifier::OnStreamReset(QuicStreamId id,
-                                          QuicRstStreamErrorCode error) {
-  if (error != QUIC_STREAM_NO_ERROR) {
-    // Delete stream to avoid retransmissions.
-    stream_map_.erase(id);
-  }
-}
-
-bool SimpleSessionNotifier::WillingToWrite() const {
-  QUIC_DVLOG(1) << "has_buffered_control_frames: " << HasBufferedControlFrames()
-                << " as_lost_control_frames: " << !lost_control_frames_.empty()
-                << " has_buffered_stream_data: " << HasBufferedStreamData()
-                << " has_lost_stream_data: " << HasLostStreamData();
-  return HasBufferedControlFrames() || !lost_control_frames_.empty() ||
-         HasBufferedStreamData() || HasLostStreamData();
-}
-
-QuicByteCount SimpleSessionNotifier::StreamBytesSent() const {
-  QuicByteCount bytes_sent = 0;
-  for (const auto& pair : stream_map_) {
-    const auto& state = pair.second;
-    bytes_sent += state.bytes_sent;
-  }
-  return bytes_sent;
-}
-
-QuicByteCount SimpleSessionNotifier::StreamBytesToSend() const {
-  QuicByteCount bytes_to_send = 0;
-  for (const auto& pair : stream_map_) {
-    const auto& state = pair.second;
-    bytes_to_send += (state.bytes_total - state.bytes_sent);
-  }
-  return bytes_to_send;
-}
-
-bool SimpleSessionNotifier::OnFrameAcked(const QuicFrame& frame,
-                                         QuicTime::Delta /*ack_delay_time*/,
-                                         QuicTime /*receive_timestamp*/) {
-  QUIC_DVLOG(1) << "Acking " << frame;
-  if (frame.type == CRYPTO_FRAME) {
-    StreamState* state = &crypto_state_[frame.crypto_frame->level];
-    QuicStreamOffset offset = frame.crypto_frame->offset;
-    QuicByteCount data_length = frame.crypto_frame->data_length;
-    QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
-    newly_acked.Difference(state->bytes_acked);
-    if (newly_acked.Empty()) {
-      return false;
-    }
-    state->bytes_acked.Add(offset, offset + data_length);
-    state->pending_retransmissions.Difference(offset, offset + data_length);
-    return true;
-  }
-  if (frame.type != STREAM_FRAME) {
-    return OnControlFrameAcked(frame);
-  }
-  if (!stream_map_.contains(frame.stream_frame.stream_id)) {
-    return false;
-  }
-  auto* state = &stream_map_.find(frame.stream_frame.stream_id)->second;
-  QuicStreamOffset offset = frame.stream_frame.offset;
-  QuicByteCount data_length = frame.stream_frame.data_length;
-  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
-  newly_acked.Difference(state->bytes_acked);
-  const bool fin_newly_acked = frame.stream_frame.fin && state->fin_outstanding;
-  if (newly_acked.Empty() && !fin_newly_acked) {
-    return false;
-  }
-  state->bytes_acked.Add(offset, offset + data_length);
-  if (fin_newly_acked) {
-    state->fin_outstanding = false;
-    state->fin_lost = false;
-  }
-  state->pending_retransmissions.Difference(offset, offset + data_length);
-  return true;
-}
-
-void SimpleSessionNotifier::OnFrameLost(const QuicFrame& frame) {
-  QUIC_DVLOG(1) << "Losting " << frame;
-  if (frame.type == CRYPTO_FRAME) {
-    StreamState* state = &crypto_state_[frame.crypto_frame->level];
-    QuicStreamOffset offset = frame.crypto_frame->offset;
-    QuicByteCount data_length = frame.crypto_frame->data_length;
-    QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
-    bytes_lost.Difference(state->bytes_acked);
-    if (bytes_lost.Empty()) {
-      return;
-    }
-    for (const auto& lost : bytes_lost) {
-      state->pending_retransmissions.Add(lost.min(), lost.max());
-    }
-    return;
-  }
-  if (frame.type != STREAM_FRAME) {
-    OnControlFrameLost(frame);
-    return;
-  }
-  if (!stream_map_.contains(frame.stream_frame.stream_id)) {
-    return;
-  }
-  auto* state = &stream_map_.find(frame.stream_frame.stream_id)->second;
-  QuicStreamOffset offset = frame.stream_frame.offset;
-  QuicByteCount data_length = frame.stream_frame.data_length;
-  QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
-  bytes_lost.Difference(state->bytes_acked);
-  const bool fin_lost = state->fin_outstanding && frame.stream_frame.fin;
-  if (bytes_lost.Empty() && !fin_lost) {
-    return;
-  }
-  for (const auto& lost : bytes_lost) {
-    state->pending_retransmissions.Add(lost.min(), lost.max());
-  }
-  state->fin_lost = fin_lost;
-}
-
-bool SimpleSessionNotifier::RetransmitFrames(const QuicFrames& frames,
-                                             TransmissionType type) {
-  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
-  connection_->SetTransmissionType(type);
-  for (const QuicFrame& frame : frames) {
-    if (frame.type == CRYPTO_FRAME) {
-      const StreamState& state = crypto_state_[frame.crypto_frame->level];
-      const EncryptionLevel current_encryption_level =
-          connection_->encryption_level();
-      QuicIntervalSet<QuicStreamOffset> retransmission(
-          frame.crypto_frame->offset,
-          frame.crypto_frame->offset + frame.crypto_frame->data_length);
-      retransmission.Difference(state.bytes_acked);
-      for (const auto& interval : retransmission) {
-        QuicStreamOffset offset = interval.min();
-        QuicByteCount length = interval.max() - interval.min();
-        connection_->SetDefaultEncryptionLevel(frame.crypto_frame->level);
-        size_t consumed = connection_->SendCryptoData(frame.crypto_frame->level,
-                                                      length, offset);
-        if (consumed < length) {
-          return false;
-        }
-      }
-      connection_->SetDefaultEncryptionLevel(current_encryption_level);
-    }
-    if (frame.type != STREAM_FRAME) {
-      if (GetControlFrameId(frame) == kInvalidControlFrameId) {
-        continue;
-      }
-      QuicFrame copy = CopyRetransmittableControlFrame(frame);
-      if (!connection_->SendControlFrame(copy)) {
-        // Connection is write blocked.
-        DeleteFrame(&copy);
-        return false;
-      }
-      continue;
-    }
-    if (!stream_map_.contains(frame.stream_frame.stream_id)) {
-      continue;
-    }
-    const auto& state = stream_map_.find(frame.stream_frame.stream_id)->second;
-    QuicIntervalSet<QuicStreamOffset> retransmission(
-        frame.stream_frame.offset,
-        frame.stream_frame.offset + frame.stream_frame.data_length);
-    EncryptionLevel retransmission_encryption_level =
-        connection_->encryption_level();
-    if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
-                                    frame.stream_frame.stream_id)) {
-      for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
-        if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
-          retransmission_encryption_level = static_cast<EncryptionLevel>(i);
-          retransmission.Intersection(crypto_bytes_transferred_[i]);
-          break;
-        }
-      }
-    }
-    retransmission.Difference(state.bytes_acked);
-    bool retransmit_fin = frame.stream_frame.fin && state.fin_outstanding;
-    QuicConsumedData consumed(0, false);
-    for (const auto& interval : retransmission) {
-      QuicStreamOffset retransmission_offset = interval.min();
-      QuicByteCount retransmission_length = interval.max() - interval.min();
-      const bool can_bundle_fin =
-          retransmit_fin &&
-          (retransmission_offset + retransmission_length == state.bytes_sent);
-      QuicConnection::ScopedEncryptionLevelContext context(
-          connection_,
-          QuicUtils::IsCryptoStreamId(connection_->transport_version(),
-                                      frame.stream_frame.stream_id)
-              ? retransmission_encryption_level
-              : connection_->framer()
-                    .GetEncryptionLevelToSendApplicationData());
-      consumed = connection_->SendStreamData(
-          frame.stream_frame.stream_id, retransmission_length,
-          retransmission_offset, can_bundle_fin ? FIN : NO_FIN);
-      QUIC_DVLOG(1) << "stream " << frame.stream_frame.stream_id
-                    << " is forced to retransmit stream data ["
-                    << retransmission_offset << ", "
-                    << retransmission_offset + retransmission_length
-                    << ") and fin: " << can_bundle_fin
-                    << ", consumed: " << consumed;
-      if (can_bundle_fin) {
-        retransmit_fin = !consumed.fin_consumed;
-      }
-      if (consumed.bytes_consumed < retransmission_length ||
-          (can_bundle_fin && !consumed.fin_consumed)) {
-        // Connection is write blocked.
-        return false;
-      }
-    }
-    if (retransmit_fin) {
-      QUIC_DVLOG(1) << "stream " << frame.stream_frame.stream_id
-                    << " retransmits fin only frame.";
-      consumed = connection_->SendStreamData(frame.stream_frame.stream_id, 0,
-                                             state.bytes_sent, FIN);
-      if (!consumed.fin_consumed) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-bool SimpleSessionNotifier::IsFrameOutstanding(const QuicFrame& frame) const {
-  if (frame.type == CRYPTO_FRAME) {
-    QuicStreamOffset offset = frame.crypto_frame->offset;
-    QuicByteCount data_length = frame.crypto_frame->data_length;
-    bool ret = data_length > 0 &&
-               !crypto_state_[frame.crypto_frame->level].bytes_acked.Contains(
-                   offset, offset + data_length);
-    return ret;
-  }
-  if (frame.type != STREAM_FRAME) {
-    return IsControlFrameOutstanding(frame);
-  }
-  if (!stream_map_.contains(frame.stream_frame.stream_id)) {
-    return false;
-  }
-  const auto& state = stream_map_.find(frame.stream_frame.stream_id)->second;
-  QuicStreamOffset offset = frame.stream_frame.offset;
-  QuicByteCount data_length = frame.stream_frame.data_length;
-  return (data_length > 0 &&
-          !state.bytes_acked.Contains(offset, offset + data_length)) ||
-         (frame.stream_frame.fin && state.fin_outstanding);
-}
-
-bool SimpleSessionNotifier::HasUnackedCryptoData() const {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
-      const StreamState& state = crypto_state_[i];
-      if (state.bytes_total > state.bytes_sent) {
-        return true;
-      }
-      QuicIntervalSet<QuicStreamOffset> bytes_to_ack(0, state.bytes_total);
-      bytes_to_ack.Difference(state.bytes_acked);
-      if (!bytes_to_ack.Empty()) {
-        return true;
-      }
-    }
-    return false;
-  }
-  if (!stream_map_.contains(
-          QuicUtils::GetCryptoStreamId(connection_->transport_version()))) {
-    return false;
-  }
-  const auto& state =
-      stream_map_
-          .find(QuicUtils::GetCryptoStreamId(connection_->transport_version()))
-          ->second;
-  if (state.bytes_total > state.bytes_sent) {
-    return true;
-  }
-  QuicIntervalSet<QuicStreamOffset> bytes_to_ack(0, state.bytes_total);
-  bytes_to_ack.Difference(state.bytes_acked);
-  return !bytes_to_ack.Empty();
-}
-
-bool SimpleSessionNotifier::HasUnackedStreamData() const {
-  for (const auto& it : stream_map_) {
-    if (StreamIsWaitingForAcks(it.first))
-      return true;
-  }
-  return false;
-}
-
-bool SimpleSessionNotifier::OnControlFrameAcked(const QuicFrame& frame) {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    return false;
-  }
-  QUICHE_DCHECK(id < least_unacked_ + control_frames_.size());
-  if (id < least_unacked_ ||
-      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
-          kInvalidControlFrameId) {
-    return false;
-  }
-  SetControlFrameId(kInvalidControlFrameId,
-                    &control_frames_.at(id - least_unacked_));
-  lost_control_frames_.erase(id);
-  while (!control_frames_.empty() &&
-         GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
-    DeleteFrame(&control_frames_.front());
-    control_frames_.pop_front();
-    ++least_unacked_;
-  }
-  return true;
-}
-
-void SimpleSessionNotifier::OnControlFrameLost(const QuicFrame& frame) {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    return;
-  }
-  QUICHE_DCHECK(id < least_unacked_ + control_frames_.size());
-  if (id < least_unacked_ ||
-      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
-          kInvalidControlFrameId) {
-    return;
-  }
-  if (!lost_control_frames_.contains(id)) {
-    lost_control_frames_[id] = true;
-  }
-}
-
-bool SimpleSessionNotifier::IsControlFrameOutstanding(
-    const QuicFrame& frame) const {
-  QuicControlFrameId id = GetControlFrameId(frame);
-  if (id == kInvalidControlFrameId) {
-    return false;
-  }
-  return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
-         GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
-             kInvalidControlFrameId;
-}
-
-bool SimpleSessionNotifier::RetransmitLostControlFrames() {
-  while (!lost_control_frames_.empty()) {
-    QuicFrame pending = control_frames_.at(lost_control_frames_.begin()->first -
-                                           least_unacked_);
-    QuicFrame copy = CopyRetransmittableControlFrame(pending);
-    connection_->SetTransmissionType(LOSS_RETRANSMISSION);
-    if (!connection_->SendControlFrame(copy)) {
-      // Connection is write blocked.
-      DeleteFrame(&copy);
-      break;
-    }
-    lost_control_frames_.pop_front();
-  }
-  return lost_control_frames_.empty();
-}
-
-bool SimpleSessionNotifier::RetransmitLostCryptoData() {
-  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    for (EncryptionLevel level :
-         {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
-          ENCRYPTION_FORWARD_SECURE}) {
-      auto& state = crypto_state_[level];
-      while (!state.pending_retransmissions.Empty()) {
-        connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
-        EncryptionLevel current_encryption_level =
-            connection_->encryption_level();
-        connection_->SetDefaultEncryptionLevel(level);
-        QuicIntervalSet<QuicStreamOffset> retransmission(
-            state.pending_retransmissions.begin()->min(),
-            state.pending_retransmissions.begin()->max());
-        retransmission.Intersection(crypto_bytes_transferred_[level]);
-        QuicStreamOffset retransmission_offset = retransmission.begin()->min();
-        QuicByteCount retransmission_length =
-            retransmission.begin()->max() - retransmission.begin()->min();
-        size_t bytes_consumed = connection_->SendCryptoData(
-            level, retransmission_length, retransmission_offset);
-        // Restore encryption level.
-        connection_->SetDefaultEncryptionLevel(current_encryption_level);
-        state.pending_retransmissions.Difference(
-            retransmission_offset, retransmission_offset + bytes_consumed);
-        if (bytes_consumed < retransmission_length) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-  if (!stream_map_.contains(
-          QuicUtils::GetCryptoStreamId(connection_->transport_version()))) {
-    return true;
-  }
-  auto& state =
-      stream_map_
-          .find(QuicUtils::GetCryptoStreamId(connection_->transport_version()))
-          ->second;
-  while (!state.pending_retransmissions.Empty()) {
-    connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
-    QuicIntervalSet<QuicStreamOffset> retransmission(
-        state.pending_retransmissions.begin()->min(),
-        state.pending_retransmissions.begin()->max());
-    EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
-    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
-      if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
-        retransmission_encryption_level = static_cast<EncryptionLevel>(i);
-        retransmission.Intersection(crypto_bytes_transferred_[i]);
-        break;
-      }
-    }
-    QuicStreamOffset retransmission_offset = retransmission.begin()->min();
-    QuicByteCount retransmission_length =
-        retransmission.begin()->max() - retransmission.begin()->min();
-    EncryptionLevel current_encryption_level = connection_->encryption_level();
-    // Set appropriate encryption level.
-    connection_->SetDefaultEncryptionLevel(retransmission_encryption_level);
-    QuicConsumedData consumed = connection_->SendStreamData(
-        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
-        retransmission_length, retransmission_offset, NO_FIN);
-    // Restore encryption level.
-    connection_->SetDefaultEncryptionLevel(current_encryption_level);
-    state.pending_retransmissions.Difference(
-        retransmission_offset, retransmission_offset + consumed.bytes_consumed);
-    if (consumed.bytes_consumed < retransmission_length) {
-      break;
-    }
-  }
-  return state.pending_retransmissions.Empty();
-}
-
-bool SimpleSessionNotifier::RetransmitLostStreamData() {
-  for (auto& pair : stream_map_) {
-    StreamState& state = pair.second;
-    QuicConsumedData consumed(0, false);
-    while (!state.pending_retransmissions.Empty() || state.fin_lost) {
-      connection_->SetTransmissionType(LOSS_RETRANSMISSION);
-      if (state.pending_retransmissions.Empty()) {
-        QUIC_DVLOG(1) << "stream " << pair.first
-                      << " retransmits fin only frame.";
-        consumed =
-            connection_->SendStreamData(pair.first, 0, state.bytes_sent, FIN);
-        state.fin_lost = !consumed.fin_consumed;
-        if (state.fin_lost) {
-          QUIC_DLOG(INFO) << "Connection is write blocked";
-          return false;
-        }
-      } else {
-        QuicStreamOffset offset = state.pending_retransmissions.begin()->min();
-        QuicByteCount length = state.pending_retransmissions.begin()->max() -
-                               state.pending_retransmissions.begin()->min();
-        const bool can_bundle_fin =
-            state.fin_lost && (offset + length == state.bytes_sent);
-        consumed = connection_->SendStreamData(pair.first, length, offset,
-                                               can_bundle_fin ? FIN : NO_FIN);
-        QUIC_DVLOG(1) << "stream " << pair.first
-                      << " tries to retransmit stream data [" << offset << ", "
-                      << offset + length << ") and fin: " << can_bundle_fin
-                      << ", consumed: " << consumed;
-        state.pending_retransmissions.Difference(
-            offset, offset + consumed.bytes_consumed);
-        if (consumed.fin_consumed) {
-          state.fin_lost = false;
-        }
-        if (length > consumed.bytes_consumed ||
-            (can_bundle_fin && !consumed.fin_consumed)) {
-          QUIC_DVLOG(1) << "Connection is write blocked";
-          break;
-        }
-      }
-    }
-  }
-  return !HasLostStreamData();
-}
-
-bool SimpleSessionNotifier::WriteBufferedCryptoData() {
-  for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
-    const StreamState& state = crypto_state_[i];
-    QuicIntervalSet<QuicStreamOffset> buffered_crypto_data(0,
-                                                           state.bytes_total);
-    buffered_crypto_data.Difference(crypto_bytes_transferred_[i]);
-    for (const auto& interval : buffered_crypto_data) {
-      size_t bytes_written = connection_->SendCryptoData(
-          static_cast<EncryptionLevel>(i), interval.Length(), interval.min());
-      crypto_state_[i].bytes_sent += bytes_written;
-      crypto_bytes_transferred_[i].Add(interval.min(),
-                                       interval.min() + bytes_written);
-      if (bytes_written < interval.Length()) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-bool SimpleSessionNotifier::WriteBufferedControlFrames() {
-  while (HasBufferedControlFrames()) {
-    QuicFrame frame_to_send =
-        control_frames_.at(least_unsent_ - least_unacked_);
-    QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
-    connection_->SetTransmissionType(NOT_RETRANSMISSION);
-    if (!connection_->SendControlFrame(copy)) {
-      // Connection is write blocked.
-      DeleteFrame(&copy);
-      break;
-    }
-    ++least_unsent_;
-  }
-  return !HasBufferedControlFrames();
-}
-
-bool SimpleSessionNotifier::HasBufferedControlFrames() const {
-  return least_unsent_ < least_unacked_ + control_frames_.size();
-}
-
-bool SimpleSessionNotifier::HasBufferedStreamData() const {
-  for (const auto& pair : stream_map_) {
-    const auto& state = pair.second;
-    if (state.bytes_total > state.bytes_sent ||
-        (state.fin_buffered && !state.fin_sent)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool SimpleSessionNotifier::StreamIsWaitingForAcks(QuicStreamId id) const {
-  if (!stream_map_.contains(id)) {
-    return false;
-  }
-  const StreamState& state = stream_map_.find(id)->second;
-  return !state.bytes_acked.Contains(0, state.bytes_sent) ||
-         state.fin_outstanding;
-}
-
-bool SimpleSessionNotifier::StreamHasBufferedData(QuicStreamId id) const {
-  if (!stream_map_.contains(id)) {
-    return false;
-  }
-  const StreamState& state = stream_map_.find(id)->second;
-  return state.bytes_total > state.bytes_sent ||
-         (state.fin_buffered && !state.fin_sent);
-}
-
-bool SimpleSessionNotifier::HasLostStreamData() const {
-  for (const auto& pair : stream_map_) {
-    const auto& state = pair.second;
-    if (!state.pending_retransmissions.Empty() || state.fin_lost) {
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace test
-
-}  // namespace quic
diff --git a/quic/test_tools/simple_session_notifier.h b/quic/test_tools/simple_session_notifier.h
deleted file mode 100644
index 0d82c70..0000000
--- a/quic/test_tools/simple_session_notifier.h
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/session_notifier_interface.h"
-#include "quic/platform/api/quic_test.h"
-#include "common/quiche_circular_deque.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-class QuicConnection;
-
-namespace test {
-
-// SimpleSessionNotifier implements the basic functionalities of a session, and
-// it manages stream data and control frames.
-class SimpleSessionNotifier : public SessionNotifierInterface {
- public:
-  explicit SimpleSessionNotifier(QuicConnection* connection);
-  ~SimpleSessionNotifier() override;
-
-  // Tries to write stream data and returns data consumed.
-  QuicConsumedData WriteOrBufferData(QuicStreamId id,
-                                     QuicByteCount data_length,
-                                     StreamSendingState state);
-
-  // Tries to write RST_STREAM_FRAME.
-  void WriteOrBufferRstStream(QuicStreamId id,
-                              QuicRstStreamErrorCode error,
-                              QuicStreamOffset bytes_written);
-
-  // Tries to write WINDOW_UPDATE.
-  void WriteOrBufferWindowUpate(QuicStreamId id, QuicStreamOffset byte_offset);
-
-  // Tries to write PING.
-  void WriteOrBufferPing();
-
-  // Tries to write ACK_FREQUENCY.
-  void WriteOrBufferAckFrequency(
-      const QuicAckFrequencyFrame& ack_frequency_frame);
-
-  // Tries to write CRYPTO data and returns the number of bytes written.
-  size_t WriteCryptoData(EncryptionLevel level,
-                         QuicByteCount data_length,
-                         QuicStreamOffset offset);
-
-  // Neuters unencrypted data of crypto stream.
-  void NeuterUnencryptedData();
-
-  // Called when connection_ becomes writable.
-  void OnCanWrite();
-
-  // Called to reset stream.
-  void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
-
-  // Returns true if there are 1) unsent control frames and stream data, or 2)
-  // lost control frames and stream data.
-  bool WillingToWrite() const;
-
-  // Number of sent stream bytes. Please note, this does not count
-  // retransmissions.
-  QuicByteCount StreamBytesSent() const;
-
-  // Number of stream bytes waiting to be sent for the first time.
-  QuicByteCount StreamBytesToSend() const;
-
-  // Returns true if there is any stream data waiting to be sent for the first
-  // time.
-  bool HasBufferedStreamData() const;
-
-  // Returns true if stream |id| has any outstanding data.
-  bool StreamIsWaitingForAcks(QuicStreamId id) const;
-
-  // SessionNotifierInterface methods:
-  bool OnFrameAcked(const QuicFrame& frame,
-                    QuicTime::Delta ack_delay_time,
-                    QuicTime receive_timestamp) override;
-  void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
-  void OnFrameLost(const QuicFrame& frame) override;
-  bool RetransmitFrames(const QuicFrames& frames,
-                        TransmissionType type) override;
-  bool IsFrameOutstanding(const QuicFrame& frame) const override;
-  bool HasUnackedCryptoData() const override;
-  bool HasUnackedStreamData() const override;
-  bool HasLostStreamData() const;
-
- private:
-  struct StreamState {
-    StreamState();
-    ~StreamState();
-
-    // Total number of bytes.
-    QuicByteCount bytes_total;
-    // Number of sent bytes.
-    QuicByteCount bytes_sent;
-    // Record of acked offsets.
-    QuicIntervalSet<QuicStreamOffset> bytes_acked;
-    // Data considered as lost and needs to be retransmitted.
-    QuicIntervalSet<QuicStreamOffset> pending_retransmissions;
-
-    bool fin_buffered;
-    bool fin_sent;
-    bool fin_outstanding;
-    bool fin_lost;
-  };
-
-  friend std::ostream& operator<<(std::ostream& os, const StreamState& s);
-
-  using StreamMap = absl::flat_hash_map<QuicStreamId, StreamState>;
-
-  void OnStreamDataConsumed(QuicStreamId id,
-                            QuicStreamOffset offset,
-                            QuicByteCount data_length,
-                            bool fin);
-
-  bool OnControlFrameAcked(const QuicFrame& frame);
-
-  void OnControlFrameLost(const QuicFrame& frame);
-
-  bool RetransmitLostControlFrames();
-
-  bool RetransmitLostCryptoData();
-
-  bool RetransmitLostStreamData();
-
-  bool WriteBufferedControlFrames();
-
-  bool WriteBufferedCryptoData();
-
-  bool IsControlFrameOutstanding(const QuicFrame& frame) const;
-
-  bool HasBufferedControlFrames() const;
-
-  bool StreamHasBufferedData(QuicStreamId id) const;
-
-  quiche::QuicheCircularDeque<QuicFrame> control_frames_;
-
-  quiche::QuicheLinkedHashMap<QuicControlFrameId, bool> lost_control_frames_;
-
-  // Id of latest saved control frame. 0 if no control frame has been saved.
-  QuicControlFrameId last_control_frame_id_;
-
-  // The control frame at the 0th index of control_frames_.
-  QuicControlFrameId least_unacked_;
-
-  // ID of the least unsent control frame.
-  QuicControlFrameId least_unsent_;
-
-  StreamMap stream_map_;
-
-  // Transferred crypto bytes according to encryption levels.
-  QuicIntervalSet<QuicStreamOffset>
-      crypto_bytes_transferred_[NUM_ENCRYPTION_LEVELS];
-
-  StreamState crypto_state_[NUM_ENCRYPTION_LEVELS];
-
-  QuicConnection* connection_;
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
diff --git a/quic/test_tools/simple_session_notifier_test.cc b/quic/test_tools/simple_session_notifier_test.cc
deleted file mode 100644
index 552ff5b..0000000
--- a/quic/test_tools/simple_session_notifier_test.cc
+++ /dev/null
@@ -1,370 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simple_session_notifier.h"
-
-#include <utility>
-
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simple_data_producer.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
- public:
-  MockQuicConnectionWithSendStreamData(MockQuicConnectionHelper* helper,
-                                       MockAlarmFactory* alarm_factory,
-                                       Perspective perspective)
-      : MockQuicConnection(helper, alarm_factory, perspective) {}
-
-  MOCK_METHOD(QuicConsumedData,
-              SendStreamData,
-              (QuicStreamId id,
-               size_t write_length,
-               QuicStreamOffset offset,
-               StreamSendingState state),
-              (override));
-};
-
-class SimpleSessionNotifierTest : public QuicTest {
- public:
-  SimpleSessionNotifierTest()
-      : connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT),
-        notifier_(&connection_) {
-    connection_.set_visitor(&visitor_);
-    connection_.SetSessionNotifier(&notifier_);
-    EXPECT_FALSE(notifier_.WillingToWrite());
-    EXPECT_EQ(0u, notifier_.StreamBytesSent());
-    EXPECT_FALSE(notifier_.HasBufferedStreamData());
-  }
-
-  bool ControlFrameConsumed(const QuicFrame& frame) {
-    DeleteFrame(&const_cast<QuicFrame&>(frame));
-    return true;
-  }
-
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  MockQuicConnectionVisitor visitor_;
-  StrictMock<MockQuicConnectionWithSendStreamData> connection_;
-  SimpleSessionNotifier notifier_;
-};
-
-TEST_F(SimpleSessionNotifierTest, WriteOrBufferData) {
-  InSequence s;
-  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(1024, false)));
-  notifier_.WriteOrBufferData(3, 1024, NO_FIN);
-  EXPECT_EQ(0u, notifier_.StreamBytesToSend());
-  EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(512, false)));
-  notifier_.WriteOrBufferData(5, 512, NO_FIN);
-  EXPECT_FALSE(notifier_.WillingToWrite());
-  // Connection is blocked.
-  EXPECT_CALL(connection_, SendStreamData(5, 512, 512, FIN))
-      .WillOnce(Return(QuicConsumedData(256, false)));
-  notifier_.WriteOrBufferData(5, 512, FIN);
-  EXPECT_TRUE(notifier_.WillingToWrite());
-  EXPECT_EQ(1792u, notifier_.StreamBytesSent());
-  EXPECT_EQ(256u, notifier_.StreamBytesToSend());
-  EXPECT_TRUE(notifier_.HasBufferedStreamData());
-
-  // New data cannot be sent as connection is blocked.
-  EXPECT_CALL(connection_, SendStreamData(7, 1024, 0, FIN)).Times(0);
-  notifier_.WriteOrBufferData(7, 1024, FIN);
-  EXPECT_EQ(1792u, notifier_.StreamBytesSent());
-}
-
-TEST_F(SimpleSessionNotifierTest, WriteOrBufferRstStream) {
-  InSequence s;
-  EXPECT_CALL(connection_, SendStreamData(5, 1024, 0, FIN))
-      .WillOnce(Return(QuicConsumedData(1024, true)));
-  notifier_.WriteOrBufferData(5, 1024, FIN);
-  EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
-  EXPECT_TRUE(notifier_.HasUnackedStreamData());
-
-  // Reset stream 5 with no error.
-  EXPECT_CALL(connection_, SendControlFrame(_))
-      .WillRepeatedly(
-          Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
-  notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 1024);
-  // Verify stream 5 is waiting for acks.
-  EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
-  EXPECT_TRUE(notifier_.HasUnackedStreamData());
-
-  // Reset stream 5 with error.
-  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
-  EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(5));
-  EXPECT_FALSE(notifier_.HasUnackedStreamData());
-}
-
-TEST_F(SimpleSessionNotifierTest, WriteOrBufferPing) {
-  InSequence s;
-  // Write ping when connection is not write blocked.
-  EXPECT_CALL(connection_, SendControlFrame(_))
-      .WillRepeatedly(
-          Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
-  notifier_.WriteOrBufferPing();
-  EXPECT_EQ(0u, notifier_.StreamBytesToSend());
-  EXPECT_FALSE(notifier_.WillingToWrite());
-
-  // Write stream data and cause the connection to be write blocked.
-  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(1024, false)));
-  notifier_.WriteOrBufferData(3, 1024, NO_FIN);
-  EXPECT_EQ(0u, notifier_.StreamBytesToSend());
-  EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(256, false)));
-  notifier_.WriteOrBufferData(5, 512, NO_FIN);
-  EXPECT_TRUE(notifier_.WillingToWrite());
-
-  // Connection is blocked.
-  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
-  notifier_.WriteOrBufferPing();
-}
-
-TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    // This test writes crypto data through crypto streams. It won't work when
-    // crypto frames are used instead.
-    return;
-  }
-  InSequence s;
-  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
-                                              connection_.transport_version()),
-                                          1024, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(1024, false)));
-  notifier_.WriteOrBufferData(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
-      NO_FIN);
-  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
-                                              connection_.transport_version()),
-                                          1024, 1024, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(1024, false)));
-  notifier_.WriteOrBufferData(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
-      NO_FIN);
-  // Ack [1024, 2048).
-  QuicStreamFrame stream_frame(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
-      1024, 1024);
-  notifier_.OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
-                         QuicTime::Zero());
-  EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version())));
-  EXPECT_TRUE(notifier_.HasUnackedStreamData());
-
-  // Neuters unencrypted data.
-  notifier_.NeuterUnencryptedData();
-  EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version())));
-  EXPECT_FALSE(notifier_.HasUnackedStreamData());
-}
-
-TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
-  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    // This test writes crypto data through crypto streams. It won't work when
-    // crypto frames are used instead.
-    return;
-  }
-  InSequence s;
-  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
-                                              connection_.transport_version()),
-                                          1024, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(1024, false)));
-  notifier_.WriteOrBufferData(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
-      NO_FIN);
-
-  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
-                                              connection_.transport_version()),
-                                          1024, 1024, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(1024, false)));
-  notifier_.WriteOrBufferData(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
-      NO_FIN);
-  // Send stream 3 [0, 1024) and connection is blocked.
-  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
-      .WillOnce(Return(QuicConsumedData(512, false)));
-  notifier_.WriteOrBufferData(3, 1024, FIN);
-  // Send stream 5 [0, 1024).
-  EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
-  notifier_.WriteOrBufferData(5, 1024, NO_FIN);
-  // Reset stream 5 with error.
-  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
-  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
-
-  // Lost crypto data [500, 1500) and stream 3 [0, 512).
-  QuicStreamFrame frame1(
-      QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 500,
-      1000);
-  QuicStreamFrame frame2(3, false, 0, 512);
-  notifier_.OnFrameLost(QuicFrame(frame1));
-  notifier_.OnFrameLost(QuicFrame(frame2));
-
-  // Connection becomes writable.
-  // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
-  // they are in different encryption levels.
-  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
-                                              connection_.transport_version()),
-                                          524, 500, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(524, false)));
-  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
-                                              connection_.transport_version()),
-                                          476, 1024, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(476, false)));
-  // Lost stream 3 data gets retransmitted.
-  EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(512, false)));
-  // Buffered control frames get sent.
-  EXPECT_CALL(connection_, SendControlFrame(_))
-      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
-  // Buffered stream 3 data [512, 1024) gets sent.
-  EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
-      .WillOnce(Return(QuicConsumedData(512, true)));
-  notifier_.OnCanWrite();
-  EXPECT_FALSE(notifier_.WillingToWrite());
-}
-
-TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
-  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
-    return;
-  }
-  SimpleDataProducer producer;
-  connection_.SetDataProducer(&producer);
-  InSequence s;
-  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
-      .WillOnce(Invoke(&connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  EXPECT_CALL(connection_, CloseConnection(QUIC_PACKET_WRITE_ERROR, _, _));
-  std::string crypto_data1(1024, 'a');
-  producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, crypto_data1);
-  std::string crypto_data2(524, 'a');
-  producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, crypto_data2);
-  notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
-  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
-  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
-                                                    Perspective::IS_CLIENT));
-  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
-  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
-      .WillOnce(Invoke(&connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  std::string crypto_data3(1024, 'a');
-  producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, crypto_data3);
-  notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
-  // Send stream 3 [0, 1024) and connection is blocked.
-  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
-      .WillOnce(Return(QuicConsumedData(512, false)));
-  notifier_.WriteOrBufferData(3, 1024, FIN);
-  // Send stream 5 [0, 1024).
-  EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
-  notifier_.WriteOrBufferData(5, 1024, NO_FIN);
-  // Reset stream 5 with error.
-  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
-  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
-
-  // Lost crypto data [500, 1500) and stream 3 [0, 512).
-  QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
-  QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
-  QuicStreamFrame stream3_frame(3, false, 0, 512);
-  notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
-  notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
-  notifier_.OnFrameLost(QuicFrame(stream3_frame));
-
-  // Connection becomes writable.
-  // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
-  // they are in different encryption levels.
-  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
-      .WillOnce(Invoke(&connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
-      .WillOnce(Invoke(&connection_,
-                       &MockQuicConnection::QuicConnection_SendCryptoData));
-  // Lost stream 3 data gets retransmitted.
-  EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(512, false)));
-  // Buffered control frames get sent.
-  EXPECT_CALL(connection_, SendControlFrame(_))
-      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
-  // Buffered stream 3 data [512, 1024) gets sent.
-  EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
-      .WillOnce(Return(QuicConsumedData(512, true)));
-  notifier_.OnCanWrite();
-  EXPECT_FALSE(notifier_.WillingToWrite());
-}
-
-TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
-  InSequence s;
-  connection_.SetEncrypter(
-      ENCRYPTION_FORWARD_SECURE,
-      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
-  // Send stream 3 data [0, 10) and fin.
-  EXPECT_CALL(connection_, SendStreamData(3, 10, 0, FIN))
-      .WillOnce(Return(QuicConsumedData(10, true)));
-  notifier_.WriteOrBufferData(3, 10, FIN);
-  QuicStreamFrame frame1(3, true, 0, 10);
-  // Send stream 5 [0, 10) and fin.
-  EXPECT_CALL(connection_, SendStreamData(5, 10, 0, FIN))
-      .WillOnce(Return(QuicConsumedData(10, true)));
-  notifier_.WriteOrBufferData(5, 10, FIN);
-  QuicStreamFrame frame2(5, true, 0, 10);
-  // Reset stream 5 with no error.
-  EXPECT_CALL(connection_, SendControlFrame(_))
-      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
-  notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 10);
-
-  // Ack stream 3 [3, 7), and stream 5 [8, 10).
-  QuicStreamFrame ack_frame1(3, false, 3, 4);
-  QuicStreamFrame ack_frame2(5, false, 8, 2);
-  notifier_.OnFrameAcked(QuicFrame(ack_frame1), QuicTime::Delta::Zero(),
-                         QuicTime::Zero());
-  notifier_.OnFrameAcked(QuicFrame(ack_frame2), QuicTime::Delta::Zero(),
-                         QuicTime::Zero());
-  EXPECT_FALSE(notifier_.WillingToWrite());
-
-  // Force to send.
-  QuicRstStreamFrame rst_stream(1, 5, QUIC_STREAM_NO_ERROR, 10);
-  QuicFrames frames;
-  frames.push_back(QuicFrame(frame2));
-  frames.push_back(QuicFrame(&rst_stream));
-  frames.push_back(QuicFrame(frame1));
-  // stream 5 data [0, 8), fin only are retransmitted.
-  EXPECT_CALL(connection_, SendStreamData(5, 8, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(8, false)));
-  EXPECT_CALL(connection_, SendStreamData(5, 0, 10, FIN))
-      .WillOnce(Return(QuicConsumedData(0, true)));
-  // rst_stream is retransmitted.
-  EXPECT_CALL(connection_, SendControlFrame(_))
-      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
-  // stream 3 data [0, 3) is retransmitted and connection is blocked.
-  EXPECT_CALL(connection_, SendStreamData(3, 3, 0, NO_FIN))
-      .WillOnce(Return(QuicConsumedData(2, false)));
-  notifier_.RetransmitFrames(frames, RTO_RETRANSMISSION);
-  EXPECT_FALSE(notifier_.WillingToWrite());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/simulator/actor.cc b/quic/test_tools/simulator/actor.cc
deleted file mode 100644
index acb548c..0000000
--- a/quic/test_tools/simulator/actor.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/actor.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-Actor::Actor(Simulator* simulator, std::string name)
-    : simulator_(simulator),
-      clock_(simulator->GetClock()),
-      name_(std::move(name)) {
-  simulator_->AddActor(this);
-}
-
-Actor::~Actor() {
-  simulator_->RemoveActor(this);
-}
-
-void Actor::Schedule(QuicTime next_tick) {
-  simulator_->Schedule(this, next_tick);
-}
-
-void Actor::Unschedule() {
-  simulator_->Unschedule(this);
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/actor.h b/quic/test_tools/simulator/actor.h
deleted file mode 100644
index 24cfe15..0000000
--- a/quic/test_tools/simulator/actor.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
-
-#include <string>
-
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-namespace simulator {
-
-class Simulator;
-
-// Actor is the base class for all participants of the simulation which can
-// schedule events to be triggered at the specified time.  Every actor has a
-// name assigned to it, which can be used for debugging and addressing purposes.
-//
-// The Actor object is scheduled as follows:
-// 1. Every Actor object appears at most once in the event queue, for one
-//    specific time.
-// 2. Actor is scheduled by calling Schedule() method.
-// 3. If Schedule() method is called with multiple different times specified,
-//    Act() method will be called at the earliest time specified.
-// 4. Before Act() is called, the Actor is removed from the event queue.  Act()
-//    will not be called again unless Schedule() is called.
-class Actor {
- public:
-  Actor(Simulator* simulator, std::string name);
-  virtual ~Actor();
-
-  // Trigger all the events the actor can potentially handle at this point.
-  // Before Act() is called, the actor is removed from the event queue, and has
-  // to schedule the next call manually.
-  virtual void Act() = 0;
-
-  std::string name() const { return name_; }
-  Simulator* simulator() const { return simulator_; }
-
- protected:
-  // Calls Schedule() on the associated simulator.
-  void Schedule(QuicTime next_tick);
-
-  // Calls Unschedule() on the associated simulator.
-  void Unschedule();
-
-  Simulator* simulator_;
-  const QuicClock* clock_;
-  std::string name_;
-
- private:
-  // Since the Actor object registers itself with a simulator using a pointer to
-  // itself, do not allow it to be moved.
-  Actor(Actor&&) = delete;
-  Actor(const Actor&) = delete;
-  Actor& operator=(const Actor&) = delete;
-  Actor& operator=(Actor&&) = delete;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
diff --git a/quic/test_tools/simulator/alarm_factory.cc b/quic/test_tools/simulator/alarm_factory.cc
deleted file mode 100644
index 86ee49e..0000000
--- a/quic/test_tools/simulator/alarm_factory.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/alarm_factory.h"
-
-#include "absl/strings/str_format.h"
-#include "quic/core/quic_alarm.h"
-
-namespace quic {
-namespace simulator {
-
-// Alarm is an implementation of QuicAlarm which can schedule alarms in the
-// simulation timeline.
-class Alarm : public QuicAlarm {
- public:
-  Alarm(Simulator* simulator,
-        std::string name,
-        QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
-      : QuicAlarm(std::move(delegate)), adapter_(simulator, name, this) {}
-  ~Alarm() override {}
-
-  void SetImpl() override {
-    QUICHE_DCHECK(deadline().IsInitialized());
-    adapter_.Set(deadline());
-  }
-
-  void CancelImpl() override { adapter_.Cancel(); }
-
- private:
-  // An adapter class triggering a QuicAlarm using a simulation time system.
-  // An adapter is required here because neither Actor nor QuicAlarm are pure
-  // interfaces.
-  class Adapter : public Actor {
-   public:
-    Adapter(Simulator* simulator, std::string name, Alarm* parent)
-        : Actor(simulator, name), parent_(parent) {}
-    ~Adapter() override {}
-
-    void Set(QuicTime time) { Schedule(std::max(time, clock_->Now())); }
-    void Cancel() { Unschedule(); }
-
-    void Act() override {
-      QUICHE_DCHECK(clock_->Now() >= parent_->deadline());
-      parent_->Fire();
-    }
-
-   private:
-    Alarm* parent_;
-  };
-  Adapter adapter_;
-};
-
-AlarmFactory::AlarmFactory(Simulator* simulator, std::string name)
-    : simulator_(simulator), name_(std::move(name)), counter_(0) {}
-
-AlarmFactory::~AlarmFactory() {}
-
-std::string AlarmFactory::GetNewAlarmName() {
-  ++counter_;
-  return absl::StrFormat("%s (alarm %i)", name_, counter_);
-}
-
-QuicAlarm* AlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
-  return new Alarm(simulator_, GetNewAlarmName(),
-                   QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
-QuicArenaScopedPtr<QuicAlarm> AlarmFactory::CreateAlarm(
-    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-    QuicConnectionArena* arena) {
-  if (arena != nullptr) {
-    return arena->New<Alarm>(simulator_, GetNewAlarmName(),
-                             std::move(delegate));
-  }
-  return QuicArenaScopedPtr<QuicAlarm>(
-      new Alarm(simulator_, GetNewAlarmName(), std::move(delegate)));
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/alarm_factory.h b/quic/test_tools/simulator/alarm_factory.h
deleted file mode 100644
index a9fdd33..0000000
--- a/quic/test_tools/simulator/alarm_factory.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
-
-#include "quic/core/quic_alarm_factory.h"
-#include "quic/test_tools/simulator/actor.h"
-
-namespace quic {
-namespace simulator {
-
-// AlarmFactory allows to schedule QuicAlarms using the simulation event queue.
-class AlarmFactory : public QuicAlarmFactory {
- public:
-  AlarmFactory(Simulator* simulator, std::string name);
-  AlarmFactory(const AlarmFactory&) = delete;
-  AlarmFactory& operator=(const AlarmFactory&) = delete;
-  ~AlarmFactory() override;
-
-  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
-  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
-      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
-      QuicConnectionArena* arena) override;
-
- private:
-  // Automatically generate a name for a new alarm.
-  std::string GetNewAlarmName();
-
-  Simulator* simulator_;
-  std::string name_;
-  int counter_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
diff --git a/quic/test_tools/simulator/link.cc b/quic/test_tools/simulator/link.cc
deleted file mode 100644
index 6d43597..0000000
--- a/quic/test_tools/simulator/link.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/link.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-// Parameters for random noise delay.
-const uint64_t kMaxRandomDelayUs = 10;
-
-OneWayLink::OneWayLink(Simulator* simulator,
-                       std::string name,
-                       UnconstrainedPortInterface* sink,
-                       QuicBandwidth bandwidth,
-                       QuicTime::Delta propagation_delay)
-    : Actor(simulator, name),
-      sink_(sink),
-      bandwidth_(bandwidth),
-      propagation_delay_(propagation_delay),
-      next_write_at_(QuicTime::Zero()) {}
-
-OneWayLink::~OneWayLink() {}
-
-OneWayLink::QueuedPacket::QueuedPacket(std::unique_ptr<Packet> packet,
-                                       QuicTime dequeue_time)
-    : packet(std::move(packet)), dequeue_time(dequeue_time) {}
-
-OneWayLink::QueuedPacket::QueuedPacket(QueuedPacket&& other) = default;
-
-OneWayLink::QueuedPacket::~QueuedPacket() {}
-
-void OneWayLink::AcceptPacket(std::unique_ptr<Packet> packet) {
-  QUICHE_DCHECK(TimeUntilAvailable().IsZero());
-  QuicTime::Delta transfer_time = bandwidth_.TransferTime(packet->size);
-  next_write_at_ = clock_->Now() + transfer_time;
-
-  packets_in_transit_.emplace_back(
-      std::move(packet),
-      // Ensure that packets are delivered in order.
-      std::max(
-          next_write_at_ + propagation_delay_ + GetRandomDelay(transfer_time),
-          packets_in_transit_.empty()
-              ? QuicTime::Zero()
-              : packets_in_transit_.back().dequeue_time));
-  ScheduleNextPacketDeparture();
-}
-
-QuicTime::Delta OneWayLink::TimeUntilAvailable() {
-  const QuicTime now = clock_->Now();
-  if (next_write_at_ <= now) {
-    return QuicTime::Delta::Zero();
-  }
-
-  return next_write_at_ - now;
-}
-
-void OneWayLink::Act() {
-  QUICHE_DCHECK(!packets_in_transit_.empty());
-  QUICHE_DCHECK(packets_in_transit_.front().dequeue_time >= clock_->Now());
-
-  sink_->AcceptPacket(std::move(packets_in_transit_.front().packet));
-  packets_in_transit_.pop_front();
-
-  ScheduleNextPacketDeparture();
-}
-
-void OneWayLink::ScheduleNextPacketDeparture() {
-  if (packets_in_transit_.empty()) {
-    return;
-  }
-
-  Schedule(packets_in_transit_.front().dequeue_time);
-}
-
-QuicTime::Delta OneWayLink::GetRandomDelay(QuicTime::Delta transfer_time) {
-  if (!simulator_->enable_random_delays()) {
-    return QuicTime::Delta::Zero();
-  }
-
-  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(
-      simulator_->GetRandomGenerator()->RandUint64() % (kMaxRandomDelayUs + 1));
-  // Have an upper bound on the delay to ensure packets do not go out of order.
-  delta = std::min(delta, transfer_time * 0.5);
-  return delta;
-}
-
-SymmetricLink::SymmetricLink(Simulator* simulator,
-                             std::string name,
-                             UnconstrainedPortInterface* sink_a,
-                             UnconstrainedPortInterface* sink_b,
-                             QuicBandwidth bandwidth,
-                             QuicTime::Delta propagation_delay)
-    : a_to_b_link_(simulator,
-                   absl::StrCat(name, " (A-to-B)"),
-                   sink_b,
-                   bandwidth,
-                   propagation_delay),
-      b_to_a_link_(simulator,
-                   absl::StrCat(name, " (B-to-A)"),
-                   sink_a,
-                   bandwidth,
-                   propagation_delay) {}
-
-SymmetricLink::SymmetricLink(Endpoint* endpoint_a,
-                             Endpoint* endpoint_b,
-                             QuicBandwidth bandwidth,
-                             QuicTime::Delta propagation_delay)
-    : SymmetricLink(endpoint_a->simulator(),
-                    absl::StrFormat("Link [%s]<->[%s]",
-                                    endpoint_a->name(),
-                                    endpoint_b->name()),
-                    endpoint_a->GetRxPort(),
-                    endpoint_b->GetRxPort(),
-                    bandwidth,
-                    propagation_delay) {
-  endpoint_a->SetTxPort(&a_to_b_link_);
-  endpoint_b->SetTxPort(&b_to_a_link_);
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/link.h b/quic/test_tools/simulator/link.h
deleted file mode 100644
index efe3727..0000000
--- a/quic/test_tools/simulator/link.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
-
-#include <utility>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_bandwidth.h"
-#include "quic/test_tools/simulator/actor.h"
-#include "quic/test_tools/simulator/port.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace simulator {
-
-// A reliable simplex link between two endpoints with constrained bandwidth.  A
-// few microseconds of random delay are added for every packet to avoid
-// synchronization issues.
-class OneWayLink : public Actor, public ConstrainedPortInterface {
- public:
-  OneWayLink(Simulator* simulator,
-             std::string name,
-             UnconstrainedPortInterface* sink,
-             QuicBandwidth bandwidth,
-             QuicTime::Delta propagation_delay);
-  OneWayLink(const OneWayLink&) = delete;
-  OneWayLink& operator=(const OneWayLink&) = delete;
-  ~OneWayLink() override;
-
-  void AcceptPacket(std::unique_ptr<Packet> packet) override;
-  QuicTime::Delta TimeUntilAvailable() override;
-  void Act() override;
-
-  QuicBandwidth bandwidth() const { return bandwidth_; }
-  void set_bandwidth(QuicBandwidth new_bandwidth) {
-    bandwidth_ = new_bandwidth;
-  }
-
- protected:
-  // Get the value of a random delay imposed on each packet.  By default, this
-  // is a short random delay in order to avoid artifical synchronization
-  // artifacts during the simulation.  Subclasses may override this behavior
-  // (for example, to provide a random component of delay).
-  virtual QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time);
-
- private:
-  struct QueuedPacket {
-    std::unique_ptr<Packet> packet;
-    QuicTime dequeue_time;
-
-    QueuedPacket(std::unique_ptr<Packet> packet, QuicTime dequeue_time);
-    QueuedPacket(QueuedPacket&& other);
-    ~QueuedPacket();
-  };
-
-  // Schedule the next packet to be egressed out of the link if there are
-  // packets on the link.
-  void ScheduleNextPacketDeparture();
-
-  UnconstrainedPortInterface* sink_;
-  quiche::QuicheCircularDeque<QueuedPacket> packets_in_transit_;
-
-  QuicBandwidth bandwidth_;
-  const QuicTime::Delta propagation_delay_;
-
-  QuicTime next_write_at_;
-};
-
-// A full-duplex link between two endpoints, functionally equivalent to two
-// OneWayLink objects tied together.
-class SymmetricLink {
- public:
-  SymmetricLink(Simulator* simulator,
-                std::string name,
-                UnconstrainedPortInterface* sink_a,
-                UnconstrainedPortInterface* sink_b,
-                QuicBandwidth bandwidth,
-                QuicTime::Delta propagation_delay);
-  SymmetricLink(Endpoint* endpoint_a,
-                Endpoint* endpoint_b,
-                QuicBandwidth bandwidth,
-                QuicTime::Delta propagation_delay);
-  SymmetricLink(const SymmetricLink&) = delete;
-  SymmetricLink& operator=(const SymmetricLink&) = delete;
-
-  QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); }
-  void set_bandwidth(QuicBandwidth new_bandwidth) {
-    a_to_b_link_.set_bandwidth(new_bandwidth);
-    b_to_a_link_.set_bandwidth(new_bandwidth);
-  }
-
- private:
-  OneWayLink a_to_b_link_;
-  OneWayLink b_to_a_link_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
diff --git a/quic/test_tools/simulator/packet_filter.cc b/quic/test_tools/simulator/packet_filter.cc
deleted file mode 100644
index 0cbb1f0..0000000
--- a/quic/test_tools/simulator/packet_filter.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/packet_filter.h"
-
-namespace quic {
-namespace simulator {
-
-PacketFilter::PacketFilter(Simulator* simulator,
-                           std::string name,
-                           Endpoint* input)
-    : Endpoint(simulator, name), input_(input) {
-  input_->SetTxPort(this);
-}
-
-PacketFilter::~PacketFilter() {}
-
-void PacketFilter::AcceptPacket(std::unique_ptr<Packet> packet) {
-  if (FilterPacket(*packet)) {
-    output_tx_port_->AcceptPacket(std::move(packet));
-  }
-}
-
-QuicTime::Delta PacketFilter::TimeUntilAvailable() {
-  return output_tx_port_->TimeUntilAvailable();
-}
-
-void PacketFilter::Act() {}
-
-UnconstrainedPortInterface* PacketFilter::GetRxPort() {
-  return input_->GetRxPort();
-}
-
-void PacketFilter::SetTxPort(ConstrainedPortInterface* port) {
-  output_tx_port_ = port;
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/packet_filter.h b/quic/test_tools/simulator/packet_filter.h
deleted file mode 100644
index d744353..0000000
--- a/quic/test_tools/simulator/packet_filter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
-
-#include "quic/test_tools/simulator/port.h"
-
-namespace quic {
-namespace simulator {
-
-// Packet filter allows subclasses to filter out the packets that enter the
-// input port and exit the output port.  Packets in the other direction are
-// always passed through.
-//
-// The filter wraps around the input endpoint, and exposes the resulting
-// filtered endpoint via the output() method.  For example, if initially there
-// are two endpoints, A and B, connected via a symmetric link:
-//
-//   QuicEndpoint endpoint_a;
-//   QuicEndpoint endpoint_b;
-//
-//   [...]
-//
-//   SymmetricLink a_b_link(&endpoint_a, &endpoint_b, ...);
-//
-// and the goal is to filter the traffic from A to B, then the new invocation
-// would be as follows:
-//
-//   PacketFilter filter(&simulator, "A-to-B packet filter", endpoint_a);
-//   SymmetricLink a_b_link(&filter, &endpoint_b, ...);
-//
-// Note that the filter drops the packet instanteneously, without it ever
-// reaching the output wire.  This means that in a direct endpoint-to-endpoint
-// scenario, whenever the packet is dropped, the link would become immediately
-// available for the next packet.
-class PacketFilter : public Endpoint, public ConstrainedPortInterface {
- public:
-  // Initialize the filter by wrapping around |input|.  Does not take the
-  // ownership of |input|.
-  PacketFilter(Simulator* simulator, std::string name, Endpoint* input);
-  PacketFilter(const PacketFilter&) = delete;
-  PacketFilter& operator=(const PacketFilter&) = delete;
-  ~PacketFilter() override;
-
-  // Implementation of ConstrainedPortInterface.
-  void AcceptPacket(std::unique_ptr<Packet> packet) override;
-  QuicTime::Delta TimeUntilAvailable() override;
-
-  // Implementation of Endpoint interface methods.
-  UnconstrainedPortInterface* GetRxPort() override;
-  void SetTxPort(ConstrainedPortInterface* port) override;
-
-  // Implementation of Actor interface methods.
-  void Act() override;
-
- protected:
-  // Returns true if the packet should be passed through, and false if it should
-  // be dropped.  The function is called once per packet, in the order that the
-  // packets arrive, so it is safe for the function to alter the internal state
-  // of the filter.
-  virtual bool FilterPacket(const Packet& packet) = 0;
-
- private:
-  // The port onto which the filtered packets are egressed.
-  ConstrainedPortInterface* output_tx_port_;
-
-  // The original network endpoint wrapped by the class.
-  Endpoint* input_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
diff --git a/quic/test_tools/simulator/port.cc b/quic/test_tools/simulator/port.cc
deleted file mode 100644
index 7aa4df3..0000000
--- a/quic/test_tools/simulator/port.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/port.h"
-
-namespace quic {
-namespace simulator {
-
-Packet::Packet()
-    : source(), destination(), tx_timestamp(QuicTime::Zero()), size(0) {}
-
-Packet::~Packet() {}
-
-Packet::Packet(const Packet& packet) = default;
-
-Endpoint::Endpoint(Simulator* simulator, std::string name)
-    : Actor(simulator, name) {}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/port.h b/quic/test_tools/simulator/port.h
deleted file mode 100644
index 772b2d5..0000000
--- a/quic/test_tools/simulator/port.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
-
-#include <string>
-#include <utility>
-
-#include "quic/core/quic_packets.h"
-#include "quic/test_tools/simulator/actor.h"
-
-namespace quic {
-namespace simulator {
-
-struct Packet {
-  Packet();
-  ~Packet();
-  Packet(const Packet& packet);
-
-  std::string source;
-  std::string destination;
-  QuicTime tx_timestamp;
-
-  std::string contents;
-  QuicByteCount size;
-};
-
-// An interface for anything that accepts packets at arbitrary rate.
-class UnconstrainedPortInterface {
- public:
-  virtual ~UnconstrainedPortInterface() {}
-  virtual void AcceptPacket(std::unique_ptr<Packet> packet) = 0;
-};
-
-// An interface for any device that accepts packets at a specific rate.
-// Typically one would use a Queue object in order to write into a constrained
-// port.
-class ConstrainedPortInterface {
- public:
-  virtual ~ConstrainedPortInterface() {}
-
-  // Accept a packet for a port.  TimeUntilAvailable() must be zero before this
-  // method is called.
-  virtual void AcceptPacket(std::unique_ptr<Packet> packet) = 0;
-
-  // Time until write for the next port is available.  Cannot be infinite.
-  virtual QuicTime::Delta TimeUntilAvailable() = 0;
-};
-
-// A convenience class for any network endpoints, i.e. the objects which can
-// both accept and send packets.
-class Endpoint : public Actor {
- public:
-  virtual UnconstrainedPortInterface* GetRxPort() = 0;
-  virtual void SetTxPort(ConstrainedPortInterface* port) = 0;
-
- protected:
-  Endpoint(Simulator* simulator, std::string name);
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
diff --git a/quic/test_tools/simulator/queue.cc b/quic/test_tools/simulator/queue.cc
deleted file mode 100644
index c7e23cd..0000000
--- a/quic/test_tools/simulator/queue.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/queue.h"
-
-#include "quic/platform/api/quic_logging.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-Queue::ListenerInterface::~ListenerInterface() {}
-
-Queue::Queue(Simulator* simulator, std::string name, QuicByteCount capacity)
-    : Actor(simulator, name),
-      capacity_(capacity),
-      bytes_queued_(0),
-      aggregation_threshold_(0),
-      aggregation_timeout_(QuicTime::Delta::Infinite()),
-      current_bundle_(0),
-      current_bundle_bytes_(0),
-      tx_port_(nullptr),
-      listener_(nullptr) {
-  aggregation_timeout_alarm_.reset(simulator_->GetAlarmFactory()->CreateAlarm(
-      new AggregationAlarmDelegate(this)));
-}
-
-Queue::~Queue() { aggregation_timeout_alarm_->PermanentCancel(); }
-
-void Queue::set_tx_port(ConstrainedPortInterface* port) {
-  tx_port_ = port;
-}
-
-void Queue::AcceptPacket(std::unique_ptr<Packet> packet) {
-  if (packet->size + bytes_queued_ > capacity_) {
-    QUIC_DVLOG(1) << "Queue [" << name() << "] has received a packet from ["
-                  << packet->source << "] to [" << packet->destination
-                  << "] which is over capacity.  Dropping it.";
-    QUIC_DVLOG(1) << "Queue size: " << bytes_queued_ << " out of " << capacity_
-                  << ".  Packet size: " << packet->size;
-    return;
-  }
-
-  bytes_queued_ += packet->size;
-  queue_.emplace_back(std::move(packet), current_bundle_);
-
-  if (IsAggregationEnabled()) {
-    current_bundle_bytes_ += queue_.front().packet->size;
-    if (!aggregation_timeout_alarm_->IsSet()) {
-      aggregation_timeout_alarm_->Set(clock_->Now() + aggregation_timeout_);
-    }
-    if (current_bundle_bytes_ >= aggregation_threshold_) {
-      NextBundle();
-    }
-  }
-
-  ScheduleNextPacketDequeue();
-}
-
-void Queue::Act() {
-  QUICHE_DCHECK(!queue_.empty());
-  if (tx_port_->TimeUntilAvailable().IsZero()) {
-    QUICHE_DCHECK(bytes_queued_ >= queue_.front().packet->size);
-    bytes_queued_ -= queue_.front().packet->size;
-
-    tx_port_->AcceptPacket(std::move(queue_.front().packet));
-    queue_.pop_front();
-    if (listener_ != nullptr) {
-      listener_->OnPacketDequeued();
-    }
-  }
-
-  ScheduleNextPacketDequeue();
-}
-
-void Queue::EnableAggregation(QuicByteCount aggregation_threshold,
-                              QuicTime::Delta aggregation_timeout) {
-  QUICHE_DCHECK_EQ(bytes_queued_, 0u);
-  QUICHE_DCHECK_GT(aggregation_threshold, 0u);
-  QUICHE_DCHECK(!aggregation_timeout.IsZero());
-  QUICHE_DCHECK(!aggregation_timeout.IsInfinite());
-
-  aggregation_threshold_ = aggregation_threshold;
-  aggregation_timeout_ = aggregation_timeout;
-}
-
-Queue::AggregationAlarmDelegate::AggregationAlarmDelegate(Queue* queue)
-    : queue_(queue) {}
-
-void Queue::AggregationAlarmDelegate::OnAlarm() {
-  queue_->NextBundle();
-  queue_->ScheduleNextPacketDequeue();
-}
-
-Queue::EnqueuedPacket::EnqueuedPacket(std::unique_ptr<Packet> packet,
-                                      AggregationBundleNumber bundle)
-    : packet(std::move(packet)), bundle(bundle) {}
-
-Queue::EnqueuedPacket::EnqueuedPacket(EnqueuedPacket&& other) = default;
-
-Queue::EnqueuedPacket::~EnqueuedPacket() = default;
-
-void Queue::NextBundle() {
-  current_bundle_++;
-  current_bundle_bytes_ = 0;
-  aggregation_timeout_alarm_->Cancel();
-}
-
-void Queue::ScheduleNextPacketDequeue() {
-  if (queue_.empty()) {
-    QUICHE_DCHECK_EQ(bytes_queued_, 0u);
-    return;
-  }
-
-  if (IsAggregationEnabled() && queue_.front().bundle == current_bundle_) {
-    return;
-  }
-
-  QuicTime::Delta time_until_available = QuicTime::Delta::Zero();
-  if (tx_port_) {
-    time_until_available = tx_port_->TimeUntilAvailable();
-  }
-
-  Schedule(clock_->Now() + time_until_available);
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/queue.h b/quic/test_tools/simulator/queue.h
deleted file mode 100644
index 7680f1b..0000000
--- a/quic/test_tools/simulator/queue.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
-
-#include "quic/core/quic_alarm.h"
-#include "quic/test_tools/simulator/link.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace simulator {
-
-// A finitely sized queue which egresses packets onto a constrained link.  The
-// capacity of the queue is measured in bytes as opposed to packets.
-class Queue : public Actor, public UnconstrainedPortInterface {
- public:
-  class ListenerInterface {
-   public:
-    virtual ~ListenerInterface();
-
-    // Called whenever a packet is removed from the queue.
-    virtual void OnPacketDequeued() = 0;
-  };
-
-  Queue(Simulator* simulator, std::string name, QuicByteCount capacity);
-  Queue(const Queue&) = delete;
-  Queue& operator=(const Queue&) = delete;
-  ~Queue() override;
-
-  void set_tx_port(ConstrainedPortInterface* port);
-
-  void AcceptPacket(std::unique_ptr<Packet> packet) override;
-
-  void Act() override;
-
-  QuicByteCount capacity() const { return capacity_; }
-  QuicByteCount bytes_queued() const { return bytes_queued_; }
-  QuicPacketCount packets_queued() const { return queue_.size(); }
-
-  void set_listener_interface(ListenerInterface* listener) {
-    listener_ = listener;
-  }
-
-  // Enables packet aggregation on the queue.  Packet aggregation makes the
-  // queue bundle packets up until they reach certain size.  When the
-  // aggregation is enabled, the packets are not dequeued until the total size
-  // of packets in the queue reaches |aggregation_threshold|.  The packets are
-  // automatically flushed from the queue if the oldest packet has been in it
-  // for |aggregation_timeout|.
-  //
-  // This method may only be called when the queue is empty.  Once enabled,
-  // aggregation cannot be disabled.
-  void EnableAggregation(QuicByteCount aggregation_threshold,
-                         QuicTime::Delta aggregation_timeout);
-
- private:
-  using AggregationBundleNumber = uint64_t;
-
-  // In order to implement packet aggregation, each packet is tagged with a
-  // bundle number.  The queue keeps a bundle counter, and whenever a bundle is
-  // ready, it increments the number of the current bundle.  Only the packets
-  // outside of the current bundle are allowed to leave the queue.
-  struct EnqueuedPacket {
-    EnqueuedPacket(std::unique_ptr<Packet> packet,
-                   AggregationBundleNumber bundle);
-    EnqueuedPacket(EnqueuedPacket&& other);
-    ~EnqueuedPacket();
-
-    std::unique_ptr<Packet> packet;
-    AggregationBundleNumber bundle;
-  };
-
-  // Alarm handler for aggregation timeout.
-  class AggregationAlarmDelegate : public QuicAlarm::DelegateWithoutContext {
-   public:
-    explicit AggregationAlarmDelegate(Queue* queue);
-
-    void OnAlarm() override;
-
-   private:
-    Queue* queue_;
-  };
-
-  bool IsAggregationEnabled() const { return aggregation_threshold_ > 0; }
-
-  // Increment the bundle counter and reset the bundle state.  This causes all
-  // packets currently in the bundle to be flushed onto the link.
-  void NextBundle();
-
-  void ScheduleNextPacketDequeue();
-
-  const QuicByteCount capacity_;
-  QuicByteCount bytes_queued_;
-
-  QuicByteCount aggregation_threshold_;
-  QuicTime::Delta aggregation_timeout_;
-  // The number of the current aggregation bundle.  Monotonically increasing.
-  // All packets in the previous bundles are allowed to leave the queue, and
-  // none of the packets in the current one are.
-  AggregationBundleNumber current_bundle_;
-  // Size of the current bundle.  Whenever it exceeds |aggregation_threshold_|,
-  // the next bundle is created.
-  QuicByteCount current_bundle_bytes_;
-  // Alarm responsible for flushing the current bundle upon timeout.  Set when
-  // the first packet in the bundle is enqueued.
-  std::unique_ptr<QuicAlarm> aggregation_timeout_alarm_;
-
-  ConstrainedPortInterface* tx_port_;
-  quiche::QuicheCircularDeque<EnqueuedPacket> queue_;
-
-  ListenerInterface* listener_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
diff --git a/quic/test_tools/simulator/quic_endpoint.cc b/quic/test_tools/simulator/quic_endpoint.cc
deleted file mode 100644
index ee3c089..0000000
--- a/quic/test_tools/simulator/quic_endpoint.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/quic_endpoint.h"
-
-#include <memory>
-#include <utility>
-
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_test_output.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-const QuicStreamId kDataStream = 3;
-const QuicByteCount kWriteChunkSize = 128 * 1024;
-const char kStreamDataContents = 'Q';
-
-QuicEndpoint::QuicEndpoint(Simulator* simulator,
-                           std::string name,
-                           std::string peer_name,
-                           Perspective perspective,
-                           QuicConnectionId connection_id)
-    : QuicEndpointBase(simulator, name, peer_name),
-      bytes_to_transfer_(0),
-      bytes_transferred_(0),
-      wrong_data_received_(false),
-      notifier_(nullptr) {
-  connection_ = std::make_unique<QuicConnection>(
-      connection_id, GetAddressFromName(name), GetAddressFromName(peer_name),
-      simulator, simulator->GetAlarmFactory(), &writer_, false, perspective,
-      ParsedVersionOfIndex(CurrentSupportedVersions(), 0));
-  connection_->set_visitor(this);
-  connection_->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
-                            std::make_unique<NullEncrypter>(perspective));
-  connection_->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
-  if (connection_->version().KnowsWhichDecrypterToUse()) {
-    connection_->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
-                                  std::make_unique<NullDecrypter>(perspective));
-    connection_->RemoveDecrypter(ENCRYPTION_INITIAL);
-  } else {
-    connection_->SetDecrypter(ENCRYPTION_FORWARD_SECURE,
-                              std::make_unique<NullDecrypter>(perspective));
-  }
-  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-  connection_->OnHandshakeComplete();
-  if (perspective == Perspective::IS_SERVER) {
-    // Skip version negotiation.
-    test::QuicConnectionPeer::SetNegotiatedVersion(connection_.get());
-  }
-  test::QuicConnectionPeer::SetAddressValidated(connection_.get());
-  connection_->SetDataProducer(&producer_);
-  connection_->SetSessionNotifier(this);
-  notifier_ = std::make_unique<test::SimpleSessionNotifier>(connection_.get());
-
-  // Configure the connection as if it received a handshake.  This is important
-  // primarily because
-  //  - this enables pacing, and
-  //  - this sets the non-handshake timeouts.
-  std::string error;
-  CryptoHandshakeMessage peer_hello;
-  peer_hello.SetValue(kICSL,
-                      static_cast<uint32_t>(kMaximumIdleTimeoutSecs - 1));
-  peer_hello.SetValue(kMIBS,
-                      static_cast<uint32_t>(kDefaultMaxStreamsPerConnection));
-  QuicConfig config;
-  QuicErrorCode error_code = config.ProcessPeerHello(
-      peer_hello, perspective == Perspective::IS_CLIENT ? SERVER : CLIENT,
-      &error);
-  QUICHE_DCHECK_EQ(error_code, QUIC_NO_ERROR)
-      << "Configuration failed: " << error;
-  if (connection_->version().UsesTls()) {
-    if (connection_->perspective() == Perspective::IS_CLIENT) {
-      test::QuicConfigPeer::SetReceivedOriginalConnectionId(
-          &config, connection_->connection_id());
-      test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-          &config, connection_->connection_id());
-    } else {
-      test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
-          &config, connection_->client_connection_id());
-    }
-  }
-  connection_->SetFromConfig(config);
-  connection_->DisableMtuDiscovery();
-}
-
-QuicByteCount QuicEndpoint::bytes_received() const {
-  QuicByteCount total = 0;
-  for (auto& interval : offsets_received_) {
-    total += interval.max() - interval.min();
-  }
-  return total;
-}
-
-QuicByteCount QuicEndpoint::bytes_to_transfer() const {
-  if (notifier_ != nullptr) {
-    return notifier_->StreamBytesToSend();
-  }
-  return bytes_to_transfer_;
-}
-
-QuicByteCount QuicEndpoint::bytes_transferred() const {
-  if (notifier_ != nullptr) {
-    return notifier_->StreamBytesSent();
-  }
-  return bytes_transferred_;
-}
-
-void QuicEndpoint::AddBytesToTransfer(QuicByteCount bytes) {
-  if (notifier_ != nullptr) {
-    if (notifier_->HasBufferedStreamData()) {
-      Schedule(clock_->Now());
-    }
-    notifier_->WriteOrBufferData(kDataStream, bytes, NO_FIN);
-    return;
-  }
-
-  if (bytes_to_transfer_ > 0) {
-    Schedule(clock_->Now());
-  }
-
-  bytes_to_transfer_ += bytes;
-  WriteStreamData();
-}
-
-void QuicEndpoint::OnStreamFrame(const QuicStreamFrame& frame) {
-  // Verify that the data received always matches the expected.
-  QUICHE_DCHECK(frame.stream_id == kDataStream);
-  for (size_t i = 0; i < frame.data_length; i++) {
-    if (frame.data_buffer[i] != kStreamDataContents) {
-      wrong_data_received_ = true;
-    }
-  }
-  offsets_received_.Add(frame.offset, frame.offset + frame.data_length);
-  // Sanity check against very pathological connections.
-  QUICHE_DCHECK_LE(offsets_received_.Size(), 1000u);
-}
-
-void QuicEndpoint::OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
-
-void QuicEndpoint::OnCanWrite() {
-  if (notifier_ != nullptr) {
-    notifier_->OnCanWrite();
-    return;
-  }
-  WriteStreamData();
-}
-
-bool QuicEndpoint::SendProbingData() {
-  if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
-          PROBING_RETRANSMISSION)) {
-    return true;
-  }
-  return false;
-}
-
-bool QuicEndpoint::WillingAndAbleToWrite() const {
-  if (notifier_ != nullptr) {
-    return notifier_->WillingToWrite();
-  }
-  return bytes_to_transfer_ != 0;
-}
-bool QuicEndpoint::ShouldKeepConnectionAlive() const {
-  return true;
-}
-
-bool QuicEndpoint::AllowSelfAddressChange() const {
-  return false;
-}
-
-bool QuicEndpoint::OnFrameAcked(const QuicFrame& frame,
-                                QuicTime::Delta ack_delay_time,
-                                QuicTime receive_timestamp) {
-  if (notifier_ != nullptr) {
-    return notifier_->OnFrameAcked(frame, ack_delay_time, receive_timestamp);
-  }
-  return false;
-}
-
-void QuicEndpoint::OnFrameLost(const QuicFrame& frame) {
-  QUICHE_DCHECK(notifier_);
-  notifier_->OnFrameLost(frame);
-}
-
-bool QuicEndpoint::RetransmitFrames(const QuicFrames& frames,
-                                    TransmissionType type) {
-  QUICHE_DCHECK(notifier_);
-  return notifier_->RetransmitFrames(frames, type);
-}
-
-bool QuicEndpoint::IsFrameOutstanding(const QuicFrame& frame) const {
-  QUICHE_DCHECK(notifier_);
-  return notifier_->IsFrameOutstanding(frame);
-}
-
-bool QuicEndpoint::HasUnackedCryptoData() const {
-  return false;
-}
-
-bool QuicEndpoint::HasUnackedStreamData() const {
-  if (notifier_ != nullptr) {
-    return notifier_->HasUnackedStreamData();
-  }
-  return false;
-}
-
-HandshakeState QuicEndpoint::GetHandshakeState() const {
-  return HANDSHAKE_COMPLETE;
-}
-
-WriteStreamDataResult QuicEndpoint::DataProducer::WriteStreamData(
-    QuicStreamId /*id*/,
-    QuicStreamOffset /*offset*/,
-    QuicByteCount data_length,
-    QuicDataWriter* writer) {
-  writer->WriteRepeatedByte(kStreamDataContents, data_length);
-  return WRITE_SUCCESS;
-}
-
-bool QuicEndpoint::DataProducer::WriteCryptoData(EncryptionLevel /*level*/,
-                                                 QuicStreamOffset /*offset*/,
-                                                 QuicByteCount /*data_length*/,
-                                                 QuicDataWriter* /*writer*/) {
-  QUIC_BUG(quic_bug_10157_1)
-      << "QuicEndpoint::DataProducer::WriteCryptoData is unimplemented";
-  return false;
-}
-
-void QuicEndpoint::WriteStreamData() {
-  // Instantiate a flusher which would normally be here due to QuicSession.
-  QuicConnection::ScopedPacketFlusher flusher(connection_.get());
-
-  while (bytes_to_transfer_ > 0) {
-    // Transfer data in chunks of size at most |kWriteChunkSize|.
-    const size_t transmission_size =
-        std::min(kWriteChunkSize, bytes_to_transfer_);
-
-    QuicConsumedData consumed_data = connection_->SendStreamData(
-        kDataStream, transmission_size, bytes_transferred_, NO_FIN);
-
-    QUICHE_DCHECK(consumed_data.bytes_consumed <= transmission_size);
-    bytes_transferred_ += consumed_data.bytes_consumed;
-    bytes_to_transfer_ -= consumed_data.bytes_consumed;
-    if (consumed_data.bytes_consumed != transmission_size) {
-      return;
-    }
-  }
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/quic_endpoint.h b/quic/test_tools/simulator/quic_endpoint.h
deleted file mode 100644
index 4e62f71..0000000
--- a/quic/test_tools/simulator/quic_endpoint.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_trace_visitor.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simple_session_notifier.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/queue.h"
-#include "quic/test_tools/simulator/quic_endpoint_base.h"
-
-namespace quic {
-namespace simulator {
-
-// A QUIC connection endpoint.  Wraps around QuicConnection.  In order to
-// initiate a transfer, the caller has to call AddBytesToTransfer().  The data
-// transferred is always the same and is always transferred on a single stream.
-// The endpoint receives all packets addressed to it, and verifies that the data
-// received is what it's supposed to be.
-class QuicEndpoint : public QuicEndpointBase,
-                     public QuicConnectionVisitorInterface,
-                     public SessionNotifierInterface {
- public:
-  QuicEndpoint(Simulator* simulator,
-               std::string name,
-               std::string peer_name,
-               Perspective perspective,
-               QuicConnectionId connection_id);
-
-  QuicByteCount bytes_to_transfer() const;
-  QuicByteCount bytes_transferred() const;
-  QuicByteCount bytes_received() const;
-  bool wrong_data_received() const { return wrong_data_received_; }
-
-  // Send |bytes| bytes.  Initiates the transfer if one is not already in
-  // progress.
-  void AddBytesToTransfer(QuicByteCount bytes);
-
-  // Begin QuicConnectionVisitorInterface implementation.
-  void OnStreamFrame(const QuicStreamFrame& frame) override;
-  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
-  void OnCanWrite() override;
-  bool SendProbingData() override;
-  bool ValidateStatelessReset(
-      const quic::QuicSocketAddress& /*self_address*/,
-      const quic::QuicSocketAddress& /*peer_address*/) override {
-    return true;
-  }
-  bool WillingAndAbleToWrite() const override;
-  bool ShouldKeepConnectionAlive() const override;
-
-  std::string GetStreamsInfoForLogging() const override { return ""; }
-  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {}
-  void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {}
-  void OnRstStream(const QuicRstStreamFrame& /*frame*/) override {}
-  void OnGoAway(const QuicGoAwayFrame& /*frame*/) override {}
-  void OnMessageReceived(absl::string_view /*message*/) override {}
-  void OnHandshakeDoneReceived() override {}
-  void OnNewTokenReceived(absl::string_view /*token*/) override {}
-  void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
-                          ConnectionCloseSource /*source*/) override {}
-  void OnWriteBlocked() override {}
-  void OnSuccessfulVersionNegotiation(
-      const ParsedQuicVersion& /*version*/) override {}
-  void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
-                        const QuicSocketAddress& /*peer_address*/,
-                        bool /*is_connectivity_probe*/) override {}
-  void OnCongestionWindowChange(QuicTime /*now*/) override {}
-  void OnConnectionMigration(AddressChangeType /*type*/) override {}
-  void OnPathDegrading() override {}
-  void OnForwardProgressMadeAfterPathDegrading() override {}
-  void OnAckNeedsRetransmittableFrame() override {}
-  void SendAckFrequency(const QuicAckFrequencyFrame& /*frame*/) override {}
-  void SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
-  }
-  void SendRetireConnectionId(uint64_t /*sequence_number*/) override {}
-  void OnServerConnectionIdIssued(
-      const QuicConnectionId& /*server_connection_id*/) override {}
-  void OnServerConnectionIdRetired(
-      const QuicConnectionId& /*server_connection_id*/) override {}
-  bool AllowSelfAddressChange() const override;
-  HandshakeState GetHandshakeState() const override;
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
-    return true;
-  }
-  bool OnStreamsBlockedFrame(
-      const QuicStreamsBlockedFrame& /*frame*/) override {
-    return true;
-  }
-  void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {}
-  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
-  void OnOneRttPacketAcknowledged() override {}
-  void OnHandshakePacketSent() override {}
-  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    return nullptr;
-  }
-  void BeforeConnectionCloseSent() override {}
-  bool ValidateToken(absl::string_view /*token*/) override { return true; }
-  bool MaybeSendAddressToken() override { return false; }
-  bool IsKnownServerAddress(
-      const QuicSocketAddress& /*address*/) const override {
-    return false;
-  }
-
-  // End QuicConnectionVisitorInterface implementation.
-
-  // Begin SessionNotifierInterface methods:
-  bool OnFrameAcked(const QuicFrame& frame,
-                    QuicTime::Delta ack_delay_time,
-                    QuicTime receive_timestamp) override;
-  void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
-  void OnFrameLost(const QuicFrame& frame) override;
-  bool RetransmitFrames(const QuicFrames& frames,
-                        TransmissionType type) override;
-  bool IsFrameOutstanding(const QuicFrame& frame) const override;
-  bool HasUnackedCryptoData() const override;
-  bool HasUnackedStreamData() const override;
-  // End SessionNotifierInterface implementation.
-
- private:
-  // The producer outputs the repetition of the same byte.  That sequence is
-  // verified by the receiver.
-  class DataProducer : public QuicStreamFrameDataProducer {
-   public:
-    WriteStreamDataResult WriteStreamData(QuicStreamId id,
-                                          QuicStreamOffset offset,
-                                          QuicByteCount data_length,
-                                          QuicDataWriter* writer) override;
-    bool WriteCryptoData(EncryptionLevel level,
-                         QuicStreamOffset offset,
-                         QuicByteCount data_length,
-                         QuicDataWriter* writer) override;
-  };
-
-  std::unique_ptr<QuicConnection> CreateConnection(
-      Simulator* simulator,
-      std::string name,
-      std::string peer_name,
-      Perspective perspective,
-      QuicConnectionId connection_id);
-
-  // Write stream data until |bytes_to_transfer_| is zero or the connection is
-  // write-blocked.
-  void WriteStreamData();
-
-  DataProducer producer_;
-
-  QuicByteCount bytes_to_transfer_;
-  QuicByteCount bytes_transferred_;
-
-  // Set to true if the endpoint receives stream data different from what it
-  // expects.
-  bool wrong_data_received_;
-
-  // Record of received offsets in the data stream.
-  QuicIntervalSet<QuicStreamOffset> offsets_received_;
-
-  std::unique_ptr<test::SimpleSessionNotifier> notifier_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
diff --git a/quic/test_tools/simulator/quic_endpoint_base.cc b/quic/test_tools/simulator/quic_endpoint_base.cc
deleted file mode 100644
index e66af8b..0000000
--- a/quic/test_tools/simulator/quic_endpoint_base.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/quic_endpoint_base.h"
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/crypto_handshake_message.h"
-#include "quic/core/crypto/crypto_protocol.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_writer.h"
-#include "quic/platform/api/quic_test_output.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-// Takes a SHA-1 hash of the name and converts it into five 32-bit integers.
-static std::vector<uint32_t> HashNameIntoFive32BitIntegers(std::string name) {
-  const std::string hash = test::Sha1Hash(name);
-
-  std::vector<uint32_t> output;
-  uint32_t current_number = 0;
-  for (size_t i = 0; i < hash.size(); i++) {
-    current_number = (current_number << 8) + hash[i];
-    if (i % 4 == 3) {
-      output.push_back(i);
-      current_number = 0;
-    }
-  }
-
-  return output;
-}
-
-QuicSocketAddress GetAddressFromName(std::string name) {
-  const std::vector<uint32_t> hash = HashNameIntoFive32BitIntegers(name);
-
-  // Generate a random port between 1025 and 65535.
-  const uint16_t port = 1025 + hash[0] % (65535 - 1025 + 1);
-
-  // Generate a random 10.x.x.x address, where x is between 1 and 254.
-  std::string ip_address{"\xa\0\0\0", 4};
-  for (size_t i = 1; i < 4; i++) {
-    ip_address[i] = 1 + hash[i] % 254;
-  }
-  QuicIpAddress host;
-  host.FromPackedString(ip_address.c_str(), ip_address.length());
-  return QuicSocketAddress(host, port);
-}
-
-QuicEndpointBase::QuicEndpointBase(Simulator* simulator,
-                                   std::string name,
-                                   std::string peer_name)
-    : Endpoint(simulator, name),
-      peer_name_(peer_name),
-      writer_(this),
-      nic_tx_queue_(simulator,
-                    absl::StrCat(name, " (TX Queue)"),
-                    kMaxOutgoingPacketSize * kTxQueueSize),
-      connection_(nullptr),
-      write_blocked_count_(0),
-      drop_next_packet_(false) {
-  nic_tx_queue_.set_listener_interface(this);
-}
-
-QuicEndpointBase::~QuicEndpointBase() {
-  if (trace_visitor_ != nullptr) {
-    const char* perspective_prefix =
-        connection_->perspective() == Perspective::IS_CLIENT ? "C" : "S";
-
-    std::string identifier = absl::StrCat(
-        perspective_prefix, connection_->connection_id().ToString());
-    QuicRecordTrace(identifier, trace_visitor_->trace()->SerializeAsString());
-  }
-}
-
-void QuicEndpointBase::DropNextIncomingPacket() {
-  drop_next_packet_ = true;
-}
-
-void QuicEndpointBase::RecordTrace() {
-  trace_visitor_ = std::make_unique<QuicTraceVisitor>(connection_.get());
-  connection_->set_debug_visitor(trace_visitor_.get());
-}
-
-void QuicEndpointBase::AcceptPacket(std::unique_ptr<Packet> packet) {
-  if (packet->destination != name_) {
-    return;
-  }
-  if (drop_next_packet_) {
-    drop_next_packet_ = false;
-    return;
-  }
-
-  QuicReceivedPacket received_packet(packet->contents.data(),
-                                     packet->contents.size(), clock_->Now());
-  connection_->ProcessUdpPacket(connection_->self_address(),
-                                connection_->peer_address(), received_packet);
-}
-
-UnconstrainedPortInterface* QuicEndpointBase::GetRxPort() {
-  return this;
-}
-
-void QuicEndpointBase::SetTxPort(ConstrainedPortInterface* port) {
-  // Any egress done by the endpoint is actually handled by a queue on an NIC.
-  nic_tx_queue_.set_tx_port(port);
-}
-
-void QuicEndpointBase::OnPacketDequeued() {
-  if (writer_.IsWriteBlocked() &&
-      (nic_tx_queue_.capacity() - nic_tx_queue_.bytes_queued()) >=
-          kMaxOutgoingPacketSize) {
-    writer_.SetWritable();
-    connection_->OnCanWrite();
-  }
-}
-
-QuicEndpointBase::Writer::Writer(QuicEndpointBase* endpoint)
-    : endpoint_(endpoint), is_blocked_(false) {}
-
-QuicEndpointBase::Writer::~Writer() {}
-
-WriteResult QuicEndpointBase::Writer::WritePacket(
-    const char* buffer,
-    size_t buf_len,
-    const QuicIpAddress& /*self_address*/,
-    const QuicSocketAddress& /*peer_address*/,
-    PerPacketOptions* options) {
-  QUICHE_DCHECK(!IsWriteBlocked());
-  QUICHE_DCHECK(options == nullptr);
-  QUICHE_DCHECK(buf_len <= kMaxOutgoingPacketSize);
-
-  // Instead of losing a packet, become write-blocked when the egress queue is
-  // full.
-  if (endpoint_->nic_tx_queue_.packets_queued() > kTxQueueSize) {
-    is_blocked_ = true;
-    endpoint_->write_blocked_count_++;
-    return WriteResult(WRITE_STATUS_BLOCKED, 0);
-  }
-
-  auto packet = std::make_unique<Packet>();
-  packet->source = endpoint_->name();
-  packet->destination = endpoint_->peer_name_;
-  packet->tx_timestamp = endpoint_->clock_->Now();
-
-  packet->contents = std::string(buffer, buf_len);
-  packet->size = buf_len;
-
-  endpoint_->nic_tx_queue_.AcceptPacket(std::move(packet));
-
-  return WriteResult(WRITE_STATUS_OK, buf_len);
-}
-
-bool QuicEndpointBase::Writer::IsWriteBlocked() const {
-  return is_blocked_;
-}
-
-void QuicEndpointBase::Writer::SetWritable() {
-  is_blocked_ = false;
-}
-
-absl::optional<int> QuicEndpointBase::Writer::MessageTooBigErrorCode() const {
-  return absl::nullopt;
-}
-
-QuicByteCount QuicEndpointBase::Writer::GetMaxPacketSize(
-    const QuicSocketAddress& /*peer_address*/) const {
-  return kMaxOutgoingPacketSize;
-}
-
-bool QuicEndpointBase::Writer::SupportsReleaseTime() const {
-  return false;
-}
-
-bool QuicEndpointBase::Writer::IsBatchMode() const {
-  return false;
-}
-
-QuicPacketBuffer QuicEndpointBase::Writer::GetNextWriteLocation(
-    const QuicIpAddress& /*self_address*/,
-    const QuicSocketAddress& /*peer_address*/) {
-  return {nullptr, nullptr};
-}
-
-WriteResult QuicEndpointBase::Writer::Flush() {
-  return WriteResult(WRITE_STATUS_OK, 0);
-}
-
-QuicEndpointMultiplexer::QuicEndpointMultiplexer(
-    std::string name,
-    const std::vector<QuicEndpointBase*>& endpoints)
-    : Endpoint((*endpoints.begin())->simulator(), name) {
-  for (QuicEndpointBase* endpoint : endpoints) {
-    mapping_.insert(std::make_pair(endpoint->name(), endpoint));
-  }
-}
-
-QuicEndpointMultiplexer::~QuicEndpointMultiplexer() {}
-
-void QuicEndpointMultiplexer::AcceptPacket(std::unique_ptr<Packet> packet) {
-  auto key_value_pair_it = mapping_.find(packet->destination);
-  if (key_value_pair_it == mapping_.end()) {
-    return;
-  }
-
-  key_value_pair_it->second->GetRxPort()->AcceptPacket(std::move(packet));
-}
-UnconstrainedPortInterface* QuicEndpointMultiplexer::GetRxPort() {
-  return this;
-}
-void QuicEndpointMultiplexer::SetTxPort(ConstrainedPortInterface* port) {
-  for (auto& key_value_pair : mapping_) {
-    key_value_pair.second->SetTxPort(port);
-  }
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/quic_endpoint_base.h b/quic/test_tools/simulator/quic_endpoint_base.h
deleted file mode 100644
index 9578c79..0000000
--- a/quic/test_tools/simulator/quic_endpoint_base.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
-
-#include <memory>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/crypto/null_decrypter.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_stream_frame_data_producer.h"
-#include "quic/core/quic_trace_visitor.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simple_session_notifier.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/queue.h"
-
-namespace quic {
-namespace simulator {
-
-// Size of the TX queue used by the kernel/NIC.  1000 is the Linux
-// kernel default.
-const QuicByteCount kTxQueueSize = 1000;
-
-// Generate a random local network host-port tuple based on the name of the
-// endpoint.
-QuicSocketAddress GetAddressFromName(std::string name);
-
-// A QUIC connection endpoint.  If the specific data transmitted does not matter
-// (e.g. for congestion control purposes), QuicEndpoint is the subclass that
-// transmits dummy data.  If the actual semantics of the connection matter,
-// subclassing QuicEndpointBase is required.
-class QuicEndpointBase : public Endpoint,
-                         public UnconstrainedPortInterface,
-                         public Queue::ListenerInterface {
- public:
-  // Does not create the connection; the subclass has to create connection by
-  // itself.
-  QuicEndpointBase(Simulator* simulator,
-                   std::string name,
-                   std::string peer_name);
-  ~QuicEndpointBase() override;
-
-  QuicConnection* connection() { return connection_.get(); }
-  size_t write_blocked_count() { return write_blocked_count_; }
-
-  // Drop the next packet upon receipt.
-  void DropNextIncomingPacket();
-
-  // UnconstrainedPortInterface method.  Called whenever the endpoint receives a
-  // packet.
-  void AcceptPacket(std::unique_ptr<Packet> packet) override;
-
-  // Enables logging of the connection trace at the end of the unit test.
-  void RecordTrace();
-
-  // Begin Endpoint implementation.
-  UnconstrainedPortInterface* GetRxPort() override;
-  void SetTxPort(ConstrainedPortInterface* port) override;
-  // End Endpoint implementation.
-
-  // Actor method.
-  void Act() override {}
-
-  // Queue::ListenerInterface method.
-  void OnPacketDequeued() override;
-
- protected:
-  // A Writer object that writes into the |nic_tx_queue_|.
-  class Writer : public QuicPacketWriter {
-   public:
-    explicit Writer(QuicEndpointBase* endpoint);
-    ~Writer() override;
-
-    WriteResult WritePacket(const char* buffer,
-                            size_t buf_len,
-                            const QuicIpAddress& self_address,
-                            const QuicSocketAddress& peer_address,
-                            PerPacketOptions* options) override;
-    bool IsWriteBlocked() const override;
-    void SetWritable() override;
-    absl::optional<int> MessageTooBigErrorCode() const override;
-    QuicByteCount GetMaxPacketSize(
-        const QuicSocketAddress& peer_address) const override;
-    bool SupportsReleaseTime() const override;
-    bool IsBatchMode() const override;
-    QuicPacketBuffer GetNextWriteLocation(
-        const QuicIpAddress& self_address,
-        const QuicSocketAddress& peer_address) override;
-    WriteResult Flush() override;
-
-   private:
-    QuicEndpointBase* endpoint_;
-
-    bool is_blocked_;
-  };
-
-  // The producer outputs the repetition of the same byte.  That sequence is
-  // verified by the receiver.
-  class DataProducer : public QuicStreamFrameDataProducer {
-   public:
-    WriteStreamDataResult WriteStreamData(QuicStreamId id,
-                                          QuicStreamOffset offset,
-                                          QuicByteCount data_length,
-                                          QuicDataWriter* writer) override;
-    bool WriteCryptoData(EncryptionLevel level,
-                         QuicStreamOffset offset,
-                         QuicByteCount data_length,
-                         QuicDataWriter* writer) override;
-  };
-
-  std::string peer_name_;
-
-  Writer writer_;
-  // The queue for the outgoing packets.  In reality, this might be either on
-  // the network card, or in the kernel, but for concreteness we assume it's on
-  // the network card.
-  Queue nic_tx_queue_;
-  // Created by the subclass.
-  std::unique_ptr<QuicConnection> connection_;
-
-  // Counts the number of times the writer became write-blocked.
-  size_t write_blocked_count_;
-
-  // If true, drop the next packet when receiving it.
-  bool drop_next_packet_;
-
-  std::unique_ptr<QuicTraceVisitor> trace_visitor_;
-};
-
-// Multiplexes multiple connections at the same host on the network.
-class QuicEndpointMultiplexer : public Endpoint,
-                                public UnconstrainedPortInterface {
- public:
-  QuicEndpointMultiplexer(std::string name,
-                          const std::vector<QuicEndpointBase*>& endpoints);
-  ~QuicEndpointMultiplexer() override;
-
-  // Receives a packet and passes it to the specified endpoint if that endpoint
-  // is one of the endpoints being multiplexed, otherwise ignores the packet.
-  void AcceptPacket(std::unique_ptr<Packet> packet) override;
-  UnconstrainedPortInterface* GetRxPort() override;
-
-  // Sets the egress port for all the endpoints being multiplexed.
-  void SetTxPort(ConstrainedPortInterface* port) override;
-
-  void Act() override {}
-
- private:
-  absl::flat_hash_map<std::string, QuicEndpointBase*> mapping_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
diff --git a/quic/test_tools/simulator/quic_endpoint_test.cc b/quic/test_tools/simulator/quic_endpoint_test.cc
deleted file mode 100644
index 69b2682..0000000
--- a/quic/test_tools/simulator/quic_endpoint_test.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/quic_endpoint.h"
-
-#include <utility>
-
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/simulator.h"
-#include "quic/test_tools/simulator/switch.h"
-
-using ::testing::_;
-using ::testing::NiceMock;
-using ::testing::Return;
-
-namespace quic {
-namespace simulator {
-
-const QuicBandwidth kDefaultBandwidth =
-    QuicBandwidth::FromKBitsPerSecond(10 * 1000);
-const QuicTime::Delta kDefaultPropagationDelay =
-    QuicTime::Delta::FromMilliseconds(20);
-const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
-
-// A simple test harness where all hosts are connected to a switch with
-// identical links.
-class QuicEndpointTest : public QuicTest {
- public:
-  QuicEndpointTest()
-      : simulator_(), switch_(&simulator_, "Switch", 8, kDefaultBdp * 2) {}
-
- protected:
-  Simulator simulator_;
-  Switch switch_;
-
-  std::unique_ptr<SymmetricLink> Link(Endpoint* a, Endpoint* b) {
-    return std::make_unique<SymmetricLink>(a, b, kDefaultBandwidth,
-                                           kDefaultPropagationDelay);
-  }
-
-  std::unique_ptr<SymmetricLink> CustomLink(Endpoint* a,
-                                            Endpoint* b,
-                                            uint64_t extra_rtt_ms) {
-    return std::make_unique<SymmetricLink>(
-        a, b, kDefaultBandwidth,
-        kDefaultPropagationDelay +
-            QuicTime::Delta::FromMilliseconds(extra_rtt_ms));
-  }
-};
-
-// Test transmission from one host to another.
-TEST_F(QuicEndpointTest, OneWayTransmission) {
-  QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
-                          Perspective::IS_CLIENT, test::TestConnectionId(42));
-  QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
-                          Perspective::IS_SERVER, test::TestConnectionId(42));
-  auto link_a = Link(&endpoint_a, switch_.port(1));
-  auto link_b = Link(&endpoint_b, switch_.port(2));
-
-  // First transmit a small, packet-size chunk of data.
-  endpoint_a.AddBytesToTransfer(600);
-  QuicTime end_time =
-      simulator_.GetClock()->Now() + QuicTime::Delta::FromMilliseconds(1000);
-  simulator_.RunUntil(
-      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
-  EXPECT_EQ(600u, endpoint_a.bytes_transferred());
-  ASSERT_EQ(600u, endpoint_b.bytes_received());
-  EXPECT_FALSE(endpoint_a.wrong_data_received());
-  EXPECT_FALSE(endpoint_b.wrong_data_received());
-
-  // After a small chunk succeeds, try to transfer 2 MiB.
-  endpoint_a.AddBytesToTransfer(2 * 1024 * 1024);
-  end_time = simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(5);
-  simulator_.RunUntil(
-      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
-  const QuicByteCount total_bytes_transferred = 600 + 2 * 1024 * 1024;
-  EXPECT_EQ(total_bytes_transferred, endpoint_a.bytes_transferred());
-  EXPECT_EQ(total_bytes_transferred, endpoint_b.bytes_received());
-  EXPECT_EQ(0u, endpoint_a.write_blocked_count());
-  EXPECT_FALSE(endpoint_a.wrong_data_received());
-  EXPECT_FALSE(endpoint_b.wrong_data_received());
-}
-
-// Test the situation in which the writer becomes write-blocked.
-TEST_F(QuicEndpointTest, WriteBlocked) {
-  QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
-                          Perspective::IS_CLIENT, test::TestConnectionId(42));
-  QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
-                          Perspective::IS_SERVER, test::TestConnectionId(42));
-  auto link_a = Link(&endpoint_a, switch_.port(1));
-  auto link_b = Link(&endpoint_b, switch_.port(2));
-
-  // Will be owned by the sent packet manager.
-  auto* sender = new NiceMock<test::MockSendAlgorithm>();
-  EXPECT_CALL(*sender, CanSend(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*sender, PacingRate(_))
-      .WillRepeatedly(Return(10 * kDefaultBandwidth));
-  EXPECT_CALL(*sender, BandwidthEstimate())
-      .WillRepeatedly(Return(10 * kDefaultBandwidth));
-  EXPECT_CALL(*sender, GetCongestionWindow())
-      .WillRepeatedly(Return(kMaxOutgoingPacketSize *
-                             GetQuicFlag(FLAGS_quic_max_congestion_window)));
-  test::QuicConnectionPeer::SetSendAlgorithm(endpoint_a.connection(), sender);
-
-  // First transmit a small, packet-size chunk of data.
-  QuicByteCount bytes_to_transfer = 3 * 1024 * 1024;
-  endpoint_a.AddBytesToTransfer(bytes_to_transfer);
-  QuicTime end_time =
-      simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(30);
-  simulator_.RunUntil([this, &endpoint_b, bytes_to_transfer, end_time]() {
-    return endpoint_b.bytes_received() == bytes_to_transfer ||
-           simulator_.GetClock()->Now() >= end_time;
-  });
-
-  EXPECT_EQ(bytes_to_transfer, endpoint_a.bytes_transferred());
-  EXPECT_EQ(bytes_to_transfer, endpoint_b.bytes_received());
-  EXPECT_GT(endpoint_a.write_blocked_count(), 0u);
-  EXPECT_FALSE(endpoint_a.wrong_data_received());
-  EXPECT_FALSE(endpoint_b.wrong_data_received());
-}
-
-// Test transmission of 1 MiB of data between two hosts simultaneously in both
-// directions.
-TEST_F(QuicEndpointTest, TwoWayTransmission) {
-  QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
-                          Perspective::IS_CLIENT, test::TestConnectionId(42));
-  QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
-                          Perspective::IS_SERVER, test::TestConnectionId(42));
-  auto link_a = Link(&endpoint_a, switch_.port(1));
-  auto link_b = Link(&endpoint_b, switch_.port(2));
-
-  endpoint_a.RecordTrace();
-  endpoint_b.RecordTrace();
-
-  endpoint_a.AddBytesToTransfer(1024 * 1024);
-  endpoint_b.AddBytesToTransfer(1024 * 1024);
-  QuicTime end_time =
-      simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(5);
-  simulator_.RunUntil(
-      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
-  EXPECT_EQ(1024u * 1024u, endpoint_a.bytes_transferred());
-  EXPECT_EQ(1024u * 1024u, endpoint_b.bytes_transferred());
-  EXPECT_EQ(1024u * 1024u, endpoint_a.bytes_received());
-  EXPECT_EQ(1024u * 1024u, endpoint_b.bytes_received());
-  EXPECT_FALSE(endpoint_a.wrong_data_received());
-  EXPECT_FALSE(endpoint_b.wrong_data_received());
-}
-
-// Simulate three hosts trying to send data to a fourth one simultaneously.
-TEST_F(QuicEndpointTest, Competition) {
-  auto endpoint_a = std::make_unique<QuicEndpoint>(
-      &simulator_, "Endpoint A", "Endpoint D (A)", Perspective::IS_CLIENT,
-      test::TestConnectionId(42));
-  auto endpoint_b = std::make_unique<QuicEndpoint>(
-      &simulator_, "Endpoint B", "Endpoint D (B)", Perspective::IS_CLIENT,
-      test::TestConnectionId(43));
-  auto endpoint_c = std::make_unique<QuicEndpoint>(
-      &simulator_, "Endpoint C", "Endpoint D (C)", Perspective::IS_CLIENT,
-      test::TestConnectionId(44));
-  auto endpoint_d_a = std::make_unique<QuicEndpoint>(
-      &simulator_, "Endpoint D (A)", "Endpoint A", Perspective::IS_SERVER,
-      test::TestConnectionId(42));
-  auto endpoint_d_b = std::make_unique<QuicEndpoint>(
-      &simulator_, "Endpoint D (B)", "Endpoint B", Perspective::IS_SERVER,
-      test::TestConnectionId(43));
-  auto endpoint_d_c = std::make_unique<QuicEndpoint>(
-      &simulator_, "Endpoint D (C)", "Endpoint C", Perspective::IS_SERVER,
-      test::TestConnectionId(44));
-  QuicEndpointMultiplexer endpoint_d(
-      "Endpoint D",
-      {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()});
-
-  // Create links with slightly different RTTs in order to avoid pathological
-  // side-effects of packets entering the queue at the exactly same time.
-  auto link_a = CustomLink(endpoint_a.get(), switch_.port(1), 0);
-  auto link_b = CustomLink(endpoint_b.get(), switch_.port(2), 1);
-  auto link_c = CustomLink(endpoint_c.get(), switch_.port(3), 2);
-  auto link_d = Link(&endpoint_d, switch_.port(4));
-
-  endpoint_a->AddBytesToTransfer(2 * 1024 * 1024);
-  endpoint_b->AddBytesToTransfer(2 * 1024 * 1024);
-  endpoint_c->AddBytesToTransfer(2 * 1024 * 1024);
-  QuicTime end_time =
-      simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(12);
-  simulator_.RunUntil(
-      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
-
-  for (QuicEndpoint* endpoint :
-       {endpoint_a.get(), endpoint_b.get(), endpoint_c.get()}) {
-    EXPECT_EQ(2u * 1024u * 1024u, endpoint->bytes_transferred());
-    EXPECT_GE(endpoint->connection()->GetStats().packets_lost, 0u);
-  }
-  for (QuicEndpoint* endpoint :
-       {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()}) {
-    EXPECT_EQ(2u * 1024u * 1024u, endpoint->bytes_received());
-    EXPECT_FALSE(endpoint->wrong_data_received());
-  }
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/simulator.cc b/quic/test_tools/simulator/simulator.cc
deleted file mode 100644
index 2cdfe44..0000000
--- a/quic/test_tools/simulator/simulator.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/simulator.h"
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-namespace simulator {
-
-Simulator::Simulator() : Simulator(nullptr) {}
-
-Simulator::Simulator(QuicRandom* random_generator)
-    : random_generator_(random_generator),
-      alarm_factory_(this, "Default Alarm Manager"),
-      run_for_should_stop_(false),
-      enable_random_delays_(false) {
-  run_for_alarm_.reset(
-      alarm_factory_.CreateAlarm(new RunForDelegate(&run_for_should_stop_)));
-}
-
-Simulator::~Simulator() {
-  // Ensure that Actor under run_for_alarm_ is removed before Simulator data
-  // structures are destructed.
-  run_for_alarm_.reset();
-}
-
-Simulator::Clock::Clock() : now_(kStartTime) {}
-
-QuicTime Simulator::Clock::ApproximateNow() const {
-  return now_;
-}
-
-QuicTime Simulator::Clock::Now() const {
-  return now_;
-}
-
-QuicWallTime Simulator::Clock::WallNow() const {
-  return QuicWallTime::FromUNIXMicroseconds(
-      (now_ - QuicTime::Zero()).ToMicroseconds());
-}
-
-void Simulator::AddActor(Actor* actor) {
-  auto emplace_times_result =
-      scheduled_times_.insert(std::make_pair(actor, QuicTime::Infinite()));
-  auto emplace_names_result = actor_names_.insert(actor->name());
-
-  // Ensure that the object was actually placed into the map.
-  QUICHE_DCHECK(emplace_times_result.second);
-  QUICHE_DCHECK(emplace_names_result.second);
-}
-
-void Simulator::RemoveActor(Actor* actor) {
-  auto scheduled_time_it = scheduled_times_.find(actor);
-  auto actor_names_it = actor_names_.find(actor->name());
-  QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
-  QUICHE_DCHECK(actor_names_it != actor_names_.end());
-
-  QuicTime scheduled_time = scheduled_time_it->second;
-  if (scheduled_time != QuicTime::Infinite()) {
-    Unschedule(actor);
-  }
-
-  scheduled_times_.erase(scheduled_time_it);
-  actor_names_.erase(actor_names_it);
-}
-
-void Simulator::Schedule(Actor* actor, QuicTime new_time) {
-  auto scheduled_time_it = scheduled_times_.find(actor);
-  QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
-  QuicTime scheduled_time = scheduled_time_it->second;
-
-  if (scheduled_time <= new_time) {
-    return;
-  }
-
-  if (scheduled_time != QuicTime::Infinite()) {
-    Unschedule(actor);
-  }
-
-  scheduled_time_it->second = new_time;
-  schedule_.insert(std::make_pair(new_time, actor));
-}
-
-void Simulator::Unschedule(Actor* actor) {
-  auto scheduled_time_it = scheduled_times_.find(actor);
-  QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
-  QuicTime scheduled_time = scheduled_time_it->second;
-
-  QUICHE_DCHECK(scheduled_time != QuicTime::Infinite());
-  auto range = schedule_.equal_range(scheduled_time);
-  for (auto it = range.first; it != range.second; ++it) {
-    if (it->second == actor) {
-      schedule_.erase(it);
-      scheduled_time_it->second = QuicTime::Infinite();
-      return;
-    }
-  }
-  QUICHE_DCHECK(false);
-}
-
-const QuicClock* Simulator::GetClock() const {
-  return &clock_;
-}
-
-QuicRandom* Simulator::GetRandomGenerator() {
-  if (random_generator_ == nullptr) {
-    random_generator_ = QuicRandom::GetInstance();
-  }
-
-  return random_generator_;
-}
-
-quiche::QuicheBufferAllocator* Simulator::GetStreamSendBufferAllocator() {
-  return &buffer_allocator_;
-}
-
-QuicAlarmFactory* Simulator::GetAlarmFactory() {
-  return &alarm_factory_;
-}
-
-Simulator::RunForDelegate::RunForDelegate(bool* run_for_should_stop)
-    : run_for_should_stop_(run_for_should_stop) {}
-
-void Simulator::RunForDelegate::OnAlarm() {
-  *run_for_should_stop_ = true;
-}
-
-void Simulator::RunFor(QuicTime::Delta time_span) {
-  QUICHE_DCHECK(!run_for_alarm_->IsSet());
-
-  // RunFor() ensures that the simulation stops at the exact time specified by
-  // scheduling an alarm at that point and using that alarm to abort the
-  // simulation.  An alarm is necessary because otherwise it is possible that
-  // nothing is scheduled at |end_time|, so the simulation will either go
-  // further than requested or stop before reaching |end_time|.
-  const QuicTime end_time = clock_.Now() + time_span;
-  run_for_alarm_->Set(end_time);
-  run_for_should_stop_ = false;
-  bool simulation_result = RunUntil([this]() { return run_for_should_stop_; });
-
-  QUICHE_DCHECK(simulation_result);
-  QUICHE_DCHECK(clock_.Now() == end_time);
-}
-
-void Simulator::HandleNextScheduledActor() {
-  const auto current_event_it = schedule_.begin();
-  QuicTime event_time = current_event_it->first;
-  Actor* actor = current_event_it->second;
-  QUIC_DVLOG(3) << "At t = " << event_time.ToDebuggingValue() << ", calling "
-                << actor->name();
-
-  Unschedule(actor);
-
-  if (clock_.Now() > event_time) {
-    QUIC_BUG(quic_bug_10150_1)
-        << "Error: event registered by [" << actor->name()
-        << "] requires travelling back in time.  Current time: "
-        << clock_.Now().ToDebuggingValue()
-        << ", scheduled time: " << event_time.ToDebuggingValue();
-  }
-  clock_.now_ = event_time;
-
-  actor->Act();
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/simulator.h b/quic/test_tools/simulator/simulator.h
deleted file mode 100644
index d51476f..0000000
--- a/quic/test_tools/simulator/simulator.h
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
-
-#include <map>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "quic/core/quic_connection.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simulator/actor.h"
-#include "quic/test_tools/simulator/alarm_factory.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-namespace simulator {
-
-// Simulator is responsible for scheduling actors in the simulation and
-// providing basic utility interfaces (clock, alarms, RNG and others).
-class Simulator : public QuicConnectionHelperInterface {
- public:
-  Simulator();
-  explicit Simulator(QuicRandom* random_generator);
-  Simulator(const Simulator&) = delete;
-  Simulator& operator=(const Simulator&) = delete;
-  ~Simulator() override;
-
-  // Schedule the specified actor.  This method will ensure that |actor| is
-  // called at |new_time| at latest.  If Schedule() is called multiple times
-  // before the Actor is called, Act() is called exactly once, at the earliest
-  // time requested, and the Actor has to reschedule itself manually for the
-  // subsequent times if they are still necessary.
-  void Schedule(Actor* actor, QuicTime new_time);
-
-  // Remove the specified actor from the schedule.
-  void Unschedule(Actor* actor);
-
-  // Begin QuicConnectionHelperInterface implementation.
-  const QuicClock* GetClock() const override;
-  QuicRandom* GetRandomGenerator() override;
-  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
-  // End QuicConnectionHelperInterface implementation.
-
-  QuicAlarmFactory* GetAlarmFactory();
-
-  void set_random_generator(QuicRandom* random) { random_generator_ = random; }
-
-  bool enable_random_delays() const { return enable_random_delays_; }
-
-  // Run the simulation until either no actors are scheduled or
-  // |termination_predicate| returns true.  Returns true if terminated due to
-  // predicate, and false otherwise.
-  template <class TerminationPredicate>
-  bool RunUntil(TerminationPredicate termination_predicate);
-
-  // Same as RunUntil, except this function also accepts a |deadline|, and will
-  // return false if the deadline is exceeded.
-  template <class TerminationPredicate>
-  bool RunUntilOrTimeout(TerminationPredicate termination_predicate,
-                         QuicTime::Delta deadline);
-
-  // Runs the simulation for exactly the specified |time_span|.
-  void RunFor(QuicTime::Delta time_span);
-
- private:
-  friend class Actor;
-
-  class Clock : public QuicClock {
-   public:
-    // Do not start at zero as certain code can treat zero as an invalid
-    // timestamp.
-    const QuicTime kStartTime =
-        QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1);
-
-    Clock();
-
-    QuicTime ApproximateNow() const override;
-    QuicTime Now() const override;
-    QuicWallTime WallNow() const override;
-
-    QuicTime now_;
-  };
-
-  // The delegate used for RunFor().
-  class RunForDelegate : public QuicAlarm::DelegateWithoutContext {
-   public:
-    explicit RunForDelegate(bool* run_for_should_stop);
-    void OnAlarm() override;
-
-   private:
-    // Pointer to |run_for_should_stop_| in the parent simulator.
-    bool* run_for_should_stop_;
-  };
-
-  // Register an actor with the simulator. Invoked by Actor constructor.
-  void AddActor(Actor* actor);
-
-  // Unregister an actor with the simulator. Invoked by Actor destructor.
-  void RemoveActor(Actor* actor);
-
-  // Finds the next scheduled actor, advances time to the schedule time and
-  // notifies the actor.
-  void HandleNextScheduledActor();
-
-  Clock clock_;
-  QuicRandom* random_generator_;
-  quiche::SimpleBufferAllocator buffer_allocator_;
-  AlarmFactory alarm_factory_;
-
-  // Alarm for RunFor() method.
-  std::unique_ptr<QuicAlarm> run_for_alarm_;
-  // Flag used to stop simulations ran via RunFor().
-  bool run_for_should_stop_;
-
-  // Indicates whether the simulator should add random delays on the links in
-  // order to avoid synchronization issues.
-  bool enable_random_delays_;
-
-  // Schedule of when the actors will be executed via an Act() call.  The
-  // schedule is subject to the following invariants:
-  // - An actor cannot be scheduled for a later time than it's currently in the
-  //   schedule.
-  // - An actor is removed from schedule either immediately before Act() is
-  //   called or by explicitly calling Unschedule().
-  // - Each Actor appears in the map at most once.
-  std::multimap<QuicTime, Actor*> schedule_;
-  // For each actor, maintain the time it is scheduled at.  The value for
-  // unscheduled actors is QuicTime::Infinite().
-  absl::flat_hash_map<Actor*, QuicTime> scheduled_times_;
-  absl::flat_hash_set<std::string> actor_names_;
-};
-
-template <class TerminationPredicate>
-bool Simulator::RunUntil(TerminationPredicate termination_predicate) {
-  bool predicate_value = false;
-  while (true) {
-    predicate_value = termination_predicate();
-    if (predicate_value || schedule_.empty()) {
-      break;
-    }
-    HandleNextScheduledActor();
-  }
-  return predicate_value;
-}
-
-template <class TerminationPredicate>
-bool Simulator::RunUntilOrTimeout(TerminationPredicate termination_predicate,
-                                  QuicTime::Delta timeout) {
-  QuicTime end_time = clock_.Now() + timeout;
-  bool return_value = RunUntil([end_time, &termination_predicate, this]() {
-    return termination_predicate() || clock_.Now() >= end_time;
-  });
-
-  if (clock_.Now() >= end_time) {
-    return false;
-  }
-  return return_value;
-}
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
diff --git a/quic/test_tools/simulator/simulator_test.cc b/quic/test_tools/simulator/simulator_test.cc
deleted file mode 100644
index fe84170..0000000
--- a/quic/test_tools/simulator/simulator_test.cc
+++ /dev/null
@@ -1,832 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/simulator.h"
-
-#include <utility>
-
-#include "absl/container/node_hash_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/test_tools/simulator/alarm_factory.h"
-#include "quic/test_tools/simulator/link.h"
-#include "quic/test_tools/simulator/packet_filter.h"
-#include "quic/test_tools/simulator/queue.h"
-#include "quic/test_tools/simulator/switch.h"
-#include "quic/test_tools/simulator/traffic_policer.h"
-
-using testing::_;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace simulator {
-
-// A simple counter that increments its value by 1 every specified period.
-class Counter : public Actor {
- public:
-  Counter(Simulator* simulator, std::string name, QuicTime::Delta period)
-      : Actor(simulator, name), value_(-1), period_(period) {
-    Schedule(clock_->Now());
-  }
-  ~Counter() override {}
-
-  inline int get_value() const { return value_; }
-
-  void Act() override {
-    ++value_;
-    QUIC_DVLOG(1) << name_ << " has value " << value_ << " at time "
-                  << clock_->Now().ToDebuggingValue();
-    Schedule(clock_->Now() + period_);
-  }
-
- private:
-  int value_;
-  QuicTime::Delta period_;
-};
-
-class SimulatorTest : public QuicTest {};
-
-// Test that the basic event handling works, and that Actors can be created and
-// destroyed mid-simulation.
-TEST_F(SimulatorTest, Counters) {
-  Simulator simulator;
-  for (int i = 0; i < 2; ++i) {
-    Counter fast_counter(&simulator, "fast_counter",
-                         QuicTime::Delta::FromSeconds(3));
-    Counter slow_counter(&simulator, "slow_counter",
-                         QuicTime::Delta::FromSeconds(10));
-
-    simulator.RunUntil(
-        [&slow_counter]() { return slow_counter.get_value() >= 10; });
-
-    EXPECT_EQ(10, slow_counter.get_value());
-    EXPECT_EQ(10 * 10 / 3, fast_counter.get_value());
-  }
-}
-
-// A port which counts the number of packets received on it, both total and
-// per-destination.
-class CounterPort : public UnconstrainedPortInterface {
- public:
-  CounterPort() { Reset(); }
-  ~CounterPort() override {}
-
-  inline QuicByteCount bytes() const { return bytes_; }
-  inline QuicPacketCount packets() const { return packets_; }
-
-  void AcceptPacket(std::unique_ptr<Packet> packet) override {
-    bytes_ += packet->size;
-    packets_ += 1;
-
-    per_destination_packet_counter_[packet->destination] += 1;
-  }
-
-  void Reset() {
-    bytes_ = 0;
-    packets_ = 0;
-    per_destination_packet_counter_.clear();
-  }
-
-  QuicPacketCount CountPacketsForDestination(std::string destination) const {
-    auto result_it = per_destination_packet_counter_.find(destination);
-    if (result_it == per_destination_packet_counter_.cend()) {
-      return 0;
-    }
-    return result_it->second;
-  }
-
- private:
-  QuicByteCount bytes_;
-  QuicPacketCount packets_;
-
-  absl::node_hash_map<std::string, QuicPacketCount>
-      per_destination_packet_counter_;
-};
-
-// Sends the packet to the specified destination at the uplink rate.  Provides a
-// CounterPort as an Rx interface.
-class LinkSaturator : public Endpoint {
- public:
-  LinkSaturator(Simulator* simulator,
-                std::string name,
-                QuicByteCount packet_size,
-                std::string destination)
-      : Endpoint(simulator, name),
-        packet_size_(packet_size),
-        destination_(std::move(destination)),
-        bytes_transmitted_(0),
-        packets_transmitted_(0) {
-    Schedule(clock_->Now());
-  }
-
-  void Act() override {
-    if (tx_port_->TimeUntilAvailable().IsZero()) {
-      auto packet = std::make_unique<Packet>();
-      packet->source = name_;
-      packet->destination = destination_;
-      packet->tx_timestamp = clock_->Now();
-      packet->size = packet_size_;
-
-      tx_port_->AcceptPacket(std::move(packet));
-
-      bytes_transmitted_ += packet_size_;
-      packets_transmitted_ += 1;
-    }
-
-    Schedule(clock_->Now() + tx_port_->TimeUntilAvailable());
-  }
-
-  UnconstrainedPortInterface* GetRxPort() override {
-    return static_cast<UnconstrainedPortInterface*>(&rx_port_);
-  }
-
-  void SetTxPort(ConstrainedPortInterface* port) override { tx_port_ = port; }
-
-  CounterPort* counter() { return &rx_port_; }
-
-  inline QuicByteCount bytes_transmitted() const { return bytes_transmitted_; }
-  inline QuicPacketCount packets_transmitted() const {
-    return packets_transmitted_;
-  }
-
-  void Pause() { Unschedule(); }
-  void Resume() { Schedule(clock_->Now()); }
-
- private:
-  QuicByteCount packet_size_;
-  std::string destination_;
-
-  ConstrainedPortInterface* tx_port_;
-  CounterPort rx_port_;
-
-  QuicByteCount bytes_transmitted_;
-  QuicPacketCount packets_transmitted_;
-};
-
-// Saturate a symmetric link and verify that the number of packets sent and
-// received is correct.
-TEST_F(SimulatorTest, DirectLinkSaturation) {
-  Simulator simulator;
-  LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
-  LinkSaturator saturator_b(&simulator, "Saturator B", 100, "Saturator A");
-  SymmetricLink link(&saturator_a, &saturator_b,
-                     QuicBandwidth::FromKBytesPerSecond(1000),
-                     QuicTime::Delta::FromMilliseconds(100) +
-                         QuicTime::Delta::FromMicroseconds(1));
-
-  const QuicTime start_time = simulator.GetClock()->Now();
-  const QuicTime after_first_50_ms =
-      start_time + QuicTime::Delta::FromMilliseconds(50);
-  simulator.RunUntil([&simulator, after_first_50_ms]() {
-    return simulator.GetClock()->Now() >= after_first_50_ms;
-  });
-  EXPECT_LE(1000u * 50u, saturator_a.bytes_transmitted());
-  EXPECT_GE(1000u * 51u, saturator_a.bytes_transmitted());
-  EXPECT_LE(1000u * 50u, saturator_b.bytes_transmitted());
-  EXPECT_GE(1000u * 51u, saturator_b.bytes_transmitted());
-  EXPECT_LE(50u, saturator_a.packets_transmitted());
-  EXPECT_GE(51u, saturator_a.packets_transmitted());
-  EXPECT_LE(500u, saturator_b.packets_transmitted());
-  EXPECT_GE(501u, saturator_b.packets_transmitted());
-  EXPECT_EQ(0u, saturator_a.counter()->bytes());
-  EXPECT_EQ(0u, saturator_b.counter()->bytes());
-
-  simulator.RunUntil([&saturator_a, &saturator_b]() {
-    if (saturator_a.counter()->packets() > 1000 ||
-        saturator_b.counter()->packets() > 100) {
-      ADD_FAILURE() << "The simulation did not arrive at the expected "
-                       "termination contidition. Saturator A counter: "
-                    << saturator_a.counter()->packets()
-                    << ", saturator B counter: "
-                    << saturator_b.counter()->packets();
-      return true;
-    }
-
-    return saturator_a.counter()->packets() == 1000 &&
-           saturator_b.counter()->packets() == 100;
-  });
-  EXPECT_EQ(201u, saturator_a.packets_transmitted());
-  EXPECT_EQ(2001u, saturator_b.packets_transmitted());
-  EXPECT_EQ(201u * 1000, saturator_a.bytes_transmitted());
-  EXPECT_EQ(2001u * 100, saturator_b.bytes_transmitted());
-
-  EXPECT_EQ(1000u,
-            saturator_a.counter()->CountPacketsForDestination("Saturator A"));
-  EXPECT_EQ(100u,
-            saturator_b.counter()->CountPacketsForDestination("Saturator B"));
-  EXPECT_EQ(0u,
-            saturator_a.counter()->CountPacketsForDestination("Saturator B"));
-  EXPECT_EQ(0u,
-            saturator_b.counter()->CountPacketsForDestination("Saturator A"));
-
-  const QuicTime end_time = simulator.GetClock()->Now();
-  const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
-      saturator_a.bytes_transmitted(), end_time - start_time);
-  EXPECT_APPROX_EQ(link.bandwidth(), observed_bandwidth, 0.01f);
-}
-
-// Accepts packets and stores them internally.
-class PacketAcceptor : public ConstrainedPortInterface {
- public:
-  void AcceptPacket(std::unique_ptr<Packet> packet) override {
-    packets_.emplace_back(std::move(packet));
-  }
-
-  QuicTime::Delta TimeUntilAvailable() override {
-    return QuicTime::Delta::Zero();
-  }
-
-  std::vector<std::unique_ptr<Packet>>* packets() { return &packets_; }
-
- private:
-  std::vector<std::unique_ptr<Packet>> packets_;
-};
-
-// Ensure the queue behaves correctly with accepting packets.
-TEST_F(SimulatorTest, Queue) {
-  Simulator simulator;
-  Queue queue(&simulator, "Queue", 1000);
-  PacketAcceptor acceptor;
-  queue.set_tx_port(&acceptor);
-
-  EXPECT_EQ(0u, queue.bytes_queued());
-  EXPECT_EQ(0u, queue.packets_queued());
-  EXPECT_EQ(0u, acceptor.packets()->size());
-
-  auto first_packet = std::make_unique<Packet>();
-  first_packet->size = 600;
-  queue.AcceptPacket(std::move(first_packet));
-  EXPECT_EQ(600u, queue.bytes_queued());
-  EXPECT_EQ(1u, queue.packets_queued());
-  EXPECT_EQ(0u, acceptor.packets()->size());
-
-  // The second packet does not fit and is dropped.
-  auto second_packet = std::make_unique<Packet>();
-  second_packet->size = 500;
-  queue.AcceptPacket(std::move(second_packet));
-  EXPECT_EQ(600u, queue.bytes_queued());
-  EXPECT_EQ(1u, queue.packets_queued());
-  EXPECT_EQ(0u, acceptor.packets()->size());
-
-  auto third_packet = std::make_unique<Packet>();
-  third_packet->size = 400;
-  queue.AcceptPacket(std::move(third_packet));
-  EXPECT_EQ(1000u, queue.bytes_queued());
-  EXPECT_EQ(2u, queue.packets_queued());
-  EXPECT_EQ(0u, acceptor.packets()->size());
-
-  // Run until there is nothing scheduled, so that the queue can deplete.
-  simulator.RunUntil([]() { return false; });
-  EXPECT_EQ(0u, queue.bytes_queued());
-  EXPECT_EQ(0u, queue.packets_queued());
-  ASSERT_EQ(2u, acceptor.packets()->size());
-  EXPECT_EQ(600u, acceptor.packets()->at(0)->size);
-  EXPECT_EQ(400u, acceptor.packets()->at(1)->size);
-}
-
-// Simulate a situation where the bottleneck link is 10 times slower than the
-// uplink, and they are separated by a queue.
-TEST_F(SimulatorTest, QueueBottleneck) {
-  const QuicBandwidth local_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(1000);
-  const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
-  const QuicTime::Delta local_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(1);
-  const QuicTime::Delta bottleneck_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(20);
-  const QuicByteCount bdp =
-      bottleneck_bandwidth *
-      (local_propagation_delay + bottleneck_propagation_delay);
-
-  Simulator simulator;
-  LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
-  ASSERT_GE(bdp, 1000u);
-  Queue queue(&simulator, "Queue", bdp);
-  CounterPort counter;
-
-  OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
-                        local_propagation_delay);
-  OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
-                             bottleneck_bandwidth,
-                             bottleneck_propagation_delay);
-  saturator.SetTxPort(&local_link);
-  queue.set_tx_port(&bottleneck_link);
-
-  static const QuicPacketCount packets_received = 1000;
-  simulator.RunUntil(
-      [&counter]() { return counter.packets() == packets_received; });
-  const double loss_ratio = 1 - static_cast<double>(packets_received) /
-                                    saturator.packets_transmitted();
-  EXPECT_NEAR(loss_ratio, 0.9, 0.001);
-}
-
-// Verify that the queue of exactly one packet allows the transmission to
-// actually go through.
-TEST_F(SimulatorTest, OnePacketQueue) {
-  const QuicBandwidth local_bandwidth =
-      QuicBandwidth::FromKBytesPerSecond(1000);
-  const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
-  const QuicTime::Delta local_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(1);
-  const QuicTime::Delta bottleneck_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(20);
-
-  Simulator simulator;
-  LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
-  Queue queue(&simulator, "Queue", 1000);
-  CounterPort counter;
-
-  OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
-                        local_propagation_delay);
-  OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
-                             bottleneck_bandwidth,
-                             bottleneck_propagation_delay);
-  saturator.SetTxPort(&local_link);
-  queue.set_tx_port(&bottleneck_link);
-
-  static const QuicPacketCount packets_received = 10;
-  // The deadline here is to prevent this tests from looping infinitely in case
-  // the packets never reach the receiver.
-  const QuicTime deadline =
-      simulator.GetClock()->Now() + QuicTime::Delta::FromSeconds(10);
-  simulator.RunUntil([&simulator, &counter, deadline]() {
-    return counter.packets() == packets_received ||
-           simulator.GetClock()->Now() > deadline;
-  });
-  ASSERT_EQ(packets_received, counter.packets());
-}
-
-// Simulate a network where three endpoints are connected to a switch and they
-// are sending traffic in circle (1 -> 2, 2 -> 3, 3 -> 1).
-TEST_F(SimulatorTest, SwitchedNetwork) {
-  const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(10000);
-  const QuicTime::Delta base_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(50);
-
-  Simulator simulator;
-  LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
-  LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 3");
-  LinkSaturator saturator3(&simulator, "Saturator 3", 1000, "Saturator 1");
-  Switch network_switch(&simulator, "Switch", 8,
-                        bandwidth * base_propagation_delay * 10);
-
-  // For determinicity, make it so that the first packet will arrive from
-  // Saturator 1, then from Saturator 2, and then from Saturator 3.
-  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
-                      base_propagation_delay);
-  SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
-                      base_propagation_delay * 2);
-  SymmetricLink link3(&saturator3, network_switch.port(3), bandwidth,
-                      base_propagation_delay * 3);
-
-  const QuicTime start_time = simulator.GetClock()->Now();
-  static const QuicPacketCount bytes_received = 64 * 1000;
-  simulator.RunUntil([&saturator1]() {
-    return saturator1.counter()->bytes() >= bytes_received;
-  });
-  const QuicTime end_time = simulator.GetClock()->Now();
-
-  const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
-      bytes_received, end_time - start_time);
-  const double bandwidth_ratio =
-      static_cast<double>(observed_bandwidth.ToBitsPerSecond()) /
-      bandwidth.ToBitsPerSecond();
-  EXPECT_NEAR(1, bandwidth_ratio, 0.1);
-
-  const double normalized_received_packets_for_saturator_2 =
-      static_cast<double>(saturator2.counter()->packets()) /
-      saturator1.counter()->packets();
-  const double normalized_received_packets_for_saturator_3 =
-      static_cast<double>(saturator3.counter()->packets()) /
-      saturator1.counter()->packets();
-  EXPECT_NEAR(1, normalized_received_packets_for_saturator_2, 0.1);
-  EXPECT_NEAR(1, normalized_received_packets_for_saturator_3, 0.1);
-
-  // Since Saturator 1 has its packet arrive first into the switch, switch will
-  // always know how to route traffic to it.
-  EXPECT_EQ(0u,
-            saturator2.counter()->CountPacketsForDestination("Saturator 1"));
-  EXPECT_EQ(0u,
-            saturator3.counter()->CountPacketsForDestination("Saturator 1"));
-
-  // Packets from the other saturators will be broadcast at least once.
-  EXPECT_EQ(1u,
-            saturator1.counter()->CountPacketsForDestination("Saturator 2"));
-  EXPECT_EQ(1u,
-            saturator3.counter()->CountPacketsForDestination("Saturator 2"));
-  EXPECT_EQ(1u,
-            saturator1.counter()->CountPacketsForDestination("Saturator 3"));
-  EXPECT_EQ(1u,
-            saturator2.counter()->CountPacketsForDestination("Saturator 3"));
-}
-
-// Toggle an alarm on and off at the specified interval.  Assumes that alarm is
-// initially set and unsets it almost immediately after the object is
-// instantiated.
-class AlarmToggler : public Actor {
- public:
-  AlarmToggler(Simulator* simulator,
-               std::string name,
-               QuicAlarm* alarm,
-               QuicTime::Delta interval)
-      : Actor(simulator, name),
-        alarm_(alarm),
-        interval_(interval),
-        deadline_(alarm->deadline()),
-        times_set_(0),
-        times_cancelled_(0) {
-    EXPECT_TRUE(alarm->IsSet());
-    EXPECT_GE(alarm->deadline(), clock_->Now());
-    Schedule(clock_->Now());
-  }
-
-  void Act() override {
-    if (deadline_ <= clock_->Now()) {
-      return;
-    }
-
-    if (alarm_->IsSet()) {
-      alarm_->Cancel();
-      times_cancelled_++;
-    } else {
-      alarm_->Set(deadline_);
-      times_set_++;
-    }
-
-    Schedule(clock_->Now() + interval_);
-  }
-
-  inline int times_set() { return times_set_; }
-  inline int times_cancelled() { return times_cancelled_; }
-
- private:
-  QuicAlarm* alarm_;
-  QuicTime::Delta interval_;
-  QuicTime deadline_;
-
-  // Counts the number of times the alarm was set.
-  int times_set_;
-  // Counts the number of times the alarm was cancelled.
-  int times_cancelled_;
-};
-
-// Counts the number of times an alarm has fired.
-class CounterDelegate : public QuicAlarm::DelegateWithoutContext {
- public:
-  explicit CounterDelegate(size_t* counter) : counter_(counter) {}
-
-  void OnAlarm() override { *counter_ += 1; }
-
- private:
-  size_t* counter_;
-};
-
-// Verifies that the alarms work correctly, even when they are repeatedly
-// toggled.
-TEST_F(SimulatorTest, Alarms) {
-  Simulator simulator;
-  QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
-
-  size_t fast_alarm_counter = 0;
-  size_t slow_alarm_counter = 0;
-  std::unique_ptr<QuicAlarm> alarm_fast(
-      alarm_factory->CreateAlarm(new CounterDelegate(&fast_alarm_counter)));
-  std::unique_ptr<QuicAlarm> alarm_slow(
-      alarm_factory->CreateAlarm(new CounterDelegate(&slow_alarm_counter)));
-
-  const QuicTime start_time = simulator.GetClock()->Now();
-  alarm_fast->Set(start_time + QuicTime::Delta::FromMilliseconds(100));
-  alarm_slow->Set(start_time + QuicTime::Delta::FromMilliseconds(750));
-  AlarmToggler toggler(&simulator, "Toggler", alarm_slow.get(),
-                       QuicTime::Delta::FromMilliseconds(100));
-
-  const QuicTime end_time =
-      start_time + QuicTime::Delta::FromMilliseconds(1000);
-  EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
-    return simulator.GetClock()->Now() >= end_time;
-  }));
-  EXPECT_EQ(1u, slow_alarm_counter);
-  EXPECT_EQ(1u, fast_alarm_counter);
-
-  EXPECT_EQ(4, toggler.times_set());
-  EXPECT_EQ(4, toggler.times_cancelled());
-}
-
-// Verifies that a cancelled alarm is never fired.
-TEST_F(SimulatorTest, AlarmCancelling) {
-  Simulator simulator;
-  QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
-
-  size_t alarm_counter = 0;
-  std::unique_ptr<QuicAlarm> alarm(
-      alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
-
-  const QuicTime start_time = simulator.GetClock()->Now();
-  const QuicTime alarm_at = start_time + QuicTime::Delta::FromMilliseconds(300);
-  const QuicTime end_time = start_time + QuicTime::Delta::FromMilliseconds(400);
-
-  alarm->Set(alarm_at);
-  alarm->Cancel();
-  EXPECT_FALSE(alarm->IsSet());
-
-  EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
-    return simulator.GetClock()->Now() >= end_time;
-  }));
-
-  EXPECT_FALSE(alarm->IsSet());
-  EXPECT_EQ(0u, alarm_counter);
-}
-
-// Verifies that alarms can be scheduled into the past.
-TEST_F(SimulatorTest, AlarmInPast) {
-  Simulator simulator;
-  QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
-
-  size_t alarm_counter = 0;
-  std::unique_ptr<QuicAlarm> alarm(
-      alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
-
-  const QuicTime start_time = simulator.GetClock()->Now();
-  simulator.RunFor(QuicTime::Delta::FromMilliseconds(400));
-
-  alarm->Set(start_time);
-  simulator.RunFor(QuicTime::Delta::FromMilliseconds(1));
-  EXPECT_FALSE(alarm->IsSet());
-  EXPECT_EQ(1u, alarm_counter);
-}
-
-// Tests Simulator::RunUntilOrTimeout() interface.
-TEST_F(SimulatorTest, RunUntilOrTimeout) {
-  Simulator simulator;
-  bool simulation_result;
-
-  // Count the number of seconds since the beginning of the simulation.
-  Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(1));
-
-  // Ensure that the counter reaches the value of 10 given a 20 second deadline.
-  simulation_result = simulator.RunUntilOrTimeout(
-      [&counter]() { return counter.get_value() == 10; },
-      QuicTime::Delta::FromSeconds(20));
-  ASSERT_TRUE(simulation_result);
-
-  // Ensure that the counter will not reach the value of 100 given that the
-  // starting value is 10 and the deadline is 20 seconds.
-  simulation_result = simulator.RunUntilOrTimeout(
-      [&counter]() { return counter.get_value() == 100; },
-      QuicTime::Delta::FromSeconds(20));
-  ASSERT_FALSE(simulation_result);
-}
-
-// Tests Simulator::RunFor() interface.
-TEST_F(SimulatorTest, RunFor) {
-  Simulator simulator;
-
-  Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(3));
-
-  simulator.RunFor(QuicTime::Delta::FromSeconds(100));
-
-  EXPECT_EQ(33, counter.get_value());
-}
-
-class MockPacketFilter : public PacketFilter {
- public:
-  MockPacketFilter(Simulator* simulator, std::string name, Endpoint* endpoint)
-      : PacketFilter(simulator, name, endpoint) {}
-  MOCK_METHOD(bool, FilterPacket, (const Packet&), (override));
-};
-
-// Set up two trivial packet filters, one allowing any packets, and one dropping
-// all of them.
-TEST_F(SimulatorTest, PacketFilter) {
-  const QuicBandwidth bandwidth =
-      QuicBandwidth::FromBytesPerSecond(1024 * 1024);
-  const QuicTime::Delta base_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(5);
-
-  Simulator simulator;
-  LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
-  LinkSaturator saturator_b(&simulator, "Saturator B", 1000, "Saturator A");
-
-  // Attach packets to the switch to create a delay between the point at which
-  // the packet is generated and the point at which it is filtered.  Note that
-  // if the saturators were connected directly, the link would be always
-  // available for the endpoint which has all of its packets dropped, resulting
-  // in saturator looping infinitely.
-  Switch network_switch(&simulator, "Switch", 8,
-                        bandwidth * base_propagation_delay * 10);
-  StrictMock<MockPacketFilter> a_to_b_filter(&simulator, "A -> B filter",
-                                             network_switch.port(1));
-  StrictMock<MockPacketFilter> b_to_a_filter(&simulator, "B -> A filter",
-                                             network_switch.port(2));
-  SymmetricLink link_a(&a_to_b_filter, &saturator_b, bandwidth,
-                       base_propagation_delay);
-  SymmetricLink link_b(&b_to_a_filter, &saturator_a, bandwidth,
-                       base_propagation_delay);
-
-  // Allow packets from A to B, but not from B to A.
-  EXPECT_CALL(a_to_b_filter, FilterPacket(_)).WillRepeatedly(Return(true));
-  EXPECT_CALL(b_to_a_filter, FilterPacket(_)).WillRepeatedly(Return(false));
-
-  // Run the simulation for a while, and expect that only B will receive any
-  // packets.
-  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
-  EXPECT_GE(saturator_b.counter()->packets(), 1u);
-  EXPECT_EQ(saturator_a.counter()->packets(), 0u);
-}
-
-// Set up a traffic policer in one direction that throttles at 25% of link
-// bandwidth, and put two link saturators at each endpoint.
-TEST_F(SimulatorTest, TrafficPolicer) {
-  const QuicBandwidth bandwidth =
-      QuicBandwidth::FromBytesPerSecond(1024 * 1024);
-  const QuicTime::Delta base_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(5);
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-
-  Simulator simulator;
-  LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
-  LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
-  Switch network_switch(&simulator, "Switch", 8,
-                        bandwidth * base_propagation_delay * 10);
-
-  static const QuicByteCount initial_burst = 1000 * 10;
-  static const QuicByteCount max_bucket_size = 1000 * 100;
-  static const QuicBandwidth target_bandwidth = bandwidth * 0.25;
-  TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
-                         target_bandwidth, network_switch.port(2));
-
-  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
-                      base_propagation_delay);
-  SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
-
-  // Ensure the initial burst passes without being dropped at all.
-  bool simulator_result = simulator.RunUntilOrTimeout(
-      [&saturator1]() {
-        return saturator1.bytes_transmitted() == initial_burst;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  saturator1.Pause();
-  simulator_result = simulator.RunUntilOrTimeout(
-      [&saturator2]() {
-        return saturator2.counter()->bytes() == initial_burst;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-  saturator1.Resume();
-
-  // Run for some time so that the initial burst is not visible.
-  const QuicTime::Delta simulation_time = QuicTime::Delta::FromSeconds(10);
-  simulator.RunFor(simulation_time);
-
-  // Ensure we've transmitted the amount of data we expected.
-  for (auto* saturator : {&saturator1, &saturator2}) {
-    EXPECT_APPROX_EQ(bandwidth * simulation_time,
-                     saturator->bytes_transmitted(), 0.01f);
-  }
-
-  // Check that only one direction is throttled.
-  EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
-                   saturator2.counter()->bytes(), 0.1f);
-  EXPECT_APPROX_EQ(saturator2.bytes_transmitted(),
-                   saturator1.counter()->bytes(), 0.1f);
-}
-
-// Ensure that a larger burst is allowed when the policed saturator exits
-// quiescence.
-TEST_F(SimulatorTest, TrafficPolicerBurst) {
-  const QuicBandwidth bandwidth =
-      QuicBandwidth::FromBytesPerSecond(1024 * 1024);
-  const QuicTime::Delta base_propagation_delay =
-      QuicTime::Delta::FromMilliseconds(5);
-  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
-
-  Simulator simulator;
-  LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
-  LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
-  Switch network_switch(&simulator, "Switch", 8,
-                        bandwidth * base_propagation_delay * 10);
-
-  const QuicByteCount initial_burst = 1000 * 10;
-  const QuicByteCount max_bucket_size = 1000 * 100;
-  const QuicBandwidth target_bandwidth = bandwidth * 0.25;
-  TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
-                         target_bandwidth, network_switch.port(2));
-
-  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
-                      base_propagation_delay);
-  SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
-
-  // Ensure at least one packet is sent on each side.
-  bool simulator_result = simulator.RunUntilOrTimeout(
-      [&saturator1, &saturator2]() {
-        return saturator1.packets_transmitted() > 0 &&
-               saturator2.packets_transmitted() > 0;
-      },
-      timeout);
-  ASSERT_TRUE(simulator_result);
-
-  // Wait until the bucket fills up.
-  saturator1.Pause();
-  saturator2.Pause();
-  simulator.RunFor(1.5f * target_bandwidth.TransferTime(max_bucket_size));
-
-  // Send a burst.
-  saturator1.Resume();
-  simulator.RunFor(bandwidth.TransferTime(max_bucket_size));
-  saturator1.Pause();
-  simulator.RunFor(2 * base_propagation_delay);
-
-  // Expect the burst to pass without losses.
-  EXPECT_APPROX_EQ(saturator1.bytes_transmitted(),
-                   saturator2.counter()->bytes(), 0.1f);
-
-  // Expect subsequent traffic to be policed.
-  saturator1.Resume();
-  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
-  EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
-                   saturator2.counter()->bytes(), 0.1f);
-}
-
-// Test that the packet aggregation support in queues work.
-TEST_F(SimulatorTest, PacketAggregation) {
-  // Model network where the delays are dominated by transfer delay.
-  const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000);
-  const QuicTime::Delta base_propagation_delay =
-      QuicTime::Delta::FromMicroseconds(1);
-  const QuicByteCount aggregation_threshold = 1000;
-  const QuicTime::Delta aggregation_timeout = QuicTime::Delta::FromSeconds(30);
-
-  Simulator simulator;
-  LinkSaturator saturator1(&simulator, "Saturator 1", 10, "Saturator 2");
-  LinkSaturator saturator2(&simulator, "Saturator 2", 10, "Saturator 1");
-  Switch network_switch(&simulator, "Switch", 8, 10 * aggregation_threshold);
-
-  // Make links with asymmetric propagation delay so that Saturator 2 only
-  // receives packets addressed to it.
-  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
-                      base_propagation_delay);
-  SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
-                      2 * base_propagation_delay);
-
-  // Enable aggregation in 1 -> 2 direction.
-  Queue* queue = network_switch.port_queue(2);
-  queue->EnableAggregation(aggregation_threshold, aggregation_timeout);
-
-  // Enable aggregation in 2 -> 1 direction in a way that all packets are larger
-  // than the threshold, so that aggregation is effectively a no-op.
-  network_switch.port_queue(1)->EnableAggregation(5, aggregation_timeout);
-
-  // Fill up the aggregation buffer up to 90% (900 bytes).
-  simulator.RunFor(0.9 * bandwidth.TransferTime(aggregation_threshold));
-  EXPECT_EQ(0u, saturator2.counter()->bytes());
-
-  // Stop sending, ensure that given a timespan much shorter than timeout, the
-  // packets remain in the queue.
-  saturator1.Pause();
-  saturator2.Pause();
-  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
-  EXPECT_EQ(0u, saturator2.counter()->bytes());
-  EXPECT_EQ(900u, queue->bytes_queued());
-
-  // Ensure that all packets have reached the saturator not affected by
-  // aggregation.  Here, 10 extra bytes account for a misrouted packet in the
-  // beginning.
-  EXPECT_EQ(910u, saturator1.counter()->bytes());
-
-  // Send 500 more bytes.  Since the aggregation threshold is 1000 bytes, and
-  // queue already has 900 bytes, 1000 bytes will be send and 400 will be in the
-  // queue.
-  saturator1.Resume();
-  simulator.RunFor(0.5 * bandwidth.TransferTime(aggregation_threshold));
-  saturator1.Pause();
-  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
-  EXPECT_EQ(1000u, saturator2.counter()->bytes());
-  EXPECT_EQ(400u, queue->bytes_queued());
-
-  // Actually time out, and cause all of the data to be received.
-  simulator.RunFor(aggregation_timeout);
-  EXPECT_EQ(1400u, saturator2.counter()->bytes());
-  EXPECT_EQ(0u, queue->bytes_queued());
-
-  // Run saturator for a longer time, to ensure that the logic to cancel and
-  // reset alarms works correctly.
-  saturator1.Resume();
-  simulator.RunFor(5.5 * bandwidth.TransferTime(aggregation_threshold));
-  saturator1.Pause();
-  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
-  EXPECT_EQ(6400u, saturator2.counter()->bytes());
-  EXPECT_EQ(500u, queue->bytes_queued());
-
-  // Time out again.
-  simulator.RunFor(aggregation_timeout);
-  EXPECT_EQ(6900u, saturator2.counter()->bytes());
-  EXPECT_EQ(0u, queue->bytes_queued());
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/switch.cc b/quic/test_tools/simulator/switch.cc
deleted file mode 100644
index 3a8ee58..0000000
--- a/quic/test_tools/simulator/switch.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cinttypes>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace simulator {
-
-Switch::Switch(Simulator* simulator,
-               std::string name,
-               SwitchPortNumber port_count,
-               QuicByteCount queue_capacity) {
-  for (size_t port_number = 1; port_number <= port_count; port_number++) {
-    ports_.emplace_back(simulator,
-                        absl::StrCat(name, " (port ", port_number, ")"), this,
-                        port_number, queue_capacity);
-  }
-}
-
-Switch::~Switch() {}
-
-Switch::Port::Port(Simulator* simulator,
-                   std::string name,
-                   Switch* parent,
-                   SwitchPortNumber port_number,
-                   QuicByteCount queue_capacity)
-    : Endpoint(simulator, name),
-      parent_(parent),
-      port_number_(port_number),
-      connected_(false),
-      queue_(simulator, absl::StrCat(name, " (queue)"), queue_capacity) {}
-
-void Switch::Port::AcceptPacket(std::unique_ptr<Packet> packet) {
-  parent_->DispatchPacket(port_number_, std::move(packet));
-}
-
-void Switch::Port::EnqueuePacket(std::unique_ptr<Packet> packet) {
-  queue_.AcceptPacket(std::move(packet));
-}
-
-UnconstrainedPortInterface* Switch::Port::GetRxPort() {
-  return this;
-}
-
-void Switch::Port::SetTxPort(ConstrainedPortInterface* port) {
-  queue_.set_tx_port(port);
-  connected_ = true;
-}
-
-void Switch::Port::Act() {}
-
-void Switch::DispatchPacket(SwitchPortNumber port_number,
-                            std::unique_ptr<Packet> packet) {
-  Port* source_port = &ports_[port_number - 1];
-  const auto source_mapping_it = switching_table_.find(packet->source);
-  if (source_mapping_it == switching_table_.end()) {
-    switching_table_.insert(std::make_pair(packet->source, source_port));
-  }
-
-  const auto destination_mapping_it =
-      switching_table_.find(packet->destination);
-  if (destination_mapping_it != switching_table_.end()) {
-    destination_mapping_it->second->EnqueuePacket(std::move(packet));
-    return;
-  }
-
-  // If no mapping is available yet, broadcast the packet to all ports
-  // different from the source.
-  for (Port& egress_port : ports_) {
-    if (!egress_port.connected()) {
-      continue;
-    }
-    egress_port.EnqueuePacket(std::make_unique<Packet>(*packet));
-  }
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/switch.h b/quic/test_tools/simulator/switch.h
deleted file mode 100644
index 987086e..0000000
--- a/quic/test_tools/simulator/switch.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
-
-#include <deque>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/test_tools/simulator/queue.h"
-
-namespace quic {
-namespace simulator {
-
-using SwitchPortNumber = size_t;
-
-// Simulates a network switch with simple persistent learning scheme and queues
-// on every output port.
-class Switch {
- public:
-  Switch(Simulator* simulator,
-         std::string name,
-         SwitchPortNumber port_count,
-         QuicByteCount queue_capacity);
-  Switch(const Switch&) = delete;
-  Switch& operator=(const Switch&) = delete;
-  ~Switch();
-
-  // Returns Endpoint associated with the port under number |port_number|.  Just
-  // like on most real switches, port numbering starts with 1.
-  Endpoint* port(SwitchPortNumber port_number) {
-    QUICHE_DCHECK_NE(port_number, 0u);
-    return &ports_[port_number - 1];
-  }
-
-  Queue* port_queue(SwitchPortNumber port_number) {
-    return ports_[port_number - 1].queue();
-  }
-
- private:
-  class Port : public Endpoint, public UnconstrainedPortInterface {
-   public:
-    Port(Simulator* simulator,
-         std::string name,
-         Switch* parent,
-         SwitchPortNumber port_number,
-         QuicByteCount queue_capacity);
-    Port(Port&&) = delete;
-    Port(const Port&) = delete;
-    Port& operator=(const Port&) = delete;
-    ~Port() override {}
-
-    // Accepts packet to be routed into the switch.
-    void AcceptPacket(std::unique_ptr<Packet> packet) override;
-    // Enqueue packet to be routed out of the switch.
-    void EnqueuePacket(std::unique_ptr<Packet> packet);
-
-    UnconstrainedPortInterface* GetRxPort() override;
-    void SetTxPort(ConstrainedPortInterface* port) override;
-
-    void Act() override;
-
-    bool connected() const { return connected_; }
-    Queue* queue() { return &queue_; }
-
-   private:
-    Switch* parent_;
-    SwitchPortNumber port_number_;
-    bool connected_;
-
-    Queue queue_;
-  };
-
-  // Sends the packet to the appropriate port, or to all ports if the
-  // appropriate port is not known.
-  void DispatchPacket(SwitchPortNumber port_number,
-                      std::unique_ptr<Packet> packet);
-
-  // This cannot be a quiche::QuicheCircularDeque since pointers into this are
-  // assumed to be stable.
-  std::deque<Port> ports_;
-  absl::flat_hash_map<std::string, Port*> switching_table_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
diff --git a/quic/test_tools/simulator/traffic_policer.cc b/quic/test_tools/simulator/traffic_policer.cc
deleted file mode 100644
index be62669..0000000
--- a/quic/test_tools/simulator/traffic_policer.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/simulator/traffic_policer.h"
-
-#include <algorithm>
-
-namespace quic {
-namespace simulator {
-
-TrafficPolicer::TrafficPolicer(Simulator* simulator,
-                               std::string name,
-                               QuicByteCount initial_bucket_size,
-                               QuicByteCount max_bucket_size,
-                               QuicBandwidth target_bandwidth,
-                               Endpoint* input)
-    : PacketFilter(simulator, name, input),
-      initial_bucket_size_(initial_bucket_size),
-      max_bucket_size_(max_bucket_size),
-      target_bandwidth_(target_bandwidth),
-      last_refill_time_(clock_->Now()) {}
-
-TrafficPolicer::~TrafficPolicer() {}
-
-void TrafficPolicer::Refill() {
-  QuicTime::Delta time_passed = clock_->Now() - last_refill_time_;
-  QuicByteCount refill_size = time_passed * target_bandwidth_;
-
-  for (auto& bucket : token_buckets_) {
-    bucket.second = std::min(bucket.second + refill_size, max_bucket_size_);
-  }
-
-  last_refill_time_ = clock_->Now();
-}
-
-bool TrafficPolicer::FilterPacket(const Packet& packet) {
-  // Refill existing buckets.
-  Refill();
-
-  // Create a new bucket if one does not exist.
-  if (token_buckets_.count(packet.destination) == 0) {
-    token_buckets_.insert(
-        std::make_pair(packet.destination, initial_bucket_size_));
-  }
-
-  auto bucket = token_buckets_.find(packet.destination);
-  QUICHE_DCHECK(bucket != token_buckets_.end());
-
-  // Silently drop the packet on the floor if out of tokens
-  if (bucket->second < packet.size) {
-    return false;
-  }
-
-  bucket->second -= packet.size;
-  return true;
-}
-
-}  // namespace simulator
-}  // namespace quic
diff --git a/quic/test_tools/simulator/traffic_policer.h b/quic/test_tools/simulator/traffic_policer.h
deleted file mode 100644
index bba2b83..0000000
--- a/quic/test_tools/simulator/traffic_policer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
-#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/test_tools/simulator/packet_filter.h"
-#include "quic/test_tools/simulator/port.h"
-
-namespace quic {
-namespace simulator {
-
-// Traffic policer uses a token bucket to limit the bandwidth of the traffic
-// passing through.  It wraps around an input port and exposes an output port.
-// Only the traffic from input to the output is policed, so in case when
-// bidirectional policing is desired, two policers have to be used.  The flows
-// are hashed by the destination only.
-class TrafficPolicer : public PacketFilter {
- public:
-  TrafficPolicer(Simulator* simulator,
-                 std::string name,
-                 QuicByteCount initial_bucket_size,
-                 QuicByteCount max_bucket_size,
-                 QuicBandwidth target_bandwidth,
-                 Endpoint* input);
-  TrafficPolicer(const TrafficPolicer&) = delete;
-  TrafficPolicer& operator=(const TrafficPolicer&) = delete;
-  ~TrafficPolicer() override;
-
- protected:
-  bool FilterPacket(const Packet& packet) override;
-
- private:
-  // Refill the token buckets with all the tokens that have been granted since
-  // |last_refill_time_|.
-  void Refill();
-
-  QuicByteCount initial_bucket_size_;
-  QuicByteCount max_bucket_size_;
-  QuicBandwidth target_bandwidth_;
-
-  // The time at which the token buckets were last refilled.
-  QuicTime last_refill_time_;
-
-  // Maps each destination to the number of tokens it has left.
-  absl::flat_hash_map<std::string, QuicByteCount> token_buckets_;
-};
-
-}  // namespace simulator
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
diff --git a/quic/test_tools/test_certificates.cc b/quic/test_tools/test_certificates.cc
deleted file mode 100644
index 9194991..0000000
--- a/quic/test_tools/test_certificates.cc
+++ /dev/null
@@ -1,734 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/test_certificates.h"
-
-namespace quic {
-namespace test {
-
-// A test certificate generated by //net/tools/quic/certs/generate-certs.sh.
-ABSL_CONST_INIT const char kTestCertificateRaw[] = {
-    '\x30', '\x82', '\x03', '\xb4', '\x30', '\x82', '\x02', '\x9c', '\xa0',
-    '\x03', '\x02', '\x01', '\x02', '\x02', '\x01', '\x01', '\x30', '\x0d',
-    '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
-    '\x01', '\x0b', '\x05', '\x00', '\x30', '\x1e', '\x31', '\x1c', '\x30',
-    '\x1a', '\x06', '\x03', '\x55', '\x04', '\x03', '\x0c', '\x13', '\x51',
-    '\x55', '\x49', '\x43', '\x20', '\x53', '\x65', '\x72', '\x76', '\x65',
-    '\x72', '\x20', '\x52', '\x6f', '\x6f', '\x74', '\x20', '\x43', '\x41',
-    '\x30', '\x1e', '\x17', '\x0d', '\x32', '\x30', '\x30', '\x31', '\x33',
-    '\x30', '\x31', '\x38', '\x31', '\x33', '\x35', '\x39', '\x5a', '\x17',
-    '\x0d', '\x32', '\x30', '\x30', '\x32', '\x30', '\x32', '\x31', '\x38',
-    '\x31', '\x33', '\x35', '\x39', '\x5a', '\x30', '\x64', '\x31', '\x0b',
-    '\x30', '\x09', '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02',
-    '\x55', '\x53', '\x31', '\x13', '\x30', '\x11', '\x06', '\x03', '\x55',
-    '\x04', '\x08', '\x0c', '\x0a', '\x43', '\x61', '\x6c', '\x69', '\x66',
-    '\x6f', '\x72', '\x6e', '\x69', '\x61', '\x31', '\x16', '\x30', '\x14',
-    '\x06', '\x03', '\x55', '\x04', '\x07', '\x0c', '\x0d', '\x4d', '\x6f',
-    '\x75', '\x6e', '\x74', '\x61', '\x69', '\x6e', '\x20', '\x56', '\x69',
-    '\x65', '\x77', '\x31', '\x14', '\x30', '\x12', '\x06', '\x03', '\x55',
-    '\x04', '\x0a', '\x0c', '\x0b', '\x51', '\x55', '\x49', '\x43', '\x20',
-    '\x53', '\x65', '\x72', '\x76', '\x65', '\x72', '\x31', '\x12', '\x30',
-    '\x10', '\x06', '\x03', '\x55', '\x04', '\x03', '\x0c', '\x09', '\x31',
-    '\x32', '\x37', '\x2e', '\x30', '\x2e', '\x30', '\x2e', '\x31', '\x30',
-    '\x82', '\x01', '\x22', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86',
-    '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00',
-    '\x03', '\x82', '\x01', '\x0f', '\x00', '\x30', '\x82', '\x01', '\x0a',
-    '\x02', '\x82', '\x01', '\x01', '\x00', '\xc5', '\xe2', '\x51', '\x6d',
-    '\x3f', '\xd6', '\x28', '\xf2', '\xad', '\x34', '\x73', '\x87', '\x64',
-    '\xca', '\x33', '\x19', '\x33', '\xb7', '\x75', '\x91', '\xab', '\x31',
-    '\x19', '\x2b', '\xe3', '\xa4', '\x26', '\x09', '\x29', '\x8b', '\x2d',
-    '\xf7', '\x52', '\x75', '\xa7', '\x55', '\x15', '\xf0', '\x11', '\xc7',
-    '\xc2', '\xc4', '\xed', '\x18', '\x1b', '\x33', '\x0b', '\x71', '\x32',
-    '\xe6', '\x35', '\x89', '\xcd', '\x2d', '\x5a', '\x05', '\x57', '\x4e',
-    '\xc2', '\x78', '\x75', '\x65', '\x72', '\x2d', '\x8a', '\x17', '\x83',
-    '\xd6', '\x32', '\x90', '\x85', '\xf8', '\x22', '\xe2', '\x65', '\xa9',
-    '\xe0', '\xa0', '\xfe', '\x19', '\xb2', '\x39', '\x2d', '\x14', '\x03',
-    '\x10', '\x2f', '\xcc', '\x8b', '\x5e', '\xaa', '\x25', '\x27', '\x0d',
-    '\xa3', '\x37', '\x10', '\x0c', '\x17', '\xec', '\xf0', '\x8b', '\xc5',
-    '\x6b', '\xed', '\x6b', '\x5e', '\xb2', '\xe2', '\x35', '\x3e', '\x46',
-    '\x3b', '\xf7', '\xf6', '\x59', '\xb1', '\xe0', '\x16', '\xa6', '\xfb',
-    '\x03', '\xbf', '\x84', '\x4f', '\xce', '\x64', '\x15', '\x0d', '\x59',
-    '\x99', '\xa6', '\xf0', '\x7f', '\x8a', '\x33', '\x4b', '\xbb', '\x0b',
-    '\xb8', '\xf2', '\xd1', '\x27', '\x90', '\x8f', '\x38', '\xf8', '\x5a',
-    '\x41', '\x82', '\x07', '\x9b', '\x0d', '\xd9', '\x52', '\xe0', '\x70',
-    '\xff', '\xde', '\xda', '\xd8', '\x25', '\x4e', '\x2f', '\x2d', '\x9f',
-    '\xaf', '\x92', '\x63', '\xc7', '\x42', '\xb4', '\xdc', '\x16', '\x95',
-    '\x23', '\x05', '\x02', '\x6b', '\xb0', '\xe8', '\xc5', '\xfe', '\x15',
-    '\x9a', '\xe8', '\x7d', '\x2f', '\xdc', '\x43', '\xf4', '\x70', '\x91',
-    '\x1a', '\x93', '\xbe', '\x71', '\xaf', '\x85', '\x84', '\xdb', '\xcf',
-    '\x6b', '\x5c', '\x80', '\xb2', '\xd3', '\xf3', '\x42', '\x6e', '\x24',
-    '\xec', '\x2a', '\x62', '\x99', '\xc6', '\x3c', '\xe5', '\x32', '\xe5',
-    '\x72', '\x37', '\x30', '\x9b', '\x0b', '\xe4', '\x06', '\xb4', '\x64',
-    '\x26', '\x95', '\x59', '\xba', '\xf1', '\x53', '\x83', '\x3d', '\x99',
-    '\x6d', '\xf0', '\x80', '\xe2', '\xdb', '\x6b', '\x34', '\x52', '\x06',
-    '\x77', '\x3c', '\x73', '\xbe', '\xc6', '\xe3', '\xce', '\xb2', '\x11',
-    '\x02', '\x03', '\x01', '\x00', '\x01', '\xa3', '\x81', '\xb6', '\x30',
-    '\x81', '\xb3', '\x30', '\x0c', '\x06', '\x03', '\x55', '\x1d', '\x13',
-    '\x01', '\x01', '\xff', '\x04', '\x02', '\x30', '\x00', '\x30', '\x1d',
-    '\x06', '\x03', '\x55', '\x1d', '\x0e', '\x04', '\x16', '\x04', '\x14',
-    '\xc8', '\x54', '\x28', '\xf6', '\xd2', '\xd5', '\x12', '\x35', '\x89',
-    '\x15', '\x75', '\xb8', '\xbf', '\xdd', '\xfb', '\x4a', '\xfc', '\x6c',
-    '\x89', '\xde', '\x30', '\x1f', '\x06', '\x03', '\x55', '\x1d', '\x23',
-    '\x04', '\x18', '\x30', '\x16', '\x80', '\x14', '\x50', '\xe4', '\x1d',
-    '\xc3', '\x1a', '\xfb', '\xfd', '\x38', '\xdd', '\xa2', '\x05', '\xfd',
-    '\xc8', '\xfa', '\x57', '\x0a', '\xc1', '\x06', '\x0f', '\xae', '\x30',
-    '\x1d', '\x06', '\x03', '\x55', '\x1d', '\x25', '\x04', '\x16', '\x30',
-    '\x14', '\x06', '\x08', '\x2b', '\x06', '\x01', '\x05', '\x05', '\x07',
-    '\x03', '\x01', '\x06', '\x08', '\x2b', '\x06', '\x01', '\x05', '\x05',
-    '\x07', '\x03', '\x02', '\x30', '\x44', '\x06', '\x03', '\x55', '\x1d',
-    '\x11', '\x04', '\x3d', '\x30', '\x3b', '\x82', '\x0f', '\x77', '\x77',
-    '\x77', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
-    '\x2e', '\x6f', '\x72', '\x67', '\x82', '\x10', '\x6d', '\x61', '\x69',
-    '\x6c', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
-    '\x2e', '\x6f', '\x72', '\x67', '\x82', '\x10', '\x6d', '\x61', '\x69',
-    '\x6c', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
-    '\x2e', '\x63', '\x6f', '\x6d', '\x87', '\x04', '\x7f', '\x00', '\x00',
-    '\x01', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86',
-    '\xf7', '\x0d', '\x01', '\x01', '\x0b', '\x05', '\x00', '\x03', '\x82',
-    '\x01', '\x01', '\x00', '\x45', '\x41', '\x7a', '\x68', '\xe0', '\xa7',
-    '\x59', '\xa1', '\x62', '\x54', '\x73', '\x74', '\x14', '\x4f', '\xde',
-    '\x9c', '\x51', '\xac', '\x25', '\x97', '\x70', '\xf7', '\x09', '\x51',
-    '\x39', '\x72', '\x39', '\x3c', '\xd0', '\x31', '\xe1', '\xc3', '\x02',
-    '\x91', '\x14', '\x4d', '\x8f', '\x1d', '\x31', '\xab', '\x98', '\x7e',
-    '\xe6', '\xbb', '\xab', '\x6a', '\xd9', '\xc5', '\x86', '\xaa', '\x4e',
-    '\x6a', '\x48', '\xe9', '\xf8', '\xd7', '\xb3', '\x1d', '\xa0', '\xc5',
-    '\xe6', '\xbf', '\x4c', '\x5a', '\x9b', '\xb5', '\x78', '\x01', '\xa3',
-    '\x39', '\x7b', '\x5f', '\xbc', '\xb8', '\xa7', '\xc2', '\x71', '\xb0',
-    '\x7b', '\xdd', '\xa1', '\x87', '\xa6', '\x54', '\x9c', '\xf6', '\x59',
-    '\x81', '\xb1', '\x2c', '\xde', '\xc5', '\x8a', '\xa2', '\x06', '\x89',
-    '\xb5', '\xc1', '\x7a', '\xbe', '\x0c', '\x9f', '\x3d', '\xde', '\x81',
-    '\x48', '\x53', '\x71', '\x7b', '\x8d', '\xc7', '\xea', '\x87', '\xd7',
-    '\xd1', '\xda', '\x94', '\xb4', '\xc5', '\xac', '\x1e', '\x83', '\xa3',
-    '\x42', '\x7d', '\xe6', '\xab', '\x3f', '\xd6', '\x1c', '\xd6', '\x65',
-    '\xc3', '\x60', '\xe9', '\x76', '\x54', '\x79', '\x3f', '\xeb', '\x65',
-    '\x85', '\x4f', '\x60', '\x7d', '\xbb', '\x96', '\x03', '\x54', '\x2e',
-    '\xd0', '\x1b', '\xe2', '\x6c', '\x2d', '\x91', '\xae', '\x33', '\x9c',
-    '\x04', '\xc4', '\x44', '\x0a', '\x7d', '\x5f', '\xbb', '\x80', '\xa2',
-    '\x01', '\xbc', '\x90', '\x81', '\xa5', '\xdc', '\x4a', '\xc8', '\x77',
-    '\xc9', '\x8d', '\x34', '\x17', '\xe6', '\x2a', '\x7d', '\x02', '\x1e',
-    '\x32', '\x3f', '\x7d', '\xd7', '\x0c', '\x80', '\x5b', '\xc6', '\x94',
-    '\x6a', '\x42', '\x36', '\x05', '\x9f', '\x9e', '\xc5', '\x85', '\x9f',
-    '\x60', '\xe3', '\x72', '\x73', '\x34', '\x39', '\x44', '\x75', '\x55',
-    '\x60', '\x24', '\x7a', '\x8b', '\x09', '\x74', '\x84', '\x72', '\xfd',
-    '\x91', '\x68', '\x93', '\x57', '\x9e', '\x70', '\x46', '\x4d', '\xe4',
-    '\x30', '\x84', '\x5f', '\x20', '\x07', '\xad', '\xfd', '\x86', '\x32',
-    '\xd3', '\xfb', '\xba', '\xaf', '\xd9', '\x61', '\x14', '\x3c', '\xe0',
-    '\xa1', '\xa9', '\x51', '\x51', '\x0f', '\xad', '\x60'};
-
-ABSL_CONST_INIT const absl::string_view kTestCertificate(
-    kTestCertificateRaw,
-    sizeof(kTestCertificateRaw));
-
-ABSL_CONST_INIT const char kTestCertificatePem[] =
-    R"(Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 1 (0x1)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=QUIC Server Root CA
-        Validity
-            Not Before: Jan 30 18:13:59 2020 GMT
-            Not After : Feb  2 18:13:59 2020 GMT
-        Subject: C=US, ST=California, L=Mountain View, O=QUIC Server, CN=127.0.0.1
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-                RSA Public-Key: (2048 bit)
-                Modulus:
-                    00:c5:e2:51:6d:3f:d6:28:f2:ad:34:73:87:64:ca:
-                    33:19:33:b7:75:91:ab:31:19:2b:e3:a4:26:09:29:
-                    8b:2d:f7:52:75:a7:55:15:f0:11:c7:c2:c4:ed:18:
-                    1b:33:0b:71:32:e6:35:89:cd:2d:5a:05:57:4e:c2:
-                    78:75:65:72:2d:8a:17:83:d6:32:90:85:f8:22:e2:
-                    65:a9:e0:a0:fe:19:b2:39:2d:14:03:10:2f:cc:8b:
-                    5e:aa:25:27:0d:a3:37:10:0c:17:ec:f0:8b:c5:6b:
-                    ed:6b:5e:b2:e2:35:3e:46:3b:f7:f6:59:b1:e0:16:
-                    a6:fb:03:bf:84:4f:ce:64:15:0d:59:99:a6:f0:7f:
-                    8a:33:4b:bb:0b:b8:f2:d1:27:90:8f:38:f8:5a:41:
-                    82:07:9b:0d:d9:52:e0:70:ff:de:da:d8:25:4e:2f:
-                    2d:9f:af:92:63:c7:42:b4:dc:16:95:23:05:02:6b:
-                    b0:e8:c5:fe:15:9a:e8:7d:2f:dc:43:f4:70:91:1a:
-                    93:be:71:af:85:84:db:cf:6b:5c:80:b2:d3:f3:42:
-                    6e:24:ec:2a:62:99:c6:3c:e5:32:e5:72:37:30:9b:
-                    0b:e4:06:b4:64:26:95:59:ba:f1:53:83:3d:99:6d:
-                    f0:80:e2:db:6b:34:52:06:77:3c:73:be:c6:e3:ce:
-                    b2:11
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Basic Constraints: critical
-                CA:FALSE
-            X509v3 Subject Key Identifier:
-                C8:54:28:F6:D2:D5:12:35:89:15:75:B8:BF:DD:FB:4A:FC:6C:89:DE
-            X509v3 Authority Key Identifier:
-                keyid:50:E4:1D:C3:1A:FB:FD:38:DD:A2:05:FD:C8:FA:57:0A:C1:06:0F:AE
-
-            X509v3 Extended Key Usage:
-                TLS Web Server Authentication, TLS Web Client Authentication
-            X509v3 Subject Alternative Name:
-                DNS:www.example.org, DNS:mail.example.org, DNS:mail.example.com, IP Address:127.0.0.1
-    Signature Algorithm: sha256WithRSAEncryption
-         45:41:7a:68:e0:a7:59:a1:62:54:73:74:14:4f:de:9c:51:ac:
-         25:97:70:f7:09:51:39:72:39:3c:d0:31:e1:c3:02:91:14:4d:
-         8f:1d:31:ab:98:7e:e6:bb:ab:6a:d9:c5:86:aa:4e:6a:48:e9:
-         f8:d7:b3:1d:a0:c5:e6:bf:4c:5a:9b:b5:78:01:a3:39:7b:5f:
-         bc:b8:a7:c2:71:b0:7b:dd:a1:87:a6:54:9c:f6:59:81:b1:2c:
-         de:c5:8a:a2:06:89:b5:c1:7a:be:0c:9f:3d:de:81:48:53:71:
-         7b:8d:c7:ea:87:d7:d1:da:94:b4:c5:ac:1e:83:a3:42:7d:e6:
-         ab:3f:d6:1c:d6:65:c3:60:e9:76:54:79:3f:eb:65:85:4f:60:
-         7d:bb:96:03:54:2e:d0:1b:e2:6c:2d:91:ae:33:9c:04:c4:44:
-         0a:7d:5f:bb:80:a2:01:bc:90:81:a5:dc:4a:c8:77:c9:8d:34:
-         17:e6:2a:7d:02:1e:32:3f:7d:d7:0c:80:5b:c6:94:6a:42:36:
-         05:9f:9e:c5:85:9f:60:e3:72:73:34:39:44:75:55:60:24:7a:
-         8b:09:74:84:72:fd:91:68:93:57:9e:70:46:4d:e4:30:84:5f:
-         20:07:ad:fd:86:32:d3:fb:ba:af:d9:61:14:3c:e0:a1:a9:51:
-         51:0f:ad:60
------BEGIN CERTIFICATE-----
-MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD
-IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow
-ZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
-dW50YWluIFZpZXcxFDASBgNVBAoMC1FVSUMgU2VydmVyMRIwEAYDVQQDDAkxMjcu
-MC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF4lFtP9Yo8q00
-c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
-wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
-XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
-UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
-a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
-vsbjzrIRAgMBAAGjgbYwgbMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyFQo9tLV
-EjWJFXW4v937Svxsid4wHwYDVR0jBBgwFoAUUOQdwxr7/TjdogX9yPpXCsEGD64w
-HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEQGA1UdEQQ9MDuCD3d3dy5l
-eGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLmNvbYcE
-fwAAATANBgkqhkiG9w0BAQsFAAOCAQEARUF6aOCnWaFiVHN0FE/enFGsJZdw9wlR
-OXI5PNAx4cMCkRRNjx0xq5h+5ruratnFhqpOakjp+NezHaDF5r9MWpu1eAGjOXtf
-vLinwnGwe92hh6ZUnPZZgbEs3sWKogaJtcF6vgyfPd6BSFNxe43H6ofX0dqUtMWs
-HoOjQn3mqz/WHNZlw2DpdlR5P+tlhU9gfbuWA1Qu0BvibC2RrjOcBMRECn1fu4Ci
-AbyQgaXcSsh3yY00F+YqfQIeMj991wyAW8aUakI2BZ+exYWfYONyczQ5RHVVYCR6
-iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA==
------END CERTIFICATE-----)";
-
-// Same leaf as above, but with an intermediary attached.
-ABSL_CONST_INIT const char kTestCertificateChainPem[] =
-    R"(-----BEGIN CERTIFICATE-----
-MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD
-IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow
-ZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
-dW50YWluIFZpZXcxFDASBgNVBAoMC1FVSUMgU2VydmVyMRIwEAYDVQQDDAkxMjcu
-MC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF4lFtP9Yo8q00
-c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
-wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
-XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
-UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
-a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
-vsbjzrIRAgMBAAGjgbYwgbMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyFQo9tLV
-EjWJFXW4v937Svxsid4wHwYDVR0jBBgwFoAUUOQdwxr7/TjdogX9yPpXCsEGD64w
-HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEQGA1UdEQQ9MDuCD3d3dy5l
-eGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLmNvbYcE
-fwAAATANBgkqhkiG9w0BAQsFAAOCAQEARUF6aOCnWaFiVHN0FE/enFGsJZdw9wlR
-OXI5PNAx4cMCkRRNjx0xq5h+5ruratnFhqpOakjp+NezHaDF5r9MWpu1eAGjOXtf
-vLinwnGwe92hh6ZUnPZZgbEs3sWKogaJtcF6vgyfPd6BSFNxe43H6ofX0dqUtMWs
-HoOjQn3mqz/WHNZlw2DpdlR5P+tlhU9gfbuWA1Qu0BvibC2RrjOcBMRECn1fu4Ci
-AbyQgaXcSsh3yY00F+YqfQIeMj991wyAW8aUakI2BZ+exYWfYONyczQ5RHVVYCR6
-iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIUfVS7RH+aVGqZhrjyuyD4qCnTS+MwDQYJKoZIhvcNAQEL
-BQAwHjEcMBoGA1UEAwwTUVVJQyBTZXJ2ZXIgUm9vdCBDQTAeFw0yMDAxMzAxODEz
-NTlaFw0yMDAyMDIxODEzNTlaMB4xHDAaBgNVBAMME1FVSUMgU2VydmVyIFJvb3Qg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc3k0GGpCBf6jXHxia
-QM4ntB6pWkT+NbaZUNHb1SkG2Cp9dN5dEKOXiqOi9306j4WNWTq/q0Ku9lCPPPFs
-JTIVC3tKY8Nbiczw+mohgW4rwLgpAP5rjjVzTxSFpDWZlgkH54HpqLjJFVl4Fklg
-vzSj+rYfqP+ueesi7z7KwPwzd30jjsJlpr2rlkZkidWT5vRTD3uYhNOW7IIT0lRP
-MDTwdxTEU5unyxESAsZyckNuJDeNF0y1Aw5Xiw/Bww+CyRH+tX6OUcWNtA+ZSDU8
-oVH5m4rxYK/DaHAZrA672/ywvUcPQaNaRxsAWRVjhktgyGPT3pjqiHDCN8+42uhH
-SgrbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFDkHcMa+/04
-3aIF/cj6VwrBBg+uMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
-iX+tn1Zfxx4M5YqZlPgXFB219agrJP2vM0fzW0E4zqDvA2ALaQN+lwdnFueN3tDk
-3IJvxd2W5k1Qh7LqWFUbBghDAP43XffW/yNy0+nuR2n3nRYdNStSMrGQm7oywhBd
-5jQl0GQUyYf1jcbD76HA5JraBjEXnQyJe6gJYHiRiMaMURWyzcngOPv5w3XBzIe3
-sRM0Rk/TTZP1Qx7fDY3ikFe1w9LzAMGbKDTKfc1+F0GZByJ3pdWakUNXZvtGFhIF
-hTXMooR/wD7an6gtnXD8ixCh7bP0TyPiBhNsUb12WrvSEAm/UyciQbQlR7P+K0Z7
-Cmn1Mj4hQ+pT0t+pw/DMOw==
------END CERTIFICATE-----)";
-
-ABSL_CONST_INIT const char kTestCertWithUnknownSanTypePem[] =
-    R"(-----BEGIN CERTIFICATE-----
-MIIEYTCCA0mgAwIBAgIJAILStmLgUUcVMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV
-BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp
-c2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRAw
-DgYDVQQDDAdUZXN0IENBMB4XDTE4MTIxNzIwMTgwMFoXDTIwMTIxNjIwMTgwMFow
-gaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T
-YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu
-ZWVyaW5nMRowGAYDVQQDDBFUZXN0IEJhY2tlbmQgVGVhbTEkMCIGCSqGSIb3DQEJ
-ARYVYmFja2VuZC10ZWFtQGx5ZnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuvPdQdmwZongPAgQho/Vipd3PZWrQ6BKxIb4l/RvqtVP321IUTLs
-4vVwpXoYJ+12L+XOO3jCInszs53tHjFpTI1GE8/sasmgR6LRr2krwSoVRHPqUoc9
-tzkDG1SzKP2TRTi1MTI3FO+TnLFahntO9Zstxhv1Epz5GZ/xQLE0/LLoRYzcynL/
-iflk18iL1KM8i0Hy4cKjclOaUdnh2nh753iJfxCSb5wJfx4FH1qverYHHT6FopYR
-V40Cg0yYXcYo8yNwrg+EBY8QAT2JOMDokXNKbZpmVKiBlh0QYMX6BBiW249v3sYl
-3Ve+fZvCkle3W0xP0xJw8PdX0NRbvGOrBQIDAQABo4HAMIG9MAwGA1UdEwEB/wQC
-MAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBB
-BgNVHREEOjA4hh5zcGlmZmU6Ly9seWZ0LmNvbS9iYWNrZW5kLXRlYW2CCGx5ZnQu
-Y29tggx3d3cubHlmdC5jb20wHQYDVR0OBBYEFLHmMm0DV9jCHJSWVRwyPYpBw62r
-MB8GA1UdIwQYMBaAFBQz1vaSbPuePL++7GTMqLAMtk3kMA0GCSqGSIb3DQEBCwUA
-A4IBAQAwx3/M2o00W8GlQ3OT4y/hQGb5K2aytxx8QeSmJaaZTJbvaHhe0x3/fLgq
-uWrW3WEWFtwasilySjOrFOtB9UNmJmNOHSJD3Bslbv5htRaWnoFPCXdwZtVMdoTq
-IHIQqLoos/xj3kVD5sJSYySrveMeKaeUILTkb5ZubSivye1X2yiJLR7AtuwuiMio
-CdIOqhn6xJqYhT7z0IhdKpLNPk4w1tBZSKOXqzrXS4uoJgTC67hWslWWZ2VC6IvZ
-FmKuuGZamCCj6F1QF2IjMVM8evl84hEnN0ajdkA/QWnil9kcWvBm15Ho+oTvvJ7s
-M8MD3RDSq/90FSiME4vbyNEyTmj0
------END CERTIFICATE-----)";
-
-ABSL_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = {
-    '\x30', '\x82', '\x04', '\xbc', '\x02', '\x01', '\x00', '\x30', '\x0d',
-    '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
-    '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa6', '\x30',
-    '\x82', '\x04', '\xa2', '\x02', '\x01', '\x00', '\x02', '\x82', '\x01',
-    '\x01', '\x00', '\xc5', '\xe2', '\x51', '\x6d', '\x3f', '\xd6', '\x28',
-    '\xf2', '\xad', '\x34', '\x73', '\x87', '\x64', '\xca', '\x33', '\x19',
-    '\x33', '\xb7', '\x75', '\x91', '\xab', '\x31', '\x19', '\x2b', '\xe3',
-    '\xa4', '\x26', '\x09', '\x29', '\x8b', '\x2d', '\xf7', '\x52', '\x75',
-    '\xa7', '\x55', '\x15', '\xf0', '\x11', '\xc7', '\xc2', '\xc4', '\xed',
-    '\x18', '\x1b', '\x33', '\x0b', '\x71', '\x32', '\xe6', '\x35', '\x89',
-    '\xcd', '\x2d', '\x5a', '\x05', '\x57', '\x4e', '\xc2', '\x78', '\x75',
-    '\x65', '\x72', '\x2d', '\x8a', '\x17', '\x83', '\xd6', '\x32', '\x90',
-    '\x85', '\xf8', '\x22', '\xe2', '\x65', '\xa9', '\xe0', '\xa0', '\xfe',
-    '\x19', '\xb2', '\x39', '\x2d', '\x14', '\x03', '\x10', '\x2f', '\xcc',
-    '\x8b', '\x5e', '\xaa', '\x25', '\x27', '\x0d', '\xa3', '\x37', '\x10',
-    '\x0c', '\x17', '\xec', '\xf0', '\x8b', '\xc5', '\x6b', '\xed', '\x6b',
-    '\x5e', '\xb2', '\xe2', '\x35', '\x3e', '\x46', '\x3b', '\xf7', '\xf6',
-    '\x59', '\xb1', '\xe0', '\x16', '\xa6', '\xfb', '\x03', '\xbf', '\x84',
-    '\x4f', '\xce', '\x64', '\x15', '\x0d', '\x59', '\x99', '\xa6', '\xf0',
-    '\x7f', '\x8a', '\x33', '\x4b', '\xbb', '\x0b', '\xb8', '\xf2', '\xd1',
-    '\x27', '\x90', '\x8f', '\x38', '\xf8', '\x5a', '\x41', '\x82', '\x07',
-    '\x9b', '\x0d', '\xd9', '\x52', '\xe0', '\x70', '\xff', '\xde', '\xda',
-    '\xd8', '\x25', '\x4e', '\x2f', '\x2d', '\x9f', '\xaf', '\x92', '\x63',
-    '\xc7', '\x42', '\xb4', '\xdc', '\x16', '\x95', '\x23', '\x05', '\x02',
-    '\x6b', '\xb0', '\xe8', '\xc5', '\xfe', '\x15', '\x9a', '\xe8', '\x7d',
-    '\x2f', '\xdc', '\x43', '\xf4', '\x70', '\x91', '\x1a', '\x93', '\xbe',
-    '\x71', '\xaf', '\x85', '\x84', '\xdb', '\xcf', '\x6b', '\x5c', '\x80',
-    '\xb2', '\xd3', '\xf3', '\x42', '\x6e', '\x24', '\xec', '\x2a', '\x62',
-    '\x99', '\xc6', '\x3c', '\xe5', '\x32', '\xe5', '\x72', '\x37', '\x30',
-    '\x9b', '\x0b', '\xe4', '\x06', '\xb4', '\x64', '\x26', '\x95', '\x59',
-    '\xba', '\xf1', '\x53', '\x83', '\x3d', '\x99', '\x6d', '\xf0', '\x80',
-    '\xe2', '\xdb', '\x6b', '\x34', '\x52', '\x06', '\x77', '\x3c', '\x73',
-    '\xbe', '\xc6', '\xe3', '\xce', '\xb2', '\x11', '\x02', '\x03', '\x01',
-    '\x00', '\x01', '\x02', '\x82', '\x01', '\x00', '\x39', '\x75', '\xac',
-    '\x1b', '\x43', '\x0c', '\x16', '\xbb', '\xd0', '\xdb', '\x88', '\x28',
-    '\x6a', '\x75', '\xe4', '\x3c', '\x8f', '\x2d', '\xd8', '\x6f', '\xc1',
-    '\xfb', '\xf1', '\xc9', '\x32', '\xc2', '\xb9', '\x60', '\xb3', '\xb5',
-    '\x7c', '\x55', '\x72', '\x96', '\x43', '\x4e', '\x8b', '\x9e', '\x38',
-    '\x2b', '\x7f', '\x3c', '\xdb', '\x73', '\xc2', '\x82', '\x21', '\xf2',
-    '\x6e', '\xcb', '\x36', '\x04', '\x9b', '\x95', '\x6d', '\xac', '\x5b',
-    '\x5b', '\xbd', '\x50', '\x69', '\x16', '\x59', '\xff', '\x2b', '\x38',
-    '\x04', '\xca', '\x2f', '\xc8', '\x93', '\x7e', '\x27', '\xf3', '\x01',
-    '\x7e', '\x40', '\x81', '\xbf', '\x07', '\x0b', '\x1f', '\x5b', '\x1d',
-    '\x92', '\x7e', '\x22', '\xc3', '\x0c', '\x3d', '\x22', '\xbe', '\xc3',
-    '\x06', '\x4c', '\xbc', '\x72', '\x66', '\x70', '\x94', '\x16', '\x8d',
-    '\x1f', '\x78', '\x65', '\x6a', '\x66', '\x07', '\x1f', '\x74', '\x42',
-    '\x6e', '\xf6', '\x7e', '\xdc', '\x03', '\xd3', '\x88', '\xb4', '\x4b',
-    '\x2c', '\x5c', '\x3c', '\x42', '\x59', '\x42', '\x1f', '\x01', '\x13',
-    '\x31', '\xc5', '\x22', '\xe7', '\x6a', '\x96', '\xf2', '\xfb', '\x66',
-    '\xfe', '\xc8', '\xa1', '\x7e', '\x24', '\x96', '\x5f', '\x02', '\xee',
-    '\x38', '\x21', '\xa5', '\x14', '\xd2', '\xa6', '\x35', '\x70', '\x6c',
-    '\x8d', '\xa6', '\xd8', '\x2a', '\xd2', '\x45', '\x31', '\x5f', '\x67',
-    '\x9e', '\x35', '\x57', '\x6a', '\xc4', '\x15', '\xe7', '\xba', '\x60',
-    '\x2f', '\x8e', '\x52', '\x4e', '\xfc', '\x6f', '\xa0', '\x08', '\x91',
-    '\x31', '\x71', '\x06', '\x68', '\x19', '\x48', '\xc7', '\x81', '\x0d',
-    '\x5e', '\x52', '\x93', '\x57', '\xcc', '\xfe', '\x46', '\xac', '\xa9',
-    '\x4f', '\xe2', '\x96', '\x4f', '\xaf', '\x12', '\xfb', '\xc2', '\x4b',
-    '\xc4', '\x8d', '\x3b', '\xb0', '\x38', '\xe4', '\xbb', '\x8d', '\x19',
-    '\x81', '\xe4', '\x74', '\x63', '\x9c', '\x8d', '\xaa', '\x84', '\x82',
-    '\x91', '\xdf', '\xdc', '\x45', '\xf0', '\x39', '\xb2', '\xb4', '\xac',
-    '\x45', '\xda', '\x3f', '\x30', '\x4d', '\x46', '\xb1', '\xe1', '\xb2',
-    '\x9d', '\xdf', '\xd8', '\xc4', '\xa2', '\xef', '\xe9', '\x1a', '\x97',
-    '\x79', '\x02', '\x81', '\x81', '\x00', '\xe5', '\x23', '\xb8', '\xd7',
-    '\x09', '\x54', '\x54', '\x3b', '\xb6', '\x78', '\x78', '\x67', '\x57',
-    '\x65', '\xc5', '\xd4', '\x74', '\xaf', '\x05', '\x4f', '\xb5', '\xc8',
-    '\x8c', '\x1b', '\xd1', '\x9a', '\x2c', '\xd6', '\xe4', '\x68', '\xd1',
-    '\xaf', '\x3d', '\x72', '\x42', '\x50', '\xc8', '\xdd', '\xb1', '\xee',
-    '\x77', '\x52', '\xb8', '\xb1', '\x31', '\xbe', '\xf0', '\x74', '\x78',
-    '\x42', '\x59', '\xea', '\x13', '\x8b', '\x82', '\x00', '\x54', '\x22',
-    '\xd2', '\x0a', '\x24', '\xb0', '\x1f', '\x1e', '\x76', '\x27', '\xae',
-    '\x63', '\xc6', '\x6b', '\x59', '\x28', '\x1d', '\xa0', '\x9f', '\x42',
-    '\x30', '\xf1', '\xe3', '\x59', '\x1c', '\x4f', '\x31', '\x49', '\xff',
-    '\x45', '\x7e', '\x6b', '\xef', '\xe9', '\x6f', '\xde', '\xaf', '\x1e',
-    '\x04', '\x96', '\x61', '\x4e', '\x9f', '\x58', '\xf5', '\x0d', '\x64',
-    '\x08', '\x48', '\x0a', '\xae', '\xac', '\xe4', '\x76', '\x91', '\xdd',
-    '\x6e', '\x33', '\x97', '\xc5', '\x96', '\xda', '\xff', '\xbc', '\x42',
-    '\x5b', '\x71', '\xb5', '\x76', '\xae', '\x01', '\xb3', '\x02', '\x81',
-    '\x81', '\x00', '\xdd', '\x14', '\xa5', '\x6c', '\x89', '\x2b', '\x80',
-    '\x78', '\xf6', '\xc3', '\x80', '\x4d', '\x53', '\x54', '\xb3', '\x2b',
-    '\x40', '\xce', '\x98', '\x16', '\xa0', '\xbf', '\x72', '\xf1', '\xe3',
-    '\xdc', '\xe9', '\x0b', '\x45', '\x23', '\x86', '\x38', '\x4c', '\x29',
-    '\xf1', '\xa0', '\xe0', '\x2c', '\xfa', '\x86', '\x3f', '\x01', '\x90',
-    '\xc5', '\x1b', '\x96', '\x10', '\x44', '\x84', '\xfb', '\xec', '\x3c',
-    '\x74', '\x6c', '\x0d', '\xcc', '\xc3', '\xcd', '\x1b', '\x28', '\x12',
-    '\xaa', '\xb4', '\x67', '\x80', '\xc8', '\xd9', '\x1b', '\x7d', '\xe7',
-    '\x54', '\x39', '\x03', '\x6d', '\xba', '\xaa', '\x6f', '\xf7', '\x93',
-    '\x1f', '\x94', '\x76', '\xd6', '\xab', '\x9b', '\xda', '\x3d', '\x89',
-    '\x37', '\x83', '\xfe', '\x72', '\x2a', '\xbb', '\x6f', '\x36', '\xc5',
-    '\xe0', '\xae', '\x65', '\xf9', '\xbb', '\xc6', '\xe2', '\x98', '\x0f',
-    '\xbd', '\xf6', '\x22', '\xf8', '\x35', '\x5b', '\x99', '\xe6', '\xff',
-    '\x6d', '\x6e', '\xb2', '\x92', '\x93', '\x64', '\x25', '\xc1', '\xe8',
-    '\x9c', '\x6b', '\x73', '\x2b', '\x02', '\x81', '\x80', '\x13', '\x30',
-    '\x1a', '\x9a', '\x67', '\x3d', '\x98', '\x90', '\x27', '\x87', '\x8f',
-    '\x0d', '\x98', '\x53', '\xfd', '\x6c', '\xfd', '\x18', '\x6a', '\xe9',
-    '\x71', '\xdf', '\x89', '\x5c', '\x0b', '\x01', '\x4e', '\x1f', '\xf0',
-    '\xa0', '\x96', '\x6e', '\x86', '\x46', '\xbb', '\x26', '\xe8', '\xab',
-    '\x27', '\xeb', '\x40', '\x32', '\xbd', '\x24', '\x99', '\x75', '\xd3',
-    '\xcc', '\xed', '\x05', '\x21', '\x62', '\x68', '\xa0', '\x96', '\x12',
-    '\x50', '\xf9', '\x59', '\x7d', '\x5f', '\xf5', '\x1f', '\xa5', '\xfd',
-    '\x5e', '\xf5', '\x4b', '\x85', '\xa2', '\x17', '\xa5', '\x34', '\x55',
-    '\xef', '\x00', '\x2b', '\xf9', '\x15', '\x80', '\xb0', '\xce', '\x30',
-    '\xe2', '\x71', '\x6d', '\xf0', '\x58', '\x39', '\x8e', '\xe2', '\xbf',
-    '\x53', '\x0a', '\xc0', '\x77', '\x97', '\x4e', '\x6e', '\x29', '\x94',
-    '\xdb', '\xba', '\x34', '\xb7', '\x53', '\xad', '\xac', '\xec', '\xb4',
-    '\xc1', '\x22', '\x39', '\xc8', '\x38', '\x3d', '\x63', '\x94', '\x93',
-    '\x35', '\xc0', '\x98', '\xc7', '\xbc', '\xda', '\x63', '\x57', '\xe1',
-    '\x02', '\x81', '\x80', '\x51', '\x71', '\x7c', '\xab', '\x6a', '\x30',
-    '\xe3', '\x68', '\x2c', '\x87', '\xc2', '\xe9', '\x39', '\x8c', '\x97',
-    '\x60', '\x94', '\xc4', '\x46', '\xd4', '\xf7', '\x2c', '\xf0', '\x1c',
-    '\x5a', '\x34', '\x14', '\x89', '\xf9', '\x53', '\x67', '\xeb', '\xaf',
-    '\x6b', '\x38', '\x3f', '\x6a', '\xb6', '\x47', '\x28', '\x53', '\x67',
-    '\xb1', '\x3c', '\x5b', '\xb8', '\x41', '\x8f', '\xec', '\x69', '\x9e',
-    '\x12', '\x7b', '\x55', '\x1f', '\x14', '\x53', '\x01', '\x69', '\x42',
-    '\xae', '\xf5', '\xc1', '\xf5', '\xeb', '\x44', '\x92', '\x6e', '\x85',
-    '\x48', '\x46', '\x07', '\xa6', '\xd2', '\xb2', '\x94', '\x7d', '\x20',
-    '\xf8', '\x4b', '\x06', '\xf7', '\x6c', '\x87', '\xd5', '\xa7', '\x65',
-    '\x49', '\xfa', '\x70', '\x9e', '\xb8', '\xd2', '\x33', '\x30', '\x7a',
-    '\x3e', '\x15', '\x52', '\x49', '\xf0', '\xe1', '\x13', '\x18', '\x80',
-    '\xaa', '\x33', '\xf1', '\xcb', '\xda', '\x22', '\x55', '\xf7', '\x71',
-    '\x58', '\xa1', '\xa8', '\xc9', '\x12', '\x24', '\x48', '\x1d', '\x7c',
-    '\xbc', '\xc3', '\x7a', '\xf5', '\xf7', '\x02', '\x81', '\x80', '\x41',
-    '\x7c', '\xae', '\x6e', '\x48', '\x3f', '\xb5', '\x0b', '\x99', '\xaa',
-    '\xc5', '\xea', '\x81', '\xad', '\x84', '\x6b', '\x29', '\x78', '\x4b',
-    '\x18', '\xdb', '\x0e', '\xd3', '\x3e', '\x60', '\x8b', '\xef', '\x65',
-    '\x4d', '\x58', '\x25', '\x3a', '\x08', '\xb5', '\x21', '\xb6', '\x61',
-    '\x0c', '\xfa', '\xf0', '\x69', '\x78', '\x4e', '\x68', '\x36', '\xdb',
-    '\x41', '\x4b', '\x50', '\xd8', '\xd3', '\x8e', '\x3d', '\x74', '\x80',
-    '\x8e', '\xa0', '\xe6', '\xda', '\xec', '\x70', '\x89', '\x77', '\xb2',
-    '\x9d', '\xd6', '\x6e', '\x0a', '\xc4', '\xbd', '\xf6', '\x9a', '\x07',
-    '\x15', '\xba', '\x55', '\x9f', '\xd4', '\x4d', '\x3a', '\x0f', '\x51',
-    '\x12', '\xa4', '\xd9', '\xc2', '\x98', '\x76', '\xc5', '\xb7', '\x29',
-    '\x40', '\xca', '\xf4', '\xbb', '\x74', '\x2d', '\x71', '\x03', '\x4d',
-    '\xe7', '\x05', '\x75', '\xc0', '\x8d', '\x96', '\x7e', '\x59', '\xa1',
-    '\x8b', '\x3b', '\xa3', '\x2b', '\xa5', '\xa3', '\xc8', '\xf7', '\xd3',
-    '\x3e', '\x6b', '\x2e', '\xfa', '\x4f', '\x4d', '\xe6', '\xbe', '\xd3',
-    '\x59'};
-
-ABSL_CONST_INIT const absl::string_view kTestCertificatePrivateKey(
-    kTestCertificatePrivateKeyRaw,
-    sizeof(kTestCertificatePrivateKeyRaw));
-
-ABSL_CONST_INIT const char kTestCertificatePrivateKeyPem[] =
-    R"(-----BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDF4lFtP9Yo8q00
-c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
-wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
-XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
-UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
-a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
-vsbjzrIRAgMBAAECggEAOXWsG0MMFrvQ24goanXkPI8t2G/B+/HJMsK5YLO1fFVy
-lkNOi544K38823PCgiHybss2BJuVbaxbW71QaRZZ/ys4BMovyJN+J/MBfkCBvwcL
-H1sdkn4iwww9Ir7DBky8cmZwlBaNH3hlamYHH3RCbvZ+3APTiLRLLFw8QllCHwET
-McUi52qW8vtm/sihfiSWXwLuOCGlFNKmNXBsjabYKtJFMV9nnjVXasQV57pgL45S
-TvxvoAiRMXEGaBlIx4ENXlKTV8z+RqypT+KWT68S+8JLxI07sDjku40ZgeR0Y5yN
-qoSCkd/cRfA5srSsRdo/ME1GseGynd/YxKLv6RqXeQKBgQDlI7jXCVRUO7Z4eGdX
-ZcXUdK8FT7XIjBvRmizW5GjRrz1yQlDI3bHud1K4sTG+8HR4QlnqE4uCAFQi0gok
-sB8edieuY8ZrWSgdoJ9CMPHjWRxPMUn/RX5r7+lv3q8eBJZhTp9Y9Q1kCEgKrqzk
-dpHdbjOXxZba/7xCW3G1dq4BswKBgQDdFKVsiSuAePbDgE1TVLMrQM6YFqC/cvHj
-3OkLRSOGOEwp8aDgLPqGPwGQxRuWEESE++w8dGwNzMPNGygSqrRngMjZG33nVDkD
-bbqqb/eTH5R21qub2j2JN4P+ciq7bzbF4K5l+bvG4pgPvfYi+DVbmeb/bW6ykpNk
-JcHonGtzKwKBgBMwGppnPZiQJ4ePDZhT/Wz9GGrpcd+JXAsBTh/woJZuhka7Juir
-J+tAMr0kmXXTzO0FIWJooJYSUPlZfV/1H6X9XvVLhaIXpTRV7wAr+RWAsM4w4nFt
-8Fg5juK/UwrAd5dObimU27o0t1OtrOy0wSI5yDg9Y5STNcCYx7zaY1fhAoGAUXF8
-q2ow42gsh8LpOYyXYJTERtT3LPAcWjQUiflTZ+uvazg/arZHKFNnsTxbuEGP7Gme
-EntVHxRTAWlCrvXB9etEkm6FSEYHptKylH0g+EsG92yH1adlSfpwnrjSMzB6PhVS
-SfDhExiAqjPxy9oiVfdxWKGoyRIkSB18vMN69fcCgYBBfK5uSD+1C5mqxeqBrYRr
-KXhLGNsO0z5gi+9lTVglOgi1IbZhDPrwaXhOaDbbQUtQ2NOOPXSAjqDm2uxwiXey
-ndZuCsS99poHFbpVn9RNOg9REqTZwph2xbcpQMr0u3QtcQNN5wV1wI2Wflmhizuj
-K6WjyPfTPmsu+k9N5r7TWQ==
------END PRIVATE KEY-----)";
-
-// The legacy version was manually generated from the one above using der2ascii.
-ABSL_CONST_INIT const char kTestCertificatePrivateKeyLegacyPem[] =
-    R"(-----BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAxeJRbT/WKPKtNHOHZMozGTO3dZGrMRkr46QmCSmLLfdSdadVFfARx8LE7Rgb
-MwtxMuY1ic0tWgVXTsJ4dWVyLYoXg9YykIX4IuJlqeCg/hmyOS0UAxAvzIteqiUnDaM3EAwX7PCL
-xWvta16y4jU+Rjv39lmx4Bam+wO/hE/OZBUNWZmm8H+KM0u7C7jy0SeQjzj4WkGCB5sN2VLgcP/e
-2tglTi8tn6+SY8dCtNwWlSMFAmuw6MX+FZrofS/cQ/RwkRqTvnGvhYTbz2tcgLLT80JuJOwqYpnG
-POUy5XI3MJsL5Aa0ZCaVWbrxU4M9mW3wgOLbazRSBnc8c77G486yEQIDAQABAoIBADl1rBtDDBa7
-0NuIKGp15DyPLdhvwfvxyTLCuWCztXxVcpZDToueOCt/PNtzwoIh8m7LNgSblW2sW1u9UGkWWf8r
-OATKL8iTfifzAX5Agb8HCx9bHZJ+IsMMPSK+wwZMvHJmcJQWjR94ZWpmBx90Qm72ftwD04i0Syxc
-PEJZQh8BEzHFIudqlvL7Zv7IoX4kll8C7jghpRTSpjVwbI2m2CrSRTFfZ541V2rEFee6YC+OUk78
-b6AIkTFxBmgZSMeBDV5Sk1fM/kasqU/ilk+vEvvCS8SNO7A45LuNGYHkdGOcjaqEgpHf3EXwObK0
-rEXaPzBNRrHhsp3f2MSi7+kal3kCgYEA5SO41wlUVDu2eHhnV2XF1HSvBU+1yIwb0Zos1uRo0a89
-ckJQyN2x7ndSuLExvvB0eEJZ6hOLggBUItIKJLAfHnYnrmPGa1koHaCfQjDx41kcTzFJ/0V+a+/p
-b96vHgSWYU6fWPUNZAhICq6s5HaR3W4zl8WW2v+8QltxtXauAbMCgYEA3RSlbIkrgHj2w4BNU1Sz
-K0DOmBagv3Lx49zpC0UjhjhMKfGg4Cz6hj8BkMUblhBEhPvsPHRsDczDzRsoEqq0Z4DI2Rt951Q5
-A226qm/3kx+Udtarm9o9iTeD/nIqu282xeCuZfm7xuKYD732Ivg1W5nm/21uspKTZCXB6JxrcysC
-gYATMBqaZz2YkCeHjw2YU/1s/Rhq6XHfiVwLAU4f8KCWboZGuyboqyfrQDK9JJl108ztBSFiaKCW
-ElD5WX1f9R+l/V71S4WiF6U0Ve8AK/kVgLDOMOJxbfBYOY7iv1MKwHeXTm4plNu6NLdTrazstMEi
-Ocg4PWOUkzXAmMe82mNX4QKBgFFxfKtqMONoLIfC6TmMl2CUxEbU9yzwHFo0FIn5U2frr2s4P2q2
-RyhTZ7E8W7hBj+xpnhJ7VR8UUwFpQq71wfXrRJJuhUhGB6bSspR9IPhLBvdsh9WnZUn6cJ640jMw
-ej4VUknw4RMYgKoz8cvaIlX3cVihqMkSJEgdfLzDevX3AoGAQXyubkg/tQuZqsXqga2Eayl4Sxjb
-DtM+YIvvZU1YJToItSG2YQz68Gl4Tmg220FLUNjTjj10gI6g5trscIl3sp3WbgrEvfaaBxW6VZ/U
-TToPURKk2cKYdsW3KUDK9Lt0LXEDTecFdcCNln5ZoYs7oyulo8j30z5rLvpPTea+01k=
------END RSA PRIVATE KEY-----)";
-
-ABSL_CONST_INIT const char kWildcardCertificateRaw[] = {
-    '\x30', '\x82', '\x03', '\x5f', '\x30', '\x82', '\x02', '\x47', '\xa0',
-    '\x03', '\x02', '\x01', '\x02', '\x02', '\x14', '\x36', '\x1d', '\xe3',
-    '\xd2', '\x39', '\x35', '\x20', '\xb1', '\xae', '\x18', '\xdd', '\x71',
-    '\xc9', '\x5b', '\x4a', '\x17', '\xbe', '\x00', '\xb4', '\x15', '\x30',
-    '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d',
-    '\x01', '\x01', '\x0b', '\x05', '\x00', '\x30', '\x24', '\x31', '\x0b',
-    '\x30', '\x09', '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02',
-    '\x55', '\x53', '\x31', '\x15', '\x30', '\x13', '\x06', '\x03', '\x55',
-    '\x04', '\x03', '\x0c', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66',
-    '\x6f', '\x6f', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x1e',
-    '\x17', '\x0d', '\x32', '\x30', '\x30', '\x34', '\x32', '\x31', '\x30',
-    '\x32', '\x31', '\x38', '\x34', '\x35', '\x5a', '\x17', '\x0d', '\x32',
-    '\x31', '\x30', '\x34', '\x32', '\x31', '\x30', '\x32', '\x31', '\x38',
-    '\x34', '\x35', '\x5a', '\x30', '\x24', '\x31', '\x0b', '\x30', '\x09',
-    '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02', '\x55', '\x53',
-    '\x31', '\x15', '\x30', '\x13', '\x06', '\x03', '\x55', '\x04', '\x03',
-    '\x0c', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66', '\x6f', '\x6f',
-    '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x82', '\x01', '\x22',
-    '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7',
-    '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00', '\x03', '\x82', '\x01',
-    '\x0f', '\x00', '\x30', '\x82', '\x01', '\x0a', '\x02', '\x82', '\x01',
-    '\x01', '\x00', '\xcc', '\xd5', '\x5d', '\xa0', '\x4a', '\x03', '\x9d',
-    '\x89', '\xa2', '\xae', '\x7a', '\x59', '\x15', '\xf7', '\x27', '\x67',
-    '\x49', '\xa4', '\xc1', '\x87', '\xcd', '\x9c', '\x02', '\x9e', '\xb9',
-    '\x2f', '\xd1', '\xa1', '\x0d', '\x57', '\xff', '\xd6', '\xc0', '\x6a',
-    '\x7b', '\xaa', '\x52', '\xb2', '\x6e', '\xa6', '\x12', '\x34', '\xcf',
-    '\xdc', '\xd3', '\x1e', '\x32', '\xc1', '\x8d', '\x42', '\xa3', '\x0b',
-    '\xd6', '\xaf', '\xe9', '\x37', '\x42', '\xf8', '\x78', '\xdc', '\xcb',
-    '\x2d', '\x0e', '\x42', '\x5a', '\xe2', '\xbf', '\xd2', '\xe4', '\x9c',
-    '\xb4', '\x34', '\x38', '\x97', '\x5e', '\x4d', '\x5e', '\x8a', '\x0b',
-    '\xd8', '\x42', '\x11', '\x88', '\x19', '\xa2', '\x23', '\x4b', '\xec',
-    '\x3b', '\x0a', '\xc9', '\x67', '\x49', '\x2c', '\x8e', '\x1c', '\x5e',
-    '\x7f', '\x42', '\xe7', '\x73', '\x0b', '\x86', '\x68', '\xf0', '\xaa',
-    '\x3f', '\x1e', '\x17', '\x3e', '\x29', '\xc4', '\x57', '\x6e', '\x34',
-    '\x78', '\xaf', '\x15', '\x03', '\x39', '\x32', '\x27', '\x80', '\x76',
-    '\xb1', '\xda', '\x08', '\xe5', '\x4d', '\x3f', '\x4c', '\xfc', '\x1e',
-    '\x23', '\x5a', '\xb3', '\xd4', '\x99', '\xdc', '\x5c', '\x2b', '\xf1',
-    '\xa8', '\xe3', '\x02', '\x0a', '\xc8', '\x4d', '\x63', '\x27', '\xb9',
-    '\x0d', '\x6c', '\xc2', '\x34', '\x82', '\x82', '\x5d', '\x56', '\xa8',
-    '\x93', '\x44', '\x8b', '\xf4', '\x8b', '\xf0', '\x63', '\xe5', '\x23',
-    '\x7f', '\x8d', '\x5f', '\x3a', '\x4a', '\xa5', '\x50', '\xb9', '\xc6',
-    '\x5c', '\xe6', '\x33', '\xe3', '\xfc', '\xc8', '\x96', '\x88', '\x88',
-    '\xe9', '\x53', '\xaf', '\x0d', '\xbb', '\x80', '\x9c', '\xbb', '\xed',
-    '\x4d', '\x06', '\xfa', '\xe9', '\x7c', '\x25', '\x1c', '\x59', '\xee',
-    '\x19', '\xcc', '\xa9', '\x7c', '\x1d', '\x86', '\xd9', '\x95', '\x78',
-    '\x2d', '\x3a', '\x95', '\x49', '\x11', '\x45', '\xfa', '\xd6', '\xef',
-    '\xd5', '\x07', '\x1c', '\x23', '\xeb', '\xad', '\xd3', '\x3b', '\x95',
-    '\xcf', '\x53', '\xa3', '\x47', '\xa9', '\xa7', '\x90', '\xde', '\x34',
-    '\xa4', '\xbb', '\x05', '\xdc', '\x54', '\x87', '\x97', '\x30', '\xea',
-    '\x25', '\xf0', '\xfd', '\xba', '\xa1', '\x1b', '\x02', '\x03', '\x01',
-    '\x00', '\x01', '\xa3', '\x81', '\x88', '\x30', '\x81', '\x85', '\x30',
-    '\x1d', '\x06', '\x03', '\x55', '\x1d', '\x0e', '\x04', '\x16', '\x04',
-    '\x14', '\x09', '\xfb', '\x77', '\xbb', '\xc8', '\x8f', '\xd6', '\xa4',
-    '\xf0', '\x74', '\xb2', '\x90', '\x46', '\x0a', '\x8d', '\x09', '\x4b',
-    '\x89', '\x2e', '\x41', '\x30', '\x1f', '\x06', '\x03', '\x55', '\x1d',
-    '\x23', '\x04', '\x18', '\x30', '\x16', '\x80', '\x14', '\x09', '\xfb',
-    '\x77', '\xbb', '\xc8', '\x8f', '\xd6', '\xa4', '\xf0', '\x74', '\xb2',
-    '\x90', '\x46', '\x0a', '\x8d', '\x09', '\x4b', '\x89', '\x2e', '\x41',
-    '\x30', '\x0f', '\x06', '\x03', '\x55', '\x1d', '\x13', '\x01', '\x01',
-    '\xff', '\x04', '\x05', '\x30', '\x03', '\x01', '\x01', '\xff', '\x30',
-    '\x32', '\x06', '\x03', '\x55', '\x1d', '\x11', '\x04', '\x2b', '\x30',
-    '\x29', '\x82', '\x08', '\x66', '\x6f', '\x6f', '\x2e', '\x74', '\x65',
-    '\x73', '\x74', '\x82', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66',
-    '\x6f', '\x6f', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x82', '\x0f',
-    '\x2a', '\x2e', '\x77', '\x69', '\x6c', '\x64', '\x63', '\x61', '\x72',
-    '\x64', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x0d', '\x06',
-    '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01',
-    '\x0b', '\x05', '\x00', '\x03', '\x82', '\x01', '\x01', '\x00', '\x93',
-    '\xbc', '\x33', '\x4c', '\xa4', '\xdf', '\xdc', '\xed', '\x4b', '\x4d',
-    '\x5e', '\xdb', '\xdd', '\x4a', '\xb7', '\xbc', '\x50', '\x1f', '\xca',
-    '\x66', '\x4d', '\x28', '\x96', '\x42', '\x4e', '\x84', '\x44', '\x80',
-    '\x25', '\x17', '\x2c', '\x05', '\x93', '\xe0', '\x2a', '\x29', '\xef',
-    '\xe4', '\x26', '\x19', '\x63', '\xdf', '\xb2', '\x72', '\xb1', '\x82',
-    '\x7e', '\x5f', '\xce', '\x82', '\x41', '\xad', '\x96', '\x78', '\x94',
-    '\xa8', '\x21', '\xee', '\xf2', '\x4a', '\xf5', '\x41', '\xa8', '\xfb',
-    '\xe0', '\xe1', '\x22', '\x89', '\xf1', '\x40', '\x85', '\x86', '\x53',
-    '\x61', '\x57', '\x0f', '\x31', '\xae', '\x0c', '\xc3', '\x8d', '\xe8',
-    '\x29', '\xac', '\xe0', '\x03', '\x2d', '\x69', '\x44', '\x3d', '\xd6',
-    '\x3b', '\x2b', '\x0f', '\xb3', '\xf5', '\x83', '\x1b', '\x4e', '\x65',
-    '\x60', '\x6b', '\xa2', '\x01', '\x03', '\x1e', '\x98', '\xca', '\xca',
-    '\x32', '\xd4', '\x5b', '\xde', '\x45', '\xe2', '\x35', '\xd2', '\x54',
-    '\x1a', '\x2a', '\x38', '\xa7', '\x42', '\xa0', '\xf3', '\xef', '\x28',
-    '\xe3', '\x6e', '\x23', '\x77', '\x07', '\xd5', '\xef', '\xfd', '\x30',
-    '\xd6', '\x31', '\xfa', '\xf2', '\x94', '\x95', '\x2f', '\x03', '\x7a',
-    '\x43', '\xe0', '\xb3', '\x82', '\xca', '\x7e', '\xb4', '\x00', '\xc9',
-    '\x08', '\x15', '\x7b', '\x2e', '\x51', '\xec', '\xab', '\x68', '\xca',
-    '\xc2', '\xca', '\x44', '\xe1', '\xbe', '\xe4', '\x06', '\x98', '\x87',
-    '\x9b', '\x58', '\xbc', '\xf1', '\xea', '\x55', '\xf6', '\x64', '\x92',
-    '\xe6', '\x73', '\xc9', '\xf6', '\xc5', '\x7a', '\x90', '\x42', '\x83',
-    '\x39', '\x9e', '\xd0', '\xca', '\x85', '\x6c', '\x53', '\x99', '\x64',
-    '\xbb', '\x49', '\xdc', '\xae', '\x1c', '\xe5', '\x00', '\x65', '\x13',
-    '\xdd', '\xdc', '\xde', '\x3f', '\xf9', '\x14', '\x91', '\x0d', '\xe6',
-    '\xba', '\xc1', '\x7d', '\x5f', '\xd5', '\x6d', '\xe8', '\x65', '\x9c',
-    '\xfb', '\xda', '\x82', '\xf7', '\x4d', '\x45', '\x81', '\x8c', '\x54',
-    '\xec', '\x50', '\xbb', '\x14', '\xe9', '\x06', '\xda', '\x76', '\xb3',
-    '\xf0', '\xb7', '\xbb', '\x58', '\x4c', '\x8f', '\x6a', '\x5d', '\x8e',
-    '\x93', '\x5f', '\x35'};
-
-ABSL_CONST_INIT const absl::string_view kWildcardCertificate(
-    kWildcardCertificateRaw,
-    sizeof(kWildcardCertificateRaw));
-
-ABSL_CONST_INIT const char kWildcardCertificatePrivateKeyRaw[] = {
-    '\x30', '\x82', '\x04', '\xbe', '\x02', '\x01', '\x00', '\x30', '\x0d',
-    '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
-    '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa8', '\x30',
-    '\x82', '\x04', '\xa4', '\x02', '\x01', '\x00', '\x02', '\x82', '\x01',
-    '\x01', '\x00', '\xcc', '\xd5', '\x5d', '\xa0', '\x4a', '\x03', '\x9d',
-    '\x89', '\xa2', '\xae', '\x7a', '\x59', '\x15', '\xf7', '\x27', '\x67',
-    '\x49', '\xa4', '\xc1', '\x87', '\xcd', '\x9c', '\x02', '\x9e', '\xb9',
-    '\x2f', '\xd1', '\xa1', '\x0d', '\x57', '\xff', '\xd6', '\xc0', '\x6a',
-    '\x7b', '\xaa', '\x52', '\xb2', '\x6e', '\xa6', '\x12', '\x34', '\xcf',
-    '\xdc', '\xd3', '\x1e', '\x32', '\xc1', '\x8d', '\x42', '\xa3', '\x0b',
-    '\xd6', '\xaf', '\xe9', '\x37', '\x42', '\xf8', '\x78', '\xdc', '\xcb',
-    '\x2d', '\x0e', '\x42', '\x5a', '\xe2', '\xbf', '\xd2', '\xe4', '\x9c',
-    '\xb4', '\x34', '\x38', '\x97', '\x5e', '\x4d', '\x5e', '\x8a', '\x0b',
-    '\xd8', '\x42', '\x11', '\x88', '\x19', '\xa2', '\x23', '\x4b', '\xec',
-    '\x3b', '\x0a', '\xc9', '\x67', '\x49', '\x2c', '\x8e', '\x1c', '\x5e',
-    '\x7f', '\x42', '\xe7', '\x73', '\x0b', '\x86', '\x68', '\xf0', '\xaa',
-    '\x3f', '\x1e', '\x17', '\x3e', '\x29', '\xc4', '\x57', '\x6e', '\x34',
-    '\x78', '\xaf', '\x15', '\x03', '\x39', '\x32', '\x27', '\x80', '\x76',
-    '\xb1', '\xda', '\x08', '\xe5', '\x4d', '\x3f', '\x4c', '\xfc', '\x1e',
-    '\x23', '\x5a', '\xb3', '\xd4', '\x99', '\xdc', '\x5c', '\x2b', '\xf1',
-    '\xa8', '\xe3', '\x02', '\x0a', '\xc8', '\x4d', '\x63', '\x27', '\xb9',
-    '\x0d', '\x6c', '\xc2', '\x34', '\x82', '\x82', '\x5d', '\x56', '\xa8',
-    '\x93', '\x44', '\x8b', '\xf4', '\x8b', '\xf0', '\x63', '\xe5', '\x23',
-    '\x7f', '\x8d', '\x5f', '\x3a', '\x4a', '\xa5', '\x50', '\xb9', '\xc6',
-    '\x5c', '\xe6', '\x33', '\xe3', '\xfc', '\xc8', '\x96', '\x88', '\x88',
-    '\xe9', '\x53', '\xaf', '\x0d', '\xbb', '\x80', '\x9c', '\xbb', '\xed',
-    '\x4d', '\x06', '\xfa', '\xe9', '\x7c', '\x25', '\x1c', '\x59', '\xee',
-    '\x19', '\xcc', '\xa9', '\x7c', '\x1d', '\x86', '\xd9', '\x95', '\x78',
-    '\x2d', '\x3a', '\x95', '\x49', '\x11', '\x45', '\xfa', '\xd6', '\xef',
-    '\xd5', '\x07', '\x1c', '\x23', '\xeb', '\xad', '\xd3', '\x3b', '\x95',
-    '\xcf', '\x53', '\xa3', '\x47', '\xa9', '\xa7', '\x90', '\xde', '\x34',
-    '\xa4', '\xbb', '\x05', '\xdc', '\x54', '\x87', '\x97', '\x30', '\xea',
-    '\x25', '\xf0', '\xfd', '\xba', '\xa1', '\x1b', '\x02', '\x03', '\x01',
-    '\x00', '\x01', '\x02', '\x82', '\x01', '\x01', '\x00', '\xa3', '\xb3',
-    '\x01', '\x98', '\x50', '\x8e', '\x83', '\x20', '\xb4', '\x3a', '\xec',
-    '\xdc', '\xb5', '\x89', '\x48', '\x9c', '\x6b', '\x66', '\x98', '\xa4',
-    '\x87', '\xd5', '\xde', '\xe2', '\x2a', '\xed', '\xe4', '\x82', '\xe9',
-    '\xbf', '\x22', '\x5f', '\xe6', '\x77', '\x33', '\x4d', '\xf3', '\xb9',
-    '\x56', '\x64', '\xb2', '\xb8', '\x32', '\x47', '\x31', '\x12', '\x39',
-    '\x4e', '\x26', '\x2e', '\xd3', '\x4f', '\x6a', '\xcc', '\x3b', '\x7e',
-    '\x46', '\xaf', '\x7d', '\x28', '\x37', '\xd8', '\x52', '\x45', '\x05',
-    '\x8d', '\xa1', '\xf0', '\x51', '\x74', '\x4b', '\x30', '\x50', '\xe9',
-    '\xe8', '\x1b', '\xbd', '\x2a', '\x66', '\x3c', '\xf6', '\xd0', '\x3c',
-    '\x0d', '\x00', '\x5f', '\x65', '\x15', '\xee', '\x39', '\xb8', '\xac',
-    '\x2a', '\xf6', '\xc8', '\xbc', '\x33', '\x69', '\x51', '\x76', '\xd7',
-    '\xa2', '\xa6', '\x50', '\xc7', '\xc5', '\xc7', '\x9b', '\xac', '\xc7',
-    '\xa9', '\x69', '\x98', '\xd6', '\x22', '\x69', '\x30', '\xc3', '\x82',
-    '\x47', '\xfb', '\xa5', '\x46', '\x2d', '\x96', '\x05', '\xc2', '\x84',
-    '\xd1', '\x1d', '\xd5', '\xa7', '\x5c', '\xdb', '\x6d', '\x35', '\x7b',
-    '\x1b', '\x80', '\xe4', '\x42', '\x1f', '\x4d', '\x68', '\x2e', '\xbc',
-    '\x58', '\xb6', '\x7c', '\x7e', '\xc5', '\x07', '\xe1', '\xf5', '\x30',
-    '\xa9', '\x8f', '\x14', '\x76', '\xad', '\xe2', '\xdf', '\xaf', '\xd3',
-    '\xf1', '\xba', '\xd5', '\x98', '\xf3', '\x5e', '\x30', '\x79', '\xcb',
-    '\xe7', '\x7a', '\x83', '\xba', '\xf7', '\x71', '\xb0', '\xb2', '\xd1',
-    '\xf4', '\x34', '\x5b', '\xe1', '\xe8', '\x60', '\x39', '\x96', '\x12',
-    '\xdc', '\xb4', '\x0d', '\xf9', '\x8d', '\x8c', '\xd8', '\xbb', '\xb7',
-    '\xd2', '\x1b', '\x83', '\x10', '\xbd', '\x86', '\xef', '\x5c', '\x6c',
-    '\xe3', '\xb1', '\x96', '\x7f', '\xab', '\x58', '\xce', '\x87', '\xc9',
-    '\x48', '\x69', '\xbb', '\xb1', '\xec', '\xa4', '\x3a', '\x06', '\xa3',
-    '\x33', '\xad', '\x7a', '\xe5', '\x88', '\x6d', '\x32', '\x67', '\x1c',
-    '\x03', '\xda', '\x9d', '\x3c', '\x73', '\xe0', '\xd7', '\x6c', '\x00',
-    '\xe4', '\x8d', '\x7d', '\xf2', '\xac', '\xa5', '\xb8', '\x35', '\xb9',
-    '\xac', '\x81', '\x02', '\x81', '\x81', '\x00', '\xe8', '\xd5', '\x5b',
-    '\xd0', '\x4f', '\x7c', '\xfc', '\x4b', '\xe6', '\xe8', '\x3c', '\x4c',
-    '\x24', '\xce', '\x68', '\x73', '\x3b', '\x4b', '\xa0', '\xfb', '\x79',
-    '\xa5', '\x72', '\x1d', '\x77', '\xb2', '\xdf', '\x2b', '\x0a', '\x11',
-    '\x28', '\xe8', '\x02', '\x7f', '\x26', '\x40', '\x34', '\x8f', '\x78',
-    '\x18', '\xad', '\xf4', '\x11', '\x78', '\x45', '\x9f', '\x66', '\x4e',
-    '\x78', '\x71', '\x60', '\x40', '\xeb', '\x64', '\x28', '\x06', '\xae',
-    '\x9b', '\x32', '\x73', '\xb5', '\xe1', '\x7e', '\x3c', '\x07', '\x31',
-    '\x8d', '\x82', '\xed', '\x6a', '\xe6', '\x1e', '\x65', '\x9e', '\x81',
-    '\x29', '\x08', '\x56', '\x17', '\x4b', '\x31', '\xc3', '\xf5', '\x27',
-    '\xef', '\xb8', '\xda', '\x58', '\xff', '\x36', '\x47', '\x12', '\xb0',
-    '\xef', '\x14', '\x20', '\x5c', '\x48', '\xb3', '\x84', '\x0d', '\x64',
-    '\x22', '\x3e', '\xfe', '\x94', '\x17', '\x6c', '\x45', '\xe7', '\x3f',
-    '\x4c', '\x90', '\x67', '\x13', '\x1a', '\xa8', '\xbc', '\x5b', '\xd0',
-    '\xc1', '\x8a', '\xa9', '\x42', '\xbe', '\xe4', '\x0e', '\x59', '\x02',
-    '\x81', '\x81', '\x00', '\xe1', '\x36', '\xcd', '\x86', '\x1e', '\xcb',
-    '\x8b', '\x68', '\x65', '\x6b', '\x42', '\xec', '\x50', '\x29', '\xa0',
-    '\xab', '\x3a', '\xe5', '\x6f', '\xe1', '\x13', '\xe8', '\xa3', '\x6b',
-    '\x7c', '\x2b', '\xd3', '\x69', '\x89', '\x47', '\x07', '\x39', '\xb2',
-    '\x0f', '\x03', '\x4e', '\x6f', '\x28', '\x94', '\x1d', '\x1f', '\x22',
-    '\x47', '\xf9', '\x95', '\xff', '\x3e', '\xa4', '\x26', '\x38', '\x07',
-    '\x5b', '\xdd', '\xef', '\x0a', '\xa5', '\xe8', '\x99', '\xad', '\x91',
-    '\x68', '\x83', '\xf2', '\xf5', '\xa5', '\x3d', '\x21', '\x88', '\xa5',
-    '\x6a', '\x39', '\x3b', '\xca', '\x4c', '\xc9', '\xd1', '\x9a', '\x74',
-    '\xb2', '\xe3', '\x73', '\x5d', '\xfe', '\xbd', '\x05', '\x1b', '\x9a',
-    '\x13', '\x98', '\x39', '\x93', '\xf3', '\x88', '\x55', '\x61', '\x85',
-    '\x7a', '\x53', '\x5a', '\xd9', '\x2c', '\xdb', '\x15', '\x69', '\xa6',
-    '\x31', '\x09', '\xbb', '\xd1', '\xe8', '\x6e', '\x8c', '\x47', '\x77',
-    '\x1e', '\x9b', '\xbe', '\xb7', '\x57', '\xd4', '\xaa', '\xd5', '\x92',
-    '\xa1', '\xd5', '\x55', '\x04', '\x93', '\x02', '\x81', '\x80', '\x06',
-    '\x84', '\x01', '\xff', '\xc0', '\x59', '\xb5', '\x0d', '\xc2', '\xb6',
-    '\x79', '\x09', '\x80', '\x76', '\x2e', '\x42', '\x1b', '\x44', '\xb0',
-    '\x8a', '\x99', '\x0a', '\xe2', '\x38', '\xa4', '\xe2', '\xe2', '\x8f',
-    '\xe7', '\xc6', '\x37', '\x28', '\xd6', '\xf9', '\x0b', '\xee', '\xfc',
-    '\x09', '\x8f', '\xc8', '\xd1', '\x05', '\x65', '\x7f', '\xc2', '\x23',
-    '\x05', '\xcf', '\xe8', '\x5a', '\xf3', '\xe0', '\x9d', '\x35', '\xbe',
-    '\x51', '\x01', '\x8d', '\xe2', '\x49', '\x8e', '\xab', '\x72', '\xc6',
-    '\xe7', '\x44', '\xa1', '\xbb', '\x2a', '\x3d', '\xb5', '\x96', '\xe0',
-    '\x2d', '\x21', '\x5c', '\x2e', '\x99', '\x8a', '\x29', '\x56', '\x89',
-    '\x2f', '\x51', '\x20', '\xca', '\x41', '\x82', '\x00', '\x12', '\x5a',
-    '\xc6', '\xd1', '\x20', '\xbf', '\xa5', '\x70', '\x2f', '\xb0', '\xa6',
-    '\x5f', '\x61', '\x8f', '\xfb', '\xc7', '\x50', '\x09', '\x9f', '\xc4',
-    '\x0d', '\x06', '\x9e', '\x73', '\xe4', '\x0e', '\x8a', '\xce', '\x72',
-    '\x06', '\xf7', '\xbe', '\x92', '\xcc', '\xcd', '\xcb', '\x5d', '\xc2',
-    '\x71', '\x02', '\x81', '\x80', '\x26', '\xf3', '\xba', '\x92', '\x52',
-    '\xeb', '\x33', '\x7e', '\x67', '\xe4', '\x28', '\x5c', '\x04', '\xf5',
-    '\x5e', '\x33', '\x9f', '\x69', '\x25', '\x73', '\x91', '\x64', '\xf0',
-    '\x36', '\xdb', '\xf0', '\x1c', '\x8d', '\xa9', '\x4f', '\x9e', '\xa1',
-    '\x4c', '\xf9', '\xa9', '\xc1', '\xbc', '\x1a', '\x11', '\x9c', '\x03',
-    '\xd1', '\x83', '\x0f', '\x58', '\xf1', '\x1f', '\x9d', '\x76', '\x7a',
-    '\xc4', '\x53', '\x10', '\x4c', '\x92', '\xd3', '\xe5', '\x2a', '\x07',
-    '\x4a', '\x1a', '\x00', '\x90', '\x5a', '\x0a', '\x2d', '\x4b', '\x8a',
-    '\x7d', '\xc9', '\xa4', '\x82', '\x81', '\xd7', '\xcc', '\x24', '\x33',
-    '\x89', '\xb1', '\x93', '\x03', '\x56', '\x23', '\x83', '\xff', '\xc9',
-    '\x29', '\x59', '\xf0', '\x3f', '\x2d', '\x26', '\xb6', '\xd2', '\xc5',
-    '\x9e', '\x37', '\x6d', '\x09', '\x4e', '\x7c', '\xa2', '\x9b', '\xce',
-    '\x7d', '\x0f', '\x08', '\x36', '\xf2', '\xf4', '\x37', '\x82', '\x8d',
-    '\xad', '\xbd', '\x9e', '\x84', '\x5a', '\xe3', '\x97', '\x05', '\xc1',
-    '\x10', '\xae', '\x6a', '\xde', '\x5c', '\x7f', '\x02', '\x81', '\x81',
-    '\x00', '\x9b', '\x8e', '\xa4', '\x2b', '\xcf', '\xb6', '\x30', '\x1c',
-    '\xb5', '\x82', '\x50', '\x08', '\xc0', '\x0b', '\x57', '\xf4', '\x2d',
-    '\x82', '\x39', '\x11', '\x1b', '\x02', '\xe6', '\xbe', '\x14', '\x26',
-    '\x77', '\xd7', '\x26', '\x1f', '\x0d', '\x92', '\xc6', '\x67', '\xa0',
-    '\x01', '\x6c', '\xd9', '\x7a', '\xdf', '\xc3', '\x3d', '\x50', '\x8d',
-    '\x43', '\xef', '\x95', '\x50', '\x72', '\x25', '\x06', '\x28', '\x7a',
-    '\x7e', '\x99', '\xea', '\x4d', '\xe8', '\x87', '\xe5', '\xca', '\x71',
-    '\x36', '\x8a', '\xce', '\x18', '\x55', '\xe4', '\x87', '\x39', '\x3d',
-    '\xea', '\x9a', '\x22', '\x99', '\x1a', '\xab', '\xe3', '\x6f', '\x48',
-    '\x78', '\x49', '\x8f', '\xf6', '\xfa', '\xb1', '\xb8', '\x68', '\xae',
-    '\xc3', '\x47', '\x1d', '\x8f', '\x1d', '\x11', '\xa1', '\x06', '\xf5',
-    '\xc0', '\x0d', '\xcf', '\x7b', '\x33', '\xfe', '\x0c', '\x69', '\xca',
-    '\x46', '\xfe', '\x2c', '\xac', '\xd8', '\x4d', '\x02', '\x79', '\xfe',
-    '\x47', '\xca', '\x21', '\x30', '\x65', '\xa4', '\xe5', '\xaa', '\x4e',
-    '\x9c', '\xbc', '\xa5'};
-
-ABSL_CONST_INIT const absl::string_view kWildcardCertificatePrivateKey(
-    kWildcardCertificatePrivateKeyRaw,
-    sizeof(kWildcardCertificatePrivateKeyRaw));
-
-ABSL_CONST_INIT const char kTestEcPrivateKeyLegacyPem[] =
-    R"(-----BEGIN EC PARAMETERS-----
-BggqhkjOPQMBBw==
------END EC PARAMETERS-----
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIMdjXX0hg399DlccZuYFXPKq+dMGduXWmQYClDYJNDGroAoGCCqGSM49
-AwEHoUQDQgAENCuPQTywFI8hbsGo68AeN1KVWmd09buzlu/2CAtsJcNoECUmpVXH
-4dwvWMv6zWn9RJ5EzI72R/5FVcO485s5MQ==
------END EC PRIVATE KEY-----)";
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/test_ticket_crypter.cc b/quic/test_tools/test_ticket_crypter.cc
deleted file mode 100644
index be9021a..0000000
--- a/quic/test_tools/test_ticket_crypter.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/test_ticket_crypter.h"
-
-#include <cstring>
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/quic_random.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-// A TicketCrypter implementation is supposed to encrypt and decrypt session
-// tickets. However, the only requirement that is needed of a test
-// implementation is that calling Decrypt(Encrypt(input), callback) results in
-// callback being called with input. (The output of Encrypt must also not exceed
-// the overhead specified by MaxOverhead.) This test implementation encrypts
-// tickets by prepending kTicketPrefix to generate the ciphertext. The decrypt
-// function checks that the prefix is present and strips it; otherwise it
-// returns an empty vector to signal failure.
-constexpr char kTicketPrefix[] = "TEST TICKET";
-
-}  // namespace
-
-TestTicketCrypter::TestTicketCrypter()
-    : ticket_prefix_(ABSL_ARRAYSIZE(kTicketPrefix) + 16) {
-  memcpy(ticket_prefix_.data(), kTicketPrefix, ABSL_ARRAYSIZE(kTicketPrefix));
-  QuicRandom::GetInstance()->RandBytes(
-      ticket_prefix_.data() + ABSL_ARRAYSIZE(kTicketPrefix), 16);
-}
-
-size_t TestTicketCrypter::MaxOverhead() {
-  return ticket_prefix_.size();
-}
-
-std::vector<uint8_t> TestTicketCrypter::Encrypt(
-    absl::string_view in, absl::string_view /* encryption_key */) {
-  size_t prefix_len = ticket_prefix_.size();
-  std::vector<uint8_t> out(prefix_len + in.size());
-  memcpy(out.data(), ticket_prefix_.data(), prefix_len);
-  memcpy(out.data() + prefix_len, in.data(), in.size());
-  return out;
-}
-
-std::vector<uint8_t> TestTicketCrypter::Decrypt(absl::string_view in) {
-  size_t prefix_len = ticket_prefix_.size();
-  if (fail_decrypt_ || in.size() < prefix_len ||
-      memcmp(ticket_prefix_.data(), in.data(), prefix_len) != 0) {
-    return std::vector<uint8_t>();
-  }
-  return std::vector<uint8_t>(in.begin() + prefix_len, in.end());
-}
-
-void TestTicketCrypter::Decrypt(
-    absl::string_view in,
-    std::unique_ptr<ProofSource::DecryptCallback> callback) {
-  auto decrypted_ticket = Decrypt(in);
-  if (run_async_) {
-    pending_callbacks_.push_back({std::move(callback), decrypted_ticket});
-  } else {
-    callback->Run(decrypted_ticket);
-  }
-}
-
-void TestTicketCrypter::SetRunCallbacksAsync(bool run_async) {
-  run_async_ = run_async;
-}
-
-size_t TestTicketCrypter::NumPendingCallbacks() {
-  return pending_callbacks_.size();
-}
-
-void TestTicketCrypter::RunPendingCallback(size_t n) {
-  const PendingCallback& callback = pending_callbacks_[n];
-  callback.callback->Run(callback.decrypted_ticket);
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/test_ticket_crypter.h b/quic/test_tools/test_ticket_crypter.h
deleted file mode 100644
index 0300998..0000000
--- a/quic/test_tools/test_ticket_crypter.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
-#define QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
-
-#include "quic/core/crypto/proof_source.h"
-
-namespace quic {
-namespace test {
-
-// Provides a simple implementation of ProofSource::TicketCrypter for testing.
-// THIS IMPLEMENTATION IS NOT SECURE. It is only intended for testing purposes.
-class TestTicketCrypter : public ProofSource::TicketCrypter {
- public:
-  TestTicketCrypter();
-  ~TestTicketCrypter() override = default;
-
-  // TicketCrypter interface
-  size_t MaxOverhead() override;
-  std::vector<uint8_t> Encrypt(absl::string_view in,
-                               absl::string_view encryption_key) override;
-  void Decrypt(absl::string_view in,
-               std::unique_ptr<ProofSource::DecryptCallback> callback) override;
-
-  void SetRunCallbacksAsync(bool run_async);
-  size_t NumPendingCallbacks();
-  void RunPendingCallback(size_t n);
-
-  // Allows configuring this TestTicketCrypter to fail decryption.
-  void set_fail_decrypt(bool fail_decrypt) { fail_decrypt_ = fail_decrypt; }
-
- private:
-  // Performs the Decrypt operation synchronously.
-  std::vector<uint8_t> Decrypt(absl::string_view in);
-
-  struct PendingCallback {
-    std::unique_ptr<ProofSource::DecryptCallback> callback;
-    std::vector<uint8_t> decrypted_ticket;
-  };
-
-  bool fail_decrypt_ = false;
-  bool run_async_ = false;
-  std::vector<PendingCallback> pending_callbacks_;
-  std::vector<uint8_t> ticket_prefix_;
-};
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
diff --git a/quic/test_tools/web_transport_resets_backend.cc b/quic/test_tools/web_transport_resets_backend.cc
deleted file mode 100644
index 512619f..0000000
--- a/quic/test_tools/web_transport_resets_backend.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/test_tools/web_transport_resets_backend.h"
-
-#include <memory>
-
-#include "quic/core/web_transport_interface.h"
-#include "quic/tools/web_transport_test_visitors.h"
-#include "common/quiche_circular_deque.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-class ResetsVisitor;
-
-class BidirectionalEchoVisitorWithLogging
-    : public WebTransportBidirectionalEchoVisitor {
- public:
-  BidirectionalEchoVisitorWithLogging(WebTransportStream* stream,
-                                      ResetsVisitor* session_visitor)
-      : WebTransportBidirectionalEchoVisitor(stream),
-        session_visitor_(session_visitor) {}
-
-  void OnResetStreamReceived(WebTransportStreamError error) override;
-  void OnStopSendingReceived(WebTransportStreamError error) override;
-
- private:
-  ResetsVisitor* session_visitor_;  // Not owned.
-};
-
-class ResetsVisitor : public WebTransportVisitor {
- public:
-  ResetsVisitor(WebTransportSession* session) : session_(session) {}
-
-  void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
-  void OnSessionClosed(WebTransportSessionError /*error_code*/,
-                       const std::string& /*error_message*/) override {}
-
-  void OnIncomingBidirectionalStreamAvailable() override {
-    while (true) {
-      WebTransportStream* stream =
-          session_->AcceptIncomingBidirectionalStream();
-      if (stream == nullptr) {
-        return;
-      }
-      stream->SetVisitor(
-          std::make_unique<BidirectionalEchoVisitorWithLogging>(stream, this));
-      stream->visitor()->OnCanRead();
-    }
-  }
-  void OnIncomingUnidirectionalStreamAvailable() override {}
-
-  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
-
-  void OnCanCreateNewOutgoingBidirectionalStream() override {}
-  void OnCanCreateNewOutgoingUnidirectionalStream() override {
-    MaybeSendLogsBack();
-  }
-
-  void Log(std::string line) {
-    log_.push_back(std::move(line));
-    MaybeSendLogsBack();
-  }
-
- private:
-  void MaybeSendLogsBack() {
-    while (!log_.empty() &&
-           session_->CanOpenNextOutgoingUnidirectionalStream()) {
-      WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
-      stream->SetVisitor(
-          std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
-              stream, log_.front()));
-      log_.pop_front();
-      stream->visitor()->OnCanWrite();
-    }
-  }
-
-  WebTransportSession* session_;  // Not owned.
-  quiche::QuicheCircularDeque<std::string> log_;
-};
-
-void BidirectionalEchoVisitorWithLogging::OnResetStreamReceived(
-    WebTransportStreamError error) {
-  session_visitor_->Log(absl::StrCat("Received reset for stream ",
-                                     stream()->GetStreamId(),
-                                     " with error code ", error));
-  WebTransportBidirectionalEchoVisitor::OnResetStreamReceived(error);
-}
-void BidirectionalEchoVisitorWithLogging::OnStopSendingReceived(
-    WebTransportStreamError error) {
-  session_visitor_->Log(absl::StrCat("Received stop sending for stream ",
-                                     stream()->GetStreamId(),
-                                     " with error code ", error));
-  WebTransportBidirectionalEchoVisitor::OnStopSendingReceived(error);
-}
-
-}  // namespace
-
-QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
-    const spdy::Http2HeaderBlock& /*request_headers*/,
-    WebTransportSession* session) {
-  QuicSimpleServerBackend::WebTransportResponse response;
-  response.response_headers[":status"] = "200";
-  response.visitor = std::make_unique<ResetsVisitor>(session);
-  return response;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/web_transport_resets_backend.h b/quic/test_tools/web_transport_resets_backend.h
deleted file mode 100644
index dda06be..0000000
--- a/quic/test_tools/web_transport_resets_backend.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
-#define QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
-
-#include "quic/test_tools/quic_test_backend.h"
-
-namespace quic {
-namespace test {
-
-// A backend for testing RESET_STREAM/STOP_SENDING behavior.  Provides
-// bidirectional echo streams; whenever one of those receives RESET_STREAM or
-// STOP_SENDING, a log message is sent as a unidirectional stream.
-QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
-    const spdy::Http2HeaderBlock& request_headers,
-    WebTransportSession* session);
-
-}  // namespace test
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
diff --git a/quic/tools/fake_proof_verifier.h b/quic/tools/fake_proof_verifier.h
deleted file mode 100644
index a8e5eb8..0000000
--- a/quic/tools/fake_proof_verifier.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
-#define QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/proof_verifier.h"
-
-namespace quic {
-
-// ProofVerifier implementation which always returns success.
-class FakeProofVerifier : public ProofVerifier {
- public:
-  ~FakeProofVerifier() override {}
-  QuicAsyncStatus VerifyProof(
-      const std::string& /*hostname*/,
-      const uint16_t /*port*/,
-      const std::string& /*server_config*/,
-      QuicTransportVersion /*quic_version*/,
-      absl::string_view /*chlo_hash*/,
-      const std::vector<std::string>& /*certs*/,
-      const std::string& /*cert_sct*/,
-      const std::string& /*signature*/,
-      const ProofVerifyContext* /*context*/,
-      std::string* /*error_details*/,
-      std::unique_ptr<ProofVerifyDetails>* /*details*/,
-      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
-    return QUIC_SUCCESS;
-  }
-  QuicAsyncStatus VerifyCertChain(
-      const std::string& /*hostname*/,
-      const uint16_t /*port*/,
-      const std::vector<std::string>& /*certs*/,
-      const std::string& /*ocsp_response*/,
-      const std::string& /*cert_sct*/,
-      const ProofVerifyContext* /*context*/,
-      std::string* /*error_details*/,
-      std::unique_ptr<ProofVerifyDetails>* /*details*/,
-      uint8_t* /*out_alert*/,
-      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
-    return QUIC_SUCCESS;
-  }
-  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
-    return nullptr;
-  }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
diff --git a/quic/tools/quic_backend_response.cc b/quic/tools/quic_backend_response.cc
deleted file mode 100644
index f6177e0..0000000
--- a/quic/tools/quic_backend_response.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_backend_response.h"
-
-namespace quic {
-
-QuicBackendResponse::ServerPushInfo::ServerPushInfo(
-    QuicUrl request_url,
-    spdy::Http2HeaderBlock headers,
-    spdy::SpdyPriority priority,
-    std::string body)
-    : request_url(request_url),
-      headers(std::move(headers)),
-      priority(priority),
-      body(body) {}
-
-QuicBackendResponse::ServerPushInfo::ServerPushInfo(const ServerPushInfo& other)
-    : request_url(other.request_url),
-      headers(other.headers.Clone()),
-      priority(other.priority),
-      body(other.body) {}
-
-QuicBackendResponse::QuicBackendResponse() : response_type_(REGULAR_RESPONSE) {}
-
-QuicBackendResponse::~QuicBackendResponse() = default;
-
-}  // namespace quic
diff --git a/quic/tools/quic_backend_response.h b/quic/tools/quic_backend_response.h
deleted file mode 100644
index 64d7ade..0000000
--- a/quic/tools/quic_backend_response.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/tools/quic_url.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-// Container for HTTP response header/body pairs
-// fetched by the QuicSimpleServerBackend
-class QuicBackendResponse {
- public:
-  // A ServerPushInfo contains path of the push request and everything needed in
-  // comprising a response for the push request.
-  // TODO(b/171463363): Remove.
-  struct ServerPushInfo {
-    ServerPushInfo(QuicUrl request_url,
-                   spdy::Http2HeaderBlock headers,
-                   spdy::SpdyPriority priority,
-                   std::string body);
-    ServerPushInfo(const ServerPushInfo& other);
-
-    QuicUrl request_url;
-    spdy::Http2HeaderBlock headers;
-    spdy::SpdyPriority priority;
-    std::string body;
-  };
-
-  enum SpecialResponseType {
-    REGULAR_RESPONSE,      // Send the headers and body like a server should.
-    CLOSE_CONNECTION,      // Close the connection (sending the close packet).
-    IGNORE_REQUEST,        // Do nothing, expect the client to time out.
-    BACKEND_ERR_RESPONSE,  // There was an error fetching the response from
-                           // the backend, for example as a TCP connection
-                           // error.
-    INCOMPLETE_RESPONSE,   // The server will act as if there is a non-empty
-                           // trailer but it will not be sent, as a result, FIN
-                           // will not be sent too.
-    GENERATE_BYTES         // Sends a response with a length equal to the number
-                           // of bytes in the URL path.
-  };
-  QuicBackendResponse();
-
-  QuicBackendResponse(const QuicBackendResponse& other) = delete;
-  QuicBackendResponse& operator=(const QuicBackendResponse& other) = delete;
-
-  ~QuicBackendResponse();
-
-  const std::vector<spdy::Http2HeaderBlock>& early_hints() const {
-    return early_hints_;
-  }
-  SpecialResponseType response_type() const { return response_type_; }
-  const spdy::Http2HeaderBlock& headers() const { return headers_; }
-  const spdy::Http2HeaderBlock& trailers() const { return trailers_; }
-  const absl::string_view body() const { return absl::string_view(body_); }
-
-  void AddEarlyHints(const spdy::Http2HeaderBlock& headers) {
-    spdy::Http2HeaderBlock hints = headers.Clone();
-    hints[":status"] = "103";
-    early_hints_.push_back(std::move(hints));
-  }
-
-  void set_response_type(SpecialResponseType response_type) {
-    response_type_ = response_type;
-  }
-
-  void set_headers(spdy::Http2HeaderBlock headers) {
-    headers_ = std::move(headers);
-  }
-  void set_trailers(spdy::Http2HeaderBlock trailers) {
-    trailers_ = std::move(trailers);
-  }
-  void set_body(absl::string_view body) {
-    body_.assign(body.data(), body.size());
-  }
-
- private:
-  std::vector<spdy::Http2HeaderBlock> early_hints_;
-  SpecialResponseType response_type_;
-  spdy::Http2HeaderBlock headers_;
-  spdy::Http2HeaderBlock trailers_;
-  std::string body_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
diff --git a/quic/tools/quic_client.cc b/quic/tools/quic_client.cc
deleted file mode 100644
index cfc435e..0000000
--- a/quic/tools/quic_client.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client.h"
-
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <utility>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_simple_client_session.h"
-
-namespace quic {
-
-namespace tools {
-
-QuicSocketAddress LookupAddress(int address_family_for_lookup,
-                                std::string host,
-                                std::string port) {
-  addrinfo hint;
-  memset(&hint, 0, sizeof(hint));
-  hint.ai_family = address_family_for_lookup;
-  hint.ai_protocol = IPPROTO_UDP;
-
-  addrinfo* info_list = nullptr;
-  int result = getaddrinfo(host.c_str(), port.c_str(), &hint, &info_list);
-  if (result != 0) {
-    QUIC_LOG(ERROR) << "Failed to look up " << host << ": "
-                    << gai_strerror(result);
-    return QuicSocketAddress();
-  }
-
-  QUICHE_CHECK(info_list != nullptr);
-  std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(info_list,
-                                                                 freeaddrinfo);
-  return QuicSocketAddress(info_list->ai_addr, info_list->ai_addrlen);
-}
-
-}  // namespace tools
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
-                       const QuicServerId& server_id,
-                       const ParsedQuicVersionVector& supported_versions,
-                       QuicEpollServer* epoll_server,
-                       std::unique_ptr<ProofVerifier> proof_verifier)
-    : QuicClient(
-          server_address,
-          server_id,
-          supported_versions,
-          QuicConfig(),
-          epoll_server,
-          std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
-          std::move(proof_verifier),
-          nullptr) {}
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
-                       const QuicServerId& server_id,
-                       const ParsedQuicVersionVector& supported_versions,
-                       QuicEpollServer* epoll_server,
-                       std::unique_ptr<ProofVerifier> proof_verifier,
-                       std::unique_ptr<SessionCache> session_cache)
-    : QuicClient(
-          server_address,
-          server_id,
-          supported_versions,
-          QuicConfig(),
-          epoll_server,
-          std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
-          std::move(proof_verifier),
-          std::move(session_cache)) {}
-
-QuicClient::QuicClient(QuicSocketAddress server_address,
-                       const QuicServerId& server_id,
-                       const ParsedQuicVersionVector& supported_versions,
-                       const QuicConfig& config,
-                       QuicEpollServer* epoll_server,
-                       std::unique_ptr<ProofVerifier> proof_verifier,
-                       std::unique_ptr<SessionCache> session_cache)
-    : QuicClient(
-          server_address,
-          server_id,
-          supported_versions,
-          config,
-          epoll_server,
-          std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
-          std::move(proof_verifier),
-          std::move(session_cache)) {}
-
-QuicClient::QuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier)
-    : QuicClient(server_address,
-                 server_id,
-                 supported_versions,
-                 QuicConfig(),
-                 epoll_server,
-                 std::move(network_helper),
-                 std::move(proof_verifier),
-                 nullptr) {}
-
-QuicClient::QuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicConfig& config,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier)
-    : QuicClient(server_address,
-                 server_id,
-                 supported_versions,
-                 config,
-                 epoll_server,
-                 std::move(network_helper),
-                 std::move(proof_verifier),
-                 nullptr) {}
-
-QuicClient::QuicClient(
-    QuicSocketAddress server_address,
-    const QuicServerId& server_id,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicConfig& config,
-    QuicEpollServer* epoll_server,
-    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    std::unique_ptr<SessionCache> session_cache)
-    : QuicSpdyClientBase(
-          server_id,
-          supported_versions,
-          config,
-          new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
-          new QuicEpollAlarmFactory(epoll_server),
-          std::move(network_helper),
-          std::move(proof_verifier),
-          std::move(session_cache)) {
-  set_server_address(server_address);
-}
-
-QuicClient::~QuicClient() = default;
-
-std::unique_ptr<QuicSession> QuicClient::CreateQuicClientSession(
-    const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection) {
-  return std::make_unique<QuicSimpleClientSession>(
-      *config(), supported_versions, connection, server_id(), crypto_config(),
-      push_promise_index(), drop_response_body(), enable_web_transport(),
-      use_datagram_contexts());
-}
-
-QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() {
-  return static_cast<QuicClientEpollNetworkHelper*>(network_helper());
-}
-
-const QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() const {
-  return static_cast<const QuicClientEpollNetworkHelper*>(network_helper());
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_client.h b/quic/tools/quic_client.h
deleted file mode 100644
index cc6ec37..0000000
--- a/quic/tools/quic_client.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy client, which connects to a specified port and sends QUIC
-// request to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
-#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_client_epoll_network_helper.h"
-#include "quic/tools/quic_spdy_client_base.h"
-
-namespace quic {
-
-class QuicServerId;
-
-namespace test {
-class QuicClientPeer;
-}  // namespace test
-
-namespace tools {
-
-QuicSocketAddress LookupAddress(int address_family_for_lookup,
-                                std::string host,
-                                std::string port);
-
-inline QuicSocketAddress LookupAddress(std::string host, std::string port) {
-  return LookupAddress(0, host, port);
-}
-
-}  // namespace tools
-
-class QuicClient : public QuicSpdyClientBase {
- public:
-  // These will create their own QuicClientEpollNetworkHelper.
-  QuicClient(QuicSocketAddress server_address,
-             const QuicServerId& server_id,
-             const ParsedQuicVersionVector& supported_versions,
-             QuicEpollServer* epoll_server,
-             std::unique_ptr<ProofVerifier> proof_verifier);
-  QuicClient(QuicSocketAddress server_address,
-             const QuicServerId& server_id,
-             const ParsedQuicVersionVector& supported_versions,
-             QuicEpollServer* epoll_server,
-             std::unique_ptr<ProofVerifier> proof_verifier,
-             std::unique_ptr<SessionCache> session_cache);
-  QuicClient(QuicSocketAddress server_address,
-             const QuicServerId& server_id,
-             const ParsedQuicVersionVector& supported_versions,
-             const QuicConfig& config,
-             QuicEpollServer* epoll_server,
-             std::unique_ptr<ProofVerifier> proof_verifier,
-             std::unique_ptr<SessionCache> session_cache);
-  // This will take ownership of a passed in network primitive.
-  QuicClient(QuicSocketAddress server_address,
-             const QuicServerId& server_id,
-             const ParsedQuicVersionVector& supported_versions,
-             QuicEpollServer* epoll_server,
-             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
-             std::unique_ptr<ProofVerifier> proof_verifier);
-  QuicClient(QuicSocketAddress server_address,
-             const QuicServerId& server_id,
-             const ParsedQuicVersionVector& supported_versions,
-             const QuicConfig& config,
-             QuicEpollServer* epoll_server,
-             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
-             std::unique_ptr<ProofVerifier> proof_verifier);
-  QuicClient(QuicSocketAddress server_address,
-             const QuicServerId& server_id,
-             const ParsedQuicVersionVector& supported_versions,
-             const QuicConfig& config,
-             QuicEpollServer* epoll_server,
-             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
-             std::unique_ptr<ProofVerifier> proof_verifier,
-             std::unique_ptr<SessionCache> session_cache);
-  QuicClient(const QuicClient&) = delete;
-  QuicClient& operator=(const QuicClient&) = delete;
-
-  ~QuicClient() override;
-
-  std::unique_ptr<QuicSession> CreateQuicClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection) override;
-
-  // Exposed for the quic client test.
-  int GetLatestFD() const { return epoll_network_helper()->GetLatestFD(); }
-
-  QuicClientEpollNetworkHelper* epoll_network_helper();
-  const QuicClientEpollNetworkHelper* epoll_network_helper() const;
-
- private:
-  friend class test::QuicClientPeer;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
diff --git a/quic/tools/quic_client_base.cc b/quic/tools/quic_client_base.cc
deleted file mode 100644
index e11e25b..0000000
--- a/quic/tools/quic_client_base.cc
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client_base.h"
-
-#include <algorithm>
-#include <memory>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_path_validator.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-
-namespace quic {
-
-// A path context which owns the writer.
-class QUIC_EXPORT_PRIVATE PathMigrationContext
-    : public QuicPathValidationContext {
- public:
-  PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
-                       const QuicSocketAddress& self_address,
-                       const QuicSocketAddress& peer_address)
-      : QuicPathValidationContext(self_address, peer_address),
-        alternative_writer_(std::move(writer)) {}
-
-  QuicPacketWriter* WriterToUse() override { return alternative_writer_.get(); }
-
-  QuicPacketWriter* ReleaseWriter() { return alternative_writer_.release(); }
-
- private:
-  std::unique_ptr<QuicPacketWriter> alternative_writer_;
-};
-
-// Implements the basic feature of a result delegate for path validation for
-// connection migration. If the validation succeeds, migrate to the alternative
-// path. Otherwise, stay on the current path.
-class QuicClientSocketMigrationValidationResultDelegate
-    : public QuicPathValidator::ResultDelegate {
- public:
-  QuicClientSocketMigrationValidationResultDelegate(QuicClientBase* client)
-      : QuicPathValidator::ResultDelegate(), client_(client) {}
-
-  // QuicPathValidator::ResultDelegate
-  // Overridden to start migration and takes the ownership of the writer in the
-  // context.
-  void OnPathValidationSuccess(
-      std::unique_ptr<QuicPathValidationContext> context) override {
-    QUIC_DLOG(INFO) << "Successfully validated path from " << *context
-                    << ". Migrate to it now.";
-    auto migration_context = std::unique_ptr<PathMigrationContext>(
-        static_cast<PathMigrationContext*>(context.release()));
-    client_->session()->MigratePath(
-        migration_context->self_address(), migration_context->peer_address(),
-        migration_context->WriterToUse(), /*owns_writer=*/false);
-    QUICHE_DCHECK(migration_context->WriterToUse() != nullptr);
-    // Hand the ownership of the alternative writer to the client.
-    client_->set_writer(migration_context->ReleaseWriter());
-  }
-
-  void OnPathValidationFailure(
-      std::unique_ptr<QuicPathValidationContext> context) override {
-    QUIC_LOG(WARNING) << "Fail to validate path " << *context
-                      << ", stop migrating.";
-    client_->session()->connection()->OnPathValidationFailureAtClient();
-  }
-
- private:
-  QuicClientBase* client_;
-};
-
-QuicClientBase::NetworkHelper::~NetworkHelper() = default;
-
-QuicClientBase::QuicClientBase(
-    const QuicServerId& server_id,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicConfig& config,
-    QuicConnectionHelperInterface* helper,
-    QuicAlarmFactory* alarm_factory,
-    std::unique_ptr<NetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    std::unique_ptr<SessionCache> session_cache)
-    : server_id_(server_id),
-      initialized_(false),
-      local_port_(0),
-      config_(config),
-      crypto_config_(std::move(proof_verifier), std::move(session_cache)),
-      helper_(helper),
-      alarm_factory_(alarm_factory),
-      supported_versions_(supported_versions),
-      initial_max_packet_length_(0),
-      num_sent_client_hellos_(0),
-      connection_error_(QUIC_NO_ERROR),
-      connected_or_attempting_connect_(false),
-      network_helper_(std::move(network_helper)),
-      connection_debug_visitor_(nullptr),
-      server_connection_id_length_(kQuicDefaultConnectionIdLength),
-      client_connection_id_length_(0) {}
-
-QuicClientBase::~QuicClientBase() = default;
-
-bool QuicClientBase::Initialize() {
-  num_sent_client_hellos_ = 0;
-  connection_error_ = QUIC_NO_ERROR;
-  connected_or_attempting_connect_ = false;
-
-  // If an initial flow control window has not explicitly been set, then use the
-  // same values that Chrome uses.
-  const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024;  // 15 MB
-  const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024;    //  6 MB
-  if (config()->GetInitialStreamFlowControlWindowToSend() ==
-      kDefaultFlowControlSendWindow) {
-    config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize);
-  }
-  if (config()->GetInitialSessionFlowControlWindowToSend() ==
-      kDefaultFlowControlSendWindow) {
-    config()->SetInitialSessionFlowControlWindowToSend(
-        kSessionMaxRecvWindowSize);
-  }
-
-  if (!network_helper_->CreateUDPSocketAndBind(server_address_,
-                                               bind_to_address_, local_port_)) {
-    return false;
-  }
-
-  initialized_ = true;
-  return true;
-}
-
-bool QuicClientBase::Connect() {
-  // Attempt multiple connects until the maximum number of client hellos have
-  // been sent.
-  int num_attempts = 0;
-  while (!connected() &&
-         num_attempts <= QuicCryptoClientStream::kMaxClientHellos) {
-    StartConnect();
-    while (EncryptionBeingEstablished()) {
-      WaitForEvents();
-    }
-    ParsedQuicVersion version = UnsupportedQuicVersion();
-    if (session() != nullptr && !CanReconnectWithDifferentVersion(&version)) {
-      // We've successfully created a session but we're not connected, and we
-      // cannot reconnect with a different version.  Give up trying.
-      break;
-    }
-    num_attempts++;
-  }
-  if (session() == nullptr) {
-    QUIC_BUG(quic_bug_10906_1) << "Missing session after Connect";
-    return false;
-  }
-  return session()->connection()->connected();
-}
-
-void QuicClientBase::StartConnect() {
-  QUICHE_DCHECK(initialized_);
-  QUICHE_DCHECK(!connected());
-  QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
-  ParsedQuicVersion mutual_version = UnsupportedQuicVersion();
-  const bool can_reconnect_with_different_version =
-      CanReconnectWithDifferentVersion(&mutual_version);
-  if (connected_or_attempting_connect()) {
-    // Clear queued up data if client can not try to connect with a different
-    // version.
-    if (!can_reconnect_with_different_version) {
-      ClearDataToResend();
-    }
-    // Before we destroy the last session and create a new one, gather its stats
-    // and update the stats for the overall connection.
-    UpdateStats();
-  }
-
-  const quic::ParsedQuicVersionVector client_supported_versions =
-      can_reconnect_with_different_version
-          ? ParsedQuicVersionVector{mutual_version}
-          : supported_versions();
-
-  session_ = CreateQuicClientSession(
-      client_supported_versions,
-      new QuicConnection(GetNextConnectionId(), QuicSocketAddress(),
-                         server_address(), helper(), alarm_factory(), writer,
-                         /* owns_writer= */ false, Perspective::IS_CLIENT,
-                         client_supported_versions));
-  if (can_reconnect_with_different_version) {
-    session()->set_client_original_supported_versions(supported_versions());
-  }
-  if (connection_debug_visitor_ != nullptr) {
-    session()->connection()->set_debug_visitor(connection_debug_visitor_);
-  }
-  session()->connection()->set_client_connection_id(GetClientConnectionId());
-  if (initial_max_packet_length_ != 0) {
-    session()->connection()->SetMaxPacketLength(initial_max_packet_length_);
-  }
-  // Reset |writer()| after |session()| so that the old writer outlives the old
-  // session.
-  set_writer(writer);
-  InitializeSession();
-  if (can_reconnect_with_different_version) {
-    // This is a reconnect using server supported |mutual_version|.
-    session()->connection()->SetVersionNegotiated();
-  }
-  set_connected_or_attempting_connect(true);
-}
-
-void QuicClientBase::InitializeSession() {
-  session()->Initialize();
-}
-
-void QuicClientBase::Disconnect() {
-  QUICHE_DCHECK(initialized_);
-
-  initialized_ = false;
-  if (connected()) {
-    session()->connection()->CloseConnection(
-        QUIC_PEER_GOING_AWAY, "Client disconnecting",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  }
-
-  ClearDataToResend();
-
-  network_helper_->CleanUpAllUDPSockets();
-}
-
-ProofVerifier* QuicClientBase::proof_verifier() const {
-  return crypto_config_.proof_verifier();
-}
-
-bool QuicClientBase::EncryptionBeingEstablished() {
-  return !session_->IsEncryptionEstablished() &&
-         session_->connection()->connected();
-}
-
-bool QuicClientBase::WaitForEvents() {
-  if (!connected()) {
-    QUIC_BUG(quic_bug_10906_2)
-        << "Cannot call WaitForEvents on non-connected client";
-    return false;
-  }
-
-  network_helper_->RunEventLoop();
-
-  QUICHE_DCHECK(session() != nullptr);
-  ParsedQuicVersion version = UnsupportedQuicVersion();
-  if (!connected() && CanReconnectWithDifferentVersion(&version)) {
-    QUIC_DLOG(INFO) << "Can reconnect with version: " << version
-                    << ", attempting to reconnect.";
-
-    Connect();
-  }
-
-  return HasActiveRequests();
-}
-
-bool QuicClientBase::MigrateSocket(const QuicIpAddress& new_host) {
-  return MigrateSocketWithSpecifiedPort(new_host, local_port_);
-}
-
-bool QuicClientBase::MigrateSocketWithSpecifiedPort(
-    const QuicIpAddress& new_host,
-    int port) {
-  if (!connected()) {
-    QUICHE_DVLOG(1)
-        << "MigrateSocketWithSpecifiedPort failed as connection has closed";
-    return false;
-  }
-
-  network_helper_->CleanUpAllUDPSockets();
-  std::unique_ptr<QuicPacketWriter> writer =
-      CreateWriterForNewNetwork(new_host, port);
-  if (writer == nullptr) {
-    QUICHE_DVLOG(1)
-        << "MigrateSocketWithSpecifiedPort failed from writer creation";
-    return false;
-  }
-  if (!session()->MigratePath(network_helper_->GetLatestClientAddress(),
-                              session()->connection()->peer_address(),
-                              writer.get(), false)) {
-    QUICHE_DVLOG(1)
-        << "MigrateSocketWithSpecifiedPort failed from session()->MigratePath";
-    return false;
-  }
-  set_writer(writer.release());
-  return true;
-}
-
-bool QuicClientBase::ValidateAndMigrateSocket(const QuicIpAddress& new_host) {
-  QUICHE_DCHECK(VersionHasIetfQuicFrames(
-                    session_->connection()->version().transport_version) &&
-                session_->connection()->use_path_validator());
-  if (!connected()) {
-    return false;
-  }
-
-  std::unique_ptr<QuicPacketWriter> writer =
-      CreateWriterForNewNetwork(new_host, local_port_);
-  if (writer == nullptr) {
-    return false;
-  }
-  // Asynchronously start migration.
-  session_->ValidatePath(
-      std::make_unique<PathMigrationContext>(
-          std::move(writer), network_helper_->GetLatestClientAddress(),
-          session_->peer_address()),
-      std::make_unique<QuicClientSocketMigrationValidationResultDelegate>(
-          this));
-  return true;
-}
-
-std::unique_ptr<QuicPacketWriter> QuicClientBase::CreateWriterForNewNetwork(
-    const QuicIpAddress& new_host,
-    int port) {
-  set_bind_to_address(new_host);
-  set_local_port(port);
-  if (!network_helper_->CreateUDPSocketAndBind(server_address_,
-                                               bind_to_address_, port)) {
-    return nullptr;
-  }
-
-  QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
-  QUIC_LOG_IF(WARNING, writer == writer_.get())
-      << "The new writer is wrapped in the same wrapper as the old one, thus "
-         "appearing to have the same address as the old one.";
-  return std::unique_ptr<QuicPacketWriter>(writer);
-}
-
-bool QuicClientBase::ChangeEphemeralPort() {
-  auto current_host = network_helper_->GetLatestClientAddress().host();
-  return MigrateSocketWithSpecifiedPort(current_host, 0 /*any ephemeral port*/);
-}
-
-QuicSession* QuicClientBase::session() {
-  return session_.get();
-}
-
-const QuicSession* QuicClientBase::session() const {
-  return session_.get();
-}
-
-QuicClientBase::NetworkHelper* QuicClientBase::network_helper() {
-  return network_helper_.get();
-}
-
-const QuicClientBase::NetworkHelper* QuicClientBase::network_helper() const {
-  return network_helper_.get();
-}
-
-void QuicClientBase::WaitForStreamToClose(QuicStreamId id) {
-  if (!connected()) {
-    QUIC_BUG(quic_bug_10906_3)
-        << "Cannot WaitForStreamToClose on non-connected client";
-    return;
-  }
-
-  while (connected() && !session_->IsClosedStream(id)) {
-    WaitForEvents();
-  }
-}
-
-bool QuicClientBase::WaitForOneRttKeysAvailable() {
-  if (!connected()) {
-    QUIC_BUG(quic_bug_10906_4)
-        << "Cannot WaitForOneRttKeysAvailable on non-connected client";
-    return false;
-  }
-
-  while (connected() && !session_->OneRttKeysAvailable()) {
-    WaitForEvents();
-  }
-
-  // If the handshake fails due to a timeout, the connection will be closed.
-  QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
-  return connected();
-}
-
-bool QuicClientBase::WaitForHandshakeConfirmed() {
-  if (!session_->connection()->version().UsesTls()) {
-    return WaitForOneRttKeysAvailable();
-  }
-  // Otherwise, wait for receipt of HANDSHAKE_DONE frame.
-  while (connected() && session_->GetHandshakeState() < HANDSHAKE_CONFIRMED) {
-    WaitForEvents();
-  }
-
-  // If the handshake fails due to a timeout, the connection will be closed.
-  QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
-  return connected();
-}
-
-bool QuicClientBase::connected() const {
-  return session_.get() && session_->connection() &&
-         session_->connection()->connected();
-}
-
-bool QuicClientBase::goaway_received() const {
-  return session_ != nullptr && session_->transport_goaway_received();
-}
-
-int QuicClientBase::GetNumSentClientHellos() {
-  // If we are not actively attempting to connect, the session object
-  // corresponds to the previous connection and should not be used.
-  const int current_session_hellos = !connected_or_attempting_connect_
-                                         ? 0
-                                         : GetNumSentClientHellosFromSession();
-  return num_sent_client_hellos_ + current_session_hellos;
-}
-
-void QuicClientBase::UpdateStats() {
-  num_sent_client_hellos_ += GetNumSentClientHellosFromSession();
-}
-
-int QuicClientBase::GetNumReceivedServerConfigUpdates() {
-  // If we are not actively attempting to connect, the session object
-  // corresponds to the previous connection and should not be used.
-  return !connected_or_attempting_connect_
-             ? 0
-             : GetNumReceivedServerConfigUpdatesFromSession();
-}
-
-QuicErrorCode QuicClientBase::connection_error() const {
-  // Return the high-level error if there was one.  Otherwise, return the
-  // connection error from the last session.
-  if (connection_error_ != QUIC_NO_ERROR) {
-    return connection_error_;
-  }
-  if (session_ == nullptr) {
-    return QUIC_NO_ERROR;
-  }
-  return session_->error();
-}
-
-QuicConnectionId QuicClientBase::GetNextConnectionId() {
-  return GenerateNewConnectionId();
-}
-
-QuicConnectionId QuicClientBase::GenerateNewConnectionId() {
-  return QuicUtils::CreateRandomConnectionId(server_connection_id_length_);
-}
-
-QuicConnectionId QuicClientBase::GetClientConnectionId() {
-  return QuicUtils::CreateRandomConnectionId(client_connection_id_length_);
-}
-
-bool QuicClientBase::CanReconnectWithDifferentVersion(
-    ParsedQuicVersion* version) const {
-  if (session_ == nullptr || session_->connection() == nullptr ||
-      session_->error() != QUIC_INVALID_VERSION) {
-    return false;
-  }
-
-  const auto& server_supported_versions =
-      session_->connection()->server_supported_versions();
-  if (server_supported_versions.empty()) {
-    return false;
-  }
-
-  for (const auto& client_version : supported_versions_) {
-    if (std::find(server_supported_versions.begin(),
-                  server_supported_versions.end(),
-                  client_version) != server_supported_versions.end()) {
-      *version = client_version;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicClientBase::HasPendingPathValidation() {
-  return session()->HasPendingPathValidation();
-}
-
-class ValidationResultDelegate : public QuicPathValidator::ResultDelegate {
- public:
-  ValidationResultDelegate(QuicClientBase* client)
-      : QuicPathValidator::ResultDelegate(), client_(client) {}
-
-  void OnPathValidationSuccess(
-      std::unique_ptr<QuicPathValidationContext> context) override {
-    QUIC_DLOG(INFO) << "Successfully validated path from " << *context;
-    client_->AddValidatedPath(std::move(context));
-  }
-  void OnPathValidationFailure(
-      std::unique_ptr<QuicPathValidationContext> context) override {
-    QUIC_LOG(WARNING) << "Fail to validate path " << *context
-                      << ", stop migrating.";
-    client_->session()->connection()->OnPathValidationFailureAtClient();
-  }
-
- private:
-  QuicClientBase* client_;
-};
-
-void QuicClientBase::ValidateNewNetwork(const QuicIpAddress& host) {
-  std::unique_ptr<QuicPacketWriter> writer =
-      CreateWriterForNewNetwork(host, local_port_);
-  auto result_delegate = std::make_unique<ValidationResultDelegate>(this);
-  if (writer == nullptr) {
-    result_delegate->OnPathValidationFailure(
-        std::make_unique<PathMigrationContext>(
-            nullptr, network_helper_->GetLatestClientAddress(),
-            session_->peer_address()));
-    return;
-  }
-  session()->ValidatePath(
-      std::make_unique<PathMigrationContext>(
-          std::move(writer), network_helper_->GetLatestClientAddress(),
-          session_->peer_address()),
-      std::move(result_delegate));
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_client_base.h b/quic/tools/quic_client_base.h
deleted file mode 100644
index 51e3433..0000000
--- a/quic/tools/quic_client_base.h
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A base class for the toy client, which connects to a specified port and sends
-// QUIC request to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
-
-#include <memory>
-#include <string>
-
-#include "absl/base/attributes.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_config.h"
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-class ProofVerifier;
-class QuicServerId;
-class SessionCache;
-
-// QuicClientBase handles establishing a connection to the passed in
-// server id, including ensuring that it supports the passed in versions
-// and config.
-// Subclasses derived from this class are responsible for creating the
-// actual QuicSession instance, as well as defining functions that
-// create and run the underlying network transport.
-class QuicClientBase {
- public:
-  // An interface to various network events that the QuicClient will need to
-  // interact with.
-  class NetworkHelper {
-   public:
-    virtual ~NetworkHelper();
-
-    // Runs one iteration of the event loop.
-    virtual void RunEventLoop() = 0;
-
-    // Used during initialization: creates the UDP socket FD, sets socket
-    // options, and binds the socket to our address.
-    virtual bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
-                                        QuicIpAddress bind_to_address,
-                                        int bind_to_port) = 0;
-
-    // Unregister and close all open UDP sockets.
-    virtual void CleanUpAllUDPSockets() = 0;
-
-    // If the client has at least one UDP socket, return address of the latest
-    // created one. Otherwise, return an empty socket address.
-    virtual QuicSocketAddress GetLatestClientAddress() const = 0;
-
-    // Creates a packet writer to be used for the next connection.
-    virtual QuicPacketWriter* CreateQuicPacketWriter() = 0;
-  };
-
-  QuicClientBase(const QuicServerId& server_id,
-                 const ParsedQuicVersionVector& supported_versions,
-                 const QuicConfig& config,
-                 QuicConnectionHelperInterface* helper,
-                 QuicAlarmFactory* alarm_factory,
-                 std::unique_ptr<NetworkHelper> network_helper,
-                 std::unique_ptr<ProofVerifier> proof_verifier,
-                 std::unique_ptr<SessionCache> session_cache);
-  QuicClientBase(const QuicClientBase&) = delete;
-  QuicClientBase& operator=(const QuicClientBase&) = delete;
-
-  virtual ~QuicClientBase();
-
-  // Initializes the client to create a connection. Should be called exactly
-  // once before calling StartConnect or Connect. Returns true if the
-  // initialization succeeds, false otherwise.
-  virtual bool Initialize();
-
-  // "Connect" to the QUIC server, including performing synchronous crypto
-  // handshake.
-  bool Connect();
-
-  // Start the crypto handshake.  This can be done in place of the synchronous
-  // Connect(), but callers are responsible for making sure the crypto handshake
-  // completes.
-  void StartConnect();
-
-  // Calls session()->Initialize(). Subclasses may override this if any extra
-  // initialization needs to be done. Subclasses should expect that session()
-  // is non-null and valid.
-  virtual void InitializeSession();
-
-  // Disconnects from the QUIC server.
-  void Disconnect();
-
-  // Returns true if the crypto handshake has yet to establish encryption.
-  // Returns false if encryption is active (even if the server hasn't confirmed
-  // the handshake) or if the connection has been closed.
-  bool EncryptionBeingEstablished();
-
-  // Wait for events until the stream with the given ID is closed.
-  void WaitForStreamToClose(QuicStreamId id);
-
-  // Wait for 1-RTT keys become available.
-  // Returns true once 1-RTT keys are available, false otherwise.
-  ABSL_MUST_USE_RESULT bool WaitForOneRttKeysAvailable();
-
-  // Wait for handshake state proceeds to HANDSHAKE_CONFIRMED.
-  // In QUIC crypto, this does the same as WaitForOneRttKeysAvailable, while in
-  // TLS, this waits for HANDSHAKE_DONE frame is received.
-  ABSL_MUST_USE_RESULT bool WaitForHandshakeConfirmed();
-
-  // Wait up to 50ms, and handle any events which occur.
-  // Returns true if there are any outstanding requests.
-  bool WaitForEvents();
-
-  // Migrate to a new socket (new_host) during an active connection.
-  bool MigrateSocket(const QuicIpAddress& new_host);
-
-  // Migrate to a new socket (new_host, port) during an active connection.
-  bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
-
-  // Validate the new socket and migrate to it if the validation succeeds.
-  // Otherwise stay on the current socket. Return true if the validation has
-  // started.
-  bool ValidateAndMigrateSocket(const QuicIpAddress& new_host);
-
-  // Open a new socket to change to a new ephemeral port.
-  bool ChangeEphemeralPort();
-
-  QuicSession* session();
-  const QuicSession* session() const;
-
-  bool connected() const;
-  virtual bool goaway_received() const;
-
-  const QuicServerId& server_id() const { return server_id_; }
-
-  // This should only be set before the initial Connect()
-  void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; }
-
-  void SetUserAgentID(const std::string& user_agent_id) {
-    crypto_config_.set_user_agent_id(user_agent_id);
-  }
-
-  void SetTlsSignatureAlgorithms(std::string signature_algorithms) {
-    crypto_config_.set_tls_signature_algorithms(
-        std::move(signature_algorithms));
-  }
-
-  const ParsedQuicVersionVector& supported_versions() const {
-    return supported_versions_;
-  }
-
-  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
-    supported_versions_ = versions;
-  }
-
-  QuicConfig* config() { return &config_; }
-
-  QuicCryptoClientConfig* crypto_config() { return &crypto_config_; }
-
-  // Change the initial maximum packet size of the connection.  Has to be called
-  // before Connect()/StartConnect() in order to have any effect.
-  void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) {
-    initial_max_packet_length_ = initial_max_packet_length;
-  }
-
-  // The number of client hellos sent.
-  int GetNumSentClientHellos();
-
-  // Returns true if early data (0-RTT data) was sent and the server accepted
-  // it.
-  virtual bool EarlyDataAccepted() = 0;
-
-  // Returns true if the handshake was delayed one round trip by the server
-  // because the server wanted proof the client controls its source address
-  // before progressing further. In Google QUIC, this would be due to an
-  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
-  // to a Retry packet.
-  // TODO(nharper): Consider a better name for this method.
-  virtual bool ReceivedInchoateReject() = 0;
-
-  // Gather the stats for the last session and update the stats for the overall
-  // connection.
-  void UpdateStats();
-
-  // The number of server config updates received.
-  int GetNumReceivedServerConfigUpdates();
-
-  // Returns any errors that occurred at the connection-level.
-  QuicErrorCode connection_error() const;
-  void set_connection_error(QuicErrorCode connection_error) {
-    connection_error_ = connection_error;
-  }
-
-  bool connected_or_attempting_connect() const {
-    return connected_or_attempting_connect_;
-  }
-  void set_connected_or_attempting_connect(
-      bool connected_or_attempting_connect) {
-    connected_or_attempting_connect_ = connected_or_attempting_connect;
-  }
-
-  QuicPacketWriter* writer() { return writer_.get(); }
-  void set_writer(QuicPacketWriter* writer) {
-    if (writer_.get() != writer) {
-      writer_.reset(writer);
-    }
-  }
-
-  void reset_writer() { writer_.reset(); }
-
-  ProofVerifier* proof_verifier() const;
-
-  void set_bind_to_address(QuicIpAddress address) {
-    bind_to_address_ = address;
-  }
-
-  QuicIpAddress bind_to_address() const { return bind_to_address_; }
-
-  void set_local_port(int local_port) { local_port_ = local_port; }
-
-  int local_port() const { return local_port_; }
-
-  const QuicSocketAddress& server_address() const { return server_address_; }
-
-  void set_server_address(const QuicSocketAddress& server_address) {
-    server_address_ = server_address;
-  }
-
-  QuicConnectionHelperInterface* helper() { return helper_.get(); }
-
-  NetworkHelper* network_helper();
-  const NetworkHelper* network_helper() const;
-
-  bool initialized() const { return initialized_; }
-
-  void SetPreSharedKey(absl::string_view key) {
-    crypto_config_.set_pre_shared_key(key);
-  }
-
-  void set_connection_debug_visitor(
-      QuicConnectionDebugVisitor* connection_debug_visitor) {
-    connection_debug_visitor_ = connection_debug_visitor;
-  }
-
-  void set_server_connection_id_length(uint8_t server_connection_id_length) {
-    server_connection_id_length_ = server_connection_id_length;
-  }
-
-  void set_client_connection_id_length(uint8_t client_connection_id_length) {
-    client_connection_id_length_ = client_connection_id_length;
-  }
-
-  bool HasPendingPathValidation();
-
-  void ValidateNewNetwork(const QuicIpAddress& host);
-
-  void AddValidatedPath(std::unique_ptr<QuicPathValidationContext> context) {
-    validated_paths_.push_back(std::move(context));
-  }
-
-  const std::vector<std::unique_ptr<QuicPathValidationContext>>&
-  validated_paths() const {
-    return validated_paths_;
-  }
-
- protected:
-  // TODO(rch): Move GetNumSentClientHellosFromSession and
-  // GetNumReceivedServerConfigUpdatesFromSession into a new/better
-  // QuicSpdyClientSession class. The current inherits dependencies from
-  // Spdy. When that happens this class and all its subclasses should
-  // work with QuicSpdyClientSession instead of QuicSession.
-  // That will obviate the need for the pure virtual functions below.
-
-  // Extract the number of sent client hellos from the session.
-  virtual int GetNumSentClientHellosFromSession() = 0;
-
-  // The number of server config updates received.
-  virtual int GetNumReceivedServerConfigUpdatesFromSession() = 0;
-
-  // If this client supports buffering data, resend it.
-  virtual void ResendSavedData() = 0;
-
-  // If this client supports buffering data, clear it.
-  virtual void ClearDataToResend() = 0;
-
-  // Takes ownership of |connection|. If you override this function,
-  // you probably want to call ResetSession() in your destructor.
-  // TODO(rch): Change the connection parameter to take in a
-  // std::unique_ptr<QuicConnection> instead.
-  virtual std::unique_ptr<QuicSession> CreateQuicClientSession(
-      const ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection) = 0;
-
-  // Generates the next ConnectionId for |server_id_|.  By default, if the
-  // cached server config contains a server-designated ID, that ID will be
-  // returned.  Otherwise, the next random ID will be returned.
-  QuicConnectionId GetNextConnectionId();
-
-  // Generates a new, random connection ID (as opposed to a server-designated
-  // connection ID).
-  virtual QuicConnectionId GenerateNewConnectionId();
-
-  // Returns the client connection ID to use.
-  virtual QuicConnectionId GetClientConnectionId();
-
-  QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
-
-  // Subclasses may need to explicitly clear the session on destruction
-  // if they create it with objects that will be destroyed before this is.
-  // You probably want to call this if you override CreateQuicSpdyClientSession.
-  void ResetSession() { session_.reset(); }
-
-  // Returns true if the corresponding of this client has active requests.
-  virtual bool HasActiveRequests() = 0;
-
- private:
-  // Returns true and set |version| if client can reconnect with a different
-  // version.
-  bool CanReconnectWithDifferentVersion(ParsedQuicVersion* version) const;
-
-  std::unique_ptr<QuicPacketWriter> CreateWriterForNewNetwork(
-      const QuicIpAddress& new_host,
-      int port);
-
-  // |server_id_| is a tuple (hostname, port, is_https) of the server.
-  QuicServerId server_id_;
-
-  // Tracks if the client is initialized to connect.
-  bool initialized_;
-
-  // Address of the server.
-  QuicSocketAddress server_address_;
-
-  // If initialized, the address to bind to.
-  QuicIpAddress bind_to_address_;
-
-  // Local port to bind to. Initialize to 0.
-  int local_port_;
-
-  // config_ and crypto_config_ contain configuration and cached state about
-  // servers.
-  QuicConfig config_;
-  QuicCryptoClientConfig crypto_config_;
-
-  // Helper to be used by created connections. Must outlive |session_|.
-  std::unique_ptr<QuicConnectionHelperInterface> helper_;
-
-  // Alarm factory to be used by created connections. Must outlive |session_|.
-  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
-
-  // Writer used to actually send packets to the wire. Must outlive |session_|.
-  std::unique_ptr<QuicPacketWriter> writer_;
-
-  // Session which manages streams.
-  std::unique_ptr<QuicSession> session_;
-
-  // This vector contains QUIC versions which we currently support.
-  // This should be ordered such that the highest supported version is the first
-  // element, with subsequent elements in descending order (versions can be
-  // skipped as necessary). We will always pick supported_versions_[0] as the
-  // initial version to use.
-  ParsedQuicVersionVector supported_versions_;
-
-  // The initial value of maximum packet size of the connection.  If set to
-  // zero, the default is used.
-  QuicByteCount initial_max_packet_length_;
-
-  // The number of hellos sent during the current/latest connection.
-  int num_sent_client_hellos_;
-
-  // Used to store any errors that occurred with the overall connection (as
-  // opposed to that associated with the last session object).
-  QuicErrorCode connection_error_;
-
-  // True when the client is attempting to connect.  Set to false between a call
-  // to Disconnect() and the subsequent call to StartConnect().  When
-  // connected_or_attempting_connect_ is false, the session object corresponds
-  // to the previous client-level connection.
-  bool connected_or_attempting_connect_;
-
-  // The network helper used to create sockets and manage the event loop.
-  // Not owned by this class.
-  std::unique_ptr<NetworkHelper> network_helper_;
-
-  // The debug visitor set on the connection right after it is constructed.
-  // Not owned, must be valid for the lifetime of the QuicClientBase instance.
-  QuicConnectionDebugVisitor* connection_debug_visitor_;
-
-  // GenerateNewConnectionId creates a random connection ID of this length.
-  // Defaults to 8.
-  uint8_t server_connection_id_length_;
-
-  // GetClientConnectionId creates a random connection ID of this length.
-  // Defaults to 0.
-  uint8_t client_connection_id_length_;
-
-  // Stores validated paths.
-  std::vector<std::unique_ptr<QuicPathValidationContext>> validated_paths_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
diff --git a/quic/tools/quic_client_bin.cc b/quic/tools/quic_client_bin.cc
deleted file mode 100644
index 1efc0e0..0000000
--- a/quic/tools/quic_client_bin.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A binary wrapper for QuicClient.
-// Connects to a host using QUIC, sends a request to the provided URL, and
-// displays the response.
-//
-// Some usage examples:
-//
-// Standard request/response:
-//   quic_client www.google.com
-//   quic_client www.google.com --quiet
-//   quic_client www.google.com --port=443
-//
-// Use a specific version:
-//   quic_client www.google.com --quic_version=23
-//
-// Send a POST instead of a GET:
-//   quic_client www.google.com --body="this is a POST body"
-//
-// Append additional headers to the request:
-//   quic_client www.google.com --headers="header-a: 1234; header-b: 5678"
-//
-// Connect to a host different to the URL being requested:
-//   quic_client mail.google.com --host=www.google.com
-//
-// Connect to a specific IP:
-//   IP=`dig www.google.com +short | head -1`
-//   quic_client www.google.com --host=${IP}
-//
-// Send repeated requests and change ephemeral port between requests
-//   quic_client www.google.com --num_requests=10
-//
-// Try to connect to a host which does not speak QUIC:
-//   quic_client www.example.com
-//
-// This tool is available as a built binary at:
-// /google/data/ro/teams/quic/tools/quic_client
-// After submitting changes to this file, you will need to follow the
-// instructions at go/quic_client_binary_update
-
-#include <iostream>
-#include <memory>
-#include <string>
-
-#include "quic/tools/quic_epoll_client_factory.h"
-#include "quic/tools/quic_toy_client.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/platform/api/quiche_system_event_loop.h"
-
-int main(int argc, char* argv[]) {
-  quiche::QuicheSystemEventLoop event_loop("quic_client");
-  const char* usage = "Usage: quic_client [options] <url>";
-
-  // All non-flag arguments should be interpreted as URLs to fetch.
-  std::vector<std::string> urls =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-  if (urls.size() != 1) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    exit(0);
-  }
-
-  quic::QuicEpollClientFactory factory;
-  quic::QuicToyClient client(&factory);
-  return client.SendRequestsAndPrintResponses(urls);
-}
diff --git a/quic/tools/quic_client_epoll_network_helper.cc b/quic/tools/quic_client_epoll_network_helper.cc
deleted file mode 100644
index bd184ab..0000000
--- a/quic/tools/quic_client_epoll_network_helper.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client_epoll_network_helper.h"
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_system_event_loop.h"
-
-namespace quic {
-
-namespace {
-const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
-}  // namespace
-
-QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper(
-    QuicEpollServer* epoll_server,
-    QuicClientBase* client)
-    : epoll_server_(epoll_server),
-      packets_dropped_(0),
-      overflow_supported_(false),
-      packet_reader_(new QuicPacketReader()),
-      client_(client),
-      max_reads_per_epoll_loop_(std::numeric_limits<int>::max()) {}
-
-QuicClientEpollNetworkHelper::~QuicClientEpollNetworkHelper() {
-  if (client_->connected()) {
-    client_->session()->connection()->CloseConnection(
-        QUIC_PEER_GOING_AWAY, "Client being torn down",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-  }
-
-  CleanUpAllUDPSockets();
-}
-
-std::string QuicClientEpollNetworkHelper::Name() const {
-  return "QuicClientEpollNetworkHelper";
-}
-
-bool QuicClientEpollNetworkHelper::CreateUDPSocketAndBind(
-    QuicSocketAddress server_address,
-    QuicIpAddress bind_to_address,
-    int bind_to_port) {
-  epoll_server_->set_timeout_in_us(50 * 1000);
-
-  int fd = CreateUDPSocket(server_address, &overflow_supported_);
-  if (fd < 0) {
-    return false;
-  }
-
-  QuicSocketAddress client_address;
-  if (bind_to_address.IsInitialized()) {
-    client_address = QuicSocketAddress(bind_to_address, client_->local_port());
-  } else if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
-    client_address = QuicSocketAddress(QuicIpAddress::Any4(), bind_to_port);
-  } else {
-    client_address = QuicSocketAddress(QuicIpAddress::Any6(), bind_to_port);
-  }
-
-  // Some platforms expect that the addrlen given to bind() exactly matches the
-  // size of the associated protocol family's sockaddr struct.
-  // TODO(b/179430548): Revert this when affected platforms are updated to
-  // to support binding with an addrelen of sizeof(sockaddr_storage)
-  socklen_t addrlen;
-  switch (client_address.host().address_family()) {
-    case IpAddressFamily::IP_V4:
-      addrlen = sizeof(sockaddr_in);
-      break;
-    case IpAddressFamily::IP_V6:
-      addrlen = sizeof(sockaddr_in6);
-      break;
-    case IpAddressFamily::IP_UNSPEC:
-      addrlen = 0;
-      break;
-  }
-
-  sockaddr_storage addr = client_address.generic_address();
-  int rc = bind(fd, reinterpret_cast<sockaddr*>(&addr), addrlen);
-  if (rc < 0) {
-    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno)
-                    << " bind_to_address:" << bind_to_address
-                    << ", bind_to_port:" << bind_to_port
-                    << ", client_address:" << client_address;
-    return false;
-  }
-
-  if (client_address.FromSocket(fd) != 0) {
-    QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
-                    << strerror(errno);
-  }
-
-  fd_address_map_[fd] = client_address;
-  epoll_server_->RegisterFD(fd, this, kEpollFlags);
-  return true;
-}
-
-void QuicClientEpollNetworkHelper::CleanUpUDPSocket(int fd) {
-  CleanUpUDPSocketImpl(fd);
-  fd_address_map_.erase(fd);
-}
-
-void QuicClientEpollNetworkHelper::CleanUpAllUDPSockets() {
-  for (std::pair<int, QuicSocketAddress> fd_address : fd_address_map_) {
-    CleanUpUDPSocketImpl(fd_address.first);
-  }
-  fd_address_map_.clear();
-}
-
-void QuicClientEpollNetworkHelper::CleanUpUDPSocketImpl(int fd) {
-  if (fd > -1) {
-    epoll_server_->UnregisterFD(fd);
-    int rc = close(fd);
-    QUICHE_DCHECK_EQ(0, rc);
-  }
-}
-
-void QuicClientEpollNetworkHelper::RunEventLoop() {
-  quiche::QuicheRunSystemEventLoopIteration();
-  epoll_server_->WaitForEventsAndExecuteCallbacks();
-}
-
-void QuicClientEpollNetworkHelper::OnRegistration(QuicEpollServer* /*eps*/,
-                                                  int /*fd*/,
-                                                  int /*event_mask*/) {}
-void QuicClientEpollNetworkHelper::OnModification(int /*fd*/,
-                                                  int /*event_mask*/) {}
-void QuicClientEpollNetworkHelper::OnUnregistration(int /*fd*/,
-                                                    bool /*replaced*/) {}
-void QuicClientEpollNetworkHelper::OnShutdown(QuicEpollServer* /*eps*/,
-                                              int /*fd*/) {}
-
-void QuicClientEpollNetworkHelper::OnEvent(int fd, QuicEpollEvent* event) {
-  if (event->in_events & EPOLLIN) {
-    QUIC_DVLOG(1) << "Read packets on EPOLLIN";
-    int times_to_read = max_reads_per_epoll_loop_;
-    bool more_to_read = true;
-    QuicPacketCount packets_dropped = 0;
-    while (client_->connected() && more_to_read && times_to_read > 0) {
-      more_to_read = packet_reader_->ReadAndDispatchPackets(
-          fd, GetLatestClientAddress().port(), *client_->helper()->GetClock(),
-          this, overflow_supported_ ? &packets_dropped : nullptr);
-      --times_to_read;
-    }
-    if (packets_dropped_ < packets_dropped) {
-      QUIC_LOG(ERROR)
-          << packets_dropped - packets_dropped_
-          << " more packets are dropped in the socket receive buffer.";
-      packets_dropped_ = packets_dropped;
-    }
-    if (client_->connected() && more_to_read) {
-      event->out_ready_mask |= EPOLLIN;
-    }
-  }
-  if (client_->connected() && (event->in_events & EPOLLOUT)) {
-    client_->writer()->SetWritable();
-    client_->session()->connection()->OnCanWrite();
-  }
-  if (event->in_events & EPOLLERR) {
-    QUIC_DLOG(INFO) << "Epollerr";
-  }
-}
-
-QuicPacketWriter* QuicClientEpollNetworkHelper::CreateQuicPacketWriter() {
-  return new QuicDefaultPacketWriter(GetLatestFD());
-}
-
-void QuicClientEpollNetworkHelper::SetClientPort(int port) {
-  fd_address_map_.back().second =
-      QuicSocketAddress(GetLatestClientAddress().host(), port);
-}
-
-QuicSocketAddress QuicClientEpollNetworkHelper::GetLatestClientAddress() const {
-  if (fd_address_map_.empty()) {
-    return QuicSocketAddress();
-  }
-
-  return fd_address_map_.back().second;
-}
-
-int QuicClientEpollNetworkHelper::GetLatestFD() const {
-  if (fd_address_map_.empty()) {
-    return -1;
-  }
-
-  return fd_address_map_.back().first;
-}
-
-void QuicClientEpollNetworkHelper::ProcessPacket(
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address,
-    const QuicReceivedPacket& packet) {
-  client_->session()->ProcessUdpPacket(self_address, peer_address, packet);
-}
-
-int QuicClientEpollNetworkHelper::CreateUDPSocket(
-    QuicSocketAddress server_address,
-    bool* overflow_supported) {
-  QuicUdpSocketApi api;
-  int fd = api.Create(server_address.host().AddressFamilyToInt(),
-                      /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
-                      /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
-  if (fd < 0) {
-    return fd;
-  }
-
-  *overflow_supported = api.EnableDroppedPacketCount(fd);
-  api.EnableReceiveTimestamp(fd);
-  return fd;
-}
-}  // namespace quic
diff --git a/quic/tools/quic_client_epoll_network_helper.h b/quic/tools/quic_client_epoll_network_helper.h
deleted file mode 100644
index bb8a898..0000000
--- a/quic/tools/quic_client_epoll_network_helper.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// An implementation of the QuicClientBase::NetworkHelper
-// that is based off the epoll server.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_client_base.h"
-#include "common/quiche_linked_hash_map.h"
-
-namespace quic {
-
-namespace test {
-class QuicClientPeer;
-}  // namespace test
-
-// An implementation of the QuicClientBase::NetworkHelper based off
-// the epoll server.
-class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
-                                     public QuicEpollCallbackInterface,
-                                     public ProcessPacketInterface {
- public:
-  // Create a quic client, which will have events managed by an externally owned
-  // EpollServer.
-  QuicClientEpollNetworkHelper(QuicEpollServer* epoll_server,
-                               QuicClientBase* client);
-  QuicClientEpollNetworkHelper(const QuicClientEpollNetworkHelper&) = delete;
-  QuicClientEpollNetworkHelper& operator=(const QuicClientEpollNetworkHelper&) =
-      delete;
-
-  ~QuicClientEpollNetworkHelper() override;
-
-  // Return a name describing the class for use in debug/error reporting.
-  std::string Name() const override;
-
-  // From EpollCallbackInterface
-  void OnRegistration(QuicEpollServer* eps, int fd, int event_mask) override;
-  void OnModification(int fd, int event_mask) override;
-  void OnEvent(int fd, QuicEpollEvent* event) override;
-  // |fd_| can be unregistered without the client being disconnected. This
-  // happens in b3m QuicProber where we unregister |fd_| to feed in events to
-  // the client from the SelectServer.
-  void OnUnregistration(int fd, bool replaced) override;
-  void OnShutdown(QuicEpollServer* eps, int fd) override;
-
-  // From ProcessPacketInterface. This will be called for each received
-  // packet.
-  void ProcessPacket(const QuicSocketAddress& self_address,
-                     const QuicSocketAddress& peer_address,
-                     const QuicReceivedPacket& packet) override;
-
-  // From NetworkHelper.
-  void RunEventLoop() override;
-  bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
-                              QuicIpAddress bind_to_address,
-                              int bind_to_port) override;
-  void CleanUpAllUDPSockets() override;
-  QuicSocketAddress GetLatestClientAddress() const override;
-  QuicPacketWriter* CreateQuicPacketWriter() override;
-
-  // Accessors provided for convenience, not part of any interface.
-
-  QuicEpollServer* epoll_server() { return epoll_server_; }
-
-  const quiche::QuicheLinkedHashMap<int, QuicSocketAddress>& fd_address_map()
-      const {
-    return fd_address_map_;
-  }
-
-  // If the client has at least one UDP socket, return the latest created one.
-  // Otherwise, return -1.
-  int GetLatestFD() const;
-
-  // Create socket for connection to |server_address| with default socket
-  // options.
-  // Return fd index.
-  virtual int CreateUDPSocket(QuicSocketAddress server_address,
-                              bool* overflow_supported);
-
-  QuicClientBase* client() { return client_; }
-
-  void set_max_reads_per_epoll_loop(int num_reads) {
-    max_reads_per_epoll_loop_ = num_reads;
-  }
-  // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
-  // nothing.
-  void CleanUpUDPSocket(int fd);
-
- private:
-  friend class test::QuicClientPeer;
-
-  // Used for testing.
-  void SetClientPort(int port);
-
-  // Actually clean up |fd|.
-  void CleanUpUDPSocketImpl(int fd);
-
-  // Listens for events on the client socket.
-  QuicEpollServer* epoll_server_;
-
-  // Map mapping created UDP sockets to their addresses. By using linked hash
-  // map, the order of socket creation can be recorded.
-  quiche::QuicheLinkedHashMap<int, QuicSocketAddress> fd_address_map_;
-
-  // If overflow_supported_ is true, this will be the number of packets dropped
-  // during the lifetime of the server.
-  QuicPacketCount packets_dropped_;
-
-  // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
-  // because the socket would otherwise overflow.
-  bool overflow_supported_;
-
-  // Point to a QuicPacketReader object on the heap. The reader allocates more
-  // space than allowed on the stack.
-  std::unique_ptr<QuicPacketReader> packet_reader_;
-
-  QuicClientBase* client_;
-
-  int max_reads_per_epoll_loop_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc
deleted file mode 100644
index 7411e12..0000000
--- a/quic/tools/quic_client_interop_test_bin.cc
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/quic_client_session_cache.h"
-#include "quic/core/quic_epoll_clock.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "quic/tools/quic_client.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/platform/api/quiche_system_event_loop.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, host, "",
-                                "The IP or hostname to connect to.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, quic_version, "",
-    "The QUIC version to use. Defaults to most recent IETF QUIC version.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
-
-namespace quic {
-
-enum class Feature {
-  // First row of features ("table stakes")
-  // A version negotiation response is elicited and acted on.
-  kVersionNegotiation,
-  // The handshake completes successfully.
-  kHandshake,
-  // Stream data is being exchanged and ACK'ed.
-  kStreamData,
-  // The connection close procedcure completes with a zero error code.
-  kConnectionClose,
-  // The connection was established using TLS resumption.
-  kResumption,
-  // 0-RTT data is being sent and acted on.
-  kZeroRtt,
-  // A RETRY packet was successfully processed.
-  kRetry,
-  // A handshake using a ClientHello that spans multiple packets completed
-  // successfully.
-  kQuantum,
-
-  // Second row of features (anything else protocol-related)
-  // We switched to a different port and the server migrated to it.
-  kRebinding,
-  // One endpoint can update keys and its peer responds correctly.
-  kKeyUpdate,
-
-  // Third row of features (H3 tests)
-  // An H3 transaction succeeded.
-  kHttp3,
-  // One or both endpoints insert entries into dynamic table and subsequenly
-  // reference them from header blocks.
-  kDynamicEntryReferenced,
-};
-
-char MatrixLetter(Feature f) {
-  switch (f) {
-    case Feature::kVersionNegotiation:
-      return 'V';
-    case Feature::kHandshake:
-      return 'H';
-    case Feature::kStreamData:
-      return 'D';
-    case Feature::kConnectionClose:
-      return 'C';
-    case Feature::kResumption:
-      return 'R';
-    case Feature::kZeroRtt:
-      return 'Z';
-    case Feature::kRetry:
-      return 'S';
-    case Feature::kQuantum:
-      return 'Q';
-    case Feature::kRebinding:
-      return 'B';
-    case Feature::kKeyUpdate:
-      return 'U';
-    case Feature::kHttp3:
-      return '3';
-    case Feature::kDynamicEntryReferenced:
-      return 'd';
-  }
-}
-
-class QuicClientInteropRunner : QuicConnectionDebugVisitor {
- public:
-  QuicClientInteropRunner() {}
-
-  void InsertFeature(Feature feature) { features_.insert(feature); }
-
-  std::set<Feature> features() const { return features_; }
-
-  // Attempts a resumption using |client| by disconnecting and reconnecting. If
-  // resumption is successful, |features_| is modified to add
-  // Feature::kResumption to it, otherwise it is left unmodified.
-  void AttemptResumption(QuicClient* client, const std::string& authority);
-
-  void AttemptRequest(QuicSocketAddress addr,
-                      std::string authority,
-                      QuicServerId server_id,
-                      ParsedQuicVersion version,
-                      bool test_version_negotiation,
-                      bool attempt_rebind,
-                      bool attempt_multi_packet_chlo,
-                      bool attempt_key_update);
-
-  // Constructs a SpdyHeaderBlock containing the pseudo-headers needed to make a
-  // GET request to "/" on the hostname |authority|.
-  spdy::Http2HeaderBlock ConstructHeaderBlock(const std::string& authority);
-
-  // Sends an HTTP request represented by |header_block| using |client|.
-  void SendRequest(QuicClient* client,
-                   const spdy::Http2HeaderBlock& header_block);
-
-  void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
-    switch (frame.close_type) {
-      case GOOGLE_QUIC_CONNECTION_CLOSE:
-        QUIC_LOG(ERROR) << "Received unexpected GoogleQUIC connection close";
-        break;
-      case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
-        if (frame.wire_error_code == NO_IETF_QUIC_ERROR) {
-          InsertFeature(Feature::kConnectionClose);
-        } else {
-          QUIC_LOG(ERROR) << "Received transport connection close "
-                          << QuicIetfTransportErrorCodeString(
-                                 static_cast<QuicIetfTransportErrorCodes>(
-                                     frame.wire_error_code));
-        }
-        break;
-      case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
-        if (frame.wire_error_code == 0) {
-          InsertFeature(Feature::kConnectionClose);
-        } else {
-          QUIC_LOG(ERROR) << "Received application connection close "
-                          << frame.wire_error_code;
-        }
-        break;
-    }
-  }
-
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& /*packet*/) override {
-    InsertFeature(Feature::kVersionNegotiation);
-  }
-
- private:
-  std::set<Feature> features_;
-};
-
-void QuicClientInteropRunner::AttemptResumption(QuicClient* client,
-                                                const std::string& authority) {
-  client->Disconnect();
-  if (!client->Initialize()) {
-    QUIC_LOG(ERROR) << "Failed to reinitialize client";
-    return;
-  }
-  if (!client->Connect()) {
-    return;
-  }
-
-  bool zero_rtt_attempt = !client->session()->OneRttKeysAvailable();
-
-  spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority);
-  SendRequest(client, header_block);
-
-  if (!client->session()->OneRttKeysAvailable()) {
-    return;
-  }
-
-  if (static_cast<QuicCryptoClientStream*>(
-          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
-          ->IsResumption()) {
-    InsertFeature(Feature::kResumption);
-  }
-  if (static_cast<QuicCryptoClientStream*>(
-          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
-          ->EarlyDataAccepted() &&
-      zero_rtt_attempt && client->latest_response_code() != -1) {
-    InsertFeature(Feature::kZeroRtt);
-  }
-}
-
-void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
-                                             std::string authority,
-                                             QuicServerId server_id,
-                                             ParsedQuicVersion version,
-                                             bool test_version_negotiation,
-                                             bool attempt_rebind,
-                                             bool attempt_multi_packet_chlo,
-                                             bool attempt_key_update) {
-  ParsedQuicVersionVector versions = {version};
-  if (test_version_negotiation) {
-    versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
-  }
-
-  auto proof_verifier = std::make_unique<FakeProofVerifier>();
-  auto session_cache = std::make_unique<QuicClientSessionCache>();
-  QuicEpollServer epoll_server;
-  QuicEpollClock epoll_clock(&epoll_server);
-  QuicConfig config;
-  QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(20);
-  config.SetIdleNetworkTimeout(timeout);
-  if (attempt_multi_packet_chlo) {
-    // Make the ClientHello span multiple packets by adding a custom transport
-    // parameter.
-    constexpr auto kCustomParameter =
-        static_cast<TransportParameters::TransportParameterId>(0x173E);
-    std::string custom_value(2000, '?');
-    config.custom_transport_parameters_to_send()[kCustomParameter] =
-        custom_value;
-  }
-  auto client = std::make_unique<QuicClient>(
-      addr, server_id, versions, config, &epoll_server,
-      std::move(proof_verifier), std::move(session_cache));
-  client->set_connection_debug_visitor(this);
-  if (!client->Initialize()) {
-    QUIC_LOG(ERROR) << "Failed to initialize client";
-    return;
-  }
-  const bool connect_result = client->Connect();
-  QuicConnection* connection = client->session()->connection();
-  if (connection == nullptr) {
-    QUIC_LOG(ERROR) << "No QuicConnection object";
-    return;
-  }
-  QuicConnectionStats client_stats = connection->GetStats();
-  if (client_stats.retry_packet_processed) {
-    InsertFeature(Feature::kRetry);
-  }
-  if (test_version_negotiation && connection->version() == version) {
-    InsertFeature(Feature::kVersionNegotiation);
-  }
-  if (test_version_negotiation && !connect_result) {
-    // Failed to negotiate version, retry without version negotiation.
-    AttemptRequest(addr, authority, server_id, version,
-                   /*test_version_negotiation=*/false, attempt_rebind,
-                   attempt_multi_packet_chlo, attempt_key_update);
-    return;
-  }
-  if (!client->session()->OneRttKeysAvailable()) {
-    if (attempt_multi_packet_chlo) {
-      // Failed to handshake with multi-packet client hello, retry without it.
-      AttemptRequest(addr, authority, server_id, version,
-                     test_version_negotiation, attempt_rebind,
-                     /*attempt_multi_packet_chlo=*/false, attempt_key_update);
-      return;
-    }
-    return;
-  }
-  InsertFeature(Feature::kHandshake);
-  if (attempt_multi_packet_chlo) {
-    InsertFeature(Feature::kQuantum);
-  }
-
-  spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority);
-  SendRequest(client.get(), header_block);
-
-  if (!client->connected()) {
-    return;
-  }
-
-  if (client->latest_response_code() != -1) {
-    InsertFeature(Feature::kHttp3);
-
-    if (client->client_session()->dynamic_table_entry_referenced()) {
-      InsertFeature(Feature::kDynamicEntryReferenced);
-    }
-
-    if (attempt_rebind) {
-      // Now make a second request after switching to a different client port.
-      if (client->ChangeEphemeralPort()) {
-        client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
-        if (!client->connected()) {
-          // Rebinding does not work, retry without attempting it.
-          AttemptRequest(addr, authority, server_id, version,
-                         test_version_negotiation, /*attempt_rebind=*/false,
-                         attempt_multi_packet_chlo, attempt_key_update);
-          return;
-        }
-        InsertFeature(Feature::kRebinding);
-
-        if (client->client_session()->dynamic_table_entry_referenced()) {
-          InsertFeature(Feature::kDynamicEntryReferenced);
-        }
-      } else {
-        QUIC_LOG(ERROR) << "Failed to change ephemeral port";
-      }
-    }
-
-    if (attempt_key_update) {
-      if (connection->IsKeyUpdateAllowed()) {
-        if (connection->InitiateKeyUpdate(
-                KeyUpdateReason::kLocalForInteropRunner)) {
-          client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
-          if (!client->connected()) {
-            // Key update does not work, retry without attempting it.
-            AttemptRequest(addr, authority, server_id, version,
-                           test_version_negotiation, attempt_rebind,
-                           attempt_multi_packet_chlo,
-                           /*attempt_key_update=*/false);
-            return;
-          }
-          InsertFeature(Feature::kKeyUpdate);
-        } else {
-          QUIC_LOG(ERROR) << "Failed to initiate key update";
-        }
-      } else {
-        QUIC_LOG(ERROR) << "Key update not allowed";
-      }
-    }
-  }
-
-  if (connection->connected()) {
-    connection->CloseConnection(
-        QUIC_NO_ERROR, "Graceful close",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    InsertFeature(Feature::kConnectionClose);
-  }
-
-  AttemptResumption(client.get(), authority);
-}
-
-spdy::Http2HeaderBlock QuicClientInteropRunner::ConstructHeaderBlock(
-    const std::string& authority) {
-  // Construct and send a request.
-  spdy::Http2HeaderBlock header_block;
-  header_block[":method"] = "GET";
-  header_block[":scheme"] = "https";
-  header_block[":authority"] = authority;
-  header_block[":path"] = "/";
-  return header_block;
-}
-
-void QuicClientInteropRunner::SendRequest(
-    QuicClient* client,
-    const spdy::Http2HeaderBlock& header_block) {
-  client->set_store_response(true);
-  client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
-
-  QuicConnection* connection = client->session()->connection();
-  if (connection == nullptr) {
-    QUIC_LOG(ERROR) << "No QuicConnection object";
-    return;
-  }
-  QuicConnectionStats client_stats = connection->GetStats();
-  QuicSentPacketManager* sent_packet_manager =
-      test::QuicConnectionPeer::GetSentPacketManager(connection);
-  const bool received_forward_secure_ack =
-      sent_packet_manager != nullptr &&
-      sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
-          .IsInitialized();
-  if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
-    InsertFeature(Feature::kStreamData);
-  }
-}
-
-std::set<Feature> ServerSupport(std::string dns_host,
-                                std::string url_host,
-                                int port,
-                                ParsedQuicVersion version) {
-  std::cout << "Attempting interop with version " << version << std::endl;
-
-  // Build the client, and try to connect.
-  QuicSocketAddress addr = tools::LookupAddress(dns_host, absl::StrCat(port));
-  if (!addr.IsInitialized()) {
-    QUIC_LOG(ERROR) << "Failed to resolve " << dns_host;
-    return std::set<Feature>();
-  }
-  QuicServerId server_id(url_host, port, false);
-  std::string authority = absl::StrCat(url_host, ":", port);
-
-  QuicClientInteropRunner runner;
-
-  runner.AttemptRequest(addr, authority, server_id, version,
-                        /*test_version_negotiation=*/true,
-                        /*attempt_rebind=*/true,
-                        /*attempt_multi_packet_chlo=*/true,
-                        /*attempt_key_update=*/true);
-
-  return runner.features();
-}
-
-}  // namespace quic
-
-int main(int argc, char* argv[]) {
-  quiche::QuicheSystemEventLoop event_loop("quic_client");
-  const char* usage = "Usage: quic_client_interop_test [options] [url]";
-
-  std::vector<std::string> args =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-  if (args.size() > 1) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    exit(1);
-  }
-  std::string dns_host = GetQuicFlag(FLAGS_host);
-  std::string url_host = "";
-  int port = GetQuicFlag(FLAGS_port);
-
-  if (!args.empty()) {
-    quic::QuicUrl url(args[0], "https");
-    url_host = url.host();
-    if (dns_host.empty()) {
-      dns_host = url_host;
-    }
-    if (port == 0) {
-      port = url.port();
-    }
-  }
-  if (port == 0) {
-    port = 443;
-  }
-  if (dns_host.empty()) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    exit(1);
-  }
-  if (url_host.empty()) {
-    url_host = dns_host;
-  }
-
-  // Pick QUIC version to use.
-  quic::QuicVersionInitializeSupportForIetfDraft();
-  quic::ParsedQuicVersion version = quic::UnsupportedQuicVersion();
-  std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
-  if (!quic_version_string.empty()) {
-    version = quic::ParseQuicVersionString(quic_version_string);
-  } else {
-    for (const quic::ParsedQuicVersion& vers : quic::AllSupportedVersions()) {
-      // Use the most recent IETF QUIC version.
-      if (vers.HasIetfQuicFrames() && vers.UsesHttp3() && vers.UsesTls()) {
-        version = vers;
-        break;
-      }
-    }
-  }
-  QUICHE_CHECK(version.IsKnown());
-  QuicEnableVersion(version);
-
-  auto supported_features =
-      quic::ServerSupport(dns_host, url_host, port, version);
-  std::cout << "Results for " << url_host << ":" << port << std::endl;
-  int current_row = 1;
-  for (auto feature : supported_features) {
-    if (current_row < 2 && feature >= quic::Feature::kRebinding) {
-      std::cout << std::endl;
-      current_row = 2;
-    }
-    if (current_row < 3 && feature >= quic::Feature::kHttp3) {
-      std::cout << std::endl;
-      current_row = 3;
-    }
-    std::cout << MatrixLetter(feature);
-  }
-  std::cout << std::endl;
-}
diff --git a/quic/tools/quic_client_test.cc b/quic/tools/quic_client_test.cc
deleted file mode 100644
index 945f73c..0000000
--- a/quic/tools/quic_client_test.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_client.h"
-
-#include <dirent.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <utility>
-
-#include "absl/strings/match.h"
-#include "absl/strings/string_view.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_client_peer.h"
-#include "common/quiche_text_utils.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-const char* kPathToFds = "/proc/self/fd";
-
-// Return the value of a symbolic link in |path|, if |path| is not found, return
-// an empty string.
-std::string ReadLink(const std::string& path) {
-  std::string result(PATH_MAX, '\0');
-  ssize_t result_size = readlink(path.c_str(), &result[0], result.size());
-  if (result_size < 0 && errno == ENOENT) {
-    return "";
-  }
-  QUICHE_CHECK(result_size > 0 &&
-               static_cast<size_t>(result_size) < result.size())
-      << "result_size:" << result_size << ", errno:" << errno
-      << ", path:" << path;
-  result.resize(result_size);
-  return result;
-}
-
-// Counts the number of open sockets for the current process.
-size_t NumOpenSocketFDs() {
-  size_t socket_count = 0;
-  dirent* file;
-  std::unique_ptr<DIR, int (*)(DIR*)> fd_directory(opendir(kPathToFds),
-                                                   closedir);
-  while ((file = readdir(fd_directory.get())) != nullptr) {
-    absl::string_view name(file->d_name);
-    if (name == "." || name == "..") {
-      continue;
-    }
-
-    std::string fd_path = ReadLink(absl::StrCat(kPathToFds, "/", name));
-    if (absl::StartsWith(fd_path, "socket:")) {
-      socket_count++;
-    }
-  }
-  return socket_count;
-}
-
-class QuicClientTest : public QuicTest {
- public:
-  QuicClientTest() {
-    // Creates and destroys a single client first which may open persistent
-    // sockets when initializing platform dependencies like certificate
-    // verifier. Future creation of addtional clients will deterministically
-    // open one socket per client.
-    CreateAndInitializeQuicClient();
-  }
-
-  // Creates a new QuicClient and Initializes it on an unused port.
-  // Caller is responsible for deletion.
-  std::unique_ptr<QuicClient> CreateAndInitializeQuicClient() {
-    QuicSocketAddress server_address(QuicSocketAddress(TestLoopback(), 0));
-    QuicServerId server_id("hostname", server_address.port(), false);
-    ParsedQuicVersionVector versions = AllSupportedVersions();
-    auto client = std::make_unique<QuicClient>(
-        server_address, server_id, versions, &epoll_server_,
-        crypto_test_utils::ProofVerifierForTesting());
-    EXPECT_TRUE(client->Initialize());
-    return client;
-  }
-
- private:
-  QuicEpollServer epoll_server_;
-};
-
-TEST_F(QuicClientTest, DoNotLeakSocketFDs) {
-  // Make sure that the QuicClient doesn't leak socket FDs. Doing so could cause
-  // port exhaustion in long running processes which repeatedly create clients.
-
-  // Record the initial number of FDs.
-  size_t number_of_open_fds = NumOpenSocketFDs();
-
-  // Create a number of clients, initialize them, and verify this has resulted
-  // in additional FDs being opened.
-  const int kNumClients = 50;
-  for (int i = 0; i < kNumClients; ++i) {
-    EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
-    std::unique_ptr<QuicClient> client(CreateAndInitializeQuicClient());
-    // Initializing the client will create a new FD.
-    EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
-  }
-
-  // The FDs created by the QuicClients should now be closed.
-  EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
-}
-
-TEST_F(QuicClientTest, CreateAndCleanUpUDPSockets) {
-  size_t number_of_open_fds = NumOpenSocketFDs();
-
-  std::unique_ptr<QuicClient> client(CreateAndInitializeQuicClient());
-  // Creating and initializing a client will result in one socket being opened.
-  EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
-
-  // Create more UDP sockets.
-  EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
-  EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
-  EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
-  EXPECT_EQ(number_of_open_fds + 3, NumOpenSocketFDs());
-
-  // Clean up UDP sockets.
-  QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
-  EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
-  QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
-  EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/quic_epoll_client_factory.cc b/quic/tools/quic_epoll_client_factory.cc
deleted file mode 100644
index 1fff089..0000000
--- a/quic/tools/quic_epoll_client_factory.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_epoll_client_factory.h"
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_client.h"
-
-namespace quic {
-
-std::unique_ptr<QuicSpdyClientBase> QuicEpollClientFactory::CreateClient(
-    std::string host_for_handshake,
-    std::string host_for_lookup,
-    int address_family_for_lookup,
-    uint16_t port,
-    ParsedQuicVersionVector versions,
-    const QuicConfig& config,
-    std::unique_ptr<ProofVerifier> verifier,
-    std::unique_ptr<SessionCache> session_cache) {
-  QuicSocketAddress addr = tools::LookupAddress(
-      address_family_for_lookup, host_for_lookup, absl::StrCat(port));
-  if (!addr.IsInitialized()) {
-    QUIC_LOG(ERROR) << "Unable to resolve address: " << host_for_lookup;
-    return nullptr;
-  }
-  QuicServerId server_id(host_for_handshake, port, false);
-  return std::make_unique<QuicClient>(addr, server_id, versions, config,
-                                      &epoll_server_, std::move(verifier),
-                                      std::move(session_cache));
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_epoll_client_factory.h b/quic/tools/quic_epoll_client_factory.h
deleted file mode 100644
index 9e78b47..0000000
--- a/quic/tools/quic_epoll_client_factory.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
-#define QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
-
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_toy_client.h"
-
-namespace quic {
-
-// Factory creating QuicClient instances.
-class QuicEpollClientFactory : public QuicToyClient::ClientFactory {
- public:
-  std::unique_ptr<QuicSpdyClientBase> CreateClient(
-      std::string host_for_handshake,
-      std::string host_for_lookup,
-      int address_family_for_lookup,
-      uint16_t port,
-      ParsedQuicVersionVector versions,
-      const QuicConfig& config,
-      std::unique_ptr<ProofVerifier> verifier,
-      std::unique_ptr<SessionCache> session_cache) override;
-
- private:
-  QuicEpollServer epoll_server_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
diff --git a/quic/tools/quic_epoll_server_factory.cc b/quic/tools/quic_epoll_server_factory.cc
deleted file mode 100644
index 98c60ae..0000000
--- a/quic/tools/quic_epoll_server_factory.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_epoll_server_factory.h"
-
-#include <utility>
-
-#include "quic/tools/quic_server.h"
-
-namespace quic {
-
-std::unique_ptr<quic::QuicSpdyServerBase> QuicEpollServerFactory::CreateServer(
-    quic::QuicSimpleServerBackend* backend,
-    std::unique_ptr<quic::ProofSource> proof_source,
-    const quic::ParsedQuicVersionVector& supported_versions) {
-  return std::make_unique<quic::QuicServer>(std::move(proof_source), backend,
-                                            supported_versions);
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_epoll_server_factory.h b/quic/tools/quic_epoll_server_factory.h
deleted file mode 100644
index 7fc61fb..0000000
--- a/quic/tools/quic_epoll_server_factory.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
-#define QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
-
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/tools/quic_toy_server.h"
-
-namespace quic {
-
-// Factory creating QuicServer instances.
-class QuicEpollServerFactory : public QuicToyServer::ServerFactory {
- public:
-  std::unique_ptr<QuicSpdyServerBase> CreateServer(
-      QuicSimpleServerBackend* backend,
-      std::unique_ptr<ProofSource> proof_source,
-      const quic::ParsedQuicVersionVector& supported_versions) override;
-
- private:
-  QuicEpollServer epoll_server_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
diff --git a/quic/tools/quic_memory_cache_backend.cc b/quic/tools/quic_memory_cache_backend.cc
deleted file mode 100644
index 19ac29a..0000000
--- a/quic/tools/quic_memory_cache_backend.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_memory_cache_backend.h"
-
-#include <utility>
-
-#include "absl/strings/match.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/web_transport_test_visitors.h"
-#include "common/platform/api/quiche_file_utils.h"
-#include "common/quiche_text_utils.h"
-
-using spdy::Http2HeaderBlock;
-using spdy::kV3LowestPriority;
-
-namespace quic {
-
-QuicMemoryCacheBackend::ResourceFile::ResourceFile(const std::string& file_name)
-    : file_name_(file_name) {}
-
-QuicMemoryCacheBackend::ResourceFile::~ResourceFile() = default;
-
-void QuicMemoryCacheBackend::ResourceFile::Read() {
-  absl::optional<std::string> maybe_file_contents =
-      quiche::ReadFileContents(file_name_);
-  if (!maybe_file_contents) {
-    QUIC_LOG(DFATAL) << "Failed to read file for the memory cache backend: "
-                     << file_name_;
-    return;
-  }
-  file_contents_ = *maybe_file_contents;
-
-  // First read the headers.
-  size_t start = 0;
-  while (start < file_contents_.length()) {
-    size_t pos = file_contents_.find('\n', start);
-    if (pos == std::string::npos) {
-      QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file_name_;
-      return;
-    }
-    size_t len = pos - start;
-    // Support both dos and unix line endings for convenience.
-    if (file_contents_[pos - 1] == '\r') {
-      len -= 1;
-    }
-    absl::string_view line(file_contents_.data() + start, len);
-    start = pos + 1;
-    // Headers end with an empty line.
-    if (line.empty()) {
-      break;
-    }
-    // Extract the status from the HTTP first line.
-    if (line.substr(0, 4) == "HTTP") {
-      pos = line.find(' ');
-      if (pos == std::string::npos) {
-        QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
-                         << file_name_;
-        return;
-      }
-      spdy_headers_[":status"] = line.substr(pos + 1, 3);
-      continue;
-    }
-    // Headers are "key: value".
-    pos = line.find(": ");
-    if (pos == std::string::npos) {
-      QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file_name_;
-      return;
-    }
-    spdy_headers_.AppendValueOrAddHeader(
-        quiche::QuicheTextUtils::ToLower(line.substr(0, pos)),
-        line.substr(pos + 2));
-  }
-
-  // The connection header is prohibited in HTTP/2.
-  spdy_headers_.erase("connection");
-
-  // Override the URL with the X-Original-Url header, if present.
-  auto it = spdy_headers_.find("x-original-url");
-  if (it != spdy_headers_.end()) {
-    x_original_url_ = it->second;
-    HandleXOriginalUrl();
-  }
-
-  // X-Push-URL header is a relatively quick way to support sever push
-  // in the toy server.  A production server should use link=preload
-  // stuff as described in https://w3c.github.io/preload/.
-  it = spdy_headers_.find("x-push-url");
-  if (it != spdy_headers_.end()) {
-    absl::string_view push_urls = it->second;
-    size_t start = 0;
-    while (start < push_urls.length()) {
-      size_t pos = push_urls.find('\0', start);
-      if (pos == std::string::npos) {
-        push_urls_.push_back(absl::string_view(push_urls.data() + start,
-                                               push_urls.length() - start));
-        break;
-      }
-      push_urls_.push_back(absl::string_view(push_urls.data() + start, pos));
-      start += pos + 1;
-    }
-  }
-
-  body_ = absl::string_view(file_contents_.data() + start,
-                            file_contents_.size() - start);
-}
-
-void QuicMemoryCacheBackend::ResourceFile::SetHostPathFromBase(
-    absl::string_view base) {
-  QUICHE_DCHECK(base[0] != '/') << base;
-  size_t path_start = base.find_first_of('/');
-  if (path_start == absl::string_view::npos) {
-    host_ = std::string(base);
-    path_ = "";
-    return;
-  }
-
-  host_ = std::string(base.substr(0, path_start));
-  size_t query_start = base.find_first_of(',');
-  if (query_start > 0) {
-    path_ = std::string(base.substr(path_start, query_start - 1));
-  } else {
-    path_ = std::string(base.substr(path_start));
-  }
-}
-
-absl::string_view QuicMemoryCacheBackend::ResourceFile::RemoveScheme(
-    absl::string_view url) {
-  if (absl::StartsWith(url, "https://")) {
-    url.remove_prefix(8);
-  } else if (absl::StartsWith(url, "http://")) {
-    url.remove_prefix(7);
-  }
-  return url;
-}
-
-void QuicMemoryCacheBackend::ResourceFile::HandleXOriginalUrl() {
-  absl::string_view url(x_original_url_);
-  SetHostPathFromBase(RemoveScheme(url));
-}
-
-const QuicBackendResponse* QuicMemoryCacheBackend::GetResponse(
-    absl::string_view host, absl::string_view path) const {
-  QuicWriterMutexLock lock(&response_mutex_);
-
-  auto it = responses_.find(GetKey(host, path));
-  if (it == responses_.end()) {
-    uint64_t ignored = 0;
-    if (generate_bytes_response_) {
-      if (absl::SimpleAtoi(absl::string_view(path.data() + 1, path.size() - 1),
-                           &ignored)) {
-        // The actual parsed length is ignored here and will be recomputed
-        // by the caller.
-        return generate_bytes_response_.get();
-      }
-    }
-    QUIC_DVLOG(1) << "Get response for resource failed: host " << host
-                  << " path " << path;
-    if (default_response_) {
-      return default_response_.get();
-    }
-    return nullptr;
-  }
-  return it->second.get();
-}
-
-using ServerPushInfo = QuicBackendResponse::ServerPushInfo;
-using SpecialResponseType = QuicBackendResponse::SpecialResponseType;
-
-void QuicMemoryCacheBackend::AddSimpleResponse(absl::string_view host,
-                                               absl::string_view path,
-                                               int response_code,
-                                               absl::string_view body) {
-  Http2HeaderBlock response_headers;
-  response_headers[":status"] = absl::StrCat(response_code);
-  response_headers["content-length"] = absl::StrCat(body.length());
-  AddResponse(host, path, std::move(response_headers), body);
-}
-
-void QuicMemoryCacheBackend::AddSimpleResponseWithServerPushResources(
-    absl::string_view host, absl::string_view path, int response_code,
-    absl::string_view body, std::list<ServerPushInfo> push_resources) {
-  AddSimpleResponse(host, path, response_code, body);
-  MaybeAddServerPushResources(host, path, push_resources);
-}
-
-void QuicMemoryCacheBackend::AddDefaultResponse(QuicBackendResponse* response) {
-  QuicWriterMutexLock lock(&response_mutex_);
-  default_response_.reset(response);
-}
-
-void QuicMemoryCacheBackend::AddResponse(absl::string_view host,
-                                         absl::string_view path,
-                                         Http2HeaderBlock response_headers,
-                                         absl::string_view response_body) {
-  AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
-                  std::move(response_headers), response_body,
-                  Http2HeaderBlock(), std::vector<spdy::Http2HeaderBlock>());
-}
-
-void QuicMemoryCacheBackend::AddResponse(absl::string_view host,
-                                         absl::string_view path,
-                                         Http2HeaderBlock response_headers,
-                                         absl::string_view response_body,
-                                         Http2HeaderBlock response_trailers) {
-  AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
-                  std::move(response_headers), response_body,
-                  std::move(response_trailers),
-                  std::vector<spdy::Http2HeaderBlock>());
-}
-
-void QuicMemoryCacheBackend::AddResponseWithEarlyHints(
-    absl::string_view host, absl::string_view path,
-    spdy::Http2HeaderBlock response_headers, absl::string_view response_body,
-    const std::vector<spdy::Http2HeaderBlock>& early_hints) {
-  AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
-                  std::move(response_headers), response_body,
-                  Http2HeaderBlock(), early_hints);
-}
-
-void QuicMemoryCacheBackend::AddSpecialResponse(
-    absl::string_view host, absl::string_view path,
-    SpecialResponseType response_type) {
-  AddResponseImpl(host, path, response_type, Http2HeaderBlock(), "",
-                  Http2HeaderBlock(), std::vector<spdy::Http2HeaderBlock>());
-}
-
-void QuicMemoryCacheBackend::AddSpecialResponse(
-    absl::string_view host, absl::string_view path,
-    spdy::Http2HeaderBlock response_headers, absl::string_view response_body,
-    SpecialResponseType response_type) {
-  AddResponseImpl(host, path, response_type, std::move(response_headers),
-                  response_body, Http2HeaderBlock(),
-                  std::vector<spdy::Http2HeaderBlock>());
-}
-
-QuicMemoryCacheBackend::QuicMemoryCacheBackend() : cache_initialized_(false) {}
-
-bool QuicMemoryCacheBackend::InitializeBackend(
-    const std::string& cache_directory) {
-  if (cache_directory.empty()) {
-    QUIC_BUG(quic_bug_10932_1) << "cache_directory must not be empty.";
-    return false;
-  }
-  QUIC_LOG(INFO)
-      << "Attempting to initialize QuicMemoryCacheBackend from directory: "
-      << cache_directory;
-  std::vector<std::string> files;
-  if (!quiche::EnumerateDirectoryRecursively(cache_directory, files)) {
-    QUIC_BUG(QuicMemoryCacheBackend unreadable directory)
-        << "Can't read QuicMemoryCacheBackend directory: " << cache_directory;
-    return false;
-  }
-  std::list<std::unique_ptr<ResourceFile>> resource_files;
-  for (const auto& filename : files) {
-    std::unique_ptr<ResourceFile> resource_file(new ResourceFile(filename));
-
-    // Tease apart filename into host and path.
-    std::string base(resource_file->file_name());
-    // Transform windows path separators to URL path separators.
-    for (size_t i = 0; i < base.length(); ++i) {
-      if (base[i] == '\\') {
-        base[i] = '/';
-      }
-    }
-    base.erase(0, cache_directory.length());
-    if (base[0] == '/') {
-      base.erase(0, 1);
-    }
-
-    resource_file->SetHostPathFromBase(base);
-    resource_file->Read();
-
-    AddResponse(resource_file->host(), resource_file->path(),
-                resource_file->spdy_headers().Clone(), resource_file->body());
-
-    resource_files.push_back(std::move(resource_file));
-  }
-
-  for (const auto& resource_file : resource_files) {
-    std::list<ServerPushInfo> push_resources;
-    for (const auto& push_url : resource_file->push_urls()) {
-      QuicUrl url(push_url);
-      const QuicBackendResponse* response = GetResponse(url.host(), url.path());
-      if (!response) {
-        QUIC_BUG(quic_bug_10932_2)
-            << "Push URL '" << push_url << "' not found.";
-        return false;
-      }
-      push_resources.push_back(ServerPushInfo(url, response->headers().Clone(),
-                                              kV3LowestPriority,
-                                              (std::string(response->body()))));
-    }
-    MaybeAddServerPushResources(resource_file->host(), resource_file->path(),
-                                push_resources);
-  }
-
-  cache_initialized_ = true;
-  return true;
-}
-
-void QuicMemoryCacheBackend::GenerateDynamicResponses() {
-  QuicWriterMutexLock lock(&response_mutex_);
-  // Add a generate bytes response.
-  spdy::Http2HeaderBlock response_headers;
-  response_headers[":status"] = "200";
-  generate_bytes_response_ = std::make_unique<QuicBackendResponse>();
-  generate_bytes_response_->set_headers(std::move(response_headers));
-  generate_bytes_response_->set_response_type(
-      QuicBackendResponse::GENERATE_BYTES);
-}
-
-void QuicMemoryCacheBackend::EnableWebTransport() {
-  enable_webtransport_ = true;
-}
-
-bool QuicMemoryCacheBackend::IsBackendInitialized() const {
-  return cache_initialized_;
-}
-
-void QuicMemoryCacheBackend::FetchResponseFromBackend(
-    const Http2HeaderBlock& request_headers,
-    const std::string& /*request_body*/,
-    QuicSimpleServerBackend::RequestHandler* quic_stream) {
-  const QuicBackendResponse* quic_response = nullptr;
-  // Find response in cache. If not found, send error response.
-  auto authority = request_headers.find(":authority");
-  auto path = request_headers.find(":path");
-  if (authority != request_headers.end() && path != request_headers.end()) {
-    quic_response = GetResponse(authority->second, path->second);
-  }
-
-  std::string request_url;
-  if (authority != request_headers.end()) {
-    request_url = std::string(authority->second);
-  }
-  if (path != request_headers.end()) {
-    request_url += std::string(path->second);
-  }
-  QUIC_DVLOG(1)
-      << "Fetching QUIC response from backend in-memory cache for url "
-      << request_url;
-  quic_stream->OnResponseBackendComplete(quic_response);
-}
-
-// The memory cache does not have a per-stream handler
-void QuicMemoryCacheBackend::CloseBackendResponseStream(
-    QuicSimpleServerBackend::RequestHandler* /*quic_stream*/) {}
-
-std::list<ServerPushInfo> QuicMemoryCacheBackend::GetServerPushResources(
-    std::string request_url) {
-  QuicWriterMutexLock lock(&response_mutex_);
-
-  std::list<ServerPushInfo> resources;
-  auto resource_range = server_push_resources_.equal_range(request_url);
-  for (auto it = resource_range.first; it != resource_range.second; ++it) {
-    resources.push_back(it->second);
-  }
-  QUIC_DVLOG(1) << "Found " << resources.size() << " push resources for "
-                << request_url;
-  return resources;
-}
-
-QuicMemoryCacheBackend::WebTransportResponse
-QuicMemoryCacheBackend::ProcessWebTransportRequest(
-    const spdy::Http2HeaderBlock& request_headers,
-    WebTransportSession* session) {
-  if (!SupportsWebTransport()) {
-    return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
-                                                               session);
-  }
-
-  auto path_it = request_headers.find(":path");
-  if (path_it == request_headers.end()) {
-    WebTransportResponse response;
-    response.response_headers[":status"] = "400";
-    return response;
-  }
-  absl::string_view path = path_it->second;
-  if (path == "/echo") {
-    WebTransportResponse response;
-    response.response_headers[":status"] = "200";
-    response.visitor =
-        std::make_unique<EchoWebTransportSessionVisitor>(session);
-    return response;
-  }
-
-  WebTransportResponse response;
-  response.response_headers[":status"] = "404";
-  return response;
-}
-
-QuicMemoryCacheBackend::~QuicMemoryCacheBackend() {
-  {
-    QuicWriterMutexLock lock(&response_mutex_);
-    responses_.clear();
-  }
-}
-
-void QuicMemoryCacheBackend::AddResponseImpl(
-    absl::string_view host, absl::string_view path,
-    SpecialResponseType response_type, Http2HeaderBlock response_headers,
-    absl::string_view response_body, Http2HeaderBlock response_trailers,
-    const std::vector<spdy::Http2HeaderBlock>& early_hints) {
-  QuicWriterMutexLock lock(&response_mutex_);
-
-  QUICHE_DCHECK(!host.empty())
-      << "Host must be populated, e.g. \"www.google.com\"";
-  std::string key = GetKey(host, path);
-  if (responses_.contains(key)) {
-    QUIC_BUG(quic_bug_10932_3)
-        << "Response for '" << key << "' already exists!";
-    return;
-  }
-  auto new_response = std::make_unique<QuicBackendResponse>();
-  new_response->set_response_type(response_type);
-  new_response->set_headers(std::move(response_headers));
-  new_response->set_body(response_body);
-  new_response->set_trailers(std::move(response_trailers));
-  for (auto& headers : early_hints) {
-    new_response->AddEarlyHints(headers);
-  }
-  QUIC_DVLOG(1) << "Add response with key " << key;
-  responses_[key] = std::move(new_response);
-}
-
-std::string QuicMemoryCacheBackend::GetKey(absl::string_view host,
-                                           absl::string_view path) const {
-  std::string host_string = std::string(host);
-  size_t port = host_string.find(':');
-  if (port != std::string::npos)
-    host_string = std::string(host_string.c_str(), port);
-  return host_string + std::string(path);
-}
-
-void QuicMemoryCacheBackend::MaybeAddServerPushResources(
-    absl::string_view request_host, absl::string_view request_path,
-    std::list<ServerPushInfo> push_resources) {
-  std::string request_url = GetKey(request_host, request_path);
-
-  for (const auto& push_resource : push_resources) {
-    if (PushResourceExistsInCache(request_url, push_resource)) {
-      continue;
-    }
-
-    QUIC_DVLOG(1) << "Add request-resource association: request url "
-                  << request_url << " push url "
-                  << push_resource.request_url.ToString()
-                  << " response headers "
-                  << push_resource.headers.DebugString();
-    {
-      QuicWriterMutexLock lock(&response_mutex_);
-      server_push_resources_.insert(std::make_pair(request_url, push_resource));
-    }
-    std::string host = push_resource.request_url.host();
-    if (host.empty()) {
-      host = std::string(request_host);
-    }
-    std::string path = push_resource.request_url.path();
-    bool found_existing_response = false;
-    {
-      QuicWriterMutexLock lock(&response_mutex_);
-      found_existing_response = responses_.contains(GetKey(host, path));
-    }
-    if (!found_existing_response) {
-      // Add a server push response to responses map, if it is not in the map.
-      absl::string_view body = push_resource.body;
-      QUIC_DVLOG(1) << "Add response for push resource: host " << host
-                    << " path " << path;
-      AddResponse(host, path, push_resource.headers.Clone(), body);
-    }
-  }
-}
-
-bool QuicMemoryCacheBackend::PushResourceExistsInCache(
-    std::string original_request_url, ServerPushInfo resource) {
-  QuicWriterMutexLock lock(&response_mutex_);
-  auto resource_range =
-      server_push_resources_.equal_range(original_request_url);
-  for (auto it = resource_range.first; it != resource_range.second; ++it) {
-    ServerPushInfo push_resource = it->second;
-    if (push_resource.request_url.ToString() ==
-        resource.request_url.ToString()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_memory_cache_backend.h b/quic/tools/quic_memory_cache_backend.h
deleted file mode 100644
index 72c5784..0000000
--- a/quic/tools/quic_memory_cache_backend.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
-#define QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_mutex.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_url.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-// In-memory cache for HTTP responses.
-// Reads from disk cache generated by:
-// `wget -p --save_headers <url>`
-class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
- public:
-  // Class to manage loading a resource file into memory.  There are
-  // two uses: called by InitializeBackend to load resources
-  // from files, and recursively called when said resources specify
-  // server push associations.
-  class ResourceFile {
-   public:
-    explicit ResourceFile(const std::string& file_name);
-    ResourceFile(const ResourceFile&) = delete;
-    ResourceFile& operator=(const ResourceFile&) = delete;
-    virtual ~ResourceFile();
-
-    void Read();
-
-    // |base| is |file_name_| with |cache_directory| prefix stripped.
-    void SetHostPathFromBase(absl::string_view base);
-
-    const std::string& file_name() { return file_name_; }
-
-    absl::string_view host() { return host_; }
-
-    absl::string_view path() { return path_; }
-
-    const spdy::Http2HeaderBlock& spdy_headers() { return spdy_headers_; }
-
-    absl::string_view body() { return body_; }
-
-    const std::vector<absl::string_view>& push_urls() { return push_urls_; }
-
-   private:
-    void HandleXOriginalUrl();
-    absl::string_view RemoveScheme(absl::string_view url);
-
-    std::string file_name_;
-    std::string file_contents_;
-    absl::string_view body_;
-    spdy::Http2HeaderBlock spdy_headers_;
-    absl::string_view x_original_url_;
-    std::vector<absl::string_view> push_urls_;
-    std::string host_;
-    std::string path_;
-  };
-
-  QuicMemoryCacheBackend();
-  QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete;
-  QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete;
-  ~QuicMemoryCacheBackend() override;
-
-  // Retrieve a response from this cache for a given host and path..
-  // If no appropriate response exists, nullptr is returned.
-  const QuicBackendResponse* GetResponse(absl::string_view host,
-                                         absl::string_view path) const;
-
-  // Adds a simple response to the cache.  The response headers will
-  // only contain the "content-length" header with the length of |body|.
-  void AddSimpleResponse(absl::string_view host,
-                         absl::string_view path,
-                         int response_code,
-                         absl::string_view body);
-
-  // Add a simple response to the cache as AddSimpleResponse() does, and add
-  // some server push resources(resource path, corresponding response status and
-  // path) associated with it.
-  // Push resource implicitly come from the same host.
-  // TODO(b/171463363): Remove.
-  void AddSimpleResponseWithServerPushResources(
-      absl::string_view host,
-      absl::string_view path,
-      int response_code,
-      absl::string_view body,
-      std::list<QuicBackendResponse::ServerPushInfo> push_resources);
-
-  // Add a response to the cache.
-  void AddResponse(absl::string_view host,
-                   absl::string_view path,
-                   spdy::Http2HeaderBlock response_headers,
-                   absl::string_view response_body);
-
-  // Add a response, with trailers, to the cache.
-  void AddResponse(absl::string_view host,
-                   absl::string_view path,
-                   spdy::Http2HeaderBlock response_headers,
-                   absl::string_view response_body,
-                   spdy::Http2HeaderBlock response_trailers);
-
-  // Add a response, with 103 Early Hints, to the cache.
-  void AddResponseWithEarlyHints(
-      absl::string_view host,
-      absl::string_view path,
-      spdy::Http2HeaderBlock response_headers,
-      absl::string_view response_body,
-      const std::vector<spdy::Http2HeaderBlock>& early_hints);
-
-  // Simulate a special behavior at a particular path.
-  void AddSpecialResponse(
-      absl::string_view host,
-      absl::string_view path,
-      QuicBackendResponse::SpecialResponseType response_type);
-
-  void AddSpecialResponse(
-      absl::string_view host,
-      absl::string_view path,
-      spdy::Http2HeaderBlock response_headers,
-      absl::string_view response_body,
-      QuicBackendResponse::SpecialResponseType response_type);
-
-  // Sets a default response in case of cache misses.  Takes ownership of
-  // 'response'.
-  void AddDefaultResponse(QuicBackendResponse* response);
-
-  // Once called, URLs which have a numeric path will send a dynamically
-  // generated response of that many bytes.
-  void GenerateDynamicResponses();
-
-  void EnableWebTransport();
-
-  // Find all the server push resources associated with |request_url|.
-  // TODO(b/171463363): Remove.
-  std::list<QuicBackendResponse::ServerPushInfo> GetServerPushResources(
-      std::string request_url);
-
-  // Implements the functions for interface QuicSimpleServerBackend
-  // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
-  bool InitializeBackend(const std::string& cache_directory) override;
-  bool IsBackendInitialized() const override;
-  void FetchResponseFromBackend(
-      const spdy::Http2HeaderBlock& request_headers,
-      const std::string& request_body,
-      QuicSimpleServerBackend::RequestHandler* quic_stream) override;
-  void CloseBackendResponseStream(
-      QuicSimpleServerBackend::RequestHandler* quic_stream) override;
-  WebTransportResponse ProcessWebTransportRequest(
-      const spdy::Http2HeaderBlock& request_headers,
-      WebTransportSession* session) override;
-  bool SupportsWebTransport() override { return enable_webtransport_; }
-
- private:
-  void AddResponseImpl(absl::string_view host,
-                       absl::string_view path,
-                       QuicBackendResponse::SpecialResponseType response_type,
-                       spdy::Http2HeaderBlock response_headers,
-                       absl::string_view response_body,
-                       spdy::Http2HeaderBlock response_trailers,
-                       const std::vector<spdy::Http2HeaderBlock>& early_hints);
-
-  std::string GetKey(absl::string_view host, absl::string_view path) const;
-
-  // Add some server push urls with given responses for specified
-  // request if these push resources are not associated with this request yet.
-  // TODO(b/171463363): Remove.
-  void MaybeAddServerPushResources(
-      absl::string_view request_host,
-      absl::string_view request_path,
-      std::list<QuicBackendResponse::ServerPushInfo> push_resources);
-
-  // Check if push resource(push_host/push_path) associated with given request
-  // url already exists in server push map.
-  // TODO(b/171463363): Remove.
-  bool PushResourceExistsInCache(std::string original_request_url,
-                                 QuicBackendResponse::ServerPushInfo resource);
-
-  // Cached responses.
-  absl::flat_hash_map<std::string, std::unique_ptr<QuicBackendResponse>>
-      responses_ QUIC_GUARDED_BY(response_mutex_);
-
-  // The default response for cache misses, if set.
-  std::unique_ptr<QuicBackendResponse> default_response_
-      QUIC_GUARDED_BY(response_mutex_);
-
-  // The generate bytes response, if set.
-  std::unique_ptr<QuicBackendResponse> generate_bytes_response_
-      QUIC_GUARDED_BY(response_mutex_);
-
-  // A map from request URL to associated server push responses (if any).
-  // TODO(b/171463363): Remove.
-  std::multimap<std::string, QuicBackendResponse::ServerPushInfo>
-      server_push_resources_ QUIC_GUARDED_BY(response_mutex_);
-
-  // Protects against concurrent access from test threads setting responses, and
-  // server threads accessing those responses.
-  mutable QuicMutex response_mutex_;
-  bool cache_initialized_;
-
-  bool enable_webtransport_ = false;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
diff --git a/quic/tools/quic_memory_cache_backend_test.cc b/quic/tools/quic_memory_cache_backend_test.cc
deleted file mode 100644
index 79dac6b..0000000
--- a/quic/tools/quic_memory_cache_backend_test.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_memory_cache_backend.h"
-
-#include <vector>
-
-#include "absl/strings/match.h"
-#include "absl/strings/str_cat.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/tools/quic_backend_response.h"
-#include "common/platform/api/quiche_file_utils.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-using Response = QuicBackendResponse;
-using ServerPushInfo = QuicBackendResponse::ServerPushInfo;
-}  // namespace
-
-class QuicMemoryCacheBackendTest : public QuicTest {
- protected:
-  void CreateRequest(std::string host, std::string path,
-                     spdy::Http2HeaderBlock* headers) {
-    (*headers)[":method"] = "GET";
-    (*headers)[":path"] = path;
-    (*headers)[":authority"] = host;
-    (*headers)[":scheme"] = "https";
-  }
-
-  std::string CacheDirectory() { return QuicGetTestMemoryCachePath(); }
-
-  QuicMemoryCacheBackend cache_;
-};
-
-TEST_F(QuicMemoryCacheBackendTest, GetResponseNoMatch) {
-  const Response* response =
-      cache_.GetResponse("mail.google.com", "/index.html");
-  ASSERT_FALSE(response);
-}
-
-TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseGetResponse) {
-  std::string response_body("hello response");
-  cache_.AddSimpleResponse("www.google.com", "/", 200, response_body);
-
-  spdy::Http2HeaderBlock request_headers;
-  CreateRequest("www.google.com", "/", &request_headers);
-  const Response* response = cache_.GetResponse("www.google.com", "/");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("200", response->headers().find(":status")->second);
-  EXPECT_EQ(response_body.size(), response->body().length());
-}
-
-TEST_F(QuicMemoryCacheBackendTest, AddResponse) {
-  const std::string kRequestHost = "www.foo.com";
-  const std::string kRequestPath = "/";
-  const std::string kResponseBody("hello response");
-
-  spdy::Http2HeaderBlock response_headers;
-  response_headers[":status"] = "200";
-  response_headers["content-length"] = absl::StrCat(kResponseBody.size());
-
-  spdy::Http2HeaderBlock response_trailers;
-  response_trailers["key-1"] = "value-1";
-  response_trailers["key-2"] = "value-2";
-  response_trailers["key-3"] = "value-3";
-
-  cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody,
-                     response_trailers.Clone());
-
-  const Response* response = cache_.GetResponse(kRequestHost, kRequestPath);
-  EXPECT_EQ(response->headers(), response_headers);
-  EXPECT_EQ(response->body(), kResponseBody);
-  EXPECT_EQ(response->trailers(), response_trailers);
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_ReadsCacheDir DISABLED_ReadsCacheDir
-#else
-#define MAYBE_ReadsCacheDir ReadsCacheDir
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDir) {
-  cache_.InitializeBackend(CacheDirectory());
-  const Response* response =
-      cache_.GetResponse("test.example.com", "/index.html");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("200", response->headers().find(":status")->second);
-  // Connection headers are not valid in HTTP/2.
-  EXPECT_FALSE(response->headers().contains("connection"));
-  EXPECT_LT(0U, response->body().length());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_ReadsCacheDirWithServerPushResource \
-  DISABLED_ReadsCacheDirWithServerPushResource
-#else
-#define MAYBE_ReadsCacheDirWithServerPushResource \
-  ReadsCacheDirWithServerPushResource
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDirWithServerPushResource) {
-  cache_.InitializeBackend(CacheDirectory() + "_with_push");
-  std::list<ServerPushInfo> resources =
-      cache_.GetServerPushResources("test.example.com/");
-  ASSERT_EQ(1UL, resources.size());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_ReadsCacheDirWithServerPushResources \
-  DISABLED_ReadsCacheDirWithServerPushResources
-#else
-#define MAYBE_ReadsCacheDirWithServerPushResources \
-  ReadsCacheDirWithServerPushResources
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDirWithServerPushResources) {
-  cache_.InitializeBackend(CacheDirectory() + "_with_push");
-  std::list<ServerPushInfo> resources =
-      cache_.GetServerPushResources("test.example.com/index2.html");
-  ASSERT_EQ(2UL, resources.size());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_UsesOriginalUrl DISABLED_UsesOriginalUrl
-#else
-#define MAYBE_UsesOriginalUrl UsesOriginalUrl
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrl) {
-  cache_.InitializeBackend(CacheDirectory());
-  const Response* response =
-      cache_.GetResponse("test.example.com", "/site_map.html");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("200", response->headers().find(":status")->second);
-  // Connection headers are not valid in HTTP/2.
-  EXPECT_FALSE(response->headers().contains("connection"));
-  EXPECT_LT(0U, response->body().length());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_UsesOriginalUrlOnly DISABLED_UsesOriginalUrlOnly
-#else
-#define MAYBE_UsesOriginalUrlOnly UsesOriginalUrlOnly
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrlOnly) {
-  // Tests that if the URL cannot be inferred correctly from the path
-  // because the directory does not include the hostname, that the
-  // X-Original-Url header's value will be used.
-  std::string dir;
-  std::string path = "map.html";
-  std::vector<std::string> files;
-  ASSERT_TRUE(quiche::EnumerateDirectoryRecursively(CacheDirectory(), files));
-  for (const std::string& file : files) {
-    if (absl::EndsWithIgnoreCase(file, "map.html")) {
-      dir = file;
-      dir.erase(dir.length() - path.length() - 1);
-      break;
-    }
-  }
-  ASSERT_NE("", dir);
-
-  cache_.InitializeBackend(dir);
-  const Response* response =
-      cache_.GetResponse("test.example.com", "/site_map.html");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("200", response->headers().find(":status")->second);
-  // Connection headers are not valid in HTTP/2.
-  EXPECT_FALSE(response->headers().contains("connection"));
-  EXPECT_LT(0U, response->body().length());
-}
-
-TEST_F(QuicMemoryCacheBackendTest, DefaultResponse) {
-  // Verify GetResponse returns nullptr when no default is set.
-  const Response* response = cache_.GetResponse("www.google.com", "/");
-  ASSERT_FALSE(response);
-
-  // Add a default response.
-  spdy::Http2HeaderBlock response_headers;
-  response_headers[":status"] = "200";
-  response_headers["content-length"] = "0";
-  Response* default_response = new Response;
-  default_response->set_headers(std::move(response_headers));
-  cache_.AddDefaultResponse(default_response);
-
-  // Now we should get the default response for the original request.
-  response = cache_.GetResponse("www.google.com", "/");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("200", response->headers().find(":status")->second);
-
-  // Now add a set response for / and make sure it is returned
-  cache_.AddSimpleResponse("www.google.com", "/", 302, "");
-  response = cache_.GetResponse("www.google.com", "/");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("302", response->headers().find(":status")->second);
-
-  // We should get the default response for other requests.
-  response = cache_.GetResponse("www.google.com", "/asd");
-  ASSERT_TRUE(response);
-  ASSERT_TRUE(response->headers().contains(":status"));
-  EXPECT_EQ("200", response->headers().find(":status")->second);
-}
-
-TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseWithServerPushResources) {
-  std::string request_host = "www.foo.com";
-  std::string response_body("hello response");
-  const size_t kNumResources = 5;
-  int NumResources = 5;
-  std::list<ServerPushInfo> push_resources;
-  std::string scheme = "http";
-  for (int i = 0; i < NumResources; ++i) {
-    std::string path = absl::StrCat("/server_push_src", i);
-    std::string url = scheme + "://" + request_host + path;
-    QuicUrl resource_url(url);
-    std::string body =
-        absl::StrCat("This is server push response body for ", path);
-    spdy::Http2HeaderBlock response_headers;
-    response_headers[":status"] = "200";
-    response_headers["content-length"] = absl::StrCat(body.size());
-    push_resources.push_back(
-        ServerPushInfo(resource_url, response_headers.Clone(), i, body));
-  }
-
-  cache_.AddSimpleResponseWithServerPushResources(
-      request_host, "/", 200, response_body, push_resources);
-
-  std::string request_url = request_host + "/";
-  std::list<ServerPushInfo> resources =
-      cache_.GetServerPushResources(request_url);
-  ASSERT_EQ(kNumResources, resources.size());
-  for (const auto& push_resource : push_resources) {
-    ServerPushInfo resource = resources.front();
-    EXPECT_EQ(resource.request_url.ToString(),
-              push_resource.request_url.ToString());
-    EXPECT_EQ(resource.priority, push_resource.priority);
-    resources.pop_front();
-  }
-}
-
-TEST_F(QuicMemoryCacheBackendTest, GetServerPushResourcesAndPushResponses) {
-  std::string request_host = "www.foo.com";
-  std::string response_body("hello response");
-  const size_t kNumResources = 4;
-  int NumResources = 4;
-  std::string scheme = "http";
-  std::string push_response_status[kNumResources] = {"200", "200", "301",
-                                                     "404"};
-  std::list<ServerPushInfo> push_resources;
-  for (int i = 0; i < NumResources; ++i) {
-    std::string path = absl::StrCat("/server_push_src", i);
-    std::string url = scheme + "://" + request_host + path;
-    QuicUrl resource_url(url);
-    std::string body = "This is server push response body for " + path;
-    spdy::Http2HeaderBlock response_headers;
-    response_headers[":status"] = push_response_status[i];
-    response_headers["content-length"] = absl::StrCat(body.size());
-    push_resources.push_back(
-        ServerPushInfo(resource_url, response_headers.Clone(), i, body));
-  }
-  cache_.AddSimpleResponseWithServerPushResources(
-      request_host, "/", 200, response_body, push_resources);
-  std::string request_url = request_host + "/";
-  std::list<ServerPushInfo> resources =
-      cache_.GetServerPushResources(request_url);
-  ASSERT_EQ(kNumResources, resources.size());
-  int i = 0;
-  for (const auto& push_resource : push_resources) {
-    QuicUrl url = resources.front().request_url;
-    std::string host = url.host();
-    std::string path = url.path();
-    const Response* response = cache_.GetResponse(host, path);
-    ASSERT_TRUE(response);
-    ASSERT_TRUE(response->headers().contains(":status"));
-    EXPECT_EQ(push_response_status[i++],
-              response->headers().find(":status")->second);
-    EXPECT_EQ(push_resource.body, response->body());
-    resources.pop_front();
-  }
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/quic_packet_printer_bin.cc b/quic/tools/quic_packet_printer_bin.cc
deleted file mode 100644
index 8ffae27..0000000
--- a/quic/tools/quic_packet_printer_bin.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// clang-format off
-
-// Dumps out the decryptable contents of a QUIC packet in a human-readable way.
-// If the packet is null encrypted, this will dump full packet contents.
-// Otherwise it will dump the header, and fail with an error that the
-// packet is undecryptable.
-//
-// Usage: quic_packet_printer server|client <hex dump of packet>
-//
-// Example input:
-// quic_packet_printer server 0c6b810308320f24c004a939a38a2e3fd6ca589917f200400201b80b0100501c0700060003023d0000001c00556e656e637279707465642073747265616d2064617461207365656e
-//
-// Example output:
-// OnPacket
-// OnUnauthenticatedPublicHeader
-// OnUnauthenticatedHeader: { connection_id: 13845207862000976235, connection_id_length:8, packet_number_length:1, multipath_flag: 0, reset_flag: 0, version_flag: 0, path_id: , packet_number: 4 }
-// OnDecryptedPacket
-// OnPacketHeader
-// OnAckFrame:  largest_observed: 1 ack_delay_time: 3000 missing_packets: [  ] is_truncated: 0 received_packets: [ 1 at 466016  ]
-// OnStopWaitingFrame
-// OnConnectionCloseFrame: error_code { 61 } error_details { Unencrypted stream data seen }
-
-// clang-format on
-
-#include <iostream>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/quiche_text_utils.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, quic_version, "",
-                                "If set, specify the QUIC version to use.");
-
-namespace quic {
-
-class QuicPacketPrinter : public QuicFramerVisitorInterface {
- public:
-  explicit QuicPacketPrinter(QuicFramer* framer) : framer_(framer) {}
-
-  void OnError(QuicFramer* framer) override {
-    std::cerr << "OnError: " << QuicErrorCodeToString(framer->error())
-              << " detail: " << framer->detailed_error() << "\n";
-  }
-  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
-    framer_->set_version(received_version);
-    std::cerr << "OnProtocolVersionMismatch: "
-              << ParsedQuicVersionToString(received_version) << "\n";
-    return true;
-  }
-  void OnPacket() override { std::cerr << "OnPacket\n"; }
-  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {
-    std::cerr << "OnPublicResetPacket\n";
-  }
-  void OnVersionNegotiationPacket(
-      const QuicVersionNegotiationPacket& /*packet*/) override {
-    std::cerr << "OnVersionNegotiationPacket\n";
-  }
-  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
-                     QuicConnectionId /*new_connection_id*/,
-                     absl::string_view /*retry_token*/,
-                     absl::string_view /*retry_integrity_tag*/,
-                     absl::string_view /*retry_without_tag*/) override {
-    std::cerr << "OnRetryPacket\n";
-  }
-  bool OnUnauthenticatedPublicHeader(
-      const QuicPacketHeader& /*header*/) override {
-    std::cerr << "OnUnauthenticatedPublicHeader\n";
-    return true;
-  }
-  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
-    std::cerr << "OnUnauthenticatedHeader: " << header;
-    return true;
-  }
-  void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
-    // This only currently supports "decrypting" null encrypted packets.
-    QUICHE_DCHECK_EQ(ENCRYPTION_INITIAL, level);
-    std::cerr << "OnDecryptedPacket\n";
-  }
-  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
-    std::cerr << "OnPacketHeader\n";
-    return true;
-  }
-  void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {
-    std::cerr << "OnCoalescedPacket\n";
-  }
-  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
-                             EncryptionLevel /*decryption_level*/,
-                             bool /*has_decryption_key*/) override {
-    std::cerr << "OnUndecryptablePacket\n";
-  }
-  bool OnStreamFrame(const QuicStreamFrame& frame) override {
-    std::cerr << "OnStreamFrame: " << frame;
-    std::cerr << "         data: { "
-              << absl::BytesToHexString(
-                     absl::string_view(frame.data_buffer, frame.data_length))
-              << " }\n";
-    return true;
-  }
-  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
-    std::cerr << "OnCryptoFrame: " << frame;
-    std::cerr << "         data: { "
-              << absl::BytesToHexString(
-                     absl::string_view(frame.data_buffer, frame.data_length))
-              << " }\n";
-    return true;
-  }
-  bool OnAckFrameStart(QuicPacketNumber largest_acked,
-                       QuicTime::Delta /*ack_delay_time*/) override {
-    std::cerr << "OnAckFrameStart, largest_acked: " << largest_acked;
-    return true;
-  }
-  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
-    std::cerr << "OnAckRange: [" << start << ", " << end << ")";
-    return true;
-  }
-  bool OnAckTimestamp(QuicPacketNumber packet_number,
-                      QuicTime timestamp) override {
-    std::cerr << "OnAckTimestamp: [" << packet_number << ", "
-              << timestamp.ToDebuggingValue() << ")";
-    return true;
-  }
-  bool OnAckFrameEnd(QuicPacketNumber start) override {
-    std::cerr << "OnAckFrameEnd, start: " << start;
-    return true;
-  }
-  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
-    std::cerr << "OnStopWaitingFrame: " << frame;
-    return true;
-  }
-  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
-    std::cerr << "OnPaddingFrame: " << frame;
-    return true;
-  }
-  bool OnPingFrame(const QuicPingFrame& frame) override {
-    std::cerr << "OnPingFrame: " << frame;
-    return true;
-  }
-  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
-    std::cerr << "OnRstStreamFrame: " << frame;
-    return true;
-  }
-  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
-    // The frame printout will indicate whether it's a Google QUIC
-    // CONNECTION_CLOSE, IETF QUIC CONNECTION_CLOSE/Transport, or IETF QUIC
-    // CONNECTION_CLOSE/Application frame.
-    std::cerr << "OnConnectionCloseFrame: " << frame;
-    return true;
-  }
-  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
-    std::cerr << "OnNewConnectionIdFrame: " << frame;
-    return true;
-  }
-  bool OnRetireConnectionIdFrame(
-      const QuicRetireConnectionIdFrame& frame) override {
-    std::cerr << "OnRetireConnectionIdFrame: " << frame;
-    return true;
-  }
-  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
-    std::cerr << "OnNewTokenFrame: " << frame;
-    return true;
-  }
-  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
-    std::cerr << "OnStopSendingFrame: " << frame;
-    return true;
-  }
-  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
-    std::cerr << "OnPathChallengeFrame: " << frame;
-    return true;
-  }
-  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
-    std::cerr << "OnPathResponseFrame: " << frame;
-    return true;
-  }
-  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
-    std::cerr << "OnGoAwayFrame: " << frame;
-    return true;
-  }
-  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
-    std::cerr << "OnMaxStreamsFrame: " << frame;
-    return true;
-  }
-  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
-    std::cerr << "OnStreamsBlockedFrame: " << frame;
-    return true;
-  }
-  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
-    std::cerr << "OnWindowUpdateFrame: " << frame;
-    return true;
-  }
-  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
-    std::cerr << "OnBlockedFrame: " << frame;
-    return true;
-  }
-  bool OnMessageFrame(const QuicMessageFrame& frame) override {
-    std::cerr << "OnMessageFrame: " << frame;
-    return true;
-  }
-  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
-    std::cerr << "OnHandshakeDoneFrame: " << frame;
-    return true;
-  }
-  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
-    std::cerr << "OnAckFrequencyFrame: " << frame;
-    return true;
-  }
-  void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
-  bool IsValidStatelessResetToken(
-      const StatelessResetToken& /*token*/) const override {
-    std::cerr << "IsValidStatelessResetToken\n";
-    return false;
-  }
-  void OnAuthenticatedIetfStatelessResetPacket(
-      const QuicIetfStatelessResetPacket& /*packet*/) override {
-    std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n";
-  }
-  void OnKeyUpdate(KeyUpdateReason reason) override {
-    std::cerr << "OnKeyUpdate: " << reason << "\n";
-  }
-  void OnDecryptedFirstPacketInKeyPhase() override {
-    std::cerr << "OnDecryptedFirstPacketInKeyPhase\n";
-  }
-  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
-      override {
-    std::cerr << "AdvanceKeysAndCreateCurrentOneRttDecrypter\n";
-    return nullptr;
-  }
-  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
-    std::cerr << "CreateCurrentOneRttEncrypter\n";
-    return nullptr;
-  }
-
- private:
-  QuicFramer* framer_;  // Unowned.
-};
-
-}  // namespace quic
-
-int main(int argc, char* argv[]) {
-  const char* usage = "Usage: quic_packet_printer client|server <hex>";
-  std::vector<std::string> args =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-
-  if (args.size() < 2) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    return 1;
-  }
-
-  std::string perspective_string = args[0];
-  quic::Perspective perspective;
-  if (perspective_string == "client") {
-    perspective = quic::Perspective::IS_CLIENT;
-  } else if (perspective_string == "server") {
-    perspective = quic::Perspective::IS_SERVER;
-  } else {
-    std::cerr << "Invalid perspective" << std::endl;
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    return 1;
-  }
-  std::string hex = absl::HexStringToBytes(args[1]);
-  quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
-  // Fake a time since we're not actually generating acks.
-  quic::QuicTime start(quic::QuicTime::Zero());
-  quic::QuicFramer framer(versions, start, perspective,
-                          quic::kQuicDefaultConnectionIdLength);
-  const quic::ParsedQuicVersion& version =
-      quic::ParseQuicVersionString(GetQuicFlag(FLAGS_quic_version));
-  if (version != quic::ParsedQuicVersion::Unsupported()) {
-    framer.set_version(version);
-  }
-  quic::QuicPacketPrinter visitor(&framer);
-  framer.set_visitor(&visitor);
-  quic::QuicEncryptedPacket encrypted(hex.c_str(), hex.length());
-  return framer.ProcessPacket(encrypted);
-}
diff --git a/quic/tools/quic_reject_reason_decoder_bin.cc b/quic/tools/quic_reject_reason_decoder_bin.cc
deleted file mode 100644
index ed83d27..0000000
--- a/quic/tools/quic_reject_reason_decoder_bin.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Decodes the packet HandshakeFailureReason from the chromium histogram
-// Net.QuicClientHelloRejectReasons
-
-#include <iostream>
-
-#include "absl/strings/numbers.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/crypto_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/quiche_text_utils.h"
-
-using quic::CryptoUtils;
-using quic::HandshakeFailureReason;
-using quic::MAX_FAILURE_REASON;
-
-int main(int argc, char* argv[]) {
-  const char* usage = "Usage: quic_reject_reason_decoder <packed_reason>";
-  std::vector<std::string> args =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-
-  if (args.size() != 1) {
-    std::cerr << usage << std::endl;
-    return 1;
-  }
-
-  uint32_t packed_error = 0;
-  if (!absl::SimpleAtoi(args[0], &packed_error)) {
-    std::cerr << "Unable to parse: " << args[0] << "\n";
-    return 2;
-  }
-
-  for (int i = 1; i < MAX_FAILURE_REASON; ++i) {
-    if ((packed_error & (1 << (i - 1))) == 0) {
-      continue;
-    }
-    HandshakeFailureReason reason = static_cast<HandshakeFailureReason>(i);
-    std::cout << CryptoUtils::HandshakeFailureReasonToString(reason) << "\n";
-  }
-  return 0;
-}
diff --git a/quic/tools/quic_server.cc b/quic/tools/quic_server.cc
deleted file mode 100644
index 743eaaf..0000000
--- a/quic/tools/quic_server.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_server.h"
-
-#include <errno.h>
-#include <features.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-
-#include <cstdint>
-#include <memory>
-
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_crypto_stream.h"
-#include "quic/core/quic_data_reader.h"
-#include "quic/core/quic_default_packet_writer.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_clock.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_packet_reader.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-#include "quic/tools/quic_simple_dispatcher.h"
-#include "quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-
-namespace {
-
-const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
-const char kSourceAddressTokenSecret[] = "secret";
-
-}  // namespace
-
-const size_t kNumSessionsToCreatePerSocketEvent = 16;
-
-QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
-                       QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicServer(std::move(proof_source),
-                 quic_simple_server_backend,
-                 AllSupportedVersions()) {}
-
-QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
-                       QuicSimpleServerBackend* quic_simple_server_backend,
-                       const ParsedQuicVersionVector& supported_versions)
-    : QuicServer(std::move(proof_source),
-                 QuicConfig(),
-                 QuicCryptoServerConfig::ConfigOptions(),
-                 supported_versions,
-                 quic_simple_server_backend,
-                 kQuicDefaultConnectionIdLength) {}
-
-QuicServer::QuicServer(
-    std::unique_ptr<ProofSource> proof_source,
-    const QuicConfig& config,
-    const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
-    const ParsedQuicVersionVector& supported_versions,
-    QuicSimpleServerBackend* quic_simple_server_backend,
-    uint8_t expected_server_connection_id_length)
-    : port_(0),
-      fd_(-1),
-      packets_dropped_(0),
-      overflow_supported_(false),
-      silent_close_(false),
-      config_(config),
-      crypto_config_(kSourceAddressTokenSecret,
-                     QuicRandom::GetInstance(),
-                     std::move(proof_source),
-                     KeyExchangeSource::Default()),
-      crypto_config_options_(crypto_config_options),
-      version_manager_(supported_versions),
-      packet_reader_(new QuicPacketReader()),
-      quic_simple_server_backend_(quic_simple_server_backend),
-      expected_server_connection_id_length_(
-          expected_server_connection_id_length) {
-  QUICHE_DCHECK(quic_simple_server_backend_);
-  Initialize();
-}
-
-void QuicServer::Initialize() {
-  // If an initial flow control window has not explicitly been set, then use a
-  // sensible value for a server: 1 MB for session, 64 KB for each stream.
-  const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024;  // 1 MB
-  const uint32_t kInitialStreamFlowControlWindow = 64 * 1024;         // 64 KB
-  if (config_.GetInitialStreamFlowControlWindowToSend() ==
-      kDefaultFlowControlSendWindow) {
-    config_.SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindow);
-  }
-  if (config_.GetInitialSessionFlowControlWindowToSend() ==
-      kDefaultFlowControlSendWindow) {
-    config_.SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindow);
-  }
-
-  epoll_server_.set_timeout_in_us(50 * 1000);
-
-  QuicEpollClock clock(&epoll_server_);
-
-  std::unique_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
-      QuicRandom::GetInstance(), &clock, crypto_config_options_));
-}
-
-QuicServer::~QuicServer() = default;
-
-bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
-  QuicUdpSocketApi socket_api;
-  fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
-                          /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
-                          /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
-  if (fd_ == kQuicInvalidSocketFd) {
-    QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
-    return false;
-  }
-
-  overflow_supported_ = socket_api.EnableDroppedPacketCount(fd_);
-  socket_api.EnableReceiveTimestamp(fd_);
-
-  sockaddr_storage addr = address.generic_address();
-  int rc = bind(fd_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
-  if (rc < 0) {
-    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
-    return false;
-  }
-  QUIC_LOG(INFO) << "Listening on " << address.ToString();
-  port_ = address.port();
-  if (port_ == 0) {
-    QuicSocketAddress address;
-    if (address.FromSocket(fd_) != 0) {
-      QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
-                      << strerror(errno);
-    }
-    port_ = address.port();
-  }
-
-  epoll_server_.RegisterFD(fd_, this, kEpollFlags);
-  dispatcher_.reset(CreateQuicDispatcher());
-  dispatcher_->InitializeWithWriter(CreateWriter(fd_));
-
-  return true;
-}
-
-QuicPacketWriter* QuicServer::CreateWriter(int fd) {
-  return new QuicDefaultPacketWriter(fd);
-}
-
-QuicDispatcher* QuicServer::CreateQuicDispatcher() {
-  QuicEpollAlarmFactory alarm_factory(&epoll_server_);
-  return new QuicSimpleDispatcher(
-      &config_, &crypto_config_, &version_manager_,
-      std::unique_ptr<QuicEpollConnectionHelper>(new QuicEpollConnectionHelper(
-          &epoll_server_, QuicAllocator::BUFFER_POOL)),
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
-          new QuicSimpleCryptoServerStreamHelper()),
-      std::unique_ptr<QuicEpollAlarmFactory>(
-          new QuicEpollAlarmFactory(&epoll_server_)),
-      quic_simple_server_backend_, expected_server_connection_id_length_);
-}
-
-void QuicServer::HandleEventsForever() {
-  while (true) {
-    WaitForEvents();
-  }
-}
-
-void QuicServer::WaitForEvents() {
-  epoll_server_.WaitForEventsAndExecuteCallbacks();
-}
-
-void QuicServer::Shutdown() {
-  if (!silent_close_) {
-    // Before we shut down the epoll server, give all active sessions a chance
-    // to notify clients that they're closing.
-    dispatcher_->Shutdown();
-  }
-
-  epoll_server_.Shutdown();
-
-  close(fd_);
-  fd_ = -1;
-}
-
-void QuicServer::OnEvent(int fd, QuicEpollEvent* event) {
-  QUICHE_DCHECK_EQ(fd, fd_);
-  event->out_ready_mask = 0;
-
-  if (event->in_events & EPOLLIN) {
-    QUIC_DVLOG(1) << "EPOLLIN";
-
-    dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
-
-    bool more_to_read = true;
-    while (more_to_read) {
-      more_to_read = packet_reader_->ReadAndDispatchPackets(
-          fd_, port_, QuicEpollClock(&epoll_server_), dispatcher_.get(),
-          overflow_supported_ ? &packets_dropped_ : nullptr);
-    }
-
-    if (dispatcher_->HasChlosBuffered()) {
-      // Register EPOLLIN event to consume buffered CHLO(s).
-      event->out_ready_mask |= EPOLLIN;
-    }
-  }
-  if (event->in_events & EPOLLOUT) {
-    dispatcher_->OnCanWrite();
-    if (dispatcher_->HasPendingWrites()) {
-      event->out_ready_mask |= EPOLLOUT;
-    }
-  }
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_server.h b/quic/tools/quic_server.h
deleted file mode 100644
index 931ac64..0000000
--- a/quic/tools/quic_server.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy server, which listens on a specified address for QUIC traffic and
-// handles incoming responses.
-//
-// Note that this server is intended to verify correctness of the client and is
-// in no way expected to be performant.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/quic_config.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_framer.h"
-#include "quic/core/quic_packet_writer.h"
-#include "quic/core/quic_udp_socket.h"
-#include "quic/core/quic_version_manager.h"
-#include "quic/platform/api/quic_epoll.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_spdy_server_base.h"
-
-namespace quic {
-
-namespace test {
-class QuicServerPeer;
-}  // namespace test
-
-class QuicDispatcher;
-class QuicPacketReader;
-
-class QuicServer : public QuicSpdyServerBase,
-                   public QuicEpollCallbackInterface {
- public:
-  QuicServer(std::unique_ptr<ProofSource> proof_source,
-             QuicSimpleServerBackend* quic_simple_server_backend);
-  QuicServer(std::unique_ptr<ProofSource> proof_source,
-             QuicSimpleServerBackend* quic_simple_server_backend,
-             const ParsedQuicVersionVector& supported_versions);
-  QuicServer(std::unique_ptr<ProofSource> proof_source,
-             const QuicConfig& config,
-             const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
-             const ParsedQuicVersionVector& supported_versions,
-             QuicSimpleServerBackend* quic_simple_server_backend,
-             uint8_t expected_server_connection_id_length);
-  QuicServer(const QuicServer&) = delete;
-  QuicServer& operator=(const QuicServer&) = delete;
-
-  ~QuicServer() override;
-
-  std::string Name() const override { return "QuicServer"; }
-
-  // Start listening on the specified address.
-  bool CreateUDPSocketAndListen(const QuicSocketAddress& address) override;
-  // Handles all events. Does not return.
-  void HandleEventsForever() override;
-
-  // Wait up to 50ms, and handle any events which occur.
-  void WaitForEvents();
-
-  // Server deletion is imminent.  Start cleaning up the epoll server.
-  virtual void Shutdown();
-
-  // From EpollCallbackInterface
-  void OnRegistration(QuicEpollServer* /*eps*/,
-                      int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, QuicEpollEvent* /*event*/) override;
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  void OnShutdown(QuicEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void SetChloMultiplier(size_t multiplier) {
-    crypto_config_.set_chlo_multiplier(multiplier);
-  }
-
-  void SetPreSharedKey(absl::string_view key) {
-    crypto_config_.set_pre_shared_key(key);
-  }
-
-  bool overflow_supported() { return overflow_supported_; }
-
-  QuicPacketCount packets_dropped() { return packets_dropped_; }
-
-  int port() { return port_; }
-
-  QuicEpollServer* epoll_server() { return &epoll_server_; }
-
- protected:
-  virtual QuicPacketWriter* CreateWriter(int fd);
-
-  virtual QuicDispatcher* CreateQuicDispatcher();
-
-  const QuicConfig& config() const { return config_; }
-  const QuicCryptoServerConfig& crypto_config() const { return crypto_config_; }
-
-  QuicDispatcher* dispatcher() { return dispatcher_.get(); }
-
-  QuicVersionManager* version_manager() { return &version_manager_; }
-
-  QuicSimpleServerBackend* server_backend() {
-    return quic_simple_server_backend_;
-  }
-
-  void set_silent_close(bool value) { silent_close_ = value; }
-
-  uint8_t expected_server_connection_id_length() {
-    return expected_server_connection_id_length_;
-  }
-
- private:
-  friend class quic::test::QuicServerPeer;
-
-  // Initialize the internal state of the server.
-  void Initialize();
-
-  // Accepts data from the framer and demuxes clients to sessions.
-  std::unique_ptr<QuicDispatcher> dispatcher_;
-  // Frames incoming packets and hands them to the dispatcher.
-  QuicEpollServer epoll_server_;
-
-  // The port the server is listening on.
-  int port_;
-
-  // Listening connection.  Also used for outbound client communication.
-  QuicUdpSocketFd fd_;
-
-  // If overflow_supported_ is true this will be the number of packets dropped
-  // during the lifetime of the server.  This may overflow if enough packets
-  // are dropped.
-  QuicPacketCount packets_dropped_;
-
-  // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
-  // because the socket would otherwise overflow.
-  bool overflow_supported_;
-
-  // If true, do not call Shutdown on the dispatcher.  Connections will close
-  // without sending a final connection close.
-  bool silent_close_;
-
-  // config_ contains non-crypto parameters that are negotiated in the crypto
-  // handshake.
-  QuicConfig config_;
-  // crypto_config_ contains crypto parameters for the handshake.
-  QuicCryptoServerConfig crypto_config_;
-  // crypto_config_options_ contains crypto parameters for the handshake.
-  QuicCryptoServerConfig::ConfigOptions crypto_config_options_;
-
-  // Used to generate current supported versions.
-  QuicVersionManager version_manager_;
-
-  // Point to a QuicPacketReader object on the heap. The reader allocates more
-  // space than allowed on the stack.
-  std::unique_ptr<QuicPacketReader> packet_reader_;
-
-  QuicSimpleServerBackend* quic_simple_server_backend_;  // unowned.
-
-  // Connection ID length expected to be read on incoming IETF short headers.
-  uint8_t expected_server_connection_id_length_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
diff --git a/quic/tools/quic_server_bin.cc b/quic/tools/quic_server_bin.cc
deleted file mode 100644
index 7ddfe18..0000000
--- a/quic/tools/quic_server_bin.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A binary wrapper for QuicServer.  It listens forever on --port
-// (default 6121) until it's killed or ctrl-cd to death.
-
-#include <vector>
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/tools/quic_epoll_server_factory.h"
-#include "quic/tools/quic_toy_server.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/platform/api/quiche_system_event_loop.h"
-
-int main(int argc, char* argv[]) {
-  quiche::QuicheSystemEventLoop event_loop("quic_server");
-  const char* usage = "Usage: quic_server [options]";
-  std::vector<std::string> non_option_args =
-      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
-  if (!non_option_args.empty()) {
-    quiche::QuichePrintCommandLineFlagHelp(usage);
-    exit(0);
-  }
-
-  quic::QuicToyServer::MemoryCacheBackendFactory backend_factory;
-  quic::QuicEpollServerFactory server_factory;
-  quic::QuicToyServer server(&backend_factory, &server_factory);
-  return server.Start();
-}
diff --git a/quic/tools/quic_server_test.cc b/quic/tools/quic_server_test.cc
deleted file mode 100644
index 8059e7d..0000000
--- a/quic/tools/quic_server_test.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_server.h"
-
-#include "absl/base/macros.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_epoll_alarm_factory.h"
-#include "quic/core/quic_epoll_connection_helper.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/platform/api/quic_test_loopback.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_dispatcher.h"
-#include "quic/test_tools/quic_server_peer.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-
-namespace quic {
-namespace test {
-
-using ::testing::_;
-
-namespace {
-
-class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
- public:
-  MockQuicSimpleDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicSimpleDispatcher(config,
-                             crypto_config,
-                             version_manager,
-                             std::move(helper),
-                             std::move(session_helper),
-                             std::move(alarm_factory),
-                             quic_simple_server_backend,
-                             kQuicDefaultConnectionIdLength) {}
-  ~MockQuicSimpleDispatcher() override = default;
-
-  MOCK_METHOD(void, OnCanWrite, (), (override));
-  MOCK_METHOD(bool, HasPendingWrites, (), (const, override));
-  MOCK_METHOD(bool, HasChlosBuffered, (), (const, override));
-  MOCK_METHOD(void, ProcessBufferedChlos, (size_t), (override));
-};
-
-class TestQuicServer : public QuicServer {
- public:
-  TestQuicServer()
-      : QuicServer(crypto_test_utils::ProofSourceForTesting(),
-                   &quic_simple_server_backend_) {}
-
-  ~TestQuicServer() override = default;
-
-  MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
-
- protected:
-  QuicDispatcher* CreateQuicDispatcher() override {
-    mock_dispatcher_ = new MockQuicSimpleDispatcher(
-        &config(), &crypto_config(), version_manager(),
-        std::unique_ptr<QuicEpollConnectionHelper>(
-            new QuicEpollConnectionHelper(epoll_server(),
-                                          QuicAllocator::BUFFER_POOL)),
-        std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
-            new QuicSimpleCryptoServerStreamHelper()),
-        std::unique_ptr<QuicEpollAlarmFactory>(
-            new QuicEpollAlarmFactory(epoll_server())),
-        &quic_simple_server_backend_);
-    return mock_dispatcher_;
-  }
-
-  MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
-  QuicMemoryCacheBackend quic_simple_server_backend_;
-};
-
-class QuicServerEpollInTest : public QuicTest {
- public:
-  QuicServerEpollInTest() : server_address_(TestLoopback(), 0) {}
-
-  void StartListening() {
-    server_.CreateUDPSocketAndListen(server_address_);
-    server_address_ = QuicSocketAddress(server_address_.host(), server_.port());
-
-    ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
-
-    if (!server_.overflow_supported()) {
-      QUIC_LOG(WARNING) << "Overflow not supported.  Not testing.";
-      return;
-    }
-  }
-
- protected:
-  QuicSocketAddress server_address_;
-  TestQuicServer server_;
-};
-
-// Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
-// event should try to create connections for them. And set epoll mask with
-// EPOLLIN if there are still CHLOs remaining at the end of epoll event.
-TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
-  // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
-  // event, dispatcher can't create session for all of CHLOs. So listener should
-  // register another EPOLLIN event by itself. Even without new packet arrival,
-  // the rest CHLOs should be process in next epoll event.
-  StartListening();
-  bool more_chlos = true;
-  MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
-  QUICHE_DCHECK(dispatcher_ != nullptr);
-  EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
-  EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
-  EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
-  // Expect there are still CHLOs buffered after 1st event. But not any more
-  // after 2nd event.
-  EXPECT_CALL(*dispatcher_, HasChlosBuffered())
-      .WillOnce(testing::Return(true))
-      .WillOnce(
-          DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
-
-  // Send a packet to trigger epoll event.
-  int fd = socket(
-      AddressFamilyUnderTest() == IpAddressFamily::IP_V4 ? AF_INET : AF_INET6,
-      SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-  ASSERT_LT(0, fd);
-
-  char buf[1024];
-  memset(buf, 0, ABSL_ARRAYSIZE(buf));
-  sockaddr_storage storage = server_address_.generic_address();
-  int rc = sendto(fd, buf, ABSL_ARRAYSIZE(buf), 0,
-                  reinterpret_cast<sockaddr*>(&storage), sizeof(storage));
-  if (rc < 0) {
-    QUIC_DLOG(INFO) << errno << " " << strerror(errno);
-  }
-
-  while (more_chlos) {
-    server_.WaitForEvents();
-  }
-}
-
-class QuicServerDispatchPacketTest : public QuicTest {
- public:
-  QuicServerDispatchPacketTest()
-      : crypto_config_("blah",
-                       QuicRandom::GetInstance(),
-                       crypto_test_utils::ProofSourceForTesting(),
-                       KeyExchangeSource::Default()),
-        version_manager_(AllSupportedVersions()),
-        dispatcher_(
-            &config_,
-            &crypto_config_,
-            &version_manager_,
-            std::unique_ptr<QuicEpollConnectionHelper>(
-                new QuicEpollConnectionHelper(&eps_,
-                                              QuicAllocator::BUFFER_POOL)),
-            std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
-                new QuicSimpleCryptoServerStreamHelper()),
-            std::unique_ptr<QuicEpollAlarmFactory>(
-                new QuicEpollAlarmFactory(&eps_)),
-            &quic_simple_server_backend_) {
-    dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
-  }
-
-  void DispatchPacket(const QuicReceivedPacket& packet) {
-    QuicSocketAddress client_addr, server_addr;
-    dispatcher_.ProcessPacket(server_addr, client_addr, packet);
-  }
-
- protected:
-  QuicConfig config_;
-  QuicCryptoServerConfig crypto_config_;
-  QuicVersionManager version_manager_;
-  QuicEpollServer eps_;
-  QuicMemoryCacheBackend quic_simple_server_backend_;
-  MockQuicDispatcher dispatcher_;
-};
-
-TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
-  // clang-format off
-  unsigned char valid_packet[] = {
-    // public flags (8 byte connection_id)
-    0x3C,
-    // connection_id
-    0x10, 0x32, 0x54, 0x76,
-    0x98, 0xBA, 0xDC, 0xFE,
-    // packet number
-    0xBC, 0x9A, 0x78, 0x56,
-    0x34, 0x12,
-    // private flags
-    0x00
-  };
-  // clang-format on
-  QuicReceivedPacket encrypted_valid_packet(
-      reinterpret_cast<char*>(valid_packet), ABSL_ARRAYSIZE(valid_packet),
-      QuicTime::Zero(), false);
-
-  EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
-  DispatchPacket(encrypted_valid_packet);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/quic_simple_client_session.cc b/quic/tools/quic_simple_client_session.cc
deleted file mode 100644
index 2e70919..0000000
--- a/quic/tools/quic_simple_client_session.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_client_session.h"
-
-#include <utility>
-
-namespace quic {
-
-QuicSimpleClientSession::QuicSimpleClientSession(
-    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection, const QuicServerId& server_id,
-    QuicCryptoClientConfig* crypto_config,
-    QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body)
-    : QuicSimpleClientSession(config, supported_versions, connection, server_id,
-                              crypto_config, push_promise_index,
-                              drop_response_body,
-                              /*enable_web_transport=*/false,
-                              /*use_datagram_contexts=*/false) {}
-
-QuicSimpleClientSession::QuicSimpleClientSession(
-    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection, const QuicServerId& server_id,
-    QuicCryptoClientConfig* crypto_config,
-    QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body,
-    bool enable_web_transport, bool use_datagram_contexts)
-    : QuicSpdyClientSession(config, supported_versions, connection, server_id,
-                            crypto_config, push_promise_index),
-      drop_response_body_(drop_response_body),
-      enable_web_transport_(enable_web_transport),
-      use_datagram_contexts_(use_datagram_contexts) {}
-
-std::unique_ptr<QuicSpdyClientStream>
-QuicSimpleClientSession::CreateClientStream() {
-  return std::make_unique<QuicSimpleClientStream>(
-      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
-      drop_response_body_);
-}
-
-bool QuicSimpleClientSession::ShouldNegotiateWebTransport() {
-  return enable_web_transport_;
-}
-
-bool QuicSimpleClientSession::ShouldNegotiateDatagramContexts() {
-  return use_datagram_contexts_;
-}
-
-HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() {
-  return enable_web_transport_ ? HttpDatagramSupport::kDraft04
-                               : HttpDatagramSupport::kNone;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_simple_client_session.h b/quic/tools/quic_simple_client_session.h
deleted file mode 100644
index 6371448..0000000
--- a/quic/tools/quic_simple_client_session.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
-
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/tools/quic_simple_client_stream.h"
-
-namespace quic {
-
-class QuicSimpleClientSession : public QuicSpdyClientSession {
- public:
-  QuicSimpleClientSession(const QuicConfig& config,
-                          const ParsedQuicVersionVector& supported_versions,
-                          QuicConnection* connection,
-                          const QuicServerId& server_id,
-                          QuicCryptoClientConfig* crypto_config,
-                          QuicClientPushPromiseIndex* push_promise_index,
-                          bool drop_response_body);
-  QuicSimpleClientSession(const QuicConfig& config,
-                          const ParsedQuicVersionVector& supported_versions,
-                          QuicConnection* connection,
-                          const QuicServerId& server_id,
-                          QuicCryptoClientConfig* crypto_config,
-                          QuicClientPushPromiseIndex* push_promise_index,
-                          bool drop_response_body, bool enable_web_transport,
-                          bool use_datagram_contexts);
-
-  std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override;
-  bool ShouldNegotiateWebTransport() override;
-  bool ShouldNegotiateDatagramContexts() override;
-  HttpDatagramSupport LocalHttpDatagramSupport() override;
-
- private:
-  const bool drop_response_body_;
-  const bool enable_web_transport_;
-  const bool use_datagram_contexts_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
diff --git a/quic/tools/quic_simple_client_stream.cc b/quic/tools/quic_simple_client_stream.cc
deleted file mode 100644
index 21145e1..0000000
--- a/quic/tools/quic_simple_client_stream.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_client_stream.h"
-
-namespace quic {
-
-void QuicSimpleClientStream::OnBodyAvailable() {
-  if (!drop_response_body_) {
-    QuicSpdyClientStream::OnBodyAvailable();
-    return;
-  }
-
-  while (HasBytesToRead()) {
-    struct iovec iov;
-    if (GetReadableRegions(&iov, 1) == 0) {
-      break;
-    }
-    MarkConsumed(iov.iov_len);
-  }
-  if (sequencer()->IsClosed()) {
-    OnFinRead();
-  } else {
-    sequencer()->SetUnblocked();
-  }
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_simple_client_stream.h b/quic/tools/quic_simple_client_stream.h
deleted file mode 100644
index 471bdfb..0000000
--- a/quic/tools/quic_simple_client_stream.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
-
-#include "quic/core/http/quic_spdy_client_stream.h"
-
-namespace quic {
-
-class QuicSimpleClientStream : public QuicSpdyClientStream {
- public:
-  QuicSimpleClientStream(QuicStreamId id,
-                         QuicSpdyClientSession* session,
-                         StreamType type,
-                         bool drop_response_body)
-      : QuicSpdyClientStream(id, session, type),
-        drop_response_body_(drop_response_body) {}
-  void OnBodyAvailable() override;
-
- private:
-  const bool drop_response_body_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
diff --git a/quic/tools/quic_simple_crypto_server_stream_helper.cc b/quic/tools/quic_simple_crypto_server_stream_helper.cc
deleted file mode 100644
index 5c39d20..0000000
--- a/quic/tools/quic_simple_crypto_server_stream_helper.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
-
-#include "quic/core/quic_utils.h"
-
-namespace quic {
-
-QuicSimpleCryptoServerStreamHelper::QuicSimpleCryptoServerStreamHelper() =
-    default;
-
-QuicSimpleCryptoServerStreamHelper::~QuicSimpleCryptoServerStreamHelper() =
-    default;
-
-bool QuicSimpleCryptoServerStreamHelper::CanAcceptClientHello(
-    const CryptoHandshakeMessage& /*message*/,
-    const QuicSocketAddress& /*client_address*/,
-    const QuicSocketAddress& /*peer_address*/,
-    const QuicSocketAddress& /*self_address*/,
-    std::string* /*error_details*/) const {
-  return true;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_simple_crypto_server_stream_helper.h b/quic/tools/quic_simple_crypto_server_stream_helper.h
deleted file mode 100644
index 1fccfc0..0000000
--- a/quic/tools/quic_simple_crypto_server_stream_helper.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
-
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-
-namespace quic {
-
-// Simple helper for server crypto streams which generates a new random
-// connection ID for rejects.
-class QuicSimpleCryptoServerStreamHelper
-    : public QuicCryptoServerStreamBase::Helper {
- public:
-  QuicSimpleCryptoServerStreamHelper();
-
-  ~QuicSimpleCryptoServerStreamHelper() override;
-
-  bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
-                            const QuicSocketAddress& client_address,
-                            const QuicSocketAddress& peer_address,
-                            const QuicSocketAddress& self_address,
-                            std::string* error_details) const override;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
diff --git a/quic/tools/quic_simple_dispatcher.cc b/quic/tools/quic_simple_dispatcher.cc
deleted file mode 100644
index 7864ce7..0000000
--- a/quic/tools/quic_simple_dispatcher.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_dispatcher.h"
-
-#include "absl/strings/string_view.h"
-#include "quic/tools/quic_simple_server_session.h"
-
-namespace quic {
-
-QuicSimpleDispatcher::QuicSimpleDispatcher(
-    const QuicConfig* config,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicVersionManager* version_manager,
-    std::unique_ptr<QuicConnectionHelperInterface> helper,
-    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-    std::unique_ptr<QuicAlarmFactory> alarm_factory,
-    QuicSimpleServerBackend* quic_simple_server_backend,
-    uint8_t expected_server_connection_id_length)
-    : QuicDispatcher(config,
-                     crypto_config,
-                     version_manager,
-                     std::move(helper),
-                     std::move(session_helper),
-                     std::move(alarm_factory),
-                     expected_server_connection_id_length),
-      quic_simple_server_backend_(quic_simple_server_backend) {}
-
-QuicSimpleDispatcher::~QuicSimpleDispatcher() = default;
-
-int QuicSimpleDispatcher::GetRstErrorCount(
-    QuicRstStreamErrorCode error_code) const {
-  auto it = rst_error_map_.find(error_code);
-  if (it == rst_error_map_.end()) {
-    return 0;
-  }
-  return it->second;
-}
-
-void QuicSimpleDispatcher::OnRstStreamReceived(
-    const QuicRstStreamFrame& frame) {
-  auto it = rst_error_map_.find(frame.error_code);
-  if (it == rst_error_map_.end()) {
-    rst_error_map_.insert(std::make_pair(frame.error_code, 1));
-  } else {
-    it->second++;
-  }
-}
-
-std::unique_ptr<QuicSession> QuicSimpleDispatcher::CreateQuicSession(
-    QuicConnectionId connection_id, const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
-    const ParsedQuicVersion& version,
-    const ParsedClientHello& /*parsed_chlo*/) {
-  // The QuicServerSessionBase takes ownership of |connection| below.
-  QuicConnection* connection =
-      new QuicConnection(connection_id, self_address, peer_address, helper(),
-                         alarm_factory(), writer(),
-                         /* owns_writer= */ false, Perspective::IS_SERVER,
-                         ParsedQuicVersionVector{version});
-
-  auto session = std::make_unique<QuicSimpleServerSession>(
-      config(), GetSupportedVersions(), connection, this, session_helper(),
-      crypto_config(), compressed_certs_cache(), quic_simple_server_backend_);
-  session->Initialize();
-  return session;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_simple_dispatcher.h b/quic/tools/quic_simple_dispatcher.h
deleted file mode 100644
index ce9d680..0000000
--- a/quic/tools/quic_simple_dispatcher.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_server_session_base.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-
-class QuicSimpleDispatcher : public QuicDispatcher {
- public:
-  QuicSimpleDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      QuicSimpleServerBackend* quic_simple_server_backend,
-      uint8_t expected_server_connection_id_length);
-
-  ~QuicSimpleDispatcher() override;
-
-  int GetRstErrorCount(QuicRstStreamErrorCode rst_error_code) const;
-
-  void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
-
- protected:
-  std::unique_ptr<QuicSession> CreateQuicSession(
-      QuicConnectionId connection_id, const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address, absl::string_view alpn,
-      const ParsedQuicVersion& version,
-      const ParsedClientHello& parsed_chlo) override;
-
-  QuicSimpleServerBackend* server_backend() {
-    return quic_simple_server_backend_;
-  }
-
- private:
-  QuicSimpleServerBackend* quic_simple_server_backend_;  // Unowned.
-
-  // The map of the reset error code with its counter.
-  std::map<QuicRstStreamErrorCode, int> rst_error_map_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
diff --git a/quic/tools/quic_simple_server_backend.h b/quic/tools/quic_simple_server_backend.h
deleted file mode 100644
index 25204ac..0000000
--- a/quic/tools/quic_simple_server_backend.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
-
-#include <memory>
-
-#include "quic/core/quic_types.h"
-#include "quic/core/web_transport_interface.h"
-#include "quic/tools/quic_backend_response.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace quic {
-
-// This interface implements the functionality to fetch a response
-// from the backend (such as cache, http-proxy etc) to serve
-// requests received by a Quic Server
-class QuicSimpleServerBackend {
- public:
-  // This interface implements the methods
-  // called by the QuicSimpleServerBackend implementation
-  // to process the request in the backend
-  class RequestHandler {
-   public:
-    virtual ~RequestHandler() {}
-
-    virtual QuicConnectionId connection_id() const = 0;
-    virtual QuicStreamId stream_id() const = 0;
-    virtual std::string peer_host() const = 0;
-    // Called when the response is ready at the backend and can be send back to
-    // the QUIC client.
-    virtual void OnResponseBackendComplete(
-        const QuicBackendResponse* response) = 0;
-  };
-
-  struct WebTransportResponse {
-    spdy::Http2HeaderBlock response_headers;
-    std::unique_ptr<WebTransportVisitor> visitor;
-  };
-
-  virtual ~QuicSimpleServerBackend() = default;
-  // This method initializes the backend instance to fetch responses
-  // from a backend server, in-memory cache etc.
-  virtual bool InitializeBackend(const std::string& backend_url) = 0;
-  // Returns true if the backend has been successfully initialized
-  // and could be used to fetch HTTP requests
-  virtual bool IsBackendInitialized() const = 0;
-  // Triggers a HTTP request to be sent to the backend server or cache
-  // If response is immediately available, the function synchronously calls
-  // the |request_handler| with the HTTP response.
-  // If the response has to be fetched over the network, the function
-  // asynchronously calls |request_handler| with the HTTP response.
-  virtual void FetchResponseFromBackend(
-      const spdy::Http2HeaderBlock& request_headers,
-      const std::string& request_body,
-      RequestHandler* request_handler) = 0;
-  // Clears the state of the backend  instance
-  virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0;
-
-  virtual WebTransportResponse ProcessWebTransportRequest(
-      const spdy::Http2HeaderBlock& /*request_headers*/,
-      WebTransportSession* /*session*/) {
-    WebTransportResponse response;
-    response.response_headers[":status"] = "400";
-    return response;
-  }
-  virtual bool SupportsWebTransport() { return false; }
-  virtual bool UsesDatagramContexts() { return false; }
-  virtual bool SupportsExtendedConnect() { return true; }
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
diff --git a/quic/tools/quic_simple_server_session.cc b/quic/tools/quic_simple_server_session.cc
deleted file mode 100644
index 6288182..0000000
--- a/quic/tools/quic_simple_server_session.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_server_session.h"
-
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "quic/core/http/quic_server_initiated_spdy_stream.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-namespace quic {
-
-QuicSimpleServerSession::QuicSimpleServerSession(
-    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection, QuicSession::Visitor* visitor,
-    QuicCryptoServerStreamBase::Helper* helper,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicServerSessionBase(config, supported_versions, connection, visitor,
-                            helper, crypto_config, compressed_certs_cache),
-      highest_promised_stream_id_(
-          QuicUtils::GetInvalidStreamId(connection->transport_version())),
-      quic_simple_server_backend_(quic_simple_server_backend) {
-  QUICHE_DCHECK(quic_simple_server_backend_);
-}
-
-QuicSimpleServerSession::~QuicSimpleServerSession() { DeleteConnection(); }
-
-std::unique_ptr<QuicCryptoServerStreamBase>
-QuicSimpleServerSession::CreateQuicCryptoServerStream(
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache) {
-  return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
-                                  stream_helper());
-}
-
-void QuicSimpleServerSession::OnStreamFrame(const QuicStreamFrame& frame) {
-  if (!IsIncomingStream(frame.stream_id) && !WillNegotiateWebTransport()) {
-    QUIC_LOG(WARNING) << "Client shouldn't send data on server push stream";
-    connection()->CloseConnection(
-        QUIC_INVALID_STREAM_ID, "Client sent data on server push stream",
-        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-    return;
-  }
-  QuicSpdySession::OnStreamFrame(frame);
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(QuicStreamId id) {
-  if (!ShouldCreateIncomingStream(id)) {
-    return nullptr;
-  }
-
-  QuicSpdyStream* stream = new QuicSimpleServerStream(
-      id, this, BIDIRECTIONAL, quic_simple_server_backend_);
-  ActivateStream(absl::WrapUnique(stream));
-  return stream;
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(
-    PendingStream* pending) {
-  QuicSpdyStream* stream =
-      new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
-  ActivateStream(absl::WrapUnique(stream));
-  return stream;
-}
-
-QuicSpdyStream* QuicSimpleServerSession::CreateOutgoingBidirectionalStream() {
-  if (!WillNegotiateWebTransport()) {
-    QUIC_BUG(QuicSimpleServerSession CreateOutgoingBidirectionalStream without
-                 WebTransport support)
-        << "QuicSimpleServerSession::CreateOutgoingBidirectionalStream called "
-           "in a session without WebTransport support.";
-    return nullptr;
-  }
-  if (!ShouldCreateOutgoingBidirectionalStream()) {
-    return nullptr;
-  }
-
-  QuicServerInitiatedSpdyStream* stream = new QuicServerInitiatedSpdyStream(
-      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
-  ActivateStream(absl::WrapUnique(stream));
-  return stream;
-}
-
-QuicSimpleServerStream*
-QuicSimpleServerSession::CreateOutgoingUnidirectionalStream() {
-  if (!ShouldCreateOutgoingUnidirectionalStream()) {
-    return nullptr;
-  }
-
-  QuicSimpleServerStream* stream = new QuicSimpleServerStream(
-      GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
-      quic_simple_server_backend_);
-  ActivateStream(absl::WrapUnique(stream));
-  return stream;
-}
-
-void QuicSimpleServerSession::HandleFrameOnNonexistentOutgoingStream(
-    QuicStreamId stream_id) {
-  // If this stream is a promised but not created stream (stream_id within the
-  // range of next_outgoing_stream_id_ and highes_promised_stream_id_),
-  // connection shouldn't be closed.
-  // Otherwise behave in the same way as base class.
-  if (highest_promised_stream_id_ ==
-          QuicUtils::GetInvalidStreamId(transport_version()) ||
-      stream_id > highest_promised_stream_id_) {
-    QuicSession::HandleFrameOnNonexistentOutgoingStream(stream_id);
-  }
-}
-
-void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
-    const QuicRstStreamFrame& frame) {
-  QuicSession::HandleRstOnValidNonexistentStream(frame);
-  if (!IsClosedStream(frame.stream_id)) {
-    // If a nonexistent stream is not a closed stream and still valid, it must
-    // be a locally preserved stream. Resetting this kind of stream means
-    // cancelling the promised server push.
-    // Since PromisedStreamInfo are queued in sequence, the corresponding
-    // index for it in promised_streams_ can be calculated.
-    QuicStreamId next_stream_id = next_outgoing_unidirectional_stream_id();
-    if ((!version().HasIetfQuicFrames() ||
-         !QuicUtils::IsBidirectionalStreamId(frame.stream_id, version())) &&
-        frame.stream_id >= next_stream_id) {
-      size_t index = (frame.stream_id - next_stream_id) /
-                     QuicUtils::StreamIdDelta(transport_version());
-      if (index < promised_streams_.size()) {
-        promised_streams_[index].is_cancelled = true;
-      }
-    }
-    control_frame_manager().WriteOrBufferRstStream(
-        frame.stream_id,
-        QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 0);
-    connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
-  }
-}
-
-spdy::Http2HeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders(
-    std::string request_url, QuicBackendResponse::ServerPushInfo resource,
-    const spdy::Http2HeaderBlock& original_request_headers) {
-  QuicUrl push_request_url = resource.request_url;
-
-  spdy::Http2HeaderBlock spdy_headers = original_request_headers.Clone();
-  // :authority could be different from original request.
-  spdy_headers[":authority"] = push_request_url.host();
-  spdy_headers[":path"] = push_request_url.path();
-  // Push request always use GET.
-  spdy_headers[":method"] = "GET";
-  spdy_headers["referer"] = request_url;
-  spdy_headers[":scheme"] = push_request_url.scheme();
-  // It is not possible to push a response to a request that includes a request
-  // body.
-  spdy_headers["content-length"] = "0";
-  // Remove "host" field as push request is a directly generated HTTP2 request
-  // which should use ":authority" instead of "host".
-  spdy_headers.erase("host");
-  return spdy_headers;
-}
-
-void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id,
-                                              QuicStreamId promised_stream_id,
-                                              spdy::Http2HeaderBlock headers) {
-  QUIC_DLOG(INFO) << "stream " << original_stream_id
-                  << " send PUSH_PROMISE for promised stream "
-                  << promised_stream_id;
-  WritePushPromise(original_stream_id, promised_stream_id, std::move(headers));
-}
-
-void QuicSimpleServerSession::HandlePromisedPushRequests() {
-  while (!promised_streams_.empty() &&
-         ShouldCreateOutgoingUnidirectionalStream()) {
-    PromisedStreamInfo& promised_info = promised_streams_.front();
-    QUICHE_DCHECK_EQ(next_outgoing_unidirectional_stream_id(),
-                     promised_info.stream_id);
-
-    if (promised_info.is_cancelled) {
-      // This stream has been reset by client. Skip this stream id.
-      promised_streams_.pop_front();
-      GetNextOutgoingUnidirectionalStreamId();
-      return;
-    }
-
-    QuicSimpleServerStream* promised_stream =
-        static_cast<QuicSimpleServerStream*>(
-            CreateOutgoingUnidirectionalStream());
-    QUICHE_DCHECK_NE(promised_stream, nullptr);
-    QUICHE_DCHECK_EQ(promised_info.stream_id, promised_stream->id());
-    QUIC_DLOG(INFO) << "created server push stream " << promised_stream->id();
-
-    promised_stream->SetPriority(promised_info.precedence);
-
-    spdy::Http2HeaderBlock request_headers(
-        std::move(promised_info.request_headers));
-
-    promised_streams_.pop_front();
-    promised_stream->PushResponse(std::move(request_headers));
-  }
-}
-
-void QuicSimpleServerSession::OnCanCreateNewOutgoingStream(
-    bool unidirectional) {
-  QuicSpdySession::OnCanCreateNewOutgoingStream(unidirectional);
-  if (unidirectional) {
-    HandlePromisedPushRequests();
-  }
-}
-
-void QuicSimpleServerSession::MaybeInitializeHttp3UnidirectionalStreams() {
-  size_t previous_static_stream_count = num_static_streams();
-  QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams();
-  size_t current_static_stream_count = num_static_streams();
-  QUICHE_DCHECK_GE(current_static_stream_count, previous_static_stream_count);
-  highest_promised_stream_id_ +=
-      QuicUtils::StreamIdDelta(transport_version()) *
-      (current_static_stream_count - previous_static_stream_count);
-}
-}  // namespace quic
diff --git a/quic/tools/quic_simple_server_session.h b/quic/tools/quic_simple_server_session.h
deleted file mode 100644
index 393a2d8..0000000
--- a/quic/tools/quic_simple_server_session.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy server specific QuicSession subclass.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
-
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "quic/core/http/quic_server_session_base.h"
-#include "quic/core/http/quic_spdy_session.h"
-#include "quic/core/quic_crypto_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-namespace quic {
-
-namespace test {
-class QuicSimpleServerSessionPeer;
-}  // namespace test
-
-class QuicSimpleServerSession : public QuicServerSessionBase {
- public:
-  // A PromisedStreamInfo is an element of the queue to store promised
-  // stream which hasn't been created yet. It keeps a mapping between promised
-  // stream id with its priority and the headers sent out in PUSH_PROMISE.
-  struct PromisedStreamInfo {
-   public:
-    PromisedStreamInfo(spdy::Http2HeaderBlock request_headers,
-                       QuicStreamId stream_id,
-                       const spdy::SpdyStreamPrecedence& precedence)
-        : request_headers(std::move(request_headers)),
-          stream_id(stream_id),
-          precedence(precedence),
-          is_cancelled(false) {}
-    spdy::Http2HeaderBlock request_headers;
-    QuicStreamId stream_id;
-    spdy::SpdyStreamPrecedence precedence;
-    bool is_cancelled;
-  };
-
-  // Takes ownership of |connection|.
-  QuicSimpleServerSession(const QuicConfig& config,
-                          const ParsedQuicVersionVector& supported_versions,
-                          QuicConnection* connection,
-                          QuicSession::Visitor* visitor,
-                          QuicCryptoServerStreamBase::Helper* helper,
-                          const QuicCryptoServerConfig* crypto_config,
-                          QuicCompressedCertsCache* compressed_certs_cache,
-                          QuicSimpleServerBackend* quic_simple_server_backend);
-  QuicSimpleServerSession(const QuicSimpleServerSession&) = delete;
-  QuicSimpleServerSession& operator=(const QuicSimpleServerSession&) = delete;
-
-  ~QuicSimpleServerSession() override;
-
-  // Override base class to detact client sending data on server push stream.
-  void OnStreamFrame(const QuicStreamFrame& frame) override;
-
-  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
-
-  bool ShouldNegotiateDatagramContexts() override {
-    return quic_simple_server_backend_->UsesDatagramContexts();
-  }
-
- protected:
-  // QuicSession methods:
-  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
-  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
-  QuicSpdyStream* CreateOutgoingBidirectionalStream() override;
-  QuicSimpleServerStream* CreateOutgoingUnidirectionalStream() override;
-  // Override to return true for locally preserved server push stream.
-  void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
-  // Override to handle reseting locally preserved streams.
-  void HandleRstOnValidNonexistentStream(
-      const QuicRstStreamFrame& frame) override;
-
-  // QuicServerSessionBaseMethod:
-  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache) override;
-
-  QuicSimpleServerBackend* server_backend() {
-    return quic_simple_server_backend_;
-  }
-
-  void MaybeInitializeHttp3UnidirectionalStreams() override;
-
-  bool ShouldNegotiateWebTransport() override {
-    return quic_simple_server_backend_->SupportsWebTransport();
-  }
-  HttpDatagramSupport LocalHttpDatagramSupport() override {
-    if (ShouldNegotiateWebTransport()) {
-      return HttpDatagramSupport::kDraft00And04;
-    }
-    return QuicServerSessionBase::LocalHttpDatagramSupport();
-  }
-
- private:
-  friend class test::QuicSimpleServerSessionPeer;
-
-  // Create a server push headers block by copying request's headers block.
-  // But replace or add these pseudo-headers as they are specific to each
-  // request:
-  // :authority, :path, :method, :scheme, referer.
-  // Copying the rest headers ensures they are the same as the original
-  // request, especially cookies.
-  spdy::Http2HeaderBlock SynthesizePushRequestHeaders(
-      std::string request_url,
-      QuicBackendResponse::ServerPushInfo resource,
-      const spdy::Http2HeaderBlock& original_request_headers);
-
-  // Send PUSH_PROMISE frame on headers stream.
-  void SendPushPromise(QuicStreamId original_stream_id,
-                       QuicStreamId promised_stream_id,
-                       spdy::Http2HeaderBlock headers);
-
-  // Fetch response from cache for request headers enqueued into
-  // promised_headers_and_streams_ and send them on dedicated stream until
-  // reaches max_open_stream_ limit.
-  // Called when return value of GetNumOpenOutgoingStreams() changes:
-  //    CloseStreamInner();
-  //    StreamDraining();
-  // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
-  // return value becasue all push streams are impossible to become locally
-  // closed. Since a locally preserved stream becomes remotely closed after
-  // HandlePromisedPushRequests() starts to process it, and if it is reset
-  // locally afterwards, it will be immediately become closed and never get into
-  // locally_closed_stream_highest_offset_. So all the streams in this map
-  // are not outgoing streams.
-  void HandlePromisedPushRequests();
-
-  // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
-  QuicStreamId highest_promised_stream_id_;
-
-  // Promised streams which hasn't been created yet because of max_open_stream_
-  // limit. New element is added to the end of the queue.
-  // Since outgoing stream is created in sequence, stream_id of each element in
-  // the queue also increases by 2 from previous one's. The front element's
-  // stream_id is always next_outgoing_stream_id_, and the last one is always
-  // highest_promised_stream_id_.
-  quiche::QuicheCircularDeque<PromisedStreamInfo> promised_streams_;
-
-  QuicSimpleServerBackend* quic_simple_server_backend_;  // Not owned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
diff --git a/quic/tools/quic_simple_server_session_test.cc b/quic/tools/quic_simple_server_session_test.cc
deleted file mode 100644
index 9cc7bfd..0000000
--- a/quic/tools/quic_simple_server_session_test.cc
+++ /dev/null
@@ -1,595 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_server_session.h"
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/crypto/quic_crypto_server_config.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/proto/cached_network_parameters_proto.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_crypto_server_stream.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/core/tls_server_handshaker.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/mock_quic_session_visitor.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_sent_packet_manager_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_server_stream.h"
-
-using testing::_;
-using testing::AtLeast;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-// Data to be sent on a request stream.  In Google QUIC, this is interpreted as
-// DATA payload (there is no framing on request streams).  In IETF QUIC, this is
-// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z').  Since
-// no payload is included, QPACK decoder will not be invoked.
-const char* const kStreamData = "\1z";
-
-}  // namespace
-
-class QuicSimpleServerSessionPeer {
- public:
-  static void SetCryptoStream(QuicSimpleServerSession* s,
-                              QuicCryptoServerStreamBase* crypto_stream) {
-    s->crypto_stream_.reset(crypto_stream);
-  }
-
-  static QuicSpdyStream* CreateIncomingStream(QuicSimpleServerSession* s,
-                                              QuicStreamId id) {
-    return s->CreateIncomingStream(id);
-  }
-
-  static QuicSimpleServerStream* CreateOutgoingUnidirectionalStream(
-      QuicSimpleServerSession* s) {
-    return s->CreateOutgoingUnidirectionalStream();
-  }
-};
-
-namespace {
-
-const size_t kMaxStreamsForTest = 10;
-
-class MockQuicCryptoServerStream : public QuicCryptoServerStream {
- public:
-  explicit MockQuicCryptoServerStream(
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      QuicSession* session,
-      QuicCryptoServerStreamBase::Helper* helper)
-      : QuicCryptoServerStream(crypto_config,
-                               compressed_certs_cache,
-                               session,
-                               helper) {}
-  MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
-  MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
-      delete;
-  ~MockQuicCryptoServerStream() override {}
-
-  MOCK_METHOD(void,
-              SendServerConfigUpdate,
-              (const CachedNetworkParameters*),
-              (override));
-
-  bool encryption_established() const override { return true; }
-};
-
-class MockTlsServerHandshaker : public TlsServerHandshaker {
- public:
-  explicit MockTlsServerHandshaker(QuicSession* session,
-                                   const QuicCryptoServerConfig* crypto_config)
-      : TlsServerHandshaker(session, crypto_config) {}
-  MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
-  MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
-  ~MockTlsServerHandshaker() override {}
-
-  MOCK_METHOD(void,
-              SendServerConfigUpdate,
-              (const CachedNetworkParameters*),
-              (override));
-
-  bool encryption_established() const override { return true; }
-};
-
-QuicCryptoServerStreamBase* CreateMockCryptoServerStream(
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    QuicSession* session,
-    QuicCryptoServerStreamBase::Helper* helper) {
-  switch (session->connection()->version().handshake_protocol) {
-    case PROTOCOL_QUIC_CRYPTO:
-      return new MockQuicCryptoServerStream(
-          crypto_config, compressed_certs_cache, session, helper);
-    case PROTOCOL_TLS1_3:
-      return new MockTlsServerHandshaker(session, crypto_config);
-    case PROTOCOL_UNSUPPORTED:
-      break;
-  }
-  QUIC_BUG(quic_bug_10933_1)
-      << "Unknown handshake protocol: "
-      << static_cast<int>(session->connection()->version().handshake_protocol);
-  return nullptr;
-}
-
-class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
- public:
-  MockQuicConnectionWithSendStreamData(
-      MockQuicConnectionHelper* helper,
-      MockAlarmFactory* alarm_factory,
-      Perspective perspective,
-      const ParsedQuicVersionVector& supported_versions)
-      : MockQuicConnection(helper,
-                           alarm_factory,
-                           perspective,
-                           supported_versions) {
-    auto consume_all_data = [](QuicStreamId /*id*/, size_t write_length,
-                               QuicStreamOffset /*offset*/,
-                               StreamSendingState state) {
-      return QuicConsumedData(write_length, state != NO_FIN);
-    };
-    ON_CALL(*this, SendStreamData(_, _, _, _))
-        .WillByDefault(Invoke(consume_all_data));
-  }
-
-  MOCK_METHOD(QuicConsumedData,
-              SendStreamData,
-              (QuicStreamId id,
-               size_t write_length,
-               QuicStreamOffset offset,
-               StreamSendingState state),
-              (override));
-};
-
-class MockQuicSimpleServerSession : public QuicSimpleServerSession {
- public:
-  MockQuicSimpleServerSession(
-      const QuicConfig& config,
-      QuicConnection* connection,
-      QuicSession::Visitor* visitor,
-      QuicCryptoServerStreamBase::Helper* helper,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicSimpleServerSession(config,
-                                CurrentSupportedVersions(),
-                                connection,
-                                visitor,
-                                helper,
-                                crypto_config,
-                                compressed_certs_cache,
-                                quic_simple_server_backend) {}
-  // Methods taking non-copyable types like Http2HeaderBlock by value cannot be
-  // mocked directly.
-  void WritePushPromise(QuicStreamId original_stream_id,
-                        QuicStreamId promised_stream_id,
-                        spdy::Http2HeaderBlock headers) override {
-    return WritePushPromiseMock(original_stream_id, promised_stream_id,
-                                headers);
-  }
-  MOCK_METHOD(void,
-              WritePushPromiseMock,
-              (QuicStreamId original_stream_id,
-               QuicStreamId promised_stream_id,
-               const spdy::Http2HeaderBlock& headers),
-              ());
-
-  MOCK_METHOD(void, SendBlocked, (QuicStreamId), (override));
-  MOCK_METHOD(bool,
-              WriteControlFrame,
-              (const QuicFrame& frame, TransmissionType type),
-              (override));
-};
-
-class QuicSimpleServerSessionTest
-    : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  // The function ensures that A) the MAX_STREAMS frames get properly deleted
-  // (since the test uses a 'did we leak memory' check ... if we just lose the
-  // frame, the test fails) and B) returns true (instead of the default, false)
-  // which ensures that the rest of the system thinks that the frame actually
-  // was transmitted.
-  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
-    if (frame.type == MAX_STREAMS_FRAME) {
-      DeleteFrame(&const_cast<QuicFrame&>(frame));
-      return true;
-    }
-    return false;
-  }
-
- protected:
-  QuicSimpleServerSessionTest()
-      : crypto_config_(QuicCryptoServerConfig::TESTING,
-                       QuicRandom::GetInstance(),
-                       crypto_test_utils::ProofSourceForTesting(),
-                       KeyExchangeSource::Default()),
-        compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
-    config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
-    QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
-                                                       kMaxStreamsForTest);
-    config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
-
-    config_.SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-        kInitialStreamFlowControlWindowForTest);
-    config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-        kInitialStreamFlowControlWindowForTest);
-    config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
-        kInitialStreamFlowControlWindowForTest);
-    config_.SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-    if (VersionUsesHttp3(transport_version())) {
-      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
-          &config_, kMaxStreamsForTest + 3);
-    } else {
-      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
-                                                          kMaxStreamsForTest);
-    }
-
-    ParsedQuicVersionVector supported_versions = SupportedVersions(version());
-    connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
-        &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    connection_->SetEncrypter(
-        ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<NullEncrypter>(connection_->perspective()));
-    session_ = std::make_unique<MockQuicSimpleServerSession>(
-        config_, connection_, &owner_, &stream_helper_, &crypto_config_,
-        &compressed_certs_cache_, &memory_cache_backend_);
-    MockClock clock;
-    handshake_message_ = crypto_config_.AddDefaultConfig(
-        QuicRandom::GetInstance(), &clock,
-        QuicCryptoServerConfig::ConfigOptions());
-    session_->Initialize();
-
-    if (VersionHasIetfQuicFrames(transport_version())) {
-      EXPECT_CALL(*session_, WriteControlFrame(_, _))
-          .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
-    }
-    session_->OnConfigNegotiated();
-  }
-
-  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
-  }
-
-  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
-    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
-        transport_version(), n);
-  }
-
-  ParsedQuicVersion version() const { return GetParam(); }
-
-  QuicTransportVersion transport_version() const {
-    return version().transport_version;
-  }
-
-  void InjectStopSending(QuicStreamId stream_id,
-                         QuicRstStreamErrorCode rst_stream_code) {
-    // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-    // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
-    // a one-way close.
-    if (!VersionHasIetfQuicFrames(transport_version())) {
-      // Only needed for version 99/IETF QUIC.
-      return;
-    }
-    EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
-                                      rst_stream_code);
-    // Expect the RESET_STREAM that is generated in response to receiving a
-    // STOP_SENDING.
-    EXPECT_CALL(*connection_, OnStreamReset(stream_id, rst_stream_code));
-    session_->OnStopSendingFrame(stop_sending);
-  }
-
-  StrictMock<MockQuicSessionVisitor> owner_;
-  StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnectionWithSendStreamData>* connection_;
-  QuicConfig config_;
-  QuicCryptoServerConfig crypto_config_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-  QuicMemoryCacheBackend memory_cache_backend_;
-  std::unique_ptr<MockQuicSimpleServerSession> session_;
-  std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         QuicSimpleServerSessionTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
-  // Send some data open a stream, then reset it.
-  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        kStreamData);
-  session_->OnStreamFrame(data1);
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Receive a reset (and send a RST in response).
-  QuicRstStreamFrame rst1(kInvalidControlFrameId,
-                          GetNthClientInitiatedBidirectionalId(0),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
-  EXPECT_CALL(*session_, WriteControlFrame(_, _));
-
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    // For version 99, this is covered in InjectStopSending()
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  session_->OnRstStream(rst1);
-  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
-  // a one-way close.
-  InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
-                    QUIC_ERROR_PROCESSING_STREAM);
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Send the same two bytes of payload in a new packet.
-  session_->OnStreamFrame(data1);
-
-  // The stream should not be re-opened.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) {
-  // Send a reset (and expect the peer to send a RST in response).
-  QuicRstStreamFrame rst1(kInvalidControlFrameId,
-                          GetNthClientInitiatedBidirectionalId(0),
-                          QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    // For version 99, this is covered in InjectStopSending()
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  session_->OnRstStream(rst1);
-  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
-  // a one-way close.
-  InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
-                    QUIC_ERROR_PROCESSING_STREAM);
-
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        kStreamData);
-  session_->OnStreamFrame(data1);
-
-  // The stream should never be opened, now that the reset is received.
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) {
-  // Send some data to open two streams.
-  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                         kStreamData);
-  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
-                         kStreamData);
-  session_->OnStreamFrame(frame1);
-  session_->OnStreamFrame(frame2);
-  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-
-  // Send a reset (and expect the peer to send a RST in response).
-  QuicRstStreamFrame rst(kInvalidControlFrameId,
-                         GetNthClientInitiatedBidirectionalId(0),
-                         QUIC_ERROR_PROCESSING_STREAM, 0);
-  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
-  if (!VersionHasIetfQuicFrames(transport_version())) {
-    EXPECT_CALL(*session_, WriteControlFrame(_, _));
-    // For version 99, this is covered in InjectStopSending()
-    EXPECT_CALL(*connection_,
-                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
-                              QUIC_RST_ACKNOWLEDGEMENT));
-  }
-  session_->OnRstStream(rst);
-  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
-  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
-  // a one-way close.
-  InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
-                    QUIC_ERROR_PROCESSING_STREAM);
-
-  // If we were tracking, we'd probably want to reject this because it's data
-  // past the reset point of stream 3.  As it's a closed stream we just drop the
-  // data on the floor, but accept the packet because it has data for stream 5.
-  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
-                         kStreamData);
-  QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
-                         kStreamData);
-  session_->OnStreamFrame(frame3);
-  session_->OnStreamFrame(frame4);
-  // The stream should never be opened, now that the reset is received.
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_TRUE(connection_->connected());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateIncomingStreamDisconnected) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (version() != AllSupportedVersions()[0]) {
-    return;
-  }
-
-  // Tests that incoming stream creation fails when connection is not connected.
-  size_t initial_num_open_stream =
-      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
-  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
-  EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateIncomingStream(
-                      session_.get(), GetNthClientInitiatedBidirectionalId(0)),
-                  "ShouldCreateIncomingStream called when disconnected");
-  EXPECT_EQ(initial_num_open_stream,
-            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateIncomingStream) {
-  QuicSpdyStream* stream = QuicSimpleServerSessionPeer::CreateIncomingStream(
-      session_.get(), GetNthClientInitiatedBidirectionalId(0));
-  EXPECT_NE(nullptr, stream);
-  EXPECT_EQ(GetNthClientInitiatedBidirectionalId(0), stream->id());
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamDisconnected) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (version() != AllSupportedVersions()[0]) {
-    return;
-  }
-
-  // Tests that outgoing stream creation fails when connection is not connected.
-  size_t initial_num_open_stream =
-      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
-  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
-  EXPECT_QUIC_BUG(
-      QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
-          session_.get()),
-      "ShouldCreateOutgoingUnidirectionalStream called when disconnected");
-
-  EXPECT_EQ(initial_num_open_stream,
-            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUnencrypted) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (version() != AllSupportedVersions()[0]) {
-    return;
-  }
-
-  // Tests that outgoing stream creation fails when encryption has not yet been
-  // established.
-  size_t initial_num_open_stream =
-      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
-  EXPECT_QUIC_BUG(
-      QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
-          session_.get()),
-      "Encryption not established so no outgoing stream created.");
-  EXPECT_EQ(initial_num_open_stream,
-            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
-  // Tests that outgoing stream creation should not be affected by existing
-  // incoming stream and vice-versa. But when reaching the limit of max outgoing
-  // stream allowed, creation should fail.
-
-  // Receive some data to initiate a incoming stream which should not effect
-  // creating outgoing streams.
-  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
-                        kStreamData);
-  session_->OnStreamFrame(data1);
-  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
-                    /*incoming=*/1);
-
-  if (!VersionUsesHttp3(transport_version())) {
-    session_->UnregisterStreamPriority(
-        QuicUtils::GetHeadersStreamId(transport_version()),
-        /*is_static=*/true);
-  }
-  // Assume encryption already established.
-  QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
-  QuicCryptoServerStreamBase* crypto_stream =
-      CreateMockCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
-                                   session_.get(), &stream_helper_);
-  QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
-  if (!VersionUsesHttp3(transport_version())) {
-    session_->RegisterStreamPriority(
-        QuicUtils::GetHeadersStreamId(transport_version()),
-        /*is_static=*/true,
-        spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
-  }
-
-  // Create push streams till reaching the upper limit of allowed open streams.
-  for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
-    QuicSpdyStream* created_stream =
-        QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
-            session_.get());
-    if (VersionUsesHttp3(transport_version())) {
-      EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i + 3),
-                created_stream->id());
-    } else {
-      EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i), created_stream->id());
-    }
-    EXPECT_EQ(i + 1, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
-                         /*incoming=*/1);
-  }
-
-  // Continuing creating push stream would fail.
-  EXPECT_EQ(nullptr,
-            QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
-                session_.get()));
-  EXPECT_EQ(kMaxStreamsForTest,
-            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
-                /*incoming=*/1);
-
-  // Create peer initiated stream should have no problem.
-  QuicStreamFrame data2(GetNthClientInitiatedBidirectionalId(1), false, 0,
-                        kStreamData);
-  session_->OnStreamFrame(data2);
-  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
-                    /*outcoming=*/kMaxStreamsForTest);
-}
-
-TEST_P(QuicSimpleServerSessionTest, OnStreamFrameWithEvenStreamId) {
-  QuicStreamFrame frame(GetNthServerInitiatedUnidirectionalId(0), false, 0,
-                        kStreamData);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_STREAM_ID,
-                              "Client sent data on server push stream", _));
-  session_->OnStreamFrame(frame);
-}
-
-// Tests that calling GetOrCreateStream() on an outgoing stream not promised yet
-// should result close connection.
-TEST_P(QuicSimpleServerSessionTest, GetEvenIncomingError) {
-  const size_t initial_num_open_stream =
-      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
-  const QuicErrorCode expected_error = VersionUsesHttp3(transport_version())
-                                           ? QUIC_HTTP_STREAM_WRONG_DIRECTION
-                                           : QUIC_INVALID_STREAM_ID;
-  EXPECT_CALL(*connection_, CloseConnection(expected_error,
-                                            "Data for nonexistent stream", _));
-  EXPECT_EQ(nullptr,
-            QuicSessionPeer::GetOrCreateStream(
-                session_.get(), GetNthServerInitiatedUnidirectionalId(3)));
-  EXPECT_EQ(initial_num_open_stream,
-            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/quic_simple_server_stream.cc b/quic/tools/quic_simple_server_stream.cc
deleted file mode 100644
index 0ea0e50..0000000
--- a/quic/tools/quic_simple_server_stream.cc
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_server_stream.h"
-
-#include <list>
-#include <utility>
-
-#include "absl/strings/match.h"
-#include "absl/strings/numbers.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_stream.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/http/web_transport_http3.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/tools/quic_simple_server_session.h"
-#include "spdy/core/spdy_protocol.h"
-
-using spdy::Http2HeaderBlock;
-
-namespace quic {
-
-QuicSimpleServerStream::QuicSimpleServerStream(
-    QuicStreamId id,
-    QuicSpdySession* session,
-    StreamType type,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicSpdyServerStreamBase(id, session, type),
-      content_length_(-1),
-      generate_bytes_length_(0),
-      quic_simple_server_backend_(quic_simple_server_backend) {
-  QUICHE_DCHECK(quic_simple_server_backend_);
-}
-
-QuicSimpleServerStream::QuicSimpleServerStream(
-    PendingStream* pending, QuicSpdySession* session,
-    QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicSpdyServerStreamBase(pending, session),
-      content_length_(-1),
-      generate_bytes_length_(0),
-      quic_simple_server_backend_(quic_simple_server_backend) {
-  QUICHE_DCHECK(quic_simple_server_backend_);
-}
-
-QuicSimpleServerStream::~QuicSimpleServerStream() {
-  quic_simple_server_backend_->CloseBackendResponseStream(this);
-}
-
-void QuicSimpleServerStream::OnInitialHeadersComplete(
-    bool fin,
-    size_t frame_len,
-    const QuicHeaderList& header_list) {
-  QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
-  // QuicSpdyStream::OnInitialHeadersComplete() may have already sent error
-  // response.
-  if (!response_sent_ &&
-      !SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
-                                         &request_headers_)) {
-    QUIC_DVLOG(1) << "Invalid headers";
-      SendErrorResponse();
-  }
-  ConsumeHeaderList();
-  if (!fin && !response_sent_) {
-    // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) require
-    // sending the response right after parsing the headers even though the FIN
-    // bit has not been received on the request stream.
-    auto it = request_headers_.find(":method");
-    if (it != request_headers_.end() &&
-        absl::StartsWith(it->second, "CONNECT")) {
-      SendResponse();
-    }
-  }
-}
-
-void QuicSimpleServerStream::OnTrailingHeadersComplete(
-    bool /*fin*/,
-    size_t /*frame_len*/,
-    const QuicHeaderList& /*header_list*/) {
-  QUIC_BUG(quic_bug_10962_1) << "Server does not support receiving Trailers.";
-  SendErrorResponse();
-}
-
-void QuicSimpleServerStream::OnBodyAvailable() {
-  while (HasBytesToRead()) {
-    struct iovec iov;
-    if (GetReadableRegions(&iov, 1) == 0) {
-      // No more data to read.
-      break;
-    }
-    QUIC_DVLOG(1) << "Stream " << id() << " processed " << iov.iov_len
-                  << " bytes.";
-    body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
-
-    if (content_length_ >= 0 &&
-        body_.size() > static_cast<uint64_t>(content_length_)) {
-      QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
-                    << content_length_ << ").";
-      SendErrorResponse();
-      return;
-    }
-    MarkConsumed(iov.iov_len);
-  }
-  if (!sequencer()->IsClosed()) {
-    sequencer()->SetUnblocked();
-    return;
-  }
-
-  // If the sequencer is closed, then all the body, including the fin, has been
-  // consumed.
-  OnFinRead();
-
-  if (write_side_closed() || fin_buffered()) {
-    return;
-  }
-
-  SendResponse();
-}
-
-void QuicSimpleServerStream::PushResponse(
-    Http2HeaderBlock push_request_headers) {
-  if (QuicUtils::IsClientInitiatedStreamId(session()->transport_version(),
-                                           id())) {
-    QUIC_BUG(quic_bug_10962_2)
-        << "Client initiated stream shouldn't be used as promised stream.";
-    return;
-  }
-  // Change the stream state to emulate a client request.
-  request_headers_ = std::move(push_request_headers);
-  content_length_ = 0;
-  QUIC_DVLOG(1) << "Stream " << id()
-                << " ready to receive server push response.";
-  QUICHE_DCHECK(reading_stopped());
-
-  // Directly send response based on the emulated request_headers_.
-  SendResponse();
-}
-
-void QuicSimpleServerStream::SendResponse() {
-  if (request_headers_.empty()) {
-    QUIC_DVLOG(1) << "Request headers empty.";
-    SendErrorResponse();
-    return;
-  }
-
-  if (content_length_ > 0 &&
-      static_cast<uint64_t>(content_length_) != body_.size()) {
-    QUIC_DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
-                  << body_.size() << ").";
-    SendErrorResponse();
-    return;
-  }
-
-  if (!request_headers_.contains(":authority")) {
-    QUIC_DVLOG(1) << "Request headers do not contain :authority.";
-    SendErrorResponse();
-    return;
-  }
-
-  if (!request_headers_.contains(":path")) {
-    // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) do not all
-    // require :path to be present.
-    auto it = request_headers_.find(":method");
-    if (it == request_headers_.end() ||
-        !absl::StartsWith(it->second, "CONNECT")) {
-      QUIC_DVLOG(1) << "Request headers do not contain :path.";
-      SendErrorResponse();
-      return;
-    }
-  }
-
-  if (quic_simple_server_backend_ == nullptr) {
-    QUIC_DVLOG(1) << "Backend is missing.";
-    SendErrorResponse();
-    return;
-  }
-
-  if (web_transport() != nullptr) {
-    QuicSimpleServerBackend::WebTransportResponse response =
-        quic_simple_server_backend_->ProcessWebTransportRequest(
-            request_headers_, web_transport());
-    if (response.response_headers[":status"] == "200") {
-      WriteHeaders(std::move(response.response_headers), false, nullptr);
-      if (response.visitor != nullptr) {
-        web_transport()->SetVisitor(std::move(response.visitor));
-      }
-      web_transport()->HeadersReceived(request_headers_);
-    } else {
-      WriteHeaders(std::move(response.response_headers), true, nullptr);
-    }
-    return;
-  }
-
-  // Fetch the response from the backend interface and wait for callback once
-  // response is ready
-  quic_simple_server_backend_->FetchResponseFromBackend(request_headers_, body_,
-                                                        this);
-}
-
-QuicConnectionId QuicSimpleServerStream::connection_id() const {
-  return spdy_session()->connection_id();
-}
-
-QuicStreamId QuicSimpleServerStream::stream_id() const {
-  return id();
-}
-
-std::string QuicSimpleServerStream::peer_host() const {
-  return spdy_session()->peer_address().host().ToString();
-}
-
-void QuicSimpleServerStream::OnResponseBackendComplete(
-    const QuicBackendResponse* response) {
-  if (response == nullptr) {
-    QUIC_DVLOG(1) << "Response not found in cache.";
-    SendNotFoundResponse();
-    return;
-  }
-
-  // Send Early Hints first.
-  for (const auto& headers : response->early_hints()) {
-    QUIC_DVLOG(1) << "Stream " << id() << " sending an Early Hints response: "
-                  << headers.DebugString();
-    WriteHeaders(headers.Clone(), false, nullptr);
-  }
-
-  if (response->response_type() == QuicBackendResponse::CLOSE_CONNECTION) {
-    QUIC_DVLOG(1) << "Special response: closing connection.";
-    OnUnrecoverableError(QUIC_NO_ERROR, "Toy server forcing close");
-    return;
-  }
-
-  if (response->response_type() == QuicBackendResponse::IGNORE_REQUEST) {
-    QUIC_DVLOG(1) << "Special response: ignoring request.";
-    return;
-  }
-
-  if (response->response_type() == QuicBackendResponse::BACKEND_ERR_RESPONSE) {
-    QUIC_DVLOG(1) << "Quic Proxy: Backend connection error.";
-    /*502 Bad Gateway
-      The server was acting as a gateway or proxy and received an
-      invalid response from the upstream server.*/
-    SendErrorResponse(502);
-    return;
-  }
-
-  // Examing response status, if it was not pure integer as typical h2
-  // response status, send error response. Notice that
-  // QuicHttpResponseCache push urls are strictly authority + path only,
-  // scheme is not included (see |QuicHttpResponseCache::GetKey()|).
-  std::string request_url = request_headers_[":authority"].as_string() +
-                            request_headers_[":path"].as_string();
-  int response_code;
-  const Http2HeaderBlock& response_headers = response->headers();
-  if (!ParseHeaderStatusCode(response_headers, &response_code)) {
-    auto status = response_headers.find(":status");
-    if (status == response_headers.end()) {
-      QUIC_LOG(WARNING)
-          << ":status not present in response from cache for request "
-          << request_url;
-    } else {
-      QUIC_LOG(WARNING) << "Illegal (non-integer) response :status from cache: "
-                        << status->second << " for request " << request_url;
-    }
-    SendErrorResponse();
-    return;
-  }
-
-  if (QuicUtils::IsServerInitiatedStreamId(session()->transport_version(),
-                                           id())) {
-    // A server initiated stream is only used for a server push response,
-    // and only 200 and 30X response codes are supported for server push.
-    // This behavior mirrors the HTTP/2 implementation.
-    bool is_redirection = response_code / 100 == 3;
-    if (response_code != 200 && !is_redirection) {
-      QUIC_LOG(WARNING) << "Response to server push request " << request_url
-                        << " result in response code " << response_code;
-      Reset(QUIC_STREAM_CANCELLED);
-      return;
-    }
-  }
-
-  if (response->response_type() == QuicBackendResponse::INCOMPLETE_RESPONSE) {
-    QUIC_DVLOG(1)
-        << "Stream " << id()
-        << " sending an incomplete response, i.e. no trailer, no fin.";
-    SendIncompleteResponse(response->headers().Clone(), response->body());
-    return;
-  }
-
-  if (response->response_type() == QuicBackendResponse::GENERATE_BYTES) {
-    QUIC_DVLOG(1) << "Stream " << id() << " sending a generate bytes response.";
-    std::string path = request_headers_[":path"].as_string().substr(1);
-    if (!absl::SimpleAtoi(path, &generate_bytes_length_)) {
-      QUIC_LOG(ERROR) << "Path is not a number.";
-      SendNotFoundResponse();
-      return;
-    }
-    Http2HeaderBlock headers = response->headers().Clone();
-    headers["content-length"] = absl::StrCat(generate_bytes_length_);
-
-    WriteHeaders(std::move(headers), false, nullptr);
-    QUICHE_DCHECK(!response_sent_);
-    response_sent_ = true;
-
-    WriteGeneratedBytes();
-
-    return;
-  }
-
-  QUIC_DVLOG(1) << "Stream " << id() << " sending response.";
-  SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(),
-                                response->trailers().Clone());
-}
-
-void QuicSimpleServerStream::OnCanWrite() {
-  QuicSpdyStream::OnCanWrite();
-  WriteGeneratedBytes();
-}
-
-void QuicSimpleServerStream::WriteGeneratedBytes() {
-  static size_t kChunkSize = 1024;
-  while (!HasBufferedData() && generate_bytes_length_ > 0) {
-    size_t len = std::min<size_t>(kChunkSize, generate_bytes_length_);
-    std::string data(len, 'a');
-    generate_bytes_length_ -= len;
-    bool fin = generate_bytes_length_ == 0;
-    WriteOrBufferBody(data, fin);
-  }
-}
-
-void QuicSimpleServerStream::SendNotFoundResponse() {
-  QUIC_DVLOG(1) << "Stream " << id() << " sending not found response.";
-  Http2HeaderBlock headers;
-  headers[":status"] = "404";
-  headers["content-length"] = absl::StrCat(strlen(kNotFoundResponseBody));
-  SendHeadersAndBody(std::move(headers), kNotFoundResponseBody);
-}
-
-void QuicSimpleServerStream::SendErrorResponse() {
-  SendErrorResponse(0);
-}
-
-void QuicSimpleServerStream::SendErrorResponse(int resp_code) {
-  QUIC_DVLOG(1) << "Stream " << id() << " sending error response.";
-  if (!reading_stopped()) {
-    StopReading();
-  }
-  Http2HeaderBlock headers;
-  if (resp_code <= 0) {
-    headers[":status"] = "500";
-  } else {
-    headers[":status"] = absl::StrCat(resp_code);
-  }
-  headers["content-length"] = absl::StrCat(strlen(kErrorResponseBody));
-  SendHeadersAndBody(std::move(headers), kErrorResponseBody);
-}
-
-void QuicSimpleServerStream::SendIncompleteResponse(
-    Http2HeaderBlock response_headers,
-    absl::string_view body) {
-  QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = false) : "
-                  << response_headers.DebugString();
-  WriteHeaders(std::move(response_headers), /*fin=*/false, nullptr);
-  QUICHE_DCHECK(!response_sent_);
-  response_sent_ = true;
-
-  QUIC_DLOG(INFO) << "Stream " << id()
-                  << " writing body (fin = false) with size: " << body.size();
-  if (!body.empty()) {
-    WriteOrBufferBody(body, /*fin=*/false);
-  }
-}
-
-void QuicSimpleServerStream::SendHeadersAndBody(
-    Http2HeaderBlock response_headers,
-    absl::string_view body) {
-  SendHeadersAndBodyAndTrailers(std::move(response_headers), body,
-                                Http2HeaderBlock());
-}
-
-void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
-    Http2HeaderBlock response_headers,
-    absl::string_view body,
-    Http2HeaderBlock response_trailers) {
-  // Send the headers, with a FIN if there's nothing else to send.
-  bool send_fin = (body.empty() && response_trailers.empty());
-  QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = " << send_fin
-                  << ") : " << response_headers.DebugString();
-  WriteHeaders(std::move(response_headers), send_fin, nullptr);
-  QUICHE_DCHECK(!response_sent_);
-  response_sent_ = true;
-  if (send_fin) {
-    // Nothing else to send.
-    return;
-  }
-
-  // Send the body, with a FIN if there's no trailers to send.
-  send_fin = response_trailers.empty();
-  QUIC_DLOG(INFO) << "Stream " << id() << " writing body (fin = " << send_fin
-                  << ") with size: " << body.size();
-  if (!body.empty() || send_fin) {
-    WriteOrBufferBody(body, send_fin);
-  }
-  if (send_fin) {
-    // Nothing else to send.
-    return;
-  }
-
-  // Send the trailers. A FIN is always sent with trailers.
-  QUIC_DLOG(INFO) << "Stream " << id() << " writing trailers (fin = true): "
-                  << response_trailers.DebugString();
-  WriteTrailers(std::move(response_trailers), nullptr);
-}
-
-void QuicSimpleServerStream::OnInvalidHeaders() {
-  QUIC_DVLOG(1) << "Invalid headers";
-  SendErrorResponse(400);
-}
-
-const char* const QuicSimpleServerStream::kErrorResponseBody = "bad";
-const char* const QuicSimpleServerStream::kNotFoundResponseBody =
-    "file not found";
-
-}  // namespace quic
diff --git a/quic/tools/quic_simple_server_stream.h b/quic/tools/quic_simple_server_stream.h
deleted file mode 100644
index cd04bd7..0000000
--- a/quic/tools/quic_simple_server_stream.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
-
-#include "absl/strings/string_view.h"
-#include "quic/core/http/quic_spdy_server_stream_base.h"
-#include "quic/core/quic_packets.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "spdy/core/spdy_framer.h"
-
-namespace quic {
-
-// All this does right now is aggregate data, and on fin, send an HTTP
-// response.
-class QuicSimpleServerStream : public QuicSpdyServerStreamBase,
-                               public QuicSimpleServerBackend::RequestHandler {
- public:
-  QuicSimpleServerStream(QuicStreamId id,
-                         QuicSpdySession* session,
-                         StreamType type,
-                         QuicSimpleServerBackend* quic_simple_server_backend);
-  QuicSimpleServerStream(PendingStream* pending,
-                         QuicSpdySession* session,
-                         QuicSimpleServerBackend* quic_simple_server_backend);
-  QuicSimpleServerStream(const QuicSimpleServerStream&) = delete;
-  QuicSimpleServerStream& operator=(const QuicSimpleServerStream&) = delete;
-  ~QuicSimpleServerStream() override;
-
-  // QuicSpdyStream
-  void OnInitialHeadersComplete(bool fin,
-                                size_t frame_len,
-                                const QuicHeaderList& header_list) override;
-  void OnTrailingHeadersComplete(bool fin,
-                                 size_t frame_len,
-                                 const QuicHeaderList& header_list) override;
-  void OnCanWrite() override;
-
-  // QuicStream implementation called by the sequencer when there is
-  // data (or a FIN) to be read.
-  void OnBodyAvailable() override;
-
-  void OnInvalidHeaders() override;
-
-  // Make this stream start from as if it just finished parsing an incoming
-  // request whose headers are equivalent to |push_request_headers|.
-  // Doing so will trigger this toy stream to fetch response and send it back.
-  virtual void PushResponse(spdy::Http2HeaderBlock push_request_headers);
-
-  // The response body of error responses.
-  static const char* const kErrorResponseBody;
-  static const char* const kNotFoundResponseBody;
-
-  // Implements QuicSimpleServerBackend::RequestHandler callbacks
-  QuicConnectionId connection_id() const override;
-  QuicStreamId stream_id() const override;
-  std::string peer_host() const override;
-  void OnResponseBackendComplete(const QuicBackendResponse* response) override;
-
- protected:
-  // Sends a basic 200 response using SendHeaders for the headers and WriteData
-  // for the body.
-  virtual void SendResponse();
-
-  // Sends a basic 500 response using SendHeaders for the headers and WriteData
-  // for the body.
-  virtual void SendErrorResponse();
-  virtual void SendErrorResponse(int resp_code);
-
-  // Sends a basic 404 response using SendHeaders for the headers and WriteData
-  // for the body.
-  void SendNotFoundResponse();
-
-  // Sends the response header and body, but not the fin.
-  void SendIncompleteResponse(spdy::Http2HeaderBlock response_headers,
-                              absl::string_view body);
-
-  void SendHeadersAndBody(spdy::Http2HeaderBlock response_headers,
-                          absl::string_view body);
-  void SendHeadersAndBodyAndTrailers(spdy::Http2HeaderBlock response_headers,
-                                     absl::string_view body,
-                                     spdy::Http2HeaderBlock response_trailers);
-
-  spdy::Http2HeaderBlock* request_headers() { return &request_headers_; }
-
-  const std::string& body() { return body_; }
-
-  // Writes the body bytes for the GENERATE_BYTES response type.
-  void WriteGeneratedBytes();
-
-  // The parsed headers received from the client.
-  spdy::Http2HeaderBlock request_headers_;
-  int64_t content_length_;
-  std::string body_;
-
- private:
-  uint64_t generate_bytes_length_;
-  // Whether response headers have already been sent.
-  bool response_sent_ = false;
-
-  QuicSimpleServerBackend* quic_simple_server_backend_;  // Not owned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
diff --git a/quic/tools/quic_simple_server_stream_test.cc b/quic/tools/quic_simple_server_stream_test.cc
deleted file mode 100644
index 411ee96..0000000
--- a/quic/tools/quic_simple_server_stream_test.cc
+++ /dev/null
@@ -1,790 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_simple_server_stream.h"
-
-#include <list>
-#include <memory>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "quic/core/crypto/null_encrypter.h"
-#include "quic/core/http/http_encoder.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_error_codes.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_utils.h"
-#include "quic/platform/api/quic_expect_bug.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/crypto_test_utils.h"
-#include "quic/test_tools/quic_config_peer.h"
-#include "quic/test_tools/quic_connection_peer.h"
-#include "quic/test_tools/quic_session_peer.h"
-#include "quic/test_tools/quic_spdy_session_peer.h"
-#include "quic/test_tools/quic_stream_peer.h"
-#include "quic/test_tools/quic_test_utils.h"
-#include "quic/tools/quic_backend_response.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "quic/tools/quic_simple_server_session.h"
-#include "common/simple_buffer_allocator.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::InSequence;
-using testing::Invoke;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-
-const size_t kFakeFrameLen = 60;
-const size_t kErrorLength = strlen(QuicSimpleServerStream::kErrorResponseBody);
-const size_t kDataFrameHeaderLength = 2;
-
-class TestStream : public QuicSimpleServerStream {
- public:
-  TestStream(QuicStreamId stream_id, QuicSpdySession* session, StreamType type,
-             QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicSimpleServerStream(stream_id, session, type,
-                               quic_simple_server_backend) {}
-
-  ~TestStream() override = default;
-
-  MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
-  MOCK_METHOD(void, WriteEarlyHintsHeadersMock, (bool fin), ());
-
-  size_t WriteHeaders(
-      spdy::Http2HeaderBlock header_block, bool fin,
-      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
-      /*ack_listener*/) override {
-    if (header_block[":status"] == "103") {
-      WriteEarlyHintsHeadersMock(fin);
-    } else {
-      WriteHeadersMock(fin);
-    }
-    return 0;
-  }
-
-  // Expose protected QuicSimpleServerStream methods.
-  void DoSendResponse() { SendResponse(); }
-  void DoSendErrorResponse() { QuicSimpleServerStream::SendErrorResponse(); }
-
-  spdy::Http2HeaderBlock* mutable_headers() { return &request_headers_; }
-  void set_body(std::string body) { body_ = std::move(body); }
-  const std::string& body() const { return body_; }
-  int content_length() const { return content_length_; }
-  bool send_response_was_called() const { return send_response_was_called_; }
-  bool send_error_response_was_called() const {
-    return send_error_response_was_called_;
-  }
-
-  absl::string_view GetHeader(absl::string_view key) const {
-    auto it = request_headers_.find(key);
-    QUICHE_DCHECK(it != request_headers_.end());
-    return it->second;
-  }
-
- protected:
-  void SendResponse() override {
-    send_response_was_called_ = true;
-    QuicSimpleServerStream::SendResponse();
-  }
-
-  void SendErrorResponse(int resp_code) override {
-    send_error_response_was_called_ = true;
-    QuicSimpleServerStream::SendErrorResponse(resp_code);
-  }
-
- private:
-  bool send_response_was_called_ = false;
-  bool send_error_response_was_called_ = false;
-};
-
-namespace {
-
-class MockQuicSimpleServerSession : public QuicSimpleServerSession {
- public:
-  const size_t kMaxStreamsForTest = 100;
-
-  MockQuicSimpleServerSession(
-      QuicConnection* connection, MockQuicSessionVisitor* owner,
-      MockQuicCryptoServerStreamHelper* helper,
-      QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      QuicSimpleServerBackend* quic_simple_server_backend)
-      : QuicSimpleServerSession(DefaultQuicConfig(), CurrentSupportedVersions(),
-                                connection, owner, helper, crypto_config,
-                                compressed_certs_cache,
-                                quic_simple_server_backend) {
-    if (VersionHasIetfQuicFrames(connection->transport_version())) {
-      QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
-          this, kMaxStreamsForTest);
-      QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
-          this, kMaxStreamsForTest);
-    } else {
-      QuicSessionPeer::SetMaxOpenIncomingStreams(this, kMaxStreamsForTest);
-      QuicSessionPeer::SetMaxOpenOutgoingStreams(this, kMaxStreamsForTest);
-    }
-    ON_CALL(*this, WritevData(_, _, _, _, _, _))
-        .WillByDefault(Invoke(this, &MockQuicSimpleServerSession::ConsumeData));
-  }
-
-  MockQuicSimpleServerSession(const MockQuicSimpleServerSession&) = delete;
-  MockQuicSimpleServerSession& operator=(const MockQuicSimpleServerSession&) =
-      delete;
-  ~MockQuicSimpleServerSession() override = default;
-
-  MOCK_METHOD(void, OnConnectionClosed,
-              (const QuicConnectionCloseFrame& frame,
-               ConnectionCloseSource source),
-              (override));
-  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
-              (override));
-  MOCK_METHOD(QuicConsumedData, WritevData,
-              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
-               StreamSendingState state, TransmissionType type,
-               EncryptionLevel level),
-              (override));
-  MOCK_METHOD(void, OnStreamHeaderList,
-              (QuicStreamId stream_id, bool fin, size_t frame_len,
-               const QuicHeaderList& header_list),
-              (override));
-  MOCK_METHOD(void, OnStreamHeadersPriority,
-              (QuicStreamId stream_id,
-               const spdy::SpdyStreamPrecedence& precedence),
-              (override));
-  MOCK_METHOD(void, MaybeSendRstStreamFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error,
-               QuicStreamOffset bytes_written),
-              (override));
-  MOCK_METHOD(void, MaybeSendStopSendingFrame,
-              (QuicStreamId stream_id, QuicResetStreamError error), (override));
-
-  using QuicSession::ActivateStream;
-
-  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
-                               QuicStreamOffset offset,
-                               StreamSendingState state,
-                               TransmissionType /*type*/,
-                               absl::optional<EncryptionLevel> /*level*/) {
-    if (write_length > 0) {
-      auto buf = std::make_unique<char[]>(write_length);
-      QuicStream* stream = GetOrCreateStream(id);
-      QUICHE_DCHECK(stream);
-      QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
-      stream->WriteStreamData(offset, write_length, &writer);
-    } else {
-      QUICHE_DCHECK(state != NO_FIN);
-    }
-    return QuicConsumedData(write_length, state != NO_FIN);
-  }
-
-  spdy::Http2HeaderBlock original_request_headers_;
-};
-
-class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
- public:
-  QuicSimpleServerStreamTest()
-      : connection_(new StrictMock<MockQuicConnection>(
-            &helper_, &alarm_factory_, Perspective::IS_SERVER,
-            SupportedVersions(GetParam()))),
-        crypto_config_(new QuicCryptoServerConfig(
-            QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
-            crypto_test_utils::ProofSourceForTesting(),
-            KeyExchangeSource::Default())),
-        compressed_certs_cache_(
-            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
-        session_(connection_, &session_owner_, &session_helper_,
-                 crypto_config_.get(), &compressed_certs_cache_,
-                 &memory_cache_backend_),
-        quic_response_(new QuicBackendResponse),
-        body_("hello world") {
-    connection_->set_visitor(&session_);
-    header_list_.OnHeaderBlockStart();
-    header_list_.OnHeader(":authority", "www.google.com");
-    header_list_.OnHeader(":path", "/");
-    header_list_.OnHeader(":method", "POST");
-    header_list_.OnHeader(":scheme", "https");
-    header_list_.OnHeader("content-length", "11");
-
-    header_list_.OnHeaderBlockEnd(128, 128);
-
-    // New streams rely on having the peer's flow control receive window
-    // negotiated in the config.
-    session_.config()->SetInitialStreamFlowControlWindowToSend(
-        kInitialStreamFlowControlWindowForTest);
-    session_.config()->SetInitialSessionFlowControlWindowToSend(
-        kInitialSessionFlowControlWindowForTest);
-    session_.Initialize();
-    connection_->SetEncrypter(
-        quic::ENCRYPTION_FORWARD_SECURE,
-        std::make_unique<quic::NullEncrypter>(connection_->perspective()));
-    if (connection_->version().SupportsAntiAmplificationLimit()) {
-      QuicConnectionPeer::SetAddressValidated(connection_);
-    }
-    stream_ = new StrictMock<TestStream>(
-        GetNthClientInitiatedBidirectionalStreamId(
-            connection_->transport_version(), 0),
-        &session_, BIDIRECTIONAL, &memory_cache_backend_);
-    // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
-    session_.ActivateStream(absl::WrapUnique(stream_));
-    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
-        session_.config(), kMinimumFlowControlSendWindow);
-    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 10);
-    session_.OnConfigNegotiated();
-    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
-  }
-
-  const std::string& StreamBody() { return stream_->body(); }
-
-  std::string StreamHeadersValue(const std::string& key) {
-    return (*stream_->mutable_headers())[key].as_string();
-  }
-
-  bool UsesHttp3() const {
-    return VersionUsesHttp3(connection_->transport_version());
-  }
-
-  spdy::Http2HeaderBlock response_headers_;
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  StrictMock<MockQuicSessionVisitor> session_owner_;
-  StrictMock<MockQuicCryptoServerStreamHelper> session_helper_;
-  std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
-  QuicCompressedCertsCache compressed_certs_cache_;
-  QuicMemoryCacheBackend memory_cache_backend_;
-  StrictMock<MockQuicSimpleServerSession> session_;
-  StrictMock<TestStream>* stream_;  // Owned by session_.
-  std::unique_ptr<QuicBackendResponse> quic_response_;
-  std::string body_;
-  QuicHeaderList header_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests, QuicSimpleServerStreamTest,
-                         ::testing::ValuesIn(AllSupportedVersions()),
-                         ::testing::PrintToStringParamName());
-
-TEST_P(QuicSimpleServerStreamTest, TestFraming) {
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data =
-      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  EXPECT_EQ("11", StreamHeadersValue("content-length"));
-  EXPECT_EQ("/", StreamHeadersValue(":path"));
-  EXPECT_EQ("POST", StreamHeadersValue(":method"));
-  EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-
-  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data =
-      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  EXPECT_EQ("11", StreamHeadersValue("content-length"));
-  EXPECT_EQ("/", StreamHeadersValue(":path"));
-  EXPECT_EQ("POST", StreamHeadersValue(":method"));
-  EXPECT_EQ(body_, StreamBody());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-
-  EXPECT_FALSE(stream_->fin_received());
-  EXPECT_FALSE(stream_->rst_received());
-
-  QuicStreamPeer::SetFinSent(stream_);
-  stream_->CloseWriteSide();
-
-  if (session_.version().UsesHttp3()) {
-    EXPECT_CALL(session_,
-                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
-                                                 QUIC_STREAM_NO_ERROR)))
-        .Times(1);
-  } else {
-    EXPECT_CALL(
-        session_,
-        MaybeSendRstStreamFrame(
-            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
-        .Times(1);
-  }
-  stream_->StopReading();
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
-  InSequence seq;
-  std::string large_body = "hello world!!!!!!";
-
-  // We'll automatically write out an error (headers + body)
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_,
-                WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
-  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data =
-      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
-
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  // Content length is still 11.  This will register as an error and we won't
-  // accept the bytes.
-  header = HttpEncoder::SerializeDataFrameHeader(
-      large_body.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data2 = UsesHttp3()
-                          ? absl::StrCat(header.AsStringView(), large_body)
-                          : large_body;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/true, data.size(), data2));
-  EXPECT_EQ("11", StreamHeadersValue("content-length"));
-  EXPECT_EQ("/", StreamHeadersValue(":path"));
-  EXPECT_EQ("POST", StreamHeadersValue(":method"));
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
-  // Send an illegal response with response status not supported by HTTP/2.
-  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
-  (*request_headers)[":path"] = "/bar";
-  (*request_headers)[":authority"] = "www.google.com";
-  (*request_headers)[":method"] = "GET";
-
-  // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
-  response_headers_[":status"] = "200 OK";
-  response_headers_["content-length"] = "5";
-  std::string body = "Yummm";
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body.length(), quiche::SimpleBufferAllocator::Get());
-
-  memory_cache_backend_.AddResponse("www.google.com", "/bar",
-                                    std::move(response_headers_), body);
-
-  QuicStreamPeer::SetFinReceived(stream_);
-
-  InSequence s;
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
-  stream_->DoSendResponse();
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) {
-  // Send an illegal response with response status not supported by HTTP/2.
-  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
-  (*request_headers)[":path"] = "/bar";
-  (*request_headers)[":authority"] = "www.google.com";
-  (*request_headers)[":method"] = "GET";
-
-  // HTTP/2 only supports 3-digit-integer, so "+200" is illegal.
-  response_headers_[":status"] = "+200";
-  response_headers_["content-length"] = "5";
-  std::string body = "Yummm";
-
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body.length(), quiche::SimpleBufferAllocator::Get());
-
-  memory_cache_backend_.AddResponse("www.google.com", "/bar",
-                                    std::move(response_headers_), body);
-
-  QuicStreamPeer::SetFinReceived(stream_);
-
-  InSequence s;
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
-  stream_->DoSendResponse();
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) {
-  // Create a new promised stream with even id().
-  auto promised_stream = new StrictMock<TestStream>(
-      GetNthServerInitiatedUnidirectionalStreamId(
-          connection_->transport_version(), 3),
-      &session_, WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
-  session_.ActivateStream(absl::WrapUnique(promised_stream));
-
-  // Send a push response with response status 404, which will be regarded as
-  // invalid server push response.
-  spdy::Http2HeaderBlock* request_headers = promised_stream->mutable_headers();
-  (*request_headers)[":path"] = "/bar";
-  (*request_headers)[":authority"] = "www.google.com";
-  (*request_headers)[":method"] = "GET";
-
-  response_headers_[":status"] = "404";
-  response_headers_["content-length"] = "8";
-  std::string body = "NotFound";
-
-  memory_cache_backend_.AddResponse("www.google.com", "/bar",
-                                    std::move(response_headers_), body);
-
-  InSequence s;
-  if (session_.version().UsesHttp3()) {
-    EXPECT_CALL(session_,
-                MaybeSendStopSendingFrame(
-                    promised_stream->id(),
-                    QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)));
-  }
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          promised_stream->id(),
-          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0));
-
-  promised_stream->DoSendResponse();
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
-  // Add a request and response with valid headers.
-  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
-  (*request_headers)[":path"] = "/bar";
-  (*request_headers)[":authority"] = "www.google.com";
-  (*request_headers)[":method"] = "GET";
-
-  response_headers_[":status"] = "200";
-  response_headers_["content-length"] = "5";
-  std::string body = "Yummm";
-
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body.length(), quiche::SimpleBufferAllocator::Get());
-
-  memory_cache_backend_.AddResponse("www.google.com", "/bar",
-                                    std::move(response_headers_), body);
-  QuicStreamPeer::SetFinReceived(stream_);
-
-  InSequence s;
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
-
-  stream_->DoSendResponse();
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, SendResponseWithEarlyHints) {
-  std::string host = "www.google.com";
-  std::string request_path = "/foo";
-  std::string body = "Yummm";
-
-  // Add a request and response with early hints.
-  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
-  (*request_headers)[":path"] = request_path;
-  (*request_headers)[":authority"] = host;
-  (*request_headers)[":method"] = "GET";
-
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body.length(), quiche::SimpleBufferAllocator::Get());
-  std::vector<spdy::Http2HeaderBlock> early_hints;
-  // Add two Early Hints.
-  const size_t kNumEarlyHintsResponses = 2;
-  for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
-    spdy::Http2HeaderBlock hints;
-    hints["link"] = "</image.png>; rel=preload; as=image";
-    early_hints.push_back(std::move(hints));
-  }
-
-  response_headers_[":status"] = "200";
-  response_headers_["content-length"] = "5";
-  memory_cache_backend_.AddResponseWithEarlyHints(
-      host, request_path, std::move(response_headers_), body, early_hints);
-  QuicStreamPeer::SetFinReceived(stream_);
-
-  InSequence s;
-  for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
-    EXPECT_CALL(*stream_, WriteEarlyHintsHeadersMock(false));
-  }
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
-
-  stream_->DoSendResponse();
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) {
-  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
-  if (GetParam() != AllSupportedVersions()[0]) {
-    return;
-  }
-
-  // Calling PushResponse() on a client initialted stream is never supposed to
-  // happen.
-  EXPECT_QUIC_BUG(stream_->PushResponse(spdy::Http2HeaderBlock()),
-                  "Client initiated stream"
-                  " shouldn't be used as promised stream.");
-}
-
-TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
-  // Tests that PushResponse() should take the given headers as request headers
-  // and fetch response from cache, and send it out.
-
-  // Create a stream with even stream id and test against this stream.
-  const QuicStreamId kServerInitiatedStreamId =
-      GetNthServerInitiatedUnidirectionalStreamId(
-          connection_->transport_version(), 3);
-  // Create a server initiated stream and pass it to session_.
-  auto server_initiated_stream =
-      new StrictMock<TestStream>(kServerInitiatedStreamId, &session_,
-                                 WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
-  session_.ActivateStream(absl::WrapUnique(server_initiated_stream));
-
-  const std::string kHost = "www.foo.com";
-  const std::string kPath = "/bar";
-  spdy::Http2HeaderBlock headers;
-  headers[":path"] = kPath;
-  headers[":authority"] = kHost;
-  headers[":method"] = "GET";
-
-  response_headers_[":status"] = "200";
-  response_headers_["content-length"] = "5";
-  const std::string kBody = "Hello";
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  memory_cache_backend_.AddResponse(kHost, kPath, std::move(response_headers_),
-                                    kBody);
-
-  // Call PushResponse() should trigger stream to fetch response from cache
-  // and send it back.
-  InSequence s;
-  EXPECT_CALL(*server_initiated_stream, WriteHeadersMock(false));
-
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, header.size(), _,
-                                     NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_,
-              WritevData(kServerInitiatedStreamId, kBody.size(), _, FIN, _, _));
-  server_initiated_stream->PushResponse(std::move(headers));
-  EXPECT_EQ(kPath, server_initiated_stream->GetHeader(":path"));
-  EXPECT_EQ("GET", server_initiated_stream->GetHeader(":method"));
-}
-
-TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
-  QuicStreamPeer::SetFinReceived(stream_);
-
-  InSequence s;
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_,
-                WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
-  }
-  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
-
-  stream_->DoSendErrorResponse();
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
-  spdy::Http2HeaderBlock request_headers;
-  // \000 is a way to write the null byte when followed by a literal digit.
-  header_list_.OnHeader("content-length", absl::string_view("11\00012", 5));
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-  stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
-
-  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->reading_stopped());
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
-  spdy::Http2HeaderBlock request_headers;
-  // \000 is a way to write the null byte when followed by a literal digit.
-  header_list_.OnHeader("content-length", absl::string_view("\00012", 3));
-
-  EXPECT_CALL(*stream_, WriteHeadersMock(false));
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-  stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
-
-  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_TRUE(stream_->reading_stopped());
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) {
-  spdy::Http2HeaderBlock request_headers;
-  // \000 is a way to write the null byte when followed by a literal digit.
-  header_list_.OnHeader("content-length", absl::string_view("11\00011", 5));
-
-  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
-
-  EXPECT_EQ(11, stream_->content_length());
-  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
-  EXPECT_FALSE(stream_->reading_stopped());
-  EXPECT_FALSE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest,
-       DoNotSendQuicRstStreamNoErrorWithRstReceived) {
-  EXPECT_FALSE(stream_->reading_stopped());
-
-  if (VersionUsesHttp3(connection_->transport_version())) {
-    // Unidirectional stream type and then a Stream Cancellation instruction is
-    // sent on the QPACK decoder stream.  Ignore these writes without any
-    // assumption on their number or size.
-    auto* qpack_decoder_stream =
-        QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
-    EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _))
-        .Times(AnyNumber());
-  }
-
-  EXPECT_CALL(
-      session_,
-      MaybeSendRstStreamFrame(
-          _,
-          session_.version().UsesHttp3()
-              ? QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)
-              : QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT),
-          _))
-      .Times(1);
-  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
-                               QUIC_STREAM_CANCELLED, 1234);
-  stream_->OnStreamReset(rst_frame);
-  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
-    EXPECT_CALL(session_owner_, OnStopSendingReceived(_));
-    // Create and inject a STOP SENDING frame to complete the close
-    // of the stream. This is only needed for version 99/IETF QUIC.
-    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
-                                      QUIC_STREAM_CANCELLED);
-    session_.OnStopSendingFrame(stop_sending);
-  }
-  EXPECT_TRUE(stream_->reading_stopped());
-  EXPECT_TRUE(stream_->write_side_closed());
-}
-
-TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
-  char arr[] = {
-      0x3a,   0x68, 0x6f, 0x73,  // :hos
-      0x74,   0x00, 0x00, 0x00,  // t...
-      0x00,   0x00, 0x00, 0x00,  // ....
-      0x07,   0x3a, 0x6d, 0x65,  // .:me
-      0x74,   0x68, 0x6f, 0x64,  // thod
-      0x00,   0x00, 0x00, 0x03,  // ....
-      0x47,   0x45, 0x54, 0x00,  // GET.
-      0x00,   0x00, 0x05, 0x3a,  // ...:
-      0x70,   0x61, 0x74, 0x68,  // path
-      0x00,   0x00, 0x00, 0x04,  // ....
-      0x2f,   0x66, 0x6f, 0x6f,  // /foo
-      0x00,   0x00, 0x00, 0x07,  // ....
-      0x3a,   0x73, 0x63, 0x68,  // :sch
-      0x65,   0x6d, 0x65, 0x00,  // eme.
-      0x00,   0x00, 0x00, 0x00,  // ....
-      0x00,   0x00, 0x08, 0x3a,  // ...:
-      0x76,   0x65, 0x72, 0x73,  // vers
-      '\x96', 0x6f, 0x6e, 0x00,  // <i(69)>on.
-      0x00,   0x00, 0x08, 0x48,  // ...H
-      0x54,   0x54, 0x50, 0x2f,  // TTP/
-      0x31,   0x2e, 0x31,        // 1.1
-  };
-  absl::string_view data(arr, ABSL_ARRAYSIZE(arr));
-  QuicStreamFrame frame(stream_->id(), true, 0, data);
-  // Verify that we don't crash when we get a invalid headers in stream frame.
-  stream_->OnStreamFrame(frame);
-}
-
-TEST_P(QuicSimpleServerStreamTest, ConnectSendsResponseBeforeFinReceived) {
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  header_list.OnHeaderBlockEnd(128, 128);
-  EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
-  stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
-  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
-      body_.length(), quiche::SimpleBufferAllocator::Get());
-  std::string data =
-      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
-  EXPECT_EQ("CONNECT", StreamHeadersValue(":method"));
-  EXPECT_EQ(body_, StreamBody());
-  EXPECT_TRUE(stream_->send_response_was_called());
-  EXPECT_FALSE(stream_->send_error_response_was_called());
-}
-
-TEST_P(QuicSimpleServerStreamTest, ConnectWithInvalidHeader) {
-  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
-      .WillRepeatedly(
-          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
-  QuicHeaderList header_list;
-  header_list.OnHeaderBlockStart();
-  header_list.OnHeader(":authority", "www.google.com:4433");
-  header_list.OnHeader(":method", "CONNECT");
-  // QUIC requires lower-case header names.
-  header_list.OnHeader("InVaLiD-HeAdEr", "Well that's just wrong!");
-  header_list.OnHeaderBlockEnd(128, 128);
-
-  if (UsesHttp3()) {
-    EXPECT_CALL(session_,
-                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
-                                                 QUIC_STREAM_NO_ERROR)))
-        .Times(1);
-  } else {
-    EXPECT_CALL(
-        session_,
-        MaybeSendRstStreamFrame(
-            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
-        .Times(1);
-  }
-  EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
-  stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
-  EXPECT_FALSE(stream_->send_response_was_called());
-  EXPECT_TRUE(stream_->send_error_response_was_called());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/quic_spdy_client_base.cc b/quic/tools/quic_spdy_client_base.cc
deleted file mode 100644
index 464fa70..0000000
--- a/quic/tools/quic_spdy_client_base.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_spdy_client_base.h"
-
-#include <utility>
-
-#include "absl/strings/numbers.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_random.h"
-#include "quic/core/http/spdy_utils.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/quiche_text_utils.h"
-
-using spdy::Http2HeaderBlock;
-
-namespace quic {
-
-void QuicSpdyClientBase::ClientQuicDataToResend::Resend() {
-  client_->SendRequest(*headers_, body_, fin_);
-  headers_ = nullptr;
-}
-
-QuicSpdyClientBase::QuicDataToResend::QuicDataToResend(
-    std::unique_ptr<Http2HeaderBlock> headers,
-    absl::string_view body,
-    bool fin)
-    : headers_(std::move(headers)), body_(body), fin_(fin) {}
-
-QuicSpdyClientBase::QuicDataToResend::~QuicDataToResend() = default;
-
-QuicSpdyClientBase::QuicSpdyClientBase(
-    const QuicServerId& server_id,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicConfig& config,
-    QuicConnectionHelperInterface* helper,
-    QuicAlarmFactory* alarm_factory,
-    std::unique_ptr<NetworkHelper> network_helper,
-    std::unique_ptr<ProofVerifier> proof_verifier,
-    std::unique_ptr<SessionCache> session_cache)
-    : QuicClientBase(server_id,
-                     supported_versions,
-                     config,
-                     helper,
-                     alarm_factory,
-                     std::move(network_helper),
-                     std::move(proof_verifier),
-                     std::move(session_cache)),
-      store_response_(false),
-      latest_response_code_(-1) {}
-
-QuicSpdyClientBase::~QuicSpdyClientBase() {
-  // We own the push promise index. We need to explicitly kill
-  // the session before the push promise index goes out of scope.
-  ResetSession();
-}
-
-QuicSpdyClientSession* QuicSpdyClientBase::client_session() {
-  return static_cast<QuicSpdyClientSession*>(QuicClientBase::session());
-}
-
-const QuicSpdyClientSession* QuicSpdyClientBase::client_session() const {
-  return static_cast<const QuicSpdyClientSession*>(QuicClientBase::session());
-}
-
-void QuicSpdyClientBase::InitializeSession() {
-  if (max_inbound_header_list_size_ > 0) {
-    client_session()->set_max_inbound_header_list_size(
-        max_inbound_header_list_size_);
-  }
-  client_session()->Initialize();
-  client_session()->CryptoConnect();
-}
-
-void QuicSpdyClientBase::OnClose(QuicSpdyStream* stream) {
-  QUICHE_DCHECK(stream != nullptr);
-  QuicSpdyClientStream* client_stream =
-      static_cast<QuicSpdyClientStream*>(stream);
-
-  const Http2HeaderBlock& response_headers = client_stream->response_headers();
-  if (response_listener_ != nullptr) {
-    response_listener_->OnCompleteResponse(stream->id(), response_headers,
-                                           client_stream->data());
-  }
-
-  // Store response headers and body.
-  if (store_response_) {
-    auto status = response_headers.find(":status");
-    if (status == response_headers.end()) {
-      QUIC_LOG(ERROR) << "Missing :status response header";
-    } else if (!absl::SimpleAtoi(status->second, &latest_response_code_)) {
-      QUIC_LOG(ERROR) << "Invalid :status response header: " << status->second;
-    }
-    latest_response_headers_ = response_headers.DebugString();
-    preliminary_response_headers_ =
-        client_stream->preliminary_headers().DebugString();
-    latest_response_header_block_ = response_headers.Clone();
-    latest_response_body_ = client_stream->data();
-    latest_response_trailers_ =
-        client_stream->received_trailers().DebugString();
-  }
-}
-
-std::unique_ptr<QuicSession> QuicSpdyClientBase::CreateQuicClientSession(
-    const quic::ParsedQuicVersionVector& supported_versions,
-    QuicConnection* connection) {
-  return std::make_unique<QuicSpdyClientSession>(
-      *config(), supported_versions, connection, server_id(), crypto_config(),
-      &push_promise_index_);
-}
-
-void QuicSpdyClientBase::SendRequest(const Http2HeaderBlock& headers,
-                                     absl::string_view body,
-                                     bool fin) {
-  if (GetQuicFlag(FLAGS_quic_client_convert_http_header_name_to_lowercase)) {
-    QUIC_CODE_COUNT(quic_client_convert_http_header_name_to_lowercase);
-    Http2HeaderBlock sanitized_headers;
-    for (const auto& p : headers) {
-      sanitized_headers[quiche::QuicheTextUtils::ToLower(p.first)] = p.second;
-    }
-
-    SendRequestInternal(std::move(sanitized_headers), body, fin);
-  } else {
-    SendRequestInternal(headers.Clone(), body, fin);
-  }
-}
-
-void QuicSpdyClientBase::SendRequestInternal(Http2HeaderBlock sanitized_headers,
-                                             absl::string_view body,
-                                             bool fin) {
-  QuicClientPushPromiseIndex::TryHandle* handle;
-  QuicAsyncStatus rv =
-      push_promise_index()->Try(sanitized_headers, this, &handle);
-  if (rv == QUIC_SUCCESS)
-    return;
-
-  if (rv == QUIC_PENDING) {
-    // May need to retry request if asynchronous rendezvous fails.
-    AddPromiseDataToResend(sanitized_headers, body, fin);
-    return;
-  }
-
-  QuicSpdyClientStream* stream = CreateClientStream();
-  if (stream == nullptr) {
-    QUIC_BUG(quic_bug_10949_1) << "stream creation failed!";
-    return;
-  }
-  stream->SendRequest(std::move(sanitized_headers), body, fin);
-}
-
-void QuicSpdyClientBase::SendRequestAndWaitForResponse(
-    const Http2HeaderBlock& headers,
-    absl::string_view body,
-    bool fin) {
-  SendRequest(headers, body, fin);
-  while (WaitForEvents()) {
-  }
-}
-
-void QuicSpdyClientBase::SendRequestsAndWaitForResponse(
-    const std::vector<std::string>& url_list) {
-  for (size_t i = 0; i < url_list.size(); ++i) {
-    Http2HeaderBlock headers;
-    if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) {
-      QUIC_BUG(quic_bug_10949_2) << "Unable to create request";
-      continue;
-    }
-    SendRequest(headers, "", true);
-  }
-  while (WaitForEvents()) {
-  }
-}
-
-QuicSpdyClientStream* QuicSpdyClientBase::CreateClientStream() {
-  if (!connected()) {
-    return nullptr;
-  }
-  if (VersionHasIetfQuicFrames(client_session()->transport_version())) {
-    // Process MAX_STREAMS from peer or wait for liveness testing succeeds.
-    while (!client_session()->CanOpenNextOutgoingBidirectionalStream()) {
-      network_helper()->RunEventLoop();
-    }
-  }
-  auto* stream = static_cast<QuicSpdyClientStream*>(
-      client_session()->CreateOutgoingBidirectionalStream());
-  if (stream) {
-    stream->set_visitor(this);
-  }
-  return stream;
-}
-
-bool QuicSpdyClientBase::goaway_received() const {
-  return client_session() && client_session()->goaway_received();
-}
-
-bool QuicSpdyClientBase::EarlyDataAccepted() {
-  return client_session()->EarlyDataAccepted();
-}
-
-bool QuicSpdyClientBase::ReceivedInchoateReject() {
-  return client_session()->ReceivedInchoateReject();
-}
-
-int QuicSpdyClientBase::GetNumSentClientHellosFromSession() {
-  return client_session()->GetNumSentClientHellos();
-}
-
-int QuicSpdyClientBase::GetNumReceivedServerConfigUpdatesFromSession() {
-  return client_session()->GetNumReceivedServerConfigUpdates();
-}
-
-void QuicSpdyClientBase::MaybeAddQuicDataToResend(
-    std::unique_ptr<QuicDataToResend> data_to_resend) {
-  data_to_resend_on_connect_.push_back(std::move(data_to_resend));
-}
-
-void QuicSpdyClientBase::ClearDataToResend() {
-  data_to_resend_on_connect_.clear();
-}
-
-void QuicSpdyClientBase::ResendSavedData() {
-  // Calling Resend will re-enqueue the data, so swap out
-  //  data_to_resend_on_connect_ before iterating.
-  std::vector<std::unique_ptr<QuicDataToResend>> old_data;
-  old_data.swap(data_to_resend_on_connect_);
-  for (const auto& data : old_data) {
-    data->Resend();
-  }
-}
-
-void QuicSpdyClientBase::AddPromiseDataToResend(const Http2HeaderBlock& headers,
-                                                absl::string_view body,
-                                                bool fin) {
-  std::unique_ptr<Http2HeaderBlock> new_headers(
-      new Http2HeaderBlock(headers.Clone()));
-  push_promise_data_to_resend_.reset(
-      new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
-}
-
-bool QuicSpdyClientBase::CheckVary(
-    const Http2HeaderBlock& /*client_request*/,
-    const Http2HeaderBlock& /*promise_request*/,
-    const Http2HeaderBlock& /*promise_response*/) {
-  return true;
-}
-
-void QuicSpdyClientBase::OnRendezvousResult(QuicSpdyStream* stream) {
-  std::unique_ptr<ClientQuicDataToResend> data_to_resend =
-      std::move(push_promise_data_to_resend_);
-  if (stream) {
-    stream->set_visitor(this);
-    stream->OnBodyAvailable();
-  } else if (data_to_resend) {
-    data_to_resend->Resend();
-  }
-}
-
-int QuicSpdyClientBase::latest_response_code() const {
-  QUIC_BUG_IF(quic_bug_10949_3, !store_response_) << "Response not stored!";
-  return latest_response_code_;
-}
-
-const std::string& QuicSpdyClientBase::latest_response_headers() const {
-  QUIC_BUG_IF(quic_bug_10949_4, !store_response_) << "Response not stored!";
-  return latest_response_headers_;
-}
-
-const std::string& QuicSpdyClientBase::preliminary_response_headers() const {
-  QUIC_BUG_IF(quic_bug_10949_5, !store_response_) << "Response not stored!";
-  return preliminary_response_headers_;
-}
-
-const Http2HeaderBlock& QuicSpdyClientBase::latest_response_header_block()
-    const {
-  QUIC_BUG_IF(quic_bug_10949_6, !store_response_) << "Response not stored!";
-  return latest_response_header_block_;
-}
-
-const std::string& QuicSpdyClientBase::latest_response_body() const {
-  QUIC_BUG_IF(quic_bug_10949_7, !store_response_) << "Response not stored!";
-  return latest_response_body_;
-}
-
-const std::string& QuicSpdyClientBase::latest_response_trailers() const {
-  QUIC_BUG_IF(quic_bug_10949_8, !store_response_) << "Response not stored!";
-  return latest_response_trailers_;
-}
-
-bool QuicSpdyClientBase::HasActiveRequests() {
-  return client_session()->HasActiveRequestStreams();
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_spdy_client_base.h b/quic/tools/quic_spdy_client_base.h
deleted file mode 100644
index 3e41725..0000000
--- a/quic/tools/quic_spdy_client_base.h
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A base class for the toy client, which connects to a specified port and sends
-// QUIC request to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/crypto_handshake.h"
-#include "quic/core/http/quic_client_push_promise_index.h"
-#include "quic/core/http/quic_spdy_client_session.h"
-#include "quic/core/http/quic_spdy_client_stream.h"
-#include "quic/core/quic_config.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_client_base.h"
-
-namespace quic {
-
-class ProofVerifier;
-class QuicServerId;
-class SessionCache;
-
-class QuicSpdyClientBase : public QuicClientBase,
-                           public QuicClientPushPromiseIndex::Delegate,
-                           public QuicSpdyStream::Visitor {
- public:
-  // A ResponseListener is notified when a complete response is received.
-  class ResponseListener {
-   public:
-    ResponseListener() {}
-    virtual ~ResponseListener() {}
-    virtual void OnCompleteResponse(
-        QuicStreamId id,
-        const spdy::Http2HeaderBlock& response_headers,
-        const std::string& response_body) = 0;
-  };
-
-  // A piece of data that can be sent multiple times. For example, it can be a
-  // HTTP request that is resent after a connect=>version negotiation=>reconnect
-  // sequence.
-  class QuicDataToResend {
-   public:
-    // |headers| may be null, since it's possible to send data without headers.
-    QuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers,
-                     absl::string_view body,
-                     bool fin);
-    QuicDataToResend(const QuicDataToResend&) = delete;
-    QuicDataToResend& operator=(const QuicDataToResend&) = delete;
-
-    virtual ~QuicDataToResend();
-
-    // Must be overridden by specific classes with the actual method for
-    // re-sending data.
-    virtual void Resend() = 0;
-
-   protected:
-    std::unique_ptr<spdy::Http2HeaderBlock> headers_;
-    absl::string_view body_;
-    bool fin_;
-  };
-
-  QuicSpdyClientBase(const QuicServerId& server_id,
-                     const ParsedQuicVersionVector& supported_versions,
-                     const QuicConfig& config,
-                     QuicConnectionHelperInterface* helper,
-                     QuicAlarmFactory* alarm_factory,
-                     std::unique_ptr<NetworkHelper> network_helper,
-                     std::unique_ptr<ProofVerifier> proof_verifier,
-                     std::unique_ptr<SessionCache> session_cache);
-  QuicSpdyClientBase(const QuicSpdyClientBase&) = delete;
-  QuicSpdyClientBase& operator=(const QuicSpdyClientBase&) = delete;
-
-  ~QuicSpdyClientBase() override;
-
-  // QuicSpdyStream::Visitor
-  void OnClose(QuicSpdyStream* stream) override;
-
-  // A spdy session has to call CryptoConnect on top of the regular
-  // initialization.
-  void InitializeSession() override;
-
-  // Sends an HTTP request and does not wait for response before returning.
-  void SendRequest(const spdy::Http2HeaderBlock& headers,
-                   absl::string_view body,
-                   bool fin);
-
-  // Sends an HTTP request and waits for response before returning.
-  void SendRequestAndWaitForResponse(const spdy::Http2HeaderBlock& headers,
-                                     absl::string_view body,
-                                     bool fin);
-
-  // Sends a request simple GET for each URL in |url_list|, and then waits for
-  // each to complete.
-  void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list);
-
-  // Returns a newly created QuicSpdyClientStream.
-  QuicSpdyClientStream* CreateClientStream();
-
-  // Returns a the session used for this client downcasted to a
-  // QuicSpdyClientSession.
-  QuicSpdyClientSession* client_session();
-  const QuicSpdyClientSession* client_session() const;
-
-  QuicClientPushPromiseIndex* push_promise_index() {
-    return &push_promise_index_;
-  }
-
-  bool CheckVary(const spdy::Http2HeaderBlock& client_request,
-                 const spdy::Http2HeaderBlock& promise_request,
-                 const spdy::Http2HeaderBlock& promise_response) override;
-  void OnRendezvousResult(QuicSpdyStream*) override;
-
-  // If the crypto handshake has not yet been confirmed, adds the data to the
-  // queue of data to resend if the client receives a stateless reject.
-  // Otherwise, deletes the data.
-  void MaybeAddQuicDataToResend(
-      std::unique_ptr<QuicDataToResend> data_to_resend);
-
-  void set_store_response(bool val) { store_response_ = val; }
-
-  int latest_response_code() const;
-  const std::string& latest_response_headers() const;
-  const std::string& preliminary_response_headers() const;
-  const spdy::Http2HeaderBlock& latest_response_header_block() const;
-  const std::string& latest_response_body() const;
-  const std::string& latest_response_trailers() const;
-
-  void set_response_listener(std::unique_ptr<ResponseListener> listener) {
-    response_listener_ = std::move(listener);
-  }
-
-  void set_drop_response_body(bool drop_response_body) {
-    drop_response_body_ = drop_response_body;
-  }
-  bool drop_response_body() const { return drop_response_body_; }
-
-  void set_enable_web_transport(bool enable_web_transport) {
-    enable_web_transport_ = enable_web_transport;
-  }
-  bool enable_web_transport() const { return enable_web_transport_; }
-
-  void set_use_datagram_contexts(bool use_datagram_contexts) {
-    use_datagram_contexts_ = use_datagram_contexts;
-  }
-  bool use_datagram_contexts() const { return use_datagram_contexts_; }
-
-  // QuicClientBase methods.
-  bool goaway_received() const override;
-  bool EarlyDataAccepted() override;
-  bool ReceivedInchoateReject() override;
-
-  void set_max_inbound_header_list_size(size_t size) {
-    max_inbound_header_list_size_ = size;
-  }
-
- protected:
-  int GetNumSentClientHellosFromSession() override;
-  int GetNumReceivedServerConfigUpdatesFromSession() override;
-
-  // Takes ownership of |connection|.
-  std::unique_ptr<QuicSession> CreateQuicClientSession(
-      const quic::ParsedQuicVersionVector& supported_versions,
-      QuicConnection* connection) override;
-
-  void ClearDataToResend() override;
-
-  void ResendSavedData() override;
-
-  void AddPromiseDataToResend(const spdy::Http2HeaderBlock& headers,
-                              absl::string_view body,
-                              bool fin);
-  bool HasActiveRequests() override;
-
- private:
-  // Specific QuicClient class for storing data to resend.
-  class ClientQuicDataToResend : public QuicDataToResend {
-   public:
-    ClientQuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers,
-                           absl::string_view body,
-                           bool fin,
-                           QuicSpdyClientBase* client)
-        : QuicDataToResend(std::move(headers), body, fin), client_(client) {
-      QUICHE_DCHECK(headers_);
-      QUICHE_DCHECK(client);
-    }
-
-    ClientQuicDataToResend(const ClientQuicDataToResend&) = delete;
-    ClientQuicDataToResend& operator=(const ClientQuicDataToResend&) = delete;
-    ~ClientQuicDataToResend() override {}
-
-    void Resend() override;
-
-   private:
-    QuicSpdyClientBase* client_;
-  };
-
-  void SendRequestInternal(spdy::Http2HeaderBlock sanitized_headers,
-                           absl::string_view body,
-                           bool fin);
-
-  // Index of pending promised streams. Must outlive |session_|.
-  QuicClientPushPromiseIndex push_promise_index_;
-
-  // If true, store the latest response code, headers, and body.
-  bool store_response_;
-  // HTTP response code from most recent response.
-  int latest_response_code_;
-  // HTTP/2 headers from most recent response.
-  std::string latest_response_headers_;
-  // preliminary 100 Continue HTTP/2 headers from most recent response, if any.
-  std::string preliminary_response_headers_;
-  // HTTP/2 headers from most recent response.
-  spdy::Http2HeaderBlock latest_response_header_block_;
-  // Body of most recent response.
-  std::string latest_response_body_;
-  // HTTP/2 trailers from most recent response.
-  std::string latest_response_trailers_;
-
-  // Listens for full responses.
-  std::unique_ptr<ResponseListener> response_listener_;
-
-  // Keeps track of any data that must be resent upon a subsequent successful
-  // connection, in case the client receives a stateless reject.
-  std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_;
-
-  std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_;
-
-  bool drop_response_body_ = false;
-  bool enable_web_transport_ = false;
-  bool use_datagram_contexts_ = false;
-  // If not zero, used to set client's max inbound header size before session
-  // initialize.
-  size_t max_inbound_header_list_size_ = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
diff --git a/quic/tools/quic_spdy_server_base.h b/quic/tools/quic_spdy_server_base.h
deleted file mode 100644
index c84398f..0000000
--- a/quic/tools/quic_spdy_server_base.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy server, which connects to a specified port and sends QUIC
-// requests to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
-#define QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
-
-#include "quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// Base class for service instances to be used with QuicToyServer.
-class QuicSpdyServerBase {
- public:
-  virtual ~QuicSpdyServerBase() = default;
-
-  // Creates a UDP socket and listens on |address|. Returns true on success
-  // and false otherwise.
-  virtual bool CreateUDPSocketAndListen(const QuicSocketAddress& address) = 0;
-
-  // Handles incoming requests. Does not return.
-  virtual void HandleEventsForever() = 0;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
diff --git a/quic/tools/quic_tcp_like_trace_converter.cc b/quic/tools/quic_tcp_like_trace_converter.cc
deleted file mode 100644
index 22e8731..0000000
--- a/quic/tools/quic_tcp_like_trace_converter.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_tcp_like_trace_converter.h"
-
-#include "quic/core/quic_constants.h"
-#include "quic/platform/api/quic_bug_tracker.h"
-
-namespace quic {
-
-QuicTcpLikeTraceConverter::QuicTcpLikeTraceConverter()
-    : largest_observed_control_frame_id_(kInvalidControlFrameId),
-      connection_offset_(0) {}
-
-QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment()
-    : connection_offset(0) {}
-
-QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment(
-    QuicStreamOffset stream_offset,
-    uint64_t connection_offset,
-    QuicByteCount data_length)
-    : stream_data(stream_offset, stream_offset + data_length),
-      connection_offset(connection_offset) {}
-
-QuicTcpLikeTraceConverter::StreamInfo::StreamInfo() : fin(false) {}
-
-QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnCryptoFrameSent(
-    EncryptionLevel level,
-    QuicStreamOffset offset,
-    QuicByteCount data_length) {
-  if (level >= NUM_ENCRYPTION_LEVELS) {
-    QUIC_BUG(quic_bug_10907_1) << "Invalid encryption level";
-    return {};
-  }
-  return OnFrameSent(offset, data_length, /*fin=*/false,
-                     &crypto_frames_info_[level]);
-}
-
-QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnStreamFrameSent(
-    QuicStreamId stream_id,
-    QuicStreamOffset offset,
-    QuicByteCount data_length,
-    bool fin) {
-  return OnFrameSent(
-      offset, data_length, fin,
-      &streams_info_.emplace(stream_id, StreamInfo()).first->second);
-}
-
-QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnFrameSent(
-    QuicStreamOffset offset,
-    QuicByteCount data_length,
-    bool fin,
-    StreamInfo* info) {
-  QuicIntervalSet<uint64_t> connection_offsets;
-  if (fin) {
-    // Stream fin consumes a connection offset.
-    ++data_length;
-  }
-  // Get connection offsets of retransmission data in this frame.
-  for (const auto& segment : info->segments) {
-    QuicInterval<QuicStreamOffset> retransmission(offset, offset + data_length);
-    retransmission.IntersectWith(segment.stream_data);
-    if (retransmission.Empty()) {
-      continue;
-    }
-    const uint64_t connection_offset = segment.connection_offset +
-                                       retransmission.min() -
-                                       segment.stream_data.min();
-    connection_offsets.Add(connection_offset,
-                           connection_offset + retransmission.Length());
-  }
-
-  if (info->fin) {
-    return connection_offsets;
-  }
-
-  // Get connection offsets of new data in this frame.
-  QuicStreamOffset least_unsent_offset =
-      info->segments.empty() ? 0 : info->segments.back().stream_data.max();
-  if (least_unsent_offset >= offset + data_length) {
-    return connection_offsets;
-  }
-  // Ignore out-of-order stream data so that as connection offset increases,
-  // stream offset increases.
-  QuicStreamOffset new_data_offset = std::max(least_unsent_offset, offset);
-  QuicByteCount new_data_length = offset + data_length - new_data_offset;
-  connection_offsets.Add(connection_offset_,
-                         connection_offset_ + new_data_length);
-  if (!info->segments.empty() && new_data_offset == least_unsent_offset &&
-      connection_offset_ == info->segments.back().connection_offset +
-                                info->segments.back().stream_data.Length()) {
-    // Extend the last segment if both stream and connection offsets are
-    // contiguous.
-    info->segments.back().stream_data.SetMax(new_data_offset + new_data_length);
-  } else {
-    info->segments.emplace_back(new_data_offset, connection_offset_,
-                                new_data_length);
-  }
-  info->fin = fin;
-  connection_offset_ += new_data_length;
-
-  return connection_offsets;
-}
-
-QuicInterval<uint64_t> QuicTcpLikeTraceConverter::OnControlFrameSent(
-    QuicControlFrameId control_frame_id,
-    QuicByteCount control_frame_length) {
-  if (control_frame_id > largest_observed_control_frame_id_) {
-    // New control frame.
-    QuicInterval<uint64_t> connection_offset = QuicInterval<uint64_t>(
-        connection_offset_, connection_offset_ + control_frame_length);
-    connection_offset_ += control_frame_length;
-    control_frames_info_[control_frame_id] = connection_offset;
-    largest_observed_control_frame_id_ = control_frame_id;
-    return connection_offset;
-  }
-  const auto iter = control_frames_info_.find(control_frame_id);
-  if (iter == control_frames_info_.end()) {
-    // Ignore out of order control frames.
-    return {};
-  }
-  return iter->second;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_tcp_like_trace_converter.h b/quic/tools/quic_tcp_like_trace_converter.h
deleted file mode 100644
index b90d455..0000000
--- a/quic/tools/quic_tcp_like_trace_converter.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
-
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "quic/core/frames/quic_stream_frame.h"
-#include "quic/core/quic_interval.h"
-#include "quic/core/quic_interval_set.h"
-#include "quic/core/quic_types.h"
-#include "quic/platform/api/quic_containers.h"
-
-namespace quic {
-
-// This converter converts sent QUIC frames to connection byte offset (just like
-// TCP byte sequence number).
-class QuicTcpLikeTraceConverter {
- public:
-  // StreamOffsetSegment stores a stream offset range which has contiguous
-  // connection offset.
-  struct StreamOffsetSegment {
-    StreamOffsetSegment();
-    StreamOffsetSegment(QuicStreamOffset stream_offset,
-                        uint64_t connection_offset,
-                        QuicByteCount data_length);
-
-    QuicInterval<QuicStreamOffset> stream_data;
-    uint64_t connection_offset;
-  };
-
-  QuicTcpLikeTraceConverter();
-  QuicTcpLikeTraceConverter(const QuicTcpLikeTraceConverter& other) = delete;
-  QuicTcpLikeTraceConverter(QuicTcpLikeTraceConverter&& other) = delete;
-
-  ~QuicTcpLikeTraceConverter() {}
-
-  // Called when a crypto frame is sent. Returns the corresponding connection
-  // offsets.
-  QuicIntervalSet<uint64_t> OnCryptoFrameSent(EncryptionLevel level,
-                                              QuicStreamOffset offset,
-                                              QuicByteCount data_length);
-
-  // Called when a stream frame is sent. Returns the corresponding connection
-  // offsets.
-  QuicIntervalSet<uint64_t> OnStreamFrameSent(QuicStreamId stream_id,
-                                              QuicStreamOffset offset,
-                                              QuicByteCount data_length,
-                                              bool fin);
-
-  // Called when a control frame is sent. Returns the corresponding connection
-  // offsets.
-  QuicInterval<uint64_t> OnControlFrameSent(QuicControlFrameId control_frame_id,
-                                            QuicByteCount control_frame_length);
-
- private:
-  struct StreamInfo {
-    StreamInfo();
-
-    // Stores contiguous connection offset pieces.
-    std::vector<StreamOffsetSegment> segments;
-    // Indicates whether fin has been sent.
-    bool fin;
-  };
-
-  // Called when frame with |offset|, |data_length| and |fin| has been sent.
-  // Update |info| and returns connection offsets.
-  QuicIntervalSet<uint64_t> OnFrameSent(QuicStreamOffset offset,
-                                        QuicByteCount data_length,
-                                        bool fin,
-                                        StreamInfo* info);
-
-  StreamInfo crypto_frames_info_[NUM_ENCRYPTION_LEVELS];
-  absl::flat_hash_map<QuicStreamId, StreamInfo> streams_info_;
-  absl::flat_hash_map<QuicControlFrameId, QuicInterval<uint64_t>>
-      control_frames_info_;
-
-  QuicControlFrameId largest_observed_control_frame_id_;
-
-  uint64_t connection_offset_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
diff --git a/quic/tools/quic_tcp_like_trace_converter_test.cc b/quic/tools/quic_tcp_like_trace_converter_test.cc
deleted file mode 100644
index 97edd4d..0000000
--- a/quic/tools/quic_tcp_like_trace_converter_test.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_tcp_like_trace_converter.h"
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-TEST(QuicTcpLikeTraceConverterTest, BasicTest) {
-  QuicTcpLikeTraceConverter converter;
-
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
-            converter.OnStreamFrameSent(1, 0, 100, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
-            converter.OnStreamFrameSent(3, 0, 100, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
-            converter.OnStreamFrameSent(3, 100, 100, false));
-  EXPECT_EQ(QuicInterval<uint64_t>(300, 450),
-            converter.OnControlFrameSent(2, 150));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(450, 550),
-            converter.OnStreamFrameSent(1, 100, 100, false));
-  EXPECT_EQ(QuicInterval<uint64_t>(550, 650),
-            converter.OnControlFrameSent(3, 100));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(650, 850),
-            converter.OnStreamFrameSent(3, 200, 200, false));
-  EXPECT_EQ(QuicInterval<uint64_t>(850, 1050),
-            converter.OnControlFrameSent(4, 200));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(1050, 1100),
-            converter.OnStreamFrameSent(1, 200, 50, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(1100, 1150),
-            converter.OnStreamFrameSent(1, 250, 50, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(1150, 1350),
-            converter.OnStreamFrameSent(3, 400, 200, false));
-
-  // Stream 1 retransmits [50, 300) and sends new data [300, 350) in the same
-  // frame.
-  QuicIntervalSet<uint64_t> expected;
-  expected.Add(50, 100);
-  expected.Add(450, 550);
-  expected.Add(1050, 1150);
-  expected.Add(1350, 1401);
-  EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 300, true));
-
-  expected.Clear();
-  // Stream 3 retransmits [150, 500).
-  expected.Add(250, 300);
-  expected.Add(650, 850);
-  expected.Add(1150, 1250);
-  EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 150, 350, false));
-
-  // Stream 3 retransmits [300, 600) and sends new data [600, 800) in the same
-  // frame.
-  expected.Clear();
-  expected.Add(750, 850);
-  expected.Add(1150, 1350);
-  expected.Add(1401, 1602);
-  EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 300, 500, true));
-
-  // Stream 3 retransmits fin only frame.
-  expected.Clear();
-  expected.Add(1601, 1602);
-  EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 800, 0, true));
-
-  QuicInterval<uint64_t> expected2;
-  // Ignore out of order control frames.
-  EXPECT_EQ(expected2, converter.OnControlFrameSent(1, 100));
-
-  // Ignore passed in length for retransmitted frame.
-  expected2 = {300, 450};
-  EXPECT_EQ(expected2, converter.OnControlFrameSent(2, 200));
-
-  expected2 = {1602, 1702};
-  EXPECT_EQ(expected2, converter.OnControlFrameSent(10, 100));
-}
-
-TEST(QuicTcpLikeTraceConverterTest, FuzzerTest) {
-  QuicTcpLikeTraceConverter converter;
-  // Stream does not start from offset 0.
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
-            converter.OnStreamFrameSent(1, 100, 100, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 300),
-            converter.OnStreamFrameSent(3, 200, 200, false));
-  // Stream does not send data contiguously.
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
-            converter.OnStreamFrameSent(1, 300, 100, false));
-
-  // Stream fills existing holes.
-  QuicIntervalSet<uint64_t> expected;
-  expected.Add(0, 100);
-  expected.Add(300, 501);
-  EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 0, 500, true));
-
-  // Stream sends frame after fin.
-  EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 600, false));
-}
-
-TEST(QuicTcpLikeTraceConverterTest, OnCryptoFrameSent) {
-  QuicTcpLikeTraceConverter converter;
-
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
-            converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
-            converter.OnStreamFrameSent(1, 0, 100, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
-            converter.OnStreamFrameSent(1, 100, 100, false));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
-            converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 0, 100));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
-            converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
-
-  // Verify crypto frame retransmission works as intended.
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
-            converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
-  EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
-            converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/quic_toy_client.cc b/quic/tools/quic_toy_client.cc
deleted file mode 100644
index 08d9a67..0000000
--- a/quic/tools/quic_toy_client.cc
+++ /dev/null
@@ -1,501 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A binary wrapper for QuicClient.
-// Connects to a host using QUIC, sends a request to the provided URL, and
-// displays the response.
-//
-// Some usage examples:
-//
-// Standard request/response:
-//   quic_client www.google.com
-//   quic_client www.google.com --quiet
-//   quic_client www.google.com --port=443
-//
-// Use a specific version:
-//   quic_client www.google.com --quic_version=23
-//
-// Send a POST instead of a GET:
-//   quic_client www.google.com --body="this is a POST body"
-//
-// Append additional headers to the request:
-//   quic_client www.google.com --headers="Header-A: 1234; Header-B: 5678"
-//
-// Connect to a host different to the URL being requested:
-//   quic_client mail.google.com --host=www.google.com
-//
-// Connect to a specific IP:
-//   IP=`dig www.google.com +short | head -1`
-//   quic_client www.google.com --host=${IP}
-//
-// Send repeated requests and change ephemeral port between requests
-//   quic_client www.google.com --num_requests=10
-//
-// Try to connect to a host which does not speak QUIC:
-//   quic_client www.example.com
-//
-// This tool is available as a built binary at:
-// /google/data/ro/teams/quic/tools/quic_client
-// After submitting changes to this file, you will need to follow the
-// instructions at go/quic_client_binary_update
-
-#include "quic/tools/quic_toy_client.h"
-
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/escaping.h"
-#include "absl/strings/str_split.h"
-#include "absl/strings/string_view.h"
-#include "quic/core/crypto/quic_client_session_cache.h"
-#include "quic/core/quic_packets.h"
-#include "quic/core/quic_server_id.h"
-#include "quic/core/quic_utils.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/platform/api/quic_ip_address.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/fake_proof_verifier.h"
-#include "quic/tools/quic_url.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-#include "common/quiche_text_utils.h"
-
-namespace {
-
-using quiche::QuicheTextUtils;
-
-}  // namespace
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, host, "",
-    "The IP or hostname to connect to. If not provided, the host "
-    "will be derived from the provided URL.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, ip_version_for_host_lookup, "",
-                                "Only used if host address lookup is needed. "
-                                "4=ipv4; 6=ipv6; otherwise=don't care.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, body, "",
-                                "If set, send a POST with this body.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, body_hex, "",
-    "If set, contents are converted from hex to ascii, before "
-    "sending as body of a POST. e.g. --body_hex=\"68656c6c6f\"");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, headers, "",
-    "A semicolon separated list of key:value pairs to "
-    "add to request headers.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quiet, false,
-                                "Set to true for a quieter output experience.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, quic_version, "",
-    "QUIC version to speak, e.g. 21. If not set, then all available "
-    "versions are offered in the handshake. Also supports wire versions "
-    "such as Q043 or T099.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, connection_options, "",
-    "Connection options as ASCII tags separated by commas, "
-    "e.g. \"ABCD,EFGH\"");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, client_connection_options, "",
-    "Client connection options as ASCII tags separated by commas, "
-    "e.g. \"ABCD,EFGH\"");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
-                                "Use the IETF draft version. This also enables "
-                                "required internal QUIC flags.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, version_mismatch_ok, false,
-    "If true, a version mismatch in the handshake is not considered a "
-    "failure. Useful for probing a server to determine if it speaks "
-    "any version of QUIC.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, force_version_negotiation, false,
-    "If true, start by proposing a version that is reserved for version "
-    "negotiation.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, multi_packet_chlo, false,
-    "If true, add a transport parameter to make the ClientHello span two "
-    "packets. Only works with QUIC+TLS.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, redirect_is_success, true,
-    "If true, an HTTP response code of 3xx is considered to be a "
-    "successful response, otherwise a failure.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, initial_mtu, 0,
-                                "Initial MTU of the connection.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    int32_t, num_requests, 1,
-    "How many sequential requests to make on a single connection.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, disable_certificate_verification, false,
-    "If true, don't verify the server certificate.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, default_client_cert, "",
-    "The path to the file containing PEM-encoded client default certificate to "
-    "be sent to the server, if server requested client certs.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, default_client_cert_key, "",
-    "The path to the file containing PEM-encoded private key of the client's "
-    "default certificate for signing, if server requested client certs.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, drop_response_body, false,
-    "If true, drop response body immediately after it is received.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, disable_port_changes, false,
-    "If true, do not change local port after each request.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, one_connection_per_request, false,
-                                "If true, close the connection after each "
-                                "request. This allows testing 0-RTT.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, server_connection_id_length, -1,
-                                "Length of the server connection ID used.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, client_connection_id_length, -1,
-                                "Length of the client connection ID used.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, max_time_before_crypto_handshake_ms,
-                                10000,
-                                "Max time to wait before handshake completes.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    int32_t, max_inbound_header_list_size, 128 * 1024,
-    "Max inbound header list size. 0 means default.");
-
-namespace quic {
-namespace {
-
-// Creates a ClientProofSource which only contains a default client certificate.
-// Return nullptr for failure.
-std::unique_ptr<ClientProofSource> CreateTestClientProofSource(
-    absl::string_view default_client_cert_file,
-    absl::string_view default_client_cert_key_file) {
-  std::ifstream cert_stream(std::string{default_client_cert_file},
-                            std::ios::binary);
-  std::vector<std::string> certs =
-      CertificateView::LoadPemFromStream(&cert_stream);
-  if (certs.empty()) {
-    std::cerr << "Failed to load client certs." << std::endl;
-    return nullptr;
-  }
-
-  std::ifstream key_stream(std::string{default_client_cert_key_file},
-                           std::ios::binary);
-  std::unique_ptr<CertificatePrivateKey> private_key =
-      CertificatePrivateKey::LoadPemFromStream(&key_stream);
-  if (private_key == nullptr) {
-    std::cerr << "Failed to load client cert key." << std::endl;
-    return nullptr;
-  }
-
-  auto proof_source = std::make_unique<DefaultClientProofSource>();
-  proof_source->AddCertAndKey(
-      {"*"},
-      quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
-          new ClientProofSource::Chain(certs)),
-      std::move(*private_key));
-
-  return proof_source;
-}
-
-}  // namespace
-
-QuicToyClient::QuicToyClient(ClientFactory* client_factory)
-    : client_factory_(client_factory) {}
-
-int QuicToyClient::SendRequestsAndPrintResponses(
-    std::vector<std::string> urls) {
-  QuicUrl url(urls[0], "https");
-  std::string host = GetQuicFlag(FLAGS_host);
-  if (host.empty()) {
-    host = url.host();
-  }
-  int port = GetQuicFlag(FLAGS_port);
-  if (port == 0) {
-    port = url.port();
-  }
-
-  quic::ParsedQuicVersionVector versions = quic::CurrentSupportedVersions();
-
-  if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
-    quic::QuicVersionInitializeSupportForIetfDraft();
-    versions = {};
-    for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-      if (version.HasIetfQuicFrames() &&
-          version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
-        versions.push_back(version);
-      }
-    }
-  }
-
-  std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
-  if (!quic_version_string.empty()) {
-    versions = quic::ParseQuicVersionVectorString(quic_version_string);
-  }
-
-  if (versions.empty()) {
-    std::cerr << "No known version selected." << std::endl;
-    return 1;
-  }
-
-  for (const quic::ParsedQuicVersion& version : versions) {
-    quic::QuicEnableVersion(version);
-  }
-
-  if (GetQuicFlag(FLAGS_force_version_negotiation)) {
-    versions.insert(versions.begin(),
-                    quic::QuicVersionReservedForNegotiation());
-  }
-
-  const int32_t num_requests(GetQuicFlag(FLAGS_num_requests));
-  std::unique_ptr<quic::ProofVerifier> proof_verifier;
-  if (GetQuicFlag(FLAGS_disable_certificate_verification)) {
-    proof_verifier = std::make_unique<FakeProofVerifier>();
-  } else {
-    proof_verifier = quic::CreateDefaultProofVerifier(url.host());
-  }
-  std::unique_ptr<quic::SessionCache> session_cache;
-  if (num_requests > 1 && GetQuicFlag(FLAGS_one_connection_per_request)) {
-    session_cache = std::make_unique<QuicClientSessionCache>();
-  }
-
-  QuicConfig config;
-  std::string connection_options_string = GetQuicFlag(FLAGS_connection_options);
-  if (!connection_options_string.empty()) {
-    config.SetConnectionOptionsToSend(
-        ParseQuicTagVector(connection_options_string));
-  }
-  std::string client_connection_options_string =
-      GetQuicFlag(FLAGS_client_connection_options);
-  if (!client_connection_options_string.empty()) {
-    config.SetClientConnectionOptions(
-        ParseQuicTagVector(client_connection_options_string));
-  }
-  if (GetQuicFlag(FLAGS_multi_packet_chlo)) {
-    // Make the ClientHello span multiple packets by adding a custom transport
-    // parameter.
-    constexpr auto kCustomParameter =
-        static_cast<TransportParameters::TransportParameterId>(0x173E);
-    std::string custom_value(2000, '?');
-    config.custom_transport_parameters_to_send()[kCustomParameter] =
-        custom_value;
-  }
-  config.set_max_time_before_crypto_handshake(QuicTime::Delta::FromMilliseconds(
-      GetQuicFlag(FLAGS_max_time_before_crypto_handshake_ms)));
-
-  int address_family_for_lookup = AF_UNSPEC;
-  if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "4") {
-    address_family_for_lookup = AF_INET;
-  } else if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "6") {
-    address_family_for_lookup = AF_INET6;
-  }
-
-  // Build the client, and try to connect.
-  std::unique_ptr<QuicSpdyClientBase> client = client_factory_->CreateClient(
-      url.host(), host, address_family_for_lookup, port, versions, config,
-      std::move(proof_verifier), std::move(session_cache));
-
-  if (client == nullptr) {
-    std::cerr << "Failed to create client." << std::endl;
-    return 1;
-  }
-
-  if (!GetQuicFlag(FLAGS_default_client_cert).empty() &&
-      !GetQuicFlag(FLAGS_default_client_cert_key).empty()) {
-    std::unique_ptr<ClientProofSource> proof_source =
-        CreateTestClientProofSource(GetQuicFlag(FLAGS_default_client_cert),
-                                    GetQuicFlag(FLAGS_default_client_cert_key));
-    if (proof_source == nullptr) {
-      std::cerr << "Failed to create client proof source." << std::endl;
-      return 1;
-    }
-    client->crypto_config()->set_proof_source(std::move(proof_source));
-  }
-
-  int32_t initial_mtu = GetQuicFlag(FLAGS_initial_mtu);
-  client->set_initial_max_packet_length(
-      initial_mtu != 0 ? initial_mtu : quic::kDefaultMaxPacketSize);
-  client->set_drop_response_body(GetQuicFlag(FLAGS_drop_response_body));
-  const int32_t server_connection_id_length =
-      GetQuicFlag(FLAGS_server_connection_id_length);
-  if (server_connection_id_length >= 0) {
-    client->set_server_connection_id_length(server_connection_id_length);
-  }
-  const int32_t client_connection_id_length =
-      GetQuicFlag(FLAGS_client_connection_id_length);
-  if (client_connection_id_length >= 0) {
-    client->set_client_connection_id_length(client_connection_id_length);
-  }
-  const size_t max_inbound_header_list_size =
-      GetQuicFlag(FLAGS_max_inbound_header_list_size);
-  if (max_inbound_header_list_size > 0) {
-    client->set_max_inbound_header_list_size(max_inbound_header_list_size);
-  }
-  if (!client->Initialize()) {
-    std::cerr << "Failed to initialize client." << std::endl;
-    return 1;
-  }
-  if (!client->Connect()) {
-    quic::QuicErrorCode error = client->session()->error();
-    if (error == quic::QUIC_INVALID_VERSION) {
-      std::cerr << "Failed to negotiate version with " << host << ":" << port
-                << ". " << client->session()->error_details() << std::endl;
-      // 0: No error.
-      // 20: Failed to connect due to QUIC_INVALID_VERSION.
-      return GetQuicFlag(FLAGS_version_mismatch_ok) ? 0 : 20;
-    }
-    std::cerr << "Failed to connect to " << host << ":" << port << ". "
-              << quic::QuicErrorCodeToString(error) << " "
-              << client->session()->error_details() << std::endl;
-    return 1;
-  }
-  std::cerr << "Connected to " << host << ":" << port << std::endl;
-
-  // Construct the string body from flags, if provided.
-  std::string body = GetQuicFlag(FLAGS_body);
-  if (!GetQuicFlag(FLAGS_body_hex).empty()) {
-    QUICHE_DCHECK(GetQuicFlag(FLAGS_body).empty())
-        << "Only set one of --body and --body_hex.";
-    body = absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex));
-  }
-
-  // Construct a GET or POST request for supplied URL.
-  spdy::Http2HeaderBlock header_block;
-  header_block[":method"] = body.empty() ? "GET" : "POST";
-  header_block[":scheme"] = url.scheme();
-  header_block[":authority"] = url.HostPort();
-  header_block[":path"] = url.PathParamsQuery();
-
-  // Append any additional headers supplied on the command line.
-  const std::string headers = GetQuicFlag(FLAGS_headers);
-  for (absl::string_view sp : absl::StrSplit(headers, ';')) {
-    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp);
-    if (sp.empty()) {
-      continue;
-    }
-    std::vector<absl::string_view> kv =
-        absl::StrSplit(sp, absl::MaxSplits(':', 1));
-    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]);
-    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]);
-    header_block[kv[0]] = kv[1];
-  }
-
-  // Make sure to store the response, for later output.
-  client->set_store_response(true);
-
-  for (int i = 0; i < num_requests; ++i) {
-    // Send the request.
-    client->SendRequestAndWaitForResponse(header_block, body, /*fin=*/true);
-
-    // Print request and response details.
-    if (!GetQuicFlag(FLAGS_quiet)) {
-      std::cout << "Request:" << std::endl;
-      std::cout << "headers:" << header_block.DebugString();
-      if (!GetQuicFlag(FLAGS_body_hex).empty()) {
-        // Print the user provided hex, rather than binary body.
-        std::cout << "body:\n"
-                  << QuicheTextUtils::HexDump(
-                         absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex)))
-                  << std::endl;
-      } else {
-        std::cout << "body: " << body << std::endl;
-      }
-      std::cout << std::endl;
-
-      if (!client->preliminary_response_headers().empty()) {
-        std::cout << "Preliminary response headers: "
-                  << client->preliminary_response_headers() << std::endl;
-        std::cout << std::endl;
-      }
-
-      std::cout << "Response:" << std::endl;
-      std::cout << "headers: " << client->latest_response_headers()
-                << std::endl;
-      std::string response_body = client->latest_response_body();
-      if (!GetQuicFlag(FLAGS_body_hex).empty()) {
-        // Assume response is binary data.
-        std::cout << "body:\n"
-                  << QuicheTextUtils::HexDump(response_body) << std::endl;
-      } else {
-        std::cout << "body: " << response_body << std::endl;
-      }
-      std::cout << "trailers: " << client->latest_response_trailers()
-                << std::endl;
-    }
-
-    if (!client->connected()) {
-      std::cerr << "Request caused connection failure. Error: "
-                << quic::QuicErrorCodeToString(client->session()->error())
-                << std::endl;
-      return 1;
-    }
-
-    int response_code = client->latest_response_code();
-    if (response_code >= 200 && response_code < 300) {
-      std::cout << "Request succeeded (" << response_code << ")." << std::endl;
-    } else if (response_code >= 300 && response_code < 400) {
-      if (GetQuicFlag(FLAGS_redirect_is_success)) {
-        std::cout << "Request succeeded (redirect " << response_code << ")."
-                  << std::endl;
-      } else {
-        std::cout << "Request failed (redirect " << response_code << ")."
-                  << std::endl;
-        return 1;
-      }
-    } else {
-      std::cout << "Request failed (" << response_code << ")." << std::endl;
-      return 1;
-    }
-
-    if (i + 1 < num_requests) {  // There are more requests to perform.
-      if (GetQuicFlag(FLAGS_one_connection_per_request)) {
-        std::cout << "Disconnecting client between requests." << std::endl;
-        client->Disconnect();
-        if (!client->Initialize()) {
-          std::cerr << "Failed to reinitialize client between requests."
-                    << std::endl;
-          return 1;
-        }
-        if (!client->Connect()) {
-          std::cerr << "Failed to reconnect client between requests."
-                    << std::endl;
-          return 1;
-        }
-      } else if (!GetQuicFlag(FLAGS_disable_port_changes)) {
-        // Change the ephemeral port.
-        if (!client->ChangeEphemeralPort()) {
-          std::cerr << "Failed to change ephemeral port." << std::endl;
-          return 1;
-        }
-      }
-    }
-  }
-
-  return 0;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_toy_client.h b/quic/tools/quic_toy_client.h
deleted file mode 100644
index 81b3733..0000000
--- a/quic/tools/quic_toy_client.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A toy client, which connects to a specified port and sends QUIC
-// requests to that endpoint.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
-
-#include "quic/tools/quic_spdy_client_base.h"
-
-namespace quic {
-
-class QuicToyClient {
- public:
-  class ClientFactory {
-   public:
-    virtual ~ClientFactory() = default;
-
-    // Creates a new client configured to connect to |host_for_lookup:port|
-    // supporting |versions|, using |host_for_handshake| for handshake and
-    // |verifier| to verify proofs.
-    virtual std::unique_ptr<QuicSpdyClientBase> CreateClient(
-        std::string host_for_handshake,
-        std::string host_for_lookup,
-        // AF_INET, AF_INET6, or AF_UNSPEC(=don't care).
-        int address_family_for_lookup,
-        uint16_t port,
-        ParsedQuicVersionVector versions,
-        const QuicConfig& config,
-        std::unique_ptr<ProofVerifier> verifier,
-        std::unique_ptr<SessionCache> session_cache) = 0;
-  };
-
-  // Constructs a new toy client that will use |client_factory| to create the
-  // actual QuicSpdyClientBase instance.
-  QuicToyClient(ClientFactory* client_factory);
-
-  // Connects to the QUIC server based on the various flags defined in the
-  // .cc file, sends requests and prints the responses. Returns 0 on success
-  // and non-zero otherwise.
-  int SendRequestsAndPrintResponses(std::vector<std::string> urls);
-
- private:
-  ClientFactory* client_factory_;  // Unowned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
diff --git a/quic/tools/quic_toy_server.cc b/quic/tools/quic_toy_server.cc
deleted file mode 100644
index cdbe9b3..0000000
--- a/quic/tools/quic_toy_server.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_toy_server.h"
-
-#include <utility>
-#include <vector>
-
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_default_proof_providers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_socket_address.h"
-#include "quic/tools/quic_memory_cache_backend.h"
-#include "common/platform/api/quiche_command_line_flags.h"
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 6121,
-                                "The port the quic server will listen on.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, quic_response_cache_dir, "",
-    "Specifies the directory used during QuicHttpResponseCache "
-    "construction to seed the cache. Cache directory can be "
-    "generated using `wget -p --save-headers <url>`");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    bool, generate_dynamic_responses, false,
-    "If true, then URLs which have a numeric path will send a dynamically "
-    "generated response of that many bytes.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
-                                "Only enable IETF draft versions. This also "
-                                "enables required internal QUIC flags.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, quic_versions, "",
-    "QUIC versions to enable, e.g. \"h3-25,h3-27\". If not set, then all "
-    "available versions are enabled.");
-
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, enable_webtransport, false,
-                                "If true, WebTransport support is enabled.");
-
-namespace quic {
-
-std::unique_ptr<quic::QuicSimpleServerBackend>
-QuicToyServer::MemoryCacheBackendFactory::CreateBackend() {
-  auto memory_cache_backend = std::make_unique<QuicMemoryCacheBackend>();
-  if (GetQuicFlag(FLAGS_generate_dynamic_responses)) {
-    memory_cache_backend->GenerateDynamicResponses();
-  }
-  if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
-    memory_cache_backend->InitializeBackend(
-        GetQuicFlag(FLAGS_quic_response_cache_dir));
-  }
-  if (GetQuicFlag(FLAGS_enable_webtransport)) {
-    memory_cache_backend->EnableWebTransport();
-  }
-  return memory_cache_backend;
-}
-
-QuicToyServer::QuicToyServer(BackendFactory* backend_factory,
-                             ServerFactory* server_factory)
-    : backend_factory_(backend_factory), server_factory_(server_factory) {}
-
-int QuicToyServer::Start() {
-  ParsedQuicVersionVector supported_versions;
-  if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
-    QuicVersionInitializeSupportForIetfDraft();
-    for (const ParsedQuicVersion& version : AllSupportedVersions()) {
-      // Add all versions that supports IETF QUIC.
-      if (version.HasIetfQuicFrames() &&
-          version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
-        supported_versions.push_back(version);
-      }
-    }
-  } else {
-    supported_versions = AllSupportedVersions();
-  }
-  std::string versions_string = GetQuicFlag(FLAGS_quic_versions);
-  if (!versions_string.empty()) {
-    supported_versions = ParseQuicVersionVectorString(versions_string);
-  }
-  if (supported_versions.empty()) {
-    return 1;
-  }
-  for (const auto& version : supported_versions) {
-    QuicEnableVersion(version);
-  }
-  auto proof_source = quic::CreateDefaultProofSource();
-  auto backend = backend_factory_->CreateBackend();
-  auto server = server_factory_->CreateServer(
-      backend.get(), std::move(proof_source), supported_versions);
-
-  if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
-          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
-    return 1;
-  }
-
-  server->HandleEventsForever();
-  return 0;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_toy_server.h b/quic/tools/quic_toy_server.h
deleted file mode 100644
index 94e28ee..0000000
--- a/quic/tools/quic_toy_server.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
-
-#include "quic/core/crypto/proof_source.h"
-#include "quic/tools/quic_simple_server_backend.h"
-#include "quic/tools/quic_spdy_server_base.h"
-
-namespace quic {
-
-// A binary wrapper for QuicServer.  It listens forever on --port
-// (default 6121) until it's killed or ctrl-cd to death.
-class QuicToyServer {
- public:
-  // A factory for creating QuicSpdyServerBase instances.
-  class ServerFactory {
-   public:
-    virtual ~ServerFactory() = default;
-
-    // Creates a QuicSpdyServerBase instance using |backend| for generating
-    // responses, and |proof_source| for certificates.
-    virtual std::unique_ptr<QuicSpdyServerBase> CreateServer(
-        QuicSimpleServerBackend* backend,
-        std::unique_ptr<ProofSource> proof_source,
-        const ParsedQuicVersionVector& supported_versions) = 0;
-  };
-
-  // A facotry for creating QuicSimpleServerBackend instances.
-  class BackendFactory {
-   public:
-    virtual ~BackendFactory() = default;
-
-    // Creates a new backend.
-    virtual std::unique_ptr<QuicSimpleServerBackend> CreateBackend() = 0;
-  };
-
-  // A factory for creating QuicMemoryCacheBackend instances, configured
-  // to load files from disk, if necessary.
-  class MemoryCacheBackendFactory : public BackendFactory {
-   public:
-    std::unique_ptr<quic::QuicSimpleServerBackend> CreateBackend() override;
-  };
-
-  // Constructs a new toy server that will use |server_factory| to create the
-  // actual QuicSpdyServerBase instance.
-  QuicToyServer(BackendFactory* backend_factory, ServerFactory* server_factory);
-
-  // Connects to the QUIC server based on the various flags defined in the
-  // .cc file, listends for requests and sends the responses. Returns 1 on
-  // failure and does not return otherwise.
-  int Start();
-
- private:
-  BackendFactory* backend_factory_;  // Unowned.
-  ServerFactory* server_factory_;    // Unowned.
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
diff --git a/quic/tools/quic_transport_simple_server_dispatcher.cc b/quic/tools/quic_transport_simple_server_dispatcher.cc
deleted file mode 100644
index b767434..0000000
--- a/quic/tools/quic_transport_simple_server_dispatcher.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_transport_simple_server_dispatcher.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quic/core/quic_connection.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/tools/quic_transport_simple_server_session.h"
-
-namespace quic {
-
-QuicTransportSimpleServerDispatcher::QuicTransportSimpleServerDispatcher(
-    const QuicConfig* config,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicVersionManager* version_manager,
-    std::unique_ptr<QuicConnectionHelperInterface> helper,
-    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-    std::unique_ptr<QuicAlarmFactory> alarm_factory,
-    uint8_t expected_server_connection_id_length,
-    std::vector<url::Origin> accepted_origins)
-    : QuicDispatcher(config,
-                     crypto_config,
-                     version_manager,
-                     std::move(helper),
-                     std::move(session_helper),
-                     std::move(alarm_factory),
-                     expected_server_connection_id_length),
-      accepted_origins_(accepted_origins) {}
-
-std::unique_ptr<QuicSession>
-QuicTransportSimpleServerDispatcher::CreateQuicSession(
-    QuicConnectionId server_connection_id,
-    const QuicSocketAddress& self_address,
-    const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
-    const ParsedQuicVersion& version,
-    const ParsedClientHello& /*parsed_chlo*/) {
-  auto connection = std::make_unique<QuicConnection>(
-      server_connection_id, self_address, peer_address, helper(),
-      alarm_factory(), writer(),
-      /*owns_writer=*/false, Perspective::IS_SERVER,
-      ParsedQuicVersionVector{version});
-  auto session = std::make_unique<QuicTransportSimpleServerSession>(
-      connection.release(), /*owns_connection=*/true, this, config(),
-      GetSupportedVersions(), crypto_config(), compressed_certs_cache(),
-      accepted_origins_);
-  session->Initialize();
-  return session;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_transport_simple_server_dispatcher.h b/quic/tools/quic_transport_simple_server_dispatcher.h
deleted file mode 100644
index d8761f6..0000000
--- a/quic/tools/quic_transport_simple_server_dispatcher.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
-
-#include "absl/strings/string_view.h"
-#include "url/origin.h"
-#include "quic/core/quic_dispatcher.h"
-#include "quic/tools/quic_transport_simple_server_session.h"
-
-namespace quic {
-
-// Dispatcher that creates a QuicTransportSimpleServerSession for every incoming
-// connection.
-class QuicTransportSimpleServerDispatcher : public QuicDispatcher {
- public:
-  QuicTransportSimpleServerDispatcher(
-      const QuicConfig* config,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicVersionManager* version_manager,
-      std::unique_ptr<QuicConnectionHelperInterface> helper,
-      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
-      std::unique_ptr<QuicAlarmFactory> alarm_factory,
-      uint8_t expected_server_connection_id_length,
-      std::vector<url::Origin> accepted_origins);
-
- protected:
-  std::unique_ptr<QuicSession> CreateQuicSession(
-      QuicConnectionId server_connection_id,
-      const QuicSocketAddress& self_address,
-      const QuicSocketAddress& peer_address, absl::string_view alpn,
-      const ParsedQuicVersion& version,
-      const ParsedClientHello& parsed_chlo) override;
-
-  std::vector<url::Origin> accepted_origins_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
diff --git a/quic/tools/quic_transport_simple_server_session.cc b/quic/tools/quic_transport_simple_server_session.cc
deleted file mode 100644
index b8616d8..0000000
--- a/quic/tools/quic_transport_simple_server_session.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_transport_simple_server_session.h"
-
-#include <memory>
-
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/platform/api/quic_logging.h"
-#include "quic/quic_transport/quic_transport_protocol.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-#include "quic/tools/web_transport_test_visitors.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_buffer_allocator.h"
-
-namespace quic {
-
-QuicTransportSimpleServerSession::QuicTransportSimpleServerSession(
-    QuicConnection* connection,
-    bool owns_connection,
-    Visitor* owner,
-    const QuicConfig& config,
-    const ParsedQuicVersionVector& supported_versions,
-    const QuicCryptoServerConfig* crypto_config,
-    QuicCompressedCertsCache* compressed_certs_cache,
-    std::vector<url::Origin> accepted_origins)
-    : QuicTransportServerSession(connection,
-                                 owner,
-                                 config,
-                                 supported_versions,
-                                 crypto_config,
-                                 compressed_certs_cache,
-                                 this),
-      owns_connection_(owns_connection),
-      mode_(DISCARD),
-      accepted_origins_(accepted_origins) {}
-
-QuicTransportSimpleServerSession::~QuicTransportSimpleServerSession() {
-  if (owns_connection_) {
-    DeleteConnection();
-  }
-}
-
-void QuicTransportSimpleServerSession::OnIncomingDataStream(
-    QuicTransportStream* stream) {
-  switch (mode_) {
-    case DISCARD:
-      stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
-      break;
-
-    case ECHO:
-      switch (stream->type()) {
-        case BIDIRECTIONAL:
-          QUIC_DVLOG(1) << "Opening bidirectional echo stream " << stream->id();
-          stream->SetVisitor(
-              std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
-          break;
-        case READ_UNIDIRECTIONAL:
-          QUIC_DVLOG(1)
-              << "Started receiving data on unidirectional echo stream "
-              << stream->id();
-          stream->SetVisitor(
-              std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
-                  stream,
-                  [this](const std::string& s) { this->EchoStreamBack(s); }));
-          break;
-        default:
-          QUIC_NOTREACHED();
-          break;
-      }
-      break;
-
-    case OUTGOING_BIDIRECTIONAL:
-      stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
-      ++pending_outgoing_bidirectional_streams_;
-      MaybeCreateOutgoingBidirectionalStream();
-      break;
-  }
-}
-
-void QuicTransportSimpleServerSession::OnCanCreateNewOutgoingStream(
-    bool unidirectional) {
-  if (mode_ == ECHO && unidirectional) {
-    MaybeEchoStreamsBack();
-  } else if (mode_ == OUTGOING_BIDIRECTIONAL && !unidirectional) {
-    MaybeCreateOutgoingBidirectionalStream();
-  }
-}
-
-bool QuicTransportSimpleServerSession::CheckOrigin(url::Origin origin) {
-  if (accepted_origins_.empty()) {
-    return true;
-  }
-
-  for (const url::Origin& accepted_origin : accepted_origins_) {
-    if (origin.IsSameOriginWith(accepted_origin)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool QuicTransportSimpleServerSession::ProcessPath(const GURL& url) {
-  if (url.path() == "/discard") {
-    mode_ = DISCARD;
-    return true;
-  }
-  if (url.path() == "/echo") {
-    mode_ = ECHO;
-    return true;
-  }
-  if (url.path() == "/receive-bidirectional") {
-    mode_ = OUTGOING_BIDIRECTIONAL;
-    return true;
-  }
-
-  QUIC_DLOG(WARNING) << "Unknown path requested: " << url.path();
-  return false;
-}
-
-void QuicTransportSimpleServerSession::OnMessageReceived(
-    absl::string_view message) {
-  if (mode_ != ECHO) {
-    return;
-  }
-  datagram_queue()->SendOrQueueDatagram(
-      quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
-          connection()->helper()->GetStreamSendBufferAllocator(), message)));
-}
-
-void QuicTransportSimpleServerSession::MaybeEchoStreamsBack() {
-  while (!streams_to_echo_back_.empty() &&
-         CanOpenNextOutgoingUnidirectionalStream()) {
-    // Remove the stream from the queue first, in order to avoid accidentally
-    // entering an infinite loop in case any of the following code calls
-    // OnCanCreateNewOutgoingStream().
-    std::string data = std::move(streams_to_echo_back_.front());
-    streams_to_echo_back_.pop_front();
-
-    auto stream_owned = std::make_unique<QuicTransportStream>(
-        GetNextOutgoingUnidirectionalStreamId(), this, this);
-    QuicTransportStream* stream = stream_owned.get();
-    ActivateStream(std::move(stream_owned));
-    QUIC_DVLOG(1) << "Opened echo response stream " << stream->id();
-
-    stream->SetVisitor(
-        std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(stream,
-                                                                     data));
-    stream->visitor()->OnCanWrite();
-  }
-}
-
-void QuicTransportSimpleServerSession::
-    MaybeCreateOutgoingBidirectionalStream() {
-  while (pending_outgoing_bidirectional_streams_ > 0 &&
-         CanOpenNextOutgoingBidirectionalStream()) {
-    auto stream_owned = std::make_unique<QuicTransportStream>(
-        GetNextOutgoingBidirectionalStreamId(), this, this);
-    QuicTransportStream* stream = stream_owned.get();
-    ActivateStream(std::move(stream_owned));
-    QUIC_DVLOG(1) << "Opened outgoing bidirectional stream " << stream->id();
-    stream->SetVisitor(
-        std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
-    if (!stream->Write("hello")) {
-      QUIC_DVLOG(1) << "Write failed.";
-    }
-    --pending_outgoing_bidirectional_streams_;
-  }
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_transport_simple_server_session.h b/quic/tools/quic_transport_simple_server_session.h
deleted file mode 100644
index a51eab6..0000000
--- a/quic/tools/quic_transport_simple_server_session.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
-
-#include <memory>
-#include <vector>
-
-#include "url/origin.h"
-#include "quic/core/quic_types.h"
-#include "quic/core/quic_versions.h"
-#include "quic/platform/api/quic_containers.h"
-#include "quic/platform/api/quic_flags.h"
-#include "quic/quic_transport/quic_transport_server_session.h"
-#include "quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-// QuicTransport simple server is a non-production server that can be used for
-// testing QuicTransport.  It has two modes that can be changed using the
-// command line flags, "echo" and "discard".
-class QuicTransportSimpleServerSession
-    : public QuicTransportServerSession,
-      QuicTransportServerSession::ServerVisitor {
- public:
-  enum Mode {
-    // In DISCARD mode, any data on incoming streams is discarded and no
-    // outgoing streams are initiated.
-    DISCARD,
-    // In ECHO mode, any data sent on a bidirectional stream is echoed back.
-    // Any data sent on a unidirectional stream is buffered, and echoed back on
-    // a server-initiated unidirectional stream that is sent as soon as a FIN is
-    // received on the incoming stream.
-    ECHO,
-    // In OUTGOING_BIDIRECTIONAL mode, a server-originated bidirectional stream
-    // is created on receipt of a unidirectional stream. The contents of the
-    // unidirectional stream are disregarded. The bidirectional stream initially
-    // sends "hello", then any received data is echoed back.
-    // TODO(ricea): Maybe this should be replaced by a more general mechanism
-    // where commands on the unidirectional stream trigger different behaviour?
-    OUTGOING_BIDIRECTIONAL,
-  };
-
-  QuicTransportSimpleServerSession(
-      QuicConnection* connection,
-      bool owns_connection,
-      Visitor* owner,
-      const QuicConfig& config,
-      const ParsedQuicVersionVector& supported_versions,
-      const QuicCryptoServerConfig* crypto_config,
-      QuicCompressedCertsCache* compressed_certs_cache,
-      std::vector<url::Origin> accepted_origins);
-  ~QuicTransportSimpleServerSession();
-
-  void OnIncomingDataStream(QuicTransportStream* stream) override;
-  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
-  bool CheckOrigin(url::Origin origin) override;
-  bool ProcessPath(const GURL& url) override;
-  void OnMessageReceived(absl::string_view message) override;
-
-  void EchoStreamBack(const std::string& data) {
-    streams_to_echo_back_.push_back(data);
-    MaybeEchoStreamsBack();
-  }
-
- private:
-  void MaybeEchoStreamsBack();
-  void MaybeCreateOutgoingBidirectionalStream();
-
-  const bool owns_connection_;
-  size_t pending_outgoing_bidirectional_streams_ = 0u;
-  Mode mode_;
-  std::vector<url::Origin> accepted_origins_;
-  quiche::QuicheCircularDeque<std::string> streams_to_echo_back_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
diff --git a/quic/tools/quic_url.cc b/quic/tools/quic_url.cc
deleted file mode 100644
index 53b9ab0..0000000
--- a/quic/tools/quic_url.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_url.h"
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-
-namespace quic {
-
-static constexpr size_t kMaxHostNameLength = 256;
-
-QuicUrl::QuicUrl(absl::string_view url) : url_(static_cast<std::string>(url)) {}
-
-QuicUrl::QuicUrl(absl::string_view url, absl::string_view default_scheme)
-    : QuicUrl(url) {
-  if (url_.has_scheme()) {
-    return;
-  }
-
-  url_ = GURL(absl::StrCat(default_scheme, "://", url));
-}
-
-std::string QuicUrl::ToString() const {
-  if (IsValid()) {
-    return url_.spec();
-  }
-  return "";
-}
-
-bool QuicUrl::IsValid() const {
-  if (!url_.is_valid() || !url_.has_scheme()) {
-    return false;
-  }
-
-  if (url_.has_host() && url_.host().length() > kMaxHostNameLength) {
-    return false;
-  }
-
-  return true;
-}
-
-std::string QuicUrl::HostPort() const {
-  if (!IsValid() || !url_.has_host()) {
-    return "";
-  }
-
-  std::string host = url_.host();
-  int port = url_.IntPort();
-  if (port == url::PORT_UNSPECIFIED) {
-    return host;
-  }
-  return absl::StrCat(host, ":", port);
-}
-
-std::string QuicUrl::PathParamsQuery() const {
-  if (!IsValid() || !url_.has_path()) {
-    return "/";
-  }
-
-  return url_.PathForRequest();
-}
-
-std::string QuicUrl::scheme() const {
-  if (!IsValid()) {
-    return "";
-  }
-
-  return url_.scheme();
-}
-
-std::string QuicUrl::host() const {
-  if (!IsValid()) {
-    return "";
-  }
-
-  return url_.HostNoBrackets();
-}
-
-std::string QuicUrl::path() const {
-  if (!IsValid()) {
-    return "";
-  }
-
-  return url_.path();
-}
-
-uint16_t QuicUrl::port() const {
-  if (!IsValid()) {
-    return 0;
-  }
-
-  int port = url_.EffectiveIntPort();
-  if (port == url::PORT_UNSPECIFIED) {
-    return 0;
-  }
-  return port;
-}
-
-}  // namespace quic
diff --git a/quic/tools/quic_url.h b/quic/tools/quic_url.h
deleted file mode 100644
index bc2ec99..0000000
--- a/quic/tools/quic_url.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_URL_H_
-#define QUICHE_QUIC_TOOLS_QUIC_URL_H_
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "url/gurl.h"
-#include "quic/platform/api/quic_export.h"
-
-namespace quic {
-
-// A utility class that wraps GURL.
-class QuicUrl {
- public:
-  // Constructs an empty QuicUrl.
-  QuicUrl() = default;
-
-  // Constructs a QuicUrl from the url string |url|.
-  //
-  // NOTE: If |url| doesn't have a scheme, it will have an empty scheme
-  // field. If that's not what you want, use the QuicUrlImpl(url,
-  // default_scheme) form below.
-  explicit QuicUrl(absl::string_view url);
-
-  // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL
-  // is |default_scheme| if there is no scheme specified in |url|.
-  QuicUrl(absl::string_view url, absl::string_view default_scheme);
-
-  // Returns false if the URL is not valid.
-  bool IsValid() const;
-
-  // Returns full text of the QuicUrl if it is valid. Return empty string
-  // otherwise.
-  std::string ToString() const;
-
-  // Returns host:port.
-  // If the host is empty, it will return an empty string.
-  // If the host is an IPv6 address, it will be bracketed.
-  // If port is not present or is equal to default_port of scheme (e.g., port
-  // 80 for HTTP), it won't be returned.
-  std::string HostPort() const;
-
-  // Returns a string assembles path, parameters and query.
-  std::string PathParamsQuery() const;
-
-  std::string scheme() const;
-  std::string host() const;
-  std::string path() const;
-  uint16_t port() const;
-
- private:
-  GURL url_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_QUIC_URL_H_
diff --git a/quic/tools/quic_url_test.cc b/quic/tools/quic_url_test.cc
deleted file mode 100644
index ccb7aea..0000000
--- a/quic/tools/quic_url_test.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/quic_url.h"
-
-#include <string>
-
-#include "quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace test {
-namespace {
-
-class QuicUrlTest : public QuicTest {};
-
-TEST_F(QuicUrlTest, Basic) {
-  // No scheme specified.
-  std::string url_str = "www.example.com";
-  QuicUrl url(url_str);
-  EXPECT_FALSE(url.IsValid());
-
-  // scheme is HTTP.
-  url_str = "http://www.example.com";
-  url = QuicUrl(url_str);
-  EXPECT_TRUE(url.IsValid());
-  EXPECT_EQ("http://www.example.com/", url.ToString());
-  EXPECT_EQ("http", url.scheme());
-  EXPECT_EQ("www.example.com", url.HostPort());
-  EXPECT_EQ("/", url.PathParamsQuery());
-  EXPECT_EQ(80u, url.port());
-
-  // scheme is HTTPS.
-  url_str = "https://www.example.com:12345/path/to/resource?a=1&campaign=2";
-  url = QuicUrl(url_str);
-  EXPECT_TRUE(url.IsValid());
-  EXPECT_EQ("https://www.example.com:12345/path/to/resource?a=1&campaign=2",
-            url.ToString());
-  EXPECT_EQ("https", url.scheme());
-  EXPECT_EQ("www.example.com:12345", url.HostPort());
-  EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery());
-  EXPECT_EQ(12345u, url.port());
-
-  // scheme is FTP.
-  url_str = "ftp://www.example.com";
-  url = QuicUrl(url_str);
-  EXPECT_TRUE(url.IsValid());
-  EXPECT_EQ("ftp://www.example.com/", url.ToString());
-  EXPECT_EQ("ftp", url.scheme());
-  EXPECT_EQ("www.example.com", url.HostPort());
-  EXPECT_EQ("/", url.PathParamsQuery());
-  EXPECT_EQ(21u, url.port());
-}
-
-TEST_F(QuicUrlTest, DefaultScheme) {
-  // Default scheme to HTTP.
-  std::string url_str = "www.example.com";
-  QuicUrl url(url_str, "http");
-  EXPECT_EQ("http://www.example.com/", url.ToString());
-  EXPECT_EQ("http", url.scheme());
-
-  // URL already has a scheme specified.
-  url_str = "http://www.example.com";
-  url = QuicUrl(url_str, "https");
-  EXPECT_EQ("http://www.example.com/", url.ToString());
-  EXPECT_EQ("http", url.scheme());
-
-  // Default scheme to FTP.
-  url_str = "www.example.com";
-  url = QuicUrl(url_str, "ftp");
-  EXPECT_EQ("ftp://www.example.com/", url.ToString());
-  EXPECT_EQ("ftp", url.scheme());
-}
-
-TEST_F(QuicUrlTest, IsValid) {
-  std::string url_str =
-      "ftp://www.example.com:12345/path/to/resource?a=1&campaign=2";
-  EXPECT_TRUE(QuicUrl(url_str).IsValid());
-
-  // Invalid characters in host name.
-  url_str = "https://www%.example.com:12345/path/to/resource?a=1&campaign=2";
-  EXPECT_FALSE(QuicUrl(url_str).IsValid());
-
-  // Invalid characters in scheme.
-  url_str = "%http://www.example.com:12345/path/to/resource?a=1&campaign=2";
-  EXPECT_FALSE(QuicUrl(url_str).IsValid());
-
-  // Host name too long.
-  std::string host(1024, 'a');
-  url_str = "https://" + host;
-  EXPECT_FALSE(QuicUrl(url_str).IsValid());
-
-  // Invalid port number.
-  url_str = "https://www..example.com:123456/path/to/resource?a=1&campaign=2";
-  EXPECT_FALSE(QuicUrl(url_str).IsValid());
-}
-
-TEST_F(QuicUrlTest, HostPort) {
-  std::string url_str = "http://www.example.com/";
-  QuicUrl url(url_str);
-  EXPECT_EQ("www.example.com", url.HostPort());
-  EXPECT_EQ("www.example.com", url.host());
-  EXPECT_EQ(80u, url.port());
-
-  url_str = "http://www.example.com:80/";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("www.example.com", url.HostPort());
-  EXPECT_EQ("www.example.com", url.host());
-  EXPECT_EQ(80u, url.port());
-
-  url_str = "http://www.example.com:81/";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("www.example.com:81", url.HostPort());
-  EXPECT_EQ("www.example.com", url.host());
-  EXPECT_EQ(81u, url.port());
-
-  url_str = "https://192.168.1.1:443/";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("192.168.1.1", url.HostPort());
-  EXPECT_EQ("192.168.1.1", url.host());
-  EXPECT_EQ(443u, url.port());
-
-  url_str = "http://[2001::1]:80/";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("[2001::1]", url.HostPort());
-  EXPECT_EQ("2001::1", url.host());
-  EXPECT_EQ(80u, url.port());
-
-  url_str = "http://[2001::1]:81/";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("[2001::1]:81", url.HostPort());
-  EXPECT_EQ("2001::1", url.host());
-  EXPECT_EQ(81u, url.port());
-}
-
-TEST_F(QuicUrlTest, PathParamsQuery) {
-  std::string url_str =
-      "https://www.example.com:12345/path/to/resource?a=1&campaign=2";
-  QuicUrl url(url_str);
-  EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery());
-  EXPECT_EQ("/path/to/resource", url.path());
-
-  url_str = "https://www.example.com/?";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("/?", url.PathParamsQuery());
-  EXPECT_EQ("/", url.path());
-
-  url_str = "https://www.example.com/";
-  url = QuicUrl(url_str);
-  EXPECT_EQ("/", url.PathParamsQuery());
-  EXPECT_EQ("/", url.path());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/simple_ticket_crypter.cc b/quic/tools/simple_ticket_crypter.cc
deleted file mode 100644
index 149adda..0000000
--- a/quic/tools/simple_ticket_crypter.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/simple_ticket_crypter.h"
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "third_party/boringssl/src/include/openssl/rand.h"
-
-namespace quic {
-
-namespace {
-
-constexpr QuicTime::Delta kTicketKeyLifetime =
-    QuicTime::Delta::FromSeconds(60 * 60 * 24 * 7);
-
-// The format of an encrypted ticket is 1 byte for the key epoch, followed by
-// 16 bytes of IV, followed by the output from the AES-GCM Seal operation. The
-// seal operation has an overhead of 16 bytes for its auth tag.
-constexpr size_t kEpochSize = 1;
-constexpr size_t kIVSize = 16;
-constexpr size_t kAuthTagSize = 16;
-
-// Offsets into the ciphertext to make message parsing easier.
-constexpr size_t kIVOffset = kEpochSize;
-constexpr size_t kMessageOffset = kIVOffset + kIVSize;
-
-}  // namespace
-
-SimpleTicketCrypter::SimpleTicketCrypter(QuicClock* clock) : clock_(clock) {
-  RAND_bytes(&key_epoch_, 1);
-  current_key_ = NewKey();
-}
-
-SimpleTicketCrypter::~SimpleTicketCrypter() = default;
-
-size_t SimpleTicketCrypter::MaxOverhead() {
-  return kEpochSize + kIVSize + kAuthTagSize;
-}
-
-std::vector<uint8_t> SimpleTicketCrypter::Encrypt(
-    absl::string_view in, absl::string_view encryption_key) {
-  // This class is only used in Chromium, in which the |encryption_key| argument
-  // will never be populated and an internally-cached key should be used for
-  // encrypting tickets.
-  QUICHE_DCHECK(encryption_key.empty());
-  MaybeRotateKeys();
-  std::vector<uint8_t> out(in.size() + MaxOverhead());
-  out[0] = key_epoch_;
-  RAND_bytes(out.data() + kIVOffset, kIVSize);
-  size_t out_len;
-  const EVP_AEAD_CTX* ctx = current_key_->aead_ctx.get();
-  if (!EVP_AEAD_CTX_seal(ctx, out.data() + kMessageOffset, &out_len,
-                         out.size() - kMessageOffset, out.data() + kIVOffset,
-                         kIVSize, reinterpret_cast<const uint8_t*>(in.data()),
-                         in.size(), nullptr, 0)) {
-    return std::vector<uint8_t>();
-  }
-  out.resize(out_len + kMessageOffset);
-  return out;
-}
-
-std::vector<uint8_t> SimpleTicketCrypter::Decrypt(absl::string_view in) {
-  MaybeRotateKeys();
-  if (in.size() < kMessageOffset) {
-    return std::vector<uint8_t>();
-  }
-  const uint8_t* input = reinterpret_cast<const uint8_t*>(in.data());
-  std::vector<uint8_t> out(in.size() - kMessageOffset);
-  size_t out_len;
-  const EVP_AEAD_CTX* ctx = current_key_->aead_ctx.get();
-  if (input[0] != key_epoch_) {
-    if (input[0] == static_cast<uint8_t>(key_epoch_ - 1) && previous_key_) {
-      ctx = previous_key_->aead_ctx.get();
-    } else {
-      return std::vector<uint8_t>();
-    }
-  }
-  if (!EVP_AEAD_CTX_open(ctx, out.data(), &out_len, out.size(),
-                         input + kIVOffset, kIVSize, input + kMessageOffset,
-                         in.size() - kMessageOffset, nullptr, 0)) {
-    return std::vector<uint8_t>();
-  }
-  out.resize(out_len);
-  return out;
-}
-
-void SimpleTicketCrypter::Decrypt(
-    absl::string_view in,
-    std::unique_ptr<quic::ProofSource::DecryptCallback> callback) {
-  callback->Run(Decrypt(in));
-}
-
-void SimpleTicketCrypter::MaybeRotateKeys() {
-  QuicTime now = clock_->ApproximateNow();
-  if (current_key_->expiration < now) {
-    previous_key_ = std::move(current_key_);
-    current_key_ = NewKey();
-    key_epoch_++;
-  }
-}
-
-std::unique_ptr<SimpleTicketCrypter::Key> SimpleTicketCrypter::NewKey() {
-  auto key = std::make_unique<SimpleTicketCrypter::Key>();
-  RAND_bytes(key->key, kKeySize);
-  EVP_AEAD_CTX_init(key->aead_ctx.get(), EVP_aead_aes_128_gcm(), key->key,
-                    kKeySize, EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr);
-  key->expiration = clock_->ApproximateNow() + kTicketKeyLifetime;
-  return key;
-}
-
-}  // namespace quic
diff --git a/quic/tools/simple_ticket_crypter.h b/quic/tools/simple_ticket_crypter.h
deleted file mode 100644
index 052bc58..0000000
--- a/quic/tools/simple_ticket_crypter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
-#define QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
-
-#include "third_party/boringssl/src/include/openssl/aead.h"
-#include "quic/core/crypto/proof_source.h"
-#include "quic/core/quic_clock.h"
-#include "quic/core/quic_time.h"
-
-namespace quic {
-
-// SimpleTicketCrypter implements the QUIC ProofSource::TicketCrypter interface.
-// It generates a random key at startup and every 7 days it rotates the key,
-// keeping track of the previous key used to facilitate decrypting older
-// tickets. This implementation is not suitable for server setups where multiple
-// servers need to share keys.
-class QUIC_NO_EXPORT SimpleTicketCrypter
-    : public quic::ProofSource::TicketCrypter {
- public:
-  explicit SimpleTicketCrypter(QuicClock* clock);
-  ~SimpleTicketCrypter() override;
-
-  size_t MaxOverhead() override;
-  std::vector<uint8_t> Encrypt(absl::string_view in,
-                               absl::string_view encryption_key) override;
-  void Decrypt(
-      absl::string_view in,
-      std::unique_ptr<quic::ProofSource::DecryptCallback> callback) override;
-
- private:
-  std::vector<uint8_t> Decrypt(absl::string_view in);
-
-  void MaybeRotateKeys();
-
-  static constexpr size_t kKeySize = 16;
-
-  struct Key {
-    uint8_t key[kKeySize];
-    bssl::ScopedEVP_AEAD_CTX aead_ctx;
-    QuicTime expiration = QuicTime::Zero();
-  };
-
-  std::unique_ptr<Key> NewKey();
-
-  std::unique_ptr<Key> current_key_;
-  std::unique_ptr<Key> previous_key_;
-  uint8_t key_epoch_ = 0;
-  QuicClock* clock_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
diff --git a/quic/tools/simple_ticket_crypter_test.cc b/quic/tools/simple_ticket_crypter_test.cc
deleted file mode 100644
index be71018..0000000
--- a/quic/tools/simple_ticket_crypter_test.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quic/tools/simple_ticket_crypter.h"
-
-#include "quic/platform/api/quic_test.h"
-#include "quic/test_tools/mock_clock.h"
-
-namespace quic {
-namespace test {
-
-namespace {
-
-constexpr QuicTime::Delta kOneDay = QuicTime::Delta::FromSeconds(60 * 60 * 24);
-
-}  // namespace
-
-class DecryptCallback : public quic::ProofSource::DecryptCallback {
- public:
-  explicit DecryptCallback(std::vector<uint8_t>* out) : out_(out) {}
-
-  void Run(std::vector<uint8_t> plaintext) override { *out_ = plaintext; }
-
- private:
-  std::vector<uint8_t>* out_;
-};
-
-absl::string_view StringPiece(const std::vector<uint8_t>& in) {
-  return absl::string_view(reinterpret_cast<const char*>(in.data()), in.size());
-}
-
-class SimpleTicketCrypterTest : public QuicTest {
- public:
-  SimpleTicketCrypterTest() : ticket_crypter_(&mock_clock_) {}
-
- protected:
-  MockClock mock_clock_;
-  SimpleTicketCrypter ticket_crypter_;
-};
-
-TEST_F(SimpleTicketCrypterTest, EncryptDecrypt) {
-  std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
-  std::vector<uint8_t> ciphertext =
-      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
-  EXPECT_NE(plaintext, ciphertext);
-
-  std::vector<uint8_t> out_plaintext;
-  ticket_crypter_.Decrypt(StringPiece(ciphertext),
-                          std::make_unique<DecryptCallback>(&out_plaintext));
-  EXPECT_EQ(out_plaintext, plaintext);
-}
-
-TEST_F(SimpleTicketCrypterTest, CiphertextsDiffer) {
-  std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
-  std::vector<uint8_t> ciphertext1 =
-      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
-  std::vector<uint8_t> ciphertext2 =
-      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
-  EXPECT_NE(ciphertext1, ciphertext2);
-}
-
-TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithModifiedCiphertext) {
-  std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
-  std::vector<uint8_t> ciphertext =
-      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
-  EXPECT_NE(plaintext, ciphertext);
-
-  // Check that a bit flip in any byte will cause a decryption failure.
-  for (size_t i = 0; i < ciphertext.size(); i++) {
-    SCOPED_TRACE(i);
-    std::vector<uint8_t> munged_ciphertext = ciphertext;
-    munged_ciphertext[i] ^= 1;
-    std::vector<uint8_t> out_plaintext;
-    ticket_crypter_.Decrypt(StringPiece(munged_ciphertext),
-                            std::make_unique<DecryptCallback>(&out_plaintext));
-    EXPECT_TRUE(out_plaintext.empty());
-  }
-}
-
-TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithEmptyCiphertext) {
-  std::vector<uint8_t> out_plaintext;
-  ticket_crypter_.Decrypt(absl::string_view(),
-                          std::make_unique<DecryptCallback>(&out_plaintext));
-  EXPECT_TRUE(out_plaintext.empty());
-}
-
-TEST_F(SimpleTicketCrypterTest, KeyRotation) {
-  std::vector<uint8_t> plaintext = {1, 2, 3};
-  std::vector<uint8_t> ciphertext =
-      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
-  EXPECT_FALSE(ciphertext.empty());
-
-  // Advance the clock 8 days, so the key used for |ciphertext| is now the
-  // previous key. Check that decryption still works.
-  mock_clock_.AdvanceTime(kOneDay * 8);
-  std::vector<uint8_t> out_plaintext;
-  ticket_crypter_.Decrypt(StringPiece(ciphertext),
-                          std::make_unique<DecryptCallback>(&out_plaintext));
-  EXPECT_EQ(out_plaintext, plaintext);
-
-  // Advance the clock 8 more days. Now the original key should be expired and
-  // decryption should fail.
-  mock_clock_.AdvanceTime(kOneDay * 8);
-  ticket_crypter_.Decrypt(StringPiece(ciphertext),
-                          std::make_unique<DecryptCallback>(&out_plaintext));
-  EXPECT_TRUE(out_plaintext.empty());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/tools/web_transport_test_visitors.h b/quic/tools/web_transport_test_visitors.h
deleted file mode 100644
index 27605b1..0000000
--- a/quic/tools/web_transport_test_visitors.h
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright (c) 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
-#define QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
-
-#include <string>
-
-#include "quic/core/web_transport_interface.h"
-#include "quic/platform/api/quic_logging.h"
-#include "common/platform/api/quiche_mem_slice.h"
-#include "common/quiche_circular_deque.h"
-#include "common/simple_buffer_allocator.h"
-
-namespace quic {
-
-// Discards any incoming data.
-class WebTransportDiscardVisitor : public WebTransportStreamVisitor {
- public:
-  WebTransportDiscardVisitor(WebTransportStream* stream) : stream_(stream) {}
-
-  void OnCanRead() override {
-    std::string buffer;
-    WebTransportStream::ReadResult result = stream_->Read(&buffer);
-    QUIC_DVLOG(2) << "Read " << result.bytes_read
-                  << " bytes from WebTransport stream "
-                  << stream_->GetStreamId() << ", fin: " << result.fin;
-  }
-
-  void OnCanWrite() override {}
-
-  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
-  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
-  void OnWriteSideInDataRecvdState() override {}
-
- private:
-  WebTransportStream* stream_;
-};
-
-// Echoes any incoming data back on the same stream.
-class WebTransportBidirectionalEchoVisitor : public WebTransportStreamVisitor {
- public:
-  WebTransportBidirectionalEchoVisitor(WebTransportStream* stream)
-      : stream_(stream) {}
-
-  void OnCanRead() override {
-    WebTransportStream::ReadResult result = stream_->Read(&buffer_);
-    QUIC_DVLOG(1) << "Attempted reading on WebTransport bidirectional stream "
-                  << stream_->GetStreamId()
-                  << ", bytes read: " << result.bytes_read;
-    if (result.fin) {
-      send_fin_ = true;
-    }
-    OnCanWrite();
-  }
-
-  void OnCanWrite() override {
-    if (stop_sending_received_) {
-      return;
-    }
-
-    if (!buffer_.empty()) {
-      bool success = stream_->Write(buffer_);
-      QUIC_DVLOG(1) << "Attempted writing on WebTransport bidirectional stream "
-                    << stream_->GetStreamId()
-                    << ", success: " << (success ? "yes" : "no");
-      if (!success) {
-        return;
-      }
-
-      buffer_ = "";
-    }
-
-    if (send_fin_) {
-      bool success = stream_->SendFin();
-      QUICHE_DCHECK(success);
-    }
-  }
-
-  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {
-    // Send FIN in response to a stream reset.  We want to test that we can
-    // operate one side of the stream cleanly while the other is reset, thus
-    // replying with a FIN rather than a RESET_STREAM is more appropriate here.
-    send_fin_ = true;
-    OnCanWrite();
-  }
-  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {
-    stop_sending_received_ = true;
-  }
-  void OnWriteSideInDataRecvdState() override {}
-
- protected:
-  WebTransportStream* stream() { return stream_; }
-
- private:
-  WebTransportStream* stream_;
-  std::string buffer_;
-  bool send_fin_ = false;
-  bool stop_sending_received_ = false;
-};
-
-// Buffers all of the data and calls |callback| with the entirety of the stream
-// data.
-class WebTransportUnidirectionalEchoReadVisitor
-    : public WebTransportStreamVisitor {
- public:
-  using Callback = std::function<void(const std::string&)>;
-
-  WebTransportUnidirectionalEchoReadVisitor(WebTransportStream* stream,
-                                            Callback callback)
-      : stream_(stream), callback_(std::move(callback)) {}
-
-  void OnCanRead() override {
-    WebTransportStream::ReadResult result = stream_->Read(&buffer_);
-    QUIC_DVLOG(1) << "Attempted reading on WebTransport unidirectional stream "
-                  << stream_->GetStreamId()
-                  << ", bytes read: " << result.bytes_read;
-    if (result.fin) {
-      QUIC_DVLOG(1) << "Finished receiving data on a WebTransport stream "
-                    << stream_->GetStreamId() << ", queueing up the echo";
-      callback_(buffer_);
-    }
-  }
-
-  void OnCanWrite() override { QUIC_NOTREACHED(); }
-
-  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
-  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
-  void OnWriteSideInDataRecvdState() override {}
-
- private:
-  WebTransportStream* stream_;
-  std::string buffer_;
-  Callback callback_;
-};
-
-// Sends supplied data.
-class WebTransportUnidirectionalEchoWriteVisitor
-    : public WebTransportStreamVisitor {
- public:
-  WebTransportUnidirectionalEchoWriteVisitor(WebTransportStream* stream,
-                                             const std::string& data)
-      : stream_(stream), data_(data) {}
-
-  void OnCanRead() override { QUIC_NOTREACHED(); }
-  void OnCanWrite() override {
-    if (data_.empty()) {
-      return;
-    }
-    if (!stream_->Write(data_)) {
-      return;
-    }
-    data_ = "";
-    bool fin_sent = stream_->SendFin();
-    QUICHE_DVLOG(1)
-        << "WebTransportUnidirectionalEchoWriteVisitor finished sending data.";
-    QUICHE_DCHECK(fin_sent);
-  }
-
-  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
-  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
-  void OnWriteSideInDataRecvdState() override {}
-
- private:
-  WebTransportStream* stream_;
-  std::string data_;
-};
-
-// A session visitor which sets unidirectional or bidirectional stream visitors
-// to echo.
-class EchoWebTransportSessionVisitor : public WebTransportVisitor {
- public:
-  EchoWebTransportSessionVisitor(WebTransportSession* session)
-      : session_(session) {}
-
-  void OnSessionReady(const spdy::SpdyHeaderBlock&) override {
-    if (session_->CanOpenNextOutgoingBidirectionalStream()) {
-      OnCanCreateNewOutgoingBidirectionalStream();
-    }
-  }
-
-  void OnSessionClosed(WebTransportSessionError /*error_code*/,
-                       const std::string& /*error_message*/) override {}
-
-  void OnIncomingBidirectionalStreamAvailable() override {
-    while (true) {
-      WebTransportStream* stream =
-          session_->AcceptIncomingBidirectionalStream();
-      if (stream == nullptr) {
-        return;
-      }
-      QUIC_DVLOG(1)
-          << "EchoWebTransportSessionVisitor received a bidirectional stream "
-          << stream->GetStreamId();
-      stream->SetVisitor(
-          std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
-      stream->visitor()->OnCanRead();
-    }
-  }
-
-  void OnIncomingUnidirectionalStreamAvailable() override {
-    while (true) {
-      WebTransportStream* stream =
-          session_->AcceptIncomingUnidirectionalStream();
-      if (stream == nullptr) {
-        return;
-      }
-      QUIC_DVLOG(1)
-          << "EchoWebTransportSessionVisitor received a unidirectional stream";
-      stream->SetVisitor(
-          std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
-              stream, [this](const std::string& data) {
-                streams_to_echo_back_.push_back(data);
-                TrySendingUnidirectionalStreams();
-              }));
-      stream->visitor()->OnCanRead();
-    }
-  }
-
-  void OnDatagramReceived(absl::string_view datagram) override {
-    quiche::QuicheMemSlice slice(
-        quiche::QuicheBuffer::Copy(&allocator_, datagram));
-    session_->SendOrQueueDatagram(std::move(slice));
-  }
-
-  void OnCanCreateNewOutgoingBidirectionalStream() override {
-    if (!echo_stream_opened_) {
-      WebTransportStream* stream = session_->OpenOutgoingBidirectionalStream();
-      stream->SetVisitor(
-          std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
-      echo_stream_opened_ = true;
-    }
-  }
-  void OnCanCreateNewOutgoingUnidirectionalStream() override {
-    TrySendingUnidirectionalStreams();
-  }
-
-  void TrySendingUnidirectionalStreams() {
-    while (!streams_to_echo_back_.empty() &&
-           session_->CanOpenNextOutgoingUnidirectionalStream()) {
-      QUIC_DVLOG(1)
-          << "EchoWebTransportServer echoed a unidirectional stream back";
-      WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
-      stream->SetVisitor(
-          std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
-              stream, streams_to_echo_back_.front()));
-      streams_to_echo_back_.pop_front();
-      stream->visitor()->OnCanWrite();
-    }
-  }
-
- private:
-  WebTransportSession* session_;
-  quiche::SimpleBufferAllocator allocator_;
-  bool echo_stream_opened_ = false;
-
-  quiche::QuicheCircularDeque<std::string> streams_to_echo_back_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
diff --git a/CONTRIBUTING.md b/quiche/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to quiche/CONTRIBUTING.md
diff --git a/LICENSE b/quiche/LICENSE
similarity index 100%
rename from LICENSE
rename to quiche/LICENSE
diff --git a/README.md b/quiche/README.md
similarity index 100%
rename from README.md
rename to quiche/README.md
diff --git a/common/platform/api/quiche_bug_tracker.h b/quiche/common/platform/api/quiche_bug_tracker.h
similarity index 100%
rename from common/platform/api/quiche_bug_tracker.h
rename to quiche/common/platform/api/quiche_bug_tracker.h
diff --git a/common/platform/api/quiche_client_stats.h b/quiche/common/platform/api/quiche_client_stats.h
similarity index 100%
rename from common/platform/api/quiche_client_stats.h
rename to quiche/common/platform/api/quiche_client_stats.h
diff --git a/common/platform/api/quiche_command_line_flags.h b/quiche/common/platform/api/quiche_command_line_flags.h
similarity index 100%
rename from common/platform/api/quiche_command_line_flags.h
rename to quiche/common/platform/api/quiche_command_line_flags.h
diff --git a/common/platform/api/quiche_containers.h b/quiche/common/platform/api/quiche_containers.h
similarity index 100%
rename from common/platform/api/quiche_containers.h
rename to quiche/common/platform/api/quiche_containers.h
diff --git a/quiche/common/platform/api/quiche_default_proof_providers.h b/quiche/common/platform/api/quiche_default_proof_providers.h
new file mode 100644
index 0000000..9d5522e
--- /dev/null
+++ b/quiche/common/platform/api/quiche_default_proof_providers.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
+
+#include <memory>
+
+#include "quiche_platform_impl/quiche_default_proof_providers_impl.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+
+namespace quiche {
+
+// Provides a default proof verifier that can verify a cert chain for |host|.
+// The verifier has to do a good faith attempt at verifying the certificate
+// against a reasonable root store, and not just always return success.
+inline std::unique_ptr<quic::ProofVerifier> CreateDefaultProofVerifier(
+    const std::string& host) {
+  return CreateDefaultProofVerifierImpl(host);
+}
+
+// Provides a default proof source for CLI-based tools.  The actual certificates
+// used in the proof source should be confifgurable via command-line flags.
+inline std::unique_ptr<quic::ProofSource> CreateDefaultProofSource() {
+  return CreateDefaultProofSourceImpl();
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/common/platform/api/quiche_epoll.h b/quiche/common/platform/api/quiche_epoll.h
similarity index 100%
rename from common/platform/api/quiche_epoll.h
rename to quiche/common/platform/api/quiche_epoll.h
diff --git a/common/platform/api/quiche_epoll_test_tools.h b/quiche/common/platform/api/quiche_epoll_test_tools.h
similarity index 100%
rename from common/platform/api/quiche_epoll_test_tools.h
rename to quiche/common/platform/api/quiche_epoll_test_tools.h
diff --git a/common/platform/api/quiche_expect_bug.h b/quiche/common/platform/api/quiche_expect_bug.h
similarity index 100%
rename from common/platform/api/quiche_expect_bug.h
rename to quiche/common/platform/api/quiche_expect_bug.h
diff --git a/common/platform/api/quiche_export.h b/quiche/common/platform/api/quiche_export.h
similarity index 100%
rename from common/platform/api/quiche_export.h
rename to quiche/common/platform/api/quiche_export.h
diff --git a/quiche/common/platform/api/quiche_file_utils.cc b/quiche/common/platform/api/quiche_file_utils.cc
new file mode 100644
index 0000000..6453ea2
--- /dev/null
+++ b/quiche/common/platform/api/quiche_file_utils.cc
@@ -0,0 +1,51 @@
+#include "quiche/common/platform/api/quiche_file_utils.h"
+
+#include "quiche_platform_impl/quiche_file_utils_impl.h"
+
+namespace quiche {
+
+std::string JoinPath(absl::string_view a, absl::string_view b) {
+  return JoinPathImpl(a, b);
+}
+
+absl::optional<std::string> ReadFileContents(absl::string_view file) {
+  return ReadFileContentsImpl(file);
+}
+
+bool EnumerateDirectory(absl::string_view path,
+                        std::vector<std::string>& directories,
+                        std::vector<std::string>& files) {
+  return EnumerateDirectoryImpl(path, directories, files);
+}
+
+bool EnumerateDirectoryRecursivelyInner(absl::string_view path,
+                                        int recursion_limit,
+                                        std::vector<std::string>& files) {
+  if (recursion_limit < 0) {
+    return false;
+  }
+
+  std::vector<std::string> local_files;
+  std::vector<std::string> directories;
+  if (!EnumerateDirectory(path, directories, local_files)) {
+    return false;
+  }
+  for (const std::string& directory : directories) {
+    if (!EnumerateDirectoryRecursivelyInner(JoinPath(path, directory),
+                                            recursion_limit - 1, files)) {
+      return false;
+    }
+  }
+  for (const std::string& file : local_files) {
+    files.push_back(JoinPath(path, file));
+  }
+  return true;
+}
+
+bool EnumerateDirectoryRecursively(absl::string_view path,
+                                   std::vector<std::string>& files) {
+  constexpr int kRecursionLimit = 20;
+  return EnumerateDirectoryRecursivelyInner(path, kRecursionLimit, files);
+}
+
+}  // namespace quiche
diff --git a/common/platform/api/quiche_file_utils.h b/quiche/common/platform/api/quiche_file_utils.h
similarity index 100%
rename from common/platform/api/quiche_file_utils.h
rename to quiche/common/platform/api/quiche_file_utils.h
diff --git a/quiche/common/platform/api/quiche_file_utils_test.cc b/quiche/common/platform/api/quiche_file_utils_test.cc
new file mode 100644
index 0000000..68387a4
--- /dev/null
+++ b/quiche/common/platform/api/quiche_file_utils_test.cc
@@ -0,0 +1,86 @@
+#include "quiche/common/platform/api/quiche_file_utils.h"
+
+#include <vector>
+
+#include "absl/algorithm/container.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/strip.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+using testing::UnorderedElementsAre;
+using testing::UnorderedElementsAreArray;
+
+TEST(QuicheFileUtilsTest, ReadFileContents) {
+  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
+                                  "/platform/api/testdir/testfile");
+  absl::optional<std::string> contents = ReadFileContents(path);
+  ASSERT_TRUE(contents.has_value());
+  EXPECT_EQ(*contents, "This is a test file.");
+}
+
+TEST(QuicheFileUtilsTest, ReadFileContentsFileNotFound) {
+  std::string path =
+      absl::StrCat(QuicheGetCommonSourcePath(),
+                   "/platform/api/testdir/file-that-does-not-exist");
+  absl::optional<std::string> contents = ReadFileContents(path);
+  EXPECT_FALSE(contents.has_value());
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectory) {
+  std::string path =
+      absl::StrCat(QuicheGetCommonSourcePath(), "/platform/api/testdir");
+  std::vector<std::string> dirs;
+  std::vector<std::string> files;
+  bool success = EnumerateDirectory(path, dirs, files);
+  EXPECT_TRUE(success);
+  EXPECT_THAT(files, UnorderedElementsAre("testfile", "README.md"));
+  EXPECT_THAT(dirs, UnorderedElementsAre("a"));
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectoryNoSuchDirectory) {
+  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
+                                  "/platform/api/testdir/no-such-directory");
+  std::vector<std::string> dirs;
+  std::vector<std::string> files;
+  bool success = EnumerateDirectory(path, dirs, files);
+  EXPECT_FALSE(success);
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectoryNotADirectory) {
+  std::string path = absl::StrCat(QuicheGetCommonSourcePath(),
+                                  "/platform/api/testdir/testfile");
+  std::vector<std::string> dirs;
+  std::vector<std::string> files;
+  bool success = EnumerateDirectory(path, dirs, files);
+  EXPECT_FALSE(success);
+}
+
+TEST(QuicheFileUtilsTest, EnumerateDirectoryRecursively) {
+  std::vector<std::string> expected_paths = {"a/b/c/d/e", "a/subdir/testfile",
+                                             "a/z", "testfile", "README.md"};
+
+  std::string root_path =
+      absl::StrCat(QuicheGetCommonSourcePath(), "/platform/api/testdir");
+  for (std::string& path : expected_paths) {
+    // For Windows, use Windows path separators.
+    if (JoinPath("a", "b") == "a\\b") {
+      absl::c_replace(path, '/', '\\');
+    }
+
+    path = JoinPath(root_path, path);
+  }
+
+  std::vector<std::string> files;
+  bool success = EnumerateDirectoryRecursively(root_path, files);
+  EXPECT_TRUE(success);
+  EXPECT_THAT(files, UnorderedElementsAreArray(expected_paths));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/common/platform/api/quiche_flag_utils.h b/quiche/common/platform/api/quiche_flag_utils.h
similarity index 100%
rename from common/platform/api/quiche_flag_utils.h
rename to quiche/common/platform/api/quiche_flag_utils.h
diff --git a/common/platform/api/quiche_flags.h b/quiche/common/platform/api/quiche_flags.h
similarity index 100%
rename from common/platform/api/quiche_flags.h
rename to quiche/common/platform/api/quiche_flags.h
diff --git a/quiche/common/platform/api/quiche_hostname_utils.cc b/quiche/common/platform/api/quiche_hostname_utils.cc
new file mode 100644
index 0000000..19ac83e
--- /dev/null
+++ b/quiche/common/platform/api/quiche_hostname_utils.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_hostname_utils.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "url/url_canon.h"
+#include "url/url_canon_stdstring.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+// TODO(vasilvv): the functions below are forked from Chromium's
+// net/base/url_util.h; those should be moved to googleurl.
+namespace {
+
+std::string CanonicalizeHost(absl::string_view host,
+                             url::CanonHostInfo* host_info) {
+  // Try to canonicalize the host.
+  const url::Component raw_host_component(0, static_cast<int>(host.length()));
+  std::string canon_host;
+  url::StdStringCanonOutput canon_host_output(&canon_host);
+  url::CanonicalizeHostVerbose(host.data(), raw_host_component,
+                               &canon_host_output, host_info);
+
+  if (host_info->out_host.is_nonempty() &&
+      host_info->family != url::CanonHostInfo::BROKEN) {
+    // Success!  Assert that there's no extra garbage.
+    canon_host_output.Complete();
+    QUICHE_DCHECK_EQ(host_info->out_host.len,
+                     static_cast<int>(canon_host.length()));
+  } else {
+    // Empty host, or canonicalization failed.  We'll return empty.
+    canon_host.clear();
+  }
+
+  return canon_host;
+}
+
+bool IsHostCharAlphanumeric(char c) {
+  // We can just check lowercase because uppercase characters have already been
+  // normalized.
+  return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
+}
+
+bool IsCanonicalizedHostCompliant(const std::string& host) {
+  if (host.empty()) {
+    return false;
+  }
+
+  bool in_component = false;
+  bool most_recent_component_started_alphanumeric = false;
+
+  for (char c : host) {
+    if (!in_component) {
+      most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c);
+      if (!most_recent_component_started_alphanumeric && (c != '-') &&
+          (c != '_')) {
+        return false;
+      }
+      in_component = true;
+    } else if (c == '.') {
+      in_component = false;
+    } else if (!IsHostCharAlphanumeric(c) && (c != '-') && (c != '_')) {
+      return false;
+    }
+  }
+
+  return most_recent_component_started_alphanumeric;
+}
+
+}  // namespace
+
+// static
+bool QuicheHostnameUtils::IsValidSNI(absl::string_view sni) {
+  // TODO(rtenneti): Support RFC2396 hostname.
+  // NOTE: Microsoft does NOT enforce this spec, so if we throw away hostnames
+  // based on the above spec, we may be losing some hostnames that windows
+  // would consider valid. By far the most common hostname character NOT
+  // accepted by the above spec is '_'.
+  url::CanonHostInfo host_info;
+  std::string canonicalized_host = CanonicalizeHost(sni, &host_info);
+  return !host_info.IsIPAddress() &&
+         IsCanonicalizedHostCompliant(canonicalized_host);
+}
+
+// static
+std::string QuicheHostnameUtils::NormalizeHostname(absl::string_view hostname) {
+  url::CanonHostInfo host_info;
+  std::string host = CanonicalizeHost(hostname, &host_info);
+
+  // Walk backwards over the string, stopping at the first trailing dot.
+  size_t host_end = host.length();
+  while (host_end != 0 && host[host_end - 1] == '.') {
+    host_end--;
+  }
+
+  // Erase the trailing dots.
+  if (host_end != host.length()) {
+    host.erase(host_end, host.length() - host_end);
+  }
+
+  return host;
+}
+
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_hostname_utils.h b/quiche/common/platform/api/quiche_hostname_utils.h
new file mode 100644
index 0000000..00c611f
--- /dev/null
+++ b/quiche/common/platform/api/quiche_hostname_utils.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE QuicheHostnameUtils {
+ public:
+  QuicheHostnameUtils() = delete;
+
+  // Returns true if the sni is valid, false otherwise.
+  //  (1) disallow IP addresses;
+  //  (2) check that the hostname contains valid characters only; and
+  //  (3) contains at least one dot.
+  static bool IsValidSNI(absl::string_view sni);
+
+  // Canonicalizes the specified hostname.  This involves a wide variety of
+  // transformations, including lowercasing, removing trailing dots and IDNA
+  // conversion.
+  static std::string NormalizeHostname(absl::string_view hostname);
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_HOSTNAME_UTILS_H_
diff --git a/quiche/common/platform/api/quiche_hostname_utils_test.cc b/quiche/common/platform/api/quiche_hostname_utils_test.cc
new file mode 100644
index 0000000..5d52c4f
--- /dev/null
+++ b/quiche/common/platform/api/quiche_hostname_utils_test.cc
@@ -0,0 +1,89 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_hostname_utils.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class QuicheHostnameUtilsTest : public QuicheTest {};
+
+TEST_F(QuicheHostnameUtilsTest, IsValidSNI) {
+  // IP as SNI.
+  EXPECT_FALSE(QuicheHostnameUtils::IsValidSNI("192.168.0.1"));
+  // SNI without any dot.
+  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("somedomain"));
+  // Invalid by RFC2396 but unfortunately domains of this form exist.
+  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("some_domain.com"));
+  // An empty string must be invalid otherwise the QUIC client will try sending
+  // it.
+  EXPECT_FALSE(QuicheHostnameUtils::IsValidSNI(""));
+
+  // Valid SNI
+  EXPECT_TRUE(QuicheHostnameUtils::IsValidSNI("test.google.com"));
+}
+
+TEST_F(QuicheHostnameUtilsTest, NormalizeHostname) {
+  // clang-format off
+  struct {
+    const char *input, *expected;
+  } tests[] = {
+      {
+          "www.google.com",
+          "www.google.com",
+      },
+      {
+          "WWW.GOOGLE.COM",
+          "www.google.com",
+      },
+      {
+          "www.google.com.",
+          "www.google.com",
+      },
+      {
+          "www.google.COM.",
+          "www.google.com",
+      },
+      {
+          "www.google.com..",
+          "www.google.com",
+      },
+      {
+          "www.google.com........",
+          "www.google.com",
+      },
+      {
+          "",
+          "",
+      },
+      {
+          ".",
+          "",
+      },
+      {
+          "........",
+          "",
+      },
+      {
+          "\xe5\x85\x89.google.com",
+          "xn--54q.google.com",
+      },
+  };
+  // clang-format on
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(tests); ++i) {
+    EXPECT_EQ(std::string(tests[i].expected),
+              QuicheHostnameUtils::NormalizeHostname(tests[i].input));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/common/platform/api/quiche_iovec.h b/quiche/common/platform/api/quiche_iovec.h
similarity index 100%
rename from common/platform/api/quiche_iovec.h
rename to quiche/common/platform/api/quiche_iovec.h
diff --git a/common/platform/api/quiche_logging.h b/quiche/common/platform/api/quiche_logging.h
similarity index 100%
rename from common/platform/api/quiche_logging.h
rename to quiche/common/platform/api/quiche_logging.h
diff --git a/common/platform/api/quiche_lower_case_string.h b/quiche/common/platform/api/quiche_lower_case_string.h
similarity index 100%
rename from common/platform/api/quiche_lower_case_string.h
rename to quiche/common/platform/api/quiche_lower_case_string.h
diff --git a/quiche/common/platform/api/quiche_mem_slice.h b/quiche/common/platform/api/quiche_mem_slice.h
new file mode 100644
index 0000000..bb703a4
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mem_slice.h
@@ -0,0 +1,71 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
+
+#include <memory>
+
+#include "quiche_platform_impl/quiche_mem_slice_impl.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quiche {
+
+// QuicheMemSlice is a wrapper around a platform-specific I/O buffer type. It
+// may be reference counted, though QUICHE itself does not rely on that.
+class QUICHE_EXPORT_PRIVATE QuicheMemSlice {
+ public:
+  // Constructs a empty QuicheMemSlice with no underlying data.
+  QuicheMemSlice() = default;
+
+  // Constructs a QuicheMemSlice that takes ownership of |buffer|.  The length
+  // of the |buffer| must not be zero.  To construct an empty QuicheMemSlice,
+  // use the zero-argument constructor instead.
+  explicit QuicheMemSlice(QuicheBuffer buffer) : impl_(std::move(buffer)) {}
+
+  // Constructs a QuicheMemSlice that takes ownership of |buffer| allocated on
+  // heap.  |length| must not be zero.
+  QuicheMemSlice(std::unique_ptr<char[]> buffer, size_t length)
+      : impl_(std::move(buffer), length) {}
+
+  // Constructs QuicheMemSlice from |impl|. It takes the reference away from
+  // |impl|.
+  explicit QuicheMemSlice(QuicheMemSliceImpl impl) : impl_(std::move(impl)) {}
+
+  QuicheMemSlice(const QuicheMemSlice& other) = delete;
+  QuicheMemSlice& operator=(const QuicheMemSlice& other) = delete;
+
+  // Move constructors. |other| will not hold a reference to the data buffer
+  // after this call completes.
+  QuicheMemSlice(QuicheMemSlice&& other) = default;
+  QuicheMemSlice& operator=(QuicheMemSlice&& other) = default;
+
+  ~QuicheMemSlice() = default;
+
+  // Release the underlying reference. Further access the memory will result in
+  // undefined behavior.
+  void Reset() { impl_.Reset(); }
+
+  // Returns a const char pointer to underlying data buffer.
+  const char* data() const { return impl_.data(); }
+  // Returns the length of underlying data buffer.
+  size_t length() const { return impl_.length(); }
+  // Returns the representation of the underlying data as a string view.
+  absl::string_view AsStringView() const {
+    return absl::string_view(data(), length());
+  }
+
+  bool empty() const { return impl_.empty(); }
+
+  QuicheMemSliceImpl* impl() { return &impl_; }
+
+ private:
+  QuicheMemSliceImpl impl_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_
diff --git a/quiche/common/platform/api/quiche_mem_slice_test.cc b/quiche/common/platform/api/quiche_mem_slice_test.cc
new file mode 100644
index 0000000..472dbe1
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mem_slice_test.cc
@@ -0,0 +1,76 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class QuicheMemSliceTest : public QuicheTest {
+ public:
+  QuicheMemSliceTest() {
+    size_t length = 1024;
+    slice_ = QuicheMemSlice(QuicheBuffer(&allocator_, length));
+    orig_data_ = slice_.data();
+    orig_length_ = slice_.length();
+  }
+
+  SimpleBufferAllocator allocator_;
+  QuicheMemSlice slice_;
+  const char* orig_data_;
+  size_t orig_length_;
+};
+
+TEST_F(QuicheMemSliceTest, MoveConstruct) {
+  QuicheMemSlice moved(std::move(slice_));
+  EXPECT_EQ(moved.data(), orig_data_);
+  EXPECT_EQ(moved.length(), orig_length_);
+  EXPECT_EQ(nullptr, slice_.data());
+  EXPECT_EQ(0u, slice_.length());
+  EXPECT_TRUE(slice_.empty());
+}
+
+TEST_F(QuicheMemSliceTest, MoveAssign) {
+  QuicheMemSlice moved;
+  moved = std::move(slice_);
+  EXPECT_EQ(moved.data(), orig_data_);
+  EXPECT_EQ(moved.length(), orig_length_);
+  EXPECT_EQ(nullptr, slice_.data());
+  EXPECT_EQ(0u, slice_.length());
+  EXPECT_TRUE(slice_.empty());
+}
+
+TEST_F(QuicheMemSliceTest, SliceAllocatedOnHeap) {
+  auto buffer = std::make_unique<char[]>(128);
+  char* orig_data = buffer.get();
+  size_t used_length = 105;
+  QuicheMemSlice slice = QuicheMemSlice(std::move(buffer), used_length);
+  QuicheMemSlice moved = std::move(slice);
+  EXPECT_EQ(moved.data(), orig_data);
+  EXPECT_EQ(moved.length(), used_length);
+}
+
+TEST_F(QuicheMemSliceTest, SliceFromBuffer) {
+  const absl::string_view kTestString =
+      "RFC 9000 Release Celebration Memorial Test String";
+  auto buffer = QuicheBuffer::Copy(&allocator_, kTestString);
+  QuicheMemSlice slice(std::move(buffer));
+
+  EXPECT_EQ(buffer.data(), nullptr);  // NOLINT(bugprone-use-after-move)
+  EXPECT_EQ(buffer.size(), 0u);
+  EXPECT_EQ(slice.AsStringView(), kTestString);
+  EXPECT_EQ(slice.length(), kTestString.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/common/platform/api/quiche_mock_log.h b/quiche/common/platform/api/quiche_mock_log.h
similarity index 100%
rename from common/platform/api/quiche_mock_log.h
rename to quiche/common/platform/api/quiche_mock_log.h
diff --git a/quiche/common/platform/api/quiche_mutex.cc b/quiche/common/platform/api/quiche_mutex.cc
new file mode 100644
index 0000000..e6d4b0c
--- /dev/null
+++ b/quiche/common/platform/api/quiche_mutex.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_mutex.h"
+
+namespace quiche {
+
+void QuicheMutex::WriterLock() { impl_.WriterLock(); }
+
+void QuicheMutex::WriterUnlock() { impl_.WriterUnlock(); }
+
+void QuicheMutex::ReaderLock() { impl_.ReaderLock(); }
+
+void QuicheMutex::ReaderUnlock() { impl_.ReaderUnlock(); }
+
+void QuicheMutex::AssertReaderHeld() const { impl_.AssertReaderHeld(); }
+
+QuicheReaderMutexLock::QuicheReaderMutexLock(QuicheMutex* lock) : lock_(lock) {
+  lock->ReaderLock();
+}
+
+QuicheReaderMutexLock::~QuicheReaderMutexLock() { lock_->ReaderUnlock(); }
+
+QuicheWriterMutexLock::QuicheWriterMutexLock(QuicheMutex* lock) : lock_(lock) {
+  lock->WriterLock();
+}
+
+QuicheWriterMutexLock::~QuicheWriterMutexLock() { lock_->WriterUnlock(); }
+
+}  // namespace quiche
diff --git a/common/platform/api/quiche_mutex.h b/quiche/common/platform/api/quiche_mutex.h
similarity index 100%
rename from common/platform/api/quiche_mutex.h
rename to quiche/common/platform/api/quiche_mutex.h
diff --git a/common/platform/api/quiche_prefetch.h b/quiche/common/platform/api/quiche_prefetch.h
similarity index 100%
rename from common/platform/api/quiche_prefetch.h
rename to quiche/common/platform/api/quiche_prefetch.h
diff --git a/quiche/common/platform/api/quiche_reference_counted.h b/quiche/common/platform/api/quiche_reference_counted.h
new file mode 100644
index 0000000..a2cc296
--- /dev/null
+++ b/quiche/common/platform/api/quiche_reference_counted.h
@@ -0,0 +1,169 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
+
+#include "quiche_platform_impl/quiche_reference_counted_impl.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// Base class for explicitly reference-counted objects in QUIC.
+class QUICHE_EXPORT_PRIVATE QuicheReferenceCounted
+    : public QuicheReferenceCountedImpl {
+ public:
+  QuicheReferenceCounted() {}
+
+ protected:
+  ~QuicheReferenceCounted() override {}
+};
+
+// A class representing a reference counted pointer in QUIC.
+//
+// Construct or initialize QuicheReferenceCountedPointer from raw pointer. Here
+// raw pointer MUST be a newly created object. Reference count of a newly
+// created object is undefined, but that will be 1 after being added to
+// QuicheReferenceCountedPointer.
+// QuicheReferenceCountedPointer is used as a local variable.
+// QuicheReferenceCountedPointer<T> r_ptr(new T());
+// or, equivalently:
+// QuicheReferenceCountedPointer<T> r_ptr;
+// T* p = new T();
+// r_ptr = T;
+//
+// QuicheReferenceCountedPointer is used as a member variable:
+// MyClass::MyClass() : r_ptr(new T()) {}
+//
+// This is WRONG, since *p is not guaranteed to be newly created:
+// MyClass::MyClass(T* p) : r_ptr(p) {}
+//
+// Given an existing QuicheReferenceCountedPointer, create a duplicate that has
+// its own reference on the object:
+// QuicheReferenceCountedPointer<T> r_ptr_b(r_ptr_a);
+// or, equivalently:
+// QuicheReferenceCountedPointer<T> r_ptr_b = r_ptr_a;
+//
+// Given an existing QuicheReferenceCountedPointer, create a
+// QuicheReferenceCountedPointer that adopts the reference:
+// QuicheReferenceCountedPointer<T> r_ptr_b(std::move(r_ptr_a));
+// or, equivalently:
+// QuicheReferenceCountedPointer<T> r_ptr_b = std::move(r_ptr_a);
+
+template <class T>
+class QUICHE_NO_EXPORT QuicheReferenceCountedPointer {
+ public:
+  QuicheReferenceCountedPointer() = default;
+
+  // Constructor from raw pointer |p|. This guarantees that the reference count
+  // of *p is 1. This should be only called when a new object is created.
+  // Calling this on an already existent object does not increase its reference
+  // count.
+  explicit QuicheReferenceCountedPointer(T* p) : impl_(p) {}
+
+  // Allows implicit conversion from nullptr.
+  QuicheReferenceCountedPointer(std::nullptr_t) : impl_(nullptr) {}  // NOLINT
+
+  // Copy and copy conversion constructors. It does not take the reference away
+  // from |other| and they each end up with their own reference.
+  template <typename U>
+  QuicheReferenceCountedPointer(  // NOLINT
+      const QuicheReferenceCountedPointer<U>& other)
+      : impl_(other.impl()) {}
+  QuicheReferenceCountedPointer(const QuicheReferenceCountedPointer& other)
+      : impl_(other.impl()) {}
+
+  // Move constructors. After move, it adopts the reference from |other|.
+  template <typename U>
+  QuicheReferenceCountedPointer(
+      QuicheReferenceCountedPointer<U>&& other)  // NOLINT
+      : impl_(std::move(other.impl())) {}
+  QuicheReferenceCountedPointer(QuicheReferenceCountedPointer&& other)
+      : impl_(std::move(other.impl())) {}
+
+  ~QuicheReferenceCountedPointer() = default;
+
+  // Copy assignments.
+  QuicheReferenceCountedPointer& operator=(
+      const QuicheReferenceCountedPointer& other) {
+    impl_ = other.impl();
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointer<T>& operator=(
+      const QuicheReferenceCountedPointer<U>& other) {
+    impl_ = other.impl();
+    return *this;
+  }
+
+  // Move assignments.
+  QuicheReferenceCountedPointer& operator=(
+      QuicheReferenceCountedPointer&& other) {
+    impl_ = std::move(other.impl());
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointer<T>& operator=(
+      QuicheReferenceCountedPointer<U>&& other) {
+    impl_ = std::move(other.impl());
+    return *this;
+  }
+
+  // Accessors for the referenced object.
+  // operator*() and operator->() will assert() if there is no current object.
+  T& operator*() const { return *impl_; }
+  T* operator->() const { return impl_.get(); }
+
+  explicit operator bool() const { return static_cast<bool>(impl_); }
+
+  // Assignment operator on raw pointer. Drops a reference to current pointee,
+  // if any, and replaces it with |p|. This guarantees that the reference count
+  // of *p is 1. This should only be used when a new object is created.  Calling
+  // this on an already existent object is undefined behavior.
+  QuicheReferenceCountedPointer<T>& operator=(T* p) {
+    impl_ = p;
+    return *this;
+  }
+
+  // Returns the raw pointer with no change in reference count.
+  T* get() const { return impl_.get(); }
+
+  QuicheReferenceCountedPointerImpl<T>& impl() { return impl_; }
+  const QuicheReferenceCountedPointerImpl<T>& impl() const { return impl_; }
+
+  // Comparisons against same type.
+  friend bool operator==(const QuicheReferenceCountedPointer& a,
+                         const QuicheReferenceCountedPointer& b) {
+    return a.get() == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointer& a,
+                         const QuicheReferenceCountedPointer& b) {
+    return a.get() != b.get();
+  }
+
+  // Comparisons against nullptr.
+  friend bool operator==(const QuicheReferenceCountedPointer& a,
+                         std::nullptr_t) {
+    return a.get() == nullptr;
+  }
+  friend bool operator==(std::nullptr_t,
+                         const QuicheReferenceCountedPointer& b) {
+    return nullptr == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointer& a,
+                         std::nullptr_t) {
+    return a.get() != nullptr;
+  }
+  friend bool operator!=(std::nullptr_t,
+                         const QuicheReferenceCountedPointer& b) {
+    return nullptr != b.get();
+  }
+
+ private:
+  QuicheReferenceCountedPointerImpl<T> impl_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
diff --git a/quiche/common/platform/api/quiche_reference_counted_test.cc b/quiche/common/platform/api/quiche_reference_counted_test.cc
new file mode 100644
index 0000000..7c05d7a
--- /dev/null
+++ b/quiche/common/platform/api/quiche_reference_counted_test.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class Base : public QuicheReferenceCounted {
+ public:
+  explicit Base(bool* destroyed) : destroyed_(destroyed) {
+    *destroyed_ = false;
+  }
+
+ protected:
+  ~Base() override { *destroyed_ = true; }
+
+ private:
+  bool* destroyed_;
+};
+
+class Derived : public Base {
+ public:
+  explicit Derived(bool* destroyed) : Base(destroyed) {}
+
+ private:
+  ~Derived() override {}
+};
+
+class QuicheReferenceCountedTest : public QuicheTest {};
+
+TEST_F(QuicheReferenceCountedTest, DefaultConstructor) {
+  QuicheReferenceCountedPointer<Base> a;
+  EXPECT_EQ(nullptr, a);
+  EXPECT_EQ(nullptr, a.get());
+  EXPECT_FALSE(a);
+}
+
+TEST_F(QuicheReferenceCountedTest, ConstructFromRawPointer) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, RawPointerAssignment) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a;
+    Base* rct = new Base(&destroyed);
+    a = rct;
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopy) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b(a);
+      EXPECT_EQ(a, b);
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopyAssignment) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Base> a(new Base(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b = a;
+      EXPECT_EQ(a, b);
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopyFromOtherType) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b(a);
+      EXPECT_EQ(a.get(), b.get());
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerCopyAssignmentFromOtherType) {
+  bool destroyed = false;
+  {
+    QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+    {
+      QuicheReferenceCountedPointer<Base> b = a;
+      EXPECT_EQ(a.get(), b.get());
+      EXPECT_FALSE(destroyed);
+    }
+    EXPECT_FALSE(destroyed);
+  }
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMove) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b(std::move(a));
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMoveAssignment) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Base> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b = std::move(a);
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMoveFromOtherType) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b(std::move(a));
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(QuicheReferenceCountedTest, PointerMoveAssignmentFromOtherType) {
+  bool destroyed = false;
+  QuicheReferenceCountedPointer<Derived> a(new Derived(&destroyed));
+  EXPECT_FALSE(destroyed);
+  QuicheReferenceCountedPointer<Base> b = std::move(a);
+  EXPECT_FALSE(destroyed);
+  EXPECT_NE(nullptr, b);
+  EXPECT_EQ(nullptr, a);  // NOLINT
+
+  b = nullptr;
+  EXPECT_TRUE(destroyed);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/common/platform/api/quiche_server_stats.h b/quiche/common/platform/api/quiche_server_stats.h
similarity index 100%
rename from common/platform/api/quiche_server_stats.h
rename to quiche/common/platform/api/quiche_server_stats.h
diff --git a/common/platform/api/quiche_stack_trace.h b/quiche/common/platform/api/quiche_stack_trace.h
similarity index 100%
rename from common/platform/api/quiche_stack_trace.h
rename to quiche/common/platform/api/quiche_stack_trace.h
diff --git a/common/platform/api/quiche_stream_buffer_allocator.h b/quiche/common/platform/api/quiche_stream_buffer_allocator.h
similarity index 100%
rename from common/platform/api/quiche_stream_buffer_allocator.h
rename to quiche/common/platform/api/quiche_stream_buffer_allocator.h
diff --git a/common/platform/api/quiche_system_event_loop.h b/quiche/common/platform/api/quiche_system_event_loop.h
similarity index 100%
rename from common/platform/api/quiche_system_event_loop.h
rename to quiche/common/platform/api/quiche_system_event_loop.h
diff --git a/common/platform/api/quiche_test.h b/quiche/common/platform/api/quiche_test.h
similarity index 100%
rename from common/platform/api/quiche_test.h
rename to quiche/common/platform/api/quiche_test.h
diff --git a/common/platform/api/quiche_test_helpers.h b/quiche/common/platform/api/quiche_test_helpers.h
similarity index 100%
rename from common/platform/api/quiche_test_helpers.h
rename to quiche/common/platform/api/quiche_test_helpers.h
diff --git a/quiche/common/platform/api/quiche_test_loopback.cc b/quiche/common/platform/api/quiche_test_loopback.cc
new file mode 100644
index 0000000..07d3ccf
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test_loopback.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_test_loopback.h"
+
+namespace quiche {
+
+quic::IpAddressFamily AddressFamilyUnderTest() {
+  return AddressFamilyUnderTestImpl();
+}
+
+quic::QuicIpAddress TestLoopback4() { return TestLoopback4Impl(); }
+
+quic::QuicIpAddress TestLoopback6() { return TestLoopback6Impl(); }
+
+quic::QuicIpAddress TestLoopback() { return TestLoopbackImpl(); }
+
+quic::QuicIpAddress TestLoopback(int index) { return TestLoopbackImpl(index); }
+
+}  // namespace quiche
diff --git a/quiche/common/platform/api/quiche_test_loopback.h b/quiche/common/platform/api/quiche_test_loopback.h
new file mode 100644
index 0000000..b493ca4
--- /dev/null
+++ b/quiche/common/platform/api/quiche_test_loopback.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
+
+#include "quiche_platform_impl/quiche_test_loopback_impl.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quiche {
+
+// Returns the address family (IPv4 or IPv6) used to run test under.
+quic::IpAddressFamily AddressFamilyUnderTest();
+
+// Returns an IPv4 loopback address.
+quic::QuicIpAddress TestLoopback4();
+
+// Returns the only IPv6 loopback address.
+quic::QuicIpAddress TestLoopback6();
+
+// Returns an appropriate IPv4/Ipv6 loopback address based upon whether the
+// test's environment.
+quic::QuicIpAddress TestLoopback();
+
+// If address family under test is IPv4, returns an indexed IPv4 loopback
+// address. If address family under test is IPv6, the address returned is
+// platform-dependent.
+quic::QuicIpAddress TestLoopback(int index);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_TEST_LOOPBACK_H_
diff --git a/common/platform/api/quiche_test_output.h b/quiche/common/platform/api/quiche_test_output.h
similarity index 100%
rename from common/platform/api/quiche_test_output.h
rename to quiche/common/platform/api/quiche_test_output.h
diff --git a/common/platform/api/quiche_testvalue.h b/quiche/common/platform/api/quiche_testvalue.h
similarity index 100%
rename from common/platform/api/quiche_testvalue.h
rename to quiche/common/platform/api/quiche_testvalue.h
diff --git a/quiche/common/platform/api/quiche_thread.h b/quiche/common/platform/api/quiche_thread.h
new file mode 100644
index 0000000..96a596b
--- /dev/null
+++ b/quiche/common/platform/api/quiche_thread.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
+
+#include <string>
+
+#include "quiche_platform_impl/quiche_thread_impl.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// A class representing a thread of execution in QUIC.
+class QUICHE_EXPORT_PRIVATE QuicheThread : public QuicheThreadImpl {
+ public:
+  QuicheThread(const std::string& string) : QuicheThreadImpl(string) {}
+  QuicheThread(const QuicheThread&) = delete;
+  QuicheThread& operator=(const QuicheThread&) = delete;
+
+  // Impl defines a virtual void Run() method which subclasses
+  // must implement.
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_API_QUICHE_THREAD_H_
diff --git a/common/platform/api/quiche_thread_local.h b/quiche/common/platform/api/quiche_thread_local.h
similarity index 100%
rename from common/platform/api/quiche_thread_local.h
rename to quiche/common/platform/api/quiche_thread_local.h
diff --git a/common/platform/api/quiche_time_utils.h b/quiche/common/platform/api/quiche_time_utils.h
similarity index 100%
rename from common/platform/api/quiche_time_utils.h
rename to quiche/common/platform/api/quiche_time_utils.h
diff --git a/quiche/common/platform/api/quiche_time_utils_test.cc b/quiche/common/platform/api/quiche_time_utils_test.cc
new file mode 100644
index 0000000..5d09004
--- /dev/null
+++ b/quiche/common/platform/api/quiche_time_utils_test.cc
@@ -0,0 +1,51 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_time_utils.h"
+
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+TEST(QuicheTimeUtilsTest, Basic) {
+  EXPECT_EQ(1, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 0, 1));
+  EXPECT_EQ(365 * 86400, QuicheUtcDateTimeToUnixSeconds(1971, 1, 1, 0, 0, 0));
+  // Some arbitrary timestamps closer to the present, compared to the output of
+  // "Date(...).getTime()" from the JavaScript console.
+  EXPECT_EQ(1152966896,
+            QuicheUtcDateTimeToUnixSeconds(2006, 7, 15, 12, 34, 56));
+  EXPECT_EQ(1591130001, QuicheUtcDateTimeToUnixSeconds(2020, 6, 2, 20, 33, 21));
+
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 2, 29, 0, 0, 1));
+  EXPECT_NE(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1972, 2, 29, 0, 0, 1));
+}
+
+TEST(QuicheTimeUtilsTest, Bounds) {
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 1, 32, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 4, 31, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 13, 1, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt, QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 24, 0, 0));
+  EXPECT_EQ(absl::nullopt,
+            QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 60, 0));
+}
+
+TEST(QuicheTimeUtilsTest, LeapSecond) {
+  EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 23, 59, 60),
+            QuicheUtcDateTimeToUnixSeconds(2015, 7, 1, 0, 0, 0));
+  EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 25, 59, 60),
+            absl::nullopt);
+}
+
+}  // namespace
+}  // namespace quiche
diff --git a/common/platform/api/quiche_udp_socket_platform_api.h b/quiche/common/platform/api/quiche_udp_socket_platform_api.h
similarity index 100%
rename from common/platform/api/quiche_udp_socket_platform_api.h
rename to quiche/common/platform/api/quiche_udp_socket_platform_api.h
diff --git a/common/platform/api/quiche_url_utils.h b/quiche/common/platform/api/quiche_url_utils.h
similarity index 100%
rename from common/platform/api/quiche_url_utils.h
rename to quiche/common/platform/api/quiche_url_utils.h
diff --git a/quiche/common/platform/api/quiche_url_utils_test.cc b/quiche/common/platform/api/quiche_url_utils_test.cc
new file mode 100644
index 0000000..33a30ec
--- /dev/null
+++ b/quiche/common/platform/api/quiche_url_utils_test.cc
@@ -0,0 +1,80 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_url_utils.h"
+
+#include <set>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+void ValidateExpansion(
+    const std::string& uri_template,
+    const absl::flat_hash_map<std::string, std::string>& parameters,
+    const std::string& expected_expansion,
+    const absl::flat_hash_set<std::string>& expected_vars_found) {
+  absl::flat_hash_set<std::string> vars_found;
+  std::string target;
+  ASSERT_TRUE(
+      ExpandURITemplate(uri_template, parameters, &target, &vars_found));
+  EXPECT_EQ(expected_expansion, target);
+  EXPECT_EQ(vars_found, expected_vars_found);
+}
+
+TEST(QuicheUrlUtilsTest, Basic) {
+  ValidateExpansion("/{foo}/{bar}/", {{"foo", "123"}, {"bar", "456"}},
+                    "/123/456/", {"foo", "bar"});
+}
+
+TEST(QuicheUrlUtilsTest, ExtraParameter) {
+  ValidateExpansion("/{foo}/{bar}/{baz}/", {{"foo", "123"}, {"bar", "456"}},
+                    "/123/456//", {"foo", "bar"});
+}
+
+TEST(QuicheUrlUtilsTest, MissingParameter) {
+  ValidateExpansion("/{foo}/{baz}/", {{"foo", "123"}, {"bar", "456"}}, "/123//",
+                    {"foo"});
+}
+
+TEST(QuicheUrlUtilsTest, RepeatedParameter) {
+  ValidateExpansion("/{foo}/{bar}/{foo}/", {{"foo", "123"}, {"bar", "456"}},
+                    "/123/456/123/", {"foo", "bar"});
+}
+
+TEST(QuicheUrlUtilsTest, URLEncoding) {
+  ValidateExpansion("/{foo}/{bar}/", {{"foo", "123"}, {"bar", ":"}},
+                    "/123/%3A/", {"foo", "bar"});
+}
+
+void ValidateUrlDecode(const std::string& input,
+                       const absl::optional<std::string>& expected_output) {
+  absl::optional<std::string> decode_result = AsciiUrlDecode(input);
+  if (!expected_output.has_value()) {
+    EXPECT_FALSE(decode_result.has_value());
+    return;
+  }
+  ASSERT_TRUE(decode_result.has_value());
+  EXPECT_EQ(decode_result.value(), expected_output);
+}
+
+TEST(QuicheUrlUtilsTest, DecodeNoChange) {
+  ValidateUrlDecode("foobar", "foobar");
+}
+
+TEST(QuicheUrlUtilsTest, DecodeReplace) {
+  ValidateUrlDecode("%7Bfoobar%7D", "{foobar}");
+}
+
+TEST(QuicheUrlUtilsTest, DecodeFail) {
+  ValidateUrlDecode("%FF", absl::nullopt);
+}
+
+}  // namespace
+}  // namespace quiche
diff --git a/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.cc
new file mode 100644
index 0000000..df2c88e
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.cc
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche_platform_impl/quic_flags_impl.h"
+
+#define DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE(type, flag, value, doc) \
+  type FLAGS_##flag = value;
+
+#define DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES(type, flag, internal_value, \
+                                             external_value, doc)        \
+  type FLAGS_##flag = external_value;
+
+// Preprocessor macros can only have one definition.
+// Select the right macro based on the number of arguments.
+#define GET_6TH_ARG(arg1, arg2, arg3, arg4, arg5, arg6, ...) arg6
+#define QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(...)                    \
+  GET_6TH_ARG(__VA_ARGS__, DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES, \
+              DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE)
+#define QUIC_PROTOCOL_FLAG(...) \
+  QUIC_PROTOCOL_FLAG_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
+
+#include "quiche/quic/core/quic_protocol_flags_list.h"
+
+#undef QUIC_PROTOCOL_FLAG
+#undef QUIC_PROTOCOL_FLAG_MACRO_CHOOSER
+#undef GET_6TH_ARG
+#undef DEFINE_QUIC_PROTOCOL_FLAG_TWO_VALUES
+#undef DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE
diff --git a/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h
new file mode 100644
index 0000000..2d7af12
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
+
+#include <string>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_flags.h"
+
+#define QUIC_PROTOCOL_FLAG(type, flag, ...) \
+  QUICHE_EXPORT_PRIVATE extern type FLAGS_##flag;
+#include "quiche/quic/core/quic_protocol_flags_list.h"
+#undef QUIC_PROTOCOL_FLAG
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h
new file mode 100644
index 0000000..913300f
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h
@@ -0,0 +1,15 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+#define QUICHE_BUG_IMPL(b) QUICHE_LOG(DFATAL)
+#define QUICHE_BUG_IF_IMPL(b, condition) QUICHE_LOG_IF(DFATAL, condition)
+#define QUICHE_PEER_BUG_IMPL(b) QUICHE_LOG(DFATAL)
+#define QUICHE_PEER_BUG_IF_IMPL(b, condition) QUICHE_LOG_IF(DFATAL, condition)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_BUG_TRACKER_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_client_stats_impl.h
diff --git a/common/platform/default/quiche_platform_impl/quiche_containers_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_containers_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_containers_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_containers_impl.h
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_export_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_export_impl.h
new file mode 100644
index 0000000..d97748b
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_export_impl.h
@@ -0,0 +1,10 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
+
+// These macros are documented in: quiche/quic/platform/api/quic_export.h
+
+#define QUICHE_EXPORT_IMPL
+#define QUICHE_EXPORT_PRIVATE_IMPL
+#define QUICHE_NO_EXPORT_IMPL
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_EXPORT_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc
rename to quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc
diff --git a/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h
diff --git a/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_flag_utils_impl.h
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
new file mode 100644
index 0000000..6a8e1ca
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc
@@ -0,0 +1,9 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche_platform_impl/quiche_flags_impl.h"
+
+#define QUIC_FLAG(flag, value) bool flag = value;
+#include "quiche/quic/core/quic_flags_list.h"
+#undef QUIC_FLAG
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
new file mode 100644
index 0000000..a1eba51
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.h
@@ -0,0 +1,42 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+#define QUIC_FLAG(flag, value) QUICHE_EXPORT_PRIVATE extern bool flag;
+#include "quiche/quic/core/quic_flags_list.h"
+#undef QUIC_FLAG
+
+inline bool GetQuicheFlagImpl(bool flag) { return flag; }
+inline int32_t GetQuicheFlagImpl(int32_t flag) { return flag; }
+inline int64_t GetQuicheFlagImpl(int64_t flag) { return flag; }
+inline uint64_t GetQuicheFlagImpl(uint64_t flag) { return flag; }
+inline double GetQuicheFlagImpl(double flag) { return flag; }
+inline std::string GetQuicheFlagImpl(const std::string& flag) { return flag; }
+#define SetQuicheFlagImpl(flag, value) ((flag) = (value))
+
+// ------------------------------------------------------------------------
+// QUIC feature flags implementation.
+// ------------------------------------------------------------------------
+#define QUICHE_RELOADABLE_FLAG(flag) FLAGS_quic_reloadable_flag_##flag
+#define QUICHE_RESTART_FLAG(flag) FLAGS_quic_restart_flag_##flag
+#define GetQuicheReloadableFlagImpl(module, flag) \
+  GetQuicheFlag(QUICHE_RELOADABLE_FLAG(flag))
+#define SetQuicheReloadableFlagImpl(module, flag, value) \
+  SetQuicheFlag(QUICHE_RELOADABLE_FLAG(flag), value)
+#define GetQuicheRestartFlagImpl(module, flag) \
+  GetQuicheFlag(QUICHE_RESTART_FLAG(flag))
+#define SetQuicheRestartFlagImpl(module, flag, value) \
+  SetQuicheFlag(QUICHE_RESTART_FLAG(flag), value)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_FLAGS_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
new file mode 100644
index 0000000..32f0678
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_iovec_impl.h
@@ -0,0 +1,24 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+#if defined(_WIN32)
+
+// See <https://pubs.opengroup.org/onlinepubs/009604599/basedefs/sys/uio.h.html>
+struct QUICHE_EXPORT_PRIVAATE iovec {
+  void* iov_base;
+  size_t iov_len;
+};
+
+#else
+
+#include <sys/uio.h>  // IWYU pragma: export
+
+#endif  // defined(_WIN32)
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_IOVEC_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_logging_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_logging_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.h
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
new file mode 100644
index 0000000..a40fa94
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
@@ -0,0 +1,46 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE QuicheMemSliceImpl {
+ public:
+  QuicheMemSliceImpl() = default;
+
+  explicit QuicheMemSliceImpl(QuicheBuffer buffer)
+      : buffer_(std::move(buffer)) {}
+
+  QuicheMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length)
+      : buffer_(
+            QuicheBuffer(QuicheUniqueBufferPtr(
+                             buffer.release(),
+                             QuicheBufferDeleter(SimpleBufferAllocator::Get())),
+                         length)) {}
+
+  QuicheMemSliceImpl(const QuicheMemSliceImpl& other) = delete;
+  QuicheMemSliceImpl& operator=(const QuicheMemSliceImpl& other) = delete;
+
+  // Move constructors. |other| will not hold a reference to the data buffer
+  // after this call completes.
+  QuicheMemSliceImpl(QuicheMemSliceImpl&& other) = default;
+  QuicheMemSliceImpl& operator=(QuicheMemSliceImpl&& other) = default;
+
+  ~QuicheMemSliceImpl() = default;
+
+  void Reset() { buffer_ = QuicheBuffer(); }
+
+  const char* data() const { return buffer_.data(); }
+  size_t length() const { return buffer_.size(); }
+  bool empty() const { return buffer_.empty(); }
+
+ private:
+  QuicheBuffer buffer_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc
rename to quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.cc
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
new file mode 100644
index 0000000..e358c2b
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_mutex_impl.h
@@ -0,0 +1,68 @@
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
+
+#include "absl/synchronization/mutex.h"
+#include "absl/synchronization/notification.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+#define QUICHE_EXCLUSIVE_LOCKS_REQUIRED_IMPL ABSL_EXCLUSIVE_LOCKS_REQUIRED
+#define QUICHE_GUARDED_BY_IMPL ABSL_GUARDED_BY
+#define QUICHE_LOCKABLE_IMPL ABSL_LOCKABLE
+#define QUICHE_LOCKS_EXCLUDED_IMPL ABSL_LOCKS_EXCLUDED
+#define QUICHE_SHARED_LOCKS_REQUIRED_IMPL ABSL_SHARED_LOCKS_REQUIRED
+#define QUICHE_EXCLUSIVE_LOCK_FUNCTION_IMPL ABSL_EXCLUSIVE_LOCK_FUNCTION
+#define QUICHE_UNLOCK_FUNCTION_IMPL ABSL_UNLOCK_FUNCTION
+#define QUICHE_SHARED_LOCK_FUNCTION_IMPL ABSL_SHARED_LOCK_FUNCTION
+#define QUICHE_SCOPED_LOCKABLE_IMPL ABSL_SCOPED_LOCKABLE
+#define QUICHE_ASSERT_SHARED_LOCK_IMPL ABSL_ASSERT_SHARED_LOCK
+
+namespace quiche {
+
+// A class wrapping a non-reentrant mutex.
+class ABSL_LOCKABLE QUICHE_EXPORT_PRIVATE QuicheLockImpl {
+ public:
+  QuicheLockImpl() = default;
+  QuicheLockImpl(const QuicheLockImpl&) = delete;
+  QuicheLockImpl& operator=(const QuicheLockImpl&) = delete;
+
+  // Block until mu_ is free, then acquire it exclusively.
+  void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION();
+
+  // Release mu_. Caller must hold it exclusively.
+  void WriterUnlock() ABSL_UNLOCK_FUNCTION();
+
+  // Block until mu_ is free or shared, then acquire a share of it.
+  void ReaderLock() ABSL_SHARED_LOCK_FUNCTION();
+
+  // Release mu_. Caller could hold it in shared mode.
+  void ReaderUnlock() ABSL_UNLOCK_FUNCTION();
+
+  // Returns immediately if current thread holds mu_ in at least shared
+  // mode.  Otherwise, reports an error by crashing with a diagnostic.
+  void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK();
+
+ private:
+  absl::Mutex mu_;
+};
+
+// A Notification allows threads to receive notification of a single occurrence
+// of a single event.
+class QUICHE_EXPORT_PRIVATE QuicheNotificationImpl {
+ public:
+  QuicheNotificationImpl() = default;
+  QuicheNotificationImpl(const QuicheNotificationImpl&) = delete;
+  QuicheNotificationImpl& operator=(const QuicheNotificationImpl&) = delete;
+
+  bool HasBeenNotified() { return notification_.HasBeenNotified(); }
+
+  void Notify() { notification_.Notify(); }
+
+  void WaitForNotification() { notification_.WaitForNotification(); }
+
+ private:
+  absl::Notification notification_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MUTEX_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_prefetch_impl.h
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h
new file mode 100644
index 0000000..8f8a514
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_reference_counted_impl.h
@@ -0,0 +1,190 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
+
+#include <atomic>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE QuicheReferenceCountedImpl {
+ public:
+  virtual ~QuicheReferenceCountedImpl() { QUICHE_DCHECK_EQ(ref_count_, 0); }
+
+  void AddReference() { ref_count_.fetch_add(1, std::memory_order_relaxed); }
+
+  // Returns true if the objects needs to be deleted.
+  ABSL_MUST_USE_RESULT bool RemoveReference() {
+    int new_count = ref_count_.fetch_sub(1, std::memory_order_acq_rel) - 1;
+    QUICHE_DCHECK_GE(new_count, 0);
+    return new_count == 0;
+  }
+
+  bool HasUniqueReference() const {
+    return ref_count_.load(std::memory_order_acquire) == 1;
+  }
+
+ private:
+  std::atomic<int> ref_count_ = 1;
+};
+
+template <class T>
+class QUICHE_NO_EXPORT QuicheReferenceCountedPointerImpl {
+ public:
+  QuicheReferenceCountedPointerImpl() = default;
+  ~QuicheReferenceCountedPointerImpl() { RemoveReference(); }
+
+  // Constructor from raw pointer |p|. This guarantees that the reference count
+  // of *p is 1. This should be only called when a new object is created.
+  explicit QuicheReferenceCountedPointerImpl(T* p) : object_(p) {
+    if (p != nullptr) {
+      QUICHE_DCHECK(p->HasUniqueReference());
+    }
+  }
+
+  explicit QuicheReferenceCountedPointerImpl(std::nullptr_t)
+      : object_(nullptr) {}
+
+  // Copy and copy conversion constructors.
+  QuicheReferenceCountedPointerImpl(
+      const QuicheReferenceCountedPointerImpl& other) {
+    AssignObject(other.get());
+    AddReference();
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl(  // NOLINT
+      const QuicheReferenceCountedPointerImpl<U>& other) {
+    AssignObject(other.get());
+    AddReference();
+  }
+
+  // Move constructors.
+  QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl&& other) {
+    object_ = other.object_;
+    other.object_ = nullptr;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl(
+      QuicheReferenceCountedPointerImpl<U>&& other) {  // NOLINT
+    // We can't access other.object_ since other has different T and object_ is
+    // private.
+    object_ = other.get();
+    AddReference();
+    other = nullptr;
+  }
+
+  // Copy assignments.
+  QuicheReferenceCountedPointerImpl& operator=(
+      const QuicheReferenceCountedPointerImpl& other) {
+    AssignObject(other.object_);
+    AddReference();
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl<T>& operator=(
+      const QuicheReferenceCountedPointerImpl<U>& other) {
+    AssignObject(other.object_);
+    AddReference();
+    return *this;
+  }
+
+  // Move assignments.
+  QuicheReferenceCountedPointerImpl& operator=(
+      QuicheReferenceCountedPointerImpl&& other) {
+    AssignObject(other.object_);
+    other.object_ = nullptr;
+    return *this;
+  }
+  template <typename U>
+  QuicheReferenceCountedPointerImpl<T>& operator=(
+      QuicheReferenceCountedPointerImpl<U>&& other) {
+    AssignObject(other.get());
+    AddReference();
+    other = nullptr;
+    return *this;
+  }
+
+  T& operator*() const { return *object_; }
+  T* operator->() const { return object_; }
+
+  explicit operator bool() const { return object_ != nullptr; }
+
+  // Assignment operator on raw pointer.  Behaves similar to the raw pointer
+  // constructor.
+  QuicheReferenceCountedPointerImpl<T>& operator=(T* p) {
+    AssignObject(p);
+    if (p != nullptr) {
+      QUICHE_DCHECK(p->HasUniqueReference());
+    }
+    return *this;
+  }
+
+  // Returns the raw pointer with no change in reference count.
+  T* get() const { return object_; }
+
+  // Comparisons against same type.
+  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return a.get() == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return a.get() != b.get();
+  }
+
+  // Comparisons against nullptr.
+  friend bool operator==(const QuicheReferenceCountedPointerImpl& a,
+                         std::nullptr_t) {
+    return a.get() == nullptr;
+  }
+  friend bool operator==(std::nullptr_t,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return nullptr == b.get();
+  }
+  friend bool operator!=(const QuicheReferenceCountedPointerImpl& a,
+                         std::nullptr_t) {
+    return a.get() != nullptr;
+  }
+  friend bool operator!=(std::nullptr_t,
+                         const QuicheReferenceCountedPointerImpl& b) {
+    return nullptr != b.get();
+  }
+
+ private:
+  void AddReference() {
+    if (object_ == nullptr) {
+      return;
+    }
+    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
+    implicitly_cast_object->AddReference();
+  }
+
+  void RemoveReference() {
+    if (object_ == nullptr) {
+      return;
+    }
+    QuicheReferenceCountedImpl* implicitly_cast_object = object_;
+    if (implicitly_cast_object->RemoveReference()) {
+      delete implicitly_cast_object;
+    }
+    object_ = nullptr;
+  }
+
+  void AssignObject(T* new_object) {
+    RemoveReference();
+    object_ = new_object;
+  }
+
+  T* object_ = nullptr;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_server_stats_impl.h
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
new file mode 100644
index 0000000..ec56ba5
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
+
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+
+using QuicheStreamBufferAllocatorImpl = quiche::SimpleBufferAllocator;
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_STREAM_BUFFER_ALLOCATOR_IMPL_H_
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h
new file mode 100644
index 0000000..c3305c2
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_system_event_loop_impl.h
@@ -0,0 +1,24 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+inline void QuicheRunSystemEventLoopIterationImpl() {}
+
+class QUICHE_EXPORT_PRIVATE QuicheSystemEventLoopImpl {
+ public:
+  QuicheSystemEventLoopImpl(std::string context_name) {
+    QUICHE_LOG(INFO) << "Starting event loop for " << context_name;
+  }
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_SYSTEM_EVENT_LOOP_IMPL_H_
diff --git a/common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_testvalue_impl.h
diff --git a/common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_thread_local_impl.h
diff --git a/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc
rename to quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.cc
diff --git a/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h
rename to quiche/common/platform/default/quiche_platform_impl/quiche_time_utils_impl.h
diff --git a/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc
similarity index 100%
rename from common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc
rename to quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h
new file mode 100644
index 0000000..dd042a3
--- /dev/null
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
+#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
+
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// Produces concrete URLs in |target| from templated ones in |uri_template|.
+// Parameters are URL-encoded. Collects the names of any expanded variables in
+// |vars_found|. Supports level 1 templates as specified in RFC 6570. Returns
+// true if the template was parseable, false if it was malformed.
+QUICHE_EXPORT_PRIVATE bool ExpandURITemplateImpl(
+    const std::string& uri_template,
+    const absl::flat_hash_map<std::string, std::string>& parameters,
+    std::string* target,
+    absl::flat_hash_set<std::string>* vars_found = nullptr);
+
+// Decodes a URL-encoded string and converts it to ASCII. If the decoded input
+// contains non-ASCII characters, decoding fails and absl::nullopt is returned.
+QUICHE_EXPORT_PRIVATE absl::optional<std::string> AsciiUrlDecodeImpl(
+    absl::string_view input);
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
diff --git a/quiche/common/print_elements.h b/quiche/common/print_elements.h
new file mode 100644
index 0000000..627b4c9
--- /dev/null
+++ b/quiche/common/print_elements.h
@@ -0,0 +1,37 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PRINT_ELEMENTS_H_
+#define QUICHE_COMMON_PRINT_ELEMENTS_H_
+
+#include <ostream>
+#include <sstream>
+#include <string>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+// Print elements of any iterable container that has cbegin() and cend() methods
+// and the elements have operator<<(ostream) override.
+template <typename T>
+QUICHE_EXPORT_PRIVATE inline std::string PrintElements(const T& container) {
+  std::stringstream debug_string;
+  debug_string << "{";
+  auto it = container.cbegin();
+  if (it != container.cend()) {
+    debug_string << *it;
+    ++it;
+    while (it != container.cend()) {
+      debug_string << ", " << *it;
+      ++it;
+    }
+  }
+  debug_string << "}";
+  return debug_string.str();
+}
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_PRINT_ELEMENTS_H_
diff --git a/quiche/common/print_elements_test.cc b/quiche/common/print_elements_test.cc
new file mode 100644
index 0000000..17f1b1c
--- /dev/null
+++ b/quiche/common/print_elements_test.cc
@@ -0,0 +1,61 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/print_elements.h"
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using quic::QuicIetfTransportErrorCodes;
+
+namespace quiche {
+namespace test {
+namespace {
+
+TEST(PrintElementsTest, Empty) {
+  std::vector<std::string> empty{};
+  EXPECT_EQ("{}", PrintElements(empty));
+}
+
+TEST(PrintElementsTest, StdContainers) {
+  std::vector<std::string> one{"foo"};
+  EXPECT_EQ("{foo}", PrintElements(one));
+
+  std::list<std::string> two{"foo", "bar"};
+  EXPECT_EQ("{foo, bar}", PrintElements(two));
+
+  std::deque<absl::string_view> three{"foo", "bar", "baz"};
+  EXPECT_EQ("{foo, bar, baz}", PrintElements(three));
+}
+
+// QuicIetfTransportErrorCodes has a custom operator<<() override.
+TEST(PrintElementsTest, CustomPrinter) {
+  std::vector<QuicIetfTransportErrorCodes> empty{};
+  EXPECT_EQ("{}", PrintElements(empty));
+
+  std::list<QuicIetfTransportErrorCodes> one{
+      QuicIetfTransportErrorCodes::NO_IETF_QUIC_ERROR};
+  EXPECT_EQ("{NO_IETF_QUIC_ERROR}", PrintElements(one));
+
+  std::vector<QuicIetfTransportErrorCodes> two{
+      QuicIetfTransportErrorCodes::FLOW_CONTROL_ERROR,
+      QuicIetfTransportErrorCodes::STREAM_LIMIT_ERROR};
+  EXPECT_EQ("{FLOW_CONTROL_ERROR, STREAM_LIMIT_ERROR}", PrintElements(two));
+
+  std::list<QuicIetfTransportErrorCodes> three{
+      QuicIetfTransportErrorCodes::CONNECTION_ID_LIMIT_ERROR,
+      QuicIetfTransportErrorCodes::PROTOCOL_VIOLATION,
+      QuicIetfTransportErrorCodes::INVALID_TOKEN};
+  EXPECT_EQ("{CONNECTION_ID_LIMIT_ERROR, PROTOCOL_VIOLATION, INVALID_TOKEN}",
+            PrintElements(three));
+}
+
+}  // anonymous namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/quiche_buffer_allocator.cc b/quiche/common/quiche_buffer_allocator.cc
new file mode 100644
index 0000000..9d53d9d
--- /dev/null
+++ b/quiche/common/quiche_buffer_allocator.cc
@@ -0,0 +1,76 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_buffer_allocator.h"
+
+#include <cstring>
+
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_prefetch.h"
+
+namespace quiche {
+
+QuicheBuffer QuicheBuffer::CopyFromIovec(QuicheBufferAllocator* allocator,
+                                         const struct iovec* iov, int iov_count,
+                                         size_t iov_offset,
+                                         size_t buffer_length) {
+  if (buffer_length == 0) {
+    return {};
+  }
+
+  int iovnum = 0;
+  while (iovnum < iov_count && iov_offset >= iov[iovnum].iov_len) {
+    iov_offset -= iov[iovnum].iov_len;
+    ++iovnum;
+  }
+  QUICHE_DCHECK_LE(iovnum, iov_count);
+  if (iovnum >= iov_count) {
+    QUICHE_BUG(quiche_bug_10839_1)
+        << "iov_offset larger than iovec total size.";
+    return {};
+  }
+  QUICHE_DCHECK_LE(iov_offset, iov[iovnum].iov_len);
+
+  // Unroll the first iteration that handles iov_offset.
+  const size_t iov_available = iov[iovnum].iov_len - iov_offset;
+  size_t copy_len = std::min(buffer_length, iov_available);
+
+  // Try to prefetch the next iov if there is at least one more after the
+  // current. Otherwise, it looks like an irregular access that the hardware
+  // prefetcher won't speculatively prefetch. Only prefetch one iov because
+  // generally, the iov_offset is not 0, input iov consists of 2K buffers and
+  // the output buffer is ~1.4K.
+  if (copy_len == iov_available && iovnum + 1 < iov_count) {
+    char* next_base = static_cast<char*>(iov[iovnum + 1].iov_base);
+    // Prefetch 2 cachelines worth of data to get the prefetcher started; leave
+    // it to the hardware prefetcher after that.
+    quiche::QuichePrefetchT0(next_base);
+    if (iov[iovnum + 1].iov_len >= 64) {
+      quiche::QuichePrefetchT0(next_base + ABSL_CACHELINE_SIZE);
+    }
+  }
+
+  QuicheBuffer buffer(allocator, buffer_length);
+
+  const char* src = static_cast<char*>(iov[iovnum].iov_base) + iov_offset;
+  char* dst = buffer.data();
+  while (true) {
+    memcpy(dst, src, copy_len);
+    buffer_length -= copy_len;
+    dst += copy_len;
+    if (buffer_length == 0 || ++iovnum >= iov_count) {
+      break;
+    }
+    src = static_cast<char*>(iov[iovnum].iov_base);
+    copy_len = std::min(buffer_length, iov[iovnum].iov_len);
+  }
+
+  QUICHE_BUG_IF(quiche_bug_10839_2, buffer_length > 0)
+      << "iov_offset + buffer_length larger than iovec total size.";
+
+  return buffer;
+}
+
+}  // namespace quiche
diff --git a/quiche/common/quiche_buffer_allocator.h b/quiche/common/quiche_buffer_allocator.h
new file mode 100644
index 0000000..6bb1af9
--- /dev/null
+++ b/quiche/common/quiche_buffer_allocator.h
@@ -0,0 +1,126 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
+#define QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+
+namespace quiche {
+
+// Abstract base class for classes which allocate and delete buffers.
+class QUICHE_EXPORT_PRIVATE QuicheBufferAllocator {
+ public:
+  virtual ~QuicheBufferAllocator() = default;
+
+  // Returns or allocates a new buffer of |size|. Never returns null.
+  virtual char* New(size_t size) = 0;
+
+  // Returns or allocates a new buffer of |size| if |flag_enable| is true.
+  // Otherwise, returns a buffer that is compatible with this class directly
+  // with operator new. Never returns null.
+  virtual char* New(size_t size, bool flag_enable) = 0;
+
+  // Releases a buffer.
+  virtual void Delete(char* buffer) = 0;
+
+  // Marks the allocator as being idle. Serves as a hint to notify the allocator
+  // that it should release any resources it's still holding on to.
+  virtual void MarkAllocatorIdle() {}
+};
+
+// A deleter that can be used to manage ownership of buffers allocated via
+// QuicheBufferAllocator through std::unique_ptr.
+class QUICHE_EXPORT_PRIVATE QuicheBufferDeleter {
+ public:
+  explicit QuicheBufferDeleter(QuicheBufferAllocator* allocator)
+      : allocator_(allocator) {}
+
+  QuicheBufferAllocator* allocator() { return allocator_; }
+  void operator()(char* buffer) { allocator_->Delete(buffer); }
+
+ private:
+  QuicheBufferAllocator* allocator_;
+};
+
+using QuicheUniqueBufferPtr = std::unique_ptr<char[], QuicheBufferDeleter>;
+
+inline QuicheUniqueBufferPtr MakeUniqueBuffer(QuicheBufferAllocator* allocator,
+                                              size_t size) {
+  return QuicheUniqueBufferPtr(allocator->New(size),
+                               QuicheBufferDeleter(allocator));
+}
+
+// QuicheUniqueBufferPtr with a length attached to it.  Similar to
+// QuicheMemSlice, except unlike QuicheMemSlice, QuicheBuffer is mutable and is
+// not platform-specific.  Also unlike QuicheMemSlice, QuicheBuffer can be
+// empty.
+class QUICHE_EXPORT_PRIVATE QuicheBuffer {
+ public:
+  QuicheBuffer() : buffer_(nullptr, QuicheBufferDeleter(nullptr)), size_(0) {}
+  QuicheBuffer(QuicheBufferAllocator* allocator, size_t size)
+      : buffer_(MakeUniqueBuffer(allocator, size)), size_(size) {}
+
+  QuicheBuffer(QuicheUniqueBufferPtr buffer, size_t size)
+      : buffer_(std::move(buffer)), size_(size) {}
+
+  // Make sure the move constructor zeroes out the size field.
+  QuicheBuffer(QuicheBuffer&& other)
+      : buffer_(std::move(other.buffer_)), size_(other.size_) {
+    other.buffer_ = nullptr;
+    other.size_ = 0;
+  }
+  QuicheBuffer& operator=(QuicheBuffer&& other) {
+    buffer_ = std::move(other.buffer_);
+    size_ = other.size_;
+
+    other.buffer_ = nullptr;
+    other.size_ = 0;
+    return *this;
+  }
+
+  // Factory method to create a QuicheBuffer that holds a copy of `data`.
+  static QuicheBuffer Copy(QuicheBufferAllocator* allocator,
+                           absl::string_view data) {
+    QuicheBuffer buffer(allocator, data.size());
+    memcpy(buffer.data(), data.data(), data.size());
+    return buffer;
+  }
+
+  // Factory method to create a QuicheBuffer of length `buffer_length` that
+  // holds a copy of `buffer_length` bytes from `iov` starting at offset
+  // `iov_offset`.  `iov` must be at least `iov_offset + buffer_length` total
+  // length.
+  static QuicheBuffer CopyFromIovec(QuicheBufferAllocator* allocator,
+                                    const struct iovec* iov, int iov_count,
+                                    size_t iov_offset, size_t buffer_length);
+
+  const char* data() const { return buffer_.get(); }
+  char* data() { return buffer_.get(); }
+  size_t size() const { return size_; }
+  bool empty() const { return size_ == 0; }
+  absl::string_view AsStringView() const {
+    return absl::string_view(data(), size());
+  }
+
+  // Releases the ownership of the underlying buffer.
+  QuicheUniqueBufferPtr Release() {
+    size_ = 0;
+    return std::move(buffer_);
+  }
+
+ private:
+  QuicheUniqueBufferPtr buffer_;
+  size_t size_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
diff --git a/quiche/common/quiche_buffer_allocator_test.cc b/quiche/common/quiche_buffer_allocator_test.cc
new file mode 100644
index 0000000..e641481
--- /dev/null
+++ b/quiche/common/quiche_buffer_allocator_test.cc
@@ -0,0 +1,141 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_buffer_allocator.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+TEST(QuicheBuffer, CopyFromEmpty) {
+  SimpleBufferAllocator allocator;
+  QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "");
+  EXPECT_TRUE(buffer.empty());
+}
+
+TEST(QuicheBuffer, Copy) {
+  SimpleBufferAllocator allocator;
+  QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "foobar");
+  EXPECT_EQ("foobar", buffer.AsStringView());
+}
+
+TEST(QuicheBuffer, CopyFromIovecZeroBytes) {
+  const int buffer_length = 0;
+
+  SimpleBufferAllocator allocator;
+  QuicheBuffer buffer = QuicheBuffer::CopyFromIovec(
+      &allocator, nullptr,
+      /* iov_count = */ 0, /* iov_offset = */ 0, buffer_length);
+  EXPECT_TRUE(buffer.empty());
+
+  constexpr absl::string_view kData("foobar");
+  iovec iov = MakeIOVector(kData);
+
+  buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov,
+                                       /* iov_count = */ 1,
+                                       /* iov_offset = */ 0, buffer_length);
+  EXPECT_TRUE(buffer.empty());
+
+  buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov,
+                                       /* iov_count = */ 1,
+                                       /* iov_offset = */ 3, buffer_length);
+  EXPECT_TRUE(buffer.empty());
+}
+
+TEST(QuicheBuffer, CopyFromIovecSimple) {
+  constexpr absl::string_view kData("foobar");
+  iovec iov = MakeIOVector(kData);
+
+  SimpleBufferAllocator allocator;
+  QuicheBuffer buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov,
+                                  /* iov_count = */ 1, /* iov_offset = */ 0,
+                                  /* buffer_length = */ 6);
+  EXPECT_EQ("foobar", buffer.AsStringView());
+
+  buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov,
+                                  /* iov_count = */ 1, /* iov_offset = */ 0,
+                                  /* buffer_length = */ 3);
+  EXPECT_EQ("foo", buffer.AsStringView());
+
+  buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov,
+                                  /* iov_count = */ 1, /* iov_offset = */ 3,
+                                  /* buffer_length = */ 3);
+  EXPECT_EQ("bar", buffer.AsStringView());
+
+  buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov,
+                                  /* iov_count = */ 1, /* iov_offset = */ 1,
+                                  /* buffer_length = */ 4);
+  EXPECT_EQ("ooba", buffer.AsStringView());
+}
+
+TEST(QuicheBuffer, CopyFromIovecMultiple) {
+  constexpr absl::string_view kData1("foo");
+  constexpr absl::string_view kData2("bar");
+  iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
+
+  SimpleBufferAllocator allocator;
+  QuicheBuffer buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
+                                  /* iov_count = */ 2, /* iov_offset = */ 0,
+                                  /* buffer_length = */ 6);
+  EXPECT_EQ("foobar", buffer.AsStringView());
+
+  buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
+                                  /* iov_count = */ 2, /* iov_offset = */ 0,
+                                  /* buffer_length = */ 3);
+  EXPECT_EQ("foo", buffer.AsStringView());
+
+  buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
+                                  /* iov_count = */ 2, /* iov_offset = */ 3,
+                                  /* buffer_length = */ 3);
+  EXPECT_EQ("bar", buffer.AsStringView());
+
+  buffer =
+      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
+                                  /* iov_count = */ 2, /* iov_offset = */ 1,
+                                  /* buffer_length = */ 4);
+  EXPECT_EQ("ooba", buffer.AsStringView());
+}
+
+TEST(QuicheBuffer, CopyFromIovecOffsetTooLarge) {
+  constexpr absl::string_view kData1("foo");
+  constexpr absl::string_view kData2("bar");
+  iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
+
+  SimpleBufferAllocator allocator;
+  EXPECT_QUICHE_BUG(
+      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
+                                  /* iov_count = */ 2, /* iov_offset = */ 10,
+                                  /* buffer_length = */ 6),
+      "iov_offset larger than iovec total size");
+}
+
+TEST(QuicheBuffer, CopyFromIovecTooManyBytesRequested) {
+  constexpr absl::string_view kData1("foo");
+  constexpr absl::string_view kData2("bar");
+  iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
+
+  SimpleBufferAllocator allocator;
+  EXPECT_QUICHE_BUG(
+      QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
+                                  /* iov_count = */ 2, /* iov_offset = */ 2,
+                                  /* buffer_length = */ 10),
+      "iov_offset [+] buffer_length larger than iovec total size");
+}
+
+}  // anonymous namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/quiche_circular_deque.h b/quiche/common/quiche_circular_deque.h
new file mode 100644
index 0000000..f743b2d
--- /dev/null
+++ b/quiche/common/quiche_circular_deque.h
@@ -0,0 +1,759 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_CIRCULAR_DEQUE_H_
+#define QUICHE_COMMON_QUICHE_CIRCULAR_DEQUE_H_
+
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <ostream>
+#include <type_traits>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+// QuicheCircularDeque is a STL-style container that is similar to std::deque in
+// API and std::vector in capacity management. The goal is to optimize a common
+// QUIC use case where we keep adding new elements to the end and removing old
+// elements from the beginning, under such scenarios, if the container's size()
+// remain relatively stable, QuicheCircularDeque requires little to no memory
+// allocations or deallocations.
+//
+// The implementation, as the name suggests, uses a flat circular buffer to hold
+// all elements. At any point in time, either
+// a) All elements are placed in a contiguous portion of this buffer, like a
+//    c-array, or
+// b) Elements are phycially divided into two parts: the first part occupies the
+//    end of the buffer and the second part occupies the beginning of the
+//    buffer.
+//
+// Currently, elements can only be pushed or poped from either ends, it can't be
+// inserted or erased in the middle.
+//
+// TODO(wub): Make memory grow/shrink strategies customizable.
+template <typename T,
+          size_t MinCapacityIncrement = 3,
+          typename Allocator = std::allocator<T>>
+class QUICHE_NO_EXPORT QuicheCircularDeque {
+  using AllocatorTraits = std::allocator_traits<Allocator>;
+
+  // Pointee is either T or const T.
+  template <typename Pointee>
+  class QUICHE_NO_EXPORT basic_iterator {
+    using size_type = typename AllocatorTraits::size_type;
+
+   public:
+    using iterator_category = std::random_access_iterator_tag;
+    using value_type = typename AllocatorTraits::value_type;
+    using difference_type = typename AllocatorTraits::difference_type;
+    using pointer = Pointee*;
+    using reference = Pointee&;
+
+    basic_iterator() = default;
+
+    // A copy constructor if Pointee is T.
+    // A conversion from iterator to const_iterator if Pointee is const T.
+    basic_iterator(
+        const basic_iterator<value_type>& it)  // NOLINT(runtime/explicit)
+        : deque_(it.deque_), index_(it.index_) {}
+
+    // A copy assignment if Pointee is T.
+    // A assignment from iterator to const_iterator if Pointee is const T.
+    basic_iterator& operator=(const basic_iterator<value_type>& it) {
+      if (this != &it) {
+        deque_ = it.deque_;
+        index_ = it.index_;
+      }
+      return *this;
+    }
+
+    reference operator*() const { return *deque_->index_to_address(index_); }
+    pointer operator->() const { return deque_->index_to_address(index_); }
+    reference operator[](difference_type i) { return *(*this + i); }
+
+    basic_iterator& operator++() {
+      Increment();
+      return *this;
+    }
+
+    basic_iterator operator++(int) {
+      basic_iterator result = *this;
+      Increment();
+      return result;
+    }
+
+    basic_iterator operator--() {
+      Decrement();
+      return *this;
+    }
+
+    basic_iterator operator--(int) {
+      basic_iterator result = *this;
+      Decrement();
+      return result;
+    }
+
+    friend basic_iterator operator+(const basic_iterator& it,
+                                    difference_type delta) {
+      basic_iterator result = it;
+      result.IncrementBy(delta);
+      return result;
+    }
+
+    basic_iterator& operator+=(difference_type delta) {
+      IncrementBy(delta);
+      return *this;
+    }
+
+    friend basic_iterator operator-(const basic_iterator& it,
+                                    difference_type delta) {
+      basic_iterator result = it;
+      result.IncrementBy(-delta);
+      return result;
+    }
+
+    basic_iterator& operator-=(difference_type delta) {
+      IncrementBy(-delta);
+      return *this;
+    }
+
+    friend difference_type operator-(const basic_iterator& lhs,
+                                     const basic_iterator& rhs) {
+      return lhs.ExternalPosition() - rhs.ExternalPosition();
+    }
+
+    friend bool operator==(const basic_iterator& lhs,
+                           const basic_iterator& rhs) {
+      return lhs.index_ == rhs.index_;
+    }
+
+    friend bool operator!=(const basic_iterator& lhs,
+                           const basic_iterator& rhs) {
+      return !(lhs == rhs);
+    }
+
+    friend bool operator<(const basic_iterator& lhs,
+                          const basic_iterator& rhs) {
+      return lhs.ExternalPosition() < rhs.ExternalPosition();
+    }
+
+    friend bool operator<=(const basic_iterator& lhs,
+                           const basic_iterator& rhs) {
+      return !(lhs > rhs);
+    }
+
+    friend bool operator>(const basic_iterator& lhs,
+                          const basic_iterator& rhs) {
+      return lhs.ExternalPosition() > rhs.ExternalPosition();
+    }
+
+    friend bool operator>=(const basic_iterator& lhs,
+                           const basic_iterator& rhs) {
+      return !(lhs < rhs);
+    }
+
+   private:
+    basic_iterator(const QuicheCircularDeque* deque, size_type index)
+        : deque_(deque), index_(index) {}
+
+    void Increment() {
+      QUICHE_DCHECK_LE(ExternalPosition() + 1, deque_->size());
+      index_ = deque_->index_next(index_);
+    }
+
+    void Decrement() {
+      QUICHE_DCHECK_GE(ExternalPosition(), 1u);
+      index_ = deque_->index_prev(index_);
+    }
+
+    void IncrementBy(difference_type delta) {
+      if (delta >= 0) {
+        // After increment we are before or at end().
+        QUICHE_DCHECK_LE(static_cast<size_type>(ExternalPosition() + delta),
+                         deque_->size());
+      } else {
+        // After decrement we are after or at begin().
+        QUICHE_DCHECK_GE(ExternalPosition(), static_cast<size_type>(-delta));
+      }
+      index_ = deque_->index_increment_by(index_, delta);
+    }
+
+    size_type ExternalPosition() const {
+      if (index_ >= deque_->begin_) {
+        return index_ - deque_->begin_;
+      }
+      return index_ + deque_->data_capacity() - deque_->begin_;
+    }
+
+    friend class QuicheCircularDeque;
+    const QuicheCircularDeque* deque_ = nullptr;
+    size_type index_ = 0;
+  };
+
+ public:
+  using allocator_type = typename AllocatorTraits::allocator_type;
+  using value_type = typename AllocatorTraits::value_type;
+  using size_type = typename AllocatorTraits::size_type;
+  using difference_type = typename AllocatorTraits::difference_type;
+  using reference = value_type&;
+  using const_reference = const value_type&;
+  using pointer = typename AllocatorTraits::pointer;
+  using const_pointer = typename AllocatorTraits::const_pointer;
+  using iterator = basic_iterator<T>;
+  using const_iterator = basic_iterator<const T>;
+  using reverse_iterator = std::reverse_iterator<iterator>;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+  QuicheCircularDeque() : QuicheCircularDeque(allocator_type()) {}
+  explicit QuicheCircularDeque(const allocator_type& alloc)
+      : allocator_and_data_(alloc) {}
+
+  QuicheCircularDeque(size_type count,
+                      const T& value,
+                      const Allocator& alloc = allocator_type())
+      : allocator_and_data_(alloc) {
+    resize(count, value);
+  }
+
+  explicit QuicheCircularDeque(size_type count,
+                               const Allocator& alloc = allocator_type())
+      : allocator_and_data_(alloc) {
+    resize(count);
+  }
+
+  template <
+      class InputIt,
+      typename = std::enable_if_t<std::is_base_of<
+          std::input_iterator_tag,
+          typename std::iterator_traits<InputIt>::iterator_category>::value>>
+  QuicheCircularDeque(InputIt first,
+                      InputIt last,
+                      const Allocator& alloc = allocator_type())
+      : allocator_and_data_(alloc) {
+    AssignRange(first, last);
+  }
+
+  QuicheCircularDeque(const QuicheCircularDeque& other)
+      : QuicheCircularDeque(
+            other,
+            AllocatorTraits::select_on_container_copy_construction(
+                other.allocator_and_data_.allocator())) {}
+
+  QuicheCircularDeque(const QuicheCircularDeque& other,
+                      const allocator_type& alloc)
+      : allocator_and_data_(alloc) {
+    assign(other.begin(), other.end());
+  }
+
+  QuicheCircularDeque(QuicheCircularDeque&& other)
+      : begin_(other.begin_),
+        end_(other.end_),
+        allocator_and_data_(std::move(other.allocator_and_data_)) {
+    other.begin_ = other.end_ = 0;
+    other.allocator_and_data_.data = nullptr;
+    other.allocator_and_data_.data_capacity = 0;
+  }
+
+  QuicheCircularDeque(QuicheCircularDeque&& other, const allocator_type& alloc)
+      : allocator_and_data_(alloc) {
+    MoveRetainAllocator(std::move(other));
+  }
+
+  QuicheCircularDeque(std::initializer_list<T> init,
+                      const allocator_type& alloc = allocator_type())
+      : QuicheCircularDeque(init.begin(), init.end(), alloc) {}
+
+  QuicheCircularDeque& operator=(const QuicheCircularDeque& other) {
+    if (this == &other) {
+      return *this;
+    }
+    if (AllocatorTraits::propagate_on_container_copy_assignment::value &&
+        (allocator_and_data_.allocator() !=
+         other.allocator_and_data_.allocator())) {
+      // Destroy all current elements and blocks with the current allocator,
+      // before switching this to use the allocator propagated from "other".
+      DestroyAndDeallocateAll();
+      begin_ = end_ = 0;
+      allocator_and_data_ =
+          AllocatorAndData(other.allocator_and_data_.allocator());
+    }
+    assign(other.begin(), other.end());
+    return *this;
+  }
+
+  QuicheCircularDeque& operator=(QuicheCircularDeque&& other) {
+    if (this == &other) {
+      return *this;
+    }
+    if (AllocatorTraits::propagate_on_container_move_assignment::value) {
+      // Take over the storage of "other", along with its allocator.
+      this->~QuicheCircularDeque();
+      new (this) QuicheCircularDeque(std::move(other));
+    } else {
+      MoveRetainAllocator(std::move(other));
+    }
+    return *this;
+  }
+
+  ~QuicheCircularDeque() { DestroyAndDeallocateAll(); }
+
+  void assign(size_type count, const T& value) {
+    ClearRetainCapacity();
+    reserve(count);
+    for (size_t i = 0; i < count; ++i) {
+      emplace_back(value);
+    }
+  }
+
+  template <
+      class InputIt,
+      typename = std::enable_if_t<std::is_base_of<
+          std::input_iterator_tag,
+          typename std::iterator_traits<InputIt>::iterator_category>::value>>
+  void assign(InputIt first, InputIt last) {
+    AssignRange(first, last);
+  }
+
+  void assign(std::initializer_list<T> ilist) {
+    assign(ilist.begin(), ilist.end());
+  }
+
+  reference at(size_type pos) {
+    QUICHE_DCHECK(pos < size()) << "pos:" << pos << ", size():" << size();
+    size_type index = begin_ + pos;
+    if (index < data_capacity()) {
+      return *index_to_address(index);
+    }
+    return *index_to_address(index - data_capacity());
+  }
+
+  const_reference at(size_type pos) const {
+    return const_cast<QuicheCircularDeque*>(this)->at(pos);
+  }
+
+  reference operator[](size_type pos) { return at(pos); }
+
+  const_reference operator[](size_type pos) const { return at(pos); }
+
+  reference front() {
+    QUICHE_DCHECK(!empty());
+    return *index_to_address(begin_);
+  }
+
+  const_reference front() const {
+    return const_cast<QuicheCircularDeque*>(this)->front();
+  }
+
+  reference back() {
+    QUICHE_DCHECK(!empty());
+    return *(index_to_address(end_ == 0 ? data_capacity() - 1 : end_ - 1));
+  }
+
+  const_reference back() const {
+    return const_cast<QuicheCircularDeque*>(this)->back();
+  }
+
+  iterator begin() { return iterator(this, begin_); }
+  const_iterator begin() const { return const_iterator(this, begin_); }
+  const_iterator cbegin() const { return const_iterator(this, begin_); }
+
+  iterator end() { return iterator(this, end_); }
+  const_iterator end() const { return const_iterator(this, end_); }
+  const_iterator cend() const { return const_iterator(this, end_); }
+
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  const_reverse_iterator crbegin() const { return rbegin(); }
+
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+  const_reverse_iterator crend() const { return rend(); }
+
+  size_type capacity() const {
+    return data_capacity() == 0 ? 0 : data_capacity() - 1;
+  }
+
+  void reserve(size_type new_cap) {
+    if (new_cap > capacity()) {
+      Relocate(new_cap);
+    }
+  }
+
+  // Remove all elements. Leave capacity unchanged.
+  void clear() { ClearRetainCapacity(); }
+
+  bool empty() const { return begin_ == end_; }
+
+  size_type size() const {
+    if (begin_ <= end_) {
+      return end_ - begin_;
+    }
+    return data_capacity() + end_ - begin_;
+  }
+
+  void resize(size_type count) { ResizeInternal(count); }
+
+  void resize(size_type count, const value_type& value) {
+    ResizeInternal(count, value);
+  }
+
+  void push_front(const T& value) { emplace_front(value); }
+  void push_front(T&& value) { emplace_front(std::move(value)); }
+
+  template <class... Args>
+  reference emplace_front(Args&&... args) {
+    MaybeExpandCapacity(1);
+    begin_ = index_prev(begin_);
+    new (index_to_address(begin_)) T(std::forward<Args>(args)...);
+    return front();
+  }
+
+  void push_back(const T& value) { emplace_back(value); }
+  void push_back(T&& value) { emplace_back(std::move(value)); }
+
+  template <class... Args>
+  reference emplace_back(Args&&... args) {
+    MaybeExpandCapacity(1);
+    new (index_to_address(end_)) T(std::forward<Args>(args)...);
+    end_ = index_next(end_);
+    return back();
+  }
+
+  void pop_front() {
+    QUICHE_DCHECK(!empty());
+    DestroyByIndex(begin_);
+    begin_ = index_next(begin_);
+    MaybeShrinkCapacity();
+  }
+
+  size_type pop_front_n(size_type count) {
+    size_type num_elements_to_pop = std::min(count, size());
+    size_type new_begin = index_increment_by(begin_, num_elements_to_pop);
+    DestroyRange(begin_, new_begin);
+    begin_ = new_begin;
+    MaybeShrinkCapacity();
+    return num_elements_to_pop;
+  }
+
+  void pop_back() {
+    QUICHE_DCHECK(!empty());
+    end_ = index_prev(end_);
+    DestroyByIndex(end_);
+    MaybeShrinkCapacity();
+  }
+
+  size_type pop_back_n(size_type count) {
+    size_type num_elements_to_pop = std::min(count, size());
+    size_type new_end = index_increment_by(end_, -num_elements_to_pop);
+    DestroyRange(new_end, end_);
+    end_ = new_end;
+    MaybeShrinkCapacity();
+    return num_elements_to_pop;
+  }
+
+  void swap(QuicheCircularDeque& other) {
+    using std::swap;
+    swap(begin_, other.begin_);
+    swap(end_, other.end_);
+
+    if (AllocatorTraits::propagate_on_container_swap::value) {
+      swap(allocator_and_data_, other.allocator_and_data_);
+    } else {
+      // When propagate_on_container_swap is false, it is undefined behavior, by
+      // c++ standard, to swap between two AllocatorAwareContainer(s) with
+      // unequal allocators.
+      QUICHE_DCHECK(get_allocator() == other.get_allocator())
+          << "Undefined swap behavior";
+      swap(allocator_and_data_.data, other.allocator_and_data_.data);
+      swap(allocator_and_data_.data_capacity,
+           other.allocator_and_data_.data_capacity);
+    }
+  }
+
+  friend void swap(QuicheCircularDeque& lhs, QuicheCircularDeque& rhs) {
+    lhs.swap(rhs);
+  }
+
+  allocator_type get_allocator() const {
+    return allocator_and_data_.allocator();
+  }
+
+  friend bool operator==(const QuicheCircularDeque& lhs,
+                         const QuicheCircularDeque& rhs) {
+    return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
+  }
+
+  friend bool operator!=(const QuicheCircularDeque& lhs,
+                         const QuicheCircularDeque& rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend QUICHE_NO_EXPORT std::ostream& operator<<(
+      std::ostream& os,
+      const QuicheCircularDeque& dq) {
+    os << "{";
+    for (size_type pos = 0; pos != dq.size(); ++pos) {
+      if (pos != 0) {
+        os << ",";
+      }
+      os << " " << dq[pos];
+    }
+    os << " }";
+    return os;
+  }
+
+ private:
+  void MoveRetainAllocator(QuicheCircularDeque&& other) {
+    if (get_allocator() == other.get_allocator()) {
+      // Take over the storage of "other", with which we share an allocator.
+      DestroyAndDeallocateAll();
+
+      begin_ = other.begin_;
+      end_ = other.end_;
+      allocator_and_data_.data = other.allocator_and_data_.data;
+      allocator_and_data_.data_capacity =
+          other.allocator_and_data_.data_capacity;
+
+      other.begin_ = other.end_ = 0;
+      other.allocator_and_data_.data = nullptr;
+      other.allocator_and_data_.data_capacity = 0;
+    } else {
+      // We cannot take over of the storage from "other", since it has a
+      // different allocator; we're stuck move-assigning elements individually.
+      ClearRetainCapacity();
+      for (auto& elem : other) {
+        push_back(std::move(elem));
+      }
+      other.clear();
+    }
+  }
+
+  template <
+      typename InputIt,
+      typename = std::enable_if_t<std::is_base_of<
+          std::input_iterator_tag,
+          typename std::iterator_traits<InputIt>::iterator_category>::value>>
+  void AssignRange(InputIt first, InputIt last) {
+    ClearRetainCapacity();
+    if (std::is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<InputIt>::iterator_category>::value) {
+      reserve(std::distance(first, last));
+    }
+    for (; first != last; ++first) {
+      emplace_back(*first);
+    }
+  }
+
+  // WARNING: begin_, end_ and allocator_and_data_ are not modified.
+  void DestroyAndDeallocateAll() {
+    DestroyRange(begin_, end_);
+
+    if (data_capacity() > 0) {
+      QUICHE_DCHECK_NE(nullptr, allocator_and_data_.data);
+      AllocatorTraits::deallocate(allocator_and_data_.allocator(),
+                                  allocator_and_data_.data, data_capacity());
+    }
+  }
+
+  void ClearRetainCapacity() {
+    DestroyRange(begin_, end_);
+    begin_ = end_ = 0;
+  }
+
+  void MaybeShrinkCapacity() {
+    // TODO(wub): Implement a storage policy that actually shrinks.
+  }
+
+  void MaybeExpandCapacity(size_t num_additional_elements) {
+    size_t new_size = size() + num_additional_elements;
+    if (capacity() >= new_size) {
+      return;
+    }
+
+    // The minimum amount of additional capacity to grow.
+    size_t min_additional_capacity =
+        std::max(MinCapacityIncrement, capacity() / 4);
+    size_t new_capacity =
+        std::max(new_size, capacity() + min_additional_capacity);
+
+    Relocate(new_capacity);
+  }
+
+  void Relocate(size_t new_capacity) {
+    const size_t num_elements = size();
+    QUICHE_DCHECK_GT(new_capacity, num_elements)
+        << "new_capacity:" << new_capacity << ", num_elements:" << num_elements;
+
+    size_t new_data_capacity = new_capacity + 1;
+    pointer new_data = AllocatorTraits::allocate(
+        allocator_and_data_.allocator(), new_data_capacity);
+
+    if (begin_ < end_) {
+      // Not wrapped.
+      RelocateUnwrappedRange(begin_, end_, new_data);
+    } else if (begin_ > end_) {
+      // Wrapped.
+      const size_t num_elements_before_wrap = data_capacity() - begin_;
+      RelocateUnwrappedRange(begin_, data_capacity(), new_data);
+      RelocateUnwrappedRange(0, end_, new_data + num_elements_before_wrap);
+    }
+
+    if (data_capacity()) {
+      AllocatorTraits::deallocate(allocator_and_data_.allocator(),
+                                  allocator_and_data_.data, data_capacity());
+    }
+
+    allocator_and_data_.data = new_data;
+    allocator_and_data_.data_capacity = new_data_capacity;
+    begin_ = 0;
+    end_ = num_elements;
+  }
+
+  template <typename T_ = T>
+  typename std::enable_if<std::is_trivially_copyable<T_>::value, void>::type
+  RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const {
+    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
+    pointer src = index_to_address(begin);
+    QUICHE_DCHECK_NE(src, nullptr);
+    memcpy(dest, src, sizeof(T) * (end - begin));
+    DestroyRange(begin, end);
+  }
+
+  template <typename T_ = T>
+  typename std::enable_if<!std::is_trivially_copyable<T_>::value &&
+                              std::is_move_constructible<T_>::value,
+                          void>::type
+  RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const {
+    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
+    pointer src = index_to_address(begin);
+    pointer src_end = index_to_address(end);
+    while (src != src_end) {
+      new (dest) T(std::move(*src));
+      DestroyByAddress(src);
+      ++dest;
+      ++src;
+    }
+  }
+
+  template <typename T_ = T>
+  typename std::enable_if<!std::is_trivially_copyable<T_>::value &&
+                              !std::is_move_constructible<T_>::value,
+                          void>::type
+  RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const {
+    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
+    pointer src = index_to_address(begin);
+    pointer src_end = index_to_address(end);
+    while (src != src_end) {
+      new (dest) T(*src);
+      DestroyByAddress(src);
+      ++dest;
+      ++src;
+    }
+  }
+
+  template <class... U>
+  void ResizeInternal(size_type count, U&&... u) {
+    if (count > size()) {
+      // Expanding.
+      MaybeExpandCapacity(count - size());
+      while (size() < count) {
+        emplace_back(std::forward<U>(u)...);
+      }
+    } else {
+      // Most likely shrinking. No-op if count == size().
+      size_type new_end = (begin_ + count) % data_capacity();
+      DestroyRange(new_end, end_);
+      end_ = new_end;
+
+      MaybeShrinkCapacity();
+    }
+  }
+
+  void DestroyRange(size_type begin, size_type end) const {
+    if (std::is_trivially_destructible<T>::value) {
+      return;
+    }
+    if (end >= begin) {
+      DestroyUnwrappedRange(begin, end);
+    } else {
+      DestroyUnwrappedRange(begin, data_capacity());
+      DestroyUnwrappedRange(0, end);
+    }
+  }
+
+  // Should only be called from DestroyRange.
+  void DestroyUnwrappedRange(size_type begin, size_type end) const {
+    QUICHE_DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end;
+    for (; begin != end; ++begin) {
+      DestroyByIndex(begin);
+    }
+  }
+
+  void DestroyByIndex(size_type index) const {
+    DestroyByAddress(index_to_address(index));
+  }
+
+  void DestroyByAddress(pointer address) const {
+    if (std::is_trivially_destructible<T>::value) {
+      return;
+    }
+    address->~T();
+  }
+
+  size_type data_capacity() const { return allocator_and_data_.data_capacity; }
+
+  pointer index_to_address(size_type index) const {
+    return allocator_and_data_.data + index;
+  }
+
+  size_type index_prev(size_type index) const {
+    return index == 0 ? data_capacity() - 1 : index - 1;
+  }
+
+  size_type index_next(size_type index) const {
+    return index == data_capacity() - 1 ? 0 : index + 1;
+  }
+
+  size_type index_increment_by(size_type index, difference_type delta) const {
+    if (delta == 0) {
+      return index;
+    }
+
+    QUICHE_DCHECK_LT(static_cast<size_type>(std::abs(delta)), data_capacity());
+    return (index + data_capacity() + delta) % data_capacity();
+  }
+
+  // Empty base-class optimization: bundle storage for our allocator together
+  // with the fields we had to store anyway, via inheriting from the allocator,
+  // so this allocator instance doesn't consume any storage when its type has no
+  // data members.
+  struct AllocatorAndData : private allocator_type {
+    explicit AllocatorAndData(const allocator_type& alloc)
+        : allocator_type(alloc) {}
+
+    const allocator_type& allocator() const { return *this; }
+    allocator_type& allocator() { return *this; }
+
+    pointer data = nullptr;
+    size_type data_capacity = 0;
+  };
+
+  size_type begin_ = 0;
+  size_type end_ = 0;
+  AllocatorAndData allocator_and_data_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_CIRCULAR_DEQUE_H_
diff --git a/quiche/common/quiche_circular_deque_test.cc b/quiche/common/quiche_circular_deque_test.cc
new file mode 100644
index 0000000..6db7240
--- /dev/null
+++ b/quiche/common/quiche_circular_deque_test.cc
@@ -0,0 +1,801 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_circular_deque.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <type_traits>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using testing::ElementsAre;
+
+namespace quiche {
+namespace test {
+namespace {
+
+template <typename T, template <typename> class BaseAllocator = std::allocator>
+class CountingAllocator : public BaseAllocator<T> {
+  using BaseType = BaseAllocator<T>;
+
+ public:
+  using propagate_on_container_copy_assignment = std::true_type;
+  using propagate_on_container_move_assignment = std::true_type;
+  using propagate_on_container_swap = std::true_type;
+
+  T* allocate(std::size_t n) {
+    ++shared_counts_->allocate_count;
+    return BaseType::allocate(n);
+  }
+
+  void deallocate(T* ptr, std::size_t n) {
+    ++shared_counts_->deallocate_count;
+    return BaseType::deallocate(ptr, n);
+  }
+
+  size_t allocate_count() const { return shared_counts_->allocate_count; }
+
+  size_t deallocate_count() const { return shared_counts_->deallocate_count; }
+
+  friend bool operator==(const CountingAllocator& lhs,
+                         const CountingAllocator& rhs) {
+    return lhs.shared_counts_ == rhs.shared_counts_;
+  }
+
+  friend bool operator!=(const CountingAllocator& lhs,
+                         const CountingAllocator& rhs) {
+    return !(lhs == rhs);
+  }
+
+ private:
+  struct Counts {
+    size_t allocate_count = 0;
+    size_t deallocate_count = 0;
+  };
+
+  std::shared_ptr<Counts> shared_counts_ = std::make_shared<Counts>();
+};
+
+template <typename T,
+          typename propagate_on_copy_assignment,
+          typename propagate_on_move_assignment,
+          typename propagate_on_swap,
+          bool equality_result,
+          template <typename> class BaseAllocator = std::allocator>
+struct ConfigurableAllocator : public BaseAllocator<T> {
+  using propagate_on_container_copy_assignment = propagate_on_copy_assignment;
+  using propagate_on_container_move_assignment = propagate_on_move_assignment;
+  using propagate_on_container_swap = propagate_on_swap;
+
+  friend bool operator==(const ConfigurableAllocator& /*lhs*/,
+                         const ConfigurableAllocator& /*rhs*/) {
+    return equality_result;
+  }
+
+  friend bool operator!=(const ConfigurableAllocator& lhs,
+                         const ConfigurableAllocator& rhs) {
+    return !(lhs == rhs);
+  }
+};
+
+// [1, 2, 3, 4] ==> [4, 1, 2, 3]
+template <typename Deque>
+void ShiftRight(Deque* dq, bool emplace) {
+  auto back = *(&dq->back());
+  dq->pop_back();
+  if (emplace) {
+    dq->emplace_front(back);
+  } else {
+    dq->push_front(back);
+  }
+}
+
+// [1, 2, 3, 4] ==> [2, 3, 4, 1]
+template <typename Deque>
+void ShiftLeft(Deque* dq, bool emplace) {
+  auto front = *(&dq->front());
+  dq->pop_front();
+  if (emplace) {
+    dq->emplace_back(front);
+  } else {
+    dq->push_back(front);
+  }
+}
+
+class QuicheCircularDequeTest : public QuicheTest {};
+
+TEST_F(QuicheCircularDequeTest, Empty) {
+  QuicheCircularDeque<int> dq;
+  EXPECT_TRUE(dq.empty());
+  EXPECT_EQ(0u, dq.size());
+  dq.clear();
+  dq.push_back(10);
+  EXPECT_FALSE(dq.empty());
+  EXPECT_EQ(1u, dq.size());
+  EXPECT_EQ(10, dq.front());
+  EXPECT_EQ(10, dq.back());
+  dq.pop_front();
+  EXPECT_TRUE(dq.empty());
+  EXPECT_EQ(0u, dq.size());
+
+  EXPECT_QUICHE_DEBUG_DEATH(dq.front(), "");
+  EXPECT_QUICHE_DEBUG_DEATH(dq.back(), "");
+  EXPECT_QUICHE_DEBUG_DEATH(dq.at(0), "");
+  EXPECT_QUICHE_DEBUG_DEATH(dq[0], "");
+}
+
+TEST_F(QuicheCircularDequeTest, Constructor) {
+  QuicheCircularDeque<int> dq;
+  EXPECT_TRUE(dq.empty());
+
+  std::allocator<int> alloc;
+  QuicheCircularDeque<int> dq1(alloc);
+  EXPECT_TRUE(dq1.empty());
+
+  QuicheCircularDeque<int> dq2(8, 100, alloc);
+  EXPECT_THAT(dq2, ElementsAre(100, 100, 100, 100, 100, 100, 100, 100));
+
+  QuicheCircularDeque<int> dq3(5, alloc);
+  EXPECT_THAT(dq3, ElementsAre(0, 0, 0, 0, 0));
+
+  QuicheCircularDeque<int> dq4_rand_iter(dq3.begin(), dq3.end(), alloc);
+  EXPECT_THAT(dq4_rand_iter, ElementsAre(0, 0, 0, 0, 0));
+  EXPECT_EQ(dq4_rand_iter, dq3);
+
+  std::list<int> dq4_src = {4, 4, 4, 4};
+  QuicheCircularDeque<int> dq4_bidi_iter(dq4_src.begin(), dq4_src.end());
+  EXPECT_THAT(dq4_bidi_iter, ElementsAre(4, 4, 4, 4));
+
+  QuicheCircularDeque<int> dq5(dq4_bidi_iter);
+  EXPECT_THAT(dq5, ElementsAre(4, 4, 4, 4));
+  EXPECT_EQ(dq5, dq4_bidi_iter);
+
+  QuicheCircularDeque<int> dq6(dq5, alloc);
+  EXPECT_THAT(dq6, ElementsAre(4, 4, 4, 4));
+  EXPECT_EQ(dq6, dq5);
+
+  QuicheCircularDeque<int> dq7(std::move(*&dq6));
+  EXPECT_THAT(dq7, ElementsAre(4, 4, 4, 4));
+  EXPECT_TRUE(dq6.empty());
+
+  QuicheCircularDeque<int> dq8_equal_allocator(std::move(*&dq7), alloc);
+  EXPECT_THAT(dq8_equal_allocator, ElementsAre(4, 4, 4, 4));
+  EXPECT_TRUE(dq7.empty());
+
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq8_temp = {5, 6, 7, 8,
+                                                                  9};
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq8_unequal_allocator(
+      std::move(*&dq8_temp), CountingAllocator<int>());
+  EXPECT_THAT(dq8_unequal_allocator, ElementsAre(5, 6, 7, 8, 9));
+  EXPECT_TRUE(dq8_temp.empty());
+
+  QuicheCircularDeque<int> dq9({3, 4, 5, 6, 7}, alloc);
+  EXPECT_THAT(dq9, ElementsAre(3, 4, 5, 6, 7));
+}
+
+TEST_F(QuicheCircularDequeTest, Assign) {
+  // assign()
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq;
+  dq.assign(7, 1);
+  EXPECT_THAT(dq, ElementsAre(1, 1, 1, 1, 1, 1, 1));
+  EXPECT_EQ(1u, dq.get_allocator().allocate_count());
+
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq2;
+  dq2.assign(dq.begin(), dq.end());
+  EXPECT_THAT(dq2, ElementsAre(1, 1, 1, 1, 1, 1, 1));
+  EXPECT_EQ(1u, dq2.get_allocator().allocate_count());
+  EXPECT_TRUE(std::equal(dq.begin(), dq.end(), dq2.begin(), dq2.end()));
+
+  dq2.assign({2, 2, 2, 2, 2, 2});
+  EXPECT_THAT(dq2, ElementsAre(2, 2, 2, 2, 2, 2));
+
+  // Assign from a non random access iterator.
+  std::list<int> dq3_src = {3, 3, 3, 3, 3};
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq3;
+  dq3.assign(dq3_src.begin(), dq3_src.end());
+  EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3));
+  EXPECT_LT(1u, dq3.get_allocator().allocate_count());
+
+  // Copy assignment
+  dq3 = *&dq3;
+  EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3));
+
+  QuicheCircularDeque<
+      int, 3,
+      ConfigurableAllocator<int,
+                            /*propagate_on_copy_assignment=*/std::true_type,
+                            /*propagate_on_move_assignment=*/std::true_type,
+                            /*propagate_on_swap=*/std::true_type,
+                            /*equality_result=*/false>>
+      dq4, dq5;
+  dq4.assign(dq3.begin(), dq3.end());
+  dq5 = dq4;
+  EXPECT_THAT(dq5, ElementsAre(3, 3, 3, 3, 3));
+
+  QuicheCircularDeque<
+      int, 3,
+      ConfigurableAllocator<int,
+                            /*propagate_on_copy_assignment=*/std::false_type,
+                            /*propagate_on_move_assignment=*/std::true_type,
+                            /*propagate_on_swap=*/std::true_type,
+                            /*equality_result=*/true>>
+      dq6, dq7;
+  dq6.assign(dq3.begin(), dq3.end());
+  dq7 = dq6;
+  EXPECT_THAT(dq7, ElementsAre(3, 3, 3, 3, 3));
+
+  // Move assignment
+  dq3 = std::move(*&dq3);
+  EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3));
+
+  ASSERT_TRUE(decltype(
+      dq3.get_allocator())::propagate_on_container_move_assignment::value);
+  decltype(dq3) dq8;
+  dq8 = std::move(*&dq3);
+  EXPECT_THAT(dq8, ElementsAre(3, 3, 3, 3, 3));
+  EXPECT_TRUE(dq3.empty());
+
+  QuicheCircularDeque<
+      int, 3,
+      ConfigurableAllocator<int,
+                            /*propagate_on_copy_assignment=*/std::true_type,
+                            /*propagate_on_move_assignment=*/std::false_type,
+                            /*propagate_on_swap=*/std::true_type,
+                            /*equality_result=*/true>>
+      dq9, dq10;
+  dq9.assign(dq8.begin(), dq8.end());
+  dq10.assign(dq2.begin(), dq2.end());
+  dq9 = std::move(*&dq10);
+  EXPECT_THAT(dq9, ElementsAre(2, 2, 2, 2, 2, 2));
+  EXPECT_TRUE(dq10.empty());
+
+  QuicheCircularDeque<
+      int, 3,
+      ConfigurableAllocator<int,
+                            /*propagate_on_copy_assignment=*/std::true_type,
+                            /*propagate_on_move_assignment=*/std::false_type,
+                            /*propagate_on_swap=*/std::true_type,
+                            /*equality_result=*/false>>
+      dq11, dq12;
+  dq11.assign(dq8.begin(), dq8.end());
+  dq12.assign(dq2.begin(), dq2.end());
+  dq11 = std::move(*&dq12);
+  EXPECT_THAT(dq11, ElementsAre(2, 2, 2, 2, 2, 2));
+  EXPECT_TRUE(dq12.empty());
+}
+
+TEST_F(QuicheCircularDequeTest, Access) {
+  // at()
+  // operator[]
+  // front()
+  // back()
+
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq;
+  dq.push_back(10);
+  EXPECT_EQ(dq.front(), 10);
+  EXPECT_EQ(dq.back(), 10);
+  EXPECT_EQ(dq.at(0), 10);
+  EXPECT_EQ(dq[0], 10);
+  dq.front() = 12;
+  EXPECT_EQ(dq.front(), 12);
+  EXPECT_EQ(dq.back(), 12);
+  EXPECT_EQ(dq.at(0), 12);
+  EXPECT_EQ(dq[0], 12);
+
+  const auto& dqref = dq;
+  EXPECT_EQ(dqref.front(), 12);
+  EXPECT_EQ(dqref.back(), 12);
+  EXPECT_EQ(dqref.at(0), 12);
+  EXPECT_EQ(dqref[0], 12);
+
+  dq.pop_front();
+  EXPECT_TRUE(dqref.empty());
+
+  // Push to capacity.
+  dq.push_back(15);
+  dq.push_front(5);
+  dq.push_back(25);
+  EXPECT_EQ(dq.size(), dq.capacity());
+  EXPECT_THAT(dq, ElementsAre(5, 15, 25));
+  EXPECT_LT(&dq.front(), &dq.back());
+  EXPECT_EQ(dq.front(), 5);
+  EXPECT_EQ(dq.back(), 25);
+  EXPECT_EQ(dq.at(0), 5);
+  EXPECT_EQ(dq.at(1), 15);
+  EXPECT_EQ(dq.at(2), 25);
+  EXPECT_EQ(dq[0], 5);
+  EXPECT_EQ(dq[1], 15);
+  EXPECT_EQ(dq[2], 25);
+
+  // Shift right such that begin=1 and end=0. Data is still not wrapped.
+  dq.pop_front();
+  dq.push_back(35);
+  EXPECT_THAT(dq, ElementsAre(15, 25, 35));
+  EXPECT_LT(&dq.front(), &dq.back());
+  EXPECT_EQ(dq.front(), 15);
+  EXPECT_EQ(dq.back(), 35);
+  EXPECT_EQ(dq.at(0), 15);
+  EXPECT_EQ(dq.at(1), 25);
+  EXPECT_EQ(dq.at(2), 35);
+  EXPECT_EQ(dq[0], 15);
+  EXPECT_EQ(dq[1], 25);
+  EXPECT_EQ(dq[2], 35);
+
+  // Shift right such that data is wrapped.
+  dq.pop_front();
+  dq.push_back(45);
+  EXPECT_THAT(dq, ElementsAre(25, 35, 45));
+  EXPECT_GT(&dq.front(), &dq.back());
+  EXPECT_EQ(dq.front(), 25);
+  EXPECT_EQ(dq.back(), 45);
+  EXPECT_EQ(dq.at(0), 25);
+  EXPECT_EQ(dq.at(1), 35);
+  EXPECT_EQ(dq.at(2), 45);
+  EXPECT_EQ(dq[0], 25);
+  EXPECT_EQ(dq[1], 35);
+  EXPECT_EQ(dq[2], 45);
+
+  // Shift right again, data is still wrapped.
+  dq.pop_front();
+  dq.push_back(55);
+  EXPECT_THAT(dq, ElementsAre(35, 45, 55));
+  EXPECT_GT(&dq.front(), &dq.back());
+  EXPECT_EQ(dq.front(), 35);
+  EXPECT_EQ(dq.back(), 55);
+  EXPECT_EQ(dq.at(0), 35);
+  EXPECT_EQ(dq.at(1), 45);
+  EXPECT_EQ(dq.at(2), 55);
+  EXPECT_EQ(dq[0], 35);
+  EXPECT_EQ(dq[1], 45);
+  EXPECT_EQ(dq[2], 55);
+
+  // Shift right one last time. begin returns to 0. Data is no longer wrapped.
+  dq.pop_front();
+  dq.push_back(65);
+  EXPECT_THAT(dq, ElementsAre(45, 55, 65));
+  EXPECT_LT(&dq.front(), &dq.back());
+  EXPECT_EQ(dq.front(), 45);
+  EXPECT_EQ(dq.back(), 65);
+  EXPECT_EQ(dq.at(0), 45);
+  EXPECT_EQ(dq.at(1), 55);
+  EXPECT_EQ(dq.at(2), 65);
+  EXPECT_EQ(dq[0], 45);
+  EXPECT_EQ(dq[1], 55);
+  EXPECT_EQ(dq[2], 65);
+
+  EXPECT_EQ(1u, dq.get_allocator().allocate_count());
+}
+
+TEST_F(QuicheCircularDequeTest, Iterate) {
+  QuicheCircularDeque<int> dq;
+  EXPECT_EQ(dq.begin(), dq.end());
+  EXPECT_EQ(dq.cbegin(), dq.cend());
+  EXPECT_EQ(dq.rbegin(), dq.rend());
+  EXPECT_EQ(dq.crbegin(), dq.crend());
+
+  dq.emplace_back(2);
+  QuicheCircularDeque<int>::const_iterator citer = dq.begin();
+  EXPECT_NE(citer, dq.end());
+  EXPECT_EQ(*citer, 2);
+  ++citer;
+  EXPECT_EQ(citer, dq.end());
+
+  EXPECT_EQ(*dq.begin(), 2);
+  EXPECT_EQ(*dq.cbegin(), 2);
+  EXPECT_EQ(*dq.rbegin(), 2);
+  EXPECT_EQ(*dq.crbegin(), 2);
+
+  dq.emplace_front(1);
+  QuicheCircularDeque<int>::const_reverse_iterator criter = dq.rbegin();
+  EXPECT_NE(criter, dq.rend());
+  EXPECT_EQ(*criter, 2);
+  ++criter;
+  EXPECT_NE(criter, dq.rend());
+  EXPECT_EQ(*criter, 1);
+  ++criter;
+  EXPECT_EQ(criter, dq.rend());
+
+  EXPECT_EQ(*dq.begin(), 1);
+  EXPECT_EQ(*dq.cbegin(), 1);
+  EXPECT_EQ(*dq.rbegin(), 2);
+  EXPECT_EQ(*dq.crbegin(), 2);
+
+  dq.push_back(3);
+
+  // Forward iterate.
+  int expected_value = 1;
+  for (QuicheCircularDeque<int>::iterator it = dq.begin(); it != dq.end();
+       ++it) {
+    EXPECT_EQ(expected_value++, *it);
+  }
+
+  expected_value = 1;
+  for (QuicheCircularDeque<int>::const_iterator it = dq.cbegin();
+       it != dq.cend(); ++it) {
+    EXPECT_EQ(expected_value++, *it);
+  }
+
+  // Reverse iterate.
+  expected_value = 3;
+  for (QuicheCircularDeque<int>::reverse_iterator it = dq.rbegin();
+       it != dq.rend(); ++it) {
+    EXPECT_EQ(expected_value--, *it);
+  }
+
+  expected_value = 3;
+  for (QuicheCircularDeque<int>::const_reverse_iterator it = dq.crbegin();
+       it != dq.crend(); ++it) {
+    EXPECT_EQ(expected_value--, *it);
+  }
+}
+
+TEST_F(QuicheCircularDequeTest, Iterator) {
+  // Default constructed iterators of the same type compare equal.
+  EXPECT_EQ(QuicheCircularDeque<int>::iterator(),
+            QuicheCircularDeque<int>::iterator());
+  EXPECT_EQ(QuicheCircularDeque<int>::const_iterator(),
+            QuicheCircularDeque<int>::const_iterator());
+  EXPECT_EQ(QuicheCircularDeque<int>::reverse_iterator(),
+            QuicheCircularDeque<int>::reverse_iterator());
+  EXPECT_EQ(QuicheCircularDeque<int>::const_reverse_iterator(),
+            QuicheCircularDeque<int>::const_reverse_iterator());
+
+  QuicheCircularDeque<QuicheCircularDeque<int>, 3> dqdq = {
+      {1, 2}, {10, 20, 30}, {100, 200, 300, 400}};
+
+  // iter points to {1, 2}
+  decltype(dqdq)::iterator iter = dqdq.begin();
+  EXPECT_EQ(iter->size(), 2u);
+  EXPECT_THAT(*iter, ElementsAre(1, 2));
+
+  // citer points to {10, 20, 30}
+  decltype(dqdq)::const_iterator citer = dqdq.cbegin() + 1;
+  EXPECT_NE(*iter, *citer);
+  EXPECT_EQ(citer->size(), 3u);
+  int x = 10;
+  for (auto it = citer->begin(); it != citer->end(); ++it) {
+    EXPECT_EQ(*it, x);
+    x += 10;
+  }
+
+  EXPECT_LT(iter, citer);
+  EXPECT_LE(iter, iter);
+  EXPECT_GT(citer, iter);
+  EXPECT_GE(citer, citer);
+
+  // iter points to {100, 200, 300, 400}
+  iter += 2;
+  EXPECT_NE(*iter, *citer);
+  EXPECT_EQ(iter->size(), 4u);
+  for (int i = 1; i <= 4; ++i) {
+    EXPECT_EQ(iter->begin()[i - 1], i * 100);
+  }
+
+  EXPECT_LT(citer, iter);
+  EXPECT_LE(iter, iter);
+  EXPECT_GT(iter, citer);
+  EXPECT_GE(citer, citer);
+
+  // iter points to {10, 20, 30}. (same as citer)
+  iter -= 1;
+  EXPECT_EQ(*iter, *citer);
+  EXPECT_EQ(iter->size(), 3u);
+  x = 10;
+  for (auto it = iter->begin(); it != iter->end();) {
+    EXPECT_EQ(*(it++), x);
+    x += 10;
+  }
+  x = 30;
+  for (auto it = iter->begin() + 2; it != iter->begin();) {
+    EXPECT_EQ(*(it--), x);
+    x -= 10;
+  }
+}
+
+TEST_F(QuicheCircularDequeTest, Resize) {
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq;
+  dq.resize(8);
+  EXPECT_THAT(dq, ElementsAre(0, 0, 0, 0, 0, 0, 0, 0));
+  EXPECT_EQ(1u, dq.get_allocator().allocate_count());
+
+  dq.resize(10, 5);
+  EXPECT_THAT(dq, ElementsAre(0, 0, 0, 0, 0, 0, 0, 0, 5, 5));
+
+  QuicheCircularDeque<int, 3, CountingAllocator<int>> dq2 = dq;
+
+  for (size_t new_size = dq.size(); new_size != 0; --new_size) {
+    dq.resize(new_size);
+    EXPECT_TRUE(
+        std::equal(dq.begin(), dq.end(), dq2.begin(), dq2.begin() + new_size));
+  }
+
+  dq.resize(0);
+  EXPECT_TRUE(dq.empty());
+
+  // Resize when data is wrapped.
+  ASSERT_EQ(dq2.size(), dq2.capacity());
+  while (dq2.size() < dq2.capacity()) {
+    dq2.push_back(5);
+  }
+
+  // Shift left once such that data is wrapped.
+  ASSERT_LT(&dq2.front(), &dq2.back());
+  dq2.pop_back();
+  dq2.push_front(-5);
+  ASSERT_GT(&dq2.front(), &dq2.back());
+
+  EXPECT_EQ(-5, dq2.front());
+  EXPECT_EQ(5, dq2.back());
+  dq2.resize(dq2.size() + 1, 10);
+
+  // Data should be unwrapped after the resize.
+  ASSERT_LT(&dq2.front(), &dq2.back());
+  EXPECT_EQ(-5, dq2.front());
+  EXPECT_EQ(10, dq2.back());
+  EXPECT_EQ(5, *(dq2.rbegin() + 1));
+}
+
+namespace {
+class Foo {
+ public:
+  Foo() : Foo(0xF00) {}
+
+  explicit Foo(int i) : i_(new int(i)) {}
+
+  ~Foo() {
+    if (i_ != nullptr) {
+      delete i_;
+      // Do not set i_ to nullptr such that if the container calls destructor
+      // multiple times, asan can detect it.
+    }
+  }
+
+  Foo(const Foo& other) : i_(new int(*other.i_)) {}
+
+  Foo(Foo&& other) = delete;
+
+  void Set(int i) { *i_ = i; }
+
+  int i() const { return *i_; }
+
+  friend bool operator==(const Foo& lhs, const Foo& rhs) {
+    return lhs.i() == rhs.i();
+  }
+
+  friend std::ostream& operator<<(std::ostream& os, const Foo& foo) {
+    return os << "Foo(" << foo.i() << ")";
+  }
+
+ private:
+  // By pointing i_ to a dynamically allocated integer, a memory leak will be
+  // reported if the container forget to properly destruct this object.
+  int* i_ = nullptr;
+};
+}  // namespace
+
+TEST_F(QuicheCircularDequeTest, RelocateNonTriviallyCopyable) {
+  // When relocating non-trivially-copyable objects:
+  // - Move constructor is preferred, if available.
+  // - Copy constructor is used otherwise.
+
+  {
+    // Move construct in Relocate.
+    using MoveConstructible = std::unique_ptr<Foo>;
+    ASSERT_FALSE(std::is_trivially_copyable<MoveConstructible>::value);
+    ASSERT_TRUE(std::is_move_constructible<MoveConstructible>::value);
+    QuicheCircularDeque<MoveConstructible, 3,
+                        CountingAllocator<MoveConstructible>>
+        dq1;
+    dq1.resize(3);
+    EXPECT_EQ(dq1.size(), dq1.capacity());
+    EXPECT_EQ(1u, dq1.get_allocator().allocate_count());
+
+    dq1.emplace_back(new Foo(0xF1));  // Cause existing elements to relocate.
+    EXPECT_EQ(4u, dq1.size());
+    EXPECT_EQ(2u, dq1.get_allocator().allocate_count());
+    EXPECT_EQ(dq1[0], nullptr);
+    EXPECT_EQ(dq1[1], nullptr);
+    EXPECT_EQ(dq1[2], nullptr);
+    EXPECT_EQ(dq1[3]->i(), 0xF1);
+  }
+
+  {
+    // Copy construct in Relocate.
+    using NonMoveConstructible = Foo;
+    ASSERT_FALSE(std::is_trivially_copyable<NonMoveConstructible>::value);
+    ASSERT_FALSE(std::is_move_constructible<NonMoveConstructible>::value);
+    QuicheCircularDeque<NonMoveConstructible, 3,
+                        CountingAllocator<NonMoveConstructible>>
+        dq2;
+    dq2.resize(3);
+    EXPECT_EQ(dq2.size(), dq2.capacity());
+    EXPECT_EQ(1u, dq2.get_allocator().allocate_count());
+
+    dq2.emplace_back(0xF1);  // Cause existing elements to relocate.
+    EXPECT_EQ(4u, dq2.size());
+    EXPECT_EQ(2u, dq2.get_allocator().allocate_count());
+    EXPECT_EQ(dq2[0].i(), 0xF00);
+    EXPECT_EQ(dq2[1].i(), 0xF00);
+    EXPECT_EQ(dq2[2].i(), 0xF00);
+    EXPECT_EQ(dq2[3].i(), 0xF1);
+  }
+}
+
+TEST_F(QuicheCircularDequeTest, PushPop) {
+  // (push|pop|emplace)_(back|front)
+
+  {
+    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq(4);
+    for (size_t i = 0; i < dq.size(); ++i) {
+      dq[i].Set(i + 1);
+    }
+    QUICHE_LOG(INFO) << "dq initialized to " << dq;
+    EXPECT_THAT(dq, ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4)));
+
+    ShiftLeft(&dq, false);
+    QUICHE_LOG(INFO) << "shift left once : " << dq;
+    EXPECT_THAT(dq, ElementsAre(Foo(2), Foo(3), Foo(4), Foo(1)));
+
+    ShiftLeft(&dq, true);
+    QUICHE_LOG(INFO) << "shift left twice: " << dq;
+    EXPECT_THAT(dq, ElementsAre(Foo(3), Foo(4), Foo(1), Foo(2)));
+    ASSERT_GT(&dq.front(), &dq.back());
+    // dq destructs with wrapped data.
+  }
+
+  {
+    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq1(4);
+    for (size_t i = 0; i < dq1.size(); ++i) {
+      dq1[i].Set(i + 1);
+    }
+    QUICHE_LOG(INFO) << "dq1 initialized to " << dq1;
+    EXPECT_THAT(dq1, ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4)));
+
+    ShiftRight(&dq1, false);
+    QUICHE_LOG(INFO) << "shift right once : " << dq1;
+    EXPECT_THAT(dq1, ElementsAre(Foo(4), Foo(1), Foo(2), Foo(3)));
+
+    ShiftRight(&dq1, true);
+    QUICHE_LOG(INFO) << "shift right twice: " << dq1;
+    EXPECT_THAT(dq1, ElementsAre(Foo(3), Foo(4), Foo(1), Foo(2)));
+    ASSERT_GT(&dq1.front(), &dq1.back());
+    // dq1 destructs with wrapped data.
+  }
+
+  {  // Pop n elements from front.
+    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq2(5);
+    for (size_t i = 0; i < dq2.size(); ++i) {
+      dq2[i].Set(i + 1);
+    }
+    EXPECT_THAT(dq2, ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)));
+
+    EXPECT_EQ(2u, dq2.pop_front_n(2));
+    EXPECT_THAT(dq2, ElementsAre(Foo(3), Foo(4), Foo(5)));
+
+    EXPECT_EQ(3u, dq2.pop_front_n(100));
+    EXPECT_TRUE(dq2.empty());
+  }
+
+  {  // Pop n elements from back.
+    QuicheCircularDeque<Foo, 4, CountingAllocator<Foo>> dq3(6);
+    for (size_t i = 0; i < dq3.size(); ++i) {
+      dq3[i].Set(i + 1);
+    }
+    EXPECT_THAT(dq3,
+                ElementsAre(Foo(1), Foo(2), Foo(3), Foo(4), Foo(5), Foo(6)));
+
+    ShiftRight(&dq3, true);
+    ShiftRight(&dq3, true);
+    ShiftRight(&dq3, true);
+    EXPECT_THAT(dq3,
+                ElementsAre(Foo(4), Foo(5), Foo(6), Foo(1), Foo(2), Foo(3)));
+
+    EXPECT_EQ(2u, dq3.pop_back_n(2));
+    EXPECT_THAT(dq3, ElementsAre(Foo(4), Foo(5), Foo(6), Foo(1)));
+
+    EXPECT_EQ(2u, dq3.pop_back_n(2));
+    EXPECT_THAT(dq3, ElementsAre(Foo(4), Foo(5)));
+  }
+}
+
+TEST_F(QuicheCircularDequeTest, Allocation) {
+  CountingAllocator<int> alloc;
+
+  {
+    QuicheCircularDeque<int, 3, CountingAllocator<int>> dq(alloc);
+    EXPECT_EQ(alloc, dq.get_allocator());
+    EXPECT_EQ(0u, dq.size());
+    EXPECT_EQ(0u, dq.capacity());
+    EXPECT_EQ(0u, alloc.allocate_count());
+    EXPECT_EQ(0u, alloc.deallocate_count());
+
+    for (int i = 1; i <= 18; ++i) {
+      SCOPED_TRACE(testing::Message()
+                   << "i=" << i << ", capacity_b4_push=" << dq.capacity());
+      dq.push_back(i);
+      EXPECT_EQ(i, static_cast<int>(dq.size()));
+
+      const size_t capacity = 3 + (i - 1) / 3 * 3;
+      EXPECT_EQ(capacity, dq.capacity());
+      EXPECT_EQ(capacity / 3, alloc.allocate_count());
+      EXPECT_EQ(capacity / 3 - 1, alloc.deallocate_count());
+    }
+
+    dq.push_back(19);
+    EXPECT_EQ(22u, dq.capacity());  // 18 + 18 / 4
+    EXPECT_EQ(7u, alloc.allocate_count());
+    EXPECT_EQ(6u, alloc.deallocate_count());
+  }
+
+  EXPECT_EQ(7u, alloc.deallocate_count());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
+
+// Use a non-quiche namespace to make sure swap can be used via ADL.
+namespace {
+
+template <typename T>
+using SwappableAllocator = quiche::test::ConfigurableAllocator<
+    T,
+    /*propagate_on_copy_assignment=*/std::true_type,
+    /*propagate_on_move_assignment=*/std::true_type,
+    /*propagate_on_swap=*/std::true_type,
+    /*equality_result=*/true>;
+
+template <typename T>
+using UnswappableEqualAllocator = quiche::test::ConfigurableAllocator<
+    T,
+    /*propagate_on_copy_assignment=*/std::true_type,
+    /*propagate_on_move_assignment=*/std::true_type,
+    /*propagate_on_swap=*/std::false_type,
+    /*equality_result=*/true>;
+
+template <typename T>
+using UnswappableUnequalAllocator = quiche::test::ConfigurableAllocator<
+    T,
+    /*propagate_on_copy_assignment=*/std::true_type,
+    /*propagate_on_move_assignment=*/std::true_type,
+    /*propagate_on_swap=*/std::false_type,
+    /*equality_result=*/false>;
+
+using quiche::test::QuicheCircularDequeTest;
+
+TEST_F(QuicheCircularDequeTest, Swap) {
+  using std::swap;
+
+  quiche::QuicheCircularDeque<int64_t, 3, SwappableAllocator<int64_t>> dq1, dq2;
+  dq1.push_back(10);
+  dq1.push_back(11);
+  dq2.push_back(20);
+  swap(dq1, dq2);
+  EXPECT_THAT(dq1, ElementsAre(20));
+  EXPECT_THAT(dq2, ElementsAre(10, 11));
+
+  quiche::QuicheCircularDeque<char, 3, UnswappableEqualAllocator<char>> dq3,
+      dq4;
+  dq3 = {1, 2, 3, 4, 5};
+  dq4 = {6, 7, 8, 9, 0};
+  swap(dq3, dq4);
+  EXPECT_THAT(dq3, ElementsAre(6, 7, 8, 9, 0));
+  EXPECT_THAT(dq4, ElementsAre(1, 2, 3, 4, 5));
+
+  quiche::QuicheCircularDeque<int, 3, UnswappableUnequalAllocator<int>> dq5,
+      dq6;
+  dq6.push_front(4);
+
+  // Using UnswappableUnequalAllocator is ok as long as swap is not called.
+  dq5.assign(dq6.begin(), dq6.end());
+  EXPECT_THAT(dq5, ElementsAre(4));
+
+  // Undefined behavior to swap between two containers with unequal allocators.
+  EXPECT_QUICHE_DEBUG_DEATH(swap(dq5, dq6), "Undefined swap behavior");
+}
+}  // namespace
diff --git a/quiche/common/quiche_data_reader.cc b/quiche/common/quiche_data_reader.cc
new file mode 100644
index 0000000..7724c6f
--- /dev/null
+++ b/quiche/common/quiche_data_reader.cc
@@ -0,0 +1,231 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_data_reader.h"
+
+#include <cstring>
+
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quiche {
+
+QuicheDataReader::QuicheDataReader(absl::string_view data)
+    : QuicheDataReader(data.data(), data.length(), quiche::NETWORK_BYTE_ORDER) {
+}
+
+QuicheDataReader::QuicheDataReader(const char* data, const size_t len)
+    : QuicheDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
+
+QuicheDataReader::QuicheDataReader(const char* data,
+                                   const size_t len,
+                                   quiche::Endianness endianness)
+    : data_(data), len_(len), pos_(0), endianness_(endianness) {}
+
+bool QuicheDataReader::ReadUInt8(uint8_t* result) {
+  return ReadBytes(result, sizeof(*result));
+}
+
+bool QuicheDataReader::ReadUInt16(uint16_t* result) {
+  if (!ReadBytes(result, sizeof(*result))) {
+    return false;
+  }
+  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
+    *result = quiche::QuicheEndian::NetToHost16(*result);
+  }
+  return true;
+}
+
+bool QuicheDataReader::ReadUInt24(uint32_t* result) {
+  if (endianness_ != quiche::NETWORK_BYTE_ORDER) {
+    // TODO(b/214573190): Implement and test HOST_BYTE_ORDER case.
+    QUICHE_BUG(QuicheDataReader_ReadUInt24_NotImplemented);
+    return false;
+  }
+
+  *result = 0;
+  if (!ReadBytes(reinterpret_cast<char*>(result) + 1, 3u)) {
+    return false;
+  }
+  *result = quiche::QuicheEndian::NetToHost32(*result);
+  return true;
+}
+
+bool QuicheDataReader::ReadUInt32(uint32_t* result) {
+  if (!ReadBytes(result, sizeof(*result))) {
+    return false;
+  }
+  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
+    *result = quiche::QuicheEndian::NetToHost32(*result);
+  }
+  return true;
+}
+
+bool QuicheDataReader::ReadUInt64(uint64_t* result) {
+  if (!ReadBytes(result, sizeof(*result))) {
+    return false;
+  }
+  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
+    *result = quiche::QuicheEndian::NetToHost64(*result);
+  }
+  return true;
+}
+
+bool QuicheDataReader::ReadBytesToUInt64(size_t num_bytes, uint64_t* result) {
+  *result = 0u;
+  if (num_bytes > sizeof(*result)) {
+    return false;
+  }
+  if (endianness_ == quiche::HOST_BYTE_ORDER) {
+    return ReadBytes(result, num_bytes);
+  }
+
+  if (!ReadBytes(reinterpret_cast<char*>(result) + sizeof(*result) - num_bytes,
+                 num_bytes)) {
+    return false;
+  }
+  *result = quiche::QuicheEndian::NetToHost64(*result);
+  return true;
+}
+
+bool QuicheDataReader::ReadStringPiece16(absl::string_view* result) {
+  // Read resultant length.
+  uint16_t result_len;
+  if (!ReadUInt16(&result_len)) {
+    // OnFailure() already called.
+    return false;
+  }
+
+  return ReadStringPiece(result, result_len);
+}
+
+bool QuicheDataReader::ReadStringPiece8(absl::string_view* result) {
+  // Read resultant length.
+  uint8_t result_len;
+  if (!ReadUInt8(&result_len)) {
+    // OnFailure() already called.
+    return false;
+  }
+
+  return ReadStringPiece(result, result_len);
+}
+
+bool QuicheDataReader::ReadStringPiece(absl::string_view* result, size_t size) {
+  // Make sure that we have enough data to read.
+  if (!CanRead(size)) {
+    OnFailure();
+    return false;
+  }
+
+  // Set result.
+  *result = absl::string_view(data_ + pos_, size);
+
+  // Iterate.
+  pos_ += size;
+
+  return true;
+}
+
+bool QuicheDataReader::ReadTag(uint32_t* tag) {
+  return ReadBytes(tag, sizeof(*tag));
+}
+
+bool QuicheDataReader::ReadDecimal64(size_t num_digits, uint64_t* result) {
+  absl::string_view digits;
+  if (!ReadStringPiece(&digits, num_digits)) {
+    return false;
+  }
+
+  return absl::SimpleAtoi(digits, result);
+}
+
+absl::string_view QuicheDataReader::ReadRemainingPayload() {
+  absl::string_view payload = PeekRemainingPayload();
+  pos_ = len_;
+  return payload;
+}
+
+absl::string_view QuicheDataReader::PeekRemainingPayload() const {
+  return absl::string_view(data_ + pos_, len_ - pos_);
+}
+
+absl::string_view QuicheDataReader::FullPayload() const {
+  return absl::string_view(data_, len_);
+}
+
+absl::string_view QuicheDataReader::PreviouslyReadPayload() const {
+  return absl::string_view(data_, pos_);
+}
+
+bool QuicheDataReader::ReadBytes(void* result, size_t size) {
+  // Make sure that we have enough data to read.
+  if (!CanRead(size)) {
+    OnFailure();
+    return false;
+  }
+
+  // Read into result.
+  memcpy(result, data_ + pos_, size);
+
+  // Iterate.
+  pos_ += size;
+
+  return true;
+}
+
+bool QuicheDataReader::Seek(size_t size) {
+  if (!CanRead(size)) {
+    OnFailure();
+    return false;
+  }
+  pos_ += size;
+  return true;
+}
+
+bool QuicheDataReader::IsDoneReading() const {
+  return len_ == pos_;
+}
+
+size_t QuicheDataReader::BytesRemaining() const {
+  return len_ - pos_;
+}
+
+bool QuicheDataReader::TruncateRemaining(size_t truncation_length) {
+  if (truncation_length > BytesRemaining()) {
+    return false;
+  }
+  len_ = pos_ + truncation_length;
+  return true;
+}
+
+bool QuicheDataReader::CanRead(size_t bytes) const {
+  return bytes <= (len_ - pos_);
+}
+
+void QuicheDataReader::OnFailure() {
+  // Set our iterator to the end of the buffer so that further reads fail
+  // immediately.
+  pos_ = len_;
+}
+
+uint8_t QuicheDataReader::PeekByte() const {
+  if (pos_ >= len_) {
+    QUICHE_LOG(FATAL)
+        << "Reading is done, cannot peek next byte. Tried to read pos = "
+        << pos_ << " buffer length = " << len_;
+    return 0;
+  }
+  return data_[pos_];
+}
+
+std::string QuicheDataReader::DebugString() const {
+  return absl::StrCat(" { length: ", len_, ", position: ", pos_, " }");
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quiche
diff --git a/quiche/common/quiche_data_reader.h b/quiche/common/quiche_data_reader.h
new file mode 100644
index 0000000..67ca7b2
--- /dev/null
+++ b/quiche/common/quiche_data_reader.h
@@ -0,0 +1,198 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_DATA_READER_H_
+#define QUICHE_COMMON_QUICHE_DATA_READER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quiche {
+
+// To use, simply construct a QuicheDataReader using the underlying buffer that
+// you'd like to read fields from, then call one of the Read*() methods to
+// actually do some reading.
+//
+// This class keeps an internal iterator to keep track of what's already been
+// read and each successive Read*() call automatically increments said iterator
+// on success. On failure, internal state of the QuicheDataReader should not be
+// trusted and it is up to the caller to throw away the failed instance and
+// handle the error as appropriate. None of the Read*() methods should ever be
+// called after failure, as they will also fail immediately.
+class QUICHE_EXPORT_PRIVATE QuicheDataReader {
+ public:
+  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
+  // Caller must provide an underlying buffer to work on.
+  explicit QuicheDataReader(absl::string_view data);
+  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
+  // Caller must provide an underlying buffer to work on.
+  QuicheDataReader(const char* data, const size_t len);
+  // Constructs a reader using the specified endianness.
+  // Caller must provide an underlying buffer to work on.
+  QuicheDataReader(const char* data,
+                   const size_t len,
+                   quiche::Endianness endianness);
+  QuicheDataReader(const QuicheDataReader&) = delete;
+  QuicheDataReader& operator=(const QuicheDataReader&) = delete;
+
+  // Empty destructor.
+  ~QuicheDataReader() {}
+
+  // Reads an 8/16/24/32/64-bit unsigned integer into the given output
+  // parameter. Forwards the internal iterator on success. Returns true on
+  // success, false otherwise.
+  bool ReadUInt8(uint8_t* result);
+  bool ReadUInt16(uint16_t* result);
+  bool ReadUInt24(uint32_t* result);
+  bool ReadUInt32(uint32_t* result);
+  bool ReadUInt64(uint64_t* result);
+
+  // Set |result| to 0, then read |num_bytes| bytes in the correct byte order
+  // into least significant bytes of |result|.
+  bool ReadBytesToUInt64(size_t num_bytes, uint64_t* result);
+
+  // Reads a string prefixed with 16-bit length into the given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPiece16(absl::string_view* result);
+
+  // Reads a string prefixed with 8-bit length into the given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPiece8(absl::string_view* result);
+
+  // Reads a given number of bytes into the given buffer. The buffer
+  // must be of adequate size.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPiece(absl::string_view* result, size_t size);
+
+  // Reads tag represented as 32-bit unsigned integer into given output
+  // parameter. Tags are in big endian on the wire (e.g., CHLO is
+  // 'C','H','L','O') and are read in byte order, so tags in memory are in big
+  // endian.
+  bool ReadTag(uint32_t* tag);
+
+  // Reads a sequence of a fixed number of decimal digits, parses them as an
+  // unsigned integer and returns them as a uint64_t.  Forwards internal
+  // iterator on success, may forward it even in case of failure.
+  bool ReadDecimal64(size_t num_digits, uint64_t* result);
+
+  // Returns the remaining payload as a absl::string_view.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterator.
+  absl::string_view ReadRemainingPayload();
+
+  // Returns the remaining payload as a absl::string_view.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // DOES NOT forward the internal iterator.
+  absl::string_view PeekRemainingPayload() const;
+
+  // Returns the entire payload as a absl::string_view.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // DOES NOT forward the internal iterator.
+  absl::string_view FullPayload() const;
+
+  // Returns the part of the payload that has been already read as a
+  // absl::string_view.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // DOES NOT forward the internal iterator.
+  absl::string_view PreviouslyReadPayload() const;
+
+  // Reads a given number of bytes into the given buffer. The buffer
+  // must be of adequate size.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadBytes(void* result, size_t size);
+
+  // Skips over |size| bytes from the buffer and forwards the internal iterator.
+  // Returns true if there are at least |size| bytes remaining to read, false
+  // otherwise.
+  bool Seek(size_t size);
+
+  // Returns true if the entirety of the underlying buffer has been read via
+  // Read*() calls.
+  bool IsDoneReading() const;
+
+  // Returns the number of bytes remaining to be read.
+  size_t BytesRemaining() const;
+
+  // Truncates the reader down by reducing its internal length.
+  // If called immediately after calling this, BytesRemaining will
+  // return |truncation_length|. If truncation_length is less than the
+  // current value of BytesRemaining, this does nothing and returns false.
+  bool TruncateRemaining(size_t truncation_length);
+
+  // Returns the next byte that to be read. Must not be called when there are no
+  // bytes to be read.
+  //
+  // DOES NOT forward the internal iterator.
+  uint8_t PeekByte() const;
+
+  std::string DebugString() const;
+
+ protected:
+  // Returns true if the underlying buffer has enough room to read the given
+  // amount of bytes.
+  bool CanRead(size_t bytes) const;
+
+  // To be called when a read fails for any reason.
+  void OnFailure();
+
+  const char* data() const { return data_; }
+
+  size_t pos() const { return pos_; }
+
+  void AdvancePos(size_t amount) {
+    QUICHE_DCHECK_LE(pos_, std::numeric_limits<size_t>::max() - amount);
+    QUICHE_DCHECK_LE(pos_, len_ - amount);
+    pos_ += amount;
+  }
+
+  quiche::Endianness endianness() const { return endianness_; }
+
+ private:
+  // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
+  // char. The data buffer that we're reading from.
+  const char* data_;
+
+  // The length of the data buffer that we're reading from.
+  size_t len_;
+
+  // The location of the next read from our data buffer.
+  size_t pos_;
+
+  // The endianness to read integers and floating numbers.
+  quiche::Endianness endianness_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_DATA_READER_H_
diff --git a/quiche/common/quiche_data_reader_test.cc b/quiche/common/quiche_data_reader_test.cc
new file mode 100644
index 0000000..d65dd88
--- /dev/null
+++ b/quiche/common/quiche_data_reader_test.cc
@@ -0,0 +1,187 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_data_reader.h"
+
+#include <cstdint>
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quiche {
+
+// TODO(b/214573190): Test Endianness::HOST_BYTE_ORDER.
+// TODO(b/214573190): Test ReadUInt8, ReadUInt24, ReadUInt64, ReadBytesToUInt64,
+// ReadStringPiece8, ReadStringPiece, ReadTag, etc.
+
+TEST(QuicheDataReaderTest, ReadUInt16) {
+  // Data in network byte order.
+  const uint16_t kData[] = {
+      QuicheEndian::HostToNet16(1),
+      QuicheEndian::HostToNet16(1 << 15),
+  };
+
+  QuicheDataReader reader(reinterpret_cast<const char*>(kData), sizeof(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  uint16_t uint16_val;
+  EXPECT_TRUE(reader.ReadUInt16(&uint16_val));
+  EXPECT_FALSE(reader.IsDoneReading());
+  EXPECT_EQ(1, uint16_val);
+
+  EXPECT_TRUE(reader.ReadUInt16(&uint16_val));
+  EXPECT_TRUE(reader.IsDoneReading());
+  EXPECT_EQ(1 << 15, uint16_val);
+}
+
+TEST(QuicheDataReaderTest, ReadUInt32) {
+  // Data in network byte order.
+  const uint32_t kData[] = {
+      QuicheEndian::HostToNet32(1),
+      QuicheEndian::HostToNet32(0x80000000),
+  };
+
+  QuicheDataReader reader(reinterpret_cast<const char*>(kData),
+                          ABSL_ARRAYSIZE(kData) * sizeof(uint32_t));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  uint32_t uint32_val;
+  EXPECT_TRUE(reader.ReadUInt32(&uint32_val));
+  EXPECT_FALSE(reader.IsDoneReading());
+  EXPECT_EQ(1u, uint32_val);
+
+  EXPECT_TRUE(reader.ReadUInt32(&uint32_val));
+  EXPECT_TRUE(reader.IsDoneReading());
+  EXPECT_EQ(1u << 31, uint32_val);
+}
+
+TEST(QuicheDataReaderTest, ReadStringPiece16) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x00, 0x02,  // uint16_t(2)
+      0x48, 0x69,  // "Hi"
+      0x00, 0x10,  // uint16_t(16)
+      0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2c,
+      0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33,  // "Testing, 1, 2, 3"
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  absl::string_view stringpiece_val;
+  EXPECT_TRUE(reader.ReadStringPiece16(&stringpiece_val));
+  EXPECT_FALSE(reader.IsDoneReading());
+  EXPECT_EQ(0, stringpiece_val.compare("Hi"));
+
+  EXPECT_TRUE(reader.ReadStringPiece16(&stringpiece_val));
+  EXPECT_TRUE(reader.IsDoneReading());
+  EXPECT_EQ(0, stringpiece_val.compare("Testing, 1, 2, 3"));
+}
+
+TEST(QuicheDataReaderTest, ReadUInt16WithBufferTooSmall) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x00,  // part of a uint16_t
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  uint16_t uint16_val;
+  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
+}
+
+TEST(QuicheDataReaderTest, ReadUInt32WithBufferTooSmall) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x00, 0x00, 0x00,  // part of a uint32_t
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  uint32_t uint32_val;
+  EXPECT_FALSE(reader.ReadUInt32(&uint32_val));
+
+  // Also make sure that trying to read a uint16_t, which technically could
+  // work, fails immediately due to previously encountered failed read.
+  uint16_t uint16_val;
+  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
+}
+
+// Tests ReadStringPiece16() with a buffer too small to fit the entire string.
+TEST(QuicheDataReaderTest, ReadStringPiece16WithBufferTooSmall) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x00, 0x03,  // uint16_t(3)
+      0x48, 0x69,  // "Hi"
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  absl::string_view stringpiece_val;
+  EXPECT_FALSE(reader.ReadStringPiece16(&stringpiece_val));
+
+  // Also make sure that trying to read a uint16_t, which technically could
+  // work, fails immediately due to previously encountered failed read.
+  uint16_t uint16_val;
+  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
+}
+
+// Tests ReadStringPiece16() with a buffer too small even to fit the length.
+TEST(QuicheDataReaderTest, ReadStringPiece16WithBufferWayTooSmall) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x00,  // part of a uint16_t
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  absl::string_view stringpiece_val;
+  EXPECT_FALSE(reader.ReadStringPiece16(&stringpiece_val));
+
+  // Also make sure that trying to read a uint16_t, which technically could
+  // work, fails immediately due to previously encountered failed read.
+  uint16_t uint16_val;
+  EXPECT_FALSE(reader.ReadUInt16(&uint16_val));
+}
+
+TEST(QuicheDataReaderTest, ReadBytes) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x66, 0x6f, 0x6f,  // "foo"
+      0x48, 0x69,        // "Hi"
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  char dest1[3] = {};
+  EXPECT_TRUE(reader.ReadBytes(&dest1, ABSL_ARRAYSIZE(dest1)));
+  EXPECT_FALSE(reader.IsDoneReading());
+  EXPECT_EQ("foo", absl::string_view(dest1, ABSL_ARRAYSIZE(dest1)));
+
+  char dest2[2] = {};
+  EXPECT_TRUE(reader.ReadBytes(&dest2, ABSL_ARRAYSIZE(dest2)));
+  EXPECT_TRUE(reader.IsDoneReading());
+  EXPECT_EQ("Hi", absl::string_view(dest2, ABSL_ARRAYSIZE(dest2)));
+}
+
+TEST(QuicheDataReaderTest, ReadBytesWithBufferTooSmall) {
+  // Data in network byte order.
+  const char kData[] = {
+      0x01,
+  };
+
+  QuicheDataReader reader(kData, ABSL_ARRAYSIZE(kData));
+  EXPECT_FALSE(reader.IsDoneReading());
+
+  char dest[ABSL_ARRAYSIZE(kData) + 2] = {};
+  EXPECT_FALSE(reader.ReadBytes(&dest, ABSL_ARRAYSIZE(kData) + 1));
+  EXPECT_STREQ("", dest);
+}
+
+}  // namespace quiche
diff --git a/quiche/common/quiche_data_writer.cc b/quiche/common/quiche_data_writer.cc
new file mode 100644
index 0000000..d75ceae
--- /dev/null
+++ b/quiche/common/quiche_data_writer.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_data_writer.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quiche {
+
+QuicheDataWriter::QuicheDataWriter(size_t size, char* buffer)
+    : QuicheDataWriter(size, buffer, quiche::NETWORK_BYTE_ORDER) {}
+
+QuicheDataWriter::QuicheDataWriter(size_t size,
+                                   char* buffer,
+                                   quiche::Endianness endianness)
+    : buffer_(buffer), capacity_(size), length_(0), endianness_(endianness) {}
+
+QuicheDataWriter::~QuicheDataWriter() {}
+
+char* QuicheDataWriter::data() {
+  return buffer_;
+}
+
+bool QuicheDataWriter::WriteUInt8(uint8_t value) {
+  return WriteBytes(&value, sizeof(value));
+}
+
+bool QuicheDataWriter::WriteUInt16(uint16_t value) {
+  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
+    value = quiche::QuicheEndian::HostToNet16(value);
+  }
+  return WriteBytes(&value, sizeof(value));
+}
+
+bool QuicheDataWriter::WriteUInt32(uint32_t value) {
+  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
+    value = quiche::QuicheEndian::HostToNet32(value);
+  }
+  return WriteBytes(&value, sizeof(value));
+}
+
+bool QuicheDataWriter::WriteUInt64(uint64_t value) {
+  if (endianness_ == quiche::NETWORK_BYTE_ORDER) {
+    value = quiche::QuicheEndian::HostToNet64(value);
+  }
+  return WriteBytes(&value, sizeof(value));
+}
+
+bool QuicheDataWriter::WriteBytesToUInt64(size_t num_bytes, uint64_t value) {
+  if (num_bytes > sizeof(value)) {
+    return false;
+  }
+  if (endianness_ == quiche::HOST_BYTE_ORDER) {
+    return WriteBytes(&value, num_bytes);
+  }
+
+  value = quiche::QuicheEndian::HostToNet64(value);
+  return WriteBytes(reinterpret_cast<char*>(&value) + sizeof(value) - num_bytes,
+                    num_bytes);
+}
+
+bool QuicheDataWriter::WriteStringPiece16(absl::string_view val) {
+  if (val.size() > std::numeric_limits<uint16_t>::max()) {
+    return false;
+  }
+  if (!WriteUInt16(static_cast<uint16_t>(val.size()))) {
+    return false;
+  }
+  return WriteBytes(val.data(), val.size());
+}
+
+bool QuicheDataWriter::WriteStringPiece(absl::string_view val) {
+  return WriteBytes(val.data(), val.size());
+}
+
+char* QuicheDataWriter::BeginWrite(size_t length) {
+  if (length_ > capacity_) {
+    return nullptr;
+  }
+
+  if (capacity_ - length_ < length) {
+    return nullptr;
+  }
+
+#ifdef ARCH_CPU_64_BITS
+  QUICHE_DCHECK_LE(length, std::numeric_limits<uint32_t>::max());
+#endif
+
+  return buffer_ + length_;
+}
+
+bool QuicheDataWriter::WriteBytes(const void* data, size_t data_len) {
+  char* dest = BeginWrite(data_len);
+  if (!dest) {
+    return false;
+  }
+
+  memcpy(dest, data, data_len);
+
+  length_ += data_len;
+  return true;
+}
+
+bool QuicheDataWriter::WriteRepeatedByte(uint8_t byte, size_t count) {
+  char* dest = BeginWrite(count);
+  if (!dest) {
+    return false;
+  }
+
+  memset(dest, byte, count);
+
+  length_ += count;
+  return true;
+}
+
+void QuicheDataWriter::WritePadding() {
+  QUICHE_DCHECK_LE(length_, capacity_);
+  if (length_ > capacity_) {
+    return;
+  }
+  memset(buffer_ + length_, 0x00, capacity_ - length_);
+  length_ = capacity_;
+}
+
+bool QuicheDataWriter::WritePaddingBytes(size_t count) {
+  return WriteRepeatedByte(0x00, count);
+}
+
+bool QuicheDataWriter::WriteTag(uint32_t tag) {
+  return WriteBytes(&tag, sizeof(tag));
+}
+
+bool QuicheDataWriter::Seek(size_t length) {
+  if (!BeginWrite(length)) {
+    return false;
+  }
+  length_ += length;
+  return true;
+}
+
+std::string QuicheDataWriter::DebugString() const {
+  return absl::StrCat(" { capacity: ", capacity_, ", length: ", length_, " }");
+}
+
+}  // namespace quiche
diff --git a/quiche/common/quiche_data_writer.h b/quiche/common/quiche_data_writer.h
new file mode 100644
index 0000000..5f027a9
--- /dev/null
+++ b/quiche/common/quiche_data_writer.h
@@ -0,0 +1,112 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_DATA_WRITER_H_
+#define QUICHE_COMMON_QUICHE_DATA_WRITER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quiche {
+
+// This class provides facilities for packing binary data.
+//
+// The QuicheDataWriter supports appending primitive values (int, string, etc)
+// to a frame instance.  The internal memory buffer is exposed as the "data"
+// of the QuicheDataWriter.
+class QUICHE_EXPORT_PRIVATE QuicheDataWriter {
+ public:
+  // Creates a QuicheDataWriter where |buffer| is not owned
+  // using NETWORK_BYTE_ORDER endianness.
+  QuicheDataWriter(size_t size, char* buffer);
+  // Creates a QuicheDataWriter where |buffer| is not owned
+  // using the specified endianness.
+  QuicheDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
+  QuicheDataWriter(const QuicheDataWriter&) = delete;
+  QuicheDataWriter& operator=(const QuicheDataWriter&) = delete;
+
+  ~QuicheDataWriter();
+
+  // Returns the size of the QuicheDataWriter's data.
+  size_t length() const { return length_; }
+
+  // Retrieves the buffer from the QuicheDataWriter without changing ownership.
+  char* data();
+
+  // Methods for adding to the payload.  These values are appended to the end
+  // of the QuicheDataWriter payload.
+
+  // Writes 8/16/32/64-bit unsigned integers.
+  bool WriteUInt8(uint8_t value);
+  bool WriteUInt16(uint16_t value);
+  bool WriteUInt32(uint32_t value);
+  bool WriteUInt64(uint64_t value);
+
+  // Writes least significant |num_bytes| of a 64-bit unsigned integer in the
+  // correct byte order.
+  bool WriteBytesToUInt64(size_t num_bytes, uint64_t value);
+
+  bool WriteStringPiece(absl::string_view val);
+  bool WriteStringPiece16(absl::string_view val);
+  bool WriteBytes(const void* data, size_t data_len);
+  bool WriteRepeatedByte(uint8_t byte, size_t count);
+  // Fills the remaining buffer with null characters.
+  void WritePadding();
+  // Write padding of |count| bytes.
+  bool WritePaddingBytes(size_t count);
+
+  // Write tag as a 32-bit unsigned integer to the payload. As tags are already
+  // converted to big endian (e.g., CHLO is 'C','H','L','O') in memory by TAG or
+  // MakeQuicTag and tags are written in byte order, so tags on the wire are
+  // in big endian.
+  bool WriteTag(uint32_t tag);
+
+  // Advance the writer's position for writing by |length| bytes without writing
+  // anything. This method only makes sense to be used on a buffer that has
+  // already been written to (and is having certain parts rewritten).
+  bool Seek(size_t length);
+
+  size_t capacity() const { return capacity_; }
+
+  size_t remaining() const { return capacity_ - length_; }
+
+  std::string DebugString() const;
+
+ protected:
+  // Returns the location that the data should be written at, or nullptr if
+  // there is not enough room. Call EndWrite with the returned offset and the
+  // given length to pad out for the next write.
+  char* BeginWrite(size_t length);
+
+  quiche::Endianness endianness() const { return endianness_; }
+
+  char* buffer() const { return buffer_; }
+
+  void IncreaseLength(size_t delta) {
+    QUICHE_DCHECK_LE(length_, std::numeric_limits<size_t>::max() - delta);
+    QUICHE_DCHECK_LE(length_, capacity_ - delta);
+    length_ += delta;
+  }
+
+ private:
+  // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
+  // char.
+  char* buffer_;
+  size_t capacity_;  // Allocation size of payload (or -1 if buffer is const).
+  size_t length_;    // Current length of the buffer.
+
+  // The endianness to write integers and floating numbers.
+  quiche::Endianness endianness_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_DATA_WRITER_H_
diff --git a/quiche/common/quiche_data_writer_test.cc b/quiche/common/quiche_data_writer_test.cc
new file mode 100644
index 0000000..d58dafc
--- /dev/null
+++ b/quiche/common/quiche_data_writer_test.cc
@@ -0,0 +1,428 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_data_writer.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+char* AsChars(unsigned char* data) {
+  return reinterpret_cast<char*>(data);
+}
+
+struct TestParams {
+  explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
+
+  quiche::Endianness endianness;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
+      "ByteOrder");
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (quiche::Endianness endianness :
+       {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
+    params.push_back(TestParams(endianness));
+  }
+  return params;
+}
+
+class QuicheDataWriterTest : public QuicheTestWithParam<TestParams> {};
+
+INSTANTIATE_TEST_SUITE_P(QuicheDataWriterTests,
+                         QuicheDataWriterTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicheDataWriterTest, Write16BitUnsignedIntegers) {
+  char little_endian16[] = {0x22, 0x11};
+  char big_endian16[] = {0x11, 0x22};
+  char buffer16[2];
+  {
+    uint16_t in_memory16 = 0x1122;
+    QuicheDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteUInt16(in_memory16);
+    test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
+                                                            : little_endian16,
+        2);
+
+    uint16_t read_number16;
+    QuicheDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadUInt16(&read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+
+  {
+    uint64_t in_memory16 = 0x0000000000001122;
+    QuicheDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteBytesToUInt64(2, in_memory16);
+    test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
+                                                            : little_endian16,
+        2);
+
+    uint64_t read_number16;
+    QuicheDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadBytesToUInt64(2, &read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+}
+
+TEST_P(QuicheDataWriterTest, Write24BitUnsignedIntegers) {
+  char little_endian24[] = {0x33, 0x22, 0x11};
+  char big_endian24[] = {0x11, 0x22, 0x33};
+  char buffer24[3];
+  uint64_t in_memory24 = 0x0000000000112233;
+  QuicheDataWriter writer(3, buffer24, GetParam().endianness);
+  writer.WriteBytesToUInt64(3, in_memory24);
+  test::CompareCharArraysWithHexError(
+      "uint24", buffer24, 3,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
+                                                          : little_endian24,
+      3);
+
+  uint64_t read_number24;
+  QuicheDataReader reader(buffer24, 3, GetParam().endianness);
+  reader.ReadBytesToUInt64(3, &read_number24);
+  EXPECT_EQ(in_memory24, read_number24);
+}
+
+TEST_P(QuicheDataWriterTest, Write32BitUnsignedIntegers) {
+  char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
+  char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
+  char buffer32[4];
+  {
+    uint32_t in_memory32 = 0x11223344;
+    QuicheDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteUInt32(in_memory32);
+    test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
+                                                            : little_endian32,
+        4);
+
+    uint32_t read_number32;
+    QuicheDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadUInt32(&read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+
+  {
+    uint64_t in_memory32 = 0x11223344;
+    QuicheDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteBytesToUInt64(4, in_memory32);
+    test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
+                                                            : little_endian32,
+        4);
+
+    uint64_t read_number32;
+    QuicheDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadBytesToUInt64(4, &read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+}
+
+TEST_P(QuicheDataWriterTest, Write40BitUnsignedIntegers) {
+  uint64_t in_memory40 = 0x0000001122334455;
+  char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
+  char buffer40[5];
+  QuicheDataWriter writer(5, buffer40, GetParam().endianness);
+  writer.WriteBytesToUInt64(5, in_memory40);
+  test::CompareCharArraysWithHexError(
+      "uint40", buffer40, 5,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
+                                                          : little_endian40,
+      5);
+
+  uint64_t read_number40;
+  QuicheDataReader reader(buffer40, 5, GetParam().endianness);
+  reader.ReadBytesToUInt64(5, &read_number40);
+  EXPECT_EQ(in_memory40, read_number40);
+}
+
+TEST_P(QuicheDataWriterTest, Write48BitUnsignedIntegers) {
+  uint64_t in_memory48 = 0x0000112233445566;
+  char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+  char buffer48[6];
+  QuicheDataWriter writer(6, buffer48, GetParam().endianness);
+  writer.WriteBytesToUInt64(6, in_memory48);
+  test::CompareCharArraysWithHexError(
+      "uint48", buffer48, 6,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
+                                                          : little_endian48,
+      6);
+
+  uint64_t read_number48;
+  QuicheDataReader reader(buffer48, 6, GetParam().endianness);
+  reader.ReadBytesToUInt64(6., &read_number48);
+  EXPECT_EQ(in_memory48, read_number48);
+}
+
+TEST_P(QuicheDataWriterTest, Write56BitUnsignedIntegers) {
+  uint64_t in_memory56 = 0x0011223344556677;
+  char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+  char buffer56[7];
+  QuicheDataWriter writer(7, buffer56, GetParam().endianness);
+  writer.WriteBytesToUInt64(7, in_memory56);
+  test::CompareCharArraysWithHexError(
+      "uint56", buffer56, 7,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
+                                                          : little_endian56,
+      7);
+
+  uint64_t read_number56;
+  QuicheDataReader reader(buffer56, 7, GetParam().endianness);
+  reader.ReadBytesToUInt64(7, &read_number56);
+  EXPECT_EQ(in_memory56, read_number56);
+}
+
+TEST_P(QuicheDataWriterTest, Write64BitUnsignedIntegers) {
+  uint64_t in_memory64 = 0x1122334455667788;
+  unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11};
+  unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
+                                  0x55, 0x66, 0x77, 0x88};
+  char buffer64[8];
+  QuicheDataWriter writer(8, buffer64, GetParam().endianness);
+  writer.WriteBytesToUInt64(8, in_memory64);
+  test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
+          ? AsChars(big_endian64)
+          : AsChars(little_endian64),
+      8);
+
+  uint64_t read_number64;
+  QuicheDataReader reader(buffer64, 8, GetParam().endianness);
+  reader.ReadBytesToUInt64(8, &read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+
+  QuicheDataWriter writer2(8, buffer64, GetParam().endianness);
+  writer2.WriteUInt64(in_memory64);
+  test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
+          ? AsChars(big_endian64)
+          : AsChars(little_endian64),
+      8);
+  read_number64 = 0u;
+  QuicheDataReader reader2(buffer64, 8, GetParam().endianness);
+  reader2.ReadUInt64(&read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+}
+
+TEST_P(QuicheDataWriterTest, WriteIntegers) {
+  char buf[43];
+  uint8_t i8 = 0x01;
+  uint16_t i16 = 0x0123;
+  uint32_t i32 = 0x01234567;
+  uint64_t i64 = 0x0123456789ABCDEF;
+  QuicheDataWriter writer(46, buf, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 1u:
+        EXPECT_TRUE(writer.WriteUInt8(i8));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 2u:
+        EXPECT_TRUE(writer.WriteUInt16(i16));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 3u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 4u:
+        EXPECT_TRUE(writer.WriteUInt32(i32));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 5u:
+      case 6u:
+      case 7u:
+      case 8u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      default:
+        EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
+    }
+  }
+
+  QuicheDataReader reader(buf, 46, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    uint8_t read8;
+    uint16_t read16;
+    uint32_t read32;
+    uint64_t read64;
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0u, read64);
+        break;
+      case 1u:
+        EXPECT_TRUE(reader.ReadUInt8(&read8));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i8, read8);
+        EXPECT_EQ(0xEFu, read64);
+        break;
+      case 2u:
+        EXPECT_TRUE(reader.ReadUInt16(&read16));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i16, read16);
+        EXPECT_EQ(0xCDEFu, read64);
+        break;
+      case 3u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0xABCDEFu, read64);
+        break;
+      case 4u:
+        EXPECT_TRUE(reader.ReadUInt32(&read32));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i32, read32);
+        EXPECT_EQ(0x89ABCDEFu, read64);
+        break;
+      case 5u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x6789ABCDEFu, read64);
+        break;
+      case 6u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x456789ABCDEFu, read64);
+        break;
+      case 7u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x23456789ABCDEFu, read64);
+        break;
+      case 8u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x0123456789ABCDEFu, read64);
+        break;
+      default:
+        EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
+    }
+  }
+}
+
+TEST_P(QuicheDataWriterTest, WriteBytes) {
+  char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+  char buf[ABSL_ARRAYSIZE(bytes)];
+  QuicheDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
+  for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
+    EXPECT_EQ(bytes[i], buf[i]);
+  }
+}
+
+TEST_P(QuicheDataWriterTest, Seek) {
+  char buffer[3] = {};
+  QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+  EXPECT_TRUE(writer.WriteUInt8(42));
+  EXPECT_TRUE(writer.Seek(1));
+  EXPECT_TRUE(writer.WriteUInt8(3));
+
+  char expected[] = {42, 0, 3};
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
+    EXPECT_EQ(buffer[i], expected[i]);
+  }
+}
+
+TEST_P(QuicheDataWriterTest, SeekTooFarFails) {
+  char buffer[20];
+
+  // Check that one can seek to the end of the writer, but not past.
+  {
+    QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                            GetParam().endianness);
+    EXPECT_TRUE(writer.Seek(20));
+    EXPECT_FALSE(writer.Seek(1));
+  }
+
+  // Seeking several bytes past the end fails.
+  {
+    QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                            GetParam().endianness);
+    EXPECT_FALSE(writer.Seek(100));
+  }
+
+  // Seeking so far that arithmetic overflow could occur also fails.
+  {
+    QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                            GetParam().endianness);
+    EXPECT_TRUE(writer.Seek(10));
+    EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
+  }
+}
+
+TEST_P(QuicheDataWriterTest, PayloadReads) {
+  char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  char expected_first_read[4] = {1, 2, 3, 4};
+  char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  QuicheDataReader reader(buffer, sizeof(buffer));
+  absl::string_view previously_read_payload1 = reader.PreviouslyReadPayload();
+  EXPECT_TRUE(previously_read_payload1.empty());
+  char first_read_buffer[4] = {};
+  EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
+  test::CompareCharArraysWithHexError(
+      "first read", first_read_buffer, sizeof(first_read_buffer),
+      expected_first_read, sizeof(expected_first_read));
+  absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
+  test::CompareCharArraysWithHexError(
+      "peeked_remaining_payload", peeked_remaining_payload.data(),
+      peeked_remaining_payload.length(), expected_remaining,
+      sizeof(expected_remaining));
+  absl::string_view full_payload = reader.FullPayload();
+  test::CompareCharArraysWithHexError("full_payload", full_payload.data(),
+                                      full_payload.length(), buffer,
+                                      sizeof(buffer));
+  absl::string_view previously_read_payload2 = reader.PreviouslyReadPayload();
+  test::CompareCharArraysWithHexError(
+      "previously_read_payload2", previously_read_payload2.data(),
+      previously_read_payload2.length(), first_read_buffer,
+      sizeof(first_read_buffer));
+  absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
+  test::CompareCharArraysWithHexError(
+      "read_remaining_payload", read_remaining_payload.data(),
+      read_remaining_payload.length(), expected_remaining,
+      sizeof(expected_remaining));
+  EXPECT_TRUE(reader.IsDoneReading());
+  absl::string_view full_payload2 = reader.FullPayload();
+  test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(),
+                                      full_payload2.length(), buffer,
+                                      sizeof(buffer));
+  absl::string_view previously_read_payload3 = reader.PreviouslyReadPayload();
+  test::CompareCharArraysWithHexError(
+      "previously_read_payload3", previously_read_payload3.data(),
+      previously_read_payload3.length(), buffer, sizeof(buffer));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/quiche_endian.h b/quiche/common/quiche_endian.h
new file mode 100644
index 0000000..30639cc
--- /dev/null
+++ b/quiche/common/quiche_endian.h
@@ -0,0 +1,59 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_ENDIAN_H_
+#define QUICHE_COMMON_QUICHE_ENDIAN_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <type_traits>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+enum Endianness {
+  NETWORK_BYTE_ORDER,  // big endian
+  HOST_BYTE_ORDER      // little endian
+};
+
+// Provide utility functions that convert from/to network order (big endian)
+// to/from host order (little endian).
+class QUICHE_EXPORT_PRIVATE QuicheEndian {
+ public:
+  // Convert |x| from host order (little endian) to network order (big endian).
+#if defined(__clang__) || \
+    (defined(__GNUC__) && \
+     ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
+  static uint16_t HostToNet16(uint16_t x) { return __builtin_bswap16(x); }
+  static uint32_t HostToNet32(uint32_t x) { return __builtin_bswap32(x); }
+  static uint64_t HostToNet64(uint64_t x) { return __builtin_bswap64(x); }
+#else
+  static uint16_t HostToNet16(uint16_t x) { return PortableByteSwap(x); }
+  static uint32_t HostToNet32(uint32_t x) { return PortableByteSwap(x); }
+  static uint64_t HostToNet64(uint64_t x) { return PortableByteSwap(x); }
+#endif
+
+  // Convert |x| from network order (big endian) to host order (little endian).
+  static uint16_t NetToHost16(uint16_t x) { return HostToNet16(x); }
+  static uint32_t NetToHost32(uint32_t x) { return HostToNet32(x); }
+  static uint64_t NetToHost64(uint64_t x) { return HostToNet64(x); }
+
+  // Left public for tests.
+  template <typename T>
+  static T PortableByteSwap(T input) {
+    static_assert(std::is_unsigned<T>::value, "T has to be uintNN_t");
+    union {
+      T number;
+      char bytes[sizeof(T)];
+    } value;
+    value.number = input;
+    std::reverse(std::begin(value.bytes), std::end(value.bytes));
+    return value.number;
+  }
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_ENDIAN_H_
diff --git a/quiche/common/quiche_endian_test.cc b/quiche/common/quiche_endian_test.cc
new file mode 100644
index 0000000..66527a9
--- /dev/null
+++ b/quiche/common/quiche_endian_test.cc
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_endian.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+const uint16_t k16BitTestData = 0xaabb;
+const uint16_t k16BitSwappedTestData = 0xbbaa;
+const uint32_t k32BitTestData = 0xaabbccdd;
+const uint32_t k32BitSwappedTestData = 0xddccbbaa;
+const uint64_t k64BitTestData = 0xaabbccdd44332211;
+const uint64_t k64BitSwappedTestData = 0x11223344ddccbbaa;
+
+class QuicheEndianTest : public QuicheTest {};
+
+// Test portable version.  Since we normally compile with either GCC or Clang,
+// it will very rarely used otherwise.
+TEST_F(QuicheEndianTest, Portable) {
+  EXPECT_EQ(k16BitSwappedTestData,
+            QuicheEndian::PortableByteSwap(k16BitTestData));
+  EXPECT_EQ(k32BitSwappedTestData,
+            QuicheEndian::PortableByteSwap(k32BitTestData));
+  EXPECT_EQ(k64BitSwappedTestData,
+            QuicheEndian::PortableByteSwap(k64BitTestData));
+}
+
+TEST_F(QuicheEndianTest, HostToNet) {
+  EXPECT_EQ(k16BitSwappedTestData,
+            quiche::QuicheEndian::HostToNet16(k16BitTestData));
+  EXPECT_EQ(k32BitSwappedTestData,
+            quiche::QuicheEndian::HostToNet32(k32BitTestData));
+  EXPECT_EQ(k64BitSwappedTestData,
+            quiche::QuicheEndian::HostToNet64(k64BitTestData));
+}
+
+TEST_F(QuicheEndianTest, NetToHost) {
+  EXPECT_EQ(k16BitTestData,
+            quiche::QuicheEndian::NetToHost16(k16BitSwappedTestData));
+  EXPECT_EQ(k32BitTestData,
+            quiche::QuicheEndian::NetToHost32(k32BitSwappedTestData));
+  EXPECT_EQ(k64BitTestData,
+            quiche::QuicheEndian::NetToHost64(k64BitSwappedTestData));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/quiche_linked_hash_map.h b/quiche/common/quiche_linked_hash_map.h
new file mode 100644
index 0000000..25c70fb
--- /dev/null
+++ b/quiche/common/quiche_linked_hash_map.h
@@ -0,0 +1,237 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a simplistic insertion-ordered map.  It behaves similarly to an STL
+// map, but only implements a small subset of the map's methods.  Internally, we
+// just keep a map and a list going in parallel.
+//
+// This class provides no thread safety guarantees, beyond what you would
+// normally see with std::list.
+//
+// Iterators point into the list and should be stable in the face of
+// mutations, except for an iterator pointing to an element that was just
+// deleted.
+
+#ifndef QUICHE_COMMON_QUICHE_LINKED_HASH_MAP_H_
+#define QUICHE_COMMON_QUICHE_LINKED_HASH_MAP_H_
+
+#include <functional>
+#include <list>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/hash/hash.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+
+// This holds a list of pair<Key, Value> items.  This list is what gets
+// traversed, and it's iterators from this list that we return from
+// begin/end/find.
+//
+// We also keep a set<list::iterator> for find.  Since std::list is a
+// doubly-linked list, the iterators should remain stable.
+
+// QUICHE_NO_EXPORT comments suppress erroneous presubmit failures.
+template <class Key,                      // QUICHE_NO_EXPORT
+          class Value,                    // QUICHE_NO_EXPORT
+          class Hash = absl::Hash<Key>,   // QUICHE_NO_EXPORT
+          class Eq = std::equal_to<Key>>  // QUICHE_NO_EXPORT
+class QuicheLinkedHashMap {               // QUICHE_NO_EXPORT
+ private:
+  typedef std::list<std::pair<Key, Value>> ListType;
+  typedef absl::flat_hash_map<Key, typename ListType::iterator, Hash, Eq>
+      MapType;
+
+ public:
+  typedef typename ListType::iterator iterator;
+  typedef typename ListType::reverse_iterator reverse_iterator;
+  typedef typename ListType::const_iterator const_iterator;
+  typedef typename ListType::const_reverse_iterator const_reverse_iterator;
+  typedef typename MapType::key_type key_type;
+  typedef typename ListType::value_type value_type;
+  typedef typename ListType::size_type size_type;
+
+  QuicheLinkedHashMap() = default;
+  explicit QuicheLinkedHashMap(size_type bucket_count) : map_(bucket_count) {}
+
+  QuicheLinkedHashMap(const QuicheLinkedHashMap& other) = delete;
+  QuicheLinkedHashMap& operator=(const QuicheLinkedHashMap& other) = delete;
+  QuicheLinkedHashMap(QuicheLinkedHashMap&& other) = default;
+  QuicheLinkedHashMap& operator=(QuicheLinkedHashMap&& other) = default;
+
+  // Returns an iterator to the first (insertion-ordered) element.  Like a map,
+  // this can be dereferenced to a pair<Key, Value>.
+  iterator begin() { return list_.begin(); }
+  const_iterator begin() const { return list_.begin(); }
+
+  // Returns an iterator beyond the last element.
+  iterator end() { return list_.end(); }
+  const_iterator end() const { return list_.end(); }
+
+  // Returns an iterator to the last (insertion-ordered) element.  Like a map,
+  // this can be dereferenced to a pair<Key, Value>.
+  reverse_iterator rbegin() { return list_.rbegin(); }
+  const_reverse_iterator rbegin() const { return list_.rbegin(); }
+
+  // Returns an iterator beyond the first element.
+  reverse_iterator rend() { return list_.rend(); }
+  const_reverse_iterator rend() const { return list_.rend(); }
+
+  // Front and back accessors common to many stl containers.
+
+  // Returns the earliest-inserted element
+  const value_type& front() const { return list_.front(); }
+
+  // Returns the earliest-inserted element.
+  value_type& front() { return list_.front(); }
+
+  // Returns the most-recently-inserted element.
+  const value_type& back() const { return list_.back(); }
+
+  // Returns the most-recently-inserted element.
+  value_type& back() { return list_.back(); }
+
+  // Clears the map of all values.
+  void clear() {
+    map_.clear();
+    list_.clear();
+  }
+
+  // Returns true iff the map is empty.
+  bool empty() const { return list_.empty(); }
+
+  // Removes the first element from the list.
+  void pop_front() { erase(begin()); }
+
+  // Erases values with the provided key.  Returns the number of elements
+  // erased.  In this implementation, this will be 0 or 1.
+  size_type erase(const Key& key) {
+    typename MapType::iterator found = map_.find(key);
+    if (found == map_.end()) {
+      return 0;
+    }
+
+    list_.erase(found->second);
+    map_.erase(found);
+
+    return 1;
+  }
+
+  // Erases the item that 'position' points to. Returns an iterator that points
+  // to the item that comes immediately after the deleted item in the list, or
+  // end().
+  // If the provided iterator is invalid or there is inconsistency between the
+  // map and list, a QUICHE_CHECK() error will occur.
+  iterator erase(iterator position) {
+    typename MapType::iterator found = map_.find(position->first);
+    QUICHE_CHECK(found->second == position)
+        << "Inconsistent iterator for map and list, or the iterator is "
+           "invalid.";
+
+    map_.erase(found);
+    return list_.erase(position);
+  }
+
+  // Erases all the items in the range [first, last).  Returns an iterator that
+  // points to the item that comes immediately after the last deleted item in
+  // the list, or end().
+  iterator erase(iterator first, iterator last) {
+    while (first != last && first != end()) {
+      first = erase(first);
+    }
+    return first;
+  }
+
+  // Finds the element with the given key.  Returns an iterator to the
+  // value found, or to end() if the value was not found.  Like a map, this
+  // iterator points to a pair<Key, Value>.
+  iterator find(const Key& key) {
+    typename MapType::iterator found = map_.find(key);
+    if (found == map_.end()) {
+      return end();
+    }
+    return found->second;
+  }
+
+  const_iterator find(const Key& key) const {
+    typename MapType::const_iterator found = map_.find(key);
+    if (found == map_.end()) {
+      return end();
+    }
+    return found->second;
+  }
+
+  bool contains(const Key& key) const { return find(key) != end(); }
+
+  // Returns the value mapped to key, or an inserted iterator to that position
+  // in the map.
+  Value& operator[](const key_type& key) {
+    return (*((this->insert(std::make_pair(key, Value()))).first)).second;
+  }
+
+  // Inserts an element into the map
+  std::pair<iterator, bool> insert(const std::pair<Key, Value>& pair) {
+    return InsertInternal(pair);
+  }
+
+  // Inserts an element into the map
+  std::pair<iterator, bool> insert(std::pair<Key, Value>&& pair) {
+    return InsertInternal(std::move(pair));
+  }
+
+  // Derive size_ from map_, as list::size might be O(N).
+  size_type size() const { return map_.size(); }
+
+  template <typename... Args>
+  std::pair<iterator, bool> emplace(Args&&... args) {
+    ListType node_donor;
+    auto node_pos =
+        node_donor.emplace(node_donor.end(), std::forward<Args>(args)...);
+    const auto& k = node_pos->first;
+    auto ins = map_.insert({k, node_pos});
+    if (!ins.second) {
+      return {ins.first->second, false};
+    }
+    list_.splice(list_.end(), node_donor, node_pos);
+    return {ins.first->second, true};
+  }
+
+  void swap(QuicheLinkedHashMap& other) {
+    map_.swap(other.map_);
+    list_.swap(other.list_);
+  }
+
+ private:
+  template <typename U>
+  std::pair<iterator, bool> InsertInternal(U&& pair) {
+    auto insert_result = map_.try_emplace(pair.first);
+    auto map_iter = insert_result.first;
+
+    // If the map already contains this key, return a pair with an iterator to
+    // it, and false indicating that we didn't insert anything.
+    if (!insert_result.second) {
+      return {map_iter->second, false};
+    }
+
+    // Otherwise, insert into the list, and set value in map.
+    auto list_iter = list_.insert(list_.end(), std::forward<U>(pair));
+    map_iter->second = list_iter;
+
+    return {list_iter, true};
+  }
+
+  // The map component, used for speedy lookups
+  MapType map_;
+
+  // The list component, used for maintaining insertion order
+  ListType list_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_LINKED_HASH_MAP_H_
diff --git a/quiche/common/quiche_linked_hash_map_test.cc b/quiche/common/quiche_linked_hash_map_test.cc
new file mode 100644
index 0000000..4b2fb9b
--- /dev/null
+++ b/quiche/common/quiche_linked_hash_map_test.cc
@@ -0,0 +1,395 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Tests QuicheLinkedHashMap.
+
+#include "quiche/common/quiche_linked_hash_map.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+using testing::Pair;
+using testing::Pointee;
+using testing::UnorderedElementsAre;
+
+namespace quiche {
+namespace test {
+
+// Tests that move constructor works.
+TEST(LinkedHashMapTest, Move) {
+  // Use unique_ptr as an example of a non-copyable type.
+  QuicheLinkedHashMap<int, std::unique_ptr<int>> m;
+  m[2] = std::make_unique<int>(12);
+  m[3] = std::make_unique<int>(13);
+  QuicheLinkedHashMap<int, std::unique_ptr<int>> n = std::move(m);
+  EXPECT_THAT(n,
+              UnorderedElementsAre(Pair(2, Pointee(12)), Pair(3, Pointee(13))));
+}
+
+TEST(LinkedHashMapTest, CanEmplaceMoveOnly) {
+  QuicheLinkedHashMap<int, std::unique_ptr<int>> m;
+  struct Data {
+    int k, v;
+  };
+  const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
+  for (const auto& kv : data) {
+    m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
+              std::make_tuple(new int{kv.v}));
+  }
+  EXPECT_TRUE(m.contains(2));
+  auto found = m.find(2);
+  ASSERT_TRUE(found != m.end());
+  EXPECT_EQ(234, *found->second);
+}
+
+struct NoCopy {
+  explicit NoCopy(int x) : x(x) {}
+  NoCopy(const NoCopy&) = delete;
+  NoCopy& operator=(const NoCopy&) = delete;
+  NoCopy(NoCopy&&) = delete;
+  NoCopy& operator=(NoCopy&&) = delete;
+  int x;
+};
+
+TEST(LinkedHashMapTest, CanEmplaceNoMoveNoCopy) {
+  QuicheLinkedHashMap<int, NoCopy> m;
+  struct Data {
+    int k, v;
+  };
+  const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
+  for (const auto& kv : data) {
+    m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
+              std::make_tuple(kv.v));
+  }
+  EXPECT_TRUE(m.contains(2));
+  auto found = m.find(2);
+  ASSERT_TRUE(found != m.end());
+  EXPECT_EQ(234, found->second.x);
+}
+
+TEST(LinkedHashMapTest, ConstKeys) {
+  QuicheLinkedHashMap<int, int> m;
+  m.insert(std::make_pair(1, 2));
+  // Test that keys are const in iteration.
+  std::pair<int, int>& p = *m.begin();
+  EXPECT_EQ(1, p.first);
+}
+
+// Tests that iteration from begin() to end() works
+TEST(LinkedHashMapTest, Iteration) {
+  QuicheLinkedHashMap<int, int> m;
+  EXPECT_TRUE(m.begin() == m.end());
+
+  m.insert(std::make_pair(2, 12));
+  m.insert(std::make_pair(1, 11));
+  m.insert(std::make_pair(3, 13));
+
+  QuicheLinkedHashMap<int, int>::iterator i = m.begin();
+  ASSERT_TRUE(m.begin() == i);
+  ASSERT_TRUE(m.end() != i);
+  EXPECT_EQ(2, i->first);
+  EXPECT_EQ(12, i->second);
+
+  ++i;
+  ASSERT_TRUE(m.end() != i);
+  EXPECT_EQ(1, i->first);
+  EXPECT_EQ(11, i->second);
+
+  ++i;
+  ASSERT_TRUE(m.end() != i);
+  EXPECT_EQ(3, i->first);
+  EXPECT_EQ(13, i->second);
+
+  ++i;  // Should be the end of the line.
+  ASSERT_TRUE(m.end() == i);
+}
+
+// Tests that reverse iteration from rbegin() to rend() works
+TEST(LinkedHashMapTest, ReverseIteration) {
+  QuicheLinkedHashMap<int, int> m;
+  EXPECT_TRUE(m.rbegin() == m.rend());
+
+  m.insert(std::make_pair(2, 12));
+  m.insert(std::make_pair(1, 11));
+  m.insert(std::make_pair(3, 13));
+
+  QuicheLinkedHashMap<int, int>::reverse_iterator i = m.rbegin();
+  ASSERT_TRUE(m.rbegin() == i);
+  ASSERT_TRUE(m.rend() != i);
+  EXPECT_EQ(3, i->first);
+  EXPECT_EQ(13, i->second);
+
+  ++i;
+  ASSERT_TRUE(m.rend() != i);
+  EXPECT_EQ(1, i->first);
+  EXPECT_EQ(11, i->second);
+
+  ++i;
+  ASSERT_TRUE(m.rend() != i);
+  EXPECT_EQ(2, i->first);
+  EXPECT_EQ(12, i->second);
+
+  ++i;  // Should be the end of the line.
+  ASSERT_TRUE(m.rend() == i);
+}
+
+// Tests that clear() works
+TEST(LinkedHashMapTest, Clear) {
+  QuicheLinkedHashMap<int, int> m;
+  m.insert(std::make_pair(2, 12));
+  m.insert(std::make_pair(1, 11));
+  m.insert(std::make_pair(3, 13));
+
+  ASSERT_EQ(3u, m.size());
+
+  m.clear();
+
+  EXPECT_EQ(0u, m.size());
+
+  m.clear();  // Make sure we can call it on an empty map.
+
+  EXPECT_EQ(0u, m.size());
+}
+
+// Tests that size() works.
+TEST(LinkedHashMapTest, Size) {
+  QuicheLinkedHashMap<int, int> m;
+  EXPECT_EQ(0u, m.size());
+  m.insert(std::make_pair(2, 12));
+  EXPECT_EQ(1u, m.size());
+  m.insert(std::make_pair(1, 11));
+  EXPECT_EQ(2u, m.size());
+  m.insert(std::make_pair(3, 13));
+  EXPECT_EQ(3u, m.size());
+  m.clear();
+  EXPECT_EQ(0u, m.size());
+}
+
+// Tests empty()
+TEST(LinkedHashMapTest, Empty) {
+  QuicheLinkedHashMap<int, int> m;
+  ASSERT_TRUE(m.empty());
+  m.insert(std::make_pair(2, 12));
+  ASSERT_FALSE(m.empty());
+  m.clear();
+  ASSERT_TRUE(m.empty());
+}
+
+TEST(LinkedHashMapTest, Erase) {
+  QuicheLinkedHashMap<int, int> m;
+  ASSERT_EQ(0u, m.size());
+  EXPECT_EQ(0u, m.erase(2));  // Nothing to erase yet
+
+  m.insert(std::make_pair(2, 12));
+  ASSERT_EQ(1u, m.size());
+  EXPECT_EQ(1u, m.erase(2));
+  EXPECT_EQ(0u, m.size());
+
+  EXPECT_EQ(0u, m.erase(2));  // Make sure nothing bad happens if we repeat.
+  EXPECT_EQ(0u, m.size());
+}
+
+TEST(LinkedHashMapTest, Erase2) {
+  QuicheLinkedHashMap<int, int> m;
+  ASSERT_EQ(0u, m.size());
+  EXPECT_EQ(0u, m.erase(2));  // Nothing to erase yet
+
+  m.insert(std::make_pair(2, 12));
+  m.insert(std::make_pair(1, 11));
+  m.insert(std::make_pair(3, 13));
+  m.insert(std::make_pair(4, 14));
+  ASSERT_EQ(4u, m.size());
+
+  // Erase middle two
+  EXPECT_EQ(1u, m.erase(1));
+  EXPECT_EQ(1u, m.erase(3));
+
+  EXPECT_EQ(2u, m.size());
+
+  // Make sure we can still iterate over everything that's left.
+  QuicheLinkedHashMap<int, int>::iterator it = m.begin();
+  ASSERT_TRUE(it != m.end());
+  EXPECT_EQ(12, it->second);
+  ++it;
+  ASSERT_TRUE(it != m.end());
+  EXPECT_EQ(14, it->second);
+  ++it;
+  ASSERT_TRUE(it == m.end());
+
+  EXPECT_EQ(0u, m.erase(1));  // Make sure nothing bad happens if we repeat.
+  ASSERT_EQ(2u, m.size());
+
+  EXPECT_EQ(1u, m.erase(2));
+  EXPECT_EQ(1u, m.erase(4));
+  ASSERT_EQ(0u, m.size());
+
+  EXPECT_EQ(0u, m.erase(1));  // Make sure nothing bad happens if we repeat.
+  ASSERT_EQ(0u, m.size());
+}
+
+// Test that erase(iter,iter) and erase(iter) compile and work.
+TEST(LinkedHashMapTest, Erase3) {
+  QuicheLinkedHashMap<int, int> m;
+
+  m.insert(std::make_pair(1, 11));
+  m.insert(std::make_pair(2, 12));
+  m.insert(std::make_pair(3, 13));
+  m.insert(std::make_pair(4, 14));
+
+  // Erase middle two
+  QuicheLinkedHashMap<int, int>::iterator it2 = m.find(2);
+  QuicheLinkedHashMap<int, int>::iterator it4 = m.find(4);
+  EXPECT_EQ(m.erase(it2, it4), m.find(4));
+  EXPECT_EQ(2u, m.size());
+
+  // Make sure we can still iterate over everything that's left.
+  QuicheLinkedHashMap<int, int>::iterator it = m.begin();
+  ASSERT_TRUE(it != m.end());
+  EXPECT_EQ(11, it->second);
+  ++it;
+  ASSERT_TRUE(it != m.end());
+  EXPECT_EQ(14, it->second);
+  ++it;
+  ASSERT_TRUE(it == m.end());
+
+  // Erase first one using an iterator.
+  EXPECT_EQ(m.erase(m.begin()), m.find(4));
+
+  // Only the last element should be left.
+  it = m.begin();
+  ASSERT_TRUE(it != m.end());
+  EXPECT_EQ(14, it->second);
+  ++it;
+  ASSERT_TRUE(it == m.end());
+}
+
+TEST(LinkedHashMapTest, Insertion) {
+  QuicheLinkedHashMap<int, int> m;
+  ASSERT_EQ(0u, m.size());
+  std::pair<QuicheLinkedHashMap<int, int>::iterator, bool> result;
+
+  result = m.insert(std::make_pair(2, 12));
+  ASSERT_EQ(1u, m.size());
+  EXPECT_TRUE(result.second);
+  EXPECT_EQ(2, result.first->first);
+  EXPECT_EQ(12, result.first->second);
+
+  result = m.insert(std::make_pair(1, 11));
+  ASSERT_EQ(2u, m.size());
+  EXPECT_TRUE(result.second);
+  EXPECT_EQ(1, result.first->first);
+  EXPECT_EQ(11, result.first->second);
+
+  result = m.insert(std::make_pair(3, 13));
+  QuicheLinkedHashMap<int, int>::iterator result_iterator = result.first;
+  ASSERT_EQ(3u, m.size());
+  EXPECT_TRUE(result.second);
+  EXPECT_EQ(3, result.first->first);
+  EXPECT_EQ(13, result.first->second);
+
+  result = m.insert(std::make_pair(3, 13));
+  EXPECT_EQ(3u, m.size());
+  EXPECT_FALSE(result.second) << "No insertion should have occurred.";
+  EXPECT_TRUE(result_iterator == result.first)
+      << "Duplicate insertion should have given us the original iterator.";
+}
+
+static std::pair<int, int> Pair(int i, int j) {
+  return {i, j};
+}
+
+// Test front accessors.
+TEST(LinkedHashMapTest, Front) {
+  QuicheLinkedHashMap<int, int> m;
+
+  m.insert(std::make_pair(2, 12));
+  m.insert(std::make_pair(1, 11));
+  m.insert(std::make_pair(3, 13));
+
+  EXPECT_EQ(3u, m.size());
+  EXPECT_EQ(Pair(2, 12), m.front());
+  m.pop_front();
+  EXPECT_EQ(2u, m.size());
+  EXPECT_EQ(Pair(1, 11), m.front());
+  m.pop_front();
+  EXPECT_EQ(1u, m.size());
+  EXPECT_EQ(Pair(3, 13), m.front());
+  m.pop_front();
+  EXPECT_TRUE(m.empty());
+}
+
+TEST(LinkedHashMapTest, Find) {
+  QuicheLinkedHashMap<int, int> m;
+
+  EXPECT_TRUE(m.end() == m.find(1))
+      << "We shouldn't find anything in an empty map.";
+
+  m.insert(std::make_pair(2, 12));
+  EXPECT_TRUE(m.end() == m.find(1))
+      << "We shouldn't find an element that doesn't exist in the map.";
+
+  std::pair<QuicheLinkedHashMap<int, int>::iterator, bool> result =
+      m.insert(std::make_pair(1, 11));
+  ASSERT_TRUE(result.second);
+  ASSERT_TRUE(m.end() != result.first);
+  EXPECT_TRUE(result.first == m.find(1))
+      << "We should have found an element we know exists in the map.";
+  EXPECT_EQ(11, result.first->second);
+
+  // Check that a follow-up insertion doesn't affect our original
+  m.insert(std::make_pair(3, 13));
+  QuicheLinkedHashMap<int, int>::iterator it = m.find(1);
+  ASSERT_TRUE(m.end() != it);
+  EXPECT_EQ(11, it->second);
+
+  m.clear();
+  EXPECT_TRUE(m.end() == m.find(1))
+      << "We shouldn't find anything in a map that we've cleared.";
+}
+
+TEST(LinkedHashMapTest, Contains) {
+  QuicheLinkedHashMap<int, int> m;
+
+  EXPECT_FALSE(m.contains(1)) << "An empty map shouldn't contain anything.";
+
+  m.insert(std::make_pair(2, 12));
+  EXPECT_FALSE(m.contains(1))
+      << "The map shouldn't contain an element that doesn't exist.";
+
+  m.insert(std::make_pair(1, 11));
+  EXPECT_TRUE(m.contains(1))
+      << "The map should contain an element that we know exists.";
+
+  m.clear();
+  EXPECT_FALSE(m.contains(1))
+      << "A map that we've cleared shouldn't contain anything.";
+}
+
+TEST(LinkedHashMapTest, Swap) {
+  QuicheLinkedHashMap<int, int> m1;
+  QuicheLinkedHashMap<int, int> m2;
+  m1.insert(std::make_pair(1, 1));
+  m1.insert(std::make_pair(2, 2));
+  m2.insert(std::make_pair(3, 3));
+  ASSERT_EQ(2u, m1.size());
+  ASSERT_EQ(1u, m2.size());
+  m1.swap(m2);
+  ASSERT_EQ(1u, m1.size());
+  ASSERT_EQ(2u, m2.size());
+}
+
+TEST(LinkedHashMapTest, CustomHashAndEquality) {
+  struct CustomIntHash {
+    size_t operator()(int x) const { return x; }
+  };
+  QuicheLinkedHashMap<int, int, CustomIntHash> m;
+  m.insert(std::make_pair(1, 1));
+  EXPECT_TRUE(m.contains(1));
+  EXPECT_EQ(1, m[1]);
+}
+
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/quiche_mem_slice_storage.cc b/quiche/common/quiche_mem_slice_storage.cc
new file mode 100644
index 0000000..4b304af
--- /dev/null
+++ b/quiche/common/quiche_mem_slice_storage.cc
@@ -0,0 +1,34 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_mem_slice_storage.h"
+
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quiche {
+
+QuicheMemSliceStorage::QuicheMemSliceStorage(
+    const struct iovec* iov, int iov_count, QuicheBufferAllocator* allocator,
+    const quic::QuicByteCount max_slice_len) {
+  if (iov == nullptr) {
+    return;
+  }
+  quic::QuicByteCount write_len = 0;
+  for (int i = 0; i < iov_count; ++i) {
+    write_len += iov[i].iov_len;
+  }
+  QUICHE_DCHECK_LT(0u, write_len);
+
+  size_t io_offset = 0;
+  while (write_len > 0) {
+    size_t slice_len = std::min(write_len, max_slice_len);
+    QuicheBuffer buffer = QuicheBuffer::CopyFromIovec(allocator, iov, iov_count,
+                                                      io_offset, slice_len);
+    storage_.push_back(QuicheMemSlice(std::move(buffer)));
+    write_len -= slice_len;
+    io_offset += slice_len;
+  }
+}
+
+}  // namespace quiche
diff --git a/quiche/common/quiche_mem_slice_storage.h b/quiche/common/quiche_mem_slice_storage.h
new file mode 100644
index 0000000..3d772d1
--- /dev/null
+++ b/quiche/common/quiche_mem_slice_storage.h
@@ -0,0 +1,44 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_MEM_SLICE_STORAGE_H_
+#define QUICHE_COMMON_QUICHE_MEM_SLICE_STORAGE_H_
+
+#include <vector>
+
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quiche {
+
+// QuicheMemSliceStorage is a container class that store QuicheMemSlices for
+// further use cases such as turning into QuicheMemSliceSpan.
+class QUICHE_EXPORT_PRIVATE QuicheMemSliceStorage {
+ public:
+  QuicheMemSliceStorage(const struct iovec* iov, int iov_count,
+                        QuicheBufferAllocator* allocator,
+                        const quic::QuicByteCount max_slice_len);
+
+  QuicheMemSliceStorage(const QuicheMemSliceStorage& other) = default;
+  QuicheMemSliceStorage& operator=(const QuicheMemSliceStorage& other) =
+      default;
+  QuicheMemSliceStorage(QuicheMemSliceStorage&& other) = default;
+  QuicheMemSliceStorage& operator=(QuicheMemSliceStorage&& other) = default;
+
+  ~QuicheMemSliceStorage() = default;
+
+  // Return a QuicheMemSliceSpan form of the storage.
+  absl::Span<QuicheMemSlice> ToSpan() { return absl::MakeSpan(storage_); }
+
+ private:
+  std::vector<QuicheMemSlice> storage_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_MEM_SLICE_STORAGE_H_
diff --git a/quiche/common/quiche_mem_slice_storage_test.cc b/quiche/common/quiche_mem_slice_storage_test.cc
new file mode 100644
index 0000000..8b7ed1a
--- /dev/null
+++ b/quiche/common/quiche_mem_slice_storage_test.cc
@@ -0,0 +1,61 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_mem_slice_storage.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+namespace test {
+namespace {
+
+class QuicheMemSliceStorageImplTest : public QuicheTest {
+ public:
+  QuicheMemSliceStorageImplTest() = default;
+};
+
+TEST_F(QuicheMemSliceStorageImplTest, EmptyIov) {
+  QuicheMemSliceStorage storage(nullptr, 0, nullptr, 1024);
+  EXPECT_TRUE(storage.ToSpan().empty());
+}
+
+TEST_F(QuicheMemSliceStorageImplTest, SingleIov) {
+  SimpleBufferAllocator allocator;
+  std::string body(3, 'c');
+  struct iovec iov = {const_cast<char*>(body.data()), body.length()};
+  QuicheMemSliceStorage storage(&iov, 1, &allocator, 1024);
+  auto span = storage.ToSpan();
+  EXPECT_EQ("ccc", span[0].AsStringView());
+  EXPECT_NE(static_cast<const void*>(span[0].data()), body.data());
+}
+
+TEST_F(QuicheMemSliceStorageImplTest, MultipleIovInSingleSlice) {
+  SimpleBufferAllocator allocator;
+  std::string body1(3, 'a');
+  std::string body2(4, 'b');
+  struct iovec iov[] = {{const_cast<char*>(body1.data()), body1.length()},
+                        {const_cast<char*>(body2.data()), body2.length()}};
+
+  QuicheMemSliceStorage storage(iov, 2, &allocator, 1024);
+  auto span = storage.ToSpan();
+  EXPECT_EQ("aaabbbb", span[0].AsStringView());
+}
+
+TEST_F(QuicheMemSliceStorageImplTest, MultipleIovInMultipleSlice) {
+  SimpleBufferAllocator allocator;
+  std::string body1(4, 'a');
+  std::string body2(4, 'b');
+  struct iovec iov[] = {{const_cast<char*>(body1.data()), body1.length()},
+                        {const_cast<char*>(body2.data()), body2.length()}};
+
+  QuicheMemSliceStorage storage(iov, 2, &allocator, 4);
+  auto span = storage.ToSpan();
+  EXPECT_EQ("aaaa", span[0].AsStringView());
+  EXPECT_EQ("bbbb", span[1].AsStringView());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/quiche_text_utils.cc b/quiche/common/quiche_text_utils.cc
new file mode 100644
index 0000000..e31e898
--- /dev/null
+++ b/quiche/common/quiche_text_utils.cc
@@ -0,0 +1,77 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_text_utils.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+
+namespace quiche {
+
+// static
+void QuicheTextUtils::Base64Encode(const uint8_t* data,
+                                   size_t data_len,
+                                   std::string* output) {
+  absl::Base64Escape(std::string(reinterpret_cast<const char*>(data), data_len),
+                     output);
+  // Remove padding.
+  size_t len = output->size();
+  if (len >= 2) {
+    if ((*output)[len - 1] == '=') {
+      len--;
+      if ((*output)[len - 1] == '=') {
+        len--;
+      }
+      output->resize(len);
+    }
+  }
+}
+
+// static
+absl::optional<std::string> QuicheTextUtils::Base64Decode(
+    absl::string_view input) {
+  std::string output;
+  if (!absl::Base64Unescape(input, &output)) {
+    return absl::nullopt;
+  }
+  return output;
+}
+
+// static
+std::string QuicheTextUtils::HexDump(absl::string_view binary_data) {
+  const int kBytesPerLine = 16;  // Maximum bytes dumped per line.
+  int offset = 0;
+  const char* p = binary_data.data();
+  int bytes_remaining = binary_data.size();
+  std::string output;
+  while (bytes_remaining > 0) {
+    const int line_bytes = std::min(bytes_remaining, kBytesPerLine);
+    absl::StrAppendFormat(&output, "0x%04x:  ", offset);
+    for (int i = 0; i < kBytesPerLine; ++i) {
+      if (i < line_bytes) {
+        absl::StrAppendFormat(&output, "%02x",
+                              static_cast<unsigned char>(p[i]));
+      } else {
+        absl::StrAppend(&output, "  ");
+      }
+      if (i % 2) {
+        absl::StrAppend(&output, " ");
+      }
+    }
+    absl::StrAppend(&output, " ");
+    for (int i = 0; i < line_bytes; ++i) {
+      // Replace non-printable characters and 0x20 (space) with '.'
+      output += absl::ascii_isgraph(p[i]) ? p[i] : '.';
+    }
+
+    bytes_remaining -= line_bytes;
+    offset += line_bytes;
+    p += line_bytes;
+    absl::StrAppend(&output, "\n");
+  }
+  return output;
+}
+
+}  // namespace quiche
diff --git a/quiche/common/quiche_text_utils.h b/quiche/common/quiche_text_utils.h
new file mode 100644
index 0000000..a7af5ef
--- /dev/null
+++ b/quiche/common/quiche_text_utils.h
@@ -0,0 +1,76 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_TEXT_UTILS_H_
+#define QUICHE_COMMON_QUICHE_TEXT_UTILS_H_
+
+#include <string>
+
+#include "absl/hash/hash.h"
+#include "absl/strings/ascii.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace quiche {
+
+struct QUICHE_EXPORT_PRIVATE StringPieceCaseHash {
+  size_t operator()(absl::string_view data) const {
+    std::string lower = absl::AsciiStrToLower(data);
+    absl::Hash<absl::string_view> hasher;
+    return hasher(lower);
+  }
+};
+
+struct QUICHE_EXPORT_PRIVATE StringPieceCaseEqual {
+  bool operator()(absl::string_view piece1, absl::string_view piece2) const {
+    return absl::EqualsIgnoreCase(piece1, piece2);
+  }
+};
+
+// Various utilities for manipulating text.
+class QUICHE_EXPORT_PRIVATE QuicheTextUtils {
+ public:
+  // Returns a new string in which |data| has been converted to lower case.
+  static std::string ToLower(absl::string_view data) {
+    return absl::AsciiStrToLower(data);
+  }
+
+  // Removes leading and trailing whitespace from |data|.
+  static void RemoveLeadingAndTrailingWhitespace(absl::string_view* data) {
+    *data = absl::StripAsciiWhitespace(*data);
+  }
+
+  // Base64 encodes with no padding |data_len| bytes of |data| into |output|.
+  static void Base64Encode(const uint8_t* data,
+                           size_t data_len,
+                           std::string* output);
+
+  // Decodes a base64-encoded |input|.  Returns nullopt when the input is
+  // invalid.
+  static absl::optional<std::string> Base64Decode(absl::string_view input);
+
+  // Returns a string containing hex and ASCII representations of |binary|,
+  // side-by-side in the style of hexdump. Non-printable characters will be
+  // printed as '.' in the ASCII output.
+  // For example, given the input "Hello, QUIC!\01\02\03\04", returns:
+  // "0x0000:  4865 6c6c 6f2c 2051 5549 4321 0102 0304  Hello,.QUIC!...."
+  static std::string HexDump(absl::string_view binary_data);
+
+  // Returns true if |data| contains any uppercase characters.
+  static bool ContainsUpperCase(absl::string_view data) {
+    return std::any_of(data.begin(), data.end(), absl::ascii_isupper);
+  }
+
+  // Returns true if |data| contains only decimal digits.
+  static bool IsAllDigits(absl::string_view data) {
+    return std::all_of(data.begin(), data.end(), absl::ascii_isdigit);
+  }
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_TEXT_UTILS_H_
diff --git a/quiche/common/quiche_text_utils_test.cc b/quiche/common/quiche_text_utils_test.cc
new file mode 100644
index 0000000..aeaa940
--- /dev/null
+++ b/quiche/common/quiche_text_utils_test.cc
@@ -0,0 +1,92 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/quiche_text_utils.h"
+
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace test {
+
+TEST(QuicheTextUtilsTest, ToLower) {
+  EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("LOWER"));
+  EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("lower"));
+  EXPECT_EQ("lower", quiche::QuicheTextUtils::ToLower("lOwEr"));
+  EXPECT_EQ("123", quiche::QuicheTextUtils::ToLower("123"));
+  EXPECT_EQ("", quiche::QuicheTextUtils::ToLower(""));
+}
+
+TEST(QuicheTextUtilsTest, RemoveLeadingAndTrailingWhitespace) {
+  std::string input;
+
+  for (auto* input : {"text", " text", "  text", "text ", "text  ", " text ",
+                      "  text  ", "\r\n\ttext", "text\n\r\t"}) {
+    absl::string_view piece(input);
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&piece);
+    EXPECT_EQ("text", piece);
+  }
+}
+
+TEST(QuicheTextUtilsTest, HexDump) {
+  // Verify output for empty input.
+  EXPECT_EQ("", quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("")));
+  // Verify output of the HexDump method is as expected.
+  char packet[] = {
+      0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x51, 0x55, 0x49, 0x43, 0x21,
+      0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+      0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x6c,
+      0x6f, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74,
+      0x6f, 0x20, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69,
+      0x70, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x6f, 0x66,
+      0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x01, 0x02, 0x03, 0x00,
+  };
+  EXPECT_EQ(
+      quiche::QuicheTextUtils::HexDump(packet),
+      "0x0000:  4865 6c6c 6f2c 2051 5549 4321 2054 6869  Hello,.QUIC!.Thi\n"
+      "0x0010:  7320 7374 7269 6e67 2073 686f 756c 6420  s.string.should.\n"
+      "0x0020:  6265 206c 6f6e 6720 656e 6f75 6768 2074  be.long.enough.t\n"
+      "0x0030:  6f20 7370 616e 206d 756c 7469 706c 6520  o.span.multiple.\n"
+      "0x0040:  6c69 6e65 7320 6f66 206f 7574 7075 742e  lines.of.output.\n"
+      "0x0050:  0102 03                                  ...\n");
+  // Verify that 0x21 and 0x7e are printable, 0x20 and 0x7f are not.
+  EXPECT_EQ(
+      "0x0000:  2021 7e7f                                .!~.\n",
+      quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("20217e7f")));
+  // Verify that values above numeric_limits<unsigned char>::max() are formatted
+  // properly on platforms where char is unsigned.
+  EXPECT_EQ("0x0000:  90aa ff                                  ...\n",
+            quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("90aaff")));
+}
+
+TEST(QuicheTextUtilsTest, Base64Encode) {
+  std::string output;
+  std::string input = "Hello";
+  quiche::QuicheTextUtils::Base64Encode(
+      reinterpret_cast<const uint8_t*>(input.data()), input.length(), &output);
+  EXPECT_EQ("SGVsbG8", output);
+
+  input =
+      "Hello, QUIC! This string should be long enough to span"
+      "multiple lines of output\n";
+  quiche::QuicheTextUtils::Base64Encode(
+      reinterpret_cast<const uint8_t*>(input.data()), input.length(), &output);
+  EXPECT_EQ(
+      "SGVsbG8sIFFVSUMhIFRoaXMgc3RyaW5nIHNob3VsZCBiZSBsb25n"
+      "IGVub3VnaCB0byBzcGFubXVsdGlwbGUgbGluZXMgb2Ygb3V0cHV0Cg",
+      output);
+}
+
+TEST(QuicheTextUtilsTest, ContainsUpperCase) {
+  EXPECT_FALSE(quiche::QuicheTextUtils::ContainsUpperCase("abc"));
+  EXPECT_FALSE(quiche::QuicheTextUtils::ContainsUpperCase(""));
+  EXPECT_FALSE(quiche::QuicheTextUtils::ContainsUpperCase("123"));
+  EXPECT_TRUE(quiche::QuicheTextUtils::ContainsUpperCase("ABC"));
+  EXPECT_TRUE(quiche::QuicheTextUtils::ContainsUpperCase("aBc"));
+}
+
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/simple_buffer_allocator.cc b/quiche/common/simple_buffer_allocator.cc
new file mode 100644
index 0000000..b2726ed
--- /dev/null
+++ b/quiche/common/simple_buffer_allocator.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quiche {
+
+char* SimpleBufferAllocator::New(size_t size) {
+  return new char[size];
+}
+
+char* SimpleBufferAllocator::New(size_t size, bool /* flag_enable */) {
+  return New(size);
+}
+
+void SimpleBufferAllocator::Delete(char* buffer) {
+  delete[] buffer;
+}
+
+}  // namespace quiche
diff --git a/quiche/common/simple_buffer_allocator.h b/quiche/common/simple_buffer_allocator.h
new file mode 100644
index 0000000..eb98196
--- /dev/null
+++ b/quiche/common/simple_buffer_allocator.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_SIMPLE_BUFFER_ALLOCATOR_H_
+#define QUICHE_COMMON_QUICHE_SIMPLE_BUFFER_ALLOCATOR_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quiche {
+
+// Provides buffer allocation using operators new[] and delete[] on char arrays.
+// Note that some of the QUICHE code relies on this being the case for deleting
+// new[]-allocated arrays from elsewhere.
+class QUICHE_EXPORT_PRIVATE SimpleBufferAllocator
+    : public QuicheBufferAllocator {
+ public:
+  static SimpleBufferAllocator* Get() {
+    static SimpleBufferAllocator* singleton = new SimpleBufferAllocator();
+    return singleton;
+  }
+
+  char* New(size_t size) override;
+  char* New(size_t size, bool flag_enable) override;
+  void Delete(char* buffer) override;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_SIMPLE_BUFFER_ALLOCATOR_H_
diff --git a/quiche/common/simple_buffer_allocator_test.cc b/quiche/common/simple_buffer_allocator_test.cc
new file mode 100644
index 0000000..c23d6b7
--- /dev/null
+++ b/quiche/common/simple_buffer_allocator_test.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/simple_buffer_allocator.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+TEST(SimpleBufferAllocatorTest, NewDelete) {
+  SimpleBufferAllocator alloc;
+  char* buf = alloc.New(4);
+  EXPECT_NE(nullptr, buf);
+  alloc.Delete(buf);
+}
+
+TEST(SimpleBufferAllocatorTest, DeleteNull) {
+  SimpleBufferAllocator alloc;
+  alloc.Delete(nullptr);
+}
+
+TEST(SimpleBufferAllocatorTest, MoveBuffersConstructor) {
+  SimpleBufferAllocator alloc;
+  QuicheBuffer buffer1(&alloc, 16);
+
+  EXPECT_NE(buffer1.data(), nullptr);
+  EXPECT_EQ(buffer1.size(), 16u);
+
+  QuicheBuffer buffer2(std::move(buffer1));
+  EXPECT_EQ(buffer1.data(), nullptr);  // NOLINT(bugprone-use-after-move)
+  EXPECT_EQ(buffer1.size(), 0u);
+  EXPECT_NE(buffer2.data(), nullptr);
+  EXPECT_EQ(buffer2.size(), 16u);
+}
+
+TEST(SimpleBufferAllocatorTest, MoveBuffersAssignment) {
+  SimpleBufferAllocator alloc;
+  QuicheBuffer buffer1(&alloc, 16);
+  QuicheBuffer buffer2;
+
+  EXPECT_NE(buffer1.data(), nullptr);
+  EXPECT_EQ(buffer1.size(), 16u);
+  EXPECT_EQ(buffer2.data(), nullptr);
+  EXPECT_EQ(buffer2.size(), 0u);
+
+  buffer2 = std::move(buffer1);
+  EXPECT_EQ(buffer1.data(), nullptr);  // NOLINT(bugprone-use-after-move)
+  EXPECT_EQ(buffer1.size(), 0u);
+  EXPECT_NE(buffer2.data(), nullptr);
+  EXPECT_EQ(buffer2.size(), 16u);
+}
+
+TEST(SimpleBufferAllocatorTest, CopyBuffer) {
+  SimpleBufferAllocator alloc;
+  const absl::string_view original = "Test string";
+  QuicheBuffer copy = QuicheBuffer::Copy(&alloc, original);
+  EXPECT_EQ(copy.AsStringView(), original);
+}
+
+}  // namespace
+}  // namespace quiche
diff --git a/quiche/common/structured_headers.cc b/quiche/common/structured_headers.cc
new file mode 100644
index 0000000..6aca4d0
--- /dev/null
+++ b/quiche/common/structured_headers.cc
@@ -0,0 +1,909 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/structured_headers.h"
+
+#include <cmath>
+#include <string>
+#include <utility>
+
+#include "absl/algorithm/container.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/ascii.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+namespace structured_headers {
+
+namespace {
+
+#define DIGIT "0123456789"
+#define LCALPHA "abcdefghijklmnopqrstuvwxyz"
+#define UCALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define TCHAR DIGIT LCALPHA UCALPHA "!#$%&'*+-.^_`|~"
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.9
+constexpr char kTokenChars09[] = DIGIT UCALPHA LCALPHA "_-.:%*/";
+// https://www.rfc-editor.org/rfc/rfc8941.html#section-3.3.4
+constexpr char kTokenChars[] = TCHAR ":/";
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.1
+constexpr char kKeyChars09[] = DIGIT LCALPHA "_-";
+// https://www.rfc-editor.org/rfc/rfc8941.html#section-3.1.2
+constexpr char kKeyChars[] = DIGIT LCALPHA "_-.*";
+constexpr char kSP[] = " ";
+constexpr char kOWS[] = " \t";
+#undef DIGIT
+#undef LCALPHA
+#undef UCALPHA
+
+// https://www.rfc-editor.org/rfc/rfc8941.html#section-3.3.1
+constexpr int64_t kMaxInteger = 999'999'999'999'999L;
+constexpr int64_t kMinInteger = -999'999'999'999'999L;
+
+// Smallest value which is too large for an sh-decimal. This is the smallest
+// double which will round up to 1e12 when serialized, which exceeds the range
+// for sh-decimal. Any float less than this should round down. This behaviour is
+// verified by unit tests.
+constexpr double kTooLargeDecimal = 1e12 - 0.0005;
+
+// Removes characters in remove from the beginning of s.
+void StripLeft(absl::string_view& s, absl::string_view remove) {
+  size_t i = 0;
+  while (i < s.size() && memchr(remove.data(), s[i], remove.size())) {
+    ++i;
+  }
+  if (i > 0) s.remove_prefix(i);
+}
+
+// Parser for (a subset of) Structured Headers for HTTP defined in [SH09] and
+// [RFC8941]. [SH09] compatibility is retained for use by Web Packaging, and can
+// be removed once that spec is updated, and users have migrated to new headers.
+// [SH09] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09
+// [RFC8941] https://www.rfc-editor.org/rfc/rfc8941.html
+class StructuredHeaderParser {
+ public:
+  enum DraftVersion {
+    kDraft09,
+    kFinal,
+  };
+  explicit StructuredHeaderParser(absl::string_view str, DraftVersion version)
+      : input_(str), version_(version) {
+    // [SH09] 4.2 Step 1.
+    // Discard any leading OWS from input_string.
+    // [RFC8941] 4.2 Step 2.
+    // Discard any leading SP characters from input_string.
+    SkipWhitespaces();
+  }
+  StructuredHeaderParser(const StructuredHeaderParser&) = delete;
+  StructuredHeaderParser& operator=(const StructuredHeaderParser&) = delete;
+
+  // Callers should call this after ReadSomething(), to check if parser has
+  // consumed all the input successfully.
+  bool FinishParsing() {
+    // [SH09] 4.2 Step 7.
+    // Discard any leading OWS from input_string.
+    // [RFC8941] 4.2 Step 6.
+    // Discard any leading SP characters from input_string.
+    SkipWhitespaces();
+    // [SH09] 4.2 Step 8. [RFC8941] 4.2 Step 7.
+    // If input_string is not empty, fail parsing.
+    return input_.empty();
+  }
+
+  // Parses a List of Lists ([SH09] 4.2.4).
+  absl::optional<ListOfLists> ReadListOfLists() {
+    QUICHE_CHECK_EQ(version_, kDraft09);
+    ListOfLists result;
+    while (true) {
+      std::vector<Item> inner_list;
+      while (true) {
+        absl::optional<Item> item(ReadBareItem());
+        if (!item) return absl::nullopt;
+        inner_list.push_back(std::move(*item));
+        SkipWhitespaces();
+        if (!ConsumeChar(';')) break;
+        SkipWhitespaces();
+      }
+      result.push_back(std::move(inner_list));
+      SkipWhitespaces();
+      if (!ConsumeChar(',')) break;
+      SkipWhitespaces();
+    }
+    return result;
+  }
+
+  // Parses a List ([RFC8941] 4.2.1).
+  absl::optional<List> ReadList() {
+    QUICHE_CHECK_EQ(version_, kFinal);
+    List members;
+    while (!input_.empty()) {
+      absl::optional<ParameterizedMember> member(ReadItemOrInnerList());
+      if (!member) return absl::nullopt;
+      members.push_back(std::move(*member));
+      SkipOWS();
+      if (input_.empty()) break;
+      if (!ConsumeChar(',')) return absl::nullopt;
+      SkipOWS();
+      if (input_.empty()) return absl::nullopt;
+    }
+    return members;
+  }
+
+  // Parses an Item ([RFC8941] 4.2.3).
+  absl::optional<ParameterizedItem> ReadItem() {
+    absl::optional<Item> item = ReadBareItem();
+    if (!item) return absl::nullopt;
+    absl::optional<Parameters> parameters = ReadParameters();
+    if (!parameters) return absl::nullopt;
+    return ParameterizedItem(std::move(*item), std::move(*parameters));
+  }
+
+  // Parses a bare Item ([RFC8941] 4.2.3.1, though this is also the algorithm
+  // for parsing an Item from [SH09] 4.2.7).
+  absl::optional<Item> ReadBareItem() {
+    if (input_.empty()) {
+      DVLOG(1) << "ReadBareItem: unexpected EOF";
+      return absl::nullopt;
+    }
+    switch (input_.front()) {
+      case '"':
+        return ReadString();
+      case '*':
+        if (version_ == kDraft09) return ReadByteSequence();
+        return ReadToken();
+      case ':':
+        if (version_ == kFinal) return ReadByteSequence();
+        return absl::nullopt;
+      case '?':
+        return ReadBoolean();
+      default:
+        if (input_.front() == '-' || absl::ascii_isdigit(input_.front()))
+          return ReadNumber();
+        if (absl::ascii_isalpha(input_.front())) return ReadToken();
+        return absl::nullopt;
+    }
+  }
+
+  // Parses a Dictionary ([RFC8941] 4.2.2).
+  absl::optional<Dictionary> ReadDictionary() {
+    QUICHE_CHECK_EQ(version_, kFinal);
+    Dictionary members;
+    while (!input_.empty()) {
+      absl::optional<std::string> key(ReadKey());
+      if (!key) return absl::nullopt;
+      absl::optional<ParameterizedMember> member;
+      if (ConsumeChar('=')) {
+        member = ReadItemOrInnerList();
+        if (!member) return absl::nullopt;
+      } else {
+        absl::optional<Parameters> parameters;
+        parameters = ReadParameters();
+        if (!parameters) return absl::nullopt;
+        member = ParameterizedMember{Item(true), std::move(*parameters)};
+      }
+      members[*key] = std::move(*member);
+      SkipOWS();
+      if (input_.empty()) break;
+      if (!ConsumeChar(',')) return absl::nullopt;
+      SkipOWS();
+      if (input_.empty()) return absl::nullopt;
+    }
+    return members;
+  }
+
+  // Parses a Parameterised List ([SH09] 4.2.5).
+  absl::optional<ParameterisedList> ReadParameterisedList() {
+    QUICHE_CHECK_EQ(version_, kDraft09);
+    ParameterisedList items;
+    while (true) {
+      absl::optional<ParameterisedIdentifier> item =
+          ReadParameterisedIdentifier();
+      if (!item) return absl::nullopt;
+      items.push_back(std::move(*item));
+      SkipWhitespaces();
+      if (!ConsumeChar(',')) return items;
+      SkipWhitespaces();
+    }
+  }
+
+ private:
+  // Parses a Parameterised Identifier ([SH09] 4.2.6).
+  absl::optional<ParameterisedIdentifier> ReadParameterisedIdentifier() {
+    QUICHE_CHECK_EQ(version_, kDraft09);
+    absl::optional<Item> primary_identifier = ReadToken();
+    if (!primary_identifier) return absl::nullopt;
+
+    ParameterisedIdentifier::Parameters parameters;
+
+    SkipWhitespaces();
+    while (ConsumeChar(';')) {
+      SkipWhitespaces();
+
+      absl::optional<std::string> name = ReadKey();
+      if (!name) return absl::nullopt;
+
+      Item value;
+      if (ConsumeChar('=')) {
+        auto item = ReadBareItem();
+        if (!item) return absl::nullopt;
+        value = std::move(*item);
+      }
+      if (!parameters.emplace(*name, value).second) {
+        DVLOG(1) << "ReadParameterisedIdentifier: duplicated parameter: "
+                 << *name;
+        return absl::nullopt;
+      }
+      SkipWhitespaces();
+    }
+    return ParameterisedIdentifier(std::move(*primary_identifier),
+                                   std::move(parameters));
+  }
+
+  // Parses an Item or Inner List ([RFC8941] 4.2.1.1).
+  absl::optional<ParameterizedMember> ReadItemOrInnerList() {
+    QUICHE_CHECK_EQ(version_, kFinal);
+    std::vector<Item> member;
+    bool member_is_inner_list = (!input_.empty() && input_.front() == '(');
+    if (member_is_inner_list) {
+      return ReadInnerList();
+    } else {
+      auto item = ReadItem();
+      if (!item) return absl::nullopt;
+      return ParameterizedMember(std::move(item->item),
+                                 std::move(item->params));
+    }
+  }
+
+  // Parses Parameters ([RFC8941] 4.2.3.2)
+  absl::optional<Parameters> ReadParameters() {
+    Parameters parameters;
+    absl::flat_hash_set<std::string> keys;
+
+    while (ConsumeChar(';')) {
+      SkipWhitespaces();
+
+      absl::optional<std::string> name = ReadKey();
+      if (!name) return absl::nullopt;
+      bool is_duplicate_key = !keys.insert(*name).second;
+
+      Item value{true};
+      if (ConsumeChar('=')) {
+        auto item = ReadBareItem();
+        if (!item) return absl::nullopt;
+        value = std::move(*item);
+      }
+      if (is_duplicate_key) {
+        for (auto& param : parameters) {
+          if (param.first == name) {
+            param.second = std::move(value);
+            break;
+          }
+        }
+      } else {
+        parameters.emplace_back(std::move(*name), std::move(value));
+      }
+    }
+    return parameters;
+  }
+
+  // Parses an Inner List ([RFC8941] 4.2.1.2).
+  absl::optional<ParameterizedMember> ReadInnerList() {
+    QUICHE_CHECK_EQ(version_, kFinal);
+    if (!ConsumeChar('(')) return absl::nullopt;
+    std::vector<ParameterizedItem> inner_list;
+    while (true) {
+      SkipWhitespaces();
+      if (ConsumeChar(')')) {
+        absl::optional<Parameters> parameters;
+        parameters = ReadParameters();
+        if (!parameters) return absl::nullopt;
+        return ParameterizedMember(std::move(inner_list), true,
+                                   std::move(*parameters));
+      }
+      auto item = ReadItem();
+      if (!item) return absl::nullopt;
+      inner_list.push_back(std::move(*item));
+      if (input_.empty() || (input_.front() != ' ' && input_.front() != ')'))
+        return absl::nullopt;
+    }
+    QUICHE_NOTREACHED();
+    return absl::nullopt;
+  }
+
+  // Parses a Key ([SH09] 4.2.2, [RFC8941] 4.2.3.3).
+  absl::optional<std::string> ReadKey() {
+    if (version_ == kDraft09) {
+      if (input_.empty() || !absl::ascii_islower(input_.front())) {
+        LogParseError("ReadKey", "lcalpha");
+        return absl::nullopt;
+      }
+    } else {
+      if (input_.empty() ||
+          (!absl::ascii_islower(input_.front()) && input_.front() != '*')) {
+        LogParseError("ReadKey", "lcalpha | *");
+        return absl::nullopt;
+      }
+    }
+    const char* allowed_chars =
+        (version_ == kDraft09 ? kKeyChars09 : kKeyChars);
+    size_t len = input_.find_first_not_of(allowed_chars);
+    if (len == absl::string_view::npos) len = input_.size();
+    std::string key(input_.substr(0, len));
+    input_.remove_prefix(len);
+    return key;
+  }
+
+  // Parses a Token ([SH09] 4.2.10, [RFC8941] 4.2.6).
+  absl::optional<Item> ReadToken() {
+    if (input_.empty() ||
+        !(absl::ascii_isalpha(input_.front()) || input_.front() == '*')) {
+      LogParseError("ReadToken", "ALPHA");
+      return absl::nullopt;
+    }
+    size_t len = input_.find_first_not_of(version_ == kDraft09 ? kTokenChars09
+                                                               : kTokenChars);
+    if (len == absl::string_view::npos) len = input_.size();
+    std::string token(input_.substr(0, len));
+    input_.remove_prefix(len);
+    return Item(std::move(token), Item::kTokenType);
+  }
+
+  // Parses a Number ([SH09] 4.2.8, [RFC8941] 4.2.4).
+  absl::optional<Item> ReadNumber() {
+    bool is_negative = ConsumeChar('-');
+    bool is_decimal = false;
+    size_t decimal_position = 0;
+    size_t i = 0;
+    for (; i < input_.size(); ++i) {
+      if (i > 0 && input_[i] == '.' && !is_decimal) {
+        is_decimal = true;
+        decimal_position = i;
+        continue;
+      }
+      if (!absl::ascii_isdigit(input_[i])) break;
+    }
+    if (i == 0) {
+      LogParseError("ReadNumber", "DIGIT");
+      return absl::nullopt;
+    }
+    if (!is_decimal) {
+      // [RFC8941] restricts the range of integers further.
+      if (version_ == kFinal && i > 15) {
+        LogParseError("ReadNumber", "integer too long");
+        return absl::nullopt;
+      }
+    } else {
+      if (version_ != kFinal && i > 16) {
+        LogParseError("ReadNumber", "float too long");
+        return absl::nullopt;
+      }
+      if (version_ == kFinal && decimal_position > 12) {
+        LogParseError("ReadNumber", "decimal too long");
+        return absl::nullopt;
+      }
+      if (i - decimal_position > (version_ == kFinal ? 4 : 7)) {
+        LogParseError("ReadNumber", "too many digits after decimal");
+        return absl::nullopt;
+      }
+      if (i == decimal_position) {
+        LogParseError("ReadNumber", "no digits after decimal");
+        return absl::nullopt;
+      }
+    }
+    std::string output_number_string(input_.substr(0, i));
+    input_.remove_prefix(i);
+
+    if (is_decimal) {
+      // Convert to a 64-bit double, and return if the conversion is
+      // successful.
+      double f;
+      if (!absl::SimpleAtod(output_number_string, &f)) return absl::nullopt;
+      return Item(is_negative ? -f : f);
+    } else {
+      // Convert to a 64-bit signed integer, and return if the conversion is
+      // successful.
+      int64_t n;
+      if (!absl::SimpleAtoi(output_number_string, &n)) return absl::nullopt;
+      QUICHE_CHECK(version_ != kFinal ||
+                   (n <= kMaxInteger && n >= kMinInteger));
+      return Item(is_negative ? -n : n);
+    }
+  }
+
+  // Parses a String ([SH09] 4.2.9, [RFC8941] 4.2.5).
+  absl::optional<Item> ReadString() {
+    std::string s;
+    if (!ConsumeChar('"')) {
+      LogParseError("ReadString", "'\"'");
+      return absl::nullopt;
+    }
+    while (!ConsumeChar('"')) {
+      size_t i = 0;
+      for (; i < input_.size(); ++i) {
+        if (!absl::ascii_isprint(input_[i])) {
+          DVLOG(1) << "ReadString: non printable-ASCII character";
+          return absl::nullopt;
+        }
+        if (input_[i] == '"' || input_[i] == '\\') break;
+      }
+      if (i == input_.size()) {
+        DVLOG(1) << "ReadString: missing closing '\"'";
+        return absl::nullopt;
+      }
+      s.append(std::string(input_.substr(0, i)));
+      input_.remove_prefix(i);
+      if (ConsumeChar('\\')) {
+        if (input_.empty()) {
+          DVLOG(1) << "ReadString: backslash at string end";
+          return absl::nullopt;
+        }
+        if (input_[0] != '"' && input_[0] != '\\') {
+          DVLOG(1) << "ReadString: invalid escape";
+          return absl::nullopt;
+        }
+        s.push_back(input_.front());
+        input_.remove_prefix(1);
+      }
+    }
+    return s;
+  }
+
+  // Parses a Byte Sequence ([SH09] 4.2.11, [RFC8941] 4.2.7).
+  absl::optional<Item> ReadByteSequence() {
+    char delimiter = (version_ == kDraft09 ? '*' : ':');
+    if (!ConsumeChar(delimiter)) {
+      LogParseError("ReadByteSequence", "delimiter");
+      return absl::nullopt;
+    }
+    size_t len = input_.find(delimiter);
+    if (len == absl::string_view::npos) {
+      DVLOG(1) << "ReadByteSequence: missing closing delimiter";
+      return absl::nullopt;
+    }
+    std::string base64(input_.substr(0, len));
+    // Append the necessary padding characters.
+    base64.resize((base64.size() + 3) / 4 * 4, '=');
+
+    std::string binary;
+    if (!absl::Base64Unescape(base64, &binary)) {
+      DVLOG(1) << "ReadByteSequence: failed to decode base64: " << base64;
+      return absl::nullopt;
+    }
+    input_.remove_prefix(len);
+    ConsumeChar(delimiter);
+    return Item(std::move(binary), Item::kByteSequenceType);
+  }
+
+  // Parses a Boolean ([RFC8941] 4.2.8).
+  // Note that this only parses ?0 and ?1 forms from SH version 10+, not the
+  // previous ?F and ?T, which were not needed by any consumers of SH version 9.
+  absl::optional<Item> ReadBoolean() {
+    if (!ConsumeChar('?')) {
+      LogParseError("ReadBoolean", "'?'");
+      return absl::nullopt;
+    }
+    if (ConsumeChar('1')) {
+      return Item(true);
+    }
+    if (ConsumeChar('0')) {
+      return Item(false);
+    }
+    return absl::nullopt;
+  }
+
+  // There are several points in the specs where the handling of whitespace
+  // differs between Draft 9 and the final RFC. In those cases, Draft 9 allows
+  // any OWS character, while the RFC allows only a U+0020 SPACE.
+  void SkipWhitespaces() {
+    if (version_ == kDraft09) {
+      StripLeft(input_, kOWS);
+    } else {
+      StripLeft(input_, kSP);
+    }
+  }
+
+  void SkipOWS() { StripLeft(input_, kOWS); }
+
+  bool ConsumeChar(char expected) {
+    if (!input_.empty() && input_.front() == expected) {
+      input_.remove_prefix(1);
+      return true;
+    }
+    return false;
+  }
+
+  void LogParseError(const char* func, const char* expected) {
+    DVLOG(1) << func << ": " << expected << " expected, got "
+             << (input_.empty() ? "EOS"
+                                : "'" + std::string(input_.substr(0, 1)) + "'");
+  }
+
+  absl::string_view input_;
+  DraftVersion version_;
+};
+
+// Serializer for (a subset of) Structured Field Values for HTTP defined in
+// [RFC8941]. Note that this serializer does not attempt to support [SH09].
+class StructuredHeaderSerializer {
+ public:
+  StructuredHeaderSerializer() = default;
+  ~StructuredHeaderSerializer() = default;
+  StructuredHeaderSerializer(const StructuredHeaderSerializer&) = delete;
+  StructuredHeaderSerializer& operator=(const StructuredHeaderSerializer&) =
+      delete;
+
+  std::string Output() { return output_.str(); }
+
+  // Serializes a List ([RFC8941] 4.1.1).
+  bool WriteList(const List& value) {
+    bool first = true;
+    for (const auto& member : value) {
+      if (!first) output_ << ", ";
+      if (!WriteParameterizedMember(member)) return false;
+      first = false;
+    }
+    return true;
+  }
+
+  // Serializes an Item ([RFC8941] 4.1.3).
+  bool WriteItem(const ParameterizedItem& value) {
+    if (!WriteBareItem(value.item)) return false;
+    return WriteParameters(value.params);
+  }
+
+  // Serializes an Item ([RFC8941] 4.1.3).
+  bool WriteBareItem(const Item& value) {
+    if (value.is_string()) {
+      // Serializes a String ([RFC8941] 4.1.6).
+      output_ << "\"";
+      for (const char& c : value.GetString()) {
+        if (!absl::ascii_isprint(c)) return false;
+        if (c == '\\' || c == '\"') output_ << "\\";
+        output_ << c;
+      }
+      output_ << "\"";
+      return true;
+    }
+    if (value.is_token()) {
+      // Serializes a Token ([RFC8941] 4.1.7).
+      if (value.GetString().empty() ||
+          !(absl::ascii_isalpha(value.GetString().front()) ||
+            value.GetString().front() == '*'))
+        return false;
+      if (value.GetString().find_first_not_of(kTokenChars) != std::string::npos)
+        return false;
+      output_ << value.GetString();
+      return true;
+    }
+    if (value.is_byte_sequence()) {
+      // Serializes a Byte Sequence ([RFC8941] 4.1.8).
+      output_ << ":";
+      output_ << absl::Base64Escape(value.GetString());
+      output_ << ":";
+      return true;
+    }
+    if (value.is_integer()) {
+      // Serializes an Integer ([RFC8941] 4.1.4).
+      if (value.GetInteger() > kMaxInteger || value.GetInteger() < kMinInteger)
+        return false;
+      output_ << value.GetInteger();
+      return true;
+    }
+    if (value.is_decimal()) {
+      // Serializes a Decimal ([RFC8941] 4.1.5).
+      double decimal_value = value.GetDecimal();
+      if (!std::isfinite(decimal_value) ||
+          fabs(decimal_value) >= kTooLargeDecimal)
+        return false;
+
+      // Handle sign separately to simplify the rest of the formatting.
+      if (decimal_value < 0) output_ << "-";
+      // Unconditionally take absolute value to ensure that -0 is serialized as
+      // "0.0", with no negative sign, as required by spec. (4.1.5, step 2).
+      decimal_value = fabs(decimal_value);
+      double remainder = fmod(decimal_value, 0.002);
+      if (remainder == 0.0005) {
+        // Value ended in exactly 0.0005, 0.0025, 0.0045, etc. Round down.
+        decimal_value -= 0.0005;
+      } else if (remainder == 0.0015) {
+        // Value ended in exactly 0.0015, 0.0035, 0,0055, etc. Round up.
+        decimal_value += 0.0005;
+      } else {
+        // Standard rounding will work in all other cases.
+        decimal_value = round(decimal_value * 1000.0) / 1000.0;
+      }
+
+      // Use standard library functions to write the decimal, and then truncate
+      // if necessary to conform to spec.
+
+      // Maximum is 12 integer digits, one decimal point, three fractional
+      // digits, and a null terminator.
+      char buffer[17];
+      absl::SNPrintF(buffer, std::size(buffer), "%#.3f", decimal_value);
+
+      // Strip any trailing 0s after the decimal point, but leave at least one
+      // digit after it in all cases. (So 1.230 becomes 1.23, but 1.000 becomes
+      // 1.0.)
+      absl::string_view formatted_number(buffer);
+      auto truncate_index = formatted_number.find_last_not_of('0');
+      if (formatted_number[truncate_index] == '.') truncate_index++;
+      output_ << formatted_number.substr(0, truncate_index + 1);
+      return true;
+    }
+    if (value.is_boolean()) {
+      // Serializes a Boolean ([RFC8941] 4.1.9).
+      output_ << (value.GetBoolean() ? "?1" : "?0");
+      return true;
+    }
+    return false;
+  }
+
+  // Serializes a Dictionary ([RFC8941] 4.1.2).
+  bool WriteDictionary(const Dictionary& value) {
+    bool first = true;
+    for (const auto& [dict_key, dict_value] : value) {
+      if (!first) output_ << ", ";
+      if (!WriteKey(dict_key)) return false;
+      first = false;
+      if (!dict_value.member_is_inner_list && !dict_value.member.empty() &&
+          dict_value.member.front().item.is_boolean() &&
+          dict_value.member.front().item.GetBoolean()) {
+        if (!WriteParameters(dict_value.params)) return false;
+      } else {
+        output_ << "=";
+        if (!WriteParameterizedMember(dict_value)) return false;
+      }
+    }
+    return true;
+  }
+
+ private:
+  bool WriteParameterizedMember(const ParameterizedMember& value) {
+    // Serializes a parameterized member ([RFC8941] 4.1.1).
+    if (value.member_is_inner_list) {
+      if (!WriteInnerList(value.member)) return false;
+    } else {
+      QUICHE_CHECK_EQ(value.member.size(), 1UL);
+      if (!WriteItem(value.member[0])) return false;
+    }
+    return WriteParameters(value.params);
+  }
+
+  bool WriteInnerList(const std::vector<ParameterizedItem>& value) {
+    // Serializes an inner list ([RFC8941] 4.1.1.1).
+    output_ << "(";
+    bool first = true;
+    for (const ParameterizedItem& member : value) {
+      if (!first) output_ << " ";
+      if (!WriteItem(member)) return false;
+      first = false;
+    }
+    output_ << ")";
+    return true;
+  }
+
+  bool WriteParameters(const Parameters& value) {
+    // Serializes a parameter list ([RFC8941] 4.1.1.2).
+    for (const auto& param_name_and_value : value) {
+      const std::string& param_name = param_name_and_value.first;
+      const Item& param_value = param_name_and_value.second;
+      output_ << ";";
+      if (!WriteKey(param_name)) return false;
+      if (!param_value.is_null()) {
+        if (param_value.is_boolean() && param_value.GetBoolean()) continue;
+        output_ << "=";
+        if (!WriteBareItem(param_value)) return false;
+      }
+    }
+    return true;
+  }
+
+  bool WriteKey(const std::string& value) {
+    // Serializes a Key ([RFC8941] 4.1.1.3).
+    if (value.empty()) return false;
+    if (value.find_first_not_of(kKeyChars) != std::string::npos) return false;
+    if (!absl::ascii_islower(value[0]) && value[0] != '*') return false;
+    output_ << value;
+    return true;
+  }
+
+  std::ostringstream output_;
+};
+
+}  // namespace
+
+Item::Item() {}
+Item::Item(const std::string& value, Item::ItemType type)
+    : type_(type), string_value_(value) {}
+Item::Item(std::string&& value, Item::ItemType type)
+    : type_(type), string_value_(std::move(value)) {
+  QUICHE_CHECK(type_ == kStringType || type_ == kTokenType ||
+               type_ == kByteSequenceType);
+}
+Item::Item(const char* value, Item::ItemType type)
+    : Item(std::string(value), type) {}
+Item::Item(int64_t value) : type_(kIntegerType), integer_value_(value) {}
+Item::Item(double value) : type_(kDecimalType), decimal_value_(value) {}
+Item::Item(bool value) : type_(kBooleanType), boolean_value_(value) {}
+
+bool operator==(const Item& lhs, const Item& rhs) {
+  if (lhs.type_ != rhs.type_) return false;
+  switch (lhs.type_) {
+    case Item::kNullType:
+      return true;
+    case Item::kStringType:
+    case Item::kTokenType:
+    case Item::kByteSequenceType:
+      return lhs.string_value_ == rhs.string_value_;
+    case Item::kIntegerType:
+      return lhs.integer_value_ == rhs.integer_value_;
+    case Item::kDecimalType:
+      return lhs.decimal_value_ == rhs.decimal_value_;
+    case Item::kBooleanType:
+      return lhs.boolean_value_ == rhs.boolean_value_;
+  }
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+ParameterizedItem::ParameterizedItem(const ParameterizedItem&) = default;
+ParameterizedItem& ParameterizedItem::operator=(const ParameterizedItem&) =
+    default;
+ParameterizedItem::ParameterizedItem(Item id, const Parameters& ps)
+    : item(std::move(id)), params(ps) {}
+ParameterizedItem::~ParameterizedItem() = default;
+
+ParameterizedMember::ParameterizedMember() = default;
+ParameterizedMember::ParameterizedMember(const ParameterizedMember&) = default;
+ParameterizedMember& ParameterizedMember::operator=(
+    const ParameterizedMember&) = default;
+ParameterizedMember::ParameterizedMember(std::vector<ParameterizedItem> id,
+                                         bool member_is_inner_list,
+                                         const Parameters& ps)
+    : member(std::move(id)),
+      member_is_inner_list(member_is_inner_list),
+      params(ps) {}
+ParameterizedMember::ParameterizedMember(std::vector<ParameterizedItem> id,
+                                         const Parameters& ps)
+    : member(std::move(id)), member_is_inner_list(true), params(ps) {}
+ParameterizedMember::ParameterizedMember(Item id, const Parameters& ps)
+    : member({{std::move(id), {}}}), member_is_inner_list(false), params(ps) {}
+ParameterizedMember::~ParameterizedMember() = default;
+
+ParameterisedIdentifier::ParameterisedIdentifier(
+    const ParameterisedIdentifier&) = default;
+ParameterisedIdentifier& ParameterisedIdentifier::operator=(
+    const ParameterisedIdentifier&) = default;
+ParameterisedIdentifier::ParameterisedIdentifier(Item id, const Parameters& ps)
+    : identifier(std::move(id)), params(ps) {}
+ParameterisedIdentifier::~ParameterisedIdentifier() = default;
+
+Dictionary::Dictionary() = default;
+Dictionary::Dictionary(const Dictionary&) = default;
+Dictionary::Dictionary(std::vector<DictionaryMember> members)
+    : members_(std::move(members)) {}
+Dictionary::~Dictionary() = default;
+std::vector<DictionaryMember>::iterator Dictionary::begin() {
+  return members_.begin();
+}
+std::vector<DictionaryMember>::const_iterator Dictionary::begin() const {
+  return members_.begin();
+}
+std::vector<DictionaryMember>::iterator Dictionary::end() {
+  return members_.end();
+}
+std::vector<DictionaryMember>::const_iterator Dictionary::end() const {
+  return members_.end();
+}
+ParameterizedMember& Dictionary::operator[](std::size_t idx) {
+  return members_[idx].second;
+}
+const ParameterizedMember& Dictionary::operator[](std::size_t idx) const {
+  return members_[idx].second;
+}
+ParameterizedMember& Dictionary::at(std::size_t idx) { return (*this)[idx]; }
+const ParameterizedMember& Dictionary::at(std::size_t idx) const {
+  return (*this)[idx];
+}
+ParameterizedMember& Dictionary::operator[](absl::string_view key) {
+  auto it = absl::c_find_if(
+      members_, [key](const auto& member) { return member.first == key; });
+  if (it != members_.end()) return it->second;
+  members_.push_back({std::string(key), ParameterizedMember()});
+  return members_.back().second;
+}
+ParameterizedMember& Dictionary::at(absl::string_view key) {
+  auto it = absl::c_find_if(
+      members_, [key](const auto& member) { return member.first == key; });
+  QUICHE_CHECK(it != members_.end()) << "Provided key not found in dictionary";
+  return it->second;
+}
+const ParameterizedMember& Dictionary::at(absl::string_view key) const {
+  auto it = absl::c_find_if(
+      members_, [key](const auto& member) { return member.first == key; });
+  QUICHE_CHECK(it != members_.end()) << "Provided key not found in dictionary";
+  return it->second;
+}
+bool Dictionary::empty() const { return members_.empty(); }
+std::size_t Dictionary::size() const { return members_.size(); }
+bool Dictionary::contains(absl::string_view key) const {
+  for (auto& member : members_) {
+    if (member.first == key) return true;
+  }
+  return false;
+}
+
+absl::optional<ParameterizedItem> ParseItem(absl::string_view str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
+  absl::optional<ParameterizedItem> item = parser.ReadItem();
+  if (item && parser.FinishParsing()) return item;
+  return absl::nullopt;
+}
+
+absl::optional<Item> ParseBareItem(absl::string_view str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
+  absl::optional<Item> item = parser.ReadBareItem();
+  if (item && parser.FinishParsing()) return item;
+  return absl::nullopt;
+}
+
+absl::optional<ParameterisedList> ParseParameterisedList(
+    absl::string_view str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
+  absl::optional<ParameterisedList> param_list = parser.ReadParameterisedList();
+  if (param_list && parser.FinishParsing()) return param_list;
+  return absl::nullopt;
+}
+
+absl::optional<ListOfLists> ParseListOfLists(absl::string_view str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09);
+  absl::optional<ListOfLists> list_of_lists = parser.ReadListOfLists();
+  if (list_of_lists && parser.FinishParsing()) return list_of_lists;
+  return absl::nullopt;
+}
+
+absl::optional<List> ParseList(absl::string_view str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
+  absl::optional<List> list = parser.ReadList();
+  if (list && parser.FinishParsing()) return list;
+  return absl::nullopt;
+}
+
+absl::optional<Dictionary> ParseDictionary(const absl::string_view& str) {
+  StructuredHeaderParser parser(str, StructuredHeaderParser::kFinal);
+  absl::optional<Dictionary> dictionary = parser.ReadDictionary();
+  if (dictionary && parser.FinishParsing()) return dictionary;
+  return absl::nullopt;
+}
+
+absl::optional<std::string> SerializeItem(const Item& value) {
+  StructuredHeaderSerializer s;
+  if (s.WriteItem(ParameterizedItem(value, {}))) return s.Output();
+  return absl::nullopt;
+}
+
+absl::optional<std::string> SerializeItem(const ParameterizedItem& value) {
+  StructuredHeaderSerializer s;
+  if (s.WriteItem(value)) return s.Output();
+  return absl::nullopt;
+}
+
+absl::optional<std::string> SerializeList(const List& value) {
+  StructuredHeaderSerializer s;
+  if (s.WriteList(value)) return s.Output();
+  return absl::nullopt;
+}
+
+absl::optional<std::string> SerializeDictionary(const Dictionary& value) {
+  StructuredHeaderSerializer s;
+  if (s.WriteDictionary(value)) return s.Output();
+  return absl::nullopt;
+}
+
+}  // namespace structured_headers
+}  // namespace quiche
diff --git a/quiche/common/structured_headers.h b/quiche/common/structured_headers.h
new file mode 100644
index 0000000..6b338a7
--- /dev/null
+++ b/quiche/common/structured_headers.h
@@ -0,0 +1,306 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_STRUCTURED_HEADERS_H_
+#define QUICHE_COMMON_STRUCTURED_HEADERS_H_
+
+#include <algorithm>
+#include <map>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quiche {
+namespace structured_headers {
+
+// This file implements parsing of HTTP structured headers, as defined in
+// RFC8941 (https://www.rfc-editor.org/rfc/rfc8941.html). For compatibility with
+// the shipped implementation of Web Packaging, this file also supports a
+// previous revision of the standard, referred to here as "Draft 9".
+// (https://datatracker.ietf.org/doc/draft-ietf-httpbis-header-structure/09/)
+//
+// The major difference between the two revisions is in the various list
+// formats: Draft 9 describes "parameterised lists" and "lists-of-lists", while
+// the final RFC uses a single "list" syntax, whose members may be inner lists.
+// There should be no ambiguity, however, as the code which calls this parser
+// should be expecting only a single type for a given header.
+//
+// References within the code are tagged with either [SH09] or [RFC8941],
+// depending on which revision they refer to.
+//
+// Currently supported data types are:
+//  Item:
+//   integer: 123
+//   string: "abc"
+//   token: abc
+//   byte sequence: *YWJj*
+//  Parameterised list: abc_123;a=1;b=2; cdef_456, ghi;q="9";r="w"
+//  List-of-lists: "foo";"bar", "baz", "bat"; "one"
+//  List: "foo", "bar", "It was the best of times."
+//        ("foo" "bar"), ("baz"), ("bat" "one"), ()
+//        abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w
+//  Dictionary: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?0
+//
+// Functions are provided to parse each of these, which are intended to be
+// called with the complete value of an HTTP header (that is, any
+// sub-structure will be handled internally by the parser; the exported
+// functions are not intended to be called on partial header strings.) Input
+// values should be ASCII byte strings (non-ASCII characters should not be
+// present in Structured Header values, and will cause the entire header to fail
+// to parse.)
+
+class QUICHE_EXPORT_PRIVATE Item {
+ public:
+  enum ItemType {
+    kNullType,
+    kIntegerType,
+    kDecimalType,
+    kStringType,
+    kTokenType,
+    kByteSequenceType,
+    kBooleanType
+  };
+  Item();
+  explicit Item(int64_t value);
+  explicit Item(double value);
+  explicit Item(bool value);
+
+  // Constructors for string-like items: Strings, Tokens and Byte Sequences.
+  Item(const char* value, Item::ItemType type = kStringType);
+  Item(const std::string& value, Item::ItemType type = kStringType);
+  Item(std::string&& value, Item::ItemType type = kStringType);
+
+  QUICHE_EXPORT_PRIVATE friend bool operator==(const Item& lhs,
+                                               const Item& rhs);
+  inline friend bool operator!=(const Item& lhs, const Item& rhs) {
+    return !(lhs == rhs);
+  }
+
+  bool is_null() const { return type_ == kNullType; }
+  bool is_integer() const { return type_ == kIntegerType; }
+  bool is_decimal() const { return type_ == kDecimalType; }
+  bool is_string() const { return type_ == kStringType; }
+  bool is_token() const { return type_ == kTokenType; }
+  bool is_byte_sequence() const { return type_ == kByteSequenceType; }
+  bool is_boolean() const { return type_ == kBooleanType; }
+
+  int64_t GetInteger() const {
+    QUICHE_CHECK_EQ(type_, kIntegerType);
+    return integer_value_;
+  }
+  double GetDecimal() const {
+    QUICHE_CHECK_EQ(type_, kDecimalType);
+    return decimal_value_;
+  }
+  bool GetBoolean() const {
+    QUICHE_CHECK_EQ(type_, kBooleanType);
+    return boolean_value_;
+  }
+  // TODO(iclelland): Split up accessors for String, Token and Byte Sequence.
+  const std::string& GetString() const {
+    QUICHE_CHECK(type_ == kStringType || type_ == kTokenType ||
+                 type_ == kByteSequenceType);
+    return string_value_;
+  }
+
+  ItemType Type() const { return type_; }
+
+ private:
+  ItemType type_ = kNullType;
+  // TODO(iclelland): Make this class more memory-efficient, replacing the
+  // values here with a union or std::variant (when available).
+  int64_t integer_value_ = 0;
+  std::string string_value_;
+  double decimal_value_;
+  bool boolean_value_;
+};
+
+// Holds a ParameterizedIdentifier (draft 9 only). The contained Item must be a
+// Token, and there may be any number of parameters. Parameter ordering is not
+// significant.
+struct QUICHE_EXPORT_PRIVATE ParameterisedIdentifier {
+  using Parameters = std::map<std::string, Item>;
+
+  Item identifier;
+  Parameters params;
+
+  ParameterisedIdentifier(const ParameterisedIdentifier&);
+  ParameterisedIdentifier& operator=(const ParameterisedIdentifier&);
+  ParameterisedIdentifier(Item, const Parameters&);
+  ~ParameterisedIdentifier();
+};
+
+inline bool operator==(const ParameterisedIdentifier& lhs,
+                       const ParameterisedIdentifier& rhs) {
+  return std::tie(lhs.identifier, lhs.params) ==
+         std::tie(rhs.identifier, rhs.params);
+}
+
+using Parameters = std::vector<std::pair<std::string, Item>>;
+
+struct QUICHE_EXPORT_PRIVATE ParameterizedItem {
+  Item item;
+  Parameters params;
+
+  ParameterizedItem(const ParameterizedItem&);
+  ParameterizedItem& operator=(const ParameterizedItem&);
+  ParameterizedItem(Item, const Parameters&);
+  ~ParameterizedItem();
+};
+
+inline bool operator==(const ParameterizedItem& lhs,
+                       const ParameterizedItem& rhs) {
+  return std::tie(lhs.item, lhs.params) == std::tie(rhs.item, rhs.params);
+}
+
+inline bool operator!=(const ParameterizedItem& lhs,
+                       const ParameterizedItem& rhs) {
+  return !(lhs == rhs);
+}
+
+// Holds a ParameterizedMember, which may be either an single Item, or an Inner
+// List of ParameterizedItems, along with any number of parameters. Parameter
+// ordering is significant.
+struct QUICHE_EXPORT_PRIVATE ParameterizedMember {
+  std::vector<ParameterizedItem> member;
+  // If false, then |member| should only hold one Item.
+  bool member_is_inner_list = false;
+
+  Parameters params;
+
+  ParameterizedMember();
+  ParameterizedMember(const ParameterizedMember&);
+  ParameterizedMember& operator=(const ParameterizedMember&);
+  ParameterizedMember(std::vector<ParameterizedItem>, bool member_is_inner_list,
+                      const Parameters&);
+  // Shorthand constructor for a member which is an inner list.
+  ParameterizedMember(std::vector<ParameterizedItem>, const Parameters&);
+  // Shorthand constructor for a member which is a single Item.
+  ParameterizedMember(Item, const Parameters&);
+  ~ParameterizedMember();
+};
+
+inline bool operator==(const ParameterizedMember& lhs,
+                       const ParameterizedMember& rhs) {
+  return std::tie(lhs.member, lhs.member_is_inner_list, lhs.params) ==
+         std::tie(rhs.member, rhs.member_is_inner_list, rhs.params);
+}
+
+using DictionaryMember = std::pair<std::string, ParameterizedMember>;
+
+// Structured Headers RFC8941 Dictionary.
+class QUICHE_EXPORT_PRIVATE Dictionary {
+ public:
+  using iterator = std::vector<DictionaryMember>::iterator;
+  using const_iterator = std::vector<DictionaryMember>::const_iterator;
+
+  Dictionary();
+  Dictionary(const Dictionary&);
+  explicit Dictionary(std::vector<DictionaryMember> members);
+  ~Dictionary();
+  Dictionary& operator=(const Dictionary&) = default;
+  iterator begin();
+  const_iterator begin() const;
+  iterator end();
+  const_iterator end() const;
+
+  // operator[](size_t) and at(size_t) will both abort the program in case of
+  // out of bounds access.
+  ParameterizedMember& operator[](std::size_t idx);
+  const ParameterizedMember& operator[](std::size_t idx) const;
+  ParameterizedMember& at(std::size_t idx);
+  const ParameterizedMember& at(std::size_t idx) const;
+
+  // Consistent with std::map, if |key| does not exist in the Dictionary, then
+  // operator[](absl::string_view) will create an entry for it, but at() will
+  // abort the entire program.
+  ParameterizedMember& operator[](absl::string_view key);
+  ParameterizedMember& at(absl::string_view key);
+  const ParameterizedMember& at(absl::string_view key) const;
+
+  bool empty() const;
+  std::size_t size() const;
+  bool contains(absl::string_view key) const;
+  friend bool operator==(const Dictionary& lhs, const Dictionary& rhs);
+  friend bool operator!=(const Dictionary& lhs, const Dictionary& rhs);
+
+ private:
+  // Uses a vector to hold pairs of key and dictionary member. This makes
+  // look up by index and serialization much easier.
+  std::vector<DictionaryMember> members_;
+};
+
+inline bool operator==(const Dictionary& lhs, const Dictionary& rhs) {
+  return lhs.members_ == rhs.members_;
+}
+
+inline bool operator!=(const Dictionary& lhs, const Dictionary& rhs) {
+  return !(lhs == rhs);
+}
+
+// Structured Headers Draft 09 Parameterised List.
+using ParameterisedList = std::vector<ParameterisedIdentifier>;
+// Structured Headers Draft 09 List of Lists.
+using ListOfLists = std::vector<std::vector<Item>>;
+// Structured Headers RFC8941 List.
+using List = std::vector<ParameterizedMember>;
+
+// Returns the result of parsing the header value as an Item, if it can be
+// parsed as one, or nullopt if it cannot. Note that this uses the Draft 15
+// parsing rules, and so applies tighter range limits to integers.
+QUICHE_EXPORT_PRIVATE absl::optional<ParameterizedItem> ParseItem(
+    absl::string_view str);
+
+// Returns the result of parsing the header value as an Item with no parameters,
+// or nullopt if it cannot. Note that this uses the Draft 15 parsing rules, and
+// so applies tighter range limits to integers.
+QUICHE_EXPORT_PRIVATE absl::optional<Item> ParseBareItem(absl::string_view str);
+
+// Returns the result of parsing the header value as a Parameterised List, if it
+// can be parsed as one, or nullopt if it cannot. Note that parameter keys will
+// be returned as strings, which are guaranteed to be ASCII-encoded. List items,
+// as well as parameter values, will be returned as Items. This method uses the
+// Draft 09 parsing rules for Items, so integers have the 64-bit int range.
+// Structured-Headers Draft 09 only.
+QUICHE_EXPORT_PRIVATE absl::optional<ParameterisedList> ParseParameterisedList(
+    absl::string_view str);
+
+// Returns the result of parsing the header value as a List of Lists, if it can
+// be parsed as one, or nullopt if it cannot. Inner list items will be returned
+// as Items. This method uses the Draft 09 parsing rules for Items, so integers
+// have the 64-bit int range.
+// Structured-Headers Draft 09 only.
+QUICHE_EXPORT_PRIVATE absl::optional<ListOfLists> ParseListOfLists(
+    absl::string_view str);
+
+// Returns the result of parsing the header value as a general List, if it can
+// be parsed as one, or nullopt if it cannot.
+// Structured-Headers Draft 15 only.
+QUICHE_EXPORT_PRIVATE absl::optional<List> ParseList(absl::string_view str);
+
+// Returns the result of parsing the header value as a general Dictionary, if it
+// can be parsed as one, or nullopt if it cannot. Structured-Headers Draft 15
+// only.
+QUICHE_EXPORT_PRIVATE absl::optional<Dictionary> ParseDictionary(
+    const absl::string_view& str);
+
+// Serialization is implemented for Structured-Headers Draft 15 only.
+QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeItem(
+    const Item& value);
+QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeItem(
+    const ParameterizedItem& value);
+QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeList(
+    const List& value);
+QUICHE_EXPORT_PRIVATE absl::optional<std::string> SerializeDictionary(
+    const Dictionary& value);
+
+}  // namespace structured_headers
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_STRUCTURED_HEADERS_H_
diff --git a/quiche/common/structured_headers_fuzzer.cc b/quiche/common/structured_headers_fuzzer.cc
new file mode 100644
index 0000000..aefeea5
--- /dev/null
+++ b/quiche/common/structured_headers_fuzzer.cc
@@ -0,0 +1,22 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/structured_headers.h"
+
+namespace quiche {
+namespace structured_headers {
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  absl::string_view input(reinterpret_cast<const char*>(data), size);
+  ParseItem(input);
+  ParseListOfLists(input);
+  ParseList(input);
+  ParseDictionary(input);
+  ParseParameterisedList(input);
+  return 0;
+}
+
+}  // namespace structured_headers
+}  // namespace quiche
diff --git a/quiche/common/structured_headers_generated_test.cc b/quiche/common/structured_headers_generated_test.cc
new file mode 100644
index 0000000..7e94e49
--- /dev/null
+++ b/quiche/common/structured_headers_generated_test.cc
@@ -0,0 +1,3944 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/structured_headers.h"
+
+// This file contains tests cases for the Structured Header parser and
+// serializer, taken from the public test case repository at
+// https://github.com/httpwg/structured-field-tests. All of the tests are named,
+// so a given test case can be found in the JSON files in that repository by
+// searching for the test name. This file is generated, with the test cases
+// being automatically translated from the JSON source to C++ unit tests. Please
+// do not modify, as the contents will be overwritten when this is re-generated.
+
+// Generated on 2022-03-15 from structured-field-tests.git @
+// faed1f92942abd4fb5d61b1f9f0dc359f499f1d7.
+
+namespace quiche {
+namespace structured_headers {
+namespace {
+
+// Helpers to make test cases clearer
+
+Item Integer(int64_t value) { return Item(value); }
+
+std::pair<std::string, Item> BooleanParam(std::string key, bool value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> DoubleParam(std::string key, double value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> Param(std::string key, int64_t value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> Param(std::string key, std::string value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> TokenParam(std::string key, std::string value) {
+  return std::make_pair(key, Item(value, Item::kTokenType));
+}
+
+const struct ParameterizedItemTestCase {
+  const char* name;
+  const char* raw;
+  size_t raw_len;
+  const absl::optional<ParameterizedItem>
+      expected;           // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} parameterized_item_test_cases[] = {
+    // binary.json
+    {"basic binary",
+     ":aGVsbG8=:",
+     10,
+     {{Item("hello", Item::kByteSequenceType), {}}},
+     nullptr},
+    {"empty binary",
+     "::",
+     2,
+     {{Item("", Item::kByteSequenceType), {}}},
+     nullptr},
+    {"bad paddding",
+     ":aGVsbG8:",
+     9,
+     {{Item("hello", Item::kByteSequenceType), {}}},
+     ":aGVsbG8=:"},
+    {"bad end delimiter", ":aGVsbG8=", 9, absl::nullopt, nullptr},
+    {"extra whitespace", ":aGVsb G8=:", 11, absl::nullopt, nullptr},
+    {"extra chars", ":aGVsbG!8=:", 11, absl::nullopt, nullptr},
+    {"suffix chars", ":aGVsbG8=!:", 11, absl::nullopt, nullptr},
+    {"non-zero pad bits",
+     ":iZ==:",
+     6,
+     {{Item("\211", Item::kByteSequenceType), {}}},
+     ":iQ==:"},
+    {"non-ASCII binary",
+     ":/+Ah:",
+     6,
+     {{Item("\377\340!", Item::kByteSequenceType), {}}},
+     nullptr},
+    {"base64url binary", ":_-Ah:", 6, absl::nullopt, nullptr},
+    // boolean.json
+    {"basic true boolean", "?1", 2, {{Item(true), {}}}, nullptr},
+    {"basic false boolean", "?0", 2, {{Item(false), {}}}, nullptr},
+    {"unknown boolean", "?Q", 2, absl::nullopt, nullptr},
+    {"whitespace boolean", "? 1", 3, absl::nullopt, nullptr},
+    {"negative zero boolean", "?-0", 3, absl::nullopt, nullptr},
+    {"T boolean", "?T", 2, absl::nullopt, nullptr},
+    {"F boolean", "?F", 2, absl::nullopt, nullptr},
+    {"t boolean", "?t", 2, absl::nullopt, nullptr},
+    {"f boolean", "?f", 2, absl::nullopt, nullptr},
+    {"spelled-out True boolean", "?True", 5, absl::nullopt, nullptr},
+    {"spelled-out False boolean", "?False", 6, absl::nullopt, nullptr},
+    // examples.json
+    {"Foo-Example",
+     "2; foourl=\"https://foo.example.com/\"",
+     36,
+     {{Integer(2), {Param("foourl", "https://foo.example.com/")}}},
+     "2;foourl=\"https://foo.example.com/\""},
+    {"Example-IntHeader",
+     "1; a; b=?0",
+     10,
+     {{Integer(1), {BooleanParam("a", true), BooleanParam("b", false)}}},
+     "1;a;b=?0"},
+    {"Example-IntItemHeader", "5", 1, {{Integer(5), {}}}, nullptr},
+    {"Example-IntItemHeader (params)",
+     "5; foo=bar",
+     10,
+     {{Integer(5), {TokenParam("foo", "bar")}}},
+     "5;foo=bar"},
+    {"Example-IntegerHeader", "42", 2, {{Integer(42), {}}}, nullptr},
+    {"Example-FloatHeader", "4.5", 3, {{Item(4.500000), {}}}, nullptr},
+    {"Example-StringHeader",
+     "\"hello world\"",
+     13,
+     {{Item("hello world"), {}}},
+     nullptr},
+    {"Example-BinaryHdr",
+     ":cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==:",
+     46,
+     {{Item("pretend this is binary content.", Item::kByteSequenceType), {}}},
+     nullptr},
+    {"Example-BoolHdr", "?1", 2, {{Item(true), {}}}, nullptr},
+    // item.json
+    {"empty item", "", 0, absl::nullopt, nullptr},
+    {"leading space", " \t 1", 4, absl::nullopt, nullptr},
+    {"trailing space", "1 \t ", 4, absl::nullopt, nullptr},
+    {"leading and trailing space", "  1  ", 5, {{Integer(1), {}}}, "1"},
+    {"leading and trailing whitespace", "     1  ", 8, {{Integer(1), {}}}, "1"},
+    // number-generated.json
+    {"1 digits of zero", "0", 1, {{Integer(0), {}}}, "0"},
+    {"1 digit small integer", "1", 1, {{Integer(1), {}}}, nullptr},
+    {"1 digit large integer", "9", 1, {{Integer(9), {}}}, nullptr},
+    {"2 digits of zero", "00", 2, {{Integer(0), {}}}, "0"},
+    {"2 digit small integer", "11", 2, {{Integer(11), {}}}, nullptr},
+    {"2 digit large integer", "99", 2, {{Integer(99), {}}}, nullptr},
+    {"3 digits of zero", "000", 3, {{Integer(0), {}}}, "0"},
+    {"3 digit small integer", "111", 3, {{Integer(111), {}}}, nullptr},
+    {"3 digit large integer", "999", 3, {{Integer(999), {}}}, nullptr},
+    {"4 digits of zero", "0000", 4, {{Integer(0), {}}}, "0"},
+    {"4 digit small integer", "1111", 4, {{Integer(1111), {}}}, nullptr},
+    {"4 digit large integer", "9999", 4, {{Integer(9999), {}}}, nullptr},
+    {"5 digits of zero", "00000", 5, {{Integer(0), {}}}, "0"},
+    {"5 digit small integer", "11111", 5, {{Integer(11111), {}}}, nullptr},
+    {"5 digit large integer", "99999", 5, {{Integer(99999), {}}}, nullptr},
+    {"6 digits of zero", "000000", 6, {{Integer(0), {}}}, "0"},
+    {"6 digit small integer", "111111", 6, {{Integer(111111), {}}}, nullptr},
+    {"6 digit large integer", "999999", 6, {{Integer(999999), {}}}, nullptr},
+    {"7 digits of zero", "0000000", 7, {{Integer(0), {}}}, "0"},
+    {"7 digit small integer", "1111111", 7, {{Integer(1111111), {}}}, nullptr},
+    {"7 digit large integer", "9999999", 7, {{Integer(9999999), {}}}, nullptr},
+    {"8 digits of zero", "00000000", 8, {{Integer(0), {}}}, "0"},
+    {"8 digit small integer",
+     "11111111",
+     8,
+     {{Integer(11111111), {}}},
+     nullptr},
+    {"8 digit large integer",
+     "99999999",
+     8,
+     {{Integer(99999999), {}}},
+     nullptr},
+    {"9 digits of zero", "000000000", 9, {{Integer(0), {}}}, "0"},
+    {"9 digit small integer",
+     "111111111",
+     9,
+     {{Integer(111111111), {}}},
+     nullptr},
+    {"9 digit large integer",
+     "999999999",
+     9,
+     {{Integer(999999999), {}}},
+     nullptr},
+    {"10 digits of zero", "0000000000", 10, {{Integer(0), {}}}, "0"},
+    {"10 digit small integer",
+     "1111111111",
+     10,
+     {{Integer(1111111111), {}}},
+     nullptr},
+    {"10 digit large integer",
+     "9999999999",
+     10,
+     {{Integer(9999999999), {}}},
+     nullptr},
+    {"11 digits of zero", "00000000000", 11, {{Integer(0), {}}}, "0"},
+    {"11 digit small integer",
+     "11111111111",
+     11,
+     {{Integer(11111111111), {}}},
+     nullptr},
+    {"11 digit large integer",
+     "99999999999",
+     11,
+     {{Integer(99999999999), {}}},
+     nullptr},
+    {"12 digits of zero", "000000000000", 12, {{Integer(0), {}}}, "0"},
+    {"12 digit small integer",
+     "111111111111",
+     12,
+     {{Integer(111111111111), {}}},
+     nullptr},
+    {"12 digit large integer",
+     "999999999999",
+     12,
+     {{Integer(999999999999), {}}},
+     nullptr},
+    {"13 digits of zero", "0000000000000", 13, {{Integer(0), {}}}, "0"},
+    {"13 digit small integer",
+     "1111111111111",
+     13,
+     {{Integer(1111111111111), {}}},
+     nullptr},
+    {"13 digit large integer",
+     "9999999999999",
+     13,
+     {{Integer(9999999999999), {}}},
+     nullptr},
+    {"14 digits of zero", "00000000000000", 14, {{Integer(0), {}}}, "0"},
+    {"14 digit small integer",
+     "11111111111111",
+     14,
+     {{Integer(11111111111111), {}}},
+     nullptr},
+    {"14 digit large integer",
+     "99999999999999",
+     14,
+     {{Integer(99999999999999), {}}},
+     nullptr},
+    {"15 digits of zero", "000000000000000", 15, {{Integer(0), {}}}, "0"},
+    {"15 digit small integer",
+     "111111111111111",
+     15,
+     {{Integer(111111111111111), {}}},
+     nullptr},
+    {"15 digit large integer",
+     "999999999999999",
+     15,
+     {{Integer(999999999999999), {}}},
+     nullptr},
+    {"2 digit 0, 1 fractional small decimal",
+     "0.1",
+     3,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"2 digit, 1 fractional 0 decimal",
+     "1.0",
+     3,
+     {{Item(1.000000), {}}},
+     "1.0"},
+    {"2 digit, 1 fractional small decimal",
+     "1.1",
+     3,
+     {{Item(1.100000), {}}},
+     nullptr},
+    {"2 digit, 1 fractional large decimal",
+     "9.9",
+     3,
+     {{Item(9.900000), {}}},
+     nullptr},
+    {"3 digit 0, 2 fractional small decimal",
+     "0.11",
+     4,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"3 digit, 2 fractional 0 decimal",
+     "1.00",
+     4,
+     {{Item(1.000000), {}}},
+     "1.0"},
+    {"3 digit, 2 fractional small decimal",
+     "1.11",
+     4,
+     {{Item(1.110000), {}}},
+     nullptr},
+    {"3 digit, 2 fractional large decimal",
+     "9.99",
+     4,
+     {{Item(9.990000), {}}},
+     nullptr},
+    {"4 digit 0, 3 fractional small decimal",
+     "0.111",
+     5,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"4 digit, 3 fractional 0 decimal",
+     "1.000",
+     5,
+     {{Item(1.000000), {}}},
+     "1.0"},
+    {"4 digit, 3 fractional small decimal",
+     "1.111",
+     5,
+     {{Item(1.111000), {}}},
+     nullptr},
+    {"4 digit, 3 fractional large decimal",
+     "9.999",
+     5,
+     {{Item(9.999000), {}}},
+     nullptr},
+    {"3 digit 0, 1 fractional small decimal",
+     "00.1",
+     4,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"3 digit, 1 fractional 0 decimal",
+     "11.0",
+     4,
+     {{Item(11.000000), {}}},
+     "11.0"},
+    {"3 digit, 1 fractional small decimal",
+     "11.1",
+     4,
+     {{Item(11.100000), {}}},
+     nullptr},
+    {"3 digit, 1 fractional large decimal",
+     "99.9",
+     4,
+     {{Item(99.900000), {}}},
+     nullptr},
+    {"4 digit 0, 2 fractional small decimal",
+     "00.11",
+     5,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"4 digit, 2 fractional 0 decimal",
+     "11.00",
+     5,
+     {{Item(11.000000), {}}},
+     "11.0"},
+    {"4 digit, 2 fractional small decimal",
+     "11.11",
+     5,
+     {{Item(11.110000), {}}},
+     nullptr},
+    {"4 digit, 2 fractional large decimal",
+     "99.99",
+     5,
+     {{Item(99.990000), {}}},
+     nullptr},
+    {"5 digit 0, 3 fractional small decimal",
+     "00.111",
+     6,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"5 digit, 3 fractional 0 decimal",
+     "11.000",
+     6,
+     {{Item(11.000000), {}}},
+     "11.0"},
+    {"5 digit, 3 fractional small decimal",
+     "11.111",
+     6,
+     {{Item(11.111000), {}}},
+     nullptr},
+    {"5 digit, 3 fractional large decimal",
+     "99.999",
+     6,
+     {{Item(99.999000), {}}},
+     nullptr},
+    {"4 digit 0, 1 fractional small decimal",
+     "000.1",
+     5,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"4 digit, 1 fractional 0 decimal",
+     "111.0",
+     5,
+     {{Item(111.000000), {}}},
+     "111.0"},
+    {"4 digit, 1 fractional small decimal",
+     "111.1",
+     5,
+     {{Item(111.100000), {}}},
+     nullptr},
+    {"4 digit, 1 fractional large decimal",
+     "999.9",
+     5,
+     {{Item(999.900000), {}}},
+     nullptr},
+    {"5 digit 0, 2 fractional small decimal",
+     "000.11",
+     6,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"5 digit, 2 fractional 0 decimal",
+     "111.00",
+     6,
+     {{Item(111.000000), {}}},
+     "111.0"},
+    {"5 digit, 2 fractional small decimal",
+     "111.11",
+     6,
+     {{Item(111.110000), {}}},
+     nullptr},
+    {"5 digit, 2 fractional large decimal",
+     "999.99",
+     6,
+     {{Item(999.990000), {}}},
+     nullptr},
+    {"6 digit 0, 3 fractional small decimal",
+     "000.111",
+     7,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"6 digit, 3 fractional 0 decimal",
+     "111.000",
+     7,
+     {{Item(111.000000), {}}},
+     "111.0"},
+    {"6 digit, 3 fractional small decimal",
+     "111.111",
+     7,
+     {{Item(111.111000), {}}},
+     nullptr},
+    {"6 digit, 3 fractional large decimal",
+     "999.999",
+     7,
+     {{Item(999.999000), {}}},
+     nullptr},
+    {"5 digit 0, 1 fractional small decimal",
+     "0000.1",
+     6,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"5 digit, 1 fractional 0 decimal",
+     "1111.0",
+     6,
+     {{Item(1111.000000), {}}},
+     "1111.0"},
+    {"5 digit, 1 fractional small decimal",
+     "1111.1",
+     6,
+     {{Item(1111.100000), {}}},
+     nullptr},
+    {"5 digit, 1 fractional large decimal",
+     "9999.9",
+     6,
+     {{Item(9999.900000), {}}},
+     nullptr},
+    {"6 digit 0, 2 fractional small decimal",
+     "0000.11",
+     7,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"6 digit, 2 fractional 0 decimal",
+     "1111.00",
+     7,
+     {{Item(1111.000000), {}}},
+     "1111.0"},
+    {"6 digit, 2 fractional small decimal",
+     "1111.11",
+     7,
+     {{Item(1111.110000), {}}},
+     nullptr},
+    {"6 digit, 2 fractional large decimal",
+     "9999.99",
+     7,
+     {{Item(9999.990000), {}}},
+     nullptr},
+    {"7 digit 0, 3 fractional small decimal",
+     "0000.111",
+     8,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"7 digit, 3 fractional 0 decimal",
+     "1111.000",
+     8,
+     {{Item(1111.000000), {}}},
+     "1111.0"},
+    {"7 digit, 3 fractional small decimal",
+     "1111.111",
+     8,
+     {{Item(1111.111000), {}}},
+     nullptr},
+    {"7 digit, 3 fractional large decimal",
+     "9999.999",
+     8,
+     {{Item(9999.999000), {}}},
+     nullptr},
+    {"6 digit 0, 1 fractional small decimal",
+     "00000.1",
+     7,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"6 digit, 1 fractional 0 decimal",
+     "11111.0",
+     7,
+     {{Item(11111.000000), {}}},
+     "11111.0"},
+    {"6 digit, 1 fractional small decimal",
+     "11111.1",
+     7,
+     {{Item(11111.100000), {}}},
+     nullptr},
+    {"6 digit, 1 fractional large decimal",
+     "99999.9",
+     7,
+     {{Item(99999.900000), {}}},
+     nullptr},
+    {"7 digit 0, 2 fractional small decimal",
+     "00000.11",
+     8,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"7 digit, 2 fractional 0 decimal",
+     "11111.00",
+     8,
+     {{Item(11111.000000), {}}},
+     "11111.0"},
+    {"7 digit, 2 fractional small decimal",
+     "11111.11",
+     8,
+     {{Item(11111.110000), {}}},
+     nullptr},
+    {"7 digit, 2 fractional large decimal",
+     "99999.99",
+     8,
+     {{Item(99999.990000), {}}},
+     nullptr},
+    {"8 digit 0, 3 fractional small decimal",
+     "00000.111",
+     9,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"8 digit, 3 fractional 0 decimal",
+     "11111.000",
+     9,
+     {{Item(11111.000000), {}}},
+     "11111.0"},
+    {"8 digit, 3 fractional small decimal",
+     "11111.111",
+     9,
+     {{Item(11111.111000), {}}},
+     nullptr},
+    {"8 digit, 3 fractional large decimal",
+     "99999.999",
+     9,
+     {{Item(99999.999000), {}}},
+     nullptr},
+    {"7 digit 0, 1 fractional small decimal",
+     "000000.1",
+     8,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"7 digit, 1 fractional 0 decimal",
+     "111111.0",
+     8,
+     {{Item(111111.000000), {}}},
+     "111111.0"},
+    {"7 digit, 1 fractional small decimal",
+     "111111.1",
+     8,
+     {{Item(111111.100000), {}}},
+     nullptr},
+    {"7 digit, 1 fractional large decimal",
+     "999999.9",
+     8,
+     {{Item(999999.900000), {}}},
+     nullptr},
+    {"8 digit 0, 2 fractional small decimal",
+     "000000.11",
+     9,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"8 digit, 2 fractional 0 decimal",
+     "111111.00",
+     9,
+     {{Item(111111.000000), {}}},
+     "111111.0"},
+    {"8 digit, 2 fractional small decimal",
+     "111111.11",
+     9,
+     {{Item(111111.110000), {}}},
+     nullptr},
+    {"8 digit, 2 fractional large decimal",
+     "999999.99",
+     9,
+     {{Item(999999.990000), {}}},
+     nullptr},
+    {"9 digit 0, 3 fractional small decimal",
+     "000000.111",
+     10,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"9 digit, 3 fractional 0 decimal",
+     "111111.000",
+     10,
+     {{Item(111111.000000), {}}},
+     "111111.0"},
+    {"9 digit, 3 fractional small decimal",
+     "111111.111",
+     10,
+     {{Item(111111.111000), {}}},
+     nullptr},
+    {"9 digit, 3 fractional large decimal",
+     "999999.999",
+     10,
+     {{Item(999999.999000), {}}},
+     nullptr},
+    {"8 digit 0, 1 fractional small decimal",
+     "0000000.1",
+     9,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"8 digit, 1 fractional 0 decimal",
+     "1111111.0",
+     9,
+     {{Item(1111111.000000), {}}},
+     "1111111.0"},
+    {"8 digit, 1 fractional small decimal",
+     "1111111.1",
+     9,
+     {{Item(1111111.100000), {}}},
+     nullptr},
+    {"8 digit, 1 fractional large decimal",
+     "9999999.9",
+     9,
+     {{Item(9999999.900000), {}}},
+     nullptr},
+    {"9 digit 0, 2 fractional small decimal",
+     "0000000.11",
+     10,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"9 digit, 2 fractional 0 decimal",
+     "1111111.00",
+     10,
+     {{Item(1111111.000000), {}}},
+     "1111111.0"},
+    {"9 digit, 2 fractional small decimal",
+     "1111111.11",
+     10,
+     {{Item(1111111.110000), {}}},
+     nullptr},
+    {"9 digit, 2 fractional large decimal",
+     "9999999.99",
+     10,
+     {{Item(9999999.990000), {}}},
+     nullptr},
+    {"10 digit 0, 3 fractional small decimal",
+     "0000000.111",
+     11,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"10 digit, 3 fractional 0 decimal",
+     "1111111.000",
+     11,
+     {{Item(1111111.000000), {}}},
+     "1111111.0"},
+    {"10 digit, 3 fractional small decimal",
+     "1111111.111",
+     11,
+     {{Item(1111111.111000), {}}},
+     nullptr},
+    {"10 digit, 3 fractional large decimal",
+     "9999999.999",
+     11,
+     {{Item(9999999.999000), {}}},
+     nullptr},
+    {"9 digit 0, 1 fractional small decimal",
+     "00000000.1",
+     10,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"9 digit, 1 fractional 0 decimal",
+     "11111111.0",
+     10,
+     {{Item(11111111.000000), {}}},
+     "11111111.0"},
+    {"9 digit, 1 fractional small decimal",
+     "11111111.1",
+     10,
+     {{Item(11111111.100000), {}}},
+     nullptr},
+    {"9 digit, 1 fractional large decimal",
+     "99999999.9",
+     10,
+     {{Item(99999999.900000), {}}},
+     nullptr},
+    {"10 digit 0, 2 fractional small decimal",
+     "00000000.11",
+     11,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"10 digit, 2 fractional 0 decimal",
+     "11111111.00",
+     11,
+     {{Item(11111111.000000), {}}},
+     "11111111.0"},
+    {"10 digit, 2 fractional small decimal",
+     "11111111.11",
+     11,
+     {{Item(11111111.110000), {}}},
+     nullptr},
+    {"10 digit, 2 fractional large decimal",
+     "99999999.99",
+     11,
+     {{Item(99999999.990000), {}}},
+     nullptr},
+    {"11 digit 0, 3 fractional small decimal",
+     "00000000.111",
+     12,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"11 digit, 3 fractional 0 decimal",
+     "11111111.000",
+     12,
+     {{Item(11111111.000000), {}}},
+     "11111111.0"},
+    {"11 digit, 3 fractional small decimal",
+     "11111111.111",
+     12,
+     {{Item(11111111.111000), {}}},
+     nullptr},
+    {"11 digit, 3 fractional large decimal",
+     "99999999.999",
+     12,
+     {{Item(99999999.999000), {}}},
+     nullptr},
+    {"10 digit 0, 1 fractional small decimal",
+     "000000000.1",
+     11,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"10 digit, 1 fractional 0 decimal",
+     "111111111.0",
+     11,
+     {{Item(111111111.000000), {}}},
+     "111111111.0"},
+    {"10 digit, 1 fractional small decimal",
+     "111111111.1",
+     11,
+     {{Item(111111111.100000), {}}},
+     nullptr},
+    {"10 digit, 1 fractional large decimal",
+     "999999999.9",
+     11,
+     {{Item(999999999.900000), {}}},
+     nullptr},
+    {"11 digit 0, 2 fractional small decimal",
+     "000000000.11",
+     12,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"11 digit, 2 fractional 0 decimal",
+     "111111111.00",
+     12,
+     {{Item(111111111.000000), {}}},
+     "111111111.0"},
+    {"11 digit, 2 fractional small decimal",
+     "111111111.11",
+     12,
+     {{Item(111111111.110000), {}}},
+     nullptr},
+    {"11 digit, 2 fractional large decimal",
+     "999999999.99",
+     12,
+     {{Item(999999999.990000), {}}},
+     nullptr},
+    {"12 digit 0, 3 fractional small decimal",
+     "000000000.111",
+     13,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"12 digit, 3 fractional 0 decimal",
+     "111111111.000",
+     13,
+     {{Item(111111111.000000), {}}},
+     "111111111.0"},
+    {"12 digit, 3 fractional small decimal",
+     "111111111.111",
+     13,
+     {{Item(111111111.111000), {}}},
+     nullptr},
+    {"12 digit, 3 fractional large decimal",
+     "999999999.999",
+     13,
+     {{Item(999999999.999000), {}}},
+     nullptr},
+    {"11 digit 0, 1 fractional small decimal",
+     "0000000000.1",
+     12,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"11 digit, 1 fractional 0 decimal",
+     "1111111111.0",
+     12,
+     {{Item(1111111111.000000), {}}},
+     "1111111111.0"},
+    {"11 digit, 1 fractional small decimal",
+     "1111111111.1",
+     12,
+     {{Item(1111111111.100000), {}}},
+     nullptr},
+    {"11 digit, 1 fractional large decimal",
+     "9999999999.9",
+     12,
+     {{Item(9999999999.900000), {}}},
+     nullptr},
+    {"12 digit 0, 2 fractional small decimal",
+     "0000000000.11",
+     13,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"12 digit, 2 fractional 0 decimal",
+     "1111111111.00",
+     13,
+     {{Item(1111111111.000000), {}}},
+     "1111111111.0"},
+    {"12 digit, 2 fractional small decimal",
+     "1111111111.11",
+     13,
+     {{Item(1111111111.110000), {}}},
+     nullptr},
+    {"12 digit, 2 fractional large decimal",
+     "9999999999.99",
+     13,
+     {{Item(9999999999.990000), {}}},
+     nullptr},
+    {"13 digit 0, 3 fractional small decimal",
+     "0000000000.111",
+     14,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"13 digit, 3 fractional 0 decimal",
+     "1111111111.000",
+     14,
+     {{Item(1111111111.000000), {}}},
+     "1111111111.0"},
+    {"13 digit, 3 fractional small decimal",
+     "1111111111.111",
+     14,
+     {{Item(1111111111.111000), {}}},
+     nullptr},
+    {"13 digit, 3 fractional large decimal",
+     "9999999999.999",
+     14,
+     {{Item(9999999999.999001), {}}},
+     nullptr},
+    {"12 digit 0, 1 fractional small decimal",
+     "00000000000.1",
+     13,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"12 digit, 1 fractional 0 decimal",
+     "11111111111.0",
+     13,
+     {{Item(11111111111.000000), {}}},
+     "11111111111.0"},
+    {"12 digit, 1 fractional small decimal",
+     "11111111111.1",
+     13,
+     {{Item(11111111111.100000), {}}},
+     nullptr},
+    {"12 digit, 1 fractional large decimal",
+     "99999999999.9",
+     13,
+     {{Item(99999999999.899994), {}}},
+     nullptr},
+    {"13 digit 0, 2 fractional small decimal",
+     "00000000000.11",
+     14,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"13 digit, 2 fractional 0 decimal",
+     "11111111111.00",
+     14,
+     {{Item(11111111111.000000), {}}},
+     "11111111111.0"},
+    {"13 digit, 2 fractional small decimal",
+     "11111111111.11",
+     14,
+     {{Item(11111111111.110001), {}}},
+     nullptr},
+    {"13 digit, 2 fractional large decimal",
+     "99999999999.99",
+     14,
+     {{Item(99999999999.990005), {}}},
+     nullptr},
+    {"14 digit 0, 3 fractional small decimal",
+     "00000000000.111",
+     15,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"14 digit, 3 fractional 0 decimal",
+     "11111111111.000",
+     15,
+     {{Item(11111111111.000000), {}}},
+     "11111111111.0"},
+    {"14 digit, 3 fractional small decimal",
+     "11111111111.111",
+     15,
+     {{Item(11111111111.111000), {}}},
+     nullptr},
+    {"14 digit, 3 fractional large decimal",
+     "99999999999.999",
+     15,
+     {{Item(99999999999.998993), {}}},
+     nullptr},
+    {"13 digit 0, 1 fractional small decimal",
+     "000000000000.1",
+     14,
+     {{Item(0.100000), {}}},
+     "0.1"},
+    {"13 digit, 1 fractional 0 decimal",
+     "111111111111.0",
+     14,
+     {{Item(111111111111.000000), {}}},
+     "111111111111.0"},
+    {"13 digit, 1 fractional small decimal",
+     "111111111111.1",
+     14,
+     {{Item(111111111111.100006), {}}},
+     nullptr},
+    {"13 digit, 1 fractional large decimal",
+     "999999999999.9",
+     14,
+     {{Item(999999999999.900024), {}}},
+     nullptr},
+    {"14 digit 0, 2 fractional small decimal",
+     "000000000000.11",
+     15,
+     {{Item(0.110000), {}}},
+     "0.11"},
+    {"14 digit, 2 fractional 0 decimal",
+     "111111111111.00",
+     15,
+     {{Item(111111111111.000000), {}}},
+     "111111111111.0"},
+    {"14 digit, 2 fractional small decimal",
+     "111111111111.11",
+     15,
+     {{Item(111111111111.110001), {}}},
+     nullptr},
+    {"14 digit, 2 fractional large decimal",
+     "999999999999.99",
+     15,
+     {{Item(999999999999.989990), {}}},
+     nullptr},
+    {"15 digit 0, 3 fractional small decimal",
+     "000000000000.111",
+     16,
+     {{Item(0.111000), {}}},
+     "0.111"},
+    {"15 digit, 3 fractional 0 decimal",
+     "111111111111.000",
+     16,
+     {{Item(111111111111.000000), {}}},
+     "111111111111.0"},
+    {"15 digit, 3 fractional small decimal",
+     "111111111111.111",
+     16,
+     {{Item(111111111111.110992), {}}},
+     nullptr},
+    {"15 digit, 3 fractional large decimal",
+     "999999999999.999",
+     16,
+     {{Item(999999999999.999023), {}}},
+     nullptr},
+    {"too many digit 0 decimal", "000000000000000.0", 17, absl::nullopt,
+     nullptr},
+    {"too many fractional digits 0 decimal", "000000000000.0000", 17,
+     absl::nullopt, nullptr},
+    {"too many digit 9 decimal", "999999999999999.9", 17, absl::nullopt,
+     nullptr},
+    {"too many fractional digits 9 decimal", "999999999999.9999", 17,
+     absl::nullopt, nullptr},
+    // number.json
+    {"basic integer", "42", 2, {{Integer(42), {}}}, nullptr},
+    {"zero integer", "0", 1, {{Integer(0), {}}}, nullptr},
+    {"negative zero", "-0", 2, {{Integer(0), {}}}, "0"},
+    {"double negative zero", "--0", 3, absl::nullopt, nullptr},
+    {"negative integer", "-42", 3, {{Integer(-42), {}}}, nullptr},
+    {"leading 0 integer", "042", 3, {{Integer(42), {}}}, "42"},
+    {"leading 0 negative integer", "-042", 4, {{Integer(-42), {}}}, "-42"},
+    {"leading 0 zero", "00", 2, {{Integer(0), {}}}, "0"},
+    {"comma", "2,3", 3, absl::nullopt, nullptr},
+    {"negative non-DIGIT first character", "-a23", 4, absl::nullopt, nullptr},
+    {"sign out of place", "4-2", 3, absl::nullopt, nullptr},
+    {"whitespace after sign", "- 42", 4, absl::nullopt, nullptr},
+    {"long integer",
+     "123456789012345",
+     15,
+     {{Integer(123456789012345), {}}},
+     nullptr},
+    {"long negative integer",
+     "-123456789012345",
+     16,
+     {{Integer(-123456789012345), {}}},
+     nullptr},
+    {"too long integer", "1234567890123456", 16, absl::nullopt, nullptr},
+    {"negative too long integer", "-1234567890123456", 17, absl::nullopt,
+     nullptr},
+    {"simple decimal", "1.23", 4, {{Item(1.230000), {}}}, nullptr},
+    {"negative decimal", "-1.23", 5, {{Item(-1.230000), {}}}, nullptr},
+    {"decimal, whitespace after decimal", "1. 23", 5, absl::nullopt, nullptr},
+    {"decimal, whitespace before decimal", "1 .23", 5, absl::nullopt, nullptr},
+    {"negative decimal, whitespace after sign", "- 1.23", 6, absl::nullopt,
+     nullptr},
+    {"tricky precision decimal",
+     "123456789012.1",
+     14,
+     {{Item(123456789012.100006), {}}},
+     nullptr},
+    {"double decimal decimal", "1.5.4", 5, absl::nullopt, nullptr},
+    {"adjacent double decimal decimal", "1..4", 4, absl::nullopt, nullptr},
+    {"decimal with three fractional digits",
+     "1.123",
+     5,
+     {{Item(1.123000), {}}},
+     nullptr},
+    {"negative decimal with three fractional digits",
+     "-1.123",
+     6,
+     {{Item(-1.123000), {}}},
+     nullptr},
+    {"decimal with four fractional digits", "1.1234", 6, absl::nullopt,
+     nullptr},
+    {"negative decimal with four fractional digits", "-1.1234", 7,
+     absl::nullopt, nullptr},
+    {"decimal with thirteen integer digits", "1234567890123.0", 15,
+     absl::nullopt, nullptr},
+    {"negative decimal with thirteen integer digits", "-1234567890123.0", 16,
+     absl::nullopt, nullptr},
+    // string-generated.json
+    {"0x00 in string", "\" \000 \"", 5, absl::nullopt, nullptr},
+    {"0x01 in string", "\" \001 \"", 5, absl::nullopt, nullptr},
+    {"0x02 in string", "\" \002 \"", 5, absl::nullopt, nullptr},
+    {"0x03 in string", "\" \003 \"", 5, absl::nullopt, nullptr},
+    {"0x04 in string", "\" \004 \"", 5, absl::nullopt, nullptr},
+    {"0x05 in string", "\" \005 \"", 5, absl::nullopt, nullptr},
+    {"0x06 in string", "\" \006 \"", 5, absl::nullopt, nullptr},
+    {"0x07 in string", "\" \a \"", 5, absl::nullopt, nullptr},
+    {"0x08 in string", "\" \b \"", 5, absl::nullopt, nullptr},
+    {"0x09 in string", "\" \t \"", 5, absl::nullopt, nullptr},
+    {"0x0a in string", "\" \n \"", 5, absl::nullopt, nullptr},
+    {"0x0b in string", "\" \v \"", 5, absl::nullopt, nullptr},
+    {"0x0c in string", "\" \f \"", 5, absl::nullopt, nullptr},
+    {"0x0d in string", "\" \r \"", 5, absl::nullopt, nullptr},
+    {"0x0e in string", "\" \016 \"", 5, absl::nullopt, nullptr},
+    {"0x0f in string", "\" \017 \"", 5, absl::nullopt, nullptr},
+    {"0x10 in string", "\" \020 \"", 5, absl::nullopt, nullptr},
+    {"0x11 in string", "\" \021 \"", 5, absl::nullopt, nullptr},
+    {"0x12 in string", "\" \022 \"", 5, absl::nullopt, nullptr},
+    {"0x13 in string", "\" \023 \"", 5, absl::nullopt, nullptr},
+    {"0x14 in string", "\" \024 \"", 5, absl::nullopt, nullptr},
+    {"0x15 in string", "\" \025 \"", 5, absl::nullopt, nullptr},
+    {"0x16 in string", "\" \026 \"", 5, absl::nullopt, nullptr},
+    {"0x17 in string", "\" \027 \"", 5, absl::nullopt, nullptr},
+    {"0x18 in string", "\" \030 \"", 5, absl::nullopt, nullptr},
+    {"0x19 in string", "\" \031 \"", 5, absl::nullopt, nullptr},
+    {"0x1a in string", "\" \032 \"", 5, absl::nullopt, nullptr},
+    {"0x1b in string", "\" \033 \"", 5, absl::nullopt, nullptr},
+    {"0x1c in string", "\" \034 \"", 5, absl::nullopt, nullptr},
+    {"0x1d in string", "\" \035 \"", 5, absl::nullopt, nullptr},
+    {"0x1e in string", "\" \036 \"", 5, absl::nullopt, nullptr},
+    {"0x1f in string", "\" \037 \"", 5, absl::nullopt, nullptr},
+    {"0x20 in string", "\"   \"", 5, {{Item("   "), {}}}, nullptr},
+    {"0x21 in string", "\" ! \"", 5, {{Item(" ! "), {}}}, nullptr},
+    {"0x22 in string", "\" \" \"", 5, absl::nullopt, nullptr},
+    {"0x23 in string", "\" # \"", 5, {{Item(" # "), {}}}, nullptr},
+    {"0x24 in string", "\" $ \"", 5, {{Item(" $ "), {}}}, nullptr},
+    {"0x25 in string", "\" % \"", 5, {{Item(" % "), {}}}, nullptr},
+    {"0x26 in string", "\" & \"", 5, {{Item(" & "), {}}}, nullptr},
+    {"0x27 in string", "\" ' \"", 5, {{Item(" ' "), {}}}, nullptr},
+    {"0x28 in string", "\" ( \"", 5, {{Item(" ( "), {}}}, nullptr},
+    {"0x29 in string", "\" ) \"", 5, {{Item(" ) "), {}}}, nullptr},
+    {"0x2a in string", "\" * \"", 5, {{Item(" * "), {}}}, nullptr},
+    {"0x2b in string", "\" + \"", 5, {{Item(" + "), {}}}, nullptr},
+    {"0x2c in string", "\" , \"", 5, {{Item(" , "), {}}}, nullptr},
+    {"0x2d in string", "\" - \"", 5, {{Item(" - "), {}}}, nullptr},
+    {"0x2e in string", "\" . \"", 5, {{Item(" . "), {}}}, nullptr},
+    {"0x2f in string", "\" / \"", 5, {{Item(" / "), {}}}, nullptr},
+    {"0x30 in string", "\" 0 \"", 5, {{Item(" 0 "), {}}}, nullptr},
+    {"0x31 in string", "\" 1 \"", 5, {{Item(" 1 "), {}}}, nullptr},
+    {"0x32 in string", "\" 2 \"", 5, {{Item(" 2 "), {}}}, nullptr},
+    {"0x33 in string", "\" 3 \"", 5, {{Item(" 3 "), {}}}, nullptr},
+    {"0x34 in string", "\" 4 \"", 5, {{Item(" 4 "), {}}}, nullptr},
+    {"0x35 in string", "\" 5 \"", 5, {{Item(" 5 "), {}}}, nullptr},
+    {"0x36 in string", "\" 6 \"", 5, {{Item(" 6 "), {}}}, nullptr},
+    {"0x37 in string", "\" 7 \"", 5, {{Item(" 7 "), {}}}, nullptr},
+    {"0x38 in string", "\" 8 \"", 5, {{Item(" 8 "), {}}}, nullptr},
+    {"0x39 in string", "\" 9 \"", 5, {{Item(" 9 "), {}}}, nullptr},
+    {"0x3a in string", "\" : \"", 5, {{Item(" : "), {}}}, nullptr},
+    {"0x3b in string", "\" ; \"", 5, {{Item(" ; "), {}}}, nullptr},
+    {"0x3c in string", "\" < \"", 5, {{Item(" < "), {}}}, nullptr},
+    {"0x3d in string", "\" = \"", 5, {{Item(" = "), {}}}, nullptr},
+    {"0x3e in string", "\" > \"", 5, {{Item(" > "), {}}}, nullptr},
+    {"0x3f in string", "\" ? \"", 5, {{Item(" ? "), {}}}, nullptr},
+    {"0x40 in string", "\" @ \"", 5, {{Item(" @ "), {}}}, nullptr},
+    {"0x41 in string", "\" A \"", 5, {{Item(" A "), {}}}, nullptr},
+    {"0x42 in string", "\" B \"", 5, {{Item(" B "), {}}}, nullptr},
+    {"0x43 in string", "\" C \"", 5, {{Item(" C "), {}}}, nullptr},
+    {"0x44 in string", "\" D \"", 5, {{Item(" D "), {}}}, nullptr},
+    {"0x45 in string", "\" E \"", 5, {{Item(" E "), {}}}, nullptr},
+    {"0x46 in string", "\" F \"", 5, {{Item(" F "), {}}}, nullptr},
+    {"0x47 in string", "\" G \"", 5, {{Item(" G "), {}}}, nullptr},
+    {"0x48 in string", "\" H \"", 5, {{Item(" H "), {}}}, nullptr},
+    {"0x49 in string", "\" I \"", 5, {{Item(" I "), {}}}, nullptr},
+    {"0x4a in string", "\" J \"", 5, {{Item(" J "), {}}}, nullptr},
+    {"0x4b in string", "\" K \"", 5, {{Item(" K "), {}}}, nullptr},
+    {"0x4c in string", "\" L \"", 5, {{Item(" L "), {}}}, nullptr},
+    {"0x4d in string", "\" M \"", 5, {{Item(" M "), {}}}, nullptr},
+    {"0x4e in string", "\" N \"", 5, {{Item(" N "), {}}}, nullptr},
+    {"0x4f in string", "\" O \"", 5, {{Item(" O "), {}}}, nullptr},
+    {"0x50 in string", "\" P \"", 5, {{Item(" P "), {}}}, nullptr},
+    {"0x51 in string", "\" Q \"", 5, {{Item(" Q "), {}}}, nullptr},
+    {"0x52 in string", "\" R \"", 5, {{Item(" R "), {}}}, nullptr},
+    {"0x53 in string", "\" S \"", 5, {{Item(" S "), {}}}, nullptr},
+    {"0x54 in string", "\" T \"", 5, {{Item(" T "), {}}}, nullptr},
+    {"0x55 in string", "\" U \"", 5, {{Item(" U "), {}}}, nullptr},
+    {"0x56 in string", "\" V \"", 5, {{Item(" V "), {}}}, nullptr},
+    {"0x57 in string", "\" W \"", 5, {{Item(" W "), {}}}, nullptr},
+    {"0x58 in string", "\" X \"", 5, {{Item(" X "), {}}}, nullptr},
+    {"0x59 in string", "\" Y \"", 5, {{Item(" Y "), {}}}, nullptr},
+    {"0x5a in string", "\" Z \"", 5, {{Item(" Z "), {}}}, nullptr},
+    {"0x5b in string", "\" [ \"", 5, {{Item(" [ "), {}}}, nullptr},
+    {"0x5c in string", "\" \\ \"", 5, absl::nullopt, nullptr},
+    {"0x5d in string", "\" ] \"", 5, {{Item(" ] "), {}}}, nullptr},
+    {"0x5e in string", "\" ^ \"", 5, {{Item(" ^ "), {}}}, nullptr},
+    {"0x5f in string", "\" _ \"", 5, {{Item(" _ "), {}}}, nullptr},
+    {"0x60 in string", "\" ` \"", 5, {{Item(" ` "), {}}}, nullptr},
+    {"0x61 in string", "\" a \"", 5, {{Item(" a "), {}}}, nullptr},
+    {"0x62 in string", "\" b \"", 5, {{Item(" b "), {}}}, nullptr},
+    {"0x63 in string", "\" c \"", 5, {{Item(" c "), {}}}, nullptr},
+    {"0x64 in string", "\" d \"", 5, {{Item(" d "), {}}}, nullptr},
+    {"0x65 in string", "\" e \"", 5, {{Item(" e "), {}}}, nullptr},
+    {"0x66 in string", "\" f \"", 5, {{Item(" f "), {}}}, nullptr},
+    {"0x67 in string", "\" g \"", 5, {{Item(" g "), {}}}, nullptr},
+    {"0x68 in string", "\" h \"", 5, {{Item(" h "), {}}}, nullptr},
+    {"0x69 in string", "\" i \"", 5, {{Item(" i "), {}}}, nullptr},
+    {"0x6a in string", "\" j \"", 5, {{Item(" j "), {}}}, nullptr},
+    {"0x6b in string", "\" k \"", 5, {{Item(" k "), {}}}, nullptr},
+    {"0x6c in string", "\" l \"", 5, {{Item(" l "), {}}}, nullptr},
+    {"0x6d in string", "\" m \"", 5, {{Item(" m "), {}}}, nullptr},
+    {"0x6e in string", "\" n \"", 5, {{Item(" n "), {}}}, nullptr},
+    {"0x6f in string", "\" o \"", 5, {{Item(" o "), {}}}, nullptr},
+    {"0x70 in string", "\" p \"", 5, {{Item(" p "), {}}}, nullptr},
+    {"0x71 in string", "\" q \"", 5, {{Item(" q "), {}}}, nullptr},
+    {"0x72 in string", "\" r \"", 5, {{Item(" r "), {}}}, nullptr},
+    {"0x73 in string", "\" s \"", 5, {{Item(" s "), {}}}, nullptr},
+    {"0x74 in string", "\" t \"", 5, {{Item(" t "), {}}}, nullptr},
+    {"0x75 in string", "\" u \"", 5, {{Item(" u "), {}}}, nullptr},
+    {"0x76 in string", "\" v \"", 5, {{Item(" v "), {}}}, nullptr},
+    {"0x77 in string", "\" w \"", 5, {{Item(" w "), {}}}, nullptr},
+    {"0x78 in string", "\" x \"", 5, {{Item(" x "), {}}}, nullptr},
+    {"0x79 in string", "\" y \"", 5, {{Item(" y "), {}}}, nullptr},
+    {"0x7a in string", "\" z \"", 5, {{Item(" z "), {}}}, nullptr},
+    {"0x7b in string", "\" { \"", 5, {{Item(" { "), {}}}, nullptr},
+    {"0x7c in string", "\" | \"", 5, {{Item(" | "), {}}}, nullptr},
+    {"0x7d in string", "\" } \"", 5, {{Item(" } "), {}}}, nullptr},
+    {"0x7e in string", "\" ~ \"", 5, {{Item(" ~ "), {}}}, nullptr},
+    {"0x7f in string", "\" \177 \"", 5, absl::nullopt, nullptr},
+    {"Escaped 0x00 in string", "\"\\\000\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x01 in string", "\"\\\001\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x02 in string", "\"\\\002\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x03 in string", "\"\\\003\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x04 in string", "\"\\\004\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x05 in string", "\"\\\005\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x06 in string", "\"\\\006\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x07 in string", "\"\\\a\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x08 in string", "\"\\\b\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x09 in string", "\"\\\t\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x0a in string", "\"\\\n\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x0b in string", "\"\\\v\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x0c in string", "\"\\\f\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x0d in string", "\"\\\r\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x0e in string", "\"\\\016\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x0f in string", "\"\\\017\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x10 in string", "\"\\\020\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x11 in string", "\"\\\021\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x12 in string", "\"\\\022\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x13 in string", "\"\\\023\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x14 in string", "\"\\\024\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x15 in string", "\"\\\025\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x16 in string", "\"\\\026\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x17 in string", "\"\\\027\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x18 in string", "\"\\\030\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x19 in string", "\"\\\031\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x1a in string", "\"\\\032\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x1b in string", "\"\\\033\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x1c in string", "\"\\\034\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x1d in string", "\"\\\035\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x1e in string", "\"\\\036\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x1f in string", "\"\\\037\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x20 in string", "\"\\ \"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x21 in string", "\"\\!\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x22 in string", "\"\\\"\"", 4, {{Item("\""), {}}}, nullptr},
+    {"Escaped 0x23 in string", "\"\\#\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x24 in string", "\"\\$\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x25 in string", "\"\\%\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x26 in string", "\"\\&\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x27 in string", "\"\\'\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x28 in string", "\"\\(\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x29 in string", "\"\\)\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x2a in string", "\"\\*\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x2b in string", "\"\\+\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x2c in string", "\"\\,\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x2d in string", "\"\\-\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x2e in string", "\"\\.\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x2f in string", "\"\\/\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x30 in string", "\"\\0\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x31 in string", "\"\\1\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x32 in string", "\"\\2\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x33 in string", "\"\\3\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x34 in string", "\"\\4\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x35 in string", "\"\\5\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x36 in string", "\"\\6\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x37 in string", "\"\\7\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x38 in string", "\"\\8\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x39 in string", "\"\\9\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x3a in string", "\"\\:\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x3b in string", "\"\\;\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x3c in string", "\"\\<\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x3d in string", "\"\\=\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x3e in string", "\"\\>\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x3f in string", "\"\\?\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x40 in string", "\"\\@\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x41 in string", "\"\\A\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x42 in string", "\"\\B\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x43 in string", "\"\\C\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x44 in string", "\"\\D\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x45 in string", "\"\\E\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x46 in string", "\"\\F\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x47 in string", "\"\\G\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x48 in string", "\"\\H\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x49 in string", "\"\\I\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x4a in string", "\"\\J\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x4b in string", "\"\\K\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x4c in string", "\"\\L\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x4d in string", "\"\\M\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x4e in string", "\"\\N\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x4f in string", "\"\\O\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x50 in string", "\"\\P\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x51 in string", "\"\\Q\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x52 in string", "\"\\R\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x53 in string", "\"\\S\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x54 in string", "\"\\T\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x55 in string", "\"\\U\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x56 in string", "\"\\V\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x57 in string", "\"\\W\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x58 in string", "\"\\X\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x59 in string", "\"\\Y\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x5a in string", "\"\\Z\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x5b in string", "\"\\[\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x5c in string", "\"\\\\\"", 4, {{Item("\\"), {}}}, nullptr},
+    {"Escaped 0x5d in string", "\"\\]\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x5e in string", "\"\\^\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x5f in string", "\"\\_\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x60 in string", "\"\\`\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x61 in string", "\"\\a\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x62 in string", "\"\\b\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x63 in string", "\"\\c\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x64 in string", "\"\\d\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x65 in string", "\"\\e\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x66 in string", "\"\\f\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x67 in string", "\"\\g\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x68 in string", "\"\\h\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x69 in string", "\"\\i\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x6a in string", "\"\\j\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x6b in string", "\"\\k\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x6c in string", "\"\\l\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x6d in string", "\"\\m\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x6e in string", "\"\\n\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x6f in string", "\"\\o\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x70 in string", "\"\\p\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x71 in string", "\"\\q\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x72 in string", "\"\\r\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x73 in string", "\"\\s\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x74 in string", "\"\\t\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x75 in string", "\"\\u\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x76 in string", "\"\\v\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x77 in string", "\"\\w\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x78 in string", "\"\\x\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x79 in string", "\"\\y\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x7a in string", "\"\\z\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x7b in string", "\"\\{\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x7c in string", "\"\\|\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x7d in string", "\"\\}\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x7e in string", "\"\\~\"", 4, absl::nullopt, nullptr},
+    {"Escaped 0x7f in string", "\"\\\177\"", 4, absl::nullopt, nullptr},
+    // string.json
+    {"basic string", "\"foo bar\"", 9, {{Item("foo bar"), {}}}, nullptr},
+    {"empty string", "\"\"", 2, {{Item(""), {}}}, nullptr},
+    {"long string",
+     "\"foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+     "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+     "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+     "foo foo foo foo foo foo foo foo foo foo foo foo \"",
+     262,
+     {{Item("foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+            "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+            "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+            "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo "
+            "foo "),
+       {}}},
+     nullptr},
+    {"whitespace string", "\"   \"", 5, {{Item("   "), {}}}, nullptr},
+    {"non-ascii string", "\"f\374\374\"", 5, absl::nullopt, nullptr},
+    {"tab in string", "\"\\t\"", 4, absl::nullopt, nullptr},
+    {"newline in string", "\" \\n \"", 6, absl::nullopt, nullptr},
+    {"single quoted string", "'foo'", 5, absl::nullopt, nullptr},
+    {"unbalanced string", "\"foo", 4, absl::nullopt, nullptr},
+    {"string quoting",
+     "\"foo \\\"bar\\\" \\\\ baz\"",
+     20,
+     {{Item("foo \"bar\" \\ baz"), {}}},
+     nullptr},
+    {"bad string quoting", "\"foo \\,\"", 8, absl::nullopt, nullptr},
+    {"ending string quote", "\"foo \\\"", 7, absl::nullopt, nullptr},
+    {"abruptly ending string quote", "\"foo \\", 6, absl::nullopt, nullptr},
+    // token-generated.json
+    {"0x00 in token", "a\000a", 3, absl::nullopt, nullptr},
+    {"0x01 in token", "a\001a", 3, absl::nullopt, nullptr},
+    {"0x02 in token", "a\002a", 3, absl::nullopt, nullptr},
+    {"0x03 in token", "a\003a", 3, absl::nullopt, nullptr},
+    {"0x04 in token", "a\004a", 3, absl::nullopt, nullptr},
+    {"0x05 in token", "a\005a", 3, absl::nullopt, nullptr},
+    {"0x06 in token", "a\006a", 3, absl::nullopt, nullptr},
+    {"0x07 in token", "a\aa", 3, absl::nullopt, nullptr},
+    {"0x08 in token", "a\ba", 3, absl::nullopt, nullptr},
+    {"0x09 in token", "a\ta", 3, absl::nullopt, nullptr},
+    {"0x0a in token", "a\na", 3, absl::nullopt, nullptr},
+    {"0x0b in token", "a\va", 3, absl::nullopt, nullptr},
+    {"0x0c in token", "a\fa", 3, absl::nullopt, nullptr},
+    {"0x0d in token", "a\ra", 3, absl::nullopt, nullptr},
+    {"0x0e in token", "a\016a", 3, absl::nullopt, nullptr},
+    {"0x0f in token", "a\017a", 3, absl::nullopt, nullptr},
+    {"0x10 in token", "a\020a", 3, absl::nullopt, nullptr},
+    {"0x11 in token", "a\021a", 3, absl::nullopt, nullptr},
+    {"0x12 in token", "a\022a", 3, absl::nullopt, nullptr},
+    {"0x13 in token", "a\023a", 3, absl::nullopt, nullptr},
+    {"0x14 in token", "a\024a", 3, absl::nullopt, nullptr},
+    {"0x15 in token", "a\025a", 3, absl::nullopt, nullptr},
+    {"0x16 in token", "a\026a", 3, absl::nullopt, nullptr},
+    {"0x17 in token", "a\027a", 3, absl::nullopt, nullptr},
+    {"0x18 in token", "a\030a", 3, absl::nullopt, nullptr},
+    {"0x19 in token", "a\031a", 3, absl::nullopt, nullptr},
+    {"0x1a in token", "a\032a", 3, absl::nullopt, nullptr},
+    {"0x1b in token", "a\033a", 3, absl::nullopt, nullptr},
+    {"0x1c in token", "a\034a", 3, absl::nullopt, nullptr},
+    {"0x1d in token", "a\035a", 3, absl::nullopt, nullptr},
+    {"0x1e in token", "a\036a", 3, absl::nullopt, nullptr},
+    {"0x1f in token", "a\037a", 3, absl::nullopt, nullptr},
+    {"0x20 in token", "a a", 3, absl::nullopt, nullptr},
+    {"0x21 in token", "a!a", 3, {{Item("a!a", Item::kTokenType), {}}}, nullptr},
+    {"0x22 in token", "a\"a", 3, absl::nullopt, nullptr},
+    {"0x23 in token", "a#a", 3, {{Item("a#a", Item::kTokenType), {}}}, nullptr},
+    {"0x24 in token", "a$a", 3, {{Item("a$a", Item::kTokenType), {}}}, nullptr},
+    {"0x25 in token", "a%a", 3, {{Item("a%a", Item::kTokenType), {}}}, nullptr},
+    {"0x26 in token", "a&a", 3, {{Item("a&a", Item::kTokenType), {}}}, nullptr},
+    {"0x27 in token", "a'a", 3, {{Item("a'a", Item::kTokenType), {}}}, nullptr},
+    {"0x28 in token", "a(a", 3, absl::nullopt, nullptr},
+    {"0x29 in token", "a)a", 3, absl::nullopt, nullptr},
+    {"0x2a in token", "a*a", 3, {{Item("a*a", Item::kTokenType), {}}}, nullptr},
+    {"0x2b in token", "a+a", 3, {{Item("a+a", Item::kTokenType), {}}}, nullptr},
+    {"0x2c in token", "a,a", 3, absl::nullopt, nullptr},
+    {"0x2d in token", "a-a", 3, {{Item("a-a", Item::kTokenType), {}}}, nullptr},
+    {"0x2e in token", "a.a", 3, {{Item("a.a", Item::kTokenType), {}}}, nullptr},
+    {"0x2f in token", "a/a", 3, {{Item("a/a", Item::kTokenType), {}}}, nullptr},
+    {"0x30 in token", "a0a", 3, {{Item("a0a", Item::kTokenType), {}}}, nullptr},
+    {"0x31 in token", "a1a", 3, {{Item("a1a", Item::kTokenType), {}}}, nullptr},
+    {"0x32 in token", "a2a", 3, {{Item("a2a", Item::kTokenType), {}}}, nullptr},
+    {"0x33 in token", "a3a", 3, {{Item("a3a", Item::kTokenType), {}}}, nullptr},
+    {"0x34 in token", "a4a", 3, {{Item("a4a", Item::kTokenType), {}}}, nullptr},
+    {"0x35 in token", "a5a", 3, {{Item("a5a", Item::kTokenType), {}}}, nullptr},
+    {"0x36 in token", "a6a", 3, {{Item("a6a", Item::kTokenType), {}}}, nullptr},
+    {"0x37 in token", "a7a", 3, {{Item("a7a", Item::kTokenType), {}}}, nullptr},
+    {"0x38 in token", "a8a", 3, {{Item("a8a", Item::kTokenType), {}}}, nullptr},
+    {"0x39 in token", "a9a", 3, {{Item("a9a", Item::kTokenType), {}}}, nullptr},
+    {"0x3a in token", "a:a", 3, {{Item("a:a", Item::kTokenType), {}}}, nullptr},
+    {"0x3b in token",
+     "a;a",
+     3,
+     {{Item("a", Item::kTokenType), {BooleanParam("a", true)}}},
+     nullptr},
+    {"0x3c in token", "a<a", 3, absl::nullopt, nullptr},
+    {"0x3d in token", "a=a", 3, absl::nullopt, nullptr},
+    {"0x3e in token", "a>a", 3, absl::nullopt, nullptr},
+    {"0x3f in token", "a?a", 3, absl::nullopt, nullptr},
+    {"0x40 in token", "a@a", 3, absl::nullopt, nullptr},
+    {"0x41 in token", "aAa", 3, {{Item("aAa", Item::kTokenType), {}}}, nullptr},
+    {"0x42 in token", "aBa", 3, {{Item("aBa", Item::kTokenType), {}}}, nullptr},
+    {"0x43 in token", "aCa", 3, {{Item("aCa", Item::kTokenType), {}}}, nullptr},
+    {"0x44 in token", "aDa", 3, {{Item("aDa", Item::kTokenType), {}}}, nullptr},
+    {"0x45 in token", "aEa", 3, {{Item("aEa", Item::kTokenType), {}}}, nullptr},
+    {"0x46 in token", "aFa", 3, {{Item("aFa", Item::kTokenType), {}}}, nullptr},
+    {"0x47 in token", "aGa", 3, {{Item("aGa", Item::kTokenType), {}}}, nullptr},
+    {"0x48 in token", "aHa", 3, {{Item("aHa", Item::kTokenType), {}}}, nullptr},
+    {"0x49 in token", "aIa", 3, {{Item("aIa", Item::kTokenType), {}}}, nullptr},
+    {"0x4a in token", "aJa", 3, {{Item("aJa", Item::kTokenType), {}}}, nullptr},
+    {"0x4b in token", "aKa", 3, {{Item("aKa", Item::kTokenType), {}}}, nullptr},
+    {"0x4c in token", "aLa", 3, {{Item("aLa", Item::kTokenType), {}}}, nullptr},
+    {"0x4d in token", "aMa", 3, {{Item("aMa", Item::kTokenType), {}}}, nullptr},
+    {"0x4e in token", "aNa", 3, {{Item("aNa", Item::kTokenType), {}}}, nullptr},
+    {"0x4f in token", "aOa", 3, {{Item("aOa", Item::kTokenType), {}}}, nullptr},
+    {"0x50 in token", "aPa", 3, {{Item("aPa", Item::kTokenType), {}}}, nullptr},
+    {"0x51 in token", "aQa", 3, {{Item("aQa", Item::kTokenType), {}}}, nullptr},
+    {"0x52 in token", "aRa", 3, {{Item("aRa", Item::kTokenType), {}}}, nullptr},
+    {"0x53 in token", "aSa", 3, {{Item("aSa", Item::kTokenType), {}}}, nullptr},
+    {"0x54 in token", "aTa", 3, {{Item("aTa", Item::kTokenType), {}}}, nullptr},
+    {"0x55 in token", "aUa", 3, {{Item("aUa", Item::kTokenType), {}}}, nullptr},
+    {"0x56 in token", "aVa", 3, {{Item("aVa", Item::kTokenType), {}}}, nullptr},
+    {"0x57 in token", "aWa", 3, {{Item("aWa", Item::kTokenType), {}}}, nullptr},
+    {"0x58 in token", "aXa", 3, {{Item("aXa", Item::kTokenType), {}}}, nullptr},
+    {"0x59 in token", "aYa", 3, {{Item("aYa", Item::kTokenType), {}}}, nullptr},
+    {"0x5a in token", "aZa", 3, {{Item("aZa", Item::kTokenType), {}}}, nullptr},
+    {"0x5b in token", "a[a", 3, absl::nullopt, nullptr},
+    {"0x5c in token", "a\\a", 3, absl::nullopt, nullptr},
+    {"0x5d in token", "a]a", 3, absl::nullopt, nullptr},
+    {"0x5e in token", "a^a", 3, {{Item("a^a", Item::kTokenType), {}}}, nullptr},
+    {"0x5f in token", "a_a", 3, {{Item("a_a", Item::kTokenType), {}}}, nullptr},
+    {"0x60 in token", "a`a", 3, {{Item("a`a", Item::kTokenType), {}}}, nullptr},
+    {"0x61 in token", "aaa", 3, {{Item("aaa", Item::kTokenType), {}}}, nullptr},
+    {"0x62 in token", "aba", 3, {{Item("aba", Item::kTokenType), {}}}, nullptr},
+    {"0x63 in token", "aca", 3, {{Item("aca", Item::kTokenType), {}}}, nullptr},
+    {"0x64 in token", "ada", 3, {{Item("ada", Item::kTokenType), {}}}, nullptr},
+    {"0x65 in token", "aea", 3, {{Item("aea", Item::kTokenType), {}}}, nullptr},
+    {"0x66 in token", "afa", 3, {{Item("afa", Item::kTokenType), {}}}, nullptr},
+    {"0x67 in token", "aga", 3, {{Item("aga", Item::kTokenType), {}}}, nullptr},
+    {"0x68 in token", "aha", 3, {{Item("aha", Item::kTokenType), {}}}, nullptr},
+    {"0x69 in token", "aia", 3, {{Item("aia", Item::kTokenType), {}}}, nullptr},
+    {"0x6a in token", "aja", 3, {{Item("aja", Item::kTokenType), {}}}, nullptr},
+    {"0x6b in token", "aka", 3, {{Item("aka", Item::kTokenType), {}}}, nullptr},
+    {"0x6c in token", "ala", 3, {{Item("ala", Item::kTokenType), {}}}, nullptr},
+    {"0x6d in token", "ama", 3, {{Item("ama", Item::kTokenType), {}}}, nullptr},
+    {"0x6e in token", "ana", 3, {{Item("ana", Item::kTokenType), {}}}, nullptr},
+    {"0x6f in token", "aoa", 3, {{Item("aoa", Item::kTokenType), {}}}, nullptr},
+    {"0x70 in token", "apa", 3, {{Item("apa", Item::kTokenType), {}}}, nullptr},
+    {"0x71 in token", "aqa", 3, {{Item("aqa", Item::kTokenType), {}}}, nullptr},
+    {"0x72 in token", "ara", 3, {{Item("ara", Item::kTokenType), {}}}, nullptr},
+    {"0x73 in token", "asa", 3, {{Item("asa", Item::kTokenType), {}}}, nullptr},
+    {"0x74 in token", "ata", 3, {{Item("ata", Item::kTokenType), {}}}, nullptr},
+    {"0x75 in token", "aua", 3, {{Item("aua", Item::kTokenType), {}}}, nullptr},
+    {"0x76 in token", "ava", 3, {{Item("ava", Item::kTokenType), {}}}, nullptr},
+    {"0x77 in token", "awa", 3, {{Item("awa", Item::kTokenType), {}}}, nullptr},
+    {"0x78 in token", "axa", 3, {{Item("axa", Item::kTokenType), {}}}, nullptr},
+    {"0x79 in token", "aya", 3, {{Item("aya", Item::kTokenType), {}}}, nullptr},
+    {"0x7a in token", "aza", 3, {{Item("aza", Item::kTokenType), {}}}, nullptr},
+    {"0x7b in token", "a{a", 3, absl::nullopt, nullptr},
+    {"0x7c in token", "a|a", 3, {{Item("a|a", Item::kTokenType), {}}}, nullptr},
+    {"0x7d in token", "a}a", 3, absl::nullopt, nullptr},
+    {"0x7e in token", "a~a", 3, {{Item("a~a", Item::kTokenType), {}}}, nullptr},
+    {"0x7f in token", "a\177a", 3, absl::nullopt, nullptr},
+    {"0x00 starting an token", "\000a", 2, absl::nullopt, nullptr},
+    {"0x01 starting an token", "\001a", 2, absl::nullopt, nullptr},
+    {"0x02 starting an token", "\002a", 2, absl::nullopt, nullptr},
+    {"0x03 starting an token", "\003a", 2, absl::nullopt, nullptr},
+    {"0x04 starting an token", "\004a", 2, absl::nullopt, nullptr},
+    {"0x05 starting an token", "\005a", 2, absl::nullopt, nullptr},
+    {"0x06 starting an token", "\006a", 2, absl::nullopt, nullptr},
+    {"0x07 starting an token", "\aa", 2, absl::nullopt, nullptr},
+    {"0x08 starting an token", "\ba", 2, absl::nullopt, nullptr},
+    {"0x09 starting an token", "\ta", 2, absl::nullopt, nullptr},
+    {"0x0a starting an token", "\na", 2, absl::nullopt, nullptr},
+    {"0x0b starting an token", "\va", 2, absl::nullopt, nullptr},
+    {"0x0c starting an token", "\fa", 2, absl::nullopt, nullptr},
+    {"0x0d starting an token", "\ra", 2, absl::nullopt, nullptr},
+    {"0x0e starting an token", "\016a", 2, absl::nullopt, nullptr},
+    {"0x0f starting an token", "\017a", 2, absl::nullopt, nullptr},
+    {"0x10 starting an token", "\020a", 2, absl::nullopt, nullptr},
+    {"0x11 starting an token", "\021a", 2, absl::nullopt, nullptr},
+    {"0x12 starting an token", "\022a", 2, absl::nullopt, nullptr},
+    {"0x13 starting an token", "\023a", 2, absl::nullopt, nullptr},
+    {"0x14 starting an token", "\024a", 2, absl::nullopt, nullptr},
+    {"0x15 starting an token", "\025a", 2, absl::nullopt, nullptr},
+    {"0x16 starting an token", "\026a", 2, absl::nullopt, nullptr},
+    {"0x17 starting an token", "\027a", 2, absl::nullopt, nullptr},
+    {"0x18 starting an token", "\030a", 2, absl::nullopt, nullptr},
+    {"0x19 starting an token", "\031a", 2, absl::nullopt, nullptr},
+    {"0x1a starting an token", "\032a", 2, absl::nullopt, nullptr},
+    {"0x1b starting an token", "\033a", 2, absl::nullopt, nullptr},
+    {"0x1c starting an token", "\034a", 2, absl::nullopt, nullptr},
+    {"0x1d starting an token", "\035a", 2, absl::nullopt, nullptr},
+    {"0x1e starting an token", "\036a", 2, absl::nullopt, nullptr},
+    {"0x1f starting an token", "\037a", 2, absl::nullopt, nullptr},
+    {"0x20 starting an token",
+     " a",
+     2,
+     {{Item("a", Item::kTokenType), {}}},
+     "a"},
+    {"0x21 starting an token", "!a", 2, absl::nullopt, nullptr},
+    {"0x22 starting an token", "\"a", 2, absl::nullopt, nullptr},
+    {"0x23 starting an token", "#a", 2, absl::nullopt, nullptr},
+    {"0x24 starting an token", "$a", 2, absl::nullopt, nullptr},
+    {"0x25 starting an token", "%a", 2, absl::nullopt, nullptr},
+    {"0x26 starting an token", "&a", 2, absl::nullopt, nullptr},
+    {"0x27 starting an token", "'a", 2, absl::nullopt, nullptr},
+    {"0x28 starting an token", "(a", 2, absl::nullopt, nullptr},
+    {"0x29 starting an token", ")a", 2, absl::nullopt, nullptr},
+    {"0x2a starting an token",
+     "*a",
+     2,
+     {{Item("*a", Item::kTokenType), {}}},
+     nullptr},
+    {"0x2b starting an token", "+a", 2, absl::nullopt, nullptr},
+    {"0x2c starting an token", ",a", 2, absl::nullopt, nullptr},
+    {"0x2d starting an token", "-a", 2, absl::nullopt, nullptr},
+    {"0x2e starting an token", ".a", 2, absl::nullopt, nullptr},
+    {"0x2f starting an token", "/a", 2, absl::nullopt, nullptr},
+    {"0x30 starting an token", "0a", 2, absl::nullopt, nullptr},
+    {"0x31 starting an token", "1a", 2, absl::nullopt, nullptr},
+    {"0x32 starting an token", "2a", 2, absl::nullopt, nullptr},
+    {"0x33 starting an token", "3a", 2, absl::nullopt, nullptr},
+    {"0x34 starting an token", "4a", 2, absl::nullopt, nullptr},
+    {"0x35 starting an token", "5a", 2, absl::nullopt, nullptr},
+    {"0x36 starting an token", "6a", 2, absl::nullopt, nullptr},
+    {"0x37 starting an token", "7a", 2, absl::nullopt, nullptr},
+    {"0x38 starting an token", "8a", 2, absl::nullopt, nullptr},
+    {"0x39 starting an token", "9a", 2, absl::nullopt, nullptr},
+    {"0x3a starting an token", ":a", 2, absl::nullopt, nullptr},
+    {"0x3b starting an token", ";a", 2, absl::nullopt, nullptr},
+    {"0x3c starting an token", "<a", 2, absl::nullopt, nullptr},
+    {"0x3d starting an token", "=a", 2, absl::nullopt, nullptr},
+    {"0x3e starting an token", ">a", 2, absl::nullopt, nullptr},
+    {"0x3f starting an token", "?a", 2, absl::nullopt, nullptr},
+    {"0x40 starting an token", "@a", 2, absl::nullopt, nullptr},
+    {"0x41 starting an token",
+     "Aa",
+     2,
+     {{Item("Aa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x42 starting an token",
+     "Ba",
+     2,
+     {{Item("Ba", Item::kTokenType), {}}},
+     nullptr},
+    {"0x43 starting an token",
+     "Ca",
+     2,
+     {{Item("Ca", Item::kTokenType), {}}},
+     nullptr},
+    {"0x44 starting an token",
+     "Da",
+     2,
+     {{Item("Da", Item::kTokenType), {}}},
+     nullptr},
+    {"0x45 starting an token",
+     "Ea",
+     2,
+     {{Item("Ea", Item::kTokenType), {}}},
+     nullptr},
+    {"0x46 starting an token",
+     "Fa",
+     2,
+     {{Item("Fa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x47 starting an token",
+     "Ga",
+     2,
+     {{Item("Ga", Item::kTokenType), {}}},
+     nullptr},
+    {"0x48 starting an token",
+     "Ha",
+     2,
+     {{Item("Ha", Item::kTokenType), {}}},
+     nullptr},
+    {"0x49 starting an token",
+     "Ia",
+     2,
+     {{Item("Ia", Item::kTokenType), {}}},
+     nullptr},
+    {"0x4a starting an token",
+     "Ja",
+     2,
+     {{Item("Ja", Item::kTokenType), {}}},
+     nullptr},
+    {"0x4b starting an token",
+     "Ka",
+     2,
+     {{Item("Ka", Item::kTokenType), {}}},
+     nullptr},
+    {"0x4c starting an token",
+     "La",
+     2,
+     {{Item("La", Item::kTokenType), {}}},
+     nullptr},
+    {"0x4d starting an token",
+     "Ma",
+     2,
+     {{Item("Ma", Item::kTokenType), {}}},
+     nullptr},
+    {"0x4e starting an token",
+     "Na",
+     2,
+     {{Item("Na", Item::kTokenType), {}}},
+     nullptr},
+    {"0x4f starting an token",
+     "Oa",
+     2,
+     {{Item("Oa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x50 starting an token",
+     "Pa",
+     2,
+     {{Item("Pa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x51 starting an token",
+     "Qa",
+     2,
+     {{Item("Qa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x52 starting an token",
+     "Ra",
+     2,
+     {{Item("Ra", Item::kTokenType), {}}},
+     nullptr},
+    {"0x53 starting an token",
+     "Sa",
+     2,
+     {{Item("Sa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x54 starting an token",
+     "Ta",
+     2,
+     {{Item("Ta", Item::kTokenType), {}}},
+     nullptr},
+    {"0x55 starting an token",
+     "Ua",
+     2,
+     {{Item("Ua", Item::kTokenType), {}}},
+     nullptr},
+    {"0x56 starting an token",
+     "Va",
+     2,
+     {{Item("Va", Item::kTokenType), {}}},
+     nullptr},
+    {"0x57 starting an token",
+     "Wa",
+     2,
+     {{Item("Wa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x58 starting an token",
+     "Xa",
+     2,
+     {{Item("Xa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x59 starting an token",
+     "Ya",
+     2,
+     {{Item("Ya", Item::kTokenType), {}}},
+     nullptr},
+    {"0x5a starting an token",
+     "Za",
+     2,
+     {{Item("Za", Item::kTokenType), {}}},
+     nullptr},
+    {"0x5b starting an token", "[a", 2, absl::nullopt, nullptr},
+    {"0x5c starting an token", "\\a", 2, absl::nullopt, nullptr},
+    {"0x5d starting an token", "]a", 2, absl::nullopt, nullptr},
+    {"0x5e starting an token", "^a", 2, absl::nullopt, nullptr},
+    {"0x5f starting an token", "_a", 2, absl::nullopt, nullptr},
+    {"0x60 starting an token", "`a", 2, absl::nullopt, nullptr},
+    {"0x61 starting an token",
+     "aa",
+     2,
+     {{Item("aa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x62 starting an token",
+     "ba",
+     2,
+     {{Item("ba", Item::kTokenType), {}}},
+     nullptr},
+    {"0x63 starting an token",
+     "ca",
+     2,
+     {{Item("ca", Item::kTokenType), {}}},
+     nullptr},
+    {"0x64 starting an token",
+     "da",
+     2,
+     {{Item("da", Item::kTokenType), {}}},
+     nullptr},
+    {"0x65 starting an token",
+     "ea",
+     2,
+     {{Item("ea", Item::kTokenType), {}}},
+     nullptr},
+    {"0x66 starting an token",
+     "fa",
+     2,
+     {{Item("fa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x67 starting an token",
+     "ga",
+     2,
+     {{Item("ga", Item::kTokenType), {}}},
+     nullptr},
+    {"0x68 starting an token",
+     "ha",
+     2,
+     {{Item("ha", Item::kTokenType), {}}},
+     nullptr},
+    {"0x69 starting an token",
+     "ia",
+     2,
+     {{Item("ia", Item::kTokenType), {}}},
+     nullptr},
+    {"0x6a starting an token",
+     "ja",
+     2,
+     {{Item("ja", Item::kTokenType), {}}},
+     nullptr},
+    {"0x6b starting an token",
+     "ka",
+     2,
+     {{Item("ka", Item::kTokenType), {}}},
+     nullptr},
+    {"0x6c starting an token",
+     "la",
+     2,
+     {{Item("la", Item::kTokenType), {}}},
+     nullptr},
+    {"0x6d starting an token",
+     "ma",
+     2,
+     {{Item("ma", Item::kTokenType), {}}},
+     nullptr},
+    {"0x6e starting an token",
+     "na",
+     2,
+     {{Item("na", Item::kTokenType), {}}},
+     nullptr},
+    {"0x6f starting an token",
+     "oa",
+     2,
+     {{Item("oa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x70 starting an token",
+     "pa",
+     2,
+     {{Item("pa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x71 starting an token",
+     "qa",
+     2,
+     {{Item("qa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x72 starting an token",
+     "ra",
+     2,
+     {{Item("ra", Item::kTokenType), {}}},
+     nullptr},
+    {"0x73 starting an token",
+     "sa",
+     2,
+     {{Item("sa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x74 starting an token",
+     "ta",
+     2,
+     {{Item("ta", Item::kTokenType), {}}},
+     nullptr},
+    {"0x75 starting an token",
+     "ua",
+     2,
+     {{Item("ua", Item::kTokenType), {}}},
+     nullptr},
+    {"0x76 starting an token",
+     "va",
+     2,
+     {{Item("va", Item::kTokenType), {}}},
+     nullptr},
+    {"0x77 starting an token",
+     "wa",
+     2,
+     {{Item("wa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x78 starting an token",
+     "xa",
+     2,
+     {{Item("xa", Item::kTokenType), {}}},
+     nullptr},
+    {"0x79 starting an token",
+     "ya",
+     2,
+     {{Item("ya", Item::kTokenType), {}}},
+     nullptr},
+    {"0x7a starting an token",
+     "za",
+     2,
+     {{Item("za", Item::kTokenType), {}}},
+     nullptr},
+    {"0x7b starting an token", "{a", 2, absl::nullopt, nullptr},
+    {"0x7c starting an token", "|a", 2, absl::nullopt, nullptr},
+    {"0x7d starting an token", "}a", 2, absl::nullopt, nullptr},
+    {"0x7e starting an token", "~a", 2, absl::nullopt, nullptr},
+    {"0x7f starting an token", "\177a", 2, absl::nullopt, nullptr},
+    // token.json
+    {"basic token - item",
+     "a_b-c.d3:f%00/*",
+     15,
+     {{Item("a_b-c.d3:f%00/*", Item::kTokenType), {}}},
+     nullptr},
+    {"token with capitals - item",
+     "fooBar",
+     6,
+     {{Item("fooBar", Item::kTokenType), {}}},
+     nullptr},
+    {"token starting with capitals - item",
+     "FooBar",
+     6,
+     {{Item("FooBar", Item::kTokenType), {}}},
+     nullptr},
+};
+
+const struct ListTestCase {
+  const char* name;
+  const char* raw;
+  size_t raw_len;
+  const absl::optional<List> expected;  // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} list_test_cases[] = {
+    // examples.json
+    {"Example-StrListHeader",
+     "\"foo\", \"bar\", \"It was the best of times.\"",
+     41,
+     {{{Item("foo"), {}},
+       {Item("bar"), {}},
+       {Item("It was the best of times."), {}}}},
+     nullptr},
+    {"Example-Hdr (list on one line)",
+     "foo, bar",
+     8,
+     {{{Item("foo", Item::kTokenType), {}},
+       {Item("bar", Item::kTokenType), {}}}},
+     nullptr},
+    {"Example-Hdr (list on two lines)",
+     "foo, bar",
+     8,
+     {{{Item("foo", Item::kTokenType), {}},
+       {Item("bar", Item::kTokenType), {}}}},
+     "foo, bar"},
+    {"Example-StrListListHeader",
+     "(\"foo\" \"bar\"), (\"baz\"), (\"bat\" \"one\"), ()",
+     41,
+     {{{{{Item("foo"), {}}, {Item("bar"), {}}}, {}},
+       {{{Item("baz"), {}}}, {}},
+       {{{Item("bat"), {}}, {Item("one"), {}}}, {}},
+       {std::vector<ParameterizedItem>(), {}}}},
+     nullptr},
+    {"Example-ListListParam",
+     "(\"foo\"; a=1;b=2);lvl=5, (\"bar\" \"baz\");lvl=1",
+     43,
+     {{{{{Item("foo"), {Param("a", 1), Param("b", 2)}}}, {Param("lvl", 5)}},
+       {{{Item("bar"), {}}, {Item("baz"), {}}}, {Param("lvl", 1)}}}},
+     "(\"foo\";a=1;b=2);lvl=5, (\"bar\" \"baz\");lvl=1"},
+    {"Example-ParamListHeader",
+     "abc;a=1;b=2; cde_456, (ghi;jk=4 l);q=\"9\";r=w",
+     44,
+     {{{Item("abc", Item::kTokenType),
+        {Param("a", 1), Param("b", 2), BooleanParam("cde_456", true)}},
+       {{{Item("ghi", Item::kTokenType), {Param("jk", 4)}},
+         {Item("l", Item::kTokenType), {}}},
+        {Param("q", "9"), TokenParam("r", "w")}}}},
+     "abc;a=1;b=2;cde_456, (ghi;jk=4 l);q=\"9\";r=w"},
+    // key-generated.json
+    {"0x00 in parameterised list key", "foo; a\000a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x01 in parameterised list key", "foo; a\001a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x02 in parameterised list key", "foo; a\002a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x03 in parameterised list key", "foo; a\003a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x04 in parameterised list key", "foo; a\004a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x05 in parameterised list key", "foo; a\005a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x06 in parameterised list key", "foo; a\006a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x07 in parameterised list key", "foo; a\aa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x08 in parameterised list key", "foo; a\ba=1", 10, absl::nullopt,
+     nullptr},
+    {"0x09 in parameterised list key", "foo; a\ta=1", 10, absl::nullopt,
+     nullptr},
+    {"0x0a in parameterised list key", "foo; a\na=1", 10, absl::nullopt,
+     nullptr},
+    {"0x0b in parameterised list key", "foo; a\va=1", 10, absl::nullopt,
+     nullptr},
+    {"0x0c in parameterised list key", "foo; a\fa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x0d in parameterised list key", "foo; a\ra=1", 10, absl::nullopt,
+     nullptr},
+    {"0x0e in parameterised list key", "foo; a\016a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x0f in parameterised list key", "foo; a\017a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x10 in parameterised list key", "foo; a\020a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x11 in parameterised list key", "foo; a\021a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x12 in parameterised list key", "foo; a\022a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x13 in parameterised list key", "foo; a\023a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x14 in parameterised list key", "foo; a\024a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x15 in parameterised list key", "foo; a\025a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x16 in parameterised list key", "foo; a\026a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x17 in parameterised list key", "foo; a\027a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x18 in parameterised list key", "foo; a\030a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x19 in parameterised list key", "foo; a\031a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x1a in parameterised list key", "foo; a\032a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x1b in parameterised list key", "foo; a\033a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x1c in parameterised list key", "foo; a\034a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x1d in parameterised list key", "foo; a\035a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x1e in parameterised list key", "foo; a\036a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x1f in parameterised list key", "foo; a\037a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x20 in parameterised list key", "foo; a a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x21 in parameterised list key", "foo; a!a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x22 in parameterised list key", "foo; a\"a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x23 in parameterised list key", "foo; a#a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x24 in parameterised list key", "foo; a$a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x25 in parameterised list key", "foo; a%a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x26 in parameterised list key", "foo; a&a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x27 in parameterised list key", "foo; a'a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x28 in parameterised list key", "foo; a(a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x29 in parameterised list key", "foo; a)a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x2a in parameterised list key",
+     "foo; a*a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a*a", 1)}}}},
+     "foo;a*a=1"},
+    {"0x2b in parameterised list key", "foo; a+a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x2c in parameterised list key", "foo; a,a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x2d in parameterised list key",
+     "foo; a-a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a-a", 1)}}}},
+     "foo;a-a=1"},
+    {"0x2e in parameterised list key",
+     "foo; a.a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a.a", 1)}}}},
+     "foo;a.a=1"},
+    {"0x2f in parameterised list key", "foo; a/a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x30 in parameterised list key",
+     "foo; a0a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a0a", 1)}}}},
+     "foo;a0a=1"},
+    {"0x31 in parameterised list key",
+     "foo; a1a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a1a", 1)}}}},
+     "foo;a1a=1"},
+    {"0x32 in parameterised list key",
+     "foo; a2a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a2a", 1)}}}},
+     "foo;a2a=1"},
+    {"0x33 in parameterised list key",
+     "foo; a3a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a3a", 1)}}}},
+     "foo;a3a=1"},
+    {"0x34 in parameterised list key",
+     "foo; a4a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a4a", 1)}}}},
+     "foo;a4a=1"},
+    {"0x35 in parameterised list key",
+     "foo; a5a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a5a", 1)}}}},
+     "foo;a5a=1"},
+    {"0x36 in parameterised list key",
+     "foo; a6a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a6a", 1)}}}},
+     "foo;a6a=1"},
+    {"0x37 in parameterised list key",
+     "foo; a7a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a7a", 1)}}}},
+     "foo;a7a=1"},
+    {"0x38 in parameterised list key",
+     "foo; a8a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a8a", 1)}}}},
+     "foo;a8a=1"},
+    {"0x39 in parameterised list key",
+     "foo; a9a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a9a", 1)}}}},
+     "foo;a9a=1"},
+    {"0x3a in parameterised list key", "foo; a:a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x3b in parameterised list key",
+     "foo; a;a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a", 1)}}}},
+     "foo;a=1"},
+    {"0x3c in parameterised list key", "foo; a<a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x3d in parameterised list key", "foo; a=a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x3e in parameterised list key", "foo; a>a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x3f in parameterised list key", "foo; a?a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x40 in parameterised list key", "foo; a@a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x41 in parameterised list key", "foo; aAa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x42 in parameterised list key", "foo; aBa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x43 in parameterised list key", "foo; aCa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x44 in parameterised list key", "foo; aDa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x45 in parameterised list key", "foo; aEa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x46 in parameterised list key", "foo; aFa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x47 in parameterised list key", "foo; aGa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x48 in parameterised list key", "foo; aHa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x49 in parameterised list key", "foo; aIa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x4a in parameterised list key", "foo; aJa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x4b in parameterised list key", "foo; aKa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x4c in parameterised list key", "foo; aLa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x4d in parameterised list key", "foo; aMa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x4e in parameterised list key", "foo; aNa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x4f in parameterised list key", "foo; aOa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x50 in parameterised list key", "foo; aPa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x51 in parameterised list key", "foo; aQa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x52 in parameterised list key", "foo; aRa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x53 in parameterised list key", "foo; aSa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x54 in parameterised list key", "foo; aTa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x55 in parameterised list key", "foo; aUa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x56 in parameterised list key", "foo; aVa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x57 in parameterised list key", "foo; aWa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x58 in parameterised list key", "foo; aXa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x59 in parameterised list key", "foo; aYa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x5a in parameterised list key", "foo; aZa=1", 10, absl::nullopt,
+     nullptr},
+    {"0x5b in parameterised list key", "foo; a[a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x5c in parameterised list key", "foo; a\\a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x5d in parameterised list key", "foo; a]a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x5e in parameterised list key", "foo; a^a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x5f in parameterised list key",
+     "foo; a_a=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("a_a", 1)}}}},
+     "foo;a_a=1"},
+    {"0x60 in parameterised list key", "foo; a`a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x61 in parameterised list key",
+     "foo; aaa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aaa", 1)}}}},
+     "foo;aaa=1"},
+    {"0x62 in parameterised list key",
+     "foo; aba=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aba", 1)}}}},
+     "foo;aba=1"},
+    {"0x63 in parameterised list key",
+     "foo; aca=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aca", 1)}}}},
+     "foo;aca=1"},
+    {"0x64 in parameterised list key",
+     "foo; ada=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ada", 1)}}}},
+     "foo;ada=1"},
+    {"0x65 in parameterised list key",
+     "foo; aea=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aea", 1)}}}},
+     "foo;aea=1"},
+    {"0x66 in parameterised list key",
+     "foo; afa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("afa", 1)}}}},
+     "foo;afa=1"},
+    {"0x67 in parameterised list key",
+     "foo; aga=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aga", 1)}}}},
+     "foo;aga=1"},
+    {"0x68 in parameterised list key",
+     "foo; aha=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aha", 1)}}}},
+     "foo;aha=1"},
+    {"0x69 in parameterised list key",
+     "foo; aia=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aia", 1)}}}},
+     "foo;aia=1"},
+    {"0x6a in parameterised list key",
+     "foo; aja=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aja", 1)}}}},
+     "foo;aja=1"},
+    {"0x6b in parameterised list key",
+     "foo; aka=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aka", 1)}}}},
+     "foo;aka=1"},
+    {"0x6c in parameterised list key",
+     "foo; ala=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ala", 1)}}}},
+     "foo;ala=1"},
+    {"0x6d in parameterised list key",
+     "foo; ama=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ama", 1)}}}},
+     "foo;ama=1"},
+    {"0x6e in parameterised list key",
+     "foo; ana=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ana", 1)}}}},
+     "foo;ana=1"},
+    {"0x6f in parameterised list key",
+     "foo; aoa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aoa", 1)}}}},
+     "foo;aoa=1"},
+    {"0x70 in parameterised list key",
+     "foo; apa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("apa", 1)}}}},
+     "foo;apa=1"},
+    {"0x71 in parameterised list key",
+     "foo; aqa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aqa", 1)}}}},
+     "foo;aqa=1"},
+    {"0x72 in parameterised list key",
+     "foo; ara=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ara", 1)}}}},
+     "foo;ara=1"},
+    {"0x73 in parameterised list key",
+     "foo; asa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("asa", 1)}}}},
+     "foo;asa=1"},
+    {"0x74 in parameterised list key",
+     "foo; ata=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ata", 1)}}}},
+     "foo;ata=1"},
+    {"0x75 in parameterised list key",
+     "foo; aua=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aua", 1)}}}},
+     "foo;aua=1"},
+    {"0x76 in parameterised list key",
+     "foo; ava=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("ava", 1)}}}},
+     "foo;ava=1"},
+    {"0x77 in parameterised list key",
+     "foo; awa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("awa", 1)}}}},
+     "foo;awa=1"},
+    {"0x78 in parameterised list key",
+     "foo; axa=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("axa", 1)}}}},
+     "foo;axa=1"},
+    {"0x79 in parameterised list key",
+     "foo; aya=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aya", 1)}}}},
+     "foo;aya=1"},
+    {"0x7a in parameterised list key",
+     "foo; aza=1",
+     10,
+     {{{Item("foo", Item::kTokenType), {Param("aza", 1)}}}},
+     "foo;aza=1"},
+    {"0x7b in parameterised list key", "foo; a{a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x7c in parameterised list key", "foo; a|a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x7d in parameterised list key", "foo; a}a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x7e in parameterised list key", "foo; a~a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x7f in parameterised list key", "foo; a\177a=1", 10, absl::nullopt,
+     nullptr},
+    {"0x00 starting a parameterised list key", "foo; \000a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x01 starting a parameterised list key", "foo; \001a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x02 starting a parameterised list key", "foo; \002a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x03 starting a parameterised list key", "foo; \003a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x04 starting a parameterised list key", "foo; \004a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x05 starting a parameterised list key", "foo; \005a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x06 starting a parameterised list key", "foo; \006a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x07 starting a parameterised list key", "foo; \aa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x08 starting a parameterised list key", "foo; \ba=1", 9, absl::nullopt,
+     nullptr},
+    {"0x09 starting a parameterised list key", "foo; \ta=1", 9, absl::nullopt,
+     nullptr},
+    {"0x0a starting a parameterised list key", "foo; \na=1", 9, absl::nullopt,
+     nullptr},
+    {"0x0b starting a parameterised list key", "foo; \va=1", 9, absl::nullopt,
+     nullptr},
+    {"0x0c starting a parameterised list key", "foo; \fa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x0d starting a parameterised list key", "foo; \ra=1", 9, absl::nullopt,
+     nullptr},
+    {"0x0e starting a parameterised list key", "foo; \016a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x0f starting a parameterised list key", "foo; \017a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x10 starting a parameterised list key", "foo; \020a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x11 starting a parameterised list key", "foo; \021a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x12 starting a parameterised list key", "foo; \022a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x13 starting a parameterised list key", "foo; \023a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x14 starting a parameterised list key", "foo; \024a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x15 starting a parameterised list key", "foo; \025a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x16 starting a parameterised list key", "foo; \026a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x17 starting a parameterised list key", "foo; \027a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x18 starting a parameterised list key", "foo; \030a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x19 starting a parameterised list key", "foo; \031a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x1a starting a parameterised list key", "foo; \032a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x1b starting a parameterised list key", "foo; \033a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x1c starting a parameterised list key", "foo; \034a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x1d starting a parameterised list key", "foo; \035a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x1e starting a parameterised list key", "foo; \036a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x1f starting a parameterised list key", "foo; \037a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x20 starting a parameterised list key",
+     "foo;  a=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("a", 1)}}}},
+     "foo;a=1"},
+    {"0x21 starting a parameterised list key", "foo; !a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x22 starting a parameterised list key", "foo; \"a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x23 starting a parameterised list key", "foo; #a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x24 starting a parameterised list key", "foo; $a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x25 starting a parameterised list key", "foo; %a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x26 starting a parameterised list key", "foo; &a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x27 starting a parameterised list key", "foo; 'a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x28 starting a parameterised list key", "foo; (a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x29 starting a parameterised list key", "foo; )a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x2a starting a parameterised list key",
+     "foo; *a=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("*a", 1)}}}},
+     "foo;*a=1"},
+    {"0x2b starting a parameterised list key", "foo; +a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x2c starting a parameterised list key", "foo; ,a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x2d starting a parameterised list key", "foo; -a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x2e starting a parameterised list key", "foo; .a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x2f starting a parameterised list key", "foo; /a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x30 starting a parameterised list key", "foo; 0a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x31 starting a parameterised list key", "foo; 1a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x32 starting a parameterised list key", "foo; 2a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x33 starting a parameterised list key", "foo; 3a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x34 starting a parameterised list key", "foo; 4a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x35 starting a parameterised list key", "foo; 5a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x36 starting a parameterised list key", "foo; 6a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x37 starting a parameterised list key", "foo; 7a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x38 starting a parameterised list key", "foo; 8a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x39 starting a parameterised list key", "foo; 9a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x3a starting a parameterised list key", "foo; :a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x3b starting a parameterised list key", "foo; ;a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x3c starting a parameterised list key", "foo; <a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x3d starting a parameterised list key", "foo; =a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x3e starting a parameterised list key", "foo; >a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x3f starting a parameterised list key", "foo; ?a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x40 starting a parameterised list key", "foo; @a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x41 starting a parameterised list key", "foo; Aa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x42 starting a parameterised list key", "foo; Ba=1", 9, absl::nullopt,
+     nullptr},
+    {"0x43 starting a parameterised list key", "foo; Ca=1", 9, absl::nullopt,
+     nullptr},
+    {"0x44 starting a parameterised list key", "foo; Da=1", 9, absl::nullopt,
+     nullptr},
+    {"0x45 starting a parameterised list key", "foo; Ea=1", 9, absl::nullopt,
+     nullptr},
+    {"0x46 starting a parameterised list key", "foo; Fa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x47 starting a parameterised list key", "foo; Ga=1", 9, absl::nullopt,
+     nullptr},
+    {"0x48 starting a parameterised list key", "foo; Ha=1", 9, absl::nullopt,
+     nullptr},
+    {"0x49 starting a parameterised list key", "foo; Ia=1", 9, absl::nullopt,
+     nullptr},
+    {"0x4a starting a parameterised list key", "foo; Ja=1", 9, absl::nullopt,
+     nullptr},
+    {"0x4b starting a parameterised list key", "foo; Ka=1", 9, absl::nullopt,
+     nullptr},
+    {"0x4c starting a parameterised list key", "foo; La=1", 9, absl::nullopt,
+     nullptr},
+    {"0x4d starting a parameterised list key", "foo; Ma=1", 9, absl::nullopt,
+     nullptr},
+    {"0x4e starting a parameterised list key", "foo; Na=1", 9, absl::nullopt,
+     nullptr},
+    {"0x4f starting a parameterised list key", "foo; Oa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x50 starting a parameterised list key", "foo; Pa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x51 starting a parameterised list key", "foo; Qa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x52 starting a parameterised list key", "foo; Ra=1", 9, absl::nullopt,
+     nullptr},
+    {"0x53 starting a parameterised list key", "foo; Sa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x54 starting a parameterised list key", "foo; Ta=1", 9, absl::nullopt,
+     nullptr},
+    {"0x55 starting a parameterised list key", "foo; Ua=1", 9, absl::nullopt,
+     nullptr},
+    {"0x56 starting a parameterised list key", "foo; Va=1", 9, absl::nullopt,
+     nullptr},
+    {"0x57 starting a parameterised list key", "foo; Wa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x58 starting a parameterised list key", "foo; Xa=1", 9, absl::nullopt,
+     nullptr},
+    {"0x59 starting a parameterised list key", "foo; Ya=1", 9, absl::nullopt,
+     nullptr},
+    {"0x5a starting a parameterised list key", "foo; Za=1", 9, absl::nullopt,
+     nullptr},
+    {"0x5b starting a parameterised list key", "foo; [a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x5c starting a parameterised list key", "foo; \\a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x5d starting a parameterised list key", "foo; ]a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x5e starting a parameterised list key", "foo; ^a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x5f starting a parameterised list key", "foo; _a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x60 starting a parameterised list key", "foo; `a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x61 starting a parameterised list key",
+     "foo; aa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("aa", 1)}}}},
+     "foo;aa=1"},
+    {"0x62 starting a parameterised list key",
+     "foo; ba=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ba", 1)}}}},
+     "foo;ba=1"},
+    {"0x63 starting a parameterised list key",
+     "foo; ca=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ca", 1)}}}},
+     "foo;ca=1"},
+    {"0x64 starting a parameterised list key",
+     "foo; da=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("da", 1)}}}},
+     "foo;da=1"},
+    {"0x65 starting a parameterised list key",
+     "foo; ea=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ea", 1)}}}},
+     "foo;ea=1"},
+    {"0x66 starting a parameterised list key",
+     "foo; fa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("fa", 1)}}}},
+     "foo;fa=1"},
+    {"0x67 starting a parameterised list key",
+     "foo; ga=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ga", 1)}}}},
+     "foo;ga=1"},
+    {"0x68 starting a parameterised list key",
+     "foo; ha=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ha", 1)}}}},
+     "foo;ha=1"},
+    {"0x69 starting a parameterised list key",
+     "foo; ia=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ia", 1)}}}},
+     "foo;ia=1"},
+    {"0x6a starting a parameterised list key",
+     "foo; ja=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ja", 1)}}}},
+     "foo;ja=1"},
+    {"0x6b starting a parameterised list key",
+     "foo; ka=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ka", 1)}}}},
+     "foo;ka=1"},
+    {"0x6c starting a parameterised list key",
+     "foo; la=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("la", 1)}}}},
+     "foo;la=1"},
+    {"0x6d starting a parameterised list key",
+     "foo; ma=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ma", 1)}}}},
+     "foo;ma=1"},
+    {"0x6e starting a parameterised list key",
+     "foo; na=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("na", 1)}}}},
+     "foo;na=1"},
+    {"0x6f starting a parameterised list key",
+     "foo; oa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("oa", 1)}}}},
+     "foo;oa=1"},
+    {"0x70 starting a parameterised list key",
+     "foo; pa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("pa", 1)}}}},
+     "foo;pa=1"},
+    {"0x71 starting a parameterised list key",
+     "foo; qa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("qa", 1)}}}},
+     "foo;qa=1"},
+    {"0x72 starting a parameterised list key",
+     "foo; ra=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ra", 1)}}}},
+     "foo;ra=1"},
+    {"0x73 starting a parameterised list key",
+     "foo; sa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("sa", 1)}}}},
+     "foo;sa=1"},
+    {"0x74 starting a parameterised list key",
+     "foo; ta=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ta", 1)}}}},
+     "foo;ta=1"},
+    {"0x75 starting a parameterised list key",
+     "foo; ua=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ua", 1)}}}},
+     "foo;ua=1"},
+    {"0x76 starting a parameterised list key",
+     "foo; va=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("va", 1)}}}},
+     "foo;va=1"},
+    {"0x77 starting a parameterised list key",
+     "foo; wa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("wa", 1)}}}},
+     "foo;wa=1"},
+    {"0x78 starting a parameterised list key",
+     "foo; xa=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("xa", 1)}}}},
+     "foo;xa=1"},
+    {"0x79 starting a parameterised list key",
+     "foo; ya=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("ya", 1)}}}},
+     "foo;ya=1"},
+    {"0x7a starting a parameterised list key",
+     "foo; za=1",
+     9,
+     {{{Item("foo", Item::kTokenType), {Param("za", 1)}}}},
+     "foo;za=1"},
+    {"0x7b starting a parameterised list key", "foo; {a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x7c starting a parameterised list key", "foo; |a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x7d starting a parameterised list key", "foo; }a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x7e starting a parameterised list key", "foo; ~a=1", 9, absl::nullopt,
+     nullptr},
+    {"0x7f starting a parameterised list key", "foo; \177a=1", 9, absl::nullopt,
+     nullptr},
+    // list.json
+    {"basic list",
+     "1, 42",
+     5,
+     {{{Integer(1), {}}, {Integer(42), {}}}},
+     nullptr},
+    {"empty list", "", 0, {List()}, nullptr},
+    {"leading SP list",
+     "  42, 43",
+     8,
+     {{{Integer(42), {}}, {Integer(43), {}}}},
+     "42, 43"},
+    {"single item list", "42", 2, {{{Integer(42), {}}}}, nullptr},
+    {"no whitespace list",
+     "1,42",
+     4,
+     {{{Integer(1), {}}, {Integer(42), {}}}},
+     "1, 42"},
+    {"extra whitespace list",
+     "1 , 42",
+     6,
+     {{{Integer(1), {}}, {Integer(42), {}}}},
+     "1, 42"},
+    {"tab separated list",
+     "1\t,\t42",
+     6,
+     {{{Integer(1), {}}, {Integer(42), {}}}},
+     "1, 42"},
+    {"two line list",
+     "1, 42",
+     5,
+     {{{Integer(1), {}}, {Integer(42), {}}}},
+     "1, 42"},
+    {"trailing comma list", "1, 42,", 6, absl::nullopt, nullptr},
+    {"empty item list", "1,,42", 5, absl::nullopt, nullptr},
+    {"empty item list (multiple field lines)", "1, , 42", 7, absl::nullopt,
+     nullptr},
+    // listlist.json
+    {"basic list of lists",
+     "(1 2), (42 43)",
+     14,
+     {{{{{Integer(1), {}}, {Integer(2), {}}}, {}},
+       {{{Integer(42), {}}, {Integer(43), {}}}, {}}}},
+     nullptr},
+    {"single item list of lists",
+     "(42)",
+     4,
+     {{{{{Integer(42), {}}}, {}}}},
+     nullptr},
+    {"empty item list of lists",
+     "()",
+     2,
+     {{{std::vector<ParameterizedItem>(), {}}}},
+     nullptr},
+    {"empty middle item list of lists",
+     "(1),(),(42)",
+     11,
+     {{{{{Integer(1), {}}}, {}},
+       {std::vector<ParameterizedItem>(), {}},
+       {{{Integer(42), {}}}, {}}}},
+     "(1), (), (42)"},
+    {"extra whitespace list of lists",
+     "(  1  42  )",
+     11,
+     {{{{{Integer(1), {}}, {Integer(42), {}}}, {}}}},
+     "(1 42)"},
+    {"wrong whitespace list of lists", "(1\t 42)", 7, absl::nullopt, nullptr},
+    {"no trailing parenthesis list of lists", "(1 42", 5, absl::nullopt,
+     nullptr},
+    {"no trailing parenthesis middle list of lists", "(1 2, (42 43)", 13,
+     absl::nullopt, nullptr},
+    {"no spaces in inner-list", "(abc\"def\"?0123*dXZ3*xyz)", 24, absl::nullopt,
+     nullptr},
+    {"no closing parenthesis", "(", 1, absl::nullopt, nullptr},
+    // param-list.json
+    {"basic parameterised list",
+     "abc_123;a=1;b=2; cdef_456, ghi;q=9;r=\"+w\"",
+     41,
+     {{{Item("abc_123", Item::kTokenType),
+        {Param("a", 1), Param("b", 2), BooleanParam("cdef_456", true)}},
+       {Item("ghi", Item::kTokenType), {Param("q", 9), Param("r", "+w")}}}},
+     "abc_123;a=1;b=2;cdef_456, ghi;q=9;r=\"+w\""},
+    {"single item parameterised list",
+     "text/html;q=1.0",
+     15,
+     {{{Item("text/html", Item::kTokenType), {DoubleParam("q", 1.000000)}}}},
+     nullptr},
+    {"missing parameter value parameterised list",
+     "text/html;a;q=1.0",
+     17,
+     {{{Item("text/html", Item::kTokenType),
+        {BooleanParam("a", true), DoubleParam("q", 1.000000)}}}},
+     nullptr},
+    {"missing terminal parameter value parameterised list",
+     "text/html;q=1.0;a",
+     17,
+     {{{Item("text/html", Item::kTokenType),
+        {DoubleParam("q", 1.000000), BooleanParam("a", true)}}}},
+     nullptr},
+    {"no whitespace parameterised list",
+     "text/html,text/plain;q=0.5",
+     26,
+     {{{Item("text/html", Item::kTokenType), {}},
+       {Item("text/plain", Item::kTokenType), {DoubleParam("q", 0.500000)}}}},
+     "text/html, text/plain;q=0.5"},
+    {"whitespace before = parameterised list", "text/html, text/plain;q =0.5",
+     28, absl::nullopt, nullptr},
+    {"whitespace after = parameterised list", "text/html, text/plain;q= 0.5",
+     28, absl::nullopt, nullptr},
+    {"whitespace before ; parameterised list", "text/html, text/plain ;q=0.5",
+     28, absl::nullopt, nullptr},
+    {"whitespace after ; parameterised list",
+     "text/html, text/plain; q=0.5",
+     28,
+     {{{Item("text/html", Item::kTokenType), {}},
+       {Item("text/plain", Item::kTokenType), {DoubleParam("q", 0.500000)}}}},
+     "text/html, text/plain;q=0.5"},
+    {"extra whitespace parameterised list",
+     "text/html  ,  text/plain;  q=0.5;  charset=utf-8",
+     48,
+     {{{Item("text/html", Item::kTokenType), {}},
+       {Item("text/plain", Item::kTokenType),
+        {DoubleParam("q", 0.500000), TokenParam("charset", "utf-8")}}}},
+     "text/html, text/plain;q=0.5;charset=utf-8"},
+    {"two lines parameterised list",
+     "text/html, text/plain;q=0.5",
+     27,
+     {{{Item("text/html", Item::kTokenType), {}},
+       {Item("text/plain", Item::kTokenType), {DoubleParam("q", 0.500000)}}}},
+     "text/html, text/plain;q=0.5"},
+    {"trailing comma parameterised list", "text/html,text/plain;q=0.5,", 27,
+     absl::nullopt, nullptr},
+    {"empty item parameterised list", "text/html,,text/plain;q=0.5,", 28,
+     absl::nullopt, nullptr},
+    // param-listlist.json
+    {"parameterised inner list",
+     "(abc_123);a=1;b=2, cdef_456",
+     27,
+     {{{{{Item("abc_123", Item::kTokenType), {}}},
+        {Param("a", 1), Param("b", 2)}},
+       {Item("cdef_456", Item::kTokenType), {}}}},
+     nullptr},
+    {"parameterised inner list item",
+     "(abc_123;a=1;b=2;cdef_456)",
+     26,
+     {{{{{Item("abc_123", Item::kTokenType),
+          {Param("a", 1), Param("b", 2), BooleanParam("cdef_456", true)}}},
+        {}}}},
+     nullptr},
+    {"parameterised inner list with parameterised item",
+     "(abc_123;a=1;b=2);cdef_456",
+     26,
+     {{{{{Item("abc_123", Item::kTokenType), {Param("a", 1), Param("b", 2)}}},
+        {BooleanParam("cdef_456", true)}}}},
+     nullptr},
+    // token.json
+    {"basic token - list",
+     "a_b-c3/*",
+     8,
+     {{{Item("a_b-c3/*", Item::kTokenType), {}}}},
+     nullptr},
+    {"token with capitals - list",
+     "fooBar",
+     6,
+     {{{Item("fooBar", Item::kTokenType), {}}}},
+     nullptr},
+    {"token starting with capitals - list",
+     "FooBar",
+     6,
+     {{{Item("FooBar", Item::kTokenType), {}}}},
+     nullptr},
+};
+
+const struct DictionaryTestCase {
+  const char* name;
+  const char* raw;
+  size_t raw_len;
+  const absl::optional<Dictionary>
+      expected;           // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} dictionary_test_cases[] = {
+    // dictionary.json
+    {"basic dictionary",
+     "en=\"Applepie\", da=:w4ZibGV0w6ZydGUK:",
+     36,
+     {Dictionary{
+         {{"en", {Item("Applepie"), {}}},
+          {"da",
+           {Item("\303\206blet\303\246rte\n", Item::kByteSequenceType), {}}}}}},
+     nullptr},
+    {"empty dictionary", "", 0, {Dictionary{{}}}, nullptr},
+    {"single item dictionary",
+     "a=1",
+     3,
+     {Dictionary{{{"a", {Integer(1), {}}}}}},
+     nullptr},
+    {"list item dictionary",
+     "a=(1 2)",
+     7,
+     {Dictionary{{{"a", {{{Integer(1), {}}, {Integer(2), {}}}, {}}}}}},
+     nullptr},
+    {"single list item dictionary",
+     "a=(1)",
+     5,
+     {Dictionary{{{"a", {{{Integer(1), {}}}, {}}}}}},
+     nullptr},
+    {"empty list item dictionary",
+     "a=()",
+     4,
+     {Dictionary{{{"a", {std::vector<ParameterizedItem>(), {}}}}}},
+     nullptr},
+    {"no whitespace dictionary",
+     "a=1,b=2",
+     7,
+     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
+     "a=1, b=2"},
+    {"extra whitespace dictionary",
+     "a=1 ,  b=2",
+     10,
+     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
+     "a=1, b=2"},
+    {"tab separated dictionary",
+     "a=1\t,\tb=2",
+     9,
+     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
+     "a=1, b=2"},
+    {"leading whitespace dictionary",
+     "     a=1 ,  b=2",
+     15,
+     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
+     "a=1, b=2"},
+    {"whitespace before = dictionary", "a =1, b=2", 9, absl::nullopt, nullptr},
+    {"whitespace after = dictionary", "a=1, b= 2", 9, absl::nullopt, nullptr},
+    {"two lines dictionary",
+     "a=1, b=2",
+     8,
+     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Integer(2), {}}}}}},
+     "a=1, b=2"},
+    {"missing value dictionary",
+     "a=1, b, c=3",
+     11,
+     {Dictionary{{{"a", {Integer(1), {}}},
+                  {"b", {Item(true), {}}},
+                  {"c", {Integer(3), {}}}}}},
+     nullptr},
+    {"all missing value dictionary",
+     "a, b, c",
+     7,
+     {Dictionary{{{"a", {Item(true), {}}},
+                  {"b", {Item(true), {}}},
+                  {"c", {Item(true), {}}}}}},
+     nullptr},
+    {"start missing value dictionary",
+     "a, b=2",
+     6,
+     {Dictionary{{{"a", {Item(true), {}}}, {"b", {Integer(2), {}}}}}},
+     nullptr},
+    {"end missing value dictionary",
+     "a=1, b",
+     6,
+     {Dictionary{{{"a", {Integer(1), {}}}, {"b", {Item(true), {}}}}}},
+     nullptr},
+    {"missing value with params dictionary",
+     "a=1, b;foo=9, c=3",
+     17,
+     {Dictionary{{{"a", {Integer(1), {}}},
+                  {"b", {Item(true), {Param("foo", 9)}}},
+                  {"c", {Integer(3), {}}}}}},
+     nullptr},
+    {"explicit true value with params dictionary",
+     "a=1, b=?1;foo=9, c=3",
+     20,
+     {Dictionary{{{"a", {Integer(1), {}}},
+                  {"b", {Item(true), {Param("foo", 9)}}},
+                  {"c", {Integer(3), {}}}}}},
+     "a=1, b;foo=9, c=3"},
+    {"trailing comma dictionary", "a=1, b=2,", 9, absl::nullopt, nullptr},
+    {"empty item dictionary", "a=1,,b=2,", 9, absl::nullopt, nullptr},
+    {"duplicate key dictionary",
+     "a=1,b=2,a=3",
+     11,
+     {Dictionary{{{"a", {Integer(3), {}}}, {"b", {Integer(2), {}}}}}},
+     "a=3, b=2"},
+    {"numeric key dictionary", "a=1,1b=2,a=1", 12, absl::nullopt, nullptr},
+    {"uppercase key dictionary", "a=1,B=2,a=1", 11, absl::nullopt, nullptr},
+    {"bad key dictionary", "a=1,b!=2,a=1", 12, absl::nullopt, nullptr},
+    // examples.json
+    {"Example-DictHeader",
+     "en=\"Applepie\", da=:w4ZibGV0w6ZydGU=:",
+     36,
+     {Dictionary{
+         {{"en", {Item("Applepie"), {}}},
+          {"da",
+           {Item("\303\206blet\303\246rte", Item::kByteSequenceType), {}}}}}},
+     nullptr},
+    {"Example-DictHeader (boolean values)",
+     "a=?0, b, c; foo=bar",
+     19,
+     {Dictionary{{{"a", {Item(false), {}}},
+                  {"b", {Item(true), {}}},
+                  {"c", {Item(true), {TokenParam("foo", "bar")}}}}}},
+     "a=?0, b, c;foo=bar"},
+    {"Example-DictListHeader",
+     "rating=1.5, feelings=(joy sadness)",
+     34,
+     {Dictionary{{{"rating", {Item(1.500000), {}}},
+                  {"feelings",
+                   {{{Item("joy", Item::kTokenType), {}},
+                     {Item("sadness", Item::kTokenType), {}}},
+                    {}}}}}},
+     nullptr},
+    {"Example-MixDict",
+     "a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid",
+     38,
+     {Dictionary{{{"a", {{{Integer(1), {}}, {Integer(2), {}}}, {}}},
+                  {"b", {Integer(3), {}}},
+                  {"c", {Integer(4), {TokenParam("aa", "bb")}}},
+                  {"d",
+                   {{{Integer(5), {}}, {Integer(6), {}}},
+                    {BooleanParam("valid", true)}}}}}},
+     "a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid"},
+    {"Example-Hdr (dictionary on one line)",
+     "foo=1, bar=2",
+     12,
+     {Dictionary{{{"foo", {Integer(1), {}}}, {"bar", {Integer(2), {}}}}}},
+     nullptr},
+    {"Example-Hdr (dictionary on two lines)",
+     "foo=1, bar=2",
+     12,
+     {Dictionary{{{"foo", {Integer(1), {}}}, {"bar", {Integer(2), {}}}}}},
+     "foo=1, bar=2"},
+    // key-generated.json
+    {"0x00 as a single-character dictionary key", "\000=1", 3, absl::nullopt,
+     nullptr},
+    {"0x01 as a single-character dictionary key", "\001=1", 3, absl::nullopt,
+     nullptr},
+    {"0x02 as a single-character dictionary key", "\002=1", 3, absl::nullopt,
+     nullptr},
+    {"0x03 as a single-character dictionary key", "\003=1", 3, absl::nullopt,
+     nullptr},
+    {"0x04 as a single-character dictionary key", "\004=1", 3, absl::nullopt,
+     nullptr},
+    {"0x05 as a single-character dictionary key", "\005=1", 3, absl::nullopt,
+     nullptr},
+    {"0x06 as a single-character dictionary key", "\006=1", 3, absl::nullopt,
+     nullptr},
+    {"0x07 as a single-character dictionary key", "\a=1", 3, absl::nullopt,
+     nullptr},
+    {"0x08 as a single-character dictionary key", "\b=1", 3, absl::nullopt,
+     nullptr},
+    {"0x09 as a single-character dictionary key", "\t=1", 3, absl::nullopt,
+     nullptr},
+    {"0x0a as a single-character dictionary key", "\n=1", 3, absl::nullopt,
+     nullptr},
+    {"0x0b as a single-character dictionary key", "\v=1", 3, absl::nullopt,
+     nullptr},
+    {"0x0c as a single-character dictionary key", "\f=1", 3, absl::nullopt,
+     nullptr},
+    {"0x0d as a single-character dictionary key", "\r=1", 3, absl::nullopt,
+     nullptr},
+    {"0x0e as a single-character dictionary key", "\016=1", 3, absl::nullopt,
+     nullptr},
+    {"0x0f as a single-character dictionary key", "\017=1", 3, absl::nullopt,
+     nullptr},
+    {"0x10 as a single-character dictionary key", "\020=1", 3, absl::nullopt,
+     nullptr},
+    {"0x11 as a single-character dictionary key", "\021=1", 3, absl::nullopt,
+     nullptr},
+    {"0x12 as a single-character dictionary key", "\022=1", 3, absl::nullopt,
+     nullptr},
+    {"0x13 as a single-character dictionary key", "\023=1", 3, absl::nullopt,
+     nullptr},
+    {"0x14 as a single-character dictionary key", "\024=1", 3, absl::nullopt,
+     nullptr},
+    {"0x15 as a single-character dictionary key", "\025=1", 3, absl::nullopt,
+     nullptr},
+    {"0x16 as a single-character dictionary key", "\026=1", 3, absl::nullopt,
+     nullptr},
+    {"0x17 as a single-character dictionary key", "\027=1", 3, absl::nullopt,
+     nullptr},
+    {"0x18 as a single-character dictionary key", "\030=1", 3, absl::nullopt,
+     nullptr},
+    {"0x19 as a single-character dictionary key", "\031=1", 3, absl::nullopt,
+     nullptr},
+    {"0x1a as a single-character dictionary key", "\032=1", 3, absl::nullopt,
+     nullptr},
+    {"0x1b as a single-character dictionary key", "\033=1", 3, absl::nullopt,
+     nullptr},
+    {"0x1c as a single-character dictionary key", "\034=1", 3, absl::nullopt,
+     nullptr},
+    {"0x1d as a single-character dictionary key", "\035=1", 3, absl::nullopt,
+     nullptr},
+    {"0x1e as a single-character dictionary key", "\036=1", 3, absl::nullopt,
+     nullptr},
+    {"0x1f as a single-character dictionary key", "\037=1", 3, absl::nullopt,
+     nullptr},
+    {"0x20 as a single-character dictionary key", "=1", 2, absl::nullopt,
+     nullptr},
+    {"0x21 as a single-character dictionary key", "!=1", 3, absl::nullopt,
+     nullptr},
+    {"0x22 as a single-character dictionary key", "\"=1", 3, absl::nullopt,
+     nullptr},
+    {"0x23 as a single-character dictionary key", "#=1", 3, absl::nullopt,
+     nullptr},
+    {"0x24 as a single-character dictionary key", "$=1", 3, absl::nullopt,
+     nullptr},
+    {"0x25 as a single-character dictionary key", "%=1", 3, absl::nullopt,
+     nullptr},
+    {"0x26 as a single-character dictionary key", "&=1", 3, absl::nullopt,
+     nullptr},
+    {"0x27 as a single-character dictionary key", "'=1", 3, absl::nullopt,
+     nullptr},
+    {"0x28 as a single-character dictionary key", "(=1", 3, absl::nullopt,
+     nullptr},
+    {"0x29 as a single-character dictionary key", ")=1", 3, absl::nullopt,
+     nullptr},
+    {"0x2a as a single-character dictionary key",
+     "*=1",
+     3,
+     {Dictionary{{{"*", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x2b as a single-character dictionary key", "+=1", 3, absl::nullopt,
+     nullptr},
+    {"0x2c as a single-character dictionary key", ",=1", 3, absl::nullopt,
+     nullptr},
+    {"0x2d as a single-character dictionary key", "-=1", 3, absl::nullopt,
+     nullptr},
+    {"0x2e as a single-character dictionary key", ".=1", 3, absl::nullopt,
+     nullptr},
+    {"0x2f as a single-character dictionary key", "/=1", 3, absl::nullopt,
+     nullptr},
+    {"0x30 as a single-character dictionary key", "0=1", 3, absl::nullopt,
+     nullptr},
+    {"0x31 as a single-character dictionary key", "1=1", 3, absl::nullopt,
+     nullptr},
+    {"0x32 as a single-character dictionary key", "2=1", 3, absl::nullopt,
+     nullptr},
+    {"0x33 as a single-character dictionary key", "3=1", 3, absl::nullopt,
+     nullptr},
+    {"0x34 as a single-character dictionary key", "4=1", 3, absl::nullopt,
+     nullptr},
+    {"0x35 as a single-character dictionary key", "5=1", 3, absl::nullopt,
+     nullptr},
+    {"0x36 as a single-character dictionary key", "6=1", 3, absl::nullopt,
+     nullptr},
+    {"0x37 as a single-character dictionary key", "7=1", 3, absl::nullopt,
+     nullptr},
+    {"0x38 as a single-character dictionary key", "8=1", 3, absl::nullopt,
+     nullptr},
+    {"0x39 as a single-character dictionary key", "9=1", 3, absl::nullopt,
+     nullptr},
+    {"0x3a as a single-character dictionary key", ":=1", 3, absl::nullopt,
+     nullptr},
+    {"0x3b as a single-character dictionary key", ";=1", 3, absl::nullopt,
+     nullptr},
+    {"0x3c as a single-character dictionary key", "<=1", 3, absl::nullopt,
+     nullptr},
+    {"0x3d as a single-character dictionary key", "==1", 3, absl::nullopt,
+     nullptr},
+    {"0x3e as a single-character dictionary key", ">=1", 3, absl::nullopt,
+     nullptr},
+    {"0x3f as a single-character dictionary key", "?=1", 3, absl::nullopt,
+     nullptr},
+    {"0x40 as a single-character dictionary key", "@=1", 3, absl::nullopt,
+     nullptr},
+    {"0x41 as a single-character dictionary key", "A=1", 3, absl::nullopt,
+     nullptr},
+    {"0x42 as a single-character dictionary key", "B=1", 3, absl::nullopt,
+     nullptr},
+    {"0x43 as a single-character dictionary key", "C=1", 3, absl::nullopt,
+     nullptr},
+    {"0x44 as a single-character dictionary key", "D=1", 3, absl::nullopt,
+     nullptr},
+    {"0x45 as a single-character dictionary key", "E=1", 3, absl::nullopt,
+     nullptr},
+    {"0x46 as a single-character dictionary key", "F=1", 3, absl::nullopt,
+     nullptr},
+    {"0x47 as a single-character dictionary key", "G=1", 3, absl::nullopt,
+     nullptr},
+    {"0x48 as a single-character dictionary key", "H=1", 3, absl::nullopt,
+     nullptr},
+    {"0x49 as a single-character dictionary key", "I=1", 3, absl::nullopt,
+     nullptr},
+    {"0x4a as a single-character dictionary key", "J=1", 3, absl::nullopt,
+     nullptr},
+    {"0x4b as a single-character dictionary key", "K=1", 3, absl::nullopt,
+     nullptr},
+    {"0x4c as a single-character dictionary key", "L=1", 3, absl::nullopt,
+     nullptr},
+    {"0x4d as a single-character dictionary key", "M=1", 3, absl::nullopt,
+     nullptr},
+    {"0x4e as a single-character dictionary key", "N=1", 3, absl::nullopt,
+     nullptr},
+    {"0x4f as a single-character dictionary key", "O=1", 3, absl::nullopt,
+     nullptr},
+    {"0x50 as a single-character dictionary key", "P=1", 3, absl::nullopt,
+     nullptr},
+    {"0x51 as a single-character dictionary key", "Q=1", 3, absl::nullopt,
+     nullptr},
+    {"0x52 as a single-character dictionary key", "R=1", 3, absl::nullopt,
+     nullptr},
+    {"0x53 as a single-character dictionary key", "S=1", 3, absl::nullopt,
+     nullptr},
+    {"0x54 as a single-character dictionary key", "T=1", 3, absl::nullopt,
+     nullptr},
+    {"0x55 as a single-character dictionary key", "U=1", 3, absl::nullopt,
+     nullptr},
+    {"0x56 as a single-character dictionary key", "V=1", 3, absl::nullopt,
+     nullptr},
+    {"0x57 as a single-character dictionary key", "W=1", 3, absl::nullopt,
+     nullptr},
+    {"0x58 as a single-character dictionary key", "X=1", 3, absl::nullopt,
+     nullptr},
+    {"0x59 as a single-character dictionary key", "Y=1", 3, absl::nullopt,
+     nullptr},
+    {"0x5a as a single-character dictionary key", "Z=1", 3, absl::nullopt,
+     nullptr},
+    {"0x5b as a single-character dictionary key", "[=1", 3, absl::nullopt,
+     nullptr},
+    {"0x5c as a single-character dictionary key", "\\=1", 3, absl::nullopt,
+     nullptr},
+    {"0x5d as a single-character dictionary key", "]=1", 3, absl::nullopt,
+     nullptr},
+    {"0x5e as a single-character dictionary key", "^=1", 3, absl::nullopt,
+     nullptr},
+    {"0x5f as a single-character dictionary key", "_=1", 3, absl::nullopt,
+     nullptr},
+    {"0x60 as a single-character dictionary key", "`=1", 3, absl::nullopt,
+     nullptr},
+    {"0x61 as a single-character dictionary key",
+     "a=1",
+     3,
+     {Dictionary{{{"a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x62 as a single-character dictionary key",
+     "b=1",
+     3,
+     {Dictionary{{{"b", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x63 as a single-character dictionary key",
+     "c=1",
+     3,
+     {Dictionary{{{"c", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x64 as a single-character dictionary key",
+     "d=1",
+     3,
+     {Dictionary{{{"d", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x65 as a single-character dictionary key",
+     "e=1",
+     3,
+     {Dictionary{{{"e", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x66 as a single-character dictionary key",
+     "f=1",
+     3,
+     {Dictionary{{{"f", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x67 as a single-character dictionary key",
+     "g=1",
+     3,
+     {Dictionary{{{"g", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x68 as a single-character dictionary key",
+     "h=1",
+     3,
+     {Dictionary{{{"h", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x69 as a single-character dictionary key",
+     "i=1",
+     3,
+     {Dictionary{{{"i", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6a as a single-character dictionary key",
+     "j=1",
+     3,
+     {Dictionary{{{"j", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6b as a single-character dictionary key",
+     "k=1",
+     3,
+     {Dictionary{{{"k", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6c as a single-character dictionary key",
+     "l=1",
+     3,
+     {Dictionary{{{"l", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6d as a single-character dictionary key",
+     "m=1",
+     3,
+     {Dictionary{{{"m", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6e as a single-character dictionary key",
+     "n=1",
+     3,
+     {Dictionary{{{"n", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6f as a single-character dictionary key",
+     "o=1",
+     3,
+     {Dictionary{{{"o", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x70 as a single-character dictionary key",
+     "p=1",
+     3,
+     {Dictionary{{{"p", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x71 as a single-character dictionary key",
+     "q=1",
+     3,
+     {Dictionary{{{"q", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x72 as a single-character dictionary key",
+     "r=1",
+     3,
+     {Dictionary{{{"r", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x73 as a single-character dictionary key",
+     "s=1",
+     3,
+     {Dictionary{{{"s", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x74 as a single-character dictionary key",
+     "t=1",
+     3,
+     {Dictionary{{{"t", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x75 as a single-character dictionary key",
+     "u=1",
+     3,
+     {Dictionary{{{"u", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x76 as a single-character dictionary key",
+     "v=1",
+     3,
+     {Dictionary{{{"v", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x77 as a single-character dictionary key",
+     "w=1",
+     3,
+     {Dictionary{{{"w", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x78 as a single-character dictionary key",
+     "x=1",
+     3,
+     {Dictionary{{{"x", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x79 as a single-character dictionary key",
+     "y=1",
+     3,
+     {Dictionary{{{"y", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x7a as a single-character dictionary key",
+     "z=1",
+     3,
+     {Dictionary{{{"z", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x7b as a single-character dictionary key", "{=1", 3, absl::nullopt,
+     nullptr},
+    {"0x7c as a single-character dictionary key", "|=1", 3, absl::nullopt,
+     nullptr},
+    {"0x7d as a single-character dictionary key", "}=1", 3, absl::nullopt,
+     nullptr},
+    {"0x7e as a single-character dictionary key", "~=1", 3, absl::nullopt,
+     nullptr},
+    {"0x7f as a single-character dictionary key", "\177=1", 3, absl::nullopt,
+     nullptr},
+    {"0x00 in dictionary key", "a\000a=1", 5, absl::nullopt, nullptr},
+    {"0x01 in dictionary key", "a\001a=1", 5, absl::nullopt, nullptr},
+    {"0x02 in dictionary key", "a\002a=1", 5, absl::nullopt, nullptr},
+    {"0x03 in dictionary key", "a\003a=1", 5, absl::nullopt, nullptr},
+    {"0x04 in dictionary key", "a\004a=1", 5, absl::nullopt, nullptr},
+    {"0x05 in dictionary key", "a\005a=1", 5, absl::nullopt, nullptr},
+    {"0x06 in dictionary key", "a\006a=1", 5, absl::nullopt, nullptr},
+    {"0x07 in dictionary key", "a\aa=1", 5, absl::nullopt, nullptr},
+    {"0x08 in dictionary key", "a\ba=1", 5, absl::nullopt, nullptr},
+    {"0x09 in dictionary key", "a\ta=1", 5, absl::nullopt, nullptr},
+    {"0x0a in dictionary key", "a\na=1", 5, absl::nullopt, nullptr},
+    {"0x0b in dictionary key", "a\va=1", 5, absl::nullopt, nullptr},
+    {"0x0c in dictionary key", "a\fa=1", 5, absl::nullopt, nullptr},
+    {"0x0d in dictionary key", "a\ra=1", 5, absl::nullopt, nullptr},
+    {"0x0e in dictionary key", "a\016a=1", 5, absl::nullopt, nullptr},
+    {"0x0f in dictionary key", "a\017a=1", 5, absl::nullopt, nullptr},
+    {"0x10 in dictionary key", "a\020a=1", 5, absl::nullopt, nullptr},
+    {"0x11 in dictionary key", "a\021a=1", 5, absl::nullopt, nullptr},
+    {"0x12 in dictionary key", "a\022a=1", 5, absl::nullopt, nullptr},
+    {"0x13 in dictionary key", "a\023a=1", 5, absl::nullopt, nullptr},
+    {"0x14 in dictionary key", "a\024a=1", 5, absl::nullopt, nullptr},
+    {"0x15 in dictionary key", "a\025a=1", 5, absl::nullopt, nullptr},
+    {"0x16 in dictionary key", "a\026a=1", 5, absl::nullopt, nullptr},
+    {"0x17 in dictionary key", "a\027a=1", 5, absl::nullopt, nullptr},
+    {"0x18 in dictionary key", "a\030a=1", 5, absl::nullopt, nullptr},
+    {"0x19 in dictionary key", "a\031a=1", 5, absl::nullopt, nullptr},
+    {"0x1a in dictionary key", "a\032a=1", 5, absl::nullopt, nullptr},
+    {"0x1b in dictionary key", "a\033a=1", 5, absl::nullopt, nullptr},
+    {"0x1c in dictionary key", "a\034a=1", 5, absl::nullopt, nullptr},
+    {"0x1d in dictionary key", "a\035a=1", 5, absl::nullopt, nullptr},
+    {"0x1e in dictionary key", "a\036a=1", 5, absl::nullopt, nullptr},
+    {"0x1f in dictionary key", "a\037a=1", 5, absl::nullopt, nullptr},
+    {"0x20 in dictionary key", "a a=1", 5, absl::nullopt, nullptr},
+    {"0x21 in dictionary key", "a!a=1", 5, absl::nullopt, nullptr},
+    {"0x22 in dictionary key", "a\"a=1", 5, absl::nullopt, nullptr},
+    {"0x23 in dictionary key", "a#a=1", 5, absl::nullopt, nullptr},
+    {"0x24 in dictionary key", "a$a=1", 5, absl::nullopt, nullptr},
+    {"0x25 in dictionary key", "a%a=1", 5, absl::nullopt, nullptr},
+    {"0x26 in dictionary key", "a&a=1", 5, absl::nullopt, nullptr},
+    {"0x27 in dictionary key", "a'a=1", 5, absl::nullopt, nullptr},
+    {"0x28 in dictionary key", "a(a=1", 5, absl::nullopt, nullptr},
+    {"0x29 in dictionary key", "a)a=1", 5, absl::nullopt, nullptr},
+    {"0x2a in dictionary key",
+     "a*a=1",
+     5,
+     {Dictionary{{{"a*a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x2b in dictionary key", "a+a=1", 5, absl::nullopt, nullptr},
+    {"0x2c in dictionary key",
+     "a,a=1",
+     5,
+     {Dictionary{{{"a", {Integer(1), {}}}}}},
+     "a=1"},
+    {"0x2d in dictionary key",
+     "a-a=1",
+     5,
+     {Dictionary{{{"a-a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x2e in dictionary key",
+     "a.a=1",
+     5,
+     {Dictionary{{{"a.a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x2f in dictionary key", "a/a=1", 5, absl::nullopt, nullptr},
+    {"0x30 in dictionary key",
+     "a0a=1",
+     5,
+     {Dictionary{{{"a0a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x31 in dictionary key",
+     "a1a=1",
+     5,
+     {Dictionary{{{"a1a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x32 in dictionary key",
+     "a2a=1",
+     5,
+     {Dictionary{{{"a2a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x33 in dictionary key",
+     "a3a=1",
+     5,
+     {Dictionary{{{"a3a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x34 in dictionary key",
+     "a4a=1",
+     5,
+     {Dictionary{{{"a4a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x35 in dictionary key",
+     "a5a=1",
+     5,
+     {Dictionary{{{"a5a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x36 in dictionary key",
+     "a6a=1",
+     5,
+     {Dictionary{{{"a6a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x37 in dictionary key",
+     "a7a=1",
+     5,
+     {Dictionary{{{"a7a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x38 in dictionary key",
+     "a8a=1",
+     5,
+     {Dictionary{{{"a8a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x39 in dictionary key",
+     "a9a=1",
+     5,
+     {Dictionary{{{"a9a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x3a in dictionary key", "a:a=1", 5, absl::nullopt, nullptr},
+    {"0x3b in dictionary key",
+     "a;a=1",
+     5,
+     {Dictionary{{{"a", {Item(true), {Param("a", 1)}}}}}},
+     nullptr},
+    {"0x3c in dictionary key", "a<a=1", 5, absl::nullopt, nullptr},
+    {"0x3d in dictionary key", "a=a=1", 5, absl::nullopt, nullptr},
+    {"0x3e in dictionary key", "a>a=1", 5, absl::nullopt, nullptr},
+    {"0x3f in dictionary key", "a?a=1", 5, absl::nullopt, nullptr},
+    {"0x40 in dictionary key", "a@a=1", 5, absl::nullopt, nullptr},
+    {"0x41 in dictionary key", "aAa=1", 5, absl::nullopt, nullptr},
+    {"0x42 in dictionary key", "aBa=1", 5, absl::nullopt, nullptr},
+    {"0x43 in dictionary key", "aCa=1", 5, absl::nullopt, nullptr},
+    {"0x44 in dictionary key", "aDa=1", 5, absl::nullopt, nullptr},
+    {"0x45 in dictionary key", "aEa=1", 5, absl::nullopt, nullptr},
+    {"0x46 in dictionary key", "aFa=1", 5, absl::nullopt, nullptr},
+    {"0x47 in dictionary key", "aGa=1", 5, absl::nullopt, nullptr},
+    {"0x48 in dictionary key", "aHa=1", 5, absl::nullopt, nullptr},
+    {"0x49 in dictionary key", "aIa=1", 5, absl::nullopt, nullptr},
+    {"0x4a in dictionary key", "aJa=1", 5, absl::nullopt, nullptr},
+    {"0x4b in dictionary key", "aKa=1", 5, absl::nullopt, nullptr},
+    {"0x4c in dictionary key", "aLa=1", 5, absl::nullopt, nullptr},
+    {"0x4d in dictionary key", "aMa=1", 5, absl::nullopt, nullptr},
+    {"0x4e in dictionary key", "aNa=1", 5, absl::nullopt, nullptr},
+    {"0x4f in dictionary key", "aOa=1", 5, absl::nullopt, nullptr},
+    {"0x50 in dictionary key", "aPa=1", 5, absl::nullopt, nullptr},
+    {"0x51 in dictionary key", "aQa=1", 5, absl::nullopt, nullptr},
+    {"0x52 in dictionary key", "aRa=1", 5, absl::nullopt, nullptr},
+    {"0x53 in dictionary key", "aSa=1", 5, absl::nullopt, nullptr},
+    {"0x54 in dictionary key", "aTa=1", 5, absl::nullopt, nullptr},
+    {"0x55 in dictionary key", "aUa=1", 5, absl::nullopt, nullptr},
+    {"0x56 in dictionary key", "aVa=1", 5, absl::nullopt, nullptr},
+    {"0x57 in dictionary key", "aWa=1", 5, absl::nullopt, nullptr},
+    {"0x58 in dictionary key", "aXa=1", 5, absl::nullopt, nullptr},
+    {"0x59 in dictionary key", "aYa=1", 5, absl::nullopt, nullptr},
+    {"0x5a in dictionary key", "aZa=1", 5, absl::nullopt, nullptr},
+    {"0x5b in dictionary key", "a[a=1", 5, absl::nullopt, nullptr},
+    {"0x5c in dictionary key", "a\\a=1", 5, absl::nullopt, nullptr},
+    {"0x5d in dictionary key", "a]a=1", 5, absl::nullopt, nullptr},
+    {"0x5e in dictionary key", "a^a=1", 5, absl::nullopt, nullptr},
+    {"0x5f in dictionary key",
+     "a_a=1",
+     5,
+     {Dictionary{{{"a_a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x60 in dictionary key", "a`a=1", 5, absl::nullopt, nullptr},
+    {"0x61 in dictionary key",
+     "aaa=1",
+     5,
+     {Dictionary{{{"aaa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x62 in dictionary key",
+     "aba=1",
+     5,
+     {Dictionary{{{"aba", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x63 in dictionary key",
+     "aca=1",
+     5,
+     {Dictionary{{{"aca", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x64 in dictionary key",
+     "ada=1",
+     5,
+     {Dictionary{{{"ada", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x65 in dictionary key",
+     "aea=1",
+     5,
+     {Dictionary{{{"aea", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x66 in dictionary key",
+     "afa=1",
+     5,
+     {Dictionary{{{"afa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x67 in dictionary key",
+     "aga=1",
+     5,
+     {Dictionary{{{"aga", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x68 in dictionary key",
+     "aha=1",
+     5,
+     {Dictionary{{{"aha", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x69 in dictionary key",
+     "aia=1",
+     5,
+     {Dictionary{{{"aia", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6a in dictionary key",
+     "aja=1",
+     5,
+     {Dictionary{{{"aja", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6b in dictionary key",
+     "aka=1",
+     5,
+     {Dictionary{{{"aka", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6c in dictionary key",
+     "ala=1",
+     5,
+     {Dictionary{{{"ala", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6d in dictionary key",
+     "ama=1",
+     5,
+     {Dictionary{{{"ama", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6e in dictionary key",
+     "ana=1",
+     5,
+     {Dictionary{{{"ana", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6f in dictionary key",
+     "aoa=1",
+     5,
+     {Dictionary{{{"aoa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x70 in dictionary key",
+     "apa=1",
+     5,
+     {Dictionary{{{"apa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x71 in dictionary key",
+     "aqa=1",
+     5,
+     {Dictionary{{{"aqa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x72 in dictionary key",
+     "ara=1",
+     5,
+     {Dictionary{{{"ara", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x73 in dictionary key",
+     "asa=1",
+     5,
+     {Dictionary{{{"asa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x74 in dictionary key",
+     "ata=1",
+     5,
+     {Dictionary{{{"ata", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x75 in dictionary key",
+     "aua=1",
+     5,
+     {Dictionary{{{"aua", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x76 in dictionary key",
+     "ava=1",
+     5,
+     {Dictionary{{{"ava", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x77 in dictionary key",
+     "awa=1",
+     5,
+     {Dictionary{{{"awa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x78 in dictionary key",
+     "axa=1",
+     5,
+     {Dictionary{{{"axa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x79 in dictionary key",
+     "aya=1",
+     5,
+     {Dictionary{{{"aya", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x7a in dictionary key",
+     "aza=1",
+     5,
+     {Dictionary{{{"aza", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x7b in dictionary key", "a{a=1", 5, absl::nullopt, nullptr},
+    {"0x7c in dictionary key", "a|a=1", 5, absl::nullopt, nullptr},
+    {"0x7d in dictionary key", "a}a=1", 5, absl::nullopt, nullptr},
+    {"0x7e in dictionary key", "a~a=1", 5, absl::nullopt, nullptr},
+    {"0x7f in dictionary key", "a\177a=1", 5, absl::nullopt, nullptr},
+    {"0x00 starting an dictionary key", "\000a=1", 4, absl::nullopt, nullptr},
+    {"0x01 starting an dictionary key", "\001a=1", 4, absl::nullopt, nullptr},
+    {"0x02 starting an dictionary key", "\002a=1", 4, absl::nullopt, nullptr},
+    {"0x03 starting an dictionary key", "\003a=1", 4, absl::nullopt, nullptr},
+    {"0x04 starting an dictionary key", "\004a=1", 4, absl::nullopt, nullptr},
+    {"0x05 starting an dictionary key", "\005a=1", 4, absl::nullopt, nullptr},
+    {"0x06 starting an dictionary key", "\006a=1", 4, absl::nullopt, nullptr},
+    {"0x07 starting an dictionary key", "\aa=1", 4, absl::nullopt, nullptr},
+    {"0x08 starting an dictionary key", "\ba=1", 4, absl::nullopt, nullptr},
+    {"0x09 starting an dictionary key", "\ta=1", 4, absl::nullopt, nullptr},
+    {"0x0a starting an dictionary key", "\na=1", 4, absl::nullopt, nullptr},
+    {"0x0b starting an dictionary key", "\va=1", 4, absl::nullopt, nullptr},
+    {"0x0c starting an dictionary key", "\fa=1", 4, absl::nullopt, nullptr},
+    {"0x0d starting an dictionary key", "\ra=1", 4, absl::nullopt, nullptr},
+    {"0x0e starting an dictionary key", "\016a=1", 4, absl::nullopt, nullptr},
+    {"0x0f starting an dictionary key", "\017a=1", 4, absl::nullopt, nullptr},
+    {"0x10 starting an dictionary key", "\020a=1", 4, absl::nullopt, nullptr},
+    {"0x11 starting an dictionary key", "\021a=1", 4, absl::nullopt, nullptr},
+    {"0x12 starting an dictionary key", "\022a=1", 4, absl::nullopt, nullptr},
+    {"0x13 starting an dictionary key", "\023a=1", 4, absl::nullopt, nullptr},
+    {"0x14 starting an dictionary key", "\024a=1", 4, absl::nullopt, nullptr},
+    {"0x15 starting an dictionary key", "\025a=1", 4, absl::nullopt, nullptr},
+    {"0x16 starting an dictionary key", "\026a=1", 4, absl::nullopt, nullptr},
+    {"0x17 starting an dictionary key", "\027a=1", 4, absl::nullopt, nullptr},
+    {"0x18 starting an dictionary key", "\030a=1", 4, absl::nullopt, nullptr},
+    {"0x19 starting an dictionary key", "\031a=1", 4, absl::nullopt, nullptr},
+    {"0x1a starting an dictionary key", "\032a=1", 4, absl::nullopt, nullptr},
+    {"0x1b starting an dictionary key", "\033a=1", 4, absl::nullopt, nullptr},
+    {"0x1c starting an dictionary key", "\034a=1", 4, absl::nullopt, nullptr},
+    {"0x1d starting an dictionary key", "\035a=1", 4, absl::nullopt, nullptr},
+    {"0x1e starting an dictionary key", "\036a=1", 4, absl::nullopt, nullptr},
+    {"0x1f starting an dictionary key", "\037a=1", 4, absl::nullopt, nullptr},
+    {"0x20 starting an dictionary key",
+     " a=1",
+     4,
+     {Dictionary{{{"a", {Integer(1), {}}}}}},
+     "a=1"},
+    {"0x21 starting an dictionary key", "!a=1", 4, absl::nullopt, nullptr},
+    {"0x22 starting an dictionary key", "\"a=1", 4, absl::nullopt, nullptr},
+    {"0x23 starting an dictionary key", "#a=1", 4, absl::nullopt, nullptr},
+    {"0x24 starting an dictionary key", "$a=1", 4, absl::nullopt, nullptr},
+    {"0x25 starting an dictionary key", "%a=1", 4, absl::nullopt, nullptr},
+    {"0x26 starting an dictionary key", "&a=1", 4, absl::nullopt, nullptr},
+    {"0x27 starting an dictionary key", "'a=1", 4, absl::nullopt, nullptr},
+    {"0x28 starting an dictionary key", "(a=1", 4, absl::nullopt, nullptr},
+    {"0x29 starting an dictionary key", ")a=1", 4, absl::nullopt, nullptr},
+    {"0x2a starting an dictionary key",
+     "*a=1",
+     4,
+     {Dictionary{{{"*a", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x2b starting an dictionary key", "+a=1", 4, absl::nullopt, nullptr},
+    {"0x2c starting an dictionary key", ",a=1", 4, absl::nullopt, nullptr},
+    {"0x2d starting an dictionary key", "-a=1", 4, absl::nullopt, nullptr},
+    {"0x2e starting an dictionary key", ".a=1", 4, absl::nullopt, nullptr},
+    {"0x2f starting an dictionary key", "/a=1", 4, absl::nullopt, nullptr},
+    {"0x30 starting an dictionary key", "0a=1", 4, absl::nullopt, nullptr},
+    {"0x31 starting an dictionary key", "1a=1", 4, absl::nullopt, nullptr},
+    {"0x32 starting an dictionary key", "2a=1", 4, absl::nullopt, nullptr},
+    {"0x33 starting an dictionary key", "3a=1", 4, absl::nullopt, nullptr},
+    {"0x34 starting an dictionary key", "4a=1", 4, absl::nullopt, nullptr},
+    {"0x35 starting an dictionary key", "5a=1", 4, absl::nullopt, nullptr},
+    {"0x36 starting an dictionary key", "6a=1", 4, absl::nullopt, nullptr},
+    {"0x37 starting an dictionary key", "7a=1", 4, absl::nullopt, nullptr},
+    {"0x38 starting an dictionary key", "8a=1", 4, absl::nullopt, nullptr},
+    {"0x39 starting an dictionary key", "9a=1", 4, absl::nullopt, nullptr},
+    {"0x3a starting an dictionary key", ":a=1", 4, absl::nullopt, nullptr},
+    {"0x3b starting an dictionary key", ";a=1", 4, absl::nullopt, nullptr},
+    {"0x3c starting an dictionary key", "<a=1", 4, absl::nullopt, nullptr},
+    {"0x3d starting an dictionary key", "=a=1", 4, absl::nullopt, nullptr},
+    {"0x3e starting an dictionary key", ">a=1", 4, absl::nullopt, nullptr},
+    {"0x3f starting an dictionary key", "?a=1", 4, absl::nullopt, nullptr},
+    {"0x40 starting an dictionary key", "@a=1", 4, absl::nullopt, nullptr},
+    {"0x41 starting an dictionary key", "Aa=1", 4, absl::nullopt, nullptr},
+    {"0x42 starting an dictionary key", "Ba=1", 4, absl::nullopt, nullptr},
+    {"0x43 starting an dictionary key", "Ca=1", 4, absl::nullopt, nullptr},
+    {"0x44 starting an dictionary key", "Da=1", 4, absl::nullopt, nullptr},
+    {"0x45 starting an dictionary key", "Ea=1", 4, absl::nullopt, nullptr},
+    {"0x46 starting an dictionary key", "Fa=1", 4, absl::nullopt, nullptr},
+    {"0x47 starting an dictionary key", "Ga=1", 4, absl::nullopt, nullptr},
+    {"0x48 starting an dictionary key", "Ha=1", 4, absl::nullopt, nullptr},
+    {"0x49 starting an dictionary key", "Ia=1", 4, absl::nullopt, nullptr},
+    {"0x4a starting an dictionary key", "Ja=1", 4, absl::nullopt, nullptr},
+    {"0x4b starting an dictionary key", "Ka=1", 4, absl::nullopt, nullptr},
+    {"0x4c starting an dictionary key", "La=1", 4, absl::nullopt, nullptr},
+    {"0x4d starting an dictionary key", "Ma=1", 4, absl::nullopt, nullptr},
+    {"0x4e starting an dictionary key", "Na=1", 4, absl::nullopt, nullptr},
+    {"0x4f starting an dictionary key", "Oa=1", 4, absl::nullopt, nullptr},
+    {"0x50 starting an dictionary key", "Pa=1", 4, absl::nullopt, nullptr},
+    {"0x51 starting an dictionary key", "Qa=1", 4, absl::nullopt, nullptr},
+    {"0x52 starting an dictionary key", "Ra=1", 4, absl::nullopt, nullptr},
+    {"0x53 starting an dictionary key", "Sa=1", 4, absl::nullopt, nullptr},
+    {"0x54 starting an dictionary key", "Ta=1", 4, absl::nullopt, nullptr},
+    {"0x55 starting an dictionary key", "Ua=1", 4, absl::nullopt, nullptr},
+    {"0x56 starting an dictionary key", "Va=1", 4, absl::nullopt, nullptr},
+    {"0x57 starting an dictionary key", "Wa=1", 4, absl::nullopt, nullptr},
+    {"0x58 starting an dictionary key", "Xa=1", 4, absl::nullopt, nullptr},
+    {"0x59 starting an dictionary key", "Ya=1", 4, absl::nullopt, nullptr},
+    {"0x5a starting an dictionary key", "Za=1", 4, absl::nullopt, nullptr},
+    {"0x5b starting an dictionary key", "[a=1", 4, absl::nullopt, nullptr},
+    {"0x5c starting an dictionary key", "\\a=1", 4, absl::nullopt, nullptr},
+    {"0x5d starting an dictionary key", "]a=1", 4, absl::nullopt, nullptr},
+    {"0x5e starting an dictionary key", "^a=1", 4, absl::nullopt, nullptr},
+    {"0x5f starting an dictionary key", "_a=1", 4, absl::nullopt, nullptr},
+    {"0x60 starting an dictionary key", "`a=1", 4, absl::nullopt, nullptr},
+    {"0x61 starting an dictionary key",
+     "aa=1",
+     4,
+     {Dictionary{{{"aa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x62 starting an dictionary key",
+     "ba=1",
+     4,
+     {Dictionary{{{"ba", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x63 starting an dictionary key",
+     "ca=1",
+     4,
+     {Dictionary{{{"ca", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x64 starting an dictionary key",
+     "da=1",
+     4,
+     {Dictionary{{{"da", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x65 starting an dictionary key",
+     "ea=1",
+     4,
+     {Dictionary{{{"ea", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x66 starting an dictionary key",
+     "fa=1",
+     4,
+     {Dictionary{{{"fa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x67 starting an dictionary key",
+     "ga=1",
+     4,
+     {Dictionary{{{"ga", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x68 starting an dictionary key",
+     "ha=1",
+     4,
+     {Dictionary{{{"ha", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x69 starting an dictionary key",
+     "ia=1",
+     4,
+     {Dictionary{{{"ia", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6a starting an dictionary key",
+     "ja=1",
+     4,
+     {Dictionary{{{"ja", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6b starting an dictionary key",
+     "ka=1",
+     4,
+     {Dictionary{{{"ka", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6c starting an dictionary key",
+     "la=1",
+     4,
+     {Dictionary{{{"la", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6d starting an dictionary key",
+     "ma=1",
+     4,
+     {Dictionary{{{"ma", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6e starting an dictionary key",
+     "na=1",
+     4,
+     {Dictionary{{{"na", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x6f starting an dictionary key",
+     "oa=1",
+     4,
+     {Dictionary{{{"oa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x70 starting an dictionary key",
+     "pa=1",
+     4,
+     {Dictionary{{{"pa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x71 starting an dictionary key",
+     "qa=1",
+     4,
+     {Dictionary{{{"qa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x72 starting an dictionary key",
+     "ra=1",
+     4,
+     {Dictionary{{{"ra", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x73 starting an dictionary key",
+     "sa=1",
+     4,
+     {Dictionary{{{"sa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x74 starting an dictionary key",
+     "ta=1",
+     4,
+     {Dictionary{{{"ta", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x75 starting an dictionary key",
+     "ua=1",
+     4,
+     {Dictionary{{{"ua", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x76 starting an dictionary key",
+     "va=1",
+     4,
+     {Dictionary{{{"va", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x77 starting an dictionary key",
+     "wa=1",
+     4,
+     {Dictionary{{{"wa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x78 starting an dictionary key",
+     "xa=1",
+     4,
+     {Dictionary{{{"xa", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x79 starting an dictionary key",
+     "ya=1",
+     4,
+     {Dictionary{{{"ya", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x7a starting an dictionary key",
+     "za=1",
+     4,
+     {Dictionary{{{"za", {Integer(1), {}}}}}},
+     nullptr},
+    {"0x7b starting an dictionary key", "{a=1", 4, absl::nullopt, nullptr},
+    {"0x7c starting an dictionary key", "|a=1", 4, absl::nullopt, nullptr},
+    {"0x7d starting an dictionary key", "}a=1", 4, absl::nullopt, nullptr},
+    {"0x7e starting an dictionary key", "~a=1", 4, absl::nullopt, nullptr},
+    {"0x7f starting an dictionary key", "\177a=1", 4, absl::nullopt, nullptr},
+    // param-dict.json
+    {"basic parameterised dict",
+     "abc=123;a=1;b=2, def=456, ghi=789;q=9;r=\"+w\"",
+     44,
+     {Dictionary{{{"abc", {Integer(123), {Param("a", 1), Param("b", 2)}}},
+                  {"def", {Integer(456), {}}},
+                  {"ghi", {Integer(789), {Param("q", 9), Param("r", "+w")}}}}}},
+     nullptr},
+    {"single item parameterised dict",
+     "a=b; q=1.0",
+     10,
+     {Dictionary{
+         {{"a", {Item("b", Item::kTokenType), {DoubleParam("q", 1.000000)}}}}}},
+     "a=b;q=1.0"},
+    {"list item parameterised dictionary",
+     "a=(1 2); q=1.0",
+     14,
+     {Dictionary{{{"a",
+                   {{{Integer(1), {}}, {Integer(2), {}}},
+                    {DoubleParam("q", 1.000000)}}}}}},
+     "a=(1 2);q=1.0"},
+    {"missing parameter value parameterised dict",
+     "a=3;c;d=5",
+     9,
+     {Dictionary{
+         {{"a", {Integer(3), {BooleanParam("c", true), Param("d", 5)}}}}}},
+     nullptr},
+    {"terminal missing parameter value parameterised dict",
+     "a=3;c=5;d",
+     9,
+     {Dictionary{
+         {{"a", {Integer(3), {Param("c", 5), BooleanParam("d", true)}}}}}},
+     nullptr},
+    {"no whitespace parameterised dict",
+     "a=b;c=1,d=e;f=2",
+     15,
+     {Dictionary{{{"a", {Item("b", Item::kTokenType), {Param("c", 1)}}},
+                  {"d", {Item("e", Item::kTokenType), {Param("f", 2)}}}}}},
+     "a=b;c=1, d=e;f=2"},
+    {"whitespace before = parameterised dict", "a=b;q =0.5", 10, absl::nullopt,
+     nullptr},
+    {"whitespace after = parameterised dict", "a=b;q= 0.5", 10, absl::nullopt,
+     nullptr},
+    {"whitespace before ; parameterised dict", "a=b ;q=0.5", 10, absl::nullopt,
+     nullptr},
+    {"whitespace after ; parameterised dict",
+     "a=b; q=0.5",
+     10,
+     {Dictionary{
+         {{"a", {Item("b", Item::kTokenType), {DoubleParam("q", 0.500000)}}}}}},
+     "a=b;q=0.5"},
+    {"extra whitespace parameterised dict",
+     "a=b;  c=1  ,  d=e; f=2; g=3",
+     27,
+     {Dictionary{
+         {{"a", {Item("b", Item::kTokenType), {Param("c", 1)}}},
+          {"d",
+           {Item("e", Item::kTokenType), {Param("f", 2), Param("g", 3)}}}}}},
+     "a=b;c=1, d=e;f=2;g=3"},
+    {"two lines parameterised list",
+     "a=b;c=1, d=e;f=2",
+     16,
+     {Dictionary{{{"a", {Item("b", Item::kTokenType), {Param("c", 1)}}},
+                  {"d", {Item("e", Item::kTokenType), {Param("f", 2)}}}}}},
+     "a=b;c=1, d=e;f=2"},
+    {"trailing comma parameterised list", "a=b; q=1.0,", 11, absl::nullopt,
+     nullptr},
+    {"empty item parameterised list", "a=b; q=1.0,,c=d", 15, absl::nullopt,
+     nullptr},
+};
+
+}  // namespace
+
+TEST(StructuredHeaderGeneratedTest, ParseItem) {
+  for (const auto& c : parameterized_item_test_cases) {
+    if (c.raw) {
+      SCOPED_TRACE(c.name);
+      std::string raw{c.raw, c.raw_len};
+      absl::optional<ParameterizedItem> result = ParseItem(raw);
+      EXPECT_EQ(result, c.expected);
+    }
+  }
+}
+
+TEST(StructuredHeaderGeneratedTest, ParseList) {
+  for (const auto& c : list_test_cases) {
+    if (c.raw) {
+      SCOPED_TRACE(c.name);
+      std::string raw{c.raw, c.raw_len};
+      absl::optional<List> result = ParseList(raw);
+      EXPECT_EQ(result, c.expected);
+    }
+  }
+}
+
+TEST(StructuredHeaderGeneratedTest, ParseDictionary) {
+  for (const auto& c : dictionary_test_cases) {
+    if (c.raw) {
+      SCOPED_TRACE(c.name);
+      std::string raw{c.raw, c.raw_len};
+      absl::optional<Dictionary> result = ParseDictionary(raw);
+      EXPECT_EQ(result, c.expected);
+    }
+  }
+}
+
+TEST(StructuredHeaderGeneratedTest, SerializeItem) {
+  for (const auto& c : parameterized_item_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeItem(*c.expected);
+      if (c.raw || c.canonical) {
+        EXPECT_TRUE(result.has_value());
+        EXPECT_EQ(result.value(),
+                  std::string(c.canonical ? c.canonical : c.raw));
+      } else {
+        EXPECT_FALSE(result.has_value());
+      }
+    }
+  }
+}
+
+TEST(StructuredHeaderGeneratedTest, SerializeList) {
+  for (const auto& c : list_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeList(*c.expected);
+      if (c.raw || c.canonical) {
+        EXPECT_TRUE(result.has_value());
+        EXPECT_EQ(result.value(),
+                  std::string(c.canonical ? c.canonical : c.raw));
+      } else {
+        EXPECT_FALSE(result.has_value());
+      }
+    }
+  }
+}
+
+TEST(StructuredHeaderGeneratedTest, SerializeDictionary) {
+  for (const auto& c : dictionary_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeDictionary(*c.expected);
+      if (c.raw || c.canonical) {
+        EXPECT_TRUE(result.has_value());
+        EXPECT_EQ(result.value(),
+                  std::string(c.canonical ? c.canonical : c.raw));
+      } else {
+        EXPECT_FALSE(result.has_value());
+      }
+    }
+  }
+}
+
+}  // namespace structured_headers
+}  // namespace quiche
diff --git a/quiche/common/structured_headers_test.cc b/quiche/common/structured_headers_test.cc
new file mode 100644
index 0000000..73a7ab3
--- /dev/null
+++ b/quiche/common/structured_headers_test.cc
@@ -0,0 +1,762 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/structured_headers.h"
+
+#include <math.h>
+
+#include <limits>
+#include <string>
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace structured_headers {
+namespace {
+
+// Helpers to make test cases clearer
+
+Item Token(std::string value) { return Item(value, Item::kTokenType); }
+
+Item Integer(int64_t value) { return Item(value); }
+
+// Parameter with null value, only used in Structured Headers Draft 09
+std::pair<std::string, Item> NullParam(std::string key) {
+  return std::make_pair(key, Item());
+}
+
+std::pair<std::string, Item> BooleanParam(std::string key, bool value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> DoubleParam(std::string key, double value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> Param(std::string key, int64_t value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> Param(std::string key, std::string value) {
+  return std::make_pair(key, Item(value));
+}
+
+std::pair<std::string, Item> ByteSequenceParam(std::string key,
+                                               std::string value) {
+  return std::make_pair(key, Item(value, Item::kByteSequenceType));
+}
+
+std::pair<std::string, Item> TokenParam(std::string key, std::string value) {
+  return std::make_pair(key, Token(value));
+}
+
+// Test cases taken from https://github.com/httpwg/structured-header-tests can
+// be found in structured_headers_generated_unittest.cc
+
+const struct ItemTestCase {
+  const char* name;
+  const char* raw;
+  const absl::optional<Item> expected;  // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} item_test_cases[] = {
+    // Token
+    {"bad token - item", "abc$@%!", absl::nullopt, nullptr},
+    {"leading whitespace", " foo", Token("foo"), "foo"},
+    {"trailing whitespace", "foo ", Token("foo"), "foo"},
+    {"leading asterisk", "*foo", Token("*foo"), nullptr},
+    // Number
+    {"long integer", "999999999999999", Integer(999999999999999L), nullptr},
+    {"long negative integer", "-999999999999999", Integer(-999999999999999L),
+     nullptr},
+    {"too long integer", "1000000000000000", absl::nullopt, nullptr},
+    {"negative too long integer", "-1000000000000000", absl::nullopt, nullptr},
+    {"integral decimal", "1.0", Item(1.0), nullptr},
+    // String
+    {"basic string", "\"foo\"", Item("foo"), nullptr},
+    {"non-ascii string", "\"f\xC3\xBC\xC3\xBC\"", absl::nullopt, nullptr},
+    // Additional tests
+    {"valid quoting containing \\n", "\"\\\\n\"", Item("\\n"), nullptr},
+    {"valid quoting containing \\t", "\"\\\\t\"", Item("\\t"), nullptr},
+    {"valid quoting containing \\x", "\"\\\\x61\"", Item("\\x61"), nullptr},
+    {"c-style hex escape in string", "\"\\x61\"", absl::nullopt, nullptr},
+    {"valid quoting containing \\u", "\"\\\\u0061\"", Item("\\u0061"), nullptr},
+    {"c-style unicode escape in string", "\"\\u0061\"", absl::nullopt, nullptr},
+};
+
+const ItemTestCase sh09_item_test_cases[] = {
+    // Integer
+    {"large integer", "9223372036854775807", Integer(9223372036854775807L),
+     nullptr},
+    {"large negative integer", "-9223372036854775807",
+     Integer(-9223372036854775807L), nullptr},
+    {"too large integer", "9223372036854775808", absl::nullopt, nullptr},
+    {"too large negative integer", "-9223372036854775808", absl::nullopt,
+     nullptr},
+    // Byte Sequence
+    {"basic binary", "*aGVsbG8=*", Item("hello", Item::kByteSequenceType),
+     nullptr},
+    {"empty binary", "**", Item("", Item::kByteSequenceType), nullptr},
+    {"bad paddding", "*aGVsbG8*", Item("hello", Item::kByteSequenceType),
+     "*aGVsbG8=*"},
+    {"bad end delimiter", "*aGVsbG8=", absl::nullopt, nullptr},
+    {"extra whitespace", "*aGVsb G8=*", absl::nullopt, nullptr},
+    {"extra chars", "*aGVsbG!8=*", absl::nullopt, nullptr},
+    {"suffix chars", "*aGVsbG8=!*", absl::nullopt, nullptr},
+    {"non-zero pad bits", "*iZ==*", Item("\x89", Item::kByteSequenceType),
+     "*iQ==*"},
+    {"non-ASCII binary", "*/+Ah*", Item("\xFF\xE0!", Item::kByteSequenceType),
+     nullptr},
+    {"base64url binary", "*_-Ah*", absl::nullopt, nullptr},
+    {"token with leading asterisk", "*foo", absl::nullopt, nullptr},
+};
+
+// For Structured Headers Draft 15
+const struct ParameterizedItemTestCase {
+  const char* name;
+  const char* raw;
+  const absl::optional<ParameterizedItem>
+      expected;           // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} parameterized_item_test_cases[] = {
+    {"single parameter item",
+     "text/html;q=1.0",
+     {{Token("text/html"), {DoubleParam("q", 1)}}},
+     nullptr},
+    {"missing parameter value item",
+     "text/html;a;q=1.0",
+     {{Token("text/html"), {BooleanParam("a", true), DoubleParam("q", 1)}}},
+     nullptr},
+    {"missing terminal parameter value item",
+     "text/html;q=1.0;a",
+     {{Token("text/html"), {DoubleParam("q", 1), BooleanParam("a", true)}}},
+     nullptr},
+    {"duplicate parameter keys with different value",
+     "text/html;a=1;b=2;a=3.0",
+     {{Token("text/html"), {DoubleParam("a", 3), Param("b", 2L)}}},
+     "text/html;a=3.0;b=2"},
+    {"multiple duplicate parameter keys at different position",
+     "text/html;c=1;a=2;b;b=3.0;a",
+     {{Token("text/html"),
+       {Param("c", 1L), BooleanParam("a", true), DoubleParam("b", 3)}}},
+     "text/html;c=1;a;b=3.0"},
+    {"duplicate parameter keys with missing value",
+     "text/html;a;a=1",
+     {{Token("text/html"), {Param("a", 1L)}}},
+     "text/html;a=1"},
+    {"whitespace before = parameterised item", "text/html, text/plain;q =0.5",
+     absl::nullopt, nullptr},
+    {"whitespace after = parameterised item", "text/html, text/plain;q= 0.5",
+     absl::nullopt, nullptr},
+    {"whitespace before ; parameterised item", "text/html, text/plain ;q=0.5",
+     absl::nullopt, nullptr},
+    {"whitespace after ; parameterised item",
+     "text/plain; q=0.5",
+     {{Token("text/plain"), {DoubleParam("q", 0.5)}}},
+     "text/plain;q=0.5"},
+    {"extra whitespace parameterised item",
+     "text/plain;  q=0.5;  charset=utf-8",
+     {{Token("text/plain"),
+       {DoubleParam("q", 0.5), TokenParam("charset", "utf-8")}}},
+     "text/plain;q=0.5;charset=utf-8"},
+};
+
+// For Structured Headers Draft 15
+const struct ListTestCase {
+  const char* name;
+  const char* raw;
+  const absl::optional<List> expected;  // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} list_test_cases[] = {
+    // Lists of lists
+    {"extra whitespace list of lists",
+     "(1  42)",
+     {{{{{Integer(1L), {}}, {Integer(42L), {}}}, {}}}},
+     "(1 42)"},
+    // Parameterized Lists
+    {"basic parameterised list",
+     "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"+w\"",
+     {{{Token("abc_123"),
+        {Param("a", 1), Param("b", 2), BooleanParam("cdef_456", true)}},
+       {Token("ghi"), {Param("q", "9"), Param("r", "+w")}}}},
+     "abc_123;a=1;b=2;cdef_456, ghi;q=\"9\";r=\"+w\""},
+    // Parameterized inner lists
+    {"parameterised basic list of lists",
+     "(1;a=1.0 2), (42 43)",
+     {{{{{Integer(1L), {DoubleParam("a", 1.0)}}, {Integer(2L), {}}}, {}},
+       {{{Integer(42L), {}}, {Integer(43L), {}}}, {}}}},
+     nullptr},
+    {"parameters on inner members",
+     "(1;a=1.0 2;b=c), (42;d=?0 43;e=:Zmdo:)",
+     {{{{{Integer(1L), {DoubleParam("a", 1.0)}},
+         {Integer(2L), {TokenParam("b", "c")}}},
+        {}},
+       {{{Integer(42L), {BooleanParam("d", false)}},
+         {Integer(43L), {ByteSequenceParam("e", "fgh")}}},
+        {}}}},
+     nullptr},
+    {"parameters on inner lists",
+     "(1 2);a=1.0, (42 43);b=?0",
+     {{{{{Integer(1L), {}}, {Integer(2L), {}}}, {DoubleParam("a", 1.0)}},
+       {{{Integer(42L), {}}, {Integer(43L), {}}}, {BooleanParam("b", false)}}}},
+     nullptr},
+    {"default true values for parameters on inner list members",
+     "(1;a 2), (42 43;b)",
+     {{{{{Integer(1L), {BooleanParam("a", true)}}, {Integer(2L), {}}}, {}},
+       {{{Integer(42L), {}}, {Integer(43L), {BooleanParam("b", true)}}}, {}}}},
+     nullptr},
+    {"default true values for parameters on inner lists",
+     "(1 2);a, (42 43);b",
+     {{{{{Integer(1L), {}}, {Integer(2L), {}}}, {BooleanParam("a", true)}},
+       {{{Integer(42L), {}}, {Integer(43L), {}}}, {BooleanParam("b", true)}}}},
+     nullptr},
+    {"extra whitespace before semicolon in parameters on inner list member",
+     "(a;b ;c b)", absl::nullopt, nullptr},
+    {"extra whitespace between parameters on inner list member",
+     "(a;b; c b)",
+     {{{{{Token("a"), {BooleanParam("b", true), BooleanParam("c", true)}},
+         {Token("b"), {}}},
+        {}}}},
+     "(a;b;c b)"},
+    {"extra whitespace before semicolon in parameters on inner list",
+     "(a b);c ;d, (e)", absl::nullopt, nullptr},
+    {"extra whitespace between parameters on inner list",
+     "(a b);c; d, (e)",
+     {{{{{Token("a"), {}}, {Token("b"), {}}},
+        {BooleanParam("c", true), BooleanParam("d", true)}},
+       {{{Token("e"), {}}}, {}}}},
+     "(a b);c;d, (e)"},
+};
+
+// For Structured Headers Draft 15
+const struct DictionaryTestCase {
+  const char* name;
+  const char* raw;
+  const absl::optional<Dictionary>
+      expected;           // nullopt if parse error is expected.
+  const char* canonical;  // nullptr if parse error is expected, or if canonical
+                          // format is identical to raw.
+} dictionary_test_cases[] = {
+    {"basic dictionary",
+     "en=\"Applepie\", da=:aGVsbG8=:",
+     {Dictionary{{{"en", {Item("Applepie"), {}}},
+                  {"da", {Item("hello", Item::kByteSequenceType), {}}}}}},
+     nullptr},
+    {"tab separated dictionary",
+     "a=1\t,\tb=2",
+     {Dictionary{{{"a", {Integer(1L), {}}}, {"b", {Integer(2L), {}}}}}},
+     "a=1, b=2"},
+    {"missing value with params dictionary",
+     "a=1, b;foo=9, c=3",
+     {Dictionary{{{"a", {Integer(1L), {}}},
+                  {"b", {Item(true), {Param("foo", 9)}}},
+                  {"c", {Integer(3L), {}}}}}},
+     nullptr},
+    // Parameterised dictionary tests
+    {"parameterised inner list member dict",
+     "a=(\"1\";b=1;c=?0 \"2\");d=\"e\"",
+     {Dictionary{{{"a",
+                   {{{Item("1"), {Param("b", 1), BooleanParam("c", false)}},
+                     {Item("2"), {}}},
+                    {Param("d", "e")}}}}}},
+     nullptr},
+    {"explicit true value with parameter",
+     "a=?1;b=1",
+     {Dictionary{{{"a", {Item(true), {Param("b", 1)}}}}}},
+     "a;b=1"},
+    {"implicit true value with parameter",
+     "a;b=1",
+     {Dictionary{{{"a", {Item(true), {Param("b", 1)}}}}}},
+     nullptr},
+    {"implicit true value with implicitly-valued parameter",
+     "a;b",
+     {Dictionary{{{"a", {Item(true), {BooleanParam("b", true)}}}}}},
+     nullptr},
+};
+}  // namespace
+
+TEST(StructuredHeaderTest, ParseBareItem) {
+  for (const auto& c : item_test_cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<Item> result = ParseBareItem(c.raw);
+    EXPECT_EQ(result, c.expected);
+  }
+}
+
+// For Structured Headers Draft 15, these tests include parameters on Items.
+TEST(StructuredHeaderTest, ParseItem) {
+  for (const auto& c : parameterized_item_test_cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<ParameterizedItem> result = ParseItem(c.raw);
+    EXPECT_EQ(result, c.expected);
+  }
+}
+
+// Structured Headers Draft 9 parsing rules are different than Draft 15, and
+// some strings which are considered invalid in SH15 should parse in SH09.
+// The SH09 Item parser is not directly exposed, but can be used indirectly by
+// calling the parser for SH09-specific lists.
+TEST(StructuredHeaderTest, ParseSH09Item) {
+  for (const auto& c : sh09_item_test_cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<ListOfLists> result = ParseListOfLists(c.raw);
+    if (c.expected.has_value()) {
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(result->size(), 1UL);
+      EXPECT_EQ((*result)[0].size(), 1UL);
+      EXPECT_EQ((*result)[0][0], c.expected);
+    } else {
+      EXPECT_FALSE(result.has_value());
+    }
+  }
+}
+
+// In Structured Headers Draft 9, floats can have more than three fractional
+// digits, and can be larger than 1e12. This behaviour is exposed in the parser
+// for SH09-specific lists, so test it through that interface.
+TEST(StructuredHeaderTest, SH09HighPrecisionFloats) {
+  // These values are exactly representable in binary floating point, so no
+  // accuracy issues are expected in this test.
+  absl::optional<ListOfLists> result =
+      ParseListOfLists("1.03125;-1.03125;12345678901234.5;-12345678901234.5");
+  ASSERT_TRUE(result.has_value());
+  EXPECT_EQ(*result,
+            (ListOfLists{{Item(1.03125), Item(-1.03125), Item(12345678901234.5),
+                          Item(-12345678901234.5)}}));
+
+  result = ParseListOfLists("123456789012345.0");
+  EXPECT_FALSE(result.has_value());
+
+  result = ParseListOfLists("-123456789012345.0");
+  EXPECT_FALSE(result.has_value());
+}
+
+// For Structured Headers Draft 9
+TEST(StructuredHeaderTest, ParseListOfLists) {
+  static const struct TestCase {
+    const char* name;
+    const char* raw;
+    ListOfLists expected;  // empty if parse error is expected
+  } cases[] = {
+      {"basic list of lists",
+       "1;2, 42;43",
+       {{Integer(1L), Integer(2L)}, {Integer(42L), Integer(43L)}}},
+      {"empty list of lists", "", {}},
+      {"single item list of lists", "42", {{Integer(42L)}}},
+      {"no whitespace list of lists", "1,42", {{Integer(1L)}, {Integer(42L)}}},
+      {"no inner whitespace list of lists",
+       "1;2, 42;43",
+       {{Integer(1L), Integer(2L)}, {Integer(42L), Integer(43L)}}},
+      {"extra whitespace list of lists",
+       "1 , 42",
+       {{Integer(1L)}, {Integer(42L)}}},
+      {"extra inner whitespace list of lists",
+       "1 ; 2,42 ; 43",
+       {{Integer(1L), Integer(2L)}, {Integer(42L), Integer(43L)}}},
+      {"trailing comma list of lists", "1;2, 42,", {}},
+      {"trailing semicolon list of lists", "1;2, 42;43;", {}},
+      {"leading comma list of lists", ",1;2, 42", {}},
+      {"leading semicolon list of lists", ";1;2, 42;43", {}},
+      {"empty item list of lists", "1,,42", {}},
+      {"empty inner item list of lists", "1;;2,42", {}},
+  };
+  for (const auto& c : cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<ListOfLists> result = ParseListOfLists(c.raw);
+    if (!c.expected.empty()) {
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(*result, c.expected);
+    } else {
+      EXPECT_FALSE(result.has_value());
+    }
+  }
+}
+
+// For Structured Headers Draft 9
+TEST(StructuredHeaderTest, ParseParameterisedList) {
+  static const struct TestCase {
+    const char* name;
+    const char* raw;
+    ParameterisedList expected;  // empty if parse error is expected
+  } cases[] = {
+      {"basic param-list",
+       "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"",
+       {
+           {Token("abc_123"),
+            {Param("a", 1), Param("b", 2), NullParam("cdef_456")}},
+           {Token("ghi"), {Param("q", "9"), Param("r", "w")}},
+       }},
+      {"empty param-list", "", {}},
+      {"single item param-list",
+       "text/html;q=1",
+       {{Token("text/html"), {Param("q", 1)}}}},
+      {"empty param-list", "", {}},
+      {"no whitespace param-list",
+       "text/html,text/plain;q=1",
+       {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}},
+      {"whitespace before = param-list", "text/html, text/plain;q =1", {}},
+      {"whitespace after = param-list", "text/html, text/plain;q= 1", {}},
+      {"extra whitespace param-list",
+       "text/html  ,  text/plain ;  q=1",
+       {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}},
+      {"duplicate key", "abc;a=1;b=2;a=1", {}},
+      {"numeric key", "abc;a=1;1b=2;c=1", {}},
+      {"uppercase key", "abc;a=1;B=2;c=1", {}},
+      {"bad key", "abc;a=1;b!=2;c=1", {}},
+      {"another bad key", "abc;a=1;b==2;c=1", {}},
+      {"empty key name", "abc;a=1;=2;c=1", {}},
+      {"empty parameter", "abc;a=1;;c=1", {}},
+      {"empty list item", "abc;a=1,,def;b=1", {}},
+      {"extra semicolon", "abc;a=1;b=1;", {}},
+      {"extra comma", "abc;a=1,def;b=1,", {}},
+      {"leading semicolon", ";abc;a=1", {}},
+      {"leading comma", ",abc;a=1", {}},
+  };
+  for (const auto& c : cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<ParameterisedList> result = ParseParameterisedList(c.raw);
+    if (c.expected.empty()) {
+      EXPECT_FALSE(result.has_value());
+      continue;
+    }
+    EXPECT_TRUE(result.has_value());
+    EXPECT_EQ(result->size(), c.expected.size());
+    if (result->size() == c.expected.size()) {
+      for (size_t i = 0; i < c.expected.size(); ++i) {
+        EXPECT_EQ((*result)[i], c.expected[i]);
+      }
+    }
+  }
+}
+
+// For Structured Headers Draft 15
+TEST(StructuredHeaderTest, ParseList) {
+  for (const auto& c : list_test_cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<List> result = ParseList(c.raw);
+    EXPECT_EQ(result, c.expected);
+  }
+}
+
+// For Structured Headers Draft 15
+TEST(StructuredHeaderTest, ParseDictionary) {
+  for (const auto& c : dictionary_test_cases) {
+    SCOPED_TRACE(c.name);
+    absl::optional<Dictionary> result = ParseDictionary(c.raw);
+    EXPECT_EQ(result, c.expected);
+  }
+}
+
+// Serializer tests are all exclusively for Structured Headers Draft 15
+
+TEST(StructuredHeaderTest, SerializeItem) {
+  for (const auto& c : item_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeItem(*c.expected);
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
+    }
+  }
+}
+
+TEST(StructuredHeaderTest, SerializeParameterizedItem) {
+  for (const auto& c : parameterized_item_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeItem(*c.expected);
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
+    }
+  }
+}
+
+TEST(StructuredHeaderTest, UnserializableItems) {
+  // Test that items with unknown type are not serialized.
+  EXPECT_FALSE(SerializeItem(Item()).has_value());
+}
+
+TEST(StructuredHeaderTest, UnserializableTokens) {
+  static const struct UnserializableString {
+    const char* name;
+    const char* value;
+  } bad_tokens[] = {
+      {"empty token", ""},
+      {"contains high ascii", "a\xff"},
+      {"contains nonprintable character", "a\x7f"},
+      {"contains C0", "a\x01"},
+      {"UTF-8 encoded", "a\xc3\xa9"},
+      {"contains TAB", "a\t"},
+      {"contains LF", "a\n"},
+      {"contains CR", "a\r"},
+      {"contains SP", "a "},
+      {"begins with digit", "9token"},
+      {"begins with hyphen", "-token"},
+      {"begins with LF", "\ntoken"},
+      {"begins with SP", " token"},
+      {"begins with colon", ":token"},
+      {"begins with percent", "%token"},
+      {"begins with period", ".token"},
+      {"begins with slash", "/token"},
+  };
+  for (const auto& bad_token : bad_tokens) {
+    SCOPED_TRACE(bad_token.name);
+    absl::optional<std::string> serialization =
+        SerializeItem(Token(bad_token.value));
+    EXPECT_FALSE(serialization.has_value()) << *serialization;
+  }
+}
+
+TEST(StructuredHeaderTest, UnserializableKeys) {
+  static const struct UnserializableString {
+    const char* name;
+    const char* value;
+  } bad_keys[] = {
+      {"empty key", ""},
+      {"contains high ascii", "a\xff"},
+      {"contains nonprintable character", "a\x7f"},
+      {"contains C0", "a\x01"},
+      {"UTF-8 encoded", "a\xc3\xa9"},
+      {"contains TAB", "a\t"},
+      {"contains LF", "a\n"},
+      {"contains CR", "a\r"},
+      {"contains SP", "a "},
+      {"begins with uppercase", "Atoken"},
+      {"begins with digit", "9token"},
+      {"begins with hyphen", "-token"},
+      {"begins with LF", "\ntoken"},
+      {"begins with SP", " token"},
+      {"begins with colon", ":token"},
+      {"begins with percent", "%token"},
+      {"begins with period", ".token"},
+      {"begins with slash", "/token"},
+  };
+  for (const auto& bad_key : bad_keys) {
+    SCOPED_TRACE(bad_key.name);
+    absl::optional<std::string> serialization =
+        SerializeItem(ParameterizedItem("a", {{bad_key.value, "a"}}));
+    EXPECT_FALSE(serialization.has_value()) << *serialization;
+  }
+}
+
+TEST(StructuredHeaderTest, UnserializableStrings) {
+  static const struct UnserializableString {
+    const char* name;
+    const char* value;
+  } bad_strings[] = {
+      {"contains high ascii", "a\xff"},
+      {"contains nonprintable character", "a\x7f"},
+      {"UTF-8 encoded", "a\xc3\xa9"},
+      {"contains TAB", "a\t"},
+      {"contains LF", "a\n"},
+      {"contains CR", "a\r"},
+      {"contains C0", "a\x01"},
+  };
+  for (const auto& bad_string : bad_strings) {
+    SCOPED_TRACE(bad_string.name);
+    absl::optional<std::string> serialization =
+        SerializeItem(Item(bad_string.value));
+    EXPECT_FALSE(serialization.has_value()) << *serialization;
+  }
+}
+
+TEST(StructuredHeaderTest, UnserializableIntegers) {
+  EXPECT_FALSE(SerializeItem(Integer(1e15L)).has_value());
+  EXPECT_FALSE(SerializeItem(Integer(-1e15L)).has_value());
+}
+
+TEST(StructuredHeaderTest, UnserializableDecimals) {
+  for (double value :
+       {std::numeric_limits<double>::quiet_NaN(),
+        std::numeric_limits<double>::infinity(),
+        -std::numeric_limits<double>::infinity(), 1e12, 1e12 - 0.0001,
+        1e12 - 0.0005, -1e12, -1e12 + 0.0001, -1e12 + 0.0005}) {
+    auto x = SerializeItem(Item(value));
+    EXPECT_FALSE(SerializeItem(Item(value)).has_value());
+  }
+}
+
+// These values cannot be directly parsed from headers, but are valid doubles
+// which can be serialized as sh-floats (though rounding is expected.)
+TEST(StructuredHeaderTest, SerializeUnparseableDecimals) {
+  struct UnparseableDecimal {
+    const char* name;
+    double value;
+    const char* canonical;
+  } float_test_cases[] = {
+      {"negative 0", -0.0, "0.0"},
+      {"0.0001", 0.0001, "0.0"},
+      {"0.0000001", 0.0000001, "0.0"},
+      {"1.0001", 1.0001, "1.0"},
+      {"1.0009", 1.0009, "1.001"},
+      {"round positive odd decimal", 0.0015, "0.002"},
+      {"round positive even decimal", 0.0025, "0.002"},
+      {"round negative odd decimal", -0.0015, "-0.002"},
+      {"round negative even decimal", -0.0025, "-0.002"},
+      {"round decimal up to integer part", 9.9995, "10.0"},
+      {"subnormal numbers", std::numeric_limits<double>::denorm_min(), "0.0"},
+      {"round up to 10 digits", 1e9 - 0.0000001, "1000000000.0"},
+      {"round up to 11 digits", 1e10 - 0.000001, "10000000000.0"},
+      {"round up to 12 digits", 1e11 - 0.00001, "100000000000.0"},
+      {"largest serializable float", nextafter(1e12 - 0.0005, 0),
+       "999999999999.999"},
+      {"largest serializable negative float", -nextafter(1e12 - 0.0005, 0),
+       "-999999999999.999"},
+      // This will fail if we simply truncate the fractional portion.
+      {"float rounds up to next int", 3.9999999, "4.0"},
+      // This will fail if we first round to >3 digits, and then round again to
+      // 3 digits.
+      {"don't double round", 3.99949, "3.999"},
+      // This will fail if we first round to 3 digits, and then round again to
+      // max_avail_digits.
+      {"don't double round", 123456789.99949, "123456789.999"},
+  };
+  for (const auto& test_case : float_test_cases) {
+    SCOPED_TRACE(test_case.name);
+    absl::optional<std::string> serialization =
+        SerializeItem(Item(test_case.value));
+    EXPECT_TRUE(serialization.has_value());
+    EXPECT_EQ(*serialization, test_case.canonical);
+  }
+}
+
+TEST(StructuredHeaderTest, SerializeList) {
+  for (const auto& c : list_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeList(*c.expected);
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
+    }
+  }
+}
+
+TEST(StructuredHeaderTest, UnserializableLists) {
+  static const struct UnserializableList {
+    const char* name;
+    const List value;
+  } bad_lists[] = {
+      {"Null item as member", {{Item(), {}}}},
+      {"Unserializable item as member", {{Token("\n"), {}}}},
+      {"Key is empty", {{Token("abc"), {Param("", 1)}}}},
+      {"Key containswhitespace", {{Token("abc"), {Param("a\n", 1)}}}},
+      {"Key contains UTF8", {{Token("abc"), {Param("a\xc3\xa9", 1)}}}},
+      {"Key contains unprintable characters",
+       {{Token("abc"), {Param("a\x7f", 1)}}}},
+      {"Key contains disallowed characters",
+       {{Token("abc"), {Param("a:", 1)}}}},
+      {"Param value is unserializable", {{Token("abc"), {{"a", Token("\n")}}}}},
+      {"Inner list contains unserializable item",
+       {{std::vector<ParameterizedItem>{{Token("\n"), {}}}, {}}}},
+  };
+  for (const auto& bad_list : bad_lists) {
+    SCOPED_TRACE(bad_list.name);
+    absl::optional<std::string> serialization = SerializeList(bad_list.value);
+    EXPECT_FALSE(serialization.has_value()) << *serialization;
+  }
+}
+
+TEST(StructuredHeaderTest, SerializeDictionary) {
+  for (const auto& c : dictionary_test_cases) {
+    SCOPED_TRACE(c.name);
+    if (c.expected) {
+      absl::optional<std::string> result = SerializeDictionary(*c.expected);
+      EXPECT_TRUE(result.has_value());
+      EXPECT_EQ(result.value(), std::string(c.canonical ? c.canonical : c.raw));
+    }
+  }
+}
+
+TEST(StructuredHeaderTest, DictionaryConstructors) {
+  const std::string key0 = "key0";
+  const std::string key1 = "key1";
+  const ParameterizedMember member0{Item("Applepie"), {}};
+  const ParameterizedMember member1{Item("hello", Item::kByteSequenceType), {}};
+
+  Dictionary dict;
+  EXPECT_TRUE(dict.empty());
+  EXPECT_EQ(0U, dict.size());
+  dict[key0] = member0;
+  EXPECT_FALSE(dict.empty());
+  EXPECT_EQ(1U, dict.size());
+
+  const Dictionary dict_copy = dict;
+  EXPECT_FALSE(dict_copy.empty());
+  EXPECT_EQ(1U, dict_copy.size());
+  EXPECT_EQ(dict, dict_copy);
+
+  const Dictionary dict_init{{{key0, member0}, {key1, member1}}};
+  EXPECT_FALSE(dict_init.empty());
+  EXPECT_EQ(2U, dict_init.size());
+  EXPECT_EQ(member0, dict_init.at(key0));
+  EXPECT_EQ(member1, dict_init.at(key1));
+}
+
+TEST(StructuredHeaderTest, DictionaryAccessors) {
+  const std::string key0 = "key0";
+  const std::string key1 = "key1";
+
+  const ParameterizedMember nonempty_member0{Item("Applepie"), {}};
+  const ParameterizedMember nonempty_member1{
+      Item("hello", Item::kByteSequenceType), {}};
+  const ParameterizedMember empty_member;
+
+  Dictionary dict{{{key0, nonempty_member0}}};
+  EXPECT_TRUE(dict.contains(key0));
+  EXPECT_EQ(nonempty_member0, dict[key0]);
+  EXPECT_EQ(&dict[key0], &dict.at(key0));
+  EXPECT_EQ(&dict[key0], &dict[0]);
+  EXPECT_EQ(&dict[key0], &dict.at(0));
+
+  // Even if the key does not yet exist in |dict|, operator[]() should
+  // automatically create an empty entry.
+  ASSERT_FALSE(dict.contains(key1));
+  ParameterizedMember& member1 = dict[key1];
+  EXPECT_TRUE(dict.contains(key1));
+  EXPECT_EQ(empty_member, member1);
+  EXPECT_EQ(&member1, &dict[key1]);
+  EXPECT_EQ(&member1, &dict.at(key1));
+  EXPECT_EQ(&member1, &dict[1]);
+  EXPECT_EQ(&member1, &dict.at(1));
+
+  member1 = nonempty_member1;
+  EXPECT_EQ(nonempty_member1, dict[key1]);
+  EXPECT_EQ(&dict[key1], &dict.at(key1));
+  EXPECT_EQ(&dict[key1], &dict[1]);
+  EXPECT_EQ(&dict[key1], &dict.at(1));
+
+  // at(StringPiece) and indexed accessors have const overloads.
+  const Dictionary& dict_ref = dict;
+  EXPECT_EQ(&member1, &dict_ref.at(key1));
+  EXPECT_EQ(&member1, &dict_ref[1]);
+  EXPECT_EQ(&member1, &dict_ref.at(1));
+}
+
+TEST(StructuredHeaderTest, UnserializableDictionary) {
+  static const struct UnserializableDictionary {
+    const char* name;
+    const Dictionary value;
+  } bad_dictionaries[] = {
+      {"Unserializable dict key", Dictionary{{{"ABC", {Token("abc"), {}}}}}},
+      {"Dictionary item is unserializable",
+       Dictionary{{{"abc", {Token("abc="), {}}}}}},
+      {"Param value is unserializable",
+       Dictionary{{{"abc", {Token("abc"), {{"a", Token("\n")}}}}}}},
+      {"Dictionary inner-list contains unserializable item",
+       Dictionary{
+           {{"abc",
+             {std::vector<ParameterizedItem>{{Token("abc="), {}}}, {}}}}}},
+  };
+  for (const auto& bad_dictionary : bad_dictionaries) {
+    SCOPED_TRACE(bad_dictionary.name);
+    absl::optional<std::string> serialization =
+        SerializeDictionary(bad_dictionary.value);
+    EXPECT_FALSE(serialization.has_value()) << *serialization;
+  }
+}
+
+}  // namespace structured_headers
+}  // namespace quiche
diff --git a/quiche/common/test_tools/quiche_test_utils.cc b/quiche/common/test_tools/quiche_test_utils.cc
new file mode 100644
index 0000000..778a7d5
--- /dev/null
+++ b/quiche/common/test_tools/quiche_test_utils.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+#include <string>
+
+namespace {
+
+std::string HexDumpWithMarks(const char* data,
+                             int length,
+                             const bool* marks,
+                             int mark_length) {
+  static const char kHexChars[] = "0123456789abcdef";
+  static const int kColumns = 4;
+
+  const int kSizeLimit = 1024;
+  if (length > kSizeLimit || mark_length > kSizeLimit) {
+    QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
+    length = std::min(length, kSizeLimit);
+    mark_length = std::min(mark_length, kSizeLimit);
+  }
+
+  std::string hex;
+  for (const char* row = data; length > 0;
+       row += kColumns, length -= kColumns) {
+    for (const char* p = row; p < row + 4; ++p) {
+      if (p < row + length) {
+        const bool mark =
+            (marks && (p - data) < mark_length && marks[p - data]);
+        hex += mark ? '*' : ' ';
+        hex += kHexChars[(*p & 0xf0) >> 4];
+        hex += kHexChars[*p & 0x0f];
+        hex += mark ? '*' : ' ';
+      } else {
+        hex += "    ";
+      }
+    }
+    hex = hex + "  ";
+
+    for (const char* p = row; p < row + 4 && p < row + length; ++p) {
+      hex += (*p >= 0x20 && *p < 0x7f) ? (*p) : '.';
+    }
+
+    hex = hex + '\n';
+  }
+  return hex;
+}
+
+}  // namespace
+
+namespace quiche {
+namespace test {
+
+void CompareCharArraysWithHexError(const std::string& description,
+                                   const char* actual,
+                                   const int actual_len,
+                                   const char* expected,
+                                   const int expected_len) {
+  EXPECT_EQ(actual_len, expected_len);
+  const int min_len = std::min(actual_len, expected_len);
+  const int max_len = std::max(actual_len, expected_len);
+  std::unique_ptr<bool[]> marks(new bool[max_len]);
+  bool identical = (actual_len == expected_len);
+  for (int i = 0; i < min_len; ++i) {
+    if (actual[i] != expected[i]) {
+      marks[i] = true;
+      identical = false;
+    } else {
+      marks[i] = false;
+    }
+  }
+  for (int i = min_len; i < max_len; ++i) {
+    marks[i] = true;
+  }
+  if (identical)
+    return;
+  ADD_FAILURE() << "Description:\n"
+                << description << "\n\nExpected:\n"
+                << HexDumpWithMarks(expected, expected_len, marks.get(),
+                                    max_len)
+                << "\nActual:\n"
+                << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
+}
+
+iovec MakeIOVector(absl::string_view str) {
+  return iovec{const_cast<char*>(str.data()), static_cast<size_t>(str.size())};
+}
+
+}  // namespace test
+}  // namespace quiche
diff --git a/quiche/common/test_tools/quiche_test_utils.h b/quiche/common/test_tools/quiche_test_utils.h
new file mode 100644
index 0000000..a9ef27a
--- /dev/null
+++ b/quiche/common/test_tools/quiche_test_utils.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_QUICHE_TEST_UTILS_H_
+#define QUICHE_COMMON_QUICHE_TEST_UTILS_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+
+namespace quiche {
+namespace test {
+
+void CompareCharArraysWithHexError(const std::string& description,
+                                   const char* actual,
+                                   const int actual_len,
+                                   const char* expected,
+                                   const int expected_len);
+
+// Create iovec that points to that data that `str` points to.
+iovec MakeIOVector(absl::string_view str);
+
+}  // namespace test
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_QUICHE_TEST_UTILS_H_
diff --git a/quiche/epoll_server/fake_simple_epoll_server.cc b/quiche/epoll_server/fake_simple_epoll_server.cc
new file mode 100644
index 0000000..f21ae1c
--- /dev/null
+++ b/quiche/epoll_server/fake_simple_epoll_server.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/epoll_server/fake_simple_epoll_server.h"
+
+namespace epoll_server {
+namespace test {
+
+FakeTimeSimpleEpollServer::FakeTimeSimpleEpollServer() : now_in_usec_(0) {}
+
+FakeTimeSimpleEpollServer::~FakeTimeSimpleEpollServer() = default;
+
+int64_t FakeTimeSimpleEpollServer::NowInUsec() const { return now_in_usec_; }
+
+FakeSimpleEpollServer::FakeSimpleEpollServer() : until_in_usec_(-1) {}
+
+FakeSimpleEpollServer::~FakeSimpleEpollServer() = default;
+
+int FakeSimpleEpollServer::epoll_wait_impl(int /*epfd*/,
+                                           struct epoll_event* events,
+                                           int max_events, int timeout_in_ms) {
+  int num_events = 0;
+  while (!event_queue_.empty() && num_events < max_events &&
+         event_queue_.begin()->first <= NowInUsec() &&
+         ((until_in_usec_ == -1) ||
+          (event_queue_.begin()->first < until_in_usec_))) {
+    int64_t event_time_in_usec = event_queue_.begin()->first;
+    events[num_events] = event_queue_.begin()->second;
+    if (event_time_in_usec > NowInUsec()) {
+      set_now_in_usec(event_time_in_usec);
+    }
+    event_queue_.erase(event_queue_.begin());
+    ++num_events;
+  }
+  if (num_events == 0) {       // then we'd have waited 'till the timeout.
+    if (until_in_usec_ < 0) {  // then we don't care what the final time is.
+      if (timeout_in_ms > 0) {
+        AdvanceBy(timeout_in_ms * 1000);
+      }
+    } else {  // except we assume that we don't wait for the timeout
+      // period if until_in_usec_ is a positive number.
+      set_now_in_usec(until_in_usec_);
+      // And reset until_in_usec_ to signal no waiting (as
+      // the AdvanceByExactly* stuff is meant to be one-shot,
+      // as are all similar net::EpollServer functions)
+      until_in_usec_ = -1;
+    }
+  }
+  if (until_in_usec_ >= 0) {
+    CHECK(until_in_usec_ >= NowInUsec());
+  }
+  return num_events;
+}
+
+}  // namespace test
+}  // namespace epoll_server
diff --git a/quiche/epoll_server/fake_simple_epoll_server.h b/quiche/epoll_server/fake_simple_epoll_server.h
new file mode 100644
index 0000000..4338afe
--- /dev/null
+++ b/quiche/epoll_server/fake_simple_epoll_server.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
+#define QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <map>
+
+#include "quiche/epoll_server/platform/api/epoll_export.h"
+#include "quiche/epoll_server/simple_epoll_server.h"
+
+namespace epoll_server {
+namespace test {
+
+// Unlike the full FakeEpollServer, this only lies about the time but lets
+// fd events operate normally.  Usefully when interacting with real backends
+// but wanting to skip forward in time to trigger timeouts.
+class EPOLL_EXPORT_PRIVATE FakeTimeSimpleEpollServer
+    : public SimpleEpollServer {
+ public:
+  FakeTimeSimpleEpollServer();
+  FakeTimeSimpleEpollServer(const FakeTimeSimpleEpollServer&) = delete;
+  FakeTimeSimpleEpollServer operator=(const FakeTimeSimpleEpollServer&) =
+      delete;
+
+  ~FakeTimeSimpleEpollServer() override;
+
+  // Replaces the net::EpollServer NowInUsec.
+  int64_t NowInUsec() const override;
+
+  void set_now_in_usec(int64_t nius) { now_in_usec_ = nius; }
+
+  // Advances the virtual 'now' by advancement_usec.
+  void AdvanceBy(int64_t advancement_usec) {
+    set_now_in_usec(NowInUsec() + advancement_usec);
+  }
+
+  // Advances the virtual 'now' by advancement_usec, and
+  // calls WaitForEventAndExecteCallbacks.
+  // Note that the WaitForEventsAndExecuteCallbacks invocation
+  // may cause NowInUs to advance beyond what was specified here.
+  // If that is not desired, use the AdvanceByExactly calls.
+  void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64_t advancement_usec) {
+    AdvanceBy(advancement_usec);
+    WaitForEventsAndExecuteCallbacks();
+  }
+
+ private:
+  int64_t now_in_usec_;
+};
+
+class EPOLL_EXPORT_PRIVATE FakeSimpleEpollServer
+    : public FakeTimeSimpleEpollServer {
+ public:  // type definitions
+  using EventQueue = std::multimap<int64_t, struct epoll_event>;
+
+  FakeSimpleEpollServer();
+  FakeSimpleEpollServer(const FakeSimpleEpollServer&) = delete;
+  FakeSimpleEpollServer operator=(const FakeSimpleEpollServer&) = delete;
+
+  ~FakeSimpleEpollServer() override;
+
+  // time_in_usec is the time at which the event specified
+  // by 'ee' will be delivered. Note that it -is- possible
+  // to add an event for a time which has already been passed..
+  // .. upon the next time that the callbacks are invoked,
+  // all events which are in the 'past' will be delivered.
+  void AddEvent(int64_t time_in_usec, const struct epoll_event& ee) {
+    event_queue_.insert(std::make_pair(time_in_usec, ee));
+  }
+
+  // Advances the virtual 'now' by advancement_usec,
+  // and ensure that the next invocation of
+  // WaitForEventsAndExecuteCallbacks goes no farther than
+  // advancement_usec from the current time.
+  void AdvanceByExactly(int64_t advancement_usec) {
+    until_in_usec_ = NowInUsec() + advancement_usec;
+    set_now_in_usec(NowInUsec() + advancement_usec);
+  }
+
+  // As above, except calls WaitForEventsAndExecuteCallbacks.
+  void AdvanceByExactlyAndCallCallbacks(int64_t advancement_usec) {
+    AdvanceByExactly(advancement_usec);
+    WaitForEventsAndExecuteCallbacks();
+  }
+
+  std::unordered_set<AlarmCB*>::size_type NumberOfAlarms() const {
+    return all_alarms_.size();
+  }
+
+ protected:  // functions
+  // These functions do nothing here, as we're not actually
+  // using the epoll_* syscalls.
+  void DelFD(int /*fd*/) const override {}
+  void AddFD(int /*fd*/, int /*event_mask*/) const override {}
+  void ModFD(int /*fd*/, int /*event_mask*/) const override {}
+
+  // Replaces the epoll_server's epoll_wait_impl.
+  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
+                      int timeout_in_ms) override;
+  void SetNonblocking(int /*fd*/) override {}
+
+ private:  // members
+  EventQueue event_queue_;
+  int64_t until_in_usec_;
+};
+
+}  // namespace test
+}  // namespace epoll_server
+
+#endif  // QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
diff --git a/epoll_server/platform/api/epoll_address_test_utils.h b/quiche/epoll_server/platform/api/epoll_address_test_utils.h
similarity index 100%
rename from epoll_server/platform/api/epoll_address_test_utils.h
rename to quiche/epoll_server/platform/api/epoll_address_test_utils.h
diff --git a/epoll_server/platform/api/epoll_bug.h b/quiche/epoll_server/platform/api/epoll_bug.h
similarity index 100%
rename from epoll_server/platform/api/epoll_bug.h
rename to quiche/epoll_server/platform/api/epoll_bug.h
diff --git a/epoll_server/platform/api/epoll_expect_bug.h b/quiche/epoll_server/platform/api/epoll_expect_bug.h
similarity index 100%
rename from epoll_server/platform/api/epoll_expect_bug.h
rename to quiche/epoll_server/platform/api/epoll_expect_bug.h
diff --git a/epoll_server/platform/api/epoll_export.h b/quiche/epoll_server/platform/api/epoll_export.h
similarity index 100%
rename from epoll_server/platform/api/epoll_export.h
rename to quiche/epoll_server/platform/api/epoll_export.h
diff --git a/epoll_server/platform/api/epoll_logging.h b/quiche/epoll_server/platform/api/epoll_logging.h
similarity index 100%
rename from epoll_server/platform/api/epoll_logging.h
rename to quiche/epoll_server/platform/api/epoll_logging.h
diff --git a/epoll_server/platform/api/epoll_ptr_util.h b/quiche/epoll_server/platform/api/epoll_ptr_util.h
similarity index 100%
rename from epoll_server/platform/api/epoll_ptr_util.h
rename to quiche/epoll_server/platform/api/epoll_ptr_util.h
diff --git a/epoll_server/platform/api/epoll_test.h b/quiche/epoll_server/platform/api/epoll_test.h
similarity index 100%
rename from epoll_server/platform/api/epoll_test.h
rename to quiche/epoll_server/platform/api/epoll_test.h
diff --git a/epoll_server/platform/api/epoll_thread.h b/quiche/epoll_server/platform/api/epoll_thread.h
similarity index 100%
rename from epoll_server/platform/api/epoll_thread.h
rename to quiche/epoll_server/platform/api/epoll_thread.h
diff --git a/epoll_server/platform/api/epoll_time.h b/quiche/epoll_server/platform/api/epoll_time.h
similarity index 100%
rename from epoll_server/platform/api/epoll_time.h
rename to quiche/epoll_server/platform/api/epoll_time.h
diff --git a/quiche/epoll_server/simple_epoll_server.cc b/quiche/epoll_server/simple_epoll_server.cc
new file mode 100644
index 0000000..227089e
--- /dev/null
+++ b/quiche/epoll_server/simple_epoll_server.cc
@@ -0,0 +1,813 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/epoll_server/simple_epoll_server.h"
+
+#include <errno.h>   // for errno
+#include <stdlib.h>  // for abort
+#include <string.h>  // for strerror_r
+#include <unistd.h>  // For read, pipe, close and write.
+
+#include <algorithm>
+#include <utility>
+
+#include "quiche/epoll_server/platform/api/epoll_bug.h"
+#include "quiche/epoll_server/platform/api/epoll_time.h"
+
+// Design notes: An efficient implementation of ready list has the following
+// desirable properties:
+//
+// A. O(1) insertion into/removal from the list in any location.
+// B. Once the callback is found by hash lookup using the fd, the lookup of
+//    corresponding entry in the list is O(1).
+// C. Safe insertion into/removal from the list during list iteration. (The
+//    ready list's purpose is to enable completely event driven I/O model.
+//    Thus, all the interesting bits happen in the callback. It is critical
+//    to not place any restriction on the API during list iteration.
+//
+// The current implementation achieves these goals with the following design:
+//
+// - The ready list is constructed as a doubly linked list to enable O(1)
+//   insertion/removal (see man 3 queue).
+// - The forward and backward links are directly embedded inside the
+//   CBAndEventMask struct. This enables O(1) lookup in the list for a given
+//   callback. (Techincally, we could've used std::list of hash_set::iterator,
+//   and keep a list::iterator in CBAndEventMask to achieve the same effect.
+//   However, iterators have two problems: no way to portably invalidate them,
+//   and no way to tell whether an iterator is singular or not. The only way to
+//   overcome these issues is to keep bools in both places, but that throws off
+//   memory alignment (up to 7 wasted bytes for each bool). The extra level of
+//   indirection will also likely be less cache friendly. Direct manipulation
+//   of link pointers makes it easier to retrieve the CBAndEventMask from the
+//   list, easier to check whether an CBAndEventMask is in the list, uses less
+//   memory (save 32 bytes/fd), and does not affect cache usage (we need to
+//   read in the struct to use the callback anyway).)
+// - Embed the fd directly into CBAndEventMask and switch to using hash_set.
+//   This removes the need to store hash_map::iterator in the list just so that
+//   we can get both the fd and the callback.
+// - The ready list is "one shot": each entry is removed before OnEvent is
+//   called. This removes the mutation-while-iterating problem.
+// - Use two lists to keep track of callbacks. The ready_list_ is the one used
+//   for registration. Before iteration, the ready_list_ is swapped into the
+//   tmp_list_. Once iteration is done, tmp_list_ will be empty, and
+//   ready_list_ will have all the new ready fds.
+
+// The size we use for buffers passed to strerror_r
+static const int kErrorBufferSize = 256;
+
+namespace epoll_server {
+
+template <typename T>
+class AutoReset {
+ public:
+  AutoReset(T* scoped_variable, T new_value)
+      : scoped_variable_(scoped_variable),
+        original_value_(std::move(*scoped_variable)) {
+    *scoped_variable_ = std::move(new_value);
+  }
+  AutoReset(const AutoReset&) = delete;
+  AutoReset& operator=(const AutoReset&) = delete;
+
+  ~AutoReset() { *scoped_variable_ = std::move(original_value_); }
+
+ private:
+  T* scoped_variable_;
+  T original_value_;
+};
+
+// Clears the pipe and returns.  Used for waking the epoll server up.
+class ReadPipeCallback : public EpollCallbackInterface {
+ public:
+  void OnEvent(int fd, EpollEvent* event) override {
+    DCHECK(event->in_events == EPOLLIN);
+    int data;
+    int data_read = 1;
+    // Read until the pipe is empty.
+    while (data_read > 0) {
+      data_read = read(fd, &data, sizeof(data));
+    }
+  }
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+  void OnRegistration(SimpleEpollServer*, int, int) override {}
+  void OnModification(int, int) override {}     // COV_NF_LINE
+  void OnUnregistration(int, bool) override {}  // COV_NF_LINE
+  std::string Name() const override { return "ReadPipeCallback"; }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+SimpleEpollServer::SimpleEpollServer()
+    : epoll_fd_(epoll_create(1024)),
+      timeout_in_us_(0),
+      recorded_now_in_us_(0),
+      ready_list_size_(0),
+      wake_cb_(new ReadPipeCallback),
+      read_fd_(-1),
+      write_fd_(-1),
+      in_wait_for_events_and_execute_callbacks_(false),
+      in_shutdown_(false),
+      last_delay_in_usec_(0) {
+  // ensure that the epoll_fd_ is valid.
+  CHECK_NE(epoll_fd_, -1);
+  LIST_INIT(&ready_list_);
+  LIST_INIT(&tmp_list_);
+
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    // Unfortunately, it is impossible to test any such initialization in
+    // a constructor (as virtual methods do not yet work).
+    // This -could- be solved by moving initialization to an outside
+    // call...
+    int saved_errno = errno;
+    char buf[kErrorBufferSize];
+    EPOLL_LOG(FATAL) << "Error " << saved_errno << " in pipe(): "
+                     << strerror_r(saved_errno, buf, sizeof(buf));
+  }
+  read_fd_ = pipe_fds[0];
+  write_fd_ = pipe_fds[1];
+  RegisterFD(read_fd_, wake_cb_.get(), EPOLLIN);
+}
+
+void SimpleEpollServer::CleanupFDToCBMap() {
+  auto cb_iter = cb_map_.begin();
+  while (cb_iter != cb_map_.end()) {
+    int fd = cb_iter->fd;
+    CB* cb = cb_iter->cb;
+
+    cb_iter->in_use = true;
+    if (cb) {
+      cb->OnShutdown(this, fd);
+    }
+
+    cb_map_.erase(cb_iter);
+    cb_iter = cb_map_.begin();
+  }
+}
+
+void SimpleEpollServer::CleanupTimeToAlarmCBMap() {
+  TimeToAlarmCBMap::iterator erase_it;
+
+  // Call OnShutdown() on alarms. Note that the structure of the loop
+  // is similar to the structure of loop in the function HandleAlarms()
+  for (auto i = alarm_map_.begin(); i != alarm_map_.end();) {
+    // Note that OnShutdown() can call UnregisterAlarm() on
+    // other iterators. OnShutdown() should not call UnregisterAlarm()
+    // on self because by definition the iterator is not valid any more.
+    i->second->OnShutdown(this);
+    erase_it = i;
+    ++i;
+    alarm_map_.erase(erase_it);
+  }
+}
+
+SimpleEpollServer::~SimpleEpollServer() {
+  DCHECK_EQ(in_shutdown_, false);
+  in_shutdown_ = true;
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  EPOLL_LOG(INFO) << "\n" << event_recorder_;
+#endif
+  EPOLL_VLOG(2) << "Shutting down epoll server ";
+  CleanupFDToCBMap();
+
+  LIST_INIT(&ready_list_);
+  LIST_INIT(&tmp_list_);
+
+  CleanupTimeToAlarmCBMap();
+
+  close(read_fd_);
+  close(write_fd_);
+  close(epoll_fd_);
+}
+
+// Whether a CBAandEventMask is on the ready list is determined by a non-NULL
+// le_prev pointer (le_next being NULL indicates end of list).
+inline void SimpleEpollServer::AddToReadyList(CBAndEventMask* cb_and_mask) {
+  if (cb_and_mask->entry.le_prev == NULL) {
+    LIST_INSERT_HEAD(&ready_list_, cb_and_mask, entry);
+    ++ready_list_size_;
+  }
+}
+
+inline void SimpleEpollServer::RemoveFromReadyList(
+    const CBAndEventMask& cb_and_mask) {
+  if (cb_and_mask.entry.le_prev != NULL) {
+    LIST_REMOVE(&cb_and_mask, entry);
+    // Clean up all the ready list states. Don't bother with the other fields
+    // as they are initialized when the CBAandEventMask is added to the ready
+    // list. This saves a few cycles in the inner loop.
+    cb_and_mask.entry.le_prev = NULL;
+    --ready_list_size_;
+    if (ready_list_size_ == 0) {
+      DCHECK(ready_list_.lh_first == NULL);
+      DCHECK(tmp_list_.lh_first == NULL);
+    }
+  }
+}
+
+void SimpleEpollServer::RegisterFD(int fd, CB* cb, int event_mask) {
+  CHECK(cb);
+  EPOLL_VLOG(3) << "RegisterFD fd=" << fd << " event_mask=" << event_mask;
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  if (cb_map_.end() != fd_i) {
+    // do we just abort, or do we just unregister the other callback?
+    // for now, lets just unregister the other callback.
+
+    // unregister any callback that may already be registered for this FD.
+    CB* other_cb = fd_i->cb;
+    if (other_cb) {
+      // Must remove from the ready list before erasing.
+      RemoveFromReadyList(*fd_i);
+      other_cb->OnUnregistration(fd, true);
+      ModFD(fd, event_mask);
+    } else {
+      // already unregistered, so just recycle the node.
+      AddFD(fd, event_mask);
+    }
+    fd_i->cb = cb;
+    fd_i->event_mask = event_mask;
+    fd_i->events_to_fake = 0;
+  } else {
+    AddFD(fd, event_mask);
+    cb_map_.insert(CBAndEventMask(cb, event_mask, fd));
+  }
+
+  // set the FD to be non-blocking.
+  SetNonblocking(fd);
+
+  cb->OnRegistration(this, fd, event_mask);
+}
+
+void SimpleEpollServer::SetNonblocking(int fd) {
+  int flags = fcntl(fd, F_GETFL, 0);
+  if (flags == -1) {
+    int saved_errno = errno;
+    char buf[kErrorBufferSize];
+    EPOLL_LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
+                     << ", F_GETFL, 0): "
+                     << strerror_r(saved_errno, buf, sizeof(buf));
+  }
+  if (!(flags & O_NONBLOCK)) {
+    int saved_flags = flags;
+    flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+    if (flags == -1) {
+      // bad.
+      int saved_errno = errno;
+      char buf[kErrorBufferSize];
+      EPOLL_LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
+                       << ", F_SETFL, " << saved_flags
+                       << "): " << strerror_r(saved_errno, buf, sizeof(buf));
+    }
+  }
+}
+
+int SimpleEpollServer::epoll_wait_impl(int epfd, struct epoll_event* events,
+                                       int max_events, int timeout_in_ms) {
+  return epoll_wait(epfd, events, max_events, timeout_in_ms);
+}
+
+void SimpleEpollServer::RegisterFDForWrite(int fd, CB* cb) {
+  RegisterFD(fd, cb, EPOLLOUT);
+}
+
+void SimpleEpollServer::RegisterFDForReadWrite(int fd, CB* cb) {
+  RegisterFD(fd, cb, EPOLLIN | EPOLLOUT);
+}
+
+void SimpleEpollServer::RegisterFDForRead(int fd, CB* cb) {
+  RegisterFD(fd, cb, EPOLLIN);
+}
+
+void SimpleEpollServer::UnregisterFD(int fd) {
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  if (cb_map_.end() == fd_i || fd_i->cb == NULL) {
+    // Doesn't exist in server, or has gone through UnregisterFD once and still
+    // inside the callchain of OnEvent.
+    return;
+  }
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  event_recorder_.RecordUnregistration(fd);
+#endif
+  CB* cb = fd_i->cb;
+  // Since the links are embedded within the struct, we must remove it from the
+  // list before erasing it from the hash_set.
+  RemoveFromReadyList(*fd_i);
+  DelFD(fd);
+  cb->OnUnregistration(fd, false);
+  // fd_i->cb is NULL if that fd is unregistered inside the callchain of
+  // OnEvent. Since the SimpleEpollServer needs a valid CBAndEventMask after
+  // OnEvent returns in order to add it to the ready list, we cannot have
+  // UnregisterFD erase the entry if it is in use. Thus, a NULL fd_i->cb is used
+  // as a condition that tells the SimpleEpollServer that this entry is unused
+  // at a later point.
+  if (!fd_i->in_use) {
+    cb_map_.erase(fd_i);
+  } else {
+    // Remove all trace of the registration, and just keep the node alive long
+    // enough so the code that calls OnEvent doesn't have to worry about
+    // figuring out whether the CBAndEventMask is valid or not.
+    fd_i->cb = NULL;
+    fd_i->event_mask = 0;
+    fd_i->events_to_fake = 0;
+  }
+}
+
+void SimpleEpollServer::ModifyCallback(int fd, int event_mask) {
+  ModifyFD(fd, ~0, event_mask);
+}
+
+void SimpleEpollServer::StopRead(int fd) { ModifyFD(fd, EPOLLIN, 0); }
+
+void SimpleEpollServer::StartRead(int fd) { ModifyFD(fd, 0, EPOLLIN); }
+
+void SimpleEpollServer::StopWrite(int fd) { ModifyFD(fd, EPOLLOUT, 0); }
+
+void SimpleEpollServer::StartWrite(int fd) { ModifyFD(fd, 0, EPOLLOUT); }
+
+void SimpleEpollServer::HandleEvent(int fd, int event_mask) {
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  event_recorder_.RecordEpollEvent(fd, event_mask);
+#endif
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  if (fd_i == cb_map_.end() || fd_i->cb == NULL) {
+    // Ignore the event.
+    // This could occur if epoll() returns a set of events, and
+    // while processing event A (earlier) we removed the callback
+    // for event B (and are now processing event B).
+    return;
+  }
+  fd_i->events_asserted = event_mask;
+  CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i);
+  AddToReadyList(cb_and_mask);
+}
+
+void SimpleEpollServer::WaitForEventsAndExecuteCallbacks() {
+  if (in_wait_for_events_and_execute_callbacks_) {
+    EPOLL_LOG(DFATAL) << "Attempting to call WaitForEventsAndExecuteCallbacks"
+                         " when an ancestor to the current function is already"
+                         " WaitForEventsAndExecuteCallbacks!";
+    // The line below is actually tested, but in coverage mode,
+    // we never see it.
+    return;  // COV_NF_LINE
+  }
+  AutoReset<bool> recursion_guard(&in_wait_for_events_and_execute_callbacks_,
+                                  true);
+  if (alarm_map_.empty()) {
+    // no alarms, this is business as usual.
+    WaitForEventsAndCallHandleEvents(timeout_in_us_, events_, events_size_);
+    recorded_now_in_us_ = 0;
+    return;
+  }
+
+  // store the 'now'. If we recomputed 'now' every iteration
+  // down below, then we might never exit that loop-- any
+  // long-running alarms might install other long-running
+  // alarms, etc. By storing it here now, we ensure that
+  // a more reasonable amount of work is done here.
+  int64_t now_in_us = NowInUsec();
+
+  // Get the first timeout from the alarm_map where it is
+  // stored in absolute time.
+  int64_t next_alarm_time_in_us = alarm_map_.begin()->first;
+  EPOLL_VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us
+                << " now             = " << now_in_us
+                << " timeout_in_us = " << timeout_in_us_;
+
+  int64_t wait_time_in_us;
+  int64_t alarm_timeout_in_us = next_alarm_time_in_us - now_in_us;
+
+  // If the next alarm is sooner than the default timeout, or if there is no
+  // timeout (timeout_in_us_ == -1), wake up when the alarm should fire.
+  // Otherwise use the default timeout.
+  if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) {
+    wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64_t>(0));
+  } else {
+    wait_time_in_us = timeout_in_us_;
+  }
+
+  EPOLL_VLOG(4) << "wait_time_in_us = " << wait_time_in_us;
+
+  // wait for events.
+
+  WaitForEventsAndCallHandleEvents(wait_time_in_us, events_, events_size_);
+  CallAndReregisterAlarmEvents();
+  recorded_now_in_us_ = 0;
+}
+
+void SimpleEpollServer::SetFDReady(int fd, int events_to_fake) {
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  if (cb_map_.end() != fd_i && fd_i->cb != NULL) {
+    // This const_cast is necessary for LIST_HEAD_INSERT to work. Declaring
+    // entry mutable is insufficient because LIST_HEAD_INSERT assigns the
+    // forward pointer of the list head to the current cb_and_mask, and the
+    // compiler complains that it can't assign a const T* to a T*.
+    CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i);
+    // Note that there is no clearly correct behavior here when
+    // cb_and_mask->events_to_fake != 0 and this function is called.
+    // Of the two operations:
+    //      cb_and_mask->events_to_fake = events_to_fake
+    //      cb_and_mask->events_to_fake |= events_to_fake
+    // the first was picked because it discourages users from calling
+    // SetFDReady repeatedly to build up the correct event set as it is more
+    // efficient to call SetFDReady once with the correct, final mask.
+    cb_and_mask->events_to_fake = events_to_fake;
+    AddToReadyList(cb_and_mask);
+  }
+}
+
+void SimpleEpollServer::SetFDNotReady(int fd) {
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  if (cb_map_.end() != fd_i) {
+    RemoveFromReadyList(*fd_i);
+  }
+}
+
+bool SimpleEpollServer::IsFDReady(int fd) const {
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  return (cb_map_.end() != fd_i && fd_i->cb != NULL &&
+          fd_i->entry.le_prev != NULL);
+}
+
+void SimpleEpollServer::VerifyReadyList() const {
+  int count = 0;
+  CBAndEventMask* cur = ready_list_.lh_first;
+  for (; cur; cur = cur->entry.le_next) {
+    ++count;
+  }
+  for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) {
+    ++count;
+  }
+  CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count";
+}
+
+void SimpleEpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) {
+  EPOLL_VLOG(4) << "RegisteringAlarm " << ac << " at : " << timeout_time_in_us;
+  CHECK(ac);
+  if (all_alarms_.find(ac) != all_alarms_.end()) {
+    EPOLL_BUG(epoll_bug_1_1) << "Alarm already exists";
+  }
+
+  auto alarm_iter = alarm_map_.insert(std::make_pair(timeout_time_in_us, ac));
+
+  all_alarms_.insert(ac);
+  // Pass the iterator to the EpollAlarmCallbackInterface.
+  ac->OnRegistration(alarm_iter, this);
+}
+
+// Unregister a specific alarm callback: iterator_token must be a
+//  valid iterator. The caller must ensure the validity of the iterator.
+void SimpleEpollServer::UnregisterAlarm(const AlarmRegToken& iterator_token) {
+  AlarmCB* cb = iterator_token->second;
+  EPOLL_VLOG(4) << "UnregisteringAlarm " << cb;
+  alarm_map_.erase(iterator_token);
+  all_alarms_.erase(cb);
+  cb->OnUnregistration();
+}
+
+SimpleEpollServer::AlarmRegToken SimpleEpollServer::ReregisterAlarm(
+    SimpleEpollServer::AlarmRegToken iterator_token,
+    int64_t timeout_time_in_us) {
+  AlarmCB* cb = iterator_token->second;
+  alarm_map_.erase(iterator_token);
+  return alarm_map_.emplace(timeout_time_in_us, cb);
+}
+
+int SimpleEpollServer::NumFDsRegistered() const {
+  DCHECK_GE(cb_map_.size(), 1u);
+  // Omit the internal FD (read_fd_)
+  return cb_map_.size() - 1;
+}
+
+void SimpleEpollServer::Wake() {
+  char data = 'd';  // 'd' is for data.  It's good enough for me.
+  int rv = write(write_fd_, &data, 1);
+  DCHECK_EQ(rv, 1);
+}
+
+int64_t SimpleEpollServer::NowInUsec() const { return WallTimeNowInUsec(); }
+
+int64_t SimpleEpollServer::ApproximateNowInUsec() const {
+  if (recorded_now_in_us_ != 0) {
+    return recorded_now_in_us_;
+  }
+  return this->NowInUsec();
+}
+
+std::string SimpleEpollServer::EventMaskToString(int event_mask) {
+  std::string s;
+  if (event_mask & EPOLLIN) s += "EPOLLIN ";
+  if (event_mask & EPOLLPRI) s += "EPOLLPRI ";
+  if (event_mask & EPOLLOUT) s += "EPOLLOUT ";
+  if (event_mask & EPOLLRDNORM) s += "EPOLLRDNORM ";
+  if (event_mask & EPOLLRDBAND) s += "EPOLLRDBAND ";
+  if (event_mask & EPOLLWRNORM) s += "EPOLLWRNORM ";
+  if (event_mask & EPOLLWRBAND) s += "EPOLLWRBAND ";
+  if (event_mask & EPOLLMSG) s += "EPOLLMSG ";
+  if (event_mask & EPOLLERR) s += "EPOLLERR ";
+  if (event_mask & EPOLLHUP) s += "EPOLLHUP ";
+  if (event_mask & EPOLLONESHOT) s += "EPOLLONESHOT ";
+  if (event_mask & EPOLLET) s += "EPOLLET ";
+  return s;
+}
+
+void SimpleEpollServer::LogStateOnCrash() {
+  EPOLL_LOG(ERROR)
+      << "-------------------Epoll Server-------------------------";
+  EPOLL_LOG(ERROR) << "Epoll server " << this << " polling on fd " << epoll_fd_;
+  EPOLL_LOG(ERROR) << "timeout_in_us_: " << timeout_in_us_;
+
+  // Log sessions with alarms.
+  EPOLL_LOG(ERROR) << alarm_map_.size() << " alarms registered.";
+  for (auto it = alarm_map_.begin(); it != alarm_map_.end(); ++it) {
+    const bool skipped =
+        alarms_reregistered_and_should_be_skipped_.find(it->second) !=
+        alarms_reregistered_and_should_be_skipped_.end();
+    EPOLL_LOG(ERROR) << "Alarm " << it->second << " registered at time "
+                     << it->first << " and should be skipped = " << skipped;
+  }
+
+  EPOLL_LOG(ERROR) << cb_map_.size() << " fd callbacks registered.";
+  for (auto it = cb_map_.begin(); it != cb_map_.end(); ++it) {
+    EPOLL_LOG(ERROR) << "fd: " << it->fd << " with mask " << it->event_mask
+                     << " registered with cb: " << it->cb;
+  }
+  EPOLL_LOG(ERROR)
+      << "-------------------/Epoll Server------------------------";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+void SimpleEpollServer::DelFD(int fd) const {
+  struct epoll_event ee;
+  memset(&ee, 0, sizeof(ee));
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  event_recorder_.RecordFDMaskEvent(fd, 0, "DelFD");
+#endif
+  if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee)) {
+    int saved_errno = errno;
+    char buf[kErrorBufferSize];
+    EPOLL_LOG(FATAL) << "Epoll set removal error for fd " << fd << ": "
+                     << strerror_r(saved_errno, buf, sizeof(buf));
+  }
+}
+
+////////////////////////////////////////
+
+void SimpleEpollServer::AddFD(int fd, int event_mask) const {
+  struct epoll_event ee;
+  memset(&ee, 0, sizeof(ee));
+  ee.events = event_mask | EPOLLERR | EPOLLHUP;
+  ee.data.fd = fd;
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  event_recorder_.RecordFDMaskEvent(fd, ee.events, "AddFD");
+#endif
+  if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ee)) {
+    int saved_errno = errno;
+    char buf[kErrorBufferSize];
+    EPOLL_LOG(FATAL) << "Epoll set insertion error for fd " << fd << ": "
+                     << strerror_r(saved_errno, buf, sizeof(buf));
+  }
+}
+
+////////////////////////////////////////
+
+void SimpleEpollServer::ModFD(int fd, int event_mask) const {
+  struct epoll_event ee;
+  memset(&ee, 0, sizeof(ee));
+  ee.events = event_mask | EPOLLERR | EPOLLHUP;
+  ee.data.fd = fd;
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  event_recorder_.RecordFDMaskEvent(fd, ee.events, "ModFD");
+#endif
+  EPOLL_VLOG(3) << "modifying fd= " << fd << " "
+                << EventMaskToString(ee.events);
+  if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ee)) {
+    int saved_errno = errno;
+    char buf[kErrorBufferSize];
+    EPOLL_LOG(FATAL) << "Epoll set modification error for fd " << fd << ": "
+                     << strerror_r(saved_errno, buf, sizeof(buf));
+  }
+}
+
+////////////////////////////////////////
+
+void SimpleEpollServer::ModifyFD(int fd, int remove_event, int add_event) {
+  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
+  if (cb_map_.end() == fd_i) {
+    EPOLL_VLOG(2) << "Didn't find the fd " << fd << "in internal structures";
+    return;
+  }
+
+  if (fd_i->cb != NULL) {
+    int& event_mask = fd_i->event_mask;
+    EPOLL_VLOG(3) << "fd= " << fd
+                  << " event_mask before: " << EventMaskToString(event_mask);
+    event_mask &= ~remove_event;
+    event_mask |= add_event;
+
+    EPOLL_VLOG(3) << " event_mask after: " << EventMaskToString(event_mask);
+
+    ModFD(fd, event_mask);
+
+    fd_i->cb->OnModification(fd, event_mask);
+  }
+}
+
+void SimpleEpollServer::WaitForEventsAndCallHandleEvents(
+    int64_t timeout_in_us, struct epoll_event events[], int events_size) {
+  if (timeout_in_us == 0 || ready_list_.lh_first != NULL) {
+    // If ready list is not empty, then don't sleep at all.
+    timeout_in_us = 0;
+  } else if (timeout_in_us < 0) {
+    EPOLL_LOG(INFO) << "Negative epoll timeout: " << timeout_in_us
+                    << "us; epoll will wait forever for events.";
+    // If timeout_in_us is < 0 we are supposed to Wait forever.  This means we
+    // should set timeout_in_us to -1000 so we will
+    // Wait(-1000/1000) == Wait(-1) == Wait forever.
+    timeout_in_us = -1000;
+  } else {
+    // If timeout is specified, and the ready list is empty.
+    if (timeout_in_us < 1000) {
+      timeout_in_us = 1000;
+    }
+  }
+  const int timeout_in_ms = timeout_in_us / 1000;
+  int64_t expected_wakeup_us = NowInUsec() + timeout_in_us;
+
+  int nfds = epoll_wait_impl(epoll_fd_, events, events_size, timeout_in_ms);
+  EPOLL_VLOG(3) << "nfds=" << nfds;
+
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  event_recorder_.RecordEpollWaitEvent(timeout_in_ms, nfds);
+#endif
+
+  // If you're wondering why the NowInUsec() is recorded here, the answer is
+  // simple: If we did it before the epoll_wait_impl, then the max error for
+  // the ApproximateNowInUs() call would be as large as the maximum length of
+  // epoll_wait, which can be arbitrarily long. Since this would make
+  // ApproximateNowInUs() worthless, we instead record the time -after- we've
+  // done epoll_wait, which guarantees that the maximum error is the amount of
+  // time it takes to process all the events generated by epoll_wait.
+  recorded_now_in_us_ = NowInUsec();
+
+  if (timeout_in_us > 0) {
+    int64_t delta = NowInUsec() - expected_wakeup_us;
+    last_delay_in_usec_ = delta > 0 ? delta : 0;
+  } else {
+    // timeout_in_us < 0 means we waited forever until an event;
+    // timeout_in_us == 0 means there was no kernel delay to track.
+    last_delay_in_usec_ = 0;
+  }
+
+  if (nfds > 0) {
+    for (int i = 0; i < nfds; ++i) {
+      int event_mask = events[i].events;
+      int fd = events[i].data.fd;
+      HandleEvent(fd, event_mask);
+    }
+  } else if (nfds < 0) {
+    // Catch interrupted syscall and just ignore it and move on.
+    if (errno != EINTR && errno != 0) {
+      int saved_errno = errno;
+      char buf[kErrorBufferSize];
+      EPOLL_LOG(FATAL) << "Error " << saved_errno << " in epoll_wait: "
+                       << strerror_r(saved_errno, buf, sizeof(buf));
+    }
+  }
+
+  // Now run through the ready list.
+  if (ready_list_.lh_first) {
+    CallReadyListCallbacks();
+  }
+}
+
+void SimpleEpollServer::CallReadyListCallbacks() {
+  // Check pre-conditions.
+  DCHECK(tmp_list_.lh_first == NULL);
+  // Swap out the ready_list_ into the tmp_list_ before traversing the list to
+  // enable SetFDReady() to just push new items into the ready_list_.
+  std::swap(ready_list_.lh_first, tmp_list_.lh_first);
+  if (tmp_list_.lh_first) {
+    tmp_list_.lh_first->entry.le_prev = &tmp_list_.lh_first;
+    EpollEvent event(0);
+    while (tmp_list_.lh_first != NULL) {
+      DCHECK_GT(ready_list_size_, 0);
+      CBAndEventMask* cb_and_mask = tmp_list_.lh_first;
+      RemoveFromReadyList(*cb_and_mask);
+
+      event.out_ready_mask = 0;
+      event.in_events =
+          cb_and_mask->events_asserted | cb_and_mask->events_to_fake;
+      // TODO(fenix): get rid of the two separate fields in cb_and_mask.
+      cb_and_mask->events_asserted = 0;
+      cb_and_mask->events_to_fake = 0;
+      {
+        // OnEvent() may call UnRegister, so we set in_use, here. Any
+        // UnRegister call will now simply set the cb to NULL instead of
+        // invalidating the cb_and_mask object (by deleting the object in the
+        // map to which cb_and_mask refers)
+        AutoReset<bool> in_use_guard(&(cb_and_mask->in_use), true);
+        cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event);
+      }
+
+      // Since OnEvent may have called UnregisterFD, we must check here that
+      // the callback is still valid. If it isn't, then UnregisterFD *was*
+      // called, and we should now get rid of the object.
+      if (cb_and_mask->cb == NULL) {
+        cb_map_.erase(*cb_and_mask);
+      } else if (event.out_ready_mask != 0) {
+        cb_and_mask->events_to_fake = event.out_ready_mask;
+        AddToReadyList(cb_and_mask);
+      }
+    }
+  }
+  DCHECK(tmp_list_.lh_first == NULL);
+}
+
+void SimpleEpollServer::CallAndReregisterAlarmEvents() {
+  int64_t now_in_us = recorded_now_in_us_;
+  DCHECK_NE(0, recorded_now_in_us_);
+
+  TimeToAlarmCBMap::iterator erase_it;
+
+  // execute alarms.
+  for (auto i = alarm_map_.begin(); i != alarm_map_.end();) {
+    if (i->first > now_in_us) {
+      break;
+    }
+    AlarmCB* cb = i->second;
+    // Execute the OnAlarm() only if we did not register
+    // it in this loop itself.
+    const bool added_in_this_round =
+        alarms_reregistered_and_should_be_skipped_.find(cb) !=
+        alarms_reregistered_and_should_be_skipped_.end();
+    if (added_in_this_round) {
+      ++i;
+      continue;
+    }
+    all_alarms_.erase(cb);
+    const int64_t new_timeout_time_in_us = cb->OnAlarm();
+
+    erase_it = i;
+    ++i;
+    alarm_map_.erase(erase_it);
+
+    if (new_timeout_time_in_us > 0) {
+      // We add to hash_set only if the new timeout is <= now_in_us.
+      // if timeout is > now_in_us then we have no fear that this alarm
+      // can be reexecuted in this loop, and hence we do not need to
+      // worry about a recursive loop.
+      EPOLL_DVLOG(3) << "Reregistering alarm "
+                     << " " << cb << " " << new_timeout_time_in_us << " "
+                     << now_in_us;
+      if (new_timeout_time_in_us <= now_in_us) {
+        alarms_reregistered_and_should_be_skipped_.insert(cb);
+      }
+      RegisterAlarm(new_timeout_time_in_us, cb);
+    }
+  }
+  alarms_reregistered_and_should_be_skipped_.clear();
+}
+
+EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) {}
+
+EpollAlarm::~EpollAlarm() { UnregisterIfRegistered(); }
+
+int64_t EpollAlarm::OnAlarm() {
+  registered_ = false;
+  return 0;
+}
+
+void EpollAlarm::OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
+                                SimpleEpollServer* eps) {
+  DCHECK_EQ(false, registered_);
+
+  token_ = token;
+  eps_ = eps;
+  registered_ = true;
+}
+
+void EpollAlarm::OnUnregistration() { registered_ = false; }
+
+void EpollAlarm::OnShutdown(SimpleEpollServer* /*eps*/) {
+  registered_ = false;
+  eps_ = NULL;
+}
+
+// If the alarm was registered, unregister it.
+void EpollAlarm::UnregisterIfRegistered() {
+  if (!registered_) {
+    return;
+  }
+
+  eps_->UnregisterAlarm(token_);
+}
+
+void EpollAlarm::ReregisterAlarm(int64_t timeout_time_in_us) {
+  DCHECK(registered_);
+  token_ = eps_->ReregisterAlarm(token_, timeout_time_in_us);
+}
+
+}  // namespace epoll_server
diff --git a/quiche/epoll_server/simple_epoll_server.h b/quiche/epoll_server/simple_epoll_server.h
new file mode 100644
index 0000000..bfe784b
--- /dev/null
+++ b/quiche/epoll_server/simple_epoll_server.h
@@ -0,0 +1,1052 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_EPOLL_SERVER_H_
+#define QUICHE_EPOLL_SERVER_H_
+
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+// #define EPOLL_SERVER_EVENT_TRACING 1
+//
+// Defining EPOLL_SERVER_EVENT_TRACING
+// causes code to exist which didn't before.
+// This code tracks each event generated by the epollserver,
+// as well as providing a per-fd-registered summary of
+// events. Note that enabling this code vastly slows
+// down operations, and uses substantially more
+// memory. For these reasons, it should only be enabled by developers doing
+// development at their workstations.
+//
+// A structure called 'EventRecorder' will exist when
+// the macro is defined. See the EventRecorder class interface
+// within the SimpleEpollServer class for more details.
+#ifdef EPOLL_SERVER_EVENT_TRACING
+#include <ostream>
+#endif
+
+#include <sys/epoll.h>
+
+#include "quiche/epoll_server/platform/api/epoll_export.h"
+#include "quiche/epoll_server/platform/api/epoll_logging.h"
+
+namespace epoll_server {
+
+class SimpleEpollServer;
+class EpollAlarmCallbackInterface;
+class ReadPipeCallback;
+
+struct EpollEvent {
+  EpollEvent(int events) : in_events(events), out_ready_mask(0) {}
+
+  int in_events;       // incoming events
+  int out_ready_mask;  // the new event mask for ready list (0 means don't
+                       // get on the ready list). This field is always
+                       // initialized to 0 when the event is passed to
+                       // OnEvent.
+};
+
+// Callbacks which go into SimpleEpollServers are expected to derive from this
+// class.
+class EpollCallbackInterface {
+ public:
+  // Summary:
+  //   Called when the callback is registered into a SimpleEpollServer.
+  // Args:
+  //   eps - the poll server into which this callback was registered
+  //   fd - the file descriptor which was registered
+  //   event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc)
+  //                which was registered (and will initially be used
+  //                in the epoll() calls)
+  virtual void OnRegistration(SimpleEpollServer* eps, int fd,
+                              int event_mask) = 0;
+
+  // Summary:
+  //   Called when the event_mask is modified (for a file-descriptor)
+  // Args:
+  //   fd - the file descriptor which was registered
+  //   event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc)
+  //                which was is now curren (and will be used
+  //                in subsequent epoll() calls)
+  virtual void OnModification(int fd, int event_mask) = 0;
+
+  // Summary:
+  //   Called whenever an event occurs on the file-descriptor.
+  //   This is where the bulk of processing is expected to occur.
+  // Args:
+  //   fd - the file descriptor which was registered
+  //   event - a struct that contains the event mask (composed of EPOLLIN,
+  //           EPOLLOUT, etc), a flag that indicates whether this is a true
+  //           epoll_wait event vs one from the ready list, and an output
+  //           parameter for OnEvent to inform the SimpleEpollServer whether to
+  //           put this fd on the ready list.
+  virtual void OnEvent(int fd, EpollEvent* event) = 0;
+
+  // Summary:
+  //   Called when the file-descriptor is unregistered from the poll-server.
+  // Args:
+  //   fd - the file descriptor which was registered, and of this call, is now
+  //        unregistered.
+  //   replaced - If true, this callback is being replaced by another, otherwise
+  //              it is simply being removed.
+  virtual void OnUnregistration(int fd, bool replaced) = 0;
+
+  // Summary:
+  //   Called when the epoll server is shutting down.  This is different from
+  //   OnUnregistration because the subclass may want to clean up memory.
+  //   This is called in leiu of OnUnregistration.
+  // Args:
+  //  fd - the file descriptor which was registered.
+  virtual void OnShutdown(SimpleEpollServer* eps, int fd) = 0;
+
+  // Summary:
+  //   Returns a name describing the class for use in debug/error reporting.
+  virtual std::string Name() const = 0;
+
+  virtual ~EpollCallbackInterface() {}
+
+ protected:
+  EpollCallbackInterface() {}
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+class EPOLL_EXPORT_PRIVATE SimpleEpollServer {
+ public:
+  typedef EpollAlarmCallbackInterface AlarmCB;
+  typedef EpollCallbackInterface CB;
+
+  typedef std::multimap<int64_t, AlarmCB*> TimeToAlarmCBMap;
+  typedef TimeToAlarmCBMap::iterator AlarmRegToken;
+
+  // Summary:
+  //   Constructor:
+  //    By default, we don't wait any amount of time for events, and
+  //    we suggest to the epoll-system that we're going to use on-the-order
+  //    of 1024 FDs.
+  SimpleEpollServer();
+
+  SimpleEpollServer(const SimpleEpollServer&) = delete;
+  SimpleEpollServer operator=(const SimpleEpollServer&) = delete;
+
+  ////////////////////////////////////////
+
+  // Destructor
+  virtual ~SimpleEpollServer();
+
+  ////////////////////////////////////////
+
+  // Summary
+  //   Register a callback to be called whenever an event contained
+  //   in the set of events included in event_mask occurs on the
+  //   file-descriptor 'fd'
+  //
+  //   Note that only one callback is allowed to be registered for
+  //   any specific file-decriptor.
+  //
+  //   If a callback is registered for a file-descriptor which has already
+  //   been registered, then the previous callback is unregistered with
+  //   the 'replaced' flag set to true. I.e. the previous callback's
+  //   OnUnregistration() function is called like so:
+  //      OnUnregistration(fd, true);
+  //
+  //  The epoll server does NOT take on ownership of the callback: the callback
+  //  creator is responsible for managing that memory.
+  //
+  // Args:
+  //   fd - a valid file-descriptor
+  //   cb - an instance of a subclass of EpollCallbackInterface
+  //   event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating
+  //                the events for which the callback would like to be
+  //                called.
+  virtual void RegisterFD(int fd, CB* cb, int event_mask);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   A shortcut for RegisterFD which sets things up such that the
+  //   callback is called when 'fd' is available for writing.
+  // Args:
+  //   fd - a valid file-descriptor
+  //   cb - an instance of a subclass of EpollCallbackInterface
+  virtual void RegisterFDForWrite(int fd, CB* cb);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   A shortcut for RegisterFD which sets things up such that the
+  //   callback is called when 'fd' is available for reading or writing.
+  // Args:
+  //   fd - a valid file-descriptor
+  //   cb - an instance of a subclass of EpollCallbackInterface
+  virtual void RegisterFDForReadWrite(int fd, CB* cb);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   A shortcut for RegisterFD which sets things up such that the
+  //   callback is called when 'fd' is available for reading.
+  // Args:
+  //   fd - a valid file-descriptor
+  //   cb - an instance of a subclass of EpollCallbackInterface
+  virtual void RegisterFDForRead(int fd, CB* cb);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Removes the FD and the associated callback from the pollserver.
+  //   If the callback is registered with other FDs, they will continue
+  //   to be processed using the callback without modification.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the file-descriptor which should no-longer be monitored.
+  virtual void UnregisterFD(int fd);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modifies the event mask for the file-descriptor, replacing
+  //   the old event_mask with the new one specified here.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the fd whose event mask should be modified.
+  //   event_mask - the new event mask.
+  virtual void ModifyCallback(int fd, int event_mask);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modifies the event mask for the file-descriptor such that we
+  //   no longer request events when 'fd' is readable.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the fd whose event mask should be modified.
+  virtual void StopRead(int fd);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modifies the event mask for the file-descriptor such that we
+  //   request events when 'fd' is readable.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the fd whose event mask should be modified.
+  virtual void StartRead(int fd);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modifies the event mask for the file-descriptor such that we
+  //   no longer request events when 'fd' is writable.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the fd whose event mask should be modified.
+  virtual void StopWrite(int fd);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modifies the event mask for the file-descriptor such that we
+  //   request events when 'fd' is writable.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the fd whose event mask should be modified.
+  virtual void StartWrite(int fd);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Looks up the callback associated with the file-descriptor 'fd'.
+  //   If a callback is associated with this file-descriptor, then
+  //   it's OnEvent() method is called with the file-descriptor 'fd',
+  //   and event_mask 'event_mask'
+  //
+  //   If no callback is registered for this file-descriptor, nothing
+  //   will happen as a result of this call.
+  //
+  //   This function is used internally by the SimpleEpollServer, but is
+  //   available publicly so that events might be 'faked'. Calling
+  //   this function with an fd and event_mask is equivalent (as far
+  //   as the callback is concerned) to having a real event generated
+  //   by epoll (except, of course, that read(), etc won't necessarily
+  //   be able to read anything)
+  // Args:
+  //   fd - the file-descriptor on which an event has occurred.
+  //   event_mask - a bitmask representing the events which have occurred
+  //                on/for this fd. This bitmask is composed of
+  //                POLLIN, POLLOUT, etc.
+  //
+  void HandleEvent(int fd, int event_mask);
+
+  // Summary:
+  //   Call this when you want the pollserver to
+  //   wait for events and execute the callbacks associated with
+  //   the file-descriptors on which those events have occurred.
+  //   Depending on the value of timeout_in_us_, this may or may
+  //   not return immediately. Please reference the set_timeout()
+  //   function for the specific behaviour.
+  virtual void WaitForEventsAndExecuteCallbacks();
+
+  // Summary:
+  //   When an fd is registered to use edge trigger notification, the ready
+  //   list can be used to simulate level trigger semantics. Edge trigger
+  //   registration doesn't send an initial event, and only rising edge (going
+  //   from blocked to unblocked) events are sent. A callback can put itself on
+  //   the ready list by calling SetFDReady() after calling RegisterFD(). The
+  //   OnEvent method of all callbacks associated with the fds on the ready
+  //   list will be called immediately after processing the events returned by
+  //   epoll_wait(). The fd is removed from the ready list before the
+  //   callback's OnEvent() method is invoked. To stay on the ready list, the
+  //   OnEvent() (or some function in that call chain) must call SetFDReady
+  //   again. When a fd is unregistered using UnregisterFD(), the fd is
+  //   automatically removed from the ready list.
+  //
+  //   When the callback for a edge triggered fd hits the falling edge (about
+  //   to block, either because of it got an EAGAIN, or had a short read/write
+  //   operation), it should remove itself from the ready list using
+  //   SetFDNotReady() (since OnEvent cannot distinguish between invocation
+  //   from the ready list vs from a normal epoll event). All four ready list
+  //   methods are safe to be called  within the context of the callbacks.
+  //
+  //   Since the ready list invokes EpollCallbackInterface::OnEvent, only fds
+  //   that are registered with the SimpleEpollServer will be put on the ready
+  //   list. SetFDReady() and SetFDNotReady() will do nothing if the
+  //   SimpleEpollServer doesn't know about the fd passed in.
+  //
+  //   Since the ready list cannot reliably determine proper set of events
+  //   which should be sent to the callback, SetFDReady() requests the caller
+  //   to provide the ready list with the event mask, which will be used later
+  //   when OnEvent() is invoked by the ready list. Hence, the event_mask
+  //   passedto SetFDReady() does not affect the actual epoll registration of
+  //   the fd with the kernel. If a fd is already put on the ready list, and
+  //   SetFDReady() is called again for that fd with a different event_mask,
+  //   the event_mask will be updated.
+  virtual void SetFDReady(int fd, int events_to_fake);
+
+  virtual void SetFDNotReady(int fd);
+
+  // Summary:
+  //   IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as
+  //   debugging tools and for writing unit tests.
+  //   ISFDReady() returns whether a fd is in the ready list.
+  //   ReadyListSize() returns the number of fds on the ready list.
+  //   VerifyReadyList() checks the consistency of internal data structure. It
+  //   will CHECK if it finds an error.
+  virtual bool IsFDReady(int fd) const;
+
+  size_t ReadyListSize() const { return ready_list_size_; }
+
+  void VerifyReadyList() const;
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Registers an alarm 'ac' to go off at time 'timeout_time_in_us'.
+  //   If the callback returns a positive number from its OnAlarm() function,
+  //   then the callback will be re-registered at that time, else the alarm
+  //   owner is responsible for freeing up memory.
+  //
+  //   Important: A give AlarmCB* can not be registered again if it is already
+  //    registered. If a user wants to register a callback again it should first
+  //    unregister the previous callback before calling RegisterAlarm again.
+  // Args:
+  //   timeout_time_in_us - the absolute time at which the alarm should go off
+  //   ac - the alarm which will be called.
+  virtual void RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac);
+
+  // Summary:
+  //   Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() +
+  //   delta_in_us). While this is somewhat less accurate (see the description
+  //   for ApproximateNowInUs() to see how 'approximate'), the error is never
+  //   worse than the amount of time it takes to process all events in one
+  //   WaitForEvents.  As with 'RegisterAlarm()', if the callback returns a
+  //   positive number from its OnAlarm() function, then the callback will be
+  //   re-registered at that time, else the alarm owner is responsible for
+  //   freeing up memory.
+  //   Note that this function is purely a convienence. The
+  //   same thing may be accomplished by using RegisterAlarm with
+  //   ApproximateNowInUs() directly.
+  //
+  //   Important: A give AlarmCB* can not be registered again if it is already
+  //    registered. If a user wants to register a callback again it should first
+  //    unregister the previous callback before calling RegisterAlarm again.
+  // Args:
+  //   delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at
+  //                 which point the alarm should go off.
+  //   ac - the alarm which will be called.
+  void RegisterAlarmApproximateDelta(int64_t delta_in_us, AlarmCB* ac) {
+    RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac);
+  }
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Unregister  the alarm referred to by iterator_token; Callers should
+  //   be warned that a token may have become already invalid when OnAlarm()
+  //   is called, was unregistered, or OnShutdown was called on that alarm.
+  // Args:
+  //    iterator_token - iterator to the alarm callback to unregister.
+  virtual void UnregisterAlarm(
+      const SimpleEpollServer::AlarmRegToken& iterator_token);
+
+  virtual SimpleEpollServer::AlarmRegToken ReregisterAlarm(
+      SimpleEpollServer::AlarmRegToken iterator_token,
+      int64_t timeout_time_in_us);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   returns the number of file-descriptors registered in this
+  //   SimpleEpollServer.
+  // Returns:
+  //   number of FDs registered (discounting the internal pipe used for Wake)
+  virtual int NumFDsRegistered() const;
+
+  // Summary:
+  //   Force the epoll server to wake up (by writing to an internal pipe).
+  virtual void Wake();
+
+  // Summary:
+  //   Wrapper around WallTimer's NowInUsec.  We do this so that we can test
+  //   SimpleEpollServer without using the system clock (and can avoid the
+  //   flakiness that would ensue)
+  // Returns:
+  //   the current time as number of microseconds since the Unix epoch.
+  virtual int64_t NowInUsec() const;
+
+  // Summary:
+  //   Since calling NowInUsec() many thousands of times per
+  //   WaitForEventsAndExecuteCallbacks function call is, to say the least,
+  //   inefficient, we allow users to use an approximate time instead. The
+  //   time returned from this function is as accurate as NowInUsec() when
+  //   WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's
+  //   callstack.
+  //   However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then
+  //   this function returns the time at which the
+  //   WaitForEventsAndExecuteCallbacks function started to process events or
+  //   alarms.
+  //
+  //   Essentially, this function makes available a fast and mostly accurate
+  //   mechanism for getting the time for any function handling an event or
+  //   alarm. When functions which are not handling callbacks or alarms call
+  //   this function, they get the slow and "absolutely" accurate time.
+  //
+  //   Users should be encouraged to use this function.
+  // Returns:
+  //   the "approximate" current time as number of microseconds since the Unix
+  //   epoch.
+  virtual int64_t ApproximateNowInUsec() const;
+
+  static std::string EventMaskToString(int event_mask);
+
+  // Summary:
+  //   Logs the state of the epoll server with EPOLL_LOG(ERROR).
+  void LogStateOnCrash();
+
+  // Summary:
+  //   Set the timeout to the value specified.
+  //   If the timeout is set to a negative number,
+  //      WaitForEventsAndExecuteCallbacks() will only return when an event has
+  //      occurred
+  //   If the timeout is set to zero,
+  //      WaitForEventsAndExecuteCallbacks() will return immediately
+  //   If the timeout is set to a positive number,
+  //      WaitForEventsAndExecuteCallbacks() will return when an event has
+  //      occurred, or when timeout_in_us microseconds has elapsed, whichever
+  //      is first.
+  //  Args:
+  //    timeout_in_us - value specified depending on behaviour desired.
+  //                    See above.
+  void set_timeout_in_us(int64_t timeout_in_us) {
+    timeout_in_us_ = timeout_in_us;
+  }
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Accessor for the current value of timeout_in_us.
+  int timeout_in_us_for_test() const { return timeout_in_us_; }
+
+  // Summary:
+  // Returns true when the SimpleEpollServer() is being destroyed.
+  bool in_shutdown() const { return in_shutdown_; }
+  bool ShutdownCalled() const { return in_shutdown(); }
+
+  // Compatibility stub.
+  void Shutdown() {}
+
+  // Summary:
+  //   A function for implementing the ready list. It invokes OnEvent for each
+  //   of the fd in the ready list, and takes care of adding them back to the
+  //   ready list if the callback requests it (by checking that out_ready_mask
+  //   is non-zero).
+  void CallReadyListCallbacks();
+
+  int64_t LastDelayInUsec() const { return last_delay_in_usec_; }
+
+ protected:
+  virtual void SetNonblocking(int fd);
+
+  // This exists here so that we can override this function in unittests
+  // in order to make effective mock SimpleEpollServer objects.
+  virtual int epoll_wait_impl(int epfd, struct epoll_event* events,
+                              int max_events, int timeout_in_ms);
+
+  // this struct is used internally, and is never used by anything external
+  // to this class. Some of its members are declared mutable to get around the
+  // restriction imposed by hash_set. Since hash_set knows nothing about the
+  // objects it stores, it has to assume that every bit of the object is used
+  // in the hash function and equal_to comparison. Thus hash_set::iterator is a
+  // const iterator. In this case, the only thing that must stay constant is
+  // fd. Everything else are just along for the ride and changing them doesn't
+  // compromise the hash_set integrity.
+  struct CBAndEventMask {
+    CBAndEventMask()
+        : cb(NULL),
+          fd(-1),
+          event_mask(0),
+          events_asserted(0),
+          events_to_fake(0),
+          in_use(false) {
+      entry.le_next = NULL;
+      entry.le_prev = NULL;
+    }
+
+    CBAndEventMask(EpollCallbackInterface* cb, int event_mask, int fd)
+        : cb(cb),
+          fd(fd),
+          event_mask(event_mask),
+          events_asserted(0),
+          events_to_fake(0),
+          in_use(false) {
+      entry.le_next = NULL;
+      entry.le_prev = NULL;
+    }
+
+    // Required operator for hash_set. Normally operator== should be a free
+    // standing function. However, since CBAndEventMask is a protected type and
+    // it will never be a base class, it makes no difference.
+    bool operator==(const CBAndEventMask& cb_and_mask) const {
+      return fd == cb_and_mask.fd;
+    }
+    // A callback. If the fd is unregistered inside the callchain of OnEvent,
+    // the cb will be set to NULL.
+    mutable EpollCallbackInterface* cb;
+
+    mutable LIST_ENTRY(CBAndEventMask) entry;
+    // file descriptor registered with the epoll server.
+    int fd;
+    // the current event_mask registered for this callback.
+    mutable int event_mask;
+    // the event_mask that was returned by epoll
+    mutable int events_asserted;
+    // the event_mask for the ready list to use to call OnEvent.
+    mutable int events_to_fake;
+    // toggle around calls to OnEvent to tell UnregisterFD to not erase the
+    // iterator because HandleEvent is using it.
+    mutable bool in_use;
+  };
+
+  // Custom hash function to be used by hash_set.
+  struct CBAndEventMaskHash {
+    size_t operator()(const CBAndEventMask& cb_and_eventmask) const {
+      return static_cast<size_t>(cb_and_eventmask.fd);
+    }
+  };
+
+  using FDToCBMap = std::unordered_set<CBAndEventMask, CBAndEventMaskHash>;
+
+  // the following four functions are OS-specific, and are likely
+  // to be changed in a subclass if the poll/select method is changed
+  // from epoll.
+
+  // Summary:
+  //   Deletes a file-descriptor from the set of FDs that should be
+  //   monitored with epoll.
+  //   Note that this only deals with modifying data relating -directly-
+  //   with the epoll call-- it does not modify any data within the
+  //   epoll_server.
+  // Args:
+  //   fd - the file descriptor to-be-removed from the monitoring set
+  virtual void DelFD(int fd) const;
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Adds a file-descriptor to the set of FDs that should be
+  //   monitored with epoll.
+  //   Note that this only deals with modifying data relating -directly-
+  //   with the epoll call.
+  // Args:
+  //   fd - the file descriptor to-be-added to the monitoring set
+  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
+  //                 OR'd together) which will be associated with this
+  //                 FD initially.
+  virtual void AddFD(int fd, int event_mask) const;
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modifies a file-descriptor in the set of FDs that should be
+  //   monitored with epoll.
+  //   Note that this only deals with modifying data relating -directly-
+  //   with the epoll call.
+  // Args:
+  //   fd - the file descriptor to-be-added to the monitoring set
+  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
+  //                 OR'd together) which will be associated with this
+  //                 FD after this call.
+  virtual void ModFD(int fd, int event_mask) const;
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Modified the event mask associated with an FD in the set of
+  //   data needed by epoll.
+  //   Events are removed before they are added, thus, if ~0 is put
+  //   in 'remove_event', whatever is put in 'add_event' will be
+  //   the new event mask.
+  //   If the file-descriptor specified is not registered in the
+  //   epoll_server, then nothing happens as a result of this call.
+  // Args:
+  //   fd - the file descriptor whose event mask is to be modified
+  //   remove_event - the events which are to be removed from the current
+  //                  event_mask
+  //   add_event - the events which are to be added to the current event_mask
+  //
+  //
+  virtual void ModifyFD(int fd, int remove_event, int add_event);
+
+  ////////////////////////////////////////
+
+  // Summary:
+  //   Waits for events, and calls HandleEvents() for each
+  //   fd, event pair discovered to possibly have an event.
+  //   Note that a callback (B) may get a spurious event if
+  //   another callback (A) has closed a file-descriptor N, and
+  //   the callback (B) has a newly opened file-descriptor, which
+  //   also happens to be N.
+  virtual void WaitForEventsAndCallHandleEvents(int64_t timeout_in_us,
+                                                struct epoll_event events[],
+                                                int events_size);
+
+  // Summary:
+  //   An internal function for implementing the ready list. It adds a fd's
+  //   CBAndEventMask to the ready list. If the fd is already on the ready
+  //   list, it is a no-op.
+  void AddToReadyList(CBAndEventMask* cb_and_mask);
+
+  // Summary:
+  //   An internal function for implementing the ready list. It remove a fd's
+  //   CBAndEventMask from the ready list. If the fd is not on the ready list,
+  //   it is a no-op.
+  void RemoveFromReadyList(const CBAndEventMask& cb_and_mask);
+
+  // Summary:
+  // Calls any pending alarms that should go off and reregisters them if they
+  // were recurring.
+  virtual void CallAndReregisterAlarmEvents();
+
+  // The file-descriptor created for epolling
+  int epoll_fd_;
+
+  // The mapping of file-descriptor to CBAndEventMasks
+  FDToCBMap cb_map_;
+
+  // Custom hash function to be used by hash_set.
+  struct AlarmCBHash {
+    size_t operator()(AlarmCB* const& p) const {
+      return reinterpret_cast<size_t>(p);
+    }
+  };
+
+  // TODO(sushantj): Having this hash_set is avoidable. We currently have it
+  // only so that we can enforce stringent checks that a caller can not register
+  // the same alarm twice. One option is to have an implementation in which
+  // this hash_set is used only in the debug mode.
+  using AlarmCBMap = std::unordered_set<AlarmCB*, AlarmCBHash>;
+  AlarmCBMap all_alarms_;
+
+  TimeToAlarmCBMap alarm_map_;
+
+  // The amount of time in microseconds that we'll wait before returning
+  // from the WaitForEventsAndExecuteCallbacks() function.
+  // If this is positive, wait that many microseconds.
+  // If this is negative, wait forever, or for the first event that occurs
+  // If this is zero, never wait for an event.
+  int64_t timeout_in_us_;
+
+  // This is nonzero only after the invocation of epoll_wait_impl within
+  // WaitForEventsAndCallHandleEvents and before the function
+  // WaitForEventsAndExecuteCallbacks returns.  At all other times, this is
+  // zero. This enables us to have relatively accurate time returned from the
+  // ApproximateNowInUs() function. See that function for more details.
+  int64_t recorded_now_in_us_;
+
+  // This is used to implement CallAndReregisterAlarmEvents. This stores
+  // all alarms that were reregistered because OnAlarm() returned a
+  // value > 0 and the time at which they should be executed is less that
+  // the current time.  By storing such alarms in this map we ensure
+  // that while calling CallAndReregisterAlarmEvents we do not call
+  // OnAlarm on any alarm in this set. This ensures that we do not
+  // go in an infinite loop.
+  AlarmCBMap alarms_reregistered_and_should_be_skipped_;
+
+  LIST_HEAD(ReadyList, CBAndEventMask) ready_list_;
+  LIST_HEAD(TmpList, CBAndEventMask) tmp_list_;
+  int ready_list_size_;
+  // TODO(alyssar): make this into something that scales up.
+  static const int events_size_ = 256;
+  struct epoll_event events_[256];
+
+#ifdef EPOLL_SERVER_EVENT_TRACING
+  struct EventRecorder {
+   public:
+    EventRecorder() : num_records_(0), record_threshold_(10000) {}
+
+    ~EventRecorder() { Clear(); }
+
+    // When a number of events equals the record threshold,
+    // the collected data summary for all FDs will be written
+    // to EPOLL_LOG(INFO). Note that this does not include the
+    // individual events (if you'reinterested in those, you'll
+    // have to get at them programmatically).
+    // After any such flushing to EPOLL_LOG(INFO) all events will
+    // be cleared.
+    // Note that the definition of an 'event' is a bit 'hazy',
+    // as it includes the 'Unregistration' event, and perhaps
+    // others.
+    void set_record_threshold(int64_t new_threshold) {
+      record_threshold_ = new_threshold;
+    }
+
+    void Clear() {
+      for (int i = 0; i < debug_events_.size(); ++i) {
+        delete debug_events_[i];
+      }
+      debug_events_.clear();
+      unregistered_fds_.clear();
+      event_counts_.clear();
+    }
+
+    void MaybeRecordAndClear() {
+      ++num_records_;
+      if ((num_records_ > record_threshold_) && (record_threshold_ > 0)) {
+        EPOLL_LOG(INFO) << "\n" << *this;
+        num_records_ = 0;
+        Clear();
+      }
+    }
+
+    void RecordFDMaskEvent(int fd, int mask, const char* function) {
+      FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function);
+      debug_events_.push_back(fdmo);
+      MaybeRecordAndClear();
+    }
+
+    void RecordEpollWaitEvent(int timeout_in_ms, int num_events_generated) {
+      EpollWaitOutput* ewo =
+          new EpollWaitOutput(timeout_in_ms, num_events_generated);
+      debug_events_.push_back(ewo);
+      MaybeRecordAndClear();
+    }
+
+    void RecordEpollEvent(int fd, int event_mask) {
+      Events& events_for_fd = event_counts_[fd];
+      events_for_fd.AssignFromMask(event_mask);
+      MaybeRecordAndClear();
+    }
+
+    friend ostream& operator<<(ostream& os, const EventRecorder& er) {
+      for (int i = 0; i < er.unregistered_fds_.size(); ++i) {
+        os << "fd: " << er.unregistered_fds_[i] << "\n";
+        os << er.unregistered_fds_[i];
+      }
+      for (EventCountsMap::const_iterator i = er.event_counts_.begin();
+           i != er.event_counts_.end(); ++i) {
+        os << "fd: " << i->first << "\n";
+        os << i->second;
+      }
+      for (int i = 0; i < er.debug_events_.size(); ++i) {
+        os << *(er.debug_events_[i]) << "\n";
+      }
+      return os;
+    }
+
+    void RecordUnregistration(int fd) {
+      EventCountsMap::iterator i = event_counts_.find(fd);
+      if (i != event_counts_.end()) {
+        unregistered_fds_.push_back(i->second);
+        event_counts_.erase(i);
+      }
+      MaybeRecordAndClear();
+    }
+
+   protected:
+    class DebugOutput {
+     public:
+      friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) {
+        debug_output.OutputToStream(os);
+        return os;
+      }
+      virtual void OutputToStream(ostream* os) const = 0;
+      virtual ~DebugOutput() {}
+    };
+
+    class FDMaskOutput : public DebugOutput {
+     public:
+      FDMaskOutput(int fd, int mask, const char* function)
+          : fd_(fd), mask_(mask), function_(function) {}
+      virtual void OutputToStream(ostream* os) const {
+        (*os) << "func: " << function_ << "\tfd: " << fd_;
+        if (mask_ != 0) {
+          (*os) << "\tmask: " << EventMaskToString(mask_);
+        }
+      }
+      int fd_;
+      int mask_;
+      const char* function_;
+    };
+
+    class EpollWaitOutput : public DebugOutput {
+     public:
+      EpollWaitOutput(int timeout_in_ms, int num_events_generated)
+          : timeout_in_ms_(timeout_in_ms),
+            num_events_generated_(num_events_generated) {}
+      virtual void OutputToStream(ostream* os) const {
+        (*os) << "timeout_in_ms: " << timeout_in_ms_
+              << "\tnum_events_generated: " << num_events_generated_;
+      }
+
+     protected:
+      int timeout_in_ms_;
+      int num_events_generated_;
+    };
+
+    struct Events {
+      Events()
+          : epoll_in(0),
+            epoll_pri(0),
+            epoll_out(0),
+            epoll_rdnorm(0),
+            epoll_rdband(0),
+            epoll_wrnorm(0),
+            epoll_wrband(0),
+            epoll_msg(0),
+            epoll_err(0),
+            epoll_hup(0),
+            epoll_oneshot(0),
+            epoll_et(0) {}
+
+      void AssignFromMask(int event_mask) {
+        if (event_mask & EPOLLIN) ++epoll_in;
+        if (event_mask & EPOLLPRI) ++epoll_pri;
+        if (event_mask & EPOLLOUT) ++epoll_out;
+        if (event_mask & EPOLLRDNORM) ++epoll_rdnorm;
+        if (event_mask & EPOLLRDBAND) ++epoll_rdband;
+        if (event_mask & EPOLLWRNORM) ++epoll_wrnorm;
+        if (event_mask & EPOLLWRBAND) ++epoll_wrband;
+        if (event_mask & EPOLLMSG) ++epoll_msg;
+        if (event_mask & EPOLLERR) ++epoll_err;
+        if (event_mask & EPOLLHUP) ++epoll_hup;
+        if (event_mask & EPOLLONESHOT) ++epoll_oneshot;
+        if (event_mask & EPOLLET) ++epoll_et;
+      }
+
+      friend ostream& operator<<(ostream& os, const Events& ev) {
+        if (ev.epoll_in) {
+          os << "\t      EPOLLIN: " << ev.epoll_in << "\n";
+        }
+        if (ev.epoll_pri) {
+          os << "\t     EPOLLPRI: " << ev.epoll_pri << "\n";
+        }
+        if (ev.epoll_out) {
+          os << "\t     EPOLLOUT: " << ev.epoll_out << "\n";
+        }
+        if (ev.epoll_rdnorm) {
+          os << "\t  EPOLLRDNORM: " << ev.epoll_rdnorm << "\n";
+        }
+        if (ev.epoll_rdband) {
+          os << "\t  EPOLLRDBAND: " << ev.epoll_rdband << "\n";
+        }
+        if (ev.epoll_wrnorm) {
+          os << "\t  EPOLLWRNORM: " << ev.epoll_wrnorm << "\n";
+        }
+        if (ev.epoll_wrband) {
+          os << "\t  EPOLLWRBAND: " << ev.epoll_wrband << "\n";
+        }
+        if (ev.epoll_msg) {
+          os << "\t     EPOLLMSG: " << ev.epoll_msg << "\n";
+        }
+        if (ev.epoll_err) {
+          os << "\t     EPOLLERR: " << ev.epoll_err << "\n";
+        }
+        if (ev.epoll_hup) {
+          os << "\t     EPOLLHUP: " << ev.epoll_hup << "\n";
+        }
+        if (ev.epoll_oneshot) {
+          os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n";
+        }
+        if (ev.epoll_et) {
+          os << "\t      EPOLLET: " << ev.epoll_et << "\n";
+        }
+        return os;
+      }
+
+      unsigned int epoll_in;
+      unsigned int epoll_pri;
+      unsigned int epoll_out;
+      unsigned int epoll_rdnorm;
+      unsigned int epoll_rdband;
+      unsigned int epoll_wrnorm;
+      unsigned int epoll_wrband;
+      unsigned int epoll_msg;
+      unsigned int epoll_err;
+      unsigned int epoll_hup;
+      unsigned int epoll_oneshot;
+      unsigned int epoll_et;
+    };
+
+    std::vector<DebugOutput*> debug_events_;
+    std::vector<Events> unregistered_fds_;
+    using EventCountsMap = std::unordered_map<int, Events>;
+    EventCountsMap event_counts_;
+    int64_t num_records_;
+    int64_t record_threshold_;
+  };
+
+  void ClearEventRecords() { event_recorder_.Clear(); }
+  void WriteEventRecords(ostream* os) const { (*os) << event_recorder_; }
+
+  mutable EventRecorder event_recorder_;
+
+#endif
+
+ private:
+  // Helper functions used in the destructor.
+  void CleanupFDToCBMap();
+  void CleanupTimeToAlarmCBMap();
+
+  // The callback registered to the fds below.  As the purpose of their
+  // registration is to wake the epoll server it just clears the pipe and
+  // returns.
+  std::unique_ptr<ReadPipeCallback> wake_cb_;
+
+  // A pipe owned by the epoll server.  The server will be registered to listen
+  // on read_fd_ and can be woken by Wake() which writes to write_fd_.
+  int read_fd_;
+  int write_fd_;
+
+  // This boolean is checked to see if it is false at the top of the
+  // WaitForEventsAndExecuteCallbacks function. If not, then it either returns
+  // without doing work, and logs to ERROR, or aborts the program (in
+  // DEBUG mode). If so, then it sets the bool to true, does work, and
+  // sets it back to false when done. This catches unwanted recursion.
+  bool in_wait_for_events_and_execute_callbacks_;
+
+  // Returns true when the SimpleEpollServer() is being destroyed.
+  bool in_shutdown_;
+  int64_t last_delay_in_usec_;
+};
+
+class EpollAlarmCallbackInterface {
+ public:
+  // Summary:
+  //   Called when an alarm times out. Invalidates an AlarmRegToken.
+  //   WARNING: If a token was saved to refer to an alarm callback, OnAlarm must
+  //   delete it, as the reference is no longer valid.
+  // Returns:
+  //   the unix time (in microseconds) at which this alarm should be signaled
+  //   again, or 0 if the alarm should be removed.
+  virtual int64_t OnAlarm() = 0;
+
+  // Summary:
+  //   Called when the an alarm is registered. Invalidates an AlarmRegToken.
+  // Args:
+  //   token: the iterator to the alarm registered in the alarm map.
+  //   WARNING: this token becomes invalid when the alarm fires, is
+  //   unregistered, or OnShutdown is called on that alarm.
+  //   eps: the epoll server the alarm is registered with.
+  virtual void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
+                              SimpleEpollServer* eps) = 0;
+
+  // Summary:
+  //   Called when the an alarm is unregistered.
+  //   WARNING: It is not valid to unregister a callback and then use the token
+  //   that was saved to refer to the callback.
+  virtual void OnUnregistration() = 0;
+
+  // Summary:
+  //   Called when the epoll server is shutting down.
+  //   Invalidates the AlarmRegToken that was given when this alarm was
+  //   registered.
+  virtual void OnShutdown(SimpleEpollServer* eps) = 0;
+
+  virtual ~EpollAlarmCallbackInterface() {}
+
+ protected:
+  EpollAlarmCallbackInterface() {}
+};
+
+// A simple alarm which unregisters itself on destruction.
+//
+// PLEASE NOTE:
+// Any classes overriding these functions must either call the implementation
+// of the parent class, or is must otherwise make sure that the 'registered_'
+// boolean and the token, 'token_', are updated appropriately.
+class EPOLL_EXPORT_PRIVATE EpollAlarm : public EpollAlarmCallbackInterface {
+ public:
+  EpollAlarm();
+
+  ~EpollAlarm() override;
+
+  // Marks the alarm as unregistered and returns 0.  The return value may be
+  // safely ignored by subclasses.
+  int64_t OnAlarm() override;
+
+  // Marks the alarm as registered, and stores the token.
+  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
+                      SimpleEpollServer* eps) override;
+
+  // Marks the alarm as unregistered.
+  void OnUnregistration() override;
+
+  // Marks the alarm as unregistered.
+  void OnShutdown(SimpleEpollServer* eps) override;
+
+  // If the alarm was registered, unregister it.
+  void UnregisterIfRegistered();
+
+  // Reregisters the alarm at specified time.
+  void ReregisterAlarm(int64_t timeout_time_in_us);
+
+  bool registered() const { return registered_; }
+
+  const SimpleEpollServer* eps() const { return eps_; }
+
+ private:
+  SimpleEpollServer::AlarmRegToken token_;
+  SimpleEpollServer* eps_;
+  bool registered_;
+};
+
+}  // namespace epoll_server
+
+#endif  // QUICHE_EPOLL_SERVER_H_
diff --git a/quiche/epoll_server/simple_epoll_server_test.cc b/quiche/epoll_server/simple_epoll_server_test.cc
new file mode 100644
index 0000000..d684521
--- /dev/null
+++ b/quiche/epoll_server/simple_epoll_server_test.cc
@@ -0,0 +1,2522 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Epoll tests which determine that the right things happen in the right order.
+// Also lots of testing of individual functions.
+
+#include "quiche/epoll_server/simple_epoll_server.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "quiche/epoll_server/fake_simple_epoll_server.h"
+#include "quiche/epoll_server/platform/api/epoll_address_test_utils.h"
+#include "quiche/epoll_server/platform/api/epoll_expect_bug.h"
+#include "quiche/epoll_server/platform/api/epoll_ptr_util.h"
+#include "quiche/epoll_server/platform/api/epoll_test.h"
+#include "quiche/epoll_server/platform/api/epoll_thread.h"
+#include "quiche/epoll_server/platform/api/epoll_time.h"
+
+namespace epoll_server {
+
+namespace test {
+
+namespace {
+
+const int kPageSize = 4096;
+const int kMaxBufLen = 10000;
+
+// These are used to record what is happening.
+enum {
+  CREATION,
+  REGISTRATION,
+  MODIFICATION,
+  EVENT,
+  UNREGISTRATION,
+  SHUTDOWN,
+  DESTRUCTION
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+struct RecordEntry {
+  RecordEntry() : time(0), instance(nullptr), event_type(0), fd(0), data(0) {}
+
+  RecordEntry(int64_t time, void* instance, int event_type, int fd, int data)
+      : time(time),
+        instance(instance),
+        event_type(event_type),
+        fd(fd),
+        data(data) {}
+
+  int64_t time;
+  void* instance;
+  int event_type;
+  int fd;
+  int data;
+
+  bool IsEqual(const RecordEntry *entry) const {
+    bool retval = true;
+
+    if (instance  !=  entry->instance) {
+      retval = false;
+      EPOLL_LOG(INFO) << " instance (" << instance << ") != entry->instance("
+                      << entry->instance << ")";
+    }
+    if (event_type != entry->event_type) {
+      retval = false;
+      EPOLL_LOG(INFO) << " event_type (" << event_type
+                      << ") != entry->event_type(" << entry->event_type << ")";
+    }
+    if ( fd != entry->fd ) {
+      retval = false;
+      EPOLL_LOG(INFO) << " fd (" << fd << ") != entry->fd (" << entry->fd
+                      << ")";
+    }
+    if (data != entry->data) {
+      retval = false;
+      EPOLL_LOG(INFO) << " data (" << data << ") != entry->data(" << entry->data
+                      << ")";
+    }
+    return retval;
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+class Recorder {
+ public:
+  void Record(void* instance, int event_type, int fd, int data) {
+    records_.push_back(
+        RecordEntry(WallTimeNowInUsec(), instance, event_type, fd, data));
+  }
+
+  const std::vector<RecordEntry> *records() const { return &records_; }
+
+  bool IsEqual(const Recorder *recorder) const {
+    const std::vector<RecordEntry> *records = recorder->records();
+
+     if (records_.size() != records->size()) {
+       EPOLL_LOG(INFO) << "records_.size() (" << records_.size()
+                       << ") != records->size() (" << records->size() << ")";
+       return false;
+     }
+     for (size_t i = 0; i < std::min(records_.size(), records->size()); ++i) {
+       if (!records_[i].IsEqual(&(*records)[i])) {
+         EPOLL_LOG(INFO) << "entry in index: " << i
+                         << " differs from recorder.";
+         return false;
+       }
+     }
+    return true;
+  }
+
+ private:
+  std::vector<RecordEntry> records_;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+class RecordingCB : public EpollCallbackInterface {
+ public:
+  RecordingCB() : recorder_(new Recorder()) {
+    recorder_->Record(this, CREATION, 0, 0);
+  }
+
+  ~RecordingCB() override {
+    recorder_->Record(this, DESTRUCTION, 0, 0);
+    delete recorder_;
+  }
+
+  void OnRegistration(SimpleEpollServer* /*eps*/, int fd,
+                      int event_mask) override {
+    recorder_->Record(this, REGISTRATION, fd, event_mask);
+  }
+
+  void OnModification(int fd, int event_mask) override {
+    recorder_->Record(this, MODIFICATION, fd, event_mask);
+  }
+
+  void OnEvent(int fd, EpollEvent* event) override {
+    recorder_->Record(this, EVENT, fd, event->in_events);
+    if (event->in_events & EPOLLIN) {
+      const int kLength = 1024;
+      char buf[kLength];
+      int data_read;
+      do {
+        data_read = read(fd, &buf, kLength);
+      } while (data_read > 0);
+    }
+  }
+
+  void OnUnregistration(int fd, bool replaced) override {
+    recorder_->Record(this, UNREGISTRATION, fd, replaced);
+  }
+
+  void OnShutdown(SimpleEpollServer* eps, int fd) override {
+    if (fd >= 0) {
+      eps->UnregisterFD(fd);
+    }
+    recorder_->Record(this, SHUTDOWN, fd, 0);
+  }
+
+  std::string Name() const override { return "RecordingCB"; }
+
+  const Recorder* recorder() const { return recorder_; }
+
+ protected:
+  Recorder* recorder_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// A simple test server that adds some test functions to SimpleEpollServer as
+// well as allowing access to protected functions.
+class EpollTestServer : public SimpleEpollServer {
+ public:
+  EpollTestServer() : SimpleEpollServer() {}
+
+  ~EpollTestServer() override {}
+
+  void CheckMapping(int fd, CB* cb) {
+    CBAndEventMask tmp;
+    tmp.fd = fd;
+    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
+    CHECK(fd_i != cb_map_.end());  // Chokes CHECK_NE.
+    CHECK(fd_i->cb == cb);
+  }
+
+  void CheckNotMapped(int fd) {
+    CBAndEventMask tmp;
+    tmp.fd = fd;
+    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
+    CHECK(fd_i == cb_map_.end());  // Chokes CHECK_EQ.
+  }
+
+  void CheckEventMask(int fd, int event_mask) {
+    CBAndEventMask tmp;
+    tmp.fd = fd;
+    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
+    CHECK(cb_map_.end() != fd_i);  // Chokes CHECK_NE.
+    CHECK_EQ(fd_i->event_mask, event_mask);
+  }
+
+  void CheckNotRegistered(int fd) {
+    struct epoll_event ee;
+    memset(&ee, 0, sizeof(ee));
+    // If the fd is registered, the epoll_ctl call would succeed (return 0) and
+    // the CHECK would fail.
+    CHECK(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee));
+  }
+
+  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }
+
+  bool ContainsAlarm(AlarmCB* ac) {
+    return all_alarms_.find(ac) != all_alarms_.end();
+  }
+
+  using SimpleEpollServer::WaitForEventsAndCallHandleEvents;
+};
+
+class EpollFunctionTest : public EpollTest {
+ public:
+  EpollFunctionTest()
+      : fd_(-1), fd2_(-1), recorder_(nullptr), cb_(nullptr), ep_(nullptr) {
+  }
+
+  ~EpollFunctionTest() override {
+    delete ep_;
+    delete cb_;
+  }
+
+  void SetUp() override {
+    ep_ = new EpollTestServer();
+    cb_ = new RecordingCB();
+    // recorder_ is safe to use directly as we know it has the same scope as
+    // cb_
+    recorder_ = cb_->recorder();
+
+    int pipe_fds[2];
+    if (pipe(pipe_fds) < 0) {
+      EPOLL_PLOG(FATAL) << "pipe() failed";
+    }
+    fd_ = pipe_fds[0];
+    fd2_ = pipe_fds[1];
+  }
+
+  void TearDown() override {
+    close(fd_);
+    close(fd2_);
+  }
+
+  void DeleteSimpleEpollServer() {
+    delete ep_;
+    ep_ = nullptr;
+  }
+
+  int fd() { return fd_; }
+  int fd2() { return fd2_; }
+  EpollTestServer*  ep() { return ep_; }
+  EpollCallbackInterface* cb() { return cb_; }
+  const Recorder* recorder() { return recorder_; }
+
+ private:
+  int fd_;
+  int fd2_;
+  const Recorder *recorder_;
+  RecordingCB* cb_;
+  EpollTestServer* ep_;
+};
+
+TEST_F(EpollFunctionTest, TestUnconnectedSocket) {
+  int fd = socket(AddressFamilyUnderTest(), SOCK_STREAM, IPPROTO_TCP);
+  ep()->RegisterFD(fd, cb(), EPOLLIN | EPOLLOUT);
+  ep()->WaitForEventsAndExecuteCallbacks();
+
+  Recorder tmp;
+  tmp.Record(cb(), CREATION, 0, 0);
+  tmp.Record(cb(), REGISTRATION, fd, EPOLLIN | EPOLLOUT);
+  tmp.Record(cb(), EVENT, fd, EPOLLOUT | EPOLLHUP);
+  EXPECT_TRUE(recorder()->IsEqual(&tmp));
+}
+
+TEST_F(EpollFunctionTest, TestRegisterFD) {
+  // Check that the basic register works.
+  ep()->RegisterFD(fd(), cb(), EPOLLIN);
+
+  // Make sure that the fd-CB mapping is there.
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN);
+
+  // Now make sure that if we register again, we stomp the old callback.
+  // Also make sure we handle O_NONBLOCK correctly
+  RecordingCB cb2;
+  ep()->RegisterFD(fd(), &cb2, EPOLLOUT | O_NONBLOCK);
+  ep()->CheckMapping(fd(), &cb2);
+  ep()->CheckEventMask(fd(), EPOLLOUT | O_NONBLOCK);
+
+  // Clean up.
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestRegisterFDForWrite) {
+  ep()->RegisterFDForWrite(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLOUT);
+
+  // Clean up.
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestRegisterFDForReadWrite) {
+  ep()->RegisterFDForReadWrite(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
+
+  // Clean up.
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestRegisterFDForRead) {
+  ep()->RegisterFDForRead(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN);
+
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestUnregisterFD) {
+  ep()->RegisterFDForRead(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN);
+
+    // Unregister and make sure that it's gone.
+  ep()->UnregisterFD(fd());
+  ep()->CheckNotMapped(fd());
+  ep()->CheckNotRegistered(fd());
+
+  // And make sure that unregistering something a second time doesn't cause
+  // crashes.
+  ep()->UnregisterFD(fd());
+  ep()->CheckNotMapped(fd());
+  ep()->CheckNotRegistered(fd());
+}
+
+TEST_F(EpollFunctionTest, TestModifyCallback) {
+  // Check that nothing terrible happens if we modify an unregistered fd.
+  ep()->ModifyCallback(fd(), EPOLLOUT);
+  ep()->CheckNotMapped(fd());
+  ep()->CheckNotRegistered(fd());
+
+  // Check that the basic register works.
+  ep()->RegisterFD(fd(), cb(), EPOLLIN);
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN);
+
+  // Check that adding a signal swaps it out for the first.
+  ep()->ModifyCallback(fd(), EPOLLOUT);
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLOUT);
+
+  // Check that modifying from X to X works correctly.
+  ep()->ModifyCallback(fd(), EPOLLOUT);
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLOUT);
+
+  // Check that modifying from something to nothing works.
+  ep()->ModifyCallback(fd(), 0);
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), 0);
+
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestStopRead) {
+  ep()->RegisterFDForReadWrite(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
+
+  // Unregister and make sure you only lose the read event.
+  ep()->StopRead(fd());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLOUT);
+
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestStartRead) {
+  ep()->RegisterFDForWrite(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLOUT);
+
+  // Make sure that StartRead adds EPOLLIN and doesn't remove other signals.
+  ep()->StartRead(fd());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
+
+  // Clean up.
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestStopWrite) {
+  ep()->RegisterFDForReadWrite(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
+
+  // Unregister write and make sure you only lose the write event.
+  ep()->StopWrite(fd());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN);
+
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestStartWrite) {
+  ep()->RegisterFDForRead(fd(), cb());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN);
+
+  // Make sure that StartWrite adds EPOLLOUT and doesn't remove other
+  // signals.
+  ep()->StartWrite(fd());
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
+
+  // Clean up.
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestSet_timeout_in_us) {
+  // Check that set works with various values.  There's a separate test below
+  // to make sure the values are used properly.
+  ep()->set_timeout_in_us(10);
+  EXPECT_EQ(10, ep()->timeout_in_us_for_test());
+
+  ep()->set_timeout_in_us(-1);
+  EXPECT_EQ(-1, ep()->timeout_in_us_for_test());
+}
+
+TEST_F(EpollFunctionTest, TestHandleEvent) {
+  const std::vector<RecordEntry> *records = recorder()->records();
+
+  // Test that nothing bad happens if the FD is not in the map.
+  ep()->HandleEvent(fd(), EPOLLOUT);
+  ep()->CallReadyListCallbacks();
+
+  ep()->RegisterFD(fd(), cb(), 0);
+  ep()->CheckMapping(fd(), cb());
+  ep()->CheckEventMask(fd(), 0);
+
+  // At this point we should have creation and registration recorded.
+  EXPECT_EQ(2u, records->size());
+
+  // Call handle event and make sure something was recorded.
+  ep()->HandleEvent(fd(), EPOLLOUT);
+  ep()->CallReadyListCallbacks();
+  EXPECT_EQ(3u, records->size());
+
+  // Call handle event and make sure something was recorded.
+  ep()->HandleEvent(fd(), EPOLLIN | O_NONBLOCK);
+  ep()->CallReadyListCallbacks();
+  EXPECT_EQ(4u, records->size());
+
+  Recorder tmp;
+  tmp.Record(cb(), CREATION, 0, 0);
+  tmp.Record(cb(), REGISTRATION, fd(), 0);
+  tmp.Record(cb(), EVENT, fd(), EPOLLOUT);
+  tmp.Record(cb(), EVENT, fd(), EPOLLIN | O_NONBLOCK);
+
+  EXPECT_TRUE(recorder()->IsEqual(&tmp));
+  ep()->UnregisterFD(fd());
+}
+
+TEST_F(EpollFunctionTest, TestNumFDsRegistered) {
+  EXPECT_EQ(0, ep()->NumFDsRegistered());
+
+  ep()->RegisterFD(fd(), cb(), 0);
+  EXPECT_EQ(1, ep()->NumFDsRegistered());
+
+  ep()->RegisterFD(fd2(), cb(), 0);
+  EXPECT_EQ(2, ep()->NumFDsRegistered());
+
+  ep()->RegisterFD(fd2(), cb(), 0);
+  EXPECT_EQ(2, ep()->NumFDsRegistered());
+
+  ep()->UnregisterFD(fd2());
+  EXPECT_EQ(1, ep()->NumFDsRegistered());
+
+  ep()->UnregisterFD(fd());
+  EXPECT_EQ(0, ep()->NumFDsRegistered());
+}
+
+// Check all of the individual signals and 1-2 combinations.
+TEST_F(EpollFunctionTest, TestEventMaskToString) {
+  std::string test;
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLIN);
+  EXPECT_EQ(test, "EPOLLIN ");
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLOUT);
+  EXPECT_EQ(test, "EPOLLOUT ");
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLPRI);
+  EXPECT_EQ(test, "EPOLLPRI ");
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLERR);
+  EXPECT_EQ(test, "EPOLLERR ");
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLHUP);
+  EXPECT_EQ(test, "EPOLLHUP ");
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLHUP | EPOLLIN);
+  EXPECT_EQ(test, "EPOLLIN EPOLLHUP ");
+
+  test = SimpleEpollServer::EventMaskToString(EPOLLIN | EPOLLOUT);
+  EXPECT_EQ(test, "EPOLLIN EPOLLOUT ");
+}
+
+class TestAlarm : public EpollAlarmCallbackInterface {
+ public:
+  TestAlarm()
+    : time_before_next_alarm_(-1),
+      was_called_(false),
+      num_called_(0),
+      absolute_time_(false),
+      onshutdown_called_(false),
+      has_token_(false),
+      eps_(nullptr) {
+  }
+  ~TestAlarm() override {
+  }
+  int64_t OnAlarm() override {
+    has_token_ = false;
+    was_called_ = true;
+    ++num_called_;
+    if (time_before_next_alarm_ < 0) {
+      return 0;
+    }
+    if (absolute_time_) {
+      return time_before_next_alarm_;
+    } else {
+      return WallTimeNowInUsec() + time_before_next_alarm_;
+    }
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/) override {
+    onshutdown_called_ = true;
+    has_token_ = false;
+  }
+  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
+                      SimpleEpollServer* eps) override {
+    has_token_ = true;
+    last_token_ = token;
+    eps_ = eps;
+  }
+  void OnUnregistration() override {
+    has_token_ = false;
+  }
+
+  void UnregisterIfRegistered(SimpleEpollServer* eps) {
+    if (has_token_) {
+      eps->UnregisterAlarm(last_token_);
+    }
+  }
+
+  void ReregisterAlarm(int64_t timeout_in_us) {
+    CHECK(has_token_);
+    eps_->ReregisterAlarm(last_token_, timeout_in_us);
+  }
+
+  void Reset() {
+    time_before_next_alarm_ = -1;
+    was_called_ = false;
+    absolute_time_ = false;
+  }
+
+  bool was_called() const { return was_called_; }
+  int num_called() const { return num_called_; }
+
+  void set_time_before_next_alarm(int64_t time) {
+    time_before_next_alarm_ = time;
+  }
+  void set_absolute_time(bool absolute) {
+    absolute_time_ = absolute;
+  }
+  bool onshutdown_called() { return onshutdown_called_; }
+
+ protected:
+  int64_t time_before_next_alarm_;
+  bool was_called_;
+  int num_called_;
+  // Is time_before_next_alarm relative to the current time or absolute?
+  bool absolute_time_;
+  bool onshutdown_called_;
+  bool has_token_;
+  SimpleEpollServer::AlarmRegToken last_token_;
+  SimpleEpollServer* eps_;
+};
+
+class TestChildAlarm;
+
+// This node unregister all other alarms when it receives
+// OnShutdown() from any one child.
+class TestParentAlarm {
+ public:
+  void OnShutdown(TestChildAlarm* child, SimpleEpollServer* eps) {
+    // Unregister
+    for (ChildTokenMap::const_iterator it = child_tokens_.begin();
+         it != child_tokens_.end(); ++it) {
+      if (it->first != child) {
+        eps->UnregisterAlarm(it->second);
+      }
+    }
+    child_tokens_.clear();
+  }
+
+  void OnRegistration(TestChildAlarm* child,
+                      const SimpleEpollServer::AlarmRegToken& token) {
+    child_tokens_[child] = token;
+  }
+
+ protected:
+  typedef std::unordered_map<TestChildAlarm*, SimpleEpollServer::AlarmRegToken>
+      ChildTokenMap;
+
+  ChildTokenMap child_tokens_;
+};
+
+class TestChildAlarm : public TestAlarm {
+ public:
+  void set_parent(TestParentAlarm* tp) { parent_ = tp; }
+  void OnShutdown(SimpleEpollServer* eps) override {
+    onshutdown_called_ = true;
+    // Inform parent of shutdown
+    parent_->OnShutdown(this, eps);
+  }
+  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
+                      SimpleEpollServer* /*eps*/) override {
+    parent_->OnRegistration(this, token);
+  }
+
+ protected:
+  TestParentAlarm* parent_;
+};
+
+class TestAlarmThatRegistersAnotherAlarm : public TestAlarm {
+ public:
+  TestAlarmThatRegistersAnotherAlarm()
+      : alarm_(nullptr),
+        reg_time_delta_usec_(0),
+        eps_to_register_(nullptr),
+        has_reg_alarm_(false) {}
+  void SetRegisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
+                        SimpleEpollServer* eps) {
+    alarm_ = alarm;
+    reg_time_delta_usec_ = time_delta_usec;
+    has_reg_alarm_ = true;
+    eps_to_register_ = eps;
+  }
+  int64_t OnAlarm() override {
+    if (has_reg_alarm_) {
+      eps_to_register_->RegisterAlarm(
+          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
+          alarm_);
+      has_reg_alarm_ = false;
+    }
+    return TestAlarm::OnAlarm();
+  }
+
+ protected:
+  TestAlarm* alarm_;
+  int64_t reg_time_delta_usec_;
+  SimpleEpollServer* eps_to_register_;
+  bool has_reg_alarm_;
+};
+
+class TestAlarmThatRegistersAndReregistersAnotherAlarm : public TestAlarm {
+ public:
+  TestAlarmThatRegistersAndReregistersAnotherAlarm()
+      : alarm_(nullptr),
+        reg_time_delta_usec_(0),
+        reregister_time_delta_usec_(0),
+        eps_to_register_(nullptr),
+        has_reg_alarm_(false) {}
+  void SetRegisterAndReregisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
+                                     int64_t reregister_delta_usec,
+                                     SimpleEpollServer* eps) {
+    alarm_ = alarm;
+    reg_time_delta_usec_ = time_delta_usec;
+    reregister_time_delta_usec_ = reregister_delta_usec;
+    has_reg_alarm_ = true;
+    eps_to_register_ = eps;
+  }
+  int64_t OnAlarm() override {
+    if (has_reg_alarm_) {
+      eps_to_register_->RegisterAlarm(
+          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
+          alarm_);
+      alarm_->ReregisterAlarm(eps_to_register_->ApproximateNowInUsec() +
+                              reregister_time_delta_usec_);
+      has_reg_alarm_ = false;
+    }
+    return TestAlarm::OnAlarm();
+  }
+
+ protected:
+  TestAlarm* alarm_;
+  int64_t reg_time_delta_usec_;
+  int64_t reregister_time_delta_usec_;
+  SimpleEpollServer* eps_to_register_;
+  bool has_reg_alarm_;
+};
+
+class TestAlarmThatUnregistersAnotherAlarm : public TestAlarm {
+ public:
+  TestAlarmThatUnregistersAnotherAlarm()
+      : alarm_(nullptr), eps_to_register_(nullptr), has_unreg_alarm_(false) {}
+  void SetUnregisterAlarm(TestAlarm* alarm, SimpleEpollServer* eps) {
+    alarm_ = alarm;
+    has_unreg_alarm_ = true;
+    eps_to_register_ = eps;
+  }
+  int64_t OnAlarm() override {
+    if (has_unreg_alarm_) {
+      has_unreg_alarm_ = false;
+      alarm_->UnregisterIfRegistered(eps_to_register_);
+    }
+    return TestAlarm::OnAlarm();
+  }
+
+ protected:
+  TestAlarm* alarm_;
+  SimpleEpollServer* eps_to_register_;
+  bool has_unreg_alarm_;
+};
+
+class TestAlarmUnregister : public TestAlarm {
+ public:
+  TestAlarmUnregister()
+      : onunregistration_called_(false),
+        iterator_token_(nullptr) {
+  }
+  ~TestAlarmUnregister() override {
+    delete iterator_token_;
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/) override {
+    onshutdown_called_ = true;
+  }
+
+  int64_t OnAlarm() override {
+    delete iterator_token_;
+    iterator_token_ = nullptr;
+
+    return TestAlarm::OnAlarm();
+  }
+
+  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
+                      SimpleEpollServer* /*eps*/) override {
+    // Multiple iterator tokens are not maintained by this code,
+    // so we should have reset the iterator_token in OnAlarm or
+    // OnUnregistration.
+    CHECK(iterator_token_ == nullptr);
+    iterator_token_ = new SimpleEpollServer::AlarmRegToken(token);
+  }
+  void OnUnregistration() override {
+    delete iterator_token_;
+    iterator_token_ = nullptr;
+    // Make sure that this alarm was not already unregistered.
+    CHECK(onunregistration_called_ == false);
+    onunregistration_called_ = true;
+  }
+
+  bool onunregistration_called() { return onunregistration_called_; }
+  // Returns true if the token has been filled in with the saved iterator
+  // and false if it has not.
+  bool get_token(SimpleEpollServer::AlarmRegToken* token) {
+    if (iterator_token_ != nullptr) {
+      *token = *iterator_token_;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+ protected:
+  bool onunregistration_called_;
+  SimpleEpollServer::AlarmRegToken* iterator_token_;
+};
+
+void WaitForAlarm(SimpleEpollServer* eps, const TestAlarm& alarm) {
+  for (int i = 0; i < 5; ++i) {
+    // Ideally we would only have to call this once but it could wake up a bit
+    // early and so not call the alarm.  If it wakes up early several times
+    // there is something wrong.
+    eps->WaitForEventsAndExecuteCallbacks();
+    if (alarm.was_called()) {
+      break;
+    }
+  }
+}
+
+// Check a couple of alarm times to make sure they're falling within a
+// reasonable range.
+TEST(SimpleEpollServerTest, TestAlarms) {
+  EpollTestServer ep;
+  TestAlarm alarm;
+
+  int alarm_time = 10;
+
+  // Register an alarm and make sure we wait long enough to hit it.
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+
+  // Test a different time just to be careful.
+  alarm_time = 20;
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  alarm.Reset();
+
+  // The alarm was a one-time thing.  Make sure that we don't hit it again.
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(alarm.was_called());
+  alarm.Reset();
+}
+
+// Same as above, but using RegisterAlarmApproximateDelta.
+TEST(SimpleEpollServerTest, TestRegisterAlarmApproximateDelta) {
+  EpollTestServer ep;
+  TestAlarm alarm;
+
+  int alarm_time = 10;
+
+  // Register an alarm and make sure we wait long enough to hit it.
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+  int64_t first_now = ep.ApproximateNowInUsec();
+  EXPECT_LT(0u, first_now);
+
+  // Test a different time just to be careful.
+  alarm_time = 20;
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  alarm.Reset();
+  int64_t second_now = ep.ApproximateNowInUsec();
+
+  EXPECT_LT(first_now, second_now);
+
+
+  // The alarm was a one-time thing.  Make sure that we don't hit it again.
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(alarm.was_called());
+  alarm.Reset();
+}
+
+TEST(SimpleEpollServerTest, TestAlarmsWithInfiniteWait) {
+  EpollTestServer ep;
+  TestAlarm alarm;
+
+  int alarm_time = 10;
+
+  // Register an alarm and make sure we wait long enough to hit it.
+  ep.set_timeout_in_us(-1);
+  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+}
+
+// In this test we have an alarm that when fires gets re-registered
+// at almost the same time at which it fires. Here, we want to make
+// sure that when the alarm gets re-registered we do not call OnAlarm()
+// on the same Alarm object again, until we have called
+// WaitForEventsAndExecuteCallbacks(). A poor implementation of epoll
+// server alarm handling can potentially cause OnAlarm() to be called
+// multiple times. We make sure that the epoll server is not going in
+// an infinite loop by checking that OnAlarm() is called exactly once
+// on the alarm object that got registered again.
+TEST(SimpleEpollServerTest, TestAlarmsThatGetReRegisteredAreNotCalledTwice) {
+  // This alarm would get registered again
+  TestAlarm alarm;
+  TestAlarm alarm2;
+  EpollTestServer ep;
+  ep.set_timeout_in_us(-1);
+
+  int64_t alarm_time = 10;
+  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
+
+  // This will make the alarm re-register when OnAlarm is called.
+  alarm.set_absolute_time(true);
+  alarm.set_time_before_next_alarm(abs_time + 2);
+
+  // Register two alarms and make sure we wait long enough to hit it.
+  ep.RegisterAlarm(abs_time, &alarm);
+  ep.RegisterAlarm(abs_time, &alarm2);
+  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
+
+  WaitForAlarm(&ep, alarm);
+
+  EXPECT_TRUE(alarm.was_called());
+  // Make sure that alarm is called only once.
+  EXPECT_EQ(1, alarm.num_called());
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+}
+
+// Here we make sure that when one alarm unregisters another alarm
+// (that is supposed to be registered again because its OnAlarm
+// returned > 0), the alarm thats supposed to be unregistered does
+// actually gets unregistered.
+TEST(SimpleEpollServerTest, TestAlarmsOneOnAlarmUnRegistersAnotherAlarm) {
+  TestAlarm alarm;
+  TestAlarmThatUnregistersAnotherAlarm alarm2;
+  EpollTestServer ep;
+  ep.set_timeout_in_us(-1);
+
+  int64_t alarm_time = 1;
+  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
+
+  // This will make the alarm re-register when OnAlarm is called.
+  alarm.set_absolute_time(true);
+  alarm.set_time_before_next_alarm(abs_time + 2);
+
+
+  // Register two alarms and make sure we wait long enough to hit it.
+  ep.RegisterAlarm(abs_time, &alarm);
+  // This would cause us to unregister alarm when OnAlarm is called
+  // on alarm2.
+  alarm2.SetUnregisterAlarm(&alarm, &ep);
+  ep.RegisterAlarm(abs_time + 1, &alarm2);
+  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
+
+  WaitForAlarm(&ep, alarm);
+
+  EXPECT_TRUE(alarm.was_called());
+  // Make sure that alarm is called only once.
+  EXPECT_EQ(1, alarm.num_called());
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+}
+
+// Check a couple of alarm times to make sure they're falling within a
+// reasonable range.
+TEST(SimpleEpollServerTest, TestRepeatAlarms) {
+  EpollTestServer ep;
+  TestAlarm alarm;
+
+  int alarm_time = 20;
+
+  // Register an alarm and make sure we wait long enough to hit it.
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  alarm.set_time_before_next_alarm(1000*alarm_time);
+  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+
+  WaitForAlarm(&ep, alarm);
+  // When we wake up it should be because the Alarm has been called, and has
+  // registered itself to be called again.
+
+  // Make sure the first alarm was called properly.
+  EXPECT_TRUE(alarm.was_called());
+
+  // Resetting means that the alarm is no longer a recurring alarm.  It will be
+  // called once more and then stop.
+  alarm.Reset();
+
+  // Make sure the alarm is called one final time.
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  WaitForAlarm(&ep, alarm);
+
+  EXPECT_TRUE(alarm.was_called());
+  alarm.Reset();
+
+  // The alarm was a one-time thing.  Make sure that we don't hit it again.
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(alarm.was_called());
+}
+
+// Verify that an alarm that repeats itself in the past works properly.
+TEST(SimpleEpollServerTest, TestRepeatAlarmInPast) {
+  EpollTestServer ep;
+  TestAlarm alarm;
+
+  int64_t alarm_time = 20;
+  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
+
+  // Make the alarm re-register in the past when OnAlarm is called.
+  alarm.set_absolute_time(true);
+  alarm.set_time_before_next_alarm(abs_time - 1000);
+
+  // Register the alarm and make sure we wait long enough to hit it.
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  ep.RegisterAlarm(abs_time, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+
+  WaitForAlarm(&ep, alarm);
+  // When we wake up it should be because the Alarm has been called, and has
+  // registered itself to be called again.
+
+  // Make sure the first alarm was called properly.
+  EXPECT_TRUE(alarm.was_called());
+
+  // Resetting means that the alarm is no longer a recurring alarm.  It will be
+  // called once more and then stop.
+  alarm.Reset();
+
+  // Make sure the alarm is called one final time.
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  ep.set_timeout_in_us(alarm_time * 1000 * 2);
+  WaitForAlarm(&ep, alarm);
+
+  EXPECT_TRUE(alarm.was_called());
+  alarm.Reset();
+
+  // The alarm was a one-time thing.  Make sure that we don't hit it again.
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(alarm.was_called());
+}
+
+class EpollTestAlarms : public SimpleEpollServer {
+ public:
+  EpollTestAlarms() : SimpleEpollServer() {}
+
+  inline int64_t NowInUsec() const override { return time_; }
+
+  void CallAndReregisterAlarmEvents() override {
+    recorded_now_in_us_ = NowInUsec();
+    SimpleEpollServer::CallAndReregisterAlarmEvents();
+  }
+
+  void set_time(int64_t time) { time_ = time; }
+
+  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }
+
+ private:
+  int64_t time_;
+};
+
+// Test multiple interleaving alarms to make sure they work right.
+// Pattern is roughly:
+// time:   15    20    30    40
+// alarm:   A     B     A'    C
+TEST(SimpleEpollServerTest, TestMultipleAlarms) {
+  EpollTestAlarms ep;
+  TestAlarm alarmA;
+  TestAlarm alarmB;
+  TestAlarm alarmC;
+
+  ep.set_timeout_in_us(50 * 1000 * 2);
+  alarmA.set_time_before_next_alarm(1000 * 30);
+  alarmA.set_absolute_time(true);
+  ep.RegisterAlarm(15 * 1000, &alarmA);
+  ep.RegisterAlarm(20 * 1000, &alarmB);
+  ep.RegisterAlarm(40 * 1000, &alarmC);
+
+  ep.set_time(15 * 1000);
+  ep.CallAndReregisterAlarmEvents();  // A
+  EXPECT_TRUE(alarmA.was_called());
+  EXPECT_FALSE(alarmB.was_called());
+  EXPECT_FALSE(alarmC.was_called());
+  alarmA.Reset();  // Unregister A in the future.
+
+  ep.set_time(20 * 1000);
+  ep.CallAndReregisterAlarmEvents();  // B
+  EXPECT_FALSE(alarmA.was_called());
+  EXPECT_TRUE(alarmB.was_called());
+  EXPECT_FALSE(alarmC.was_called());
+  alarmB.Reset();
+
+  ep.set_time(30 * 1000);
+  ep.CallAndReregisterAlarmEvents();  // A
+  EXPECT_TRUE(alarmA.was_called());
+  EXPECT_FALSE(alarmB.was_called());
+  EXPECT_FALSE(alarmC.was_called());
+  alarmA.Reset();
+
+  ep.set_time(40 * 1000);
+  ep.CallAndReregisterAlarmEvents();  // C
+  EXPECT_FALSE(alarmA.was_called());
+  EXPECT_FALSE(alarmB.was_called());
+  EXPECT_TRUE(alarmC.was_called());
+  alarmC.Reset();
+
+  ep.CallAndReregisterAlarmEvents();  // None.
+  EXPECT_FALSE(alarmA.was_called());
+  EXPECT_FALSE(alarmB.was_called());
+  EXPECT_FALSE(alarmC.was_called());
+}
+
+TEST(SimpleEpollServerTest, TestAlarmOnShutdown) {
+  TestAlarm alarm1;
+  {
+    EpollTestServer ep;
+    const int64_t now = WallTimeNowInUsec();
+    ep.RegisterAlarm(now + 5000, &alarm1);
+  }
+
+  EXPECT_TRUE(alarm1.onshutdown_called());
+}
+
+// Tests that if we have multiple alarms
+// OnShutdown then we handle them properly.
+TEST(SimpleEpollServerTest, TestMultipleAlarmOnShutdown) {
+  TestAlarm alarm1;
+  TestAlarm alarm2;
+  TestAlarm alarm3;
+  {
+    EpollTestServer ep;
+    const int64_t now = WallTimeNowInUsec();
+    ep.RegisterAlarm(now + 5000, &alarm1);
+    ep.RegisterAlarm(now + 9000, &alarm2);
+    ep.RegisterAlarm(now + 9000, &alarm3);
+  }
+
+  EXPECT_TRUE(alarm1.onshutdown_called());
+  EXPECT_TRUE(alarm2.onshutdown_called());
+  EXPECT_TRUE(alarm3.onshutdown_called());
+}
+TEST(SimpleEpollServerTest, TestMultipleAlarmUnregistrationOnShutdown) {
+  TestParentAlarm tp;
+  TestChildAlarm alarm1;
+  TestChildAlarm alarm2;
+  alarm1.set_parent(&tp);
+  alarm2.set_parent(&tp);
+  {
+    EpollTestServer ep;
+    const int64_t now = WallTimeNowInUsec();
+    ep.RegisterAlarm(now + 5000, &alarm1);
+    ep.RegisterAlarm(now + 9000, &alarm2);
+  }
+
+  EXPECT_TRUE(alarm1.onshutdown_called());
+  EXPECT_FALSE(alarm2.onshutdown_called());
+}
+
+// Check an alarm set in the past runs right away.
+TEST(SimpleEpollServerTest, TestPastAlarm) {
+  EpollTestServer ep;
+  TestAlarm alarm;
+
+  // Register the alarm and make sure we wait long enough to hit it.
+  ep.set_timeout_in_us(1000 * 2);
+  ep.RegisterAlarm(WallTimeNowInUsec() - 1000, &alarm);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+}
+
+// Test Unregistering of Alarms
+TEST(SimpleEpollServerTest, TestUnregisterAlarm) {
+  EpollTestServer ep;
+  SimpleEpollServer::AlarmRegToken temptok;
+
+  TestAlarmUnregister alarm1;
+  TestAlarmUnregister alarm2;
+
+  ep.RegisterAlarm(WallTimeNowInUsec() + 5 * 1000, &alarm1);
+  ep.RegisterAlarm(WallTimeNowInUsec() + 13 * 1000, &alarm2);
+
+  // Unregister an alarm.
+  if (alarm2.get_token(&temptok)) {
+    ep.UnregisterAlarm(temptok);
+  }
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  EXPECT_TRUE(alarm2.onunregistration_called());
+
+  if (alarm1.get_token(&temptok)) {
+    ep.UnregisterAlarm(temptok);
+  }
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+  EXPECT_TRUE(alarm1.onunregistration_called());
+}
+
+// Test Reregistering of Alarms
+TEST(SimpleEpollServerTest, TestReregisterAlarm) {
+  EpollTestAlarms ep;
+  SimpleEpollServer::AlarmRegToken token;
+
+  TestAlarmUnregister alarm;
+  ep.set_time(1000);
+  ep.RegisterAlarm(5000, &alarm);
+
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  ASSERT_TRUE(alarm.get_token(&token));
+  ep.ReregisterAlarm(token, 6000);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(5000);
+  ep.set_timeout_in_us(0);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_FALSE(alarm.was_called());
+
+  ep.set_time(6000);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_TRUE(alarm.was_called());
+}
+
+TEST(SimpleEpollServerTest, TestReregisterDeferredAlarm) {
+  EpollTestAlarms ep;
+  ep.set_timeout_in_us(0);
+
+  TestAlarm alarm;
+  TestAlarmThatRegistersAndReregistersAnotherAlarm register_alarm;
+  // Register the alarm in the past so it is added as a deferred alarm.
+  register_alarm.SetRegisterAndReregisterAlarm(&alarm, -500, 500, &ep);
+  ep.set_time(1000);
+  ep.RegisterAlarm(1000, &register_alarm);
+  // Call reregister twice, first to run register_alarm and second to run any
+  // scheduled deferred alarms.
+  ep.CallAndReregisterAlarmEvents();
+  ep.CallAndReregisterAlarmEvents();
+
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  EXPECT_FALSE(alarm.was_called());
+
+  ep.set_time(1500);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_TRUE(alarm.was_called());
+}
+
+// Check if an alarm fired and got reregistered, you are able to
+// unregister the second registration.
+TEST(SimpleEpollServerTest, TestFiredReregisteredAlarm) {
+  EpollTestAlarms ep;
+  TestAlarmUnregister alarmA;
+
+  SimpleEpollServer::AlarmRegToken first_token;
+  SimpleEpollServer::AlarmRegToken second_token;
+  bool found;
+
+  ep.set_timeout_in_us(50 * 1000 * 2);
+  alarmA.set_time_before_next_alarm(1000 * 30);
+  alarmA.set_absolute_time(true);
+
+// Alarm A first fires at 15, then 30
+  ep.RegisterAlarm(15 * 1000, &alarmA);
+
+  found = alarmA.get_token(&first_token);
+  EXPECT_TRUE(found);
+
+  ep.set_time(15 * 1000);
+  ep.CallAndReregisterAlarmEvents();  // A
+  EXPECT_TRUE(alarmA.was_called());
+
+  alarmA.Reset();
+
+  found = alarmA.get_token(&second_token);
+  EXPECT_TRUE(found);
+  if (found) {
+    ep.UnregisterAlarm(second_token);
+  }
+
+  ep.set_time(30 * 1000);
+  ep.CallAndReregisterAlarmEvents();  // A
+
+  alarmA.Reset();
+}
+
+// Here we make sure that one alarm can unregister another alarm
+// in OnShutdown().
+TEST(SimpleEpollServerTest, TestAlarmCanUnregistersAnotherAlarmOnShutdown) {
+  TestAlarmThatUnregistersAnotherAlarm alarm1;
+  TestAlarm alarm2;
+  {
+    EpollTestServer ep;
+    // Register two alarms and make alarm1 is placed in queue in front of alarm2
+    // so that when the queue is cleared, alarm1 is processed first.
+    const int64_t now = WallTimeNowInUsec();
+    ep.RegisterAlarm(now + 5000, &alarm1);
+    ep.RegisterAlarm(now + 9000, &alarm2);
+    alarm1.SetUnregisterAlarm(&alarm2, &ep);
+    EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
+  }
+}
+
+class TestAlarmRegisterAnotherAlarmShutdown : public TestAlarmUnregister {
+ public:
+  TestAlarmRegisterAnotherAlarmShutdown(EpollAlarmCallbackInterface* alarm2,
+                                        int64_t when)
+      : alarm2_(alarm2), when_(when) {}
+  void OnShutdown(SimpleEpollServer* eps) override {
+    TestAlarmUnregister::OnShutdown(eps);
+    eps->RegisterAlarm(when_, alarm2_);
+  }
+
+ private:
+  EpollAlarmCallbackInterface* alarm2_;
+  int64_t when_;
+};
+
+// This tests that alarm registers another alarm when shutting down.
+// The two cases are: new alarm comes before and after the alarm being
+// notified by OnShutdown()
+TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownBeforeSelf) {
+  TestAlarm alarm2;
+  int64_t alarm_time = WallTimeNowInUsec() + 5000;
+  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time - 1000);
+  {
+    EpollTestAlarms ep;
+    ep.RegisterAlarm(alarm_time, &alarm1);
+  }
+  EXPECT_TRUE(alarm1.onshutdown_called());
+  EXPECT_FALSE(alarm2.onshutdown_called());
+}
+
+TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownAfterSelf) {
+  TestAlarm alarm2;
+  int64_t alarm_time = WallTimeNowInUsec() + 5000;
+  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time + 1000);
+  {
+    EpollTestAlarms ep;
+    ep.RegisterAlarm(alarm_time, &alarm1);
+  }
+  EXPECT_TRUE(alarm1.onshutdown_called());
+  EXPECT_TRUE(alarm2.onshutdown_called());
+}
+
+TEST(SimpleEpollServerTest, TestWrite) {
+  SimpleEpollServer ep;
+  ep.set_timeout_in_us(1);
+  char data[kPageSize] = {0};
+
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int read_fd = pipe_fds[0];
+  int write_fd = pipe_fds[1];
+
+  RecordingCB recording_cb;
+  const Recorder* recorder = recording_cb.recorder();
+  const std::vector<RecordEntry> *records = recorder->records();
+
+  // Register to listen to write events.
+  ep.RegisterFD(write_fd, &recording_cb, EPOLLOUT | O_NONBLOCK);
+  // At this point the recorder should have the creation and registration
+  // events.
+  EXPECT_EQ(2u, records->size());
+
+  // Fill up the pipe.
+  int written = 1;
+  for (int i = 0; i < 17 && written > 0 ; ++i) {
+    written = write(write_fd, &data, kPageSize);
+  }
+  EXPECT_LT(written, 0);
+
+  // There should be no new events as the pipe is not available for writing.
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(2u, records->size());
+
+  // Now read data from the pipe to make it writable again.  This time the
+  // we should get an EPOLLOUT event.
+  int size = read(read_fd, &data, kPageSize);
+  EXPECT_EQ(kPageSize, size);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3u, records->size());
+
+  // Now unsubscribe from writable events (which adds a modification record)
+  // and wait to verify that no event records are added.
+  ep.StopWrite(write_fd);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(4u, records->size());
+
+  // We had the right number of events all along. Make sure they were actually
+  // the right events.
+  Recorder tmp;
+  tmp.Record(&recording_cb, CREATION, 0, 0);
+  tmp.Record(&recording_cb, REGISTRATION, write_fd, EPOLLOUT | O_NONBLOCK);
+  tmp.Record(&recording_cb, EVENT, write_fd, EPOLLOUT);
+  tmp.Record(&recording_cb, MODIFICATION, write_fd, O_NONBLOCK);
+
+  EXPECT_TRUE(recorder->IsEqual(&tmp));
+  ep.UnregisterFD(write_fd);
+
+  close(read_fd);
+  close(write_fd);
+}
+
+TEST(SimpleEpollServerTest, TestReadWrite) {
+  SimpleEpollServer ep;
+  ep.set_timeout_in_us(1);
+  char data[kPageSize] = {0};
+
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int read_fd = pipe_fds[0];
+  int write_fd = pipe_fds[1];
+
+  RecordingCB recording_cb;
+  const Recorder* recorder = recording_cb.recorder();
+  const std::vector<RecordEntry> *records = recorder->records();
+
+  // Register to listen to read and write events.
+  ep.RegisterFDForReadWrite(read_fd, &recording_cb);
+  // At this point the recorder should have the creation and registration
+  // events.
+  EXPECT_EQ(2u, records->size());
+
+  int written = write(write_fd, &data, kPageSize);
+  EXPECT_EQ(kPageSize, written);
+
+  ep.WaitForEventsAndExecuteCallbacks();
+  ep.UnregisterFD(read_fd);
+
+  close(read_fd);
+  close(write_fd);
+}
+
+TEST(SimpleEpollServerTest, TestMultipleFDs) {
+  SimpleEpollServer ep;
+  ep.set_timeout_in_us(1);
+  char data = 'x';
+
+  int pipe_one[2];
+  if (pipe(pipe_one) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int pipe_two[2];
+  if (pipe(pipe_two) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+
+  RecordingCB recording_cb_one;
+  const Recorder* recorder_one = recording_cb_one.recorder();
+  const std::vector<RecordEntry> *records_one = recorder_one->records();
+
+  RecordingCB recording_cb_two;
+  const Recorder* recorder_two = recording_cb_two.recorder();
+  const std::vector<RecordEntry> *records_two = recorder_two->records();
+
+  // Register to listen to read events for both pipes
+  ep.RegisterFDForRead(pipe_one[0], &recording_cb_one);
+  ep.RegisterFDForRead(pipe_two[0], &recording_cb_two);
+
+  EXPECT_EQ(2u, records_one->size());
+  EXPECT_EQ(2u, records_two->size());
+
+  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3u, records_one->size());
+  EXPECT_EQ(2u, records_two->size());
+
+  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3u, records_one->size());
+  EXPECT_EQ(3u, records_two->size());
+
+  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
+  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(4u, records_one->size());
+  EXPECT_EQ(4u, records_two->size());
+
+  ep.WaitForEventsAndExecuteCallbacks();
+  ep.UnregisterFD(pipe_one[0]);
+  ep.UnregisterFD(pipe_two[0]);
+  close(pipe_one[0]);
+  close(pipe_one[1]);
+  close(pipe_two[0]);
+  close(pipe_two[1]);
+}
+
+// Check that the SimpleEpollServer calls OnShutdown for any registered FDs.
+TEST(SimpleEpollServerTest, TestFDOnShutdown) {
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int read_fd = pipe_fds[0];
+  int write_fd = pipe_fds[1];
+
+  RecordingCB recording_cb1;
+  RecordingCB recording_cb2;
+  const Recorder* recorder1 = recording_cb1.recorder();
+  const Recorder* recorder2 = recording_cb2.recorder();
+
+  {
+    SimpleEpollServer ep;
+    ep.set_timeout_in_us(1);
+
+    // Register to listen to write events.
+    ep.RegisterFD(write_fd, &recording_cb1, EPOLLOUT | O_NONBLOCK);
+    ep.RegisterFD(read_fd, &recording_cb2, EPOLLIN | O_NONBLOCK);
+  }
+
+  // Make sure OnShutdown was called for both callbacks.
+  Recorder write_recorder;
+  write_recorder.Record(&recording_cb1, CREATION, 0, 0);
+  write_recorder.Record(
+      &recording_cb1, REGISTRATION, write_fd, EPOLLOUT | O_NONBLOCK);
+  write_recorder.Record(&recording_cb1, UNREGISTRATION, write_fd, false);
+  write_recorder.Record(&recording_cb1, SHUTDOWN, write_fd, 0);
+  EXPECT_TRUE(recorder1->IsEqual(&write_recorder));
+
+  Recorder read_recorder;
+  read_recorder.Record(&recording_cb2, CREATION, 0, 0);
+  read_recorder.Record(
+      &recording_cb2, REGISTRATION, read_fd, EPOLLIN | O_NONBLOCK);
+  read_recorder.Record(&recording_cb2, UNREGISTRATION, read_fd, false);
+  read_recorder.Record(&recording_cb2, SHUTDOWN, read_fd, 0);
+  EXPECT_TRUE(recorder2->IsEqual(&read_recorder));
+
+  close(read_fd);
+  close(write_fd);
+}
+
+class UnregisterCB : public EpollCallbackInterface {
+ public:
+  explicit UnregisterCB(int fd)
+    : eps_(nullptr), fd_(fd), onshutdown_called_(false) {
+  }
+
+  ~UnregisterCB() override {
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int fd) override {
+    eps_->UnregisterFD(fd_);
+    eps_->UnregisterFD(fd);
+    onshutdown_called_ = true;
+    eps_ = nullptr;
+  }
+
+  void set_epollserver(SimpleEpollServer* eps) { eps_ = eps; }
+  bool onshutdown_called() { return onshutdown_called_; }
+
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {}
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+
+  std::string Name() const override { return "UnregisterCB"; }
+
+ protected:
+  SimpleEpollServer* eps_;
+  int fd_;
+  bool onshutdown_called_;
+};
+
+// Check that unregistering fds in OnShutdown works cleanly.
+TEST(SimpleEpollServerTest, TestUnregisteringFDsOnShutdown) {
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int read_fd = pipe_fds[0];
+  int write_fd = pipe_fds[1];
+
+  UnregisterCB unreg_cb1(read_fd);
+  UnregisterCB unreg_cb2(write_fd);
+
+  {
+    SimpleEpollServer ep;
+    ep.set_timeout_in_us(1);
+
+    unreg_cb1.set_epollserver(&ep);
+    unreg_cb2.set_epollserver(&ep);
+
+    // Register to listen to write events.
+    ep.RegisterFD(write_fd, &unreg_cb1, EPOLLOUT | O_NONBLOCK);
+    ep.RegisterFD(read_fd, &unreg_cb2, EPOLLIN | O_NONBLOCK);
+  }
+
+  // Make sure at least one onshutdown was called.
+  EXPECT_TRUE(unreg_cb1.onshutdown_called() ||
+              unreg_cb2.onshutdown_called());
+  // Make sure that both onshutdowns were not called.
+  EXPECT_TRUE(!(unreg_cb1.onshutdown_called() &&
+              unreg_cb2.onshutdown_called()));
+
+  close(read_fd);
+  close(write_fd);
+}
+
+TEST(SimpleEpollServerTest, TestFDsAndAlarms) {
+  SimpleEpollServer ep;
+  ep.set_timeout_in_us(5);
+  char data = 'x';
+
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+
+  RecordingCB recording_cb;
+  const Recorder* recorder = recording_cb.recorder();
+  const std::vector<RecordEntry> *records = recorder->records();
+
+  TestAlarm alarm;
+
+  ep.RegisterFDForRead(pipe_fds[0], &recording_cb);
+
+  EXPECT_EQ(2u, records->size());
+  EXPECT_FALSE(alarm.was_called());
+
+  // Write to the pipe and set a longish alarm so we get a read event followed
+  // by an alarm event.
+  int written = write(pipe_fds[1], &data, 1);
+  EXPECT_EQ(1, written);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3u, records->size());
+  EXPECT_FALSE(alarm.was_called());
+  ep.RegisterAlarm(WallTimeNowInUsec() + 1000, &alarm);
+  WaitForAlarm(&ep, alarm);
+  EXPECT_EQ(3u, records->size());
+  EXPECT_TRUE(alarm.was_called());
+  alarm.Reset();
+
+  // Now set a short alarm so the alarm and the read event are called together.
+  ep.RegisterAlarm(WallTimeNowInUsec(), &alarm);
+  written = write(pipe_fds[1], &data, 1);
+  EXPECT_EQ(1, written);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(4u, records->size());
+
+  ep.UnregisterFD(pipe_fds[0]);
+
+  close(pipe_fds[0]);
+  close(pipe_fds[1]);
+}
+
+class EpollReader: public EpollCallbackInterface {
+ public:
+  explicit EpollReader(int len)
+      : len_(0),
+        expected_len_(len),
+        done_reading_(false) {
+    memset(&buf_, 0, kMaxBufLen);
+  }
+
+  ~EpollReader() override {}
+
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+
+  void OnEvent(int fd, EpollEvent* event) override {
+    if (event->in_events & EPOLLIN) {
+      len_ += read(fd, &buf_ + len_, kMaxBufLen - len_);
+    }
+
+    // If we have finished reading...
+    if (event->in_events & EPOLLHUP) {
+      CHECK_EQ(len_, expected_len_);
+      done_reading_ = true;
+    }
+  }
+
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
+    // None of the current tests involve having active callbacks when the
+    // server shuts down.
+    EPOLL_LOG(FATAL);
+  }
+
+  std::string Name() const override { return "EpollReader"; }
+
+  // Returns true if the data in buf is the same as buf_, false otherwise.
+  bool CheckOutput(char* buf, int len) {
+    if (len != len_) {
+      return false;
+    }
+    return !memcmp(buf, buf_, len);
+  }
+
+  bool done_reading() { return done_reading_; }
+
+ protected:
+  int len_;
+  int expected_len_;
+  char buf_[kMaxBufLen];
+  bool done_reading_;
+};
+
+void TestPipe(char *test_message, int len) {
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe failed()";
+  }
+  int reader_pipe = pipe_fds[0];
+  int writer_pipe = pipe_fds[1];
+  int child_pid;
+  memset(test_message, 'x', len);
+
+  switch (child_pid = fork()) {
+    case 0: {  // Child will send message.
+      const char *message = test_message;
+      int size;
+      close(reader_pipe);
+      while ((size = write(writer_pipe, message, len)) > 0) {
+        message += size;
+        len -= size;
+        if (len == 0) {
+          break;
+        }
+      }
+      if (len > 0) {
+        EPOLL_PLOG(FATAL) << "write() failed";
+      }
+      close(writer_pipe);
+
+      _exit(0);
+    }
+    case -1:
+      EPOLL_PLOG(FATAL) << "fork() failed";
+      break;
+    default: {  // Parent will receive message.
+      close(writer_pipe);
+      auto ep = EpollMakeUnique<SimpleEpollServer>();
+      ep->set_timeout_in_us(1);
+      EpollReader reader(len);
+      ep->RegisterFD(reader_pipe, &reader, EPOLLIN);
+
+      int64_t start_ms = WallTimeNowInUsec() / 1000;
+      // Loop until we're either done reading, or have waited ~10 us.
+      while (!reader.done_reading() &&
+             (WallTimeNowInUsec() / 1000 - start_ms) < 10000) {
+        ep->WaitForEventsAndExecuteCallbacks();
+      }
+      ep->UnregisterFD(reader_pipe);
+      CHECK(reader.CheckOutput(test_message, len));
+      break;
+    }
+  }
+
+  close(reader_pipe);
+  close(writer_pipe);
+}
+
+TEST(SimpleEpollServerTest, TestSmallPipe) {
+  char buf[kMaxBufLen];
+  TestPipe(buf, 10);
+}
+
+TEST(SimpleEpollServerTest, TestLargePipe) {
+  char buf[kMaxBufLen];
+  TestPipe(buf, kMaxBufLen);
+}
+
+// Tests RegisterFDForRead as well as StopRead.
+TEST(SimpleEpollServerTest, TestRead) {
+  SimpleEpollServer ep;
+  ep.set_timeout_in_us(1);
+  int len = 1;
+
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+  int read_fd = pipe_fds[0];
+  int write_fd = pipe_fds[1];
+
+  auto reader = EpollMakeUnique<EpollReader>(len);
+
+  // Check that registering a FD for read alerts us when there is data to be
+  // read.
+  ep.RegisterFDForRead(read_fd, reader.get());
+  char data = 'a';
+  int size = write(write_fd, &data, 1);
+  EXPECT_EQ(1, size);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(reader->CheckOutput(&data, len));
+
+  // Remove the callback for read events, write to the pipe and make sure that
+  // we did not read more data.
+  ep.StopRead(read_fd);
+  size = write(write_fd, &data, len);
+  EXPECT_EQ(1, size);
+  // The wait will return after timeout.
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(reader->CheckOutput(&data, len));
+  ep.UnregisterFD(read_fd);
+
+  close(read_fd);
+  close(write_fd);
+}
+
+class EdgeTriggerCB : public EpollCallbackInterface {
+ public:
+  EdgeTriggerCB(int read_size, int write_size, char write_char, char peer_char)
+      : eps_(nullptr),
+        read_buf_(read_size),
+        write_buf_(write_size, write_char),
+        peer_char_(peer_char) {
+    Reset();
+  }
+
+  ~EdgeTriggerCB() override {}
+
+  void Reset() {
+    CHECK(eps_ == nullptr);
+    bytes_read_ = 0;
+    bytes_written_ = 0;
+    can_read_ = false;
+    will_read_ = false;
+    can_write_ = false;
+    will_write_ = false;
+    read_closed_ = false;
+    write_closed_ = false;
+  }
+
+  void ResetByteCounts() {
+    bytes_read_ = bytes_written_ = 0;
+  }
+
+  void set_will_read(bool will_read) { will_read_ = will_read; }
+
+  void set_will_write(bool will_write) { will_write_ = will_write; }
+
+  bool can_write() const { return can_write_; }
+
+  int bytes_read() const { return bytes_read_; }
+
+  int bytes_written() const { return bytes_written_; }
+
+  void OnRegistration(SimpleEpollServer* eps, int fd, int event_mask) override {
+    EXPECT_TRUE(eps_ == nullptr);
+    eps_ = eps;
+    Initialize(fd, event_mask);
+  }
+
+  void OnModification(int fd, int event_mask) override {
+    EXPECT_TRUE(eps_ != nullptr);
+    if (event_mask & EPOLLET) {
+      Initialize(fd, event_mask);
+    } else {
+      eps_->SetFDNotReady(fd);
+    }
+  }
+
+  void OnEvent(int fd, EpollEvent* event) override {
+    const int event_mask = event->in_events;
+    if (event_mask & (EPOLLHUP | EPOLLERR)) {
+      write_closed_ = true;
+      return;
+    }
+    if (will_read_ && event_mask & EPOLLIN) {
+      EXPECT_FALSE(read_closed_);
+      int read_size = read_buf_.size();
+      memset(&read_buf_[0], 0, read_size);
+      int len = recv(fd, &read_buf_[0], read_size, MSG_DONTWAIT);
+      // Update the readiness states
+      can_read_ = (len == read_size);
+
+      if (len > 0) {
+        bytes_read_ += len;
+        EPOLL_VLOG(1) << "fd: " << fd << ", read " << len
+                      << ", total: " << bytes_read_;
+        // Now check the bytes read
+        EXPECT_TRUE(CheckReadBuffer(len));
+      } else if (len < 0) {
+        EPOLL_VLOG(1) << "fd: " << fd << " read hit EAGAIN";
+        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
+        can_read_ = false;
+      } else {
+        read_closed_ = true;
+      }
+    }
+    if (will_write_ && event_mask & EPOLLOUT) {
+      // Write side close/full close can only detected by EPOLLHUP, which is
+      // caused by EPIPE.
+      EXPECT_FALSE(write_closed_);
+      int write_size = write_buf_.size();
+      int len = send(fd, &write_buf_[0], write_size, MSG_DONTWAIT);
+      can_write_ = (len == write_size);
+      if (len > 0) {
+        bytes_written_ += len;
+        EPOLL_VLOG(1) << "fd: " << fd << ", write " << len
+                      << ", total: " << bytes_written_;
+      } else {
+        EPOLL_VLOG(1) << "fd: " << fd << " write hit EAGAIN";
+        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
+        can_write_ = false;
+      }
+    }
+    // Since we can only get on the ready list once, wait till we confirm both
+    // read and write side continuation state and set the correct event mask
+    // for the ready list.
+    event->out_ready_mask = can_read_ ? static_cast<int>(EPOLLIN) : 0;
+    if (can_write_) {
+      event->out_ready_mask |= EPOLLOUT;
+    }
+  }
+
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {
+    EXPECT_TRUE(eps_ != nullptr);
+    eps_ = nullptr;
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
+    // None of the current tests involve having active callbacks when the
+    // server shuts down.
+    EPOLL_LOG(FATAL);
+  }
+
+  std::string Name() const override { return "EdgeTriggerCB"; }
+
+ private:
+  SimpleEpollServer* eps_;
+  std::vector<char> read_buf_;
+  int bytes_read_;
+  std::vector<char> write_buf_;
+  int bytes_written_;
+  char peer_char_;   // The char we expected to read.
+  bool can_read_;
+  bool will_read_;
+  bool can_write_;
+  bool will_write_;
+  bool read_closed_;
+  bool write_closed_;
+
+  void Initialize(int fd, int event_mask) {
+    CHECK(eps_);
+    can_read_ = can_write_ = false;
+    if (event_mask & EPOLLET) {
+      int events = 0;
+      if (event_mask & EPOLLIN) {
+        events |= EPOLLIN;
+        can_read_ = true;
+      }
+      if (event_mask & EPOLLOUT) {
+        events |= EPOLLOUT;
+        can_write_ = true;
+      }
+      eps_->SetFDReady(fd, events);
+    }
+  }
+
+  bool CheckReadBuffer(int len) const {
+    for (int i = 0; i < len; ++i) {
+      if (peer_char_ != read_buf_[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+// Test adding and removing from the ready list.
+TEST(SimpleEpollServerTest, TestReadyList) {
+  SimpleEpollServer ep;
+  int pipe_fds[2];
+  if (pipe(pipe_fds) < 0) {
+    EPOLL_PLOG(FATAL) << "pipe() failed";
+  }
+
+  // Just use any CB will do, since we never wait on epoll events.
+  EdgeTriggerCB reader1(0, 0, 0, 0);
+  EdgeTriggerCB reader2(0, 0, 0, 0);
+
+  ep.RegisterFD(pipe_fds[0], &reader1, EPOLLIN);
+  ep.RegisterFD(pipe_fds[1], &reader2, EPOLLOUT);
+
+  // Adding fds that are registered with eps
+  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
+
+  ep.SetFDReady(pipe_fds[0], EPOLLIN);
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
+  EXPECT_EQ(1u, ep.ReadyListSize());
+  ep.SetFDReady(pipe_fds[1], EPOLLOUT);
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
+  EXPECT_EQ(2u, ep.ReadyListSize());
+
+  // Now check that SetFDNotReady doesn't affect other fds
+  ep.SetFDNotReady(pipe_fds[0]);
+  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
+  EXPECT_EQ(1u, ep.ReadyListSize());
+
+  ep.UnregisterFD(pipe_fds[0]);
+  ep.UnregisterFD(pipe_fds[1]);
+  EXPECT_EQ(0u, ep.ReadyListSize());
+
+  // Now try adding them when they are not registered, and it shouldn't work.
+  ep.SetFDReady(pipe_fds[0], EPOLLIN);
+  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_EQ(0u, ep.ReadyListSize());
+
+  close(pipe_fds[0]);
+  close(pipe_fds[1]);
+}
+
+class EPSWaitThread : public EpollThread {
+ public:
+  explicit EPSWaitThread(SimpleEpollServer* eps)
+      : EpollThread("EPSWait"), eps_(eps), done_(false) {}
+
+  void Run() override {
+    eps_->WaitForEventsAndExecuteCallbacks();
+  }
+
+  bool done() { return done_; }
+ private:
+  SimpleEpollServer* eps_;
+  bool done_;
+};
+
+TEST(EpollServerTest, TestWake) {
+  SimpleEpollServer eps;
+  eps.set_timeout_in_us(-1);
+  EPSWaitThread eps_thread(&eps);
+  eps_thread.Start();
+
+  EXPECT_FALSE(eps_thread.done());
+  eps.Wake();
+  eps_thread.Join();
+}
+
+class UnRegisterWhileProcessingCB: public EpollCallbackInterface {
+ public:
+  explicit UnRegisterWhileProcessingCB(int fd) : eps_(nullptr), fd_(fd) {}
+
+  ~UnRegisterWhileProcessingCB() override {
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+
+  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
+    // This should cause no problems.
+    eps_->UnregisterFD(fd_);
+  }
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+  std::string Name() const override { return "UnRegisterWhileProcessingCB"; }
+
+ protected:
+  SimpleEpollServer* eps_;
+  int fd_;
+};
+
+class RegisterWhileProcessingCB: public EpollCallbackInterface {
+ public:
+  RegisterWhileProcessingCB(int fd, EpollCallbackInterface* cb)
+    : eps_(nullptr), fd_(fd), cb_(cb) {}
+
+  ~RegisterWhileProcessingCB() override {
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+
+  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
+    // This should cause no problems.
+    eps_->RegisterFDForReadWrite(fd_, cb_);
+  }
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+  std::string Name() const override { return "RegisterWhileProcessingCB"; }
+
+ protected:
+  SimpleEpollServer* eps_;
+  int fd_;
+  EpollCallbackInterface* cb_;
+};
+
+// Nothing bad should happen when we do this. We're -only-
+// testing that nothing bad occurs in this test.
+TEST(SimpleEpollServerTest, NothingBadWhenUnRegisteringFDWhileProcessingIt) {
+  UnRegisterWhileProcessingCB cb(0);
+  {
+    FakeSimpleEpollServer epoll_server;
+    cb.set_epoll_server(&epoll_server);
+    epoll_server.RegisterFDForReadWrite(0, &cb);
+    epoll_event ee;
+    ee.data.fd = 0;
+    epoll_server.AddEvent(0, ee);
+    epoll_server.AdvanceBy(1);
+    epoll_server.WaitForEventsAndExecuteCallbacks();
+  }
+}
+
+//
+// testing that nothing bad occurs in this test.
+TEST(SimpleEpollServerTest,
+     NoEventsDeliveredForFdsOfUnregisteredCBsWithReRegdFD) {
+  // events: fd0, fd1, fd2
+  // fd0 -> unreg fd2
+  // fd1 -> reg fd2
+  // fd2 -> no event should be seen
+  RecordingCB recorder_cb;
+  UnRegisterWhileProcessingCB unreg_cb(-3);
+  RegisterWhileProcessingCB reg_other_cb(-3, &recorder_cb);
+  {
+    FakeSimpleEpollServer epoll_server;
+    unreg_cb.set_epoll_server(&epoll_server);
+    reg_other_cb.set_epoll_server(&epoll_server);
+    epoll_server.RegisterFDForReadWrite(-1, &unreg_cb);
+    epoll_server.RegisterFDForReadWrite(-2, &reg_other_cb);
+    epoll_server.RegisterFDForReadWrite(-3, &recorder_cb);
+
+    epoll_event ee;
+    ee.events = EPOLLIN;  // asserted for all events for this test.
+
+    // Note that these events are in 'backwards' order in terms of time.
+    // Currently, the SimpleEpollServer code invokes the CBs from last delivered
+    // to first delivered, so this is to be sure that we invoke the CB for -1
+    // before -2, before -3.
+    ee.data.fd = -1;
+    epoll_server.AddEvent(2, ee);
+    ee.data.fd = -2;
+    epoll_server.AddEvent(1, ee);
+    ee.data.fd = -3;
+    epoll_server.AddEvent(0, ee);
+
+    epoll_server.AdvanceBy(5);
+    epoll_server.WaitForEventsAndExecuteCallbacks();
+  }
+
+  Recorder correct_recorder;
+  correct_recorder.Record(&recorder_cb, CREATION, 0, 0);
+  correct_recorder.Record(&recorder_cb, REGISTRATION, -3,
+                          EPOLLIN | EPOLLOUT);
+  correct_recorder.Record(&recorder_cb, UNREGISTRATION, -3, 0);
+  correct_recorder.Record(&recorder_cb, REGISTRATION, -3,
+                          EPOLLIN | EPOLLOUT);
+  correct_recorder.Record(&recorder_cb, SHUTDOWN, -3, 0);
+
+  EXPECT_TRUE(correct_recorder.IsEqual(recorder_cb.recorder()));
+}
+
+class ReRegWhileReadyListOnEvent: public EpollCallbackInterface {
+ public:
+  explicit ReRegWhileReadyListOnEvent(int /*fd*/) : eps_(nullptr) {}
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+
+  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int fd, EpollEvent* /*event_mask*/) override {
+    // This should cause no problems.
+    eps_->UnregisterFD(fd);
+    eps_->RegisterFDForReadWrite(fd, this);
+    eps_->UnregisterFD(fd);
+  }
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+  std::string Name() const override { return "ReRegWhileReadyListOnEvent"; }
+
+ protected:
+  SimpleEpollServer* eps_;
+};
+
+// Nothing bad should happen when we do this. We're -only-
+// testing that nothing bad occurs in this test.
+TEST(SimpleEpollServerTest,
+     NothingBadWhenReRegisteringFDWhileProcessingFromReadyList) {
+  ReRegWhileReadyListOnEvent cb(0);
+  {
+    FakeSimpleEpollServer epoll_server;
+    cb.set_epoll_server(&epoll_server);
+    epoll_server.RegisterFDForReadWrite(0, &cb);
+    epoll_event ee;
+    ee.data.fd = 0;
+    epoll_server.AddEvent(0, ee);
+    epoll_server.AdvanceBy(1);
+    epoll_server.WaitForEventsAndExecuteCallbacks();
+  }
+}
+
+class UnRegEverythingReadyListOnEvent: public EpollCallbackInterface {
+ public:
+  UnRegEverythingReadyListOnEvent() : eps_(nullptr), fd_(0), fd_range_(0) {}
+
+  void set_fd(int fd) { fd_ = fd; }
+  void set_fd_range(int fd_range) { fd_range_ = fd_range; }
+  void set_num_called(int* num_called) { num_called_ = num_called; }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+
+  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
+  void OnRegistration(SimpleEpollServer* eps, int fd,
+                      int /*event_mask*/) override {
+    eps->SetFDReady(fd, EPOLLIN);
+  }
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
+    // This should cause no problems.
+    CHECK(num_called_ != nullptr);
+    ++(*num_called_);
+    // Note that we're iterating from -fd_range + 1 -> 0.
+    // We do this because there is an FD installed into the
+    // epollserver somewhere in the low numbers.
+    // Using negative FD numbers (which are guaranteed to not
+    // exist in the epoll-server) ensures that we will not
+    // come in conflict with the preexisting FD.
+    for (int i = -fd_range_ + 1; i <= 0; ++i) {
+      eps_->UnregisterFD(i);
+    }
+  }
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+  std::string Name() const override {
+    return "UnRegEverythingReadyListOnEvent";
+  }
+
+ protected:
+  SimpleEpollServer* eps_;
+  int fd_;
+  int fd_range_;
+  int* num_called_;
+};
+
+TEST(SimpleEpollServerTest,
+     NothingBadWhenUnRegisteredWhileProcessingFromReadyList) {
+  const size_t kNumCallbacks = 32u;
+  UnRegEverythingReadyListOnEvent callbacks[kNumCallbacks];
+  int num_called = 0;
+  {
+    FakeSimpleEpollServer epoll_server;
+    for (size_t i = 0; i < kNumCallbacks; ++i) {
+      callbacks[i].set_fd(-i);
+      callbacks[i].set_fd_range(kNumCallbacks);
+      callbacks[i].set_num_called(&num_called);
+      callbacks[i].set_epoll_server(&epoll_server);
+      epoll_server.RegisterFDForReadWrite(0, &callbacks[i]);
+      epoll_event ee;
+      ee.data.fd = -i;
+      epoll_server.AddEvent(0, ee);
+    }
+    epoll_server.AdvanceBy(1);
+    epoll_server.WaitForEventsAndExecuteCallbacks();
+    epoll_server.WaitForEventsAndExecuteCallbacks();
+  }
+  EXPECT_EQ(1, num_called);
+}
+
+TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithNothingInList) {
+  FakeSimpleEpollServer epoll_server;
+  epoll_server.VerifyReadyList();
+}
+
+TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithStuffInLists) {
+  FakeSimpleEpollServer epoll_server;
+  epoll_server.VerifyReadyList();
+}
+
+TEST(SimpleEpollServerTest,
+     ApproximateNowInUsAccurateOutideOfWaitForEventsAndExecuteCallbacks) {
+  FakeSimpleEpollServer epoll_server;
+  epoll_server.AdvanceBy(1232);
+  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
+  epoll_server.AdvanceBy(1111);
+  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
+}
+
+class ApproximateNowInUsecTestCB: public EpollCallbackInterface {
+ public:
+  ApproximateNowInUsecTestCB() : feps_(nullptr), called_(false) {}
+
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
+    EXPECT_EQ(feps_->ApproximateNowInUsec(), feps_->NowInUsec());
+    feps_->AdvanceBy(1111);
+    EXPECT_EQ(1 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
+    feps_->AdvanceBy(1111);
+    EXPECT_EQ(2 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
+    called_ = true;
+  }
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+  std::string Name() const override { return "ApproximateNowInUsecTestCB"; }
+
+  void set_fakeepollserver(FakeSimpleEpollServer* feps) { feps_ = feps; }
+  bool called() const { return called_; }
+
+ protected:
+  FakeSimpleEpollServer* feps_;
+  bool called_;
+};
+
+TEST(SimpleEpollServerTest,
+     ApproximateNowInUsApproximateInsideOfWaitForEventsAndExecuteCallbacks) {
+  int dummy_fd = 11111;
+  ApproximateNowInUsecTestCB aniutcb;
+  {
+    FakeSimpleEpollServer epoll_server;
+    aniutcb.set_fakeepollserver(&epoll_server);
+
+    epoll_server.RegisterFD(dummy_fd, &aniutcb, EPOLLIN);
+    epoll_event ee;
+    ee.data.fd = dummy_fd;
+    ee.events = EPOLLIN;
+    epoll_server.AddEvent(10242, ee);
+    epoll_server.set_timeout_in_us(-1);
+    epoll_server.AdvanceByAndWaitForEventsAndExecuteCallbacks(20000);
+    EXPECT_TRUE(aniutcb.called());
+  }
+}
+
+// A mock epoll server that also simulates kernel delay in scheduling epoll
+// events.
+class FakeEpollServerWithDelay : public FakeSimpleEpollServer {
+ public:
+  FakeEpollServerWithDelay() : FakeSimpleEpollServer(), delay(0) {}
+
+  int delay;
+
+ protected:
+  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
+                      int timeout_in_ms) override {
+    int out = FakeSimpleEpollServer::epoll_wait_impl(epfd, events, max_events,
+                                                     timeout_in_ms);
+    AdvanceBy(delay);
+    return out;
+  }
+};
+
+// A callback that records the epoll event's delay.
+class RecordDelayOnEvent: public EpollCallbackInterface {
+ public:
+  RecordDelayOnEvent() : last_delay(-1), eps_(nullptr) {}
+
+  ~RecordDelayOnEvent() override {
+  }
+
+  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
+
+  std::string Name() const override { return "RecordDelayOnEvent"; }
+
+  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
+  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
+    last_delay = eps_->LastDelayInUsec();
+  }
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+
+  int64_t last_delay;
+
+ protected:
+  SimpleEpollServer* eps_;
+};
+
+// Tests that an epoll callback sees the correct delay for its event when it
+// calls LastDelayInUsec().
+TEST(EpollServerTest, TestLastDelay) {
+  RecordDelayOnEvent cb;
+  FakeEpollServerWithDelay epoll_server;
+
+  cb.set_epoll_server(&epoll_server);
+
+  epoll_server.RegisterFDForReadWrite(0, &cb);
+  epoll_event ee;
+  ee.data.fd = 0;
+
+  // Inject delay, and confirm that it's reported.
+  epoll_server.set_timeout_in_us(5000);
+  epoll_server.delay = 6000;
+  epoll_server.AddEvent(0, ee);
+  epoll_server.AdvanceBy(1);
+  epoll_server.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(cb.last_delay, 1000);
+
+  // Fire an event before the timeout ends, and confirm that reported delay
+  // isn't negative.
+  epoll_server.set_timeout_in_us(5000);
+  epoll_server.delay = 0;
+  epoll_server.AddEvent(0, ee);
+  epoll_server.AdvanceBy(1);
+  epoll_server.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(cb.last_delay, 0);
+
+  // Wait forever until an event fires, and confirm there's no reported delay.
+  epoll_server.set_timeout_in_us(-1);
+  epoll_server.delay = 6000;
+  epoll_server.AddEvent(0, ee);
+  epoll_server.AdvanceBy(1);
+  epoll_server.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(cb.last_delay, 0);
+}
+
+TEST(SimpleEpollServerAlarmTest, TestShutdown) {
+  std::unique_ptr<SimpleEpollServer> eps(new SimpleEpollServer);
+  EpollAlarm alarm1;
+  EpollAlarm alarm2;
+
+  eps->RegisterAlarmApproximateDelta(10000000, &alarm1);
+  eps->RegisterAlarmApproximateDelta(10000000, &alarm2);
+
+  alarm2.UnregisterIfRegistered();
+  EXPECT_FALSE(alarm2.registered());
+  eps = nullptr;
+
+  EXPECT_FALSE(alarm1.registered());
+}
+
+TEST(SimpleEpollServerAlarmTest, TestUnregister) {
+  SimpleEpollServer eps;
+  EpollAlarm alarm;
+
+  eps.RegisterAlarmApproximateDelta(10000000, &alarm);
+  EXPECT_TRUE(alarm.registered());
+
+  alarm.UnregisterIfRegistered();
+  EXPECT_FALSE(alarm.registered());
+
+  alarm.UnregisterIfRegistered();
+  EXPECT_FALSE(alarm.registered());
+}
+
+TEST(SimpleEpollServerAlarmTest, TestUnregisterOnDestruction) {
+  EpollTestServer eps;
+  std::unique_ptr<EpollAlarm> alarm(new EpollAlarm());
+  EpollAlarm* alarm_ptr = alarm.get();
+
+  eps.RegisterAlarmApproximateDelta(10000000, alarm.get());
+  EXPECT_TRUE(eps.ContainsAlarm(alarm_ptr));
+  alarm = nullptr;
+  EXPECT_EQ(0u, eps.GetNumPendingAlarmsForTest());
+}
+
+TEST(SimpleEpollServerAlarmTest, TestUnregisterOnAlarm) {
+  EpollTestServer eps;
+  EpollAlarm alarm;
+
+  eps.RegisterAlarmApproximateDelta(1, &alarm);
+  EXPECT_TRUE(eps.ContainsAlarm(&alarm));
+
+  while (alarm.registered()) {
+    eps.WaitForEventsAndExecuteCallbacks();
+  }
+  EXPECT_FALSE(eps.ContainsAlarm(&alarm));
+}
+
+TEST(SimpleEpollServerAlarmTest, TestReregisterAlarm) {
+  EpollTestAlarms ep;
+
+  EpollAlarm alarm;
+  ep.set_time(1000);
+  ep.RegisterAlarm(5000, &alarm);
+
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+  alarm.ReregisterAlarm(6000);
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(5000);
+  ep.set_timeout_in_us(0);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(6000);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
+}
+
+TEST(SimpleEpollServerAlarmTest, TestThatSameAlarmCanNotBeRegisteredTwice) {
+  TestAlarm alarm;
+  SimpleEpollServer epoll_server;
+  epoll_server.RegisterAlarm(1, &alarm);
+  EXPECT_EPOLL_BUG(epoll_server.RegisterAlarm(1, &alarm),
+                   "Alarm already exists");
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace epoll_server
diff --git a/quiche/http2/adapter/adapter_impl_comparison_test.cc b/quiche/http2/adapter/adapter_impl_comparison_test.cc
new file mode 100644
index 0000000..841314b
--- /dev/null
+++ b/quiche/http2/adapter/adapter_impl_comparison_test.cc
@@ -0,0 +1,83 @@
+#include "quiche/http2/adapter/recording_http2_visitor.h"
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/nghttp2_adapter.h"
+#include "quiche/http2/adapter/oghttp2_adapter.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+TEST(AdapterImplComparisonTest, ClientHandlesFrames) {
+  RecordingHttp2Visitor nghttp2_visitor;
+  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
+      NgHttp2Adapter::CreateClientAdapter(nghttp2_visitor);
+
+  RecordingHttp2Visitor oghttp2_visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
+      OgHttp2Adapter::Create(oghttp2_visitor, options);
+
+  const std::string initial_frames = TestFrameSequence()
+                                         .ServerPreface()
+                                         .Ping(42)
+                                         .WindowUpdate(0, 1000)
+                                         .Serialize();
+
+  nghttp2_adapter->ProcessBytes(initial_frames);
+  oghttp2_adapter->ProcessBytes(initial_frames);
+
+  EXPECT_EQ(nghttp2_visitor.GetEventSequence(),
+            oghttp2_visitor.GetEventSequence());
+
+  // TODO(b/181586191): Consider consistent behavior for delivering events on
+  // non-existent streams between nghttp2_adapter and oghttp2_adapter.
+}
+
+TEST(AdapterImplComparisonTest, ServerHandlesFrames) {
+  RecordingHttp2Visitor nghttp2_visitor;
+  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
+      NgHttp2Adapter::CreateServerAdapter(nghttp2_visitor);
+
+  RecordingHttp2Visitor oghttp2_visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
+      OgHttp2Adapter::Create(oghttp2_visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Ping(42)
+                                 .WindowUpdate(0, 1000)
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+
+  nghttp2_adapter->ProcessBytes(frames);
+  oghttp2_adapter->ProcessBytes(frames);
+
+  EXPECT_EQ(nghttp2_visitor.GetEventSequence(),
+            oghttp2_visitor.GetEventSequence());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/callback_visitor.cc b/quiche/http2/adapter/callback_visitor.cc
new file mode 100644
index 0000000..ea782e7
--- /dev/null
+++ b/quiche/http2/adapter/callback_visitor.cc
@@ -0,0 +1,465 @@
+#include "quiche/http2/adapter/callback_visitor.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/http2/adapter/http2_util.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/quiche_endian.h"
+
+// This visitor implementation needs visibility into the
+// nghttp2_session_callbacks type. There's no public header, so we'll redefine
+// the struct here.
+struct nghttp2_session_callbacks {
+  nghttp2_send_callback send_callback;
+  nghttp2_recv_callback recv_callback;
+  nghttp2_on_frame_recv_callback on_frame_recv_callback;
+  nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
+  nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
+  nghttp2_before_frame_send_callback before_frame_send_callback;
+  nghttp2_on_frame_send_callback on_frame_send_callback;
+  nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
+  nghttp2_on_stream_close_callback on_stream_close_callback;
+  nghttp2_on_begin_headers_callback on_begin_headers_callback;
+  nghttp2_on_header_callback on_header_callback;
+  nghttp2_on_header_callback2 on_header_callback2;
+  nghttp2_on_invalid_header_callback on_invalid_header_callback;
+  nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
+  nghttp2_select_padding_callback select_padding_callback;
+  nghttp2_data_source_read_length_callback read_length_callback;
+  nghttp2_on_begin_frame_callback on_begin_frame_callback;
+  nghttp2_send_data_callback send_data_callback;
+  nghttp2_pack_extension_callback pack_extension_callback;
+  nghttp2_unpack_extension_callback unpack_extension_callback;
+  nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
+  nghttp2_error_callback error_callback;
+  nghttp2_error_callback2 error_callback2;
+};
+
+namespace http2 {
+namespace adapter {
+
+CallbackVisitor::CallbackVisitor(Perspective perspective,
+                                 const nghttp2_session_callbacks& callbacks,
+                                 void* user_data)
+    : perspective_(perspective),
+      callbacks_(MakeCallbacksPtr(nullptr)),
+      user_data_(user_data) {
+  nghttp2_session_callbacks* c;
+  nghttp2_session_callbacks_new(&c);
+  *c = callbacks;
+  callbacks_ = MakeCallbacksPtr(c);
+}
+
+int64_t CallbackVisitor::OnReadyToSend(absl::string_view serialized) {
+  if (!callbacks_->send_callback) {
+    return kSendError;
+  }
+  int64_t result = callbacks_->send_callback(
+      nullptr, ToUint8Ptr(serialized.data()), serialized.size(), 0, user_data_);
+  QUICHE_VLOG(1) << "CallbackVisitor::OnReadyToSend called with "
+                 << serialized.size() << " bytes, returning " << result;
+  QUICHE_VLOG(2) << (perspective_ == Perspective::kClient ? "Client" : "Server")
+                 << " sending: [" << absl::CEscape(serialized) << "]";
+  if (result > 0) {
+    return result;
+  } else if (result == NGHTTP2_ERR_WOULDBLOCK) {
+    return kSendBlocked;
+  } else {
+    return kSendError;
+  }
+}
+
+void CallbackVisitor::OnConnectionError(ConnectionError /*error*/) {
+  QUICHE_VLOG(1) << "OnConnectionError not implemented";
+}
+
+bool CallbackVisitor::OnFrameHeader(Http2StreamId stream_id, size_t length,
+                                    uint8_t type, uint8_t flags) {
+  QUICHE_VLOG(1) << "CallbackVisitor::OnFrameHeader(stream_id=" << stream_id
+                 << ", type=" << int(type) << ", length=" << length
+                 << ", flags=" << int(flags) << ")";
+  if (static_cast<FrameType>(type) == FrameType::CONTINUATION) {
+    // Treat CONTINUATION as HEADERS
+    QUICHE_DCHECK_EQ(current_frame_.hd.stream_id, stream_id);
+    current_frame_.hd.length += length;
+    current_frame_.hd.flags |= flags;
+    QUICHE_DLOG_IF(ERROR, length == 0) << "Empty CONTINUATION!";
+    // Still need to deliver the CONTINUATION to the begin frame callback.
+    nghttp2_frame_hd hd;
+    memset(&hd, 0, sizeof(hd));
+    hd.stream_id = stream_id;
+    hd.length = length;
+    hd.type = type;
+    hd.flags = flags;
+    if (callbacks_->on_begin_frame_callback) {
+      const int result =
+          callbacks_->on_begin_frame_callback(nullptr, &hd, user_data_);
+      return result == 0;
+    }
+    return true;
+  }
+  // The general strategy is to clear |current_frame_| at the start of a new
+  // frame, accumulate frame information from the various callback events, then
+  // invoke the on_frame_recv_callback() with the accumulated frame data.
+  memset(&current_frame_, 0, sizeof(current_frame_));
+  current_frame_.hd.stream_id = stream_id;
+  current_frame_.hd.length = length;
+  current_frame_.hd.type = type;
+  current_frame_.hd.flags = flags;
+  if (callbacks_->on_begin_frame_callback) {
+    const int result = callbacks_->on_begin_frame_callback(
+        nullptr, &current_frame_.hd, user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+void CallbackVisitor::OnSettingsStart() {}
+
+void CallbackVisitor::OnSetting(Http2Setting setting) {
+  settings_.push_back({setting.id, setting.value});
+}
+
+void CallbackVisitor::OnSettingsEnd() {
+  current_frame_.settings.niv = settings_.size();
+  current_frame_.settings.iv = settings_.data();
+  QUICHE_VLOG(1) << "OnSettingsEnd, received settings of size "
+                 << current_frame_.settings.niv;
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    QUICHE_DCHECK_EQ(0, result);
+  }
+  settings_.clear();
+}
+
+void CallbackVisitor::OnSettingsAck() {
+  // ACK is part of the flags, which were set in OnFrameHeader().
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    QUICHE_DCHECK_EQ(0, result);
+  }
+}
+
+bool CallbackVisitor::OnBeginHeadersForStream(Http2StreamId stream_id) {
+  auto it = GetStreamInfo(stream_id);
+  if (it->second.received_headers) {
+    // At least one headers frame has already been received.
+    QUICHE_VLOG(1)
+        << "Headers already received for stream " << stream_id
+        << ", these are trailers or headers following a 100 response";
+    current_frame_.headers.cat = NGHTTP2_HCAT_HEADERS;
+  } else {
+    switch (perspective_) {
+      case Perspective::kClient:
+        QUICHE_VLOG(1) << "First headers at the client for stream " << stream_id
+                       << "; these are response headers";
+        current_frame_.headers.cat = NGHTTP2_HCAT_RESPONSE;
+        break;
+      case Perspective::kServer:
+        QUICHE_VLOG(1) << "First headers at the server for stream " << stream_id
+                       << "; these are request headers";
+        current_frame_.headers.cat = NGHTTP2_HCAT_REQUEST;
+        break;
+    }
+  }
+  it->second.received_headers = true;
+  if (callbacks_->on_begin_headers_callback) {
+    const int result = callbacks_->on_begin_headers_callback(
+        nullptr, &current_frame_, user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+Http2VisitorInterface::OnHeaderResult CallbackVisitor::OnHeaderForStream(
+    Http2StreamId /*stream_id*/, absl::string_view name,
+    absl::string_view value) {
+  if (callbacks_->on_header_callback) {
+    const int result = callbacks_->on_header_callback(
+        nullptr, &current_frame_, ToUint8Ptr(name.data()), name.size(),
+        ToUint8Ptr(value.data()), value.size(), NGHTTP2_NV_FLAG_NONE,
+        user_data_);
+    if (result == 0) {
+      return HEADER_OK;
+    } else if (result == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+      return HEADER_RST_STREAM;
+    } else {
+      // Assume NGHTTP2_ERR_CALLBACK_FAILURE.
+      return HEADER_CONNECTION_ERROR;
+    }
+  }
+  return HEADER_OK;
+}
+
+bool CallbackVisitor::OnEndHeadersForStream(Http2StreamId /*stream_id*/) {
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+bool CallbackVisitor::OnDataPaddingLength(Http2StreamId /*stream_id*/,
+                                          size_t padding_length) {
+  QUICHE_DCHECK_GE(remaining_data_, padding_length);
+  current_frame_.data.padlen = padding_length;
+  remaining_data_ -= padding_length;
+  if (remaining_data_ == 0 && callbacks_->on_frame_recv_callback != nullptr) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+bool CallbackVisitor::OnBeginDataForStream(Http2StreamId /*stream_id*/,
+                                           size_t payload_length) {
+  remaining_data_ = payload_length;
+  if (remaining_data_ == 0 && callbacks_->on_frame_recv_callback != nullptr) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+bool CallbackVisitor::OnDataForStream(Http2StreamId stream_id,
+                                      absl::string_view data) {
+  int result = 0;
+  if (callbacks_->on_data_chunk_recv_callback) {
+    result = callbacks_->on_data_chunk_recv_callback(
+        nullptr, current_frame_.hd.flags, stream_id, ToUint8Ptr(data.data()),
+        data.size(), user_data_);
+  }
+  remaining_data_ -= data.size();
+  if (result == 0 && remaining_data_ == 0 &&
+      callbacks_->on_frame_recv_callback) {
+    result = callbacks_->on_frame_recv_callback(nullptr, &current_frame_,
+                                                user_data_);
+  }
+  return result == 0;
+}
+
+void CallbackVisitor::OnEndStream(Http2StreamId /*stream_id*/) {}
+
+void CallbackVisitor::OnRstStream(Http2StreamId /*stream_id*/,
+                                  Http2ErrorCode error_code) {
+  current_frame_.rst_stream.error_code = static_cast<uint32_t>(error_code);
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    QUICHE_DCHECK_EQ(0, result);
+  }
+}
+
+bool CallbackVisitor::OnCloseStream(Http2StreamId stream_id,
+                                    Http2ErrorCode error_code) {
+  int result = 0;
+  if (callbacks_->on_stream_close_callback) {
+    QUICHE_VLOG(1) << "OnCloseStream(stream_id: " << stream_id
+                   << ", error_code: " << int(error_code) << ")";
+    result = callbacks_->on_stream_close_callback(
+        nullptr, stream_id, static_cast<uint32_t>(error_code), user_data_);
+  }
+  stream_map_.erase(stream_id);
+  if (stream_close_listener_) {
+    stream_close_listener_(stream_id);
+  }
+  return result == 0;
+}
+
+void CallbackVisitor::OnPriorityForStream(Http2StreamId /*stream_id*/,
+                                          Http2StreamId parent_stream_id,
+                                          int weight, bool exclusive) {
+  current_frame_.priority.pri_spec.stream_id = parent_stream_id;
+  current_frame_.priority.pri_spec.weight = weight;
+  current_frame_.priority.pri_spec.exclusive = exclusive;
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    QUICHE_DCHECK_EQ(0, result);
+  }
+}
+
+void CallbackVisitor::OnPing(Http2PingId ping_id, bool /*is_ack*/) {
+  uint64_t network_order_opaque_data =
+      quiche::QuicheEndian::HostToNet64(ping_id);
+  std::memcpy(current_frame_.ping.opaque_data, &network_order_opaque_data,
+              sizeof(network_order_opaque_data));
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    QUICHE_DCHECK_EQ(0, result);
+  }
+}
+
+void CallbackVisitor::OnPushPromiseForStream(
+    Http2StreamId /*stream_id*/, Http2StreamId /*promised_stream_id*/) {
+  QUICHE_LOG(DFATAL) << "Not implemented";
+}
+
+bool CallbackVisitor::OnGoAway(Http2StreamId last_accepted_stream_id,
+                               Http2ErrorCode error_code,
+                               absl::string_view opaque_data) {
+  current_frame_.goaway.last_stream_id = last_accepted_stream_id;
+  current_frame_.goaway.error_code = static_cast<uint32_t>(error_code);
+  current_frame_.goaway.opaque_data = ToUint8Ptr(opaque_data.data());
+  current_frame_.goaway.opaque_data_len = opaque_data.size();
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+void CallbackVisitor::OnWindowUpdate(Http2StreamId /*stream_id*/,
+                                     int window_increment) {
+  current_frame_.window_update.window_size_increment = window_increment;
+  if (callbacks_->on_frame_recv_callback) {
+    const int result = callbacks_->on_frame_recv_callback(
+        nullptr, &current_frame_, user_data_);
+    QUICHE_DCHECK_EQ(0, result);
+  }
+}
+
+void CallbackVisitor::PopulateFrame(nghttp2_frame& frame, uint8_t frame_type,
+                                    Http2StreamId stream_id, size_t length,
+                                    uint8_t flags, uint32_t error_code,
+                                    bool sent_headers) {
+  frame.hd.type = frame_type;
+  frame.hd.stream_id = stream_id;
+  frame.hd.length = length;
+  frame.hd.flags = flags;
+  const FrameType frame_type_enum = static_cast<FrameType>(frame_type);
+  if (frame_type_enum == FrameType::HEADERS) {
+    if (sent_headers) {
+      frame.headers.cat = NGHTTP2_HCAT_HEADERS;
+    } else {
+      switch (perspective_) {
+        case Perspective::kClient:
+          QUICHE_VLOG(1) << "First headers sent by the client for stream "
+                         << stream_id << "; these are request headers";
+          frame.headers.cat = NGHTTP2_HCAT_REQUEST;
+          break;
+        case Perspective::kServer:
+          QUICHE_VLOG(1) << "First headers sent by the server for stream "
+                         << stream_id << "; these are response headers";
+          frame.headers.cat = NGHTTP2_HCAT_RESPONSE;
+          break;
+      }
+    }
+  } else if (frame_type_enum == FrameType::RST_STREAM) {
+    frame.rst_stream.error_code = error_code;
+  } else if (frame_type_enum == FrameType::GOAWAY) {
+    frame.goaway.error_code = error_code;
+  }
+}
+
+int CallbackVisitor::OnBeforeFrameSent(uint8_t frame_type,
+                                       Http2StreamId stream_id, size_t length,
+                                       uint8_t flags) {
+  if (callbacks_->before_frame_send_callback) {
+    QUICHE_VLOG(1) << "OnBeforeFrameSent(stream_id=" << stream_id
+                   << ", type=" << int(frame_type) << ", length=" << length
+                   << ", flags=" << int(flags) << ")";
+    nghttp2_frame frame;
+    auto it = GetStreamInfo(stream_id);
+    // The implementation of the before_frame_send_callback doesn't look at the
+    // error code, so for now it's populated with 0.
+    PopulateFrame(frame, frame_type, stream_id, length, flags, /*error_code=*/0,
+                  it->second.before_sent_headers);
+    it->second.before_sent_headers = true;
+    return callbacks_->before_frame_send_callback(nullptr, &frame, user_data_);
+  }
+  return 0;
+}
+
+int CallbackVisitor::OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
+                                 size_t length, uint8_t flags,
+                                 uint32_t error_code) {
+  if (callbacks_->on_frame_send_callback) {
+    QUICHE_VLOG(1) << "OnFrameSent(stream_id=" << stream_id
+                   << ", type=" << int(frame_type) << ", length=" << length
+                   << ", flags=" << int(flags) << ", error_code=" << error_code
+                   << ")";
+    nghttp2_frame frame;
+    auto it = GetStreamInfo(stream_id);
+    PopulateFrame(frame, frame_type, stream_id, length, flags, error_code,
+                  it->second.sent_headers);
+    it->second.sent_headers = true;
+    return callbacks_->on_frame_send_callback(nullptr, &frame, user_data_);
+  }
+  return 0;
+}
+
+bool CallbackVisitor::OnInvalidFrame(Http2StreamId stream_id,
+                                     InvalidFrameError error) {
+  QUICHE_VLOG(1) << "OnInvalidFrame(" << stream_id << ", "
+                 << InvalidFrameErrorToString(error) << ")";
+  QUICHE_DCHECK_EQ(stream_id, current_frame_.hd.stream_id);
+  if (callbacks_->on_invalid_frame_recv_callback) {
+    return 0 ==
+           callbacks_->on_invalid_frame_recv_callback(
+               nullptr, &current_frame_, ToNgHttp2ErrorCode(error), user_data_);
+  }
+  return true;
+}
+
+void CallbackVisitor::OnBeginMetadataForStream(Http2StreamId stream_id,
+                                               size_t payload_length) {
+  QUICHE_VLOG(1) << "OnBeginMetadataForStream(stream_id=" << stream_id
+                 << ", payload_length=" << payload_length << ")";
+}
+
+bool CallbackVisitor::OnMetadataForStream(Http2StreamId stream_id,
+                                          absl::string_view metadata) {
+  QUICHE_VLOG(1) << "OnMetadataForStream(stream_id=" << stream_id
+                 << ", len=" << metadata.size() << ")";
+  if (callbacks_->on_extension_chunk_recv_callback) {
+    int result = callbacks_->on_extension_chunk_recv_callback(
+        nullptr, &current_frame_.hd, ToUint8Ptr(metadata.data()),
+        metadata.size(), user_data_);
+    return result == 0;
+  }
+  return true;
+}
+
+bool CallbackVisitor::OnMetadataEndForStream(Http2StreamId stream_id) {
+  QUICHE_LOG_IF(DFATAL, current_frame_.hd.flags != kMetadataEndFlag);
+  QUICHE_VLOG(1) << "OnMetadataEndForStream(stream_id=" << stream_id << ")";
+  if (callbacks_->unpack_extension_callback) {
+    void* payload;
+    int result = callbacks_->unpack_extension_callback(
+        nullptr, &payload, &current_frame_.hd, user_data_);
+    if (result == 0 && callbacks_->on_frame_recv_callback) {
+      current_frame_.ext.payload = payload;
+      result = callbacks_->on_frame_recv_callback(nullptr, &current_frame_,
+                                                  user_data_);
+    }
+    return (result == 0);
+  }
+  return true;
+}
+
+void CallbackVisitor::OnErrorDebug(absl::string_view message) {
+  if (callbacks_->error_callback2) {
+    callbacks_->error_callback2(nullptr, -1, message.data(), message.size(),
+                                user_data_);
+  }
+}
+
+CallbackVisitor::StreamInfoMap::iterator CallbackVisitor::GetStreamInfo(
+    Http2StreamId stream_id) {
+  auto it = stream_map_.find(stream_id);
+  if (it == stream_map_.end()) {
+    auto p = stream_map_.insert({stream_id, {}});
+    it = p.first;
+  }
+  return it;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/callback_visitor.h b/quiche/http2/adapter/callback_visitor.h
new file mode 100644
index 0000000..06e8e0c
--- /dev/null
+++ b/quiche/http2/adapter/callback_visitor.h
@@ -0,0 +1,114 @@
+#ifndef QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_
+#define QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_
+
+#include <cstdint>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+// This visitor implementation accepts a set of nghttp2 callbacks and a "user
+// data" pointer, and invokes the callbacks according to HTTP/2 events received.
+class QUICHE_EXPORT_PRIVATE CallbackVisitor : public Http2VisitorInterface {
+ public:
+  // Called when the visitor receives a close event for `stream_id`.
+  using StreamCloseListener = std::function<void(Http2StreamId stream_id)>;
+
+  explicit CallbackVisitor(Perspective perspective,
+                           const nghttp2_session_callbacks& callbacks,
+                           void* user_data);
+
+  int64_t OnReadyToSend(absl::string_view serialized) override;
+  void OnConnectionError(ConnectionError error) override;
+  bool OnFrameHeader(Http2StreamId stream_id, size_t length, uint8_t type,
+                     uint8_t flags) override;
+  void OnSettingsStart() override;
+  void OnSetting(Http2Setting setting) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck() override;
+  bool OnBeginHeadersForStream(Http2StreamId stream_id) override;
+  OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
+                                   absl::string_view name,
+                                   absl::string_view value) override;
+  bool OnEndHeadersForStream(Http2StreamId stream_id) override;
+  bool OnDataPaddingLength(Http2StreamId stream_id,
+                           size_t padding_length) override;
+  bool OnBeginDataForStream(Http2StreamId stream_id,
+                            size_t payload_length) override;
+  bool OnDataForStream(Http2StreamId stream_id,
+                       absl::string_view data) override;
+  void OnEndStream(Http2StreamId stream_id) override;
+  void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
+  bool OnCloseStream(Http2StreamId stream_id,
+                     Http2ErrorCode error_code) override;
+  void OnPriorityForStream(Http2StreamId stream_id,
+                           Http2StreamId parent_stream_id,
+                           int weight,
+                           bool exclusive) override;
+  void OnPing(Http2PingId ping_id, bool is_ack) override;
+  void OnPushPromiseForStream(Http2StreamId stream_id,
+                              Http2StreamId promised_stream_id) override;
+  bool OnGoAway(Http2StreamId last_accepted_stream_id,
+                Http2ErrorCode error_code,
+                absl::string_view opaque_data) override;
+  void OnWindowUpdate(Http2StreamId stream_id, int window_increment) override;
+  int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
+                        size_t length, uint8_t flags) override;
+  int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length,
+                  uint8_t flags, uint32_t error_code) override;
+  bool OnInvalidFrame(Http2StreamId stream_id,
+                      InvalidFrameError error) override;
+  void OnBeginMetadataForStream(Http2StreamId stream_id,
+                                size_t payload_length) override;
+  bool OnMetadataForStream(Http2StreamId stream_id,
+                           absl::string_view metadata) override;
+  bool OnMetadataEndForStream(Http2StreamId stream_id) override;
+  void OnErrorDebug(absl::string_view message) override;
+
+  size_t stream_map_size() const { return stream_map_.size(); }
+
+  void set_stream_close_listener(StreamCloseListener stream_close_listener) {
+    stream_close_listener_ = std::move(stream_close_listener);
+  }
+
+ private:
+  struct QUICHE_EXPORT_PRIVATE StreamInfo {
+    bool before_sent_headers = false;
+    bool sent_headers = false;
+    bool received_headers = false;
+  };
+
+  using StreamInfoMap = absl::flat_hash_map<Http2StreamId, StreamInfo>;
+
+  void PopulateFrame(nghttp2_frame& frame, uint8_t frame_type,
+                     Http2StreamId stream_id, size_t length, uint8_t flags,
+                     uint32_t error_code, bool sent_headers);
+
+  // Creates the StreamInfoMap entry if it doesn't exist.
+  StreamInfoMap::iterator GetStreamInfo(Http2StreamId stream_id);
+
+  StreamInfoMap stream_map_;
+
+  StreamCloseListener stream_close_listener_;
+
+  Perspective perspective_;
+  nghttp2_session_callbacks_unique_ptr callbacks_;
+  void* user_data_;
+
+  nghttp2_frame current_frame_;
+  std::vector<nghttp2_settings_entry> settings_;
+  size_t remaining_data_ = 0;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_
diff --git a/quiche/http2/adapter/callback_visitor_test.cc b/quiche/http2/adapter/callback_visitor_test.cc
new file mode 100644
index 0000000..3a42f53
--- /dev/null
+++ b/quiche/http2/adapter/callback_visitor_test.cc
@@ -0,0 +1,434 @@
+#include "quiche/http2/adapter/callback_visitor.h"
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/mock_nghttp2_callbacks.h"
+#include "quiche/http2/adapter/nghttp2_test_utils.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::IsEmpty;
+using testing::Pair;
+using testing::UnorderedElementsAre;
+
+enum FrameType {
+  DATA,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+  CONTINUATION,
+};
+
+// Tests connection-level events.
+TEST(ClientCallbackVisitorUnitTest, ConnectionFrames) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kClient,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+  testing::InSequence seq;
+
+  // SETTINGS
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));
+  visitor.OnFrameHeader(0, 0, SETTINGS, 0);
+
+  visitor.OnSettingsStart();
+  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
+  visitor.OnSettingsEnd();
+
+  // PING
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, PING, _)));
+  visitor.OnFrameHeader(0, 8, PING, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsPing(42)));
+  visitor.OnPing(42, false);
+
+  // WINDOW_UPDATE
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, _)));
+  visitor.OnFrameHeader(0, 4, WINDOW_UPDATE, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsWindowUpdate(1000)));
+  visitor.OnWindowUpdate(0, 1000);
+
+  // PING ack
+  EXPECT_CALL(callbacks,
+              OnBeginFrame(HasFrameHeader(0, PING, NGHTTP2_FLAG_ACK)));
+  visitor.OnFrameHeader(0, 8, PING, 1);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsPingAck(247)));
+  visitor.OnPing(247, true);
+
+  // GOAWAY
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, GOAWAY, 0)));
+  visitor.OnFrameHeader(0, 19, GOAWAY, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsGoAway(5, NGHTTP2_ENHANCE_YOUR_CALM,
+                                              "calm down!!")));
+  visitor.OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!");
+
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+}
+
+TEST(ClientCallbackVisitorUnitTest, StreamFrames) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kClient,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+  absl::flat_hash_map<Http2StreamId, int> stream_close_counts;
+  visitor.set_stream_close_listener(
+      [&stream_close_counts](Http2StreamId stream_id) {
+        ++stream_close_counts[stream_id];
+      });
+
+  testing::InSequence seq;
+
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+
+  // HEADERS on stream 1
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
+  visitor.OnFrameHeader(1, 23, HEADERS, 4);
+
+  EXPECT_CALL(callbacks,
+              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
+  visitor.OnBeginHeadersForStream(1);
+
+  EXPECT_EQ(visitor.stream_map_size(), 1);
+
+  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
+  visitor.OnHeaderForStream(1, ":status", "200");
+
+  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
+  visitor.OnHeaderForStream(1, "server", "my-fake-server");
+
+  EXPECT_CALL(callbacks,
+              OnHeader(_, "date", "Tue, 6 Apr 2021 12:54:01 GMT", _));
+  visitor.OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT");
+
+  EXPECT_CALL(callbacks, OnHeader(_, "trailer", "x-server-status", _));
+  visitor.OnHeaderForStream(1, "trailer", "x-server-status");
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
+  visitor.OnEndHeadersForStream(1);
+
+  // DATA for stream 1
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, DATA, 0)));
+  visitor.OnFrameHeader(1, 26, DATA, 0);
+
+  visitor.OnBeginDataForStream(1, 26);
+  EXPECT_CALL(callbacks, OnDataChunkRecv(0, 1, "This is the response body."));
+  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, 0)));
+  visitor.OnDataForStream(1, "This is the response body.");
+
+  // Trailers for stream 1, with a different nghttp2 "category".
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
+  visitor.OnFrameHeader(1, 23, HEADERS, 4);
+
+  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_HEADERS)));
+  visitor.OnBeginHeadersForStream(1);
+
+  EXPECT_CALL(callbacks, OnHeader(_, "x-server-status", "OK", _));
+  visitor.OnHeaderForStream(1, "x-server-status", "OK");
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_HEADERS)));
+  visitor.OnEndHeadersForStream(1);
+
+  EXPECT_THAT(stream_close_counts, IsEmpty());
+
+  // RST_STREAM on stream 3
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, RST_STREAM, 0)));
+  visitor.OnFrameHeader(3, 4, RST_STREAM, 0);
+
+  // No change in stream map size.
+  EXPECT_EQ(visitor.stream_map_size(), 1);
+  EXPECT_THAT(stream_close_counts, IsEmpty());
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(3, NGHTTP2_INTERNAL_ERROR)));
+  visitor.OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR);
+
+  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_INTERNAL_ERROR));
+  visitor.OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR);
+
+  EXPECT_THAT(stream_close_counts, UnorderedElementsAre(Pair(3, 1)));
+
+  // More stream close events
+  EXPECT_CALL(callbacks,
+              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));
+  visitor.OnFrameHeader(1, 0, DATA, 1);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
+  visitor.OnBeginDataForStream(1, 0);
+  visitor.OnEndStream(1);
+
+  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
+  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
+
+  // Stream map is empty again after both streams were closed.
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+  EXPECT_THAT(stream_close_counts,
+              UnorderedElementsAre(Pair(3, 1), Pair(1, 1)));
+
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(5, RST_STREAM, _)));
+  visitor.OnFrameHeader(5, 4, RST_STREAM, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(5, NGHTTP2_REFUSED_STREAM)));
+  visitor.OnRstStream(5, Http2ErrorCode::REFUSED_STREAM);
+
+  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_REFUSED_STREAM));
+  visitor.OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM);
+
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+  EXPECT_THAT(stream_close_counts,
+              UnorderedElementsAre(Pair(3, 1), Pair(1, 1), Pair(5, 1)));
+}
+
+TEST(ClientCallbackVisitorUnitTest, HeadersWithContinuation) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kClient,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+  testing::InSequence seq;
+
+  // HEADERS on stream 1
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, 0x0)));
+  visitor.OnFrameHeader(1, 23, HEADERS, 0x0);
+
+  EXPECT_CALL(callbacks,
+              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
+  visitor.OnBeginHeadersForStream(1);
+
+  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
+  visitor.OnHeaderForStream(1, ":status", "200");
+
+  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
+  visitor.OnHeaderForStream(1, "server", "my-fake-server");
+
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, CONTINUATION, 0x4)));
+  visitor.OnFrameHeader(1, 23, CONTINUATION, 0x4);
+
+  EXPECT_CALL(callbacks,
+              OnHeader(_, "date", "Tue, 6 Apr 2021 12:54:01 GMT", _));
+  visitor.OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT");
+
+  EXPECT_CALL(callbacks, OnHeader(_, "trailer", "x-server-status", _));
+  visitor.OnHeaderForStream(1, "trailer", "x-server-status");
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
+  visitor.OnEndHeadersForStream(1);
+}
+
+TEST(ClientCallbackVisitorUnitTest, ResetAndGoaway) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kClient,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+  testing::InSequence seq;
+
+  // RST_STREAM on stream 1
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, RST_STREAM, 0x0)));
+  EXPECT_TRUE(visitor.OnFrameHeader(1, 13, RST_STREAM, 0x0));
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(1, NGHTTP2_INTERNAL_ERROR)));
+  visitor.OnRstStream(1, Http2ErrorCode::INTERNAL_ERROR);
+
+  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_INTERNAL_ERROR));
+  EXPECT_TRUE(visitor.OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
+
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, GOAWAY, 0x0)));
+  EXPECT_TRUE(visitor.OnFrameHeader(0, 13, GOAWAY, 0x0));
+
+  EXPECT_CALL(callbacks,
+              OnFrameRecv(IsGoAway(3, NGHTTP2_ENHANCE_YOUR_CALM, "calma te")));
+  EXPECT_TRUE(
+      visitor.OnGoAway(3, Http2ErrorCode::ENHANCE_YOUR_CALM, "calma te"));
+
+  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_STREAM_CLOSED))
+      .WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
+  EXPECT_FALSE(visitor.OnCloseStream(5, Http2ErrorCode::STREAM_CLOSED));
+}
+
+TEST(ServerCallbackVisitorUnitTest, ConnectionFrames) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kServer,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+  testing::InSequence seq;
+
+  // SETTINGS
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));
+  visitor.OnFrameHeader(0, 0, SETTINGS, 0);
+
+  visitor.OnSettingsStart();
+  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
+  visitor.OnSettingsEnd();
+
+  // PING
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, PING, _)));
+  visitor.OnFrameHeader(0, 8, PING, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsPing(42)));
+  visitor.OnPing(42, false);
+
+  // WINDOW_UPDATE
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, _)));
+  visitor.OnFrameHeader(0, 4, WINDOW_UPDATE, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsWindowUpdate(1000)));
+  visitor.OnWindowUpdate(0, 1000);
+
+  // PING ack
+  EXPECT_CALL(callbacks,
+              OnBeginFrame(HasFrameHeader(0, PING, NGHTTP2_FLAG_ACK)));
+  visitor.OnFrameHeader(0, 8, PING, 1);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsPingAck(247)));
+  visitor.OnPing(247, true);
+
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+}
+
+TEST(ServerCallbackVisitorUnitTest, StreamFrames) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kServer,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+  testing::InSequence seq;
+
+  // HEADERS on stream 1
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(
+                             1, HEADERS, NGHTTP2_FLAG_END_HEADERS)));
+  visitor.OnFrameHeader(1, 23, HEADERS, 4);
+
+  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
+                                                  NGHTTP2_HCAT_REQUEST)));
+  visitor.OnBeginHeadersForStream(1);
+
+  EXPECT_EQ(visitor.stream_map_size(), 1);
+
+  EXPECT_CALL(callbacks, OnHeader(_, ":method", "POST", _));
+  visitor.OnHeaderForStream(1, ":method", "POST");
+
+  EXPECT_CALL(callbacks, OnHeader(_, ":path", "/example/path", _));
+  visitor.OnHeaderForStream(1, ":path", "/example/path");
+
+  EXPECT_CALL(callbacks, OnHeader(_, ":scheme", "https", _));
+  visitor.OnHeaderForStream(1, ":scheme", "https");
+
+  EXPECT_CALL(callbacks, OnHeader(_, ":authority", "example.com", _));
+  visitor.OnHeaderForStream(1, ":authority", "example.com");
+
+  EXPECT_CALL(callbacks, OnHeader(_, "accept", "text/html", _));
+  visitor.OnHeaderForStream(1, "accept", "text/html");
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
+                                               NGHTTP2_HCAT_REQUEST)));
+  visitor.OnEndHeadersForStream(1);
+
+  // DATA on stream 1
+  EXPECT_CALL(callbacks,
+              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));
+  visitor.OnFrameHeader(1, 25, DATA, NGHTTP2_FLAG_END_STREAM);
+
+  visitor.OnBeginDataForStream(1, 25);
+  EXPECT_CALL(callbacks, OnDataChunkRecv(NGHTTP2_FLAG_END_STREAM, 1,
+                                         "This is the request body."));
+  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
+  visitor.OnDataForStream(1, "This is the request body.");
+  visitor.OnEndStream(1);
+
+  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
+  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
+
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+
+  // RST_STREAM on stream 3
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, RST_STREAM, 0)));
+  visitor.OnFrameHeader(3, 4, RST_STREAM, 0);
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(3, NGHTTP2_INTERNAL_ERROR)));
+  visitor.OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR);
+
+  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_INTERNAL_ERROR));
+  visitor.OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR);
+
+  EXPECT_EQ(visitor.stream_map_size(), 0);
+}
+
+TEST(ServerCallbackVisitorUnitTest, DataWithPadding) {
+  testing::StrictMock<MockNghttp2Callbacks> callbacks;
+  CallbackVisitor visitor(Perspective::kServer,
+                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
+
+  const size_t kPaddingLength = 39;
+  const uint8_t kFlags = NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_END_STREAM;
+
+  testing::InSequence seq;
+
+  // DATA on stream 1
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, DATA, kFlags)));
+  EXPECT_TRUE(visitor.OnFrameHeader(1, 25 + kPaddingLength, DATA, kFlags));
+
+  EXPECT_TRUE(visitor.OnBeginDataForStream(1, 25 + kPaddingLength));
+
+  // Padding before data.
+  EXPECT_TRUE(visitor.OnDataPaddingLength(1, kPaddingLength));
+
+  EXPECT_CALL(callbacks,
+              OnDataChunkRecv(kFlags, 1, "This is the request body."));
+  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, kFlags, kPaddingLength)));
+  EXPECT_TRUE(visitor.OnDataForStream(1, "This is the request body."));
+  visitor.OnEndStream(1);
+
+  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
+  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);
+
+  // DATA on stream 3
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, DATA, kFlags)));
+  EXPECT_TRUE(visitor.OnFrameHeader(3, 25 + kPaddingLength, DATA, kFlags));
+
+  EXPECT_TRUE(visitor.OnBeginDataForStream(3, 25 + kPaddingLength));
+
+  // Data before padding.
+  EXPECT_CALL(callbacks,
+              OnDataChunkRecv(kFlags, 3, "This is the request body."));
+  EXPECT_TRUE(visitor.OnDataForStream(3, "This is the request body."));
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsData(3, _, kFlags, kPaddingLength)));
+  EXPECT_TRUE(visitor.OnDataPaddingLength(3, kPaddingLength));
+  visitor.OnEndStream(3);
+
+  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_NO_ERROR));
+  visitor.OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR);
+
+  // DATA on stream 5
+  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(5, DATA, kFlags)));
+  EXPECT_TRUE(visitor.OnFrameHeader(5, 25 + kPaddingLength, DATA, kFlags));
+
+  EXPECT_TRUE(visitor.OnBeginDataForStream(5, 25 + kPaddingLength));
+
+  // Error during padding.
+  EXPECT_CALL(callbacks,
+              OnDataChunkRecv(kFlags, 5, "This is the request body."));
+  EXPECT_TRUE(visitor.OnDataForStream(5, "This is the request body."));
+
+  EXPECT_CALL(callbacks, OnFrameRecv(IsData(5, _, kFlags, kPaddingLength)))
+      .WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
+  EXPECT_FALSE(visitor.OnDataPaddingLength(5, kPaddingLength));
+  visitor.OnEndStream(3);
+
+  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_NO_ERROR));
+  visitor.OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/data_source.h b/quiche/http2/adapter/data_source.h
new file mode 100644
index 0000000..0c40095
--- /dev/null
+++ b/quiche/http2/adapter/data_source.h
@@ -0,0 +1,60 @@
+#ifndef QUICHE_HTTP2_ADAPTER_DATA_SOURCE_H_
+#define QUICHE_HTTP2_ADAPTER_DATA_SOURCE_H_
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+// Represents a source of DATA frames for transmission to the peer.
+class QUICHE_EXPORT_PRIVATE DataFrameSource {
+ public:
+  virtual ~DataFrameSource() {}
+
+  enum : int64_t { kBlocked = 0, kError = -1 };
+
+  // Returns the number of bytes to send in the next DATA frame, and whether
+  // this frame indicates the end of the data. Returns {kBlocked, false} if
+  // blocked, {kError, false} on error.
+  virtual std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) = 0;
+
+  // This method is called with a frame header and a payload length to send. The
+  // source should send or buffer the entire frame and return true, or return
+  // false without sending or buffering anything.
+  virtual bool Send(absl::string_view frame_header, size_t payload_length) = 0;
+
+  // If true, the end of this data source indicates the end of the stream.
+  // Otherwise, this data will be followed by trailers.
+  virtual bool send_fin() const = 0;
+};
+
+// Represents a source of metadata frames for transmission to the peer.
+class QUICHE_EXPORT_PRIVATE MetadataSource {
+ public:
+  virtual ~MetadataSource() {}
+
+  // Returns the number of frames of at most |max_frame_size| required to
+  // serialize the metadata for this source. Only required by the nghttp2
+  // implementation.
+  virtual size_t NumFrames(size_t max_frame_size) const = 0;
+
+  // This method is called with a destination buffer and length. It should
+  // return the number of payload bytes copied to |dest|, or a negative integer
+  // to indicate an error, as well as a boolean indicating whether the metadata
+  // has been completely copied.
+  virtual std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) = 0;
+
+  // This method is called when transmission of the metadata for this source
+  // fails in a non-recoverable way.
+  virtual void OnFailure() = 0;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_DATA_SOURCE_H_
diff --git a/quiche/http2/adapter/event_forwarder.cc b/quiche/http2/adapter/event_forwarder.cc
new file mode 100644
index 0000000..b5c0389
--- /dev/null
+++ b/quiche/http2/adapter/event_forwarder.cc
@@ -0,0 +1,181 @@
+#include "quiche/http2/adapter/event_forwarder.h"
+
+namespace http2 {
+namespace adapter {
+
+EventForwarder::EventForwarder(ForwardPredicate can_forward,
+                               spdy::SpdyFramerVisitorInterface& receiver)
+    : can_forward_(std::move(can_forward)), receiver_(receiver) {}
+
+void EventForwarder::OnError(Http2DecoderAdapter::SpdyFramerError error,
+                             std::string detailed_error) {
+  if (can_forward_()) {
+    receiver_.OnError(error, std::move(detailed_error));
+  }
+}
+
+void EventForwarder::OnCommonHeader(spdy::SpdyStreamId stream_id, size_t length,
+                                    uint8_t type, uint8_t flags) {
+  if (can_forward_()) {
+    receiver_.OnCommonHeader(stream_id, length, type, flags);
+  }
+}
+
+void EventForwarder::OnDataFrameHeader(spdy::SpdyStreamId stream_id,
+                                       size_t length, bool fin) {
+  if (can_forward_()) {
+    receiver_.OnDataFrameHeader(stream_id, length, fin);
+  }
+}
+
+void EventForwarder::OnStreamFrameData(spdy::SpdyStreamId stream_id,
+                                       const char* data, size_t len) {
+  if (can_forward_()) {
+    receiver_.OnStreamFrameData(stream_id, data, len);
+  }
+}
+
+void EventForwarder::OnStreamEnd(spdy::SpdyStreamId stream_id) {
+  if (can_forward_()) {
+    receiver_.OnStreamEnd(stream_id);
+  }
+}
+
+void EventForwarder::OnStreamPadLength(spdy::SpdyStreamId stream_id,
+                                       size_t value) {
+  if (can_forward_()) {
+    receiver_.OnStreamPadLength(stream_id, value);
+  }
+}
+
+void EventForwarder::OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) {
+  if (can_forward_()) {
+    receiver_.OnStreamPadding(stream_id, len);
+  }
+}
+
+spdy::SpdyHeadersHandlerInterface* EventForwarder::OnHeaderFrameStart(
+    spdy::SpdyStreamId stream_id) {
+  return receiver_.OnHeaderFrameStart(stream_id);
+}
+
+void EventForwarder::OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) {
+  if (can_forward_()) {
+    receiver_.OnHeaderFrameEnd(stream_id);
+  }
+}
+
+void EventForwarder::OnRstStream(spdy::SpdyStreamId stream_id,
+                                 spdy::SpdyErrorCode error_code) {
+  if (can_forward_()) {
+    receiver_.OnRstStream(stream_id, error_code);
+  }
+}
+
+void EventForwarder::OnSettings() {
+  if (can_forward_()) {
+    receiver_.OnSettings();
+  }
+}
+
+void EventForwarder::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
+  if (can_forward_()) {
+    receiver_.OnSetting(id, value);
+  }
+}
+
+void EventForwarder::OnSettingsEnd() {
+  if (can_forward_()) {
+    receiver_.OnSettingsEnd();
+  }
+}
+
+void EventForwarder::OnSettingsAck() {
+  if (can_forward_()) {
+    receiver_.OnSettingsAck();
+  }
+}
+
+void EventForwarder::OnPing(spdy::SpdyPingId unique_id, bool is_ack) {
+  if (can_forward_()) {
+    receiver_.OnPing(unique_id, is_ack);
+  }
+}
+
+void EventForwarder::OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
+                              spdy::SpdyErrorCode error_code) {
+  if (can_forward_()) {
+    receiver_.OnGoAway(last_accepted_stream_id, error_code);
+  }
+}
+
+bool EventForwarder::OnGoAwayFrameData(const char* goaway_data, size_t len) {
+  if (can_forward_()) {
+    return receiver_.OnGoAwayFrameData(goaway_data, len);
+  }
+  return false;
+}
+
+void EventForwarder::OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
+                               int weight, spdy::SpdyStreamId parent_stream_id,
+                               bool exclusive, bool fin, bool end) {
+  if (can_forward_()) {
+    receiver_.OnHeaders(stream_id, has_priority, weight, parent_stream_id,
+                        exclusive, fin, end);
+  }
+}
+
+void EventForwarder::OnWindowUpdate(spdy::SpdyStreamId stream_id,
+                                    int delta_window_size) {
+  if (can_forward_()) {
+    receiver_.OnWindowUpdate(stream_id, delta_window_size);
+  }
+}
+
+void EventForwarder::OnPushPromise(spdy::SpdyStreamId stream_id,
+                                   spdy::SpdyStreamId promised_stream_id,
+                                   bool end) {
+  if (can_forward_()) {
+    receiver_.OnPushPromise(stream_id, promised_stream_id, end);
+  }
+}
+
+void EventForwarder::OnContinuation(spdy::SpdyStreamId stream_id, bool end) {
+  if (can_forward_()) {
+    receiver_.OnContinuation(stream_id, end);
+  }
+}
+
+void EventForwarder::OnAltSvc(
+    spdy::SpdyStreamId stream_id, absl::string_view origin,
+    const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
+  if (can_forward_()) {
+    receiver_.OnAltSvc(stream_id, origin, altsvc_vector);
+  }
+}
+
+void EventForwarder::OnPriority(spdy::SpdyStreamId stream_id,
+                                spdy::SpdyStreamId parent_stream_id, int weight,
+                                bool exclusive) {
+  if (can_forward_()) {
+    receiver_.OnPriority(stream_id, parent_stream_id, weight, exclusive);
+  }
+}
+
+void EventForwarder::OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
+                                      absl::string_view priority_field_value) {
+  if (can_forward_()) {
+    receiver_.OnPriorityUpdate(prioritized_stream_id, priority_field_value);
+  }
+}
+
+bool EventForwarder::OnUnknownFrame(spdy::SpdyStreamId stream_id,
+                                    uint8_t frame_type) {
+  if (can_forward_()) {
+    return receiver_.OnUnknownFrame(stream_id, frame_type);
+  }
+  return false;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/event_forwarder.h b/quiche/http2/adapter/event_forwarder.h
new file mode 100644
index 0000000..1682263
--- /dev/null
+++ b/quiche/http2/adapter/event_forwarder.h
@@ -0,0 +1,76 @@
+#ifndef QUICHE_HTTP2_ADAPTER_EVENT_FORWARDER_H_
+#define QUICHE_HTTP2_ADAPTER_EVENT_FORWARDER_H_
+
+#include <functional>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+
+namespace http2 {
+namespace adapter {
+
+// Forwards events to a provided SpdyFramerVisitorInterface receiver if the
+// provided predicate succeeds. Currently, OnHeaderFrameStart() is always
+// forwarded regardless of the predicate.
+// TODO(diannahu): Add a NoOpHeadersHandler if needed.
+class QUICHE_EXPORT_PRIVATE EventForwarder
+    : public spdy::SpdyFramerVisitorInterface {
+ public:
+  // Whether the forwarder can forward events to the receiver.
+  using ForwardPredicate = std::function<bool()>;
+
+  EventForwarder(ForwardPredicate can_forward,
+                 spdy::SpdyFramerVisitorInterface& receiver);
+
+  void OnError(Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error) override;
+  void OnCommonHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
+                      uint8_t flags) override;
+  void OnDataFrameHeader(spdy::SpdyStreamId stream_id, size_t length,
+                         bool fin) override;
+  void OnStreamFrameData(spdy::SpdyStreamId stream_id, const char* data,
+                         size_t len) override;
+  void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
+  void OnStreamPadLength(spdy::SpdyStreamId stream_id, size_t value) override;
+  void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
+  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      spdy::SpdyStreamId stream_id) override;
+  void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
+  void OnRstStream(spdy::SpdyStreamId stream_id,
+                   spdy::SpdyErrorCode error_code) override;
+  void OnSettings() override;
+  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck() override;
+  void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
+  void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
+                spdy::SpdyErrorCode error_code) override;
+  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
+  void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority, int weight,
+                 spdy::SpdyStreamId parent_stream_id, bool exclusive, bool fin,
+                 bool end) override;
+  void OnWindowUpdate(spdy::SpdyStreamId stream_id,
+                      int delta_window_size) override;
+  void OnPushPromise(spdy::SpdyStreamId stream_id,
+                     spdy::SpdyStreamId promised_stream_id, bool end) override;
+  void OnContinuation(spdy::SpdyStreamId stream_id, bool end) override;
+  void OnAltSvc(spdy::SpdyStreamId stream_id, absl::string_view origin,
+                const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
+                    altsvc_vector) override;
+  void OnPriority(spdy::SpdyStreamId stream_id,
+                  spdy::SpdyStreamId parent_stream_id, int weight,
+                  bool exclusive) override;
+  void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
+                        absl::string_view priority_field_value) override;
+  bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
+                      uint8_t frame_type) override;
+
+ private:
+  ForwardPredicate can_forward_;
+  spdy::SpdyFramerVisitorInterface& receiver_;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_EVENT_FORWARDER_H_
diff --git a/quiche/http2/adapter/event_forwarder_test.cc b/quiche/http2/adapter/event_forwarder_test.cc
new file mode 100644
index 0000000..eb22e63
--- /dev/null
+++ b/quiche/http2/adapter/event_forwarder_test.cc
@@ -0,0 +1,220 @@
+#include "quiche/http2/adapter/event_forwarder.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/mock_spdy_framer_visitor.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+constexpr absl::string_view some_data = "Here is some data for events";
+constexpr spdy::SpdyStreamId stream_id = 1;
+constexpr spdy::SpdyErrorCode error_code =
+    spdy::SpdyErrorCode::ERROR_CODE_ENHANCE_YOUR_CALM;
+constexpr size_t length = 42;
+
+TEST(EventForwarderTest, ForwardsEventsWithTruePredicate) {
+  spdy::test::MockSpdyFramerVisitor receiver;
+  receiver.DelegateHeaderHandling();
+  EventForwarder event_forwarder([]() { return true; }, receiver);
+
+  EXPECT_CALL(
+      receiver,
+      OnError(Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
+              std::string(some_data)));
+  event_forwarder.OnError(
+      Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
+      std::string(some_data));
+
+  EXPECT_CALL(receiver,
+              OnCommonHeader(stream_id, length, /*type=*/0x0, /*flags=*/0x1));
+  event_forwarder.OnCommonHeader(stream_id, length, /*type=*/0x0,
+                                 /*flags=*/0x1);
+
+  EXPECT_CALL(receiver, OnDataFrameHeader(stream_id, length, /*fin=*/true));
+  event_forwarder.OnDataFrameHeader(stream_id, length, /*fin=*/true);
+
+  EXPECT_CALL(receiver,
+              OnStreamFrameData(stream_id, some_data.data(), some_data.size()));
+  event_forwarder.OnStreamFrameData(stream_id, some_data.data(),
+                                    some_data.size());
+
+  EXPECT_CALL(receiver, OnStreamEnd(stream_id));
+  event_forwarder.OnStreamEnd(stream_id);
+
+  EXPECT_CALL(receiver, OnStreamPadLength(stream_id, length));
+  event_forwarder.OnStreamPadLength(stream_id, length);
+
+  EXPECT_CALL(receiver, OnStreamPadding(stream_id, length));
+  event_forwarder.OnStreamPadding(stream_id, length);
+
+  EXPECT_CALL(receiver, OnHeaderFrameStart(stream_id));
+  spdy::SpdyHeadersHandlerInterface* handler =
+      event_forwarder.OnHeaderFrameStart(stream_id);
+  EXPECT_EQ(handler, receiver.ReturnTestHeadersHandler(stream_id));
+
+  EXPECT_CALL(receiver, OnHeaderFrameEnd(stream_id));
+  event_forwarder.OnHeaderFrameEnd(stream_id);
+
+  EXPECT_CALL(receiver, OnRstStream(stream_id, error_code));
+  event_forwarder.OnRstStream(stream_id, error_code);
+
+  EXPECT_CALL(receiver, OnSettings());
+  event_forwarder.OnSettings();
+
+  EXPECT_CALL(
+      receiver,
+      OnSetting(spdy::SpdyKnownSettingsId::SETTINGS_MAX_CONCURRENT_STREAMS,
+                100));
+  event_forwarder.OnSetting(
+      spdy::SpdyKnownSettingsId::SETTINGS_MAX_CONCURRENT_STREAMS, 100);
+
+  EXPECT_CALL(receiver, OnSettingsEnd());
+  event_forwarder.OnSettingsEnd();
+
+  EXPECT_CALL(receiver, OnSettingsAck());
+  event_forwarder.OnSettingsAck();
+
+  EXPECT_CALL(receiver, OnPing(/*unique_id=*/42, /*is_ack=*/false));
+  event_forwarder.OnPing(/*unique_id=*/42, /*is_ack=*/false);
+
+  EXPECT_CALL(receiver, OnGoAway(stream_id, error_code));
+  event_forwarder.OnGoAway(stream_id, error_code);
+
+  EXPECT_CALL(receiver, OnGoAwayFrameData(some_data.data(), some_data.size()));
+  event_forwarder.OnGoAwayFrameData(some_data.data(), some_data.size());
+
+  EXPECT_CALL(
+      receiver,
+      OnHeaders(stream_id, /*has_priority=*/false, /*weight=*/42, stream_id + 2,
+                /*exclusive=*/false, /*fin=*/true, /*end=*/true));
+  event_forwarder.OnHeaders(stream_id, /*has_priority=*/false, /*weight=*/42,
+                            stream_id + 2, /*exclusive=*/false, /*fin=*/true,
+                            /*end=*/true);
+
+  EXPECT_CALL(receiver, OnWindowUpdate(stream_id, /*delta_window_size=*/42));
+  event_forwarder.OnWindowUpdate(stream_id, /*delta_window_size=*/42);
+
+  EXPECT_CALL(receiver, OnPushPromise(stream_id, stream_id + 1, /*end=*/true));
+  event_forwarder.OnPushPromise(stream_id, stream_id + 1, /*end=*/true);
+
+  EXPECT_CALL(receiver, OnContinuation(stream_id, /*end=*/true));
+  event_forwarder.OnContinuation(stream_id, /*end=*/true);
+
+  const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  EXPECT_CALL(receiver, OnAltSvc(stream_id, some_data, altsvc_vector));
+  event_forwarder.OnAltSvc(stream_id, some_data, altsvc_vector);
+
+  EXPECT_CALL(receiver, OnPriority(stream_id, stream_id + 2, /*weight=*/42,
+                                   /*exclusive=*/false));
+  event_forwarder.OnPriority(stream_id, stream_id + 2, /*weight=*/42,
+                             /*exclusive=*/false);
+
+  EXPECT_CALL(receiver, OnPriorityUpdate(stream_id, some_data));
+  event_forwarder.OnPriorityUpdate(stream_id, some_data);
+
+  EXPECT_CALL(receiver, OnUnknownFrame(stream_id, /*frame_type=*/0x4D));
+  event_forwarder.OnUnknownFrame(stream_id, /*frame_type=*/0x4D);
+}
+
+TEST(EventForwarderTest, DoesNotForwardEventsWithFalsePredicate) {
+  spdy::test::MockSpdyFramerVisitor receiver;
+  receiver.DelegateHeaderHandling();
+  EventForwarder event_forwarder([]() { return false; }, receiver);
+
+  EXPECT_CALL(receiver, OnError).Times(0);
+  event_forwarder.OnError(
+      Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
+      std::string(some_data));
+
+  EXPECT_CALL(receiver, OnCommonHeader).Times(0);
+  event_forwarder.OnCommonHeader(stream_id, length, /*type=*/0x0,
+                                 /*flags=*/0x1);
+
+  EXPECT_CALL(receiver, OnDataFrameHeader).Times(0);
+  event_forwarder.OnDataFrameHeader(stream_id, length, /*fin=*/true);
+
+  EXPECT_CALL(receiver, OnStreamFrameData).Times(0);
+  event_forwarder.OnStreamFrameData(stream_id, some_data.data(),
+                                    some_data.size());
+
+  EXPECT_CALL(receiver, OnStreamEnd).Times(0);
+  event_forwarder.OnStreamEnd(stream_id);
+
+  EXPECT_CALL(receiver, OnStreamPadLength).Times(0);
+  event_forwarder.OnStreamPadLength(stream_id, length);
+
+  EXPECT_CALL(receiver, OnStreamPadding).Times(0);
+  event_forwarder.OnStreamPadding(stream_id, length);
+
+  EXPECT_CALL(receiver, OnHeaderFrameStart(stream_id));
+  spdy::SpdyHeadersHandlerInterface* handler =
+      event_forwarder.OnHeaderFrameStart(stream_id);
+  EXPECT_EQ(handler, receiver.ReturnTestHeadersHandler(stream_id));
+
+  EXPECT_CALL(receiver, OnHeaderFrameEnd).Times(0);
+  event_forwarder.OnHeaderFrameEnd(stream_id);
+
+  EXPECT_CALL(receiver, OnRstStream).Times(0);
+  event_forwarder.OnRstStream(stream_id, error_code);
+
+  EXPECT_CALL(receiver, OnSettings).Times(0);
+  event_forwarder.OnSettings();
+
+  EXPECT_CALL(receiver, OnSetting).Times(0);
+  event_forwarder.OnSetting(
+      spdy::SpdyKnownSettingsId::SETTINGS_MAX_CONCURRENT_STREAMS, 100);
+
+  EXPECT_CALL(receiver, OnSettingsEnd).Times(0);
+  event_forwarder.OnSettingsEnd();
+
+  EXPECT_CALL(receiver, OnSettingsAck).Times(0);
+  event_forwarder.OnSettingsAck();
+
+  EXPECT_CALL(receiver, OnPing).Times(0);
+  event_forwarder.OnPing(/*unique_id=*/42, /*is_ack=*/false);
+
+  EXPECT_CALL(receiver, OnGoAway).Times(0);
+  event_forwarder.OnGoAway(stream_id, error_code);
+
+  EXPECT_CALL(receiver, OnGoAwayFrameData).Times(0);
+  event_forwarder.OnGoAwayFrameData(some_data.data(), some_data.size());
+
+  EXPECT_CALL(receiver, OnHeaders).Times(0);
+  event_forwarder.OnHeaders(stream_id, /*has_priority=*/false, /*weight=*/42,
+                            stream_id + 2, /*exclusive=*/false, /*fin=*/true,
+                            /*end=*/true);
+
+  EXPECT_CALL(receiver, OnWindowUpdate).Times(0);
+  event_forwarder.OnWindowUpdate(stream_id, /*delta_window_size=*/42);
+
+  EXPECT_CALL(receiver, OnPushPromise).Times(0);
+  event_forwarder.OnPushPromise(stream_id, stream_id + 1, /*end=*/true);
+
+  EXPECT_CALL(receiver, OnContinuation).Times(0);
+  event_forwarder.OnContinuation(stream_id, /*end=*/true);
+
+  EXPECT_CALL(receiver, OnAltSvc).Times(0);
+  const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  event_forwarder.OnAltSvc(stream_id, some_data, altsvc_vector);
+
+  EXPECT_CALL(receiver, OnPriority).Times(0);
+  event_forwarder.OnPriority(stream_id, stream_id + 2, /*weight=*/42,
+                             /*exclusive=*/false);
+
+  EXPECT_CALL(receiver, OnPriorityUpdate).Times(0);
+  event_forwarder.OnPriorityUpdate(stream_id, some_data);
+
+  EXPECT_CALL(receiver, OnUnknownFrame).Times(0);
+  event_forwarder.OnUnknownFrame(stream_id, /*frame_type=*/0x4D);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/header_validator.cc b/quiche/http2/adapter/header_validator.cc
new file mode 100644
index 0000000..43653a6
--- /dev/null
+++ b/quiche/http2/adapter/header_validator.cc
@@ -0,0 +1,257 @@
+#include "quiche/http2/adapter/header_validator.h"
+
+#include <array>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/numbers.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace http2 {
+namespace adapter {
+
+namespace {
+
+const absl::string_view kHttp2HeaderNameAllowedChars =
+    "!#$%&\'*+-.0123456789"
+    "^_`abcdefghijklmnopqrstuvwxyz|~";
+
+const absl::string_view kHttp2HeaderValueAllowedChars =
+    "\t "
+    "!\"#$%&'()*+,-./"
+    "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
+    "abcdefghijklmnopqrstuvwxyz{|}~";
+
+const absl::string_view kHttp2StatusValueAllowedChars = "0123456789";
+
+const absl::string_view kValidAuthorityChars =
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%!$&'()["
+    "]*+,;=:";
+
+using CharMap = std::array<bool, 256>;
+
+CharMap BuildValidCharMap(absl::string_view valid_chars) {
+  CharMap map;
+  map.fill(false);
+  for (char c : valid_chars) {
+    // Cast to uint8_t, guaranteed to have 8 bits. A char may have more, leading
+    // to possible indices above 256.
+    map[static_cast<uint8_t>(c)] = true;
+  }
+  return map;
+}
+
+bool AllCharsInMap(absl::string_view str, const CharMap& map) {
+  for (char c : str) {
+    if (!map[static_cast<uint8_t>(c)]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool IsValidHeaderName(absl::string_view name) {
+  static const CharMap valid_chars =
+      BuildValidCharMap(kHttp2HeaderNameAllowedChars);
+  return AllCharsInMap(name, valid_chars);
+}
+
+bool IsValidHeaderValue(absl::string_view value) {
+  static const CharMap valid_chars =
+      BuildValidCharMap(kHttp2HeaderValueAllowedChars);
+  return AllCharsInMap(value, valid_chars);
+}
+
+bool IsValidStatus(absl::string_view status) {
+  static const CharMap valid_chars =
+      BuildValidCharMap(kHttp2StatusValueAllowedChars);
+  return AllCharsInMap(status, valid_chars);
+}
+
+bool ValidateRequestHeaders(const std::vector<std::string>& pseudo_headers,
+                            absl::string_view method, absl::string_view path,
+                            bool allow_connect) {
+  QUICHE_VLOG(2) << "Request pseudo-headers: ["
+                 << absl::StrJoin(pseudo_headers, ", ")
+                 << "], allow_connect: " << allow_connect
+                 << ", method: " << method << ", path: " << path;
+  if (allow_connect && method == "CONNECT") {
+    static const std::vector<std::string>* kConnectHeaders =
+        new std::vector<std::string>(
+            {":authority", ":method", ":path", ":protocol", ":scheme"});
+    return pseudo_headers == *kConnectHeaders;
+  }
+
+  if (path.empty()) {
+    return false;
+  }
+  if (path == "*") {
+    if (method != "OPTIONS") {
+      return false;
+    }
+  } else if (path[0] != '/') {
+    return false;
+  }
+
+  static const std::vector<std::string>* kRequiredHeaders =
+      new std::vector<std::string>(
+          {":authority", ":method", ":path", ":scheme"});
+  return pseudo_headers == *kRequiredHeaders;
+}
+
+bool ValidateRequestTrailers(const std::vector<std::string>& pseudo_headers) {
+  return pseudo_headers.empty();
+}
+
+bool ValidateResponseHeaders(const std::vector<std::string>& pseudo_headers) {
+  static const std::vector<std::string>* kRequiredHeaders =
+      new std::vector<std::string>({":status"});
+  return pseudo_headers == *kRequiredHeaders;
+}
+
+bool ValidateResponseTrailers(const std::vector<std::string>& pseudo_headers) {
+  return pseudo_headers.empty();
+}
+
+}  // namespace
+
+void HeaderValidator::StartHeaderBlock() {
+  pseudo_headers_.clear();
+  status_.clear();
+  method_.clear();
+  path_.clear();
+  authority_ = absl::nullopt;
+  content_length_.reset();
+}
+
+HeaderValidator::HeaderStatus HeaderValidator::ValidateSingleHeader(
+    absl::string_view key, absl::string_view value) {
+  if (key.empty()) {
+    return HEADER_FIELD_INVALID;
+  }
+  if (max_field_size_.has_value() &&
+      key.size() + value.size() > max_field_size_.value()) {
+    QUICHE_VLOG(2) << "Header field size is " << key.size() + value.size()
+                   << ", exceeds max size of " << max_field_size_.value();
+    return HEADER_FIELD_TOO_LONG;
+  }
+  const absl::string_view validated_key = key[0] == ':' ? key.substr(1) : key;
+  if (!IsValidHeaderName(validated_key)) {
+    QUICHE_VLOG(2) << "invalid chars in header name: ["
+                   << absl::CEscape(validated_key) << "]";
+    return HEADER_FIELD_INVALID;
+  }
+  if (!IsValidHeaderValue(value)) {
+    QUICHE_VLOG(2) << "invalid chars in header value: [" << absl::CEscape(value)
+                   << "]";
+    return HEADER_FIELD_INVALID;
+  }
+  if (key[0] == ':') {
+    if (key == ":status") {
+      if (value.size() != 3 || !IsValidStatus(value)) {
+        QUICHE_VLOG(2) << "malformed status value: [" << absl::CEscape(value)
+                       << "]";
+        return HEADER_FIELD_INVALID;
+      }
+      if (value == "101") {
+        // Switching protocols is not allowed on a HTTP/2 stream.
+        return HEADER_FIELD_INVALID;
+      }
+      status_ = std::string(value);
+    } else if (key == ":method") {
+      method_ = std::string(value);
+    } else if (key == ":authority" && !ValidateAndSetAuthority(value)) {
+      return HEADER_FIELD_INVALID;
+    } else if (key == ":path") {
+      if (value.empty()) {
+        // For now, reject an empty path regardless of scheme.
+        return HEADER_FIELD_INVALID;
+      }
+      path_ = std::string(value);
+    }
+    pseudo_headers_.push_back(std::string(key));
+  } else if (key == "host") {
+    if (!status_.empty()) {
+      // Response headers can contain "Host".
+    } else {
+      if (!authority_.has_value()) {
+        pseudo_headers_.push_back(std::string(":authority"));
+      }
+      if (!ValidateAndSetAuthority(value)) {
+        return HEADER_FIELD_INVALID;
+      }
+    }
+  } else if (key == "content-length") {
+    const bool success = HandleContentLength(value);
+    if (!success) {
+      return HEADER_FIELD_INVALID;
+    }
+  } else if (key == "te" && value != "trailers") {
+    return HEADER_FIELD_INVALID;
+  } else if (key == "upgrade" || GetInvalidHttp2HeaderSet().contains(key)) {
+    // TODO(b/78024822): Remove the "upgrade" here once it's added to
+    // GetInvalidHttp2HeaderSet().
+    return HEADER_FIELD_INVALID;
+  }
+  return HEADER_OK;
+}
+
+// Returns true if all required pseudoheaders and no extra pseudoheaders are
+// present for the given header type.
+bool HeaderValidator::FinishHeaderBlock(HeaderType type) {
+  std::sort(pseudo_headers_.begin(), pseudo_headers_.end());
+  switch (type) {
+    case HeaderType::REQUEST:
+      return ValidateRequestHeaders(pseudo_headers_, method_, path_,
+                                    allow_connect_);
+    case HeaderType::REQUEST_TRAILER:
+      return ValidateRequestTrailers(pseudo_headers_);
+    case HeaderType::RESPONSE_100:
+    case HeaderType::RESPONSE:
+      return ValidateResponseHeaders(pseudo_headers_);
+    case HeaderType::RESPONSE_TRAILER:
+      return ValidateResponseTrailers(pseudo_headers_);
+  }
+  return false;
+}
+
+bool HeaderValidator::HandleContentLength(absl::string_view value) {
+  if (value.empty()) {
+    return false;
+  }
+
+  if (status_ == "204" && value != "0") {
+    // There should be no body in a "204 No Content" response.
+    return false;
+  }
+  if (!status_.empty() && status_[0] == '1' && value != "0") {
+    // There should also be no body in a 1xx response.
+    return false;
+  }
+
+  size_t content_length = 0;
+  const bool valid = absl::SimpleAtoi(value, &content_length);
+  if (!valid) {
+    return false;
+  }
+
+  content_length_ = content_length;
+  return true;
+}
+
+// Returns whether `authority` contains only characters from the `host` ABNF
+// from RFC 3986 section 3.2.2.
+bool HeaderValidator::ValidateAndSetAuthority(absl::string_view authority) {
+  static const CharMap valid_chars = BuildValidCharMap(kValidAuthorityChars);
+  if (!AllCharsInMap(authority, valid_chars)) {
+    return false;
+  }
+  if (authority_.has_value() && authority != authority_.value()) {
+    return false;
+  }
+  authority_ = std::string(authority);
+  return true;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/header_validator.h b/quiche/http2/adapter/header_validator.h
new file mode 100644
index 0000000..fb4eecf
--- /dev/null
+++ b/quiche/http2/adapter/header_validator.h
@@ -0,0 +1,68 @@
+#ifndef QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_H_
+#define QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+enum class HeaderType : uint8_t {
+  REQUEST,
+  REQUEST_TRAILER,
+  RESPONSE_100,
+  RESPONSE,
+  RESPONSE_TRAILER,
+};
+
+class QUICHE_EXPORT_PRIVATE HeaderValidator {
+ public:
+  HeaderValidator() {}
+
+  void SetMaxFieldSize(uint32_t field_size) { max_field_size_ = field_size; }
+
+  // If called, this validator will allow the `:protocol` pseudo-header, as
+  // described in RFC 8441.
+  void AllowConnect() { allow_connect_ = true; }
+
+  void StartHeaderBlock();
+
+  enum HeaderStatus {
+    HEADER_OK,
+    HEADER_FIELD_INVALID,
+    HEADER_FIELD_TOO_LONG,
+  };
+  HeaderStatus ValidateSingleHeader(absl::string_view key,
+                                    absl::string_view value);
+
+  // Returns true if all required pseudoheaders and no extra pseudoheaders are
+  // present for the given header type.
+  bool FinishHeaderBlock(HeaderType type);
+
+  // For responses, returns the value of the ":status" header, if present.
+  absl::string_view status_header() const { return status_; }
+
+  absl::optional<size_t> content_length() const { return content_length_; }
+
+ private:
+  bool HandleContentLength(absl::string_view value);
+  bool ValidateAndSetAuthority(absl::string_view authority);
+
+  std::vector<std::string> pseudo_headers_;
+  absl::optional<std::string> authority_ = absl::nullopt;
+  std::string status_;
+  std::string method_;
+  std::string path_;
+  absl::optional<size_t> max_field_size_;
+  absl::optional<size_t> content_length_;
+  bool allow_connect_ = false;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_HEADER_VALIDATOR_H_
diff --git a/quiche/http2/adapter/header_validator_test.cc b/quiche/http2/adapter/header_validator_test.cc
new file mode 100644
index 0000000..6d25261
--- /dev/null
+++ b/quiche/http2/adapter/header_validator_test.cc
@@ -0,0 +1,563 @@
+#include "quiche/http2/adapter/header_validator.h"
+
+#include <utility>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/types/optional.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+using ::testing::Optional;
+
+using Header = std::pair<absl::string_view, absl::string_view>;
+constexpr Header kSampleRequestPseudoheaders[] = {{":authority", "www.foo.com"},
+                                                  {":method", "GET"},
+                                                  {":path", "/foo"},
+                                                  {":scheme", "https"}};
+
+TEST(HeaderValidatorTest, HeaderNameEmpty) {
+  HeaderValidator v;
+  HeaderValidator::HeaderStatus status = v.ValidateSingleHeader("", "value");
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+}
+
+TEST(HeaderValidatorTest, HeaderValueEmpty) {
+  HeaderValidator v;
+  HeaderValidator::HeaderStatus status = v.ValidateSingleHeader("name", "");
+  EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+}
+
+TEST(HeaderValidatorTest, ExceedsMaxSize) {
+  HeaderValidator v;
+  v.SetMaxFieldSize(64u);
+  HeaderValidator::HeaderStatus status =
+      v.ValidateSingleHeader("name", "value");
+  EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+  status = v.ValidateSingleHeader(
+      "name2",
+      "Antidisestablishmentariansism is supercalifragilisticexpialodocious.");
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_TOO_LONG, status);
+}
+
+TEST(HeaderValidatorTest, NameHasInvalidChar) {
+  HeaderValidator v;
+  for (const bool is_pseudo_header : {true, false}) {
+    // These characters should be allowed. (Not exhaustive.)
+    for (const char* c : {"!", "3", "a", "_", "|", "~"}) {
+      const std::string name = is_pseudo_header ? absl::StrCat(":met", c, "hod")
+                                                : absl::StrCat("na", c, "me");
+      HeaderValidator::HeaderStatus status =
+          v.ValidateSingleHeader(name, "value");
+      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+    }
+    // These should not. (Not exhaustive.)
+    for (const char* c : {"\\", "<", ";", "[", "=", " ", "\r", "\n", ",", "\"",
+                          "\x1F", "\x91"}) {
+      const std::string name = is_pseudo_header ? absl::StrCat(":met", c, "hod")
+                                                : absl::StrCat("na", c, "me");
+      HeaderValidator::HeaderStatus status =
+          v.ValidateSingleHeader(name, "value");
+      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+    }
+    // Test nul separately.
+    {
+      const absl::string_view name = is_pseudo_header
+                                         ? absl::string_view(":met\0hod", 8)
+                                         : absl::string_view("na\0me", 5);
+      HeaderValidator::HeaderStatus status =
+          v.ValidateSingleHeader(name, "value");
+      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+    }
+    // Uppercase characters in header names should not be allowed.
+    const std::string uc_name = is_pseudo_header ? ":Method" : "Name";
+    HeaderValidator::HeaderStatus status =
+        v.ValidateSingleHeader(uc_name, "value");
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+  }
+}
+
+TEST(HeaderValidatorTest, ValueHasInvalidChar) {
+  HeaderValidator v;
+  // These characters should be allowed. (Not exhaustive.)
+  for (const char* c :
+       {"!", "3", "a", "_", "|", "~", "\\", "<", ";", "[", "=", "A", "\t"}) {
+    HeaderValidator::HeaderStatus status =
+        v.ValidateSingleHeader("name", absl::StrCat("val", c, "ue"));
+    EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+  }
+  // These should not.
+  for (const char* c : {"\r", "\n"}) {
+    HeaderValidator::HeaderStatus status =
+        v.ValidateSingleHeader("name", absl::StrCat("val", c, "ue"));
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+  }
+  // Test nul separately.
+  {
+    HeaderValidator::HeaderStatus status =
+        v.ValidateSingleHeader("name", absl::string_view("val\0ue", 6));
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+  }
+}
+
+TEST(HeaderValidatorTest, StatusHasInvalidChar) {
+  HeaderValidator v;
+
+  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
+    // When `:status` has a non-digit value, validation will fail.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+              v.ValidateSingleHeader(":status", "bar"));
+    EXPECT_FALSE(v.FinishHeaderBlock(type));
+
+    // When `:status` is too short, validation will fail.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+              v.ValidateSingleHeader(":status", "10"));
+    EXPECT_FALSE(v.FinishHeaderBlock(type));
+
+    // When `:status` is too long, validation will fail.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+              v.ValidateSingleHeader(":status", "9000"));
+    EXPECT_FALSE(v.FinishHeaderBlock(type));
+
+    // When `:status` is just right, validation will succeed.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(":status", "400"));
+    EXPECT_TRUE(v.FinishHeaderBlock(type));
+  }
+}
+
+TEST(HeaderValidatorTest, AuthorityHasInvalidChar) {
+  for (absl::string_view key : {":authority", "host"}) {
+    // These characters should be allowed. (Not exhaustive.)
+    for (const absl::string_view c : {"1", "-", "!", ":", "+", "=", ","}) {
+      HeaderValidator v;
+      v.StartHeaderBlock();
+      HeaderValidator::HeaderStatus status =
+          v.ValidateSingleHeader(key, absl::StrCat("ho", c, "st.example.com"));
+      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+    }
+    // These should not.
+    for (const absl::string_view c : {"\r", "\n", "|", "\\", "`"}) {
+      HeaderValidator v;
+      v.StartHeaderBlock();
+      HeaderValidator::HeaderStatus status =
+          v.ValidateSingleHeader(key, absl::StrCat("ho", c, "st.example.com"));
+      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID, status);
+    }
+
+    {
+      // IPv4 example
+      HeaderValidator v;
+      v.StartHeaderBlock();
+      HeaderValidator::HeaderStatus status =
+          v.ValidateSingleHeader(key, "123.45.67.89");
+      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+    }
+
+    {
+      // IPv6 examples
+      HeaderValidator v;
+      v.StartHeaderBlock();
+      HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(
+          key, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+      HeaderValidator v2;
+      v2.StartHeaderBlock();
+      status = v2.ValidateSingleHeader(key, "[::1]:80");
+      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+    }
+
+    {
+      // Empty field
+      HeaderValidator v;
+      v.StartHeaderBlock();
+      HeaderValidator::HeaderStatus status = v.ValidateSingleHeader(key, "");
+      EXPECT_EQ(HeaderValidator::HEADER_OK, status);
+    }
+  }
+}
+
+TEST(HeaderValidatorTest, RequestHostAndAuthority) {
+  HeaderValidator v;
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(to_add.first, to_add.second));
+  }
+  // If both "host" and ":authority" have the same value, validation succeeds.
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("host", "www.foo.com"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(to_add.first, to_add.second));
+  }
+  // If "host" and ":authority" have different values, validation fails.
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("host", "www.bar.com"));
+}
+
+TEST(HeaderValidatorTest, RequestPseudoHeaders) {
+  HeaderValidator v;
+  for (Header to_skip : kSampleRequestPseudoheaders) {
+    v.StartHeaderBlock();
+    for (Header to_add : kSampleRequestPseudoheaders) {
+      if (to_add != to_skip) {
+        EXPECT_EQ(HeaderValidator::HEADER_OK,
+                  v.ValidateSingleHeader(to_add.first, to_add.second));
+      }
+    }
+    // When any pseudo-header is missing, final validation will fail.
+    EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+  }
+
+  // When all pseudo-headers are present, final validation will succeed.
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(to_add.first, to_add.second));
+  }
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  // When an extra pseudo-header is present, final validation will fail.
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(to_add.first, to_add.second));
+  }
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":extra", "blah"));
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  // When a required pseudo-header is repeated, final validation will fail.
+  for (Header to_repeat : kSampleRequestPseudoheaders) {
+    v.StartHeaderBlock();
+    for (Header to_add : kSampleRequestPseudoheaders) {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, to_add.second));
+      if (to_add == to_repeat) {
+        EXPECT_EQ(HeaderValidator::HEADER_OK,
+                  v.ValidateSingleHeader(to_add.first, to_add.second));
+      }
+    }
+    EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+  }
+}
+
+TEST(HeaderValidatorTest, WebsocketPseudoHeaders) {
+  HeaderValidator v;
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(to_add.first, to_add.second));
+  }
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":protocol", "websocket"));
+  // At this point, `:protocol` is treated as an extra pseudo-header.
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  // Future header blocks may send the `:protocol` pseudo-header for CONNECT
+  // requests.
+  v.AllowConnect();
+
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(to_add.first, to_add.second));
+  }
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":protocol", "websocket"));
+  // The method is not "CONNECT", so `:protocol` is still treated as an extra
+  // pseudo-header.
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    if (to_add.first == ":method") {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, "CONNECT"));
+    } else {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, to_add.second));
+    }
+  }
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":protocol", "websocket"));
+  // After allowing the method, `:protocol` is acepted for CONNECT requests.
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
+}
+
+TEST(HeaderValidatorTest, AsteriskPathPseudoHeader) {
+  HeaderValidator v;
+
+  // An asterisk :path should not be allowed for non-OPTIONS requests.
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    if (to_add.first == ":path") {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, "*"));
+    } else {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, to_add.second));
+    }
+  }
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  // An asterisk :path should be allowed for OPTIONS requests.
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    if (to_add.first == ":path") {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, "*"));
+    } else if (to_add.first == ":method") {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, "OPTIONS"));
+    } else {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, to_add.second));
+    }
+  }
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
+}
+
+TEST(HeaderValidatorTest, InvalidPathPseudoHeader) {
+  HeaderValidator v;
+
+  // An empty path should fail on single header validation and finish.
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    if (to_add.first == ":path") {
+      EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+                v.ValidateSingleHeader(to_add.first, ""));
+    } else {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, to_add.second));
+    }
+  }
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+
+  // A path that does not start with a slash should fail on finish.
+  v.StartHeaderBlock();
+  for (Header to_add : kSampleRequestPseudoheaders) {
+    if (to_add.first == ":path") {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, "shawarma"));
+    } else {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(to_add.first, to_add.second));
+    }
+  }
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::REQUEST));
+}
+
+TEST(HeaderValidatorTest, ResponsePseudoHeaders) {
+  HeaderValidator v;
+
+  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
+    // When `:status` is missing, validation will fail.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
+    EXPECT_FALSE(v.FinishHeaderBlock(type));
+
+    // When all pseudo-headers are present, final validation will succeed.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(":status", "199"));
+    EXPECT_TRUE(v.FinishHeaderBlock(type));
+    EXPECT_EQ("199", v.status_header());
+
+    // When `:status` is repeated, validation will fail.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(":status", "199"));
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(":status", "299"));
+    EXPECT_FALSE(v.FinishHeaderBlock(type));
+
+    // When an extra pseudo-header is present, final validation will fail.
+    v.StartHeaderBlock();
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(":status", "199"));
+    EXPECT_EQ(HeaderValidator::HEADER_OK,
+              v.ValidateSingleHeader(":extra", "blorp"));
+    EXPECT_FALSE(v.FinishHeaderBlock(type));
+  }
+}
+
+TEST(HeaderValidatorTest, ResponseWithHost) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "200"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("host", "myserver.com"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
+}
+
+TEST(HeaderValidatorTest, Response204) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "204"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("x-content", "is not present"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
+}
+
+TEST(HeaderValidatorTest, Response204WithContentLengthZero) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "204"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("x-content", "is not present"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("content-length", "0"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
+}
+
+TEST(HeaderValidatorTest, Response204WithContentLength) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "204"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("x-content", "is not present"));
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("content-length", "1"));
+}
+
+TEST(HeaderValidatorTest, Response100) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "100"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("x-content", "is not present"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
+}
+
+TEST(HeaderValidatorTest, Response100WithContentLengthZero) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "100"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("x-content", "is not present"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("content-length", "0"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
+}
+
+TEST(HeaderValidatorTest, Response100WithContentLength) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "100"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("x-content", "is not present"));
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("content-length", "1"));
+}
+
+TEST(HeaderValidatorTest, ResponseTrailerPseudoHeaders) {
+  HeaderValidator v;
+
+  // When no pseudo-headers are present, validation will succeed.
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
+  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
+
+  // When any pseudo-header is present, final validation will fail.
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader(":status", "200"));
+  EXPECT_EQ(HeaderValidator::HEADER_OK, v.ValidateSingleHeader("foo", "bar"));
+  EXPECT_FALSE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
+}
+
+TEST(HeaderValidatorTest, ValidContentLength) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(v.content_length(), absl::nullopt);
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("content-length", "41"));
+  EXPECT_THAT(v.content_length(), Optional(41));
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(v.content_length(), absl::nullopt);
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("content-length", "42"));
+  EXPECT_THAT(v.content_length(), Optional(42));
+}
+
+TEST(HeaderValidatorTest, InvalidContentLength) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(v.content_length(), absl::nullopt);
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("content-length", ""));
+  EXPECT_EQ(v.content_length(), absl::nullopt);
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("content-length", "nan"));
+  EXPECT_EQ(v.content_length(), absl::nullopt);
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("content-length", "-42"));
+  EXPECT_EQ(v.content_length(), absl::nullopt);
+  // End on a positive note.
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("content-length", "42"));
+  EXPECT_THAT(v.content_length(), Optional(42));
+}
+
+TEST(HeaderValidatorTest, TeHeader) {
+  HeaderValidator v;
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_OK,
+            v.ValidateSingleHeader("te", "trailers"));
+
+  v.StartHeaderBlock();
+  EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+            v.ValidateSingleHeader("te", "trailers, deflate"));
+}
+
+TEST(HeaderValidatorTest, ConnectionSpecificHeaders) {
+  const std::vector<Header> connection_headers = {
+      {"connection", "keep-alive"}, {"proxy-connection", "keep-alive"},
+      {"keep-alive", "timeout=42"}, {"transfer-encoding", "chunked"},
+      {"upgrade", "h2c"},
+  };
+  for (const auto& [connection_key, connection_value] : connection_headers) {
+    HeaderValidator v;
+    v.StartHeaderBlock();
+    for (const auto& [sample_key, sample_value] : kSampleRequestPseudoheaders) {
+      EXPECT_EQ(HeaderValidator::HEADER_OK,
+                v.ValidateSingleHeader(sample_key, sample_value));
+    }
+    EXPECT_EQ(HeaderValidator::HEADER_FIELD_INVALID,
+              v.ValidateSingleHeader(connection_key, connection_value));
+  }
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/http2_adapter.h b/quiche/http2/adapter/http2_adapter.h
new file mode 100644
index 0000000..310c970
--- /dev/null
+++ b/quiche/http2/adapter/http2_adapter.h
@@ -0,0 +1,164 @@
+#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_
+#define QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+#include "quiche/http2/adapter/data_source.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_session.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+// Http2Adapter is an HTTP/2-processing class that exposes an interface similar
+// to the nghttp2 library for processing the HTTP/2 wire format. As nghttp2
+// parses HTTP/2 frames and invokes callbacks on Http2Adapter, Http2Adapter then
+// invokes corresponding callbacks on its passed-in Http2VisitorInterface.
+// Http2Adapter is a base class shared between client-side and server-side
+// implementations.
+class QUICHE_EXPORT_PRIVATE Http2Adapter {
+ public:
+  Http2Adapter(const Http2Adapter&) = delete;
+  Http2Adapter& operator=(const Http2Adapter&) = delete;
+
+  virtual ~Http2Adapter() {}
+
+  virtual bool IsServerSession() const = 0;
+
+  virtual bool want_read() const = 0;
+  virtual bool want_write() const = 0;
+
+  // Processes the incoming |bytes| as HTTP/2 and invokes callbacks on the
+  // |visitor_| as appropriate.
+  virtual int64_t ProcessBytes(absl::string_view bytes) = 0;
+
+  // Submits the |settings| to be written to the peer, e.g., as part of the
+  // HTTP/2 connection preface.
+  virtual void SubmitSettings(absl::Span<const Http2Setting> settings) = 0;
+
+  // Submits a PRIORITY frame for the given stream.
+  virtual void SubmitPriorityForStream(Http2StreamId stream_id,
+                                       Http2StreamId parent_stream_id,
+                                       int weight,
+                                       bool exclusive) = 0;
+
+  // Submits a PING on the connection.
+  virtual void SubmitPing(Http2PingId ping_id) = 0;
+
+  // Starts a graceful shutdown. A no-op for clients.
+  virtual void SubmitShutdownNotice() = 0;
+
+  // Submits a GOAWAY on the connection. Note that |last_accepted_stream_id|
+  // refers to stream IDs initiated by the peer. For a server sending this
+  // frame, this last stream ID must be odd (or 0).
+  virtual void SubmitGoAway(Http2StreamId last_accepted_stream_id,
+                            Http2ErrorCode error_code,
+                            absl::string_view opaque_data) = 0;
+
+  // Submits a WINDOW_UPDATE for the given stream (a |stream_id| of 0 indicates
+  // a connection-level WINDOW_UPDATE).
+  virtual void SubmitWindowUpdate(Http2StreamId stream_id,
+                                  int window_increment) = 0;
+
+  // Submits a RST_STREAM for the given |stream_id| and |error_code|.
+  virtual void SubmitRst(Http2StreamId stream_id,
+                         Http2ErrorCode error_code) = 0;
+
+  // Submits a sequence of METADATA frames for the given stream. A |stream_id|
+  // of 0 indicates connection-level METADATA.
+  virtual void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
+                              std::unique_ptr<MetadataSource> source) = 0;
+
+  // Invokes the visitor's OnReadyToSend() method for serialized frame data.
+  // Returns 0 on success.
+  virtual int Send() = 0;
+
+  // Returns the connection-level flow control window advertised by the peer.
+  virtual int GetSendWindowSize() const = 0;
+
+  // Returns the stream-level flow control window advertised by the peer.
+  virtual int GetStreamSendWindowSize(Http2StreamId stream_id) const = 0;
+
+  // Returns the current upper bound on the flow control receive window for this
+  // stream. This value does not account for data received from the peer.
+  virtual int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const = 0;
+
+  // Returns the amount of data a peer could send on a given stream. This is
+  // the outstanding stream receive window.
+  virtual int GetStreamReceiveWindowSize(Http2StreamId stream_id) const = 0;
+
+  // Returns the total amount of data a peer could send on the connection. This
+  // is the outstanding connection receive window.
+  virtual int GetReceiveWindowSize() const = 0;
+
+  // Returns the size of the HPACK encoder's dynamic table, including the
+  // per-entry overhead from the specification.
+  virtual int GetHpackEncoderDynamicTableSize() const = 0;
+
+  // Returns the size of the HPACK decoder's dynamic table, including the
+  // per-entry overhead from the specification.
+  virtual int GetHpackDecoderDynamicTableSize() const = 0;
+
+  // Gets the highest stream ID value seen in a frame received by this endpoint.
+  // This method is only guaranteed to work for server endpoints.
+  virtual Http2StreamId GetHighestReceivedStreamId() const = 0;
+
+  // Marks the given amount of data as consumed for the given stream, which
+  // enables the implementation layer to send WINDOW_UPDATEs as appropriate.
+  virtual void MarkDataConsumedForStream(Http2StreamId stream_id,
+                                         size_t num_bytes) = 0;
+
+  // Returns the assigned stream ID if the operation succeeds. Otherwise,
+  // returns a negative integer indicating an error code. |data_source| may be
+  // nullptr if the request does not have a body.
+  virtual int32_t SubmitRequest(absl::Span<const Header> headers,
+                                std::unique_ptr<DataFrameSource> data_source,
+                                void* user_data) = 0;
+
+  // Returns 0 on success. |data_source| may be nullptr if the response does not
+  // have a body.
+  virtual int SubmitResponse(Http2StreamId stream_id,
+                             absl::Span<const Header> headers,
+                             std::unique_ptr<DataFrameSource> data_source) = 0;
+
+  // Queues trailers to be sent after any outstanding data on the stream with ID
+  // |stream_id|. Returns 0 on success.
+  virtual int SubmitTrailer(Http2StreamId stream_id,
+                            absl::Span<const Header> trailers) = 0;
+
+  // Sets a user data pointer for the given stream. Can be called after
+  // SubmitRequest/SubmitResponse, or after receiving any frame for a given
+  // stream.
+  virtual void SetStreamUserData(Http2StreamId stream_id, void* user_data) = 0;
+
+  // Returns nullptr if the stream does not exist, or if stream user data has
+  // not been set.
+  virtual void* GetStreamUserData(Http2StreamId stream_id) = 0;
+
+  // Resumes a stream that was previously blocked (for example, due to
+  // DataFrameSource::SelectPayloadLength() returning kBlocked). Returns true if
+  // the stream was successfully resumed.
+  virtual bool ResumeStream(Http2StreamId stream_id) = 0;
+
+ protected:
+  // Subclasses should expose a public factory method for constructing and
+  // initializing (via Initialize()) adapter instances.
+  explicit Http2Adapter(Http2VisitorInterface& visitor) : visitor_(visitor) {}
+
+  // Accessors. Do not transfer ownership.
+  Http2VisitorInterface& visitor() { return visitor_; }
+
+ private:
+  // Http2Adapter will invoke callbacks upon the |visitor_| while processing.
+  Http2VisitorInterface& visitor_;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_ADAPTER_H_
diff --git a/quiche/http2/adapter/http2_protocol.cc b/quiche/http2/adapter/http2_protocol.cc
new file mode 100644
index 0000000..7281050
--- /dev/null
+++ b/quiche/http2/adapter/http2_protocol.cc
@@ -0,0 +1,85 @@
+#include "quiche/http2/adapter/http2_protocol.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+
+namespace http2 {
+namespace adapter {
+
+const char kHttp2MethodPseudoHeader[] = ":method";
+const char kHttp2SchemePseudoHeader[] = ":scheme";
+const char kHttp2AuthorityPseudoHeader[] = ":authority";
+const char kHttp2PathPseudoHeader[] = ":path";
+const char kHttp2StatusPseudoHeader[] = ":status";
+
+const uint8_t kMetadataFrameType = 0x4d;
+const uint8_t kMetadataEndFlag = 0x04;
+const uint16_t kMetadataExtensionId = 0x4d44;
+
+std::pair<absl::string_view, bool> GetStringView(const HeaderRep& rep) {
+  if (absl::holds_alternative<absl::string_view>(rep)) {
+    return std::make_pair(absl::get<absl::string_view>(rep), true);
+  } else {
+    absl::string_view view = absl::get<std::string>(rep);
+    return std::make_pair(view, false);
+  }
+}
+
+bool operator==(const Http2Setting& a, const Http2Setting& b) {
+  return a.id == b.id && a.value == b.value;
+}
+
+absl::string_view Http2SettingsIdToString(uint16_t id) {
+  switch (id) {
+    case Http2KnownSettingsId::HEADER_TABLE_SIZE:
+      return "SETTINGS_HEADER_TABLE_SIZE";
+    case Http2KnownSettingsId::ENABLE_PUSH:
+      return "SETTINGS_ENABLE_PUSH";
+    case Http2KnownSettingsId::MAX_CONCURRENT_STREAMS:
+      return "SETTINGS_MAX_CONCURRENT_STREAMS";
+    case Http2KnownSettingsId::INITIAL_WINDOW_SIZE:
+      return "SETTINGS_INITIAL_WINDOW_SIZE";
+    case Http2KnownSettingsId::MAX_FRAME_SIZE:
+      return "SETTINGS_MAX_FRAME_SIZE";
+    case Http2KnownSettingsId::MAX_HEADER_LIST_SIZE:
+      return "SETTINGS_MAX_HEADER_LIST_SIZE";
+  }
+  return "SETTINGS_UNKNOWN";
+}
+
+absl::string_view Http2ErrorCodeToString(Http2ErrorCode error_code) {
+  switch (error_code) {
+    case Http2ErrorCode::HTTP2_NO_ERROR:
+      return "HTTP2_NO_ERROR";
+    case Http2ErrorCode::PROTOCOL_ERROR:
+      return "PROTOCOL_ERROR";
+    case Http2ErrorCode::INTERNAL_ERROR:
+      return "INTERNAL_ERROR";
+    case Http2ErrorCode::FLOW_CONTROL_ERROR:
+      return "FLOW_CONTROL_ERROR";
+    case Http2ErrorCode::SETTINGS_TIMEOUT:
+      return "SETTINGS_TIMEOUT";
+    case Http2ErrorCode::STREAM_CLOSED:
+      return "STREAM_CLOSED";
+    case Http2ErrorCode::FRAME_SIZE_ERROR:
+      return "FRAME_SIZE_ERROR";
+    case Http2ErrorCode::REFUSED_STREAM:
+      return "REFUSED_STREAM";
+    case Http2ErrorCode::CANCEL:
+      return "CANCEL";
+    case Http2ErrorCode::COMPRESSION_ERROR:
+      return "COMPRESSION_ERROR";
+    case Http2ErrorCode::CONNECT_ERROR:
+      return "CONNECT_ERROR";
+    case Http2ErrorCode::ENHANCE_YOUR_CALM:
+      return "ENHANCE_YOUR_CALM";
+    case Http2ErrorCode::INADEQUATE_SECURITY:
+      return "INADEQUATE_SECURITY";
+    case Http2ErrorCode::HTTP_1_1_REQUIRED:
+      return "HTTP_1_1_REQUIRED";
+  }
+  return "UNKNOWN_ERROR";
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/http2_protocol.h b/quiche/http2/adapter/http2_protocol.h
new file mode 100644
index 0000000..817d6be
--- /dev/null
+++ b/quiche/http2/adapter/http2_protocol.h
@@ -0,0 +1,145 @@
+#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_PROTOCOL_H_
+#define QUICHE_HTTP2_ADAPTER_HTTP2_PROTOCOL_H_
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/variant.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+// Represents an HTTP/2 stream ID, consistent with nghttp2.
+using Http2StreamId = int32_t;
+
+// Represents an HTTP/2 SETTINGS parameter as specified in RFC 7540 Section 6.5.
+using Http2SettingsId = uint16_t;
+
+// Represents the payload of an HTTP/2 PING frame.
+using Http2PingId = uint64_t;
+
+// Represents a single header name or value.
+using HeaderRep = absl::variant<absl::string_view, std::string>;
+
+// Boolean return value is true if |rep| holds a string_view, which is assumed
+// to have an indefinite lifetime.
+std::pair<absl::string_view, bool> GetStringView(const HeaderRep& rep);
+
+// Represents an HTTP/2 header field. A header field is a key-value pair with
+// lowercase keys (as specified in RFC 7540 Section 8.1.2).
+using Header = std::pair<HeaderRep, HeaderRep>;
+
+// Represents an HTTP/2 SETTINGS key-value parameter.
+struct QUICHE_EXPORT_PRIVATE Http2Setting {
+  Http2SettingsId id;
+  uint32_t value;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2Setting& a,
+                                      const Http2Setting& b);
+
+// The maximum possible stream ID.
+const Http2StreamId kMaxStreamId = 0x7FFFFFFF;
+
+// The stream ID that represents the connection (e.g., for connection-level flow
+// control updates).
+const Http2StreamId kConnectionStreamId = 0;
+
+// The default value for the size of the largest frame payload, according to RFC
+// 7540 Section 6.5.2 (SETTINGS_MAX_FRAME_SIZE).
+const int kDefaultFramePayloadSizeLimit = 16 * 1024;
+
+// The default value for the initial stream and connection flow control window
+// size, according to RFC 7540 Section 6.9.2.
+const int kInitialFlowControlWindowSize = 64 * 1024 - 1;
+
+// The pseudo-header fields as specified in RFC 7540 Section 8.1.2.3 (request)
+// and Section 8.1.2.4 (response).
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
+    kHttp2MethodPseudoHeader[];
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
+    kHttp2SchemePseudoHeader[];
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
+    kHttp2AuthorityPseudoHeader[];
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
+    kHttp2PathPseudoHeader[];
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const char
+    kHttp2StatusPseudoHeader[];
+
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const uint8_t kMetadataFrameType;
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const uint8_t kMetadataEndFlag;
+ABSL_CONST_INIT QUICHE_EXPORT_PRIVATE extern const uint16_t
+    kMetadataExtensionId;
+
+enum class FrameType : uint8_t {
+  DATA = 0x0,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+  CONTINUATION,
+};
+
+// HTTP/2 error codes as specified in RFC 7540 Section 7.
+enum class Http2ErrorCode {
+  HTTP2_NO_ERROR = 0x0,
+  PROTOCOL_ERROR = 0x1,
+  INTERNAL_ERROR = 0x2,
+  FLOW_CONTROL_ERROR = 0x3,
+  SETTINGS_TIMEOUT = 0x4,
+  STREAM_CLOSED = 0x5,
+  FRAME_SIZE_ERROR = 0x6,
+  REFUSED_STREAM = 0x7,
+  CANCEL = 0x8,
+  COMPRESSION_ERROR = 0x9,
+  CONNECT_ERROR = 0xA,
+  ENHANCE_YOUR_CALM = 0xB,
+  INADEQUATE_SECURITY = 0xC,
+  HTTP_1_1_REQUIRED = 0xD,
+  MAX_ERROR_CODE = HTTP_1_1_REQUIRED,
+};
+
+// The SETTINGS parameters defined in RFC 7540 Section 6.5.2. Endpoints may send
+// SETTINGS parameters outside of these definitions as per RFC 7540 Section 5.5.
+// This is explicitly an enum instead of an enum class for ease of implicit
+// conversion to the underlying Http2SettingsId type and use with non-standard
+// extension SETTINGS parameters.
+enum Http2KnownSettingsId : Http2SettingsId {
+  HEADER_TABLE_SIZE = 0x1,
+  MIN_SETTING = HEADER_TABLE_SIZE,
+  ENABLE_PUSH = 0x2,
+  MAX_CONCURRENT_STREAMS = 0x3,
+  INITIAL_WINDOW_SIZE = 0x4,
+  MAX_FRAME_SIZE = 0x5,
+  MAX_HEADER_LIST_SIZE = 0x6,
+  ENABLE_CONNECT_PROTOCOL = 0x8,  // See RFC 8441
+  MAX_SETTING = ENABLE_CONNECT_PROTOCOL
+};
+
+// Returns a human-readable string representation of the given SETTINGS |id| for
+// logging/debugging. Returns "SETTINGS_UNKNOWN" for IDs outside of the RFC 7540
+// Section 6.5.2 definitions.
+absl::string_view Http2SettingsIdToString(uint16_t id);
+
+// Returns a human-readable string representation of the given |error_code| for
+// logging/debugging. Returns "UNKNOWN_ERROR" for errors outside of RFC 7540
+// Section 7 definitions.
+absl::string_view Http2ErrorCodeToString(Http2ErrorCode error_code);
+
+enum class Perspective {
+  kClient,
+  kServer,
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_PROTOCOL_H_
diff --git a/quiche/http2/adapter/http2_session.h b/quiche/http2/adapter/http2_session.h
new file mode 100644
index 0000000..0a76726
--- /dev/null
+++ b/quiche/http2/adapter/http2_session.h
@@ -0,0 +1,33 @@
+#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_SESSION_H_
+#define QUICHE_HTTP2_ADAPTER_HTTP2_SESSION_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+struct QUICHE_EXPORT_PRIVATE Http2SessionCallbacks {};
+
+// A class to represent the state of a single HTTP/2 connection.
+class QUICHE_EXPORT_PRIVATE Http2Session {
+ public:
+  Http2Session() = default;
+  virtual ~Http2Session() {}
+
+  virtual int64_t ProcessBytes(absl::string_view bytes) = 0;
+
+  virtual int Consume(Http2StreamId stream_id, size_t num_bytes) = 0;
+
+  virtual bool want_read() const = 0;
+  virtual bool want_write() const = 0;
+  virtual int GetRemoteWindowSize() const = 0;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_SESSION_H_
diff --git a/quiche/http2/adapter/http2_util.cc b/quiche/http2/adapter/http2_util.cc
new file mode 100644
index 0000000..7cca26b
--- /dev/null
+++ b/quiche/http2/adapter/http2_util.cc
@@ -0,0 +1,130 @@
+#include "quiche/http2/adapter/http2_util.h"
+
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+namespace {
+
+using ConnectionError = Http2VisitorInterface::ConnectionError;
+using InvalidFrameError = Http2VisitorInterface::InvalidFrameError;
+
+}  // anonymous namespace
+
+spdy::SpdyErrorCode TranslateErrorCode(Http2ErrorCode code) {
+  switch (code) {
+    case Http2ErrorCode::HTTP2_NO_ERROR:
+      return spdy::ERROR_CODE_NO_ERROR;
+    case Http2ErrorCode::PROTOCOL_ERROR:
+      return spdy::ERROR_CODE_PROTOCOL_ERROR;
+    case Http2ErrorCode::INTERNAL_ERROR:
+      return spdy::ERROR_CODE_INTERNAL_ERROR;
+    case Http2ErrorCode::FLOW_CONTROL_ERROR:
+      return spdy::ERROR_CODE_FLOW_CONTROL_ERROR;
+    case Http2ErrorCode::SETTINGS_TIMEOUT:
+      return spdy::ERROR_CODE_SETTINGS_TIMEOUT;
+    case Http2ErrorCode::STREAM_CLOSED:
+      return spdy::ERROR_CODE_STREAM_CLOSED;
+    case Http2ErrorCode::FRAME_SIZE_ERROR:
+      return spdy::ERROR_CODE_FRAME_SIZE_ERROR;
+    case Http2ErrorCode::REFUSED_STREAM:
+      return spdy::ERROR_CODE_REFUSED_STREAM;
+    case Http2ErrorCode::CANCEL:
+      return spdy::ERROR_CODE_CANCEL;
+    case Http2ErrorCode::COMPRESSION_ERROR:
+      return spdy::ERROR_CODE_COMPRESSION_ERROR;
+    case Http2ErrorCode::CONNECT_ERROR:
+      return spdy::ERROR_CODE_CONNECT_ERROR;
+    case Http2ErrorCode::ENHANCE_YOUR_CALM:
+      return spdy::ERROR_CODE_ENHANCE_YOUR_CALM;
+    case Http2ErrorCode::INADEQUATE_SECURITY:
+      return spdy::ERROR_CODE_INADEQUATE_SECURITY;
+    case Http2ErrorCode::HTTP_1_1_REQUIRED:
+      return spdy::ERROR_CODE_HTTP_1_1_REQUIRED;
+  }
+  return spdy::ERROR_CODE_INTERNAL_ERROR;
+}
+
+Http2ErrorCode TranslateErrorCode(spdy::SpdyErrorCode code) {
+  switch (code) {
+    case spdy::ERROR_CODE_NO_ERROR:
+      return Http2ErrorCode::HTTP2_NO_ERROR;
+    case spdy::ERROR_CODE_PROTOCOL_ERROR:
+      return Http2ErrorCode::PROTOCOL_ERROR;
+    case spdy::ERROR_CODE_INTERNAL_ERROR:
+      return Http2ErrorCode::INTERNAL_ERROR;
+    case spdy::ERROR_CODE_FLOW_CONTROL_ERROR:
+      return Http2ErrorCode::FLOW_CONTROL_ERROR;
+    case spdy::ERROR_CODE_SETTINGS_TIMEOUT:
+      return Http2ErrorCode::SETTINGS_TIMEOUT;
+    case spdy::ERROR_CODE_STREAM_CLOSED:
+      return Http2ErrorCode::STREAM_CLOSED;
+    case spdy::ERROR_CODE_FRAME_SIZE_ERROR:
+      return Http2ErrorCode::FRAME_SIZE_ERROR;
+    case spdy::ERROR_CODE_REFUSED_STREAM:
+      return Http2ErrorCode::REFUSED_STREAM;
+    case spdy::ERROR_CODE_CANCEL:
+      return Http2ErrorCode::CANCEL;
+    case spdy::ERROR_CODE_COMPRESSION_ERROR:
+      return Http2ErrorCode::COMPRESSION_ERROR;
+    case spdy::ERROR_CODE_CONNECT_ERROR:
+      return Http2ErrorCode::CONNECT_ERROR;
+    case spdy::ERROR_CODE_ENHANCE_YOUR_CALM:
+      return Http2ErrorCode::ENHANCE_YOUR_CALM;
+    case spdy::ERROR_CODE_INADEQUATE_SECURITY:
+      return Http2ErrorCode::INADEQUATE_SECURITY;
+    case spdy::ERROR_CODE_HTTP_1_1_REQUIRED:
+      return Http2ErrorCode::HTTP_1_1_REQUIRED;
+  }
+  return Http2ErrorCode::INTERNAL_ERROR;
+}
+
+absl::string_view ConnectionErrorToString(ConnectionError error) {
+  switch (error) {
+    case ConnectionError::kInvalidConnectionPreface:
+      return "InvalidConnectionPreface";
+    case ConnectionError::kSendError:
+      return "SendError";
+    case ConnectionError::kParseError:
+      return "ParseError";
+    case ConnectionError::kHeaderError:
+      return "HeaderError";
+    case ConnectionError::kInvalidNewStreamId:
+      return "InvalidNewStreamId";
+    case ConnectionError::kWrongFrameSequence:
+      return "kWrongFrameSequence";
+    case ConnectionError::kInvalidPushPromise:
+      return "InvalidPushPromise";
+    case ConnectionError::kExceededMaxConcurrentStreams:
+      return "ExceededMaxConcurrentStreams";
+    case ConnectionError::kFlowControlError:
+      return "FlowControlError";
+  }
+  return "UnknownConnectionError";
+}
+
+absl::string_view InvalidFrameErrorToString(
+    Http2VisitorInterface::InvalidFrameError error) {
+  switch (error) {
+    case InvalidFrameError::kProtocol:
+      return "Protocol";
+    case InvalidFrameError::kRefusedStream:
+      return "RefusedStream";
+    case InvalidFrameError::kHttpHeader:
+      return "HttpHeader";
+    case InvalidFrameError::kHttpMessaging:
+      return "HttpMessaging";
+    case InvalidFrameError::kFlowControl:
+      return "FlowControl";
+    case InvalidFrameError::kStreamClosed:
+      return "StreamClosed";
+  }
+  return "UnknownInvalidFrameError";
+}
+
+bool DeltaAtLeastHalfLimit(int64_t limit, int64_t /*size*/, int64_t delta) {
+  return delta > 0 && delta >= limit / 2;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/http2_util.h b/quiche/http2/adapter/http2_util.h
new file mode 100644
index 0000000..00580a3
--- /dev/null
+++ b/quiche/http2/adapter/http2_util.h
@@ -0,0 +1,34 @@
+#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_UTIL_H_
+#define QUICHE_HTTP2_ADAPTER_HTTP2_UTIL_H_
+
+#include <cstdint>
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+
+QUICHE_EXPORT_PRIVATE spdy::SpdyErrorCode TranslateErrorCode(
+    Http2ErrorCode code);
+QUICHE_EXPORT_PRIVATE Http2ErrorCode
+TranslateErrorCode(spdy::SpdyErrorCode code);
+
+QUICHE_EXPORT_PRIVATE absl::string_view ConnectionErrorToString(
+    Http2VisitorInterface::ConnectionError error);
+
+QUICHE_EXPORT_PRIVATE absl::string_view InvalidFrameErrorToString(
+    Http2VisitorInterface::InvalidFrameError error);
+
+// A WINDOW_UPDATE sending strategy that returns true if the `delta` to be sent
+// is positive and at least half of the window `limit`.
+QUICHE_EXPORT_PRIVATE bool DeltaAtLeastHalfLimit(int64_t limit,
+                                                 int64_t /*size*/,
+                                                 int64_t delta);
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_UTIL_H_
diff --git a/quiche/http2/adapter/http2_visitor_interface.h b/quiche/http2/adapter/http2_visitor_interface.h
new file mode 100644
index 0000000..012d91a
--- /dev/null
+++ b/quiche/http2/adapter/http2_visitor_interface.h
@@ -0,0 +1,260 @@
+#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
+#define QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+// Http2VisitorInterface contains callbacks for receiving HTTP/2-level events. A
+// processor like NghttpAdapter parses HTTP/2 frames and invokes the callbacks
+// on an instance of this interface. Prefer a void return type for these
+// callbacks, instead setting output parameters as needed.
+//
+// Example sequences of calls/events:
+//   GET:
+//     - OnBeginHeadersForStream()
+//     - OnHeaderForStream()
+//     - OnEndHeadersForStream()
+//     - OnEndStream()
+//
+//   POST:
+//     - OnBeginHeadersForStream()
+//     - OnHeaderForStream()
+//     - OnEndHeadersForStream()
+//     - OnBeginDataForStream()
+//     - OnDataForStream()
+//     - OnEndStream()
+//
+//   Request canceled mid-stream, e.g, with error code CANCEL:
+//     - OnBeginHeadersForStream()
+//     - OnHeaderForStream()
+//     - OnEndHeadersForStream()
+//     - OnRstStream()
+//     - OnCloseStream()
+//
+//   Request closed mid-stream, e.g., with error code NO_ERROR:
+//     - OnBeginHeadersForStream()
+//     - OnHeaderForStream()
+//     - OnEndHeadersForStream()
+//     - OnRstStream()
+//     - OnCloseStream()
+//
+// More details are at RFC 7540 (go/http2spec).
+class QUICHE_EXPORT_PRIVATE Http2VisitorInterface {
+ public:
+  Http2VisitorInterface(const Http2VisitorInterface&) = delete;
+  Http2VisitorInterface& operator=(const Http2VisitorInterface&) = delete;
+  virtual ~Http2VisitorInterface() = default;
+
+  enum : int64_t {
+    kSendBlocked = 0,
+    kSendError = -1,
+  };
+  // Called when there are serialized frames to send. Should return how many
+  // bytes were actually sent. May return kSendBlocked or kSendError.
+  virtual int64_t OnReadyToSend(absl::string_view serialized) = 0;
+
+  // Called when a connection-level error has occurred.
+  enum class ConnectionError {
+    // The peer sent an invalid connection preface.
+    kInvalidConnectionPreface,
+    // The visitor encountered an error sending bytes to the peer.
+    kSendError,
+    // There was an error reading and framing bytes from the peer.
+    kParseError,
+    // The visitor considered a received header to be a connection error.
+    kHeaderError,
+    // The peer attempted to open a stream with an invalid stream ID.
+    kInvalidNewStreamId,
+    // The peer sent a frame that is invalid on an idle stream (before HEADERS).
+    kWrongFrameSequence,
+    // The peer sent an invalid PUSH_PROMISE frame.
+    kInvalidPushPromise,
+    // The peer exceeded the max concurrent streams limit.
+    kExceededMaxConcurrentStreams,
+    // The peer caused a flow control error.
+    kFlowControlError,
+  };
+  virtual void OnConnectionError(ConnectionError error) = 0;
+
+  // Called when the header for a frame is received. Returns false if a fatal
+  // error has occurred.
+  virtual bool OnFrameHeader(Http2StreamId /*stream_id*/, size_t /*length*/,
+                             uint8_t /*type*/, uint8_t /*flags*/) {
+    return true;
+  }
+
+  // Called when a non-ack SETTINGS frame is received.
+  virtual void OnSettingsStart() = 0;
+
+  // Called for each SETTINGS id-value pair.
+  virtual void OnSetting(Http2Setting setting) = 0;
+
+  // Called at the end of a non-ack SETTINGS frame.
+  virtual void OnSettingsEnd() = 0;
+
+  // Called when a SETTINGS ack frame is received.
+  virtual void OnSettingsAck() = 0;
+
+  // Called when the connection receives the header block for a HEADERS frame on
+  // a stream but has not yet parsed individual headers. Returns false if a
+  // fatal error has occurred.
+  virtual bool OnBeginHeadersForStream(Http2StreamId stream_id) = 0;
+
+  // Called when the connection receives the header |key| and |value| for a
+  // stream. The HTTP/2 pseudo-headers defined in RFC 7540 Sections 8.1.2.3 and
+  // 8.1.2.4 are also conveyed in this callback. This method is called after
+  // OnBeginHeadersForStream(). May return HEADER_RST_STREAM to indicate the
+  // header block should be rejected. This will cause the library to queue a
+  // RST_STREAM frame, which will have a default error code of INTERNAL_ERROR.
+  // The visitor implementation may choose to queue a RST_STREAM with a
+  // different error code instead, which should be done before returning
+  // HEADER_RST_STREAM. Returning HEADER_CONNECTION_ERROR will lead to a
+  // non-recoverable error on the connection.
+  enum OnHeaderResult {
+    // The header was accepted.
+    HEADER_OK,
+    // The application considers the header a connection error.
+    HEADER_CONNECTION_ERROR,
+    // The application rejects the header and requests the stream be reset.
+    HEADER_RST_STREAM,
+    // The header field is invalid and will be reset with error code
+    // PROTOCOL_ERROR.
+    HEADER_FIELD_INVALID,
+    // The headers are a violation of HTTP messaging semantics and will be reset
+    // with error code PROTOCOL_ERROR.
+    HEADER_HTTP_MESSAGING,
+    // The headers caused a compression context error.
+    HEADER_COMPRESSION_ERROR,
+  };
+  virtual OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
+                                           absl::string_view key,
+                                           absl::string_view value) = 0;
+
+  // Called when the connection has received the complete header block for a
+  // logical HEADERS frame on a stream (which may contain CONTINUATION frames,
+  // transparent to the user). Returns false if a fatal error has occurred.
+  virtual bool OnEndHeadersForStream(Http2StreamId stream_id) = 0;
+
+  // Called when the connection receives the beginning of a DATA frame. The data
+  // payload will be provided via subsequent calls to OnDataForStream(). Returns
+  // false if a fatal error has occurred.
+  virtual bool OnBeginDataForStream(Http2StreamId stream_id,
+                                    size_t payload_length) = 0;
+
+  // Called when the optional padding length field is parsed as part of a DATA
+  // frame payload. `padding_length` represents the total amount of padding for
+  // this frame, including the length byte itself. Returns false if a fatal
+  // error has occurred.
+  virtual bool OnDataPaddingLength(Http2StreamId stream_id,
+                                   size_t padding_length) = 0;
+
+  // Called when the connection receives some |data| (as part of a DATA frame
+  // payload) for a stream. Returns false if a fatal error has occurred.
+  virtual bool OnDataForStream(Http2StreamId stream_id,
+                               absl::string_view data) = 0;
+
+  // Called when the peer sends the END_STREAM flag on a stream, indicating that
+  // the peer will not send additional headers or data for that stream.
+  virtual void OnEndStream(Http2StreamId stream_id) = 0;
+
+  // Called when the connection receives a RST_STREAM for a stream. This call
+  // will be followed by either OnCloseStream().
+  virtual void OnRstStream(Http2StreamId stream_id,
+                           Http2ErrorCode error_code) = 0;
+
+  // Called when a stream is closed. Returns false if a fatal error has
+  // occurred.
+  virtual bool OnCloseStream(Http2StreamId stream_id,
+                             Http2ErrorCode error_code) = 0;
+
+  // Called when the connection receives a PRIORITY frame.
+  virtual void OnPriorityForStream(Http2StreamId stream_id,
+                                   Http2StreamId parent_stream_id, int weight,
+                                   bool exclusive) = 0;
+
+  // Called when the connection receives a PING frame.
+  virtual void OnPing(Http2PingId ping_id, bool is_ack) = 0;
+
+  // Called when the connection receives a PUSH_PROMISE frame. The server push
+  // request headers follow in calls to OnHeaderForStream() with |stream_id|.
+  virtual void OnPushPromiseForStream(Http2StreamId stream_id,
+                                      Http2StreamId promised_stream_id) = 0;
+
+  // Called when the connection receives a GOAWAY frame. Returns false if a
+  // fatal error has occurred.
+  virtual bool OnGoAway(Http2StreamId last_accepted_stream_id,
+                        Http2ErrorCode error_code,
+                        absl::string_view opaque_data) = 0;
+
+  // Called when the connection receives a WINDOW_UPDATE frame. For
+  // connection-level window updates, the |stream_id| will be 0.
+  virtual void OnWindowUpdate(Http2StreamId stream_id,
+                              int window_increment) = 0;
+
+  // Called immediately before a frame of the given type is sent. Should return
+  // 0 on success.
+  virtual int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
+                                size_t length, uint8_t flags) = 0;
+
+  // Called immediately after a frame of the given type is sent. Should return 0
+  // on success. |error_code| is only populated for RST_STREAM and GOAWAY frame
+  // types.
+  virtual int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
+                          size_t length, uint8_t flags,
+                          uint32_t error_code) = 0;
+
+  // Called when the connection receives an invalid frame. A return value of
+  // false will result in the connection entering an error state, with no
+  // further frame processing possible.
+  enum class InvalidFrameError {
+    // The frame contains a general protocol error.
+    kProtocol,
+    // The frame would have caused a new (invalid) stream to be opened.
+    kRefusedStream,
+    // The frame contains an invalid header field.
+    kHttpHeader,
+    // The frame contains a violation in HTTP messaging rules.
+    kHttpMessaging,
+    // The frame causes a flow control error.
+    kFlowControl,
+    // The frame is on an already closed stream or has an invalid stream ID.
+    kStreamClosed,
+  };
+  virtual bool OnInvalidFrame(Http2StreamId stream_id,
+                              InvalidFrameError error) = 0;
+
+  // Called when the connection receives the beginning of a METADATA frame
+  // (which may itself be the middle of a logical metadata block). The metadata
+  // payload will be provided via subsequent calls to OnMetadataForStream().
+  // TODO(birenroy): Consider removing this unnecessary method.
+  virtual void OnBeginMetadataForStream(Http2StreamId stream_id,
+                                        size_t payload_length) = 0;
+
+  // Called when the connection receives |metadata| as part of a METADATA frame
+  // payload for a stream. Returns false if a fatal error has occurred.
+  virtual bool OnMetadataForStream(Http2StreamId stream_id,
+                                   absl::string_view metadata) = 0;
+
+  // Called when the connection has finished receiving a logical metadata block
+  // for a stream. Note that there may be multiple metadata blocks for a stream.
+  // Returns false if there was an error unpacking the metadata payload.
+  virtual bool OnMetadataEndForStream(Http2StreamId stream_id) = 0;
+
+  // Invoked with an error message from the application.
+  virtual void OnErrorDebug(absl::string_view message) = 0;
+
+ protected:
+  Http2VisitorInterface() = default;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
diff --git a/quiche/http2/adapter/mock_http2_visitor.h b/quiche/http2/adapter/mock_http2_visitor.h
new file mode 100644
index 0000000..8da7d81
--- /dev/null
+++ b/quiche/http2/adapter/mock_http2_visitor.h
@@ -0,0 +1,131 @@
+#ifndef QUICHE_HTTP2_ADAPTER_MOCK_HTTP2_VISITOR_INTERFACE_H_
+#define QUICHE_HTTP2_ADAPTER_MOCK_HTTP2_VISITOR_INTERFACE_H_
+
+#include <cstdint>
+
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+// A mock visitor class, for use in tests.
+class QUICHE_NO_EXPORT MockHttp2Visitor : public Http2VisitorInterface {
+ public:
+  MockHttp2Visitor() {
+    ON_CALL(*this, OnFrameHeader).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnBeginHeadersForStream)
+        .WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnHeaderForStream).WillByDefault(testing::Return(HEADER_OK));
+    ON_CALL(*this, OnEndHeadersForStream).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnDataPaddingLength).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnBeginDataForStream).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnDataForStream).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnCloseStream).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnGoAway).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnInvalidFrame).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnMetadataForStream).WillByDefault(testing::Return(true));
+    ON_CALL(*this, OnMetadataEndForStream).WillByDefault(testing::Return(true));
+  }
+
+  MOCK_METHOD(int64_t, OnReadyToSend, (absl::string_view serialized),
+              (override));
+  MOCK_METHOD(void, OnConnectionError, (ConnectionError error), (override));
+  MOCK_METHOD(bool, OnFrameHeader,
+              (Http2StreamId stream_id, size_t length, uint8_t type,
+               uint8_t flags),
+              (override));
+  MOCK_METHOD(void, OnSettingsStart, (), (override));
+  MOCK_METHOD(void, OnSetting, (Http2Setting setting), (override));
+  MOCK_METHOD(void, OnSettingsEnd, (), (override));
+  MOCK_METHOD(void, OnSettingsAck, (), (override));
+  MOCK_METHOD(bool, OnBeginHeadersForStream, (Http2StreamId stream_id),
+              (override));
+
+  MOCK_METHOD(OnHeaderResult, OnHeaderForStream,
+              (Http2StreamId stream_id, absl::string_view key,
+               absl::string_view value),
+              (override));
+
+  MOCK_METHOD(bool, OnEndHeadersForStream, (Http2StreamId stream_id),
+              (override));
+
+  MOCK_METHOD(bool, OnDataPaddingLength,
+              (Http2StreamId strema_id, size_t padding_length), (override));
+
+  MOCK_METHOD(bool, OnBeginDataForStream,
+              (Http2StreamId stream_id, size_t payload_length), (override));
+
+  MOCK_METHOD(bool, OnDataForStream,
+              (Http2StreamId stream_id, absl::string_view data), (override));
+
+  MOCK_METHOD(void, OnEndStream, (Http2StreamId stream_id), (override));
+
+  MOCK_METHOD(void,
+              OnRstStream,
+              (Http2StreamId stream_id, Http2ErrorCode error_code),
+              (override));
+
+  MOCK_METHOD(bool, OnCloseStream,
+              (Http2StreamId stream_id, Http2ErrorCode error_code), (override));
+
+  MOCK_METHOD(void,
+              OnPriorityForStream,
+              (Http2StreamId stream_id,
+               Http2StreamId parent_stream_id,
+               int weight,
+               bool exclusive),
+              (override));
+
+  MOCK_METHOD(void, OnPing, (Http2PingId ping_id, bool is_ack), (override));
+
+  MOCK_METHOD(void,
+              OnPushPromiseForStream,
+              (Http2StreamId stream_id, Http2StreamId promised_stream_id),
+              (override));
+
+  MOCK_METHOD(bool, OnGoAway,
+              (Http2StreamId last_accepted_stream_id, Http2ErrorCode error_code,
+               absl::string_view opaque_data),
+              (override));
+
+  MOCK_METHOD(void,
+              OnWindowUpdate,
+              (Http2StreamId stream_id, int window_increment),
+              (override));
+
+  MOCK_METHOD(int, OnBeforeFrameSent,
+              (uint8_t frame_type, Http2StreamId stream_id, size_t length,
+               uint8_t flags),
+              (override));
+
+  MOCK_METHOD(int, OnFrameSent,
+              (uint8_t frame_type, Http2StreamId stream_id, size_t length,
+               uint8_t flags, uint32_t error_code),
+              (override));
+
+  MOCK_METHOD(bool, OnInvalidFrame,
+              (Http2StreamId stream_id, InvalidFrameError error), (override));
+
+  MOCK_METHOD(void,
+              OnBeginMetadataForStream,
+              (Http2StreamId stream_id, size_t payload_length),
+              (override));
+
+  MOCK_METHOD(bool, OnMetadataForStream,
+              (Http2StreamId stream_id, absl::string_view metadata),
+              (override));
+
+  MOCK_METHOD(bool, OnMetadataEndForStream, (Http2StreamId stream_id),
+              (override));
+
+  MOCK_METHOD(void, OnErrorDebug, (absl::string_view message), (override));
+};
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_MOCK_HTTP2_VISITOR_INTERFACE_H_
diff --git a/quiche/http2/adapter/mock_nghttp2_callbacks.cc b/quiche/http2/adapter/mock_nghttp2_callbacks.cc
new file mode 100644
index 0000000..20ac327
--- /dev/null
+++ b/quiche/http2/adapter/mock_nghttp2_callbacks.cc
@@ -0,0 +1,130 @@
+#include "quiche/http2/adapter/mock_nghttp2_callbacks.h"
+
+#include "quiche/http2/adapter/nghttp2_util.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+/* static */
+nghttp2_session_callbacks_unique_ptr MockNghttp2Callbacks::GetCallbacks() {
+  nghttp2_session_callbacks* callbacks;
+  nghttp2_session_callbacks_new(&callbacks);
+
+  // All of the callback implementations below just delegate to the mock methods
+  // of |user_data|, which is assumed to be a MockNghttp2Callbacks*.
+  nghttp2_session_callbacks_set_send_callback(
+      callbacks,
+      [](nghttp2_session*, const uint8_t* data, size_t length, int flags,
+         void* user_data) -> ssize_t {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->Send(data, length,
+                                                                   flags);
+      });
+
+  nghttp2_session_callbacks_set_send_data_callback(
+      callbacks,
+      [](nghttp2_session*, nghttp2_frame* frame, const uint8_t* framehd,
+         size_t length, nghttp2_data_source* source, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->SendData(
+            frame, framehd, length, source);
+      });
+
+  nghttp2_session_callbacks_set_on_begin_headers_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnBeginHeaders(
+            frame);
+      });
+
+  nghttp2_session_callbacks_set_on_header_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, const uint8_t* raw_name,
+         size_t name_length, const uint8_t* raw_value, size_t value_length,
+         uint8_t flags, void* user_data) -> int {
+        absl::string_view name = ToStringView(raw_name, name_length);
+        absl::string_view value = ToStringView(raw_value, value_length);
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnHeader(
+            frame, name, value, flags);
+      });
+
+  nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
+      callbacks,
+      [](nghttp2_session*, uint8_t flags, int32_t stream_id,
+         const uint8_t* data, size_t len, void* user_data) -> int {
+        absl::string_view chunk = ToStringView(data, len);
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnDataChunkRecv(
+            flags, stream_id, chunk);
+      });
+
+  nghttp2_session_callbacks_set_on_begin_frame_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame_hd* hd, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnBeginFrame(hd);
+      });
+
+  nghttp2_session_callbacks_set_on_frame_recv_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameRecv(
+            frame);
+      });
+
+  nghttp2_session_callbacks_set_on_stream_close_callback(
+      callbacks,
+      [](nghttp2_session*, int32_t stream_id, uint32_t error_code,
+         void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnStreamClose(
+            stream_id, error_code);
+      });
+
+  nghttp2_session_callbacks_set_on_frame_send_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameSend(
+            frame);
+      });
+
+  nghttp2_session_callbacks_set_before_frame_send_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->BeforeFrameSend(
+            frame);
+      });
+
+  nghttp2_session_callbacks_set_on_frame_not_send_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, int lib_error_code,
+         void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameNotSend(
+            frame, lib_error_code);
+      });
+
+  nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
+      callbacks,
+      [](nghttp2_session*, const nghttp2_frame* frame, int error_code,
+         void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)
+            ->OnInvalidFrameRecv(frame, error_code);
+      });
+
+  nghttp2_session_callbacks_set_error_callback2(
+      callbacks,
+      [](nghttp2_session* /*session*/, int lib_error_code, const char* msg,
+         size_t len, void* user_data) -> int {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnErrorCallback2(
+            lib_error_code, msg, len);
+      });
+
+  nghttp2_session_callbacks_set_pack_extension_callback(
+      callbacks,
+      [](nghttp2_session*, uint8_t* buf, size_t len, const nghttp2_frame* frame,
+         void* user_data) -> ssize_t {
+        return static_cast<MockNghttp2Callbacks*>(user_data)->OnPackExtension(
+            buf, len, frame);
+      });
+  return MakeCallbacksPtr(callbacks);
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/mock_nghttp2_callbacks.h b/quiche/http2/adapter/mock_nghttp2_callbacks.h
new file mode 100644
index 0000000..88faf24
--- /dev/null
+++ b/quiche/http2/adapter/mock_nghttp2_callbacks.h
@@ -0,0 +1,86 @@
+#ifndef QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_
+#define QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+// This class provides a set of mock nghttp2 callbacks for use in unit test
+// expectations.
+class QUICHE_NO_EXPORT MockNghttp2Callbacks {
+ public:
+  MockNghttp2Callbacks() = default;
+
+  // The caller takes ownership of the |nghttp2_session_callbacks|.
+  static nghttp2_session_callbacks_unique_ptr GetCallbacks();
+
+  MOCK_METHOD(ssize_t,
+              Send,
+              (const uint8_t* data, size_t length, int flags),
+              ());
+
+  MOCK_METHOD(int,
+              SendData,
+              (nghttp2_frame * frame,
+               const uint8_t* framehd,
+               size_t length,
+               nghttp2_data_source* source),
+              ());
+
+  MOCK_METHOD(int, OnBeginHeaders, (const nghttp2_frame* frame), ());
+
+  MOCK_METHOD(int,
+              OnHeader,
+              (const nghttp2_frame* frame,
+               absl::string_view name,
+               absl::string_view value,
+               uint8_t flags),
+              ());
+
+  MOCK_METHOD(int,
+              OnDataChunkRecv,
+              (uint8_t flags, int32_t stream_id, absl::string_view data),
+              ());
+
+  MOCK_METHOD(int, OnBeginFrame, (const nghttp2_frame_hd* hd), ());
+
+  MOCK_METHOD(int, OnFrameRecv, (const nghttp2_frame* frame), ());
+
+  MOCK_METHOD(int, OnStreamClose, (int32_t stream_id, uint32_t error_code), ());
+
+  MOCK_METHOD(int, BeforeFrameSend, (const nghttp2_frame* frame), ());
+
+  MOCK_METHOD(int, OnFrameSend, (const nghttp2_frame* frame), ());
+
+  MOCK_METHOD(int,
+              OnFrameNotSend,
+              (const nghttp2_frame* frame, int lib_error_code),
+              ());
+
+  MOCK_METHOD(int,
+              OnInvalidFrameRecv,
+              (const nghttp2_frame* frame, int error_code),
+              ());
+
+  MOCK_METHOD(int,
+              OnErrorCallback2,
+              (int lib_error_code, const char* msg, size_t len),
+              ());
+
+  MOCK_METHOD(ssize_t, OnPackExtension,
+              (uint8_t * buf, size_t len, const nghttp2_frame* frame), ());
+};
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_
diff --git a/http2/adapter/nghttp2.h b/quiche/http2/adapter/nghttp2.h
similarity index 100%
rename from http2/adapter/nghttp2.h
rename to quiche/http2/adapter/nghttp2.h
diff --git a/quiche/http2/adapter/nghttp2_adapter.cc b/quiche/http2/adapter/nghttp2_adapter.cc
new file mode 100644
index 0000000..f68779a
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_adapter.cc
@@ -0,0 +1,308 @@
+#include "quiche/http2/adapter/nghttp2_adapter.h"
+
+#include "absl/algorithm/container.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/http2/adapter/nghttp2_callbacks.h"
+#include "quiche/http2/adapter/nghttp2_data_provider.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace http2 {
+namespace adapter {
+
+namespace {
+
+using ConnectionError = Http2VisitorInterface::ConnectionError;
+
+// A metadata source that deletes itself upon completion.
+class SelfDeletingMetadataSource : public MetadataSource {
+ public:
+  explicit SelfDeletingMetadataSource(std::unique_ptr<MetadataSource> source)
+      : source_(std::move(source)) {}
+
+  size_t NumFrames(size_t max_frame_size) const override {
+    return source_->NumFrames(max_frame_size);
+  }
+
+  std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override {
+    const auto result = source_->Pack(dest, dest_len);
+    if (result.first < 0 || result.second) {
+      delete this;
+    }
+    return result;
+  }
+
+  void OnFailure() override {
+    source_->OnFailure();
+    delete this;
+  }
+
+ private:
+  std::unique_ptr<MetadataSource> source_;
+};
+
+}  // anonymous namespace
+
+/* static */
+std::unique_ptr<NgHttp2Adapter> NgHttp2Adapter::CreateClientAdapter(
+    Http2VisitorInterface& visitor, const nghttp2_option* options) {
+  auto adapter = new NgHttp2Adapter(visitor, Perspective::kClient, options);
+  adapter->Initialize();
+  return absl::WrapUnique(adapter);
+}
+
+/* static */
+std::unique_ptr<NgHttp2Adapter> NgHttp2Adapter::CreateServerAdapter(
+    Http2VisitorInterface& visitor, const nghttp2_option* options) {
+  auto adapter = new NgHttp2Adapter(visitor, Perspective::kServer, options);
+  adapter->Initialize();
+  return absl::WrapUnique(adapter);
+}
+
+bool NgHttp2Adapter::IsServerSession() const {
+  int result = nghttp2_session_check_server_session(session_->raw_ptr());
+  QUICHE_DCHECK_EQ(perspective_ == Perspective::kServer, result > 0);
+  return result > 0;
+}
+
+int64_t NgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
+  const int64_t processed_bytes = session_->ProcessBytes(bytes);
+  if (processed_bytes < 0) {
+    visitor_.OnConnectionError(ConnectionError::kParseError);
+  }
+  return processed_bytes;
+}
+
+void NgHttp2Adapter::SubmitSettings(absl::Span<const Http2Setting> settings) {
+  // Submit SETTINGS, converting each Http2Setting to an nghttp2_settings_entry.
+  std::vector<nghttp2_settings_entry> nghttp2_settings;
+  absl::c_transform(settings, std::back_inserter(nghttp2_settings),
+                    [](const Http2Setting& setting) {
+                      return nghttp2_settings_entry{setting.id, setting.value};
+                    });
+  nghttp2_submit_settings(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
+                          nghttp2_settings.data(), nghttp2_settings.size());
+}
+
+void NgHttp2Adapter::SubmitPriorityForStream(Http2StreamId stream_id,
+                                             Http2StreamId parent_stream_id,
+                                             int weight,
+                                             bool exclusive) {
+  nghttp2_priority_spec priority_spec;
+  nghttp2_priority_spec_init(&priority_spec, parent_stream_id, weight,
+                             static_cast<int>(exclusive));
+  nghttp2_submit_priority(session_->raw_ptr(), NGHTTP2_FLAG_NONE, stream_id,
+                          &priority_spec);
+}
+
+void NgHttp2Adapter::SubmitPing(Http2PingId ping_id) {
+  uint8_t opaque_data[8] = {};
+  Http2PingId ping_id_to_serialize = quiche::QuicheEndian::HostToNet64(ping_id);
+  std::memcpy(opaque_data, &ping_id_to_serialize, sizeof(Http2PingId));
+  nghttp2_submit_ping(session_->raw_ptr(), NGHTTP2_FLAG_NONE, opaque_data);
+}
+
+void NgHttp2Adapter::SubmitShutdownNotice() {
+  nghttp2_submit_shutdown_notice(session_->raw_ptr());
+}
+
+void NgHttp2Adapter::SubmitGoAway(Http2StreamId last_accepted_stream_id,
+                                  Http2ErrorCode error_code,
+                                  absl::string_view opaque_data) {
+  nghttp2_submit_goaway(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
+                        last_accepted_stream_id,
+                        static_cast<uint32_t>(error_code),
+                        ToUint8Ptr(opaque_data.data()), opaque_data.size());
+}
+
+void NgHttp2Adapter::SubmitWindowUpdate(Http2StreamId stream_id,
+                                        int window_increment) {
+  nghttp2_submit_window_update(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
+                               stream_id, window_increment);
+}
+
+void NgHttp2Adapter::SubmitMetadata(Http2StreamId stream_id,
+                                    size_t max_frame_size,
+                                    std::unique_ptr<MetadataSource> source) {
+  auto* wrapped_source = new SelfDeletingMetadataSource(std::move(source));
+  const size_t num_frames = wrapped_source->NumFrames(max_frame_size);
+  size_t num_successes = 0;
+  for (size_t i = 1; i <= num_frames; ++i) {
+    const int result = nghttp2_submit_extension(
+        session_->raw_ptr(), kMetadataFrameType,
+        i == num_frames ? kMetadataEndFlag : 0, stream_id, wrapped_source);
+    if (result != 0) {
+      QUICHE_LOG(DFATAL) << "Failed to submit extension frame " << i << " of "
+                         << num_frames;
+      break;
+    }
+    ++num_successes;
+  }
+  if (num_successes == 0) {
+    delete wrapped_source;
+  }
+}
+
+int NgHttp2Adapter::Send() {
+  const int result = nghttp2_session_send(session_->raw_ptr());
+  if (result != 0) {
+    QUICHE_VLOG(1) << "nghttp2_session_send returned " << result;
+    visitor_.OnConnectionError(ConnectionError::kSendError);
+  }
+  return result;
+}
+
+int NgHttp2Adapter::GetSendWindowSize() const {
+  return session_->GetRemoteWindowSize();
+}
+
+int NgHttp2Adapter::GetStreamSendWindowSize(Http2StreamId stream_id) const {
+  return nghttp2_session_get_stream_remote_window_size(session_->raw_ptr(),
+                                                       stream_id);
+}
+
+int NgHttp2Adapter::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
+  return nghttp2_session_get_stream_effective_local_window_size(
+      session_->raw_ptr(), stream_id);
+}
+
+int NgHttp2Adapter::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
+  return nghttp2_session_get_stream_local_window_size(session_->raw_ptr(),
+                                                      stream_id);
+}
+
+int NgHttp2Adapter::GetReceiveWindowSize() const {
+  return nghttp2_session_get_local_window_size(session_->raw_ptr());
+}
+
+int NgHttp2Adapter::GetHpackEncoderDynamicTableSize() const {
+  return nghttp2_session_get_hd_deflate_dynamic_table_size(session_->raw_ptr());
+}
+
+int NgHttp2Adapter::GetHpackDecoderDynamicTableSize() const {
+  return nghttp2_session_get_hd_inflate_dynamic_table_size(session_->raw_ptr());
+}
+
+Http2StreamId NgHttp2Adapter::GetHighestReceivedStreamId() const {
+  return nghttp2_session_get_last_proc_stream_id(session_->raw_ptr());
+}
+
+void NgHttp2Adapter::MarkDataConsumedForStream(Http2StreamId stream_id,
+                                               size_t num_bytes) {
+  int rc = session_->Consume(stream_id, num_bytes);
+  if (rc != 0) {
+    QUICHE_LOG(ERROR) << "Error " << rc << " marking " << num_bytes
+                      << " bytes consumed for stream " << stream_id;
+  }
+}
+
+void NgHttp2Adapter::SubmitRst(Http2StreamId stream_id,
+                               Http2ErrorCode error_code) {
+  int status =
+      nghttp2_submit_rst_stream(session_->raw_ptr(), NGHTTP2_FLAG_NONE,
+                                stream_id, static_cast<uint32_t>(error_code));
+  if (status < 0) {
+    QUICHE_LOG(WARNING) << "Reset stream failed: " << stream_id
+                        << " with status code " << status;
+  }
+}
+
+int32_t NgHttp2Adapter::SubmitRequest(
+    absl::Span<const Header> headers,
+    std::unique_ptr<DataFrameSource> data_source, void* stream_user_data) {
+  auto nvs = GetNghttp2Nvs(headers);
+  std::unique_ptr<nghttp2_data_provider> provider =
+      MakeDataProvider(data_source.get());
+
+  int32_t stream_id =
+      nghttp2_submit_request(session_->raw_ptr(), nullptr, nvs.data(),
+                             nvs.size(), provider.get(), stream_user_data);
+  sources_.emplace(stream_id, std::move(data_source));
+  QUICHE_VLOG(1) << "Submitted request with " << nvs.size()
+                 << " request headers and user data " << stream_user_data
+                 << "; resulted in stream " << stream_id;
+  return stream_id;
+}
+
+int NgHttp2Adapter::SubmitResponse(
+    Http2StreamId stream_id, absl::Span<const Header> headers,
+    std::unique_ptr<DataFrameSource> data_source) {
+  auto nvs = GetNghttp2Nvs(headers);
+  std::unique_ptr<nghttp2_data_provider> provider =
+      MakeDataProvider(data_source.get());
+
+  sources_.emplace(stream_id, std::move(data_source));
+
+  int result = nghttp2_submit_response(session_->raw_ptr(), stream_id,
+                                       nvs.data(), nvs.size(), provider.get());
+  QUICHE_VLOG(1) << "Submitted response with " << nvs.size()
+                 << " response headers; result = " << result;
+  return result;
+}
+
+int NgHttp2Adapter::SubmitTrailer(Http2StreamId stream_id,
+                                  absl::Span<const Header> trailers) {
+  auto nvs = GetNghttp2Nvs(trailers);
+  int result = nghttp2_submit_trailer(session_->raw_ptr(), stream_id,
+                                      nvs.data(), nvs.size());
+  QUICHE_VLOG(1) << "Submitted trailers with " << nvs.size()
+                 << " response trailers; result = " << result;
+  return result;
+}
+
+void NgHttp2Adapter::SetStreamUserData(Http2StreamId stream_id,
+                                       void* stream_user_data) {
+  nghttp2_session_set_stream_user_data(session_->raw_ptr(), stream_id,
+                                       stream_user_data);
+}
+
+void* NgHttp2Adapter::GetStreamUserData(Http2StreamId stream_id) {
+  return nghttp2_session_get_stream_user_data(session_->raw_ptr(), stream_id);
+}
+
+bool NgHttp2Adapter::ResumeStream(Http2StreamId stream_id) {
+  return 0 == nghttp2_session_resume_data(session_->raw_ptr(), stream_id);
+}
+
+void NgHttp2Adapter::RemoveStream(Http2StreamId stream_id) {
+  sources_.erase(stream_id);
+}
+
+NgHttp2Adapter::NgHttp2Adapter(Http2VisitorInterface& visitor,
+                               Perspective perspective,
+                               const nghttp2_option* options)
+    : Http2Adapter(visitor),
+      visitor_(visitor),
+      options_(options),
+      perspective_(perspective) {}
+
+NgHttp2Adapter::~NgHttp2Adapter() {}
+
+void NgHttp2Adapter::Initialize() {
+  nghttp2_option* owned_options = nullptr;
+  if (options_ == nullptr) {
+    nghttp2_option_new(&owned_options);
+    // Set some common options for compatibility.
+    nghttp2_option_set_no_closed_streams(owned_options, 1);
+    nghttp2_option_set_no_auto_window_update(owned_options, 1);
+    nghttp2_option_set_max_send_header_block_length(owned_options, 0x2000000);
+    nghttp2_option_set_max_outbound_ack(owned_options, 10000);
+    nghttp2_option_set_user_recv_extension_type(owned_options,
+                                                kMetadataFrameType);
+    options_ = owned_options;
+  }
+
+  session_ = absl::make_unique<NgHttp2Session>(perspective_,
+                                               callbacks::Create(), options_,
+                                               static_cast<void*>(&visitor_));
+  if (owned_options != nullptr) {
+    nghttp2_option_del(owned_options);
+  }
+  options_ = nullptr;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_adapter.h b/quiche/http2/adapter/nghttp2_adapter.h
new file mode 100644
index 0000000..02bb9f0
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_adapter.h
@@ -0,0 +1,116 @@
+#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
+#define QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
+
+#include <cstdint>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/http2/adapter/http2_adapter.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/nghttp2_session.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+class QUICHE_EXPORT_PRIVATE NgHttp2Adapter : public Http2Adapter {
+ public:
+  ~NgHttp2Adapter() override;
+
+  // Creates an adapter that functions as a client. Does not take ownership of
+  // |options|.
+  static std::unique_ptr<NgHttp2Adapter> CreateClientAdapter(
+      Http2VisitorInterface& visitor, const nghttp2_option* options = nullptr);
+
+  // Creates an adapter that functions as a server. Does not take ownership of
+  // |options|.
+  static std::unique_ptr<NgHttp2Adapter> CreateServerAdapter(
+      Http2VisitorInterface& visitor, const nghttp2_option* options = nullptr);
+
+  bool IsServerSession() const override;
+  bool want_read() const override { return session_->want_read(); }
+  bool want_write() const override { return session_->want_write(); }
+
+  int64_t ProcessBytes(absl::string_view bytes) override;
+  void SubmitSettings(absl::Span<const Http2Setting> settings) override;
+  void SubmitPriorityForStream(Http2StreamId stream_id,
+                               Http2StreamId parent_stream_id,
+                               int weight,
+                               bool exclusive) override;
+
+  // Submits a PING on the connection. Note that nghttp2 automatically submits
+  // PING acks upon receiving non-ack PINGs from the peer, so callers only use
+  // this method to originate PINGs. See nghttp2_option_set_no_auto_ping_ack().
+  void SubmitPing(Http2PingId ping_id) override;
+
+  void SubmitShutdownNotice() override;
+  void SubmitGoAway(Http2StreamId last_accepted_stream_id,
+                    Http2ErrorCode error_code,
+                    absl::string_view opaque_data) override;
+
+  void SubmitWindowUpdate(Http2StreamId stream_id,
+                          int window_increment) override;
+
+  void SubmitRst(Http2StreamId stream_id, Http2ErrorCode error_code) override;
+
+  void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
+                      std::unique_ptr<MetadataSource> source) override;
+
+  int Send() override;
+
+  int GetSendWindowSize() const override;
+  int GetStreamSendWindowSize(Http2StreamId stream_id) const override;
+
+  int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const override;
+  int GetStreamReceiveWindowSize(Http2StreamId stream_id) const override;
+  int GetReceiveWindowSize() const override;
+
+  int GetHpackEncoderDynamicTableSize() const override;
+  int GetHpackDecoderDynamicTableSize() const override;
+
+  Http2StreamId GetHighestReceivedStreamId() const override;
+
+  void MarkDataConsumedForStream(Http2StreamId stream_id,
+                                 size_t num_bytes) override;
+
+  int32_t SubmitRequest(absl::Span<const Header> headers,
+                        std::unique_ptr<DataFrameSource> data_source,
+                        void* user_data) override;
+
+  int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
+                     std::unique_ptr<DataFrameSource> data_source) override;
+
+  int SubmitTrailer(Http2StreamId stream_id,
+                    absl::Span<const Header> trailers) override;
+
+  void SetStreamUserData(Http2StreamId stream_id, void* user_data) override;
+  void* GetStreamUserData(Http2StreamId stream_id) override;
+
+  bool ResumeStream(Http2StreamId stream_id) override;
+
+  // Removes references to the `stream_id` from this adapter.
+  void RemoveStream(Http2StreamId stream_id);
+
+  // Accessor for testing.
+  size_t sources_size() const { return sources_.size(); }
+
+ private:
+  NgHttp2Adapter(Http2VisitorInterface& visitor, Perspective perspective,
+                 const nghttp2_option* options);
+
+  // Performs any necessary initialization of the underlying HTTP/2 session,
+  // such as preparing initial SETTINGS.
+  void Initialize();
+
+  std::unique_ptr<NgHttp2Session> session_;
+  Http2VisitorInterface& visitor_;
+  const nghttp2_option* options_;
+  Perspective perspective_;
+
+  absl::flat_hash_map<int32_t, std::unique_ptr<DataFrameSource>> sources_;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
diff --git a/quiche/http2/adapter/nghttp2_adapter_test.cc b/quiche/http2/adapter/nghttp2_adapter_test.cc
new file mode 100644
index 0000000..289748b
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_adapter_test.cc
@@ -0,0 +1,6391 @@
+#include "quiche/http2/adapter/nghttp2_adapter.h"
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/mock_http2_visitor.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/http2/adapter/nghttp2_test_utils.h"
+#include "quiche/http2/adapter/oghttp2_util.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using ConnectionError = Http2VisitorInterface::ConnectionError;
+
+using spdy::SpdyFrameType;
+using testing::_;
+
+enum FrameType {
+  DATA,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+  CONTINUATION,
+};
+
+// This send callback assumes |source|'s pointer is a TestDataSource, and
+// |user_data| is a Http2VisitorInterface.
+int TestSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/,
+                     const uint8_t* framehd, size_t length,
+                     nghttp2_data_source* source, void* user_data) {
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  // Send the frame header via the visitor.
+  ssize_t result = visitor->OnReadyToSend(ToStringView(framehd, 9));
+  if (result == 0) {
+    return NGHTTP2_ERR_WOULDBLOCK;
+  }
+  auto* test_source = static_cast<TestDataSource*>(source->ptr);
+  absl::string_view payload = test_source->ReadNext(length);
+  // Send the frame payload via the visitor.
+  visitor->OnReadyToSend(payload);
+  return 0;
+}
+
+TEST(NgHttp2AdapterTest, ClientConstruction) {
+  testing::StrictMock<MockHttp2Visitor> visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  ASSERT_NE(nullptr, adapter);
+  EXPECT_TRUE(adapter->want_read());
+  EXPECT_FALSE(adapter->want_write());
+  EXPECT_FALSE(adapter->IsServerSession());
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesFrames) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
+  visitor.Clear();
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string initial_frames = TestFrameSequence()
+                                         .ServerPreface()
+                                         .Ping(42)
+                                         .WindowUpdate(0, 1000)
+                                         .Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_EQ(adapter->GetSendWindowSize(), kInitialFlowControlWindowSize + 1000);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
+
+  result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
+  visitor.Clear();
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  const std::vector<Header> headers3 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/three"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const char* kSentinel3 = "arbitrary pointer 3";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
+  ASSERT_GT(stream_id2, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id2;
+
+  const int32_t stream_id3 =
+      adapter->SubmitRequest(headers3, nullptr, const_cast<char*>(kSentinel3));
+  ASSERT_GT(stream_id3, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id3;
+
+  const char* kSentinel2 = "arbitrary pointer 2";
+  adapter->SetStreamUserData(stream_id2, const_cast<char*>(kSentinel2));
+  adapter->SetStreamUserData(stream_id3, nullptr);
+
+  EXPECT_EQ(adapter->sources_size(), 3);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id3, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id3, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  // All streams are active and have not yet received any data, so the receive
+  // window should be at the initial value.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(stream_id1));
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(stream_id2));
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(stream_id3));
+
+  // Upper bound on the flow control receive window should be the initial value.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowLimit(stream_id1));
+
+  // Connection has not yet received any data.
+  EXPECT_EQ(kInitialFlowControlWindowSize, adapter->GetReceiveWindowSize());
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(stream_id1));
+  EXPECT_EQ(kSentinel2, adapter->GetStreamUserData(stream_id2));
+  EXPECT_EQ(nullptr, adapter->GetStreamUserData(stream_id3));
+
+  EXPECT_EQ(0, adapter->GetHpackDecoderDynamicTableSize());
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
+          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR))
+      .WillOnce(
+          [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
+            adapter->RemoveStream(stream_id);
+            return true;
+          });
+  EXPECT_CALL(visitor, OnFrameHeader(0, 19, GOAWAY, 0));
+  EXPECT_CALL(visitor,
+              OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!"));
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  // First stream has received some data.
+  EXPECT_GT(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(stream_id1));
+  // Second stream was closed.
+  EXPECT_EQ(-1, adapter->GetStreamReceiveWindowSize(stream_id2));
+  // Third stream has not received any data.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(stream_id3));
+
+  // One stream was closed.
+  EXPECT_EQ(adapter->sources_size(), 2);
+
+  // Connection window should be the same as the first stream.
+  EXPECT_EQ(adapter->GetReceiveWindowSize(),
+            adapter->GetStreamReceiveWindowSize(stream_id1));
+
+  // Upper bound on the flow control receive window should still be the initial
+  // value.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowLimit(stream_id1));
+
+  EXPECT_GT(adapter->GetHpackDecoderDynamicTableSize(), 0);
+
+  // Should be 3, but this method only works for server adapters.
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  // Even though the client recieved a GOAWAY, streams 1 and 5 are still active.
+  EXPECT_TRUE(adapter->want_read());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 0, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 0));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR))
+      .WillOnce(
+          [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
+            adapter->RemoveStream(stream_id);
+            return true;
+          });
+  EXPECT_CALL(visitor, OnFrameHeader(5, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(5, Http2ErrorCode::REFUSED_STREAM));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM))
+      .WillOnce(
+          [&adapter](Http2StreamId stream_id, Http2ErrorCode /*error_code*/) {
+            adapter->RemoveStream(stream_id);
+            return true;
+          });
+  adapter->ProcessBytes(TestFrameSequence()
+                            .Data(1, "", true)
+                            .RstStream(5, Http2ErrorCode::REFUSED_STREAM)
+                            .Serialize());
+
+  // Should be 5, but this method only works for server adapters.
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  // After receiving END_STREAM for 1 and RST_STREAM for 5, the session no
+  // longer expects reads.
+  EXPECT_FALSE(adapter->want_read());
+  EXPECT_EQ(adapter->sources_size(), 0);
+
+  // Client will not have anything else to write.
+  EXPECT_FALSE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+}
+
+TEST(NgHttp2AdapterTest, QueuingWindowUpdateAffectsWindow) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  EXPECT_EQ(adapter->GetReceiveWindowSize(), kInitialFlowControlWindowSize);
+  adapter->SubmitWindowUpdate(0, 10000);
+  EXPECT_EQ(adapter->GetReceiveWindowSize(),
+            kInitialFlowControlWindowSize + 10000);
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
+            kInitialFlowControlWindowSize);
+  adapter->SubmitWindowUpdate(1, 20000);
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
+            kInitialFlowControlWindowSize + 20000);
+}
+
+TEST(NgHttp2AdapterTest, AckOfSettingInitialWindowSizeAffectsWindow) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id1 = adapter->SubmitRequest(headers, nullptr, nullptr);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  int64_t parse_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(parse_result));
+
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
+            kInitialFlowControlWindowSize);
+  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000u}});
+  // No update for the first stream, yet.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
+            kInitialFlowControlWindowSize);
+
+  // Ack of server's initial settings.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  // Outbound SETTINGS containing INITIAL_WINDOW_SIZE.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  // Still no update, as a SETTINGS ack has not yet been received.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
+            kInitialFlowControlWindowSize);
+
+  const std::string settings_ack =
+      TestFrameSequence().SettingsAck().Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  parse_result = adapter->ProcessBytes(settings_ack);
+  EXPECT_EQ(settings_ack.size(), static_cast<size_t>(parse_result));
+
+  // Stream window has been updated.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1), 80000);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+  const int32_t stream_id2 = adapter->SubmitRequest(headers, nullptr, nullptr);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id2), 80000);
+}
+
+TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithFin) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}}, /*fin=*/false)
+          .Headers(1, {{":status", "100"}}, /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithContent) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}},
+                   /*fin=*/false)
+          .Data(1, "We needed the final headers before data, whoops")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientRejects100HeadersWithContentLength) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}, {"content-length", "42"}},
+                   /*fin=*/false)
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [content-length], value: [42]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandles204WithContent) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
+  ASSERT_GT(stream_id2, stream_id1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "204"}, {"content-length", "2"}},
+                   /*fin=*/false)
+          .Data(1, "hi")
+          .Headers(3, {{":status", "204"}}, /*fin=*/false)
+          .Data(3, "hi")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "204"));
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [content-length], value: [2]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":status", "204"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(3, 2));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandles304WithContent) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
+                   /*fin=*/false)
+          .Data(1, "hi")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandles304WithContentLength) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesTrailers) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Headers(1, {{"final-status", "A-OK"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "final-status", "A-OK"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientSendsTrailers) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const std::string kBody = "This is an example request body.";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  // nghttp2 does not require that the data source indicate the end of data
+  // before trailers are enqueued.
+
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  visitor.Clear();
+
+  const std::vector<Header> trailers1 =
+      ToHeaders({{"extra-info", "Trailers are weird but good?"}});
+  adapter->SubmitTrailer(stream_id1, trailers1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  data = visitor.data();
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesMetadata) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Metadata(0, "Example connection metadata")
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(1, "Example stream metadata")
+          .Data(1, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesMetadataWithEmptyPayload) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(1, "")
+          .Data(1, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(3);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesMetadataWithError) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Metadata(0, "Example connection metadata")
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(1, "Example stream metadata")
+          .Data(1, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _))
+      .WillOnce(testing::Return(false));
+  // Remaining frames are not processed due to the error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  // The false return from OnMetadataForStream() results in a connection error.
+  EXPECT_EQ(stream_result, NGHTTP2_ERR_CALLBACK_FAILURE);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_TRUE(adapter->want_read());  // Even after an error. Why?
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesHpackHeaderTableSetting) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 = ToHeaders({
+      {":method", "GET"},
+      {":scheme", "http"},
+      {":authority", "example.com"},
+      {":path", "/this/is/request/one"},
+      {"x-i-do-not-like", "green eggs and ham"},
+      {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
+      {"x-like-them-in-a-house", "no"},
+      {"x-like-them-with-a-mouse", "no"},
+  });
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 100);
+
+  const std::string stream_frames =
+      TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 100u}}).Serialize();
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
+
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  EXPECT_LE(adapter->GetHpackEncoderDynamicTableSize(), 100);
+}
+
+TEST(NgHttp2AdapterTest, ClientHandlesInvalidTrailers) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Headers(1, {{":bad-status", "9000"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [:bad-status], value: [9000]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  // Bad status trailer will cause a PROTOCOL_ERROR. The header is never
+  // delivered in an OnHeaderForStream callback.
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id1, 4, 0x0, 1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientRstStreamWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
+      .WillOnce(testing::DoAll(
+          testing::InvokeWithoutArgs([&adapter]() {
+            adapter->SubmitRst(1, Http2ErrorCode::REFUSED_STREAM);
+          }),
+          testing::Return(Http2VisitorInterface::HEADER_RST_STREAM)));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, stream_id1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::REFUSED_STREAM));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
+      .WillOnce(
+          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
+  // Translation to nghttp2 treats this error as a general parsing error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(-902 /* NGHTTP2_ERR_CALLBACK_FAILURE */, stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeadersOnly) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
+      .WillOnce(
+          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
+  // Translation to nghttp2 treats this error as a general parsing error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(-902 /* NGHTTP2_ERR_CALLBACK_FAILURE */, stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientRejectsHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1))
+      .WillOnce(testing::Return(false));
+  // Rejecting headers leads to a connection error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientStartsShutdown) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  // No-op for a client implementation.
+  adapter->SubmitShutdownNotice();
+  EXPECT_FALSE(adapter->want_write());
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_EQ(visitor.data(), spdy::kHttp2ConnectionHeaderPrefix);
+}
+
+TEST(NgHttp2AdapterTest, ClientReceivesGoAway) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
+  ASSERT_GT(stream_id2, stream_id1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
+          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
+          .WindowUpdate(0, 42)
+          .WindowUpdate(1, 42)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
+  EXPECT_CALL(visitor,
+              OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion"));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 42));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  // Intriguingly, despite want_write() being true, the sent data is empty; the
+  // receipt of the GOAWAY prevents the SETTINGS ack from being written.
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+}
+
+TEST(NgHttp2AdapterTest, ClientFailsOnGoAway) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
+  EXPECT_CALL(visitor,
+              OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion"))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientRejects101Response) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"},
+                 {"upgrade", "new-protocol"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "101"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [:status], value: [101]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(static_cast<int64_t>(stream_frames.size()), stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                  static_cast<uint32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientSubmitRequest) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  EXPECT_THAT(visitor.data(),
+              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
+  EXPECT_FALSE(adapter->want_write());
+  const char* kSentinel = "";
+  const absl::string_view kBody = "This is an example request body.";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), const_cast<char*>(kSentinel));
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(stream_id));
+  EXPECT_EQ(kInitialFlowControlWindowSize, adapter->GetReceiveWindowSize());
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowLimit(stream_id));
+
+  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
+
+  // Some data was sent, so the remaining send window size should be less than
+  // the default.
+  EXPECT_LT(adapter->GetStreamSendWindowSize(stream_id),
+            kInitialFlowControlWindowSize);
+  EXPECT_GT(adapter->GetStreamSendWindowSize(stream_id), 0);
+  // Send window for a nonexistent stream is not available.
+  EXPECT_EQ(-1, adapter->GetStreamSendWindowSize(stream_id + 2));
+
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             nullptr, nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+  const char* kSentinel2 = "arbitrary pointer 2";
+  EXPECT_EQ(nullptr, adapter->GetStreamUserData(stream_id));
+  adapter->SetStreamUserData(stream_id, const_cast<char*>(kSentinel2));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+
+  EXPECT_EQ(kSentinel2, adapter->GetStreamUserData(stream_id));
+
+  // No data was sent (just HEADERS), so the remaining send window size should
+  // still be the default.
+  EXPECT_EQ(adapter->GetStreamSendWindowSize(stream_id),
+            kInitialFlowControlWindowSize);
+}
+
+// This is really a test of the MakeZeroCopyDataFrameSource adapter, but I
+// wasn't sure where else to put it.
+TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProvider) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  EXPECT_THAT(visitor.data(),
+              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_FALSE(adapter->want_write());
+  const absl::string_view kBody = "This is an example request body.";
+  // This test will use TestDataSource as the source of the body payload data.
+  TestDataSource body1{kBody};
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+  nghttp2_send_data_callback send_callback = &TestSendCallback;
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(frame_source), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+// This test verifies how nghttp2 behaves when a data source becomes
+// read-blocked.
+TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProviderAndReadBlock) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const absl::string_view kBody = "This is an example request body.";
+  // This test will use TestDataSource as the source of the body payload data.
+  TestDataSource body1{kBody};
+  body1.set_is_data_available(false);
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+  nghttp2_send_data_callback send_callback = &TestSendCallback;
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(frame_source), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  // Resume the deferred stream.
+  body1.set_is_data_available(true);
+  EXPECT_TRUE(adapter->ResumeStream(stream_id));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
+  EXPECT_FALSE(adapter->want_write());
+
+  // Stream data is done, so this stream cannot be resumed.
+  EXPECT_FALSE(adapter->ResumeStream(stream_id));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+// This test verifies how nghttp2 behaves when a data source is read block, then
+// ends with an empty DATA frame.
+TEST(NgHttp2AdapterTest, ClientSubmitRequestEmptyDataWithFin) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const absl::string_view kEmptyBody = "";
+  // This test will use TestDataSource as the source of the body payload data.
+  TestDataSource body1{kEmptyBody};
+  body1.set_is_data_available(false);
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+  nghttp2_send_data_callback send_callback = &TestSendCallback;
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(frame_source), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  // Resume the deferred stream.
+  body1.set_is_data_available(true);
+  EXPECT_TRUE(adapter->ResumeStream(stream_id));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 0, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
+  EXPECT_FALSE(adapter->want_write());
+
+  // Stream data is done, so this stream cannot be resumed.
+  EXPECT_FALSE(adapter->ResumeStream(stream_id));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+// This test verifies how nghttp2 behaves when a connection becomes
+// write-blocked.
+TEST(NgHttp2AdapterTest, ClientSubmitRequestWithDataProviderAndWriteBlock) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const absl::string_view kBody = "This is an example request body.";
+  // This test will use TestDataSource as the source of the body payload data.
+  TestDataSource body1{kBody};
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+  nghttp2_send_data_callback send_callback = &TestSendCallback;
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &visitor, std::move(send_callback));
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(frame_source), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  visitor.set_is_write_blocked(true);
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  visitor.set_is_write_blocked(false);
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ClientReceivesDataOnClosedStream) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  EXPECT_THAT(visitor.data(),
+              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  // Client SETTINGS ack
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Let the client open a stream with a request.
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             nullptr, nullptr);
+  EXPECT_GT(stream_id, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  // Let the client RST_STREAM the stream it opened.
+  adapter->SubmitRst(stream_id, Http2ErrorCode::CANCEL);
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id, _, 0x0,
+                                   static_cast<int>(Http2ErrorCode::CANCEL)));
+  EXPECT_CALL(visitor, OnCloseStream(stream_id, Http2ErrorCode::CANCEL));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
+  visitor.Clear();
+
+  // Let the server send a response on the stream. (It might not have received
+  // the RST_STREAM yet.)
+  const std::string response_frames =
+      TestFrameSequence()
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(stream_id, "This is the response body.", /*fin=*/true)
+          .Serialize();
+
+  // The visitor gets notified about the HEADERS frame but not the DATA frame on
+  // the closed stream. No further processing for either frame occurs.
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, DATA, _)).Times(0);
+
+  const int64_t response_result = adapter->ProcessBytes(response_frames);
+  EXPECT_EQ(response_frames.size(), response_result);
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ClientQueuesRequests) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  adapter->SubmitSettings({});
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  adapter->Send();
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ServerPreface({{MAX_CONCURRENT_STREAMS, 2}})
+          .SettingsAck()
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{
+                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+
+  adapter->ProcessBytes(initial_frames);
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/example/request"}});
+  std::vector<int32_t> stream_ids;
+  // Start two, which hits the limit.
+  int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+  // Start two more, which must be queued.
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[0], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[0], _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[1], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[1], _, 0x5, 0));
+
+  adapter->Send();
+
+  const std::string update_streams =
+      TestFrameSequence().Settings({{MAX_CONCURRENT_STREAMS, 5}}).Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{
+                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  adapter->ProcessBytes(update_streams);
+
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[2], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[2], _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[3], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[3], _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[4], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[4], _, 0x5, 0));
+  // Header frames should all have been sent in order, regardless of any
+  // queuing.
+
+  adapter->Send();
+}
+
+TEST(NgHttp2AdapterTest, SubmitMetadata) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType)}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, SubmitMetadataMultipleFrames) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const auto kLargeValue = std::string(63 * 1024, 'a');
+  auto source = absl::make_unique<TestMetadataSource>(
+      ToHeaderBlock(ToHeaders({{"large-value", kLargeValue}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+  EXPECT_TRUE(adapter->want_write());
+
+  testing::InSequence seq;
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType),
+                            static_cast<SpdyFrameType>(kMetadataFrameType),
+                            static_cast<SpdyFrameType>(kMetadataFrameType),
+                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, SubmitConnectionMetadata) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(0, 16384u, std::move(source));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 0, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 0, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({static_cast<SpdyFrameType>(kMetadataFrameType)}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ClientObeysMaxConcurrentStreams) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  // Client preface does not appear to include the mandatory SETTINGS frame.
+  EXPECT_THAT(visitor.data(),
+              testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ServerPreface({{.id = MAX_CONCURRENT_STREAMS, .value = 1}})
+          .Serialize();
+  testing::InSequence s;
+
+  // Server preface (SETTINGS with MAX_CONCURRENT_STREAMS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting);
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_FALSE(adapter->want_write());
+  const absl::string_view kBody = "This is an example request body.";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+  const int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  const int next_stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/two"}}),
+                             nullptr, nullptr);
+
+  // A new pending stream is created, but because of MAX_CONCURRENT_STREAMS, the
+  // session should not want to write it at the moment.
+  EXPECT_GT(next_stream_id, stream_id);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(stream_id, "This is the response body.", /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(stream_id, "server", "my-fake-server"));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
+                                         "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0x1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
+  EXPECT_CALL(visitor,
+              OnDataForStream(stream_id, "This is the response body."));
+  EXPECT_CALL(visitor, OnEndStream(stream_id));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  // The first stream should close, which should make the session want to write
+  // the next stream.
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, next_stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, next_stream_id, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ClientReceivesInitialWindowSetting) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .Settings({{INITIAL_WINDOW_SIZE, 80000u}})
+          .WindowUpdate(0, 65536)
+          .Serialize();
+  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int64_t result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string kLongBody = std::string(81000, 'c');
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kLongBody);
+  body1->EndData();
+  const int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  // The client can send more than 4 frames (65536 bytes) of data.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(4);
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14464, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA, SpdyFrameType::DATA}));
+}
+
+TEST(NgHttp2AdapterTest, ClientReceivesInitialWindowSettingAfterStreamStart) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().WindowUpdate(0, 65536).Serialize();
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int64_t result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string kLongBody = std::string(81000, 'c');
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kLongBody);
+  body1->EndData();
+  const int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  // The client can only send 65535 bytes of data, as the stream window has not
+  // yet been increased.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(3);
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16383, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA}));
+  visitor.Clear();
+
+  // Can't write any more due to flow control.
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string settings_frame =
+      TestFrameSequence().Settings({{INITIAL_WINDOW_SIZE, 80000u}}).Serialize();
+  // SETTINGS with INITIAL_STREAM_WINDOW
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t settings_result = adapter->ProcessBytes(settings_frame);
+  EXPECT_EQ(settings_frame.size(), static_cast<size_t>(settings_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  // The client can write more after receiving the INITIAL_WINDOW_SIZE setting.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14465, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::DATA}));
+}
+
+TEST(NgHttp2AdapterTest, InvalidInitialWindowSetting) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const uint32_t kTooLargeInitialWindow = 1u << 31;
+  const std::string initial_frames =
+      TestFrameSequence()
+          .Settings({{INITIAL_WINDOW_SIZE, kTooLargeInitialWindow}})
+          .Serialize();
+  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  0, Http2VisitorInterface::InvalidFrameError::kFlowControl));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a GOAWAY.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  int64_t result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::GOAWAY}));
+  visitor.Clear();
+}
+
+TEST(NgHttp2AdapterTest, InitialWindowSettingCausesOverflow) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+  int64_t write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const uint32_t kLargeInitialWindow = (1u << 31) - 1;
+  const std::string frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(stream_id, {{":status", "200"}}, /*fin=*/false)
+          .WindowUpdate(stream_id, 65536u)
+          .Settings({{INITIAL_WINDOW_SIZE, kLargeInitialWindow}})
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 4, WINDOW_UPDATE, 0x0));
+  EXPECT_CALL(visitor, OnWindowUpdate(stream_id, 65536));
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE,
+                                              kLargeInitialWindow}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  // The stream window update plus the SETTINGS frame with INITIAL_WINDOW_SIZE
+  // pushes the stream's flow control window outside of the acceptable range.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, 4, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(RST_STREAM, stream_id, 4, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id, Http2ErrorCode::FLOW_CONTROL_ERROR));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ClientForbidsPushPromise) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  adapter->SubmitSettings({{ENABLE_PUSH, 0}});
+
+  testing::InSequence s;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  int write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+
+  visitor.Clear();
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+  write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::vector<Header> push_headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/push"}});
+  const std::string frames = TestFrameSequence()
+                                 .ServerPreface()
+                                 .SettingsAck()
+                                 .PushPromise(stream_id, 2, push_headers)
+                                 .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // SETTINGS ack (to acknowledge PUSH_ENABLED=0)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  // The PUSH_PROMISE is now treated as an invalid frame.
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, PUSH_PROMISE, _));
+  EXPECT_CALL(visitor, OnInvalidFrame(stream_id, _));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), read_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+}
+
+TEST(NgHttp2AdapterTest, ClientForbidsPushStream) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+  adapter->SubmitSettings({{ENABLE_PUSH, 0}});
+
+  testing::InSequence s;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  int write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+
+  visitor.Clear();
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+  write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .SettingsAck()
+          .Headers(2,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // SETTINGS ack (to acknowledge PUSH_ENABLED=0)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  // The push HEADERS are invalid.
+  EXPECT_CALL(visitor, OnFrameHeader(2, _, HEADERS, _));
+  EXPECT_CALL(visitor, OnInvalidFrame(2, _));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), read_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+}
+
+TEST(NgHttp2AdapterTest, FailureSendingConnectionPreface) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  visitor.set_has_write_error();
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
+
+  int result = adapter->Send();
+  EXPECT_EQ(result, NGHTTP2_ERR_CALLBACK_FAILURE);
+}
+
+TEST(NgHttp2AdapterTest, MaxFrameSizeSettingNotAppliedBeforeAck) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
+  const int32_t stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
+                                        {":scheme", "https"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             /*data_source=*/nullptr, /*user_data=*/nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  testing::InSequence s;
+
+  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string server_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "200"}}, /*fin=*/false)
+          .Data(1, std::string(large_frame_size, 'a'))
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Response HEADERS. Because the SETTINGS with MAX_FRAME_SIZE was not
+  // acknowledged, the large DATA is treated as a connection error. Note that
+  // nghttp2 does not deliver any DATA or connection error events.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  const int64_t process_result = adapter->ProcessBytes(server_frames);
+  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::FRAME_SIZE_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, MaxFrameSizeSettingAppliedAfterAck) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateClientAdapter(visitor);
+
+  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
+  const int32_t stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
+                                        {":scheme", "https"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             /*data_source=*/nullptr, /*user_data=*/nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  testing::InSequence s;
+
+  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string server_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .SettingsAck()
+          .Headers(1, {{":status", "200"}}, /*fin=*/false)
+          .Data(1, std::string(large_frame_size, 'a'))
+          .Serialize();
+
+  // Server preface (empty SETTINGS) and ack of SETTINGS.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+
+  // Response HEADERS and DATA. Because the SETTINGS with MAX_FRAME_SIZE was
+  // acknowledged, the large DATA is accepted without any error.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, large_frame_size));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+
+  const int64_t process_result = adapter->ProcessBytes(server_frames);
+  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
+
+  // Client ack of SETTINGS.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ConnectionErrorOnControlFrameSent) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().Ping(42).Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // PING
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0))
+      .WillOnce(testing::Return(-902));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
+
+  int send_result = adapter->Send();
+  EXPECT_LT(send_result, 0);
+
+  // Apparently nghttp2 retries sending the frames that had failed before.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
+  send_result = adapter->Send();
+  EXPECT_EQ(send_result, 0);
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ConnectionErrorOnDataFrameSent) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body->AppendPayload("Here is some data, which will lead to a fatal error");
+  TestDataFrameSource* body_ptr = body.get();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}}), std::move(body));
+  ASSERT_EQ(0, submit_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  // Stream 1, with doomed DATA
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0))
+      .WillOnce(testing::Return(-902));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
+
+  int send_result = adapter->Send();
+  EXPECT_LT(send_result, 0);
+
+  // The test data source got a signal that the first chunk of data was sent
+  // successfully, so discarded that data internally. However, due to the send
+  // error, the next Send() from nghttp2 will try to send that exact same data
+  // again. Without this line appending the exact same data back to the data
+  // source, the test crashes. It is not clear how the data source would know to
+  // not discard the data, unless told by the session? This is not intuitive.
+  body_ptr->AppendPayload(
+      "Here is some data, which will lead to a fatal error");
+
+  // Apparently nghttp2 retries sending the frames that had failed before.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(send_result, 0);
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ServerConstruction) {
+  testing::StrictMock<MockHttp2Visitor> visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  ASSERT_NE(nullptr, adapter);
+  EXPECT_TRUE(adapter->want_read());
+  EXPECT_FALSE(adapter->want_write());
+  EXPECT_TRUE(adapter->IsServerSession());
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesFrames) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+  EXPECT_EQ(0, adapter->GetHpackDecoderDynamicTableSize());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Ping(42)
+                                 .WindowUpdate(0, 1000)
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
+      .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
+        adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
+        return true;
+      }));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "http"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/two"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(47, false));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
+
+  EXPECT_GT(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowSize(1));
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1),
+            adapter->GetReceiveWindowSize());
+  // Upper bound should still be the original value.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            adapter->GetStreamReceiveWindowLimit(1));
+
+  EXPECT_GT(adapter->GetHpackDecoderDynamicTableSize(), 0);
+
+  // Because stream 3 has already been closed, it's not possible to set user
+  // data.
+  const char* kSentinel3 = "another arbitrary pointer";
+  adapter->SetStreamUserData(3, const_cast<char*>(kSentinel3));
+  EXPECT_EQ(nullptr, adapter->GetStreamUserData(3));
+
+  EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_EQ(adapter->GetSendWindowSize(), kInitialFlowControlWindowSize + 1000);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x1, 0));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack, two PING acks.
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING,
+                            SpdyFrameType::PING}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesDataWithPadding) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.",
+                                       /*fin=*/true, /*padding_length=*/39)
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25 + 39, DATA, 0x9));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25 + 39));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+  // Note: nghttp2 passes padding information after the actual data.
+  EXPECT_CALL(visitor, OnDataPaddingLength(1, 39));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesHostHeader) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":path", "/this/is/request/one"},
+                                           {"host", "example.com"}},
+                                          /*fin=*/true)
+                                 .Headers(3,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"host", "example.com"}},
+                                          /*fin=*/true)
+                                 .Headers(5,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "foo.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"host", "bar.com"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(5));
+  EXPECT_CALL(visitor, OnEndStream(5));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  visitor.Clear();
+}
+
+// Tests the case where the response body is in the progress of being sent while
+// trailers are queued.
+TEST(NgHttp2AdapterTest, ServerSubmitsTrailersWhileDataDeferred) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  visitor.Clear();
+
+  const absl::string_view kBody = "This is an example response body.";
+
+  // The body source must indicate that the end of the body is not the end of
+  // the stream.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  auto* body1_ptr = body1.get();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  int trailer_result =
+      adapter->SubmitTrailer(1, ToHeaders({{"final-status", "a-ok"}}));
+  ASSERT_EQ(trailer_result, 0);
+
+  // Even though the data source has not finished sending data, nghttp2 will
+  // write the trailers anyway.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  // Resuming the stream results in the library wanting to write again.
+  body1_ptr->AppendPayload(kBody);
+  body1_ptr->EndData();
+  adapter->ResumeStream(1);
+  EXPECT_TRUE(adapter->want_write());
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+
+  // But no data is written for the stream.
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControl) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 // 70000 bytes of data
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(4464, 'a'))
+                                 .Serialize();
+
+  testing::InSequence s;
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  // No further frame data or headers are delivered.
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // No SETTINGS ack is written.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControlWithOneDataFrame) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  // Allow the client to send a DATA frame that exceeds the connection flow
+  // control window.
+  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "POST"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  int64_t process_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Outbound SETTINGS containing MAX_FRAME_SIZE.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  // Ack of client's initial settings.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
+  // overflow the connection-level window. The result should be a GOAWAY.
+  const std::string overflow_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Data(1, std::string(window_overflow_bytes, 'a'))
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, window_overflow_bytes));
+  // No further frame data is delivered.
+
+  process_result = adapter->ProcessBytes(overflow_frames);
+  EXPECT_EQ(overflow_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ClientDisobeysConnectionFlowControlAcrossReads) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  // Allow the client to send a DATA frame that exceeds the connection flow
+  // control window.
+  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "POST"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  int64_t process_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Outbound SETTINGS containing MAX_FRAME_SIZE.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  // Ack of client's initial settings.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
+  // overflow the connection-level window. The result should be a GOAWAY, but
+  // because the processing is split across several calls, nghttp2 instead
+  // delivers the data payloads (which the visitor then consumes). This is a bug
+  // in nghttp2, which should recognize the flow control error.
+  const std::string overflow_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Data(1, std::string(window_overflow_bytes, 'a'))
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, window_overflow_bytes));
+  // BUG: The visitor should not have received the data.
+  EXPECT_CALL(visitor, OnDataForStream(1, _))
+      .WillRepeatedly(
+          [&adapter](Http2StreamId stream_id, absl::string_view data) {
+            adapter->MarkDataConsumedForStream(stream_id, data.size());
+            return true;
+          });
+
+  const size_t chunk_length = 16384;
+  ASSERT_GE(overflow_frames.size(), chunk_length);
+  absl::string_view remaining = overflow_frames;
+  while (!remaining.empty()) {
+    absl::string_view chunk = remaining.substr(0, chunk_length);
+    process_result = adapter->ProcessBytes(chunk);
+    EXPECT_EQ(chunk.length(), static_cast<size_t>(process_result));
+
+    remaining.remove_prefix(chunk.length());
+  }
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::WINDOW_UPDATE,
+                                            SpdyFrameType::WINDOW_UPDATE}));
+}
+
+TEST(NgHttp2AdapterTest, ClientDisobeysStreamFlowControl) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  const std::string more_frames = TestFrameSequence()
+                                      // 70000 bytes of data
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(4464, 'a'))
+                                      .Serialize();
+
+  testing::InSequence s;
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  adapter->SubmitWindowUpdate(0, 20000);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::WINDOW_UPDATE}));
+  visitor.Clear();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  // No further frame data or headers for stream 1 are delivered.
+
+  result = adapter->ProcessBytes(more_frames);
+  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::FLOW_CONTROL_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerErrorWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
+      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
+  // DATA frame is not delivered to the visitor.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerErrorWhileHandlingHeadersDropsFrames) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .Metadata(1, "This is the request metadata.")
+                                 .RstStream(1, Http2ErrorCode::CANCEL)
+                                 .WindowUpdate(0, 2000)
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/false)
+                                 .Metadata(3, "This is the request metadata.",
+                                           /*multiple_frames=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
+      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
+  // For the RST_STREAM-marked stream, the control frames and METADATA frame but
+  // not the DATA frame are delivered to the visitor.
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 0));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(3, "This is the re"))
+      .WillOnce(testing::DoAll(testing::InvokeWithoutArgs([&adapter]() {
+                                 adapter->SubmitRst(
+                                     3, Http2ErrorCode::REFUSED_STREAM);
+                               }),
+                               testing::Return(true)));
+  // The rest of the metadata is still delivered to the visitor.
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(3, "quest metadata."));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(3));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::REFUSED_STREAM));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerConnectionErrorWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"Accept", "uppercase, oh boy!"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnErrorDebug);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader))
+      .WillOnce(testing::Return(false));
+  // Translation to nghttp2 treats this error as a general parsing error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(result, NGHTTP2_ERR_CALLBACK_FAILURE);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack and RST_STREAM
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerErrorAfterHandlingHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(-902, result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+// Exercises the case when a visitor chooses to reject a frame based solely on
+// the frame header, which is a fatal error for the connection.
+TEST(NgHttp2AdapterTest, ServerRejectsFrameHeader) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Ping(64)
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(-902, result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerRejectsBeginningOfData) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack.
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerRejectsStreamData) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
+  EXPECT_CALL(visitor, OnDataForStream(1, _)).WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack.
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerReceivesTooLargeHeader) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  // nghttp2 will accept a maximum of 64kB of huffman encoded data per header
+  // field.
+  const std::string too_large_value = std::string(80 * 1024, 'q');
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"x-toobig", too_large_value}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  // Further header processing is skipped, as the header field is too large.
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Since nghttp2 opted not to process the header, it generates a GOAWAY with
+  // error code COMPRESSION_ERROR.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, 8, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, 8, 0x0,
+                          static_cast<int>(Http2ErrorCode::COMPRESSION_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // GOAWAY.
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerReceivesInvalidAuthority) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "ex|ample.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [:authority], value: [ex|ample.com]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0x0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerSubmitResponse) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
+      .WillOnce(testing::InvokeWithoutArgs([&adapter, kSentinel1]() {
+        adapter->SetStreamUserData(1, const_cast<char*>(kSentinel1));
+        return true;
+      }));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
+
+  // Server will want to send a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_EQ(0, adapter->GetHpackEncoderDynamicTableSize());
+
+  EXPECT_FALSE(adapter->want_write());
+  const absl::string_view kBody = "This is an example response body.";
+  // A data fin is not sent so that the stream remains open, and the flow
+  // control state can be verified.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  int submit_result = adapter->SubmitResponse(
+      1,
+      ToHeaders({{":status", "404"},
+                 {"x-comment", "I have no idea what you're talking about."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  // Stream user data should have been set successfully after receiving headers.
+  EXPECT_EQ(kSentinel1, adapter->GetStreamUserData(1));
+  adapter->SetStreamUserData(1, nullptr);
+  EXPECT_EQ(nullptr, adapter->GetStreamUserData(1));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  EXPECT_FALSE(adapter->want_write());
+
+  // Some data was sent, so the remaining send window size should be less than
+  // the default.
+  EXPECT_LT(adapter->GetStreamSendWindowSize(1), kInitialFlowControlWindowSize);
+  EXPECT_GT(adapter->GetStreamSendWindowSize(1), 0);
+  // Send window for a nonexistent stream is not available.
+  EXPECT_EQ(adapter->GetStreamSendWindowSize(3), -1);
+
+  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 0);
+}
+
+// Should also test: client attempts shutdown, server attempts shutdown after an
+// explicit GOAWAY.
+TEST(NgHttp2AdapterTest, ServerSendsShutdown) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  adapter->SubmitShutdownNotice();
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerSendsTrailers) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  // Server will want to send a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_FALSE(adapter->want_write());
+  const absl::string_view kBody = "This is an example response body.";
+
+  // The body source must indicate that the end of the body is not the end of
+  // the stream.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  // The body source has been exhausted by the call to Send() above.
+  int trailer_result = adapter->SubmitTrailer(
+      1, ToHeaders({{"final-status", "a-ok"},
+                    {"x-comment", "trailers sure are cool"}}));
+  ASSERT_EQ(trailer_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+}
+
+TEST(NgHttp2AdapterTest, ClientSendsContinuation) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true,
+                                          /*add_continuation=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 1));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+}
+
+TEST(NgHttp2AdapterTest, ClientSendsMetadataWithContinuation) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Metadata(0, "Example connection metadata in multiple frames", true)
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false,
+                   /*add_continuation=*/true)
+          .Metadata(1,
+                    "Some stream metadata that's also sent in multiple frames",
+                    true)
+          .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Metadata on stream 0
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 0));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  // Metadata on stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 0));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+  EXPECT_EQ("Example connection metadata in multiple frames",
+            absl::StrJoin(visitor.GetMetadata(0), ""));
+  EXPECT_EQ("Some stream metadata that's also sent in multiple frames",
+            absl::StrJoin(visitor.GetMetadata(1), ""));
+}
+
+TEST(NgHttp2AdapterTest, RepeatedHeaderNames) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "text/plain"},
+                                           {"accept", "text/html"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/plain"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/html"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  const std::vector<Header> headers1 = ToHeaders(
+      {{":status", "200"}, {"content-length", "10"}, {"content-length", "10"}});
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload("perfection");
+  body1->EndData();
+
+  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
+  ASSERT_EQ(0, submit_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 10, 0x1, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::DATA}));
+}
+
+TEST(NgHttp2AdapterTest, ServerRespondsToRequestWithTrailers) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/one"}})
+          .Data(1, "Example data, woohoo.")
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  const std::vector<Header> headers1 = ToHeaders({{":status", "200"}});
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  TestDataFrameSource* body1_ptr = body1.get();
+
+  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
+  ASSERT_EQ(0, submit_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string more_frames =
+      TestFrameSequence()
+          .Headers(1, {{"extra-info", "Trailers are weird but good?"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "extra-info",
+                                         "Trailers are weird but good?"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  result = adapter->ProcessBytes(more_frames);
+  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
+
+  body1_ptr->EndData();
+  EXPECT_EQ(true, adapter->ResumeStream(1));
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
+}
+
+TEST(NgHttp2AdapterTest, ServerSubmitsResponseWithDataSourceError) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->SimulateError();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 2));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::RST_STREAM}));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  int trailer_result =
+      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
+  // The library does not object to the user queuing trailers, even through the
+  // stream has already been closed.
+  EXPECT_EQ(trailer_result, 0);
+}
+
+TEST(NgHttp2AdapterTest, CompleteRequestWithServerResponse) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.", /*fin=*/true)
+          .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  int submit_result =
+      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, IncompleteRequestWithServerResponse) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  int submit_result =
+      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  // BUG: Should send RST_STREAM NO_ERROR as well, but nghttp2 does not.
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ServerSendsInvalidTrailers) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  const absl::string_view kBody = "This is an example response body.";
+
+  // The body source must indicate that the end of the body is not the end of
+  // the stream.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  // The body source has been exhausted by the call to Send() above.
+  int trailer_result =
+      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
+  ASSERT_EQ(trailer_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerDropsNewStreamBelowWatermark) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(3,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(3, "This is the request body.")
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(3, 25));
+  EXPECT_CALL(visitor, OnDataForStream(3, "This is the request body."));
+
+  // It looks like nghttp2 delivers the under-watermark frame header but
+  // otherwise silently drops the rest of the frame without error.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnInvalidFrame).Times(0);
+  EXPECT_CALL(visitor, OnConnectionError).Times(0);
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterInteractionTest,
+     ClientServerInteractionRepeatedHeaderNames) {
+  DataSavingVisitor client_visitor;
+  auto client_adapter = NgHttp2Adapter::CreateClientAdapter(client_visitor);
+
+  client_adapter->SubmitSettings({});
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"},
+                 {"accept", "text/plain"},
+                 {"accept", "text/html"}});
+
+  const int32_t stream_id1 =
+      client_adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(client_visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(client_visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  int send_result = client_adapter->Send();
+  EXPECT_EQ(0, send_result);
+
+  DataSavingVisitor server_visitor;
+  auto server_adapter = NgHttp2Adapter::CreateServerAdapter(server_visitor);
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
+  EXPECT_CALL(server_visitor, OnSettingsStart());
+  EXPECT_CALL(server_visitor, OnSetting(_)).Times(testing::AnyNumber());
+  EXPECT_CALL(server_visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
+  EXPECT_CALL(server_visitor,
+              OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(server_visitor,
+              OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/plain"));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/html"));
+  EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(server_visitor, OnEndStream(1));
+
+  int64_t result = server_adapter->ProcessBytes(client_visitor.data());
+  EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
+}
+
+TEST(NgHttp2AdapterTest, ServerForbidsWindowUpdateOnIdleStream) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnInvalidFrame(1, _));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // The GOAWAY apparently causes the SETTINGS ack to be dropped.
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerForbidsDataOnIdleStream) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Data(1, "Sorry, out of order")
+                                 .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // In this case, nghttp2 goes straight to GOAWAY and does not invoke the
+  // invalid frame callback.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // The GOAWAY apparently causes the SETTINGS ack to be dropped.
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerForbidsRstStreamOnIdleStream) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnInvalidFrame(1, _));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // The GOAWAY apparently causes the SETTINGS ack to be dropped.
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerForbidsNewStreamAboveStreamLimit) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Let the client send a SETTINGS ack and then attempt to open more than the
+  // advertised number of streams. The overflow stream should be rejected.
+  const std::string stream_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":method", "GET"},
+                    {":scheme", "http"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kProtocol));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  // The server should send a GOAWAY for this error, even though
+  // OnInvalidFrame() returns true.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerRstStreamsNewStreamAboveStreamLimitBeforeAck) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Let the client avoid sending a SETTINGS ack and attempt to open more than
+  // the advertised number of streams. The server should still reject the
+  // overflow stream, albeit with RST_STREAM REFUSED_STREAM instead of GOAWAY.
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":method", "GET"},
+                    {":scheme", "http"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  3, Http2VisitorInterface::InvalidFrameError::kRefusedStream));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_result, stream_frames.size());
+
+  // The server sends a RST_STREAM for the offending stream.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, AutomaticSettingsAndPingAcks) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  const std::string frames =
+      TestFrameSequence().ClientPreface().Ping(42).Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // PING
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server preface does not appear to include the mandatory SETTINGS frame.
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  // PING ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
+}
+
+TEST(NgHttp2AdapterTest, AutomaticPingAcksDisabled) {
+  DataSavingVisitor visitor;
+  nghttp2_option* options;
+  nghttp2_option_new(&options);
+  nghttp2_option_set_no_auto_ping_ack(options, 1);
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor, options);
+  nghttp2_option_del(options);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().Ping(42).Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // PING
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server preface does not appear to include the mandatory SETTINGS frame.
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  // No PING ack expected because automatic PING acks are disabled.
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  // The client attempts to send a CONNECT request with the `:protocol`
+  // pseudoheader before receiving the server's SETTINGS frame.
+  const std::string stream1_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":method", "CONNECT"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"},
+                    {":protocol", "websocket"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [:protocol], value: [websocket]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  int64_t stream_result = adapter->ProcessBytes(stream1_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream1_frames.size());
+
+  // Server sends a SETTINGS ack and initial SETTINGS (with
+  // ENABLE_CONNECT_PROTOCOL).
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  // The server sends a RST_STREAM for the offending stream.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+  visitor.Clear();
+
+  // The client attempts to send a CONNECT request with the `:protocol`
+  // pseudoheader before acking the server's SETTINGS frame.
+  const std::string stream3_frames =
+      TestFrameSequence()
+          .Headers(3,
+                   {{":method", "CONNECT"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"},
+                    {":protocol", "websocket"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Surprisingly, nghttp2 is okay with this.
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  stream_result = adapter->ProcessBytes(stream3_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream3_frames.size());
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, ServerAllowsProtocolPseudoheaderAfterAck) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  // Server initial SETTINGS (with ENABLE_CONNECT_PROTOCOL) and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  visitor.Clear();
+
+  // The client attempts to send a CONNECT request with the `:protocol`
+  // pseudoheader after acking the server's SETTINGS frame.
+  const std::string stream_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Headers(1,
+                   {{":method", "CONNECT"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"},
+                    {":protocol", "websocket"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(NgHttp2AdapterTest, SkipsSendingFramesForRejectedStream) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "http"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body->AppendPayload("Here is some data, which will be completely ignored!");
+
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}}), std::move(body));
+  ASSERT_EQ(0, submit_result);
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+
+  adapter->SubmitWindowUpdate(1, 1024);
+  adapter->SubmitRst(1, Http2ErrorCode::INTERNAL_ERROR);
+
+  // Server initial SETTINGS and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  // nghttp2 apparently allows extension frames to be sent on reset streams.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
+
+  // The server sends a RST_STREAM for the offending stream.
+  // The response HEADERS, DATA and WINDOW_UPDATE are all ignored.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS,
+                            static_cast<SpdyFrameType>(kMetadataFrameType),
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerStartsShutdown) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  adapter->SubmitShutdownNotice();
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(NgHttp2AdapterTest, ServerStartsShutdownAfterGoaway) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  adapter->SubmitGoAway(1, Http2ErrorCode::HTTP2_NO_ERROR,
+                        "and don't come back!");
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+
+  // No-op, since a GOAWAY has previously been enqueued.
+  adapter->SubmitShutdownNotice();
+  EXPECT_FALSE(adapter->want_write());
+}
+
+// Verifies that a connection-level processing error results in repeatedly
+// returning a positive value for ProcessBytes() to mark all data as consumed.
+TEST(NgHttp2AdapterTest, ConnectionErrorWithBlackholeSinkingData) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnInvalidFrame(1, _));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  // Ask the connection to process more bytes. Because the option is enabled,
+  // the data should be marked as consumed.
+  const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
+  const int64_t next_result = adapter->ProcessBytes(next_frame);
+  EXPECT_EQ(static_cast<size_t>(next_result), next_frame.size());
+}
+
+TEST(NgHttp2AdapterTest, ServerDoesNotSendFramesAfterImmediateGoAway) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  // Submit a custom initial SETTINGS frame with one setting.
+  adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  // Submit a response for the stream.
+  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body->AppendPayload("This data is doomed to never be written.");
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}}), std::move(body));
+  ASSERT_EQ(0, submit_result);
+
+  // Submit a WINDOW_UPDATE frame.
+  adapter->SubmitWindowUpdate(kConnectionStreamId, 42);
+
+  // Submit another SETTINGS frame.
+  adapter->SubmitSettings({});
+
+  // Submit some metadata.
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Trigger a connection error. Only the response headers will be written.
+  const std::string connection_error_frames =
+      TestFrameSequence().WindowUpdate(3, 42).Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnInvalidFrame(3, _));
+
+  const int64_t result = adapter->ProcessBytes(connection_error_frames);
+  EXPECT_EQ(static_cast<size_t>(result), connection_error_frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // The GOAWAY apparently causes the other frames to be dropped except for the
+  // non-ack SETTINGS frames; nghttp2 sends non-ack SETTINGS frames because they
+  // could be the initial SETTINGS frame. However, nghttp2 still allows sending
+  // multiple non-ack SETTINGS, which feels non-ideal.
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::GOAWAY}));
+  visitor.Clear();
+
+  // Try to submit more frames for writing. They should not be written.
+  adapter->SubmitPing(42);
+  EXPECT_FALSE(adapter->want_write());
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesContentLength) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/one"},
+                       {"content-length", "2"}})
+          .Data(1, "hi", /*fin=*/true)
+          .Headers(3,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"},
+                    {"content-length", "nan"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Stream 1: content-length is correct
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
+  EXPECT_CALL(visitor, OnDataForStream(1, "hi"));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  // Stream 3: content-length is not a number
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 3, name: [content-length], value: [nan]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesContentLengthMismatch) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/two"},
+                       {"content-length", "2"}})
+          .Data(1, "h", /*fin=*/true)
+          .Headers(3, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/three"},
+                       {"content-length", "2"}})
+          .Data(3, "howdy", /*fin=*/true)
+          .Headers(5,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/four"},
+                    {"content-length", "2"}},
+                   /*fin=*/true)
+          .Headers(7,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/four"},
+                    {"content-length", "2"}},
+                   /*fin=*/false)
+          .Data(7, "h", /*fin=*/false)
+          .Headers(7, {{"extra-info", "Trailers with content-length mismatch"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Stream 1: content-length is larger than actual data
+  // All data is delivered to the visitor, but OnInvalidFrame() is not.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 1));
+  EXPECT_CALL(visitor, OnDataForStream(1, "h"));
+
+  // Stream 3: content-length is smaller than actual data
+  // The beginning of data is delivered to the visitor, but not the actual data,
+  // and neither is OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(3, 5));
+
+  // Stream 5: content-length is invalid and HEADERS ends the stream
+  // When the stream ends with HEADERS, nghttp2 invokes OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  5, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  // Stream 7: content-length is invalid and trailers end the stream
+  // When the stream ends with trailers, nghttp2 invokes OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
+  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(7));
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(7, 1));
+  EXPECT_CALL(visitor, OnDataForStream(7, "h"));
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
+  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _));
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  7, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 7, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesAsteriskPathForOptions) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::string stream_frames = TestFrameSequence()
+                                        .ClientPreface()
+                                        .Headers(1,
+                                                 {{":scheme", "https"},
+                                                  {":authority", "example.com"},
+                                                  {":path", "*"},
+                                                  {":method", "OPTIONS"}},
+                                                 /*fin=*/true)
+                                        .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesInvalidPath) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "*"},
+                    {":method", "GET"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "other/non/slash/starter"},
+                    {":method", "GET"}},
+                   /*fin=*/true)
+          .Headers(5,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", ""},
+                    {":method", "GET"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  3, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(2);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 5, name: [:path], value: []"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesTeHeader) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::string stream_frames = TestFrameSequence()
+                                        .ClientPreface()
+                                        .Headers(1,
+                                                 {{":scheme", "https"},
+                                                  {":authority", "example.com"},
+                                                  {":path", "/"},
+                                                  {":method", "GET"},
+                                                  {"te", "trailers"}},
+                                                 /*fin=*/true)
+                                        .Headers(3,
+                                                 {{":scheme", "https"},
+                                                  {":authority", "example.com"},
+                                                  {":path", "/"},
+                                                  {":method", "GET"},
+                                                  {"te", "trailers, deflate"}},
+                                                 /*fin=*/true)
+                                        .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Stream 1: TE: trailers should be allowed.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  // Stream 3: TE: <non-trailers> should be rejected.
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 3, name: [te], value: [trailers, deflate]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(NgHttp2AdapterTest, ServerHandlesConnectionSpecificHeaders) {
+  DataSavingVisitor visitor;
+  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"connection", "keep-alive"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"proxy-connection", "keep-alive"}},
+                   /*fin=*/true)
+          .Headers(5,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"keep-alive", "timeout=42"}},
+                   /*fin=*/true)
+          .Headers(7,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"transfer-encoding", "chunked"}},
+                   /*fin=*/true)
+          .Headers(9,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"upgrade", "h2c"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // All streams contain a connection-specific header and should be rejected.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 1, name: [connection], value: [keep-alive]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 3, name: [proxy-connection], value: [keep-alive]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 5, name: [keep-alive], value: [timeout=42]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
+  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 7, name: [transfer-encoding], value: [chunked]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(7, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
+  EXPECT_CALL(visitor, OnHeaderForStream(9, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnErrorDebug("Invalid HTTP header field was received: frame type: 1, "
+                   "stream: 9, name: [upgrade], value: [h2c]"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(9, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 7, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 9, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 9, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(9, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_callbacks.cc b/quiche/http2/adapter/nghttp2_callbacks.cc
new file mode 100644
index 0000000..a474c0e
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_callbacks.cc
@@ -0,0 +1,354 @@
+#include "quiche/http2/adapter/nghttp2_callbacks.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/data_source.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/nghttp2_data_provider.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace http2 {
+namespace adapter {
+namespace callbacks {
+
+ssize_t OnReadyToSend(nghttp2_session* /* session */, const uint8_t* data,
+                      size_t length, int flags, void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const int64_t result = visitor->OnReadyToSend(ToStringView(data, length));
+  QUICHE_VLOG(1) << "OnReadyToSend(length=" << length << ", flags=" << flags
+                 << ") returning " << result;
+  if (result > 0) {
+    return result;
+  } else if (result == Http2VisitorInterface::kSendBlocked) {
+    return -504;  // NGHTTP2_ERR_WOULDBLOCK
+  } else {
+    return -902;  // NGHTTP2_ERR_CALLBACK_FAILURE
+  }
+}
+
+int OnBeginFrame(nghttp2_session* /* session */,
+                 const nghttp2_frame_hd* header,
+                 void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  bool result = visitor->OnFrameHeader(header->stream_id, header->length,
+                                       header->type, header->flags);
+  if (!result) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  if (header->type == NGHTTP2_DATA) {
+    result = visitor->OnBeginDataForStream(header->stream_id, header->length);
+  } else if (header->type == kMetadataFrameType) {
+    visitor->OnBeginMetadataForStream(header->stream_id, header->length);
+  }
+  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
+}
+
+int OnFrameReceived(nghttp2_session* /* session */,
+                    const nghttp2_frame* frame,
+                    void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const Http2StreamId stream_id = frame->hd.stream_id;
+  switch (frame->hd.type) {
+    // The beginning of the DATA frame is handled in OnBeginFrame(), and the
+    // beginning of the header block is handled in client/server-specific
+    // callbacks. This callback handles the point at which the entire logical
+    // frame has been received and processed.
+    case NGHTTP2_DATA:
+      if ((frame->hd.flags & NGHTTP2_FLAG_PADDED) != 0) {
+        visitor->OnDataPaddingLength(stream_id, frame->data.padlen);
+      }
+      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+        visitor->OnEndStream(stream_id);
+      }
+      break;
+    case NGHTTP2_HEADERS: {
+      if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS) {
+        const bool result = visitor->OnEndHeadersForStream(stream_id);
+        if (!result) {
+          return NGHTTP2_ERR_CALLBACK_FAILURE;
+        }
+      }
+      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+        visitor->OnEndStream(stream_id);
+      }
+      break;
+    }
+    case NGHTTP2_PRIORITY: {
+      nghttp2_priority_spec priority_spec = frame->priority.pri_spec;
+      visitor->OnPriorityForStream(stream_id, priority_spec.stream_id,
+                                   priority_spec.weight,
+                                   priority_spec.exclusive != 0);
+      break;
+    }
+    case NGHTTP2_RST_STREAM: {
+      visitor->OnRstStream(stream_id,
+                           ToHttp2ErrorCode(frame->rst_stream.error_code));
+      break;
+    }
+    case NGHTTP2_SETTINGS:
+      if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
+        visitor->OnSettingsAck();
+      } else {
+        visitor->OnSettingsStart();
+        for (size_t i = 0; i < frame->settings.niv; ++i) {
+          nghttp2_settings_entry entry = frame->settings.iv[i];
+          // The nghttp2_settings_entry uses int32_t for the ID; we must cast.
+          visitor->OnSetting(Http2Setting{
+              static_cast<Http2SettingsId>(entry.settings_id), entry.value});
+        }
+        visitor->OnSettingsEnd();
+      }
+      break;
+    case NGHTTP2_PUSH_PROMISE:
+      // This case is handled by headers-related callbacks:
+      //   1. visitor->OnPushPromiseForStream() is invoked in the client-side
+      //      OnHeadersStart() adapter callback, as nghttp2 only allows clients
+      //      to receive PUSH_PROMISE frames.
+      //   2. visitor->OnHeaderForStream() is invoked for each server push
+      //      request header in the PUSH_PROMISE header block.
+      //   3. This switch statement is reached once all server push request
+      //      headers have been parsed.
+      break;
+    case NGHTTP2_PING: {
+      Http2PingId ping_id;
+      std::memcpy(&ping_id, frame->ping.opaque_data, sizeof(Http2PingId));
+      visitor->OnPing(quiche::QuicheEndian::NetToHost64(ping_id),
+                      (frame->hd.flags & NGHTTP2_FLAG_ACK) != 0);
+      break;
+    }
+    case NGHTTP2_GOAWAY: {
+      absl::string_view opaque_data(
+          reinterpret_cast<const char*>(frame->goaway.opaque_data),
+          frame->goaway.opaque_data_len);
+      const bool result = visitor->OnGoAway(
+          frame->goaway.last_stream_id,
+          ToHttp2ErrorCode(frame->goaway.error_code), opaque_data);
+      if (!result) {
+        return NGHTTP2_ERR_CALLBACK_FAILURE;
+      }
+      break;
+    }
+    case NGHTTP2_WINDOW_UPDATE: {
+      visitor->OnWindowUpdate(stream_id,
+                              frame->window_update.window_size_increment);
+      break;
+    }
+    case NGHTTP2_CONTINUATION:
+      // This frame type should not be passed to any callbacks, according to
+      // https://nghttp2.org/documentation/enums.html#c.NGHTTP2_CONTINUATION.
+      QUICHE_LOG(ERROR) << "Unexpected receipt of NGHTTP2_CONTINUATION type!";
+      break;
+    case NGHTTP2_ALTSVC:
+      break;
+    case NGHTTP2_ORIGIN:
+      break;
+  }
+
+  return 0;
+}
+
+int OnBeginHeaders(nghttp2_session* /* session */,
+                   const nghttp2_frame* frame,
+                   void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const bool result = visitor->OnBeginHeadersForStream(frame->hd.stream_id);
+  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
+}
+
+int OnHeader(nghttp2_session* /* session */, const nghttp2_frame* frame,
+             nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t /*flags*/,
+             void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const Http2VisitorInterface::OnHeaderResult result =
+      visitor->OnHeaderForStream(frame->hd.stream_id, ToStringView(name),
+                                 ToStringView(value));
+  switch (result) {
+    case Http2VisitorInterface::HEADER_OK:
+      return 0;
+    case Http2VisitorInterface::HEADER_CONNECTION_ERROR:
+    case Http2VisitorInterface::HEADER_COMPRESSION_ERROR:
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    case Http2VisitorInterface::HEADER_RST_STREAM:
+    case Http2VisitorInterface::HEADER_FIELD_INVALID:
+    case Http2VisitorInterface::HEADER_HTTP_MESSAGING:
+      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+  }
+  // Unexpected value.
+  return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+}
+
+int OnBeforeFrameSent(nghttp2_session* /* session */,
+                      const nghttp2_frame* frame, void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  LogBeforeSend(*frame);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  return visitor->OnBeforeFrameSent(frame->hd.type, frame->hd.stream_id,
+                                    frame->hd.length, frame->hd.flags);
+}
+
+int OnFrameSent(nghttp2_session* /* session */, const nghttp2_frame* frame,
+                void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  uint32_t error_code = 0;
+  if (frame->hd.type == NGHTTP2_RST_STREAM) {
+    error_code = frame->rst_stream.error_code;
+  } else if (frame->hd.type == NGHTTP2_GOAWAY) {
+    error_code = frame->goaway.error_code;
+  }
+  return visitor->OnFrameSent(frame->hd.type, frame->hd.stream_id,
+                              frame->hd.length, frame->hd.flags, error_code);
+}
+
+int OnFrameNotSent(nghttp2_session* /* session */, const nghttp2_frame* frame,
+                   int /* lib_error_code */, void* /* user_data */) {
+  if (frame->hd.type == kMetadataFrameType) {
+    auto* source = static_cast<MetadataSource*>(frame->ext.payload);
+    if (source == nullptr) {
+      QUICHE_BUG(not_sent_payload_is_nullptr)
+          << "Extension frame payload for stream " << frame->hd.stream_id
+          << " is null!";
+    } else {
+      source->OnFailure();
+    }
+  }
+  return 0;
+}
+
+int OnInvalidFrameReceived(nghttp2_session* /* session */,
+                           const nghttp2_frame* frame, int lib_error_code,
+                           void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const bool result = visitor->OnInvalidFrame(
+      frame->hd.stream_id, ToInvalidFrameError(lib_error_code));
+  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
+}
+
+int OnDataChunk(nghttp2_session* /* session */, uint8_t /*flags*/,
+                Http2StreamId stream_id, const uint8_t* data, size_t len,
+                void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const bool result = visitor->OnDataForStream(
+      stream_id, absl::string_view(reinterpret_cast<const char*>(data), len));
+  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
+}
+
+int OnStreamClosed(nghttp2_session* /* session */,
+                   Http2StreamId stream_id,
+                   uint32_t error_code,
+                   void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  const bool result =
+      visitor->OnCloseStream(stream_id, ToHttp2ErrorCode(error_code));
+  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
+}
+
+int OnExtensionChunkReceived(nghttp2_session* /*session*/,
+                             const nghttp2_frame_hd* hd, const uint8_t* data,
+                             size_t len, void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  if (hd->type != kMetadataFrameType) {
+    QUICHE_LOG(ERROR) << "Unexpected frame type: "
+                      << static_cast<int>(hd->type);
+    return NGHTTP2_ERR_CANCEL;
+  }
+  const bool result =
+      visitor->OnMetadataForStream(hd->stream_id, ToStringView(data, len));
+  return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
+}
+
+int OnUnpackExtensionCallback(nghttp2_session* /*session*/, void** /*payload*/,
+                              const nghttp2_frame_hd* hd, void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  if (hd->flags == kMetadataEndFlag) {
+    const bool result = visitor->OnMetadataEndForStream(hd->stream_id);
+    if (!result) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+ssize_t OnPackExtensionCallback(nghttp2_session* /*session*/, uint8_t* buf,
+                                size_t len, const nghttp2_frame* frame,
+                                void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* source = static_cast<MetadataSource*>(frame->ext.payload);
+  if (source == nullptr) {
+    QUICHE_BUG(payload_is_nullptr) << "Extension frame payload for stream "
+                                   << frame->hd.stream_id << " is null!";
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  const std::pair<int64_t, bool> result = source->Pack(buf, len);
+  if (result.first < 0) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  const bool end_metadata_flag = (frame->hd.flags & kMetadataEndFlag);
+  QUICHE_LOG_IF(DFATAL, result.second != end_metadata_flag)
+      << "Metadata ends: " << result.second
+      << " has kMetadataEndFlag: " << end_metadata_flag;
+  return result.first;
+}
+
+int OnError(nghttp2_session* /*session*/, int /*lib_error_code*/,
+            const char* msg, size_t len, void* user_data) {
+  QUICHE_CHECK_NE(user_data, nullptr);
+  auto* visitor = static_cast<Http2VisitorInterface*>(user_data);
+  visitor->OnErrorDebug(absl::string_view(msg, len));
+  return 0;
+}
+
+nghttp2_session_callbacks_unique_ptr Create() {
+  nghttp2_session_callbacks* callbacks;
+  nghttp2_session_callbacks_new(&callbacks);
+
+  nghttp2_session_callbacks_set_send_callback(callbacks, &OnReadyToSend);
+  nghttp2_session_callbacks_set_on_begin_frame_callback(callbacks,
+                                                        &OnBeginFrame);
+  nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
+                                                       &OnFrameReceived);
+  nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks,
+                                                          &OnBeginHeaders);
+  nghttp2_session_callbacks_set_on_header_callback2(callbacks, &OnHeader);
+  nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks,
+                                                            &OnDataChunk);
+  nghttp2_session_callbacks_set_on_stream_close_callback(callbacks,
+                                                         &OnStreamClosed);
+  nghttp2_session_callbacks_set_before_frame_send_callback(callbacks,
+                                                           &OnBeforeFrameSent);
+  nghttp2_session_callbacks_set_on_frame_send_callback(callbacks, &OnFrameSent);
+  nghttp2_session_callbacks_set_on_frame_not_send_callback(callbacks,
+                                                           &OnFrameNotSent);
+  nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
+      callbacks, &OnInvalidFrameReceived);
+  nghttp2_session_callbacks_set_error_callback2(callbacks, &OnError);
+  nghttp2_session_callbacks_set_send_data_callback(
+      callbacks, &DataFrameSourceSendCallback);
+  nghttp2_session_callbacks_set_pack_extension_callback(
+      callbacks, &OnPackExtensionCallback);
+  nghttp2_session_callbacks_set_unpack_extension_callback(
+      callbacks, &OnUnpackExtensionCallback);
+  nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
+      callbacks, &OnExtensionChunkReceived);
+  return MakeCallbacksPtr(callbacks);
+}
+
+}  // namespace callbacks
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_callbacks.h b/quiche/http2/adapter/nghttp2_callbacks.h
new file mode 100644
index 0000000..51f9c74
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_callbacks.h
@@ -0,0 +1,94 @@
+#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_CALLBACKS_H_
+#define QUICHE_HTTP2_ADAPTER_NGHTTP2_CALLBACKS_H_
+
+#include <cstdint>
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+
+namespace http2 {
+namespace adapter {
+namespace callbacks {
+
+// The following functions are nghttp2 callbacks that Nghttp2Adapter sets at the
+// beginning of its lifetime. It is expected that |user_data| holds an
+// Http2VisitorInterface.
+
+// Callback once the library is ready to send serialized frames.
+ssize_t OnReadyToSend(nghttp2_session* session,
+                      const uint8_t* data,
+                      size_t length,
+                      int flags,
+                      void* user_data);
+
+// Callback once a frame header has been received.
+int OnBeginFrame(nghttp2_session* session, const nghttp2_frame_hd* header,
+                 void* user_data);
+
+// Callback once a complete frame has been received.
+int OnFrameReceived(nghttp2_session* session, const nghttp2_frame* frame,
+                    void* user_data);
+
+// Callback at the start of a frame carrying headers.
+int OnBeginHeaders(nghttp2_session* session,
+                   const nghttp2_frame* frame,
+                   void* user_data);
+
+// Callback once a name-value header has been received.
+int OnHeader(nghttp2_session* session, const nghttp2_frame* frame,
+             nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t flags,
+             void* user_data);
+
+// Invoked immediately before sending a frame.
+int OnBeforeFrameSent(nghttp2_session* session, const nghttp2_frame* frame,
+                      void* user_data);
+
+// Invoked immediately after a frame is sent.
+int OnFrameSent(nghttp2_session* session, const nghttp2_frame* frame,
+                void* user_data);
+
+// Invoked when a non-DATA frame is not sent because of an error.
+int OnFrameNotSent(nghttp2_session* session, const nghttp2_frame* frame,
+                   int lib_error_code, void* user_data);
+
+// Invoked when an invalid frame is received.
+int OnInvalidFrameReceived(nghttp2_session* session, const nghttp2_frame* frame,
+                           int lib_error_code, void* user_data);
+
+// Invoked when a chunk of data (from a DATA frame payload) has been received.
+int OnDataChunk(nghttp2_session* session, uint8_t flags,
+                Http2StreamId stream_id, const uint8_t* data, size_t len,
+                void* user_data);
+
+// Callback once a stream has been closed.
+int OnStreamClosed(nghttp2_session* session, Http2StreamId stream_id,
+                   uint32_t error_code, void* user_data);
+
+// Invoked when nghttp2 has a chunk of extension frame data to pass to the
+// application.
+int OnExtensionChunkReceived(nghttp2_session* session,
+                             const nghttp2_frame_hd* hd, const uint8_t* data,
+                             size_t len, void* user_data);
+
+// Invoked when nghttp2 wants the application to unpack an extension payload.
+int OnUnpackExtensionCallback(nghttp2_session* session, void** payload,
+                              const nghttp2_frame_hd* hd, void* user_data);
+
+// Invoked when nghttp2 is ready to pack an extension payload. Returns the
+// number of bytes serialized to |buf|.
+ssize_t OnPackExtensionCallback(nghttp2_session* session, uint8_t* buf,
+                                size_t len, const nghttp2_frame* frame,
+                                void* user_data);
+
+// Invoked when the library has an error message to deliver.
+int OnError(nghttp2_session* session, int lib_error_code, const char* msg,
+            size_t len, void* user_data);
+
+nghttp2_session_callbacks_unique_ptr Create();
+
+}  // namespace callbacks
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_CALLBACKS_H_
diff --git a/quiche/http2/adapter/nghttp2_data_provider.cc b/quiche/http2/adapter/nghttp2_data_provider.cc
new file mode 100644
index 0000000..0a22fb3
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_data_provider.cc
@@ -0,0 +1,63 @@
+#include "quiche/http2/adapter/nghttp2_data_provider.h"
+
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+
+namespace http2 {
+namespace adapter {
+namespace callbacks {
+
+namespace {
+const size_t kFrameHeaderSize = 9;
+}
+
+ssize_t DataFrameSourceReadCallback(nghttp2_session* /* session */,
+                                    int32_t /* stream_id */,
+                                    uint8_t* /* buf */,
+                                    size_t length,
+                                    uint32_t* data_flags,
+                                    nghttp2_data_source* source,
+                                    void* /* user_data */) {
+  *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
+  auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
+  auto [result_length, done] = frame_source->SelectPayloadLength(length);
+  if (result_length == 0 && !done) {
+    return NGHTTP2_ERR_DEFERRED;
+  } else if (result_length == DataFrameSource::kError) {
+    return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+  }
+  if (done) {
+    *data_flags |= NGHTTP2_DATA_FLAG_EOF;
+  }
+  if (!frame_source->send_fin()) {
+    *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
+  }
+  return result_length;
+}
+
+int DataFrameSourceSendCallback(nghttp2_session* /* session */,
+                                nghttp2_frame* /* frame */,
+                                const uint8_t* framehd,
+                                size_t length,
+                                nghttp2_data_source* source,
+                                void* /* user_data */) {
+  auto* frame_source = static_cast<DataFrameSource*>(source->ptr);
+  frame_source->Send(ToStringView(framehd, kFrameHeaderSize), length);
+  return 0;
+}
+
+}  // namespace callbacks
+
+std::unique_ptr<nghttp2_data_provider> MakeDataProvider(
+    DataFrameSource* source) {
+  if (source == nullptr) {
+    return nullptr;
+  }
+  auto provider = absl::make_unique<nghttp2_data_provider>();
+  provider->source.ptr = source;
+  provider->read_callback = &callbacks::DataFrameSourceReadCallback;
+  return provider;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_data_provider.h b/quiche/http2/adapter/nghttp2_data_provider.h
new file mode 100644
index 0000000..5973998
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_data_provider.h
@@ -0,0 +1,40 @@
+#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_DATA_PROVIDER_H_
+#define QUICHE_HTTP2_ADAPTER_NGHTTP2_DATA_PROVIDER_H_
+
+#include <cstdint>
+#include <memory>
+
+#include "quiche/http2/adapter/data_source.h"
+#include "quiche/http2/adapter/nghttp2.h"
+
+namespace http2 {
+namespace adapter {
+namespace callbacks {
+
+// Assumes |source| is a DataFrameSource.
+ssize_t DataFrameSourceReadCallback(nghttp2_session* /*session */,
+                                    int32_t /* stream_id */,
+                                    uint8_t* /* buf */,
+                                    size_t length,
+                                    uint32_t* data_flags,
+                                    nghttp2_data_source* source,
+                                    void* /* user_data */);
+
+int DataFrameSourceSendCallback(nghttp2_session* /* session */,
+                                nghttp2_frame* /* frame */,
+                                const uint8_t* framehd,
+                                size_t length,
+                                nghttp2_data_source* source,
+                                void* /* user_data */);
+
+}  // namespace callbacks
+
+// Transforms a DataFrameSource into a nghttp2_data_provider. Does not take
+// ownership of |source|. Returns nullptr if |source| is nullptr.
+std::unique_ptr<nghttp2_data_provider> MakeDataProvider(
+    DataFrameSource* source);
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_DATA_PROVIDER_H_
diff --git a/quiche/http2/adapter/nghttp2_data_provider_test.cc b/quiche/http2/adapter/nghttp2_data_provider_test.cc
new file mode 100644
index 0000000..3d90855
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_data_provider_test.cc
@@ -0,0 +1,117 @@
+#include "quiche/http2/adapter/nghttp2_data_provider.h"
+
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+const size_t kFrameHeaderSize = 9;
+
+// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
+// correctly with nghttp2-style callbacks when the amount of data read is less
+// than what the source provides.
+TEST(DataProviderTest, ReadLessThanSourceProvides) {
+  DataSavingVisitor visitor;
+  TestDataFrameSource source(visitor, true);
+  source.AppendPayload("Example payload");
+  source.EndData();
+  auto provider = MakeDataProvider(&source);
+  uint32_t data_flags = 0;
+  const int32_t kStreamId = 1;
+  const size_t kReadLength = 10;
+  // Read callback selects a payload length given an upper bound.
+  ssize_t result =
+      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
+                              &data_flags, &provider->source, nullptr);
+  ASSERT_EQ(kReadLength, result);
+  EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY, data_flags);
+
+  const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  // Sends the frame header and some payload bytes.
+  int send_result = callbacks::DataFrameSourceSendCallback(
+      nullptr, nullptr, framehd, result, &provider->source, nullptr);
+  EXPECT_EQ(0, send_result);
+  // Data accepted by the visitor includes a frame header and kReadLength bytes
+  // of payload.
+  EXPECT_EQ(visitor.data().size(), kFrameHeaderSize + kReadLength);
+}
+
+// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
+// correctly with nghttp2-style callbacks when the amount of data read is more
+// than what the source provides.
+TEST(DataProviderTest, ReadMoreThanSourceProvides) {
+  DataSavingVisitor visitor;
+  const absl::string_view kPayload = "Example payload";
+  TestDataFrameSource source(visitor, true);
+  source.AppendPayload(kPayload);
+  source.EndData();
+  auto provider = MakeDataProvider(&source);
+  uint32_t data_flags = 0;
+  const int32_t kStreamId = 1;
+  const size_t kReadLength = 30;
+  // Read callback selects a payload length given an upper bound.
+  ssize_t result =
+      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
+                              &data_flags, &provider->source, nullptr);
+  ASSERT_EQ(kPayload.size(), result);
+  EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
+
+  const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  // Sends the frame header and some payload bytes.
+  int send_result = callbacks::DataFrameSourceSendCallback(
+      nullptr, nullptr, framehd, result, &provider->source, nullptr);
+  EXPECT_EQ(0, send_result);
+  // Data accepted by the visitor includes a frame header and the entire
+  // payload.
+  EXPECT_EQ(visitor.data().size(), kFrameHeaderSize + kPayload.size());
+}
+
+// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
+// correctly with nghttp2-style callbacks when the source is blocked.
+TEST(DataProviderTest, ReadFromBlockedSource) {
+  DataSavingVisitor visitor;
+  // Source has no payload, but also no fin, so it's blocked.
+  TestDataFrameSource source(visitor, false);
+  auto provider = MakeDataProvider(&source);
+  uint32_t data_flags = 0;
+  const int32_t kStreamId = 1;
+  const size_t kReadLength = 10;
+  ssize_t result =
+      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
+                              &data_flags, &provider->source, nullptr);
+  // Read operation is deferred, since the source is blocked.
+  EXPECT_EQ(NGHTTP2_ERR_DEFERRED, result);
+}
+
+// Verifies that a nghttp2_data_provider derived from a DataFrameSource works
+// correctly with nghttp2-style callbacks when the source provides only fin and
+// no data.
+TEST(DataProviderTest, ReadFromZeroLengthSource) {
+  DataSavingVisitor visitor;
+  // Empty payload and fin=true indicates the source is done.
+  TestDataFrameSource source(visitor, true);
+  source.EndData();
+  auto provider = MakeDataProvider(&source);
+  uint32_t data_flags = 0;
+  const int32_t kStreamId = 1;
+  const size_t kReadLength = 10;
+  ssize_t result =
+      provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
+                              &data_flags, &provider->source, nullptr);
+  ASSERT_EQ(0, result);
+  EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
+
+  const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  int send_result = callbacks::DataFrameSourceSendCallback(
+      nullptr, nullptr, framehd, result, &provider->source, nullptr);
+  EXPECT_EQ(0, send_result);
+  // Data accepted by the visitor includes a frame header with fin and zero
+  // bytes of payload.
+  EXPECT_EQ(visitor.data().size(), kFrameHeaderSize);
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_session.cc b/quiche/http2/adapter/nghttp2_session.cc
new file mode 100644
index 0000000..f7f49fb
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_session.cc
@@ -0,0 +1,57 @@
+#include "quiche/http2/adapter/nghttp2_session.h"
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace http2 {
+namespace adapter {
+
+NgHttp2Session::NgHttp2Session(Perspective perspective,
+                               nghttp2_session_callbacks_unique_ptr callbacks,
+                               const nghttp2_option* options, void* userdata)
+    : session_(MakeSessionPtr(nullptr)), perspective_(perspective) {
+  nghttp2_session* session;
+  switch (perspective_) {
+    case Perspective::kClient:
+      nghttp2_session_client_new2(&session, callbacks.get(), userdata, options);
+      break;
+    case Perspective::kServer:
+      nghttp2_session_server_new2(&session, callbacks.get(), userdata, options);
+      break;
+  }
+  session_ = MakeSessionPtr(session);
+}
+
+NgHttp2Session::~NgHttp2Session() {
+  // Can't invoke want_read() or want_write(), as they are virtual methods.
+  const bool pending_reads = nghttp2_session_want_read(session_.get()) != 0;
+  const bool pending_writes = nghttp2_session_want_write(session_.get()) != 0;
+  if (pending_reads || pending_writes) {
+    QUICHE_VLOG(1) << "Shutting down connection with pending reads: "
+                   << pending_reads << " or pending writes: " << pending_writes;
+  }
+}
+
+int64_t NgHttp2Session::ProcessBytes(absl::string_view bytes) {
+  return nghttp2_session_mem_recv(
+      session_.get(), reinterpret_cast<const uint8_t*>(bytes.data()),
+      bytes.size());
+}
+
+int NgHttp2Session::Consume(Http2StreamId stream_id, size_t num_bytes) {
+  return nghttp2_session_consume(session_.get(), stream_id, num_bytes);
+}
+
+bool NgHttp2Session::want_read() const {
+  return nghttp2_session_want_read(session_.get()) != 0;
+}
+
+bool NgHttp2Session::want_write() const {
+  return nghttp2_session_want_write(session_.get()) != 0;
+}
+
+int NgHttp2Session::GetRemoteWindowSize() const {
+  return nghttp2_session_get_remote_window_size(session_.get());
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_session.h b/quiche/http2/adapter/nghttp2_session.h
new file mode 100644
index 0000000..5837f2f
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_session.h
@@ -0,0 +1,41 @@
+#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_SESSION_H_
+#define QUICHE_HTTP2_ADAPTER_NGHTTP2_SESSION_H_
+
+#include <cstdint>
+
+#include "quiche/http2/adapter/http2_session.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+// A C++ wrapper around common nghttp2_session operations.
+class QUICHE_EXPORT_PRIVATE NgHttp2Session : public Http2Session {
+ public:
+  // Does not take ownership of |options|.
+  NgHttp2Session(Perspective perspective,
+                 nghttp2_session_callbacks_unique_ptr callbacks,
+                 const nghttp2_option* options, void* userdata);
+  ~NgHttp2Session() override;
+
+  int64_t ProcessBytes(absl::string_view bytes) override;
+
+  int Consume(Http2StreamId stream_id, size_t num_bytes) override;
+
+  bool want_read() const override;
+  bool want_write() const override;
+  int GetRemoteWindowSize() const override;
+
+  nghttp2_session* raw_ptr() const { return session_.get(); }
+
+ private:
+  nghttp2_session_unique_ptr session_;
+  Perspective perspective_;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_SESSION_H_
diff --git a/quiche/http2/adapter/nghttp2_session_test.cc b/quiche/http2/adapter/nghttp2_session_test.cc
new file mode 100644
index 0000000..8f0663d
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_session_test.cc
@@ -0,0 +1,322 @@
+#include "quiche/http2/adapter/nghttp2_session.h"
+
+#include "quiche/http2/adapter/mock_http2_visitor.h"
+#include "quiche/http2/adapter/nghttp2_callbacks.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using testing::_;
+
+enum FrameType {
+  DATA,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+};
+
+class NgHttp2SessionTest : public testing::Test {
+ public:
+  void SetUp() override {
+    nghttp2_option_new(&options_);
+    nghttp2_option_set_no_auto_window_update(options_, 1);
+  }
+
+  void TearDown() override { nghttp2_option_del(options_); }
+
+  nghttp2_session_callbacks_unique_ptr CreateCallbacks() {
+    nghttp2_session_callbacks_unique_ptr callbacks = callbacks::Create();
+    return callbacks;
+  }
+
+  DataSavingVisitor visitor_;
+  nghttp2_option* options_ = nullptr;
+};
+
+TEST_F(NgHttp2SessionTest, ClientConstruction) {
+  NgHttp2Session session(Perspective::kClient, CreateCallbacks(), options_,
+                         &visitor_);
+  EXPECT_TRUE(session.want_read());
+  EXPECT_FALSE(session.want_write());
+  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
+  EXPECT_NE(session.raw_ptr(), nullptr);
+}
+
+TEST_F(NgHttp2SessionTest, ClientHandlesFrames) {
+  NgHttp2Session session(Perspective::kClient, CreateCallbacks(), options_,
+                         &visitor_);
+
+  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
+  ASSERT_GT(visitor_.data().size(), 0);
+
+  const std::string initial_frames = TestFrameSequence()
+                                         .ServerPreface()
+                                         .Ping(42)
+                                         .WindowUpdate(0, 1000)
+                                         .Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor_, OnSettingsStart());
+  EXPECT_CALL(visitor_, OnSettingsEnd());
+
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor_, OnPing(42, false));
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor_, OnWindowUpdate(0, 1000));
+
+  const int64_t initial_result = session.ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), initial_result);
+
+  EXPECT_EQ(session.GetRemoteWindowSize(),
+            kInitialFlowControlWindowSize + 1000);
+
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor_, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(PING, 0, 8, 0x1));
+  EXPECT_CALL(visitor_, OnFrameSent(PING, 0, 8, 0x1, 0));
+
+  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
+  // Some bytes should have been serialized.
+  absl::string_view serialized = visitor_.data();
+  ASSERT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({spdy::SpdyFrameType::SETTINGS,
+                                        spdy::SpdyFrameType::PING}));
+  visitor_.Clear();
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const auto nvs1 = GetNghttp2Nvs(headers1);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+  const auto nvs2 = GetNghttp2Nvs(headers2);
+
+  const std::vector<Header> headers3 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/three"}});
+  const auto nvs3 = GetNghttp2Nvs(headers3);
+
+  const int32_t stream_id1 = nghttp2_submit_request(
+      session.raw_ptr(), nullptr, nvs1.data(), nvs1.size(), nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  const int32_t stream_id2 = nghttp2_submit_request(
+      session.raw_ptr(), nullptr, nvs2.data(), nvs2.size(), nullptr, nullptr);
+  ASSERT_GT(stream_id2, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id2;
+
+  const int32_t stream_id3 = nghttp2_submit_request(
+      session.raw_ptr(), nullptr, nvs3.data(), nvs3.size(), nullptr, nullptr);
+  ASSERT_GT(stream_id3, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id3;
+
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor_, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(HEADERS, 3, _, 0x5));
+  EXPECT_CALL(visitor_, OnFrameSent(HEADERS, 3, _, 0x5, 0));
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(HEADERS, 5, _, 0x5));
+  EXPECT_CALL(visitor_, OnFrameSent(HEADERS, 5, _, 0x5, 0));
+
+  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
+  serialized = visitor_.data();
+  EXPECT_THAT(serialized, EqualsFrames({spdy::SpdyFrameType::HEADERS,
+                                        spdy::SpdyFrameType::HEADERS,
+                                        spdy::SpdyFrameType::HEADERS}));
+  visitor_.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
+          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
+          .Serialize();
+
+  EXPECT_CALL(visitor_, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor_, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor_,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor_, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor_, OnFrameHeader(1, 26, DATA, 0));
+  EXPECT_CALL(visitor_, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor_, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor_, OnFrameHeader(3, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor_, OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR));
+  EXPECT_CALL(visitor_, OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR));
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 19, GOAWAY, 0));
+  EXPECT_CALL(visitor_,
+              OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!"));
+  const int64_t stream_result = session.ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), stream_result);
+
+  // Even though the client recieved a GOAWAY, streams 1 and 5 are still active.
+  EXPECT_TRUE(session.want_read());
+
+  EXPECT_CALL(visitor_, OnFrameHeader(1, 0, DATA, 1));
+  EXPECT_CALL(visitor_, OnBeginDataForStream(1, 0));
+  EXPECT_CALL(visitor_, OnEndStream(1));
+  EXPECT_CALL(visitor_, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor_, OnFrameHeader(5, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor_, OnRstStream(5, Http2ErrorCode::REFUSED_STREAM));
+  EXPECT_CALL(visitor_, OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM));
+  session.ProcessBytes(TestFrameSequence()
+                           .Data(1, "", true)
+                           .RstStream(5, Http2ErrorCode::REFUSED_STREAM)
+                           .Serialize());
+  // After receiving END_STREAM for 1 and RST_STREAM for 5, the session no
+  // longer expects reads.
+  EXPECT_FALSE(session.want_read());
+
+  // Client will not have anything else to write.
+  EXPECT_FALSE(session.want_write());
+  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
+  serialized = visitor_.data();
+  EXPECT_EQ(serialized.size(), 0);
+}
+
+TEST_F(NgHttp2SessionTest, ServerConstruction) {
+  NgHttp2Session session(Perspective::kServer, CreateCallbacks(), options_,
+                         &visitor_);
+  EXPECT_TRUE(session.want_read());
+  EXPECT_FALSE(session.want_write());
+  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
+  EXPECT_NE(session.raw_ptr(), nullptr);
+}
+
+TEST_F(NgHttp2SessionTest, ServerHandlesFrames) {
+  NgHttp2Session session(Perspective::kServer, CreateCallbacks(), options_,
+                         &visitor_);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Ping(42)
+                                 .WindowUpdate(0, 1000)
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor_, OnSettingsStart());
+  EXPECT_CALL(visitor_, OnSettingsEnd());
+
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor_, OnPing(42, false));
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor_, OnWindowUpdate(0, 1000));
+  EXPECT_CALL(visitor_, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor_, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor_, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor_, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor_, OnWindowUpdate(1, 2000));
+  EXPECT_CALL(visitor_, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor_, OnBeginDataForStream(1, 25));
+  EXPECT_CALL(visitor_, OnDataForStream(1, "This is the request body."));
+  EXPECT_CALL(visitor_, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor_, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":method", "GET"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":scheme", "http"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":authority", "example.com"));
+  EXPECT_CALL(visitor_, OnHeaderForStream(3, ":path", "/this/is/request/two"));
+  EXPECT_CALL(visitor_, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor_, OnEndStream(3));
+  EXPECT_CALL(visitor_, OnFrameHeader(3, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor_, OnRstStream(3, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor_, OnCloseStream(3, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor_, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor_, OnPing(47, false));
+
+  const int64_t result = session.ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), result);
+
+  EXPECT_EQ(session.GetRemoteWindowSize(),
+            kInitialFlowControlWindowSize + 1000);
+
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor_, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(PING, 0, 8, 0x1));
+  EXPECT_CALL(visitor_, OnFrameSent(PING, 0, 8, 0x1, 0));
+  EXPECT_CALL(visitor_, OnBeforeFrameSent(PING, 0, 8, 0x1));
+  EXPECT_CALL(visitor_, OnFrameSent(PING, 0, 8, 0x1, 0));
+
+  EXPECT_TRUE(session.want_write());
+  ASSERT_EQ(0, nghttp2_session_send(session.raw_ptr()));
+  // Some bytes should have been serialized.
+  absl::string_view serialized = visitor_.data();
+  // SETTINGS ack, two PING acks.
+  EXPECT_THAT(serialized, EqualsFrames({spdy::SpdyFrameType::SETTINGS,
+                                        spdy::SpdyFrameType::PING,
+                                        spdy::SpdyFrameType::PING}));
+}
+
+// Verifies that a null payload is caught by the OnPackExtensionCallback
+// implementation.
+TEST_F(NgHttp2SessionTest, NullPayload) {
+  NgHttp2Session session(Perspective::kClient, CreateCallbacks(), options_,
+                         &visitor_);
+
+  void* payload = nullptr;
+  const int result = nghttp2_submit_extension(
+      session.raw_ptr(), kMetadataFrameType, 0, 1, payload);
+  ASSERT_EQ(0, result);
+  EXPECT_TRUE(session.want_write());
+  int send_result = -1;
+  EXPECT_QUICHE_BUG(send_result = nghttp2_session_send(session.raw_ptr()),
+                    "Extension frame payload for stream 1 is null!");
+  EXPECT_EQ(NGHTTP2_ERR_CALLBACK_FAILURE, send_result);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_test.cc b/quiche/http2/adapter/nghttp2_test.cc
new file mode 100644
index 0000000..e4f5db5
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_test.cc
@@ -0,0 +1,205 @@
+#include "quiche/http2/adapter/nghttp2.h"
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/adapter/mock_nghttp2_callbacks.h"
+#include "quiche/http2/adapter/nghttp2_test_utils.h"
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using testing::_;
+
+enum FrameType {
+  DATA,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+};
+
+nghttp2_option* GetOptions() {
+  nghttp2_option* options;
+  nghttp2_option_new(&options);
+  // Set some common options for compatibility.
+  nghttp2_option_set_no_closed_streams(options, 1);
+  nghttp2_option_set_no_auto_window_update(options, 1);
+  nghttp2_option_set_max_send_header_block_length(options, 0x2000000);
+  nghttp2_option_set_max_outbound_ack(options, 10000);
+  return options;
+}
+
+class Nghttp2Test : public testing::Test {
+ public:
+  Nghttp2Test() : session_(MakeSessionPtr(nullptr)) {}
+
+  void SetUp() override { InitializeSession(); }
+
+  virtual Perspective GetPerspective() = 0;
+
+  void InitializeSession() {
+    auto nghttp2_callbacks = MockNghttp2Callbacks::GetCallbacks();
+    nghttp2_option* options = GetOptions();
+    nghttp2_session* ptr;
+    if (GetPerspective() == Perspective::kClient) {
+      nghttp2_session_client_new2(&ptr, nghttp2_callbacks.get(),
+                                  &mock_callbacks_, options);
+    } else {
+      nghttp2_session_server_new2(&ptr, nghttp2_callbacks.get(),
+                                  &mock_callbacks_, options);
+    }
+    nghttp2_option_del(options);
+
+    // Sets up the Send() callback to append to |serialized_|.
+    EXPECT_CALL(mock_callbacks_, Send(_, _, _))
+        .WillRepeatedly(
+            [this](const uint8_t* data, size_t length, int /*flags*/) {
+              absl::StrAppend(&serialized_, ToStringView(data, length));
+              return length;
+            });
+    // Sets up the SendData() callback to fetch and append data from a
+    // TestDataSource.
+    EXPECT_CALL(mock_callbacks_, SendData(_, _, _, _))
+        .WillRepeatedly([this](nghttp2_frame* /*frame*/, const uint8_t* framehd,
+                               size_t length, nghttp2_data_source* source) {
+          QUICHE_LOG(INFO) << "Appending frame header and " << length
+                           << " bytes of data";
+          auto* s = static_cast<TestDataSource*>(source->ptr);
+          absl::StrAppend(&serialized_, ToStringView(framehd, 9),
+                          s->ReadNext(length));
+          return 0;
+        });
+    session_ = MakeSessionPtr(ptr);
+  }
+
+  testing::StrictMock<MockNghttp2Callbacks> mock_callbacks_;
+  nghttp2_session_unique_ptr session_;
+  std::string serialized_;
+};
+
+class Nghttp2ClientTest : public Nghttp2Test {
+ public:
+  Perspective GetPerspective() override { return Perspective::kClient; }
+};
+
+// Verifies nghttp2 behavior when acting as a client.
+TEST_F(Nghttp2ClientTest, ClientReceivesUnexpectedHeaders) {
+  const std::string initial_frames = TestFrameSequence()
+                                         .ServerPreface()
+                                         .Ping(42)
+                                         .WindowUpdate(0, 1000)
+                                         .Serialize();
+
+  testing::InSequence seq;
+  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(0, SETTINGS, 0)));
+  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsSettings(testing::IsEmpty())));
+  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(0, PING, 0)));
+  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsPing(42)));
+  EXPECT_CALL(mock_callbacks_,
+              OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, 0)));
+  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsWindowUpdate(1000)));
+
+  ssize_t result = nghttp2_session_mem_recv(
+      session_.get(), ToUint8Ptr(initial_frames.data()), initial_frames.size());
+  ASSERT_EQ(result, initial_frames.size());
+
+  const std::string unexpected_stream_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
+          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
+          .Serialize();
+
+  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
+  EXPECT_CALL(mock_callbacks_, OnInvalidFrameRecv(IsHeaders(1, _, _), _));
+  // No events from the DATA, RST_STREAM or GOAWAY.
+
+  nghttp2_session_mem_recv(session_.get(),
+                           ToUint8Ptr(unexpected_stream_frames.data()),
+                           unexpected_stream_frames.size());
+}
+
+// Tests the request-sending behavior of nghttp2 when acting as a client.
+TEST_F(Nghttp2ClientTest, ClientSendsRequest) {
+  int result = nghttp2_session_send(session_.get());
+  ASSERT_EQ(result, 0);
+
+  EXPECT_THAT(serialized_, testing::StrEq(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized_.clear();
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(mock_callbacks_, OnBeginFrame(HasFrameHeader(0, SETTINGS, 0)));
+  EXPECT_CALL(mock_callbacks_, OnFrameRecv(IsSettings(testing::IsEmpty())));
+
+  ssize_t recv_result = nghttp2_session_mem_recv(
+      session_.get(), ToUint8Ptr(initial_frames.data()), initial_frames.size());
+  EXPECT_EQ(initial_frames.size(), recv_result);
+
+  // Client wants to send a SETTINGS ack.
+  EXPECT_CALL(mock_callbacks_, BeforeFrameSend(IsSettings(testing::IsEmpty())));
+  EXPECT_CALL(mock_callbacks_, OnFrameSend(IsSettings(testing::IsEmpty())));
+  EXPECT_TRUE(nghttp2_session_want_write(session_.get()));
+  result = nghttp2_session_send(session_.get());
+  EXPECT_THAT(serialized_, EqualsFrames({spdy::SpdyFrameType::SETTINGS}));
+  serialized_.clear();
+
+  EXPECT_FALSE(nghttp2_session_want_write(session_.get()));
+
+  // The following sets up the client request.
+  std::vector<std::pair<absl::string_view, absl::string_view>> headers = {
+      {":method", "POST"},
+      {":scheme", "http"},
+      {":authority", "example.com"},
+      {":path", "/this/is/request/one"}};
+  std::vector<nghttp2_nv> nvs;
+  for (const auto& h : headers) {
+    nvs.push_back({.name = ToUint8Ptr(h.first.data()),
+                   .value = ToUint8Ptr(h.second.data()),
+                   .namelen = h.first.size(),
+                   .valuelen = h.second.size()});
+  }
+  const absl::string_view kBody = "This is an example request body.";
+  TestDataSource source{kBody};
+  nghttp2_data_provider provider = source.MakeDataProvider();
+  // After submitting the request, the client will want to write.
+  int stream_id =
+      nghttp2_submit_request(session_.get(), nullptr /* pri_spec */, nvs.data(),
+                             nvs.size(), &provider, nullptr /* stream_data */);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(nghttp2_session_want_write(session_.get()));
+
+  // We expect that the client will want to write HEADERS, then DATA.
+  EXPECT_CALL(mock_callbacks_, BeforeFrameSend(IsHeaders(stream_id, _, _)));
+  EXPECT_CALL(mock_callbacks_, OnFrameSend(IsHeaders(stream_id, _, _)));
+  EXPECT_CALL(mock_callbacks_, OnFrameSend(IsData(stream_id, kBody.size(), _)));
+  nghttp2_session_send(session_.get());
+  EXPECT_THAT(serialized_, EqualsFrames({spdy::SpdyFrameType::HEADERS,
+                                         spdy::SpdyFrameType::DATA}));
+  EXPECT_THAT(serialized_, testing::HasSubstr(kBody));
+
+  // Once the request is flushed, the client no longer wants to write.
+  EXPECT_FALSE(nghttp2_session_want_write(session_.get()));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_test_utils.cc b/quiche/http2/adapter/nghttp2_test_utils.cc
new file mode 100644
index 0000000..0de00d8
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_test_utils.cc
@@ -0,0 +1,463 @@
+#include "quiche/http2/adapter/nghttp2_test_utils.h"
+
+#include "quiche/http2/adapter/nghttp2_util.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+namespace {
+
+// Custom gMock matcher, used to implement HasFrameHeader().
+class FrameHeaderMatcher {
+ public:
+  FrameHeaderMatcher(int32_t streamid, uint8_t type,
+                     const testing::Matcher<int> flags)
+      : stream_id_(streamid), type_(type), flags_(flags) {}
+
+  bool Match(const nghttp2_frame_hd& frame,
+             testing::MatchResultListener* listener) const {
+    bool matched = true;
+    if (stream_id_ != frame.stream_id) {
+      *listener << "; expected stream " << stream_id_ << ", saw "
+                << frame.stream_id;
+      matched = false;
+    }
+    if (type_ != frame.type) {
+      *listener << "; expected frame type " << type_ << ", saw "
+                << static_cast<int>(frame.type);
+      matched = false;
+    }
+    if (!flags_.MatchAndExplain(frame.flags, listener)) {
+      matched = false;
+    }
+    return matched;
+  }
+
+  void DescribeTo(std::ostream* os) const {
+    *os << "contains a frame header with stream " << stream_id_ << ", type "
+        << type_ << ", ";
+    flags_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const {
+    *os << "does not contain a frame header with stream " << stream_id_
+        << ", type " << type_ << ", ";
+    flags_.DescribeNegationTo(os);
+  }
+
+ private:
+  const int32_t stream_id_;
+  const int type_;
+  const testing::Matcher<int> flags_;
+};
+
+class PointerToFrameHeaderMatcher
+    : public FrameHeaderMatcher,
+      public testing::MatcherInterface<const nghttp2_frame_hd*> {
+ public:
+  PointerToFrameHeaderMatcher(int32_t streamid, uint8_t type,
+                              const testing::Matcher<int> flags)
+      : FrameHeaderMatcher(streamid, type, flags) {}
+
+  bool MatchAndExplain(const nghttp2_frame_hd* frame,
+                       testing::MatchResultListener* listener) const override {
+    return FrameHeaderMatcher::Match(*frame, listener);
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    FrameHeaderMatcher::DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    FrameHeaderMatcher::DescribeNegationTo(os);
+  }
+};
+
+class ReferenceToFrameHeaderMatcher
+    : public FrameHeaderMatcher,
+      public testing::MatcherInterface<const nghttp2_frame_hd&> {
+ public:
+  ReferenceToFrameHeaderMatcher(int32_t streamid, uint8_t type,
+                                const testing::Matcher<int> flags)
+      : FrameHeaderMatcher(streamid, type, flags) {}
+
+  bool MatchAndExplain(const nghttp2_frame_hd& frame,
+                       testing::MatchResultListener* listener) const override {
+    return FrameHeaderMatcher::Match(frame, listener);
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    FrameHeaderMatcher::DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    FrameHeaderMatcher::DescribeNegationTo(os);
+  }
+};
+
+class DataMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  DataMatcher(const testing::Matcher<uint32_t> stream_id,
+              const testing::Matcher<size_t> length,
+              const testing::Matcher<int> flags,
+              const testing::Matcher<size_t> padding)
+      : stream_id_(stream_id),
+        length_(length),
+        flags_(flags),
+        padding_(padding) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_DATA) {
+      *listener << "; expected DATA frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    bool matched = true;
+    if (!stream_id_.MatchAndExplain(frame->hd.stream_id, listener)) {
+      matched = false;
+    }
+    if (!length_.MatchAndExplain(frame->hd.length, listener)) {
+      matched = false;
+    }
+    if (!flags_.MatchAndExplain(frame->hd.flags, listener)) {
+      matched = false;
+    }
+    if (!padding_.MatchAndExplain(frame->data.padlen, listener)) {
+      matched = false;
+    }
+    return matched;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a DATA frame, ";
+    stream_id_.DescribeTo(os);
+    length_.DescribeTo(os);
+    flags_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a DATA frame, ";
+    stream_id_.DescribeNegationTo(os);
+    length_.DescribeNegationTo(os);
+    flags_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<uint32_t> stream_id_;
+  const testing::Matcher<size_t> length_;
+  const testing::Matcher<int> flags_;
+  const testing::Matcher<size_t> padding_;
+};
+
+class HeadersMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  HeadersMatcher(const testing::Matcher<uint32_t> stream_id,
+                 const testing::Matcher<int> flags,
+                 const testing::Matcher<int> category)
+      : stream_id_(stream_id), flags_(flags), category_(category) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_HEADERS) {
+      *listener << "; expected HEADERS frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    bool matched = true;
+    if (!stream_id_.MatchAndExplain(frame->hd.stream_id, listener)) {
+      matched = false;
+    }
+    if (!flags_.MatchAndExplain(frame->hd.flags, listener)) {
+      matched = false;
+    }
+    if (!category_.MatchAndExplain(frame->headers.cat, listener)) {
+      matched = false;
+    }
+    return matched;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a HEADERS frame, ";
+    stream_id_.DescribeTo(os);
+    flags_.DescribeTo(os);
+    category_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a HEADERS frame, ";
+    stream_id_.DescribeNegationTo(os);
+    flags_.DescribeNegationTo(os);
+    category_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<uint32_t> stream_id_;
+  const testing::Matcher<int> flags_;
+  const testing::Matcher<int> category_;
+};
+
+class RstStreamMatcher
+    : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  RstStreamMatcher(const testing::Matcher<uint32_t> stream_id,
+                   const testing::Matcher<uint32_t> error_code)
+      : stream_id_(stream_id), error_code_(error_code) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_RST_STREAM) {
+      *listener << "; expected RST_STREAM frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    bool matched = true;
+    if (!stream_id_.MatchAndExplain(frame->hd.stream_id, listener)) {
+      matched = false;
+    }
+    if (!error_code_.MatchAndExplain(frame->rst_stream.error_code, listener)) {
+      matched = false;
+    }
+    return matched;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a RST_STREAM frame, ";
+    stream_id_.DescribeTo(os);
+    error_code_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a RST_STREAM frame, ";
+    stream_id_.DescribeNegationTo(os);
+    error_code_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<uint32_t> stream_id_;
+  const testing::Matcher<uint32_t> error_code_;
+};
+
+class SettingsMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  SettingsMatcher(const testing::Matcher<std::vector<Http2Setting>> values)
+      : values_(values) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_SETTINGS) {
+      *listener << "; expected SETTINGS frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    std::vector<Http2Setting> settings;
+    settings.reserve(frame->settings.niv);
+    for (size_t i = 0; i < frame->settings.niv; ++i) {
+      const auto& p = frame->settings.iv[i];
+      settings.push_back({static_cast<uint16_t>(p.settings_id), p.value});
+    }
+    return values_.MatchAndExplain(settings, listener);
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a SETTINGS frame, ";
+    values_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a SETTINGS frame, ";
+    values_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<std::vector<Http2Setting>> values_;
+};
+
+class PingMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  PingMatcher(const testing::Matcher<uint64_t> id, bool is_ack)
+      : id_(id), is_ack_(is_ack) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_PING) {
+      *listener << "; expected PING frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    bool matched = true;
+    bool frame_ack = frame->hd.flags & NGHTTP2_FLAG_ACK;
+    if (is_ack_ != frame_ack) {
+      *listener << "; expected is_ack=" << is_ack_ << ", saw " << frame_ack;
+      matched = false;
+    }
+    uint64_t data;
+    std::memcpy(&data, frame->ping.opaque_data, sizeof(data));
+    data = quiche::QuicheEndian::HostToNet64(data);
+    if (!id_.MatchAndExplain(data, listener)) {
+      matched = false;
+    }
+    return matched;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a PING frame, ";
+    id_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a PING frame, ";
+    id_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<uint64_t> id_;
+  const bool is_ack_;
+};
+
+class GoAwayMatcher : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  GoAwayMatcher(const testing::Matcher<uint32_t> last_stream_id,
+                const testing::Matcher<uint32_t> error_code,
+                const testing::Matcher<absl::string_view> opaque_data)
+      : last_stream_id_(last_stream_id),
+        error_code_(error_code),
+        opaque_data_(opaque_data) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_GOAWAY) {
+      *listener << "; expected GOAWAY frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    bool matched = true;
+    if (!last_stream_id_.MatchAndExplain(frame->goaway.last_stream_id,
+                                         listener)) {
+      matched = false;
+    }
+    if (!error_code_.MatchAndExplain(frame->goaway.error_code, listener)) {
+      matched = false;
+    }
+    auto opaque_data =
+        ToStringView(frame->goaway.opaque_data, frame->goaway.opaque_data_len);
+    if (!opaque_data_.MatchAndExplain(opaque_data, listener)) {
+      matched = false;
+    }
+    return matched;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a GOAWAY frame, ";
+    last_stream_id_.DescribeTo(os);
+    error_code_.DescribeTo(os);
+    opaque_data_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a GOAWAY frame, ";
+    last_stream_id_.DescribeNegationTo(os);
+    error_code_.DescribeNegationTo(os);
+    opaque_data_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<uint32_t> last_stream_id_;
+  const testing::Matcher<uint32_t> error_code_;
+  const testing::Matcher<absl::string_view> opaque_data_;
+};
+
+class WindowUpdateMatcher
+    : public testing::MatcherInterface<const nghttp2_frame*> {
+ public:
+  WindowUpdateMatcher(const testing::Matcher<uint32_t> delta) : delta_(delta) {}
+
+  bool MatchAndExplain(const nghttp2_frame* frame,
+                       testing::MatchResultListener* listener) const override {
+    if (frame->hd.type != NGHTTP2_WINDOW_UPDATE) {
+      *listener << "; expected WINDOW_UPDATE frame, saw frame of type "
+                << static_cast<int>(frame->hd.type);
+      return false;
+    }
+    return delta_.MatchAndExplain(frame->window_update.window_size_increment,
+                                  listener);
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "contains a WINDOW_UPDATE frame, ";
+    delta_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "does not contain a WINDOW_UPDATE frame, ";
+    delta_.DescribeNegationTo(os);
+  }
+
+ private:
+  const testing::Matcher<uint32_t> delta_;
+};
+
+}  // namespace
+
+testing::Matcher<const nghttp2_frame_hd*> HasFrameHeader(
+    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags) {
+  return MakeMatcher(new PointerToFrameHeaderMatcher(streamid, type, flags));
+}
+
+testing::Matcher<const nghttp2_frame_hd&> HasFrameHeaderRef(
+    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags) {
+  return MakeMatcher(new ReferenceToFrameHeaderMatcher(streamid, type, flags));
+}
+
+testing::Matcher<const nghttp2_frame*> IsData(
+    const testing::Matcher<uint32_t> stream_id,
+    const testing::Matcher<size_t> length, const testing::Matcher<int> flags,
+    const testing::Matcher<size_t> padding) {
+  return MakeMatcher(new DataMatcher(stream_id, length, flags, padding));
+}
+
+testing::Matcher<const nghttp2_frame*> IsHeaders(
+    const testing::Matcher<uint32_t> stream_id,
+    const testing::Matcher<int> flags, const testing::Matcher<int> category) {
+  return MakeMatcher(new HeadersMatcher(stream_id, flags, category));
+}
+
+testing::Matcher<const nghttp2_frame*> IsRstStream(
+    const testing::Matcher<uint32_t> stream_id,
+    const testing::Matcher<uint32_t> error_code) {
+  return MakeMatcher(new RstStreamMatcher(stream_id, error_code));
+}
+
+testing::Matcher<const nghttp2_frame*> IsSettings(
+    const testing::Matcher<std::vector<Http2Setting>> values) {
+  return MakeMatcher(new SettingsMatcher(values));
+}
+
+testing::Matcher<const nghttp2_frame*> IsPing(
+    const testing::Matcher<uint64_t> id) {
+  return MakeMatcher(new PingMatcher(id, false));
+}
+
+testing::Matcher<const nghttp2_frame*> IsPingAck(
+    const testing::Matcher<uint64_t> id) {
+  return MakeMatcher(new PingMatcher(id, true));
+}
+
+testing::Matcher<const nghttp2_frame*> IsGoAway(
+    const testing::Matcher<uint32_t> last_stream_id,
+    const testing::Matcher<uint32_t> error_code,
+    const testing::Matcher<absl::string_view> opaque_data) {
+  return MakeMatcher(
+      new GoAwayMatcher(last_stream_id, error_code, opaque_data));
+}
+
+testing::Matcher<const nghttp2_frame*> IsWindowUpdate(
+    const testing::Matcher<uint32_t> delta) {
+  return MakeMatcher(new WindowUpdateMatcher(delta));
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_test_utils.h b/quiche/http2/adapter/nghttp2_test_utils.h
new file mode 100644
index 0000000..00a2f4c
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_test_utils.h
@@ -0,0 +1,101 @@
+#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
+#define QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+// A simple class that can easily be adapted to act as a nghttp2_data_source.
+class QUICHE_NO_EXPORT TestDataSource {
+ public:
+  explicit TestDataSource(absl::string_view data) : data_(std::string(data)) {}
+
+  absl::string_view ReadNext(size_t size) {
+    const size_t to_send = std::min(size, remaining_.size());
+    auto ret = remaining_.substr(0, to_send);
+    remaining_.remove_prefix(to_send);
+    return ret;
+  }
+
+  size_t SelectPayloadLength(size_t max_length) {
+    return std::min(max_length, remaining_.size());
+  }
+
+  nghttp2_data_provider MakeDataProvider() {
+    return nghttp2_data_provider{
+        .source = {.ptr = this},
+        .read_callback = [](nghttp2_session*, int32_t, uint8_t*, size_t length,
+                            uint32_t* data_flags, nghttp2_data_source* source,
+                            void*) -> ssize_t {
+          *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
+          auto* s = static_cast<TestDataSource*>(source->ptr);
+          if (!s->is_data_available()) {
+            return NGHTTP2_ERR_DEFERRED;
+          }
+          const ssize_t ret = s->SelectPayloadLength(length);
+          if (ret < static_cast<ssize_t>(length)) {
+            *data_flags |= NGHTTP2_DATA_FLAG_EOF;
+          }
+          return ret;
+        }};
+  }
+
+  bool is_data_available() const { return is_data_available_; }
+  void set_is_data_available(bool value) { is_data_available_ = value; }
+
+ private:
+  const std::string data_;
+  absl::string_view remaining_ = data_;
+  bool is_data_available_ = true;
+};
+
+// Matchers for nghttp2 data types.
+testing::Matcher<const nghttp2_frame_hd*> HasFrameHeader(
+    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags);
+testing::Matcher<const nghttp2_frame_hd&> HasFrameHeaderRef(
+    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags);
+
+testing::Matcher<const nghttp2_frame*> IsData(
+    const testing::Matcher<uint32_t> stream_id,
+    const testing::Matcher<size_t> length, const testing::Matcher<int> flags,
+    const testing::Matcher<size_t> padding = testing::_);
+
+testing::Matcher<const nghttp2_frame*> IsHeaders(
+    const testing::Matcher<uint32_t> stream_id,
+    const testing::Matcher<int> flags, const testing::Matcher<int> category);
+
+testing::Matcher<const nghttp2_frame*> IsRstStream(
+    const testing::Matcher<uint32_t> stream_id,
+    const testing::Matcher<uint32_t> error_code);
+
+testing::Matcher<const nghttp2_frame*> IsSettings(
+    const testing::Matcher<std::vector<Http2Setting>> values);
+
+testing::Matcher<const nghttp2_frame*> IsPing(
+    const testing::Matcher<uint64_t> id);
+
+testing::Matcher<const nghttp2_frame*> IsPingAck(
+    const testing::Matcher<uint64_t> id);
+
+testing::Matcher<const nghttp2_frame*> IsGoAway(
+    const testing::Matcher<uint32_t> last_stream_id,
+    const testing::Matcher<uint32_t> error_code,
+    const testing::Matcher<absl::string_view> opaque_data);
+
+testing::Matcher<const nghttp2_frame*> IsWindowUpdate(
+    const testing::Matcher<uint32_t> delta);
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
diff --git a/quiche/http2/adapter/nghttp2_util.cc b/quiche/http2/adapter/nghttp2_util.cc
new file mode 100644
index 0000000..faf5dd5
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_util.cc
@@ -0,0 +1,305 @@
+#include "quiche/http2/adapter/nghttp2_util.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace http2 {
+namespace adapter {
+
+namespace {
+
+using InvalidFrameError = Http2VisitorInterface::InvalidFrameError;
+
+void DeleteCallbacks(nghttp2_session_callbacks* callbacks) {
+  if (callbacks) {
+    nghttp2_session_callbacks_del(callbacks);
+  }
+}
+
+void DeleteSession(nghttp2_session* session) {
+  if (session) {
+    nghttp2_session_del(session);
+  }
+}
+
+}  // namespace
+
+nghttp2_session_callbacks_unique_ptr MakeCallbacksPtr(
+    nghttp2_session_callbacks* callbacks) {
+  return nghttp2_session_callbacks_unique_ptr(callbacks, &DeleteCallbacks);
+}
+
+nghttp2_session_unique_ptr MakeSessionPtr(nghttp2_session* session) {
+  return nghttp2_session_unique_ptr(session, &DeleteSession);
+}
+
+uint8_t* ToUint8Ptr(char* str) { return reinterpret_cast<uint8_t*>(str); }
+uint8_t* ToUint8Ptr(const char* str) {
+  return const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(str));
+}
+
+absl::string_view ToStringView(nghttp2_rcbuf* rc_buffer) {
+  nghttp2_vec buffer = nghttp2_rcbuf_get_buf(rc_buffer);
+  return absl::string_view(reinterpret_cast<const char*>(buffer.base),
+                           buffer.len);
+}
+
+absl::string_view ToStringView(uint8_t* pointer, size_t length) {
+  return absl::string_view(reinterpret_cast<const char*>(pointer), length);
+}
+
+absl::string_view ToStringView(const uint8_t* pointer, size_t length) {
+  return absl::string_view(reinterpret_cast<const char*>(pointer), length);
+}
+
+std::vector<nghttp2_nv> GetNghttp2Nvs(absl::Span<const Header> headers) {
+  const int num_headers = headers.size();
+  std::vector<nghttp2_nv> nghttp2_nvs;
+  nghttp2_nvs.reserve(num_headers);
+  for (int i = 0; i < num_headers; ++i) {
+    nghttp2_nv header;
+    uint8_t flags = NGHTTP2_NV_FLAG_NONE;
+
+    const auto [name, no_copy_name] = GetStringView(headers[i].first);
+    header.name = ToUint8Ptr(name.data());
+    header.namelen = name.size();
+    if (no_copy_name) {
+      flags |= NGHTTP2_NV_FLAG_NO_COPY_NAME;
+    }
+    const auto [value, no_copy_value] = GetStringView(headers[i].second);
+    header.value = ToUint8Ptr(value.data());
+    header.valuelen = value.size();
+    if (no_copy_value) {
+      flags |= NGHTTP2_NV_FLAG_NO_COPY_VALUE;
+    }
+    header.flags = flags;
+    nghttp2_nvs.push_back(std::move(header));
+  }
+
+  return nghttp2_nvs;
+}
+
+std::vector<nghttp2_nv> GetResponseNghttp2Nvs(
+    const spdy::Http2HeaderBlock& headers,
+    absl::string_view response_code) {
+  // Allocate enough for all headers and also the :status pseudoheader.
+  const int num_headers = headers.size();
+  std::vector<nghttp2_nv> nghttp2_nvs;
+  nghttp2_nvs.reserve(num_headers + 1);
+
+  // Add the :status pseudoheader first.
+  nghttp2_nv status;
+  status.name = ToUint8Ptr(kHttp2StatusPseudoHeader);
+  status.namelen = strlen(kHttp2StatusPseudoHeader);
+  status.value = ToUint8Ptr(response_code.data());
+  status.valuelen = response_code.size();
+  status.flags = NGHTTP2_FLAG_NONE;
+  nghttp2_nvs.push_back(std::move(status));
+
+  // Add the remaining headers.
+  for (const auto& header_pair : headers) {
+    nghttp2_nv header;
+    header.name = ToUint8Ptr(header_pair.first.data());
+    header.namelen = header_pair.first.size();
+    header.value = ToUint8Ptr(header_pair.second.data());
+    header.valuelen = header_pair.second.size();
+    header.flags = NGHTTP2_FLAG_NONE;
+    nghttp2_nvs.push_back(std::move(header));
+  }
+
+  return nghttp2_nvs;
+}
+
+Http2ErrorCode ToHttp2ErrorCode(uint32_t wire_error_code) {
+  if (wire_error_code > static_cast<int>(Http2ErrorCode::MAX_ERROR_CODE)) {
+    return Http2ErrorCode::INTERNAL_ERROR;
+  }
+  return static_cast<Http2ErrorCode>(wire_error_code);
+}
+
+int ToNgHttp2ErrorCode(InvalidFrameError error) {
+  switch (error) {
+    case InvalidFrameError::kProtocol:
+      return NGHTTP2_ERR_PROTO;
+    case InvalidFrameError::kRefusedStream:
+      return NGHTTP2_ERR_REFUSED_STREAM;
+    case InvalidFrameError::kHttpHeader:
+      return NGHTTP2_ERR_HTTP_HEADER;
+    case InvalidFrameError::kHttpMessaging:
+      return NGHTTP2_ERR_HTTP_MESSAGING;
+    case InvalidFrameError::kFlowControl:
+      return NGHTTP2_ERR_FLOW_CONTROL;
+    case InvalidFrameError::kStreamClosed:
+      return NGHTTP2_ERR_STREAM_CLOSED;
+  }
+  return NGHTTP2_ERR_PROTO;
+}
+
+InvalidFrameError ToInvalidFrameError(int error) {
+  switch (error) {
+    case NGHTTP2_ERR_PROTO:
+      return InvalidFrameError::kProtocol;
+    case NGHTTP2_ERR_REFUSED_STREAM:
+      return InvalidFrameError::kRefusedStream;
+    case NGHTTP2_ERR_HTTP_HEADER:
+      return InvalidFrameError::kHttpHeader;
+    case NGHTTP2_ERR_HTTP_MESSAGING:
+      return InvalidFrameError::kHttpMessaging;
+    case NGHTTP2_ERR_FLOW_CONTROL:
+      return InvalidFrameError::kFlowControl;
+    case NGHTTP2_ERR_STREAM_CLOSED:
+      return InvalidFrameError::kStreamClosed;
+  }
+  return InvalidFrameError::kProtocol;
+}
+
+class Nghttp2DataFrameSource : public DataFrameSource {
+ public:
+  Nghttp2DataFrameSource(nghttp2_data_provider provider,
+                         nghttp2_send_data_callback send_data,
+                         void* user_data)
+      : provider_(std::move(provider)),
+        send_data_(std::move(send_data)),
+        user_data_(user_data) {}
+
+  std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) override {
+    const int32_t stream_id = 0;
+    uint32_t data_flags = 0;
+    int64_t result = provider_.read_callback(
+        nullptr /* session */, stream_id, nullptr /* buf */, max_length,
+        &data_flags, &provider_.source, nullptr /* user_data */);
+    if (result == NGHTTP2_ERR_DEFERRED) {
+      return {kBlocked, false};
+    } else if (result < 0) {
+      return {kError, false};
+    } else if ((data_flags & NGHTTP2_DATA_FLAG_NO_COPY) == 0) {
+      QUICHE_LOG(ERROR) << "Source did not use the zero-copy API!";
+      return {kError, false};
+    } else {
+      const bool eof = data_flags & NGHTTP2_DATA_FLAG_EOF;
+      if (eof && (data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM) == 0) {
+        send_fin_ = true;
+      }
+      return {result, eof};
+    }
+  }
+
+  bool Send(absl::string_view frame_header, size_t payload_length) override {
+    nghttp2_frame frame;
+    frame.hd.type = 0;
+    frame.hd.length = payload_length;
+    frame.hd.flags = 0;
+    frame.hd.stream_id = 0;
+    frame.data.padlen = 0;
+    const int result = send_data_(
+        nullptr /* session */, &frame, ToUint8Ptr(frame_header.data()),
+        payload_length, &provider_.source, user_data_);
+    QUICHE_LOG_IF(ERROR, result < 0 && result != NGHTTP2_ERR_WOULDBLOCK)
+        << "Unexpected error code from send: " << result;
+    return result == 0;
+  }
+
+  bool send_fin() const override { return send_fin_; }
+
+ private:
+  nghttp2_data_provider provider_;
+  nghttp2_send_data_callback send_data_;
+  void* user_data_;
+  bool send_fin_ = false;
+};
+
+std::unique_ptr<DataFrameSource> MakeZeroCopyDataFrameSource(
+    nghttp2_data_provider provider,
+    void* user_data,
+    nghttp2_send_data_callback send_data) {
+  return absl::make_unique<Nghttp2DataFrameSource>(
+      std::move(provider), std::move(send_data), user_data);
+}
+
+absl::string_view ErrorString(uint32_t error_code) {
+  return Http2ErrorCodeToString(static_cast<Http2ErrorCode>(error_code));
+}
+
+size_t PaddingLength(uint8_t flags, size_t padlen) {
+  return (flags & 0x8 ? 1 : 0) + padlen;
+}
+
+struct NvFormatter {
+  void operator()(std::string* out, const nghttp2_nv& nv) {
+    absl::StrAppend(out, ToStringView(nv.name, nv.namelen), ": ",
+                    ToStringView(nv.value, nv.valuelen));
+  }
+};
+
+std::string NvsAsString(nghttp2_nv* nva, size_t nvlen) {
+  return absl::StrJoin(absl::MakeConstSpan(nva, nvlen), ", ", NvFormatter());
+}
+
+#define HTTP2_FRAME_SEND_LOG QUICHE_VLOG(1)
+
+void LogBeforeSend(const nghttp2_frame& frame) {
+  switch (static_cast<FrameType>(frame.hd.type)) {
+    case FrameType::DATA:
+      HTTP2_FRAME_SEND_LOG << "Sending DATA on stream " << frame.hd.stream_id
+                           << " with length "
+                           << frame.hd.length - PaddingLength(frame.hd.flags,
+                                                              frame.data.padlen)
+                           << " and padding "
+                           << PaddingLength(frame.hd.flags, frame.data.padlen);
+      break;
+    case FrameType::HEADERS:
+      HTTP2_FRAME_SEND_LOG << "Sending HEADERS on stream " << frame.hd.stream_id
+                           << " with headers ["
+                           << NvsAsString(frame.headers.nva,
+                                          frame.headers.nvlen)
+                           << "]";
+      break;
+    case FrameType::PRIORITY:
+      HTTP2_FRAME_SEND_LOG << "Sending PRIORITY";
+      break;
+    case FrameType::RST_STREAM:
+      HTTP2_FRAME_SEND_LOG << "Sending RST_STREAM on stream "
+                           << frame.hd.stream_id << " with error code "
+                           << ErrorString(frame.rst_stream.error_code);
+      break;
+    case FrameType::SETTINGS:
+      HTTP2_FRAME_SEND_LOG << "Sending SETTINGS with " << frame.settings.niv
+                           << " entries, is_ack: " << (frame.hd.flags & 0x01);
+      break;
+    case FrameType::PUSH_PROMISE:
+      HTTP2_FRAME_SEND_LOG << "Sending PUSH_PROMISE";
+      break;
+    case FrameType::PING: {
+      Http2PingId ping_id;
+      std::memcpy(&ping_id, frame.ping.opaque_data, sizeof(Http2PingId));
+      HTTP2_FRAME_SEND_LOG << "Sending PING with unique_id "
+                           << quiche::QuicheEndian::NetToHost64(ping_id)
+                           << ", is_ack: " << (frame.hd.flags & 0x01);
+      break;
+    }
+    case FrameType::GOAWAY:
+      HTTP2_FRAME_SEND_LOG << "Sending GOAWAY with last_stream: "
+                           << frame.goaway.last_stream_id << " and error "
+                           << ErrorString(frame.goaway.error_code);
+      break;
+    case FrameType::WINDOW_UPDATE:
+      HTTP2_FRAME_SEND_LOG << "Sending WINDOW_UPDATE on stream "
+                           << frame.hd.stream_id << " with update delta "
+                           << frame.window_update.window_size_increment;
+      break;
+    case FrameType::CONTINUATION:
+      HTTP2_FRAME_SEND_LOG << "Sending CONTINUATION, which is unexpected";
+      break;
+  }
+}
+
+#undef HTTP2_FRAME_SEND_LOG
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/nghttp2_util.h b/quiche/http2/adapter/nghttp2_util.h
new file mode 100644
index 0000000..5e8b201
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_util.h
@@ -0,0 +1,78 @@
+// Various utility/conversion functions for compatibility with the nghttp2 API.
+
+#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_UTIL_H_
+#define QUICHE_HTTP2_ADAPTER_NGHTTP2_UTIL_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/http2/adapter/data_source.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/nghttp2.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace http2 {
+namespace adapter {
+
+// Return codes to represent various errors.
+inline constexpr int kStreamCallbackFailureStatus =
+    NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+inline constexpr int kCancelStatus = NGHTTP2_ERR_CANCEL;
+
+using CallbacksDeleter = void (*)(nghttp2_session_callbacks*);
+using SessionDeleter = void (*)(nghttp2_session*);
+
+using nghttp2_session_callbacks_unique_ptr =
+    std::unique_ptr<nghttp2_session_callbacks, CallbacksDeleter>;
+using nghttp2_session_unique_ptr =
+    std::unique_ptr<nghttp2_session, SessionDeleter>;
+
+nghttp2_session_callbacks_unique_ptr MakeCallbacksPtr(
+    nghttp2_session_callbacks* callbacks);
+nghttp2_session_unique_ptr MakeSessionPtr(nghttp2_session* session);
+
+uint8_t* ToUint8Ptr(char* str);
+uint8_t* ToUint8Ptr(const char* str);
+
+absl::string_view ToStringView(nghttp2_rcbuf* rc_buffer);
+absl::string_view ToStringView(uint8_t* pointer, size_t length);
+absl::string_view ToStringView(const uint8_t* pointer, size_t length);
+
+// Returns the nghttp2 header structure from the given |headers|, which
+// must have the correct pseudoheaders preceding other headers.
+std::vector<nghttp2_nv> GetNghttp2Nvs(absl::Span<const Header> headers);
+
+// Returns the nghttp2 header structure from the given response |headers|, with
+// the :status pseudoheader first based on the given |response_code|. The
+// |response_code| is passed in separately from |headers| for lifetime reasons.
+std::vector<nghttp2_nv> GetResponseNghttp2Nvs(
+    const spdy::Http2HeaderBlock& headers,
+    absl::string_view response_code);
+
+// Returns the HTTP/2 error code corresponding to the raw wire value, as defined
+// in RFC 7540 Section 7. Unrecognized error codes are treated as INTERNAL_ERROR
+// based on the RFC 7540 Section 7 suggestion.
+Http2ErrorCode ToHttp2ErrorCode(uint32_t wire_error_code);
+
+// Converts between the integer error code used by nghttp2 and the corresponding
+// InvalidFrameError value.
+int ToNgHttp2ErrorCode(Http2VisitorInterface::InvalidFrameError error);
+Http2VisitorInterface::InvalidFrameError ToInvalidFrameError(int error);
+
+// Transforms a nghttp2_data_provider into a DataFrameSource. Assumes that
+// |provider| uses the zero-copy nghttp2_data_source_read_callback API. Unsafe
+// otherwise.
+std::unique_ptr<DataFrameSource> MakeZeroCopyDataFrameSource(
+    nghttp2_data_provider provider,
+    void* user_data,
+    nghttp2_send_data_callback send_data);
+
+void LogBeforeSend(const nghttp2_frame& frame);
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_UTIL_H_
diff --git a/quiche/http2/adapter/nghttp2_util_test.cc b/quiche/http2/adapter/nghttp2_util_test.cc
new file mode 100644
index 0000000..9ac6ef6
--- /dev/null
+++ b/quiche/http2/adapter/nghttp2_util_test.cc
@@ -0,0 +1,109 @@
+#include "quiche/http2/adapter/nghttp2_util.h"
+
+#include "quiche/http2/adapter/nghttp2_test_utils.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+// This send callback assumes |source|'s pointer is a TestDataSource, and
+// |user_data| is a std::string.
+int FakeSendCallback(nghttp2_session*, nghttp2_frame* /*frame*/,
+                     const uint8_t* framehd, size_t length,
+                     nghttp2_data_source* source, void* user_data) {
+  auto* dest = static_cast<std::string*>(user_data);
+  // Appends the frame header to the string.
+  absl::StrAppend(dest, ToStringView(framehd, 9));
+  auto* test_source = static_cast<TestDataSource*>(source->ptr);
+  absl::string_view payload = test_source->ReadNext(length);
+  // Appends the frame payload to the string.
+  absl::StrAppend(dest, payload);
+  return 0;
+}
+
+TEST(MakeZeroCopyDataFrameSource, EmptyPayload) {
+  std::string result;
+
+  const absl::string_view kEmptyBody = "";
+  TestDataSource body1{kEmptyBody};
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
+  auto [length, eof] = frame_source->SelectPayloadLength(100);
+  EXPECT_EQ(length, 0);
+  EXPECT_TRUE(eof);
+  frame_source->Send("ninebytes", 0);
+  EXPECT_EQ(result, "ninebytes");
+}
+
+TEST(MakeZeroCopyDataFrameSource, ShortPayload) {
+  std::string result;
+
+  const absl::string_view kShortBody =
+      "<html><head><title>Example Page!</title></head>"
+      "<body><div><span><table><tr><th><blink>Wow!!"
+      "</blink></th></tr></table></span></div></body>"
+      "</html>";
+  TestDataSource body1{kShortBody};
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
+  auto [length, eof] = frame_source->SelectPayloadLength(200);
+  EXPECT_EQ(length, kShortBody.size());
+  EXPECT_TRUE(eof);
+  frame_source->Send("ninebytes", length);
+  EXPECT_EQ(result, absl::StrCat("ninebytes", kShortBody));
+}
+
+TEST(MakeZeroCopyDataFrameSource, MultiFramePayload) {
+  std::string result;
+
+  const absl::string_view kShortBody =
+      "<html><head><title>Example Page!</title></head>"
+      "<body><div><span><table><tr><th><blink>Wow!!"
+      "</blink></th></tr></table></span></div></body>"
+      "</html>";
+  TestDataSource body1{kShortBody};
+  // The TestDataSource is wrapped in the nghttp2_data_provider data type.
+  nghttp2_data_provider provider = body1.MakeDataProvider();
+
+  // This call transforms it back into a DataFrameSource, which is compatible
+  // with the Http2Adapter API.
+  std::unique_ptr<DataFrameSource> frame_source =
+      MakeZeroCopyDataFrameSource(provider, &result, FakeSendCallback);
+  auto ret = frame_source->SelectPayloadLength(50);
+  EXPECT_EQ(ret.first, 50);
+  EXPECT_FALSE(ret.second);
+  frame_source->Send("ninebyte1", ret.first);
+
+  ret = frame_source->SelectPayloadLength(50);
+  EXPECT_EQ(ret.first, 50);
+  EXPECT_FALSE(ret.second);
+  frame_source->Send("ninebyte2", ret.first);
+
+  ret = frame_source->SelectPayloadLength(50);
+  EXPECT_EQ(ret.first, 44);
+  EXPECT_TRUE(ret.second);
+  frame_source->Send("ninebyte3", ret.first);
+
+  EXPECT_EQ(result,
+            "ninebyte1<html><head><title>Example Page!</title></head><bo"
+            "ninebyte2dy><div><span><table><tr><th><blink>Wow!!</blink><"
+            "ninebyte3/th></tr></table></span></div></body></html>");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/oghttp2_adapter.cc b/quiche/http2/adapter/oghttp2_adapter.cc
new file mode 100644
index 0000000..9c43c76
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_adapter.cc
@@ -0,0 +1,169 @@
+#include "quiche/http2/adapter/oghttp2_adapter.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/adapter/http2_util.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+
+namespace {
+
+using spdy::SpdyGoAwayIR;
+using spdy::SpdyPingIR;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyWindowUpdateIR;
+
+}  // namespace
+
+/* static */
+std::unique_ptr<OgHttp2Adapter> OgHttp2Adapter::Create(
+    Http2VisitorInterface& visitor,
+    Options options) {
+  // Using `new` to access a non-public constructor.
+  return absl::WrapUnique(new OgHttp2Adapter(visitor, std::move(options)));
+}
+
+OgHttp2Adapter::~OgHttp2Adapter() {}
+
+bool OgHttp2Adapter::IsServerSession() const {
+  return session_->IsServerSession();
+}
+
+int64_t OgHttp2Adapter::ProcessBytes(absl::string_view bytes) {
+  return session_->ProcessBytes(bytes);
+}
+
+void OgHttp2Adapter::SubmitSettings(absl::Span<const Http2Setting> settings) {
+  session_->SubmitSettings(settings);
+}
+
+void OgHttp2Adapter::SubmitPriorityForStream(Http2StreamId stream_id,
+                                             Http2StreamId parent_stream_id,
+                                             int weight,
+                                             bool exclusive) {
+  session_->EnqueueFrame(absl::make_unique<SpdyPriorityIR>(
+      stream_id, parent_stream_id, weight, exclusive));
+}
+
+void OgHttp2Adapter::SubmitPing(Http2PingId ping_id) {
+  session_->EnqueueFrame(absl::make_unique<SpdyPingIR>(ping_id));
+}
+
+void OgHttp2Adapter::SubmitShutdownNotice() {
+  session_->StartGracefulShutdown();
+}
+
+void OgHttp2Adapter::SubmitGoAway(Http2StreamId last_accepted_stream_id,
+                                  Http2ErrorCode error_code,
+                                  absl::string_view opaque_data) {
+  session_->EnqueueFrame(absl::make_unique<SpdyGoAwayIR>(
+      last_accepted_stream_id, TranslateErrorCode(error_code),
+      std::string(opaque_data)));
+}
+void OgHttp2Adapter::SubmitWindowUpdate(Http2StreamId stream_id,
+                                        int window_increment) {
+  session_->EnqueueFrame(
+      absl::make_unique<SpdyWindowUpdateIR>(stream_id, window_increment));
+}
+
+void OgHttp2Adapter::SubmitMetadata(Http2StreamId stream_id,
+                                    size_t /* max_frame_size */,
+                                    std::unique_ptr<MetadataSource> source) {
+  // Not necessary to pass max_frame_size along, since OgHttp2Session tracks the
+  // peer's advertised max frame size.
+  session_->SubmitMetadata(stream_id, std::move(source));
+}
+
+int OgHttp2Adapter::Send() { return session_->Send(); }
+
+int OgHttp2Adapter::GetSendWindowSize() const {
+  return session_->GetRemoteWindowSize();
+}
+
+int OgHttp2Adapter::GetStreamSendWindowSize(Http2StreamId stream_id) const {
+  return session_->GetStreamSendWindowSize(stream_id);
+}
+
+int OgHttp2Adapter::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
+  return session_->GetStreamReceiveWindowLimit(stream_id);
+}
+
+int OgHttp2Adapter::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
+  return session_->GetStreamReceiveWindowSize(stream_id);
+}
+
+int OgHttp2Adapter::GetReceiveWindowSize() const {
+  return session_->GetReceiveWindowSize();
+}
+
+int OgHttp2Adapter::GetHpackEncoderDynamicTableSize() const {
+  return session_->GetHpackEncoderDynamicTableSize();
+}
+
+int OgHttp2Adapter::GetHpackEncoderDynamicTableCapacity() const {
+  return session_->GetHpackEncoderDynamicTableCapacity();
+}
+
+int OgHttp2Adapter::GetHpackDecoderDynamicTableSize() const {
+  return session_->GetHpackDecoderDynamicTableSize();
+}
+
+int OgHttp2Adapter::GetHpackDecoderSizeLimit() const {
+  return session_->GetHpackDecoderSizeLimit();
+}
+
+Http2StreamId OgHttp2Adapter::GetHighestReceivedStreamId() const {
+  return session_->GetHighestReceivedStreamId();
+}
+
+void OgHttp2Adapter::MarkDataConsumedForStream(Http2StreamId stream_id,
+                                               size_t num_bytes) {
+  session_->Consume(stream_id, num_bytes);
+}
+
+void OgHttp2Adapter::SubmitRst(Http2StreamId stream_id,
+                               Http2ErrorCode error_code) {
+  session_->EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+      stream_id, TranslateErrorCode(error_code)));
+}
+
+int32_t OgHttp2Adapter::SubmitRequest(
+    absl::Span<const Header> headers,
+    std::unique_ptr<DataFrameSource> data_source, void* user_data) {
+  return session_->SubmitRequest(headers, std::move(data_source), user_data);
+}
+
+int OgHttp2Adapter::SubmitResponse(
+    Http2StreamId stream_id, absl::Span<const Header> headers,
+    std::unique_ptr<DataFrameSource> data_source) {
+  return session_->SubmitResponse(stream_id, headers, std::move(data_source));
+}
+
+int OgHttp2Adapter::SubmitTrailer(Http2StreamId stream_id,
+                                  absl::Span<const Header> trailers) {
+  return session_->SubmitTrailer(stream_id, trailers);
+}
+
+void OgHttp2Adapter::SetStreamUserData(Http2StreamId stream_id,
+                                       void* user_data) {
+  session_->SetStreamUserData(stream_id, user_data);
+}
+
+void* OgHttp2Adapter::GetStreamUserData(Http2StreamId stream_id) {
+  return session_->GetStreamUserData(stream_id);
+}
+
+bool OgHttp2Adapter::ResumeStream(Http2StreamId stream_id) {
+  return session_->ResumeStream(stream_id);
+}
+
+OgHttp2Adapter::OgHttp2Adapter(Http2VisitorInterface& visitor, Options options)
+    : Http2Adapter(visitor),
+      session_(absl::make_unique<OgHttp2Session>(visitor, std::move(options))) {
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/oghttp2_adapter.h b/quiche/http2/adapter/oghttp2_adapter.h
new file mode 100644
index 0000000..c1534c0
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_adapter.h
@@ -0,0 +1,78 @@
+#ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_ADAPTER_H_
+#define QUICHE_HTTP2_ADAPTER_OGHTTP2_ADAPTER_H_
+
+#include <cstdint>
+#include <memory>
+
+#include "quiche/http2/adapter/http2_adapter.h"
+#include "quiche/http2/adapter/http2_session.h"
+#include "quiche/http2/adapter/oghttp2_session.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+class QUICHE_EXPORT_PRIVATE OgHttp2Adapter : public Http2Adapter {
+ public:
+  using Options = OgHttp2Session::Options;
+  static std::unique_ptr<OgHttp2Adapter> Create(Http2VisitorInterface& visitor,
+                                                Options options);
+
+  ~OgHttp2Adapter() override;
+
+  // From Http2Adapter.
+  bool IsServerSession() const override;
+  bool want_read() const override { return session_->want_read(); }
+  bool want_write() const override { return session_->want_write(); }
+  int64_t ProcessBytes(absl::string_view bytes) override;
+  void SubmitSettings(absl::Span<const Http2Setting> settings) override;
+  void SubmitPriorityForStream(Http2StreamId stream_id,
+                               Http2StreamId parent_stream_id,
+                               int weight,
+                               bool exclusive) override;
+  void SubmitPing(Http2PingId ping_id) override;
+  void SubmitShutdownNotice() override;
+  void SubmitGoAway(Http2StreamId last_accepted_stream_id,
+                    Http2ErrorCode error_code,
+                    absl::string_view opaque_data) override;
+  void SubmitWindowUpdate(Http2StreamId stream_id,
+                          int window_increment) override;
+  void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
+                      std::unique_ptr<MetadataSource> source) override;
+  int Send() override;
+  int GetSendWindowSize() const override;
+  int GetStreamSendWindowSize(Http2StreamId stream_id) const override;
+  int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const override;
+  int GetStreamReceiveWindowSize(Http2StreamId stream_id) const override;
+  int GetReceiveWindowSize() const override;
+  int GetHpackEncoderDynamicTableSize() const override;
+  int GetHpackEncoderDynamicTableCapacity() const;
+  int GetHpackDecoderDynamicTableSize() const override;
+  int GetHpackDecoderSizeLimit() const;
+  Http2StreamId GetHighestReceivedStreamId() const override;
+  void MarkDataConsumedForStream(Http2StreamId stream_id,
+                                 size_t num_bytes) override;
+  void SubmitRst(Http2StreamId stream_id, Http2ErrorCode error_code) override;
+  int32_t SubmitRequest(absl::Span<const Header> headers,
+                        std::unique_ptr<DataFrameSource> data_source,
+                        void* user_data) override;
+  int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
+                     std::unique_ptr<DataFrameSource> data_source) override;
+
+  int SubmitTrailer(Http2StreamId stream_id,
+                    absl::Span<const Header> trailers) override;
+
+  void SetStreamUserData(Http2StreamId stream_id, void* user_data) override;
+  void* GetStreamUserData(Http2StreamId stream_id) override;
+  bool ResumeStream(Http2StreamId stream_id) override;
+
+ private:
+  OgHttp2Adapter(Http2VisitorInterface& visitor, Options options);
+
+  std::unique_ptr<OgHttp2Session> session_;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_ADAPTER_H_
diff --git a/quiche/http2/adapter/oghttp2_adapter_test.cc b/quiche/http2/adapter/oghttp2_adapter_test.cc
new file mode 100644
index 0000000..1546f66
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_adapter_test.cc
@@ -0,0 +1,6781 @@
+#include "quiche/http2/adapter/oghttp2_adapter.h"
+
+#include <string>
+
+#include "absl/strings/str_join.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/mock_http2_visitor.h"
+#include "quiche/http2/adapter/oghttp2_util.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using ConnectionError = Http2VisitorInterface::ConnectionError;
+
+using spdy::SpdyFrameType;
+using testing::_;
+
+enum FrameType {
+  DATA,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+  CONTINUATION,
+};
+
+// TODO(birenroy): replace numeric flag values with named constants
+enum FrameFlag {
+  END_STREAM = 0x01,
+  ACK = END_STREAM,
+  END_HEADERS = 0x04,
+};
+
+TEST(OgHttp2AdapterTest, IsServerSession) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_TRUE(adapter->IsServerSession());
+}
+
+TEST(OgHttp2AdapterTest, ProcessBytes) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence seq;
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, 4, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, 6, 0));
+  EXPECT_CALL(visitor, OnPing(17, false));
+  adapter->ProcessBytes(
+      TestFrameSequence().ClientPreface().Ping(17).Serialize());
+}
+
+TEST(OgHttp2AdapterTest, InitialSettingsNoExtendedConnect) {
+  DataSavingVisitor client_visitor;
+  OgHttp2Adapter::Options client_options{.perspective = Perspective::kClient,
+                                         .max_header_list_bytes = 42,
+                                         .allow_extended_connect = false};
+  auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
+
+  DataSavingVisitor server_visitor;
+  OgHttp2Adapter::Options server_options{.perspective = Perspective::kServer,
+                                         .allow_extended_connect = false};
+  auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
+
+  testing::InSequence s;
+
+  // Client sends the connection preface, including the initial SETTINGS.
+  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, 12, 0x0));
+  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, 12, 0x0, 0));
+  {
+    int result = client_adapter->Send();
+    EXPECT_EQ(0, result);
+    absl::string_view data = client_visitor.data();
+    EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+    data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+  }
+
+  // Server sends the connection preface, including the initial SETTINGS.
+  EXPECT_CALL(server_visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
+  EXPECT_CALL(server_visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
+  {
+    int result = server_adapter->Send();
+    EXPECT_EQ(0, result);
+    absl::string_view data = server_visitor.data();
+    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+  }
+
+  // Client processes the server's initial bytes, including initial SETTINGS.
+  EXPECT_CALL(client_visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
+  EXPECT_CALL(client_visitor, OnSettingsStart());
+  EXPECT_CALL(client_visitor, OnSettingsEnd());
+  {
+    const int64_t result = client_adapter->ProcessBytes(server_visitor.data());
+    EXPECT_EQ(server_visitor.data().size(), static_cast<size_t>(result));
+  }
+
+  // Server processes the client's initial bytes, including initial SETTINGS.
+  EXPECT_CALL(server_visitor, OnFrameHeader(0, 12, SETTINGS, 0x0));
+  EXPECT_CALL(server_visitor, OnSettingsStart());
+  EXPECT_CALL(server_visitor,
+              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
+  EXPECT_CALL(
+      server_visitor,
+      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}));
+  EXPECT_CALL(server_visitor, OnSettingsEnd());
+  {
+    const int64_t result = server_adapter->ProcessBytes(client_visitor.data());
+    EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
+  }
+}
+
+TEST(OgHttp2AdapterTest, InitialSettings) {
+  DataSavingVisitor client_visitor;
+  OgHttp2Adapter::Options client_options{.perspective = Perspective::kClient,
+                                         .max_header_list_bytes = 42};
+  ASSERT_TRUE(client_options.allow_extended_connect);
+  auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
+
+  DataSavingVisitor server_visitor;
+  OgHttp2Adapter::Options server_options{.perspective = Perspective::kServer};
+  ASSERT_TRUE(server_options.allow_extended_connect);
+  auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
+
+  testing::InSequence s;
+
+  // Client sends the connection preface, including the initial SETTINGS.
+  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, 12, 0x0));
+  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, 12, 0x0, 0));
+  {
+    int result = client_adapter->Send();
+    EXPECT_EQ(0, result);
+    absl::string_view data = client_visitor.data();
+    EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+    data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+  }
+
+  // Server sends the connection preface, including the initial SETTINGS.
+  EXPECT_CALL(server_visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(server_visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  {
+    int result = server_adapter->Send();
+    EXPECT_EQ(0, result);
+    absl::string_view data = server_visitor.data();
+    EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+  }
+
+  // Client processes the server's initial bytes, including initial SETTINGS.
+  EXPECT_CALL(client_visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
+  EXPECT_CALL(client_visitor, OnSettingsStart());
+  EXPECT_CALL(client_visitor,
+              OnSetting(Http2Setting{
+                  Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u}));
+  EXPECT_CALL(client_visitor, OnSettingsEnd());
+  {
+    const int64_t result = client_adapter->ProcessBytes(server_visitor.data());
+    EXPECT_EQ(server_visitor.data().size(), static_cast<size_t>(result));
+  }
+
+  // Server processes the client's initial bytes, including initial SETTINGS.
+  EXPECT_CALL(server_visitor, OnFrameHeader(0, 12, SETTINGS, 0x0));
+  EXPECT_CALL(server_visitor, OnSettingsStart());
+  EXPECT_CALL(server_visitor,
+              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
+  EXPECT_CALL(
+      server_visitor,
+      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}));
+  EXPECT_CALL(server_visitor, OnSettingsEnd());
+  {
+    const int64_t result = server_adapter->ProcessBytes(client_visitor.data());
+    EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
+  }
+}
+
+TEST(OgHttp2AdapterTest, AutomaticSettingsAndPingAcks) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().Ping(42).Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // PING
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  // PING ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::PING}));
+}
+
+TEST(OgHttp2AdapterTest, AutomaticPingAcksDisabled) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .auto_ping_ack = false};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().Ping(42).Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // PING
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  // No PING ack expected because automatic PING acks are disabled.
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandles100Headers) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}},
+                   /*fin=*/false)
+          .Ping(101)
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(101, false));
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
+}
+
+TEST(OgHttp2AdapterTest, QueuingWindowUpdateAffectsWindow) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_EQ(adapter->GetReceiveWindowSize(), kInitialFlowControlWindowSize);
+  adapter->SubmitWindowUpdate(0, 10000);
+  EXPECT_EQ(adapter->GetReceiveWindowSize(),
+            kInitialFlowControlWindowSize + 10000);
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
+            kInitialFlowControlWindowSize);
+  adapter->SubmitWindowUpdate(1, 20000);
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id),
+            kInitialFlowControlWindowSize + 20000);
+}
+
+TEST(OgHttp2AdapterTest, AckOfSettingInitialWindowSizeAffectsWindow) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id1 = adapter->SubmitRequest(headers, nullptr, nullptr);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .SettingsAck()  // Ack of the client's initial settings.
+          .Serialize();
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  int64_t parse_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(parse_result));
+
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
+            kInitialFlowControlWindowSize);
+  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000u}});
+  // No update for the first stream, yet.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
+            kInitialFlowControlWindowSize);
+
+  // Ack of server's initial settings.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  // Outbound SETTINGS containing INITIAL_WINDOW_SIZE.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  // Still no update, as a SETTINGS ack has not yet been received.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1),
+            kInitialFlowControlWindowSize);
+
+  const std::string settings_ack =
+      TestFrameSequence().SettingsAck().Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  parse_result = adapter->ProcessBytes(settings_ack);
+  EXPECT_EQ(settings_ack.size(), static_cast<size_t>(parse_result));
+
+  // Stream window has been updated.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id1), 80000);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+  const int32_t stream_id2 = adapter->SubmitRequest(headers, nullptr, nullptr);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(stream_id2), 80000);
+}
+
+TEST(OgHttp2AdapterTest, ClientRejects100HeadersWithFin) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}}, /*fin=*/false)
+          .Headers(1, {{":status", "100"}}, /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, 0x0, 1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientRejects100HeadersWithContent) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}},
+                   /*fin=*/false)
+          .Data(1, "We needed the final headers before data, whoops")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientRejects100HeadersWithContentLength) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "100"}, {"content-length", "42"}},
+                   /*fin=*/false)
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "100"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandles204WithContent) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
+  ASSERT_GT(stream_id2, stream_id1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "204"}, {"content-length", "2"}},
+                   /*fin=*/false)
+          .Data(1, "hi")
+          .Headers(3, {{":status", "204"}}, /*fin=*/false)
+          .Data(3, "hi")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "204"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":status", "204"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(3, 2));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandles304WithContent) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
+                   /*fin=*/false)
+          .Data(1, "hi")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandles304WithContentLength) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "304"}, {"content-length", "2"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "304"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "content-length", "2"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesTrailers) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Headers(1, {{"final-status", "A-OK"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "final-status", "A-OK"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientSendsTrailers) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const std::string kBody = "This is an example request body.";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::DATA}));
+  visitor.Clear();
+
+  const std::vector<Header> trailers1 =
+      ToHeaders({{"extra-info", "Trailers are weird but good?"}});
+  adapter->SubmitTrailer(stream_id1, trailers1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  data = visitor.data();
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::HEADERS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesMetadata) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Metadata(0, "Example connection metadata")
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(1, "Example stream metadata")
+          .Data(1, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesMetadataWithEmptyPayload) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(1, "")
+          .Data(1, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(3);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesMetadataWithPayloadError) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Metadata(0, "Example connection metadata")
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(stream_id, "Example stream metadata")
+          .Data(stream_id, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, _, _)).Times(3);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(stream_id, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(stream_id, _))
+      .WillOnce(testing::Return(false));
+  // Remaining frames are not processed due to the error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  // Negative integer returned to indicate an error.
+  EXPECT_LT(stream_result, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  EXPECT_FALSE(adapter->want_read());
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesMetadataWithCompletionError) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Metadata(0, "Example connection metadata")
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Metadata(stream_id, "Example stream metadata")
+          .Data(stream_id, "This is the response body.", true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, _, _)).Times(3);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(stream_id, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(stream_id, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(stream_id))
+      .WillOnce(testing::Return(false));
+  // Remaining frames are not processed due to the error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  // Negative integer returned to indicate an error.
+  EXPECT_LT(stream_result, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  EXPECT_FALSE(adapter->want_read());
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientRstStreamWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
+      .WillOnce(testing::DoAll(
+          testing::InvokeWithoutArgs([&adapter]() {
+            adapter->SubmitRst(1, Http2ErrorCode::REFUSED_STREAM);
+          }),
+          testing::Return(Http2VisitorInterface::HEADER_RST_STREAM)));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, stream_id1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
+      .WillOnce(
+          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_LT(stream_result, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientConnectionErrorWhileHandlingHeadersOnly) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"))
+      .WillOnce(
+          testing::Return(Http2VisitorInterface::HEADER_CONNECTION_ERROR));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_LT(stream_result, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientRejectsHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1))
+      .WillOnce(testing::Return(false));
+  // Rejecting headers leads to a connection error.
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_LT(stream_result, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesSmallerHpackHeaderTableSetting) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 = ToHeaders({
+      {":method", "GET"},
+      {":scheme", "http"},
+      {":authority", "example.com"},
+      {":path", "/this/is/request/one"},
+      {"x-i-do-not-like", "green eggs and ham"},
+      {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
+      {"x-like-them-in-a-house", "no"},
+      {"x-like-them-with-a-mouse", "no"},
+  });
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  EXPECT_GT(adapter->GetHpackEncoderDynamicTableSize(), 100);
+
+  const std::string stream_frames =
+      TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 100u}}).Serialize();
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 100);
+  EXPECT_LE(adapter->GetHpackEncoderDynamicTableSize(), 100);
+}
+
+TEST(OgHttp2AdapterTest, ClientHandlesLargerHpackHeaderTableSetting) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 4096);
+
+  const std::string stream_frames =
+      TestFrameSequence().Settings({{HEADER_TABLE_SIZE, 40960u}}).Serialize();
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 40960u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  // The increased capacity will not be applied until a SETTINGS ack is
+  // serialized.
+  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 4096);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  EXPECT_EQ(adapter->GetHpackEncoderDynamicTableCapacity(), 40960);
+}
+
+TEST(OgHttp2AdapterTest, ClientSendsHpackHeaderTableSetting) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 = ToHeaders({
+      {":method", "GET"},
+      {":scheme", "http"},
+      {":authority", "example.com"},
+      {":path", "/this/is/request/one"},
+  });
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .SettingsAck()
+          .Headers(
+              1,
+              {{":status", "200"},
+               {"server", "my-fake-server"},
+               {"date", "Tue, 6 Apr 2021 12:54:01 GMT"},
+               {"x-i-do-not-like", "green eggs and ham"},
+               {"x-i-will-not-eat-them", "here or there, in a box, with a fox"},
+               {"x-like-them-in-a-house", "no"},
+               {"x-like-them-with-a-mouse", "no"}},
+              /*fin=*/true)
+          .Serialize();
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Server acks client's initial SETTINGS.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(7);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
+
+  // Submit settings, check decoder table size.
+  adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
+  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
+
+  // Server preface SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  // SETTINGS with the new header table size value
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  // Because the client has not yet seen an ack from the server for the SETTINGS
+  // with header table size, it has not applied the new value.
+  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::vector<Header> headers2 = ToHeaders({
+      {":method", "GET"},
+      {":scheme", "http"},
+      {":authority", "example.com"},
+      {":path", "/this/is/request/two"},
+  });
+
+  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
+  ASSERT_GT(stream_id2, stream_id1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string response_frames =
+      TestFrameSequence()
+          .Headers(stream_id2,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id2, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id2));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id2, _, _)).Times(3);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id2));
+  EXPECT_CALL(visitor, OnEndStream(stream_id2));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id2, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  const int64_t response_result = adapter->ProcessBytes(response_frames);
+  EXPECT_EQ(response_frames.size(), static_cast<size_t>(response_result));
+
+  // Still no ack for the outbound settings.
+  EXPECT_GT(adapter->GetHpackDecoderSizeLimit(), 100);
+
+  const std::string settings_ack =
+      TestFrameSequence().SettingsAck().Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+
+  const int64_t ack_result = adapter->ProcessBytes(settings_ack);
+  EXPECT_EQ(settings_ack.size(), static_cast<size_t>(ack_result));
+  // Ack has finally arrived.
+  EXPECT_EQ(adapter->GetHpackDecoderSizeLimit(), 100);
+}
+
+// TODO(birenroy): Validate headers and re-enable this test. The library should
+// invoke OnErrorDebug() with an error message for the invalid header. The
+// library should also invoke OnInvalidFrame() for the invalid HEADERS frame.
+TEST(OgHttp2AdapterTest, DISABLED_ClientHandlesInvalidTrailers) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.")
+          .Headers(1, {{":bad-status", "9000"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+
+  // Bad status trailer will cause a PROTOCOL_ERROR. The header is never
+  // delivered in an OnHeaderForStream callback.
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id1, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id1, 4, 0x0, 1));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::PROTOCOL_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientStartsShutdown) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  // No-op (except for logging) for a client implementation.
+  adapter->SubmitShutdownNotice();
+  EXPECT_FALSE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientReceivesGoAway) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  const int32_t stream_id2 = adapter->SubmitRequest(headers2, nullptr, nullptr);
+  ASSERT_GT(stream_id2, stream_id1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
+          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
+          .WindowUpdate(0, 42)
+          .WindowUpdate(1, 42)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM));
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
+  // Currently, oghttp2 does not pass the opaque data to the visitor.
+  EXPECT_CALL(visitor, OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, ""));
+  // TODO(b/228093860): Close stream IDs above the GOAWAY's last_stream_id.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 42));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientFailsOnGoAway) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, nullptr, const_cast<char*>(kSentinel1));
+  ASSERT_GT(stream_id1, 0);
+  QUICHE_LOG(INFO) << "Created stream: " << stream_id1;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .GoAway(1, Http2ErrorCode::INTERNAL_ERROR, "indigestion")
+          .Data(1, "This is the response body.")
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, GOAWAY, 0));
+  // TODO(birenroy): Pass the GOAWAY opaque data through the oghttp2 stack.
+  EXPECT_CALL(visitor, OnGoAway(1, Http2ErrorCode::INTERNAL_ERROR, ""))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_LT(stream_result, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientRejects101Response) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"},
+                 {"upgrade", "new-protocol"}});
+
+  const int32_t stream_id1 = adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1,
+                   {{":status", "101"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(static_cast<int64_t>(stream_frames.size()), stream_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                  static_cast<uint32_t>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS,
+                                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ClientObeysMaxConcurrentStreams) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  // Even though the user has not queued any frames for the session, it should
+  // still send the connection preface.
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  // Initial SETTINGS.
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ServerPreface({{.id = MAX_CONCURRENT_STREAMS, .value = 1}})
+          .Serialize();
+  testing::InSequence s;
+
+  // Server preface (SETTINGS with MAX_CONCURRENT_STREAMS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting);
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string kBody = "This is an example request body.";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+  const int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  const int next_stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/two"}}),
+                             nullptr, nullptr);
+
+  // A new pending stream is created, but because of MAX_CONCURRENT_STREAMS, the
+  // session should not want to write it at the moment.
+  EXPECT_GT(next_stream_id, stream_id);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(stream_id, "This is the response body.", /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(stream_id, "server", "my-fake-server"));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
+                                         "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0x1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
+  EXPECT_CALL(visitor,
+              OnDataForStream(stream_id, "This is the response body."));
+  EXPECT_CALL(visitor, OnEndStream(stream_id));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  // The first stream should close, which should make the session want to write
+  // the next stream.
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, next_stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, next_stream_id, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, ClientReceivesInitialWindowSetting) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .Settings({{INITIAL_WINDOW_SIZE, 80000u}})
+          .WindowUpdate(0, 65536)
+          .Serialize();
+  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int64_t result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string kLongBody = std::string(81000, 'c');
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kLongBody);
+  body1->EndData();
+  const int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  // The client can send more than 4 frames (65536 bytes) of data.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(4);
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14464, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA, SpdyFrameType::DATA}));
+}
+
+TEST(OgHttp2AdapterTest, ClientReceivesInitialWindowSettingAfterStreamStart) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().WindowUpdate(0, 65536).Serialize();
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int64_t result = adapter->Send();
+  EXPECT_EQ(0, result);
+  visitor.Clear();
+
+  const std::string kLongBody = std::string(81000, 'c');
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload(kLongBody);
+  body1->EndData();
+  const int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "POST"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             std::move(body1), nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  // The client can only send 65535 bytes of data, as the stream window has not
+  // yet been increased.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16384, 0x0, 0)).Times(3);
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 16383, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA, SpdyFrameType::DATA,
+                            SpdyFrameType::DATA}));
+  visitor.Clear();
+
+  // Can't write any more due to flow control.
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string settings_frame =
+      TestFrameSequence().Settings({{INITIAL_WINDOW_SIZE, 80000u}}).Serialize();
+  // SETTINGS with INITIAL_STREAM_WINDOW
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t settings_result = adapter->ProcessBytes(settings_frame);
+  EXPECT_EQ(settings_frame.size(), static_cast<size_t>(settings_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  // The client can write more after receiving the INITIAL_WINDOW_SIZE setting.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 14465, 0x0, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::DATA}));
+}
+
+TEST(OgHttp2AdapterTest, InvalidInitialWindowSetting) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const uint32_t kTooLargeInitialWindow = 1u << 31;
+  const std::string initial_frames =
+      TestFrameSequence()
+          .Settings({{INITIAL_WINDOW_SIZE, kTooLargeInitialWindow}})
+          .Serialize();
+  // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  0, Http2VisitorInterface::InvalidFrameError::kFlowControl));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a GOAWAY.
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  int64_t result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+  visitor.Clear();
+}
+
+TEST(OggHttp2AdapterClientTest, InitialWindowSettingCausesOverflow) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+  int64_t write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const uint32_t kLargeInitialWindow = (1u << 31) - 1;
+  const std::string frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(stream_id, {{":status", "200"}}, /*fin=*/false)
+          .WindowUpdate(stream_id, 65536u)
+          .Settings({{INITIAL_WINDOW_SIZE, kLargeInitialWindow}})
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 4, WINDOW_UPDATE, 0x0));
+  EXPECT_CALL(visitor, OnWindowUpdate(stream_id, 65536));
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE,
+                                              kLargeInitialWindow}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  // The stream window update plus the SETTINGS frame with INITIAL_WINDOW_SIZE
+  // pushes the stream's flow control window outside of the acceptable range.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, 4, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(RST_STREAM, stream_id, 4, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, FailureSendingConnectionPreface) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  visitor.set_has_write_error();
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
+
+  int result = adapter->Send();
+  EXPECT_LT(result, 0);
+}
+
+TEST(OgHttp2AdapterTest, MaxFrameSizeSettingNotAppliedBeforeAck) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
+  const int32_t stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
+                                        {":scheme", "https"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             /*data_source=*/nullptr, /*user_data=*/nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  testing::InSequence s;
+
+  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string server_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .Headers(1, {{":status", "200"}}, /*fin=*/false)
+          .Data(1, std::string(large_frame_size, 'a'))
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Response HEADERS. Because the SETTINGS with MAX_FRAME_SIZE was not
+  // acknowledged, the large DATA is treated as a connection error. Note that
+  // oghttp2 delivers the DATA frame header and connection error events.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t process_result = adapter->ProcessBytes(server_frames);
+  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::FRAME_SIZE_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, MaxFrameSizeSettingAppliedAfterAck) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const uint32_t large_frame_size = kDefaultFramePayloadSizeLimit + 42;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, large_frame_size}});
+  const int32_t stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
+                                        {":scheme", "https"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             /*data_source=*/nullptr, /*user_data=*/nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  testing::InSequence s;
+
+  // Client preface (SETTINGS with MAX_FRAME_SIZE) and request HEADERS
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string server_frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .SettingsAck()
+          .Headers(1, {{":status", "200"}}, /*fin=*/false)
+          .Data(1, std::string(large_frame_size, 'a'))
+          .Serialize();
+
+  // Server preface (empty SETTINGS) and ack of SETTINGS.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+
+  // Response HEADERS and DATA. Because the SETTINGS with MAX_FRAME_SIZE was
+  // acknowledged, the large DATA is accepted without any error.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, large_frame_size, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, large_frame_size));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+
+  const int64_t process_result = adapter->ProcessBytes(server_frames);
+  EXPECT_EQ(server_frames.size(), static_cast<size_t>(process_result));
+
+  // Client ack of SETTINGS.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ClientForbidsPushPromise) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+
+  visitor.Clear();
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+  write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::vector<Header> push_headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/push"}});
+  const std::string frames = TestFrameSequence()
+                                 .ServerPreface()
+                                 .SettingsAck()
+                                 .PushPromise(stream_id, 2, push_headers)
+                                 .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // SETTINGS ack (to acknowledge PUSH_ENABLED=0, though this is not explicitly
+  // required for OgHttp2: should it be?)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  // The PUSH_PROMISE is treated as an invalid frame.
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, PUSH_PROMISE, _));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidPushPromise));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientForbidsPushStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+
+  visitor.Clear();
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+  const int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  ASSERT_GT(stream_id, 0);
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+  write_result = adapter->Send();
+  EXPECT_EQ(0, write_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string frames =
+      TestFrameSequence()
+          .ServerPreface()
+          .SettingsAck()
+          .Headers(2,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // SETTINGS ack (to acknowledge PUSH_ENABLED=0, though this is not explicitly
+  // required for OgHttp2: should it be?)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck);
+
+  // The push HEADERS are invalid.
+  EXPECT_CALL(visitor, OnFrameHeader(2, _, HEADERS, _));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidNewStreamId));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientReceivesDataOnClosedStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view data = visitor.data();
+  EXPECT_THAT(data, testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  data.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(data, EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Client SETTINGS ack
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Let the client open a stream with a request.
+  int stream_id =
+      adapter->SubmitRequest(ToHeaders({{":method", "GET"},
+                                        {":scheme", "http"},
+                                        {":authority", "example.com"},
+                                        {":path", "/this/is/request/one"}}),
+                             nullptr, nullptr);
+  EXPECT_GT(stream_id, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  // Let the client RST_STREAM the stream it opened.
+  adapter->SubmitRst(stream_id, Http2ErrorCode::CANCEL);
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, stream_id, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, stream_id, _, 0x0,
+                                   static_cast<int>(Http2ErrorCode::CANCEL)));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
+  visitor.Clear();
+
+  // Let the server send a response on the stream. (It might not have received
+  // the RST_STREAM yet.)
+  const std::string response_frames =
+      TestFrameSequence()
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(stream_id, "This is the response body.", /*fin=*/true)
+          .Serialize();
+
+  // The visitor gets notified about the HEADERS frame and DATA frame for the
+  // closed stream with no further processing on either frame.
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 0x4));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, DATA, 0x1));
+
+  const int64_t response_result = adapter->ProcessBytes(response_frames);
+  EXPECT_EQ(response_frames.size(), static_cast<size_t>(response_result));
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, ClientEncountersFlowControlBlock) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const std::string kBody = std::string(100 * 1024, 'a');
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  auto body2 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body2->AppendPayload(kBody);
+  body2->EndData();
+
+  const int32_t stream_id2 =
+      adapter->SubmitRequest(headers2, std::move(body2), nullptr);
+  ASSERT_GT(stream_id2, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x4, 0));
+  // 4 DATA frames should saturate the default 64kB stream/connection flow
+  // control window.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0)).Times(4);
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_EQ(0, adapter->GetSendWindowSize());
+
+  const std::string stream_frames = TestFrameSequence()
+                                        .ServerPreface()
+                                        .WindowUpdate(0, 80000)
+                                        .WindowUpdate(stream_id1, 20000)
+                                        .Serialize();
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 80000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(1, 20000));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id2, _, 0x0, 0))
+      .Times(testing::AtLeast(1));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0))
+      .Times(testing::AtLeast(1));
+
+  EXPECT_TRUE(adapter->want_write());
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+}
+
+TEST(OgHttp2AdapterTest, ClientSendsTrailersAfterFlowControlBlock) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload("Really small body.");
+  body1->EndData();
+
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  const std::vector<Header> headers2 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/two"}});
+
+  const std::string kBody = std::string(100 * 1024, 'a');
+  auto body2 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body2->AppendPayload(kBody);
+  body2->EndData();
+
+  const int32_t stream_id2 =
+      adapter->SubmitRequest(headers2, std::move(body2), nullptr);
+  ASSERT_GT(stream_id2, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id2, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id2, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0)).Times(1);
+  // 4 DATA frames should saturate the default 64kB stream/connection flow
+  // control window.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id2, _, 0x0, 0)).Times(4);
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_FALSE(adapter->want_write());
+  EXPECT_EQ(0, adapter->GetSendWindowSize());
+
+  const std::vector<Header> trailers1 =
+      ToHeaders({{"extra-info", "Trailers are weird but good?"}});
+  adapter->SubmitTrailer(stream_id1, trailers1);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+}
+
+TEST(OgHttp2AdapterTest, ClientSendsMetadataAfterFlowControlBlock) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}});
+
+  const std::string kBody = std::string(100 * 1024, 'a');
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+
+  const int32_t stream_id1 =
+      adapter->SubmitRequest(headers1, std::move(body1), nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id1, _, 0x4, 0));
+  // 4 DATA frames should saturate the default 64kB stream/connection flow
+  // control window.
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id1, _, 0x0, 0)).Times(4);
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_FALSE(adapter->want_write());
+  EXPECT_EQ(0, adapter->GetSendWindowSize());
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
+
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+}
+
+TEST(OgHttp2AdapterTest, ClientQueuesRequests) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kClient};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  adapter->Send();
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ServerPreface({{MAX_CONCURRENT_STREAMS, 2}})
+          .SettingsAck()
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{
+                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+
+  adapter->ProcessBytes(initial_frames);
+
+  const std::vector<Header> headers =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/example/request"}});
+  std::vector<int32_t> stream_ids;
+  // Start two, which hits the limit.
+  int32_t stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+  // Start two more, which must be queued.
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[0], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[0], _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[1], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[1], _, 0x5, 0));
+
+  adapter->Send();
+
+  const std::string update_streams =
+      TestFrameSequence().Settings({{MAX_CONCURRENT_STREAMS, 5}}).Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{
+                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}));
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  adapter->ProcessBytes(update_streams);
+  stream_id = adapter->SubmitRequest(headers, nullptr, nullptr);
+  stream_ids.push_back(stream_id);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[2], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[2], _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[3], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[3], _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_ids[4], _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_ids[4], _, 0x5, 0));
+  // Header frames should all have been sent in order, regardless of any
+  // queuing.
+
+  adapter->Send();
+}
+
+TEST(OgHttp2AdapterTest, SubmitMetadata) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS,
+                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, SubmitMetadataMultipleFrames) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const auto kLargeValue = std::string(63 * 1024, 'a');
+  auto source = absl::make_unique<TestMetadataSource>(
+      ToHeaderBlock(ToHeaders({{"large-value", kLargeValue}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+  EXPECT_TRUE(adapter->want_write());
+
+  testing::InSequence seq;
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 1, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS,
+                            static_cast<SpdyFrameType>(kMetadataFrameType),
+                            static_cast<SpdyFrameType>(kMetadataFrameType),
+                            static_cast<SpdyFrameType>(kMetadataFrameType),
+                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, SubmitConnectionMetadata) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(0, 16384u, std::move(source));
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(kMetadataFrameType, 0, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(kMetadataFrameType, 0, _, 0x4, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS,
+                            static_cast<SpdyFrameType>(kMetadataFrameType)}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, GetSendWindowSize) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const int peer_window = adapter->GetSendWindowSize();
+  EXPECT_EQ(peer_window, kInitialFlowControlWindowSize);
+}
+
+TEST(OgHttp2AdapterTest, MarkDataConsumedForNonexistentStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  // Send some data on stream 1 so the connection window manager doesn't
+  // underflow later.
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "Some data on stream 1")
+                                 .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+
+  adapter->ProcessBytes(frames);
+
+  // This should not cause a crash or QUICHE_BUG.
+  adapter->MarkDataConsumedForStream(3, 11);
+}
+
+TEST(OgHttp2AdapterTest, TestSerialize) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_TRUE(adapter->want_read());
+  EXPECT_FALSE(adapter->want_write());
+
+  adapter->SubmitSettings(
+      {{HEADER_TABLE_SIZE, 128}, {MAX_FRAME_SIZE, 128 << 10}});
+  EXPECT_TRUE(adapter->want_write());
+
+  const Http2StreamId accepted_stream = 3;
+  const Http2StreamId rejected_stream = 7;
+  adapter->SubmitPriorityForStream(accepted_stream, 1, 255, true);
+  adapter->SubmitRst(rejected_stream, Http2ErrorCode::CANCEL);
+  adapter->SubmitPing(42);
+  adapter->SubmitGoAway(13, Http2ErrorCode::HTTP2_NO_ERROR, "");
+  adapter->SubmitWindowUpdate(accepted_stream, 127);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PRIORITY, accepted_stream, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(PRIORITY, accepted_stream, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, rejected_stream, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, rejected_stream, _, 0x0, 0x8));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor,
+              OnBeforeFrameSent(WINDOW_UPDATE, accepted_stream, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, accepted_stream, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PRIORITY,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::PING,
+                    SpdyFrameType::GOAWAY, SpdyFrameType::WINDOW_UPDATE}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, TestPartialSerialize) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  adapter->SubmitSettings(
+      {{HEADER_TABLE_SIZE, 128}, {MAX_FRAME_SIZE, 128 << 10}});
+  adapter->SubmitGoAway(13, Http2ErrorCode::HTTP2_NO_ERROR,
+                        "And don't come back!");
+  adapter->SubmitPing(42);
+  EXPECT_TRUE(adapter->want_write());
+
+  visitor.set_send_limit(20);
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x0, 0));
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_FALSE(adapter->want_write());
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY,
+                            SpdyFrameType::PING}));
+}
+
+TEST(OgHttp2AdapterTest, TestStreamInitialWindowSizeUpdates) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 80000}});
+  EXPECT_TRUE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  // New stream window size has not yet been applied.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 65535);
+
+  // Server initial SETTINGS
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  // New stream window size has still not been applied.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 65535);
+
+  const std::string ack = TestFrameSequence().SettingsAck().Serialize();
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  adapter->ProcessBytes(ack);
+
+  // New stream window size has finally been applied upon SETTINGS ack.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 80000);
+
+  // Update the stream window size again.
+  adapter->SubmitSettings({{INITIAL_WINDOW_SIZE, 90000}});
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  result = adapter->Send();
+  EXPECT_EQ(0, result);
+
+  // New stream window size has not yet been applied.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 80000);
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  adapter->ProcessBytes(ack);
+
+  // New stream window size is applied after the ack.
+  EXPECT_EQ(adapter->GetStreamReceiveWindowSize(1), 90000);
+}
+
+TEST(OgHttp2AdapterTest, ConnectionErrorOnControlFrameSent) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().Ping(42).Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // PING
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0))
+      .WillOnce(testing::Return(-902));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
+
+  int send_result = adapter->Send();
+  EXPECT_LT(send_result, 0);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  send_result = adapter->Send();
+  EXPECT_LT(send_result, 0);
+}
+
+TEST(OgHttp2AdapterTest, ConnectionErrorOnDataFrameSent) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body->AppendPayload("Here is some data, which will lead to a fatal error");
+  TestDataFrameSource* body_ptr = body.get();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}}), std::move(body));
+  ASSERT_EQ(0, submit_result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server preface (SETTINGS)
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  // SETTINGS ack
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  // Stream 1, with doomed DATA
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0))
+      .WillOnce(testing::Return(-902));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kSendError));
+
+  int send_result = adapter->Send();
+  EXPECT_LT(send_result, 0);
+
+  body_ptr->AppendPayload("After the fatal error, data will be sent no more");
+
+  EXPECT_FALSE(adapter->want_write());
+
+  send_result = adapter->Send();
+  EXPECT_LT(send_result, 0);
+}
+
+TEST(OgHttp2AdapterTest, ClientSendsContinuation) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true,
+                                          /*add_continuation=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 1));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+}
+
+TEST(OgHttp2AdapterTest, ClientSendsMetadataWithContinuation) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Metadata(0, "Example connection metadata in multiple frames", true)
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false,
+                   /*add_continuation=*/true)
+          .Metadata(1,
+                    "Some stream metadata that's also sent in multiple frames",
+                    true)
+          .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Metadata on stream 0
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 0));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(0, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(0));
+
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 4));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  // Metadata on stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 0));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, kMetadataFrameType, 4));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(1, _));
+  EXPECT_CALL(visitor, OnMetadataEndForStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+  EXPECT_EQ("Example connection metadata in multiple frames",
+            absl::StrJoin(visitor.GetMetadata(0), ""));
+  EXPECT_EQ("Some stream metadata that's also sent in multiple frames",
+            absl::StrJoin(visitor.GetMetadata(1), ""));
+}
+
+TEST(OgHttp2AdapterTest, RepeatedHeaderNames) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "text/plain"},
+                                           {"accept", "text/html"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/plain"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "text/html"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  const std::vector<Header> headers1 = ToHeaders(
+      {{":status", "200"}, {"content-length", "10"}, {"content-length", "10"}});
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload("perfection");
+  body1->EndData();
+
+  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
+  ASSERT_EQ(0, submit_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 10, 0x1, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+}
+
+TEST(OgHttp2AdapterTest, ServerRespondsToRequestWithTrailers) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/one"}})
+          .Data(1, "Example data, woohoo.")
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  const std::vector<Header> headers1 = ToHeaders({{":status", "200"}});
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  TestDataFrameSource* body1_ptr = body1.get();
+
+  int submit_result = adapter->SubmitResponse(1, headers1, std::move(body1));
+  ASSERT_EQ(0, submit_result);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::HEADERS}));
+  visitor.Clear();
+
+  const std::string more_frames =
+      TestFrameSequence()
+          .Headers(1, {{"extra-info", "Trailers are weird but good?"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "extra-info",
+                                         "Trailers are weird but good?"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  result = adapter->ProcessBytes(more_frames);
+  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
+
+  body1_ptr->EndData();
+  EXPECT_EQ(true, adapter->ResumeStream(1));
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
+}
+
+TEST(OgHttp2AdapterTest, ServerReceivesMoreHeaderBytesThanConfigured) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .max_header_list_bytes = 42};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"},
+                    {"from-douglas-de-fermat",
+                     "I have discovered a truly marvelous answer to the life, "
+                     "the universe, and everything that the header setting is "
+                     "too narrow to contain."}},
+                   /*fin=*/true)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::COMPRESSION_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerSubmitsResponseWithDataSourceError) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->SimulateError();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  // TODO(birenroy): Send RST_STREAM INTERNAL_ERROR to the client as well.
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::HEADERS}));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  // Since the stream has been closed, it is not possible to submit trailers for
+  // the stream.
+  int trailer_result =
+      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
+  ASSERT_LT(trailer_result, 0);
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, CompleteRequestWithServerResponse) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false)
+          .Data(1, "This is the response body.", /*fin=*/true)
+          .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  int submit_result =
+      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::HEADERS}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, IncompleteRequestWithServerResponse) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  int submit_result =
+      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  // RST_STREAM NO_ERROR option is disabled.
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::HEADERS}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, IncompleteRequestWithServerResponseRstStreamEnabled) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .rst_stream_no_error_when_incomplete = true};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  int submit_result =
+      adapter->SubmitResponse(1, ToHeaders({{":status", "200"}}), nullptr);
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, 4, 0x0, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                    SpdyFrameType::HEADERS, SpdyFrameType::RST_STREAM}));
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, ServerSendsInvalidTrailers) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  EXPECT_FALSE(adapter->want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  const absl::string_view kBody = "This is an example response body.";
+
+  // The body source must indicate that the end of the body is not the end of
+  // the stream.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload(kBody);
+  body1->EndData();
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_THAT(visitor.data(), testing::HasSubstr(kBody));
+  visitor.Clear();
+  EXPECT_FALSE(adapter->want_write());
+
+  // The body source has been exhausted by the call to Send() above.
+  int trailer_result =
+      adapter->SubmitTrailer(1, ToHeaders({{":final-status", "a-ok"}}));
+  ASSERT_EQ(trailer_result, 0);
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesDataWithPadding) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.",
+                                       /*fin=*/true, /*padding_length=*/39)
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25 + 39, DATA, 0x9));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25 + 39));
+  // Note: oghttp2 passes padding information before the actual data.
+  EXPECT_CALL(visitor, OnDataPaddingLength(1, 39));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesHostHeader) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":path", "/this/is/request/one"},
+                                           {"host", "example.com"}},
+                                          /*fin=*/true)
+                                 .Headers(3,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"host", "example.com"}},
+                                          /*fin=*/true)
+                                 .Headers(5,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "foo.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"host", "bar.com"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  visitor.Clear();
+}
+
+// Tests the case where the response body is in the progress of being sent while
+// trailers are queued.
+TEST(OgHttp2AdapterTest, ServerSubmitsTrailersWhileDataDeferred) {
+  DataSavingVisitor visitor;
+  for (const bool queue_trailers : {true, false}) {
+    OgHttp2Adapter::Options options{
+        .perspective = Perspective::kServer,
+        .trailers_require_end_data = queue_trailers};
+    auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+    const std::string frames = TestFrameSequence()
+                                   .ClientPreface()
+                                   .Headers(1,
+                                            {{":method", "POST"},
+                                             {":scheme", "https"},
+                                             {":authority", "example.com"},
+                                             {":path", "/this/is/request/one"}},
+                                            /*fin=*/false)
+                                   .WindowUpdate(1, 2000)
+                                   .Data(1, "This is the request body.")
+                                   .WindowUpdate(0, 2000)
+                                   .Serialize();
+    testing::InSequence s;
+
+    // Client preface (empty SETTINGS)
+    EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+    EXPECT_CALL(visitor, OnSettingsStart());
+    EXPECT_CALL(visitor, OnSettingsEnd());
+
+    EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+    EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+    EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+    EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+    EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+    EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
+    EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+    EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+    EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+    EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+    EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
+
+    const int64_t result = adapter->ProcessBytes(frames);
+    EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+    EXPECT_TRUE(adapter->want_write());
+
+    EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+    EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+    EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+    EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+    int send_result = adapter->Send();
+    EXPECT_EQ(0, send_result);
+    visitor.Clear();
+
+    const absl::string_view kBody = "This is an example response body.";
+
+    // The body source must indicate that the end of the body is not the end of
+    // the stream.
+    auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+    body1->AppendPayload(kBody);
+    auto* body1_ptr = body1.get();
+    int submit_result = adapter->SubmitResponse(
+        1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+        std::move(body1));
+    EXPECT_EQ(submit_result, 0);
+    EXPECT_TRUE(adapter->want_write());
+
+    EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+    EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+    EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+    send_result = adapter->Send();
+    EXPECT_EQ(0, send_result);
+    visitor.Clear();
+    EXPECT_FALSE(adapter->want_write());
+
+    int trailer_result =
+        adapter->SubmitTrailer(1, ToHeaders({{"final-status", "a-ok"}}));
+    ASSERT_EQ(trailer_result, 0);
+    if (queue_trailers) {
+      // Even though there are new trailers to write, the data source has not
+      // finished writing data and is blocked.
+      EXPECT_FALSE(adapter->want_write());
+
+      body1_ptr->EndData();
+      adapter->ResumeStream(1);
+      EXPECT_TRUE(adapter->want_write());
+
+      EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+      EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+
+      send_result = adapter->Send();
+      EXPECT_EQ(0, send_result);
+    } else {
+      // Even though the data source has not finished sending data, the library
+      // will write the trailers anyway.
+      EXPECT_TRUE(adapter->want_write());
+
+      EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+      EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+
+      send_result = adapter->Send();
+      EXPECT_EQ(0, send_result);
+      EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+    }
+  }
+}
+
+TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControl) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 // 70000 bytes of data
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(16384, 'a'))
+                                 .Data(1, std::string(4464, 'a'))
+                                 .Serialize();
+
+  testing::InSequence s;
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
+  // No further frame data or headers are delivered.
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControlWithOneDataFrame) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  // Allow the client to send a DATA frame that exceeds the connection flow
+  // control window.
+  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "POST"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  int64_t process_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Outbound SETTINGS containing MAX_FRAME_SIZE.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  // Ack of client's initial settings.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
+  // overflow the connection-level window. The result should be a GOAWAY.
+  const std::string overflow_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Data(1, std::string(window_overflow_bytes, 'a'))
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
+  // No further frame data is delivered.
+
+  process_result = adapter->ProcessBytes(overflow_frames);
+  EXPECT_EQ(overflow_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientDisobeysConnectionFlowControlAcrossReads) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  // Allow the client to send a DATA frame that exceeds the connection flow
+  // control window.
+  const uint32_t window_overflow_bytes = kInitialFlowControlWindowSize + 1;
+  adapter->SubmitSettings({{MAX_FRAME_SIZE, window_overflow_bytes}});
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "POST"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/false)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  int64_t process_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(process_result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Outbound SETTINGS containing MAX_FRAME_SIZE.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  // Ack of client's initial settings.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Now let the client ack the MAX_FRAME_SIZE SETTINGS and send a DATA frame to
+  // overflow the connection-level window. The result should be a GOAWAY.
+  const std::string overflow_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Data(1, std::string(window_overflow_bytes, 'a'))
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, window_overflow_bytes, DATA, 0x0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
+
+  const size_t chunk_length = 16384;
+  ASSERT_GE(overflow_frames.size(), chunk_length);
+  process_result =
+      adapter->ProcessBytes(overflow_frames.substr(0, chunk_length));
+  EXPECT_EQ(chunk_length, static_cast<size_t>(process_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(GOAWAY, 0, _, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ClientDisobeysStreamFlowControl) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  const std::string more_frames = TestFrameSequence()
+                                      // 70000 bytes of data
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(16384, 'a'))
+                                      .Data(1, std::string(4464, 'a'))
+                                      .Serialize();
+
+  testing::InSequence s;
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+
+  int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  adapter->SubmitWindowUpdate(0, 20000);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::WINDOW_UPDATE}));
+  visitor.Clear();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 16384));
+  EXPECT_CALL(visitor, OnDataForStream(1, _));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 16384, DATA, 0x0));
+  // No further frame data or headers are delivered.
+
+  result = adapter->ProcessBytes(more_frames);
+  EXPECT_EQ(more_frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(
+      visitor,
+      OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                  static_cast<int>(Http2ErrorCode::FLOW_CONTROL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerErrorWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
+      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
+  // Stream WINDOW_UPDATE and DATA frames are not delivered to the visitor.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerErrorWhileHandlingHeadersDropsFrames) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"accept", "some bogus value!"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .Metadata(1, "This is the request metadata.")
+                                 .RstStream(1, Http2ErrorCode::CANCEL)
+                                 .WindowUpdate(0, 2000)
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/false)
+                                 .Metadata(3, "This is the request metadata.",
+                                           /*multiple_frames=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnHeaderForStream(1, "accept", "some bogus value!"))
+      .WillOnce(testing::Return(Http2VisitorInterface::HEADER_RST_STREAM));
+  // Frames for the RST_STREAM-marked stream are not delivered to the visitor.
+  // Note: nghttp2 still delivers control frames and metadata for the stream.
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 2000));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, kMetadataFrameType, 0));
+  EXPECT_CALL(visitor, OnBeginMetadataForStream(3, _));
+  EXPECT_CALL(visitor, OnMetadataForStream(3, "This is the re"))
+      .WillOnce(testing::DoAll(testing::InvokeWithoutArgs([&adapter]() {
+                                 adapter->SubmitRst(
+                                     3, Http2ErrorCode::REFUSED_STREAM);
+                               }),
+                               testing::Return(true)));
+  // The rest of the metadata is not delivered to the visitor.
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  // SETTINGS ack
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerConnectionErrorWhileHandlingHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"Accept", "uppercase, oh boy!"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kHeaderError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_LT(result, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::RST_STREAM,
+                            SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerErrorAfterHandlingHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_LT(result, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+// Exercises the case when a visitor chooses to reject a frame based solely on
+// the frame header, which is a fatal error for the connection.
+TEST(OgHttp2AdapterTest, ServerRejectsFrameHeader) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Ping(64)
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .WindowUpdate(0, 2000)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_LT(result, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerRejectsBeginningOfData) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_LT(result, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerReceivesTooLargeHeader) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .max_header_list_bytes = 64 * 1024,
+                                  .max_header_field_size = 64 * 1024};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  // Due to configuration, the library will accept a maximum of 64kB of huffman
+  // encoded data per header field.
+  const std::string too_large_value = std::string(80 * 1024, 'q');
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"},
+                                           {"x-toobig", too_large_value}},
+                                          /*fin=*/true)
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, END_STREAM));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, 0)).Times(3);
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, CONTINUATION, END_HEADERS));
+  // Further header processing is skipped, as the header field is too large.
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, END_STREAM | END_HEADERS));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, ACK));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, ACK, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerReceivesInvalidAuthority) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "ex|ample.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0x0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0x0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, 4, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, 4, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerRejectsStreamData) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
+  EXPECT_CALL(visitor, OnDataForStream(1, _)).WillOnce(testing::Return(false));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kParseError));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_LT(result, 0);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+// Exercises a naive mutually recursive test client and server. This test fails
+// without recursion guards in OgHttp2Session.
+TEST(OgHttp2AdapterInteractionTest, ClientServerInteractionTest) {
+  MockHttp2Visitor client_visitor;
+  auto client_adapter = OgHttp2Adapter::Create(
+      client_visitor, {.perspective = Perspective::kClient});
+  MockHttp2Visitor server_visitor;
+  auto server_adapter = OgHttp2Adapter::Create(
+      server_visitor, {.perspective = Perspective::kServer});
+
+  // Feeds bytes sent from the client into the server's ProcessBytes.
+  EXPECT_CALL(client_visitor, OnReadyToSend(_))
+      .WillRepeatedly(
+          testing::Invoke(server_adapter.get(), &OgHttp2Adapter::ProcessBytes));
+  // Feeds bytes sent from the server into the client's ProcessBytes.
+  EXPECT_CALL(server_visitor, OnReadyToSend(_))
+      .WillRepeatedly(
+          testing::Invoke(client_adapter.get(), &OgHttp2Adapter::ProcessBytes));
+  // Sets up the server to respond automatically to a request from a client.
+  EXPECT_CALL(server_visitor, OnEndHeadersForStream(_))
+      .WillRepeatedly([&server_adapter](Http2StreamId stream_id) {
+        server_adapter->SubmitResponse(
+            stream_id, ToHeaders({{":status", "200"}}), nullptr);
+        server_adapter->Send();
+        return true;
+      });
+  // Sets up the client to create a new stream automatically when receiving a
+  // response.
+  EXPECT_CALL(client_visitor, OnEndHeadersForStream(_))
+      .WillRepeatedly([&client_adapter,
+                       &client_visitor](Http2StreamId stream_id) {
+        if (stream_id < 10) {
+          const Http2StreamId new_stream_id = stream_id + 2;
+          auto body =
+              absl::make_unique<TestDataFrameSource>(client_visitor, true);
+          body->AppendPayload("This is an example request body.");
+          body->EndData();
+          const int created_stream_id = client_adapter->SubmitRequest(
+              ToHeaders({{":method", "GET"},
+                         {":scheme", "http"},
+                         {":authority", "example.com"},
+                         {":path",
+                          absl::StrCat("/this/is/request/", new_stream_id)}}),
+              std::move(body), nullptr);
+          EXPECT_EQ(new_stream_id, created_stream_id);
+          client_adapter->Send();
+        }
+        return true;
+      });
+
+  // Submit a request to ensure the first stream is created.
+  int stream_id = client_adapter->SubmitRequest(
+      ToHeaders({{":method", "POST"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"}}),
+      nullptr, nullptr);
+  EXPECT_EQ(stream_id, 1);
+
+  client_adapter->Send();
+}
+
+TEST(OgHttp2AdapterInteractionTest,
+     ClientServerInteractionRepeatedHeaderNames) {
+  DataSavingVisitor client_visitor;
+  OgHttp2Adapter::Options client_options{.perspective = Perspective::kClient};
+  auto client_adapter = OgHttp2Adapter::Create(client_visitor, client_options);
+
+  const std::vector<Header> headers1 =
+      ToHeaders({{":method", "GET"},
+                 {":scheme", "http"},
+                 {":authority", "example.com"},
+                 {":path", "/this/is/request/one"},
+                 {"accept", "text/plain"},
+                 {"accept", "text/html"}});
+
+  const int32_t stream_id1 =
+      client_adapter->SubmitRequest(headers1, nullptr, nullptr);
+  ASSERT_GT(stream_id1, 0);
+
+  EXPECT_CALL(client_visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(client_visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(client_visitor, OnBeforeFrameSent(HEADERS, stream_id1, _, 0x5));
+  EXPECT_CALL(client_visitor, OnFrameSent(HEADERS, stream_id1, _, 0x5, 0));
+  int send_result = client_adapter->Send();
+  EXPECT_EQ(0, send_result);
+
+  DataSavingVisitor server_visitor;
+  OgHttp2Adapter::Options server_options{.perspective = Perspective::kServer};
+  auto server_adapter = OgHttp2Adapter::Create(server_visitor, server_options);
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
+  EXPECT_CALL(server_visitor, OnSettingsStart());
+  EXPECT_CALL(server_visitor, OnSetting).Times(testing::AnyNumber());
+  EXPECT_CALL(server_visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(server_visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, ":scheme", "http"));
+  EXPECT_CALL(server_visitor,
+              OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(server_visitor,
+              OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/plain"));
+  EXPECT_CALL(server_visitor, OnHeaderForStream(1, "accept", "text/html"));
+  EXPECT_CALL(server_visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(server_visitor, OnEndStream(1));
+
+  int64_t result = server_adapter->ProcessBytes(client_visitor.data());
+  EXPECT_EQ(client_visitor.data().size(), static_cast<size_t>(result));
+}
+
+TEST(OgHttp2AdapterTest, ServerForbidsNewStreamBelowWatermark) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(3,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(3, "This is the request body.")
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(3, 25));
+  EXPECT_CALL(visitor, OnDataForStream(3, "This is the request body."));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kInvalidNewStreamId));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  EXPECT_EQ(3, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerForbidsWindowUpdateOnIdleStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerForbidsDataOnIdleStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Data(1, "Sorry, out of order")
+                                 .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerForbidsRstStreamOnIdleStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_EQ(0, adapter->GetHighestReceivedStreamId());
+
+  const std::string frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .RstStream(1, Http2ErrorCode::ENHANCE_YOUR_CALM)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  EXPECT_EQ(1, adapter->GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerForbidsNewStreamAboveStreamLimit) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Let the client send a SETTINGS ack and then attempt to open more than the
+  // advertised number of streams. The overflow stream should be rejected.
+  const std::string stream_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":method", "GET"},
+                    {":scheme", "http"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kProtocol));
+  // The oghttp2 stack also signals the error via OnConnectionError().
+  EXPECT_CALL(visitor, OnConnectionError(
+                           ConnectionError::kExceededMaxConcurrentStreams));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
+
+  // The server should send a GOAWAY for this error, even though
+  // OnInvalidFrame() returns true.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerRstStreamsNewStreamAboveStreamLimitBeforeAck) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  adapter->SubmitSettings({{MAX_CONCURRENT_STREAMS, 1}});
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Server initial SETTINGS (with MAX_CONCURRENT_STREAMS) and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // Let the client avoid sending a SETTINGS ack and attempt to open more than
+  // the advertised number of streams. The server should still reject the
+  // overflow stream, albeit with RST_STREAM REFUSED_STREAM instead of GOAWAY.
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":method", "GET"},
+                    {":scheme", "http"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  3, Http2VisitorInterface::InvalidFrameError::kRefusedStream));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
+
+  // The server sends a RST_STREAM for the offending stream.
+  EXPECT_TRUE(adapter->want_write());
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::REFUSED_STREAM)));
+
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerForbidsProtocolPseudoheaderBeforeAck) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .allow_extended_connect = false};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  // The client attempts to send a CONNECT request with the `:protocol`
+  // pseudoheader before receiving the server's SETTINGS frame.
+  const std::string stream1_frames =
+      TestFrameSequence()
+          .Headers(1,
+                   {{":method", "CONNECT"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"},
+                    {":protocol", "websocket"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  int64_t stream_result = adapter->ProcessBytes(stream1_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream1_frames.size());
+
+  // Server initial SETTINGS and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  // The server sends a RST_STREAM for the offending stream.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  // Server settings with ENABLE_CONNECT_PROTOCOL.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+
+  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  // The client attempts to send a CONNECT request with the `:protocol`
+  // pseudoheader before acking the server's SETTINGS frame.
+  const std::string stream3_frames =
+      TestFrameSequence()
+          .Headers(3,
+                   {{":method", "CONNECT"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/two"},
+                    {":protocol", "websocket"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // After sending SETTINGS with `ENABLE_CONNECT_PROTOCOL`, oghttp2 matches
+  // nghttp2 in allowing this, even though the `allow_extended_connect` option
+  // is false.
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+
+  stream_result = adapter->ProcessBytes(stream3_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream3_frames.size());
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, ServerAllowsProtocolPseudoheaderAfterAck) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+  adapter->SubmitSettings({{ENABLE_CONNECT_PROTOCOL, 1}});
+
+  const std::string initial_frames =
+      TestFrameSequence().ClientPreface().Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  // Server initial SETTINGS (with ENABLE_CONNECT_PROTOCOL) and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  visitor.Clear();
+
+  // The client attempts to send a CONNECT request with the `:protocol`
+  // pseudoheader after acking the server's SETTINGS frame.
+  const std::string stream_frames =
+      TestFrameSequence()
+          .SettingsAck()
+          .Headers(1,
+                   {{":method", "CONNECT"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"},
+                    {":protocol", "websocket"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, _, SETTINGS, 0x1));
+  EXPECT_CALL(visitor, OnSettingsAck());
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(static_cast<size_t>(stream_result), stream_frames.size());
+
+  EXPECT_FALSE(adapter->want_write());
+}
+
+TEST(OgHttp2AdapterTest, SkipsSendingFramesForRejectedStream) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string initial_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":method", "GET"},
+                    {":scheme", "http"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/one"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t initial_result = adapter->ProcessBytes(initial_frames);
+  EXPECT_EQ(static_cast<size_t>(initial_result), initial_frames.size());
+
+  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body->AppendPayload("Here is some data, which will be completely ignored!");
+
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}}), std::move(body));
+  ASSERT_EQ(0, submit_result);
+
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+
+  adapter->SubmitWindowUpdate(1, 1024);
+  adapter->SubmitRst(1, Http2ErrorCode::INTERNAL_ERROR);
+
+  // Server initial SETTINGS and SETTINGS ack.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+
+  // The server sends a RST_STREAM for the offending stream.
+  // The response HEADERS, DATA and WINDOW_UPDATE are all ignored.
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::INTERNAL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttpAdapterServerTest, ServerStartsShutdown) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  adapter->SubmitShutdownNotice();
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+}
+
+TEST(OgHttp2AdapterTest, ServerStartsShutdownAfterGoaway) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  EXPECT_FALSE(adapter->want_write());
+
+  adapter->SubmitGoAway(1, Http2ErrorCode::HTTP2_NO_ERROR,
+                        "and don't come back!");
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(GOAWAY, 0, _, 0x0, 0));
+
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+
+  // No-op, since a GOAWAY has previously been enqueued.
+  adapter->SubmitShutdownNotice();
+  EXPECT_FALSE(adapter->want_write());
+}
+
+// Verifies that a connection-level processing error results in repeatedly
+// returning a positive value for ProcessBytes() to mark all data as consumed
+// when the blackhole option is enabled.
+TEST(OgHttp2AdapterTest, ConnectionErrorWithBlackholingData) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .blackhole_data_on_connection_error = true};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(result), frames.size());
+
+  // Ask the connection to process more bytes. Because the option is enabled,
+  // the data should be marked as consumed.
+  const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
+  const int64_t next_result = adapter->ProcessBytes(next_frame);
+  EXPECT_EQ(static_cast<size_t>(next_result), next_frame.size());
+}
+
+// Verifies that a connection-level processing error results in returning a
+// negative value for ProcessBytes() when the blackhole option is disabled.
+TEST(OgHttp2AdapterTest, ConnectionErrorWithoutBlackholingData) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer,
+                                  .blackhole_data_on_connection_error = false};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames =
+      TestFrameSequence().ClientPreface().WindowUpdate(1, 42).Serialize();
+
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_LT(result, 0);
+
+  // Ask the connection to process more bytes. Because the option is disabled,
+  // ProcessBytes() should continue to return an error.
+  const std::string next_frame = TestFrameSequence().Ping(42).Serialize();
+  const int64_t next_result = adapter->ProcessBytes(next_frame);
+  EXPECT_LT(next_result, 0);
+}
+
+TEST(OgHttp2AdapterTest, ServerDoesNotSendFramesAfterImmediateGoAway) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  // Submit a custom initial SETTINGS frame with one setting.
+  adapter->SubmitSettings({{HEADER_TABLE_SIZE, 100u}});
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 0x5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t read_result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<size_t>(read_result), frames.size());
+
+  // Submit a response for the stream.
+  auto body = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body->AppendPayload("This data is doomed to never be written.");
+  int submit_result = adapter->SubmitResponse(
+      1, ToHeaders({{":status", "200"}}), std::move(body));
+  ASSERT_EQ(0, submit_result);
+
+  // Submit a WINDOW_UPDATE frame.
+  adapter->SubmitWindowUpdate(kConnectionStreamId, 42);
+
+  // Submit another SETTINGS frame.
+  adapter->SubmitSettings({});
+
+  // Submit some metadata.
+  auto source = absl::make_unique<TestMetadataSource>(ToHeaderBlock(ToHeaders(
+      {{"query-cost", "is too darn high"}, {"secret-sauce", "hollandaise"}})));
+  adapter->SubmitMetadata(1, 16384u, std::move(source));
+
+  EXPECT_TRUE(adapter->want_write());
+
+  // Trigger a connection error. Only the response headers will be written.
+  const std::string connection_error_frames =
+      TestFrameSequence().WindowUpdate(3, 42).Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kWrongFrameSequence));
+
+  const int64_t result = adapter->ProcessBytes(connection_error_frames);
+  EXPECT_EQ(static_cast<size_t>(result), connection_error_frames.size());
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 6, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 6, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(GOAWAY, 0, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(GOAWAY, 0, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+
+  int send_result = adapter->Send();
+  // Some bytes should have been serialized.
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::GOAWAY}));
+  visitor.Clear();
+
+  // Try to submit more frames for writing. They should not be written.
+  adapter->SubmitPing(42);
+  // TODO(diannahu): Enable the below expectation.
+  // EXPECT_FALSE(adapter->want_write());
+  send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesContentLength) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/one"},
+                       {"content-length", "2"}})
+          .Data(1, "hi", /*fin=*/true)
+          .Headers(3,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/three"},
+                    {"content-length", "nan"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Stream 1: content-length is correct
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 2));
+  EXPECT_CALL(visitor, OnDataForStream(1, "hi"));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  // Stream 3: content-length is not a number
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesContentLengthMismatch) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/two"},
+                       {"content-length", "2"}})
+          .Data(1, "h", /*fin=*/true)
+          .Headers(3, {{":method", "GET"},
+                       {":scheme", "https"},
+                       {":authority", "example.com"},
+                       {":path", "/this/is/request/three"},
+                       {"content-length", "2"}})
+          .Data(3, "howdy", /*fin=*/true)
+          .Headers(5,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/four"},
+                    {"content-length", "2"}},
+                   /*fin=*/true)
+          .Headers(7,
+                   {{":method", "GET"},
+                    {":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/this/is/request/four"},
+                    {"content-length", "2"}},
+                   /*fin=*/false)
+          .Data(7, "h", /*fin=*/false)
+          .Headers(7, {{"extra-info", "Trailers with content-length mismatch"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Stream 1: content-length is larger than actual data
+  // All data is delivered to the visitor. Note that neither oghttp2 nor
+  // nghttp2 delivers OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 1));
+  EXPECT_CALL(visitor, OnDataForStream(1, "h"));
+
+  // Stream 3: content-length is smaller than actual data
+  // The beginning of data is delivered to the visitor, but not the actual data.
+  // Again, neither oghttp2 nor nghttp2 delivers OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, DATA, 1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(3, 5));
+
+  // Stream 5: content-length is invalid and HEADERS ends the stream
+  // Only oghttp2 invokes OnEndHeadersForStream(). Only nghttp2 invokes
+  // OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(5));
+
+  // Stream 7: content-length is invalid and trailers end the stream
+  // Only oghttp2 invokes OnEndHeadersForStream(). Only nghttp2 invokes
+  // OnInvalidFrame().
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
+  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(7));
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(7, 1));
+  EXPECT_CALL(visitor, OnDataForStream(7, "h"));
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
+  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(7));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 7, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesAsteriskPathForOptions) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::string stream_frames = TestFrameSequence()
+                                        .ClientPreface()
+                                        .Headers(1,
+                                                 {{":scheme", "https"},
+                                                  {":authority", "example.com"},
+                                                  {":path", "*"},
+                                                  {":method", "OPTIONS"}},
+                                                 /*fin=*/true)
+                                        .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesInvalidPath) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "*"},
+                    {":method", "GET"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "other/non/slash/starter"},
+                    {":method", "GET"}},
+                   /*fin=*/true)
+          .Headers(5,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", ""},
+                    {":method", "GET"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  1, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  3, Http2VisitorInterface::InvalidFrameError::kHttpMessaging));
+
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(2);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesTeHeader) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::string stream_frames = TestFrameSequence()
+                                        .ClientPreface()
+                                        .Headers(1,
+                                                 {{":scheme", "https"},
+                                                  {":authority", "example.com"},
+                                                  {":path", "/"},
+                                                  {":method", "GET"},
+                                                  {"te", "trailers"}},
+                                                 /*fin=*/true)
+                                        .Headers(3,
+                                                 {{":scheme", "https"},
+                                                  {":authority", "example.com"},
+                                                  {":path", "/"},
+                                                  {":method", "GET"},
+                                                  {"te", "trailers, deflate"}},
+                                                 /*fin=*/true)
+                                        .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // Stream 1: TE: trailers should be allowed.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(5);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  // Stream 3: TE: <non-trailers> should be rejected.
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerHandlesConnectionSpecificHeaders) {
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{.perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  testing::InSequence s;
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .ClientPreface()
+          .Headers(1,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"connection", "keep-alive"}},
+                   /*fin=*/true)
+          .Headers(3,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"proxy-connection", "keep-alive"}},
+                   /*fin=*/true)
+          .Headers(5,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"keep-alive", "timeout=42"}},
+                   /*fin=*/true)
+          .Headers(7,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"transfer-encoding", "chunked"}},
+                   /*fin=*/true)
+          .Headers(9,
+                   {{":scheme", "https"},
+                    {":authority", "example.com"},
+                    {":path", "/"},
+                    {":method", "GET"},
+                    {"upgrade", "h2c"}},
+                   /*fin=*/true)
+          .Serialize();
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  // All streams contain a connection-specific header and should be rejected.
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(1, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(3, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(5, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(5));
+  EXPECT_CALL(visitor, OnHeaderForStream(5, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(5, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(7, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(7));
+  EXPECT_CALL(visitor, OnHeaderForStream(7, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(7, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+  EXPECT_CALL(visitor, OnFrameHeader(9, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(9));
+  EXPECT_CALL(visitor, OnHeaderForStream(9, _, _)).Times(4);
+  EXPECT_CALL(
+      visitor,
+      OnInvalidFrame(9, Http2VisitorInterface::InvalidFrameError::kHttpHeader));
+
+  const int64_t stream_result = adapter->ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 1, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 3, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 3, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 5, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 5, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 7, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 7, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(7, Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 9, _, 0x0));
+  EXPECT_CALL(visitor,
+              OnFrameSent(RST_STREAM, 9, _, 0x0,
+                          static_cast<int>(Http2ErrorCode::PROTOCOL_ERROR)));
+  EXPECT_CALL(visitor, OnCloseStream(9, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  EXPECT_TRUE(adapter->want_write());
+  int result = adapter->Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(
+      visitor.data(),
+      EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM, SpdyFrameType::RST_STREAM,
+                    SpdyFrameType::RST_STREAM}));
+}
+
+TEST(OgHttp2AdapterTest, ServerUsesCustomWindowUpdateStrategy) {
+  // Test the use of a custom WINDOW_UPDATE strategy.
+  DataSavingVisitor visitor;
+  OgHttp2Adapter::Options options{
+      .should_window_update_fn = [](int64_t /*limit*/, int64_t /*size*/,
+                                    int64_t /*delta*/) { return true; },
+      .perspective = Perspective::kServer};
+  auto adapter = OgHttp2Adapter::Create(visitor, options);
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .Data(1, "This is the request body.",
+                                       /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, _, _)).Times(4);
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, DATA, 0x1));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, _));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = adapter->ProcessBytes(frames);
+  EXPECT_EQ(static_cast<int64_t>(frames.size()), result);
+
+  // Mark a small number of bytes for the stream as consumed. Because of the
+  // custom WINDOW_UPDATE strategy, the session should send WINDOW_UPDATEs.
+  adapter->MarkDataConsumedForStream(1, 5);
+
+  EXPECT_TRUE(adapter->want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, 0, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, 0, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 1, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 1, 4, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(WINDOW_UPDATE, 0, 4, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(WINDOW_UPDATE, 0, 4, 0x0, 0));
+
+  int send_result = adapter->Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS,
+                            SpdyFrameType::WINDOW_UPDATE,
+                            SpdyFrameType::WINDOW_UPDATE}));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/oghttp2_session.cc b/quiche/http2/adapter/oghttp2_session.cc
new file mode 100644
index 0000000..fec6c06
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_session.cc
@@ -0,0 +1,1869 @@
+#include "quiche/http2/adapter/oghttp2_session.h"
+
+#include <cstdint>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "quiche/http2/adapter/header_validator.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_util.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/oghttp2_util.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+
+namespace {
+
+using ConnectionError = Http2VisitorInterface::ConnectionError;
+using SpdyFramerError = Http2DecoderAdapter::SpdyFramerError;
+
+using ::spdy::SpdySettingsIR;
+
+// #define OGHTTP2_DEBUG_TRACE 1
+
+#ifdef OGHTTP2_DEBUG_TRACE
+const bool kTraceLoggingEnabled = true;
+#else
+const bool kTraceLoggingEnabled = false;
+#endif
+
+const uint32_t kMaxAllowedMetadataFrameSize = 65536u;
+const uint32_t kDefaultHpackTableCapacity = 4096u;
+const uint32_t kMaximumHpackTableCapacity = 65536u;
+
+// Corresponds to NGHTTP2_ERR_CALLBACK_FAILURE.
+const int kSendError = -902;
+
+// TODO(birenroy): Consider incorporating spdy::FlagsSerializionVisitor here.
+class FrameAttributeCollector : public spdy::SpdyFrameVisitor {
+ public:
+  FrameAttributeCollector() = default;
+  void VisitData(const spdy::SpdyDataIR& data) override {
+    frame_type_ = static_cast<uint8_t>(data.frame_type());
+    stream_id_ = data.stream_id();
+    flags_ = (data.fin() ? 0x1 : 0) | (data.padded() ? 0x8 : 0);
+  }
+  void VisitHeaders(const spdy::SpdyHeadersIR& headers) override {
+    frame_type_ = static_cast<uint8_t>(headers.frame_type());
+    stream_id_ = headers.stream_id();
+    flags_ = 0x4 | (headers.fin() ? 0x1 : 0) | (headers.padded() ? 0x8 : 0) |
+             (headers.has_priority() ? 0x20 : 0);
+  }
+  void VisitPriority(const spdy::SpdyPriorityIR& priority) override {
+    frame_type_ = static_cast<uint8_t>(priority.frame_type());
+    frame_type_ = 2;
+    stream_id_ = priority.stream_id();
+  }
+  void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override {
+    frame_type_ = static_cast<uint8_t>(rst_stream.frame_type());
+    frame_type_ = 3;
+    stream_id_ = rst_stream.stream_id();
+    error_code_ = rst_stream.error_code();
+  }
+  void VisitSettings(const spdy::SpdySettingsIR& settings) override {
+    frame_type_ = static_cast<uint8_t>(settings.frame_type());
+    frame_type_ = 4;
+    flags_ = (settings.is_ack() ? 0x1 : 0);
+  }
+  void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override {
+    frame_type_ = static_cast<uint8_t>(push_promise.frame_type());
+    frame_type_ = 5;
+    stream_id_ = push_promise.stream_id();
+    flags_ = (push_promise.padded() ? 0x8 : 0);
+  }
+  void VisitPing(const spdy::SpdyPingIR& ping) override {
+    frame_type_ = static_cast<uint8_t>(ping.frame_type());
+    frame_type_ = 6;
+    flags_ = (ping.is_ack() ? 0x1 : 0);
+  }
+  void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override {
+    frame_type_ = static_cast<uint8_t>(goaway.frame_type());
+    frame_type_ = 7;
+    error_code_ = goaway.error_code();
+  }
+  void VisitWindowUpdate(
+      const spdy::SpdyWindowUpdateIR& window_update) override {
+    frame_type_ = static_cast<uint8_t>(window_update.frame_type());
+    frame_type_ = 8;
+    stream_id_ = window_update.stream_id();
+  }
+  void VisitContinuation(
+      const spdy::SpdyContinuationIR& continuation) override {
+    frame_type_ = static_cast<uint8_t>(continuation.frame_type());
+    stream_id_ = continuation.stream_id();
+    flags_ = continuation.end_headers() ? 0x4 : 0;
+  }
+  void VisitUnknown(const spdy::SpdyUnknownIR& unknown) override {
+    frame_type_ = static_cast<uint8_t>(unknown.frame_type());
+    stream_id_ = unknown.stream_id();
+    flags_ = unknown.flags();
+  }
+  void VisitAltSvc(const spdy::SpdyAltSvcIR& /*altsvc*/) override {}
+  void VisitPriorityUpdate(
+      const spdy::SpdyPriorityUpdateIR& /*priority_update*/) override {}
+  void VisitAcceptCh(const spdy::SpdyAcceptChIR& /*accept_ch*/) override {}
+
+  uint32_t stream_id() { return stream_id_; }
+  uint32_t error_code() { return error_code_; }
+  uint8_t frame_type() { return frame_type_; }
+  uint8_t flags() { return flags_; }
+
+ private:
+  uint32_t stream_id_ = 0;
+  uint32_t error_code_ = 0;
+  uint8_t frame_type_ = 0;
+  uint8_t flags_ = 0;
+};
+
+absl::string_view TracePerspectiveAsString(Perspective p) {
+  switch (p) {
+    case Perspective::kClient:
+      return "OGHTTP2_CLIENT";
+    case Perspective::kServer:
+      return "OGHTTP2_SERVER";
+  }
+  return "OGHTTP2_SERVER";
+}
+
+class RunOnExit {
+ public:
+  RunOnExit() = default;
+  explicit RunOnExit(std::function<void()> f) : f_(std::move(f)) {}
+
+  RunOnExit(const RunOnExit& other) = delete;
+  RunOnExit& operator=(const RunOnExit& other) = delete;
+  RunOnExit(RunOnExit&& other) = delete;
+  RunOnExit& operator=(RunOnExit&& other) = delete;
+
+  ~RunOnExit() {
+    if (f_) {
+      f_();
+    }
+    f_ = {};
+  }
+
+  void emplace(std::function<void()> f) { f_ = std::move(f); }
+
+ private:
+  std::function<void()> f_;
+};
+
+Http2ErrorCode GetHttp2ErrorCode(SpdyFramerError error) {
+  switch (error) {
+    case SpdyFramerError::SPDY_NO_ERROR:
+      return Http2ErrorCode::HTTP2_NO_ERROR;
+    case SpdyFramerError::SPDY_INVALID_STREAM_ID:
+    case SpdyFramerError::SPDY_INVALID_CONTROL_FRAME:
+    case SpdyFramerError::SPDY_INVALID_PADDING:
+    case SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS:
+    case SpdyFramerError::SPDY_UNEXPECTED_FRAME:
+      return Http2ErrorCode::PROTOCOL_ERROR;
+    case SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE:
+    case SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE:
+    case SpdyFramerError::SPDY_OVERSIZED_PAYLOAD:
+      return Http2ErrorCode::FRAME_SIZE_ERROR;
+    case SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
+    case SpdyFramerError::SPDY_HPACK_INDEX_VARINT_ERROR:
+    case SpdyFramerError::SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
+    case SpdyFramerError::SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
+    case SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG:
+    case SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG:
+    case SpdyFramerError::SPDY_HPACK_NAME_HUFFMAN_ERROR:
+    case SpdyFramerError::SPDY_HPACK_VALUE_HUFFMAN_ERROR:
+    case SpdyFramerError::SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
+    case SpdyFramerError::SPDY_HPACK_INVALID_INDEX:
+    case SpdyFramerError::SPDY_HPACK_INVALID_NAME_INDEX:
+    case SpdyFramerError::SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
+    case SpdyFramerError::
+        SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
+    case SpdyFramerError::
+        SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
+    case SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK:
+    case SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG:
+    case SpdyFramerError::SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
+      return Http2ErrorCode::COMPRESSION_ERROR;
+    case SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR:
+    case SpdyFramerError::SPDY_STOP_PROCESSING:
+    case SpdyFramerError::LAST_ERROR:
+      return Http2ErrorCode::INTERNAL_ERROR;
+  }
+  return Http2ErrorCode::INTERNAL_ERROR;
+}
+
+bool IsResponse(HeaderType type) {
+  return type == HeaderType::RESPONSE_100 || type == HeaderType::RESPONSE;
+}
+
+bool StatusIs1xx(absl::string_view status) {
+  return status.size() == 3 && status[0] == '1';
+}
+
+// Returns the upper bound on HPACK encoder table capacity. If not specified in
+// the Options, a reasonable default upper bound is used.
+uint32_t HpackCapacityBound(const OgHttp2Session::Options& o) {
+  return o.max_hpack_encoding_table_capacity.value_or(
+      kMaximumHpackTableCapacity);
+}
+
+bool IsNonAckSettings(const spdy::SpdyFrameIR& frame) {
+  return frame.frame_type() == spdy::SpdyFrameType::SETTINGS &&
+         !reinterpret_cast<const SpdySettingsIR&>(frame).is_ack();
+}
+
+}  // namespace
+
+void OgHttp2Session::PassthroughHeadersHandler::OnHeaderBlockStart() {
+  result_ = Http2VisitorInterface::HEADER_OK;
+  const bool status = visitor_.OnBeginHeadersForStream(stream_id_);
+  if (!status) {
+    QUICHE_VLOG(1)
+        << "Visitor rejected header block, returning HEADER_CONNECTION_ERROR";
+    result_ = Http2VisitorInterface::HEADER_CONNECTION_ERROR;
+  }
+  validator_.StartHeaderBlock();
+}
+
+Http2VisitorInterface::OnHeaderResult InterpretHeaderStatus(
+    HeaderValidator::HeaderStatus status) {
+  switch (status) {
+    case HeaderValidator::HEADER_OK:
+      return Http2VisitorInterface::HEADER_OK;
+    case HeaderValidator::HEADER_FIELD_INVALID:
+      return Http2VisitorInterface::HEADER_FIELD_INVALID;
+    case HeaderValidator::HEADER_FIELD_TOO_LONG:
+      return Http2VisitorInterface::HEADER_RST_STREAM;
+  }
+  return Http2VisitorInterface::HEADER_CONNECTION_ERROR;
+}
+
+void OgHttp2Session::PassthroughHeadersHandler::OnHeader(
+    absl::string_view key,
+    absl::string_view value) {
+  if (result_ != Http2VisitorInterface::HEADER_OK) {
+    QUICHE_VLOG(2) << "Early return; status not HEADER_OK";
+    return;
+  }
+  const HeaderValidator::HeaderStatus validation_result =
+      validator_.ValidateSingleHeader(key, value);
+  if (validation_result != HeaderValidator::HEADER_OK) {
+    QUICHE_VLOG(2) << "Header validation failed with result "
+                   << static_cast<int>(validation_result);
+    result_ = InterpretHeaderStatus(validation_result);
+    return;
+  }
+  result_ = visitor_.OnHeaderForStream(stream_id_, key, value);
+}
+
+void OgHttp2Session::PassthroughHeadersHandler::OnHeaderBlockEnd(
+    size_t /* uncompressed_header_bytes */,
+    size_t /* compressed_header_bytes */) {
+  if (result_ == Http2VisitorInterface::HEADER_OK) {
+    if (!validator_.FinishHeaderBlock(type_)) {
+      QUICHE_VLOG(1) << "FinishHeaderBlock returned false; returning "
+                        "HEADER_HTTP_MESSAGING";
+      result_ = Http2VisitorInterface::HEADER_HTTP_MESSAGING;
+    }
+  }
+  if (frame_contains_fin_ && IsResponse(type_) &&
+      StatusIs1xx(status_header())) {
+    QUICHE_VLOG(1) << "Unexpected end of stream without final headers";
+    result_ = Http2VisitorInterface::HEADER_HTTP_MESSAGING;
+  }
+  if (result_ == Http2VisitorInterface::HEADER_OK) {
+    const bool result = visitor_.OnEndHeadersForStream(stream_id_);
+    if (!result) {
+      session_.fatal_visitor_callback_failure_ = true;
+      session_.decoder_.StopProcessing();
+    }
+  } else {
+    session_.OnHeaderStatus(stream_id_, result_);
+  }
+  frame_contains_fin_ = false;
+}
+
+// TODO(diannahu): Add checks for request methods.
+bool OgHttp2Session::PassthroughHeadersHandler::CanReceiveBody() const {
+  switch (header_type()) {
+    case HeaderType::REQUEST_TRAILER:
+    case HeaderType::RESPONSE_TRAILER:
+    case HeaderType::RESPONSE_100:
+      return false;
+    case HeaderType::RESPONSE:
+      // 304 responses should not have a body:
+      // https://httpwg.org/specs/rfc7230.html#rfc.section.3.3.2
+      // Neither should 204 responses:
+      // https://httpwg.org/specs/rfc7231.html#rfc.section.6.3.5
+      return status_header() != "304" && status_header() != "204";
+    case HeaderType::REQUEST:
+      return true;
+  }
+  return true;
+}
+
+// A visitor that extracts an int64_t from each type of a ProcessBytesResult.
+struct OgHttp2Session::ProcessBytesResultVisitor {
+  int64_t operator()(const int64_t bytes) const { return bytes; }
+
+  int64_t operator()(const ProcessBytesError error) const {
+    switch (error) {
+      case ProcessBytesError::kUnspecified:
+        return -1;
+      case ProcessBytesError::kInvalidConnectionPreface:
+        return -903;  // NGHTTP2_ERR_BAD_CLIENT_MAGIC
+      case ProcessBytesError::kVisitorCallbackFailed:
+        return -902;  // NGHTTP2_ERR_CALLBACK_FAILURE
+    }
+    return -1;
+  }
+};
+
+OgHttp2Session::OgHttp2Session(Http2VisitorInterface& visitor, Options options)
+    : visitor_(visitor),
+      event_forwarder_([this]() { return !latched_error_; }, *this),
+      receive_logger_(
+          &event_forwarder_, TracePerspectiveAsString(options.perspective),
+          []() { return kTraceLoggingEnabled; }, this),
+      send_logger_(
+          TracePerspectiveAsString(options.perspective),
+          []() { return kTraceLoggingEnabled; }, this),
+      headers_handler_(*this, visitor),
+      noop_headers_handler_(/*listener=*/nullptr),
+      connection_window_manager_(
+          kInitialFlowControlWindowSize,
+          [this](size_t window_update_delta) {
+            SendWindowUpdate(kConnectionStreamId, window_update_delta);
+          },
+          options.should_window_update_fn,
+          /*update_window_on_notify=*/false),
+      options_(options) {
+  decoder_.set_visitor(&receive_logger_);
+  decoder_.set_extension_visitor(this);
+  if (options_.max_header_list_bytes) {
+    // Limit buffering of encoded HPACK data to 2x the decoded limit.
+    decoder_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
+        2 * *options_.max_header_list_bytes);
+    // Limit the total bytes accepted for HPACK decoding to 4x the limit.
+    decoder_.GetHpackDecoder()->set_max_header_block_bytes(
+        4 * *options_.max_header_list_bytes);
+  }
+  if (IsServerSession()) {
+    remaining_preface_ = {spdy::kHttp2ConnectionHeaderPrefix,
+                          spdy::kHttp2ConnectionHeaderPrefixSize};
+  }
+  if (options_.max_header_field_size.has_value()) {
+    headers_handler_.SetMaxFieldSize(options_.max_header_field_size.value());
+  }
+}
+
+OgHttp2Session::~OgHttp2Session() {}
+
+void OgHttp2Session::SetStreamUserData(Http2StreamId stream_id,
+                                       void* user_data) {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    it->second.user_data = user_data;
+  }
+}
+
+void* OgHttp2Session::GetStreamUserData(Http2StreamId stream_id) {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    return it->second.user_data;
+  }
+  auto p = pending_streams_.find(stream_id);
+  if (p != pending_streams_.end()) {
+    return p->second.user_data;
+  }
+  return nullptr;
+}
+
+bool OgHttp2Session::ResumeStream(Http2StreamId stream_id) {
+  auto it = stream_map_.find(stream_id);
+  if (it == stream_map_.end() || it->second.outbound_body == nullptr ||
+      !write_scheduler_.StreamRegistered(stream_id)) {
+    return false;
+  }
+  it->second.data_deferred = false;
+  write_scheduler_.MarkStreamReady(stream_id, /*add_to_front=*/false);
+  return true;
+}
+
+int OgHttp2Session::GetStreamSendWindowSize(Http2StreamId stream_id) const {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    return it->second.send_window;
+  }
+  return -1;
+}
+
+int OgHttp2Session::GetStreamReceiveWindowLimit(Http2StreamId stream_id) const {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    return it->second.window_manager.WindowSizeLimit();
+  }
+  return -1;
+}
+
+int OgHttp2Session::GetStreamReceiveWindowSize(Http2StreamId stream_id) const {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    return it->second.window_manager.CurrentWindowSize();
+  }
+  return -1;
+}
+
+int OgHttp2Session::GetReceiveWindowSize() const {
+  return connection_window_manager_.CurrentWindowSize();
+}
+
+int OgHttp2Session::GetHpackEncoderDynamicTableSize() const {
+  const spdy::HpackEncoder* encoder = framer_.GetHpackEncoder();
+  return encoder == nullptr ? 0 : encoder->GetDynamicTableSize();
+}
+
+int OgHttp2Session::GetHpackEncoderDynamicTableCapacity() const {
+  const spdy::HpackEncoder* encoder = framer_.GetHpackEncoder();
+  return encoder == nullptr ? kDefaultHpackTableCapacity
+                            : encoder->CurrentHeaderTableSizeSetting();
+}
+
+int OgHttp2Session::GetHpackDecoderDynamicTableSize() const {
+  const spdy::HpackDecoderAdapter* decoder = decoder_.GetHpackDecoder();
+  return decoder == nullptr ? 0 : decoder->GetDynamicTableSize();
+}
+
+int OgHttp2Session::GetHpackDecoderSizeLimit() const {
+  const spdy::HpackDecoderAdapter* decoder = decoder_.GetHpackDecoder();
+  return decoder == nullptr ? 0 : decoder->GetCurrentHeaderTableSizeSetting();
+}
+
+int64_t OgHttp2Session::ProcessBytes(absl::string_view bytes) {
+  QUICHE_VLOG(2) << TracePerspectiveAsString(options_.perspective)
+                 << " processing [" << absl::CEscape(bytes) << "]";
+  return absl::visit(ProcessBytesResultVisitor(), ProcessBytesImpl(bytes));
+}
+
+absl::variant<int64_t, OgHttp2Session::ProcessBytesError>
+OgHttp2Session::ProcessBytesImpl(absl::string_view bytes) {
+  if (processing_bytes_) {
+    QUICHE_VLOG(1) << "Returning early; already processing bytes.";
+    return 0;
+  }
+  processing_bytes_ = true;
+  RunOnExit r{[this]() { processing_bytes_ = false; }};
+
+  if (options_.blackhole_data_on_connection_error && latched_error_) {
+    return static_cast<int64_t>(bytes.size());
+  }
+
+  int64_t preface_consumed = 0;
+  if (!remaining_preface_.empty()) {
+    QUICHE_VLOG(2) << "Preface bytes remaining: " << remaining_preface_.size();
+    // decoder_ does not understand the client connection preface.
+    size_t min_size = std::min(remaining_preface_.size(), bytes.size());
+    if (!absl::StartsWith(remaining_preface_, bytes.substr(0, min_size))) {
+      // Preface doesn't match!
+      QUICHE_DLOG(INFO) << "Preface doesn't match! Expected: ["
+                        << absl::CEscape(remaining_preface_) << "], actual: ["
+                        << absl::CEscape(bytes) << "]";
+      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                          ConnectionError::kInvalidConnectionPreface);
+      return ProcessBytesError::kInvalidConnectionPreface;
+    }
+    remaining_preface_.remove_prefix(min_size);
+    bytes.remove_prefix(min_size);
+    if (!remaining_preface_.empty()) {
+      QUICHE_VLOG(2) << "Preface bytes remaining: "
+                     << remaining_preface_.size();
+      return static_cast<int64_t>(min_size);
+    }
+    preface_consumed = min_size;
+  }
+  int64_t result = decoder_.ProcessInput(bytes.data(), bytes.size());
+  QUICHE_VLOG(2) << "ProcessBytes result: " << result;
+  if (fatal_visitor_callback_failure_) {
+    QUICHE_DCHECK(latched_error_);
+    QUICHE_VLOG(2) << "Visitor callback failed while processing bytes.";
+    return ProcessBytesError::kVisitorCallbackFailed;
+  }
+  if (latched_error_ || result < 0) {
+    QUICHE_VLOG(2) << "ProcessBytes encountered an error.";
+    if (options_.blackhole_data_on_connection_error) {
+      return static_cast<int64_t>(bytes.size() + preface_consumed);
+    } else {
+      return ProcessBytesError::kUnspecified;
+    }
+  }
+  return result + preface_consumed;
+}
+
+int OgHttp2Session::Consume(Http2StreamId stream_id, size_t num_bytes) {
+  auto it = stream_map_.find(stream_id);
+  if (it == stream_map_.end()) {
+    QUICHE_LOG(ERROR) << "Stream " << stream_id << " not found when consuming "
+                      << num_bytes << " bytes";
+  } else {
+    it->second.window_manager.MarkDataFlushed(num_bytes);
+  }
+  connection_window_manager_.MarkDataFlushed(num_bytes);
+  return 0;  // Remove?
+}
+
+void OgHttp2Session::StartGracefulShutdown() {
+  if (IsServerSession()) {
+    if (!queued_goaway_) {
+      EnqueueFrame(absl::make_unique<spdy::SpdyGoAwayIR>(
+          std::numeric_limits<int32_t>::max(), spdy::ERROR_CODE_NO_ERROR,
+          "graceful_shutdown"));
+    }
+  } else {
+    QUICHE_LOG(ERROR) << "Graceful shutdown not needed for clients.";
+  }
+}
+
+void OgHttp2Session::EnqueueFrame(std::unique_ptr<spdy::SpdyFrameIR> frame) {
+  if (queued_immediate_goaway_) {
+    // Do not allow additional frames to be enqueued after the GOAWAY.
+    return;
+  }
+
+  const bool is_non_ack_settings = IsNonAckSettings(*frame);
+  MaybeSetupPreface(is_non_ack_settings);
+
+  if (frame->frame_type() == spdy::SpdyFrameType::GOAWAY) {
+    queued_goaway_ = true;
+    if (latched_error_) {
+      PrepareForImmediateGoAway();
+    }
+  } else if (frame->fin() ||
+             frame->frame_type() == spdy::SpdyFrameType::RST_STREAM) {
+    auto iter = stream_map_.find(frame->stream_id());
+    if (iter != stream_map_.end()) {
+      iter->second.half_closed_local = true;
+    }
+    if (frame->frame_type() == spdy::SpdyFrameType::RST_STREAM) {
+      // TODO(diannahu): Condition on existence in the stream map?
+      streams_reset_.insert(frame->stream_id());
+    }
+  } else if (frame->frame_type() == spdy::SpdyFrameType::WINDOW_UPDATE) {
+    UpdateReceiveWindow(
+        frame->stream_id(),
+        reinterpret_cast<spdy::SpdyWindowUpdateIR&>(*frame).delta());
+  } else if (is_non_ack_settings) {
+    HandleOutboundSettings(
+        *reinterpret_cast<spdy::SpdySettingsIR*>(frame.get()));
+  }
+  if (frame->stream_id() != 0) {
+    auto result = queued_frames_.insert({frame->stream_id(), 1});
+    if (!result.second) {
+      ++(result.first->second);
+    }
+  }
+  frames_.push_back(std::move(frame));
+}
+
+int OgHttp2Session::Send() {
+  if (sending_) {
+    QUICHE_VLOG(1) << TracePerspectiveAsString(options_.perspective)
+                   << " returning early; already sending.";
+    return 0;
+  }
+  sending_ = true;
+  RunOnExit r{[this]() { sending_ = false; }};
+
+  if (fatal_send_error_) {
+    return kSendError;
+  }
+
+  MaybeSetupPreface(/*sending_outbound_settings=*/false);
+
+  SendResult continue_writing = SendQueuedFrames();
+  if (queued_immediate_goaway_) {
+    // If an immediate GOAWAY was queued, then the above flush either sent the
+    // GOAWAY or buffered it to be sent on the next successful flush. In either
+    // case, return early here to avoid sending other frames.
+    return InterpretSendResult(continue_writing);
+  }
+  while (continue_writing == SendResult::SEND_OK &&
+         !connection_metadata_.empty()) {
+    continue_writing = SendMetadata(0, connection_metadata_);
+  }
+  // Wake streams for writes.
+  while (continue_writing == SendResult::SEND_OK && HasReadyStream()) {
+    const Http2StreamId stream_id = GetNextReadyStream();
+    // TODO(birenroy): Add a return value to indicate write blockage, so streams
+    // aren't woken unnecessarily.
+    QUICHE_VLOG(1) << "Waking stream " << stream_id << " for writes.";
+    continue_writing = WriteForStream(stream_id);
+  }
+  if (continue_writing == SendResult::SEND_OK) {
+    continue_writing = SendQueuedFrames();
+  }
+  return InterpretSendResult(continue_writing);
+}
+
+int OgHttp2Session::InterpretSendResult(SendResult result) {
+  if (result == SendResult::SEND_ERROR) {
+    fatal_send_error_ = true;
+    return kSendError;
+  } else {
+    return 0;
+  }
+}
+
+bool OgHttp2Session::HasReadyStream() const {
+  return !metadata_ready_.empty() || !trailers_ready_.empty() ||
+         (write_scheduler_.HasReadyStreams() && connection_send_window_ > 0);
+}
+
+Http2StreamId OgHttp2Session::GetNextReadyStream() {
+  QUICHE_DCHECK(HasReadyStream());
+  if (!metadata_ready_.empty()) {
+    const Http2StreamId stream_id = *metadata_ready_.begin();
+    // WriteForStream() will re-mark the stream as ready, if necessary.
+    write_scheduler_.MarkStreamNotReady(stream_id);
+    return stream_id;
+  }
+  if (!trailers_ready_.empty()) {
+    const Http2StreamId stream_id = *trailers_ready_.begin();
+    // WriteForStream() will re-mark the stream as ready, if necessary.
+    write_scheduler_.MarkStreamNotReady(stream_id);
+    return stream_id;
+  }
+  return write_scheduler_.PopNextReadyStream();
+}
+
+OgHttp2Session::SendResult OgHttp2Session::MaybeSendBufferedData() {
+  int64_t result = std::numeric_limits<int64_t>::max();
+  while (result > 0 && !buffered_data_.empty()) {
+    result = visitor_.OnReadyToSend(buffered_data_);
+    if (result > 0) {
+      buffered_data_.erase(0, result);
+    }
+  }
+  if (result < 0) {
+    LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
+                        ConnectionError::kSendError);
+    return SendResult::SEND_ERROR;
+  }
+  return buffered_data_.empty() ? SendResult::SEND_OK
+                                : SendResult::SEND_BLOCKED;
+}
+
+OgHttp2Session::SendResult OgHttp2Session::SendQueuedFrames() {
+  // Flush any serialized prefix.
+  const SendResult result = MaybeSendBufferedData();
+  if (result != SendResult::SEND_OK) {
+    return result;
+  }
+  // Serialize and send frames in the queue.
+  while (!frames_.empty()) {
+    const auto& frame_ptr = frames_.front();
+    FrameAttributeCollector c;
+    frame_ptr->Visit(&c);
+
+    // DATA frames should never be queued.
+    QUICHE_DCHECK_NE(c.frame_type(), 0);
+
+    const bool stream_reset =
+        c.stream_id() != 0 && streams_reset_.count(c.stream_id()) > 0;
+    if (stream_reset &&
+        c.frame_type() != static_cast<uint8_t>(FrameType::RST_STREAM)) {
+      // The stream has been reset, so any other remaining frames can be
+      // skipped.
+      // TODO(birenroy): inform the visitor of frames that are skipped.
+      DecrementQueuedFrameCount(c.stream_id(), c.frame_type());
+      frames_.pop_front();
+      continue;
+    }
+    // Frames can't accurately report their own length; the actual serialized
+    // length must be used instead.
+    spdy::SpdySerializedFrame frame = framer_.SerializeFrame(*frame_ptr);
+    const size_t frame_payload_length = frame.size() - spdy::kFrameHeaderSize;
+    frame_ptr->Visit(&send_logger_);
+    visitor_.OnBeforeFrameSent(c.frame_type(), c.stream_id(),
+                               frame_payload_length, c.flags());
+    const int64_t result = visitor_.OnReadyToSend(absl::string_view(frame));
+    if (result < 0) {
+      LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
+                          ConnectionError::kSendError);
+      return SendResult::SEND_ERROR;
+    } else if (result == 0) {
+      // Write blocked.
+      return SendResult::SEND_BLOCKED;
+    } else {
+      frames_.pop_front();
+
+      const bool ok =
+          AfterFrameSent(c.frame_type(), c.stream_id(), frame_payload_length,
+                         c.flags(), c.error_code());
+      if (!ok) {
+        LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
+                            ConnectionError::kSendError);
+        return SendResult::SEND_ERROR;
+      }
+      if (static_cast<size_t>(result) < frame.size()) {
+        // The frame was partially written, so the rest must be buffered.
+        buffered_data_.append(frame.data() + result, frame.size() - result);
+        return SendResult::SEND_BLOCKED;
+      }
+    }
+  }
+  return SendResult::SEND_OK;
+}
+
+bool OgHttp2Session::AfterFrameSent(uint8_t frame_type_int, uint32_t stream_id,
+                                    size_t payload_length, uint8_t flags,
+                                    uint32_t error_code) {
+  const FrameType frame_type = static_cast<FrameType>(frame_type_int);
+  int result = visitor_.OnFrameSent(frame_type_int, stream_id, payload_length,
+                                    flags, error_code);
+  if (result < 0) {
+    return false;
+  }
+  if (stream_id == 0) {
+    if (frame_type == FrameType::SETTINGS) {
+      const bool is_settings_ack = (flags & 0x01);
+      if (is_settings_ack && encoder_header_table_capacity_when_acking_) {
+        framer_.UpdateHeaderEncoderTableSize(
+            encoder_header_table_capacity_when_acking_.value());
+        encoder_header_table_capacity_when_acking_ = absl::nullopt;
+      } else if (!is_settings_ack) {
+        sent_non_ack_settings_ = true;
+      }
+    }
+    return true;
+  }
+
+  const bool contains_fin =
+      (frame_type == FrameType::DATA || frame_type == FrameType::HEADERS) &&
+      (flags & 0x01) == 0x01;
+  auto it = stream_map_.find(stream_id);
+  const bool still_open_remote =
+      it != stream_map_.end() && !it->second.half_closed_remote;
+  if (contains_fin && still_open_remote &&
+      options_.rst_stream_no_error_when_incomplete && IsServerSession()) {
+    // Since the peer has not yet ended the stream, this endpoint should
+    // send a RST_STREAM NO_ERROR. See RFC 7540 Section 8.1.
+    frames_.push_front(absl::make_unique<spdy::SpdyRstStreamIR>(
+        stream_id, spdy::SpdyErrorCode::ERROR_CODE_NO_ERROR));
+    auto queued_result = queued_frames_.insert({stream_id, 1});
+    if (!queued_result.second) {
+      ++(queued_result.first->second);
+    }
+    it->second.half_closed_remote = true;
+  }
+
+  DecrementQueuedFrameCount(stream_id, frame_type_int);
+  return true;
+}
+
+OgHttp2Session::SendResult OgHttp2Session::WriteForStream(
+    Http2StreamId stream_id) {
+  auto it = stream_map_.find(stream_id);
+  if (it == stream_map_.end()) {
+    QUICHE_LOG(ERROR) << "Can't find stream " << stream_id
+                      << " which is ready to write!";
+    return SendResult::SEND_OK;
+  }
+  StreamState& state = it->second;
+  auto reset_it = streams_reset_.find(stream_id);
+  if (reset_it != streams_reset_.end()) {
+    // The stream has been reset; there's no point in sending DATA or trailing
+    // HEADERS.
+    state.outbound_body = nullptr;
+    state.trailers = nullptr;
+    state.outbound_metadata.clear();
+    return SendResult::SEND_OK;
+  }
+  SendResult connection_can_write = SendResult::SEND_OK;
+  if (!state.outbound_metadata.empty()) {
+    connection_can_write = SendMetadata(stream_id, state.outbound_metadata);
+  }
+
+  if (state.outbound_body == nullptr ||
+      (!options_.trailers_require_end_data && state.data_deferred)) {
+    // No data to send, but there might be trailers.
+    if (state.trailers != nullptr) {
+      // Trailers will include END_STREAM, so the data source can be discarded.
+      // Since data_deferred is true, there is no data waiting to be flushed for
+      // this stream.
+      state.outbound_body = nullptr;
+      auto block_ptr = std::move(state.trailers);
+      if (state.half_closed_local) {
+        QUICHE_LOG(ERROR) << "Sent fin; can't send trailers.";
+      } else {
+        SendTrailers(stream_id, std::move(*block_ptr));
+      }
+    }
+    return SendResult::SEND_OK;
+  }
+  int32_t available_window =
+      std::min({connection_send_window_, state.send_window,
+                static_cast<int32_t>(max_frame_payload_)});
+  while (connection_can_write == SendResult::SEND_OK && available_window > 0 &&
+         state.outbound_body != nullptr && !state.data_deferred) {
+    auto [length, end_data] =
+        state.outbound_body->SelectPayloadLength(available_window);
+    QUICHE_VLOG(2) << "WriteForStream | length: " << length
+                   << " end_data: " << end_data
+                   << " trailers: " << state.trailers.get();
+    if (length == 0 && !end_data &&
+        (options_.trailers_require_end_data || state.trailers == nullptr)) {
+      // An unproductive call to SelectPayloadLength() results in this stream
+      // entering the "deferred" state only if either no trailers are available
+      // to send, or trailers require an explicit end_data before being sent.
+      state.data_deferred = true;
+      break;
+    } else if (length == DataFrameSource::kError) {
+      // TODO(birenroy): Consider queuing a RST_STREAM INTERNAL_ERROR instead.
+      CloseStream(stream_id, Http2ErrorCode::INTERNAL_ERROR);
+      // No more work on the stream; it has been closed.
+      break;
+    }
+    const bool fin = end_data ? state.outbound_body->send_fin() : false;
+    if (length > 0 || fin) {
+      spdy::SpdyDataIR data(stream_id);
+      data.set_fin(fin);
+      data.SetDataShallow(length);
+      spdy::SpdySerializedFrame header =
+          spdy::SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
+              data);
+      QUICHE_DCHECK(buffered_data_.empty() && frames_.empty());
+      const bool success =
+          state.outbound_body->Send(absl::string_view(header), length);
+      if (!success) {
+        connection_can_write = SendResult::SEND_BLOCKED;
+        break;
+      }
+      connection_send_window_ -= length;
+      state.send_window -= length;
+      available_window = std::min({connection_send_window_, state.send_window,
+                                   static_cast<int32_t>(max_frame_payload_)});
+      if (fin) {
+        state.half_closed_local = true;
+        MaybeFinWithRstStream(it);
+      }
+      const bool ok =
+          AfterFrameSent(/* DATA */ 0, stream_id, length, fin ? 0x1 : 0x0, 0);
+      if (!ok) {
+        LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
+                            ConnectionError::kSendError);
+        return SendResult::SEND_ERROR;
+      }
+      if (!stream_map_.contains(stream_id)) {
+        // Note: the stream may have been closed if `fin` is true.
+        break;
+      }
+    }
+    if (end_data || (length == 0 && state.trailers != nullptr &&
+                     !options_.trailers_require_end_data)) {
+      // If SelectPayloadLength() returned {0, false}, and there are trailers to
+      // send, and the safety feature is disabled, it's okay to send the
+      // trailers.
+      if (state.trailers != nullptr) {
+        auto block_ptr = std::move(state.trailers);
+        if (fin) {
+          QUICHE_LOG(ERROR) << "Sent fin; can't send trailers.";
+        } else {
+          SendTrailers(stream_id, std::move(*block_ptr));
+        }
+      }
+      state.outbound_body = nullptr;
+    }
+  }
+  // If the stream still exists and has data to send, it should be marked as
+  // ready in the write scheduler.
+  if (stream_map_.contains(stream_id) && !state.data_deferred &&
+      state.send_window > 0 && state.outbound_body != nullptr) {
+    write_scheduler_.MarkStreamReady(stream_id, false);
+  }
+  // Streams can continue writing as long as the connection is not write-blocked
+  // and there is additional flow control quota available.
+  if (connection_can_write != SendResult::SEND_OK) {
+    return connection_can_write;
+  }
+  return connection_send_window_ <= 0 ? SendResult::SEND_BLOCKED
+                                      : SendResult::SEND_OK;
+}
+
+OgHttp2Session::SendResult OgHttp2Session::SendMetadata(
+    Http2StreamId stream_id, OgHttp2Session::MetadataSequence& sequence) {
+  const uint32_t max_payload_size =
+      std::min(kMaxAllowedMetadataFrameSize, max_frame_payload_);
+  auto payload_buffer = absl::make_unique<uint8_t[]>(max_payload_size);
+  while (!sequence.empty()) {
+    MetadataSource& source = *sequence.front();
+
+    auto [written, end_metadata] =
+        source.Pack(payload_buffer.get(), max_payload_size);
+    if (written < 0) {
+      // Did not touch the connection, so perhaps writes are still possible.
+      return SendResult::SEND_OK;
+    }
+    QUICHE_DCHECK_LE(static_cast<size_t>(written), max_payload_size);
+    auto payload = absl::string_view(
+        reinterpret_cast<const char*>(payload_buffer.get()), written);
+    EnqueueFrame(absl::make_unique<spdy::SpdyUnknownIR>(
+        stream_id, kMetadataFrameType, end_metadata ? kMetadataEndFlag : 0u,
+        std::string(payload)));
+    if (end_metadata) {
+      sequence.erase(sequence.begin());
+      metadata_ready_.erase(stream_id);
+    }
+  }
+  return SendQueuedFrames();
+}
+
+int32_t OgHttp2Session::SubmitRequest(
+    absl::Span<const Header> headers,
+    std::unique_ptr<DataFrameSource> data_source, void* user_data) {
+  // TODO(birenroy): return an error for the incorrect perspective
+  const Http2StreamId stream_id = next_stream_id_;
+  next_stream_id_ += 2;
+  if (!pending_streams_.empty() || !CanCreateStream()) {
+    // TODO(diannahu): There should probably be a limit to the number of allowed
+    // pending streams.
+    pending_streams_.insert(
+        {stream_id, PendingStreamState{ToHeaderBlock(headers),
+                                       std::move(data_source), user_data}});
+    StartPendingStreams();
+  } else {
+    StartRequest(stream_id, ToHeaderBlock(headers), std::move(data_source),
+                 user_data);
+  }
+  return stream_id;
+}
+
+int OgHttp2Session::SubmitResponse(
+    Http2StreamId stream_id, absl::Span<const Header> headers,
+    std::unique_ptr<DataFrameSource> data_source) {
+  // TODO(birenroy): return an error for the incorrect perspective
+  auto iter = stream_map_.find(stream_id);
+  if (iter == stream_map_.end()) {
+    QUICHE_LOG(ERROR) << "Unable to find stream " << stream_id;
+    return -501;  // NGHTTP2_ERR_INVALID_ARGUMENT
+  }
+  const bool end_stream = data_source == nullptr;
+  if (!end_stream) {
+    // Add data source to stream state
+    iter->second.outbound_body = std::move(data_source);
+    write_scheduler_.MarkStreamReady(stream_id, false);
+  }
+  SendHeaders(stream_id, ToHeaderBlock(headers), end_stream);
+  return 0;
+}
+
+int OgHttp2Session::SubmitTrailer(Http2StreamId stream_id,
+                                  absl::Span<const Header> trailers) {
+  // TODO(birenroy): Reject trailers when acting as a client?
+  auto iter = stream_map_.find(stream_id);
+  if (iter == stream_map_.end()) {
+    QUICHE_LOG(ERROR) << "Unable to find stream " << stream_id;
+    return -501;  // NGHTTP2_ERR_INVALID_ARGUMENT
+  }
+  StreamState& state = iter->second;
+  if (state.half_closed_local) {
+    QUICHE_LOG(ERROR) << "Stream " << stream_id << " is half closed (local)";
+    return -514;  // NGHTTP2_ERR_INVALID_STREAM_STATE
+  }
+  if (state.trailers != nullptr) {
+    QUICHE_LOG(ERROR) << "Stream " << stream_id
+                      << " already has trailers queued";
+    return -514;  // NGHTTP2_ERR_INVALID_STREAM_STATE
+  }
+  if (state.outbound_body == nullptr) {
+    // Enqueue trailers immediately.
+    SendTrailers(stream_id, ToHeaderBlock(trailers));
+  } else {
+    QUICHE_LOG_IF(ERROR, state.outbound_body->send_fin())
+        << "DataFrameSource will send fin, preventing trailers!";
+    // Save trailers so they can be written once data is done.
+    state.trailers =
+        absl::make_unique<spdy::SpdyHeaderBlock>(ToHeaderBlock(trailers));
+    if (!options_.trailers_require_end_data || !iter->second.data_deferred) {
+      trailers_ready_.insert(stream_id);
+    }
+  }
+  return 0;
+}
+
+void OgHttp2Session::SubmitMetadata(Http2StreamId stream_id,
+                                    std::unique_ptr<MetadataSource> source) {
+  if (stream_id == 0) {
+    connection_metadata_.push_back(std::move(source));
+  } else {
+    auto iter = CreateStream(stream_id);
+    iter->second.outbound_metadata.push_back(std::move(source));
+    metadata_ready_.insert(stream_id);
+  }
+}
+
+void OgHttp2Session::SubmitSettings(absl::Span<const Http2Setting> settings) {
+  auto frame = PrepareSettingsFrame(settings);
+  EnqueueFrame(std::move(frame));
+}
+
+void OgHttp2Session::OnError(SpdyFramerError error,
+                             std::string detailed_error) {
+  QUICHE_VLOG(1) << "Error: "
+                 << http2::Http2DecoderAdapter::SpdyFramerErrorToString(error)
+                 << " details: " << detailed_error;
+  // TODO(diannahu): Consider propagating `detailed_error`.
+  LatchErrorAndNotify(GetHttp2ErrorCode(error), ConnectionError::kParseError);
+}
+
+void OgHttp2Session::OnCommonHeader(spdy::SpdyStreamId stream_id,
+                                    size_t length,
+                                    uint8_t type,
+                                    uint8_t flags) {
+  highest_received_stream_id_ = std::max(static_cast<Http2StreamId>(stream_id),
+                                         highest_received_stream_id_);
+  if (streams_reset_.contains(stream_id)) {
+    return;
+  }
+  const bool result = visitor_.OnFrameHeader(stream_id, length, type, flags);
+  if (!result) {
+    fatal_visitor_callback_failure_ = true;
+    decoder_.StopProcessing();
+  }
+}
+
+void OgHttp2Session::OnDataFrameHeader(spdy::SpdyStreamId stream_id,
+                                       size_t length, bool /*fin*/) {
+  auto iter = stream_map_.find(stream_id);
+  if (iter == stream_map_.end() || streams_reset_.contains(stream_id)) {
+    // The stream does not exist; it could be an error or a benign close, e.g.,
+    // getting data for a stream this connection recently closed.
+    if (static_cast<Http2StreamId>(stream_id) > highest_processed_stream_id_) {
+      // Receiving DATA before HEADERS is a connection error.
+      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                          ConnectionError::kWrongFrameSequence);
+    }
+    return;
+  }
+
+  if (static_cast<int64_t>(length) >
+      connection_window_manager_.CurrentWindowSize()) {
+    // Peer exceeded the connection flow control limit.
+    LatchErrorAndNotify(
+        Http2ErrorCode::FLOW_CONTROL_ERROR,
+        Http2VisitorInterface::ConnectionError::kFlowControlError);
+    return;
+  }
+
+  if (static_cast<int64_t>(length) >
+      iter->second.window_manager.CurrentWindowSize()) {
+    // Peer exceeded the stream flow control limit.
+    EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+        stream_id, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
+    return;
+  }
+
+  const bool result = visitor_.OnBeginDataForStream(stream_id, length);
+  if (!result) {
+    fatal_visitor_callback_failure_ = true;
+    decoder_.StopProcessing();
+  }
+
+  if (!iter->second.can_receive_body && length > 0) {
+    EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+        stream_id, spdy::ERROR_CODE_PROTOCOL_ERROR));
+    return;
+  }
+
+  // Validate against the content-length if it exists.
+  if (iter->second.remaining_content_length.has_value()) {
+    if (length > *iter->second.remaining_content_length) {
+      HandleContentLengthError(stream_id);
+      iter->second.remaining_content_length.reset();
+    } else {
+      *iter->second.remaining_content_length -= length;
+    }
+  }
+}
+
+void OgHttp2Session::OnStreamFrameData(spdy::SpdyStreamId stream_id,
+                                       const char* data,
+                                       size_t len) {
+  // Count the data against flow control, even if the stream is unknown.
+  MarkDataBuffered(stream_id, len);
+
+  if (!stream_map_.contains(stream_id) || streams_reset_.contains(stream_id)) {
+    // If the stream was unknown due to a protocol error, the visitor was
+    // informed in OnDataFrameHeader().
+    return;
+  }
+
+  const bool result =
+      visitor_.OnDataForStream(stream_id, absl::string_view(data, len));
+  if (!result) {
+    fatal_visitor_callback_failure_ = true;
+    decoder_.StopProcessing();
+  }
+}
+
+void OgHttp2Session::OnStreamEnd(spdy::SpdyStreamId stream_id) {
+  auto iter = stream_map_.find(stream_id);
+  if (iter != stream_map_.end()) {
+    iter->second.half_closed_remote = true;
+    if (streams_reset_.contains(stream_id)) {
+      return;
+    }
+
+    // Validate against the content-length if it exists.
+    if (iter->second.remaining_content_length.has_value() &&
+        *iter->second.remaining_content_length != 0) {
+      HandleContentLengthError(stream_id);
+      return;
+    }
+
+    visitor_.OnEndStream(stream_id);
+  }
+
+  auto queued_frames_iter = queued_frames_.find(stream_id);
+  const bool no_queued_frames = queued_frames_iter == queued_frames_.end() ||
+                                queued_frames_iter->second == 0;
+  if (iter != stream_map_.end() && iter->second.half_closed_local &&
+      !IsServerSession() && no_queued_frames) {
+    // From the client's perspective, the stream can be closed if it's already
+    // half_closed_local.
+    CloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR);
+  }
+}
+
+void OgHttp2Session::OnStreamPadLength(spdy::SpdyStreamId stream_id,
+                                       size_t value) {
+  bool result = visitor_.OnDataPaddingLength(stream_id, 1 + value);
+  if (!result) {
+    fatal_visitor_callback_failure_ = true;
+    decoder_.StopProcessing();
+  }
+  MarkDataBuffered(stream_id, 1 + value);
+}
+
+void OgHttp2Session::OnStreamPadding(spdy::SpdyStreamId /*stream_id*/, size_t
+                                     /*len*/) {
+  // Flow control was accounted for in OnStreamPadLength().
+  // TODO(181586191): Pass padding to the visitor?
+}
+
+spdy::SpdyHeadersHandlerInterface* OgHttp2Session::OnHeaderFrameStart(
+    spdy::SpdyStreamId stream_id) {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end() && !streams_reset_.contains(stream_id)) {
+    headers_handler_.set_stream_id(stream_id);
+    headers_handler_.set_header_type(
+        NextHeaderType(it->second.received_header_type));
+    return &headers_handler_;
+  } else {
+    return &noop_headers_handler_;
+  }
+}
+
+void OgHttp2Session::OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) {
+  auto it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    if (headers_handler_.header_type() == HeaderType::RESPONSE &&
+        !headers_handler_.status_header().empty() &&
+        headers_handler_.status_header()[0] == '1') {
+      // If response headers carried a 1xx response code, final response headers
+      // should still be forthcoming.
+      headers_handler_.set_header_type(HeaderType::RESPONSE_100);
+    }
+    it->second.received_header_type = headers_handler_.header_type();
+
+    // Track the content-length if the headers indicate that a body can follow.
+    it->second.can_receive_body = headers_handler_.CanReceiveBody();
+    if (it->second.can_receive_body) {
+      it->second.remaining_content_length = headers_handler_.content_length();
+    }
+
+    headers_handler_.set_stream_id(0);
+  }
+}
+
+void OgHttp2Session::OnRstStream(spdy::SpdyStreamId stream_id,
+                                 spdy::SpdyErrorCode error_code) {
+  auto iter = stream_map_.find(stream_id);
+  if (iter != stream_map_.end()) {
+    iter->second.half_closed_remote = true;
+    iter->second.outbound_body = nullptr;
+  } else if (static_cast<Http2StreamId>(stream_id) >
+             highest_processed_stream_id_) {
+    // Receiving RST_STREAM before HEADERS is a connection error.
+    LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                        ConnectionError::kWrongFrameSequence);
+    return;
+  }
+  if (streams_reset_.contains(stream_id)) {
+    return;
+  }
+  visitor_.OnRstStream(stream_id, TranslateErrorCode(error_code));
+  // TODO(birenroy): Consider whether there are outbound frames queued for the
+  // stream.
+  CloseStream(stream_id, TranslateErrorCode(error_code));
+}
+
+void OgHttp2Session::OnSettings() {
+  visitor_.OnSettingsStart();
+  auto settings = absl::make_unique<SpdySettingsIR>();
+  settings->set_is_ack(true);
+  EnqueueFrame(std::move(settings));
+}
+
+void OgHttp2Session::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
+  switch (id) {
+    case MAX_FRAME_SIZE:
+      max_frame_payload_ = value;
+      break;
+    case MAX_CONCURRENT_STREAMS:
+      max_outbound_concurrent_streams_ = value;
+      break;
+    case HEADER_TABLE_SIZE:
+      value = std::min(value, HpackCapacityBound(options_));
+      if (value < framer_.GetHpackEncoder()->CurrentHeaderTableSizeSetting()) {
+        // Safe to apply a smaller table capacity immediately.
+        QUICHE_VLOG(2) << TracePerspectiveAsString(options_.perspective)
+                       << " applying encoder table capacity " << value;
+        framer_.GetHpackEncoder()->ApplyHeaderTableSizeSetting(value);
+      } else {
+        QUICHE_VLOG(2)
+            << TracePerspectiveAsString(options_.perspective)
+            << " NOT applying encoder table capacity until writing ack: "
+            << value;
+        encoder_header_table_capacity_when_acking_ = value;
+      }
+      break;
+    case INITIAL_WINDOW_SIZE:
+      if (value > spdy::kSpdyMaximumWindowSize) {
+        visitor_.OnInvalidFrame(
+            0, Http2VisitorInterface::InvalidFrameError::kFlowControl);
+        // The specification says this is a connection-level flow control error.
+        LatchErrorAndNotify(
+            Http2ErrorCode::FLOW_CONTROL_ERROR,
+            Http2VisitorInterface::ConnectionError::kFlowControlError);
+        return;
+      } else {
+        UpdateStreamSendWindowSizes(value);
+      }
+      break;
+    default:
+      // TODO(bnc): See if C++17 inline constants are allowed in QUICHE.
+      if (id == kMetadataExtensionId) {
+        peer_supports_metadata_ = (value != 0);
+      } else {
+        QUICHE_VLOG(1) << "Unimplemented SETTING id: " << id;
+      }
+  }
+  visitor_.OnSetting({id, value});
+}
+
+void OgHttp2Session::OnSettingsEnd() {
+  visitor_.OnSettingsEnd();
+}
+
+void OgHttp2Session::OnSettingsAck() {
+  if (!settings_ack_callbacks_.empty()) {
+    SettingsAckCallback callback = std::move(settings_ack_callbacks_.front());
+    settings_ack_callbacks_.pop_front();
+    callback();
+  }
+
+  visitor_.OnSettingsAck();
+}
+
+void OgHttp2Session::OnPing(spdy::SpdyPingId unique_id, bool is_ack) {
+  visitor_.OnPing(unique_id, is_ack);
+  if (options_.auto_ping_ack && !is_ack) {
+    auto ping = absl::make_unique<spdy::SpdyPingIR>(unique_id);
+    ping->set_is_ack(true);
+    EnqueueFrame(std::move(ping));
+  }
+}
+
+void OgHttp2Session::OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
+                              spdy::SpdyErrorCode error_code) {
+  received_goaway_ = true;
+  const bool result = visitor_.OnGoAway(last_accepted_stream_id,
+                                        TranslateErrorCode(error_code), "");
+  if (!result) {
+    fatal_visitor_callback_failure_ = true;
+    decoder_.StopProcessing();
+  }
+}
+
+bool OgHttp2Session::OnGoAwayFrameData(const char* /*goaway_data*/, size_t
+                                       /*len*/) {
+  // Opaque data is currently ignored.
+  return true;
+}
+
+void OgHttp2Session::OnHeaders(spdy::SpdyStreamId stream_id,
+                               bool /*has_priority*/, int /*weight*/,
+                               spdy::SpdyStreamId /*parent_stream_id*/,
+                               bool /*exclusive*/, bool fin, bool /*end*/) {
+  if (stream_id % 2 == 0) {
+    // Server push is disabled; receiving push HEADERS is a connection error.
+    LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                        ConnectionError::kInvalidNewStreamId);
+    return;
+  }
+  if (fin) {
+    headers_handler_.set_frame_contains_fin();
+  }
+  if (IsServerSession()) {
+    const auto new_stream_id = static_cast<Http2StreamId>(stream_id);
+    if (stream_map_.find(new_stream_id) != stream_map_.end() && fin) {
+      // Not a new stream, must be trailers.
+      return;
+    }
+    if (new_stream_id <= highest_processed_stream_id_) {
+      // A new stream ID lower than the watermark is a connection error.
+      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                          ConnectionError::kInvalidNewStreamId);
+      return;
+    }
+
+    if (stream_map_.size() >= max_inbound_concurrent_streams_) {
+      // The new stream would exceed our advertised and acknowledged
+      // MAX_CONCURRENT_STREAMS. For parity with nghttp2, treat this error as a
+      // connection-level PROTOCOL_ERROR.
+      bool ok = visitor_.OnInvalidFrame(
+          stream_id, Http2VisitorInterface::InvalidFrameError::kProtocol);
+      if (!ok) {
+        fatal_visitor_callback_failure_ = true;
+      }
+      LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                          ConnectionError::kExceededMaxConcurrentStreams);
+      return;
+    }
+    if (stream_map_.size() >= pending_max_inbound_concurrent_streams_) {
+      // The new stream would exceed our advertised but unacked
+      // MAX_CONCURRENT_STREAMS. Refuse the stream for parity with nghttp2.
+      EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+          stream_id, spdy::ERROR_CODE_REFUSED_STREAM));
+      const bool ok = visitor_.OnInvalidFrame(
+          stream_id, Http2VisitorInterface::InvalidFrameError::kRefusedStream);
+      if (!ok) {
+        fatal_visitor_callback_failure_ = true;
+        LatchErrorAndNotify(Http2ErrorCode::REFUSED_STREAM,
+                            ConnectionError::kExceededMaxConcurrentStreams);
+      }
+      return;
+    }
+
+    CreateStream(stream_id);
+  }
+}
+
+void OgHttp2Session::OnWindowUpdate(spdy::SpdyStreamId stream_id,
+                                    int delta_window_size) {
+  if (stream_id == 0) {
+    connection_send_window_ += delta_window_size;
+  } else {
+    auto it = stream_map_.find(stream_id);
+    if (it == stream_map_.end()) {
+      QUICHE_VLOG(1) << "Stream " << stream_id << " not found!";
+      if (static_cast<Http2StreamId>(stream_id) >
+          highest_processed_stream_id_) {
+        // Receiving WINDOW_UPDATE before HEADERS is a connection error.
+        LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                            ConnectionError::kWrongFrameSequence);
+      }
+      // Do not inform the visitor of a WINDOW_UPDATE for a non-existent stream.
+      return;
+    } else {
+      if (streams_reset_.contains(stream_id)) {
+        return;
+      }
+      if (it->second.send_window == 0) {
+        // The stream was blocked on flow control.
+        QUICHE_VLOG(1) << "Marking stream " << stream_id << " ready to write.";
+        write_scheduler_.MarkStreamReady(stream_id, false);
+      }
+      it->second.send_window += delta_window_size;
+    }
+  }
+  visitor_.OnWindowUpdate(stream_id, delta_window_size);
+}
+
+void OgHttp2Session::OnPushPromise(spdy::SpdyStreamId /*stream_id*/,
+                                   spdy::SpdyStreamId /*promised_stream_id*/,
+                                   bool /*end*/) {
+  // Server push is disabled; PUSH_PROMISE is an invalid frame.
+  LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR,
+                      ConnectionError::kInvalidPushPromise);
+}
+
+void OgHttp2Session::OnContinuation(spdy::SpdyStreamId /*stream_id*/, bool
+                                    /*end*/) {}
+
+void OgHttp2Session::OnAltSvc(spdy::SpdyStreamId /*stream_id*/,
+                              absl::string_view /*origin*/,
+                              const spdy::SpdyAltSvcWireFormat::
+                                  AlternativeServiceVector& /*altsvc_vector*/) {
+}
+
+void OgHttp2Session::OnPriority(spdy::SpdyStreamId /*stream_id*/,
+                                spdy::SpdyStreamId /*parent_stream_id*/,
+                                int /*weight*/, bool /*exclusive*/) {}
+
+void OgHttp2Session::OnPriorityUpdate(
+    spdy::SpdyStreamId /*prioritized_stream_id*/,
+    absl::string_view /*priority_field_value*/) {}
+
+bool OgHttp2Session::OnUnknownFrame(spdy::SpdyStreamId /*stream_id*/,
+                                    uint8_t /*frame_type*/) {
+  return true;
+}
+
+void OgHttp2Session::OnHeaderStatus(
+    Http2StreamId stream_id, Http2VisitorInterface::OnHeaderResult result) {
+  QUICHE_DCHECK_NE(result, Http2VisitorInterface::HEADER_OK);
+  QUICHE_VLOG(1) << "OnHeaderStatus(stream_id=" << stream_id
+                 << ", result=" << result << ")";
+  const bool should_reset_stream =
+      result == Http2VisitorInterface::HEADER_RST_STREAM ||
+      result == Http2VisitorInterface::HEADER_FIELD_INVALID ||
+      result == Http2VisitorInterface::HEADER_HTTP_MESSAGING;
+  if (should_reset_stream) {
+    const Http2ErrorCode error_code =
+        (result == Http2VisitorInterface::HEADER_RST_STREAM)
+            ? Http2ErrorCode::INTERNAL_ERROR
+            : Http2ErrorCode::PROTOCOL_ERROR;
+    const spdy::SpdyErrorCode spdy_error_code = TranslateErrorCode(error_code);
+    const Http2VisitorInterface::InvalidFrameError frame_error =
+        (result == Http2VisitorInterface::HEADER_RST_STREAM ||
+         result == Http2VisitorInterface::HEADER_FIELD_INVALID)
+            ? Http2VisitorInterface::InvalidFrameError::kHttpHeader
+            : Http2VisitorInterface::InvalidFrameError::kHttpMessaging;
+    auto it = streams_reset_.find(stream_id);
+    if (it == streams_reset_.end()) {
+      EnqueueFrame(
+          absl::make_unique<spdy::SpdyRstStreamIR>(stream_id, spdy_error_code));
+
+      if (result == Http2VisitorInterface::HEADER_FIELD_INVALID ||
+          result == Http2VisitorInterface::HEADER_HTTP_MESSAGING) {
+        const bool ok = visitor_.OnInvalidFrame(stream_id, frame_error);
+        if (!ok) {
+          fatal_visitor_callback_failure_ = true;
+          LatchErrorAndNotify(error_code, ConnectionError::kHeaderError);
+        }
+      }
+    }
+  } else if (result == Http2VisitorInterface::HEADER_CONNECTION_ERROR) {
+    fatal_visitor_callback_failure_ = true;
+    LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
+                        ConnectionError::kHeaderError);
+  } else if (result == Http2VisitorInterface::HEADER_COMPRESSION_ERROR) {
+    LatchErrorAndNotify(Http2ErrorCode::COMPRESSION_ERROR,
+                        ConnectionError::kHeaderError);
+  }
+}
+
+bool OgHttp2Session::OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length,
+                                   uint8_t type, uint8_t flags) {
+  if (streams_reset_.contains(stream_id)) {
+    return false;
+  }
+  if (type == kMetadataFrameType) {
+    QUICHE_DCHECK_EQ(metadata_length_, 0u);
+    visitor_.OnBeginMetadataForStream(stream_id, length);
+    metadata_stream_id_ = stream_id;
+    metadata_length_ = length;
+    end_metadata_ = flags & kMetadataEndFlag;
+
+    // Empty metadata payloads will not trigger OnFramePayload(), so handle
+    // that possibility here.
+    MaybeHandleMetadataEndForStream(metadata_stream_id_);
+
+    return true;
+  } else {
+    QUICHE_DLOG(INFO) << "Unexpected frame type " << static_cast<int>(type)
+                      << " received by the extension visitor.";
+    return false;
+  }
+}
+
+void OgHttp2Session::OnFramePayload(const char* data, size_t len) {
+  if (streams_reset_.contains(metadata_stream_id_)) {
+    return;
+  }
+  if (metadata_length_ > 0) {
+    QUICHE_DCHECK_LE(len, metadata_length_);
+    const bool payload_success = visitor_.OnMetadataForStream(
+        metadata_stream_id_, absl::string_view(data, len));
+    if (payload_success) {
+      metadata_length_ -= len;
+      MaybeHandleMetadataEndForStream(metadata_stream_id_);
+    } else {
+      fatal_visitor_callback_failure_ = true;
+      decoder_.StopProcessing();
+    }
+  } else {
+    QUICHE_DLOG(INFO) << "Unexpected metadata payload for stream "
+                      << metadata_stream_id_;
+  }
+}
+
+void OgHttp2Session::MaybeSetupPreface(bool sending_outbound_settings) {
+  if (!queued_preface_) {
+    queued_preface_ = true;
+    if (!IsServerSession()) {
+      buffered_data_.assign(spdy::kHttp2ConnectionHeaderPrefix,
+                            spdy::kHttp2ConnectionHeaderPrefixSize);
+    }
+    if (!sending_outbound_settings) {
+      QUICHE_DCHECK(frames_.empty());
+      // First frame must be a non-ack SETTINGS.
+      EnqueueFrame(PrepareSettingsFrame(GetInitialSettings()));
+    }
+  }
+}
+
+std::vector<Http2Setting> OgHttp2Session::GetInitialSettings() const {
+  std::vector<Http2Setting> settings;
+  if (!IsServerSession()) {
+    // Disable server push. Note that server push from clients is already
+    // disabled, so the server does not need to send this disabling setting.
+    // TODO(diannahu): Consider applying server push disabling on SETTINGS ack.
+    settings.push_back({Http2KnownSettingsId::ENABLE_PUSH, 0});
+  }
+  if (options_.max_header_list_bytes) {
+    settings.push_back({Http2KnownSettingsId::MAX_HEADER_LIST_SIZE,
+                        *options_.max_header_list_bytes});
+  }
+  if (options_.allow_extended_connect && IsServerSession()) {
+    settings.push_back({Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u});
+  }
+  return settings;
+}
+
+std::unique_ptr<SpdySettingsIR> OgHttp2Session::PrepareSettingsFrame(
+    absl::Span<const Http2Setting> settings) {
+  auto settings_ir = absl::make_unique<SpdySettingsIR>();
+  for (const Http2Setting& setting : settings) {
+    settings_ir->AddSetting(setting.id, setting.value);
+  }
+  return settings_ir;
+}
+
+void OgHttp2Session::HandleOutboundSettings(
+    const spdy::SpdySettingsIR& settings_frame) {
+  for (const auto& [id, value] : settings_frame.values()) {
+    switch (static_cast<Http2KnownSettingsId>(id)) {
+      case MAX_CONCURRENT_STREAMS:
+        pending_max_inbound_concurrent_streams_ = value;
+        break;
+      case ENABLE_CONNECT_PROTOCOL:
+        if (value == 1u && IsServerSession()) {
+          // Allow extended CONNECT semantics even before SETTINGS are acked, to
+          // make things easier for clients.
+          headers_handler_.AllowConnect();
+        }
+        break;
+      case HEADER_TABLE_SIZE:
+      case ENABLE_PUSH:
+      case INITIAL_WINDOW_SIZE:
+      case MAX_FRAME_SIZE:
+      case MAX_HEADER_LIST_SIZE:
+        QUICHE_VLOG(2)
+            << "Not adjusting internal state for outbound setting with id "
+            << id;
+        break;
+    }
+  }
+
+  // Copy the (small) map of settings we are about to send so that we can set
+  // values in the SETTINGS ack callback.
+  settings_ack_callbacks_.push_back(
+      [this, settings_map = settings_frame.values()]() {
+        for (const auto& [id, value] : settings_map) {
+          switch (static_cast<Http2KnownSettingsId>(id)) {
+            case MAX_CONCURRENT_STREAMS:
+              max_inbound_concurrent_streams_ = value;
+              break;
+            case HEADER_TABLE_SIZE:
+              decoder_.GetHpackDecoder()->ApplyHeaderTableSizeSetting(value);
+              break;
+            case INITIAL_WINDOW_SIZE:
+              UpdateStreamReceiveWindowSizes(value);
+              initial_stream_receive_window_ = value;
+              break;
+            case MAX_FRAME_SIZE:
+              decoder_.SetMaxFrameSize(value);
+              break;
+            case ENABLE_PUSH:
+            case MAX_HEADER_LIST_SIZE:
+            case ENABLE_CONNECT_PROTOCOL:
+              QUICHE_VLOG(2)
+                  << "No action required in ack for outbound setting with id "
+                  << id;
+              break;
+          }
+        }
+      });
+}
+
+void OgHttp2Session::SendWindowUpdate(Http2StreamId stream_id,
+                                      size_t update_delta) {
+  EnqueueFrame(
+      absl::make_unique<spdy::SpdyWindowUpdateIR>(stream_id, update_delta));
+}
+
+void OgHttp2Session::SendHeaders(Http2StreamId stream_id,
+                                 spdy::SpdyHeaderBlock headers,
+                                 bool end_stream) {
+  auto frame =
+      absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(headers));
+  frame->set_fin(end_stream);
+  EnqueueFrame(std::move(frame));
+}
+
+void OgHttp2Session::SendTrailers(Http2StreamId stream_id,
+                                  spdy::SpdyHeaderBlock trailers) {
+  auto frame =
+      absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(trailers));
+  frame->set_fin(true);
+  EnqueueFrame(std::move(frame));
+  trailers_ready_.erase(stream_id);
+}
+
+void OgHttp2Session::MaybeFinWithRstStream(StreamStateMap::iterator iter) {
+  QUICHE_DCHECK(iter != stream_map_.end() && iter->second.half_closed_local);
+
+  if (options_.rst_stream_no_error_when_incomplete && IsServerSession() &&
+      !iter->second.half_closed_remote) {
+    // Since the peer has not yet ended the stream, this endpoint should
+    // send a RST_STREAM NO_ERROR. See RFC 7540 Section 8.1.
+    EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+        iter->first, spdy::SpdyErrorCode::ERROR_CODE_NO_ERROR));
+    iter->second.half_closed_remote = true;
+  }
+}
+
+void OgHttp2Session::MarkDataBuffered(Http2StreamId stream_id, size_t bytes) {
+  connection_window_manager_.MarkDataBuffered(bytes);
+  if (auto it = stream_map_.find(stream_id); it != stream_map_.end()) {
+    it->second.window_manager.MarkDataBuffered(bytes);
+  }
+}
+
+OgHttp2Session::StreamStateMap::iterator OgHttp2Session::CreateStream(
+    Http2StreamId stream_id) {
+  WindowManager::WindowUpdateListener listener =
+      [this, stream_id](size_t window_update_delta) {
+        SendWindowUpdate(stream_id, window_update_delta);
+      };
+  auto [iter, inserted] = stream_map_.try_emplace(
+      stream_id,
+      StreamState(initial_stream_receive_window_, initial_stream_send_window_,
+                  std::move(listener), options_.should_window_update_fn));
+  if (inserted) {
+    // Add the stream to the write scheduler.
+    const WriteScheduler::StreamPrecedenceType precedence(3);
+    write_scheduler_.RegisterStream(stream_id, precedence);
+
+    highest_processed_stream_id_ =
+        std::max(highest_processed_stream_id_, stream_id);
+  }
+  return iter;
+}
+
+void OgHttp2Session::StartRequest(Http2StreamId stream_id,
+                                  spdy::SpdyHeaderBlock headers,
+                                  std::unique_ptr<DataFrameSource> data_source,
+                                  void* user_data) {
+  auto iter = CreateStream(stream_id);
+  const bool end_stream = data_source == nullptr;
+  if (!end_stream) {
+    iter->second.outbound_body = std::move(data_source);
+    write_scheduler_.MarkStreamReady(stream_id, false);
+  }
+  iter->second.user_data = user_data;
+  SendHeaders(stream_id, std::move(headers), end_stream);
+}
+
+void OgHttp2Session::StartPendingStreams() {
+  while (!pending_streams_.empty() && CanCreateStream()) {
+    auto& [stream_id, pending_stream] = pending_streams_.front();
+    StartRequest(stream_id, std::move(pending_stream.headers),
+                 std::move(pending_stream.data_source),
+                 pending_stream.user_data);
+    pending_streams_.pop_front();
+  }
+}
+
+void OgHttp2Session::CloseStream(Http2StreamId stream_id,
+                                 Http2ErrorCode error_code) {
+  const bool result = visitor_.OnCloseStream(stream_id, error_code);
+  if (!result) {
+    latched_error_ = true;
+    decoder_.StopProcessing();
+  }
+  stream_map_.erase(stream_id);
+  trailers_ready_.erase(stream_id);
+  metadata_ready_.erase(stream_id);
+  streams_reset_.erase(stream_id);
+  queued_frames_.erase(stream_id);
+  stream_map_.erase(stream_id);
+  if (write_scheduler_.StreamRegistered(stream_id)) {
+    write_scheduler_.UnregisterStream(stream_id);
+  }
+
+  StartPendingStreams();
+}
+
+bool OgHttp2Session::CanCreateStream() const {
+  return stream_map_.size() < max_outbound_concurrent_streams_;
+}
+
+HeaderType OgHttp2Session::NextHeaderType(
+    absl::optional<HeaderType> current_type) {
+  if (IsServerSession()) {
+    if (!current_type) {
+      return HeaderType::REQUEST;
+    } else {
+      QUICHE_DCHECK(current_type == HeaderType::REQUEST);
+      return HeaderType::REQUEST_TRAILER;
+    }
+  } else if (!current_type ||
+             current_type.value() == HeaderType::RESPONSE_100) {
+    return HeaderType::RESPONSE;
+  } else {
+    return HeaderType::RESPONSE_TRAILER;
+  }
+}
+
+void OgHttp2Session::LatchErrorAndNotify(Http2ErrorCode error_code,
+                                         ConnectionError error) {
+  if (latched_error_) {
+    // Do not kick a connection when it is down.
+    return;
+  }
+
+  latched_error_ = true;
+  visitor_.OnConnectionError(error);
+  decoder_.StopProcessing();
+  EnqueueFrame(absl::make_unique<spdy::SpdyGoAwayIR>(
+      highest_processed_stream_id_, TranslateErrorCode(error_code),
+      ConnectionErrorToString(error)));
+}
+
+void OgHttp2Session::CloseStreamIfReady(uint8_t frame_type,
+                                        uint32_t stream_id) {
+  auto iter = stream_map_.find(stream_id);
+  if (iter == stream_map_.end()) {
+    return;
+  }
+  const StreamState& state = iter->second;
+  if (static_cast<FrameType>(frame_type) == FrameType::RST_STREAM ||
+      (state.half_closed_local && state.half_closed_remote)) {
+    CloseStream(stream_id, Http2ErrorCode::HTTP2_NO_ERROR);
+  }
+}
+
+void OgHttp2Session::PrepareForImmediateGoAway() {
+  queued_immediate_goaway_ = true;
+
+  // Keep the initial SETTINGS frame if the session has SETTINGS at the front of
+  // the queue but has not sent SETTINGS yet. The session should send initial
+  // SETTINGS before GOAWAY.
+  std::unique_ptr<spdy::SpdyFrameIR> initial_settings;
+  if (!sent_non_ack_settings_ && !frames_.empty() &&
+      IsNonAckSettings(*frames_.front())) {
+    initial_settings = std::move(frames_.front());
+    frames_.pop_front();
+  }
+
+  // Remove all pending frames except for RST_STREAMs. It is important to send
+  // RST_STREAMs so the peer knows of errors below the GOAWAY last stream ID.
+  // TODO(diannahu): Consider informing the visitor of dropped frames. This may
+  // mean keeping the frames and invoking a frame-not-sent callback, similar to
+  // nghttp2. Could add a closure to each frame in the frames queue.
+  frames_.remove_if([](const auto& frame) {
+    return frame->frame_type() != spdy::SpdyFrameType::RST_STREAM;
+  });
+
+  if (initial_settings != nullptr) {
+    frames_.push_front(std::move(initial_settings));
+  }
+}
+
+void OgHttp2Session::MaybeHandleMetadataEndForStream(Http2StreamId stream_id) {
+  if (metadata_length_ == 0 && end_metadata_) {
+    const bool completion_success = visitor_.OnMetadataEndForStream(stream_id);
+    if (!completion_success) {
+      fatal_visitor_callback_failure_ = true;
+      decoder_.StopProcessing();
+    }
+    metadata_stream_id_ = 0;
+    end_metadata_ = false;
+  }
+}
+
+void OgHttp2Session::DecrementQueuedFrameCount(uint32_t stream_id,
+                                               uint8_t frame_type) {
+  auto iter = queued_frames_.find(stream_id);
+  if (iter == queued_frames_.end()) {
+    QUICHE_LOG(ERROR) << "Unable to find a queued frame count for stream "
+                      << stream_id;
+    return;
+  }
+  if (static_cast<FrameType>(frame_type) != FrameType::DATA) {
+    --iter->second;
+  }
+  if (iter->second == 0) {
+    // TODO(birenroy): Consider passing through `error_code` here.
+    CloseStreamIfReady(frame_type, stream_id);
+  }
+}
+
+void OgHttp2Session::HandleContentLengthError(Http2StreamId stream_id) {
+  EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+      stream_id, spdy::ERROR_CODE_PROTOCOL_ERROR));
+}
+
+void OgHttp2Session::UpdateReceiveWindow(Http2StreamId stream_id,
+                                         int32_t delta) {
+  if (stream_id == 0) {
+    connection_window_manager_.IncreaseWindow(delta);
+  } else {
+    auto iter = stream_map_.find(stream_id);
+    if (iter != stream_map_.end()) {
+      iter->second.window_manager.IncreaseWindow(delta);
+    }
+  }
+}
+
+void OgHttp2Session::UpdateStreamSendWindowSizes(uint32_t new_value) {
+  const int32_t delta =
+      static_cast<int32_t>(new_value) - initial_stream_send_window_;
+  initial_stream_send_window_ = new_value;
+  for (auto& [stream_id, stream_state] : stream_map_) {
+    const int64_t current_window_size = stream_state.send_window;
+    const int64_t new_window_size = current_window_size + delta;
+    if (new_window_size > spdy::kSpdyMaximumWindowSize) {
+      EnqueueFrame(absl::make_unique<spdy::SpdyRstStreamIR>(
+          stream_id, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
+    } else {
+      stream_state.send_window += delta;
+    }
+    if (current_window_size <= 0 && new_window_size > 0) {
+      write_scheduler_.MarkStreamReady(stream_id, false);
+    }
+  }
+}
+
+void OgHttp2Session::UpdateStreamReceiveWindowSizes(uint32_t new_value) {
+  for (auto& [stream_id, stream_state] : stream_map_) {
+    stream_state.window_manager.OnWindowSizeLimitChange(new_value);
+  }
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/oghttp2_session.h b/quiche/http2/adapter/oghttp2_session.h
new file mode 100644
index 0000000..e7d14fe
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_session.h
@@ -0,0 +1,552 @@
+#ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
+#define QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
+
+#include <cstdint>
+#include <limits>
+#include <list>
+#include <memory>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/variant.h"
+#include "quiche/http2/adapter/data_source.h"
+#include "quiche/http2/adapter/event_forwarder.h"
+#include "quiche/http2/adapter/header_validator.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_session.h"
+#include "quiche/http2/adapter/http2_util.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/adapter/window_manager.h"
+#include "quiche/http2/core/http2_trace_logging.h"
+#include "quiche/http2/core/priority_write_scheduler.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/no_op_headers_handler.h"
+#include "quiche/spdy/core/spdy_framer.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+
+// This class manages state associated with a single multiplexed HTTP/2 session.
+class QUICHE_EXPORT_PRIVATE OgHttp2Session
+    : public Http2Session,
+      public spdy::SpdyFramerVisitorInterface,
+      public spdy::ExtensionVisitorInterface {
+ public:
+  struct QUICHE_EXPORT_PRIVATE Options {
+    // Returns whether to send a WINDOW_UPDATE based on the window limit, window
+    // size, and delta that would be sent in the WINDOW_UPDATE.
+    WindowManager::ShouldWindowUpdateFn should_window_update_fn =
+        DeltaAtLeastHalfLimit;
+    // The perspective of this session.
+    Perspective perspective = Perspective::kClient;
+    // The maximum HPACK table size to use.
+    absl::optional<size_t> max_hpack_encoding_table_capacity = absl::nullopt;
+    // The maximum number of decoded header bytes that a stream can receive.
+    absl::optional<uint32_t> max_header_list_bytes = absl::nullopt;
+    // The maximum size of an individual header field, including name and value.
+    absl::optional<uint32_t> max_header_field_size = absl::nullopt;
+    // Whether to automatically send PING acks when receiving a PING.
+    bool auto_ping_ack = true;
+    // Whether (as server) to send a RST_STREAM NO_ERROR when sending a fin on
+    // an incomplete stream.
+    bool rst_stream_no_error_when_incomplete = false;
+    // Whether (as server) to queue trailers until after a stream's data source
+    // has indicated the end of data. If false, the server will assume that
+    // submitting trailers indicates the end of data.
+    bool trailers_require_end_data = false;
+    // Whether to mark all input data as consumed upon encountering a connection
+    // error while processing bytes. If true, subsequent processing will also
+    // mark all input data as consumed.
+    bool blackhole_data_on_connection_error = true;
+    // Whether to advertise support for the extended CONNECT semantics described
+    // in RFC 8441. If true, this endpoint will send the appropriate setting in
+    // initial SETTINGS.
+    bool allow_extended_connect = true;
+  };
+
+  OgHttp2Session(Http2VisitorInterface& visitor, Options options);
+  ~OgHttp2Session() override;
+
+  // Enqueues a frame for transmission to the peer.
+  void EnqueueFrame(std::unique_ptr<spdy::SpdyFrameIR> frame);
+
+  // Starts a graceful shutdown sequence. No-op if a GOAWAY has already been
+  // sent.
+  void StartGracefulShutdown();
+
+  // Invokes the visitor's OnReadyToSend() method for serialized frames and
+  // DataFrameSource::Send() for data frames.
+  int Send();
+
+  int32_t SubmitRequest(absl::Span<const Header> headers,
+                        std::unique_ptr<DataFrameSource> data_source,
+                        void* user_data);
+  int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
+                     std::unique_ptr<DataFrameSource> data_source);
+  int SubmitTrailer(Http2StreamId stream_id, absl::Span<const Header> trailers);
+  void SubmitMetadata(Http2StreamId stream_id,
+                      std::unique_ptr<MetadataSource> source);
+  void SubmitSettings(absl::Span<const Http2Setting> settings);
+
+  bool IsServerSession() const {
+    return options_.perspective == Perspective::kServer;
+  }
+  Http2StreamId GetHighestReceivedStreamId() const {
+    return highest_received_stream_id_;
+  }
+  void SetStreamUserData(Http2StreamId stream_id, void* user_data);
+  void* GetStreamUserData(Http2StreamId stream_id);
+
+  // Resumes a stream that was previously blocked. Returns true on success.
+  bool ResumeStream(Http2StreamId stream_id);
+
+  // Returns the peer's outstanding stream receive window for the given stream.
+  int GetStreamSendWindowSize(Http2StreamId stream_id) const;
+
+  // Returns the current upper bound on the flow control receive window for this
+  // stream.
+  int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const;
+
+  // Returns the outstanding stream receive window, or -1 if the stream does not
+  // exist.
+  int GetStreamReceiveWindowSize(Http2StreamId stream_id) const;
+
+  // Returns the outstanding connection receive window.
+  int GetReceiveWindowSize() const;
+
+  // Returns the size of the HPACK encoder's dynamic table, including the
+  // per-entry overhead from the specification.
+  int GetHpackEncoderDynamicTableSize() const;
+
+  // Returns the maximum capacity of the HPACK encoder's dynamic table.
+  int GetHpackEncoderDynamicTableCapacity() const;
+
+  // Returns the size of the HPACK decoder's dynamic table, including the
+  // per-entry overhead from the specification.
+  int GetHpackDecoderDynamicTableSize() const;
+
+  // Returns the size of the HPACK decoder's most recently applied size limit.
+  int GetHpackDecoderSizeLimit() const;
+
+  // From Http2Session.
+  int64_t ProcessBytes(absl::string_view bytes) override;
+  int Consume(Http2StreamId stream_id, size_t num_bytes) override;
+  bool want_read() const override {
+    return !received_goaway_ && !decoder_.HasError();
+  }
+  bool want_write() const override {
+    return !fatal_send_error_ &&
+           (!frames_.empty() || !buffered_data_.empty() ||
+            !connection_metadata_.empty() || HasReadyStream());
+  }
+  int GetRemoteWindowSize() const override { return connection_send_window_; }
+
+  // From SpdyFramerVisitorInterface
+  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error) override;
+  void OnCommonHeader(spdy::SpdyStreamId /*stream_id*/,
+                      size_t /*length*/,
+                      uint8_t /*type*/,
+                      uint8_t /*flags*/) override;
+  void OnDataFrameHeader(spdy::SpdyStreamId stream_id,
+                         size_t length,
+                         bool fin) override;
+  void OnStreamFrameData(spdy::SpdyStreamId stream_id,
+                         const char* data,
+                         size_t len) override;
+  void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
+  void OnStreamPadLength(spdy::SpdyStreamId /*stream_id*/,
+                         size_t /*value*/) override;
+  void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
+  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      spdy::SpdyStreamId stream_id) override;
+  void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
+  void OnRstStream(spdy::SpdyStreamId stream_id,
+                   spdy::SpdyErrorCode error_code) override;
+  void OnSettings() override;
+  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck() override;
+  void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
+  void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
+                spdy::SpdyErrorCode error_code) override;
+  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
+  void OnHeaders(spdy::SpdyStreamId stream_id,
+                 bool has_priority,
+                 int weight,
+                 spdy::SpdyStreamId parent_stream_id,
+                 bool exclusive,
+                 bool fin,
+                 bool end) override;
+  void OnWindowUpdate(spdy::SpdyStreamId stream_id,
+                      int delta_window_size) override;
+  void OnPushPromise(spdy::SpdyStreamId stream_id,
+                     spdy::SpdyStreamId promised_stream_id,
+                     bool end) override;
+  void OnContinuation(spdy::SpdyStreamId stream_id, bool end) override;
+  void OnAltSvc(spdy::SpdyStreamId /*stream_id*/, absl::string_view /*origin*/,
+                const spdy::SpdyAltSvcWireFormat::
+                    AlternativeServiceVector& /*altsvc_vector*/) override;
+  void OnPriority(spdy::SpdyStreamId stream_id,
+                  spdy::SpdyStreamId parent_stream_id,
+                  int weight,
+                  bool exclusive) override;
+  void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
+                        absl::string_view priority_field_value) override;
+  bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
+                      uint8_t frame_type) override;
+
+  // Invoked when header processing encounters an invalid or otherwise
+  // problematic header.
+  void OnHeaderStatus(Http2StreamId stream_id,
+                      Http2VisitorInterface::OnHeaderResult result);
+
+  // Returns true if a recognized extension frame is received.
+  bool OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
+                     uint8_t flags) override;
+
+  // Handles the payload for a recognized extension frame.
+  void OnFramePayload(const char* data, size_t len) override;
+
+ private:
+  using MetadataSequence = std::vector<std::unique_ptr<MetadataSource>>;
+
+  struct QUICHE_EXPORT_PRIVATE StreamState {
+    StreamState(int32_t stream_receive_window, int32_t stream_send_window,
+                WindowManager::WindowUpdateListener listener,
+                WindowManager::ShouldWindowUpdateFn should_window_update_fn)
+        : window_manager(stream_receive_window, std::move(listener),
+                         std::move(should_window_update_fn),
+                         /*update_window_on_notify=*/false),
+          send_window(stream_send_window) {}
+
+    WindowManager window_manager;
+    std::unique_ptr<DataFrameSource> outbound_body;
+    MetadataSequence outbound_metadata;
+    std::unique_ptr<spdy::SpdyHeaderBlock> trailers;
+    void* user_data = nullptr;
+    int32_t send_window;
+    absl::optional<HeaderType> received_header_type;
+    absl::optional<size_t> remaining_content_length;
+    bool half_closed_local = false;
+    bool half_closed_remote = false;
+    // Indicates that `outbound_body` temporarily cannot produce data.
+    bool data_deferred = false;
+    bool can_receive_body = true;
+  };
+  using StreamStateMap = absl::flat_hash_map<Http2StreamId, StreamState>;
+
+  struct QUICHE_EXPORT_PRIVATE PendingStreamState {
+    spdy::SpdyHeaderBlock headers;
+    std::unique_ptr<DataFrameSource> data_source;
+    void* user_data = nullptr;
+  };
+
+  class QUICHE_EXPORT_PRIVATE PassthroughHeadersHandler
+      : public spdy::SpdyHeadersHandlerInterface {
+   public:
+    explicit PassthroughHeadersHandler(OgHttp2Session& session,
+                                       Http2VisitorInterface& visitor)
+        : session_(session), visitor_(visitor) {}
+
+    void set_stream_id(Http2StreamId stream_id) {
+      stream_id_ = stream_id;
+      result_ = Http2VisitorInterface::HEADER_OK;
+    }
+
+    void set_frame_contains_fin() { frame_contains_fin_ = true; }
+    void set_header_type(HeaderType type) { type_ = type; }
+    HeaderType header_type() const { return type_; }
+
+    void OnHeaderBlockStart() override;
+    void OnHeader(absl::string_view key, absl::string_view value) override;
+    void OnHeaderBlockEnd(size_t /* uncompressed_header_bytes */,
+                          size_t /* compressed_header_bytes */) override;
+    absl::string_view status_header() const {
+      QUICHE_DCHECK(type_ == HeaderType::RESPONSE ||
+                    type_ == HeaderType::RESPONSE_100);
+      return validator_.status_header();
+    }
+    absl::optional<size_t> content_length() const {
+      return validator_.content_length();
+    }
+    void AllowConnect() { validator_.AllowConnect(); }
+    void SetMaxFieldSize(uint32_t field_size) {
+      validator_.SetMaxFieldSize(field_size);
+    }
+    bool CanReceiveBody() const;
+
+   private:
+    OgHttp2Session& session_;
+    Http2VisitorInterface& visitor_;
+    Http2StreamId stream_id_ = 0;
+    Http2VisitorInterface::OnHeaderResult result_ =
+        Http2VisitorInterface::HEADER_OK;
+    // Validates header blocks according to the HTTP/2 specification.
+    HeaderValidator validator_;
+    HeaderType type_ = HeaderType::RESPONSE;
+    bool frame_contains_fin_ = false;
+  };
+
+  struct QUICHE_EXPORT_PRIVATE ProcessBytesResultVisitor;
+
+  // Queues the connection preface, if not already done. If not
+  // `sending_outbound_settings` and the preface has not yet been queued, this
+  // method will generate and enqueue initial SETTINGS.
+  void MaybeSetupPreface(bool sending_outbound_settings);
+
+  // Gets the settings to be sent in the initial SETTINGS frame sent as part of
+  // the connection preface.
+  std::vector<Http2Setting> GetInitialSettings() const;
+
+  // Prepares and returns a SETTINGS frame with the given `settings`.
+  std::unique_ptr<spdy::SpdySettingsIR> PrepareSettingsFrame(
+      absl::Span<const Http2Setting> settings);
+
+  // Updates internal state to match the SETTINGS advertised to the peer.
+  void HandleOutboundSettings(const spdy::SpdySettingsIR& settings_frame);
+
+  void SendWindowUpdate(Http2StreamId stream_id, size_t update_delta);
+
+  enum class SendResult {
+    // All data was flushed.
+    SEND_OK,
+    // Not all data was flushed (due to flow control or TCP back pressure).
+    SEND_BLOCKED,
+    // An error occurred while sending data.
+    SEND_ERROR,
+  };
+
+  // Returns the int corresponding to the `result`, updating state as needed.
+  int InterpretSendResult(SendResult result);
+
+  enum class ProcessBytesError {
+    // A general, unspecified error.
+    kUnspecified,
+    // The (server-side) session received an invalid client connection preface.
+    kInvalidConnectionPreface,
+    // A user/visitor callback failed with a fatal error.
+    kVisitorCallbackFailed,
+  };
+  using ProcessBytesResult = absl::variant<int64_t, ProcessBytesError>;
+
+  // Attempts to process `bytes` and returns the number of bytes proccessed on
+  // success or the processing error on failure.
+  ProcessBytesResult ProcessBytesImpl(absl::string_view bytes);
+
+  // Returns true if at least one stream has data or control frames to write.
+  bool HasReadyStream() const;
+
+  // Returns the next stream that has something to write. If there are no such
+  // streams, returns zero.
+  Http2StreamId GetNextReadyStream();
+
+  // Sends the buffered connection preface or serialized frame data, if any.
+  SendResult MaybeSendBufferedData();
+
+  // Serializes and sends queued frames.
+  SendResult SendQueuedFrames();
+
+  // Returns false if a fatal connection error occurred.
+  bool AfterFrameSent(uint8_t frame_type_int, uint32_t stream_id,
+                      size_t payload_length, uint8_t flags,
+                      uint32_t error_code);
+
+  // Writes DATA frames for stream `stream_id`.
+  SendResult WriteForStream(Http2StreamId stream_id);
+
+  SendResult SendMetadata(Http2StreamId stream_id, MetadataSequence& sequence);
+
+  void SendHeaders(Http2StreamId stream_id, spdy::SpdyHeaderBlock headers,
+                   bool end_stream);
+
+  void SendTrailers(Http2StreamId stream_id, spdy::SpdyHeaderBlock trailers);
+
+  // Encapsulates the RST_STREAM NO_ERROR behavior described in RFC 7540
+  // Section 8.1.
+  void MaybeFinWithRstStream(StreamStateMap::iterator iter);
+
+  // Performs flow control accounting for data sent by the peer.
+  void MarkDataBuffered(Http2StreamId stream_id, size_t bytes);
+
+  // Creates a stream for `stream_id` if not already present and returns an
+  // iterator pointing to it.
+  StreamStateMap::iterator CreateStream(Http2StreamId stream_id);
+
+  // Creates a stream for `stream_id`, stores the `data_source` and `user_data`
+  // in the stream state, and sends the `headers`.
+  void StartRequest(Http2StreamId stream_id, spdy::SpdyHeaderBlock headers,
+                    std::unique_ptr<DataFrameSource> data_source,
+                    void* user_data);
+
+  // Sends headers for pending streams as long as the stream limit allows.
+  void StartPendingStreams();
+
+  // Closes the given `stream_id` with the given `error_code`.
+  void CloseStream(Http2StreamId stream_id, Http2ErrorCode error_code);
+
+  // Calculates the next expected header type for a stream in a given state.
+  HeaderType NextHeaderType(absl::optional<HeaderType> current_type);
+
+  // Returns true if the session can create a new stream.
+  bool CanCreateStream() const;
+
+  // Informs the visitor of the connection `error` and stops processing on the
+  // connection. If server-side, also sends a GOAWAY with `error_code`.
+  void LatchErrorAndNotify(Http2ErrorCode error_code,
+                           Http2VisitorInterface::ConnectionError error);
+
+  void CloseStreamIfReady(uint8_t frame_type, uint32_t stream_id);
+
+  // Updates internal state to prepare for sending an immediate GOAWAY.
+  void PrepareForImmediateGoAway();
+
+  // Handles the potential end of received metadata for the given `stream_id`.
+  void MaybeHandleMetadataEndForStream(Http2StreamId stream_id);
+
+  void DecrementQueuedFrameCount(uint32_t stream_id, uint8_t frame_type);
+
+  void HandleContentLengthError(Http2StreamId stream_id);
+
+  // Invoked when sending a flow control window update to the peer.
+  void UpdateReceiveWindow(Http2StreamId stream_id, int32_t delta);
+
+  // Updates stream send window accounting to respect the peer's advertised
+  // initial window setting.
+  void UpdateStreamSendWindowSizes(uint32_t new_value);
+
+  // Updates stream receive window managers to use the newly advertised stream
+  // initial window.
+  void UpdateStreamReceiveWindowSizes(uint32_t new_value);
+
+  // Receives events when inbound frames are parsed.
+  Http2VisitorInterface& visitor_;
+
+  // Forwards received events to the session if it can accept them.
+  EventForwarder event_forwarder_;
+
+  // Logs received frames when enabled.
+  Http2TraceLogger receive_logger_;
+  // Logs sent frames when enabled.
+  Http2FrameLogger send_logger_;
+
+  // Encodes outbound frames.
+  spdy::SpdyFramer framer_{spdy::SpdyFramer::ENABLE_COMPRESSION};
+
+  // Decodes inbound frames.
+  http2::Http2DecoderAdapter decoder_;
+
+  // Maintains the state of active streams known to this session.
+  StreamStateMap stream_map_;
+
+  // Maintains the state of pending streams known to this session. A pending
+  // stream is kept in this list until it can be created while complying with
+  // `max_outbound_concurrent_streams_`.
+  quiche::QuicheLinkedHashMap<Http2StreamId, PendingStreamState>
+      pending_streams_;
+
+  // The queue of outbound frames.
+  std::list<std::unique_ptr<spdy::SpdyFrameIR>> frames_;
+  // Buffered data (connection preface, serialized frames) that has not yet been
+  // sent.
+  std::string buffered_data_;
+
+  // Maintains the set of streams ready to write data to the peer.
+  using WriteScheduler = PriorityWriteScheduler<Http2StreamId>;
+  WriteScheduler write_scheduler_;
+
+  // Stores the queue of callbacks to invoke upon receiving SETTINGS acks. At
+  // most one callback is invoked for each SETTINGS ack.
+  using SettingsAckCallback = std::function<void()>;
+  std::list<SettingsAckCallback> settings_ack_callbacks_;
+
+  // Delivers header name-value pairs to the visitor.
+  PassthroughHeadersHandler headers_handler_;
+
+  // Ignores header data, e.g., for an unknown or rejected stream.
+  spdy::NoOpHeadersHandler noop_headers_handler_;
+
+  // Tracks the remaining client connection preface, in the case of a server
+  // session.
+  absl::string_view remaining_preface_;
+
+  WindowManager connection_window_manager_;
+
+  // Tracks the streams that have been marked for reset. A stream is removed
+  // from this set once it is closed.
+  absl::flat_hash_set<Http2StreamId> streams_reset_;
+
+  // The number of frames currently queued per stream.
+  absl::flat_hash_map<Http2StreamId, int> queued_frames_;
+  // Includes streams that are currently ready to write trailers.
+  absl::flat_hash_set<Http2StreamId> trailers_ready_;
+  // Includes streams that are currently ready to write metadata.
+  absl::flat_hash_set<Http2StreamId> metadata_ready_;
+
+  MetadataSequence connection_metadata_;
+
+  Http2StreamId next_stream_id_ = 1;
+  // The highest received stream ID is the highest stream ID in any frame read
+  // from the peer. The highest processed stream ID is the highest stream ID for
+  // which this endpoint created a stream in the stream map.
+  Http2StreamId highest_received_stream_id_ = 0;
+  Http2StreamId highest_processed_stream_id_ = 0;
+  Http2StreamId metadata_stream_id_ = 0;
+  size_t metadata_length_ = 0;
+  int32_t connection_send_window_ = kInitialFlowControlWindowSize;
+  // The initial flow control receive window size for any newly created streams.
+  int32_t initial_stream_receive_window_ = kInitialFlowControlWindowSize;
+  // The initial flow control send window size for any newly created streams.
+  int32_t initial_stream_send_window_ = kInitialFlowControlWindowSize;
+  uint32_t max_frame_payload_ = 16384u;
+  // The maximum number of concurrent streams that this connection can open to
+  // its peer and allow from its peer, respectively. Although the initial value
+  // is unlimited, the spec encourages a value of at least 100. We limit
+  // ourselves to opening 100 until told otherwise by the peer and allow an
+  // unlimited number from the peer until updated from SETTINGS we send.
+  uint32_t max_outbound_concurrent_streams_ = 100u;
+  uint32_t pending_max_inbound_concurrent_streams_ =
+      std::numeric_limits<uint32_t>::max();
+  uint32_t max_inbound_concurrent_streams_ =
+      std::numeric_limits<uint32_t>::max();
+  const Options options_;
+
+  // The HPACK encoder header table capacity that will be applied when
+  // acking SETTINGS from the peer. Only contains a value if the peer advertises
+  // a larger table capacity than currently used; a smaller value can safely be
+  // applied immediately upon receipt.
+  absl::optional<uint32_t> encoder_header_table_capacity_when_acking_;
+
+  bool received_goaway_ = false;
+  bool queued_preface_ = false;
+  bool peer_supports_metadata_ = false;
+  bool end_metadata_ = false;
+  bool sent_non_ack_settings_ = false;
+
+  // Recursion guard for ProcessBytes().
+  bool processing_bytes_ = false;
+  // Recursion guard for Send().
+  bool sending_ = false;
+
+  // Replace this with a stream ID, for multiple GOAWAY support.
+  bool queued_goaway_ = false;
+  bool queued_immediate_goaway_ = false;
+  bool latched_error_ = false;
+
+  // True if a fatal sending error has occurred.
+  bool fatal_send_error_ = false;
+
+  // True if a fatal processing visitor callback failed.
+  bool fatal_visitor_callback_failure_ = false;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
diff --git a/quiche/http2/adapter/oghttp2_session_test.cc b/quiche/http2/adapter/oghttp2_session_test.cc
new file mode 100644
index 0000000..c6ee166
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_session_test.cc
@@ -0,0 +1,920 @@
+#include "quiche/http2/adapter/oghttp2_session.h"
+
+#include "quiche/http2/adapter/mock_http2_visitor.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/http2/adapter/test_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using spdy::SpdyFrameType;
+using testing::_;
+
+enum FrameType {
+  DATA,
+  HEADERS,
+  PRIORITY,
+  RST_STREAM,
+  SETTINGS,
+  PUSH_PROMISE,
+  PING,
+  GOAWAY,
+  WINDOW_UPDATE,
+};
+
+}  // namespace
+
+TEST(OgHttp2SessionTest, ClientConstruction) {
+  testing::StrictMock<MockHttp2Visitor> visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_TRUE(session.want_read());
+  EXPECT_FALSE(session.want_write());
+  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
+  EXPECT_FALSE(session.IsServerSession());
+  EXPECT_EQ(0, session.GetHighestReceivedStreamId());
+}
+
+TEST(OgHttp2SessionTest, ClientHandlesFrames) {
+  testing::StrictMock<MockHttp2Visitor> visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+
+  const std::string initial_frames = TestFrameSequence()
+                                         .ServerPreface()
+                                         .Ping(42)
+                                         .WindowUpdate(0, 1000)
+                                         .Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
+
+  const int64_t initial_result = session.ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  EXPECT_EQ(session.GetRemoteWindowSize(),
+            kInitialFlowControlWindowSize + 1000);
+  EXPECT_EQ(0, session.GetHighestReceivedStreamId());
+
+  // Connection has not yet received any data.
+  EXPECT_EQ(kInitialFlowControlWindowSize, session.GetReceiveWindowSize());
+
+  EXPECT_EQ(0, session.GetHpackDecoderDynamicTableSize());
+
+  // Submit a request to ensure the first stream is created.
+  const char* kSentinel1 = "arbitrary pointer 1";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload("This is an example request body.");
+  body1->EndData();
+  int stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/one"}}),
+                            std::move(body1), const_cast<char*>(kSentinel1));
+  EXPECT_EQ(stream_id, 1);
+
+  // Submit another request to ensure the next stream is created.
+  int stream_id2 =
+      session.SubmitRequest(ToHeaders({{":method", "GET"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/two"}}),
+                            nullptr, nullptr);
+  EXPECT_EQ(stream_id2, 3);
+
+  const std::string stream_frames =
+      TestFrameSequence()
+          .Headers(stream_id,
+                   {{":status", "200"},
+                    {"server", "my-fake-server"},
+                    {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
+                   /*fin=*/false)
+          .Data(stream_id, "This is the response body.")
+          .RstStream(stream_id2, Http2ErrorCode::INTERNAL_ERROR)
+          .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
+          .Serialize();
+
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, ":status", "200"));
+  EXPECT_CALL(visitor,
+              OnHeaderForStream(stream_id, "server", "my-fake-server"));
+  EXPECT_CALL(visitor, OnHeaderForStream(stream_id, "date",
+                                         "Tue, 6 Apr 2021 12:54:01 GMT"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(stream_id));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id, 26, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(stream_id, 26));
+  EXPECT_CALL(visitor,
+              OnDataForStream(stream_id, "This is the response body."));
+  EXPECT_CALL(visitor, OnFrameHeader(stream_id2, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(stream_id2, Http2ErrorCode::INTERNAL_ERROR));
+  EXPECT_CALL(visitor,
+              OnCloseStream(stream_id2, Http2ErrorCode::INTERNAL_ERROR));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 19, GOAWAY, 0));
+  EXPECT_CALL(visitor, OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, ""));
+  const int64_t stream_result = session.ProcessBytes(stream_frames);
+  EXPECT_EQ(stream_frames.size(), static_cast<size_t>(stream_result));
+  EXPECT_EQ(stream_id2, session.GetHighestReceivedStreamId());
+
+  // The first stream is active and has received some data.
+  EXPECT_GT(kInitialFlowControlWindowSize,
+            session.GetStreamReceiveWindowSize(stream_id));
+  // Connection receive window is equivalent to the first stream's.
+  EXPECT_EQ(session.GetReceiveWindowSize(),
+            session.GetStreamReceiveWindowSize(stream_id));
+  // Receive window upper bound is still the initial value.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            session.GetStreamReceiveWindowLimit(stream_id));
+
+  EXPECT_GT(session.GetHpackDecoderDynamicTableSize(), 0);
+}
+
+// Verifies that a client session enqueues initial SETTINGS if Send() is called
+// before any frames are explicitly queued.
+TEST(OgHttp2SessionTest, ClientEnqueuesSettingsOnSend) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_FALSE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+// Verifies that a client session enqueues initial SETTINGS before whatever
+// frame type is passed to the first invocation of EnqueueFrame().
+TEST(OgHttp2SessionTest, ClientEnqueuesSettingsBeforeOtherFrame) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_FALSE(session.want_write());
+  session.EnqueueFrame(absl::make_unique<spdy::SpdyPingIR>(42));
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, 8, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, 8, 0x0, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
+}
+
+// Verifies that if the first call to EnqueueFrame() passes a SETTINGS frame,
+// the client session will not enqueue an additional SETTINGS frame.
+TEST(OgHttp2SessionTest, ClientEnqueuesSettingsOnce) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_FALSE(session.want_write());
+  session.EnqueueFrame(absl::make_unique<spdy::SpdySettingsIR>());
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2SessionTest, ClientSubmitRequest) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+
+  EXPECT_FALSE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  // Even though the user has not queued any frames for the session, it should
+  // still send the connection preface.
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  // Initial SETTINGS.
+  EXPECT_THAT(serialized, EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  const std::string initial_frames =
+      TestFrameSequence().ServerPreface().Serialize();
+  testing::InSequence s;
+
+  // Server preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  const int64_t initial_result = session.ProcessBytes(initial_frames);
+  EXPECT_EQ(initial_frames.size(), static_cast<size_t>(initial_result));
+
+  // Session will want to write a SETTINGS ack.
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_EQ(0, session.GetHpackEncoderDynamicTableSize());
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload("This is an example request body.");
+  body1->EndData();
+  int stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/one"}}),
+                            std::move(body1), const_cast<char*>(kSentinel1));
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(session.want_write());
+  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({spdy::SpdyFrameType::HEADERS,
+                                            spdy::SpdyFrameType::DATA}));
+  visitor.Clear();
+  EXPECT_FALSE(session.want_write());
+
+  // Some data was sent, so the remaining send window size should be less than
+  // the default.
+  EXPECT_LT(session.GetStreamSendWindowSize(stream_id),
+            kInitialFlowControlWindowSize);
+  EXPECT_GT(session.GetStreamSendWindowSize(stream_id), 0);
+  // Send window for a nonexistent stream is not available.
+  EXPECT_EQ(-1, session.GetStreamSendWindowSize(stream_id + 2));
+
+  EXPECT_GT(session.GetHpackEncoderDynamicTableSize(), 0);
+
+  stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/two"}}),
+                            nullptr, nullptr);
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(session.want_write());
+  const char* kSentinel2 = "arbitrary pointer 2";
+  EXPECT_EQ(nullptr, session.GetStreamUserData(stream_id));
+  session.SetStreamUserData(stream_id, const_cast<char*>(kSentinel2));
+  EXPECT_EQ(kSentinel2, session.GetStreamUserData(stream_id));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x5, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({spdy::SpdyFrameType::HEADERS}));
+
+  // No data was sent (just HEADERS), so the remaining send window size should
+  // still be the default.
+  EXPECT_EQ(session.GetStreamSendWindowSize(stream_id),
+            kInitialFlowControlWindowSize);
+}
+
+// This test exercises the case where the client request body source is read
+// blocked.
+TEST(OgHttp2SessionTest, ClientSubmitRequestWithReadBlock) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_FALSE(session.want_write());
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  TestDataFrameSource* body_ref = body1.get();
+  int stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/one"}}),
+                            std::move(body1), const_cast<char*>(kSentinel1));
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(session.want_write());
+  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  // No data frame, as body1 was read blocked.
+  visitor.Clear();
+  EXPECT_FALSE(session.want_write());
+
+  body_ref->AppendPayload("This is an example request body.");
+  body_ref->EndData();
+  EXPECT_TRUE(session.ResumeStream(stream_id));
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
+  EXPECT_FALSE(session.want_write());
+
+  // Stream data is done, so this stream cannot be resumed.
+  EXPECT_FALSE(session.ResumeStream(stream_id));
+  EXPECT_FALSE(session.want_write());
+}
+
+// This test exercises the case where the client request body source is read
+// blocked, then ends with an empty DATA frame.
+TEST(OgHttp2SessionTest, ClientSubmitRequestEmptyDataWithFin) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_FALSE(session.want_write());
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  TestDataFrameSource* body_ref = body1.get();
+  int stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/one"}}),
+                            std::move(body1), const_cast<char*>(kSentinel1));
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(session.want_write());
+  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS}));
+  // No data frame, as body1 was read blocked.
+  visitor.Clear();
+  EXPECT_FALSE(session.want_write());
+
+  body_ref->EndData();
+  EXPECT_TRUE(session.ResumeStream(stream_id));
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, 0, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::DATA}));
+  EXPECT_FALSE(session.want_write());
+
+  // Stream data is done, so this stream cannot be resumed.
+  EXPECT_FALSE(session.ResumeStream(stream_id));
+  EXPECT_FALSE(session.want_write());
+}
+
+// This test exercises the case where the connection to the peer is write
+// blocked.
+TEST(OgHttp2SessionTest, ClientSubmitRequestWithWriteBlock) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
+  EXPECT_FALSE(session.want_write());
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, true);
+  body1->AppendPayload("This is an example request body.");
+  body1->EndData();
+  int stream_id =
+      session.SubmitRequest(ToHeaders({{":method", "POST"},
+                                       {":scheme", "http"},
+                                       {":authority", "example.com"},
+                                       {":path", "/this/is/request/one"}}),
+                            std::move(body1), const_cast<char*>(kSentinel1));
+  EXPECT_GT(stream_id, 0);
+  EXPECT_TRUE(session.want_write());
+  EXPECT_EQ(kSentinel1, session.GetStreamUserData(stream_id));
+  visitor.set_is_write_blocked(true);
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+
+  EXPECT_THAT(visitor.data(), testing::IsEmpty());
+  EXPECT_TRUE(session.want_write());
+  visitor.set_is_write_blocked(false);
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, stream_id, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, stream_id, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, stream_id, _, 0x1, 0));
+
+  result = session.Send();
+  EXPECT_EQ(0, result);
+
+  absl::string_view serialized = visitor.data();
+  EXPECT_THAT(serialized,
+              testing::StartsWith(spdy::kHttp2ConnectionHeaderPrefix));
+  serialized.remove_prefix(strlen(spdy::kHttp2ConnectionHeaderPrefix));
+  EXPECT_THAT(serialized,
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::HEADERS,
+                            SpdyFrameType::DATA}));
+  EXPECT_FALSE(session.want_write());
+}
+
+TEST(OgHttp2SessionTest, ServerConstruction) {
+  testing::StrictMock<MockHttp2Visitor> visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+  EXPECT_TRUE(session.want_read());
+  EXPECT_FALSE(session.want_write());
+  EXPECT_EQ(session.GetRemoteWindowSize(), kInitialFlowControlWindowSize);
+  EXPECT_TRUE(session.IsServerSession());
+  EXPECT_EQ(0, session.GetHighestReceivedStreamId());
+}
+
+TEST(OgHttp2SessionTest, ServerHandlesFrames) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+
+  EXPECT_EQ(0, session.GetHpackDecoderDynamicTableSize());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Ping(42)
+                                 .WindowUpdate(0, 1000)
+                                 .Headers(1,
+                                          {{":method", "POST"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/false)
+                                 .WindowUpdate(1, 2000)
+                                 .Data(1, "This is the request body.")
+                                 .Headers(3,
+                                          {{":method", "GET"},
+                                           {":scheme", "http"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/two"}},
+                                          /*fin=*/true)
+                                 .RstStream(3, Http2ErrorCode::CANCEL)
+                                 .Ping(47)
+                                 .Serialize();
+  testing::InSequence s;
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(42, false));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
+      .WillOnce(testing::InvokeWithoutArgs([&session, kSentinel1]() {
+        session.SetStreamUserData(1, const_cast<char*>(kSentinel1));
+        return true;
+      }));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
+  EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
+  EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
+  EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
+  EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
+  EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "http"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/two"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(3));
+  EXPECT_CALL(visitor, OnEndStream(3));
+  EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
+  EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::CANCEL));
+  EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
+  EXPECT_CALL(visitor, OnPing(47, false));
+
+  const int64_t result = session.ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_EQ(kSentinel1, session.GetStreamUserData(1));
+
+  // The first stream is active and has received some data.
+  EXPECT_GT(kInitialFlowControlWindowSize,
+            session.GetStreamReceiveWindowSize(1));
+  // Connection receive window is equivalent to the first stream's.
+  EXPECT_EQ(session.GetReceiveWindowSize(),
+            session.GetStreamReceiveWindowSize(1));
+  // Receive window upper bound is still the initial value.
+  EXPECT_EQ(kInitialFlowControlWindowSize,
+            session.GetStreamReceiveWindowLimit(1));
+
+  EXPECT_GT(session.GetHpackDecoderDynamicTableSize(), 0);
+
+  // It should no longer be possible to set user data on a closed stream.
+  const char* kSentinel3 = "another arbitrary pointer";
+  session.SetStreamUserData(3, const_cast<char*>(kSentinel3));
+  EXPECT_EQ(nullptr, session.GetStreamUserData(3));
+
+  EXPECT_EQ(session.GetRemoteWindowSize(),
+            kInitialFlowControlWindowSize + 1000);
+  EXPECT_EQ(3, session.GetHighestReceivedStreamId());
+
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x1, 0));
+
+  // Some bytes should have been serialized.
+  int send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  // Initial SETTINGS, SETTINGS ack, and PING acks (for PING IDs 42 and 47).
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames(
+                  {spdy::SpdyFrameType::SETTINGS, spdy::SpdyFrameType::SETTINGS,
+                   spdy::SpdyFrameType::PING, spdy::SpdyFrameType::PING}));
+}
+
+// Verifies that a server session enqueues initial SETTINGS before whatever
+// frame type is passed to the first invocation of EnqueueFrame().
+TEST(OgHttp2SessionTest, ServerEnqueuesSettingsBeforeOtherFrame) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+  EXPECT_FALSE(session.want_write());
+  session.EnqueueFrame(absl::make_unique<spdy::SpdyPingIR>(42));
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(PING, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(PING, 0, _, 0x0, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::PING}));
+}
+
+// Verifies that if the first call to EnqueueFrame() passes a SETTINGS frame,
+// the server session will not enqueue an additional SETTINGS frame.
+TEST(OgHttp2SessionTest, ServerEnqueuesSettingsOnce) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+  EXPECT_FALSE(session.want_write());
+  session.EnqueueFrame(absl::make_unique<spdy::SpdySettingsIR>());
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+
+  int result = session.Send();
+  EXPECT_EQ(0, result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::SETTINGS}));
+}
+
+TEST(OgHttp2SessionTest, ServerSubmitResponse) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+
+  EXPECT_FALSE(session.want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  const char* kSentinel1 = "arbitrary pointer 1";
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1))
+      .WillOnce(testing::InvokeWithoutArgs([&session, kSentinel1]() {
+        session.SetStreamUserData(1, const_cast<char*>(kSentinel1));
+        return true;
+      }));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = session.ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  EXPECT_EQ(1, session.GetHighestReceivedStreamId());
+
+  EXPECT_EQ(0, session.GetHpackEncoderDynamicTableSize());
+
+  // Server will want to send initial SETTINGS, and a SETTINGS ack.
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_FALSE(session.want_write());
+  // A data fin is not sent so that the stream remains open, and the flow
+  // control state can be verified.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload("This is an example response body.");
+  int submit_result = session.SubmitResponse(
+      1,
+      ToHeaders({{":status", "404"},
+                 {"x-comment", "I have no idea what you're talking about."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(session.want_write());
+
+  // Stream user data should have been set successfully after receiving headers.
+  EXPECT_EQ(kSentinel1, session.GetStreamUserData(1));
+  session.SetStreamUserData(1, nullptr);
+  EXPECT_EQ(nullptr, session.GetStreamUserData(1));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  EXPECT_FALSE(session.want_write());
+
+  // Some data was sent, so the remaining send window size should be less than
+  // the default.
+  EXPECT_LT(session.GetStreamSendWindowSize(1), kInitialFlowControlWindowSize);
+  EXPECT_GT(session.GetStreamSendWindowSize(1), 0);
+  // Send window for a nonexistent stream is not available.
+  EXPECT_EQ(session.GetStreamSendWindowSize(3), -1);
+
+  EXPECT_GT(session.GetHpackEncoderDynamicTableSize(), 0);
+}
+
+// Tests the case where the server queues trailers after the data stream is
+// exhausted.
+TEST(OgHttp2SessionTest, ServerSendsTrailers) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+
+  EXPECT_FALSE(session.want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = session.ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  // Server will want to send initial SETTINGS, and a SETTINGS ack.
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_FALSE(session.want_write());
+
+  // The body source must indicate that the end of the body is not the end of
+  // the stream.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload("This is an example response body.");
+  body1->EndData();
+  int submit_result = session.SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA}));
+  visitor.Clear();
+  EXPECT_FALSE(session.want_write());
+
+  // The body source has been exhausted by the call to Send() above.
+  int trailer_result = session.SubmitTrailer(
+      1, ToHeaders({{"final-status", "a-ok"},
+                    {"x-comment", "trailers sure are cool"}}));
+  ASSERT_EQ(trailer_result, 0);
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(), EqualsFrames({SpdyFrameType::HEADERS}));
+}
+
+// Tests the case where the server queues trailers immediately after headers and
+// data, and before any writes have taken place.
+TEST(OgHttp2SessionTest, ServerQueuesTrailersWithResponse) {
+  DataSavingVisitor visitor;
+  OgHttp2Session session(
+      visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
+
+  EXPECT_FALSE(session.want_write());
+
+  const std::string frames = TestFrameSequence()
+                                 .ClientPreface()
+                                 .Headers(1,
+                                          {{":method", "GET"},
+                                           {":scheme", "https"},
+                                           {":authority", "example.com"},
+                                           {":path", "/this/is/request/one"}},
+                                          /*fin=*/true)
+                                 .Serialize();
+  testing::InSequence s;
+
+  // Client preface (empty SETTINGS)
+  EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
+  EXPECT_CALL(visitor, OnSettingsStart());
+  EXPECT_CALL(visitor, OnSettingsEnd());
+  // Stream 1
+  EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 5));
+  EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "GET"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
+  EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
+  EXPECT_CALL(visitor, OnEndHeadersForStream(1));
+  EXPECT_CALL(visitor, OnEndStream(1));
+
+  const int64_t result = session.ProcessBytes(frames);
+  EXPECT_EQ(frames.size(), static_cast<size_t>(result));
+
+  // Server will want to send initial SETTINGS, and a SETTINGS ack.
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
+  EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x1));
+  EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x1, 0));
+
+  int send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::SETTINGS, SpdyFrameType::SETTINGS}));
+  visitor.Clear();
+
+  EXPECT_FALSE(session.want_write());
+
+  // The body source must indicate that the end of the body is not the end of
+  // the stream.
+  auto body1 = absl::make_unique<TestDataFrameSource>(visitor, false);
+  body1->AppendPayload("This is an example response body.");
+  body1->EndData();
+  int submit_result = session.SubmitResponse(
+      1, ToHeaders({{":status", "200"}, {"x-comment", "Sure, sounds good."}}),
+      std::move(body1));
+  EXPECT_EQ(submit_result, 0);
+  EXPECT_TRUE(session.want_write());
+  // There has not been a call to Send() yet, so neither headers nor body have
+  // been written.
+  int trailer_result = session.SubmitTrailer(
+      1, ToHeaders({{"final-status", "a-ok"},
+                    {"x-comment", "trailers sure are cool"}}));
+  ASSERT_EQ(trailer_result, 0);
+  EXPECT_TRUE(session.want_write());
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));
+  EXPECT_CALL(visitor, OnFrameSent(DATA, 1, _, 0x0, 0));
+
+  EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x5));
+  EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x5, 0));
+  EXPECT_CALL(visitor, OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR));
+
+  send_result = session.Send();
+  EXPECT_EQ(0, send_result);
+  EXPECT_THAT(visitor.data(),
+              EqualsFrames({SpdyFrameType::HEADERS, SpdyFrameType::DATA,
+                            SpdyFrameType::HEADERS}));
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/oghttp2_util.cc b/quiche/http2/adapter/oghttp2_util.cc
new file mode 100644
index 0000000..b1acc22
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_util.cc
@@ -0,0 +1,17 @@
+#include "quiche/http2/adapter/oghttp2_util.h"
+
+namespace http2 {
+namespace adapter {
+
+spdy::SpdyHeaderBlock ToHeaderBlock(absl::Span<const Header> headers) {
+  spdy::SpdyHeaderBlock block;
+  for (const Header& header : headers) {
+    absl::string_view name = GetStringView(header.first).first;
+    absl::string_view value = GetStringView(header.second).first;
+    block.AppendValueOrAddHeader(name, value);
+  }
+  return block;
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/oghttp2_util.h b/quiche/http2/adapter/oghttp2_util.h
new file mode 100644
index 0000000..c9f7aa6
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_util.h
@@ -0,0 +1,18 @@
+#ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_UTIL_H_
+#define QUICHE_HTTP2_ADAPTER_OGHTTP2_UTIL_H_
+
+#include "absl/types/span.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace http2 {
+namespace adapter {
+
+QUICHE_EXPORT_PRIVATE spdy::SpdyHeaderBlock ToHeaderBlock(
+    absl::Span<const Header> headers);
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_UTIL_H_
diff --git a/quiche/http2/adapter/oghttp2_util_test.cc b/quiche/http2/adapter/oghttp2_util_test.cc
new file mode 100644
index 0000000..ac63073
--- /dev/null
+++ b/quiche/http2/adapter/oghttp2_util_test.cc
@@ -0,0 +1,83 @@
+#include "quiche/http2/adapter/oghttp2_util.h"
+
+#include <utility>
+#include <vector>
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/test_frame_sequence.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using HeaderPair = std::pair<absl::string_view, absl::string_view>;
+
+TEST(ToHeaderBlock, EmptySpan) {
+  spdy::SpdyHeaderBlock block = ToHeaderBlock({});
+  EXPECT_TRUE(block.empty());
+}
+
+TEST(ToHeaderBlock, ExampleRequestHeaders) {
+  const std::vector<HeaderPair> pairs = {{":authority", "example.com"},
+                                         {":method", "GET"},
+                                         {":path", "/example.html"},
+                                         {":scheme", "http"},
+                                         {"accept", "text/plain, text/html"}};
+  const std::vector<Header> headers = ToHeaders(pairs);
+  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
+  EXPECT_THAT(block, testing::ElementsAreArray(pairs));
+}
+
+TEST(ToHeaderBlock, ExampleResponseHeaders) {
+  const std::vector<HeaderPair> pairs = {
+      {":status", "403"},
+      {"content-length", "1023"},
+      {"x-extra-info", "humblest apologies"}};
+  const std::vector<Header> headers = ToHeaders(pairs);
+  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
+  EXPECT_THAT(block, testing::ElementsAreArray(pairs));
+}
+
+TEST(ToHeaderBlock, RepeatedRequestHeaderNames) {
+  const std::vector<HeaderPair> pairs = {
+      {":authority", "example.com"},     {":method", "GET"},
+      {":path", "/example.html"},        {":scheme", "http"},
+      {"cookie", "chocolate_chips=yes"}, {"accept", "text/plain, text/html"},
+      {"cookie", "raisins=no"}};
+  const std::vector<HeaderPair> expected = {
+      {":authority", "example.com"},
+      {":method", "GET"},
+      {":path", "/example.html"},
+      {":scheme", "http"},
+      {"cookie", "chocolate_chips=yes; raisins=no"},
+      {"accept", "text/plain, text/html"}};
+  const std::vector<Header> headers = ToHeaders(pairs);
+  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
+  EXPECT_THAT(block, testing::ElementsAreArray(expected));
+}
+
+TEST(ToHeaderBlock, RepeatedResponseHeaderNames) {
+  const std::vector<HeaderPair> pairs = {
+      {":status", "403"},          {"x-extra-info", "sorry"},
+      {"content-length", "1023"},  {"x-extra-info", "humblest apologies"},
+      {"content-length", "1024"},  {"set-cookie", "chocolate_chips=yes"},
+      {"set-cookie", "raisins=no"}};
+  const std::vector<HeaderPair> expected = {
+      {":status", "403"},
+      {"x-extra-info", absl::string_view("sorry\0humblest apologies", 24)},
+      {"content-length", absl::string_view("1023"
+                                           "\0"
+                                           "1024",
+                                           9)},
+      {"set-cookie", absl::string_view("chocolate_chips=yes\0raisins=no", 30)}};
+  const std::vector<Header> headers = ToHeaders(pairs);
+  spdy::SpdyHeaderBlock block = ToHeaderBlock(headers);
+  EXPECT_THAT(block, testing::ElementsAreArray(expected));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/recording_http2_visitor.cc b/quiche/http2/adapter/recording_http2_visitor.cc
new file mode 100644
index 0000000..fe6e080
--- /dev/null
+++ b/quiche/http2/adapter/recording_http2_visitor.cc
@@ -0,0 +1,182 @@
+#include "quiche/http2/adapter/recording_http2_visitor.h"
+
+#include "absl/strings/str_format.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_util.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+int64_t RecordingHttp2Visitor::OnReadyToSend(absl::string_view serialized) {
+  events_.push_back(absl::StrFormat("OnReadyToSend %d", serialized.size()));
+  return serialized.size();
+}
+
+void RecordingHttp2Visitor::OnConnectionError(ConnectionError error) {
+  events_.push_back(
+      absl::StrFormat("OnConnectionError %s", ConnectionErrorToString(error)));
+}
+
+bool RecordingHttp2Visitor::OnFrameHeader(Http2StreamId stream_id,
+                                          size_t length, uint8_t type,
+                                          uint8_t flags) {
+  events_.push_back(absl::StrFormat("OnFrameHeader %d %d %d %d", stream_id,
+                                    length, type, flags));
+  return true;
+}
+
+void RecordingHttp2Visitor::OnSettingsStart() {
+  events_.push_back("OnSettingsStart");
+}
+
+void RecordingHttp2Visitor::OnSetting(Http2Setting setting) {
+  events_.push_back(absl::StrFormat(
+      "OnSetting %s %d", Http2SettingsIdToString(setting.id), setting.value));
+}
+
+void RecordingHttp2Visitor::OnSettingsEnd() {
+  events_.push_back("OnSettingsEnd");
+}
+
+void RecordingHttp2Visitor::OnSettingsAck() {
+  events_.push_back("OnSettingsAck");
+}
+
+bool RecordingHttp2Visitor::OnBeginHeadersForStream(Http2StreamId stream_id) {
+  events_.push_back(absl::StrFormat("OnBeginHeadersForStream %d", stream_id));
+  return true;
+}
+
+Http2VisitorInterface::OnHeaderResult RecordingHttp2Visitor::OnHeaderForStream(
+    Http2StreamId stream_id, absl::string_view name, absl::string_view value) {
+  events_.push_back(
+      absl::StrFormat("OnHeaderForStream %d %s %s", stream_id, name, value));
+  return HEADER_OK;
+}
+
+bool RecordingHttp2Visitor::OnEndHeadersForStream(Http2StreamId stream_id) {
+  events_.push_back(absl::StrFormat("OnEndHeadersForStream %d", stream_id));
+  return true;
+}
+
+bool RecordingHttp2Visitor::OnDataPaddingLength(Http2StreamId stream_id,
+                                                size_t padding_length) {
+  events_.push_back(
+      absl::StrFormat("OnDataPaddingLength %d %d", stream_id, padding_length));
+  return true;
+}
+
+bool RecordingHttp2Visitor::OnBeginDataForStream(Http2StreamId stream_id,
+                                                 size_t payload_length) {
+  events_.push_back(
+      absl::StrFormat("OnBeginDataForStream %d %d", stream_id, payload_length));
+  return true;
+}
+
+bool RecordingHttp2Visitor::OnDataForStream(Http2StreamId stream_id,
+                                            absl::string_view data) {
+  events_.push_back(absl::StrFormat("OnDataForStream %d %s", stream_id, data));
+  return true;
+}
+
+void RecordingHttp2Visitor::OnEndStream(Http2StreamId stream_id) {
+  events_.push_back(absl::StrFormat("OnEndStream %d", stream_id));
+}
+
+void RecordingHttp2Visitor::OnRstStream(Http2StreamId stream_id,
+                                        Http2ErrorCode error_code) {
+  events_.push_back(absl::StrFormat("OnRstStream %d %s", stream_id,
+                                    Http2ErrorCodeToString(error_code)));
+}
+
+bool RecordingHttp2Visitor::OnCloseStream(Http2StreamId stream_id,
+                                          Http2ErrorCode error_code) {
+  events_.push_back(absl::StrFormat("OnCloseStream %d %s", stream_id,
+                                    Http2ErrorCodeToString(error_code)));
+  return true;
+}
+
+void RecordingHttp2Visitor::OnPriorityForStream(Http2StreamId stream_id,
+                                                Http2StreamId parent_stream_id,
+                                                int weight,
+                                                bool exclusive) {
+  events_.push_back(absl::StrFormat("OnPriorityForStream %d %d %d %d",
+                                    stream_id, parent_stream_id, weight,
+                                    exclusive));
+}
+
+void RecordingHttp2Visitor::OnPing(Http2PingId ping_id, bool is_ack) {
+  events_.push_back(absl::StrFormat("OnPing %d %d", ping_id, is_ack));
+}
+
+void RecordingHttp2Visitor::OnPushPromiseForStream(
+    Http2StreamId stream_id,
+    Http2StreamId promised_stream_id) {
+  events_.push_back(absl::StrFormat("OnPushPromiseForStream %d %d", stream_id,
+                                    promised_stream_id));
+}
+
+bool RecordingHttp2Visitor::OnGoAway(Http2StreamId last_accepted_stream_id,
+                                     Http2ErrorCode error_code,
+                                     absl::string_view opaque_data) {
+  events_.push_back(
+      absl::StrFormat("OnGoAway %d %s %s", last_accepted_stream_id,
+                      Http2ErrorCodeToString(error_code), opaque_data));
+  return true;
+}
+
+void RecordingHttp2Visitor::OnWindowUpdate(Http2StreamId stream_id,
+                                           int window_increment) {
+  events_.push_back(
+      absl::StrFormat("OnWindowUpdate %d %d", stream_id, window_increment));
+}
+
+int RecordingHttp2Visitor::OnBeforeFrameSent(uint8_t frame_type,
+                                             Http2StreamId stream_id,
+                                             size_t length, uint8_t flags) {
+  events_.push_back(absl::StrFormat("OnBeforeFrameSent %d %d %d %d", frame_type,
+                                    stream_id, length, flags));
+  return 0;
+}
+
+int RecordingHttp2Visitor::OnFrameSent(uint8_t frame_type,
+                                       Http2StreamId stream_id, size_t length,
+                                       uint8_t flags, uint32_t error_code) {
+  events_.push_back(absl::StrFormat("OnFrameSent %d %d %d %d %d", frame_type,
+                                    stream_id, length, flags, error_code));
+  return 0;
+}
+
+bool RecordingHttp2Visitor::OnInvalidFrame(Http2StreamId stream_id,
+                                           InvalidFrameError error) {
+  events_.push_back(absl::StrFormat("OnInvalidFrame %d %s", stream_id,
+                                    InvalidFrameErrorToString(error)));
+  return true;
+}
+
+void RecordingHttp2Visitor::OnBeginMetadataForStream(Http2StreamId stream_id,
+                                                     size_t payload_length) {
+  events_.push_back(absl::StrFormat("OnBeginMetadataForStream %d %d", stream_id,
+                                    payload_length));
+}
+
+bool RecordingHttp2Visitor::OnMetadataForStream(Http2StreamId stream_id,
+                                                absl::string_view metadata) {
+  events_.push_back(
+      absl::StrFormat("OnMetadataForStream %d %s", stream_id, metadata));
+  return true;
+}
+
+bool RecordingHttp2Visitor::OnMetadataEndForStream(Http2StreamId stream_id) {
+  events_.push_back(absl::StrFormat("OnMetadataEndForStream %d", stream_id));
+  return true;
+}
+
+void RecordingHttp2Visitor::OnErrorDebug(absl::string_view message) {
+  events_.push_back(absl::StrFormat("OnErrorDebug %s", message));
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/recording_http2_visitor.h b/quiche/http2/adapter/recording_http2_visitor.h
new file mode 100644
index 0000000..27d98a0
--- /dev/null
+++ b/quiche/http2/adapter/recording_http2_visitor.h
@@ -0,0 +1,81 @@
+#ifndef QUICHE_HTTP2_ADAPTER_RECORDING_HTTP2_VISITOR_H_
+#define QUICHE_HTTP2_ADAPTER_RECORDING_HTTP2_VISITOR_H_
+
+#include <cstdint>
+#include <list>
+#include <string>
+
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+// A visitor implementation that records the sequence of callbacks it receives.
+class QUICHE_NO_EXPORT RecordingHttp2Visitor : public Http2VisitorInterface {
+ public:
+  using Event = std::string;
+  using EventSequence = std::list<Event>;
+
+  // From Http2VisitorInterface
+  int64_t OnReadyToSend(absl::string_view serialized) override;
+  void OnConnectionError(ConnectionError error) override;
+  bool OnFrameHeader(Http2StreamId stream_id, size_t length, uint8_t type,
+                     uint8_t flags) override;
+  void OnSettingsStart() override;
+  void OnSetting(Http2Setting setting) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck() override;
+  bool OnBeginHeadersForStream(Http2StreamId stream_id) override;
+  OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
+                                   absl::string_view name,
+                                   absl::string_view value) override;
+  bool OnEndHeadersForStream(Http2StreamId stream_id) override;
+  bool OnDataPaddingLength(Http2StreamId stream_id,
+                           size_t padding_length) override;
+  bool OnBeginDataForStream(Http2StreamId stream_id,
+                            size_t payload_length) override;
+  bool OnDataForStream(Http2StreamId stream_id,
+                       absl::string_view data) override;
+  void OnEndStream(Http2StreamId stream_id) override;
+  void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
+  bool OnCloseStream(Http2StreamId stream_id,
+                     Http2ErrorCode error_code) override;
+  void OnPriorityForStream(Http2StreamId stream_id,
+                           Http2StreamId parent_stream_id,
+                           int weight,
+                           bool exclusive) override;
+  void OnPing(Http2PingId ping_id, bool is_ack) override;
+  void OnPushPromiseForStream(Http2StreamId stream_id,
+                              Http2StreamId promised_stream_id) override;
+  bool OnGoAway(Http2StreamId last_accepted_stream_id,
+                Http2ErrorCode error_code,
+                absl::string_view opaque_data) override;
+  void OnWindowUpdate(Http2StreamId stream_id, int window_increment) override;
+  int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
+                        size_t length, uint8_t flags) override;
+  int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length,
+                  uint8_t flags, uint32_t error_code) override;
+  bool OnInvalidFrame(Http2StreamId stream_id,
+                      InvalidFrameError error) override;
+  void OnBeginMetadataForStream(Http2StreamId stream_id,
+                                size_t payload_length) override;
+  bool OnMetadataForStream(Http2StreamId stream_id,
+                           absl::string_view metadata) override;
+  bool OnMetadataEndForStream(Http2StreamId stream_id) override;
+  void OnErrorDebug(absl::string_view message) override;
+
+  const EventSequence& GetEventSequence() const { return events_; }
+  void Clear() { events_.clear(); }
+
+ private:
+  EventSequence events_;
+};
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_RECORDING_HTTP2_VISITOR_H_
diff --git a/quiche/http2/adapter/recording_http2_visitor_test.cc b/quiche/http2/adapter/recording_http2_visitor_test.cc
new file mode 100644
index 0000000..34d96f9
--- /dev/null
+++ b/quiche/http2/adapter/recording_http2_visitor_test.cc
@@ -0,0 +1,132 @@
+#include "quiche/http2/adapter/recording_http2_visitor.h"
+
+#include <list>
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using ::testing::IsEmpty;
+
+TEST(RecordingHttp2VisitorTest, EmptySequence) {
+  RecordingHttp2Visitor chocolate_visitor;
+  RecordingHttp2Visitor vanilla_visitor;
+
+  EXPECT_THAT(chocolate_visitor.GetEventSequence(), IsEmpty());
+  EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
+  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+
+  chocolate_visitor.OnSettingsStart();
+
+  EXPECT_THAT(chocolate_visitor.GetEventSequence(), testing::Not(IsEmpty()));
+  EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
+  EXPECT_NE(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+
+  chocolate_visitor.Clear();
+
+  EXPECT_THAT(chocolate_visitor.GetEventSequence(), IsEmpty());
+  EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
+  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+}
+
+TEST(RecordingHttp2VisitorTest, SameEventsProduceSameSequence) {
+  RecordingHttp2Visitor chocolate_visitor;
+  RecordingHttp2Visitor vanilla_visitor;
+
+  // Prepare some random values to deliver with the events.
+  http2::test::Http2Random random;
+  const Http2StreamId stream_id = random.Uniform(kMaxStreamId);
+  const Http2StreamId another_stream_id = random.Uniform(kMaxStreamId);
+  const size_t length = random.Rand16();
+  const uint8_t type = random.Rand8();
+  const uint8_t flags = random.Rand8();
+  const Http2ErrorCode error_code = static_cast<Http2ErrorCode>(
+      random.Uniform(static_cast<int>(Http2ErrorCode::MAX_ERROR_CODE)));
+  const Http2Setting setting = {.id = random.Rand16(),
+                                .value = random.Rand32()};
+  const absl::string_view alphabet = "abcdefghijklmnopqrstuvwxyz0123456789-";
+  const std::string some_string =
+      random.RandStringWithAlphabet(random.Rand8(), alphabet);
+  const std::string another_string =
+      random.RandStringWithAlphabet(random.Rand8(), alphabet);
+  const uint16_t some_int = random.Rand16();
+  const bool some_bool = random.OneIn(2);
+
+  // Send the same arbitrary sequence of events to both visitors.
+  std::list<RecordingHttp2Visitor*> visitors = {&chocolate_visitor,
+                                                &vanilla_visitor};
+  for (RecordingHttp2Visitor* visitor : visitors) {
+    visitor->OnConnectionError(
+        Http2VisitorInterface::ConnectionError::kSendError);
+    visitor->OnFrameHeader(stream_id, length, type, flags);
+    visitor->OnSettingsStart();
+    visitor->OnSetting(setting);
+    visitor->OnSettingsEnd();
+    visitor->OnSettingsAck();
+    visitor->OnBeginHeadersForStream(stream_id);
+    visitor->OnHeaderForStream(stream_id, some_string, another_string);
+    visitor->OnEndHeadersForStream(stream_id);
+    visitor->OnBeginDataForStream(stream_id, length);
+    visitor->OnDataForStream(stream_id, some_string);
+    visitor->OnDataForStream(stream_id, another_string);
+    visitor->OnEndStream(stream_id);
+    visitor->OnRstStream(stream_id, error_code);
+    visitor->OnCloseStream(stream_id, error_code);
+    visitor->OnPriorityForStream(stream_id, another_stream_id, some_int,
+                                 some_bool);
+    visitor->OnPing(some_int, some_bool);
+    visitor->OnPushPromiseForStream(stream_id, another_stream_id);
+    visitor->OnGoAway(stream_id, error_code, some_string);
+    visitor->OnWindowUpdate(stream_id, some_int);
+    visitor->OnBeginMetadataForStream(stream_id, length);
+    visitor->OnMetadataForStream(stream_id, some_string);
+    visitor->OnMetadataForStream(stream_id, another_string);
+    visitor->OnMetadataEndForStream(stream_id);
+  }
+
+  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+}
+
+TEST(RecordingHttp2VisitorTest, DifferentEventsProduceDifferentSequence) {
+  RecordingHttp2Visitor chocolate_visitor;
+  RecordingHttp2Visitor vanilla_visitor;
+  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+
+  const Http2StreamId stream_id = 1;
+  const size_t length = 42;
+
+  // Different events with the same method arguments should produce different
+  // event sequences.
+  chocolate_visitor.OnBeginDataForStream(stream_id, length);
+  vanilla_visitor.OnBeginMetadataForStream(stream_id, length);
+  EXPECT_NE(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+
+  chocolate_visitor.Clear();
+  vanilla_visitor.Clear();
+  EXPECT_EQ(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+
+  // The same events with different method arguments should produce different
+  // event sequences.
+  chocolate_visitor.OnBeginHeadersForStream(stream_id);
+  vanilla_visitor.OnBeginHeadersForStream(stream_id + 2);
+  EXPECT_NE(chocolate_visitor.GetEventSequence(),
+            vanilla_visitor.GetEventSequence());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/test_frame_sequence.cc b/quiche/http2/adapter/test_frame_sequence.cc
new file mode 100644
index 0000000..c462c45
--- /dev/null
+++ b/quiche/http2/adapter/test_frame_sequence.cc
@@ -0,0 +1,188 @@
+#include "quiche/http2/adapter/test_frame_sequence.h"
+
+#include "quiche/http2/adapter/http2_util.h"
+#include "quiche/http2/adapter/oghttp2_util.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+std::vector<Header> ToHeaders(
+    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers) {
+  std::vector<Header> out;
+  for (auto [name, value] : headers) {
+    out.push_back(std::make_pair(HeaderRep(name), HeaderRep(value)));
+  }
+  return out;
+}
+
+TestFrameSequence& TestFrameSequence::ClientPreface(
+    absl::Span<const Http2Setting> settings) {
+  preface_ = spdy::kHttp2ConnectionHeaderPrefix;
+  return Settings(settings);
+}
+
+TestFrameSequence& TestFrameSequence::ServerPreface(
+    absl::Span<const Http2Setting> settings) {
+  return Settings(settings);
+}
+
+TestFrameSequence& TestFrameSequence::Data(Http2StreamId stream_id,
+                                           absl::string_view payload,
+                                           bool fin,
+                                           absl::optional<int> padding_length) {
+  auto data = absl::make_unique<spdy::SpdyDataIR>(stream_id, payload);
+  data->set_fin(fin);
+  if (padding_length) {
+    data->set_padding_len(padding_length.value());
+  }
+  frames_.push_back(std::move(data));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::RstStream(Http2StreamId stream_id,
+                                                Http2ErrorCode error) {
+  frames_.push_back(absl::make_unique<spdy::SpdyRstStreamIR>(
+      stream_id, TranslateErrorCode(error)));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::Settings(
+    absl::Span<const Http2Setting> settings) {
+  auto settings_frame = absl::make_unique<spdy::SpdySettingsIR>();
+  for (const Http2Setting& setting : settings) {
+    settings_frame->AddSetting(setting.id, setting.value);
+  }
+  frames_.push_back(std::move(settings_frame));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::SettingsAck() {
+  auto settings = absl::make_unique<spdy::SpdySettingsIR>();
+  settings->set_is_ack(true);
+  frames_.push_back(std::move(settings));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::PushPromise(
+    Http2StreamId stream_id, Http2StreamId promised_stream_id,
+    absl::Span<const Header> headers) {
+  frames_.push_back(absl::make_unique<spdy::SpdyPushPromiseIR>(
+      stream_id, promised_stream_id, ToHeaderBlock(headers)));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::Ping(Http2PingId id) {
+  frames_.push_back(absl::make_unique<spdy::SpdyPingIR>(id));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::PingAck(Http2PingId id) {
+  auto ping = absl::make_unique<spdy::SpdyPingIR>(id);
+  ping->set_is_ack(true);
+  frames_.push_back(std::move(ping));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::GoAway(Http2StreamId last_good_stream_id,
+                                             Http2ErrorCode error,
+                                             absl::string_view payload) {
+  frames_.push_back(absl::make_unique<spdy::SpdyGoAwayIR>(
+      last_good_stream_id, TranslateErrorCode(error), std::string(payload)));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::Headers(
+    Http2StreamId stream_id,
+    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers,
+    bool fin, bool add_continuation) {
+  return Headers(stream_id, ToHeaders(headers), fin, add_continuation);
+}
+
+TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
+                                              spdy::Http2HeaderBlock block,
+                                              bool fin, bool add_continuation) {
+  if (add_continuation) {
+    // The normal intermediate representations don't allow you to represent a
+    // nonterminal HEADERS frame explicitly, so we'll need to use
+    // SpdyUnknownIRs. For simplicity, and in order not to mess up HPACK state,
+    // the payload will be uncompressed.
+    spdy::HpackEncoder encoder;
+    encoder.DisableCompression();
+    std::string encoded_block = encoder.EncodeHeaderBlock(block);
+    const size_t pos = encoded_block.size() / 2;
+    const uint8_t flags = fin ? 0x1 : 0x0;
+    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
+        stream_id, static_cast<uint8_t>(spdy::SpdyFrameType::HEADERS), flags,
+        encoded_block.substr(0, pos)));
+
+    auto continuation = absl::make_unique<spdy::SpdyContinuationIR>(stream_id);
+    continuation->set_end_headers(true);
+    continuation->take_encoding(encoded_block.substr(pos));
+    frames_.push_back(std::move(continuation));
+  } else {
+    auto headers =
+        absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(block));
+    headers->set_fin(fin);
+    frames_.push_back(std::move(headers));
+  }
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
+                                              absl::Span<const Header> headers,
+                                              bool fin, bool add_continuation) {
+  return Headers(stream_id, ToHeaderBlock(headers), fin, add_continuation);
+}
+
+TestFrameSequence& TestFrameSequence::WindowUpdate(Http2StreamId stream_id,
+                                                   int32_t delta) {
+  frames_.push_back(
+      absl::make_unique<spdy::SpdyWindowUpdateIR>(stream_id, delta));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::Priority(Http2StreamId stream_id,
+                                               Http2StreamId parent_stream_id,
+                                               int weight,
+                                               bool exclusive) {
+  frames_.push_back(absl::make_unique<spdy::SpdyPriorityIR>(
+      stream_id, parent_stream_id, weight, exclusive));
+  return *this;
+}
+
+TestFrameSequence& TestFrameSequence::Metadata(Http2StreamId stream_id,
+                                               absl::string_view payload,
+                                               bool multiple_frames) {
+  if (multiple_frames) {
+    const size_t pos = payload.size() / 2;
+    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
+        stream_id, kMetadataFrameType, 0, std::string(payload.substr(0, pos))));
+    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
+        stream_id, kMetadataFrameType, kMetadataEndFlag,
+        std::string(payload.substr(pos))));
+  } else {
+    frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
+        stream_id, kMetadataFrameType, kMetadataEndFlag, std::string(payload)));
+  }
+  return *this;
+}
+
+std::string TestFrameSequence::Serialize() {
+  std::string result;
+  if (!preface_.empty()) {
+    result = preface_;
+  }
+  spdy::SpdyFramer framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
+  for (const auto& frame : frames_) {
+    spdy::SpdySerializedFrame f = framer.SerializeFrame(*frame);
+    absl::StrAppend(&result, absl::string_view(f));
+  }
+  return result;
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/test_frame_sequence.h b/quiche/http2/adapter/test_frame_sequence.h
new file mode 100644
index 0000000..e7943fa
--- /dev/null
+++ b/quiche/http2/adapter/test_frame_sequence.h
@@ -0,0 +1,73 @@
+#ifndef QUICHE_HTTP2_ADAPTER_TEST_FRAME_SEQUENCE_H_
+#define QUICHE_HTTP2_ADAPTER_TEST_FRAME_SEQUENCE_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+std::vector<Header> QUICHE_NO_EXPORT ToHeaders(
+    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers);
+
+class QUICHE_NO_EXPORT TestFrameSequence {
+ public:
+  TestFrameSequence() = default;
+
+  TestFrameSequence& ClientPreface(
+      absl::Span<const Http2Setting> settings = {});
+  TestFrameSequence& ServerPreface(
+      absl::Span<const Http2Setting> settings = {});
+  TestFrameSequence& Data(Http2StreamId stream_id,
+                          absl::string_view payload,
+                          bool fin = false,
+                          absl::optional<int> padding_length = absl::nullopt);
+  TestFrameSequence& RstStream(Http2StreamId stream_id, Http2ErrorCode error);
+  TestFrameSequence& Settings(absl::Span<const Http2Setting> settings);
+  TestFrameSequence& SettingsAck();
+  TestFrameSequence& PushPromise(Http2StreamId stream_id,
+                                 Http2StreamId promised_stream_id,
+                                 absl::Span<const Header> headers);
+  TestFrameSequence& Ping(Http2PingId id);
+  TestFrameSequence& PingAck(Http2PingId id);
+  TestFrameSequence& GoAway(Http2StreamId last_good_stream_id,
+                            Http2ErrorCode error,
+                            absl::string_view payload = "");
+  TestFrameSequence& Headers(
+      Http2StreamId stream_id,
+      absl::Span<const std::pair<absl::string_view, absl::string_view>> headers,
+      bool fin = false, bool add_continuation = false);
+  TestFrameSequence& Headers(Http2StreamId stream_id,
+                             spdy::Http2HeaderBlock block, bool fin = false,
+                             bool add_continuation = false);
+  TestFrameSequence& Headers(Http2StreamId stream_id,
+                             absl::Span<const Header> headers, bool fin = false,
+                             bool add_continuation = false);
+  TestFrameSequence& WindowUpdate(Http2StreamId stream_id, int32_t delta);
+  TestFrameSequence& Priority(Http2StreamId stream_id,
+                              Http2StreamId parent_stream_id,
+                              int weight,
+                              bool exclusive);
+  TestFrameSequence& Metadata(Http2StreamId stream_id,
+                              absl::string_view payload,
+                              bool multiple_frames = false);
+
+  std::string Serialize();
+
+ private:
+  std::string preface_;
+  std::vector<std::unique_ptr<spdy::SpdyFrameIR>> frames_;
+};
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_TEST_FRAME_SEQUENCE_H_
diff --git a/quiche/http2/adapter/test_utils.cc b/quiche/http2/adapter/test_utils.cc
new file mode 100644
index 0000000..5d6d427
--- /dev/null
+++ b/quiche/http2/adapter/test_utils.cc
@@ -0,0 +1,224 @@
+#include "quiche/http2/adapter/test_utils.h"
+
+#include <ostream>
+
+#include "absl/strings/str_format.h"
+#include "quiche/http2/adapter/http2_visitor_interface.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using ConnectionError = Http2VisitorInterface::ConnectionError;
+
+}  // anonymous namespace
+
+TestDataFrameSource::TestDataFrameSource(Http2VisitorInterface& visitor,
+                                         bool has_fin)
+    : visitor_(visitor), has_fin_(has_fin) {}
+
+void TestDataFrameSource::AppendPayload(absl::string_view payload) {
+  QUICHE_CHECK(!end_data_);
+  if (!payload.empty()) {
+    payload_fragments_.push_back(std::string(payload));
+    current_fragment_ = payload_fragments_.front();
+  }
+}
+
+void TestDataFrameSource::EndData() { end_data_ = true; }
+
+std::pair<int64_t, bool> TestDataFrameSource::SelectPayloadLength(
+    size_t max_length) {
+  if (return_error_) {
+    return {DataFrameSource::kError, false};
+  }
+  // The stream is done if there's no more data, or if |max_length| is at least
+  // as large as the remaining data.
+  const bool end_data = end_data_ && (current_fragment_.empty() ||
+                                      (payload_fragments_.size() == 1 &&
+                                       max_length >= current_fragment_.size()));
+  const int64_t length = std::min(max_length, current_fragment_.size());
+  return {length, end_data};
+}
+
+bool TestDataFrameSource::Send(absl::string_view frame_header,
+                               size_t payload_length) {
+  QUICHE_LOG_IF(DFATAL, payload_length > current_fragment_.size())
+      << "payload_length: " << payload_length
+      << " current_fragment_size: " << current_fragment_.size();
+  const std::string concatenated =
+      absl::StrCat(frame_header, current_fragment_.substr(0, payload_length));
+  const int64_t result = visitor_.OnReadyToSend(concatenated);
+  if (result < 0) {
+    // Write encountered error.
+    visitor_.OnConnectionError(ConnectionError::kSendError);
+    current_fragment_ = {};
+    payload_fragments_.clear();
+    return false;
+  } else if (result == 0) {
+    // Write blocked.
+    return false;
+  } else if (static_cast<const size_t>(result) < concatenated.size()) {
+    // Probably need to handle this better within this test class.
+    QUICHE_LOG(DFATAL)
+        << "DATA frame not fully flushed. Connection will be corrupt!";
+    visitor_.OnConnectionError(ConnectionError::kSendError);
+    current_fragment_ = {};
+    payload_fragments_.clear();
+    return false;
+  }
+  if (payload_length > 0) {
+    current_fragment_.remove_prefix(payload_length);
+  }
+  if (current_fragment_.empty() && !payload_fragments_.empty()) {
+    payload_fragments_.erase(payload_fragments_.begin());
+    if (!payload_fragments_.empty()) {
+      current_fragment_ = payload_fragments_.front();
+    }
+  }
+  return true;
+}
+
+std::string EncodeHeaders(const spdy::SpdyHeaderBlock& entries) {
+  spdy::HpackEncoder encoder;
+  encoder.DisableCompression();
+  return encoder.EncodeHeaderBlock(entries);
+}
+
+TestMetadataSource::TestMetadataSource(const spdy::SpdyHeaderBlock& entries)
+    : encoded_entries_(EncodeHeaders(entries)) {
+  remaining_ = encoded_entries_;
+}
+
+std::pair<int64_t, bool> TestMetadataSource::Pack(uint8_t* dest,
+                                                  size_t dest_len) {
+  const size_t copied = std::min(dest_len, remaining_.size());
+  std::memcpy(dest, remaining_.data(), copied);
+  remaining_.remove_prefix(copied);
+  return std::make_pair(copied, remaining_.empty());
+}
+
+namespace {
+
+using TypeAndOptionalLength =
+    std::pair<spdy::SpdyFrameType, absl::optional<size_t>>;
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const std::vector<TypeAndOptionalLength>& types_and_lengths) {
+  for (const auto& type_and_length : types_and_lengths) {
+    os << "(" << spdy::FrameTypeToString(type_and_length.first) << ", "
+       << (type_and_length.second ? absl::StrCat(type_and_length.second.value())
+                                  : "<unspecified>")
+       << ") ";
+  }
+  return os;
+}
+
+std::string FrameTypeToString(uint8_t frame_type) {
+  if (spdy::IsDefinedFrameType(frame_type)) {
+    return spdy::FrameTypeToString(spdy::ParseFrameType(frame_type));
+  } else {
+    return absl::StrFormat("0x%x", static_cast<int>(frame_type));
+  }
+}
+
+// Custom gMock matcher, used to implement EqualsFrames().
+class SpdyControlFrameMatcher
+    : public testing::MatcherInterface<absl::string_view> {
+ public:
+  explicit SpdyControlFrameMatcher(
+      std::vector<TypeAndOptionalLength> types_and_lengths)
+      : expected_types_and_lengths_(std::move(types_and_lengths)) {}
+
+  bool MatchAndExplain(absl::string_view s,
+                       testing::MatchResultListener* listener) const override {
+    quiche::QuicheDataReader reader(s.data(), s.size());
+
+    for (TypeAndOptionalLength expected : expected_types_and_lengths_) {
+      if (!MatchAndExplainOneFrame(expected.first, expected.second, &reader,
+                                   listener)) {
+        return false;
+      }
+    }
+    if (!reader.IsDoneReading()) {
+      *listener << "; " << reader.BytesRemaining() << " bytes left to read!";
+      return false;
+    }
+    return true;
+  }
+
+  bool MatchAndExplainOneFrame(spdy::SpdyFrameType expected_type,
+                               absl::optional<size_t> expected_length,
+                               quiche::QuicheDataReader* reader,
+                               testing::MatchResultListener* listener) const {
+    uint32_t payload_length;
+    if (!reader->ReadUInt24(&payload_length)) {
+      *listener << "; unable to read length field for expected_type "
+                << FrameTypeToString(expected_type) << ". data too short!";
+      return false;
+    }
+
+    if (expected_length && payload_length != expected_length.value()) {
+      *listener << "; actual length: " << payload_length
+                << " but expected length: " << expected_length.value();
+      return false;
+    }
+
+    uint8_t raw_type;
+    if (!reader->ReadUInt8(&raw_type)) {
+      *listener << "; unable to read type field for expected_type "
+                << FrameTypeToString(expected_type) << ". data too short!";
+      return false;
+    }
+
+    if (raw_type != static_cast<uint8_t>(expected_type)) {
+      *listener << "; actual type: " << FrameTypeToString(raw_type)
+                << " but expected type: " << FrameTypeToString(expected_type);
+      return false;
+    }
+
+    // Seek past flags (1B), stream ID (4B), and payload. Reach the next frame.
+    reader->Seek(5 + payload_length);
+    return true;
+  }
+
+  void DescribeTo(std::ostream* os) const override {
+    *os << "Data contains frames of types in sequence "
+        << expected_types_and_lengths_;
+  }
+
+  void DescribeNegationTo(std::ostream* os) const override {
+    *os << "Data does not contain frames of types in sequence "
+        << expected_types_and_lengths_;
+  }
+
+ private:
+  const std::vector<TypeAndOptionalLength> expected_types_and_lengths_;
+};
+
+}  // namespace
+
+testing::Matcher<absl::string_view> EqualsFrames(
+    std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
+        types_and_lengths) {
+  return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
+}
+
+testing::Matcher<absl::string_view> EqualsFrames(
+    std::vector<spdy::SpdyFrameType> types) {
+  std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
+      types_and_lengths;
+  types_and_lengths.reserve(types.size());
+  for (spdy::SpdyFrameType type : types) {
+    types_and_lengths.push_back({type, absl::nullopt});
+  }
+  return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
+}
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/test_utils.h b/quiche/http2/adapter/test_utils.h
new file mode 100644
index 0000000..d71a400
--- /dev/null
+++ b/quiche/http2/adapter/test_utils.h
@@ -0,0 +1,139 @@
+#ifndef QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
+#define QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/adapter/data_source.h"
+#include "quiche/http2/adapter/http2_protocol.h"
+#include "quiche/http2/adapter/mock_http2_visitor.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+class QUICHE_NO_EXPORT DataSavingVisitor
+    : public testing::StrictMock<MockHttp2Visitor> {
+ public:
+  int64_t OnReadyToSend(absl::string_view data) override {
+    if (has_write_error_) {
+      return kSendError;
+    }
+    if (is_write_blocked_) {
+      return kSendBlocked;
+    }
+    const size_t to_accept = std::min(send_limit_, data.size());
+    if (to_accept == 0) {
+      return kSendBlocked;
+    }
+    absl::StrAppend(&data_, data.substr(0, to_accept));
+    return to_accept;
+  }
+
+  bool OnMetadataForStream(Http2StreamId stream_id,
+                           absl::string_view metadata) override {
+    const bool ret = testing::StrictMock<MockHttp2Visitor>::OnMetadataForStream(
+        stream_id, metadata);
+    if (ret) {
+      auto result =
+          metadata_map_.try_emplace(stream_id, std::vector<std::string>());
+      result.first->second.push_back(std::string(metadata));
+    }
+    return ret;
+  }
+
+  const std::vector<std::string> GetMetadata(Http2StreamId stream_id) {
+    auto it = metadata_map_.find(stream_id);
+    if (it == metadata_map_.end()) {
+      return {};
+    } else {
+      return it->second;
+    }
+  }
+
+  const std::string& data() { return data_; }
+  void Clear() { data_.clear(); }
+
+  void set_send_limit(size_t limit) { send_limit_ = limit; }
+
+  bool is_write_blocked() const { return is_write_blocked_; }
+  void set_is_write_blocked(bool value) { is_write_blocked_ = value; }
+
+  void set_has_write_error() { has_write_error_ = true; }
+
+ private:
+  std::string data_;
+  absl::flat_hash_map<Http2StreamId, std::vector<std::string>> metadata_map_;
+  size_t send_limit_ = std::numeric_limits<size_t>::max();
+  bool is_write_blocked_ = false;
+  bool has_write_error_ = false;
+};
+
+// A test DataFrameSource. Starts out in the empty, blocked state.
+class QUICHE_NO_EXPORT TestDataFrameSource : public DataFrameSource {
+ public:
+  TestDataFrameSource(Http2VisitorInterface& visitor, bool has_fin);
+
+  void AppendPayload(absl::string_view payload);
+  void EndData();
+  void SimulateError() { return_error_ = true; }
+
+  std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) override;
+  bool Send(absl::string_view frame_header, size_t payload_length) override;
+  bool send_fin() const override { return has_fin_; }
+
+ private:
+  Http2VisitorInterface& visitor_;
+  std::vector<std::string> payload_fragments_;
+  absl::string_view current_fragment_;
+  // Whether the stream should end with the final frame of data.
+  const bool has_fin_;
+  // Whether |payload_fragments_| contains the final segment of data.
+  bool end_data_ = false;
+  // Whether SelectPayloadLength() should return an error.
+  bool return_error_ = false;
+};
+
+class QUICHE_NO_EXPORT TestMetadataSource : public MetadataSource {
+ public:
+  explicit TestMetadataSource(const spdy::SpdyHeaderBlock& entries);
+
+  size_t NumFrames(size_t max_frame_size) const override {
+    // Round up to the next frame.
+    return (encoded_entries_.size() + max_frame_size - 1) / max_frame_size;
+  }
+  std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override;
+  void OnFailure() override {}
+
+ private:
+  const std::string encoded_entries_;
+  absl::string_view remaining_;
+};
+
+// These matchers check whether a string consists entirely of HTTP/2 frames of
+// the specified ordered sequence. This is useful in tests where we want to show
+// that one or more particular frame types are serialized for sending to the
+// peer. The match will fail if there are input bytes not consumed by the
+// matcher.
+
+// Requires that frames match both types and lengths.
+testing::Matcher<absl::string_view> EqualsFrames(
+    std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
+        types_and_lengths);
+
+// Requires that frames match the specified types.
+testing::Matcher<absl::string_view> EqualsFrames(
+    std::vector<spdy::SpdyFrameType> types);
+
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
diff --git a/quiche/http2/adapter/test_utils_test.cc b/quiche/http2/adapter/test_utils_test.cc
new file mode 100644
index 0000000..0ea44dc
--- /dev/null
+++ b/quiche/http2/adapter/test_utils_test.cc
@@ -0,0 +1,123 @@
+#include "quiche/http2/adapter/test_utils.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+namespace {
+
+using spdy::SpdyFramer;
+
+TEST(EqualsFrames, Empty) {
+  EXPECT_THAT("", EqualsFrames(std::vector<spdy::SpdyFrameType>{}));
+}
+
+TEST(EqualsFrames, SingleFrameWithLength) {
+  SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
+
+  spdy::SpdyPingIR ping{511};
+  EXPECT_THAT(framer.SerializeFrame(ping),
+              EqualsFrames({{spdy::SpdyFrameType::PING, 8}}));
+
+  spdy::SpdyWindowUpdateIR window_update{1, 101};
+  EXPECT_THAT(framer.SerializeFrame(window_update),
+              EqualsFrames({{spdy::SpdyFrameType::WINDOW_UPDATE, 4}}));
+
+  spdy::SpdyDataIR data{3, "Some example data, ha ha!"};
+  EXPECT_THAT(framer.SerializeFrame(data),
+              EqualsFrames({{spdy::SpdyFrameType::DATA, 25}}));
+}
+
+TEST(EqualsFrames, SingleFrameWithoutLength) {
+  SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
+
+  spdy::SpdyRstStreamIR rst_stream{7, spdy::ERROR_CODE_REFUSED_STREAM};
+  EXPECT_THAT(framer.SerializeFrame(rst_stream),
+              EqualsFrames({{spdy::SpdyFrameType::RST_STREAM, absl::nullopt}}));
+
+  spdy::SpdyGoAwayIR goaway{13, spdy::ERROR_CODE_ENHANCE_YOUR_CALM,
+                            "Consider taking some deep breaths."};
+  EXPECT_THAT(framer.SerializeFrame(goaway),
+              EqualsFrames({{spdy::SpdyFrameType::GOAWAY, absl::nullopt}}));
+
+  spdy::Http2HeaderBlock block;
+  block[":method"] = "GET";
+  block[":path"] = "/example";
+  block[":authority"] = "example.com";
+  spdy::SpdyHeadersIR headers{17, std::move(block)};
+  EXPECT_THAT(framer.SerializeFrame(headers),
+              EqualsFrames({{spdy::SpdyFrameType::HEADERS, absl::nullopt}}));
+}
+
+TEST(EqualsFrames, MultipleFrames) {
+  SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
+
+  spdy::SpdyPingIR ping{511};
+  spdy::SpdyWindowUpdateIR window_update{1, 101};
+  spdy::SpdyDataIR data{3, "Some example data, ha ha!"};
+  spdy::SpdyRstStreamIR rst_stream{7, spdy::ERROR_CODE_REFUSED_STREAM};
+  spdy::SpdyGoAwayIR goaway{13, spdy::ERROR_CODE_ENHANCE_YOUR_CALM,
+                            "Consider taking some deep breaths."};
+  spdy::Http2HeaderBlock block;
+  block[":method"] = "GET";
+  block[":path"] = "/example";
+  block[":authority"] = "example.com";
+  spdy::SpdyHeadersIR headers{17, std::move(block)};
+
+  const std::string frame_sequence =
+      absl::StrCat(absl::string_view(framer.SerializeFrame(ping)),
+                   absl::string_view(framer.SerializeFrame(window_update)),
+                   absl::string_view(framer.SerializeFrame(data)),
+                   absl::string_view(framer.SerializeFrame(rst_stream)),
+                   absl::string_view(framer.SerializeFrame(goaway)),
+                   absl::string_view(framer.SerializeFrame(headers)));
+  absl::string_view frame_sequence_view = frame_sequence;
+  EXPECT_THAT(frame_sequence,
+              EqualsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
+                            {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
+                            {spdy::SpdyFrameType::DATA, 25},
+                            {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
+                            {spdy::SpdyFrameType::GOAWAY, 42},
+                            {spdy::SpdyFrameType::HEADERS, 19}}));
+  EXPECT_THAT(frame_sequence_view,
+              EqualsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
+                            {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
+                            {spdy::SpdyFrameType::DATA, 25},
+                            {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
+                            {spdy::SpdyFrameType::GOAWAY, 42},
+                            {spdy::SpdyFrameType::HEADERS, 19}}));
+  EXPECT_THAT(
+      frame_sequence,
+      EqualsFrames(
+          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+           spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::HEADERS}));
+  EXPECT_THAT(
+      frame_sequence_view,
+      EqualsFrames(
+          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+           spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::HEADERS}));
+
+  // If the final frame type is removed the expectation fails, as there are
+  // bytes left to read.
+  EXPECT_THAT(
+      frame_sequence,
+      testing::Not(EqualsFrames(
+          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+           spdy::SpdyFrameType::GOAWAY})));
+  EXPECT_THAT(
+      frame_sequence_view,
+      testing::Not(EqualsFrames(
+          {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+           spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+           spdy::SpdyFrameType::GOAWAY})));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/window_manager.cc b/quiche/http2/adapter/window_manager.cc
new file mode 100644
index 0000000..81eaa77
--- /dev/null
+++ b/quiche/http2/adapter/window_manager.cc
@@ -0,0 +1,103 @@
+#include "quiche/http2/adapter/window_manager.h"
+
+#include <utility>
+
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace http2 {
+namespace adapter {
+
+bool DefaultShouldWindowUpdateFn(int64_t limit, int64_t window, int64_t delta) {
+  // For the sake of efficiency, we want to send window updates if less than
+  // half of the max quota is available to the peer at any point in time.
+  const int64_t kDesiredMinWindow = limit / 2;
+  const int64_t kDesiredMinDelta = limit / 3;
+  if (delta >= kDesiredMinDelta) {
+    // This particular window update was sent because the available delta
+    // exceeded the desired minimum.
+    return true;
+  } else if (window < kDesiredMinWindow) {
+    // This particular window update was sent because the quota available to the
+    // peer at this moment is less than the desired minimum.
+    return true;
+  }
+  return false;
+}
+
+WindowManager::WindowManager(int64_t window_size_limit,
+                             WindowUpdateListener listener,
+                             ShouldWindowUpdateFn should_window_update_fn,
+                             bool update_window_on_notify)
+    : limit_(window_size_limit),
+      window_(window_size_limit),
+      buffered_(0),
+      listener_(std::move(listener)),
+      should_window_update_fn_(std::move(should_window_update_fn)),
+      update_window_on_notify_(update_window_on_notify) {
+  if (!should_window_update_fn_) {
+    should_window_update_fn_ = DefaultShouldWindowUpdateFn;
+  }
+}
+
+void WindowManager::OnWindowSizeLimitChange(const int64_t new_limit) {
+  QUICHE_VLOG(2) << "WindowManager@" << this
+                 << " OnWindowSizeLimitChange from old limit of " << limit_
+                 << " to new limit of " << new_limit;
+  window_ += (new_limit - limit_);
+  limit_ = new_limit;
+}
+
+void WindowManager::SetWindowSizeLimit(int64_t new_limit) {
+  QUICHE_VLOG(2) << "WindowManager@" << this
+                 << " SetWindowSizeLimit from old limit of " << limit_
+                 << " to new limit of " << new_limit;
+  limit_ = new_limit;
+  MaybeNotifyListener();
+}
+
+bool WindowManager::MarkDataBuffered(int64_t bytes) {
+  QUICHE_VLOG(2) << "WindowManager@" << this << " window: " << window_
+                 << " bytes: " << bytes;
+  if (window_ < bytes) {
+    QUICHE_VLOG(2) << "WindowManager@" << this << " window underflow "
+                   << "window: " << window_ << " bytes: " << bytes;
+    window_ = 0;
+  } else {
+    window_ -= bytes;
+  }
+  buffered_ += bytes;
+  if (window_ == 0) {
+    // If data hasn't been flushed in a while there may be space available.
+    MaybeNotifyListener();
+  }
+  return window_ > 0;
+}
+
+void WindowManager::MarkDataFlushed(int64_t bytes) {
+  QUICHE_VLOG(2) << "WindowManager@" << this << " buffered: " << buffered_
+                 << " bytes: " << bytes;
+  if (buffered_ < bytes) {
+    QUICHE_BUG(bug_2816_1) << "WindowManager@" << this << " buffered underflow "
+                           << "buffered_: " << buffered_ << " bytes: " << bytes;
+    buffered_ = 0;
+  } else {
+    buffered_ -= bytes;
+  }
+  MaybeNotifyListener();
+}
+
+void WindowManager::MaybeNotifyListener() {
+  const int64_t delta = limit_ - (buffered_ + window_);
+  if (should_window_update_fn_(limit_, window_, delta) && delta > 0) {
+    QUICHE_VLOG(2) << "WindowManager@" << this
+                   << " Informing listener of delta: " << delta;
+    listener_(delta);
+    if (update_window_on_notify_) {
+      window_ += delta;
+    }
+  }
+}
+
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/adapter/window_manager.h b/quiche/http2/adapter/window_manager.h
new file mode 100644
index 0000000..272f96c
--- /dev/null
+++ b/quiche/http2/adapter/window_manager.h
@@ -0,0 +1,92 @@
+#ifndef QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_
+#define QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_
+
+#include <stddef.h>
+
+#include <functional>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace adapter {
+
+namespace test {
+class WindowManagerPeer;
+}
+
+// This class keeps track of a HTTP/2 flow control window, notifying a listener
+// when a window update needs to be sent. This class is not thread-safe.
+class QUICHE_EXPORT_PRIVATE WindowManager {
+ public:
+  // A WindowUpdateListener is invoked when it is time to send a window update.
+  using WindowUpdateListener = std::function<void(int64_t)>;
+
+  // Invoked to determine whether to call the listener based on the window
+  // limit, window size, and delta that would be sent.
+  using ShouldWindowUpdateFn =
+      std::function<bool(int64_t limit, int64_t size, int64_t delta)>;
+
+  WindowManager(int64_t window_size_limit, WindowUpdateListener listener,
+                ShouldWindowUpdateFn should_window_update_fn = {},
+                bool update_window_on_notify = true);
+
+  int64_t CurrentWindowSize() const { return window_; }
+  int64_t WindowSizeLimit() const { return limit_; }
+
+  // Called when the window size limit is changed (typically via settings) but
+  // no window update should be sent.
+  void OnWindowSizeLimitChange(int64_t new_limit);
+
+  // Sets the window size limit to |new_limit| and notifies the listener to
+  // update as necessary.
+  void SetWindowSizeLimit(int64_t new_limit);
+
+  // Increments the running total of data bytes buffered. Returns true iff there
+  // is more window remaining.
+  bool MarkDataBuffered(int64_t bytes);
+
+  // Increments the running total of data bytes that have been flushed or
+  // dropped. Invokes the listener if the current window is smaller than some
+  // threshold and there is quota available to send.
+  void MarkDataFlushed(int64_t bytes);
+
+  // Convenience method, used when incoming data is immediately dropped or
+  // ignored.
+  void MarkWindowConsumed(int64_t bytes) {
+    MarkDataBuffered(bytes);
+    MarkDataFlushed(bytes);
+  }
+
+  // Increments the window size without affecting the limit. Useful if this end
+  // of a stream or connection issues a one-time WINDOW_UPDATE.
+  void IncreaseWindow(int64_t delta) { window_ += delta; }
+
+ private:
+  friend class test::WindowManagerPeer;
+
+  void MaybeNotifyListener();
+
+  // The upper bound on the flow control window. The GFE attempts to maintain a
+  // window of this size at the peer as data is proxied through.
+  int64_t limit_;
+
+  // The current flow control window that has not been advertised to the peer
+  // and not yet consumed. The peer can send this many bytes before becoming
+  // blocked.
+  int64_t window_;
+
+  // The amount of data already buffered, which should count against the flow
+  // control window upper bound.
+  int64_t buffered_;
+
+  WindowUpdateListener listener_;
+
+  ShouldWindowUpdateFn should_window_update_fn_;
+
+  bool update_window_on_notify_;
+};
+
+}  // namespace adapter
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_
diff --git a/quiche/http2/adapter/window_manager_test.cc b/quiche/http2/adapter/window_manager_test.cc
new file mode 100644
index 0000000..9c92e71
--- /dev/null
+++ b/quiche/http2/adapter/window_manager_test.cc
@@ -0,0 +1,336 @@
+#include "quiche/http2/adapter/window_manager.h"
+
+#include <list>
+
+#include "absl/functional/bind_front.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+
+namespace http2 {
+namespace adapter {
+namespace test {
+
+// Use the peer to access private vars of WindowManager.
+class WindowManagerPeer {
+ public:
+  explicit WindowManagerPeer(const WindowManager& wm) : wm_(wm) {}
+
+  int64_t buffered() { return wm_.buffered_; }
+
+ private:
+  const WindowManager& wm_;
+};
+
+namespace {
+
+class WindowManagerTest : public ::testing::Test {
+ protected:
+  WindowManagerTest()
+      : wm_(kDefaultLimit, absl::bind_front(&WindowManagerTest::OnCall, this)),
+        peer_(wm_) {}
+
+  void OnCall(int64_t s) { call_sequence_.push_back(s); }
+
+  const int64_t kDefaultLimit = 32 * 1024 * 3;
+  std::list<int64_t> call_sequence_;
+  WindowManager wm_;
+  WindowManagerPeer peer_;
+  ::http2::test::Http2Random random_;
+};
+
+// A few no-op calls.
+TEST_F(WindowManagerTest, NoOps) {
+  wm_.SetWindowSizeLimit(kDefaultLimit);
+  wm_.SetWindowSizeLimit(0);
+  wm_.SetWindowSizeLimit(kDefaultLimit);
+  wm_.MarkDataBuffered(0);
+  wm_.MarkDataFlushed(0);
+  EXPECT_TRUE(call_sequence_.empty());
+}
+
+// This test verifies that WindowManager does not notify its listener when data
+// is only buffered, and never flushed.
+TEST_F(WindowManagerTest, DataOnlyBuffered) {
+  int64_t total = 0;
+  while (total < kDefaultLimit) {
+    int64_t s = std::min<int64_t>(kDefaultLimit - total, random_.Uniform(1024));
+    total += s;
+    wm_.MarkDataBuffered(s);
+  }
+  EXPECT_THAT(call_sequence_, ::testing::IsEmpty());
+}
+
+// This test verifies that WindowManager does notify its listener when data is
+// buffered and subsequently flushed.
+TEST_F(WindowManagerTest, DataBufferedAndFlushed) {
+  int64_t total_buffered = 0;
+  int64_t total_flushed = 0;
+  while (call_sequence_.empty()) {
+    int64_t buffered = std::min<int64_t>(kDefaultLimit - total_buffered,
+                                         random_.Uniform(1024));
+    wm_.MarkDataBuffered(buffered);
+    total_buffered += buffered;
+    EXPECT_TRUE(call_sequence_.empty());
+    int64_t flushed = random_.Uniform(total_buffered - total_flushed);
+    wm_.MarkDataFlushed(flushed);
+    total_flushed += flushed;
+  }
+  // If WindowManager decided to send an update, at least one third of the
+  // window must have been consumed by buffered data.
+  EXPECT_GE(total_buffered, kDefaultLimit / 3);
+}
+
+// Window manager should avoid window underflow.
+TEST_F(WindowManagerTest, AvoidWindowUnderflow) {
+  EXPECT_EQ(wm_.CurrentWindowSize(), wm_.WindowSizeLimit());
+  // Don't buffer more than the total window!
+  wm_.MarkDataBuffered(wm_.WindowSizeLimit() + 1);
+  EXPECT_EQ(wm_.CurrentWindowSize(), 0u);
+}
+
+// Window manager should GFE_BUG and avoid buffered underflow.
+TEST_F(WindowManagerTest, AvoidBufferedUnderflow) {
+  EXPECT_EQ(peer_.buffered(), 0u);
+  // Don't flush more than has been buffered!
+  EXPECT_QUICHE_BUG(wm_.MarkDataFlushed(1), "buffered underflow");
+  EXPECT_EQ(peer_.buffered(), 0u);
+
+  wm_.MarkDataBuffered(42);
+  EXPECT_EQ(peer_.buffered(), 42u);
+  // Don't flush more than has been buffered!
+  EXPECT_QUICHE_BUG(wm_.MarkDataFlushed(43), "buffered underflow");
+  EXPECT_EQ(peer_.buffered(), 0u);
+}
+
+// This test verifies that WindowManager notifies its listener when window is
+// consumed (data is ignored or immediately dropped).
+TEST_F(WindowManagerTest, WindowConsumed) {
+  int64_t consumed = kDefaultLimit / 3 - 1;
+  wm_.MarkWindowConsumed(consumed);
+  EXPECT_TRUE(call_sequence_.empty());
+  const int64_t extra = 1;
+  wm_.MarkWindowConsumed(extra);
+  EXPECT_THAT(call_sequence_, testing::ElementsAre(consumed + extra));
+}
+
+// This test verifies that WindowManager notifies its listener when the window
+// size limit is increased.
+TEST_F(WindowManagerTest, ListenerCalledOnSizeUpdate) {
+  wm_.SetWindowSizeLimit(kDefaultLimit - 1024);
+  EXPECT_TRUE(call_sequence_.empty());
+  wm_.SetWindowSizeLimit(kDefaultLimit * 5);
+  // Because max(outstanding window, previous limit) is kDefaultLimit, it is
+  // only appropriate to increase the window by kDefaultLimit * 4.
+  EXPECT_THAT(call_sequence_, testing::ElementsAre(kDefaultLimit * 4));
+}
+
+// This test verifies that when data is buffered and then the limit is
+// decreased, WindowManager only notifies the listener once any outstanding
+// window has been consumed.
+TEST_F(WindowManagerTest, WindowUpdateAfterLimitDecreased) {
+  wm_.MarkDataBuffered(kDefaultLimit - 1024);
+  wm_.SetWindowSizeLimit(kDefaultLimit - 2048);
+
+  // Now there are 2048 bytes of window outstanding beyond the current limit,
+  // and we have 1024 bytes of data buffered beyond the current limit. This is
+  // intentional, to be sure that WindowManager works properly if the limit is
+  // decreased at runtime.
+
+  wm_.MarkDataFlushed(512);
+  EXPECT_TRUE(call_sequence_.empty());
+  wm_.MarkDataFlushed(512);
+  EXPECT_TRUE(call_sequence_.empty());
+  wm_.MarkDataFlushed(512);
+  EXPECT_TRUE(call_sequence_.empty());
+  wm_.MarkDataFlushed(1024);
+  EXPECT_THAT(call_sequence_, testing::ElementsAre(512));
+}
+
+// For normal behavior, we only call MaybeNotifyListener() when data is
+// flushed. But if window runs out entirely, we still need to call
+// MaybeNotifyListener() to avoid becoming artificially blocked when data isn't
+// being flushed.
+TEST_F(WindowManagerTest, ZeroWindowNotification) {
+  // Consume a byte of window, but not enough to trigger an update.
+  wm_.MarkWindowConsumed(1);
+
+  // Buffer the remaining window.
+  wm_.MarkDataBuffered(kDefaultLimit - 1);
+  // Listener is notified of the remaining byte of possible window.
+  EXPECT_THAT(call_sequence_, testing::ElementsAre(1));
+}
+
+TEST_F(WindowManagerTest, OnWindowSizeLimitChange) {
+  wm_.MarkDataBuffered(10000);
+  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 10000);
+  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);
+
+  wm_.OnWindowSizeLimitChange(kDefaultLimit + 1000);
+  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 9000);
+  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit + 1000);
+
+  wm_.OnWindowSizeLimitChange(kDefaultLimit - 1000);
+  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 11000);
+  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit - 1000);
+}
+
+TEST_F(WindowManagerTest, NegativeWindowSize) {
+  wm_.MarkDataBuffered(80000);
+  // 98304 window - 80000 buffered = 18304 available
+  EXPECT_EQ(wm_.CurrentWindowSize(), 18304);
+  wm_.OnWindowSizeLimitChange(65535);
+  // limit decreases by 98304 - 65535 = 32769, window becomes -14465
+  EXPECT_EQ(wm_.CurrentWindowSize(), -14465);
+  wm_.MarkDataFlushed(70000);
+  // Still 10000 bytes buffered, so window manager grants sufficient quota to
+  // reach a window of 65535 - 10000.
+  EXPECT_EQ(wm_.CurrentWindowSize(), 55535);
+  // Desired window minus existing window: 55535 - (-14465) = 70000
+  EXPECT_THAT(call_sequence_, testing::ElementsAre(70000));
+}
+
+TEST_F(WindowManagerTest, IncreaseWindow) {
+  wm_.MarkDataBuffered(1000);
+  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 1000);
+  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);
+
+  // Increasing the window beyond the limit is allowed.
+  wm_.IncreaseWindow(5000);
+  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit + 4000);
+  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);
+
+  // 80000 bytes are buffered, then flushed.
+  wm_.MarkWindowConsumed(80000);
+  // The window manager replenishes the consumed quota up to the limit.
+  EXPECT_THAT(call_sequence_, testing::ElementsAre(75000));
+  // The window is the limit, minus buffered data, as expected.
+  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 1000);
+}
+
+// This test verifies that when the constructor option is specified,
+// WindowManager does not update its internal accounting of the flow control
+// window when notifying the listener.
+TEST(WindowManagerNoUpdateTest, NoWindowUpdateOnListener) {
+  const int64_t kDefaultLimit = 65535;
+
+  std::list<int64_t> call_sequence1;
+  WindowManager wm1(
+      kDefaultLimit,
+      [&call_sequence1](int64_t delta) { call_sequence1.push_back(delta); },
+      /*should_notify_listener=*/{},
+      /*update_window_on_notify=*/true);  // default
+  std::list<int64_t> call_sequence2;
+  WindowManager wm2(
+      kDefaultLimit,
+      [&call_sequence2](int64_t delta) { call_sequence2.push_back(delta); },
+      /*should_notify_listener=*/{},
+      /*update_window_on_notify=*/false);
+
+  const int64_t consumed = kDefaultLimit / 3 - 1;
+
+  wm1.MarkWindowConsumed(consumed);
+  EXPECT_TRUE(call_sequence1.empty());
+  wm2.MarkWindowConsumed(consumed);
+  EXPECT_TRUE(call_sequence2.empty());
+
+  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit - consumed);
+  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit - consumed);
+
+  const int64_t extra = 1;
+  wm1.MarkWindowConsumed(extra);
+  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed + extra));
+  // Window size *is* updated after invoking the listener.
+  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit);
+  call_sequence1.clear();
+
+  wm2.MarkWindowConsumed(extra);
+  EXPECT_THAT(call_sequence2, testing::ElementsAre(consumed + extra));
+  // Window size is *not* updated after invoking the listener.
+  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit - (consumed + extra));
+  call_sequence2.clear();
+
+  // Manually increase the window by the listener notification amount.
+  wm2.IncreaseWindow(consumed + extra);
+  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit);
+
+  wm1.SetWindowSizeLimit(kDefaultLimit * 5);
+  EXPECT_THAT(call_sequence1, testing::ElementsAre(kDefaultLimit * 4));
+  // *Does* update the window size.
+  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit * 5);
+
+  wm2.SetWindowSizeLimit(kDefaultLimit * 5);
+  EXPECT_THAT(call_sequence2, testing::ElementsAre(kDefaultLimit * 4));
+  // Does *not* update the window size.
+  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit);
+}
+
+// This test verifies that when the constructor option is specified,
+// WindowManager uses the provided ShouldWindowUpdateFn to determine when to
+// notify the listener.
+TEST(WindowManagerShouldUpdateTest, CustomShouldWindowUpdateFn) {
+  const int64_t kDefaultLimit = 65535;
+
+  // This window manager should always notify.
+  std::list<int64_t> call_sequence1;
+  WindowManager wm1(
+      kDefaultLimit,
+      [&call_sequence1](int64_t delta) { call_sequence1.push_back(delta); },
+      [](int64_t /*limit*/, int64_t /*window*/, int64_t /*delta*/) {
+        return true;
+      });
+  // This window manager should never notify.
+  std::list<int64_t> call_sequence2;
+  WindowManager wm2(
+      kDefaultLimit,
+      [&call_sequence2](int64_t delta) { call_sequence2.push_back(delta); },
+      [](int64_t /*limit*/, int64_t /*window*/, int64_t /*delta*/) {
+        return false;
+      });
+  // This window manager should notify as long as no data is buffered.
+  std::list<int64_t> call_sequence3;
+  WindowManager wm3(
+      kDefaultLimit,
+      [&call_sequence3](int64_t delta) { call_sequence3.push_back(delta); },
+      [](int64_t limit, int64_t window, int64_t delta) {
+        return delta == limit - window;
+      });
+
+  const int64_t consumed = kDefaultLimit / 4;
+
+  wm1.MarkWindowConsumed(consumed);
+  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed));
+  wm2.MarkWindowConsumed(consumed);
+  EXPECT_TRUE(call_sequence2.empty());
+  wm3.MarkWindowConsumed(consumed);
+  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));
+
+  const int64_t buffered = 42;
+
+  wm1.MarkDataBuffered(buffered);
+  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed));
+  wm2.MarkDataBuffered(buffered);
+  EXPECT_TRUE(call_sequence2.empty());
+  wm3.MarkDataBuffered(buffered);
+  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));
+
+  wm1.MarkDataFlushed(buffered / 3);
+  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed, buffered / 3));
+  wm2.MarkDataFlushed(buffered / 3);
+  EXPECT_TRUE(call_sequence2.empty());
+  wm3.MarkDataFlushed(buffered / 3);
+  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));
+
+  wm1.MarkDataFlushed(2 * buffered / 3);
+  EXPECT_THAT(call_sequence1,
+              testing::ElementsAre(consumed, buffered / 3, 2 * buffered / 3));
+  wm2.MarkDataFlushed(2 * buffered / 3);
+  EXPECT_TRUE(call_sequence2.empty());
+  wm3.MarkDataFlushed(2 * buffered / 3);
+  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed, buffered));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace adapter
+}  // namespace http2
diff --git a/quiche/http2/core/http2_trace_logging.cc b/quiche/http2/core/http2_trace_logging.cc
new file mode 100644
index 0000000..e21e5c4
--- /dev/null
+++ b/quiche/http2/core/http2_trace_logging.cc
@@ -0,0 +1,459 @@
+#include "quiche/http2/core/http2_trace_logging.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+// Convenience macros for printing function arguments in log lines in the
+// format arg_name=value.
+#define FORMAT_ARG(arg) " " #arg "=" << arg
+#define FORMAT_INT_ARG(arg) " " #arg "=" << static_cast<int>(arg)
+
+// Convenience macros for printing Spdy*IR attributes in log lines in the
+// format attrib_name=value.
+#define FORMAT_ATTR(ir, attrib) " " #attrib "=" << ir.attrib()
+#define FORMAT_INT_ATTR(ir, attrib) \
+  " " #attrib "=" << static_cast<int>(ir.attrib())
+
+namespace {
+
+// Logs a container, using a user-provided object to log each individual item.
+template <typename T, typename ItemLogger>
+struct ContainerLogger {
+  explicit ContainerLogger(const T& c, ItemLogger l)
+      : container(c), item_logger(l) {}
+
+  friend std::ostream& operator<<(std::ostream& out,
+                                  const ContainerLogger& logger) {
+    out << "[";
+    auto begin = logger.container.begin();
+    for (auto it = begin; it != logger.container.end(); ++it) {
+      if (it != begin) {
+        out << ", ";
+      }
+      logger.item_logger.Log(out, *it);
+    }
+    out << "]";
+    return out;
+  }
+  const T& container;
+  ItemLogger item_logger;
+};
+
+// Returns a ContainerLogger that will log |container| using |item_logger|.
+template <typename T, typename ItemLogger>
+auto LogContainer(const T& container, ItemLogger item_logger)
+    -> decltype(ContainerLogger<T, ItemLogger>(container, item_logger)) {
+  return ContainerLogger<T, ItemLogger>(container, item_logger);
+}
+
+}  // anonymous namespace
+
+#define FORMAT_HEADER_BLOCK(ir) \
+  " header_block=" << LogContainer(ir.header_block(), LogHeaderBlockEntry())
+
+namespace http2 {
+
+using spdy::SettingsMap;
+using spdy::SpdyAltSvcIR;
+using spdy::SpdyContinuationIR;
+using spdy::SpdyDataIR;
+using spdy::SpdyGoAwayIR;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyPingIR;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdyRstStreamIR;
+using spdy::SpdySettingsIR;
+using spdy::SpdyStreamId;
+using spdy::SpdyUnknownIR;
+using spdy::SpdyWindowUpdateIR;
+
+namespace {
+
+// Defines how elements of SpdyHeaderBlocks are logged.
+struct LogHeaderBlockEntry {
+  void Log(std::ostream& out,
+           const SpdyHeaderBlock::value_type& entry) const {  // NOLINT
+    out << "\"" << entry.first << "\": \"" << entry.second << "\"";
+  }
+};
+
+// Defines how elements of SettingsMap are logged.
+struct LogSettingsEntry {
+  void Log(std::ostream& out,
+           const SettingsMap::value_type& entry) const {  // NOLINT
+    out << spdy::SettingsIdToString(entry.first) << ": " << entry.second;
+  }
+};
+
+// Defines how elements of AlternativeServiceVector are logged.
+struct LogAlternativeService {
+  void Log(std::ostream& out,
+           const spdy::SpdyAltSvcWireFormat::AlternativeService& altsvc)
+      const {  // NOLINT
+    out << "{"
+        << "protocol_id=" << altsvc.protocol_id << " host=" << altsvc.host
+        << " port=" << altsvc.port
+        << " max_age_seconds=" << altsvc.max_age_seconds << " version=";
+    for (auto v : altsvc.version) {
+      out << v << ",";
+    }
+    out << "}";
+  }
+};
+
+}  // anonymous namespace
+
+Http2TraceLogger::Http2TraceLogger(SpdyFramerVisitorInterface* parent,
+                                   absl::string_view perspective,
+                                   std::function<bool()> is_enabled,
+                                   const void* connection_id)
+    : wrapped_(parent),
+      perspective_(perspective),
+      is_enabled_(std::move(is_enabled)),
+      connection_id_(connection_id) {}
+
+Http2TraceLogger::~Http2TraceLogger() {
+  if (recording_headers_handler_ != nullptr &&
+      !recording_headers_handler_->decoded_block().empty()) {
+    HTTP2_TRACE_LOG(perspective_, is_enabled_)
+        << "connection_id=" << connection_id_
+        << " Received headers that were never logged! keys/values:"
+        << recording_headers_handler_->decoded_block().DebugString();
+  }
+}
+
+void Http2TraceLogger::OnError(Http2DecoderAdapter::SpdyFramerError error,
+                               std::string detailed_error) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnError:" << FORMAT_ARG(connection_id_)
+      << ", error=" << Http2DecoderAdapter::SpdyFramerErrorToString(error);
+  wrapped_->OnError(error, detailed_error);
+}
+
+void Http2TraceLogger::OnCommonHeader(SpdyStreamId stream_id, size_t length,
+                                      uint8_t type, uint8_t flags) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnCommonHeader:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_INT_ARG(type)
+      << FORMAT_INT_ARG(flags);
+  wrapped_->OnCommonHeader(stream_id, length, type, flags);
+}
+
+void Http2TraceLogger::OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
+                                        bool fin) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnDataFrameHeader:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_ARG(fin);
+  wrapped_->OnDataFrameHeader(stream_id, length, fin);
+}
+
+void Http2TraceLogger::OnStreamFrameData(SpdyStreamId stream_id,
+                                        const char* data, size_t len) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnStreamFrameData:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
+  wrapped_->OnStreamFrameData(stream_id, data, len);
+}
+
+void Http2TraceLogger::OnStreamEnd(SpdyStreamId stream_id) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnStreamEnd:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id);
+  wrapped_->OnStreamEnd(stream_id);
+}
+
+void Http2TraceLogger::OnStreamPadLength(SpdyStreamId stream_id, size_t value) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnStreamPadLength:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(value);
+  wrapped_->OnStreamPadLength(stream_id, value);
+}
+
+void Http2TraceLogger::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnStreamPadding:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
+  wrapped_->OnStreamPadding(stream_id, len);
+}
+
+spdy::SpdyHeadersHandlerInterface* Http2TraceLogger::OnHeaderFrameStart(
+    SpdyStreamId stream_id) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnHeaderFrameStart:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id);
+  spdy::SpdyHeadersHandlerInterface* result =
+      wrapped_->OnHeaderFrameStart(stream_id);
+  if (is_enabled_()) {
+    recording_headers_handler_ =
+        absl::make_unique<spdy::RecordingHeadersHandler>(result);
+    result = recording_headers_handler_.get();
+  } else {
+    recording_headers_handler_ = nullptr;
+  }
+  return result;
+}
+
+void Http2TraceLogger::OnHeaderFrameEnd(SpdyStreamId stream_id) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnHeaderFrameEnd:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id);
+  LogReceivedHeaders();
+  wrapped_->OnHeaderFrameEnd(stream_id);
+  recording_headers_handler_ = nullptr;
+}
+
+void Http2TraceLogger::OnRstStream(SpdyStreamId stream_id,
+                                  SpdyErrorCode error_code) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnRstStream:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
+      << " error_code=" << spdy::ErrorCodeToString(error_code);
+  wrapped_->OnRstStream(stream_id, error_code);
+}
+
+void Http2TraceLogger::OnSettings() { wrapped_->OnSettings(); }
+
+void Http2TraceLogger::OnSetting(SpdySettingsId id, uint32_t value) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnSetting:" << FORMAT_ARG(connection_id_)
+      << " id=" << spdy::SettingsIdToString(id) << FORMAT_ARG(value);
+  wrapped_->OnSetting(id, value);
+}
+
+void Http2TraceLogger::OnSettingsEnd() {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnSettingsEnd:" << FORMAT_ARG(connection_id_);
+  wrapped_->OnSettingsEnd();
+}
+
+void Http2TraceLogger::OnSettingsAck() {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnSettingsAck:" << FORMAT_ARG(connection_id_);
+  wrapped_->OnSettingsAck();
+}
+
+void Http2TraceLogger::OnPing(SpdyPingId unique_id, bool is_ack) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnPing:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(unique_id)
+      << FORMAT_ARG(is_ack);
+  wrapped_->OnPing(unique_id, is_ack);
+}
+
+void Http2TraceLogger::OnGoAway(SpdyStreamId last_accepted_stream_id,
+                               SpdyErrorCode error_code) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnGoAway:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(last_accepted_stream_id)
+      << " error_code=" << spdy::ErrorCodeToString(error_code);
+  wrapped_->OnGoAway(last_accepted_stream_id, error_code);
+}
+
+bool Http2TraceLogger::OnGoAwayFrameData(const char* goaway_data, size_t len) {
+  return wrapped_->OnGoAwayFrameData(goaway_data, len);
+}
+
+void Http2TraceLogger::OnHeaders(SpdyStreamId stream_id, bool has_priority,
+                                int weight, SpdyStreamId parent_stream_id,
+                                bool exclusive, bool fin, bool end) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnHeaders:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
+      << FORMAT_ARG(has_priority) << FORMAT_INT_ARG(weight)
+      << FORMAT_ARG(parent_stream_id) << FORMAT_ARG(exclusive)
+      << FORMAT_ARG(fin) << FORMAT_ARG(end);
+  wrapped_->OnHeaders(stream_id, has_priority, weight, parent_stream_id,
+                      exclusive, fin, end);
+}
+
+void Http2TraceLogger::OnWindowUpdate(SpdyStreamId stream_id,
+                                     int delta_window_size) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnWindowUpdate:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(delta_window_size);
+  wrapped_->OnWindowUpdate(stream_id, delta_window_size);
+}
+
+void Http2TraceLogger::OnPushPromise(SpdyStreamId original_stream_id,
+                                    SpdyStreamId promised_stream_id, bool end) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnPushPromise:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(original_stream_id) << FORMAT_ARG(promised_stream_id)
+      << FORMAT_ARG(end);
+  wrapped_->OnPushPromise(original_stream_id, promised_stream_id, end);
+}
+
+void Http2TraceLogger::OnContinuation(SpdyStreamId stream_id, bool end) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnContinuation:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_ARG(end);
+  wrapped_->OnContinuation(stream_id, end);
+}
+
+void Http2TraceLogger::OnAltSvc(
+    SpdyStreamId stream_id, absl::string_view origin,
+    const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnAltSvc:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
+      << FORMAT_ARG(origin) << " altsvc_vector="
+      << LogContainer(altsvc_vector, LogAlternativeService());
+  wrapped_->OnAltSvc(stream_id, origin, altsvc_vector);
+}
+
+void Http2TraceLogger::OnPriority(SpdyStreamId stream_id,
+                                 SpdyStreamId parent_stream_id, int weight,
+                                 bool exclusive) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnPriority:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
+      << FORMAT_ARG(parent_stream_id) << FORMAT_INT_ARG(weight)
+      << FORMAT_ARG(exclusive);
+  wrapped_->OnPriority(stream_id, parent_stream_id, weight, exclusive);
+}
+
+void Http2TraceLogger::OnPriorityUpdate(
+    SpdyStreamId prioritized_stream_id,
+    absl::string_view priority_field_value) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnPriorityUpdate:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(prioritized_stream_id) << FORMAT_ARG(priority_field_value);
+  wrapped_->OnPriorityUpdate(prioritized_stream_id, priority_field_value);
+}
+
+bool Http2TraceLogger::OnUnknownFrame(SpdyStreamId stream_id,
+                                     uint8_t frame_type) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "OnUnknownFrame:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ARG(stream_id) << FORMAT_INT_ARG(frame_type);
+  return wrapped_->OnUnknownFrame(stream_id, frame_type);
+}
+
+void Http2TraceLogger::LogReceivedHeaders() const {
+  if (recording_headers_handler_ == nullptr) {
+    // Trace logging was not enabled when the start of the header block was
+    // received.
+    return;
+  }
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Received headers;" << FORMAT_ARG(connection_id_) << " keys/values:"
+      << recording_headers_handler_->decoded_block().DebugString()
+      << " compressed_bytes="
+      << recording_headers_handler_->compressed_header_bytes()
+      << " uncompressed_bytes="
+      << recording_headers_handler_->uncompressed_header_bytes();
+}
+
+void Http2FrameLogger::VisitRstStream(const SpdyRstStreamIR& rst_stream) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyRstStreamIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(rst_stream, stream_id)
+      << " error_code=" << spdy::ErrorCodeToString(rst_stream.error_code());
+}
+
+void Http2FrameLogger::VisitSettings(const SpdySettingsIR& settings) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdySettingsIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(settings, is_ack)
+      << " values=" << LogContainer(settings.values(), LogSettingsEntry());
+}
+
+void Http2FrameLogger::VisitPing(const SpdyPingIR& ping) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyPingIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(ping, id) << FORMAT_ATTR(ping, is_ack);
+}
+
+void Http2FrameLogger::VisitGoAway(const SpdyGoAwayIR& goaway) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyGoAwayIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(goaway, last_good_stream_id)
+      << " error_code=" << spdy::ErrorCodeToString(goaway.error_code())
+      << FORMAT_ATTR(goaway, description);
+}
+
+void Http2FrameLogger::VisitHeaders(const SpdyHeadersIR& headers) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyHeadersIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(headers, stream_id) << FORMAT_ATTR(headers, fin)
+      << FORMAT_ATTR(headers, has_priority) << FORMAT_INT_ATTR(headers, weight)
+      << FORMAT_ATTR(headers, parent_stream_id)
+      << FORMAT_ATTR(headers, exclusive) << FORMAT_ATTR(headers, padded)
+      << FORMAT_ATTR(headers, padding_payload_len)
+      << FORMAT_HEADER_BLOCK(headers);
+}
+
+void Http2FrameLogger::VisitWindowUpdate(
+    const SpdyWindowUpdateIR& window_update) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyWindowUpdateIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(window_update, stream_id)
+      << FORMAT_ATTR(window_update, delta);
+}
+
+void Http2FrameLogger::VisitPushPromise(const SpdyPushPromiseIR& push_promise) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyPushPromiseIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(push_promise, stream_id) << FORMAT_ATTR(push_promise, fin)
+      << FORMAT_ATTR(push_promise, promised_stream_id)
+      << FORMAT_ATTR(push_promise, padded)
+      << FORMAT_ATTR(push_promise, padding_payload_len)
+      << FORMAT_HEADER_BLOCK(push_promise);
+}
+
+void Http2FrameLogger::VisitContinuation(
+    const SpdyContinuationIR& continuation) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyContinuationIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(continuation, stream_id)
+      << FORMAT_ATTR(continuation, end_headers);
+}
+
+void Http2FrameLogger::VisitAltSvc(const SpdyAltSvcIR& altsvc) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyAltSvcIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(altsvc, stream_id) << FORMAT_ATTR(altsvc, origin)
+      << " altsvc_vector="
+      << LogContainer(altsvc.altsvc_vector(), LogAlternativeService());
+}
+
+void Http2FrameLogger::VisitPriority(const SpdyPriorityIR& priority) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyPriorityIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(priority, stream_id)
+      << FORMAT_ATTR(priority, parent_stream_id)
+      << FORMAT_INT_ATTR(priority, weight) << FORMAT_ATTR(priority, exclusive);
+}
+
+void Http2FrameLogger::VisitData(const SpdyDataIR& data) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyDataIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(data, stream_id) << FORMAT_ATTR(data, fin)
+      << " data_len=" << data.data_len() << FORMAT_ATTR(data, padded)
+      << FORMAT_ATTR(data, padding_payload_len);
+}
+
+void Http2FrameLogger::VisitPriorityUpdate(
+    const spdy::SpdyPriorityUpdateIR& priority_update) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyPriorityUpdateIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(priority_update, stream_id)
+      << FORMAT_ATTR(priority_update, prioritized_stream_id)
+      << FORMAT_ATTR(priority_update, priority_field_value);
+}
+
+void Http2FrameLogger::VisitAcceptCh(
+    const spdy::SpdyAcceptChIR& /*accept_ch*/) {
+  QUICHE_BUG(bug_2794_2)
+      << "Sending ACCEPT_CH frames is currently unimplemented.";
+}
+
+void Http2FrameLogger::VisitUnknown(const SpdyUnknownIR& ir) {
+  HTTP2_TRACE_LOG(perspective_, is_enabled_)
+      << "Wrote SpdyUnknownIR:" << FORMAT_ARG(connection_id_)
+      << FORMAT_ATTR(ir, stream_id) << FORMAT_INT_ATTR(ir, type)
+      << FORMAT_INT_ATTR(ir, flags) << FORMAT_ATTR(ir, length);
+}
+
+}  // namespace http2
diff --git a/quiche/http2/core/http2_trace_logging.h b/quiche/http2/core/http2_trace_logging.h
new file mode 100644
index 0000000..6f982dc
--- /dev/null
+++ b/quiche/http2/core/http2_trace_logging.h
@@ -0,0 +1,140 @@
+// Classes and utilities for supporting HTTP/2 trace logging, which logs
+// information about all control and data frames sent and received over
+// HTTP/2 connections.
+
+#ifndef QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
+#define QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/recording_headers_handler.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+// Logging macro to use for all HTTP/2 trace logging. Iff trace logging is
+// enabled, logs at level INFO with a common prefix prepended (to facilitate
+// post-hoc filtering of trace logging output).
+#define HTTP2_TRACE_LOG(perspective, is_enabled) \
+  QUICHE_LOG_IF(INFO, is_enabled()) << "[HTTP2_TRACE " << perspective << "] "
+
+namespace http2 {
+
+// Intercepts deframing events to provide detailed logs. Intended to be used for
+// manual debugging.
+//
+// Note any new methods in SpdyFramerVisitorInterface MUST be overridden here to
+// properly forward the event. This could be ensured by making every event in
+// SpdyFramerVisitorInterface a pure virtual.
+class QUICHE_EXPORT_PRIVATE Http2TraceLogger
+    : public spdy::SpdyFramerVisitorInterface {
+ public:
+  typedef spdy::SpdyAltSvcWireFormat SpdyAltSvcWireFormat;
+  typedef spdy::SpdyErrorCode SpdyErrorCode;
+  typedef spdy::SpdyFramerVisitorInterface SpdyFramerVisitorInterface;
+  typedef spdy::SpdyPingId SpdyPingId;
+  typedef spdy::SpdyPriority SpdyPriority;
+  typedef spdy::SpdySettingsId SpdySettingsId;
+  typedef spdy::SpdyStreamId SpdyStreamId;
+
+  Http2TraceLogger(SpdyFramerVisitorInterface* parent,
+                   absl::string_view perspective,
+                   std::function<bool()> is_enabled, const void* connection_id);
+  ~Http2TraceLogger() override;
+
+  Http2TraceLogger(const Http2TraceLogger&) = delete;
+  Http2TraceLogger& operator=(const Http2TraceLogger&) = delete;
+
+  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error) override;
+  void OnCommonHeader(SpdyStreamId stream_id, size_t length, uint8_t type,
+                      uint8_t flags) override;
+  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId stream_id) override;
+  void OnHeaderFrameEnd(SpdyStreamId stream_id) override;
+  void OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
+                         bool fin) override;
+  void OnStreamFrameData(SpdyStreamId stream_id, const char* data,
+                         size_t len) override;
+  void OnStreamEnd(SpdyStreamId stream_id) override;
+  void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
+  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
+  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
+  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
+  void OnPing(SpdyPingId unique_id, bool is_ack) override;
+  void OnSettings() override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck() override;
+  void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                SpdyErrorCode error_code) override;
+  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
+  void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
+                 SpdyStreamId parent_stream_id, bool exclusive, bool fin,
+                 bool end) override;
+  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
+  void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
+                     bool end) override;
+  void OnContinuation(SpdyStreamId stream_id, bool end) override;
+  void OnAltSvc(SpdyStreamId stream_id, absl::string_view origin,
+                const SpdyAltSvcWireFormat::AlternativeServiceVector&
+                    altsvc_vector) override;
+  void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id,
+                  int weight, bool exclusive) override;
+  void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
+                        absl::string_view priority_field_value) override;
+  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
+
+ private:
+  void LogReceivedHeaders() const;
+
+  std::unique_ptr<spdy::RecordingHeadersHandler> recording_headers_handler_;
+
+  SpdyFramerVisitorInterface* wrapped_;
+  const absl::string_view perspective_;
+  const std::function<bool()> is_enabled_;
+  const void* connection_id_;
+};
+
+// Visitor to log control frames that have been written.
+class QUICHE_EXPORT_PRIVATE Http2FrameLogger : public spdy::SpdyFrameVisitor {
+ public:
+  // This class will preface all of its log messages with the value of
+  // |connection_id| in hexadecimal.
+  Http2FrameLogger(absl::string_view perspective,
+                   std::function<bool()> is_enabled, const void* connection_id)
+      : perspective_(perspective),
+        is_enabled_(std::move(is_enabled)),
+        connection_id_(connection_id) {}
+
+  Http2FrameLogger(const Http2FrameLogger&) = delete;
+  Http2FrameLogger& operator=(const Http2FrameLogger&) = delete;
+
+  void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override;
+  void VisitSettings(const spdy::SpdySettingsIR& settings) override;
+  void VisitPing(const spdy::SpdyPingIR& ping) override;
+  void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override;
+  void VisitHeaders(const spdy::SpdyHeadersIR& headers) override;
+  void VisitWindowUpdate(
+      const spdy::SpdyWindowUpdateIR& window_update) override;
+  void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override;
+  void VisitContinuation(const spdy::SpdyContinuationIR& continuation) override;
+  void VisitAltSvc(const spdy::SpdyAltSvcIR& altsvc) override;
+  void VisitPriority(const spdy::SpdyPriorityIR& priority) override;
+  void VisitData(const spdy::SpdyDataIR& data) override;
+  void VisitPriorityUpdate(
+      const spdy::SpdyPriorityUpdateIR& priority_update) override;
+  void VisitAcceptCh(const spdy::SpdyAcceptChIR& accept_ch) override;
+  void VisitUnknown(const spdy::SpdyUnknownIR& ir) override;
+
+ private:
+  const absl::string_view perspective_;
+  const std::function<bool()> is_enabled_;
+  const void* connection_id_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_
diff --git a/quiche/http2/core/priority_write_scheduler.h b/quiche/http2/core/priority_write_scheduler.h
new file mode 100644
index 0000000..2466fbf
--- /dev/null
+++ b/quiche/http2/core/priority_write_scheduler.h
@@ -0,0 +1,333 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_CORE_PRIORITY_WRITE_SCHEDULER_H_
+#define QUICHE_HTTP2_CORE_PRIORITY_WRITE_SCHEDULER_H_
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/core/write_scheduler.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+
+namespace test {
+template <typename StreamIdType>
+class PriorityWriteSchedulerPeer;
+}
+
+// WriteScheduler implementation that manages the order in which streams are
+// written using the SPDY priority scheme described at:
+// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
+//
+// Internally, PriorityWriteScheduler consists of 8 PriorityInfo objects, one
+// for each priority value.  Each PriorityInfo contains a list of streams of
+// that priority that are ready to write, as well as a timestamp of the last
+// I/O event that occurred for a stream of that priority.
+//
+template <typename StreamIdType>
+class QUICHE_EXPORT_PRIVATE PriorityWriteScheduler
+    : public WriteScheduler<StreamIdType> {
+ public:
+  using typename WriteScheduler<StreamIdType>::StreamPrecedenceType;
+
+  // Creates scheduler with no streams.
+  PriorityWriteScheduler() : PriorityWriteScheduler(spdy::kHttp2RootStreamId) {}
+  explicit PriorityWriteScheduler(StreamIdType root_stream_id)
+      : root_stream_id_(root_stream_id) {}
+
+  void RegisterStream(StreamIdType stream_id,
+                      const StreamPrecedenceType& precedence) override {
+    // TODO(mpw): verify |precedence.is_spdy3_priority() == true| once
+    //   Http2PriorityWriteScheduler enabled for HTTP/2.
+
+    // parent_id not used here, but may as well validate it.  However,
+    // parent_id may legitimately not be registered yet--see b/15676312.
+    StreamIdType parent_id = precedence.parent_id();
+    QUICHE_DVLOG_IF(
+        1, parent_id != root_stream_id_ && !StreamRegistered(parent_id))
+        << "Parent stream " << parent_id << " not registered";
+
+    if (stream_id == root_stream_id_) {
+      QUICHE_BUG(spdy_bug_19_1)
+          << "Stream " << root_stream_id_ << " already registered";
+      return;
+    }
+    StreamInfo stream_info = {precedence.spdy3_priority(), stream_id, false};
+    bool inserted =
+        stream_infos_.insert(std::make_pair(stream_id, stream_info)).second;
+    QUICHE_BUG_IF(spdy_bug_19_2, !inserted)
+        << "Stream " << stream_id << " already registered";
+  }
+
+  void UnregisterStream(StreamIdType stream_id) override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_BUG(spdy_bug_19_3) << "Stream " << stream_id << " not registered";
+      return;
+    }
+    StreamInfo& stream_info = it->second;
+    if (stream_info.ready) {
+      bool erased =
+          Erase(&priority_infos_[stream_info.priority].ready_list, stream_info);
+      QUICHE_DCHECK(erased);
+    }
+    stream_infos_.erase(it);
+  }
+
+  bool StreamRegistered(StreamIdType stream_id) const override {
+    return stream_infos_.find(stream_id) != stream_infos_.end();
+  }
+
+  StreamPrecedenceType GetStreamPrecedence(
+      StreamIdType stream_id) const override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_DVLOG(1) << "Stream " << stream_id << " not registered";
+      return StreamPrecedenceType(spdy::kV3LowestPriority);
+    }
+    return StreamPrecedenceType(it->second.priority);
+  }
+
+  void UpdateStreamPrecedence(StreamIdType stream_id,
+                              const StreamPrecedenceType& precedence) override {
+    // TODO(mpw): verify |precedence.is_spdy3_priority() == true| once
+    //   Http2PriorityWriteScheduler enabled for HTTP/2.
+
+    // parent_id not used here, but may as well validate it.  However,
+    // parent_id may legitimately not be registered yet--see b/15676312.
+    StreamIdType parent_id = precedence.parent_id();
+    QUICHE_DVLOG_IF(
+        1, parent_id != root_stream_id_ && !StreamRegistered(parent_id))
+        << "Parent stream " << parent_id << " not registered";
+
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      // TODO(mpw): add to stream_infos_ on demand--see b/15676312.
+      QUICHE_DVLOG(1) << "Stream " << stream_id << " not registered";
+      return;
+    }
+    StreamInfo& stream_info = it->second;
+    spdy::SpdyPriority new_priority = precedence.spdy3_priority();
+    if (stream_info.priority == new_priority) {
+      return;
+    }
+    if (stream_info.ready) {
+      bool erased =
+          Erase(&priority_infos_[stream_info.priority].ready_list, stream_info);
+      QUICHE_DCHECK(erased);
+      priority_infos_[new_priority].ready_list.push_back(&stream_info);
+      ++num_ready_streams_;
+    }
+    stream_info.priority = new_priority;
+  }
+
+  std::vector<StreamIdType> GetStreamChildren(
+      StreamIdType /*stream_id*/) const override {
+    return std::vector<StreamIdType>();
+  }
+
+  void RecordStreamEventTime(StreamIdType stream_id,
+                             int64_t now_in_usec) override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_BUG(spdy_bug_19_4) << "Stream " << stream_id << " not registered";
+      return;
+    }
+    PriorityInfo& priority_info = priority_infos_[it->second.priority];
+    priority_info.last_event_time_usec =
+        std::max(priority_info.last_event_time_usec, now_in_usec);
+  }
+
+  int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_BUG(spdy_bug_19_5) << "Stream " << stream_id << " not registered";
+      return 0;
+    }
+    int64_t last_event_time_usec = 0;
+    const StreamInfo& stream_info = it->second;
+    for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
+         p < stream_info.priority; ++p) {
+      last_event_time_usec = std::max(last_event_time_usec,
+                                      priority_infos_[p].last_event_time_usec);
+    }
+    return last_event_time_usec;
+  }
+
+  StreamIdType PopNextReadyStream() override {
+    return std::get<0>(PopNextReadyStreamAndPrecedence());
+  }
+
+  // Returns the next ready stream and its precedence.
+  std::tuple<StreamIdType, StreamPrecedenceType>
+  PopNextReadyStreamAndPrecedence() override {
+    for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
+         p <= spdy::kV3LowestPriority; ++p) {
+      ReadyList& ready_list = priority_infos_[p].ready_list;
+      if (!ready_list.empty()) {
+        StreamInfo* info = ready_list.front();
+        ready_list.pop_front();
+        --num_ready_streams_;
+
+        QUICHE_DCHECK(stream_infos_.find(info->stream_id) !=
+                      stream_infos_.end());
+        info->ready = false;
+        return std::make_tuple(info->stream_id,
+                               StreamPrecedenceType(info->priority));
+      }
+    }
+    QUICHE_BUG(spdy_bug_19_6) << "No ready streams available";
+    return std::make_tuple(0, StreamPrecedenceType(spdy::kV3LowestPriority));
+  }
+
+  bool ShouldYield(StreamIdType stream_id) const override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_BUG(spdy_bug_19_7) << "Stream " << stream_id << " not registered";
+      return false;
+    }
+
+    // If there's a higher priority stream, this stream should yield.
+    const StreamInfo& stream_info = it->second;
+    for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
+         p < stream_info.priority; ++p) {
+      if (!priority_infos_[p].ready_list.empty()) {
+        return true;
+      }
+    }
+
+    // If this priority level is empty, or this stream is the next up, there's
+    // no need to yield.
+    const auto& ready_list = priority_infos_[it->second.priority].ready_list;
+    if (ready_list.empty() || ready_list.front()->stream_id == stream_id) {
+      return false;
+    }
+
+    // There are other streams in this priority level which take precedence.
+    // Yield.
+    return true;
+  }
+
+  void MarkStreamReady(StreamIdType stream_id, bool add_to_front) override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_BUG(spdy_bug_19_8) << "Stream " << stream_id << " not registered";
+      return;
+    }
+    StreamInfo& stream_info = it->second;
+    if (stream_info.ready) {
+      return;
+    }
+    ReadyList& ready_list = priority_infos_[stream_info.priority].ready_list;
+    if (add_to_front) {
+      ready_list.push_front(&stream_info);
+    } else {
+      ready_list.push_back(&stream_info);
+    }
+    ++num_ready_streams_;
+    stream_info.ready = true;
+  }
+
+  void MarkStreamNotReady(StreamIdType stream_id) override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_BUG(spdy_bug_19_9) << "Stream " << stream_id << " not registered";
+      return;
+    }
+    StreamInfo& stream_info = it->second;
+    if (!stream_info.ready) {
+      return;
+    }
+    bool erased =
+        Erase(&priority_infos_[stream_info.priority].ready_list, stream_info);
+    QUICHE_DCHECK(erased);
+    stream_info.ready = false;
+  }
+
+  // Returns true iff the number of ready streams is non-zero.
+  bool HasReadyStreams() const override { return num_ready_streams_ > 0; }
+
+  // Returns the number of ready streams.
+  size_t NumReadyStreams() const override { return num_ready_streams_; }
+
+  size_t NumRegisteredStreams() const override { return stream_infos_.size(); }
+
+  std::string DebugString() const override {
+    return absl::StrCat(
+        "PriorityWriteScheduler {num_streams=", stream_infos_.size(),
+        " num_ready_streams=", NumReadyStreams(), "}");
+  }
+
+  // Returns true if a stream is ready.
+  bool IsStreamReady(StreamIdType stream_id) const override {
+    auto it = stream_infos_.find(stream_id);
+    if (it == stream_infos_.end()) {
+      QUICHE_DLOG(INFO) << "Stream " << stream_id << " not registered";
+      return false;
+    }
+    return it->second.ready;
+  }
+
+ private:
+  friend class test::PriorityWriteSchedulerPeer<StreamIdType>;
+
+  // State kept for all registered streams. All ready streams have ready = true
+  // and should be present in priority_infos_[priority].ready_list.
+  struct QUICHE_EXPORT_PRIVATE StreamInfo {
+    spdy::SpdyPriority priority;
+    StreamIdType stream_id;
+    bool ready;
+  };
+
+  // O(1) size lookup, O(1) insert at front or back (amortized).
+  using ReadyList = quiche::QuicheCircularDeque<StreamInfo*>;
+
+  // State kept for each priority level.
+  struct QUICHE_EXPORT_PRIVATE PriorityInfo {
+    // IDs of streams that are ready to write.
+    ReadyList ready_list;
+    // Time of latest write event for stream of this priority, in microseconds.
+    int64_t last_event_time_usec = 0;
+  };
+
+  typedef std::unordered_map<StreamIdType, StreamInfo> StreamInfoMap;
+
+  // Erases `info` from `ready_list`, returning true if found (and erased), or
+  // false otherwise. Decrements `num_ready_streams_` if an entry is erased.
+  bool Erase(ReadyList* ready_list, const StreamInfo& info) {
+    auto it = std::remove(ready_list->begin(), ready_list->end(), &info);
+    if (it == ready_list->end()) {
+      // `info` was not found.
+      return false;
+    }
+    ready_list->pop_back();
+    --num_ready_streams_;
+    return true;
+  }
+
+  // Number of ready streams.
+  size_t num_ready_streams_ = 0;
+  // Per-priority state, including ready lists.
+  PriorityInfo priority_infos_[spdy::kV3LowestPriority + 1];
+  // StreamInfos for all registered streams.
+  StreamInfoMap stream_infos_;
+  StreamIdType root_stream_id_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_CORE_PRIORITY_WRITE_SCHEDULER_H_
diff --git a/quiche/http2/core/priority_write_scheduler_test.cc b/quiche/http2/core/priority_write_scheduler_test.cc
new file mode 100644
index 0000000..bb9c4ae
--- /dev/null
+++ b/quiche/http2/core/priority_write_scheduler_test.cc
@@ -0,0 +1,385 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/core/priority_write_scheduler.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+namespace http2 {
+namespace test {
+
+using ::spdy::kHttp2RootStreamId;
+using ::spdy::kV3LowestPriority;
+using ::spdy::SpdyPriority;
+using ::spdy::SpdyStreamId;
+using ::spdy::SpdyStreamPrecedence;
+
+template <typename StreamIdType>
+class PriorityWriteSchedulerPeer {
+ public:
+  explicit PriorityWriteSchedulerPeer(
+      PriorityWriteScheduler<StreamIdType>* scheduler)
+      : scheduler_(scheduler) {}
+
+  size_t NumReadyStreams(SpdyPriority priority) const {
+    return scheduler_->priority_infos_[priority].ready_list.size();
+  }
+
+ private:
+  PriorityWriteScheduler<StreamIdType>* scheduler_;
+};
+
+namespace {
+
+class PriorityWriteSchedulerTest : public QuicheTest {
+ public:
+  PriorityWriteSchedulerTest() : peer_(&scheduler_) {}
+
+  PriorityWriteScheduler<SpdyStreamId> scheduler_;
+  PriorityWriteSchedulerPeer<SpdyStreamId> peer_;
+};
+
+TEST_F(PriorityWriteSchedulerTest, RegisterUnregisterStreams) {
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+  EXPECT_FALSE(scheduler_.StreamRegistered(1));
+  EXPECT_EQ(0u, scheduler_.NumRegisteredStreams());
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(1));
+  EXPECT_TRUE(scheduler_.StreamRegistered(1));
+  EXPECT_EQ(1u, scheduler_.NumRegisteredStreams());
+
+  // Root stream counts as already registered.
+  EXPECT_QUICHE_BUG(
+      scheduler_.RegisterStream(kHttp2RootStreamId, SpdyStreamPrecedence(1)),
+      "Stream 0 already registered");
+
+  // Try redundant registrations.
+  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(1)),
+                    "Stream 1 already registered");
+  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(2)),
+                    "Stream 1 already registered");
+
+  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
+  EXPECT_EQ(2u, scheduler_.NumRegisteredStreams());
+
+  // Verify registration != ready.
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+
+  scheduler_.UnregisterStream(1);
+  EXPECT_EQ(1u, scheduler_.NumRegisteredStreams());
+  scheduler_.UnregisterStream(2);
+  EXPECT_EQ(0u, scheduler_.NumRegisteredStreams());
+
+  // Try redundant unregistration.
+  EXPECT_QUICHE_BUG(scheduler_.UnregisterStream(1), "Stream 1 not registered");
+  EXPECT_QUICHE_BUG(scheduler_.UnregisterStream(2), "Stream 2 not registered");
+}
+
+TEST_F(PriorityWriteSchedulerTest, RegisterStreamWithHttp2StreamDependency) {
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+  EXPECT_FALSE(scheduler_.StreamRegistered(1));
+  scheduler_.RegisterStream(
+      1, SpdyStreamPrecedence(kHttp2RootStreamId, 123, false));
+  EXPECT_TRUE(scheduler_.StreamRegistered(1));
+  EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority());
+  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+
+  EXPECT_QUICHE_BUG(
+      scheduler_.RegisterStream(
+          1, SpdyStreamPrecedence(kHttp2RootStreamId, 256, false)),
+      "Stream 1 already registered");
+  EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority());
+  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  // Registering stream with a non-existent parent stream is permissible, per
+  // b/15676312, but parent stream will always be reset to 0.
+  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3, 123, false));
+  EXPECT_TRUE(scheduler_.StreamRegistered(2));
+  EXPECT_FALSE(scheduler_.StreamRegistered(3));
+  EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(2).parent_id());
+}
+
+TEST_F(PriorityWriteSchedulerTest, GetStreamPrecedence) {
+  // Unknown streams tolerated due to b/15676312. However, return lowest
+  // priority.
+  EXPECT_EQ(kV3LowestPriority,
+            scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
+  EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority());
+  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  // Redundant registration shouldn't change stream priority.
+  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(4)),
+                    "Stream 1 already registered");
+  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(5));
+  EXPECT_EQ(5, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  // Toggling ready state shouldn't change stream priority.
+  scheduler_.MarkStreamReady(1, true);
+  EXPECT_EQ(5, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  // Test changing priority of ready stream.
+  EXPECT_EQ(1u, peer_.NumReadyStreams(5));
+  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(6));
+  EXPECT_EQ(6, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+  EXPECT_EQ(0u, peer_.NumReadyStreams(5));
+  EXPECT_EQ(1u, peer_.NumReadyStreams(6));
+
+  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(6, scheduler_.GetStreamPrecedence(1).spdy3_priority());
+
+  scheduler_.UnregisterStream(1);
+  EXPECT_EQ(kV3LowestPriority,
+            scheduler_.GetStreamPrecedence(1).spdy3_priority());
+}
+
+TEST_F(PriorityWriteSchedulerTest, PopNextReadyStreamAndPrecedence) {
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(1, true);
+  EXPECT_EQ(std::make_tuple(1u, SpdyStreamPrecedence(3)),
+            scheduler_.PopNextReadyStreamAndPrecedence());
+  scheduler_.UnregisterStream(1);
+}
+
+TEST_F(PriorityWriteSchedulerTest, UpdateStreamPrecedence) {
+  // For the moment, updating stream precedence on a non-registered stream
+  // should have no effect. In the future, it will lazily cause the stream to
+  // be registered (b/15676312).
+  EXPECT_EQ(kV3LowestPriority,
+            scheduler_.GetStreamPrecedence(3).spdy3_priority());
+  EXPECT_FALSE(scheduler_.StreamRegistered(3));
+  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(1));
+  EXPECT_FALSE(scheduler_.StreamRegistered(3));
+  EXPECT_EQ(kV3LowestPriority,
+            scheduler_.GetStreamPrecedence(3).spdy3_priority());
+
+  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1));
+  EXPECT_EQ(1, scheduler_.GetStreamPrecedence(3).spdy3_priority());
+  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(2));
+  EXPECT_EQ(2, scheduler_.GetStreamPrecedence(3).spdy3_priority());
+
+  // Updating priority of stream to current priority value is valid, but has no
+  // effect.
+  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(2));
+  EXPECT_EQ(2, scheduler_.GetStreamPrecedence(3).spdy3_priority());
+
+  // Even though stream 4 is marked ready after stream 5, it should be returned
+  // first by PopNextReadyStream() since it has higher priority.
+  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1));
+  scheduler_.MarkStreamReady(3, false);  // priority 2
+  EXPECT_TRUE(scheduler_.IsStreamReady(3));
+  scheduler_.MarkStreamReady(4, false);  // priority 1
+  EXPECT_TRUE(scheduler_.IsStreamReady(4));
+  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
+  EXPECT_FALSE(scheduler_.IsStreamReady(4));
+  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
+  EXPECT_FALSE(scheduler_.IsStreamReady(3));
+
+  // Verify that lowering priority of stream 4 causes it to be returned later
+  // by PopNextReadyStream().
+  scheduler_.MarkStreamReady(3, false);  // priority 2
+  scheduler_.MarkStreamReady(4, false);  // priority 1
+  scheduler_.UpdateStreamPrecedence(4, SpdyStreamPrecedence(3));
+  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
+
+  scheduler_.UnregisterStream(3);
+}
+
+TEST_F(PriorityWriteSchedulerTest,
+       UpdateStreamPrecedenceWithHttp2StreamDependency) {
+  // Unknown streams tolerated due to b/15676312, but should have no effect.
+  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false));
+  EXPECT_FALSE(scheduler_.StreamRegistered(3));
+
+  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
+  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false));
+  EXPECT_TRUE(scheduler_.GetStreamPrecedence(3).is_spdy3_priority());
+  EXPECT_EQ(4, scheduler_.GetStreamPrecedence(3).spdy3_priority());
+
+  scheduler_.UnregisterStream(3);
+  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false));
+  EXPECT_FALSE(scheduler_.StreamRegistered(3));
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBack) {
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+  EXPECT_QUICHE_BUG(scheduler_.MarkStreamReady(1, false),
+                    "Stream 1 not registered");
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+
+  // Add a bunch of ready streams to tail of per-priority lists.
+  // Expected order: (P2) 4, (P3) 1, 2, 3, (P5) 5.
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(1, false);
+  EXPECT_TRUE(scheduler_.HasReadyStreams());
+  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(2, false);
+  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(3, false);
+  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2));
+  scheduler_.MarkStreamReady(4, false);
+  scheduler_.RegisterStream(5, SpdyStreamPrecedence(5));
+  scheduler_.MarkStreamReady(5, false);
+
+  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyFront) {
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+  EXPECT_QUICHE_BUG(scheduler_.MarkStreamReady(1, true),
+                    "Stream 1 not registered");
+  EXPECT_FALSE(scheduler_.HasReadyStreams());
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+
+  // Add a bunch of ready streams to head of per-priority lists.
+  // Expected order: (P2) 4, (P3) 3, 2, 1, (P5) 5
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(1, true);
+  EXPECT_TRUE(scheduler_.HasReadyStreams());
+  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(2, true);
+  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
+  scheduler_.MarkStreamReady(3, true);
+  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2));
+  scheduler_.MarkStreamReady(4, true);
+  scheduler_.RegisterStream(5, SpdyStreamPrecedence(5));
+  scheduler_.MarkStreamReady(5, true);
+
+  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBackAndFront) {
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(4));
+  scheduler_.RegisterStream(2, SpdyStreamPrecedence(3));
+  scheduler_.RegisterStream(3, SpdyStreamPrecedence(3));
+  scheduler_.RegisterStream(4, SpdyStreamPrecedence(3));
+  scheduler_.RegisterStream(5, SpdyStreamPrecedence(4));
+  scheduler_.RegisterStream(6, SpdyStreamPrecedence(1));
+
+  // Add a bunch of ready streams to per-priority lists, with variety of adding
+  // at head and tail.
+  // Expected order: (P1) 6, (P3) 4, 2, 3, (P4) 1, 5
+  scheduler_.MarkStreamReady(1, true);
+  scheduler_.MarkStreamReady(2, true);
+  scheduler_.MarkStreamReady(3, false);
+  scheduler_.MarkStreamReady(4, true);
+  scheduler_.MarkStreamReady(5, false);
+  scheduler_.MarkStreamReady(6, true);
+
+  EXPECT_EQ(6u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(1u, scheduler_.PopNextReadyStream());
+  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, MarkStreamNotReady) {
+  // Verify ready state reflected in NumReadyStreams().
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(1));
+  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+  scheduler_.MarkStreamReady(1, false);
+  EXPECT_EQ(1u, scheduler_.NumReadyStreams());
+  scheduler_.MarkStreamNotReady(1);
+  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+
+  // Empty pop should fail.
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+
+  // Tolerate redundant marking of a stream as not ready.
+  scheduler_.MarkStreamNotReady(1);
+  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+
+  // Should only be able to mark registered streams.
+  EXPECT_QUICHE_BUG(scheduler_.MarkStreamNotReady(3),
+                    "Stream 3 not registered");
+}
+
+TEST_F(PriorityWriteSchedulerTest, UnregisterRemovesStream) {
+  scheduler_.RegisterStream(3, SpdyStreamPrecedence(4));
+  scheduler_.MarkStreamReady(3, false);
+  EXPECT_EQ(1u, scheduler_.NumReadyStreams());
+
+  // Unregistering a stream should remove it from set of ready streams.
+  scheduler_.UnregisterStream(3);
+  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()),
+                    "No ready streams available");
+}
+
+TEST_F(PriorityWriteSchedulerTest, ShouldYield) {
+  scheduler_.RegisterStream(1, SpdyStreamPrecedence(1));
+  scheduler_.RegisterStream(4, SpdyStreamPrecedence(4));
+  scheduler_.RegisterStream(5, SpdyStreamPrecedence(4));
+  scheduler_.RegisterStream(7, SpdyStreamPrecedence(7));
+
+  // Make sure we don't yield when the list is empty.
+  EXPECT_FALSE(scheduler_.ShouldYield(1));
+
+  // Add a low priority stream.
+  scheduler_.MarkStreamReady(4, false);
+  // 4 should not yield to itself.
+  EXPECT_FALSE(scheduler_.ShouldYield(4));
+  // 7 should yield as 4 is blocked and a higher priority.
+  EXPECT_TRUE(scheduler_.ShouldYield(7));
+  // 5 should yield to 4 as they are the same priority.
+  EXPECT_TRUE(scheduler_.ShouldYield(5));
+  // 1 should not yield as 1 is higher priority.
+  EXPECT_FALSE(scheduler_.ShouldYield(1));
+
+  // Add a second stream in that priority class.
+  scheduler_.MarkStreamReady(5, false);
+  // 4 and 5 are both blocked, but 4 is at the front so should not yield.
+  EXPECT_FALSE(scheduler_.ShouldYield(4));
+  EXPECT_TRUE(scheduler_.ShouldYield(5));
+}
+
+TEST_F(PriorityWriteSchedulerTest, GetLatestEventWithPrecedence) {
+  EXPECT_QUICHE_BUG(scheduler_.RecordStreamEventTime(3, 5),
+                    "Stream 3 not registered");
+  EXPECT_QUICHE_BUG(EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(4)),
+                    "Stream 4 not registered");
+
+  for (int i = 1; i < 5; ++i) {
+    scheduler_.RegisterStream(i, SpdyStreamPrecedence(i));
+  }
+  for (int i = 1; i < 5; ++i) {
+    EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(i));
+  }
+  for (int i = 1; i < 5; ++i) {
+    scheduler_.RecordStreamEventTime(i, i * 100);
+  }
+  for (int i = 1; i < 5; ++i) {
+    EXPECT_EQ((i - 1) * 100, scheduler_.GetLatestEventWithPrecedence(i));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/core/write_scheduler.h b/quiche/http2/core/write_scheduler.h
new file mode 100644
index 0000000..7b68694
--- /dev/null
+++ b/quiche/http2/core/write_scheduler.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
+#define QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace http2 {
+
+// Abstract superclass for classes that decide which SPDY or HTTP/2 stream to
+// write next. Concrete subclasses implement various scheduling policies:
+//
+// PriorityWriteScheduler: implements SPDY priority-based stream scheduling,
+//     where (writable) higher-priority streams are always given precedence
+//     over lower-priority streams.
+//
+// The type used to represent stream IDs (StreamIdType) is templated in order
+// to allow for use by both SPDY and QUIC codebases. It must be a POD that
+// supports comparison (i.e., a numeric type).
+//
+// Each stream can be in one of two states: ready or not ready (for writing).
+// Ready state is changed by calling the MarkStreamReady() and
+// MarkStreamNotReady() methods. Only streams in the ready state can be
+// returned by PopNextReadyStream(); when returned by that method, the stream's
+// state changes to not ready.
+template <typename StreamIdType>
+class QUICHE_EXPORT_PRIVATE WriteScheduler {
+ public:
+  typedef spdy::StreamPrecedence<StreamIdType> StreamPrecedenceType;
+
+  virtual ~WriteScheduler() {}
+
+  // Registers new stream |stream_id| with the scheduler, assigning it the
+  // given precedence. If the scheduler supports stream dependencies, the
+  // stream is inserted into the dependency tree under
+  // |precedence.parent_id()|.
+  //
+  // Preconditions: |stream_id| should be unregistered, and
+  // |precedence.parent_id()| should be registered or |kHttp2RootStreamId|.
+  virtual void RegisterStream(StreamIdType stream_id,
+                              const StreamPrecedenceType& precedence) = 0;
+
+  // Unregisters the given stream from the scheduler, which will no longer keep
+  // state for it.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual void UnregisterStream(StreamIdType stream_id) = 0;
+
+  // Returns true if the given stream is currently registered.
+  virtual bool StreamRegistered(StreamIdType stream_id) const = 0;
+
+  // Returns the precedence of the specified stream. If the scheduler supports
+  // stream dependencies, calling |parent_id()| on the return value returns the
+  // stream's parent, and calling |exclusive()| returns true iff the specified
+  // stream is an only child of the parent stream.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual StreamPrecedenceType GetStreamPrecedence(
+      StreamIdType stream_id) const = 0;
+
+  // Updates the precedence of the given stream. If the scheduler supports
+  // stream dependencies, |stream_id|'s parent will be updated to be
+  // |precedence.parent_id()| if it is not already.
+  //
+  // Preconditions: |stream_id| should be unregistered, and
+  // |precedence.parent_id()| should be registered or |kHttp2RootStreamId|.
+  virtual void UpdateStreamPrecedence(
+      StreamIdType stream_id,
+      const StreamPrecedenceType& precedence) = 0;
+
+  // Returns child streams of the given stream, if any. If the scheduler
+  // doesn't support stream dependencies, returns an empty vector.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual std::vector<StreamIdType> GetStreamChildren(
+      StreamIdType stream_id) const = 0;
+
+  // Records time (in microseconds) of a read/write event for the given
+  // stream.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual void RecordStreamEventTime(StreamIdType stream_id,
+                                     int64_t now_in_usec) = 0;
+
+  // Returns time (in microseconds) of the last read/write event for a stream
+  // with higher priority than the priority of the given stream, or 0 if there
+  // is no such event.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual int64_t GetLatestEventWithPrecedence(
+      StreamIdType stream_id) const = 0;
+
+  // If the scheduler has any ready streams, returns the next scheduled
+  // ready stream, in the process transitioning the stream from ready to not
+  // ready.
+  //
+  // Preconditions: |HasReadyStreams() == true|
+  virtual StreamIdType PopNextReadyStream() = 0;
+
+  // If the scheduler has any ready streams, returns the next scheduled
+  // ready stream and its priority, in the process transitioning the stream from
+  // ready to not ready.
+  //
+  // Preconditions: |HasReadyStreams() == true|
+  virtual std::tuple<StreamIdType, StreamPrecedenceType>
+  PopNextReadyStreamAndPrecedence() = 0;
+
+  // Returns true if there's another stream ahead of the given stream in the
+  // scheduling queue.  This function can be called to see if the given stream
+  // should yield work to another stream.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual bool ShouldYield(StreamIdType stream_id) const = 0;
+
+  // Marks the stream as ready to write. If the stream was already ready, does
+  // nothing. If add_to_front is true, the stream is scheduled ahead of other
+  // streams of the same priority/weight, otherwise it is scheduled behind them.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual void MarkStreamReady(StreamIdType stream_id, bool add_to_front) = 0;
+
+  // Marks the stream as not ready to write. If the stream is not registered or
+  // not ready, does nothing.
+  //
+  // Preconditions: |stream_id| should be registered.
+  virtual void MarkStreamNotReady(StreamIdType stream_id) = 0;
+
+  // Returns true iff the scheduler has any ready streams.
+  virtual bool HasReadyStreams() const = 0;
+
+  // Returns the number of streams currently marked ready.
+  virtual size_t NumReadyStreams() const = 0;
+
+  // Returns true if stream with |stream_id| is ready.
+  virtual bool IsStreamReady(StreamIdType stream_id) const = 0;
+
+  // Returns the number of registered streams.
+  virtual size_t NumRegisteredStreams() const = 0;
+
+  // Returns summary of internal state, for logging/debugging.
+  virtual std::string DebugString() const = 0;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
diff --git a/quiche/http2/decoder/decode_buffer.cc b/quiche/http2/decoder/decode_buffer.cc
new file mode 100644
index 0000000..1d13ca0
--- /dev/null
+++ b/quiche/http2/decoder/decode_buffer.cc
@@ -0,0 +1,93 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+
+namespace http2 {
+
+uint8_t DecodeBuffer::DecodeUInt8() {
+  return static_cast<uint8_t>(DecodeChar());
+}
+
+uint16_t DecodeBuffer::DecodeUInt16() {
+  QUICHE_DCHECK_LE(2u, Remaining());
+  const uint8_t b1 = DecodeUInt8();
+  const uint8_t b2 = DecodeUInt8();
+  // Note that chars are automatically promoted to ints during arithmetic,
+  // so the b1 << 8 doesn't end up as zero before being or-ed with b2.
+  // And the left-shift operator has higher precedence than the or operator.
+  return b1 << 8 | b2;
+}
+
+uint32_t DecodeBuffer::DecodeUInt24() {
+  QUICHE_DCHECK_LE(3u, Remaining());
+  const uint8_t b1 = DecodeUInt8();
+  const uint8_t b2 = DecodeUInt8();
+  const uint8_t b3 = DecodeUInt8();
+  return b1 << 16 | b2 << 8 | b3;
+}
+
+uint32_t DecodeBuffer::DecodeUInt31() {
+  QUICHE_DCHECK_LE(4u, Remaining());
+  const uint8_t b1 = DecodeUInt8() & 0x7f;  // Mask out the high order bit.
+  const uint8_t b2 = DecodeUInt8();
+  const uint8_t b3 = DecodeUInt8();
+  const uint8_t b4 = DecodeUInt8();
+  return b1 << 24 | b2 << 16 | b3 << 8 | b4;
+}
+
+uint32_t DecodeBuffer::DecodeUInt32() {
+  QUICHE_DCHECK_LE(4u, Remaining());
+  const uint8_t b1 = DecodeUInt8();
+  const uint8_t b2 = DecodeUInt8();
+  const uint8_t b3 = DecodeUInt8();
+  const uint8_t b4 = DecodeUInt8();
+  return b1 << 24 | b2 << 16 | b3 << 8 | b4;
+}
+
+#ifndef NDEBUG
+void DecodeBuffer::set_subset_of_base(DecodeBuffer* base,
+                                      const DecodeBufferSubset* subset) {
+  QUICHE_DCHECK_EQ(this, subset);
+  base->set_subset(subset);
+}
+void DecodeBuffer::clear_subset_of_base(DecodeBuffer* base,
+                                        const DecodeBufferSubset* subset) {
+  QUICHE_DCHECK_EQ(this, subset);
+  base->clear_subset(subset);
+}
+void DecodeBuffer::set_subset(const DecodeBufferSubset* subset) {
+  QUICHE_DCHECK(subset != nullptr);
+  QUICHE_DCHECK_EQ(subset_, nullptr) << "There is already a subset";
+  subset_ = subset;
+}
+void DecodeBuffer::clear_subset(const DecodeBufferSubset* subset) {
+  QUICHE_DCHECK(subset != nullptr);
+  QUICHE_DCHECK_EQ(subset_, subset);
+  subset_ = nullptr;
+}
+void DecodeBufferSubset::DebugSetup() {
+  start_base_offset_ = base_buffer_->Offset();
+  max_base_offset_ = start_base_offset_ + FullSize();
+  QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());
+
+  // Ensure that there is only one DecodeBufferSubset at a time for a base.
+  set_subset_of_base(base_buffer_, this);
+}
+void DecodeBufferSubset::DebugTearDown() {
+  // Ensure that the base hasn't been modified.
+  QUICHE_DCHECK_EQ(start_base_offset_, base_buffer_->Offset())
+      << "The base buffer was modified";
+
+  // Ensure that we haven't gone beyond the maximum allowed offset.
+  size_t offset = Offset();
+  QUICHE_DCHECK_LE(offset, FullSize());
+  QUICHE_DCHECK_LE(start_base_offset_ + offset, max_base_offset_);
+  QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());
+
+  clear_subset_of_base(base_buffer_, this);
+}
+#endif
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/decode_buffer.h b/quiche/http2/decoder/decode_buffer.h
new file mode 100644
index 0000000..e44231d
--- /dev/null
+++ b/quiche/http2/decoder/decode_buffer.h
@@ -0,0 +1,171 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
+#define QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
+
+// DecodeBuffer provides primitives for decoding various integer types found in
+// HTTP/2 frames. It wraps a byte array from which we can read and decode
+// serialized HTTP/2 frames, or parts thereof. DecodeBuffer is intended only for
+// stack allocation, where the caller is typically going to use the DecodeBuffer
+// instance as part of decoding the entire buffer before returning to its own
+// caller.
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+class DecodeBufferSubset;
+
+class QUICHE_EXPORT_PRIVATE DecodeBuffer {
+ public:
+  // We assume the decode buffers will typically be modest in size (i.e. often a
+  // few KB, perhaps as high as 100KB). Let's make sure during testing that we
+  // don't go very high, with 32MB selected rather arbitrarily. This is exposed
+  // to support testing.
+  static constexpr size_t kMaxDecodeBufferLength = 1 << 25;
+
+  DecodeBuffer(const char* buffer, size_t len)
+      : buffer_(buffer), cursor_(buffer), beyond_(buffer + len) {
+    QUICHE_DCHECK(buffer != nullptr);
+    QUICHE_DCHECK_LE(len, kMaxDecodeBufferLength);
+  }
+  explicit DecodeBuffer(absl::string_view s)
+      : DecodeBuffer(s.data(), s.size()) {}
+  // Constructor for character arrays, typically in tests. For example:
+  //    const char input[] = { 0x11 };
+  //    DecodeBuffer b(input);
+  template <size_t N>
+  explicit DecodeBuffer(const char (&buf)[N]) : DecodeBuffer(buf, N) {}
+
+  DecodeBuffer(const DecodeBuffer&) = delete;
+  DecodeBuffer operator=(const DecodeBuffer&) = delete;
+
+  bool Empty() const { return cursor_ >= beyond_; }
+  bool HasData() const { return cursor_ < beyond_; }
+  size_t Remaining() const {
+    QUICHE_DCHECK_LE(cursor_, beyond_);
+    return beyond_ - cursor_;
+  }
+  size_t Offset() const { return cursor_ - buffer_; }
+  size_t FullSize() const { return beyond_ - buffer_; }
+
+  // Returns the minimum of the number of bytes remaining in this DecodeBuffer
+  // and |length|, in support of determining how much of some structure/payload
+  // is in this DecodeBuffer.
+  size_t MinLengthRemaining(size_t length) const {
+    return std::min(length, Remaining());
+  }
+
+  // For string decoding, returns a pointer to the next byte/char to be decoded.
+  const char* cursor() const { return cursor_; }
+  // Advances the cursor (pointer to the next byte/char to be decoded).
+  void AdvanceCursor(size_t amount) {
+    QUICHE_DCHECK_LE(amount,
+                     Remaining());  // Need at least that much remaining.
+    QUICHE_DCHECK_EQ(subset_, nullptr)
+        << "Access via subset only when present.";
+    cursor_ += amount;
+  }
+
+  // Only call methods starting "Decode" when there is enough input remaining.
+  char DecodeChar() {
+    QUICHE_DCHECK_LE(1u, Remaining());  // Need at least one byte remaining.
+    QUICHE_DCHECK_EQ(subset_, nullptr)
+        << "Access via subset only when present.";
+    return *cursor_++;
+  }
+
+  uint8_t DecodeUInt8();
+  uint16_t DecodeUInt16();
+  uint32_t DecodeUInt24();
+
+  // For 31-bit unsigned integers, where the 32nd bit is reserved for future
+  // use (i.e. the high-bit of the first byte of the encoding); examples:
+  // the Stream Id in a frame header or the Window Size Increment in a
+  // WINDOW_UPDATE frame.
+  uint32_t DecodeUInt31();
+
+  uint32_t DecodeUInt32();
+
+ protected:
+#ifndef NDEBUG
+  // These are part of validating during tests that there is at most one
+  // DecodeBufferSubset instance at a time for any DecodeBuffer instance.
+  void set_subset_of_base(DecodeBuffer* base, const DecodeBufferSubset* subset);
+  void clear_subset_of_base(DecodeBuffer* base,
+                            const DecodeBufferSubset* subset);
+#endif
+
+ private:
+#ifndef NDEBUG
+  void set_subset(const DecodeBufferSubset* subset);
+  void clear_subset(const DecodeBufferSubset* subset);
+#endif
+
+  // Prevent heap allocation of DecodeBuffer.
+  static void* operator new(size_t s);
+  static void* operator new[](size_t s);
+  static void operator delete(void* p);
+  static void operator delete[](void* p);
+
+  const char* const buffer_;
+  const char* cursor_;
+  const char* const beyond_;
+  const DecodeBufferSubset* subset_ = nullptr;  // Used for QUICHE_DCHECKs.
+};
+
+// DecodeBufferSubset is used when decoding a known sized chunk of data, which
+// starts at base->cursor(), and continues for subset_len, which may be
+// entirely in |base|, or may extend beyond it (hence the MinLengthRemaining
+// in the constructor).
+// There are two benefits to using DecodeBufferSubset: it ensures that the
+// cursor of |base| is advanced when the subset's destructor runs, and it
+// ensures that the consumer of the subset can't go beyond the subset which
+// it is intended to decode.
+// There must be only a single DecodeBufferSubset at a time for a base
+// DecodeBuffer, though they can be nested (i.e. a DecodeBufferSubset's
+// base may itself be a DecodeBufferSubset). This avoids the AdvanceCursor
+// being called erroneously.
+class QUICHE_EXPORT_PRIVATE DecodeBufferSubset : public DecodeBuffer {
+ public:
+  DecodeBufferSubset(DecodeBuffer* base, size_t subset_len)
+      : DecodeBuffer(base->cursor(), base->MinLengthRemaining(subset_len)),
+        base_buffer_(base) {
+#ifndef NDEBUG
+    DebugSetup();
+#endif
+  }
+
+  DecodeBufferSubset(const DecodeBufferSubset&) = delete;
+  DecodeBufferSubset operator=(const DecodeBufferSubset&) = delete;
+
+  ~DecodeBufferSubset() {
+    size_t offset = Offset();
+#ifndef NDEBUG
+    DebugTearDown();
+#endif
+    base_buffer_->AdvanceCursor(offset);
+  }
+
+ private:
+  DecodeBuffer* const base_buffer_;
+#ifndef NDEBUG
+  size_t start_base_offset_;  // Used for QUICHE_DCHECKs.
+  size_t max_base_offset_;    // Used for QUICHE_DCHECKs.
+
+  void DebugSetup();
+  void DebugTearDown();
+#endif
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
diff --git a/quiche/http2/decoder/decode_buffer_test.cc b/quiche/http2/decoder/decode_buffer_test.cc
new file mode 100644
index 0000000..f8739a7
--- /dev/null
+++ b/quiche/http2/decoder/decode_buffer_test.cc
@@ -0,0 +1,209 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+
+#include <functional>
+
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+enum class TestEnumClass32 {
+  kValue1 = 1,
+  kValue99 = 99,
+  kValue1M = 1000000,
+};
+
+enum class TestEnumClass8 {
+  kValue1 = 1,
+  kValue2 = 1,
+  kValue99 = 99,
+  kValue255 = 255,
+};
+
+enum TestEnum8 {
+  kMaskLo = 0x01,
+  kMaskHi = 0x80,
+};
+
+struct TestStruct {
+  uint8_t f1;
+  uint16_t f2;
+  uint32_t f3;  // Decoded as a uint24
+  uint32_t f4;
+  uint32_t f5;  // Decoded as if uint31
+  TestEnumClass32 f6;
+  TestEnumClass8 f7;
+  TestEnum8 f8;
+};
+
+class DecodeBufferTest : public QuicheTest {
+ protected:
+  Http2Random random_;
+  uint32_t decode_offset_;
+};
+
+TEST_F(DecodeBufferTest, DecodesFixedInts) {
+  const char data[] = "\x01\x12\x23\x34\x45\x56\x67\x78\x89\x9a";
+  DecodeBuffer b1(data, strlen(data));
+  EXPECT_EQ(1, b1.DecodeUInt8());
+  EXPECT_EQ(0x1223u, b1.DecodeUInt16());
+  EXPECT_EQ(0x344556u, b1.DecodeUInt24());
+  EXPECT_EQ(0x6778899Au, b1.DecodeUInt32());
+}
+
+// Make sure that DecodeBuffer is not copying input, just pointing into
+// provided input buffer.
+TEST_F(DecodeBufferTest, HasNotCopiedInput) {
+  const char data[] = "ab";
+  DecodeBuffer b1(data, 2);
+
+  EXPECT_EQ(2u, b1.Remaining());
+  EXPECT_EQ(0u, b1.Offset());
+  EXPECT_FALSE(b1.Empty());
+  EXPECT_EQ(data, b1.cursor());  // cursor points to input buffer
+  EXPECT_TRUE(b1.HasData());
+
+  b1.AdvanceCursor(1);
+
+  EXPECT_EQ(1u, b1.Remaining());
+  EXPECT_EQ(1u, b1.Offset());
+  EXPECT_FALSE(b1.Empty());
+  EXPECT_EQ(&data[1], b1.cursor());
+  EXPECT_TRUE(b1.HasData());
+
+  b1.AdvanceCursor(1);
+
+  EXPECT_EQ(0u, b1.Remaining());
+  EXPECT_EQ(2u, b1.Offset());
+  EXPECT_TRUE(b1.Empty());
+  EXPECT_EQ(&data[2], b1.cursor());
+  EXPECT_FALSE(b1.HasData());
+
+  DecodeBuffer b2(data, 0);
+
+  EXPECT_EQ(0u, b2.Remaining());
+  EXPECT_EQ(0u, b2.Offset());
+  EXPECT_TRUE(b2.Empty());
+  EXPECT_EQ(data, b2.cursor());
+  EXPECT_FALSE(b2.HasData());
+}
+
+// DecodeBufferSubset can't go beyond the end of the base buffer.
+TEST_F(DecodeBufferTest, DecodeBufferSubsetLimited) {
+  const char data[] = "abc";
+  DecodeBuffer base(data, 3);
+  base.AdvanceCursor(1);
+  DecodeBufferSubset subset(&base, 100);
+  EXPECT_EQ(2u, subset.FullSize());
+}
+
+// DecodeBufferSubset advances the cursor of its base upon destruction.
+TEST_F(DecodeBufferTest, DecodeBufferSubsetAdvancesCursor) {
+  const char data[] = "abc";
+  const size_t size = sizeof(data) - 1;
+  EXPECT_EQ(3u, size);
+  DecodeBuffer base(data, size);
+  {
+    // First no change to the cursor.
+    DecodeBufferSubset subset(&base, size + 100);
+    EXPECT_EQ(size, subset.FullSize());
+    EXPECT_EQ(base.FullSize(), subset.FullSize());
+    EXPECT_EQ(0u, subset.Offset());
+  }
+  EXPECT_EQ(0u, base.Offset());
+  EXPECT_EQ(size, base.Remaining());
+}
+
+// Make sure that DecodeBuffer ctor complains about bad args.
+#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+TEST(DecodeBufferDeathTest, NonNullBufferRequired) {
+  EXPECT_DEBUG_DEATH({ DecodeBuffer b(nullptr, 3); }, "nullptr");
+}
+
+// Make sure that DecodeBuffer ctor complains about bad args.
+TEST(DecodeBufferDeathTest, ModestBufferSizeRequired) {
+  EXPECT_DEBUG_DEATH(
+      {
+        // This depends on being able to allocate a fairly large array on the
+        // stack. If that fails, we can instead do this:
+        //
+        //   std::string data(DecodeBuffer::kMaxDecodeBufferLength + 1, ' ');
+        //   DecodeBuffer b(data.data(), data.size());
+
+        const char data[DecodeBuffer::kMaxDecodeBufferLength + 1] = {};
+        DecodeBuffer b(data, sizeof data);
+      },
+      "Max.*Length");
+}
+
+// Make sure that DecodeBuffer detects advance beyond end, in debug mode.
+TEST(DecodeBufferDeathTest, LimitedAdvance) {
+  {
+    // Advance right up to end is OK.
+    const char data[] = "abc";
+    DecodeBuffer b(data, 3);
+    b.AdvanceCursor(3);  // OK
+    EXPECT_TRUE(b.Empty());
+  }
+  EXPECT_DEBUG_DEATH(
+      {
+        // Going beyond is not OK.
+        const char data[] = "abc";
+        DecodeBuffer b(data, 3);
+        b.AdvanceCursor(4);
+      },
+      "4 vs. 3");
+}
+
+// Make sure that DecodeBuffer detects decode beyond end, in debug mode.
+TEST(DecodeBufferDeathTest, DecodeUInt8PastEnd) {
+  const char data[] = {0x12, 0x23};
+  DecodeBuffer b(data, sizeof data);
+  EXPECT_EQ(2u, b.FullSize());
+  EXPECT_EQ(0x1223, b.DecodeUInt16());
+  EXPECT_DEBUG_DEATH({ b.DecodeUInt8(); }, "1 vs. 0");
+}
+
+// Make sure that DecodeBuffer detects decode beyond end, in debug mode.
+TEST(DecodeBufferDeathTest, DecodeUInt16OverEnd) {
+  const char data[] = {0x12, 0x23, 0x34};
+  DecodeBuffer b(data, sizeof data);
+  EXPECT_EQ(3u, b.FullSize());
+  EXPECT_EQ(0x1223, b.DecodeUInt16());
+  EXPECT_DEBUG_DEATH({ b.DecodeUInt16(); }, "2 vs. 1");
+}
+
+// Make sure that DecodeBuffer doesn't agree with having two subsets.
+TEST(DecodeBufferSubsetDeathTest, TwoSubsets) {
+  const char data[] = "abc";
+  DecodeBuffer base(data, 3);
+  DecodeBufferSubset subset1(&base, 1);
+  EXPECT_DEBUG_DEATH({ DecodeBufferSubset subset2(&base, 1); },
+                     "There is already a subset");
+}
+
+// Make sure that DecodeBufferSubset notices when the base's cursor has moved.
+TEST(DecodeBufferSubsetDeathTest, BaseCursorAdvanced) {
+  const char data[] = "abc";
+  DecodeBuffer base(data, 3);
+  base.AdvanceCursor(1);
+  EXPECT_DEBUG_DEATH(
+      {
+        DecodeBufferSubset subset1(&base, 2);
+        base.AdvanceCursor(1);
+      },
+      "Access via subset only when present");
+}
+#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/decode_http2_structures.cc b/quiche/http2/decoder/decode_http2_structures.cc
new file mode 100644
index 0000000..8930272
--- /dev/null
+++ b/quiche/http2/decoder/decode_http2_structures.cc
@@ -0,0 +1,121 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/decode_http2_structures.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+// Http2FrameHeader decoding:
+
+void DoDecode(Http2FrameHeader* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2FrameHeader::EncodedSize(), b->Remaining());
+  out->payload_length = b->DecodeUInt24();
+  out->type = static_cast<Http2FrameType>(b->DecodeUInt8());
+  out->flags = static_cast<Http2FrameFlag>(b->DecodeUInt8());
+  out->stream_id = b->DecodeUInt31();
+}
+
+// Http2PriorityFields decoding:
+
+void DoDecode(Http2PriorityFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2PriorityFields::EncodedSize(), b->Remaining());
+  uint32_t stream_id_and_flag = b->DecodeUInt32();
+  out->stream_dependency = stream_id_and_flag & StreamIdMask();
+  if (out->stream_dependency == stream_id_and_flag) {
+    out->is_exclusive = false;
+  } else {
+    out->is_exclusive = true;
+  }
+  // Note that chars are automatically promoted to ints during arithmetic,
+  // so 255 + 1 doesn't end up as zero.
+  out->weight = b->DecodeUInt8() + 1;
+}
+
+// Http2RstStreamFields decoding:
+
+void DoDecode(Http2RstStreamFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2RstStreamFields::EncodedSize(), b->Remaining());
+  out->error_code = static_cast<Http2ErrorCode>(b->DecodeUInt32());
+}
+
+// Http2SettingFields decoding:
+
+void DoDecode(Http2SettingFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2SettingFields::EncodedSize(), b->Remaining());
+  out->parameter = static_cast<Http2SettingsParameter>(b->DecodeUInt16());
+  out->value = b->DecodeUInt32();
+}
+
+// Http2PushPromiseFields decoding:
+
+void DoDecode(Http2PushPromiseFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2PushPromiseFields::EncodedSize(), b->Remaining());
+  out->promised_stream_id = b->DecodeUInt31();
+}
+
+// Http2PingFields decoding:
+
+void DoDecode(Http2PingFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2PingFields::EncodedSize(), b->Remaining());
+  memcpy(out->opaque_bytes, b->cursor(), Http2PingFields::EncodedSize());
+  b->AdvanceCursor(Http2PingFields::EncodedSize());
+}
+
+// Http2GoAwayFields decoding:
+
+void DoDecode(Http2GoAwayFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2GoAwayFields::EncodedSize(), b->Remaining());
+  out->last_stream_id = b->DecodeUInt31();
+  out->error_code = static_cast<Http2ErrorCode>(b->DecodeUInt32());
+}
+
+// Http2WindowUpdateFields decoding:
+
+void DoDecode(Http2WindowUpdateFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2WindowUpdateFields::EncodedSize(), b->Remaining());
+  out->window_size_increment = b->DecodeUInt31();
+}
+
+// Http2PriorityUpdateFields decoding:
+
+void DoDecode(Http2PriorityUpdateFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2PriorityUpdateFields::EncodedSize(), b->Remaining());
+  out->prioritized_stream_id = b->DecodeUInt31();
+}
+
+// Http2AltSvcFields decoding:
+
+void DoDecode(Http2AltSvcFields* out, DecodeBuffer* b) {
+  QUICHE_DCHECK_NE(nullptr, out);
+  QUICHE_DCHECK_NE(nullptr, b);
+  QUICHE_DCHECK_LE(Http2AltSvcFields::EncodedSize(), b->Remaining());
+  out->origin_length = b->DecodeUInt16();
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/decode_http2_structures.h b/quiche/http2/decoder/decode_http2_structures.h
new file mode 100644
index 0000000..eeb69a9
--- /dev/null
+++ b/quiche/http2/decoder/decode_http2_structures.h
@@ -0,0 +1,36 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_DECODE_HTTP2_STRUCTURES_H_
+#define QUICHE_HTTP2_DECODER_DECODE_HTTP2_STRUCTURES_H_
+
+// Provides functions for decoding the fixed size structures in the HTTP/2 spec.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// DoDecode(STRUCTURE* out, DecodeBuffer* b) decodes the structure from start
+// to end, advancing the cursor by STRUCTURE::EncodedSize(). The decode buffer
+// must be large enough (i.e. b->Remaining() >= STRUCTURE::EncodedSize()).
+
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2FrameHeader* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2PriorityFields* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2RstStreamFields* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2SettingFields* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2PushPromiseFields* out,
+                                    DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2PingFields* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2GoAwayFields* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2WindowUpdateFields* out,
+                                    DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2AltSvcFields* out, DecodeBuffer* b);
+QUICHE_EXPORT_PRIVATE void DoDecode(Http2PriorityUpdateFields* out,
+                                    DecodeBuffer* b);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_DECODE_HTTP2_STRUCTURES_H_
diff --git a/quiche/http2/decoder/decode_http2_structures_test.cc b/quiche/http2/decoder/decode_http2_structures_test.cc
new file mode 100644
index 0000000..1c3f9bd
--- /dev/null
+++ b/quiche/http2/decoder/decode_http2_structures_test.cc
@@ -0,0 +1,461 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/decode_http2_structures.h"
+
+// Tests decoding all of the fixed size HTTP/2 structures (i.e. those defined
+// in quiche/http2/http2_structures.h).
+
+#include <stddef.h>
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+template <typename T, size_t N>
+absl::string_view ToStringPiece(T (&data)[N]) {
+  return absl::string_view(reinterpret_cast<const char*>(data), N * sizeof(T));
+}
+
+template <class S>
+std::string SerializeStructure(const S& s) {
+  Http2FrameBuilder fb;
+  fb.Append(s);
+  EXPECT_EQ(S::EncodedSize(), fb.size());
+  return fb.buffer();
+}
+
+template <class S>
+class StructureDecoderTest : public QuicheTest {
+ protected:
+  typedef S Structure;
+
+  StructureDecoderTest() : random_(), random_decode_count_(100) {}
+
+  // Set the fields of |*p| to random values.
+  void Randomize(S* p) { ::http2::test::Randomize(p, &random_); }
+
+  // Fully decodes the Structure at the start of data, and confirms it matches
+  // *expected (if provided).
+  void DecodeLeadingStructure(const S* expected, absl::string_view data) {
+    ASSERT_LE(S::EncodedSize(), data.size());
+    DecodeBuffer db(data);
+    Randomize(&structure_);
+    DoDecode(&structure_, &db);
+    EXPECT_EQ(db.Offset(), S::EncodedSize());
+    if (expected != nullptr) {
+      EXPECT_EQ(structure_, *expected);
+    }
+  }
+
+  template <size_t N>
+  void DecodeLeadingStructure(const char (&data)[N]) {
+    DecodeLeadingStructure(nullptr, absl::string_view(data, N));
+  }
+
+  // Encode the structure |in_s| into bytes, then decode the bytes
+  // and validate that the decoder produced the same field values.
+  void EncodeThenDecode(const S& in_s) {
+    std::string bytes = SerializeStructure(in_s);
+    EXPECT_EQ(S::EncodedSize(), bytes.size());
+    DecodeLeadingStructure(&in_s, bytes);
+  }
+
+  // Generate
+  void TestDecodingRandomizedStructures(size_t count) {
+    for (size_t i = 0; i < count && !HasFailure(); ++i) {
+      Structure input;
+      Randomize(&input);
+      EncodeThenDecode(input);
+    }
+  }
+
+  void TestDecodingRandomizedStructures() {
+    TestDecodingRandomizedStructures(random_decode_count_);
+  }
+
+  Http2Random random_;
+  const size_t random_decode_count_;
+  uint32_t decode_offset_ = 0;
+  S structure_;
+  size_t fast_decode_count_ = 0;
+  size_t slow_decode_count_ = 0;
+};
+
+class FrameHeaderDecoderTest : public StructureDecoderTest<Http2FrameHeader> {};
+
+TEST_F(FrameHeaderDecoderTest, DecodesLiteral) {
+  {
+    // Realistic input.
+    const char kData[] = {
+        '\x00', '\x00', '\x05',          // Payload length: 5
+        '\x01',                          // Frame type: HEADERS
+        '\x08',                          // Flags: PADDED
+        '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
+        '\x04',                          // Padding length: 4
+        '\x00', '\x00', '\x00', '\x00',  // Padding bytes
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(5u, structure_.payload_length);
+      EXPECT_EQ(Http2FrameType::HEADERS, structure_.type);
+      EXPECT_EQ(Http2FrameFlag::PADDED, structure_.flags);
+      EXPECT_EQ(1u, structure_.stream_id);
+    }
+  }
+  {
+    // Unlikely input.
+    const char kData[] = {
+        '\xff', '\xff', '\xff',          // Payload length: uint24 max
+        '\xff',                          // Frame type: Unknown
+        '\xff',                          // Flags: Unknown/All
+        '\xff', '\xff', '\xff', '\xff',  // Stream ID: uint31 max, plus R-bit
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ((1u << 24) - 1, structure_.payload_length);
+      EXPECT_EQ(static_cast<Http2FrameType>(255), structure_.type);
+      EXPECT_EQ(255, structure_.flags);
+      EXPECT_EQ(0x7FFFFFFFu, structure_.stream_id);
+    }
+  }
+}
+
+TEST_F(FrameHeaderDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class PriorityFieldsDecoderTest
+    : public StructureDecoderTest<Http2PriorityFields> {};
+
+TEST_F(PriorityFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x80', '\x00', '\x00', '\x05',  // Exclusive (yes) and Dependency (5)
+        '\xff',                          // Weight: 256 (after adding 1)
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(5u, structure_.stream_dependency);
+      EXPECT_EQ(256u, structure_.weight);
+      EXPECT_EQ(true, structure_.is_exclusive);
+    }
+  }
+  {
+    const char kData[] = {
+        '\x7f', '\xff',
+        '\xff', '\xff',  // Exclusive (no) and Dependency (0x7fffffff)
+        '\x00',          // Weight: 1 (after adding 1)
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(StreamIdMask(), structure_.stream_dependency);
+      EXPECT_EQ(1u, structure_.weight);
+      EXPECT_FALSE(structure_.is_exclusive);
+    }
+  }
+}
+
+TEST_F(PriorityFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class RstStreamFieldsDecoderTest
+    : public StructureDecoderTest<Http2RstStreamFields> {};
+
+TEST_F(RstStreamFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x00', '\x00', '\x00', '\x01',  // Error: PROTOCOL_ERROR
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_TRUE(structure_.IsSupportedErrorCode());
+      EXPECT_EQ(Http2ErrorCode::PROTOCOL_ERROR, structure_.error_code);
+    }
+  }
+  {
+    const char kData[] = {
+        '\xff', '\xff', '\xff',
+        '\xff',  // Error: max uint32 (Unknown error code)
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_FALSE(structure_.IsSupportedErrorCode());
+      EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_.error_code);
+    }
+  }
+}
+
+TEST_F(RstStreamFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class SettingFieldsDecoderTest
+    : public StructureDecoderTest<Http2SettingFields> {};
+
+TEST_F(SettingFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x00', '\x01',                  // Setting: HEADER_TABLE_SIZE
+        '\x00', '\x00', '\x40', '\x00',  // Value: 16K
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_TRUE(structure_.IsSupportedParameter());
+      EXPECT_EQ(Http2SettingsParameter::HEADER_TABLE_SIZE,
+                structure_.parameter);
+      EXPECT_EQ(1u << 14, structure_.value);
+    }
+  }
+  {
+    const char kData[] = {
+        '\x00', '\x00',                  // Setting: Unknown (0)
+        '\xff', '\xff', '\xff', '\xff',  // Value: max uint32
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_FALSE(structure_.IsSupportedParameter());
+      EXPECT_EQ(static_cast<Http2SettingsParameter>(0), structure_.parameter);
+    }
+  }
+}
+
+TEST_F(SettingFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class PushPromiseFieldsDecoderTest
+    : public StructureDecoderTest<Http2PushPromiseFields> {};
+
+TEST_F(PushPromiseFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x00', '\x01', '\x8a', '\x92',  // Promised Stream ID: 101010
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(101010u, structure_.promised_stream_id);
+    }
+  }
+  {
+    // Promised stream id has R-bit (reserved for future use) set, which
+    // should be cleared by the decoder.
+    const char kData[] = {
+        '\xff', '\xff', '\xff',
+        '\xff',  // Promised Stream ID: max uint31 and R-bit
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(StreamIdMask(), structure_.promised_stream_id);
+    }
+  }
+}
+
+TEST_F(PushPromiseFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class PingFieldsDecoderTest : public StructureDecoderTest<Http2PingFields> {};
+
+TEST_F(PingFieldsDecoderTest, DecodesLiteral) {
+  {
+    // Each byte is different, so can detect if order changed.
+    const char kData[] = {
+        '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(absl::string_view(kData, 8),
+                ToStringPiece(structure_.opaque_bytes));
+    }
+  }
+  {
+    // All zeros, detect problems handling NULs.
+    const char kData[] = {
+        '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(absl::string_view(kData, 8),
+                ToStringPiece(structure_.opaque_bytes));
+    }
+  }
+  {
+    const char kData[] = {
+        '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(absl::string_view(kData, 8),
+                ToStringPiece(structure_.opaque_bytes));
+    }
+  }
+}
+
+TEST_F(PingFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class GoAwayFieldsDecoderTest : public StructureDecoderTest<Http2GoAwayFields> {
+};
+
+TEST_F(GoAwayFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x00', '\x00', '\x00', '\x00',  // Last Stream ID: 0
+        '\x00', '\x00', '\x00', '\x00',  // Error: NO_ERROR (0)
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(0u, structure_.last_stream_id);
+      EXPECT_TRUE(structure_.IsSupportedErrorCode());
+      EXPECT_EQ(Http2ErrorCode::HTTP2_NO_ERROR, structure_.error_code);
+    }
+  }
+  {
+    const char kData[] = {
+        '\x00', '\x00', '\x00', '\x01',  // Last Stream ID: 1
+        '\x00', '\x00', '\x00', '\x0d',  // Error: HTTP_1_1_REQUIRED
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(1u, structure_.last_stream_id);
+      EXPECT_TRUE(structure_.IsSupportedErrorCode());
+      EXPECT_EQ(Http2ErrorCode::HTTP_1_1_REQUIRED, structure_.error_code);
+    }
+  }
+  {
+    const char kData[] = {
+        '\xff', '\xff',
+        '\xff', '\xff',  // Last Stream ID: max uint31 and R-bit
+        '\xff', '\xff',
+        '\xff', '\xff',  // Error: max uint32 (Unknown error code)
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(StreamIdMask(), structure_.last_stream_id);  // No high-bit.
+      EXPECT_FALSE(structure_.IsSupportedErrorCode());
+      EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_.error_code);
+    }
+  }
+}
+
+TEST_F(GoAwayFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class WindowUpdateFieldsDecoderTest
+    : public StructureDecoderTest<Http2WindowUpdateFields> {};
+
+TEST_F(WindowUpdateFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x00', '\x01', '\x00', '\x00',  // Window Size Increment: 2 ^ 16
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(1u << 16, structure_.window_size_increment);
+    }
+  }
+  {
+    // Increment must be non-zero, but we need to be able to decode the invalid
+    // zero to detect it.
+    const char kData[] = {
+        '\x00', '\x00', '\x00', '\x00',  // Window Size Increment: 0
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(0u, structure_.window_size_increment);
+    }
+  }
+  {
+    // Increment has R-bit (reserved for future use) set, which
+    // should be cleared by the decoder.
+    // clang-format off
+    const char kData[] = {
+        // Window Size Increment: max uint31 and R-bit
+        '\xff', '\xff', '\xff', '\xff',
+    };
+    // clang-format on
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(StreamIdMask(), structure_.window_size_increment);
+    }
+  }
+}
+
+TEST_F(WindowUpdateFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+//------------------------------------------------------------------------------
+
+class AltSvcFieldsDecoderTest : public StructureDecoderTest<Http2AltSvcFields> {
+};
+
+TEST_F(AltSvcFieldsDecoderTest, DecodesLiteral) {
+  {
+    const char kData[] = {
+        '\x00', '\x00',  // Origin Length: 0
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(0, structure_.origin_length);
+    }
+  }
+  {
+    const char kData[] = {
+        '\x00', '\x14',  // Origin Length: 20
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(20, structure_.origin_length);
+    }
+  }
+  {
+    const char kData[] = {
+        '\xff', '\xff',  // Origin Length: uint16 max
+    };
+    DecodeLeadingStructure(kData);
+    if (!HasFailure()) {
+      EXPECT_EQ(65535, structure_.origin_length);
+    }
+  }
+}
+
+TEST_F(AltSvcFieldsDecoderTest, DecodesRandomized) {
+  TestDecodingRandomizedStructures();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/decode_status.cc b/quiche/http2/decoder/decode_status.cc
new file mode 100644
index 0000000..2adf9b5
--- /dev/null
+++ b/quiche/http2/decoder/decode_status.cc
@@ -0,0 +1,28 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/decode_status.h"
+
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out, DecodeStatus v) {
+  switch (v) {
+    case DecodeStatus::kDecodeDone:
+      return out << "DecodeDone";
+    case DecodeStatus::kDecodeInProgress:
+      return out << "DecodeInProgress";
+    case DecodeStatus::kDecodeError:
+      return out << "DecodeError";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_147_1) << "Unknown DecodeStatus " << unknown;
+  return out << "DecodeStatus(" << unknown << ")";
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/decode_status.h b/quiche/http2/decoder/decode_status.h
new file mode 100644
index 0000000..e59d68a
--- /dev/null
+++ b/quiche/http2/decoder/decode_status.h
@@ -0,0 +1,33 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_DECODE_STATUS_H_
+#define QUICHE_HTTP2_DECODER_DECODE_STATUS_H_
+
+// Enum DecodeStatus is used to report the status of decoding of many
+// types of HTTP/2 and HPACK objects.
+
+#include <ostream>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+enum class DecodeStatus {
+  // Decoding is done.
+  kDecodeDone,
+
+  // Decoder needs more input to be able to make progress.
+  kDecodeInProgress,
+
+  // Decoding failed (e.g. HPACK variable length integer is too large, or
+  // an HTTP/2 frame has padding declared to be larger than the payload).
+  kDecodeError,
+};
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               DecodeStatus v);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_DECODE_STATUS_H_
diff --git a/quiche/http2/decoder/frame_decoder_state.cc b/quiche/http2/decoder/frame_decoder_state.cc
new file mode 100644
index 0000000..0467486
--- /dev/null
+++ b/quiche/http2/decoder/frame_decoder_state.cc
@@ -0,0 +1,80 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/frame_decoder_state.h"
+
+namespace http2 {
+
+DecodeStatus FrameDecoderState::ReadPadLength(DecodeBuffer* db,
+                                              bool report_pad_length) {
+  HTTP2_DVLOG(2) << "ReadPadLength db->Remaining=" << db->Remaining()
+                 << "; payload_length=" << frame_header().payload_length;
+  QUICHE_DCHECK(IsPaddable());
+  QUICHE_DCHECK(frame_header().IsPadded());
+
+  // Pad Length is always at the start of the frame, so remaining_payload_
+  // should equal payload_length at this point.
+  const uint32_t total_payload = frame_header().payload_length;
+  QUICHE_DCHECK_EQ(total_payload, remaining_payload_);
+  QUICHE_DCHECK_EQ(0u, remaining_padding_);
+
+  if (db->HasData()) {
+    const uint32_t pad_length = db->DecodeUInt8();
+    const uint32_t total_padding = pad_length + 1;
+    if (total_padding <= total_payload) {
+      remaining_padding_ = pad_length;
+      remaining_payload_ = total_payload - total_padding;
+      if (report_pad_length) {
+        listener()->OnPadLength(pad_length);
+      }
+      return DecodeStatus::kDecodeDone;
+    }
+    const uint32_t missing_length = total_padding - total_payload;
+    // To allow for the possibility of recovery, record the number of
+    // remaining bytes of the frame's payload (invalid though it is)
+    // in remaining_payload_.
+    remaining_payload_ = total_payload - 1;  // 1 for sizeof(Pad Length).
+    remaining_padding_ = 0;
+    listener()->OnPaddingTooLong(frame_header(), missing_length);
+    return DecodeStatus::kDecodeError;
+  }
+
+  if (total_payload == 0) {
+    remaining_payload_ = 0;
+    remaining_padding_ = 0;
+    listener()->OnPaddingTooLong(frame_header(), 1);
+    return DecodeStatus::kDecodeError;
+  }
+  // Need to wait for another buffer.
+  return DecodeStatus::kDecodeInProgress;
+}
+
+bool FrameDecoderState::SkipPadding(DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "SkipPadding remaining_padding_=" << remaining_padding_
+                 << ", db->Remaining=" << db->Remaining()
+                 << ", header: " << frame_header();
+  QUICHE_DCHECK_EQ(remaining_payload_, 0u);
+  QUICHE_DCHECK(IsPaddable()) << "header: " << frame_header();
+  QUICHE_DCHECK(remaining_padding_ == 0 || frame_header().IsPadded())
+      << "remaining_padding_=" << remaining_padding_
+      << ", header: " << frame_header();
+  const size_t avail = AvailablePadding(db);
+  if (avail > 0) {
+    listener()->OnPadding(db->cursor(), avail);
+    db->AdvanceCursor(avail);
+    remaining_padding_ -= avail;
+  }
+  return remaining_padding_ == 0;
+}
+
+DecodeStatus FrameDecoderState::ReportFrameSizeError() {
+  HTTP2_DVLOG(2) << "FrameDecoderState::ReportFrameSizeError: "
+                 << " remaining_payload_=" << remaining_payload_
+                 << "; remaining_padding_=" << remaining_padding_
+                 << ", header: " << frame_header();
+  listener()->OnFrameSizeError(frame_header());
+  return DecodeStatus::kDecodeError;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/frame_decoder_state.h b/quiche/http2/decoder/frame_decoder_state.h
new file mode 100644
index 0000000..aac7154
--- /dev/null
+++ b/quiche/http2/decoder/frame_decoder_state.h
@@ -0,0 +1,252 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
+#define QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
+
+// FrameDecoderState provides state and behaviors in support of decoding
+// the common frame header and the payload of all frame types.
+// It is an input to all of the payload decoders.
+
+// TODO(jamessynge): Since FrameDecoderState has far more than state in it,
+// rename to FrameDecoderHelper, or similar.
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/http2_structure_decoder.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class FrameDecoderStatePeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE FrameDecoderState {
+ public:
+  FrameDecoderState() {}
+
+  // Sets the listener which the decoders should call as they decode HTTP/2
+  // frames. The listener can be changed at any time, which allows for replacing
+  // it with a no-op listener when an error is detected, either by the payload
+  // decoder (OnPaddingTooLong or OnFrameSizeError) or by the "real" listener.
+  // That in turn allows us to define Http2FrameDecoderListener such that all
+  // methods have return type void, with no direct way to indicate whether the
+  // decoder should stop, and to eliminate from the decoder all checks of the
+  // return value. Instead the listener/caller can simply replace the current
+  // listener with a no-op listener implementation.
+  // TODO(jamessynge): Make set_listener private as only Http2FrameDecoder
+  // and tests need to set it, so it doesn't need to be public.
+  void set_listener(Http2FrameDecoderListener* listener) {
+    listener_ = listener;
+  }
+  Http2FrameDecoderListener* listener() const { return listener_; }
+
+  // The most recently decoded frame header.
+  const Http2FrameHeader& frame_header() const { return frame_header_; }
+
+  // Decode a structure in the payload, adjusting remaining_payload_ to account
+  // for the consumed portion of the payload. Returns kDecodeDone when fully
+  // decoded, kDecodeError if it ran out of payload before decoding completed,
+  // and kDecodeInProgress if the decode buffer didn't have enough of the
+  // remaining payload.
+  template <class S>
+  DecodeStatus StartDecodingStructureInPayload(S* out, DecodeBuffer* db) {
+    HTTP2_DVLOG(2) << __func__ << "\n\tdb->Remaining=" << db->Remaining()
+                   << "\n\tremaining_payload_=" << remaining_payload_
+                   << "\n\tneed=" << S::EncodedSize();
+    DecodeStatus status =
+        structure_decoder_.Start(out, db, &remaining_payload_);
+    if (status != DecodeStatus::kDecodeError) {
+      return status;
+    }
+    HTTP2_DVLOG(2)
+        << "StartDecodingStructureInPayload: detected frame size error";
+    return ReportFrameSizeError();
+  }
+
+  // Resume decoding of a structure that has been split across buffers,
+  // adjusting remaining_payload_ to account for the consumed portion of
+  // the payload. Returns values are as for StartDecodingStructureInPayload.
+  template <class S>
+  DecodeStatus ResumeDecodingStructureInPayload(S* out, DecodeBuffer* db) {
+    HTTP2_DVLOG(2) << __func__ << "\n\tdb->Remaining=" << db->Remaining()
+                   << "\n\tremaining_payload_=" << remaining_payload_;
+    if (structure_decoder_.Resume(out, db, &remaining_payload_)) {
+      return DecodeStatus::kDecodeDone;
+    } else if (remaining_payload_ > 0) {
+      return DecodeStatus::kDecodeInProgress;
+    } else {
+      HTTP2_DVLOG(2)
+          << "ResumeDecodingStructureInPayload: detected frame size error";
+      return ReportFrameSizeError();
+    }
+  }
+
+  // Initializes the two remaining* fields, which is needed if the frame's
+  // payload is split across buffers, or the decoder calls ReadPadLength or
+  // StartDecodingStructureInPayload, and of course the methods below which
+  // read those fields, as their names imply.
+  void InitializeRemainders() {
+    remaining_payload_ = frame_header().payload_length;
+    // Note that remaining_total_payload() relies on remaining_padding_ being
+    // zero for frames that have no padding.
+    remaining_padding_ = 0;
+  }
+
+  // Returns the number of bytes of the frame's payload that remain to be
+  // decoded, including any trailing padding. This method must only be called
+  // after the variables have been initialized, which in practice means once a
+  // payload decoder has called InitializeRemainders and/or ReadPadLength.
+  size_t remaining_total_payload() const {
+    QUICHE_DCHECK(IsPaddable() || remaining_padding_ == 0) << frame_header();
+    return remaining_payload_ + remaining_padding_;
+  }
+
+  // Returns the number of bytes of the frame's payload that remain to be
+  // decoded, excluding any trailing padding. This method must only be called
+  // after the variable has been initialized, which in practice means once a
+  // payload decoder has called InitializeRemainders; ReadPadLength will deduct
+  // the total number of padding bytes from remaining_payload_, including the
+  // size of the Pad Length field itself (1 byte).
+  size_t remaining_payload() const { return remaining_payload_; }
+
+  // Returns the number of bytes of the frame's payload that remain to be
+  // decoded, including any trailing padding. This method must only be called if
+  // the frame type allows padding, and after the variable has been initialized,
+  // which in practice means once a payload decoder has called
+  // InitializeRemainders and/or ReadPadLength.
+  size_t remaining_payload_and_padding() const {
+    QUICHE_DCHECK(IsPaddable()) << frame_header();
+    return remaining_payload_ + remaining_padding_;
+  }
+
+  // Returns the number of bytes of trailing padding after the payload that
+  // remain to be decoded. This method must only be called if the frame type
+  // allows padding, and after the variable has been initialized, which in
+  // practice means once a payload decoder has called InitializeRemainders,
+  // and isn't set to a non-zero value until ReadPadLength has been called.
+  uint32_t remaining_padding() const {
+    QUICHE_DCHECK(IsPaddable()) << frame_header();
+    return remaining_padding_;
+  }
+
+  // How many bytes of the remaining payload are in db?
+  size_t AvailablePayload(DecodeBuffer* db) const {
+    return db->MinLengthRemaining(remaining_payload_);
+  }
+
+  // How many bytes of the remaining payload and padding are in db?
+  // Call only for frames whose type is paddable.
+  size_t AvailablePayloadAndPadding(DecodeBuffer* db) const {
+    QUICHE_DCHECK(IsPaddable()) << frame_header();
+    return db->MinLengthRemaining(remaining_payload_ + remaining_padding_);
+  }
+
+  // How many bytes of the padding that have not yet been skipped are in db?
+  // Call only after remaining_padding_ has been set (for padded frames), or
+  // been cleared (for unpadded frames); and after all of the non-padding
+  // payload has been decoded.
+  size_t AvailablePadding(DecodeBuffer* db) const {
+    QUICHE_DCHECK(IsPaddable()) << frame_header();
+    QUICHE_DCHECK_EQ(remaining_payload_, 0u);
+    return db->MinLengthRemaining(remaining_padding_);
+  }
+
+  // Reduces remaining_payload_ by amount. To be called by a payload decoder
+  // after it has passed a variable length portion of the payload to the
+  // listener; remaining_payload_ will be automatically reduced when fixed
+  // size structures and padding, including the Pad Length field, are decoded.
+  void ConsumePayload(size_t amount) {
+    QUICHE_DCHECK_LE(amount, remaining_payload_);
+    remaining_payload_ -= amount;
+  }
+
+  // Reads the Pad Length field into remaining_padding_, and appropriately sets
+  // remaining_payload_. When present, the Pad Length field is always the first
+  // field in the payload, which this method relies on so that the caller need
+  // not set remaining_payload_ before calling this method.
+  // If report_pad_length is true, calls the listener's OnPadLength method when
+  // it decodes the Pad Length field.
+  // Returns kDecodeDone if the decode buffer was not empty (i.e. because the
+  // field is only a single byte long, it can always be decoded if the buffer is
+  // not empty).
+  // Returns kDecodeError if the buffer is empty because the frame has no
+  // payload (i.e. payload_length() == 0).
+  // Returns kDecodeInProgress if the buffer is empty but the frame has a
+  // payload.
+  DecodeStatus ReadPadLength(DecodeBuffer* db, bool report_pad_length);
+
+  // Skip the trailing padding bytes; only call once remaining_payload_==0.
+  // Returns true when the padding has been skipped.
+  // Does NOT check that the padding is all zeroes.
+  bool SkipPadding(DecodeBuffer* db);
+
+  // Calls the listener's OnFrameSizeError method and returns kDecodeError.
+  DecodeStatus ReportFrameSizeError();
+
+ private:
+  friend class Http2FrameDecoder;
+  friend class test::FrameDecoderStatePeer;
+
+  // Starts the decoding of a common frame header. Returns true if completed the
+  // decoding, false if the decode buffer didn't have enough data in it, in
+  // which case the decode buffer will have been drained and the caller should
+  // call ResumeDecodingFrameHeader when more data is available. This is called
+  // from Http2FrameDecoder, a friend class.
+  bool StartDecodingFrameHeader(DecodeBuffer* db) {
+    return structure_decoder_.Start(&frame_header_, db);
+  }
+
+  // Resumes decoding the common frame header after the preceding call to
+  // StartDecodingFrameHeader returned false, as did any subsequent calls to
+  // ResumeDecodingFrameHeader. This is called from Http2FrameDecoder,
+  // a friend class.
+  bool ResumeDecodingFrameHeader(DecodeBuffer* db) {
+    return structure_decoder_.Resume(&frame_header_, db);
+  }
+
+  // Clear any of the flags in the frame header that aren't set in valid_flags.
+  void RetainFlags(uint8_t valid_flags) {
+    frame_header_.RetainFlags(valid_flags);
+  }
+
+  // Clear all of the flags in the frame header; for use with frame types that
+  // don't define any flags, such as WINDOW_UPDATE.
+  void ClearFlags() { frame_header_.flags = Http2FrameFlag(); }
+
+  // Returns true if the type of frame being decoded can have padding.
+  bool IsPaddable() const {
+    return frame_header().type == Http2FrameType::DATA ||
+           frame_header().type == Http2FrameType::HEADERS ||
+           frame_header().type == Http2FrameType::PUSH_PROMISE;
+  }
+
+  Http2FrameDecoderListener* listener_ = nullptr;
+  Http2FrameHeader frame_header_;
+
+  // Number of bytes remaining to be decoded, if set; does not include the
+  // trailing padding once the length of padding has been determined.
+  // See ReadPadLength.
+  uint32_t remaining_payload_;
+
+  // The amount of trailing padding after the payload that remains to be
+  // decoded. See ReadPadLength.
+  uint32_t remaining_padding_;
+
+  // Generic decoder of structures, which takes care of buffering the needed
+  // bytes if the encoded structure is split across decode buffers.
+  Http2StructureDecoder structure_decoder_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
diff --git a/quiche/http2/decoder/frame_decoder_state_test_util.cc b/quiche/http2/decoder/frame_decoder_state_test_util.cc
new file mode 100644
index 0000000..9f34210
--- /dev/null
+++ b/quiche/http2/decoder/frame_decoder_state_test_util.cc
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/frame_decoder_state_test_util.h"
+
+#include "quiche/http2/decoder/http2_structure_decoder_test_util.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+
+namespace http2 {
+namespace test {
+
+// static
+void FrameDecoderStatePeer::Randomize(FrameDecoderState* p, Http2Random* rng) {
+  HTTP2_VLOG(1) << "FrameDecoderStatePeer::Randomize";
+  ::http2::test::Randomize(&p->frame_header_, rng);
+  p->remaining_payload_ = rng->Rand32();
+  p->remaining_padding_ = rng->Rand32();
+  Http2StructureDecoderPeer::Randomize(&p->structure_decoder_, rng);
+}
+
+// static
+void FrameDecoderStatePeer::set_frame_header(const Http2FrameHeader& header,
+                                             FrameDecoderState* p) {
+  HTTP2_VLOG(1) << "FrameDecoderStatePeer::set_frame_header " << header;
+  p->frame_header_ = header;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/frame_decoder_state_test_util.h b/quiche/http2/decoder/frame_decoder_state_test_util.h
new file mode 100644
index 0000000..b690040
--- /dev/null
+++ b/quiche/http2/decoder/frame_decoder_state_test_util.h
@@ -0,0 +1,36 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_TEST_UTIL_H_
+#define QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_TEST_UTIL_H_
+
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+
+namespace http2 {
+namespace test {
+
+class FrameDecoderStatePeer {
+ public:
+  // Randomizes (i.e. corrupts) the fields of the FrameDecoderState.
+  // PayloadDecoderBaseTest::StartDecoding calls this before passing the first
+  // decode buffer to the payload decoder, which increases the likelihood of
+  // detecting any use of prior states of the decoder on the decoding of
+  // future payloads.
+  static void Randomize(FrameDecoderState* p, Http2Random* rng);
+
+  // Inject a frame header into the FrameDecoderState.
+  // PayloadDecoderBaseTest::StartDecoding calls this just after calling
+  // Randomize (above), to simulate a full frame decoder having just finished
+  // decoding the common frame header and then calling the appropriate payload
+  // decoder based on the frame type in that frame header.
+  static void set_frame_header(const Http2FrameHeader& header,
+                               FrameDecoderState* p);
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_TEST_UTIL_H_
diff --git a/quiche/http2/decoder/http2_frame_decoder.cc b/quiche/http2/decoder/http2_frame_decoder.cc
new file mode 100644
index 0000000..8daa81d
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder.cc
@@ -0,0 +1,460 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_frame_decoder.h"
+
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out, Http2FrameDecoder::State v) {
+  switch (v) {
+    case Http2FrameDecoder::State::kStartDecodingHeader:
+      return out << "kStartDecodingHeader";
+    case Http2FrameDecoder::State::kResumeDecodingHeader:
+      return out << "kResumeDecodingHeader";
+    case Http2FrameDecoder::State::kResumeDecodingPayload:
+      return out << "kResumeDecodingPayload";
+    case Http2FrameDecoder::State::kDiscardPayload:
+      return out << "kDiscardPayload";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_155_1) << "Http2FrameDecoder::State " << unknown;
+  return out << "Http2FrameDecoder::State(" << unknown << ")";
+}
+
+Http2FrameDecoder::Http2FrameDecoder(Http2FrameDecoderListener* listener)
+    : state_(State::kStartDecodingHeader),
+      maximum_payload_size_(Http2SettingsInfo::DefaultMaxFrameSize()) {
+  set_listener(listener);
+}
+
+void Http2FrameDecoder::set_listener(Http2FrameDecoderListener* listener) {
+  if (listener == nullptr) {
+    listener = &no_op_listener_;
+  }
+  frame_decoder_state_.set_listener(listener);
+}
+
+Http2FrameDecoderListener* Http2FrameDecoder::listener() const {
+  return frame_decoder_state_.listener();
+}
+
+DecodeStatus Http2FrameDecoder::DecodeFrame(DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "Http2FrameDecoder::DecodeFrame state=" << state_;
+  switch (state_) {
+    case State::kStartDecodingHeader:
+      if (frame_decoder_state_.StartDecodingFrameHeader(db)) {
+        return StartDecodingPayload(db);
+      }
+      state_ = State::kResumeDecodingHeader;
+      return DecodeStatus::kDecodeInProgress;
+
+    case State::kResumeDecodingHeader:
+      if (frame_decoder_state_.ResumeDecodingFrameHeader(db)) {
+        return StartDecodingPayload(db);
+      }
+      return DecodeStatus::kDecodeInProgress;
+
+    case State::kResumeDecodingPayload:
+      return ResumeDecodingPayload(db);
+
+    case State::kDiscardPayload:
+      return DiscardPayload(db);
+  }
+
+  QUICHE_NOTREACHED();
+  return DecodeStatus::kDecodeError;
+}
+
+size_t Http2FrameDecoder::remaining_payload() const {
+  return frame_decoder_state_.remaining_payload();
+}
+
+uint32_t Http2FrameDecoder::remaining_padding() const {
+  return frame_decoder_state_.remaining_padding();
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingPayload(DecodeBuffer* db) {
+  const Http2FrameHeader& header = frame_header();
+
+  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
+  // SpdyFramer's exact states.
+  if (!listener()->OnFrameHeader(header)) {
+    HTTP2_DVLOG(2) << "OnFrameHeader rejected the frame, will discard; header: "
+                   << header;
+    state_ = State::kDiscardPayload;
+    frame_decoder_state_.InitializeRemainders();
+    return DecodeStatus::kDecodeError;
+  }
+
+  if (header.payload_length > maximum_payload_size_) {
+    HTTP2_DVLOG(2) << "Payload length is greater than allowed: "
+                   << header.payload_length << " > " << maximum_payload_size_
+                   << "\n   header: " << header;
+    state_ = State::kDiscardPayload;
+    frame_decoder_state_.InitializeRemainders();
+    listener()->OnFrameSizeError(header);
+    return DecodeStatus::kDecodeError;
+  }
+
+  // The decode buffer can extend across many frames. Make sure that the
+  // buffer we pass to the start method that is specific to the frame type
+  // does not exend beyond this frame.
+  DecodeBufferSubset subset(db, header.payload_length);
+  DecodeStatus status;
+  switch (header.type) {
+    case Http2FrameType::DATA:
+      status = StartDecodingDataPayload(&subset);
+      break;
+
+    case Http2FrameType::HEADERS:
+      status = StartDecodingHeadersPayload(&subset);
+      break;
+
+    case Http2FrameType::PRIORITY:
+      status = StartDecodingPriorityPayload(&subset);
+      break;
+
+    case Http2FrameType::RST_STREAM:
+      status = StartDecodingRstStreamPayload(&subset);
+      break;
+
+    case Http2FrameType::SETTINGS:
+      status = StartDecodingSettingsPayload(&subset);
+      break;
+
+    case Http2FrameType::PUSH_PROMISE:
+      status = StartDecodingPushPromisePayload(&subset);
+      break;
+
+    case Http2FrameType::PING:
+      status = StartDecodingPingPayload(&subset);
+      break;
+
+    case Http2FrameType::GOAWAY:
+      status = StartDecodingGoAwayPayload(&subset);
+      break;
+
+    case Http2FrameType::WINDOW_UPDATE:
+      status = StartDecodingWindowUpdatePayload(&subset);
+      break;
+
+    case Http2FrameType::CONTINUATION:
+      status = StartDecodingContinuationPayload(&subset);
+      break;
+
+    case Http2FrameType::ALTSVC:
+      status = StartDecodingAltSvcPayload(&subset);
+      break;
+
+    case Http2FrameType::PRIORITY_UPDATE:
+      status = StartDecodingPriorityUpdatePayload(&subset);
+      break;
+
+    default:
+      status = StartDecodingUnknownPayload(&subset);
+      break;
+  }
+
+  if (status == DecodeStatus::kDecodeDone) {
+    state_ = State::kStartDecodingHeader;
+    return status;
+  } else if (status == DecodeStatus::kDecodeInProgress) {
+    state_ = State::kResumeDecodingPayload;
+    return status;
+  } else {
+    state_ = State::kDiscardPayload;
+    return status;
+  }
+}
+
+DecodeStatus Http2FrameDecoder::ResumeDecodingPayload(DecodeBuffer* db) {
+  // The decode buffer can extend across many frames. Make sure that the
+  // buffer we pass to the start method that is specific to the frame type
+  // does not exend beyond this frame.
+  size_t remaining = frame_decoder_state_.remaining_total_payload();
+  QUICHE_DCHECK_LE(remaining, frame_header().payload_length);
+  DecodeBufferSubset subset(db, remaining);
+  DecodeStatus status;
+  switch (frame_header().type) {
+    case Http2FrameType::DATA:
+      status = ResumeDecodingDataPayload(&subset);
+      break;
+
+    case Http2FrameType::HEADERS:
+      status = ResumeDecodingHeadersPayload(&subset);
+      break;
+
+    case Http2FrameType::PRIORITY:
+      status = ResumeDecodingPriorityPayload(&subset);
+      break;
+
+    case Http2FrameType::RST_STREAM:
+      status = ResumeDecodingRstStreamPayload(&subset);
+      break;
+
+    case Http2FrameType::SETTINGS:
+      status = ResumeDecodingSettingsPayload(&subset);
+      break;
+
+    case Http2FrameType::PUSH_PROMISE:
+      status = ResumeDecodingPushPromisePayload(&subset);
+      break;
+
+    case Http2FrameType::PING:
+      status = ResumeDecodingPingPayload(&subset);
+      break;
+
+    case Http2FrameType::GOAWAY:
+      status = ResumeDecodingGoAwayPayload(&subset);
+      break;
+
+    case Http2FrameType::WINDOW_UPDATE:
+      status = ResumeDecodingWindowUpdatePayload(&subset);
+      break;
+
+    case Http2FrameType::CONTINUATION:
+      status = ResumeDecodingContinuationPayload(&subset);
+      break;
+
+    case Http2FrameType::ALTSVC:
+      status = ResumeDecodingAltSvcPayload(&subset);
+      break;
+
+    case Http2FrameType::PRIORITY_UPDATE:
+      status = ResumeDecodingPriorityUpdatePayload(&subset);
+      break;
+
+    default:
+      status = ResumeDecodingUnknownPayload(&subset);
+      break;
+  }
+
+  if (status == DecodeStatus::kDecodeDone) {
+    state_ = State::kStartDecodingHeader;
+    return status;
+  } else if (status == DecodeStatus::kDecodeInProgress) {
+    return status;
+  } else {
+    state_ = State::kDiscardPayload;
+    return status;
+  }
+}
+
+// Clear any of the flags in the frame header that aren't set in valid_flags.
+void Http2FrameDecoder::RetainFlags(uint8_t valid_flags) {
+  frame_decoder_state_.RetainFlags(valid_flags);
+}
+
+// Clear all of the flags in the frame header; for use with frame types that
+// don't define any flags, such as WINDOW_UPDATE.
+void Http2FrameDecoder::ClearFlags() {
+  frame_decoder_state_.ClearFlags();
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingAltSvcPayload(DecodeBuffer* db) {
+  ClearFlags();
+  return altsvc_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                      db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingAltSvcPayload(DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return altsvc_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
+                                                       db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingContinuationPayload(
+    DecodeBuffer* db) {
+  RetainFlags(Http2FrameFlag::END_HEADERS);
+  return continuation_payload_decoder_.StartDecodingPayload(
+      &frame_decoder_state_, db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingContinuationPayload(
+    DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return continuation_payload_decoder_.ResumeDecodingPayload(
+      &frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingDataPayload(DecodeBuffer* db) {
+  RetainFlags(Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED);
+  return data_payload_decoder_.StartDecodingPayload(&frame_decoder_state_, db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingDataPayload(DecodeBuffer* db) {
+  return data_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingGoAwayPayload(DecodeBuffer* db) {
+  ClearFlags();
+  return goaway_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                      db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingGoAwayPayload(DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return goaway_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
+                                                       db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingHeadersPayload(DecodeBuffer* db) {
+  RetainFlags(Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS |
+              Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY);
+  return headers_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                       db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingHeadersPayload(DecodeBuffer* db) {
+  QUICHE_DCHECK_LE(frame_decoder_state_.remaining_payload_and_padding(),
+                   frame_header().payload_length);
+  return headers_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
+                                                        db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingPingPayload(DecodeBuffer* db) {
+  RetainFlags(Http2FrameFlag::ACK);
+  return ping_payload_decoder_.StartDecodingPayload(&frame_decoder_state_, db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingPingPayload(DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return ping_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingPriorityPayload(DecodeBuffer* db) {
+  ClearFlags();
+  return priority_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                        db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingPriorityPayload(
+    DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return priority_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
+                                                         db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingPriorityUpdatePayload(
+    DecodeBuffer* db) {
+  ClearFlags();
+  return priority_payload_update_decoder_.StartDecodingPayload(
+      &frame_decoder_state_, db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingPriorityUpdatePayload(
+    DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return priority_payload_update_decoder_.ResumeDecodingPayload(
+      &frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingPushPromisePayload(
+    DecodeBuffer* db) {
+  RetainFlags(Http2FrameFlag::END_HEADERS | Http2FrameFlag::PADDED);
+  return push_promise_payload_decoder_.StartDecodingPayload(
+      &frame_decoder_state_, db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingPushPromisePayload(
+    DecodeBuffer* db) {
+  QUICHE_DCHECK_LE(frame_decoder_state_.remaining_payload_and_padding(),
+                   frame_header().payload_length);
+  return push_promise_payload_decoder_.ResumeDecodingPayload(
+      &frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingRstStreamPayload(
+    DecodeBuffer* db) {
+  ClearFlags();
+  return rst_stream_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                          db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingRstStreamPayload(
+    DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return rst_stream_payload_decoder_.ResumeDecodingPayload(
+      &frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingSettingsPayload(DecodeBuffer* db) {
+  RetainFlags(Http2FrameFlag::ACK);
+  return settings_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                        db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingSettingsPayload(
+    DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return settings_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
+                                                         db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingUnknownPayload(DecodeBuffer* db) {
+  // We don't known what type of frame this is, so we don't know which flags
+  // are valid, so we don't touch them.
+  return unknown_payload_decoder_.StartDecodingPayload(&frame_decoder_state_,
+                                                       db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingUnknownPayload(DecodeBuffer* db) {
+  // We don't known what type of frame this is, so we treat it as not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return unknown_payload_decoder_.ResumeDecodingPayload(&frame_decoder_state_,
+                                                        db);
+}
+
+DecodeStatus Http2FrameDecoder::StartDecodingWindowUpdatePayload(
+    DecodeBuffer* db) {
+  ClearFlags();
+  return window_update_payload_decoder_.StartDecodingPayload(
+      &frame_decoder_state_, db);
+}
+DecodeStatus Http2FrameDecoder::ResumeDecodingWindowUpdatePayload(
+    DecodeBuffer* db) {
+  // The frame is not paddable.
+  QUICHE_DCHECK_EQ(frame_decoder_state_.remaining_total_payload(),
+                   frame_decoder_state_.remaining_payload());
+  return window_update_payload_decoder_.ResumeDecodingPayload(
+      &frame_decoder_state_, db);
+}
+
+DecodeStatus Http2FrameDecoder::DiscardPayload(DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "remaining_payload="
+                 << frame_decoder_state_.remaining_payload_
+                 << "; remaining_padding="
+                 << frame_decoder_state_.remaining_padding_;
+  frame_decoder_state_.remaining_payload_ +=
+      frame_decoder_state_.remaining_padding_;
+  frame_decoder_state_.remaining_padding_ = 0;
+  const size_t avail = frame_decoder_state_.AvailablePayload(db);
+  HTTP2_DVLOG(2) << "avail=" << avail;
+  if (avail > 0) {
+    frame_decoder_state_.ConsumePayload(avail);
+    db->AdvanceCursor(avail);
+  }
+  if (frame_decoder_state_.remaining_payload_ == 0) {
+    state_ = State::kStartDecodingHeader;
+    return DecodeStatus::kDecodeDone;
+  }
+  return DecodeStatus::kDecodeInProgress;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_frame_decoder.h b/quiche/http2/decoder/http2_frame_decoder.h
new file mode 100644
index 0000000..70c3858
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder.h
@@ -0,0 +1,215 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_H_
+#define QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_H_
+
+// Http2FrameDecoder decodes the available input until it reaches the end of
+// the input or it reaches the end of the first frame in the input.
+// Note that Http2FrameDecoder does only minimal validation; for example,
+// stream ids are not checked, nor is the sequence of frames such as
+// CONTINUATION frame placement.
+//
+// Http2FrameDecoder enters state kError once it has called the listener's
+// OnFrameSizeError or OnPaddingTooLong methods, and at this time has no
+// provision for leaving that state. While the HTTP/2 spec (RFC7540) allows
+// for some such errors to be considered as just stream errors in some cases,
+// this implementation treats them all as connection errors.
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/continuation_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/data_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/goaway_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/headers_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/ping_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/priority_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/settings_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/unknown_payload_decoder.h"
+#include "quiche/http2/decoder/payload_decoders/window_update_payload_decoder.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class Http2FrameDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE Http2FrameDecoder {
+ public:
+  explicit Http2FrameDecoder(Http2FrameDecoderListener* listener);
+
+  Http2FrameDecoder(const Http2FrameDecoder&) = delete;
+  Http2FrameDecoder& operator=(const Http2FrameDecoder&) = delete;
+
+  // The decoder will call the listener's methods as it decodes a frame.
+  void set_listener(Http2FrameDecoderListener* listener);
+  Http2FrameDecoderListener* listener() const;
+
+  // The decoder will reject frame's whose payload
+  // length field exceeds the maximum payload size.
+  void set_maximum_payload_size(size_t v) { maximum_payload_size_ = v; }
+  size_t maximum_payload_size() const { return maximum_payload_size_; }
+
+  // Decodes the input up to the next frame boundary (i.e. at most one frame).
+  //
+  // Returns kDecodeDone if it decodes the final byte of a frame, OR if there
+  // is no input and it is awaiting the start of a new frame (e.g. if this
+  // is the first call to DecodeFrame, or if the previous call returned
+  // kDecodeDone).
+  //
+  // Returns kDecodeInProgress if it decodes all of the decode buffer, but has
+  // not reached the end of the frame.
+  //
+  // Returns kDecodeError if the frame's padding or length wasn't valid (i.e. if
+  // the decoder called either the listener's OnPaddingTooLong or
+  // OnFrameSizeError method).
+  //
+  // If the decode buffer contains the entirety of a frame payload or field,
+  // then the corresponding Http2FrameDecoderListener::On*Payload(),
+  // OnHpackFragment(), OnGoAwayOpaqueData(), or OnAltSvcValueData() method is
+  // guaranteed to be called exactly once, with the entire payload or field in a
+  // single chunk.
+  DecodeStatus DecodeFrame(DecodeBuffer* db);
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Methods that support Http2FrameDecoderAdapter.
+
+  // Is the remainder of the frame's payload being discarded?
+  bool IsDiscardingPayload() const { return state_ == State::kDiscardPayload; }
+
+  // Returns the number of bytes of the frame's payload that remain to be
+  // decoded, excluding any trailing padding. This method must only be called
+  // after the frame header has been decoded AND DecodeFrame has returned
+  // kDecodeInProgress.
+  size_t remaining_payload() const;
+
+  // Returns the number of bytes of trailing padding after the payload that
+  // remain to be decoded. This method must only be called if the frame type
+  // allows padding, and after the frame header has been decoded AND
+  // DecodeFrame has returned. Will return 0 if the Pad Length field has not
+  // yet been decoded.
+  uint32_t remaining_padding() const;
+
+ private:
+  enum class State {
+    // Ready to start decoding a new frame's header.
+    kStartDecodingHeader,
+    // Was in state kStartDecodingHeader, but unable to read the entire frame
+    // header, so needs more input to complete decoding the header.
+    kResumeDecodingHeader,
+
+    // Have decoded the frame header, and started decoding the available bytes
+    // of the frame's payload, but need more bytes to finish the job.
+    kResumeDecodingPayload,
+
+    // Decoding of the most recently started frame resulted in an error:
+    // OnPaddingTooLong or OnFrameSizeError was called to indicate that the
+    // decoder detected a problem, or OnFrameHeader returned false, indicating
+    // that the listener detected a problem. Regardless of which, the decoder
+    // will stay in state kDiscardPayload until it has been passed the rest
+    // of the bytes of the frame's payload that it hasn't yet seen, after
+    // which it will be ready to decode another frame.
+    kDiscardPayload,
+  };
+
+  friend class test::Http2FrameDecoderPeer;
+  QUICHE_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& out,
+                                                        State v);
+
+  DecodeStatus StartDecodingPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingPayload(DecodeBuffer* db);
+  DecodeStatus DiscardPayload(DecodeBuffer* db);
+
+  const Http2FrameHeader& frame_header() const {
+    return frame_decoder_state_.frame_header();
+  }
+
+  // Clear any of the flags in the frame header that aren't set in valid_flags.
+  void RetainFlags(uint8_t valid_flags);
+
+  // Clear all of the flags in the frame header; for use with frame types that
+  // don't define any flags, such as WINDOW_UPDATE.
+  void ClearFlags();
+
+  // These methods call the StartDecodingPayload() method of the frame type's
+  // payload decoder, after first clearing invalid flags in the header. The
+  // caller must ensure that the decode buffer does not extend beyond the
+  // end of the payload (handled by Http2FrameDecoder::StartDecodingPayload).
+  DecodeStatus StartDecodingAltSvcPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingContinuationPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingDataPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingGoAwayPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingHeadersPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingPingPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingPriorityPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingPriorityUpdatePayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingPushPromisePayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingRstStreamPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingSettingsPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingUnknownPayload(DecodeBuffer* db);
+  DecodeStatus StartDecodingWindowUpdatePayload(DecodeBuffer* db);
+
+  // These methods call the ResumeDecodingPayload() method of the frame type's
+  // payload decoder; they are called only if the preceding call to the
+  // corresponding Start method (above) returned kDecodeInProgress, as did any
+  // subsequent calls to the resume method.
+  // Unlike the Start methods, the decode buffer may extend beyond the
+  // end of the payload, so the method will create a DecodeBufferSubset
+  // before calling the ResumeDecodingPayload method of the frame type's
+  // payload decoder.
+  DecodeStatus ResumeDecodingAltSvcPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingContinuationPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingDataPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingGoAwayPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingHeadersPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingPingPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingPriorityPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingPriorityUpdatePayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingPushPromisePayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingRstStreamPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingSettingsPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingUnknownPayload(DecodeBuffer* db);
+  DecodeStatus ResumeDecodingWindowUpdatePayload(DecodeBuffer* db);
+
+  FrameDecoderState frame_decoder_state_;
+
+  // We only need one payload decoder at a time, so they share the same storage.
+  union {
+    AltSvcPayloadDecoder altsvc_payload_decoder_;
+    ContinuationPayloadDecoder continuation_payload_decoder_;
+    DataPayloadDecoder data_payload_decoder_;
+    GoAwayPayloadDecoder goaway_payload_decoder_;
+    HeadersPayloadDecoder headers_payload_decoder_;
+    PingPayloadDecoder ping_payload_decoder_;
+    PriorityPayloadDecoder priority_payload_decoder_;
+    PriorityUpdatePayloadDecoder priority_payload_update_decoder_;
+    PushPromisePayloadDecoder push_promise_payload_decoder_;
+    RstStreamPayloadDecoder rst_stream_payload_decoder_;
+    SettingsPayloadDecoder settings_payload_decoder_;
+    UnknownPayloadDecoder unknown_payload_decoder_;
+    WindowUpdatePayloadDecoder window_update_payload_decoder_;
+  };
+
+  State state_;
+  size_t maximum_payload_size_;
+
+  // Listener used whenever caller passes nullptr to set_listener.
+  Http2FrameDecoderNoOpListener no_op_listener_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_H_
diff --git a/quiche/http2/decoder/http2_frame_decoder_listener.cc b/quiche/http2/decoder/http2_frame_decoder_listener.cc
new file mode 100644
index 0000000..76f19da
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder_listener.cc
@@ -0,0 +1,14 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+
+namespace http2 {
+
+bool Http2FrameDecoderNoOpListener::OnFrameHeader(
+    const Http2FrameHeader& /*header*/) {
+  return true;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_frame_decoder_listener.h b/quiche/http2/decoder/http2_frame_decoder_listener.h
new file mode 100644
index 0000000..ad6bc5f
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder_listener.h
@@ -0,0 +1,384 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_
+#define QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_
+
+// Http2FrameDecoderListener is the interface which the HTTP/2 decoder uses
+// to report the decoded frames to a listener.
+//
+// The general design is to assume that the listener will copy the data it needs
+// (e.g. frame headers) and will keep track of the implicit state of the
+// decoding process (i.e. the decoder maintains just the information it needs in
+// order to perform the decoding). Therefore, the parameters are just those with
+// (potentially) new data, not previously provided info about the current frame.
+//
+// The calls are described as if they are made in quick succession, i.e. one
+// after another, but of course the decoder needs input to decode, and the
+// decoder will only call the listener once the necessary input has been
+// provided. For example: OnDataStart can only be called once the 9 bytes of
+// of an HTTP/2 common frame header have been received. The decoder will call
+// the listener methods as soon as possible to avoid almost all buffering.
+//
+// The listener interface is designed so that it is possible to exactly
+// reconstruct the serialized frames, with the exception of reserved bits,
+// including in the frame header's flags and stream_id fields, which will have
+// been cleared before the methods below are called.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <type_traits>
+
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+
+namespace http2 {
+
+// TODO(jamessynge): Consider sorting the methods by frequency of call, if that
+// helps at all.
+class Http2FrameDecoderListener {
+ public:
+  Http2FrameDecoderListener() {}
+  virtual ~Http2FrameDecoderListener() {}
+
+  // Called once the common frame header has been decoded for any frame, and
+  // before any of the methods below, which will also be called. This method is
+  // included in this interface only for the purpose of supporting SpdyFramer
+  // semantics via an adapter. This is the only method that has a non-void
+  // return type, and this is just so that Http2FrameDecoderAdapter (called
+  // from SpdyFramer) can more readily pass existing tests that expect decoding
+  // to stop if the headers alone indicate an error. Return false to stop
+  // decoding just after decoding the header, else return true to continue
+  // decoding.
+  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
+  // SpdyFramer's exact states.
+  virtual bool OnFrameHeader(const Http2FrameHeader& header) = 0;
+
+  //////////////////////////////////////////////////////////////////////////////
+
+  // Called once the common frame header has been decoded for a DATA frame,
+  // before examining the frame's payload, after which:
+  //   OnPadLength will be called if header.IsPadded() is true, i.e. if the
+  //     PADDED flag is set;
+  //   OnDataPayload will be called as the non-padding portion of the payload
+  //     is available until all of it has been provided;
+  //   OnPadding will be called if the frame is padded AND the Pad Length field
+  //     is greater than zero;
+  //   OnDataEnd will be called last. If the frame is unpadded and has no
+  //     payload, then this will be called immediately after OnDataStart.
+  virtual void OnDataStart(const Http2FrameHeader& header) = 0;
+
+  // Called when the next non-padding portion of a DATA frame's payload is
+  // received.
+  // |data| The start of |len| bytes of data.
+  // |len| The length of the data buffer. Maybe zero in some cases, which does
+  //       not mean anything special.
+  virtual void OnDataPayload(const char* data, size_t len) = 0;
+
+  // Called after an entire DATA frame has been received.
+  // If header.IsEndStream() == true, this is the last data for the stream.
+  virtual void OnDataEnd() = 0;
+
+  // Called once the common frame header has been decoded for a HEADERS frame,
+  // before examining the frame's payload, after which:
+  //   OnPadLength will be called if header.IsPadded() is true, i.e. if the
+  //     PADDED flag is set;
+  //   OnHeadersPriority will be called if header.HasPriority() is true, i.e. if
+  //     the frame has the PRIORITY flag;
+  //   OnHpackFragment as the remainder of the non-padding payload is available
+  //     until all if has been provided;
+  //   OnPadding will be called if the frame is padded AND the Pad Length field
+  //     is greater than zero;
+  //   OnHeadersEnd will be called last; If the frame is unpadded and has no
+  //     payload, then this will be called immediately after OnHeadersStart;
+  //     OnHeadersEnd indicates the end of the HPACK block only if the frame
+  //     header had the END_HEADERS flag set, else the END_HEADERS should be
+  //     looked for on a subsequent CONTINUATION frame.
+  virtual void OnHeadersStart(const Http2FrameHeader& header) = 0;
+
+  // Called when a HEADERS frame is received with the PRIORITY flag set and
+  // the priority fields have been decoded.
+  virtual void OnHeadersPriority(
+      const Http2PriorityFields& priority_fields) = 0;
+
+  // Called when a fragment (i.e. some or all of an HPACK Block) is received;
+  // this may be part of a HEADERS, PUSH_PROMISE or CONTINUATION frame.
+  // |data| The start of |len| bytes of data.
+  // |len| The length of the data buffer. Maybe zero in some cases, which does
+  //       not mean anything special, except that it simplified the decoder.
+  virtual void OnHpackFragment(const char* data, size_t len) = 0;
+
+  // Called after an entire HEADERS frame has been received. The frame is the
+  // end of the HEADERS if the END_HEADERS flag is set; else there should be
+  // CONTINUATION frames after this frame.
+  virtual void OnHeadersEnd() = 0;
+
+  // Called when an entire PRIORITY frame has been decoded.
+  virtual void OnPriorityFrame(const Http2FrameHeader& header,
+                               const Http2PriorityFields& priority_fields) = 0;
+
+  // Called once the common frame header has been decoded for a CONTINUATION
+  // frame, before examining the frame's payload, after which:
+  //   OnHpackFragment as the frame's payload is available until all of it
+  //     has been provided;
+  //   OnContinuationEnd will be called last; If the frame has no payload,
+  //     then this will be called immediately after OnContinuationStart;
+  //     the HPACK block is at an end if and only if the frame header passed
+  //     to OnContinuationStart had the END_HEADERS flag set.
+  virtual void OnContinuationStart(const Http2FrameHeader& header) = 0;
+
+  // Called after an entire CONTINUATION frame has been received. The frame is
+  // the end of the HEADERS if the END_HEADERS flag is set.
+  virtual void OnContinuationEnd() = 0;
+
+  // Called when Pad Length field has been read. Applies to DATA and HEADERS
+  // frames. For PUSH_PROMISE frames, the Pad Length + 1 is provided in the
+  // OnPushPromiseStart call as total_padding_length.
+  virtual void OnPadLength(size_t pad_length) = 0;
+
+  // Called when padding is skipped over.
+  virtual void OnPadding(const char* padding, size_t skipped_length) = 0;
+
+  // Called when an entire RST_STREAM frame has been decoded.
+  // This is the only callback for RST_STREAM frames.
+  virtual void OnRstStream(const Http2FrameHeader& header,
+                           Http2ErrorCode error_code) = 0;
+
+  // Called once the common frame header has been decoded for a SETTINGS frame
+  // without the ACK flag, before examining the frame's payload, after which:
+  //   OnSetting will be called in turn for each pair of settings parameter and
+  //     value found in the payload;
+  //   OnSettingsEnd will be called last; If the frame has no payload,
+  //     then this will be called immediately after OnSettingsStart.
+  // The frame header is passed so that the caller can check the stream_id,
+  // which should be zero, but that hasn't been checked by the decoder.
+  virtual void OnSettingsStart(const Http2FrameHeader& header) = 0;
+
+  // Called for each setting parameter and value within a SETTINGS frame.
+  virtual void OnSetting(const Http2SettingFields& setting_fields) = 0;
+
+  // Called after parsing the complete payload of SETTINGS frame (non-ACK).
+  virtual void OnSettingsEnd() = 0;
+
+  // Called when an entire SETTINGS frame, with the ACK flag, has been decoded.
+  virtual void OnSettingsAck(const Http2FrameHeader& header) = 0;
+
+  // Called just before starting to process the HPACK block of a PUSH_PROMISE
+  // frame. The Pad Length field has already been decoded at this point, so
+  // OnPadLength will not be called; note that total_padding_length is Pad
+  // Length + 1. After OnPushPromiseStart:
+  //   OnHpackFragment as the remainder of the non-padding payload is available
+  //     until all if has been provided;
+  //   OnPadding will be called if the frame is padded AND the Pad Length field
+  //     is greater than zero (i.e. total_padding_length > 1);
+  //   OnPushPromiseEnd will be called last; If the frame is unpadded and has no
+  //     payload, then this will be called immediately after OnPushPromiseStart.
+  virtual void OnPushPromiseStart(const Http2FrameHeader& header,
+                                  const Http2PushPromiseFields& promise,
+                                  size_t total_padding_length) = 0;
+
+  // Called after all of the HPACK block fragment and padding of a PUSH_PROMISE
+  // has been decoded and delivered to the listener. This call indicates the end
+  // of the HPACK block if and only if the frame header had the END_HEADERS flag
+  // set (i.e. header.IsEndHeaders() is true); otherwise the next block must be
+  // a CONTINUATION frame with the same stream id (not the same promised stream
+  // id).
+  virtual void OnPushPromiseEnd() = 0;
+
+  // Called when an entire PING frame, without the ACK flag, has been decoded.
+  virtual void OnPing(const Http2FrameHeader& header,
+                      const Http2PingFields& ping) = 0;
+
+  // Called when an entire PING frame, with the ACK flag, has been decoded.
+  virtual void OnPingAck(const Http2FrameHeader& header,
+                         const Http2PingFields& ping) = 0;
+
+  // Called after parsing a GOAWAY frame's header and fixed size fields, after
+  // which:
+  //   OnGoAwayOpaqueData will be called as opaque data of the payload becomes
+  //     available to the decoder, until all of it has been provided to the
+  //     listener;
+  //   OnGoAwayEnd will be called last, after all the opaque data has been
+  //     provided to the listener; if there is no opaque data, then OnGoAwayEnd
+  //     will be called immediately after OnGoAwayStart.
+  virtual void OnGoAwayStart(const Http2FrameHeader& header,
+                             const Http2GoAwayFields& goaway) = 0;
+
+  // Called when the next portion of a GOAWAY frame's payload is received.
+  // |data| The start of |len| bytes of opaque data.
+  // |len| The length of the opaque data buffer. Maybe zero in some cases,
+  //       which does not mean anything special.
+  virtual void OnGoAwayOpaqueData(const char* data, size_t len) = 0;
+
+  // Called after finishing decoding all of a GOAWAY frame.
+  virtual void OnGoAwayEnd() = 0;
+
+  // Called when an entire WINDOW_UPDATE frame has been decoded. The
+  // window_size_increment is required to be non-zero, but that has not been
+  // checked. If header.stream_id==0, the connection's flow control window is
+  // being increased, else the specified stream's flow control is being
+  // increased.
+  virtual void OnWindowUpdate(const Http2FrameHeader& header,
+                              uint32_t window_size_increment) = 0;
+
+  // Called when an ALTSVC frame header and origin length have been parsed.
+  // Either or both lengths may be zero. After OnAltSvcStart:
+  //   OnAltSvcOriginData will be called until all of the (optional) Origin
+  //     has been provided;
+  //   OnAltSvcValueData will be called until all of the Alt-Svc-Field-Value
+  //     has been provided;
+  //   OnAltSvcEnd will called last, after all of the origin and
+  //     Alt-Svc-Field-Value have been delivered to the listener.
+  virtual void OnAltSvcStart(const Http2FrameHeader& header,
+                             size_t origin_length,
+                             size_t value_length) = 0;
+
+  // Called when decoding the (optional) origin of an ALTSVC;
+  // the field is uninterpreted.
+  virtual void OnAltSvcOriginData(const char* data, size_t len) = 0;
+
+  // Called when decoding the Alt-Svc-Field-Value of an ALTSVC;
+  // the field is uninterpreted.
+  virtual void OnAltSvcValueData(const char* data, size_t len) = 0;
+
+  // Called after decoding all of a ALTSVC frame and providing to the listener
+  // via the above methods.
+  virtual void OnAltSvcEnd() = 0;
+
+  // Called when an PRIORITY_UPDATE frame header and Prioritized Stream ID have
+  // been parsed.  Afterwards:
+  //   OnPriorityUpdatePayload will be called each time a portion of the
+  //     Priority Field Value field is available until all of it has been
+  //     provided;
+  //   OnPriorityUpdateEnd will be called last. If the frame has an empty
+  //     Priority Field Value, then this will be called immediately after
+  //     OnPriorityUpdateStart.
+  virtual void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) = 0;
+
+  // Called when the next portion of a PRIORITY_UPDATE frame's Priority Field
+  // Value field is received.
+  // |data| The start of |len| bytes of data.
+  // |len| The length of the data buffer. May be zero in some cases, which does
+  //     not mean anything special.
+  virtual void OnPriorityUpdatePayload(const char* data, size_t len) = 0;
+
+  // Called after an entire PRIORITY_UPDATE frame has been received.
+  virtual void OnPriorityUpdateEnd() = 0;
+
+  // Called when the common frame header has been decoded, but the frame type
+  // is unknown, after which:
+  //   OnUnknownPayload is called as the payload of the frame is provided to the
+  //     decoder, until all of the payload has been decoded;
+  //   OnUnknownEnd will called last, after the entire frame of the unknown type
+  //     has been decoded and provided to the listener.
+  virtual void OnUnknownStart(const Http2FrameHeader& header) = 0;
+
+  // Called when the payload of an unknown frame type is received.
+  // |data| A buffer containing the data received.
+  // |len| The length of the data buffer.
+  virtual void OnUnknownPayload(const char* data, size_t len) = 0;
+
+  // Called after decoding all of the payload of an unknown frame type.
+  virtual void OnUnknownEnd() = 0;
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Below here are events indicating a problem has been detected during
+  // decoding (i.e. the received frames are malformed in some way).
+
+  // Padding field (uint8) has a value that is too large (i.e. the amount of
+  // padding is greater than the remainder of the payload that isn't required).
+  // From RFC Section 6.1, DATA:
+  //     If the length of the padding is the length of the frame payload or
+  //     greater, the recipient MUST treat this as a connection error
+  //     (Section 5.4.1) of type PROTOCOL_ERROR.
+  // The same is true for HEADERS and PUSH_PROMISE.
+  virtual void OnPaddingTooLong(const Http2FrameHeader& header,
+                                size_t missing_length) = 0;
+
+  // Frame size error. Depending upon the effected frame, this may or may not
+  // require terminating the connection, though that is probably the best thing
+  // to do.
+  // From RFC Section 4.2, Frame Size:
+  //     An endpoint MUST send an error code of FRAME_SIZE_ERROR if a frame
+  //     exceeds the size defined in SETTINGS_MAX_FRAME_SIZE, exceeds any limit
+  //     defined for the frame type, or is too small to contain mandatory frame
+  //     data. A frame size error in a frame that could alter the state of the
+  //     the entire connection MUST be treated as a connection error
+  //     (Section 5.4.1); this includes any frame carrying a header block
+  //     (Section 4.3) (that is, HEADERS, PUSH_PROMISE, and CONTINUATION),
+  //     SETTINGS, and any frame with a stream identifier of 0.
+  virtual void OnFrameSizeError(const Http2FrameHeader& header) = 0;
+};
+
+// Do nothing for each call. Useful for ignoring a frame that is invalid.
+class Http2FrameDecoderNoOpListener : public Http2FrameDecoderListener {
+ public:
+  Http2FrameDecoderNoOpListener() {}
+  ~Http2FrameDecoderNoOpListener() override {}
+
+  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
+  // SpdyFramer's exact states.
+  bool OnFrameHeader(const Http2FrameHeader& header) override;
+
+  void OnDataStart(const Http2FrameHeader& /*header*/) override {}
+  void OnDataPayload(const char* /*data*/, size_t /*len*/) override {}
+  void OnDataEnd() override {}
+  void OnHeadersStart(const Http2FrameHeader& /*header*/) override {}
+  void OnHeadersPriority(const Http2PriorityFields& /*priority*/) override {}
+  void OnHpackFragment(const char* /*data*/, size_t /*len*/) override {}
+  void OnHeadersEnd() override {}
+  void OnPriorityFrame(const Http2FrameHeader& /*header*/,
+                       const Http2PriorityFields& /*priority*/) override {}
+  void OnContinuationStart(const Http2FrameHeader& /*header*/) override {}
+  void OnContinuationEnd() override {}
+  void OnPadLength(size_t /*trailing_length*/) override {}
+  void OnPadding(const char* /*padding*/, size_t /*skipped_length*/) override {}
+  void OnRstStream(const Http2FrameHeader& /*header*/,
+                   Http2ErrorCode /*error_code*/) override {}
+  void OnSettingsStart(const Http2FrameHeader& /*header*/) override {}
+  void OnSetting(const Http2SettingFields& /*setting_fields*/) override {}
+  void OnSettingsEnd() override {}
+  void OnSettingsAck(const Http2FrameHeader& /*header*/) override {}
+  void OnPushPromiseStart(const Http2FrameHeader& /*header*/,
+                          const Http2PushPromiseFields& /*promise*/,
+                          size_t /*total_padding_length*/) override {}
+  void OnPushPromiseEnd() override {}
+  void OnPing(const Http2FrameHeader& /*header*/,
+              const Http2PingFields& /*ping*/) override {}
+  void OnPingAck(const Http2FrameHeader& /*header*/,
+                 const Http2PingFields& /*ping*/) override {}
+  void OnGoAwayStart(const Http2FrameHeader& /*header*/,
+                     const Http2GoAwayFields& /*goaway*/) override {}
+  void OnGoAwayOpaqueData(const char* /*data*/, size_t /*len*/) override {}
+  void OnGoAwayEnd() override {}
+  void OnWindowUpdate(const Http2FrameHeader& /*header*/,
+                      uint32_t /*increment*/) override {}
+  void OnAltSvcStart(const Http2FrameHeader& /*header*/,
+                     size_t /*origin_length*/,
+                     size_t /*value_length*/) override {}
+  void OnAltSvcOriginData(const char* /*data*/, size_t /*len*/) override {}
+  void OnAltSvcValueData(const char* /*data*/, size_t /*len*/) override {}
+  void OnAltSvcEnd() override {}
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& /*header*/,
+      const Http2PriorityUpdateFields& /*priority_update*/) override {}
+  void OnPriorityUpdatePayload(const char* /*data*/, size_t /*len*/) override {}
+  void OnPriorityUpdateEnd() override {}
+  void OnUnknownStart(const Http2FrameHeader& /*header*/) override {}
+  void OnUnknownPayload(const char* /*data*/, size_t /*len*/) override {}
+  void OnUnknownEnd() override {}
+  void OnPaddingTooLong(const Http2FrameHeader& /*header*/,
+                        size_t /*missing_length*/) override {}
+  void OnFrameSizeError(const Http2FrameHeader& /*header*/) override {}
+};
+
+static_assert(!std::is_abstract<Http2FrameDecoderNoOpListener>(),
+              "Http2FrameDecoderNoOpListener ought to be concrete.");
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_
diff --git a/quiche/http2/decoder/http2_frame_decoder_listener_test_util.cc b/quiche/http2/decoder/http2_frame_decoder_listener_test_util.cc
new file mode 100644
index 0000000..a0b7ea8
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder_listener_test_util.cc
@@ -0,0 +1,530 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener_test_util.h"
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+
+FailingHttp2FrameDecoderListener::FailingHttp2FrameDecoderListener() = default;
+FailingHttp2FrameDecoderListener::~FailingHttp2FrameDecoderListener() = default;
+
+bool FailingHttp2FrameDecoderListener::OnFrameHeader(
+    const Http2FrameHeader& header) {
+  ADD_FAILURE() << "OnFrameHeader: " << header;
+  return false;
+}
+
+void FailingHttp2FrameDecoderListener::OnDataStart(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnDataStart: " << header;
+}
+
+void FailingHttp2FrameDecoderListener::OnDataPayload(const char* /*data*/,
+                                                     size_t len) {
+  FAIL() << "OnDataPayload: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnDataEnd() {
+  FAIL() << "OnDataEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnHeadersStart(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnHeadersStart: " << header;
+}
+
+void FailingHttp2FrameDecoderListener::OnHeadersPriority(
+    const Http2PriorityFields& priority) {
+  FAIL() << "OnHeadersPriority: " << priority;
+}
+
+void FailingHttp2FrameDecoderListener::OnHpackFragment(const char* /*data*/,
+                                                       size_t len) {
+  FAIL() << "OnHpackFragment: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnHeadersEnd() {
+  FAIL() << "OnHeadersEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnPriorityFrame(
+    const Http2FrameHeader& header,
+    const Http2PriorityFields& priority) {
+  FAIL() << "OnPriorityFrame: " << header << "; priority: " << priority;
+}
+
+void FailingHttp2FrameDecoderListener::OnContinuationStart(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnContinuationStart: " << header;
+}
+
+void FailingHttp2FrameDecoderListener::OnContinuationEnd() {
+  FAIL() << "OnContinuationEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnPadLength(size_t trailing_length) {
+  FAIL() << "OnPadLength: trailing_length=" << trailing_length;
+}
+
+void FailingHttp2FrameDecoderListener::OnPadding(const char* /*padding*/,
+                                                 size_t skipped_length) {
+  FAIL() << "OnPadding: skipped_length=" << skipped_length;
+}
+
+void FailingHttp2FrameDecoderListener::OnRstStream(
+    const Http2FrameHeader& header,
+    Http2ErrorCode error_code) {
+  FAIL() << "OnRstStream: " << header << "; code=" << error_code;
+}
+
+void FailingHttp2FrameDecoderListener::OnSettingsStart(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnSettingsStart: " << header;
+}
+
+void FailingHttp2FrameDecoderListener::OnSetting(
+    const Http2SettingFields& setting_fields) {
+  FAIL() << "OnSetting: " << setting_fields;
+}
+
+void FailingHttp2FrameDecoderListener::OnSettingsEnd() {
+  FAIL() << "OnSettingsEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnSettingsAck(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnSettingsAck: " << header;
+}
+
+void FailingHttp2FrameDecoderListener::OnPushPromiseStart(
+    const Http2FrameHeader& header,
+    const Http2PushPromiseFields& promise,
+    size_t total_padding_length) {
+  FAIL() << "OnPushPromiseStart: " << header << "; promise: " << promise
+         << "; total_padding_length: " << total_padding_length;
+}
+
+void FailingHttp2FrameDecoderListener::OnPushPromiseEnd() {
+  FAIL() << "OnPushPromiseEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnPing(const Http2FrameHeader& header,
+                                              const Http2PingFields& ping) {
+  FAIL() << "OnPing: " << header << "; ping: " << ping;
+}
+
+void FailingHttp2FrameDecoderListener::OnPingAck(const Http2FrameHeader& header,
+                                                 const Http2PingFields& ping) {
+  FAIL() << "OnPingAck: " << header << "; ping: " << ping;
+}
+
+void FailingHttp2FrameDecoderListener::OnGoAwayStart(
+    const Http2FrameHeader& header,
+    const Http2GoAwayFields& goaway) {
+  FAIL() << "OnGoAwayStart: " << header << "; goaway: " << goaway;
+}
+
+void FailingHttp2FrameDecoderListener::OnGoAwayOpaqueData(const char* /*data*/,
+                                                          size_t len) {
+  FAIL() << "OnGoAwayOpaqueData: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnGoAwayEnd() {
+  FAIL() << "OnGoAwayEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnWindowUpdate(
+    const Http2FrameHeader& header,
+    uint32_t increment) {
+  FAIL() << "OnWindowUpdate: " << header << "; increment=" << increment;
+}
+
+void FailingHttp2FrameDecoderListener::OnAltSvcStart(
+    const Http2FrameHeader& header,
+    size_t origin_length,
+    size_t value_length) {
+  FAIL() << "OnAltSvcStart: " << header << "; origin_length: " << origin_length
+         << "; value_length: " << value_length;
+}
+
+void FailingHttp2FrameDecoderListener::OnAltSvcOriginData(const char* /*data*/,
+                                                          size_t len) {
+  FAIL() << "OnAltSvcOriginData: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnAltSvcValueData(const char* /*data*/,
+                                                         size_t len) {
+  FAIL() << "OnAltSvcValueData: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnAltSvcEnd() {
+  FAIL() << "OnAltSvcEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnPriorityUpdateStart(
+    const Http2FrameHeader& header,
+    const Http2PriorityUpdateFields& priority_update) {
+  FAIL() << "OnPriorityUpdateStart: " << header << "; prioritized_stream_id: "
+         << priority_update.prioritized_stream_id;
+}
+
+void FailingHttp2FrameDecoderListener::OnPriorityUpdatePayload(
+    const char* /*data*/,
+    size_t len) {
+  FAIL() << "OnPriorityUpdatePayload: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnPriorityUpdateEnd() {
+  FAIL() << "OnPriorityUpdateEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnUnknownStart(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnUnknownStart: " << header;
+}
+
+void FailingHttp2FrameDecoderListener::OnUnknownPayload(const char* /*data*/,
+                                                        size_t len) {
+  FAIL() << "OnUnknownPayload: len=" << len;
+}
+
+void FailingHttp2FrameDecoderListener::OnUnknownEnd() {
+  FAIL() << "OnUnknownEnd";
+}
+
+void FailingHttp2FrameDecoderListener::OnPaddingTooLong(
+    const Http2FrameHeader& header,
+    size_t missing_length) {
+  FAIL() << "OnPaddingTooLong: " << header
+         << "; missing_length: " << missing_length;
+}
+
+void FailingHttp2FrameDecoderListener::OnFrameSizeError(
+    const Http2FrameHeader& header) {
+  FAIL() << "OnFrameSizeError: " << header;
+}
+
+LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener()
+    : wrapped_(nullptr) {}
+LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener(
+    Http2FrameDecoderListener* wrapped)
+    : wrapped_(wrapped) {}
+LoggingHttp2FrameDecoderListener::~LoggingHttp2FrameDecoderListener() = default;
+
+bool LoggingHttp2FrameDecoderListener::OnFrameHeader(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnFrameHeader: " << header;
+  if (wrapped_ != nullptr) {
+    return wrapped_->OnFrameHeader(header);
+  }
+  return true;
+}
+
+void LoggingHttp2FrameDecoderListener::OnDataStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnDataStart: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnDataStart(header);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnDataPayload(const char* data,
+                                                     size_t len) {
+  HTTP2_VLOG(1) << "OnDataPayload: len=" << len;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnDataPayload(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnDataEnd() {
+  HTTP2_VLOG(1) << "OnDataEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnDataEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnHeadersStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeadersStart(header);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnHeadersPriority(
+    const Http2PriorityFields& priority) {
+  HTTP2_VLOG(1) << "OnHeadersPriority: " << priority;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeadersPriority(priority);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnHpackFragment(const char* data,
+                                                       size_t len) {
+  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHpackFragment(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnHeadersEnd() {
+  HTTP2_VLOG(1) << "OnHeadersEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeadersEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPriorityFrame(
+    const Http2FrameHeader& header,
+    const Http2PriorityFields& priority) {
+  HTTP2_VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPriorityFrame(header, priority);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnContinuationStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnContinuationStart(header);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnContinuationEnd() {
+  HTTP2_VLOG(1) << "OnContinuationEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnContinuationEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPadLength(size_t trailing_length) {
+  HTTP2_VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPadLength(trailing_length);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPadding(const char* padding,
+                                                 size_t skipped_length) {
+  HTTP2_VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPadding(padding, skipped_length);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnRstStream(
+    const Http2FrameHeader& header,
+    Http2ErrorCode error_code) {
+  HTTP2_VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnRstStream(header, error_code);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnSettingsStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnSettingsStart(header);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnSetting(
+    const Http2SettingFields& setting_fields) {
+  HTTP2_VLOG(1) << "OnSetting: " << setting_fields;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnSetting(setting_fields);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnSettingsEnd() {
+  HTTP2_VLOG(1) << "OnSettingsEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnSettingsEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnSettingsAck(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnSettingsAck(header);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPushPromiseStart(
+    const Http2FrameHeader& header,
+    const Http2PushPromiseFields& promise,
+    size_t total_padding_length) {
+  HTTP2_VLOG(1) << "OnPushPromiseStart: " << header << "; promise: " << promise
+                << "; total_padding_length: " << total_padding_length;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPushPromiseStart(header, promise, total_padding_length);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPushPromiseEnd() {
+  HTTP2_VLOG(1) << "OnPushPromiseEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPushPromiseEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPing(const Http2FrameHeader& header,
+                                              const Http2PingFields& ping) {
+  HTTP2_VLOG(1) << "OnPing: " << header << "; ping: " << ping;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPing(header, ping);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPingAck(const Http2FrameHeader& header,
+                                                 const Http2PingFields& ping) {
+  HTTP2_VLOG(1) << "OnPingAck: " << header << "; ping: " << ping;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPingAck(header, ping);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnGoAwayStart(
+    const Http2FrameHeader& header,
+    const Http2GoAwayFields& goaway) {
+  HTTP2_VLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnGoAwayStart(header, goaway);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnGoAwayOpaqueData(const char* data,
+                                                          size_t len) {
+  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnGoAwayOpaqueData(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnGoAwayEnd() {
+  HTTP2_VLOG(1) << "OnGoAwayEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnGoAwayEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnWindowUpdate(
+    const Http2FrameHeader& header,
+    uint32_t increment) {
+  HTTP2_VLOG(1) << "OnWindowUpdate: " << header << "; increment=" << increment;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnWindowUpdate(header, increment);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnAltSvcStart(
+    const Http2FrameHeader& header,
+    size_t origin_length,
+    size_t value_length) {
+  HTTP2_VLOG(1) << "OnAltSvcStart: " << header
+                << "; origin_length: " << origin_length
+                << "; value_length: " << value_length;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnAltSvcStart(header, origin_length, value_length);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnAltSvcOriginData(const char* data,
+                                                          size_t len) {
+  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnAltSvcOriginData(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnAltSvcValueData(const char* data,
+                                                         size_t len) {
+  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnAltSvcValueData(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnAltSvcEnd() {
+  HTTP2_VLOG(1) << "OnAltSvcEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnAltSvcEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPriorityUpdateStart(
+    const Http2FrameHeader& header,
+    const Http2PriorityUpdateFields& priority_update) {
+  HTTP2_VLOG(1) << "OnPriorityUpdateStart";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPriorityUpdateStart(header, priority_update);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPriorityUpdatePayload(const char* data,
+                                                               size_t len) {
+  HTTP2_VLOG(1) << "OnPriorityUpdatePayload";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPriorityUpdatePayload(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPriorityUpdateEnd() {
+  HTTP2_VLOG(1) << "OnPriorityUpdateEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPriorityUpdateEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnUnknownStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnUnknownStart(header);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnUnknownPayload(const char* data,
+                                                        size_t len) {
+  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnUnknownPayload(data, len);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnUnknownEnd() {
+  HTTP2_VLOG(1) << "OnUnknownEnd";
+  if (wrapped_ != nullptr) {
+    wrapped_->OnUnknownEnd();
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnPaddingTooLong(
+    const Http2FrameHeader& header,
+    size_t missing_length) {
+  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
+                << "; missing_length: " << missing_length;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnPaddingTooLong(header, missing_length);
+  }
+}
+
+void LoggingHttp2FrameDecoderListener::OnFrameSizeError(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnFrameSizeError(header);
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_frame_decoder_listener_test_util.h b/quiche/http2/decoder/http2_frame_decoder_listener_test_util.h
new file mode 100644
index 0000000..a109d1d
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder_listener_test_util.h
@@ -0,0 +1,153 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_TEST_UTIL_H_
+#define QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_TEST_UTIL_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+
+namespace http2 {
+
+// Fail if any of the methods are called. Allows a test to override only the
+// expected calls.
+class FailingHttp2FrameDecoderListener : public Http2FrameDecoderListener {
+ public:
+  FailingHttp2FrameDecoderListener();
+  ~FailingHttp2FrameDecoderListener() override;
+
+  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
+  // SpdyFramer's exact states.
+  bool OnFrameHeader(const Http2FrameHeader& header) override;
+  void OnDataStart(const Http2FrameHeader& header) override;
+  void OnDataPayload(const char* data, size_t len) override;
+  void OnDataEnd() override;
+  void OnHeadersStart(const Http2FrameHeader& header) override;
+  void OnHeadersPriority(const Http2PriorityFields& priority) override;
+  void OnHpackFragment(const char* data, size_t len) override;
+  void OnHeadersEnd() override;
+  void OnPriorityFrame(const Http2FrameHeader& header,
+                       const Http2PriorityFields& priority) override;
+  void OnContinuationStart(const Http2FrameHeader& header) override;
+  void OnContinuationEnd() override;
+  void OnPadLength(size_t trailing_length) override;
+  void OnPadding(const char* padding, size_t skipped_length) override;
+  void OnRstStream(const Http2FrameHeader& header,
+                   Http2ErrorCode error_code) override;
+  void OnSettingsStart(const Http2FrameHeader& header) override;
+  void OnSetting(const Http2SettingFields& setting_fields) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck(const Http2FrameHeader& header) override;
+  void OnPushPromiseStart(const Http2FrameHeader& header,
+                          const Http2PushPromiseFields& promise,
+                          size_t total_padding_length) override;
+  void OnPushPromiseEnd() override;
+  void OnPing(const Http2FrameHeader& header,
+              const Http2PingFields& ping) override;
+  void OnPingAck(const Http2FrameHeader& header,
+                 const Http2PingFields& ping) override;
+  void OnGoAwayStart(const Http2FrameHeader& header,
+                     const Http2GoAwayFields& goaway) override;
+  void OnGoAwayOpaqueData(const char* data, size_t len) override;
+  void OnGoAwayEnd() override;
+  void OnWindowUpdate(const Http2FrameHeader& header,
+                      uint32_t increment) override;
+  void OnAltSvcStart(const Http2FrameHeader& header,
+                     size_t origin_length,
+                     size_t value_length) override;
+  void OnAltSvcOriginData(const char* data, size_t len) override;
+  void OnAltSvcValueData(const char* data, size_t len) override;
+  void OnAltSvcEnd() override;
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) override;
+  void OnPriorityUpdatePayload(const char* data, size_t len) override;
+  void OnPriorityUpdateEnd() override;
+  void OnUnknownStart(const Http2FrameHeader& header) override;
+  void OnUnknownPayload(const char* data, size_t len) override;
+  void OnUnknownEnd() override;
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override;
+  void OnFrameSizeError(const Http2FrameHeader& header) override;
+
+ private:
+  void EnsureNotAbstract() { FailingHttp2FrameDecoderListener instance; }
+};
+
+// HTTP2_VLOG's all the calls it receives, and forwards those calls to an
+// optional listener.
+class LoggingHttp2FrameDecoderListener : public Http2FrameDecoderListener {
+ public:
+  LoggingHttp2FrameDecoderListener();
+  explicit LoggingHttp2FrameDecoderListener(Http2FrameDecoderListener* wrapped);
+  ~LoggingHttp2FrameDecoderListener() override;
+
+  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
+  // SpdyFramer's exact states.
+  bool OnFrameHeader(const Http2FrameHeader& header) override;
+  void OnDataStart(const Http2FrameHeader& header) override;
+  void OnDataPayload(const char* data, size_t len) override;
+  void OnDataEnd() override;
+  void OnHeadersStart(const Http2FrameHeader& header) override;
+  void OnHeadersPriority(const Http2PriorityFields& priority) override;
+  void OnHpackFragment(const char* data, size_t len) override;
+  void OnHeadersEnd() override;
+  void OnPriorityFrame(const Http2FrameHeader& header,
+                       const Http2PriorityFields& priority) override;
+  void OnContinuationStart(const Http2FrameHeader& header) override;
+  void OnContinuationEnd() override;
+  void OnPadLength(size_t trailing_length) override;
+  void OnPadding(const char* padding, size_t skipped_length) override;
+  void OnRstStream(const Http2FrameHeader& header,
+                   Http2ErrorCode error_code) override;
+  void OnSettingsStart(const Http2FrameHeader& header) override;
+  void OnSetting(const Http2SettingFields& setting_fields) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck(const Http2FrameHeader& header) override;
+  void OnPushPromiseStart(const Http2FrameHeader& header,
+                          const Http2PushPromiseFields& promise,
+                          size_t total_padding_length) override;
+  void OnPushPromiseEnd() override;
+  void OnPing(const Http2FrameHeader& header,
+              const Http2PingFields& ping) override;
+  void OnPingAck(const Http2FrameHeader& header,
+                 const Http2PingFields& ping) override;
+  void OnGoAwayStart(const Http2FrameHeader& header,
+                     const Http2GoAwayFields& goaway) override;
+  void OnGoAwayOpaqueData(const char* data, size_t len) override;
+  void OnGoAwayEnd() override;
+  void OnWindowUpdate(const Http2FrameHeader& header,
+                      uint32_t increment) override;
+  void OnAltSvcStart(const Http2FrameHeader& header,
+                     size_t origin_length,
+                     size_t value_length) override;
+  void OnAltSvcOriginData(const char* data, size_t len) override;
+  void OnAltSvcValueData(const char* data, size_t len) override;
+  void OnAltSvcEnd() override;
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) override;
+  void OnPriorityUpdatePayload(const char* data, size_t len) override;
+  void OnPriorityUpdateEnd() override;
+  void OnUnknownStart(const Http2FrameHeader& header) override;
+  void OnUnknownPayload(const char* data, size_t len) override;
+  void OnUnknownEnd() override;
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override;
+  void OnFrameSizeError(const Http2FrameHeader& header) override;
+
+ private:
+  void EnsureNotAbstract() { LoggingHttp2FrameDecoderListener instance; }
+
+  Http2FrameDecoderListener* wrapped_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_TEST_UTIL_H_
diff --git a/quiche/http2/decoder/http2_frame_decoder_test.cc b/quiche/http2/decoder/http2_frame_decoder_test.cc
new file mode 100644
index 0000000..8269500
--- /dev/null
+++ b/quiche/http2/decoder/http2_frame_decoder_test.cc
@@ -0,0 +1,924 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_frame_decoder.h"
+
+// Tests of Http2FrameDecoder.
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector_listener.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+class Http2FrameDecoderPeer {
+ public:
+  static size_t remaining_total_payload(Http2FrameDecoder* decoder) {
+    return decoder->frame_decoder_state_.remaining_total_payload();
+  }
+};
+
+namespace {
+
+class Http2FrameDecoderTest : public RandomDecoderTest {
+ protected:
+  DecodeStatus StartDecoding(DecodeBuffer* db) override {
+    HTTP2_DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining();
+    collector_.Reset();
+    PrepareDecoder();
+
+    DecodeStatus status = decoder_->DecodeFrame(db);
+    if (status != DecodeStatus::kDecodeInProgress) {
+      // Keep track of this so that a concrete test can verify that both fast
+      // and slow decoding paths have been tested.
+      ++fast_decode_count_;
+      if (status == DecodeStatus::kDecodeError) {
+        ConfirmDiscardsRemainingPayload();
+      }
+    }
+    return status;
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* db) override {
+    HTTP2_DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining();
+    DecodeStatus status = decoder_->DecodeFrame(db);
+    if (status != DecodeStatus::kDecodeInProgress) {
+      // Keep track of this so that a concrete test can verify that both fast
+      // and slow decoding paths have been tested.
+      ++slow_decode_count_;
+      if (status == DecodeStatus::kDecodeError) {
+        ConfirmDiscardsRemainingPayload();
+      }
+    }
+    return status;
+  }
+
+  // When an error is returned, the decoder is in state kDiscardPayload, and
+  // stays there until the remaining bytes of the frame's payload have been
+  // skipped over. There are no callbacks for this situation.
+  void ConfirmDiscardsRemainingPayload() {
+    ASSERT_TRUE(decoder_->IsDiscardingPayload());
+    size_t remaining =
+        Http2FrameDecoderPeer::remaining_total_payload(decoder_.get());
+    // The decoder will discard the remaining bytes, but not go beyond that,
+    // which these conditions verify.
+    size_t extra = 10;
+    std::string junk(remaining + extra, '0');
+    DecodeBuffer tmp(junk);
+    EXPECT_EQ(DecodeStatus::kDecodeDone, decoder_->DecodeFrame(&tmp));
+    EXPECT_EQ(remaining, tmp.Offset());
+    EXPECT_EQ(extra, tmp.Remaining());
+    EXPECT_FALSE(decoder_->IsDiscardingPayload());
+  }
+
+  void PrepareDecoder() {
+    decoder_ = std::make_unique<Http2FrameDecoder>(&collector_);
+    decoder_->set_maximum_payload_size(maximum_payload_size_);
+  }
+
+  void ResetDecodeSpeedCounters() {
+    fast_decode_count_ = 0;
+    slow_decode_count_ = 0;
+  }
+
+  AssertionResult VerifyCollected(const FrameParts& expected) {
+    VERIFY_FALSE(collector_.IsInProgress());
+    VERIFY_EQ(1u, collector_.size());
+    VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*collector_.frame(0)));
+  }
+
+  AssertionResult DecodePayloadAndValidateSeveralWays(absl::string_view payload,
+                                                      Validator validator) {
+    DecodeBuffer db(payload);
+    bool start_decoding_requires_non_empty = false;
+    return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty,
+                                        validator);
+  }
+
+  // Decode one frame's payload and confirm that the listener recorded the
+  // expected FrameParts instance, and only one FrameParts instance. The
+  // payload will be decoded several times with different partitionings
+  // of the payload, and after each the validator will be called.
+  AssertionResult DecodePayloadAndValidateSeveralWays(
+      absl::string_view payload,
+      const FrameParts& expected) {
+    auto validator = [&expected, this](const DecodeBuffer& /*input*/,
+                                       DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
+      VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
+    };
+    ResetDecodeSpeedCounters();
+    VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays(
+        payload, ValidateDoneAndEmpty(validator)));
+    VERIFY_GT(fast_decode_count_, 0u);
+    VERIFY_GT(slow_decode_count_, 0u);
+
+    // Repeat with more input; it should stop without reading that input.
+    std::string next_frame = Random().RandString(10);
+    std::string input(payload.data(), payload.size());
+    input += next_frame;
+
+    ResetDecodeSpeedCounters();
+    VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays(
+        payload, ValidateDoneAndOffset(payload.size(), validator)));
+    VERIFY_GT(fast_decode_count_, 0u);
+    VERIFY_GT(slow_decode_count_, 0u);
+
+    return AssertionSuccess();
+  }
+
+  template <size_t N>
+  AssertionResult DecodePayloadAndValidateSeveralWays(
+      const char (&buf)[N],
+      const FrameParts& expected) {
+    return DecodePayloadAndValidateSeveralWays(absl::string_view(buf, N),
+                                               expected);
+  }
+
+  template <size_t N>
+  AssertionResult DecodePayloadAndValidateSeveralWays(
+      const char (&buf)[N],
+      const Http2FrameHeader& header) {
+    return DecodePayloadAndValidateSeveralWays(absl::string_view(buf, N),
+                                               FrameParts(header));
+  }
+
+  template <size_t N>
+  AssertionResult DecodePayloadExpectingError(const char (&buf)[N],
+                                              const FrameParts& expected) {
+    auto validator = [&expected, this](const DecodeBuffer& /*input*/,
+                                       DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(status, DecodeStatus::kDecodeError);
+      VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
+    };
+    ResetDecodeSpeedCounters();
+    EXPECT_TRUE(
+        DecodePayloadAndValidateSeveralWays(ToStringPiece(buf), validator));
+    EXPECT_GT(fast_decode_count_, 0u);
+    EXPECT_GT(slow_decode_count_, 0u);
+    return AssertionSuccess();
+  }
+
+  template <size_t N>
+  AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N],
+                                                       FrameParts expected) {
+    expected.SetHasFrameSizeError(true);
+    VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected));
+  }
+
+  template <size_t N>
+  AssertionResult DecodePayloadExpectingFrameSizeError(
+      const char (&buf)[N],
+      const Http2FrameHeader& header) {
+    return DecodePayloadExpectingFrameSizeError(buf, FrameParts(header));
+  }
+
+  // Count of payloads that are fully decoded by StartDecodingPayload or for
+  // which an error was detected by StartDecodingPayload.
+  size_t fast_decode_count_ = 0;
+
+  // Count of payloads that required calling ResumeDecodingPayload in order to
+  // decode completely, or for which an error was detected by
+  // ResumeDecodingPayload.
+  size_t slow_decode_count_ = 0;
+
+  uint32_t maximum_payload_size_ = Http2SettingsInfo::DefaultMaxFrameSize();
+  FramePartsCollectorListener collector_;
+  std::unique_ptr<Http2FrameDecoder> decoder_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests that pass the minimum allowed size for the frame type, which is often
+// empty. The tests are in order by frame type value (i.e. 0 for DATA frames).
+
+TEST_F(Http2FrameDecoderTest, DataEmpty) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',  // Payload length: 0
+      '\x00',                  // DATA
+      '\x00',                  // Flags: none
+      '\x00', '\x00', '\x00',
+      '\x00',  // Stream ID: 0 (invalid but unchecked here)
+  };
+  Http2FrameHeader header(0, Http2FrameType::DATA, 0, 0);
+  FrameParts expected(header, "");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeadersEmpty) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',          // Payload length: 0
+      '\x01',                          // HEADERS
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 0  (REQUIRES ID)
+  };
+  Http2FrameHeader header(0, Http2FrameType::HEADERS, 0, 1);
+  FrameParts expected(header, "");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, Priority) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x05',          // Length: 5
+      '\x02',                          //   Type: PRIORITY
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream: 2
+      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
+      '\x10',                          // Weight: 17
+  };
+  Http2FrameHeader header(5, Http2FrameType::PRIORITY, 0, 2);
+  FrameParts expected(header);
+  expected.SetOptPriority(Http2PriorityFields(1, 17, true));
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, RstStream) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x04',          // Length: 4
+      '\x03',                          //   Type: RST_STREAM
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
+      '\x00', '\x00', '\x00', '\x01',  //  Error: PROTOCOL_ERROR
+  };
+  Http2FrameHeader header(4, Http2FrameType::RST_STREAM, 0, 1);
+  FrameParts expected(header);
+  expected.SetOptRstStreamErrorCode(Http2ErrorCode::PROTOCOL_ERROR);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, SettingsEmpty) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',          // Length: 0
+      '\x04',                          //   Type: SETTINGS
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1 (invalid but unchecked here)
+  };
+  Http2FrameHeader header(0, Http2FrameType::SETTINGS, 0, 1);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, SettingsAck) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',          //   Length: 6
+      '\x04',                          //     Type: SETTINGS
+      '\x01',                          //    Flags: ACK
+      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
+  };
+  Http2FrameHeader header(0, Http2FrameType::SETTINGS, Http2FrameFlag::ACK, 0);
+  FrameParts expected(header);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, PushPromiseMinimal) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x04',  // Payload length: 4
+      '\x05',                  // PUSH_PROMISE
+      '\x04',                  // Flags: END_HEADERS
+      '\x00', '\x00', '\x00',
+      '\x02',  //   Stream: 2 (invalid but unchecked here)
+      '\x00', '\x00', '\x00',
+      '\x01',  // Promised: 1 (invalid but unchecked here)
+  };
+  Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
+                          Http2FrameFlag::END_HEADERS, 2);
+  FrameParts expected(header, "");
+  expected.SetOptPushPromise(Http2PushPromiseFields{1});
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, Ping) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x08',          //   Length: 8
+      '\x06',                          //     Type: PING
+      '\xfe',                          //    Flags: no valid flags
+      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
+      's',    'o',    'm',    'e',     // "some"
+      'd',    'a',    't',    'a',     // "data"
+  };
+  Http2FrameHeader header(8, Http2FrameType::PING, 0, 0);
+  FrameParts expected(header);
+  expected.SetOptPing(
+      Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, PingAck) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x08',          //   Length: 8
+      '\x06',                          //     Type: PING
+      '\xff',                          //    Flags: ACK (plus all invalid flags)
+      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
+      's',    'o',    'm',    'e',     // "some"
+      'd',    'a',    't',    'a',     // "data"
+  };
+  Http2FrameHeader header(8, Http2FrameType::PING, Http2FrameFlag::ACK, 0);
+  FrameParts expected(header);
+  expected.SetOptPing(
+      Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, GoAwayMinimal) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x08',          // Length: 8 (no opaque data)
+      '\x07',                          //   Type: GOAWAY
+      '\xff',                          //  Flags: 0xff (no valid flags)
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1 (invalid but unchecked here)
+      '\x80', '\x00', '\x00', '\xff',  //   Last: 255 (plus R bit)
+      '\x00', '\x00', '\x00', '\x09',  //  Error: COMPRESSION_ERROR
+  };
+  Http2FrameHeader header(8, Http2FrameType::GOAWAY, 0, 1);
+  FrameParts expected(header);
+  expected.SetOptGoaway(
+      Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR));
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, WindowUpdate) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x04',          // Length: 4
+      '\x08',                          //   Type: WINDOW_UPDATE
+      '\x0f',                          //  Flags: 0xff (no valid flags)
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
+      '\x80', '\x00', '\x04', '\x00',  //   Incr: 1024 (plus R bit)
+  };
+  Http2FrameHeader header(4, Http2FrameType::WINDOW_UPDATE, 0, 1);
+  FrameParts expected(header);
+  expected.SetOptWindowUpdateIncrement(1024);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, ContinuationEmpty) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',  // Payload length: 0
+      '\x09',                  // CONTINUATION
+      '\x00',                  // Flags: none
+      '\x00', '\x00', '\x00',
+      '\x00',  // Stream ID: 0 (invalid but unchecked here)
+  };
+  Http2FrameHeader header(0, Http2FrameType::CONTINUATION, 0, 0);
+  FrameParts expected(header);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, AltSvcMinimal) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x02',  // Payload length: 2
+      '\x0a',                  // ALTSVC
+      '\xff',                  // Flags: none (plus 0xff)
+      '\x00', '\x00', '\x00',
+      '\x00',          // Stream ID: 0 (invalid but unchecked here)
+      '\x00', '\x00',  // Origin Length: 0
+  };
+  Http2FrameHeader header(2, Http2FrameType::ALTSVC, 0, 0);
+  FrameParts expected(header);
+  expected.SetOptAltsvcOriginLength(0);
+  expected.SetOptAltsvcValueLength(0);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, UnknownEmpty) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',          // Payload length: 0
+      '\x20',                          // 32 (unknown)
+      '\xff',                          // Flags: all
+      '\x00', '\x00', '\x00', '\x00',  // Stream ID: 0
+  };
+  Http2FrameHeader header(0, static_cast<Http2FrameType>(32), 0xff, 0);
+  FrameParts expected(header);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests of longer payloads, for those frame types that allow longer payloads.
+
+TEST_F(Http2FrameDecoderTest, DataPayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x03',          // Payload length: 7
+      '\x00',                          // DATA
+      '\x80',                          // Flags: 0x80
+      '\x00', '\x00', '\x02', '\x02',  // Stream ID: 514
+      'a',    'b',    'c',             // Data
+  };
+  Http2FrameHeader header(3, Http2FrameType::DATA, 0, 514);
+  FrameParts expected(header, "abc");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeadersPayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x03',          // Payload length: 3
+      '\x01',                          // HEADERS
+      '\x05',                          // Flags: END_STREAM | END_HEADERS
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
+      'a',    'b',    'c',  // HPACK fragment (doesn't have to be valid)
+  };
+  Http2FrameHeader header(
+      3, Http2FrameType::HEADERS,
+      Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS, 2);
+  FrameParts expected(header, "abc");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeadersPriority) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x05',          // Payload length: 5
+      '\x01',                          // HEADERS
+      '\x20',                          // Flags: PRIORITY
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
+      '\x00', '\x00', '\x00', '\x01',  // Parent: 1 (Not Exclusive)
+      '\xff',                          // Weight: 256
+  };
+  Http2FrameHeader header(5, Http2FrameType::HEADERS, Http2FrameFlag::PRIORITY,
+                          2);
+  FrameParts expected(header);
+  expected.SetOptPriority(Http2PriorityFields(1, 256, false));
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, Settings) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x0c',          // Length: 12
+      '\x04',                          //   Type: SETTINGS
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x00',  // Stream: 0
+      '\x00', '\x04',                  //  Param: INITIAL_WINDOW_SIZE
+      '\x0a', '\x0b', '\x0c', '\x0d',  //  Value: 168496141
+      '\x00', '\x02',                  //  Param: ENABLE_PUSH
+      '\x00', '\x00', '\x00', '\x03',  //  Value: 3 (invalid but unchecked here)
+  };
+  Http2FrameHeader header(12, Http2FrameType::SETTINGS, 0, 0);
+  FrameParts expected(header);
+  expected.AppendSetting(Http2SettingFields(
+      Http2SettingsParameter::INITIAL_WINDOW_SIZE, 168496141));
+  expected.AppendSetting(
+      Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, PushPromisePayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', 7,               // Payload length: 7
+      '\x05',                          // PUSH_PROMISE
+      '\x04',                          // Flags: END_HEADERS
+      '\x00', '\x00', '\x00', '\xff',  // Stream ID: 255
+      '\x00', '\x00', '\x01', '\x00',  // Promised: 256
+      'a',    'b',    'c',  // HPACK fragment (doesn't have to be valid)
+  };
+  Http2FrameHeader header(7, Http2FrameType::PUSH_PROMISE,
+                          Http2FrameFlag::END_HEADERS, 255);
+  FrameParts expected(header, "abc");
+  expected.SetOptPushPromise(Http2PushPromiseFields{256});
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, GoAwayOpaqueData) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x0e',          // Length: 14
+      '\x07',                          //   Type: GOAWAY
+      '\xff',                          //  Flags: 0xff (no valid flags)
+      '\x80', '\x00', '\x00', '\x00',  // Stream: 0 (plus R bit)
+      '\x00', '\x00', '\x01', '\x00',  //   Last: 256
+      '\x00', '\x00', '\x00', '\x03',  //  Error: FLOW_CONTROL_ERROR
+      'o',    'p',    'a',    'q',    'u', 'e',
+  };
+  Http2FrameHeader header(14, Http2FrameType::GOAWAY, 0, 0);
+  FrameParts expected(header, "opaque");
+  expected.SetOptGoaway(
+      Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR));
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, ContinuationPayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x03',          // Payload length: 3
+      '\x09',                          // CONTINUATION
+      '\xff',                          // Flags: END_HEADERS | 0xfb
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
+      'a',    'b',    'c',             // Data
+  };
+  Http2FrameHeader header(3, Http2FrameType::CONTINUATION,
+                          Http2FrameFlag::END_HEADERS, 2);
+  FrameParts expected(header, "abc");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, AltSvcPayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x08',          // Payload length: 3
+      '\x0a',                          // ALTSVC
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
+      '\x00', '\x03',                  // Origin Length: 0
+      'a',    'b',    'c',             // Origin
+      'd',    'e',    'f',             // Value
+  };
+  Http2FrameHeader header(8, Http2FrameType::ALTSVC, 0, 2);
+  FrameParts expected(header);
+  expected.SetAltSvcExpected("abc", "def");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, PriorityUpdatePayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x07',          // Payload length: 7
+      '\x10',                          // PRIORITY_UPDATE
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x00',  // Stream ID: 0
+      '\x00', '\x00', '\x00', '\x05',  // Prioritized Stream ID: 5
+      'a',    'b',    'c',             // Priority Field Value
+  };
+  Http2FrameHeader header(7, Http2FrameType::PRIORITY_UPDATE, 0, 0);
+
+  FrameParts expected(header, "abc");
+  expected.SetOptPriorityUpdate(Http2PriorityUpdateFields{5});
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, UnknownPayload) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x03',          // Payload length: 3
+      '\x30',                          // 48 (unknown)
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
+      'a',    'b',    'c',             // Payload
+  };
+  Http2FrameHeader header(3, static_cast<Http2FrameType>(48), 0, 2);
+  FrameParts expected(header, "abc");
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests of padded payloads, for those frame types that allow padding.
+
+TEST_F(Http2FrameDecoderTest, DataPayloadAndPadding) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x07',          // Payload length: 7
+      '\x00',                          // DATA
+      '\x09',                          // Flags: END_STREAM | PADDED
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
+      '\x03',                          // Pad Len
+      'a',    'b',    'c',             // Data
+      '\x00', '\x00', '\x00',          // Padding
+  };
+  Http2FrameHeader header(7, Http2FrameType::DATA,
+                          Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED,
+                          2);
+  size_t total_pad_length = 4;  // Including the Pad Length field.
+  FrameParts expected(header, "abc", total_pad_length);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeadersPayloadAndPadding) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x07',          // Payload length: 7
+      '\x01',                          // HEADERS
+      '\x08',                          // Flags: PADDED
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
+      '\x03',                          // Pad Len
+      'a',    'b',    'c',     // HPACK fragment (doesn't have to be valid)
+      '\x00', '\x00', '\x00',  // Padding
+  };
+  Http2FrameHeader header(7, Http2FrameType::HEADERS, Http2FrameFlag::PADDED,
+                          2);
+  size_t total_pad_length = 4;  // Including the Pad Length field.
+  FrameParts expected(header, "abc", total_pad_length);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeadersPayloadPriorityAndPadding) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x0c',          // Payload length: 12
+      '\x01',                          // HEADERS
+      '\xff',                          // Flags: all, including undefined
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
+      '\x03',                          // Pad Len
+      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
+      '\x10',                          // Weight: 17
+      'a',    'b',    'c',     // HPACK fragment (doesn't have to be valid)
+      '\x00', '\x00', '\x00',  // Padding
+  };
+  Http2FrameHeader header(12, Http2FrameType::HEADERS,
+                          Http2FrameFlag::END_STREAM |
+                              Http2FrameFlag::END_HEADERS |
+                              Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY,
+                          2);
+  size_t total_pad_length = 4;  // Including the Pad Length field.
+  FrameParts expected(header, "abc", total_pad_length);
+  expected.SetOptPriority(Http2PriorityFields(1, 17, true));
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, PushPromisePayloadAndPadding) {
+  const char kFrameData[] = {
+      '\x00', '\x00', 11,              // Payload length: 11
+      '\x05',                          // PUSH_PROMISE
+      '\xff',                          // Flags: END_HEADERS | PADDED | 0xf3
+      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
+      '\x03',                          // Pad Len
+      '\x00', '\x00', '\x00', '\x02',  // Promised: 2
+      'a',    'b',    'c',     // HPACK fragment (doesn't have to be valid)
+      '\x00', '\x00', '\x00',  // Padding
+  };
+  Http2FrameHeader header(11, Http2FrameType::PUSH_PROMISE,
+                          Http2FrameFlag::END_HEADERS | Http2FrameFlag::PADDED,
+                          1);
+  size_t total_pad_length = 4;  // Including the Pad Length field.
+  FrameParts expected(header, "abc", total_pad_length);
+  expected.SetOptPushPromise(Http2PushPromiseFields{2});
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Payload too short errors.
+
+TEST_F(Http2FrameDecoderTest, DataMissingPadLengthField) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',          // Payload length: 0
+      '\x00',                          // DATA
+      '\x08',                          // Flags: PADDED
+      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
+  };
+  Http2FrameHeader header(0, Http2FrameType::DATA, Http2FrameFlag::PADDED, 1);
+  FrameParts expected(header);
+  expected.SetOptMissingLength(1);
+  EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeaderPaddingTooLong) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x02',          // Payload length: 0
+      '\x01',                          // HEADERS
+      '\x08',                          // Flags: PADDED
+      '\x00', '\x01', '\x00', '\x00',  // Stream ID: 65536
+      '\xff',                          // Pad Len: 255
+      '\x00',                          // Only one byte of padding
+  };
+  Http2FrameHeader header(2, Http2FrameType::HEADERS, Http2FrameFlag::PADDED,
+                          65536);
+  FrameParts expected(header);
+  expected.SetOptMissingLength(254);
+  EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, HeaderMissingPriority) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x04',          // Payload length: 0
+      '\x01',                          // HEADERS
+      '\x20',                          // Flags: PRIORITY
+      '\x00', '\x01', '\x00', '\x00',  // Stream ID: 65536
+      '\x00', '\x00', '\x00', '\x00',  // Priority (truncated)
+  };
+  Http2FrameHeader header(4, Http2FrameType::HEADERS, Http2FrameFlag::PRIORITY,
+                          65536);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, PriorityTooShort) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x04',          // Length: 5
+      '\x02',                          //   Type: PRIORITY
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream: 2
+      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
+  };
+  Http2FrameHeader header(4, Http2FrameType::PRIORITY, 0, 2);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, RstStreamTooShort) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x03',          // Length: 4
+      '\x03',                          //   Type: RST_STREAM
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
+      '\x00', '\x00', '\x00',          //  Truncated
+  };
+  Http2FrameHeader header(3, Http2FrameType::RST_STREAM, 0, 1);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+// SETTINGS frames must a multiple of 6 bytes long, so an 9 byte payload is
+// invalid.
+TEST_F(Http2FrameDecoderTest, SettingsWrongSize) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x09',          // Length: 2
+      '\x04',                          //   Type: SETTINGS
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x00',  // Stream: 0
+      '\x00', '\x02',                  //  Param: ENABLE_PUSH
+      '\x00', '\x00', '\x00', '\x03',  //  Value: 1
+      '\x00', '\x04',                  //  Param: INITIAL_WINDOW_SIZE
+      '\x00',                          //  Value: Truncated
+  };
+  Http2FrameHeader header(9, Http2FrameType::SETTINGS, 0, 0);
+  FrameParts expected(header);
+  expected.AppendSetting(
+      Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, expected));
+}
+
+TEST_F(Http2FrameDecoderTest, PushPromiseTooShort) {
+  const char kFrameData[] = {
+      '\x00', '\x00', 3,               // Payload length: 3
+      '\x05',                          // PUSH_PROMISE
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
+      '\x00', '\x00', '\x00',          // Truncated promise id
+  };
+  Http2FrameHeader header(3, Http2FrameType::PUSH_PROMISE, 0, 1);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, PushPromisePaddedTruncatedPromise) {
+  const char kFrameData[] = {
+      '\x00', '\x00', 4,               // Payload length: 4
+      '\x05',                          // PUSH_PROMISE
+      '\x08',                          // Flags: PADDED
+      '\x00', '\x00', '\x00', '\x01',  // Stream ID: 1
+      '\x00',                          // Pad Len
+      '\x00', '\x00', '\x00',          // Truncated promise id
+  };
+  Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
+                          Http2FrameFlag::PADDED, 1);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, PingTooShort) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x07',          //   Length: 8
+      '\x06',                          //     Type: PING
+      '\xfe',                          //    Flags: no valid flags
+      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
+      's',    'o',    'm',    'e',     // "some"
+      'd',    'a',    't',             // Too little
+  };
+  Http2FrameHeader header(7, Http2FrameType::PING, 0, 0);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, GoAwayTooShort) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x00',          // Length: 0
+      '\x07',                          //   Type: GOAWAY
+      '\xff',                          //  Flags: 0xff (no valid flags)
+      '\x00', '\x00', '\x00', '\x00',  // Stream: 0
+  };
+  Http2FrameHeader header(0, Http2FrameType::GOAWAY, 0, 0);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, WindowUpdateTooShort) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x03',          // Length: 3
+      '\x08',                          //   Type: WINDOW_UPDATE
+      '\x0f',                          //  Flags: 0xff (no valid flags)
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
+      '\x80', '\x00', '\x04',          // Truncated
+  };
+  Http2FrameHeader header(3, Http2FrameType::WINDOW_UPDATE, 0, 1);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOriginLength) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x01',          // Payload length: 3
+      '\x0a',                          // ALTSVC
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
+      '\x00',                          // Origin Length: truncated
+  };
+  Http2FrameHeader header(1, Http2FrameType::ALTSVC, 0, 2);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOrigin) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x05',          // Payload length: 3
+      '\x0a',                          // ALTSVC
+      '\x00',                          // Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 2
+      '\x00', '\x04',                  // Origin Length: 4 (too long)
+      'a',    'b',    'c',             // Origin
+  };
+  Http2FrameHeader header(5, Http2FrameType::ALTSVC, 0, 2);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Payload too long errors.
+
+// The decoder calls the listener's OnFrameSizeError method if the frame's
+// payload is longer than the currently configured maximum payload size.
+TEST_F(Http2FrameDecoderTest, BeyondMaximum) {
+  maximum_payload_size_ = 2;
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x07',          // Payload length: 7
+      '\x00',                          // DATA
+      '\x09',                          // Flags: END_STREAM | PADDED
+      '\x00', '\x00', '\x00', '\x02',  // Stream ID: 0  (REQUIRES ID)
+      '\x03',                          // Pad Len
+      'a',    'b',    'c',             // Data
+      '\x00', '\x00', '\x00',          // Padding
+  };
+  Http2FrameHeader header(7, Http2FrameType::DATA,
+                          Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED,
+                          2);
+  FrameParts expected(header);
+  expected.SetHasFrameSizeError(true);
+  auto validator = [&expected, this](const DecodeBuffer& input,
+                                     DecodeStatus status) -> AssertionResult {
+    VERIFY_EQ(status, DecodeStatus::kDecodeError);
+    // The decoder detects this error after decoding the header, and without
+    // trying to decode the payload.
+    VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize());
+    VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected));
+  };
+  ResetDecodeSpeedCounters();
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(ToStringPiece(kFrameData),
+                                                  validator));
+  EXPECT_GT(fast_decode_count_, 0u);
+  EXPECT_GT(slow_decode_count_, 0u);
+}
+
+TEST_F(Http2FrameDecoderTest, PriorityTooLong) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x06',          // Length: 5
+      '\x02',                          //   Type: PRIORITY
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x02',  // Stream: 2
+      '\x80', '\x00', '\x00', '\x01',  // Parent: 1 (Exclusive)
+      '\x10',                          // Weight: 17
+      '\x00',                          // Too much
+  };
+  Http2FrameHeader header(6, Http2FrameType::PRIORITY, 0, 2);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, RstStreamTooLong) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x05',          // Length: 4
+      '\x03',                          //   Type: RST_STREAM
+      '\x00',                          //  Flags: none
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
+      '\x00', '\x00', '\x00', '\x01',  //  Error: PROTOCOL_ERROR
+      '\x00',                          // Too much
+  };
+  Http2FrameHeader header(5, Http2FrameType::RST_STREAM, 0, 1);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, SettingsAckTooLong) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x06',          //   Length: 6
+      '\x04',                          //     Type: SETTINGS
+      '\x01',                          //    Flags: ACK
+      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
+      '\x00', '\x00',                  //   Extra
+      '\x00', '\x00', '\x00', '\x00',  //   Extra
+  };
+  Http2FrameHeader header(6, Http2FrameType::SETTINGS, Http2FrameFlag::ACK, 0);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, PingAckTooLong) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x09',          //   Length: 8
+      '\x06',                          //     Type: PING
+      '\xff',                          //    Flags: ACK | 0xfe
+      '\x00', '\x00', '\x00', '\x00',  //   Stream: 0
+      's',    'o',    'm',    'e',     // "some"
+      'd',    'a',    't',    'a',     // "data"
+      '\x00',                          // Too much
+  };
+  Http2FrameHeader header(9, Http2FrameType::PING, Http2FrameFlag::ACK, 0);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+TEST_F(Http2FrameDecoderTest, WindowUpdateTooLong) {
+  const char kFrameData[] = {
+      '\x00', '\x00', '\x05',          // Length: 5
+      '\x08',                          //   Type: WINDOW_UPDATE
+      '\x0f',                          //  Flags: 0xff (no valid flags)
+      '\x00', '\x00', '\x00', '\x01',  // Stream: 1
+      '\x80', '\x00', '\x04', '\x00',  //   Incr: 1024 (plus R bit)
+      '\x00',                          // Too much
+  };
+  Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1);
+  EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_structure_decoder.cc b/quiche/http2/decoder/http2_structure_decoder.cc
new file mode 100644
index 0000000..b8d0a9e
--- /dev/null
+++ b/quiche/http2/decoder/http2_structure_decoder.cc
@@ -0,0 +1,95 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_structure_decoder.h"
+
+#include <algorithm>
+#include <cstring>
+
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+
+namespace http2 {
+
+// Below we have some defensive coding: if we somehow run off the end, don't
+// overwrite lots of memory. Note that most of this decoder is not defensive
+// against bugs in the decoder, only against malicious encoders, but since
+// we're copying memory into a buffer here, let's make sure we don't allow a
+// small mistake to grow larger. The decoder will get stuck if we hit the
+// HTTP2_BUG conditions, but shouldn't corrupt memory.
+
+uint32_t Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
+                                                uint32_t target_size) {
+  if (target_size > sizeof buffer_) {
+    HTTP2_BUG(http2_bug_154_1)
+        << "target_size too large for buffer: " << target_size;
+    return 0;
+  }
+  const uint32_t num_to_copy = db->MinLengthRemaining(target_size);
+  memcpy(buffer_, db->cursor(), num_to_copy);
+  offset_ = num_to_copy;
+  db->AdvanceCursor(num_to_copy);
+  return num_to_copy;
+}
+
+DecodeStatus Http2StructureDecoder::IncompleteStart(DecodeBuffer* db,
+                                                    uint32_t* remaining_payload,
+                                                    uint32_t target_size) {
+  HTTP2_DVLOG(1) << "IncompleteStart@" << this
+                 << ": *remaining_payload=" << *remaining_payload
+                 << "; target_size=" << target_size
+                 << "; db->Remaining=" << db->Remaining();
+  *remaining_payload -=
+      IncompleteStart(db, std::min(target_size, *remaining_payload));
+  if (*remaining_payload > 0 && db->Empty()) {
+    return DecodeStatus::kDecodeInProgress;
+  }
+  HTTP2_DVLOG(1) << "IncompleteStart: kDecodeError";
+  return DecodeStatus::kDecodeError;
+}
+
+bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
+                                                uint32_t target_size) {
+  HTTP2_DVLOG(2) << "ResumeFillingBuffer@" << this
+                 << ": target_size=" << target_size << "; offset_=" << offset_
+                 << "; db->Remaining=" << db->Remaining();
+  if (target_size < offset_) {
+    HTTP2_BUG(http2_bug_154_2)
+        << "Already filled buffer_! target_size=" << target_size
+        << "    offset_=" << offset_;
+    return false;
+  }
+  const uint32_t needed = target_size - offset_;
+  const uint32_t num_to_copy = db->MinLengthRemaining(needed);
+  HTTP2_DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
+  memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
+  db->AdvanceCursor(num_to_copy);
+  offset_ += num_to_copy;
+  return needed == num_to_copy;
+}
+
+bool Http2StructureDecoder::ResumeFillingBuffer(DecodeBuffer* db,
+                                                uint32_t* remaining_payload,
+                                                uint32_t target_size) {
+  HTTP2_DVLOG(2) << "ResumeFillingBuffer@" << this
+                 << ": target_size=" << target_size << "; offset_=" << offset_
+                 << "; *remaining_payload=" << *remaining_payload
+                 << "; db->Remaining=" << db->Remaining();
+  if (target_size < offset_) {
+    HTTP2_BUG(http2_bug_154_3)
+        << "Already filled buffer_! target_size=" << target_size
+        << "    offset_=" << offset_;
+    return false;
+  }
+  const uint32_t needed = target_size - offset_;
+  const uint32_t num_to_copy =
+      db->MinLengthRemaining(std::min(needed, *remaining_payload));
+  HTTP2_DVLOG(2) << "ResumeFillingBuffer num_to_copy=" << num_to_copy;
+  memcpy(&buffer_[offset_], db->cursor(), num_to_copy);
+  db->AdvanceCursor(num_to_copy);
+  offset_ += num_to_copy;
+  *remaining_payload -= num_to_copy;
+  return needed == num_to_copy;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_structure_decoder.h b/quiche/http2/decoder/http2_structure_decoder.h
new file mode 100644
index 0000000..648ec32
--- /dev/null
+++ b/quiche/http2/decoder/http2_structure_decoder.h
@@ -0,0 +1,132 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_H_
+#define QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_H_
+
+// Http2StructureDecoder is a class for decoding the fixed size structures in
+// the HTTP/2 spec, defined in quiche/http2/http2_structures.h. This class
+// is in aid of deciding whether to keep the SlowDecode methods which I
+// (jamessynge) now think may not be worth their complexity. In particular,
+// if most transport buffers are large, so it is rare that a structure is
+// split across buffer boundaries, than the cost of buffering upon
+// those rare occurrences is small, which then simplifies the callers.
+
+#include <cstdint>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_http2_structures.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class Http2StructureDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE Http2StructureDecoder {
+ public:
+  // The caller needs to keep track of whether to call Start or Resume.
+  //
+  // Start has an optimization for the case where the DecodeBuffer holds the
+  // entire encoded structure; in that case it decodes into *out and returns
+  // true, and does NOT touch the data members of the Http2StructureDecoder
+  // instance because the caller won't be calling Resume later.
+  //
+  // However, if the DecodeBuffer is too small to hold the entire encoded
+  // structure, Start copies the available bytes into the Http2StructureDecoder
+  // instance, and returns false to indicate that it has not been able to
+  // complete the decoding.
+  //
+  template <class S>
+  bool Start(S* out, DecodeBuffer* db) {
+    static_assert(S::EncodedSize() <= sizeof buffer_, "buffer_ is too small");
+    HTTP2_DVLOG(2) << __func__ << "@" << this
+                   << ": db->Remaining=" << db->Remaining()
+                   << "; EncodedSize=" << S::EncodedSize();
+    if (db->Remaining() >= S::EncodedSize()) {
+      DoDecode(out, db);
+      return true;
+    }
+    IncompleteStart(db, S::EncodedSize());
+    return false;
+  }
+
+  template <class S>
+  bool Resume(S* out, DecodeBuffer* db) {
+    HTTP2_DVLOG(2) << __func__ << "@" << this << ": offset_=" << offset_
+                   << "; db->Remaining=" << db->Remaining();
+    if (ResumeFillingBuffer(db, S::EncodedSize())) {
+      // We have the whole thing now.
+      HTTP2_DVLOG(2) << __func__ << "@" << this << "    offset_=" << offset_
+                     << "    Ready to decode from buffer_.";
+      DecodeBuffer buffer_db(buffer_, S::EncodedSize());
+      DoDecode(out, &buffer_db);
+      return true;
+    }
+    QUICHE_DCHECK_LT(offset_, S::EncodedSize());
+    return false;
+  }
+
+  // A second pair of Start and Resume, where the caller has a variable,
+  // |remaining_payload| that is both tested for sufficiency and updated
+  // during decoding. Note that the decode buffer may extend beyond the
+  // remaining payload because the buffer may include padding.
+  template <class S>
+  DecodeStatus Start(S* out, DecodeBuffer* db, uint32_t* remaining_payload) {
+    static_assert(S::EncodedSize() <= sizeof buffer_, "buffer_ is too small");
+    HTTP2_DVLOG(2) << __func__ << "@" << this
+                   << ": *remaining_payload=" << *remaining_payload
+                   << "; db->Remaining=" << db->Remaining()
+                   << "; EncodedSize=" << S::EncodedSize();
+    if (db->MinLengthRemaining(*remaining_payload) >= S::EncodedSize()) {
+      DoDecode(out, db);
+      *remaining_payload -= S::EncodedSize();
+      return DecodeStatus::kDecodeDone;
+    }
+    return IncompleteStart(db, remaining_payload, S::EncodedSize());
+  }
+
+  template <class S>
+  bool Resume(S* out, DecodeBuffer* db, uint32_t* remaining_payload) {
+    HTTP2_DVLOG(3) << __func__ << "@" << this << ": offset_=" << offset_
+                   << "; *remaining_payload=" << *remaining_payload
+                   << "; db->Remaining=" << db->Remaining()
+                   << "; EncodedSize=" << S::EncodedSize();
+    if (ResumeFillingBuffer(db, remaining_payload, S::EncodedSize())) {
+      // We have the whole thing now.
+      HTTP2_DVLOG(2) << __func__ << "@" << this << ": offset_=" << offset_
+                     << "; Ready to decode from buffer_.";
+      DecodeBuffer buffer_db(buffer_, S::EncodedSize());
+      DoDecode(out, &buffer_db);
+      return true;
+    }
+    QUICHE_DCHECK_LT(offset_, S::EncodedSize());
+    return false;
+  }
+
+  uint32_t offset() const { return offset_; }
+
+ private:
+  friend class test::Http2StructureDecoderPeer;
+
+  uint32_t IncompleteStart(DecodeBuffer* db, uint32_t target_size);
+  DecodeStatus IncompleteStart(DecodeBuffer* db,
+                               uint32_t* remaining_payload,
+                               uint32_t target_size);
+
+  bool ResumeFillingBuffer(DecodeBuffer* db, uint32_t target_size);
+  bool ResumeFillingBuffer(DecodeBuffer* db,
+                           uint32_t* remaining_payload,
+                           uint32_t target_size);
+
+  uint32_t offset_;
+  char buffer_[Http2FrameHeader::EncodedSize()];
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_H_
diff --git a/quiche/http2/decoder/http2_structure_decoder_test.cc b/quiche/http2/decoder/http2_structure_decoder_test.cc
new file mode 100644
index 0000000..44bf785
--- /dev/null
+++ b/quiche/http2/decoder/http2_structure_decoder_test.cc
@@ -0,0 +1,537 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_structure_decoder.h"
+
+// Tests decoding all of the fixed size HTTP/2 structures (i.e. those defined in
+// quiche/http2/http2_structures.h) using Http2StructureDecoder, which
+// handles buffering of structures split across input buffer boundaries, and in
+// turn uses DoDecode when it has all of a structure in a contiguous buffer.
+
+// NOTE: This tests the first pair of Start and Resume, which don't take
+// a remaining_payload parameter. The other pair are well tested via the
+// payload decoder tests, though...
+// TODO(jamessynge): Create type parameterized tests for Http2StructureDecoder
+// where the type is the type of structure, and with testing of both pairs of
+// Start and Resume methods; note that it appears that the first pair will be
+// used only for Http2FrameHeader, and the other pair only for structures in the
+// frame payload.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+namespace {
+const bool kMayReturnZeroOnFirst = false;
+
+template <class S>
+class Http2StructureDecoderTest : public RandomDecoderTest {
+ protected:
+  typedef S Structure;
+
+  Http2StructureDecoderTest() {
+    // IF the test adds more data after the encoded structure, stop as
+    // soon as the structure is decoded.
+    stop_decode_on_done_ = true;
+  }
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    // Overwrite the current contents of |structure_|, into which we'll
+    // decode the buffer, so that we can be confident that we really decoded
+    // the structure every time.
+    structure_ = std::make_unique<S>();
+    uint32_t old_remaining = b->Remaining();
+    if (structure_decoder_.Start(structure_.get(), b)) {
+      EXPECT_EQ(old_remaining - S::EncodedSize(), b->Remaining());
+      ++fast_decode_count_;
+      return DecodeStatus::kDecodeDone;
+    } else {
+      EXPECT_LT(structure_decoder_.offset(), S::EncodedSize());
+      EXPECT_EQ(0u, b->Remaining());
+      EXPECT_EQ(old_remaining - structure_decoder_.offset(), b->Remaining());
+      ++incomplete_start_count_;
+      return DecodeStatus::kDecodeInProgress;
+    }
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    uint32_t old_offset = structure_decoder_.offset();
+    EXPECT_LT(old_offset, S::EncodedSize());
+    uint32_t avail = b->Remaining();
+    if (structure_decoder_.Resume(structure_.get(), b)) {
+      EXPECT_LE(S::EncodedSize(), old_offset + avail);
+      EXPECT_EQ(b->Remaining(), avail - (S::EncodedSize() - old_offset));
+      ++slow_decode_count_;
+      return DecodeStatus::kDecodeDone;
+    } else {
+      EXPECT_LT(structure_decoder_.offset(), S::EncodedSize());
+      EXPECT_EQ(0u, b->Remaining());
+      EXPECT_GT(S::EncodedSize(), old_offset + avail);
+      ++incomplete_resume_count_;
+      return DecodeStatus::kDecodeInProgress;
+    }
+  }
+
+  // Fully decodes the Structure at the start of data, and confirms it matches
+  // *expected (if provided).
+  AssertionResult DecodeLeadingStructure(const S* expected,
+                                         absl::string_view data) {
+    VERIFY_LE(S::EncodedSize(), data.size());
+    DecodeBuffer original(data);
+
+    // The validator is called after each of the several times that the input
+    // DecodeBuffer is decoded, each with a different segmentation of the input.
+    // Validate that structure_ matches the expected value, if provided.
+    Validator validator;
+    if (expected != nullptr) {
+      validator = [expected, this](const DecodeBuffer& /*db*/,
+                                   DecodeStatus /*status*/) -> AssertionResult {
+        VERIFY_EQ(*expected, *structure_);
+        return AssertionSuccess();
+      };
+    }
+
+    // Before that, validate that decoding is done and that we've advanced
+    // the cursor the expected amount.
+    validator = ValidateDoneAndOffset(S::EncodedSize(), validator);
+
+    // Decode several times, with several segmentations of the input buffer.
+    fast_decode_count_ = 0;
+    slow_decode_count_ = 0;
+    incomplete_start_count_ = 0;
+    incomplete_resume_count_ = 0;
+    VERIFY_SUCCESS(DecodeAndValidateSeveralWays(
+        &original, kMayReturnZeroOnFirst, validator));
+    VERIFY_FALSE(HasFailure());
+    VERIFY_EQ(S::EncodedSize(), structure_decoder_.offset());
+    VERIFY_EQ(S::EncodedSize(), original.Offset());
+    VERIFY_LT(0u, fast_decode_count_);
+    VERIFY_LT(0u, slow_decode_count_);
+    VERIFY_LT(0u, incomplete_start_count_);
+
+    // If the structure is large enough so that SelectZeroOrOne will have
+    // caused Resume to return false, check that occurred.
+    if (S::EncodedSize() >= 2) {
+      VERIFY_LE(0u, incomplete_resume_count_);
+    } else {
+      VERIFY_EQ(0u, incomplete_resume_count_);
+    }
+    if (expected != nullptr) {
+      HTTP2_DVLOG(1) << "DecodeLeadingStructure expected: " << *expected;
+      HTTP2_DVLOG(1) << "DecodeLeadingStructure   actual: " << *structure_;
+      VERIFY_EQ(*expected, *structure_);
+    }
+    return AssertionSuccess();
+  }
+
+  template <size_t N>
+  AssertionResult DecodeLeadingStructure(const char (&data)[N]) {
+    VERIFY_AND_RETURN_SUCCESS(
+        DecodeLeadingStructure(nullptr, absl::string_view(data, N)));
+  }
+
+  template <size_t N>
+  AssertionResult DecodeLeadingStructure(const unsigned char (&data)[N]) {
+    VERIFY_AND_RETURN_SUCCESS(
+        DecodeLeadingStructure(nullptr, ToStringPiece(data)));
+  }
+
+  // Encode the structure |in_s| into bytes, then decode the bytes
+  // and validate that the decoder produced the same field values.
+  AssertionResult EncodeThenDecode(const S& in_s) {
+    std::string bytes = SerializeStructure(in_s);
+    VERIFY_EQ(S::EncodedSize(), bytes.size());
+    VERIFY_AND_RETURN_SUCCESS(DecodeLeadingStructure(&in_s, bytes));
+  }
+
+  // Repeatedly fill a structure with random but valid contents, encode it, then
+  // decode it, and finally validate that the decoded structure matches the
+  // random input. Lather-rinse-and-repeat.
+  AssertionResult TestDecodingRandomizedStructures(size_t count) {
+    for (size_t i = 0; i < count; ++i) {
+      Structure input;
+      Randomize(&input, RandomPtr());
+      VERIFY_SUCCESS(EncodeThenDecode(input));
+    }
+    return AssertionSuccess();
+  }
+
+  AssertionResult TestDecodingRandomizedStructures() {
+    VERIFY_SUCCESS(TestDecodingRandomizedStructures(100));
+    return AssertionSuccess();
+  }
+
+  uint32_t decode_offset_ = 0;
+  std::unique_ptr<S> structure_;
+  Http2StructureDecoder structure_decoder_;
+  size_t fast_decode_count_ = 0;
+  size_t slow_decode_count_ = 0;
+  size_t incomplete_start_count_ = 0;
+  size_t incomplete_resume_count_ = 0;
+};
+
+class Http2FrameHeaderDecoderTest
+    : public Http2StructureDecoderTest<Http2FrameHeader> {};
+
+TEST_F(Http2FrameHeaderDecoderTest, DecodesLiteral) {
+  {
+    // Realistic input.
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x00, 0x05,        // Payload length: 5
+        0x01,                    // Frame type: HEADERS
+        0x08,                    // Flags: PADDED
+        0x00, 0x00, 0x00, 0x01,  // Stream ID: 1
+        0x04,                    // Padding length: 4
+        0x00, 0x00, 0x00, 0x00,  // Padding bytes
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(5u, structure_->payload_length);
+    EXPECT_EQ(Http2FrameType::HEADERS, structure_->type);
+    EXPECT_EQ(Http2FrameFlag::PADDED, structure_->flags);
+    EXPECT_EQ(1u, structure_->stream_id);
+  }
+  {
+    // Unlikely input.
+    // clang-format off
+    const unsigned char kData[] = {
+        0xff, 0xff, 0xff,        // Payload length: uint24 max
+        0xff,                    // Frame type: Unknown
+        0xff,                    // Flags: Unknown/All
+        0xff, 0xff, 0xff, 0xff,  // Stream ID: uint31 max, plus R-bit
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ((1u << 24) - 1u, structure_->payload_length);
+    EXPECT_EQ(static_cast<Http2FrameType>(255), structure_->type);
+    EXPECT_EQ(255, structure_->flags);
+    EXPECT_EQ(0x7FFFFFFFu, structure_->stream_id);
+  }
+}
+
+TEST_F(Http2FrameHeaderDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2PriorityFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2PriorityFields> {};
+
+TEST_F(Http2PriorityFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0x80, 0x00, 0x00, 0x05,  // Exclusive (yes) and Dependency (5)
+        0xff,                    // Weight: 256 (after adding 1)
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(5u, structure_->stream_dependency);
+    EXPECT_EQ(256u, structure_->weight);
+    EXPECT_EQ(true, structure_->is_exclusive);
+  }
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0x7f, 0xff, 0xff, 0xff,  // Excl. (no) and Dependency (uint31 max)
+        0x00,                    // Weight: 1 (after adding 1)
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(StreamIdMask(), structure_->stream_dependency);
+    EXPECT_EQ(1u, structure_->weight);
+    EXPECT_FALSE(structure_->is_exclusive);
+  }
+}
+
+TEST_F(Http2PriorityFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2RstStreamFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2RstStreamFields> {};
+
+TEST_F(Http2RstStreamFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x00, 0x00, 0x01,  // Error: PROTOCOL_ERROR
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_TRUE(structure_->IsSupportedErrorCode());
+    EXPECT_EQ(Http2ErrorCode::PROTOCOL_ERROR, structure_->error_code);
+  }
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0xff, 0xff, 0xff, 0xff,  // Error: max uint32 (Unknown error code)
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_FALSE(structure_->IsSupportedErrorCode());
+    EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_->error_code);
+  }
+}
+
+TEST_F(Http2RstStreamFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2SettingFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2SettingFields> {};
+
+TEST_F(Http2SettingFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x01,              // Setting: HEADER_TABLE_SIZE
+        0x00, 0x00, 0x40, 0x00,  // Value: 16K
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_TRUE(structure_->IsSupportedParameter());
+    EXPECT_EQ(Http2SettingsParameter::HEADER_TABLE_SIZE, structure_->parameter);
+    EXPECT_EQ(1u << 14, structure_->value);
+  }
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0x00, 0x00,              // Setting: Unknown (0)
+        0xff, 0xff, 0xff, 0xff,  // Value: max uint32
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_FALSE(structure_->IsSupportedParameter());
+    EXPECT_EQ(static_cast<Http2SettingsParameter>(0), structure_->parameter);
+  }
+}
+
+TEST_F(Http2SettingFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2PushPromiseFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2PushPromiseFields> {};
+
+TEST_F(Http2PushPromiseFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0x00, 0x01, 0x8a, 0x92,  // Promised Stream ID: 101010
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(101010u, structure_->promised_stream_id);
+  }
+  {
+    // Promised stream id has R-bit (reserved for future use) set, which
+    // should be cleared by the decoder.
+    // clang-format off
+    const unsigned char kData[] = {
+        // Promised Stream ID: max uint31 and R-bit
+        0xff, 0xff, 0xff, 0xff,
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(StreamIdMask(), structure_->promised_stream_id);
+  }
+}
+
+TEST_F(Http2PushPromiseFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2PingFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2PingFields> {};
+
+TEST_F(Http2PingFieldsDecoderTest, DecodesLiteral) {
+  {
+    // Each byte is different, so can detect if order changed.
+    const char kData[] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    };
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(ToStringPiece(kData), ToStringPiece(structure_->opaque_bytes));
+  }
+  {
+    // All zeros, detect problems handling NULs.
+    const char kData[] = {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    };
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(ToStringPiece(kData), ToStringPiece(structure_->opaque_bytes));
+  }
+  {
+    const unsigned char kData[] = {
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    };
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(ToStringPiece(kData), ToStringPiece(structure_->opaque_bytes));
+  }
+}
+
+TEST_F(Http2PingFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2GoAwayFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2GoAwayFields> {};
+
+TEST_F(Http2GoAwayFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x00, 0x00, 0x00,  // Last Stream ID: 0
+        0x00, 0x00, 0x00, 0x00,  // Error: NO_ERROR (0)
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(0u, structure_->last_stream_id);
+    EXPECT_TRUE(structure_->IsSupportedErrorCode());
+    EXPECT_EQ(Http2ErrorCode::HTTP2_NO_ERROR, structure_->error_code);
+  }
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x00, 0x00, 0x01,  // Last Stream ID: 1
+        0x00, 0x00, 0x00, 0x0d,  // Error: HTTP_1_1_REQUIRED
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(1u, structure_->last_stream_id);
+    EXPECT_TRUE(structure_->IsSupportedErrorCode());
+    EXPECT_EQ(Http2ErrorCode::HTTP_1_1_REQUIRED, structure_->error_code);
+  }
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0xff, 0xff, 0xff, 0xff,  // Last Stream ID: max uint31 and R-bit
+        0xff, 0xff, 0xff, 0xff,  // Error: max uint32 (Unknown error code)
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(StreamIdMask(), structure_->last_stream_id);  // No high-bit.
+    EXPECT_FALSE(structure_->IsSupportedErrorCode());
+    EXPECT_EQ(static_cast<Http2ErrorCode>(0xffffffff), structure_->error_code);
+  }
+}
+
+TEST_F(Http2GoAwayFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2WindowUpdateFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2WindowUpdateFields> {};
+
+TEST_F(Http2WindowUpdateFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x01, 0x00, 0x00,  // Window Size Increment: 2 ^ 16
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(1u << 16, structure_->window_size_increment);
+  }
+  {
+    // Increment must be non-zero, but we need to be able to decode the invalid
+    // zero to detect it.
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x00, 0x00, 0x00,  // Window Size Increment: 0
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(0u, structure_->window_size_increment);
+  }
+  {
+    // Increment has R-bit (reserved for future use) set, which
+    // should be cleared by the decoder.
+    // clang-format off
+    const unsigned char kData[] = {
+        // Window Size Increment: max uint31 and R-bit
+        0xff, 0xff, 0xff, 0xff,
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(StreamIdMask(), structure_->window_size_increment);
+  }
+}
+
+TEST_F(Http2WindowUpdateFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+//------------------------------------------------------------------------------
+
+class Http2AltSvcFieldsDecoderTest
+    : public Http2StructureDecoderTest<Http2AltSvcFields> {};
+
+TEST_F(Http2AltSvcFieldsDecoderTest, DecodesLiteral) {
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x00,  // Origin Length: 0
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(0, structure_->origin_length);
+  }
+  {
+    // clang-format off
+    const char kData[] = {
+        0x00, 0x14,  // Origin Length: 20
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(20, structure_->origin_length);
+  }
+  {
+    // clang-format off
+    const unsigned char kData[] = {
+        0xff, 0xff,  // Origin Length: uint16 max
+    };
+    // clang-format on
+    ASSERT_TRUE(DecodeLeadingStructure(kData));
+    EXPECT_EQ(65535, structure_->origin_length);
+  }
+}
+
+TEST_F(Http2AltSvcFieldsDecoderTest, DecodesRandomized) {
+  EXPECT_TRUE(TestDecodingRandomizedStructures());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_structure_decoder_test_util.cc b/quiche/http2/decoder/http2_structure_decoder_test_util.cc
new file mode 100644
index 0000000..877d517
--- /dev/null
+++ b/quiche/http2/decoder/http2_structure_decoder_test_util.cc
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/http2_structure_decoder_test_util.h"
+
+#include <cstddef>
+
+namespace http2 {
+namespace test {
+
+// static
+void Http2StructureDecoderPeer::Randomize(Http2StructureDecoder* p,
+                                          Http2Random* rng) {
+  p->offset_ = rng->Rand32();
+  for (size_t i = 0; i < sizeof p->buffer_; ++i) {
+    p->buffer_[i] = rng->Rand8();
+  }
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/http2_structure_decoder_test_util.h b/quiche/http2/decoder/http2_structure_decoder_test_util.h
new file mode 100644
index 0000000..32145aa
--- /dev/null
+++ b/quiche/http2/decoder/http2_structure_decoder_test_util.h
@@ -0,0 +1,24 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_TEST_UTIL_H_
+#define QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_TEST_UTIL_H_
+
+#include "quiche/http2/decoder/http2_structure_decoder.h"
+
+#include "quiche/http2/test_tools/http2_random.h"
+
+namespace http2 {
+namespace test {
+
+class Http2StructureDecoderPeer {
+ public:
+  // Overwrite the Http2StructureDecoder instance with random values.
+  static void Randomize(Http2StructureDecoder* p, Http2Random* rng);
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_HTTP2_STRUCTURE_DECODER_TEST_UTIL_H_
diff --git a/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.cc
new file mode 100644
index 0000000..45c3cbd
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.cc
@@ -0,0 +1,151 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         AltSvcPayloadDecoder::PayloadState v) {
+  switch (v) {
+    case AltSvcPayloadDecoder::PayloadState::kStartDecodingStruct:
+      return out << "kStartDecodingStruct";
+    case AltSvcPayloadDecoder::PayloadState::kMaybeDecodedStruct:
+      return out << "kMaybeDecodedStruct";
+    case AltSvcPayloadDecoder::PayloadState::kDecodingStrings:
+      return out << "kDecodingStrings";
+    case AltSvcPayloadDecoder::PayloadState::kResumeDecodingStruct:
+      return out << "kResumeDecodingStruct";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_163_1)
+      << "Invalid AltSvcPayloadDecoder::PayloadState: " << unknown;
+  return out << "AltSvcPayloadDecoder::PayloadState(" << unknown << ")";
+}
+
+DecodeStatus AltSvcPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "AltSvcPayloadDecoder::StartDecodingPayload: "
+                 << state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::ALTSVC, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
+
+  state->InitializeRemainders();
+  payload_state_ = PayloadState::kStartDecodingStruct;
+
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus AltSvcPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  HTTP2_DVLOG(2) << "AltSvcPayloadDecoder::ResumeDecodingPayload: "
+                 << frame_header;
+  QUICHE_DCHECK_EQ(Http2FrameType::ALTSVC, frame_header.type);
+  QUICHE_DCHECK_LE(state->remaining_payload(), frame_header.payload_length);
+  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
+  QUICHE_DCHECK_NE(PayloadState::kMaybeDecodedStruct, payload_state_);
+  // |status| has to be initialized to some value to avoid compiler error in
+  // case PayloadState::kMaybeDecodedStruct below, but value does not matter,
+  // see QUICHE_DCHECK_NE above.
+  DecodeStatus status = DecodeStatus::kDecodeError;
+  while (true) {
+    HTTP2_DVLOG(2)
+        << "AltSvcPayloadDecoder::ResumeDecodingPayload payload_state_="
+        << payload_state_;
+    switch (payload_state_) {
+      case PayloadState::kStartDecodingStruct:
+        status = state->StartDecodingStructureInPayload(&altsvc_fields_, db);
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kMaybeDecodedStruct:
+        if (status == DecodeStatus::kDecodeDone &&
+            altsvc_fields_.origin_length <= state->remaining_payload()) {
+          size_t origin_length = altsvc_fields_.origin_length;
+          size_t value_length = state->remaining_payload() - origin_length;
+          state->listener()->OnAltSvcStart(frame_header, origin_length,
+                                           value_length);
+        } else if (status != DecodeStatus::kDecodeDone) {
+          QUICHE_DCHECK(state->remaining_payload() > 0 ||
+                        status == DecodeStatus::kDecodeError)
+              << "\nremaining_payload: " << state->remaining_payload()
+              << "\nstatus: " << status << "\nheader: " << frame_header;
+          // Assume in progress.
+          payload_state_ = PayloadState::kResumeDecodingStruct;
+          return status;
+        } else {
+          // The origin's length is longer than the remaining payload.
+          QUICHE_DCHECK_GT(altsvc_fields_.origin_length,
+                           state->remaining_payload());
+          return state->ReportFrameSizeError();
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kDecodingStrings:
+        return DecodeStrings(state, db);
+
+      case PayloadState::kResumeDecodingStruct:
+        status = state->ResumeDecodingStructureInPayload(&altsvc_fields_, db);
+        payload_state_ = PayloadState::kMaybeDecodedStruct;
+        continue;
+    }
+    HTTP2_BUG(http2_bug_163_2) << "PayloadState: " << payload_state_;
+  }
+}
+
+DecodeStatus AltSvcPayloadDecoder::DecodeStrings(FrameDecoderState* state,
+                                                 DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "AltSvcPayloadDecoder::DecodeStrings remaining_payload="
+                 << state->remaining_payload()
+                 << ", db->Remaining=" << db->Remaining();
+  // Note that we don't explicitly keep track of exactly how far through the
+  // origin; instead we compute it from how much is left of the original
+  // payload length and the decoded total length of the origin.
+  size_t origin_length = altsvc_fields_.origin_length;
+  size_t value_length = state->frame_header().payload_length - origin_length -
+                        Http2AltSvcFields::EncodedSize();
+  if (state->remaining_payload() > value_length) {
+    size_t remaining_origin_length = state->remaining_payload() - value_length;
+    size_t avail = db->MinLengthRemaining(remaining_origin_length);
+    state->listener()->OnAltSvcOriginData(db->cursor(), avail);
+    db->AdvanceCursor(avail);
+    state->ConsumePayload(avail);
+    if (remaining_origin_length > avail) {
+      payload_state_ = PayloadState::kDecodingStrings;
+      return DecodeStatus::kDecodeInProgress;
+    }
+  }
+  // All that is left is the value string.
+  QUICHE_DCHECK_LE(state->remaining_payload(), value_length);
+  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
+  if (db->HasData()) {
+    size_t avail = db->Remaining();
+    state->listener()->OnAltSvcValueData(db->cursor(), avail);
+    db->AdvanceCursor(avail);
+    state->ConsumePayload(avail);
+  }
+  if (state->remaining_payload() == 0) {
+    state->listener()->OnAltSvcEnd();
+    return DecodeStatus::kDecodeDone;
+  }
+  payload_state_ = PayloadState::kDecodingStrings;
+  return DecodeStatus::kDecodeInProgress;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.h b/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.h
new file mode 100644
index 0000000..64cf703
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.h
@@ -0,0 +1,64 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_ALTSVC_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_ALTSVC_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a ALTSVC frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class AltSvcPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE AltSvcPayloadDecoder {
+ public:
+  // States during decoding of a ALTSVC frame.
+  enum class PayloadState {
+    // Start decoding the fixed size structure at the start of an ALTSVC
+    // frame (Http2AltSvcFields).
+    kStartDecodingStruct,
+
+    // Handle the DecodeStatus returned from starting or resuming the
+    // decoding of Http2AltSvcFields. If complete, calls OnAltSvcStart.
+    kMaybeDecodedStruct,
+
+    // Reports the value of the strings (origin and value) of an ALTSVC frame
+    // to the listener.
+    kDecodingStrings,
+
+    // The initial decode buffer wasn't large enough for the Http2AltSvcFields,
+    // so this state resumes the decoding when ResumeDecodingPayload is called
+    // later with a new DecodeBuffer.
+    kResumeDecodingStruct,
+  };
+
+  // Starts the decoding of a ALTSVC frame's payload, and completes it if the
+  // entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a ALTSVC frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::AltSvcPayloadDecoderPeer;
+
+  // Implements state kDecodingStrings.
+  DecodeStatus DecodeStrings(FrameDecoderState* state, DecodeBuffer* db);
+
+  Http2AltSvcFields altsvc_fields_;
+  PayloadState payload_state_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_ALTSVC_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc
new file mode 100644
index 0000000..b81c161
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc
@@ -0,0 +1,123 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+// Provides friend access to an instance of the payload decoder, and also
+// provides info to aid in testing.
+class AltSvcPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() { return Http2FrameType::ALTSVC; }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnAltSvcStart(const Http2FrameHeader& header,
+                     size_t origin_length,
+                     size_t value_length) override {
+    HTTP2_VLOG(1) << "OnAltSvcStart header: " << header
+                  << "; origin_length=" << origin_length
+                  << "; value_length=" << value_length;
+    StartFrame(header)->OnAltSvcStart(header, origin_length, value_length);
+  }
+
+  void OnAltSvcOriginData(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
+    CurrentFrame()->OnAltSvcOriginData(data, len);
+  }
+
+  void OnAltSvcValueData(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
+    CurrentFrame()->OnAltSvcValueData(data, len);
+  }
+
+  void OnAltSvcEnd() override {
+    HTTP2_VLOG(1) << "OnAltSvcEnd";
+    EndFrame()->OnAltSvcEnd();
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class AltSvcPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<AltSvcPayloadDecoder,
+                                        AltSvcPayloadDecoderPeer,
+                                        Listener> {};
+
+// Confirm we get an error if the payload is not long enough to hold
+// Http2AltSvcFields and the indicated length of origin.
+TEST_F(AltSvcPayloadDecoderTest, Truncated) {
+  Http2FrameBuilder fb;
+  fb.Append(Http2AltSvcFields{0xffff});  // The longest possible origin length.
+  fb.Append("Too little origin!");
+  EXPECT_TRUE(
+      VerifyDetectsFrameSizeError(0, fb.buffer(), /*approve_size*/ nullptr));
+}
+
+class AltSvcPayloadLengthTests : public AltSvcPayloadDecoderTest,
+                                 public ::testing::WithParamInterface<
+                                     ::testing::tuple<uint16_t, uint32_t>> {
+ protected:
+  AltSvcPayloadLengthTests()
+      : origin_length_(::testing::get<0>(GetParam())),
+        value_length_(::testing::get<1>(GetParam())) {
+    HTTP2_VLOG(1) << "################  origin_length_=" << origin_length_
+                  << "   value_length_=" << value_length_
+                  << "  ################";
+  }
+
+  const uint16_t origin_length_;
+  const uint32_t value_length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(VariousOriginAndValueLengths,
+                         AltSvcPayloadLengthTests,
+                         ::testing::Combine(::testing::Values(0, 1, 3, 65535),
+                                            ::testing::Values(0, 1, 3, 65537)));
+
+TEST_P(AltSvcPayloadLengthTests, ValidOriginAndValueLength) {
+  std::string origin = Random().RandString(origin_length_);
+  std::string value = Random().RandString(value_length_);
+  Http2FrameBuilder fb;
+  fb.Append(Http2AltSvcFields{origin_length_});
+  fb.Append(origin);
+  fb.Append(value);
+  Http2FrameHeader header(fb.size(), Http2FrameType::ALTSVC, RandFlags(),
+                          RandStreamId());
+  set_frame_header(header);
+  FrameParts expected(header);
+  expected.SetAltSvcExpected(origin, value);
+  ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.cc
new file mode 100644
index 0000000..8d161f3
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.cc
@@ -0,0 +1,59 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/continuation_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus ContinuationPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "ContinuationPayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+  QUICHE_DCHECK_EQ(Http2FrameType::CONTINUATION, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::END_HEADERS));
+
+  state->InitializeRemainders();
+  state->listener()->OnContinuationStart(frame_header);
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus ContinuationPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "ContinuationPayloadDecoder::ResumeDecodingPayload"
+                 << "  remaining_payload=" << state->remaining_payload()
+                 << "  db->Remaining=" << db->Remaining();
+  QUICHE_DCHECK_EQ(Http2FrameType::CONTINUATION, state->frame_header().type);
+  QUICHE_DCHECK_LE(state->remaining_payload(),
+                   state->frame_header().payload_length);
+  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
+
+  size_t avail = db->Remaining();
+  QUICHE_DCHECK_LE(avail, state->remaining_payload());
+  if (avail > 0) {
+    state->listener()->OnHpackFragment(db->cursor(), avail);
+    db->AdvanceCursor(avail);
+    state->ConsumePayload(avail);
+  }
+  if (state->remaining_payload() == 0) {
+    state->listener()->OnContinuationEnd();
+    return DecodeStatus::kDecodeDone;
+  }
+  return DecodeStatus::kDecodeInProgress;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.h b/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.h
new file mode 100644
index 0000000..ba23a56
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.h
@@ -0,0 +1,31 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_CONTINUATION_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_CONTINUATION_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a CONTINUATION frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE ContinuationPayloadDecoder {
+ public:
+  // Starts the decoding of a CONTINUATION frame's payload, and completes
+  // it if the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a CONTINUATION frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_CONTINUATION_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc
new file mode 100644
index 0000000..c2c6293
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc
@@ -0,0 +1,86 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/continuation_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+#include <type_traits>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+// Provides friend access to an instance of the payload decoder, and also
+// provides info to aid in testing.
+class ContinuationPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::CONTINUATION;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnContinuationStart(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnContinuationStart: " << header;
+    StartFrame(header)->OnContinuationStart(header);
+  }
+
+  void OnHpackFragment(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
+    CurrentFrame()->OnHpackFragment(data, len);
+  }
+
+  void OnContinuationEnd() override {
+    HTTP2_VLOG(1) << "OnContinuationEnd";
+    EndFrame()->OnContinuationEnd();
+  }
+};
+
+class ContinuationPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<ContinuationPayloadDecoder,
+                                        ContinuationPayloadDecoderPeer,
+                                        Listener>,
+      public ::testing::WithParamInterface<uint32_t> {
+ protected:
+  ContinuationPayloadDecoderTest() : length_(GetParam()) {
+    HTTP2_VLOG(1) << "################  length_=" << length_
+                  << "  ################";
+  }
+
+  const uint32_t length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(VariousLengths,
+                         ContinuationPayloadDecoderTest,
+                         ::testing::Values(0, 1, 2, 3, 4, 5, 6));
+
+TEST_P(ContinuationPayloadDecoderTest, ValidLength) {
+  std::string hpack_payload = Random().RandString(length_);
+  Http2FrameHeader frame_header(length_, Http2FrameType::CONTINUATION,
+                                RandFlags(), RandStreamId());
+  set_frame_header(frame_header);
+  FrameParts expected(frame_header, hpack_payload);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(hpack_payload, expected));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/data_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/data_payload_decoder.cc
new file mode 100644
index 0000000..8f4dcdd
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/data_payload_decoder.cc
@@ -0,0 +1,128 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/data_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         DataPayloadDecoder::PayloadState v) {
+  switch (v) {
+    case DataPayloadDecoder::PayloadState::kReadPadLength:
+      return out << "kReadPadLength";
+    case DataPayloadDecoder::PayloadState::kReadPayload:
+      return out << "kReadPayload";
+    case DataPayloadDecoder::PayloadState::kSkipPadding:
+      return out << "kSkipPadding";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_174_1)
+      << "Invalid DataPayloadDecoder::PayloadState: " << unknown;
+  return out << "DataPayloadDecoder::PayloadState(" << unknown << ")";
+}
+
+DecodeStatus DataPayloadDecoder::StartDecodingPayload(FrameDecoderState* state,
+                                                      DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "DataPayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+  QUICHE_DCHECK_EQ(Http2FrameType::DATA, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::END_STREAM |
+                                             Http2FrameFlag::PADDED));
+
+  // Special case for the hoped for common case: unpadded and fits fully into
+  // the decode buffer. TO BE SEEN if that is true. It certainly requires that
+  // the transport buffers be large (e.g. >> 16KB typically).
+  // TODO(jamessynge) Add counters.
+  HTTP2_DVLOG(2) << "StartDecodingPayload total_length=" << total_length;
+  if (!frame_header.IsPadded()) {
+    HTTP2_DVLOG(2) << "StartDecodingPayload !IsPadded";
+    if (db->Remaining() == total_length) {
+      HTTP2_DVLOG(2) << "StartDecodingPayload all present";
+      // Note that we don't cache the listener field so that the callee can
+      // replace it if the frame is bad.
+      // If this case is common enough, consider combining the 3 callbacks
+      // into one.
+      state->listener()->OnDataStart(frame_header);
+      if (total_length > 0) {
+        state->listener()->OnDataPayload(db->cursor(), total_length);
+        db->AdvanceCursor(total_length);
+      }
+      state->listener()->OnDataEnd();
+      return DecodeStatus::kDecodeDone;
+    }
+    payload_state_ = PayloadState::kReadPayload;
+  } else {
+    payload_state_ = PayloadState::kReadPadLength;
+  }
+  state->InitializeRemainders();
+  state->listener()->OnDataStart(frame_header);
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus DataPayloadDecoder::ResumeDecodingPayload(FrameDecoderState* state,
+                                                       DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "DataPayloadDecoder::ResumeDecodingPayload payload_state_="
+                 << payload_state_;
+  const Http2FrameHeader& frame_header = state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::DATA, frame_header.type);
+  QUICHE_DCHECK_LE(state->remaining_payload_and_padding(),
+                   frame_header.payload_length);
+  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload_and_padding());
+  DecodeStatus status;
+  size_t avail;
+  switch (payload_state_) {
+    case PayloadState::kReadPadLength:
+      // ReadPadLength handles the OnPadLength callback, and updating the
+      // remaining_payload and remaining_padding fields. If the amount of
+      // padding is too large to fit in the frame's payload, ReadPadLength
+      // instead calls OnPaddingTooLong and returns kDecodeError.
+      status = state->ReadPadLength(db, /*report_pad_length*/ true);
+      if (status != DecodeStatus::kDecodeDone) {
+        return status;
+      }
+      ABSL_FALLTHROUGH_INTENDED;
+
+    case PayloadState::kReadPayload:
+      avail = state->AvailablePayload(db);
+      if (avail > 0) {
+        state->listener()->OnDataPayload(db->cursor(), avail);
+        db->AdvanceCursor(avail);
+        state->ConsumePayload(avail);
+      }
+      if (state->remaining_payload() > 0) {
+        payload_state_ = PayloadState::kReadPayload;
+        return DecodeStatus::kDecodeInProgress;
+      }
+      ABSL_FALLTHROUGH_INTENDED;
+
+    case PayloadState::kSkipPadding:
+      // SkipPadding handles the OnPadding callback.
+      if (state->SkipPadding(db)) {
+        state->listener()->OnDataEnd();
+        return DecodeStatus::kDecodeDone;
+      }
+      payload_state_ = PayloadState::kSkipPadding;
+      return DecodeStatus::kDecodeInProgress;
+  }
+  HTTP2_BUG(http2_bug_174_2) << "PayloadState: " << payload_state_;
+  return DecodeStatus::kDecodeError;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/data_payload_decoder.h b/quiche/http2/decoder/payload_decoders/data_payload_decoder.h
new file mode 100644
index 0000000..ffc516f
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/data_payload_decoder.h
@@ -0,0 +1,54 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_DATA_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_DATA_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a DATA frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class DataPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE DataPayloadDecoder {
+ public:
+  // States during decoding of a DATA frame.
+  enum class PayloadState {
+    // The frame is padded and we need to read the PAD_LENGTH field (1 byte),
+    // and then call OnPadLength
+    kReadPadLength,
+
+    // Report the non-padding portion of the payload to the listener's
+    // OnDataPayload method.
+    kReadPayload,
+
+    // The decoder has finished with the non-padding portion of the payload,
+    // and is now ready to skip the trailing padding, if the frame has any.
+    kSkipPadding,
+  };
+
+  // Starts decoding a DATA frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a DATA frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::DataPayloadDecoderPeer;
+
+  PayloadState payload_state_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_DATA_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/data_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/data_payload_decoder_test.cc
new file mode 100644
index 0000000..c460b0b
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/data_payload_decoder_test.cc
@@ -0,0 +1,112 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/data_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+// Provides friend access to an instance of the payload decoder, and also
+// provides info to aid in testing.
+class DataPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() { return Http2FrameType::DATA; }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
+    return Http2FrameFlag::PADDED;
+  }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnDataStart(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnDataStart: " << header;
+    StartFrame(header)->OnDataStart(header);
+  }
+
+  void OnDataPayload(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnDataPayload: len=" << len;
+    CurrentFrame()->OnDataPayload(data, len);
+  }
+
+  void OnDataEnd() override {
+    HTTP2_VLOG(1) << "OnDataEnd";
+    EndFrame()->OnDataEnd();
+  }
+
+  void OnPadLength(size_t pad_length) override {
+    HTTP2_VLOG(1) << "OnPadLength: " << pad_length;
+    CurrentFrame()->OnPadLength(pad_length);
+  }
+
+  void OnPadding(const char* padding, size_t skipped_length) override {
+    HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
+    CurrentFrame()->OnPadding(padding, skipped_length);
+  }
+
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override {
+    HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
+                  << "    missing_length: " << missing_length;
+    EndFrame()->OnPaddingTooLong(header, missing_length);
+  }
+};
+
+class DataPayloadDecoderTest
+    : public AbstractPaddablePayloadDecoderTest<DataPayloadDecoder,
+                                                DataPayloadDecoderPeer,
+                                                Listener> {
+ protected:
+  AssertionResult CreateAndDecodeDataOfSize(size_t data_size) {
+    Reset();
+    uint8_t flags = RandFlags();
+
+    std::string data_payload = Random().RandString(data_size);
+    frame_builder_.Append(data_payload);
+    MaybeAppendTrailingPadding();
+
+    Http2FrameHeader frame_header(frame_builder_.size(), Http2FrameType::DATA,
+                                  flags, RandStreamId());
+    set_frame_header(frame_header);
+    ScrubFlagsOfHeader(&frame_header);
+    FrameParts expected(frame_header, data_payload, total_pad_length_);
+    VERIFY_AND_RETURN_SUCCESS(
+        DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(), expected));
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(VariousPadLengths,
+                         DataPayloadDecoderTest,
+                         ::testing::Values(0, 1, 2, 3, 4, 254, 255, 256));
+
+TEST_P(DataPayloadDecoderTest, VariousDataPayloadSizes) {
+  for (size_t data_size : {0, 1, 2, 3, 255, 256, 1024}) {
+    EXPECT_TRUE(CreateAndDecodeDataOfSize(data_size));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.cc
new file mode 100644
index 0000000..03caac2
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.cc
@@ -0,0 +1,122 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/goaway_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         GoAwayPayloadDecoder::PayloadState v) {
+  switch (v) {
+    case GoAwayPayloadDecoder::PayloadState::kStartDecodingFixedFields:
+      return out << "kStartDecodingFixedFields";
+    case GoAwayPayloadDecoder::PayloadState::kHandleFixedFieldsStatus:
+      return out << "kHandleFixedFieldsStatus";
+    case GoAwayPayloadDecoder::PayloadState::kReadOpaqueData:
+      return out << "kReadOpaqueData";
+    case GoAwayPayloadDecoder::PayloadState::kResumeDecodingFixedFields:
+      return out << "kResumeDecodingFixedFields";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_167_1)
+      << "Invalid GoAwayPayloadDecoder::PayloadState: " << unknown;
+  return out << "GoAwayPayloadDecoder::PayloadState(" << unknown << ")";
+}
+
+DecodeStatus GoAwayPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "GoAwayPayloadDecoder::StartDecodingPayload: "
+                 << state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::GOAWAY, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
+
+  state->InitializeRemainders();
+  payload_state_ = PayloadState::kStartDecodingFixedFields;
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus GoAwayPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2)
+      << "GoAwayPayloadDecoder::ResumeDecodingPayload: remaining_payload="
+      << state->remaining_payload() << ", db->Remaining=" << db->Remaining();
+
+  const Http2FrameHeader& frame_header = state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::GOAWAY, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
+  QUICHE_DCHECK_NE(PayloadState::kHandleFixedFieldsStatus, payload_state_);
+
+  // |status| has to be initialized to some value to avoid compiler error in
+  // case PayloadState::kHandleFixedFieldsStatus below, but value does not
+  // matter, see QUICHE_DCHECK_NE above.
+  DecodeStatus status = DecodeStatus::kDecodeError;
+  size_t avail;
+  while (true) {
+    HTTP2_DVLOG(2)
+        << "GoAwayPayloadDecoder::ResumeDecodingPayload payload_state_="
+        << payload_state_;
+    switch (payload_state_) {
+      case PayloadState::kStartDecodingFixedFields:
+        status = state->StartDecodingStructureInPayload(&goaway_fields_, db);
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kHandleFixedFieldsStatus:
+        if (status == DecodeStatus::kDecodeDone) {
+          state->listener()->OnGoAwayStart(frame_header, goaway_fields_);
+        } else {
+          // Not done decoding the structure. Either we've got more payload
+          // to decode, or we've run out because the payload is too short,
+          // in which case OnFrameSizeError will have already been called.
+          QUICHE_DCHECK((status == DecodeStatus::kDecodeInProgress &&
+                         state->remaining_payload() > 0) ||
+                        (status == DecodeStatus::kDecodeError &&
+                         state->remaining_payload() == 0))
+              << "\n status=" << status
+              << "; remaining_payload=" << state->remaining_payload();
+          payload_state_ = PayloadState::kResumeDecodingFixedFields;
+          return status;
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kReadOpaqueData:
+        // The opaque data is all the remains to be decoded, so anything left
+        // in the decode buffer is opaque data.
+        avail = db->Remaining();
+        if (avail > 0) {
+          state->listener()->OnGoAwayOpaqueData(db->cursor(), avail);
+          db->AdvanceCursor(avail);
+          state->ConsumePayload(avail);
+        }
+        if (state->remaining_payload() > 0) {
+          payload_state_ = PayloadState::kReadOpaqueData;
+          return DecodeStatus::kDecodeInProgress;
+        }
+        state->listener()->OnGoAwayEnd();
+        return DecodeStatus::kDecodeDone;
+
+      case PayloadState::kResumeDecodingFixedFields:
+        status = state->ResumeDecodingStructureInPayload(&goaway_fields_, db);
+        payload_state_ = PayloadState::kHandleFixedFieldsStatus;
+        continue;
+    }
+    HTTP2_BUG(http2_bug_167_2) << "PayloadState: " << payload_state_;
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.h b/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.h
new file mode 100644
index 0000000..2664642
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.h
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_GOAWAY_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_GOAWAY_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a GOAWAY frame.
+
+// TODO(jamessynge): Sweep through all payload decoders, changing the names of
+// the PayloadState enums so that they are really states, and not actions.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class GoAwayPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE GoAwayPayloadDecoder {
+ public:
+  // States during decoding of a GOAWAY frame.
+  enum class PayloadState {
+    // At the start of the GOAWAY frame payload, ready to start decoding the
+    // fixed size fields into goaway_fields_.
+    kStartDecodingFixedFields,
+
+    // Handle the DecodeStatus returned from starting or resuming the
+    // decoding of Http2GoAwayFields into goaway_fields_. If complete,
+    // calls OnGoAwayStart.
+    kHandleFixedFieldsStatus,
+
+    // Report the Opaque Data portion of the payload to the listener's
+    // OnGoAwayOpaqueData method, and call OnGoAwayEnd when the end of the
+    // payload is reached.
+    kReadOpaqueData,
+
+    // The fixed size fields weren't all available when the decoder first
+    // tried to decode them (state kStartDecodingFixedFields); this state
+    // resumes the decoding when ResumeDecodingPayload is called later.
+    kResumeDecodingFixedFields,
+  };
+
+  // Starts the decoding of a GOAWAY frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a GOAWAY frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::GoAwayPayloadDecoderPeer;
+
+  Http2GoAwayFields goaway_fields_;
+  PayloadState payload_state_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_GOAWAY_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
new file mode 100644
index 0000000..ab113b0
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
@@ -0,0 +1,110 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/goaway_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class GoAwayPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() { return Http2FrameType::GOAWAY; }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnGoAwayStart(const Http2FrameHeader& header,
+                     const Http2GoAwayFields& goaway) override {
+    HTTP2_VLOG(1) << "OnGoAwayStart header: " << header
+                  << "; goaway: " << goaway;
+    StartFrame(header)->OnGoAwayStart(header, goaway);
+  }
+
+  void OnGoAwayOpaqueData(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
+    CurrentFrame()->OnGoAwayOpaqueData(data, len);
+  }
+
+  void OnGoAwayEnd() override {
+    HTTP2_VLOG(1) << "OnGoAwayEnd";
+    EndFrame()->OnGoAwayEnd();
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class GoAwayPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<GoAwayPayloadDecoder,
+                                        GoAwayPayloadDecoderPeer,
+                                        Listener> {};
+
+// Confirm we get an error if the payload is not long enough to hold
+// Http2GoAwayFields.
+TEST_F(GoAwayPayloadDecoderTest, Truncated) {
+  auto approve_size = [](size_t size) {
+    return size != Http2GoAwayFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(Http2GoAwayFields(123, Http2ErrorCode::ENHANCE_YOUR_CALM));
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+class GoAwayOpaqueDataLengthTests
+    : public GoAwayPayloadDecoderTest,
+      public ::testing::WithParamInterface<uint32_t> {
+ protected:
+  GoAwayOpaqueDataLengthTests() : length_(GetParam()) {
+    HTTP2_VLOG(1) << "################  length_=" << length_
+                  << "  ################";
+  }
+
+  const uint32_t length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(VariousLengths,
+                         GoAwayOpaqueDataLengthTests,
+                         ::testing::Values(0, 1, 2, 3, 4, 5, 6));
+
+TEST_P(GoAwayOpaqueDataLengthTests, ValidLength) {
+  Http2GoAwayFields goaway;
+  Randomize(&goaway, RandomPtr());
+  std::string opaque_data = Random().RandString(length_);
+  Http2FrameBuilder fb;
+  fb.Append(goaway);
+  fb.Append(opaque_data);
+  Http2FrameHeader header(fb.size(), Http2FrameType::GOAWAY, RandFlags(),
+                          RandStreamId());
+  set_frame_header(header);
+  FrameParts expected(header, opaque_data);
+  expected.SetOptGoaway(goaway);
+  ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/headers_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/headers_payload_decoder.cc
new file mode 100644
index 0000000..e64f959
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/headers_payload_decoder.cc
@@ -0,0 +1,178 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/headers_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         HeadersPayloadDecoder::PayloadState v) {
+  switch (v) {
+    case HeadersPayloadDecoder::PayloadState::kReadPadLength:
+      return out << "kReadPadLength";
+    case HeadersPayloadDecoder::PayloadState::kStartDecodingPriorityFields:
+      return out << "kStartDecodingPriorityFields";
+    case HeadersPayloadDecoder::PayloadState::kResumeDecodingPriorityFields:
+      return out << "kResumeDecodingPriorityFields";
+    case HeadersPayloadDecoder::PayloadState::kReadPayload:
+      return out << "kReadPayload";
+    case HeadersPayloadDecoder::PayloadState::kSkipPadding:
+      return out << "kSkipPadding";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_189_1)
+      << "Invalid HeadersPayloadDecoder::PayloadState: " << unknown;
+  return out << "HeadersPayloadDecoder::PayloadState(" << unknown << ")";
+}
+
+DecodeStatus HeadersPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "HeadersPayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+
+  QUICHE_DCHECK_EQ(Http2FrameType::HEADERS, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+  QUICHE_DCHECK_EQ(
+      0, frame_header.flags &
+             ~(Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS |
+               Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY));
+
+  // Special case for HEADERS frames that contain only the HPACK block
+  // (fragment or whole) and that fit fully into the decode buffer.
+  // Why? Unencoded browser GET requests are typically under 1K and HPACK
+  // commonly shrinks request headers by 80%, so we can expect this to
+  // be common.
+  // TODO(jamessynge) Add counters here and to Spdy for determining how
+  // common this situation is. A possible approach is to create a
+  // Http2FrameDecoderListener that counts the callbacks and then forwards
+  // them on to another listener, which makes it easy to add and remove
+  // counting on a connection or even frame basis.
+
+  // PADDED and PRIORITY both extra steps to decode, but if neither flag is
+  // set then we can decode faster.
+  const auto payload_flags = Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY;
+  if (!frame_header.HasAnyFlags(payload_flags)) {
+    HTTP2_DVLOG(2) << "StartDecodingPayload !IsPadded && !HasPriority";
+    if (db->Remaining() == total_length) {
+      HTTP2_DVLOG(2) << "StartDecodingPayload all present";
+      // Note that we don't cache the listener field so that the callee can
+      // replace it if the frame is bad.
+      // If this case is common enough, consider combining the 3 callbacks
+      // into one, especially if END_HEADERS is also set.
+      state->listener()->OnHeadersStart(frame_header);
+      if (total_length > 0) {
+        state->listener()->OnHpackFragment(db->cursor(), total_length);
+        db->AdvanceCursor(total_length);
+      }
+      state->listener()->OnHeadersEnd();
+      return DecodeStatus::kDecodeDone;
+    }
+    payload_state_ = PayloadState::kReadPayload;
+  } else if (frame_header.IsPadded()) {
+    payload_state_ = PayloadState::kReadPadLength;
+  } else {
+    QUICHE_DCHECK(frame_header.HasPriority()) << frame_header;
+    payload_state_ = PayloadState::kStartDecodingPriorityFields;
+  }
+  state->InitializeRemainders();
+  state->listener()->OnHeadersStart(frame_header);
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus HeadersPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "HeadersPayloadDecoder::ResumeDecodingPayload "
+                 << "remaining_payload=" << state->remaining_payload()
+                 << "; db->Remaining=" << db->Remaining();
+
+  const Http2FrameHeader& frame_header = state->frame_header();
+
+  QUICHE_DCHECK_EQ(Http2FrameType::HEADERS, frame_header.type);
+  QUICHE_DCHECK_LE(state->remaining_payload_and_padding(),
+                   frame_header.payload_length);
+  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload_and_padding());
+  DecodeStatus status;
+  size_t avail;
+  while (true) {
+    HTTP2_DVLOG(2)
+        << "HeadersPayloadDecoder::ResumeDecodingPayload payload_state_="
+        << payload_state_;
+    switch (payload_state_) {
+      case PayloadState::kReadPadLength:
+        // ReadPadLength handles the OnPadLength callback, and updating the
+        // remaining_payload and remaining_padding fields. If the amount of
+        // padding is too large to fit in the frame's payload, ReadPadLength
+        // instead calls OnPaddingTooLong and returns kDecodeError.
+        status = state->ReadPadLength(db, /*report_pad_length*/ true);
+        if (status != DecodeStatus::kDecodeDone) {
+          return status;
+        }
+        if (!frame_header.HasPriority()) {
+          payload_state_ = PayloadState::kReadPayload;
+          continue;
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kStartDecodingPriorityFields:
+        status = state->StartDecodingStructureInPayload(&priority_fields_, db);
+        if (status != DecodeStatus::kDecodeDone) {
+          payload_state_ = PayloadState::kResumeDecodingPriorityFields;
+          return status;
+        }
+        state->listener()->OnHeadersPriority(priority_fields_);
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kReadPayload:
+        avail = state->AvailablePayload(db);
+        if (avail > 0) {
+          state->listener()->OnHpackFragment(db->cursor(), avail);
+          db->AdvanceCursor(avail);
+          state->ConsumePayload(avail);
+        }
+        if (state->remaining_payload() > 0) {
+          payload_state_ = PayloadState::kReadPayload;
+          return DecodeStatus::kDecodeInProgress;
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kSkipPadding:
+        // SkipPadding handles the OnPadding callback.
+        if (state->SkipPadding(db)) {
+          state->listener()->OnHeadersEnd();
+          return DecodeStatus::kDecodeDone;
+        }
+        payload_state_ = PayloadState::kSkipPadding;
+        return DecodeStatus::kDecodeInProgress;
+
+      case PayloadState::kResumeDecodingPriorityFields:
+        status = state->ResumeDecodingStructureInPayload(&priority_fields_, db);
+        if (status != DecodeStatus::kDecodeDone) {
+          return status;
+        }
+        state->listener()->OnHeadersPriority(priority_fields_);
+        payload_state_ = PayloadState::kReadPayload;
+        continue;
+    }
+    HTTP2_BUG(http2_bug_189_2) << "PayloadState: " << payload_state_;
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/headers_payload_decoder.h b/quiche/http2/decoder/payload_decoders/headers_payload_decoder.h
new file mode 100644
index 0000000..e76908b
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/headers_payload_decoder.h
@@ -0,0 +1,67 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_HEADERS_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_HEADERS_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a HEADERS frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class HeadersPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE HeadersPayloadDecoder {
+ public:
+  // States during decoding of a HEADERS frame, unless the fast path kicks
+  // in, in which case the state machine will be bypassed.
+  enum class PayloadState {
+    // The PADDED flag is set, and we now need to read the Pad Length field
+    // (the first byte of the payload, after the common frame header).
+    kReadPadLength,
+
+    // The PRIORITY flag is set, and we now need to read the fixed size priority
+    // fields (E, Stream Dependency, Weight) into priority_fields_.  Calls on
+    // OnHeadersPriority if completely decodes those fields.
+    kStartDecodingPriorityFields,
+
+    // The decoder passes the non-padding portion of the remaining payload
+    // (i.e. the HPACK block fragment) to the listener's OnHpackFragment method.
+    kReadPayload,
+
+    // The decoder has finished with the HPACK block fragment, and is now
+    // ready to skip the trailing padding, if the frame has any.
+    kSkipPadding,
+
+    // The fixed size fields weren't all available when the decoder first tried
+    // to decode them (state kStartDecodingPriorityFields); this state resumes
+    // the decoding when ResumeDecodingPayload is called later.
+    kResumeDecodingPriorityFields,
+  };
+
+  // Starts the decoding of a HEADERS frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a HEADERS frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::HeadersPayloadDecoderPeer;
+
+  PayloadState payload_state_;
+  Http2PriorityFields priority_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_HEADERS_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/headers_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
new file mode 100644
index 0000000..f6f0df5
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
@@ -0,0 +1,160 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/headers_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class HeadersPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::HEADERS;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
+    return Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY;
+  }
+};
+
+namespace {
+
+// Listener handles all On* methods that are expected to be called. If any other
+// On* methods of Http2FrameDecoderListener is called then the test fails; this
+// is achieved by way of FailingHttp2FrameDecoderListener, the base class of
+// FramePartsCollector.
+// These On* methods make use of StartFrame, EndFrame, etc. of the base class
+// to create and access to FrameParts instance(s) that will record the details.
+// After decoding, the test validation code can access the FramePart instance(s)
+// via the public methods of FramePartsCollector.
+struct Listener : public FramePartsCollector {
+  void OnHeadersStart(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnHeadersStart: " << header;
+    StartFrame(header)->OnHeadersStart(header);
+  }
+
+  void OnHeadersPriority(const Http2PriorityFields& priority) override {
+    HTTP2_VLOG(1) << "OnHeadersPriority: " << priority;
+    CurrentFrame()->OnHeadersPriority(priority);
+  }
+
+  void OnHpackFragment(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
+    CurrentFrame()->OnHpackFragment(data, len);
+  }
+
+  void OnHeadersEnd() override {
+    HTTP2_VLOG(1) << "OnHeadersEnd";
+    EndFrame()->OnHeadersEnd();
+  }
+
+  void OnPadLength(size_t pad_length) override {
+    HTTP2_VLOG(1) << "OnPadLength: " << pad_length;
+    CurrentFrame()->OnPadLength(pad_length);
+  }
+
+  void OnPadding(const char* padding, size_t skipped_length) override {
+    HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
+    CurrentFrame()->OnPadding(padding, skipped_length);
+  }
+
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override {
+    HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
+                  << "; missing_length: " << missing_length;
+    FrameError(header)->OnPaddingTooLong(header, missing_length);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class HeadersPayloadDecoderTest
+    : public AbstractPaddablePayloadDecoderTest<HeadersPayloadDecoder,
+                                                HeadersPayloadDecoderPeer,
+                                                Listener> {};
+
+INSTANTIATE_TEST_SUITE_P(VariousPadLengths,
+                         HeadersPayloadDecoderTest,
+                         ::testing::Values(0, 1, 2, 3, 4, 254, 255, 256));
+
+// Decode various sizes of (fake) HPACK payload, both with and without the
+// PRIORITY flag set.
+TEST_P(HeadersPayloadDecoderTest, VariousHpackPayloadSizes) {
+  for (size_t hpack_size : {0, 1, 2, 3, 255, 256, 1024}) {
+    HTTP2_LOG(INFO) << "###########   hpack_size = " << hpack_size
+                    << "  ###########";
+    Http2PriorityFields priority(RandStreamId(), 1 + Random().Rand8(),
+                                 Random().OneIn(2));
+
+    for (bool has_priority : {false, true}) {
+      Reset();
+      ASSERT_EQ(IsPadded() ? 1u : 0u, frame_builder_.size());
+      uint8_t flags = RandFlags();
+      if (has_priority) {
+        flags |= Http2FrameFlag::PRIORITY;
+        frame_builder_.Append(priority);
+      }
+
+      std::string hpack_payload = Random().RandString(hpack_size);
+      frame_builder_.Append(hpack_payload);
+
+      MaybeAppendTrailingPadding();
+      Http2FrameHeader frame_header(frame_builder_.size(),
+                                    Http2FrameType::HEADERS, flags,
+                                    RandStreamId());
+      set_frame_header(frame_header);
+      ScrubFlagsOfHeader(&frame_header);
+      FrameParts expected(frame_header, hpack_payload, total_pad_length_);
+      if (has_priority) {
+        expected.SetOptPriority(priority);
+      }
+      EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(),
+                                                      expected));
+    }
+  }
+}
+
+// Confirm we get an error if the PRIORITY flag is set but the payload is
+// not long enough, regardless of the amount of (valid) padding.
+TEST_P(HeadersPayloadDecoderTest, Truncated) {
+  auto approve_size = [](size_t size) {
+    return size != Http2PriorityFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(Http2PriorityFields(RandStreamId(), 1 + Random().Rand8(),
+                                Random().OneIn(2)));
+  EXPECT_TRUE(VerifyDetectsMultipleFrameSizeErrors(
+      Http2FrameFlag::PRIORITY, fb.buffer(), approve_size, total_pad_length_));
+}
+
+// Confirm we get an error if the PADDED flag is set but the payload is not
+// long enough to hold even the Pad Length amount of padding.
+TEST_P(HeadersPayloadDecoderTest, PaddingTooLong) {
+  EXPECT_TRUE(VerifyDetectsPaddingTooLong());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc b/quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc
new file mode 100644
index 0000000..a0d488d
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.cc
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+
+#include "quiche/http2/decoder/frame_decoder_state_test_util.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+PayloadDecoderBaseTest::PayloadDecoderBaseTest() {
+  // If the test adds more data after the frame payload,
+  // stop as soon as the payload is decoded.
+  stop_decode_on_done_ = true;
+  frame_header_is_set_ = false;
+  Randomize(&frame_header_, RandomPtr());
+}
+
+DecodeStatus PayloadDecoderBaseTest::StartDecoding(DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining();
+  // Make sure sub-class has set frame_header_ so that we can inject it
+  // into the payload decoder below.
+  if (!frame_header_is_set_) {
+    ADD_FAILURE() << "frame_header_ is not set";
+    return DecodeStatus::kDecodeError;
+  }
+  // The contract with the payload decoders is that they won't receive a
+  // decode buffer that extends beyond the end of the frame.
+  if (db->Remaining() > frame_header_.payload_length) {
+    ADD_FAILURE() << "DecodeBuffer has too much data: " << db->Remaining()
+                  << " > " << frame_header_.payload_length;
+    return DecodeStatus::kDecodeError;
+  }
+
+  // Prepare the payload decoder.
+  PreparePayloadDecoder();
+
+  // Reconstruct the FrameDecoderState, prepare the listener, and add it to
+  // the FrameDecoderState.
+  frame_decoder_state_ = std::make_unique<FrameDecoderState>();
+  frame_decoder_state_->set_listener(PrepareListener());
+
+  // Make sure that a listener was provided.
+  if (frame_decoder_state_->listener() == nullptr) {
+    ADD_FAILURE() << "PrepareListener must return a listener.";
+    return DecodeStatus::kDecodeError;
+  }
+
+  // Now that nothing in the payload decoder should be valid, inject the
+  // Http2FrameHeader whose payload we're about to decode. That header is the
+  // only state that a payload decoder should expect is valid when its Start
+  // method is called.
+  FrameDecoderStatePeer::set_frame_header(frame_header_,
+                                          frame_decoder_state_.get());
+  DecodeStatus status = StartDecodingPayload(db);
+  if (status != DecodeStatus::kDecodeInProgress) {
+    // Keep track of this so that a concrete test can verify that both fast
+    // and slow decoding paths have been tested.
+    ++fast_decode_count_;
+  }
+  return status;
+}
+
+DecodeStatus PayloadDecoderBaseTest::ResumeDecoding(DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining();
+  DecodeStatus status = ResumeDecodingPayload(db);
+  if (status != DecodeStatus::kDecodeInProgress) {
+    // Keep track of this so that a concrete test can verify that both fast
+    // and slow decoding paths have been tested.
+    ++slow_decode_count_;
+  }
+  return status;
+}
+
+::testing::AssertionResult
+PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
+    absl::string_view payload,
+    Validator validator) {
+  VERIFY_TRUE(frame_header_is_set_);
+  // Cap the payload to be decoded at the declared payload length. This is
+  // required by the decoders' preconditions; they are designed on the
+  // assumption that they're never passed more than they're permitted to
+  // consume.
+  // Note that it is OK if the payload is too short; the validator may be
+  // designed to check for that.
+  if (payload.size() > frame_header_.payload_length) {
+    payload = absl::string_view(payload.data(), frame_header_.payload_length);
+  }
+  DecodeBuffer db(payload);
+  ResetDecodeSpeedCounters();
+  const bool kMayReturnZeroOnFirst = false;
+  return DecodeAndValidateSeveralWays(&db, kMayReturnZeroOnFirst, validator);
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h b/quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
new file mode 100644
index 0000000..5eead55
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
@@ -0,0 +1,449 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
+
+// Base class for testing concrete payload decoder classes.
+
+#include <stddef.h>
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_constants_test_util.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+
+namespace http2 {
+namespace test {
+
+// Base class for tests of payload decoders. Below this there is a templated
+// sub-class that adds a bunch of type specific features.
+class PayloadDecoderBaseTest : public RandomDecoderTest {
+ protected:
+  PayloadDecoderBaseTest();
+
+  // Virtual functions to be implemented by the test classes for the individual
+  // payload decoders...
+
+  // Start decoding the payload.
+  virtual DecodeStatus StartDecodingPayload(DecodeBuffer* db) = 0;
+
+  // Resume decoding the payload.
+  virtual DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) = 0;
+
+  // In support of ensuring that we're really accessing and updating the
+  // decoder, prepare the decoder by, for example, overwriting the decoder.
+  virtual void PreparePayloadDecoder() = 0;
+
+  // Get the listener to be inserted into the FrameDecoderState, ready for
+  // listening (e.g. reset if it is a FramePartsCollector).
+  virtual Http2FrameDecoderListener* PrepareListener() = 0;
+
+  // Record a frame header for use on each call to StartDecoding.
+  void set_frame_header(const Http2FrameHeader& header) {
+    EXPECT_EQ(0, InvalidFlagMaskForFrameType(header.type) & header.flags);
+    if (!frame_header_is_set_ || frame_header_ != header) {
+      HTTP2_VLOG(2) << "set_frame_header: " << frame_header_;
+    }
+    frame_header_ = header;
+    frame_header_is_set_ = true;
+  }
+
+  FrameDecoderState* mutable_state() { return frame_decoder_state_.get(); }
+
+  // Randomize the payload decoder, sets the payload decoder's frame_header_,
+  // then start decoding the payload. Called by RandomDecoderTest. This method
+  // is final so that we can always perform certain actions when
+  // RandomDecoderTest starts the decoding of a payload, such as randomizing the
+  // the payload decoder, injecting the frame header and counting fast decoding
+  // cases. Sub-classes must implement StartDecodingPayload to perform their
+  // initial decoding of a frame's payload.
+  DecodeStatus StartDecoding(DecodeBuffer* db) final;
+
+  // Called by RandomDecoderTest. This method is final so that we can always
+  // perform certain actions when RandomDecoderTest calls it, such as counting
+  // slow decode cases. Sub-classes must implement ResumeDecodingPayload to
+  // continue decoding the frame's payload, which must not all be in one buffer.
+  DecodeStatus ResumeDecoding(DecodeBuffer* db) final;
+
+  // Given the specified payload (without the common frame header), decode
+  // it with several partitionings of the payload.
+  ::testing::AssertionResult DecodePayloadAndValidateSeveralWays(
+      absl::string_view payload,
+      Validator validator);
+
+  // TODO(jamessynge): Add helper method for verifying these are both non-zero,
+  // and call the new method from tests that expect successful decoding.
+  void ResetDecodeSpeedCounters() {
+    fast_decode_count_ = 0;
+    slow_decode_count_ = 0;
+  }
+
+  // Count of payloads that are full decoded by StartDecodingPayload, or that
+  // an error was detected by StartDecodingPayload.
+  size_t fast_decode_count_ = 0;
+
+  // Count of payloads that require calling ResumeDecodingPayload in order to
+  // decode them completely (or to detect an error during decoding).
+  size_t slow_decode_count_ = 0;
+
+ private:
+  bool frame_header_is_set_ = false;
+  Http2FrameHeader frame_header_;
+  std::unique_ptr<FrameDecoderState> frame_decoder_state_;
+};
+
+// Base class for payload decoders of type Decoder, with corresponding test
+// peer of type DecoderPeer, and using class Listener as the implementation
+// of Http2FrameDecoderListenerInterface to be used during decoding.
+// Typically Listener is a sub-class of FramePartsCollector.
+// SupportedFrameType is set to false only for UnknownPayloadDecoder.
+template <class Decoder,
+          class DecoderPeer,
+          class Listener,
+          bool SupportedFrameType = true>
+class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest {
+ protected:
+  // An ApproveSize function returns true to approve decoding the specified
+  // size of payload, else false to skip that size. Typically used for negative
+  // tests; for example, decoding a SETTINGS frame at all sizes except for
+  // multiples of 6.
+  typedef std::function<bool(size_t size)> ApproveSize;
+
+  AbstractPayloadDecoderTest() {}
+
+  // These tests are in setup rather than the constructor for two reasons:
+  // 1) Constructors are not allowed to fail, so gUnit documents that EXPECT_*
+  //    and ASSERT_* are not allowed in constructors, and should instead be in
+  //    SetUp if they are needed before the body of the test is executed.
+  // 2) To allow the sub-class constructor to make any desired modifications to
+  //    the DecoderPeer before these tests are executed; in particular,
+  //    UnknownPayloadDecoderPeer has not got a fixed frame type, but it is
+  //    instead set during the test's constructor.
+  void SetUp() override {
+    PayloadDecoderBaseTest::SetUp();
+
+    // Confirm that DecoderPeer et al returns sensible values. Using auto as the
+    // variable type so that no (narrowing) conversions take place that hide
+    // problems; i.e. if someone changes KnownFlagsMaskForFrameType so that it
+    // doesn't return a uint8, and has bits above the low-order 8 bits set, this
+    // bit of paranoia should detect the problem before we get too far.
+    auto frame_type = DecoderPeer::FrameType();
+    if (SupportedFrameType) {
+      EXPECT_TRUE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
+    } else {
+      EXPECT_FALSE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
+    }
+
+    auto known_flags = KnownFlagsMaskForFrameType(frame_type);
+    EXPECT_EQ(known_flags, known_flags & 0xff);
+
+    auto flags_to_avoid = DecoderPeer::FlagsAffectingPayloadDecoding();
+    EXPECT_EQ(flags_to_avoid, flags_to_avoid & known_flags);
+  }
+
+  void PreparePayloadDecoder() override {
+    payload_decoder_ = std::make_unique<Decoder>();
+  }
+
+  Http2FrameDecoderListener* PrepareListener() override {
+    listener_.Reset();
+    return &listener_;
+  }
+
+  // Returns random flags, but only those valid for the frame type, yet not
+  // those that the DecoderPeer says will affect the decoding of the payload
+  // (e.g. the PRIORTY flag on a HEADERS frame or PADDED on DATA frames).
+  uint8_t RandFlags() {
+    return Random().Rand8() &
+           KnownFlagsMaskForFrameType(DecoderPeer::FrameType()) &
+           ~DecoderPeer::FlagsAffectingPayloadDecoding();
+  }
+
+  // Start decoding the payload.
+  DecodeStatus StartDecodingPayload(DecodeBuffer* db) override {
+    HTTP2_DVLOG(2) << "StartDecodingPayload, db->Remaining=" << db->Remaining();
+    return payload_decoder_->StartDecodingPayload(mutable_state(), db);
+  }
+
+  // Resume decoding the payload.
+  DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) override {
+    HTTP2_DVLOG(2) << "ResumeDecodingPayload, db->Remaining="
+                   << db->Remaining();
+    return payload_decoder_->ResumeDecodingPayload(mutable_state(), db);
+  }
+
+  // Decode one frame's payload and confirm that the listener recorded the
+  // expected FrameParts instance, and only FrameParts instance. The payload
+  // will be decoded several times with different partitionings of the payload,
+  // and after each the validator will be called.
+  AssertionResult DecodePayloadAndValidateSeveralWays(
+      absl::string_view payload,
+      const FrameParts& expected) {
+    auto validator = [&expected, this]() -> AssertionResult {
+      VERIFY_FALSE(listener_.IsInProgress());
+      VERIFY_EQ(1u, listener_.size());
+      VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*listener_.frame(0)));
+    };
+    return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
+        payload, ValidateDoneAndEmpty(validator));
+  }
+
+  // Decode one frame's payload, expecting that the final status will be
+  // kDecodeError, and that OnFrameSizeError will have been called on the
+  // listener. The payload will be decoded several times with different
+  // partitionings of the payload. The type WrappedValidator is either
+  // RandomDecoderTest::Validator, RandomDecoderTest::NoArgValidator or
+  // std::nullptr_t (not extra validation).
+  template <typename WrappedValidator>
+  ::testing::AssertionResult VerifyDetectsFrameSizeError(
+      absl::string_view payload,
+      const Http2FrameHeader& header,
+      WrappedValidator wrapped_validator) {
+    set_frame_header(header);
+    // If wrapped_validator is not a RandomDecoderTest::Validator, make it so.
+    Validator validator = ToValidator(wrapped_validator);
+    // And wrap that validator in another which will check that we've reached
+    // the expected state of kDecodeError with OnFrameSizeError having been
+    // called by the payload decoder.
+    validator = [header, validator, this](
+                    const DecodeBuffer& input,
+                    DecodeStatus status) -> ::testing::AssertionResult {
+      HTTP2_DVLOG(2) << "VerifyDetectsFrameSizeError validator; status="
+                     << status << "; input.Remaining=" << input.Remaining();
+      VERIFY_EQ(DecodeStatus::kDecodeError, status);
+      VERIFY_FALSE(listener_.IsInProgress());
+      VERIFY_EQ(1u, listener_.size());
+      const FrameParts* frame = listener_.frame(0);
+      VERIFY_EQ(header, frame->GetFrameHeader());
+      VERIFY_TRUE(frame->GetHasFrameSizeError());
+      // Verify did not get OnPaddingTooLong, as we should only ever produce
+      // one of these two errors for a single frame.
+      VERIFY_FALSE(frame->GetOptMissingLength());
+      return validator(input, status);
+    };
+    VERIFY_AND_RETURN_SUCCESS(
+        PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(payload,
+                                                                    validator));
+  }
+
+  // Confirm that we get OnFrameSizeError when trying to decode unpadded_payload
+  // at all sizes from zero to unpadded_payload.size(), except those sizes not
+  // approved by approve_size.
+  // If total_pad_length is greater than zero, then that amount of padding
+  // is added to the payload (including the Pad Length field).
+  // The flags will be required_flags, PADDED if total_pad_length > 0, and some
+  // randomly selected flag bits not excluded by FlagsAffectingPayloadDecoding.
+  ::testing::AssertionResult VerifyDetectsMultipleFrameSizeErrors(
+      uint8_t required_flags,
+      absl::string_view unpadded_payload,
+      ApproveSize approve_size,
+      int total_pad_length) {
+    // required_flags should come from those that are defined for the frame
+    // type AND are those that affect the decoding of the payload (otherwise,
+    // the flag shouldn't be required).
+    Http2FrameType frame_type = DecoderPeer::FrameType();
+    VERIFY_EQ(required_flags,
+              required_flags & KnownFlagsMaskForFrameType(frame_type));
+    VERIFY_EQ(required_flags,
+              required_flags & DecoderPeer::FlagsAffectingPayloadDecoding());
+
+    if (0 !=
+        (Http2FrameFlag::PADDED & KnownFlagsMaskForFrameType(frame_type))) {
+      // Frame type supports padding.
+      if (total_pad_length == 0) {
+        required_flags &= ~Http2FrameFlag::PADDED;
+      } else {
+        required_flags |= Http2FrameFlag::PADDED;
+      }
+    } else {
+      VERIFY_EQ(0, total_pad_length);
+    }
+
+    bool validated = false;
+    for (size_t real_payload_size = 0;
+         real_payload_size <= unpadded_payload.size(); ++real_payload_size) {
+      if (approve_size != nullptr && !approve_size(real_payload_size)) {
+        continue;
+      }
+      HTTP2_VLOG(1) << "real_payload_size=" << real_payload_size;
+      uint8_t flags = required_flags | RandFlags();
+      Http2FrameBuilder fb;
+      if (total_pad_length > 0) {
+        // total_pad_length_ includes the size of the Pad Length field, and thus
+        // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
+        fb.AppendUInt8(total_pad_length - 1);
+      }
+      // Append a subset of the unpadded_payload, which the decoder should
+      // determine is not a valid amount.
+      fb.Append(unpadded_payload.substr(0, real_payload_size));
+      if (total_pad_length > 0) {
+        fb.AppendZeroes(total_pad_length - 1);
+      }
+      // We choose a random stream id because the payload decoders aren't
+      // checking stream ids.
+      uint32_t stream_id = RandStreamId();
+      Http2FrameHeader header(fb.size(), frame_type, flags, stream_id);
+      VERIFY_SUCCESS(VerifyDetectsFrameSizeError(fb.buffer(), header, nullptr));
+      validated = true;
+    }
+    VERIFY_TRUE(validated);
+    return ::testing::AssertionSuccess();
+  }
+
+  // As above, but for frames without padding.
+  ::testing::AssertionResult VerifyDetectsFrameSizeError(
+      uint8_t required_flags,
+      absl::string_view unpadded_payload,
+      const ApproveSize& approve_size) {
+    Http2FrameType frame_type = DecoderPeer::FrameType();
+    uint8_t known_flags = KnownFlagsMaskForFrameType(frame_type);
+    VERIFY_EQ(0, known_flags & Http2FrameFlag::PADDED);
+    VERIFY_EQ(0, required_flags & Http2FrameFlag::PADDED);
+    VERIFY_AND_RETURN_SUCCESS(VerifyDetectsMultipleFrameSizeErrors(
+        required_flags, unpadded_payload, approve_size, 0));
+  }
+
+  Listener listener_;
+  std::unique_ptr<Decoder> payload_decoder_;
+};
+
+// A base class for tests parameterized by the total number of bytes of
+// padding, including the Pad Length field (i.e. a total_pad_length of 0
+// means unpadded as there is then no room for the Pad Length field).
+// The frame type must support padding.
+template <class Decoder, class DecoderPeer, class Listener>
+class AbstractPaddablePayloadDecoderTest
+    : public AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener>,
+      public ::testing::WithParamInterface<int> {
+  typedef AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener> Base;
+
+ protected:
+  using Base::listener_;
+  using Base::Random;
+  using Base::RandStreamId;
+  using Base::set_frame_header;
+  typedef typename Base::Validator Validator;
+
+  AbstractPaddablePayloadDecoderTest() : total_pad_length_(GetParam()) {
+    HTTP2_LOG(INFO) << "total_pad_length_ = " << total_pad_length_;
+  }
+
+  // Note that total_pad_length_ includes the size of the Pad Length field,
+  // and thus ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
+  bool IsPadded() const { return total_pad_length_ > 0; }
+
+  // Value of the Pad Length field. Only call if IsPadded.
+  size_t pad_length() const {
+    EXPECT_TRUE(IsPadded());
+    return total_pad_length_ - 1;
+  }
+
+  // Clear the frame builder and add the Pad Length field if appropriate.
+  void Reset() {
+    frame_builder_ = Http2FrameBuilder();
+    if (IsPadded()) {
+      frame_builder_.AppendUInt8(pad_length());
+    }
+  }
+
+  void MaybeAppendTrailingPadding() {
+    if (IsPadded()) {
+      frame_builder_.AppendZeroes(pad_length());
+    }
+  }
+
+  uint8_t RandFlags() {
+    uint8_t flags = Base::RandFlags();
+    if (IsPadded()) {
+      flags |= Http2FrameFlag::PADDED;
+    } else {
+      flags &= ~Http2FrameFlag::PADDED;
+    }
+    return flags;
+  }
+
+  // Verify that we get OnPaddingTooLong when decoding payload, and that the
+  // amount of missing padding is as specified. header.IsPadded must be true,
+  // and the payload must be empty or the PadLength field must be too large.
+  ::testing::AssertionResult VerifyDetectsPaddingTooLong(
+      absl::string_view payload,
+      const Http2FrameHeader& header,
+      size_t expected_missing_length) {
+    set_frame_header(header);
+    auto& listener = listener_;
+    Validator validator =
+        [header, expected_missing_length, &listener](
+            const DecodeBuffer&,
+            DecodeStatus status) -> ::testing::AssertionResult {
+      VERIFY_EQ(DecodeStatus::kDecodeError, status);
+      VERIFY_FALSE(listener.IsInProgress());
+      VERIFY_EQ(1u, listener.size());
+      const FrameParts* frame = listener.frame(0);
+      VERIFY_EQ(header, frame->GetFrameHeader());
+      VERIFY_TRUE(frame->GetOptMissingLength());
+      VERIFY_EQ(expected_missing_length, frame->GetOptMissingLength().value());
+      // Verify did not get OnFrameSizeError.
+      VERIFY_FALSE(frame->GetHasFrameSizeError());
+      return ::testing::AssertionSuccess();
+    };
+    VERIFY_AND_RETURN_SUCCESS(
+        PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(payload,
+                                                                    validator));
+  }
+
+  // Verifies that we get OnPaddingTooLong for a padded frame payload whose
+  // (randomly selected) payload length is less than total_pad_length_.
+  // Flags will be selected at random, except PADDED will be set and
+  // flags_to_avoid will not be set. The stream id is selected at random.
+  ::testing::AssertionResult VerifyDetectsPaddingTooLong() {
+    uint8_t flags = RandFlags() | Http2FrameFlag::PADDED;
+
+    // Create an all padding payload for total_pad_length_.
+    int payload_length = 0;
+    Http2FrameBuilder fb;
+    if (IsPadded()) {
+      fb.AppendUInt8(pad_length());
+      fb.AppendZeroes(pad_length());
+      HTTP2_VLOG(1) << "fb.size=" << fb.size();
+      // Pick a random length for the payload that is shorter than neccesary.
+      payload_length = Random().Uniform(fb.size());
+    }
+
+    HTTP2_VLOG(1) << "payload_length=" << payload_length;
+    std::string payload = fb.buffer().substr(0, payload_length);
+
+    // The missing length is the amount we cut off the end, unless
+    // payload_length is zero, in which case the decoder knows only that 1
+    // byte, the Pad Length field, is missing.
+    size_t missing_length =
+        payload_length == 0 ? 1 : fb.size() - payload_length;
+    HTTP2_VLOG(1) << "missing_length=" << missing_length;
+
+    const Http2FrameHeader header(payload_length, DecoderPeer::FrameType(),
+                                  flags, RandStreamId());
+    VERIFY_AND_RETURN_SUCCESS(
+        VerifyDetectsPaddingTooLong(payload, header, missing_length));
+  }
+
+  // total_pad_length_ includes the size of the Pad Length field, and thus
+  // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
+  const size_t total_pad_length_;
+  Http2FrameBuilder frame_builder_;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
diff --git a/quiche/http2/decoder/payload_decoders/ping_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/ping_payload_decoder.cc
new file mode 100644
index 0000000..2f9408a
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/ping_payload_decoder.cc
@@ -0,0 +1,90 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/ping_payload_decoder.h"
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+namespace {
+constexpr auto kOpaqueSize = Http2PingFields::EncodedSize();
+}
+
+DecodeStatus PingPayloadDecoder::StartDecodingPayload(FrameDecoderState* state,
+                                                      DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "PingPayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+  QUICHE_DCHECK_EQ(Http2FrameType::PING, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::ACK));
+
+  // Is the payload entirely in the decode buffer and is it the correct size?
+  // Given the size of the header and payload (17 bytes total), this is most
+  // likely the case the vast majority of the time.
+  if (db->Remaining() == kOpaqueSize && total_length == kOpaqueSize) {
+    // Special case this situation as it allows us to avoid any copying;
+    // the other path makes two copies, first into the buffer in
+    // Http2StructureDecoder as it accumulates the 8 bytes of opaque data,
+    // and a second copy into the Http2PingFields member of in this class.
+    // This supports the claim that this decoder is (mostly) non-buffering.
+    static_assert(sizeof(Http2PingFields) == kOpaqueSize,
+                  "If not, then can't enter this block!");
+    auto* ping = reinterpret_cast<const Http2PingFields*>(db->cursor());
+    if (frame_header.IsAck()) {
+      state->listener()->OnPingAck(frame_header, *ping);
+    } else {
+      state->listener()->OnPing(frame_header, *ping);
+    }
+    db->AdvanceCursor(kOpaqueSize);
+    return DecodeStatus::kDecodeDone;
+  }
+  state->InitializeRemainders();
+  return HandleStatus(
+      state, state->StartDecodingStructureInPayload(&ping_fields_, db));
+}
+
+DecodeStatus PingPayloadDecoder::ResumeDecodingPayload(FrameDecoderState* state,
+                                                       DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "ResumeDecodingPayload: remaining_payload="
+                 << state->remaining_payload();
+  QUICHE_DCHECK_EQ(Http2FrameType::PING, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  return HandleStatus(
+      state, state->ResumeDecodingStructureInPayload(&ping_fields_, db));
+}
+
+DecodeStatus PingPayloadDecoder::HandleStatus(FrameDecoderState* state,
+                                              DecodeStatus status) {
+  HTTP2_DVLOG(2) << "HandleStatus: status=" << status
+                 << "; remaining_payload=" << state->remaining_payload();
+  if (status == DecodeStatus::kDecodeDone) {
+    if (state->remaining_payload() == 0) {
+      const Http2FrameHeader& frame_header = state->frame_header();
+      if (frame_header.IsAck()) {
+        state->listener()->OnPingAck(frame_header, ping_fields_);
+      } else {
+        state->listener()->OnPing(frame_header, ping_fields_);
+      }
+      return DecodeStatus::kDecodeDone;
+    }
+    // Payload is too long.
+    return state->ReportFrameSizeError();
+  }
+  // Not done decoding the structure. Either we've got more payload to decode,
+  // or we've run out because the payload is too short.
+  QUICHE_DCHECK(
+      (status == DecodeStatus::kDecodeInProgress &&
+       state->remaining_payload() > 0) ||
+      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
+      << "\n status=" << status
+      << "; remaining_payload=" << state->remaining_payload();
+  return status;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/ping_payload_decoder.h b/quiche/http2/decoder/payload_decoders/ping_payload_decoder.h
new file mode 100644
index 0000000..71e4928
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/ping_payload_decoder.h
@@ -0,0 +1,43 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PING_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PING_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a PING frame; for the RFC, see:
+//     http://httpwg.org/specs/rfc7540.html#PING
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class PingPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE PingPayloadDecoder {
+ public:
+  // Starts the decoding of a PING frame's payload, and completes it if the
+  // entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a PING frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::PingPayloadDecoderPeer;
+
+  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
+
+  Http2PingFields ping_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PING_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/ping_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
new file mode 100644
index 0000000..318c3bd
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
@@ -0,0 +1,110 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/ping_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class PingPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() { return Http2FrameType::PING; }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnPing(const Http2FrameHeader& header,
+              const Http2PingFields& ping) override {
+    HTTP2_VLOG(1) << "OnPing: " << header << "; " << ping;
+    StartAndEndFrame(header)->OnPing(header, ping);
+  }
+
+  void OnPingAck(const Http2FrameHeader& header,
+                 const Http2PingFields& ping) override {
+    HTTP2_VLOG(1) << "OnPingAck: " << header << "; " << ping;
+    StartAndEndFrame(header)->OnPingAck(header, ping);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class PingPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<PingPayloadDecoder,
+                                        PingPayloadDecoderPeer,
+                                        Listener> {
+ protected:
+  Http2PingFields RandPingFields() {
+    Http2PingFields fields;
+    test::Randomize(&fields, RandomPtr());
+    return fields;
+  }
+};
+
+// Confirm we get an error if the payload is not the correct size to hold
+// exactly one Http2PingFields.
+TEST_F(PingPayloadDecoderTest, WrongSize) {
+  auto approve_size = [](size_t size) {
+    return size != Http2PingFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(RandPingFields());
+  fb.Append(RandPingFields());
+  fb.Append(RandPingFields());
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+TEST_F(PingPayloadDecoderTest, Ping) {
+  for (int n = 0; n < 100; ++n) {
+    Http2PingFields fields = RandPingFields();
+    Http2FrameBuilder fb;
+    fb.Append(fields);
+    Http2FrameHeader header(fb.size(), Http2FrameType::PING,
+                            RandFlags() & ~Http2FrameFlag::ACK, RandStreamId());
+    set_frame_header(header);
+    FrameParts expected(header);
+    expected.SetOptPing(fields);
+    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+  }
+}
+
+TEST_F(PingPayloadDecoderTest, PingAck) {
+  for (int n = 0; n < 100; ++n) {
+    Http2PingFields fields;
+    Randomize(&fields, RandomPtr());
+    Http2FrameBuilder fb;
+    fb.Append(fields);
+    Http2FrameHeader header(fb.size(), Http2FrameType::PING,
+                            RandFlags() | Http2FrameFlag::ACK, RandStreamId());
+    set_frame_header(header);
+    FrameParts expected(header);
+    expected.SetOptPing(fields);
+    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/priority_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/priority_payload_decoder.cc
new file mode 100644
index 0000000..18e0ffc
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/priority_payload_decoder.cc
@@ -0,0 +1,64 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/priority_payload_decoder.h"
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus PriorityPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "PriorityPayloadDecoder::StartDecodingPayload: "
+                 << state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  // PRIORITY frames have no flags.
+  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
+  state->InitializeRemainders();
+  return HandleStatus(
+      state, state->StartDecodingStructureInPayload(&priority_fields_, db));
+}
+
+DecodeStatus PriorityPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "PriorityPayloadDecoder::ResumeDecodingPayload"
+                 << "  remaining_payload=" << state->remaining_payload()
+                 << "  db->Remaining=" << db->Remaining();
+  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  return HandleStatus(
+      state, state->ResumeDecodingStructureInPayload(&priority_fields_, db));
+}
+
+DecodeStatus PriorityPayloadDecoder::HandleStatus(FrameDecoderState* state,
+                                                  DecodeStatus status) {
+  if (status == DecodeStatus::kDecodeDone) {
+    if (state->remaining_payload() == 0) {
+      state->listener()->OnPriorityFrame(state->frame_header(),
+                                         priority_fields_);
+      return DecodeStatus::kDecodeDone;
+    }
+    // Payload is too long.
+    return state->ReportFrameSizeError();
+  }
+  // Not done decoding the structure. Either we've got more payload to decode,
+  // or we've run out because the payload is too short, in which case
+  // OnFrameSizeError will have already been called.
+  QUICHE_DCHECK(
+      (status == DecodeStatus::kDecodeInProgress &&
+       state->remaining_payload() > 0) ||
+      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
+      << "\n status=" << status
+      << "; remaining_payload=" << state->remaining_payload();
+  return status;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/priority_payload_decoder.h b/quiche/http2/decoder/payload_decoders/priority_payload_decoder.h
new file mode 100644
index 0000000..5ee3dc9
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/priority_payload_decoder.h
@@ -0,0 +1,44 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a PRIORITY frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class PriorityPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE PriorityPayloadDecoder {
+ public:
+  // Starts the decoding of a PRIORITY frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a PRIORITY frame that has been split across decode
+  // buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::PriorityPayloadDecoderPeer;
+
+  // Determines whether to report the PRIORITY to the listener, wait for more
+  // input, or to report a Frame Size Error.
+  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
+
+  Http2PriorityFields priority_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/priority_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
new file mode 100644
index 0000000..8b3db89
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
@@ -0,0 +1,90 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/priority_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class PriorityPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::PRIORITY;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnPriorityFrame(const Http2FrameHeader& header,
+                       const Http2PriorityFields& priority_fields) override {
+    HTTP2_VLOG(1) << "OnPriority: " << header << "; " << priority_fields;
+    StartAndEndFrame(header)->OnPriorityFrame(header, priority_fields);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class PriorityPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<PriorityPayloadDecoder,
+                                        PriorityPayloadDecoderPeer,
+                                        Listener> {
+ protected:
+  Http2PriorityFields RandPriorityFields() {
+    Http2PriorityFields fields;
+    test::Randomize(&fields, RandomPtr());
+    return fields;
+  }
+};
+
+// Confirm we get an error if the payload is not the correct size to hold
+// exactly one Http2PriorityFields.
+TEST_F(PriorityPayloadDecoderTest, WrongSize) {
+  auto approve_size = [](size_t size) {
+    return size != Http2PriorityFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(RandPriorityFields());
+  fb.Append(RandPriorityFields());
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+TEST_F(PriorityPayloadDecoderTest, VariousPayloads) {
+  for (int n = 0; n < 100; ++n) {
+    Http2PriorityFields fields = RandPriorityFields();
+    Http2FrameBuilder fb;
+    fb.Append(fields);
+    Http2FrameHeader header(fb.size(), Http2FrameType::PRIORITY, RandFlags(),
+                            RandStreamId());
+    set_frame_header(header);
+    FrameParts expected(header);
+    expected.SetOptPriority(fields);
+    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.cc
new file mode 100644
index 0000000..57796c6
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.cc
@@ -0,0 +1,125 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         PriorityUpdatePayloadDecoder::PayloadState v) {
+  switch (v) {
+    case PriorityUpdatePayloadDecoder::PayloadState::kStartDecodingFixedFields:
+      return out << "kStartDecodingFixedFields";
+    case PriorityUpdatePayloadDecoder::PayloadState::kResumeDecodingFixedFields:
+      return out << "kResumeDecodingFixedFields";
+    case PriorityUpdatePayloadDecoder::PayloadState::kHandleFixedFieldsStatus:
+      return out << "kHandleFixedFieldsStatus";
+    case PriorityUpdatePayloadDecoder::PayloadState::kReadPriorityFieldValue:
+      return out << "kReadPriorityFieldValue";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_173_1)
+      << "Invalid PriorityUpdatePayloadDecoder::PayloadState: " << unknown;
+  return out << "PriorityUpdatePayloadDecoder::PayloadState(" << unknown << ")";
+}
+
+DecodeStatus PriorityUpdatePayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "PriorityUpdatePayloadDecoder::StartDecodingPayload: "
+                 << state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY_UPDATE, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
+
+  state->InitializeRemainders();
+  payload_state_ = PayloadState::kStartDecodingFixedFields;
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus PriorityUpdatePayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "PriorityUpdatePayloadDecoder::ResumeDecodingPayload: "
+                    "remaining_payload="
+                 << state->remaining_payload()
+                 << ", db->Remaining=" << db->Remaining();
+
+  const Http2FrameHeader& frame_header = state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::PRIORITY_UPDATE, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
+  QUICHE_DCHECK_NE(PayloadState::kHandleFixedFieldsStatus, payload_state_);
+
+  // |status| has to be initialized to some value to avoid compiler error in
+  // case PayloadState::kHandleFixedFieldsStatus below, but value does not
+  // matter, see QUICHE_DCHECK_NE above.
+  DecodeStatus status = DecodeStatus::kDecodeError;
+  size_t avail;
+  while (true) {
+    HTTP2_DVLOG(2)
+        << "PriorityUpdatePayloadDecoder::ResumeDecodingPayload payload_state_="
+        << payload_state_;
+    switch (payload_state_) {
+      case PayloadState::kStartDecodingFixedFields:
+        status = state->StartDecodingStructureInPayload(
+            &priority_update_fields_, db);
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kHandleFixedFieldsStatus:
+        if (status == DecodeStatus::kDecodeDone) {
+          state->listener()->OnPriorityUpdateStart(frame_header,
+                                                   priority_update_fields_);
+        } else {
+          // Not done decoding the structure. Either we've got more payload
+          // to decode, or we've run out because the payload is too short,
+          // in which case OnFrameSizeError will have already been called.
+          QUICHE_DCHECK((status == DecodeStatus::kDecodeInProgress &&
+                         state->remaining_payload() > 0) ||
+                        (status == DecodeStatus::kDecodeError &&
+                         state->remaining_payload() == 0))
+              << "\n status=" << status
+              << "; remaining_payload=" << state->remaining_payload();
+          payload_state_ = PayloadState::kResumeDecodingFixedFields;
+          return status;
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kReadPriorityFieldValue:
+        // Anything left in the decode buffer is the Priority Field Value.
+        avail = db->Remaining();
+        if (avail > 0) {
+          state->listener()->OnPriorityUpdatePayload(db->cursor(), avail);
+          db->AdvanceCursor(avail);
+          state->ConsumePayload(avail);
+        }
+        if (state->remaining_payload() > 0) {
+          payload_state_ = PayloadState::kReadPriorityFieldValue;
+          return DecodeStatus::kDecodeInProgress;
+        }
+        state->listener()->OnPriorityUpdateEnd();
+        return DecodeStatus::kDecodeDone;
+
+      case PayloadState::kResumeDecodingFixedFields:
+        status = state->ResumeDecodingStructureInPayload(
+            &priority_update_fields_, db);
+        payload_state_ = PayloadState::kHandleFixedFieldsStatus;
+        continue;
+    }
+    HTTP2_BUG(http2_bug_173_2) << "PayloadState: " << payload_state_;
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.h b/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.h
new file mode 100644
index 0000000..9cfba58
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.h
@@ -0,0 +1,63 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_UPDATE_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_UPDATE_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a PRIORITY_UPDATE frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class PriorityUpdatePayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE PriorityUpdatePayloadDecoder {
+ public:
+  // States during decoding of a PRIORITY_UPDATE frame.
+  enum class PayloadState {
+    // At the start of the PRIORITY_UPDATE frame payload, ready to start
+    // decoding the fixed size fields into priority_update_fields_.
+    kStartDecodingFixedFields,
+
+    // The fixed size fields weren't all available when the decoder first
+    // tried to decode them; this state resumes the decoding when
+    // ResumeDecodingPayload is called later.
+    kResumeDecodingFixedFields,
+
+    // Handle the DecodeStatus returned from starting or resuming the decoding
+    // of Http2PriorityUpdateFields into priority_update_fields_. If complete,
+    // calls OnPriorityUpdateStart.
+    kHandleFixedFieldsStatus,
+
+    // Report the Priority Field Value portion of the payload to the listener's
+    // OnPriorityUpdatePayload method, and call OnPriorityUpdateEnd when the end
+    // of the payload is reached.
+    kReadPriorityFieldValue,
+  };
+
+  // Starts the decoding of a PRIORITY_UPDATE frame's payload, and completes it
+  // if the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a PRIORITY_UPDATE frame that has been split across decode
+  // buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::PriorityUpdatePayloadDecoderPeer;
+
+  Http2PriorityUpdateFields priority_update_fields_;
+  PayloadState payload_state_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PRIORITY_UPDATE_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc
new file mode 100644
index 0000000..1905c01
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc
@@ -0,0 +1,115 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class PriorityUpdatePayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::PRIORITY_UPDATE;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) override {
+    HTTP2_VLOG(1) << "OnPriorityUpdateStart header: " << header
+                  << "; priority_update: " << priority_update;
+    StartFrame(header)->OnPriorityUpdateStart(header, priority_update);
+  }
+
+  void OnPriorityUpdatePayload(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
+    CurrentFrame()->OnPriorityUpdatePayload(data, len);
+  }
+
+  void OnPriorityUpdateEnd() override {
+    HTTP2_VLOG(1) << "OnPriorityUpdateEnd";
+    EndFrame()->OnPriorityUpdateEnd();
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class PriorityUpdatePayloadDecoderTest
+    : public AbstractPayloadDecoderTest<PriorityUpdatePayloadDecoder,
+                                        PriorityUpdatePayloadDecoderPeer,
+                                        Listener> {};
+
+// Confirm we get an error if the payload is not long enough to hold
+// Http2PriorityUpdateFields.
+TEST_F(PriorityUpdatePayloadDecoderTest, Truncated) {
+  auto approve_size = [](size_t size) {
+    return size != Http2PriorityUpdateFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(Http2PriorityUpdateFields(123));
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+class PriorityUpdatePayloadLengthTests
+    : public AbstractPayloadDecoderTest<PriorityUpdatePayloadDecoder,
+                                        PriorityUpdatePayloadDecoderPeer,
+                                        Listener>,
+      public ::testing::WithParamInterface<uint32_t> {
+ protected:
+  PriorityUpdatePayloadLengthTests() : length_(GetParam()) {
+    HTTP2_VLOG(1) << "################  length_=" << length_
+                  << "  ################";
+  }
+
+  const uint32_t length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(VariousLengths,
+                         PriorityUpdatePayloadLengthTests,
+                         ::testing::Values(0, 1, 2, 3, 4, 5, 6));
+
+TEST_P(PriorityUpdatePayloadLengthTests, ValidLength) {
+  Http2PriorityUpdateFields priority_update;
+  Randomize(&priority_update, RandomPtr());
+  std::string priority_field_value = Random().RandString(length_);
+  Http2FrameBuilder fb;
+  fb.Append(priority_update);
+  fb.Append(priority_field_value);
+  Http2FrameHeader header(fb.size(), Http2FrameType::PRIORITY_UPDATE,
+                          RandFlags(), RandStreamId());
+  set_frame_header(header);
+  FrameParts expected(header, priority_field_value);
+  expected.SetOptPriorityUpdate(Http2PriorityUpdateFields{priority_update});
+  ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.cc
new file mode 100644
index 0000000..b6caa6c
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.cc
@@ -0,0 +1,173 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         PushPromisePayloadDecoder::PayloadState v) {
+  switch (v) {
+    case PushPromisePayloadDecoder::PayloadState::kReadPadLength:
+      return out << "kReadPadLength";
+    case PushPromisePayloadDecoder::PayloadState::
+        kStartDecodingPushPromiseFields:
+      return out << "kStartDecodingPushPromiseFields";
+    case PushPromisePayloadDecoder::PayloadState::kReadPayload:
+      return out << "kReadPayload";
+    case PushPromisePayloadDecoder::PayloadState::kSkipPadding:
+      return out << "kSkipPadding";
+    case PushPromisePayloadDecoder::PayloadState::
+        kResumeDecodingPushPromiseFields:
+      return out << "kResumeDecodingPushPromiseFields";
+  }
+  return out << static_cast<int>(v);
+}
+
+DecodeStatus PushPromisePayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "PushPromisePayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+
+  QUICHE_DCHECK_EQ(Http2FrameType::PUSH_PROMISE, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::END_HEADERS |
+                                             Http2FrameFlag::PADDED));
+
+  if (!frame_header.IsPadded()) {
+    // If it turns out that PUSH_PROMISE frames without padding are sufficiently
+    // common, and that they are usually short enough that they fit entirely
+    // into one DecodeBuffer, we can detect that here and implement a special
+    // case, avoiding the state machine in ResumeDecodingPayload.
+    payload_state_ = PayloadState::kStartDecodingPushPromiseFields;
+  } else {
+    payload_state_ = PayloadState::kReadPadLength;
+  }
+  state->InitializeRemainders();
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus PushPromisePayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "UnknownPayloadDecoder::ResumeDecodingPayload"
+                 << "  remaining_payload=" << state->remaining_payload()
+                 << "  db->Remaining=" << db->Remaining();
+
+  const Http2FrameHeader& frame_header = state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::PUSH_PROMISE, frame_header.type);
+  QUICHE_DCHECK_LE(state->remaining_payload(), frame_header.payload_length);
+  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
+
+  DecodeStatus status;
+  while (true) {
+    HTTP2_DVLOG(2)
+        << "PushPromisePayloadDecoder::ResumeDecodingPayload payload_state_="
+        << payload_state_;
+    switch (payload_state_) {
+      case PayloadState::kReadPadLength:
+        QUICHE_DCHECK_EQ(state->remaining_payload(),
+                         frame_header.payload_length);
+        // ReadPadLength handles the OnPadLength callback, and updating the
+        // remaining_payload and remaining_padding fields. If the amount of
+        // padding is too large to fit in the frame's payload, ReadPadLength
+        // instead calls OnPaddingTooLong and returns kDecodeError.
+        // Suppress the call to OnPadLength because we haven't yet called
+        // OnPushPromiseStart, which needs to wait until we've decoded the
+        // Promised Stream ID.
+        status = state->ReadPadLength(db, /*report_pad_length*/ false);
+        if (status != DecodeStatus::kDecodeDone) {
+          payload_state_ = PayloadState::kReadPadLength;
+          return status;
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kStartDecodingPushPromiseFields:
+        status =
+            state->StartDecodingStructureInPayload(&push_promise_fields_, db);
+        if (status != DecodeStatus::kDecodeDone) {
+          payload_state_ = PayloadState::kResumeDecodingPushPromiseFields;
+          return status;
+        }
+        // Finished decoding the Promised Stream ID. Can now tell the listener
+        // that we're starting to decode a PUSH_PROMISE frame.
+        ReportPushPromise(state);
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kReadPayload:
+        QUICHE_DCHECK_LT(state->remaining_payload(),
+                         frame_header.payload_length);
+        QUICHE_DCHECK_LE(state->remaining_payload(),
+                         frame_header.payload_length -
+                             Http2PushPromiseFields::EncodedSize());
+        QUICHE_DCHECK_LE(
+            state->remaining_payload(),
+            frame_header.payload_length -
+                Http2PushPromiseFields::EncodedSize() -
+                (frame_header.IsPadded() ? (1 + state->remaining_padding())
+                                         : 0));
+        {
+          size_t avail = state->AvailablePayload(db);
+          state->listener()->OnHpackFragment(db->cursor(), avail);
+          db->AdvanceCursor(avail);
+          state->ConsumePayload(avail);
+        }
+        if (state->remaining_payload() > 0) {
+          payload_state_ = PayloadState::kReadPayload;
+          return DecodeStatus::kDecodeInProgress;
+        }
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case PayloadState::kSkipPadding:
+        // SkipPadding handles the OnPadding callback.
+        if (state->SkipPadding(db)) {
+          state->listener()->OnPushPromiseEnd();
+          return DecodeStatus::kDecodeDone;
+        }
+        payload_state_ = PayloadState::kSkipPadding;
+        return DecodeStatus::kDecodeInProgress;
+
+      case PayloadState::kResumeDecodingPushPromiseFields:
+        status =
+            state->ResumeDecodingStructureInPayload(&push_promise_fields_, db);
+        if (status == DecodeStatus::kDecodeDone) {
+          // Finished decoding the Promised Stream ID. Can now tell the listener
+          // that we're starting to decode a PUSH_PROMISE frame.
+          ReportPushPromise(state);
+          payload_state_ = PayloadState::kReadPayload;
+          continue;
+        }
+        payload_state_ = PayloadState::kResumeDecodingPushPromiseFields;
+        return status;
+    }
+    HTTP2_BUG(http2_bug_183_1) << "PayloadState: " << payload_state_;
+  }
+}
+
+void PushPromisePayloadDecoder::ReportPushPromise(FrameDecoderState* state) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  if (frame_header.IsPadded()) {
+    state->listener()->OnPushPromiseStart(frame_header, push_promise_fields_,
+                                          1 + state->remaining_padding());
+  } else {
+    state->listener()->OnPushPromiseStart(frame_header, push_promise_fields_,
+                                          0);
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.h b/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.h
new file mode 100644
index 0000000..f5bf53d
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.h
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PUSH_PROMISE_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PUSH_PROMISE_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a PUSH_PROMISE frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class PushPromisePayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE PushPromisePayloadDecoder {
+ public:
+  // States during decoding of a PUSH_PROMISE frame.
+  enum class PayloadState {
+    // The frame is padded and we need to read the PAD_LENGTH field (1 byte).
+    kReadPadLength,
+
+    // Ready to start decoding the fixed size fields of the PUSH_PROMISE
+    // frame into push_promise_fields_.
+    kStartDecodingPushPromiseFields,
+
+    // The decoder has already called OnPushPromiseStart, and is now reporting
+    // the HPACK block fragment to the listener's OnHpackFragment method.
+    kReadPayload,
+
+    // The decoder has finished with the HPACK block fragment, and is now
+    // ready to skip the trailing padding, if the frame has any.
+    kSkipPadding,
+
+    // The fixed size fields weren't all available when the decoder first tried
+    // to decode them (state kStartDecodingPushPromiseFields); this state
+    // resumes the decoding when ResumeDecodingPayload is called later.
+    kResumeDecodingPushPromiseFields,
+  };
+
+  // Starts the decoding of a PUSH_PROMISE frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a PUSH_PROMISE frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::PushPromisePayloadDecoderPeer;
+
+  void ReportPushPromise(FrameDecoderState* state);
+
+  PayloadState payload_state_;
+  Http2PushPromiseFields push_promise_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_PUSH_PROMISE_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
new file mode 100644
index 0000000..174fd33
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
@@ -0,0 +1,139 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+// Provides friend access to an instance of the payload decoder, and also
+// provides info to aid in testing.
+class PushPromisePayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::PUSH_PROMISE;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
+    return Http2FrameFlag::PADDED;
+  }
+};
+
+namespace {
+
+// Listener listens for only those methods expected by the payload decoder
+// under test, and forwards them onto the FrameParts instance for the current
+// frame.
+struct Listener : public FramePartsCollector {
+  void OnPushPromiseStart(const Http2FrameHeader& header,
+                          const Http2PushPromiseFields& promise,
+                          size_t total_padding_length) override {
+    HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
+                  << "  promise: " << promise
+                  << "  total_padding_length: " << total_padding_length;
+    EXPECT_EQ(Http2FrameType::PUSH_PROMISE, header.type);
+    StartFrame(header)->OnPushPromiseStart(header, promise,
+                                           total_padding_length);
+  }
+
+  void OnHpackFragment(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
+    CurrentFrame()->OnHpackFragment(data, len);
+  }
+
+  void OnPushPromiseEnd() override {
+    HTTP2_VLOG(1) << "OnPushPromiseEnd";
+    EndFrame()->OnPushPromiseEnd();
+  }
+
+  void OnPadding(const char* padding, size_t skipped_length) override {
+    HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
+    CurrentFrame()->OnPadding(padding, skipped_length);
+  }
+
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override {
+    HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
+                  << "; missing_length: " << missing_length;
+    FrameError(header)->OnPaddingTooLong(header, missing_length);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class PushPromisePayloadDecoderTest
+    : public AbstractPaddablePayloadDecoderTest<PushPromisePayloadDecoder,
+                                                PushPromisePayloadDecoderPeer,
+                                                Listener> {};
+
+INSTANTIATE_TEST_SUITE_P(VariousPadLengths,
+                         PushPromisePayloadDecoderTest,
+                         ::testing::Values(0, 1, 2, 3, 4, 254, 255, 256));
+
+// Payload contains the required Http2PushPromiseFields, followed by some
+// (fake) HPACK payload.
+TEST_P(PushPromisePayloadDecoderTest, VariousHpackPayloadSizes) {
+  for (size_t hpack_size : {0, 1, 2, 3, 255, 256, 1024}) {
+    HTTP2_LOG(INFO) << "###########   hpack_size = " << hpack_size
+                    << "  ###########";
+    Reset();
+    std::string hpack_payload = Random().RandString(hpack_size);
+    Http2PushPromiseFields push_promise{RandStreamId()};
+    frame_builder_.Append(push_promise);
+    frame_builder_.Append(hpack_payload);
+    MaybeAppendTrailingPadding();
+    Http2FrameHeader frame_header(frame_builder_.size(),
+                                  Http2FrameType::PUSH_PROMISE, RandFlags(),
+                                  RandStreamId());
+    set_frame_header(frame_header);
+    FrameParts expected(frame_header, hpack_payload, total_pad_length_);
+    expected.SetOptPushPromise(push_promise);
+    EXPECT_TRUE(
+        DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(), expected));
+  }
+}
+
+// Confirm we get an error if the payload is not long enough for the required
+// portion of the payload, regardless of the amount of (valid) padding.
+TEST_P(PushPromisePayloadDecoderTest, Truncated) {
+  auto approve_size = [](size_t size) {
+    return size != Http2PushPromiseFields::EncodedSize();
+  };
+  Http2PushPromiseFields push_promise{RandStreamId()};
+  Http2FrameBuilder fb;
+  fb.Append(push_promise);
+  EXPECT_TRUE(VerifyDetectsMultipleFrameSizeErrors(0, fb.buffer(), approve_size,
+                                                   total_pad_length_));
+}
+
+// Confirm we get an error if the PADDED flag is set but the payload is not
+// long enough to hold even the Pad Length amount of padding.
+TEST_P(PushPromisePayloadDecoderTest, PaddingTooLong) {
+  EXPECT_TRUE(VerifyDetectsPaddingTooLong());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc
new file mode 100644
index 0000000..11033f0
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.h"
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus RstStreamPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "RstStreamPayloadDecoder::StartDecodingPayload: "
+                 << state->frame_header();
+  QUICHE_DCHECK_EQ(Http2FrameType::RST_STREAM, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  // RST_STREAM has no flags.
+  QUICHE_DCHECK_EQ(0, state->frame_header().flags);
+  state->InitializeRemainders();
+  return HandleStatus(
+      state, state->StartDecodingStructureInPayload(&rst_stream_fields_, db));
+}
+
+DecodeStatus RstStreamPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "RstStreamPayloadDecoder::ResumeDecodingPayload"
+                 << "  remaining_payload=" << state->remaining_payload()
+                 << "  db->Remaining=" << db->Remaining();
+  QUICHE_DCHECK_EQ(Http2FrameType::RST_STREAM, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  return HandleStatus(
+      state, state->ResumeDecodingStructureInPayload(&rst_stream_fields_, db));
+}
+
+DecodeStatus RstStreamPayloadDecoder::HandleStatus(FrameDecoderState* state,
+                                                   DecodeStatus status) {
+  HTTP2_DVLOG(2) << "HandleStatus: status=" << status
+                 << "; remaining_payload=" << state->remaining_payload();
+  if (status == DecodeStatus::kDecodeDone) {
+    if (state->remaining_payload() == 0) {
+      state->listener()->OnRstStream(state->frame_header(),
+                                     rst_stream_fields_.error_code);
+      return DecodeStatus::kDecodeDone;
+    }
+    // Payload is too long.
+    return state->ReportFrameSizeError();
+  }
+  // Not done decoding the structure. Either we've got more payload to decode,
+  // or we've run out because the payload is too short, in which case
+  // OnFrameSizeError will have already been called by the FrameDecoderState.
+  QUICHE_DCHECK(
+      (status == DecodeStatus::kDecodeInProgress &&
+       state->remaining_payload() > 0) ||
+      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
+      << "\n status=" << status
+      << "; remaining_payload=" << state->remaining_payload();
+  return status;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.h b/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.h
new file mode 100644
index 0000000..a263bd2
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.h
@@ -0,0 +1,42 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_RST_STREAM_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_RST_STREAM_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a RST_STREAM frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class RstStreamPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE RstStreamPayloadDecoder {
+ public:
+  // Starts the decoding of a RST_STREAM frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a RST_STREAM frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::RstStreamPayloadDecoderPeer;
+
+  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
+
+  Http2RstStreamFields rst_stream_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_RST_STREAM_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
new file mode 100644
index 0000000..c943667
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
@@ -0,0 +1,92 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_constants_test_util.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class RstStreamPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::RST_STREAM;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnRstStream(const Http2FrameHeader& header,
+                   Http2ErrorCode error_code) override {
+    HTTP2_VLOG(1) << "OnRstStream: " << header << "; error_code=" << error_code;
+    StartAndEndFrame(header)->OnRstStream(header, error_code);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class RstStreamPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<RstStreamPayloadDecoder,
+                                        RstStreamPayloadDecoderPeer,
+                                        Listener> {
+ protected:
+  Http2RstStreamFields RandRstStreamFields() {
+    Http2RstStreamFields fields;
+    test::Randomize(&fields, RandomPtr());
+    return fields;
+  }
+};
+
+// Confirm we get an error if the payload is not the correct size to hold
+// exactly one Http2RstStreamFields.
+TEST_F(RstStreamPayloadDecoderTest, WrongSize) {
+  auto approve_size = [](size_t size) {
+    return size != Http2RstStreamFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(RandRstStreamFields());
+  fb.Append(RandRstStreamFields());
+  fb.Append(RandRstStreamFields());
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+TEST_F(RstStreamPayloadDecoderTest, AllErrors) {
+  for (auto error_code : AllHttp2ErrorCodes()) {
+    Http2RstStreamFields fields{error_code};
+    Http2FrameBuilder fb;
+    fb.Append(fields);
+    Http2FrameHeader header(fb.size(), Http2FrameType::RST_STREAM, RandFlags(),
+                            RandStreamId());
+    set_frame_header(header);
+    FrameParts expected(header);
+    expected.SetOptRstStreamErrorCode(error_code);
+    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/settings_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/settings_payload_decoder.cc
new file mode 100644
index 0000000..d1b25a9
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/settings_payload_decoder.cc
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/settings_payload_decoder.h"
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus SettingsPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "SettingsPayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+  QUICHE_DCHECK_EQ(Http2FrameType::SETTINGS, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+  QUICHE_DCHECK_EQ(0, frame_header.flags & ~(Http2FrameFlag::ACK));
+
+  if (frame_header.IsAck()) {
+    if (total_length == 0) {
+      state->listener()->OnSettingsAck(frame_header);
+      return DecodeStatus::kDecodeDone;
+    } else {
+      state->InitializeRemainders();
+      return state->ReportFrameSizeError();
+    }
+  } else {
+    state->InitializeRemainders();
+    state->listener()->OnSettingsStart(frame_header);
+    return StartDecodingSettings(state, db);
+  }
+}
+
+DecodeStatus SettingsPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "SettingsPayloadDecoder::ResumeDecodingPayload"
+                 << "  remaining_payload=" << state->remaining_payload()
+                 << "  db->Remaining=" << db->Remaining();
+  QUICHE_DCHECK_EQ(Http2FrameType::SETTINGS, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+
+  DecodeStatus status =
+      state->ResumeDecodingStructureInPayload(&setting_fields_, db);
+  if (status == DecodeStatus::kDecodeDone) {
+    state->listener()->OnSetting(setting_fields_);
+    return StartDecodingSettings(state, db);
+  }
+  return HandleNotDone(state, db, status);
+}
+
+DecodeStatus SettingsPayloadDecoder::StartDecodingSettings(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "SettingsPayloadDecoder::StartDecodingSettings"
+                 << "  remaining_payload=" << state->remaining_payload()
+                 << "  db->Remaining=" << db->Remaining();
+  while (state->remaining_payload() > 0) {
+    DecodeStatus status =
+        state->StartDecodingStructureInPayload(&setting_fields_, db);
+    if (status == DecodeStatus::kDecodeDone) {
+      state->listener()->OnSetting(setting_fields_);
+      continue;
+    }
+    return HandleNotDone(state, db, status);
+  }
+  HTTP2_DVLOG(2) << "LEAVING SettingsPayloadDecoder::StartDecodingSettings"
+                 << "\n\tdb->Remaining=" << db->Remaining()
+                 << "\n\t remaining_payload=" << state->remaining_payload();
+  state->listener()->OnSettingsEnd();
+  return DecodeStatus::kDecodeDone;
+}
+
+DecodeStatus SettingsPayloadDecoder::HandleNotDone(FrameDecoderState* state,
+                                                   DecodeBuffer* db,
+                                                   DecodeStatus status) {
+  // Not done decoding the structure. Either we've got more payload to decode,
+  // or we've run out because the payload is too short, in which case
+  // OnFrameSizeError will have already been called.
+  QUICHE_DCHECK(
+      (status == DecodeStatus::kDecodeInProgress &&
+       state->remaining_payload() > 0) ||
+      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
+      << "\n status=" << status
+      << "; remaining_payload=" << state->remaining_payload()
+      << "; db->Remaining=" << db->Remaining();
+  return status;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/settings_payload_decoder.h b/quiche/http2/decoder/payload_decoders/settings_payload_decoder.h
new file mode 100644
index 0000000..9f26c86
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/settings_payload_decoder.h
@@ -0,0 +1,54 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_SETTINGS_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_SETTINGS_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a SETTINGS frame; for the RFC, see:
+//     http://httpwg.org/specs/rfc7540.html#SETTINGS
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class SettingsPayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE SettingsPayloadDecoder {
+ public:
+  // Starts the decoding of a SETTINGS frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a SETTINGS frame that has been split across decode
+  // buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::SettingsPayloadDecoderPeer;
+
+  // Decodes as many settings as are available in the decode buffer, starting at
+  // the first byte of one setting; if a single setting is split across buffers,
+  // ResumeDecodingPayload will handle starting from where the previous call
+  // left off, and then will call StartDecodingSettings.
+  DecodeStatus StartDecodingSettings(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+  // Decoding a single SETTING returned a status other than kDecodeDone; this
+  // method just brings together the QUICHE_DCHECKs to reduce duplication.
+  DecodeStatus HandleNotDone(FrameDecoderState* state,
+                             DecodeBuffer* db,
+                             DecodeStatus status);
+
+  Http2SettingFields setting_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_SETTINGS_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/settings_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
new file mode 100644
index 0000000..b0750d2
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
@@ -0,0 +1,160 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/settings_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <vector>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_constants_test_util.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class SettingsPayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::SETTINGS;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() {
+    return Http2FrameFlag::ACK;
+  }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnSettingsStart(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnSettingsStart: " << header;
+    EXPECT_EQ(Http2FrameType::SETTINGS, header.type) << header;
+    EXPECT_EQ(Http2FrameFlag(), header.flags) << header;
+    StartFrame(header)->OnSettingsStart(header);
+  }
+
+  void OnSetting(const Http2SettingFields& setting_fields) override {
+    HTTP2_VLOG(1) << "Http2SettingFields: setting_fields=" << setting_fields;
+    CurrentFrame()->OnSetting(setting_fields);
+  }
+
+  void OnSettingsEnd() override {
+    HTTP2_VLOG(1) << "OnSettingsEnd";
+    EndFrame()->OnSettingsEnd();
+  }
+
+  void OnSettingsAck(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnSettingsAck: " << header;
+    StartAndEndFrame(header)->OnSettingsAck(header);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class SettingsPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<SettingsPayloadDecoder,
+                                        SettingsPayloadDecoderPeer,
+                                        Listener> {
+ protected:
+  Http2SettingFields RandSettingsFields() {
+    Http2SettingFields fields;
+    test::Randomize(&fields, RandomPtr());
+    return fields;
+  }
+};
+
+// Confirm we get an error if the SETTINGS payload is not the correct size
+// to hold exactly zero or more whole Http2SettingFields.
+TEST_F(SettingsPayloadDecoderTest, SettingsWrongSize) {
+  auto approve_size = [](size_t size) {
+    // Should get an error if size is not an integral multiple of the size
+    // of one setting.
+    return 0 != (size % Http2SettingFields::EncodedSize());
+  };
+  Http2FrameBuilder fb;
+  fb.Append(RandSettingsFields());
+  fb.Append(RandSettingsFields());
+  fb.Append(RandSettingsFields());
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+// Confirm we get an error if the SETTINGS ACK payload is not empty.
+TEST_F(SettingsPayloadDecoderTest, SettingsAkcWrongSize) {
+  auto approve_size = [](size_t size) { return size != 0; };
+  Http2FrameBuilder fb;
+  fb.Append(RandSettingsFields());
+  fb.Append(RandSettingsFields());
+  fb.Append(RandSettingsFields());
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(Http2FrameFlag::ACK, fb.buffer(),
+                                          approve_size));
+}
+
+// SETTINGS must have stream_id==0, but the payload decoder doesn't check that.
+TEST_F(SettingsPayloadDecoderTest, SettingsAck) {
+  for (int stream_id = 0; stream_id < 3; ++stream_id) {
+    Http2FrameHeader header(0, Http2FrameType::SETTINGS,
+                            RandFlags() | Http2FrameFlag::ACK, stream_id);
+    set_frame_header(header);
+    FrameParts expected(header);
+    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays("", expected));
+  }
+}
+
+// Try several values of each known SETTINGS parameter.
+TEST_F(SettingsPayloadDecoderTest, OneRealSetting) {
+  std::vector<uint32_t> values = {0, 1, 0xffffffff, Random().Rand32()};
+  for (auto param : AllHttp2SettingsParameters()) {
+    for (uint32_t value : values) {
+      Http2SettingFields fields(param, value);
+      Http2FrameBuilder fb;
+      fb.Append(fields);
+      Http2FrameHeader header(fb.size(), Http2FrameType::SETTINGS, RandFlags(),
+                              RandStreamId());
+      set_frame_header(header);
+      FrameParts expected(header);
+      expected.AppendSetting(fields);
+      EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+    }
+  }
+}
+
+// Decode a SETTINGS frame with lots of fields.
+TEST_F(SettingsPayloadDecoderTest, ManySettings) {
+  const size_t num_settings = 100;
+  const size_t size = Http2SettingFields::EncodedSize() * num_settings;
+  Http2FrameHeader header(size, Http2FrameType::SETTINGS,
+                          RandFlags(),  // & ~Http2FrameFlag::ACK,
+                          RandStreamId());
+  set_frame_header(header);
+  FrameParts expected(header);
+  Http2FrameBuilder fb;
+  for (size_t n = 0; n < num_settings; ++n) {
+    Http2SettingFields fields(static_cast<Http2SettingsParameter>(n),
+                              Random().Rand32());
+    fb.Append(fields);
+    expected.AppendSetting(fields);
+  }
+  ASSERT_EQ(size, fb.size());
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.cc
new file mode 100644
index 0000000..01d7040
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.cc
@@ -0,0 +1,57 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/unknown_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus UnknownPayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+
+  HTTP2_DVLOG(2) << "UnknownPayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+  QUICHE_DCHECK(!IsSupportedHttp2FrameType(frame_header.type)) << frame_header;
+  QUICHE_DCHECK_LE(db->Remaining(), frame_header.payload_length);
+
+  state->InitializeRemainders();
+  state->listener()->OnUnknownStart(frame_header);
+  return ResumeDecodingPayload(state, db);
+}
+
+DecodeStatus UnknownPayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "UnknownPayloadDecoder::ResumeDecodingPayload "
+                 << "remaining_payload=" << state->remaining_payload()
+                 << "; db->Remaining=" << db->Remaining();
+  QUICHE_DCHECK(!IsSupportedHttp2FrameType(state->frame_header().type))
+      << state->frame_header();
+  QUICHE_DCHECK_LE(state->remaining_payload(),
+                   state->frame_header().payload_length);
+  QUICHE_DCHECK_LE(db->Remaining(), state->remaining_payload());
+
+  size_t avail = db->Remaining();
+  if (avail > 0) {
+    state->listener()->OnUnknownPayload(db->cursor(), avail);
+    db->AdvanceCursor(avail);
+    state->ConsumePayload(avail);
+  }
+  if (state->remaining_payload() == 0) {
+    state->listener()->OnUnknownEnd();
+    return DecodeStatus::kDecodeDone;
+  }
+  return DecodeStatus::kDecodeInProgress;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.h b/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.h
new file mode 100644
index 0000000..4d4f85a
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.h
@@ -0,0 +1,33 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_UNKNOWN_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_UNKNOWN_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a frame whose type unknown.  According to the HTTP/2
+// specification (http://httpwg.org/specs/rfc7540.html#FrameHeader):
+//     Implementations MUST ignore and discard any frame that has
+//     a type that is unknown.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE UnknownPayloadDecoder {
+ public:
+  // Starts decoding a payload of unknown type; just passes it to the listener.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a payload of unknown type that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_UNKNOWN_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc
new file mode 100644
index 0000000..72bd865
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc
@@ -0,0 +1,101 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/unknown_payload_decoder.h"
+
+#include <stddef.h>
+
+#include <string>
+#include <type_traits>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+Http2FrameType g_unknown_frame_type;
+}  // namespace
+
+// Provides friend access to an instance of the payload decoder, and also
+// provides info to aid in testing.
+class UnknownPayloadDecoderPeer {
+ public:
+  static Http2FrameType FrameType() { return g_unknown_frame_type; }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnUnknownStart(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnUnknownStart: " << header;
+    StartFrame(header)->OnUnknownStart(header);
+  }
+
+  void OnUnknownPayload(const char* data, size_t len) override {
+    HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
+    CurrentFrame()->OnUnknownPayload(data, len);
+  }
+
+  void OnUnknownEnd() override {
+    HTTP2_VLOG(1) << "OnUnknownEnd";
+    EndFrame()->OnUnknownEnd();
+  }
+};
+
+constexpr bool SupportedFrameType = false;
+
+class UnknownPayloadDecoderTest
+    : public AbstractPayloadDecoderTest<UnknownPayloadDecoder,
+                                        UnknownPayloadDecoderPeer,
+                                        Listener,
+                                        SupportedFrameType>,
+      public ::testing::WithParamInterface<uint32_t> {
+ protected:
+  UnknownPayloadDecoderTest() : length_(GetParam()) {
+    HTTP2_VLOG(1) << "################  length_=" << length_
+                  << "  ################";
+
+    // Each test case will choose a random frame type that isn't supported.
+    do {
+      g_unknown_frame_type = static_cast<Http2FrameType>(Random().Rand8());
+    } while (IsSupportedHttp2FrameType(g_unknown_frame_type));
+  }
+
+  const uint32_t length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(VariousLengths,
+                         UnknownPayloadDecoderTest,
+                         ::testing::Values(0, 1, 2, 3, 255, 256));
+
+TEST_P(UnknownPayloadDecoderTest, ValidLength) {
+  std::string unknown_payload = Random().RandString(length_);
+  Http2FrameHeader frame_header(length_, g_unknown_frame_type, Random().Rand8(),
+                                RandStreamId());
+  set_frame_header(frame_header);
+  FrameParts expected(frame_header, unknown_payload);
+  EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(unknown_payload, expected));
+  // TODO(jamessynge): Check here (and in other such tests) that the fast
+  // and slow decode counts are both non-zero. Perhaps also add some kind of
+  // test for the listener having been called. That could simply be a test
+  // that there is a single collected FrameParts instance, and that it matches
+  // expected.
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.cc b/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.cc
new file mode 100644
index 0000000..e509de4
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.cc
@@ -0,0 +1,82 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/window_update_payload_decoder.h"
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_http2_structures.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus WindowUpdatePayloadDecoder::StartDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  const Http2FrameHeader& frame_header = state->frame_header();
+  const uint32_t total_length = frame_header.payload_length;
+
+  HTTP2_DVLOG(2) << "WindowUpdatePayloadDecoder::StartDecodingPayload: "
+                 << frame_header;
+
+  QUICHE_DCHECK_EQ(Http2FrameType::WINDOW_UPDATE, frame_header.type);
+  QUICHE_DCHECK_LE(db->Remaining(), total_length);
+
+  // WINDOW_UPDATE frames have no flags.
+  QUICHE_DCHECK_EQ(0, frame_header.flags);
+
+  // Special case for when the payload is the correct size and entirely in
+  // the buffer.
+  if (db->Remaining() == Http2WindowUpdateFields::EncodedSize() &&
+      total_length == Http2WindowUpdateFields::EncodedSize()) {
+    DoDecode(&window_update_fields_, db);
+    state->listener()->OnWindowUpdate(
+        frame_header, window_update_fields_.window_size_increment);
+    return DecodeStatus::kDecodeDone;
+  }
+  state->InitializeRemainders();
+  return HandleStatus(state, state->StartDecodingStructureInPayload(
+                                 &window_update_fields_, db));
+}
+
+DecodeStatus WindowUpdatePayloadDecoder::ResumeDecodingPayload(
+    FrameDecoderState* state,
+    DecodeBuffer* db) {
+  HTTP2_DVLOG(2) << "ResumeDecodingPayload: remaining_payload="
+                 << state->remaining_payload()
+                 << "; db->Remaining=" << db->Remaining();
+  QUICHE_DCHECK_EQ(Http2FrameType::WINDOW_UPDATE, state->frame_header().type);
+  QUICHE_DCHECK_LE(db->Remaining(), state->frame_header().payload_length);
+  return HandleStatus(state, state->ResumeDecodingStructureInPayload(
+                                 &window_update_fields_, db));
+}
+
+DecodeStatus WindowUpdatePayloadDecoder::HandleStatus(FrameDecoderState* state,
+                                                      DecodeStatus status) {
+  HTTP2_DVLOG(2) << "HandleStatus: status=" << status
+                 << "; remaining_payload=" << state->remaining_payload();
+  if (status == DecodeStatus::kDecodeDone) {
+    if (state->remaining_payload() == 0) {
+      state->listener()->OnWindowUpdate(
+          state->frame_header(), window_update_fields_.window_size_increment);
+      return DecodeStatus::kDecodeDone;
+    }
+    // Payload is too long.
+    return state->ReportFrameSizeError();
+  }
+  // Not done decoding the structure. Either we've got more payload to decode,
+  // or we've run out because the payload is too short, in which case
+  // OnFrameSizeError will have already been called.
+  QUICHE_DCHECK(
+      (status == DecodeStatus::kDecodeInProgress &&
+       state->remaining_payload() > 0) ||
+      (status == DecodeStatus::kDecodeError && state->remaining_payload() == 0))
+      << "\n status=" << status
+      << "; remaining_payload=" << state->remaining_payload();
+  return status;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.h b/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.h
new file mode 100644
index 0000000..c12c347
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.h
@@ -0,0 +1,42 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_WINDOW_UPDATE_PAYLOAD_DECODER_H_
+#define QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_WINDOW_UPDATE_PAYLOAD_DECODER_H_
+
+// Decodes the payload of a WINDOW_UPDATE frame.
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/frame_decoder_state.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class WindowUpdatePayloadDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE WindowUpdatePayloadDecoder {
+ public:
+  // Starts decoding a WINDOW_UPDATE frame's payload, and completes it if
+  // the entire payload is in the provided decode buffer.
+  DecodeStatus StartDecodingPayload(FrameDecoderState* state, DecodeBuffer* db);
+
+  // Resumes decoding a WINDOW_UPDATE frame's payload that has been split across
+  // decode buffers.
+  DecodeStatus ResumeDecodingPayload(FrameDecoderState* state,
+                                     DecodeBuffer* db);
+
+ private:
+  friend class test::WindowUpdatePayloadDecoderPeer;
+
+  DecodeStatus HandleStatus(FrameDecoderState* state, DecodeStatus status);
+
+  Http2WindowUpdateFields window_update_fields_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_DECODER_PAYLOAD_DECODERS_WINDOW_UPDATE_PAYLOAD_DECODER_H_
diff --git a/quiche/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc b/quiche/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
new file mode 100644
index 0000000..3b339a4
--- /dev/null
+++ b/quiche/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
@@ -0,0 +1,95 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/decoder/payload_decoders/window_update_payload_decoder.h"
+
+#include <stddef.h>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/payload_decoders/payload_decoder_base_test_util.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class WindowUpdatePayloadDecoderPeer {
+ public:
+  static constexpr Http2FrameType FrameType() {
+    return Http2FrameType::WINDOW_UPDATE;
+  }
+
+  // Returns the mask of flags that affect the decoding of the payload (i.e.
+  // flags that that indicate the presence of certain fields or padding).
+  static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
+};
+
+namespace {
+
+struct Listener : public FramePartsCollector {
+  void OnWindowUpdate(const Http2FrameHeader& header,
+                      uint32_t window_size_increment) override {
+    HTTP2_VLOG(1) << "OnWindowUpdate: " << header
+                  << "; window_size_increment=" << window_size_increment;
+    EXPECT_EQ(Http2FrameType::WINDOW_UPDATE, header.type);
+    StartAndEndFrame(header)->OnWindowUpdate(header, window_size_increment);
+  }
+
+  void OnFrameSizeError(const Http2FrameHeader& header) override {
+    HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+    FrameError(header)->OnFrameSizeError(header);
+  }
+};
+
+class WindowUpdatePayloadDecoderTest
+    : public AbstractPayloadDecoderTest<WindowUpdatePayloadDecoder,
+                                        WindowUpdatePayloadDecoderPeer,
+                                        Listener> {
+ protected:
+  Http2WindowUpdateFields RandWindowUpdateFields() {
+    Http2WindowUpdateFields fields;
+    test::Randomize(&fields, RandomPtr());
+    HTTP2_VLOG(3) << "RandWindowUpdateFields: " << fields;
+    return fields;
+  }
+};
+
+// Confirm we get an error if the payload is not the correct size to hold
+// exactly one Http2WindowUpdateFields.
+TEST_F(WindowUpdatePayloadDecoderTest, WrongSize) {
+  auto approve_size = [](size_t size) {
+    return size != Http2WindowUpdateFields::EncodedSize();
+  };
+  Http2FrameBuilder fb;
+  fb.Append(RandWindowUpdateFields());
+  fb.Append(RandWindowUpdateFields());
+  fb.Append(RandWindowUpdateFields());
+  EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
+}
+
+TEST_F(WindowUpdatePayloadDecoderTest, VariousPayloads) {
+  for (int n = 0; n < 100; ++n) {
+    uint32_t stream_id = n == 0 ? 0 : RandStreamId();
+    Http2WindowUpdateFields fields = RandWindowUpdateFields();
+    Http2FrameBuilder fb;
+    fb.Append(fields);
+    Http2FrameHeader header(fb.size(), Http2FrameType::WINDOW_UPDATE,
+                            RandFlags(), stream_id);
+    set_frame_header(header);
+    FrameParts expected(header);
+    expected.SetOptWindowUpdateIncrement(fields.window_size_increment);
+    EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_block_collector.cc b/quiche/http2/hpack/decoder/hpack_block_collector.cc
new file mode 100644
index 0000000..620da14
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_block_collector.cc
@@ -0,0 +1,151 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_block_collector.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+
+HpackBlockCollector::HpackBlockCollector() = default;
+HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other)
+    : pending_entry_(other.pending_entry_), entries_(other.entries_) {}
+HpackBlockCollector::~HpackBlockCollector() = default;
+
+void HpackBlockCollector::OnIndexedHeader(size_t index) {
+  pending_entry_.OnIndexedHeader(index);
+  PushPendingEntry();
+}
+void HpackBlockCollector::OnDynamicTableSizeUpdate(size_t size) {
+  pending_entry_.OnDynamicTableSizeUpdate(size);
+  PushPendingEntry();
+}
+void HpackBlockCollector::OnStartLiteralHeader(HpackEntryType header_type,
+                                               size_t maybe_name_index) {
+  pending_entry_.OnStartLiteralHeader(header_type, maybe_name_index);
+}
+void HpackBlockCollector::OnNameStart(bool huffman_encoded, size_t len) {
+  pending_entry_.OnNameStart(huffman_encoded, len);
+}
+void HpackBlockCollector::OnNameData(const char* data, size_t len) {
+  pending_entry_.OnNameData(data, len);
+}
+void HpackBlockCollector::OnNameEnd() {
+  pending_entry_.OnNameEnd();
+}
+void HpackBlockCollector::OnValueStart(bool huffman_encoded, size_t len) {
+  pending_entry_.OnValueStart(huffman_encoded, len);
+}
+void HpackBlockCollector::OnValueData(const char* data, size_t len) {
+  pending_entry_.OnValueData(data, len);
+}
+void HpackBlockCollector::OnValueEnd() {
+  pending_entry_.OnValueEnd();
+  PushPendingEntry();
+}
+
+void HpackBlockCollector::PushPendingEntry() {
+  EXPECT_TRUE(pending_entry_.IsComplete());
+  HTTP2_DVLOG(2) << "PushPendingEntry: " << pending_entry_;
+  entries_.push_back(pending_entry_);
+  EXPECT_TRUE(entries_.back().IsComplete());
+  pending_entry_.Clear();
+}
+void HpackBlockCollector::Clear() {
+  pending_entry_.Clear();
+  entries_.clear();
+}
+
+void HpackBlockCollector::ExpectIndexedHeader(size_t index) {
+  entries_.push_back(
+      HpackEntryCollector(HpackEntryType::kIndexedHeader, index));
+}
+void HpackBlockCollector::ExpectDynamicTableSizeUpdate(size_t size) {
+  entries_.push_back(
+      HpackEntryCollector(HpackEntryType::kDynamicTableSizeUpdate, size));
+}
+void HpackBlockCollector::ExpectNameIndexAndLiteralValue(
+    HpackEntryType type,
+    size_t index,
+    bool value_huffman,
+    const std::string& value) {
+  entries_.push_back(HpackEntryCollector(type, index, value_huffman, value));
+}
+void HpackBlockCollector::ExpectLiteralNameAndValue(HpackEntryType type,
+                                                    bool name_huffman,
+                                                    const std::string& name,
+                                                    bool value_huffman,
+                                                    const std::string& value) {
+  entries_.push_back(
+      HpackEntryCollector(type, name_huffman, name, value_huffman, value));
+}
+
+void HpackBlockCollector::ShuffleEntries(Http2Random* rng) {
+  std::shuffle(entries_.begin(), entries_.end(), *rng);
+}
+
+void HpackBlockCollector::AppendToHpackBlockBuilder(
+    HpackBlockBuilder* hbb) const {
+  QUICHE_CHECK(IsNotPending());
+  for (const auto& entry : entries_) {
+    entry.AppendToHpackBlockBuilder(hbb);
+  }
+}
+
+AssertionResult HpackBlockCollector::ValidateSoleIndexedHeader(
+    size_t ndx) const {
+  VERIFY_TRUE(pending_entry_.IsClear());
+  VERIFY_EQ(1u, entries_.size());
+  VERIFY_TRUE(entries_.front().ValidateIndexedHeader(ndx));
+  return AssertionSuccess();
+}
+AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader(
+    HpackEntryType expected_type,
+    size_t expected_index,
+    bool expected_value_huffman,
+    absl::string_view expected_value) const {
+  VERIFY_TRUE(pending_entry_.IsClear());
+  VERIFY_EQ(1u, entries_.size());
+  VERIFY_TRUE(entries_.front().ValidateLiteralValueHeader(
+      expected_type, expected_index, expected_value_huffman, expected_value));
+  return AssertionSuccess();
+}
+AssertionResult HpackBlockCollector::ValidateSoleLiteralNameValueHeader(
+    HpackEntryType expected_type,
+    bool expected_name_huffman,
+    absl::string_view expected_name,
+    bool expected_value_huffman,
+    absl::string_view expected_value) const {
+  VERIFY_TRUE(pending_entry_.IsClear());
+  VERIFY_EQ(1u, entries_.size());
+  VERIFY_TRUE(entries_.front().ValidateLiteralNameValueHeader(
+      expected_type, expected_name_huffman, expected_name,
+      expected_value_huffman, expected_value));
+  return AssertionSuccess();
+}
+AssertionResult HpackBlockCollector::ValidateSoleDynamicTableSizeUpdate(
+    size_t size) const {
+  VERIFY_TRUE(pending_entry_.IsClear());
+  VERIFY_EQ(1u, entries_.size());
+  VERIFY_TRUE(entries_.front().ValidateDynamicTableSizeUpdate(size));
+  return AssertionSuccess();
+}
+
+AssertionResult HpackBlockCollector::VerifyEq(
+    const HpackBlockCollector& that) const {
+  VERIFY_EQ(pending_entry_, that.pending_entry_);
+  VERIFY_EQ(entries_, that.entries_);
+  return AssertionSuccess();
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_block_collector.h b/quiche/http2/hpack/decoder/hpack_block_collector.h
new file mode 100644
index 0000000..ccd11c6
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_block_collector.h
@@ -0,0 +1,128 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
+
+// HpackBlockCollector implements HpackEntryDecoderListener in order to record
+// the calls using HpackEntryCollector instances (one per HPACK entry). This
+// supports testing of HpackBlockDecoder, which decodes entire HPACK blocks.
+//
+// In addition to implementing the callback methods, HpackBlockCollector also
+// supports comparing two HpackBlockCollector instances (i.e. an expected and
+// an actual), or a sole HPACK entry against an expected value.
+
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_collector.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/test_tools/http2_random.h"
+
+namespace http2 {
+namespace test {
+
+class HpackBlockCollector : public HpackEntryDecoderListener {
+ public:
+  HpackBlockCollector();
+  HpackBlockCollector(const HpackBlockCollector& other);
+  ~HpackBlockCollector() override;
+
+  // Implementations of HpackEntryDecoderListener, forwarding to pending_entry_,
+  // an HpackEntryCollector for the "in-progress" HPACK entry. OnIndexedHeader
+  // and OnDynamicTableSizeUpdate are pending only for that one call, while
+  // OnStartLiteralHeader is followed by many calls, ending with OnValueEnd.
+  // Once all the calls for one HPACK entry have been received, PushPendingEntry
+  // is used to append the pending_entry_ entry to the collected entries_.
+  void OnIndexedHeader(size_t index) override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+  void OnStartLiteralHeader(HpackEntryType header_type,
+                            size_t maybe_name_index) override;
+  void OnNameStart(bool huffman_encoded, size_t len) override;
+  void OnNameData(const char* data, size_t len) override;
+  void OnNameEnd() override;
+  void OnValueStart(bool huffman_encoded, size_t len) override;
+  void OnValueData(const char* data, size_t len) override;
+  void OnValueEnd() override;
+
+  // Methods for creating a set of expectations (i.e. HPACK entries to compare
+  // against those collected by another instance of HpackBlockCollector).
+
+  // Add an HPACK entry for an indexed header.
+  void ExpectIndexedHeader(size_t index);
+
+  // Add an HPACK entry for a dynamic table size update.
+  void ExpectDynamicTableSizeUpdate(size_t size);
+
+  // Add an HPACK entry for a header entry with an index for the name, and a
+  // literal value.
+  void ExpectNameIndexAndLiteralValue(HpackEntryType type,
+                                      size_t index,
+                                      bool value_huffman,
+                                      const std::string& value);
+
+  // Add an HPACK entry for a header entry with a literal name and value.
+  void ExpectLiteralNameAndValue(HpackEntryType type,
+                                 bool name_huffman,
+                                 const std::string& name,
+                                 bool value_huffman,
+                                 const std::string& value);
+
+  // Shuffle the entries, in support of generating an HPACK block of entries
+  // in some random order.
+  void ShuffleEntries(Http2Random* rng);
+
+  // Serialize entries_ to the HpackBlockBuilder.
+  void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const;
+
+  // Return AssertionSuccess if there is just one entry, and it is an
+  // Indexed Header with the specified index.
+  ::testing::AssertionResult ValidateSoleIndexedHeader(size_t ndx) const;
+
+  // Return AssertionSuccess if there is just one entry, and it is a
+  // Dynamic Table Size Update with the specified size.
+  ::testing::AssertionResult ValidateSoleDynamicTableSizeUpdate(
+      size_t size) const;
+
+  // Return AssertionSuccess if there is just one entry, and it is a Header
+  // entry with an index for the name and a literal value.
+  ::testing::AssertionResult ValidateSoleLiteralValueHeader(
+      HpackEntryType expected_type,
+      size_t expected_index,
+      bool expected_value_huffman,
+      absl::string_view expected_value) const;
+
+  // Return AssertionSuccess if there is just one entry, and it is a Header
+  // with a literal name and literal value.
+  ::testing::AssertionResult ValidateSoleLiteralNameValueHeader(
+      HpackEntryType expected_type,
+      bool expected_name_huffman,
+      absl::string_view expected_name,
+      bool expected_value_huffman,
+      absl::string_view expected_value) const;
+
+  bool IsNotPending() const { return pending_entry_.IsClear(); }
+  bool IsClear() const { return IsNotPending() && entries_.empty(); }
+  void Clear();
+
+  ::testing::AssertionResult VerifyEq(const HpackBlockCollector& that) const;
+
+ private:
+  // Push the value of pending_entry_ onto entries_, and clear pending_entry_.
+  // The pending_entry_ must be complete.
+  void PushPendingEntry();
+
+  HpackEntryCollector pending_entry_;
+  std::vector<HpackEntryCollector> entries_;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
diff --git a/quiche/http2/hpack/decoder/hpack_block_decoder.cc b/quiche/http2/hpack/decoder/hpack_block_decoder.cc
new file mode 100644
index 0000000..8c8d4c0
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_block_decoder.cc
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_block_decoder.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+DecodeStatus HpackBlockDecoder::Decode(DecodeBuffer* db) {
+  if (!before_entry_) {
+    HTTP2_DVLOG(2) << "HpackBlockDecoder::Decode resume entry, db->Remaining="
+                   << db->Remaining();
+    DecodeStatus status = entry_decoder_.Resume(db, listener_);
+    switch (status) {
+      case DecodeStatus::kDecodeDone:
+        before_entry_ = true;
+        break;
+      case DecodeStatus::kDecodeInProgress:
+        QUICHE_DCHECK_EQ(0u, db->Remaining());
+        return DecodeStatus::kDecodeInProgress;
+      case DecodeStatus::kDecodeError:
+        HTTP2_CODE_COUNT_N(decompress_failure_3, 1, 23);
+        return DecodeStatus::kDecodeError;
+    }
+  }
+  QUICHE_DCHECK(before_entry_);
+  while (db->HasData()) {
+    HTTP2_DVLOG(2) << "HpackBlockDecoder::Decode start entry, db->Remaining="
+                   << db->Remaining();
+    DecodeStatus status = entry_decoder_.Start(db, listener_);
+    switch (status) {
+      case DecodeStatus::kDecodeDone:
+        continue;
+      case DecodeStatus::kDecodeInProgress:
+        QUICHE_DCHECK_EQ(0u, db->Remaining());
+        before_entry_ = false;
+        return DecodeStatus::kDecodeInProgress;
+      case DecodeStatus::kDecodeError:
+        HTTP2_CODE_COUNT_N(decompress_failure_3, 2, 23);
+        return DecodeStatus::kDecodeError;
+    }
+    QUICHE_DCHECK(false);
+  }
+  QUICHE_DCHECK(before_entry_);
+  return DecodeStatus::kDecodeDone;
+}
+
+std::string HpackBlockDecoder::DebugString() const {
+  return absl::StrCat(
+      "HpackBlockDecoder(", entry_decoder_.DebugString(), ", listener@",
+      absl::Hex(reinterpret_cast<intptr_t>(listener_)),
+      (before_entry_ ? ", between entries)" : ", in an entry)"));
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackBlockDecoder& v) {
+  return out << v.DebugString();
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_block_decoder.h b/quiche/http2/hpack/decoder/hpack_block_decoder.h
new file mode 100644
index 0000000..85ee8ff
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_block_decoder.h
@@ -0,0 +1,69 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_DECODER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_DECODER_H_
+
+// HpackBlockDecoder decodes an entire HPACK block (or the available portion
+// thereof in the DecodeBuffer) into entries, but doesn't include HPACK static
+// or dynamic table support, so table indices remain indices at this level.
+// Reports the entries to an HpackEntryDecoderListener.
+
+#include <string>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackBlockDecoder {
+ public:
+  explicit HpackBlockDecoder(HpackEntryDecoderListener* listener)
+      : listener_(listener) {
+    QUICHE_DCHECK_NE(listener_, nullptr);
+  }
+  ~HpackBlockDecoder() {}
+
+  HpackBlockDecoder(const HpackBlockDecoder&) = delete;
+  HpackBlockDecoder& operator=(const HpackBlockDecoder&) = delete;
+
+  // Prepares the decoder to start decoding a new HPACK block. Expected
+  // to be called from an implementation of Http2FrameDecoderListener's
+  // OnHeadersStart or OnPushPromiseStart methods.
+  void Reset() {
+    HTTP2_DVLOG(2) << "HpackBlockDecoder::Reset";
+    before_entry_ = true;
+  }
+
+  // Decode the fragment of the HPACK block contained in the decode buffer.
+  // Expected to be called from an implementation of Http2FrameDecoderListener's
+  // OnHpackFragment method.
+  DecodeStatus Decode(DecodeBuffer* db);
+
+  // Is the decoding process between entries (i.e. would the next byte be the
+  // first byte of a new HPACK entry)?
+  bool before_entry() const { return before_entry_; }
+
+  // Return error code after decoding error occurred in HpackEntryDecoder.
+  HpackDecodingError error() const { return entry_decoder_.error(); }
+
+  std::string DebugString() const;
+
+ private:
+  HpackEntryDecoder entry_decoder_;
+  HpackEntryDecoderListener* const listener_;
+  bool before_entry_ = true;
+};
+
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const HpackBlockDecoder& v);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_DECODER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_block_decoder_test.cc b/quiche/http2/hpack/decoder/hpack_block_decoder_test.cc
new file mode 100644
index 0000000..2cac66c
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_block_decoder_test.cc
@@ -0,0 +1,293 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_block_decoder.h"
+
+// Tests of HpackBlockDecoder.
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_block_collector.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/hpack/tools/hpack_example.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+class HpackBlockDecoderTest : public RandomDecoderTest {
+ protected:
+  HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) {
+    stop_decode_on_done_ = false;
+    decoder_.Reset();
+    // Make sure logging doesn't crash. Not examining the result.
+    std::ostringstream strm;
+    strm << decoder_;
+  }
+
+  DecodeStatus StartDecoding(DecodeBuffer* db) override {
+    collector_.Clear();
+    decoder_.Reset();
+    return ResumeDecoding(db);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* db) override {
+    DecodeStatus status = decoder_.Decode(db);
+
+    // Make sure logging doesn't crash. Not examining the result.
+    std::ostringstream strm;
+    strm << decoder_;
+
+    return status;
+  }
+
+  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* db,
+                                               const Validator& validator) {
+    bool return_non_zero_on_first = false;
+    return RandomDecoderTest::DecodeAndValidateSeveralWays(
+        db, return_non_zero_on_first, validator);
+  }
+
+  AssertionResult DecodeAndValidateSeveralWays(const HpackBlockBuilder& hbb,
+                                               const Validator& validator) {
+    DecodeBuffer db(hbb.buffer());
+    return DecodeAndValidateSeveralWays(&db, validator);
+  }
+
+  AssertionResult DecodeHpackExampleAndValidateSeveralWays(
+      absl::string_view hpack_example,
+      Validator validator) {
+    std::string input = HpackExampleToStringOrDie(hpack_example);
+    DecodeBuffer db(input);
+    return DecodeAndValidateSeveralWays(&db, validator);
+  }
+
+  uint8_t Rand8() { return Random().Rand8(); }
+
+  std::string Rand8String() { return Random().RandString(Rand8()); }
+
+  HpackBlockCollector collector_;
+  HpackEntryDecoderVLoggingListener listener_;
+  HpackBlockDecoder decoder_;
+};
+
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1
+TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) {
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader(
+        HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false,
+        "custom-header"));
+  };
+  const char hpack_example[] = R"(
+      40                                      | == Literal indexed ==
+      0a                                      |   Literal name (len = 10)
+      6375 7374 6f6d 2d6b 6579                | custom-key
+      0d                                      |   Literal value (len = 13)
+      6375 7374 6f6d 2d68 6561 6465 72        | custom-header
+                                              | -> custom-key:
+                                              |   custom-header
+      )";
+  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
+      hpack_example, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2
+TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) {
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralValueHeader(
+        HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path"));
+  };
+  const char hpack_example[] = R"(
+      04                                      | == Literal not indexed ==
+                                              |   Indexed name (idx = 4)
+                                              |     :path
+      0c                                      |   Literal value (len = 12)
+      2f73 616d 706c 652f 7061 7468           | /sample/path
+                                              | -> :path: /sample/path
+      )";
+  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
+      hpack_example, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3
+TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) {
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader(
+        HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false,
+        "secret"));
+  };
+  const char hpack_example[] = R"(
+      10                                      | == Literal never indexed ==
+      08                                      |   Literal name (len = 8)
+      7061 7373 776f 7264                     | password
+      06                                      |   Literal value (len = 6)
+      7365 6372 6574                          | secret
+                                              | -> password: secret
+      )";
+  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
+      hpack_example, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4
+TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) {
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleIndexedHeader(2));
+  };
+  const char hpack_example[] = R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      )";
+  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
+      hpack_example, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1
+TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) {
+  std::string example = R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      86                                      | == Indexed - Add ==
+                                              |   idx = 6
+                                              | -> :scheme: http
+      84                                      | == Indexed - Add ==
+                                              |   idx = 4
+                                              | -> :path: /
+      41                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 1)
+                                              |     :authority
+      0f                                      |   Literal value (len = 15)
+      7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
+                                              | -> :authority:
+                                              |   www.example.com
+      )";
+  HpackBlockCollector expected;
+  expected.ExpectIndexedHeader(2);
+  expected.ExpectIndexedHeader(6);
+  expected.ExpectIndexedHeader(4);
+  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
+                                          1, false, "www.example.com");
+  NoArgValidator do_check = [expected, this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected));
+  };
+  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
+      example, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1
+TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) {
+  std::string example = R"(
+      48                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 8)
+                                              |     :status
+      03                                      |   Literal value (len = 3)
+      3330 32                                 | 302
+                                              | -> :status: 302
+      58                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 24)
+                                              |     cache-control
+      07                                      |   Literal value (len = 7)
+      7072 6976 6174 65                       | private
+                                              | -> cache-control: private
+      61                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 33)
+                                              |     date
+      1d                                      |   Literal value (len = 29)
+      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
+      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:21 GMT
+      6e                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 46)
+                                              |     location
+      17                                      |   Literal value (len = 23)
+      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
+      706c 652e 636f 6d                       | ple.com
+                                              | -> location:
+                                              |   https://www.example.com
+      )";
+  HpackBlockCollector expected;
+  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
+                                          8, false, "302");
+  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
+                                          24, false, "private");
+  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
+                                          33, false,
+                                          "Mon, 21 Oct 2013 20:13:21 GMT");
+  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
+                                          46, false, "https://www.example.com");
+  NoArgValidator do_check = [expected, this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected));
+  };
+  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
+      example, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+// Generate a bunch of HPACK block entries to expect, use those expectations
+// to generate an HPACK block, then decode it and confirm it matches those
+// expectations. Some of these are invalid (such as Indexed, with index=0),
+// but well-formed, and the decoder doesn't check for validity, just
+// well-formedness. That includes the validity of the strings not being checked,
+// such as lower-case ascii for the names, and valid Huffman encodings.
+TEST_F(HpackBlockDecoderTest, Computed) {
+  HpackBlockCollector expected;
+  expected.ExpectIndexedHeader(0);
+  expected.ExpectIndexedHeader(1);
+  expected.ExpectIndexedHeader(126);
+  expected.ExpectIndexedHeader(127);
+  expected.ExpectIndexedHeader(128);
+  expected.ExpectDynamicTableSizeUpdate(0);
+  expected.ExpectDynamicTableSizeUpdate(1);
+  expected.ExpectDynamicTableSizeUpdate(14);
+  expected.ExpectDynamicTableSizeUpdate(15);
+  expected.ExpectDynamicTableSizeUpdate(30);
+  expected.ExpectDynamicTableSizeUpdate(31);
+  expected.ExpectDynamicTableSizeUpdate(4095);
+  expected.ExpectDynamicTableSizeUpdate(4096);
+  expected.ExpectDynamicTableSizeUpdate(8192);
+  for (auto type : {HpackEntryType::kIndexedLiteralHeader,
+                    HpackEntryType::kUnindexedLiteralHeader,
+                    HpackEntryType::kNeverIndexedLiteralHeader}) {
+    for (bool value_huffman : {false, true}) {
+      // An entry with an index for the name. Ensure the name index
+      // is not zero by adding one to the Rand8() result.
+      expected.ExpectNameIndexAndLiteralValue(type, Rand8() + 1, value_huffman,
+                                              Rand8String());
+      // And two entries with literal names, one plain, one huffman encoded.
+      expected.ExpectLiteralNameAndValue(type, false, Rand8String(),
+                                         value_huffman, Rand8String());
+      expected.ExpectLiteralNameAndValue(type, true, Rand8String(),
+                                         value_huffman, Rand8String());
+    }
+  }
+  // Shuffle the entries and serialize them to produce an HPACK block.
+  expected.ShuffleEntries(RandomPtr());
+  HpackBlockBuilder hbb;
+  expected.AppendToHpackBlockBuilder(&hbb);
+
+  NoArgValidator do_check = [expected, this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected));
+  };
+  EXPECT_TRUE(
+      DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder.cc b/quiche/http2/hpack/decoder/hpack_decoder.cc
new file mode 100644
index 0000000..77ad8bd
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder.cc
@@ -0,0 +1,125 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder.h"
+
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+HpackDecoder::HpackDecoder(HpackDecoderListener* listener,
+                           size_t max_string_size)
+    : decoder_state_(listener),
+      entry_buffer_(&decoder_state_, max_string_size),
+      block_decoder_(&entry_buffer_),
+      error_(HpackDecodingError::kOk) {}
+
+HpackDecoder::~HpackDecoder() = default;
+
+void HpackDecoder::set_max_string_size_bytes(size_t max_string_size_bytes) {
+  entry_buffer_.set_max_string_size_bytes(max_string_size_bytes);
+}
+
+void HpackDecoder::ApplyHeaderTableSizeSetting(uint32_t max_header_table_size) {
+  decoder_state_.ApplyHeaderTableSizeSetting(max_header_table_size);
+}
+
+bool HpackDecoder::StartDecodingBlock() {
+  HTTP2_DVLOG(3) << "HpackDecoder::StartDecodingBlock, error_detected="
+                 << (DetectError() ? "true" : "false");
+  if (DetectError()) {
+    return false;
+  }
+  // TODO(jamessynge): Eliminate Reset(), which shouldn't be necessary
+  // if there are no errors, and shouldn't be necessary with errors if
+  // we never resume decoding after an error has been detected.
+  block_decoder_.Reset();
+  decoder_state_.OnHeaderBlockStart();
+  return true;
+}
+
+bool HpackDecoder::DecodeFragment(DecodeBuffer* db) {
+  HTTP2_DVLOG(3) << "HpackDecoder::DecodeFragment, error_detected="
+                 << (DetectError() ? "true" : "false")
+                 << ", size=" << db->Remaining();
+  if (DetectError()) {
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 3, 23);
+    return false;
+  }
+  // Decode contents of db as an HPACK block fragment, forwards the decoded
+  // entries to entry_buffer_, which in turn forwards them to decode_state_,
+  // which finally forwards them to the HpackDecoderListener.
+  DecodeStatus status = block_decoder_.Decode(db);
+  if (status == DecodeStatus::kDecodeError) {
+    ReportError(block_decoder_.error(), "");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 4, 23);
+    return false;
+  } else if (DetectError()) {
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 5, 23);
+    return false;
+  }
+  // Should be positioned between entries iff decoding is complete.
+  QUICHE_DCHECK_EQ(block_decoder_.before_entry(),
+                   status == DecodeStatus::kDecodeDone)
+      << status;
+  if (!block_decoder_.before_entry()) {
+    entry_buffer_.BufferStringsIfUnbuffered();
+  }
+  return true;
+}
+
+bool HpackDecoder::EndDecodingBlock() {
+  HTTP2_DVLOG(3) << "HpackDecoder::EndDecodingBlock, error_detected="
+                 << (DetectError() ? "true" : "false");
+  if (DetectError()) {
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 6, 23);
+    return false;
+  }
+  if (!block_decoder_.before_entry()) {
+    // The HPACK block ended in the middle of an entry.
+    ReportError(HpackDecodingError::kTruncatedBlock, "");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 7, 23);
+    return false;
+  }
+  decoder_state_.OnHeaderBlockEnd();
+  if (DetectError()) {
+    // HpackDecoderState will have reported the error.
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 8, 23);
+    return false;
+  }
+  return true;
+}
+
+bool HpackDecoder::DetectError() {
+  if (error_ != HpackDecodingError::kOk) {
+    return true;
+  }
+
+  if (decoder_state_.error() != HpackDecodingError::kOk) {
+    HTTP2_DVLOG(2) << "Error detected in decoder_state_";
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 10, 23);
+    error_ = decoder_state_.error();
+    detailed_error_ = decoder_state_.detailed_error();
+  }
+
+  return error_ != HpackDecodingError::kOk;
+}
+
+void HpackDecoder::ReportError(HpackDecodingError error,
+                               std::string detailed_error) {
+  HTTP2_DVLOG(3) << "HpackDecoder::ReportError is new="
+                 << (error_ == HpackDecodingError::kOk ? "true" : "false")
+                 << ", error: " << HpackDecodingErrorToString(error);
+  if (error_ == HpackDecodingError::kOk) {
+    error_ = error;
+    detailed_error_ = detailed_error;
+    decoder_state_.listener()->OnHeaderErrorDetected(
+        HpackDecodingErrorToString(error));
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder.h b/quiche/http2/hpack/decoder/hpack_decoder.h
new file mode 100644
index 0000000..393a6ca
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder.h
@@ -0,0 +1,132 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_H_
+
+// Decodes HPACK blocks, calls an HpackDecoderListener with the decoded header
+// entries. Also notifies the listener of errors and of the boundaries of the
+// HPACK blocks.
+
+// TODO(jamessynge): Add feature allowing an HpackEntryDecoderListener
+// sub-class (and possibly others) to be passed in for counting events,
+// so that deciding whether to count is not done by having lots of if
+// statements, but instead by inserting an indirection only when needed.
+
+// TODO(jamessynge): Consider whether to return false from methods below
+// when an error has been previously detected. It protects calling code
+// from its failure to pay attention to previous errors, but should we
+// spend time to do that?
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_block_decoder.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_state.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+#include "quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class HpackDecoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE HpackDecoder {
+ public:
+  HpackDecoder(HpackDecoderListener* listener, size_t max_string_size);
+  virtual ~HpackDecoder();
+
+  HpackDecoder(const HpackDecoder&) = delete;
+  HpackDecoder& operator=(const HpackDecoder&) = delete;
+
+  // max_string_size specifies the maximum size of an on-the-wire string (name
+  // or value, plain or Huffman encoded) that will be accepted. See sections
+  // 5.1 and 5.2 of RFC 7541. This is a defense against OOM attacks; HTTP/2
+  // allows a decoder to enforce any limit of the size of the header lists
+  // that it is willing to decode, including less than the MAX_HEADER_LIST_SIZE
+  // setting, a setting that is initially unlimited. For example, we might
+  // choose to send a MAX_HEADER_LIST_SIZE of 64KB, and to use that same value
+  // as the upper bound for individual strings.
+  void set_max_string_size_bytes(size_t max_string_size_bytes);
+
+  // ApplyHeaderTableSizeSetting notifies this object that this endpoint has
+  // received a SETTINGS ACK frame acknowledging an earlier SETTINGS frame from
+  // this endpoint specifying a new value for SETTINGS_HEADER_TABLE_SIZE (the
+  // maximum size of the dynamic table that this endpoint will use to decode
+  // HPACK blocks).
+  // Because a SETTINGS frame can contain SETTINGS_HEADER_TABLE_SIZE values,
+  // the caller must keep track of those multiple changes, and make
+  // corresponding calls to this method. In particular, a call must be made
+  // with the lowest value acknowledged by the peer, and a call must be made
+  // with the final value acknowledged, in that order; additional calls may
+  // be made if additional values were sent. These calls must be made between
+  // decoding the SETTINGS ACK, and before the next HPACK block is decoded.
+  void ApplyHeaderTableSizeSetting(uint32_t max_header_table_size);
+
+  // Returns the most recently applied value of SETTINGS_HEADER_TABLE_SIZE.
+  size_t GetCurrentHeaderTableSizeSetting() const {
+    return decoder_state_.GetCurrentHeaderTableSizeSetting();
+  }
+
+  // Prepares the decoder for decoding a new HPACK block, and announces this to
+  // its listener. Returns true if OK to continue with decoding, false if an
+  // error has been detected, which for StartDecodingBlock means the error was
+  // detected while decoding a previous HPACK block.
+  bool StartDecodingBlock();
+
+  // Decodes a fragment (some or all of the remainder) of an HPACK block,
+  // reporting header entries (name & value pairs) that it completely decodes
+  // in the process to the listener. Returns true successfully decoded, false if
+  // an error has been detected, either during decoding of the fragment, or
+  // prior to this call.
+  bool DecodeFragment(DecodeBuffer* db);
+
+  // Completes the process of decoding an HPACK block: if the HPACK block was
+  // properly terminated, announces the end of the header list to the listener
+  // and returns true; else returns false.
+  bool EndDecodingBlock();
+
+  // If no error has been detected so far, query |decoder_state_| for errors and
+  // set |error_| if necessary.  Returns true if an error has ever been
+  // detected.
+  bool DetectError();
+
+  size_t GetDynamicTableSize() const {
+    return decoder_state_.GetDynamicTableSize();
+  }
+
+  // Error code if an error has occurred, HpackDecodingError::kOk otherwise.
+  HpackDecodingError error() const { return error_; }
+
+  std::string detailed_error() const { return detailed_error_; }
+
+ private:
+  friend class test::HpackDecoderPeer;
+
+  // Reports an error to the listener IF this is the first error detected.
+  void ReportError(HpackDecodingError error, std::string detailed_error);
+
+  // The decompressor state, as defined by HPACK (i.e. the static and dynamic
+  // tables).
+  HpackDecoderState decoder_state_;
+
+  // Assembles the various parts of a header entry into whole entries.
+  HpackWholeEntryBuffer entry_buffer_;
+
+  // The decoder of HPACK blocks into entry parts, passed to entry_buffer_.
+  HpackBlockDecoder block_decoder_;
+
+  // Error code if an error has occurred, HpackDecodingError::kOk otherwise.
+  HpackDecodingError error_;
+  std::string detailed_error_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_listener.cc b/quiche/http2/hpack/decoder/hpack_decoder_listener.cc
new file mode 100644
index 0000000..75a5969
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_listener.cc
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_listener.h"
+
+namespace http2 {
+
+HpackDecoderListener::HpackDecoderListener() = default;
+HpackDecoderListener::~HpackDecoderListener() = default;
+
+HpackDecoderNoOpListener::HpackDecoderNoOpListener() = default;
+HpackDecoderNoOpListener::~HpackDecoderNoOpListener() = default;
+
+void HpackDecoderNoOpListener::OnHeaderListStart() {}
+void HpackDecoderNoOpListener::OnHeader(const std::string& /*name*/,
+                                        const std::string& /*value*/) {}
+void HpackDecoderNoOpListener::OnHeaderListEnd() {}
+void HpackDecoderNoOpListener::OnHeaderErrorDetected(
+    absl::string_view /*error_message*/) {}
+
+// static
+HpackDecoderNoOpListener* HpackDecoderNoOpListener::NoOpListener() {
+  static HpackDecoderNoOpListener* static_instance =
+      new HpackDecoderNoOpListener();
+  return static_instance;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_listener.h b/quiche/http2/hpack/decoder/hpack_decoder_listener.h
new file mode 100644
index 0000000..bd87c62
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_listener.h
@@ -0,0 +1,61 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Defines HpackDecoderListener, the base class of listeners for HTTP header
+// lists decoded from an HPACK block.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackDecoderListener {
+ public:
+  HpackDecoderListener();
+  virtual ~HpackDecoderListener();
+
+  // OnHeaderListStart is called at the start of decoding an HPACK block into
+  // an HTTP/2 header list. Will only be called once per block, even if it
+  // extends into CONTINUATION frames.
+  virtual void OnHeaderListStart() = 0;
+
+  // Called for each header name-value pair that is decoded, in the order they
+  // appear in the HPACK block. Multiple values for a given key will be emitted
+  // as multiple calls to OnHeader.
+  virtual void OnHeader(const std::string& name, const std::string& value) = 0;
+
+  // OnHeaderListEnd is called after successfully decoding an HPACK block into
+  // an HTTP/2 header list. Will only be called once per block, even if it
+  // extends into CONTINUATION frames.
+  virtual void OnHeaderListEnd() = 0;
+
+  // OnHeaderErrorDetected is called if an error is detected while decoding.
+  // error_message may be used in a GOAWAY frame as the Opaque Data.
+  virtual void OnHeaderErrorDetected(absl::string_view error_message) = 0;
+};
+
+// A no-op implementation of HpackDecoderListener, useful for ignoring
+// callbacks once an error is detected.
+class QUICHE_EXPORT_PRIVATE HpackDecoderNoOpListener
+    : public HpackDecoderListener {
+ public:
+  HpackDecoderNoOpListener();
+  ~HpackDecoderNoOpListener() override;
+
+  void OnHeaderListStart() override;
+  void OnHeader(const std::string& name, const std::string& value) override;
+  void OnHeaderListEnd() override;
+  void OnHeaderErrorDetected(absl::string_view error_message) override;
+
+  // Returns a listener that ignores all the calls.
+  static HpackDecoderNoOpListener* NoOpListener();
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_LISTENER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_state.cc b/quiche/http2/hpack/decoder/hpack_decoder_state.cc
new file mode 100644
index 0000000..c8672bb
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_state.cc
@@ -0,0 +1,226 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_state.h"
+
+#include <utility>
+
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace http2 {
+namespace {
+
+std::string ExtractString(HpackDecoderStringBuffer* string_buffer) {
+  if (string_buffer->IsBuffered()) {
+    return string_buffer->ReleaseString();
+  } else {
+    auto result = std::string(string_buffer->str());
+    string_buffer->Reset();
+    return result;
+  }
+}
+
+}  // namespace
+
+HpackDecoderState::HpackDecoderState(HpackDecoderListener* listener)
+    : listener_(listener),
+      final_header_table_size_(Http2SettingsInfo::DefaultHeaderTableSize()),
+      lowest_header_table_size_(final_header_table_size_),
+      require_dynamic_table_size_update_(false),
+      allow_dynamic_table_size_update_(true),
+      saw_dynamic_table_size_update_(false),
+      error_(HpackDecodingError::kOk) {
+  QUICHE_CHECK(listener_);
+}
+
+HpackDecoderState::~HpackDecoderState() = default;
+
+void HpackDecoderState::ApplyHeaderTableSizeSetting(
+    uint32_t header_table_size) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::ApplyHeaderTableSizeSetting("
+                 << header_table_size << ")";
+  QUICHE_DCHECK_LE(lowest_header_table_size_, final_header_table_size_);
+  if (header_table_size < lowest_header_table_size_) {
+    lowest_header_table_size_ = header_table_size;
+  }
+  final_header_table_size_ = header_table_size;
+  HTTP2_DVLOG(2) << "low water mark: " << lowest_header_table_size_;
+  HTTP2_DVLOG(2) << "final limit: " << final_header_table_size_;
+}
+
+// Called to notify this object that we're starting to decode an HPACK block
+// (e.g. a HEADERS or PUSH_PROMISE frame's header has been decoded).
+void HpackDecoderState::OnHeaderBlockStart() {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnHeaderBlockStart";
+  // This instance can't be reused after an error has been detected, as we must
+  // assume that the encoder and decoder compression states are no longer
+  // synchronized.
+  QUICHE_DCHECK(error_ == HpackDecodingError::kOk)
+      << HpackDecodingErrorToString(error_);
+  QUICHE_DCHECK_LE(lowest_header_table_size_, final_header_table_size_);
+  allow_dynamic_table_size_update_ = true;
+  saw_dynamic_table_size_update_ = false;
+  // If the peer has acknowledged a HEADER_TABLE_SIZE smaller than that which
+  // its HPACK encoder has been using, then the next HPACK block it sends MUST
+  // start with a Dynamic Table Size Update entry that is at least as low as
+  // lowest_header_table_size_. That may be followed by another as great as
+  // final_header_table_size_, if those are different.
+  require_dynamic_table_size_update_ =
+      (lowest_header_table_size_ <
+           decoder_tables_.current_header_table_size() ||
+       final_header_table_size_ < decoder_tables_.header_table_size_limit());
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnHeaderListStart "
+                 << "require_dynamic_table_size_update_="
+                 << require_dynamic_table_size_update_;
+  listener_->OnHeaderListStart();
+}
+
+void HpackDecoderState::OnIndexedHeader(size_t index) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnIndexedHeader: " << index;
+  if (error_ != HpackDecodingError::kOk) {
+    return;
+  }
+  if (require_dynamic_table_size_update_) {
+    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
+    return;
+  }
+  allow_dynamic_table_size_update_ = false;
+  const HpackStringPair* entry = decoder_tables_.Lookup(index);
+  if (entry != nullptr) {
+    listener_->OnHeader(entry->name, entry->value);
+  } else {
+    ReportError(HpackDecodingError::kInvalidIndex, "");
+  }
+}
+
+void HpackDecoderState::OnNameIndexAndLiteralValue(
+    HpackEntryType entry_type,
+    size_t name_index,
+    HpackDecoderStringBuffer* value_buffer) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnNameIndexAndLiteralValue "
+                 << entry_type << ", " << name_index << ", "
+                 << value_buffer->str();
+  if (error_ != HpackDecodingError::kOk) {
+    return;
+  }
+  if (require_dynamic_table_size_update_) {
+    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
+    return;
+  }
+  allow_dynamic_table_size_update_ = false;
+  const HpackStringPair* entry = decoder_tables_.Lookup(name_index);
+  if (entry != nullptr) {
+    std::string value(ExtractString(value_buffer));
+    listener_->OnHeader(entry->name, value);
+    if (entry_type == HpackEntryType::kIndexedLiteralHeader) {
+      decoder_tables_.Insert(entry->name, std::move(value));
+    }
+  } else {
+    ReportError(HpackDecodingError::kInvalidNameIndex, "");
+  }
+}
+
+void HpackDecoderState::OnLiteralNameAndValue(
+    HpackEntryType entry_type,
+    HpackDecoderStringBuffer* name_buffer,
+    HpackDecoderStringBuffer* value_buffer) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnLiteralNameAndValue " << entry_type
+                 << ", " << name_buffer->str() << ", " << value_buffer->str();
+  if (error_ != HpackDecodingError::kOk) {
+    return;
+  }
+  if (require_dynamic_table_size_update_) {
+    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
+    return;
+  }
+  allow_dynamic_table_size_update_ = false;
+  std::string name(ExtractString(name_buffer));
+  std::string value(ExtractString(value_buffer));
+  listener_->OnHeader(name, value);
+  if (entry_type == HpackEntryType::kIndexedLiteralHeader) {
+    decoder_tables_.Insert(std::move(name), std::move(value));
+  }
+}
+
+void HpackDecoderState::OnDynamicTableSizeUpdate(size_t size_limit) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnDynamicTableSizeUpdate " << size_limit
+                 << ", required="
+                 << (require_dynamic_table_size_update_ ? "true" : "false")
+                 << ", allowed="
+                 << (allow_dynamic_table_size_update_ ? "true" : "false");
+  if (error_ != HpackDecodingError::kOk) {
+    return;
+  }
+  QUICHE_DCHECK_LE(lowest_header_table_size_, final_header_table_size_);
+  if (!allow_dynamic_table_size_update_) {
+    // At most two dynamic table size updates allowed at the start, and not
+    // after a header.
+    ReportError(HpackDecodingError::kDynamicTableSizeUpdateNotAllowed, "");
+    return;
+  }
+  if (require_dynamic_table_size_update_) {
+    // The new size must not be greater than the low water mark.
+    if (size_limit > lowest_header_table_size_) {
+      ReportError(
+          HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark,
+          "");
+      return;
+    }
+    require_dynamic_table_size_update_ = false;
+  } else if (size_limit > final_header_table_size_) {
+    // The new size must not be greater than the final max header table size
+    // that the peer acknowledged.
+    ReportError(
+        HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting,
+        "");
+    return;
+  }
+  decoder_tables_.DynamicTableSizeUpdate(size_limit);
+  if (saw_dynamic_table_size_update_) {
+    allow_dynamic_table_size_update_ = false;
+  } else {
+    saw_dynamic_table_size_update_ = true;
+  }
+  // We no longer need to keep an eye out for a lower header table size.
+  lowest_header_table_size_ = final_header_table_size_;
+}
+
+void HpackDecoderState::OnHpackDecodeError(HpackDecodingError error,
+                                           std::string detailed_error) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnHpackDecodeError "
+                 << HpackDecodingErrorToString(error);
+  if (error_ == HpackDecodingError::kOk) {
+    ReportError(error, detailed_error);
+  }
+}
+
+void HpackDecoderState::OnHeaderBlockEnd() {
+  HTTP2_DVLOG(2) << "HpackDecoderState::OnHeaderBlockEnd";
+  if (error_ != HpackDecodingError::kOk) {
+    return;
+  }
+  if (require_dynamic_table_size_update_) {
+    // Apparently the HPACK block was empty, but we needed it to contain at
+    // least 1 dynamic table size update.
+    ReportError(HpackDecodingError::kMissingDynamicTableSizeUpdate, "");
+  } else {
+    listener_->OnHeaderListEnd();
+  }
+}
+
+void HpackDecoderState::ReportError(HpackDecodingError error,
+                                    std::string detailed_error) {
+  HTTP2_DVLOG(2) << "HpackDecoderState::ReportError is new="
+                 << (error_ == HpackDecodingError::kOk ? "true" : "false")
+                 << ", error: " << HpackDecodingErrorToString(error);
+  if (error_ == HpackDecodingError::kOk) {
+    listener_->OnHeaderErrorDetected(HpackDecodingErrorToString(error));
+    error_ = error;
+    detailed_error_ = detailed_error;
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_state.h b/quiche/http2/hpack/decoder/hpack_decoder_state.h
new file mode 100644
index 0000000..272805f
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_state.h
@@ -0,0 +1,138 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// HpackDecoderState maintains the HPACK decompressor state; i.e. updates the
+// HPACK dynamic table according to RFC 7541 as the entries in an HPACK block
+// are decoded, and reads from the static and dynamic tables in order to build
+// complete header entries. Calls an HpackDecoderListener with the completely
+// decoded headers (i.e. after resolving table indices into names or values),
+// thus translating the decoded HPACK entries into HTTP/2 headers.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+#include "quiche/http2/hpack/decoder/hpack_whole_entry_listener.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+class HpackDecoderStatePeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE HpackDecoderState : public HpackWholeEntryListener {
+ public:
+  explicit HpackDecoderState(HpackDecoderListener* listener);
+  ~HpackDecoderState() override;
+
+  HpackDecoderState(const HpackDecoderState&) = delete;
+  HpackDecoderState& operator=(const HpackDecoderState&) = delete;
+
+  // Set the listener to be notified when a whole entry has been decoded,
+  // including resolving name or name and value references.
+  // The listener may be changed at any time.
+  HpackDecoderListener* listener() const { return listener_; }
+
+  // ApplyHeaderTableSizeSetting notifies this object that this endpoint has
+  // received a SETTINGS ACK frame acknowledging an earlier SETTINGS frame from
+  // this endpoint specifying a new value for SETTINGS_HEADER_TABLE_SIZE (the
+  // maximum size of the dynamic table that this endpoint will use to decode
+  // HPACK blocks).
+  // Because a SETTINGS frame can contain SETTINGS_HEADER_TABLE_SIZE values,
+  // the caller must keep track of those multiple changes, and make
+  // corresponding calls to this method. In particular, a call must be made
+  // with the lowest value acknowledged by the peer, and a call must be made
+  // with the final value acknowledged, in that order; additional calls may
+  // be made if additional values were sent. These calls must be made between
+  // decoding the SETTINGS ACK, and before the next HPACK block is decoded.
+  void ApplyHeaderTableSizeSetting(uint32_t max_header_table_size);
+
+  // Returns the most recently applied value of SETTINGS_HEADER_TABLE_SIZE.
+  size_t GetCurrentHeaderTableSizeSetting() const {
+    return final_header_table_size_;
+  }
+
+  // OnHeaderBlockStart notifies this object that we're starting to decode the
+  // HPACK payload of a HEADERS or PUSH_PROMISE frame.
+  void OnHeaderBlockStart();
+
+  // Implement the HpackWholeEntryListener methods, each of which notifies this
+  // object when an entire entry has been decoded.
+  void OnIndexedHeader(size_t index) override;
+  void OnNameIndexAndLiteralValue(
+      HpackEntryType entry_type,
+      size_t name_index,
+      HpackDecoderStringBuffer* value_buffer) override;
+  void OnLiteralNameAndValue(HpackEntryType entry_type,
+                             HpackDecoderStringBuffer* name_buffer,
+                             HpackDecoderStringBuffer* value_buffer) override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+  void OnHpackDecodeError(HpackDecodingError error,
+                          std::string detailed_error) override;
+
+  // OnHeaderBlockEnd notifies this object that an entire HPACK block has been
+  // decoded, which might have extended into CONTINUATION blocks.
+  void OnHeaderBlockEnd();
+
+  // Returns error code after an error has been detected and reported.
+  // No further callbacks will be made to the listener.
+  HpackDecodingError error() const { return error_; }
+
+  size_t GetDynamicTableSize() const {
+    return decoder_tables_.current_header_table_size();
+  }
+
+  const HpackDecoderTables& decoder_tables_for_test() const {
+    return decoder_tables_;
+  }
+
+  std::string detailed_error() const { return detailed_error_; }
+
+ private:
+  friend class test::HpackDecoderStatePeer;
+
+  // Reports an error to the listener IF this is the first error detected.
+  void ReportError(HpackDecodingError error, std::string detailed_error);
+
+  // The static and dynamic HPACK tables.
+  HpackDecoderTables decoder_tables_;
+
+  // The listener to be notified of headers, the start and end of header
+  // lists, and of errors.
+  HpackDecoderListener* listener_;
+
+  // The most recent HEADER_TABLE_SIZE setting acknowledged by the peer.
+  uint32_t final_header_table_size_;
+
+  // The lowest HEADER_TABLE_SIZE setting acknowledged by the peer; valid until
+  // the next HPACK block is decoded.
+  // TODO(jamessynge): Test raising the HEADER_TABLE_SIZE.
+  uint32_t lowest_header_table_size_;
+
+  // Must the next (first) HPACK entry be a dynamic table size update?
+  bool require_dynamic_table_size_update_;
+
+  // May the next (first or second) HPACK entry be a dynamic table size update?
+  bool allow_dynamic_table_size_update_;
+
+  // Have we already seen a dynamic table size update in this HPACK block?
+  bool saw_dynamic_table_size_update_;
+
+  // Has an error already been detected and reported to the listener?
+  HpackDecodingError error_;
+  std::string detailed_error_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STATE_H_
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc
new file mode 100644
index 0000000..566b617
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc
@@ -0,0 +1,549 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_state.h"
+
+// Tests of HpackDecoderState.
+
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using ::testing::Eq;
+using ::testing::Mock;
+using ::testing::StrictMock;
+
+namespace http2 {
+namespace test {
+class HpackDecoderStatePeer {
+ public:
+  static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) {
+    return &state->decoder_tables_;
+  }
+};
+
+namespace {
+
+class MockHpackDecoderListener : public HpackDecoderListener {
+ public:
+  MOCK_METHOD(void, OnHeaderListStart, (), (override));
+  MOCK_METHOD(void,
+              OnHeader,
+              (const std::string& name, const std::string& value),
+              (override));
+  MOCK_METHOD(void, OnHeaderListEnd, (), (override));
+  MOCK_METHOD(void,
+              OnHeaderErrorDetected,
+              (absl::string_view error_message),
+              (override));
+};
+
+enum StringBacking { STATIC, UNBUFFERED, BUFFERED };
+
+class HpackDecoderStateTest : public QuicheTest {
+ protected:
+  HpackDecoderStateTest() : decoder_state_(&listener_) {}
+
+  HpackDecoderTables* GetDecoderTables() {
+    return HpackDecoderStatePeer::GetDecoderTables(&decoder_state_);
+  }
+
+  const HpackStringPair* Lookup(size_t index) {
+    return GetDecoderTables()->Lookup(index);
+  }
+
+  size_t current_header_table_size() {
+    return GetDecoderTables()->current_header_table_size();
+  }
+
+  size_t header_table_size_limit() {
+    return GetDecoderTables()->header_table_size_limit();
+  }
+
+  void set_header_table_size_limit(size_t size) {
+    GetDecoderTables()->DynamicTableSizeUpdate(size);
+  }
+
+  void SetStringBuffer(const char* s,
+                       StringBacking backing,
+                       HpackDecoderStringBuffer* string_buffer) {
+    switch (backing) {
+      case STATIC:
+        string_buffer->Set(s, true);
+        break;
+      case UNBUFFERED:
+        string_buffer->Set(s, false);
+        break;
+      case BUFFERED:
+        string_buffer->Set(s, false);
+        string_buffer->BufferStringIfUnbuffered();
+        break;
+    }
+  }
+
+  void SetName(const char* s, StringBacking backing) {
+    SetStringBuffer(s, backing, &name_buffer_);
+  }
+
+  void SetValue(const char* s, StringBacking backing) {
+    SetStringBuffer(s, backing, &value_buffer_);
+  }
+
+  void SendStartAndVerifyCallback() {
+    EXPECT_CALL(listener_, OnHeaderListStart());
+    decoder_state_.OnHeaderBlockStart();
+    Mock::VerifyAndClearExpectations(&listener_);
+  }
+
+  void SendSizeUpdate(size_t size) {
+    decoder_state_.OnDynamicTableSizeUpdate(size);
+    Mock::VerifyAndClearExpectations(&listener_);
+  }
+
+  void SendIndexAndVerifyCallback(size_t index,
+                                  HpackEntryType /*expected_type*/,
+                                  const char* expected_name,
+                                  const char* expected_value) {
+    EXPECT_CALL(listener_, OnHeader(Eq(expected_name), Eq(expected_value)));
+    decoder_state_.OnIndexedHeader(index);
+    Mock::VerifyAndClearExpectations(&listener_);
+  }
+
+  void SendValueAndVerifyCallback(size_t name_index,
+                                  HpackEntryType entry_type,
+                                  const char* name,
+                                  const char* value,
+                                  StringBacking value_backing) {
+    SetValue(value, value_backing);
+    EXPECT_CALL(listener_, OnHeader(Eq(name), Eq(value)));
+    decoder_state_.OnNameIndexAndLiteralValue(entry_type, name_index,
+                                              &value_buffer_);
+    Mock::VerifyAndClearExpectations(&listener_);
+  }
+
+  void SendNameAndValueAndVerifyCallback(HpackEntryType entry_type,
+                                         const char* name,
+                                         StringBacking name_backing,
+                                         const char* value,
+                                         StringBacking value_backing) {
+    SetName(name, name_backing);
+    SetValue(value, value_backing);
+    EXPECT_CALL(listener_, OnHeader(Eq(name), Eq(value)));
+    decoder_state_.OnLiteralNameAndValue(entry_type, &name_buffer_,
+                                         &value_buffer_);
+    Mock::VerifyAndClearExpectations(&listener_);
+  }
+
+  void SendEndAndVerifyCallback() {
+    EXPECT_CALL(listener_, OnHeaderListEnd());
+    decoder_state_.OnHeaderBlockEnd();
+    Mock::VerifyAndClearExpectations(&listener_);
+  }
+
+  // dynamic_index is one-based, because that is the way RFC 7541 shows it.
+  AssertionResult VerifyEntry(size_t dynamic_index,
+                              const char* name,
+                              const char* value) {
+    const HpackStringPair* entry =
+        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
+    VERIFY_NE(entry, nullptr);
+    VERIFY_EQ(entry->name, name);
+    VERIFY_EQ(entry->value, value);
+    return AssertionSuccess();
+  }
+  AssertionResult VerifyNoEntry(size_t dynamic_index) {
+    const HpackStringPair* entry =
+        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
+    VERIFY_EQ(entry, nullptr);
+    return AssertionSuccess();
+  }
+  AssertionResult VerifyDynamicTableContents(
+      const std::vector<std::pair<const char*, const char*>>& entries) {
+    size_t index = 1;
+    for (const auto& entry : entries) {
+      VERIFY_SUCCESS(VerifyEntry(index, entry.first, entry.second));
+      ++index;
+    }
+    VERIFY_SUCCESS(VerifyNoEntry(index));
+    return AssertionSuccess();
+  }
+
+  StrictMock<MockHpackDecoderListener> listener_;
+  HpackDecoderState decoder_state_;
+  HpackDecoderStringBuffer name_buffer_, value_buffer_;
+};
+
+// Test based on RFC 7541, section C.3: Request Examples without Huffman Coding.
+// This section shows several consecutive header lists, corresponding to HTTP
+// requests, on the same connection.
+TEST_F(HpackDecoderStateTest, C3_RequestExamples) {
+  // C.3.1 First Request
+  //
+  // Header list to encode:
+  //
+  //   :method: GET
+  //   :scheme: http
+  //   :path: /
+  //   :authority: www.example.com
+
+  SendStartAndVerifyCallback();
+  SendIndexAndVerifyCallback(2, HpackEntryType::kIndexedHeader, ":method",
+                             "GET");
+  SendIndexAndVerifyCallback(6, HpackEntryType::kIndexedHeader, ":scheme",
+                             "http");
+  SendIndexAndVerifyCallback(4, HpackEntryType::kIndexedHeader, ":path", "/");
+  SendValueAndVerifyCallback(1, HpackEntryType::kIndexedLiteralHeader,
+                             ":authority", "www.example.com", UNBUFFERED);
+  SendEndAndVerifyCallback();
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  57) :authority: www.example.com
+  //         Table size:  57
+
+  ASSERT_TRUE(VerifyDynamicTableContents({{":authority", "www.example.com"}}));
+  ASSERT_EQ(57u, current_header_table_size());
+
+  // C.3.2 Second Request
+  //
+  // Header list to encode:
+  //
+  //   :method: GET
+  //   :scheme: http
+  //   :path: /
+  //   :authority: www.example.com
+  //   cache-control: no-cache
+
+  SendStartAndVerifyCallback();
+  SendIndexAndVerifyCallback(2, HpackEntryType::kIndexedHeader, ":method",
+                             "GET");
+  SendIndexAndVerifyCallback(6, HpackEntryType::kIndexedHeader, ":scheme",
+                             "http");
+  SendIndexAndVerifyCallback(4, HpackEntryType::kIndexedHeader, ":path", "/");
+  SendIndexAndVerifyCallback(62, HpackEntryType::kIndexedHeader, ":authority",
+                             "www.example.com");
+  SendValueAndVerifyCallback(24, HpackEntryType::kIndexedLiteralHeader,
+                             "cache-control", "no-cache", UNBUFFERED);
+  SendEndAndVerifyCallback();
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  53) cache-control: no-cache
+  //   [  2] (s =  57) :authority: www.example.com
+  //         Table size: 110
+
+  ASSERT_TRUE(VerifyDynamicTableContents(
+      {{"cache-control", "no-cache"}, {":authority", "www.example.com"}}));
+  ASSERT_EQ(110u, current_header_table_size());
+
+  // C.3.3 Third Request
+  //
+  // Header list to encode:
+  //
+  //   :method: GET
+  //   :scheme: https
+  //   :path: /index.html
+  //   :authority: www.example.com
+  //   custom-key: custom-value
+
+  SendStartAndVerifyCallback();
+  SendIndexAndVerifyCallback(2, HpackEntryType::kIndexedHeader, ":method",
+                             "GET");
+  SendIndexAndVerifyCallback(7, HpackEntryType::kIndexedHeader, ":scheme",
+                             "https");
+  SendIndexAndVerifyCallback(5, HpackEntryType::kIndexedHeader, ":path",
+                             "/index.html");
+  SendIndexAndVerifyCallback(63, HpackEntryType::kIndexedHeader, ":authority",
+                             "www.example.com");
+  SendNameAndValueAndVerifyCallback(HpackEntryType::kIndexedLiteralHeader,
+                                    "custom-key", UNBUFFERED, "custom-value",
+                                    UNBUFFERED);
+  SendEndAndVerifyCallback();
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  54) custom-key: custom-value
+  //   [  2] (s =  53) cache-control: no-cache
+  //   [  3] (s =  57) :authority: www.example.com
+  //         Table size: 164
+
+  ASSERT_TRUE(VerifyDynamicTableContents({{"custom-key", "custom-value"},
+                                          {"cache-control", "no-cache"},
+                                          {":authority", "www.example.com"}}));
+  ASSERT_EQ(164u, current_header_table_size());
+}
+
+// Test based on RFC 7541, section C.5: Response Examples without Huffman
+// Coding. This section shows several consecutive header lists, corresponding
+// to HTTP responses, on the same connection. The HTTP/2 setting parameter
+// SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing
+// some evictions to occur.
+TEST_F(HpackDecoderStateTest, C5_ResponseExamples) {
+  set_header_table_size_limit(256);
+
+  // C.5.1 First Response
+  //
+  // Header list to encode:
+  //
+  //   :status: 302
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   location: https://www.example.com
+
+  SendStartAndVerifyCallback();
+  SendValueAndVerifyCallback(8, HpackEntryType::kIndexedLiteralHeader,
+                             ":status", "302", BUFFERED);
+  SendValueAndVerifyCallback(24, HpackEntryType::kIndexedLiteralHeader,
+                             "cache-control", "private", UNBUFFERED);
+  SendValueAndVerifyCallback(33, HpackEntryType::kIndexedLiteralHeader, "date",
+                             "Mon, 21 Oct 2013 20:13:21 GMT", UNBUFFERED);
+  SendValueAndVerifyCallback(46, HpackEntryType::kIndexedLiteralHeader,
+                             "location", "https://www.example.com", UNBUFFERED);
+  SendEndAndVerifyCallback();
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  63) location: https://www.example.com
+  //   [  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   [  3] (s =  52) cache-control: private
+  //   [  4] (s =  42) :status: 302
+  //         Table size: 222
+
+  ASSERT_TRUE(
+      VerifyDynamicTableContents({{"location", "https://www.example.com"},
+                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                                  {"cache-control", "private"},
+                                  {":status", "302"}}));
+  ASSERT_EQ(222u, current_header_table_size());
+
+  // C.5.2 Second Response
+  //
+  // The (":status", "302") header field is evicted from the dynamic table to
+  // free space to allow adding the (":status", "307") header field.
+  //
+  // Header list to encode:
+  //
+  //   :status: 307
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   location: https://www.example.com
+
+  SendStartAndVerifyCallback();
+  SendValueAndVerifyCallback(8, HpackEntryType::kIndexedLiteralHeader,
+                             ":status", "307", BUFFERED);
+  SendIndexAndVerifyCallback(65, HpackEntryType::kIndexedHeader,
+                             "cache-control", "private");
+  SendIndexAndVerifyCallback(64, HpackEntryType::kIndexedHeader, "date",
+                             "Mon, 21 Oct 2013 20:13:21 GMT");
+  SendIndexAndVerifyCallback(63, HpackEntryType::kIndexedHeader, "location",
+                             "https://www.example.com");
+  SendEndAndVerifyCallback();
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  42) :status: 307
+  //   [  2] (s =  63) location: https://www.example.com
+  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   [  4] (s =  52) cache-control: private
+  //         Table size: 222
+
+  ASSERT_TRUE(
+      VerifyDynamicTableContents({{":status", "307"},
+                                  {"location", "https://www.example.com"},
+                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                                  {"cache-control", "private"}}));
+  ASSERT_EQ(222u, current_header_table_size());
+
+  // C.5.3 Third Response
+  //
+  // Several header fields are evicted from the dynamic table during the
+  // processing of this header list.
+  //
+  // Header list to encode:
+  //
+  //   :status: 200
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:22 GMT
+  //   location: https://www.example.com
+  //   content-encoding: gzip
+  //   set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1
+
+  SendStartAndVerifyCallback();
+  SendIndexAndVerifyCallback(8, HpackEntryType::kIndexedHeader, ":status",
+                             "200");
+  SendIndexAndVerifyCallback(65, HpackEntryType::kIndexedHeader,
+                             "cache-control", "private");
+  SendValueAndVerifyCallback(33, HpackEntryType::kIndexedLiteralHeader, "date",
+                             "Mon, 21 Oct 2013 20:13:22 GMT", BUFFERED);
+  SendIndexAndVerifyCallback(64, HpackEntryType::kIndexedHeader, "location",
+                             "https://www.example.com");
+  SendValueAndVerifyCallback(26, HpackEntryType::kIndexedLiteralHeader,
+                             "content-encoding", "gzip", UNBUFFERED);
+  SendValueAndVerifyCallback(
+      55, HpackEntryType::kIndexedLiteralHeader, "set-cookie",
+      "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", BUFFERED);
+  SendEndAndVerifyCallback();
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
+  //                    max-age=3600; version=1
+  //   [  2] (s =  52) content-encoding: gzip
+  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
+  //         Table size: 215
+
+  ASSERT_TRUE(VerifyDynamicTableContents(
+      {{"set-cookie",
+        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
+       {"content-encoding", "gzip"},
+       {"date", "Mon, 21 Oct 2013 20:13:22 GMT"}}));
+  ASSERT_EQ(215u, current_header_table_size());
+}
+
+// Confirm that the table size can be changed, but at most twice.
+TEST_F(HpackDecoderStateTest, OptionalTableSizeChanges) {
+  SendStartAndVerifyCallback();
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+  SendSizeUpdate(1024);
+  EXPECT_EQ(1024u, header_table_size_limit());
+  SendSizeUpdate(0);
+  EXPECT_EQ(0u, header_table_size_limit());
+
+  // Three updates aren't allowed.
+  EXPECT_CALL(listener_, OnHeaderErrorDetected(
+                             Eq("Dynamic table size update not allowed")));
+  SendSizeUpdate(0);
+}
+
+// Confirm that required size updates are indeed required before headers.
+TEST_F(HpackDecoderStateTest, RequiredTableSizeChangeBeforeHeader) {
+  EXPECT_EQ(4096u, decoder_state_.GetCurrentHeaderTableSizeSetting());
+  decoder_state_.ApplyHeaderTableSizeSetting(1024);
+  decoder_state_.ApplyHeaderTableSizeSetting(2048);
+  EXPECT_EQ(2048u, decoder_state_.GetCurrentHeaderTableSizeSetting());
+
+  // First provide the required update, and an allowed second update.
+  SendStartAndVerifyCallback();
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+  SendSizeUpdate(1024);
+  EXPECT_EQ(1024u, header_table_size_limit());
+  SendSizeUpdate(1500);
+  EXPECT_EQ(1500u, header_table_size_limit());
+  SendEndAndVerifyCallback();
+
+  // Another HPACK block, but this time missing the required size update.
+  decoder_state_.ApplyHeaderTableSizeSetting(1024);
+  EXPECT_EQ(1024u, decoder_state_.GetCurrentHeaderTableSizeSetting());
+  SendStartAndVerifyCallback();
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(Eq("Missing dynamic table size update")));
+  decoder_state_.OnIndexedHeader(1);
+
+  // Further decoded entries are ignored.
+  decoder_state_.OnIndexedHeader(1);
+  decoder_state_.OnDynamicTableSizeUpdate(1);
+  SetValue("value", UNBUFFERED);
+  decoder_state_.OnNameIndexAndLiteralValue(
+      HpackEntryType::kIndexedLiteralHeader, 4, &value_buffer_);
+  SetName("name", UNBUFFERED);
+  decoder_state_.OnLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader,
+                                       &name_buffer_, &value_buffer_);
+  decoder_state_.OnHeaderBlockEnd();
+  decoder_state_.OnHpackDecodeError(HpackDecodingError::kIndexVarintError, "");
+}
+
+// Confirm that required size updates are validated.
+TEST_F(HpackDecoderStateTest, InvalidRequiredSizeUpdate) {
+  // Require a size update, but provide one that isn't small enough.
+  decoder_state_.ApplyHeaderTableSizeSetting(1024);
+  SendStartAndVerifyCallback();
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+  EXPECT_CALL(
+      listener_,
+      OnHeaderErrorDetected(
+          Eq("Initial dynamic table size update is above low water mark")));
+  SendSizeUpdate(2048);
+}
+
+// Confirm that required size updates are indeed required before the end.
+TEST_F(HpackDecoderStateTest, RequiredTableSizeChangeBeforeEnd) {
+  decoder_state_.ApplyHeaderTableSizeSetting(1024);
+  SendStartAndVerifyCallback();
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(Eq("Missing dynamic table size update")));
+  decoder_state_.OnHeaderBlockEnd();
+}
+
+// Confirm that optional size updates are validated.
+TEST_F(HpackDecoderStateTest, InvalidOptionalSizeUpdate) {
+  // Require a size update, but provide one that isn't small enough.
+  SendStartAndVerifyCallback();
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(Eq(
+                  "Dynamic table size update is above acknowledged setting")));
+  SendSizeUpdate(Http2SettingsInfo::DefaultHeaderTableSize() + 1);
+}
+
+TEST_F(HpackDecoderStateTest, InvalidStaticIndex) {
+  SendStartAndVerifyCallback();
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(
+                  Eq("Invalid index in indexed header field representation")));
+  decoder_state_.OnIndexedHeader(0);
+}
+
+TEST_F(HpackDecoderStateTest, InvalidDynamicIndex) {
+  SendStartAndVerifyCallback();
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(
+                  Eq("Invalid index in indexed header field representation")));
+  decoder_state_.OnIndexedHeader(kFirstDynamicTableIndex);
+}
+
+TEST_F(HpackDecoderStateTest, InvalidNameIndex) {
+  SendStartAndVerifyCallback();
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(Eq("Invalid index in literal header field "
+                                       "with indexed name representation")));
+  SetValue("value", UNBUFFERED);
+  decoder_state_.OnNameIndexAndLiteralValue(
+      HpackEntryType::kIndexedLiteralHeader, kFirstDynamicTableIndex,
+      &value_buffer_);
+}
+
+TEST_F(HpackDecoderStateTest, ErrorsSuppressCallbacks) {
+  SendStartAndVerifyCallback();
+  EXPECT_CALL(listener_,
+              OnHeaderErrorDetected(Eq("Name Huffman encoding error")));
+  decoder_state_.OnHpackDecodeError(HpackDecodingError::kNameHuffmanError, "");
+
+  // Further decoded entries are ignored.
+  decoder_state_.OnIndexedHeader(1);
+  decoder_state_.OnDynamicTableSizeUpdate(1);
+  SetValue("value", UNBUFFERED);
+  decoder_state_.OnNameIndexAndLiteralValue(
+      HpackEntryType::kIndexedLiteralHeader, 4, &value_buffer_);
+  SetName("name", UNBUFFERED);
+  decoder_state_.OnLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader,
+                                       &name_buffer_, &value_buffer_);
+  decoder_state_.OnHeaderBlockEnd();
+  decoder_state_.OnHpackDecodeError(HpackDecodingError::kIndexVarintError, "");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.cc
new file mode 100644
index 0000000..e928686
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.cc
@@ -0,0 +1,239 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h"
+
+#include <utility>
+
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::ostream& operator<<(std::ostream& out,
+                         const HpackDecoderStringBuffer::State v) {
+  switch (v) {
+    case HpackDecoderStringBuffer::State::RESET:
+      return out << "RESET";
+    case HpackDecoderStringBuffer::State::COLLECTING:
+      return out << "COLLECTING";
+    case HpackDecoderStringBuffer::State::COMPLETE:
+      return out << "COMPLETE";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  int unknown = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_50_1)
+      << "Invalid HpackDecoderStringBuffer::State: " << unknown;
+  return out << "HpackDecoderStringBuffer::State(" << unknown << ")";
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         const HpackDecoderStringBuffer::Backing v) {
+  switch (v) {
+    case HpackDecoderStringBuffer::Backing::RESET:
+      return out << "RESET";
+    case HpackDecoderStringBuffer::Backing::UNBUFFERED:
+      return out << "UNBUFFERED";
+    case HpackDecoderStringBuffer::Backing::BUFFERED:
+      return out << "BUFFERED";
+    case HpackDecoderStringBuffer::Backing::STATIC:
+      return out << "STATIC";
+  }
+  // Since the value doesn't come over the wire, only a programming bug should
+  // result in reaching this point.
+  auto v2 = static_cast<int>(v);
+  HTTP2_BUG(http2_bug_50_2)
+      << "Invalid HpackDecoderStringBuffer::Backing: " << v2;
+  return out << "HpackDecoderStringBuffer::Backing(" << v2 << ")";
+}
+
+HpackDecoderStringBuffer::HpackDecoderStringBuffer()
+    : remaining_len_(0),
+      is_huffman_encoded_(false),
+      state_(State::RESET),
+      backing_(Backing::RESET) {}
+HpackDecoderStringBuffer::~HpackDecoderStringBuffer() = default;
+
+void HpackDecoderStringBuffer::Reset() {
+  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::Reset";
+  state_ = State::RESET;
+}
+
+void HpackDecoderStringBuffer::Set(absl::string_view value, bool is_static) {
+  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::Set";
+  QUICHE_DCHECK_EQ(state_, State::RESET);
+  value_ = value;
+  state_ = State::COMPLETE;
+  backing_ = is_static ? Backing::STATIC : Backing::UNBUFFERED;
+  // TODO(jamessynge): Determine which of these two fields must be set.
+  remaining_len_ = 0;
+  is_huffman_encoded_ = false;
+}
+
+void HpackDecoderStringBuffer::OnStart(bool huffman_encoded, size_t len) {
+  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::OnStart";
+  QUICHE_DCHECK_EQ(state_, State::RESET);
+
+  remaining_len_ = len;
+  is_huffman_encoded_ = huffman_encoded;
+  state_ = State::COLLECTING;
+
+  if (huffman_encoded) {
+    // We don't set, clear or use value_ for buffered strings until OnEnd.
+    decoder_.Reset();
+    buffer_.clear();
+    backing_ = Backing::BUFFERED;
+
+    // Reserve space in buffer_ for the uncompressed string, assuming the
+    // maximum expansion. The shortest Huffman codes in the RFC are 5 bits long,
+    // which then expand to 8 bits during decoding (i.e. each code is for one
+    // plain text octet, aka byte), so the maximum size is 60% longer than the
+    // encoded size.
+    len = len * 8 / 5;
+    if (buffer_.capacity() < len) {
+      buffer_.reserve(len);
+    }
+  } else {
+    // Assume for now that we won't need to use buffer_, so don't reserve space
+    // in it.
+    backing_ = Backing::RESET;
+    // OnData is not called for empty (zero length) strings, so make sure that
+    // value_ is cleared.
+    value_ = absl::string_view();
+  }
+}
+
+bool HpackDecoderStringBuffer::OnData(const char* data, size_t len) {
+  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::OnData state=" << state_
+                 << ", backing=" << backing_;
+  QUICHE_DCHECK_EQ(state_, State::COLLECTING);
+  QUICHE_DCHECK_LE(len, remaining_len_);
+  remaining_len_ -= len;
+
+  if (is_huffman_encoded_) {
+    QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
+    return decoder_.Decode(absl::string_view(data, len), &buffer_);
+  }
+
+  if (backing_ == Backing::RESET) {
+    // This is the first call to OnData. If data contains the entire string,
+    // don't copy the string. If we later find that the HPACK entry is split
+    // across input buffers, then we'll copy the string into buffer_.
+    if (remaining_len_ == 0) {
+      value_ = absl::string_view(data, len);
+      backing_ = Backing::UNBUFFERED;
+      return true;
+    }
+
+    // We need to buffer the string because it is split across input buffers.
+    // Reserve space in buffer_ for the entire string.
+    backing_ = Backing::BUFFERED;
+    buffer_.reserve(remaining_len_ + len);
+    buffer_.assign(data, len);
+    return true;
+  }
+
+  // This is not the first call to OnData for this string, so it should be
+  // buffered.
+  QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
+
+  // Append to the current contents of the buffer.
+  buffer_.append(data, len);
+  return true;
+}
+
+bool HpackDecoderStringBuffer::OnEnd() {
+  HTTP2_DVLOG(2) << "HpackDecoderStringBuffer::OnEnd";
+  QUICHE_DCHECK_EQ(state_, State::COLLECTING);
+  QUICHE_DCHECK_EQ(0u, remaining_len_);
+
+  if (is_huffman_encoded_) {
+    QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
+    // Did the Huffman encoding of the string end properly?
+    if (!decoder_.InputProperlyTerminated()) {
+      return false;  // No, it didn't.
+    }
+    value_ = buffer_;
+  } else if (backing_ == Backing::BUFFERED) {
+    value_ = buffer_;
+  }
+  state_ = State::COMPLETE;
+  return true;
+}
+
+void HpackDecoderStringBuffer::BufferStringIfUnbuffered() {
+  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::BufferStringIfUnbuffered state="
+                 << state_ << ", backing=" << backing_;
+  if (state_ != State::RESET && backing_ == Backing::UNBUFFERED) {
+    HTTP2_DVLOG(2)
+        << "HpackDecoderStringBuffer buffering std::string of length "
+        << value_.size();
+    buffer_.assign(value_.data(), value_.size());
+    if (state_ == State::COMPLETE) {
+      value_ = buffer_;
+    }
+    backing_ = Backing::BUFFERED;
+  }
+}
+
+bool HpackDecoderStringBuffer::IsBuffered() const {
+  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::IsBuffered";
+  return state_ != State::RESET && backing_ == Backing::BUFFERED;
+}
+
+size_t HpackDecoderStringBuffer::BufferedLength() const {
+  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::BufferedLength";
+  return IsBuffered() ? buffer_.size() : 0;
+}
+
+absl::string_view HpackDecoderStringBuffer::str() const {
+  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::str";
+  QUICHE_DCHECK_EQ(state_, State::COMPLETE);
+  return value_;
+}
+
+absl::string_view HpackDecoderStringBuffer::GetStringIfComplete() const {
+  if (state_ != State::COMPLETE) {
+    return {};
+  }
+  return str();
+}
+
+std::string HpackDecoderStringBuffer::ReleaseString() {
+  HTTP2_DVLOG(3) << "HpackDecoderStringBuffer::ReleaseString";
+  QUICHE_DCHECK_EQ(state_, State::COMPLETE);
+  QUICHE_DCHECK_EQ(backing_, Backing::BUFFERED);
+  if (state_ == State::COMPLETE) {
+    state_ = State::RESET;
+    if (backing_ == Backing::BUFFERED) {
+      return std::move(buffer_);
+    } else {
+      return std::string(value_);
+    }
+  }
+  return "";
+}
+
+void HpackDecoderStringBuffer::OutputDebugStringTo(std::ostream& out) const {
+  out << "{state=" << state_;
+  if (state_ != State::RESET) {
+    out << ", backing=" << backing_;
+    out << ", remaining_len=" << remaining_len_;
+    out << ", is_huffman_encoded=" << is_huffman_encoded_;
+    if (backing_ == Backing::BUFFERED) {
+      out << ", buffer: " << buffer_;
+    } else {
+      out << ", value: " << value_;
+    }
+  }
+  out << "}";
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackDecoderStringBuffer& v) {
+  v.OutputDebugStringTo(out);
+  return out;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h b/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h
new file mode 100644
index 0000000..a1877c8
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h
@@ -0,0 +1,102 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
+
+// HpackDecoderStringBuffer helps an HPACK decoder to avoid copies of a string
+// literal (name or value) except when necessary (e.g. when split across two
+// or more HPACK block fragments).
+
+#include <stddef.h>
+
+#include <ostream>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackDecoderStringBuffer {
+ public:
+  enum class State : uint8_t { RESET, COLLECTING, COMPLETE };
+  enum class Backing : uint8_t { RESET, UNBUFFERED, BUFFERED, STATIC };
+
+  HpackDecoderStringBuffer();
+  ~HpackDecoderStringBuffer();
+
+  HpackDecoderStringBuffer(const HpackDecoderStringBuffer&) = delete;
+  HpackDecoderStringBuffer& operator=(const HpackDecoderStringBuffer&) = delete;
+
+  void Reset();
+  void Set(absl::string_view value, bool is_static);
+
+  // Note that for Huffman encoded strings the length of the string after
+  // decoding may be larger (expected), the same or even smaller; the latter
+  // are unlikely, but possible if the encoder makes odd choices.
+  void OnStart(bool huffman_encoded, size_t len);
+  bool OnData(const char* data, size_t len);
+  bool OnEnd();
+  void BufferStringIfUnbuffered();
+  bool IsBuffered() const;
+  size_t BufferedLength() const;
+
+  // Accessors for the completely collected string (i.e. Set or OnEnd has just
+  // been called, and no reset of the state has occurred).
+
+  // Returns a string_view pointing to the backing store for the string,
+  // either the internal buffer or the original transport buffer (e.g. for a
+  // literal value that wasn't Huffman encoded, and that wasn't split across
+  // transport buffers).
+  absl::string_view str() const;
+
+  // Same as str() if state_ is COMPLETE. Otherwise, returns empty string piece.
+  absl::string_view GetStringIfComplete() const;
+
+  // Returns the completely collected string by value, using std::move in an
+  // effort to avoid unnecessary copies. ReleaseString() must not be called
+  // unless the string has been buffered (to avoid forcing a potentially
+  // unnecessary copy). ReleaseString() also resets the instance so that it can
+  // be used to collect another string.
+  std::string ReleaseString();
+
+  State state_for_testing() const { return state_; }
+  Backing backing_for_testing() const { return backing_; }
+  void OutputDebugStringTo(std::ostream& out) const;
+
+ private:
+  // Storage for the string being buffered, if buffering is necessary
+  // (e.g. if Huffman encoded, buffer_ is storage for the decoded string).
+  std::string buffer_;
+
+  // The string_view to be returned by HpackDecoderStringBuffer::str(). If
+  // a string has been collected, but not buffered, value_ points to that
+  // string.
+  absl::string_view value_;
+
+  // The decoder to use if the string is Huffman encoded.
+  HpackHuffmanDecoder decoder_;
+
+  // Count of bytes not yet passed to OnData.
+  size_t remaining_len_;
+
+  // Is the HPACK string Huffman encoded?
+  bool is_huffman_encoded_;
+
+  // State of the string decoding process.
+  State state_;
+
+  // Where is the string stored?
+  Backing backing_;
+};
+
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& out,
+    const HpackDecoderStringBuffer& v);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_STRING_BUFFER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc
new file mode 100644
index 0000000..3cd5f82
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc
@@ -0,0 +1,249 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h"
+
+// Tests of HpackDecoderStringBuffer.
+
+#include <initializer_list>
+
+#include "absl/strings/escaping.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using ::testing::HasSubstr;
+
+namespace http2 {
+namespace test {
+namespace {
+
+class HpackDecoderStringBufferTest : public QuicheTest {
+ protected:
+  typedef HpackDecoderStringBuffer::State State;
+  typedef HpackDecoderStringBuffer::Backing Backing;
+
+  State state() const { return buf_.state_for_testing(); }
+  Backing backing() const { return buf_.backing_for_testing(); }
+
+  // We want to know that HTTP2_LOG(x) << buf_ will work in production should
+  // that be needed, so we test that it outputs the expected values.
+  AssertionResult VerifyLogHasSubstrs(std::initializer_list<std::string> strs) {
+    HTTP2_VLOG(1) << buf_;
+    std::ostringstream ss;
+    buf_.OutputDebugStringTo(ss);
+    std::string dbg_str(ss.str());
+    for (const auto& expected : strs) {
+      VERIFY_THAT(dbg_str, HasSubstr(expected));
+    }
+    return AssertionSuccess();
+  }
+
+  HpackDecoderStringBuffer buf_;
+};
+
+TEST_F(HpackDecoderStringBufferTest, SetStatic) {
+  absl::string_view data("static string");
+
+  EXPECT_EQ(state(), State::RESET);
+  EXPECT_TRUE(VerifyLogHasSubstrs({"state=RESET"}));
+
+  buf_.Set(data, /*is_static*/ true);
+  HTTP2_LOG(INFO) << buf_;
+  EXPECT_EQ(state(), State::COMPLETE);
+  EXPECT_EQ(backing(), Backing::STATIC);
+  EXPECT_EQ(data, buf_.str());
+  EXPECT_EQ(data.data(), buf_.str().data());
+  EXPECT_TRUE(VerifyLogHasSubstrs(
+      {"state=COMPLETE", "backing=STATIC", "value: static string"}));
+
+  // The string is static, so BufferStringIfUnbuffered won't change anything.
+  buf_.BufferStringIfUnbuffered();
+  EXPECT_EQ(state(), State::COMPLETE);
+  EXPECT_EQ(backing(), Backing::STATIC);
+  EXPECT_EQ(data, buf_.str());
+  EXPECT_EQ(data.data(), buf_.str().data());
+  EXPECT_TRUE(VerifyLogHasSubstrs(
+      {"state=COMPLETE", "backing=STATIC", "value: static string"}));
+}
+
+TEST_F(HpackDecoderStringBufferTest, PlainWhole) {
+  absl::string_view data("some text.");
+
+  HTTP2_LOG(INFO) << buf_;
+  EXPECT_EQ(state(), State::RESET);
+
+  buf_.OnStart(/*huffman_encoded*/ false, data.size());
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::RESET);
+  HTTP2_LOG(INFO) << buf_;
+
+  EXPECT_TRUE(buf_.OnData(data.data(), data.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::UNBUFFERED);
+
+  EXPECT_TRUE(buf_.OnEnd());
+  EXPECT_EQ(state(), State::COMPLETE);
+  EXPECT_EQ(backing(), Backing::UNBUFFERED);
+  EXPECT_EQ(0u, buf_.BufferedLength());
+  EXPECT_TRUE(VerifyLogHasSubstrs(
+      {"state=COMPLETE", "backing=UNBUFFERED", "value: some text."}));
+
+  // We expect that the string buffer points to the passed in
+  // string_view's backing store.
+  EXPECT_EQ(data.data(), buf_.str().data());
+
+  // Now force it to buffer the string, after which it will still have the same
+  // string value, but the backing store will be different.
+  buf_.BufferStringIfUnbuffered();
+  HTTP2_LOG(INFO) << buf_;
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), data.size());
+  EXPECT_EQ(data, buf_.str());
+  EXPECT_NE(data.data(), buf_.str().data());
+  EXPECT_TRUE(VerifyLogHasSubstrs(
+      {"state=COMPLETE", "backing=BUFFERED", "buffer: some text."}));
+}
+
+TEST_F(HpackDecoderStringBufferTest, PlainSplit) {
+  absl::string_view data("some text.");
+  absl::string_view part1 = data.substr(0, 1);
+  absl::string_view part2 = data.substr(1);
+
+  EXPECT_EQ(state(), State::RESET);
+  buf_.OnStart(/*huffman_encoded*/ false, data.size());
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::RESET);
+
+  // OnData with only a part of the data, not the whole, so buf_ will buffer
+  // the data.
+  EXPECT_TRUE(buf_.OnData(part1.data(), part1.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), part1.size());
+  HTTP2_LOG(INFO) << buf_;
+
+  EXPECT_TRUE(buf_.OnData(part2.data(), part2.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), data.size());
+
+  EXPECT_TRUE(buf_.OnEnd());
+  EXPECT_EQ(state(), State::COMPLETE);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), data.size());
+  HTTP2_LOG(INFO) << buf_;
+
+  absl::string_view buffered = buf_.str();
+  EXPECT_EQ(data, buffered);
+  EXPECT_NE(data.data(), buffered.data());
+
+  // The string is already buffered, so BufferStringIfUnbuffered should not make
+  // any change.
+  buf_.BufferStringIfUnbuffered();
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), data.size());
+  EXPECT_EQ(buffered, buf_.str());
+  EXPECT_EQ(buffered.data(), buf_.str().data());
+}
+
+TEST_F(HpackDecoderStringBufferTest, HuffmanWhole) {
+  std::string encoded = absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff");
+  absl::string_view decoded("www.example.com");
+
+  EXPECT_EQ(state(), State::RESET);
+  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
+  EXPECT_EQ(state(), State::COLLECTING);
+
+  EXPECT_TRUE(buf_.OnData(encoded.data(), encoded.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+
+  EXPECT_TRUE(buf_.OnEnd());
+  EXPECT_EQ(state(), State::COMPLETE);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), decoded.size());
+  EXPECT_EQ(decoded, buf_.str());
+  EXPECT_TRUE(VerifyLogHasSubstrs(
+      {"{state=COMPLETE", "backing=BUFFERED", "buffer: www.example.com}"}));
+
+  std::string s = buf_.ReleaseString();
+  EXPECT_EQ(s, decoded);
+  EXPECT_EQ(state(), State::RESET);
+}
+
+TEST_F(HpackDecoderStringBufferTest, HuffmanSplit) {
+  std::string encoded = absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff");
+  std::string part1 = encoded.substr(0, 5);
+  std::string part2 = encoded.substr(5);
+  absl::string_view decoded("www.example.com");
+
+  EXPECT_EQ(state(), State::RESET);
+  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(0u, buf_.BufferedLength());
+  HTTP2_LOG(INFO) << buf_;
+
+  EXPECT_TRUE(buf_.OnData(part1.data(), part1.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_GT(buf_.BufferedLength(), 0u);
+  EXPECT_LT(buf_.BufferedLength(), decoded.size());
+  HTTP2_LOG(INFO) << buf_;
+
+  EXPECT_TRUE(buf_.OnData(part2.data(), part2.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), decoded.size());
+  HTTP2_LOG(INFO) << buf_;
+
+  EXPECT_TRUE(buf_.OnEnd());
+  EXPECT_EQ(state(), State::COMPLETE);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+  EXPECT_EQ(buf_.BufferedLength(), decoded.size());
+  EXPECT_EQ(decoded, buf_.str());
+  HTTP2_LOG(INFO) << buf_;
+
+  buf_.Reset();
+  EXPECT_EQ(state(), State::RESET);
+  HTTP2_LOG(INFO) << buf_;
+}
+
+TEST_F(HpackDecoderStringBufferTest, InvalidHuffmanOnData) {
+  // Explicitly encode the End-of-String symbol, a no-no.
+  std::string encoded = absl::HexStringToBytes("ffffffff");
+
+  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
+  EXPECT_EQ(state(), State::COLLECTING);
+
+  EXPECT_FALSE(buf_.OnData(encoded.data(), encoded.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+
+  HTTP2_LOG(INFO) << buf_;
+}
+
+TEST_F(HpackDecoderStringBufferTest, InvalidHuffmanOnEnd) {
+  // Last byte of string doesn't end with prefix of End-of-String symbol.
+  std::string encoded = absl::HexStringToBytes("00");
+
+  buf_.OnStart(/*huffman_encoded*/ true, encoded.size());
+  EXPECT_EQ(state(), State::COLLECTING);
+
+  EXPECT_TRUE(buf_.OnData(encoded.data(), encoded.size()));
+  EXPECT_EQ(state(), State::COLLECTING);
+  EXPECT_EQ(backing(), Backing::BUFFERED);
+
+  EXPECT_FALSE(buf_.OnEnd());
+  HTTP2_LOG(INFO) << buf_;
+}
+
+// TODO(jamessynge): Add tests for ReleaseString().
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_tables.cc b/quiche/http2/hpack/decoder/hpack_decoder_tables.cc
new file mode 100644
index 0000000..233e4b6
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_tables.cc
@@ -0,0 +1,148 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+namespace {
+
+std::vector<HpackStringPair>* MakeStaticTable() {
+  auto* ptr = new std::vector<HpackStringPair>();
+  ptr->reserve(kFirstDynamicTableIndex);
+  ptr->emplace_back("", "");
+
+#define STATIC_TABLE_ENTRY(name, value, index)               \
+  QUICHE_DCHECK_EQ(ptr->size(), static_cast<size_t>(index)); \
+  ptr->emplace_back(name, value)
+
+#include "quiche/http2/hpack/hpack_static_table_entries.inc"
+
+#undef STATIC_TABLE_ENTRY
+
+  return ptr;
+}
+
+const std::vector<HpackStringPair>* GetStaticTable() {
+  static const std::vector<HpackStringPair>* const g_static_table =
+      MakeStaticTable();
+  return g_static_table;
+}
+
+}  // namespace
+
+HpackStringPair::HpackStringPair(std::string name, std::string value)
+    : name(std::move(name)), value(std::move(value)) {
+  HTTP2_DVLOG(3) << DebugString() << " ctor";
+}
+
+HpackStringPair::~HpackStringPair() {
+  HTTP2_DVLOG(3) << DebugString() << " dtor";
+}
+
+std::string HpackStringPair::DebugString() const {
+  return absl::StrCat("HpackStringPair(name=", name, ", value=", value, ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const HpackStringPair& p) {
+  os << p.DebugString();
+  return os;
+}
+
+HpackDecoderStaticTable::HpackDecoderStaticTable(
+    const std::vector<HpackStringPair>* table)
+    : table_(table) {}
+
+HpackDecoderStaticTable::HpackDecoderStaticTable() : table_(GetStaticTable()) {}
+
+const HpackStringPair* HpackDecoderStaticTable::Lookup(size_t index) const {
+  if (0 < index && index < kFirstDynamicTableIndex) {
+    return &((*table_)[index]);
+  }
+  return nullptr;
+}
+
+HpackDecoderDynamicTable::HpackDecoderDynamicTable()
+    : insert_count_(kFirstDynamicTableIndex - 1) {}
+HpackDecoderDynamicTable::~HpackDecoderDynamicTable() = default;
+
+void HpackDecoderDynamicTable::DynamicTableSizeUpdate(size_t size_limit) {
+  HTTP2_DVLOG(3) << "HpackDecoderDynamicTable::DynamicTableSizeUpdate "
+                 << size_limit;
+  EnsureSizeNoMoreThan(size_limit);
+  QUICHE_DCHECK_LE(current_size_, size_limit);
+  size_limit_ = size_limit;
+}
+
+// TODO(jamessynge): Check somewhere before here that names received from the
+// peer are valid (e.g. are lower-case, no whitespace, etc.).
+void HpackDecoderDynamicTable::Insert(std::string name, std::string value) {
+  HpackStringPair entry(std::move(name), std::move(value));
+  size_t entry_size = entry.size();
+  HTTP2_DVLOG(2) << "InsertEntry of size=" << entry_size
+                 << "\n     name: " << entry.name
+                 << "\n    value: " << entry.value;
+  if (entry_size > size_limit_) {
+    HTTP2_DVLOG(2) << "InsertEntry: entry larger than table, removing "
+                   << table_.size() << " entries, of total size "
+                   << current_size_ << " bytes.";
+    table_.clear();
+    current_size_ = 0;
+    return;
+  }
+  ++insert_count_;
+  size_t insert_limit = size_limit_ - entry_size;
+  EnsureSizeNoMoreThan(insert_limit);
+  table_.push_front(entry);
+  current_size_ += entry_size;
+  HTTP2_DVLOG(2) << "InsertEntry: current_size_=" << current_size_;
+  QUICHE_DCHECK_GE(current_size_, entry_size);
+  QUICHE_DCHECK_LE(current_size_, size_limit_);
+}
+
+const HpackStringPair* HpackDecoderDynamicTable::Lookup(size_t index) const {
+  if (index < table_.size()) {
+    return &table_[index];
+  }
+  return nullptr;
+}
+
+void HpackDecoderDynamicTable::EnsureSizeNoMoreThan(size_t limit) {
+  HTTP2_DVLOG(2) << "EnsureSizeNoMoreThan limit=" << limit
+                 << ", current_size_=" << current_size_;
+  // Not the most efficient choice, but any easy way to start.
+  while (current_size_ > limit) {
+    RemoveLastEntry();
+  }
+  QUICHE_DCHECK_LE(current_size_, limit);
+}
+
+void HpackDecoderDynamicTable::RemoveLastEntry() {
+  QUICHE_DCHECK(!table_.empty());
+  if (!table_.empty()) {
+    HTTP2_DVLOG(2) << "RemoveLastEntry current_size_=" << current_size_
+                   << ", last entry size=" << table_.back().size();
+    QUICHE_DCHECK_GE(current_size_, table_.back().size());
+    current_size_ -= table_.back().size();
+    table_.pop_back();
+    // Empty IFF current_size_ == 0.
+    QUICHE_DCHECK_EQ(table_.empty(), current_size_ == 0);
+  }
+}
+
+HpackDecoderTables::HpackDecoderTables() = default;
+HpackDecoderTables::~HpackDecoderTables() = default;
+
+const HpackStringPair* HpackDecoderTables::Lookup(size_t index) const {
+  if (index < kFirstDynamicTableIndex) {
+    return static_table_.Lookup(index);
+  } else {
+    return dynamic_table_.Lookup(index - kFirstDynamicTableIndex);
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_tables.h b/quiche/http2/hpack/decoder/hpack_decoder_tables.h
new file mode 100644
index 0000000..e78b91d
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_tables.h
@@ -0,0 +1,166 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
+
+// Static and dynamic tables for the HPACK decoder. See:
+// http://httpwg.org/specs/rfc7541.html#indexing.tables
+
+// Note that the Lookup methods return nullptr if the requested index was not
+// found. This should be treated as a COMPRESSION error according to the HTTP/2
+// spec, which is a connection level protocol error (i.e. the connection must
+// be terminated). See these sections in the two RFCs:
+// http://httpwg.org/specs/rfc7541.html#indexed.header.representation
+// http://httpwg.org/specs/rfc7541.html#index.address.space
+// http://httpwg.org/specs/rfc7540.html#HeaderBlock
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <iosfwd>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "quiche/http2/http2_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace http2 {
+namespace test {
+class HpackDecoderTablesPeer;
+}  // namespace test
+
+struct QUICHE_EXPORT_PRIVATE HpackStringPair {
+  HpackStringPair(std::string name, std::string value);
+  ~HpackStringPair();
+
+  // Returns the size of a header entry with this name and value, per the RFC:
+  // http://httpwg.org/specs/rfc7541.html#calculating.table.size
+  size_t size() const { return 32 + name.size() + value.size(); }
+
+  std::string DebugString() const;
+
+  const std::string name;
+  const std::string value;
+};
+
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                               const HpackStringPair& p);
+
+// See http://httpwg.org/specs/rfc7541.html#static.table.definition for the
+// contents, and http://httpwg.org/specs/rfc7541.html#index.address.space for
+// info about accessing the static table.
+class QUICHE_EXPORT_PRIVATE HpackDecoderStaticTable {
+ public:
+  explicit HpackDecoderStaticTable(const std::vector<HpackStringPair>* table);
+  // Uses a global table shared by all threads.
+  HpackDecoderStaticTable();
+
+  // If index is valid, returns a pointer to the entry, otherwise returns
+  // nullptr.
+  const HpackStringPair* Lookup(size_t index) const;
+
+ private:
+  friend class test::HpackDecoderTablesPeer;
+  const std::vector<HpackStringPair>* const table_;
+};
+
+// HpackDecoderDynamicTable implements HPACK compression feature "indexed
+// headers"; previously sent headers may be referenced later by their index
+// in the dynamic table. See these sections of the RFC:
+//   http://httpwg.org/specs/rfc7541.html#dynamic.table
+//   http://httpwg.org/specs/rfc7541.html#dynamic.table.management
+class QUICHE_EXPORT_PRIVATE HpackDecoderDynamicTable {
+ public:
+  HpackDecoderDynamicTable();
+  ~HpackDecoderDynamicTable();
+
+  HpackDecoderDynamicTable(const HpackDecoderDynamicTable&) = delete;
+  HpackDecoderDynamicTable& operator=(const HpackDecoderDynamicTable&) = delete;
+
+  // Sets a new size limit, received from the peer; performs evictions if
+  // necessary to ensure that the current size does not exceed the new limit.
+  // The caller needs to have validated that size_limit does not
+  // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
+  void DynamicTableSizeUpdate(size_t size_limit);
+
+  // Insert entry if possible.
+  // If entry is too large to insert, then dynamic table will be empty.
+  void Insert(std::string name, std::string value);
+
+  // If index is valid, returns a pointer to the entry, otherwise returns
+  // nullptr.
+  const HpackStringPair* Lookup(size_t index) const;
+
+  size_t size_limit() const { return size_limit_; }
+  size_t current_size() const { return current_size_; }
+
+ private:
+  friend class test::HpackDecoderTablesPeer;
+
+  // Drop older entries to ensure the size is not greater than limit.
+  void EnsureSizeNoMoreThan(size_t limit);
+
+  // Removes the oldest dynamic table entry.
+  void RemoveLastEntry();
+
+  quiche::QuicheCircularDeque<HpackStringPair> table_;
+
+  // The last received DynamicTableSizeUpdate value, initialized to
+  // SETTINGS_HEADER_TABLE_SIZE.
+  size_t size_limit_ = Http2SettingsInfo::DefaultHeaderTableSize();
+
+  size_t current_size_ = 0;
+
+  // insert_count_ and debug_listener_ are used by a QUIC experiment; remove
+  // when the experiment is done.
+  size_t insert_count_;
+};
+
+class QUICHE_EXPORT_PRIVATE HpackDecoderTables {
+ public:
+  HpackDecoderTables();
+  ~HpackDecoderTables();
+
+  HpackDecoderTables(const HpackDecoderTables&) = delete;
+  HpackDecoderTables& operator=(const HpackDecoderTables&) = delete;
+
+  // Sets a new size limit, received from the peer; performs evictions if
+  // necessary to ensure that the current size does not exceed the new limit.
+  // The caller needs to have validated that size_limit does not
+  // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
+  void DynamicTableSizeUpdate(size_t size_limit) {
+    dynamic_table_.DynamicTableSizeUpdate(size_limit);
+  }
+
+  // Insert entry if possible.
+  // If entry is too large to insert, then dynamic table will be empty.
+  void Insert(std::string name, std::string value) {
+    dynamic_table_.Insert(std::move(name), std::move(value));
+  }
+
+  // If index is valid, returns a pointer to the entry, otherwise returns
+  // nullptr.
+  const HpackStringPair* Lookup(size_t index) const;
+
+  // The size limit that the peer (the HPACK encoder) has told the decoder it is
+  // currently operating with. Defaults to SETTINGS_HEADER_TABLE_SIZE, 4096.
+  size_t header_table_size_limit() const { return dynamic_table_.size_limit(); }
+
+  // Sum of the sizes of the dynamic table entries.
+  size_t current_header_table_size() const {
+    return dynamic_table_.current_size();
+  }
+
+ private:
+  friend class test::HpackDecoderTablesPeer;
+  HpackDecoderStaticTable static_table_;
+  HpackDecoderDynamicTable dynamic_table_;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc
new file mode 100644
index 0000000..93ffa73
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc
@@ -0,0 +1,259 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+
+#include <algorithm>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_util.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+class HpackDecoderTablesPeer {
+ public:
+  static size_t num_dynamic_entries(const HpackDecoderTables& tables) {
+    return tables.dynamic_table_.table_.size();
+  }
+};
+
+namespace {
+struct StaticEntry {
+  const char* name;
+  const char* value;
+  size_t index;
+};
+
+std::vector<StaticEntry> MakeSpecStaticEntries() {
+  std::vector<StaticEntry> static_entries;
+
+#define STATIC_TABLE_ENTRY(name, value, index)                             \
+  QUICHE_DCHECK_EQ(static_entries.size() + 1, static_cast<size_t>(index)); \
+  static_entries.push_back({name, value, index});
+
+#include "quiche/http2/hpack/hpack_static_table_entries.inc"
+
+#undef STATIC_TABLE_ENTRY
+
+  return static_entries;
+}
+
+template <class C>
+void ShuffleCollection(C* collection, Http2Random* r) {
+  std::shuffle(collection->begin(), collection->end(), *r);
+}
+
+class HpackDecoderStaticTableTest : public QuicheTest {
+ protected:
+  HpackDecoderStaticTableTest() = default;
+
+  std::vector<StaticEntry> shuffled_static_entries() {
+    std::vector<StaticEntry> entries = MakeSpecStaticEntries();
+    ShuffleCollection(&entries, &random_);
+    return entries;
+  }
+
+  // This test is in a function so that it can be applied to both the static
+  // table and the combined static+dynamic tables.
+  AssertionResult VerifyStaticTableContents() {
+    for (const auto& expected : shuffled_static_entries()) {
+      const HpackStringPair* found = Lookup(expected.index);
+      VERIFY_NE(found, nullptr);
+      VERIFY_EQ(expected.name, found->name) << expected.index;
+      VERIFY_EQ(expected.value, found->value) << expected.index;
+    }
+
+    // There should be no entry with index 0.
+    VERIFY_EQ(nullptr, Lookup(0));
+    return AssertionSuccess();
+  }
+
+  virtual const HpackStringPair* Lookup(size_t index) {
+    return static_table_.Lookup(index);
+  }
+
+  Http2Random* RandomPtr() { return &random_; }
+
+  Http2Random random_;
+
+ private:
+  HpackDecoderStaticTable static_table_;
+};
+
+TEST_F(HpackDecoderStaticTableTest, StaticTableContents) {
+  EXPECT_TRUE(VerifyStaticTableContents());
+}
+
+size_t Size(const std::string& name, const std::string& value) {
+  return name.size() + value.size() + 32;
+}
+
+// To support tests with more than a few of hand crafted changes to the dynamic
+// table, we have another, exceedingly simple, implementation of the HPACK
+// dynamic table containing FakeHpackEntry instances. We can thus compare the
+// contents of the actual table with those in fake_dynamic_table_.
+
+typedef std::tuple<std::string, std::string, size_t> FakeHpackEntry;
+const std::string& Name(const FakeHpackEntry& entry) {
+  return std::get<0>(entry);
+}
+const std::string& Value(const FakeHpackEntry& entry) {
+  return std::get<1>(entry);
+}
+size_t Size(const FakeHpackEntry& entry) {
+  return std::get<2>(entry);
+}
+
+class HpackDecoderTablesTest : public HpackDecoderStaticTableTest {
+ protected:
+  const HpackStringPair* Lookup(size_t index) override {
+    return tables_.Lookup(index);
+  }
+
+  size_t dynamic_size_limit() const {
+    return tables_.header_table_size_limit();
+  }
+  size_t current_dynamic_size() const {
+    return tables_.current_header_table_size();
+  }
+  size_t num_dynamic_entries() const {
+    return HpackDecoderTablesPeer::num_dynamic_entries(tables_);
+  }
+
+  // Insert the name and value into fake_dynamic_table_.
+  void FakeInsert(const std::string& name, const std::string& value) {
+    FakeHpackEntry entry(name, value, Size(name, value));
+    fake_dynamic_table_.insert(fake_dynamic_table_.begin(), entry);
+  }
+
+  // Add up the size of all entries in fake_dynamic_table_.
+  size_t FakeSize() {
+    size_t sz = 0;
+    for (const auto& entry : fake_dynamic_table_) {
+      sz += Size(entry);
+    }
+    return sz;
+  }
+
+  // If the total size of the fake_dynamic_table_ is greater than limit,
+  // keep the first N entries such that those N entries have a size not
+  // greater than limit, and such that keeping entry N+1 would have a size
+  // greater than limit. Returns the count of removed bytes.
+  size_t FakeTrim(size_t limit) {
+    size_t original_size = FakeSize();
+    size_t total_size = 0;
+    for (size_t ndx = 0; ndx < fake_dynamic_table_.size(); ++ndx) {
+      total_size += Size(fake_dynamic_table_[ndx]);
+      if (total_size > limit) {
+        // Need to get rid of ndx and all following entries.
+        fake_dynamic_table_.erase(fake_dynamic_table_.begin() + ndx,
+                                  fake_dynamic_table_.end());
+        return original_size - FakeSize();
+      }
+    }
+    return 0;
+  }
+
+  // Verify that the contents of the actual dynamic table match those in
+  // fake_dynamic_table_.
+  AssertionResult VerifyDynamicTableContents() {
+    VERIFY_EQ(current_dynamic_size(), FakeSize());
+    VERIFY_EQ(num_dynamic_entries(), fake_dynamic_table_.size());
+
+    for (size_t ndx = 0; ndx < fake_dynamic_table_.size(); ++ndx) {
+      const HpackStringPair* found = Lookup(ndx + kFirstDynamicTableIndex);
+      VERIFY_NE(found, nullptr);
+
+      const auto& expected = fake_dynamic_table_[ndx];
+      VERIFY_EQ(Name(expected), found->name);
+      VERIFY_EQ(Value(expected), found->value);
+    }
+
+    // Make sure there are no more entries.
+    VERIFY_EQ(nullptr,
+              Lookup(fake_dynamic_table_.size() + kFirstDynamicTableIndex));
+    return AssertionSuccess();
+  }
+
+  // Apply an update to the limit on the maximum size of the dynamic table.
+  AssertionResult DynamicTableSizeUpdate(size_t size_limit) {
+    VERIFY_EQ(current_dynamic_size(), FakeSize());
+    if (size_limit < current_dynamic_size()) {
+      // Will need to trim the dynamic table's oldest entries.
+      tables_.DynamicTableSizeUpdate(size_limit);
+      FakeTrim(size_limit);
+      return VerifyDynamicTableContents();
+    }
+    // Shouldn't change the size.
+    tables_.DynamicTableSizeUpdate(size_limit);
+    return VerifyDynamicTableContents();
+  }
+
+  // Insert an entry into the dynamic table, confirming that trimming of entries
+  // occurs if the total size is greater than the limit, and that older entries
+  // move up by 1 index.
+  AssertionResult Insert(const std::string& name, const std::string& value) {
+    size_t old_count = num_dynamic_entries();
+    tables_.Insert(name, value);
+    FakeInsert(name, value);
+    VERIFY_EQ(old_count + 1, fake_dynamic_table_.size());
+    FakeTrim(dynamic_size_limit());
+    VERIFY_EQ(current_dynamic_size(), FakeSize());
+    VERIFY_EQ(num_dynamic_entries(), fake_dynamic_table_.size());
+    return VerifyDynamicTableContents();
+  }
+
+ private:
+  HpackDecoderTables tables_;
+
+  std::vector<FakeHpackEntry> fake_dynamic_table_;
+};
+
+TEST_F(HpackDecoderTablesTest, StaticTableContents) {
+  EXPECT_TRUE(VerifyStaticTableContents());
+}
+
+// Generate a bunch of random header entries, insert them, and confirm they
+// present, as required by the RFC, using VerifyDynamicTableContents above on
+// each Insert. Also apply various resizings of the dynamic table.
+TEST_F(HpackDecoderTablesTest, RandomDynamicTable) {
+  EXPECT_EQ(0u, current_dynamic_size());
+  EXPECT_TRUE(VerifyStaticTableContents());
+  EXPECT_TRUE(VerifyDynamicTableContents());
+
+  std::vector<size_t> table_sizes;
+  table_sizes.push_back(dynamic_size_limit());
+  table_sizes.push_back(0);
+  table_sizes.push_back(dynamic_size_limit() / 2);
+  table_sizes.push_back(dynamic_size_limit());
+  table_sizes.push_back(dynamic_size_limit() / 2);
+  table_sizes.push_back(0);
+  table_sizes.push_back(dynamic_size_limit());
+
+  for (size_t limit : table_sizes) {
+    ASSERT_TRUE(DynamicTableSizeUpdate(limit));
+    for (int insert_count = 0; insert_count < 100; ++insert_count) {
+      std::string name =
+          GenerateHttp2HeaderName(random_.UniformInRange(2, 40), RandomPtr());
+      std::string value =
+          GenerateWebSafeString(random_.UniformInRange(2, 600), RandomPtr());
+      ASSERT_TRUE(Insert(name, value));
+    }
+    EXPECT_TRUE(VerifyStaticTableContents());
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_test.cc
new file mode 100644
index 0000000..9974421
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoder_test.cc
@@ -0,0 +1,1192 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoder.h"
+
+// Tests of HpackDecoder.
+
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_state.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/hpack/tools/hpack_example.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_util.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using ::testing::ElementsAreArray;
+using ::testing::Eq;
+
+namespace http2 {
+namespace test {
+class HpackDecoderStatePeer {
+ public:
+  static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) {
+    return &state->decoder_tables_;
+  }
+  static void set_listener(HpackDecoderState* state,
+                           HpackDecoderListener* listener) {
+    state->listener_ = listener;
+  }
+};
+class HpackDecoderPeer {
+ public:
+  static HpackDecoderState* GetDecoderState(HpackDecoder* decoder) {
+    return &decoder->decoder_state_;
+  }
+  static HpackDecoderTables* GetDecoderTables(HpackDecoder* decoder) {
+    return HpackDecoderStatePeer::GetDecoderTables(GetDecoderState(decoder));
+  }
+};
+
+namespace {
+
+typedef std::pair<std::string, std::string> HpackHeaderEntry;
+typedef std::vector<HpackHeaderEntry> HpackHeaderEntries;
+
+// TODO(jamessynge): Create a ...test_utils.h file with the mock listener
+// and with VerifyDynamicTableContents.
+class MockHpackDecoderListener : public HpackDecoderListener {
+ public:
+  MOCK_METHOD(void, OnHeaderListStart, (), (override));
+  MOCK_METHOD(void,
+              OnHeader,
+              (const std::string& name, const std::string& value),
+              (override));
+  MOCK_METHOD(void, OnHeaderListEnd, (), (override));
+  MOCK_METHOD(void,
+              OnHeaderErrorDetected,
+              (absl::string_view error_message),
+              (override));
+};
+
+class HpackDecoderTest : public QuicheTestWithParam<bool>,
+                         public HpackDecoderListener {
+ protected:
+  // Note that we initialize the random number generator with the same seed
+  // for each individual test, therefore the order in which the tests are
+  // executed does not effect the sequence produced by the RNG within any
+  // one test.
+  HpackDecoderTest() : decoder_(this, 4096) {
+    fragment_the_hpack_block_ = GetParam();
+  }
+  ~HpackDecoderTest() override = default;
+
+  void OnHeaderListStart() override {
+    ASSERT_FALSE(saw_start_);
+    ASSERT_FALSE(saw_end_);
+    saw_start_ = true;
+    header_entries_.clear();
+  }
+
+  // Called for each header name-value pair that is decoded, in the order they
+  // appear in the HPACK block. Multiple values for a given key will be emitted
+  // as multiple calls to OnHeader.
+  void OnHeader(const std::string& name, const std::string& value) override {
+    ASSERT_TRUE(saw_start_);
+    ASSERT_FALSE(saw_end_);
+    header_entries_.emplace_back(name, value);
+  }
+
+  // OnHeaderBlockEnd is called after successfully decoding an HPACK block. Will
+  // only be called once per block, even if it extends into CONTINUATION frames.
+  // A callback method which notifies when the parser finishes handling a
+  // header block (i.e. the containing frame has the END_STREAM flag set).
+  // Also indicates the total number of bytes in this block.
+  void OnHeaderListEnd() override {
+    ASSERT_TRUE(saw_start_);
+    ASSERT_FALSE(saw_end_);
+    ASSERT_TRUE(error_messages_.empty());
+    saw_end_ = true;
+  }
+
+  // OnHeaderErrorDetected is called if an error is detected while decoding.
+  // error_message may be used in a GOAWAY frame as the Opaque Data.
+  void OnHeaderErrorDetected(absl::string_view error_message) override {
+    ASSERT_TRUE(saw_start_);
+    error_messages_.push_back(std::string(error_message));
+    // No further callbacks should be made at this point, so replace 'this' as
+    // the listener with mock_listener_, which is a strict mock, so will
+    // generate an error for any calls.
+    HpackDecoderStatePeer::set_listener(
+        HpackDecoderPeer::GetDecoderState(&decoder_), &mock_listener_);
+  }
+
+  AssertionResult DecodeBlock(absl::string_view block) {
+    HTTP2_VLOG(1) << "HpackDecoderTest::DecodeBlock";
+
+    VERIFY_FALSE(decoder_.DetectError());
+    VERIFY_TRUE(error_messages_.empty());
+    VERIFY_FALSE(saw_start_);
+    VERIFY_FALSE(saw_end_);
+    header_entries_.clear();
+
+    VERIFY_FALSE(decoder_.DetectError());
+    VERIFY_TRUE(decoder_.StartDecodingBlock());
+    VERIFY_FALSE(decoder_.DetectError());
+
+    if (fragment_the_hpack_block_) {
+      // See note in ctor regarding RNG.
+      while (!block.empty()) {
+        size_t fragment_size = random_.RandomSizeSkewedLow(block.size());
+        DecodeBuffer db(block.substr(0, fragment_size));
+        VERIFY_TRUE(decoder_.DecodeFragment(&db));
+        VERIFY_EQ(0u, db.Remaining());
+        block.remove_prefix(fragment_size);
+      }
+    } else {
+      DecodeBuffer db(block);
+      VERIFY_TRUE(decoder_.DecodeFragment(&db));
+      VERIFY_EQ(0u, db.Remaining());
+    }
+    VERIFY_FALSE(decoder_.DetectError());
+
+    VERIFY_TRUE(decoder_.EndDecodingBlock());
+    if (saw_end_) {
+      VERIFY_FALSE(decoder_.DetectError());
+      VERIFY_TRUE(error_messages_.empty());
+    } else {
+      VERIFY_TRUE(decoder_.DetectError());
+      VERIFY_FALSE(error_messages_.empty());
+    }
+
+    saw_start_ = saw_end_ = false;
+    return AssertionSuccess();
+  }
+
+  const HpackDecoderTables& GetDecoderTables() {
+    return *HpackDecoderPeer::GetDecoderTables(&decoder_);
+  }
+  const HpackStringPair* Lookup(size_t index) {
+    return GetDecoderTables().Lookup(index);
+  }
+  size_t current_header_table_size() {
+    return GetDecoderTables().current_header_table_size();
+  }
+  size_t header_table_size_limit() {
+    return GetDecoderTables().header_table_size_limit();
+  }
+  void set_header_table_size_limit(size_t size) {
+    HpackDecoderPeer::GetDecoderTables(&decoder_)->DynamicTableSizeUpdate(size);
+  }
+
+  // dynamic_index is one-based, because that is the way RFC 7541 shows it.
+  AssertionResult VerifyEntry(size_t dynamic_index,
+                              const char* name,
+                              const char* value) {
+    const HpackStringPair* entry =
+        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
+    VERIFY_NE(entry, nullptr);
+    VERIFY_EQ(entry->name, name);
+    VERIFY_EQ(entry->value, value);
+    return AssertionSuccess();
+  }
+  AssertionResult VerifyNoEntry(size_t dynamic_index) {
+    const HpackStringPair* entry =
+        Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
+    VERIFY_EQ(entry, nullptr);
+    return AssertionSuccess();
+  }
+  AssertionResult VerifyDynamicTableContents(
+      const std::vector<std::pair<const char*, const char*>>& entries) {
+    size_t index = 1;
+    for (const auto& entry : entries) {
+      VERIFY_SUCCESS(VerifyEntry(index, entry.first, entry.second));
+      ++index;
+    }
+    VERIFY_SUCCESS(VerifyNoEntry(index));
+    return AssertionSuccess();
+  }
+
+  Http2Random random_;
+  HpackDecoder decoder_;
+  testing::StrictMock<MockHpackDecoderListener> mock_listener_;
+  HpackHeaderEntries header_entries_;
+  std::vector<std::string> error_messages_;
+  bool fragment_the_hpack_block_;
+  bool saw_start_ = false;
+  bool saw_end_ = false;
+};
+INSTANTIATE_TEST_SUITE_P(AllWays, HpackDecoderTest, ::testing::Bool());
+
+// Test based on RFC 7541, section C.3: Request Examples without Huffman Coding.
+// This section shows several consecutive header lists, corresponding to HTTP
+// requests, on the same connection.
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3
+TEST_P(HpackDecoderTest, C3_RequestExamples) {
+  // C.3.1 First Request
+  std::string hpack_block = HpackExampleToStringOrDie(R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      86                                      | == Indexed - Add ==
+                                              |   idx = 6
+                                              | -> :scheme: http
+      84                                      | == Indexed - Add ==
+                                              |   idx = 4
+                                              | -> :path: /
+      41                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 1)
+                                              |     :authority
+      0f                                      |   Literal value (len = 15)
+      7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
+                                              | -> :authority:
+                                              |   www.example.com
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":method", "GET"},
+                  HpackHeaderEntry{":scheme", "http"},
+                  HpackHeaderEntry{":path", "/"},
+                  HpackHeaderEntry{":authority", "www.example.com"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  57) :authority: www.example.com
+  //         Table size:  57
+  ASSERT_TRUE(VerifyDynamicTableContents({{":authority", "www.example.com"}}));
+  ASSERT_EQ(57u, current_header_table_size());
+
+  // C.3.2 Second Request
+  hpack_block = HpackExampleToStringOrDie(R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      86                                      | == Indexed - Add ==
+                                              |   idx = 6
+                                              | -> :scheme: http
+      84                                      | == Indexed - Add ==
+                                              |   idx = 4
+                                              | -> :path: /
+      be                                      | == Indexed - Add ==
+                                              |   idx = 62
+                                              | -> :authority:
+                                              |   www.example.com
+      58                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 24)
+                                              |     cache-control
+      08                                      |   Literal value (len = 8)
+      6e6f 2d63 6163 6865                     | no-cache
+                                              | -> cache-control: no-cache
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":method", "GET"},
+                  HpackHeaderEntry{":scheme", "http"},
+                  HpackHeaderEntry{":path", "/"},
+                  HpackHeaderEntry{":authority", "www.example.com"},
+                  HpackHeaderEntry{"cache-control", "no-cache"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  53) cache-control: no-cache
+  //   [  2] (s =  57) :authority: www.example.com
+  //         Table size: 110
+  ASSERT_TRUE(VerifyDynamicTableContents(
+      {{"cache-control", "no-cache"}, {":authority", "www.example.com"}}));
+  ASSERT_EQ(110u, current_header_table_size());
+
+  // C.3.2 Third Request
+  hpack_block = HpackExampleToStringOrDie(R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      87                                      | == Indexed - Add ==
+                                              |   idx = 7
+                                              | -> :scheme: https
+      85                                      | == Indexed - Add ==
+                                              |   idx = 5
+                                              | -> :path: /index.html
+      bf                                      | == Indexed - Add ==
+                                              |   idx = 63
+                                              | -> :authority:
+                                              |   www.example.com
+      40                                      | == Literal indexed ==
+      0a                                      |   Literal name (len = 10)
+      6375 7374 6f6d 2d6b 6579                | custom-key
+      0c                                      |   Literal value (len = 12)
+      6375 7374 6f6d 2d76 616c 7565           | custom-value
+                                              | -> custom-key:
+                                              |   custom-value
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":method", "GET"},
+                  HpackHeaderEntry{":scheme", "https"},
+                  HpackHeaderEntry{":path", "/index.html"},
+                  HpackHeaderEntry{":authority", "www.example.com"},
+                  HpackHeaderEntry{"custom-key", "custom-value"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  54) custom-key: custom-value
+  //   [  2] (s =  53) cache-control: no-cache
+  //   [  3] (s =  57) :authority: www.example.com
+  //         Table size: 164
+  ASSERT_TRUE(VerifyDynamicTableContents({{"custom-key", "custom-value"},
+                                          {"cache-control", "no-cache"},
+                                          {":authority", "www.example.com"}}));
+  ASSERT_EQ(164u, current_header_table_size());
+}
+
+// Test based on RFC 7541, section C.4 Request Examples with Huffman Coding.
+// This section shows the same examples as the previous section but uses
+// Huffman encoding for the literal values.
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4
+TEST_P(HpackDecoderTest, C4_RequestExamplesWithHuffmanEncoding) {
+  // C.4.1 First Request
+  std::string hpack_block = HpackExampleToStringOrDie(R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      86                                      | == Indexed - Add ==
+                                              |   idx = 6
+                                              | -> :scheme: http
+      84                                      | == Indexed - Add ==
+                                              |   idx = 4
+                                              | -> :path: /
+      41                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 1)
+                                              |     :authority
+      8c                                      |   Literal value (len = 12)
+                                              |     Huffman encoded:
+      f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
+                                              |     Decoded:
+                                              | www.example.com
+                                              | -> :authority:
+                                              |   www.example.com
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":method", "GET"},
+                  HpackHeaderEntry{":scheme", "http"},
+                  HpackHeaderEntry{":path", "/"},
+                  HpackHeaderEntry{":authority", "www.example.com"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  57) :authority: www.example.com
+  //         Table size:  57
+  ASSERT_TRUE(VerifyDynamicTableContents({{":authority", "www.example.com"}}));
+  ASSERT_EQ(57u, current_header_table_size());
+
+  // C.4.2 Second Request
+  hpack_block = HpackExampleToStringOrDie(R"(
+      82                                      | == Indexed - Add ==
+                                              |   idx = 2
+                                              | -> :method: GET
+      86                                      | == Indexed - Add ==
+                                              |   idx = 6
+                                              | -> :scheme: http
+      84                                      | == Indexed - Add ==
+                                              |   idx = 4
+                                              | -> :path: /
+      be                                      | == Indexed - Add ==
+                                              |   idx = 62
+                                              | -> :authority:
+                                              |   www.example.com
+      58                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 24)
+                                              |     cache-control
+      86                                      |   Literal value (len = 6)
+                                              |     Huffman encoded:
+      a8eb 1064 9cbf                          | ...d..
+                                              |     Decoded:
+                                              | no-cache
+                                              | -> cache-control: no-cache
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":method", "GET"},
+                  HpackHeaderEntry{":scheme", "http"},
+                  HpackHeaderEntry{":path", "/"},
+                  HpackHeaderEntry{":authority", "www.example.com"},
+                  HpackHeaderEntry{"cache-control", "no-cache"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  53) cache-control: no-cache
+  //   [  2] (s =  57) :authority: www.example.com
+  //         Table size: 110
+  ASSERT_TRUE(VerifyDynamicTableContents(
+      {{"cache-control", "no-cache"}, {":authority", "www.example.com"}}));
+  ASSERT_EQ(110u, current_header_table_size());
+
+  // C.4.2 Third Request
+  hpack_block = HpackExampleToStringOrDie(R"(
+    82                                      | == Indexed - Add ==
+                                            |   idx = 2
+                                            | -> :method: GET
+    87                                      | == Indexed - Add ==
+                                            |   idx = 7
+                                            | -> :scheme: https
+    85                                      | == Indexed - Add ==
+                                            |   idx = 5
+                                            | -> :path: /index.html
+    bf                                      | == Indexed - Add ==
+                                            |   idx = 63
+                                            | -> :authority:
+                                            |   www.example.com
+    40                                      | == Literal indexed ==
+    88                                      |   Literal name (len = 8)
+                                            |     Huffman encoded:
+    25a8 49e9 5ba9 7d7f                     | %.I.[.}.
+                                            |     Decoded:
+                                            | custom-key
+    89                                      |   Literal value (len = 9)
+                                            |     Huffman encoded:
+    25a8 49e9 5bb8 e8b4 bf                  | %.I.[....
+                                            |     Decoded:
+                                            | custom-value
+                                            | -> custom-key:
+                                            |   custom-value
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":method", "GET"},
+                  HpackHeaderEntry{":scheme", "https"},
+                  HpackHeaderEntry{":path", "/index.html"},
+                  HpackHeaderEntry{":authority", "www.example.com"},
+                  HpackHeaderEntry{"custom-key", "custom-value"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  54) custom-key: custom-value
+  //   [  2] (s =  53) cache-control: no-cache
+  //   [  3] (s =  57) :authority: www.example.com
+  //         Table size: 164
+  ASSERT_TRUE(VerifyDynamicTableContents({{"custom-key", "custom-value"},
+                                          {"cache-control", "no-cache"},
+                                          {":authority", "www.example.com"}}));
+  ASSERT_EQ(164u, current_header_table_size());
+}
+
+// Test based on RFC 7541, section C.5: Response Examples without Huffman
+// Coding. This section shows several consecutive header lists, corresponding
+// to HTTP responses, on the same connection. The HTTP/2 setting parameter
+// SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing
+// some evictions to occur.
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.5
+TEST_P(HpackDecoderTest, C5_ResponseExamples) {
+  set_header_table_size_limit(256);
+
+  // C.5.1 First Response
+  //
+  // Header list to encode:
+  //
+  //   :status: 302
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   location: https://www.example.com
+
+  std::string hpack_block = HpackExampleToStringOrDie(R"(
+      48                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 8)
+                                              |     :status
+      03                                      |   Literal value (len = 3)
+      3330 32                                 | 302
+                                              | -> :status: 302
+      58                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 24)
+                                              |     cache-control
+      07                                      |   Literal value (len = 7)
+      7072 6976 6174 65                       | private
+                                              | -> cache-control: private
+      61                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 33)
+                                              |     date
+      1d                                      |   Literal value (len = 29)
+      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
+      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:21 GMT
+      6e                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 46)
+                                              |     location
+      17                                      |   Literal value (len = 23)
+      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
+      706c 652e 636f 6d                       | ple.com
+                                              | -> location:
+                                              |   https://www.example.com
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":status", "302"},
+                  HpackHeaderEntry{"cache-control", "private"},
+                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                  HpackHeaderEntry{"location", "https://www.example.com"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  63) location: https://www.example.com
+  //   [  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   [  3] (s =  52) cache-control: private
+  //   [  4] (s =  42) :status: 302
+  //         Table size: 222
+  ASSERT_TRUE(
+      VerifyDynamicTableContents({{"location", "https://www.example.com"},
+                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                                  {"cache-control", "private"},
+                                  {":status", "302"}}));
+  ASSERT_EQ(222u, current_header_table_size());
+
+  // C.5.2 Second Response
+  //
+  // The (":status", "302") header field is evicted from the dynamic table to
+  // free space to allow adding the (":status", "307") header field.
+  //
+  // Header list to encode:
+  //
+  //   :status: 307
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   location: https://www.example.com
+
+  hpack_block = HpackExampleToStringOrDie(R"(
+      48                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 8)
+                                              |     :status
+      03                                      |   Literal value (len = 3)
+      3330 37                                 | 307
+                                              | - evict: :status: 302
+                                              | -> :status: 307
+      c1                                      | == Indexed - Add ==
+                                              |   idx = 65
+                                              | -> cache-control: private
+      c0                                      | == Indexed - Add ==
+                                              |   idx = 64
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:21 GMT
+      bf                                      | == Indexed - Add ==
+                                              |   idx = 63
+                                              | -> location:
+                                              |   https://www.example.com
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":status", "307"},
+                  HpackHeaderEntry{"cache-control", "private"},
+                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                  HpackHeaderEntry{"location", "https://www.example.com"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  42) :status: 307
+  //   [  2] (s =  63) location: https://www.example.com
+  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   [  4] (s =  52) cache-control: private
+  //         Table size: 222
+
+  ASSERT_TRUE(
+      VerifyDynamicTableContents({{":status", "307"},
+                                  {"location", "https://www.example.com"},
+                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                                  {"cache-control", "private"}}));
+  ASSERT_EQ(222u, current_header_table_size());
+
+  // C.5.3 Third Response
+  //
+  // Several header fields are evicted from the dynamic table during the
+  // processing of this header list.
+  //
+  // Header list to encode:
+  //
+  //   :status: 200
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:22 GMT
+  //   location: https://www.example.com
+  //   content-encoding: gzip
+  //   set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1
+  hpack_block = HpackExampleToStringOrDie(R"(
+      88                                      | == Indexed - Add ==
+                                              |   idx = 8
+                                              | -> :status: 200
+      c1                                      | == Indexed - Add ==
+                                              |   idx = 65
+                                              | -> cache-control: private
+      61                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 33)
+                                              |     date
+      1d                                      |   Literal value (len = 29)
+      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
+      2032 303a 3133 3a32 3220 474d 54        |  20:13:22 GMT
+                                              | - evict: cache-control:
+                                              |   private
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:22 GMT
+      c0                                      | == Indexed - Add ==
+                                              |   idx = 64
+                                              | -> location:
+                                              |   https://www.example.com
+      5a                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 26)
+                                              |     content-encoding
+      04                                      |   Literal value (len = 4)
+      677a 6970                               | gzip
+                                              | - evict: date: Mon, 21 Oct
+                                              |    2013 20:13:21 GMT
+                                              | -> content-encoding: gzip
+      77                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 55)
+                                              |     set-cookie
+      38                                      |   Literal value (len = 56)
+      666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO
+      5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU;
+      206d 6178 2d61 6765 3d33 3630 303b 2076 |  max-age=3600; v
+      6572 7369 6f6e 3d31                     | ersion=1
+                                              | - evict: location:
+                                              |   https://www.example.com
+                                              | - evict: :status: 307
+                                              | -> set-cookie: foo=ASDJKHQ
+                                              |   KBZXOQWEOPIUAXQWEOIU; ma
+                                              |   x-age=3600; version=1
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(
+      header_entries_,
+      ElementsAreArray({
+          HpackHeaderEntry{":status", "200"},
+          HpackHeaderEntry{"cache-control", "private"},
+          HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:22 GMT"},
+          HpackHeaderEntry{"location", "https://www.example.com"},
+          HpackHeaderEntry{"content-encoding", "gzip"},
+          HpackHeaderEntry{
+              "set-cookie",
+              "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
+      }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
+  //                    max-age=3600; version=1
+  //   [  2] (s =  52) content-encoding: gzip
+  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
+  //         Table size: 215
+  ASSERT_TRUE(VerifyDynamicTableContents(
+      {{"set-cookie",
+        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
+       {"content-encoding", "gzip"},
+       {"date", "Mon, 21 Oct 2013 20:13:22 GMT"}}));
+  ASSERT_EQ(215u, current_header_table_size());
+}
+
+// Test based on RFC 7541, section C.6: Response Examples with Huffman Coding.
+// This section shows the same examples as the previous section but uses Huffman
+// encoding for the literal values. The HTTP/2 setting parameter
+// SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing some
+// evictions to occur. The eviction mechanism uses the length of the decoded
+// literal values, so the same evictions occur as in the previous section.
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6
+TEST_P(HpackDecoderTest, C6_ResponseExamplesWithHuffmanEncoding) {
+  set_header_table_size_limit(256);
+
+  // C.5.1 First Response
+  //
+  // Header list to encode:
+  //
+  //   :status: 302
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   location: https://www.example.com
+  std::string hpack_block = HpackExampleToStringOrDie(R"(
+      48                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 8)
+                                              |     :status
+      03                                      |   Literal value (len = 3)
+      3330 32                                 | 302
+                                              | -> :status: 302
+      58                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 24)
+                                              |     cache-control
+      07                                      |   Literal value (len = 7)
+      7072 6976 6174 65                       | private
+                                              | -> cache-control: private
+      61                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 33)
+                                              |     date
+      1d                                      |   Literal value (len = 29)
+      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
+      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:21 GMT
+      6e                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 46)
+                                              |     location
+      17                                      |   Literal value (len = 23)
+      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
+      706c 652e 636f 6d                       | ple.com
+                                              | -> location:
+                                              |   https://www.example.com
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":status", "302"},
+                  HpackHeaderEntry{"cache-control", "private"},
+                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                  HpackHeaderEntry{"location", "https://www.example.com"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  63) location: https://www.example.com
+  //   [  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   [  3] (s =  52) cache-control: private
+  //   [  4] (s =  42) :status: 302
+  //         Table size: 222
+  ASSERT_TRUE(
+      VerifyDynamicTableContents({{"location", "https://www.example.com"},
+                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                                  {"cache-control", "private"},
+                                  {":status", "302"}}));
+  ASSERT_EQ(222u, current_header_table_size());
+
+  // C.5.2 Second Response
+  //
+  // The (":status", "302") header field is evicted from the dynamic table to
+  // free space to allow adding the (":status", "307") header field.
+  //
+  // Header list to encode:
+  //
+  //   :status: 307
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   location: https://www.example.com
+  hpack_block = HpackExampleToStringOrDie(R"(
+      48                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 8)
+                                              |     :status
+      03                                      |   Literal value (len = 3)
+      3330 37                                 | 307
+                                              | - evict: :status: 302
+                                              | -> :status: 307
+      c1                                      | == Indexed - Add ==
+                                              |   idx = 65
+                                              | -> cache-control: private
+      c0                                      | == Indexed - Add ==
+                                              |   idx = 64
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:21 GMT
+      bf                                      | == Indexed - Add ==
+                                              |   idx = 63
+                                              | -> location:
+                                              |   https://www.example.com
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(header_entries_,
+              ElementsAreArray({
+                  HpackHeaderEntry{":status", "307"},
+                  HpackHeaderEntry{"cache-control", "private"},
+                  HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                  HpackHeaderEntry{"location", "https://www.example.com"},
+              }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  42) :status: 307
+  //   [  2] (s =  63) location: https://www.example.com
+  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT
+  //   [  4] (s =  52) cache-control: private
+  //         Table size: 222
+  ASSERT_TRUE(
+      VerifyDynamicTableContents({{":status", "307"},
+                                  {"location", "https://www.example.com"},
+                                  {"date", "Mon, 21 Oct 2013 20:13:21 GMT"},
+                                  {"cache-control", "private"}}));
+  ASSERT_EQ(222u, current_header_table_size());
+
+  // C.5.3 Third Response
+  //
+  // Several header fields are evicted from the dynamic table during the
+  // processing of this header list.
+  //
+  // Header list to encode:
+  //
+  //   :status: 200
+  //   cache-control: private
+  //   date: Mon, 21 Oct 2013 20:13:22 GMT
+  //   location: https://www.example.com
+  //   content-encoding: gzip
+  //   set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1
+  hpack_block = HpackExampleToStringOrDie(R"(
+      88                                      | == Indexed - Add ==
+                                              |   idx = 8
+                                              | -> :status: 200
+      c1                                      | == Indexed - Add ==
+                                              |   idx = 65
+                                              | -> cache-control: private
+      61                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 33)
+                                              |     date
+      1d                                      |   Literal value (len = 29)
+      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
+      2032 303a 3133 3a32 3220 474d 54        |  20:13:22 GMT
+                                              | - evict: cache-control:
+                                              |   private
+                                              | -> date: Mon, 21 Oct 2013
+                                              |   20:13:22 GMT
+      c0                                      | == Indexed - Add ==
+                                              |   idx = 64
+                                              | -> location:
+                                              |   https://www.example.com
+      5a                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 26)
+                                              |     content-encoding
+      04                                      |   Literal value (len = 4)
+      677a 6970                               | gzip
+                                              | - evict: date: Mon, 21 Oct
+                                              |    2013 20:13:21 GMT
+                                              | -> content-encoding: gzip
+      77                                      | == Literal indexed ==
+                                              |   Indexed name (idx = 55)
+                                              |     set-cookie
+      38                                      |   Literal value (len = 56)
+      666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO
+      5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU;
+      206d 6178 2d61 6765 3d33 3630 303b 2076 |  max-age=3600; v
+      6572 7369 6f6e 3d31                     | ersion=1
+                                              | - evict: location:
+                                              |   https://www.example.com
+                                              | - evict: :status: 307
+                                              | -> set-cookie: foo=ASDJKHQ
+                                              |   KBZXOQWEOPIUAXQWEOIU; ma
+                                              |   x-age=3600; version=1
+  )");
+  EXPECT_TRUE(DecodeBlock(hpack_block));
+  ASSERT_THAT(
+      header_entries_,
+      ElementsAreArray({
+          HpackHeaderEntry{":status", "200"},
+          HpackHeaderEntry{"cache-control", "private"},
+          HpackHeaderEntry{"date", "Mon, 21 Oct 2013 20:13:22 GMT"},
+          HpackHeaderEntry{"location", "https://www.example.com"},
+          HpackHeaderEntry{"content-encoding", "gzip"},
+          HpackHeaderEntry{
+              "set-cookie",
+              "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
+      }));
+
+  // Dynamic Table (after decoding):
+  //
+  //   [  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;
+  //                    max-age=3600; version=1
+  //   [  2] (s =  52) content-encoding: gzip
+  //   [  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT
+  //         Table size: 215
+  ASSERT_TRUE(VerifyDynamicTableContents(
+      {{"set-cookie",
+        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
+       {"content-encoding", "gzip"},
+       {"date", "Mon, 21 Oct 2013 20:13:22 GMT"}}));
+  ASSERT_EQ(215u, current_header_table_size());
+}
+
+// Confirm that the table size can be changed, but at most twice.
+TEST_P(HpackDecoderTest, ProcessesOptionalTableSizeUpdates) {
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+  // One update allowed.
+  {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(3000);
+    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+    EXPECT_EQ(3000u, header_table_size_limit());
+    EXPECT_EQ(0u, current_header_table_size());
+    EXPECT_TRUE(header_entries_.empty());
+  }
+  // Two updates allowed.
+  {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(2000);
+    hbb.AppendDynamicTableSizeUpdate(2500);
+    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+    EXPECT_EQ(2500u, header_table_size_limit());
+    EXPECT_EQ(0u, current_header_table_size());
+    EXPECT_TRUE(header_entries_.empty());
+  }
+  // A third update in the same HPACK block is rejected, so the final
+  // size is 1000, not 500.
+  {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(1500);
+    hbb.AppendDynamicTableSizeUpdate(1000);
+    hbb.AppendDynamicTableSizeUpdate(500);
+    EXPECT_FALSE(DecodeBlock(hbb.buffer()));
+    EXPECT_EQ(HpackDecodingError::kDynamicTableSizeUpdateNotAllowed,
+              decoder_.error());
+    EXPECT_EQ(1u, error_messages_.size());
+    EXPECT_THAT(error_messages_[0],
+                Eq("Dynamic table size update not allowed"));
+    EXPECT_EQ(1000u, header_table_size_limit());
+    EXPECT_EQ(0u, current_header_table_size());
+    EXPECT_TRUE(header_entries_.empty());
+  }
+  // An error has been detected, so calls to HpackDecoder::DecodeFragment
+  // should return immediately.
+  DecodeBuffer db("\x80");
+  EXPECT_FALSE(decoder_.DecodeFragment(&db));
+  EXPECT_EQ(0u, db.Offset());
+  EXPECT_EQ(1u, error_messages_.size());
+}
+
+// Confirm that the table size can be changed when required, but at most twice.
+TEST_P(HpackDecoderTest, ProcessesRequiredTableSizeUpdate) {
+  EXPECT_EQ(4096u, decoder_.GetCurrentHeaderTableSizeSetting());
+  // One update required, two allowed, one provided, followed by a header.
+  decoder_.ApplyHeaderTableSizeSetting(1024);
+  decoder_.ApplyHeaderTableSizeSetting(2048);
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+  EXPECT_EQ(2048u, decoder_.GetCurrentHeaderTableSizeSetting());
+  {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(1024);
+    hbb.AppendIndexedHeader(4);  // :path: /
+    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+    EXPECT_THAT(header_entries_,
+                ElementsAreArray({HpackHeaderEntry{":path", "/"}}));
+    EXPECT_EQ(1024u, header_table_size_limit());
+    EXPECT_EQ(0u, current_header_table_size());
+  }
+  // One update required, two allowed, two provided, followed by a header.
+  decoder_.ApplyHeaderTableSizeSetting(1000);
+  decoder_.ApplyHeaderTableSizeSetting(1500);
+  EXPECT_EQ(1500u, decoder_.GetCurrentHeaderTableSizeSetting());
+  {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(500);
+    hbb.AppendDynamicTableSizeUpdate(1250);
+    hbb.AppendIndexedHeader(5);  // :path: /index.html
+    EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+    EXPECT_THAT(header_entries_,
+                ElementsAreArray({HpackHeaderEntry{":path", "/index.html"}}));
+    EXPECT_EQ(1250u, header_table_size_limit());
+    EXPECT_EQ(0u, current_header_table_size());
+  }
+  // One update required, two allowed, three provided, followed by a header.
+  // The third update is rejected, so the final size is 1000, not 500.
+  decoder_.ApplyHeaderTableSizeSetting(500);
+  decoder_.ApplyHeaderTableSizeSetting(1000);
+  EXPECT_EQ(1000u, decoder_.GetCurrentHeaderTableSizeSetting());
+  {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(200);
+    hbb.AppendDynamicTableSizeUpdate(700);
+    hbb.AppendDynamicTableSizeUpdate(900);
+    hbb.AppendIndexedHeader(5);  // Not decoded.
+    EXPECT_FALSE(DecodeBlock(hbb.buffer()));
+    EXPECT_FALSE(saw_end_);
+    EXPECT_EQ(HpackDecodingError::kDynamicTableSizeUpdateNotAllowed,
+              decoder_.error());
+    EXPECT_EQ(1u, error_messages_.size());
+    EXPECT_THAT(error_messages_[0],
+                Eq("Dynamic table size update not allowed"));
+    EXPECT_EQ(700u, header_table_size_limit());
+    EXPECT_EQ(0u, current_header_table_size());
+    EXPECT_TRUE(header_entries_.empty());
+  }
+  EXPECT_EQ(1000u, decoder_.GetCurrentHeaderTableSizeSetting());
+  // Now that an error has been detected, StartDecodingBlock should return
+  // false.
+  EXPECT_FALSE(decoder_.StartDecodingBlock());
+}
+
+// Confirm that required size updates are validated.
+TEST_P(HpackDecoderTest, InvalidRequiredSizeUpdate) {
+  // Require a size update, but provide one that isn't small enough (must be
+  // zero or one, in this case).
+  decoder_.ApplyHeaderTableSizeSetting(1);
+  decoder_.ApplyHeaderTableSizeSetting(1024);
+  HpackBlockBuilder hbb;
+  hbb.AppendDynamicTableSizeUpdate(2);
+  EXPECT_TRUE(decoder_.StartDecodingBlock());
+  DecodeBuffer db(hbb.buffer());
+  EXPECT_FALSE(decoder_.DecodeFragment(&db));
+  EXPECT_FALSE(saw_end_);
+  EXPECT_EQ(
+      HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark,
+      decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0],
+              Eq("Initial dynamic table size update is above low water mark"));
+  EXPECT_EQ(Http2SettingsInfo::DefaultHeaderTableSize(),
+            header_table_size_limit());
+}
+
+// Confirm that required size updates are indeed required before the end.
+TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeEnd) {
+  decoder_.ApplyHeaderTableSizeSetting(1024);
+  EXPECT_FALSE(DecodeBlock(""));
+  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
+            decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
+  EXPECT_FALSE(saw_end_);
+}
+
+// Confirm that required size updates are indeed required before an
+// indexed header.
+TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeIndexedHeader) {
+  decoder_.ApplyHeaderTableSizeSetting(1024);
+  HpackBlockBuilder hbb;
+  hbb.AppendIndexedHeader(1);
+  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
+  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
+            decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
+  EXPECT_FALSE(saw_end_);
+  EXPECT_TRUE(header_entries_.empty());
+}
+
+// Confirm that required size updates are indeed required before an indexed
+// header name.
+// TODO(jamessynge): Move some of these to hpack_decoder_state_test.cc.
+TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeIndexedHeaderName) {
+  decoder_.ApplyHeaderTableSizeSetting(1024);
+  HpackBlockBuilder hbb;
+  hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 2,
+                                     false, "PUT");
+  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
+  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
+            decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
+  EXPECT_FALSE(saw_end_);
+  EXPECT_TRUE(header_entries_.empty());
+}
+
+// Confirm that required size updates are indeed required before a literal
+// header name.
+TEST_P(HpackDecoderTest, RequiredTableSizeChangeBeforeLiteralName) {
+  decoder_.ApplyHeaderTableSizeSetting(1024);
+  HpackBlockBuilder hbb;
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
+                                false, "name", false, "some data.");
+  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
+  EXPECT_EQ(HpackDecodingError::kMissingDynamicTableSizeUpdate,
+            decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0], Eq("Missing dynamic table size update"));
+  EXPECT_FALSE(saw_end_);
+  EXPECT_TRUE(header_entries_.empty());
+}
+
+// Confirm that an excessively long varint is detected, in this case an
+// index of 127, but with lots of additional high-order 0 bits provided,
+// too many to be allowed.
+TEST_P(HpackDecoderTest, InvalidIndexedHeaderVarint) {
+  EXPECT_TRUE(decoder_.StartDecodingBlock());
+  DecodeBuffer db("\xff\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00");
+  EXPECT_FALSE(decoder_.DecodeFragment(&db));
+  EXPECT_TRUE(decoder_.DetectError());
+  EXPECT_FALSE(saw_end_);
+  EXPECT_EQ(HpackDecodingError::kIndexVarintError, decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0],
+              Eq("Index varint beyond implementation limit"));
+  EXPECT_TRUE(header_entries_.empty());
+  // Now that an error has been detected, EndDecodingBlock should not succeed.
+  EXPECT_FALSE(decoder_.EndDecodingBlock());
+}
+
+// Confirm that an invalid index into the tables is detected, in this case an
+// index of 0.
+TEST_P(HpackDecoderTest, InvalidIndex) {
+  EXPECT_TRUE(decoder_.StartDecodingBlock());
+  DecodeBuffer db("\x80");
+  EXPECT_FALSE(decoder_.DecodeFragment(&db));
+  EXPECT_TRUE(decoder_.DetectError());
+  EXPECT_FALSE(saw_end_);
+  EXPECT_EQ(HpackDecodingError::kInvalidIndex, decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0],
+              Eq("Invalid index in indexed header field representation"));
+  EXPECT_TRUE(header_entries_.empty());
+  // Now that an error has been detected, EndDecodingBlock should not succeed.
+  EXPECT_FALSE(decoder_.EndDecodingBlock());
+}
+
+// Confirm that EndDecodingBlock detects a truncated HPACK block.
+TEST_P(HpackDecoderTest, TruncatedBlock) {
+  HpackBlockBuilder hbb;
+  hbb.AppendDynamicTableSizeUpdate(3000);
+  EXPECT_EQ(3u, hbb.size());
+  hbb.AppendDynamicTableSizeUpdate(4000);
+  EXPECT_EQ(6u, hbb.size());
+  // Decodes this block if the whole thing is provided.
+  EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+  EXPECT_EQ(4000u, header_table_size_limit());
+  // Multiple times even.
+  EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+  EXPECT_EQ(4000u, header_table_size_limit());
+  // But not if the block is truncated.
+  EXPECT_FALSE(DecodeBlock(hbb.buffer().substr(0, hbb.size() - 1)));
+  EXPECT_FALSE(saw_end_);
+  EXPECT_EQ(HpackDecodingError::kTruncatedBlock, decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0],
+              Eq("Block ends in the middle of an instruction"));
+  // The first update was decoded.
+  EXPECT_EQ(3000u, header_table_size_limit());
+  EXPECT_EQ(0u, current_header_table_size());
+  EXPECT_TRUE(header_entries_.empty());
+}
+
+// Confirm that an oversized string is detected, ending decoding.
+TEST_P(HpackDecoderTest, OversizeStringDetected) {
+  HpackBlockBuilder hbb;
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
+                                false, "name", false, "some data.");
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kUnindexedLiteralHeader, false,
+                                "name2", false, "longer data");
+
+  // Normally able to decode this block.
+  EXPECT_TRUE(DecodeBlock(hbb.buffer()));
+  EXPECT_THAT(header_entries_,
+              ElementsAreArray({HpackHeaderEntry{"name", "some data."},
+                                HpackHeaderEntry{"name2", "longer data"}}));
+
+  // But not if the maximum size of strings is less than the longest string.
+  decoder_.set_max_string_size_bytes(10);
+  EXPECT_FALSE(DecodeBlock(hbb.buffer()));
+  EXPECT_THAT(header_entries_,
+              ElementsAreArray({HpackHeaderEntry{"name", "some data."}}));
+  EXPECT_FALSE(saw_end_);
+  EXPECT_EQ(HpackDecodingError::kValueTooLong, decoder_.error());
+  EXPECT_EQ(1u, error_messages_.size());
+  EXPECT_THAT(error_messages_[0], Eq("Value length exceeds buffer limit"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoding_error.cc b/quiche/http2/hpack/decoder/hpack_decoding_error.cc
new file mode 100644
index 0000000..9adb2e2
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoding_error.cc
@@ -0,0 +1,51 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+
+namespace http2 {
+
+// static
+absl::string_view HpackDecodingErrorToString(HpackDecodingError error) {
+  switch (error) {
+    case HpackDecodingError::kOk:
+      return "No error detected";
+    case HpackDecodingError::kIndexVarintError:
+      return "Index varint beyond implementation limit";
+    case HpackDecodingError::kNameLengthVarintError:
+      return "Name length varint beyond implementation limit";
+    case HpackDecodingError::kValueLengthVarintError:
+      return "Value length varint beyond implementation limit";
+    case HpackDecodingError::kNameTooLong:
+      return "Name length exceeds buffer limit";
+    case HpackDecodingError::kValueTooLong:
+      return "Value length exceeds buffer limit";
+    case HpackDecodingError::kNameHuffmanError:
+      return "Name Huffman encoding error";
+    case HpackDecodingError::kValueHuffmanError:
+      return "Value Huffman encoding error";
+    case HpackDecodingError::kMissingDynamicTableSizeUpdate:
+      return "Missing dynamic table size update";
+    case HpackDecodingError::kInvalidIndex:
+      return "Invalid index in indexed header field representation";
+    case HpackDecodingError::kInvalidNameIndex:
+      return "Invalid index in literal header field with indexed name "
+             "representation";
+    case HpackDecodingError::kDynamicTableSizeUpdateNotAllowed:
+      return "Dynamic table size update not allowed";
+    case HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark:
+      return "Initial dynamic table size update is above low water mark";
+    case HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting:
+      return "Dynamic table size update is above acknowledged setting";
+    case HpackDecodingError::kTruncatedBlock:
+      return "Block ends in the middle of an instruction";
+    case HpackDecodingError::kFragmentTooLong:
+      return "Incoming data fragment exceeds buffer limit";
+    case HpackDecodingError::kCompressedHeaderSizeExceedsLimit:
+      return "Total compressed HPACK data size exceeds limit";
+  }
+  return "invalid HpackDecodingError value";
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_decoding_error.h b/quiche/http2/hpack/decoder/hpack_decoding_error.h
new file mode 100644
index 0000000..e24eaf1
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_decoding_error.h
@@ -0,0 +1,51 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+enum class HpackDecodingError {
+  // No error detected so far.
+  kOk,
+  // Varint beyond implementation limit.
+  kIndexVarintError,
+  kNameLengthVarintError,
+  kValueLengthVarintError,
+  // String literal length exceeds buffer limit.
+  kNameTooLong,
+  kValueTooLong,
+  // Error in Huffman encoding.
+  kNameHuffmanError,
+  kValueHuffmanError,
+  // Next instruction should have been a dynamic table size update.
+  kMissingDynamicTableSizeUpdate,
+  // Invalid index in indexed header field representation.
+  kInvalidIndex,
+  // Invalid index in literal header field with indexed name representation.
+  kInvalidNameIndex,
+  // Dynamic table size update not allowed.
+  kDynamicTableSizeUpdateNotAllowed,
+  // Initial dynamic table size update is above low water mark.
+  kInitialDynamicTableSizeUpdateIsAboveLowWaterMark,
+  // Dynamic table size update is above acknowledged setting.
+  kDynamicTableSizeUpdateIsAboveAcknowledgedSetting,
+  // HPACK block ends in the middle of an instruction.
+  kTruncatedBlock,
+  // Incoming data fragment exceeds buffer limit.
+  kFragmentTooLong,
+  // Total compressed HPACK data size exceeds limit.
+  kCompressedHeaderSizeExceedsLimit,
+};
+
+QUICHE_EXPORT_PRIVATE absl::string_view HpackDecodingErrorToString(
+    HpackDecodingError error);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_DECODING_ERROR_H_
diff --git a/quiche/http2/hpack/decoder/hpack_entry_collector.cc b/quiche/http2/hpack/decoder/hpack_entry_collector.cc
new file mode 100644
index 0000000..853b99a
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_collector.cc
@@ -0,0 +1,301 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_entry_collector.h"
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/hpack/decoder/hpack_string_collector.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+
+namespace http2 {
+namespace test {
+namespace {
+
+const HpackEntryType kInvalidHeaderType = static_cast<HpackEntryType>(99);
+const size_t kInvalidIndex = 99999999;
+
+}  // namespace
+
+HpackEntryCollector::HpackEntryCollector() {
+  Clear();
+}
+
+HpackEntryCollector::HpackEntryCollector(const HpackEntryCollector& other) =
+    default;
+
+HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
+                                         size_t index_or_size)
+    : header_type_(type), index_(index_or_size), started_(true), ended_(true) {}
+HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
+                                         size_t index,
+                                         bool value_huffman,
+                                         const std::string& value)
+    : header_type_(type),
+      index_(index),
+      value_(value, value_huffman),
+      started_(true),
+      ended_(true) {}
+HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
+                                         bool name_huffman,
+                                         const std::string& name,
+                                         bool value_huffman,
+                                         const std::string& value)
+    : header_type_(type),
+      index_(0),
+      name_(name, name_huffman),
+      value_(value, value_huffman),
+      started_(true),
+      ended_(true) {}
+
+HpackEntryCollector::~HpackEntryCollector() = default;
+
+void HpackEntryCollector::OnIndexedHeader(size_t index) {
+  ASSERT_FALSE(started_);
+  ASSERT_TRUE(IsClear()) << ToString();
+  Init(HpackEntryType::kIndexedHeader, index);
+  ended_ = true;
+}
+void HpackEntryCollector::OnStartLiteralHeader(HpackEntryType header_type,
+                                               size_t maybe_name_index) {
+  ASSERT_FALSE(started_);
+  ASSERT_TRUE(IsClear()) << ToString();
+  Init(header_type, maybe_name_index);
+}
+void HpackEntryCollector::OnNameStart(bool huffman_encoded, size_t len) {
+  ASSERT_TRUE(started_);
+  ASSERT_FALSE(ended_);
+  ASSERT_FALSE(IsClear());
+  ASSERT_TRUE(LiteralNameExpected()) << ToString();
+  name_.OnStringStart(huffman_encoded, len);
+}
+void HpackEntryCollector::OnNameData(const char* data, size_t len) {
+  ASSERT_TRUE(started_);
+  ASSERT_FALSE(ended_);
+  ASSERT_TRUE(LiteralNameExpected()) << ToString();
+  ASSERT_TRUE(name_.IsInProgress());
+  name_.OnStringData(data, len);
+}
+void HpackEntryCollector::OnNameEnd() {
+  ASSERT_TRUE(started_);
+  ASSERT_FALSE(ended_);
+  ASSERT_TRUE(LiteralNameExpected()) << ToString();
+  ASSERT_TRUE(name_.IsInProgress());
+  name_.OnStringEnd();
+}
+void HpackEntryCollector::OnValueStart(bool huffman_encoded, size_t len) {
+  ASSERT_TRUE(started_);
+  ASSERT_FALSE(ended_);
+  if (LiteralNameExpected()) {
+    ASSERT_TRUE(name_.HasEnded());
+  }
+  ASSERT_TRUE(LiteralValueExpected()) << ToString();
+  ASSERT_TRUE(value_.IsClear()) << value_.ToString();
+  value_.OnStringStart(huffman_encoded, len);
+}
+void HpackEntryCollector::OnValueData(const char* data, size_t len) {
+  ASSERT_TRUE(started_);
+  ASSERT_FALSE(ended_);
+  ASSERT_TRUE(LiteralValueExpected()) << ToString();
+  ASSERT_TRUE(value_.IsInProgress());
+  value_.OnStringData(data, len);
+}
+void HpackEntryCollector::OnValueEnd() {
+  ASSERT_TRUE(started_);
+  ASSERT_FALSE(ended_);
+  ASSERT_TRUE(LiteralValueExpected()) << ToString();
+  ASSERT_TRUE(value_.IsInProgress());
+  value_.OnStringEnd();
+  ended_ = true;
+}
+void HpackEntryCollector::OnDynamicTableSizeUpdate(size_t size) {
+  ASSERT_FALSE(started_);
+  ASSERT_TRUE(IsClear()) << ToString();
+  Init(HpackEntryType::kDynamicTableSizeUpdate, size);
+  ended_ = true;
+}
+
+void HpackEntryCollector::Clear() {
+  header_type_ = kInvalidHeaderType;
+  index_ = kInvalidIndex;
+  name_.Clear();
+  value_.Clear();
+  started_ = ended_ = false;
+}
+bool HpackEntryCollector::IsClear() const {
+  return header_type_ == kInvalidHeaderType && index_ == kInvalidIndex &&
+         name_.IsClear() && value_.IsClear() && !started_ && !ended_;
+}
+bool HpackEntryCollector::IsComplete() const {
+  return started_ && ended_;
+}
+bool HpackEntryCollector::LiteralNameExpected() const {
+  switch (header_type_) {
+    case HpackEntryType::kIndexedLiteralHeader:
+    case HpackEntryType::kUnindexedLiteralHeader:
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      return index_ == 0;
+    default:
+      return false;
+  }
+}
+bool HpackEntryCollector::LiteralValueExpected() const {
+  switch (header_type_) {
+    case HpackEntryType::kIndexedLiteralHeader:
+    case HpackEntryType::kUnindexedLiteralHeader:
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      return true;
+    default:
+      return false;
+  }
+}
+AssertionResult HpackEntryCollector::ValidateIndexedHeader(
+    size_t expected_index) const {
+  VERIFY_TRUE(started_);
+  VERIFY_TRUE(ended_);
+  VERIFY_EQ(HpackEntryType::kIndexedHeader, header_type_);
+  VERIFY_EQ(expected_index, index_);
+  return ::testing::AssertionSuccess();
+}
+AssertionResult HpackEntryCollector::ValidateLiteralValueHeader(
+    HpackEntryType expected_type,
+    size_t expected_index,
+    bool expected_value_huffman,
+    absl::string_view expected_value) const {
+  VERIFY_TRUE(started_);
+  VERIFY_TRUE(ended_);
+  VERIFY_EQ(expected_type, header_type_);
+  VERIFY_NE(0u, expected_index);
+  VERIFY_EQ(expected_index, index_);
+  VERIFY_TRUE(name_.IsClear());
+  VERIFY_SUCCESS(value_.Collected(expected_value, expected_value_huffman));
+  return ::testing::AssertionSuccess();
+}
+AssertionResult HpackEntryCollector::ValidateLiteralNameValueHeader(
+    HpackEntryType expected_type,
+    bool expected_name_huffman,
+    absl::string_view expected_name,
+    bool expected_value_huffman,
+    absl::string_view expected_value) const {
+  VERIFY_TRUE(started_);
+  VERIFY_TRUE(ended_);
+  VERIFY_EQ(expected_type, header_type_);
+  VERIFY_EQ(0u, index_);
+  VERIFY_SUCCESS(name_.Collected(expected_name, expected_name_huffman));
+  VERIFY_SUCCESS(value_.Collected(expected_value, expected_value_huffman));
+  return ::testing::AssertionSuccess();
+}
+AssertionResult HpackEntryCollector::ValidateDynamicTableSizeUpdate(
+    size_t size) const {
+  VERIFY_TRUE(started_);
+  VERIFY_TRUE(ended_);
+  VERIFY_EQ(HpackEntryType::kDynamicTableSizeUpdate, header_type_);
+  VERIFY_EQ(index_, size);
+  return ::testing::AssertionSuccess();
+}
+
+void HpackEntryCollector::AppendToHpackBlockBuilder(
+    HpackBlockBuilder* hbb) const {
+  ASSERT_TRUE(started_ && ended_) << *this;
+  switch (header_type_) {
+    case HpackEntryType::kIndexedHeader:
+      hbb->AppendIndexedHeader(index_);
+      return;
+
+    case HpackEntryType::kDynamicTableSizeUpdate:
+      hbb->AppendDynamicTableSizeUpdate(index_);
+      return;
+
+    case HpackEntryType::kIndexedLiteralHeader:
+    case HpackEntryType::kUnindexedLiteralHeader:
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      ASSERT_TRUE(value_.HasEnded()) << *this;
+      if (index_ != 0) {
+        QUICHE_CHECK(name_.IsClear());
+        hbb->AppendNameIndexAndLiteralValue(header_type_, index_,
+                                            value_.huffman_encoded, value_.s);
+      } else {
+        QUICHE_CHECK(name_.HasEnded()) << *this;
+        hbb->AppendLiteralNameAndValue(header_type_, name_.huffman_encoded,
+                                       name_.s, value_.huffman_encoded,
+                                       value_.s);
+      }
+      return;
+
+    default:
+      ADD_FAILURE() << *this;
+  }
+}
+
+std::string HpackEntryCollector::ToString() const {
+  std::string result("Type=");
+  switch (header_type_) {
+    case HpackEntryType::kIndexedHeader:
+      result += "IndexedHeader";
+      break;
+    case HpackEntryType::kDynamicTableSizeUpdate:
+      result += "DynamicTableSizeUpdate";
+      break;
+    case HpackEntryType::kIndexedLiteralHeader:
+      result += "IndexedLiteralHeader";
+      break;
+    case HpackEntryType::kUnindexedLiteralHeader:
+      result += "UnindexedLiteralHeader";
+      break;
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      result += "NeverIndexedLiteralHeader";
+      break;
+    default:
+      if (header_type_ == kInvalidHeaderType) {
+        result += "<unset>";
+      } else {
+        absl::StrAppend(&result, header_type_);
+      }
+  }
+  if (index_ != 0) {
+    absl::StrAppend(&result, " Index=", index_);
+  }
+  if (!name_.IsClear()) {
+    absl::StrAppend(&result, " Name", name_.ToString());
+  }
+  if (!value_.IsClear()) {
+    absl::StrAppend(&result, " Value", value_.ToString());
+  }
+  if (!started_) {
+    EXPECT_FALSE(ended_);
+    absl::StrAppend(&result, " !started");
+  } else if (!ended_) {
+    absl::StrAppend(&result, " !ended");
+  } else {
+    absl::StrAppend(&result, " Complete");
+  }
+  return result;
+}
+
+void HpackEntryCollector::Init(HpackEntryType type, size_t maybe_index) {
+  ASSERT_TRUE(IsClear()) << ToString();
+  header_type_ = type;
+  index_ = maybe_index;
+  started_ = true;
+}
+
+bool operator==(const HpackEntryCollector& a, const HpackEntryCollector& b) {
+  return a.name() == b.name() && a.value() == b.value() &&
+         a.index() == b.index() && a.header_type() == b.header_type() &&
+         a.started() == b.started() && a.ended() == b.ended();
+}
+bool operator!=(const HpackEntryCollector& a, const HpackEntryCollector& b) {
+  return !(a == b);
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackEntryCollector& v) {
+  return out << v.ToString();
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_entry_collector.h b/quiche/http2/hpack/decoder/hpack_entry_collector.h
new file mode 100644
index 0000000..d4743fa
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_collector.h
@@ -0,0 +1,155 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_COLLECTOR_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_COLLECTOR_H_
+
+// HpackEntryCollector records calls to HpackEntryDecoderListener in support
+// of tests of HpackEntryDecoder, or which use it. Can only record the callbacks
+// for the decoding of a single entry; call Clear() between decoding successive
+// entries or use a distinct HpackEntryCollector for each entry.
+
+#include <stddef.h>
+
+#include <iosfwd>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_string_collector.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class HpackEntryCollector : public HpackEntryDecoderListener {
+ public:
+  HpackEntryCollector();
+  HpackEntryCollector(const HpackEntryCollector& other);
+
+  // These next three constructors are intended for use in tests that create
+  // an HpackEntryCollector "manually", and then compare it against another
+  // that is populated via calls to the HpackEntryDecoderListener methods.
+  HpackEntryCollector(HpackEntryType type, size_t index_or_size);
+  HpackEntryCollector(HpackEntryType type,
+                      size_t index,
+                      bool value_huffman,
+                      const std::string& value);
+  HpackEntryCollector(HpackEntryType type,
+                      bool name_huffman,
+                      const std::string& name,
+                      bool value_huffman,
+                      const std::string& value);
+
+  ~HpackEntryCollector() override;
+
+  // Methods defined by HpackEntryDecoderListener.
+  void OnIndexedHeader(size_t index) override;
+  void OnStartLiteralHeader(HpackEntryType header_type,
+                            size_t maybe_name_index) override;
+  void OnNameStart(bool huffman_encoded, size_t len) override;
+  void OnNameData(const char* data, size_t len) override;
+  void OnNameEnd() override;
+  void OnValueStart(bool huffman_encoded, size_t len) override;
+  void OnValueData(const char* data, size_t len) override;
+  void OnValueEnd() override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+
+  // Clears the fields of the collector so that it is ready to start collecting
+  // another HPACK block entry.
+  void Clear();
+
+  // Is the collector ready to start collecting another HPACK block entry.
+  bool IsClear() const;
+
+  // Has a complete entry been collected?
+  bool IsComplete() const;
+
+  // Based on the HpackEntryType, is a literal name expected?
+  bool LiteralNameExpected() const;
+
+  // Based on the HpackEntryType, is a literal value expected?
+  bool LiteralValueExpected() const;
+
+  // Returns success if collected an Indexed Header (i.e. OnIndexedHeader was
+  // called).
+  ::testing::AssertionResult ValidateIndexedHeader(size_t expected_index) const;
+
+  // Returns success if collected a Header with an indexed name and literal
+  // value (i.e. OnStartLiteralHeader was called with a non-zero index for
+  // the name, which must match expected_index).
+  ::testing::AssertionResult ValidateLiteralValueHeader(
+      HpackEntryType expected_type,
+      size_t expected_index,
+      bool expected_value_huffman,
+      absl::string_view expected_value) const;
+
+  // Returns success if collected a Header with an literal name and literal
+  // value.
+  ::testing::AssertionResult ValidateLiteralNameValueHeader(
+      HpackEntryType expected_type,
+      bool expected_name_huffman,
+      absl::string_view expected_name,
+      bool expected_value_huffman,
+      absl::string_view expected_value) const;
+
+  // Returns success if collected a Dynamic Table Size Update,
+  // with the specified size.
+  ::testing::AssertionResult ValidateDynamicTableSizeUpdate(
+      size_t expected_size) const;
+
+  void set_header_type(HpackEntryType v) { header_type_ = v; }
+  HpackEntryType header_type() const { return header_type_; }
+
+  void set_index(size_t v) { index_ = v; }
+  size_t index() const { return index_; }
+
+  void set_name(const HpackStringCollector& v) { name_ = v; }
+  const HpackStringCollector& name() const { return name_; }
+
+  void set_value(const HpackStringCollector& v) { value_ = v; }
+  const HpackStringCollector& value() const { return value_; }
+
+  void set_started(bool v) { started_ = v; }
+  bool started() const { return started_; }
+
+  void set_ended(bool v) { ended_ = v; }
+  bool ended() const { return ended_; }
+
+  void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const;
+
+  // Returns a debug string.
+  std::string ToString() const;
+
+ private:
+  void Init(HpackEntryType type, size_t maybe_index);
+
+  HpackEntryType header_type_;
+  size_t index_;
+
+  HpackStringCollector name_;
+  HpackStringCollector value_;
+
+  // True if has received a call to an HpackEntryDecoderListener method
+  // indicating the start of decoding an HPACK entry; for example,
+  // OnIndexedHeader set it true, but OnNameStart does not change it.
+  bool started_ = false;
+
+  // True if has received a call to an HpackEntryDecoderListener method
+  // indicating the end of decoding an HPACK entry; for example,
+  // OnIndexedHeader and OnValueEnd both set it true, but OnNameEnd does
+  // not change it.
+  bool ended_ = false;
+};
+
+bool operator==(const HpackEntryCollector& a, const HpackEntryCollector& b);
+bool operator!=(const HpackEntryCollector& a, const HpackEntryCollector& b);
+std::ostream& operator<<(std::ostream& out, const HpackEntryCollector& v);
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_COLLECTOR_H_
diff --git a/quiche/http2/hpack/decoder/hpack_entry_decoder.cc b/quiche/http2/hpack/decoder/hpack_entry_decoder.cc
new file mode 100644
index 0000000..c81e298
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_decoder.cc
@@ -0,0 +1,295 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder.h"
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+namespace {
+// Converts calls from HpackStringDecoder when decoding a header name into the
+// appropriate HpackEntryDecoderListener::OnName* calls.
+class NameDecoderListener {
+ public:
+  explicit NameDecoderListener(HpackEntryDecoderListener* listener)
+      : listener_(listener) {}
+  bool OnStringStart(bool huffman_encoded, size_t len) {
+    listener_->OnNameStart(huffman_encoded, len);
+    return true;
+  }
+  void OnStringData(const char* data, size_t len) {
+    listener_->OnNameData(data, len);
+  }
+  void OnStringEnd() { listener_->OnNameEnd(); }
+
+ private:
+  HpackEntryDecoderListener* listener_;
+};
+
+// Converts calls from HpackStringDecoder when decoding a header value into
+// the appropriate HpackEntryDecoderListener::OnValue* calls.
+class ValueDecoderListener {
+ public:
+  explicit ValueDecoderListener(HpackEntryDecoderListener* listener)
+      : listener_(listener) {}
+  bool OnStringStart(bool huffman_encoded, size_t len) {
+    listener_->OnValueStart(huffman_encoded, len);
+    return true;
+  }
+  void OnStringData(const char* data, size_t len) {
+    listener_->OnValueData(data, len);
+  }
+  void OnStringEnd() { listener_->OnValueEnd(); }
+
+ private:
+  HpackEntryDecoderListener* listener_;
+};
+}  // namespace
+
+DecodeStatus HpackEntryDecoder::Start(DecodeBuffer* db,
+                                      HpackEntryDecoderListener* listener) {
+  QUICHE_DCHECK(db != nullptr);
+  QUICHE_DCHECK(listener != nullptr);
+  QUICHE_DCHECK(db->HasData());
+  DecodeStatus status = entry_type_decoder_.Start(db);
+  switch (status) {
+    case DecodeStatus::kDecodeDone:
+      // The type of the entry and its varint fit into the current decode
+      // buffer.
+      if (entry_type_decoder_.entry_type() == HpackEntryType::kIndexedHeader) {
+        // The entry consists solely of the entry type and varint.
+        // This is by far the most common case in practice.
+        listener->OnIndexedHeader(entry_type_decoder_.varint());
+        return DecodeStatus::kDecodeDone;
+      }
+      state_ = EntryDecoderState::kDecodedType;
+      return Resume(db, listener);
+    case DecodeStatus::kDecodeInProgress:
+      // Hit the end of the decode buffer before fully decoding
+      // the entry type and varint.
+      QUICHE_DCHECK_EQ(0u, db->Remaining());
+      state_ = EntryDecoderState::kResumeDecodingType;
+      return status;
+    case DecodeStatus::kDecodeError:
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 11, 23);
+      error_ = HpackDecodingError::kIndexVarintError;
+      // The varint must have been invalid (too long).
+      return status;
+  }
+
+  HTTP2_BUG(http2_bug_63_1) << "Unreachable";
+  return DecodeStatus::kDecodeError;
+}
+
+DecodeStatus HpackEntryDecoder::Resume(DecodeBuffer* db,
+                                       HpackEntryDecoderListener* listener) {
+  QUICHE_DCHECK(db != nullptr);
+  QUICHE_DCHECK(listener != nullptr);
+
+  DecodeStatus status;
+
+  do {
+    switch (state_) {
+      case EntryDecoderState::kResumeDecodingType:
+        // entry_type_decoder_ returned kDecodeInProgress when last called.
+        HTTP2_DVLOG(1) << "kResumeDecodingType: db->Remaining="
+                       << db->Remaining();
+        status = entry_type_decoder_.Resume(db);
+        if (status == DecodeStatus::kDecodeError) {
+          HTTP2_CODE_COUNT_N(decompress_failure_3, 12, 23);
+          error_ = HpackDecodingError::kIndexVarintError;
+        }
+        if (status != DecodeStatus::kDecodeDone) {
+          return status;
+        }
+        state_ = EntryDecoderState::kDecodedType;
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case EntryDecoderState::kDecodedType:
+        // entry_type_decoder_ returned kDecodeDone, now need to decide how
+        // to proceed.
+        HTTP2_DVLOG(1) << "kDecodedType: db->Remaining=" << db->Remaining();
+        if (DispatchOnType(listener)) {
+          // All done.
+          return DecodeStatus::kDecodeDone;
+        }
+        continue;
+
+      case EntryDecoderState::kStartDecodingName:
+        HTTP2_DVLOG(1) << "kStartDecodingName: db->Remaining="
+                       << db->Remaining();
+        {
+          NameDecoderListener ncb(listener);
+          status = string_decoder_.Start(db, &ncb);
+        }
+        if (status != DecodeStatus::kDecodeDone) {
+          // On the assumption that the status is kDecodeInProgress, set
+          // state_ accordingly; unnecessary if status is kDecodeError, but
+          // that will only happen if the varint encoding the name's length
+          // is too long.
+          state_ = EntryDecoderState::kResumeDecodingName;
+          if (status == DecodeStatus::kDecodeError) {
+            HTTP2_CODE_COUNT_N(decompress_failure_3, 13, 23);
+            error_ = HpackDecodingError::kNameLengthVarintError;
+          }
+          return status;
+        }
+        state_ = EntryDecoderState::kStartDecodingValue;
+        ABSL_FALLTHROUGH_INTENDED;
+
+      case EntryDecoderState::kStartDecodingValue:
+        HTTP2_DVLOG(1) << "kStartDecodingValue: db->Remaining="
+                       << db->Remaining();
+        {
+          ValueDecoderListener vcb(listener);
+          status = string_decoder_.Start(db, &vcb);
+        }
+        if (status == DecodeStatus::kDecodeError) {
+          HTTP2_CODE_COUNT_N(decompress_failure_3, 14, 23);
+          error_ = HpackDecodingError::kValueLengthVarintError;
+        }
+        if (status == DecodeStatus::kDecodeDone) {
+          // Done with decoding the literal value, so we've reached the
+          // end of the header entry.
+          return status;
+        }
+        // On the assumption that the status is kDecodeInProgress, set
+        // state_ accordingly; unnecessary if status is kDecodeError, but
+        // that will only happen if the varint encoding the value's length
+        // is too long.
+        state_ = EntryDecoderState::kResumeDecodingValue;
+        return status;
+
+      case EntryDecoderState::kResumeDecodingName:
+        // The literal name was split across decode buffers.
+        HTTP2_DVLOG(1) << "kResumeDecodingName: db->Remaining="
+                       << db->Remaining();
+        {
+          NameDecoderListener ncb(listener);
+          status = string_decoder_.Resume(db, &ncb);
+        }
+        if (status != DecodeStatus::kDecodeDone) {
+          // On the assumption that the status is kDecodeInProgress, set
+          // state_ accordingly; unnecessary if status is kDecodeError, but
+          // that will only happen if the varint encoding the name's length
+          // is too long.
+          state_ = EntryDecoderState::kResumeDecodingName;
+          if (status == DecodeStatus::kDecodeError) {
+            HTTP2_CODE_COUNT_N(decompress_failure_3, 15, 23);
+            error_ = HpackDecodingError::kNameLengthVarintError;
+          }
+          return status;
+        }
+        state_ = EntryDecoderState::kStartDecodingValue;
+        break;
+
+      case EntryDecoderState::kResumeDecodingValue:
+        // The literal value was split across decode buffers.
+        HTTP2_DVLOG(1) << "kResumeDecodingValue: db->Remaining="
+                       << db->Remaining();
+        {
+          ValueDecoderListener vcb(listener);
+          status = string_decoder_.Resume(db, &vcb);
+        }
+        if (status == DecodeStatus::kDecodeError) {
+          HTTP2_CODE_COUNT_N(decompress_failure_3, 16, 23);
+          error_ = HpackDecodingError::kValueLengthVarintError;
+        }
+        if (status == DecodeStatus::kDecodeDone) {
+          // Done with decoding the value, therefore the entry as a whole.
+          return status;
+        }
+        // On the assumption that the status is kDecodeInProgress, set
+        // state_ accordingly; unnecessary if status is kDecodeError, but
+        // that will only happen if the varint encoding the value's length
+        // is too long.
+        state_ = EntryDecoderState::kResumeDecodingValue;
+        return status;
+    }
+  } while (true);
+}
+
+bool HpackEntryDecoder::DispatchOnType(HpackEntryDecoderListener* listener) {
+  const HpackEntryType entry_type = entry_type_decoder_.entry_type();
+  const uint32_t varint = static_cast<uint32_t>(entry_type_decoder_.varint());
+  switch (entry_type) {
+    case HpackEntryType::kIndexedHeader:
+      // The entry consists solely of the entry type and varint. See:
+      // http://httpwg.org/specs/rfc7541.html#indexed.header.representation
+      listener->OnIndexedHeader(varint);
+      return true;
+
+    case HpackEntryType::kIndexedLiteralHeader:
+    case HpackEntryType::kUnindexedLiteralHeader:
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      // The entry has a literal value, and if the varint is zero also has a
+      // literal name preceding the value. See:
+      // http://httpwg.org/specs/rfc7541.html#literal.header.representation
+      listener->OnStartLiteralHeader(entry_type, varint);
+      if (varint == 0) {
+        state_ = EntryDecoderState::kStartDecodingName;
+      } else {
+        state_ = EntryDecoderState::kStartDecodingValue;
+      }
+      return false;
+
+    case HpackEntryType::kDynamicTableSizeUpdate:
+      // The entry consists solely of the entry type and varint. FWIW, I've
+      // never seen this type of entry in production (primarily browser
+      // traffic) so if you're designing an HPACK successor someday, consider
+      // dropping it or giving it a much longer prefix. See:
+      // http://httpwg.org/specs/rfc7541.html#encoding.context.update
+      listener->OnDynamicTableSizeUpdate(varint);
+      return true;
+  }
+
+  HTTP2_BUG(http2_bug_63_2) << "Unreachable, entry_type=" << entry_type;
+  return true;
+}
+
+void HpackEntryDecoder::OutputDebugString(std::ostream& out) const {
+  out << "HpackEntryDecoder(state=" << state_ << ", " << entry_type_decoder_
+      << ", " << string_decoder_ << ")";
+}
+
+std::string HpackEntryDecoder::DebugString() const {
+  std::stringstream s;
+  s << *this;
+  return s.str();
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackEntryDecoder& v) {
+  v.OutputDebugString(out);
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         HpackEntryDecoder::EntryDecoderState state) {
+  typedef HpackEntryDecoder::EntryDecoderState EntryDecoderState;
+  switch (state) {
+    case EntryDecoderState::kResumeDecodingType:
+      return out << "kResumeDecodingType";
+    case EntryDecoderState::kDecodedType:
+      return out << "kDecodedType";
+    case EntryDecoderState::kStartDecodingName:
+      return out << "kStartDecodingName";
+    case EntryDecoderState::kResumeDecodingName:
+      return out << "kResumeDecodingName";
+    case EntryDecoderState::kStartDecodingValue:
+      return out << "kStartDecodingValue";
+    case EntryDecoderState::kResumeDecodingValue:
+      return out << "kResumeDecodingValue";
+  }
+  return out << static_cast<int>(state);
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_entry_decoder.h b/quiche/http2/hpack/decoder/hpack_entry_decoder.h
new file mode 100644
index 0000000..50ddd98
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_decoder.h
@@ -0,0 +1,91 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
+
+// HpackEntryDecoder decodes a single HPACK entry (i.e. one header or one
+// dynamic table size update), in a resumable fashion. The first call, Start(),
+// must provide a non-empty decode buffer. Continue with calls to Resume() if
+// Start, and any subsequent calls to Resume, returns kDecodeInProgress.
+
+#include <string>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_type_decoder.h"
+#include "quiche/http2/hpack/decoder/hpack_string_decoder.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackEntryDecoder {
+ public:
+  enum class EntryDecoderState {
+    // Have started decoding the type/varint, but didn't finish on the previous
+    // attempt.  Next state is kResumeDecodingType or kDecodedType.
+    kResumeDecodingType,
+
+    // Have just finished decoding the type/varint. Final state if the type is
+    // kIndexedHeader or kDynamicTableSizeUpdate. Otherwise, the next state is
+    // kStartDecodingName (if the varint is 0), else kStartDecodingValue.
+    kDecodedType,
+
+    // Ready to start decoding the literal name of a header entry. Next state
+    // is kResumeDecodingName (if the name is split across decode buffers),
+    // else kStartDecodingValue.
+    kStartDecodingName,
+
+    // Resume decoding the literal name of a header that is split across decode
+    // buffers.
+    kResumeDecodingName,
+
+    // Ready to start decoding the literal value of a header entry. Final state
+    // if the value string is entirely in the decode buffer, else the next state
+    // is kResumeDecodingValue.
+    kStartDecodingValue,
+
+    // Resume decoding the literal value of a header that is split across decode
+    // buffers.
+    kResumeDecodingValue,
+  };
+
+  // Only call when the decode buffer has data (i.e. HpackBlockDecoder must
+  // not call until there is data).
+  DecodeStatus Start(DecodeBuffer* db, HpackEntryDecoderListener* listener);
+
+  // Only call Resume if the previous call (Start or Resume) returned
+  // kDecodeInProgress; Resume is also called from Start when it has succeeded
+  // in decoding the entry type and its varint.
+  DecodeStatus Resume(DecodeBuffer* db, HpackEntryDecoderListener* listener);
+
+  // Return error code after decoding error occurred.
+  HpackDecodingError error() const { return error_; }
+
+  std::string DebugString() const;
+  void OutputDebugString(std::ostream& out) const;
+
+ private:
+  // Implements handling state kDecodedType.
+  bool DispatchOnType(HpackEntryDecoderListener* listener);
+
+  HpackEntryTypeDecoder entry_type_decoder_;
+  HpackStringDecoder string_decoder_;
+  EntryDecoderState state_ = EntryDecoderState();
+  HpackDecodingError error_ = HpackDecodingError::kOk;
+};
+
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const HpackEntryDecoder& v);
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& out,
+    HpackEntryDecoder::EntryDecoderState state);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.cc b/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.cc
new file mode 100644
index 0000000..c7fe4b4
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.cc
@@ -0,0 +1,81 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
+
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+void HpackEntryDecoderVLoggingListener::OnIndexedHeader(size_t index) {
+  HTTP2_VLOG(1) << "OnIndexedHeader, index=" << index;
+  if (wrapped_) {
+    wrapped_->OnIndexedHeader(index);
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnStartLiteralHeader(
+    HpackEntryType entry_type,
+    size_t maybe_name_index) {
+  HTTP2_VLOG(1) << "OnStartLiteralHeader: entry_type=" << entry_type
+                << ", maybe_name_index=" << maybe_name_index;
+  if (wrapped_) {
+    wrapped_->OnStartLiteralHeader(entry_type, maybe_name_index);
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnNameStart(bool huffman_encoded,
+                                                    size_t len) {
+  HTTP2_VLOG(1) << "OnNameStart: H=" << huffman_encoded << ", len=" << len;
+  if (wrapped_) {
+    wrapped_->OnNameStart(huffman_encoded, len);
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnNameData(const char* data,
+                                                   size_t len) {
+  HTTP2_VLOG(1) << "OnNameData: len=" << len;
+  if (wrapped_) {
+    wrapped_->OnNameData(data, len);
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnNameEnd() {
+  HTTP2_VLOG(1) << "OnNameEnd";
+  if (wrapped_) {
+    wrapped_->OnNameEnd();
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnValueStart(bool huffman_encoded,
+                                                     size_t len) {
+  HTTP2_VLOG(1) << "OnValueStart: H=" << huffman_encoded << ", len=" << len;
+  if (wrapped_) {
+    wrapped_->OnValueStart(huffman_encoded, len);
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnValueData(const char* data,
+                                                    size_t len) {
+  HTTP2_VLOG(1) << "OnValueData: len=" << len;
+  if (wrapped_) {
+    wrapped_->OnValueData(data, len);
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnValueEnd() {
+  HTTP2_VLOG(1) << "OnValueEnd";
+  if (wrapped_) {
+    wrapped_->OnValueEnd();
+  }
+}
+
+void HpackEntryDecoderVLoggingListener::OnDynamicTableSizeUpdate(size_t size) {
+  HTTP2_VLOG(1) << "OnDynamicTableSizeUpdate: size=" << size;
+  if (wrapped_) {
+    wrapped_->OnDynamicTableSizeUpdate(size);
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h b/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h
new file mode 100644
index 0000000..1ba9339
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h
@@ -0,0 +1,110 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_LISTENER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_LISTENER_H_
+
+// Defines HpackEntryDecoderListener, the base class of listeners that
+// HpackEntryDecoder calls. Also defines HpackEntryDecoderVLoggingListener
+// which logs before calling another HpackEntryDecoderListener implementation.
+
+#include <stddef.h>
+
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackEntryDecoderListener {
+ public:
+  virtual ~HpackEntryDecoderListener() {}
+
+  // Called when an indexed header (i.e. one in the static or dynamic table) has
+  // been decoded from an HPACK block. index is supposed to be non-zero, but
+  // that has not been checked by the caller.
+  virtual void OnIndexedHeader(size_t index) = 0;
+
+  // Called when the start of a header with a literal value, and maybe a literal
+  // name, has been decoded. maybe_name_index is zero if the header has a
+  // literal name, else it is a reference into the static or dynamic table, from
+  // which the name should be determined. When the name is literal, the next
+  // call will be to OnNameStart; else it will be to OnValueStart. entry_type
+  // indicates whether the peer has added the entry to its dynamic table, and
+  // whether a proxy is permitted to do so when forwarding the entry.
+  virtual void OnStartLiteralHeader(HpackEntryType entry_type,
+                                    size_t maybe_name_index) = 0;
+
+  // Called when the encoding (Huffman compressed or plain text) and the encoded
+  // length of a literal name has been decoded. OnNameData will be called next,
+  // and repeatedly until the sum of lengths passed to OnNameData is len.
+  virtual void OnNameStart(bool huffman_encoded, size_t len) = 0;
+
+  // Called when len bytes of an encoded header name have been decoded.
+  virtual void OnNameData(const char* data, size_t len) = 0;
+
+  // Called after the entire name has been passed to OnNameData.
+  // OnValueStart will be called next.
+  virtual void OnNameEnd() = 0;
+
+  // Called when the encoding (Huffman compressed or plain text) and the encoded
+  // length of a literal value has been decoded. OnValueData will be called
+  // next, and repeatedly until the sum of lengths passed to OnValueData is len.
+  virtual void OnValueStart(bool huffman_encoded, size_t len) = 0;
+
+  // Called when len bytes of an encoded header value have been decoded.
+  virtual void OnValueData(const char* data, size_t len) = 0;
+
+  // Called after the entire value has been passed to OnValueData, marking the
+  // end of a header entry with a literal value, and maybe a literal name.
+  virtual void OnValueEnd() = 0;
+
+  // Called when an update to the size of the peer's dynamic table has been
+  // decoded.
+  virtual void OnDynamicTableSizeUpdate(size_t size) = 0;
+};
+
+class QUICHE_EXPORT_PRIVATE HpackEntryDecoderVLoggingListener
+    : public HpackEntryDecoderListener {
+ public:
+  HpackEntryDecoderVLoggingListener() : wrapped_(nullptr) {}
+  explicit HpackEntryDecoderVLoggingListener(HpackEntryDecoderListener* wrapped)
+      : wrapped_(wrapped) {}
+  ~HpackEntryDecoderVLoggingListener() override {}
+
+  void OnIndexedHeader(size_t index) override;
+  void OnStartLiteralHeader(HpackEntryType entry_type,
+                            size_t maybe_name_index) override;
+  void OnNameStart(bool huffman_encoded, size_t len) override;
+  void OnNameData(const char* data, size_t len) override;
+  void OnNameEnd() override;
+  void OnValueStart(bool huffman_encoded, size_t len) override;
+  void OnValueData(const char* data, size_t len) override;
+  void OnValueEnd() override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+
+ private:
+  HpackEntryDecoderListener* const wrapped_;
+};
+
+// A no-op implementation of HpackEntryDecoderListener.
+class QUICHE_EXPORT_PRIVATE HpackEntryDecoderNoOpListener
+    : public HpackEntryDecoderListener {
+ public:
+  ~HpackEntryDecoderNoOpListener() override {}
+
+  void OnIndexedHeader(size_t /*index*/) override {}
+  void OnStartLiteralHeader(HpackEntryType /*entry_type*/,
+                            size_t /*maybe_name_index*/) override {}
+  void OnNameStart(bool /*huffman_encoded*/, size_t /*len*/) override {}
+  void OnNameData(const char* /*data*/, size_t /*len*/) override {}
+  void OnNameEnd() override {}
+  void OnValueStart(bool /*huffman_encoded*/, size_t /*len*/) override {}
+  void OnValueData(const char* /*data*/, size_t /*len*/) override {}
+  void OnValueEnd() override {}
+  void OnDynamicTableSizeUpdate(size_t /*size*/) override {}
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_DECODER_LISTENER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_entry_decoder_test.cc b/quiche/http2/hpack/decoder/hpack_entry_decoder_test.cc
new file mode 100644
index 0000000..a748d73
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_decoder_test.cc
@@ -0,0 +1,208 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder.h"
+
+// Tests of HpackEntryDecoder.
+
+#include <cstdint>
+
+#include "quiche/http2/hpack/decoder/hpack_entry_collector.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+class HpackEntryDecoderTest : public RandomDecoderTest {
+ protected:
+  HpackEntryDecoderTest() : listener_(&collector_) {}
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    collector_.Clear();
+    return decoder_.Start(b, &listener_);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    return decoder_.Resume(b, &listener_);
+  }
+
+  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* db,
+                                               const Validator& validator) {
+    // StartDecoding, above, requires the DecodeBuffer be non-empty so that it
+    // can call Start with the prefix byte.
+    bool return_non_zero_on_first = true;
+    return RandomDecoderTest::DecodeAndValidateSeveralWays(
+        db, return_non_zero_on_first, validator);
+  }
+
+  AssertionResult DecodeAndValidateSeveralWays(const HpackBlockBuilder& hbb,
+                                               const Validator& validator) {
+    DecodeBuffer db(hbb.buffer());
+    return DecodeAndValidateSeveralWays(&db, validator);
+  }
+
+  HpackEntryDecoder decoder_;
+  HpackEntryCollector collector_;
+  HpackEntryDecoderVLoggingListener listener_;
+};
+
+TEST_F(HpackEntryDecoderTest, IndexedHeader_Literals) {
+  {
+    const char input[] = {'\x82'};  // == Index 2 ==
+    DecodeBuffer b(input);
+    auto do_check = [this]() {
+      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(2));
+    };
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
+    EXPECT_TRUE(do_check());
+  }
+  collector_.Clear();
+  {
+    const char input[] = {'\xfe'};  // == Index 126 ==
+    DecodeBuffer b(input);
+    auto do_check = [this]() {
+      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(126));
+    };
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
+    EXPECT_TRUE(do_check());
+  }
+  collector_.Clear();
+  {
+    const char input[] = {'\xff', '\x00'};  // == Index 127 ==
+    DecodeBuffer b(input);
+    auto do_check = [this]() {
+      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(127));
+    };
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
+    EXPECT_TRUE(do_check());
+  }
+}
+
+TEST_F(HpackEntryDecoderTest, IndexedHeader_Various) {
+  // Indices chosen to hit encoding and table boundaries.
+  for (const uint32_t ndx : {1, 2, 61, 62, 63, 126, 127, 254, 255, 256}) {
+    HpackBlockBuilder hbb;
+    hbb.AppendIndexedHeader(ndx);
+
+    auto do_check = [this, ndx]() {
+      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateIndexedHeader(ndx));
+    };
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
+    EXPECT_TRUE(do_check());
+  }
+}
+
+TEST_F(HpackEntryDecoderTest, IndexedLiteralValue_Literal) {
+  const char input[] =
+      "\x7f"            // == Literal indexed, name index 0x40 ==
+      "\x01"            // 2nd byte of name index (0x01 + 0x3f == 0x40)
+      "\x0d"            // Value length (13)
+      "custom-header";  // Value
+  DecodeBuffer b(input, sizeof input - 1);
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralValueHeader(
+        HpackEntryType::kIndexedLiteralHeader, 0x40, false, "custom-header"));
+  };
+  EXPECT_TRUE(DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+TEST_F(HpackEntryDecoderTest, IndexedLiteralNameValue_Literal) {
+  const char input[] =
+      "\x40"            // == Literal indexed ==
+      "\x0a"            // Name length (10)
+      "custom-key"      // Name
+      "\x0d"            // Value length (13)
+      "custom-header";  // Value
+
+  DecodeBuffer b(input, sizeof input - 1);
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralNameValueHeader(
+        HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false,
+        "custom-header"));
+  };
+  EXPECT_TRUE(DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+TEST_F(HpackEntryDecoderTest, DynamicTableSizeUpdate_Literal) {
+  // Size update, length 31.
+  const char input[] = "\x3f\x00";
+  DecodeBuffer b(input, 2);
+  auto do_check = [this]() {
+    VERIFY_AND_RETURN_SUCCESS(collector_.ValidateDynamicTableSizeUpdate(31));
+  };
+  EXPECT_TRUE(DecodeAndValidateSeveralWays(&b, ValidateDoneAndEmpty(do_check)));
+  EXPECT_TRUE(do_check());
+}
+
+class HpackLiteralEntryDecoderTest
+    : public HpackEntryDecoderTest,
+      public ::testing::WithParamInterface<HpackEntryType> {
+ protected:
+  HpackLiteralEntryDecoderTest() : entry_type_(GetParam()) {}
+
+  const HpackEntryType entry_type_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    AllLiteralTypes, HpackLiteralEntryDecoderTest,
+    testing::Values(HpackEntryType::kIndexedLiteralHeader,
+                    HpackEntryType::kUnindexedLiteralHeader,
+                    HpackEntryType::kNeverIndexedLiteralHeader));
+
+TEST_P(HpackLiteralEntryDecoderTest, RandNameIndexAndLiteralValue) {
+  for (int n = 0; n < 10; n++) {
+    const uint32_t ndx = 1 + Random().Rand8();
+    const bool value_is_huffman_encoded = (n % 2) == 0;
+    const std::string value = Random().RandString(Random().Rand8());
+    HpackBlockBuilder hbb;
+    hbb.AppendNameIndexAndLiteralValue(entry_type_, ndx,
+                                       value_is_huffman_encoded, value);
+    auto do_check = [this, ndx, value_is_huffman_encoded,
+                     value]() -> AssertionResult {
+      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralValueHeader(
+          entry_type_, ndx, value_is_huffman_encoded, value));
+    };
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
+    EXPECT_TRUE(do_check());
+  }
+}
+
+TEST_P(HpackLiteralEntryDecoderTest, RandLiteralNameAndValue) {
+  for (int n = 0; n < 10; n++) {
+    const bool name_is_huffman_encoded = (n & 1) == 0;
+    const int name_len = 1 + Random().Rand8();
+    const std::string name = Random().RandString(name_len);
+    const bool value_is_huffman_encoded = (n & 2) == 0;
+    const int value_len = Random().Skewed(10);
+    const std::string value = Random().RandString(value_len);
+    HpackBlockBuilder hbb;
+    hbb.AppendLiteralNameAndValue(entry_type_, name_is_huffman_encoded, name,
+                                  value_is_huffman_encoded, value);
+    auto do_check = [this, name_is_huffman_encoded, name,
+                     value_is_huffman_encoded, value]() -> AssertionResult {
+      VERIFY_AND_RETURN_SUCCESS(collector_.ValidateLiteralNameValueHeader(
+          entry_type_, name_is_huffman_encoded, name, value_is_huffman_encoded,
+          value));
+    };
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
+    EXPECT_TRUE(do_check());
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_entry_type_decoder.cc b/quiche/http2/hpack/decoder/hpack_entry_type_decoder.cc
new file mode 100644
index 0000000..2bf6d8d
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_type_decoder.cc
@@ -0,0 +1,362 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_entry_type_decoder.h"
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::string HpackEntryTypeDecoder::DebugString() const {
+  return absl::StrCat(
+      "HpackEntryTypeDecoder(varint_decoder=", varint_decoder_.DebugString(),
+      ", entry_type=", entry_type_, ")");
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackEntryTypeDecoder& v) {
+  return out << v.DebugString();
+}
+
+// This ridiculous looking function turned out to be the winner in benchmarking
+// of several very different alternative implementations. It would be even
+// faster (~7%) if inlined in the header file, but I'm not sure if that is
+// worth doing... yet.
+// TODO(jamessynge): Benchmark again at a higher level (e.g. at least at the
+// full HTTP/2 decoder level, but preferably still higher) to determine if the
+// alternatives that take less code/data space are preferable in that situation.
+DecodeStatus HpackEntryTypeDecoder::Start(DecodeBuffer* db) {
+  QUICHE_DCHECK(db != nullptr);
+  QUICHE_DCHECK(db->HasData());
+
+  // The high four bits (nibble) of first byte of the entry determine the type
+  // of the entry, and may also be the initial bits of the varint that
+  // represents an index or table size. Note the use of the word 'initial'
+  // rather than 'high'; the HPACK encoding of varints is not in network
+  // order (i.e. not big-endian, the high-order byte isn't first), nor in
+  // little-endian order. See:
+  // http://httpwg.org/specs/rfc7541.html#integer.representation
+  uint8_t byte = db->DecodeUInt8();
+  switch (byte) {
+    case 0b00000000:
+    case 0b00000001:
+    case 0b00000010:
+    case 0b00000011:
+    case 0b00000100:
+    case 0b00000101:
+    case 0b00000110:
+    case 0b00000111:
+    case 0b00001000:
+    case 0b00001001:
+    case 0b00001010:
+    case 0b00001011:
+    case 0b00001100:
+    case 0b00001101:
+    case 0b00001110:
+      // The low 4 bits of |byte| are the initial bits of the varint.
+      // One of those bits is 0, so the varint is only one byte long.
+      entry_type_ = HpackEntryType::kUnindexedLiteralHeader;
+      varint_decoder_.set_value(byte);
+      return DecodeStatus::kDecodeDone;
+
+    case 0b00001111:
+      // The low 4 bits of |byte| are the initial bits of the varint. All 4
+      // are 1, so the varint extends into another byte.
+      entry_type_ = HpackEntryType::kUnindexedLiteralHeader;
+      return varint_decoder_.StartExtended(4, db);
+
+    case 0b00010000:
+    case 0b00010001:
+    case 0b00010010:
+    case 0b00010011:
+    case 0b00010100:
+    case 0b00010101:
+    case 0b00010110:
+    case 0b00010111:
+    case 0b00011000:
+    case 0b00011001:
+    case 0b00011010:
+    case 0b00011011:
+    case 0b00011100:
+    case 0b00011101:
+    case 0b00011110:
+      // The low 4 bits of |byte| are the initial bits of the varint.
+      // One of those bits is 0, so the varint is only one byte long.
+      entry_type_ = HpackEntryType::kNeverIndexedLiteralHeader;
+      varint_decoder_.set_value(byte & 0x0f);
+      return DecodeStatus::kDecodeDone;
+
+    case 0b00011111:
+      // The low 4 bits of |byte| are the initial bits of the varint.
+      // All of those bits are 1, so the varint extends into another byte.
+      entry_type_ = HpackEntryType::kNeverIndexedLiteralHeader;
+      return varint_decoder_.StartExtended(4, db);
+
+    case 0b00100000:
+    case 0b00100001:
+    case 0b00100010:
+    case 0b00100011:
+    case 0b00100100:
+    case 0b00100101:
+    case 0b00100110:
+    case 0b00100111:
+    case 0b00101000:
+    case 0b00101001:
+    case 0b00101010:
+    case 0b00101011:
+    case 0b00101100:
+    case 0b00101101:
+    case 0b00101110:
+    case 0b00101111:
+    case 0b00110000:
+    case 0b00110001:
+    case 0b00110010:
+    case 0b00110011:
+    case 0b00110100:
+    case 0b00110101:
+    case 0b00110110:
+    case 0b00110111:
+    case 0b00111000:
+    case 0b00111001:
+    case 0b00111010:
+    case 0b00111011:
+    case 0b00111100:
+    case 0b00111101:
+    case 0b00111110:
+      entry_type_ = HpackEntryType::kDynamicTableSizeUpdate;
+      // The low 5 bits of |byte| are the initial bits of the varint.
+      // One of those bits is 0, so the varint is only one byte long.
+      varint_decoder_.set_value(byte & 0x01f);
+      return DecodeStatus::kDecodeDone;
+
+    case 0b00111111:
+      entry_type_ = HpackEntryType::kDynamicTableSizeUpdate;
+      // The low 5 bits of |byte| are the initial bits of the varint.
+      // All of those bits are 1, so the varint extends into another byte.
+      return varint_decoder_.StartExtended(5, db);
+
+    case 0b01000000:
+    case 0b01000001:
+    case 0b01000010:
+    case 0b01000011:
+    case 0b01000100:
+    case 0b01000101:
+    case 0b01000110:
+    case 0b01000111:
+    case 0b01001000:
+    case 0b01001001:
+    case 0b01001010:
+    case 0b01001011:
+    case 0b01001100:
+    case 0b01001101:
+    case 0b01001110:
+    case 0b01001111:
+    case 0b01010000:
+    case 0b01010001:
+    case 0b01010010:
+    case 0b01010011:
+    case 0b01010100:
+    case 0b01010101:
+    case 0b01010110:
+    case 0b01010111:
+    case 0b01011000:
+    case 0b01011001:
+    case 0b01011010:
+    case 0b01011011:
+    case 0b01011100:
+    case 0b01011101:
+    case 0b01011110:
+    case 0b01011111:
+    case 0b01100000:
+    case 0b01100001:
+    case 0b01100010:
+    case 0b01100011:
+    case 0b01100100:
+    case 0b01100101:
+    case 0b01100110:
+    case 0b01100111:
+    case 0b01101000:
+    case 0b01101001:
+    case 0b01101010:
+    case 0b01101011:
+    case 0b01101100:
+    case 0b01101101:
+    case 0b01101110:
+    case 0b01101111:
+    case 0b01110000:
+    case 0b01110001:
+    case 0b01110010:
+    case 0b01110011:
+    case 0b01110100:
+    case 0b01110101:
+    case 0b01110110:
+    case 0b01110111:
+    case 0b01111000:
+    case 0b01111001:
+    case 0b01111010:
+    case 0b01111011:
+    case 0b01111100:
+    case 0b01111101:
+    case 0b01111110:
+      entry_type_ = HpackEntryType::kIndexedLiteralHeader;
+      // The low 6 bits of |byte| are the initial bits of the varint.
+      // One of those bits is 0, so the varint is only one byte long.
+      varint_decoder_.set_value(byte & 0x03f);
+      return DecodeStatus::kDecodeDone;
+
+    case 0b01111111:
+      entry_type_ = HpackEntryType::kIndexedLiteralHeader;
+      // The low 6 bits of |byte| are the initial bits of the varint.
+      // All of those bits are 1, so the varint extends into another byte.
+      return varint_decoder_.StartExtended(6, db);
+
+    case 0b10000000:
+    case 0b10000001:
+    case 0b10000010:
+    case 0b10000011:
+    case 0b10000100:
+    case 0b10000101:
+    case 0b10000110:
+    case 0b10000111:
+    case 0b10001000:
+    case 0b10001001:
+    case 0b10001010:
+    case 0b10001011:
+    case 0b10001100:
+    case 0b10001101:
+    case 0b10001110:
+    case 0b10001111:
+    case 0b10010000:
+    case 0b10010001:
+    case 0b10010010:
+    case 0b10010011:
+    case 0b10010100:
+    case 0b10010101:
+    case 0b10010110:
+    case 0b10010111:
+    case 0b10011000:
+    case 0b10011001:
+    case 0b10011010:
+    case 0b10011011:
+    case 0b10011100:
+    case 0b10011101:
+    case 0b10011110:
+    case 0b10011111:
+    case 0b10100000:
+    case 0b10100001:
+    case 0b10100010:
+    case 0b10100011:
+    case 0b10100100:
+    case 0b10100101:
+    case 0b10100110:
+    case 0b10100111:
+    case 0b10101000:
+    case 0b10101001:
+    case 0b10101010:
+    case 0b10101011:
+    case 0b10101100:
+    case 0b10101101:
+    case 0b10101110:
+    case 0b10101111:
+    case 0b10110000:
+    case 0b10110001:
+    case 0b10110010:
+    case 0b10110011:
+    case 0b10110100:
+    case 0b10110101:
+    case 0b10110110:
+    case 0b10110111:
+    case 0b10111000:
+    case 0b10111001:
+    case 0b10111010:
+    case 0b10111011:
+    case 0b10111100:
+    case 0b10111101:
+    case 0b10111110:
+    case 0b10111111:
+    case 0b11000000:
+    case 0b11000001:
+    case 0b11000010:
+    case 0b11000011:
+    case 0b11000100:
+    case 0b11000101:
+    case 0b11000110:
+    case 0b11000111:
+    case 0b11001000:
+    case 0b11001001:
+    case 0b11001010:
+    case 0b11001011:
+    case 0b11001100:
+    case 0b11001101:
+    case 0b11001110:
+    case 0b11001111:
+    case 0b11010000:
+    case 0b11010001:
+    case 0b11010010:
+    case 0b11010011:
+    case 0b11010100:
+    case 0b11010101:
+    case 0b11010110:
+    case 0b11010111:
+    case 0b11011000:
+    case 0b11011001:
+    case 0b11011010:
+    case 0b11011011:
+    case 0b11011100:
+    case 0b11011101:
+    case 0b11011110:
+    case 0b11011111:
+    case 0b11100000:
+    case 0b11100001:
+    case 0b11100010:
+    case 0b11100011:
+    case 0b11100100:
+    case 0b11100101:
+    case 0b11100110:
+    case 0b11100111:
+    case 0b11101000:
+    case 0b11101001:
+    case 0b11101010:
+    case 0b11101011:
+    case 0b11101100:
+    case 0b11101101:
+    case 0b11101110:
+    case 0b11101111:
+    case 0b11110000:
+    case 0b11110001:
+    case 0b11110010:
+    case 0b11110011:
+    case 0b11110100:
+    case 0b11110101:
+    case 0b11110110:
+    case 0b11110111:
+    case 0b11111000:
+    case 0b11111001:
+    case 0b11111010:
+    case 0b11111011:
+    case 0b11111100:
+    case 0b11111101:
+    case 0b11111110:
+      entry_type_ = HpackEntryType::kIndexedHeader;
+      // The low 7 bits of |byte| are the initial bits of the varint.
+      // One of those bits is 0, so the varint is only one byte long.
+      varint_decoder_.set_value(byte & 0x07f);
+      return DecodeStatus::kDecodeDone;
+
+    case 0b11111111:
+      entry_type_ = HpackEntryType::kIndexedHeader;
+      // The low 7 bits of |byte| are the initial bits of the varint.
+      // All of those bits are 1, so the varint extends into another byte.
+      return varint_decoder_.StartExtended(7, db);
+  }
+  HTTP2_BUG(http2_bug_66_1)
+      << "Unreachable, byte=" << std::hex << static_cast<uint32_t>(byte);
+  HTTP2_CODE_COUNT_N(decompress_failure_3, 17, 23);
+  return DecodeStatus::kDecodeError;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_entry_type_decoder.h b/quiche/http2/hpack/decoder/hpack_entry_type_decoder.h
new file mode 100644
index 0000000..94554d4
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_type_decoder.h
@@ -0,0 +1,57 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_TYPE_DECODER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_TYPE_DECODER_H_
+
+// Decodes the type of an HPACK entry, and the variable length integer whose
+// prefix is in the low-order bits of the same byte, "below" the type bits.
+// The integer represents an index into static or dynamic table, which may be
+// zero, or is the new size limit of the dynamic table.
+
+#include <cstdint>
+#include <string>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackEntryTypeDecoder {
+ public:
+  // Only call when the decode buffer has data (i.e. HpackEntryDecoder must
+  // not call until there is data).
+  DecodeStatus Start(DecodeBuffer* db);
+
+  // Only call Resume if the previous call (Start or Resume) returned
+  // DecodeStatus::kDecodeInProgress.
+  DecodeStatus Resume(DecodeBuffer* db) { return varint_decoder_.Resume(db); }
+
+  // Returns the decoded entry type. Only call if the preceding call to Start
+  // or Resume returned kDecodeDone.
+  HpackEntryType entry_type() const { return entry_type_; }
+
+  // Returns the decoded variable length integer. Only call if the
+  // preceding call to Start or Resume returned kDecodeDone.
+  uint64_t varint() const { return varint_decoder_.value(); }
+
+  std::string DebugString() const;
+
+ private:
+  HpackVarintDecoder varint_decoder_;
+
+  // This field is initialized just to keep ASAN happy about reading it
+  // from DebugString().
+  HpackEntryType entry_type_ = HpackEntryType::kIndexedHeader;
+};
+
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const HpackEntryTypeDecoder& v);
+
+}  // namespace http2
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_ENTRY_TYPE_DECODER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_entry_type_decoder_test.cc b/quiche/http2/hpack/decoder/hpack_entry_type_decoder_test.cc
new file mode 100644
index 0000000..4aaff79
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_entry_type_decoder_test.cc
@@ -0,0 +1,85 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_entry_type_decoder.h"
+
+#include <vector>
+
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+namespace {
+const bool kReturnNonZeroOnFirst = true;
+
+class HpackEntryTypeDecoderTest : public RandomDecoderTest {
+ protected:
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    QUICHE_CHECK_LT(0u, b->Remaining());
+    return decoder_.Start(b);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    return decoder_.Resume(b);
+  }
+
+  HpackEntryTypeDecoder decoder_;
+};
+
+TEST_F(HpackEntryTypeDecoderTest, DynamicTableSizeUpdate) {
+  for (uint32_t size = 0; size < 1000 * 1000; size += 256) {
+    HpackBlockBuilder bb;
+    bb.AppendDynamicTableSizeUpdate(size);
+    DecodeBuffer db(bb.buffer());
+    auto validator = [size, this]() -> AssertionResult {
+      VERIFY_EQ(HpackEntryType::kDynamicTableSizeUpdate, decoder_.entry_type());
+      VERIFY_EQ(size, decoder_.varint());
+      return AssertionSuccess();
+    };
+    EXPECT_TRUE(DecodeAndValidateSeveralWays(&db, kReturnNonZeroOnFirst,
+                                             ValidateDoneAndEmpty(validator)))
+        << "\nentry_type=kDynamicTableSizeUpdate, size=" << size;
+    // Run the validator again to make sure that DecodeAndValidateSeveralWays
+    // did the right thing.
+    EXPECT_TRUE(validator());
+  }
+}
+
+TEST_F(HpackEntryTypeDecoderTest, HeaderWithIndex) {
+  std::vector<HpackEntryType> entry_types = {
+      HpackEntryType::kIndexedHeader,
+      HpackEntryType::kIndexedLiteralHeader,
+      HpackEntryType::kUnindexedLiteralHeader,
+      HpackEntryType::kNeverIndexedLiteralHeader,
+  };
+  for (const HpackEntryType entry_type : entry_types) {
+    const uint32_t first = entry_type == HpackEntryType::kIndexedHeader ? 1 : 0;
+    for (uint32_t index = first; index < 1000; ++index) {
+      HpackBlockBuilder bb;
+      bb.AppendEntryTypeAndVarint(entry_type, index);
+      DecodeBuffer db(bb.buffer());
+      auto validator = [entry_type, index, this]() -> AssertionResult {
+        VERIFY_EQ(entry_type, decoder_.entry_type());
+        VERIFY_EQ(index, decoder_.varint());
+        return AssertionSuccess();
+      };
+      EXPECT_TRUE(DecodeAndValidateSeveralWays(&db, kReturnNonZeroOnFirst,
+                                               ValidateDoneAndEmpty(validator)))
+          << "\nentry_type=" << entry_type << ", index=" << index;
+      // Run the validator again to make sure that DecodeAndValidateSeveralWays
+      // did the right thing.
+      EXPECT_TRUE(validator());
+    }
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_string_collector.cc b/quiche/http2/hpack/decoder/hpack_string_collector.cc
new file mode 100644
index 0000000..d9fa440
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_collector.cc
@@ -0,0 +1,124 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_string_collector.h"
+
+#include <stddef.h>
+
+#include <iosfwd>
+#include <ostream>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+std::ostream& operator<<(std::ostream& out,
+                         HpackStringCollector::CollectorState v) {
+  switch (v) {
+    case HpackStringCollector::CollectorState::kGenesis:
+      return out << "kGenesis";
+    case HpackStringCollector::CollectorState::kStarted:
+      return out << "kStarted";
+    case HpackStringCollector::CollectorState::kEnded:
+      return out << "kEnded";
+  }
+  return out << "UnknownCollectorState";
+}
+
+}  // namespace
+
+HpackStringCollector::HpackStringCollector() {
+  Clear();
+}
+
+HpackStringCollector::HpackStringCollector(const std::string& str, bool huffman)
+    : s(str), len(str.size()), huffman_encoded(huffman), state(kEnded) {}
+
+void HpackStringCollector::Clear() {
+  s = "";
+  len = 0;
+  huffman_encoded = false;
+  state = kGenesis;
+}
+
+bool HpackStringCollector::IsClear() const {
+  return s.empty() && len == 0 && huffman_encoded == false && state == kGenesis;
+}
+
+bool HpackStringCollector::IsInProgress() const {
+  return state == kStarted;
+}
+
+bool HpackStringCollector::HasEnded() const {
+  return state == kEnded;
+}
+
+void HpackStringCollector::OnStringStart(bool huffman, size_t length) {
+  EXPECT_TRUE(IsClear()) << ToString();
+  state = kStarted;
+  huffman_encoded = huffman;
+  len = length;
+}
+
+void HpackStringCollector::OnStringData(const char* data, size_t length) {
+  absl::string_view sp(data, length);
+  EXPECT_TRUE(IsInProgress()) << ToString();
+  EXPECT_LE(sp.size(), len) << ToString();
+  absl::StrAppend(&s, sp);
+  EXPECT_LE(s.size(), len) << ToString();
+}
+
+void HpackStringCollector::OnStringEnd() {
+  EXPECT_TRUE(IsInProgress()) << ToString();
+  EXPECT_EQ(s.size(), len) << ToString();
+  state = kEnded;
+}
+
+::testing::AssertionResult HpackStringCollector::Collected(
+    absl::string_view str,
+    bool is_huffman_encoded) const {
+  VERIFY_TRUE(HasEnded());
+  VERIFY_EQ(str.size(), len);
+  VERIFY_EQ(is_huffman_encoded, huffman_encoded);
+  VERIFY_EQ(str, s);
+  return ::testing::AssertionSuccess();
+}
+
+std::string HpackStringCollector::ToString() const {
+  std::stringstream ss;
+  ss << *this;
+  return ss.str();
+}
+
+bool operator==(const HpackStringCollector& a, const HpackStringCollector& b) {
+  return a.s == b.s && a.len == b.len &&
+         a.huffman_encoded == b.huffman_encoded && a.state == b.state;
+}
+
+bool operator!=(const HpackStringCollector& a, const HpackStringCollector& b) {
+  return !(a == b);
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackStringCollector& v) {
+  out << "HpackStringCollector(state=" << v.state;
+  if (v.state == HpackStringCollector::kGenesis) {
+    return out << ")";
+  }
+  if (v.huffman_encoded) {
+    out << ", Huffman Encoded";
+  }
+  out << ", Length=" << v.len;
+  if (!v.s.empty() && v.len != v.s.size()) {
+    out << " (" << v.s.size() << ")";
+  }
+  return out << ", String=\"" << absl::CHexEscape(v.s) << "\")";
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_string_collector.h b/quiche/http2/hpack/decoder/hpack_string_collector.h
new file mode 100644
index 0000000..270c8a5
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_collector.h
@@ -0,0 +1,63 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_COLLECTOR_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_COLLECTOR_H_
+
+// Supports tests of decoding HPACK strings.
+
+#include <stddef.h>
+
+#include <iosfwd>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_string_decoder_listener.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+// Records the callbacks associated with a decoding a string; must
+// call Clear() between decoding successive strings.
+struct HpackStringCollector : public HpackStringDecoderListener {
+  enum CollectorState {
+    kGenesis,
+    kStarted,
+    kEnded,
+  };
+
+  HpackStringCollector();
+  HpackStringCollector(const std::string& str, bool huffman);
+
+  void Clear();
+  bool IsClear() const;
+  bool IsInProgress() const;
+  bool HasEnded() const;
+
+  void OnStringStart(bool huffman, size_t length) override;
+  void OnStringData(const char* data, size_t length) override;
+  void OnStringEnd() override;
+
+  ::testing::AssertionResult Collected(absl::string_view str,
+                                       bool is_huffman_encoded) const;
+
+  std::string ToString() const;
+
+  std::string s;
+  size_t len;
+  bool huffman_encoded;
+  CollectorState state;
+};
+
+bool operator==(const HpackStringCollector& a, const HpackStringCollector& b);
+
+bool operator!=(const HpackStringCollector& a, const HpackStringCollector& b);
+
+std::ostream& operator<<(std::ostream& out, const HpackStringCollector& v);
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_COLLECTOR_H_
diff --git a/quiche/http2/hpack/decoder/hpack_string_decoder.cc b/quiche/http2/hpack/decoder/hpack_string_decoder.cc
new file mode 100644
index 0000000..f2a4bf8
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_decoder.cc
@@ -0,0 +1,35 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_string_decoder.h"
+
+#include "absl/strings/str_cat.h"
+
+namespace http2 {
+
+std::string HpackStringDecoder::DebugString() const {
+  return absl::StrCat("HpackStringDecoder(state=", StateToString(state_),
+                      ", length=", length_decoder_.DebugString(),
+                      ", remaining=", remaining_,
+                      ", huffman=", huffman_encoded_ ? "true)" : "false)");
+}
+
+// static
+std::string HpackStringDecoder::StateToString(StringDecoderState v) {
+  switch (v) {
+    case kStartDecodingLength:
+      return "kStartDecodingLength";
+    case kDecodingString:
+      return "kDecodingString";
+    case kResumeDecodingLength:
+      return "kResumeDecodingLength";
+  }
+  return absl::StrCat("UNKNOWN_STATE(", static_cast<uint32_t>(v), ")");
+}
+
+std::ostream& operator<<(std::ostream& out, const HpackStringDecoder& v) {
+  return out << v.DebugString();
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_string_decoder.h b/quiche/http2/hpack/decoder/hpack_string_decoder.h
new file mode 100644
index 0000000..a856685
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_decoder.h
@@ -0,0 +1,209 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_H_
+
+// HpackStringDecoder decodes strings encoded per the HPACK spec; this does
+// not mean decompressing Huffman encoded strings, just identifying the length,
+// encoding and contents for a listener.
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// Decodes a single string in an HPACK header entry. The high order bit of
+// the first byte of the length is the H (Huffman) bit indicating whether
+// the value is Huffman encoded, and the remainder of the byte is the first
+// 7 bits of an HPACK varint.
+//
+// Call Start() to begin decoding; if it returns kDecodeInProgress, then call
+// Resume() when more input is available, repeating until kDecodeInProgress is
+// not returned. If kDecodeDone or kDecodeError is returned, then Resume() must
+// not be called until Start() has been called to start decoding a new string.
+class QUICHE_EXPORT_PRIVATE HpackStringDecoder {
+ public:
+  enum StringDecoderState {
+    kStartDecodingLength,
+    kDecodingString,
+    kResumeDecodingLength,
+  };
+
+  template <class Listener>
+  DecodeStatus Start(DecodeBuffer* db, Listener* cb) {
+    // Fast decode path is used if the string is under 127 bytes and the
+    // entire length of the string is in the decode buffer. More than 83% of
+    // string lengths are encoded in just one byte.
+    if (db->HasData() && (*db->cursor() & 0x7f) != 0x7f) {
+      // The string is short.
+      uint8_t h_and_prefix = db->DecodeUInt8();
+      uint8_t length = h_and_prefix & 0x7f;
+      bool huffman_encoded = (h_and_prefix & 0x80) == 0x80;
+      cb->OnStringStart(huffman_encoded, length);
+      if (length <= db->Remaining()) {
+        // Yeah, we've got the whole thing in the decode buffer.
+        // Ideally this will be the common case. Note that we don't
+        // update any of the member variables in this path.
+        cb->OnStringData(db->cursor(), length);
+        db->AdvanceCursor(length);
+        cb->OnStringEnd();
+        return DecodeStatus::kDecodeDone;
+      }
+      // Not all in the buffer.
+      huffman_encoded_ = huffman_encoded;
+      remaining_ = length;
+      // Call Resume to decode the string body, which is only partially
+      // in the decode buffer (or not at all).
+      state_ = kDecodingString;
+      return Resume(db, cb);
+    }
+    // Call Resume to decode the string length, which is either not in
+    // the decode buffer, or spans multiple bytes.
+    state_ = kStartDecodingLength;
+    return Resume(db, cb);
+  }
+
+  template <class Listener>
+  DecodeStatus Resume(DecodeBuffer* db, Listener* cb) {
+    DecodeStatus status;
+    while (true) {
+      switch (state_) {
+        case kStartDecodingLength:
+          HTTP2_DVLOG(2) << "kStartDecodingLength: db->Remaining="
+                         << db->Remaining();
+          if (!StartDecodingLength(db, cb, &status)) {
+            // The length is split across decode buffers.
+            return status;
+          }
+          // We've finished decoding the length, which spanned one or more
+          // bytes. Approximately 17% of strings have a length that is greater
+          // than 126 bytes, and thus the length is encoded in more than one
+          // byte, and so doesn't get the benefit of the optimization in
+          // Start() for single byte lengths. But, we still expect that most
+          // of such strings will be contained entirely in a single decode
+          // buffer, and hence this fall through skips another trip through the
+          // switch above and more importantly skips setting the state_ variable
+          // again in those cases where we don't need it.
+          ABSL_FALLTHROUGH_INTENDED;
+
+        case kDecodingString:
+          HTTP2_DVLOG(2) << "kDecodingString: db->Remaining=" << db->Remaining()
+                         << "    remaining_=" << remaining_;
+          return DecodeString(db, cb);
+
+        case kResumeDecodingLength:
+          HTTP2_DVLOG(2) << "kResumeDecodingLength: db->Remaining="
+                         << db->Remaining();
+          if (!ResumeDecodingLength(db, cb, &status)) {
+            return status;
+          }
+      }
+    }
+  }
+
+  std::string DebugString() const;
+
+ private:
+  static std::string StateToString(StringDecoderState v);
+
+  // Returns true if the length is fully decoded and the listener wants the
+  // decoding to continue, false otherwise; status is set to the status from
+  // the varint decoder.
+  // If the length is not fully decoded, case state_ is set appropriately
+  // for the next call to Resume.
+  template <class Listener>
+  bool StartDecodingLength(DecodeBuffer* db,
+                           Listener* cb,
+                           DecodeStatus* status) {
+    if (db->Empty()) {
+      *status = DecodeStatus::kDecodeInProgress;
+      state_ = kStartDecodingLength;
+      return false;
+    }
+    uint8_t h_and_prefix = db->DecodeUInt8();
+    huffman_encoded_ = (h_and_prefix & 0x80) == 0x80;
+    *status = length_decoder_.Start(h_and_prefix, 7, db);
+    if (*status == DecodeStatus::kDecodeDone) {
+      OnStringStart(cb, status);
+      return true;
+    }
+    // Set the state to cover the DecodeStatus::kDecodeInProgress case.
+    // Won't be needed if the status is kDecodeError.
+    state_ = kResumeDecodingLength;
+    return false;
+  }
+
+  // Returns true if the length is fully decoded and the listener wants the
+  // decoding to continue, false otherwise; status is set to the status from
+  // the varint decoder; state_ is updated when fully decoded.
+  // If the length is not fully decoded, case state_ is set appropriately
+  // for the next call to Resume.
+  template <class Listener>
+  bool ResumeDecodingLength(DecodeBuffer* db,
+                            Listener* cb,
+                            DecodeStatus* status) {
+    QUICHE_DCHECK_EQ(state_, kResumeDecodingLength);
+    *status = length_decoder_.Resume(db);
+    if (*status == DecodeStatus::kDecodeDone) {
+      state_ = kDecodingString;
+      OnStringStart(cb, status);
+      return true;
+    }
+    return false;
+  }
+
+  // Returns true if the listener wants the decoding to continue, and
+  // false otherwise, in which case status set.
+  template <class Listener>
+  void OnStringStart(Listener* cb, DecodeStatus* /*status*/) {
+    // TODO(vasilvv): fail explicitly in case of truncation.
+    remaining_ = static_cast<size_t>(length_decoder_.value());
+    // Make callback so consumer knows what is coming.
+    cb->OnStringStart(huffman_encoded_, remaining_);
+  }
+
+  // Passes the available portion of the string to the listener, and signals
+  // the end of the string when it is reached. Returns kDecodeDone or
+  // kDecodeInProgress as appropriate.
+  template <class Listener>
+  DecodeStatus DecodeString(DecodeBuffer* db, Listener* cb) {
+    size_t len = std::min(remaining_, db->Remaining());
+    if (len > 0) {
+      cb->OnStringData(db->cursor(), len);
+      db->AdvanceCursor(len);
+      remaining_ -= len;
+    }
+    if (remaining_ == 0) {
+      cb->OnStringEnd();
+      return DecodeStatus::kDecodeDone;
+    }
+    state_ = kDecodingString;
+    return DecodeStatus::kDecodeInProgress;
+  }
+
+  HpackVarintDecoder length_decoder_;
+
+  // These fields are initialized just to keep ASAN happy about reading
+  // them from DebugString().
+  size_t remaining_ = 0;
+  StringDecoderState state_ = kStartDecodingLength;
+  bool huffman_encoded_ = false;
+};
+
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const HpackStringDecoder& v);
+
+}  // namespace http2
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_string_decoder_listener.cc b/quiche/http2/hpack/decoder/hpack_string_decoder_listener.cc
new file mode 100644
index 0000000..fef70c2
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_decoder_listener.cc
@@ -0,0 +1,36 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_string_decoder_listener.h"
+
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+namespace test {
+
+void HpackStringDecoderVLoggingListener::OnStringStart(bool huffman_encoded,
+                                                       size_t len) {
+  HTTP2_VLOG(1) << "OnStringStart: H=" << huffman_encoded << ", len=" << len;
+  if (wrapped_) {
+    wrapped_->OnStringStart(huffman_encoded, len);
+  }
+}
+
+void HpackStringDecoderVLoggingListener::OnStringData(const char* data,
+                                                      size_t len) {
+  HTTP2_VLOG(1) << "OnStringData: len=" << len;
+  if (wrapped_) {
+    return wrapped_->OnStringData(data, len);
+  }
+}
+
+void HpackStringDecoderVLoggingListener::OnStringEnd() {
+  HTTP2_VLOG(1) << "OnStringEnd";
+  if (wrapped_) {
+    return wrapped_->OnStringEnd();
+  }
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_string_decoder_listener.h b/quiche/http2/hpack/decoder/hpack_string_decoder_listener.h
new file mode 100644
index 0000000..c343d40
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_decoder_listener.h
@@ -0,0 +1,62 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_LISTENER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_LISTENER_H_
+
+// Defines HpackStringDecoderListener which defines the methods required by an
+// HpackStringDecoder. Also defines HpackStringDecoderVLoggingListener which
+// logs before calling another HpackStringDecoderListener implementation.
+// For now these are only used by tests, so placed in the test namespace.
+
+#include <stddef.h>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+namespace test {
+
+// HpackStringDecoder methods require a listener that implements the methods
+// below, but it is NOT necessary to extend this class because the methods
+// are templates.
+class QUICHE_EXPORT_PRIVATE HpackStringDecoderListener {
+ public:
+  virtual ~HpackStringDecoderListener() {}
+
+  // Called at the start of decoding an HPACK string. The encoded length of the
+  // string is |len| bytes, which may be zero. The string is Huffman encoded
+  // if huffman_encoded is true, else it is plain text (i.e. the encoded length
+  // is then the plain text length).
+  virtual void OnStringStart(bool huffman_encoded, size_t len) = 0;
+
+  // Called when some data is available, or once when the string length is zero
+  // (to simplify the decoder, it doesn't have a special case for len==0).
+  virtual void OnStringData(const char* data, size_t len) = 0;
+
+  // Called after OnStringData has provided all of the encoded bytes of the
+  // string.
+  virtual void OnStringEnd() = 0;
+};
+
+class QUICHE_EXPORT_PRIVATE HpackStringDecoderVLoggingListener
+    : public HpackStringDecoderListener {
+ public:
+  HpackStringDecoderVLoggingListener() : wrapped_(nullptr) {}
+  explicit HpackStringDecoderVLoggingListener(
+      HpackStringDecoderListener* wrapped)
+      : wrapped_(wrapped) {}
+  ~HpackStringDecoderVLoggingListener() override {}
+
+  void OnStringStart(bool huffman_encoded, size_t len) override;
+  void OnStringData(const char* data, size_t len) override;
+  void OnStringEnd() override;
+
+ private:
+  HpackStringDecoderListener* const wrapped_;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_STRING_DECODER_LISTENER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_string_decoder_test.cc b/quiche/http2/hpack/decoder/hpack_string_decoder_test.cc
new file mode 100644
index 0000000..58b4abc
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_string_decoder_test.cc
@@ -0,0 +1,154 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_string_decoder.h"
+
+// Tests of HpackStringDecoder.
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_string_collector.h"
+#include "quiche/http2/hpack/decoder/hpack_string_decoder_listener.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+const bool kMayReturnZeroOnFirst = false;
+const bool kCompressed = true;
+const bool kUncompressed = false;
+
+class HpackStringDecoderTest : public RandomDecoderTest {
+ protected:
+  HpackStringDecoderTest() : listener_(&collector_) {}
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    ++start_decoding_calls_;
+    collector_.Clear();
+    return decoder_.Start(b, &listener_);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    // Provides coverage of DebugString and StateToString.
+    // Not validating output.
+    HTTP2_VLOG(1) << decoder_.DebugString();
+    HTTP2_VLOG(2) << collector_;
+    return decoder_.Resume(b, &listener_);
+  }
+
+  AssertionResult Collected(absl::string_view s, bool huffman_encoded) {
+    HTTP2_VLOG(1) << collector_;
+    return collector_.Collected(s, huffman_encoded);
+  }
+
+  // expected_str is a std::string rather than a const std::string& or
+  // absl::string_view so that the lambda makes a copy of the string, and thus
+  // the string to be passed to Collected outlives the call to MakeValidator.
+  Validator MakeValidator(const std::string& expected_str,
+                          bool expected_huffman) {
+    return
+        [expected_str, expected_huffman, this](
+            const DecodeBuffer& /*input*/,
+            DecodeStatus /*status*/) -> AssertionResult {
+          AssertionResult result = Collected(expected_str, expected_huffman);
+          if (result) {
+            VERIFY_EQ(collector_,
+                      HpackStringCollector(expected_str, expected_huffman));
+          } else {
+            VERIFY_NE(collector_,
+                      HpackStringCollector(expected_str, expected_huffman));
+          }
+          HTTP2_VLOG(2) << collector_.ToString();
+          collector_.Clear();
+          HTTP2_VLOG(2) << collector_;
+          return result;
+        };
+  }
+
+  HpackStringDecoder decoder_;
+  HpackStringCollector collector_;
+  HpackStringDecoderVLoggingListener listener_;
+  size_t start_decoding_calls_ = 0;
+};
+
+TEST_F(HpackStringDecoderTest, DecodeEmptyString) {
+  {
+    Validator validator = ValidateDoneAndEmpty(MakeValidator("", kCompressed));
+    const char kData[] = {'\x80'};
+    DecodeBuffer b(kData);
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
+  }
+  {
+    // Make sure it stops after decoding the empty string.
+    Validator validator =
+        ValidateDoneAndOffset(1, MakeValidator("", kUncompressed));
+    const char kData[] = {'\x00', '\xff'};
+    DecodeBuffer b(kData);
+    EXPECT_EQ(2u, b.Remaining());
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
+    EXPECT_EQ(1u, b.Remaining());
+  }
+}
+
+TEST_F(HpackStringDecoderTest, DecodeShortString) {
+  {
+    // Make sure it stops after decoding the non-empty string.
+    Validator validator =
+        ValidateDoneAndOffset(11, MakeValidator("start end.", kCompressed));
+    const char kData[] = "\x8astart end.Don't peek at this.";
+    DecodeBuffer b(kData);
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
+  }
+  {
+    Validator validator =
+        ValidateDoneAndOffset(11, MakeValidator("start end.", kUncompressed));
+    absl::string_view data("\x0astart end.");
+    DecodeBuffer b(data);
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, kMayReturnZeroOnFirst, validator));
+  }
+}
+
+TEST_F(HpackStringDecoderTest, DecodeLongStrings) {
+  std::string name = Random().RandString(1024);
+  std::string value = Random().RandString(65536);
+  HpackBlockBuilder hbb;
+
+  hbb.AppendString(false, name);
+  uint32_t offset_after_name = hbb.size();
+  EXPECT_EQ(3 + name.size(), offset_after_name);
+
+  hbb.AppendString(true, value);
+  uint32_t offset_after_value = hbb.size();
+  EXPECT_EQ(3 + name.size() + 4 + value.size(), offset_after_value);
+
+  DecodeBuffer b(hbb.buffer());
+
+  // Decode the name...
+  EXPECT_TRUE(DecodeAndValidateSeveralWays(
+      &b, kMayReturnZeroOnFirst,
+      ValidateDoneAndOffset(offset_after_name,
+                            MakeValidator(name, kUncompressed))));
+  EXPECT_EQ(offset_after_name, b.Offset());
+  EXPECT_EQ(offset_after_value - offset_after_name, b.Remaining());
+
+  // Decode the value...
+  EXPECT_TRUE(DecodeAndValidateSeveralWays(
+      &b, kMayReturnZeroOnFirst,
+      ValidateDoneAndOffset(offset_after_value - offset_after_name,
+                            MakeValidator(value, kCompressed))));
+  EXPECT_EQ(offset_after_value, b.Offset());
+  EXPECT_EQ(0u, b.Remaining());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.cc
new file mode 100644
index 0000000..3bb9652
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.cc
@@ -0,0 +1,153 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h"
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace http2 {
+
+HpackWholeEntryBuffer::HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
+                                             size_t max_string_size_bytes)
+    : max_string_size_bytes_(max_string_size_bytes) {
+  set_listener(listener);
+}
+HpackWholeEntryBuffer::~HpackWholeEntryBuffer() = default;
+
+void HpackWholeEntryBuffer::set_listener(HpackWholeEntryListener* listener) {
+  QUICHE_CHECK(listener);
+  listener_ = listener;
+}
+
+void HpackWholeEntryBuffer::set_max_string_size_bytes(
+    size_t max_string_size_bytes) {
+  max_string_size_bytes_ = max_string_size_bytes;
+}
+
+void HpackWholeEntryBuffer::BufferStringsIfUnbuffered() {
+  name_.BufferStringIfUnbuffered();
+  value_.BufferStringIfUnbuffered();
+}
+
+void HpackWholeEntryBuffer::OnIndexedHeader(size_t index) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnIndexedHeader: index=" << index;
+  listener_->OnIndexedHeader(index);
+}
+
+void HpackWholeEntryBuffer::OnStartLiteralHeader(HpackEntryType entry_type,
+                                                 size_t maybe_name_index) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnStartLiteralHeader: entry_type="
+                 << entry_type << ",  maybe_name_index=" << maybe_name_index;
+  entry_type_ = entry_type;
+  maybe_name_index_ = maybe_name_index;
+}
+
+void HpackWholeEntryBuffer::OnNameStart(bool huffman_encoded, size_t len) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameStart: huffman_encoded="
+                 << (huffman_encoded ? "true" : "false") << ",  len=" << len;
+  QUICHE_DCHECK_EQ(maybe_name_index_, 0u);
+  if (!error_detected_) {
+    if (len > max_string_size_bytes_) {
+      HTTP2_DVLOG(1) << "Name length (" << len << ") is longer than permitted ("
+                     << max_string_size_bytes_ << ")";
+      ReportError(HpackDecodingError::kNameTooLong, "");
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 18, 23);
+      return;
+    }
+    name_.OnStart(huffman_encoded, len);
+  }
+}
+
+void HpackWholeEntryBuffer::OnNameData(const char* data, size_t len) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameData: len=" << len
+                 << " data:\n"
+                 << quiche::QuicheTextUtils::HexDump(
+                        absl::string_view(data, len));
+  QUICHE_DCHECK_EQ(maybe_name_index_, 0u);
+  if (!error_detected_ && !name_.OnData(data, len)) {
+    ReportError(HpackDecodingError::kNameHuffmanError, "");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 19, 23);
+  }
+}
+
+void HpackWholeEntryBuffer::OnNameEnd() {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameEnd";
+  QUICHE_DCHECK_EQ(maybe_name_index_, 0u);
+  if (!error_detected_ && !name_.OnEnd()) {
+    ReportError(HpackDecodingError::kNameHuffmanError, "");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 20, 23);
+  }
+}
+
+void HpackWholeEntryBuffer::OnValueStart(bool huffman_encoded, size_t len) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueStart: huffman_encoded="
+                 << (huffman_encoded ? "true" : "false") << ",  len=" << len;
+  if (!error_detected_) {
+    if (len > max_string_size_bytes_) {
+      std::string detailed_error = absl::StrCat(
+          "Value length (", len, ") of [", name_.GetStringIfComplete(),
+          "] is longer than permitted (", max_string_size_bytes_, ")");
+      HTTP2_DVLOG(1) << detailed_error;
+      ReportError(HpackDecodingError::kValueTooLong, detailed_error);
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 21, 23);
+      return;
+    }
+    value_.OnStart(huffman_encoded, len);
+  }
+}
+
+void HpackWholeEntryBuffer::OnValueData(const char* data, size_t len) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueData: len=" << len
+                 << " data:\n"
+                 << quiche::QuicheTextUtils::HexDump(
+                        absl::string_view(data, len));
+  if (!error_detected_ && !value_.OnData(data, len)) {
+    ReportError(HpackDecodingError::kValueHuffmanError, "");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 22, 23);
+  }
+}
+
+void HpackWholeEntryBuffer::OnValueEnd() {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueEnd";
+  if (error_detected_) {
+    return;
+  }
+  if (!value_.OnEnd()) {
+    ReportError(HpackDecodingError::kValueHuffmanError, "");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 23, 23);
+    return;
+  }
+  if (maybe_name_index_ == 0) {
+    listener_->OnLiteralNameAndValue(entry_type_, &name_, &value_);
+    name_.Reset();
+  } else {
+    listener_->OnNameIndexAndLiteralValue(entry_type_, maybe_name_index_,
+                                          &value_);
+  }
+  value_.Reset();
+}
+
+void HpackWholeEntryBuffer::OnDynamicTableSizeUpdate(size_t size) {
+  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnDynamicTableSizeUpdate: size="
+                 << size;
+  listener_->OnDynamicTableSizeUpdate(size);
+}
+
+void HpackWholeEntryBuffer::ReportError(HpackDecodingError error,
+                                        std::string detailed_error) {
+  if (!error_detected_) {
+    HTTP2_DVLOG(1) << "HpackWholeEntryBuffer::ReportError: "
+                   << HpackDecodingErrorToString(error);
+    error_detected_ = true;
+    listener_->OnHpackDecodeError(error, detailed_error);
+    listener_ = HpackWholeEntryNoOpListener::NoOpListener();
+  }
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h b/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h
new file mode 100644
index 0000000..0cdde65
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h
@@ -0,0 +1,102 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
+
+// HpackWholeEntryBuffer isolates a listener from the fact that an entry may
+// be split across multiple input buffers, providing one callback per entry.
+// HpackWholeEntryBuffer requires that the HpackEntryDecoderListener be made in
+// the correct order, which is tested by hpack_entry_decoder_test.cc.
+
+#include <stddef.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+#include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_whole_entry_listener.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// TODO(jamessynge): Consider renaming HpackEntryDecoderListener to
+// HpackEntryPartsListener or HpackEntryFragmentsListener.
+class QUICHE_EXPORT_PRIVATE HpackWholeEntryBuffer
+    : public HpackEntryDecoderListener {
+ public:
+  // max_string_size specifies the maximum size of an on-the-wire string (name
+  // or value, plain or Huffman encoded) that will be accepted. See sections
+  // 5.1 and 5.2 of RFC 7541. This is a defense against OOM attacks; HTTP/2
+  // allows a decoder to enforce any limit of the size of the header lists
+  // that it is willing decode, including less than the MAX_HEADER_LIST_SIZE
+  // setting, a setting that is initially unlimited. For example, we might
+  // choose to send a MAX_HEADER_LIST_SIZE of 64KB, and to use that same value
+  // as the upper bound for individual strings.
+  HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
+                        size_t max_string_size);
+  ~HpackWholeEntryBuffer() override;
+
+  HpackWholeEntryBuffer(const HpackWholeEntryBuffer&) = delete;
+  HpackWholeEntryBuffer& operator=(const HpackWholeEntryBuffer&) = delete;
+
+  // Set the listener to be notified when a whole entry has been decoded.
+  // The listener may be changed at any time.
+  void set_listener(HpackWholeEntryListener* listener);
+
+  // Set how much encoded data this decoder is willing to buffer.
+  // TODO(jamessynge): Come up with consistent semantics for this protection
+  // across the various decoders; e.g. should it be for a single string or
+  // a single header entry?
+  void set_max_string_size_bytes(size_t max_string_size_bytes);
+
+  // Ensure that decoded strings pointed to by the HpackDecoderStringBuffer
+  // instances name_ and value_ are buffered, which allows any underlying
+  // transport buffer to be freed or reused without overwriting the decoded
+  // strings. This is needed only when an HPACK entry is split across transport
+  // buffers. See HpackDecoder::DecodeFragment.
+  void BufferStringsIfUnbuffered();
+
+  // Was an error detected? After an error has been detected and reported,
+  // no further callbacks will be made to the listener.
+  bool error_detected() const { return error_detected_; }
+
+  // Implement the HpackEntryDecoderListener methods.
+
+  void OnIndexedHeader(size_t index) override;
+  void OnStartLiteralHeader(HpackEntryType entry_type,
+                            size_t maybe_name_index) override;
+  void OnNameStart(bool huffman_encoded, size_t len) override;
+  void OnNameData(const char* data, size_t len) override;
+  void OnNameEnd() override;
+  void OnValueStart(bool huffman_encoded, size_t len) override;
+  void OnValueData(const char* data, size_t len) override;
+  void OnValueEnd() override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+
+ private:
+  void ReportError(HpackDecodingError error, std::string detailed_error);
+
+  HpackWholeEntryListener* listener_;
+  HpackDecoderStringBuffer name_, value_;
+
+  // max_string_size_bytes_ specifies the maximum allowed size of an on-the-wire
+  // string. Larger strings will be reported as errors to the listener; the
+  // endpoint should treat these as COMPRESSION errors, which are CONNECTION
+  // level errors.
+  size_t max_string_size_bytes_;
+
+  // The name index (or zero) of the current header entry with a literal value.
+  size_t maybe_name_index_;
+
+  // The type of the current header entry (with literals) that is being decoded.
+  HpackEntryType entry_type_;
+
+  bool error_detected_ = false;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_BUFFER_H_
diff --git a/quiche/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc b/quiche/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
new file mode 100644
index 0000000..ea20564
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
@@ -0,0 +1,232 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h"
+
+// Tests of HpackWholeEntryBuffer: does it buffer correctly, and does it
+// detect Huffman decoding errors and oversize string errors?
+
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::InSequence;
+using ::testing::Property;
+using ::testing::StrictMock;
+
+namespace http2 {
+namespace test {
+namespace {
+
+constexpr size_t kMaxStringSize = 20;
+
+class MockHpackWholeEntryListener : public HpackWholeEntryListener {
+ public:
+  ~MockHpackWholeEntryListener() override = default;
+
+  MOCK_METHOD(void, OnIndexedHeader, (size_t index), (override));
+  MOCK_METHOD(void,
+              OnNameIndexAndLiteralValue,
+              (HpackEntryType entry_type,
+               size_t name_index,
+               HpackDecoderStringBuffer* value_buffer),
+              (override));
+  MOCK_METHOD(void,
+              OnLiteralNameAndValue,
+              (HpackEntryType entry_type,
+               HpackDecoderStringBuffer* name_buffer,
+               HpackDecoderStringBuffer* value_buffer),
+              (override));
+  MOCK_METHOD(void, OnDynamicTableSizeUpdate, (size_t size), (override));
+  MOCK_METHOD(void,
+              OnHpackDecodeError,
+              (HpackDecodingError error, std::string detailed_error),
+              (override));
+};
+
+class HpackWholeEntryBufferTest : public QuicheTest {
+ protected:
+  HpackWholeEntryBufferTest() : entry_buffer_(&listener_, kMaxStringSize) {}
+  ~HpackWholeEntryBufferTest() override = default;
+
+  StrictMock<MockHpackWholeEntryListener> listener_;
+  HpackWholeEntryBuffer entry_buffer_;
+};
+
+// OnIndexedHeader is an immediate pass through.
+TEST_F(HpackWholeEntryBufferTest, OnIndexedHeader) {
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnIndexedHeader(17));
+    entry_buffer_.OnIndexedHeader(17);
+  }
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnIndexedHeader(62));
+    entry_buffer_.OnIndexedHeader(62);
+  }
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnIndexedHeader(62));
+    entry_buffer_.OnIndexedHeader(62);
+  }
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnIndexedHeader(128));
+    entry_buffer_.OnIndexedHeader(128);
+  }
+  StrictMock<MockHpackWholeEntryListener> listener2;
+  entry_buffer_.set_listener(&listener2);
+  {
+    InSequence seq;
+    EXPECT_CALL(listener2, OnIndexedHeader(100));
+    entry_buffer_.OnIndexedHeader(100);
+  }
+}
+
+// OnDynamicTableSizeUpdate is an immediate pass through.
+TEST_F(HpackWholeEntryBufferTest, OnDynamicTableSizeUpdate) {
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(4096));
+    entry_buffer_.OnDynamicTableSizeUpdate(4096);
+  }
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(0));
+    entry_buffer_.OnDynamicTableSizeUpdate(0);
+  }
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(1024));
+    entry_buffer_.OnDynamicTableSizeUpdate(1024);
+  }
+  {
+    InSequence seq;
+    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(1024));
+    entry_buffer_.OnDynamicTableSizeUpdate(1024);
+  }
+  StrictMock<MockHpackWholeEntryListener> listener2;
+  entry_buffer_.set_listener(&listener2);
+  {
+    InSequence seq;
+    EXPECT_CALL(listener2, OnDynamicTableSizeUpdate(0));
+    entry_buffer_.OnDynamicTableSizeUpdate(0);
+  }
+}
+
+TEST_F(HpackWholeEntryBufferTest, OnNameIndexAndLiteralValue) {
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kNeverIndexedLiteralHeader,
+                                     123);
+  entry_buffer_.OnValueStart(false, 10);
+  entry_buffer_.OnValueData("some data.", 10);
+
+  // Force the value to be buffered.
+  entry_buffer_.BufferStringsIfUnbuffered();
+
+  EXPECT_CALL(
+      listener_,
+      OnNameIndexAndLiteralValue(
+          HpackEntryType::kNeverIndexedLiteralHeader, 123,
+          AllOf(Property(&HpackDecoderStringBuffer::str, "some data."),
+                Property(&HpackDecoderStringBuffer::BufferedLength, 10))));
+
+  entry_buffer_.OnValueEnd();
+}
+
+TEST_F(HpackWholeEntryBufferTest, OnLiteralNameAndValue) {
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
+  // Force the name to be buffered by delivering it in two pieces.
+  entry_buffer_.OnNameStart(false, 9);
+  entry_buffer_.OnNameData("some-", 5);
+  entry_buffer_.OnNameData("name", 4);
+  entry_buffer_.OnNameEnd();
+  entry_buffer_.OnValueStart(false, 12);
+  entry_buffer_.OnValueData("Header Value", 12);
+
+  EXPECT_CALL(
+      listener_,
+      OnLiteralNameAndValue(
+          HpackEntryType::kIndexedLiteralHeader,
+          AllOf(Property(&HpackDecoderStringBuffer::str, "some-name"),
+                Property(&HpackDecoderStringBuffer::BufferedLength, 9)),
+          AllOf(Property(&HpackDecoderStringBuffer::str, "Header Value"),
+                Property(&HpackDecoderStringBuffer::BufferedLength, 0))));
+
+  entry_buffer_.OnValueEnd();
+}
+
+// Verify that a name longer than the allowed size generates an error.
+TEST_F(HpackWholeEntryBufferTest, NameTooLong) {
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
+  EXPECT_CALL(listener_,
+              OnHpackDecodeError(HpackDecodingError::kNameTooLong, _));
+  entry_buffer_.OnNameStart(false, kMaxStringSize + 1);
+}
+
+// Verify that a value longer than the allowed size generates an error.
+TEST_F(HpackWholeEntryBufferTest, ValueTooLong) {
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
+  EXPECT_CALL(listener_,
+              OnHpackDecodeError(
+                  HpackDecodingError::kValueTooLong,
+                  "Value length (21) of [path] is longer than permitted (20)"));
+  entry_buffer_.OnNameStart(false, 4);
+  entry_buffer_.OnNameData("path", 4);
+  entry_buffer_.OnNameEnd();
+  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
+}
+
+// Regression test for b/162141899.
+TEST_F(HpackWholeEntryBufferTest, ValueTooLongWithoutName) {
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 1);
+  EXPECT_CALL(listener_,
+              OnHpackDecodeError(
+                  HpackDecodingError::kValueTooLong,
+                  "Value length (21) of [] is longer than permitted (20)"));
+  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
+}
+
+// Verify that a Huffman encoded name with an explicit EOS generates an error
+// for an explicit EOS.
+TEST_F(HpackWholeEntryBufferTest, NameHuffmanError) {
+  const char data[] = "\xff\xff\xff";
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kUnindexedLiteralHeader,
+                                     0);
+  entry_buffer_.OnNameStart(true, 4);
+  entry_buffer_.OnNameData(data, 3);
+
+  EXPECT_CALL(listener_,
+              OnHpackDecodeError(HpackDecodingError::kNameHuffmanError, _));
+
+  entry_buffer_.OnNameData(data, 1);
+
+  // After an error is reported, the listener is not called again.
+  EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(8096)).Times(0);
+  entry_buffer_.OnDynamicTableSizeUpdate(8096);
+}
+
+// Verify that a Huffman encoded value that isn't properly terminated with
+// a partial EOS symbol generates an error.
+TEST_F(HpackWholeEntryBufferTest, ValueHuffmanError) {
+  const char data[] = "\x00\x00\x00";
+  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kNeverIndexedLiteralHeader,
+                                     61);
+  entry_buffer_.OnValueStart(true, 3);
+  entry_buffer_.OnValueData(data, 3);
+
+  EXPECT_CALL(listener_,
+              OnHpackDecodeError(HpackDecodingError::kValueHuffmanError, _));
+
+  entry_buffer_.OnValueEnd();
+
+  // After an error is reported, the listener is not called again.
+  EXPECT_CALL(listener_, OnIndexedHeader(17)).Times(0);
+  entry_buffer_.OnIndexedHeader(17);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_whole_entry_listener.cc b/quiche/http2/hpack/decoder/hpack_whole_entry_listener.cc
new file mode 100644
index 0000000..cafd6ec
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_whole_entry_listener.cc
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/decoder/hpack_whole_entry_listener.h"
+
+namespace http2 {
+
+HpackWholeEntryListener::~HpackWholeEntryListener() = default;
+
+HpackWholeEntryNoOpListener::~HpackWholeEntryNoOpListener() = default;
+
+void HpackWholeEntryNoOpListener::OnIndexedHeader(size_t /*index*/) {}
+void HpackWholeEntryNoOpListener::OnNameIndexAndLiteralValue(
+    HpackEntryType /*entry_type*/,
+    size_t /*name_index*/,
+    HpackDecoderStringBuffer* /*value_buffer*/) {}
+void HpackWholeEntryNoOpListener::OnLiteralNameAndValue(
+    HpackEntryType /*entry_type*/,
+    HpackDecoderStringBuffer* /*name_buffer*/,
+    HpackDecoderStringBuffer* /*value_buffer*/) {}
+void HpackWholeEntryNoOpListener::OnDynamicTableSizeUpdate(size_t /*size*/) {}
+void HpackWholeEntryNoOpListener::OnHpackDecodeError(
+    HpackDecodingError /*error*/,
+    std::string /*detailed_error*/) {}
+
+// static
+HpackWholeEntryNoOpListener* HpackWholeEntryNoOpListener::NoOpListener() {
+  static HpackWholeEntryNoOpListener* static_instance =
+      new HpackWholeEntryNoOpListener();
+  return static_instance;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/decoder/hpack_whole_entry_listener.h b/quiche/http2/hpack/decoder/hpack_whole_entry_listener.h
new file mode 100644
index 0000000..0e710ab
--- /dev/null
+++ b/quiche/http2/hpack/decoder/hpack_whole_entry_listener.h
@@ -0,0 +1,82 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Defines HpackWholeEntryListener, the base class of listeners for decoded
+// complete HPACK entries, as opposed to HpackEntryDecoderListener which
+// receives multiple callbacks for some single entries.
+
+#ifndef QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_LISTENER_H_
+#define QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_LISTENER_H_
+
+#include <stddef.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_string_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+class QUICHE_EXPORT_PRIVATE HpackWholeEntryListener {
+ public:
+  virtual ~HpackWholeEntryListener();
+
+  // Called when an indexed header (i.e. one in the static or dynamic table) has
+  // been decoded from an HPACK block. index is supposed to be non-zero, but
+  // that has not been checked by the caller.
+  virtual void OnIndexedHeader(size_t index) = 0;
+
+  // Called when a header entry with a name index and literal value has
+  // been fully decoded from an HPACK block. name_index is NOT zero.
+  // entry_type will be kIndexedLiteralHeader, kUnindexedLiteralHeader, or
+  // kNeverIndexedLiteralHeader.
+  virtual void OnNameIndexAndLiteralValue(
+      HpackEntryType entry_type,
+      size_t name_index,
+      HpackDecoderStringBuffer* value_buffer) = 0;
+
+  // Called when a header entry with a literal name and literal value
+  // has been fully decoded from an HPACK block. entry_type will be
+  // kIndexedLiteralHeader, kUnindexedLiteralHeader, or
+  // kNeverIndexedLiteralHeader.
+  virtual void OnLiteralNameAndValue(
+      HpackEntryType entry_type,
+      HpackDecoderStringBuffer* name_buffer,
+      HpackDecoderStringBuffer* value_buffer) = 0;
+
+  // Called when an update to the size of the peer's dynamic table has been
+  // decoded.
+  virtual void OnDynamicTableSizeUpdate(size_t size) = 0;
+
+  // OnHpackDecodeError is called if an error is detected while decoding.
+  virtual void OnHpackDecodeError(HpackDecodingError error,
+                                  std::string detailed_error) = 0;
+};
+
+// A no-op implementation of HpackWholeEntryDecoderListener, useful for ignoring
+// callbacks once an error is detected.
+class HpackWholeEntryNoOpListener : public HpackWholeEntryListener {
+ public:
+  ~HpackWholeEntryNoOpListener() override;
+
+  void OnIndexedHeader(size_t index) override;
+  void OnNameIndexAndLiteralValue(
+      HpackEntryType entry_type,
+      size_t name_index,
+      HpackDecoderStringBuffer* value_buffer) override;
+  void OnLiteralNameAndValue(HpackEntryType entry_type,
+                             HpackDecoderStringBuffer* name_buffer,
+                             HpackDecoderStringBuffer* value_buffer) override;
+  void OnDynamicTableSizeUpdate(size_t size) override;
+  void OnHpackDecodeError(HpackDecodingError error,
+                          std::string detailed_error) override;
+
+  // Returns a listener that ignores all the calls.
+  static HpackWholeEntryNoOpListener* NoOpListener();
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_DECODER_HPACK_WHOLE_ENTRY_LISTENER_H_
diff --git a/http2/hpack/hpack_static_table_entries.inc b/quiche/http2/hpack/hpack_static_table_entries.inc
similarity index 100%
rename from http2/hpack/hpack_static_table_entries.inc
rename to quiche/http2/hpack/hpack_static_table_entries.inc
diff --git a/quiche/http2/hpack/http2_hpack_constants.cc b/quiche/http2/hpack/http2_hpack_constants.cc
new file mode 100644
index 0000000..e4a71b8
--- /dev/null
+++ b/quiche/http2/hpack/http2_hpack_constants.cc
@@ -0,0 +1,31 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+
+#include "absl/strings/str_cat.h"
+
+namespace http2 {
+
+std::string HpackEntryTypeToString(HpackEntryType v) {
+  switch (v) {
+    case HpackEntryType::kIndexedHeader:
+      return "kIndexedHeader";
+    case HpackEntryType::kDynamicTableSizeUpdate:
+      return "kDynamicTableSizeUpdate";
+    case HpackEntryType::kIndexedLiteralHeader:
+      return "kIndexedLiteralHeader";
+    case HpackEntryType::kUnindexedLiteralHeader:
+      return "kUnindexedLiteralHeader";
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      return "kNeverIndexedLiteralHeader";
+  }
+  return absl::StrCat("UnknownHpackEntryType(", static_cast<int>(v), ")");
+}
+
+std::ostream& operator<<(std::ostream& out, HpackEntryType v) {
+  return out << HpackEntryTypeToString(v);
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/http2_hpack_constants.h b/quiche/http2/hpack/http2_hpack_constants.h
new file mode 100644
index 0000000..a10b140
--- /dev/null
+++ b/quiche/http2/hpack/http2_hpack_constants.h
@@ -0,0 +1,63 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
+#define QUICHE_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
+
+// Enum HpackEntryType identifies the 5 basic types of HPACK Block Entries.
+//
+// See the spec for details:
+// https://http2.github.io/http2-spec/compression.html#rfc.section.6
+
+#include <ostream>
+#include <string>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+const size_t kFirstDynamicTableIndex = 62;
+
+enum class HpackEntryType {
+  // Entry is an index into the static or dynamic table. Decoding it has no
+  // effect on the dynamic table.
+  kIndexedHeader,
+
+  // The entry contains a literal value. The name may be either a literal or a
+  // reference to an entry in the static or dynamic table.
+  // The entry is added to the dynamic table after decoding.
+  kIndexedLiteralHeader,
+
+  // The entry contains a literal value. The name may be either a literal or a
+  // reference to an entry in the static or dynamic table.
+  // The entry is not added to the dynamic table after decoding, but a proxy
+  // may choose to insert the entry into its dynamic table when forwarding
+  // to another endpoint.
+  kUnindexedLiteralHeader,
+
+  // The entry contains a literal value. The name may be either a literal or a
+  // reference to an entry in the static or dynamic table.
+  // The entry is not added to the dynamic table after decoding, and a proxy
+  // must NOT insert the entry into its dynamic table when forwarding to another
+  // endpoint.
+  kNeverIndexedLiteralHeader,
+
+  // Entry conveys the size limit of the dynamic table of the encoder to
+  // the decoder. May be used to flush the table by sending a zero and then
+  // resetting the size back up to the maximum that the encoder will use
+  // (within the limits of SETTINGS_HEADER_TABLE_SIZE sent by the
+  // decoder to the encoder, with the default of 4096 assumed).
+  kDynamicTableSizeUpdate,
+};
+
+// Returns the name of the enum member.
+QUICHE_EXPORT_PRIVATE std::string HpackEntryTypeToString(HpackEntryType v);
+
+// Inserts the name of the enum member into |out|.
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               HpackEntryType v);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
diff --git a/quiche/http2/hpack/http2_hpack_constants_test.cc b/quiche/http2/hpack/http2_hpack_constants_test.cc
new file mode 100644
index 0000000..277492e
--- /dev/null
+++ b/quiche/http2/hpack/http2_hpack_constants_test.cc
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+
+#include <sstream>
+
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+TEST(HpackEntryTypeTest, HpackEntryTypeToString) {
+  EXPECT_EQ("kIndexedHeader",
+            HpackEntryTypeToString(HpackEntryType::kIndexedHeader));
+  EXPECT_EQ("kDynamicTableSizeUpdate",
+            HpackEntryTypeToString(HpackEntryType::kDynamicTableSizeUpdate));
+  EXPECT_EQ("kIndexedLiteralHeader",
+            HpackEntryTypeToString(HpackEntryType::kIndexedLiteralHeader));
+  EXPECT_EQ("kUnindexedLiteralHeader",
+            HpackEntryTypeToString(HpackEntryType::kUnindexedLiteralHeader));
+  EXPECT_EQ("kNeverIndexedLiteralHeader",
+            HpackEntryTypeToString(HpackEntryType::kNeverIndexedLiteralHeader));
+  EXPECT_EQ("UnknownHpackEntryType(12321)",
+            HpackEntryTypeToString(static_cast<HpackEntryType>(12321)));
+}
+
+TEST(HpackEntryTypeTest, OutputHpackEntryType) {
+  {
+    std::stringstream log;
+    log << HpackEntryType::kIndexedHeader;
+    EXPECT_EQ("kIndexedHeader", log.str());
+  }
+  {
+    std::stringstream log;
+    log << HpackEntryType::kDynamicTableSizeUpdate;
+    EXPECT_EQ("kDynamicTableSizeUpdate", log.str());
+  }
+  {
+    std::stringstream log;
+    log << HpackEntryType::kIndexedLiteralHeader;
+    EXPECT_EQ("kIndexedLiteralHeader", log.str());
+  }
+  {
+    std::stringstream log;
+    log << HpackEntryType::kUnindexedLiteralHeader;
+    EXPECT_EQ("kUnindexedLiteralHeader", log.str());
+  }
+  {
+    std::stringstream log;
+    log << HpackEntryType::kNeverIndexedLiteralHeader;
+    EXPECT_EQ("kNeverIndexedLiteralHeader", log.str());
+  }
+  {
+    std::stringstream log;
+    log << static_cast<HpackEntryType>(1234321);
+    EXPECT_EQ("UnknownHpackEntryType(1234321)", log.str());
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_decoder.cc b/quiche/http2/hpack/huffman/hpack_huffman_decoder.cc
new file mode 100644
index 0000000..6a026a4
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_decoder.cc
@@ -0,0 +1,485 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
+
+#include <bitset>
+#include <limits>
+
+#include "quiche/http2/platform/api/http2_logging.h"
+
+// Terminology:
+//
+// Symbol - a plain text (unencoded) character (uint8), or the End-of-String
+//          (EOS) symbol, 256.
+//
+// Code - the sequence of bits used to encode a symbol, varying in length from
+//        5 bits for the most common symbols (e.g. '0', '1', and 'a'), to
+//        30 bits for the least common (e.g. the EOS symbol).
+//        For those symbols whose codes have the same length, their code values
+//        are sorted such that the lower symbol value has a lower code value.
+//
+// Canonical - a symbol's cardinal value when sorted first by code length, and
+//             then by symbol value. For example, canonical 0 is for ASCII '0'
+//             (uint8 value 0x30), which is the first of the symbols whose code
+//             is 5 bits long, and the last canonical is EOS, which is the last
+//             of the symbols whose code is 30 bits long.
+
+namespace http2 {
+namespace {
+
+// HuffmanCode is used to store the codes associated with symbols (a pattern of
+// from 5 to 30 bits).
+typedef uint32_t HuffmanCode;
+
+// HuffmanCodeBitCount is used to store a count of bits in a code.
+typedef uint16_t HuffmanCodeBitCount;
+
+// HuffmanCodeBitSet is used for producing a string version of a code because
+// std::bitset logs nicely.
+typedef std::bitset<32> HuffmanCodeBitSet;
+typedef std::bitset<64> HuffmanAccumulatorBitSet;
+
+static constexpr HuffmanCodeBitCount kMinCodeBitCount = 5;
+static constexpr HuffmanCodeBitCount kMaxCodeBitCount = 30;
+static constexpr HuffmanCodeBitCount kHuffmanCodeBitCount =
+    std::numeric_limits<HuffmanCode>::digits;
+
+static_assert(std::numeric_limits<HuffmanCode>::digits >= kMaxCodeBitCount,
+              "HuffmanCode isn't big enough.");
+
+static_assert(std::numeric_limits<HuffmanAccumulator>::digits >=
+                  kMaxCodeBitCount,
+              "HuffmanAccumulator isn't big enough.");
+
+static constexpr HuffmanAccumulatorBitCount kHuffmanAccumulatorBitCount =
+    std::numeric_limits<HuffmanAccumulator>::digits;
+static constexpr HuffmanAccumulatorBitCount kExtraAccumulatorBitCount =
+    kHuffmanAccumulatorBitCount - kHuffmanCodeBitCount;
+
+// PrefixInfo holds info about a group of codes that are all of the same length.
+struct PrefixInfo {
+  // Given the leading bits (32 in this case) of the encoded string, and that
+  // they start with a code of length |code_length|, return the corresponding
+  // canonical for that leading code.
+  uint32_t DecodeToCanonical(HuffmanCode bits) const {
+    // What is the position of the canonical symbol being decoded within
+    // the canonical symbols of |length|?
+    HuffmanCode ordinal_in_length =
+        ((bits - first_code) >> (kHuffmanCodeBitCount - code_length));
+
+    // Combined with |canonical| to produce the position of the canonical symbol
+    // being decoded within all of the canonical symbols.
+    return first_canonical + ordinal_in_length;
+  }
+
+  const HuffmanCode first_code;  // First code of this length, left justified in
+                                 // the field (i.e. the first bit of the code is
+                                 // the high-order bit).
+  const uint16_t code_length;    // Length of the prefix code |base|.
+  const uint16_t first_canonical;  // First canonical symbol of this length.
+};
+
+inline std::ostream& operator<<(std::ostream& out, const PrefixInfo& v) {
+  return out << "{first_code: " << HuffmanCodeBitSet(v.first_code)
+             << ", code_length: " << v.code_length
+             << ", first_canonical: " << v.first_canonical << "}";
+}
+
+// Given |value|, a sequence of the leading bits remaining to be decoded,
+// figure out which group of canonicals (by code length) that value starts
+// with. This function was generated.
+PrefixInfo PrefixToInfo(HuffmanCode value) {
+  if (value < 0b10111000000000000000000000000000) {
+    if (value < 0b01010000000000000000000000000000) {
+      return {0b00000000000000000000000000000000, 5, 0};
+    } else {
+      return {0b01010000000000000000000000000000, 6, 10};
+    }
+  } else {
+    if (value < 0b11111110000000000000000000000000) {
+      if (value < 0b11111000000000000000000000000000) {
+        return {0b10111000000000000000000000000000, 7, 36};
+      } else {
+        return {0b11111000000000000000000000000000, 8, 68};
+      }
+    } else {
+      if (value < 0b11111111110000000000000000000000) {
+        if (value < 0b11111111101000000000000000000000) {
+          if (value < 0b11111111010000000000000000000000) {
+            return {0b11111110000000000000000000000000, 10, 74};
+          } else {
+            return {0b11111111010000000000000000000000, 11, 79};
+          }
+        } else {
+          return {0b11111111101000000000000000000000, 12, 82};
+        }
+      } else {
+        if (value < 0b11111111111111100000000000000000) {
+          if (value < 0b11111111111110000000000000000000) {
+            if (value < 0b11111111111100000000000000000000) {
+              return {0b11111111110000000000000000000000, 13, 84};
+            } else {
+              return {0b11111111111100000000000000000000, 14, 90};
+            }
+          } else {
+            return {0b11111111111110000000000000000000, 15, 92};
+          }
+        } else {
+          if (value < 0b11111111111111110100100000000000) {
+            if (value < 0b11111111111111101110000000000000) {
+              if (value < 0b11111111111111100110000000000000) {
+                return {0b11111111111111100000000000000000, 19, 95};
+              } else {
+                return {0b11111111111111100110000000000000, 20, 98};
+              }
+            } else {
+              return {0b11111111111111101110000000000000, 21, 106};
+            }
+          } else {
+            if (value < 0b11111111111111111110101000000000) {
+              if (value < 0b11111111111111111011000000000000) {
+                return {0b11111111111111110100100000000000, 22, 119};
+              } else {
+                return {0b11111111111111111011000000000000, 23, 145};
+              }
+            } else {
+              if (value < 0b11111111111111111111101111000000) {
+                if (value < 0b11111111111111111111100000000000) {
+                  if (value < 0b11111111111111111111011000000000) {
+                    return {0b11111111111111111110101000000000, 24, 174};
+                  } else {
+                    return {0b11111111111111111111011000000000, 25, 186};
+                  }
+                } else {
+                  return {0b11111111111111111111100000000000, 26, 190};
+                }
+              } else {
+                if (value < 0b11111111111111111111111111110000) {
+                  if (value < 0b11111111111111111111111000100000) {
+                    return {0b11111111111111111111101111000000, 27, 205};
+                  } else {
+                    return {0b11111111111111111111111000100000, 28, 224};
+                  }
+                } else {
+                  return {0b11111111111111111111111111110000, 30, 253};
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+// Mapping from canonical symbol (0 to 255) to actual symbol.
+// clang-format off
+constexpr unsigned char kCanonicalToSymbol[] = {
+    '0',  '1',  '2',  'a',  'c',  'e',  'i',  'o',
+    's',  't',  0x20, '%',  '-',  '.',  '/',  '3',
+    '4',  '5',  '6',  '7',  '8',  '9',  '=',  'A',
+    '_',  'b',  'd',  'f',  'g',  'h',  'l',  'm',
+    'n',  'p',  'r',  'u',  ':',  'B',  'C',  'D',
+    'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L',
+    'M',  'N',  'O',  'P',  'Q',  'R',  'S',  'T',
+    'U',  'V',  'W',  'Y',  'j',  'k',  'q',  'v',
+    'w',  'x',  'y',  'z',  '&',  '*',  ',',  ';',
+    'X',  'Z',  '!',  '\"', '(',  ')',  '?',  '\'',
+    '+',  '|',  '#',  '>',  0x00, '$',  '@',  '[',
+    ']',  '~',  '^',  '}',  '<',  '`',  '{',  '\\',
+    0xc3, 0xd0, 0x80, 0x82, 0x83, 0xa2, 0xb8, 0xc2,
+    0xe0, 0xe2, 0x99, 0xa1, 0xa7, 0xac, 0xb0, 0xb1,
+    0xb3, 0xd1, 0xd8, 0xd9, 0xe3, 0xe5, 0xe6, 0x81,
+    0x84, 0x85, 0x86, 0x88, 0x92, 0x9a, 0x9c, 0xa0,
+    0xa3, 0xa4, 0xa9, 0xaa, 0xad, 0xb2, 0xb5, 0xb9,
+    0xba, 0xbb, 0xbd, 0xbe, 0xc4, 0xc6, 0xe4, 0xe8,
+    0xe9, 0x01, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
+    0x8f, 0x93, 0x95, 0x96, 0x97, 0x98, 0x9b, 0x9d,
+    0x9e, 0xa5, 0xa6, 0xa8, 0xae, 0xaf, 0xb4, 0xb6,
+    0xb7, 0xbc, 0xbf, 0xc5, 0xe7, 0xef, 0x09, 0x8e,
+    0x90, 0x91, 0x94, 0x9f, 0xab, 0xce, 0xd7, 0xe1,
+    0xec, 0xed, 0xc7, 0xcf, 0xea, 0xeb, 0xc0, 0xc1,
+    0xc8, 0xc9, 0xca, 0xcd, 0xd2, 0xd5, 0xda, 0xdb,
+    0xee, 0xf0, 0xf2, 0xf3, 0xff, 0xcb, 0xcc, 0xd3,
+    0xd4, 0xd6, 0xdd, 0xde, 0xdf, 0xf1, 0xf4, 0xf5,
+    0xf6, 0xf7, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
+    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0b,
+    0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+    0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+    0x1e, 0x1f, 0x7f, 0xdc, 0xf9, 0x0a, 0x0d, 0x16,
+};
+// clang-format on
+
+constexpr size_t kShortCodeTableSize = 124;
+struct ShortCodeInfo {
+  uint8_t symbol;
+  uint8_t length;
+} kShortCodeTable[kShortCodeTableSize] = {
+    {0x30, 5},  // Match: 0b0000000, Symbol: 0
+    {0x30, 5},  // Match: 0b0000001, Symbol: 0
+    {0x30, 5},  // Match: 0b0000010, Symbol: 0
+    {0x30, 5},  // Match: 0b0000011, Symbol: 0
+    {0x31, 5},  // Match: 0b0000100, Symbol: 1
+    {0x31, 5},  // Match: 0b0000101, Symbol: 1
+    {0x31, 5},  // Match: 0b0000110, Symbol: 1
+    {0x31, 5},  // Match: 0b0000111, Symbol: 1
+    {0x32, 5},  // Match: 0b0001000, Symbol: 2
+    {0x32, 5},  // Match: 0b0001001, Symbol: 2
+    {0x32, 5},  // Match: 0b0001010, Symbol: 2
+    {0x32, 5},  // Match: 0b0001011, Symbol: 2
+    {0x61, 5},  // Match: 0b0001100, Symbol: a
+    {0x61, 5},  // Match: 0b0001101, Symbol: a
+    {0x61, 5},  // Match: 0b0001110, Symbol: a
+    {0x61, 5},  // Match: 0b0001111, Symbol: a
+    {0x63, 5},  // Match: 0b0010000, Symbol: c
+    {0x63, 5},  // Match: 0b0010001, Symbol: c
+    {0x63, 5},  // Match: 0b0010010, Symbol: c
+    {0x63, 5},  // Match: 0b0010011, Symbol: c
+    {0x65, 5},  // Match: 0b0010100, Symbol: e
+    {0x65, 5},  // Match: 0b0010101, Symbol: e
+    {0x65, 5},  // Match: 0b0010110, Symbol: e
+    {0x65, 5},  // Match: 0b0010111, Symbol: e
+    {0x69, 5},  // Match: 0b0011000, Symbol: i
+    {0x69, 5},  // Match: 0b0011001, Symbol: i
+    {0x69, 5},  // Match: 0b0011010, Symbol: i
+    {0x69, 5},  // Match: 0b0011011, Symbol: i
+    {0x6f, 5},  // Match: 0b0011100, Symbol: o
+    {0x6f, 5},  // Match: 0b0011101, Symbol: o
+    {0x6f, 5},  // Match: 0b0011110, Symbol: o
+    {0x6f, 5},  // Match: 0b0011111, Symbol: o
+    {0x73, 5},  // Match: 0b0100000, Symbol: s
+    {0x73, 5},  // Match: 0b0100001, Symbol: s
+    {0x73, 5},  // Match: 0b0100010, Symbol: s
+    {0x73, 5},  // Match: 0b0100011, Symbol: s
+    {0x74, 5},  // Match: 0b0100100, Symbol: t
+    {0x74, 5},  // Match: 0b0100101, Symbol: t
+    {0x74, 5},  // Match: 0b0100110, Symbol: t
+    {0x74, 5},  // Match: 0b0100111, Symbol: t
+    {0x20, 6},  // Match: 0b0101000, Symbol: (space)
+    {0x20, 6},  // Match: 0b0101001, Symbol: (space)
+    {0x25, 6},  // Match: 0b0101010, Symbol: %
+    {0x25, 6},  // Match: 0b0101011, Symbol: %
+    {0x2d, 6},  // Match: 0b0101100, Symbol: -
+    {0x2d, 6},  // Match: 0b0101101, Symbol: -
+    {0x2e, 6},  // Match: 0b0101110, Symbol: .
+    {0x2e, 6},  // Match: 0b0101111, Symbol: .
+    {0x2f, 6},  // Match: 0b0110000, Symbol: /
+    {0x2f, 6},  // Match: 0b0110001, Symbol: /
+    {0x33, 6},  // Match: 0b0110010, Symbol: 3
+    {0x33, 6},  // Match: 0b0110011, Symbol: 3
+    {0x34, 6},  // Match: 0b0110100, Symbol: 4
+    {0x34, 6},  // Match: 0b0110101, Symbol: 4
+    {0x35, 6},  // Match: 0b0110110, Symbol: 5
+    {0x35, 6},  // Match: 0b0110111, Symbol: 5
+    {0x36, 6},  // Match: 0b0111000, Symbol: 6
+    {0x36, 6},  // Match: 0b0111001, Symbol: 6
+    {0x37, 6},  // Match: 0b0111010, Symbol: 7
+    {0x37, 6},  // Match: 0b0111011, Symbol: 7
+    {0x38, 6},  // Match: 0b0111100, Symbol: 8
+    {0x38, 6},  // Match: 0b0111101, Symbol: 8
+    {0x39, 6},  // Match: 0b0111110, Symbol: 9
+    {0x39, 6},  // Match: 0b0111111, Symbol: 9
+    {0x3d, 6},  // Match: 0b1000000, Symbol: =
+    {0x3d, 6},  // Match: 0b1000001, Symbol: =
+    {0x41, 6},  // Match: 0b1000010, Symbol: A
+    {0x41, 6},  // Match: 0b1000011, Symbol: A
+    {0x5f, 6},  // Match: 0b1000100, Symbol: _
+    {0x5f, 6},  // Match: 0b1000101, Symbol: _
+    {0x62, 6},  // Match: 0b1000110, Symbol: b
+    {0x62, 6},  // Match: 0b1000111, Symbol: b
+    {0x64, 6},  // Match: 0b1001000, Symbol: d
+    {0x64, 6},  // Match: 0b1001001, Symbol: d
+    {0x66, 6},  // Match: 0b1001010, Symbol: f
+    {0x66, 6},  // Match: 0b1001011, Symbol: f
+    {0x67, 6},  // Match: 0b1001100, Symbol: g
+    {0x67, 6},  // Match: 0b1001101, Symbol: g
+    {0x68, 6},  // Match: 0b1001110, Symbol: h
+    {0x68, 6},  // Match: 0b1001111, Symbol: h
+    {0x6c, 6},  // Match: 0b1010000, Symbol: l
+    {0x6c, 6},  // Match: 0b1010001, Symbol: l
+    {0x6d, 6},  // Match: 0b1010010, Symbol: m
+    {0x6d, 6},  // Match: 0b1010011, Symbol: m
+    {0x6e, 6},  // Match: 0b1010100, Symbol: n
+    {0x6e, 6},  // Match: 0b1010101, Symbol: n
+    {0x70, 6},  // Match: 0b1010110, Symbol: p
+    {0x70, 6},  // Match: 0b1010111, Symbol: p
+    {0x72, 6},  // Match: 0b1011000, Symbol: r
+    {0x72, 6},  // Match: 0b1011001, Symbol: r
+    {0x75, 6},  // Match: 0b1011010, Symbol: u
+    {0x75, 6},  // Match: 0b1011011, Symbol: u
+    {0x3a, 7},  // Match: 0b1011100, Symbol: :
+    {0x42, 7},  // Match: 0b1011101, Symbol: B
+    {0x43, 7},  // Match: 0b1011110, Symbol: C
+    {0x44, 7},  // Match: 0b1011111, Symbol: D
+    {0x45, 7},  // Match: 0b1100000, Symbol: E
+    {0x46, 7},  // Match: 0b1100001, Symbol: F
+    {0x47, 7},  // Match: 0b1100010, Symbol: G
+    {0x48, 7},  // Match: 0b1100011, Symbol: H
+    {0x49, 7},  // Match: 0b1100100, Symbol: I
+    {0x4a, 7},  // Match: 0b1100101, Symbol: J
+    {0x4b, 7},  // Match: 0b1100110, Symbol: K
+    {0x4c, 7},  // Match: 0b1100111, Symbol: L
+    {0x4d, 7},  // Match: 0b1101000, Symbol: M
+    {0x4e, 7},  // Match: 0b1101001, Symbol: N
+    {0x4f, 7},  // Match: 0b1101010, Symbol: O
+    {0x50, 7},  // Match: 0b1101011, Symbol: P
+    {0x51, 7},  // Match: 0b1101100, Symbol: Q
+    {0x52, 7},  // Match: 0b1101101, Symbol: R
+    {0x53, 7},  // Match: 0b1101110, Symbol: S
+    {0x54, 7},  // Match: 0b1101111, Symbol: T
+    {0x55, 7},  // Match: 0b1110000, Symbol: U
+    {0x56, 7},  // Match: 0b1110001, Symbol: V
+    {0x57, 7},  // Match: 0b1110010, Symbol: W
+    {0x59, 7},  // Match: 0b1110011, Symbol: Y
+    {0x6a, 7},  // Match: 0b1110100, Symbol: j
+    {0x6b, 7},  // Match: 0b1110101, Symbol: k
+    {0x71, 7},  // Match: 0b1110110, Symbol: q
+    {0x76, 7},  // Match: 0b1110111, Symbol: v
+    {0x77, 7},  // Match: 0b1111000, Symbol: w
+    {0x78, 7},  // Match: 0b1111001, Symbol: x
+    {0x79, 7},  // Match: 0b1111010, Symbol: y
+    {0x7a, 7},  // Match: 0b1111011, Symbol: z
+};
+
+}  // namespace
+
+HuffmanBitBuffer::HuffmanBitBuffer() {
+  Reset();
+}
+
+void HuffmanBitBuffer::Reset() {
+  accumulator_ = 0;
+  count_ = 0;
+}
+
+size_t HuffmanBitBuffer::AppendBytes(absl::string_view input) {
+  HuffmanAccumulatorBitCount free_cnt = free_count();
+  size_t bytes_available = input.size();
+  if (free_cnt < 8 || bytes_available == 0) {
+    return 0;
+  }
+
+  // Top up |accumulator_| until there isn't room for a whole byte.
+  size_t bytes_used = 0;
+  auto* ptr = reinterpret_cast<const uint8_t*>(input.data());
+  do {
+    auto b = static_cast<HuffmanAccumulator>(*ptr++);
+    free_cnt -= 8;
+    accumulator_ |= (b << free_cnt);
+    ++bytes_used;
+  } while (free_cnt >= 8 && bytes_used < bytes_available);
+  count_ += (bytes_used * 8);
+  return bytes_used;
+}
+
+HuffmanAccumulatorBitCount HuffmanBitBuffer::free_count() const {
+  return kHuffmanAccumulatorBitCount - count_;
+}
+
+void HuffmanBitBuffer::ConsumeBits(HuffmanAccumulatorBitCount code_length) {
+  QUICHE_DCHECK_LE(code_length, count_);
+  accumulator_ <<= code_length;
+  count_ -= code_length;
+}
+
+bool HuffmanBitBuffer::InputProperlyTerminated() const {
+  auto cnt = count();
+  if (cnt < 8) {
+    if (cnt == 0) {
+      return true;
+    }
+    HuffmanAccumulator expected = ~(~HuffmanAccumulator() >> cnt);
+    // We expect all the bits below the high order |cnt| bits of accumulator_
+    // to be cleared as we perform left shift operations while decoding.
+    QUICHE_DCHECK_EQ(accumulator_ & ~expected, 0u)
+        << "\n  expected: " << HuffmanAccumulatorBitSet(expected) << "\n  "
+        << *this;
+    return accumulator_ == expected;
+  }
+  return false;
+}
+
+std::string HuffmanBitBuffer::DebugString() const {
+  std::stringstream ss;
+  ss << "{accumulator: " << HuffmanAccumulatorBitSet(accumulator_)
+     << "; count: " << count_ << "}";
+  return ss.str();
+}
+
+HpackHuffmanDecoder::HpackHuffmanDecoder() = default;
+
+HpackHuffmanDecoder::~HpackHuffmanDecoder() = default;
+
+bool HpackHuffmanDecoder::Decode(absl::string_view input, std::string* output) {
+  HTTP2_DVLOG(1) << "HpackHuffmanDecoder::Decode";
+
+  // Fill bit_buffer_ from input.
+  input.remove_prefix(bit_buffer_.AppendBytes(input));
+
+  while (true) {
+    HTTP2_DVLOG(3) << "Enter Decode Loop, bit_buffer_: " << bit_buffer_;
+    if (bit_buffer_.count() >= 7) {
+      // Get high 7 bits of the bit buffer, see if that contains a complete
+      // code of 5, 6 or 7 bits.
+      uint8_t short_code =
+          bit_buffer_.value() >> (kHuffmanAccumulatorBitCount - 7);
+      QUICHE_DCHECK_LT(short_code, 128);
+      if (short_code < kShortCodeTableSize) {
+        ShortCodeInfo info = kShortCodeTable[short_code];
+        bit_buffer_.ConsumeBits(info.length);
+        output->push_back(static_cast<char>(info.symbol));
+        continue;
+      }
+      // The code is more than 7 bits long. Use PrefixToInfo, etc. to decode
+      // longer codes.
+    } else {
+      // We may have (mostly) drained bit_buffer_. If we can top it up, try
+      // using the table decoder above.
+      size_t byte_count = bit_buffer_.AppendBytes(input);
+      if (byte_count > 0) {
+        input.remove_prefix(byte_count);
+        continue;
+      }
+    }
+
+    HuffmanCode code_prefix = bit_buffer_.value() >> kExtraAccumulatorBitCount;
+    HTTP2_DVLOG(3) << "code_prefix: " << HuffmanCodeBitSet(code_prefix);
+
+    PrefixInfo prefix_info = PrefixToInfo(code_prefix);
+    HTTP2_DVLOG(3) << "prefix_info: " << prefix_info;
+    QUICHE_DCHECK_LE(kMinCodeBitCount, prefix_info.code_length);
+    QUICHE_DCHECK_LE(prefix_info.code_length, kMaxCodeBitCount);
+
+    if (prefix_info.code_length <= bit_buffer_.count()) {
+      // We have enough bits for one code.
+      uint32_t canonical = prefix_info.DecodeToCanonical(code_prefix);
+      if (canonical < 256) {
+        // Valid code.
+        char c = kCanonicalToSymbol[canonical];
+        output->push_back(c);
+        bit_buffer_.ConsumeBits(prefix_info.code_length);
+        continue;
+      }
+      // Encoder is not supposed to explicity encode the EOS symbol.
+      HTTP2_DLOG(ERROR) << "EOS explicitly encoded!\n " << bit_buffer_ << "\n "
+                        << prefix_info;
+      return false;
+    }
+    // bit_buffer_ doesn't have enough bits in it to decode the next symbol.
+    // Append to it as many bytes as are available AND fit.
+    size_t byte_count = bit_buffer_.AppendBytes(input);
+    if (byte_count == 0) {
+      QUICHE_DCHECK_EQ(input.size(), 0u);
+      return true;
+    }
+    input.remove_prefix(byte_count);
+  }
+}
+
+std::string HpackHuffmanDecoder::DebugString() const {
+  return bit_buffer_.DebugString();
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_decoder.h b/quiche/http2/hpack/huffman/hpack_huffman_decoder.h
new file mode 100644
index 0000000..9befd6c
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_decoder.h
@@ -0,0 +1,134 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_DECODER_H_
+#define QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_DECODER_H_
+
+// HpackHuffmanDecoder is an incremental decoder of strings that have been
+// encoded using the Huffman table defined in the HPACK spec.
+// By incremental, we mean that the HpackHuffmanDecoder::Decode method does
+// not require the entire string to be provided, and can instead decode the
+// string as fragments of it become available (e.g. as HPACK block fragments
+// are received for decoding by HpackEntryDecoder).
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <iosfwd>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// HuffmanAccumulator is used to store bits during decoding, e.g. next N bits
+// that have not yet been decoded, but have been extracted from the encoded
+// string).  An advantage of using a uint64 for the accumulator
+// is that it has room for the bits of the longest code plus the bits of a full
+// byte; that means that when adding more bits to the accumulator, it can always
+// be done in whole bytes. For example, if we currently have 26 bits in the
+// accumulator, and need more to decode the current symbol, we can add a whole
+// byte to the accumulator, and not have to do juggling with adding 6 bits (to
+// reach 30), and then keep track of the last two bits we've not been able to
+// add to the accumulator.
+typedef uint64_t HuffmanAccumulator;
+typedef size_t HuffmanAccumulatorBitCount;
+
+// HuffmanBitBuffer stores the leading edge of bits to be decoded. The high
+// order bit of accumulator_ is the next bit to be decoded.
+class QUICHE_EXPORT_PRIVATE HuffmanBitBuffer {
+ public:
+  HuffmanBitBuffer();
+
+  // Prepare for decoding a new Huffman encoded string.
+  void Reset();
+
+  // Add as many whole bytes to the accumulator (accumulator_) as possible,
+  // returning the number of bytes added.
+  size_t AppendBytes(absl::string_view input);
+
+  // Get the bits of the accumulator.
+  HuffmanAccumulator value() const { return accumulator_; }
+
+  // Number of bits of the encoded string that are in the accumulator
+  // (accumulator_).
+  HuffmanAccumulatorBitCount count() const { return count_; }
+
+  // Are there no bits in the accumulator?
+  bool IsEmpty() const { return count_ == 0; }
+
+  // Number of additional bits that can be added to the accumulator.
+  HuffmanAccumulatorBitCount free_count() const;
+
+  // Consume the leading |code_length| bits of the accumulator.
+  void ConsumeBits(HuffmanAccumulatorBitCount code_length);
+
+  // Are the contents valid for the end of a Huffman encoded string? The RFC
+  // states that EOS (end-of-string) symbol must not be explicitly encoded in
+  // the bit stream, but any unused bits in the final byte must be set to the
+  // prefix of the EOS symbol, which is all 1 bits. So there can be at most 7
+  // such bits.
+  // Returns true if the bit buffer is empty, or contains at most 7 bits, all
+  // of them 1. Otherwise returns false.
+  bool InputProperlyTerminated() const;
+
+  std::string DebugString() const;
+
+ private:
+  HuffmanAccumulator accumulator_;
+  HuffmanAccumulatorBitCount count_;
+};
+
+inline std::ostream& operator<<(std::ostream& out, const HuffmanBitBuffer& v) {
+  return out << v.DebugString();
+}
+
+class QUICHE_EXPORT_PRIVATE HpackHuffmanDecoder {
+ public:
+  HpackHuffmanDecoder();
+  ~HpackHuffmanDecoder();
+
+  // Prepare for decoding a new Huffman encoded string.
+  void Reset() { bit_buffer_.Reset(); }
+
+  // Decode the portion of a HPACK Huffman encoded string that is in |input|,
+  // appending the decoded symbols into |*output|, stopping when more bits are
+  // needed to determine the next symbol, which/ means that the input has been
+  // drained, and also that the bit_buffer_ is empty or that the bits that are
+  // in it are not a whole symbol.
+  // If |input| is the start of a string, the caller must first call Reset.
+  // If |input| includes the end of the encoded string, the caller must call
+  // InputProperlyTerminated after Decode has returned true in order to
+  // determine if the encoded string was properly terminated.
+  // Returns false if something went wrong (e.g. the encoding contains the code
+  // EOS symbol). Otherwise returns true, in which case input has been fully
+  // decoded or buffered; in particular, if the low-order bit of the final byte
+  // of the input is not the last bit of an encoded symbol, then bit_buffer_
+  // will contain the leading bits of the code for that symbol, but not the
+  // final bits of that code.
+  // Note that output should be empty, but that it is not cleared by Decode().
+  bool Decode(absl::string_view input, std::string* output);
+
+  // Is what remains in the bit_buffer_ valid at the end of an encoded string?
+  // Call after passing the the final portion of a Huffman string to Decode,
+  // and getting true as the result.
+  bool InputProperlyTerminated() const {
+    return bit_buffer_.InputProperlyTerminated();
+  }
+
+  std::string DebugString() const;
+
+ private:
+  HuffmanBitBuffer bit_buffer_;
+};
+
+inline std::ostream& operator<<(std::ostream& out,
+                                const HpackHuffmanDecoder& v) {
+  return out << v.DebugString();
+}
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_DECODER_H_
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_decoder_test.cc b/quiche/http2/hpack/huffman/hpack_huffman_decoder_test.cc
new file mode 100644
index 0000000..d73acd5
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_decoder_test.cc
@@ -0,0 +1,242 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
+
+// Tests of HpackHuffmanDecoder and HuffmanBitBuffer.
+
+#include <iostream>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+TEST(HuffmanBitBufferTest, Reset) {
+  HuffmanBitBuffer bb;
+  EXPECT_TRUE(bb.IsEmpty());
+  EXPECT_TRUE(bb.InputProperlyTerminated());
+  EXPECT_EQ(bb.count(), 0u);
+  EXPECT_EQ(bb.free_count(), 64u);
+  EXPECT_EQ(bb.value(), 0u);
+}
+
+TEST(HuffmanBitBufferTest, AppendBytesAligned) {
+  std::string s;
+  s.push_back('\x11');
+  s.push_back('\x22');
+  s.push_back('\x33');
+  absl::string_view sp(s);
+
+  HuffmanBitBuffer bb;
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_TRUE(sp.empty());
+  EXPECT_FALSE(bb.IsEmpty()) << bb;
+  EXPECT_FALSE(bb.InputProperlyTerminated());
+  EXPECT_EQ(bb.count(), 24u) << bb;
+  EXPECT_EQ(bb.free_count(), 40u) << bb;
+  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 40) << bb;
+
+  s.clear();
+  s.push_back('\x44');
+  sp = s;
+
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_TRUE(sp.empty());
+  EXPECT_EQ(bb.count(), 32u) << bb;
+  EXPECT_EQ(bb.free_count(), 32u) << bb;
+  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x11223344) << 32) << bb;
+
+  s.clear();
+  s.push_back('\x55');
+  s.push_back('\x66');
+  s.push_back('\x77');
+  s.push_back('\x88');
+  s.push_back('\x99');
+  sp = s;
+
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_EQ(sp.size(), 1u);
+  EXPECT_EQ('\x99', sp[0]);
+  EXPECT_EQ(bb.count(), 64u) << bb;
+  EXPECT_EQ(bb.free_count(), 0u) << bb;
+  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
+
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_EQ(sp.size(), 1u);
+  EXPECT_EQ('\x99', sp[0]);
+  EXPECT_EQ(bb.count(), 64u) << bb;
+  EXPECT_EQ(bb.free_count(), 0u) << bb;
+  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
+}
+
+TEST(HuffmanBitBufferTest, ConsumeBits) {
+  std::string s;
+  s.push_back('\x11');
+  s.push_back('\x22');
+  s.push_back('\x33');
+  absl::string_view sp(s);
+
+  HuffmanBitBuffer bb;
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_TRUE(sp.empty());
+
+  bb.ConsumeBits(1);
+  EXPECT_EQ(bb.count(), 23u) << bb;
+  EXPECT_EQ(bb.free_count(), 41u) << bb;
+  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 41) << bb;
+
+  bb.ConsumeBits(20);
+  EXPECT_EQ(bb.count(), 3u) << bb;
+  EXPECT_EQ(bb.free_count(), 61u) << bb;
+  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x3) << 61) << bb;
+}
+
+TEST(HuffmanBitBufferTest, AppendBytesUnaligned) {
+  std::string s;
+  s.push_back('\x11');
+  s.push_back('\x22');
+  s.push_back('\x33');
+  s.push_back('\x44');
+  s.push_back('\x55');
+  s.push_back('\x66');
+  s.push_back('\x77');
+  s.push_back('\x88');
+  s.push_back('\x99');
+  s.push_back('\xaa');
+  s.push_back('\xbb');
+  s.push_back('\xcc');
+  s.push_back('\xdd');
+  absl::string_view sp(s);
+
+  HuffmanBitBuffer bb;
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_EQ(sp.size(), 5u);
+  EXPECT_FALSE(bb.InputProperlyTerminated());
+
+  bb.ConsumeBits(15);
+  EXPECT_EQ(bb.count(), 49u) << bb;
+  EXPECT_EQ(bb.free_count(), 15u) << bb;
+
+  HuffmanAccumulator expected(0x1122334455667788);
+  expected <<= 15;
+  EXPECT_EQ(bb.value(), expected);
+
+  sp.remove_prefix(bb.AppendBytes(sp));
+  EXPECT_EQ(sp.size(), 4u);
+  EXPECT_EQ(bb.count(), 57u) << bb;
+  EXPECT_EQ(bb.free_count(), 7u) << bb;
+
+  expected |= (HuffmanAccumulator(0x99) << 7);
+  EXPECT_EQ(bb.value(), expected)
+      << bb << std::hex << "\n   actual: " << bb.value()
+      << "\n expected: " << expected;
+}
+
+class HpackHuffmanDecoderTest : public RandomDecoderTest {
+ protected:
+  HpackHuffmanDecoderTest() {
+    // The decoder may return true, and its accumulator may be empty, at
+    // many boundaries while decoding, and yet the whole string hasn't
+    // been decoded.
+    stop_decode_on_done_ = false;
+  }
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    input_bytes_seen_ = 0;
+    output_buffer_.clear();
+    decoder_.Reset();
+    return ResumeDecoding(b);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    input_bytes_seen_ += b->Remaining();
+    absl::string_view sp(b->cursor(), b->Remaining());
+    if (decoder_.Decode(sp, &output_buffer_)) {
+      b->AdvanceCursor(b->Remaining());
+      // Successfully decoded (or buffered) the bytes in absl::string_view.
+      EXPECT_LE(input_bytes_seen_, input_bytes_expected_);
+      // Have we reached the end of the encoded string?
+      if (input_bytes_expected_ == input_bytes_seen_) {
+        if (decoder_.InputProperlyTerminated()) {
+          return DecodeStatus::kDecodeDone;
+        } else {
+          return DecodeStatus::kDecodeError;
+        }
+      }
+      return DecodeStatus::kDecodeInProgress;
+    }
+    return DecodeStatus::kDecodeError;
+  }
+
+  HpackHuffmanDecoder decoder_;
+  std::string output_buffer_;
+  size_t input_bytes_seen_;
+  size_t input_bytes_expected_;
+};
+
+TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) {
+  HpackHuffmanDecoder decoder;
+  std::string test_table[] = {
+      absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff"),
+      "www.example.com",
+      absl::HexStringToBytes("a8eb10649cbf"),
+      "no-cache",
+      absl::HexStringToBytes("25a849e95ba97d7f"),
+      "custom-key",
+      absl::HexStringToBytes("25a849e95bb8e8b4bf"),
+      "custom-value",
+  };
+  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
+    const std::string& huffman_encoded(test_table[i]);
+    const std::string& plain_string(test_table[i + 1]);
+    std::string buffer;
+    decoder.Reset();
+    EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
+    EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
+    EXPECT_EQ(buffer, plain_string);
+  }
+}
+
+TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) {
+  HpackHuffmanDecoder decoder;
+  // clang-format off
+  std::string test_table[] = {
+    absl::HexStringToBytes("6402"),
+    "302",
+    absl::HexStringToBytes("aec3771a4b"),
+    "private",
+    absl::HexStringToBytes("d07abe941054d444a8200595040b8166"
+            "e082a62d1bff"),
+    "Mon, 21 Oct 2013 20:13:21 GMT",
+    absl::HexStringToBytes("9d29ad171863c78f0b97c8e9ae82ae43"
+            "d3"),
+    "https://www.example.com",
+    absl::HexStringToBytes("94e7821dd7f2e6c7b335dfdfcd5b3960"
+            "d5af27087f3672c1ab270fb5291f9587"
+            "316065c003ed4ee5b1063d5007"),
+    "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
+  };
+  // clang-format on
+  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
+    const std::string& huffman_encoded(test_table[i]);
+    const std::string& plain_string(test_table[i + 1]);
+    std::string buffer;
+    decoder.Reset();
+    EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
+    EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
+    EXPECT_EQ(buffer, plain_string);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_encoder.cc b/quiche/http2/hpack/huffman/hpack_huffman_encoder.cc
new file mode 100644
index 0000000..b5e3404
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_encoder.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+
+#include "quiche/http2/hpack/huffman/huffman_spec_tables.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+size_t HuffmanSize(absl::string_view plain) {
+  size_t bits = 0;
+  for (const uint8_t c : plain) {
+    bits += HuffmanSpecTables::kCodeLengths[c];
+  }
+  return (bits + 7) / 8;
+}
+
+void HuffmanEncode(absl::string_view plain,
+                   size_t encoded_size,
+                   std::string* huffman) {
+  QUICHE_DCHECK(huffman != nullptr);
+  huffman->reserve(huffman->size() + encoded_size);
+  uint64_t bit_buffer = 0;  // High-bit is next bit to output. Not clear if that
+                            // is more performant than having the low-bit be the
+                            // last to be output.
+  size_t bits_unused = 64;  // Number of bits available for the next code.
+  for (uint8_t c : plain) {
+    size_t code_length = HuffmanSpecTables::kCodeLengths[c];
+    if (bits_unused < code_length) {
+      // There isn't enough room in bit_buffer for the code of c.
+      // Flush until bits_unused > 56 (i.e. 64 - 8).
+      do {
+        char h = static_cast<char>(bit_buffer >> 56);
+        bit_buffer <<= 8;
+        bits_unused += 8;
+        // Perhaps would be more efficient if we populated an array of chars,
+        // so we don't have to call push_back each time. Reconsider if used
+        // for production.
+        huffman->push_back(h);
+      } while (bits_unused <= 56);
+    }
+    uint64_t code = HuffmanSpecTables::kRightCodes[c];
+    size_t shift_by = bits_unused - code_length;
+    bit_buffer |= (code << shift_by);
+    bits_unused -= code_length;
+  }
+  // bit_buffer contains (64-bits_unused) bits that still need to be flushed.
+  // Output whole bytes until we don't have any whole bytes left.
+  size_t bits_used = 64 - bits_unused;
+  while (bits_used >= 8) {
+    char h = static_cast<char>(bit_buffer >> 56);
+    bit_buffer <<= 8;
+    bits_used -= 8;
+    huffman->push_back(h);
+  }
+  if (bits_used > 0) {
+    // We have less than a byte left to output. The spec calls for padding out
+    // the final byte with the leading bits of the EOS symbol (30 1-bits).
+    constexpr uint64_t leading_eos_bits = 0b11111111;
+    bit_buffer |= (leading_eos_bits << (56 - bits_used));
+    char h = static_cast<char>(bit_buffer >> 56);
+    huffman->push_back(h);
+  }
+}
+
+void HuffmanEncodeFast(absl::string_view input,
+                       size_t encoded_size,
+                       std::string* output) {
+  const size_t original_size = output->size();
+  const size_t final_size = original_size + encoded_size;
+  // Reserve an extra four bytes to avoid accessing unallocated memory (even
+  // though it would only be OR'd with zeros and thus not modified).
+  output->resize(final_size + 4, 0);
+
+  // Pointer to first appended byte.
+  char* const first = &*output->begin() + original_size;
+  size_t bit_counter = 0;
+  for (uint8_t c : input) {
+    // Align the Huffman code to byte boundaries as it needs to be written.
+    // The longest Huffman code is 30 bits long, and it can be shifted by up to
+    // 7 bits, requiring 37 bits in total.  The most significant 25 bits and
+    // least significant 2 bits of |code| are always zero.
+    uint64_t code = static_cast<uint64_t>(HuffmanSpecTables::kLeftCodes[c])
+                    << (8 - (bit_counter % 8));
+    // The byte where the first bit of |code| needs to be written.
+    char* const current = first + (bit_counter / 8);
+
+    bit_counter += HuffmanSpecTables::kCodeLengths[c];
+
+    *current |= code >> 32;
+
+    // Do not check if this write is zero before executing it, because with
+    // uniformly random shifts and an ideal random input distribution
+    // corresponding to the Huffman tree it would only be zero in 29% of the
+    // cases.
+    *(current + 1) |= (code >> 24) & 0xff;
+
+    // Continue to next input character if there is nothing else to write.
+    // (If next byte is zero, then rest must also be zero.)
+    if ((code & 0xff0000) == 0) {
+      continue;
+    }
+    *(current + 2) |= (code >> 16) & 0xff;
+
+    // Continue to next input character if there is nothing else to write.
+    // (If next byte is zero, then rest must also be zero.)
+    if ((code & 0xff00) == 0) {
+      continue;
+    }
+    *(current + 3) |= (code >> 8) & 0xff;
+
+    // Do not check if this write is zero, because the check would probably be
+    // as expensive as the write.
+    *(current + 4) |= code & 0xff;
+  }
+
+  QUICHE_DCHECK_EQ(encoded_size, (bit_counter + 7) / 8);
+
+  // EOF
+  if (bit_counter % 8 != 0) {
+    *(first + encoded_size - 1) |= 0xff >> (bit_counter & 7);
+  }
+
+  output->resize(final_size);
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_encoder.h b/quiche/http2/hpack/huffman/hpack_huffman_encoder.h
new file mode 100644
index 0000000..7e73187
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_encoder.h
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_
+#define QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_
+
+// Functions supporting the encoding of strings using the HPACK-defined Huffman
+// table.
+
+#include <cstddef>  // For size_t
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// Returns the size of the Huffman encoding of |plain|, which may be greater
+// than plain.size().
+QUICHE_EXPORT_PRIVATE size_t HuffmanSize(absl::string_view plain);
+
+// Encode the plain text string |plain| with the Huffman encoding defined in the
+// HPACK RFC, 7541.  |encoded_size| is used to pre-allocate storage and it
+// should be the value returned by HuffmanSize().  Appends the result to
+// |*huffman|.
+QUICHE_EXPORT_PRIVATE void HuffmanEncode(absl::string_view plain,
+                                         size_t encoded_size,
+                                         std::string* huffman);
+
+// Encode |input| with the Huffman encoding defined RFC7541, used in HPACK and
+// QPACK.  |encoded_size| must be the value returned by HuffmanSize().
+// Appends the result to the end of |*output|.
+QUICHE_EXPORT_PRIVATE void HuffmanEncodeFast(absl::string_view input,
+                                             size_t encoded_size,
+                                             std::string* output);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_HUFFMAN_HPACK_HUFFMAN_ENCODER_H_
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_encoder_test.cc b/quiche/http2/hpack/huffman/hpack_huffman_encoder_test.cc
new file mode 100644
index 0000000..a670b03
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_encoder_test.cc
@@ -0,0 +1,131 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace {
+
+class HuffmanEncoderTest : public ::testing::TestWithParam<bool> {
+ protected:
+  HuffmanEncoderTest() : use_fast_encoder_(GetParam()) {}
+  virtual ~HuffmanEncoderTest() = default;
+
+  void Encode(absl::string_view input,
+              size_t encoded_size,
+              std::string* output) {
+    use_fast_encoder_ ? HuffmanEncodeFast(input, encoded_size, output)
+                      : HuffmanEncode(input, encoded_size, output);
+  }
+
+  const bool use_fast_encoder_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TwoEncoders, HuffmanEncoderTest, ::testing::Bool());
+
+TEST_P(HuffmanEncoderTest, Empty) {
+  std::string empty("");
+  size_t encoded_size = HuffmanSize(empty);
+  EXPECT_EQ(0u, encoded_size);
+
+  std::string buffer;
+  Encode(empty, encoded_size, &buffer);
+  EXPECT_EQ("", buffer);
+}
+
+TEST_P(HuffmanEncoderTest, SpecRequestExamples) {
+  std::string test_table[] = {
+      absl::HexStringToBytes("f1e3c2e5f23a6ba0ab90f4ff"),
+      "www.example.com",
+      absl::HexStringToBytes("a8eb10649cbf"),
+      "no-cache",
+      absl::HexStringToBytes("25a849e95ba97d7f"),
+      "custom-key",
+      absl::HexStringToBytes("25a849e95bb8e8b4bf"),
+      "custom-value",
+  };
+  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
+    const std::string& huffman_encoded(test_table[i]);
+    const std::string& plain_string(test_table[i + 1]);
+    size_t encoded_size = HuffmanSize(plain_string);
+    EXPECT_EQ(huffman_encoded.size(), encoded_size);
+    std::string buffer;
+    buffer.reserve();
+    Encode(plain_string, encoded_size, &buffer);
+    EXPECT_EQ(buffer, huffman_encoded) << "Error encoding " << plain_string;
+  }
+}
+
+TEST_P(HuffmanEncoderTest, SpecResponseExamples) {
+  // clang-format off
+  std::string test_table[] = {
+    absl::HexStringToBytes("6402"),
+    "302",
+    absl::HexStringToBytes("aec3771a4b"),
+    "private",
+    absl::HexStringToBytes("d07abe941054d444a8200595040b8166"
+            "e082a62d1bff"),
+    "Mon, 21 Oct 2013 20:13:21 GMT",
+    absl::HexStringToBytes("9d29ad171863c78f0b97c8e9ae82ae43"
+            "d3"),
+    "https://www.example.com",
+    absl::HexStringToBytes("94e7821dd7f2e6c7b335dfdfcd5b3960"
+            "d5af27087f3672c1ab270fb5291f9587"
+            "316065c003ed4ee5b1063d5007"),
+    "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
+  };
+  // clang-format on
+  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) {
+    const std::string& huffman_encoded(test_table[i]);
+    const std::string& plain_string(test_table[i + 1]);
+    size_t encoded_size = HuffmanSize(plain_string);
+    EXPECT_EQ(huffman_encoded.size(), encoded_size);
+    std::string buffer;
+    Encode(plain_string, encoded_size, &buffer);
+    EXPECT_EQ(buffer, huffman_encoded) << "Error encoding " << plain_string;
+  }
+}
+
+TEST_P(HuffmanEncoderTest, EncodedSizeAgreesWithEncodeString) {
+  std::string test_table[] = {
+      "",
+      "Mon, 21 Oct 2013 20:13:21 GMT",
+      "https://www.example.com",
+      "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
+      std::string(1, '\0'),
+      std::string("foo\0bar", 7),
+      std::string(256, '\0'),
+  };
+  // Modify last |test_table| entry to cover all codes.
+  for (size_t i = 0; i != 256; ++i) {
+    test_table[ABSL_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i);
+  }
+
+  for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); ++i) {
+    const std::string& plain_string = test_table[i];
+    size_t encoded_size = HuffmanSize(plain_string);
+    std::string huffman_encoded;
+    Encode(plain_string, encoded_size, &huffman_encoded);
+    EXPECT_EQ(encoded_size, huffman_encoded.size());
+  }
+}
+
+// Test that encoding appends to output without overwriting it.
+TEST_P(HuffmanEncoderTest, AppendToOutput) {
+  size_t encoded_size = HuffmanSize("foo");
+  std::string buffer;
+  Encode("foo", encoded_size, &buffer);
+  EXPECT_EQ(absl::HexStringToBytes("94e7"), buffer);
+
+  encoded_size = HuffmanSize("bar");
+  Encode("bar", encoded_size, &buffer);
+  EXPECT_EQ(absl::HexStringToBytes("94e78c767f"), buffer);
+}
+
+}  // namespace
+}  // namespace http2
diff --git a/quiche/http2/hpack/huffman/hpack_huffman_transcoder_test.cc b/quiche/http2/hpack/huffman/hpack_huffman_transcoder_test.cc
new file mode 100644
index 0000000..8d57ec9
--- /dev/null
+++ b/quiche/http2/hpack/huffman/hpack_huffman_transcoder_test.cc
@@ -0,0 +1,183 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A test of roundtrips through the encoder and decoder.
+
+#include <stddef.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using ::testing::AssertionSuccess;
+using ::testing::Combine;
+using ::testing::Range;
+using ::testing::Values;
+
+namespace http2 {
+namespace test {
+namespace {
+
+std::string GenAsciiNonControlSet() {
+  std::string s;
+  const char space = ' ';  // First character after the control characters: 0x20
+  const char del = 127;    // First character after the non-control characters.
+  for (char c = space; c < del; ++c) {
+    s.push_back(c);
+  }
+  return s;
+}
+
+class HpackHuffmanTranscoderTest : public RandomDecoderTest {
+ protected:
+  HpackHuffmanTranscoderTest()
+      : ascii_non_control_set_(GenAsciiNonControlSet()) {
+    // The decoder may return true, and its accumulator may be empty, at
+    // many boundaries while decoding, and yet the whole string hasn't
+    // been decoded.
+    stop_decode_on_done_ = false;
+  }
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    input_bytes_seen_ = 0;
+    output_buffer_.clear();
+    decoder_.Reset();
+    return ResumeDecoding(b);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    input_bytes_seen_ += b->Remaining();
+    absl::string_view sp(b->cursor(), b->Remaining());
+    if (decoder_.Decode(sp, &output_buffer_)) {
+      b->AdvanceCursor(b->Remaining());
+      // Successfully decoded (or buffered) the bytes in absl::string_view.
+      EXPECT_LE(input_bytes_seen_, input_bytes_expected_);
+      // Have we reached the end of the encoded string?
+      if (input_bytes_expected_ == input_bytes_seen_) {
+        if (decoder_.InputProperlyTerminated()) {
+          return DecodeStatus::kDecodeDone;
+        } else {
+          return DecodeStatus::kDecodeError;
+        }
+      }
+      return DecodeStatus::kDecodeInProgress;
+    }
+    return DecodeStatus::kDecodeError;
+  }
+
+  AssertionResult TranscodeAndValidateSeveralWays(
+      absl::string_view plain,
+      absl::string_view expected_huffman) {
+    size_t encoded_size = HuffmanSize(plain);
+    std::string encoded;
+    HuffmanEncode(plain, encoded_size, &encoded);
+    VERIFY_EQ(encoded_size, encoded.size());
+    if (!expected_huffman.empty() || plain.empty()) {
+      VERIFY_EQ(encoded, expected_huffman);
+    }
+    input_bytes_expected_ = encoded.size();
+    auto validator = [plain, this]() -> AssertionResult {
+      VERIFY_EQ(output_buffer_.size(), plain.size());
+      VERIFY_EQ(output_buffer_, plain);
+      return AssertionSuccess();
+    };
+    DecodeBuffer db(encoded);
+    bool return_non_zero_on_first = false;
+    return DecodeAndValidateSeveralWays(&db, return_non_zero_on_first,
+                                        ValidateDoneAndEmpty(validator));
+  }
+
+  AssertionResult TranscodeAndValidateSeveralWays(absl::string_view plain) {
+    return TranscodeAndValidateSeveralWays(plain, "");
+  }
+
+  std::string RandomAsciiNonControlString(int length) {
+    return Random().RandStringWithAlphabet(length, ascii_non_control_set_);
+  }
+
+  std::string RandomBytes(int length) { return Random().RandString(length); }
+
+  const std::string ascii_non_control_set_;
+  HpackHuffmanDecoder decoder_;
+  std::string output_buffer_;
+  size_t input_bytes_seen_;
+  size_t input_bytes_expected_;
+};
+
+TEST_F(HpackHuffmanTranscoderTest, RoundTripRandomAsciiNonControlString) {
+  for (size_t length = 0; length != 20; length++) {
+    const std::string s = RandomAsciiNonControlString(length);
+    ASSERT_TRUE(TranscodeAndValidateSeveralWays(s))
+        << "Unable to decode:\n\n"
+        << quiche::QuicheTextUtils::HexDump(s) << "\n\noutput_buffer_:\n"
+        << quiche::QuicheTextUtils::HexDump(output_buffer_);
+  }
+}
+
+TEST_F(HpackHuffmanTranscoderTest, RoundTripRandomBytes) {
+  for (size_t length = 0; length != 20; length++) {
+    const std::string s = RandomBytes(length);
+    ASSERT_TRUE(TranscodeAndValidateSeveralWays(s))
+        << "Unable to decode:\n\n"
+        << quiche::QuicheTextUtils::HexDump(s) << "\n\noutput_buffer_:\n"
+        << quiche::QuicheTextUtils::HexDump(output_buffer_);
+  }
+}
+
+// Two parameters: decoder choice, and the character to round-trip.
+class HpackHuffmanTranscoderAdjacentCharTest
+    : public HpackHuffmanTranscoderTest,
+      public testing::WithParamInterface<int> {
+ protected:
+  HpackHuffmanTranscoderAdjacentCharTest()
+      : c_(static_cast<char>(GetParam())) {}
+
+  const char c_;
+};
+
+INSTANTIATE_TEST_SUITE_P(HpackHuffmanTranscoderAdjacentCharTest,
+                         HpackHuffmanTranscoderAdjacentCharTest, Range(0, 256));
+
+// Test c_ adjacent to every other character, both before and after.
+TEST_P(HpackHuffmanTranscoderAdjacentCharTest, RoundTripAdjacentChar) {
+  std::string s;
+  for (int a = 0; a < 256; ++a) {
+    s.push_back(static_cast<char>(a));
+    s.push_back(c_);
+    s.push_back(static_cast<char>(a));
+  }
+  ASSERT_TRUE(TranscodeAndValidateSeveralWays(s));
+}
+
+// Two parameters: character to repeat, number of repeats.
+class HpackHuffmanTranscoderRepeatedCharTest
+    : public HpackHuffmanTranscoderTest,
+      public testing::WithParamInterface<std::tuple<int, int>> {
+ protected:
+  HpackHuffmanTranscoderRepeatedCharTest()
+      : c_(static_cast<char>(std::get<0>(GetParam()))),
+        length_(std::get<1>(GetParam())) {}
+  std::string MakeString() { return std::string(length_, c_); }
+
+ private:
+  const char c_;
+  const size_t length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(HpackHuffmanTranscoderRepeatedCharTest,
+                         HpackHuffmanTranscoderRepeatedCharTest,
+                         Combine(Range(0, 256), Values(1, 2, 3, 4, 8, 16, 32)));
+
+TEST_P(HpackHuffmanTranscoderRepeatedCharTest, RoundTripRepeatedChar) {
+  ASSERT_TRUE(TranscodeAndValidateSeveralWays(MakeString()));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/huffman/huffman_spec_tables.cc b/quiche/http2/hpack/huffman/huffman_spec_tables.cc
new file mode 100644
index 0000000..f4b103b
--- /dev/null
+++ b/quiche/http2/hpack/huffman/huffman_spec_tables.cc
@@ -0,0 +1,572 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/huffman/huffman_spec_tables.h"
+
+namespace http2 {
+
+// clang-format off
+// static
+const uint8_t HuffmanSpecTables::kCodeLengths[] = {
+    13, 23, 28, 28, 28, 28, 28, 28,  //   0 -   7
+    28, 24, 30, 28, 28, 30, 28, 28,  //   8 -  15
+    28, 28, 28, 28, 28, 28, 30, 28,  //  16 -  23
+    28, 28, 28, 28, 28, 28, 28, 28,  //  24 -  31
+     6, 10, 10, 12, 13,  6,  8, 11,  //  32 -  39
+    10, 10,  8, 11,  8,  6,  6,  6,  //  40 -  47
+     5,  5,  5,  6,  6,  6,  6,  6,  //  48 -  55
+     6,  6,  7,  8, 15,  6, 12, 10,  //  56 -  63
+    13,  6,  7,  7,  7,  7,  7,  7,  //  64 -  71
+     7,  7,  7,  7,  7,  7,  7,  7,  //  72 -  79
+     7,  7,  7,  7,  7,  7,  7,  7,  //  80 -  87
+     8,  7,  8, 13, 19, 13, 14,  6,  //  88 -  95
+    15,  5,  6,  5,  6,  5,  6,  6,  //  96 - 103
+     6,  5,  7,  7,  6,  6,  6,  5,  // 104 - 111
+     6,  7,  6,  5,  5,  6,  7,  7,  // 112 - 119
+     7,  7,  7, 15, 11, 14, 13, 28,  // 120 - 127
+    20, 22, 20, 20, 22, 22, 22, 23,  // 128 - 135
+    22, 23, 23, 23, 23, 23, 24, 23,  // 136 - 143
+    24, 24, 22, 23, 24, 23, 23, 23,  // 144 - 151
+    23, 21, 22, 23, 22, 23, 23, 24,  // 152 - 159
+    22, 21, 20, 22, 22, 23, 23, 21,  // 160 - 167
+    23, 22, 22, 24, 21, 22, 23, 23,  // 168 - 175
+    21, 21, 22, 21, 23, 22, 23, 23,  // 176 - 183
+    20, 22, 22, 22, 23, 22, 22, 23,  // 184 - 191
+    26, 26, 20, 19, 22, 23, 22, 25,  // 192 - 199
+    26, 26, 26, 27, 27, 26, 24, 25,  // 200 - 207
+    19, 21, 26, 27, 27, 26, 27, 24,  // 208 - 215
+    21, 21, 26, 26, 28, 27, 27, 27,  // 216 - 223
+    20, 24, 20, 21, 22, 21, 21, 23,  // 224 - 231
+    22, 22, 25, 25, 24, 24, 26, 23,  // 232 - 239
+    26, 27, 26, 26, 27, 27, 27, 27,  // 240 - 247
+    27, 28, 27, 27, 27, 27, 27, 26,  // 248 - 255
+    30,                              // 256
+};
+
+// The encoding of each symbol, left justified (as printed), which means that
+// the first bit of the encoding is the high-order bit of the uint32.
+// static
+const uint32_t HuffmanSpecTables::kLeftCodes[] = {
+    0b11111111110000000000000000000000,  // 0x00
+    0b11111111111111111011000000000000,  // 0x01
+    0b11111111111111111111111000100000,  // 0x02
+    0b11111111111111111111111000110000,  // 0x03
+    0b11111111111111111111111001000000,  // 0x04
+    0b11111111111111111111111001010000,  // 0x05
+    0b11111111111111111111111001100000,  // 0x06
+    0b11111111111111111111111001110000,  // 0x07
+    0b11111111111111111111111010000000,  // 0x08
+    0b11111111111111111110101000000000,  // 0x09
+    0b11111111111111111111111111110000,  // 0x0a
+    0b11111111111111111111111010010000,  // 0x0b
+    0b11111111111111111111111010100000,  // 0x0c
+    0b11111111111111111111111111110100,  // 0x0d
+    0b11111111111111111111111010110000,  // 0x0e
+    0b11111111111111111111111011000000,  // 0x0f
+    0b11111111111111111111111011010000,  // 0x10
+    0b11111111111111111111111011100000,  // 0x11
+    0b11111111111111111111111011110000,  // 0x12
+    0b11111111111111111111111100000000,  // 0x13
+    0b11111111111111111111111100010000,  // 0x14
+    0b11111111111111111111111100100000,  // 0x15
+    0b11111111111111111111111111111000,  // 0x16
+    0b11111111111111111111111100110000,  // 0x17
+    0b11111111111111111111111101000000,  // 0x18
+    0b11111111111111111111111101010000,  // 0x19
+    0b11111111111111111111111101100000,  // 0x1a
+    0b11111111111111111111111101110000,  // 0x1b
+    0b11111111111111111111111110000000,  // 0x1c
+    0b11111111111111111111111110010000,  // 0x1d
+    0b11111111111111111111111110100000,  // 0x1e
+    0b11111111111111111111111110110000,  // 0x1f
+    0b01010000000000000000000000000000,  // 0x20
+    0b11111110000000000000000000000000,  // '!'
+    0b11111110010000000000000000000000,  // '\"'
+    0b11111111101000000000000000000000,  // '#'
+    0b11111111110010000000000000000000,  // '$'
+    0b01010100000000000000000000000000,  // '%'
+    0b11111000000000000000000000000000,  // '&'
+    0b11111111010000000000000000000000,  // '\''
+    0b11111110100000000000000000000000,  // '('
+    0b11111110110000000000000000000000,  // ')'
+    0b11111001000000000000000000000000,  // '*'
+    0b11111111011000000000000000000000,  // '+'
+    0b11111010000000000000000000000000,  // ','
+    0b01011000000000000000000000000000,  // '-'
+    0b01011100000000000000000000000000,  // '.'
+    0b01100000000000000000000000000000,  // '/'
+    0b00000000000000000000000000000000,  // '0'
+    0b00001000000000000000000000000000,  // '1'
+    0b00010000000000000000000000000000,  // '2'
+    0b01100100000000000000000000000000,  // '3'
+    0b01101000000000000000000000000000,  // '4'
+    0b01101100000000000000000000000000,  // '5'
+    0b01110000000000000000000000000000,  // '6'
+    0b01110100000000000000000000000000,  // '7'
+    0b01111000000000000000000000000000,  // '8'
+    0b01111100000000000000000000000000,  // '9'
+    0b10111000000000000000000000000000,  // ':'
+    0b11111011000000000000000000000000,  // ';'
+    0b11111111111110000000000000000000,  // '<'
+    0b10000000000000000000000000000000,  // '='
+    0b11111111101100000000000000000000,  // '>'
+    0b11111111000000000000000000000000,  // '?'
+    0b11111111110100000000000000000000,  // '@'
+    0b10000100000000000000000000000000,  // 'A'
+    0b10111010000000000000000000000000,  // 'B'
+    0b10111100000000000000000000000000,  // 'C'
+    0b10111110000000000000000000000000,  // 'D'
+    0b11000000000000000000000000000000,  // 'E'
+    0b11000010000000000000000000000000,  // 'F'
+    0b11000100000000000000000000000000,  // 'G'
+    0b11000110000000000000000000000000,  // 'H'
+    0b11001000000000000000000000000000,  // 'I'
+    0b11001010000000000000000000000000,  // 'J'
+    0b11001100000000000000000000000000,  // 'K'
+    0b11001110000000000000000000000000,  // 'L'
+    0b11010000000000000000000000000000,  // 'M'
+    0b11010010000000000000000000000000,  // 'N'
+    0b11010100000000000000000000000000,  // 'O'
+    0b11010110000000000000000000000000,  // 'P'
+    0b11011000000000000000000000000000,  // 'Q'
+    0b11011010000000000000000000000000,  // 'R'
+    0b11011100000000000000000000000000,  // 'S'
+    0b11011110000000000000000000000000,  // 'T'
+    0b11100000000000000000000000000000,  // 'U'
+    0b11100010000000000000000000000000,  // 'V'
+    0b11100100000000000000000000000000,  // 'W'
+    0b11111100000000000000000000000000,  // 'X'
+    0b11100110000000000000000000000000,  // 'Y'
+    0b11111101000000000000000000000000,  // 'Z'
+    0b11111111110110000000000000000000,  // '['
+    0b11111111111111100000000000000000,  // '\\'
+    0b11111111111000000000000000000000,  // ']'
+    0b11111111111100000000000000000000,  // '^'
+    0b10001000000000000000000000000000,  // '_'
+    0b11111111111110100000000000000000,  // '`'
+    0b00011000000000000000000000000000,  // 'a'
+    0b10001100000000000000000000000000,  // 'b'
+    0b00100000000000000000000000000000,  // 'c'
+    0b10010000000000000000000000000000,  // 'd'
+    0b00101000000000000000000000000000,  // 'e'
+    0b10010100000000000000000000000000,  // 'f'
+    0b10011000000000000000000000000000,  // 'g'
+    0b10011100000000000000000000000000,  // 'h'
+    0b00110000000000000000000000000000,  // 'i'
+    0b11101000000000000000000000000000,  // 'j'
+    0b11101010000000000000000000000000,  // 'k'
+    0b10100000000000000000000000000000,  // 'l'
+    0b10100100000000000000000000000000,  // 'm'
+    0b10101000000000000000000000000000,  // 'n'
+    0b00111000000000000000000000000000,  // 'o'
+    0b10101100000000000000000000000000,  // 'p'
+    0b11101100000000000000000000000000,  // 'q'
+    0b10110000000000000000000000000000,  // 'r'
+    0b01000000000000000000000000000000,  // 's'
+    0b01001000000000000000000000000000,  // 't'
+    0b10110100000000000000000000000000,  // 'u'
+    0b11101110000000000000000000000000,  // 'v'
+    0b11110000000000000000000000000000,  // 'w'
+    0b11110010000000000000000000000000,  // 'x'
+    0b11110100000000000000000000000000,  // 'y'
+    0b11110110000000000000000000000000,  // 'z'
+    0b11111111111111000000000000000000,  // '{'
+    0b11111111100000000000000000000000,  // '|'
+    0b11111111111101000000000000000000,  // '}'
+    0b11111111111010000000000000000000,  // '~'
+    0b11111111111111111111111111000000,  // 0x7f
+    0b11111111111111100110000000000000,  // 0x80
+    0b11111111111111110100100000000000,  // 0x81
+    0b11111111111111100111000000000000,  // 0x82
+    0b11111111111111101000000000000000,  // 0x83
+    0b11111111111111110100110000000000,  // 0x84
+    0b11111111111111110101000000000000,  // 0x85
+    0b11111111111111110101010000000000,  // 0x86
+    0b11111111111111111011001000000000,  // 0x87
+    0b11111111111111110101100000000000,  // 0x88
+    0b11111111111111111011010000000000,  // 0x89
+    0b11111111111111111011011000000000,  // 0x8a
+    0b11111111111111111011100000000000,  // 0x8b
+    0b11111111111111111011101000000000,  // 0x8c
+    0b11111111111111111011110000000000,  // 0x8d
+    0b11111111111111111110101100000000,  // 0x8e
+    0b11111111111111111011111000000000,  // 0x8f
+    0b11111111111111111110110000000000,  // 0x90
+    0b11111111111111111110110100000000,  // 0x91
+    0b11111111111111110101110000000000,  // 0x92
+    0b11111111111111111100000000000000,  // 0x93
+    0b11111111111111111110111000000000,  // 0x94
+    0b11111111111111111100001000000000,  // 0x95
+    0b11111111111111111100010000000000,  // 0x96
+    0b11111111111111111100011000000000,  // 0x97
+    0b11111111111111111100100000000000,  // 0x98
+    0b11111111111111101110000000000000,  // 0x99
+    0b11111111111111110110000000000000,  // 0x9a
+    0b11111111111111111100101000000000,  // 0x9b
+    0b11111111111111110110010000000000,  // 0x9c
+    0b11111111111111111100110000000000,  // 0x9d
+    0b11111111111111111100111000000000,  // 0x9e
+    0b11111111111111111110111100000000,  // 0x9f
+    0b11111111111111110110100000000000,  // 0xa0
+    0b11111111111111101110100000000000,  // 0xa1
+    0b11111111111111101001000000000000,  // 0xa2
+    0b11111111111111110110110000000000,  // 0xa3
+    0b11111111111111110111000000000000,  // 0xa4
+    0b11111111111111111101000000000000,  // 0xa5
+    0b11111111111111111101001000000000,  // 0xa6
+    0b11111111111111101111000000000000,  // 0xa7
+    0b11111111111111111101010000000000,  // 0xa8
+    0b11111111111111110111010000000000,  // 0xa9
+    0b11111111111111110111100000000000,  // 0xaa
+    0b11111111111111111111000000000000,  // 0xab
+    0b11111111111111101111100000000000,  // 0xac
+    0b11111111111111110111110000000000,  // 0xad
+    0b11111111111111111101011000000000,  // 0xae
+    0b11111111111111111101100000000000,  // 0xaf
+    0b11111111111111110000000000000000,  // 0xb0
+    0b11111111111111110000100000000000,  // 0xb1
+    0b11111111111111111000000000000000,  // 0xb2
+    0b11111111111111110001000000000000,  // 0xb3
+    0b11111111111111111101101000000000,  // 0xb4
+    0b11111111111111111000010000000000,  // 0xb5
+    0b11111111111111111101110000000000,  // 0xb6
+    0b11111111111111111101111000000000,  // 0xb7
+    0b11111111111111101010000000000000,  // 0xb8
+    0b11111111111111111000100000000000,  // 0xb9
+    0b11111111111111111000110000000000,  // 0xba
+    0b11111111111111111001000000000000,  // 0xbb
+    0b11111111111111111110000000000000,  // 0xbc
+    0b11111111111111111001010000000000,  // 0xbd
+    0b11111111111111111001100000000000,  // 0xbe
+    0b11111111111111111110001000000000,  // 0xbf
+    0b11111111111111111111100000000000,  // 0xc0
+    0b11111111111111111111100001000000,  // 0xc1
+    0b11111111111111101011000000000000,  // 0xc2
+    0b11111111111111100010000000000000,  // 0xc3
+    0b11111111111111111001110000000000,  // 0xc4
+    0b11111111111111111110010000000000,  // 0xc5
+    0b11111111111111111010000000000000,  // 0xc6
+    0b11111111111111111111011000000000,  // 0xc7
+    0b11111111111111111111100010000000,  // 0xc8
+    0b11111111111111111111100011000000,  // 0xc9
+    0b11111111111111111111100100000000,  // 0xca
+    0b11111111111111111111101111000000,  // 0xcb
+    0b11111111111111111111101111100000,  // 0xcc
+    0b11111111111111111111100101000000,  // 0xcd
+    0b11111111111111111111000100000000,  // 0xce
+    0b11111111111111111111011010000000,  // 0xcf
+    0b11111111111111100100000000000000,  // 0xd0
+    0b11111111111111110001100000000000,  // 0xd1
+    0b11111111111111111111100110000000,  // 0xd2
+    0b11111111111111111111110000000000,  // 0xd3
+    0b11111111111111111111110000100000,  // 0xd4
+    0b11111111111111111111100111000000,  // 0xd5
+    0b11111111111111111111110001000000,  // 0xd6
+    0b11111111111111111111001000000000,  // 0xd7
+    0b11111111111111110010000000000000,  // 0xd8
+    0b11111111111111110010100000000000,  // 0xd9
+    0b11111111111111111111101000000000,  // 0xda
+    0b11111111111111111111101001000000,  // 0xdb
+    0b11111111111111111111111111010000,  // 0xdc
+    0b11111111111111111111110001100000,  // 0xdd
+    0b11111111111111111111110010000000,  // 0xde
+    0b11111111111111111111110010100000,  // 0xdf
+    0b11111111111111101100000000000000,  // 0xe0
+    0b11111111111111111111001100000000,  // 0xe1
+    0b11111111111111101101000000000000,  // 0xe2
+    0b11111111111111110011000000000000,  // 0xe3
+    0b11111111111111111010010000000000,  // 0xe4
+    0b11111111111111110011100000000000,  // 0xe5
+    0b11111111111111110100000000000000,  // 0xe6
+    0b11111111111111111110011000000000,  // 0xe7
+    0b11111111111111111010100000000000,  // 0xe8
+    0b11111111111111111010110000000000,  // 0xe9
+    0b11111111111111111111011100000000,  // 0xea
+    0b11111111111111111111011110000000,  // 0xeb
+    0b11111111111111111111010000000000,  // 0xec
+    0b11111111111111111111010100000000,  // 0xed
+    0b11111111111111111111101010000000,  // 0xee
+    0b11111111111111111110100000000000,  // 0xef
+    0b11111111111111111111101011000000,  // 0xf0
+    0b11111111111111111111110011000000,  // 0xf1
+    0b11111111111111111111101100000000,  // 0xf2
+    0b11111111111111111111101101000000,  // 0xf3
+    0b11111111111111111111110011100000,  // 0xf4
+    0b11111111111111111111110100000000,  // 0xf5
+    0b11111111111111111111110100100000,  // 0xf6
+    0b11111111111111111111110101000000,  // 0xf7
+    0b11111111111111111111110101100000,  // 0xf8
+    0b11111111111111111111111111100000,  // 0xf9
+    0b11111111111111111111110110000000,  // 0xfa
+    0b11111111111111111111110110100000,  // 0xfb
+    0b11111111111111111111110111000000,  // 0xfc
+    0b11111111111111111111110111100000,  // 0xfd
+    0b11111111111111111111111000000000,  // 0xfe
+    0b11111111111111111111101110000000,  // 0xff
+    0b11111111111111111111111111111100,  // 0x100
+};
+
+// static
+const uint32_t HuffmanSpecTables::kRightCodes[] = {
+    0b00000000000000000001111111111000,  // 0x00
+    0b00000000011111111111111111011000,  // 0x01
+    0b00001111111111111111111111100010,  // 0x02
+    0b00001111111111111111111111100011,  // 0x03
+    0b00001111111111111111111111100100,  // 0x04
+    0b00001111111111111111111111100101,  // 0x05
+    0b00001111111111111111111111100110,  // 0x06
+    0b00001111111111111111111111100111,  // 0x07
+    0b00001111111111111111111111101000,  // 0x08
+    0b00000000111111111111111111101010,  // 0x09
+    0b00111111111111111111111111111100,  // 0x0a
+    0b00001111111111111111111111101001,  // 0x0b
+    0b00001111111111111111111111101010,  // 0x0c
+    0b00111111111111111111111111111101,  // 0x0d
+    0b00001111111111111111111111101011,  // 0x0e
+    0b00001111111111111111111111101100,  // 0x0f
+    0b00001111111111111111111111101101,  // 0x10
+    0b00001111111111111111111111101110,  // 0x11
+    0b00001111111111111111111111101111,  // 0x12
+    0b00001111111111111111111111110000,  // 0x13
+    0b00001111111111111111111111110001,  // 0x14
+    0b00001111111111111111111111110010,  // 0x15
+    0b00111111111111111111111111111110,  // 0x16
+    0b00001111111111111111111111110011,  // 0x17
+    0b00001111111111111111111111110100,  // 0x18
+    0b00001111111111111111111111110101,  // 0x19
+    0b00001111111111111111111111110110,  // 0x1a
+    0b00001111111111111111111111110111,  // 0x1b
+    0b00001111111111111111111111111000,  // 0x1c
+    0b00001111111111111111111111111001,  // 0x1d
+    0b00001111111111111111111111111010,  // 0x1e
+    0b00001111111111111111111111111011,  // 0x1f
+    0b00000000000000000000000000010100,  // 0x20
+    0b00000000000000000000001111111000,  // '!'
+    0b00000000000000000000001111111001,  // '\"'
+    0b00000000000000000000111111111010,  // '#'
+    0b00000000000000000001111111111001,  // '$'
+    0b00000000000000000000000000010101,  // '%'
+    0b00000000000000000000000011111000,  // '&'
+    0b00000000000000000000011111111010,  // '\''
+    0b00000000000000000000001111111010,  // '('
+    0b00000000000000000000001111111011,  // ')'
+    0b00000000000000000000000011111001,  // '*'
+    0b00000000000000000000011111111011,  // '+'
+    0b00000000000000000000000011111010,  // ','
+    0b00000000000000000000000000010110,  // '-'
+    0b00000000000000000000000000010111,  // '.'
+    0b00000000000000000000000000011000,  // '/'
+    0b00000000000000000000000000000000,  // '0'
+    0b00000000000000000000000000000001,  // '1'
+    0b00000000000000000000000000000010,  // '2'
+    0b00000000000000000000000000011001,  // '3'
+    0b00000000000000000000000000011010,  // '4'
+    0b00000000000000000000000000011011,  // '5'
+    0b00000000000000000000000000011100,  // '6'
+    0b00000000000000000000000000011101,  // '7'
+    0b00000000000000000000000000011110,  // '8'
+    0b00000000000000000000000000011111,  // '9'
+    0b00000000000000000000000001011100,  // ':'
+    0b00000000000000000000000011111011,  // ';'
+    0b00000000000000000111111111111100,  // '<'
+    0b00000000000000000000000000100000,  // '='
+    0b00000000000000000000111111111011,  // '>'
+    0b00000000000000000000001111111100,  // '?'
+    0b00000000000000000001111111111010,  // '@'
+    0b00000000000000000000000000100001,  // 'A'
+    0b00000000000000000000000001011101,  // 'B'
+    0b00000000000000000000000001011110,  // 'C'
+    0b00000000000000000000000001011111,  // 'D'
+    0b00000000000000000000000001100000,  // 'E'
+    0b00000000000000000000000001100001,  // 'F'
+    0b00000000000000000000000001100010,  // 'G'
+    0b00000000000000000000000001100011,  // 'H'
+    0b00000000000000000000000001100100,  // 'I'
+    0b00000000000000000000000001100101,  // 'J'
+    0b00000000000000000000000001100110,  // 'K'
+    0b00000000000000000000000001100111,  // 'L'
+    0b00000000000000000000000001101000,  // 'M'
+    0b00000000000000000000000001101001,  // 'N'
+    0b00000000000000000000000001101010,  // 'O'
+    0b00000000000000000000000001101011,  // 'P'
+    0b00000000000000000000000001101100,  // 'Q'
+    0b00000000000000000000000001101101,  // 'R'
+    0b00000000000000000000000001101110,  // 'S'
+    0b00000000000000000000000001101111,  // 'T'
+    0b00000000000000000000000001110000,  // 'U'
+    0b00000000000000000000000001110001,  // 'V'
+    0b00000000000000000000000001110010,  // 'W'
+    0b00000000000000000000000011111100,  // 'X'
+    0b00000000000000000000000001110011,  // 'Y'
+    0b00000000000000000000000011111101,  // 'Z'
+    0b00000000000000000001111111111011,  // '['
+    0b00000000000001111111111111110000,  // '\\'
+    0b00000000000000000001111111111100,  // ']'
+    0b00000000000000000011111111111100,  // '^'
+    0b00000000000000000000000000100010,  // '_'
+    0b00000000000000000111111111111101,  // '`'
+    0b00000000000000000000000000000011,  // 'a'
+    0b00000000000000000000000000100011,  // 'b'
+    0b00000000000000000000000000000100,  // 'c'
+    0b00000000000000000000000000100100,  // 'd'
+    0b00000000000000000000000000000101,  // 'e'
+    0b00000000000000000000000000100101,  // 'f'
+    0b00000000000000000000000000100110,  // 'g'
+    0b00000000000000000000000000100111,  // 'h'
+    0b00000000000000000000000000000110,  // 'i'
+    0b00000000000000000000000001110100,  // 'j'
+    0b00000000000000000000000001110101,  // 'k'
+    0b00000000000000000000000000101000,  // 'l'
+    0b00000000000000000000000000101001,  // 'm'
+    0b00000000000000000000000000101010,  // 'n'
+    0b00000000000000000000000000000111,  // 'o'
+    0b00000000000000000000000000101011,  // 'p'
+    0b00000000000000000000000001110110,  // 'q'
+    0b00000000000000000000000000101100,  // 'r'
+    0b00000000000000000000000000001000,  // 's'
+    0b00000000000000000000000000001001,  // 't'
+    0b00000000000000000000000000101101,  // 'u'
+    0b00000000000000000000000001110111,  // 'v'
+    0b00000000000000000000000001111000,  // 'w'
+    0b00000000000000000000000001111001,  // 'x'
+    0b00000000000000000000000001111010,  // 'y'
+    0b00000000000000000000000001111011,  // 'z'
+    0b00000000000000000111111111111110,  // '{'
+    0b00000000000000000000011111111100,  // '|'
+    0b00000000000000000011111111111101,  // '}'
+    0b00000000000000000001111111111101,  // '~'
+    0b00001111111111111111111111111100,  // 0x7f
+    0b00000000000011111111111111100110,  // 0x80
+    0b00000000001111111111111111010010,  // 0x81
+    0b00000000000011111111111111100111,  // 0x82
+    0b00000000000011111111111111101000,  // 0x83
+    0b00000000001111111111111111010011,  // 0x84
+    0b00000000001111111111111111010100,  // 0x85
+    0b00000000001111111111111111010101,  // 0x86
+    0b00000000011111111111111111011001,  // 0x87
+    0b00000000001111111111111111010110,  // 0x88
+    0b00000000011111111111111111011010,  // 0x89
+    0b00000000011111111111111111011011,  // 0x8a
+    0b00000000011111111111111111011100,  // 0x8b
+    0b00000000011111111111111111011101,  // 0x8c
+    0b00000000011111111111111111011110,  // 0x8d
+    0b00000000111111111111111111101011,  // 0x8e
+    0b00000000011111111111111111011111,  // 0x8f
+    0b00000000111111111111111111101100,  // 0x90
+    0b00000000111111111111111111101101,  // 0x91
+    0b00000000001111111111111111010111,  // 0x92
+    0b00000000011111111111111111100000,  // 0x93
+    0b00000000111111111111111111101110,  // 0x94
+    0b00000000011111111111111111100001,  // 0x95
+    0b00000000011111111111111111100010,  // 0x96
+    0b00000000011111111111111111100011,  // 0x97
+    0b00000000011111111111111111100100,  // 0x98
+    0b00000000000111111111111111011100,  // 0x99
+    0b00000000001111111111111111011000,  // 0x9a
+    0b00000000011111111111111111100101,  // 0x9b
+    0b00000000001111111111111111011001,  // 0x9c
+    0b00000000011111111111111111100110,  // 0x9d
+    0b00000000011111111111111111100111,  // 0x9e
+    0b00000000111111111111111111101111,  // 0x9f
+    0b00000000001111111111111111011010,  // 0xa0
+    0b00000000000111111111111111011101,  // 0xa1
+    0b00000000000011111111111111101001,  // 0xa2
+    0b00000000001111111111111111011011,  // 0xa3
+    0b00000000001111111111111111011100,  // 0xa4
+    0b00000000011111111111111111101000,  // 0xa5
+    0b00000000011111111111111111101001,  // 0xa6
+    0b00000000000111111111111111011110,  // 0xa7
+    0b00000000011111111111111111101010,  // 0xa8
+    0b00000000001111111111111111011101,  // 0xa9
+    0b00000000001111111111111111011110,  // 0xaa
+    0b00000000111111111111111111110000,  // 0xab
+    0b00000000000111111111111111011111,  // 0xac
+    0b00000000001111111111111111011111,  // 0xad
+    0b00000000011111111111111111101011,  // 0xae
+    0b00000000011111111111111111101100,  // 0xaf
+    0b00000000000111111111111111100000,  // 0xb0
+    0b00000000000111111111111111100001,  // 0xb1
+    0b00000000001111111111111111100000,  // 0xb2
+    0b00000000000111111111111111100010,  // 0xb3
+    0b00000000011111111111111111101101,  // 0xb4
+    0b00000000001111111111111111100001,  // 0xb5
+    0b00000000011111111111111111101110,  // 0xb6
+    0b00000000011111111111111111101111,  // 0xb7
+    0b00000000000011111111111111101010,  // 0xb8
+    0b00000000001111111111111111100010,  // 0xb9
+    0b00000000001111111111111111100011,  // 0xba
+    0b00000000001111111111111111100100,  // 0xbb
+    0b00000000011111111111111111110000,  // 0xbc
+    0b00000000001111111111111111100101,  // 0xbd
+    0b00000000001111111111111111100110,  // 0xbe
+    0b00000000011111111111111111110001,  // 0xbf
+    0b00000011111111111111111111100000,  // 0xc0
+    0b00000011111111111111111111100001,  // 0xc1
+    0b00000000000011111111111111101011,  // 0xc2
+    0b00000000000001111111111111110001,  // 0xc3
+    0b00000000001111111111111111100111,  // 0xc4
+    0b00000000011111111111111111110010,  // 0xc5
+    0b00000000001111111111111111101000,  // 0xc6
+    0b00000001111111111111111111101100,  // 0xc7
+    0b00000011111111111111111111100010,  // 0xc8
+    0b00000011111111111111111111100011,  // 0xc9
+    0b00000011111111111111111111100100,  // 0xca
+    0b00000111111111111111111111011110,  // 0xcb
+    0b00000111111111111111111111011111,  // 0xcc
+    0b00000011111111111111111111100101,  // 0xcd
+    0b00000000111111111111111111110001,  // 0xce
+    0b00000001111111111111111111101101,  // 0xcf
+    0b00000000000001111111111111110010,  // 0xd0
+    0b00000000000111111111111111100011,  // 0xd1
+    0b00000011111111111111111111100110,  // 0xd2
+    0b00000111111111111111111111100000,  // 0xd3
+    0b00000111111111111111111111100001,  // 0xd4
+    0b00000011111111111111111111100111,  // 0xd5
+    0b00000111111111111111111111100010,  // 0xd6
+    0b00000000111111111111111111110010,  // 0xd7
+    0b00000000000111111111111111100100,  // 0xd8
+    0b00000000000111111111111111100101,  // 0xd9
+    0b00000011111111111111111111101000,  // 0xda
+    0b00000011111111111111111111101001,  // 0xdb
+    0b00001111111111111111111111111101,  // 0xdc
+    0b00000111111111111111111111100011,  // 0xdd
+    0b00000111111111111111111111100100,  // 0xde
+    0b00000111111111111111111111100101,  // 0xdf
+    0b00000000000011111111111111101100,  // 0xe0
+    0b00000000111111111111111111110011,  // 0xe1
+    0b00000000000011111111111111101101,  // 0xe2
+    0b00000000000111111111111111100110,  // 0xe3
+    0b00000000001111111111111111101001,  // 0xe4
+    0b00000000000111111111111111100111,  // 0xe5
+    0b00000000000111111111111111101000,  // 0xe6
+    0b00000000011111111111111111110011,  // 0xe7
+    0b00000000001111111111111111101010,  // 0xe8
+    0b00000000001111111111111111101011,  // 0xe9
+    0b00000001111111111111111111101110,  // 0xea
+    0b00000001111111111111111111101111,  // 0xeb
+    0b00000000111111111111111111110100,  // 0xec
+    0b00000000111111111111111111110101,  // 0xed
+    0b00000011111111111111111111101010,  // 0xee
+    0b00000000011111111111111111110100,  // 0xef
+    0b00000011111111111111111111101011,  // 0xf0
+    0b00000111111111111111111111100110,  // 0xf1
+    0b00000011111111111111111111101100,  // 0xf2
+    0b00000011111111111111111111101101,  // 0xf3
+    0b00000111111111111111111111100111,  // 0xf4
+    0b00000111111111111111111111101000,  // 0xf5
+    0b00000111111111111111111111101001,  // 0xf6
+    0b00000111111111111111111111101010,  // 0xf7
+    0b00000111111111111111111111101011,  // 0xf8
+    0b00001111111111111111111111111110,  // 0xf9
+    0b00000111111111111111111111101100,  // 0xfa
+    0b00000111111111111111111111101101,  // 0xfb
+    0b00000111111111111111111111101110,  // 0xfc
+    0b00000111111111111111111111101111,  // 0xfd
+    0b00000111111111111111111111110000,  // 0xfe
+    0b00000011111111111111111111101110,  // 0xff
+    0b00111111111111111111111111111111,  // 0x100
+};
+// clang-format off
+
+}  // namespace http2
diff --git a/http2/hpack/huffman/huffman_spec_tables.h b/quiche/http2/hpack/huffman/huffman_spec_tables.h
similarity index 100%
rename from http2/hpack/huffman/huffman_spec_tables.h
rename to quiche/http2/hpack/huffman/huffman_spec_tables.h
diff --git a/quiche/http2/hpack/tools/hpack_block_builder.cc b/quiche/http2/hpack/tools/hpack_block_builder.cc
new file mode 100644
index 0000000..d958b7c
--- /dev/null
+++ b/quiche/http2/hpack/tools/hpack_block_builder.cc
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+
+#include "quiche/http2/hpack/varint/hpack_varint_encoder.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+void HpackBlockBuilder::AppendHighBitsAndVarint(uint8_t high_bits,
+                                                uint8_t prefix_length,
+                                                uint64_t varint) {
+  EXPECT_LE(3, prefix_length);
+  EXPECT_LE(prefix_length, 8);
+
+  HpackVarintEncoder::Encode(high_bits, prefix_length, varint, &buffer_);
+}
+
+void HpackBlockBuilder::AppendEntryTypeAndVarint(HpackEntryType entry_type,
+                                                 uint64_t varint) {
+  uint8_t high_bits;
+  uint8_t prefix_length;  // Bits of the varint prefix in the first byte.
+  switch (entry_type) {
+    case HpackEntryType::kIndexedHeader:
+      high_bits = 0x80;
+      prefix_length = 7;
+      break;
+    case HpackEntryType::kDynamicTableSizeUpdate:
+      high_bits = 0x20;
+      prefix_length = 5;
+      break;
+    case HpackEntryType::kIndexedLiteralHeader:
+      high_bits = 0x40;
+      prefix_length = 6;
+      break;
+    case HpackEntryType::kUnindexedLiteralHeader:
+      high_bits = 0x00;
+      prefix_length = 4;
+      break;
+    case HpackEntryType::kNeverIndexedLiteralHeader:
+      high_bits = 0x10;
+      prefix_length = 4;
+      break;
+    default:
+      HTTP2_BUG(http2_bug_110_1) << "Unreached, entry_type=" << entry_type;
+      high_bits = 0;
+      prefix_length = 0;
+      break;
+  }
+  AppendHighBitsAndVarint(high_bits, prefix_length, varint);
+}
+
+void HpackBlockBuilder::AppendString(bool is_huffman_encoded,
+                                     absl::string_view str) {
+  uint8_t high_bits = is_huffman_encoded ? 0x80 : 0;
+  uint8_t prefix_length = 7;
+  AppendHighBitsAndVarint(high_bits, prefix_length, str.size());
+  buffer_.append(str.data(), str.size());
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/tools/hpack_block_builder.h b/quiche/http2/hpack/tools/hpack_block_builder.h
new file mode 100644
index 0000000..ef5f3c7
--- /dev/null
+++ b/quiche/http2/hpack/tools/hpack_block_builder.h
@@ -0,0 +1,97 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
+#define QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
+
+// HpackBlockBuilder builds wire-format HPACK blocks (or fragments thereof)
+// from components.
+
+// Supports very large varints to enable tests to create HPACK blocks with
+// values that the decoder should reject. For now, this is only intended for
+// use in tests, and thus has EXPECT* in the code. If desired to use it in an
+// encoder, it will need optimization work, especially w.r.t memory mgmt, and
+// the EXPECT* will need to be removed or replaced with QUICHE_DCHECKs. And of
+// course the support for very large varints will not be needed in production
+// code.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class HpackBlockBuilder {
+ public:
+  explicit HpackBlockBuilder(absl::string_view initial_contents)
+      : buffer_(initial_contents.data(), initial_contents.size()) {}
+  HpackBlockBuilder() {}
+  ~HpackBlockBuilder() {}
+
+  size_t size() const { return buffer_.size(); }
+  const std::string& buffer() const { return buffer_; }
+
+  //----------------------------------------------------------------------------
+  // Methods for appending a valid HPACK entry.
+
+  void AppendIndexedHeader(uint64_t index) {
+    AppendEntryTypeAndVarint(HpackEntryType::kIndexedHeader, index);
+  }
+
+  void AppendDynamicTableSizeUpdate(uint64_t size) {
+    AppendEntryTypeAndVarint(HpackEntryType::kDynamicTableSizeUpdate, size);
+  }
+
+  void AppendNameIndexAndLiteralValue(HpackEntryType entry_type,
+                                      uint64_t name_index,
+                                      bool value_is_huffman_encoded,
+                                      absl::string_view value) {
+    // name_index==0 would indicate that the entry includes a literal name.
+    // Call AppendLiteralNameAndValue in that case.
+    EXPECT_NE(0u, name_index);
+    AppendEntryTypeAndVarint(entry_type, name_index);
+    AppendString(value_is_huffman_encoded, value);
+  }
+
+  void AppendLiteralNameAndValue(HpackEntryType entry_type,
+                                 bool name_is_huffman_encoded,
+                                 absl::string_view name,
+                                 bool value_is_huffman_encoded,
+                                 absl::string_view value) {
+    AppendEntryTypeAndVarint(entry_type, 0);
+    AppendString(name_is_huffman_encoded, name);
+    AppendString(value_is_huffman_encoded, value);
+  }
+
+  //----------------------------------------------------------------------------
+  // Primitive methods that are not guaranteed to write a valid HPACK entry.
+
+  // Appends a varint, with the specified high_bits above the prefix of the
+  // varint.
+  void AppendHighBitsAndVarint(uint8_t high_bits,
+                               uint8_t prefix_length,
+                               uint64_t varint);
+
+  // Append the start of an HPACK entry for the specified type, with the
+  // specified varint.
+  void AppendEntryTypeAndVarint(HpackEntryType entry_type, uint64_t varint);
+
+  // Append a header string (i.e. a header name or value) in HPACK format.
+  // Does NOT perform Huffman encoding.
+  void AppendString(bool is_huffman_encoded, absl::string_view str);
+
+ private:
+  std::string buffer_;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
diff --git a/quiche/http2/hpack/tools/hpack_block_builder_test.cc b/quiche/http2/hpack/tools/hpack_block_builder_test.cc
new file mode 100644
index 0000000..26e42ff
--- /dev/null
+++ b/quiche/http2/hpack/tools/hpack_block_builder_test.cc
@@ -0,0 +1,169 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+const bool kUncompressed = false;
+const bool kCompressed = true;
+
+// TODO(jamessynge): Once static table code is checked in, switch to using
+// constants from there.
+const uint32_t kStaticTableMethodGET = 2;
+const uint32_t kStaticTablePathSlash = 4;
+const uint32_t kStaticTableSchemeHttp = 6;
+
+// Tests of encoding per the RFC. See:
+//   http://httpwg.org/specs/rfc7541.html#header.field.representation.examples
+// The expected values have been copied from the RFC.
+TEST(HpackBlockBuilderTest, ExamplesFromSpecC2) {
+  {
+    HpackBlockBuilder b;
+    b.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader,
+                                kUncompressed, "custom-key", kUncompressed,
+                                "custom-header");
+    EXPECT_EQ(26u, b.size());
+
+    const char kExpected[] =
+        "\x40"            // == Literal indexed ==
+        "\x0a"            // Name length (10)
+        "custom-key"      // Name
+        "\x0d"            // Value length (13)
+        "custom-header";  // Value
+    EXPECT_EQ(kExpected, b.buffer());
+  }
+  {
+    HpackBlockBuilder b;
+    b.AppendNameIndexAndLiteralValue(HpackEntryType::kUnindexedLiteralHeader, 4,
+                                     kUncompressed, "/sample/path");
+    EXPECT_EQ(14u, b.size());
+
+    const char kExpected[] =
+        "\x04"           // == Literal unindexed, name index 0x04 ==
+        "\x0c"           // Value length (12)
+        "/sample/path";  // Value
+    EXPECT_EQ(kExpected, b.buffer());
+  }
+  {
+    HpackBlockBuilder b;
+    b.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
+                                kUncompressed, "password", kUncompressed,
+                                "secret");
+    EXPECT_EQ(17u, b.size());
+
+    const char kExpected[] =
+        "\x10"      // == Literal never indexed ==
+        "\x08"      // Name length (8)
+        "password"  // Name
+        "\x06"      // Value length (6)
+        "secret";   // Value
+    EXPECT_EQ(kExpected, b.buffer());
+  }
+  {
+    HpackBlockBuilder b;
+    b.AppendIndexedHeader(2);
+    EXPECT_EQ(1u, b.size());
+
+    const char kExpected[] = "\x82";  // == Indexed (2) ==
+    EXPECT_EQ(kExpected, b.buffer());
+  }
+}
+
+// Tests of encoding per the RFC. See:
+//  http://httpwg.org/specs/rfc7541.html#request.examples.without.huffman.coding
+TEST(HpackBlockBuilderTest, ExamplesFromSpecC3) {
+  {
+    // Header block to encode:
+    //   :method: GET
+    //   :scheme: http
+    //   :path: /
+    //   :authority: www.example.com
+    HpackBlockBuilder b;
+    b.AppendIndexedHeader(2);  // :method: GET
+    b.AppendIndexedHeader(6);  // :scheme: http
+    b.AppendIndexedHeader(4);  // :path: /
+    b.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 1,
+                                     kUncompressed, "www.example.com");
+    EXPECT_EQ(20u, b.size());
+
+    // Hex dump of encoded data (copied from RFC):
+    // 0x0000:  8286 8441 0f77 7777 2e65 7861 6d70 6c65  ...A.www.example
+    // 0x0010:  2e63 6f6d                                .com
+
+    const std::string expected =
+        absl::HexStringToBytes("828684410f7777772e6578616d706c652e636f6d");
+    EXPECT_EQ(expected, b.buffer());
+  }
+}
+
+// Tests of encoding per the RFC. See:
+//   http://httpwg.org/specs/rfc7541.html#request.examples.with.huffman.coding
+TEST(HpackBlockBuilderTest, ExamplesFromSpecC4) {
+  {
+    // Header block to encode:
+    //   :method: GET
+    //   :scheme: http
+    //   :path: /
+    //   :authority: www.example.com  (Huffman encoded)
+    HpackBlockBuilder b;
+    b.AppendIndexedHeader(kStaticTableMethodGET);
+    b.AppendIndexedHeader(kStaticTableSchemeHttp);
+    b.AppendIndexedHeader(kStaticTablePathSlash);
+    const char kHuffmanWwwExampleCom[] = {'\xf1', '\xe3', '\xc2', '\xe5',
+                                          '\xf2', '\x3a', '\x6b', '\xa0',
+                                          '\xab', '\x90', '\xf4', '\xff'};
+    b.AppendNameIndexAndLiteralValue(
+        HpackEntryType::kIndexedLiteralHeader, 1, kCompressed,
+        absl::string_view(kHuffmanWwwExampleCom, sizeof kHuffmanWwwExampleCom));
+    EXPECT_EQ(17u, b.size());
+
+    // Hex dump of encoded data (copied from RFC):
+    // 0x0000:  8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4  ...A......:k....
+    // 0x0010:  ff                                       .
+
+    const std::string expected =
+        absl::HexStringToBytes("828684418cf1e3c2e5f23a6ba0ab90f4ff");
+    EXPECT_EQ(expected, b.buffer());
+  }
+}
+
+TEST(HpackBlockBuilderTest, DynamicTableSizeUpdate) {
+  {
+    HpackBlockBuilder b;
+    b.AppendDynamicTableSizeUpdate(0);
+    EXPECT_EQ(1u, b.size());
+
+    const char kData[] = {'\x20'};
+    absl::string_view expected(kData, sizeof kData);
+    EXPECT_EQ(expected, b.buffer());
+  }
+  {
+    HpackBlockBuilder b;
+    b.AppendDynamicTableSizeUpdate(4096);  // The default size.
+    EXPECT_EQ(3u, b.size());
+
+    const char kData[] = {'\x3f', '\xe1', '\x1f'};
+    absl::string_view expected(kData, sizeof kData);
+    EXPECT_EQ(expected, b.buffer());
+  }
+  {
+    HpackBlockBuilder b;
+    b.AppendDynamicTableSizeUpdate(1000000000000);  // A very large value.
+    EXPECT_EQ(7u, b.size());
+
+    const char kData[] = {'\x3f', '\xe1', '\x9f', '\x94',
+                          '\xa5', '\x8d', '\x1d'};
+    absl::string_view expected(kData, sizeof kData);
+    EXPECT_EQ(expected, b.buffer());
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/tools/hpack_example.cc b/quiche/http2/hpack/tools/hpack_example.cc
new file mode 100644
index 0000000..c6e6d2d
--- /dev/null
+++ b/quiche/http2/hpack/tools/hpack_example.cc
@@ -0,0 +1,59 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/tools/hpack_example.h"
+
+#include <ctype.h>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/platform/api/http2_bug_tracker.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+void HpackExampleToStringOrDie(absl::string_view example, std::string* output) {
+  while (!example.empty()) {
+    const char c0 = example[0];
+    if (isxdigit(c0)) {
+      QUICHE_CHECK_GT(example.size(), 1u) << "Truncated hex byte?";
+      const char c1 = example[1];
+      QUICHE_CHECK(isxdigit(c1)) << "Found half a byte?";
+      *output += absl::HexStringToBytes(example.substr(0, 2));
+      example.remove_prefix(2);
+      continue;
+    }
+    if (isspace(c0)) {
+      example.remove_prefix(1);
+      continue;
+    }
+    if (!example.empty() && example[0] == '|') {
+      // Start of a comment. Skip to end of line or of input.
+      auto pos = example.find('\n');
+      if (pos == absl::string_view::npos) {
+        // End of input.
+        break;
+      }
+      example.remove_prefix(pos + 1);
+      continue;
+    }
+    HTTP2_BUG(http2_bug_107_1)
+        << "Can't parse byte " << static_cast<int>(c0)
+        << absl::StrCat(" (0x", absl::Hex(c0), ")") << "\nExample: " << example;
+  }
+  QUICHE_CHECK_LT(0u, output->size()) << "Example is empty.";
+}
+
+}  // namespace
+
+std::string HpackExampleToStringOrDie(absl::string_view example) {
+  std::string output;
+  HpackExampleToStringOrDie(example, &output);
+  return output;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/http2/hpack/tools/hpack_example.h b/quiche/http2/hpack/tools/hpack_example.h
similarity index 100%
rename from http2/hpack/tools/hpack_example.h
rename to quiche/http2/hpack/tools/hpack_example.h
diff --git a/quiche/http2/hpack/varint/hpack_varint_decoder.cc b/quiche/http2/hpack/varint/hpack_varint_decoder.cc
new file mode 100644
index 0000000..3334807
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_decoder.cc
@@ -0,0 +1,143 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+
+#include "absl/strings/str_cat.h"
+
+namespace http2 {
+
+DecodeStatus HpackVarintDecoder::Start(uint8_t prefix_value,
+                                       uint8_t prefix_length,
+                                       DecodeBuffer* db) {
+  QUICHE_DCHECK_LE(3u, prefix_length);
+  QUICHE_DCHECK_LE(prefix_length, 8u);
+
+  // |prefix_mask| defines the sequence of low-order bits of the first byte
+  // that encode the prefix of the value. It is also the marker in those bits
+  // of the first byte indicating that at least one extension byte is needed.
+  const uint8_t prefix_mask = (1 << prefix_length) - 1;
+
+  // Ignore the bits that aren't a part of the prefix of the varint.
+  value_ = prefix_value & prefix_mask;
+
+  if (value_ < prefix_mask) {
+    MarkDone();
+    return DecodeStatus::kDecodeDone;
+  }
+
+  offset_ = 0;
+  return Resume(db);
+}
+
+DecodeStatus HpackVarintDecoder::StartExtended(uint8_t prefix_length,
+                                               DecodeBuffer* db) {
+  QUICHE_DCHECK_LE(3u, prefix_length);
+  QUICHE_DCHECK_LE(prefix_length, 8u);
+
+  value_ = (1 << prefix_length) - 1;
+  offset_ = 0;
+  return Resume(db);
+}
+
+DecodeStatus HpackVarintDecoder::Resume(DecodeBuffer* db) {
+  // There can be at most 10 continuation bytes.  Offset is zero for the
+  // first one and increases by 7 for each subsequent one.
+  const uint8_t kMaxOffset = 63;
+  CheckNotDone();
+
+  // Process most extension bytes without the need for overflow checking.
+  while (offset_ < kMaxOffset) {
+    if (db->Empty()) {
+      return DecodeStatus::kDecodeInProgress;
+    }
+
+    uint8_t byte = db->DecodeUInt8();
+    uint64_t summand = byte & 0x7f;
+
+    // Shifting a 7 bit value to the left by at most 56 places can never
+    // overflow on uint64_t.
+    QUICHE_DCHECK_LE(offset_, 56);
+    QUICHE_DCHECK_LE(summand, std::numeric_limits<uint64_t>::max() >> offset_);
+
+    summand <<= offset_;
+
+    // At this point,
+    // |value_| is at most (2^prefix_length - 1) + (2^49 - 1), and
+    // |summand| is at most 255 << 56 (which is smaller than 2^63),
+    // so adding them can never overflow on uint64_t.
+    QUICHE_DCHECK_LE(value_, std::numeric_limits<uint64_t>::max() - summand);
+
+    value_ += summand;
+
+    // Decoding ends if continuation flag is not set.
+    if ((byte & 0x80) == 0) {
+      MarkDone();
+      return DecodeStatus::kDecodeDone;
+    }
+
+    offset_ += 7;
+  }
+
+  if (db->Empty()) {
+    return DecodeStatus::kDecodeInProgress;
+  }
+
+  QUICHE_DCHECK_EQ(kMaxOffset, offset_);
+
+  uint8_t byte = db->DecodeUInt8();
+  // No more extension bytes are allowed after this.
+  if ((byte & 0x80) == 0) {
+    uint64_t summand = byte & 0x7f;
+    // Check for overflow in left shift.
+    if (summand <= std::numeric_limits<uint64_t>::max() >> offset_) {
+      summand <<= offset_;
+      // Check for overflow in addition.
+      if (value_ <= std::numeric_limits<uint64_t>::max() - summand) {
+        value_ += summand;
+        MarkDone();
+        return DecodeStatus::kDecodeDone;
+      }
+    }
+  }
+
+  // Signal error if value is too large or there are too many extension bytes.
+  HTTP2_DLOG(WARNING)
+      << "Variable length int encoding is too large or too long. "
+      << DebugString();
+  MarkDone();
+  return DecodeStatus::kDecodeError;
+}
+
+uint64_t HpackVarintDecoder::value() const {
+  CheckDone();
+  return value_;
+}
+
+void HpackVarintDecoder::set_value(uint64_t v) {
+  MarkDone();
+  value_ = v;
+}
+
+std::string HpackVarintDecoder::DebugString() const {
+  return absl::StrCat("HpackVarintDecoder(value=", value_, ", offset=", offset_,
+                      ")");
+}
+
+DecodeStatus HpackVarintDecoder::StartForTest(uint8_t prefix_value,
+                                              uint8_t prefix_length,
+                                              DecodeBuffer* db) {
+  return Start(prefix_value, prefix_length, db);
+}
+
+DecodeStatus HpackVarintDecoder::StartExtendedForTest(uint8_t prefix_length,
+                                                      DecodeBuffer* db) {
+  return StartExtended(prefix_length, db);
+}
+
+DecodeStatus HpackVarintDecoder::ResumeForTest(DecodeBuffer* db) {
+  return Resume(db);
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/varint/hpack_varint_decoder.h b/quiche/http2/hpack/varint/hpack_varint_decoder.h
new file mode 100644
index 0000000..bffbdcc
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_decoder.h
@@ -0,0 +1,130 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// HpackVarintDecoder decodes HPACK variable length unsigned integers. In HPACK,
+// these integers are used to identify static or dynamic table index entries, to
+// specify string lengths, and to update the size limit of the dynamic table.
+// In QPACK, in addition to these uses, these integers also identify streams.
+//
+// The caller will need to validate that the decoded value is in an acceptable
+// range.
+//
+// For details of the encoding, see:
+//        http://httpwg.org/specs/rfc7541.html#integer.representation
+//
+// HpackVarintDecoder supports decoding any integer that can be represented on
+// uint64_t, thereby exceeding the requirements for QPACK: "QPACK
+// implementations MUST be able to decode integers up to 62 bits long."  See
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.1.1
+//
+// This decoder supports at most 10 extension bytes (bytes following the prefix,
+// also called continuation bytes).  An encoder is allowed to zero pad the
+// encoded integer on the left, thereby increasing the number of extension
+// bytes.  If an encoder uses so much padding that the number of extension bytes
+// exceeds the limit, then this decoder signals an error.
+
+#ifndef QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_DECODER_H_
+#define QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_DECODER_H_
+
+#include <cstdint>
+#include <limits>
+#include <string>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// Sentinel value for |HpackVarintDecoder::offset_| to signify that decoding is
+// completed.  Only used in debug builds.
+#ifndef NDEBUG
+const uint8_t kHpackVarintDecoderOffsetDone =
+    std::numeric_limits<uint8_t>::max();
+#endif
+
+// Decodes an HPACK variable length unsigned integer, in a resumable fashion
+// so it can handle running out of input in the DecodeBuffer. Call Start or
+// StartExtended the first time (when decoding the byte that contains the
+// prefix), then call Resume later if it is necessary to resume. When done,
+// call value() to retrieve the decoded value.
+//
+// No constructor or destructor. Holds no resources, so destruction isn't
+// needed. Start and StartExtended handles the initialization of member
+// variables. This is necessary in order for HpackVarintDecoder to be part
+// of a union.
+class QUICHE_EXPORT_PRIVATE HpackVarintDecoder {
+ public:
+  // |prefix_value| is the first byte of the encoded varint.
+  // |prefix_length| is number of bits in the first byte that are used for
+  // encoding the integer.  |db| is the rest of the buffer,  that is, not
+  // including the first byte.
+  DecodeStatus Start(uint8_t prefix_value,
+                     uint8_t prefix_length,
+                     DecodeBuffer* db);
+
+  // The caller has already determined that the encoding requires multiple
+  // bytes, i.e. that the 3 to 8 low-order bits (the number determined by
+  // |prefix_length|) of the first byte are are all 1.  |db| is the rest of the
+  // buffer,  that is, not including the first byte.
+  DecodeStatus StartExtended(uint8_t prefix_length, DecodeBuffer* db);
+
+  // Resume decoding a variable length integer after an earlier
+  // call to Start or StartExtended returned kDecodeInProgress.
+  DecodeStatus Resume(DecodeBuffer* db);
+
+  uint64_t value() const;
+
+  // This supports optimizations for the case of a varint with zero extension
+  // bytes, where the handling of the prefix is done by the caller.
+  void set_value(uint64_t v);
+
+  // All the public methods below are for supporting assertions and tests.
+
+  std::string DebugString() const;
+
+  // For benchmarking, these methods ensure the decoder
+  // is NOT inlined into the caller.
+  DecodeStatus StartForTest(uint8_t prefix_value,
+                            uint8_t prefix_length,
+                            DecodeBuffer* db);
+  DecodeStatus StartExtendedForTest(uint8_t prefix_length, DecodeBuffer* db);
+  DecodeStatus ResumeForTest(DecodeBuffer* db);
+
+ private:
+  // Protection in case Resume is called when it shouldn't be.
+  void MarkDone() {
+#ifndef NDEBUG
+    offset_ = kHpackVarintDecoderOffsetDone;
+#endif
+  }
+  void CheckNotDone() const {
+#ifndef NDEBUG
+    QUICHE_DCHECK_NE(kHpackVarintDecoderOffsetDone, offset_);
+#endif
+  }
+  void CheckDone() const {
+#ifndef NDEBUG
+    QUICHE_DCHECK_EQ(kHpackVarintDecoderOffsetDone, offset_);
+#endif
+  }
+
+  // These fields are initialized just to keep ASAN happy about reading
+  // them from DebugString().
+
+  // The encoded integer is being accumulated in |value_|.  When decoding is
+  // complete, |value_| holds the result.
+  uint64_t value_ = 0;
+
+  // Each extension byte encodes in its lowest 7 bits a segment of the integer.
+  // |offset_| is the number of places this segment has to be shifted to the
+  // left for decoding.  It is zero for the first extension byte, and increases
+  // by 7 for each subsequent extension byte.
+  uint8_t offset_ = 0;
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_DECODER_H_
diff --git a/quiche/http2/hpack/varint/hpack_varint_decoder_test.cc b/quiche/http2/hpack/varint/hpack_varint_decoder_test.cc
new file mode 100644
index 0000000..e5a2025
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_decoder_test.cc
@@ -0,0 +1,311 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+
+// Test HpackVarintDecoder against hardcoded data.
+
+#include <stddef.h>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+namespace {
+
+class HpackVarintDecoderTest
+    : public RandomDecoderTest,
+      public ::testing::WithParamInterface<std::tuple<uint8_t, const char*>> {
+ protected:
+  HpackVarintDecoderTest()
+      : high_bits_(std::get<0>(GetParam())),
+        suffix_(absl::HexStringToBytes(std::get<1>(GetParam()))),
+        prefix_length_(0) {}
+
+  void DecodeExpectSuccess(absl::string_view data,
+                           uint32_t prefix_length,
+                           uint64_t expected_value) {
+    Validator validator = [expected_value, this](
+                              const DecodeBuffer& /*db*/,
+                              DecodeStatus /*status*/) -> AssertionResult {
+      VERIFY_EQ(expected_value, decoder_.value())
+          << "Value doesn't match expected: " << decoder_.value()
+          << " != " << expected_value;
+      return AssertionSuccess();
+    };
+
+    // First validate that decoding is done and that we've advanced the cursor
+    // the expected amount.
+    validator = ValidateDoneAndOffset(/* offset = */ data.size(), validator);
+
+    EXPECT_TRUE(Decode(data, prefix_length, validator));
+
+    EXPECT_EQ(expected_value, decoder_.value());
+  }
+
+  void DecodeExpectError(absl::string_view data, uint32_t prefix_length) {
+    Validator validator = [](const DecodeBuffer& /*db*/,
+                             DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(DecodeStatus::kDecodeError, status);
+      return AssertionSuccess();
+    };
+
+    EXPECT_TRUE(Decode(data, prefix_length, validator));
+  }
+
+ private:
+  AssertionResult Decode(absl::string_view data,
+                         uint32_t prefix_length,
+                         const Validator validator) {
+    prefix_length_ = prefix_length;
+
+    // Copy |data| so that it can be modified.
+    std::string data_copy(data);
+
+    // Bits of the first byte not part of the prefix should be ignored.
+    uint8_t high_bits_mask = 0b11111111 << prefix_length_;
+    data_copy[0] |= (high_bits_mask & high_bits_);
+
+    // Extra bytes appended to the input should be ignored.
+    data_copy.append(suffix_);
+
+    DecodeBuffer b(data_copy);
+
+    // StartDecoding, above, requires the DecodeBuffer be non-empty so that it
+    // can call Start with the prefix byte.
+    bool return_non_zero_on_first = true;
+
+    return DecodeAndValidateSeveralWays(&b, return_non_zero_on_first,
+                                        validator);
+  }
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    QUICHE_CHECK_LT(0u, b->Remaining());
+    uint8_t prefix = b->DecodeUInt8();
+    return decoder_.Start(prefix, prefix_length_, b);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    return decoder_.Resume(b);
+  }
+
+  // Bits of the first byte not part of the prefix.
+  const uint8_t high_bits_;
+  // Extra bytes appended to the input.
+  const std::string suffix_;
+
+  HpackVarintDecoder decoder_;
+  uint8_t prefix_length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    HpackVarintDecoderTest,
+    HpackVarintDecoderTest,
+    ::testing::Combine(
+        // Bits of the first byte not part of the prefix should be ignored.
+        ::testing::Values(0b00000000, 0b11111111, 0b10101010),
+        // Extra bytes appended to the input should be ignored.
+        ::testing::Values("", "00", "666f6f")));
+
+struct {
+  const char* data;
+  uint32_t prefix_length;
+  uint64_t expected_value;
+} kSuccessTestData[] = {
+    // Zero value with different prefix lengths.
+    {"00", 3, 0},
+    {"00", 4, 0},
+    {"00", 5, 0},
+    {"00", 6, 0},
+    {"00", 7, 0},
+    {"00", 8, 0},
+    // Small values that fit in the prefix.
+    {"06", 3, 6},
+    {"0d", 4, 13},
+    {"10", 5, 16},
+    {"29", 6, 41},
+    {"56", 7, 86},
+    {"bf", 8, 191},
+    // Values of 2^n-1, which have an all-zero extension byte.
+    {"0700", 3, 7},
+    {"0f00", 4, 15},
+    {"1f00", 5, 31},
+    {"3f00", 6, 63},
+    {"7f00", 7, 127},
+    {"ff00", 8, 255},
+    // Values of 2^n-1, plus one extra byte of padding.
+    {"078000", 3, 7},
+    {"0f8000", 4, 15},
+    {"1f8000", 5, 31},
+    {"3f8000", 6, 63},
+    {"7f8000", 7, 127},
+    {"ff8000", 8, 255},
+    // Values requiring one extension byte.
+    {"0760", 3, 103},
+    {"0f2a", 4, 57},
+    {"1f7f", 5, 158},
+    {"3f02", 6, 65},
+    {"7f49", 7, 200},
+    {"ff6f", 8, 366},
+    // Values requiring one extension byte, plus one byte of padding.
+    {"07e000", 3, 103},
+    {"0faa00", 4, 57},
+    {"1fff00", 5, 158},
+    {"3f8200", 6, 65},
+    {"7fc900", 7, 200},
+    {"ffef00", 8, 366},
+    // Values requiring one extension byte, plus two bytes of padding.
+    {"07e08000", 3, 103},
+    {"0faa8000", 4, 57},
+    {"1fff8000", 5, 158},
+    {"3f828000", 6, 65},
+    {"7fc98000", 7, 200},
+    {"ffef8000", 8, 366},
+    // Values requiring one extension byte, plus the maximum amount of padding.
+    {"07e0808080808080808000", 3, 103},
+    {"0faa808080808080808000", 4, 57},
+    {"1fff808080808080808000", 5, 158},
+    {"3f82808080808080808000", 6, 65},
+    {"7fc9808080808080808000", 7, 200},
+    {"ffef808080808080808000", 8, 366},
+    // Values requiring two extension bytes.
+    {"07b260", 3, 12345},
+    {"0f8a2a", 4, 5401},
+    {"1fa87f", 5, 16327},
+    {"3fd002", 6, 399},
+    {"7fff49", 7, 9598},
+    {"ffe32f", 8, 6370},
+    // Values requiring two extension bytes, plus one byte of padding.
+    {"07b2e000", 3, 12345},
+    {"0f8aaa00", 4, 5401},
+    {"1fa8ff00", 5, 16327},
+    {"3fd08200", 6, 399},
+    {"7fffc900", 7, 9598},
+    {"ffe3af00", 8, 6370},
+    // Values requiring two extension bytes, plus the maximum amount of padding.
+    {"07b2e080808080808000", 3, 12345},
+    {"0f8aaa80808080808000", 4, 5401},
+    {"1fa8ff80808080808000", 5, 16327},
+    {"3fd08280808080808000", 6, 399},
+    {"7fffc980808080808000", 7, 9598},
+    {"ffe3af80808080808000", 8, 6370},
+    // Values requiring three extension bytes.
+    {"078ab260", 3, 1579281},
+    {"0fc18a2a", 4, 689488},
+    {"1fada87f", 5, 2085964},
+    {"3fa0d002", 6, 43103},
+    {"7ffeff49", 7, 1212541},
+    {"ff93de23", 8, 585746},
+    // Values requiring three extension bytes, plus one byte of padding.
+    {"078ab2e000", 3, 1579281},
+    {"0fc18aaa00", 4, 689488},
+    {"1fada8ff00", 5, 2085964},
+    {"3fa0d08200", 6, 43103},
+    {"7ffeffc900", 7, 1212541},
+    {"ff93dea300", 8, 585746},
+    // Values requiring four extension bytes.
+    {"079f8ab260", 3, 202147110},
+    {"0fa2c18a2a", 4, 88252593},
+    {"1fd0ada87f", 5, 266999535},
+    {"3ff9a0d002", 6, 5509304},
+    {"7f9efeff49", 7, 155189149},
+    {"ffaa82f404", 8, 10289705},
+    // Values requiring four extension bytes, plus one byte of padding.
+    {"079f8ab2e000", 3, 202147110},
+    {"0fa2c18aaa00", 4, 88252593},
+    {"1fd0ada8ff00", 5, 266999535},
+    {"3ff9a0d08200", 6, 5509304},
+    {"7f9efeffc900", 7, 155189149},
+    {"ffaa82f48400", 8, 10289705},
+    // Values requiring six extension bytes.
+    {"0783aa9f8ab260", 3, 3311978140938},
+    {"0ff0b0a2c18a2a", 4, 1445930244223},
+    {"1fda84d0ada87f", 5, 4374519874169},
+    {"3fb5fbf9a0d002", 6, 90263420404},
+    {"7fcff19efeff49", 7, 2542616951118},
+    {"ff9fa486bbc327", 8, 1358138807070},
+    // Values requiring eight extension bytes.
+    {"07f19883aa9f8ab260", 3, 54263449861016696},
+    {"0f84fdf0b0a2c18a2a", 4, 23690121121119891},
+    {"1fa0dfda84d0ada87f", 5, 71672133617889215},
+    {"3f9ff0b5fbf9a0d002", 6, 1478875878881374},
+    {"7ffbc1cff19efeff49", 7, 41658236125045114},
+    {"ff91b6fb85af99c342", 8, 37450237664484368},
+    // Values requiring ten extension bytes.
+    {"0794f1f19883aa9f8ab201", 3, 12832019021693745307u},
+    {"0fa08f84fdf0b0a2c18a01", 4, 9980690937382242223u},
+    {"1fbfdda0dfda84d0ada801", 5, 12131360551794650846u},
+    {"3f9dc79ff0b5fbf9a0d001", 6, 15006530362736632796u},
+    {"7f8790fbc1cff19efeff01", 7, 18445754019193211014u},
+    {"fffba8c5b8d3fe9f8c8401", 8, 9518498503615141242u},
+    // Maximum value: 2^64-1.
+    {"07f8ffffffffffffffff01", 3, 18446744073709551615u},
+    {"0ff0ffffffffffffffff01", 4, 18446744073709551615u},
+    {"1fe0ffffffffffffffff01", 5, 18446744073709551615u},
+    {"3fc0ffffffffffffffff01", 6, 18446744073709551615u},
+    {"7f80ffffffffffffffff01", 7, 18446744073709551615u},
+    {"ff80feffffffffffffff01", 8, 18446744073709551615u},
+    // Examples from RFC7541 C.1.
+    {"0a", 5, 10},
+    {"1f9a0a", 5, 1337},
+};
+
+TEST_P(HpackVarintDecoderTest, Success) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kSuccessTestData); ++i) {
+    DecodeExpectSuccess(absl::HexStringToBytes(kSuccessTestData[i].data),
+                        kSuccessTestData[i].prefix_length,
+                        kSuccessTestData[i].expected_value);
+  }
+}
+
+struct {
+  const char* data;
+  uint32_t prefix_length;
+} kErrorTestData[] = {
+    // Too many extension bytes, all 0s (except for extension bit in each byte).
+    {"0780808080808080808080", 3},
+    {"0f80808080808080808080", 4},
+    {"1f80808080808080808080", 5},
+    {"3f80808080808080808080", 6},
+    {"7f80808080808080808080", 7},
+    {"ff80808080808080808080", 8},
+    // Too many extension bytes, all 1s.
+    {"07ffffffffffffffffffff", 3},
+    {"0fffffffffffffffffffff", 4},
+    {"1fffffffffffffffffffff", 5},
+    {"3fffffffffffffffffffff", 6},
+    {"7fffffffffffffffffffff", 7},
+    {"ffffffffffffffffffffff", 8},
+    // Value of 2^64, one higher than maximum of 2^64-1.
+    {"07f9ffffffffffffffff01", 3},
+    {"0ff1ffffffffffffffff01", 4},
+    {"1fe1ffffffffffffffff01", 5},
+    {"3fc1ffffffffffffffff01", 6},
+    {"7f81ffffffffffffffff01", 7},
+    {"ff81feffffffffffffff01", 8},
+    // Maximum value: 2^64-1, with one byte of padding.
+    {"07f8ffffffffffffffff8100", 3},
+    {"0ff0ffffffffffffffff8100", 4},
+    {"1fe0ffffffffffffffff8100", 5},
+    {"3fc0ffffffffffffffff8100", 6},
+    {"7f80ffffffffffffffff8100", 7},
+    {"ff80feffffffffffffff8100", 8}};
+
+TEST_P(HpackVarintDecoderTest, Error) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kErrorTestData); ++i) {
+    DecodeExpectError(absl::HexStringToBytes(kErrorTestData[i].data),
+                      kErrorTestData[i].prefix_length);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/varint/hpack_varint_encoder.cc b/quiche/http2/hpack/varint/hpack_varint_encoder.cc
new file mode 100644
index 0000000..d7fc66b
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_encoder.cc
@@ -0,0 +1,49 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/varint/hpack_varint_encoder.h"
+
+#include <limits>
+
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+// static
+void HpackVarintEncoder::Encode(uint8_t high_bits,
+                                uint8_t prefix_length,
+                                uint64_t varint,
+                                std::string* output) {
+  QUICHE_DCHECK_LE(1u, prefix_length);
+  QUICHE_DCHECK_LE(prefix_length, 8u);
+
+  // prefix_mask defines the sequence of low-order bits of the first byte
+  // that encode the prefix of the value. It is also the marker in those bits
+  // of the first byte indicating that at least one extension byte is needed.
+  const uint8_t prefix_mask = (1 << prefix_length) - 1;
+  QUICHE_DCHECK_EQ(0, high_bits & prefix_mask);
+
+  if (varint < prefix_mask) {
+    // The integer fits into the prefix in its entirety.
+    unsigned char first_byte = high_bits | static_cast<unsigned char>(varint);
+    output->push_back(first_byte);
+    return;
+  }
+
+  // Extension bytes are needed.
+  unsigned char first_byte = high_bits | prefix_mask;
+  output->push_back(first_byte);
+
+  varint -= prefix_mask;
+  while (varint >= 128) {
+    // Encode the next seven bits, with continuation bit set to one.
+    output->push_back(0b10000000 | (varint % 128));
+    varint >>= 7;
+  }
+
+  // Encode final seven bits, with continuation bit set to zero.
+  output->push_back(varint);
+}
+
+}  // namespace http2
diff --git a/quiche/http2/hpack/varint/hpack_varint_encoder.h b/quiche/http2/hpack/varint/hpack_varint_encoder.h
new file mode 100644
index 0000000..b120ece
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_encoder.h
@@ -0,0 +1,31 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_ENCODER_H_
+#define QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_ENCODER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+// HPACK integer encoder class with single static method implementing variable
+// length integer representation defined in RFC7541, Section 5.1:
+// https://httpwg.org/specs/rfc7541.html#integer.representation
+class QUICHE_EXPORT_PRIVATE HpackVarintEncoder {
+ public:
+  // Encode |varint|, appending encoded data to |*output|.
+  // Appends between 1 and 11 bytes in total.
+  static void Encode(uint8_t high_bits,
+                     uint8_t prefix_length,
+                     uint64_t varint,
+                     std::string* output);
+};
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HPACK_VARINT_HPACK_VARINT_ENCODER_H_
diff --git a/quiche/http2/hpack/varint/hpack_varint_encoder_test.cc b/quiche/http2/hpack/varint/hpack_varint_encoder_test.cc
new file mode 100644
index 0000000..bd51606
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_encoder_test.cc
@@ -0,0 +1,161 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/varint/hpack_varint_encoder.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+struct {
+  uint8_t high_bits;
+  uint8_t prefix_length;
+  uint64_t value;
+  uint8_t expected_encoding;
+} kShortTestData[] = {{0b10110010, 1, 0, 0b10110010},
+                      {0b10101100, 2, 2, 0b10101110},
+                      {0b10100000, 3, 6, 0b10100110},
+                      {0b10110000, 4, 13, 0b10111101},
+                      {0b10100000, 5, 8, 0b10101000},
+                      {0b11000000, 6, 48, 0b11110000},
+                      {0b10000000, 7, 99, 0b11100011},
+                      // Example from RFC7541 C.1.
+                      {0b00000000, 5, 10, 0b00001010}};
+
+// Encode integers that fit in the prefix.
+TEST(HpackVarintEncoderTest, Short) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kShortTestData); ++i) {
+    std::string output;
+    HpackVarintEncoder::Encode(kShortTestData[i].high_bits,
+                               kShortTestData[i].prefix_length,
+                               kShortTestData[i].value, &output);
+    ASSERT_EQ(1u, output.size());
+    EXPECT_EQ(kShortTestData[i].expected_encoding,
+              static_cast<uint8_t>(output[0]));
+  }
+}
+
+struct {
+  uint8_t high_bits;
+  uint8_t prefix_length;
+  uint64_t value;
+  const char* expected_encoding;
+} kLongTestData[] = {
+    // One extension byte.
+    {0b10011000, 3, 103, "9f60"},
+    {0b10010000, 4, 57, "9f2a"},
+    {0b11000000, 5, 158, "df7f"},
+    {0b01000000, 6, 65, "7f02"},
+    {0b00000000, 7, 200, "7f49"},
+    // Two extension bytes.
+    {0b10011000, 3, 12345, "9fb260"},
+    {0b10010000, 4, 5401, "9f8a2a"},
+    {0b11000000, 5, 16327, "dfa87f"},
+    {0b01000000, 6, 399, "7fd002"},
+    {0b00000000, 7, 9598, "7fff49"},
+    // Three extension bytes.
+    {0b10011000, 3, 1579281, "9f8ab260"},
+    {0b10010000, 4, 689488, "9fc18a2a"},
+    {0b11000000, 5, 2085964, "dfada87f"},
+    {0b01000000, 6, 43103, "7fa0d002"},
+    {0b00000000, 7, 1212541, "7ffeff49"},
+    // Four extension bytes.
+    {0b10011000, 3, 202147110, "9f9f8ab260"},
+    {0b10010000, 4, 88252593, "9fa2c18a2a"},
+    {0b11000000, 5, 266999535, "dfd0ada87f"},
+    {0b01000000, 6, 5509304, "7ff9a0d002"},
+    {0b00000000, 7, 155189149, "7f9efeff49"},
+    // Six extension bytes.
+    {0b10011000, 3, 3311978140938, "9f83aa9f8ab260"},
+    {0b10010000, 4, 1445930244223, "9ff0b0a2c18a2a"},
+    {0b11000000, 5, 4374519874169, "dfda84d0ada87f"},
+    {0b01000000, 6, 90263420404, "7fb5fbf9a0d002"},
+    {0b00000000, 7, 2542616951118, "7fcff19efeff49"},
+    // Eight extension bytes.
+    {0b10011000, 3, 54263449861016696, "9ff19883aa9f8ab260"},
+    {0b10010000, 4, 23690121121119891, "9f84fdf0b0a2c18a2a"},
+    {0b11000000, 5, 71672133617889215, "dfa0dfda84d0ada87f"},
+    {0b01000000, 6, 1478875878881374, "7f9ff0b5fbf9a0d002"},
+    {0b00000000, 7, 41658236125045114, "7ffbc1cff19efeff49"},
+    // Ten extension bytes.
+    {0b10011000, 3, 12832019021693745307u, "9f94f1f19883aa9f8ab201"},
+    {0b10010000, 4, 9980690937382242223u, "9fa08f84fdf0b0a2c18a01"},
+    {0b11000000, 5, 12131360551794650846u, "dfbfdda0dfda84d0ada801"},
+    {0b01000000, 6, 15006530362736632796u, "7f9dc79ff0b5fbf9a0d001"},
+    {0b00000000, 7, 18445754019193211014u, "7f8790fbc1cff19efeff01"},
+    // Maximum value: 2^64-1.
+    {0b10011000, 3, 18446744073709551615u, "9ff8ffffffffffffffff01"},
+    {0b10010000, 4, 18446744073709551615u, "9ff0ffffffffffffffff01"},
+    {0b11000000, 5, 18446744073709551615u, "dfe0ffffffffffffffff01"},
+    {0b01000000, 6, 18446744073709551615u, "7fc0ffffffffffffffff01"},
+    {0b00000000, 7, 18446744073709551615u, "7f80ffffffffffffffff01"},
+    // Example from RFC7541 C.1.
+    {0b00000000, 5, 1337, "1f9a0a"},
+};
+
+// Encode integers that do not fit in the prefix.
+TEST(HpackVarintEncoderTest, Long) {
+  // Test encoding byte by byte, also test encoding in
+  // a single ResumeEncoding() call.
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kLongTestData); ++i) {
+    std::string expected_encoding =
+        absl::HexStringToBytes(kLongTestData[i].expected_encoding);
+
+    std::string output;
+    HpackVarintEncoder::Encode(kLongTestData[i].high_bits,
+                               kLongTestData[i].prefix_length,
+                               kLongTestData[i].value, &output);
+
+    EXPECT_EQ(expected_encoding, output);
+  }
+}
+
+struct {
+  uint8_t high_bits;
+  uint8_t prefix_length;
+  uint64_t value;
+  uint8_t expected_encoding_first_byte;
+} kLastByteIsZeroTestData[] = {
+    {0b10110010, 1, 1, 0b10110011},   {0b10101100, 2, 3, 0b10101111},
+    {0b10101000, 3, 7, 0b10101111},   {0b10110000, 4, 15, 0b10111111},
+    {0b10100000, 5, 31, 0b10111111},  {0b11000000, 6, 63, 0b11111111},
+    {0b10000000, 7, 127, 0b11111111}, {0b00000000, 8, 255, 0b11111111}};
+
+// Make sure that the encoder outputs the last byte even when it is zero.  This
+// happens exactly when encoding  the value 2^prefix_length - 1.
+TEST(HpackVarintEncoderTest, LastByteIsZero) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kLastByteIsZeroTestData); ++i) {
+    std::string output;
+    HpackVarintEncoder::Encode(kLastByteIsZeroTestData[i].high_bits,
+                               kLastByteIsZeroTestData[i].prefix_length,
+                               kLastByteIsZeroTestData[i].value, &output);
+    ASSERT_EQ(2u, output.size());
+    EXPECT_EQ(kLastByteIsZeroTestData[i].expected_encoding_first_byte,
+              static_cast<uint8_t>(output[0]));
+    EXPECT_EQ(0b00000000, output[1]);
+  }
+}
+
+// Test that encoder appends correctly to non-empty string.
+TEST(HpackVarintEncoderTest, Append) {
+  std::string output("foo");
+  EXPECT_EQ(absl::HexStringToBytes("666f6f"), output);
+
+  HpackVarintEncoder::Encode(0b10011000, 3, 103, &output);
+  EXPECT_EQ(absl::HexStringToBytes("666f6f9f60"), output);
+
+  HpackVarintEncoder::Encode(0b10100000, 5, 8, &output);
+  EXPECT_EQ(absl::HexStringToBytes("666f6f9f60a8"), output);
+
+  HpackVarintEncoder::Encode(0b10011000, 3, 202147110, &output);
+  EXPECT_EQ(absl::HexStringToBytes("666f6f9f60a89f9f8ab260"), output);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/hpack/varint/hpack_varint_round_trip_test.cc b/quiche/http2/hpack/varint/hpack_varint_round_trip_test.cc
new file mode 100644
index 0000000..44d5b46
--- /dev/null
+++ b/quiche/http2/hpack/varint/hpack_varint_round_trip_test.cc
@@ -0,0 +1,420 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+
+// Test HpackVarintDecoder against data encoded via HpackBlockBuilder,
+// which uses HpackVarintEncoder under the hood.
+
+#include <stddef.h>
+
+#include <iterator>
+#include <set>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/tools/random_decoder_test.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using ::testing::AssertionFailure;
+using ::testing::AssertionSuccess;
+
+namespace http2 {
+namespace test {
+namespace {
+
+// Returns the highest value with the specified number of extension bytes
+// and the specified prefix length (bits).
+uint64_t HiValueOfExtensionBytes(uint32_t extension_bytes,
+                                 uint32_t prefix_length) {
+  return (1 << prefix_length) - 2 +
+         (extension_bytes == 0 ? 0 : (1LLU << (extension_bytes * 7)));
+}
+
+class HpackVarintRoundTripTest : public RandomDecoderTest {
+ protected:
+  HpackVarintRoundTripTest() : prefix_length_(0) {}
+
+  DecodeStatus StartDecoding(DecodeBuffer* b) override {
+    QUICHE_CHECK_LT(0u, b->Remaining());
+    uint8_t prefix = b->DecodeUInt8();
+    return decoder_.Start(prefix, prefix_length_, b);
+  }
+
+  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
+    return decoder_.Resume(b);
+  }
+
+  void DecodeSeveralWays(uint64_t expected_value, uint32_t expected_offset) {
+    // The validator is called after each of the several times that the input
+    // DecodeBuffer is decoded, each with a different segmentation of the input.
+    // Validate that decoder_.value() matches the expected value.
+    Validator validator = [expected_value, this](
+                              const DecodeBuffer& /*db*/,
+                              DecodeStatus /*status*/) -> AssertionResult {
+      if (decoder_.value() != expected_value) {
+        return AssertionFailure()
+               << "Value doesn't match expected: " << decoder_.value()
+               << " != " << expected_value;
+      }
+      return AssertionSuccess();
+    };
+
+    // First validate that decoding is done and that we've advanced the cursor
+    // the expected amount.
+    validator = ValidateDoneAndOffset(expected_offset, validator);
+
+    // StartDecoding, above, requires the DecodeBuffer be non-empty so that it
+    // can call Start with the prefix byte.
+    bool return_non_zero_on_first = true;
+
+    DecodeBuffer b(buffer_);
+    EXPECT_TRUE(
+        DecodeAndValidateSeveralWays(&b, return_non_zero_on_first, validator));
+
+    EXPECT_EQ(expected_value, decoder_.value());
+    EXPECT_EQ(expected_offset, b.Offset());
+  }
+
+  void EncodeNoRandom(uint64_t value, uint8_t prefix_length) {
+    QUICHE_DCHECK_LE(3, prefix_length);
+    QUICHE_DCHECK_LE(prefix_length, 8);
+    prefix_length_ = prefix_length;
+
+    HpackBlockBuilder bb;
+    bb.AppendHighBitsAndVarint(0, prefix_length_, value);
+    buffer_ = bb.buffer();
+    ASSERT_LT(0u, buffer_.size());
+
+    const uint8_t prefix_mask = (1 << prefix_length_) - 1;
+    ASSERT_EQ(static_cast<uint8_t>(buffer_[0]),
+              static_cast<uint8_t>(buffer_[0]) & prefix_mask);
+  }
+
+  void Encode(uint64_t value, uint8_t prefix_length) {
+    EncodeNoRandom(value, prefix_length);
+    // Add some random bits to the prefix (the first byte) above the mask.
+    uint8_t prefix = buffer_[0];
+    buffer_[0] = prefix | (Random().Rand8() << prefix_length);
+    const uint8_t prefix_mask = (1 << prefix_length_) - 1;
+    ASSERT_EQ(prefix, buffer_[0] & prefix_mask);
+  }
+
+  // This is really a test of HpackBlockBuilder, making sure that the input to
+  // HpackVarintDecoder is as expected, which also acts as confirmation that
+  // my thinking about the encodings being used by the tests, i.e. cover the
+  // range desired.
+  void ValidateEncoding(uint64_t value,
+                        uint64_t minimum,
+                        uint64_t maximum,
+                        size_t expected_bytes) {
+    ASSERT_EQ(expected_bytes, buffer_.size());
+    if (expected_bytes > 1) {
+      const uint8_t prefix_mask = (1 << prefix_length_) - 1;
+      EXPECT_EQ(prefix_mask, buffer_[0] & prefix_mask);
+      size_t last = expected_bytes - 1;
+      for (size_t ndx = 1; ndx < last; ++ndx) {
+        // Before the last extension byte, we expect the high-bit set.
+        uint8_t byte = buffer_[ndx];
+        if (value == minimum) {
+          EXPECT_EQ(0x80, byte) << "ndx=" << ndx;
+        } else if (value == maximum) {
+          if (expected_bytes < 11) {
+            EXPECT_EQ(0xff, byte) << "ndx=" << ndx;
+          }
+        } else {
+          EXPECT_EQ(0x80, byte & 0x80) << "ndx=" << ndx;
+        }
+      }
+      // The last extension byte should not have the high-bit set.
+      uint8_t byte = buffer_[last];
+      if (value == minimum) {
+        if (expected_bytes == 2) {
+          EXPECT_EQ(0x00, byte);
+        } else {
+          EXPECT_EQ(0x01, byte);
+        }
+      } else if (value == maximum) {
+        if (expected_bytes < 11) {
+          EXPECT_EQ(0x7f, byte);
+        }
+      } else {
+        EXPECT_EQ(0x00, byte & 0x80);
+      }
+    } else {
+      const uint8_t prefix_mask = (1 << prefix_length_) - 1;
+      EXPECT_EQ(value, static_cast<uint32_t>(buffer_[0] & prefix_mask));
+      EXPECT_LT(value, prefix_mask);
+    }
+  }
+
+  void EncodeAndDecodeValues(const std::set<uint64_t>& values,
+                             uint8_t prefix_length,
+                             size_t expected_bytes) {
+    QUICHE_CHECK(!values.empty());
+    const uint64_t minimum = *values.begin();
+    const uint64_t maximum = *values.rbegin();
+    for (const uint64_t value : values) {
+      Encode(value, prefix_length);  // Sets buffer_.
+
+      std::string msg = absl::StrCat("value=", value, " (0x", absl::Hex(value),
+                                     "), prefix_length=", prefix_length,
+                                     ", expected_bytes=", expected_bytes, "\n",
+                                     quiche::QuicheTextUtils::HexDump(buffer_));
+
+      if (value == minimum) {
+        HTTP2_LOG(INFO) << "Checking minimum; " << msg;
+      } else if (value == maximum) {
+        HTTP2_LOG(INFO) << "Checking maximum; " << msg;
+      }
+
+      SCOPED_TRACE(msg);
+      ValidateEncoding(value, minimum, maximum, expected_bytes);
+      DecodeSeveralWays(value, expected_bytes);
+
+      // Append some random data to the end of buffer_ and repeat. That random
+      // data should be ignored.
+      buffer_.append(Random().RandString(1 + Random().Uniform(10)));
+      DecodeSeveralWays(value, expected_bytes);
+
+      // If possible, add extension bytes that don't change the value.
+      if (1 < expected_bytes) {
+        buffer_.resize(expected_bytes);
+        for (uint8_t total_bytes = expected_bytes + 1; total_bytes <= 6;
+             ++total_bytes) {
+          // Mark the current last byte as not being the last one.
+          EXPECT_EQ(0x00, 0x80 & buffer_.back());
+          buffer_.back() |= 0x80;
+          buffer_.push_back('\0');
+          DecodeSeveralWays(value, total_bytes);
+        }
+      }
+    }
+  }
+
+  // Encode values (all or some of it) in [start, start+range).  Check
+  // that |start| is the smallest value and |start+range-1| is the largest value
+  // corresponding to |expected_bytes|, except if |expected_bytes| is maximal.
+  void EncodeAndDecodeValuesInRange(uint64_t start,
+                                    uint64_t range,
+                                    uint8_t prefix_length,
+                                    size_t expected_bytes) {
+    const uint8_t prefix_mask = (1 << prefix_length) - 1;
+    const uint64_t beyond = start + range;
+
+    HTTP2_LOG(INFO)
+        << "############################################################";
+    HTTP2_LOG(INFO) << "prefix_length=" << static_cast<int>(prefix_length);
+    HTTP2_LOG(INFO) << "prefix_mask=" << std::hex
+                    << static_cast<int>(prefix_mask);
+    HTTP2_LOG(INFO) << "start=" << start << " (" << std::hex << start << ")";
+    HTTP2_LOG(INFO) << "range=" << range << " (" << std::hex << range << ")";
+    HTTP2_LOG(INFO) << "beyond=" << beyond << " (" << std::hex << beyond << ")";
+    HTTP2_LOG(INFO) << "expected_bytes=" << expected_bytes;
+
+    if (expected_bytes < 11) {
+      // Confirm the claim that beyond requires more bytes.
+      Encode(beyond, prefix_length);
+      EXPECT_EQ(expected_bytes + 1, buffer_.size())
+          << quiche::QuicheTextUtils::HexDump(buffer_);
+    }
+
+    std::set<uint64_t> values;
+    if (range < 200) {
+      // Select all values in the range.
+      for (uint64_t offset = 0; offset < range; ++offset) {
+        values.insert(start + offset);
+      }
+    } else {
+      // Select some values in this range, including the minimum and maximum
+      // values that require exactly |expected_bytes| extension bytes.
+      values.insert({start, start + 1, beyond - 2, beyond - 1});
+      while (values.size() < 100) {
+        values.insert(Random().UniformInRange(start, beyond - 1));
+      }
+    }
+
+    EncodeAndDecodeValues(values, prefix_length, expected_bytes);
+  }
+
+  HpackVarintDecoder decoder_;
+  std::string buffer_;
+  uint8_t prefix_length_;
+};
+
+// To help me and future debuggers of varint encodings, this HTTP2_LOGs out the
+// transition points where a new extension byte is added.
+TEST_F(HpackVarintRoundTripTest, Encode) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t a = HiValueOfExtensionBytes(0, prefix_length);
+    const uint64_t b = HiValueOfExtensionBytes(1, prefix_length);
+    const uint64_t c = HiValueOfExtensionBytes(2, prefix_length);
+    const uint64_t d = HiValueOfExtensionBytes(3, prefix_length);
+    const uint64_t e = HiValueOfExtensionBytes(4, prefix_length);
+    const uint64_t f = HiValueOfExtensionBytes(5, prefix_length);
+    const uint64_t g = HiValueOfExtensionBytes(6, prefix_length);
+    const uint64_t h = HiValueOfExtensionBytes(7, prefix_length);
+    const uint64_t i = HiValueOfExtensionBytes(8, prefix_length);
+    const uint64_t j = HiValueOfExtensionBytes(9, prefix_length);
+
+    HTTP2_LOG(INFO)
+        << "############################################################";
+    HTTP2_LOG(INFO) << "prefix_length=" << prefix_length << "   a=" << a
+                    << "   b=" << b << "   c=" << c << "   d=" << d
+                    << "   e=" << e << "   f=" << f << "   g=" << g
+                    << "   h=" << h << "   i=" << i << "   j=" << j;
+
+    std::vector<uint64_t> values = {
+        0,     1,                       // Force line break.
+        a - 1, a, a + 1, a + 2, a + 3,  // Force line break.
+        b - 1, b, b + 1, b + 2, b + 3,  // Force line break.
+        c - 1, c, c + 1, c + 2, c + 3,  // Force line break.
+        d - 1, d, d + 1, d + 2, d + 3,  // Force line break.
+        e - 1, e, e + 1, e + 2, e + 3,  // Force line break.
+        f - 1, f, f + 1, f + 2, f + 3,  // Force line break.
+        g - 1, g, g + 1, g + 2, g + 3,  // Force line break.
+        h - 1, h, h + 1, h + 2, h + 3,  // Force line break.
+        i - 1, i, i + 1, i + 2, i + 3,  // Force line break.
+        j - 1, j, j + 1, j + 2, j + 3,  // Force line break.
+    };
+
+    for (uint64_t value : values) {
+      EncodeNoRandom(value, prefix_length);
+      std::string dump = quiche::QuicheTextUtils::HexDump(buffer_);
+      HTTP2_LOG(INFO) << absl::StrFormat("%10llu %0#18x ", value, value)
+                      << quiche::QuicheTextUtils::HexDump(buffer_).substr(7);
+    }
+  }
+}
+
+TEST_F(HpackVarintRoundTripTest, FromSpec1337) {
+  DecodeBuffer b(absl::string_view("\x1f\x9a\x0a"));
+  uint32_t prefix_length = 5;
+  uint8_t p = b.DecodeUInt8();
+  EXPECT_EQ(1u, b.Offset());
+  EXPECT_EQ(DecodeStatus::kDecodeDone, decoder_.Start(p, prefix_length, &b));
+  EXPECT_EQ(3u, b.Offset());
+  EXPECT_EQ(1337u, decoder_.value());
+
+  EncodeNoRandom(1337, prefix_length);
+  EXPECT_EQ(3u, buffer_.size());
+  EXPECT_EQ('\x1f', buffer_[0]);
+  EXPECT_EQ('\x9a', buffer_[1]);
+  EXPECT_EQ('\x0a', buffer_[2]);
+}
+
+// Test all the values that fit into the prefix (one less than the mask).
+TEST_F(HpackVarintRoundTripTest, ValidatePrefixOnly) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint8_t prefix_mask = (1 << prefix_length) - 1;
+    EncodeAndDecodeValuesInRange(0, prefix_mask, prefix_length, 1);
+  }
+}
+
+// Test all values that require exactly 1 extension byte.
+TEST_F(HpackVarintRoundTripTest, ValidateOneExtensionByte) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(0, prefix_length) + 1;
+    EncodeAndDecodeValuesInRange(start, 128, prefix_length, 2);
+  }
+}
+
+// Test *some* values that require exactly 2 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateTwoExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(1, prefix_length) + 1;
+    const uint64_t range = 127 << 7;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 3);
+  }
+}
+
+// Test *some* values that require 3 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateThreeExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(2, prefix_length) + 1;
+    const uint64_t range = 127 << 14;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 4);
+  }
+}
+
+// Test *some* values that require 4 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateFourExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(3, prefix_length) + 1;
+    const uint64_t range = 127 << 21;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 5);
+  }
+}
+
+// Test *some* values that require 5 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateFiveExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(4, prefix_length) + 1;
+    const uint64_t range = 127llu << 28;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 6);
+  }
+}
+
+// Test *some* values that require 6 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateSixExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(5, prefix_length) + 1;
+    const uint64_t range = 127llu << 35;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 7);
+  }
+}
+
+// Test *some* values that require 7 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateSevenExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(6, prefix_length) + 1;
+    const uint64_t range = 127llu << 42;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 8);
+  }
+}
+
+// Test *some* values that require 8 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateEightExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(7, prefix_length) + 1;
+    const uint64_t range = 127llu << 49;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 9);
+  }
+}
+
+// Test *some* values that require 9 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateNineExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(8, prefix_length) + 1;
+    const uint64_t range = 127llu << 56;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 10);
+  }
+}
+
+// Test *some* values that require 10 extension bytes.
+TEST_F(HpackVarintRoundTripTest, ValidateTenExtensionBytes) {
+  for (int prefix_length = 3; prefix_length <= 8; ++prefix_length) {
+    const uint64_t start = HiValueOfExtensionBytes(9, prefix_length) + 1;
+    const uint64_t range = std::numeric_limits<uint64_t>::max() - start;
+
+    EncodeAndDecodeValuesInRange(start, range, prefix_length, 11);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/http2_constants.cc b/quiche/http2/http2_constants.cc
new file mode 100644
index 0000000..3b947b5
--- /dev/null
+++ b/quiche/http2/http2_constants.cc
@@ -0,0 +1,180 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/http2_constants.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/platform/api/http2_flag_utils.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+
+namespace http2 {
+
+std::string Http2FrameTypeToString(Http2FrameType v) {
+  switch (v) {
+    case Http2FrameType::DATA:
+      return "DATA";
+    case Http2FrameType::HEADERS:
+      return "HEADERS";
+    case Http2FrameType::PRIORITY:
+      return "PRIORITY";
+    case Http2FrameType::RST_STREAM:
+      return "RST_STREAM";
+    case Http2FrameType::SETTINGS:
+      return "SETTINGS";
+    case Http2FrameType::PUSH_PROMISE:
+      return "PUSH_PROMISE";
+    case Http2FrameType::PING:
+      return "PING";
+    case Http2FrameType::GOAWAY:
+      return "GOAWAY";
+    case Http2FrameType::WINDOW_UPDATE:
+      return "WINDOW_UPDATE";
+    case Http2FrameType::CONTINUATION:
+      return "CONTINUATION";
+    case Http2FrameType::ALTSVC:
+      return "ALTSVC";
+    case Http2FrameType::PRIORITY_UPDATE:
+      return "PRIORITY_UPDATE";
+  }
+  return absl::StrCat("UnknownFrameType(", static_cast<int>(v), ")");
+}
+
+std::string Http2FrameTypeToString(uint8_t v) {
+  return Http2FrameTypeToString(static_cast<Http2FrameType>(v));
+}
+
+std::string Http2FrameFlagsToString(Http2FrameType type, uint8_t flags) {
+  std::string s;
+  // Closure to append flag name |v| to the std::string |s|,
+  // and to clear |bit| from |flags|.
+  auto append_and_clear = [&s, &flags](absl::string_view v, uint8_t bit) {
+    if (!s.empty()) {
+      s.push_back('|');
+    }
+    absl::StrAppend(&s, v);
+    flags ^= bit;
+  };
+  if (flags & 0x01) {
+    if (type == Http2FrameType::DATA || type == Http2FrameType::HEADERS) {
+      append_and_clear("END_STREAM", Http2FrameFlag::END_STREAM);
+    } else if (type == Http2FrameType::SETTINGS ||
+               type == Http2FrameType::PING) {
+      append_and_clear("ACK", Http2FrameFlag::ACK);
+    }
+  }
+  if (flags & 0x04) {
+    if (type == Http2FrameType::HEADERS ||
+        type == Http2FrameType::PUSH_PROMISE ||
+        type == Http2FrameType::CONTINUATION) {
+      append_and_clear("END_HEADERS", Http2FrameFlag::END_HEADERS);
+    }
+  }
+  if (flags & 0x08) {
+    if (type == Http2FrameType::DATA || type == Http2FrameType::HEADERS ||
+        type == Http2FrameType::PUSH_PROMISE) {
+      append_and_clear("PADDED", Http2FrameFlag::PADDED);
+    }
+  }
+  if (flags & 0x20) {
+    if (type == Http2FrameType::HEADERS) {
+      append_and_clear("PRIORITY", Http2FrameFlag::PRIORITY);
+    }
+  }
+  if (flags != 0) {
+    append_and_clear(absl::StrFormat("0x%02x", flags), flags);
+  }
+  QUICHE_DCHECK_EQ(0, flags);
+  return s;
+}
+std::string Http2FrameFlagsToString(uint8_t type, uint8_t flags) {
+  return Http2FrameFlagsToString(static_cast<Http2FrameType>(type), flags);
+}
+
+std::string Http2ErrorCodeToString(uint32_t v) {
+  switch (v) {
+    case 0x0:
+      return "NO_ERROR";
+    case 0x1:
+      return "PROTOCOL_ERROR";
+    case 0x2:
+      return "INTERNAL_ERROR";
+    case 0x3:
+      return "FLOW_CONTROL_ERROR";
+    case 0x4:
+      return "SETTINGS_TIMEOUT";
+    case 0x5:
+      return "STREAM_CLOSED";
+    case 0x6:
+      return "FRAME_SIZE_ERROR";
+    case 0x7:
+      return "REFUSED_STREAM";
+    case 0x8:
+      return "CANCEL";
+    case 0x9:
+      return "COMPRESSION_ERROR";
+    case 0xa:
+      return "CONNECT_ERROR";
+    case 0xb:
+      return "ENHANCE_YOUR_CALM";
+    case 0xc:
+      return "INADEQUATE_SECURITY";
+    case 0xd:
+      return "HTTP_1_1_REQUIRED";
+  }
+  return absl::StrCat("UnknownErrorCode(0x", absl::Hex(v), ")");
+}
+std::string Http2ErrorCodeToString(Http2ErrorCode v) {
+  return Http2ErrorCodeToString(static_cast<uint32_t>(v));
+}
+
+std::string Http2SettingsParameterToString(uint32_t v) {
+  switch (v) {
+    case 0x1:
+      return "HEADER_TABLE_SIZE";
+    case 0x2:
+      return "ENABLE_PUSH";
+    case 0x3:
+      return "MAX_CONCURRENT_STREAMS";
+    case 0x4:
+      return "INITIAL_WINDOW_SIZE";
+    case 0x5:
+      return "MAX_FRAME_SIZE";
+    case 0x6:
+      return "MAX_HEADER_LIST_SIZE";
+  }
+  return absl::StrCat("UnknownSettingsParameter(0x", absl::Hex(v), ")");
+}
+std::string Http2SettingsParameterToString(Http2SettingsParameter v) {
+  return Http2SettingsParameterToString(static_cast<uint32_t>(v));
+}
+
+// Invalid HTTP/2 header names according to
+// https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2.
+// TODO(b/78024822): Consider adding "upgrade" to this set.
+constexpr char const* kHttp2InvalidHeaderNames[] = {
+    "connection",        "host", "keep-alive", "proxy-connection",
+    "transfer-encoding", "",
+};
+
+constexpr char const* kHttp2InvalidHeaderNamesOld[] = {
+    "connection", "host", "keep-alive", "proxy-connection", "transfer-encoding",
+};
+
+const InvalidHeaderSet& GetInvalidHttp2HeaderSet() {
+  if (!GetQuicheReloadableFlag(quic, quic_verify_request_headers_2)) {
+    static const auto* invalid_header_set_old =
+        new InvalidHeaderSet(std::begin(http2::kHttp2InvalidHeaderNamesOld),
+                             std::end(http2::kHttp2InvalidHeaderNamesOld));
+    return *invalid_header_set_old;
+  }
+  HTTP2_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 3, 3);
+  static const auto* invalid_header_set =
+      new InvalidHeaderSet(std::begin(http2::kHttp2InvalidHeaderNames),
+                           std::end(http2::kHttp2InvalidHeaderNames));
+  return *invalid_header_set;
+}
+
+}  // namespace http2
diff --git a/quiche/http2/http2_constants.h b/quiche/http2/http2_constants.h
new file mode 100644
index 0000000..35cb61f
--- /dev/null
+++ b/quiche/http2/http2_constants.h
@@ -0,0 +1,272 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HTTP2_CONSTANTS_H_
+#define QUICHE_HTTP2_HTTP2_CONSTANTS_H_
+
+// Constants from the HTTP/2 spec, RFC 7540, and associated helper functions.
+
+#include <cstdint>
+#include <iosfwd>
+#include <ostream>
+#include <string>
+
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/platform/api/http2_flags.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace http2 {
+
+// TODO(jamessynge): create http2_simple_types for types similar to
+// SpdyStreamId, but not for structures like Http2FrameHeader. Then will be
+// able to move these stream id functions there.
+constexpr uint32_t UInt31Mask() { return 0x7fffffff; }
+constexpr uint32_t StreamIdMask() { return UInt31Mask(); }
+
+// The value used to identify types of frames. Upper case to match the RFC.
+// The comments indicate which flags are valid for that frame type.
+enum class Http2FrameType : uint8_t {
+  DATA = 0,           // END_STREAM | PADDED
+  HEADERS = 1,        // END_STREAM | END_HEADERS | PADDED | PRIORITY
+  PRIORITY = 2,       //
+  RST_STREAM = 3,     //
+  SETTINGS = 4,       // ACK
+  PUSH_PROMISE = 5,   // END_HEADERS | PADDED
+  PING = 6,           // ACK
+  GOAWAY = 7,         //
+  WINDOW_UPDATE = 8,  //
+  CONTINUATION = 9,   // END_HEADERS
+  // https://tools.ietf.org/html/rfc7838
+  ALTSVC = 10,  // no flags
+  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-02
+  PRIORITY_UPDATE = 16,  // no flags
+};
+
+// Is the frame type known/supported?
+inline bool IsSupportedHttp2FrameType(uint32_t v) {
+  return v <= static_cast<uint32_t>(Http2FrameType::ALTSVC) ||
+         v == static_cast<uint32_t>(Http2FrameType::PRIORITY_UPDATE);
+}
+inline bool IsSupportedHttp2FrameType(Http2FrameType v) {
+  return IsSupportedHttp2FrameType(static_cast<uint32_t>(v));
+}
+
+// The return type is 'std::string' so that they can generate a unique string
+// for each unsupported value. Since these are just used for debugging/error
+// messages, that isn't a cost to we need to worry about. The same applies to
+// the functions later in this file.
+QUICHE_EXPORT_PRIVATE std::string Http2FrameTypeToString(Http2FrameType v);
+QUICHE_EXPORT_PRIVATE std::string Http2FrameTypeToString(uint8_t v);
+QUICHE_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
+                                                      Http2FrameType v) {
+  return out << Http2FrameTypeToString(v);
+}
+
+// Flags that appear in supported frame types. These are treated as bit masks.
+// The comments indicate for which frame types the flag is valid.
+enum Http2FrameFlag : uint8_t {
+  END_STREAM = 0x01,   // DATA, HEADERS
+  ACK = 0x01,          // SETTINGS, PING
+  END_HEADERS = 0x04,  // HEADERS, PUSH_PROMISE, CONTINUATION
+  PADDED = 0x08,       // DATA, HEADERS, PUSH_PROMISE
+  PRIORITY = 0x20,     // HEADERS
+};
+
+// Formats zero or more flags for the specified type of frame. Returns an
+// empty string if flags==0.
+QUICHE_EXPORT_PRIVATE std::string Http2FrameFlagsToString(Http2FrameType type,
+                                                          uint8_t flags);
+QUICHE_EXPORT_PRIVATE std::string Http2FrameFlagsToString(uint8_t type,
+                                                          uint8_t flags);
+
+// Error codes for GOAWAY and RST_STREAM frames.
+enum class Http2ErrorCode : uint32_t {
+  // The associated condition is not a result of an error. For example, a GOAWAY
+  // might include this code to indicate graceful shutdown of a connection.
+  HTTP2_NO_ERROR = 0x0,
+
+  // The endpoint detected an unspecific protocol error. This error is for use
+  // when a more specific error code is not available.
+  PROTOCOL_ERROR = 0x1,
+
+  // The endpoint encountered an unexpected internal error.
+  INTERNAL_ERROR = 0x2,
+
+  // The endpoint detected that its peer violated the flow-control protocol.
+  FLOW_CONTROL_ERROR = 0x3,
+
+  // The endpoint sent a SETTINGS frame but did not receive a response in a
+  // timely manner. See Section 6.5.3 ("Settings Synchronization").
+  SETTINGS_TIMEOUT = 0x4,
+
+  // The endpoint received a frame after a stream was half-closed.
+  STREAM_CLOSED = 0x5,
+
+  // The endpoint received a frame with an invalid size.
+  FRAME_SIZE_ERROR = 0x6,
+
+  // The endpoint refused the stream prior to performing any application
+  // processing (see Section 8.1.4 for details).
+  REFUSED_STREAM = 0x7,
+
+  // Used by the endpoint to indicate that the stream is no longer needed.
+  CANCEL = 0x8,
+
+  // The endpoint is unable to maintain the header compression context
+  // for the connection.
+  COMPRESSION_ERROR = 0x9,
+
+  // The connection established in response to a CONNECT request (Section 8.3)
+  // was reset or abnormally closed.
+  CONNECT_ERROR = 0xa,
+
+  // The endpoint detected that its peer is exhibiting a behavior that might
+  // be generating excessive load.
+  ENHANCE_YOUR_CALM = 0xb,
+
+  // The underlying transport has properties that do not meet minimum
+  // security requirements (see Section 9.2).
+  INADEQUATE_SECURITY = 0xc,
+
+  // The endpoint requires that HTTP/1.1 be used instead of HTTP/2.
+  HTTP_1_1_REQUIRED = 0xd,
+};
+
+// Is the error code supported? (So far that means it is in RFC 7540.)
+inline bool IsSupportedHttp2ErrorCode(uint32_t v) {
+  return v <= static_cast<uint32_t>(Http2ErrorCode::HTTP_1_1_REQUIRED);
+}
+inline bool IsSupportedHttp2ErrorCode(Http2ErrorCode v) {
+  return IsSupportedHttp2ErrorCode(static_cast<uint32_t>(v));
+}
+
+// Format the specified error code.
+QUICHE_EXPORT_PRIVATE std::string Http2ErrorCodeToString(uint32_t v);
+QUICHE_EXPORT_PRIVATE std::string Http2ErrorCodeToString(Http2ErrorCode v);
+QUICHE_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
+                                                      Http2ErrorCode v) {
+  return out << Http2ErrorCodeToString(v);
+}
+
+// Supported parameters in SETTINGS frames; so far just those in RFC 7540.
+enum class Http2SettingsParameter : uint16_t {
+  // Allows the sender to inform the remote endpoint of the maximum size of the
+  // header compression table used to decode header blocks, in octets. The
+  // encoder can select any size equal to or less than this value by using
+  // signaling specific to the header compression format inside a header block
+  // (see [COMPRESSION]). The initial value is 4,096 octets.
+  HEADER_TABLE_SIZE = 0x1,
+
+  // This setting can be used to disable server push (Section 8.2). An endpoint
+  // MUST NOT send a PUSH_PROMISE frame if it receives this parameter set to a
+  // value of 0. An endpoint that has both set this parameter to 0 and had it
+  // acknowledged MUST treat the receipt of a PUSH_PROMISE frame as a connection
+  // error (Section 5.4.1) of type PROTOCOL_ERROR.
+  //
+  // The initial value is 1, which indicates that server push is permitted. Any
+  // value other than 0 or 1 MUST be treated as a connection error (Section
+  // 5.4.1) of type PROTOCOL_ERROR.
+  ENABLE_PUSH = 0x2,
+
+  // Indicates the maximum number of concurrent streams that the sender will
+  // allow. This limit is directional: it applies to the number of streams that
+  // the sender permits the receiver to create. Initially, there is no limit to
+  // this value. It is recommended that this value be no smaller than 100, so as
+  // to not unnecessarily limit parallelism.
+  //
+  // A value of 0 for MAX_CONCURRENT_STREAMS SHOULD NOT be treated as
+  // special by endpoints. A zero value does prevent the creation of new
+  // streams; however, this can also happen for any limit that is exhausted with
+  // active streams. Servers SHOULD only set a zero value for short durations;
+  // if a server does not wish to accept requests, closing the connection is
+  // more appropriate.
+  MAX_CONCURRENT_STREAMS = 0x3,
+
+  // Indicates the sender's initial window size (in octets) for stream-level
+  // flow control. The initial value is 2^16-1 (65,535) octets.
+  //
+  // This setting affects the window size of all streams (see Section 6.9.2).
+  //
+  // Values above the maximum flow-control window size of 2^31-1 MUST be treated
+  // as a connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR.
+  INITIAL_WINDOW_SIZE = 0x4,
+
+  // Indicates the size of the largest frame payload that the sender is willing
+  // to receive, in octets.
+  //
+  // The initial value is 2^14 (16,384) octets. The value advertised by an
+  // endpoint MUST be between this initial value and the maximum allowed frame
+  // size (2^24-1 or 16,777,215 octets), inclusive. Values outside this range
+  // MUST be treated as a connection error (Section 5.4.1) of type
+  // PROTOCOL_ERROR.
+  MAX_FRAME_SIZE = 0x5,
+
+  // This advisory setting informs a peer of the maximum size of header list
+  // that the sender is prepared to accept, in octets. The value is based on the
+  // uncompressed size of header fields, including the length of the name and
+  // value in octets plus an overhead of 32 octets for each header field.
+  //
+  // For any given request, a lower limit than what is advertised MAY be
+  // enforced. The initial value of this setting is unlimited.
+  MAX_HEADER_LIST_SIZE = 0x6,
+};
+
+// Is the settings parameter supported (so far that means it is in RFC 7540)?
+inline bool IsSupportedHttp2SettingsParameter(uint32_t v) {
+  return 0 < v && v <= static_cast<uint32_t>(
+                           Http2SettingsParameter::MAX_HEADER_LIST_SIZE);
+}
+inline bool IsSupportedHttp2SettingsParameter(Http2SettingsParameter v) {
+  return IsSupportedHttp2SettingsParameter(static_cast<uint32_t>(v));
+}
+
+// Format the specified settings parameter.
+QUICHE_EXPORT_PRIVATE std::string Http2SettingsParameterToString(uint32_t v);
+QUICHE_EXPORT_PRIVATE std::string Http2SettingsParameterToString(
+    Http2SettingsParameter v);
+inline std::ostream& operator<<(std::ostream& out, Http2SettingsParameter v) {
+  return out << Http2SettingsParameterToString(v);
+}
+
+// Information about the initial, minimum and maximum value of settings (not
+// applicable to all settings parameters).
+class QUICHE_EXPORT_PRIVATE Http2SettingsInfo {
+ public:
+  // Default value for HEADER_TABLE_SIZE.
+  static constexpr uint32_t DefaultHeaderTableSize() { return 4096; }
+
+  // Default value for ENABLE_PUSH.
+  static constexpr bool DefaultEnablePush() { return true; }
+
+  // Default value for INITIAL_WINDOW_SIZE.
+  static constexpr uint32_t DefaultInitialWindowSize() { return 65535; }
+
+  // Maximum value for INITIAL_WINDOW_SIZE, and for the connection flow control
+  // window, and for each stream flow control window.
+  static constexpr uint32_t MaximumWindowSize() { return UInt31Mask(); }
+
+  // Default value for MAX_FRAME_SIZE.
+  static constexpr uint32_t DefaultMaxFrameSize() { return 16384; }
+
+  // Minimum value for MAX_FRAME_SIZE.
+  static constexpr uint32_t MinimumMaxFrameSize() { return 16384; }
+
+  // Maximum value for MAX_FRAME_SIZE.
+  static constexpr uint32_t MaximumMaxFrameSize() { return (1 << 24) - 1; }
+};
+
+// Http3 early fails upper case request headers, but Http2 still needs case
+// insensitive comparison.
+using InvalidHeaderSet =
+    absl::flat_hash_set<absl::string_view, quiche::StringPieceCaseHash,
+                        quiche::StringPieceCaseEqual>;
+
+// Returns all disallowed HTTP/2 headers.
+QUICHE_EXPORT_PRIVATE const InvalidHeaderSet& GetInvalidHttp2HeaderSet();
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HTTP2_CONSTANTS_H_
diff --git a/quiche/http2/http2_constants_test.cc b/quiche/http2/http2_constants_test.cc
new file mode 100644
index 0000000..34cc60a
--- /dev/null
+++ b/quiche/http2/http2_constants_test.cc
@@ -0,0 +1,272 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/http2_constants.h"
+
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+class Http2ConstantsTest : public QuicheTest {};
+
+TEST(Http2ConstantsTest, Http2FrameType) {
+  EXPECT_EQ(Http2FrameType::DATA, static_cast<Http2FrameType>(0));
+  EXPECT_EQ(Http2FrameType::HEADERS, static_cast<Http2FrameType>(1));
+  EXPECT_EQ(Http2FrameType::PRIORITY, static_cast<Http2FrameType>(2));
+  EXPECT_EQ(Http2FrameType::RST_STREAM, static_cast<Http2FrameType>(3));
+  EXPECT_EQ(Http2FrameType::SETTINGS, static_cast<Http2FrameType>(4));
+  EXPECT_EQ(Http2FrameType::PUSH_PROMISE, static_cast<Http2FrameType>(5));
+  EXPECT_EQ(Http2FrameType::PING, static_cast<Http2FrameType>(6));
+  EXPECT_EQ(Http2FrameType::GOAWAY, static_cast<Http2FrameType>(7));
+  EXPECT_EQ(Http2FrameType::WINDOW_UPDATE, static_cast<Http2FrameType>(8));
+  EXPECT_EQ(Http2FrameType::CONTINUATION, static_cast<Http2FrameType>(9));
+  EXPECT_EQ(Http2FrameType::ALTSVC, static_cast<Http2FrameType>(10));
+}
+
+TEST(Http2ConstantsTest, Http2FrameTypeToString) {
+  EXPECT_EQ("DATA", Http2FrameTypeToString(Http2FrameType::DATA));
+  EXPECT_EQ("HEADERS", Http2FrameTypeToString(Http2FrameType::HEADERS));
+  EXPECT_EQ("PRIORITY", Http2FrameTypeToString(Http2FrameType::PRIORITY));
+  EXPECT_EQ("RST_STREAM", Http2FrameTypeToString(Http2FrameType::RST_STREAM));
+  EXPECT_EQ("SETTINGS", Http2FrameTypeToString(Http2FrameType::SETTINGS));
+  EXPECT_EQ("PUSH_PROMISE",
+            Http2FrameTypeToString(Http2FrameType::PUSH_PROMISE));
+  EXPECT_EQ("PING", Http2FrameTypeToString(Http2FrameType::PING));
+  EXPECT_EQ("GOAWAY", Http2FrameTypeToString(Http2FrameType::GOAWAY));
+  EXPECT_EQ("WINDOW_UPDATE",
+            Http2FrameTypeToString(Http2FrameType::WINDOW_UPDATE));
+  EXPECT_EQ("CONTINUATION",
+            Http2FrameTypeToString(Http2FrameType::CONTINUATION));
+  EXPECT_EQ("ALTSVC", Http2FrameTypeToString(Http2FrameType::ALTSVC));
+
+  EXPECT_EQ("DATA", Http2FrameTypeToString(0));
+  EXPECT_EQ("HEADERS", Http2FrameTypeToString(1));
+  EXPECT_EQ("PRIORITY", Http2FrameTypeToString(2));
+  EXPECT_EQ("RST_STREAM", Http2FrameTypeToString(3));
+  EXPECT_EQ("SETTINGS", Http2FrameTypeToString(4));
+  EXPECT_EQ("PUSH_PROMISE", Http2FrameTypeToString(5));
+  EXPECT_EQ("PING", Http2FrameTypeToString(6));
+  EXPECT_EQ("GOAWAY", Http2FrameTypeToString(7));
+  EXPECT_EQ("WINDOW_UPDATE", Http2FrameTypeToString(8));
+  EXPECT_EQ("CONTINUATION", Http2FrameTypeToString(9));
+  EXPECT_EQ("ALTSVC", Http2FrameTypeToString(10));
+
+  EXPECT_EQ("UnknownFrameType(99)", Http2FrameTypeToString(99));
+}
+
+TEST(Http2ConstantsTest, Http2FrameFlag) {
+  EXPECT_EQ(Http2FrameFlag::END_STREAM, static_cast<Http2FrameFlag>(0x01));
+  EXPECT_EQ(Http2FrameFlag::ACK, static_cast<Http2FrameFlag>(0x01));
+  EXPECT_EQ(Http2FrameFlag::END_HEADERS, static_cast<Http2FrameFlag>(0x04));
+  EXPECT_EQ(Http2FrameFlag::PADDED, static_cast<Http2FrameFlag>(0x08));
+  EXPECT_EQ(Http2FrameFlag::PRIORITY, static_cast<Http2FrameFlag>(0x20));
+
+  EXPECT_EQ(Http2FrameFlag::END_STREAM, 0x01);
+  EXPECT_EQ(Http2FrameFlag::ACK, 0x01);
+  EXPECT_EQ(Http2FrameFlag::END_HEADERS, 0x04);
+  EXPECT_EQ(Http2FrameFlag::PADDED, 0x08);
+  EXPECT_EQ(Http2FrameFlag::PRIORITY, 0x20);
+}
+
+TEST(Http2ConstantsTest, Http2FrameFlagsToString) {
+  // Single flags...
+
+  // 0b00000001
+  EXPECT_EQ("END_STREAM", Http2FrameFlagsToString(Http2FrameType::DATA,
+                                                  Http2FrameFlag::END_STREAM));
+  EXPECT_EQ("END_STREAM",
+            Http2FrameFlagsToString(Http2FrameType::HEADERS, 0x01));
+  EXPECT_EQ("ACK", Http2FrameFlagsToString(Http2FrameType::SETTINGS,
+                                           Http2FrameFlag::ACK));
+  EXPECT_EQ("ACK", Http2FrameFlagsToString(Http2FrameType::PING, 0x01));
+
+  // 0b00000010
+  EXPECT_EQ("0x02", Http2FrameFlagsToString(0xff, 0x02));
+
+  // 0b00000100
+  EXPECT_EQ("END_HEADERS",
+            Http2FrameFlagsToString(Http2FrameType::HEADERS,
+                                    Http2FrameFlag::END_HEADERS));
+  EXPECT_EQ("END_HEADERS",
+            Http2FrameFlagsToString(Http2FrameType::PUSH_PROMISE, 0x04));
+  EXPECT_EQ("END_HEADERS", Http2FrameFlagsToString(0x09, 0x04));
+  EXPECT_EQ("0x04", Http2FrameFlagsToString(0xff, 0x04));
+
+  // 0b00001000
+  EXPECT_EQ("PADDED", Http2FrameFlagsToString(Http2FrameType::DATA,
+                                              Http2FrameFlag::PADDED));
+  EXPECT_EQ("PADDED", Http2FrameFlagsToString(Http2FrameType::HEADERS, 0x08));
+  EXPECT_EQ("PADDED", Http2FrameFlagsToString(0x05, 0x08));
+  EXPECT_EQ("0x08", Http2FrameFlagsToString(0xff, Http2FrameFlag::PADDED));
+
+  // 0b00010000
+  EXPECT_EQ("0x10", Http2FrameFlagsToString(Http2FrameType::SETTINGS, 0x10));
+
+  // 0b00100000
+  EXPECT_EQ("PRIORITY", Http2FrameFlagsToString(Http2FrameType::HEADERS, 0x20));
+  EXPECT_EQ("0x20",
+            Http2FrameFlagsToString(Http2FrameType::PUSH_PROMISE, 0x20));
+
+  // 0b01000000
+  EXPECT_EQ("0x40", Http2FrameFlagsToString(0xff, 0x40));
+
+  // 0b10000000
+  EXPECT_EQ("0x80", Http2FrameFlagsToString(0xff, 0x80));
+
+  // Combined flags...
+
+  EXPECT_EQ("END_STREAM|PADDED|0xf6",
+            Http2FrameFlagsToString(Http2FrameType::DATA, 0xff));
+  EXPECT_EQ("END_STREAM|END_HEADERS|PADDED|PRIORITY|0xd2",
+            Http2FrameFlagsToString(Http2FrameType::HEADERS, 0xff));
+  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::PRIORITY, 0xff));
+  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::RST_STREAM, 0xff));
+  EXPECT_EQ("ACK|0xfe",
+            Http2FrameFlagsToString(Http2FrameType::SETTINGS, 0xff));
+  EXPECT_EQ("END_HEADERS|PADDED|0xf3",
+            Http2FrameFlagsToString(Http2FrameType::PUSH_PROMISE, 0xff));
+  EXPECT_EQ("ACK|0xfe", Http2FrameFlagsToString(Http2FrameType::PING, 0xff));
+  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::GOAWAY, 0xff));
+  EXPECT_EQ("0xff",
+            Http2FrameFlagsToString(Http2FrameType::WINDOW_UPDATE, 0xff));
+  EXPECT_EQ("END_HEADERS|0xfb",
+            Http2FrameFlagsToString(Http2FrameType::CONTINUATION, 0xff));
+  EXPECT_EQ("0xff", Http2FrameFlagsToString(Http2FrameType::ALTSVC, 0xff));
+  EXPECT_EQ("0xff", Http2FrameFlagsToString(0xff, 0xff));
+}
+
+TEST(Http2ConstantsTest, Http2ErrorCode) {
+  EXPECT_EQ(Http2ErrorCode::HTTP2_NO_ERROR, static_cast<Http2ErrorCode>(0x0));
+  EXPECT_EQ(Http2ErrorCode::PROTOCOL_ERROR, static_cast<Http2ErrorCode>(0x1));
+  EXPECT_EQ(Http2ErrorCode::INTERNAL_ERROR, static_cast<Http2ErrorCode>(0x2));
+  EXPECT_EQ(Http2ErrorCode::FLOW_CONTROL_ERROR,
+            static_cast<Http2ErrorCode>(0x3));
+  EXPECT_EQ(Http2ErrorCode::SETTINGS_TIMEOUT, static_cast<Http2ErrorCode>(0x4));
+  EXPECT_EQ(Http2ErrorCode::STREAM_CLOSED, static_cast<Http2ErrorCode>(0x5));
+  EXPECT_EQ(Http2ErrorCode::FRAME_SIZE_ERROR, static_cast<Http2ErrorCode>(0x6));
+  EXPECT_EQ(Http2ErrorCode::REFUSED_STREAM, static_cast<Http2ErrorCode>(0x7));
+  EXPECT_EQ(Http2ErrorCode::CANCEL, static_cast<Http2ErrorCode>(0x8));
+  EXPECT_EQ(Http2ErrorCode::COMPRESSION_ERROR,
+            static_cast<Http2ErrorCode>(0x9));
+  EXPECT_EQ(Http2ErrorCode::CONNECT_ERROR, static_cast<Http2ErrorCode>(0xa));
+  EXPECT_EQ(Http2ErrorCode::ENHANCE_YOUR_CALM,
+            static_cast<Http2ErrorCode>(0xb));
+  EXPECT_EQ(Http2ErrorCode::INADEQUATE_SECURITY,
+            static_cast<Http2ErrorCode>(0xc));
+  EXPECT_EQ(Http2ErrorCode::HTTP_1_1_REQUIRED,
+            static_cast<Http2ErrorCode>(0xd));
+}
+
+TEST(Http2ConstantsTest, Http2ErrorCodeToString) {
+  EXPECT_EQ("NO_ERROR", Http2ErrorCodeToString(Http2ErrorCode::HTTP2_NO_ERROR));
+  EXPECT_EQ("NO_ERROR", Http2ErrorCodeToString(0x0));
+  EXPECT_EQ("PROTOCOL_ERROR",
+            Http2ErrorCodeToString(Http2ErrorCode::PROTOCOL_ERROR));
+  EXPECT_EQ("PROTOCOL_ERROR", Http2ErrorCodeToString(0x1));
+  EXPECT_EQ("INTERNAL_ERROR",
+            Http2ErrorCodeToString(Http2ErrorCode::INTERNAL_ERROR));
+  EXPECT_EQ("INTERNAL_ERROR", Http2ErrorCodeToString(0x2));
+  EXPECT_EQ("FLOW_CONTROL_ERROR",
+            Http2ErrorCodeToString(Http2ErrorCode::FLOW_CONTROL_ERROR));
+  EXPECT_EQ("FLOW_CONTROL_ERROR", Http2ErrorCodeToString(0x3));
+  EXPECT_EQ("SETTINGS_TIMEOUT",
+            Http2ErrorCodeToString(Http2ErrorCode::SETTINGS_TIMEOUT));
+  EXPECT_EQ("SETTINGS_TIMEOUT", Http2ErrorCodeToString(0x4));
+  EXPECT_EQ("STREAM_CLOSED",
+            Http2ErrorCodeToString(Http2ErrorCode::STREAM_CLOSED));
+  EXPECT_EQ("STREAM_CLOSED", Http2ErrorCodeToString(0x5));
+  EXPECT_EQ("FRAME_SIZE_ERROR",
+            Http2ErrorCodeToString(Http2ErrorCode::FRAME_SIZE_ERROR));
+  EXPECT_EQ("FRAME_SIZE_ERROR", Http2ErrorCodeToString(0x6));
+  EXPECT_EQ("REFUSED_STREAM",
+            Http2ErrorCodeToString(Http2ErrorCode::REFUSED_STREAM));
+  EXPECT_EQ("REFUSED_STREAM", Http2ErrorCodeToString(0x7));
+  EXPECT_EQ("CANCEL", Http2ErrorCodeToString(Http2ErrorCode::CANCEL));
+  EXPECT_EQ("CANCEL", Http2ErrorCodeToString(0x8));
+  EXPECT_EQ("COMPRESSION_ERROR",
+            Http2ErrorCodeToString(Http2ErrorCode::COMPRESSION_ERROR));
+  EXPECT_EQ("COMPRESSION_ERROR", Http2ErrorCodeToString(0x9));
+  EXPECT_EQ("CONNECT_ERROR",
+            Http2ErrorCodeToString(Http2ErrorCode::CONNECT_ERROR));
+  EXPECT_EQ("CONNECT_ERROR", Http2ErrorCodeToString(0xa));
+  EXPECT_EQ("ENHANCE_YOUR_CALM",
+            Http2ErrorCodeToString(Http2ErrorCode::ENHANCE_YOUR_CALM));
+  EXPECT_EQ("ENHANCE_YOUR_CALM", Http2ErrorCodeToString(0xb));
+  EXPECT_EQ("INADEQUATE_SECURITY",
+            Http2ErrorCodeToString(Http2ErrorCode::INADEQUATE_SECURITY));
+  EXPECT_EQ("INADEQUATE_SECURITY", Http2ErrorCodeToString(0xc));
+  EXPECT_EQ("HTTP_1_1_REQUIRED",
+            Http2ErrorCodeToString(Http2ErrorCode::HTTP_1_1_REQUIRED));
+  EXPECT_EQ("HTTP_1_1_REQUIRED", Http2ErrorCodeToString(0xd));
+
+  EXPECT_EQ("UnknownErrorCode(0x123)", Http2ErrorCodeToString(0x123));
+}
+
+TEST(Http2ConstantsTest, Http2SettingsParameter) {
+  EXPECT_EQ(Http2SettingsParameter::HEADER_TABLE_SIZE,
+            static_cast<Http2SettingsParameter>(0x1));
+  EXPECT_EQ(Http2SettingsParameter::ENABLE_PUSH,
+            static_cast<Http2SettingsParameter>(0x2));
+  EXPECT_EQ(Http2SettingsParameter::MAX_CONCURRENT_STREAMS,
+            static_cast<Http2SettingsParameter>(0x3));
+  EXPECT_EQ(Http2SettingsParameter::INITIAL_WINDOW_SIZE,
+            static_cast<Http2SettingsParameter>(0x4));
+  EXPECT_EQ(Http2SettingsParameter::MAX_FRAME_SIZE,
+            static_cast<Http2SettingsParameter>(0x5));
+  EXPECT_EQ(Http2SettingsParameter::MAX_HEADER_LIST_SIZE,
+            static_cast<Http2SettingsParameter>(0x6));
+
+  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
+      Http2SettingsParameter::HEADER_TABLE_SIZE));
+  EXPECT_TRUE(
+      IsSupportedHttp2SettingsParameter(Http2SettingsParameter::ENABLE_PUSH));
+  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
+      Http2SettingsParameter::MAX_CONCURRENT_STREAMS));
+  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
+      Http2SettingsParameter::INITIAL_WINDOW_SIZE));
+  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
+      Http2SettingsParameter::MAX_FRAME_SIZE));
+  EXPECT_TRUE(IsSupportedHttp2SettingsParameter(
+      Http2SettingsParameter::MAX_HEADER_LIST_SIZE));
+
+  EXPECT_FALSE(IsSupportedHttp2SettingsParameter(
+      static_cast<Http2SettingsParameter>(0)));
+  EXPECT_FALSE(IsSupportedHttp2SettingsParameter(
+      static_cast<Http2SettingsParameter>(7)));
+}
+
+TEST(Http2ConstantsTest, Http2SettingsParameterToString) {
+  EXPECT_EQ("HEADER_TABLE_SIZE",
+            Http2SettingsParameterToString(
+                Http2SettingsParameter::HEADER_TABLE_SIZE));
+  EXPECT_EQ("HEADER_TABLE_SIZE", Http2SettingsParameterToString(0x1));
+  EXPECT_EQ("ENABLE_PUSH", Http2SettingsParameterToString(
+                               Http2SettingsParameter::ENABLE_PUSH));
+  EXPECT_EQ("ENABLE_PUSH", Http2SettingsParameterToString(0x2));
+  EXPECT_EQ("MAX_CONCURRENT_STREAMS",
+            Http2SettingsParameterToString(
+                Http2SettingsParameter::MAX_CONCURRENT_STREAMS));
+  EXPECT_EQ("MAX_CONCURRENT_STREAMS", Http2SettingsParameterToString(0x3));
+  EXPECT_EQ("INITIAL_WINDOW_SIZE",
+            Http2SettingsParameterToString(
+                Http2SettingsParameter::INITIAL_WINDOW_SIZE));
+  EXPECT_EQ("INITIAL_WINDOW_SIZE", Http2SettingsParameterToString(0x4));
+  EXPECT_EQ("MAX_FRAME_SIZE", Http2SettingsParameterToString(
+                                  Http2SettingsParameter::MAX_FRAME_SIZE));
+  EXPECT_EQ("MAX_FRAME_SIZE", Http2SettingsParameterToString(0x5));
+  EXPECT_EQ("MAX_HEADER_LIST_SIZE",
+            Http2SettingsParameterToString(
+                Http2SettingsParameter::MAX_HEADER_LIST_SIZE));
+  EXPECT_EQ("MAX_HEADER_LIST_SIZE", Http2SettingsParameterToString(0x6));
+
+  EXPECT_EQ("UnknownSettingsParameter(0x123)",
+            Http2SettingsParameterToString(0x123));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/http2_constants_test_util.cc b/quiche/http2/http2_constants_test_util.cc
new file mode 100644
index 0000000..7532595
--- /dev/null
+++ b/quiche/http2/http2_constants_test_util.cc
@@ -0,0 +1,84 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/http2_constants_test_util.h"
+
+namespace http2 {
+namespace test {
+
+std::vector<Http2ErrorCode> AllHttp2ErrorCodes() {
+  // clang-format off
+  return {
+      Http2ErrorCode::HTTP2_NO_ERROR,
+      Http2ErrorCode::PROTOCOL_ERROR,
+      Http2ErrorCode::INTERNAL_ERROR,
+      Http2ErrorCode::FLOW_CONTROL_ERROR,
+      Http2ErrorCode::SETTINGS_TIMEOUT,
+      Http2ErrorCode::STREAM_CLOSED,
+      Http2ErrorCode::FRAME_SIZE_ERROR,
+      Http2ErrorCode::REFUSED_STREAM,
+      Http2ErrorCode::CANCEL,
+      Http2ErrorCode::COMPRESSION_ERROR,
+      Http2ErrorCode::CONNECT_ERROR,
+      Http2ErrorCode::ENHANCE_YOUR_CALM,
+      Http2ErrorCode::INADEQUATE_SECURITY,
+      Http2ErrorCode::HTTP_1_1_REQUIRED,
+  };
+  // clang-format on
+}
+
+std::vector<Http2SettingsParameter> AllHttp2SettingsParameters() {
+  // clang-format off
+  return {
+      Http2SettingsParameter::HEADER_TABLE_SIZE,
+      Http2SettingsParameter::ENABLE_PUSH,
+      Http2SettingsParameter::MAX_CONCURRENT_STREAMS,
+      Http2SettingsParameter::INITIAL_WINDOW_SIZE,
+      Http2SettingsParameter::MAX_FRAME_SIZE,
+      Http2SettingsParameter::MAX_HEADER_LIST_SIZE,
+  };
+  // clang-format on
+}
+
+// Returns a mask of flags supported for the specified frame type. Returns
+// zero for unknown frame types.
+uint8_t KnownFlagsMaskForFrameType(Http2FrameType type) {
+  switch (type) {
+    case Http2FrameType::DATA:
+      return Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED;
+    case Http2FrameType::HEADERS:
+      return Http2FrameFlag::END_STREAM | Http2FrameFlag::END_HEADERS |
+             Http2FrameFlag::PADDED | Http2FrameFlag::PRIORITY;
+    case Http2FrameType::PRIORITY:
+      return 0x00;
+    case Http2FrameType::RST_STREAM:
+      return 0x00;
+    case Http2FrameType::SETTINGS:
+      return Http2FrameFlag::ACK;
+    case Http2FrameType::PUSH_PROMISE:
+      return Http2FrameFlag::END_HEADERS | Http2FrameFlag::PADDED;
+    case Http2FrameType::PING:
+      return Http2FrameFlag::ACK;
+    case Http2FrameType::GOAWAY:
+      return 0x00;
+    case Http2FrameType::WINDOW_UPDATE:
+      return 0x00;
+    case Http2FrameType::CONTINUATION:
+      return Http2FrameFlag::END_HEADERS;
+    case Http2FrameType::ALTSVC:
+      return 0x00;
+    default:
+      return 0x00;
+  }
+}
+
+uint8_t InvalidFlagMaskForFrameType(Http2FrameType type) {
+  if (IsSupportedHttp2FrameType(type)) {
+    return ~KnownFlagsMaskForFrameType(type);
+  }
+  return 0x00;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/http2_constants_test_util.h b/quiche/http2/http2_constants_test_util.h
new file mode 100644
index 0000000..ab5b2d0
--- /dev/null
+++ b/quiche/http2/http2_constants_test_util.h
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HTTP2_CONSTANTS_TEST_UTIL_H_
+#define QUICHE_HTTP2_HTTP2_CONSTANTS_TEST_UTIL_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "quiche/http2/http2_constants.h"
+
+namespace http2 {
+namespace test {
+
+// Returns a vector of all supported RST_STREAM and GOAWAY error codes.
+std::vector<Http2ErrorCode> AllHttp2ErrorCodes();
+
+// Returns a vector of all supported parameters in SETTINGS frames.
+std::vector<Http2SettingsParameter> AllHttp2SettingsParameters();
+
+// Returns a mask of flags supported for the specified frame type. Returns
+// zero for unknown frame types.
+uint8_t KnownFlagsMaskForFrameType(Http2FrameType type);
+
+// Returns a mask of flag bits known to be invalid for the frame type.
+// For unknown frame types, the mask is zero; i.e., we don't know that any
+// are invalid.
+uint8_t InvalidFlagMaskForFrameType(Http2FrameType type);
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HTTP2_CONSTANTS_TEST_UTIL_H_
diff --git a/quiche/http2/http2_structures.cc b/quiche/http2/http2_structures.cc
new file mode 100644
index 0000000..c77cfeb
--- /dev/null
+++ b/quiche/http2/http2_structures.cc
@@ -0,0 +1,153 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/http2_structures.h"
+
+#include <cstring>  // For std::memcmp
+#include <sstream>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+
+namespace http2 {
+
+// Http2FrameHeader:
+
+bool Http2FrameHeader::IsProbableHttpResponse() const {
+  return (payload_length == 0x485454 &&      // "HTT"
+          static_cast<char>(type) == 'P' &&  // "P"
+          flags == '/');                     // "/"
+}
+
+std::string Http2FrameHeader::ToString() const {
+  return absl::StrCat("length=", payload_length,
+                      ", type=", Http2FrameTypeToString(type),
+                      ", flags=", FlagsToString(), ", stream=", stream_id);
+}
+
+std::string Http2FrameHeader::FlagsToString() const {
+  return Http2FrameFlagsToString(type, flags);
+}
+
+bool operator==(const Http2FrameHeader& a, const Http2FrameHeader& b) {
+  return a.payload_length == b.payload_length && a.stream_id == b.stream_id &&
+         a.type == b.type && a.flags == b.flags;
+}
+
+std::ostream& operator<<(std::ostream& out, const Http2FrameHeader& v) {
+  return out << v.ToString();
+}
+
+// Http2PriorityFields:
+
+bool operator==(const Http2PriorityFields& a, const Http2PriorityFields& b) {
+  return a.stream_dependency == b.stream_dependency && a.weight == b.weight;
+}
+
+std::string Http2PriorityFields::ToString() const {
+  std::stringstream ss;
+  ss << "E=" << (is_exclusive ? "true" : "false")
+     << ", stream=" << stream_dependency
+     << ", weight=" << static_cast<uint32_t>(weight);
+  return ss.str();
+}
+
+std::ostream& operator<<(std::ostream& out, const Http2PriorityFields& v) {
+  return out << v.ToString();
+}
+
+// Http2RstStreamFields:
+
+bool operator==(const Http2RstStreamFields& a, const Http2RstStreamFields& b) {
+  return a.error_code == b.error_code;
+}
+
+std::ostream& operator<<(std::ostream& out, const Http2RstStreamFields& v) {
+  return out << "error_code=" << v.error_code;
+}
+
+// Http2SettingFields:
+
+bool operator==(const Http2SettingFields& a, const Http2SettingFields& b) {
+  return a.parameter == b.parameter && a.value == b.value;
+}
+std::ostream& operator<<(std::ostream& out, const Http2SettingFields& v) {
+  return out << "parameter=" << v.parameter << ", value=" << v.value;
+}
+
+// Http2PushPromiseFields:
+
+bool operator==(const Http2PushPromiseFields& a,
+                const Http2PushPromiseFields& b) {
+  return a.promised_stream_id == b.promised_stream_id;
+}
+
+std::ostream& operator<<(std::ostream& out, const Http2PushPromiseFields& v) {
+  return out << "promised_stream_id=" << v.promised_stream_id;
+}
+
+// Http2PingFields:
+
+bool operator==(const Http2PingFields& a, const Http2PingFields& b) {
+  static_assert((sizeof a.opaque_bytes) == Http2PingFields::EncodedSize(),
+                "Why not the same size?");
+  return 0 ==
+         std::memcmp(a.opaque_bytes, b.opaque_bytes, sizeof a.opaque_bytes);
+}
+
+std::ostream& operator<<(std::ostream& out, const Http2PingFields& v) {
+  return out << "opaque_bytes=0x"
+             << absl::BytesToHexString(absl::string_view(
+                    reinterpret_cast<const char*>(v.opaque_bytes),
+                    sizeof v.opaque_bytes));
+}
+
+// Http2GoAwayFields:
+
+bool operator==(const Http2GoAwayFields& a, const Http2GoAwayFields& b) {
+  return a.last_stream_id == b.last_stream_id && a.error_code == b.error_code;
+}
+std::ostream& operator<<(std::ostream& out, const Http2GoAwayFields& v) {
+  return out << "last_stream_id=" << v.last_stream_id
+             << ", error_code=" << v.error_code;
+}
+
+// Http2WindowUpdateFields:
+
+bool operator==(const Http2WindowUpdateFields& a,
+                const Http2WindowUpdateFields& b) {
+  return a.window_size_increment == b.window_size_increment;
+}
+std::ostream& operator<<(std::ostream& out, const Http2WindowUpdateFields& v) {
+  return out << "window_size_increment=" << v.window_size_increment;
+}
+
+// Http2AltSvcFields:
+
+bool operator==(const Http2AltSvcFields& a, const Http2AltSvcFields& b) {
+  return a.origin_length == b.origin_length;
+}
+std::ostream& operator<<(std::ostream& out, const Http2AltSvcFields& v) {
+  return out << "origin_length=" << v.origin_length;
+}
+
+// Http2PriorityUpdateFields:
+
+bool operator==(const Http2PriorityUpdateFields& a,
+                const Http2PriorityUpdateFields& b) {
+  return a.prioritized_stream_id == b.prioritized_stream_id;
+}
+
+std::string Http2PriorityUpdateFields::ToString() const {
+  std::stringstream ss;
+  ss << "prioritized_stream_id=" << prioritized_stream_id;
+  return ss.str();
+}
+
+std::ostream& operator<<(std::ostream& out,
+                         const Http2PriorityUpdateFields& v) {
+  return out << v.ToString();
+}
+
+}  // namespace http2
diff --git a/quiche/http2/http2_structures.h b/quiche/http2/http2_structures.h
new file mode 100644
index 0000000..1daba75
--- /dev/null
+++ b/quiche/http2/http2_structures.h
@@ -0,0 +1,351 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HTTP2_STRUCTURES_H_
+#define QUICHE_HTTP2_HTTP2_STRUCTURES_H_
+
+// Defines structs for various fixed sized structures in HTTP/2.
+//
+// Those structs with multiple fields have constructors that take arguments in
+// the same order as their encoding (which may be different from their order
+// in the struct). For single field structs, use aggregate initialization if
+// desired, e.g.:
+//
+//   Http2RstStreamFields var{Http2ErrorCode::ENHANCE_YOUR_CALM};
+// or:
+//   SomeFunc(Http2RstStreamFields{Http2ErrorCode::ENHANCE_YOUR_CALM});
+//
+// Each struct includes a static method EncodedSize which returns the number
+// of bytes of the encoding.
+//
+// With the exception of Http2FrameHeader, all the types are named
+// Http2<X>Fields, where X is the title-case form of the frame which always
+// includes the fields; the "always" is to cover the case of the PRIORITY frame;
+// its fields optionally appear in the HEADERS frame, but the struct is called
+// Http2PriorityFields.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <ostream>
+#include <string>
+
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace http2 {
+
+struct QUICHE_EXPORT_PRIVATE Http2FrameHeader {
+  Http2FrameHeader() {}
+  Http2FrameHeader(uint32_t payload_length, Http2FrameType type, uint8_t flags,
+                   uint32_t stream_id)
+      : payload_length(payload_length),
+        stream_id(stream_id),
+        type(type),
+        flags(flags) {
+    QUICHE_DCHECK_LT(payload_length, static_cast<uint32_t>(1 << 24))
+        << "Payload Length is only a 24 bit field\n"
+        << ToString();
+  }
+
+  static constexpr size_t EncodedSize() { return 9; }
+
+  // Keep the current value of those flags that are in
+  // valid_flags, and clear all the others.
+  void RetainFlags(uint8_t valid_flags) { flags = (flags & valid_flags); }
+
+  // Returns true if any of the flags in flag_mask are set,
+  // otherwise false.
+  bool HasAnyFlags(uint8_t flag_mask) const { return 0 != (flags & flag_mask); }
+
+  // Is the END_STREAM flag set?
+  bool IsEndStream() const {
+    QUICHE_DCHECK(type == Http2FrameType::DATA ||
+                  type == Http2FrameType::HEADERS)
+        << ToString();
+    return (flags & Http2FrameFlag::END_STREAM) != 0;
+  }
+
+  // Is the ACK flag set?
+  bool IsAck() const {
+    QUICHE_DCHECK(type == Http2FrameType::SETTINGS ||
+                  type == Http2FrameType::PING)
+        << ToString();
+    return (flags & Http2FrameFlag::ACK) != 0;
+  }
+
+  // Is the END_HEADERS flag set?
+  bool IsEndHeaders() const {
+    QUICHE_DCHECK(type == Http2FrameType::HEADERS ||
+                  type == Http2FrameType::PUSH_PROMISE ||
+                  type == Http2FrameType::CONTINUATION)
+        << ToString();
+    return (flags & Http2FrameFlag::END_HEADERS) != 0;
+  }
+
+  // Is the PADDED flag set?
+  bool IsPadded() const {
+    QUICHE_DCHECK(type == Http2FrameType::DATA ||
+                  type == Http2FrameType::HEADERS ||
+                  type == Http2FrameType::PUSH_PROMISE)
+        << ToString();
+    return (flags & Http2FrameFlag::PADDED) != 0;
+  }
+
+  // Is the PRIORITY flag set?
+  bool HasPriority() const {
+    QUICHE_DCHECK_EQ(type, Http2FrameType::HEADERS) << ToString();
+    return (flags & Http2FrameFlag::PRIORITY) != 0;
+  }
+
+  // Does the encoding of this header start with "HTTP/", indicating that it
+  // might be from a non-HTTP/2 server.
+  bool IsProbableHttpResponse() const;
+
+  // Produce strings useful for debugging/logging messages.
+  std::string ToString() const;
+  std::string FlagsToString() const;
+
+  // 24 bit length of the payload after the header, including any padding.
+  // First field in encoding.
+  uint32_t payload_length;  // 24 bits
+
+  // 31 bit stream id, with high bit (32nd bit) reserved (must be zero),
+  // and is cleared during decoding.
+  // Fourth field in encoding.
+  uint32_t stream_id;
+
+  // Type of the frame.
+  // Second field in encoding.
+  Http2FrameType type;
+
+  // Flag bits, with interpretations that depend upon the frame type.
+  // Flag bits not used by the frame type are cleared.
+  // Third field in encoding.
+  uint8_t flags;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2FrameHeader& a,
+                                      const Http2FrameHeader& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2FrameHeader& a,
+                                             const Http2FrameHeader& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2FrameHeader& v);
+
+// Http2PriorityFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2PriorityFields {
+  Http2PriorityFields() {}
+  Http2PriorityFields(uint32_t stream_dependency,
+                      uint32_t weight,
+                      bool is_exclusive)
+      : stream_dependency(stream_dependency),
+        weight(weight),
+        is_exclusive(is_exclusive) {
+    // Can't have the high-bit set in the stream id because we need to use
+    // that for the EXCLUSIVE flag bit.
+    QUICHE_DCHECK_EQ(stream_dependency, stream_dependency & StreamIdMask())
+        << "Stream Dependency is only a 31-bit field.\n"
+        << ToString();
+    QUICHE_DCHECK_LE(1u, weight) << "Weight is too small.";
+    QUICHE_DCHECK_LE(weight, 256u) << "Weight is too large.";
+  }
+  static constexpr size_t EncodedSize() { return 5; }
+
+  // Produce strings useful for debugging/logging messages.
+  std::string ToString() const;
+
+  // A 31-bit stream identifier for the stream that this stream depends on.
+  uint32_t stream_dependency;
+
+  // Weight (1 to 256) is encoded as a byte in the range 0 to 255, so we
+  // add one when decoding, and store it in a field larger than a byte.
+  uint32_t weight;
+
+  // A single-bit flag indicating that the stream dependency is exclusive;
+  // extracted from high bit of stream dependency field during decoding.
+  bool is_exclusive;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2PriorityFields& a,
+                                      const Http2PriorityFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2PriorityFields& a,
+                                             const Http2PriorityFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2PriorityFields& v);
+
+// Http2RstStreamFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2RstStreamFields {
+  static constexpr size_t EncodedSize() { return 4; }
+  bool IsSupportedErrorCode() const {
+    return IsSupportedHttp2ErrorCode(error_code);
+  }
+
+  Http2ErrorCode error_code;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2RstStreamFields& a,
+                                      const Http2RstStreamFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2RstStreamFields& a,
+                                             const Http2RstStreamFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2RstStreamFields& v);
+
+// Http2SettingFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2SettingFields {
+  Http2SettingFields() {}
+  Http2SettingFields(Http2SettingsParameter parameter, uint32_t value)
+      : parameter(parameter), value(value) {}
+  static constexpr size_t EncodedSize() { return 6; }
+  bool IsSupportedParameter() const {
+    return IsSupportedHttp2SettingsParameter(parameter);
+  }
+
+  Http2SettingsParameter parameter;
+  uint32_t value;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2SettingFields& a,
+                                      const Http2SettingFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2SettingFields& a,
+                                             const Http2SettingFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2SettingFields& v);
+
+// Http2PushPromiseFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2PushPromiseFields {
+  static constexpr size_t EncodedSize() { return 4; }
+
+  uint32_t promised_stream_id;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2PushPromiseFields& a,
+                                      const Http2PushPromiseFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2PushPromiseFields& a,
+                                             const Http2PushPromiseFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2PushPromiseFields& v);
+
+// Http2PingFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2PingFields {
+  static constexpr size_t EncodedSize() { return 8; }
+
+  uint8_t opaque_bytes[8];
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2PingFields& a,
+                                      const Http2PingFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2PingFields& a,
+                                             const Http2PingFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2PingFields& v);
+
+// Http2GoAwayFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2GoAwayFields {
+  Http2GoAwayFields() {}
+  Http2GoAwayFields(uint32_t last_stream_id, Http2ErrorCode error_code)
+      : last_stream_id(last_stream_id), error_code(error_code) {}
+  static constexpr size_t EncodedSize() { return 8; }
+  bool IsSupportedErrorCode() const {
+    return IsSupportedHttp2ErrorCode(error_code);
+  }
+
+  uint32_t last_stream_id;
+  Http2ErrorCode error_code;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2GoAwayFields& a,
+                                      const Http2GoAwayFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2GoAwayFields& a,
+                                             const Http2GoAwayFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2GoAwayFields& v);
+
+// Http2WindowUpdateFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2WindowUpdateFields {
+  static constexpr size_t EncodedSize() { return 4; }
+
+  // 31-bit, unsigned increase in the window size (only positive values are
+  // allowed). The high-bit is reserved for the future.
+  uint32_t window_size_increment;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2WindowUpdateFields& a,
+                                      const Http2WindowUpdateFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2WindowUpdateFields& a,
+                                             const Http2WindowUpdateFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& out,
+    const Http2WindowUpdateFields& v);
+
+// Http2AltSvcFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2AltSvcFields {
+  static constexpr size_t EncodedSize() { return 2; }
+
+  // This is the one fixed size portion of the ALTSVC payload.
+  uint16_t origin_length;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2AltSvcFields& a,
+                                      const Http2AltSvcFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(const Http2AltSvcFields& a,
+                                             const Http2AltSvcFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               const Http2AltSvcFields& v);
+
+// Http2PriorityUpdateFields:
+
+struct QUICHE_EXPORT_PRIVATE Http2PriorityUpdateFields {
+  Http2PriorityUpdateFields() {}
+  Http2PriorityUpdateFields(uint32_t prioritized_stream_id)
+      : prioritized_stream_id(prioritized_stream_id) {}
+  static constexpr size_t EncodedSize() { return 4; }
+
+  // Produce strings useful for debugging/logging messages.
+  std::string ToString() const;
+
+  // The 31-bit stream identifier of the stream whose priority is updated.
+  uint32_t prioritized_stream_id;
+};
+
+QUICHE_EXPORT_PRIVATE bool operator==(const Http2PriorityUpdateFields& a,
+                                      const Http2PriorityUpdateFields& b);
+QUICHE_EXPORT_PRIVATE inline bool operator!=(
+    const Http2PriorityUpdateFields& a,
+    const Http2PriorityUpdateFields& b) {
+  return !(a == b);
+}
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& out,
+    const Http2PriorityUpdateFields& v);
+
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HTTP2_STRUCTURES_H_
diff --git a/quiche/http2/http2_structures_test.cc b/quiche/http2/http2_structures_test.cc
new file mode 100644
index 0000000..2cb6a30
--- /dev/null
+++ b/quiche/http2/http2_structures_test.cc
@@ -0,0 +1,560 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/http2_structures.h"
+
+// Tests are focused on Http2FrameHeader because it has by far the most
+// methods of any of the structures.
+// Note that EXPECT.*DEATH tests are slow (a fork is probably involved).
+
+// And in case you're wondering, yes, these are ridiculously thorough tests,
+// but believe it or not, I've found silly bugs this way.
+
+#include <memory>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using ::testing::Combine;
+using ::testing::HasSubstr;
+using ::testing::MatchesRegex;
+using ::testing::Not;
+using ::testing::Values;
+using ::testing::ValuesIn;
+
+namespace http2 {
+namespace test {
+namespace {
+
+template <typename E>
+E IncrementEnum(E e) {
+  using I = typename std::underlying_type<E>::type;
+  return static_cast<E>(1 + static_cast<I>(e));
+}
+
+template <class T>
+AssertionResult VerifyRandomCalls() {
+  T t1;
+  // Initialize with a stable key, to avoid test flakiness.
+  Http2Random seq1(
+      "6d9a61ddf2bc1fc0b8245505a1f28e324559d8b5c9c3268f38b42b1af3287c47");
+  Randomize(&t1, &seq1);
+
+  T t2;
+  Http2Random seq2(seq1.Key());
+  Randomize(&t2, &seq2);
+
+  // The two Randomize calls should have made the same number of calls into
+  // the Http2Random implementations.
+  VERIFY_EQ(seq1.Rand64(), seq2.Rand64());
+
+  // And because Http2Random implementation is returning the same sequence, and
+  // Randomize should have been consistent in applying those results, the two
+  // Ts should have the same value.
+  VERIFY_EQ(t1, t2);
+
+  Randomize(&t2, &seq2);
+  VERIFY_NE(t1, t2);
+
+  Randomize(&t1, &seq1);
+  VERIFY_EQ(t1, t2);
+
+  VERIFY_EQ(seq1.Rand64(), seq2.Rand64());
+
+  return AssertionSuccess();
+}
+
+#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+std::vector<Http2FrameType> ValidFrameTypes() {
+  std::vector<Http2FrameType> valid_types{Http2FrameType::DATA};
+  while (valid_types.back() != Http2FrameType::ALTSVC) {
+    valid_types.push_back(IncrementEnum(valid_types.back()));
+  }
+  return valid_types;
+}
+#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+
+TEST(Http2FrameHeaderTest, Constructor) {
+  Http2Random random;
+  uint8_t frame_type = 0;
+  do {
+    // Only the payload length is QUICHE_DCHECK'd in the constructor, so we need
+    // to make sure it is a "uint24".
+    uint32_t payload_length = random.Rand32() & 0xffffff;
+    Http2FrameType type = static_cast<Http2FrameType>(frame_type);
+    uint8_t flags = random.Rand8();
+    uint32_t stream_id = random.Rand32();
+
+    Http2FrameHeader v(payload_length, type, flags, stream_id);
+
+    EXPECT_EQ(payload_length, v.payload_length);
+    EXPECT_EQ(type, v.type);
+    EXPECT_EQ(flags, v.flags);
+    EXPECT_EQ(stream_id, v.stream_id);
+  } while (frame_type++ != 255);
+
+#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+  EXPECT_DEBUG_DEATH(Http2FrameHeader(0x01000000, Http2FrameType::DATA, 0, 1),
+                     "payload_length");
+#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+}
+
+TEST(Http2FrameHeaderTest, Eq) {
+  Http2Random random;
+  uint32_t payload_length = random.Rand32() & 0xffffff;
+  Http2FrameType type = static_cast<Http2FrameType>(random.Rand8());
+
+  uint8_t flags = random.Rand8();
+  uint32_t stream_id = random.Rand32();
+
+  Http2FrameHeader v(payload_length, type, flags, stream_id);
+
+  EXPECT_EQ(payload_length, v.payload_length);
+  EXPECT_EQ(type, v.type);
+  EXPECT_EQ(flags, v.flags);
+  EXPECT_EQ(stream_id, v.stream_id);
+
+  Http2FrameHeader u(0, type, ~flags, stream_id);
+
+  EXPECT_NE(u, v);
+  EXPECT_NE(v, u);
+  EXPECT_FALSE(u == v);
+  EXPECT_FALSE(v == u);
+  EXPECT_TRUE(u != v);
+  EXPECT_TRUE(v != u);
+
+  u = v;
+
+  EXPECT_EQ(u, v);
+  EXPECT_EQ(v, u);
+  EXPECT_TRUE(u == v);
+  EXPECT_TRUE(v == u);
+  EXPECT_FALSE(u != v);
+  EXPECT_FALSE(v != u);
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2FrameHeader>());
+}
+
+#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+// The tests of the valid frame types include EXPECT_DEBUG_DEATH, which is
+// quite slow, so using value parameterized tests in order to allow sharding.
+class Http2FrameHeaderTypeAndFlagTest
+    : public QuicheTestWithParam<std::tuple<Http2FrameType, Http2FrameFlag>> {
+ protected:
+  Http2FrameHeaderTypeAndFlagTest()
+      : type_(std::get<0>(GetParam())), flags_(std::get<1>(GetParam())) {
+    HTTP2_LOG(INFO) << "Frame type: " << type_;
+    HTTP2_LOG(INFO) << "Frame flags: "
+                    << Http2FrameFlagsToString(type_, flags_);
+  }
+
+  const Http2FrameType type_;
+  const Http2FrameFlag flags_;
+};
+
+class IsEndStreamTest : public Http2FrameHeaderTypeAndFlagTest {};
+INSTANTIATE_TEST_SUITE_P(IsEndStream,
+                         IsEndStreamTest,
+                         Combine(ValuesIn(ValidFrameTypes()),
+                                 Values(~Http2FrameFlag::END_STREAM, 0xff)));
+TEST_P(IsEndStreamTest, IsEndStream) {
+  const bool is_set =
+      (flags_ & Http2FrameFlag::END_STREAM) == Http2FrameFlag::END_STREAM;
+  std::string flags_string;
+  Http2FrameHeader v(0, type_, flags_, 0);
+  switch (type_) {
+    case Http2FrameType::DATA:
+    case Http2FrameType::HEADERS:
+      EXPECT_EQ(is_set, v.IsEndStream()) << v;
+      flags_string = v.FlagsToString();
+      if (is_set) {
+        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?END_STREAM\\|.*"));
+      } else {
+        EXPECT_THAT(flags_string, Not(HasSubstr("END_STREAM")));
+      }
+      v.RetainFlags(Http2FrameFlag::END_STREAM);
+      EXPECT_EQ(is_set, v.IsEndStream()) << v;
+      {
+        std::stringstream s;
+        s << v;
+        EXPECT_EQ(v.ToString(), s.str());
+        if (is_set) {
+          EXPECT_THAT(s.str(), HasSubstr("flags=END_STREAM,"));
+        } else {
+          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
+        }
+      }
+      break;
+    default:
+      EXPECT_DEBUG_DEATH(v.IsEndStream(), "DATA.*HEADERS") << v;
+  }
+}
+
+class IsACKTest : public Http2FrameHeaderTypeAndFlagTest {};
+INSTANTIATE_TEST_SUITE_P(IsAck,
+                         IsACKTest,
+                         Combine(ValuesIn(ValidFrameTypes()),
+                                 Values(~Http2FrameFlag::ACK, 0xff)));
+TEST_P(IsACKTest, IsAck) {
+  const bool is_set = (flags_ & Http2FrameFlag::ACK) == Http2FrameFlag::ACK;
+  std::string flags_string;
+  Http2FrameHeader v(0, type_, flags_, 0);
+  switch (type_) {
+    case Http2FrameType::SETTINGS:
+    case Http2FrameType::PING:
+      EXPECT_EQ(is_set, v.IsAck()) << v;
+      flags_string = v.FlagsToString();
+      if (is_set) {
+        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?ACK\\|.*"));
+      } else {
+        EXPECT_THAT(flags_string, Not(HasSubstr("ACK")));
+      }
+      v.RetainFlags(Http2FrameFlag::ACK);
+      EXPECT_EQ(is_set, v.IsAck()) << v;
+      {
+        std::stringstream s;
+        s << v;
+        EXPECT_EQ(v.ToString(), s.str());
+        if (is_set) {
+          EXPECT_THAT(s.str(), HasSubstr("flags=ACK,"));
+        } else {
+          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
+        }
+      }
+      break;
+    default:
+      EXPECT_DEBUG_DEATH(v.IsAck(), "SETTINGS.*PING") << v;
+  }
+}
+
+class IsEndHeadersTest : public Http2FrameHeaderTypeAndFlagTest {};
+INSTANTIATE_TEST_SUITE_P(IsEndHeaders,
+                         IsEndHeadersTest,
+                         Combine(ValuesIn(ValidFrameTypes()),
+                                 Values(~Http2FrameFlag::END_HEADERS, 0xff)));
+TEST_P(IsEndHeadersTest, IsEndHeaders) {
+  const bool is_set =
+      (flags_ & Http2FrameFlag::END_HEADERS) == Http2FrameFlag::END_HEADERS;
+  std::string flags_string;
+  Http2FrameHeader v(0, type_, flags_, 0);
+  switch (type_) {
+    case Http2FrameType::HEADERS:
+    case Http2FrameType::PUSH_PROMISE:
+    case Http2FrameType::CONTINUATION:
+      EXPECT_EQ(is_set, v.IsEndHeaders()) << v;
+      flags_string = v.FlagsToString();
+      if (is_set) {
+        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?END_HEADERS\\|.*"));
+      } else {
+        EXPECT_THAT(flags_string, Not(HasSubstr("END_HEADERS")));
+      }
+      v.RetainFlags(Http2FrameFlag::END_HEADERS);
+      EXPECT_EQ(is_set, v.IsEndHeaders()) << v;
+      {
+        std::stringstream s;
+        s << v;
+        EXPECT_EQ(v.ToString(), s.str());
+        if (is_set) {
+          EXPECT_THAT(s.str(), HasSubstr("flags=END_HEADERS,"));
+        } else {
+          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
+        }
+      }
+      break;
+    default:
+      EXPECT_DEBUG_DEATH(v.IsEndHeaders(),
+                         "HEADERS.*PUSH_PROMISE.*CONTINUATION")
+          << v;
+  }
+}
+
+class IsPaddedTest : public Http2FrameHeaderTypeAndFlagTest {};
+INSTANTIATE_TEST_SUITE_P(IsPadded,
+                         IsPaddedTest,
+                         Combine(ValuesIn(ValidFrameTypes()),
+                                 Values(~Http2FrameFlag::PADDED, 0xff)));
+TEST_P(IsPaddedTest, IsPadded) {
+  const bool is_set =
+      (flags_ & Http2FrameFlag::PADDED) == Http2FrameFlag::PADDED;
+  std::string flags_string;
+  Http2FrameHeader v(0, type_, flags_, 0);
+  switch (type_) {
+    case Http2FrameType::DATA:
+    case Http2FrameType::HEADERS:
+    case Http2FrameType::PUSH_PROMISE:
+      EXPECT_EQ(is_set, v.IsPadded()) << v;
+      flags_string = v.FlagsToString();
+      if (is_set) {
+        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?PADDED\\|.*"));
+      } else {
+        EXPECT_THAT(flags_string, Not(HasSubstr("PADDED")));
+      }
+      v.RetainFlags(Http2FrameFlag::PADDED);
+      EXPECT_EQ(is_set, v.IsPadded()) << v;
+      {
+        std::stringstream s;
+        s << v;
+        EXPECT_EQ(v.ToString(), s.str());
+        if (is_set) {
+          EXPECT_THAT(s.str(), HasSubstr("flags=PADDED,"));
+        } else {
+          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
+        }
+      }
+      break;
+    default:
+      EXPECT_DEBUG_DEATH(v.IsPadded(), "DATA.*HEADERS.*PUSH_PROMISE") << v;
+  }
+}
+
+class HasPriorityTest : public Http2FrameHeaderTypeAndFlagTest {};
+INSTANTIATE_TEST_SUITE_P(HasPriority,
+                         HasPriorityTest,
+                         Combine(ValuesIn(ValidFrameTypes()),
+                                 Values(~Http2FrameFlag::PRIORITY, 0xff)));
+TEST_P(HasPriorityTest, HasPriority) {
+  const bool is_set =
+      (flags_ & Http2FrameFlag::PRIORITY) == Http2FrameFlag::PRIORITY;
+  std::string flags_string;
+  Http2FrameHeader v(0, type_, flags_, 0);
+  switch (type_) {
+    case Http2FrameType::HEADERS:
+      EXPECT_EQ(is_set, v.HasPriority()) << v;
+      flags_string = v.FlagsToString();
+      if (is_set) {
+        EXPECT_THAT(flags_string, MatchesRegex(".*\\|?PRIORITY\\|.*"));
+      } else {
+        EXPECT_THAT(flags_string, Not(HasSubstr("PRIORITY")));
+      }
+      v.RetainFlags(Http2FrameFlag::PRIORITY);
+      EXPECT_EQ(is_set, v.HasPriority()) << v;
+      {
+        std::stringstream s;
+        s << v;
+        EXPECT_EQ(v.ToString(), s.str());
+        if (is_set) {
+          EXPECT_THAT(s.str(), HasSubstr("flags=PRIORITY,"));
+        } else {
+          EXPECT_THAT(s.str(), HasSubstr("flags=,"));
+        }
+      }
+      break;
+    default:
+      EXPECT_DEBUG_DEATH(v.HasPriority(), "HEADERS") << v;
+  }
+}
+
+TEST(Http2PriorityFieldsTest, Constructor) {
+  Http2Random random;
+  uint32_t stream_dependency = random.Rand32() & StreamIdMask();
+  uint32_t weight = 1 + random.Rand8();
+  bool is_exclusive = random.OneIn(2);
+
+  Http2PriorityFields v(stream_dependency, weight, is_exclusive);
+
+  EXPECT_EQ(stream_dependency, v.stream_dependency);
+  EXPECT_EQ(weight, v.weight);
+  EXPECT_EQ(is_exclusive, v.is_exclusive);
+
+  // The high-bit must not be set on the stream id.
+  EXPECT_DEBUG_DEATH(
+      Http2PriorityFields(stream_dependency | 0x80000000, weight, is_exclusive),
+      "31-bit");
+
+  // The weight must be in the range 1-256.
+  EXPECT_DEBUG_DEATH(Http2PriorityFields(stream_dependency, 0, is_exclusive),
+                     "too small");
+  EXPECT_DEBUG_DEATH(
+      Http2PriorityFields(stream_dependency, weight + 256, is_exclusive),
+      "too large");
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2PriorityFields>());
+}
+#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
+
+TEST(Http2RstStreamFieldsTest, IsSupported) {
+  Http2RstStreamFields v{Http2ErrorCode::HTTP2_NO_ERROR};
+  EXPECT_TRUE(v.IsSupportedErrorCode()) << v;
+
+  Http2RstStreamFields u{static_cast<Http2ErrorCode>(~0)};
+  EXPECT_FALSE(u.IsSupportedErrorCode()) << v;
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2RstStreamFields>());
+}
+
+TEST(Http2SettingFieldsTest, Misc) {
+  Http2Random random;
+  Http2SettingsParameter parameter =
+      static_cast<Http2SettingsParameter>(random.Rand16());
+  uint32_t value = random.Rand32();
+
+  Http2SettingFields v(parameter, value);
+
+  EXPECT_EQ(v, v);
+  EXPECT_EQ(parameter, v.parameter);
+  EXPECT_EQ(value, v.value);
+
+  if (static_cast<uint16_t>(parameter) < 7) {
+    EXPECT_TRUE(v.IsSupportedParameter()) << v;
+  } else {
+    EXPECT_FALSE(v.IsSupportedParameter()) << v;
+  }
+
+  Http2SettingFields u(parameter, ~value);
+  EXPECT_NE(v, u);
+  EXPECT_EQ(v.parameter, u.parameter);
+  EXPECT_NE(v.value, u.value);
+
+  Http2SettingFields w(IncrementEnum(parameter), value);
+  EXPECT_NE(v, w);
+  EXPECT_NE(v.parameter, w.parameter);
+  EXPECT_EQ(v.value, w.value);
+
+  Http2SettingFields x(Http2SettingsParameter::MAX_FRAME_SIZE, 123);
+  std::stringstream s;
+  s << x;
+  EXPECT_EQ("parameter=MAX_FRAME_SIZE, value=123", s.str());
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2SettingFields>());
+}
+
+TEST(Http2PushPromiseTest, Misc) {
+  Http2Random random;
+  uint32_t promised_stream_id = random.Rand32() & StreamIdMask();
+
+  Http2PushPromiseFields v{promised_stream_id};
+  EXPECT_EQ(promised_stream_id, v.promised_stream_id);
+  EXPECT_EQ(v, v);
+
+  std::stringstream s;
+  s << v;
+  EXPECT_EQ(absl::StrCat("promised_stream_id=", promised_stream_id), s.str());
+
+  // High-bit is reserved, but not used, so we can set it.
+  promised_stream_id |= 0x80000000;
+  Http2PushPromiseFields w{promised_stream_id};
+  EXPECT_EQ(w, w);
+  EXPECT_NE(v, w);
+
+  v.promised_stream_id = promised_stream_id;
+  EXPECT_EQ(v, w);
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2PushPromiseFields>());
+}
+
+TEST(Http2PingFieldsTest, Misc) {
+  Http2PingFields v{{'8', ' ', 'b', 'y', 't', 'e', 's', '\0'}};
+  std::stringstream s;
+  s << v;
+  EXPECT_EQ("opaque_bytes=0x3820627974657300", s.str());
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2PingFields>());
+}
+
+TEST(Http2GoAwayFieldsTest, Misc) {
+  Http2Random random;
+  uint32_t last_stream_id = random.Rand32() & StreamIdMask();
+  Http2ErrorCode error_code = static_cast<Http2ErrorCode>(random.Rand32());
+
+  Http2GoAwayFields v(last_stream_id, error_code);
+  EXPECT_EQ(v, v);
+  EXPECT_EQ(last_stream_id, v.last_stream_id);
+  EXPECT_EQ(error_code, v.error_code);
+
+  if (static_cast<uint32_t>(error_code) < 14) {
+    EXPECT_TRUE(v.IsSupportedErrorCode()) << v;
+  } else {
+    EXPECT_FALSE(v.IsSupportedErrorCode()) << v;
+  }
+
+  Http2GoAwayFields u(~last_stream_id, error_code);
+  EXPECT_NE(v, u);
+  EXPECT_NE(v.last_stream_id, u.last_stream_id);
+  EXPECT_EQ(v.error_code, u.error_code);
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2GoAwayFields>());
+}
+
+TEST(Http2WindowUpdateTest, Misc) {
+  Http2Random random;
+  uint32_t window_size_increment = random.Rand32() & UInt31Mask();
+
+  Http2WindowUpdateFields v{window_size_increment};
+  EXPECT_EQ(window_size_increment, v.window_size_increment);
+  EXPECT_EQ(v, v);
+
+  std::stringstream s;
+  s << v;
+  EXPECT_EQ(absl::StrCat("window_size_increment=", window_size_increment),
+            s.str());
+
+  // High-bit is reserved, but not used, so we can set it.
+  window_size_increment |= 0x80000000;
+  Http2WindowUpdateFields w{window_size_increment};
+  EXPECT_EQ(w, w);
+  EXPECT_NE(v, w);
+
+  v.window_size_increment = window_size_increment;
+  EXPECT_EQ(v, w);
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2WindowUpdateFields>());
+}
+
+TEST(Http2AltSvcTest, Misc) {
+  Http2Random random;
+  uint16_t origin_length = random.Rand16();
+
+  Http2AltSvcFields v{origin_length};
+  EXPECT_EQ(origin_length, v.origin_length);
+  EXPECT_EQ(v, v);
+
+  std::stringstream s;
+  s << v;
+  EXPECT_EQ(absl::StrCat("origin_length=", origin_length), s.str());
+
+  Http2AltSvcFields w{++origin_length};
+  EXPECT_EQ(w, w);
+  EXPECT_NE(v, w);
+
+  v.origin_length = w.origin_length;
+  EXPECT_EQ(v, w);
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2AltSvcFields>());
+}
+
+TEST(Http2PriorityUpdateFieldsTest, Eq) {
+  Http2PriorityUpdateFields u(/* prioritized_stream_id = */ 1);
+  Http2PriorityUpdateFields v(/* prioritized_stream_id = */ 3);
+
+  EXPECT_NE(u, v);
+  EXPECT_FALSE(u == v);
+  EXPECT_TRUE(u != v);
+
+  u = v;
+  EXPECT_EQ(u, v);
+  EXPECT_TRUE(u == v);
+  EXPECT_FALSE(u != v);
+}
+
+TEST(Http2PriorityUpdateFieldsTest, Misc) {
+  Http2PriorityUpdateFields u(/* prioritized_stream_id = */ 1);
+  EXPECT_EQ("prioritized_stream_id=1", u.ToString());
+
+  EXPECT_TRUE(VerifyRandomCalls<Http2PriorityUpdateFields>());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/http2_structures_test_util.cc b/quiche/http2/http2_structures_test_util.cc
new file mode 100644
index 0000000..fbff7ea
--- /dev/null
+++ b/quiche/http2/http2_structures_test_util.cc
@@ -0,0 +1,112 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/http2_structures_test_util.h"
+
+#include <cstdint>
+
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_constants_test_util.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/test_tools/http2_random.h"
+
+namespace http2 {
+namespace test {
+
+void Randomize(Http2FrameHeader* out, Http2Random* rng) {
+  out->payload_length = rng->Rand32() & 0xffffff;
+  out->type = static_cast<Http2FrameType>(rng->Rand8());
+  out->flags = static_cast<Http2FrameFlag>(rng->Rand8());
+  out->stream_id = rng->Rand32() & StreamIdMask();
+}
+void Randomize(Http2PriorityFields* out, Http2Random* rng) {
+  out->stream_dependency = rng->Rand32() & StreamIdMask();
+  out->weight = rng->Rand8() + 1;
+  out->is_exclusive = rng->OneIn(2);
+}
+void Randomize(Http2RstStreamFields* out, Http2Random* rng) {
+  out->error_code = static_cast<Http2ErrorCode>(rng->Rand32());
+}
+void Randomize(Http2SettingFields* out, Http2Random* rng) {
+  out->parameter = static_cast<Http2SettingsParameter>(rng->Rand16());
+  out->value = rng->Rand32();
+}
+void Randomize(Http2PushPromiseFields* out, Http2Random* rng) {
+  out->promised_stream_id = rng->Rand32() & StreamIdMask();
+}
+void Randomize(Http2PingFields* out, Http2Random* rng) {
+  for (int ndx = 0; ndx < 8; ++ndx) {
+    out->opaque_bytes[ndx] = rng->Rand8();
+  }
+}
+void Randomize(Http2GoAwayFields* out, Http2Random* rng) {
+  out->last_stream_id = rng->Rand32() & StreamIdMask();
+  out->error_code = static_cast<Http2ErrorCode>(rng->Rand32());
+}
+void Randomize(Http2WindowUpdateFields* out, Http2Random* rng) {
+  out->window_size_increment = rng->Rand32() & 0x7fffffff;
+}
+void Randomize(Http2AltSvcFields* out, Http2Random* rng) {
+  out->origin_length = rng->Rand16();
+}
+void Randomize(Http2PriorityUpdateFields* out, Http2Random* rng) {
+  out->prioritized_stream_id = rng->Rand32() & StreamIdMask();
+}
+
+void ScrubFlagsOfHeader(Http2FrameHeader* header) {
+  uint8_t invalid_mask = InvalidFlagMaskForFrameType(header->type);
+  uint8_t keep_mask = ~invalid_mask;
+  header->RetainFlags(keep_mask);
+}
+
+bool FrameIsPadded(const Http2FrameHeader& header) {
+  switch (header.type) {
+    case Http2FrameType::DATA:
+    case Http2FrameType::HEADERS:
+    case Http2FrameType::PUSH_PROMISE:
+      return header.IsPadded();
+    default:
+      return false;
+  }
+}
+
+bool FrameHasPriority(const Http2FrameHeader& header) {
+  switch (header.type) {
+    case Http2FrameType::HEADERS:
+      return header.HasPriority();
+    case Http2FrameType::PRIORITY:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool FrameCanHavePayload(const Http2FrameHeader& header) {
+  switch (header.type) {
+    case Http2FrameType::DATA:
+    case Http2FrameType::HEADERS:
+    case Http2FrameType::PUSH_PROMISE:
+    case Http2FrameType::CONTINUATION:
+    case Http2FrameType::PING:
+    case Http2FrameType::GOAWAY:
+    case Http2FrameType::ALTSVC:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool FrameCanHaveHpackPayload(const Http2FrameHeader& header) {
+  switch (header.type) {
+    case Http2FrameType::HEADERS:
+    case Http2FrameType::PUSH_PROMISE:
+    case Http2FrameType::CONTINUATION:
+      return true;
+    default:
+      return false;
+  }
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/http2_structures_test_util.h b/quiche/http2/http2_structures_test_util.h
new file mode 100644
index 0000000..4a665de
--- /dev/null
+++ b/quiche/http2/http2_structures_test_util.h
@@ -0,0 +1,61 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_HTTP2_STRUCTURES_TEST_UTIL_H_
+#define QUICHE_HTTP2_HTTP2_STRUCTURES_TEST_UTIL_H_
+
+#include <string>
+
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/http2/tools/http2_frame_builder.h"
+
+namespace http2 {
+namespace test {
+
+template <class S>
+std::string SerializeStructure(const S& s) {
+  Http2FrameBuilder fb;
+  fb.Append(s);
+  EXPECT_EQ(S::EncodedSize(), fb.size());
+  return fb.buffer();
+}
+
+// Randomize the members of out, in a manner that yields encodeable contents
+// (e.g. a "uint24" field has only the low 24 bits set).
+void Randomize(Http2FrameHeader* out, Http2Random* rng);
+void Randomize(Http2PriorityFields* out, Http2Random* rng);
+void Randomize(Http2RstStreamFields* out, Http2Random* rng);
+void Randomize(Http2SettingFields* out, Http2Random* rng);
+void Randomize(Http2PushPromiseFields* out, Http2Random* rng);
+void Randomize(Http2PingFields* out, Http2Random* rng);
+void Randomize(Http2GoAwayFields* out, Http2Random* rng);
+void Randomize(Http2WindowUpdateFields* out, Http2Random* rng);
+void Randomize(Http2AltSvcFields* out, Http2Random* rng);
+void Randomize(Http2PriorityUpdateFields* out, Http2Random* rng);
+
+// Clear bits of header->flags that are known to be invalid for the
+// type. For unknown frame types, no change is made.
+void ScrubFlagsOfHeader(Http2FrameHeader* header);
+
+// Is the frame with this header padded? Only true for known/supported frame
+// types.
+bool FrameIsPadded(const Http2FrameHeader& header);
+
+// Does the frame with this header have Http2PriorityFields?
+bool FrameHasPriority(const Http2FrameHeader& header);
+
+// Does the frame with this header have a variable length payload (including
+// empty) payload (e.g. DATA or HEADERS)? Really a test of the frame type.
+bool FrameCanHavePayload(const Http2FrameHeader& header);
+
+// Does the frame with this header have a variable length HPACK payload
+// (including empty) payload (e.g. HEADERS)? Really a test of the frame type.
+bool FrameCanHaveHpackPayload(const Http2FrameHeader& header);
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_HTTP2_STRUCTURES_TEST_UTIL_H_
diff --git a/quiche/http2/platform/api/http2_bug_tracker.h b/quiche/http2/platform/api/http2_bug_tracker.h
new file mode 100644
index 0000000..b76b754
--- /dev/null
+++ b/quiche/http2/platform/api/http2_bug_tracker.h
@@ -0,0 +1,21 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_BUG_TRACKER_H_
+#define QUICHE_HTTP2_PLATFORM_API_HTTP2_BUG_TRACKER_H_
+
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+
+#define HTTP2_BUG QUICHE_BUG
+#define HTTP2_BUG_IF QUICHE_BUG_IF
+
+// V2 macros are the same as all the HTTP2_BUG flavor above, but they take a
+// bug_id parameter.
+#define HTTP2_BUG_V2 QUICHE_BUG
+#define HTTP2_BUG_IF_V2 QUICHE_BUG_IF
+
+#define FLAGS_http2_always_log_bugs_for_tests \
+  FLAGS_http2_always_log_bugs_for_tests_IMPL
+
+#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_BUG_TRACKER_H_
diff --git a/quiche/http2/platform/api/http2_flag_utils.h b/quiche/http2/platform/api/http2_flag_utils.h
new file mode 100644
index 0000000..92cedb1
--- /dev/null
+++ b/quiche/http2/platform/api/http2_flag_utils.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAG_UTILS_H_
+#define QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAG_UTILS_H_
+
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+
+#define HTTP2_RELOADABLE_FLAG_COUNT QUICHE_RELOADABLE_FLAG_COUNT
+#define HTTP2_RELOADABLE_FLAG_COUNT_N QUICHE_RELOADABLE_FLAG_COUNT_N
+
+#define HTTP2_RESTART_FLAG_COUNT QUICHE_RESTART_FLAG_COUNT
+#define HTTP2_RESTART_FLAG_COUNT_N QUICHE_RESTART_FLAG_COUNT_N
+
+#define HTTP2_CODE_COUNT QUICHE_CODE_COUNT
+#define HTTP2_CODE_COUNT_N QUICHE_CODE_COUNT_N
+
+#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAG_UTILS_H_
diff --git a/quiche/http2/platform/api/http2_flags.h b/quiche/http2/platform/api/http2_flags.h
new file mode 100644
index 0000000..0f53f5a
--- /dev/null
+++ b/quiche/http2/platform/api/http2_flags.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_
+#define QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_
+
+#include "quiche/common/platform/api/quiche_flags.h"
+
+#define GetHttp2ReloadableFlag(flag) GetQuicheReloadableFlag(http2, flag)
+#define SetHttp2ReloadableFlag(flag, value) \
+  SetQuicheReloadableFlag(http2, flag, value)
+#define GetHttp2RestartFlag(flag) GetQuicheRestartFlag(http2, flag)
+#define SetHttp2RestartFlag(flag, value) \
+  SetQuicheRestartFlag(http2, flag, value)
+#define GetHttp2Flag(flag) GetQuicheFlag(flag)
+#define SetHttp2Flag(flag, value) SetQuicheFlag(flag, value)
+
+#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_
diff --git a/quiche/http2/platform/api/http2_logging.h b/quiche/http2/platform/api/http2_logging.h
new file mode 100644
index 0000000..aa39e25
--- /dev/null
+++ b/quiche/http2/platform/api/http2_logging.h
@@ -0,0 +1,21 @@
+#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_LOGGING_H_
+#define QUICHE_HTTP2_PLATFORM_API_HTTP2_LOGGING_H_
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+#define HTTP2_LOG(severity) QUICHE_LOG(severity)
+
+#define HTTP2_VLOG(verbose_level) QUICHE_VLOG(verbose_level)
+
+#define HTTP2_DLOG(severity) QUICHE_DLOG(severity)
+
+#define HTTP2_DLOG_IF(severity, condition) QUICHE_DLOG_IF(severity, condition)
+
+#define HTTP2_DVLOG(verbose_level) QUICHE_DVLOG(verbose_level)
+
+#define HTTP2_DVLOG_IF(verbose_level, condition) \
+  QUICHE_DVLOG_IF(verbose_level, condition)
+
+#define HTTP2_LOG_FIRST_N(severity, n) QUICHE_LOG_FIRST_N(severity, n)
+
+#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_LOGGING_H_
diff --git a/quiche/http2/platform/api/http2_test_helpers.h b/quiche/http2/platform/api/http2_test_helpers.h
new file mode 100644
index 0000000..07d2906
--- /dev/null
+++ b/quiche/http2/platform/api/http2_test_helpers.h
@@ -0,0 +1,15 @@
+#ifndef QUICHE_HTTP2_PLATFORM_API_HTTP2_TEST_HELPERS_H_
+#define QUICHE_HTTP2_PLATFORM_API_HTTP2_TEST_HELPERS_H_
+
+// Provides VERIFY_* macros, similar to EXPECT_* and ASSERT_*, but they return
+// an AssertionResult if the condition is not satisfied.
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+
+#define VERIFY_AND_RETURN_SUCCESS(expression) \
+  {                                           \
+    VERIFY_SUCCESS(expression);               \
+    return ::testing::AssertionSuccess();     \
+  }
+
+#endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_TEST_HELPERS_H_
diff --git a/quiche/http2/test_tools/frame_parts.cc b/quiche/http2/test_tools/frame_parts.cc
new file mode 100644
index 0000000..bfdb2a4
--- /dev/null
+++ b/quiche/http2/test_tools/frame_parts.cc
@@ -0,0 +1,557 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/test_tools/frame_parts.h"
+
+#include <type_traits>
+
+#include "absl/strings/escaping.h"
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionFailure;
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using ::testing::ContainerEq;
+
+namespace http2 {
+namespace test {
+namespace {
+
+static_assert(std::is_base_of<Http2FrameDecoderListener, FrameParts>::value &&
+                  !std::is_abstract<FrameParts>::value,
+              "FrameParts needs to implement all of the methods of "
+              "Http2FrameDecoderListener");
+
+// Compare two optional variables of the same type.
+// TODO(jamessynge): Maybe create a ::testing::Matcher for this.
+template <class T>
+AssertionResult VerifyOptionalEq(const T& opt_a, const T& opt_b) {
+  if (opt_a) {
+    if (opt_b) {
+      VERIFY_EQ(opt_a.value(), opt_b.value());
+    } else {
+      return AssertionFailure()
+             << "opt_b is not set; opt_a.value()=" << opt_a.value();
+    }
+  } else if (opt_b) {
+    return AssertionFailure()
+           << "opt_a is not set; opt_b.value()=" << opt_b.value();
+  }
+  return AssertionSuccess();
+}
+
+}  // namespace
+
+FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header_(header) {
+  HTTP2_VLOG(1) << "FrameParts, header: " << frame_header_;
+}
+
+FrameParts::FrameParts(const Http2FrameHeader& header,
+                       absl::string_view payload)
+    : FrameParts(header) {
+  HTTP2_VLOG(1) << "FrameParts with payload.size() = " << payload.size();
+  this->payload_.append(payload.data(), payload.size());
+  opt_payload_length_ = payload.size();
+}
+FrameParts::FrameParts(const Http2FrameHeader& header,
+                       absl::string_view payload,
+                       size_t total_pad_length)
+    : FrameParts(header, payload) {
+  HTTP2_VLOG(1) << "FrameParts with total_pad_length=" << total_pad_length;
+  SetTotalPadLength(total_pad_length);
+}
+
+FrameParts::FrameParts(const FrameParts& header) = default;
+
+FrameParts::~FrameParts() = default;
+
+AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const {
+#define COMMON_MESSAGE "\n  this: " << *this << "\n  that: " << that
+
+  VERIFY_EQ(frame_header_, that.frame_header_) << COMMON_MESSAGE;
+  VERIFY_EQ(payload_, that.payload_) << COMMON_MESSAGE;
+  VERIFY_EQ(padding_, that.padding_) << COMMON_MESSAGE;
+  VERIFY_EQ(altsvc_origin_, that.altsvc_origin_) << COMMON_MESSAGE;
+  VERIFY_EQ(altsvc_value_, that.altsvc_value_) << COMMON_MESSAGE;
+  VERIFY_THAT(settings_, ContainerEq(that.settings_)) << COMMON_MESSAGE;
+
+#define VERIFY_OPTIONAL_FIELD(field_name) \
+  VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name))
+
+  VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_priority_update_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_goaway_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_missing_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_pad_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_ping_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_priority_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_push_promise_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_window_update_increment_) << COMMON_MESSAGE;
+
+#undef VERIFY_OPTIONAL_FIELD
+
+  return AssertionSuccess();
+}
+
+void FrameParts::SetTotalPadLength(size_t total_pad_length) {
+  opt_pad_length_.reset();
+  padding_.clear();
+  if (total_pad_length > 0) {
+    ASSERT_LE(total_pad_length, 256u);
+    ASSERT_TRUE(frame_header_.IsPadded());
+    opt_pad_length_ = total_pad_length - 1;
+    char zero = 0;
+    padding_.append(opt_pad_length_.value(), zero);
+  }
+
+  if (opt_pad_length_) {
+    HTTP2_VLOG(1) << "SetTotalPadLength: pad_length="
+                  << opt_pad_length_.value();
+  } else {
+    HTTP2_VLOG(1) << "SetTotalPadLength: has no pad length";
+  }
+}
+
+void FrameParts::SetAltSvcExpected(absl::string_view origin,
+                                   absl::string_view value) {
+  altsvc_origin_.append(origin.data(), origin.size());
+  altsvc_value_.append(value.data(), value.size());
+  opt_altsvc_origin_length_ = origin.size();
+  opt_altsvc_value_length_ = value.size();
+}
+
+bool FrameParts::OnFrameHeader(const Http2FrameHeader& /*header*/) {
+  ADD_FAILURE() << "OnFrameHeader: " << *this;
+  return true;
+}
+
+void FrameParts::OnDataStart(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnDataStart: " << header;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this;
+  opt_payload_length_ = header.payload_length;
+}
+
+void FrameParts::OnDataPayload(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnDataPayload: len=" << len
+                << "; frame_header_: " << frame_header_;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this;
+  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
+                           &opt_payload_length_));
+}
+
+void FrameParts::OnDataEnd() {
+  HTTP2_VLOG(1) << "OnDataEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this;
+}
+
+void FrameParts::OnHeadersStart(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this;
+  opt_payload_length_ = header.payload_length;
+}
+
+void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) {
+  HTTP2_VLOG(1) << "OnHeadersPriority: priority: " << priority
+                << "; frame_header_: " << frame_header_;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this;
+  ASSERT_FALSE(opt_priority_);
+  opt_priority_ = priority;
+  ASSERT_TRUE(opt_payload_length_);
+  opt_payload_length_ =
+      opt_payload_length_.value() - Http2PriorityFields::EncodedSize();
+}
+
+void FrameParts::OnHpackFragment(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len
+                << "; frame_header_: " << frame_header_;
+  ASSERT_TRUE(got_start_callback_);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header_)) << *this;
+  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
+                           &opt_payload_length_));
+}
+
+void FrameParts::OnHeadersEnd() {
+  HTTP2_VLOG(1) << "OnHeadersEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this;
+}
+
+void FrameParts::OnPriorityFrame(const Http2FrameHeader& header,
+                                 const Http2PriorityFields& priority) {
+  HTTP2_VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this;
+  ASSERT_FALSE(opt_priority_);
+  opt_priority_ = priority;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this;
+}
+
+void FrameParts::OnContinuationStart(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this;
+  opt_payload_length_ = header.payload_length;
+}
+
+void FrameParts::OnContinuationEnd() {
+  HTTP2_VLOG(1) << "OnContinuationEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this;
+}
+
+void FrameParts::OnPadLength(size_t trailing_length) {
+  HTTP2_VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
+  ASSERT_TRUE(InPaddedFrame()) << *this;
+  ASSERT_FALSE(opt_pad_length_);
+  ASSERT_TRUE(opt_payload_length_);
+  size_t total_padding_length = trailing_length + 1;
+  ASSERT_GE(opt_payload_length_.value(), total_padding_length);
+  opt_payload_length_ = opt_payload_length_.value() - total_padding_length;
+  opt_pad_length_ = trailing_length;
+}
+
+void FrameParts::OnPadding(const char* pad, size_t skipped_length) {
+  HTTP2_VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
+  ASSERT_TRUE(InPaddedFrame()) << *this;
+  ASSERT_TRUE(opt_pad_length_);
+  ASSERT_TRUE(AppendString(absl::string_view(pad, skipped_length), &padding_,
+                           &opt_pad_length_));
+}
+
+void FrameParts::OnRstStream(const Http2FrameHeader& header,
+                             Http2ErrorCode error_code) {
+  HTTP2_VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this;
+  ASSERT_FALSE(opt_rst_stream_error_code_);
+  opt_rst_stream_error_code_ = error_code;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this;
+}
+
+void FrameParts::OnSettingsStart(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
+  ASSERT_EQ(0u, settings_.size());
+  ASSERT_FALSE(header.IsAck()) << header;
+}
+
+void FrameParts::OnSetting(const Http2SettingFields& setting_fields) {
+  HTTP2_VLOG(1) << "OnSetting: " << setting_fields;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this;
+  settings_.push_back(setting_fields);
+}
+
+void FrameParts::OnSettingsEnd() {
+  HTTP2_VLOG(1) << "OnSettingsEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
+}
+
+void FrameParts::OnSettingsAck(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
+  ASSERT_EQ(0u, settings_.size());
+  ASSERT_TRUE(header.IsAck());
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
+}
+
+void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header,
+                                    const Http2PushPromiseFields& promise,
+                                    size_t total_padding_length) {
+  HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
+                << "; promise: " << promise
+                << "; total_padding_length: " << total_padding_length;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this;
+  ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize());
+  opt_payload_length_ =
+      header.payload_length - Http2PushPromiseFields::EncodedSize();
+  ASSERT_FALSE(opt_push_promise_);
+  opt_push_promise_ = promise;
+  if (total_padding_length > 0) {
+    ASSERT_GE(opt_payload_length_.value(), total_padding_length);
+    OnPadLength(total_padding_length - 1);
+  } else {
+    ASSERT_FALSE(header.IsPadded());
+  }
+}
+
+void FrameParts::OnPushPromiseEnd() {
+  HTTP2_VLOG(1) << "OnPushPromiseEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this;
+}
+
+void FrameParts::OnPing(const Http2FrameHeader& header,
+                        const Http2PingFields& ping) {
+  HTTP2_VLOG(1) << "OnPing header: " << header << "   ping: " << ping;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
+  ASSERT_FALSE(header.IsAck());
+  ASSERT_FALSE(opt_ping_);
+  opt_ping_ = ping;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
+}
+
+void FrameParts::OnPingAck(const Http2FrameHeader& header,
+                           const Http2PingFields& ping) {
+  HTTP2_VLOG(1) << "OnPingAck header: " << header << "   ping: " << ping;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
+  ASSERT_TRUE(header.IsAck());
+  ASSERT_FALSE(opt_ping_);
+  opt_ping_ = ping;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
+}
+
+void FrameParts::OnGoAwayStart(const Http2FrameHeader& header,
+                               const Http2GoAwayFields& goaway) {
+  HTTP2_VLOG(1) << "OnGoAwayStart: " << goaway;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this;
+  ASSERT_FALSE(opt_goaway_);
+  opt_goaway_ = goaway;
+  opt_payload_length_ =
+      header.payload_length - Http2GoAwayFields::EncodedSize();
+}
+
+void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this;
+  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
+                           &opt_payload_length_));
+}
+
+void FrameParts::OnGoAwayEnd() {
+  HTTP2_VLOG(1) << "OnGoAwayEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this;
+}
+
+void FrameParts::OnWindowUpdate(const Http2FrameHeader& header,
+                                uint32_t increment) {
+  HTTP2_VLOG(1) << "OnWindowUpdate header: " << header
+                << "     increment=" << increment;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this;
+  ASSERT_FALSE(opt_window_update_increment_);
+  opt_window_update_increment_ = increment;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this;
+}
+
+void FrameParts::OnAltSvcStart(const Http2FrameHeader& header,
+                               size_t origin_length,
+                               size_t value_length) {
+  HTTP2_VLOG(1) << "OnAltSvcStart: " << header
+                << "    origin_length: " << origin_length
+                << "    value_length: " << value_length;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this;
+  ASSERT_FALSE(opt_altsvc_origin_length_);
+  opt_altsvc_origin_length_ = origin_length;
+  ASSERT_FALSE(opt_altsvc_value_length_);
+  opt_altsvc_value_length_ = value_length;
+}
+
+void FrameParts::OnAltSvcOriginData(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
+  ASSERT_TRUE(AppendString(absl::string_view(data, len), &altsvc_origin_,
+                           &opt_altsvc_origin_length_));
+}
+
+void FrameParts::OnAltSvcValueData(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
+  ASSERT_TRUE(AppendString(absl::string_view(data, len), &altsvc_value_,
+                           &opt_altsvc_value_length_));
+}
+
+void FrameParts::OnAltSvcEnd() {
+  HTTP2_VLOG(1) << "OnAltSvcEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this;
+}
+
+void FrameParts::OnPriorityUpdateStart(
+    const Http2FrameHeader& header,
+    const Http2PriorityUpdateFields& priority_update) {
+  HTTP2_VLOG(1) << "OnPriorityUpdateStart: " << header
+                << "    prioritized_stream_id: "
+                << priority_update.prioritized_stream_id;
+  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY_UPDATE))
+      << *this;
+  ASSERT_FALSE(opt_priority_update_);
+  opt_priority_update_ = priority_update;
+  opt_payload_length_ =
+      header.payload_length - Http2PriorityUpdateFields::EncodedSize();
+}
+
+void FrameParts::OnPriorityUpdatePayload(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
+  ASSERT_TRUE(InFrameOfType(Http2FrameType::PRIORITY_UPDATE)) << *this;
+  payload_.append(data, len);
+}
+
+void FrameParts::OnPriorityUpdateEnd() {
+  HTTP2_VLOG(1) << "OnPriorityUpdateEnd; frame_header_: " << frame_header_;
+  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY_UPDATE)) << *this;
+}
+
+void FrameParts::OnUnknownStart(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
+  ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header;
+  ASSERT_FALSE(got_start_callback_);
+  ASSERT_EQ(frame_header_, header);
+  got_start_callback_ = true;
+  opt_payload_length_ = header.payload_length;
+}
+
+void FrameParts::OnUnknownPayload(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
+  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
+  ASSERT_TRUE(got_start_callback_);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_TRUE(AppendString(absl::string_view(data, len), &payload_,
+                           &opt_payload_length_));
+}
+
+void FrameParts::OnUnknownEnd() {
+  HTTP2_VLOG(1) << "OnUnknownEnd; frame_header_: " << frame_header_;
+  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
+  ASSERT_TRUE(got_start_callback_);
+  ASSERT_FALSE(got_end_callback_);
+  got_end_callback_ = true;
+}
+
+void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header,
+                                  size_t missing_length) {
+  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
+                << "; missing_length: " << missing_length;
+  ASSERT_EQ(frame_header_, header);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_TRUE(FrameIsPadded(header));
+  ASSERT_FALSE(opt_pad_length_);
+  ASSERT_FALSE(opt_missing_length_);
+  opt_missing_length_ = missing_length;
+  got_start_callback_ = true;
+  got_end_callback_ = true;
+}
+
+void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+  ASSERT_EQ(frame_header_, header);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_FALSE(has_frame_size_error_);
+  has_frame_size_error_ = true;
+  got_end_callback_ = true;
+}
+
+void FrameParts::OutputTo(std::ostream& out) const {
+  out << "FrameParts{\n  frame_header_: " << frame_header_ << "\n";
+  if (!payload_.empty()) {
+    out << "  payload_=\"" << absl::CHexEscape(payload_) << "\"\n";
+  }
+  if (!padding_.empty()) {
+    out << "  padding_=\"" << absl::CHexEscape(padding_) << "\"\n";
+  }
+  if (!altsvc_origin_.empty()) {
+    out << "  altsvc_origin_=\"" << absl::CHexEscape(altsvc_origin_) << "\"\n";
+  }
+  if (!altsvc_value_.empty()) {
+    out << "  altsvc_value_=\"" << absl::CHexEscape(altsvc_value_) << "\"\n";
+  }
+  if (opt_priority_) {
+    out << "  priority=" << opt_priority_.value() << "\n";
+  }
+  if (opt_rst_stream_error_code_) {
+    out << "  rst_stream=" << opt_rst_stream_error_code_.value() << "\n";
+  }
+  if (opt_push_promise_) {
+    out << "  push_promise=" << opt_push_promise_.value() << "\n";
+  }
+  if (opt_ping_) {
+    out << "  ping=" << opt_ping_.value() << "\n";
+  }
+  if (opt_goaway_) {
+    out << "  goaway=" << opt_goaway_.value() << "\n";
+  }
+  if (opt_window_update_increment_) {
+    out << "  window_update=" << opt_window_update_increment_.value() << "\n";
+  }
+  if (opt_payload_length_) {
+    out << "  payload_length=" << opt_payload_length_.value() << "\n";
+  }
+  if (opt_pad_length_) {
+    out << "  pad_length=" << opt_pad_length_.value() << "\n";
+  }
+  if (opt_missing_length_) {
+    out << "  missing_length=" << opt_missing_length_.value() << "\n";
+  }
+  if (opt_altsvc_origin_length_) {
+    out << "  origin_length=" << opt_altsvc_origin_length_.value() << "\n";
+  }
+  if (opt_altsvc_value_length_) {
+    out << "  value_length=" << opt_altsvc_value_length_.value() << "\n";
+  }
+  if (opt_priority_update_) {
+    out << "  prioritized_stream_id_=" << opt_priority_update_.value() << "\n";
+  }
+  if (has_frame_size_error_) {
+    out << "  has_frame_size_error\n";
+  }
+  if (got_start_callback_) {
+    out << "  got_start_callback\n";
+  }
+  if (got_end_callback_) {
+    out << "  got_end_callback\n";
+  }
+  for (size_t ndx = 0; ndx < settings_.size(); ++ndx) {
+    out << "  setting[" << ndx << "]=" << settings_[ndx];
+  }
+  out << "}";
+}
+
+AssertionResult FrameParts::StartFrameOfType(
+    const Http2FrameHeader& header,
+    Http2FrameType expected_frame_type) {
+  VERIFY_EQ(header.type, expected_frame_type);
+  VERIFY_FALSE(got_start_callback_);
+  VERIFY_FALSE(got_end_callback_);
+  VERIFY_EQ(frame_header_, header);
+  got_start_callback_ = true;
+  return AssertionSuccess();
+}
+
+AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) {
+  VERIFY_TRUE(got_start_callback_);
+  VERIFY_FALSE(got_end_callback_);
+  VERIFY_EQ(frame_header_.type, expected_frame_type);
+  return AssertionSuccess();
+}
+
+AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) {
+  VERIFY_SUCCESS(InFrameOfType(expected_frame_type));
+  got_end_callback_ = true;
+  return AssertionSuccess();
+}
+
+AssertionResult FrameParts::InPaddedFrame() {
+  VERIFY_TRUE(got_start_callback_);
+  VERIFY_FALSE(got_end_callback_);
+  VERIFY_TRUE(FrameIsPadded(frame_header_));
+  return AssertionSuccess();
+}
+
+AssertionResult FrameParts::AppendString(absl::string_view source,
+                                         std::string* target,
+                                         absl::optional<size_t>* opt_length) {
+  target->append(source.data(), source.size());
+  if (opt_length != nullptr) {
+    VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this;
+    VERIFY_LE(target->size(), opt_length->value())
+        << "String too large; source.size() = " << source.size() << "\n"
+        << *this;
+  }
+  return ::testing::AssertionSuccess();
+}
+
+std::ostream& operator<<(std::ostream& out, const FrameParts& v) {
+  v.OutputTo(out);
+  return out;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/test_tools/frame_parts.h b/quiche/http2/test_tools/frame_parts.h
new file mode 100644
index 0000000..8f1bea9
--- /dev/null
+++ b/quiche/http2/test_tools/frame_parts.h
@@ -0,0 +1,259 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
+#define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
+
+// FrameParts implements Http2FrameDecoderListener, recording the callbacks
+// during the decoding of a single frame. It is also used for comparing the
+// info that a test expects to be recorded during the decoding of a frame
+// with the actual recorded value (i.e. by providing a comparator).
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+class FrameParts : public Http2FrameDecoderListener {
+ public:
+  // The first callback for every type of frame includes the frame header; this
+  // is the only constructor used during decoding of a frame.
+  explicit FrameParts(const Http2FrameHeader& header);
+
+  // For use in tests where the expected frame has a variable size payload.
+  FrameParts(const Http2FrameHeader& header, absl::string_view payload);
+
+  // For use in tests where the expected frame has a variable size payload
+  // and may be padded.
+  FrameParts(const Http2FrameHeader& header,
+             absl::string_view payload,
+             size_t total_pad_length);
+
+  // Copy constructor.
+  FrameParts(const FrameParts& header);
+
+  ~FrameParts() override;
+
+  // Returns AssertionSuccess() if they're equal, else AssertionFailure()
+  // with info about the difference.
+  ::testing::AssertionResult VerifyEquals(const FrameParts& other) const;
+
+  // Format this FrameParts object.
+  void OutputTo(std::ostream& out) const;
+
+  // Set the total padding length (0 to 256).
+  void SetTotalPadLength(size_t total_pad_length);
+
+  // Set the origin and value expected in an ALTSVC frame.
+  void SetAltSvcExpected(absl::string_view origin, absl::string_view value);
+
+  // Http2FrameDecoderListener methods:
+  bool OnFrameHeader(const Http2FrameHeader& header) override;
+  void OnDataStart(const Http2FrameHeader& header) override;
+  void OnDataPayload(const char* data, size_t len) override;
+  void OnDataEnd() override;
+  void OnHeadersStart(const Http2FrameHeader& header) override;
+  void OnHeadersPriority(const Http2PriorityFields& priority) override;
+  void OnHpackFragment(const char* data, size_t len) override;
+  void OnHeadersEnd() override;
+  void OnPriorityFrame(const Http2FrameHeader& header,
+                       const Http2PriorityFields& priority) override;
+  void OnContinuationStart(const Http2FrameHeader& header) override;
+  void OnContinuationEnd() override;
+  void OnPadLength(size_t trailing_length) override;
+  void OnPadding(const char* pad, size_t skipped_length) override;
+  void OnRstStream(const Http2FrameHeader& header,
+                   Http2ErrorCode error_code) override;
+  void OnSettingsStart(const Http2FrameHeader& header) override;
+  void OnSetting(const Http2SettingFields& setting_fields) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck(const Http2FrameHeader& header) override;
+  void OnPushPromiseStart(const Http2FrameHeader& header,
+                          const Http2PushPromiseFields& promise,
+                          size_t total_padding_length) override;
+  void OnPushPromiseEnd() override;
+  void OnPing(const Http2FrameHeader& header,
+              const Http2PingFields& ping) override;
+  void OnPingAck(const Http2FrameHeader& header,
+                 const Http2PingFields& ping) override;
+  void OnGoAwayStart(const Http2FrameHeader& header,
+                     const Http2GoAwayFields& goaway) override;
+  void OnGoAwayOpaqueData(const char* data, size_t len) override;
+  void OnGoAwayEnd() override;
+  void OnWindowUpdate(const Http2FrameHeader& header,
+                      uint32_t increment) override;
+  void OnAltSvcStart(const Http2FrameHeader& header,
+                     size_t origin_length,
+                     size_t value_length) override;
+  void OnAltSvcOriginData(const char* data, size_t len) override;
+  void OnAltSvcValueData(const char* data, size_t len) override;
+  void OnAltSvcEnd() override;
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) override;
+  void OnPriorityUpdatePayload(const char* data, size_t len) override;
+  void OnPriorityUpdateEnd() override;
+  void OnUnknownStart(const Http2FrameHeader& header) override;
+  void OnUnknownPayload(const char* data, size_t len) override;
+  void OnUnknownEnd() override;
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override;
+  void OnFrameSizeError(const Http2FrameHeader& header) override;
+
+  void AppendSetting(const Http2SettingFields& setting_fields) {
+    settings_.push_back(setting_fields);
+  }
+
+  const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
+
+  absl::optional<Http2PriorityFields> GetOptPriority() const {
+    return opt_priority_;
+  }
+  absl::optional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
+    return opt_rst_stream_error_code_;
+  }
+  absl::optional<Http2PushPromiseFields> GetOptPushPromise() const {
+    return opt_push_promise_;
+  }
+  absl::optional<Http2PingFields> GetOptPing() const { return opt_ping_; }
+  absl::optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; }
+  absl::optional<size_t> GetOptPadLength() const { return opt_pad_length_; }
+  absl::optional<size_t> GetOptPayloadLength() const {
+    return opt_payload_length_;
+  }
+  absl::optional<size_t> GetOptMissingLength() const {
+    return opt_missing_length_;
+  }
+  absl::optional<size_t> GetOptAltsvcOriginLength() const {
+    return opt_altsvc_origin_length_;
+  }
+  absl::optional<size_t> GetOptAltsvcValueLength() const {
+    return opt_altsvc_value_length_;
+  }
+  absl::optional<size_t> GetOptWindowUpdateIncrement() const {
+    return opt_window_update_increment_;
+  }
+  bool GetHasFrameSizeError() const { return has_frame_size_error_; }
+
+  void SetOptPriority(absl::optional<Http2PriorityFields> opt_priority) {
+    opt_priority_ = opt_priority;
+  }
+  void SetOptRstStreamErrorCode(
+      absl::optional<Http2ErrorCode> opt_rst_stream_error_code) {
+    opt_rst_stream_error_code_ = opt_rst_stream_error_code;
+  }
+  void SetOptPushPromise(
+      absl::optional<Http2PushPromiseFields> opt_push_promise) {
+    opt_push_promise_ = opt_push_promise;
+  }
+  void SetOptPing(absl::optional<Http2PingFields> opt_ping) {
+    opt_ping_ = opt_ping;
+  }
+  void SetOptGoaway(absl::optional<Http2GoAwayFields> opt_goaway) {
+    opt_goaway_ = opt_goaway;
+  }
+  void SetOptPadLength(absl::optional<size_t> opt_pad_length) {
+    opt_pad_length_ = opt_pad_length;
+  }
+  void SetOptPayloadLength(absl::optional<size_t> opt_payload_length) {
+    opt_payload_length_ = opt_payload_length;
+  }
+  void SetOptMissingLength(absl::optional<size_t> opt_missing_length) {
+    opt_missing_length_ = opt_missing_length;
+  }
+  void SetOptAltsvcOriginLength(
+      absl::optional<size_t> opt_altsvc_origin_length) {
+    opt_altsvc_origin_length_ = opt_altsvc_origin_length;
+  }
+  void SetOptAltsvcValueLength(absl::optional<size_t> opt_altsvc_value_length) {
+    opt_altsvc_value_length_ = opt_altsvc_value_length;
+  }
+  void SetOptWindowUpdateIncrement(
+      absl::optional<size_t> opt_window_update_increment) {
+    opt_window_update_increment_ = opt_window_update_increment;
+  }
+  void SetOptPriorityUpdate(
+      absl::optional<Http2PriorityUpdateFields> priority_update) {
+    opt_priority_update_ = priority_update;
+  }
+
+  void SetHasFrameSizeError(bool has_frame_size_error) {
+    has_frame_size_error_ = has_frame_size_error;
+  }
+
+ private:
+  // ASSERT during an On* method that we're handling a frame of type
+  // expected_frame_type, and have not already received other On* methods
+  // (i.e. got_start_callback is false).
+  ::testing::AssertionResult StartFrameOfType(
+      const Http2FrameHeader& header,
+      Http2FrameType expected_frame_type);
+
+  // ASSERT that StartFrameOfType has already been called with
+  // expected_frame_type (i.e. got_start_callback has been called), and that
+  // EndFrameOfType has not yet been called (i.e. got_end_callback is false).
+  ::testing::AssertionResult InFrameOfType(Http2FrameType expected_frame_type);
+
+  // ASSERT that we're InFrameOfType, and then sets got_end_callback=true.
+  ::testing::AssertionResult EndFrameOfType(Http2FrameType expected_frame_type);
+
+  // ASSERT that we're in the middle of processing a frame that is padded.
+  ::testing::AssertionResult InPaddedFrame();
+
+  // Append source to target. If opt_length is not nullptr, then verifies that
+  // the optional has a value (i.e. that the necessary On*Start method has been
+  // called), and that target is not longer than opt_length->value().
+  ::testing::AssertionResult AppendString(absl::string_view source,
+                                          std::string* target,
+                                          absl::optional<size_t>* opt_length);
+
+  const Http2FrameHeader frame_header_;
+
+  std::string payload_;
+  std::string padding_;
+  std::string altsvc_origin_;
+  std::string altsvc_value_;
+
+  absl::optional<Http2PriorityFields> opt_priority_;
+  absl::optional<Http2ErrorCode> opt_rst_stream_error_code_;
+  absl::optional<Http2PushPromiseFields> opt_push_promise_;
+  absl::optional<Http2PingFields> opt_ping_;
+  absl::optional<Http2GoAwayFields> opt_goaway_;
+  absl::optional<Http2PriorityUpdateFields> opt_priority_update_;
+
+  absl::optional<size_t> opt_pad_length_;
+  absl::optional<size_t> opt_payload_length_;
+  absl::optional<size_t> opt_missing_length_;
+  absl::optional<size_t> opt_altsvc_origin_length_;
+  absl::optional<size_t> opt_altsvc_value_length_;
+
+  absl::optional<size_t> opt_window_update_increment_;
+
+  bool has_frame_size_error_ = false;
+
+  std::vector<Http2SettingFields> settings_;
+
+  // These booleans are not checked by CompareCollectedFrames.
+  bool got_start_callback_ = false;
+  bool got_end_callback_ = false;
+};
+
+std::ostream& operator<<(std::ostream& out, const FrameParts& v);
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
diff --git a/quiche/http2/test_tools/frame_parts_collector.cc b/quiche/http2/test_tools/frame_parts_collector.cc
new file mode 100644
index 0000000..6f986cd
--- /dev/null
+++ b/quiche/http2/test_tools/frame_parts_collector.cc
@@ -0,0 +1,112 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+
+#include <utility>
+
+#include "quiche/http2/http2_structures_test_util.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+FramePartsCollector::FramePartsCollector() = default;
+FramePartsCollector::~FramePartsCollector() = default;
+
+void FramePartsCollector::Reset() {
+  current_frame_.reset();
+  collected_frames_.clear();
+  expected_header_set_ = false;
+}
+
+const FrameParts* FramePartsCollector::frame(size_t n) const {
+  if (n < size()) {
+    return collected_frames_.at(n).get();
+  }
+  QUICHE_CHECK(n == size());
+  return current_frame();
+}
+
+void FramePartsCollector::ExpectFrameHeader(const Http2FrameHeader& header) {
+  EXPECT_FALSE(IsInProgress());
+  EXPECT_FALSE(expected_header_set_)
+      << "expected_header_: " << expected_header_;
+  expected_header_ = header;
+  expected_header_set_ = true;
+  // OnFrameHeader is called before the flags are scrubbed, but the other
+  // methods are called after, so scrub the invalid flags from expected_header_.
+  ScrubFlagsOfHeader(&expected_header_);
+}
+
+void FramePartsCollector::TestExpectedHeader(const Http2FrameHeader& header) {
+  if (expected_header_set_) {
+    EXPECT_EQ(header, expected_header_);
+    expected_header_set_ = false;
+  }
+}
+
+Http2FrameDecoderListener* FramePartsCollector::StartFrame(
+    const Http2FrameHeader& header) {
+  TestExpectedHeader(header);
+  EXPECT_FALSE(IsInProgress());
+  if (current_frame_ == nullptr) {
+    current_frame_ = std::make_unique<FrameParts>(header);
+  }
+  return current_frame();
+}
+
+Http2FrameDecoderListener* FramePartsCollector::StartAndEndFrame(
+    const Http2FrameHeader& header) {
+  TestExpectedHeader(header);
+  EXPECT_FALSE(IsInProgress());
+  if (current_frame_ == nullptr) {
+    current_frame_ = std::make_unique<FrameParts>(header);
+  }
+  Http2FrameDecoderListener* result = current_frame();
+  collected_frames_.push_back(std::move(current_frame_));
+  return result;
+}
+
+Http2FrameDecoderListener* FramePartsCollector::CurrentFrame() {
+  EXPECT_TRUE(IsInProgress());
+  if (current_frame_ == nullptr) {
+    return &failing_listener_;
+  }
+  return current_frame();
+}
+
+Http2FrameDecoderListener* FramePartsCollector::EndFrame() {
+  EXPECT_TRUE(IsInProgress());
+  if (current_frame_ == nullptr) {
+    return &failing_listener_;
+  }
+  Http2FrameDecoderListener* result = current_frame();
+  collected_frames_.push_back(std::move(current_frame_));
+  return result;
+}
+
+Http2FrameDecoderListener* FramePartsCollector::FrameError(
+    const Http2FrameHeader& header) {
+  TestExpectedHeader(header);
+  if (current_frame_ == nullptr) {
+    // The decoder may detect an error before making any calls to the listener
+    // regarding the frame, in which case current_frame_==nullptr and we need
+    // to create a FrameParts instance.
+    current_frame_ = std::make_unique<FrameParts>(header);
+  } else {
+    // Similarly, the decoder may have made calls to the listener regarding the
+    // frame before detecting the error; for example, the DATA payload decoder
+    // calls OnDataStart before it can detect padding errors, hence before it
+    // can call OnPaddingTooLong.
+    EXPECT_EQ(header, current_frame_->GetFrameHeader());
+  }
+  Http2FrameDecoderListener* result = current_frame();
+  collected_frames_.push_back(std::move(current_frame_));
+  return result;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/test_tools/frame_parts_collector.h b/quiche/http2/test_tools/frame_parts_collector.h
new file mode 100644
index 0000000..28ee06b
--- /dev/null
+++ b/quiche/http2/test_tools/frame_parts_collector.h
@@ -0,0 +1,111 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_
+#define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_
+
+// FramePartsCollector is a base class for Http2FrameDecoderListener
+// implementations that create one FrameParts instance for each decoded frame.
+
+#include <stddef.h>
+
+#include <memory>
+#include <vector>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener_test_util.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/test_tools/frame_parts.h"
+
+namespace http2 {
+namespace test {
+
+class FramePartsCollector : public FailingHttp2FrameDecoderListener {
+ public:
+  FramePartsCollector();
+  ~FramePartsCollector() override;
+
+  // Toss out the collected data.
+  void Reset();
+
+  // Returns true if has started recording the info for a frame and has not yet
+  // finished doing so.
+  bool IsInProgress() const { return current_frame_ != nullptr; }
+
+  // Returns the FrameParts instance into which we're currently recording
+  // callback info if IsInProgress, else nullptr.
+  const FrameParts* current_frame() const { return current_frame_.get(); }
+
+  // Returns the number of completely collected FrameParts instances.
+  size_t size() const { return collected_frames_.size(); }
+
+  // Returns the n'th frame, where 0 is the oldest of the collected frames,
+  // and n==size() is the frame currently being collected, if there is one.
+  // Returns nullptr if the requested index is not valid.
+  const FrameParts* frame(size_t n) const;
+
+ protected:
+  // In support of OnFrameHeader, set the header that we expect to be used in
+  // the next call.
+  // TODO(jamessynge): Remove ExpectFrameHeader et al. once done with supporting
+  // SpdyFramer's exact states.
+  void ExpectFrameHeader(const Http2FrameHeader& header);
+
+  // For use in implementing On*Start methods of Http2FrameDecoderListener,
+  // returns a FrameParts instance, which will be newly created if
+  // IsInProgress==false (which the caller should ensure), else will be the
+  // current_frame(); never returns nullptr.
+  // If called when IsInProgress==true, a test failure will be recorded.
+  Http2FrameDecoderListener* StartFrame(const Http2FrameHeader& header);
+
+  // For use in implementing On* callbacks, such as OnPingAck, that are the only
+  // call expected for the frame being decoded; not for On*Start methods.
+  // Returns a FrameParts instance, which will be newly created if
+  // IsInProgress==false (which the caller should ensure), else will be the
+  // current_frame(); never returns nullptr.
+  // If called when IsInProgress==true, a test failure will be recorded.
+  Http2FrameDecoderListener* StartAndEndFrame(const Http2FrameHeader& header);
+
+  // If IsInProgress==true, returns the FrameParts into which the current
+  // frame is being recorded; else records a test failure and returns
+  // failing_listener_, which will record a test failure when any of its
+  // On* methods is called.
+  Http2FrameDecoderListener* CurrentFrame();
+
+  // For use in implementing On*End methods, pushes the current frame onto
+  // the vector of completed frames, and returns a pointer to it for recording
+  // the info in the final call. If IsInProgress==false, records a test failure
+  // and returns failing_listener_, which will record a test failure when any
+  // of its On* methods is called.
+  Http2FrameDecoderListener* EndFrame();
+
+  // For use in implementing OnPaddingTooLong and OnFrameSizeError, is
+  // equivalent to EndFrame() if IsInProgress==true, else equivalent to
+  // StartAndEndFrame().
+  Http2FrameDecoderListener* FrameError(const Http2FrameHeader& header);
+
+ private:
+  // Returns the mutable FrameParts instance into which we're currently
+  // recording callback info if IsInProgress, else nullptr.
+  FrameParts* current_frame() { return current_frame_.get(); }
+
+  // If expected header is set, verify that it matches the header param.
+  // TODO(jamessynge): Remove TestExpectedHeader et al. once done
+  // with supporting SpdyFramer's exact states.
+  void TestExpectedHeader(const Http2FrameHeader& header);
+
+  std::unique_ptr<FrameParts> current_frame_;
+  std::vector<std::unique_ptr<FrameParts>> collected_frames_;
+  FailingHttp2FrameDecoderListener failing_listener_;
+
+  // TODO(jamessynge): Remove expected_header_ et al. once done with supporting
+  // SpdyFramer's exact states.
+  Http2FrameHeader expected_header_;
+  bool expected_header_set_ = false;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_H_
diff --git a/quiche/http2/test_tools/frame_parts_collector_listener.cc b/quiche/http2/test_tools/frame_parts_collector_listener.cc
new file mode 100644
index 0000000..d03e026
--- /dev/null
+++ b/quiche/http2/test_tools/frame_parts_collector_listener.cc
@@ -0,0 +1,250 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/test_tools/frame_parts_collector_listener.h"
+
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+bool FramePartsCollectorListener::OnFrameHeader(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnFrameHeader: " << header;
+  ExpectFrameHeader(header);
+  return true;
+}
+
+void FramePartsCollectorListener::OnDataStart(const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnDataStart: " << header;
+  StartFrame(header)->OnDataStart(header);
+}
+
+void FramePartsCollectorListener::OnDataPayload(const char* data, size_t len) {
+  HTTP2_VLOG(1) << "OnDataPayload: len=" << len;
+  CurrentFrame()->OnDataPayload(data, len);
+}
+
+void FramePartsCollectorListener::OnDataEnd() {
+  HTTP2_VLOG(1) << "OnDataEnd";
+  EndFrame()->OnDataEnd();
+}
+
+void FramePartsCollectorListener::OnHeadersStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
+  StartFrame(header)->OnHeadersStart(header);
+}
+
+void FramePartsCollectorListener::OnHeadersPriority(
+    const Http2PriorityFields& priority) {
+  HTTP2_VLOG(1) << "OnHeadersPriority: " << priority;
+  CurrentFrame()->OnHeadersPriority(priority);
+}
+
+void FramePartsCollectorListener::OnHpackFragment(const char* data,
+                                                  size_t len) {
+  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len;
+  CurrentFrame()->OnHpackFragment(data, len);
+}
+
+void FramePartsCollectorListener::OnHeadersEnd() {
+  HTTP2_VLOG(1) << "OnHeadersEnd";
+  EndFrame()->OnHeadersEnd();
+}
+
+void FramePartsCollectorListener::OnPriorityFrame(
+    const Http2FrameHeader& header,
+    const Http2PriorityFields& priority_fields) {
+  HTTP2_VLOG(1) << "OnPriority: " << header << "; " << priority_fields;
+  StartAndEndFrame(header)->OnPriorityFrame(header, priority_fields);
+}
+
+void FramePartsCollectorListener::OnContinuationStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
+  StartFrame(header)->OnContinuationStart(header);
+}
+
+void FramePartsCollectorListener::OnContinuationEnd() {
+  HTTP2_VLOG(1) << "OnContinuationEnd";
+  EndFrame()->OnContinuationEnd();
+}
+
+void FramePartsCollectorListener::OnPadLength(size_t pad_length) {
+  HTTP2_VLOG(1) << "OnPadLength: " << pad_length;
+  CurrentFrame()->OnPadLength(pad_length);
+}
+
+void FramePartsCollectorListener::OnPadding(const char* padding,
+                                            size_t skipped_length) {
+  HTTP2_VLOG(1) << "OnPadding: " << skipped_length;
+  CurrentFrame()->OnPadding(padding, skipped_length);
+}
+
+void FramePartsCollectorListener::OnRstStream(const Http2FrameHeader& header,
+                                              Http2ErrorCode error_code) {
+  HTTP2_VLOG(1) << "OnRstStream: " << header << "; error_code=" << error_code;
+  StartAndEndFrame(header)->OnRstStream(header, error_code);
+}
+
+void FramePartsCollectorListener::OnSettingsStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
+  EXPECT_EQ(Http2FrameType::SETTINGS, header.type) << header;
+  EXPECT_EQ(Http2FrameFlag(), header.flags) << header;
+  StartFrame(header)->OnSettingsStart(header);
+}
+
+void FramePartsCollectorListener::OnSetting(
+    const Http2SettingFields& setting_fields) {
+  HTTP2_VLOG(1) << "Http2SettingFields: setting_fields=" << setting_fields;
+  CurrentFrame()->OnSetting(setting_fields);
+}
+
+void FramePartsCollectorListener::OnSettingsEnd() {
+  HTTP2_VLOG(1) << "OnSettingsEnd";
+  EndFrame()->OnSettingsEnd();
+}
+
+void FramePartsCollectorListener::OnSettingsAck(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
+  StartAndEndFrame(header)->OnSettingsAck(header);
+}
+
+void FramePartsCollectorListener::OnPushPromiseStart(
+    const Http2FrameHeader& header,
+    const Http2PushPromiseFields& promise,
+    size_t total_padding_length) {
+  HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
+                << "  promise: " << promise
+                << "  total_padding_length: " << total_padding_length;
+  EXPECT_EQ(Http2FrameType::PUSH_PROMISE, header.type);
+  StartFrame(header)->OnPushPromiseStart(header, promise, total_padding_length);
+}
+
+void FramePartsCollectorListener::OnPushPromiseEnd() {
+  HTTP2_VLOG(1) << "OnPushPromiseEnd";
+  EndFrame()->OnPushPromiseEnd();
+}
+
+void FramePartsCollectorListener::OnPing(const Http2FrameHeader& header,
+                                         const Http2PingFields& ping) {
+  HTTP2_VLOG(1) << "OnPing: " << header << "; " << ping;
+  StartAndEndFrame(header)->OnPing(header, ping);
+}
+
+void FramePartsCollectorListener::OnPingAck(const Http2FrameHeader& header,
+                                            const Http2PingFields& ping) {
+  HTTP2_VLOG(1) << "OnPingAck: " << header << "; " << ping;
+  StartAndEndFrame(header)->OnPingAck(header, ping);
+}
+
+void FramePartsCollectorListener::OnGoAwayStart(
+    const Http2FrameHeader& header,
+    const Http2GoAwayFields& goaway) {
+  HTTP2_VLOG(1) << "OnGoAwayStart header: " << header << "; goaway: " << goaway;
+  StartFrame(header)->OnGoAwayStart(header, goaway);
+}
+
+void FramePartsCollectorListener::OnGoAwayOpaqueData(const char* data,
+                                                     size_t len) {
+  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
+  CurrentFrame()->OnGoAwayOpaqueData(data, len);
+}
+
+void FramePartsCollectorListener::OnGoAwayEnd() {
+  HTTP2_VLOG(1) << "OnGoAwayEnd";
+  EndFrame()->OnGoAwayEnd();
+}
+
+void FramePartsCollectorListener::OnWindowUpdate(
+    const Http2FrameHeader& header,
+    uint32_t window_size_increment) {
+  HTTP2_VLOG(1) << "OnWindowUpdate: " << header
+                << "; window_size_increment=" << window_size_increment;
+  EXPECT_EQ(Http2FrameType::WINDOW_UPDATE, header.type);
+  StartAndEndFrame(header)->OnWindowUpdate(header, window_size_increment);
+}
+
+void FramePartsCollectorListener::OnAltSvcStart(const Http2FrameHeader& header,
+                                                size_t origin_length,
+                                                size_t value_length) {
+  HTTP2_VLOG(1) << "OnAltSvcStart header: " << header
+                << "; origin_length=" << origin_length
+                << "; value_length=" << value_length;
+  StartFrame(header)->OnAltSvcStart(header, origin_length, value_length);
+}
+
+void FramePartsCollectorListener::OnAltSvcOriginData(const char* data,
+                                                     size_t len) {
+  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
+  CurrentFrame()->OnAltSvcOriginData(data, len);
+}
+
+void FramePartsCollectorListener::OnAltSvcValueData(const char* data,
+                                                    size_t len) {
+  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
+  CurrentFrame()->OnAltSvcValueData(data, len);
+}
+
+void FramePartsCollectorListener::OnAltSvcEnd() {
+  HTTP2_VLOG(1) << "OnAltSvcEnd";
+  EndFrame()->OnAltSvcEnd();
+}
+
+void FramePartsCollectorListener::OnPriorityUpdateStart(
+    const Http2FrameHeader& header,
+    const Http2PriorityUpdateFields& priority_update) {
+  HTTP2_VLOG(1) << "OnPriorityUpdateStart header: " << header
+                << "; priority_update=" << priority_update;
+  StartFrame(header)->OnPriorityUpdateStart(header, priority_update);
+}
+
+void FramePartsCollectorListener::OnPriorityUpdatePayload(const char* data,
+                                                          size_t len) {
+  HTTP2_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
+  CurrentFrame()->OnPriorityUpdatePayload(data, len);
+}
+
+void FramePartsCollectorListener::OnPriorityUpdateEnd() {
+  HTTP2_VLOG(1) << "OnPriorityUpdateEnd";
+  EndFrame()->OnPriorityUpdateEnd();
+}
+
+void FramePartsCollectorListener::OnUnknownStart(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
+  StartFrame(header)->OnUnknownStart(header);
+}
+
+void FramePartsCollectorListener::OnUnknownPayload(const char* data,
+                                                   size_t len) {
+  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
+  CurrentFrame()->OnUnknownPayload(data, len);
+}
+
+void FramePartsCollectorListener::OnUnknownEnd() {
+  HTTP2_VLOG(1) << "OnUnknownEnd";
+  EndFrame()->OnUnknownEnd();
+}
+
+void FramePartsCollectorListener::OnPaddingTooLong(
+    const Http2FrameHeader& header,
+    size_t missing_length) {
+  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
+                << "    missing_length: " << missing_length;
+  EndFrame()->OnPaddingTooLong(header, missing_length);
+}
+
+void FramePartsCollectorListener::OnFrameSizeError(
+    const Http2FrameHeader& header) {
+  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
+  FrameError(header)->OnFrameSizeError(header);
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/test_tools/frame_parts_collector_listener.h b/quiche/http2/test_tools/frame_parts_collector_listener.h
new file mode 100644
index 0000000..c8be4a5
--- /dev/null
+++ b/quiche/http2/test_tools/frame_parts_collector_listener.h
@@ -0,0 +1,90 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_LISTENER_H_
+#define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_LISTENER_H_
+
+// FramePartsCollectorListener extends FramePartsCollector with an
+// implementation of every method of Http2FrameDecoderListener; it is
+// essentially the union of all the Listener classes in the tests of the
+// payload decoders (i.e. in ./payload_decoders/*_test.cc files), with the
+// addition of the OnFrameHeader method.
+// FramePartsCollectorListener supports tests of Http2FrameDecoder.
+
+#include <stddef.h>
+
+#include <cstdint>
+
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/http2/test_tools/frame_parts_collector.h"
+
+namespace http2 {
+namespace test {
+
+class FramePartsCollectorListener : public FramePartsCollector {
+ public:
+  FramePartsCollectorListener() {}
+  ~FramePartsCollectorListener() override {}
+
+  // TODO(jamessynge): Remove OnFrameHeader once done with supporting
+  // SpdyFramer's exact states.
+  bool OnFrameHeader(const Http2FrameHeader& header) override;
+  void OnDataStart(const Http2FrameHeader& header) override;
+  void OnDataPayload(const char* data, size_t len) override;
+  void OnDataEnd() override;
+  void OnHeadersStart(const Http2FrameHeader& header) override;
+  void OnHeadersPriority(const Http2PriorityFields& priority) override;
+  void OnHpackFragment(const char* data, size_t len) override;
+  void OnHeadersEnd() override;
+  void OnPriorityFrame(const Http2FrameHeader& header,
+                       const Http2PriorityFields& priority_fields) override;
+  void OnContinuationStart(const Http2FrameHeader& header) override;
+  void OnContinuationEnd() override;
+  void OnPadLength(size_t pad_length) override;
+  void OnPadding(const char* padding, size_t skipped_length) override;
+  void OnRstStream(const Http2FrameHeader& header,
+                   Http2ErrorCode error_code) override;
+  void OnSettingsStart(const Http2FrameHeader& header) override;
+  void OnSetting(const Http2SettingFields& setting_fields) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck(const Http2FrameHeader& header) override;
+  void OnPushPromiseStart(const Http2FrameHeader& header,
+                          const Http2PushPromiseFields& promise,
+                          size_t total_padding_length) override;
+  void OnPushPromiseEnd() override;
+  void OnPing(const Http2FrameHeader& header,
+              const Http2PingFields& ping) override;
+  void OnPingAck(const Http2FrameHeader& header,
+                 const Http2PingFields& ping) override;
+  void OnGoAwayStart(const Http2FrameHeader& header,
+                     const Http2GoAwayFields& goaway) override;
+  void OnGoAwayOpaqueData(const char* data, size_t len) override;
+  void OnGoAwayEnd() override;
+  void OnWindowUpdate(const Http2FrameHeader& header,
+                      uint32_t window_size_increment) override;
+  void OnAltSvcStart(const Http2FrameHeader& header,
+                     size_t origin_length,
+                     size_t value_length) override;
+  void OnAltSvcOriginData(const char* data, size_t len) override;
+  void OnAltSvcValueData(const char* data, size_t len) override;
+  void OnAltSvcEnd() override;
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) override;
+  void OnPriorityUpdatePayload(const char* data, size_t len) override;
+  void OnPriorityUpdateEnd() override;
+  void OnUnknownStart(const Http2FrameHeader& header) override;
+  void OnUnknownPayload(const char* data, size_t len) override;
+  void OnUnknownEnd() override;
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override;
+  void OnFrameSizeError(const Http2FrameHeader& header) override;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_COLLECTOR_LISTENER_H_
diff --git a/quiche/http2/test_tools/http2_random.cc b/quiche/http2/test_tools/http2_random.cc
new file mode 100644
index 0000000..b519eb3
--- /dev/null
+++ b/quiche/http2/test_tools/http2_random.cc
@@ -0,0 +1,73 @@
+#include "quiche/http2/test_tools/http2_random.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "third_party/boringssl/src/include/openssl/chacha.h"
+#include "third_party/boringssl/src/include/openssl/rand.h"
+
+static const uint8_t kZeroNonce[12] = {0};
+
+namespace http2 {
+namespace test {
+
+Http2Random::Http2Random() {
+  RAND_bytes(key_, sizeof(key_));
+
+  HTTP2_LOG(INFO) << "Initialized test RNG with the following key: " << Key();
+}
+
+Http2Random::Http2Random(absl::string_view key) {
+  std::string decoded_key = absl::HexStringToBytes(key);
+  QUICHE_CHECK_EQ(sizeof(key_), decoded_key.size());
+  memcpy(key_, decoded_key.data(), sizeof(key_));
+}
+
+std::string Http2Random::Key() const {
+  return absl::BytesToHexString(
+      absl::string_view(reinterpret_cast<const char*>(key_), sizeof(key_)));
+}
+
+void Http2Random::FillRandom(void* buffer, size_t buffer_size) {
+  memset(buffer, 0, buffer_size);
+  uint8_t* buffer_u8 = reinterpret_cast<uint8_t*>(buffer);
+  CRYPTO_chacha_20(buffer_u8, buffer_u8, buffer_size, key_, kZeroNonce,
+                   counter_++);
+}
+
+std::string Http2Random::RandString(int length) {
+  std::string result;
+  result.resize(length);
+  FillRandom(&result[0], length);
+  return result;
+}
+
+uint64_t Http2Random::Rand64() {
+  union {
+    uint64_t number;
+    uint8_t bytes[sizeof(uint64_t)];
+  } result;
+  FillRandom(result.bytes, sizeof(result.bytes));
+  return result.number;
+}
+
+double Http2Random::RandDouble() {
+  union {
+    double f;
+    uint64_t i;
+  } value;
+  value.i = (1023ull << 52ull) | (Rand64() & 0xfffffffffffffu);
+  return value.f - 1.0;
+}
+
+std::string Http2Random::RandStringWithAlphabet(int length,
+                                                absl::string_view alphabet) {
+  std::string result;
+  result.resize(length);
+  for (int i = 0; i < length; i++) {
+    result[i] = alphabet[Uniform(alphabet.size())];
+  }
+  return result;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/http2/test_tools/http2_random.h b/quiche/http2/test_tools/http2_random.h
similarity index 100%
rename from http2/test_tools/http2_random.h
rename to quiche/http2/test_tools/http2_random.h
diff --git a/quiche/http2/test_tools/http2_random_test.cc b/quiche/http2/test_tools/http2_random_test.cc
new file mode 100644
index 0000000..2cf5ba7
--- /dev/null
+++ b/quiche/http2/test_tools/http2_random_test.cc
@@ -0,0 +1,93 @@
+#include "quiche/http2/test_tools/http2_random.h"
+
+#include <set>
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+namespace {
+
+TEST(Http2RandomTest, ProducesDifferentNumbers) {
+  Http2Random random;
+  uint64_t value1 = random.Rand64();
+  uint64_t value2 = random.Rand64();
+  uint64_t value3 = random.Rand64();
+
+  EXPECT_NE(value1, value2);
+  EXPECT_NE(value2, value3);
+  EXPECT_NE(value3, value1);
+}
+
+TEST(Http2RandomTest, StartsWithDifferentKeys) {
+  Http2Random random1;
+  Http2Random random2;
+
+  EXPECT_NE(random1.Key(), random2.Key());
+  EXPECT_NE(random1.Rand64(), random2.Rand64());
+  EXPECT_NE(random1.Rand64(), random2.Rand64());
+  EXPECT_NE(random1.Rand64(), random2.Rand64());
+}
+
+TEST(Http2RandomTest, ReproducibleRandom) {
+  Http2Random random;
+  uint64_t value1 = random.Rand64();
+  uint64_t value2 = random.Rand64();
+
+  Http2Random clone_random(random.Key());
+  EXPECT_EQ(clone_random.Key(), random.Key());
+  EXPECT_EQ(value1, clone_random.Rand64());
+  EXPECT_EQ(value2, clone_random.Rand64());
+}
+
+TEST(Http2RandomTest, STLShuffle) {
+  Http2Random random;
+  const std::string original = "abcdefghijklmonpqrsuvwxyz";
+
+  std::string shuffled = original;
+  std::shuffle(shuffled.begin(), shuffled.end(), random);
+  EXPECT_NE(original, shuffled);
+}
+
+TEST(Http2RandomTest, RandFloat) {
+  Http2Random random;
+  for (int i = 0; i < 10000; i++) {
+    float value = random.RandFloat();
+    ASSERT_GE(value, 0.f);
+    ASSERT_LE(value, 1.f);
+  }
+}
+
+TEST(Http2RandomTest, RandStringWithAlphabet) {
+  Http2Random random;
+  std::string str = random.RandStringWithAlphabet(1000, "xyz");
+  EXPECT_EQ(1000u, str.size());
+
+  std::set<char> characters(str.begin(), str.end());
+  EXPECT_THAT(characters, testing::ElementsAre('x', 'y', 'z'));
+}
+
+TEST(Http2RandomTest, SkewedLow) {
+  Http2Random random;
+  constexpr size_t kMax = 1234;
+  for (int i = 0; i < 10000; i++) {
+    size_t value = random.RandomSizeSkewedLow(kMax);
+    ASSERT_GE(value, 0u);
+    ASSERT_LE(value, kMax);
+  }
+}
+
+// Checks that SkewedLow() generates full range.  This is required, since in
+// some unit tests would infinitely loop.
+TEST(Http2RandomTest, SkewedLowFullRange) {
+  Http2Random random;
+  std::set<size_t> values;
+  for (int i = 0; i < 1000; i++) {
+    values.insert(random.RandomSizeSkewedLow(3));
+  }
+  EXPECT_THAT(values, testing::ElementsAre(0, 1, 2, 3));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/tools/http2_frame_builder.cc b/quiche/http2/tools/http2_frame_builder.cc
new file mode 100644
index 0000000..9fae37f
--- /dev/null
+++ b/quiche/http2/tools/http2_frame_builder.cc
@@ -0,0 +1,185 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/tools/http2_frame_builder.h"
+
+#ifdef WIN32
+#include <winsock2.h>  // for htonl() functions
+#else
+#include <arpa/inet.h>
+#include <netinet/in.h>  // for htonl, htons
+#endif
+
+#include "absl/strings/str_cat.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+Http2FrameBuilder::Http2FrameBuilder(Http2FrameType type,
+                                     uint8_t flags,
+                                     uint32_t stream_id) {
+  AppendUInt24(0);  // Frame payload length, unknown so far.
+  Append(type);
+  AppendUInt8(flags);
+  AppendUInt31(stream_id);
+}
+
+Http2FrameBuilder::Http2FrameBuilder(const Http2FrameHeader& v) {
+  Append(v);
+}
+
+void Http2FrameBuilder::Append(absl::string_view s) {
+  absl::StrAppend(&buffer_, s);
+}
+
+void Http2FrameBuilder::AppendBytes(const void* data, uint32_t num_bytes) {
+  Append(absl::string_view(static_cast<const char*>(data), num_bytes));
+}
+
+void Http2FrameBuilder::AppendZeroes(size_t num_zero_bytes) {
+  char zero = 0;
+  buffer_.append(num_zero_bytes, zero);
+}
+
+void Http2FrameBuilder::AppendUInt8(uint8_t value) {
+  AppendBytes(&value, 1);
+}
+
+void Http2FrameBuilder::AppendUInt16(uint16_t value) {
+  value = htons(value);
+  AppendBytes(&value, 2);
+}
+
+void Http2FrameBuilder::AppendUInt24(uint32_t value) {
+  // Doesn't make sense to try to append a larger value, as that doesn't
+  // simulate something an encoder could do (i.e. the other 8 bits simply aren't
+  // there to be occupied).
+  EXPECT_EQ(value, value & 0xffffff);
+  value = htonl(value);
+  AppendBytes(reinterpret_cast<char*>(&value) + 1, 3);
+}
+
+void Http2FrameBuilder::AppendUInt31(uint32_t value) {
+  // If you want to test the high-bit being set, call AppendUInt32 instead.
+  uint32_t tmp = value & StreamIdMask();
+  EXPECT_EQ(value, value & StreamIdMask())
+      << "High-bit of uint32_t should be clear.";
+  value = htonl(tmp);
+  AppendBytes(&value, 4);
+}
+
+void Http2FrameBuilder::AppendUInt32(uint32_t value) {
+  value = htonl(value);
+  AppendBytes(&value, sizeof(value));
+}
+
+void Http2FrameBuilder::Append(Http2ErrorCode error_code) {
+  AppendUInt32(static_cast<uint32_t>(error_code));
+}
+
+void Http2FrameBuilder::Append(Http2FrameType type) {
+  AppendUInt8(static_cast<uint8_t>(type));
+}
+
+void Http2FrameBuilder::Append(Http2SettingsParameter parameter) {
+  AppendUInt16(static_cast<uint16_t>(parameter));
+}
+
+void Http2FrameBuilder::Append(const Http2FrameHeader& v) {
+  AppendUInt24(v.payload_length);
+  Append(v.type);
+  AppendUInt8(v.flags);
+  AppendUInt31(v.stream_id);
+}
+
+void Http2FrameBuilder::Append(const Http2PriorityFields& v) {
+  // The EXCLUSIVE flag is the high-bit of the 32-bit stream dependency field.
+  uint32_t tmp = v.stream_dependency & StreamIdMask();
+  EXPECT_EQ(tmp, v.stream_dependency);
+  if (v.is_exclusive) {
+    tmp |= 0x80000000;
+  }
+  AppendUInt32(tmp);
+
+  // The PRIORITY frame's weight field is logically in the range [1, 256],
+  // but is encoded as a byte in the range [0, 255].
+  ASSERT_LE(1u, v.weight);
+  ASSERT_LE(v.weight, 256u);
+  AppendUInt8(v.weight - 1);
+}
+
+void Http2FrameBuilder::Append(const Http2RstStreamFields& v) {
+  Append(v.error_code);
+}
+
+void Http2FrameBuilder::Append(const Http2SettingFields& v) {
+  Append(v.parameter);
+  AppendUInt32(v.value);
+}
+
+void Http2FrameBuilder::Append(const Http2PushPromiseFields& v) {
+  AppendUInt31(v.promised_stream_id);
+}
+
+void Http2FrameBuilder::Append(const Http2PingFields& v) {
+  AppendBytes(v.opaque_bytes, sizeof Http2PingFields::opaque_bytes);
+}
+
+void Http2FrameBuilder::Append(const Http2GoAwayFields& v) {
+  AppendUInt31(v.last_stream_id);
+  Append(v.error_code);
+}
+
+void Http2FrameBuilder::Append(const Http2WindowUpdateFields& v) {
+  EXPECT_NE(0u, v.window_size_increment) << "Increment must be non-zero.";
+  AppendUInt31(v.window_size_increment);
+}
+
+void Http2FrameBuilder::Append(const Http2AltSvcFields& v) {
+  AppendUInt16(v.origin_length);
+}
+
+void Http2FrameBuilder::Append(const Http2PriorityUpdateFields& v) {
+  AppendUInt31(v.prioritized_stream_id);
+}
+
+// Methods for changing existing buffer contents.
+
+void Http2FrameBuilder::WriteAt(absl::string_view s, size_t offset) {
+  ASSERT_LE(offset, buffer_.size());
+  size_t len = offset + s.size();
+  if (len > buffer_.size()) {
+    buffer_.resize(len);
+  }
+  for (size_t ndx = 0; ndx < s.size(); ++ndx) {
+    buffer_[offset + ndx] = s[ndx];
+  }
+}
+
+void Http2FrameBuilder::WriteBytesAt(const void* data,
+                                     uint32_t num_bytes,
+                                     size_t offset) {
+  WriteAt(absl::string_view(static_cast<const char*>(data), num_bytes), offset);
+}
+
+void Http2FrameBuilder::WriteUInt24At(uint32_t value, size_t offset) {
+  ASSERT_LT(value, static_cast<uint32_t>(1 << 24));
+  value = htonl(value);
+  WriteBytesAt(reinterpret_cast<char*>(&value) + 1, sizeof(value) - 1, offset);
+}
+
+void Http2FrameBuilder::SetPayloadLength(uint32_t payload_length) {
+  WriteUInt24At(payload_length, 0);
+}
+
+size_t Http2FrameBuilder::SetPayloadLength() {
+  EXPECT_GE(size(), Http2FrameHeader::EncodedSize());
+  uint32_t payload_length = size() - Http2FrameHeader::EncodedSize();
+  SetPayloadLength(payload_length);
+  return payload_length;
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/tools/http2_frame_builder.h b/quiche/http2/tools/http2_frame_builder.h
new file mode 100644
index 0000000..e0682dc
--- /dev/null
+++ b/quiche/http2/tools/http2_frame_builder.h
@@ -0,0 +1,102 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_TOOLS_HTTP2_FRAME_BUILDER_H_
+#define QUICHE_HTTP2_TOOLS_HTTP2_FRAME_BUILDER_H_
+
+// Http2FrameBuilder builds wire-format HTTP/2 frames (or fragments thereof)
+// from components.
+//
+// For now, this is only intended for use in tests, and thus has EXPECT* in the
+// code. If desired to use it in an encoder, it will need optimization work,
+// especially w.r.t memory mgmt, and the EXPECT* will need to be removed or
+// replaced with QUICHE_DCHECKs.
+
+#include <stddef.h>  // for size_t
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+
+namespace http2 {
+namespace test {
+
+class Http2FrameBuilder {
+ public:
+  Http2FrameBuilder(Http2FrameType type, uint8_t flags, uint32_t stream_id);
+  explicit Http2FrameBuilder(const Http2FrameHeader& v);
+  Http2FrameBuilder() {}
+  ~Http2FrameBuilder() {}
+
+  size_t size() const { return buffer_.size(); }
+  const std::string& buffer() const { return buffer_; }
+
+  //----------------------------------------------------------------------------
+  // Methods for appending to the end of the buffer.
+
+  // Append a sequence of bytes from various sources.
+  void Append(absl::string_view s);
+  void AppendBytes(const void* data, uint32_t num_bytes);
+
+  // Append an array of type T[N] to the string. Intended for tests with arrays
+  // initialized from literals, such as:
+  //    const char kData[] = {0x12, 0x23, ...};
+  //    builder.AppendBytes(kData);
+  template <typename T, size_t N>
+  void AppendBytes(T (&buf)[N]) {
+    AppendBytes(buf, N * sizeof(buf[0]));
+  }
+
+  // Support for appending padding. Does not read or write the Pad Length field.
+  void AppendZeroes(size_t num_zero_bytes);
+
+  // Append various sizes of unsigned integers.
+  void AppendUInt8(uint8_t value);
+  void AppendUInt16(uint16_t value);
+  void AppendUInt24(uint32_t value);
+  void AppendUInt31(uint32_t value);
+  void AppendUInt32(uint32_t value);
+
+  // Append various enums.
+  void Append(Http2ErrorCode error_code);
+  void Append(Http2FrameType type);
+  void Append(Http2SettingsParameter parameter);
+
+  // Append various structures.
+  void Append(const Http2FrameHeader& v);
+  void Append(const Http2PriorityFields& v);
+  void Append(const Http2RstStreamFields& v);
+  void Append(const Http2SettingFields& v);
+  void Append(const Http2PushPromiseFields& v);
+  void Append(const Http2PingFields& v);
+  void Append(const Http2GoAwayFields& v);
+  void Append(const Http2WindowUpdateFields& v);
+  void Append(const Http2AltSvcFields& v);
+  void Append(const Http2PriorityUpdateFields& v);
+
+  // Methods for changing existing buffer contents (mostly focused on updating
+  // the payload length).
+
+  void WriteAt(absl::string_view s, size_t offset);
+  void WriteBytesAt(const void* data, uint32_t num_bytes, size_t offset);
+  void WriteUInt24At(uint32_t value, size_t offset);
+
+  // Set the payload length to the specified size.
+  void SetPayloadLength(uint32_t payload_length);
+
+  // Sets the payload length to the size of the buffer minus the size of
+  // the frame header.
+  size_t SetPayloadLength();
+
+ private:
+  std::string buffer_;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_TOOLS_HTTP2_FRAME_BUILDER_H_
diff --git a/quiche/http2/tools/random_decoder_test.cc b/quiche/http2/tools/random_decoder_test.cc
new file mode 100644
index 0000000..6b55db8
--- /dev/null
+++ b/quiche/http2/tools/random_decoder_test.cc
@@ -0,0 +1,167 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/tools/random_decoder_test.h"
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using ::testing::AssertionResult;
+
+namespace http2 {
+namespace test {
+
+RandomDecoderTest::RandomDecoderTest() = default;
+
+bool RandomDecoderTest::StopDecodeOnDone() {
+  return stop_decode_on_done_;
+}
+
+DecodeStatus RandomDecoderTest::DecodeSegments(DecodeBuffer* original,
+                                               const SelectSize& select_size) {
+  DecodeStatus status = DecodeStatus::kDecodeInProgress;
+  bool first = true;
+  HTTP2_VLOG(2) << "DecodeSegments: input size=" << original->Remaining();
+  while (first || original->HasData()) {
+    size_t remaining = original->Remaining();
+    size_t size =
+        std::min(remaining, select_size(first, original->Offset(), remaining));
+    DecodeBuffer db(original->cursor(), size);
+    HTTP2_VLOG(2) << "Decoding " << size << " bytes of " << remaining
+                  << " remaining";
+    if (first) {
+      first = false;
+      status = StartDecoding(&db);
+    } else {
+      status = ResumeDecoding(&db);
+    }
+    // A decoder MUST consume some input (if any is available), else we could
+    // get stuck in infinite loops.
+    if (db.Offset() == 0 && db.HasData() &&
+        status != DecodeStatus::kDecodeError) {
+      ADD_FAILURE() << "Decoder didn't make any progress; db.FullSize="
+                    << db.FullSize()
+                    << "   original.Offset=" << original->Offset();
+      return DecodeStatus::kDecodeError;
+    }
+    original->AdvanceCursor(db.Offset());
+    switch (status) {
+      case DecodeStatus::kDecodeDone:
+        if (original->Empty() || StopDecodeOnDone()) {
+          return DecodeStatus::kDecodeDone;
+        }
+        continue;
+      case DecodeStatus::kDecodeInProgress:
+        continue;
+      case DecodeStatus::kDecodeError:
+        return DecodeStatus::kDecodeError;
+    }
+  }
+  return status;
+}
+
+// Decode |original| multiple times, with different segmentations, validating
+// after each decode, returning on the first failure.
+AssertionResult RandomDecoderTest::DecodeAndValidateSeveralWays(
+    DecodeBuffer* original,
+    bool return_non_zero_on_first,
+    const Validator& validator) {
+  const uint32_t original_remaining = original->Remaining();
+  HTTP2_VLOG(1) << "DecodeAndValidateSeveralWays - Start, remaining = "
+                << original_remaining;
+  uint32_t first_consumed;
+  {
+    // Fast decode (no stopping unless decoder does so).
+    DecodeBuffer input(original->cursor(), original_remaining);
+    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectRemaining";
+    VERIFY_SUCCESS(
+        DecodeSegmentsAndValidate(&input, SelectRemaining(), validator))
+        << "\nFailed with SelectRemaining; input.Offset=" << input.Offset()
+        << "; input.Remaining=" << input.Remaining();
+    first_consumed = input.Offset();
+  }
+  if (original_remaining <= 30) {
+    // Decode again, one byte at a time.
+    DecodeBuffer input(original->cursor(), original_remaining);
+    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectOne";
+    VERIFY_SUCCESS(DecodeSegmentsAndValidate(&input, SelectOne(), validator))
+        << "\nFailed with SelectOne; input.Offset=" << input.Offset()
+        << "; input.Remaining=" << input.Remaining();
+    VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectOne";
+  }
+  if (original_remaining <= 20) {
+    // Decode again, one or zero bytes at a time.
+    DecodeBuffer input(original->cursor(), original_remaining);
+    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectZeroAndOne";
+    VERIFY_SUCCESS(DecodeSegmentsAndValidate(
+        &input, SelectZeroAndOne(return_non_zero_on_first), validator))
+        << "\nFailed with SelectZeroAndOne";
+    VERIFY_EQ(first_consumed, input.Offset())
+        << "\nFailed with SelectZeroAndOne; input.Offset=" << input.Offset()
+        << "; input.Remaining=" << input.Remaining();
+  }
+  {
+    // Decode again, with randomly selected segment sizes.
+    DecodeBuffer input(original->cursor(), original_remaining);
+    HTTP2_VLOG(2) << "DecodeSegmentsAndValidate with SelectRandom";
+    VERIFY_SUCCESS(DecodeSegmentsAndValidate(
+        &input, SelectRandom(return_non_zero_on_first), validator))
+        << "\nFailed with SelectRandom; input.Offset=" << input.Offset()
+        << "; input.Remaining=" << input.Remaining();
+    VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectRandom";
+  }
+  VERIFY_EQ(original_remaining, original->Remaining());
+  original->AdvanceCursor(first_consumed);
+  HTTP2_VLOG(1) << "DecodeAndValidateSeveralWays - SUCCESS";
+  return ::testing::AssertionSuccess();
+}
+
+// static
+RandomDecoderTest::SelectSize RandomDecoderTest::SelectZeroAndOne(
+    bool return_non_zero_on_first) {
+  std::shared_ptr<bool> zero_next(new bool);
+  *zero_next = !return_non_zero_on_first;
+  return [zero_next](bool /*first*/, size_t /*offset*/,
+                     size_t /*remaining*/) -> size_t {
+    if (*zero_next) {
+      *zero_next = false;
+      return 0;
+    } else {
+      *zero_next = true;
+      return 1;
+    }
+  };
+}
+
+RandomDecoderTest::SelectSize RandomDecoderTest::SelectRandom(
+    bool return_non_zero_on_first) {
+  return [this, return_non_zero_on_first](bool first, size_t /*offset*/,
+                                          size_t remaining) -> size_t {
+    uint32_t r = random_.Rand32();
+    if (first && return_non_zero_on_first) {
+      QUICHE_CHECK_LT(0u, remaining);
+      if (remaining == 1) {
+        return 1;
+      }
+      return 1 + (r % remaining);  // size in range [1, remaining).
+    }
+    return r % (remaining + 1);  // size in range [0, remaining].
+  };
+}
+
+uint32_t RandomDecoderTest::RandStreamId() {
+  return random_.Rand32() & StreamIdMask();
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/tools/random_decoder_test.h b/quiche/http2/tools/random_decoder_test.h
new file mode 100644
index 0000000..e6c9b79
--- /dev/null
+++ b/quiche/http2/tools/random_decoder_test.h
@@ -0,0 +1,257 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
+#define QUICHE_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
+
+// RandomDecoderTest is a base class for tests of decoding various kinds
+// of HTTP/2 and HPACK encodings.
+
+// TODO(jamessynge): Move more methods into .cc file.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <type_traits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/platform/api/http2_logging.h"
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace http2 {
+namespace test {
+
+// Some helpers.
+
+template <typename T, size_t N>
+absl::string_view ToStringPiece(T (&data)[N]) {
+  return absl::string_view(reinterpret_cast<const char*>(data), N * sizeof(T));
+}
+
+// Overwrite the enum with some random value, probably not a valid value for
+// the enum type, but which fits into its storage.
+template <typename T,
+          typename E = typename std::enable_if<std::is_enum<T>::value>::type>
+void CorruptEnum(T* out, Http2Random* rng) {
+  // Per cppreference.com, if the destination type of a static_cast is
+  // smaller than the source type (i.e. type of r and uint32 below), the
+  // resulting value is the smallest unsigned value equal to the source value
+  // modulo 2^n, where n is the number of bits used to represent the
+  // destination type unsigned U.
+  using underlying_type_T = typename std::underlying_type<T>::type;
+  using unsigned_underlying_type_T =
+      typename std::make_unsigned<underlying_type_T>::type;
+  auto r = static_cast<unsigned_underlying_type_T>(rng->Rand32());
+  *out = static_cast<T>(r);
+}
+
+// Base class for tests of the ability to decode a sequence of bytes with
+// various boundaries between the DecodeBuffers provided to the decoder.
+class RandomDecoderTest : public QuicheTest {
+ public:
+  // SelectSize returns the size of the next DecodeBuffer to be passed to the
+  // decoder. Note that RandomDecoderTest allows that size to be zero, though
+  // some decoders can't deal with that on the first byte, hence the |first|
+  // parameter.
+  typedef std::function<size_t(bool first, size_t offset, size_t remaining)>
+      SelectSize;
+
+  // Validator returns an AssertionResult so test can do:
+  // EXPECT_THAT(DecodeAndValidate(..., validator));
+  typedef ::testing::AssertionResult AssertionResult;
+  typedef std::function<AssertionResult(const DecodeBuffer& input,
+                                        DecodeStatus status)>
+      Validator;
+  typedef std::function<AssertionResult()> NoArgValidator;
+
+  RandomDecoderTest();
+
+ protected:
+  // TODO(jamessynge): Modify StartDecoding, etc. to (somehow) return
+  // AssertionResult so that the VERIFY_* methods exported from
+  // gunit_helpers.h can be widely used.
+
+  // Start decoding; call allows sub-class to Reset the decoder, or deal with
+  // the first byte if that is done in a unique fashion.  Might be called with
+  // a zero byte buffer.
+  virtual DecodeStatus StartDecoding(DecodeBuffer* db) = 0;
+
+  // Resume decoding of the input after a prior call to StartDecoding, and
+  // possibly many calls to ResumeDecoding.
+  virtual DecodeStatus ResumeDecoding(DecodeBuffer* db) = 0;
+
+  // Return true if a decode status of kDecodeDone indicates that
+  // decoding should stop.
+  virtual bool StopDecodeOnDone();
+
+  // Decode buffer |original| until we run out of input, or kDecodeDone is
+  // returned by the decoder AND StopDecodeOnDone() returns true. Segments
+  // (i.e. cuts up) the original DecodeBuffer into (potentially) smaller buffers
+  // by calling |select_size| to decide how large each buffer should be.
+  // We do this to test the ability to deal with arbitrary boundaries, as might
+  // happen in transport.
+  // Returns the final DecodeStatus.
+  DecodeStatus DecodeSegments(DecodeBuffer* original,
+                              const SelectSize& select_size);
+
+  // Decode buffer |original| until we run out of input, or kDecodeDone is
+  // returned by the decoder AND StopDecodeOnDone() returns true. Segments
+  // (i.e. cuts up) the original DecodeBuffer into (potentially) smaller buffers
+  // by calling |select_size| to decide how large each buffer should be.
+  // We do this to test the ability to deal with arbitrary boundaries, as might
+  // happen in transport.
+  // Invokes |validator| with the final decode status and the original decode
+  // buffer, with the cursor advanced as far as has been consumed by the decoder
+  // and returns validator's result.
+  ::testing::AssertionResult DecodeSegmentsAndValidate(
+      DecodeBuffer* original,
+      const SelectSize& select_size,
+      const Validator& validator) {
+    DecodeStatus status = DecodeSegments(original, select_size);
+    VERIFY_AND_RETURN_SUCCESS(validator(*original, status));
+  }
+
+  // Returns a SelectSize function for fast decoding, i.e. passing all that
+  // is available to the decoder.
+  static SelectSize SelectRemaining() {
+    return [](bool /*first*/, size_t /*offset*/, size_t remaining) -> size_t {
+      return remaining;
+    };
+  }
+
+  // Returns a SelectSize function for decoding a single byte at a time.
+  static SelectSize SelectOne() {
+    return [](bool /*first*/, size_t /*offset*/,
+              size_t /*remaining*/) -> size_t { return 1; };
+  }
+
+  // Returns a SelectSize function for decoding a single byte at a time, where
+  // zero byte buffers are also allowed. Alternates between zero and one.
+  static SelectSize SelectZeroAndOne(bool return_non_zero_on_first);
+
+  // Returns a SelectSize function for decoding random sized segments.
+  SelectSize SelectRandom(bool return_non_zero_on_first);
+
+  // Decode |original| multiple times, with different segmentations of the
+  // decode buffer, validating after each decode, and confirming that they
+  // each decode the same amount. Returns on the first failure, else returns
+  // success.
+  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* original,
+                                               bool return_non_zero_on_first,
+                                               const Validator& validator);
+
+  static Validator ToValidator(std::nullptr_t) {
+    return [](const DecodeBuffer& /*input*/, DecodeStatus /*status*/) {
+      return ::testing::AssertionSuccess();
+    };
+  }
+
+  static Validator ToValidator(const Validator& validator) {
+    if (validator == nullptr) {
+      return ToValidator(nullptr);
+    }
+    return validator;
+  }
+
+  static Validator ToValidator(const NoArgValidator& validator) {
+    if (validator == nullptr) {
+      return ToValidator(nullptr);
+    }
+    return [validator](const DecodeBuffer& /*input*/, DecodeStatus /*status*/) {
+      return validator();
+    };
+  }
+
+  // Wraps a validator with another validator
+  // that first checks that the DecodeStatus is kDecodeDone and
+  // that the DecodeBuffer is empty.
+  // TODO(jamessynge): Replace this overload with the next, as using this method
+  // usually means that the wrapped function doesn't need to be passed the
+  // DecodeBuffer nor the DecodeStatus.
+  static Validator ValidateDoneAndEmpty(const Validator& wrapped) {
+    return [wrapped](const DecodeBuffer& input,
+                     DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
+      VERIFY_EQ(0u, input.Remaining()) << "\nOffset=" << input.Offset();
+      if (wrapped) {
+        return wrapped(input, status);
+      }
+      return ::testing::AssertionSuccess();
+    };
+  }
+  static Validator ValidateDoneAndEmpty(NoArgValidator wrapped) {
+    return [wrapped](const DecodeBuffer& input,
+                     DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
+      VERIFY_EQ(0u, input.Remaining()) << "\nOffset=" << input.Offset();
+      if (wrapped) {
+        return wrapped();
+      }
+      return ::testing::AssertionSuccess();
+    };
+  }
+  static Validator ValidateDoneAndEmpty() {
+    NoArgValidator validator;
+    return ValidateDoneAndEmpty(validator);
+  }
+
+  // Wraps a validator with another validator
+  // that first checks that the DecodeStatus is kDecodeDone and
+  // that the DecodeBuffer has the expected offset.
+  // TODO(jamessynge): Replace this overload with the next, as using this method
+  // usually means that the wrapped function doesn't need to be passed the
+  // DecodeBuffer nor the DecodeStatus.
+  static Validator ValidateDoneAndOffset(uint32_t offset,
+                                         const Validator& wrapped) {
+    return [wrapped, offset](const DecodeBuffer& input,
+                             DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
+      VERIFY_EQ(offset, input.Offset()) << "\nRemaining=" << input.Remaining();
+      if (wrapped) {
+        return wrapped(input, status);
+      }
+      return ::testing::AssertionSuccess();
+    };
+  }
+  static Validator ValidateDoneAndOffset(uint32_t offset,
+                                         NoArgValidator wrapped) {
+    return [wrapped, offset](const DecodeBuffer& input,
+                             DecodeStatus status) -> AssertionResult {
+      VERIFY_EQ(status, DecodeStatus::kDecodeDone);
+      VERIFY_EQ(offset, input.Offset()) << "\nRemaining=" << input.Remaining();
+      if (wrapped) {
+        return wrapped();
+      }
+      return ::testing::AssertionSuccess();
+    };
+  }
+  static Validator ValidateDoneAndOffset(uint32_t offset) {
+    NoArgValidator validator;
+    return ValidateDoneAndOffset(offset, validator);
+  }
+
+  // Expose |random_| as Http2Random so callers don't have to care about which
+  // sub-class of Http2Random is used, nor can they rely on the specific
+  // sub-class that RandomDecoderTest uses.
+  Http2Random& Random() { return random_; }
+  Http2Random* RandomPtr() { return &random_; }
+
+  uint32_t RandStreamId();
+
+  bool stop_decode_on_done_ = true;
+
+ private:
+  Http2Random random_;
+};
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
diff --git a/quiche/http2/tools/random_util.cc b/quiche/http2/tools/random_util.cc
new file mode 100644
index 0000000..00550b2
--- /dev/null
+++ b/quiche/http2/tools/random_util.cc
@@ -0,0 +1,39 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/http2/tools/random_util.h"
+
+#include <cmath>
+
+namespace http2 {
+namespace test {
+
+// Here "word" means something that starts with a lower-case letter, and has
+// zero or more additional characters that are numbers or lower-case letters.
+std::string GenerateHttp2HeaderName(size_t len, Http2Random* rng) {
+  absl::string_view alpha_lc = "abcdefghijklmnopqrstuvwxyz";
+  // If the name is short, just make it one word.
+  if (len < 8) {
+    return rng->RandStringWithAlphabet(len, alpha_lc);
+  }
+  // If the name is longer, ensure it starts with a word, and after that may
+  // have any character in alphanumdash_lc. 4 is arbitrary, could be as low
+  // as 1.
+  absl::string_view alphanumdash_lc = "abcdefghijklmnopqrstuvwxyz0123456789-";
+  return rng->RandStringWithAlphabet(4, alpha_lc) +
+         rng->RandStringWithAlphabet(len - 4, alphanumdash_lc);
+}
+
+std::string GenerateWebSafeString(size_t len, Http2Random* rng) {
+  static const char* kWebsafe64 =
+      "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
+  return rng->RandStringWithAlphabet(len, kWebsafe64);
+}
+
+std::string GenerateWebSafeString(size_t lo, size_t hi, Http2Random* rng) {
+  return GenerateWebSafeString(rng->UniformInRange(lo, hi), rng);
+}
+
+}  // namespace test
+}  // namespace http2
diff --git a/quiche/http2/tools/random_util.h b/quiche/http2/tools/random_util.h
new file mode 100644
index 0000000..abc404d
--- /dev/null
+++ b/quiche/http2/tools/random_util.h
@@ -0,0 +1,30 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_HTTP2_TOOLS_RANDOM_UTIL_H_
+#define QUICHE_HTTP2_TOOLS_RANDOM_UTIL_H_
+
+#include <stddef.h>
+
+#include <string>
+
+#include "quiche/http2/test_tools/http2_random.h"
+
+namespace http2 {
+namespace test {
+
+// Generate a string with the allowed character set for HTTP/2 / HPACK header
+// names.
+std::string GenerateHttp2HeaderName(size_t len, Http2Random* rng);
+
+// Generate a string with the web-safe string character set of specified len.
+std::string GenerateWebSafeString(size_t len, Http2Random* rng);
+
+// Generate a string with the web-safe string character set of length [lo, hi).
+std::string GenerateWebSafeString(size_t lo, size_t hi, Http2Random* rng);
+
+}  // namespace test
+}  // namespace http2
+
+#endif  // QUICHE_HTTP2_TOOLS_RANDOM_UTIL_H_
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_base.cc b/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
new file mode 100644
index 0000000..0b39823
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
@@ -0,0 +1,181 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+namespace quic {
+
+QuicBatchWriterBase::QuicBatchWriterBase(
+    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer)
+    : write_blocked_(false), batch_buffer_(std::move(batch_buffer)) {}
+
+WriteResult QuicBatchWriterBase::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  const WriteResult result =
+      InternalWritePacket(buffer, buf_len, self_address, peer_address, options);
+
+  if (IsWriteBlockedStatus(result.status)) {
+    write_blocked_ = true;
+  }
+
+  return result;
+}
+
+WriteResult QuicBatchWriterBase::InternalWritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  if (buf_len > kMaxOutgoingPacketSize) {
+    return WriteResult(WRITE_STATUS_MSG_TOO_BIG, EMSGSIZE);
+  }
+
+  ReleaseTime release_time{0, QuicTime::Delta::Zero()};
+  if (SupportsReleaseTime()) {
+    release_time = GetReleaseTime(options);
+    if (release_time.release_time_offset >= QuicTime::Delta::Zero()) {
+      QUIC_SERVER_HISTOGRAM_TIMES(
+          "batch_writer_positive_release_time_offset",
+          release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
+          "Duration from ideal release time to actual "
+          "release time, in microseconds.");
+    } else {
+      QUIC_SERVER_HISTOGRAM_TIMES(
+          "batch_writer_negative_release_time_offset",
+          -release_time.release_time_offset.ToMicroseconds(), 1, 100000, 50,
+          "Duration from actual release time to ideal "
+          "release time, in microseconds.");
+    }
+  }
+
+  const CanBatchResult can_batch_result =
+      CanBatch(buffer, buf_len, self_address, peer_address, options,
+               release_time.actual_release_time);
+
+  bool buffered = false;
+  bool flush = can_batch_result.must_flush;
+
+  if (can_batch_result.can_batch) {
+    QuicBatchWriterBuffer::PushResult push_result =
+        batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
+                                         peer_address, options,
+                                         release_time.actual_release_time);
+    if (push_result.succeeded) {
+      buffered = true;
+      // If there's no space left after the packet is buffered, force a flush.
+      flush = flush || (batch_buffer_->GetNextWriteLocation() == nullptr);
+    } else {
+      // If there's no space without this packet, force a flush.
+      flush = true;
+    }
+  }
+
+  if (!flush) {
+    WriteResult result(WRITE_STATUS_OK, 0);
+    result.send_time_offset = release_time.release_time_offset;
+    return result;
+  }
+
+  size_t num_buffered_packets = buffered_writes().size();
+  const FlushImplResult flush_result = CheckedFlush();
+  WriteResult result = flush_result.write_result;
+  QUIC_DVLOG(1) << "Internally flushed " << flush_result.num_packets_sent
+                << " out of " << num_buffered_packets
+                << " packets. WriteResult=" << result;
+
+  if (result.status != WRITE_STATUS_OK) {
+    if (IsWriteBlockedStatus(result.status)) {
+      return WriteResult(
+          buffered ? WRITE_STATUS_BLOCKED_DATA_BUFFERED : WRITE_STATUS_BLOCKED,
+          result.error_code);
+    }
+
+    // Drop all packets, including the one being written.
+    size_t dropped_packets =
+        buffered ? buffered_writes().size() : buffered_writes().size() + 1;
+
+    batch_buffer().Clear();
+    result.dropped_packets =
+        dropped_packets > std::numeric_limits<uint16_t>::max()
+            ? std::numeric_limits<uint16_t>::max()
+            : static_cast<uint16_t>(dropped_packets);
+    return result;
+  }
+
+  if (!buffered) {
+    QuicBatchWriterBuffer::PushResult push_result =
+        batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
+                                         peer_address, options,
+                                         release_time.actual_release_time);
+    buffered = push_result.succeeded;
+
+    // Since buffered_writes has been emptied, this write must have been
+    // buffered successfully.
+    QUIC_BUG_IF(quic_bug_10826_1, !buffered)
+        << "Failed to push to an empty batch buffer."
+        << "  self_addr:" << self_address.ToString()
+        << ", peer_addr:" << peer_address.ToString() << ", buf_len:" << buf_len;
+  }
+
+  result.send_time_offset = release_time.release_time_offset;
+  return result;
+}
+
+QuicBatchWriterBase::FlushImplResult QuicBatchWriterBase::CheckedFlush() {
+  if (buffered_writes().empty()) {
+    return FlushImplResult{WriteResult(WRITE_STATUS_OK, 0),
+                           /*num_packets_sent=*/0, /*bytes_written=*/0};
+  }
+
+  const FlushImplResult flush_result = FlushImpl();
+
+  // Either flush_result.write_result.status is not WRITE_STATUS_OK, or it is
+  // WRITE_STATUS_OK and batch_buffer is empty.
+  QUICHE_DCHECK(flush_result.write_result.status != WRITE_STATUS_OK ||
+                buffered_writes().empty());
+
+  // Flush should never return WRITE_STATUS_BLOCKED_DATA_BUFFERED.
+  QUICHE_DCHECK(flush_result.write_result.status !=
+                WRITE_STATUS_BLOCKED_DATA_BUFFERED);
+
+  return flush_result;
+}
+
+WriteResult QuicBatchWriterBase::Flush() {
+  size_t num_buffered_packets = buffered_writes().size();
+  FlushImplResult flush_result = CheckedFlush();
+  QUIC_DVLOG(1) << "Externally flushed " << flush_result.num_packets_sent
+                << " out of " << num_buffered_packets
+                << " packets. WriteResult=" << flush_result.write_result;
+
+  if (IsWriteError(flush_result.write_result.status)) {
+    if (buffered_writes().size() > std::numeric_limits<uint16_t>::max()) {
+      flush_result.write_result.dropped_packets =
+          std::numeric_limits<uint16_t>::max();
+    } else {
+      flush_result.write_result.dropped_packets =
+          static_cast<uint16_t>(buffered_writes().size());
+    }
+    // Treat all errors as non-retryable fatal errors. Drop all buffered packets
+    // to avoid sending them and getting the same error again.
+    batch_buffer().Clear();
+  }
+
+  if (flush_result.write_result.status == WRITE_STATUS_BLOCKED) {
+    write_blocked_ = true;
+  }
+  return flush_result.write_result;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_base.h b/quiche/quic/core/batch_writer/quic_batch_writer_base.h
new file mode 100644
index 0000000..fc776c2
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_base.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
+
+#include <cstdint>
+#include "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// QuicBatchWriterBase implements logic common to all derived batch writers,
+// including maintaining write blockage state and a skeleton implemention of
+// WritePacket().
+// A derived batch writer must override the FlushImpl() function to send all
+// buffered writes in a batch. It must also override the CanBatch() function
+// to control whether/when a WritePacket() call should flush.
+class QUIC_EXPORT_PRIVATE QuicBatchWriterBase : public QuicPacketWriter {
+ public:
+  explicit QuicBatchWriterBase(
+      std::unique_ptr<QuicBatchWriterBuffer> batch_buffer);
+
+  // ATTENTION: If this write triggered a flush, and the flush failed, all
+  // buffered packets will be dropped to allow the next write to work. The
+  // number of dropped packets can be found in WriteResult.dropped_packets.
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+  bool IsWriteBlocked() const final { return write_blocked_; }
+
+  void SetWritable() final { write_blocked_ = false; }
+
+  absl::optional<int> MessageTooBigErrorCode() const override {
+    return EMSGSIZE;
+  }
+
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& /*peer_address*/) const final {
+    return kMaxOutgoingPacketSize;
+  }
+
+  bool SupportsReleaseTime() const override { return false; }
+
+  bool IsBatchMode() const final { return true; }
+
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& /*self_address*/,
+      const QuicSocketAddress& /*peer_address*/) final {
+    // No need to explicitly delete QuicBatchWriterBuffer.
+    return {batch_buffer_->GetNextWriteLocation(), nullptr};
+  }
+
+  WriteResult Flush() override;
+
+ protected:
+  const QuicBatchWriterBuffer& batch_buffer() const { return *batch_buffer_; }
+  QuicBatchWriterBuffer& batch_buffer() { return *batch_buffer_; }
+
+  const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
+    return batch_buffer_->buffered_writes();
+  }
+
+  // Given the release delay in |options| and the state of |batch_buffer_|, get
+  // the absolute release time.
+  struct QUIC_NO_EXPORT ReleaseTime {
+    // The actual (absolute) release time.
+    uint64_t actual_release_time = 0;
+    // The difference between |actual_release_time| and ideal release time,
+    // which is (now + |options->release_time_delay|).
+    QuicTime::Delta release_time_offset = QuicTime::Delta::Zero();
+  };
+  virtual ReleaseTime GetReleaseTime(
+      const PerPacketOptions* /*options*/) const {
+    QUICHE_DCHECK(false)
+        << "Should not be called since release time is unsupported.";
+    return ReleaseTime{0, QuicTime::Delta::Zero()};
+  }
+
+  struct QUIC_EXPORT_PRIVATE CanBatchResult {
+    CanBatchResult(bool can_batch, bool must_flush)
+        : can_batch(can_batch), must_flush(must_flush) {}
+    // Whether this write can be batched with existing buffered writes.
+    bool can_batch;
+    // If |can_batch|, whether the caller must flush after this packet is
+    // buffered.
+    // Always true if not |can_batch|.
+    bool must_flush;
+  };
+
+  // Given the existing buffered writes(in buffered_writes()), whether a new
+  // write(in the arguments) can be batched.
+  virtual CanBatchResult CanBatch(const char* buffer,
+                                  size_t buf_len,
+                                  const QuicIpAddress& self_address,
+                                  const QuicSocketAddress& peer_address,
+                                  const PerPacketOptions* options,
+                                  uint64_t release_time) const = 0;
+
+  struct QUIC_EXPORT_PRIVATE FlushImplResult {
+    // The return value of the Flush() interface, which is:
+    // - WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered writes
+    //   were sent successfully.
+    // - WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR, if the batch write is
+    //   blocked or returned an error while sending. If a portion of buffered
+    //   writes were sent successfully, |FlushImplResult.num_packets_sent| and
+    //   |FlushImplResult.bytes_written| contain the number of successfully sent
+    //   packets and their total bytes.
+    WriteResult write_result;
+    int num_packets_sent;
+    // If write_result.status == WRITE_STATUS_OK, |bytes_written| will be equal
+    // to write_result.bytes_written. Otherwise |bytes_written| will be the
+    // number of bytes written before WRITE_BLOCK or WRITE_ERROR happened.
+    int bytes_written;
+  };
+
+  // Send all buffered writes(in buffered_writes()) in a batch.
+  // buffered_writes() is guaranteed to be non-empty when this function is
+  // called.
+  virtual FlushImplResult FlushImpl() = 0;
+
+ private:
+  WriteResult InternalWritePacket(const char* buffer,
+                                  size_t buf_len,
+                                  const QuicIpAddress& self_address,
+                                  const QuicSocketAddress& peer_address,
+                                  PerPacketOptions* options);
+
+  // Calls FlushImpl() and check its post condition.
+  FlushImplResult CheckedFlush();
+
+  bool write_blocked_;
+  std::unique_ptr<QuicBatchWriterBuffer> batch_buffer_;
+};
+
+// QuicUdpBatchWriter is a batch writer backed by a UDP socket.
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriter : public QuicBatchWriterBase {
+ public:
+  QuicUdpBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+                     int fd)
+      : QuicBatchWriterBase(std::move(batch_buffer)), fd_(fd) {}
+
+  int fd() const { return fd_; }
+
+ private:
+  const int fd_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
new file mode 100644
index 0000000..1463812
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"
+
+#include <sstream>
+
+namespace quic {
+
+QuicBatchWriterBuffer::QuicBatchWriterBuffer() {
+  memset(buffer_, 0, sizeof(buffer_));
+}
+
+void QuicBatchWriterBuffer::Clear() {
+  buffered_writes_.clear();
+}
+
+std::string QuicBatchWriterBuffer::DebugString() const {
+  std::ostringstream os;
+  os << "{ buffer: " << static_cast<const void*>(buffer_)
+     << " buffer_end: " << static_cast<const void*>(buffer_end())
+     << " buffered_writes_.size(): " << buffered_writes_.size()
+     << " next_write_loc: " << static_cast<const void*>(GetNextWriteLocation())
+     << " SizeInUse: " << SizeInUse() << " }";
+  return os.str();
+}
+
+bool QuicBatchWriterBuffer::Invariants() const {
+  // Buffers in buffered_writes_ should not overlap, and collectively they
+  // should cover a continuous prefix of buffer_.
+  const char* next_buffer = buffer_;
+  for (auto iter = buffered_writes_.begin(); iter != buffered_writes_.end();
+       ++iter) {
+    if ((iter->buffer != next_buffer) ||
+        (iter->buffer + iter->buf_len > buffer_end())) {
+      return false;
+    }
+    next_buffer += iter->buf_len;
+  }
+
+  return static_cast<size_t>(next_buffer - buffer_) == SizeInUse();
+}
+
+char* QuicBatchWriterBuffer::GetNextWriteLocation() const {
+  const char* next_loc =
+      buffered_writes_.empty()
+          ? buffer_
+          : buffered_writes_.back().buffer + buffered_writes_.back().buf_len;
+  if (static_cast<size_t>(buffer_end() - next_loc) < kMaxOutgoingPacketSize) {
+    return nullptr;
+  }
+  return const_cast<char*>(next_loc);
+}
+
+QuicBatchWriterBuffer::PushResult QuicBatchWriterBuffer::PushBufferedWrite(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const PerPacketOptions* options,
+    uint64_t release_time) {
+  QUICHE_DCHECK(Invariants());
+  QUICHE_DCHECK_LE(buf_len, kMaxOutgoingPacketSize);
+
+  PushResult result = {/*succeeded=*/false, /*buffer_copied=*/false};
+  char* next_write_location = GetNextWriteLocation();
+  if (next_write_location == nullptr) {
+    return result;
+  }
+
+  if (buffer != next_write_location) {
+    if (IsExternalBuffer(buffer, buf_len)) {
+      memcpy(next_write_location, buffer, buf_len);
+    } else if (IsInternalBuffer(buffer, buf_len)) {
+      memmove(next_write_location, buffer, buf_len);
+    } else {
+      QUIC_BUG(quic_bug_10831_1)
+          << "Buffer[" << static_cast<const void*>(buffer) << ", "
+          << static_cast<const void*>(buffer + buf_len)
+          << ") overlaps with internal buffer["
+          << static_cast<const void*>(buffer_) << ", "
+          << static_cast<const void*>(buffer_end()) << ")";
+      return result;
+    }
+    result.buffer_copied = true;
+  } else {
+    // In place push, do nothing.
+  }
+  buffered_writes_.emplace_back(
+      next_write_location, buf_len, self_address, peer_address,
+      options ? options->Clone() : std::unique_ptr<PerPacketOptions>(),
+      release_time);
+
+  QUICHE_DCHECK(Invariants());
+
+  result.succeeded = true;
+  return result;
+}
+
+void QuicBatchWriterBuffer::UndoLastPush() {
+  if (!buffered_writes_.empty()) {
+    buffered_writes_.pop_back();
+  }
+}
+
+QuicBatchWriterBuffer::PopResult QuicBatchWriterBuffer::PopBufferedWrite(
+    int32_t num_buffered_writes) {
+  QUICHE_DCHECK(Invariants());
+  QUICHE_DCHECK_GE(num_buffered_writes, 0);
+  QUICHE_DCHECK_LE(static_cast<size_t>(num_buffered_writes),
+                   buffered_writes_.size());
+
+  PopResult result = {/*num_buffers_popped=*/0,
+                      /*moved_remaining_buffers=*/false};
+
+  result.num_buffers_popped = std::max<int32_t>(num_buffered_writes, 0);
+  result.num_buffers_popped =
+      std::min<int32_t>(result.num_buffers_popped, buffered_writes_.size());
+  buffered_writes_.pop_front_n(result.num_buffers_popped);
+
+  if (!buffered_writes_.empty()) {
+    // If not all buffered writes are erased, the remaining ones will not cover
+    // a continuous prefix of buffer_. We'll fix it by moving the remaining
+    // buffers to the beginning of buffer_ and adjust the buffer pointers in all
+    // remaining buffered writes.
+    // This should happen very rarely, about once per write block.
+    result.moved_remaining_buffers = true;
+    const char* buffer_before_move = buffered_writes_.front().buffer;
+    size_t buffer_len_to_move = buffered_writes_.back().buffer +
+                                buffered_writes_.back().buf_len -
+                                buffer_before_move;
+    memmove(buffer_, buffer_before_move, buffer_len_to_move);
+
+    size_t distance_to_move = buffer_before_move - buffer_;
+    for (BufferedWrite& buffered_write : buffered_writes_) {
+      buffered_write.buffer -= distance_to_move;
+    }
+
+    QUICHE_DCHECK_EQ(buffer_, buffered_writes_.front().buffer);
+  }
+  QUICHE_DCHECK(Invariants());
+
+  return result;
+}
+
+size_t QuicBatchWriterBuffer::SizeInUse() const {
+  if (buffered_writes_.empty()) {
+    return 0;
+  }
+
+  return buffered_writes_.back().buffer + buffered_writes_.back().buf_len -
+         buffer_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
new file mode 100644
index 0000000..4cf512b
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
+
+#include "absl/base/optimization.h"
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+// QuicBatchWriterBuffer manages an internal buffer to hold data from multiple
+// packets. Packet data are placed continuously within the internal buffer such
+// that they can be sent by a QuicGsoBatchWriter.
+// This class can also be used by a QuicBatchWriter which uses sendmmsg,
+// although it is not optimized for that use case.
+class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer {
+ public:
+  QuicBatchWriterBuffer();
+
+  // Clear all buffered writes, but leave the internal buffer intact.
+  void Clear();
+
+  char* GetNextWriteLocation() const;
+
+  // Push a buffered write to the back.
+  struct QUIC_EXPORT_PRIVATE PushResult {
+    bool succeeded;
+    // True in one of the following cases:
+    // 1) The packet buffer is external and copied to the internal buffer, or
+    // 2) The packet buffer is from the internal buffer and moved within it.
+    //    This only happens if PopBufferedWrite is called in the middle of a
+    //    in-place push.
+    // Only valid if |succeeded| is true.
+    bool buffer_copied;
+  };
+
+  PushResult PushBufferedWrite(const char* buffer,
+                               size_t buf_len,
+                               const QuicIpAddress& self_address,
+                               const QuicSocketAddress& peer_address,
+                               const PerPacketOptions* options,
+                               uint64_t release_time);
+
+  void UndoLastPush();
+
+  // Pop |num_buffered_writes| buffered writes from the front.
+  // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
+  // before it is used.
+  struct QUIC_EXPORT_PRIVATE PopResult {
+    int32_t num_buffers_popped;
+    // True if after |num_buffers_popped| buffers are popped from front, the
+    // remaining buffers are moved to the beginning of the internal buffer.
+    // This should normally be false.
+    bool moved_remaining_buffers;
+  };
+  PopResult PopBufferedWrite(int32_t num_buffered_writes);
+
+  const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
+    return buffered_writes_;
+  }
+
+  bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
+    return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
+  }
+  bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
+    return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
+  }
+
+  // Number of bytes used in |buffer_|.
+  // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
+  size_t SizeInUse() const;
+
+  // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
+  // size of a GSO packet.
+  static const size_t kBufferSize = 64 * 1024;
+
+  std::string DebugString() const;
+
+ protected:
+  // Whether the invariants of the buffer are upheld. For debug & test only.
+  bool Invariants() const;
+  const char* buffer_end() const { return buffer_ + sizeof(buffer_); }
+  ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize];
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc b/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
new file mode 100644
index 0000000..c3152b2
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
@@ -0,0 +1,282 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QUIC_EXPORT_PRIVATE TestQuicBatchWriterBuffer
+    : public QuicBatchWriterBuffer {
+ public:
+  using QuicBatchWriterBuffer::buffer_;
+  using QuicBatchWriterBuffer::buffered_writes_;
+};
+
+static const size_t kBatchBufferSize = QuicBatchWriterBuffer::kBufferSize;
+
+class QuicBatchWriterBufferTest : public QuicTest {
+ public:
+  QuicBatchWriterBufferTest() { SwitchToNewBuffer(); }
+
+  void SwitchToNewBuffer() {
+    batch_buffer_ = std::make_unique<TestQuicBatchWriterBuffer>();
+  }
+
+  // Fill packet_buffer_ with kMaxOutgoingPacketSize bytes of |c|s.
+  char* FillPacketBuffer(char c) {
+    return FillPacketBuffer(c, packet_buffer_, kMaxOutgoingPacketSize);
+  }
+
+  // Fill |packet_buffer| with kMaxOutgoingPacketSize bytes of |c|s.
+  char* FillPacketBuffer(char c, char* packet_buffer) {
+    return FillPacketBuffer(c, packet_buffer, kMaxOutgoingPacketSize);
+  }
+
+  // Fill |packet_buffer| with |buf_len| bytes of |c|s.
+  char* FillPacketBuffer(char c, char* packet_buffer, size_t buf_len) {
+    memset(packet_buffer, c, buf_len);
+    return packet_buffer;
+  }
+
+  void CheckBufferedWriteContent(int buffered_write_index,
+                                 char buffer_content,
+                                 size_t buf_len,
+                                 const QuicIpAddress& self_addr,
+                                 const QuicSocketAddress& peer_addr,
+                                 const PerPacketOptions* options) {
+    const BufferedWrite& buffered_write =
+        batch_buffer_->buffered_writes()[buffered_write_index];
+    EXPECT_EQ(buf_len, buffered_write.buf_len);
+    for (size_t i = 0; i < buf_len; ++i) {
+      EXPECT_EQ(buffer_content, buffered_write.buffer[i]);
+      if (buffer_content != buffered_write.buffer[i]) {
+        break;
+      }
+    }
+    EXPECT_EQ(self_addr, buffered_write.self_address);
+    EXPECT_EQ(peer_addr, buffered_write.peer_address);
+    if (options == nullptr) {
+      EXPECT_EQ(nullptr, buffered_write.options);
+    } else {
+      EXPECT_EQ(options->release_time_delay,
+                buffered_write.options->release_time_delay);
+    }
+  }
+
+ protected:
+  std::unique_ptr<TestQuicBatchWriterBuffer> batch_buffer_;
+  QuicIpAddress self_addr_;
+  QuicSocketAddress peer_addr_;
+  uint64_t release_time_ = 0;
+  char packet_buffer_[kMaxOutgoingPacketSize];
+};
+
+class BufferSizeSequence {
+ public:
+  explicit BufferSizeSequence(
+      std::vector<std::pair<std::vector<size_t>, size_t>> stages)
+      : stages_(std::move(stages)),
+        total_buf_len_(0),
+        stage_index_(0),
+        sequence_index_(0) {}
+
+  size_t Next() {
+    const std::vector<size_t>& seq = stages_[stage_index_].first;
+    size_t buf_len = seq[sequence_index_++ % seq.size()];
+    total_buf_len_ += buf_len;
+    if (stages_[stage_index_].second <= total_buf_len_) {
+      stage_index_ = std::min(stage_index_ + 1, stages_.size() - 1);
+    }
+    return buf_len;
+  }
+
+ private:
+  const std::vector<std::pair<std::vector<size_t>, size_t>> stages_;
+  size_t total_buf_len_;
+  size_t stage_index_;
+  size_t sequence_index_;
+};
+
+// Test in-place pushes. A in-place push is a push with a buffer address that is
+// equal to the result of GetNextWriteLocation().
+TEST_F(QuicBatchWriterBufferTest, InPlacePushes) {
+  std::vector<BufferSizeSequence> buffer_size_sequences = {
+      // Push large writes until the buffer is near full, then switch to 1-byte
+      // writes. This covers the edge cases when detecting insufficient buffer.
+      BufferSizeSequence({{{1350}, kBatchBufferSize - 3000}, {{1}, 1e6}}),
+      // A sequence that looks real.
+      BufferSizeSequence({{{1, 39, 97, 150, 1350, 1350, 1350, 1350}, 1e6}}),
+  };
+
+  for (auto& buffer_size_sequence : buffer_size_sequences) {
+    SwitchToNewBuffer();
+    int64_t num_push_failures = 0;
+
+    while (batch_buffer_->SizeInUse() < kBatchBufferSize) {
+      size_t buf_len = buffer_size_sequence.Next();
+      const bool has_enough_space =
+          (kBatchBufferSize - batch_buffer_->SizeInUse() >=
+           kMaxOutgoingPacketSize);
+
+      char* buffer = batch_buffer_->GetNextWriteLocation();
+
+      if (has_enough_space) {
+        EXPECT_EQ(batch_buffer_->buffer_ + batch_buffer_->SizeInUse(), buffer);
+      } else {
+        EXPECT_EQ(nullptr, buffer);
+      }
+
+      SCOPED_TRACE(testing::Message()
+                   << "Before Push: buf_len=" << buf_len
+                   << ", has_enough_space=" << has_enough_space
+                   << ", batch_buffer=" << batch_buffer_->DebugString());
+
+      auto push_result = batch_buffer_->PushBufferedWrite(
+          buffer, buf_len, self_addr_, peer_addr_, nullptr, release_time_);
+      if (!push_result.succeeded) {
+        ++num_push_failures;
+      }
+      EXPECT_EQ(has_enough_space, push_result.succeeded);
+      EXPECT_FALSE(push_result.buffer_copied);
+      if (!has_enough_space) {
+        break;
+      }
+    }
+    // Expect one and only one failure from the final push operation.
+    EXPECT_EQ(1, num_push_failures);
+  }
+}
+
+// Test some in-place pushes mixed with pushes with external buffers.
+TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
+  // First, a in-place push.
+  char* buffer = batch_buffer_->GetNextWriteLocation();
+  auto push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
+      peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_FALSE(push_result.buffer_copied);
+  CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+
+  // Then a push with external buffer.
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
+      nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_TRUE(push_result.buffer_copied);
+  CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+
+  // Then another in-place push.
+  buffer = batch_buffer_->GetNextWriteLocation();
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
+      peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_FALSE(push_result.buffer_copied);
+  CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+
+  // Then another push with external buffer.
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
+      nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_TRUE(push_result.buffer_copied);
+  CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
+                            peer_addr_, nullptr);
+}
+
+TEST_F(QuicBatchWriterBufferTest, PopAll) {
+  const int kNumBufferedWrites = 10;
+  for (int i = 0; i < kNumBufferedWrites; ++i) {
+    EXPECT_TRUE(batch_buffer_
+                    ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
+                                        self_addr_, peer_addr_, nullptr,
+                                        release_time_)
+                    .succeeded);
+  }
+  EXPECT_EQ(kNumBufferedWrites,
+            static_cast<int>(batch_buffer_->buffered_writes().size()));
+
+  auto pop_result = batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
+  EXPECT_EQ(0u, batch_buffer_->buffered_writes().size());
+  EXPECT_EQ(kNumBufferedWrites, pop_result.num_buffers_popped);
+  EXPECT_FALSE(pop_result.moved_remaining_buffers);
+}
+
+TEST_F(QuicBatchWriterBufferTest, PopPartial) {
+  const int kNumBufferedWrites = 10;
+  for (int i = 0; i < kNumBufferedWrites; ++i) {
+    EXPECT_TRUE(batch_buffer_
+                    ->PushBufferedWrite(FillPacketBuffer('A' + i),
+                                        kDefaultMaxPacketSize - i, self_addr_,
+                                        peer_addr_, nullptr, release_time_)
+                    .succeeded);
+  }
+
+  for (size_t i = 0;
+       i < kNumBufferedWrites && !batch_buffer_->buffered_writes().empty();
+       ++i) {
+    const size_t size_before_pop = batch_buffer_->buffered_writes().size();
+    const size_t expect_size_after_pop =
+        size_before_pop < i ? 0 : size_before_pop - i;
+    batch_buffer_->PopBufferedWrite(i);
+    ASSERT_EQ(expect_size_after_pop, batch_buffer_->buffered_writes().size());
+    const char first_write_content =
+        'A' + kNumBufferedWrites - expect_size_after_pop;
+    const size_t first_write_len =
+        kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
+    for (size_t j = 0; j < expect_size_after_pop; ++j) {
+      CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
+                                self_addr_, peer_addr_, nullptr);
+    }
+  }
+}
+
+TEST_F(QuicBatchWriterBufferTest, InPlacePushWithPops) {
+  // First, a in-place push.
+  char* buffer = batch_buffer_->GetNextWriteLocation();
+  const size_t first_packet_len = 2;
+  auto push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
+      self_addr_, peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_FALSE(push_result.buffer_copied);
+  CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
+                            nullptr);
+
+  // Simulate the case where the writer wants to do another in-place push, but
+  // can't do so because it can't be batched with the first buffer.
+  buffer = batch_buffer_->GetNextWriteLocation();
+  const size_t second_packet_len = 1350;
+
+  // Flush the first buffer.
+  auto pop_result = batch_buffer_->PopBufferedWrite(1);
+  EXPECT_EQ(1, pop_result.num_buffers_popped);
+  EXPECT_FALSE(pop_result.moved_remaining_buffers);
+
+  // Now the second push.
+  push_result = batch_buffer_->PushBufferedWrite(
+      FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
+      self_addr_, peer_addr_, nullptr, release_time_);
+  EXPECT_TRUE(push_result.succeeded);
+  EXPECT_TRUE(push_result.buffer_copied);
+  CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
+                            nullptr);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_batch_writer_test.cc
new file mode 100644
index 0000000..2cd3111
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_test.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_test.h"
+#include "quiche/quic/core/batch_writer/quic_gso_batch_writer.h"
+#include "quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicGsoBatchWriterIOTestDelegate
+    : public QuicUdpBatchWriterIOTestDelegate {
+ public:
+  bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& params) override {
+    QuicUdpSocketApi socket_api;
+    int fd =
+        socket_api.Create(params.address_family,
+                          /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
+                          /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
+    if (fd < 0) {
+      QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+      return false;  // Let the test fail rather than skip it.
+    }
+    const bool gso_not_supported =
+        QuicLinuxSocketUtils::GetUDPSegmentSize(fd) < 0;
+    socket_api.Destroy(fd);
+
+    if (gso_not_supported) {
+      QUIC_LOG(WARNING) << "Test skipped since GSO is not supported.";
+      return true;
+    }
+
+    QUIC_LOG(WARNING) << "OK: GSO is supported.";
+    return false;
+  }
+
+  void ResetWriter(int fd) override {
+    writer_ = std::make_unique<QuicGsoBatchWriter>(fd);
+  }
+
+  QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
+
+ private:
+  std::unique_ptr<QuicGsoBatchWriter> writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicGsoBatchWriterTest,
+    QuicUdpBatchWriterIOTest,
+    testing::ValuesIn(
+        MakeQuicBatchWriterTestParams<QuicGsoBatchWriterIOTestDelegate>()));
+
+class QuicSendmmsgBatchWriterIOTestDelegate
+    : public QuicUdpBatchWriterIOTestDelegate {
+ public:
+  void ResetWriter(int fd) override {
+    writer_ = std::make_unique<QuicSendmmsgBatchWriter>(
+        std::make_unique<QuicBatchWriterBuffer>(), fd);
+  }
+
+  QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
+
+ private:
+  std::unique_ptr<QuicSendmmsgBatchWriter> writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicSendmmsgBatchWriterTest,
+    QuicUdpBatchWriterIOTest,
+    testing::ValuesIn(MakeQuicBatchWriterTestParams<
+                      QuicSendmmsgBatchWriterIOTestDelegate>()));
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_test.h b/quiche/quic/core/batch_writer/quic_batch_writer_test.h
new file mode 100644
index 0000000..71c8aa8
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_test.h
@@ -0,0 +1,287 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <cstddef>
+#include <iostream>
+#include <utility>
+
+#include "absl/base/optimization.h"
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+static bool IsAddressFamilySupported(int address_family) {
+  static auto check_function = [](int address_family) {
+    int fd = socket(address_family, SOCK_STREAM, 0);
+    if (fd < 0) {
+      QUIC_LOG(ERROR) << "address_family not supported: " << address_family
+                      << ", error: " << strerror(errno);
+      EXPECT_EQ(EAFNOSUPPORT, errno);
+      return false;
+    }
+    close(fd);
+    return true;
+  };
+
+  if (address_family == AF_INET) {
+    static const bool ipv4_supported = check_function(AF_INET);
+    return ipv4_supported;
+  }
+
+  static const bool ipv6_supported = check_function(AF_INET6);
+  return ipv6_supported;
+}
+
+static bool CreateSocket(int family, QuicSocketAddress* address, int* fd) {
+  if (family == AF_INET) {
+    *address = QuicSocketAddress(QuicIpAddress::Loopback4(), 0);
+  } else {
+    QUICHE_DCHECK_EQ(family, AF_INET6);
+    *address = QuicSocketAddress(QuicIpAddress::Loopback6(), 0);
+  }
+
+  QuicUdpSocketApi socket_api;
+  *fd = socket_api.Create(family,
+                          /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
+                          /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
+  if (*fd < 0) {
+    QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+    return false;
+  }
+  socket_api.EnableDroppedPacketCount(*fd);
+
+  if (!socket_api.Bind(*fd, *address)) {
+    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
+    return false;
+  }
+
+  if (address->FromSocket(*fd) != 0) {
+    QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
+                    << strerror(errno);
+    return false;
+  }
+  return true;
+}
+
+struct QuicUdpBatchWriterIOTestParams;
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestDelegate {
+ public:
+  virtual ~QuicUdpBatchWriterIOTestDelegate() {}
+
+  virtual bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& /*params*/) {
+    return false;
+  }
+
+  virtual void ResetWriter(int fd) = 0;
+
+  virtual QuicUdpBatchWriter* GetWriter() = 0;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestParams {
+  // Use shared_ptr because gtest makes copies of test params.
+  std::shared_ptr<QuicUdpBatchWriterIOTestDelegate> delegate;
+  int address_family;
+  int data_size;
+  int packet_size;
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicUdpBatchWriterIOTestParams& p) {
+    os << "{ address_family: " << p.address_family
+       << " data_size: " << p.data_size << " packet_size: " << p.packet_size
+       << " }";
+    return os;
+  }
+};
+
+template <class QuicUdpBatchWriterIOTestDelegateT>
+static std::vector<QuicUdpBatchWriterIOTestParams>
+MakeQuicBatchWriterTestParams() {
+  static_assert(std::is_base_of<QuicUdpBatchWriterIOTestDelegate,
+                                QuicUdpBatchWriterIOTestDelegateT>::value,
+                "<QuicUdpBatchWriterIOTestDelegateT> needs to derive from "
+                "QuicUdpBatchWriterIOTestDelegate");
+
+  std::vector<QuicUdpBatchWriterIOTestParams> params;
+  for (int address_family : {AF_INET, AF_INET6}) {
+    for (int data_size : {1, 150, 1500, 15000, 64000, 512 * 1024}) {
+      for (int packet_size : {1, 50, 1350, 1452}) {
+        if (packet_size <= data_size && (data_size / packet_size < 2000)) {
+          params.push_back(
+              {std::make_unique<QuicUdpBatchWriterIOTestDelegateT>(),
+               address_family, data_size, packet_size});
+        }
+      }
+    }
+  }
+  return params;
+}
+
+// QuicUdpBatchWriterIOTest is a value parameterized test fixture that can be
+// used by tests of derived classes of QuicUdpBatchWriter, to verify basic
+// packet IO capabilities.
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTest
+    : public QuicTestWithParam<QuicUdpBatchWriterIOTestParams> {
+ protected:
+  QuicUdpBatchWriterIOTest()
+      : address_family_(GetParam().address_family),
+        data_size_(GetParam().data_size),
+        packet_size_(GetParam().packet_size),
+        self_socket_(-1),
+        peer_socket_(-1) {
+    QUIC_LOG(INFO) << "QuicUdpBatchWriterIOTestParams: " << GetParam();
+    EXPECT_TRUE(address_family_ == AF_INET || address_family_ == AF_INET6);
+    EXPECT_LE(packet_size_, data_size_);
+    EXPECT_LE(packet_size_, sizeof(packet_buffer_));
+  }
+
+  ~QuicUdpBatchWriterIOTest() override {
+    if (self_socket_ > 0) {
+      close(self_socket_);
+    }
+    if (peer_socket_ > 0) {
+      close(peer_socket_);
+    }
+  }
+
+  // Whether this test should be skipped. A test is passed if skipped.
+  // A test can be skipped when e.g. it exercises a kernel feature that is not
+  // available on the system.
+  bool ShouldSkip() {
+    if (!IsAddressFamilySupported(address_family_)) {
+      QUIC_LOG(WARNING)
+          << "Test skipped since address_family is not supported.";
+      return true;
+    }
+
+    return GetParam().delegate->ShouldSkip(GetParam());
+  }
+
+  // Initialize a test.
+  // To fail the test in Initialize, use ASSERT_xx macros.
+  void Initialize() {
+    ASSERT_TRUE(CreateSocket(address_family_, &self_address_, &self_socket_));
+    ASSERT_TRUE(CreateSocket(address_family_, &peer_address_, &peer_socket_));
+
+    QUIC_DLOG(INFO) << "Self address: " << self_address_.ToString() << ", fd "
+                    << self_socket_;
+    QUIC_DLOG(INFO) << "Peer address: " << peer_address_.ToString() << ", fd "
+                    << peer_socket_;
+    GetParam().delegate->ResetWriter(self_socket_);
+  }
+
+  QuicUdpBatchWriter* GetWriter() { return GetParam().delegate->GetWriter(); }
+
+  void ValidateWrite() {
+    char this_packet_content = '\0';
+    int this_packet_size;
+    int num_writes = 0;
+    size_t bytes_flushed = 0;
+    WriteResult result;
+
+    for (size_t bytes_sent = 0; bytes_sent < data_size_;
+         bytes_sent += this_packet_size, ++this_packet_content) {
+      this_packet_size = std::min(packet_size_, data_size_ - bytes_sent);
+      memset(&packet_buffer_[0], this_packet_content, this_packet_size);
+
+      result = GetWriter()->WritePacket(&packet_buffer_[0], this_packet_size,
+                                        self_address_.host(), peer_address_,
+                                        nullptr);
+
+      ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
+      bytes_flushed += result.bytes_written;
+      ++num_writes;
+
+      QUIC_DVLOG(1) << "[write #" << num_writes
+                    << "] this_packet_size: " << this_packet_size
+                    << ", total_bytes_sent: " << bytes_sent + this_packet_size
+                    << ", bytes_flushed: " << bytes_flushed
+                    << ", pkt content:" << std::hex << int(this_packet_content);
+    }
+
+    result = GetWriter()->Flush();
+    ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
+    bytes_flushed += result.bytes_written;
+    ASSERT_EQ(data_size_, bytes_flushed);
+
+    QUIC_LOG(INFO) << "Sent " << data_size_ << " bytes in " << num_writes
+                   << " writes.";
+  }
+
+  void ValidateRead() {
+    char this_packet_content = '\0';
+    int this_packet_size;
+    int packets_received = 0;
+    for (size_t bytes_received = 0; bytes_received < data_size_;
+         bytes_received += this_packet_size, ++this_packet_content) {
+      this_packet_size = std::min(packet_size_, data_size_ - bytes_received);
+      SCOPED_TRACE(testing::Message()
+                   << "Before ReadPacket: bytes_received=" << bytes_received
+                   << ", this_packet_size=" << this_packet_size);
+
+      QuicUdpSocketApi::ReadPacketResult result;
+      result.packet_buffer = {&packet_buffer_[0], sizeof(packet_buffer_)};
+      result.control_buffer = {&control_buffer_[0], sizeof(control_buffer_)};
+      QuicUdpSocketApi().ReadPacket(
+          peer_socket_,
+          quic::BitMask64(QuicUdpPacketInfoBit::V4_SELF_IP,
+                          QuicUdpPacketInfoBit::V6_SELF_IP,
+                          QuicUdpPacketInfoBit::PEER_ADDRESS),
+          &result);
+      ASSERT_TRUE(result.ok);
+      ASSERT_TRUE(
+          result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
+      QuicSocketAddress read_peer_address = result.packet_info.peer_address();
+      QuicIpAddress read_self_address = read_peer_address.host().IsIPv6()
+                                            ? result.packet_info.self_v6_ip()
+                                            : result.packet_info.self_v4_ip();
+
+      EXPECT_EQ(read_self_address, peer_address_.host());
+      EXPECT_EQ(read_peer_address, self_address_);
+      for (int i = 0; i < this_packet_size; ++i) {
+        EXPECT_EQ(this_packet_content, packet_buffer_[i]);
+      }
+      packets_received += this_packet_size;
+    }
+
+    QUIC_LOG(INFO) << "Received " << data_size_ << " bytes in "
+                   << packets_received << " packets.";
+  }
+
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  ABSL_CACHELINE_ALIGNED char packet_buffer_[1500];
+  ABSL_CACHELINE_ALIGNED char
+      control_buffer_[kDefaultUdpPacketControlBufferSize];
+  int address_family_;
+  const size_t data_size_;
+  const size_t packet_size_;
+  int self_socket_;
+  int peer_socket_;
+};
+
+TEST_P(QuicUdpBatchWriterIOTest, WriteAndRead) {
+  if (ShouldSkip()) {
+    return;
+  }
+
+  Initialize();
+
+  ValidateWrite();
+  ValidateRead();
+}
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc b/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
new file mode 100644
index 0000000..297f04e
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
@@ -0,0 +1,164 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_gso_batch_writer.h"
+
+#include <time.h>
+#include <ctime>
+
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+namespace quic {
+
+// static
+std::unique_ptr<QuicBatchWriterBuffer>
+QuicGsoBatchWriter::CreateBatchWriterBuffer() {
+  return std::make_unique<QuicBatchWriterBuffer>();
+}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(int fd)
+    : QuicGsoBatchWriter(fd, CLOCK_MONOTONIC) {}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(int fd,
+                                       clockid_t clockid_for_release_time)
+    : QuicUdpBatchWriter(CreateBatchWriterBuffer(), fd),
+      clockid_for_release_time_(clockid_for_release_time),
+      supports_release_time_(
+          GetQuicRestartFlag(quic_support_release_time_for_gso) &&
+          QuicLinuxSocketUtils::EnableReleaseTime(fd,
+                                                  clockid_for_release_time)) {
+  if (supports_release_time_) {
+    QUIC_RESTART_FLAG_COUNT(quic_support_release_time_for_gso);
+    QUIC_LOG_FIRST_N(INFO, 5) << "Release time is enabled.";
+  } else {
+    QUIC_LOG_FIRST_N(INFO, 5) << "Release time is not enabled.";
+  }
+}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(
+    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+    int fd,
+    clockid_t clockid_for_release_time,
+    ReleaseTimeForceEnabler /*enabler*/)
+    : QuicUdpBatchWriter(std::move(batch_buffer), fd),
+      clockid_for_release_time_(clockid_for_release_time),
+      supports_release_time_(true) {
+  QUIC_DLOG(INFO) << "Release time forcefully enabled.";
+}
+
+QuicGsoBatchWriter::CanBatchResult QuicGsoBatchWriter::CanBatch(
+    const char* /*buffer*/,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const PerPacketOptions* options,
+    uint64_t release_time) const {
+  // If there is nothing buffered already, this write will be included in this
+  // batch.
+  if (buffered_writes().empty()) {
+    return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
+  }
+
+  // The new write can be batched if all of the following are true:
+  // [0] The total number of the GSO segments(one write=one segment, including
+  //     the new write) must not exceed |max_segments|.
+  // [1] It has the same source and destination addresses as already buffered
+  //     writes.
+  // [2] It won't cause this batch to exceed kMaxGsoPacketSize.
+  // [3] Already buffered writes all have the same length.
+  // [4] Length of already buffered writes must >= length of the new write.
+  // [5] The new packet can be released without delay, or it has the same
+  //     release time as buffered writes.
+  const BufferedWrite& first = buffered_writes().front();
+  const BufferedWrite& last = buffered_writes().back();
+  // Whether this packet can be sent without delay, regardless of release time.
+  const bool can_burst = !SupportsReleaseTime() || !options ||
+                         options->release_time_delay.IsZero() ||
+                         options->allow_burst;
+  size_t max_segments = MaxSegments(first.buf_len);
+  bool can_batch =
+      buffered_writes().size() < max_segments &&                    // [0]
+      last.self_address == self_address &&                          // [1]
+      last.peer_address == peer_address &&                          // [1]
+      batch_buffer().SizeInUse() + buf_len <= kMaxGsoPacketSize &&  // [2]
+      first.buf_len == last.buf_len &&                              // [3]
+      first.buf_len >= buf_len &&                                   // [4]
+      (can_burst || first.release_time == release_time);            // [5]
+
+  // A flush is required if any of the following is true:
+  // [a] The new write can't be batched.
+  // [b] Length of the new write is different from the length of already
+  //     buffered writes.
+  // [c] The total number of the GSO segments, including the new write, reaches
+  //     |max_segments|.
+  bool must_flush = (!can_batch) ||                                  // [a]
+                    (last.buf_len != buf_len) ||                     // [b]
+                    (buffered_writes().size() + 1 == max_segments);  // [c]
+  return CanBatchResult(can_batch, must_flush);
+}
+
+QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime(
+    const PerPacketOptions* options) const {
+  QUICHE_DCHECK(SupportsReleaseTime());
+
+  if (options == nullptr) {
+    return {0, QuicTime::Delta::Zero()};
+  }
+
+  const uint64_t now = NowInNanosForReleaseTime();
+  const uint64_t ideal_release_time =
+      now + options->release_time_delay.ToMicroseconds() * 1000;
+
+  if ((options->release_time_delay.IsZero() || options->allow_burst) &&
+      !buffered_writes().empty() &&
+      // If release time of buffered packets is in the past, flush buffered
+      // packets and buffer this packet at the ideal release time.
+      (buffered_writes().back().release_time >= now)) {
+    // Send as soon as possible, but no sooner than the last buffered packet.
+    const uint64_t actual_release_time = buffered_writes().back().release_time;
+
+    const int64_t offset_ns = actual_release_time - ideal_release_time;
+    ReleaseTime result{actual_release_time,
+                       QuicTime::Delta::FromMicroseconds(offset_ns / 1000)};
+
+    QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time
+                  << ", actual_release_time:" << actual_release_time
+                  << ", offset:" << result.release_time_offset;
+    return result;
+  }
+
+  // Send according to the release time delay.
+  return {ideal_release_time, QuicTime::Delta::Zero()};
+}
+
+uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const {
+  struct timespec ts;
+
+  if (clock_gettime(clockid_for_release_time_, &ts) != 0) {
+    return 0;
+  }
+
+  return ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
+}
+
+// static
+void QuicGsoBatchWriter::BuildCmsg(QuicMsgHdr* hdr,
+                                   const QuicIpAddress& self_address,
+                                   uint16_t gso_size,
+                                   uint64_t release_time) {
+  hdr->SetIpInNextCmsg(self_address);
+  if (gso_size > 0) {
+    *hdr->GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = gso_size;
+  }
+  if (release_time != 0) {
+    *hdr->GetNextCmsgData<uint64_t>(SOL_SOCKET, SO_TXTIME) = release_time;
+  }
+}
+
+QuicGsoBatchWriter::FlushImplResult QuicGsoBatchWriter::FlushImpl() {
+  return InternalFlushImpl<kCmsgSpace>(BuildCmsg);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer.h b/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
new file mode 100644
index 0000000..6321cb5
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+
+namespace quic {
+
+// QuicGsoBatchWriter sends QUIC packets in batches, using UDP socket's generic
+// segmentation offload(GSO) capability.
+class QUIC_EXPORT_PRIVATE QuicGsoBatchWriter : public QuicUdpBatchWriter {
+ public:
+  explicit QuicGsoBatchWriter(int fd);
+
+  // |clockid_for_release_time|: FQ qdisc requires CLOCK_MONOTONIC, EDF requires
+  // CLOCK_TAI.
+  QuicGsoBatchWriter(int fd, clockid_t clockid_for_release_time);
+
+  bool SupportsReleaseTime() const final { return supports_release_time_; }
+
+  CanBatchResult CanBatch(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          const PerPacketOptions* options,
+                          uint64_t release_time) const override;
+
+  FlushImplResult FlushImpl() override;
+
+ protected:
+  // Test only constructor to forcefully enable release time.
+  struct QUIC_EXPORT_PRIVATE ReleaseTimeForceEnabler {};
+  QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+                     int fd,
+                     clockid_t clockid_for_release_time,
+                     ReleaseTimeForceEnabler enabler);
+
+  ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override;
+
+  // Get the current time in nanos from |clockid_for_release_time_|.
+  virtual uint64_t NowInNanosForReleaseTime() const;
+
+  static size_t MaxSegments(size_t gso_size) {
+    // Max segments should be the min of UDP_MAX_SEGMENTS(64) and
+    // (((64KB - sizeof(ip hdr) - sizeof(udp hdr)) / MSS) + 1), in the typical
+    // case of IPv6 packets with 1500-byte MTU, the result is
+    //         ((64KB - 40 - 8) / (1500 - 48)) + 1 = 46
+    // However, due a kernel bug, the limit is much lower for tiny gso_sizes.
+    return gso_size <= 2 ? 16 : 45;
+  }
+
+  static const int kCmsgSpace =
+      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize + kCmsgSpaceForTxTime;
+  static void BuildCmsg(QuicMsgHdr* hdr,
+                        const QuicIpAddress& self_address,
+                        uint16_t gso_size,
+                        uint64_t release_time);
+
+  template <size_t CmsgSpace, typename CmsgBuilderT>
+  FlushImplResult InternalFlushImpl(CmsgBuilderT cmsg_builder) {
+    QUICHE_DCHECK(!IsWriteBlocked());
+    QUICHE_DCHECK(!buffered_writes().empty());
+
+    FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
+                              /*num_packets_sent=*/0, /*bytes_written=*/0};
+    WriteResult& write_result = result.write_result;
+
+    int total_bytes = batch_buffer().SizeInUse();
+    const BufferedWrite& first = buffered_writes().front();
+    char cbuf[CmsgSpace];
+    QuicMsgHdr hdr(first.buffer, total_bytes, first.peer_address, cbuf,
+                   sizeof(cbuf));
+
+    uint16_t gso_size = buffered_writes().size() > 1 ? first.buf_len : 0;
+    cmsg_builder(&hdr, first.self_address, gso_size, first.release_time);
+
+    write_result = QuicLinuxSocketUtils::WritePacket(fd(), hdr);
+    QUIC_DVLOG(1) << "Write GSO packet result: " << write_result
+                  << ", fd: " << fd()
+                  << ", self_address: " << first.self_address.ToString()
+                  << ", peer_address: " << first.peer_address.ToString()
+                  << ", num_segments: " << buffered_writes().size()
+                  << ", total_bytes: " << total_bytes
+                  << ", gso_size: " << gso_size
+                  << ", release_time: " << first.release_time;
+
+    // All segments in a GSO packet share the same fate - if the write failed,
+    // none of them are sent, and it's not needed to call PopBufferedWrite().
+    if (write_result.status != WRITE_STATUS_OK) {
+      return result;
+    }
+
+    result.num_packets_sent = buffered_writes().size();
+
+    write_result.bytes_written = total_bytes;
+    result.bytes_written = total_bytes;
+
+    batch_buffer().PopBufferedWrite(buffered_writes().size());
+
+    QUIC_BUG_IF(quic_bug_12544_1, !buffered_writes().empty())
+        << "All packets should have been written on a successful return";
+    return result;
+  }
+
+ private:
+  static std::unique_ptr<QuicBatchWriterBuffer> CreateBatchWriterBuffer();
+
+  const clockid_t clockid_for_release_time_;
+  const bool supports_release_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
new file mode 100644
index 0000000..2bf0ffc
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
@@ -0,0 +1,472 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_gso_batch_writer.h"
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_mock_syscall_wrapper.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+size_t PacketLength(const msghdr* msg) {
+  size_t length = 0;
+  for (size_t i = 0; i < msg->msg_iovlen; ++i) {
+    length += msg->msg_iov[i].iov_len;
+  }
+  return length;
+}
+
+uint64_t MillisToNanos(uint64_t milliseconds) {
+  return milliseconds * 1000000;
+}
+
+class QUIC_EXPORT_PRIVATE TestQuicGsoBatchWriter : public QuicGsoBatchWriter {
+ public:
+  using QuicGsoBatchWriter::batch_buffer;
+  using QuicGsoBatchWriter::buffered_writes;
+  using QuicGsoBatchWriter::CanBatch;
+  using QuicGsoBatchWriter::CanBatchResult;
+  using QuicGsoBatchWriter::GetReleaseTime;
+  using QuicGsoBatchWriter::MaxSegments;
+  using QuicGsoBatchWriter::QuicGsoBatchWriter;
+  using QuicGsoBatchWriter::ReleaseTime;
+
+  static std::unique_ptr<TestQuicGsoBatchWriter>
+  NewInstanceWithReleaseTimeSupport() {
+    return std::unique_ptr<TestQuicGsoBatchWriter>(new TestQuicGsoBatchWriter(
+        std::make_unique<QuicBatchWriterBuffer>(),
+        /*fd=*/-1, CLOCK_MONOTONIC, ReleaseTimeForceEnabler()));
+  }
+
+  uint64_t NowInNanosForReleaseTime() const override {
+    return MillisToNanos(forced_release_time_ms_);
+  }
+
+  void ForceReleaseTimeMs(uint64_t forced_release_time_ms) {
+    forced_release_time_ms_ = forced_release_time_ms;
+  }
+
+ private:
+  uint64_t forced_release_time_ms_ = 1;
+};
+
+struct QUIC_EXPORT_PRIVATE TestPerPacketOptions : public PerPacketOptions {
+  std::unique_ptr<quic::PerPacketOptions> Clone() const override {
+    return std::make_unique<TestPerPacketOptions>(*this);
+  }
+};
+
+// TestBufferedWrite is a copy-constructible BufferedWrite.
+struct QUIC_EXPORT_PRIVATE TestBufferedWrite : public BufferedWrite {
+  using BufferedWrite::BufferedWrite;
+  TestBufferedWrite(const TestBufferedWrite& other)
+      : BufferedWrite(other.buffer,
+                      other.buf_len,
+                      other.self_address,
+                      other.peer_address,
+                      other.options ? other.options->Clone()
+                                    : std::unique_ptr<PerPacketOptions>(),
+                      other.release_time) {}
+};
+
+// Pointed to by all instances of |BatchCriteriaTestData|. Content not used.
+static char unused_packet_buffer[kMaxOutgoingPacketSize];
+
+struct QUIC_EXPORT_PRIVATE BatchCriteriaTestData {
+  BatchCriteriaTestData(size_t buf_len,
+                        const QuicIpAddress& self_address,
+                        const QuicSocketAddress& peer_address,
+                        uint64_t release_time,
+                        bool can_batch,
+                        bool must_flush)
+      : buffered_write(unused_packet_buffer,
+                       buf_len,
+                       self_address,
+                       peer_address,
+                       std::unique_ptr<PerPacketOptions>(),
+                       release_time),
+        can_batch(can_batch),
+        must_flush(must_flush) {}
+
+  TestBufferedWrite buffered_write;
+  // Expected value of CanBatchResult.can_batch when batching |buffered_write|.
+  bool can_batch;
+  // Expected value of CanBatchResult.must_flush when batching |buffered_write|.
+  bool must_flush;
+};
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeDecrease() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {39,       self_addr,  peer_addr,  0,      true,           true},
+    {39,       self_addr,  peer_addr,  0,      false,          true},
+    {1350,     self_addr,  peer_addr,  0,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeIncrease() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1351,     self_addr,  peer_addr,  0,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_AddressChange() {
+  const QuicIpAddress self_addr1 = QuicIpAddress::Loopback4();
+  const QuicIpAddress self_addr2 = QuicIpAddress::Loopback6();
+  const QuicSocketAddress peer_addr1(self_addr1, 666);
+  const QuicSocketAddress peer_addr2(self_addr1, 777);
+  const QuicSocketAddress peer_addr3(self_addr2, 666);
+  const QuicSocketAddress peer_addr4(self_addr2, 777);
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr    t_rel  can_batch       must_flush
+    {1350,     self_addr1, peer_addr1,  0,     true,           false},
+    {1350,     self_addr1, peer_addr1,  0,     true,           false},
+    {1350,     self_addr1, peer_addr1,  0,     true,           false},
+    {1350,     self_addr2, peer_addr1,  0,     false,          true},
+    {1350,     self_addr1, peer_addr2,  0,     false,          true},
+    {1350,     self_addr1, peer_addr3,  0,     false,          true},
+    {1350,     self_addr1, peer_addr4,  0,     false,          true},
+    {1350,     self_addr1, peer_addr4,  0,     false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime1() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  5,      true,           false},
+    {1350,     self_addr,  peer_addr,  5,      true,           false},
+    {1350,     self_addr,  peer_addr,  5,      true,           false},
+    {1350,     self_addr,  peer_addr,  9,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime2() {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table = {
+      // clang-format off
+  // buf_len   self_addr   peer_addr   t_rel   can_batch       must_flush
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  0,      true,           false},
+    {1350,     self_addr,  peer_addr,  9,      false,          true},
+      // clang-format on
+  };
+  return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_MaxSegments(
+    size_t gso_size) {
+  const QuicIpAddress self_addr;
+  const QuicSocketAddress peer_addr;
+  std::vector<BatchCriteriaTestData> test_data_table;
+  size_t max_segments = TestQuicGsoBatchWriter::MaxSegments(gso_size);
+  for (size_t i = 0; i < max_segments; ++i) {
+    bool is_last_in_batch = (i + 1 == max_segments);
+    test_data_table.push_back({gso_size, self_addr, peer_addr,
+                               /*release_time=*/0, true, is_last_in_batch});
+  }
+  test_data_table.push_back(
+      {gso_size, self_addr, peer_addr, /*release_time=*/0, false, true});
+  return test_data_table;
+}
+
+class QuicGsoBatchWriterTest : public QuicTest {
+ protected:
+  WriteResult WritePacket(QuicGsoBatchWriter* writer, size_t packet_size) {
+    return writer->WritePacket(&packet_buffer_[0], packet_size, self_address_,
+                               peer_address_, nullptr);
+  }
+
+  WriteResult WritePacketWithOptions(QuicGsoBatchWriter* writer,
+                                     PerPacketOptions* options) {
+    return writer->WritePacket(&packet_buffer_[0], 1350, self_address_,
+                               peer_address_, options);
+  }
+
+  QuicIpAddress self_address_ = QuicIpAddress::Any4();
+  QuicSocketAddress peer_address_{QuicIpAddress::Any4(), 443};
+  char packet_buffer_[1500];
+  StrictMock<MockQuicSyscallWrapper> mock_syscalls_;
+  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
+};
+
+TEST_F(QuicGsoBatchWriterTest, BatchCriteria) {
+  std::unique_ptr<TestQuicGsoBatchWriter> writer;
+
+  std::vector<std::vector<BatchCriteriaTestData>> test_data_tables;
+  test_data_tables.emplace_back(BatchCriteriaTestData_SizeDecrease());
+  test_data_tables.emplace_back(BatchCriteriaTestData_SizeIncrease());
+  test_data_tables.emplace_back(BatchCriteriaTestData_AddressChange());
+  test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime1());
+  test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime2());
+  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1));
+  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(2));
+  test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1350));
+
+  for (size_t i = 0; i < test_data_tables.size(); ++i) {
+    writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+
+    const auto& test_data_table = test_data_tables[i];
+    for (size_t j = 0; j < test_data_table.size(); ++j) {
+      const BatchCriteriaTestData& test_data = test_data_table[j];
+      SCOPED_TRACE(testing::Message() << "i=" << i << ", j=" << j);
+      TestPerPacketOptions options;
+      options.release_time_delay = QuicTime::Delta::FromMicroseconds(
+          test_data.buffered_write.release_time);
+      TestQuicGsoBatchWriter::CanBatchResult result = writer->CanBatch(
+          test_data.buffered_write.buffer, test_data.buffered_write.buf_len,
+          test_data.buffered_write.self_address,
+          test_data.buffered_write.peer_address, &options,
+          test_data.buffered_write.release_time);
+
+      ASSERT_EQ(test_data.can_batch, result.can_batch);
+      ASSERT_EQ(test_data.must_flush, result.must_flush);
+
+      if (result.can_batch) {
+        ASSERT_TRUE(writer->batch_buffer()
+                        .PushBufferedWrite(
+                            test_data.buffered_write.buffer,
+                            test_data.buffered_write.buf_len,
+                            test_data.buffered_write.self_address,
+                            test_data.buffered_write.peer_address, &options,
+                            test_data.buffered_write.release_time)
+                        .succeeded);
+      }
+    }
+  }
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteSuccess) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 1000));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(1100u, PacketLength(msg));
+        return 1100;
+      }));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 1100), WritePacket(&writer, 100));
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteBlockDataNotBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(200u, PacketLength(msg));
+        errno = EWOULDBLOCK;
+        return -1;
+      }));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
+            WritePacket(&writer, 150));
+  ASSERT_EQ(200u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(2u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteBlockDataBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(250u, PacketLength(msg));
+        errno = EWOULDBLOCK;
+        return -1;
+      }));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED_DATA_BUFFERED, EWOULDBLOCK),
+            WritePacket(&writer, 50));
+
+  EXPECT_TRUE(writer.IsWriteBlocked());
+
+  ASSERT_EQ(250u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(3u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteErrorWithoutDataBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(200u, PacketLength(msg));
+        errno = EPERM;
+        return -1;
+      }));
+  WriteResult error_result = WritePacket(&writer, 150);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
+
+  ASSERT_EQ(3u, error_result.dropped_packets);
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteErrorAfterDataBuffered) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(250u, PacketLength(msg));
+        errno = EPERM;
+        return -1;
+      }));
+  WriteResult error_result = WritePacket(&writer, 50);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
+
+  ASSERT_EQ(3u, error_result.dropped_packets);
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, FlushError) {
+  TestQuicGsoBatchWriter writer(/*fd=*/-1);
+
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(200u, PacketLength(msg));
+        errno = EINVAL;
+        return -1;
+      }));
+  WriteResult error_result = writer.Flush();
+  ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL), error_result);
+
+  ASSERT_EQ(2u, error_result.dropped_packets);
+  ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+  ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, ReleaseTimeNullOptions) {
+  auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+  EXPECT_EQ(0u, writer->GetReleaseTime(nullptr).actual_release_time);
+}
+
+TEST_F(QuicGsoBatchWriterTest, ReleaseTime) {
+  const WriteResult write_buffered(WRITE_STATUS_OK, 0);
+
+  auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+
+  TestPerPacketOptions options;
+  EXPECT_TRUE(options.release_time_delay.IsZero());
+  EXPECT_FALSE(options.allow_burst);
+  EXPECT_EQ(MillisToNanos(1),
+            writer->GetReleaseTime(&options).actual_release_time);
+
+  // The 1st packet has no delay.
+  WriteResult result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+
+  // The 2nd packet has some delay, but allows burst.
+  options.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
+  options.allow_burst = true;
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::FromMilliseconds(-3));
+
+  // The 3rd packet has more delay and does not allow burst.
+  // The first 2 packets are flushed due to different release time.
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(2700u, PacketLength(msg));
+        errno = 0;
+        return 0;
+      }));
+  options.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
+  options.allow_burst = false;
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 2700), result);
+  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+
+  // The 4th packet has same delay, but allows burst.
+  options.allow_burst = true;
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+
+  // The 5th packet has same delay, allows burst, but is shorter.
+  // Packets 3,4 and 5 are flushed.
+  EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+      .WillOnce(Invoke([](int /*sockfd*/, const msghdr* msg, int /*flags*/) {
+        EXPECT_EQ(3000u, PacketLength(msg));
+        errno = 0;
+        return 0;
+      }));
+  options.allow_burst = true;
+  EXPECT_EQ(MillisToNanos(6),
+            writer->GetReleaseTime(&options).actual_release_time);
+  ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 3000),
+            writer->WritePacket(&packet_buffer_[0], 300, self_address_,
+                                peer_address_, &options));
+  EXPECT_TRUE(writer->buffered_writes().empty());
+
+  // Pretend 1ms has elapsed and the 6th packet has 1ms less delay. In other
+  // words, the release time should still be the same as packets 3-5.
+  writer->ForceReleaseTimeMs(2);
+  options.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
+  result = WritePacketWithOptions(writer.get(), &options);
+  ASSERT_EQ(write_buffered, result);
+  EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+  EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
new file mode 100644
index 0000000..e03aed0
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+
+QuicSendmmsgBatchWriter::QuicSendmmsgBatchWriter(
+    std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+    int fd)
+    : QuicUdpBatchWriter(std::move(batch_buffer), fd) {}
+
+QuicSendmmsgBatchWriter::CanBatchResult QuicSendmmsgBatchWriter::CanBatch(
+    const char* /*buffer*/,
+    size_t /*buf_len*/,
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/,
+    const PerPacketOptions* /*options*/,
+    uint64_t /*release_time*/) const {
+  return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
+}
+
+QuicSendmmsgBatchWriter::FlushImplResult QuicSendmmsgBatchWriter::FlushImpl() {
+  return InternalFlushImpl(
+      kCmsgSpaceForIp,
+      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+      });
+}
+
+QuicSendmmsgBatchWriter::FlushImplResult
+QuicSendmmsgBatchWriter::InternalFlushImpl(size_t cmsg_space,
+                                           const CmsgBuilder& cmsg_builder) {
+  QUICHE_DCHECK(!IsWriteBlocked());
+  QUICHE_DCHECK(!buffered_writes().empty());
+
+  FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
+                            /*num_packets_sent=*/0, /*bytes_written=*/0};
+  WriteResult& write_result = result.write_result;
+
+  auto first = buffered_writes().cbegin();
+  const auto last = buffered_writes().cend();
+  while (first != last) {
+    QuicMMsgHdr mhdr(first, last, cmsg_space, cmsg_builder);
+
+    int num_packets_sent;
+    write_result = QuicLinuxSocketUtils::WriteMultiplePackets(
+        fd(), &mhdr, &num_packets_sent);
+    QUIC_DVLOG(1) << "WriteMultiplePackets sent " << num_packets_sent
+                  << " out of " << mhdr.num_msgs()
+                  << " packets. WriteResult=" << write_result;
+
+    if (write_result.status != WRITE_STATUS_OK) {
+      QUICHE_DCHECK_EQ(0, num_packets_sent);
+      break;
+    } else if (num_packets_sent == 0) {
+      QUIC_BUG(quic_bug_10825_1)
+          << "WriteMultiplePackets returned OK, but no packets were sent.";
+      write_result = WriteResult(WRITE_STATUS_ERROR, EIO);
+      break;
+    }
+
+    first += num_packets_sent;
+
+    result.num_packets_sent += num_packets_sent;
+    result.bytes_written += write_result.bytes_written;
+  }
+
+  // Call PopBufferedWrite() even if write_result.status is not WRITE_STATUS_OK,
+  // to deal with partial writes.
+  batch_buffer().PopBufferedWrite(result.num_packets_sent);
+
+  if (write_result.status != WRITE_STATUS_OK) {
+    return result;
+  }
+
+  QUIC_BUG_IF(quic_bug_12537_1, !buffered_writes().empty())
+      << "All packets should have been written on a successful return";
+  write_result.bytes_written = result.bytes_written;
+  return result;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
new file mode 100644
index 0000000..afbec10
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
+
+#include "quiche/quic/core/batch_writer/quic_batch_writer_base.h"
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicSendmmsgBatchWriter : public QuicUdpBatchWriter {
+ public:
+  QuicSendmmsgBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+                          int fd);
+
+  CanBatchResult CanBatch(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          const PerPacketOptions* options,
+                          uint64_t release_time) const override;
+
+  FlushImplResult FlushImpl() override;
+
+ protected:
+  using CmsgBuilder = QuicMMsgHdr::ControlBufferInitializer;
+  FlushImplResult InternalFlushImpl(size_t cmsg_space,
+                                    const CmsgBuilder& cmsg_builder);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
new file mode 100644
index 0000000..c8a213a
--- /dev/null
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Add tests here.
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/chlo_extractor.cc b/quiche/quic/core/chlo_extractor.cc
new file mode 100644
index 0000000..7cd6ec9
--- /dev/null
+++ b/quiche/quic/core/chlo_extractor.cc
@@ -0,0 +1,364 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/chlo_extractor.h"
+
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+namespace {
+
+class ChloFramerVisitor : public QuicFramerVisitorInterface,
+                          public CryptoFramerVisitorInterface {
+ public:
+  ChloFramerVisitor(QuicFramer* framer,
+                    const QuicTagVector& create_session_tag_indicators,
+                    ChloExtractor::Delegate* delegate);
+
+  ~ChloFramerVisitor() override = default;
+
+  // QuicFramerVisitorInterface implementation
+  void OnError(QuicFramer* /*framer*/) override {}
+  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
+  void OnPacket() override {}
+  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {}
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {}
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
+  void OnDecryptedPacket(size_t /*length*/,
+                         EncryptionLevel /*level*/) override {}
+  bool OnPacketHeader(const QuicPacketHeader& header) override;
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override;
+  bool OnStreamFrame(const QuicStreamFrame& frame) override;
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override;
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override;
+  bool OnAckFrameEnd(QuicPacketNumber start) override;
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
+  bool OnPingFrame(const QuicPingFrame& frame) override;
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override;
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
+  bool OnMessageFrame(const QuicMessageFrame& frame) override;
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& farme) override;
+  void OnPacketComplete() override {}
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override;
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& /*packet*/) override {}
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override;
+  void OnDecryptedFirstPacketInKeyPhase() override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+
+  // CryptoFramerVisitorInterface implementation.
+  void OnError(CryptoFramer* framer) override;
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+  // Shared implementation between OnStreamFrame and OnCryptoFrame.
+  bool OnHandshakeData(absl::string_view data);
+
+  bool found_chlo() { return found_chlo_; }
+  bool chlo_contains_tags() { return chlo_contains_tags_; }
+
+ private:
+  QuicFramer* framer_;
+  const QuicTagVector& create_session_tag_indicators_;
+  ChloExtractor::Delegate* delegate_;
+  bool found_chlo_;
+  bool chlo_contains_tags_;
+  QuicConnectionId connection_id_;
+};
+
+ChloFramerVisitor::ChloFramerVisitor(
+    QuicFramer* framer,
+    const QuicTagVector& create_session_tag_indicators,
+    ChloExtractor::Delegate* delegate)
+    : framer_(framer),
+      create_session_tag_indicators_(create_session_tag_indicators),
+      delegate_(delegate),
+      found_chlo_(false),
+      chlo_contains_tags_(false),
+      connection_id_(EmptyQuicConnectionId()) {}
+
+bool ChloFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
+  if (!framer_->IsSupportedVersion(version)) {
+    return false;
+  }
+  framer_->set_version(version);
+  return true;
+}
+
+bool ChloFramerVisitor::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& header) {
+  connection_id_ = header.destination_connection_id;
+  // QuicFramer creates a NullEncrypter and NullDecrypter at level
+  // ENCRYPTION_INITIAL. While those are the correct ones to use with some
+  // versions of QUIC, others use the IETF-style initial crypters, so those need
+  // to be created and installed.
+  framer_->SetInitialObfuscators(header.destination_connection_id);
+  return true;
+}
+bool ChloFramerVisitor::OnUnauthenticatedHeader(
+    const QuicPacketHeader& /*header*/) {
+  return true;
+}
+bool ChloFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
+  return true;
+}
+
+void ChloFramerVisitor::OnCoalescedPacket(
+    const QuicEncryptedPacket& /*packet*/) {}
+
+void ChloFramerVisitor::OnUndecryptablePacket(
+    const QuicEncryptedPacket& /*packet*/,
+    EncryptionLevel /*decryption_level*/,
+    bool /*has_decryption_key*/) {}
+
+bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (QuicVersionUsesCryptoFrames(framer_->transport_version())) {
+    // CHLO will be sent in CRYPTO frames in v47 and above.
+    return false;
+  }
+  absl::string_view data(frame.data_buffer, frame.data_length);
+  if (QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+                                  frame.stream_id) &&
+      frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
+    return OnHandshakeData(data);
+  }
+  return true;
+}
+
+bool ChloFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  if (!QuicVersionUsesCryptoFrames(framer_->transport_version())) {
+    // CHLO will be in stream frames before v47.
+    return false;
+  }
+  absl::string_view data(frame.data_buffer, frame.data_length);
+  if (frame.offset == 0 && absl::StartsWith(data, "CHLO")) {
+    return OnHandshakeData(data);
+  }
+  return true;
+}
+
+bool ChloFramerVisitor::OnHandshakeData(absl::string_view data) {
+  CryptoFramer crypto_framer;
+  crypto_framer.set_visitor(this);
+  if (!crypto_framer.ProcessInput(data)) {
+    return false;
+  }
+  // Interrogate the crypto framer and see if there are any
+  // intersecting tags between what we saw in the maybe-CHLO and the
+  // indicator set.
+  for (const QuicTag tag : create_session_tag_indicators_) {
+    if (crypto_framer.HasTag(tag)) {
+      chlo_contains_tags_ = true;
+    }
+  }
+  if (chlo_contains_tags_ && delegate_) {
+    // Unfortunately, because this is a partial CHLO,
+    // OnHandshakeMessage was never called, so the ALPN was never
+    // extracted. Fake it up a bit and send it to the delegate so that
+    // the correct dispatch can happen.
+    crypto_framer.ForceHandshake();
+  }
+
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
+                                        QuicTime::Delta /*ack_delay_time*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
+                                   QuicPacketNumber /*end*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
+                                       QuicTime /*timestamp*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnStopWaitingFrame(
+    const QuicStopWaitingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnConnectionCloseFrame(
+    const QuicConnectionCloseFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnStopSendingFrame(
+    const QuicStopSendingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPathChallengeFrame(
+    const QuicPathChallengeFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPathResponseFrame(
+    const QuicPathResponseFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnWindowUpdateFrame(
+    const QuicWindowUpdateFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnHandshakeDoneFrame(
+    const QuicHandshakeDoneFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::IsValidStatelessResetToken(
+    const StatelessResetToken& /*token*/) const {
+  return false;
+}
+
+bool ChloFramerVisitor::OnMaxStreamsFrame(
+    const QuicMaxStreamsFrame& /*frame*/) {
+  return true;
+}
+
+bool ChloFramerVisitor::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& /*frame*/) {
+  return true;
+}
+
+void ChloFramerVisitor::OnKeyUpdate(KeyUpdateReason /*reason*/) {}
+
+void ChloFramerVisitor::OnDecryptedFirstPacketInKeyPhase() {}
+
+std::unique_ptr<QuicDecrypter>
+ChloFramerVisitor::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return nullptr;
+}
+
+std::unique_ptr<QuicEncrypter>
+ChloFramerVisitor::CreateCurrentOneRttEncrypter() {
+  return nullptr;
+}
+
+void ChloFramerVisitor::OnError(CryptoFramer* /*framer*/) {}
+
+void ChloFramerVisitor::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  if (delegate_ != nullptr) {
+    delegate_->OnChlo(framer_->transport_version(), connection_id_, message);
+  }
+  found_chlo_ = true;
+}
+
+}  // namespace
+
+// static
+bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
+                            ParsedQuicVersion version,
+                            const QuicTagVector& create_session_tag_indicators,
+                            Delegate* delegate,
+                            uint8_t connection_id_length) {
+  QUIC_DVLOG(1) << "Extracting CHLO using version " << version;
+  QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_SERVER,
+                    connection_id_length);
+  ChloFramerVisitor visitor(&framer, create_session_tag_indicators, delegate);
+  framer.set_visitor(&visitor);
+  if (!framer.ProcessPacket(packet)) {
+    return false;
+  }
+  return visitor.found_chlo() || visitor.chlo_contains_tags();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/chlo_extractor.h b/quiche/quic/core/chlo_extractor.h
new file mode 100644
index 0000000..c2604c8
--- /dev/null
+++ b/quiche/quic/core/chlo_extractor.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
+#define QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+// A utility for extracting QUIC Client Hello messages from packets,
+// without needs to spin up a full QuicSession.
+class QUIC_NO_EXPORT ChloExtractor {
+ public:
+  class QUIC_NO_EXPORT Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Called when a CHLO message is found in the packets.
+    virtual void OnChlo(QuicTransportVersion version,
+                        QuicConnectionId connection_id,
+                        const CryptoHandshakeMessage& chlo) = 0;
+  };
+
+  // Extracts a CHLO message from |packet| and invokes the OnChlo
+  // method of |delegate|. Return true if a CHLO message was found,
+  // and false otherwise. If non-empty,
+  // |create_session_tag_indicators| contains a list of QUIC tags that
+  // if found will result in the session being created early, to
+  // enable support for multi-packet CHLOs.
+  static bool Extract(const QuicEncryptedPacket& packet,
+                      ParsedQuicVersion version,
+                      const QuicTagVector& create_session_tag_indicators,
+                      Delegate* delegate,
+                      uint8_t connection_id_length);
+
+  ChloExtractor(const ChloExtractor&) = delete;
+  ChloExtractor operator=(const ChloExtractor&) = delete;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CHLO_EXTRACTOR_H_
diff --git a/quiche/quic/core/chlo_extractor_test.cc b/quiche/quic/core/chlo_extractor_test.cc
new file mode 100644
index 0000000..c8268f8
--- /dev/null
+++ b/quiche/quic/core/chlo_extractor_test.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/chlo_extractor.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestDelegate : public ChloExtractor::Delegate {
+ public:
+  TestDelegate() = default;
+  ~TestDelegate() override = default;
+
+  // ChloExtractor::Delegate implementation
+  void OnChlo(QuicTransportVersion version,
+              QuicConnectionId connection_id,
+              const CryptoHandshakeMessage& chlo) override {
+    version_ = version;
+    connection_id_ = connection_id;
+    chlo_ = chlo.DebugString();
+    absl::string_view alpn_value;
+    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
+      alpn_ = std::string(alpn_value);
+    }
+  }
+
+  QuicConnectionId connection_id() const { return connection_id_; }
+  QuicTransportVersion transport_version() const { return version_; }
+  const std::string& chlo() const { return chlo_; }
+  const std::string& alpn() const { return alpn_; }
+
+ private:
+  QuicConnectionId connection_id_;
+  QuicTransportVersion version_;
+  std::string chlo_;
+  std::string alpn_;
+};
+
+class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  ChloExtractorTest() : version_(GetParam()) {}
+
+  void MakePacket(absl::string_view data,
+                  bool munge_offset,
+                  bool munge_stream_id) {
+    QuicPacketHeader header;
+    header.destination_connection_id = TestConnectionId();
+    header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+    header.version_flag = true;
+    header.version = version_;
+    header.reset_flag = false;
+    header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+    header.packet_number = QuicPacketNumber(1);
+    if (version_.HasLongHeaderLengths()) {
+      header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+      header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    }
+    QuicFrames frames;
+    size_t offset = 0;
+    if (munge_offset) {
+      offset++;
+    }
+    QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
+                      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+    framer.SetInitialObfuscators(TestConnectionId());
+    if (!version_.UsesCryptoFrames() || munge_stream_id) {
+      QuicStreamId stream_id =
+          QuicUtils::GetCryptoStreamId(version_.transport_version);
+      if (munge_stream_id) {
+        stream_id++;
+      }
+      frames.push_back(
+          QuicFrame(QuicStreamFrame(stream_id, false, offset, data)));
+    } else {
+      frames.push_back(
+          QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, offset, data)));
+    }
+    std::unique_ptr<QuicPacket> packet(
+        BuildUnsizedDataPacket(&framer, header, frames));
+    EXPECT_TRUE(packet != nullptr);
+    size_t encrypted_length =
+        framer.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *packet,
+                              buffer_, ABSL_ARRAYSIZE(buffer_));
+    ASSERT_NE(0u, encrypted_length);
+    packet_ = std::make_unique<QuicEncryptedPacket>(buffer_, encrypted_length);
+    EXPECT_TRUE(packet_ != nullptr);
+    DeleteFrames(&frames);
+  }
+
+ protected:
+  ParsedQuicVersion version_;
+  TestDelegate delegate_;
+  std::unique_ptr<QuicEncryptedPacket> packet_;
+  char buffer_[kMaxOutgoingPacketSize];
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ChloExtractorTests,
+    ChloExtractorTest,
+    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
+    ::testing::PrintToStringParamName());
+
+TEST_P(ChloExtractorTest, FindsValidChlo) {
+  CryptoHandshakeMessage client_hello;
+  client_hello.set_tag(kCHLO);
+
+  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
+
+  MakePacket(client_hello_str, /*munge_offset=*/false,
+             /*munge_stream_id=*/false);
+  EXPECT_TRUE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                     kQuicDefaultConnectionIdLength));
+  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
+  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
+  EXPECT_EQ(client_hello.DebugString(), delegate_.chlo());
+}
+
+TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
+  if (version_.UsesCryptoFrames()) {
+    // When crypto frames are in use we do not use stream frames.
+    return;
+  }
+  CryptoHandshakeMessage client_hello;
+  client_hello.set_tag(kCHLO);
+
+  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
+  MakePacket(client_hello_str,
+             /*munge_offset=*/false, /*munge_stream_id=*/true);
+  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                      kQuicDefaultConnectionIdLength));
+}
+
+TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
+  CryptoHandshakeMessage client_hello;
+  client_hello.set_tag(kCHLO);
+
+  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
+  MakePacket(client_hello_str, /*munge_offset=*/true,
+             /*munge_stream_id=*/false);
+  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                      kQuicDefaultConnectionIdLength));
+}
+
+TEST_P(ChloExtractorTest, DoesNotFindInvalidChlo) {
+  MakePacket("foo", /*munge_offset=*/false,
+             /*munge_stream_id=*/false);
+  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
+                                      kQuicDefaultConnectionIdLength));
+}
+
+TEST_P(ChloExtractorTest, FirstFlight) {
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_);
+  ASSERT_EQ(packets.size(), 1u);
+  EXPECT_TRUE(ChloExtractor::Extract(*packets[0], version_, {}, &delegate_,
+                                     kQuicDefaultConnectionIdLength));
+  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
+  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
+  EXPECT_EQ(AlpnForVersion(version_), delegate_.alpn());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bandwidth_sampler.cc b/quiche/quic/core/congestion_control/bandwidth_sampler.cc
new file mode 100644
index 0000000..1a8a591
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bandwidth_sampler.cc
@@ -0,0 +1,589 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os, const SendTimeState& s) {
+  os << "{valid:" << s.is_valid << ", app_limited:" << s.is_app_limited
+     << ", total_sent:" << s.total_bytes_sent
+     << ", total_acked:" << s.total_bytes_acked
+     << ", total_lost:" << s.total_bytes_lost
+     << ", inflight:" << s.bytes_in_flight << "}";
+  return os;
+}
+
+QuicByteCount MaxAckHeightTracker::Update(
+    QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
+    QuicRoundTripCount round_trip_count,
+    QuicPacketNumber last_sent_packet_number,
+    QuicPacketNumber last_acked_packet_number, QuicTime ack_time,
+    QuicByteCount bytes_acked) {
+  bool force_new_epoch = false;
+
+  if (reduce_extra_acked_on_bandwidth_increase_ && is_new_max_bandwidth) {
+    // Save and clear existing entries.
+    ExtraAckedEvent best = max_ack_height_filter_.GetBest();
+    ExtraAckedEvent second_best = max_ack_height_filter_.GetSecondBest();
+    ExtraAckedEvent third_best = max_ack_height_filter_.GetThirdBest();
+    max_ack_height_filter_.Clear();
+
+    // Reinsert the heights into the filter after recalculating.
+    QuicByteCount expected_bytes_acked = bandwidth_estimate * best.time_delta;
+    if (expected_bytes_acked < best.bytes_acked) {
+      best.extra_acked = best.bytes_acked - expected_bytes_acked;
+      max_ack_height_filter_.Update(best, best.round);
+    }
+    expected_bytes_acked = bandwidth_estimate * second_best.time_delta;
+    if (expected_bytes_acked < second_best.bytes_acked) {
+      QUICHE_DCHECK_LE(best.round, second_best.round);
+      second_best.extra_acked = second_best.bytes_acked - expected_bytes_acked;
+      max_ack_height_filter_.Update(second_best, second_best.round);
+    }
+    expected_bytes_acked = bandwidth_estimate * third_best.time_delta;
+    if (expected_bytes_acked < third_best.bytes_acked) {
+      QUICHE_DCHECK_LE(second_best.round, third_best.round);
+      third_best.extra_acked = third_best.bytes_acked - expected_bytes_acked;
+      max_ack_height_filter_.Update(third_best, third_best.round);
+    }
+  }
+
+  // If any packet sent after the start of the epoch has been acked, start a new
+  // epoch.
+  if (start_new_aggregation_epoch_after_full_round_ &&
+      last_sent_packet_number_before_epoch_.IsInitialized() &&
+      last_acked_packet_number.IsInitialized() &&
+      last_acked_packet_number > last_sent_packet_number_before_epoch_) {
+    QUIC_DVLOG(3) << "Force starting a new aggregation epoch. "
+                     "last_sent_packet_number_before_epoch_:"
+                  << last_sent_packet_number_before_epoch_
+                  << ", last_acked_packet_number:" << last_acked_packet_number;
+    if (reduce_extra_acked_on_bandwidth_increase_) {
+      QUIC_BUG(quic_bwsampler_46)
+          << "A full round of aggregation should never "
+          << "pass with startup_include_extra_acked(B204) enabled.";
+    }
+    force_new_epoch = true;
+  }
+  if (aggregation_epoch_start_time_ == QuicTime::Zero() || force_new_epoch) {
+    aggregation_epoch_bytes_ = bytes_acked;
+    aggregation_epoch_start_time_ = ack_time;
+    last_sent_packet_number_before_epoch_ = last_sent_packet_number;
+    ++num_ack_aggregation_epochs_;
+    return 0;
+  }
+
+  // Compute how many bytes are expected to be delivered, assuming max bandwidth
+  // is correct.
+  QuicTime::Delta aggregation_delta = ack_time - aggregation_epoch_start_time_;
+  QuicByteCount expected_bytes_acked = bandwidth_estimate * aggregation_delta;
+  // Reset the current aggregation epoch as soon as the ack arrival rate is less
+  // than or equal to the max bandwidth.
+  if (aggregation_epoch_bytes_ <=
+      ack_aggregation_bandwidth_threshold_ * expected_bytes_acked) {
+    QUIC_DVLOG(3) << "Starting a new aggregation epoch because "
+                     "aggregation_epoch_bytes_ "
+                  << aggregation_epoch_bytes_
+                  << " is smaller than expected. "
+                     "ack_aggregation_bandwidth_threshold_:"
+                  << ack_aggregation_bandwidth_threshold_
+                  << ", expected_bytes_acked:" << expected_bytes_acked
+                  << ", bandwidth_estimate:" << bandwidth_estimate
+                  << ", aggregation_duration:" << aggregation_delta
+                  << ", new_aggregation_epoch:" << ack_time
+                  << ", new_aggregation_bytes_acked:" << bytes_acked;
+    // Reset to start measuring a new aggregation epoch.
+    aggregation_epoch_bytes_ = bytes_acked;
+    aggregation_epoch_start_time_ = ack_time;
+    last_sent_packet_number_before_epoch_ = last_sent_packet_number;
+    ++num_ack_aggregation_epochs_;
+    return 0;
+  }
+
+  aggregation_epoch_bytes_ += bytes_acked;
+
+  // Compute how many extra bytes were delivered vs max bandwidth.
+  QuicByteCount extra_bytes_acked =
+      aggregation_epoch_bytes_ - expected_bytes_acked;
+  QUIC_DVLOG(3) << "Updating MaxAckHeight. ack_time:" << ack_time
+                << ", last sent packet:" << last_sent_packet_number
+                << ", bandwidth_estimate:" << bandwidth_estimate
+                << ", bytes_acked:" << bytes_acked
+                << ", expected_bytes_acked:" << expected_bytes_acked
+                << ", aggregation_epoch_bytes_:" << aggregation_epoch_bytes_
+                << ", extra_bytes_acked:" << extra_bytes_acked;
+  ExtraAckedEvent new_event;
+  new_event.extra_acked = extra_bytes_acked;
+  new_event.bytes_acked = aggregation_epoch_bytes_;
+  new_event.time_delta = aggregation_delta;
+  max_ack_height_filter_.Update(new_event, round_trip_count);
+  return extra_bytes_acked;
+}
+
+BandwidthSampler::BandwidthSampler(
+    const QuicUnackedPacketMap* unacked_packet_map,
+    QuicRoundTripCount max_height_tracker_window_length)
+    : total_bytes_sent_(0),
+      total_bytes_acked_(0),
+      total_bytes_lost_(0),
+      total_bytes_neutered_(0),
+      total_bytes_sent_at_last_acked_packet_(0),
+      last_acked_packet_sent_time_(QuicTime::Zero()),
+      last_acked_packet_ack_time_(QuicTime::Zero()),
+      is_app_limited_(true),
+      connection_state_map_(),
+      max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
+      unacked_packet_map_(unacked_packet_map),
+      max_ack_height_tracker_(max_height_tracker_window_length),
+      total_bytes_acked_after_last_ack_event_(0),
+      overestimate_avoidance_(false),
+      limit_max_ack_height_tracker_by_send_rate_(false) {}
+
+BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
+    : total_bytes_sent_(other.total_bytes_sent_),
+      total_bytes_acked_(other.total_bytes_acked_),
+      total_bytes_lost_(other.total_bytes_lost_),
+      total_bytes_neutered_(other.total_bytes_neutered_),
+      total_bytes_sent_at_last_acked_packet_(
+          other.total_bytes_sent_at_last_acked_packet_),
+      last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
+      last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
+      last_sent_packet_(other.last_sent_packet_),
+      last_acked_packet_(other.last_acked_packet_),
+      is_app_limited_(other.is_app_limited_),
+      end_of_app_limited_phase_(other.end_of_app_limited_phase_),
+      connection_state_map_(other.connection_state_map_),
+      recent_ack_points_(other.recent_ack_points_),
+      a0_candidates_(other.a0_candidates_),
+      max_tracked_packets_(other.max_tracked_packets_),
+      unacked_packet_map_(other.unacked_packet_map_),
+      max_ack_height_tracker_(other.max_ack_height_tracker_),
+      total_bytes_acked_after_last_ack_event_(
+          other.total_bytes_acked_after_last_ack_event_),
+      overestimate_avoidance_(other.overestimate_avoidance_),
+      limit_max_ack_height_tracker_by_send_rate_(
+          other.limit_max_ack_height_tracker_by_send_rate_) {}
+
+void BandwidthSampler::EnableOverestimateAvoidance() {
+  if (overestimate_avoidance_) {
+    return;
+  }
+
+  overestimate_avoidance_ = true;
+  // TODO(wub): Change the default value of
+  // --quic_ack_aggregation_bandwidth_threshold to 2.0.
+  max_ack_height_tracker_.SetAckAggregationBandwidthThreshold(2.0);
+}
+
+BandwidthSampler::~BandwidthSampler() {}
+
+void BandwidthSampler::OnPacketSent(
+    QuicTime sent_time,
+    QuicPacketNumber packet_number,
+    QuicByteCount bytes,
+    QuicByteCount bytes_in_flight,
+    HasRetransmittableData has_retransmittable_data) {
+  last_sent_packet_ = packet_number;
+
+  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
+    return;
+  }
+
+  total_bytes_sent_ += bytes;
+
+  // If there are no packets in flight, the time at which the new transmission
+  // opens can be treated as the A_0 point for the purpose of bandwidth
+  // sampling. This underestimates bandwidth to some extent, and produces some
+  // artificially low samples for most packets in flight, but it provides with
+  // samples at important points where we would not have them otherwise, most
+  // importantly at the beginning of the connection.
+  if (bytes_in_flight == 0) {
+    last_acked_packet_ack_time_ = sent_time;
+    if (overestimate_avoidance_) {
+      recent_ack_points_.Clear();
+      recent_ack_points_.Update(sent_time, total_bytes_acked_);
+      a0_candidates_.clear();
+      a0_candidates_.push_back(recent_ack_points_.MostRecentPoint());
+    }
+    total_bytes_sent_at_last_acked_packet_ = total_bytes_sent_;
+
+    // In this situation ack compression is not a concern, set send rate to
+    // effectively infinite.
+    last_acked_packet_sent_time_ = sent_time;
+  }
+
+  if (!connection_state_map_.IsEmpty() &&
+      packet_number >
+          connection_state_map_.last_packet() + max_tracked_packets_) {
+    if (unacked_packet_map_ != nullptr && !unacked_packet_map_->empty()) {
+      QuicPacketNumber maybe_least_unacked =
+          unacked_packet_map_->GetLeastUnacked();
+      QUIC_BUG(quic_bug_10437_1)
+          << "BandwidthSampler in-flight packet map has exceeded maximum "
+             "number of tracked packets("
+          << max_tracked_packets_
+          << ").  First tracked: " << connection_state_map_.first_packet()
+          << "; last tracked: " << connection_state_map_.last_packet()
+          << "; entry_slots_used: " << connection_state_map_.entry_slots_used()
+          << "; number_of_present_entries: "
+          << connection_state_map_.number_of_present_entries()
+          << "; packet number: " << packet_number
+          << "; unacked_map: " << unacked_packet_map_->DebugString()
+          << "; total_bytes_sent: " << total_bytes_sent_
+          << "; total_bytes_acked: " << total_bytes_acked_
+          << "; total_bytes_lost: " << total_bytes_lost_
+          << "; total_bytes_neutered: " << total_bytes_neutered_
+          << "; last_acked_packet_sent_time: " << last_acked_packet_sent_time_
+          << "; total_bytes_sent_at_last_acked_packet: "
+          << total_bytes_sent_at_last_acked_packet_
+          << "; least_unacked_packet_info: "
+          << (unacked_packet_map_->IsUnacked(maybe_least_unacked)
+                  ? unacked_packet_map_
+                        ->GetTransmissionInfo(maybe_least_unacked)
+                        .DebugString()
+                  : "n/a");
+    } else {
+      QUIC_BUG(quic_bug_10437_2)
+          << "BandwidthSampler in-flight packet map has exceeded maximum "
+             "number of tracked packets.";
+    }
+  }
+
+  bool success = connection_state_map_.Emplace(packet_number, sent_time, bytes,
+                                               bytes_in_flight + bytes, *this);
+  QUIC_BUG_IF(quic_bug_10437_3, !success)
+      << "BandwidthSampler failed to insert the packet "
+         "into the map, most likely because it's already "
+         "in it.";
+}
+
+void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
+  connection_state_map_.Remove(
+      packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
+        QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
+        total_bytes_neutered_ += sent_packet.size;
+      });
+}
+
+BandwidthSamplerInterface::CongestionEventSample
+BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
+                                    const AckedPacketVector& acked_packets,
+                                    const LostPacketVector& lost_packets,
+                                    QuicBandwidth max_bandwidth,
+                                    QuicBandwidth est_bandwidth_upper_bound,
+                                    QuicRoundTripCount round_trip_count) {
+  CongestionEventSample event_sample;
+
+  SendTimeState last_lost_packet_send_state;
+
+  for (const LostPacket& packet : lost_packets) {
+    SendTimeState send_state =
+        OnPacketLost(packet.packet_number, packet.bytes_lost);
+    if (send_state.is_valid) {
+      last_lost_packet_send_state = send_state;
+    }
+  }
+
+  if (acked_packets.empty()) {
+    // Only populate send state for a loss-only event.
+    event_sample.last_packet_send_state = last_lost_packet_send_state;
+    return event_sample;
+  }
+
+  SendTimeState last_acked_packet_send_state;
+  QuicBandwidth max_send_rate = QuicBandwidth::Zero();
+  for (const auto& packet : acked_packets) {
+    BandwidthSample sample =
+        OnPacketAcknowledged(ack_time, packet.packet_number);
+    if (!sample.state_at_send.is_valid) {
+      continue;
+    }
+
+    last_acked_packet_send_state = sample.state_at_send;
+
+    if (!sample.rtt.IsZero()) {
+      event_sample.sample_rtt = std::min(event_sample.sample_rtt, sample.rtt);
+    }
+    if (sample.bandwidth > event_sample.sample_max_bandwidth) {
+      event_sample.sample_max_bandwidth = sample.bandwidth;
+      event_sample.sample_is_app_limited = sample.state_at_send.is_app_limited;
+    }
+    if (!sample.send_rate.IsInfinite()) {
+      max_send_rate = std::max(max_send_rate, sample.send_rate);
+    }
+    const QuicByteCount inflight_sample =
+        total_bytes_acked() - last_acked_packet_send_state.total_bytes_acked;
+    if (inflight_sample > event_sample.sample_max_inflight) {
+      event_sample.sample_max_inflight = inflight_sample;
+    }
+  }
+
+  if (!last_lost_packet_send_state.is_valid) {
+    event_sample.last_packet_send_state = last_acked_packet_send_state;
+  } else if (!last_acked_packet_send_state.is_valid) {
+    event_sample.last_packet_send_state = last_lost_packet_send_state;
+  } else {
+    // If two packets are inflight and an alarm is armed to lose a packet and it
+    // wakes up late, then the first of two in flight packets could have been
+    // acknowledged before the wakeup, which re-evaluates loss detection, and
+    // could declare the later of the two lost.
+    event_sample.last_packet_send_state =
+        lost_packets.back().packet_number > acked_packets.back().packet_number
+            ? last_lost_packet_send_state
+            : last_acked_packet_send_state;
+  }
+
+  bool is_new_max_bandwidth = event_sample.sample_max_bandwidth > max_bandwidth;
+  max_bandwidth = std::max(max_bandwidth, event_sample.sample_max_bandwidth);
+  if (limit_max_ack_height_tracker_by_send_rate_) {
+    max_bandwidth = std::max(max_bandwidth, max_send_rate);
+  }
+  // TODO(ianswett): Why is the min being passed in here?
+  event_sample.extra_acked =
+      OnAckEventEnd(std::min(est_bandwidth_upper_bound, max_bandwidth),
+                    is_new_max_bandwidth, round_trip_count);
+
+  return event_sample;
+}
+
+QuicByteCount BandwidthSampler::OnAckEventEnd(
+    QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
+    QuicRoundTripCount round_trip_count) {
+  const QuicByteCount newly_acked_bytes =
+      total_bytes_acked_ - total_bytes_acked_after_last_ack_event_;
+
+  if (newly_acked_bytes == 0) {
+    return 0;
+  }
+  total_bytes_acked_after_last_ack_event_ = total_bytes_acked_;
+  QuicByteCount extra_acked = max_ack_height_tracker_.Update(
+      bandwidth_estimate, is_new_max_bandwidth, round_trip_count,
+      last_sent_packet_, last_acked_packet_, last_acked_packet_ack_time_,
+      newly_acked_bytes);
+  // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack
+  // aggregation epoch, save LessRecentPoint, which is the last ack point of the
+  // previous epoch, as a A0 candidate.
+  if (overestimate_avoidance_ && extra_acked == 0) {
+    a0_candidates_.push_back(recent_ack_points_.LessRecentPoint());
+    QUIC_DVLOG(1) << "New a0_candidate:" << a0_candidates_.back();
+  }
+  return extra_acked;
+}
+
+BandwidthSample BandwidthSampler::OnPacketAcknowledged(
+    QuicTime ack_time,
+    QuicPacketNumber packet_number) {
+  last_acked_packet_ = packet_number;
+  ConnectionStateOnSentPacket* sent_packet_pointer =
+      connection_state_map_.GetEntry(packet_number);
+  if (sent_packet_pointer == nullptr) {
+    // See the TODO below.
+    return BandwidthSample();
+  }
+  BandwidthSample sample =
+      OnPacketAcknowledgedInner(ack_time, packet_number, *sent_packet_pointer);
+  return sample;
+}
+
+BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
+    QuicTime ack_time,
+    QuicPacketNumber packet_number,
+    const ConnectionStateOnSentPacket& sent_packet) {
+  total_bytes_acked_ += sent_packet.size;
+  total_bytes_sent_at_last_acked_packet_ =
+      sent_packet.send_time_state.total_bytes_sent;
+  last_acked_packet_sent_time_ = sent_packet.sent_time;
+  last_acked_packet_ack_time_ = ack_time;
+  if (overestimate_avoidance_) {
+    recent_ack_points_.Update(ack_time, total_bytes_acked_);
+  }
+
+  if (is_app_limited_) {
+    // Exit app-limited phase in two cases:
+    // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
+    // packets are sent while there are buffered packets or pending data.
+    // (2) The current acked packet is after the sent packet marked as the end
+    // of the app limit phase.
+    if (!end_of_app_limited_phase_.IsInitialized() ||
+        packet_number > end_of_app_limited_phase_) {
+      is_app_limited_ = false;
+    }
+  }
+
+  // There might have been no packets acknowledged at the moment when the
+  // current packet was sent. In that case, there is no bandwidth sample to
+  // make.
+  if (sent_packet.last_acked_packet_sent_time == QuicTime::Zero()) {
+    QUIC_BUG(quic_bug_10437_4)
+        << "sent_packet.last_acked_packet_sent_time is zero";
+    return BandwidthSample();
+  }
+
+  // Infinite rate indicates that the sampler is supposed to discard the
+  // current send rate sample and use only the ack rate.
+  QuicBandwidth send_rate = QuicBandwidth::Infinite();
+  if (sent_packet.sent_time > sent_packet.last_acked_packet_sent_time) {
+    send_rate = QuicBandwidth::FromBytesAndTimeDelta(
+        sent_packet.send_time_state.total_bytes_sent -
+            sent_packet.total_bytes_sent_at_last_acked_packet,
+        sent_packet.sent_time - sent_packet.last_acked_packet_sent_time);
+  }
+
+  AckPoint a0;
+  if (overestimate_avoidance_ &&
+      ChooseA0Point(sent_packet.send_time_state.total_bytes_acked, &a0)) {
+    QUIC_DVLOG(2) << "Using a0 point: " << a0;
+  } else {
+    a0.ack_time = sent_packet.last_acked_packet_ack_time,
+    a0.total_bytes_acked = sent_packet.send_time_state.total_bytes_acked;
+  }
+
+  // During the slope calculation, ensure that ack time of the current packet is
+  // always larger than the time of the previous packet, otherwise division by
+  // zero or integer underflow can occur.
+  if (ack_time <= a0.ack_time) {
+    // TODO(wub): Compare this code count before and after fixing clock jitter
+    // issue.
+    if (a0.ack_time == sent_packet.sent_time) {
+      // This is the 1st packet after quiescense.
+      QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 1, 2);
+    } else {
+      QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 2, 2);
+    }
+    QUIC_LOG_EVERY_N_SEC(ERROR, 60)
+        << "Time of the previously acked packet:"
+        << a0.ack_time.ToDebuggingValue()
+        << " is larger than the ack time of the current packet:"
+        << ack_time.ToDebuggingValue()
+        << ". acked packet number:" << packet_number
+        << ", total_bytes_acked_:" << total_bytes_acked_
+        << ", overestimate_avoidance_:" << overestimate_avoidance_
+        << ", sent_packet:" << sent_packet;
+    return BandwidthSample();
+  }
+  QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      total_bytes_acked_ - a0.total_bytes_acked, ack_time - a0.ack_time);
+
+  BandwidthSample sample;
+  sample.bandwidth = std::min(send_rate, ack_rate);
+  // Note: this sample does not account for delayed acknowledgement time.  This
+  // means that the RTT measurements here can be artificially high, especially
+  // on low bandwidth connections.
+  sample.rtt = ack_time - sent_packet.sent_time;
+  sample.send_rate = send_rate;
+  SentPacketToSendTimeState(sent_packet, &sample.state_at_send);
+
+  if (sample.bandwidth.IsZero()) {
+    QUIC_LOG_EVERY_N_SEC(ERROR, 60)
+        << "ack_rate: " << ack_rate << ", send_rate: " << send_rate
+        << ". acked packet number:" << packet_number
+        << ", overestimate_avoidance_:" << overestimate_avoidance_ << "a1:{"
+        << total_bytes_acked_ << "@" << ack_time << "}, a0:{"
+        << a0.total_bytes_acked << "@" << a0.ack_time
+        << "}, sent_packet:" << sent_packet;
+  }
+  return sample;
+}
+
+bool BandwidthSampler::ChooseA0Point(QuicByteCount total_bytes_acked,
+                                     AckPoint* a0) {
+  if (a0_candidates_.empty()) {
+    QUIC_BUG(quic_bug_10437_5)
+        << "No A0 point candicates. total_bytes_acked:" << total_bytes_acked;
+    return false;
+  }
+
+  if (a0_candidates_.size() == 1) {
+    *a0 = a0_candidates_.front();
+    return true;
+  }
+
+  for (size_t i = 1; i < a0_candidates_.size(); ++i) {
+    if (a0_candidates_[i].total_bytes_acked > total_bytes_acked) {
+      *a0 = a0_candidates_[i - 1];
+      if (i > 1) {
+        a0_candidates_.pop_front_n(i - 1);
+      }
+      return true;
+    }
+  }
+
+  // All candidates' total_bytes_acked is <= |total_bytes_acked|.
+  *a0 = a0_candidates_.back();
+  a0_candidates_.pop_front_n(a0_candidates_.size() - 1);
+  return true;
+}
+
+SendTimeState BandwidthSampler::OnPacketLost(QuicPacketNumber packet_number,
+                                             QuicPacketLength bytes_lost) {
+  // TODO(vasilvv): see the comment for the case of missing packets in
+  // BandwidthSampler::OnPacketAcknowledged on why this does not raise a
+  // QUIC_BUG when removal fails.
+  SendTimeState send_time_state;
+
+  total_bytes_lost_ += bytes_lost;
+  ConnectionStateOnSentPacket* sent_packet_pointer =
+      connection_state_map_.GetEntry(packet_number);
+  if (sent_packet_pointer != nullptr) {
+    SentPacketToSendTimeState(*sent_packet_pointer, &send_time_state);
+  }
+
+  return send_time_state;
+}
+
+void BandwidthSampler::SentPacketToSendTimeState(
+    const ConnectionStateOnSentPacket& sent_packet,
+    SendTimeState* send_time_state) const {
+  *send_time_state = sent_packet.send_time_state;
+  send_time_state->is_valid = true;
+}
+
+void BandwidthSampler::OnAppLimited() {
+  is_app_limited_ = true;
+  end_of_app_limited_phase_ = last_sent_packet_;
+}
+
+void BandwidthSampler::RemoveObsoletePackets(QuicPacketNumber least_unacked) {
+  // A packet can become obsolete when it is removed from QuicUnackedPacketMap's
+  // view of inflight before it is acked or marked as lost. For example, when
+  // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet,
+  // the packet is removed from QuicUnackedPacketMap's inflight, but is not
+  // marked as acked or lost in the BandwidthSampler.
+  connection_state_map_.RemoveUpTo(least_unacked);
+}
+
+QuicByteCount BandwidthSampler::total_bytes_sent() const {
+  return total_bytes_sent_;
+}
+
+QuicByteCount BandwidthSampler::total_bytes_acked() const {
+  return total_bytes_acked_;
+}
+
+QuicByteCount BandwidthSampler::total_bytes_lost() const {
+  return total_bytes_lost_;
+}
+
+QuicByteCount BandwidthSampler::total_bytes_neutered() const {
+  return total_bytes_neutered_;
+}
+
+bool BandwidthSampler::is_app_limited() const {
+  return is_app_limited_;
+}
+
+QuicPacketNumber BandwidthSampler::end_of_app_limited_phase() const {
+  return end_of_app_limited_phase_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bandwidth_sampler.h b/quiche/quic/core/congestion_control/bandwidth_sampler.h
new file mode 100644
index 0000000..56a3bab
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bandwidth_sampler.h
@@ -0,0 +1,627 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/packet_number_indexed_queue.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class BandwidthSamplerPeer;
+}  // namespace test
+
+// A subset of BandwidthSampler::ConnectionStateOnSentPacket which is returned
+// to the caller when the packet is acked or lost.
+struct QUIC_EXPORT_PRIVATE SendTimeState {
+  SendTimeState()
+      : is_valid(false),
+        is_app_limited(false),
+        total_bytes_sent(0),
+        total_bytes_acked(0),
+        total_bytes_lost(0),
+        bytes_in_flight(0) {}
+
+  SendTimeState(bool is_app_limited,
+                QuicByteCount total_bytes_sent,
+                QuicByteCount total_bytes_acked,
+                QuicByteCount total_bytes_lost,
+                QuicByteCount bytes_in_flight)
+      : is_valid(true),
+        is_app_limited(is_app_limited),
+        total_bytes_sent(total_bytes_sent),
+        total_bytes_acked(total_bytes_acked),
+        total_bytes_lost(total_bytes_lost),
+        bytes_in_flight(bytes_in_flight) {}
+
+  SendTimeState(const SendTimeState& other) = default;
+  SendTimeState& operator=(const SendTimeState& other) = default;
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const SendTimeState& s);
+
+  // Whether other states in this object is valid.
+  bool is_valid;
+
+  // Whether the sender is app limited at the time the packet was sent.
+  // App limited bandwidth sample might be artificially low because the sender
+  // did not have enough data to send in order to saturate the link.
+  bool is_app_limited;
+
+  // Total number of sent bytes at the time the packet was sent.
+  // Includes the packet itself.
+  QuicByteCount total_bytes_sent;
+
+  // Total number of acked bytes at the time the packet was sent.
+  QuicByteCount total_bytes_acked;
+
+  // Total number of lost bytes at the time the packet was sent.
+  QuicByteCount total_bytes_lost;
+
+  // Total number of inflight bytes at the time the packet was sent.
+  // Includes the packet itself.
+  // It should be equal to |total_bytes_sent| minus the sum of
+  // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes.
+  QuicByteCount bytes_in_flight;
+};
+
+struct QUIC_NO_EXPORT ExtraAckedEvent {
+  // The excess bytes acknowlwedged in the time delta for this event.
+  QuicByteCount extra_acked = 0;
+
+  // The bytes acknowledged and time delta from the event.
+  QuicByteCount bytes_acked = 0;
+  QuicTime::Delta time_delta = QuicTime::Delta::Zero();
+  // The round trip of the event.
+  QuicRoundTripCount round = 0;
+
+  bool operator>=(const ExtraAckedEvent& other) const {
+    return extra_acked >= other.extra_acked;
+  }
+  bool operator==(const ExtraAckedEvent& other) const {
+    return extra_acked == other.extra_acked;
+  }
+};
+
+struct QUIC_EXPORT_PRIVATE BandwidthSample {
+  // The bandwidth at that particular sample. Zero if no valid bandwidth sample
+  // is available.
+  QuicBandwidth bandwidth = QuicBandwidth::Zero();
+
+  // The RTT measurement at this particular sample.  Zero if no RTT sample is
+  // available.  Does not correct for delayed ack time.
+  QuicTime::Delta rtt = QuicTime::Delta::Zero();
+
+  // |send_rate| is computed from the current packet being acked('P') and an
+  // earlier packet that is acked before P was sent.
+  QuicBandwidth send_rate = QuicBandwidth::Infinite();
+
+  // States captured when the packet was sent.
+  SendTimeState state_at_send;
+};
+
+// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every
+// ack event to keep track the degree of ack aggregation(a.k.a "ack height").
+class QUIC_EXPORT_PRIVATE MaxAckHeightTracker {
+ public:
+  explicit MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)
+      : max_ack_height_filter_(initial_filter_window, ExtraAckedEvent(), 0) {}
+
+  QuicByteCount Get() const {
+    return max_ack_height_filter_.GetBest().extra_acked;
+  }
+
+  QuicByteCount Update(QuicBandwidth bandwidth_estimate,
+                       bool is_new_max_bandwidth,
+                       QuicRoundTripCount round_trip_count,
+                       QuicPacketNumber last_sent_packet_number,
+                       QuicPacketNumber last_acked_packet_number,
+                       QuicTime ack_time, QuicByteCount bytes_acked);
+
+  void SetFilterWindowLength(QuicRoundTripCount length) {
+    max_ack_height_filter_.SetWindowLength(length);
+  }
+
+  void Reset(QuicByteCount new_height, QuicRoundTripCount new_time) {
+    ExtraAckedEvent new_event;
+    new_event.extra_acked = new_height;
+    new_event.round = new_time;
+    max_ack_height_filter_.Reset(new_event, new_time);
+  }
+
+  void SetAckAggregationBandwidthThreshold(double threshold) {
+    ack_aggregation_bandwidth_threshold_ = threshold;
+  }
+
+  void SetStartNewAggregationEpochAfterFullRound(bool value) {
+    start_new_aggregation_epoch_after_full_round_ = value;
+  }
+
+  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
+    reduce_extra_acked_on_bandwidth_increase_ = value;
+  }
+
+  double ack_aggregation_bandwidth_threshold() const {
+    return ack_aggregation_bandwidth_threshold_;
+  }
+
+  uint64_t num_ack_aggregation_epochs() const {
+    return num_ack_aggregation_epochs_;
+  }
+
+ private:
+  // Tracks the maximum number of bytes acked faster than the estimated
+  // bandwidth.
+  using MaxAckHeightFilter =
+      WindowedFilter<ExtraAckedEvent, MaxFilter<ExtraAckedEvent>,
+                     QuicRoundTripCount, QuicRoundTripCount>;
+  MaxAckHeightFilter max_ack_height_filter_;
+
+  // The time this aggregation started and the number of bytes acked during it.
+  QuicTime aggregation_epoch_start_time_ = QuicTime::Zero();
+  QuicByteCount aggregation_epoch_bytes_ = 0;
+  // The last sent packet number before the current aggregation epoch started.
+  QuicPacketNumber last_sent_packet_number_before_epoch_;
+  // The number of ack aggregation epochs ever started, including the ongoing
+  // one. Stats only.
+  uint64_t num_ack_aggregation_epochs_ = 0;
+  double ack_aggregation_bandwidth_threshold_ =
+      GetQuicFlag(FLAGS_quic_ack_aggregation_bandwidth_threshold);
+  bool start_new_aggregation_epoch_after_full_round_ = false;
+  bool reduce_extra_acked_on_bandwidth_increase_ = false;
+};
+
+// An interface common to any class that can provide bandwidth samples from the
+// information per individual acknowledged packet.
+class QUIC_EXPORT_PRIVATE BandwidthSamplerInterface {
+ public:
+  virtual ~BandwidthSamplerInterface() {}
+
+  // Inputs the sent packet information into the sampler. Assumes that all
+  // packets are sent in order. The information about the packet will not be
+  // released from the sampler until it the packet is either acknowledged or
+  // declared lost.
+  virtual void OnPacketSent(
+      QuicTime sent_time,
+      QuicPacketNumber packet_number,
+      QuicByteCount bytes,
+      QuicByteCount bytes_in_flight,
+      HasRetransmittableData has_retransmittable_data) = 0;
+
+  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
+
+  struct QUIC_NO_EXPORT CongestionEventSample {
+    // The maximum bandwidth sample from all acked packets.
+    // QuicBandwidth::Zero() if no samples are available.
+    QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
+    // Whether |sample_max_bandwidth| is from a app-limited sample.
+    bool sample_is_app_limited = false;
+    // The minimum rtt sample from all acked packets.
+    // QuicTime::Delta::Infinite() if no samples are available.
+    QuicTime::Delta sample_rtt = QuicTime::Delta::Infinite();
+    // For each packet p in acked packets, this is the max value of INFLIGHT(p),
+    // where INFLIGHT(p) is the number of bytes acked while p is inflight.
+    QuicByteCount sample_max_inflight = 0;
+    // The send state of the largest packet in acked_packets, unless it is
+    // empty. If acked_packets is empty, it's the send state of the largest
+    // packet in lost_packets.
+    SendTimeState last_packet_send_state;
+    // The number of extra bytes acked from this ack event, compared to what is
+    // expected from the flow's bandwidth. Larger value means more ack
+    // aggregation.
+    QuicByteCount extra_acked = 0;
+  };
+  // Notifies the sampler that at |ack_time|, all packets in |acked_packets|
+  // have been acked, and all packets in |lost_packets| have been lost.
+  // See the comments in CongestionEventSample for the return value.
+  // |max_bandwidth| is the windowed maximum observed bandwidth.
+  // |est_bandwidth_upper_bound| is an upper bound of estimated bandwidth used
+  // to calculate extra_acked.
+  virtual CongestionEventSample OnCongestionEvent(
+      QuicTime ack_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      QuicBandwidth max_bandwidth,
+      QuicBandwidth est_bandwidth_upper_bound,
+      QuicRoundTripCount round_trip_count) = 0;
+
+  // Informs the sampler that the connection is currently app-limited, causing
+  // the sampler to enter the app-limited phase.  The phase will expire by
+  // itself.
+  virtual void OnAppLimited() = 0;
+
+  // Remove all the packets lower than the specified packet number.
+  virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0;
+
+  // Total number of bytes sent/acked/lost/neutered in the connection.
+  virtual QuicByteCount total_bytes_sent() const = 0;
+  virtual QuicByteCount total_bytes_acked() const = 0;
+  virtual QuicByteCount total_bytes_lost() const = 0;
+  virtual QuicByteCount total_bytes_neutered() const = 0;
+
+  // Application-limited information exported for debugging.
+  virtual bool is_app_limited() const = 0;
+
+  virtual QuicPacketNumber end_of_app_limited_phase() const = 0;
+};
+
+// BandwidthSampler keeps track of sent and acknowledged packets and outputs a
+// bandwidth sample for every packet acknowledged. The samples are taken for
+// individual packets, and are not filtered; the consumer has to filter the
+// bandwidth samples itself. In certain cases, the sampler will locally severely
+// underestimate the bandwidth, hence a maximum filter with a size of at least
+// one RTT is recommended.
+//
+// This class bases its samples on the slope of two curves: the number of bytes
+// sent over time, and the number of bytes acknowledged as received over time.
+// It produces a sample of both slopes for every packet that gets acknowledged,
+// based on a slope between two points on each of the corresponding curves. Note
+// that due to the packet loss, the number of bytes on each curve might get
+// further and further away from each other, meaning that it is not feasible to
+// compare byte values coming from different curves with each other.
+//
+// The obvious points for measuring slope sample are the ones corresponding to
+// the packet that was just acknowledged. Let us denote them as S_1 (point at
+// which the current packet was sent) and A_1 (point at which the current packet
+// was acknowledged). However, taking a slope requires two points on each line,
+// so estimating bandwidth requires picking a packet in the past with respect to
+// which the slope is measured.
+//
+// For that purpose, BandwidthSampler always keeps track of the most recently
+// acknowledged packet, and records it together with every outgoing packet.
+// When a packet gets acknowledged (A_1), it has not only information about when
+// it itself was sent (S_1), but also the information about a previously
+// acknowledged packet before it was sent (S_0 and A_0).
+//
+// Based on that data, send and ack rate are estimated as:
+//   send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0))
+//   ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0))
+//
+// Here, the ack rate is intuitively the rate we want to treat as bandwidth.
+// However, in certain cases (e.g. ack compression) the ack rate at a point may
+// end up higher than the rate at which the data was originally sent, which is
+// not indicative of the real bandwidth. Hence, we use the send rate as an upper
+// bound, and the sample value is
+//   rate_sample = min(send_rate, ack_rate)
+//
+// An important edge case handled by the sampler is tracking the app-limited
+// samples. There are multiple meaning of "app-limited" used interchangeably,
+// hence it is important to understand and to be able to distinguish between
+// them.
+//
+// Meaning 1: connection state. The connection is said to be app-limited when
+// there is no outstanding data to send. This means that certain bandwidth
+// samples in the future would not be an accurate indication of the link
+// capacity, and it is important to inform consumer about that. Whenever
+// connection becomes app-limited, the sampler is notified via OnAppLimited()
+// method.
+//
+// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth
+// sampler becomes notified about the connection being app-limited, it enters
+// app-limited phase. In that phase, all *sent* packets are marked as
+// app-limited. Note that the connection itself does not have to be
+// app-limited during the app-limited phase, and in fact it will not be
+// (otherwise how would it send packets?). The boolean flag below indicates
+// whether the sampler is in that phase.
+//
+// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is
+// sent during the app-limited phase, the resulting sample related to the
+// packet will be marked as app-limited.
+//
+// With the terminology issue out of the way, let us consider the question of
+// what kind of situation it addresses.
+//
+// Consider a scenario where we first send packets 1 to 20 at a regular
+// bandwidth, and then immediately run out of data. After a few seconds, we send
+// packets 21 to 60, and only receive ack for 21 between sending packets 40 and
+// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0
+// we use to compute the slope is going to be packet 20, a few seconds apart
+// from the current packet, hence the resulting estimate would be extremely low
+// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21,
+// meaning that the bandwidth sample would exclude the quiescence.
+//
+// Based on the analysis of that scenario, we implement the following rule: once
+// OnAppLimited() is called, all sent packets will produce app-limited samples
+// up until an ack for a packet that was sent after OnAppLimited() was called.
+// Note that while the scenario above is not the only scenario when the
+// connection is app-limited, the approach works in other cases too.
+class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
+ public:
+  BandwidthSampler(const QuicUnackedPacketMap* unacked_packet_map,
+                   QuicRoundTripCount max_height_tracker_window_length);
+
+  // Copy states from |other|. This is useful when changing send algorithms in
+  // the middle of a connection.
+  BandwidthSampler(const BandwidthSampler& other);
+  ~BandwidthSampler() override;
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    QuicByteCount bytes_in_flight,
+                    HasRetransmittableData has_retransmittable_data) override;
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+
+  CongestionEventSample OnCongestionEvent(
+      QuicTime ack_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      QuicBandwidth max_bandwidth,
+      QuicBandwidth est_bandwidth_upper_bound,
+      QuicRoundTripCount round_trip_count) override;
+  QuicByteCount OnAckEventEnd(QuicBandwidth bandwidth_estimate,
+                              bool is_new_max_bandwidth,
+                              QuicRoundTripCount round_trip_count);
+
+  void OnAppLimited() override;
+
+  void RemoveObsoletePackets(QuicPacketNumber least_unacked) override;
+
+  QuicByteCount total_bytes_sent() const override;
+  QuicByteCount total_bytes_acked() const override;
+  QuicByteCount total_bytes_lost() const override;
+  QuicByteCount total_bytes_neutered() const override;
+
+  bool is_app_limited() const override;
+
+  QuicPacketNumber end_of_app_limited_phase() const override;
+
+  QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); }
+
+  uint64_t num_ack_aggregation_epochs() const {
+    return max_ack_height_tracker_.num_ack_aggregation_epochs();
+  }
+
+  void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) {
+    max_ack_height_tracker_.SetFilterWindowLength(length);
+  }
+
+  void ResetMaxAckHeightTracker(QuicByteCount new_height,
+                                QuicRoundTripCount new_time) {
+    max_ack_height_tracker_.Reset(new_height, new_time);
+  }
+
+  void SetStartNewAggregationEpochAfterFullRound(bool value) {
+    max_ack_height_tracker_.SetStartNewAggregationEpochAfterFullRound(value);
+  }
+
+  void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
+    limit_max_ack_height_tracker_by_send_rate_ = value;
+  }
+
+  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
+    max_ack_height_tracker_.SetReduceExtraAckedOnBandwidthIncrease(value);
+  }
+
+  // AckPoint represents a point on the ack line.
+  struct QUIC_NO_EXPORT AckPoint {
+    QuicTime ack_time = QuicTime::Zero();
+    QuicByteCount total_bytes_acked = 0;
+
+    friend QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
+                                                   const AckPoint& ack_point) {
+      return os << ack_point.ack_time << ":" << ack_point.total_bytes_acked;
+    }
+  };
+
+  // RecentAckPoints maintains the most recent 2 ack points at distinct times.
+  class QUIC_NO_EXPORT RecentAckPoints {
+   public:
+    void Update(QuicTime ack_time, QuicByteCount total_bytes_acked) {
+      QUICHE_DCHECK_GE(total_bytes_acked, ack_points_[1].total_bytes_acked);
+
+      if (ack_time < ack_points_[1].ack_time) {
+        // This can only happen when time goes backwards, we use the smaller
+        // timestamp for the most recent ack point in that case.
+        // TODO(wub): Add a QUIC_BUG if ack time stops going backwards.
+        ack_points_[1].ack_time = ack_time;
+      } else if (ack_time > ack_points_[1].ack_time) {
+        ack_points_[0] = ack_points_[1];
+        ack_points_[1].ack_time = ack_time;
+      }
+
+      ack_points_[1].total_bytes_acked = total_bytes_acked;
+    }
+
+    void Clear() { ack_points_[0] = ack_points_[1] = AckPoint(); }
+
+    const AckPoint& MostRecentPoint() const { return ack_points_[1]; }
+
+    const AckPoint& LessRecentPoint() const {
+      if (ack_points_[0].total_bytes_acked != 0) {
+        return ack_points_[0];
+      }
+
+      return ack_points_[1];
+    }
+
+   private:
+    AckPoint ack_points_[2];
+  };
+
+  void EnableOverestimateAvoidance();
+  bool IsOverestimateAvoidanceEnabled() const {
+    return overestimate_avoidance_;
+  }
+
+ private:
+  friend class test::BandwidthSamplerPeer;
+
+  // ConnectionStateOnSentPacket represents the information about a sent packet
+  // and the state of the connection at the moment the packet was sent,
+  // specifically the information about the most recently acknowledged packet at
+  // that moment.
+  struct QUIC_EXPORT_PRIVATE ConnectionStateOnSentPacket {
+    // Time at which the packet is sent.
+    QuicTime sent_time;
+
+    // Size of the packet.
+    QuicByteCount size;
+
+    // The value of |total_bytes_sent_at_last_acked_packet_| at the time the
+    // packet was sent.
+    QuicByteCount total_bytes_sent_at_last_acked_packet;
+
+    // The value of |last_acked_packet_sent_time_| at the time the packet was
+    // sent.
+    QuicTime last_acked_packet_sent_time;
+
+    // The value of |last_acked_packet_ack_time_| at the time the packet was
+    // sent.
+    QuicTime last_acked_packet_ack_time;
+
+    // Send time states that are returned to the congestion controller when the
+    // packet is acked or lost.
+    SendTimeState send_time_state;
+
+    // Snapshot constructor. Records the current state of the bandwidth
+    // sampler.
+    // |bytes_in_flight| is the bytes in flight right after the packet is sent.
+    ConnectionStateOnSentPacket(QuicTime sent_time,
+                                QuicByteCount size,
+                                QuicByteCount bytes_in_flight,
+                                const BandwidthSampler& sampler)
+        : sent_time(sent_time),
+          size(size),
+          total_bytes_sent_at_last_acked_packet(
+              sampler.total_bytes_sent_at_last_acked_packet_),
+          last_acked_packet_sent_time(sampler.last_acked_packet_sent_time_),
+          last_acked_packet_ack_time(sampler.last_acked_packet_ack_time_),
+          send_time_state(sampler.is_app_limited_,
+                          sampler.total_bytes_sent_,
+                          sampler.total_bytes_acked_,
+                          sampler.total_bytes_lost_,
+                          bytes_in_flight) {}
+
+    // Default constructor.  Required to put this structure into
+    // PacketNumberIndexedQueue.
+    ConnectionStateOnSentPacket()
+        : sent_time(QuicTime::Zero()),
+          size(0),
+          total_bytes_sent_at_last_acked_packet(0),
+          last_acked_packet_sent_time(QuicTime::Zero()),
+          last_acked_packet_ack_time(QuicTime::Zero()) {}
+
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const ConnectionStateOnSentPacket& p) {
+      os << "{sent_time:" << p.sent_time << ", size:" << p.size
+         << ", total_bytes_sent_at_last_acked_packet:"
+         << p.total_bytes_sent_at_last_acked_packet
+         << ", last_acked_packet_sent_time:" << p.last_acked_packet_sent_time
+         << ", last_acked_packet_ack_time:" << p.last_acked_packet_ack_time
+         << ", send_time_state:" << p.send_time_state << "}";
+      return os;
+    }
+  };
+
+  BandwidthSample OnPacketAcknowledged(QuicTime ack_time,
+                                       QuicPacketNumber packet_number);
+
+  SendTimeState OnPacketLost(QuicPacketNumber packet_number,
+                             QuicPacketLength bytes_lost);
+
+  // Copy a subset of the (private) ConnectionStateOnSentPacket to the (public)
+  // SendTimeState. Always set send_time_state->is_valid to true.
+  void SentPacketToSendTimeState(const ConnectionStateOnSentPacket& sent_packet,
+                                 SendTimeState* send_time_state) const;
+
+  // Choose the best a0 from |a0_candidates_| to calculate the ack rate.
+  // |total_bytes_acked| is the total bytes acked when the packet being acked is
+  // sent. The best a0 is chosen as follows:
+  // - If there's only one candidate, use it.
+  // - If there are multiple candidates, let a[n] be the nth candidate, and
+  //   a[n-1].total_bytes_acked <= |total_bytes_acked| < a[n].total_bytes_acked,
+  //   use a[n-1].
+  // - If all candidates's total_bytes_acked is > |total_bytes_acked|, use a[0].
+  //   This may happen when acks are received out of order, and ack[n] caused
+  //   some candidates of ack[n-x] to be removed.
+  // - If all candidates's total_bytes_acked is <= |total_bytes_acked|, use
+  //   a[a.size()-1].
+  bool ChooseA0Point(QuicByteCount total_bytes_acked, AckPoint* a0);
+
+  // The total number of congestion controlled bytes sent during the connection.
+  QuicByteCount total_bytes_sent_;
+
+  // The total number of congestion controlled bytes which were acknowledged.
+  QuicByteCount total_bytes_acked_;
+
+  // The total number of congestion controlled bytes which were lost.
+  QuicByteCount total_bytes_lost_;
+
+  // The total number of congestion controlled bytes which have been neutered.
+  QuicByteCount total_bytes_neutered_;
+
+  // The value of |total_bytes_sent_| at the time the last acknowledged packet
+  // was sent. Valid only when |last_acked_packet_sent_time_| is valid.
+  QuicByteCount total_bytes_sent_at_last_acked_packet_;
+
+  // The time at which the last acknowledged packet was sent. Set to
+  // QuicTime::Zero() if no valid timestamp is available.
+  QuicTime last_acked_packet_sent_time_;
+
+  // The time at which the most recent packet was acknowledged.
+  QuicTime last_acked_packet_ack_time_;
+
+  // The most recently sent packet.
+  QuicPacketNumber last_sent_packet_;
+
+  // The most recently acked packet.
+  QuicPacketNumber last_acked_packet_;
+
+  // Indicates whether the bandwidth sampler is currently in an app-limited
+  // phase.
+  bool is_app_limited_;
+
+  // The packet that will be acknowledged after this one will cause the sampler
+  // to exit the app-limited phase.
+  QuicPacketNumber end_of_app_limited_phase_;
+
+  // Record of the connection state at the point where each packet in flight was
+  // sent, indexed by the packet number.
+  PacketNumberIndexedQueue<ConnectionStateOnSentPacket> connection_state_map_;
+
+  RecentAckPoints recent_ack_points_;
+  quiche::QuicheCircularDeque<AckPoint> a0_candidates_;
+
+  // Maximum number of tracked packets.
+  const QuicPacketCount max_tracked_packets_;
+
+  // The main unacked packet map.  Used for outputting extra debugging details.
+  // May be null.
+  // TODO(vasilvv): remove this once it's no longer useful for debugging.
+  const QuicUnackedPacketMap* unacked_packet_map_;
+
+  // Handles the actual bandwidth calculations, whereas the outer method handles
+  // retrieving and removing |sent_packet|.
+  BandwidthSample OnPacketAcknowledgedInner(
+      QuicTime ack_time,
+      QuicPacketNumber packet_number,
+      const ConnectionStateOnSentPacket& sent_packet);
+
+  MaxAckHeightTracker max_ack_height_tracker_;
+  QuicByteCount total_bytes_acked_after_last_ack_event_;
+
+  // True if connection option 'BSAO' is set.
+  bool overestimate_avoidance_;
+
+  // True if connection option 'BBRB' is set.
+  bool limit_max_ack_height_tracker_by_send_rate_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
diff --git a/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc b/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc
new file mode 100644
index 0000000..6089232
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc
@@ -0,0 +1,889 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include <cstdint>
+#include <set>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class BandwidthSamplerPeer {
+ public:
+  static size_t GetNumberOfTrackedPackets(const BandwidthSampler& sampler) {
+    return sampler.connection_state_map_.number_of_present_entries();
+  }
+
+  static QuicByteCount GetPacketSize(const BandwidthSampler& sampler,
+                                     QuicPacketNumber packet_number) {
+    return sampler.connection_state_map_.GetEntry(packet_number)->size;
+  }
+};
+
+const QuicByteCount kRegularPacketSize = 1280;
+// Enforce divisibility for some of the tests.
+static_assert((kRegularPacketSize & 31) == 0,
+              "kRegularPacketSize has to be five times divisible by 2");
+
+struct TestParameters {
+  bool overestimate_avoidance;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParameters& p) {
+  return p.overestimate_avoidance ? "enable_overestimate_avoidance"
+                                  : "no_enable_overestimate_avoidance";
+}
+
+// A test fixture with utility methods for BandwidthSampler tests.
+class BandwidthSamplerTest : public QuicTestWithParam<TestParameters> {
+ protected:
+  BandwidthSamplerTest()
+      : sampler_(nullptr, /*max_height_tracker_window_length=*/0),
+        sampler_app_limited_at_start_(sampler_.is_app_limited()),
+        bytes_in_flight_(0),
+        max_bandwidth_(QuicBandwidth::Zero()),
+        est_bandwidth_upper_bound_(QuicBandwidth::Infinite()),
+        round_trip_count_(0) {
+    // Ensure that the clock does not start at zero.
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    if (GetParam().overestimate_avoidance) {
+      sampler_.EnableOverestimateAvoidance();
+    }
+  }
+
+  MockClock clock_;
+  BandwidthSampler sampler_;
+  bool sampler_app_limited_at_start_;
+  QuicByteCount bytes_in_flight_;
+  QuicBandwidth max_bandwidth_;  // Max observed bandwidth from acks.
+  QuicBandwidth est_bandwidth_upper_bound_;
+  QuicRoundTripCount round_trip_count_;  // Needed to calculate extra_acked.
+
+  QuicByteCount PacketsToBytes(QuicPacketCount packet_count) {
+    return packet_count * kRegularPacketSize;
+  }
+
+  void SendPacketInner(uint64_t packet_number,
+                       QuicByteCount bytes,
+                       HasRetransmittableData has_retransmittable_data) {
+    sampler_.OnPacketSent(clock_.Now(), QuicPacketNumber(packet_number), bytes,
+                          bytes_in_flight_, has_retransmittable_data);
+    if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA) {
+      bytes_in_flight_ += bytes;
+    }
+  }
+
+  void SendPacket(uint64_t packet_number) {
+    SendPacketInner(packet_number, kRegularPacketSize,
+                    HAS_RETRANSMITTABLE_DATA);
+  }
+
+  BandwidthSample AckPacketInner(uint64_t packet_number) {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
+    bytes_in_flight_ -= size;
+    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+        clock_.Now(), {MakeAckedPacket(packet_number)}, {}, max_bandwidth_,
+        est_bandwidth_upper_bound_, round_trip_count_);
+    max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
+    BandwidthSample bandwidth_sample;
+    bandwidth_sample.bandwidth = sample.sample_max_bandwidth;
+    bandwidth_sample.rtt = sample.sample_rtt;
+    bandwidth_sample.state_at_send = sample.last_packet_send_state;
+    EXPECT_TRUE(bandwidth_sample.state_at_send.is_valid);
+    return bandwidth_sample;
+  }
+
+  AckedPacket MakeAckedPacket(uint64_t packet_number) const {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
+    return AckedPacket(QuicPacketNumber(packet_number), size, clock_.Now());
+  }
+
+  LostPacket MakeLostPacket(uint64_t packet_number) const {
+    return LostPacket(QuicPacketNumber(packet_number),
+                      BandwidthSamplerPeer::GetPacketSize(
+                          sampler_, QuicPacketNumber(packet_number)));
+  }
+
+  // Acknowledge receipt of a packet and expect it to be not app-limited.
+  QuicBandwidth AckPacket(uint64_t packet_number) {
+    BandwidthSample sample = AckPacketInner(packet_number);
+    return sample.bandwidth;
+  }
+
+  BandwidthSampler::CongestionEventSample OnCongestionEvent(
+      std::set<uint64_t> acked_packet_numbers,
+      std::set<uint64_t> lost_packet_numbers) {
+    AckedPacketVector acked_packets;
+    for (auto it = acked_packet_numbers.begin();
+         it != acked_packet_numbers.end(); ++it) {
+      acked_packets.push_back(MakeAckedPacket(*it));
+      bytes_in_flight_ -= acked_packets.back().bytes_acked;
+    }
+
+    LostPacketVector lost_packets;
+    for (auto it = lost_packet_numbers.begin(); it != lost_packet_numbers.end();
+         ++it) {
+      lost_packets.push_back(MakeLostPacket(*it));
+      bytes_in_flight_ -= lost_packets.back().bytes_lost;
+    }
+
+    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+        clock_.Now(), acked_packets, lost_packets, max_bandwidth_,
+        est_bandwidth_upper_bound_, round_trip_count_);
+    max_bandwidth_ = std::max(max_bandwidth_, sample.sample_max_bandwidth);
+    return sample;
+  }
+
+  SendTimeState LosePacket(uint64_t packet_number) {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
+    bytes_in_flight_ -= size;
+    LostPacket lost_packet(QuicPacketNumber(packet_number), size);
+    BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+        clock_.Now(), {}, {lost_packet}, max_bandwidth_,
+        est_bandwidth_upper_bound_, round_trip_count_);
+    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
+    EXPECT_EQ(sample.sample_max_bandwidth, QuicBandwidth::Zero());
+    EXPECT_EQ(sample.sample_rtt, QuicTime::Delta::Infinite());
+    return sample.last_packet_send_state;
+  }
+
+  // Sends one packet and acks it.  Then, send 20 packets.  Finally, send
+  // another 20 packets while acknowledging previous 20.
+  void Send40PacketsAndAckFirst20(QuicTime::Delta time_between_packets) {
+    // Send 20 packets at a constant inter-packet time.
+    for (int i = 1; i <= 20; i++) {
+      SendPacket(i);
+      clock_.AdvanceTime(time_between_packets);
+    }
+
+    // Ack packets 1 to 20, while sending new packets at the same rate as
+    // before.
+    for (int i = 1; i <= 20; i++) {
+      AckPacket(i);
+      SendPacket(i + 20);
+      clock_.AdvanceTime(time_between_packets);
+    }
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    BandwidthSamplerTests,
+    BandwidthSamplerTest,
+    testing::Values(TestParameters{/*overestimate_avoidance=*/false},
+                    TestParameters{/*overestimate_avoidance=*/true}),
+    testing::PrintToStringParamName());
+
+// Test the sampler in a simple stop-and-wait sender setting.
+TEST_P(BandwidthSamplerTest, SendAndWait) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromBytesPerSecond(kRegularPacketSize * 100);
+
+  // Send packets at the constant bandwidth.
+  for (int i = 1; i < 20; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    QuicBandwidth current_sample = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, current_sample);
+  }
+
+  // Send packets at the exponentially decreasing bandwidth.
+  for (int i = 20; i < 25; i++) {
+    time_between_packets = time_between_packets * 2;
+    expected_bandwidth = expected_bandwidth * 0.5;
+
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    QuicBandwidth current_sample = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, current_sample);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(25));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+TEST_P(BandwidthSamplerTest, SendTimeState) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+
+  // Send packets 1-5.
+  for (int i = 1; i <= 5; i++) {
+    SendPacket(i);
+    EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packet 1.
+  SendTimeState send_time_state = AckPacketInner(1).state_at_send;
+  EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_sent);
+  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+  EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_acked());
+
+  // Lose packet 2.
+  send_time_state = LosePacket(2);
+  EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_sent);
+  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+  EXPECT_EQ(PacketsToBytes(1), sampler_.total_bytes_lost());
+
+  // Lose packet 3.
+  send_time_state = LosePacket(3);
+  EXPECT_EQ(PacketsToBytes(3), send_time_state.total_bytes_sent);
+  EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+  EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+  EXPECT_EQ(PacketsToBytes(2), sampler_.total_bytes_lost());
+
+  // Send packets 6-10.
+  for (int i = 6; i <= 10; i++) {
+    SendPacket(i);
+    EXPECT_EQ(PacketsToBytes(i), sampler_.total_bytes_sent());
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack all inflight packets.
+  QuicPacketCount acked_packet_count = 1;
+  EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
+  for (int i = 4; i <= 10; i++) {
+    send_time_state = AckPacketInner(i).state_at_send;
+    ++acked_packet_count;
+    EXPECT_EQ(PacketsToBytes(acked_packet_count), sampler_.total_bytes_acked());
+    EXPECT_EQ(PacketsToBytes(i), send_time_state.total_bytes_sent);
+    if (i <= 5) {
+      EXPECT_EQ(0u, send_time_state.total_bytes_acked);
+      EXPECT_EQ(0u, send_time_state.total_bytes_lost);
+    } else {
+      EXPECT_EQ(PacketsToBytes(1), send_time_state.total_bytes_acked);
+      EXPECT_EQ(PacketsToBytes(2), send_time_state.total_bytes_lost);
+    }
+
+    // This equation works because there is no neutered bytes.
+    EXPECT_EQ(send_time_state.total_bytes_sent -
+                  send_time_state.total_bytes_acked -
+                  send_time_state.total_bytes_lost,
+              send_time_state.bytes_in_flight);
+
+    clock_.AdvanceTime(time_between_packets);
+  }
+}
+
+// Test the sampler during regular windowed sender scenario with fixed
+// CWND of 20.
+TEST_P(BandwidthSamplerTest, SendPaced) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  Send40PacketsAndAckFirst20(time_between_packets);
+
+  // Ack the packets 21 to 40, arriving at the correct bandwidth.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 21; i <= 40; i++) {
+    last_bandwidth = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, last_bandwidth) << "i is " << i;
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the sampler in a scenario where 50% of packets is consistently lost.
+TEST_P(BandwidthSamplerTest, SendWithLosses) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
+
+  // Send 20 packets, each 1 ms apart.
+  for (int i = 1; i <= 20; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packets 1 to 20, losing every even-numbered packet, while sending new
+  // packets at the same rate as before.
+  for (int i = 1; i <= 20; i++) {
+    if (i % 2 == 0) {
+      AckPacket(i);
+    } else {
+      LosePacket(i);
+    }
+    SendPacket(i + 20);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack the packets 21 to 40 with the same loss pattern.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 21; i <= 40; i++) {
+    if (i % 2 == 0) {
+      last_bandwidth = AckPacket(i);
+      EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    } else {
+      LosePacket(i);
+    }
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the sampler in a scenario where the 50% of packets are not
+// congestion controlled (specifically, non-retransmittable data is not
+// congestion controlled).  Should be functionally consistent in behavior with
+// the SendWithLosses test.
+TEST_P(BandwidthSamplerTest, NotCongestionControlled) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
+
+  // Send 20 packets, each 1 ms apart. Every even packet is not congestion
+  // controlled.
+  for (int i = 1; i <= 20; i++) {
+    SendPacketInner(
+        i, kRegularPacketSize,
+        i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ensure only congestion controlled packets are tracked.
+  EXPECT_EQ(10u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+
+  // Ack packets 2 to 21, ignoring every even-numbered packet, while sending new
+  // packets at the same rate as before.
+  for (int i = 1; i <= 20; i++) {
+    if (i % 2 == 0) {
+      AckPacket(i);
+    }
+    SendPacketInner(
+        i + 20, kRegularPacketSize,
+        i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack the packets 22 to 41 with the same congestion controlled pattern.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 21; i <= 40; i++) {
+    if (i % 2 == 0) {
+      last_bandwidth = AckPacket(i);
+      EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    }
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  // Since only congestion controlled packets are entered into the map, it has
+  // to be empty at this point.
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Simulate a situation where ACKs arrive in burst and earlier than usual, thus
+// producing an ACK rate which is higher than the original send rate.
+TEST_P(BandwidthSamplerTest, CompressedAck) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  Send40PacketsAndAckFirst20(time_between_packets);
+
+  // Simulate an RTT somewhat lower than the one for 1-to-21 transmission.
+  clock_.AdvanceTime(time_between_packets * 15);
+
+  // Ack the packets 21 to 40 almost immediately at once.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  QuicTime::Delta ridiculously_small_time_delta =
+      QuicTime::Delta::FromMicroseconds(20);
+  for (int i = 21; i <= 40; i++) {
+    last_bandwidth = AckPacket(i);
+    clock_.AdvanceTime(ridiculously_small_time_delta);
+  }
+  EXPECT_EQ(expected_bandwidth, last_bandwidth);
+
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(41));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Tests receiving ACK packets in the reverse order.
+TEST_P(BandwidthSamplerTest, ReorderedAck) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  Send40PacketsAndAckFirst20(time_between_packets);
+
+  // Ack the packets 21 to 40 in the reverse order, while sending packets 41 to
+  // 60.
+  QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
+  for (int i = 0; i < 20; i++) {
+    last_bandwidth = AckPacket(40 - i);
+    EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    SendPacket(41 + i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack the packets 41 to 60, now in the regular order.
+  for (int i = 41; i <= 60; i++) {
+    last_bandwidth = AckPacket(i);
+    EXPECT_EQ(expected_bandwidth, last_bandwidth);
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(61));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the app-limited logic.
+TEST_P(BandwidthSamplerTest, AppLimited) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  QuicBandwidth expected_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize);
+
+  // Send 20 packets at a constant inter-packet time.
+  for (int i = 1; i <= 20; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packets 1 to 20, while sending new packets at the same rate as
+  // before.
+  for (int i = 1; i <= 20; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_EQ(sample.state_at_send.is_app_limited,
+              sampler_app_limited_at_start_);
+    SendPacket(i + 20);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // We are now app-limited. Ack 21 to 40 as usual, but do not send anything for
+  // now.
+  sampler_.OnAppLimited();
+  for (int i = 21; i <= 40; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_FALSE(sample.state_at_send.is_app_limited);
+    EXPECT_EQ(expected_bandwidth, sample.bandwidth);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Enter quiescence.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  // Send packets 41 to 60, all of which would be marked as app-limited.
+  for (int i = 41; i <= 60; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Ack packets 41 to 60, while sending packets 61 to 80.  41 to 60 should be
+  // app-limited and underestimate the bandwidth due to that.
+  for (int i = 41; i <= 60; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_TRUE(sample.state_at_send.is_app_limited);
+    EXPECT_LT(sample.bandwidth, 0.7f * expected_bandwidth);
+
+    SendPacket(i + 20);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // Run out of packets, and then ack packet 61 to 80, all of which should have
+  // correct non-app-limited samples.
+  for (int i = 61; i <= 80; i++) {
+    BandwidthSample sample = AckPacketInner(i);
+    EXPECT_FALSE(sample.state_at_send.is_app_limited);
+    EXPECT_EQ(sample.bandwidth, expected_bandwidth);
+    clock_.AdvanceTime(time_between_packets);
+  }
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(81));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  EXPECT_EQ(0u, bytes_in_flight_);
+}
+
+// Test the samples taken at the first flight of packets sent.
+TEST_P(BandwidthSamplerTest, FirstRoundTrip) {
+  const QuicTime::Delta time_between_packets =
+      QuicTime::Delta::FromMilliseconds(1);
+  const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(800);
+  const int num_packets = 10;
+  const QuicByteCount num_bytes = kRegularPacketSize * num_packets;
+  const QuicBandwidth real_bandwidth =
+      QuicBandwidth::FromBytesAndTimeDelta(num_bytes, rtt);
+
+  for (int i = 1; i <= 10; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  clock_.AdvanceTime(rtt - num_packets * time_between_packets);
+
+  QuicBandwidth last_sample = QuicBandwidth::Zero();
+  for (int i = 1; i <= 10; i++) {
+    QuicBandwidth sample = AckPacket(i);
+    EXPECT_GT(sample, last_sample);
+    last_sample = sample;
+    clock_.AdvanceTime(time_between_packets);
+  }
+
+  // The final measured sample for the first flight of sample is expected to be
+  // smaller than the real bandwidth, yet it should not lose more than 10%. The
+  // specific value of the error depends on the difference between the RTT and
+  // the time it takes to exhaust the congestion window (i.e. in the limit when
+  // all packets are sent simultaneously, last sample would indicate the real
+  // bandwidth).
+  EXPECT_LT(last_sample, real_bandwidth);
+  EXPECT_GT(last_sample, 0.9f * real_bandwidth);
+}
+
+// Test sampler's ability to remove obsolete packets.
+TEST_P(BandwidthSamplerTest, RemoveObsoletePackets) {
+  SendPacket(1);
+  SendPacket(2);
+  SendPacket(3);
+  SendPacket(4);
+  SendPacket(5);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+
+  EXPECT_EQ(5u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(4));
+  EXPECT_EQ(2u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  LosePacket(4);
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(5));
+
+  EXPECT_EQ(1u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+  AckPacket(5);
+
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(6));
+
+  EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
+}
+
+TEST_P(BandwidthSamplerTest, NeuterPacket) {
+  SendPacket(1);
+  EXPECT_EQ(0u, sampler_.total_bytes_neutered());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  sampler_.OnPacketNeutered(QuicPacketNumber(1));
+  EXPECT_LT(0u, sampler_.total_bytes_neutered());
+  EXPECT_EQ(0u, sampler_.total_bytes_acked());
+
+  // If packet 1 is acked it should not produce a bandwidth sample.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+      clock_.Now(),
+      {AckedPacket(QuicPacketNumber(1), kRegularPacketSize, clock_.Now())}, {},
+      max_bandwidth_, est_bandwidth_upper_bound_, round_trip_count_);
+  EXPECT_EQ(0u, sampler_.total_bytes_acked());
+  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
+  EXPECT_FALSE(sample.sample_is_app_limited);
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
+  EXPECT_EQ(0u, sample.sample_max_inflight);
+  EXPECT_EQ(0u, sample.extra_acked);
+}
+
+TEST_P(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
+  // Make sure a default constructed CongestionEventSample has the correct
+  // initial values for BandwidthSampler::OnCongestionEvent() to work.
+  BandwidthSampler::CongestionEventSample sample;
+
+  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
+  EXPECT_FALSE(sample.sample_is_app_limited);
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
+  EXPECT_EQ(0u, sample.sample_max_inflight);
+  EXPECT_EQ(0u, sample.extra_acked);
+}
+
+// 1) Send 2 packets, 2) Ack both in 1 event, 3) Repeat.
+TEST_P(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      kRegularPacketSize, time_between_packets);
+
+  for (uint64_t i = 1; i < 21; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    if (i % 2 != 0) {
+      continue;
+    }
+
+    BandwidthSampler::CongestionEventSample sample =
+        OnCongestionEvent({i - 1, i}, {});
+    EXPECT_EQ(sending_rate, sample.sample_max_bandwidth);
+    EXPECT_EQ(time_between_packets, sample.sample_rtt);
+    EXPECT_EQ(2 * kRegularPacketSize, sample.sample_max_inflight);
+    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
+    EXPECT_EQ(2 * kRegularPacketSize,
+              sample.last_packet_send_state.bytes_in_flight);
+    EXPECT_EQ(i * kRegularPacketSize,
+              sample.last_packet_send_state.total_bytes_sent);
+    EXPECT_EQ((i - 2) * kRegularPacketSize,
+              sample.last_packet_send_state.total_bytes_acked);
+    EXPECT_EQ(0u, sample.last_packet_send_state.total_bytes_lost);
+    sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
+  }
+}
+
+TEST_P(BandwidthSamplerTest, LoseEveryOtherPacket) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      kRegularPacketSize, time_between_packets);
+
+  for (uint64_t i = 1; i < 21; i++) {
+    SendPacket(i);
+    clock_.AdvanceTime(time_between_packets);
+    if (i % 2 != 0) {
+      continue;
+    }
+
+    // Ack packet i and lose i-1.
+    BandwidthSampler::CongestionEventSample sample =
+        OnCongestionEvent({i}, {i - 1});
+    // Losing 50% packets means sending rate is twice the bandwidth.
+    EXPECT_EQ(sending_rate, sample.sample_max_bandwidth * 2);
+    EXPECT_EQ(time_between_packets, sample.sample_rtt);
+    EXPECT_EQ(kRegularPacketSize, sample.sample_max_inflight);
+    EXPECT_TRUE(sample.last_packet_send_state.is_valid);
+    EXPECT_EQ(2 * kRegularPacketSize,
+              sample.last_packet_send_state.bytes_in_flight);
+    EXPECT_EQ(i * kRegularPacketSize,
+              sample.last_packet_send_state.total_bytes_sent);
+    EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
+              sample.last_packet_send_state.total_bytes_acked);
+    EXPECT_EQ((i - 2) * kRegularPacketSize / 2,
+              sample.last_packet_send_state.total_bytes_lost);
+    sampler_.RemoveObsoletePackets(QuicPacketNumber(i - 2));
+  }
+}
+
+TEST_P(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
+  QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
+  QuicBandwidth first_packet_sending_rate =
+      QuicBandwidth::FromBytesAndTimeDelta(kRegularPacketSize,
+                                           time_between_packets);
+
+  // Send packets 1 to 4 and ack packet 1.
+  SendPacket(1);
+  clock_.AdvanceTime(time_between_packets);
+  SendPacket(2);
+  SendPacket(3);
+  SendPacket(4);
+  BandwidthSampler::CongestionEventSample sample = OnCongestionEvent({1}, {});
+  EXPECT_EQ(first_packet_sending_rate, sample.sample_max_bandwidth);
+  EXPECT_EQ(first_packet_sending_rate, max_bandwidth_);
+
+  // Ack packet 2, 3 and 4, all of which uses S(1) to calculate ack rate since
+  // there were no acks at the time they were sent.
+  round_trip_count_++;
+  est_bandwidth_upper_bound_ = first_packet_sending_rate * 0.3;
+  clock_.AdvanceTime(time_between_packets);
+  sample = OnCongestionEvent({2, 3, 4}, {});
+  EXPECT_EQ(first_packet_sending_rate * 2, sample.sample_max_bandwidth);
+  EXPECT_EQ(max_bandwidth_, sample.sample_max_bandwidth);
+
+  EXPECT_LT(2 * kRegularPacketSize, sample.extra_acked);
+}
+
+class MaxAckHeightTrackerTest : public QuicTest {
+ protected:
+  MaxAckHeightTrackerTest() : tracker_(/*initial_filter_window=*/10) {
+    tracker_.SetAckAggregationBandwidthThreshold(1.8);
+    tracker_.SetStartNewAggregationEpochAfterFullRound(true);
+  }
+
+  // Run a full aggregation episode, which is one or more aggregated acks,
+  // followed by a quiet period in which no ack happens.
+  // After this function returns, the time is set to the earliest point at which
+  // any ack event will cause tracker_.Update() to start a new aggregation.
+  void AggregationEpisode(QuicBandwidth aggregation_bandwidth,
+                          QuicTime::Delta aggregation_duration,
+                          QuicByteCount bytes_per_ack,
+                          bool expect_new_aggregation_epoch) {
+    ASSERT_GE(aggregation_bandwidth, bandwidth_);
+    const QuicTime start_time = now_;
+
+    const QuicByteCount aggregation_bytes =
+        aggregation_bandwidth * aggregation_duration;
+
+    const int num_acks = aggregation_bytes / bytes_per_ack;
+    ASSERT_EQ(aggregation_bytes, num_acks * bytes_per_ack)
+        << "aggregation_bytes: " << aggregation_bytes << " ["
+        << aggregation_bandwidth << " in " << aggregation_duration
+        << "], bytes_per_ack: " << bytes_per_ack;
+
+    const QuicTime::Delta time_between_acks = QuicTime::Delta::FromMicroseconds(
+        aggregation_duration.ToMicroseconds() / num_acks);
+    ASSERT_EQ(aggregation_duration, num_acks * time_between_acks)
+        << "aggregation_bytes: " << aggregation_bytes
+        << ", num_acks: " << num_acks
+        << ", time_between_acks: " << time_between_acks;
+
+    // The total duration of aggregation time and quiet period.
+    const QuicTime::Delta total_duration = QuicTime::Delta::FromMicroseconds(
+        aggregation_bytes * 8 * 1000000 / bandwidth_.ToBitsPerSecond());
+    ASSERT_EQ(aggregation_bytes, total_duration * bandwidth_)
+        << "total_duration: " << total_duration
+        << ", bandwidth_: " << bandwidth_;
+
+    QuicByteCount last_extra_acked = 0;
+    for (QuicByteCount bytes = 0; bytes < aggregation_bytes;
+         bytes += bytes_per_ack) {
+      QuicByteCount extra_acked = tracker_.Update(
+          bandwidth_, true, RoundTripCount(), last_sent_packet_number_,
+          last_acked_packet_number_, now_, bytes_per_ack);
+      QUIC_VLOG(1) << "T" << now_ << ": Update after " << bytes_per_ack
+                   << " bytes acked, " << extra_acked << " extra bytes acked";
+      // |extra_acked| should be 0 if either
+      // [1] We are at the beginning of a aggregation epoch(bytes==0) and the
+      //     the current tracker implementation can identify it, or
+      // [2] We are not really aggregating acks.
+      if ((bytes == 0 && expect_new_aggregation_epoch) ||  // [1]
+          (aggregation_bandwidth == bandwidth_)) {         // [2]
+        EXPECT_EQ(0u, extra_acked);
+      } else {
+        EXPECT_LT(last_extra_acked, extra_acked);
+      }
+      now_ = now_ + time_between_acks;
+      last_extra_acked = extra_acked;
+    }
+
+    // Advance past the quiet period.
+    const QuicTime time_after_aggregation = now_;
+    now_ = start_time + total_duration;
+    QUIC_VLOG(1) << "Advanced time from " << time_after_aggregation << " to "
+                 << now_ << ". Aggregation time["
+                 << (time_after_aggregation - start_time) << "], Quiet time["
+                 << (now_ - time_after_aggregation) << "].";
+  }
+
+  QuicRoundTripCount RoundTripCount() const {
+    return (now_ - QuicTime::Zero()).ToMicroseconds() / rtt_.ToMicroseconds();
+  }
+
+  MaxAckHeightTracker tracker_;
+  QuicBandwidth bandwidth_ = QuicBandwidth::FromBytesPerSecond(10 * 1000);
+  QuicTime now_ = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime::Delta rtt_ = QuicTime::Delta::FromMilliseconds(60);
+  QuicPacketNumber last_sent_packet_number_;
+  QuicPacketNumber last_acked_packet_number_;
+};
+
+TEST_F(MaxAckHeightTrackerTest, VeryAggregatedLargeAck) {
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                     1200, true);
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                     1200, true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       1200, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       1200, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, VeryAggregatedSmallAcks) {
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
+                     true);
+  AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6), 300,
+                     true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       300, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 20, QuicTime::Delta::FromMilliseconds(6),
+                       300, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedLargeAck) {
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                     1000, true);
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                     1000, true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       1000, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       1000, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, SomewhatAggregatedSmallAcks) {
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
+                     true);
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
+                     true);
+  now_ = now_ - QuicTime::Delta::FromMilliseconds(1);
+
+  if (tracker_.ack_aggregation_bandwidth_threshold() > 1.1) {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       100, true);
+    EXPECT_EQ(3u, tracker_.num_ack_aggregation_epochs());
+  } else {
+    AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50),
+                       100, false);
+    EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+  }
+}
+
+TEST_F(MaxAckHeightTrackerTest, NotAggregated) {
+  AggregationEpisode(bandwidth_, QuicTime::Delta::FromMilliseconds(100), 100,
+                     true);
+  EXPECT_LT(2u, tracker_.num_ack_aggregation_epochs());
+}
+
+TEST_F(MaxAckHeightTrackerTest, StartNewEpochAfterAFullRound) {
+  last_sent_packet_number_ = QuicPacketNumber(10);
+  AggregationEpisode(bandwidth_ * 2, QuicTime::Delta::FromMilliseconds(50), 100,
+                     true);
+
+  last_acked_packet_number_ = QuicPacketNumber(11);
+  // Update with a tiny bandwidth causes a very low expected bytes acked, which
+  // in turn causes the current epoch to continue if the |tracker_| doesn't
+  // check the packet numbers.
+  tracker_.Update(bandwidth_ * 0.1, true, RoundTripCount(),
+                  last_sent_packet_number_, last_acked_packet_number_, now_,
+                  100);
+
+  EXPECT_EQ(2u, tracker_.num_ack_aggregation_epochs());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_drain.cc b/quiche/quic/core/congestion_control/bbr2_drain.cc
new file mode 100644
index 0000000..6fb9c94
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_drain.cc
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr2_drain.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+Bbr2Mode Bbr2DrainMode::OnCongestionEvent(
+    QuicByteCount /*prior_in_flight*/,
+    QuicTime /*event_time*/,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  model_->set_pacing_gain(Params().drain_pacing_gain);
+
+  // Only STARTUP can transition to DRAIN, both of them use the same cwnd gain.
+  QUICHE_DCHECK_EQ(model_->cwnd_gain(), Params().drain_cwnd_gain);
+  model_->set_cwnd_gain(Params().drain_cwnd_gain);
+
+  QuicByteCount drain_target = DrainTarget();
+  if (congestion_event.bytes_in_flight <= drain_target) {
+    QUIC_DVLOG(3) << sender_ << " Exiting DRAIN. bytes_in_flight:"
+                  << congestion_event.bytes_in_flight
+                  << ", bdp:" << model_->BDP()
+                  << ", drain_target:" << drain_target << "  @ "
+                  << congestion_event.event_time;
+    return Bbr2Mode::PROBE_BW;
+  }
+
+  QUIC_DVLOG(3) << sender_ << " Staying in DRAIN. bytes_in_flight:"
+                << congestion_event.bytes_in_flight << ", bdp:" << model_->BDP()
+                << ", drain_target:" << drain_target << "  @ "
+                << congestion_event.event_time;
+  return Bbr2Mode::DRAIN;
+}
+
+QuicByteCount Bbr2DrainMode::DrainTarget() const {
+  QuicByteCount bdp = model_->BDP();
+  return std::max<QuicByteCount>(bdp, sender_->GetMinimumCongestionWindow());
+}
+
+Bbr2DrainMode::DebugState Bbr2DrainMode::ExportDebugState() const {
+  DebugState s;
+  s.drain_target = DrainTarget();
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2DrainMode::DebugState& state) {
+  os << "[DRAIN] drain_target: " << state.drain_target << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2DrainMode::Params() const {
+  return sender_->Params();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_drain.h b/quiche/quic/core/congestion_control/bbr2_drain.h
new file mode 100644
index 0000000..418035c
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_drain.h
@@ -0,0 +1,61 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2DrainMode final : public Bbr2ModeBase {
+ public:
+  using Bbr2ModeBase::Bbr2ModeBase;
+
+  void Enter(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+  void Leave(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override {
+    return NoGreaterThan(model_->inflight_lo());
+  }
+
+  bool IsProbingForBandwidth() const override { return false; }
+
+  Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
+                            QuicTime /*quiescence_start_time*/) override {
+    return Bbr2Mode::DRAIN;
+  }
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    QuicByteCount drain_target;
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+
+  QuicByteCount DrainTarget() const;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2DrainMode::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_DRAIN_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_misc.cc b/quiche/quic/core/congestion_control/bbr2_misc.cc
new file mode 100644
index 0000000..a912d5a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_misc.cc
@@ -0,0 +1,454 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+RoundTripCounter::RoundTripCounter() : round_trip_count_(0) {}
+
+void RoundTripCounter::OnPacketSent(QuicPacketNumber packet_number) {
+  QUICHE_DCHECK(!last_sent_packet_.IsInitialized() ||
+                last_sent_packet_ < packet_number);
+  last_sent_packet_ = packet_number;
+}
+
+bool RoundTripCounter::OnPacketsAcked(QuicPacketNumber last_acked_packet) {
+  if (!end_of_round_trip_.IsInitialized() ||
+      last_acked_packet > end_of_round_trip_) {
+    round_trip_count_++;
+    end_of_round_trip_ = last_sent_packet_;
+    return true;
+  }
+  return false;
+}
+
+void RoundTripCounter::RestartRound() {
+  end_of_round_trip_ = last_sent_packet_;
+}
+
+MinRttFilter::MinRttFilter(QuicTime::Delta initial_min_rtt,
+                           QuicTime initial_min_rtt_timestamp)
+    : min_rtt_(initial_min_rtt),
+      min_rtt_timestamp_(initial_min_rtt_timestamp) {}
+
+void MinRttFilter::Update(QuicTime::Delta sample_rtt, QuicTime now) {
+  if (sample_rtt < min_rtt_ || min_rtt_timestamp_ == QuicTime::Zero()) {
+    min_rtt_ = sample_rtt;
+    min_rtt_timestamp_ = now;
+  }
+}
+
+void MinRttFilter::ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now) {
+  min_rtt_ = sample_rtt;
+  min_rtt_timestamp_ = now;
+}
+
+Bbr2NetworkModel::Bbr2NetworkModel(const Bbr2Params* params,
+                                   QuicTime::Delta initial_rtt,
+                                   QuicTime initial_rtt_timestamp,
+                                   float cwnd_gain,
+                                   float pacing_gain,
+                                   const BandwidthSampler* old_sampler)
+    : params_(params),
+      bandwidth_sampler_([](QuicRoundTripCount max_height_tracker_window_length,
+                            const BandwidthSampler* old_sampler) {
+        if (old_sampler != nullptr) {
+          return BandwidthSampler(*old_sampler);
+        }
+        return BandwidthSampler(/*unacked_packet_map=*/nullptr,
+                                max_height_tracker_window_length);
+      }(params->initial_max_ack_height_filter_window, old_sampler)),
+      min_rtt_filter_(initial_rtt, initial_rtt_timestamp),
+      cwnd_gain_(cwnd_gain),
+      pacing_gain_(pacing_gain) {}
+
+void Bbr2NetworkModel::OnPacketSent(QuicTime sent_time,
+                                    QuicByteCount bytes_in_flight,
+                                    QuicPacketNumber packet_number,
+                                    QuicByteCount bytes,
+                                    HasRetransmittableData is_retransmittable) {
+  round_trip_counter_.OnPacketSent(packet_number);
+
+  bandwidth_sampler_.OnPacketSent(sent_time, packet_number, bytes,
+                                  bytes_in_flight, is_retransmittable);
+}
+
+void Bbr2NetworkModel::OnCongestionEventStart(
+    QuicTime event_time,
+    const AckedPacketVector& acked_packets,
+    const LostPacketVector& lost_packets,
+    Bbr2CongestionEvent* congestion_event) {
+  const QuicByteCount prior_bytes_acked = total_bytes_acked();
+  const QuicByteCount prior_bytes_lost = total_bytes_lost();
+
+  congestion_event->event_time = event_time;
+  congestion_event->end_of_round_trip =
+      acked_packets.empty() ? false
+                            : round_trip_counter_.OnPacketsAcked(
+                                  acked_packets.rbegin()->packet_number);
+
+  BandwidthSamplerInterface::CongestionEventSample sample =
+      bandwidth_sampler_.OnCongestionEvent(event_time, acked_packets,
+                                           lost_packets, MaxBandwidth(),
+                                           bandwidth_lo(), RoundTripCount());
+
+  if (sample.extra_acked == 0) {
+    cwnd_limited_before_aggregation_epoch_ =
+        congestion_event->prior_bytes_in_flight >= congestion_event->prior_cwnd;
+  }
+
+  if (sample.last_packet_send_state.is_valid) {
+    congestion_event->last_packet_send_state = sample.last_packet_send_state;
+  }
+
+  // Avoid updating |max_bandwidth_filter_| if a) this is a loss-only event, or
+  // b) all packets in |acked_packets| did not generate valid samples. (e.g. ack
+  // of ack-only packets). In both cases, total_bytes_acked() will not change.
+  if (prior_bytes_acked != total_bytes_acked()) {
+    QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
+        << total_bytes_acked() - prior_bytes_acked << " bytes from "
+        << acked_packets.size()
+        << " packets have been acked, but sample_max_bandwidth is zero.";
+    congestion_event->sample_max_bandwidth = sample.sample_max_bandwidth;
+    if (!sample.sample_is_app_limited ||
+        sample.sample_max_bandwidth > MaxBandwidth()) {
+      max_bandwidth_filter_.Update(congestion_event->sample_max_bandwidth);
+    }
+  }
+
+  if (!sample.sample_rtt.IsInfinite()) {
+    congestion_event->sample_min_rtt = sample.sample_rtt;
+    min_rtt_filter_.Update(congestion_event->sample_min_rtt, event_time);
+  }
+
+  congestion_event->bytes_acked = total_bytes_acked() - prior_bytes_acked;
+  congestion_event->bytes_lost = total_bytes_lost() - prior_bytes_lost;
+
+  if (congestion_event->prior_bytes_in_flight >=
+      congestion_event->bytes_acked + congestion_event->bytes_lost) {
+    congestion_event->bytes_in_flight =
+        congestion_event->prior_bytes_in_flight -
+        congestion_event->bytes_acked - congestion_event->bytes_lost;
+  } else {
+    QUIC_LOG_FIRST_N(ERROR, 1)
+        << "prior_bytes_in_flight:" << congestion_event->prior_bytes_in_flight
+        << " is smaller than the sum of bytes_acked:"
+        << congestion_event->bytes_acked
+        << " and bytes_lost:" << congestion_event->bytes_lost;
+    congestion_event->bytes_in_flight = 0;
+  }
+
+  if (congestion_event->bytes_lost > 0) {
+    bytes_lost_in_round_ += congestion_event->bytes_lost;
+    loss_events_in_round_++;
+  }
+
+  if (congestion_event->bytes_acked > 0 &&
+      congestion_event->last_packet_send_state.is_valid &&
+      total_bytes_acked() >
+          congestion_event->last_packet_send_state.total_bytes_acked) {
+    QuicByteCount bytes_delivered =
+        total_bytes_acked() -
+        congestion_event->last_packet_send_state.total_bytes_acked;
+    max_bytes_delivered_in_round_ =
+        std::max(max_bytes_delivered_in_round_, bytes_delivered);
+    // TODO(ianswett) Consider treating any bytes lost as decreasing inflight,
+    // because it's a sign of overutilization, not underutilization.
+    if (min_bytes_in_flight_in_round_ == 0 ||
+        congestion_event->bytes_in_flight < min_bytes_in_flight_in_round_) {
+      min_bytes_in_flight_in_round_ = congestion_event->bytes_in_flight;
+    }
+  }
+
+  // |bandwidth_latest_| and |inflight_latest_| only increased within a round.
+  if (sample.sample_max_bandwidth > bandwidth_latest_) {
+    bandwidth_latest_ = sample.sample_max_bandwidth;
+  }
+
+  if (sample.sample_max_inflight > inflight_latest_) {
+    inflight_latest_ = sample.sample_max_inflight;
+  }
+
+  // Adapt lower bounds(bandwidth_lo and inflight_lo).
+  AdaptLowerBounds(*congestion_event);
+
+  if (!congestion_event->end_of_round_trip) {
+    return;
+  }
+
+  if (!sample.sample_max_bandwidth.IsZero()) {
+    bandwidth_latest_ = sample.sample_max_bandwidth;
+  }
+
+  if (sample.sample_max_inflight > 0) {
+    inflight_latest_ = sample.sample_max_inflight;
+  }
+}
+
+void Bbr2NetworkModel::AdaptLowerBounds(
+    const Bbr2CongestionEvent& congestion_event) {
+  if (Params().bw_lo_mode_ == Bbr2Params::DEFAULT) {
+    if (!congestion_event.end_of_round_trip ||
+        congestion_event.is_probing_for_bandwidth) {
+      return;
+    }
+
+    if (bytes_lost_in_round_ > 0) {
+      if (bandwidth_lo_.IsInfinite()) {
+        bandwidth_lo_ = MaxBandwidth();
+      }
+      bandwidth_lo_ =
+          std::max(bandwidth_latest_, bandwidth_lo_ * (1.0 - Params().beta));
+      QUIC_DVLOG(3) << "bandwidth_lo_ updated to " << bandwidth_lo_
+                    << ", bandwidth_latest_ is " << bandwidth_latest_;
+
+      if (Params().ignore_inflight_lo) {
+        return;
+      }
+      if (inflight_lo_ == inflight_lo_default()) {
+        inflight_lo_ = congestion_event.prior_cwnd;
+      }
+      inflight_lo_ = std::max<QuicByteCount>(
+          inflight_latest_, inflight_lo_ * (1.0 - Params().beta));
+    }
+    return;
+  }
+
+  // Params().bw_lo_mode_ != Bbr2Params::DEFAULT
+  if (congestion_event.bytes_lost == 0) {
+    return;
+  }
+  // Ignore losses from packets sent when probing for more bandwidth in
+  // STARTUP or PROBE_UP when they're lost in DRAIN or PROBE_DOWN.
+  if (pacing_gain_ < 1) {
+    return;
+  }
+  // Decrease bandwidth_lo whenever there is loss.
+  // Set bandwidth_lo_ if it is not yet set.
+  if (bandwidth_lo_.IsInfinite()) {
+    bandwidth_lo_ = MaxBandwidth();
+  }
+  // Save bandwidth_lo_ if it hasn't already been saved.
+  if (prior_bandwidth_lo_.IsZero()) {
+    prior_bandwidth_lo_ = bandwidth_lo_;
+  }
+  switch (Params().bw_lo_mode_) {
+    case Bbr2Params::MIN_RTT_REDUCTION:
+      bandwidth_lo_ =
+          bandwidth_lo_ - QuicBandwidth::FromBytesAndTimeDelta(
+                              congestion_event.bytes_lost, MinRtt());
+      break;
+    case Bbr2Params::INFLIGHT_REDUCTION: {
+      // Use a max of BDP and inflight to avoid starving app-limited flows.
+      const QuicByteCount effective_inflight =
+          std::max(BDP(), congestion_event.prior_bytes_in_flight);
+      // This could use bytes_lost_in_round if the bandwidth_lo_ was saved
+      // when entering 'recovery', but this BBRv2 implementation doesn't have
+      // recovery defined.
+      bandwidth_lo_ =
+          bandwidth_lo_ * ((effective_inflight - congestion_event.bytes_lost) /
+                           static_cast<double>(effective_inflight));
+      break;
+    }
+    case Bbr2Params::CWND_REDUCTION:
+      bandwidth_lo_ =
+          bandwidth_lo_ *
+          ((congestion_event.prior_cwnd - congestion_event.bytes_lost) /
+           static_cast<double>(congestion_event.prior_cwnd));
+      break;
+    case Bbr2Params::DEFAULT:
+      QUIC_BUG(quic_bug_10466_1) << "Unreachable case DEFAULT.";
+  }
+  QuicBandwidth last_bandwidth = bandwidth_latest_;
+  // sample_max_bandwidth will be Zero() if the loss is triggered by a timer
+  // expiring.  Ideally we'd use the most recent bandwidth sample,
+  // but bandwidth_latest is safer than Zero().
+  if (!congestion_event.sample_max_bandwidth.IsZero()) {
+    // bandwidth_latest_ is the max bandwidth for the round, but to allow
+    // fast, conservation style response to loss, use the last sample.
+    last_bandwidth = congestion_event.sample_max_bandwidth;
+  }
+  if (pacing_gain_ > Params().startup_full_bw_threshold) {
+    // In STARTUP, pacing_gain_ is applied to bandwidth_lo_ in
+    // UpdatePacingRate, so this backs that multiplication out to allow the
+    // pacing rate to decrease, but not below
+    // last_bandwidth * startup_full_bw_threshold.
+    // TODO(ianswett): Consider altering pacing_gain_ when in STARTUP instead.
+    bandwidth_lo_ = std::max(
+        bandwidth_lo_,
+        last_bandwidth * (Params().startup_full_bw_threshold / pacing_gain_));
+  } else {
+    // Ensure bandwidth_lo isn't lower than last_bandwidth.
+    bandwidth_lo_ = std::max(bandwidth_lo_, last_bandwidth);
+  }
+  // If it's the end of the round, ensure bandwidth_lo doesn't decrease more
+  // than beta.
+  if (congestion_event.end_of_round_trip) {
+    bandwidth_lo_ =
+        std::max(bandwidth_lo_, prior_bandwidth_lo_ * (1.0 - Params().beta));
+    prior_bandwidth_lo_ = QuicBandwidth::Zero();
+  }
+  // These modes ignore inflight_lo as well.
+}
+
+void Bbr2NetworkModel::OnCongestionEventFinish(
+    QuicPacketNumber least_unacked_packet,
+    const Bbr2CongestionEvent& congestion_event) {
+  if (congestion_event.end_of_round_trip) {
+    OnNewRound();
+  }
+
+  bandwidth_sampler_.RemoveObsoletePackets(least_unacked_packet);
+}
+
+void Bbr2NetworkModel::UpdateNetworkParameters(QuicTime::Delta rtt) {
+  if (!rtt.IsZero()) {
+    min_rtt_filter_.Update(rtt, MinRttTimestamp());
+  }
+}
+
+bool Bbr2NetworkModel::MaybeExpireMinRtt(
+    const Bbr2CongestionEvent& congestion_event) {
+  if (congestion_event.event_time <
+      (MinRttTimestamp() + Params().probe_rtt_period)) {
+    return false;
+  }
+  if (congestion_event.sample_min_rtt.IsInfinite()) {
+    return false;
+  }
+  QUIC_DVLOG(3) << "Replacing expired min rtt of " << min_rtt_filter_.Get()
+                << " by " << congestion_event.sample_min_rtt << "  @ "
+                << congestion_event.event_time;
+  min_rtt_filter_.ForceUpdate(congestion_event.sample_min_rtt,
+                              congestion_event.event_time);
+  return true;
+}
+
+bool Bbr2NetworkModel::IsInflightTooHigh(
+    const Bbr2CongestionEvent& congestion_event,
+    int64_t max_loss_events) const {
+  const SendTimeState& send_state = congestion_event.last_packet_send_state;
+  if (!send_state.is_valid) {
+    // Not enough information.
+    return false;
+  }
+
+  if (loss_events_in_round() < max_loss_events) {
+    return false;
+  }
+
+  const QuicByteCount inflight_at_send = BytesInFlight(send_state);
+  // TODO(wub): Consider total_bytes_lost() - send_state.total_bytes_lost, which
+  // is the total bytes lost when the largest numbered packet was inflight.
+  // bytes_lost_in_round_, OTOH, is the total bytes lost in the "current" round.
+  const QuicByteCount bytes_lost_in_round = bytes_lost_in_round_;
+
+  QUIC_DVLOG(3) << "IsInflightTooHigh: loss_events_in_round:"
+                << loss_events_in_round()
+
+                << " bytes_lost_in_round:" << bytes_lost_in_round
+                << ", lost_in_round_threshold:"
+                << inflight_at_send * Params().loss_threshold;
+
+  if (inflight_at_send > 0 && bytes_lost_in_round > 0) {
+    QuicByteCount lost_in_round_threshold =
+        inflight_at_send * Params().loss_threshold;
+    if (bytes_lost_in_round > lost_in_round_threshold) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void Bbr2NetworkModel::RestartRoundEarly() {
+  OnNewRound();
+  round_trip_counter_.RestartRound();
+}
+
+void Bbr2NetworkModel::OnNewRound() {
+  bytes_lost_in_round_ = 0;
+  loss_events_in_round_ = 0;
+  max_bytes_delivered_in_round_ = 0;
+  min_bytes_in_flight_in_round_ = 0;
+}
+
+void Bbr2NetworkModel::cap_inflight_lo(QuicByteCount cap) {
+  if (Params().ignore_inflight_lo) {
+    return;
+  }
+  if (inflight_lo_ != inflight_lo_default() && inflight_lo_ > cap) {
+    inflight_lo_ = cap;
+  }
+}
+
+QuicByteCount Bbr2NetworkModel::inflight_hi_with_headroom() const {
+  QuicByteCount headroom = inflight_hi_ * Params().inflight_hi_headroom;
+
+  return inflight_hi_ > headroom ? inflight_hi_ - headroom : 0;
+}
+
+bool Bbr2NetworkModel::HasBandwidthGrowth(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK(!full_bandwidth_reached_);
+  QUICHE_DCHECK(congestion_event.end_of_round_trip);
+
+  QuicBandwidth threshold =
+      full_bandwidth_baseline_ * Params().startup_full_bw_threshold;
+
+  if (MaxBandwidth() >= threshold) {
+    QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
+                  << MaxBandwidth() << ", threshold:" << threshold
+                  << " (Still growing)  @ " << congestion_event.event_time;
+    full_bandwidth_baseline_ = MaxBandwidth();
+    rounds_without_bandwidth_growth_ = 0;
+    return true;
+  }
+  ++rounds_without_bandwidth_growth_;
+
+  // full_bandwidth_reached is only set to true when not app-limited, except
+  // when exit_startup_on_persistent_queue is true.
+  if (rounds_without_bandwidth_growth_ >= Params().startup_full_bw_rounds &&
+      !congestion_event.last_packet_send_state.is_app_limited) {
+    full_bandwidth_reached_ = true;
+  }
+  QUIC_DVLOG(3) << " CheckBandwidthGrowth at end of round. max_bandwidth:"
+                << MaxBandwidth() << ", threshold:" << threshold
+                << " rounds_without_growth:" << rounds_without_bandwidth_growth_
+                << " full_bw_reached:" << full_bandwidth_reached_ << "  @ "
+                << congestion_event.event_time;
+
+  return false;
+}
+
+bool Bbr2NetworkModel::CheckPersistentQueue(
+    const Bbr2CongestionEvent& congestion_event, float bdp_gain) {
+  QUICHE_DCHECK(congestion_event.end_of_round_trip);
+  QuicByteCount target = bdp_gain * BDP();
+  if (bdp_gain >= 2) {
+    // Use a more conservative threshold for STARTUP because CWND gain is 2.
+    if (target <= QueueingThresholdExtraBytes()) {
+      return false;
+    }
+    target -= QueueingThresholdExtraBytes();
+  } else {
+    target += QueueingThresholdExtraBytes();
+  }
+  if (min_bytes_in_flight_in_round_ > target) {
+    full_bandwidth_reached_ = true;
+    return true;
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_misc.h b/quiche/quic/core/congestion_control/bbr2_misc.h
new file mode 100644
index 0000000..a7efaed
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_misc.h
@@ -0,0 +1,674 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
+
+#include <algorithm>
+#include <limits>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_EXPORT_PRIVATE Limits {
+ public:
+  Limits(T min, T max) : min_(min), max_(max) {}
+
+  // If [min, max] is an empty range, i.e. min > max, this function returns max,
+  // because typically a value larger than max means "risky".
+  T ApplyLimits(T raw_value) const {
+    return std::min(max_, std::max(min_, raw_value));
+  }
+
+  T Min() const { return min_; }
+  T Max() const { return max_; }
+
+ private:
+  T min_;
+  T max_;
+};
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> MinMax(T min, T max) {
+  return Limits<T>(min, max);
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> NoLessThan(T min) {
+  return Limits<T>(min, std::numeric_limits<T>::max());
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> NoGreaterThan(T max) {
+  return Limits<T>(std::numeric_limits<T>::min(), max);
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline Limits<T> Unlimited() {
+  return Limits<T>(std::numeric_limits<T>::min(),
+                   std::numeric_limits<T>::max());
+}
+
+template <typename T>
+QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
+                                                    const Limits<T>& limits) {
+  return os << "[" << limits.Min() << ", " << limits.Max() << "]";
+}
+
+// Bbr2Params contains all parameters of a Bbr2Sender.
+struct QUIC_EXPORT_PRIVATE Bbr2Params {
+  Bbr2Params(QuicByteCount cwnd_min, QuicByteCount cwnd_max)
+      : cwnd_limits(cwnd_min, cwnd_max) {}
+
+  /*
+   * STARTUP parameters.
+   */
+
+  // The gain for both CWND and PacingRate at startup.
+  float startup_cwnd_gain = 2.0;
+  // TODO(wub): Maybe change to the newly derived value of 2.773 (4 * ln(2)).
+  float startup_pacing_gain = 2.885;
+
+  // Full bandwidth is declared if the total bandwidth growth is less than
+  // |startup_full_bw_threshold| times in the last |startup_full_bw_rounds|
+  // round trips.
+  float startup_full_bw_threshold = 1.25;
+
+  QuicRoundTripCount startup_full_bw_rounds = 3;
+
+  // The minimum number of loss marking events to exit STARTUP.
+  int64_t startup_full_loss_count =
+      GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count);
+
+  // If true, always exit STARTUP on loss, even if bandwidth exceeds threshold.
+  // If false, exit STARTUP on loss only if bandwidth is below threshold.
+  bool always_exit_startup_on_excess_loss = false;
+
+  // If true, include extra acked during STARTUP and proactively reduce extra
+  // acked when bandwidth increases.
+  bool startup_include_extra_acked = false;
+
+  // If true, exit STARTUP if bytes in flight has not gone below 2 * BDP at
+  // any point in the last round.
+  bool exit_startup_on_persistent_queue = false;
+
+  /*
+   * DRAIN parameters.
+   */
+  float drain_cwnd_gain = 2.0;
+  float drain_pacing_gain = 1.0 / 2.885;
+
+  /*
+   * PROBE_BW parameters.
+   */
+  // Max amount of randomness to inject in round counting for Reno-coexistence.
+  QuicRoundTripCount probe_bw_max_probe_rand_rounds = 2;
+
+  // Max number of rounds before probing for Reno-coexistence.
+  uint32_t probe_bw_probe_max_rounds = 63;
+
+  // Multiplier to get Reno-style probe epoch duration as: k * BDP round trips.
+  // If zero, disables Reno-style BDP-scaled coexistence mechanism.
+  float probe_bw_probe_reno_gain = 1.0;
+
+  // Minimum duration for BBR-native probes.
+  QuicTime::Delta probe_bw_probe_base_duration =
+      QuicTime::Delta::FromMilliseconds(
+          GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_base_duration_ms));
+
+  // The upper bound of the random amount of BBR-native probes.
+  QuicTime::Delta probe_bw_probe_max_rand_duration =
+      QuicTime::Delta::FromMilliseconds(
+          GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_max_rand_duration_ms));
+
+  // The minimum number of loss marking events to exit the PROBE_UP phase.
+  int64_t probe_bw_full_loss_count =
+      GetQuicFlag(FLAGS_quic_bbr2_default_probe_bw_full_loss_count);
+
+  // Multiplier to get target inflight (as multiple of BDP) for PROBE_UP phase.
+  float probe_bw_probe_inflight_gain = 1.25;
+
+  // When attempting to grow inflight_hi in PROBE_UP, check whether we are cwnd
+  // limited before the current aggregation epoch, instead of before the current
+  // ack event.
+  bool probe_bw_check_cwnd_limited_before_aggregation_epoch = false;
+
+  // Pacing gains.
+  float probe_bw_probe_up_pacing_gain = 1.25;
+  float probe_bw_probe_down_pacing_gain = 0.75;
+  float probe_bw_default_pacing_gain = 1.0;
+
+  float probe_bw_cwnd_gain = 2.0;
+
+  /*
+   * PROBE_UP parameters.
+   */
+  bool probe_up_includes_acks_after_cwnd_limited = false;
+  bool probe_up_dont_exit_if_no_queue_ = false;
+  bool probe_up_ignore_inflight_hi = false;
+
+  /*
+   * PROBE_RTT parameters.
+   */
+  float probe_rtt_inflight_target_bdp_fraction = 0.5;
+  QuicTime::Delta probe_rtt_period = QuicTime::Delta::FromMilliseconds(
+      GetQuicFlag(FLAGS_quic_bbr2_default_probe_rtt_period_ms));
+  QuicTime::Delta probe_rtt_duration = QuicTime::Delta::FromMilliseconds(200);
+
+  /*
+   * Parameters used by multiple modes.
+   */
+
+  // The initial value of the max ack height filter's window length.
+  QuicRoundTripCount initial_max_ack_height_filter_window =
+      GetQuicFlag(FLAGS_quic_bbr2_default_initial_ack_height_filter_window);
+
+  // Fraction of unutilized headroom to try to leave in path upon high loss.
+  float inflight_hi_headroom =
+      GetQuicFlag(FLAGS_quic_bbr2_default_inflight_hi_headroom);
+
+  // Estimate startup/bw probing has gone too far if loss rate exceeds this.
+  float loss_threshold = GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold);
+
+  // A common factor for multiplicative decreases. Used for adjusting
+  // bandwidth_lo, inflight_lo and inflight_hi upon losses.
+  float beta = 0.3;
+
+  Limits<QuicByteCount> cwnd_limits;
+
+  /*
+   * Experimental flags from QuicConfig.
+   */
+
+  // Can be disabled by connection option 'B2NA'.
+  bool add_ack_height_to_queueing_threshold = true;
+
+  // Can be disabled by connection option 'B2RP'.
+  bool avoid_unnecessary_probe_rtt = true;
+
+  // Can be enabled by connection option 'B2LO'.
+  bool ignore_inflight_lo = false;
+
+  // Can be enabled by connection option 'B2H2'.
+  bool limit_inflight_hi_by_max_delivered = false;
+
+  // Can be disabled by connection option 'B2SL'.
+  bool startup_loss_exit_use_max_delivered_for_inflight_hi = true;
+
+  // Can be enabled by connection option 'B2DL'.
+  bool use_bytes_delivered_for_inflight_hi = false;
+
+  // Can be disabled by connection option 'B2RC'.
+  bool enable_reno_coexistence = true;
+
+  // For experimentation to improve fast convergence upon loss.
+  enum QuicBandwidthLoMode : uint8_t {
+    DEFAULT = 0,
+    MIN_RTT_REDUCTION = 1,   // 'BBQ7'
+    INFLIGHT_REDUCTION = 2,  // 'BBQ8'
+    CWND_REDUCTION = 3,      // 'BBQ9'
+  };
+
+  // Different modes change bandwidth_lo_ differently upon loss.
+  QuicBandwidthLoMode bw_lo_mode_ = QuicBandwidthLoMode::DEFAULT;
+
+  // Set the pacing gain to 25% larger than the recent BW increase in STARTUP.
+  bool decrease_startup_pacing_at_end_of_round = false;
+};
+
+class QUIC_EXPORT_PRIVATE RoundTripCounter {
+ public:
+  RoundTripCounter();
+
+  QuicRoundTripCount Count() const { return round_trip_count_; }
+
+  QuicPacketNumber last_sent_packet() const { return last_sent_packet_; }
+
+  // Must be called in ascending packet number order.
+  void OnPacketSent(QuicPacketNumber packet_number);
+
+  // Return whether a round trip has just completed.
+  bool OnPacketsAcked(QuicPacketNumber last_acked_packet);
+
+  void RestartRound();
+
+ private:
+  QuicRoundTripCount round_trip_count_;
+  QuicPacketNumber last_sent_packet_;
+  // The last sent packet number of the current round trip.
+  QuicPacketNumber end_of_round_trip_;
+};
+
+class QUIC_EXPORT_PRIVATE MinRttFilter {
+ public:
+  MinRttFilter(QuicTime::Delta initial_min_rtt,
+               QuicTime initial_min_rtt_timestamp);
+
+  void Update(QuicTime::Delta sample_rtt, QuicTime now);
+
+  void ForceUpdate(QuicTime::Delta sample_rtt, QuicTime now);
+
+  QuicTime::Delta Get() const { return min_rtt_; }
+
+  QuicTime GetTimestamp() const { return min_rtt_timestamp_; }
+
+ private:
+  QuicTime::Delta min_rtt_;
+  // Time when the current value of |min_rtt_| was assigned.
+  QuicTime min_rtt_timestamp_;
+};
+
+class QUIC_EXPORT_PRIVATE Bbr2MaxBandwidthFilter {
+ public:
+  void Update(QuicBandwidth sample) {
+    max_bandwidth_[1] = std::max(sample, max_bandwidth_[1]);
+  }
+
+  void Advance() {
+    if (max_bandwidth_[1].IsZero()) {
+      return;
+    }
+
+    max_bandwidth_[0] = max_bandwidth_[1];
+    max_bandwidth_[1] = QuicBandwidth::Zero();
+  }
+
+  QuicBandwidth Get() const {
+    return std::max(max_bandwidth_[0], max_bandwidth_[1]);
+  }
+
+ private:
+  QuicBandwidth max_bandwidth_[2] = {QuicBandwidth::Zero(),
+                                     QuicBandwidth::Zero()};
+};
+
+// Information that are meaningful only when Bbr2Sender::OnCongestionEvent is
+// running.
+struct QUIC_EXPORT_PRIVATE Bbr2CongestionEvent {
+  QuicTime event_time = QuicTime::Zero();
+
+  // The congestion window prior to the processing of the ack/loss events.
+  QuicByteCount prior_cwnd;
+
+  // Total bytes inflight before the processing of the ack/loss events.
+  QuicByteCount prior_bytes_in_flight = 0;
+
+  // Total bytes inflight after the processing of the ack/loss events.
+  QuicByteCount bytes_in_flight = 0;
+
+  // Total bytes acked from acks in this event.
+  QuicByteCount bytes_acked = 0;
+
+  // Total bytes lost from losses in this event.
+  QuicByteCount bytes_lost = 0;
+
+  // Whether acked_packets indicates the end of a round trip.
+  bool end_of_round_trip = false;
+
+  // When the event happened, whether the sender is probing for bandwidth.
+  bool is_probing_for_bandwidth = false;
+
+  // Minimum rtt of all bandwidth samples from acked_packets.
+  // QuicTime::Delta::Infinite() if acked_packets is empty.
+  QuicTime::Delta sample_min_rtt = QuicTime::Delta::Infinite();
+
+  // Maximum bandwidth of all bandwidth samples from acked_packets.
+  // This sample may be app-limited, and will be Zero() if there are no newly
+  // acknowledged inflight packets.
+  QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
+
+  // The send state of the largest packet in acked_packets, unless it is empty.
+  // If acked_packets is empty, it's the send state of the largest packet in
+  // lost_packets.
+  SendTimeState last_packet_send_state;
+};
+
+// Bbr2NetworkModel takes low level congestion signals(packets sent/acked/lost)
+// as input and produces BBRv2 model parameters like inflight_(hi|lo),
+// bandwidth_(hi|lo), bandwidth and rtt estimates, etc.
+class QUIC_EXPORT_PRIVATE Bbr2NetworkModel {
+ public:
+  Bbr2NetworkModel(const Bbr2Params* params,
+                   QuicTime::Delta initial_rtt,
+                   QuicTime initial_rtt_timestamp,
+                   float cwnd_gain,
+                   float pacing_gain,
+                   const BandwidthSampler* old_sampler);
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable);
+
+  void OnCongestionEventStart(QuicTime event_time,
+                              const AckedPacketVector& acked_packets,
+                              const LostPacketVector& lost_packets,
+                              Bbr2CongestionEvent* congestion_event);
+
+  void OnCongestionEventFinish(QuicPacketNumber least_unacked_packet,
+                               const Bbr2CongestionEvent& congestion_event);
+
+  // Update the model without a congestion event.
+  // Min rtt is updated if |rtt| is non-zero and smaller than existing min rtt.
+  void UpdateNetworkParameters(QuicTime::Delta rtt);
+
+  // Update inflight/bandwidth short-term lower bounds.
+  void AdaptLowerBounds(const Bbr2CongestionEvent& congestion_event);
+
+  // Restart the current round trip as if it is starting now.
+  void RestartRoundEarly();
+
+  void AdvanceMaxBandwidthFilter() { max_bandwidth_filter_.Advance(); }
+
+  void OnApplicationLimited() { bandwidth_sampler_.OnAppLimited(); }
+
+  // Calculates BDP using the current MaxBandwidth.
+  QuicByteCount BDP() const { return BDP(MaxBandwidth()); }
+
+  QuicByteCount BDP(QuicBandwidth bandwidth) const {
+    return bandwidth * MinRtt();
+  }
+
+  QuicByteCount BDP(QuicBandwidth bandwidth, float gain) const {
+    return bandwidth * MinRtt() * gain;
+  }
+
+  QuicTime::Delta MinRtt() const { return min_rtt_filter_.Get(); }
+
+  QuicTime MinRttTimestamp() const { return min_rtt_filter_.GetTimestamp(); }
+
+  // TODO(wub): If we do this too frequently, we can potentailly postpone
+  // PROBE_RTT indefinitely. Observe how it works in production and improve it.
+  void PostponeMinRttTimestamp(QuicTime::Delta duration) {
+    min_rtt_filter_.ForceUpdate(MinRtt(), MinRttTimestamp() + duration);
+  }
+
+  QuicBandwidth MaxBandwidth() const { return max_bandwidth_filter_.Get(); }
+
+  QuicByteCount MaxAckHeight() const {
+    return bandwidth_sampler_.max_ack_height();
+  }
+
+  // 2 packets.  Used to indicate the typical number of bytes ACKed at once.
+  QuicByteCount QueueingThresholdExtraBytes() const {
+    return 2 * kDefaultTCPMSS;
+  }
+
+  bool cwnd_limited_before_aggregation_epoch() const {
+    return cwnd_limited_before_aggregation_epoch_;
+  }
+
+  void EnableOverestimateAvoidance() {
+    bandwidth_sampler_.EnableOverestimateAvoidance();
+  }
+
+  bool IsBandwidthOverestimateAvoidanceEnabled() const {
+    return bandwidth_sampler_.IsOverestimateAvoidanceEnabled();
+  }
+
+  void OnPacketNeutered(QuicPacketNumber packet_number) {
+    bandwidth_sampler_.OnPacketNeutered(packet_number);
+  }
+
+  uint64_t num_ack_aggregation_epochs() const {
+    return bandwidth_sampler_.num_ack_aggregation_epochs();
+  }
+
+  void SetStartNewAggregationEpochAfterFullRound(bool value) {
+    bandwidth_sampler_.SetStartNewAggregationEpochAfterFullRound(value);
+  }
+
+  void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
+    bandwidth_sampler_.SetLimitMaxAckHeightTrackerBySendRate(value);
+  }
+
+  void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount value) {
+    bandwidth_sampler_.SetMaxAckHeightTrackerWindowLength(value);
+  }
+
+  void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
+    bandwidth_sampler_.SetReduceExtraAckedOnBandwidthIncrease(value);
+  }
+
+  bool MaybeExpireMinRtt(const Bbr2CongestionEvent& congestion_event);
+
+  QuicBandwidth BandwidthEstimate() const {
+    return std::min(MaxBandwidth(), bandwidth_lo_);
+  }
+
+  QuicRoundTripCount RoundTripCount() const {
+    return round_trip_counter_.Count();
+  }
+
+  // Return true if the number of loss events exceeds max_loss_events and
+  // fraction of bytes lost exceed the loss threshold.
+  bool IsInflightTooHigh(const Bbr2CongestionEvent& congestion_event,
+                         int64_t max_loss_events) const;
+
+  // Check bandwidth growth in the past round. Must be called at the end of a
+  // round. Returns true if there was sufficient bandwidth growth and false
+  // otherwise.  If it's been too many rounds without growth, also sets
+  // |full_bandwidth_reached_| to true.
+  bool HasBandwidthGrowth(const Bbr2CongestionEvent& congestion_event);
+
+  // Returns true if the minimum bytes in flight during the round is greater
+  // than the BDP * |bdp_gain|.
+  bool CheckPersistentQueue(const Bbr2CongestionEvent& congestion_event,
+                            float bdp_gain);
+
+  QuicPacketNumber last_sent_packet() const {
+    return round_trip_counter_.last_sent_packet();
+  }
+
+  QuicByteCount total_bytes_acked() const {
+    return bandwidth_sampler_.total_bytes_acked();
+  }
+
+  QuicByteCount total_bytes_lost() const {
+    return bandwidth_sampler_.total_bytes_lost();
+  }
+
+  QuicByteCount total_bytes_sent() const {
+    return bandwidth_sampler_.total_bytes_sent();
+  }
+
+  int64_t loss_events_in_round() const { return loss_events_in_round_; }
+
+  QuicByteCount max_bytes_delivered_in_round() const {
+    return max_bytes_delivered_in_round_;
+  }
+
+  QuicByteCount min_bytes_in_flight_in_round() const {
+    return min_bytes_in_flight_in_round_;
+  }
+
+  QuicPacketNumber end_of_app_limited_phase() const {
+    return bandwidth_sampler_.end_of_app_limited_phase();
+  }
+
+  QuicBandwidth bandwidth_latest() const { return bandwidth_latest_; }
+  QuicBandwidth bandwidth_lo() const { return bandwidth_lo_; }
+  static QuicBandwidth bandwidth_lo_default() {
+    return QuicBandwidth::Infinite();
+  }
+  void clear_bandwidth_lo() { bandwidth_lo_ = bandwidth_lo_default(); }
+
+  QuicByteCount inflight_latest() const { return inflight_latest_; }
+  QuicByteCount inflight_lo() const { return inflight_lo_; }
+  static QuicByteCount inflight_lo_default() {
+    return std::numeric_limits<QuicByteCount>::max();
+  }
+  void clear_inflight_lo() { inflight_lo_ = inflight_lo_default(); }
+  void cap_inflight_lo(QuicByteCount cap);
+
+  QuicByteCount inflight_hi_with_headroom() const;
+  QuicByteCount inflight_hi() const { return inflight_hi_; }
+  static QuicByteCount inflight_hi_default() {
+    return std::numeric_limits<QuicByteCount>::max();
+  }
+  void set_inflight_hi(QuicByteCount inflight_hi) {
+    inflight_hi_ = inflight_hi;
+  }
+
+  float cwnd_gain() const { return cwnd_gain_; }
+  void set_cwnd_gain(float cwnd_gain) { cwnd_gain_ = cwnd_gain; }
+
+  float pacing_gain() const { return pacing_gain_; }
+  void set_pacing_gain(float pacing_gain) { pacing_gain_ = pacing_gain; }
+
+  bool full_bandwidth_reached() const { return full_bandwidth_reached_; }
+  void set_full_bandwidth_reached() { full_bandwidth_reached_ = true; }
+  QuicBandwidth full_bandwidth_baseline() const {
+    return full_bandwidth_baseline_;
+  }
+  QuicRoundTripCount rounds_without_bandwidth_growth() const {
+    return rounds_without_bandwidth_growth_;
+  }
+
+ private:
+  // Called when a new round trip starts.
+  void OnNewRound();
+
+  const Bbr2Params& Params() const { return *params_; }
+  const Bbr2Params* const params_;
+  RoundTripCounter round_trip_counter_;
+
+  // Bandwidth sampler provides BBR with the bandwidth measurements at
+  // individual points.
+  BandwidthSampler bandwidth_sampler_;
+  // The filter that tracks the maximum bandwidth over multiple recent round
+  // trips.
+  Bbr2MaxBandwidthFilter max_bandwidth_filter_;
+  MinRttFilter min_rtt_filter_;
+
+  // Bytes lost in the current round. Updated once per congestion event.
+  QuicByteCount bytes_lost_in_round_ = 0;
+  // Number of loss marking events in the current round.
+  int64_t loss_events_in_round_ = 0;
+
+  // A max of bytes delivered among all congestion events in the current round.
+  // A congestions event's bytes delivered is the total bytes acked between time
+  // Ts and Ta, which is the time when the largest acked packet(within the
+  // congestion event) was sent and acked, respectively.
+  QuicByteCount max_bytes_delivered_in_round_ = 0;
+
+  // The minimum bytes in flight during this round.
+  QuicByteCount min_bytes_in_flight_in_round_ = 0;
+
+  // Max bandwidth in the current round. Updated once per congestion event.
+  QuicBandwidth bandwidth_latest_ = QuicBandwidth::Zero();
+  // Max bandwidth of recent rounds. Updated once per round.
+  QuicBandwidth bandwidth_lo_ = bandwidth_lo_default();
+  // bandwidth_lo_ at the beginning of a round with loss. Only used when the
+  // bw_lo_mode is non-default.
+  QuicBandwidth prior_bandwidth_lo_ = QuicBandwidth::Zero();
+
+  // Max inflight in the current round. Updated once per congestion event.
+  QuicByteCount inflight_latest_ = 0;
+  // Max inflight of recent rounds. Updated once per round.
+  QuicByteCount inflight_lo_ = inflight_lo_default();
+  QuicByteCount inflight_hi_ = inflight_hi_default();
+
+  float cwnd_gain_;
+  float pacing_gain_;
+
+  // Whether we are cwnd limited prior to the start of the current aggregation
+  // epoch.
+  bool cwnd_limited_before_aggregation_epoch_ = false;
+
+  // STARTUP-centric fields which experimentally used by PROBE_UP.
+  bool full_bandwidth_reached_ = false;
+  QuicBandwidth full_bandwidth_baseline_ = QuicBandwidth::Zero();
+  QuicRoundTripCount rounds_without_bandwidth_growth_ = 0;
+};
+
+enum class Bbr2Mode : uint8_t {
+  // Startup phase of the connection.
+  STARTUP,
+  // After achieving the highest possible bandwidth during the startup, lower
+  // the pacing rate in order to drain the queue.
+  DRAIN,
+  // Cruising mode.
+  PROBE_BW,
+  // Temporarily slow down sending in order to empty the buffer and measure
+  // the real minimum RTT.
+  PROBE_RTT,
+};
+
+QUIC_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& os,
+                                                    const Bbr2Mode& mode) {
+  switch (mode) {
+    case Bbr2Mode::STARTUP:
+      return os << "STARTUP";
+    case Bbr2Mode::DRAIN:
+      return os << "DRAIN";
+    case Bbr2Mode::PROBE_BW:
+      return os << "PROBE_BW";
+    case Bbr2Mode::PROBE_RTT:
+      return os << "PROBE_RTT";
+  }
+  return os << "<Invalid Mode>";
+}
+
+// The base class for all BBRv2 modes. A Bbr2Sender is in one mode at a time,
+// this interface is used to implement mode-specific behaviors.
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2ModeBase {
+ public:
+  Bbr2ModeBase(const Bbr2Sender* sender, Bbr2NetworkModel* model)
+      : sender_(sender), model_(model) {}
+
+  virtual ~Bbr2ModeBase() = default;
+
+  // Called when entering/leaving this mode.
+  // congestion_event != nullptr means BBRv2 is switching modes in the context
+  // of a ack and/or loss.
+  virtual void Enter(QuicTime now,
+                     const Bbr2CongestionEvent* congestion_event) = 0;
+  virtual void Leave(QuicTime now,
+                     const Bbr2CongestionEvent* congestion_event) = 0;
+
+  virtual Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) = 0;
+
+  virtual Limits<QuicByteCount> GetCwndLimits() const = 0;
+
+  virtual bool IsProbingForBandwidth() const = 0;
+
+  virtual Bbr2Mode OnExitQuiescence(QuicTime now,
+                                    QuicTime quiescence_start_time) = 0;
+
+ protected:
+  const Bbr2Sender* const sender_;
+  Bbr2NetworkModel* model_;
+};
+
+QUIC_EXPORT_PRIVATE inline QuicByteCount BytesInFlight(
+    const SendTimeState& send_state) {
+  QUICHE_DCHECK(send_state.is_valid);
+  if (send_state.bytes_in_flight != 0) {
+    return send_state.bytes_in_flight;
+  }
+  return send_state.total_bytes_sent - send_state.total_bytes_acked -
+         send_state.total_bytes_lost;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_MISC_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_bw.cc b/quiche/quic/core/congestion_control/bbr2_probe_bw.cc
new file mode 100644
index 0000000..48d98de
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_bw.cc
@@ -0,0 +1,677 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr2_probe_bw.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+void Bbr2ProbeBwMode::Enter(QuicTime now,
+                            const Bbr2CongestionEvent* /*congestion_event*/) {
+  if (cycle_.phase == CyclePhase::PROBE_NOT_STARTED) {
+    // First time entering PROBE_BW. Start a new probing cycle.
+    EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/false,
+                   now);
+  } else {
+    // Transitioning from PROBE_RTT to PROBE_BW. Re-enter the last phase before
+    // PROBE_RTT.
+    QUICHE_DCHECK(cycle_.phase == CyclePhase::PROBE_CRUISE ||
+                  cycle_.phase == CyclePhase::PROBE_REFILL);
+    cycle_.cycle_start_time = now;
+    if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+      EnterProbeCruise(now);
+    } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
+      EnterProbeRefill(cycle_.probe_up_rounds, now);
+    }
+  }
+}
+
+Bbr2Mode Bbr2ProbeBwMode::OnCongestionEvent(
+    QuicByteCount prior_in_flight, QuicTime event_time,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_NE(cycle_.phase, CyclePhase::PROBE_NOT_STARTED);
+
+  if (congestion_event.end_of_round_trip) {
+    if (cycle_.cycle_start_time != event_time) {
+      ++cycle_.rounds_since_probe;
+    }
+    if (cycle_.phase_start_time != event_time) {
+      ++cycle_.rounds_in_phase;
+    }
+  }
+
+  bool switch_to_probe_rtt = false;
+
+  if (cycle_.phase == CyclePhase::PROBE_UP) {
+    UpdateProbeUp(prior_in_flight, congestion_event);
+  } else if (cycle_.phase == CyclePhase::PROBE_DOWN) {
+    UpdateProbeDown(prior_in_flight, congestion_event);
+    // Maybe transition to PROBE_RTT at the end of this cycle.
+    if (cycle_.phase != CyclePhase::PROBE_DOWN &&
+        model_->MaybeExpireMinRtt(congestion_event)) {
+      switch_to_probe_rtt = true;
+    }
+  } else if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+    UpdateProbeCruise(congestion_event);
+  } else if (cycle_.phase == CyclePhase::PROBE_REFILL) {
+    UpdateProbeRefill(congestion_event);
+  }
+
+  // Do not need to set the gains if switching to PROBE_RTT, they will be set
+  // when Bbr2ProbeRttMode::Enter is called.
+  if (!switch_to_probe_rtt) {
+    model_->set_pacing_gain(PacingGainForPhase(cycle_.phase));
+    model_->set_cwnd_gain(Params().probe_bw_cwnd_gain);
+  }
+
+  return switch_to_probe_rtt ? Bbr2Mode::PROBE_RTT : Bbr2Mode::PROBE_BW;
+}
+
+Limits<QuicByteCount> Bbr2ProbeBwMode::GetCwndLimits() const {
+  if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+    return NoGreaterThan(
+        std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom()));
+  }
+  if (Params().probe_up_ignore_inflight_hi &&
+      cycle_.phase == CyclePhase::PROBE_UP) {
+    // Similar to STARTUP.
+    return NoGreaterThan(model_->inflight_lo());
+  }
+
+  return NoGreaterThan(std::min(model_->inflight_lo(), model_->inflight_hi()));
+}
+
+bool Bbr2ProbeBwMode::IsProbingForBandwidth() const {
+  return cycle_.phase == CyclePhase::PROBE_REFILL ||
+         cycle_.phase == CyclePhase::PROBE_UP;
+}
+
+Bbr2Mode Bbr2ProbeBwMode::OnExitQuiescence(QuicTime now,
+                                           QuicTime quiescence_start_time) {
+  QUIC_DVLOG(3) << sender_ << " Postponing min_rtt_timestamp("
+                << model_->MinRttTimestamp() << ") by "
+                << now - quiescence_start_time;
+  model_->PostponeMinRttTimestamp(now - quiescence_start_time);
+  return Bbr2Mode::PROBE_BW;
+}
+
+// TODO(ianswett): Remove prior_in_flight from UpdateProbeDown.
+void Bbr2ProbeBwMode::UpdateProbeDown(
+    QuicByteCount prior_in_flight,
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
+
+  if (cycle_.rounds_in_phase == 1 && congestion_event.end_of_round_trip) {
+    cycle_.is_sample_from_probing = false;
+
+    if (!congestion_event.last_packet_send_state.is_app_limited) {
+      QUIC_DVLOG(2)
+          << sender_
+          << " Advancing max bw filter after one round in PROBE_DOWN.";
+      model_->AdvanceMaxBandwidthFilter();
+      cycle_.has_advanced_max_bw = true;
+    }
+
+    if (last_cycle_stopped_risky_probe_ && !last_cycle_probed_too_high_) {
+      EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
+      return;
+    }
+  }
+
+  MaybeAdaptUpperBounds(congestion_event);
+
+  if (IsTimeToProbeBandwidth(congestion_event)) {
+    EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
+    return;
+  }
+
+  if (HasStayedLongEnoughInProbeDown(congestion_event)) {
+    QUIC_DVLOG(3) << sender_ << " Proportional time based PROBE_DOWN exit";
+    EnterProbeCruise(congestion_event.event_time);
+    return;
+  }
+
+  const QuicByteCount inflight_with_headroom =
+      model_->inflight_hi_with_headroom();
+  QUIC_DVLOG(3)
+      << sender_
+      << " Checking if have enough inflight headroom. prior_in_flight:"
+      << prior_in_flight << " congestion_event.bytes_in_flight:"
+      << congestion_event.bytes_in_flight
+      << ", inflight_with_headroom:" << inflight_with_headroom;
+  QuicByteCount bytes_in_flight = congestion_event.bytes_in_flight;
+
+  if (bytes_in_flight > inflight_with_headroom) {
+    // Stay in PROBE_DOWN.
+    return;
+  }
+
+  // Transition to PROBE_CRUISE iff we've drained to target.
+  QuicByteCount bdp = model_->BDP();
+  QUIC_DVLOG(3) << sender_ << " Checking if drained to target. bytes_in_flight:"
+                << bytes_in_flight << ", bdp:" << bdp;
+  if (bytes_in_flight < bdp) {
+    EnterProbeCruise(congestion_event.event_time);
+  }
+}
+
+Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds(
+    const Bbr2CongestionEvent& congestion_event) {
+  const SendTimeState& send_state = congestion_event.last_packet_send_state;
+  if (!send_state.is_valid) {
+    QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                  << ": NOT_ADAPTED_INVALID_SAMPLE";
+    return NOT_ADAPTED_INVALID_SAMPLE;
+  }
+
+  // TODO(ianswett): Rename to bytes_delivered if
+  // use_bytes_delivered_for_inflight_hi is default enabled.
+  QuicByteCount inflight_at_send = BytesInFlight(send_state);
+  if (Params().use_bytes_delivered_for_inflight_hi) {
+    if (congestion_event.last_packet_send_state.total_bytes_acked <=
+        model_->total_bytes_acked()) {
+      inflight_at_send =
+          model_->total_bytes_acked() -
+          congestion_event.last_packet_send_state.total_bytes_acked;
+    } else {
+      QUIC_BUG(quic_bug_10436_1)
+          << "Total_bytes_acked(" << model_->total_bytes_acked()
+          << ") < send_state.total_bytes_acked("
+          << congestion_event.last_packet_send_state.total_bytes_acked << ")";
+    }
+  }
+  // TODO(ianswett): Inflight too high is really checking for loss, not
+  // inflight.
+  if (model_->IsInflightTooHigh(congestion_event,
+                                Params().probe_bw_full_loss_count)) {
+    if (cycle_.is_sample_from_probing) {
+      cycle_.is_sample_from_probing = false;
+      if (!send_state.is_app_limited ||
+          Params().probe_up_dont_exit_if_no_queue_) {
+        if (send_state.is_app_limited) {
+          // If there's excess loss or a queue is building, exit even if the
+          // last sample was app limited.
+          QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue,
+                                       2, 2);
+        }
+        const QuicByteCount inflight_target =
+            sender_->GetTargetBytesInflight() * (1.0 - Params().beta);
+        if (inflight_at_send >= inflight_target) {
+          // The new code does not change behavior.
+          QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_noop);
+        } else {
+          // The new code actually cuts inflight_hi slower than before.
+          QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_in_effect);
+        }
+        if (Params().limit_inflight_hi_by_max_delivered) {
+          QuicByteCount new_inflight_hi =
+              std::max(inflight_at_send, inflight_target);
+          if (new_inflight_hi >= model_->max_bytes_delivered_in_round()) {
+            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_noop);
+          } else {
+            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_max_delivered_in_effect);
+            new_inflight_hi = model_->max_bytes_delivered_in_round();
+          }
+          QUIC_DVLOG(3) << sender_
+                        << " Setting inflight_hi due to loss. new_inflight_hi:"
+                        << new_inflight_hi
+                        << ", inflight_at_send:" << inflight_at_send
+                        << ", inflight_target:" << inflight_target
+                        << ", max_bytes_delivered_in_round:"
+                        << model_->max_bytes_delivered_in_round() << "  @ "
+                        << congestion_event.event_time;
+          model_->set_inflight_hi(new_inflight_hi);
+        } else {
+          model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
+        }
+      }
+
+      QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                    << ": ADAPTED_PROBED_TOO_HIGH";
+      return ADAPTED_PROBED_TOO_HIGH;
+    }
+    return ADAPTED_OK;
+  }
+
+  if (model_->inflight_hi() == model_->inflight_hi_default()) {
+    QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                  << ": NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET";
+    return NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET;
+  }
+
+  // Raise the upper bound for inflight.
+  if (inflight_at_send > model_->inflight_hi()) {
+    QUIC_DVLOG(3)
+        << sender_ << " " << cycle_.phase
+        << ": Adapting inflight_hi from inflight_at_send. inflight_at_send:"
+        << inflight_at_send << ", old inflight_hi:" << model_->inflight_hi();
+    model_->set_inflight_hi(inflight_at_send);
+  }
+
+  return ADAPTED_OK;
+}
+
+bool Bbr2ProbeBwMode::IsTimeToProbeBandwidth(
+    const Bbr2CongestionEvent& congestion_event) const {
+  if (HasCycleLasted(cycle_.probe_wait_time, congestion_event)) {
+    return true;
+  }
+
+  if (IsTimeToProbeForRenoCoexistence(1.0, congestion_event)) {
+    ++sender_->connection_stats_->bbr_num_short_cycles_for_reno_coexistence;
+    return true;
+  }
+  return false;
+}
+
+// QUIC only. Used to prevent a Bbr2 flow from staying in PROBE_DOWN for too
+// long, as seen in some multi-sender simulator tests.
+bool Bbr2ProbeBwMode::HasStayedLongEnoughInProbeDown(
+    const Bbr2CongestionEvent& congestion_event) const {
+  // Stay in PROBE_DOWN for at most the time of a min rtt, as it is done in
+  // BBRv1.
+  // TODO(wub): Consider exit after a full round instead, which typically
+  // indicates most(if not all) packets sent during PROBE_UP have been acked.
+  return HasPhaseLasted(model_->MinRtt(), congestion_event);
+}
+
+bool Bbr2ProbeBwMode::HasCycleLasted(
+    QuicTime::Delta duration,
+    const Bbr2CongestionEvent& congestion_event) const {
+  bool result =
+      (congestion_event.event_time - cycle_.cycle_start_time) > duration;
+  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                << ": HasCycleLasted=" << result << ". elapsed:"
+                << (congestion_event.event_time - cycle_.cycle_start_time)
+                << ", duration:" << duration;
+  return result;
+}
+
+bool Bbr2ProbeBwMode::HasPhaseLasted(
+    QuicTime::Delta duration,
+    const Bbr2CongestionEvent& congestion_event) const {
+  bool result =
+      (congestion_event.event_time - cycle_.phase_start_time) > duration;
+  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                << ": HasPhaseLasted=" << result << ". elapsed:"
+                << (congestion_event.event_time - cycle_.phase_start_time)
+                << ", duration:" << duration;
+  return result;
+}
+
+bool Bbr2ProbeBwMode::IsTimeToProbeForRenoCoexistence(
+    double probe_wait_fraction,
+    const Bbr2CongestionEvent& /*congestion_event*/) const {
+  if (!Params().enable_reno_coexistence) {
+    return false;
+  }
+
+  uint64_t rounds = Params().probe_bw_probe_max_rounds;
+  if (Params().probe_bw_probe_reno_gain > 0.0) {
+    QuicByteCount target_bytes_inflight = sender_->GetTargetBytesInflight();
+    uint64_t reno_rounds = Params().probe_bw_probe_reno_gain *
+                           target_bytes_inflight / kDefaultTCPMSS;
+    rounds = std::min(rounds, reno_rounds);
+  }
+  bool result = cycle_.rounds_since_probe >= (rounds * probe_wait_fraction);
+  QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
+                << ": IsTimeToProbeForRenoCoexistence=" << result
+                << ". rounds_since_probe:" << cycle_.rounds_since_probe
+                << ", rounds:" << rounds
+                << ", probe_wait_fraction:" << probe_wait_fraction;
+  return result;
+}
+
+void Bbr2ProbeBwMode::RaiseInflightHighSlope() {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
+  uint64_t growth_this_round = 1 << cycle_.probe_up_rounds;
+  // The number 30 below means |growth_this_round| is capped at 1G and the lower
+  // bound of |probe_up_bytes| is (practically) 1 mss, at this speed inflight_hi
+  // grows by approximately 1 packet per packet acked.
+  cycle_.probe_up_rounds = std::min<uint64_t>(cycle_.probe_up_rounds + 1, 30);
+  uint64_t probe_up_bytes = sender_->GetCongestionWindow() / growth_this_round;
+  cycle_.probe_up_bytes =
+      std::max<QuicByteCount>(probe_up_bytes, kDefaultTCPMSS);
+  QUIC_DVLOG(3) << sender_ << " Rasing inflight_hi slope. probe_up_rounds:"
+                << cycle_.probe_up_rounds
+                << ", probe_up_bytes:" << cycle_.probe_up_bytes;
+}
+
+void Bbr2ProbeBwMode::ProbeInflightHighUpward(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
+  if (Params().probe_up_ignore_inflight_hi) {
+    // When inflight_hi is disabled in PROBE_UP, it increases when
+    // the number of bytes delivered in a round is larger inflight_hi.
+    return;
+  }
+  if (Params().probe_bw_check_cwnd_limited_before_aggregation_epoch) {
+    if (!model_->cwnd_limited_before_aggregation_epoch()) {
+      QUIC_DVLOG(3) << sender_
+                    << " Raising inflight_hi early return: Not cwnd limited "
+                       "before aggregation epoch.";
+      // Not fully utilizing cwnd, so can't safely grow.
+      return;
+    }
+  } else if (Params().probe_up_includes_acks_after_cwnd_limited) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_bbr2_add_bytes_acked_after_inflight_hi_limited);
+    // Don't continue adding bytes to probe_up_acked if the sender was not
+    // app-limited after being inflight_hi limited at least once.
+    if (!cycle_.probe_up_app_limited_since_inflight_hi_limited_ ||
+        congestion_event.last_packet_send_state.is_app_limited) {
+      cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
+      if (congestion_event.prior_bytes_in_flight <
+          congestion_event.prior_cwnd) {
+        QUIC_DVLOG(3) << sender_
+                      << " Raising inflight_hi early return: Not cwnd limited.";
+        // Not fully utilizing cwnd, so can't safely grow.
+        return;
+      }
+
+      if (congestion_event.prior_cwnd < model_->inflight_hi()) {
+        QUIC_DVLOG(3)
+            << sender_
+            << " Raising inflight_hi early return: inflight_hi not fully used.";
+        // Not fully using inflight_hi, so don't grow it.
+        return;
+      }
+    }
+    // Start a new period of adding bytes_acked, because inflight_hi limited.
+    cycle_.probe_up_app_limited_since_inflight_hi_limited_ = true;
+  } else {
+    if (congestion_event.prior_bytes_in_flight < congestion_event.prior_cwnd) {
+      QUIC_DVLOG(3) << sender_
+                    << " Raising inflight_hi early return: Not cwnd limited.";
+      // Not fully utilizing cwnd, so can't safely grow.
+      return;
+    }
+  }
+
+  if (congestion_event.prior_cwnd < model_->inflight_hi()) {
+    QUIC_DVLOG(3)
+        << sender_
+        << " Raising inflight_hi early return: inflight_hi not fully used.";
+    // Not fully using inflight_hi, so don't grow it.
+    return;
+  }
+
+  // Increase inflight_hi by the number of probe_up_bytes within probe_up_acked.
+  cycle_.probe_up_acked += congestion_event.bytes_acked;
+  if (cycle_.probe_up_acked >= cycle_.probe_up_bytes) {
+    uint64_t delta = cycle_.probe_up_acked / cycle_.probe_up_bytes;
+    cycle_.probe_up_acked -= delta * cycle_.probe_up_bytes;
+    QuicByteCount new_inflight_hi =
+        model_->inflight_hi() + delta * kDefaultTCPMSS;
+    if (new_inflight_hi > model_->inflight_hi()) {
+      QUIC_DVLOG(3) << sender_ << " Raising inflight_hi from "
+                    << model_->inflight_hi() << " to " << new_inflight_hi
+                    << ". probe_up_bytes:" << cycle_.probe_up_bytes
+                    << ", delta:" << delta
+                    << ", (new)probe_up_acked:" << cycle_.probe_up_acked;
+
+      model_->set_inflight_hi(new_inflight_hi);
+    } else {
+      QUIC_BUG(quic_bug_10436_2)
+          << "Not growing inflight_hi due to wrap around. Old value:"
+          << model_->inflight_hi() << ", new value:" << new_inflight_hi;
+    }
+  }
+
+  if (congestion_event.end_of_round_trip) {
+    RaiseInflightHighSlope();
+  }
+}
+
+void Bbr2ProbeBwMode::UpdateProbeCruise(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_CRUISE);
+  MaybeAdaptUpperBounds(congestion_event);
+  QUICHE_DCHECK(!cycle_.is_sample_from_probing);
+
+  if (IsTimeToProbeBandwidth(congestion_event)) {
+    EnterProbeRefill(/*probe_up_rounds=*/0, congestion_event.event_time);
+    return;
+  }
+}
+
+void Bbr2ProbeBwMode::UpdateProbeRefill(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
+  MaybeAdaptUpperBounds(congestion_event);
+  QUICHE_DCHECK(!cycle_.is_sample_from_probing);
+
+  if (cycle_.rounds_in_phase > 0 && congestion_event.end_of_round_trip) {
+    EnterProbeUp(congestion_event.event_time);
+    return;
+  }
+}
+
+void Bbr2ProbeBwMode::UpdateProbeUp(
+    QuicByteCount prior_in_flight,
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_UP);
+  if (MaybeAdaptUpperBounds(congestion_event) == ADAPTED_PROBED_TOO_HIGH) {
+    EnterProbeDown(/*probed_too_high=*/true, /*stopped_risky_probe=*/false,
+                   congestion_event.event_time);
+    return;
+  }
+
+  // TODO(wub): Consider exit PROBE_UP after a certain number(e.g. 64) of RTTs.
+
+  ProbeInflightHighUpward(congestion_event);
+
+  bool is_risky = false;
+  bool is_queuing = false;
+  if (last_cycle_probed_too_high_ && prior_in_flight >= model_->inflight_hi()) {
+    is_risky = true;
+    QUIC_DVLOG(3) << sender_
+                  << " Probe is too risky. last_cycle_probed_too_high_:"
+                  << last_cycle_probed_too_high_
+                  << ", prior_in_flight:" << prior_in_flight
+                  << ", inflight_hi:" << model_->inflight_hi();
+    // TCP uses min_rtt instead of a full round:
+    //   HasPhaseLasted(model_->MinRtt(), congestion_event)
+  } else if (cycle_.rounds_in_phase > 0) {
+    if (Params().probe_up_dont_exit_if_no_queue_) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_no_probe_up_exit_if_no_queue, 1,
+                                   2);
+      is_queuing = congestion_event.end_of_round_trip &&
+                   model_->CheckPersistentQueue(
+                       congestion_event, Params().probe_bw_probe_inflight_gain);
+    } else {
+      QuicByteCount queuing_threshold_extra_bytes =
+          model_->QueueingThresholdExtraBytes();
+      if (Params().add_ack_height_to_queueing_threshold) {
+        queuing_threshold_extra_bytes += model_->MaxAckHeight();
+      }
+      QuicByteCount queuing_threshold =
+          (Params().probe_bw_probe_inflight_gain * model_->BDP()) +
+          queuing_threshold_extra_bytes;
+
+      is_queuing = congestion_event.bytes_in_flight >= queuing_threshold;
+
+      QUIC_DVLOG(3) << sender_
+                    << " Checking if building up a queue. prior_in_flight:"
+                    << prior_in_flight
+                    << ", post_in_flight:" << congestion_event.bytes_in_flight
+                    << ", threshold:" << queuing_threshold
+                    << ", is_queuing:" << is_queuing
+                    << ", max_bw:" << model_->MaxBandwidth()
+                    << ", min_rtt:" << model_->MinRtt();
+    }
+  }
+
+  if (is_risky || is_queuing) {
+    EnterProbeDown(/*probed_too_high=*/false, /*stopped_risky_probe=*/is_risky,
+                   congestion_event.event_time);
+  }
+}
+
+void Bbr2ProbeBwMode::EnterProbeDown(bool probed_too_high,
+                                     bool stopped_risky_probe, QuicTime now) {
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_DOWN << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase
+                << " rounds. probed_too_high:" << probed_too_high
+                << ", stopped_risky_probe:" << stopped_risky_probe << "  @ "
+                << now;
+  last_cycle_probed_too_high_ = probed_too_high;
+  last_cycle_stopped_risky_probe_ = stopped_risky_probe;
+
+  cycle_.cycle_start_time = now;
+  cycle_.phase = CyclePhase::PROBE_DOWN;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  ++sender_->connection_stats_->bbr_num_cycles;
+  if (Params().bw_lo_mode_ != Bbr2Params::QuicBandwidthLoMode::DEFAULT) {
+    // Clear bandwidth lo if it was set in PROBE_UP, because losses in PROBE_UP
+    // should not permanently change bandwidth_lo.
+    // It's possible for bandwidth_lo to be set during REFILL, but if that was
+    // a valid value, it'll quickly be rediscovered.
+    model_->clear_bandwidth_lo();
+  }
+
+  // Pick probe wait time.
+  cycle_.rounds_since_probe =
+      sender_->RandomUint64(Params().probe_bw_max_probe_rand_rounds);
+  cycle_.probe_wait_time =
+      Params().probe_bw_probe_base_duration +
+      QuicTime::Delta::FromMicroseconds(sender_->RandomUint64(
+          Params().probe_bw_probe_max_rand_duration.ToMicroseconds()));
+
+  cycle_.probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
+  cycle_.probe_up_app_limited_since_inflight_hi_limited_ = false;
+  cycle_.has_advanced_max_bw = false;
+  model_->RestartRoundEarly();
+}
+
+void Bbr2ProbeBwMode::EnterProbeCruise(QuicTime now) {
+  if (cycle_.phase == CyclePhase::PROBE_DOWN) {
+    ExitProbeDown();
+  }
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_CRUISE << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase << " rounds.  @ " << now;
+
+  model_->cap_inflight_lo(model_->inflight_hi());
+  cycle_.phase = CyclePhase::PROBE_CRUISE;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  cycle_.is_sample_from_probing = false;
+}
+
+void Bbr2ProbeBwMode::EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now) {
+  if (cycle_.phase == CyclePhase::PROBE_DOWN) {
+    ExitProbeDown();
+  }
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_REFILL << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase
+                << " rounds. probe_up_rounds:" << probe_up_rounds << "  @ "
+                << now;
+  cycle_.phase = CyclePhase::PROBE_REFILL;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  cycle_.is_sample_from_probing = false;
+  last_cycle_stopped_risky_probe_ = false;
+
+  model_->clear_bandwidth_lo();
+  model_->clear_inflight_lo();
+  cycle_.probe_up_rounds = probe_up_rounds;
+  cycle_.probe_up_acked = 0;
+  model_->RestartRoundEarly();
+}
+
+void Bbr2ProbeBwMode::EnterProbeUp(QuicTime now) {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_REFILL);
+  QUIC_DVLOG(2) << sender_ << " Phase change: " << cycle_.phase << " ==> "
+                << CyclePhase::PROBE_UP << " after "
+                << now - cycle_.phase_start_time << ", or "
+                << cycle_.rounds_in_phase << " rounds.  @ " << now;
+  cycle_.phase = CyclePhase::PROBE_UP;
+  cycle_.rounds_in_phase = 0;
+  cycle_.phase_start_time = now;
+  cycle_.is_sample_from_probing = true;
+  RaiseInflightHighSlope();
+
+  model_->RestartRoundEarly();
+}
+
+void Bbr2ProbeBwMode::ExitProbeDown() {
+  QUICHE_DCHECK_EQ(cycle_.phase, CyclePhase::PROBE_DOWN);
+  if (!cycle_.has_advanced_max_bw) {
+    QUIC_DVLOG(2) << sender_ << " Advancing max bw filter at end of cycle.";
+    model_->AdvanceMaxBandwidthFilter();
+    cycle_.has_advanced_max_bw = true;
+  }
+}
+
+// static
+const char* Bbr2ProbeBwMode::CyclePhaseToString(CyclePhase phase) {
+  switch (phase) {
+    case CyclePhase::PROBE_NOT_STARTED:
+      return "PROBE_NOT_STARTED";
+    case CyclePhase::PROBE_UP:
+      return "PROBE_UP";
+    case CyclePhase::PROBE_DOWN:
+      return "PROBE_DOWN";
+    case CyclePhase::PROBE_CRUISE:
+      return "PROBE_CRUISE";
+    case CyclePhase::PROBE_REFILL:
+      return "PROBE_REFILL";
+    default:
+      break;
+  }
+  return "<Invalid CyclePhase>";
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2ProbeBwMode::CyclePhase phase) {
+  return os << Bbr2ProbeBwMode::CyclePhaseToString(phase);
+}
+
+Bbr2ProbeBwMode::DebugState Bbr2ProbeBwMode::ExportDebugState() const {
+  DebugState s;
+  s.phase = cycle_.phase;
+  s.cycle_start_time = cycle_.cycle_start_time;
+  s.phase_start_time = cycle_.phase_start_time;
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2ProbeBwMode::DebugState& state) {
+  os << "[PROBE_BW] phase: " << state.phase << "\n";
+  os << "[PROBE_BW] cycle_start_time: " << state.cycle_start_time << "\n";
+  os << "[PROBE_BW] phase_start_time: " << state.phase_start_time << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2ProbeBwMode::Params() const { return sender_->Params(); }
+
+float Bbr2ProbeBwMode::PacingGainForPhase(
+    Bbr2ProbeBwMode::CyclePhase phase) const {
+  if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_UP) {
+    return Params().probe_bw_probe_up_pacing_gain;
+  }
+  if (phase == Bbr2ProbeBwMode::CyclePhase::PROBE_DOWN) {
+    return Params().probe_bw_probe_down_pacing_gain;
+  }
+  return Params().probe_bw_default_pacing_gain;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_bw.h b/quiche/quic/core/congestion_control/bbr2_probe_bw.h
new file mode 100644
index 0000000..972e2ba
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_bw.h
@@ -0,0 +1,142 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2ProbeBwMode final : public Bbr2ModeBase {
+ public:
+  using Bbr2ModeBase::Bbr2ModeBase;
+
+  void Enter(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+  void Leave(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override;
+
+  bool IsProbingForBandwidth() const override;
+
+  Bbr2Mode OnExitQuiescence(QuicTime now,
+                            QuicTime quiescence_start_time) override;
+
+  enum class CyclePhase : uint8_t {
+    PROBE_NOT_STARTED,
+    PROBE_UP,
+    PROBE_DOWN,
+    PROBE_CRUISE,
+    PROBE_REFILL,
+  };
+
+  static const char* CyclePhaseToString(CyclePhase phase);
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    CyclePhase phase;
+    QuicTime cycle_start_time = QuicTime::Zero();
+    QuicTime phase_start_time = QuicTime::Zero();
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+  float PacingGainForPhase(CyclePhase phase) const;
+
+  void UpdateProbeUp(QuicByteCount prior_in_flight,
+                     const Bbr2CongestionEvent& congestion_event);
+  void UpdateProbeDown(QuicByteCount prior_in_flight,
+                       const Bbr2CongestionEvent& congestion_event);
+  void UpdateProbeCruise(const Bbr2CongestionEvent& congestion_event);
+  void UpdateProbeRefill(const Bbr2CongestionEvent& congestion_event);
+
+  enum AdaptUpperBoundsResult : uint8_t {
+    ADAPTED_OK,
+    ADAPTED_PROBED_TOO_HIGH,
+    NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET,
+    NOT_ADAPTED_INVALID_SAMPLE,
+  };
+
+  // Return whether adapted inflight_hi. If inflight is too high, this function
+  // will not adapt inflight_hi and will return false.
+  AdaptUpperBoundsResult MaybeAdaptUpperBounds(
+      const Bbr2CongestionEvent& congestion_event);
+
+  void EnterProbeDown(bool probed_too_high,
+                      bool stopped_risky_probe,
+                      QuicTime now);
+  void EnterProbeCruise(QuicTime now);
+  void EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now);
+  void EnterProbeUp(QuicTime now);
+
+  // Call right before the exit of PROBE_DOWN.
+  void ExitProbeDown();
+
+  float PercentTimeElapsedToProbeBandwidth(
+      const Bbr2CongestionEvent& congestion_event) const;
+
+  bool IsTimeToProbeBandwidth(
+      const Bbr2CongestionEvent& congestion_event) const;
+  bool HasStayedLongEnoughInProbeDown(
+      const Bbr2CongestionEvent& congestion_event) const;
+  bool HasCycleLasted(QuicTime::Delta duration,
+                      const Bbr2CongestionEvent& congestion_event) const;
+  bool HasPhaseLasted(QuicTime::Delta duration,
+                      const Bbr2CongestionEvent& congestion_event) const;
+  bool IsTimeToProbeForRenoCoexistence(
+      double probe_wait_fraction,
+      const Bbr2CongestionEvent& congestion_event) const;
+
+  void RaiseInflightHighSlope();
+  void ProbeInflightHighUpward(const Bbr2CongestionEvent& congestion_event);
+
+  struct QUIC_EXPORT_PRIVATE Cycle {
+    QuicTime cycle_start_time = QuicTime::Zero();
+    CyclePhase phase = CyclePhase::PROBE_NOT_STARTED;
+    uint64_t rounds_in_phase = 0;
+    QuicTime phase_start_time = QuicTime::Zero();
+    QuicRoundTripCount rounds_since_probe = 0;
+    QuicTime::Delta probe_wait_time = QuicTime::Delta::Zero();
+    uint64_t probe_up_rounds = 0;
+    QuicByteCount probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
+    QuicByteCount probe_up_acked = 0;
+    bool probe_up_app_limited_since_inflight_hi_limited_ = false;
+    // Whether max bandwidth filter window has advanced in this cycle. It is
+    // advanced once per cycle.
+    bool has_advanced_max_bw = false;
+    bool is_sample_from_probing = false;
+  } cycle_;
+
+  bool last_cycle_probed_too_high_;
+  bool last_cycle_stopped_risky_probe_;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2ProbeBwMode::DebugState& state);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2ProbeBwMode::CyclePhase phase);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc b/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc
new file mode 100644
index 0000000..ef5b775
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc
@@ -0,0 +1,83 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr2_probe_rtt.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+void Bbr2ProbeRttMode::Enter(QuicTime /*now*/,
+                             const Bbr2CongestionEvent* /*congestion_event*/) {
+  model_->set_pacing_gain(1.0);
+  model_->set_cwnd_gain(1.0);
+  exit_time_ = QuicTime::Zero();
+}
+
+Bbr2Mode Bbr2ProbeRttMode::OnCongestionEvent(
+    QuicByteCount /*prior_in_flight*/,
+    QuicTime /*event_time*/,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  if (exit_time_ == QuicTime::Zero()) {
+    if (congestion_event.bytes_in_flight <= InflightTarget() ||
+        congestion_event.bytes_in_flight <=
+            sender_->GetMinimumCongestionWindow()) {
+      exit_time_ = congestion_event.event_time + Params().probe_rtt_duration;
+      QUIC_DVLOG(2) << sender_ << " PROBE_RTT exit time set to " << exit_time_
+                    << ". bytes_inflight:" << congestion_event.bytes_in_flight
+                    << ", inflight_target:" << InflightTarget()
+                    << ", min_congestion_window:"
+                    << sender_->GetMinimumCongestionWindow() << "  @ "
+                    << congestion_event.event_time;
+    }
+    return Bbr2Mode::PROBE_RTT;
+  }
+
+  return congestion_event.event_time > exit_time_ ? Bbr2Mode::PROBE_BW
+                                                  : Bbr2Mode::PROBE_RTT;
+}
+
+QuicByteCount Bbr2ProbeRttMode::InflightTarget() const {
+  return model_->BDP(model_->MaxBandwidth(),
+                     Params().probe_rtt_inflight_target_bdp_fraction);
+}
+
+Limits<QuicByteCount> Bbr2ProbeRttMode::GetCwndLimits() const {
+  QuicByteCount inflight_upper_bound =
+      std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom());
+  return NoGreaterThan(std::min(inflight_upper_bound, InflightTarget()));
+}
+
+Bbr2Mode Bbr2ProbeRttMode::OnExitQuiescence(
+    QuicTime now,
+    QuicTime /*quiescence_start_time*/) {
+  if (now > exit_time_) {
+    return Bbr2Mode::PROBE_BW;
+  }
+  return Bbr2Mode::PROBE_RTT;
+}
+
+Bbr2ProbeRttMode::DebugState Bbr2ProbeRttMode::ExportDebugState() const {
+  DebugState s;
+  s.inflight_target = InflightTarget();
+  s.exit_time = exit_time_;
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2ProbeRttMode::DebugState& state) {
+  os << "[PROBE_RTT] inflight_target: " << state.inflight_target << "\n";
+  os << "[PROBE_RTT] exit_time: " << state.exit_time << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2ProbeRttMode::Params() const {
+  return sender_->Params();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_probe_rtt.h b/quiche/quic/core/congestion_control/bbr2_probe_rtt.h
new file mode 100644
index 0000000..1640c28
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_probe_rtt.h
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2ProbeRttMode final : public Bbr2ModeBase {
+ public:
+  using Bbr2ModeBase::Bbr2ModeBase;
+
+  void Enter(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+  void Leave(QuicTime /*now*/,
+             const Bbr2CongestionEvent* /*congestion_event*/) override {}
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override;
+
+  bool IsProbingForBandwidth() const override { return false; }
+
+  Bbr2Mode OnExitQuiescence(QuicTime now,
+                            QuicTime quiescence_start_time) override;
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    QuicByteCount inflight_target;
+    QuicTime exit_time = QuicTime::Zero();
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+
+  QuicByteCount InflightTarget() const;
+
+  QuicTime exit_time_ = QuicTime::Zero();
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2ProbeRttMode::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_RTT_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.cc b/quiche/quic/core/congestion_control/bbr2_sender.cc
new file mode 100644
index 0000000..6c40e85
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_sender.cc
@@ -0,0 +1,578 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+
+#include <cstddef>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/bbr2_drain.h"
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+
+namespace {
+// Constants based on TCP defaults.
+// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
+// Does not inflate the pacing rate.
+const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
+
+const float kInitialPacingGain = 2.885f;
+
+const int kMaxModeChangesPerCongestionEvent = 4;
+}  // namespace
+
+// Call |member_function_call| based on the current Bbr2Mode we are in. e.g.
+//
+//   auto result = BBR2_MODE_DISPATCH(Foo());
+//
+// is equivalent to:
+//
+//   Bbr2ModeBase& Bbr2Sender::GetCurrentMode() {
+//     if (mode_ == Bbr2Mode::STARTUP) { return startup_; }
+//     if (mode_ == Bbr2Mode::DRAIN) { return drain_; }
+//     ...
+//   }
+//   auto result = GetCurrentMode().Foo();
+//
+// Except that BBR2_MODE_DISPATCH guarantees the call to Foo() is non-virtual.
+//
+#define BBR2_MODE_DISPATCH(member_function_call)     \
+  (mode_ == Bbr2Mode::STARTUP                        \
+       ? (startup_.member_function_call)             \
+       : (mode_ == Bbr2Mode::PROBE_BW                \
+              ? (probe_bw_.member_function_call)     \
+              : (mode_ == Bbr2Mode::DRAIN            \
+                     ? (drain_.member_function_call) \
+                     : (probe_rtt_or_die().member_function_call))))
+
+Bbr2Sender::Bbr2Sender(QuicTime now,
+                       const RttStats* rtt_stats,
+                       const QuicUnackedPacketMap* unacked_packets,
+                       QuicPacketCount initial_cwnd_in_packets,
+                       QuicPacketCount max_cwnd_in_packets,
+                       QuicRandom* random,
+                       QuicConnectionStats* stats,
+                       BbrSender* old_sender)
+    : mode_(Bbr2Mode::STARTUP),
+      rtt_stats_(rtt_stats),
+      unacked_packets_(unacked_packets),
+      random_(random),
+      connection_stats_(stats),
+      params_(kDefaultMinimumCongestionWindow,
+              max_cwnd_in_packets * kDefaultTCPMSS),
+      model_(&params_,
+             rtt_stats->SmoothedOrInitialRtt(),
+             rtt_stats->last_update_time(),
+             /*cwnd_gain=*/1.0,
+             /*pacing_gain=*/kInitialPacingGain,
+             old_sender ? &old_sender->sampler_ : nullptr),
+      initial_cwnd_(cwnd_limits().ApplyLimits(
+          (old_sender) ? old_sender->GetCongestionWindow()
+                       : (initial_cwnd_in_packets * kDefaultTCPMSS))),
+      cwnd_(initial_cwnd_),
+      pacing_rate_(kInitialPacingGain * QuicBandwidth::FromBytesAndTimeDelta(
+                                            cwnd_,
+                                            rtt_stats->SmoothedOrInitialRtt())),
+      startup_(this, &model_, now),
+      drain_(this, &model_),
+      probe_bw_(this, &model_),
+      probe_rtt_(this, &model_),
+      last_sample_is_app_limited_(false) {
+  QUIC_DVLOG(2) << this << " Initializing Bbr2Sender. mode:" << mode_
+                << ", PacingRate:" << pacing_rate_ << ", Cwnd:" << cwnd_
+                << ", CwndLimits:" << cwnd_limits() << "  @ " << now;
+  QUICHE_DCHECK_EQ(mode_, Bbr2Mode::STARTUP);
+}
+
+void Bbr2Sender::SetFromConfig(const QuicConfig& config,
+                               Perspective perspective) {
+  if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
+    params_.add_ack_height_to_queueing_threshold = false;
+  }
+  if (config.HasClientRequestedIndependentOption(kB2RP, perspective)) {
+    params_.avoid_unnecessary_probe_rtt = false;
+  }
+  if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
+    params_.startup_full_bw_rounds = 1;
+  }
+  if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
+    params_.startup_full_bw_rounds = 2;
+  }
+  if (config.HasClientRequestedIndependentOption(kB2HR, perspective)) {
+    params_.inflight_hi_headroom = 0.15;
+  }
+  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
+    max_cwnd_when_network_parameters_adjusted_ = 100 * kDefaultTCPMSS;
+  }
+
+  ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
+}
+
+void Bbr2Sender::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
+      ContainsQuicTag(connection_options, kBBR4)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 1, 2);
+    model_.SetMaxAckHeightTrackerWindowLength(20);
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_extra_acked_window) &&
+      ContainsQuicTag(connection_options, kBBR5)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_extra_acked_window, 2, 2);
+    model_.SetMaxAckHeightTrackerWindowLength(40);
+  }
+  if (ContainsQuicTag(connection_options, kBBQ2)) {
+    params_.startup_cwnd_gain = 2.885;
+    params_.drain_cwnd_gain = 2.885;
+    model_.set_cwnd_gain(params_.startup_cwnd_gain);
+  }
+  if (ContainsQuicTag(connection_options, kB2LO)) {
+    params_.ignore_inflight_lo = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2NE)) {
+    params_.always_exit_startup_on_excess_loss = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2SL)) {
+    params_.startup_loss_exit_use_max_delivered_for_inflight_hi = false;
+  }
+  if (ContainsQuicTag(connection_options, kB2H2)) {
+    params_.limit_inflight_hi_by_max_delivered = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2DL)) {
+    params_.use_bytes_delivered_for_inflight_hi = true;
+  }
+  if (ContainsQuicTag(connection_options, kB2RC)) {
+    params_.enable_reno_coexistence = false;
+  }
+  if (ContainsQuicTag(connection_options, kBSAO)) {
+    model_.EnableOverestimateAvoidance();
+  }
+  if (ContainsQuicTag(connection_options, kBBQ6)) {
+    params_.decrease_startup_pacing_at_end_of_round = true;
+  }
+  if (ContainsQuicTag(connection_options, kBBQ7)) {
+    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::MIN_RTT_REDUCTION;
+  }
+  if (ContainsQuicTag(connection_options, kBBQ8)) {
+    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::INFLIGHT_REDUCTION;
+  }
+  if (ContainsQuicTag(connection_options, kBBQ9)) {
+    params_.bw_lo_mode_ = Bbr2Params::QuicBandwidthLoMode::CWND_REDUCTION;
+  }
+  if (ContainsQuicTag(connection_options, kB201)) {
+    params_.probe_bw_check_cwnd_limited_before_aggregation_epoch = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue) &&
+      ContainsQuicTag(connection_options, kB202)) {
+    params_.probe_up_dont_exit_if_no_queue_ = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up) &&
+      ContainsQuicTag(connection_options, kB203)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_ignore_inflight_hi_in_probe_up);
+    params_.probe_up_ignore_inflight_hi = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
+      ContainsQuicTag(connection_options, kB204)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 1, 2);
+    model_.SetReduceExtraAckedOnBandwidthIncrease(true);
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_startup_extra_acked) &&
+      ContainsQuicTag(connection_options, kB205)) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_startup_extra_acked, 2, 2);
+    params_.startup_include_extra_acked = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2) &&
+      ContainsQuicTag(connection_options, kB207)) {
+    params_.exit_startup_on_persistent_queue = true;
+  }
+
+  if (ContainsQuicTag(connection_options, kBBRA)) {
+    model_.SetStartNewAggregationEpochAfterFullRound(true);
+  }
+  if (ContainsQuicTag(connection_options, kBBRB)) {
+    model_.SetLimitMaxAckHeightTrackerBySendRate(true);
+  }
+  if (GetQuicReloadableFlag(
+          quic_bbr2_add_bytes_acked_after_inflight_hi_limited) &&
+      ContainsQuicTag(connection_options, kBBQ0)) {
+    params_.probe_up_includes_acks_after_cwnd_limited = true;
+  }
+
+  if (GetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events) &&
+      ContainsQuicTag(connection_options, kB206)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_startup_probe_up_loss_events);
+    params_.startup_full_loss_count = params_.probe_bw_full_loss_count;
+  }
+}
+
+Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
+  switch (mode_) {
+    case Bbr2Mode::STARTUP:
+      return startup_.GetCwndLimits();
+    case Bbr2Mode::PROBE_BW:
+      return probe_bw_.GetCwndLimits();
+    case Bbr2Mode::DRAIN:
+      return drain_.GetCwndLimits();
+    case Bbr2Mode::PROBE_RTT:
+      return probe_rtt_.GetCwndLimits();
+    default:
+      QUIC_NOTREACHED();
+      return Unlimited<QuicByteCount>();
+  }
+}
+
+const Limits<QuicByteCount>& Bbr2Sender::cwnd_limits() const {
+  return params().cwnd_limits;
+}
+
+void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) {
+  model_.UpdateNetworkParameters(params.rtt);
+
+  if (mode_ == Bbr2Mode::STARTUP) {
+    const QuicByteCount prior_cwnd = cwnd_;
+
+    QuicBandwidth effective_bandwidth =
+        std::max(params.bandwidth, model_.BandwidthEstimate());
+    connection_stats_->cwnd_bootstrapping_rtt_us =
+        model_.MinRtt().ToMicroseconds();
+
+    if (params.max_initial_congestion_window > 0) {
+      max_cwnd_when_network_parameters_adjusted_ =
+          params.max_initial_congestion_window * kDefaultTCPMSS;
+    }
+    cwnd_ = cwnd_limits().ApplyLimits(
+        std::min(max_cwnd_when_network_parameters_adjusted_,
+                 model_.BDP(effective_bandwidth)));
+
+    if (!params.allow_cwnd_to_decrease) {
+      cwnd_ = std::max(cwnd_, prior_cwnd);
+    }
+
+    pacing_rate_ = std::max(pacing_rate_, QuicBandwidth::FromBytesAndTimeDelta(
+                                              cwnd_, model_.MinRtt()));
+  }
+}
+
+void Bbr2Sender::SetInitialCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  if (mode_ == Bbr2Mode::STARTUP) {
+    // The cwnd limits is unchanged and still applies to the new cwnd.
+    cwnd_ = cwnd_limits().ApplyLimits(congestion_window * kDefaultTCPMSS);
+  }
+}
+
+void Bbr2Sender::OnCongestionEvent(bool /*rtt_updated*/,
+                                   QuicByteCount prior_in_flight,
+                                   QuicTime event_time,
+                                   const AckedPacketVector& acked_packets,
+                                   const LostPacketVector& lost_packets) {
+  QUIC_DVLOG(3) << this
+                << " OnCongestionEvent. prior_in_flight:" << prior_in_flight
+                << " prior_cwnd:" << cwnd_ << "  @ " << event_time;
+  Bbr2CongestionEvent congestion_event;
+  congestion_event.prior_cwnd = cwnd_;
+  congestion_event.prior_bytes_in_flight = prior_in_flight;
+  congestion_event.is_probing_for_bandwidth =
+      BBR2_MODE_DISPATCH(IsProbingForBandwidth());
+
+  model_.OnCongestionEventStart(event_time, acked_packets, lost_packets,
+                                &congestion_event);
+
+  if (InSlowStart()) {
+    if (!lost_packets.empty()) {
+      connection_stats_->slowstart_packets_lost += lost_packets.size();
+      connection_stats_->slowstart_bytes_lost += congestion_event.bytes_lost;
+    }
+    if (congestion_event.end_of_round_trip) {
+      ++connection_stats_->slowstart_num_rtts;
+    }
+  }
+
+  // Number of mode changes allowed for this congestion event.
+  int mode_changes_allowed = kMaxModeChangesPerCongestionEvent;
+  while (true) {
+    Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
+        OnCongestionEvent(prior_in_flight, event_time, acked_packets,
+                          lost_packets, congestion_event));
+
+    if (next_mode == mode_) {
+      break;
+    }
+
+    QUIC_DVLOG(2) << this << " Mode change:  " << mode_ << " ==> " << next_mode
+                  << "  @ " << event_time;
+    BBR2_MODE_DISPATCH(Leave(event_time, &congestion_event));
+    mode_ = next_mode;
+    BBR2_MODE_DISPATCH(Enter(event_time, &congestion_event));
+    --mode_changes_allowed;
+    if (mode_changes_allowed < 0) {
+      QUIC_BUG(quic_bug_10443_1)
+          << "Exceeded max number of mode changes per congestion event.";
+      break;
+    }
+  }
+
+  UpdatePacingRate(congestion_event.bytes_acked);
+  QUIC_BUG_IF(quic_bug_10443_2, pacing_rate_.IsZero())
+      << "Pacing rate must not be zero!";
+
+  UpdateCongestionWindow(congestion_event.bytes_acked);
+  QUIC_BUG_IF(quic_bug_10443_3, cwnd_ == 0u)
+      << "Congestion window must not be zero!";
+
+  model_.OnCongestionEventFinish(unacked_packets_->GetLeastUnacked(),
+                                 congestion_event);
+  last_sample_is_app_limited_ =
+      congestion_event.last_packet_send_state.is_app_limited;
+  if (!last_sample_is_app_limited_) {
+    has_non_app_limited_sample_ = true;
+  }
+  if (congestion_event.bytes_in_flight == 0 &&
+      params().avoid_unnecessary_probe_rtt) {
+    OnEnterQuiescence(event_time);
+  }
+
+  QUIC_DVLOG(3)
+      << this
+      << " END CongestionEvent(acked:" << quiche::PrintElements(acked_packets)
+      << ", lost:" << lost_packets.size() << ") "
+      << ", Mode:" << mode_ << ", RttCount:" << model_.RoundTripCount()
+      << ", BytesInFlight:" << congestion_event.bytes_in_flight
+      << ", PacingRate:" << PacingRate(0) << ", CWND:" << GetCongestionWindow()
+      << ", PacingGain:" << model_.pacing_gain()
+      << ", CwndGain:" << model_.cwnd_gain()
+      << ", BandwidthEstimate(kbps):" << BandwidthEstimate().ToKBitsPerSecond()
+      << ", MinRTT(us):" << model_.MinRtt().ToMicroseconds()
+      << ", BDP:" << model_.BDP(BandwidthEstimate())
+      << ", BandwidthLatest(kbps):"
+      << model_.bandwidth_latest().ToKBitsPerSecond()
+      << ", BandwidthLow(kbps):" << model_.bandwidth_lo().ToKBitsPerSecond()
+      << ", BandwidthHigh(kbps):" << model_.MaxBandwidth().ToKBitsPerSecond()
+      << ", InflightLatest:" << model_.inflight_latest()
+      << ", InflightLow:" << model_.inflight_lo()
+      << ", InflightHigh:" << model_.inflight_hi()
+      << ", TotalAcked:" << model_.total_bytes_acked()
+      << ", TotalLost:" << model_.total_bytes_lost()
+      << ", TotalSent:" << model_.total_bytes_sent() << "  @ " << event_time;
+}
+
+void Bbr2Sender::UpdatePacingRate(QuicByteCount bytes_acked) {
+  if (BandwidthEstimate().IsZero()) {
+    return;
+  }
+
+  if (model_.total_bytes_acked() == bytes_acked) {
+    // After the first ACK, cwnd_ is still the initial congestion window.
+    pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(cwnd_, model_.MinRtt());
+    return;
+  }
+
+  QuicBandwidth target_rate = model_.pacing_gain() * model_.BandwidthEstimate();
+  if (model_.full_bandwidth_reached()) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+  if (params_.decrease_startup_pacing_at_end_of_round &&
+      model_.pacing_gain() < Params().startup_pacing_gain) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+  if (params_.bw_lo_mode_ != Bbr2Params::DEFAULT &&
+      model_.loss_events_in_round() > 0) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+
+  // By default, the pacing rate never decreases in STARTUP.
+  if (target_rate > pacing_rate_) {
+    pacing_rate_ = target_rate;
+  }
+}
+
+void Bbr2Sender::UpdateCongestionWindow(QuicByteCount bytes_acked) {
+  QuicByteCount target_cwnd = GetTargetCongestionWindow(model_.cwnd_gain());
+
+  const QuicByteCount prior_cwnd = cwnd_;
+  if (model_.full_bandwidth_reached() || Params().startup_include_extra_acked) {
+    target_cwnd += model_.MaxAckHeight();
+    cwnd_ = std::min(prior_cwnd + bytes_acked, target_cwnd);
+  } else if (prior_cwnd < target_cwnd || prior_cwnd < 2 * initial_cwnd_) {
+    cwnd_ = prior_cwnd + bytes_acked;
+  }
+  const QuicByteCount desired_cwnd = cwnd_;
+
+  cwnd_ = GetCwndLimitsByMode().ApplyLimits(cwnd_);
+  const QuicByteCount model_limited_cwnd = cwnd_;
+
+  cwnd_ = cwnd_limits().ApplyLimits(cwnd_);
+
+  QUIC_DVLOG(3) << this << " Updating CWND. target_cwnd:" << target_cwnd
+                << ", max_ack_height:" << model_.MaxAckHeight()
+                << ", full_bw:" << model_.full_bandwidth_reached()
+                << ", bytes_acked:" << bytes_acked
+                << ", inflight_lo:" << model_.inflight_lo()
+                << ", inflight_hi:" << model_.inflight_hi() << ". (prior_cwnd) "
+                << prior_cwnd << " => (desired_cwnd) " << desired_cwnd
+                << " => (model_limited_cwnd) " << model_limited_cwnd
+                << " => (final_cwnd) " << cwnd_;
+}
+
+QuicByteCount Bbr2Sender::GetTargetCongestionWindow(float gain) const {
+  return std::max(model_.BDP(model_.BandwidthEstimate(), gain),
+                  cwnd_limits().Min());
+}
+
+void Bbr2Sender::OnPacketSent(QuicTime sent_time,
+                              QuicByteCount bytes_in_flight,
+                              QuicPacketNumber packet_number,
+                              QuicByteCount bytes,
+                              HasRetransmittableData is_retransmittable) {
+  QUIC_DVLOG(3) << this << " OnPacketSent: pkn:" << packet_number
+                << ", bytes:" << bytes << ", cwnd:" << cwnd_
+                << ", inflight:" << bytes_in_flight + bytes
+                << ", total_sent:" << model_.total_bytes_sent() + bytes
+                << ", total_acked:" << model_.total_bytes_acked()
+                << ", total_lost:" << model_.total_bytes_lost() << "  @ "
+                << sent_time;
+  if (InSlowStart()) {
+    ++connection_stats_->slowstart_packets_sent;
+    connection_stats_->slowstart_bytes_sent += bytes;
+  }
+  if (bytes_in_flight == 0 && params().avoid_unnecessary_probe_rtt) {
+    OnExitQuiescence(sent_time);
+  }
+  model_.OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
+                      is_retransmittable);
+}
+
+void Bbr2Sender::OnPacketNeutered(QuicPacketNumber packet_number) {
+  model_.OnPacketNeutered(packet_number);
+}
+
+bool Bbr2Sender::CanSend(QuicByteCount bytes_in_flight) {
+  const bool result = bytes_in_flight < GetCongestionWindow();
+  return result;
+}
+
+QuicByteCount Bbr2Sender::GetCongestionWindow() const {
+  // TODO(wub): Implement Recovery?
+  return cwnd_;
+}
+
+QuicBandwidth Bbr2Sender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
+  return pacing_rate_;
+}
+
+void Bbr2Sender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
+  if (bytes_in_flight >= GetCongestionWindow()) {
+    return;
+  }
+
+  model_.OnApplicationLimited();
+  QUIC_DVLOG(2) << this << " Becoming application limited. Last sent packet: "
+                << model_.last_sent_packet()
+                << ", CWND: " << GetCongestionWindow();
+}
+
+QuicByteCount Bbr2Sender::GetTargetBytesInflight() const {
+  QuicByteCount bdp = model_.BDP(model_.BandwidthEstimate());
+  return std::min(bdp, GetCongestionWindow());
+}
+
+void Bbr2Sender::PopulateConnectionStats(QuicConnectionStats* stats) const {
+  stats->num_ack_aggregation_epochs = model_.num_ack_aggregation_epochs();
+}
+
+void Bbr2Sender::OnEnterQuiescence(QuicTime now) {
+  last_quiescence_start_ = now;
+}
+
+void Bbr2Sender::OnExitQuiescence(QuicTime now) {
+  if (last_quiescence_start_ != QuicTime::Zero()) {
+    Bbr2Mode next_mode = BBR2_MODE_DISPATCH(
+        OnExitQuiescence(now, std::min(now, last_quiescence_start_)));
+    if (next_mode != mode_) {
+      BBR2_MODE_DISPATCH(Leave(now, nullptr));
+      mode_ = next_mode;
+      BBR2_MODE_DISPATCH(Enter(now, nullptr));
+    }
+    last_quiescence_start_ = QuicTime::Zero();
+  }
+}
+
+bool Bbr2Sender::ShouldSendProbingPacket() const {
+  // TODO(wub): Implement ShouldSendProbingPacket properly.
+  return BBR2_MODE_DISPATCH(IsProbingForBandwidth());
+}
+
+std::string Bbr2Sender::GetDebugState() const {
+  std::ostringstream stream;
+  stream << ExportDebugState();
+  return stream.str();
+}
+
+Bbr2Sender::DebugState Bbr2Sender::ExportDebugState() const {
+  DebugState s;
+  s.mode = mode_;
+  s.round_trip_count = model_.RoundTripCount();
+  s.bandwidth_hi = model_.MaxBandwidth();
+  s.bandwidth_lo = model_.bandwidth_lo();
+  s.bandwidth_est = BandwidthEstimate();
+  s.inflight_hi = model_.inflight_hi();
+  s.inflight_lo = model_.inflight_lo();
+  s.max_ack_height = model_.MaxAckHeight();
+  s.min_rtt = model_.MinRtt();
+  s.min_rtt_timestamp = model_.MinRttTimestamp();
+  s.congestion_window = cwnd_;
+  s.pacing_rate = pacing_rate_;
+  s.last_sample_is_app_limited = last_sample_is_app_limited_;
+  s.end_of_app_limited_phase = model_.end_of_app_limited_phase();
+
+  s.startup = startup_.ExportDebugState();
+  s.drain = drain_.ExportDebugState();
+  s.probe_bw = probe_bw_.ExportDebugState();
+  s.probe_rtt = probe_rtt_.ExportDebugState();
+
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os, const Bbr2Sender::DebugState& s) {
+  os << "mode: " << s.mode << "\n";
+  os << "round_trip_count: " << s.round_trip_count << "\n";
+  os << "bandwidth_hi ~ lo ~ est: " << s.bandwidth_hi << " ~ " << s.bandwidth_lo
+     << " ~ " << s.bandwidth_est << "\n";
+  os << "min_rtt: " << s.min_rtt << "\n";
+  os << "min_rtt_timestamp: " << s.min_rtt_timestamp << "\n";
+  os << "congestion_window: " << s.congestion_window << "\n";
+  os << "pacing_rate: " << s.pacing_rate << "\n";
+  os << "last_sample_is_app_limited: " << s.last_sample_is_app_limited << "\n";
+
+  if (s.mode == Bbr2Mode::STARTUP) {
+    os << s.startup;
+  }
+
+  if (s.mode == Bbr2Mode::DRAIN) {
+    os << s.drain;
+  }
+
+  if (s.mode == Bbr2Mode::PROBE_BW) {
+    os << s.probe_bw;
+  }
+
+  if (s.mode == Bbr2Mode::PROBE_RTT) {
+    os << s.probe_rtt;
+  }
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.h b/quiche/quic/core/congestion_control/bbr2_sender.h
new file mode 100644
index 0000000..7529171
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_sender.h
@@ -0,0 +1,222 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/bbr2_drain.h"
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_probe_bw.h"
+#include "quiche/quic/core/congestion_control/bbr2_probe_rtt.h"
+#include "quiche/quic/core/congestion_control/bbr2_startup.h"
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface {
+ public:
+  Bbr2Sender(QuicTime now,
+             const RttStats* rtt_stats,
+             const QuicUnackedPacketMap* unacked_packets,
+             QuicPacketCount initial_cwnd_in_packets,
+             QuicPacketCount max_cwnd_in_packets,
+             QuicRandom* random,
+             QuicConnectionStats* stats,
+             BbrSender* old_sender);
+
+  ~Bbr2Sender() override = default;
+
+  // Start implementation of SendAlgorithmInterface.
+  bool InSlowStart() const override { return mode_ == Bbr2Mode::STARTUP; }
+
+  bool InRecovery() const override {
+    // TODO(wub): Implement Recovery.
+    return false;
+  }
+
+  bool ShouldSendProbingPacket() const override;
+
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+
+  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
+
+  void AdjustNetworkParameters(const NetworkParams& params) override;
+
+  void SetInitialCongestionWindowInPackets(
+      QuicPacketCount congestion_window) override;
+
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets) override;
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable) override;
+
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+
+  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
+
+  void OnConnectionMigration() override {}
+
+  bool CanSend(QuicByteCount bytes_in_flight) override;
+
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+
+  QuicBandwidth BandwidthEstimate() const override {
+    return model_.BandwidthEstimate();
+  }
+
+  bool HasGoodBandwidthEstimateForResumption() const override {
+    return has_non_app_limited_sample_;
+  }
+
+  QuicByteCount GetCongestionWindow() const override;
+
+  QuicByteCount GetSlowStartThreshold() const override { return 0; }
+
+  CongestionControlType GetCongestionControlType() const override {
+    return kBBRv2;
+  }
+
+  std::string GetDebugState() const override;
+
+  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+
+  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
+  // End implementation of SendAlgorithmInterface.
+
+  const Bbr2Params& Params() const { return params_; }
+
+  QuicByteCount GetMinimumCongestionWindow() const {
+    return cwnd_limits().Min();
+  }
+
+  // Returns the min of BDP and congestion window.
+  QuicByteCount GetTargetBytesInflight() const;
+
+  bool IsBandwidthOverestimateAvoidanceEnabled() const {
+    return model_.IsBandwidthOverestimateAvoidanceEnabled();
+  }
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    Bbr2Mode mode;
+
+    // Shared states.
+    QuicRoundTripCount round_trip_count;
+    QuicBandwidth bandwidth_hi = QuicBandwidth::Zero();
+    QuicBandwidth bandwidth_lo = QuicBandwidth::Zero();
+    QuicBandwidth bandwidth_est = QuicBandwidth::Zero();
+    QuicByteCount inflight_hi;
+    QuicByteCount inflight_lo;
+    QuicByteCount max_ack_height;
+    QuicTime::Delta min_rtt = QuicTime::Delta::Zero();
+    QuicTime min_rtt_timestamp = QuicTime::Zero();
+    QuicByteCount congestion_window;
+    QuicBandwidth pacing_rate = QuicBandwidth::Zero();
+    bool last_sample_is_app_limited;
+    QuicPacketNumber end_of_app_limited_phase;
+
+    // Mode-specific debug states.
+    Bbr2StartupMode::DebugState startup;
+    Bbr2DrainMode::DebugState drain;
+    Bbr2ProbeBwMode::DebugState probe_bw;
+    Bbr2ProbeRttMode::DebugState probe_rtt;
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  void UpdatePacingRate(QuicByteCount bytes_acked);
+  void UpdateCongestionWindow(QuicByteCount bytes_acked);
+  QuicByteCount GetTargetCongestionWindow(float gain) const;
+  void OnEnterQuiescence(QuicTime now);
+  void OnExitQuiescence(QuicTime now);
+
+  // Helper function for BBR2_MODE_DISPATCH.
+  Bbr2ProbeRttMode& probe_rtt_or_die() {
+    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
+    return probe_rtt_;
+  }
+
+  const Bbr2ProbeRttMode& probe_rtt_or_die() const {
+    QUICHE_DCHECK_EQ(mode_, Bbr2Mode::PROBE_RTT);
+    return probe_rtt_;
+  }
+
+  uint64_t RandomUint64(uint64_t max) const {
+    return random_->RandUint64() % max;
+  }
+
+  // Cwnd limits imposed by the current Bbr2 mode.
+  Limits<QuicByteCount> GetCwndLimitsByMode() const;
+
+  // Cwnd limits imposed by caller.
+  const Limits<QuicByteCount>& cwnd_limits() const;
+
+  const Bbr2Params& params() const { return params_; }
+
+  Bbr2Mode mode_;
+
+  const RttStats* const rtt_stats_;
+  const QuicUnackedPacketMap* const unacked_packets_;
+  QuicRandom* random_;
+  QuicConnectionStats* connection_stats_;
+
+  // Don't use it directly outside of SetFromConfig and ApplyConnectionOptions.
+  // Instead, use params() to get read-only access.
+  Bbr2Params params_;
+
+  // Max congestion window when adjusting network parameters.
+  QuicByteCount max_cwnd_when_network_parameters_adjusted_ =
+      kMaxInitialCongestionWindow * kDefaultTCPMSS;
+
+  Bbr2NetworkModel model_;
+
+  const QuicByteCount initial_cwnd_;
+
+  // Current cwnd and pacing rate.
+  QuicByteCount cwnd_;
+  QuicBandwidth pacing_rate_;
+
+  QuicTime last_quiescence_start_ = QuicTime::Zero();
+
+  Bbr2StartupMode startup_;
+  Bbr2DrainMode drain_;
+  Bbr2ProbeBwMode probe_bw_;
+  Bbr2ProbeRttMode probe_rtt_;
+
+  bool has_non_app_limited_sample_ = false;
+
+  // Debug only.
+  bool last_sample_is_app_limited_;
+
+  friend class Bbr2StartupMode;
+  friend class Bbr2DrainMode;
+  friend class Bbr2ProbeBwMode;
+  friend class Bbr2ProbeRttMode;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2Sender::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/bbr2_simulator_test.cc b/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
new file mode 100644
index 0000000..6eec232
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -0,0 +1,2298 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <sstream>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+#include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/send_algorithm_test_result.pb.h"
+#include "quiche/quic/test_tools/send_algorithm_test_utils.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+#include "quiche/quic/test_tools/simulator/traffic_policer.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+using testing::AllOf;
+using testing::Ge;
+using testing::Le;
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_bbr2_test_regression_mode, "",
+    "One of a) 'record' to record test result (one file per test), or "
+    "b) 'regress' to regress against recorded results, or "
+    "c) <anything else> for non-regression mode.");
+
+namespace quic {
+
+using CyclePhase = Bbr2ProbeBwMode::CyclePhase;
+
+namespace test {
+
+// Use the initial CWND of 10, as 32 is too much for the test network.
+const uint32_t kDefaultInitialCwndPackets = 10;
+const uint32_t kDefaultInitialCwndBytes =
+    kDefaultInitialCwndPackets * kDefaultTCPMSS;
+
+struct LinkParams {
+  LinkParams(int64_t kilo_bits_per_sec, int64_t delay_us)
+      : bandwidth(QuicBandwidth::FromKBitsPerSecond(kilo_bits_per_sec)),
+        delay(QuicTime::Delta::FromMicroseconds(delay_us)) {}
+  QuicBandwidth bandwidth;
+  QuicTime::Delta delay;
+};
+
+struct TrafficPolicerParams {
+  std::string name = "policer";
+  QuicByteCount initial_burst_size;
+  QuicByteCount max_bucket_size;
+  QuicBandwidth target_bandwidth = QuicBandwidth::Zero();
+};
+
+// All Bbr2DefaultTopologyTests uses the default network topology:
+//
+//            Sender
+//               |
+//               |  <-- local_link
+//               |
+//        Network switch
+//               *  <-- the bottleneck queue in the direction
+//               |          of the receiver
+//               |
+//               |  <-- test_link
+//               |
+//               |
+//           Receiver
+class DefaultTopologyParams {
+ public:
+  LinkParams local_link = {10000, 2000};
+  LinkParams test_link = {4000, 30000};
+
+  const simulator::SwitchPortNumber switch_port_count = 2;
+  // Network switch queue capacity, in number of BDPs.
+  float switch_queue_capacity_in_bdp = 2;
+
+  absl::optional<TrafficPolicerParams> sender_policer_params;
+
+  QuicBandwidth BottleneckBandwidth() const {
+    return std::min(local_link.bandwidth, test_link.bandwidth);
+  }
+
+  // Round trip time of a single full size packet.
+  QuicTime::Delta RTT() const {
+    return 2 * (local_link.delay + test_link.delay +
+                local_link.bandwidth.TransferTime(kMaxOutgoingPacketSize) +
+                test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
+  }
+
+  QuicByteCount BDP() const { return BottleneckBandwidth() * RTT(); }
+
+  QuicByteCount SwitchQueueCapacity() const {
+    return switch_queue_capacity_in_bdp * BDP();
+  }
+
+  std::string ToString() const {
+    std::ostringstream os;
+    os << "{ BottleneckBandwidth: " << BottleneckBandwidth()
+       << " RTT: " << RTT() << " BDP: " << BDP()
+       << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
+    return os.str();
+  }
+};
+
+class Bbr2SimulatorTest : public QuicTest {
+ protected:
+  Bbr2SimulatorTest() : simulator_(&random_) {
+    // Prevent the server(receiver), which only sends acks, from closing
+    // connection due to too many outstanding packets.
+    SetQuicFlag(FLAGS_quic_max_tracked_packet_count, 1000000);
+  }
+
+  void SetUp() override {
+    if (GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode) == "regress") {
+      SendAlgorithmTestResult expected;
+      ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
+      random_seed_ = expected.random_seed();
+    } else {
+      random_seed_ = QuicRandom::GetInstance()->RandUint64();
+    }
+    random_.set_seed(random_seed_);
+    QUIC_LOG(INFO) << "Using random seed: " << random_seed_;
+  }
+
+  ~Bbr2SimulatorTest() override {
+    const std::string regression_mode =
+        GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode);
+    const QuicTime::Delta simulated_duration =
+        SimulatedNow() - QuicTime::Zero();
+    if (regression_mode == "record") {
+      RecordSendAlgorithmTestResult(random_seed_,
+                                    simulated_duration.ToMicroseconds());
+    } else if (regression_mode == "regress") {
+      CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
+    }
+  }
+
+  QuicTime SimulatedNow() const { return simulator_.GetClock()->Now(); }
+
+  uint64_t random_seed_;
+  SimpleRandom random_;
+  simulator::Simulator simulator_;
+};
+
+class Bbr2DefaultTopologyTest : public Bbr2SimulatorTest {
+ protected:
+  Bbr2DefaultTopologyTest()
+      : sender_endpoint_(&simulator_,
+                         "Sender",
+                         "Receiver",
+                         Perspective::IS_CLIENT,
+                         TestConnectionId(42)),
+        receiver_endpoint_(&simulator_,
+                           "Receiver",
+                           "Sender",
+                           Perspective::IS_SERVER,
+                           TestConnectionId(42)) {
+    sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
+  }
+
+  ~Bbr2DefaultTopologyTest() {
+    const auto* test_info =
+        ::testing::UnitTest::GetInstance()->current_test_info();
+    const Bbr2Sender::DebugState& debug_state = sender_->ExportDebugState();
+    QUIC_LOG(INFO) << "Bbr2DefaultTopologyTest." << test_info->name()
+                   << " completed at simulated time: "
+                   << SimulatedNow().ToDebuggingValue() / 1e6
+                   << " sec. packet loss:"
+                   << sender_loss_rate_in_packets() * 100
+                   << "%, bw_hi:" << debug_state.bandwidth_hi;
+  }
+
+  QuicUnackedPacketMap* GetUnackedMap(QuicConnection* connection) {
+    return QuicSentPacketManagerPeer::GetUnackedPacketMap(
+        QuicConnectionPeer::GetSentPacketManager(connection));
+  }
+
+  Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint,
+                              BbrSender* old_sender) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    Bbr2Sender* sender = new Bbr2Sender(
+        endpoint->connection()->clock()->Now(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(),
+        GetUnackedMap(endpoint->connection()), kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()), old_sender);
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    const int kTestMaxPacketSize = 1350;
+    endpoint->connection()->SetMaxPacketLength(kTestMaxPacketSize);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  void CreateNetwork(const DefaultTopologyParams& params) {
+    QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
+                                                  params.switch_port_count,
+                                                  params.SwitchQueueCapacity());
+
+    // WARNING: The order to add links to network_links_ matters, because some
+    // tests adjusts the link bandwidth on the fly.
+
+    // Local link connects sender and port 1.
+    network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+        &sender_endpoint_, switch_->port(1), params.local_link.bandwidth,
+        params.local_link.delay));
+
+    // Test link connects receiver and port 2.
+    if (params.sender_policer_params.has_value()) {
+      const TrafficPolicerParams& policer_params =
+          params.sender_policer_params.value();
+      sender_policer_ = std::make_unique<simulator::TrafficPolicer>(
+          &simulator_, policer_params.name, policer_params.initial_burst_size,
+          policer_params.max_bucket_size, policer_params.target_bandwidth,
+          switch_->port(2));
+      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+          &receiver_endpoint_, sender_policer_.get(),
+          params.test_link.bandwidth, params.test_link.delay));
+    } else {
+      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+          &receiver_endpoint_, switch_->port(2), params.test_link.bandwidth,
+          params.test_link.delay));
+    }
+  }
+
+  simulator::SymmetricLink* TestLink() { return network_links_[1].get(); }
+
+  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta timeout) {
+    sender_endpoint_.AddBytesToTransfer(transfer_size);
+    // TODO(wub): consider rewriting this to run until the receiver actually
+    // receives the intended amount of bytes.
+    bool simulator_result = simulator_.RunUntilOrTimeout(
+        [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+        timeout);
+    EXPECT_TRUE(simulator_result)
+        << "Simple transfer failed.  Bytes remaining: "
+        << sender_endpoint_.bytes_to_transfer();
+    QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
+  }
+
+  // Drive the simulator by sending enough data to enter PROBE_BW.
+  void DriveOutOfStartup(const DefaultTopologyParams& params) {
+    ASSERT_FALSE(sender_->ExportDebugState().startup.full_bandwidth_reached);
+    DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
+    EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                     sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  }
+
+  // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
+  // |wait_time| between each burst.
+  void SendBursts(const DefaultTopologyParams& params,
+                  size_t number_of_bursts,
+                  QuicByteCount bytes,
+                  QuicTime::Delta wait_time) {
+    ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
+    for (size_t i = 0; i < number_of_bursts; i++) {
+      sender_endpoint_.AddBytesToTransfer(bytes);
+
+      // Transfer data and wait for three seconds between each transfer.
+      simulator_.RunFor(wait_time);
+
+      // Ensure the connection did not time out.
+      ASSERT_TRUE(sender_endpoint_.connection()->connected());
+      ASSERT_TRUE(receiver_endpoint_.connection()->connected());
+    }
+
+    simulator_.RunFor(wait_time + params.RTT());
+    ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
+  }
+
+  template <class TerminationPredicate>
+  bool SendUntilOrTimeout(TerminationPredicate termination_predicate,
+                          QuicTime::Delta timeout) {
+    EXPECT_EQ(0u, sender_endpoint_.bytes_to_transfer());
+    const QuicTime deadline = SimulatedNow() + timeout;
+    do {
+      sender_endpoint_.AddBytesToTransfer(4 * kDefaultTCPMSS);
+      if (simulator_.RunUntilOrTimeout(
+              [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+              deadline - SimulatedNow()) &&
+          termination_predicate()) {
+        return true;
+      }
+    } while (SimulatedNow() < deadline);
+    return false;
+  }
+
+  void EnableAggregation(QuicByteCount aggregation_bytes,
+                         QuicTime::Delta aggregation_timeout) {
+    switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
+                                              aggregation_timeout);
+  }
+
+  void SetConnectionOption(QuicTag option) {
+    SetConnectionOption(std::move(option), sender_);
+  }
+
+  void SetConnectionOption(QuicTag option, Bbr2Sender* sender) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(option);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    sender->SetFromConfig(config, Perspective::IS_SERVER);
+  }
+
+  bool Bbr2ModeIsOneOf(const std::vector<Bbr2Mode>& expected_modes) const {
+    const Bbr2Mode mode = sender_->ExportDebugState().mode;
+    for (Bbr2Mode expected_mode : expected_modes) {
+      if (mode == expected_mode) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  const RttStats* rtt_stats() {
+    return sender_endpoint_.connection()->sent_packet_manager().GetRttStats();
+  }
+
+  QuicConnection* sender_connection() { return sender_endpoint_.connection(); }
+
+  Bbr2Sender::DebugState sender_debug_state() const {
+    return sender_->ExportDebugState();
+  }
+
+  const QuicConnectionStats& sender_connection_stats() {
+    return sender_connection()->GetStats();
+  }
+
+  QuicUnackedPacketMap* sender_unacked_map() {
+    return GetUnackedMap(sender_connection());
+  }
+
+  float sender_loss_rate_in_packets() {
+    return static_cast<float>(sender_connection_stats().packets_lost) /
+           sender_connection_stats().packets_sent;
+  }
+
+  simulator::QuicEndpoint sender_endpoint_;
+  simulator::QuicEndpoint receiver_endpoint_;
+  Bbr2Sender* sender_;
+
+  std::unique_ptr<simulator::Switch> switch_;
+  std::unique_ptr<simulator::TrafficPolicer> sender_policer_;
+  std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
+};
+
+TEST_F(Bbr2DefaultTopologyTest, NormalStartup) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      3u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207) {
+  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
+  SetConnectionOption(kB207);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      1u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+}
+
+// Add extra_acked to CWND in STARTUP and exit STARTUP on a persistent queue.
+TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207andB205) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
+  SetConnectionOption(kB205);
+  SetConnectionOption(kB207);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      2u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+}
+
+// Test a simple long data transfer in the default setup.
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
+
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultInitialCwndBytes, rtt_stats()->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 1.0f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB2RC) {
+  SetConnectionOption(kB2RC);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB201) {
+  SetConnectionOption(kB201);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB206) {
+  SetQuicReloadableFlag(quic_bbr2_startup_probe_up_loss_events, true);
+  SetConnectionOption(kB206);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB207) {
+  SetQuicReloadableFlag(quic_bbr2_exit_startup_on_persistent_queue2, true);
+  SetConnectionOption(kB207);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBRB) {
+  SetConnectionOption(kBBRB);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR4) {
+  SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
+  SetConnectionOption(kBBR4);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR5) {
+  SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
+  SetConnectionOption(kBBR5);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) {
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  EXPECT_GE(sender_connection_stats().packets_lost, 0u);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBufferB2H2) {
+  SetConnectionOption(kB2H2);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  EXPECT_GE(sender_connection_stats().packets_lost, 0u);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
+  SetConnectionOption(kBSAO);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
+    EXPECT_EQ(sender_loss_rate_in_packets(), 0);
+  } else {
+    EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  }
+  // The margin here is high, because both link level aggregation and ack
+  // decimation can greatly increase smoothed rtt.
+  EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytesB201) {
+  SetConnectionOption(kB201);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  // TODO(wub): Tighten the error bound once BSAO is default enabled.
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.5f);
+
+  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
+    EXPECT_LE(sender_loss_rate_in_packets(), 0.01);
+  } else {
+    EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+  }
+  // The margin here is high, because both link level aggregation and ack
+  // decimation can greatly increase smoothed rtt.
+  EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
+  SetConnectionOption(kBSAO);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.001);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(params.RTT() * 3, rtt_stats()->smoothed_rtt());
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.1f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth decrease during a transfer.
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthDecrease)) {
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
+
+  // We can transfer ~12MB in the first 10 seconds. The rest ~8MB needs about
+  // 640 seconds.
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth decreasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_EQ(0u, sender_connection_stats().packets_lost);
+
+  // Now decrease the bottleneck bandwidth from 10Mbps to 100Kbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(800));
+  EXPECT_TRUE(simulator_result);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer.
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncrease)) {
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBBQ0)) {
+  SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
+                        true);
+  SetConnectionOption(kBBQ0);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseBBQ0Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_add_bytes_acked_after_inflight_hi_limited,
+                        true);
+  SetConnectionOption(kBBQ0);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  // TODO(ianswett) Make these bound tighter once overestimation is reduced.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.6f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.90f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB202)) {
+  SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
+  SetConnectionOption(kB202);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.1f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB202Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_no_probe_up_exit_if_no_queue, true);
+  SetConnectionOption(kB202);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.6f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.92f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB203)) {
+  SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
+  SetConnectionOption(kB203);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB203Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_ignore_inflight_hi_in_probe_up, true);
+  SetConnectionOption(kB203);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.60f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.91f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB204)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB204);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.25);
+  EXPECT_LE(sender_->ExportDebugState().max_ack_height, 2000u);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.02f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB204Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB204);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present, and B204 actually
+  // is increasing overestimation, which is surprising.
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.60f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
+  EXPECT_LE(sender_->ExportDebugState().max_ack_height, 10000u);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 10% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.95f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
+TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB205)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB205);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.1f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.10);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure the full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.1f);
+}
+
+// Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
+// in the presence of ACK aggregation.
+TEST_F(Bbr2DefaultTopologyTest,
+       QUIC_SLOW_TEST(BandwidthIncreaseB205Aggregation)) {
+  SetQuicReloadableFlag(quic_bbr2_startup_extra_acked, true);
+  SetConnectionOption(kB205);
+  DefaultTopologyParams params;
+  params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
+  CreateNetwork(params);
+
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * params.RTT());
+
+  // Reduce the payload to 2MB because 10MB takes too long.
+  sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
+
+  // This is much farther off when aggregation is present,
+  // Ideally BSAO or another option would fix this.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_est, 0.45f);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.15);
+
+  // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
+  params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
+  TestLink()->set_bandwidth(params.test_link.bandwidth);
+
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
+      QuicTime::Delta::FromSeconds(50));
+  EXPECT_TRUE(simulator_result);
+  // Ensure at least 5% of full bandwidth is discovered.
+  EXPECT_APPROX_EQ(params.test_link.bandwidth,
+                   sender_->ExportDebugState().bandwidth_hi, 0.9f);
+}
+
+// Test the number of losses incurred by the startup phase in a situation when
+// the buffer is less than BDP.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossOnSmallBufferStartup) {
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  // Packet loss is smaller with a CWND gain of 2 than 2.889.
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
+}
+
+// Test the number of losses decreases with packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ6SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ6);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.0575);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Test the number of losses decreases with min_rtt packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ7SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ7);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.06);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Test the number of losses decreases with Inflight packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ8SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ8);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Test the number of losses decreases with CWND packet-conservation pacing.
+TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ9SmallBufferStartup) {
+  SetConnectionOption(kBBQ2);  // Increase CWND gain.
+  SetConnectionOption(kBBQ9);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
+  // bandwidth_lo is cleared exiting STARTUP.
+  EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
+            QuicBandwidth::Infinite());
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data after sending continuously for a while.
+TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBursts) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
+  DriveOutOfStartup(params);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+
+  SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data and then starts sending continuously.
+TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBurstsWithoutPrior) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  SendBursts(params, 40, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  DriveOutOfStartup(params);
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                   sender_->ExportDebugState().bandwidth_hi, 0.01f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Verify that the DRAIN phase works correctly.
+TEST_F(Bbr2DefaultTopologyTest, Drain) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  sender_endpoint_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(Bbr2Mode::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != Bbr2Mode::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
+                   sender_->PacingRate(0), 0.01f);
+
+  // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer with
+  // approximately 1 BDP.  Here, we use 0.95 to give some margin for error.
+  EXPECT_GE(queue->bytes_queued(), 0.95 * params.BDP());
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      params.test_link.bandwidth.TransferTime(queue->bytes_queued());
+  EXPECT_APPROX_EQ(params.RTT() + queueing_delay, rtt_stats()->latest_rtt(),
+                   0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != Bbr2Mode::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), params.BDP());
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        const auto& debug_state = sender_->ExportDebugState();
+        QuicRoundTripCount rounds_passed =
+            debug_state.round_trip_count - start_round_trip;
+        return rounds_passed >= 4 && debug_state.mode == Bbr2Mode::PROBE_BW &&
+               debug_state.probe_bw.phase == CyclePhase::PROBE_REFILL;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 0.1f);
+}
+
+// Ensure that a connection that is app-limited and is at sufficiently low
+// bandwidth will not exit high gain phase, and similarly ensure that the
+// connection will exit low gain early if the number of bytes in flight is low.
+TEST_F(Bbr2DefaultTopologyTest, InFlightAwareGainCycling) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+  DriveOutOfStartup(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result;
+
+  // Start a few cycles prior to the high gain one.
+  simulator_result = SendUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().probe_bw.phase ==
+               CyclePhase::PROBE_REFILL;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Send at 10% of available rate.  Run for 3 seconds, checking in the middle
+  // and at the end.  The pacing gain should be high throughout.
+  QuicBandwidth target_bandwidth = 0.1f * params.BottleneckBandwidth();
+  QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
+  for (int i = 0; i < 2; i++) {
+    SendBursts(params, 5, target_bandwidth * burst_interval, burst_interval);
+    EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
+    EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+                     sender_->ExportDebugState().bandwidth_hi, 0.02f);
+  }
+
+  // Now that in-flight is almost zero and the pacing gain is still above 1,
+  // send approximately 1.4 BDPs worth of data. This should cause the PROBE_BW
+  // mode to enter low gain cycle(PROBE_DOWN), and exit it earlier than one
+  // min_rtt due to running out of data to send.
+  sender_endpoint_.AddBytesToTransfer(1.4 * params.BDP());
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().probe_bw.phase ==
+               CyclePhase::PROBE_DOWN;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
+  EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(CyclePhase::PROBE_CRUISE,
+            sender_->ExportDebugState().probe_bw.phase);
+}
+
+// Test exiting STARTUP earlier upon loss due to loss.
+TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLoss) {
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      1u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_NE(0u, sender_connection_stats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  EXPECT_GT(sender_->ExportDebugState().inflight_hi, 1.2f * params.BDP());
+}
+
+// Test exiting STARTUP earlier upon loss due to loss when connection option
+// B2SL is used.
+TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2SL) {
+  SetConnectionOption(kB2SL);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(
+      1u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_NE(0u, sender_connection_stats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  EXPECT_APPROX_EQ(sender_->ExportDebugState().inflight_hi, params.BDP(), 0.1f);
+}
+
+// Verifies that in STARTUP, if we exceed loss threshold in a round, we exit
+// STARTUP at the end of the round even if there's enough bandwidth growth.
+TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2NE) {
+  // Set up flags such that any loss will be considered "too high".
+  SetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count, 0);
+  SetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold, 0.0);
+
+  sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
+
+  SetConnectionOption(kB2NE);
+  DefaultTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.5;
+  CreateNetwork(params);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
+          max_bw = sender_->ExportDebugState().bandwidth_hi;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().startup.full_bandwidth_reached;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(sender_->ExportDebugState().round_trip_count, max_bw_round);
+  EXPECT_EQ(
+      0u,
+      sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
+  EXPECT_NE(0u, sender_connection_stats().packets_lost);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SenderPoliced) {
+  DefaultTopologyParams params;
+  params.sender_policer_params = TrafficPolicerParams();
+  params.sender_policer_params->initial_burst_size = 1000 * 10;
+  params.sender_policer_params->max_bucket_size = 1000 * 100;
+  params.sender_policer_params->target_bandwidth =
+      params.BottleneckBandwidth() * 0.25;
+
+  CreateNetwork(params);
+
+  ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
+
+  DoSimpleTransfer(3 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
+  // TODO(wub): Fix (long-term) bandwidth overestimation in policer mode, then
+  // reduce the loss rate upper bound.
+  EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
+}
+
+// TODO(wub): Add other slowstart stats to BBRv2.
+TEST_F(Bbr2DefaultTopologyTest, StartupStats) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  ASSERT_FALSE(sender_->InSlowStart());
+
+  const QuicConnectionStats& stats = sender_connection_stats();
+  // The test explicitly replaces the default-created send algorithm with the
+  // one created by the test. slowstart_count increaments every time a BBR
+  // sender is created.
+  EXPECT_GE(stats.slowstart_count, 1u);
+  EXPECT_FALSE(stats.slowstart_duration.IsRunning());
+  EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
+              AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
+                    Le(QuicTime::Delta::FromMilliseconds(1500))));
+  EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
+            QuicConnectionPeer::GetSentPacketManager(sender_connection())
+                ->GetSlowStartDuration());
+}
+
+TEST_F(Bbr2DefaultTopologyTest, ProbeUpAdaptInflightHiGradually) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+
+  AckedPacketVector acked_packets;
+  QuicPacketNumber acked_packet_number =
+      sender_unacked_map()->GetLeastUnacked();
+  for (auto& info : *sender_unacked_map()) {
+    acked_packets.emplace_back(acked_packet_number++, info.bytes_sent,
+                               SimulatedNow());
+  }
+
+  // Advance time significantly so the OnCongestionEvent enters PROBE_REFILL.
+  QuicTime now = SimulatedNow() + QuicTime::Delta::FromSeconds(5);
+  auto next_packet_number = sender_unacked_map()->largest_sent_packet() + 1;
+  sender_->OnCongestionEvent(
+      /*rtt_updated=*/true, sender_unacked_map()->bytes_in_flight(), now,
+      acked_packets, {});
+  ASSERT_EQ(CyclePhase::PROBE_REFILL,
+            sender_->ExportDebugState().probe_bw.phase);
+
+  // Send and Ack one packet to exit app limited and enter PROBE_UP.
+  sender_->OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
+                        kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
+  now = now + params.RTT();
+  sender_->OnCongestionEvent(
+      /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
+      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {});
+  ASSERT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
+
+  // Send 2 packets and lose the first one(50% loss) to exit PROBE_UP.
+  for (uint64_t i = 0; i < 2; ++i) {
+    sender_->OnPacketSent(now, /*bytes_in_flight=*/i * kDefaultMaxPacketSize,
+                          next_packet_number++, kDefaultMaxPacketSize,
+                          HAS_RETRANSMITTABLE_DATA);
+  }
+  now = now + params.RTT();
+  sender_->OnCongestionEvent(
+      /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
+      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)},
+      {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)});
+
+  QuicByteCount inflight_hi = sender_->ExportDebugState().inflight_hi;
+  EXPECT_LT(2 * kDefaultMaxPacketSize, inflight_hi);
+}
+
+// Ensures bandwidth estimate does not change after a loss only event.
+TEST_F(Bbr2DefaultTopologyTest, LossOnlyCongestionEvent) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // Send some bursts, each burst increments round count by 1, since it only
+  // generates small, app-limited samples, the max_bandwidth_filter_ will not be
+  // updated.
+  SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
+
+  // Run until we have something in flight.
+  sender_endpoint_.AddBytesToTransfer(50 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [&]() { return sender_unacked_map()->bytes_in_flight() > 0; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+
+  const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
+  EXPECT_APPROX_EQ(params.BottleneckBandwidth(), prior_bandwidth_estimate,
+                   0.01f);
+
+  // Lose the least unacked packet.
+  LostPacketVector lost_packets;
+  lost_packets.emplace_back(
+      sender_connection()->sent_packet_manager().GetLeastUnacked(),
+      kDefaultMaxPacketSize);
+
+  QuicTime now = simulator_.GetClock()->Now() + params.RTT() * 0.25;
+  sender_->OnCongestionEvent(false, sender_unacked_map()->bytes_in_flight(),
+                             now, {}, lost_packets);
+
+  // Bandwidth estimate should not change for the loss only event.
+  EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
+}
+
+// After quiescence, if the sender is in PROBE_RTT, it should transition to
+// PROBE_BW immediately on the first sent packet after quiescence.
+TEST_F(Bbr2DefaultTopologyTest, ProbeRttAfterQuiescenceImmediatelyExits) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(15);
+  bool simulator_result;
+
+  // Keep sending until reach PROBE_RTT.
+  simulator_result = SendUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Wait for entering a quiescence of 5 seconds.
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_unacked_map()->bytes_in_flight() == 0 &&
+               sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
+      },
+      timeout));
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(5));
+
+  // Send one packet to exit quiescence.
+  EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_RTT);
+  sender_->OnPacketSent(SimulatedNow(), /*bytes_in_flight=*/0,
+                        sender_unacked_map()->largest_sent_packet() + 1,
+                        kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
+
+  EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_BW);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, ProbeBwAfterQuiescencePostponeMinRttTimestamp) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  DriveOutOfStartup(params);
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result;
+
+  // Keep sending until reach PROBE_REFILL.
+  simulator_result = SendUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().probe_bw.phase ==
+               CyclePhase::PROBE_REFILL;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  const QuicTime min_rtt_timestamp_before_idle =
+      sender_->ExportDebugState().min_rtt_timestamp;
+
+  // Wait for entering a quiescence of 15 seconds.
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() { return sender_unacked_map()->bytes_in_flight() == 0; },
+      params.RTT() + timeout));
+
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
+
+  // Send some data to exit quiescence.
+  SendBursts(params, 1, kDefaultTCPMSS, QuicTime::Delta::Zero());
+  const QuicTime min_rtt_timestamp_after_idle =
+      sender_->ExportDebugState().min_rtt_timestamp;
+
+  EXPECT_LT(min_rtt_timestamp_before_idle + QuicTime::Delta::FromSeconds(14),
+            min_rtt_timestamp_after_idle);
+}
+
+TEST_F(Bbr2DefaultTopologyTest, SwitchToBbr2MidConnection) {
+  QuicTime now = QuicTime::Zero();
+  BbrSender old_sender(sender_connection()->clock()->Now(),
+                       sender_connection()->sent_packet_manager().GetRttStats(),
+                       GetUnackedMap(sender_connection()),
+                       kDefaultInitialCwndPackets + 1,
+                       GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+                       QuicConnectionPeer::GetStats(sender_connection()));
+
+  QuicPacketNumber next_packet_number(1);
+
+  // Send packets 1-4.
+  while (next_packet_number < QuicPacketNumber(5)) {
+    now = now + QuicTime::Delta::FromMilliseconds(10);
+
+    old_sender.OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
+                            /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  // Switch from |old_sender| to |sender_|.
+  const QuicByteCount old_sender_cwnd = old_sender.GetCongestionWindow();
+  sender_ = SetupBbr2Sender(&sender_endpoint_, &old_sender);
+  EXPECT_EQ(old_sender_cwnd, sender_->GetCongestionWindow());
+
+  // Send packets 5-7.
+  now = now + QuicTime::Delta::FromMilliseconds(10);
+  sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
+                        /*bytes=*/23, NO_RETRANSMITTABLE_DATA);
+
+  now = now + QuicTime::Delta::FromMilliseconds(10);
+  sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
+                        /*bytes=*/767, HAS_RETRANSMITTABLE_DATA);
+
+  QuicByteCount bytes_in_flight = 767;
+  while (next_packet_number < QuicPacketNumber(30)) {
+    now = now + QuicTime::Delta::FromMilliseconds(10);
+    bytes_in_flight += 1350;
+    sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
+                          /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  // Ack 1 & 2.
+  AckedPacketVector acked = {
+      AckedPacket(QuicPacketNumber(1), /*bytes_acked=*/0, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(2), /*bytes_acked=*/0, QuicTime::Zero()),
+  };
+  now = now + QuicTime::Delta::FromMilliseconds(2000);
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+
+  // Send 30-41.
+  while (next_packet_number < QuicPacketNumber(42)) {
+    now = now + QuicTime::Delta::FromMilliseconds(10);
+    bytes_in_flight += 1350;
+    sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
+                          /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  // Ack 3.
+  acked = {
+      AckedPacket(QuicPacketNumber(3), /*bytes_acked=*/0, QuicTime::Zero()),
+  };
+  now = now + QuicTime::Delta::FromMilliseconds(2000);
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+
+  // Send 42.
+  now = now + QuicTime::Delta::FromMilliseconds(10);
+  bytes_in_flight += 1350;
+  sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
+                        /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
+
+  // Ack 4-7.
+  acked = {
+      AckedPacket(QuicPacketNumber(4), /*bytes_acked=*/0, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(5), /*bytes_acked=*/0, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(6), /*bytes_acked=*/767, QuicTime::Zero()),
+      AckedPacket(QuicPacketNumber(7), /*bytes_acked=*/1350, QuicTime::Zero()),
+  };
+  now = now + QuicTime::Delta::FromMilliseconds(2000);
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+  EXPECT_FALSE(sender_->BandwidthEstimate().IsZero());
+}
+
+TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  QUIC_LOG(INFO) << "Initial cwnd: " << sender_debug_state().congestion_window
+                 << "\nInitial pacing rate: " << sender_->PacingRate(0)
+                 << "\nInitial bandwidth estimate: "
+                 << sender_->BandwidthEstimate()
+                 << "\nInitial rtt: " << sender_debug_state().min_rtt;
+
+  sender_connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(params.BottleneckBandwidth(),
+                                            params.RTT(),
+                                            /*allow_cwnd_to_decrease=*/false));
+
+  EXPECT_EQ(params.BDP(), sender_->ExportDebugState().congestion_window);
+
+  EXPECT_EQ(params.BottleneckBandwidth(),
+            sender_->PacingRate(/*bytes_in_flight=*/0));
+  EXPECT_NE(params.BottleneckBandwidth(), sender_->BandwidthEstimate());
+
+  EXPECT_APPROX_EQ(params.RTT(), sender_->ExportDebugState().min_rtt, 0.01f);
+
+  DriveOutOfStartup(params);
+}
+
+TEST_F(Bbr2DefaultTopologyTest,
+       200InitialCongestionWindowWithNetworkParameterAdjusted) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
+
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  sender_connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
+                                            QuicTime::Delta::Zero(), false));
+
+  // Verify cwnd is capped at 200.
+  EXPECT_EQ(200 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
+}
+
+TEST_F(Bbr2DefaultTopologyTest,
+       100InitialCongestionWindowFromNetworkParameter) {
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  SendAlgorithmInterface::NetworkParams network_params(
+      1024 * params.BottleneckBandwidth(), QuicTime::Delta::Zero(), false);
+  network_params.max_initial_congestion_window = 100;
+  sender_connection()->AdjustNetworkParameters(network_params);
+
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
+}
+
+TEST_F(Bbr2DefaultTopologyTest,
+       100InitialCongestionWindowWithNetworkParameterAdjusted) {
+  SetConnectionOption(kICW1);
+  DefaultTopologyParams params;
+  CreateNetwork(params);
+
+  sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  sender_connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
+                                            QuicTime::Delta::Zero(), false));
+
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
+}
+
+// All Bbr2MultiSenderTests uses the following network topology:
+//
+//   Sender 0  (A Bbr2Sender)
+//       |
+//       | <-- local_links[0]
+//       |
+//       |  Sender N (1 <= N < kNumLocalLinks) (May or may not be a Bbr2Sender)
+//       |      |
+//       |      | <-- local_links[N]
+//       |      |
+//    Network switch
+//           *  <-- the bottleneck queue in the direction
+//           |          of the receiver
+//           |
+//           |  <-- test_link
+//           |
+//           |
+//       Receiver
+class MultiSenderTopologyParams {
+ public:
+  static constexpr size_t kNumLocalLinks = 8;
+  std::array<LinkParams, kNumLocalLinks> local_links = {
+      LinkParams(10000, 1987), LinkParams(10000, 1993), LinkParams(10000, 1997),
+      LinkParams(10000, 1999), LinkParams(10000, 2003), LinkParams(10000, 2011),
+      LinkParams(10000, 2017), LinkParams(10000, 2027),
+  };
+
+  LinkParams test_link = LinkParams(4000, 30000);
+
+  const simulator::SwitchPortNumber switch_port_count = kNumLocalLinks + 1;
+
+  // Network switch queue capacity, in number of BDPs.
+  float switch_queue_capacity_in_bdp = 2;
+
+  QuicBandwidth BottleneckBandwidth() const {
+    // Make sure all local links have a higher bandwidth than the test link.
+    for (size_t i = 0; i < local_links.size(); ++i) {
+      QUICHE_CHECK_GT(local_links[i].bandwidth, test_link.bandwidth);
+    }
+    return test_link.bandwidth;
+  }
+
+  // Sender n's round trip time of a single full size packet.
+  QuicTime::Delta Rtt(size_t n) const {
+    return 2 * (local_links[n].delay + test_link.delay +
+                local_links[n].bandwidth.TransferTime(kMaxOutgoingPacketSize) +
+                test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
+  }
+
+  QuicByteCount Bdp(size_t n) const { return BottleneckBandwidth() * Rtt(n); }
+
+  QuicByteCount SwitchQueueCapacity() const {
+    return switch_queue_capacity_in_bdp * Bdp(1);
+  }
+
+  std::string ToString() const {
+    std::ostringstream os;
+    os << "{ BottleneckBandwidth: " << BottleneckBandwidth();
+    for (size_t i = 0; i < local_links.size(); ++i) {
+      os << " RTT_" << i << ": " << Rtt(i) << " BDP_" << i << ": " << Bdp(i);
+    }
+    os << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
+    return os.str();
+  }
+};
+
+class Bbr2MultiSenderTest : public Bbr2SimulatorTest {
+ protected:
+  Bbr2MultiSenderTest() {
+    uint64_t first_connection_id = 42;
+    std::vector<simulator::QuicEndpointBase*> receiver_endpoint_pointers;
+    for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
+      std::string sender_name = absl::StrCat("Sender", i + 1);
+      std::string receiver_name = absl::StrCat("Receiver", i + 1);
+      sender_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
+          &simulator_, sender_name, receiver_name, Perspective::IS_CLIENT,
+          TestConnectionId(first_connection_id + i)));
+      receiver_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
+          &simulator_, receiver_name, sender_name, Perspective::IS_SERVER,
+          TestConnectionId(first_connection_id + i)));
+      receiver_endpoint_pointers.push_back(receiver_endpoints_.back().get());
+    }
+    receiver_multiplexer_ =
+        std::make_unique<simulator::QuicEndpointMultiplexer>(
+            "Receiver multiplexer", receiver_endpoint_pointers);
+    sender_0_ = SetupBbr2Sender(sender_endpoints_[0].get());
+  }
+
+  ~Bbr2MultiSenderTest() {
+    const auto* test_info =
+        ::testing::UnitTest::GetInstance()->current_test_info();
+    QUIC_LOG(INFO) << "Bbr2MultiSenderTest." << test_info->name()
+                   << " completed at simulated time: "
+                   << SimulatedNow().ToDebuggingValue() / 1e6
+                   << " sec. Per sender stats:";
+    for (size_t i = 0; i < sender_endpoints_.size(); ++i) {
+      QUIC_LOG(INFO) << "sender[" << i << "]: "
+                     << sender_connection(i)
+                            ->sent_packet_manager()
+                            .GetSendAlgorithm()
+                            ->GetCongestionControlType()
+                     << ", packet_loss:"
+                     << 100.0 * sender_loss_rate_in_packets(i) << "%";
+    }
+  }
+
+  Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    Bbr2Sender* sender = new Bbr2Sender(
+        endpoint->connection()->clock()->Now(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(),
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
+        kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()), nullptr);
+    // TODO(ianswett): Add dedicated tests for this option until it becomes
+    // the default behavior.
+    SetConnectionOption(sender, kBBRA);
+
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    BbrSender* sender = new BbrSender(
+        endpoint->connection()->clock()->Now(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(),
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
+        kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()));
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  // reno => Reno. !reno => Cubic.
+  TcpCubicSenderBytes* SetupTcpSender(simulator::QuicEndpoint* endpoint,
+                                      bool reno) {
+    // Ownership of the sender will be overtaken by the endpoint.
+    TcpCubicSenderBytes* sender = new TcpCubicSenderBytes(
+        endpoint->connection()->clock(),
+        endpoint->connection()->sent_packet_manager().GetRttStats(), reno,
+        kDefaultInitialCwndPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window),
+        QuicConnectionPeer::GetStats(endpoint->connection()));
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  void SetConnectionOption(SendAlgorithmInterface* sender, QuicTag option) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(option);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    sender->SetFromConfig(config, Perspective::IS_SERVER);
+  }
+
+  void CreateNetwork(const MultiSenderTopologyParams& params) {
+    QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
+                                                  params.switch_port_count,
+                                                  params.SwitchQueueCapacity());
+
+    network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+        receiver_multiplexer_.get(), switch_->port(1),
+        params.test_link.bandwidth, params.test_link.delay));
+    for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
+      simulator::SwitchPortNumber port_number = i + 2;
+      network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
+          sender_endpoints_[i].get(), switch_->port(port_number),
+          params.local_links[i].bandwidth, params.local_links[i].delay));
+    }
+  }
+
+  QuicConnection* sender_connection(size_t which) {
+    return sender_endpoints_[which]->connection();
+  }
+
+  const QuicConnectionStats& sender_connection_stats(size_t which) {
+    return sender_connection(which)->GetStats();
+  }
+
+  float sender_loss_rate_in_packets(size_t which) {
+    return static_cast<float>(sender_connection_stats(which).packets_lost) /
+           sender_connection_stats(which).packets_sent;
+  }
+
+  std::vector<std::unique_ptr<simulator::QuicEndpoint>> sender_endpoints_;
+  std::vector<std::unique_ptr<simulator::QuicEndpoint>> receiver_endpoints_;
+  std::unique_ptr<simulator::QuicEndpointMultiplexer> receiver_multiplexer_;
+  Bbr2Sender* sender_0_;
+
+  std::unique_ptr<simulator::Switch> switch_;
+  std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
+};
+
+TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2) {
+  SetupBbr2Sender(sender_endpoints_[1].get());
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(MultipleBbr2s)) {
+  const int kTotalNumSenders = 6;
+  for (int i = 1; i < kTotalNumSenders; ++i) {
+    SetupBbr2Sender(sender_endpoints_[i].get());
+  }
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time
+                 << ". Now: " << SimulatedNow();
+
+  // Start all transfers.
+  for (int i = 0; i < kTotalNumSenders; ++i) {
+    if (i != 0) {
+      const QuicTime sender_start_time =
+          SimulatedNow() + QuicTime::Delta::FromSeconds(2);
+      bool simulator_result = simulator_.RunUntilOrTimeout(
+          [&]() { return SimulatedNow() >= sender_start_time; }, transfer_time);
+      ASSERT_TRUE(simulator_result);
+    }
+
+    sender_endpoints_[i]->AddBytesToTransfer(transfer_size);
+  }
+
+  // Wait for all transfers to finish.
+  QuicTime::Delta expected_total_transfer_time_upper_bound =
+      QuicTime::Delta::FromMicroseconds(kTotalNumSenders *
+                                        transfer_time.ToMicroseconds() * 1.1);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        for (int i = 0; i < kTotalNumSenders; ++i) {
+          if (receiver_endpoints_[i]->bytes_received() < transfer_size) {
+            return false;
+          }
+        }
+        return true;
+      },
+      expected_total_transfer_time_upper_bound);
+  ASSERT_TRUE(simulator_result)
+      << "Expected upper bound: " << expected_total_transfer_time_upper_bound;
+}
+
+/* The first 11 packets are sent at the same time, but the duration between the
+ * acks of the 1st and the 11th packet is 49 milliseconds, causing very low bw
+ * samples. This happens for both large and small buffers.
+ */
+/*
+TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2LargeRttTinyBuffer) {
+  SetupBbr2Sender(sender_endpoints_[1].get());
+
+  MultiSenderTopologyParams params;
+  params.switch_queue_capacity_in_bdp = 0.05;
+  params.test_link.delay = QuicTime::Delta::FromSeconds(1);
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+*/
+
+TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr1) {
+  SetupBbrSender(sender_endpoints_[1].get());
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsReno)) {
+  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsRenoB2RC)) {
+  SetConnectionOption(sender_0_, kB2RC);
+  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsCubic)) {
+  SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/false);
+
+  MultiSenderTopologyParams params;
+  CreateNetwork(params);
+
+  const QuicByteCount transfer_size = 50 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      params.BottleneckBandwidth().TransferTime(transfer_size);
+  QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
+
+  // Transfer 10% of data in first transfer.
+  sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
+      },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_endpoints_[0]->bytes_received() == transfer_size &&
+               receiver_endpoints_[1]->bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_startup.cc b/quiche/quic/core/congestion_control/bbr2_startup.cc
new file mode 100644
index 0000000..7091353
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_startup.cc
@@ -0,0 +1,157 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr2_startup.h"
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+Bbr2StartupMode::Bbr2StartupMode(const Bbr2Sender* sender,
+                                 Bbr2NetworkModel* model,
+                                 QuicTime now)
+    : Bbr2ModeBase(sender, model) {
+  // Increment, instead of reset startup stats, so we don't lose data recorded
+  // before QuicConnection switched send algorithm to BBRv2.
+  ++sender_->connection_stats_->slowstart_count;
+  if (!sender_->connection_stats_->slowstart_duration.IsRunning()) {
+    sender_->connection_stats_->slowstart_duration.Start(now);
+  }
+  // Enter() is never called for Startup, so the gains needs to be set here.
+  model_->set_pacing_gain(Params().startup_pacing_gain);
+  model_->set_cwnd_gain(Params().startup_cwnd_gain);
+}
+
+void Bbr2StartupMode::Enter(QuicTime /*now*/,
+                            const Bbr2CongestionEvent* /*congestion_event*/) {
+  QUIC_BUG(quic_bug_10463_1) << "Bbr2StartupMode::Enter should not be called";
+}
+
+void Bbr2StartupMode::Leave(QuicTime now,
+                            const Bbr2CongestionEvent* /*congestion_event*/) {
+  sender_->connection_stats_->slowstart_duration.Stop(now);
+  // Clear bandwidth_lo if it's set during STARTUP.
+  model_->clear_bandwidth_lo();
+}
+
+Bbr2Mode Bbr2StartupMode::OnCongestionEvent(
+    QuicByteCount /*prior_in_flight*/,
+    QuicTime /*event_time*/,
+    const AckedPacketVector& /*acked_packets*/,
+    const LostPacketVector& /*lost_packets*/,
+    const Bbr2CongestionEvent& congestion_event) {
+  if (model_->full_bandwidth_reached()) {
+    QUIC_BUG() << "In STARTUP, but full_bandwidth_reached is true.";
+    return Bbr2Mode::DRAIN;
+  }
+  if (!congestion_event.end_of_round_trip) {
+    return Bbr2Mode::STARTUP;
+  }
+  bool has_bandwidth_growth = model_->HasBandwidthGrowth(congestion_event);
+  if (Params().exit_startup_on_persistent_queue && !has_bandwidth_growth) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_exit_startup_on_persistent_queue2);
+    model_->CheckPersistentQueue(congestion_event, Params().startup_cwnd_gain);
+  }
+  // TCP BBR always exits upon excessive losses. QUIC BBRv1 does not exit
+  // upon excessive losses, if enough bandwidth growth is observed or if the
+  // sample was app limited.
+  if (Params().always_exit_startup_on_excess_loss ||
+      (!congestion_event.last_packet_send_state.is_app_limited &&
+       !has_bandwidth_growth)) {
+    CheckExcessiveLosses(congestion_event);
+  }
+
+  if (Params().decrease_startup_pacing_at_end_of_round) {
+    QUICHE_DCHECK_GT(model_->pacing_gain(), 0);
+    if (!congestion_event.last_packet_send_state.is_app_limited) {
+      // Multiply by startup_pacing_gain, so if the bandwidth doubles,
+      // the pacing gain will be the full startup_pacing_gain.
+      if (max_bw_at_round_beginning_ > QuicBandwidth::Zero()) {
+        const float bandwidth_ratio =
+            std::max(1., model_->MaxBandwidth().ToBitsPerSecond() /
+                             static_cast<double>(
+                                 max_bw_at_round_beginning_.ToBitsPerSecond()));
+        // Even when bandwidth isn't increasing, use a gain large enough to
+        // cause a startup_full_bw_threshold increase.
+        const float new_gain =
+            ((bandwidth_ratio - 1) * (Params().startup_pacing_gain -
+                                      Params().startup_full_bw_threshold)) +
+            Params().startup_full_bw_threshold;
+        // Allow the pacing gain to decrease.
+        model_->set_pacing_gain(
+            std::min(Params().startup_pacing_gain, new_gain));
+        // Clear bandwidth_lo if it's less than the pacing rate.
+        // This avoids a constantly app-limited flow from having it's pacing
+        // gain effectively decreased below 1.25.
+        if (model_->bandwidth_lo() <
+            model_->MaxBandwidth() * model_->pacing_gain()) {
+          model_->clear_bandwidth_lo();
+        }
+      }
+      max_bw_at_round_beginning_ = model_->MaxBandwidth();
+    }
+  }
+
+  // TODO(wub): Maybe implement STARTUP => PROBE_RTT.
+  return model_->full_bandwidth_reached() ? Bbr2Mode::DRAIN : Bbr2Mode::STARTUP;
+}
+
+void Bbr2StartupMode::CheckExcessiveLosses(
+    const Bbr2CongestionEvent& congestion_event) {
+  QUICHE_DCHECK(congestion_event.end_of_round_trip);
+
+  if (model_->full_bandwidth_reached()) {
+    return;
+  }
+
+  // At the end of a round trip. Check if loss is too high in this round.
+  if (model_->IsInflightTooHigh(congestion_event,
+                                Params().startup_full_loss_count)) {
+    QuicByteCount new_inflight_hi = model_->BDP();
+    if (Params().startup_loss_exit_use_max_delivered_for_inflight_hi) {
+      if (new_inflight_hi < model_->max_bytes_delivered_in_round()) {
+        new_inflight_hi = model_->max_bytes_delivered_in_round();
+      }
+    }
+    QUIC_DVLOG(3) << sender_ << " Exiting STARTUP due to loss at round "
+                  << model_->RoundTripCount()
+                  << ". inflight_hi:" << new_inflight_hi;
+    // TODO(ianswett): Add a shared method to set inflight_hi in the model.
+    model_->set_inflight_hi(new_inflight_hi);
+    model_->set_full_bandwidth_reached();
+    sender_->connection_stats_->bbr_exit_startup_due_to_loss = true;
+  }
+}
+
+Bbr2StartupMode::DebugState Bbr2StartupMode::ExportDebugState() const {
+  DebugState s;
+  s.full_bandwidth_reached = model_->full_bandwidth_reached();
+  s.full_bandwidth_baseline = model_->full_bandwidth_baseline();
+  s.round_trips_without_bandwidth_growth =
+      model_->rounds_without_bandwidth_growth();
+  return s;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const Bbr2StartupMode::DebugState& state) {
+  os << "[STARTUP] full_bandwidth_reached: " << state.full_bandwidth_reached
+     << "\n";
+  os << "[STARTUP] full_bandwidth_baseline: " << state.full_bandwidth_baseline
+     << "\n";
+  os << "[STARTUP] round_trips_without_bandwidth_growth: "
+     << state.round_trips_without_bandwidth_growth << "\n";
+  return os;
+}
+
+const Bbr2Params& Bbr2StartupMode::Params() const {
+  return sender_->Params();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr2_startup.h b/quiche/quic/core/congestion_control/bbr2_startup.h
new file mode 100644
index 0000000..a041178
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr2_startup.h
@@ -0,0 +1,71 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
+
+#include "quiche/quic/core/congestion_control/bbr2_misc.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class Bbr2Sender;
+class QUIC_EXPORT_PRIVATE Bbr2StartupMode final : public Bbr2ModeBase {
+ public:
+  Bbr2StartupMode(const Bbr2Sender* sender,
+                  Bbr2NetworkModel* model,
+                  QuicTime now);
+
+  void Enter(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+  void Leave(QuicTime now,
+             const Bbr2CongestionEvent* congestion_event) override;
+
+  Bbr2Mode OnCongestionEvent(
+      QuicByteCount prior_in_flight,
+      QuicTime event_time,
+      const AckedPacketVector& acked_packets,
+      const LostPacketVector& lost_packets,
+      const Bbr2CongestionEvent& congestion_event) override;
+
+  Limits<QuicByteCount> GetCwndLimits() const override {
+    // Inflight_lo is never set in STARTUP.
+    QUICHE_DCHECK_EQ(Bbr2NetworkModel::inflight_lo_default(),
+                     model_->inflight_lo());
+    return NoGreaterThan(model_->inflight_lo());
+  }
+
+  bool IsProbingForBandwidth() const override { return true; }
+
+  Bbr2Mode OnExitQuiescence(QuicTime /*now*/,
+                            QuicTime /*quiescence_start_time*/) override {
+    return Bbr2Mode::STARTUP;
+  }
+
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    bool full_bandwidth_reached;
+    QuicBandwidth full_bandwidth_baseline = QuicBandwidth::Zero();
+    QuicRoundTripCount round_trips_without_bandwidth_growth;
+  };
+
+  DebugState ExportDebugState() const;
+
+ private:
+  const Bbr2Params& Params() const;
+
+  void CheckExcessiveLosses(const Bbr2CongestionEvent& congestion_event);
+  // Used when the pacing gain can decrease in STARTUP.
+  QuicBandwidth max_bw_at_round_beginning_ = QuicBandwidth::Zero();
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const Bbr2StartupMode::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_STARTUP_H_
diff --git a/quiche/quic/core/congestion_control/bbr_sender.cc b/quiche/quic/core/congestion_control/bbr_sender.cc
new file mode 100644
index 0000000..022f225
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr_sender.cc
@@ -0,0 +1,914 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+// Constants based on TCP defaults.
+// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
+// Does not inflate the pacing rate.
+const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
+
+// The gain used for the STARTUP, equal to 2/ln(2).
+const float kDefaultHighGain = 2.885f;
+// The newly derived gain for STARTUP, equal to 4 * ln(2)
+const float kDerivedHighGain = 2.773f;
+// The newly derived CWND gain for STARTUP, 2.
+const float kDerivedHighCWNDGain = 2.0f;
+// The cycle of gains used during the PROBE_BW stage.
+const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
+
+// The length of the gain cycle.
+const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]);
+// The size of the bandwidth filter window, in round-trips.
+const QuicRoundTripCount kBandwidthWindowSize = kGainCycleLength + 2;
+
+// The time after which the current min_rtt value expires.
+const QuicTime::Delta kMinRttExpiry = QuicTime::Delta::FromSeconds(10);
+// The minimum time the connection can spend in PROBE_RTT mode.
+const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200);
+// If the bandwidth does not increase by the factor of |kStartupGrowthTarget|
+// within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection
+// will exit the STARTUP mode.
+const float kStartupGrowthTarget = 1.25;
+const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3;
+}  // namespace
+
+BbrSender::DebugState::DebugState(const BbrSender& sender)
+    : mode(sender.mode_),
+      max_bandwidth(sender.max_bandwidth_.GetBest()),
+      round_trip_count(sender.round_trip_count_),
+      gain_cycle_index(sender.cycle_current_offset_),
+      congestion_window(sender.congestion_window_),
+      is_at_full_bandwidth(sender.is_at_full_bandwidth_),
+      bandwidth_at_last_round(sender.bandwidth_at_last_round_),
+      rounds_without_bandwidth_gain(sender.rounds_without_bandwidth_gain_),
+      min_rtt(sender.min_rtt_),
+      min_rtt_timestamp(sender.min_rtt_timestamp_),
+      recovery_state(sender.recovery_state_),
+      recovery_window(sender.recovery_window_),
+      last_sample_is_app_limited(sender.last_sample_is_app_limited_),
+      end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()) {}
+
+BbrSender::DebugState::DebugState(const DebugState& state) = default;
+
+BbrSender::BbrSender(QuicTime now,
+                     const RttStats* rtt_stats,
+                     const QuicUnackedPacketMap* unacked_packets,
+                     QuicPacketCount initial_tcp_congestion_window,
+                     QuicPacketCount max_tcp_congestion_window,
+                     QuicRandom* random,
+                     QuicConnectionStats* stats)
+    : rtt_stats_(rtt_stats),
+      unacked_packets_(unacked_packets),
+      random_(random),
+      stats_(stats),
+      mode_(STARTUP),
+      sampler_(unacked_packets, kBandwidthWindowSize),
+      round_trip_count_(0),
+      num_loss_events_in_round_(0),
+      bytes_lost_in_round_(0),
+      max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
+      min_rtt_(QuicTime::Delta::Zero()),
+      min_rtt_timestamp_(QuicTime::Zero()),
+      congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
+      initial_congestion_window_(initial_tcp_congestion_window *
+                                 kDefaultTCPMSS),
+      max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
+      min_congestion_window_(kDefaultMinimumCongestionWindow),
+      high_gain_(kDefaultHighGain),
+      high_cwnd_gain_(kDefaultHighGain),
+      drain_gain_(1.f / kDefaultHighGain),
+      pacing_rate_(QuicBandwidth::Zero()),
+      pacing_gain_(1),
+      congestion_window_gain_(1),
+      congestion_window_gain_constant_(
+          static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
+      num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
+      cycle_current_offset_(0),
+      last_cycle_start_(QuicTime::Zero()),
+      is_at_full_bandwidth_(false),
+      rounds_without_bandwidth_gain_(0),
+      bandwidth_at_last_round_(QuicBandwidth::Zero()),
+      exiting_quiescence_(false),
+      exit_probe_rtt_at_(QuicTime::Zero()),
+      probe_rtt_round_passed_(false),
+      last_sample_is_app_limited_(false),
+      has_non_app_limited_sample_(false),
+      recovery_state_(NOT_IN_RECOVERY),
+      recovery_window_(max_congestion_window_),
+      slower_startup_(false),
+      rate_based_startup_(false),
+      enable_ack_aggregation_during_startup_(false),
+      expire_ack_aggregation_in_startup_(false),
+      drain_to_target_(false),
+      detect_overshooting_(false),
+      bytes_lost_while_detecting_overshooting_(0),
+      bytes_lost_multiplier_while_detecting_overshooting_(2),
+      cwnd_to_calculate_min_pacing_rate_(initial_congestion_window_),
+      max_congestion_window_with_network_parameters_adjusted_(
+          kMaxInitialCongestionWindow * kDefaultTCPMSS) {
+  if (stats_) {
+    // Clear some startup stats if |stats_| has been used by another sender,
+    // which happens e.g. when QuicConnection switch send algorithms.
+    stats_->slowstart_count = 0;
+    stats_->slowstart_duration = QuicTimeAccumulator();
+  }
+  EnterStartupMode(now);
+  set_high_cwnd_gain(kDerivedHighCWNDGain);
+}
+
+BbrSender::~BbrSender() {}
+
+void BbrSender::SetInitialCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  if (mode_ == STARTUP) {
+    initial_congestion_window_ = congestion_window * kDefaultTCPMSS;
+    congestion_window_ = congestion_window * kDefaultTCPMSS;
+    cwnd_to_calculate_min_pacing_rate_ = std::min(
+        initial_congestion_window_, cwnd_to_calculate_min_pacing_rate_);
+  }
+}
+
+bool BbrSender::InSlowStart() const {
+  return mode_ == STARTUP;
+}
+
+void BbrSender::OnPacketSent(QuicTime sent_time,
+                             QuicByteCount bytes_in_flight,
+                             QuicPacketNumber packet_number,
+                             QuicByteCount bytes,
+                             HasRetransmittableData is_retransmittable) {
+  if (stats_ && InSlowStart()) {
+    ++stats_->slowstart_packets_sent;
+    stats_->slowstart_bytes_sent += bytes;
+  }
+
+  last_sent_packet_ = packet_number;
+
+  if (bytes_in_flight == 0 && sampler_.is_app_limited()) {
+    exiting_quiescence_ = true;
+  }
+
+  sampler_.OnPacketSent(sent_time, packet_number, bytes, bytes_in_flight,
+                        is_retransmittable);
+}
+
+void BbrSender::OnPacketNeutered(QuicPacketNumber packet_number) {
+  sampler_.OnPacketNeutered(packet_number);
+}
+
+bool BbrSender::CanSend(QuicByteCount bytes_in_flight) {
+  return bytes_in_flight < GetCongestionWindow();
+}
+
+QuicBandwidth BbrSender::PacingRate(QuicByteCount /*bytes_in_flight*/) const {
+  if (pacing_rate_.IsZero()) {
+    return high_gain_ * QuicBandwidth::FromBytesAndTimeDelta(
+                            initial_congestion_window_, GetMinRtt());
+  }
+  return pacing_rate_;
+}
+
+QuicBandwidth BbrSender::BandwidthEstimate() const {
+  return max_bandwidth_.GetBest();
+}
+
+QuicByteCount BbrSender::GetCongestionWindow() const {
+  if (mode_ == PROBE_RTT) {
+    return ProbeRttCongestionWindow();
+  }
+
+  if (InRecovery()) {
+    return std::min(congestion_window_, recovery_window_);
+  }
+
+  return congestion_window_;
+}
+
+QuicByteCount BbrSender::GetSlowStartThreshold() const {
+  return 0;
+}
+
+bool BbrSender::InRecovery() const {
+  return recovery_state_ != NOT_IN_RECOVERY;
+}
+
+bool BbrSender::ShouldSendProbingPacket() const {
+  if (pacing_gain_ <= 1) {
+    return false;
+  }
+
+  // TODO(b/77975811): If the pipe is highly under-utilized, consider not
+  // sending a probing transmission, because the extra bandwidth is not needed.
+  return true;
+}
+
+void BbrSender::SetFromConfig(const QuicConfig& config,
+                              Perspective perspective) {
+  if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
+    num_startup_rtts_ = 1;
+  }
+  if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
+    num_startup_rtts_ = 2;
+  }
+  if (config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
+    drain_to_target_ = true;
+  }
+  if (config.HasClientRequestedIndependentOption(kBWM3, perspective)) {
+    bytes_lost_multiplier_while_detecting_overshooting_ = 3;
+  }
+  if (config.HasClientRequestedIndependentOption(kBWM4, perspective)) {
+    bytes_lost_multiplier_while_detecting_overshooting_ = 4;
+  }
+  if (config.HasClientRequestedIndependentOption(kBBR4, perspective)) {
+    sampler_.SetMaxAckHeightTrackerWindowLength(2 * kBandwidthWindowSize);
+  }
+  if (config.HasClientRequestedIndependentOption(kBBR5, perspective)) {
+    sampler_.SetMaxAckHeightTrackerWindowLength(4 * kBandwidthWindowSize);
+  }
+  if (config.HasClientRequestedIndependentOption(kBBQ1, perspective)) {
+    set_high_gain(kDerivedHighGain);
+    set_high_cwnd_gain(kDerivedHighGain);
+    set_drain_gain(1.f / kDerivedHighGain);
+  }
+  if (config.HasClientRequestedIndependentOption(kBBQ3, perspective)) {
+    enable_ack_aggregation_during_startup_ = true;
+  }
+  if (config.HasClientRequestedIndependentOption(kBBQ5, perspective)) {
+    expire_ack_aggregation_in_startup_ = true;
+  }
+  if (config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
+    min_congestion_window_ = kMaxSegmentSize;
+  }
+  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
+    max_congestion_window_with_network_parameters_adjusted_ =
+        100 * kDefaultTCPMSS;
+  }
+  if (config.HasClientRequestedIndependentOption(kDTOS, perspective)) {
+    detect_overshooting_ = true;
+    // DTOS would allow pacing rate drop to IW 10 / min_rtt if overshooting is
+    // detected.
+    cwnd_to_calculate_min_pacing_rate_ =
+        std::min(initial_congestion_window_, 10 * kDefaultTCPMSS);
+  }
+
+  ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
+}
+
+void BbrSender::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  if (ContainsQuicTag(connection_options, kBSAO)) {
+    sampler_.EnableOverestimateAvoidance();
+  }
+  if (ContainsQuicTag(connection_options, kBBRA)) {
+    sampler_.SetStartNewAggregationEpochAfterFullRound(true);
+  }
+  if (ContainsQuicTag(connection_options, kBBRB)) {
+    sampler_.SetLimitMaxAckHeightTrackerBySendRate(true);
+  }
+}
+
+void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
+  const QuicBandwidth& bandwidth = params.bandwidth;
+  const QuicTime::Delta& rtt = params.rtt;
+
+  if (!rtt.IsZero() && (min_rtt_ > rtt || min_rtt_.IsZero())) {
+    min_rtt_ = rtt;
+  }
+
+  if (mode_ == STARTUP) {
+    if (bandwidth.IsZero()) {
+      // Ignore bad bandwidth samples.
+      return;
+    }
+
+    auto cwnd_bootstrapping_rtt = GetMinRtt();
+    if (params.max_initial_congestion_window > 0) {
+      max_congestion_window_with_network_parameters_adjusted_ =
+          params.max_initial_congestion_window * kDefaultTCPMSS;
+    }
+    const QuicByteCount new_cwnd = std::max(
+        kMinInitialCongestionWindow * kDefaultTCPMSS,
+        std::min(max_congestion_window_with_network_parameters_adjusted_,
+                 bandwidth * cwnd_bootstrapping_rtt));
+
+    stats_->cwnd_bootstrapping_rtt_us = cwnd_bootstrapping_rtt.ToMicroseconds();
+    if (!rtt_stats_->smoothed_rtt().IsZero()) {
+      QUIC_CODE_COUNT(quic_smoothed_rtt_available);
+    } else if (rtt_stats_->initial_rtt() !=
+               QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
+      QUIC_CODE_COUNT(quic_client_initial_rtt_available);
+    } else {
+      QUIC_CODE_COUNT(quic_default_initial_rtt);
+    }
+    if (new_cwnd < congestion_window_ && !params.allow_cwnd_to_decrease) {
+      // Only decrease cwnd if allow_cwnd_to_decrease is true.
+      return;
+    }
+    if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
+      // Decreases cwnd gain and pacing gain. Please note, if pacing_rate_ has
+      // been calculated, it cannot decrease in STARTUP phase.
+      QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_cwnd_and_pacing_gains);
+      set_high_gain(kDerivedHighCWNDGain);
+      set_high_cwnd_gain(kDerivedHighCWNDGain);
+    }
+    congestion_window_ = new_cwnd;
+
+    // Pace at the rate of new_cwnd / RTT.
+    QuicBandwidth new_pacing_rate =
+        QuicBandwidth::FromBytesAndTimeDelta(congestion_window_, GetMinRtt());
+    pacing_rate_ = std::max(pacing_rate_, new_pacing_rate);
+    detect_overshooting_ = true;
+  }
+}
+
+void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
+                                  QuicByteCount prior_in_flight,
+                                  QuicTime event_time,
+                                  const AckedPacketVector& acked_packets,
+                                  const LostPacketVector& lost_packets) {
+  const QuicByteCount total_bytes_acked_before = sampler_.total_bytes_acked();
+  const QuicByteCount total_bytes_lost_before = sampler_.total_bytes_lost();
+
+  bool is_round_start = false;
+  bool min_rtt_expired = false;
+  QuicByteCount excess_acked = 0;
+  QuicByteCount bytes_lost = 0;
+
+  // The send state of the largest packet in acked_packets, unless it is
+  // empty. If acked_packets is empty, it's the send state of the largest
+  // packet in lost_packets.
+  SendTimeState last_packet_send_state;
+
+  if (!acked_packets.empty()) {
+    QuicPacketNumber last_acked_packet = acked_packets.rbegin()->packet_number;
+    is_round_start = UpdateRoundTripCounter(last_acked_packet);
+    UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
+                        is_round_start);
+  }
+
+  BandwidthSamplerInterface::CongestionEventSample sample =
+      sampler_.OnCongestionEvent(event_time, acked_packets, lost_packets,
+                                 max_bandwidth_.GetBest(),
+                                 QuicBandwidth::Infinite(), round_trip_count_);
+  if (sample.last_packet_send_state.is_valid) {
+    last_sample_is_app_limited_ = sample.last_packet_send_state.is_app_limited;
+    has_non_app_limited_sample_ |= !last_sample_is_app_limited_;
+    if (stats_) {
+      stats_->has_non_app_limited_sample = has_non_app_limited_sample_;
+    }
+  }
+  // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all
+  // packets in |acked_packets| did not generate valid samples. (e.g. ack of
+  // ack-only packets). In both cases, sampler_.total_bytes_acked() will not
+  // change.
+  if (total_bytes_acked_before != sampler_.total_bytes_acked()) {
+    QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
+        << sampler_.total_bytes_acked() - total_bytes_acked_before
+        << " bytes from " << acked_packets.size()
+        << " packets have been acked, but sample_max_bandwidth is zero.";
+    if (!sample.sample_is_app_limited ||
+        sample.sample_max_bandwidth > max_bandwidth_.GetBest()) {
+      max_bandwidth_.Update(sample.sample_max_bandwidth, round_trip_count_);
+    }
+  }
+
+  if (!sample.sample_rtt.IsInfinite()) {
+    min_rtt_expired = MaybeUpdateMinRtt(event_time, sample.sample_rtt);
+  }
+  bytes_lost = sampler_.total_bytes_lost() - total_bytes_lost_before;
+  if (mode_ == STARTUP) {
+    if (stats_) {
+      stats_->slowstart_packets_lost += lost_packets.size();
+      stats_->slowstart_bytes_lost += bytes_lost;
+    }
+  }
+  excess_acked = sample.extra_acked;
+  last_packet_send_state = sample.last_packet_send_state;
+
+  if (!lost_packets.empty()) {
+    ++num_loss_events_in_round_;
+    bytes_lost_in_round_ += bytes_lost;
+  }
+
+  // Handle logic specific to PROBE_BW mode.
+  if (mode_ == PROBE_BW) {
+    UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty());
+  }
+
+  // Handle logic specific to STARTUP and DRAIN modes.
+  if (is_round_start && !is_at_full_bandwidth_) {
+    CheckIfFullBandwidthReached(last_packet_send_state);
+  }
+  MaybeExitStartupOrDrain(event_time);
+
+  // Handle logic specific to PROBE_RTT.
+  MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired);
+
+  // Calculate number of packets acked and lost.
+  QuicByteCount bytes_acked =
+      sampler_.total_bytes_acked() - total_bytes_acked_before;
+
+  // After the model is updated, recalculate the pacing rate and congestion
+  // window.
+  CalculatePacingRate(bytes_lost);
+  CalculateCongestionWindow(bytes_acked, excess_acked);
+  CalculateRecoveryWindow(bytes_acked, bytes_lost);
+
+  // Cleanup internal state.
+  sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked());
+  if (is_round_start) {
+    num_loss_events_in_round_ = 0;
+    bytes_lost_in_round_ = 0;
+  }
+}
+
+CongestionControlType BbrSender::GetCongestionControlType() const {
+  return kBBR;
+}
+
+QuicTime::Delta BbrSender::GetMinRtt() const {
+  if (!min_rtt_.IsZero()) {
+    return min_rtt_;
+  }
+  // min_rtt could be available if the handshake packet gets neutered then
+  // gets acknowledged. This could only happen for QUIC crypto where we do not
+  // drop keys.
+  return rtt_stats_->MinOrInitialRtt();
+}
+
+QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
+  QuicByteCount bdp = GetMinRtt() * BandwidthEstimate();
+  QuicByteCount congestion_window = gain * bdp;
+
+  // BDP estimate will be zero if no bandwidth samples are available yet.
+  if (congestion_window == 0) {
+    congestion_window = gain * initial_congestion_window_;
+  }
+
+  return std::max(congestion_window, min_congestion_window_);
+}
+
+QuicByteCount BbrSender::ProbeRttCongestionWindow() const {
+  return min_congestion_window_;
+}
+
+void BbrSender::EnterStartupMode(QuicTime now) {
+  if (stats_) {
+    ++stats_->slowstart_count;
+    stats_->slowstart_duration.Start(now);
+  }
+  mode_ = STARTUP;
+  pacing_gain_ = high_gain_;
+  congestion_window_gain_ = high_cwnd_gain_;
+}
+
+void BbrSender::EnterProbeBandwidthMode(QuicTime now) {
+  mode_ = PROBE_BW;
+  congestion_window_gain_ = congestion_window_gain_constant_;
+
+  // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is
+  // excluded because in that case increased gain and decreased gain would not
+  // follow each other.
+  cycle_current_offset_ = random_->RandUint64() % (kGainCycleLength - 1);
+  if (cycle_current_offset_ >= 1) {
+    cycle_current_offset_ += 1;
+  }
+
+  last_cycle_start_ = now;
+  pacing_gain_ = kPacingGain[cycle_current_offset_];
+}
+
+bool BbrSender::UpdateRoundTripCounter(QuicPacketNumber last_acked_packet) {
+  if (!current_round_trip_end_.IsInitialized() ||
+      last_acked_packet > current_round_trip_end_) {
+    round_trip_count_++;
+    current_round_trip_end_ = last_sent_packet_;
+    if (stats_ && InSlowStart()) {
+      ++stats_->slowstart_num_rtts;
+    }
+    return true;
+  }
+
+  return false;
+}
+
+bool BbrSender::MaybeUpdateMinRtt(QuicTime now,
+                                  QuicTime::Delta sample_min_rtt) {
+  // Do not expire min_rtt if none was ever available.
+  bool min_rtt_expired =
+      !min_rtt_.IsZero() && (now > (min_rtt_timestamp_ + kMinRttExpiry));
+
+  if (min_rtt_expired || sample_min_rtt < min_rtt_ || min_rtt_.IsZero()) {
+    QUIC_DVLOG(2) << "Min RTT updated, old value: " << min_rtt_
+                  << ", new value: " << sample_min_rtt
+                  << ", current time: " << now.ToDebuggingValue();
+
+    min_rtt_ = sample_min_rtt;
+    min_rtt_timestamp_ = now;
+  }
+  QUICHE_DCHECK(!min_rtt_.IsZero());
+
+  return min_rtt_expired;
+}
+
+void BbrSender::UpdateGainCyclePhase(QuicTime now,
+                                     QuicByteCount prior_in_flight,
+                                     bool has_losses) {
+  const QuicByteCount bytes_in_flight = unacked_packets_->bytes_in_flight();
+  // In most cases, the cycle is advanced after an RTT passes.
+  bool should_advance_gain_cycling = now - last_cycle_start_ > GetMinRtt();
+
+  // If the pacing gain is above 1.0, the connection is trying to probe the
+  // bandwidth by increasing the number of bytes in flight to at least
+  // pacing_gain * BDP.  Make sure that it actually reaches the target, as long
+  // as there are no losses suggesting that the buffers are not able to hold
+  // that much.
+  if (pacing_gain_ > 1.0 && !has_losses &&
+      prior_in_flight < GetTargetCongestionWindow(pacing_gain_)) {
+    should_advance_gain_cycling = false;
+  }
+
+  // If pacing gain is below 1.0, the connection is trying to drain the extra
+  // queue which could have been incurred by probing prior to it.  If the number
+  // of bytes in flight falls down to the estimated BDP value earlier, conclude
+  // that the queue has been successfully drained and exit this cycle early.
+  if (pacing_gain_ < 1.0 && bytes_in_flight <= GetTargetCongestionWindow(1)) {
+    should_advance_gain_cycling = true;
+  }
+
+  if (should_advance_gain_cycling) {
+    cycle_current_offset_ = (cycle_current_offset_ + 1) % kGainCycleLength;
+    if (cycle_current_offset_ == 0) {
+      ++stats_->bbr_num_cycles;
+    }
+    last_cycle_start_ = now;
+    // Stay in low gain mode until the target BDP is hit.
+    // Low gain mode will be exited immediately when the target BDP is achieved.
+    if (drain_to_target_ && pacing_gain_ < 1 &&
+        kPacingGain[cycle_current_offset_] == 1 &&
+        bytes_in_flight > GetTargetCongestionWindow(1)) {
+      return;
+    }
+    pacing_gain_ = kPacingGain[cycle_current_offset_];
+  }
+}
+
+void BbrSender::CheckIfFullBandwidthReached(
+    const SendTimeState& last_packet_send_state) {
+  if (last_sample_is_app_limited_) {
+    return;
+  }
+
+  QuicBandwidth target = bandwidth_at_last_round_ * kStartupGrowthTarget;
+  if (BandwidthEstimate() >= target) {
+    bandwidth_at_last_round_ = BandwidthEstimate();
+    rounds_without_bandwidth_gain_ = 0;
+    if (expire_ack_aggregation_in_startup_) {
+      // Expire old excess delivery measurements now that bandwidth increased.
+      sampler_.ResetMaxAckHeightTracker(0, round_trip_count_);
+    }
+    return;
+  }
+
+  rounds_without_bandwidth_gain_++;
+  if ((rounds_without_bandwidth_gain_ >= num_startup_rtts_) ||
+      ShouldExitStartupDueToLoss(last_packet_send_state)) {
+    QUICHE_DCHECK(has_non_app_limited_sample_);
+    is_at_full_bandwidth_ = true;
+  }
+}
+
+void BbrSender::MaybeExitStartupOrDrain(QuicTime now) {
+  if (mode_ == STARTUP && is_at_full_bandwidth_) {
+    OnExitStartup(now);
+    mode_ = DRAIN;
+    pacing_gain_ = drain_gain_;
+    congestion_window_gain_ = high_cwnd_gain_;
+  }
+  if (mode_ == DRAIN &&
+      unacked_packets_->bytes_in_flight() <= GetTargetCongestionWindow(1)) {
+    EnterProbeBandwidthMode(now);
+  }
+}
+
+void BbrSender::OnExitStartup(QuicTime now) {
+  QUICHE_DCHECK_EQ(mode_, STARTUP);
+  if (stats_) {
+    stats_->slowstart_duration.Stop(now);
+  }
+}
+
+bool BbrSender::ShouldExitStartupDueToLoss(
+    const SendTimeState& last_packet_send_state) const {
+  if (num_loss_events_in_round_ <
+          GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count) ||
+      !last_packet_send_state.is_valid) {
+    return false;
+  }
+
+  const QuicByteCount inflight_at_send = last_packet_send_state.bytes_in_flight;
+
+  if (inflight_at_send > 0 && bytes_lost_in_round_ > 0) {
+    if (bytes_lost_in_round_ >
+        inflight_at_send *
+            GetQuicFlag(FLAGS_quic_bbr2_default_loss_threshold)) {
+      stats_->bbr_exit_startup_due_to_loss = true;
+      return true;
+    }
+    return false;
+  }
+
+  return false;
+}
+
+void BbrSender::MaybeEnterOrExitProbeRtt(QuicTime now,
+                                         bool is_round_start,
+                                         bool min_rtt_expired) {
+  if (min_rtt_expired && !exiting_quiescence_ && mode_ != PROBE_RTT) {
+    if (InSlowStart()) {
+      OnExitStartup(now);
+    }
+    mode_ = PROBE_RTT;
+    pacing_gain_ = 1;
+    // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight|
+    // is at the target small value.
+    exit_probe_rtt_at_ = QuicTime::Zero();
+  }
+
+  if (mode_ == PROBE_RTT) {
+    sampler_.OnAppLimited();
+
+    if (exit_probe_rtt_at_ == QuicTime::Zero()) {
+      // If the window has reached the appropriate size, schedule exiting
+      // PROBE_RTT.  The CWND during PROBE_RTT is kMinimumCongestionWindow, but
+      // we allow an extra packet since QUIC checks CWND before sending a
+      // packet.
+      if (unacked_packets_->bytes_in_flight() <
+          ProbeRttCongestionWindow() + kMaxOutgoingPacketSize) {
+        exit_probe_rtt_at_ = now + kProbeRttTime;
+        probe_rtt_round_passed_ = false;
+      }
+    } else {
+      if (is_round_start) {
+        probe_rtt_round_passed_ = true;
+      }
+      if (now >= exit_probe_rtt_at_ && probe_rtt_round_passed_) {
+        min_rtt_timestamp_ = now;
+        if (!is_at_full_bandwidth_) {
+          EnterStartupMode(now);
+        } else {
+          EnterProbeBandwidthMode(now);
+        }
+      }
+    }
+  }
+
+  exiting_quiescence_ = false;
+}
+
+void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet,
+                                    bool has_losses,
+                                    bool is_round_start) {
+  // Disable recovery in startup, if loss-based exit is enabled.
+  if (!is_at_full_bandwidth_) {
+    return;
+  }
+
+  // Exit recovery when there are no losses for a round.
+  if (has_losses) {
+    end_recovery_at_ = last_sent_packet_;
+  }
+
+  switch (recovery_state_) {
+    case NOT_IN_RECOVERY:
+      // Enter conservation on the first loss.
+      if (has_losses) {
+        recovery_state_ = CONSERVATION;
+        // This will cause the |recovery_window_| to be set to the correct
+        // value in CalculateRecoveryWindow().
+        recovery_window_ = 0;
+        // Since the conservation phase is meant to be lasting for a whole
+        // round, extend the current round as if it were started right now.
+        current_round_trip_end_ = last_sent_packet_;
+      }
+      break;
+
+    case CONSERVATION:
+      if (is_round_start) {
+        recovery_state_ = GROWTH;
+      }
+      ABSL_FALLTHROUGH_INTENDED;
+
+    case GROWTH:
+      // Exit recovery if appropriate.
+      if (!has_losses && last_acked_packet > end_recovery_at_) {
+        recovery_state_ = NOT_IN_RECOVERY;
+      }
+
+      break;
+  }
+}
+
+void BbrSender::CalculatePacingRate(QuicByteCount bytes_lost) {
+  if (BandwidthEstimate().IsZero()) {
+    return;
+  }
+
+  QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate();
+  if (is_at_full_bandwidth_) {
+    pacing_rate_ = target_rate;
+    return;
+  }
+
+  // Pace at the rate of initial_window / RTT as soon as RTT measurements are
+  // available.
+  if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) {
+    pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(
+        initial_congestion_window_, rtt_stats_->min_rtt());
+    return;
+  }
+
+  if (detect_overshooting_) {
+    bytes_lost_while_detecting_overshooting_ += bytes_lost;
+    // Check for overshooting with network parameters adjusted when pacing rate
+    // > target_rate and loss has been detected.
+    if (pacing_rate_ > target_rate &&
+        bytes_lost_while_detecting_overshooting_ > 0) {
+      if (has_non_app_limited_sample_ ||
+          bytes_lost_while_detecting_overshooting_ *
+                  bytes_lost_multiplier_while_detecting_overshooting_ >
+              initial_congestion_window_) {
+        // We are fairly sure overshoot happens if 1) there is at least one
+        // non app-limited bw sample or 2) half of IW gets lost. Slow pacing
+        // rate.
+        pacing_rate_ = std::max(
+            target_rate, QuicBandwidth::FromBytesAndTimeDelta(
+                             cwnd_to_calculate_min_pacing_rate_, GetMinRtt()));
+        if (stats_) {
+          stats_->overshooting_detected_with_network_parameters_adjusted = true;
+        }
+        bytes_lost_while_detecting_overshooting_ = 0;
+        detect_overshooting_ = false;
+      }
+    }
+  }
+
+  // Do not decrease the pacing rate during startup.
+  pacing_rate_ = std::max(pacing_rate_, target_rate);
+}
+
+void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked,
+                                          QuicByteCount excess_acked) {
+  if (mode_ == PROBE_RTT) {
+    return;
+  }
+
+  QuicByteCount target_window =
+      GetTargetCongestionWindow(congestion_window_gain_);
+  if (is_at_full_bandwidth_) {
+    // Add the max recently measured ack aggregation to CWND.
+    target_window += sampler_.max_ack_height();
+  } else if (enable_ack_aggregation_during_startup_) {
+    // Add the most recent excess acked.  Because CWND never decreases in
+    // STARTUP, this will automatically create a very localized max filter.
+    target_window += excess_acked;
+  }
+
+  // Instead of immediately setting the target CWND as the new one, BBR grows
+  // the CWND towards |target_window| by only increasing it |bytes_acked| at a
+  // time.
+  if (is_at_full_bandwidth_) {
+    congestion_window_ =
+        std::min(target_window, congestion_window_ + bytes_acked);
+  } else if (congestion_window_ < target_window ||
+             sampler_.total_bytes_acked() < initial_congestion_window_) {
+    // If the connection is not yet out of startup phase, do not decrease the
+    // window.
+    congestion_window_ = congestion_window_ + bytes_acked;
+  }
+
+  // Enforce the limits on the congestion window.
+  congestion_window_ = std::max(congestion_window_, min_congestion_window_);
+  congestion_window_ = std::min(congestion_window_, max_congestion_window_);
+}
+
+void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
+                                        QuicByteCount bytes_lost) {
+  if (recovery_state_ == NOT_IN_RECOVERY) {
+    return;
+  }
+
+  // Set up the initial recovery window.
+  if (recovery_window_ == 0) {
+    recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
+    recovery_window_ = std::max(min_congestion_window_, recovery_window_);
+    return;
+  }
+
+  // Remove losses from the recovery window, while accounting for a potential
+  // integer underflow.
+  recovery_window_ = recovery_window_ >= bytes_lost
+                         ? recovery_window_ - bytes_lost
+                         : kMaxSegmentSize;
+
+  // In CONSERVATION mode, just subtracting losses is sufficient.  In GROWTH,
+  // release additional |bytes_acked| to achieve a slow-start-like behavior.
+  if (recovery_state_ == GROWTH) {
+    recovery_window_ += bytes_acked;
+  }
+
+  // Always allow sending at least |bytes_acked| in response.
+  recovery_window_ = std::max(
+      recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
+  recovery_window_ = std::max(min_congestion_window_, recovery_window_);
+}
+
+std::string BbrSender::GetDebugState() const {
+  std::ostringstream stream;
+  stream << ExportDebugState();
+  return stream.str();
+}
+
+void BbrSender::OnApplicationLimited(QuicByteCount bytes_in_flight) {
+  if (bytes_in_flight >= GetCongestionWindow()) {
+    return;
+  }
+
+  sampler_.OnAppLimited();
+  QUIC_DVLOG(2) << "Becoming application limited. Last sent packet: "
+                << last_sent_packet_ << ", CWND: " << GetCongestionWindow();
+}
+
+void BbrSender::PopulateConnectionStats(QuicConnectionStats* stats) const {
+  stats->num_ack_aggregation_epochs = sampler_.num_ack_aggregation_epochs();
+}
+
+BbrSender::DebugState BbrSender::ExportDebugState() const {
+  return DebugState(*this);
+}
+
+static std::string ModeToString(BbrSender::Mode mode) {
+  switch (mode) {
+    case BbrSender::STARTUP:
+      return "STARTUP";
+    case BbrSender::DRAIN:
+      return "DRAIN";
+    case BbrSender::PROBE_BW:
+      return "PROBE_BW";
+    case BbrSender::PROBE_RTT:
+      return "PROBE_RTT";
+  }
+  return "???";
+}
+
+std::ostream& operator<<(std::ostream& os, const BbrSender::Mode& mode) {
+  os << ModeToString(mode);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const BbrSender::DebugState& state) {
+  os << "Mode: " << ModeToString(state.mode) << std::endl;
+  os << "Maximum bandwidth: " << state.max_bandwidth << std::endl;
+  os << "Round trip counter: " << state.round_trip_count << std::endl;
+  os << "Gain cycle index: " << static_cast<int>(state.gain_cycle_index)
+     << std::endl;
+  os << "Congestion window: " << state.congestion_window << " bytes"
+     << std::endl;
+
+  if (state.mode == BbrSender::STARTUP) {
+    os << "(startup) Bandwidth at last round: " << state.bandwidth_at_last_round
+       << std::endl;
+    os << "(startup) Rounds without gain: "
+       << state.rounds_without_bandwidth_gain << std::endl;
+  }
+
+  os << "Minimum RTT: " << state.min_rtt << std::endl;
+  os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
+     << std::endl;
+
+  os << "Last sample is app-limited: "
+     << (state.last_sample_is_app_limited ? "yes" : "no");
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/bbr_sender.h b/quiche/quic/core/congestion_control/bbr_sender.h
new file mode 100644
index 0000000..1b9afc3
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr_sender.h
@@ -0,0 +1,399 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// BBR (Bottleneck Bandwidth and RTT) congestion control algorithm.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
+
+#include <cstdint>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class RttStats;
+
+// BbrSender implements BBR congestion control algorithm.  BBR aims to estimate
+// the current available Bottleneck Bandwidth and RTT (hence the name), and
+// regulates the pacing rate and the size of the congestion window based on
+// those signals.
+//
+// BBR relies on pacing in order to function properly.  Do not use BBR when
+// pacing is disabled.
+//
+// TODO(vasilvv): implement traffic policer (long-term sampling) mode.
+class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
+ public:
+  enum Mode {
+    // Startup phase of the connection.
+    STARTUP,
+    // After achieving the highest possible bandwidth during the startup, lower
+    // the pacing rate in order to drain the queue.
+    DRAIN,
+    // Cruising mode.
+    PROBE_BW,
+    // Temporarily slow down sending in order to empty the buffer and measure
+    // the real minimum RTT.
+    PROBE_RTT,
+  };
+
+  // Indicates how the congestion control limits the amount of bytes in flight.
+  enum RecoveryState {
+    // Do not limit.
+    NOT_IN_RECOVERY,
+    // Allow an extra outstanding byte for each byte acknowledged.
+    CONSERVATION,
+    // Allow two extra outstanding bytes for each byte acknowledged (slow
+    // start).
+    GROWTH
+  };
+
+  // Debug state can be exported in order to troubleshoot potential congestion
+  // control issues.
+  struct QUIC_EXPORT_PRIVATE DebugState {
+    explicit DebugState(const BbrSender& sender);
+    DebugState(const DebugState& state);
+
+    Mode mode;
+    QuicBandwidth max_bandwidth;
+    QuicRoundTripCount round_trip_count;
+    int gain_cycle_index;
+    QuicByteCount congestion_window;
+
+    bool is_at_full_bandwidth;
+    QuicBandwidth bandwidth_at_last_round;
+    QuicRoundTripCount rounds_without_bandwidth_gain;
+
+    QuicTime::Delta min_rtt;
+    QuicTime min_rtt_timestamp;
+
+    RecoveryState recovery_state;
+    QuicByteCount recovery_window;
+
+    bool last_sample_is_app_limited;
+    QuicPacketNumber end_of_app_limited_phase;
+  };
+
+  BbrSender(QuicTime now,
+            const RttStats* rtt_stats,
+            const QuicUnackedPacketMap* unacked_packets,
+            QuicPacketCount initial_tcp_congestion_window,
+            QuicPacketCount max_tcp_congestion_window,
+            QuicRandom* random,
+            QuicConnectionStats* stats);
+  BbrSender(const BbrSender&) = delete;
+  BbrSender& operator=(const BbrSender&) = delete;
+  ~BbrSender() override;
+
+  // Start implementation of SendAlgorithmInterface.
+  bool InSlowStart() const override;
+  bool InRecovery() const override;
+  bool ShouldSendProbingPacket() const override;
+
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+  void ApplyConnectionOptions(const QuicTagVector& connection_options) override;
+
+  void AdjustNetworkParameters(const NetworkParams& params) override;
+  void SetInitialCongestionWindowInPackets(
+      QuicPacketCount congestion_window) override;
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets) override;
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable) override;
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+  void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
+  void OnConnectionMigration() override {}
+  bool CanSend(QuicByteCount bytes_in_flight) override;
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+  QuicBandwidth BandwidthEstimate() const override;
+  bool HasGoodBandwidthEstimateForResumption() const override {
+    return has_non_app_limited_sample();
+  }
+  QuicByteCount GetCongestionWindow() const override;
+  QuicByteCount GetSlowStartThreshold() const override;
+  CongestionControlType GetCongestionControlType() const override;
+  std::string GetDebugState() const override;
+  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+  void PopulateConnectionStats(QuicConnectionStats* stats) const override;
+  // End implementation of SendAlgorithmInterface.
+
+  // Gets the number of RTTs BBR remains in STARTUP phase.
+  QuicRoundTripCount num_startup_rtts() const { return num_startup_rtts_; }
+  bool has_non_app_limited_sample() const {
+    return has_non_app_limited_sample_;
+  }
+
+  // Sets the pacing gain used in STARTUP.  Must be greater than 1.
+  void set_high_gain(float high_gain) {
+    QUICHE_DCHECK_LT(1.0f, high_gain);
+    high_gain_ = high_gain;
+    if (mode_ == STARTUP) {
+      pacing_gain_ = high_gain;
+    }
+  }
+
+  // Sets the CWND gain used in STARTUP.  Must be greater than 1.
+  void set_high_cwnd_gain(float high_cwnd_gain) {
+    QUICHE_DCHECK_LT(1.0f, high_cwnd_gain);
+    high_cwnd_gain_ = high_cwnd_gain;
+    if (mode_ == STARTUP) {
+      congestion_window_gain_ = high_cwnd_gain;
+    }
+  }
+
+  // Sets the gain used in DRAIN.  Must be less than 1.
+  void set_drain_gain(float drain_gain) {
+    QUICHE_DCHECK_GT(1.0f, drain_gain);
+    drain_gain_ = drain_gain;
+  }
+
+  // Returns the current estimate of the RTT of the connection.  Outside of the
+  // edge cases, this is minimum RTT.
+  QuicTime::Delta GetMinRtt() const;
+
+  DebugState ExportDebugState() const;
+
+ private:
+  // For switching send algorithm mid connection.
+  friend class Bbr2Sender;
+
+  using MaxBandwidthFilter = WindowedFilter<QuicBandwidth,
+                                            MaxFilter<QuicBandwidth>,
+                                            QuicRoundTripCount,
+                                            QuicRoundTripCount>;
+
+  using MaxAckHeightFilter = WindowedFilter<QuicByteCount,
+                                            MaxFilter<QuicByteCount>,
+                                            QuicRoundTripCount,
+                                            QuicRoundTripCount>;
+
+  // Computes the target congestion window using the specified gain.
+  QuicByteCount GetTargetCongestionWindow(float gain) const;
+  // The target congestion window during PROBE_RTT.
+  QuicByteCount ProbeRttCongestionWindow() const;
+  bool MaybeUpdateMinRtt(QuicTime now, QuicTime::Delta sample_min_rtt);
+
+  // Enters the STARTUP mode.
+  void EnterStartupMode(QuicTime now);
+  // Enters the PROBE_BW mode.
+  void EnterProbeBandwidthMode(QuicTime now);
+
+  // Updates the round-trip counter if a round-trip has passed.  Returns true if
+  // the counter has been advanced.
+  bool UpdateRoundTripCounter(QuicPacketNumber last_acked_packet);
+
+  // Updates the current gain used in PROBE_BW mode.
+  void UpdateGainCyclePhase(QuicTime now,
+                            QuicByteCount prior_in_flight,
+                            bool has_losses);
+  // Tracks for how many round-trips the bandwidth has not increased
+  // significantly.
+  void CheckIfFullBandwidthReached(const SendTimeState& last_packet_send_state);
+  // Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if
+  // appropriate.
+  void MaybeExitStartupOrDrain(QuicTime now);
+  // Decides whether to enter or exit PROBE_RTT.
+  void MaybeEnterOrExitProbeRtt(QuicTime now,
+                                bool is_round_start,
+                                bool min_rtt_expired);
+  // Determines whether BBR needs to enter, exit or advance state of the
+  // recovery.
+  void UpdateRecoveryState(QuicPacketNumber last_acked_packet,
+                           bool has_losses,
+                           bool is_round_start);
+
+  // Updates the ack aggregation max filter in bytes.
+  // Returns the most recent addition to the filter, or |newly_acked_bytes| if
+  // nothing was fed in to the filter.
+  QuicByteCount UpdateAckAggregationBytes(QuicTime ack_time,
+                                          QuicByteCount newly_acked_bytes);
+
+  // Determines the appropriate pacing rate for the connection.
+  void CalculatePacingRate(QuicByteCount bytes_lost);
+  // Determines the appropriate congestion window for the connection.
+  void CalculateCongestionWindow(QuicByteCount bytes_acked,
+                                 QuicByteCount excess_acked);
+  // Determines the appropriate window that constrains the in-flight during
+  // recovery.
+  void CalculateRecoveryWindow(QuicByteCount bytes_acked,
+                               QuicByteCount bytes_lost);
+
+  // Called right before exiting STARTUP.
+  void OnExitStartup(QuicTime now);
+
+  // Return whether we should exit STARTUP due to excessive loss.
+  bool ShouldExitStartupDueToLoss(
+      const SendTimeState& last_packet_send_state) const;
+
+  const RttStats* rtt_stats_;
+  const QuicUnackedPacketMap* unacked_packets_;
+  QuicRandom* random_;
+  QuicConnectionStats* stats_;
+
+  Mode mode_;
+
+  // Bandwidth sampler provides BBR with the bandwidth measurements at
+  // individual points.
+  BandwidthSampler sampler_;
+
+  // The number of the round trips that have occurred during the connection.
+  QuicRoundTripCount round_trip_count_;
+
+  // The packet number of the most recently sent packet.
+  QuicPacketNumber last_sent_packet_;
+  // Acknowledgement of any packet after |current_round_trip_end_| will cause
+  // the round trip counter to advance.
+  QuicPacketNumber current_round_trip_end_;
+
+  // Number of congestion events with some losses, in the current round.
+  int64_t num_loss_events_in_round_;
+
+  // Number of total bytes lost in the current round.
+  QuicByteCount bytes_lost_in_round_;
+
+  // The filter that tracks the maximum bandwidth over the multiple recent
+  // round-trips.
+  MaxBandwidthFilter max_bandwidth_;
+
+  // Minimum RTT estimate.  Automatically expires within 10 seconds (and
+  // triggers PROBE_RTT mode) if no new value is sampled during that period.
+  QuicTime::Delta min_rtt_;
+  // The time at which the current value of |min_rtt_| was assigned.
+  QuicTime min_rtt_timestamp_;
+
+  // The maximum allowed number of bytes in flight.
+  QuicByteCount congestion_window_;
+
+  // The initial value of the |congestion_window_|.
+  QuicByteCount initial_congestion_window_;
+
+  // The largest value the |congestion_window_| can achieve.
+  QuicByteCount max_congestion_window_;
+
+  // The smallest value the |congestion_window_| can achieve.
+  QuicByteCount min_congestion_window_;
+
+  // The pacing gain applied during the STARTUP phase.
+  float high_gain_;
+
+  // The CWND gain applied during the STARTUP phase.
+  float high_cwnd_gain_;
+
+  // The pacing gain applied during the DRAIN phase.
+  float drain_gain_;
+
+  // The current pacing rate of the connection.
+  QuicBandwidth pacing_rate_;
+
+  // The gain currently applied to the pacing rate.
+  float pacing_gain_;
+  // The gain currently applied to the congestion window.
+  float congestion_window_gain_;
+
+  // The gain used for the congestion window during PROBE_BW.  Latched from
+  // quic_bbr_cwnd_gain flag.
+  const float congestion_window_gain_constant_;
+  // The number of RTTs to stay in STARTUP mode.  Defaults to 3.
+  QuicRoundTripCount num_startup_rtts_;
+
+  // Number of round-trips in PROBE_BW mode, used for determining the current
+  // pacing gain cycle.
+  int cycle_current_offset_;
+  // The time at which the last pacing gain cycle was started.
+  QuicTime last_cycle_start_;
+
+  // Indicates whether the connection has reached the full bandwidth mode.
+  bool is_at_full_bandwidth_;
+  // Number of rounds during which there was no significant bandwidth increase.
+  QuicRoundTripCount rounds_without_bandwidth_gain_;
+  // The bandwidth compared to which the increase is measured.
+  QuicBandwidth bandwidth_at_last_round_;
+
+  // Set to true upon exiting quiescence.
+  bool exiting_quiescence_;
+
+  // Time at which PROBE_RTT has to be exited.  Setting it to zero indicates
+  // that the time is yet unknown as the number of packets in flight has not
+  // reached the required value.
+  QuicTime exit_probe_rtt_at_;
+  // Indicates whether a round-trip has passed since PROBE_RTT became active.
+  bool probe_rtt_round_passed_;
+
+  // Indicates whether the most recent bandwidth sample was marked as
+  // app-limited.
+  bool last_sample_is_app_limited_;
+  // Indicates whether any non app-limited samples have been recorded.
+  bool has_non_app_limited_sample_;
+
+  // Current state of recovery.
+  RecoveryState recovery_state_;
+  // Receiving acknowledgement of a packet after |end_recovery_at_| will cause
+  // BBR to exit the recovery mode.  A value above zero indicates at least one
+  // loss has been detected, so it must not be set back to zero.
+  QuicPacketNumber end_recovery_at_;
+  // A window used to limit the number of bytes in flight during loss recovery.
+  QuicByteCount recovery_window_;
+  // If true, consider all samples in recovery app-limited.
+  bool is_app_limited_recovery_;
+
+  // When true, pace at 1.5x and disable packet conservation in STARTUP.
+  bool slower_startup_;
+  // When true, disables packet conservation in STARTUP.
+  bool rate_based_startup_;
+
+  // When true, add the most recent ack aggregation measurement during STARTUP.
+  bool enable_ack_aggregation_during_startup_;
+  // When true, expire the windowed ack aggregation values in STARTUP when
+  // bandwidth increases more than 25%.
+  bool expire_ack_aggregation_in_startup_;
+
+  // If true, will not exit low gain mode until bytes_in_flight drops below BDP
+  // or it's time for high gain mode.
+  bool drain_to_target_;
+
+  // If true, slow down pacing rate in STARTUP when overshooting is detected.
+  bool detect_overshooting_;
+  // Bytes lost while detect_overshooting_ is true.
+  QuicByteCount bytes_lost_while_detecting_overshooting_;
+  // Slow down pacing rate if
+  // bytes_lost_while_detecting_overshooting_ *
+  // bytes_lost_multiplier_while_detecting_overshooting_ > IW.
+  uint8_t bytes_lost_multiplier_while_detecting_overshooting_;
+  // When overshooting is detected, do not drop pacing_rate_ below this value /
+  // min_rtt.
+  QuicByteCount cwnd_to_calculate_min_pacing_rate_;
+
+  // Max congestion window when adjusting network parameters.
+  QuicByteCount max_congestion_window_with_network_parameters_adjusted_;
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const BbrSender::Mode& mode);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const BbrSender::DebugState& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/bbr_sender_test.cc b/quiche/quic/core/congestion_control/bbr_sender_test.cc
new file mode 100644
index 0000000..62abb7a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/bbr_sender_test.cc
@@ -0,0 +1,1334 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/send_algorithm_test_result.pb.h"
+#include "quiche/quic/test_tools/send_algorithm_test_utils.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+using testing::AllOf;
+using testing::Ge;
+using testing::Le;
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_bbr_test_regression_mode, "",
+    "One of a) 'record' to record test result (one file per test), or "
+    "b) 'regress' to regress against recorded results, or "
+    "c) <anything else> for non-regression mode.");
+
+namespace quic {
+namespace test {
+
+// Use the initial CWND of 10, as 32 is too much for the test network.
+const uint32_t kInitialCongestionWindowPackets = 10;
+const uint32_t kDefaultWindowTCP =
+    kInitialCongestionWindowPackets * kDefaultTCPMSS;
+
+// Test network parameters.  Here, the topology of the network is:
+//
+//          BBR sender
+//               |
+//               |  <-- local link (10 Mbps, 2 ms delay)
+//               |
+//        Network switch
+//               *  <-- the bottleneck queue in the direction
+//               |          of the receiver
+//               |
+//               |  <-- test link (4 Mbps, 30 ms delay)
+//               |
+//               |
+//           Receiver
+//
+// The reason the bandwidths chosen are relatively low is the fact that the
+// connection simulator uses QuicTime for its internal clock, and as such has
+// the granularity of 1us, meaning that at bandwidth higher than 20 Mbps the
+// packets can start to land on the same timestamp.
+const QuicBandwidth kTestLinkBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(4000);
+const QuicBandwidth kLocalLinkBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10000);
+const QuicTime::Delta kTestPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(30);
+const QuicTime::Delta kLocalPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(2);
+const QuicTime::Delta kTestTransferTime =
+    kTestLinkBandwidth.TransferTime(kMaxOutgoingPacketSize) +
+    kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
+const QuicTime::Delta kTestRtt =
+    (kTestPropagationDelay + kLocalPropagationDelay + kTestTransferTime) * 2;
+const QuicByteCount kTestBdp = kTestRtt * kTestLinkBandwidth;
+
+class BbrSenderTest : public QuicTest {
+ protected:
+  BbrSenderTest()
+      : simulator_(&random_),
+        bbr_sender_(&simulator_,
+                    "BBR sender",
+                    "Receiver",
+                    Perspective::IS_CLIENT,
+                    /*connection_id=*/TestConnectionId(42)),
+        competing_sender_(&simulator_,
+                          "Competing sender",
+                          "Competing receiver",
+                          Perspective::IS_CLIENT,
+                          /*connection_id=*/TestConnectionId(43)),
+        receiver_(&simulator_,
+                  "Receiver",
+                  "BBR sender",
+                  Perspective::IS_SERVER,
+                  /*connection_id=*/TestConnectionId(42)),
+        competing_receiver_(&simulator_,
+                            "Competing receiver",
+                            "Competing sender",
+                            Perspective::IS_SERVER,
+                            /*connection_id=*/TestConnectionId(43)),
+        receiver_multiplexer_("Receiver multiplexer",
+                              {&receiver_, &competing_receiver_}) {
+    rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats();
+    const int kTestMaxPacketSize = 1350;
+    bbr_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
+    sender_ = SetupBbrSender(&bbr_sender_);
+    SetConnectionOption(kBBRA);
+    clock_ = simulator_.GetClock();
+  }
+
+  void SetUp() override {
+    if (GetQuicFlag(FLAGS_quic_bbr_test_regression_mode) == "regress") {
+      SendAlgorithmTestResult expected;
+      ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
+      random_seed_ = expected.random_seed();
+    } else {
+      random_seed_ = QuicRandom::GetInstance()->RandUint64();
+    }
+    random_.set_seed(random_seed_);
+    QUIC_LOG(INFO) << "BbrSenderTest simulator set up.  Seed: " << random_seed_;
+  }
+
+  ~BbrSenderTest() {
+    const std::string regression_mode =
+        GetQuicFlag(FLAGS_quic_bbr_test_regression_mode);
+    const QuicTime::Delta simulated_duration = clock_->Now() - QuicTime::Zero();
+    if (regression_mode == "record") {
+      RecordSendAlgorithmTestResult(random_seed_,
+                                    simulated_duration.ToMicroseconds());
+    } else if (regression_mode == "regress") {
+      CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
+    }
+  }
+
+  uint64_t random_seed_;
+  SimpleRandom random_;
+  simulator::Simulator simulator_;
+  simulator::QuicEndpoint bbr_sender_;
+  simulator::QuicEndpoint competing_sender_;
+  simulator::QuicEndpoint receiver_;
+  simulator::QuicEndpoint competing_receiver_;
+  simulator::QuicEndpointMultiplexer receiver_multiplexer_;
+  std::unique_ptr<simulator::Switch> switch_;
+  std::unique_ptr<simulator::SymmetricLink> bbr_sender_link_;
+  std::unique_ptr<simulator::SymmetricLink> competing_sender_link_;
+  std::unique_ptr<simulator::SymmetricLink> receiver_link_;
+
+  // Owned by different components of the connection.
+  const QuicClock* clock_;
+  const RttStats* rtt_stats_;
+  BbrSender* sender_;
+
+  // Enables BBR on |endpoint| and returns the associated BBR congestion
+  // controller.
+  BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
+    const RttStats* rtt_stats =
+        endpoint->connection()->sent_packet_manager().GetRttStats();
+    // Ownership of the sender will be overtaken by the endpoint.
+    BbrSender* sender = new BbrSender(
+        endpoint->connection()->clock()->Now(), rtt_stats,
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
+        kInitialCongestionWindowPackets,
+        GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+        QuicConnectionPeer::GetStats(endpoint->connection()));
+    QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
+    endpoint->RecordTrace();
+    return sender;
+  }
+
+  // Creates a default setup, which is a network with a bottleneck between the
+  // receiver and the switch.  The switch has the buffers four times larger than
+  // the bottleneck BDP, which should guarantee a lack of losses.
+  void CreateDefaultSetup() {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  2 * kTestBdp);
+    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_, switch_->port(2), kTestLinkBandwidth,
+        kTestPropagationDelay);
+  }
+
+  // Same as the default setup, except the buffer now is half of the BDP.
+  void CreateSmallBufferSetup() {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  0.5 * kTestBdp);
+    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_, switch_->port(2), kTestLinkBandwidth,
+        kTestPropagationDelay);
+  }
+
+  // Creates the variation of the default setup in which there is another sender
+  // that competes for the same bottleneck link.
+  void CreateCompetitionSetup() {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  2 * kTestBdp);
+
+    // Add a small offset to the competing link in order to avoid
+    // synchronization effects.
+    const QuicTime::Delta small_offset = QuicTime::Delta::FromMicroseconds(3);
+    bbr_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &bbr_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    competing_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &competing_sender_, switch_->port(3), kLocalLinkBandwidth,
+        kLocalPropagationDelay + small_offset);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_multiplexer_, switch_->port(2), kTestLinkBandwidth,
+        kTestPropagationDelay);
+  }
+
+  // Creates a BBR vs BBR competition setup.
+  void CreateBbrVsBbrSetup() {
+    SetupBbrSender(&competing_sender_);
+    CreateCompetitionSetup();
+  }
+
+  void EnableAggregation(QuicByteCount aggregation_bytes,
+                         QuicTime::Delta aggregation_timeout) {
+    // Enable aggregation on the path from the receiver to the sender.
+    switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
+                                              aggregation_timeout);
+  }
+
+  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
+    bbr_sender_.AddBytesToTransfer(transfer_size);
+    // TODO(vasilvv): consider rewriting this to run until the receiver actually
+    // receives the intended amount of bytes.
+    bool simulator_result = simulator_.RunUntilOrTimeout(
+        [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, deadline);
+    EXPECT_TRUE(simulator_result)
+        << "Simple transfer failed.  Bytes remaining: "
+        << bbr_sender_.bytes_to_transfer();
+    QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
+  }
+
+  // Drive the simulator by sending enough data to enter PROBE_BW.
+  void DriveOutOfStartup() {
+    ASSERT_FALSE(sender_->ExportDebugState().is_at_full_bandwidth);
+    DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
+    EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                     sender_->ExportDebugState().max_bandwidth, 0.02f);
+  }
+
+  // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
+  // |wait_time| between each burst.
+  void SendBursts(size_t number_of_bursts,
+                  QuicByteCount bytes,
+                  QuicTime::Delta wait_time) {
+    ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
+    for (size_t i = 0; i < number_of_bursts; i++) {
+      bbr_sender_.AddBytesToTransfer(bytes);
+
+      // Transfer data and wait for three seconds between each transfer.
+      simulator_.RunFor(wait_time);
+
+      // Ensure the connection did not time out.
+      ASSERT_TRUE(bbr_sender_.connection()->connected());
+      ASSERT_TRUE(receiver_.connection()->connected());
+    }
+
+    simulator_.RunFor(wait_time + kTestRtt);
+    ASSERT_EQ(0u, bbr_sender_.bytes_to_transfer());
+  }
+
+  void SetConnectionOption(QuicTag option) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(option);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  }
+};
+
+TEST_F(BbrSenderTest, SetInitialCongestionWindow) {
+  EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+  sender_->SetInitialCongestionWindowInPackets(3);
+  EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+// Test a simple long data transfer in the default setup.
+TEST_F(BbrSenderTest, SimpleTransfer) {
+  CreateDefaultSetup();
+
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
+}
+
+TEST_F(BbrSenderTest, SimpleTransferBBRB) {
+  SetConnectionOption(kBBRB);
+  CreateDefaultSetup();
+
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  ASSERT_GE(kTestBdp, kDefaultWindowTCP + kDefaultTCPMSS);
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.2f);
+}
+
+// Test a simple transfer in a situation when the buffer is less than BDP.
+TEST_F(BbrSenderTest, SimpleTransferSmallBuffer) {
+  CreateSmallBufferSetup();
+
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_GE(bbr_sender_.connection()->GetStats().packets_lost, 0u);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // The margin here is quite high, since there exists a possibility that the
+  // connection just exited high gain cycle.
+  EXPECT_APPROX_EQ(kTestRtt, sender_->GetMinRtt(), 0.2f);
+}
+
+TEST_F(BbrSenderTest, RemoveBytesLostInRecovery) {
+  CreateDefaultSetup();
+
+  DriveOutOfStartup();
+
+  // Drop a packet to enter recovery.
+  receiver_.DropNextIncomingPacket();
+  ASSERT_TRUE(
+      simulator_.RunUntilOrTimeout([this]() { return sender_->InRecovery(); },
+                                   QuicTime::Delta::FromSeconds(30)));
+
+  QuicUnackedPacketMap* unacked_packets =
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(
+          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
+  QuicPacketNumber largest_sent =
+      bbr_sender_.connection()->sent_packet_manager().GetLargestSentPacket();
+  // least_inflight is the smallest inflight packet.
+  QuicPacketNumber least_inflight =
+      bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked();
+  while (!unacked_packets->GetTransmissionInfo(least_inflight).in_flight) {
+    ASSERT_LE(least_inflight, largest_sent);
+    least_inflight++;
+  }
+  QuicPacketLength least_inflight_packet_size =
+      unacked_packets->GetTransmissionInfo(least_inflight).bytes_sent;
+  QuicByteCount prior_recovery_window =
+      sender_->ExportDebugState().recovery_window;
+  QuicByteCount prior_inflight = unacked_packets->bytes_in_flight();
+  QUIC_LOG(INFO) << "Recovery window:" << prior_recovery_window
+                 << ", least_inflight_packet_size:"
+                 << least_inflight_packet_size
+                 << ", bytes_in_flight:" << prior_inflight;
+  ASSERT_GT(prior_recovery_window, least_inflight_packet_size);
+
+  // Lose the least inflight packet and expect the recovery window to drop.
+  unacked_packets->RemoveFromInFlight(least_inflight);
+  LostPacketVector lost_packets;
+  lost_packets.emplace_back(least_inflight, least_inflight_packet_size);
+  sender_->OnCongestionEvent(false, prior_inflight, clock_->Now(), {},
+                             lost_packets);
+  EXPECT_EQ(sender_->ExportDebugState().recovery_window,
+            prior_inflight - least_inflight_packet_size);
+  EXPECT_LT(sender_->ExportDebugState().recovery_window, prior_recovery_window);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
+  SetConnectionOption(kBSAO);
+  CreateDefaultSetup();
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * kTestRtt);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
+              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.5f);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
+  SetConnectionOption(kBSAO);
+  // Decrease the CWND gain so extra CWND is required with stretch acks.
+  SetQuicFlag(FLAGS_quic_bbr_cwnd_gain, 1.0);
+  sender_ = new BbrSender(
+      bbr_sender_.connection()->clock()->Now(), rtt_stats_,
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(
+          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())),
+      kInitialCongestionWindowPackets,
+      GetQuicFlag(FLAGS_quic_max_congestion_window), &random_,
+      QuicConnectionPeer::GetStats(bbr_sender_.connection()));
+  QuicConnectionPeer::SetSendAlgorithm(bbr_sender_.connection(), sender_);
+  CreateDefaultSetup();
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
+  // bandwidth higher than the link rate.
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 2, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.1f);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+// TODO(b/172302465) Re-enable this test.
+TEST_F(BbrSenderTest,
+       QUIC_TEST_DISABLED_IN_CHROME(
+           SimpleTransfer2RTTAggregationBytes20RTTWindow)) {
+  SetConnectionOption(kBSAO);
+  CreateDefaultSetup();
+  SetConnectionOption(kBBR4);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * kTestRtt);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
+              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
+  // bandwidth higher than the link rate.
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
+}
+
+// Test a simple long data transfer with 2 rtts of aggregation.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
+  SetConnectionOption(kBSAO);
+  CreateDefaultSetup();
+  SetConnectionOption(kBBR5);
+  // 2 RTTs of aggregation, with a max of 10kb.
+  EnableAggregation(10 * 1024, 2 * kTestRtt);
+
+  // Transfer 12MB.
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
+  EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
+              sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
+
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+
+  // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
+  // bandwidth higher than the link rate.
+  // The margin here is high, because the aggregation greatly increases
+  // smoothed rtt.
+  EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->min_rtt(), 0.25f);
+}
+
+// Test the number of losses incurred by the startup phase in a situation when
+// the buffer is less than BDP.
+TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartup) {
+  CreateSmallBufferSetup();
+
+  DriveOutOfStartup();
+  float loss_rate =
+      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
+      bbr_sender_.connection()->GetStats().packets_sent;
+  EXPECT_LE(loss_rate, 0.31);
+}
+
+// Test the number of losses incurred by the startup phase in a situation when
+// the buffer is less than BDP, with a STARTUP CWND gain of 2.
+TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartupDerivedCWNDGain) {
+  CreateSmallBufferSetup();
+
+  SetConnectionOption(kBBQ2);
+  DriveOutOfStartup();
+  float loss_rate =
+      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
+      bbr_sender_.connection()->GetStats().packets_sent;
+  EXPECT_LE(loss_rate, 0.1);
+}
+
+// Ensures the code transitions loss recovery states correctly (NOT_IN_RECOVERY
+// -> CONSERVATION -> GROWTH -> NOT_IN_RECOVERY).
+TEST_F(BbrSenderTest, RecoveryStates) {
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  bool simulator_result;
+  CreateSmallBufferSetup();
+
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+  ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
+            sender_->ExportDebugState().recovery_state);
+
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().recovery_state !=
+               BbrSender::NOT_IN_RECOVERY;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::CONSERVATION,
+            sender_->ExportDebugState().recovery_state);
+
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().recovery_state !=
+               BbrSender::CONSERVATION;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::GROWTH, sender_->ExportDebugState().recovery_state);
+
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().recovery_state != BbrSender::GROWTH;
+      },
+      timeout);
+
+  ASSERT_EQ(BbrSender::NOT_IN_RECOVERY,
+            sender_->ExportDebugState().recovery_state);
+  ASSERT_TRUE(simulator_result);
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data after sending continuously for a while.
+TEST_F(BbrSenderTest, ApplicationLimitedBursts) {
+  CreateDefaultSetup();
+  EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
+
+  DriveOutOfStartup();
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+
+  SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+  EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+}
+
+// Verify the behavior of the algorithm in the case when the connection sends
+// small bursts of data and then starts sending continuously.
+TEST_F(BbrSenderTest, ApplicationLimitedBurstsWithoutPrior) {
+  CreateDefaultSetup();
+
+  SendBursts(40, 512, QuicTime::Delta::FromSeconds(3));
+  EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  DriveOutOfStartup();
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Verify that the DRAIN phase works correctly.
+TEST_F(BbrSenderTest, Drain) {
+  CreateDefaultSetup();
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
+                   sender_->PacingRate(0), 0.01f);
+
+  // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer
+  // with approximately 1 BDP.  Here, we use 0.8 to give some margin for
+  // error.
+  EXPECT_GE(queue->bytes_queued(), 0.8 * kTestBdp);
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
+  EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), kTestBdp);
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        QuicRoundTripCount rounds_passed =
+            sender_->ExportDebugState().round_trip_count - start_round_trip;
+        return rounds_passed >= 4 &&
+               sender_->ExportDebugState().gain_cycle_index == 7;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
+}
+
+// TODO(wub): Re-enable this test once default drain_gain changed to 0.75.
+// Verify that the DRAIN phase works correctly.
+TEST_F(BbrSenderTest, DISABLED_ShallowDrain) {
+  CreateDefaultSetup();
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0.75 * sender_->BandwidthEstimate(), sender_->PacingRate(0));
+  // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer
+  // with approximately 1.88 BDPs.  Here, we use 1.5 to give some margin for
+  // error.
+  EXPECT_GE(queue->bytes_queued(), 1.5 * kTestBdp);
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
+  EXPECT_APPROX_EQ(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), kTestBdp);
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        QuicRoundTripCount rounds_passed =
+            sender_->ExportDebugState().round_trip_count - start_round_trip;
+        return rounds_passed >= 4 &&
+               sender_->ExportDebugState().gain_cycle_index == 7;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  EXPECT_APPROX_EQ(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
+}
+
+// Verify that the connection enters and exits PROBE_RTT correctly.
+TEST_F(BbrSenderTest, ProbeRtt) {
+  CreateDefaultSetup();
+  DriveOutOfStartup();
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Wait until the connection enters PROBE_RTT.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
+
+  // Exit PROBE_RTT.
+  const QuicTime probe_rtt_start = clock_->Now();
+  const QuicTime::Delta time_to_exit_probe_rtt =
+      kTestRtt + QuicTime::Delta::FromMilliseconds(200);
+  simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
+}
+
+// Ensure that a connection that is app-limited and is at sufficiently low
+// bandwidth will not exit high gain phase, and similarly ensure that the
+// connection will exit low gain early if the number of bytes in flight is low.
+// TODO(crbug.com/1145095): Re-enable this test.
+TEST_F(BbrSenderTest, QUIC_TEST_DISABLED_IN_CHROME(InFlightAwareGainCycling)) {
+  CreateDefaultSetup();
+  DriveOutOfStartup();
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  while (!(sender_->ExportDebugState().gain_cycle_index >= 4 &&
+           bbr_sender_.bytes_to_transfer() == 0)) {
+    bbr_sender_.AddBytesToTransfer(kTestLinkBandwidth.ToBytesPerSecond());
+    ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+        [this]() { return bbr_sender_.bytes_to_transfer() == 0; }, timeout));
+  }
+
+  // Send at 10% of available rate.  Run for 3 seconds, checking in the middle
+  // and at the end.  The pacing gain should be high throughout.
+  QuicBandwidth target_bandwidth = 0.1f * kTestLinkBandwidth;
+  QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
+  for (int i = 0; i < 2; i++) {
+    SendBursts(5, target_bandwidth * burst_interval, burst_interval);
+    EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+    EXPECT_EQ(0, sender_->ExportDebugState().gain_cycle_index);
+    EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                     sender_->ExportDebugState().max_bandwidth, 0.02f);
+  }
+
+  // Now that in-flight is almost zero and the pacing gain is still above 1,
+  // send approximately 1.25 BDPs worth of data.  This should cause the
+  // PROBE_BW mode to enter low gain cycle, and exit it earlier than one min_rtt
+  // due to running out of data to send.
+  bbr_sender_.AddBytesToTransfer(1.3 * kTestBdp);
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().gain_cycle_index == 1; },
+      timeout));
+
+  simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_EQ(2, sender_->ExportDebugState().gain_cycle_index);
+}
+
+// Ensure that the pacing rate does not drop at startup.
+TEST_F(BbrSenderTest, NoBandwidthDropOnStartup) {
+  CreateDefaultSetup();
+
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result;
+
+  QuicBandwidth initial_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      kInitialCongestionWindowPackets * kDefaultTCPMSS,
+      rtt_stats_->initial_rtt());
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+
+  // Send a packet.
+  bbr_sender_.AddBytesToTransfer(1000);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return receiver_.bytes_received() == 1000; }, timeout);
+  ASSERT_TRUE(simulator_result);
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+
+  // Wait for a while.
+  simulator_.RunFor(QuicTime::Delta::FromSeconds(2));
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+
+  // Send another packet.
+  bbr_sender_.AddBytesToTransfer(1000);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return receiver_.bytes_received() == 2000; }, timeout);
+  ASSERT_TRUE(simulator_result);
+  EXPECT_GE(sender_->PacingRate(0), initial_rate);
+}
+
+// Test exiting STARTUP earlier due to the 1RTT connection option.
+TEST_F(BbrSenderTest, SimpleTransfer1RTTStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(k1RTT);
+  EXPECT_EQ(1u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier due to the 2RTT connection option.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(k2RTT);
+  EXPECT_EQ(2u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(2u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier upon loss.
+TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLoss) {
+  CreateDefaultSetup();
+
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier upon loss with a small buffer.
+TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLossSmallBuffer) {
+  CreateSmallBufferSetup();
+
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_NE(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(BbrSenderTest, DerivedPacingGainStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ1);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.773 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(BbrSenderTest, DerivedCWNDGainStartup) {
+  CreateSmallBufferSetup();
+
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  if (!bbr_sender_.connection()->GetStats().bbr_exit_startup_due_to_loss) {
+    EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  }
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  float loss_rate =
+      static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) /
+      bbr_sender_.connection()->GetStats().packets_sent;
+  EXPECT_LT(loss_rate, 0.15f);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // Expect an SRTT less than 2.7 * Min RTT on exit from STARTUP.
+  EXPECT_GT(kTestRtt * 2.7, rtt_stats_->smoothed_rtt());
+}
+
+TEST_F(BbrSenderTest, AckAggregationInStartup) {
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ3);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
+                   sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_APPROX_EQ(kTestLinkBandwidth,
+                   sender_->ExportDebugState().max_bandwidth, 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test that two BBR flows started slightly apart from each other terminate.
+TEST_F(BbrSenderTest, SimpleCompetition) {
+  const QuicByteCount transfer_size = 10 * 1024 * 1024;
+  const QuicTime::Delta transfer_time =
+      kTestLinkBandwidth.TransferTime(transfer_size);
+  CreateBbrVsBbrSetup();
+
+  // Transfer 10% of data in first transfer.
+  bbr_sender_.AddBytesToTransfer(transfer_size);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return receiver_.bytes_received() >= 0.1 * transfer_size; },
+      transfer_time);
+  ASSERT_TRUE(simulator_result);
+
+  // Start the second transfer and wait until both finish.
+  competing_sender_.AddBytesToTransfer(transfer_size);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return receiver_.bytes_received() == transfer_size &&
+               competing_receiver_.bytes_received() == transfer_size;
+      },
+      3 * transfer_time);
+  ASSERT_TRUE(simulator_result);
+}
+
+// Test that BBR can resume bandwidth from cached network parameters.
+TEST_F(BbrSenderTest, ResumeConnectionState) {
+  CreateDefaultSetup();
+
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth, kTestRtt,
+                                            false));
+  EXPECT_EQ(kTestLinkBandwidth * kTestRtt,
+            sender_->ExportDebugState().congestion_window);
+
+  EXPECT_EQ(kTestLinkBandwidth, sender_->PacingRate(/*bytes_in_flight=*/0));
+
+  EXPECT_APPROX_EQ(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f);
+
+  DriveOutOfStartup();
+}
+
+// Test with a min CWND of 1 instead of 4 packets.
+TEST_F(BbrSenderTest, ProbeRTTMinCWND1) {
+  CreateDefaultSetup();
+  SetConnectionOption(kMIN1);
+  DriveOutOfStartup();
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Wait until the connection enters PROBE_RTT.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
+  // The PROBE_RTT CWND should be 1 if the min CWND is 1.
+  EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+  // Exit PROBE_RTT.
+  const QuicTime probe_rtt_start = clock_->Now();
+  const QuicTime::Delta time_to_exit_probe_rtt =
+      kTestRtt + QuicTime::Delta::FromMilliseconds(200);
+  simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
+  EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
+}
+
+TEST_F(BbrSenderTest, StartupStats) {
+  CreateDefaultSetup();
+
+  DriveOutOfStartup();
+  ASSERT_FALSE(sender_->InSlowStart());
+
+  const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
+  EXPECT_EQ(1u, stats.slowstart_count);
+  EXPECT_THAT(stats.slowstart_num_rtts, AllOf(Ge(5u), Le(15u)));
+  EXPECT_THAT(stats.slowstart_packets_sent, AllOf(Ge(100u), Le(1000u)));
+  EXPECT_THAT(stats.slowstart_bytes_sent, AllOf(Ge(100000u), Le(1000000u)));
+  EXPECT_LE(stats.slowstart_packets_lost, 10u);
+  EXPECT_LE(stats.slowstart_bytes_lost, 10000u);
+  EXPECT_FALSE(stats.slowstart_duration.IsRunning());
+  EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
+              AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
+                    Le(QuicTime::Delta::FromMilliseconds(1500))));
+  EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
+            QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection())
+                ->GetSlowStartDuration());
+}
+
+// Regression test for b/143540157.
+TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange1RTT) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  const QuicByteCount previous_cwnd =
+      sender_->ExportDebugState().congestion_window;
+
+  // Bootstrap cwnd.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  EXPECT_LT(previous_cwnd, sender_->ExportDebugState().congestion_window);
+
+  // Verify pacing rate is re-calculated based on the new cwnd and min_rtt.
+  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
+                       sender_->ExportDebugState().congestion_window,
+                       sender_->ExportDebugState().min_rtt),
+                   sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
+}
+
+TEST_F(BbrSenderTest, RecalculatePacingRateOnCwndChange0RTT) {
+  CreateDefaultSetup();
+  // Initial RTT is available.
+  const_cast<RttStats*>(rtt_stats_)->set_initial_rtt(kTestRtt);
+
+  // Bootstrap cwnd.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  EXPECT_LT(kInitialCongestionWindowPackets * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  // No Rtt sample is available.
+  EXPECT_TRUE(sender_->ExportDebugState().min_rtt.IsZero());
+
+  // Verify pacing rate is re-calculated based on the new cwnd and initial
+  // RTT.
+  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesAndTimeDelta(
+                       sender_->ExportDebugState().congestion_window,
+                       rtt_stats_->initial_rtt()),
+                   sender_->PacingRate(/*bytes_in_flight=*/0), 0.01f);
+}
+
+TEST_F(BbrSenderTest, MitigateCwndBootstrappingOvershoot) {
+  CreateDefaultSetup();
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(8 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  QuicBandwidth pacing_rate = sender_->PacingRate(0);
+  EXPECT_EQ(8 * kTestLinkBandwidth, pacing_rate);
+
+  // Wait until pacing_rate decreases.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, pacing_rate]() { return sender_->PacingRate(0) < pacing_rate; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  if (GetQuicReloadableFlag(quic_conservative_cwnd_and_pacing_gains)) {
+    EXPECT_APPROX_EQ(2.0f * sender_->BandwidthEstimate(),
+                     sender_->PacingRate(0), 0.01f);
+  } else {
+    EXPECT_APPROX_EQ(2.885f * sender_->BandwidthEstimate(),
+                     sender_->PacingRate(0), 0.01f);
+  }
+}
+
+TEST_F(BbrSenderTest, 200InitialCongestionWindowWithNetworkParameterAdjusted) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  // Verify cwnd is capped at 200.
+  EXPECT_EQ(200 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+TEST_F(BbrSenderTest, 100InitialCongestionWindowFromNetworkParameter) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  SendAlgorithmInterface::NetworkParams network_params(
+      1024 * kTestLinkBandwidth, QuicTime::Delta::Zero(), false);
+  network_params.max_initial_congestion_window = 100;
+  bbr_sender_.connection()->AdjustNetworkParameters(network_params);
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+TEST_F(BbrSenderTest, 100InitialCongestionWindowWithNetworkParameterAdjusted) {
+  SetConnectionOption(kICW1);
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+// Ensures bandwidth estimate does not change after a loss only event.
+// Regression test for b/151239871.
+TEST_F(BbrSenderTest, LossOnlyCongestionEvent) {
+  CreateDefaultSetup();
+
+  DriveOutOfStartup();
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+
+  // Send some bursts, each burst increments round count by 1, since it only
+  // generates small, app-limited samples, the max_bandwidth_ will not be
+  // updated. At the end of all bursts, all estimates in max_bandwidth_ will
+  // look very old such that any Update() will reset all estimates.
+  SendBursts(20, 512, QuicTime::Delta::FromSeconds(3));
+
+  QuicUnackedPacketMap* unacked_packets =
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(
+          QuicConnectionPeer::GetSentPacketManager(bbr_sender_.connection()));
+  // Run until we have something in flight.
+  bbr_sender_.AddBytesToTransfer(50 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [&]() { return unacked_packets->bytes_in_flight() > 0; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+
+  const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
+  EXPECT_APPROX_EQ(kTestLinkBandwidth, prior_bandwidth_estimate, 0.01f);
+
+  // Lose the least unacked packet.
+  LostPacketVector lost_packets;
+  lost_packets.emplace_back(
+      bbr_sender_.connection()->sent_packet_manager().GetLeastUnacked(),
+      kDefaultMaxPacketSize);
+
+  QuicTime now = simulator_.GetClock()->Now() + kTestRtt * 0.25;
+  sender_->OnCongestionEvent(false, unacked_packets->bytes_in_flight(), now, {},
+                             lost_packets);
+
+  // Bandwidth estimate should not change for the loss only event.
+  EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
+}
+
+TEST_F(BbrSenderTest, EnableOvershootingDetection) {
+  SetConnectionOption(kDTOS);
+  CreateSmallBufferSetup();
+  // Set a overly large initial cwnd.
+  sender_->SetInitialCongestionWindowInPackets(200);
+  const QuicConnectionStats& stats = bbr_sender_.connection()->GetStats();
+  EXPECT_FALSE(stats.overshooting_detected_with_network_parameters_adjusted);
+  DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
+
+  // Verify overshooting is detected.
+  EXPECT_TRUE(stats.overshooting_detected_with_network_parameters_adjusted);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/cubic_bytes.cc b/quiche/quic/core/congestion_control/cubic_bytes.cc
new file mode 100644
index 0000000..f3f9d37
--- /dev/null
+++ b/quiche/quic/core/congestion_control/cubic_bytes.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/cubic_bytes.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstdint>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Constants based on TCP defaults.
+// The following constants are in 2^10 fractions of a second instead of ms to
+// allow a 10 shift right to divide.
+const int kCubeScale = 40;  // 1024*1024^3 (first 1024 is from 0.100^3)
+                            // where 0.100 is 100 ms which is the scaling
+                            // round trip time.
+const int kCubeCongestionWindowScale = 410;
+// The cube factor for packets in bytes.
+const uint64_t kCubeFactor =
+    (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale / kDefaultTCPMSS;
+
+const float kDefaultCubicBackoffFactor = 0.7f;  // Default Cubic backoff factor.
+// Additional backoff factor when loss occurs in the concave part of the Cubic
+// curve. This additional backoff factor is expected to give up bandwidth to
+// new concurrent flows and speed up convergence.
+const float kBetaLastMax = 0.85f;
+
+}  // namespace
+
+CubicBytes::CubicBytes(const QuicClock* clock)
+    : clock_(clock),
+      num_connections_(kDefaultNumConnections),
+      epoch_(QuicTime::Zero()) {
+  ResetCubicState();
+}
+
+void CubicBytes::SetNumConnections(int num_connections) {
+  num_connections_ = num_connections;
+}
+
+float CubicBytes::Alpha() const {
+  // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
+  // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
+  // We derive the equivalent alpha for an N-connection emulation as:
+  const float beta = Beta();
+  return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
+}
+
+float CubicBytes::Beta() const {
+  // kNConnectionBeta is the backoff factor after loss for our N-connection
+  // emulation, which emulates the effective backoff of an ensemble of N
+  // TCP-Reno connections on a single loss event. The effective multiplier is
+  // computed as:
+  return (num_connections_ - 1 + kDefaultCubicBackoffFactor) / num_connections_;
+}
+
+float CubicBytes::BetaLastMax() const {
+  // BetaLastMax is the additional backoff factor after loss for our
+  // N-connection emulation, which emulates the additional backoff of
+  // an ensemble of N TCP-Reno connections on a single loss event. The
+  // effective multiplier is computed as:
+  return (num_connections_ - 1 + kBetaLastMax) / num_connections_;
+}
+
+void CubicBytes::ResetCubicState() {
+  epoch_ = QuicTime::Zero();             // Reset time.
+  last_max_congestion_window_ = 0;
+  acked_bytes_count_ = 0;
+  estimated_tcp_congestion_window_ = 0;
+  origin_point_congestion_window_ = 0;
+  time_to_origin_point_ = 0;
+  last_target_congestion_window_ = 0;
+}
+
+void CubicBytes::OnApplicationLimited() {
+  // When sender is not using the available congestion window, the window does
+  // not grow. But to be RTT-independent, Cubic assumes that the sender has been
+  // using the entire window during the time since the beginning of the current
+  // "epoch" (the end of the last loss recovery period). Since
+  // application-limited periods break this assumption, we reset the epoch when
+  // in such a period. This reset effectively freezes congestion window growth
+  // through application-limited periods and allows Cubic growth to continue
+  // when the entire window is being used.
+  epoch_ = QuicTime::Zero();
+}
+
+QuicByteCount CubicBytes::CongestionWindowAfterPacketLoss(
+    QuicByteCount current_congestion_window) {
+  // Since bytes-mode Reno mode slightly under-estimates the cwnd, we
+  // may never reach precisely the last cwnd over the course of an
+  // RTT.  Do not interpret a slight under-estimation as competing traffic.
+  if (current_congestion_window + kDefaultTCPMSS <
+      last_max_congestion_window_) {
+    // We never reached the old max, so assume we are competing with
+    // another flow. Use our extra back off factor to allow the other
+    // flow to go up.
+    last_max_congestion_window_ =
+        static_cast<int>(BetaLastMax() * current_congestion_window);
+  } else {
+    last_max_congestion_window_ = current_congestion_window;
+  }
+  epoch_ = QuicTime::Zero();  // Reset time.
+  return static_cast<int>(current_congestion_window * Beta());
+}
+
+QuicByteCount CubicBytes::CongestionWindowAfterAck(
+    QuicByteCount acked_bytes,
+    QuicByteCount current_congestion_window,
+    QuicTime::Delta delay_min,
+    QuicTime event_time) {
+  acked_bytes_count_ += acked_bytes;
+
+  if (!epoch_.IsInitialized()) {
+    // First ACK after a loss event.
+    QUIC_DVLOG(1) << "Start of epoch";
+    epoch_ = event_time;               // Start of epoch.
+    acked_bytes_count_ = acked_bytes;  // Reset count.
+    // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
+    estimated_tcp_congestion_window_ = current_congestion_window;
+    if (last_max_congestion_window_ <= current_congestion_window) {
+      time_to_origin_point_ = 0;
+      origin_point_congestion_window_ = current_congestion_window;
+    } else {
+      time_to_origin_point_ = static_cast<uint32_t>(
+          cbrt(kCubeFactor *
+               (last_max_congestion_window_ - current_congestion_window)));
+      origin_point_congestion_window_ = last_max_congestion_window_;
+    }
+  }
+  // Change the time unit from microseconds to 2^10 fractions per second. Take
+  // the round trip time in account. This is done to allow us to use shift as a
+  // divide operator.
+  int64_t elapsed_time =
+      ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
+      kNumMicrosPerSecond;
+
+  // Right-shifts of negative, signed numbers have implementation-dependent
+  // behavior, so force the offset to be positive, as is done in the kernel.
+  uint64_t offset = std::abs(time_to_origin_point_ - elapsed_time);
+
+  QuicByteCount delta_congestion_window = (kCubeCongestionWindowScale * offset *
+                                           offset * offset * kDefaultTCPMSS) >>
+                                          kCubeScale;
+
+  const bool add_delta = elapsed_time > time_to_origin_point_;
+  QUICHE_DCHECK(add_delta ||
+                (origin_point_congestion_window_ > delta_congestion_window));
+  QuicByteCount target_congestion_window =
+      add_delta ? origin_point_congestion_window_ + delta_congestion_window
+                : origin_point_congestion_window_ - delta_congestion_window;
+  // Limit the CWND increase to half the acked bytes.
+  target_congestion_window =
+      std::min(target_congestion_window,
+               current_congestion_window + acked_bytes_count_ / 2);
+
+  QUICHE_DCHECK_LT(0u, estimated_tcp_congestion_window_);
+  // Increase the window by approximately Alpha * 1 MSS of bytes every
+  // time we ack an estimated tcp window of bytes.  For small
+  // congestion windows (less than 25), the formula below will
+  // increase slightly slower than linearly per estimated tcp window
+  // of bytes.
+  estimated_tcp_congestion_window_ += acked_bytes_count_ *
+                                      (Alpha() * kDefaultTCPMSS) /
+                                      estimated_tcp_congestion_window_;
+  acked_bytes_count_ = 0;
+
+  // We have a new cubic congestion window.
+  last_target_congestion_window_ = target_congestion_window;
+
+  // Compute target congestion_window based on cubic target and estimated TCP
+  // congestion_window, use highest (fastest).
+  if (target_congestion_window < estimated_tcp_congestion_window_) {
+    target_congestion_window = estimated_tcp_congestion_window_;
+  }
+
+  QUIC_DVLOG(1) << "Final target congestion_window: "
+                << target_congestion_window;
+  return target_congestion_window;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/cubic_bytes.h b/quiche/quic/core/congestion_control/cubic_bytes.h
new file mode 100644
index 0000000..6eb43ab
--- /dev/null
+++ b/quiche/quic/core/congestion_control/cubic_bytes.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Cubic algorithm, helper class to TCP cubic.
+// For details see http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class CubicBytesTest;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE CubicBytes {
+ public:
+  explicit CubicBytes(const QuicClock* clock);
+  CubicBytes(const CubicBytes&) = delete;
+  CubicBytes& operator=(const CubicBytes&) = delete;
+
+  void SetNumConnections(int num_connections);
+
+  // Call after a timeout to reset the cubic state.
+  void ResetCubicState();
+
+  // Compute a new congestion window to use after a loss event.
+  // Returns the new congestion window in packets. The new congestion window is
+  // a multiplicative decrease of our current window.
+  QuicByteCount CongestionWindowAfterPacketLoss(QuicPacketCount current);
+
+  // Compute a new congestion window to use after a received ACK.
+  // Returns the new congestion window in bytes. The new congestion window
+  // follows a cubic function that depends on the time passed since last packet
+  // loss.
+  QuicByteCount CongestionWindowAfterAck(QuicByteCount acked_bytes,
+                                         QuicByteCount current,
+                                         QuicTime::Delta delay_min,
+                                         QuicTime event_time);
+
+  // Call on ack arrival when sender is unable to use the available congestion
+  // window. Resets Cubic state during quiescence.
+  void OnApplicationLimited();
+
+ private:
+  friend class test::CubicBytesTest;
+
+  static const QuicTime::Delta MaxCubicTimeInterval() {
+    return QuicTime::Delta::FromMilliseconds(30);
+  }
+
+  // Compute the TCP Cubic alpha, beta, and beta-last-max based on the
+  // current number of connections.
+  float Alpha() const;
+  float Beta() const;
+  float BetaLastMax() const;
+
+  QuicByteCount last_max_congestion_window() const {
+    return last_max_congestion_window_;
+  }
+
+  const QuicClock* clock_;
+
+  // Number of connections to simulate.
+  int num_connections_;
+
+  // Time when this cycle started, after last loss event.
+  QuicTime epoch_;
+
+  // Max congestion window used just before last loss event.
+  // Note: to improve fairness to other streams an additional back off is
+  // applied to this value if the new value is below our latest value.
+  QuicByteCount last_max_congestion_window_;
+
+  // Number of acked bytes since the cycle started (epoch).
+  QuicByteCount acked_bytes_count_;
+
+  // TCP Reno equivalent congestion window in packets.
+  QuicByteCount estimated_tcp_congestion_window_;
+
+  // Origin point of cubic function.
+  QuicByteCount origin_point_congestion_window_;
+
+  // Time to origin point of cubic function in 2^10 fractions of a second.
+  uint32_t time_to_origin_point_;
+
+  // Last congestion window in packets computed by cubic function.
+  QuicByteCount last_target_congestion_window_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_CUBIC_BYTES_H_
diff --git a/quiche/quic/core/congestion_control/cubic_bytes_test.cc b/quiche/quic/core/congestion_control/cubic_bytes_test.cc
new file mode 100644
index 0000000..4899d51
--- /dev/null
+++ b/quiche/quic/core/congestion_control/cubic_bytes_test.cc
@@ -0,0 +1,387 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/cubic_bytes.h"
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const float kBeta = 0.7f;          // Default Cubic backoff factor.
+const float kBetaLastMax = 0.85f;  // Default Cubic backoff factor.
+const uint32_t kNumConnections = 2;
+const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
+const float kNConnectionBetaLastMax =
+    (kNumConnections - 1 + kBetaLastMax) / kNumConnections;
+const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
+                                (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
+
+}  // namespace
+
+class CubicBytesTest : public QuicTest {
+ protected:
+  CubicBytesTest()
+      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+        hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
+        cubic_(&clock_) {}
+
+  QuicByteCount RenoCwndInBytes(QuicByteCount current_cwnd) {
+    QuicByteCount reno_estimated_cwnd =
+        current_cwnd +
+        kDefaultTCPMSS * (kNConnectionAlpha * kDefaultTCPMSS) / current_cwnd;
+    return reno_estimated_cwnd;
+  }
+
+  QuicByteCount ConservativeCwndInBytes(QuicByteCount current_cwnd) {
+    QuicByteCount conservative_cwnd = current_cwnd + kDefaultTCPMSS / 2;
+    return conservative_cwnd;
+  }
+
+  QuicByteCount CubicConvexCwndInBytes(QuicByteCount initial_cwnd,
+                                       QuicTime::Delta rtt,
+                                       QuicTime::Delta elapsed_time) {
+    const int64_t offset =
+        ((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000;
+    const QuicByteCount delta_congestion_window =
+        ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40);
+    const QuicByteCount cubic_cwnd = initial_cwnd + delta_congestion_window;
+    return cubic_cwnd;
+  }
+
+  QuicByteCount LastMaxCongestionWindow() {
+    return cubic_.last_max_congestion_window();
+  }
+
+  QuicTime::Delta MaxCubicTimeInterval() {
+    return cubic_.MaxCubicTimeInterval();
+  }
+
+  const QuicTime::Delta one_ms_;
+  const QuicTime::Delta hundred_ms_;
+  MockClock clock_;
+  CubicBytes cubic_;
+};
+
+// TODO(jokulik): The original "AboveOrigin" test, below, is very
+// loose.  It's nearly impossible to make the test tighter without
+// deploying the fix for convex mode.  Once cubic convex is deployed,
+// replace "AboveOrigin" with this test.
+TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) {
+  // Convex growth.
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  int64_t rtt_min_ms = rtt_min.ToMilliseconds();
+  float rtt_min_s = rtt_min_ms / 1000.0;
+  QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
+  const QuicByteCount initial_cwnd = current_cwnd;
+
+  clock_.AdvanceTime(one_ms_);
+  const QuicTime initial_time = clock_.ApproximateNow();
+  const QuicByteCount expected_first_cwnd = RenoCwndInBytes(current_cwnd);
+  current_cwnd = cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                                 rtt_min, initial_time);
+  ASSERT_EQ(expected_first_cwnd, current_cwnd);
+
+  // Normal TCP phase.
+  // The maximum number of expected Reno RTTs is calculated by
+  // finding the point where the cubic curve and the reno curve meet.
+  const int max_reno_rtts =
+      std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
+      2;
+  for (int i = 0; i < max_reno_rtts; ++i) {
+    // Alternatively, we expect it to increase by one, every time we
+    // receive current_cwnd/Alpha acks back.  (This is another way of
+    // saying we expect cwnd to increase by approximately Alpha once
+    // we receive current_cwnd number ofacks back).
+    const uint64_t num_acks_this_epoch =
+        current_cwnd / kDefaultTCPMSS / kNConnectionAlpha;
+    const QuicByteCount initial_cwnd_this_epoch = current_cwnd;
+    for (QuicPacketCount n = 0; n < num_acks_this_epoch; ++n) {
+      // Call once per ACK.
+      const QuicByteCount expected_next_cwnd = RenoCwndInBytes(current_cwnd);
+      current_cwnd = cubic_.CongestionWindowAfterAck(
+          kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+      ASSERT_EQ(expected_next_cwnd, current_cwnd);
+    }
+    // Our byte-wise Reno implementation is an estimate.  We expect
+    // the cwnd to increase by approximately one MSS every
+    // cwnd/kDefaultTCPMSS/Alpha acks, but it may be off by as much as
+    // half a packet for smaller values of current_cwnd.
+    const QuicByteCount cwnd_change_this_epoch =
+        current_cwnd - initial_cwnd_this_epoch;
+    ASSERT_NEAR(kDefaultTCPMSS, cwnd_change_this_epoch, kDefaultTCPMSS / 2);
+    clock_.AdvanceTime(hundred_ms_);
+  }
+
+  for (int i = 0; i < 54; ++i) {
+    const uint64_t max_acks_this_epoch = current_cwnd / kDefaultTCPMSS;
+    const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
+        hundred_ms_.ToMicroseconds() / max_acks_this_epoch);
+    for (QuicPacketCount n = 0; n < max_acks_this_epoch; ++n) {
+      clock_.AdvanceTime(interval);
+      current_cwnd = cubic_.CongestionWindowAfterAck(
+          kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+      const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
+          initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
+      // If we allow per-ack updates, every update is a small cubic update.
+      ASSERT_EQ(expected_cwnd, current_cwnd);
+    }
+  }
+  const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
+      initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  ASSERT_EQ(expected_cwnd, current_cwnd);
+}
+
+// TODO(ianswett): This test was disabled when all fixes were enabled, but it
+// may be worth fixing.
+TEST_F(CubicBytesTest, DISABLED_AboveOrigin) {
+  // Convex growth.
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
+  // Without the signed-integer, cubic-convex fix, we start out in the
+  // wrong mode.
+  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
+  // Initialize the state.
+  clock_.AdvanceTime(one_ms_);
+  ASSERT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+  current_cwnd = expected_cwnd;
+  const QuicPacketCount initial_cwnd = expected_cwnd;
+  // Normal TCP phase.
+  for (int i = 0; i < 48; ++i) {
+    for (QuicPacketCount n = 1;
+         n < current_cwnd / kDefaultTCPMSS / kNConnectionAlpha; ++n) {
+      // Call once per ACK.
+      ASSERT_NEAR(
+          current_cwnd,
+          cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
+                                          clock_.ApproximateNow()),
+          kDefaultTCPMSS);
+    }
+    clock_.AdvanceTime(hundred_ms_);
+    current_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+    // When we fix convex mode and the uint64 arithmetic, we
+    // increase the expected_cwnd only after after the first 100ms,
+    // rather than after the initial 1ms.
+    expected_cwnd += kDefaultTCPMSS;
+    ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
+  }
+  // Cubic phase.
+  for (int i = 0; i < 52; ++i) {
+    for (QuicPacketCount n = 1; n < current_cwnd / kDefaultTCPMSS; ++n) {
+      // Call once per ACK.
+      ASSERT_NEAR(
+          current_cwnd,
+          cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min,
+                                          clock_.ApproximateNow()),
+          kDefaultTCPMSS);
+    }
+    clock_.AdvanceTime(hundred_ms_);
+    current_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  }
+  // Total time elapsed so far; add min_rtt (0.1s) here as well.
+  float elapsed_time_s = 10.0f + 0.1f;
+  // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
+  expected_cwnd =
+      initial_cwnd / kDefaultTCPMSS +
+      (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
+  EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS);
+}
+
+// Constructs an artificial scenario to ensure that cubic-convex
+// increases are truly fine-grained:
+//
+// - After starting the epoch, this test advances the elapsed time
+// sufficiently far that cubic will do small increases at less than
+// MaxCubicTimeInterval() intervals.
+//
+// - Sets an artificially large initial cwnd to prevent Reno from the
+// convex increases on every ack.
+TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) {
+  // Start the test with an artificially large cwnd to prevent Reno
+  // from over-taking cubic.
+  QuicByteCount current_cwnd = 1000 * kDefaultTCPMSS;
+  const QuicByteCount initial_cwnd = current_cwnd;
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  clock_.AdvanceTime(one_ms_);
+  QuicTime initial_time = clock_.ApproximateNow();
+
+  // Start the epoch and then artificially advance the time.
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(600));
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+
+  // We expect the algorithm to perform only non-zero, fine-grained cubic
+  // increases on every ack in this case.
+  for (int i = 0; i < 100; ++i) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
+        initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
+    const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+    // Make sure we are performing cubic increases.
+    ASSERT_EQ(expected_cwnd, next_cwnd);
+    // Make sure that these are non-zero, less-than-packet sized
+    // increases.
+    ASSERT_GT(next_cwnd, current_cwnd);
+    const QuicByteCount cwnd_delta = next_cwnd - current_cwnd;
+    ASSERT_GT(kDefaultTCPMSS * .1, cwnd_delta);
+
+    current_cwnd = next_cwnd;
+  }
+}
+
+// Constructs an artificial scenario to show what happens when we
+// allow per-ack updates, rather than limititing update freqency.  In
+// this scenario, the first two acks of the epoch produce the same
+// cwnd.  When we limit per-ack updates, this would cause the
+// cessation of cubic updates for 30ms.  When we allow per-ack
+// updates, the window continues to grow on every ack.
+TEST_F(CubicBytesTest, PerAckUpdates) {
+  // Start the test with a large cwnd and RTT, to force the first
+  // increase to be a cubic increase.
+  QuicPacketCount initial_cwnd_packets = 150;
+  QuicByteCount current_cwnd = initial_cwnd_packets * kDefaultTCPMSS;
+  const QuicTime::Delta rtt_min = 350 * one_ms_;
+
+  // Initialize the epoch
+  clock_.AdvanceTime(one_ms_);
+  // Keep track of the growth of the reno-equivalent cwnd.
+  QuicByteCount reno_cwnd = RenoCwndInBytes(current_cwnd);
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  const QuicByteCount initial_cwnd = current_cwnd;
+
+  // Simulate the return of cwnd packets in less than
+  // MaxCubicInterval() time.
+  const QuicPacketCount max_acks = initial_cwnd_packets / kNConnectionAlpha;
+  const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
+      MaxCubicTimeInterval().ToMicroseconds() / (max_acks + 1));
+
+  // In this scenario, the first increase is dictated by the cubic
+  // equation, but it is less than one byte, so the cwnd doesn't
+  // change.  Normally, without per-ack increases, any cwnd plateau
+  // will cause the cwnd to be pinned for MaxCubicTimeInterval().  If
+  // we enable per-ack updates, the cwnd will continue to grow,
+  // regardless of the temporary plateau.
+  clock_.AdvanceTime(interval);
+  reno_cwnd = RenoCwndInBytes(reno_cwnd);
+  ASSERT_EQ(current_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+  for (QuicPacketCount i = 1; i < max_acks; ++i) {
+    clock_.AdvanceTime(interval);
+    const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+    reno_cwnd = RenoCwndInBytes(reno_cwnd);
+    // The window shoud increase on every ack.
+    ASSERT_LT(current_cwnd, next_cwnd);
+    ASSERT_EQ(reno_cwnd, next_cwnd);
+    current_cwnd = next_cwnd;
+  }
+
+  // After all the acks are returned from the epoch, we expect the
+  // cwnd to have increased by nearly one packet.  (Not exactly one
+  // packet, because our byte-wise Reno algorithm is always a slight
+  // under-estimation).  Without per-ack updates, the current_cwnd
+  // would otherwise be unchanged.
+  const QuicByteCount minimum_expected_increase = kDefaultTCPMSS * .9;
+  EXPECT_LT(minimum_expected_increase + initial_cwnd, current_cwnd);
+}
+
+TEST_F(CubicBytesTest, LossEvents) {
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
+  // Without the signed-integer, cubic-convex fix, we mistakenly
+  // increment cwnd after only one_ms_ and a single ack.
+  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
+  // Initialize the state.
+  clock_.AdvanceTime(one_ms_);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+
+  // On the first loss, the last max congestion window is set to the
+  // congestion window before the loss.
+  QuicByteCount pre_loss_cwnd = current_cwnd;
+  ASSERT_EQ(0u, LastMaxCongestionWindow());
+  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  ASSERT_EQ(pre_loss_cwnd, LastMaxCongestionWindow());
+  current_cwnd = expected_cwnd;
+
+  // On the second loss, the current congestion window has not yet
+  // reached the last max congestion window.  The last max congestion
+  // window will be reduced by an additional backoff factor to allow
+  // for competition.
+  pre_loss_cwnd = current_cwnd;
+  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
+  ASSERT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  current_cwnd = expected_cwnd;
+  EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow());
+  QuicByteCount expected_last_max =
+      static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax);
+  EXPECT_EQ(expected_last_max, LastMaxCongestionWindow());
+  EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
+  // Simulate an increase, and check that we are below the origin.
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
+
+  // On the final loss, simulate the condition where the congestion
+  // window had a chance to grow nearly to the last congestion window.
+  current_cwnd = LastMaxCongestionWindow() - 1;
+  pre_loss_cwnd = current_cwnd;
+  expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  expected_last_max = pre_loss_cwnd;
+  ASSERT_EQ(expected_last_max, LastMaxCongestionWindow());
+}
+
+TEST_F(CubicBytesTest, BelowOrigin) {
+  // Concave growth.
+  const QuicTime::Delta rtt_min = hundred_ms_;
+  QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
+  // Without the signed-integer, cubic-convex fix, we mistakenly
+  // increment cwnd after only one_ms_ and a single ack.
+  QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
+  // Initialize the state.
+  clock_.AdvanceTime(one_ms_);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd,
+                                            rtt_min, clock_.ApproximateNow()));
+  expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
+  EXPECT_EQ(expected_cwnd,
+            cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+  current_cwnd = expected_cwnd;
+  // First update after loss to initialize the epoch.
+  current_cwnd = cubic_.CongestionWindowAfterAck(
+      kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  // Cubic phase.
+  for (int i = 0; i < 40; ++i) {
+    clock_.AdvanceTime(hundred_ms_);
+    current_cwnd = cubic_.CongestionWindowAfterAck(
+        kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
+  }
+  expected_cwnd = 553632;
+  EXPECT_EQ(expected_cwnd, current_cwnd);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/general_loss_algorithm.cc b/quiche/quic/core/congestion_control/general_loss_algorithm.cc
new file mode 100644
index 0000000..38557a1
--- /dev/null
+++ b/quiche/quic/core/congestion_control/general_loss_algorithm.cc
@@ -0,0 +1,196 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+float DetectionResponseTime(QuicTime::Delta rtt,
+                            QuicTime send_time,
+                            QuicTime detection_time) {
+  if (detection_time <= send_time || rtt.IsZero()) {
+    // Time skewed, assume a very fast detection where |detection_time| is
+    // |send_time| + |rtt|.
+    return 1.0;
+  }
+  float send_to_detection_us = (detection_time - send_time).ToMicroseconds();
+  return send_to_detection_us / rtt.ToMicroseconds();
+}
+
+QuicTime::Delta GetMaxRtt(const RttStats& rtt_stats) {
+  return std::max(kAlarmGranularity,
+                  std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt()));
+}
+
+}  // namespace
+
+// Uses nack counts to decide when packets are lost.
+LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
+    const QuicUnackedPacketMap& unacked_packets,
+    QuicTime time,
+    const RttStats& rtt_stats,
+    QuicPacketNumber largest_newly_acked,
+    const AckedPacketVector& packets_acked,
+    LostPacketVector* packets_lost) {
+  DetectionStats detection_stats;
+
+  loss_detection_timeout_ = QuicTime::Zero();
+  if (!packets_acked.empty() && least_in_flight_.IsInitialized() &&
+      packets_acked.front().packet_number == least_in_flight_) {
+    if (packets_acked.back().packet_number == largest_newly_acked &&
+        least_in_flight_ + packets_acked.size() - 1 == largest_newly_acked) {
+      // Optimization for the case when no packet is missing. Please note,
+      // packets_acked can include packets of different packet number space, so
+      // do not use this optimization if largest_newly_acked is not the largest
+      // packet in packets_acked.
+      least_in_flight_ = largest_newly_acked + 1;
+      return detection_stats;
+    }
+    // There is hole in acked_packets, increment least_in_flight_ if possible.
+    for (const auto& acked : packets_acked) {
+      if (acked.packet_number != least_in_flight_) {
+        break;
+      }
+      ++least_in_flight_;
+    }
+  }
+
+  const QuicTime::Delta max_rtt = GetMaxRtt(rtt_stats);
+
+  QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
+  auto it = unacked_packets.begin();
+  if (least_in_flight_.IsInitialized() && least_in_flight_ >= packet_number) {
+    if (least_in_flight_ > unacked_packets.largest_sent_packet() + 1) {
+      QUIC_BUG(quic_bug_10430_1) << "least_in_flight: " << least_in_flight_
+                                 << " is greater than largest_sent_packet + 1: "
+                                 << unacked_packets.largest_sent_packet() + 1;
+    } else {
+      it += (least_in_flight_ - packet_number);
+      packet_number = least_in_flight_;
+    }
+  }
+  // Clear least_in_flight_.
+  least_in_flight_.Clear();
+  QUICHE_DCHECK_EQ(packet_number_space_,
+                   unacked_packets.GetPacketNumberSpace(largest_newly_acked));
+  for (; it != unacked_packets.end() && packet_number <= largest_newly_acked;
+       ++it, ++packet_number) {
+    if (unacked_packets.GetPacketNumberSpace(it->encryption_level) !=
+        packet_number_space_) {
+      // Skip packets of different packet number space.
+      continue;
+    }
+
+    if (!it->in_flight) {
+      continue;
+    }
+
+    if (parent_ != nullptr && largest_newly_acked != packet_number) {
+      parent_->OnReorderingDetected();
+    }
+
+    if (largest_newly_acked - packet_number >
+        detection_stats.sent_packets_max_sequence_reordering) {
+      detection_stats.sent_packets_max_sequence_reordering =
+          largest_newly_acked - packet_number;
+    }
+
+    // Packet threshold loss detection.
+    // Skip packet threshold loss detection if largest_newly_acked is a runt.
+    const bool skip_packet_threshold_detection =
+        !use_packet_threshold_for_runt_packets_ &&
+        it->bytes_sent >
+            unacked_packets.GetTransmissionInfo(largest_newly_acked).bytes_sent;
+    if (!skip_packet_threshold_detection &&
+        largest_newly_acked - packet_number >= reordering_threshold_) {
+      packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
+      detection_stats.total_loss_detection_response_time +=
+          DetectionResponseTime(max_rtt, it->sent_time, time);
+      continue;
+    }
+
+    // Time threshold loss detection.
+    const QuicTime::Delta loss_delay = max_rtt + (max_rtt >> reordering_shift_);
+    QuicTime when_lost = it->sent_time + loss_delay;
+    if (time < when_lost) {
+      if (time >=
+          it->sent_time + max_rtt + (max_rtt >> (reordering_shift_ + 1))) {
+        ++detection_stats.sent_packets_num_borderline_time_reorderings;
+      }
+      loss_detection_timeout_ = when_lost;
+      if (!least_in_flight_.IsInitialized()) {
+        // At this point, packet_number is in flight and not detected as lost.
+        least_in_flight_ = packet_number;
+      }
+      break;
+    }
+    packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
+    detection_stats.total_loss_detection_response_time +=
+        DetectionResponseTime(max_rtt, it->sent_time, time);
+  }
+  if (!least_in_flight_.IsInitialized()) {
+    // There is no in flight packet.
+    least_in_flight_ = largest_newly_acked + 1;
+  }
+
+  return detection_stats;
+}
+
+QuicTime GeneralLossAlgorithm::GetLossTimeout() const {
+  return loss_detection_timeout_;
+}
+
+void GeneralLossAlgorithm::SpuriousLossDetected(
+    const QuicUnackedPacketMap& unacked_packets,
+    const RttStats& rtt_stats,
+    QuicTime ack_receive_time,
+    QuicPacketNumber packet_number,
+    QuicPacketNumber previous_largest_acked) {
+  if (use_adaptive_time_threshold_ && reordering_shift_ > 0) {
+    // Increase reordering fraction such that the packet would not have been
+    // declared lost.
+    QuicTime::Delta time_needed =
+        ack_receive_time -
+        unacked_packets.GetTransmissionInfo(packet_number).sent_time;
+    QuicTime::Delta max_rtt =
+        std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt());
+    while (max_rtt + (max_rtt >> reordering_shift_) < time_needed &&
+           reordering_shift_ > 0) {
+      --reordering_shift_;
+    }
+  }
+
+  if (use_adaptive_reordering_threshold_) {
+    QUICHE_DCHECK_LT(packet_number, previous_largest_acked);
+    // Increase reordering_threshold_ such that packet_number would not have
+    // been declared lost.
+    reordering_threshold_ = std::max(
+        reordering_threshold_, previous_largest_acked - packet_number + 1);
+  }
+}
+
+void GeneralLossAlgorithm::Initialize(PacketNumberSpace packet_number_space,
+                                      LossDetectionInterface* parent) {
+  parent_ = parent;
+  if (packet_number_space_ < NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10430_2) << "Cannot switch packet_number_space";
+    return;
+  }
+
+  packet_number_space_ = packet_number_space;
+}
+
+void GeneralLossAlgorithm::Reset() {
+  loss_detection_timeout_ = QuicTime::Zero();
+  least_in_flight_.Clear();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/general_loss_algorithm.h b/quiche/quic/core/congestion_control/general_loss_algorithm.h
new file mode 100644
index 0000000..701b2dc
--- /dev/null
+++ b/quiche/quic/core/congestion_control/general_loss_algorithm.h
@@ -0,0 +1,138 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
+
+#include <algorithm>
+#include <map>
+
+#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Class which can be configured to implement's TCP's approach of detecting loss
+// when 3 nacks have been received for a packet or with a time threshold.
+// Also implements TCP's early retransmit(RFC5827).
+class QUIC_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
+ public:
+  GeneralLossAlgorithm() = default;
+  GeneralLossAlgorithm(const GeneralLossAlgorithm&) = delete;
+  GeneralLossAlgorithm& operator=(const GeneralLossAlgorithm&) = delete;
+  ~GeneralLossAlgorithm() override {}
+
+  void SetFromConfig(const QuicConfig& /*config*/,
+                     Perspective /*perspective*/) override {}
+
+  // Uses |largest_acked| and time to decide when packets are lost.
+  DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
+                              QuicTime time,
+                              const RttStats& rtt_stats,
+                              QuicPacketNumber largest_newly_acked,
+                              const AckedPacketVector& packets_acked,
+                              LostPacketVector* packets_lost) override;
+
+  // Returns a non-zero value when the early retransmit timer is active.
+  QuicTime GetLossTimeout() const override;
+
+  // Called to increases time and/or packet threshold.
+  void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
+                            const RttStats& rtt_stats,
+                            QuicTime ack_receive_time,
+                            QuicPacketNumber packet_number,
+                            QuicPacketNumber previous_largest_acked) override;
+
+  void OnConfigNegotiated() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnConfigNegotiated";
+  }
+
+  void OnMinRttAvailable() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnMinRttAvailable";
+  }
+
+  void OnUserAgentIdKnown() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnUserAgentIdKnown";
+  }
+
+  void OnConnectionClosed() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnConnectionClosed";
+  }
+
+  void OnReorderingDetected() override {
+    QUICHE_DCHECK(false)
+        << "Unexpected call to GeneralLossAlgorithm::OnReorderingDetected";
+  }
+
+  void Initialize(PacketNumberSpace packet_number_space,
+                  LossDetectionInterface* parent);
+
+  void Reset();
+
+  QuicPacketCount reordering_threshold() const { return reordering_threshold_; }
+
+  int reordering_shift() const { return reordering_shift_; }
+
+  void set_reordering_shift(int reordering_shift) {
+    reordering_shift_ = reordering_shift;
+  }
+
+  void set_reordering_threshold(QuicPacketCount reordering_threshold) {
+    reordering_threshold_ = reordering_threshold;
+  }
+
+  bool use_adaptive_reordering_threshold() const {
+    return use_adaptive_reordering_threshold_;
+  }
+
+  void set_use_adaptive_reordering_threshold(bool value) {
+    use_adaptive_reordering_threshold_ = value;
+  }
+
+  bool use_adaptive_time_threshold() const {
+    return use_adaptive_time_threshold_;
+  }
+
+  void enable_adaptive_time_threshold() { use_adaptive_time_threshold_ = true; }
+
+  bool use_packet_threshold_for_runt_packets() const {
+    return use_packet_threshold_for_runt_packets_;
+  }
+
+  void disable_packet_threshold_for_runt_packets() {
+    use_packet_threshold_for_runt_packets_ = false;
+  }
+
+ private:
+  LossDetectionInterface* parent_ = nullptr;
+  QuicTime loss_detection_timeout_ = QuicTime::Zero();
+  // Fraction of a max(SRTT, latest_rtt) to permit reordering before declaring
+  // loss.  Fraction calculated by shifting max(SRTT, latest_rtt) to the right
+  // by reordering_shift.
+  int reordering_shift_ = kDefaultLossDelayShift;
+  // Reordering threshold for loss detection.
+  QuicPacketCount reordering_threshold_ = kDefaultPacketReorderingThreshold;
+  // If true, uses adaptive reordering threshold for loss detection.
+  bool use_adaptive_reordering_threshold_ = true;
+  // If true, uses adaptive time threshold for time based loss detection.
+  bool use_adaptive_time_threshold_ = false;
+  // If true, uses packet threshold when largest acked is a runt packet.
+  bool use_packet_threshold_for_runt_packets_ = true;
+  // The least in flight packet. Loss detection should start from this. Please
+  // note, least_in_flight_ could be largest packet ever sent + 1.
+  QuicPacketNumber least_in_flight_{1};
+  PacketNumberSpace packet_number_space_ = NUM_PACKET_NUMBER_SPACES;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_GENERAL_LOSS_ALGORITHM_H_
diff --git a/quiche/quic/core/congestion_control/general_loss_algorithm_test.cc b/quiche/quic/core/congestion_control/general_loss_algorithm_test.cc
new file mode 100644
index 0000000..3b67c65
--- /dev/null
+++ b/quiche/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -0,0 +1,489 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+
+#include <algorithm>
+#include <cstdint>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class GeneralLossAlgorithmTest : public QuicTest {
+ protected:
+  GeneralLossAlgorithmTest() : unacked_packets_(Perspective::IS_CLIENT) {
+    rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                         QuicTime::Delta::Zero(), clock_.Now());
+    EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
+    loss_algorithm_.Initialize(HANDSHAKE_DATA, nullptr);
+  }
+
+  ~GeneralLossAlgorithmTest() override {}
+
+  void SendDataPacket(uint64_t packet_number,
+                      QuicPacketLength encrypted_length) {
+    QuicStreamFrame frame;
+    frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        CurrentSupportedVersions()[0].transport_version,
+        Perspective::IS_CLIENT);
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr,
+                            encrypted_length, false, false);
+    packet.retransmittable_frames.push_back(QuicFrame(frame));
+    unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
+                                   true, true);
+  }
+
+  void SendDataPacket(uint64_t packet_number) {
+    SendDataPacket(packet_number, kDefaultLength);
+  }
+
+  void SendAckPacket(uint64_t packet_number) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            true, false);
+    unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
+                                   false, true);
+  }
+
+  void VerifyLosses(uint64_t largest_newly_acked,
+                    const AckedPacketVector& packets_acked,
+                    const std::vector<uint64_t>& losses_expected) {
+    return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
+                        absl::nullopt, absl::nullopt);
+  }
+
+  void VerifyLosses(
+      uint64_t largest_newly_acked,
+      const AckedPacketVector& packets_acked,
+      const std::vector<uint64_t>& losses_expected,
+      absl::optional<QuicPacketCount> max_sequence_reordering_expected,
+      absl::optional<QuicPacketCount>
+          num_borderline_time_reorderings_expected) {
+    unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+        APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
+    LostPacketVector lost_packets;
+    LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
+        unacked_packets_, clock_.Now(), rtt_stats_,
+        QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
+    if (max_sequence_reordering_expected.has_value()) {
+      EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
+                max_sequence_reordering_expected.value());
+    }
+    if (num_borderline_time_reorderings_expected.has_value()) {
+      EXPECT_EQ(stats.sent_packets_num_borderline_time_reorderings,
+                num_borderline_time_reorderings_expected.value());
+    }
+    ASSERT_EQ(losses_expected.size(), lost_packets.size());
+    for (size_t i = 0; i < losses_expected.size(); ++i) {
+      EXPECT_EQ(lost_packets[i].packet_number,
+                QuicPacketNumber(losses_expected[i]));
+    }
+  }
+
+  QuicUnackedPacketMap unacked_packets_;
+  GeneralLossAlgorithm loss_algorithm_;
+  RttStats rtt_stats_;
+  MockClock clock_;
+};
+
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
+  const size_t kNumSentPackets = 5;
+  // Transmit 5 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // No loss on one ack.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1, 0);
+  packets_acked.clear();
+  // No loss on two acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2, 0);
+  packets_acked.clear();
+  // Loss on three acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1}, 3, 0);
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+// A stretch ack is an ack that covers more than 1 packet of previously
+// unacknowledged data.
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
+  const size_t kNumSentPackets = 10;
+  // Transmit 10 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Nack the first packet 3 times in a single StretchAck.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+// Ack a packet 3 packets ahead, causing a retransmit.
+TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
+  const size_t kNumSentPackets = 10;
+  // Transmit 10 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Nack the first packet 3 times in an AckFrame with three missing packets.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1});
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
+  const size_t kNumSentPackets = 2;
+  // Transmit 2 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Early retransmit when the final packet gets acked and the first is nacked.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  clock_.AdvanceTime(1.13 * rtt_stats_.latest_rtt());
+  // If reordering_shift increases by one we should have detected a loss.
+  VerifyLosses(2, packets_acked, {}, /*max_sequence_reordering_expected=*/1,
+               /*num_borderline_time_reorderings_expected=*/1);
+
+  clock_.AdvanceTime(0.13 * rtt_stats_.latest_rtt());
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
+  const size_t kNumSentPackets = 5;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+    // Advance the time 1/4 RTT between 3 and 4.
+    if (i == 3) {
+      clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
+    }
+  }
+  AckedPacketVector packets_acked;
+  // Early retransmit when the final packet gets acked and 1.25 RTTs have
+  // elapsed since the packets were sent.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
+  packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
+                                      kMaxOutgoingPacketSize,
+                                      QuicTime::Zero()));
+  // This simulates a single ack following multiple missing packets with FACK.
+  VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
+  packets_acked.clear();
+  // The time has already advanced 1/4 an RTT, so ensure the timeout is set
+  // 1.25 RTTs after the earliest pending packet(3), not the last(4).
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+  VerifyLosses(kNumSentPackets, packets_acked, {3});
+  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
+  VerifyLosses(kNumSentPackets, packets_acked, {4});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
+  const size_t kNumSentPackets = 2;
+  // Transmit 2 packets.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  AckedPacketVector packets_acked;
+  // Neuter packet 1.
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+
+  // Early retransmit when the final packet gets acked and the first is nacked.
+  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) {
+  // Transmit 2 data packets and one ack.
+  SendDataPacket(1);
+  SendDataPacket(2);
+  SendAckPacket(3);
+  AckedPacketVector packets_acked;
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+
+  // Early retransmit when the final packet gets acked and the first is nacked.
+  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  // The packet should be lost once the loss timeout is reached.
+  clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt());
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
+  // Transmit 1 packet and then wait an rtt plus 1ms.
+  SendDataPacket(1);
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     QuicTime::Delta::FromMilliseconds(1));
+
+  // Transmit 2 packets.
+  SendDataPacket(2);
+  SendDataPacket(3);
+  AckedPacketVector packets_acked;
+  // Wait another RTT and ack 2.
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
+  unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, {1});
+}
+
+TEST_F(GeneralLossAlgorithmTest, IncreaseTimeThresholdUponSpuriousLoss) {
+  loss_algorithm_.enable_adaptive_time_threshold();
+  loss_algorithm_.set_reordering_shift(kDefaultLossDelayShift);
+  EXPECT_EQ(kDefaultLossDelayShift, loss_algorithm_.reordering_shift());
+  EXPECT_TRUE(loss_algorithm_.use_adaptive_time_threshold());
+  const size_t kNumSentPackets = 10;
+  // Transmit 2 packets at 1/10th an RTT interval.
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+    clock_.AdvanceTime(0.1 * rtt_stats_.smoothed_rtt());
+  }
+  EXPECT_EQ(QuicTime::Zero() + rtt_stats_.smoothed_rtt(), clock_.Now());
+  AckedPacketVector packets_acked;
+  // Expect the timer to not be set.
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+  // Packet 1 should not be lost until 1/4 RTTs pass.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  // Expect the timer to be set to 1/4 RTT's in the future.
+  EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 4),
+            loss_algorithm_.GetLossTimeout() - clock_.Now());
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+  // Retransmit packet 1 as 11 and 2 as 12.
+  SendDataPacket(11);
+  SendDataPacket(12);
+
+  // Advance the time 1/4 RTT and indicate the loss was spurious.
+  // The new threshold should be 1/2 RTT.
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
+  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                       clock_.Now(), QuicPacketNumber(1),
+                                       QuicPacketNumber(2));
+  EXPECT_EQ(1, loss_algorithm_.reordering_shift());
+}
+
+TEST_F(GeneralLossAlgorithmTest, IncreaseReorderingThresholdUponSpuriousLoss) {
+  loss_algorithm_.set_use_adaptive_reordering_threshold(true);
+  for (size_t i = 1; i <= 4; ++i) {
+    SendDataPacket(i);
+  }
+  // Acking 4 causes 1 detected lost.
+  AckedPacketVector packets_acked;
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, std::vector<uint64_t>{1});
+  packets_acked.clear();
+
+  // Retransmit 1 as 5.
+  SendDataPacket(5);
+
+  // Acking 1 such that it was detected lost spuriously.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(1), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                       clock_.Now(), QuicPacketNumber(1),
+                                       QuicPacketNumber(4));
+  VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+
+  // Verify acking 5 does not cause 2 detected lost.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(5), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(5, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+
+  SendDataPacket(6);
+
+  // Acking 6 will causes 2 detected lost.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(6, packets_acked, std::vector<uint64_t>{2});
+  packets_acked.clear();
+
+  // Retransmit 2 as 7.
+  SendDataPacket(7);
+
+  // Acking 2 such that it was detected lost spuriously.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                       clock_.Now(), QuicPacketNumber(2),
+                                       QuicPacketNumber(6));
+  VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+
+  // Acking 7 will not cause 3 as detected lost.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+}
+
+TEST_F(GeneralLossAlgorithmTest, DefaultIetfLossDetection) {
+  loss_algorithm_.set_reordering_shift(kDefaultIetfLossDelayShift);
+  for (size_t i = 1; i <= 6; ++i) {
+    SendDataPacket(i);
+  }
+  // Packet threshold loss detection.
+  AckedPacketVector packets_acked;
+  // No loss on one ack.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  // No loss on two acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  // Loss on three acks.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+  packets_acked.clear();
+
+  SendDataPacket(7);
+
+  // Time threshold loss detection.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
+                (rtt_stats_.smoothed_rtt() >> 3),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     (rtt_stats_.smoothed_rtt() >> 3));
+  VerifyLosses(6, packets_acked, {5});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, IetfLossDetectionWithOneFourthRttDelay) {
+  loss_algorithm_.set_reordering_shift(2);
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  AckedPacketVector packets_acked;
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
+  packets_acked.clear();
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
+                (rtt_stats_.smoothed_rtt() >> 2),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     (rtt_stats_.smoothed_rtt() >> 2));
+  VerifyLosses(2, packets_acked, {1});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(GeneralLossAlgorithmTest, NoPacketThresholdForRuntPackets) {
+  loss_algorithm_.disable_packet_threshold_for_runt_packets();
+  for (size_t i = 1; i <= 6; ++i) {
+    SendDataPacket(i);
+  }
+  // Send a small packet.
+  SendDataPacket(7, /*encrypted_length=*/kDefaultLength / 2);
+  // No packet threshold for runt packet.
+  AckedPacketVector packets_acked;
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
+  packets_acked.push_back(AckedPacket(
+      QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
+  // Verify no packet is detected lost because packet 7 is a runt.
+  VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
+  EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
+                (rtt_stats_.smoothed_rtt() >> 2),
+            loss_algorithm_.GetLossTimeout());
+  clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
+                     (rtt_stats_.smoothed_rtt() >> 2));
+  // Verify packets are declared lost because time threshold has passed.
+  VerifyLosses(7, packets_acked, {1, 2, 3, 4, 5, 6});
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/hybrid_slow_start.cc b/quiche/quic/core/congestion_control/hybrid_slow_start.cc
new file mode 100644
index 0000000..1eb9944
--- /dev/null
+++ b/quiche/quic/core/congestion_control/hybrid_slow_start.cc
@@ -0,0 +1,104 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/hybrid_slow_start.h"
+
+#include <algorithm>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// Note(pwestin): the magic clamping numbers come from the original code in
+// tcp_cubic.c.
+const int64_t kHybridStartLowWindow = 16;
+// Number of delay samples for detecting the increase of delay.
+const uint32_t kHybridStartMinSamples = 8;
+// Exit slow start if the min rtt has increased by more than 1/8th.
+const int kHybridStartDelayFactorExp = 3;  // 2^3 = 8
+// The original paper specifies 2 and 8ms, but those have changed over time.
+const int64_t kHybridStartDelayMinThresholdUs = 4000;
+const int64_t kHybridStartDelayMaxThresholdUs = 16000;
+
+HybridSlowStart::HybridSlowStart()
+    : started_(false),
+      hystart_found_(NOT_FOUND),
+      rtt_sample_count_(0),
+      current_min_rtt_(QuicTime::Delta::Zero()) {}
+
+void HybridSlowStart::OnPacketAcked(QuicPacketNumber acked_packet_number) {
+  // OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end
+  // the round when the final packet of the burst is received and start it on
+  // the next incoming ack.
+  if (IsEndOfRound(acked_packet_number)) {
+    started_ = false;
+  }
+}
+
+void HybridSlowStart::OnPacketSent(QuicPacketNumber packet_number) {
+  last_sent_packet_number_ = packet_number;
+}
+
+void HybridSlowStart::Restart() {
+  started_ = false;
+  hystart_found_ = NOT_FOUND;
+}
+
+void HybridSlowStart::StartReceiveRound(QuicPacketNumber last_sent) {
+  QUIC_DVLOG(1) << "Reset hybrid slow start @" << last_sent;
+  end_packet_number_ = last_sent;
+  current_min_rtt_ = QuicTime::Delta::Zero();
+  rtt_sample_count_ = 0;
+  started_ = true;
+}
+
+bool HybridSlowStart::IsEndOfRound(QuicPacketNumber ack) const {
+  return !end_packet_number_.IsInitialized() || end_packet_number_ <= ack;
+}
+
+bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
+                                          QuicTime::Delta min_rtt,
+                                          QuicPacketCount congestion_window) {
+  if (!started_) {
+    // Time to start the hybrid slow start.
+    StartReceiveRound(last_sent_packet_number_);
+  }
+  if (hystart_found_ != NOT_FOUND) {
+    return true;
+  }
+  // Second detection parameter - delay increase detection.
+  // Compare the minimum delay (current_min_rtt_) of the current
+  // burst of packets relative to the minimum delay during the session.
+  // Note: we only look at the first few(8) packets in each burst, since we
+  // only want to compare the lowest RTT of the burst relative to previous
+  // bursts.
+  rtt_sample_count_++;
+  if (rtt_sample_count_ <= kHybridStartMinSamples) {
+    if (current_min_rtt_.IsZero() || current_min_rtt_ > latest_rtt) {
+      current_min_rtt_ = latest_rtt;
+    }
+  }
+  // We only need to check this once per round.
+  if (rtt_sample_count_ == kHybridStartMinSamples) {
+    // Divide min_rtt by 8 to get a rtt increase threshold for exiting.
+    int64_t min_rtt_increase_threshold_us =
+        min_rtt.ToMicroseconds() >> kHybridStartDelayFactorExp;
+    // Ensure the rtt threshold is never less than 2ms or more than 16ms.
+    min_rtt_increase_threshold_us = std::min(min_rtt_increase_threshold_us,
+                                             kHybridStartDelayMaxThresholdUs);
+    QuicTime::Delta min_rtt_increase_threshold =
+        QuicTime::Delta::FromMicroseconds(std::max(
+            min_rtt_increase_threshold_us, kHybridStartDelayMinThresholdUs));
+
+    if (current_min_rtt_ > min_rtt + min_rtt_increase_threshold) {
+      hystart_found_ = DELAY;
+    }
+  }
+  // Exit from slow start if the cwnd is greater than 16 and
+  // increasing delay is found.
+  return congestion_window >= kHybridStartLowWindow &&
+         hystart_found_ != NOT_FOUND;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/hybrid_slow_start.h b/quiche/quic/core/congestion_control/hybrid_slow_start.h
new file mode 100644
index 0000000..9ea130c
--- /dev/null
+++ b/quiche/quic/core/congestion_control/hybrid_slow_start.h
@@ -0,0 +1,83 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This class is a helper class to TcpCubicSender.
+// Slow start is the initial startup phase of TCP, it lasts until first packet
+// loss. This class implements hybrid slow start of the TCP cubic send side
+// congestion algorithm. The key feaure of hybrid slow start is that it tries to
+// avoid running into the wall too hard during the slow start phase, which
+// the traditional TCP implementation does.
+// This does not implement ack train detection because it interacts poorly with
+// pacing.
+// http://netsrv.csc.ncsu.edu/export/hybridstart_pfldnet08.pdf
+// http://research.csc.ncsu.edu/netsrv/sites/default/files/hystart_techreport_2008.pdf
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE HybridSlowStart {
+ public:
+  HybridSlowStart();
+  HybridSlowStart(const HybridSlowStart&) = delete;
+  HybridSlowStart& operator=(const HybridSlowStart&) = delete;
+
+  void OnPacketAcked(QuicPacketNumber acked_packet_number);
+
+  void OnPacketSent(QuicPacketNumber packet_number);
+
+  // ShouldExitSlowStart should be called on every new ack frame, since a new
+  // RTT measurement can be made then.
+  // rtt: the RTT for this ack packet.
+  // min_rtt: is the lowest delay (RTT) we have seen during the session.
+  // congestion_window: the congestion window in packets.
+  bool ShouldExitSlowStart(QuicTime::Delta rtt,
+                           QuicTime::Delta min_rtt,
+                           QuicPacketCount congestion_window);
+
+  // Start a new slow start phase.
+  void Restart();
+
+  // TODO(ianswett): The following methods should be private, but that requires
+  // a follow up CL to update the unit test.
+  // Returns true if this ack the last packet number of our current slow start
+  // round.
+  // Call Reset if this returns true.
+  bool IsEndOfRound(QuicPacketNumber ack) const;
+
+  // Call for the start of each receive round (burst) in the slow start phase.
+  void StartReceiveRound(QuicPacketNumber last_sent);
+
+  // Whether slow start has started.
+  bool started() const { return started_; }
+
+ private:
+  // Whether a condition for exiting slow start has been found.
+  enum HystartState {
+    NOT_FOUND,
+    DELAY,  // Too much increase in the round's min_rtt was observed.
+  };
+
+  // Whether the hybrid slow start has been started.
+  bool started_;
+  HystartState hystart_found_;
+  // Last packet number sent which was CWND limited.
+  QuicPacketNumber last_sent_packet_number_;
+
+  // Variables for tracking acks received during a slow start round.
+  QuicPacketNumber end_packet_number_;  // End of the receive round.
+  uint32_t rtt_sample_count_;  // Number of rtt samples in the current round.
+  QuicTime::Delta current_min_rtt_;  // The minimum rtt of current round.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_HYBRID_SLOW_START_H_
diff --git a/quiche/quic/core/congestion_control/hybrid_slow_start_test.cc b/quiche/quic/core/congestion_control/hybrid_slow_start_test.cc
new file mode 100644
index 0000000..94654fc
--- /dev/null
+++ b/quiche/quic/core/congestion_control/hybrid_slow_start_test.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/hybrid_slow_start.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class HybridSlowStartTest : public QuicTest {
+ protected:
+  HybridSlowStartTest()
+      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+        rtt_(QuicTime::Delta::FromMilliseconds(60)) {}
+  void SetUp() override { slow_start_ = std::make_unique<HybridSlowStart>(); }
+  const QuicTime::Delta one_ms_;
+  const QuicTime::Delta rtt_;
+  std::unique_ptr<HybridSlowStart> slow_start_;
+};
+
+TEST_F(HybridSlowStartTest, Simple) {
+  QuicPacketNumber packet_number(1);
+  QuicPacketNumber end_packet_number(3);
+  slow_start_->StartReceiveRound(end_packet_number);
+
+  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
+
+  // Test duplicates.
+  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number));
+
+  EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
+  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
+
+  // Test without a new registered end_packet_number;
+  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
+
+  end_packet_number = QuicPacketNumber(20);
+  slow_start_->StartReceiveRound(end_packet_number);
+  while (packet_number < end_packet_number) {
+    EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
+  }
+  EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
+}
+
+TEST_F(HybridSlowStartTest, Delay) {
+  // We expect to detect the increase at +1/8 of the RTT; hence at a typical
+  // RTT of 60ms the detection will happen at 67.5 ms.
+  const int kHybridStartMinSamples = 8;  // Number of acks required to trigger.
+
+  QuicPacketNumber end_packet_number(1);
+  slow_start_->StartReceiveRound(end_packet_number++);
+
+  // Will not trigger since our lowest RTT in our burst is the same as the long
+  // term RTT provided.
+  for (int n = 0; n < kHybridStartMinSamples; ++n) {
+    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
+        rtt_ + QuicTime::Delta::FromMilliseconds(n), rtt_, 100));
+  }
+  slow_start_->StartReceiveRound(end_packet_number++);
+  for (int n = 1; n < kHybridStartMinSamples; ++n) {
+    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(
+        rtt_ + QuicTime::Delta::FromMilliseconds(n + 10), rtt_, 100));
+  }
+  // Expect to trigger since all packets in this burst was above the long term
+  // RTT provided.
+  EXPECT_TRUE(slow_start_->ShouldExitSlowStart(
+      rtt_ + QuicTime::Delta::FromMilliseconds(10), rtt_, 100));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/loss_detection_interface.h b/quiche/quic/core/congestion_control/loss_detection_interface.h
new file mode 100644
index 0000000..76aa2df
--- /dev/null
+++ b/quiche/quic/core/congestion_control/loss_detection_interface.h
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The pure virtual class for send side loss detection algorithm.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicUnackedPacketMap;
+class RttStats;
+
+class QUIC_EXPORT_PRIVATE LossDetectionInterface {
+ public:
+  virtual ~LossDetectionInterface() {}
+
+  virtual void SetFromConfig(const QuicConfig& config,
+                             Perspective perspective) = 0;
+
+  struct QUIC_NO_EXPORT DetectionStats {
+    // Maximum sequence reordering observed in newly acked packets.
+    QuicPacketCount sent_packets_max_sequence_reordering = 0;
+    QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
+    // Total detection response time for lost packets from this detection.
+    // See QuicConnectionStats for the definition of detection response time.
+    float total_loss_detection_response_time = 0.0;
+  };
+
+  // Called when a new ack arrives or the loss alarm fires.
+  virtual DetectionStats DetectLosses(
+      const QuicUnackedPacketMap& unacked_packets,
+      QuicTime time,
+      const RttStats& rtt_stats,
+      QuicPacketNumber largest_newly_acked,
+      const AckedPacketVector& packets_acked,
+      LostPacketVector* packets_lost) = 0;
+
+  // Get the time the LossDetectionAlgorithm wants to re-evaluate losses.
+  // Returns QuicTime::Zero if no alarm needs to be set.
+  virtual QuicTime GetLossTimeout() const = 0;
+
+  // Called when |packet_number| was detected lost but gets acked later.
+  virtual void SpuriousLossDetected(
+      const QuicUnackedPacketMap& unacked_packets,
+      const RttStats& rtt_stats,
+      QuicTime ack_receive_time,
+      QuicPacketNumber packet_number,
+      QuicPacketNumber previous_largest_acked) = 0;
+
+  virtual void OnConfigNegotiated() = 0;
+
+  virtual void OnMinRttAvailable() = 0;
+
+  virtual void OnUserAgentIdKnown() = 0;
+
+  virtual void OnConnectionClosed() = 0;
+
+  // Called when a reordering is detected by the loss algorithm, but _before_
+  // the reordering_shift and reordering_threshold are consulted to see whether
+  // it is a loss.
+  virtual void OnReorderingDetected() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
diff --git a/quiche/quic/core/congestion_control/pacing_sender.cc b/quiche/quic/core/congestion_control/pacing_sender.cc
new file mode 100644
index 0000000..9eede85
--- /dev/null
+++ b/quiche/quic/core/congestion_control/pacing_sender.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/pacing_sender.h"
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+
+// Configured maximum size of the burst coming out of quiescence.  The burst
+// is never larger than the current CWND in packets.
+static const uint32_t kInitialUnpacedBurst = 10;
+
+}  // namespace
+
+PacingSender::PacingSender()
+    : sender_(nullptr),
+      max_pacing_rate_(QuicBandwidth::Zero()),
+      burst_tokens_(kInitialUnpacedBurst),
+      ideal_next_packet_send_time_(QuicTime::Zero()),
+      initial_burst_size_(kInitialUnpacedBurst),
+      lumpy_tokens_(0),
+      alarm_granularity_(kAlarmGranularity),
+      pacing_limited_(false) {
+  if (GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_donot_reset_ideal_next_packet_send_time);
+  }
+}
+
+PacingSender::~PacingSender() {}
+
+void PacingSender::set_sender(SendAlgorithmInterface* sender) {
+  QUICHE_DCHECK(sender != nullptr);
+  sender_ = sender;
+}
+
+void PacingSender::OnCongestionEvent(bool rtt_updated,
+                                     QuicByteCount bytes_in_flight,
+                                     QuicTime event_time,
+                                     const AckedPacketVector& acked_packets,
+                                     const LostPacketVector& lost_packets) {
+  QUICHE_DCHECK(sender_ != nullptr);
+  if (!lost_packets.empty()) {
+    // Clear any burst tokens when entering recovery.
+    burst_tokens_ = 0;
+  }
+  sender_->OnCongestionEvent(rtt_updated, bytes_in_flight, event_time,
+                             acked_packets, lost_packets);
+}
+
+void PacingSender::OnPacketSent(
+    QuicTime sent_time,
+    QuicByteCount bytes_in_flight,
+    QuicPacketNumber packet_number,
+    QuicByteCount bytes,
+    HasRetransmittableData has_retransmittable_data) {
+  QUICHE_DCHECK(sender_ != nullptr);
+  sender_->OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
+                        has_retransmittable_data);
+  if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
+    return;
+  }
+  // If in recovery, the connection is not coming out of quiescence.
+  if (bytes_in_flight == 0 && !sender_->InRecovery()) {
+    // Add more burst tokens anytime the connection is leaving quiescence, but
+    // limit it to the equivalent of a single bulk write, not exceeding the
+    // current CWND in packets.
+    burst_tokens_ = std::min(
+        initial_burst_size_,
+        static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
+  }
+  if (burst_tokens_ > 0) {
+    --burst_tokens_;
+    if (!GetQuicReloadableFlag(quic_donot_reset_ideal_next_packet_send_time)) {
+      ideal_next_packet_send_time_ = QuicTime::Zero();
+    }
+    pacing_limited_ = false;
+    return;
+  }
+  // The next packet should be sent as soon as the current packet has been
+  // transferred.  PacingRate is based on bytes in flight including this packet.
+  QuicTime::Delta delay =
+      PacingRate(bytes_in_flight + bytes).TransferTime(bytes);
+  if (!pacing_limited_ || lumpy_tokens_ == 0) {
+    // Reset lumpy_tokens_ if either application or cwnd throttles sending or
+    // token runs out.
+    lumpy_tokens_ = std::max(
+        1u, std::min(static_cast<uint32_t>(
+                         GetQuicFlag(FLAGS_quic_lumpy_pacing_size)),
+                     static_cast<uint32_t>(
+                         (sender_->GetCongestionWindow() *
+                          GetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction)) /
+                         kDefaultTCPMSS)));
+    if (sender_->BandwidthEstimate() <
+        QuicBandwidth::FromKBitsPerSecond(
+            GetQuicFlag(FLAGS_quic_lumpy_pacing_min_bandwidth_kbps))) {
+      // Below 1.2Mbps, send 1 packet at once, because one full-sized packet
+      // is about 10ms of queueing.
+      lumpy_tokens_ = 1u;
+    }
+    if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts) &&
+        (bytes_in_flight + bytes) >= sender_->GetCongestionWindow()) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_fix_pacing_sender_bursts);
+      // Don't add lumpy_tokens if the congestion controller is CWND limited.
+      lumpy_tokens_ = 1u;
+    }
+  }
+  --lumpy_tokens_;
+  if (pacing_limited_) {
+    // Make up for lost time since pacing throttles the sending.
+    ideal_next_packet_send_time_ = ideal_next_packet_send_time_ + delay;
+  } else {
+    ideal_next_packet_send_time_ =
+        std::max(ideal_next_packet_send_time_ + delay, sent_time + delay);
+  }
+  // Stop making up for lost time if underlying sender prevents sending.
+  pacing_limited_ = sender_->CanSend(bytes_in_flight + bytes);
+}
+
+void PacingSender::OnApplicationLimited() {
+  // The send is application limited, stop making up for lost time.
+  pacing_limited_ = false;
+}
+
+void PacingSender::SetBurstTokens(uint32_t burst_tokens) {
+  initial_burst_size_ = burst_tokens;
+  burst_tokens_ = std::min(
+      initial_burst_size_,
+      static_cast<uint32_t>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
+}
+
+QuicTime::Delta PacingSender::TimeUntilSend(
+    QuicTime now,
+    QuicByteCount bytes_in_flight) const {
+  QUICHE_DCHECK(sender_ != nullptr);
+
+  if (!sender_->CanSend(bytes_in_flight)) {
+    // The underlying sender prevents sending.
+    return QuicTime::Delta::Infinite();
+  }
+
+  if (burst_tokens_ > 0 || bytes_in_flight == 0 || lumpy_tokens_ > 0) {
+    // Don't pace if we have burst tokens available or leaving quiescence.
+    QUIC_DVLOG(1) << "Sending packet now. burst_tokens:" << burst_tokens_
+                  << ", bytes_in_flight:" << bytes_in_flight
+                  << ", lumpy_tokens:" << lumpy_tokens_;
+    return QuicTime::Delta::Zero();
+  }
+
+  // If the next send time is within the alarm granularity, send immediately.
+  if (ideal_next_packet_send_time_ > now + alarm_granularity_) {
+    QUIC_DVLOG(1) << "Delaying packet: "
+                  << (ideal_next_packet_send_time_ - now).ToMicroseconds();
+    return ideal_next_packet_send_time_ - now;
+  }
+
+  QUIC_DVLOG(1) << "Sending packet now. ideal_next_packet_send_time: "
+                << ideal_next_packet_send_time_ << ", now: " << now;
+  return QuicTime::Delta::Zero();
+}
+
+QuicBandwidth PacingSender::PacingRate(QuicByteCount bytes_in_flight) const {
+  QUICHE_DCHECK(sender_ != nullptr);
+  if (!max_pacing_rate_.IsZero()) {
+    return QuicBandwidth::FromBitsPerSecond(
+        std::min(max_pacing_rate_.ToBitsPerSecond(),
+                 sender_->PacingRate(bytes_in_flight).ToBitsPerSecond()));
+  }
+  return sender_->PacingRate(bytes_in_flight);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/pacing_sender.h b/quiche/quic/core/congestion_control/pacing_sender.h
new file mode 100644
index 0000000..c7be125
--- /dev/null
+++ b/quiche/quic/core/congestion_control/pacing_sender.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A send algorithm that adds pacing on top of an another send algorithm.
+// It uses the underlying sender's pacing rate to schedule packets.
+// It also takes into consideration the expected granularity of the underlying
+// alarm to ensure that alarms are not set too aggressively, and err towards
+// sending packets too early instead of too late.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicSentPacketManagerPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE PacingSender {
+ public:
+  PacingSender();
+  PacingSender(const PacingSender&) = delete;
+  PacingSender& operator=(const PacingSender&) = delete;
+  ~PacingSender();
+
+  // Sets the underlying sender. Does not take ownership of |sender|. |sender|
+  // must not be null. This must be called before any of the
+  // SendAlgorithmInterface wrapper methods are called.
+  void set_sender(SendAlgorithmInterface* sender);
+
+  void set_max_pacing_rate(QuicBandwidth max_pacing_rate) {
+    max_pacing_rate_ = max_pacing_rate;
+  }
+
+  void set_alarm_granularity(QuicTime::Delta alarm_granularity) {
+    alarm_granularity_ = alarm_granularity;
+  }
+
+  QuicBandwidth max_pacing_rate() const { return max_pacing_rate_; }
+
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount bytes_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets);
+
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData has_retransmittable_data);
+
+  // Called when application throttles the sending, so that pacing sender stops
+  // making up for lost time.
+  void OnApplicationLimited();
+
+  // Set burst_tokens_ and initial_burst_size_.
+  void SetBurstTokens(uint32_t burst_tokens);
+
+  QuicTime::Delta TimeUntilSend(QuicTime now,
+                                QuicByteCount bytes_in_flight) const;
+
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const;
+
+  NextReleaseTimeResult GetNextReleaseTime() const {
+    bool allow_burst = (burst_tokens_ > 0 || lumpy_tokens_ > 0);
+    return {ideal_next_packet_send_time_, allow_burst};
+  }
+
+  uint32_t initial_burst_size() const { return initial_burst_size_; }
+
+ protected:
+  uint32_t lumpy_tokens() const { return lumpy_tokens_; }
+
+ private:
+  friend class test::QuicSentPacketManagerPeer;
+
+  // Underlying sender. Not owned.
+  SendAlgorithmInterface* sender_;
+  // If not QuicBandidth::Zero, the maximum rate the PacingSender will use.
+  QuicBandwidth max_pacing_rate_;
+
+  // Number of unpaced packets to be sent before packets are delayed.
+  uint32_t burst_tokens_;
+  QuicTime ideal_next_packet_send_time_;  // When can the next packet be sent.
+  uint32_t initial_burst_size_;
+
+  // Number of unpaced packets to be sent before packets are delayed. This token
+  // is consumed after burst_tokens_ ran out.
+  uint32_t lumpy_tokens_;
+
+  // If the next send time is within alarm_granularity_, send immediately.
+  // TODO(fayang): Remove alarm_granularity_ when deprecating
+  // quic_offload_pacing_to_usps2 flag.
+  QuicTime::Delta alarm_granularity_;
+
+  // Indicates whether pacing throttles the sending. If true, make up for lost
+  // time.
+  bool pacing_limited_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/pacing_sender_test.cc b/quiche/quic/core/congestion_control/pacing_sender_test.cc
new file mode 100644
index 0000000..9e28c75
--- /dev/null
+++ b/quiche/quic/core/congestion_control/pacing_sender_test.cc
@@ -0,0 +1,597 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/pacing_sender.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::AtMost;
+using testing::IsEmpty;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+const QuicByteCount kBytesInFlight = 1024;
+const int kInitialBurstPackets = 10;
+
+class TestPacingSender : public PacingSender {
+ public:
+  using PacingSender::lumpy_tokens;
+  using PacingSender::PacingSender;
+
+  QuicTime ideal_next_packet_send_time() const {
+    return GetNextReleaseTime().release_time;
+  }
+};
+
+class PacingSenderTest : public QuicTest {
+ protected:
+  PacingSenderTest()
+      : zero_time_(QuicTime::Delta::Zero()),
+        infinite_time_(QuicTime::Delta::Infinite()),
+        packet_number_(1),
+        mock_sender_(new StrictMock<MockSendAlgorithm>()),
+        pacing_sender_(new TestPacingSender) {
+    pacing_sender_->set_sender(mock_sender_.get());
+    // Pick arbitrary time.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(9));
+  }
+
+  ~PacingSenderTest() override {}
+
+  void InitPacingRate(QuicPacketCount burst_size, QuicBandwidth bandwidth) {
+    mock_sender_ = std::make_unique<StrictMock<MockSendAlgorithm>>();
+    pacing_sender_ = std::make_unique<TestPacingSender>();
+    pacing_sender_->set_sender(mock_sender_.get());
+    EXPECT_CALL(*mock_sender_, PacingRate(_)).WillRepeatedly(Return(bandwidth));
+    EXPECT_CALL(*mock_sender_, BandwidthEstimate())
+        .WillRepeatedly(Return(bandwidth));
+    if (burst_size == 0) {
+      EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _));
+      LostPacketVector lost_packets;
+      lost_packets.push_back(
+          LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+      AckedPacketVector empty;
+      pacing_sender_->OnCongestionEvent(true, 1234, clock_.Now(), empty,
+                                        lost_packets);
+    } else if (burst_size != kInitialBurstPackets) {
+      QUIC_LOG(FATAL) << "Unsupported burst_size " << burst_size
+                      << " specificied, only 0 and " << kInitialBurstPackets
+                      << " are supported.";
+    }
+  }
+
+  void CheckPacketIsSentImmediately(HasRetransmittableData retransmittable_data,
+                                    QuicByteCount prior_in_flight,
+                                    bool in_recovery,
+                                    QuicPacketCount cwnd) {
+    // In order for the packet to be sendable, the underlying sender must
+    // permit it to be sent immediately.
+    for (int i = 0; i < 2; ++i) {
+      EXPECT_CALL(*mock_sender_, CanSend(prior_in_flight))
+          .WillOnce(Return(true));
+      // Verify that the packet can be sent immediately.
+      EXPECT_EQ(zero_time_,
+                pacing_sender_->TimeUntilSend(clock_.Now(), prior_in_flight));
+    }
+
+    // Actually send the packet.
+    if (prior_in_flight == 0) {
+      EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(in_recovery));
+    }
+    EXPECT_CALL(*mock_sender_,
+                OnPacketSent(clock_.Now(), prior_in_flight, packet_number_,
+                             kMaxOutgoingPacketSize, retransmittable_data));
+    EXPECT_CALL(*mock_sender_, GetCongestionWindow())
+        .WillRepeatedly(Return(cwnd * kDefaultTCPMSS));
+    EXPECT_CALL(*mock_sender_,
+                CanSend(prior_in_flight + kMaxOutgoingPacketSize))
+        .Times(AtMost(1))
+        .WillRepeatedly(Return((prior_in_flight + kMaxOutgoingPacketSize) <
+                               (cwnd * kDefaultTCPMSS)));
+    pacing_sender_->OnPacketSent(clock_.Now(), prior_in_flight,
+                                 packet_number_++, kMaxOutgoingPacketSize,
+                                 retransmittable_data);
+  }
+
+  void CheckPacketIsSentImmediately() {
+    CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight,
+                                 false, 10);
+  }
+
+  void CheckPacketIsDelayed(QuicTime::Delta delay) {
+    // In order for the packet to be sendable, the underlying sender must
+    // permit it to be sent immediately.
+    for (int i = 0; i < 2; ++i) {
+      EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight))
+          .WillOnce(Return(true));
+      // Verify that the packet is delayed.
+      EXPECT_EQ(delay.ToMicroseconds(),
+                pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight)
+                    .ToMicroseconds());
+    }
+  }
+
+  void UpdateRtt() {
+    EXPECT_CALL(*mock_sender_,
+                OnCongestionEvent(true, kBytesInFlight, _, _, _));
+    AckedPacketVector empty_acked;
+    LostPacketVector empty_lost;
+    pacing_sender_->OnCongestionEvent(true, kBytesInFlight, clock_.Now(),
+                                      empty_acked, empty_lost);
+  }
+
+  void OnApplicationLimited() { pacing_sender_->OnApplicationLimited(); }
+
+  const QuicTime::Delta zero_time_;
+  const QuicTime::Delta infinite_time_;
+  MockClock clock_;
+  QuicPacketNumber packet_number_;
+  std::unique_ptr<StrictMock<MockSendAlgorithm>> mock_sender_;
+  std::unique_ptr<TestPacingSender> pacing_sender_;
+};
+
+TEST_F(PacingSenderTest, NoSend) {
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(false));
+    EXPECT_EQ(infinite_time_,
+              pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
+  }
+}
+
+TEST_F(PacingSenderTest, SendNow) {
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_CALL(*mock_sender_, CanSend(kBytesInFlight)).WillOnce(Return(true));
+    EXPECT_EQ(zero_time_,
+              pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight));
+  }
+}
+
+TEST_F(PacingSenderTest, VariousSending) {
+  // Configure pacing rate of 1 packet per 1 ms, no initial burst.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  // Now update the RTT and verify that packets are actually paced.
+  UpdateRtt();
+
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up late.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(4));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up really late.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up really late again, but application pause partway through.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  OnApplicationLimited();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+  // Wake up early, but after enough time has passed to permit a send.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckPacketIsSentImmediately();
+}
+
+TEST_F(PacingSenderTest, InitialBurst) {
+  // Configure pacing rate of 1 packet per 1 ms.
+  InitPacingRate(
+      10, QuicBandwidth::FromBytesAndTimeDelta(
+              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  // Update the RTT and verify that the first 10 packets aren't paced.
+  UpdateRtt();
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  CheckPacketIsSentImmediately();
+
+  // Next time TimeUntilSend is called with no bytes in flight, pacing should
+  // allow a packet to be sent, and when it's sent, the tokens are refilled.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
+  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) {
+  // Configure pacing rate of 1 packet per 1 ms.
+  InitPacingRate(
+      10, QuicBandwidth::FromBytesAndTimeDelta(
+              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  CheckPacketIsSentImmediately();
+
+  // Next time TimeUntilSend is called with no bytes in flight, the tokens
+  // should be refilled and there should be no delay.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, FastSending) {
+  // Ensure the pacing sender paces, even when the inter-packet spacing(0.5ms)
+  // is less than the pacing granularity(1ms).
+  InitPacingRate(10, QuicBandwidth::FromBytesAndTimeDelta(
+                         2 * kMaxOutgoingPacketSize,
+                         QuicTime::Delta::FromMilliseconds(1)));
+  // Update the RTT and verify that the first 10 packets aren't paced.
+  UpdateRtt();
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  CheckPacketIsSentImmediately();  // Make up
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsSentImmediately();  // "In the future" but within granularity.
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  CheckPacketIsSentImmediately();
+
+  // Next time TimeUntilSend is called with no bytes in flight, the tokens
+  // should be refilled and there should be no delay.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false, 10);
+  for (int i = 0; i < kInitialBurstPackets - 1; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet was a "make up", then we sent two packets "into the
+  // future", so the delay should be 1.5ms.
+  CheckPacketIsSentImmediately();  // Make up
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsSentImmediately();  // "In the future" but within granularity.
+  CheckPacketIsSentImmediately();  // Lumpy token
+  CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(2000));
+}
+
+TEST_F(PacingSenderTest, NoBurstEnteringRecovery) {
+  // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+  // Sending a packet will set burst tokens.
+  CheckPacketIsSentImmediately();
+
+  // Losing a packet will set clear burst tokens.
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  AckedPacketVector empty_acked;
+  EXPECT_CALL(*mock_sender_,
+              OnCongestionEvent(true, kMaxOutgoingPacketSize, _, IsEmpty(), _));
+  pacing_sender_->OnCongestionEvent(true, kMaxOutgoingPacketSize, clock_.Now(),
+                                    empty_acked, lost_packets);
+  // One packet is sent immediately, because of 1ms pacing granularity.
+  CheckPacketIsSentImmediately();
+  // Ensure packets are immediately paced.
+  EXPECT_CALL(*mock_sender_, CanSend(kMaxOutgoingPacketSize))
+      .WillOnce(Return(true));
+  // Verify the next packet is paced and delayed 2ms due to granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromMilliseconds(2),
+      pacing_sender_->TimeUntilSend(clock_.Now(), kMaxOutgoingPacketSize));
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, NoBurstInRecovery) {
+  // Configure pacing rate of 1 packet per 1 ms with no burst tokens.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  UpdateRtt();
+
+  // Ensure only one packet is sent immediately and the rest are paced.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, true, 10);
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, CwndLimited) {
+  // Configure pacing rate of 1 packet per 1 ms, no initial burst.
+  InitPacingRate(
+      0, QuicBandwidth::FromBytesAndTimeDelta(
+             kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+
+  UpdateRtt();
+
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 3 will be delayed 2ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
+  // After sending packet 3, cwnd is limited.
+  // This test is slightly odd because bytes_in_flight is calculated using
+  // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
+  // which is 8 bytes larger, so 3 packets can be sent for a CWND of 2.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                               2 * kMaxOutgoingPacketSize, false, 2);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  // Verify pacing sender stops making up for lost time after sending packet 3.
+  // Packet 6 will be delayed 2ms.
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, LumpyPacingWithInitialBurstToken) {
+  // Set lumpy size to be 3, and cwnd faction to 0.5
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
+  // Configure pacing rate of 1 packet per 1 ms.
+  InitPacingRate(
+      10, QuicBandwidth::FromBytesAndTimeDelta(
+              kMaxOutgoingPacketSize, QuicTime::Delta::FromMilliseconds(1)));
+  UpdateRtt();
+
+  // Send 10 packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 14 will be delayed 3ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 17 will be delayed 3ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
+
+  // Application throttles sending.
+  OnApplicationLimited();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  CheckPacketIsSentImmediately();
+  // Packet 20 will be delayed 3ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(3));
+
+  // Wake up on time.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3));
+  CheckPacketIsSentImmediately();
+  // After sending packet 21, cwnd is limited.
+  // This test is slightly odd because bytes_in_flight is calculated using
+  // kMaxOutgoingPacketSize and CWND is calculated using kDefaultTCPMSS,
+  // which is 8 bytes larger, so 21 packets can be sent for a CWND of 20.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                               20 * kMaxOutgoingPacketSize, false, 20);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  // Suppose cwnd size is 5, so that lumpy size becomes 2.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight, false,
+                               5);
+  CheckPacketIsSentImmediately();
+  // Packet 24 will be delayed 2ms.
+  CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(PacingSenderTest, NoLumpyPacingForLowBandwidthFlows) {
+  // Set lumpy size to be 3, and cwnd fraction to 0.5
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
+
+  // Configure pacing rate of 1 packet per 100 ms.
+  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(100);
+  InitPacingRate(kInitialBurstPackets,
+                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
+                                                      inter_packet_delay));
+  UpdateRtt();
+
+  // Send kInitialBurstPackets packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  // The first packet after burst token exhausted is also sent immediately,
+  // because ideal_next_packet_send_time has not been set yet.
+  CheckPacketIsSentImmediately();
+
+  for (int i = 0; i < 200; ++i) {
+    CheckPacketIsDelayed(inter_packet_delay);
+  }
+}
+
+// Regression test for b/184471302 to ensure that ACKs received back-to-back
+// don't cause bursts in sending.
+TEST_F(PacingSenderTest, NoBurstsForLumpyPacingWithAckAggregation) {
+  // Configure pacing rate of 1 packet per millisecond.
+  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
+  InitPacingRate(kInitialBurstPackets,
+                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
+                                                      inter_packet_delay));
+  UpdateRtt();
+
+  // Send kInitialBurstPackets packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+  // The last packet of the burst causes the sender to be CWND limited.
+  CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                               10 * kMaxOutgoingPacketSize, false, 10);
+
+  if (GetQuicReloadableFlag(quic_fix_pacing_sender_bursts)) {
+    // The last sent packet made the connection CWND limited, so no lumpy tokens
+    // should be available.
+    EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
+    CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                                 10 * kMaxOutgoingPacketSize, false, 10);
+    EXPECT_EQ(0u, pacing_sender_->lumpy_tokens());
+    CheckPacketIsDelayed(2 * inter_packet_delay);
+  } else {
+    EXPECT_EQ(1u, pacing_sender_->lumpy_tokens());
+    // Repeatedly send single packets to make the sender CWND limited and
+    // observe that there's no pacing without the fix.
+    for (int i = 0; i < 10; ++i) {
+      CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA,
+                                   10 * kMaxOutgoingPacketSize, false, 10);
+    }
+  }
+}
+
+TEST_F(PacingSenderTest, IdealNextPacketSendTimeWithLumpyPacing) {
+  // Set lumpy size to be 3, and cwnd faction to 0.5
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_size, 3);
+  SetQuicFlag(FLAGS_quic_lumpy_pacing_cwnd_fraction, 0.5f);
+
+  // Configure pacing rate of 1 packet per millisecond.
+  QuicTime::Delta inter_packet_delay = QuicTime::Delta::FromMilliseconds(1);
+  InitPacingRate(kInitialBurstPackets,
+                 QuicBandwidth::FromBytesAndTimeDelta(kMaxOutgoingPacketSize,
+                                                      inter_packet_delay));
+
+  // Send kInitialBurstPackets packets, and verify that they are not paced.
+  for (int i = 0; i < kInitialBurstPackets; ++i) {
+    CheckPacketIsSentImmediately();
+  }
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 2 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 3 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
+
+  CheckPacketIsDelayed(3 * inter_packet_delay);
+
+  // Wake up on time.
+  clock_.AdvanceTime(3 * inter_packet_delay);
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 2 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 3 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
+
+  CheckPacketIsDelayed(3 * inter_packet_delay);
+
+  // Wake up late.
+  clock_.AdvanceTime(4.5 * inter_packet_delay);
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() - 0.5 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 2u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 0.5 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 1u);
+
+  CheckPacketIsSentImmediately();
+  EXPECT_EQ(pacing_sender_->ideal_next_packet_send_time(),
+            clock_.Now() + 1.5 * inter_packet_delay);
+  EXPECT_EQ(pacing_sender_->lumpy_tokens(), 0u);
+
+  CheckPacketIsDelayed(1.5 * inter_packet_delay);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/prr_sender.cc b/quiche/quic/core/congestion_control/prr_sender.cc
new file mode 100644
index 0000000..951f0ba
--- /dev/null
+++ b/quiche/quic/core/congestion_control/prr_sender.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/prr_sender.h"
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+PrrSender::PrrSender()
+    : bytes_sent_since_loss_(0),
+      bytes_delivered_since_loss_(0),
+      ack_count_since_loss_(0),
+      bytes_in_flight_before_loss_(0) {}
+
+void PrrSender::OnPacketSent(QuicByteCount sent_bytes) {
+  bytes_sent_since_loss_ += sent_bytes;
+}
+
+void PrrSender::OnPacketLost(QuicByteCount prior_in_flight) {
+  bytes_sent_since_loss_ = 0;
+  bytes_in_flight_before_loss_ = prior_in_flight;
+  bytes_delivered_since_loss_ = 0;
+  ack_count_since_loss_ = 0;
+}
+
+void PrrSender::OnPacketAcked(QuicByteCount acked_bytes) {
+  bytes_delivered_since_loss_ += acked_bytes;
+  ++ack_count_since_loss_;
+}
+
+bool PrrSender::CanSend(QuicByteCount congestion_window,
+                        QuicByteCount bytes_in_flight,
+                        QuicByteCount slowstart_threshold) const {
+  // Return QuicTime::Zero in order to ensure limited transmit always works.
+  if (bytes_sent_since_loss_ == 0 || bytes_in_flight < kMaxSegmentSize) {
+    return true;
+  }
+  if (congestion_window > bytes_in_flight) {
+    // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
+    // of sending the entire available window. This prevents burst retransmits
+    // when more packets are lost than the CWND reduction.
+    //   limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
+    if (bytes_delivered_since_loss_ + ack_count_since_loss_ * kMaxSegmentSize <=
+        bytes_sent_since_loss_) {
+      return false;
+    }
+    return true;
+  }
+  // Implement Proportional Rate Reduction (RFC6937).
+  // Checks a simplified version of the PRR formula that doesn't use division:
+  // AvailableSendWindow =
+  //   CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent
+  if (bytes_delivered_since_loss_ * slowstart_threshold >
+      bytes_sent_since_loss_ * bytes_in_flight_before_loss_) {
+    return true;
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/prr_sender.h b/quiche/quic/core/congestion_control/prr_sender.h
new file mode 100644
index 0000000..f55069b
--- /dev/null
+++ b/quiche/quic/core/congestion_control/prr_sender.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Implements Proportional Rate Reduction (PRR) per RFC 6937.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE PrrSender {
+ public:
+  PrrSender();
+  // OnPacketLost should be called on the first loss that triggers a recovery
+  // period and all other methods in this class should only be called when in
+  // recovery.
+  void OnPacketLost(QuicByteCount prior_in_flight);
+  void OnPacketSent(QuicByteCount sent_bytes);
+  void OnPacketAcked(QuicByteCount acked_bytes);
+  bool CanSend(QuicByteCount congestion_window,
+               QuicByteCount bytes_in_flight,
+               QuicByteCount slowstart_threshold) const;
+
+ private:
+  // Bytes sent and acked since the last loss event.
+  // |bytes_sent_since_loss_| is the same as "prr_out_" in RFC 6937,
+  // and |bytes_delivered_since_loss_| is the same as "prr_delivered_".
+  QuicByteCount bytes_sent_since_loss_;
+  QuicByteCount bytes_delivered_since_loss_;
+  size_t ack_count_since_loss_;
+
+  // The congestion window before the last loss event.
+  QuicByteCount bytes_in_flight_before_loss_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PRR_SENDER_H_
diff --git a/quiche/quic/core/congestion_control/prr_sender_test.cc b/quiche/quic/core/congestion_control/prr_sender_test.cc
new file mode 100644
index 0000000..60dd779
--- /dev/null
+++ b/quiche/quic/core/congestion_control/prr_sender_test.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/prr_sender.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+// Constant based on TCP defaults.
+const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
+}  // namespace
+
+class PrrSenderTest : public QuicTest {};
+
+TEST_F(PrrSenderTest, SingleLossResultsInSendOnEveryOtherAck) {
+  PrrSender prr;
+  QuicPacketCount num_packets_in_flight = 50;
+  QuicByteCount bytes_in_flight = num_packets_in_flight * kMaxSegmentSize;
+  const QuicPacketCount ssthresh_after_loss = num_packets_in_flight / 2;
+  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
+
+  prr.OnPacketLost(bytes_in_flight);
+  // Ack a packet. PRR allows one packet to leave immediately.
+  prr.OnPacketAcked(kMaxSegmentSize);
+  bytes_in_flight -= kMaxSegmentSize;
+  EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                          ssthresh_after_loss * kMaxSegmentSize));
+  // Send retransmission.
+  prr.OnPacketSent(kMaxSegmentSize);
+  // PRR shouldn't allow sending any more packets.
+  EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                           ssthresh_after_loss * kMaxSegmentSize));
+
+  // One packet is lost, and one ack was consumed above. PRR now paces
+  // transmissions through the remaining 48 acks. PRR will alternatively
+  // disallow and allow a packet to be sent in response to an ack.
+  for (uint64_t i = 0; i < ssthresh_after_loss - 1; ++i) {
+    // Ack a packet. PRR shouldn't allow sending a packet in response.
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                             ssthresh_after_loss * kMaxSegmentSize));
+    // Ack another packet. PRR should now allow sending a packet in response.
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                            ssthresh_after_loss * kMaxSegmentSize));
+    // Send a packet in response.
+    prr.OnPacketSent(kMaxSegmentSize);
+    bytes_in_flight += kMaxSegmentSize;
+  }
+
+  // Since bytes_in_flight is now equal to congestion_window, PRR now maintains
+  // packet conservation, allowing one packet to be sent in response to an ack.
+  EXPECT_EQ(congestion_window, bytes_in_flight);
+  for (int i = 0; i < 10; ++i) {
+    // Ack a packet.
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                            ssthresh_after_loss * kMaxSegmentSize));
+    // Send a packet in response, since PRR allows it.
+    prr.OnPacketSent(kMaxSegmentSize);
+    bytes_in_flight += kMaxSegmentSize;
+
+    // Since bytes_in_flight is equal to the congestion_window,
+    // PRR disallows sending.
+    EXPECT_EQ(congestion_window, bytes_in_flight);
+    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                             ssthresh_after_loss * kMaxSegmentSize));
+  }
+}
+
+TEST_F(PrrSenderTest, BurstLossResultsInSlowStart) {
+  PrrSender prr;
+  QuicByteCount bytes_in_flight = 20 * kMaxSegmentSize;
+  const QuicPacketCount num_packets_lost = 13;
+  const QuicPacketCount ssthresh_after_loss = 10;
+  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;
+
+  // Lose 13 packets.
+  bytes_in_flight -= num_packets_lost * kMaxSegmentSize;
+  prr.OnPacketLost(bytes_in_flight);
+
+  // PRR-SSRB will allow the following 3 acks to send up to 2 packets.
+  for (int i = 0; i < 3; ++i) {
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    // PRR-SSRB should allow two packets to be sent.
+    for (int j = 0; j < 2; ++j) {
+      EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                              ssthresh_after_loss * kMaxSegmentSize));
+      // Send a packet in response.
+      prr.OnPacketSent(kMaxSegmentSize);
+      bytes_in_flight += kMaxSegmentSize;
+    }
+    // PRR should allow no more than 2 packets in response to an ack.
+    EXPECT_FALSE(prr.CanSend(congestion_window, bytes_in_flight,
+                             ssthresh_after_loss * kMaxSegmentSize));
+  }
+
+  // Out of SSRB mode, PRR allows one send in response to each ack.
+  for (int i = 0; i < 10; ++i) {
+    prr.OnPacketAcked(kMaxSegmentSize);
+    bytes_in_flight -= kMaxSegmentSize;
+    EXPECT_TRUE(prr.CanSend(congestion_window, bytes_in_flight,
+                            ssthresh_after_loss * kMaxSegmentSize));
+    // Send a packet in response.
+    prr.OnPacketSent(kMaxSegmentSize);
+    bytes_in_flight += kMaxSegmentSize;
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/rtt_stats.cc b/quiche/quic/core/congestion_control/rtt_stats.cc
new file mode 100644
index 0000000..90a9efe
--- /dev/null
+++ b/quiche/quic/core/congestion_control/rtt_stats.cc
@@ -0,0 +1,144 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+
+#include <cstdlib>  // std::abs
+
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+const float kAlpha = 0.125f;
+const float kOneMinusAlpha = (1 - kAlpha);
+const float kBeta = 0.25f;
+const float kOneMinusBeta = (1 - kBeta);
+
+}  // namespace
+
+RttStats::RttStats()
+    : latest_rtt_(QuicTime::Delta::Zero()),
+      min_rtt_(QuicTime::Delta::Zero()),
+      smoothed_rtt_(QuicTime::Delta::Zero()),
+      previous_srtt_(QuicTime::Delta::Zero()),
+      mean_deviation_(QuicTime::Delta::Zero()),
+      calculate_standard_deviation_(false),
+      initial_rtt_(QuicTime::Delta::FromMilliseconds(kInitialRttMs)),
+      last_update_time_(QuicTime::Zero()) {}
+
+void RttStats::ExpireSmoothedMetrics() {
+  mean_deviation_ = std::max(
+      mean_deviation_, QuicTime::Delta::FromMicroseconds(std::abs(
+                           (smoothed_rtt_ - latest_rtt_).ToMicroseconds())));
+  smoothed_rtt_ = std::max(smoothed_rtt_, latest_rtt_);
+}
+
+// Updates the RTT based on a new sample.
+void RttStats::UpdateRtt(QuicTime::Delta send_delta,
+                         QuicTime::Delta ack_delay,
+                         QuicTime now) {
+  if (send_delta.IsInfinite() || send_delta <= QuicTime::Delta::Zero()) {
+    QUIC_LOG_FIRST_N(WARNING, 3)
+        << "Ignoring measured send_delta, because it's is "
+        << "either infinite, zero, or negative.  send_delta = "
+        << send_delta.ToMicroseconds();
+    return;
+  }
+
+  last_update_time_ = now;
+
+  // Update min_rtt_ first. min_rtt_ does not use an rtt_sample corrected for
+  // ack_delay but the raw observed send_delta, since poor clock granularity at
+  // the client may cause a high ack_delay to result in underestimation of the
+  // min_rtt_.
+  if (min_rtt_.IsZero() || min_rtt_ > send_delta) {
+    min_rtt_ = send_delta;
+  }
+
+  QuicTime::Delta rtt_sample(send_delta);
+  previous_srtt_ = smoothed_rtt_;
+  // Correct for ack_delay if information received from the peer results in a
+  // an RTT sample at least as large as min_rtt. Otherwise, only use the
+  // send_delta.
+  // TODO(fayang): consider to ignore rtt_sample if rtt_sample < ack_delay and
+  // ack_delay is relatively large.
+  if (rtt_sample > ack_delay) {
+    if (rtt_sample - min_rtt_ >= ack_delay) {
+      rtt_sample = rtt_sample - ack_delay;
+    } else {
+      QUIC_CODE_COUNT(quic_ack_delay_makes_rtt_sample_smaller_than_min_rtt);
+    }
+  } else {
+    QUIC_CODE_COUNT(quic_ack_delay_greater_than_rtt_sample);
+  }
+  latest_rtt_ = rtt_sample;
+  if (calculate_standard_deviation_) {
+    standard_deviation_calculator_.OnNewRttSample(rtt_sample, smoothed_rtt_);
+  }
+  // First time call.
+  if (smoothed_rtt_.IsZero()) {
+    smoothed_rtt_ = rtt_sample;
+    mean_deviation_ =
+        QuicTime::Delta::FromMicroseconds(rtt_sample.ToMicroseconds() / 2);
+  } else {
+    mean_deviation_ = QuicTime::Delta::FromMicroseconds(static_cast<int64_t>(
+        kOneMinusBeta * mean_deviation_.ToMicroseconds() +
+        kBeta * std::abs((smoothed_rtt_ - rtt_sample).ToMicroseconds())));
+    smoothed_rtt_ = kOneMinusAlpha * smoothed_rtt_ + kAlpha * rtt_sample;
+    QUIC_DVLOG(1) << " smoothed_rtt(us):" << smoothed_rtt_.ToMicroseconds()
+                  << " mean_deviation(us):" << mean_deviation_.ToMicroseconds();
+  }
+}
+
+void RttStats::OnConnectionMigration() {
+  latest_rtt_ = QuicTime::Delta::Zero();
+  min_rtt_ = QuicTime::Delta::Zero();
+  smoothed_rtt_ = QuicTime::Delta::Zero();
+  mean_deviation_ = QuicTime::Delta::Zero();
+  initial_rtt_ = QuicTime::Delta::FromMilliseconds(kInitialRttMs);
+}
+
+QuicTime::Delta RttStats::GetStandardOrMeanDeviation() const {
+  QUICHE_DCHECK(calculate_standard_deviation_);
+  if (!standard_deviation_calculator_.has_valid_standard_deviation) {
+    return mean_deviation_;
+  }
+  return standard_deviation_calculator_.CalculateStandardDeviation();
+}
+
+void RttStats::StandardDeviationCaculator::OnNewRttSample(
+    QuicTime::Delta rtt_sample,
+    QuicTime::Delta smoothed_rtt) {
+  double new_value = rtt_sample.ToMicroseconds();
+  if (smoothed_rtt.IsZero()) {
+    return;
+  }
+  has_valid_standard_deviation = true;
+  const double delta = new_value - smoothed_rtt.ToMicroseconds();
+  m2 = kOneMinusBeta * m2 + kBeta * pow(delta, 2);
+}
+
+QuicTime::Delta
+RttStats::StandardDeviationCaculator::CalculateStandardDeviation() const {
+  QUICHE_DCHECK(has_valid_standard_deviation);
+  return QuicTime::Delta::FromMicroseconds(sqrt(m2));
+}
+
+void RttStats::CloneFrom(const RttStats& stats) {
+  latest_rtt_ = stats.latest_rtt_;
+  min_rtt_ = stats.min_rtt_;
+  smoothed_rtt_ = stats.smoothed_rtt_;
+  previous_srtt_ = stats.previous_srtt_;
+  mean_deviation_ = stats.mean_deviation_;
+  standard_deviation_calculator_ = stats.standard_deviation_calculator_;
+  calculate_standard_deviation_ = stats.calculate_standard_deviation_;
+  initial_rtt_ = stats.initial_rtt_;
+  last_update_time_ = stats.last_update_time_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/rtt_stats.h b/quiche/quic/core/congestion_control/rtt_stats.h
new file mode 100644
index 0000000..6b6569a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/rtt_stats.h
@@ -0,0 +1,131 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A convenience class to store rtt samples and calculate smoothed rtt.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
+
+#include <algorithm>
+#include <cstdint>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class RttStatsPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE RttStats {
+ public:
+  // Calculates running standard-deviation using Welford's algorithm:
+  // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#
+  // Welford's_Online_algorithm.
+  struct QUIC_EXPORT_PRIVATE StandardDeviationCaculator {
+    StandardDeviationCaculator() {}
+
+    // Called when a new RTT sample is available.
+    void OnNewRttSample(QuicTime::Delta rtt_sample,
+                        QuicTime::Delta smoothed_rtt);
+    // Calculates the standard deviation.
+    QuicTime::Delta CalculateStandardDeviation() const;
+
+    bool has_valid_standard_deviation = false;
+
+   private:
+    double m2 = 0;
+  };
+
+  RttStats();
+  RttStats(const RttStats&) = delete;
+  RttStats& operator=(const RttStats&) = delete;
+
+  // Updates the RTT from an incoming ack which is received |send_delta| after
+  // the packet is sent and the peer reports the ack being delayed |ack_delay|.
+  void UpdateRtt(QuicTime::Delta send_delta,
+                 QuicTime::Delta ack_delay,
+                 QuicTime now);
+
+  // Causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt
+  // is larger. The mean deviation is increased to the most recent deviation if
+  // it's larger.
+  void ExpireSmoothedMetrics();
+
+  // Called when connection migrates and rtt measurement needs to be reset.
+  void OnConnectionMigration();
+
+  // Returns the EWMA smoothed RTT for the connection.
+  // May return Zero if no valid updates have occurred.
+  QuicTime::Delta smoothed_rtt() const { return smoothed_rtt_; }
+
+  // Returns the EWMA smoothed RTT prior to the most recent RTT sample.
+  QuicTime::Delta previous_srtt() const { return previous_srtt_; }
+
+  QuicTime::Delta initial_rtt() const { return initial_rtt_; }
+
+  QuicTime::Delta SmoothedOrInitialRtt() const {
+    return smoothed_rtt_.IsZero() ? initial_rtt_ : smoothed_rtt_;
+  }
+
+  QuicTime::Delta MinOrInitialRtt() const {
+    return min_rtt_.IsZero() ? initial_rtt_ : min_rtt_;
+  }
+
+  // Sets an initial RTT to be used for SmoothedRtt before any RTT updates.
+  void set_initial_rtt(QuicTime::Delta initial_rtt) {
+    if (initial_rtt.ToMicroseconds() <= 0) {
+      QUIC_BUG(quic_bug_10453_1) << "Attempt to set initial rtt to <= 0.";
+      return;
+    }
+    initial_rtt_ = initial_rtt;
+  }
+
+  // The most recent rtt measurement.
+  // May return Zero if no valid updates have occurred.
+  QuicTime::Delta latest_rtt() const { return latest_rtt_; }
+
+  // Returns the min_rtt for the entire connection.
+  // May return Zero if no valid updates have occurred.
+  QuicTime::Delta min_rtt() const { return min_rtt_; }
+
+  QuicTime::Delta mean_deviation() const { return mean_deviation_; }
+
+  // Returns standard deviation if there is a valid one. Otherwise, returns
+  // mean_deviation_.
+  QuicTime::Delta GetStandardOrMeanDeviation() const;
+
+  QuicTime last_update_time() const { return last_update_time_; }
+
+  void EnableStandardDeviationCalculation() {
+    calculate_standard_deviation_ = true;
+  }
+
+  void CloneFrom(const RttStats& stats);
+
+ private:
+  friend class test::RttStatsPeer;
+
+  QuicTime::Delta latest_rtt_;
+  QuicTime::Delta min_rtt_;
+  QuicTime::Delta smoothed_rtt_;
+  QuicTime::Delta previous_srtt_;
+  // Mean RTT deviation during this session.
+  // Approximation of standard deviation, the error is roughly 1.25 times
+  // larger than the standard deviation, for a normally distributed signal.
+  QuicTime::Delta mean_deviation_;
+  // Standard deviation calculator. Only used calculate_standard_deviation_ is
+  // true.
+  StandardDeviationCaculator standard_deviation_calculator_;
+  bool calculate_standard_deviation_;
+  QuicTime::Delta initial_rtt_;
+  QuicTime last_update_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_
diff --git a/quiche/quic/core/congestion_control/rtt_stats_test.cc b/quiche/quic/core/congestion_control/rtt_stats_test.cc
new file mode 100644
index 0000000..d1a7080
--- /dev/null
+++ b/quiche/quic/core/congestion_control/rtt_stats_test.cc
@@ -0,0 +1,242 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+
+#include <cmath>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_mock_log.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/rtt_stats_peer.h"
+
+using testing::_;
+using testing::Message;
+
+namespace quic {
+namespace test {
+
+class RttStatsTest : public QuicTest {
+ protected:
+  RttStats rtt_stats_;
+};
+
+TEST_F(RttStatsTest, DefaultsBeforeUpdate) {
+  EXPECT_LT(QuicTime::Delta::Zero(), rtt_stats_.initial_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
+}
+
+TEST_F(RttStatsTest, SmoothedRtt) {
+  // Verify that ack_delay is ignored in the first measurement.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
+                       QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
+  // Verify that a plausible ack delay increases the max ack delay.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(400),
+                       QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
+  // Verify that Smoothed RTT includes max ack delay if it's reasonable.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(350),
+                       QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300), rtt_stats_.smoothed_rtt());
+  // Verify that large erroneous ack_delay does not change Smoothed RTT.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::FromMilliseconds(300),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
+            rtt_stats_.smoothed_rtt());
+}
+
+// Ensure that the potential rounding artifacts in EWMA calculation do not cause
+// the SRTT to drift too far from the exact value.
+TEST_F(RttStatsTest, SmoothedRttStability) {
+  for (size_t time = 3; time < 20000; time++) {
+    RttStats stats;
+    for (size_t i = 0; i < 100; i++) {
+      stats.UpdateRtt(QuicTime::Delta::FromMicroseconds(time),
+                      QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
+      int64_t time_delta_us = stats.smoothed_rtt().ToMicroseconds() - time;
+      ASSERT_LE(std::abs(time_delta_us), 1);
+    }
+  }
+}
+
+TEST_F(RttStatsTest, PreviousSmoothedRtt) {
+  // Verify that ack_delay is corrected for in Smoothed RTT.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.previous_srtt());
+  // Ensure the previous SRTT is 200ms after a 100ms sample.
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(187500).ToMicroseconds(),
+            rtt_stats_.smoothed_rtt().ToMicroseconds());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.previous_srtt());
+}
+
+TEST_F(RttStatsTest, MinRtt) {
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(10), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(20));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(30));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(50), QuicTime::Delta::Zero(),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(40));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), rtt_stats_.min_rtt());
+  // Verify that ack_delay does not go into recording of min_rtt_.
+  rtt_stats_.UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(7),
+      QuicTime::Delta::FromMilliseconds(2),
+      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(50));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(7), rtt_stats_.min_rtt());
+}
+
+TEST_F(RttStatsTest, ExpireSmoothedMetrics) {
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
+  rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
+  EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
+
+  EXPECT_EQ(0.5 * initial_rtt, rtt_stats_.mean_deviation());
+
+  // Update once with a 20ms RTT.
+  QuicTime::Delta doubled_rtt = 2 * initial_rtt;
+  rtt_stats_.UpdateRtt(doubled_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(1.125 * initial_rtt, rtt_stats_.smoothed_rtt());
+
+  // Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
+  rtt_stats_.ExpireSmoothedMetrics();
+  EXPECT_EQ(doubled_rtt, rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(0.875 * initial_rtt, rtt_stats_.mean_deviation());
+
+  // Now go back down to 5ms and expire the smoothed metrics, and ensure the
+  // mean deviation increases to 15ms.
+  QuicTime::Delta half_rtt = 0.5 * initial_rtt;
+  rtt_stats_.UpdateRtt(half_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_GT(doubled_rtt, rtt_stats_.smoothed_rtt());
+  EXPECT_LT(initial_rtt, rtt_stats_.mean_deviation());
+}
+
+TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
+  // Make sure we ignore bad RTTs.
+  CREATE_QUIC_MOCK_LOG(log);
+
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
+  rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
+  EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
+
+  std::vector<QuicTime::Delta> bad_send_deltas;
+  bad_send_deltas.push_back(QuicTime::Delta::Zero());
+  bad_send_deltas.push_back(QuicTime::Delta::Infinite());
+  bad_send_deltas.push_back(QuicTime::Delta::FromMicroseconds(-1000));
+  log.StartCapturingLogs();
+
+  for (QuicTime::Delta bad_send_delta : bad_send_deltas) {
+    SCOPED_TRACE(Message() << "bad_send_delta = "
+                           << bad_send_delta.ToMicroseconds());
+    if (QUIC_LOG_WARNING_IS_ON()) {
+      EXPECT_QUIC_LOG_CALL_CONTAINS(log, WARNING, "Ignoring");
+    }
+    rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
+                         QuicTime::Zero());
+    EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
+    EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
+  }
+}
+
+TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
+                       QuicTime::Delta::FromMilliseconds(0), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
+
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
+                       QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
+
+  // Reset rtt stats on connection migrations.
+  rtt_stats_.OnConnectionMigration();
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.min_rtt());
+}
+
+TEST_F(RttStatsTest, StandardDeviationCaculatorTest1) {
+  // All samples are the same.
+  rtt_stats_.EnableStandardDeviationCalculation();
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(rtt_stats_.mean_deviation(),
+            rtt_stats_.GetStandardOrMeanDeviation());
+
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::Zero(), rtt_stats_.GetStandardOrMeanDeviation());
+}
+
+TEST_F(RttStatsTest, StandardDeviationCaculatorTest2) {
+  // Small variance.
+  rtt_stats_.EnableStandardDeviationCalculation();
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(9),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(11),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_LT(QuicTime::Delta::FromMicroseconds(500),
+            rtt_stats_.GetStandardOrMeanDeviation());
+  EXPECT_GT(QuicTime::Delta::FromMilliseconds(1),
+            rtt_stats_.GetStandardOrMeanDeviation());
+}
+
+TEST_F(RttStatsTest, StandardDeviationCaculatorTest3) {
+  // Some variance.
+  rtt_stats_.EnableStandardDeviationCalculation();
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_APPROX_EQ(rtt_stats_.mean_deviation(),
+                   rtt_stats_.GetStandardOrMeanDeviation(), 0.25f);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.cc b/quiche/quic/core/congestion_control/send_algorithm_interface.cc
new file mode 100644
index 0000000..f8be8d9
--- /dev/null
+++ b/quiche/quic/core/congestion_control/send_algorithm_interface.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+
+#include "absl/base/attributes.h"
+#include "quiche/quic/core/congestion_control/bbr2_sender.h"
+#include "quiche/quic/core/congestion_control/bbr_sender.h"
+#include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class RttStats;
+
+// Factory for send side congestion control algorithm.
+SendAlgorithmInterface* SendAlgorithmInterface::Create(
+    const QuicClock* clock,
+    const RttStats* rtt_stats,
+    const QuicUnackedPacketMap* unacked_packets,
+    CongestionControlType congestion_control_type,
+    QuicRandom* random,
+    QuicConnectionStats* stats,
+    QuicPacketCount initial_congestion_window,
+    SendAlgorithmInterface* old_send_algorithm) {
+  QuicPacketCount max_congestion_window =
+      GetQuicFlag(FLAGS_quic_max_congestion_window);
+  switch (congestion_control_type) {
+    case kGoogCC:  // GoogCC is not supported by quic/core, fall back to BBR.
+    case kBBR:
+      return new BbrSender(clock->ApproximateNow(), rtt_stats, unacked_packets,
+                           initial_congestion_window, max_congestion_window,
+                           random, stats);
+    case kBBRv2:
+      return new Bbr2Sender(
+          clock->ApproximateNow(), rtt_stats, unacked_packets,
+          initial_congestion_window, max_congestion_window, random, stats,
+          old_send_algorithm &&
+                  old_send_algorithm->GetCongestionControlType() == kBBR
+              ? static_cast<BbrSender*>(old_send_algorithm)
+              : nullptr);
+    case kPCC:
+      // PCC is currently not supported, fall back to CUBIC instead.
+      ABSL_FALLTHROUGH_INTENDED;
+    case kCubicBytes:
+      return new TcpCubicSenderBytes(
+          clock, rtt_stats, false /* don't use Reno */,
+          initial_congestion_window, max_congestion_window, stats);
+    case kRenoBytes:
+      return new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
+                                     initial_congestion_window,
+                                     max_congestion_window, stats);
+  }
+  return nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.h b/quiche/quic/core/congestion_control/send_algorithm_interface.h
new file mode 100644
index 0000000..ed85d2f
--- /dev/null
+++ b/quiche/quic/core/congestion_control/send_algorithm_interface.h
@@ -0,0 +1,181 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The pure virtual class for send side congestion control algorithm.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
+
+#include <algorithm>
+#include <map>
+#include <string>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+using QuicRoundTripCount = uint64_t;
+
+class CachedNetworkParameters;
+class RttStats;
+
+class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
+ public:
+  // Network Params for AdjustNetworkParameters.
+  struct QUIC_NO_EXPORT NetworkParams {
+    NetworkParams() = default;
+    NetworkParams(const QuicBandwidth& bandwidth, const QuicTime::Delta& rtt,
+                  bool allow_cwnd_to_decrease)
+        : bandwidth(bandwidth),
+          rtt(rtt),
+          allow_cwnd_to_decrease(allow_cwnd_to_decrease) {}
+    explicit NetworkParams(int burst_token) : burst_token(burst_token) {}
+
+    bool operator==(const NetworkParams& other) const {
+      return bandwidth == other.bandwidth && rtt == other.rtt &&
+             max_initial_congestion_window ==
+                 other.max_initial_congestion_window &&
+             burst_token == other.burst_token &&
+             allow_cwnd_to_decrease == other.allow_cwnd_to_decrease &&
+             is_rtt_trusted == other.is_rtt_trusted;
+    }
+
+    QuicBandwidth bandwidth = QuicBandwidth::Zero();
+    QuicTime::Delta rtt = QuicTime::Delta::Zero();
+    int max_initial_congestion_window = 0;
+    int burst_token = 0;
+    bool allow_cwnd_to_decrease = false;
+    bool is_rtt_trusted = false;
+  };
+
+  static SendAlgorithmInterface* Create(
+      const QuicClock* clock,
+      const RttStats* rtt_stats,
+      const QuicUnackedPacketMap* unacked_packets,
+      CongestionControlType type,
+      QuicRandom* random,
+      QuicConnectionStats* stats,
+      QuicPacketCount initial_congestion_window,
+      SendAlgorithmInterface* old_send_algorithm);
+
+  virtual ~SendAlgorithmInterface() {}
+
+  virtual void SetFromConfig(const QuicConfig& config,
+                             Perspective perspective) = 0;
+
+  virtual void ApplyConnectionOptions(
+      const QuicTagVector& connection_options) = 0;
+
+  // Sets the initial congestion window in number of packets.  May be ignored
+  // if called after the initial congestion window is no longer relevant.
+  virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0;
+
+  // Indicates an update to the congestion state, caused either by an incoming
+  // ack or loss event timeout.  |rtt_updated| indicates whether a new
+  // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
+  // prior to the congestion event.  |acked_packets| and |lost_packets| are any
+  // packets considered acked or lost as a result of the congestion event.
+  virtual void OnCongestionEvent(bool rtt_updated,
+                                 QuicByteCount prior_in_flight,
+                                 QuicTime event_time,
+                                 const AckedPacketVector& acked_packets,
+                                 const LostPacketVector& lost_packets) = 0;
+
+  // Inform that we sent |bytes| to the wire, and if the packet is
+  // retransmittable.  |bytes_in_flight| is the number of bytes in flight before
+  // the packet was sent.
+  // Note: this function must be called for every packet sent to the wire.
+  virtual void OnPacketSent(QuicTime sent_time,
+                            QuicByteCount bytes_in_flight,
+                            QuicPacketNumber packet_number,
+                            QuicByteCount bytes,
+                            HasRetransmittableData is_retransmittable) = 0;
+
+  // Inform that |packet_number| has been neutered.
+  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
+
+  // Called when the retransmission timeout fires.  Neither OnPacketAbandoned
+  // nor OnPacketLost will be called for these packets.
+  virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
+
+  // Called when connection migrates and cwnd needs to be reset.
+  virtual void OnConnectionMigration() = 0;
+
+  // Make decision on whether the sender can send right now.  Note that even
+  // when this method returns true, the sending can be delayed due to pacing.
+  virtual bool CanSend(QuicByteCount bytes_in_flight) = 0;
+
+  // The pacing rate of the send algorithm.  May be zero if the rate is unknown.
+  virtual QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const = 0;
+
+  // What's the current estimated bandwidth in bytes per second.
+  // Returns 0 when it does not have an estimate.
+  virtual QuicBandwidth BandwidthEstimate() const = 0;
+
+  // Whether BandwidthEstimate returns a good measurement for resumption.
+  virtual bool HasGoodBandwidthEstimateForResumption() const = 0;
+
+  // Returns the size of the current congestion window in bytes.  Note, this is
+  // not the *available* window.  Some send algorithms may not use a congestion
+  // window and will return 0.
+  virtual QuicByteCount GetCongestionWindow() const = 0;
+
+  // Whether the send algorithm is currently in slow start.  When true, the
+  // BandwidthEstimate is expected to be too low.
+  virtual bool InSlowStart() const = 0;
+
+  // Whether the send algorithm is currently in recovery.
+  virtual bool InRecovery() const = 0;
+
+  // True when the congestion control is probing for more bandwidth and needs
+  // enough data to not be app-limited to do so.
+  // TODO(ianswett): In the future, this API may want to indicate the size of
+  // the probing packet.
+  virtual bool ShouldSendProbingPacket() const = 0;
+
+  // Returns the size of the slow start congestion window in bytes,
+  // aka ssthresh.  Only defined for Cubic and Reno, other algorithms return 0.
+  virtual QuicByteCount GetSlowStartThreshold() const = 0;
+
+  virtual CongestionControlType GetCongestionControlType() const = 0;
+
+  // Notifies the congestion control algorithm of an external network
+  // measurement or prediction.  Either |bandwidth| or |rtt| may be zero if no
+  // sample is available.
+  virtual void AdjustNetworkParameters(const NetworkParams& params) = 0;
+
+  // Retrieves debugging information about the current state of the
+  // send algorithm.
+  virtual std::string GetDebugState() const = 0;
+
+  // Called when the connection has no outstanding data to send. Specifically,
+  // this means that none of the data streams are write-blocked, there are no
+  // packets in the connection queue, and there are no pending retransmissins,
+  // i.e. the sender cannot send anything for reasons other than being blocked
+  // by congestion controller. This includes cases when the connection is
+  // blocked by the flow controller.
+  //
+  // The fact that this method is called does not necessarily imply that the
+  // connection would not be blocked by the congestion control if it actually
+  // tried to send data. If the congestion control algorithm needs to exclude
+  // such cases, it should use the internal state it uses for congestion control
+  // for that.
+  virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0;
+
+  // Called before connection close to collect stats.
+  virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_SEND_ALGORITHM_INTERFACE_H_
diff --git a/quiche/quic/core/congestion_control/send_algorithm_test.cc b/quiche/quic/core/congestion_control/send_algorithm_test.cc
new file mode 100644
index 0000000..f55d363
--- /dev/null
+++ b/quiche/quic/core/congestion_control/send_algorithm_test.cc
@@ -0,0 +1,373 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Use the initial CWND of 10, as 32 is too much for the test network.
+const uint32_t kInitialCongestionWindowPackets = 10;
+
+// Test network parameters.  Here, the topology of the network is:
+//
+//           QUIC Sender
+//               |
+//               |  <-- local link
+//               |
+//        Network switch
+//               *  <-- the bottleneck queue in the direction
+//               |          of the receiver
+//               |
+//               |  <-- test link
+//               |
+//               |
+//           Receiver
+//
+// When setting the bandwidth of the local link and test link, choose
+// a bandwidth lower than 20Mbps, as the clock-granularity of the
+// simulator can only handle a granularity of 1us.
+
+// Default settings between the switch and the sender.
+const QuicBandwidth kLocalLinkBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10000);
+const QuicTime::Delta kLocalPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(2);
+
+// Wired network settings.  A typical desktop network setup, a
+// high-bandwidth, 30ms test link to the receiver.
+const QuicBandwidth kTestLinkWiredBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(4000);
+const QuicTime::Delta kTestLinkWiredPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(50);
+const QuicTime::Delta kTestWiredTransferTime =
+    kTestLinkWiredBandwidth.TransferTime(kMaxOutgoingPacketSize) +
+    kLocalLinkBandwidth.TransferTime(kMaxOutgoingPacketSize);
+const QuicTime::Delta kTestWiredRtt =
+    (kTestLinkWiredPropagationDelay + kLocalPropagationDelay +
+     kTestWiredTransferTime) *
+    2;
+const QuicByteCount kTestWiredBdp = kTestWiredRtt * kTestLinkWiredBandwidth;
+
+// Small BDP, Bandwidth-policed network settings.  In this scenario,
+// the receiver has a low-bandwidth, short propagation-delay link,
+// resulting in a small BDP.  We model the policer by setting the
+// queue size to only one packet.
+const QuicBandwidth kTestLinkLowBdpBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(200);
+const QuicTime::Delta kTestLinkLowBdpPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(50);
+const QuicByteCount kTestPolicerQueue = kMaxOutgoingPacketSize;
+
+// Satellite network settings.  In a satellite network, the bottleneck
+// buffer is typically sized for non-satellite links , but the
+// propagation delay of the test link to the receiver is as much as a
+// quarter second.
+const QuicTime::Delta kTestSatellitePropagationDelay =
+    QuicTime::Delta::FromMilliseconds(250);
+
+// Cellular scenarios.  In a cellular network, the bottleneck queue at
+// the edge of the network can be as great as 3MB.
+const QuicBandwidth kTestLink2GBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(100);
+const QuicBandwidth kTestLink3GBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(1500);
+const QuicByteCount kCellularQueue = 3 * 1024 * 1024;
+const QuicTime::Delta kTestCellularPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(40);
+
+// Small RTT scenario, below the per-ack-update threshold of 30ms.
+const QuicTime::Delta kTestLinkSmallRTTDelay =
+    QuicTime::Delta::FromMilliseconds(10);
+
+const char* CongestionControlTypeToString(CongestionControlType cc_type) {
+  switch (cc_type) {
+    case kCubicBytes:
+      return "CUBIC_BYTES";
+    case kRenoBytes:
+      return "RENO_BYTES";
+    case kBBR:
+      return "BBR";
+    case kPCC:
+      return "PCC";
+    default:
+      QUIC_DLOG(FATAL) << "Unexpected CongestionControlType";
+      return nullptr;
+  }
+}
+
+struct TestParams {
+  explicit TestParams(CongestionControlType congestion_control_type)
+      : congestion_control_type(congestion_control_type) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "{ congestion_control_type: "
+       << CongestionControlTypeToString(p.congestion_control_type);
+    os << " }";
+    return os;
+  }
+
+  const CongestionControlType congestion_control_type;
+};
+
+std::string TestParamToString(
+    const testing::TestParamInfo<TestParams>& params) {
+  return absl::StrCat(
+      CongestionControlTypeToString(params.param.congestion_control_type), "_");
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const CongestionControlType congestion_control_type :
+       {kBBR, kCubicBytes, kRenoBytes, kPCC}) {
+    params.push_back(TestParams(congestion_control_type));
+  }
+  return params;
+}
+
+}  // namespace
+
+class SendAlgorithmTest : public QuicTestWithParam<TestParams> {
+ protected:
+  SendAlgorithmTest()
+      : simulator_(),
+        quic_sender_(&simulator_,
+                     "QUIC sender",
+                     "Receiver",
+                     Perspective::IS_CLIENT,
+                     TestConnectionId()),
+        receiver_(&simulator_,
+                  "Receiver",
+                  "QUIC sender",
+                  Perspective::IS_SERVER,
+                  TestConnectionId()) {
+    rtt_stats_ = quic_sender_.connection()->sent_packet_manager().GetRttStats();
+    sender_ = SendAlgorithmInterface::Create(
+        simulator_.GetClock(), rtt_stats_,
+        QuicSentPacketManagerPeer::GetUnackedPacketMap(
+            QuicConnectionPeer::GetSentPacketManager(
+                quic_sender_.connection())),
+        GetParam().congestion_control_type, &random_, &stats_,
+        kInitialCongestionWindowPackets, nullptr);
+    quic_sender_.RecordTrace();
+
+    QuicConnectionPeer::SetSendAlgorithm(quic_sender_.connection(), sender_);
+    const int kTestMaxPacketSize = 1350;
+    quic_sender_.connection()->SetMaxPacketLength(kTestMaxPacketSize);
+    clock_ = simulator_.GetClock();
+    simulator_.set_random_generator(&random_);
+
+    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+    random_.set_seed(seed);
+    QUIC_LOG(INFO) << "SendAlgorithmTest simulator set up.  Seed: " << seed;
+  }
+
+  // Creates a simulated network, with default settings between the
+  // sender and the switch and the given settings from the switch to
+  // the receiver.
+  void CreateSetup(const QuicBandwidth& test_bandwidth,
+                   const QuicTime::Delta& test_link_delay,
+                   QuicByteCount bottleneck_queue_length) {
+    switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch", 8,
+                                                  bottleneck_queue_length);
+    quic_sender_link_ = std::make_unique<simulator::SymmetricLink>(
+        &quic_sender_, switch_->port(1), kLocalLinkBandwidth,
+        kLocalPropagationDelay);
+    receiver_link_ = std::make_unique<simulator::SymmetricLink>(
+        &receiver_, switch_->port(2), test_bandwidth, test_link_delay);
+  }
+
+  void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta deadline) {
+    quic_sender_.AddBytesToTransfer(transfer_size);
+    bool simulator_result = simulator_.RunUntilOrTimeout(
+        [this]() { return quic_sender_.bytes_to_transfer() == 0; }, deadline);
+    EXPECT_TRUE(simulator_result)
+        << "Simple transfer failed.  Bytes remaining: "
+        << quic_sender_.bytes_to_transfer();
+  }
+
+  void SendBursts(size_t number_of_bursts,
+                  QuicByteCount bytes,
+                  QuicTime::Delta rtt,
+                  QuicTime::Delta wait_time) {
+    ASSERT_EQ(0u, quic_sender_.bytes_to_transfer());
+    for (size_t i = 0; i < number_of_bursts; i++) {
+      quic_sender_.AddBytesToTransfer(bytes);
+
+      // Transfer data and wait for three seconds between each transfer.
+      simulator_.RunFor(wait_time);
+
+      // Ensure the connection did not time out.
+      ASSERT_TRUE(quic_sender_.connection()->connected());
+      ASSERT_TRUE(receiver_.connection()->connected());
+    }
+
+    simulator_.RunFor(wait_time + rtt);
+    EXPECT_EQ(0u, quic_sender_.bytes_to_transfer());
+  }
+
+  // Estimates the elapsed time for a given transfer size, given the
+  // bottleneck bandwidth and link propagation delay.
+  QuicTime::Delta EstimatedElapsedTime(
+      QuicByteCount transfer_size_bytes,
+      QuicBandwidth test_link_bandwidth,
+      const QuicTime::Delta& test_link_delay) const {
+    return test_link_bandwidth.TransferTime(transfer_size_bytes) +
+           2 * test_link_delay;
+  }
+
+  QuicTime QuicSenderStartTime() {
+    return quic_sender_.connection()->GetStats().connection_creation_time;
+  }
+
+  void PrintTransferStats() {
+    const QuicConnectionStats& stats = quic_sender_.connection()->GetStats();
+    QUIC_LOG(INFO) << "Summary for scenario " << GetParam();
+    QUIC_LOG(INFO) << "Sender stats is " << stats;
+    const double rtx_rate =
+        static_cast<double>(stats.bytes_retransmitted) / stats.bytes_sent;
+    QUIC_LOG(INFO) << "Retransmit rate (num_rtx/num_total_sent): " << rtx_rate;
+    QUIC_LOG(INFO) << "Connection elapsed time: "
+                   << (clock_->Now() - QuicSenderStartTime()).ToMilliseconds()
+                   << " (ms)";
+  }
+
+  simulator::Simulator simulator_;
+  simulator::QuicEndpoint quic_sender_;
+  simulator::QuicEndpoint receiver_;
+  std::unique_ptr<simulator::Switch> switch_;
+  std::unique_ptr<simulator::SymmetricLink> quic_sender_link_;
+  std::unique_ptr<simulator::SymmetricLink> receiver_link_;
+  QuicConnectionStats stats_;
+
+  SimpleRandom random_;
+
+  // Owned by different components of the connection.
+  const QuicClock* clock_;
+  const RttStats* rtt_stats_;
+  SendAlgorithmInterface* sender_;
+};
+
+INSTANTIATE_TEST_SUITE_P(SendAlgorithmTests,
+                         SendAlgorithmTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         TestParamToString);
+
+// Test a simple long data transfer in the default setup.
+TEST_P(SendAlgorithmTest, SimpleWiredNetworkTransfer) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
+              kTestWiredBdp);
+  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
+                           kTestLinkWiredPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, LowBdpPolicedNetworkTransfer) {
+  CreateSetup(kTestLinkLowBdpBandwidth, kTestLinkLowBdpPropagationDelay,
+              kTestPolicerQueue);
+  const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkLowBdpBandwidth,
+                           kTestLinkLowBdpPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, AppLimitedBurstsOverWiredNetwork) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestLinkWiredPropagationDelay,
+              kTestWiredBdp);
+  const QuicByteCount kBurstSizeBytes = 512;
+  const int kNumBursts = 20;
+  const QuicTime::Delta kWaitTime = QuicTime::Delta::FromSeconds(3);
+  SendBursts(kNumBursts, kBurstSizeBytes, kTestWiredRtt, kWaitTime);
+  PrintTransferStats();
+
+  const QuicTime::Delta estimated_burst_time =
+      EstimatedElapsedTime(kBurstSizeBytes, kTestLinkWiredBandwidth,
+                           kTestLinkWiredPropagationDelay) +
+      kWaitTime;
+  const QuicTime::Delta max_elapsed_time =
+      kNumBursts * estimated_burst_time + kWaitTime;
+  const QuicTime::Delta actual_elapsed_time =
+      clock_->Now() - QuicSenderStartTime();
+  EXPECT_GE(max_elapsed_time, actual_elapsed_time);
+}
+
+TEST_P(SendAlgorithmTest, SatelliteNetworkTransfer) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestSatellitePropagationDelay,
+              kTestWiredBdp);
+  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
+                           kTestSatellitePropagationDelay) *
+      1.25;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, 2GNetworkTransfer) {
+  CreateSetup(kTestLink2GBandwidth, kTestCellularPropagationDelay,
+              kCellularQueue);
+  const QuicByteCount kTransferSizeBytes = 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLink2GBandwidth,
+                           kTestCellularPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, 3GNetworkTransfer) {
+  CreateSetup(kTestLink3GBandwidth, kTestCellularPropagationDelay,
+              kCellularQueue);
+  const QuicByteCount kTransferSizeBytes = 5 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLink3GBandwidth,
+                           kTestCellularPropagationDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+TEST_P(SendAlgorithmTest, LowRTTTransfer) {
+  CreateSetup(kTestLinkWiredBandwidth, kTestLinkSmallRTTDelay, kCellularQueue);
+
+  const QuicByteCount kTransferSizeBytes = 12 * 1024 * 1024;
+  const QuicTime::Delta maximum_elapsed_time =
+      EstimatedElapsedTime(kTransferSizeBytes, kTestLinkWiredBandwidth,
+                           kTestLinkSmallRTTDelay) *
+      1.2;
+  DoSimpleTransfer(kTransferSizeBytes, maximum_elapsed_time);
+  PrintTransferStats();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
new file mode 100644
index 0000000..44afb90
--- /dev/null
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -0,0 +1,431 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/prr_sender.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+// Constants based on TCP defaults.
+const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
+const float kRenoBeta = 0.7f;  // Reno backoff factor.
+// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
+// fast retransmission.
+const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
+}  // namespace
+
+TcpCubicSenderBytes::TcpCubicSenderBytes(
+    const QuicClock* clock,
+    const RttStats* rtt_stats,
+    bool reno,
+    QuicPacketCount initial_tcp_congestion_window,
+    QuicPacketCount max_congestion_window,
+    QuicConnectionStats* stats)
+    : rtt_stats_(rtt_stats),
+      stats_(stats),
+      reno_(reno),
+      num_connections_(kDefaultNumConnections),
+      min4_mode_(false),
+      last_cutback_exited_slowstart_(false),
+      slow_start_large_reduction_(false),
+      no_prr_(false),
+      cubic_(clock),
+      num_acked_packets_(0),
+      congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
+      min_congestion_window_(kDefaultMinimumCongestionWindow),
+      max_congestion_window_(max_congestion_window * kDefaultTCPMSS),
+      slowstart_threshold_(max_congestion_window * kDefaultTCPMSS),
+      initial_tcp_congestion_window_(initial_tcp_congestion_window *
+                                     kDefaultTCPMSS),
+      initial_max_tcp_congestion_window_(max_congestion_window *
+                                         kDefaultTCPMSS),
+      min_slow_start_exit_window_(min_congestion_window_) {}
+
+TcpCubicSenderBytes::~TcpCubicSenderBytes() {}
+
+void TcpCubicSenderBytes::SetFromConfig(const QuicConfig& config,
+                                        Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER) {
+    if (!GetQuicReloadableFlag(quic_unified_iw_options)) {
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(3);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(10);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(20);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
+        // Initial window experiment.
+        SetInitialCongestionWindowInPackets(50);
+      }
+      if (config.HasReceivedConnectionOptions() &&
+          ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
+        // Min CWND experiment.
+        SetMinCongestionWindowInPackets(1);
+      }
+    }
+    if (config.HasReceivedConnectionOptions() &&
+        ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
+      // Min CWND of 4 experiment.
+      min4_mode_ = true;
+      SetMinCongestionWindowInPackets(1);
+    }
+    if (config.HasReceivedConnectionOptions() &&
+        ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
+      // Slow Start Fast Exit experiment.
+      slow_start_large_reduction_ = true;
+    }
+    if (config.HasReceivedConnectionOptions() &&
+        ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) {
+      // Use unity pacing instead of PRR.
+      no_prr_ = true;
+    }
+  }
+}
+
+void TcpCubicSenderBytes::AdjustNetworkParameters(const NetworkParams& params) {
+  if (params.bandwidth.IsZero() || params.rtt.IsZero()) {
+    return;
+  }
+  SetCongestionWindowFromBandwidthAndRtt(params.bandwidth, params.rtt);
+}
+
+float TcpCubicSenderBytes::RenoBeta() const {
+  // kNConnectionBeta is the backoff factor after loss for our N-connection
+  // emulation, which emulates the effective backoff of an ensemble of N
+  // TCP-Reno connections on a single loss event. The effective multiplier is
+  // computed as:
+  return (num_connections_ - 1 + kRenoBeta) / num_connections_;
+}
+
+void TcpCubicSenderBytes::OnCongestionEvent(
+    bool rtt_updated,
+    QuicByteCount prior_in_flight,
+    QuicTime event_time,
+    const AckedPacketVector& acked_packets,
+    const LostPacketVector& lost_packets) {
+  if (rtt_updated && InSlowStart() &&
+      hybrid_slow_start_.ShouldExitSlowStart(
+          rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
+          GetCongestionWindow() / kDefaultTCPMSS)) {
+    ExitSlowstart();
+  }
+  for (const LostPacket& lost_packet : lost_packets) {
+    OnPacketLost(lost_packet.packet_number, lost_packet.bytes_lost,
+                 prior_in_flight);
+  }
+  for (const AckedPacket& acked_packet : acked_packets) {
+    OnPacketAcked(acked_packet.packet_number, acked_packet.bytes_acked,
+                  prior_in_flight, event_time);
+  }
+}
+
+void TcpCubicSenderBytes::OnPacketAcked(QuicPacketNumber acked_packet_number,
+                                        QuicByteCount acked_bytes,
+                                        QuicByteCount prior_in_flight,
+                                        QuicTime event_time) {
+  largest_acked_packet_number_.UpdateMax(acked_packet_number);
+  if (InRecovery()) {
+    if (!no_prr_) {
+      // PRR is used when in recovery.
+      prr_.OnPacketAcked(acked_bytes);
+    }
+    return;
+  }
+  MaybeIncreaseCwnd(acked_packet_number, acked_bytes, prior_in_flight,
+                    event_time);
+  if (InSlowStart()) {
+    hybrid_slow_start_.OnPacketAcked(acked_packet_number);
+  }
+}
+
+void TcpCubicSenderBytes::OnPacketSent(
+    QuicTime /*sent_time*/,
+    QuicByteCount /*bytes_in_flight*/,
+    QuicPacketNumber packet_number,
+    QuicByteCount bytes,
+    HasRetransmittableData is_retransmittable) {
+  if (InSlowStart()) {
+    ++(stats_->slowstart_packets_sent);
+  }
+
+  if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
+    return;
+  }
+  if (InRecovery()) {
+    // PRR is used when in recovery.
+    prr_.OnPacketSent(bytes);
+  }
+  QUICHE_DCHECK(!largest_sent_packet_number_.IsInitialized() ||
+                largest_sent_packet_number_ < packet_number);
+  largest_sent_packet_number_ = packet_number;
+  hybrid_slow_start_.OnPacketSent(packet_number);
+}
+
+bool TcpCubicSenderBytes::CanSend(QuicByteCount bytes_in_flight) {
+  if (!no_prr_ && InRecovery()) {
+    // PRR is used when in recovery.
+    return prr_.CanSend(GetCongestionWindow(), bytes_in_flight,
+                        GetSlowStartThreshold());
+  }
+  if (GetCongestionWindow() > bytes_in_flight) {
+    return true;
+  }
+  if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
+    return true;
+  }
+  return false;
+}
+
+QuicBandwidth TcpCubicSenderBytes::PacingRate(
+    QuicByteCount /* bytes_in_flight */) const {
+  // We pace at twice the rate of the underlying sender's bandwidth estimate
+  // during slow start and 1.25x during congestion avoidance to ensure pacing
+  // doesn't prevent us from filling the window.
+  QuicTime::Delta srtt = rtt_stats_->SmoothedOrInitialRtt();
+  const QuicBandwidth bandwidth =
+      QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
+  return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
+}
+
+QuicBandwidth TcpCubicSenderBytes::BandwidthEstimate() const {
+  QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
+  if (srtt.IsZero()) {
+    // If we haven't measured an rtt, the bandwidth estimate is unknown.
+    return QuicBandwidth::Zero();
+  }
+  return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
+}
+
+bool TcpCubicSenderBytes::InSlowStart() const {
+  return GetCongestionWindow() < GetSlowStartThreshold();
+}
+
+bool TcpCubicSenderBytes::IsCwndLimited(QuicByteCount bytes_in_flight) const {
+  const QuicByteCount congestion_window = GetCongestionWindow();
+  if (bytes_in_flight >= congestion_window) {
+    return true;
+  }
+  const QuicByteCount available_bytes = congestion_window - bytes_in_flight;
+  const bool slow_start_limited =
+      InSlowStart() && bytes_in_flight > congestion_window / 2;
+  return slow_start_limited || available_bytes <= kMaxBurstBytes;
+}
+
+bool TcpCubicSenderBytes::InRecovery() const {
+  return largest_acked_packet_number_.IsInitialized() &&
+         largest_sent_at_last_cutback_.IsInitialized() &&
+         largest_acked_packet_number_ <= largest_sent_at_last_cutback_;
+}
+
+bool TcpCubicSenderBytes::ShouldSendProbingPacket() const {
+  return false;
+}
+
+void TcpCubicSenderBytes::OnRetransmissionTimeout(bool packets_retransmitted) {
+  largest_sent_at_last_cutback_.Clear();
+  if (!packets_retransmitted) {
+    return;
+  }
+  hybrid_slow_start_.Restart();
+  HandleRetransmissionTimeout();
+}
+
+std::string TcpCubicSenderBytes::GetDebugState() const {
+  return "";
+}
+
+void TcpCubicSenderBytes::OnApplicationLimited(
+    QuicByteCount /*bytes_in_flight*/) {}
+
+void TcpCubicSenderBytes::SetCongestionWindowFromBandwidthAndRtt(
+    QuicBandwidth bandwidth,
+    QuicTime::Delta rtt) {
+  QuicByteCount new_congestion_window = bandwidth.ToBytesPerPeriod(rtt);
+  // Limit new CWND if needed.
+  congestion_window_ =
+      std::max(min_congestion_window_,
+               std::min(new_congestion_window,
+                        kMaxResumptionCongestionWindow * kDefaultTCPMSS));
+}
+
+void TcpCubicSenderBytes::SetInitialCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  congestion_window_ = congestion_window * kDefaultTCPMSS;
+}
+
+void TcpCubicSenderBytes::SetMinCongestionWindowInPackets(
+    QuicPacketCount congestion_window) {
+  min_congestion_window_ = congestion_window * kDefaultTCPMSS;
+}
+
+void TcpCubicSenderBytes::SetNumEmulatedConnections(int num_connections) {
+  num_connections_ = std::max(1, num_connections);
+  cubic_.SetNumConnections(num_connections_);
+}
+
+void TcpCubicSenderBytes::ExitSlowstart() {
+  slowstart_threshold_ = congestion_window_;
+}
+
+void TcpCubicSenderBytes::OnPacketLost(QuicPacketNumber packet_number,
+                                       QuicByteCount lost_bytes,
+                                       QuicByteCount prior_in_flight) {
+  // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
+  // already sent should be treated as a single loss event, since it's expected.
+  if (largest_sent_at_last_cutback_.IsInitialized() &&
+      packet_number <= largest_sent_at_last_cutback_) {
+    if (last_cutback_exited_slowstart_) {
+      ++stats_->slowstart_packets_lost;
+      stats_->slowstart_bytes_lost += lost_bytes;
+      if (slow_start_large_reduction_) {
+        // Reduce congestion window by lost_bytes for every loss.
+        congestion_window_ = std::max(congestion_window_ - lost_bytes,
+                                      min_slow_start_exit_window_);
+        slowstart_threshold_ = congestion_window_;
+      }
+    }
+    QUIC_DVLOG(1) << "Ignoring loss for largest_missing:" << packet_number
+                  << " because it was sent prior to the last CWND cutback.";
+    return;
+  }
+  ++stats_->tcp_loss_events;
+  last_cutback_exited_slowstart_ = InSlowStart();
+  if (InSlowStart()) {
+    ++stats_->slowstart_packets_lost;
+  }
+
+  if (!no_prr_) {
+    prr_.OnPacketLost(prior_in_flight);
+  }
+
+  // TODO(b/77268641): Separate out all of slow start into a separate class.
+  if (slow_start_large_reduction_ && InSlowStart()) {
+    QUICHE_DCHECK_LT(kDefaultTCPMSS, congestion_window_);
+    if (congestion_window_ >= 2 * initial_tcp_congestion_window_) {
+      min_slow_start_exit_window_ = congestion_window_ / 2;
+    }
+    congestion_window_ = congestion_window_ - kDefaultTCPMSS;
+  } else if (reno_) {
+    congestion_window_ = congestion_window_ * RenoBeta();
+  } else {
+    congestion_window_ =
+        cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
+  }
+  if (congestion_window_ < min_congestion_window_) {
+    congestion_window_ = min_congestion_window_;
+  }
+  slowstart_threshold_ = congestion_window_;
+  largest_sent_at_last_cutback_ = largest_sent_packet_number_;
+  // Reset packet count from congestion avoidance mode. We start counting again
+  // when we're out of recovery.
+  num_acked_packets_ = 0;
+  QUIC_DVLOG(1) << "Incoming loss; congestion window: " << congestion_window_
+                << " slowstart threshold: " << slowstart_threshold_;
+}
+
+QuicByteCount TcpCubicSenderBytes::GetCongestionWindow() const {
+  return congestion_window_;
+}
+
+QuicByteCount TcpCubicSenderBytes::GetSlowStartThreshold() const {
+  return slowstart_threshold_;
+}
+
+// Called when we receive an ack. Normal TCP tracks how many packets one ack
+// represents, but quic has a separate ack for each packet.
+void TcpCubicSenderBytes::MaybeIncreaseCwnd(
+    QuicPacketNumber /*acked_packet_number*/,
+    QuicByteCount acked_bytes,
+    QuicByteCount prior_in_flight,
+    QuicTime event_time) {
+  QUIC_BUG_IF(quic_bug_10439_1, InRecovery())
+      << "Never increase the CWND during recovery.";
+  // Do not increase the congestion window unless the sender is close to using
+  // the current window.
+  if (!IsCwndLimited(prior_in_flight)) {
+    cubic_.OnApplicationLimited();
+    return;
+  }
+  if (congestion_window_ >= max_congestion_window_) {
+    return;
+  }
+  if (InSlowStart()) {
+    // TCP slow start, exponential growth, increase by one for each ACK.
+    congestion_window_ += kDefaultTCPMSS;
+    QUIC_DVLOG(1) << "Slow start; congestion window: " << congestion_window_
+                  << " slowstart threshold: " << slowstart_threshold_;
+    return;
+  }
+  // Congestion avoidance.
+  if (reno_) {
+    // Classic Reno congestion avoidance.
+    ++num_acked_packets_;
+    // Divide by num_connections to smoothly increase the CWND at a faster rate
+    // than conventional Reno.
+    if (num_acked_packets_ * num_connections_ >=
+        congestion_window_ / kDefaultTCPMSS) {
+      congestion_window_ += kDefaultTCPMSS;
+      num_acked_packets_ = 0;
+    }
+
+    QUIC_DVLOG(1) << "Reno; congestion window: " << congestion_window_
+                  << " slowstart threshold: " << slowstart_threshold_
+                  << " congestion window count: " << num_acked_packets_;
+  } else {
+    congestion_window_ = std::min(
+        max_congestion_window_,
+        cubic_.CongestionWindowAfterAck(acked_bytes, congestion_window_,
+                                        rtt_stats_->min_rtt(), event_time));
+    QUIC_DVLOG(1) << "Cubic; congestion window: " << congestion_window_
+                  << " slowstart threshold: " << slowstart_threshold_;
+  }
+}
+
+void TcpCubicSenderBytes::HandleRetransmissionTimeout() {
+  cubic_.ResetCubicState();
+  slowstart_threshold_ = congestion_window_ / 2;
+  congestion_window_ = min_congestion_window_;
+}
+
+void TcpCubicSenderBytes::OnConnectionMigration() {
+  hybrid_slow_start_.Restart();
+  prr_ = PrrSender();
+  largest_sent_packet_number_.Clear();
+  largest_acked_packet_number_.Clear();
+  largest_sent_at_last_cutback_.Clear();
+  last_cutback_exited_slowstart_ = false;
+  cubic_.ResetCubicState();
+  num_acked_packets_ = 0;
+  congestion_window_ = initial_tcp_congestion_window_;
+  max_congestion_window_ = initial_max_tcp_congestion_window_;
+  slowstart_threshold_ = initial_max_tcp_congestion_window_;
+}
+
+CongestionControlType TcpCubicSenderBytes::GetCongestionControlType() const {
+  return reno_ ? kRenoBytes : kCubicBytes;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
new file mode 100644
index 0000000..aac0c0a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -0,0 +1,175 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
+
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/cubic_bytes.h"
+#include "quiche/quic/core/congestion_control/hybrid_slow_start.h"
+#include "quiche/quic/core/congestion_control/prr_sender.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class RttStats;
+
+// Maximum window to allow when doing bandwidth resumption.
+const QuicPacketCount kMaxResumptionCongestionWindow = 200;
+
+namespace test {
+class TcpCubicSenderBytesPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
+ public:
+  TcpCubicSenderBytes(const QuicClock* clock,
+                      const RttStats* rtt_stats,
+                      bool reno,
+                      QuicPacketCount initial_tcp_congestion_window,
+                      QuicPacketCount max_congestion_window,
+                      QuicConnectionStats* stats);
+  TcpCubicSenderBytes(const TcpCubicSenderBytes&) = delete;
+  TcpCubicSenderBytes& operator=(const TcpCubicSenderBytes&) = delete;
+  ~TcpCubicSenderBytes() override;
+
+  // Start implementation of SendAlgorithmInterface.
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+  void ApplyConnectionOptions(
+      const QuicTagVector& /*connection_options*/) override {}
+  void AdjustNetworkParameters(const NetworkParams& params) override;
+  void SetNumEmulatedConnections(int num_connections);
+  void SetInitialCongestionWindowInPackets(
+      QuicPacketCount congestion_window) override;
+  void OnConnectionMigration() override;
+  void OnCongestionEvent(bool rtt_updated,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time,
+                         const AckedPacketVector& acked_packets,
+                         const LostPacketVector& lost_packets) override;
+  void OnPacketSent(QuicTime sent_time,
+                    QuicByteCount bytes_in_flight,
+                    QuicPacketNumber packet_number,
+                    QuicByteCount bytes,
+                    HasRetransmittableData is_retransmittable) override;
+  void OnPacketNeutered(QuicPacketNumber /*packet_number*/) override {}
+  void OnRetransmissionTimeout(bool packets_retransmitted) override;
+  bool CanSend(QuicByteCount bytes_in_flight) override;
+  QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+  QuicBandwidth BandwidthEstimate() const override;
+  bool HasGoodBandwidthEstimateForResumption() const override { return false; }
+  QuicByteCount GetCongestionWindow() const override;
+  QuicByteCount GetSlowStartThreshold() const override;
+  CongestionControlType GetCongestionControlType() const override;
+  bool InSlowStart() const override;
+  bool InRecovery() const override;
+  bool ShouldSendProbingPacket() const override;
+  std::string GetDebugState() const override;
+  void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
+  void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
+  // End implementation of SendAlgorithmInterface.
+
+  QuicByteCount min_congestion_window() const { return min_congestion_window_; }
+
+ protected:
+  // Compute the TCP Reno beta based on the current number of connections.
+  float RenoBeta() const;
+
+  bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
+
+  // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
+  void OnPacketAcked(QuicPacketNumber acked_packet_number,
+                     QuicByteCount acked_bytes,
+                     QuicByteCount prior_in_flight,
+                     QuicTime event_time);
+  void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
+                                              QuicTime::Delta rtt);
+  void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
+  void ExitSlowstart();
+  void OnPacketLost(QuicPacketNumber packet_number, QuicByteCount lost_bytes,
+                    QuicByteCount prior_in_flight);
+  void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
+                         QuicByteCount acked_bytes,
+                         QuicByteCount prior_in_flight,
+                         QuicTime event_time);
+  void HandleRetransmissionTimeout();
+
+ private:
+  friend class test::TcpCubicSenderBytesPeer;
+
+  HybridSlowStart hybrid_slow_start_;
+  PrrSender prr_;
+  const RttStats* rtt_stats_;
+  QuicConnectionStats* stats_;
+
+  // If true, Reno congestion control is used instead of Cubic.
+  const bool reno_;
+
+  // Number of connections to simulate.
+  uint32_t num_connections_;
+
+  // Track the largest packet that has been sent.
+  QuicPacketNumber largest_sent_packet_number_;
+
+  // Track the largest packet that has been acked.
+  QuicPacketNumber largest_acked_packet_number_;
+
+  // Track the largest packet number outstanding when a CWND cutback occurs.
+  QuicPacketNumber largest_sent_at_last_cutback_;
+
+  // Whether to use 4 packets as the actual min, but pace lower.
+  bool min4_mode_;
+
+  // Whether the last loss event caused us to exit slowstart.
+  // Used for stats collection of slowstart_packets_lost
+  bool last_cutback_exited_slowstart_;
+
+  // When true, exit slow start with large cutback of congestion window.
+  bool slow_start_large_reduction_;
+
+  // When true, use unity pacing instead of PRR.
+  bool no_prr_;
+
+  CubicBytes cubic_;
+
+  // ACK counter for the Reno implementation.
+  uint64_t num_acked_packets_;
+
+  // Congestion window in bytes.
+  QuicByteCount congestion_window_;
+
+  // Minimum congestion window in bytes.
+  QuicByteCount min_congestion_window_;
+
+  // Maximum congestion window in bytes.
+  QuicByteCount max_congestion_window_;
+
+  // Slow start congestion window in bytes, aka ssthresh.
+  QuicByteCount slowstart_threshold_;
+
+  // Initial TCP congestion window in bytes. This variable can only be set when
+  // this algorithm is created.
+  const QuicByteCount initial_tcp_congestion_window_;
+
+  // Initial maximum TCP congestion window in bytes. This variable can only be
+  // set when this algorithm is created.
+  const QuicByteCount initial_max_tcp_congestion_window_;
+
+  // The minimum window when exiting slow start with large reduction.
+  QuicByteCount min_slow_start_exit_window_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BYTES_H_
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
new file mode 100644
index 0000000..bac568a
--- /dev/null
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -0,0 +1,845 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+
+namespace quic {
+namespace test {
+
+// TODO(ianswett): A number of theses tests were written with the assumption of
+// an initial CWND of 10. They have carefully calculated values which should be
+// updated to be based on kInitialCongestionWindow.
+const uint32_t kInitialCongestionWindowPackets = 10;
+const uint32_t kMaxCongestionWindowPackets = 200;
+const uint32_t kDefaultWindowTCP =
+    kInitialCongestionWindowPackets * kDefaultTCPMSS;
+const float kRenoBeta = 0.7f;  // Reno backoff factor.
+
+class TcpCubicSenderBytesPeer : public TcpCubicSenderBytes {
+ public:
+  TcpCubicSenderBytesPeer(const QuicClock* clock, bool reno)
+      : TcpCubicSenderBytes(clock,
+                            &rtt_stats_,
+                            reno,
+                            kInitialCongestionWindowPackets,
+                            kMaxCongestionWindowPackets,
+                            &stats_) {}
+
+  const HybridSlowStart& hybrid_slow_start() const {
+    return hybrid_slow_start_;
+  }
+
+  float GetRenoBeta() const { return RenoBeta(); }
+
+  RttStats rtt_stats_;
+  QuicConnectionStats stats_;
+};
+
+class TcpCubicSenderBytesTest : public QuicTest {
+ protected:
+  TcpCubicSenderBytesTest()
+      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
+        sender_(new TcpCubicSenderBytesPeer(&clock_, true)),
+        packet_number_(1),
+        acked_packet_number_(0),
+        bytes_in_flight_(0) {}
+
+  int SendAvailableSendWindow() {
+    return SendAvailableSendWindow(kDefaultTCPMSS);
+  }
+
+  int SendAvailableSendWindow(QuicPacketLength /*packet_length*/) {
+    // Send as long as TimeUntilSend returns Zero.
+    int packets_sent = 0;
+    bool can_send = sender_->CanSend(bytes_in_flight_);
+    while (can_send) {
+      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
+                            QuicPacketNumber(packet_number_++), kDefaultTCPMSS,
+                            HAS_RETRANSMITTABLE_DATA);
+      ++packets_sent;
+      bytes_in_flight_ += kDefaultTCPMSS;
+      can_send = sender_->CanSend(bytes_in_flight_);
+    }
+    return packets_sent;
+  }
+
+  // Normal is that TCP acks every other segment.
+  void AckNPackets(int n) {
+    sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
+                                  QuicTime::Delta::Zero(), clock_.Now());
+    AckedPacketVector acked_packets;
+    LostPacketVector lost_packets;
+    for (int i = 0; i < n; ++i) {
+      ++acked_packet_number_;
+      acked_packets.push_back(
+          AckedPacket(QuicPacketNumber(acked_packet_number_), kDefaultTCPMSS,
+                      QuicTime::Zero()));
+    }
+    sender_->OnCongestionEvent(true, bytes_in_flight_, clock_.Now(),
+                               acked_packets, lost_packets);
+    bytes_in_flight_ -= n * kDefaultTCPMSS;
+    clock_.AdvanceTime(one_ms_);
+  }
+
+  void LoseNPackets(int n) { LoseNPackets(n, kDefaultTCPMSS); }
+
+  void LoseNPackets(int n, QuicPacketLength packet_length) {
+    AckedPacketVector acked_packets;
+    LostPacketVector lost_packets;
+    for (int i = 0; i < n; ++i) {
+      ++acked_packet_number_;
+      lost_packets.push_back(
+          LostPacket(QuicPacketNumber(acked_packet_number_), packet_length));
+    }
+    sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
+                               acked_packets, lost_packets);
+    bytes_in_flight_ -= n * packet_length;
+  }
+
+  // Does not increment acked_packet_number_.
+  void LosePacket(uint64_t packet_number) {
+    AckedPacketVector acked_packets;
+    LostPacketVector lost_packets;
+    lost_packets.push_back(
+        LostPacket(QuicPacketNumber(packet_number), kDefaultTCPMSS));
+    sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
+                               acked_packets, lost_packets);
+    bytes_in_flight_ -= kDefaultTCPMSS;
+  }
+
+  const QuicTime::Delta one_ms_;
+  MockClock clock_;
+  std::unique_ptr<TcpCubicSenderBytesPeer> sender_;
+  uint64_t packet_number_;
+  uint64_t acked_packet_number_;
+  QuicByteCount bytes_in_flight_;
+};
+
+TEST_F(TcpCubicSenderBytesTest, SimpleSender) {
+  // At startup make sure we are at the default.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Fill the send window with data, then verify that we can't send.
+  SendAvailableSendWindow();
+  EXPECT_FALSE(sender_->CanSend(sender_->GetCongestionWindow()));
+}
+
+TEST_F(TcpCubicSenderBytesTest, ApplicationLimitedSlowStart) {
+  // Send exactly 10 packets and ensure the CWND ends at 14 packets.
+  const int kNumberOfAcks = 5;
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+
+  SendAvailableSendWindow();
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    AckNPackets(2);
+  }
+  QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
+  // It's expected 2 acks will arrive when the bytes_in_flight are greater than
+  // half the CWND.
+  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
+}
+
+TEST_F(TcpCubicSenderBytesTest, ExponentialSlowStart) {
+  const int kNumberOfAcks = 20;
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+  EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->CanSend(0));
+
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  const QuicByteCount cwnd = sender_->GetCongestionWindow();
+  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
+  EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
+                cwnd, sender_->rtt_stats_.smoothed_rtt()),
+            sender_->BandwidthEstimate());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLoss) {
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start.
+  LoseNPackets(1);
+  size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Recovery phase. We need to ack every packet in the recovery window before
+  // we exit recovery.
+  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+  QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
+  AckNPackets(packets_in_recovery_window);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // We need to ack an entire window before we increase CWND by 1.
+  AckNPackets(number_of_packets_in_window - 2);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should increase cwnd by 1.
+  AckNPackets(1);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Now RTO and ensure slow start gets reset.
+  EXPECT_TRUE(sender_->hybrid_slow_start().started());
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithLargeReduction) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kSSLR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = (kDefaultWindowTCP / (2 * kDefaultTCPMSS)) - 1;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start. We should now have fallen out of
+  // slow start with a window reduced by 1.
+  LoseNPackets(1);
+  expected_send_window -= kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose 5 packets in recovery and verify that congestion window is reduced
+  // further.
+  LoseNPackets(5);
+  expected_send_window -= 5 * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  // Lose another 10 packets and ensure it reduces below half the peak CWND,
+  // because we never acked the full IW.
+  LoseNPackets(10);
+  expected_send_window -= 10 * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
+
+  // Recovery phase. We need to ack every packet in the recovery window before
+  // we exit recovery.
+  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+  QUIC_DLOG(INFO) << "number_packets: " << number_of_packets_in_window;
+  AckNPackets(packets_in_recovery_window);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // We need to ack an entire window before we increase CWND by 1.
+  AckNPackets(number_of_packets_in_window - 1);
+  SendAvailableSendWindow();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should increase cwnd by 1.
+  AckNPackets(1);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Now RTO and ensure slow start gets reset.
+  EXPECT_TRUE(sender_->hybrid_slow_start().started());
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartHalfPacketLossWithLargeReduction) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kSSLR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window in half sized packets.
+    SendAvailableSendWindow(kDefaultTCPMSS / 2);
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow(kDefaultTCPMSS / 2);
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start. We should now have fallen out of
+  // slow start with a window reduced by 1.
+  LoseNPackets(1);
+  expected_send_window -= kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose 10 packets in recovery and verify that congestion window is reduced
+  // by 5 packets.
+  LoseNPackets(10, kDefaultTCPMSS / 2);
+  expected_send_window -= 5 * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossWithMaxHalfReduction) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kSSLR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = kInitialCongestionWindowPackets / 2;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose a packet to exit slow start. We should now have fallen out of
+  // slow start with a window reduced by 1.
+  LoseNPackets(1);
+  expected_send_window -= kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose half the outstanding packets in recovery and verify the congestion
+  // window is only reduced by a max of half.
+  LoseNPackets(kNumberOfAcks * 2);
+  expected_send_window -= (kNumberOfAcks * 2 - 1) * kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  LoseNPackets(5);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, NoPRRWhenLessThanOnePacketInFlight) {
+  SendAvailableSendWindow();
+  LoseNPackets(kInitialCongestionWindowPackets - 1);
+  AckNPackets(1);
+  // PRR will allow 2 packets for every ack during recovery.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+  // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
+  // PRR should now allow a packet to be sent, even though prr's state variables
+  // believe it has sent enough packets.
+  EXPECT_TRUE(sender_->CanSend(0));
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartPacketLossPRR) {
+  sender_->SetNumEmulatedConnections(1);
+  // Test based on the first example in RFC6937.
+  // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
+  const int kNumberOfAcks = 5;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  size_t send_window_before_loss = expected_send_window;
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Testing TCP proportional rate reduction.
+  // We should send packets paced over the received acks for the remaining
+  // outstanding packets. The number of packets before we exit recovery is the
+  // original CWND minus the packet that has been lost and the one which
+  // triggered the loss.
+  size_t remaining_packets_in_recovery =
+      send_window_before_loss / kDefaultTCPMSS - 2;
+
+  for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
+    AckNPackets(1);
+    SendAvailableSendWindow();
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+
+  // We need to ack another window before we increase CWND by 1.
+  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
+  for (size_t i = 0; i < number_of_packets_in_window; ++i) {
+    AckNPackets(1);
+    EXPECT_EQ(1, SendAvailableSendWindow());
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+
+  AckNPackets(1);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SlowStartBurstPacketLossPRR) {
+  sender_->SetNumEmulatedConnections(1);
+  // Test based on the second example in RFC6937, though we also implement
+  // forward acknowledgements, so the first two incoming acks will trigger
+  // PRR immediately.
+  // Ack 20 packets in 10 acks to raise the CWND to 30.
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Lose one more than the congestion window reduction, so that after loss,
+  // bytes_in_flight is lesser than the congestion window.
+  size_t send_window_after_loss = kRenoBeta * expected_send_window;
+  size_t num_packets_to_lose =
+      (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
+  LoseNPackets(num_packets_to_lose);
+  // Immediately after the loss, ensure at least one packet can be sent.
+  // Losses without subsequent acks can occur with timer based loss detection.
+  EXPECT_TRUE(sender_->CanSend(bytes_in_flight_));
+  AckNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Only 2 packets should be allowed to be sent, per PRR-SSRB.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+
+  // Ack the next packet, which triggers another loss.
+  LoseNPackets(1);
+  AckNPackets(1);
+
+  // Send 2 packets to simulate PRR-SSRB.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+
+  // Ack the next packet, which triggers another loss.
+  LoseNPackets(1);
+  AckNPackets(1);
+
+  // Send 2 packets to simulate PRR-SSRB.
+  EXPECT_EQ(2, SendAvailableSendWindow());
+
+  // Exit recovery and return to sending at the new rate.
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    AckNPackets(1);
+    EXPECT_EQ(1, SendAvailableSendWindow());
+  }
+}
+
+TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindow) {
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  // Expect the window to decrease to the minimum once the RTO fires and slow
+  // start threshold to be set to 1/2 of the CWND.
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
+  EXPECT_EQ(5u * kDefaultTCPMSS, sender_->GetSlowStartThreshold());
+}
+
+TEST_F(TcpCubicSenderBytesTest, RTOCongestionWindowNoRetransmission) {
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Expect the window to remain unchanged if the RTO fires but no packets are
+  // retransmitted.
+  sender_->OnRetransmissionTimeout(false);
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, TcpCubicResetEpochOnQuiescence) {
+  const int kMaxCongestionWindow = 50;
+  const QuicByteCount kMaxCongestionWindowBytes =
+      kMaxCongestionWindow * kDefaultTCPMSS;
+  int num_sent = SendAvailableSendWindow();
+
+  // Make sure we fall out of slow start.
+  QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
+  LoseNPackets(1);
+  EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
+
+  // Ack the rest of the outstanding packets to get out of recovery.
+  for (int i = 1; i < num_sent; ++i) {
+    AckNPackets(1);
+  }
+  EXPECT_EQ(0u, bytes_in_flight_);
+
+  // Send a new window of data and ack all; cubic growth should occur.
+  saved_cwnd = sender_->GetCongestionWindow();
+  num_sent = SendAvailableSendWindow();
+  for (int i = 0; i < num_sent; ++i) {
+    AckNPackets(1);
+  }
+  EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
+  EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
+  EXPECT_EQ(0u, bytes_in_flight_);
+
+  // Quiescent time of 100 seconds
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
+
+  // Send new window of data and ack one packet. Cubic epoch should have
+  // been reset; ensure cwnd increase is not dramatic.
+  saved_cwnd = sender_->GetCongestionWindow();
+  SendAvailableSendWindow();
+  AckNPackets(1);
+  EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
+  EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, MultipleLossesInOneWindow) {
+  SendAvailableSendWindow();
+  const QuicByteCount initial_window = sender_->GetCongestionWindow();
+  LosePacket(acked_packet_number_ + 1);
+  const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
+  EXPECT_GT(initial_window, post_loss_window);
+  LosePacket(acked_packet_number_ + 3);
+  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
+  LosePacket(packet_number_ - 1);
+  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
+
+  // Lose a later packet and ensure the window decreases.
+  LosePacket(packet_number_);
+  EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, ConfigureMaxInitialWindow) {
+  SetQuicReloadableFlag(quic_unified_iw_options, false);
+  QuicConfig config;
+
+  // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
+  QuicTagVector options;
+  options.push_back(kIW10);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, SetInitialCongestionWindow) {
+  EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+  sender_->SetInitialCongestionWindowInPackets(3);
+  EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
+  sender_->SetNumEmulatedConnections(2);
+  // Ack 10 packets in 5 acks to raise the CWND to 20.
+  const int kNumberOfAcks = 5;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window = expected_send_window * sender_->GetRenoBeta();
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // No congestion window growth should occur in recovery phase, i.e., until the
+  // currently outstanding 20 packets are acked.
+  for (int i = 0; i < 10; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    EXPECT_TRUE(sender_->InRecovery());
+    AckNPackets(2);
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+  EXPECT_FALSE(sender_->InRecovery());
+
+  // Out of recovery now. Congestion window should not grow for half an RTT.
+  size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
+  SendAvailableSendWindow();
+  AckNPackets(packets_in_send_window / 2 - 2);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should increase congestion window by 1MSS.
+  SendAvailableSendWindow();
+  AckNPackets(2);
+  expected_send_window += kDefaultTCPMSS;
+  packets_in_send_window += 1;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Congestion window should remain steady again for half an RTT.
+  SendAvailableSendWindow();
+  AckNPackets(packets_in_send_window / 2 - 1);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Next ack should cause congestion window to grow by 1MSS.
+  SendAvailableSendWindow();
+  AckNPackets(2);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
+  sender_->SetNumEmulatedConnections(1);
+  // Ack 10 packets in 5 acks to raise the CWND to 20.
+  const int kNumberOfAcks = 5;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // No congestion window growth should occur in recovery phase, i.e., until the
+  // currently outstanding 20 packets are acked.
+  for (int i = 0; i < 10; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    EXPECT_TRUE(sender_->InRecovery());
+    AckNPackets(2);
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+  EXPECT_FALSE(sender_->InRecovery());
+
+  // Out of recovery now. Congestion window should not grow during RTT.
+  for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  }
+
+  // Next ack should cause congestion window to grow by 1MSS.
+  SendAvailableSendWindow();
+  AckNPackets(2);
+  expected_send_window += kDefaultTCPMSS;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, BandwidthResumption) {
+  // Test that when provided with CachedNetworkParameters and opted in to the
+  // bandwidth resumption experiment, that the TcpCubicSenderPackets sets
+  // initial CWND appropriately.
+
+  // Set some common values.
+  const QuicPacketCount kNumberOfPackets = 123;
+  const QuicBandwidth kBandwidthEstimate =
+      QuicBandwidth::FromBytesPerSecond(kNumberOfPackets * kDefaultTCPMSS);
+  const QuicTime::Delta kRttEstimate = QuicTime::Delta::FromSeconds(1);
+
+  SendAlgorithmInterface::NetworkParams network_param;
+  network_param.bandwidth = kBandwidthEstimate;
+  network_param.rtt = kRttEstimate;
+  sender_->AdjustNetworkParameters(network_param);
+  EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+  // Resume with an illegal value of 0 and verify the server ignores it.
+  SendAlgorithmInterface::NetworkParams network_param_no_bandwidth;
+  network_param_no_bandwidth.bandwidth = QuicBandwidth::Zero();
+  network_param_no_bandwidth.rtt = kRttEstimate;
+  sender_->AdjustNetworkParameters(network_param_no_bandwidth);
+  EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+  // Resumed CWND is limited to be in a sensible range.
+  const QuicBandwidth kUnreasonableBandwidth =
+      QuicBandwidth::FromBytesPerSecond((kMaxResumptionCongestionWindow + 1) *
+                                        kDefaultTCPMSS);
+  SendAlgorithmInterface::NetworkParams network_param_large_bandwidth;
+  network_param_large_bandwidth.bandwidth = kUnreasonableBandwidth;
+  network_param_large_bandwidth.rtt = QuicTime::Delta::FromSeconds(1);
+  sender_->AdjustNetworkParameters(network_param_large_bandwidth);
+  EXPECT_EQ(kMaxResumptionCongestionWindow * kDefaultTCPMSS,
+            sender_->GetCongestionWindow());
+}
+
+TEST_F(TcpCubicSenderBytesTest, PaceBelowCWND) {
+  QuicConfig config;
+
+  // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
+  // to 4 to be sent.
+  QuicTagVector options;
+  options.push_back(kMIN4);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  sender_->OnRetransmissionTimeout(true);
+  EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
+  EXPECT_TRUE(sender_->CanSend(kDefaultTCPMSS));
+  EXPECT_TRUE(sender_->CanSend(2 * kDefaultTCPMSS));
+  EXPECT_TRUE(sender_->CanSend(3 * kDefaultTCPMSS));
+  EXPECT_FALSE(sender_->CanSend(4 * kDefaultTCPMSS));
+}
+
+TEST_F(TcpCubicSenderBytesTest, NoPRR) {
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
+  sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  sender_->SetNumEmulatedConnections(1);
+  // Verify that kCOPT: kNPRR allows all packets to be sent, even if only one
+  // ack has been received.
+  QuicTagVector options;
+  options.push_back(kNPRR);
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  SendAvailableSendWindow();
+  LoseNPackets(9);
+  AckNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window.
+  EXPECT_EQ(kRenoBeta * kDefaultWindowTCP, sender_->GetCongestionWindow());
+  const QuicPacketCount window_in_packets =
+      kRenoBeta * kDefaultWindowTCP / kDefaultTCPMSS;
+  const QuicBandwidth expected_pacing_rate =
+      QuicBandwidth::FromBytesAndTimeDelta(kRenoBeta * kDefaultWindowTCP,
+                                           sender_->rtt_stats_.smoothed_rtt());
+  EXPECT_EQ(expected_pacing_rate, sender_->PacingRate(0));
+  EXPECT_EQ(window_in_packets,
+            static_cast<uint64_t>(SendAvailableSendWindow()));
+  EXPECT_EQ(expected_pacing_rate,
+            sender_->PacingRate(kRenoBeta * kDefaultWindowTCP));
+}
+
+TEST_F(TcpCubicSenderBytesTest, ResetAfterConnectionMigration) {
+  // Starts from slow start.
+  sender_->SetNumEmulatedConnections(1);
+  const int kNumberOfAcks = 10;
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    // Send our full send window.
+    SendAvailableSendWindow();
+    AckNPackets(2);
+  }
+  SendAvailableSendWindow();
+  QuicByteCount expected_send_window =
+      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+
+  // Loses a packet to exit slow start.
+  LoseNPackets(1);
+
+  // We should now have fallen out of slow start with a reduced window. Slow
+  // start threshold is also updated.
+  expected_send_window *= kRenoBeta;
+  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
+  EXPECT_EQ(expected_send_window, sender_->GetSlowStartThreshold());
+
+  // Resets cwnd and slow start threshold on connection migrations.
+  sender_->OnConnectionMigration();
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+  EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS,
+            sender_->GetSlowStartThreshold());
+  EXPECT_FALSE(sender_->hybrid_slow_start().started());
+}
+
+TEST_F(TcpCubicSenderBytesTest, DefaultMaxCwnd) {
+  RttStats rtt_stats;
+  QuicConnectionStats stats;
+  std::unique_ptr<SendAlgorithmInterface> sender(SendAlgorithmInterface::Create(
+      &clock_, &rtt_stats, /*unacked_packets=*/nullptr, kCubicBytes,
+      QuicRandom::GetInstance(), &stats, kInitialCongestionWindow, nullptr));
+
+  AckedPacketVector acked_packets;
+  LostPacketVector missing_packets;
+  QuicPacketCount max_congestion_window =
+      GetQuicFlag(FLAGS_quic_max_congestion_window);
+  for (uint64_t i = 1; i < max_congestion_window; ++i) {
+    acked_packets.clear();
+    acked_packets.push_back(
+        AckedPacket(QuicPacketNumber(i), 1350, QuicTime::Zero()));
+    sender->OnCongestionEvent(true, sender->GetCongestionWindow(), clock_.Now(),
+                              acked_packets, missing_packets);
+  }
+  EXPECT_EQ(max_congestion_window,
+            sender->GetCongestionWindow() / kDefaultTCPMSS);
+}
+
+TEST_F(TcpCubicSenderBytesTest, LimitCwndIncreaseInCongestionAvoidance) {
+  // Enable Cubic.
+  sender_ = std::make_unique<TcpCubicSenderBytesPeer>(&clock_, false);
+
+  int num_sent = SendAvailableSendWindow();
+
+  // Make sure we fall out of slow start.
+  QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
+  LoseNPackets(1);
+  EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
+
+  // Ack the rest of the outstanding packets to get out of recovery.
+  for (int i = 1; i < num_sent; ++i) {
+    AckNPackets(1);
+  }
+  EXPECT_EQ(0u, bytes_in_flight_);
+  // Send a new window of data and ack all; cubic growth should occur.
+  saved_cwnd = sender_->GetCongestionWindow();
+  num_sent = SendAvailableSendWindow();
+
+  // Ack packets until the CWND increases.
+  while (sender_->GetCongestionWindow() == saved_cwnd) {
+    AckNPackets(1);
+    SendAvailableSendWindow();
+  }
+  // Bytes in flight may be larger than the CWND if the CWND isn't an exact
+  // multiple of the packet sizes being sent.
+  EXPECT_GE(bytes_in_flight_, sender_->GetCongestionWindow());
+  saved_cwnd = sender_->GetCongestionWindow();
+
+  // Advance time 2 seconds waiting for an ack.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2000));
+
+  // Ack two packets.  The CWND should increase by only one packet.
+  AckNPackets(2);
+  EXPECT_EQ(saved_cwnd + kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/uber_loss_algorithm.cc b/quiche/quic/core/congestion_control/uber_loss_algorithm.cc
new file mode 100644
index 0000000..9fd4b8c
--- /dev/null
+++ b/quiche/quic/core/congestion_control/uber_loss_algorithm.cc
@@ -0,0 +1,215 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/uber_loss_algorithm.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+UberLossAlgorithm::UberLossAlgorithm() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].Initialize(static_cast<PacketNumberSpace>(i),
+                                           this);
+  }
+}
+
+void UberLossAlgorithm::SetFromConfig(const QuicConfig& config,
+                                      Perspective perspective) {
+  if (config.HasClientRequestedIndependentOption(kELDT, perspective) &&
+      tuner_ != nullptr) {
+    tuning_configured_ = true;
+    MaybeStartTuning();
+  }
+}
+
+LossDetectionInterface::DetectionStats UberLossAlgorithm::DetectLosses(
+    const QuicUnackedPacketMap& unacked_packets,
+    QuicTime time,
+    const RttStats& rtt_stats,
+    QuicPacketNumber /*largest_newly_acked*/,
+    const AckedPacketVector& packets_acked,
+    LostPacketVector* packets_lost) {
+  DetectionStats overall_stats;
+
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    const QuicPacketNumber largest_acked =
+        unacked_packets.GetLargestAckedOfPacketNumberSpace(
+            static_cast<PacketNumberSpace>(i));
+    if (!largest_acked.IsInitialized() ||
+        unacked_packets.GetLeastUnacked() > largest_acked) {
+      // Skip detecting losses if no packet has been received for this packet
+      // number space or the least_unacked is greater than largest_acked.
+      continue;
+    }
+
+    DetectionStats stats = general_loss_algorithms_[i].DetectLosses(
+        unacked_packets, time, rtt_stats, largest_acked, packets_acked,
+        packets_lost);
+
+    overall_stats.sent_packets_max_sequence_reordering =
+        std::max(overall_stats.sent_packets_max_sequence_reordering,
+                 stats.sent_packets_max_sequence_reordering);
+    overall_stats.sent_packets_num_borderline_time_reorderings +=
+        stats.sent_packets_num_borderline_time_reorderings;
+    overall_stats.total_loss_detection_response_time +=
+        stats.total_loss_detection_response_time;
+  }
+
+  return overall_stats;
+}
+
+QuicTime UberLossAlgorithm::GetLossTimeout() const {
+  QuicTime loss_timeout = QuicTime::Zero();
+  // Returns the earliest non-zero loss timeout.
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    const QuicTime timeout = general_loss_algorithms_[i].GetLossTimeout();
+    if (!loss_timeout.IsInitialized()) {
+      loss_timeout = timeout;
+      continue;
+    }
+    if (timeout.IsInitialized()) {
+      loss_timeout = std::min(loss_timeout, timeout);
+    }
+  }
+  return loss_timeout;
+}
+
+void UberLossAlgorithm::SpuriousLossDetected(
+    const QuicUnackedPacketMap& unacked_packets,
+    const RttStats& rtt_stats,
+    QuicTime ack_receive_time,
+    QuicPacketNumber packet_number,
+    QuicPacketNumber previous_largest_acked) {
+  general_loss_algorithms_[unacked_packets.GetPacketNumberSpace(packet_number)]
+      .SpuriousLossDetected(unacked_packets, rtt_stats, ack_receive_time,
+                            packet_number, previous_largest_acked);
+}
+
+void UberLossAlgorithm::SetLossDetectionTuner(
+    std::unique_ptr<LossDetectionTunerInterface> tuner) {
+  if (tuner_ != nullptr) {
+    QUIC_BUG(quic_bug_10469_1)
+        << "LossDetectionTuner can only be set once when session begins.";
+    return;
+  }
+  tuner_ = std::move(tuner);
+}
+
+void UberLossAlgorithm::MaybeStartTuning() {
+  if (tuner_started_ || !tuning_configured_ || !min_rtt_available_ ||
+      !user_agent_known_ || !reorder_happened_) {
+    return;
+  }
+
+  tuner_started_ = tuner_->Start(&tuned_parameters_);
+  if (!tuner_started_) {
+    return;
+  }
+
+  if (tuned_parameters_.reordering_shift.has_value() &&
+      tuned_parameters_.reordering_threshold.has_value()) {
+    QUIC_DLOG(INFO) << "Setting reordering shift to "
+                    << *tuned_parameters_.reordering_shift
+                    << ", and reordering threshold to "
+                    << *tuned_parameters_.reordering_threshold;
+    SetReorderingShift(*tuned_parameters_.reordering_shift);
+    SetReorderingThreshold(*tuned_parameters_.reordering_threshold);
+  } else {
+    QUIC_BUG(quic_bug_10469_2)
+        << "Tuner started but some parameters are missing";
+  }
+}
+
+void UberLossAlgorithm::OnConfigNegotiated() {}
+
+void UberLossAlgorithm::OnMinRttAvailable() {
+  min_rtt_available_ = true;
+  MaybeStartTuning();
+}
+
+void UberLossAlgorithm::OnUserAgentIdKnown() {
+  user_agent_known_ = true;
+  MaybeStartTuning();
+}
+
+void UberLossAlgorithm::OnConnectionClosed() {
+  if (tuner_ != nullptr && tuner_started_) {
+    tuner_->Finish(tuned_parameters_);
+  }
+}
+
+void UberLossAlgorithm::OnReorderingDetected() {
+  const bool tuner_started_before = tuner_started_;
+  const bool reorder_happened_before = reorder_happened_;
+
+  reorder_happened_ = true;
+  MaybeStartTuning();
+
+  if (!tuner_started_before && tuner_started_) {
+    if (reorder_happened_before) {
+      QUIC_CODE_COUNT(quic_loss_tuner_started_after_first_reorder);
+    } else {
+      QUIC_CODE_COUNT(quic_loss_tuner_started_on_first_reorder);
+    }
+  }
+}
+
+void UberLossAlgorithm::SetReorderingShift(int reordering_shift) {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_reordering_shift(reordering_shift);
+  }
+}
+
+void UberLossAlgorithm::SetReorderingThreshold(
+    QuicPacketCount reordering_threshold) {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_reordering_threshold(reordering_threshold);
+  }
+}
+
+void UberLossAlgorithm::EnableAdaptiveReorderingThreshold() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(true);
+  }
+}
+
+void UberLossAlgorithm::DisableAdaptiveReorderingThreshold() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].set_use_adaptive_reordering_threshold(false);
+  }
+}
+
+void UberLossAlgorithm::EnableAdaptiveTimeThreshold() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].enable_adaptive_time_threshold();
+  }
+}
+
+QuicPacketCount UberLossAlgorithm::GetPacketReorderingThreshold() const {
+  return general_loss_algorithms_[APPLICATION_DATA].reordering_threshold();
+}
+
+int UberLossAlgorithm::GetPacketReorderingShift() const {
+  return general_loss_algorithms_[APPLICATION_DATA].reordering_shift();
+}
+
+void UberLossAlgorithm::DisablePacketThresholdForRuntPackets() {
+  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    general_loss_algorithms_[i].disable_packet_threshold_for_runt_packets();
+  }
+}
+
+void UberLossAlgorithm::ResetLossDetection(PacketNumberSpace space) {
+  if (space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10469_3) << "Invalid packet number space: " << space;
+    return;
+  }
+  general_loss_algorithms_[space].Reset();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/uber_loss_algorithm.h b/quiche/quic/core/congestion_control/uber_loss_algorithm.h
new file mode 100644
index 0000000..ff79536
--- /dev/null
+++ b/quiche/quic/core/congestion_control/uber_loss_algorithm.h
@@ -0,0 +1,140 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+
+class QuicSentPacketManagerPeer;
+
+}  // namespace test
+
+struct QUIC_EXPORT_PRIVATE LossDetectionParameters {
+  // See GeneralLossAlgorithm for the meaning of reordering_(shift|threshold).
+  absl::optional<int> reordering_shift;
+  absl::optional<QuicPacketCount> reordering_threshold;
+};
+
+class QUIC_EXPORT_PRIVATE LossDetectionTunerInterface {
+ public:
+  virtual ~LossDetectionTunerInterface() {}
+
+  // Start the tuning by choosing parameters and saving them into |*params|.
+  // Called near the start of a QUIC session, see the .cc file for exactly
+  // where.
+  virtual bool Start(LossDetectionParameters* params) = 0;
+
+  // Finish tuning. The tuner is expected to use the actual loss detection
+  // performance(for its definition of performance) to improve the parameter
+  // selection for future QUIC sessions.
+  // Called when a QUIC session closes.
+  virtual void Finish(const LossDetectionParameters& params) = 0;
+};
+
+// This class comprises multiple loss algorithms, each per packet number space.
+class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
+ public:
+  UberLossAlgorithm();
+  UberLossAlgorithm(const UberLossAlgorithm&) = delete;
+  UberLossAlgorithm& operator=(const UberLossAlgorithm&) = delete;
+  ~UberLossAlgorithm() override {}
+
+  void SetFromConfig(const QuicConfig& config,
+                     Perspective perspective) override;
+
+  // Detects lost packets.
+  DetectionStats DetectLosses(const QuicUnackedPacketMap& unacked_packets,
+                              QuicTime time,
+                              const RttStats& rtt_stats,
+                              QuicPacketNumber largest_newly_acked,
+                              const AckedPacketVector& packets_acked,
+                              LostPacketVector* packets_lost) override;
+
+  // Returns the earliest time the early retransmit timer should be active.
+  QuicTime GetLossTimeout() const override;
+
+  // Called to increases time or packet threshold.
+  void SpuriousLossDetected(const QuicUnackedPacketMap& unacked_packets,
+                            const RttStats& rtt_stats,
+                            QuicTime ack_receive_time,
+                            QuicPacketNumber packet_number,
+                            QuicPacketNumber previous_largest_acked) override;
+
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner);
+  void OnConfigNegotiated() override;
+  void OnMinRttAvailable() override;
+  void OnUserAgentIdKnown() override;
+  void OnConnectionClosed() override;
+  void OnReorderingDetected() override;
+
+  // Sets reordering_shift for all packet number spaces.
+  void SetReorderingShift(int reordering_shift);
+
+  // Sets reordering_threshold for all packet number spaces.
+  void SetReorderingThreshold(QuicPacketCount reordering_threshold);
+
+  // Enable adaptive reordering threshold of all packet number spaces.
+  void EnableAdaptiveReorderingThreshold();
+
+  // Disable adaptive reordering threshold of all packet number spaces.
+  void DisableAdaptiveReorderingThreshold();
+
+  // Enable adaptive time threshold of all packet number spaces.
+  void EnableAdaptiveTimeThreshold();
+
+  // Get the packet reordering threshold from the APPLICATION_DATA PN space.
+  // Always 3 when adaptive reordering is not enabled.
+  QuicPacketCount GetPacketReorderingThreshold() const;
+
+  // Get the packet reordering shift from the APPLICATION_DATA PN space.
+  int GetPacketReorderingShift() const;
+
+  // Disable packet threshold loss detection for *runt* packets.
+  void DisablePacketThresholdForRuntPackets();
+
+  // Called to reset loss detection of |space|.
+  void ResetLossDetection(PacketNumberSpace space);
+
+  bool use_adaptive_reordering_threshold() const {
+    return general_loss_algorithms_[APPLICATION_DATA]
+        .use_adaptive_reordering_threshold();
+  }
+
+  bool use_adaptive_time_threshold() const {
+    return general_loss_algorithms_[APPLICATION_DATA]
+        .use_adaptive_time_threshold();
+  }
+
+ private:
+  friend class test::QuicSentPacketManagerPeer;
+
+  void MaybeStartTuning();
+
+  // One loss algorithm per packet number space.
+  GeneralLossAlgorithm general_loss_algorithms_[NUM_PACKET_NUMBER_SPACES];
+
+  // Used to tune reordering_shift and reordering_threshold.
+  std::unique_ptr<LossDetectionTunerInterface> tuner_;
+  LossDetectionParameters tuned_parameters_;
+  bool tuner_started_ = false;
+  bool min_rtt_available_ = false;
+  // Whether user agent is known to the session.
+  bool user_agent_known_ = false;
+  // Whether tuning is configured in QuicConfig.
+  bool tuning_configured_ = false;
+  bool reorder_happened_ = false;  // Whether any reordered packet is observed.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_UBER_LOSS_ALGORITHM_H_
diff --git a/quiche/quic/core/congestion_control/uber_loss_algorithm_test.cc b/quiche/quic/core/congestion_control/uber_loss_algorithm_test.cc
new file mode 100644
index 0000000..1a1bbe5
--- /dev/null
+++ b/quiche/quic/core/congestion_control/uber_loss_algorithm_test.cc
@@ -0,0 +1,361 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/uber_loss_algorithm.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_unacked_packet_map_peer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class UberLossAlgorithmTest : public QuicTest {
+ protected:
+  UberLossAlgorithmTest() {
+    unacked_packets_ =
+        std::make_unique<QuicUnackedPacketMap>(Perspective::IS_CLIENT);
+    rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                         QuicTime::Delta::Zero(), clock_.Now());
+    EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
+  }
+
+  void SendPacket(uint64_t packet_number, EncryptionLevel encryption_level) {
+    QuicStreamFrame frame;
+    QuicTransportVersion version =
+        CurrentSupportedVersions()[0].transport_version;
+    frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        version, Perspective::IS_CLIENT);
+    if (encryption_level == ENCRYPTION_INITIAL) {
+      if (QuicVersionUsesCryptoFrames(version)) {
+        frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+            version, Perspective::IS_CLIENT);
+      } else {
+        frame.stream_id = QuicUtils::GetCryptoStreamId(version);
+      }
+    }
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    packet.encryption_level = encryption_level;
+    packet.retransmittable_frames.push_back(QuicFrame(frame));
+    unacked_packets_->AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
+                                    true, true);
+  }
+
+  void AckPackets(const std::vector<uint64_t>& packets_acked) {
+    packets_acked_.clear();
+    for (uint64_t acked : packets_acked) {
+      unacked_packets_->RemoveFromInFlight(QuicPacketNumber(acked));
+      packets_acked_.push_back(AckedPacket(
+          QuicPacketNumber(acked), kMaxOutgoingPacketSize, QuicTime::Zero()));
+    }
+  }
+
+  void VerifyLosses(uint64_t largest_newly_acked,
+                    const AckedPacketVector& packets_acked,
+                    const std::vector<uint64_t>& losses_expected) {
+    return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
+                        absl::nullopt);
+  }
+
+  void VerifyLosses(
+      uint64_t largest_newly_acked,
+      const AckedPacketVector& packets_acked,
+      const std::vector<uint64_t>& losses_expected,
+      absl::optional<QuicPacketCount> max_sequence_reordering_expected) {
+    LostPacketVector lost_packets;
+    LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
+        *unacked_packets_, clock_.Now(), rtt_stats_,
+        QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
+    if (max_sequence_reordering_expected.has_value()) {
+      EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
+                max_sequence_reordering_expected.value());
+    }
+    ASSERT_EQ(losses_expected.size(), lost_packets.size());
+    for (size_t i = 0; i < losses_expected.size(); ++i) {
+      EXPECT_EQ(lost_packets[i].packet_number,
+                QuicPacketNumber(losses_expected[i]));
+    }
+  }
+
+  MockClock clock_;
+  std::unique_ptr<QuicUnackedPacketMap> unacked_packets_;
+  RttStats rtt_stats_;
+  UberLossAlgorithm loss_algorithm_;
+  AckedPacketVector packets_acked_;
+};
+
+TEST_F(UberLossAlgorithmTest, ScenarioA) {
+  // This test mimics a scenario: client sends 1-CHLO, 2-0RTT, 3-0RTT,
+  // timeout and retransmits 4-CHLO. Server acks packet 1 (ack gets lost).
+  // Server receives and buffers packets 2 and 3. Server receives packet 4 and
+  // processes handshake asynchronously, so server acks 4 and cannot process
+  // packets 2 and 3.
+  SendPacket(1, ENCRYPTION_INITIAL);
+  SendPacket(2, ENCRYPTION_ZERO_RTT);
+  SendPacket(3, ENCRYPTION_ZERO_RTT);
+  unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
+  SendPacket(4, ENCRYPTION_INITIAL);
+
+  AckPackets({1, 4});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      HANDSHAKE_DATA, QuicPacketNumber(4));
+  // Verify no packet is detected lost.
+  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 0);
+  EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
+}
+
+TEST_F(UberLossAlgorithmTest, ScenarioB) {
+  // This test mimics a scenario: client sends 3-0RTT, 4-0RTT, receives SHLO,
+  // sends 5-1RTT, 6-1RTT.
+  SendPacket(3, ENCRYPTION_ZERO_RTT);
+  SendPacket(4, ENCRYPTION_ZERO_RTT);
+  SendPacket(5, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(6, ENCRYPTION_FORWARD_SECURE);
+
+  AckPackets({4});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(4));
+  // No packet loss by acking 4.
+  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{}, 1);
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+
+  // Acking 6 causes 3 to be detected loss.
+  AckPackets({6});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(6));
+  VerifyLosses(6, packets_acked_, std::vector<uint64_t>{3}, 3);
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+  packets_acked_.clear();
+
+  clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
+  // Verify 5 will be early retransmitted.
+  VerifyLosses(6, packets_acked_, {5}, 1);
+}
+
+TEST_F(UberLossAlgorithmTest, ScenarioC) {
+  // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT, 4-1RTT
+  // and retransmit 4-SHLO. Client receives and buffers packet 4. Client
+  // receives packet 5 and processes 4.
+  QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
+                                           Perspective::IS_SERVER);
+  SendPacket(1, ENCRYPTION_ZERO_RTT);
+  SendPacket(2, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(3, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(4, ENCRYPTION_FORWARD_SECURE);
+  unacked_packets_->RemoveFromInFlight(QuicPacketNumber(1));
+  SendPacket(5, ENCRYPTION_ZERO_RTT);
+
+  AckPackets({4, 5});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(4));
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      HANDSHAKE_DATA, QuicPacketNumber(5));
+  // No packet loss by acking 5.
+  VerifyLosses(5, packets_acked_, std::vector<uint64_t>{}, 2);
+  EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
+            loss_algorithm_.GetLossTimeout());
+  packets_acked_.clear();
+
+  clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
+  // Verify 2 and 3 will be early retransmitted.
+  VerifyLosses(5, packets_acked_, std::vector<uint64_t>{2, 3}, 2);
+}
+
+// Regression test for b/133771183.
+TEST_F(UberLossAlgorithmTest, PacketInLimbo) {
+  // This test mimics a scenario: server sends 1-SHLO, 2-1RTT, 3-1RTT,
+  // 4-retransmit SHLO. Client receives and ACKs packets 1, 3 and 4.
+  QuicUnackedPacketMapPeer::SetPerspective(unacked_packets_.get(),
+                                           Perspective::IS_SERVER);
+
+  SendPacket(1, ENCRYPTION_ZERO_RTT);
+  SendPacket(2, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(3, ENCRYPTION_FORWARD_SECURE);
+  SendPacket(4, ENCRYPTION_ZERO_RTT);
+
+  SendPacket(5, ENCRYPTION_FORWARD_SECURE);
+  AckPackets({1, 3, 4});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(3));
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      HANDSHAKE_DATA, QuicPacketNumber(4));
+  // No packet loss detected.
+  VerifyLosses(4, packets_acked_, std::vector<uint64_t>{});
+
+  SendPacket(6, ENCRYPTION_FORWARD_SECURE);
+  AckPackets({5, 6});
+  unacked_packets_->MaybeUpdateLargestAckedOfPacketNumberSpace(
+      APPLICATION_DATA, QuicPacketNumber(6));
+  // Verify packet 2 is detected lost.
+  VerifyLosses(6, packets_acked_, std::vector<uint64_t>{2});
+}
+
+class TestLossTuner : public LossDetectionTunerInterface {
+ public:
+  TestLossTuner(bool forced_start_result,
+                LossDetectionParameters forced_parameters)
+      : forced_start_result_(forced_start_result),
+        forced_parameters_(std::move(forced_parameters)) {}
+
+  ~TestLossTuner() override = default;
+
+  bool Start(LossDetectionParameters* params) override {
+    start_called_ = true;
+    *params = forced_parameters_;
+    return forced_start_result_;
+  }
+
+  void Finish(const LossDetectionParameters& /*params*/) override {}
+
+  bool start_called() const { return start_called_; }
+
+ private:
+  bool forced_start_result_;
+  LossDetectionParameters forced_parameters_;
+  bool start_called_ = false;
+};
+
+// Verify the parameters are changed if first call SetFromConfig(), then call
+// OnMinRttAvailable().
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_SetFromConfigFirst) {
+  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+  const QuicPacketCount old_reordering_threshold =
+      loss_algorithm_.GetPacketReorderingThreshold();
+
+  loss_algorithm_.OnUserAgentIdKnown();
+
+  // Not owned.
+  TestLossTuner* test_tuner = new TestLossTuner(
+      /*forced_start_result=*/true,
+      LossDetectionParameters{
+          /*reordering_shift=*/old_reordering_shift + 1,
+          /*reordering_threshold=*/old_reordering_threshold * 2});
+  loss_algorithm_.SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kELDT);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+  // MinRtt was not available when SetFromConfig was called.
+  EXPECT_FALSE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+
+  // MinRtt available. Tuner should not start yet because no reordering yet.
+  loss_algorithm_.OnMinRttAvailable();
+  EXPECT_FALSE(test_tuner->start_called());
+
+  // Reordering happened. Tuner should start now.
+  loss_algorithm_.OnReorderingDetected();
+  EXPECT_TRUE(test_tuner->start_called());
+  EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_NE(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+// Verify the parameters are changed if first call OnMinRttAvailable(), then
+// call SetFromConfig().
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_OnMinRttAvailableFirst) {
+  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+  const QuicPacketCount old_reordering_threshold =
+      loss_algorithm_.GetPacketReorderingThreshold();
+
+  loss_algorithm_.OnUserAgentIdKnown();
+
+  // Not owned.
+  TestLossTuner* test_tuner = new TestLossTuner(
+      /*forced_start_result=*/true,
+      LossDetectionParameters{
+          /*reordering_shift=*/old_reordering_shift + 1,
+          /*reordering_threshold=*/old_reordering_threshold * 2});
+  loss_algorithm_.SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+  loss_algorithm_.OnMinRttAvailable();
+  EXPECT_FALSE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+
+  // Pretend a reodering has happened.
+  loss_algorithm_.OnReorderingDetected();
+  EXPECT_FALSE(test_tuner->start_called());
+
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kELDT);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  // Should start tuning since MinRtt is available.
+  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+  EXPECT_TRUE(test_tuner->start_called());
+  EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_NE(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+// Verify the parameters are not changed if Tuner.Start() returns false.
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_StartFailed) {
+  const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+  const QuicPacketCount old_reordering_threshold =
+      loss_algorithm_.GetPacketReorderingThreshold();
+
+  loss_algorithm_.OnUserAgentIdKnown();
+
+  // Not owned.
+  TestLossTuner* test_tuner = new TestLossTuner(
+      /*forced_start_result=*/false,
+      LossDetectionParameters{
+          /*reordering_shift=*/old_reordering_shift + 1,
+          /*reordering_threshold=*/old_reordering_threshold * 2});
+  loss_algorithm_.SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kELDT);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+  // MinRtt was not available when SetFromConfig was called.
+  EXPECT_FALSE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+
+  // Pretend a reodering has happened.
+  loss_algorithm_.OnReorderingDetected();
+  EXPECT_FALSE(test_tuner->start_called());
+
+  // Parameters should not change since test_tuner->Start() returns false.
+  loss_algorithm_.OnMinRttAvailable();
+  EXPECT_TRUE(test_tuner->start_called());
+  EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+  EXPECT_EQ(old_reordering_threshold,
+            loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/congestion_control/windowed_filter.h b/quiche/quic/core/congestion_control/windowed_filter.h
new file mode 100644
index 0000000..9326a08
--- /dev/null
+++ b/quiche/quic/core/congestion_control/windowed_filter.h
@@ -0,0 +1,164 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
+#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
+
+// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum)
+// estimate of a stream of samples over some fixed time interval. (E.g.,
+// the minimum RTT over the past five minutes.) The algorithm keeps track of
+// the best, second best, and third best min (or max) estimates, maintaining an
+// invariant that the measurement time of the n'th best >= n-1'th best.
+
+// The algorithm works as follows. On a reset, all three estimates are set to
+// the same sample. The second best estimate is then recorded in the second
+// quarter of the window, and a third best estimate is recorded in the second
+// half of the window, bounding the worst case error when the true min is
+// monotonically increasing (or true max is monotonically decreasing) over the
+// window.
+//
+// A new best sample replaces all three estimates, since the new best is lower
+// (or higher) than everything else in the window and it is the most recent.
+// The window thus effectively gets reset on every new min. The same property
+// holds true for second best and third best estimates. Specifically, when a
+// sample arrives that is better than the second best but not better than the
+// best, it replaces the second and third best estimates but not the best
+// estimate. Similarly, a sample that is better than the third best estimate
+// but not the other estimates replaces only the third best estimate.
+//
+// Finally, when the best expires, it is replaced by the second best, which in
+// turn is replaced by the third best. The newest sample replaces the third
+// best.
+
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+
+// Compares two values and returns true if the first is less than or equal
+// to the second.
+template <class T>
+struct QUIC_EXPORT_PRIVATE MinFilter {
+  bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; }
+};
+
+// Compares two values and returns true if the first is greater than or equal
+// to the second.
+template <class T>
+struct QUIC_EXPORT_PRIVATE MaxFilter {
+  bool operator()(const T& lhs, const T& rhs) const { return lhs >= rhs; }
+};
+
+// Use the following to construct a windowed filter object of type T.
+// For example, a min filter using QuicTime as the time type:
+//   WindowedFilter<T, MinFilter<T>, QuicTime, QuicTime::Delta> ObjectName;
+// A max filter using 64-bit integers as the time type:
+//   WindowedFilter<T, MaxFilter<T>, uint64_t, int64_t> ObjectName;
+// Specifically, this template takes four arguments:
+// 1. T -- type of the measurement that is being filtered.
+// 2. Compare -- MinFilter<T> or MaxFilter<T>, depending on the type of filter
+//    desired.
+// 3. TimeT -- the type used to represent timestamps.
+// 4. TimeDeltaT -- the type used to represent continuous time intervals between
+//    two timestamps.  Has to be the type of (a - b) if both |a| and |b| are
+//    of type TimeT.
+template <class T, class Compare, typename TimeT, typename TimeDeltaT>
+class QUIC_EXPORT_PRIVATE WindowedFilter {
+ public:
+  // |window_length| is the period after which a best estimate expires.
+  // |zero_value| is used as the uninitialized value for objects of T.
+  // Importantly, |zero_value| should be an invalid value for a true sample.
+  WindowedFilter(TimeDeltaT window_length, T zero_value, TimeT zero_time)
+      : window_length_(window_length),
+        zero_value_(zero_value),
+        zero_time_(zero_time),
+        estimates_{Sample(zero_value_, zero_time),
+                   Sample(zero_value_, zero_time),
+                   Sample(zero_value_, zero_time)} {}
+
+  // Changes the window length.  Does not update any current samples.
+  void SetWindowLength(TimeDeltaT window_length) {
+    window_length_ = window_length;
+  }
+
+  // Updates best estimates with |sample|, and expires and updates best
+  // estimates as necessary.
+  void Update(T new_sample, TimeT new_time) {
+    // Reset all estimates if they have not yet been initialized, if new sample
+    // is a new best, or if the newest recorded estimate is too old.
+    if (estimates_[0].sample == zero_value_ ||
+        Compare()(new_sample, estimates_[0].sample) ||
+        new_time - estimates_[2].time > window_length_) {
+      Reset(new_sample, new_time);
+      return;
+    }
+
+    if (Compare()(new_sample, estimates_[1].sample)) {
+      estimates_[1] = Sample(new_sample, new_time);
+      estimates_[2] = estimates_[1];
+    } else if (Compare()(new_sample, estimates_[2].sample)) {
+      estimates_[2] = Sample(new_sample, new_time);
+    }
+
+    // Expire and update estimates as necessary.
+    if (new_time - estimates_[0].time > window_length_) {
+      // The best estimate hasn't been updated for an entire window, so promote
+      // second and third best estimates.
+      estimates_[0] = estimates_[1];
+      estimates_[1] = estimates_[2];
+      estimates_[2] = Sample(new_sample, new_time);
+      // Need to iterate one more time. Check if the new best estimate is
+      // outside the window as well, since it may also have been recorded a
+      // long time ago. Don't need to iterate once more since we cover that
+      // case at the beginning of the method.
+      if (new_time - estimates_[0].time > window_length_) {
+        estimates_[0] = estimates_[1];
+        estimates_[1] = estimates_[2];
+      }
+      return;
+    }
+    if (estimates_[1].sample == estimates_[0].sample &&
+        new_time - estimates_[1].time > window_length_ >> 2) {
+      // A quarter of the window has passed without a better sample, so the
+      // second-best estimate is taken from the second quarter of the window.
+      estimates_[2] = estimates_[1] = Sample(new_sample, new_time);
+      return;
+    }
+
+    if (estimates_[2].sample == estimates_[1].sample &&
+        new_time - estimates_[2].time > window_length_ >> 1) {
+      // We've passed a half of the window without a better estimate, so take
+      // a third-best estimate from the second half of the window.
+      estimates_[2] = Sample(new_sample, new_time);
+    }
+  }
+
+  // Resets all estimates to new sample.
+  void Reset(T new_sample, TimeT new_time) {
+    estimates_[0] = estimates_[1] = estimates_[2] =
+        Sample(new_sample, new_time);
+  }
+
+  void Clear() { Reset(zero_value_, zero_time_); }
+
+  T GetBest() const { return estimates_[0].sample; }
+  T GetSecondBest() const { return estimates_[1].sample; }
+  T GetThirdBest() const { return estimates_[2].sample; }
+
+ private:
+  struct QUIC_EXPORT_PRIVATE Sample {
+    T sample;
+    TimeT time;
+    Sample(T init_sample, TimeT init_time)
+        : sample(init_sample), time(init_time) {}
+  };
+
+  TimeDeltaT window_length_;  // Time length of window.
+  T zero_value_;              // Uninitialized value of T.
+  TimeT zero_time_;           // Uninitialized value of TimeT.
+  Sample estimates_[3];       // Best estimate is element 0.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
diff --git a/quiche/quic/core/congestion_control/windowed_filter_test.cc b/quiche/quic/core/congestion_control/windowed_filter_test.cc
new file mode 100644
index 0000000..f2edad0
--- /dev/null
+++ b/quiche/quic/core/congestion_control/windowed_filter_test.cc
@@ -0,0 +1,388 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/congestion_control/windowed_filter.h"
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class WindowedFilterTest : public QuicTest {
+ public:
+  // Set the window to 99ms, so 25ms is more than a quarter rtt.
+  WindowedFilterTest()
+      : windowed_min_rtt_(QuicTime::Delta::FromMilliseconds(99),
+                          QuicTime::Delta::Zero(),
+                          QuicTime::Zero()),
+        windowed_max_bw_(QuicTime::Delta::FromMilliseconds(99),
+                         QuicBandwidth::Zero(),
+                         QuicTime::Zero()) {}
+
+  // Sets up windowed_min_rtt_ to have the following values:
+  // Best = 20ms, recorded at 25ms
+  // Second best = 40ms, recorded at 75ms
+  // Third best = 50ms, recorded at 100ms
+  void InitializeMinFilter() {
+    QuicTime now = QuicTime::Zero();
+    QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
+    for (int i = 0; i < 5; ++i) {
+      windowed_min_rtt_.Update(rtt_sample, now);
+      QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
+                   << " mins: "
+                   << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
+                   << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
+                   << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
+      now = now + QuicTime::Delta::FromMilliseconds(25);
+      rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
+    }
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+              windowed_min_rtt_.GetBest());
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+              windowed_min_rtt_.GetSecondBest());
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
+              windowed_min_rtt_.GetThirdBest());
+  }
+
+  // Sets up windowed_max_bw_ to have the following values:
+  // Best = 900 bps, recorded at 25ms
+  // Second best = 700 bps, recorded at 75ms
+  // Third best = 600 bps, recorded at 100ms
+  void InitializeMaxFilter() {
+    QuicTime now = QuicTime::Zero();
+    QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
+    for (int i = 0; i < 5; ++i) {
+      windowed_max_bw_.Update(bw_sample, now);
+      QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
+                   << " maxs: "
+                   << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
+                   << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
+                   << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
+      now = now + QuicTime::Delta::FromMilliseconds(25);
+      bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
+    }
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
+              windowed_max_bw_.GetBest());
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
+              windowed_max_bw_.GetSecondBest());
+    EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(600),
+              windowed_max_bw_.GetThirdBest());
+  }
+
+ protected:
+  WindowedFilter<QuicTime::Delta,
+                 MinFilter<QuicTime::Delta>,
+                 QuicTime,
+                 QuicTime::Delta>
+      windowed_min_rtt_;
+  WindowedFilter<QuicBandwidth,
+                 MaxFilter<QuicBandwidth>,
+                 QuicTime,
+                 QuicTime::Delta>
+      windowed_max_bw_;
+};
+
+namespace {
+// Test helper function: updates the filter with a lot of small values in order
+// to ensure that it is not susceptible to noise.
+void UpdateWithIrrelevantSamples(
+    WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t>* filter,
+    uint64_t max_value,
+    uint64_t time) {
+  for (uint64_t i = 0; i < 1000; i++) {
+    filter->Update(i % max_value, time);
+  }
+}
+}  // namespace
+
+TEST_F(WindowedFilterTest, UninitializedEstimates) {
+  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetBest());
+  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(QuicTime::Delta::Zero(), windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetBest());
+  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(QuicBandwidth::Zero(), windowed_max_bw_.GetThirdBest());
+}
+
+TEST_F(WindowedFilterTest, MonotonicallyIncreasingMin) {
+  QuicTime now = QuicTime::Zero();
+  QuicTime::Delta rtt_sample = QuicTime::Delta::FromMilliseconds(10);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), windowed_min_rtt_.GetBest());
+
+  // Gradually increase the rtt samples and ensure the windowed min rtt starts
+  // rising.
+  for (int i = 0; i < 6; ++i) {
+    now = now + QuicTime::Delta::FromMilliseconds(25);
+    rtt_sample = rtt_sample + QuicTime::Delta::FromMilliseconds(10);
+    windowed_min_rtt_.Update(rtt_sample, now);
+    QUIC_VLOG(1) << "i: " << i << " sample: " << rtt_sample.ToMilliseconds()
+                 << " mins: "
+                 << " " << windowed_min_rtt_.GetBest().ToMilliseconds() << " "
+                 << windowed_min_rtt_.GetSecondBest().ToMilliseconds() << " "
+                 << windowed_min_rtt_.GetThirdBest().ToMilliseconds();
+    if (i < 3) {
+      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+                windowed_min_rtt_.GetBest());
+    } else if (i == 3) {
+      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+                windowed_min_rtt_.GetBest());
+    } else if (i < 6) {
+      EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+                windowed_min_rtt_.GetBest());
+    }
+  }
+}
+
+TEST_F(WindowedFilterTest, MonotonicallyDecreasingMax) {
+  QuicTime now = QuicTime::Zero();
+  QuicBandwidth bw_sample = QuicBandwidth::FromBitsPerSecond(1000);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000), windowed_max_bw_.GetBest());
+
+  // Gradually decrease the bw samples and ensure the windowed max bw starts
+  // decreasing.
+  for (int i = 0; i < 6; ++i) {
+    now = now + QuicTime::Delta::FromMilliseconds(25);
+    bw_sample = bw_sample - QuicBandwidth::FromBitsPerSecond(100);
+    windowed_max_bw_.Update(bw_sample, now);
+    QUIC_VLOG(1) << "i: " << i << " sample: " << bw_sample.ToBitsPerSecond()
+                 << " maxs: "
+                 << " " << windowed_max_bw_.GetBest().ToBitsPerSecond() << " "
+                 << windowed_max_bw_.GetSecondBest().ToBitsPerSecond() << " "
+                 << windowed_max_bw_.GetThirdBest().ToBitsPerSecond();
+    if (i < 3) {
+      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(1000),
+                windowed_max_bw_.GetBest());
+    } else if (i == 3) {
+      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900),
+                windowed_max_bw_.GetBest());
+    } else if (i < 6) {
+      EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
+                windowed_max_bw_.GetBest());
+    }
+  }
+}
+
+TEST_F(WindowedFilterTest, SampleChangesThirdBestMin) {
+  InitializeMinFilter();
+  // RTT sample lower than the third-choice min-rtt sets that, but nothing else.
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetThirdBest() - QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_GT(windowed_min_rtt_.GetThirdBest(),
+            QuicTime::Delta::FromMilliseconds(5));
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
+            windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesThirdBestMax) {
+  InitializeMaxFilter();
+  // BW sample higher than the third-choice max sets that, but nothing else.
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetThirdBest() + QuicBandwidth::FromBitsPerSecond(50);
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(700),
+            windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesSecondBestMin) {
+  InitializeMinFilter();
+  // RTT sample lower than the second-choice min sets that and also
+  // the third-choice min.
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetSecondBest() - QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_GT(windowed_min_rtt_.GetSecondBest(),
+            QuicTime::Delta::FromMilliseconds(5));
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesSecondBestMax) {
+  InitializeMaxFilter();
+  // BW sample higher than the second-choice max sets that and also
+  // the third-choice max.
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetSecondBest() + QuicBandwidth::FromBitsPerSecond(50);
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(900), windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesAllMins) {
+  InitializeMinFilter();
+  // RTT sample lower than the first-choice min-rtt sets that and also
+  // the second and third-choice mins.
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetBest() - QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_GT(windowed_min_rtt_.GetBest(), QuicTime::Delta::FromMilliseconds(5));
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, SampleChangesAllMaxs) {
+  InitializeMaxFilter();
+  // BW sample higher than the first-choice max sets that and also
+  // the second and third-choice maxs.
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetBest() + QuicBandwidth::FromBitsPerSecond(50);
+  // Latest sample was recorded at 100ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(101);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireBestMin) {
+  InitializeMinFilter();
+  QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
+  QuicTime::Delta old_second_best = windowed_min_rtt_.GetSecondBest();
+  QuicTime::Delta rtt_sample =
+      old_third_best + QuicTime::Delta::FromMilliseconds(5);
+  // Best min sample was recorded at 25ms, so expiry time is 124ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(old_third_best, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(old_second_best, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireBestMax) {
+  InitializeMaxFilter();
+  QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
+  QuicBandwidth old_second_best = windowed_max_bw_.GetSecondBest();
+  QuicBandwidth bw_sample =
+      old_third_best - QuicBandwidth::FromBitsPerSecond(50);
+  // Best max sample was recorded at 25ms, so expiry time is 124ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(125);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(old_third_best, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(old_second_best, windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireSecondBestMin) {
+  InitializeMinFilter();
+  QuicTime::Delta old_third_best = windowed_min_rtt_.GetThirdBest();
+  QuicTime::Delta rtt_sample =
+      old_third_best + QuicTime::Delta::FromMilliseconds(5);
+  // Second best min sample was recorded at 75ms, so expiry time is 174ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(old_third_best, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireSecondBestMax) {
+  InitializeMaxFilter();
+  QuicBandwidth old_third_best = windowed_max_bw_.GetThirdBest();
+  QuicBandwidth bw_sample =
+      old_third_best - QuicBandwidth::FromBitsPerSecond(50);
+  // Second best max sample was recorded at 75ms, so expiry time is 174ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(175);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(old_third_best, windowed_max_bw_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireAllMins) {
+  InitializeMinFilter();
+  QuicTime::Delta rtt_sample =
+      windowed_min_rtt_.GetThirdBest() + QuicTime::Delta::FromMilliseconds(5);
+  // This assert is necessary to avoid triggering -Wstrict-overflow
+  // See crbug/616957
+  ASSERT_LT(windowed_min_rtt_.GetThirdBest(),
+            QuicTime::Delta::Infinite() - QuicTime::Delta::FromMilliseconds(5));
+  // Third best min sample was recorded at 100ms, so expiry time is 199ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
+  windowed_min_rtt_.Update(rtt_sample, now);
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetThirdBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetSecondBest());
+  EXPECT_EQ(rtt_sample, windowed_min_rtt_.GetBest());
+}
+
+TEST_F(WindowedFilterTest, ExpireAllMaxs) {
+  InitializeMaxFilter();
+  QuicBandwidth bw_sample =
+      windowed_max_bw_.GetThirdBest() - QuicBandwidth::FromBitsPerSecond(50);
+  // Third best max sample was recorded at 100ms, so expiry time is 199ms.
+  QuicTime now = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(200);
+  windowed_max_bw_.Update(bw_sample, now);
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetThirdBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetSecondBest());
+  EXPECT_EQ(bw_sample, windowed_max_bw_.GetBest());
+}
+
+// Test the windowed filter where the time used is an exact counter instead of a
+// timestamp.  This is useful if, for example, the time is measured in round
+// trips.
+TEST_F(WindowedFilterTest, ExpireCounterBasedMax) {
+  // Create a window which starts at t = 0 and expires after two cycles.
+  WindowedFilter<uint64_t, MaxFilter<uint64_t>, uint64_t, uint64_t> max_filter(
+      2, 0, 0);
+
+  const uint64_t kBest = 50000;
+  // Insert 50000 at t = 1.
+  max_filter.Update(50000, 1);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 1);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+
+  // Insert 40000 at t = 2.  Nothing is expected to expire.
+  max_filter.Update(40000, 2);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 2);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+
+  // Insert 30000 at t = 3.  Nothing is expected to expire yet.
+  max_filter.Update(30000, 3);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 3);
+  EXPECT_EQ(kBest, max_filter.GetBest());
+  QUIC_VLOG(0) << max_filter.GetSecondBest();
+  QUIC_VLOG(0) << max_filter.GetThirdBest();
+
+  // Insert 20000 at t = 4.  50000 at t = 1 expires, so 40000 becomes the new
+  // maximum.
+  const uint64_t kNewBest = 40000;
+  max_filter.Update(20000, 4);
+  EXPECT_EQ(kNewBest, max_filter.GetBest());
+  UpdateWithIrrelevantSamples(&max_filter, 20, 4);
+  EXPECT_EQ(kNewBest, max_filter.GetBest());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aead_base_decrypter.cc b/quiche/quic/core/crypto/aead_base_decrypter.cc
new file mode 100644
index 0000000..fecf67e
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_decrypter.cc
@@ -0,0 +1,214 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aead_base_decrypter.h"
+
+#include <cstdint>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Clear OpenSSL error stack.
+void ClearOpenSslErrors() {
+  while (ERR_get_error()) {
+  }
+}
+
+// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
+// stack.
+void DLogOpenSslErrors() {
+#ifdef NDEBUG
+  ClearOpenSslErrors();
+#else
+  while (uint32_t error = ERR_get_error()) {
+    char buf[120];
+    ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
+    QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
+  }
+#endif
+}
+
+const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
+  // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
+  // the static initializer is disabled.
+  CRYPTO_library_init();
+  return aead_getter();
+}
+
+}  // namespace
+
+AeadBaseDecrypter::AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
+                                     size_t key_size,
+                                     size_t auth_tag_size,
+                                     size_t nonce_size,
+                                     bool use_ietf_nonce_construction)
+    : aead_alg_(InitAndCall(aead_getter)),
+      key_size_(key_size),
+      auth_tag_size_(auth_tag_size),
+      nonce_size_(nonce_size),
+      use_ietf_nonce_construction_(use_ietf_nonce_construction),
+      have_preliminary_key_(false) {
+  QUICHE_DCHECK_GT(256u, key_size);
+  QUICHE_DCHECK_GT(256u, auth_tag_size);
+  QUICHE_DCHECK_GT(256u, nonce_size);
+  QUICHE_DCHECK_LE(key_size_, sizeof(key_));
+  QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
+}
+
+AeadBaseDecrypter::~AeadBaseDecrypter() {}
+
+bool AeadBaseDecrypter::SetKey(absl::string_view key) {
+  QUICHE_DCHECK_EQ(key.size(), key_size_);
+  if (key.size() != key_size_) {
+    return false;
+  }
+  memcpy(key_, key.data(), key.size());
+
+  EVP_AEAD_CTX_cleanup(ctx_.get());
+  if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
+                         nullptr)) {
+    DLogOpenSslErrors();
+    return false;
+  }
+
+  return true;
+}
+
+bool AeadBaseDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  if (use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10709_1)
+        << "Attempted to set nonce prefix on IETF QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
+  if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
+    return false;
+  }
+  memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
+  return true;
+}
+
+bool AeadBaseDecrypter::SetIV(absl::string_view iv) {
+  if (!use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10709_2) << "Attempted to set IV on Google QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
+  if (iv.size() != nonce_size_) {
+    return false;
+  }
+  memcpy(iv_, iv.data(), iv.size());
+  return true;
+}
+
+bool AeadBaseDecrypter::SetPreliminaryKey(absl::string_view key) {
+  QUICHE_DCHECK(!have_preliminary_key_);
+  SetKey(key);
+  have_preliminary_key_ = true;
+
+  return true;
+}
+
+bool AeadBaseDecrypter::SetDiversificationNonce(
+    const DiversificationNonce& nonce) {
+  if (!have_preliminary_key_) {
+    return true;
+  }
+
+  std::string key, nonce_prefix;
+  size_t prefix_size = nonce_size_;
+  if (!use_ietf_nonce_construction_) {
+    prefix_size -= sizeof(QuicPacketNumber);
+  }
+  DiversifyPreliminaryKey(
+      absl::string_view(reinterpret_cast<const char*>(key_), key_size_),
+      absl::string_view(reinterpret_cast<const char*>(iv_), prefix_size), nonce,
+      key_size_, prefix_size, &key, &nonce_prefix);
+
+  if (!SetKey(key) ||
+      (!use_ietf_nonce_construction_ && !SetNoncePrefix(nonce_prefix)) ||
+      (use_ietf_nonce_construction_ && !SetIV(nonce_prefix))) {
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  have_preliminary_key_ = false;
+  return true;
+}
+
+bool AeadBaseDecrypter::DecryptPacket(uint64_t packet_number,
+                                      absl::string_view associated_data,
+                                      absl::string_view ciphertext,
+                                      char* output,
+                                      size_t* output_length,
+                                      size_t max_output_length) {
+  if (ciphertext.length() < auth_tag_size_) {
+    return false;
+  }
+
+  if (have_preliminary_key_) {
+    QUIC_BUG(quic_bug_10709_3)
+        << "Unable to decrypt while key diversification is pending";
+    return false;
+  }
+
+  uint8_t nonce[kMaxNonceSize];
+  memcpy(nonce, iv_, nonce_size_);
+  size_t prefix_len = nonce_size_ - sizeof(packet_number);
+  if (use_ietf_nonce_construction_) {
+    for (size_t i = 0; i < sizeof(packet_number); ++i) {
+      nonce[prefix_len + i] ^=
+          (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
+    }
+  } else {
+    memcpy(nonce + prefix_len, &packet_number, sizeof(packet_number));
+  }
+  if (!EVP_AEAD_CTX_open(
+          ctx_.get(), reinterpret_cast<uint8_t*>(output), output_length,
+          max_output_length, reinterpret_cast<const uint8_t*>(nonce),
+          nonce_size_, reinterpret_cast<const uint8_t*>(ciphertext.data()),
+          ciphertext.size(),
+          reinterpret_cast<const uint8_t*>(associated_data.data()),
+          associated_data.size())) {
+    // Because QuicFramer does trial decryption, decryption errors are expected
+    // when encryption level changes. So we don't log decryption errors.
+    ClearOpenSslErrors();
+    return false;
+  }
+  return true;
+}
+
+size_t AeadBaseDecrypter::GetKeySize() const {
+  return key_size_;
+}
+
+size_t AeadBaseDecrypter::GetNoncePrefixSize() const {
+  return nonce_size_ - sizeof(QuicPacketNumber);
+}
+
+size_t AeadBaseDecrypter::GetIVSize() const {
+  return nonce_size_;
+}
+
+absl::string_view AeadBaseDecrypter::GetKey() const {
+  return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
+}
+
+absl::string_view AeadBaseDecrypter::GetNoncePrefix() const {
+  return absl::string_view(reinterpret_cast<const char*>(iv_),
+                           nonce_size_ - sizeof(QuicPacketNumber));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aead_base_decrypter.h b/quiche/quic/core/crypto/aead_base_decrypter.h
new file mode 100644
index 0000000..82a3e1c
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_decrypter.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// AeadBaseDecrypter is the base class of AEAD QuicDecrypter subclasses.
+class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
+ public:
+  // This takes the function pointer rather than the EVP_AEAD itself so
+  // subclasses do not need to call CRYPTO_library_init.
+  AeadBaseDecrypter(const EVP_AEAD* (*aead_getter)(),
+                    size_t key_size,
+                    size_t auth_tag_size,
+                    size_t nonce_size,
+                    bool use_ietf_nonce_construction);
+  AeadBaseDecrypter(const AeadBaseDecrypter&) = delete;
+  AeadBaseDecrypter& operator=(const AeadBaseDecrypter&) = delete;
+  ~AeadBaseDecrypter() override;
+
+  // QuicDecrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool SetPreliminaryKey(absl::string_view key) override;
+  bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
+  bool DecryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view ciphertext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+ protected:
+  // Make these constants available to the subclasses so that the subclasses
+  // can assert at compile time their key_size_ and nonce_size_ do not
+  // exceed the maximum.
+  static const size_t kMaxKeySize = 32;
+  static const size_t kMaxNonceSize = 12;
+
+ private:
+  const EVP_AEAD* const aead_alg_;
+  const size_t key_size_;
+  const size_t auth_tag_size_;
+  const size_t nonce_size_;
+  const bool use_ietf_nonce_construction_;
+  bool have_preliminary_key_;
+
+  // The key.
+  unsigned char key_[kMaxKeySize];
+  // The IV used to construct the nonce.
+  unsigned char iv_[kMaxNonceSize];
+
+  bssl::ScopedEVP_AEAD_CTX ctx_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aead_base_encrypter.cc b/quiche/quic/core/crypto/aead_base_encrypter.cc
new file mode 100644
index 0000000..e93f270
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_encrypter.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aead_base_encrypter.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// In debug builds only, log OpenSSL error stack. Then clear OpenSSL error
+// stack.
+void DLogOpenSslErrors() {
+#ifdef NDEBUG
+  while (ERR_get_error()) {
+  }
+#else
+  while (unsigned long error = ERR_get_error()) {
+    char buf[120];
+    ERR_error_string_n(error, buf, ABSL_ARRAYSIZE(buf));
+    QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
+  }
+#endif
+}
+
+const EVP_AEAD* InitAndCall(const EVP_AEAD* (*aead_getter)()) {
+  // Ensure BoringSSL is initialized before calling |aead_getter|. In Chromium,
+  // the static initializer is disabled.
+  CRYPTO_library_init();
+  return aead_getter();
+}
+
+}  // namespace
+
+AeadBaseEncrypter::AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
+                                     size_t key_size,
+                                     size_t auth_tag_size,
+                                     size_t nonce_size,
+                                     bool use_ietf_nonce_construction)
+    : aead_alg_(InitAndCall(aead_getter)),
+      key_size_(key_size),
+      auth_tag_size_(auth_tag_size),
+      nonce_size_(nonce_size),
+      use_ietf_nonce_construction_(use_ietf_nonce_construction) {
+  QUICHE_DCHECK_LE(key_size_, sizeof(key_));
+  QUICHE_DCHECK_LE(nonce_size_, sizeof(iv_));
+  QUICHE_DCHECK_GE(kMaxNonceSize, nonce_size_);
+}
+
+AeadBaseEncrypter::~AeadBaseEncrypter() {}
+
+bool AeadBaseEncrypter::SetKey(absl::string_view key) {
+  QUICHE_DCHECK_EQ(key.size(), key_size_);
+  if (key.size() != key_size_) {
+    return false;
+  }
+  memcpy(key_, key.data(), key.size());
+
+  EVP_AEAD_CTX_cleanup(ctx_.get());
+
+  if (!EVP_AEAD_CTX_init(ctx_.get(), aead_alg_, key_, key_size_, auth_tag_size_,
+                         nullptr)) {
+    DLogOpenSslErrors();
+    return false;
+  }
+
+  return true;
+}
+
+bool AeadBaseEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  if (use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10634_1)
+        << "Attempted to set nonce prefix on IETF QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(nonce_prefix.size(), nonce_size_ - sizeof(QuicPacketNumber));
+  if (nonce_prefix.size() != nonce_size_ - sizeof(QuicPacketNumber)) {
+    return false;
+  }
+  memcpy(iv_, nonce_prefix.data(), nonce_prefix.size());
+  return true;
+}
+
+bool AeadBaseEncrypter::SetIV(absl::string_view iv) {
+  if (!use_ietf_nonce_construction_) {
+    QUIC_BUG(quic_bug_10634_2) << "Attempted to set IV on Google QUIC crypter";
+    return false;
+  }
+  QUICHE_DCHECK_EQ(iv.size(), nonce_size_);
+  if (iv.size() != nonce_size_) {
+    return false;
+  }
+  memcpy(iv_, iv.data(), iv.size());
+  return true;
+}
+
+bool AeadBaseEncrypter::Encrypt(absl::string_view nonce,
+                                absl::string_view associated_data,
+                                absl::string_view plaintext,
+                                unsigned char* output) {
+  QUICHE_DCHECK_EQ(nonce.size(), nonce_size_);
+
+  size_t ciphertext_len;
+  if (!EVP_AEAD_CTX_seal(
+          ctx_.get(), output, &ciphertext_len,
+          plaintext.size() + auth_tag_size_,
+          reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
+          reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
+          reinterpret_cast<const uint8_t*>(associated_data.data()),
+          associated_data.size())) {
+    DLogOpenSslErrors();
+    return false;
+  }
+
+  return true;
+}
+
+bool AeadBaseEncrypter::EncryptPacket(uint64_t packet_number,
+                                      absl::string_view associated_data,
+                                      absl::string_view plaintext,
+                                      char* output,
+                                      size_t* output_length,
+                                      size_t max_output_length) {
+  size_t ciphertext_size = GetCiphertextSize(plaintext.length());
+  if (max_output_length < ciphertext_size) {
+    return false;
+  }
+  // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
+  // same packet number twice.
+  alignas(4) char nonce_buffer[kMaxNonceSize];
+  memcpy(nonce_buffer, iv_, nonce_size_);
+  size_t prefix_len = nonce_size_ - sizeof(packet_number);
+  if (use_ietf_nonce_construction_) {
+    for (size_t i = 0; i < sizeof(packet_number); ++i) {
+      nonce_buffer[prefix_len + i] ^=
+          (packet_number >> ((sizeof(packet_number) - i - 1) * 8)) & 0xff;
+    }
+  } else {
+    memcpy(nonce_buffer + prefix_len, &packet_number, sizeof(packet_number));
+  }
+
+  if (!Encrypt(absl::string_view(nonce_buffer, nonce_size_), associated_data,
+               plaintext, reinterpret_cast<unsigned char*>(output))) {
+    return false;
+  }
+  *output_length = ciphertext_size;
+  return true;
+}
+
+size_t AeadBaseEncrypter::GetKeySize() const {
+  return key_size_;
+}
+
+size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
+  return nonce_size_ - sizeof(QuicPacketNumber);
+}
+
+size_t AeadBaseEncrypter::GetIVSize() const {
+  return nonce_size_;
+}
+
+size_t AeadBaseEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
+  return ciphertext_size - std::min(ciphertext_size, auth_tag_size_);
+}
+
+size_t AeadBaseEncrypter::GetCiphertextSize(size_t plaintext_size) const {
+  return plaintext_size + auth_tag_size_;
+}
+
+absl::string_view AeadBaseEncrypter::GetKey() const {
+  return absl::string_view(reinterpret_cast<const char*>(key_), key_size_);
+}
+
+absl::string_view AeadBaseEncrypter::GetNoncePrefix() const {
+  return absl::string_view(reinterpret_cast<const char*>(iv_),
+                           GetNoncePrefixSize());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aead_base_encrypter.h b/quiche/quic/core/crypto/aead_base_encrypter.h
new file mode 100644
index 0000000..c170a87
--- /dev/null
+++ b/quiche/quic/core/crypto/aead_base_encrypter.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// AeadBaseEncrypter is the base class of AEAD QuicEncrypter subclasses.
+class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
+ public:
+  // This takes the function pointer rather than the EVP_AEAD itself so
+  // subclasses do not need to call CRYPTO_library_init.
+  AeadBaseEncrypter(const EVP_AEAD* (*aead_getter)(),
+                    size_t key_size,
+                    size_t auth_tag_size,
+                    size_t nonce_size,
+                    bool use_ietf_nonce_construction);
+  AeadBaseEncrypter(const AeadBaseEncrypter&) = delete;
+  AeadBaseEncrypter& operator=(const AeadBaseEncrypter&) = delete;
+  ~AeadBaseEncrypter() override;
+
+  // QuicEncrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool EncryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view plaintext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
+  size_t GetCiphertextSize(size_t plaintext_size) const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+  // Necessary so unit tests can explicitly specify a nonce, instead of an IV
+  // (or nonce prefix) and packet number.
+  bool Encrypt(absl::string_view nonce,
+               absl::string_view associated_data,
+               absl::string_view plaintext,
+               unsigned char* output);
+
+ protected:
+  // Make these constants available to the subclasses so that the subclasses
+  // can assert at compile time their key_size_ and nonce_size_ do not
+  // exceed the maximum.
+  static const size_t kMaxKeySize = 32;
+  enum : size_t { kMaxNonceSize = 12 };
+
+ private:
+  const EVP_AEAD* const aead_alg_;
+  const size_t key_size_;
+  const size_t auth_tag_size_;
+  const size_t nonce_size_;
+  const bool use_ietf_nonce_construction_;
+
+  // The key.
+  unsigned char key_[kMaxKeySize];
+  // The IV used to construct the nonce.
+  unsigned char iv_[kMaxNonceSize];
+
+  bssl::ScopedEVP_AEAD_CTX ctx_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AEAD_BASE_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc
new file mode 100644
index 0000000..8c6fd1d
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
+    : AesBaseDecrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {}
+
+uint32_t Aes128Gcm12Decrypter::cipher_id() const {
+  return TLS1_CK_AES_128_GCM_SHA256;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h
new file mode 100644
index 0000000..38a9419
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128Gcm12Decrypter is a QuicDecrypter that implements the
+// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
+// calling QuicDecrypter::Create(kAESG).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
+// of the nonce is four bytes.
+class QUIC_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AesBaseDecrypter {
+ public:
+  enum {
+    // Authentication tags are truncated to 96 bits.
+    kAuthTagSize = 12,
+  };
+
+  Aes128Gcm12Decrypter();
+  Aes128Gcm12Decrypter(const Aes128Gcm12Decrypter&) = delete;
+  Aes128Gcm12Decrypter& operator=(const Aes128Gcm12Decrypter&) = delete;
+  ~Aes128Gcm12Decrypter() override;
+
+  uint32_t cipher_id() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
new file mode 100644
index 0000000..64e11eb
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
@@ -0,0 +1,288 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmDecrypt128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = cf063a34d4a9a76c2c86787d3f96db71
+// IV = 113b9785971864c83b01c787
+// CT =
+// AAD =
+// Tag = 72ac8493e3a5228b5d130a69d2510e42
+// PT =
+//
+// Count = 1
+// Key = a49a5e26a2f8cb63d05546c2a62f5343
+// IV = 907763b19b9b4ab6bd4f0281
+// CT =
+// AAD =
+// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
+// FAIL
+//
+// ...
+//
+// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* ct;
+  const char* aad;
+  const char* tag;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
+     "72ac8493e3a5228b5d130a69d2510e42", ""},
+    {
+        "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
+        "a2be08210d8c470a8df6e8fbd79ec5cf",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {
+        "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
+        "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
+        nullptr  // FAIL
+    },
+    {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
+     "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
+     ""},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
+     "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
+     "28286a321293253c3e0aa2704a278032"},
+    {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
+     "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
+     "95695a5b12f2870b9cc5fdc8f218a97d"},
+    {
+        "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
+        "0216c899c88d6e32c958c7e553daa5bc", "",
+        "a145319896329c96df291f64efbe0e3a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
+     "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
+     "338b22f9bad09093276a331e9c79c7f4",
+     "41dc38988945fcb44faf2ef72d0061289ef8efd8",
+     "4f71e72bde0018f555c5adcce062e005",
+     "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
+     "5b2f69b041596e8817d0a3c16f8fadeb"},
+    {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
+     "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
+     "f401823e04b05817243d2142a3589878",
+     "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
+     "534d9234d2351cf30e565de47baece0b",
+     "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
+     "353a18017f5b36bfc00b1f6dcb7ed485"},
+    {
+        "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
+        "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
+        "32b992760b3a5f99e9a47838867000a9",
+        "93c4fc6a4135f54d640b0c976bf755a06a292c33",
+        "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
+     "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
+     "f4ee16c761b3c9aeac3da03aa9889c88",
+     "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
+     "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
+     "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
+     "9e3ac938d3eb0cadd6f5c9e35d22ba38",
+     "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
+     "d65dbd1378b196ac270588dd0621f642"},
+    {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
+     "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
+     "b0f1420be29ea547d42c713bc6af66aa",
+     "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
+     "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
+     "34a6039312774cedebf4961f3978b14a26509f96",
+     "e192c23cb036f0b31592989119eed55d",
+     "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
+     "f0a34bc305b88b804c60b90add594a17"},
+    {
+        "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
+        "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
+        "43edfd365b90d5b325950df0ada058f9",
+        "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
+        "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
+        "72c2cb136c8fd091cc4539877a5d1e72d607f960",
+        "8b347853f11d75e81e8a95010be81f17",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
+     "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
+     "48f5b426baca03064554cc2b30"},
+    {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
+     "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
+     "46a2e55c8e264df211bd112685"},
+    {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
+     "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
+     "3b95b981086ee73cc4d0cc1422"},
+    {
+        "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
+        "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  uint64_t packet_number;
+  absl::string_view nonce_prefix(nonce.data(),
+                                 nonce.size() - sizeof(packet_number));
+  decrypter->SetNoncePrefix(nonce_prefix);
+  memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
+         sizeof(packet_number));
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success = decrypter->DecryptPacket(
+      packet_number, associated_data, ciphertext, output.get(), &output_length,
+      ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class Aes128Gcm12DecrypterTest : public QuicTest {};
+
+TEST_F(Aes128Gcm12DecrypterTest, Decrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // If not present then decryption is expected to fail.
+      bool has_pt = test_vectors[j].pt;
+
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+      std::string pt;
+      if (has_pt) {
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
+      }
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+      if (has_pt) {
+        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      }
+
+      // The test vectors have 16 byte authenticators but this code only uses
+      // the first 12.
+      ASSERT_LE(static_cast<size_t>(Aes128Gcm12Decrypter::kAuthTagSize),
+                tag.length());
+      tag.resize(Aes128Gcm12Decrypter::kAuthTagSize);
+      std::string ciphertext = ct + tag;
+
+      Aes128Gcm12Decrypter decrypter;
+      ASSERT_TRUE(decrypter.SetKey(key));
+
+      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+          &decrypter, iv,
+          // This deliberately tests that the decrypter can
+          // handle an AAD that is set to nullptr, as opposed
+          // to a zero-length, non-nullptr pointer.
+          aad.length() ? aad : absl::string_view(), ciphertext));
+      if (!decrypted) {
+        EXPECT_FALSE(has_pt);
+        continue;
+      }
+      EXPECT_TRUE(has_pt);
+
+      ASSERT_EQ(pt.length(), decrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+    }
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc
new file mode 100644
index 0000000..1018c41
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128Gcm12Encrypter::Aes128Gcm12Encrypter()
+    : AesBaseEncrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h
new file mode 100644
index 0000000..64f0292
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128Gcm12Encrypter is a QuicEncrypter that implements the
+// AEAD_AES_128_GCM_12 algorithm specified in RFC 5282. Create an instance by
+// calling QuicEncrypter::Create(kAESG).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
+// of the nonce is four bytes.
+class QUIC_EXPORT_PRIVATE Aes128Gcm12Encrypter : public AesBaseEncrypter {
+ public:
+  enum {
+    // Authentication tags are truncated to 96 bits.
+    kAuthTagSize = 12,
+  };
+
+  Aes128Gcm12Encrypter();
+  Aes128Gcm12Encrypter(const Aes128Gcm12Encrypter&) = delete;
+  Aes128Gcm12Encrypter& operator=(const Aes128Gcm12Encrypter&) = delete;
+  ~Aes128Gcm12Encrypter() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_12_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
new file mode 100644
index 0000000..47dbd67
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -0,0 +1,244 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = 11754cd72aec309bf52f7687212e8957
+// IV = 3c819d9a9bed087615030b65
+// PT =
+// AAD =
+// CT =
+// Tag = 250327c674aaf477aef2675748cf6971
+//
+// Count = 1
+// Key = ca47248ac0b6f8372a97ac43508308ed
+// IV = ffd2b598feabc9019262d2be
+// PT =
+// AAD =
+// CT =
+// Tag = 60d20404af527d248d893ae495707d1a
+//
+// ...
+//
+// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* iv;
+  const char* pt;
+  const char* aad;
+  const char* ct;
+  const char* tag;
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
+     "250327c674aaf477aef2675748cf6971"},
+    {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
+     "60d20404af527d248d893ae495707d1a"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
+     "7a43ec1d9c0a5a78a0b16533a6213cab", "",
+     "209fcc8d3675ed938e9c7166709dd946"},
+    {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
+     "c94c410194c765e3dcc7964379758ed3", "",
+     "94dca8edfcf90bb74b153c8d48a17930"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
+     "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
+     "b36d1df9b9d5e596f83e8b7f52971cb3"},
+    {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
+     "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
+     "2b4401346697138c7a4891ee59867d0c"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
+     "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
+     "b840382c4bccaf3bafb4ca8429bea063",
+     "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
+     "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
+     "3ddbc5db8778371495da76d269e5db3e",
+     "291ef1982e4defedaa2249f898556b47"},
+    {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
+     "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
+     "b764b9611f6c0f8641843d5d58f3a242",
+     "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
+     "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
+     "5506fde6309ffc19e716eddf1a828c5a",
+     "890147971946b627c40016da1ecf3e77"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
+     "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
+     "8b5615ba7c1220ff6510e259f06655d8",
+     "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
+     "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
+     "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
+     "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
+     "b6ad57af43e1895df9dca2a5344a62cc",
+     "57a3ee28136e94c74838997ae9823f3a"},
+    {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
+     "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
+     "c2c6f6166f4a59431e182663fcaea05a",
+     "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
+     "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
+     "15d2e51398344b16bee1ed7c499b353d6c597af8",
+     "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
+     "3c7891c2a91fbc48db29967ec9542b23",
+     "21b51ca862cb637cdd03b99a0f93b134"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
+     "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
+     "43fd4727fe5cdb4b5b42818dea7ef8c9"},
+    {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
+     "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
+     "38e6bcd29962e5f2c13626b85a877101"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class Aes128Gcm12EncrypterTest : public QuicTest {};
+
+TEST_F(Aes128Gcm12EncrypterTest, Encrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+
+      Aes128Gcm12Encrypter encrypter;
+      ASSERT_TRUE(encrypter.SetKey(key));
+      std::unique_ptr<QuicData> encrypted(
+          EncryptWithNonce(&encrypter, iv,
+                           // This deliberately tests that the encrypter can
+                           // handle an AAD that is set to nullptr, as opposed
+                           // to a zero-length, non-nullptr pointer.
+                           aad.length() ? aad : absl::string_view(), pt));
+      ASSERT_TRUE(encrypted.get());
+
+      // The test vectors have 16 byte authenticators but this code only uses
+      // the first 12.
+      ASSERT_LE(static_cast<size_t>(Aes128Gcm12Encrypter::kAuthTagSize),
+                tag.length());
+      tag.resize(Aes128Gcm12Encrypter::kAuthTagSize);
+
+      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
+      quiche::test::CompareCharArraysWithHexError(
+          "authentication tag", encrypted->data() + ct.length(), tag.length(),
+          tag.data(), tag.length());
+    }
+  }
+}
+
+TEST_F(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) {
+  Aes128Gcm12Encrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+  EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
+}
+
+TEST_F(Aes128Gcm12EncrypterTest, GetCiphertextSize) {
+  Aes128Gcm12Encrypter encrypter;
+  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc
new file mode 100644
index 0000000..d714ca0
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128GcmDecrypter::Aes128GcmDecrypter()
+    : AesBaseDecrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128GcmDecrypter::~Aes128GcmDecrypter() {}
+
+uint32_t Aes128GcmDecrypter::cipher_id() const {
+  return TLS1_CK_AES_128_GCM_SHA256;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_decrypter.h b/quiche/quic/core/crypto/aes_128_gcm_decrypter.h
new file mode 100644
index 0000000..c5f4d17
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_decrypter.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128GcmDecrypter is a QuicDecrypter that implements the
+// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes128GcmDecrypter : public AesBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes128GcmDecrypter();
+  Aes128GcmDecrypter(const Aes128GcmDecrypter&) = delete;
+  Aes128GcmDecrypter& operator=(const Aes128GcmDecrypter&) = delete;
+  ~Aes128GcmDecrypter() override;
+
+  uint32_t cipher_id() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_decrypter_test.cc
new file mode 100644
index 0000000..e02b433
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_decrypter_test.cc
@@ -0,0 +1,291 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmDecrypt128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = cf063a34d4a9a76c2c86787d3f96db71
+// IV = 113b9785971864c83b01c787
+// CT =
+// AAD =
+// Tag = 72ac8493e3a5228b5d130a69d2510e42
+// PT =
+//
+// Count = 1
+// Key = a49a5e26a2f8cb63d05546c2a62f5343
+// IV = 907763b19b9b4ab6bd4f0281
+// CT =
+// AAD =
+// Tag = a2be08210d8c470a8df6e8fbd79ec5cf
+// FAIL
+//
+// ...
+//
+// The gcmDecrypt128.rsp file is huge (2.6 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* ct;
+  const char* aad;
+  const char* tag;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"cf063a34d4a9a76c2c86787d3f96db71", "113b9785971864c83b01c787", "", "",
+     "72ac8493e3a5228b5d130a69d2510e42", ""},
+    {
+        "a49a5e26a2f8cb63d05546c2a62f5343", "907763b19b9b4ab6bd4f0281", "", "",
+        "a2be08210d8c470a8df6e8fbd79ec5cf",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {
+        "d1f6af919cde85661208bdce0c27cb22", "898c6929b435017bf031c3c5", "",
+        "7c5faa40e636bbc91107e68010c92b9f", "ae45f11777540a2caeb128be8092468a",
+        nullptr  // FAIL
+    },
+    {"2370e320d4344208e0ff5683f243b213", "04dbb82f044d30831c441228", "",
+     "d43a8e5089eea0d026c03a85178b27da", "2a049c049d25aa95969b451d93c31c6e",
+     ""},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"e98b72a9881a84ca6b76e0f43e68647a", "8b23299fde174053f3d652ba",
+     "5a3c1cf1985dbb8bed818036fdd5ab42", "", "23c7ab0f952b7091cd324835043b5eb5",
+     "28286a321293253c3e0aa2704a278032"},
+    {"33240636cd3236165f1a553b773e728e", "17c4d61493ecdc8f31700b12",
+     "47bb7e23f7bdfe05a8091ac90e4f8b2e", "", "b723c70e931d9785f40fd4ab1d612dc9",
+     "95695a5b12f2870b9cc5fdc8f218a97d"},
+    {
+        "5164df856f1e9cac04a79b808dc5be39", "e76925d5355e0584ce871b2b",
+        "0216c899c88d6e32c958c7e553daa5bc", "",
+        "a145319896329c96df291f64efbe0e3a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"af57f42c60c0fc5a09adb81ab86ca1c3", "a2dc01871f37025dc0fc9a79",
+     "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947"
+     "338b22f9bad09093276a331e9c79c7f4",
+     "41dc38988945fcb44faf2ef72d0061289ef8efd8",
+     "4f71e72bde0018f555c5adcce062e005",
+     "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa7279"
+     "5b2f69b041596e8817d0a3c16f8fadeb"},
+    {"ebc753e5422b377d3cb64b58ffa41b61", "2e1821efaced9acf1f241c9b",
+     "069567190554e9ab2b50a4e1fbf9c147340a5025fdbd201929834eaf6532325899ccb9"
+     "f401823e04b05817243d2142a3589878",
+     "b9673412fd4f88ba0e920f46dd6438ff791d8eef",
+     "534d9234d2351cf30e565de47baece0b",
+     "39077edb35e9c5a4b1e4c2a6b9bb1fce77f00f5023af40333d6d699014c2bcf4209c18"
+     "353a18017f5b36bfc00b1f6dcb7ed485"},
+    {
+        "52bdbbf9cf477f187ec010589cb39d58", "d3be36d3393134951d324b31",
+        "700188da144fa692cf46e4a8499510a53d90903c967f7f13e8a1bd8151a74adc4fe63e"
+        "32b992760b3a5f99e9a47838867000a9",
+        "93c4fc6a4135f54d640b0c976bf755a06a292c33",
+        "8ca4e38aa3dfa6b1d0297021ccf3ea5f",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"da2bb7d581493d692380c77105590201", "44aa3e7856ca279d2eb020c6",
+     "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1a"
+     "f4ee16c761b3c9aeac3da03aa9889c88",
+     "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab"
+     "12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d7"
+     "2ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
+     "9e3ac938d3eb0cadd6f5c9e35d22ba38",
+     "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3a"
+     "d65dbd1378b196ac270588dd0621f642"},
+    {"d74e4958717a9d5c0e235b76a926cae8", "0b7471141e0c70b1995fd7b1",
+     "e701c57d2330bf066f9ff8cf3ca4343cafe4894651cd199bdaaa681ba486b4a65c5a22"
+     "b0f1420be29ea547d42c713bc6af66aa",
+     "4a42b7aae8c245c6f1598a395316e4b8484dbd6e64648d5e302021b1d3fa0a38f46e22"
+     "bd9c8080b863dc0016482538a8562a4bd0ba84edbe2697c76fd039527ac179ec5506cf"
+     "34a6039312774cedebf4961f3978b14a26509f96",
+     "e192c23cb036f0b31592989119eed55d",
+     "840d9fb95e32559fb3602e48590280a172ca36d9b49ab69510f5bd552bfab7a306f85f"
+     "f0a34bc305b88b804c60b90add594a17"},
+    {
+        "1986310c725ac94ecfe6422e75fc3ee7", "93ec4214fa8e6dc4e3afc775",
+        "b178ec72f85a311ac4168f42a4b2c23113fbea4b85f4b9dabb74e143eb1b8b0a361e02"
+        "43edfd365b90d5b325950df0ada058f9",
+        "e80b88e62c49c958b5e0b8b54f532d9ff6aa84c8a40132e93e55b59fc24e8decf28463"
+        "139f155d1e8ce4ee76aaeefcd245baa0fc519f83a5fb9ad9aa40c4b21126013f576c42"
+        "72c2cb136c8fd091cc4539877a5d1e72d607f960",
+        "8b347853f11d75e81e8a95010be81f17",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"387218b246c1a8257748b56980e50c94", "dd7e014198672be39f95b69d",
+     "cdba9e73eaf3d38eceb2b04a8d", "", "ecf90f4a47c9c626d6fb2c765d201556",
+     "48f5b426baca03064554cc2b30"},
+    {"294de463721e359863887c820524b3d4", "3338b35c9d57a5d28190e8c9",
+     "2f46634e74b8e4c89812ac83b9", "", "dabd506764e68b82a7e720aa18da0abe",
+     "46a2e55c8e264df211bd112685"},
+    {"28ead7fd2179e0d12aa6d5d88c58c2dc", "5055347f18b4d5add0ae5c41",
+     "142d8210c3fb84774cdbd0447a", "", "5fd321d9cdb01952dc85f034736c2a7d",
+     "3b95b981086ee73cc4d0cc1422"},
+    {
+        "7d7b6c988137b8d470c57bf674a09c87", "9edf2aa970d016ac962e1fd8",
+        "a85b66c3cb5eab91d5bdc8bc0e", "", "dc054efc01f3afd21d9c2484819f569a",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  decrypter->SetIV(nonce);
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success =
+      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
+                               &output_length, ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class Aes128GcmDecrypterTest : public QuicTest {};
+
+TEST_F(Aes128GcmDecrypterTest, Decrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // If not present then decryption is expected to fail.
+      bool has_pt = test_vectors[j].pt;
+
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+      std::string pt;
+      if (has_pt) {
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
+      }
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+      if (has_pt) {
+        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      }
+      std::string ciphertext = ct + tag;
+
+      Aes128GcmDecrypter decrypter;
+      ASSERT_TRUE(decrypter.SetKey(key));
+
+      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+          &decrypter, iv,
+          // This deliberately tests that the decrypter can
+          // handle an AAD that is set to nullptr, as opposed
+          // to a zero-length, non-nullptr pointer.
+          aad.length() ? aad : absl::string_view(), ciphertext));
+      if (!decrypted) {
+        EXPECT_FALSE(has_pt);
+        continue;
+      }
+      EXPECT_TRUE(has_pt);
+
+      ASSERT_EQ(pt.length(), decrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+    }
+  }
+}
+
+TEST_F(Aes128GcmDecrypterTest, GenerateHeaderProtectionMask) {
+  Aes128GcmDecrypter decrypter;
+  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
+  std::string sample =
+      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
+  QuicDataReader sample_reader(sample.data(), sample.size());
+  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
+  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
+  std::string expected_mask =
+      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc b/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc
new file mode 100644
index 0000000..56f698f
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 16;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes128GcmEncrypter::Aes128GcmEncrypter()
+    : AesBaseEncrypter(EVP_aead_aes_128_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes128GcmEncrypter::~Aes128GcmEncrypter() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_128_gcm_encrypter.h b/quiche/quic/core/crypto/aes_128_gcm_encrypter.h
new file mode 100644
index 0000000..a40735c
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_encrypter.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes128GcmEncrypter is a QuicEncrypter that implements the
+// AEAD_AES_128_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes128GcmEncrypter : public AesBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes128GcmEncrypter();
+  Aes128GcmEncrypter(const Aes128GcmEncrypter&) = delete;
+  Aes128GcmEncrypter& operator=(const Aes128GcmEncrypter&) = delete;
+  ~Aes128GcmEncrypter() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_128_GCM_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/quiche/quic/core/crypto/aes_128_gcm_encrypter_test.cc
new file mode 100644
index 0000000..7086094
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_128_gcm_encrypter_test.cc
@@ -0,0 +1,273 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmEncryptExtIV128.rsp
+// downloaded from http://csrc.nist.gov/groups/STM/cavp/index.html on
+// 2013-02-01. The test vectors in that file look like this:
+//
+// [Keylen = 128]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = 11754cd72aec309bf52f7687212e8957
+// IV = 3c819d9a9bed087615030b65
+// PT =
+// AAD =
+// CT =
+// Tag = 250327c674aaf477aef2675748cf6971
+//
+// Count = 1
+// Key = ca47248ac0b6f8372a97ac43508308ed
+// IV = ffd2b598feabc9019262d2be
+// PT =
+// AAD =
+// CT =
+// Tag = 60d20404af527d248d893ae495707d1a
+//
+// ...
+//
+// The gcmEncryptExtIV128.rsp file is huge (2.8 MB), so I selected just a
+// few test vectors for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* iv;
+  const char* pt;
+  const char* aad;
+  const char* ct;
+  const char* tag;
+};
+
+const TestGroupInfo test_group_info[] = {
+    {128, 96, 0, 0, 128},     {128, 96, 0, 128, 128},   {128, 96, 128, 0, 128},
+    {128, 96, 408, 160, 128}, {128, 96, 408, 720, 128}, {128, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", "", "",
+     "250327c674aaf477aef2675748cf6971"},
+    {"ca47248ac0b6f8372a97ac43508308ed", "ffd2b598feabc9019262d2be", "", "", "",
+     "60d20404af527d248d893ae495707d1a"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"77be63708971c4e240d1cb79e8d77feb", "e0e00f19fed7ba0136a797f3", "",
+     "7a43ec1d9c0a5a78a0b16533a6213cab", "",
+     "209fcc8d3675ed938e9c7166709dd946"},
+    {"7680c5d3ca6154758e510f4d25b98820", "f8f105f9c3df4965780321f8", "",
+     "c94c410194c765e3dcc7964379758ed3", "",
+     "94dca8edfcf90bb74b153c8d48a17930"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"7fddb57453c241d03efbed3ac44e371c", "ee283a3fc75575e33efd4887",
+     "d5de42b461646c255c87bd2962d3b9a2", "", "2ccda4a5415cb91e135c2a0f78c9b2fd",
+     "b36d1df9b9d5e596f83e8b7f52971cb3"},
+    {"ab72c77b97cb5fe9a382d9fe81ffdbed", "54cc7dc2c37ec006bcc6d1da",
+     "007c5e5b3e59df24a7c355584fc1518d", "", "0e1bde206a07a9c2c1b65300f8c64997",
+     "2b4401346697138c7a4891ee59867d0c"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"fe47fcce5fc32665d2ae399e4eec72ba", "5adb9609dbaeb58cbd6e7275",
+     "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1"
+     "b840382c4bccaf3bafb4ca8429bea063",
+     "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
+     "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf539304373636525"
+     "3ddbc5db8778371495da76d269e5db3e",
+     "291ef1982e4defedaa2249f898556b47"},
+    {"ec0c2ba17aa95cd6afffe949da9cc3a8", "296bce5b50b7d66096d627ef",
+     "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987"
+     "b764b9611f6c0f8641843d5d58f3a242",
+     "f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
+     "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a0716299"
+     "5506fde6309ffc19e716eddf1a828c5a",
+     "890147971946b627c40016da1ecf3e77"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"2c1f21cf0f6fb3661943155c3e3d8492", "23cb5ff362e22426984d1907",
+     "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d6"
+     "8b5615ba7c1220ff6510e259f06655d8",
+     "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e"
+     "3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f"
+     "4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
+     "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222"
+     "b6ad57af43e1895df9dca2a5344a62cc",
+     "57a3ee28136e94c74838997ae9823f3a"},
+    {"d9f7d2411091f947b4d6f1e2d1f0fb2e", "e1934f5db57cc983e6b180e7",
+     "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490"
+     "c2c6f6166f4a59431e182663fcaea05a",
+     "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d"
+     "0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a201"
+     "15d2e51398344b16bee1ed7c499b353d6c597af8",
+     "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d57"
+     "3c7891c2a91fbc48db29967ec9542b23",
+     "21b51ca862cb637cdd03b99a0f93b134"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"fe9bb47deb3a61e423c2231841cfd1fb", "4d328eb776f500a2f7fb47aa",
+     "f1cc3818e421876bb6b8bbd6c9", "", "b88c5c1977b35b517b0aeae967",
+     "43fd4727fe5cdb4b5b42818dea7ef8c9"},
+    {"6703df3701a7f54911ca72e24dca046a", "12823ab601c350ea4bc2488c",
+     "793cd125b0b84a043e3ac67717", "", "b2051c80014f42f08735a7b0cd",
+     "38e6bcd29962e5f2c13626b85a877101"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class Aes128GcmEncrypterTest : public QuicTest {};
+
+TEST_F(Aes128GcmEncrypterTest, Encrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+
+      Aes128GcmEncrypter encrypter;
+      ASSERT_TRUE(encrypter.SetKey(key));
+      std::unique_ptr<QuicData> encrypted(
+          EncryptWithNonce(&encrypter, iv,
+                           // This deliberately tests that the encrypter can
+                           // handle an AAD that is set to nullptr, as opposed
+                           // to a zero-length, non-nullptr pointer.
+                           aad.length() ? aad : absl::string_view(), pt));
+      ASSERT_TRUE(encrypted.get());
+
+      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
+      quiche::test::CompareCharArraysWithHexError(
+          "authentication tag", encrypted->data() + ct.length(), tag.length(),
+          tag.data(), tag.length());
+    }
+  }
+}
+
+TEST_F(Aes128GcmEncrypterTest, EncryptPacket) {
+  std::string key = absl::HexStringToBytes("d95a145250826c25a77b6a84fd4d34fc");
+  std::string iv = absl::HexStringToBytes("50c4431ebb18283448e276e2");
+  uint64_t packet_num = 0x13278f44;
+  std::string aad =
+      absl::HexStringToBytes("875d49f64a70c9cbe713278f44ff000005");
+  std::string pt = absl::HexStringToBytes("aa0003a250bd000000000001");
+  std::string ct = absl::HexStringToBytes(
+      "7dd4708b989ee7d38a013e3656e9b37beefd05808fe1ab41e3b4f2c0");
+
+  std::vector<char> out(ct.size());
+  size_t out_size;
+
+  Aes128GcmEncrypter encrypter;
+  ASSERT_TRUE(encrypter.SetKey(key));
+  ASSERT_TRUE(encrypter.SetIV(iv));
+  ASSERT_TRUE(encrypter.EncryptPacket(packet_num, aad, pt, out.data(),
+                                      &out_size, out.size()));
+  EXPECT_EQ(out_size, out.size());
+  quiche::test::CompareCharArraysWithHexError("ciphertext", out.data(),
+                                              out.size(), ct.data(), ct.size());
+}
+
+TEST_F(Aes128GcmEncrypterTest, GetMaxPlaintextSize) {
+  Aes128GcmEncrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+}
+
+TEST_F(Aes128GcmEncrypterTest, GetCiphertextSize) {
+  Aes128GcmEncrypter encrypter;
+  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+}
+
+TEST_F(Aes128GcmEncrypterTest, GenerateHeaderProtectionMask) {
+  Aes128GcmEncrypter encrypter;
+  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
+  std::string sample =
+      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
+  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
+  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
+  std::string expected_mask =
+      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc b/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc
new file mode 100644
index 0000000..f0cdc37
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_256_gcm_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes256GcmDecrypter::Aes256GcmDecrypter()
+    : AesBaseDecrypter(EVP_aead_aes_256_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes256GcmDecrypter::~Aes256GcmDecrypter() {}
+
+uint32_t Aes256GcmDecrypter::cipher_id() const {
+  return TLS1_CK_AES_256_GCM_SHA384;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_decrypter.h b/quiche/quic/core/crypto/aes_256_gcm_decrypter.h
new file mode 100644
index 0000000..dc4f8c0
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_decrypter.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes256GcmDecrypter is a QuicDecrypter that implements the
+// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes256GcmDecrypter : public AesBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes256GcmDecrypter();
+  Aes256GcmDecrypter(const Aes256GcmDecrypter&) = delete;
+  Aes256GcmDecrypter& operator=(const Aes256GcmDecrypter&) = delete;
+  ~Aes256GcmDecrypter() override;
+
+  uint32_t cipher_id() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/quiche/quic/core/crypto/aes_256_gcm_decrypter_test.cc
new file mode 100644
index 0000000..7c48c8c
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_decrypter_test.cc
@@ -0,0 +1,297 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_256_gcm_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmDecrypt256.rsp
+// downloaded from
+// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
+// on 2017-09-27. The test vectors in that file look like this:
+//
+// [Keylen = 256]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010
+// IV = 58d2240f580a31c1d24948e9
+// CT =
+// AAD =
+// Tag = 15e051a5e4a5f5da6cea92e2ebee5bac
+// PT =
+//
+// Count = 1
+// Key = e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831
+// IV = 51e43385bf533e168427e1ad
+// CT =
+// AAD =
+// Tag = 38fe845c66e66bdd884c2aecafd280e6
+// FAIL
+//
+// ...
+//
+// The gcmDecrypt256.rsp file is huge (3.0 MB), so a few test vectors were
+// selected for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* ct;
+  const char* aad;
+  const char* tag;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestGroupInfo test_group_info[] = {
+    {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
+    {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010",
+     "58d2240f580a31c1d24948e9", "", "", "15e051a5e4a5f5da6cea92e2ebee5bac",
+     ""},
+    {
+        "e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831",
+        "51e43385bf533e168427e1ad", "", "", "38fe845c66e66bdd884c2aecafd280e6",
+        nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"6dfdafd6703c285c01f14fd10a6012862b2af950d4733abb403b2e745b26945d",
+     "3749d0b3d5bacb71be06ade6", "", "c0d249871992e70302ae008193d1e89f",
+     "4aa4cc69f84ee6ac16d9bfb4e05de500", ""},
+    {
+        "2c392a5eb1a9c705371beda3a901c7c61dca4d93b4291de1dd0dd15ec11ffc45",
+        "0723fb84a08f4ea09841f32a", "", "140be561b6171eab942c486a94d33d43",
+        "aa0e1c9b57975bfc91aa137231977d2c", nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"4c8ebfe1444ec1b2d503c6986659af2c94fafe945f72c1e8486a5acfedb8a0f8",
+     "473360e0ad24889959858995", "d2c78110ac7e8f107c0df0570bd7c90c", "",
+     "c26a379b6d98ef2852ead8ce83a833a7", "7789b41cb3ee548814ca0b388c10b343"},
+    {"3934f363fd9f771352c4c7a060682ed03c2864223a1573b3af997e2ababd60ab",
+     "efe2656d878c586e41c539c4", "e0de64302ac2d04048d65a87d2ad09fe", "",
+     "33cbd8d2fb8a3a03e30c1eb1b53c1d99", "697aff2d6b77e5ed6232770e400c1ead"},
+    {
+        "c997768e2d14e3d38259667a6649079de77beb4543589771e5068e6cd7cd0b14",
+        "835090aed9552dbdd45277e2", "9f6607d68e22ccf21928db0986be126e", "",
+        "f32617f67c574fd9f44ef76ff880ab9f", nullptr  // FAIL
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {
+        "e9d381a9c413bee66175d5586a189836e5c20f5583535ab4d3f3e612dc21700e",
+        "23e81571da1c7821c681c7ca",
+        "a25f3f580306cd5065d22a6b7e9660110af7204bb77d370f7f34bee547feeff7b32a59"
+        "6fce29c9040e68b1589aad48da881990",
+        "6f39c9ae7b8e8a58a95f0dd8ea6a9087cbccdfd6",
+        "5b6dcd70eefb0892fab1539298b92a4b",
+        nullptr  // FAIL
+    },
+    {"6450d4501b1e6cfbe172c4c8570363e96b496591b842661c28c2f6c908379cad",
+     "7e4262035e0bf3d60e91668a",
+     "5a99b336fd3cfd82f10fb08f7045012415f0d9a06bb92dcf59c6f0dbe62d433671aacb8a1"
+     "c52ce7bbf6aea372bf51e2ba79406",
+     "f1c522f026e4c5d43851da516a1b78768ab18171",
+     "fe93b01636f7bb0458041f213e98de65",
+     "17449e236ef5858f6d891412495ead4607bfae2a2d735182a2a0242f9d52fc5345ef912db"
+     "e16f3bb4576fe3bcafe336dee6085"},
+    {"90f2e71ccb1148979cb742efc8f921de95457d898c84ce28edeed701650d3a26",
+     "aba58ad60047ba553f6e4c98",
+     "3fc77a5fe9203d091c7916587c9763cf2e4d0d53ca20b078b851716f1dab4873fe342b7b3"
+     "01402f015d00263bf3f77c58a99d6",
+     "2abe465df6e5be47f05b92c9a93d76ae3611fac5",
+     "9cb3d04637048bc0bddef803ffbb56cf",
+     "1d21639640e11638a2769e3fab78778f84be3f4a8ce28dfd99cb2e75171e05ea8e94e30aa"
+     "78b54bb402b39d613616a8ed951dc"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {
+        "e36aca93414b13f5313e76a7244588ee116551d1f34c32859166f2eb0ac1a9b7",
+        "e9e701b1ccef6bddd03391d8",
+        "5b059ac6733b6de0e8cf5b88b7301c02c993426f71bb12abf692e9deeacfac1ff1644c"
+        "87d4df130028f515f0feda636309a24d",
+        "6a08fe6e55a08f283cec4c4b37676e770f402af6102f548ad473ec6236da764f7076ff"
+        "d41bbd9611b439362d899682b7b0f839fc5a68d9df54afd1e2b3c4e7d072454ee27111"
+        "d52193d28b9c4f925d2a8b451675af39191a2cba",
+        "43c7c9c93cc265fc8e192000e0417b5b",
+        nullptr  // FAIL
+    },
+    {"5f72046245d3f4a0877e50a86554bfd57d1c5e073d1ed3b5451f6d0fc2a8507a",
+     "ea6f5b391e44b751b26bce6f",
+     "0e6e0b2114c40769c15958d965a14dcf50b680e0185a4409d77d894ca15b1e698dd83b353"
+     "6b18c05d8cd0873d1edce8150ecb5",
+     "9b3a68c941d42744673fb60fea49075eae77322e7e70e34502c115b6495ebfc796d629080"
+     "7653c6b53cd84281bd0311656d0013f44619d2748177e99e8f8347c989a7b59f9d8dcf00f"
+     "31db0684a4a83e037e8777bae55f799b0d",
+     "fdaaff86ceb937502cd9012d03585800",
+     "b0a881b751cc1eb0c912a4cf9bd971983707dbd2411725664503455c55db25cdb19bc669c"
+     "2654a3a8011de6bf7eff3f9f07834"},
+    {"ab639bae205547607506522bd3cdca7861369e2b42ef175ff135f6ba435d5a8e",
+     "5fbb63eb44bd59fee458d8f6",
+     "9a34c62bed0972285503a32812877187a54dedbd55d2317fed89282bf1af4ba0b6bb9f9e1"
+     "6dd86da3b441deb7841262bc6bd63",
+     "1ef2b1768b805587935ffaf754a11bd2a305076d6374f1f5098b1284444b78f55408a786d"
+     "a37e1b7f1401c330d3585ef56f3e4d35eaaac92e1381d636477dc4f4beaf559735e902d6b"
+     "e58723257d4ac1ed9bd213de387f35f3c4",
+     "e0299e079bff46fd12e36d1c60e41434",
+     "e5a3ce804a8516cdd12122c091256b789076576040dbf3c55e8be3c016025896b8a72532b"
+     "fd51196cc82efca47aa0fd8e2e0dc"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {
+        "8b37c4b8cf634704920059866ad96c49e9da502c63fca4a3a7a4dcec74cb0610",
+        "cb59344d2b06c4ae57cd0ea4", "66ab935c93555e786b775637a3", "",
+        "d8733acbb564d8afaa99d7ca2e2f92a9", nullptr  // FAIL
+    },
+    {"a71dac1377a3bf5d7fb1b5e36bee70d2e01de2a84a1c1009ba7448f7f26131dc",
+     "c5b60dda3f333b1146e9da7c", "43af49ec1ae3738a20755034d6", "",
+     "6f80b6ef2d8830a55eb63680a8dff9e0", "5b87141335f2becac1a559e05f"},
+    {"dc1f64681014be221b00793bbcf5a5bc675b968eb7a3a3d5aa5978ef4fa45ecc",
+     "056ae9a1a69e38af603924fe", "33013a48d9ea0df2911d583271", "",
+     "5b8f9cc22303e979cd1524187e9f70fe", "2a7e05612191c8bce2f529dca9"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  decrypter->SetIV(nonce);
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success =
+      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
+                               &output_length, ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class Aes256GcmDecrypterTest : public QuicTest {};
+
+TEST_F(Aes256GcmDecrypterTest, Decrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // If not present then decryption is expected to fail.
+      bool has_pt = test_vectors[j].pt;
+
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+      std::string pt;
+      if (has_pt) {
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
+      }
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+      if (has_pt) {
+        EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      }
+      std::string ciphertext = ct + tag;
+
+      Aes256GcmDecrypter decrypter;
+      ASSERT_TRUE(decrypter.SetKey(key));
+
+      std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+          &decrypter, iv,
+          // This deliberately tests that the decrypter can
+          // handle an AAD that is set to nullptr, as opposed
+          // to a zero-length, non-nullptr pointer.
+          aad.length() ? aad : absl::string_view(), ciphertext));
+      if (!decrypted) {
+        EXPECT_FALSE(has_pt);
+        continue;
+      }
+      EXPECT_TRUE(has_pt);
+
+      ASSERT_EQ(pt.length(), decrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+    }
+  }
+}
+
+TEST_F(Aes256GcmDecrypterTest, GenerateHeaderProtectionMask) {
+  Aes256GcmDecrypter decrypter;
+  std::string key = absl::HexStringToBytes(
+      "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
+  std::string sample =
+      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
+  QuicDataReader sample_reader(sample.data(), sample.size());
+  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
+  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
+  std::string expected_mask =
+      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc b/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc
new file mode 100644
index 0000000..fce2207
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+Aes256GcmEncrypter::Aes256GcmEncrypter()
+    : AesBaseEncrypter(EVP_aead_aes_256_gcm,
+                       kKeySize,
+                       kAuthTagSize,
+                       kNonceSize,
+                       /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+Aes256GcmEncrypter::~Aes256GcmEncrypter() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_256_gcm_encrypter.h b/quiche/quic/core/crypto/aes_256_gcm_encrypter.h
new file mode 100644
index 0000000..9ba47f1
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_encrypter.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An Aes256GcmEncrypter is a QuicEncrypter that implements the
+// AEAD_AES_256_GCM algorithm specified in RFC 5116 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE Aes256GcmEncrypter : public AesBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  Aes256GcmEncrypter();
+  Aes256GcmEncrypter(const Aes256GcmEncrypter&) = delete;
+  Aes256GcmEncrypter& operator=(const Aes256GcmEncrypter&) = delete;
+  ~Aes256GcmEncrypter() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_256_GCM_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc
new file mode 100644
index 0000000..6389fdb
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_256_gcm_encrypter_test.cc
@@ -0,0 +1,259 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The AES GCM test vectors come from the file gcmEncryptExtIV256.rsp
+// downloaded from
+// https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#GCMVS
+// on 2017-09-27. The test vectors in that file look like this:
+//
+// [Keylen = 256]
+// [IVlen = 96]
+// [PTlen = 0]
+// [AADlen = 0]
+// [Taglen = 128]
+//
+// Count = 0
+// Key = b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4
+// IV = 516c33929df5a3284ff463d7
+// PT =
+// AAD =
+// CT =
+// Tag = bdc1ac884d332457a1d2664f168c76f0
+//
+// Count = 1
+// Key = 5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f
+// IV = 770ac1a5a3d476d5d96944a1
+// PT =
+// AAD =
+// CT =
+// Tag = 196d691e1047093ca4b3d2ef4baba216
+//
+// ...
+//
+// The gcmEncryptExtIV256.rsp file is huge (3.2 MB), so a few test vectors were
+// selected for this unit test.
+
+// Describes a group of test vectors that all have a given key length, IV
+// length, plaintext length, AAD length, and tag length.
+struct TestGroupInfo {
+  size_t key_len;
+  size_t iv_len;
+  size_t pt_len;
+  size_t aad_len;
+  size_t tag_len;
+};
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* iv;
+  const char* pt;
+  const char* aad;
+  const char* ct;
+  const char* tag;
+};
+
+const TestGroupInfo test_group_info[] = {
+    {256, 96, 0, 0, 128},     {256, 96, 0, 128, 128},   {256, 96, 128, 0, 128},
+    {256, 96, 408, 160, 128}, {256, 96, 408, 720, 128}, {256, 96, 104, 0, 128},
+};
+
+const TestVector test_group_0[] = {
+    {"b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4",
+     "516c33929df5a3284ff463d7", "", "", "",
+     "bdc1ac884d332457a1d2664f168c76f0"},
+    {"5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f",
+     "770ac1a5a3d476d5d96944a1", "", "", "",
+     "196d691e1047093ca4b3d2ef4baba216"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_1[] = {
+    {"78dc4e0aaf52d935c3c01eea57428f00ca1fd475f5da86a49c8dd73d68c8e223",
+     "d79cf22d504cc793c3fb6c8a", "", "b96baa8c1c75a671bfb2d08d06be5f36", "",
+     "3e5d486aa2e30b22e040b85723a06e76"},
+    {"4457ff33683cca6ca493878bdc00373893a9763412eef8cddb54f91318e0da88",
+     "699d1f29d7b8c55300bb1fd2", "", "6749daeea367d0e9809e2dc2f309e6e3", "",
+     "d60c74d2517fde4a74e0cd4709ed43a9"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_2[] = {
+    {"31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22",
+     "0d18e06c7c725ac9e362e1ce", "2db5168e932556f8089a0622981d017d", "",
+     "fa4362189661d163fcd6a56d8bf0405a", "d636ac1bbedd5cc3ee727dc2ab4a9489"},
+    {"460fc864972261c2560e1eb88761ff1c992b982497bd2ac36c04071cbb8e5d99",
+     "8a4a16b9e210eb68bcb6f58d", "99e4e926ffe927f691893fb79a96b067", "",
+     "133fc15751621b5f325c7ff71ce08324", "ec4e87e0cf74a13618d0b68636ba9fa7"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_3[] = {
+    {"24501ad384e473963d476edcfe08205237acfd49b5b8f33857f8114e863fec7f",
+     "9ff18563b978ec281b3f2794",
+     "27f348f9cdc0c5bd5e66b1ccb63ad920ff2219d14e8d631b3872265cf117ee86757accb15"
+     "8bd9abb3868fdc0d0b074b5f01b2c",
+     "adb5ec720ccf9898500028bf34afccbcaca126ef",
+     "eb7cb754c824e8d96f7c6d9b76c7d26fb874ffbf1d65c6f64a698d839b0b06145dae82057"
+     "ad55994cf59ad7f67c0fa5e85fab8",
+     "bc95c532fecc594c36d1550286a7a3f0"},
+    {"fb43f5ab4a1738a30c1e053d484a94254125d55dccee1ad67c368bc1a985d235",
+     "9fbb5f8252db0bca21f1c230",
+     "34b797bb82250e23c5e796db2c37e488b3b99d1b981cea5e5b0c61a0b39adb6bd6ef1f507"
+     "22e2e4f81115cfcf53f842e2a6c08",
+     "98f8ae1735c39f732e2cbee1156dabeb854ec7a2",
+     "871cd53d95a8b806bd4821e6c4456204d27fd704ba3d07ce25872dc604ea5c5ea13322186"
+     "b7489db4fa060c1fd4159692612c8",
+     "07b48e4a32fac47e115d7ac7445d8330"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_4[] = {
+    {"148579a3cbca86d5520d66c0ec71ca5f7e41ba78e56dc6eebd566fed547fe691",
+     "b08a5ea1927499c6ecbfd4e0",
+     "9d0b15fdf1bd595f91f8b3abc0f7dec927dfd4799935a1795d9ce00c9b879434420fe42c2"
+     "75a7cd7b39d638fb81ca52b49dc41",
+     "e4f963f015ffbb99ee3349bbaf7e8e8e6c2a71c230a48f9d59860a29091d2747e01a5ca57"
+     "2347e247d25f56ba7ae8e05cde2be3c97931292c02370208ecd097ef692687fecf2f419d3"
+     "200162a6480a57dad408a0dfeb492e2c5d",
+     "2097e372950a5e9383c675e89eea1c314f999159f5611344b298cda45e62843716f215f82"
+     "ee663919c64002a5c198d7878fd3f",
+     "adbecdb0d5c2224d804d2886ff9a5760"},
+    {"e49af19182faef0ebeeba9f2d3be044e77b1212358366e4ef59e008aebcd9788",
+     "e7f37d79a6a487a5a703edbb",
+     "461cd0caf7427a3d44408d825ed719237272ecd503b9094d1f62c97d63ed83a0b50bdc804"
+     "ffdd7991da7a5b6dcf48d4bcd2cbc",
+     "19a9a1cfc647346781bef51ed9070d05f99a0e0192a223c5cd2522dbdf97d9739dd39fb17"
+     "8ade3339e68774b058aa03e9a20a9a205bc05f32381df4d63396ef691fefd5a71b49a2ad8"
+     "2d5ea428778ca47ee1398792762413cff4",
+     "32ca3588e3e56eb4c8301b009d8b84b8a900b2b88ca3c21944205e9dd7311757b51394ae9"
+     "0d8bb3807b471677614f4198af909",
+     "3e403d035c71d88f1be1a256c89ba6ad"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector test_group_5[] = {
+    {"82c4f12eeec3b2d3d157b0f992d292b237478d2cecc1d5f161389b97f999057a",
+     "7b40b20f5f397177990ef2d1", "982a296ee1cd7086afad976945", "",
+     "ec8e05a0471d6b43a59ca5335f", "113ddeafc62373cac2f5951bb9165249"},
+    {"db4340af2f835a6c6d7ea0ca9d83ca81ba02c29b7410f221cb6071114e393240",
+     "40e438357dd80a85cac3349e", "8ddb3397bd42853193cb0f80c9", "",
+     "b694118c85c41abf69e229cb0f", "c07f1b8aafbd152f697eb67f2a85fe45"},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+const TestVector* const test_group_array[] = {
+    test_group_0, test_group_1, test_group_2,
+    test_group_3, test_group_4, test_group_5,
+};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class Aes256GcmEncrypterTest : public QuicTest {};
+
+TEST_F(Aes256GcmEncrypterTest, Encrypt) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_group_array); i++) {
+    SCOPED_TRACE(i);
+    const TestVector* test_vectors = test_group_array[i];
+    const TestGroupInfo& test_info = test_group_info[i];
+    for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
+      // Decode the test vector.
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
+
+      // The test vector's lengths should look sane. Note that the lengths
+      // in |test_info| are in bits.
+      EXPECT_EQ(test_info.key_len, key.length() * 8);
+      EXPECT_EQ(test_info.iv_len, iv.length() * 8);
+      EXPECT_EQ(test_info.pt_len, pt.length() * 8);
+      EXPECT_EQ(test_info.aad_len, aad.length() * 8);
+      EXPECT_EQ(test_info.pt_len, ct.length() * 8);
+      EXPECT_EQ(test_info.tag_len, tag.length() * 8);
+
+      Aes256GcmEncrypter encrypter;
+      ASSERT_TRUE(encrypter.SetKey(key));
+      std::unique_ptr<QuicData> encrypted(
+          EncryptWithNonce(&encrypter, iv,
+                           // This deliberately tests that the encrypter can
+                           // handle an AAD that is set to nullptr, as opposed
+                           // to a zero-length, non-nullptr pointer.
+                           aad.length() ? aad : absl::string_view(), pt));
+      ASSERT_TRUE(encrypted.get());
+
+      ASSERT_EQ(ct.length() + tag.length(), encrypted->length());
+      quiche::test::CompareCharArraysWithHexError(
+          "ciphertext", encrypted->data(), ct.length(), ct.data(), ct.length());
+      quiche::test::CompareCharArraysWithHexError(
+          "authentication tag", encrypted->data() + ct.length(), tag.length(),
+          tag.data(), tag.length());
+    }
+  }
+}
+
+TEST_F(Aes256GcmEncrypterTest, GetMaxPlaintextSize) {
+  Aes256GcmEncrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+}
+
+TEST_F(Aes256GcmEncrypterTest, GetCiphertextSize) {
+  Aes256GcmEncrypter encrypter;
+  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+}
+
+TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) {
+  Aes256GcmEncrypter encrypter;
+  std::string key = absl::HexStringToBytes(
+      "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
+  std::string sample =
+      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
+  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
+  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
+  std::string expected_mask =
+      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_base_decrypter.cc b/quiche/quic/core/crypto/aes_base_decrypter.cc
new file mode 100644
index 0000000..fb21ffe
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_decrypter.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_base_decrypter.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+bool AesBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10649_1) << "Invalid key size for header protection";
+    return false;
+  }
+  if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
+                          key.size() * 8, &pne_key_) != 0) {
+    QUIC_BUG(quic_bug_10649_2) << "Unexpected failure of AES_set_encrypt_key";
+    return false;
+  }
+  return true;
+}
+
+std::string AesBaseDecrypter::GenerateHeaderProtectionMask(
+    QuicDataReader* sample_reader) {
+  absl::string_view sample;
+  if (!sample_reader->ReadStringPiece(&sample, AES_BLOCK_SIZE)) {
+    return std::string();
+  }
+  std::string out(AES_BLOCK_SIZE, 0);
+  AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
+              reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+              &pne_key_);
+  return out;
+}
+
+QuicPacketCount AesBaseDecrypter::GetIntegrityLimit() const {
+  // For AEAD_AES_128_GCM ... endpoints that do not attempt to remove
+  // protection from packets larger than 2^11 bytes can attempt to remove
+  // protection from at most 2^57 packets.
+  // For AEAD_AES_256_GCM [the limit] is substantially larger than the limit for
+  // AEAD_AES_128_GCM. However, this document recommends that the same limit be
+  // applied to both functions as either limit is acceptably large.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-integrity-limit
+  static_assert(kMaxIncomingPacketSize <= 2048,
+                "This key limit requires limits on decryption payload sizes");
+  return 144115188075855872U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_base_decrypter.h b/quiche/quic/core/crypto/aes_base_decrypter.h
new file mode 100644
index 0000000..1be0f7e
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_decrypter.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/core/crypto/aead_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE AesBaseDecrypter : public AeadBaseDecrypter {
+ public:
+  using AeadBaseDecrypter::AeadBaseDecrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) override;
+  QuicPacketCount GetIntegrityLimit() const override;
+
+ private:
+  // The key used for packet number encryption.
+  AES_KEY pne_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/aes_base_encrypter.cc b/quiche/quic/core/crypto/aes_base_encrypter.cc
new file mode 100644
index 0000000..74298ed
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_encrypter.cc
@@ -0,0 +1,48 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/aes_base_encrypter.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+bool AesBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10726_1)
+        << "Invalid key size for header protection: " << key.size();
+    return false;
+  }
+  if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key.data()),
+                          key.size() * 8, &pne_key_) != 0) {
+    QUIC_BUG(quic_bug_10726_2) << "Unexpected failure of AES_set_encrypt_key";
+    return false;
+  }
+  return true;
+}
+
+std::string AesBaseEncrypter::GenerateHeaderProtectionMask(
+    absl::string_view sample) {
+  if (sample.size() != AES_BLOCK_SIZE) {
+    return std::string();
+  }
+  std::string out(AES_BLOCK_SIZE, 0);
+  AES_encrypt(reinterpret_cast<const uint8_t*>(sample.data()),
+              reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+              &pne_key_);
+  return out;
+}
+
+QuicPacketCount AesBaseEncrypter::GetConfidentialityLimit() const {
+  // For AEAD_AES_128_GCM and AEAD_AES_256_GCM ... endpoints that do not send
+  // packets larger than 2^11 bytes cannot protect more than 2^28 packets.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-confidentiality-limit
+  static_assert(kMaxOutgoingPacketSize <= 2048,
+                "This key limit requires limits on encryption payload sizes");
+  return 268435456U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/aes_base_encrypter.h b/quiche/quic/core/crypto/aes_base_encrypter.h
new file mode 100644
index 0000000..b929cdd
--- /dev/null
+++ b/quiche/quic/core/crypto/aes_base_encrypter.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/core/crypto/aead_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE AesBaseEncrypter : public AeadBaseEncrypter {
+ public:
+  using AeadBaseEncrypter::AeadBaseEncrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
+  QuicPacketCount GetConfidentialityLimit() const override;
+
+ private:
+  // The key used for packet number encryption.
+  AES_KEY pne_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_AES_BASE_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/boring_utils.h b/quiche/quic/core/crypto/boring_utils.h
new file mode 100644
index 0000000..4a45cf4
--- /dev/null
+++ b/quiche/quic/core/crypto/boring_utils.h
@@ -0,0 +1,34 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
+#define QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+inline QUIC_EXPORT_PRIVATE absl::string_view CbsToStringPiece(CBS cbs) {
+  return absl::string_view(reinterpret_cast<const char*>(CBS_data(&cbs)),
+                           CBS_len(&cbs));
+}
+
+inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) {
+  CBS result;
+  CBS_init(&result, reinterpret_cast<const uint8_t*>(piece.data()),
+           piece.size());
+  return result;
+}
+
+inline QUIC_EXPORT_PRIVATE bool AddStringToCbb(CBB* cbb,
+                                               absl::string_view piece) {
+  return 1 == CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(piece.data()),
+                            piece.size());
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_
diff --git a/quiche/quic/core/crypto/cert_compressor.cc b/quiche/quic/core/crypto/cert_compressor.cc
new file mode 100644
index 0000000..4765643
--- /dev/null
+++ b/quiche/quic/core/crypto/cert_compressor.cc
@@ -0,0 +1,599 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/cert_compressor.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "third_party/zlib/zlib.h"
+
+namespace quic {
+
+namespace {
+
+// kCommonCertSubstrings contains ~1500 bytes of common certificate substrings
+// in order to help zlib. This was generated via a fairly dumb algorithm from
+// the Alexa Top 5000 set - we could probably do better.
+static const unsigned char kCommonCertSubstrings[] = {
+    0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
+    0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+    0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30,
+    0x5f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01,
+    0x06, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07,
+    0x17, 0x01, 0x30, 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
+    0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x20, 0x53, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x34,
+    0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+    0x32, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72,
+    0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x30, 0x2d, 0x61, 0x69, 0x61, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x2f, 0x45, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+    0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x45, 0x2e, 0x63, 0x65,
+    0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+    0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
+    0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x30, 0x0d,
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
+    0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x7b, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+    0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd2,
+    0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x2e,
+    0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+    0x04, 0x14, 0xb4, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69,
+    0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x30, 0x0b, 0x06, 0x03,
+    0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
+    0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+    0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30,
+    0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74,
+    0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33,
+    0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74,
+    0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+    0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
+    0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53,
+    0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55,
+    0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37,
+    0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c,
+    0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+    0x30, 0x1d, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+    0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+    0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+    0x03, 0x02, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d,
+    0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86,
+    0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e,
+    0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x67, 0x64, 0x73, 0x31, 0x2d, 0x32, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08,
+    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74,
+    0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65,
+    0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
+    0x70, 0x73, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17,
+    0x0d, 0x31, 0x33, 0x30, 0x35, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a,
+    0x2f, 0x2f, 0x73, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
+    0x3d, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86,
+    0xf8, 0x45, 0x01, 0x07, 0x17, 0x06, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x53, 0x31, 0x17,
+    0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72,
+    0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, 0x65,
+    0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74,
+    0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, 0x39,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, 0x73,
+    0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x68,
+    0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76,
+    0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+    0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x31, 0x10, 0x30, 0x0e,
+    0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x31, 0x13, 0x30, 0x11,
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x47, 0x31, 0x13, 0x30, 0x11,
+    0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01,
+    0x03, 0x13, 0x02, 0x55, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
+    0x03, 0x14, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+    0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0f, 0x13, 0x14, 0x50,
+    0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
+    0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x12, 0x31, 0x21, 0x30,
+    0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, 0x61,
+    0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x56,
+    0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x14, 0x31, 0x31,
+    0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x53, 0x65, 0x65,
+    0x20, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63,
+    0x75, 0x72, 0x65, 0x2e, 0x67, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53,
+    0x69, 0x67, 0x6e, 0x31, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41,
+    0x2e, 0x63, 0x72, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x63, 0x72,
+    0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x64, 0x31, 0x1a,
+    0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a,
+    0x2f, 0x2f, 0x45, 0x56, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, 0x63, 0x72,
+    0x74, 0x2e, 0x67, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x69, 0x63, 0x65, 0x72,
+    0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x31, 0x6f, 0x63, 0x73, 0x70, 0x2e,
+    0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+    0x30, 0x39, 0x72, 0x61, 0x70, 0x69, 0x64, 0x73, 0x73, 0x6c, 0x2e, 0x63,
+    0x6f, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
+    0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+    0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, 0x30, 0x24, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+    0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
+    0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, 0x06,
+    0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68,
+    0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
+    0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
+    0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74,
+    0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72,
+    0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+    0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee,
+    0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x27,
+    0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x86, 0x30,
+    0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
+};
+
+// CertEntry represents a certificate in compressed form. Each entry is one of
+// the three types enumerated in |Type|.
+struct CertEntry {
+ public:
+  enum Type {
+    // Type 0 is reserved to mean "end of list" in the wire format.
+
+    // COMPRESSED means that the certificate is included in the trailing zlib
+    // data.
+    COMPRESSED = 1,
+    // CACHED means that the certificate is already known to the peer and will
+    // be replaced by its 64-bit hash (in |hash|).
+    CACHED = 2,
+  };
+
+  Type type;
+  uint64_t hash;
+  uint64_t set_hash;
+  uint32_t index;
+};
+
+// MatchCerts returns a vector of CertEntries describing how to most
+// efficiently represent |certs| to a peer who has cached the certificates
+// with the 64-bit, FNV-1a hashes in |client_cached_cert_hashes|.
+std::vector<CertEntry> MatchCerts(const std::vector<std::string>& certs,
+                                  absl::string_view client_cached_cert_hashes) {
+  std::vector<CertEntry> entries;
+  entries.reserve(certs.size());
+
+  const bool cached_valid =
+      client_cached_cert_hashes.size() % sizeof(uint64_t) == 0 &&
+      !client_cached_cert_hashes.empty();
+
+  for (auto i = certs.begin(); i != certs.end(); ++i) {
+    CertEntry entry;
+
+    if (cached_valid) {
+      bool cached = false;
+
+      uint64_t hash = QuicUtils::FNV1a_64_Hash(*i);
+      // This assumes that the machine is little-endian.
+      for (size_t j = 0; j < client_cached_cert_hashes.size();
+           j += sizeof(uint64_t)) {
+        uint64_t cached_hash;
+        memcpy(&cached_hash, client_cached_cert_hashes.data() + j,
+               sizeof(uint64_t));
+        if (hash != cached_hash) {
+          continue;
+        }
+
+        entry.type = CertEntry::CACHED;
+        entry.hash = hash;
+        entries.push_back(entry);
+        cached = true;
+        break;
+      }
+
+      if (cached) {
+        continue;
+      }
+    }
+
+    entry.type = CertEntry::COMPRESSED;
+    entries.push_back(entry);
+  }
+
+  return entries;
+}
+
+// CertEntriesSize returns the size, in bytes, of the serialised form of
+// |entries|.
+size_t CertEntriesSize(const std::vector<CertEntry>& entries) {
+  size_t entries_size = 0;
+
+  for (auto i = entries.begin(); i != entries.end(); ++i) {
+    entries_size++;
+    switch (i->type) {
+      case CertEntry::COMPRESSED:
+        break;
+      case CertEntry::CACHED:
+        entries_size += sizeof(uint64_t);
+        break;
+    }
+  }
+
+  entries_size++;  // for end marker
+
+  return entries_size;
+}
+
+// SerializeCertEntries serialises |entries| to |out|, which must have enough
+// space to contain them.
+void SerializeCertEntries(uint8_t* out, const std::vector<CertEntry>& entries) {
+  for (auto i = entries.begin(); i != entries.end(); ++i) {
+    *out++ = static_cast<uint8_t>(i->type);
+    switch (i->type) {
+      case CertEntry::COMPRESSED:
+        break;
+      case CertEntry::CACHED:
+        memcpy(out, &i->hash, sizeof(i->hash));
+        out += sizeof(uint64_t);
+        break;
+    }
+  }
+
+  *out++ = 0;  // end marker
+}
+
+// ZlibDictForEntries returns a string that contains the zlib pre-shared
+// dictionary to use in order to decompress a zlib block following |entries|.
+// |certs| is one-to-one with |entries| and contains the certificates for those
+// entries that are CACHED.
+std::string ZlibDictForEntries(const std::vector<CertEntry>& entries,
+                               const std::vector<std::string>& certs) {
+  std::string zlib_dict;
+
+  // The dictionary starts with the cached certs in reverse order.
+  size_t zlib_dict_size = 0;
+  for (size_t i = certs.size() - 1; i < certs.size(); i--) {
+    if (entries[i].type != CertEntry::COMPRESSED) {
+      zlib_dict_size += certs[i].size();
+    }
+  }
+
+  // At the end of the dictionary is a block of common certificate substrings.
+  zlib_dict_size += sizeof(kCommonCertSubstrings);
+
+  zlib_dict.reserve(zlib_dict_size);
+
+  for (size_t i = certs.size() - 1; i < certs.size(); i--) {
+    if (entries[i].type != CertEntry::COMPRESSED) {
+      zlib_dict += certs[i];
+    }
+  }
+
+  zlib_dict += std::string(reinterpret_cast<const char*>(kCommonCertSubstrings),
+                           sizeof(kCommonCertSubstrings));
+
+  QUICHE_DCHECK_EQ(zlib_dict.size(), zlib_dict_size);
+
+  return zlib_dict;
+}
+
+// HashCerts returns the FNV-1a hashes of |certs|.
+std::vector<uint64_t> HashCerts(const std::vector<std::string>& certs) {
+  std::vector<uint64_t> ret;
+  ret.reserve(certs.size());
+
+  for (auto i = certs.begin(); i != certs.end(); ++i) {
+    ret.push_back(QuicUtils::FNV1a_64_Hash(*i));
+  }
+
+  return ret;
+}
+
+// ParseEntries parses the serialised form of a vector of CertEntries from
+// |in_out| and writes them to |out_entries|. CACHED entries are resolved using
+// |cached_certs| and written to |out_certs|. |in_out| is updated to contain
+// the trailing data.
+bool ParseEntries(absl::string_view* in_out,
+                  const std::vector<std::string>& cached_certs,
+                  std::vector<CertEntry>* out_entries,
+                  std::vector<std::string>* out_certs) {
+  absl::string_view in = *in_out;
+  std::vector<uint64_t> cached_hashes;
+
+  out_entries->clear();
+  out_certs->clear();
+
+  for (;;) {
+    if (in.empty()) {
+      return false;
+    }
+    CertEntry entry;
+    const uint8_t type_byte = in[0];
+    in.remove_prefix(1);
+
+    if (type_byte == 0) {
+      break;
+    }
+
+    entry.type = static_cast<CertEntry::Type>(type_byte);
+
+    switch (entry.type) {
+      case CertEntry::COMPRESSED:
+        out_certs->push_back(std::string());
+        break;
+      case CertEntry::CACHED: {
+        if (in.size() < sizeof(uint64_t)) {
+          return false;
+        }
+        memcpy(&entry.hash, in.data(), sizeof(uint64_t));
+        in.remove_prefix(sizeof(uint64_t));
+
+        if (cached_hashes.size() != cached_certs.size()) {
+          cached_hashes = HashCerts(cached_certs);
+        }
+        bool found = false;
+        for (size_t i = 0; i < cached_hashes.size(); i++) {
+          if (cached_hashes[i] == entry.hash) {
+            out_certs->push_back(cached_certs[i]);
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          return false;
+        }
+        break;
+      }
+
+      default:
+        return false;
+    }
+    out_entries->push_back(entry);
+  }
+
+  *in_out = in;
+  return true;
+}
+
+// ScopedZLib deals with the automatic destruction of a zlib context.
+class ScopedZLib {
+ public:
+  enum Type {
+    INFLATE,
+    DEFLATE,
+  };
+
+  explicit ScopedZLib(Type type) : z_(nullptr), type_(type) {}
+
+  void reset(z_stream* z) {
+    Clear();
+    z_ = z;
+  }
+
+  ~ScopedZLib() { Clear(); }
+
+ private:
+  void Clear() {
+    if (!z_) {
+      return;
+    }
+
+    if (type_ == DEFLATE) {
+      deflateEnd(z_);
+    } else {
+      inflateEnd(z_);
+    }
+    z_ = nullptr;
+  }
+
+  z_stream* z_;
+  const Type type_;
+};
+
+}  // anonymous namespace
+
+// static
+std::string CertCompressor::CompressChain(
+    const std::vector<std::string>& certs,
+    absl::string_view client_cached_cert_hashes) {
+  const std::vector<CertEntry> entries =
+      MatchCerts(certs, client_cached_cert_hashes);
+  QUICHE_DCHECK_EQ(entries.size(), certs.size());
+
+  size_t uncompressed_size = 0;
+  for (size_t i = 0; i < entries.size(); i++) {
+    if (entries[i].type == CertEntry::COMPRESSED) {
+      uncompressed_size += 4 /* uint32_t length */ + certs[i].size();
+    }
+  }
+
+  size_t compressed_size = 0;
+  z_stream z;
+  ScopedZLib scoped_z(ScopedZLib::DEFLATE);
+
+  if (uncompressed_size > 0) {
+    memset(&z, 0, sizeof(z));
+    int rv = deflateInit(&z, Z_DEFAULT_COMPRESSION);
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    if (rv != Z_OK) {
+      return "";
+    }
+    scoped_z.reset(&z);
+
+    std::string zlib_dict = ZlibDictForEntries(entries, certs);
+
+    rv = deflateSetDictionary(
+        &z, reinterpret_cast<const uint8_t*>(&zlib_dict[0]), zlib_dict.size());
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    if (rv != Z_OK) {
+      return "";
+    }
+
+    compressed_size = deflateBound(&z, uncompressed_size);
+  }
+
+  const size_t entries_size = CertEntriesSize(entries);
+
+  std::string result;
+  result.resize(entries_size + (uncompressed_size > 0 ? 4 : 0) +
+                compressed_size);
+
+  uint8_t* j = reinterpret_cast<uint8_t*>(&result[0]);
+  SerializeCertEntries(j, entries);
+  j += entries_size;
+
+  if (uncompressed_size == 0) {
+    return result;
+  }
+
+  uint32_t uncompressed_size_32 = uncompressed_size;
+  memcpy(j, &uncompressed_size_32, sizeof(uint32_t));
+  j += sizeof(uint32_t);
+
+  int rv;
+
+  z.next_out = j;
+  z.avail_out = compressed_size;
+
+  for (size_t i = 0; i < certs.size(); i++) {
+    if (entries[i].type != CertEntry::COMPRESSED) {
+      continue;
+    }
+
+    uint32_t length32 = certs[i].size();
+    z.next_in = reinterpret_cast<uint8_t*>(&length32);
+    z.avail_in = sizeof(length32);
+    rv = deflate(&z, Z_NO_FLUSH);
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    QUICHE_DCHECK_EQ(0u, z.avail_in);
+    if (rv != Z_OK || z.avail_in) {
+      return "";
+    }
+
+    z.next_in =
+        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(certs[i].data()));
+    z.avail_in = certs[i].size();
+    rv = deflate(&z, Z_NO_FLUSH);
+    QUICHE_DCHECK_EQ(Z_OK, rv);
+    QUICHE_DCHECK_EQ(0u, z.avail_in);
+    if (rv != Z_OK || z.avail_in) {
+      return "";
+    }
+  }
+
+  z.avail_in = 0;
+  rv = deflate(&z, Z_FINISH);
+  QUICHE_DCHECK_EQ(Z_STREAM_END, rv);
+  if (rv != Z_STREAM_END) {
+    return "";
+  }
+
+  result.resize(result.size() - z.avail_out);
+  return result;
+}
+
+// static
+bool CertCompressor::DecompressChain(
+    absl::string_view in,
+    const std::vector<std::string>& cached_certs,
+    std::vector<std::string>* out_certs) {
+  std::vector<CertEntry> entries;
+  if (!ParseEntries(&in, cached_certs, &entries, out_certs)) {
+    return false;
+  }
+  QUICHE_DCHECK_EQ(entries.size(), out_certs->size());
+
+  std::unique_ptr<uint8_t[]> uncompressed_data;
+  absl::string_view uncompressed;
+
+  if (!in.empty()) {
+    if (in.size() < sizeof(uint32_t)) {
+      return false;
+    }
+
+    uint32_t uncompressed_size;
+    memcpy(&uncompressed_size, in.data(), sizeof(uncompressed_size));
+    in.remove_prefix(sizeof(uint32_t));
+
+    if (uncompressed_size > 128 * 1024) {
+      return false;
+    }
+
+    uncompressed_data = std::make_unique<uint8_t[]>(uncompressed_size);
+    z_stream z;
+    ScopedZLib scoped_z(ScopedZLib::INFLATE);
+
+    memset(&z, 0, sizeof(z));
+    z.next_out = uncompressed_data.get();
+    z.avail_out = uncompressed_size;
+    z.next_in =
+        const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(in.data()));
+    z.avail_in = in.size();
+
+    if (Z_OK != inflateInit(&z)) {
+      return false;
+    }
+    scoped_z.reset(&z);
+
+    int rv = inflate(&z, Z_FINISH);
+    if (rv == Z_NEED_DICT) {
+      std::string zlib_dict = ZlibDictForEntries(entries, *out_certs);
+      const uint8_t* dict = reinterpret_cast<const uint8_t*>(zlib_dict.data());
+      if (Z_OK != inflateSetDictionary(&z, dict, zlib_dict.size())) {
+        return false;
+      }
+      rv = inflate(&z, Z_FINISH);
+    }
+
+    if (Z_STREAM_END != rv || z.avail_out > 0 || z.avail_in > 0) {
+      return false;
+    }
+
+    uncompressed = absl::string_view(
+        reinterpret_cast<char*>(uncompressed_data.get()), uncompressed_size);
+  }
+
+  for (size_t i = 0; i < entries.size(); i++) {
+    switch (entries[i].type) {
+      case CertEntry::COMPRESSED:
+        if (uncompressed.size() < sizeof(uint32_t)) {
+          return false;
+        }
+        uint32_t cert_len;
+        memcpy(&cert_len, uncompressed.data(), sizeof(cert_len));
+        uncompressed.remove_prefix(sizeof(uint32_t));
+        if (uncompressed.size() < cert_len) {
+          return false;
+        }
+        (*out_certs)[i] = std::string(uncompressed.substr(0, cert_len));
+        uncompressed.remove_prefix(cert_len);
+        break;
+      case CertEntry::CACHED:
+        break;
+    }
+  }
+
+  if (!uncompressed.empty()) {
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/cert_compressor.h b/quiche/quic/core/crypto/cert_compressor.h
new file mode 100644
index 0000000..9509ccd
--- /dev/null
+++ b/quiche/quic/core/crypto/cert_compressor.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// CertCompressor provides functions for compressing and decompressing
+// certificate chains using two techniquies:
+//   1) The peer may provide a list of a 64-bit, FNV-1a hashes of certificates
+//      that they already have. In the event that one of them is to be
+//      compressed, it can be replaced with just the hash.
+//   2) Otherwise the certificates are compressed with zlib using a pre-shared
+//      dictionary that consists of the certificates handled with the above
+//      methods and a small chunk of common substrings.
+class QUIC_EXPORT_PRIVATE CertCompressor {
+ public:
+  CertCompressor() = delete;
+
+  // CompressChain compresses the certificates in |certs| and returns a
+  // compressed representation. client_cached_cert_hashes| contains
+  // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
+  static std::string CompressChain(const std::vector<std::string>& certs,
+                                   absl::string_view client_cached_cert_hashes);
+
+  // DecompressChain decompresses the result of |CompressChain|, given in |in|,
+  // into a series of certificates that are written to |out_certs|.
+  // |cached_certs| contains certificates that the peer may have omitted.
+  static bool DecompressChain(absl::string_view in,
+                              const std::vector<std::string>& cached_certs,
+                              std::vector<std::string>* out_certs);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CERT_COMPRESSOR_H_
diff --git a/quiche/quic/core/crypto/cert_compressor_test.cc b/quiche/quic/core/crypto/cert_compressor_test.cc
new file mode 100644
index 0000000..d98f4c7
--- /dev/null
+++ b/quiche/quic/core/crypto/cert_compressor_test.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/cert_compressor.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class CertCompressorTest : public QuicTest {};
+
+TEST_F(CertCompressorTest, EmptyChain) {
+  std::vector<std::string> chain;
+  const std::string compressed =
+      CertCompressor::CompressChain(chain, absl::string_view());
+  EXPECT_EQ("00", absl::BytesToHexString(compressed));
+
+  std::vector<std::string> chain2, cached_certs;
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+}
+
+TEST_F(CertCompressorTest, Compressed) {
+  std::vector<std::string> chain;
+  chain.push_back("testcert");
+  const std::string compressed =
+      CertCompressor::CompressChain(chain, absl::string_view());
+  ASSERT_GE(compressed.size(), 2u);
+  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
+
+  std::vector<std::string> chain2, cached_certs;
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+  EXPECT_EQ(chain[0], chain2[0]);
+}
+
+TEST_F(CertCompressorTest, Common) {
+  std::vector<std::string> chain;
+  chain.push_back("testcert");
+  static const uint64_t set_hash = 42;
+  const std::string compressed = CertCompressor::CompressChain(
+      chain, absl::string_view(reinterpret_cast<const char*>(&set_hash),
+                               sizeof(set_hash)));
+  ASSERT_GE(compressed.size(), 2u);
+  // 01 is the prefix for a zlib "compressed" cert not common or cached.
+  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
+
+  std::vector<std::string> chain2, cached_certs;
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+  EXPECT_EQ(chain[0], chain2[0]);
+}
+
+TEST_F(CertCompressorTest, Cached) {
+  std::vector<std::string> chain;
+  chain.push_back("testcert");
+  uint64_t hash = QuicUtils::FNV1a_64_Hash(chain[0]);
+  absl::string_view hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
+  const std::string compressed =
+      CertCompressor::CompressChain(chain, hash_bytes);
+
+  EXPECT_EQ("02" /* cached */ + absl::BytesToHexString(hash_bytes) +
+                "00" /* end of list */,
+            absl::BytesToHexString(compressed));
+
+  std::vector<std::string> cached_certs, chain2;
+  cached_certs.push_back(chain[0]);
+  ASSERT_TRUE(
+      CertCompressor::DecompressChain(compressed, cached_certs, &chain2));
+  EXPECT_EQ(chain.size(), chain2.size());
+  EXPECT_EQ(chain[0], chain2[0]);
+}
+
+TEST_F(CertCompressorTest, BadInputs) {
+  std::vector<std::string> cached_certs, chain;
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("04") /* bad entry type */, cached_certs, &chain));
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("01") /* no terminator */, cached_certs, &chain));
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("0200") /* hash truncated */, cached_certs,
+      &chain));
+
+  EXPECT_FALSE(CertCompressor::DecompressChain(
+      absl::BytesToHexString("0300") /* hash and index truncated */,
+      cached_certs, &chain));
+
+  /* without a CommonCertSets */
+  EXPECT_FALSE(
+      CertCompressor::DecompressChain(absl::BytesToHexString("03"
+                                                             "0000000000000000"
+                                                             "00000000"),
+                                      cached_certs, &chain));
+
+  /* incorrect hash and index */
+  EXPECT_FALSE(
+      CertCompressor::DecompressChain(absl::BytesToHexString("03"
+                                                             "a200000000000000"
+                                                             "00000000"),
+                                      cached_certs, &chain));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_util.cc b/quiche/quic/core/crypto/certificate_util.cc
new file mode 100644
index 0000000..e56d9cf
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_util.cc
@@ -0,0 +1,280 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/certificate_util.h"
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "third_party/boringssl/src/include/openssl/pkcs7.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/stack.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+bool AddEcdsa256SignatureAlgorithm(CBB* cbb) {
+  // See RFC 5758. This is the encoding of OID 1.2.840.10045.4.3.2.
+  static const uint8_t kEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
+                                             0x3d, 0x04, 0x03, 0x02};
+
+  // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
+  CBB sequence, oid;
+  if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
+    return false;
+  }
+
+  if (!CBB_add_bytes(&oid, kEcdsaWithSha256, sizeof(kEcdsaWithSha256))) {
+    return false;
+  }
+
+  // RFC 5758, section 3.2: ecdsa-with-sha256 MUST omit the parameters field.
+  return CBB_flush(cbb);
+}
+
+// Adds an X.509 Name with the specified distinguished name to |cbb|.
+bool AddName(CBB* cbb, absl::string_view name) {
+  // See RFC 4519.
+  static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
+  static const uint8_t kCountryName[] = {0x55, 0x04, 0x06};
+  static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a};
+  static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b};
+
+  std::vector<std::string> attributes =
+      absl::StrSplit(name, ',', absl::SkipEmpty());
+
+  if (attributes.empty()) {
+    QUIC_LOG(ERROR) << "Missing DN or wrong format";
+    return false;
+  }
+
+  // See RFC 5280, section 4.1.2.4.
+  CBB rdns;
+  if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
+    return false;
+  }
+
+  for (const std::string& attribute : attributes) {
+    std::vector<std::string> parts =
+        absl::StrSplit(absl::StripAsciiWhitespace(attribute), '=');
+    if (parts.size() != 2) {
+      QUIC_LOG(ERROR) << "Wrong DN format at " + attribute;
+      return false;
+    }
+
+    const std::string& type_string = parts[0];
+    const std::string& value_string = parts[1];
+    absl::Span<const uint8_t> type_bytes;
+    if (type_string == "CN") {
+      type_bytes = kCommonName;
+    } else if (type_string == "C") {
+      type_bytes = kCountryName;
+    } else if (type_string == "O") {
+      type_bytes = kOrganizationName;
+    } else if (type_string == "OU") {
+      type_bytes = kOrganizationalUnitName;
+    } else {
+      QUIC_LOG(ERROR) << "Unrecognized type " + type_string;
+      return false;
+    }
+
+    CBB rdn, attr, type, value;
+    if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
+        !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
+        !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
+        !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) ||
+        !CBB_add_asn1(&attr, &value,
+                      type_string == "C" ? CBS_ASN1_PRINTABLESTRING
+                                         : CBS_ASN1_UTF8STRING) ||
+        !AddStringToCbb(&value, value_string) || !CBB_flush(&rdns)) {
+      return false;
+    }
+  }
+  if (!CBB_flush(cbb)) {
+    return false;
+  }
+  return true;
+}
+
+bool CBBAddTime(CBB* cbb, const CertificateTimestamp& timestamp) {
+  CBB child;
+  std::string formatted_time;
+
+  // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as
+  // UTCTime rather than GeneralizedTime.
+  const bool is_utc_time = (1950 <= timestamp.year && timestamp.year < 2050);
+  if (is_utc_time) {
+    uint16_t year = timestamp.year - 1900;
+    if (year >= 100) {
+      year -= 100;
+    }
+    formatted_time = absl::StrFormat("%02d", year);
+    if (!CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME)) {
+      return false;
+    }
+  } else {
+    formatted_time = absl::StrFormat("%04d", timestamp.year);
+    if (!CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME)) {
+      return false;
+    }
+  }
+
+  absl::StrAppendFormat(&formatted_time, "%02d%02d%02d%02d%02dZ",
+                        timestamp.month, timestamp.day, timestamp.hour,
+                        timestamp.minute, timestamp.second);
+
+  static const size_t kGeneralizedTimeLength = 15;
+  static const size_t kUTCTimeLength = 13;
+  QUICHE_DCHECK_EQ(formatted_time.size(),
+                   is_utc_time ? kUTCTimeLength : kGeneralizedTimeLength);
+
+  return AddStringToCbb(&child, formatted_time) && CBB_flush(cbb);
+}
+
+bool CBBAddExtension(CBB* extensions, absl::Span<const uint8_t> oid,
+                     bool critical, absl::Span<const uint8_t> contents) {
+  CBB extension, cbb_oid, cbb_contents;
+  if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&extension, &cbb_oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&cbb_oid, oid.data(), oid.size()) ||
+      (critical && !CBB_add_asn1_bool(&extension, 1)) ||
+      !CBB_add_asn1(&extension, &cbb_contents, CBS_ASN1_OCTETSTRING) ||
+      !CBB_add_bytes(&cbb_contents, contents.data(), contents.size()) ||
+      !CBB_flush(extensions)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool IsEcdsa256Key(const EVP_PKEY& evp_key) {
+  if (EVP_PKEY_id(&evp_key) != EVP_PKEY_EC) {
+    return false;
+  }
+  const EC_KEY* key = EVP_PKEY_get0_EC_KEY(&evp_key);
+  if (key == nullptr) {
+    return false;
+  }
+  const EC_GROUP* group = EC_KEY_get0_group(key);
+  if (group == nullptr) {
+    return false;
+  }
+  return EC_GROUP_get_curve_name(group) == NID_X9_62_prime256v1;
+}
+
+}  // namespace
+
+bssl::UniquePtr<EVP_PKEY> MakeKeyPairForSelfSignedCertificate() {
+  bssl::UniquePtr<EVP_PKEY_CTX> context(
+      EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr));
+  if (!context) {
+    return nullptr;
+  }
+  if (EVP_PKEY_keygen_init(context.get()) != 1) {
+    return nullptr;
+  }
+  if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context.get(),
+                                             NID_X9_62_prime256v1) != 1) {
+    return nullptr;
+  }
+  EVP_PKEY* raw_key = nullptr;
+  if (EVP_PKEY_keygen(context.get(), &raw_key) != 1) {
+    return nullptr;
+  }
+  return bssl::UniquePtr<EVP_PKEY>(raw_key);
+}
+
+std::string CreateSelfSignedCertificate(EVP_PKEY& key,
+                                        const CertificateOptions& options) {
+  std::string error;
+  if (!IsEcdsa256Key(key)) {
+    QUIC_LOG(ERROR) << "CreateSelfSignedCert only accepts ECDSA P-256 keys";
+    return error;
+  }
+
+  // See RFC 5280, section 4.1. First, construct the TBSCertificate.
+  bssl::ScopedCBB cbb;
+  CBB tbs_cert, version, validity;
+  uint8_t* tbs_cert_bytes;
+  size_t tbs_cert_len;
+
+  if (!CBB_init(cbb.get(), 64) ||
+      !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&tbs_cert, &version,
+                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
+      !CBB_add_asn1_uint64(&version, 2) ||  // X.509 version 3
+      !CBB_add_asn1_uint64(&tbs_cert, options.serial_number) ||
+      !AddEcdsa256SignatureAlgorithm(&tbs_cert) ||  // signature algorithm
+      !AddName(&tbs_cert, options.subject) ||       // issuer
+      !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
+      !CBBAddTime(&validity, options.validity_start) ||
+      !CBBAddTime(&validity, options.validity_end) ||
+      !AddName(&tbs_cert, options.subject) ||      // subject
+      !EVP_marshal_public_key(&tbs_cert, &key)) {  // subjectPublicKeyInfo
+    return error;
+  }
+
+  CBB outer_extensions, extensions;
+  if (!CBB_add_asn1(&tbs_cert, &outer_extensions,
+                    3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
+      !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
+    return error;
+  }
+
+  // Key Usage
+  constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f};
+  constexpr uint8_t kKeyUsageContent[] = {
+      0x3,   // BIT STRING
+      0x2,   // Length
+      0x0,   // Unused bits
+      0x80,  // bit(0): digitalSignature
+  };
+  CBBAddExtension(&extensions, kKeyUsageOid, true, kKeyUsageContent);
+
+  // TODO(wub): Add more extensions here if needed.
+
+  if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
+    return error;
+  }
+
+  bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
+
+  // Sign the TBSCertificate and write the entire certificate.
+  CBB cert, signature;
+  bssl::ScopedEVP_MD_CTX ctx;
+  uint8_t* sig_out;
+  size_t sig_len;
+  uint8_t* cert_bytes;
+  size_t cert_len;
+  if (!CBB_init(cbb.get(), tbs_cert_len) ||
+      !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
+      !AddEcdsa256SignatureAlgorithm(&cert) ||
+      !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
+      !CBB_add_u8(&signature, 0 /* no unused bits */) ||
+      !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, &key) ||
+      // Compute the maximum signature length.
+      !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
+                      tbs_cert_len) ||
+      !CBB_reserve(&signature, &sig_out, sig_len) ||
+      // Actually sign the TBSCertificate.
+      !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
+                      tbs_cert_len) ||
+      !CBB_did_write(&signature, sig_len) ||
+      !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
+    return error;
+  }
+  bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
+  return std::string(reinterpret_cast<char*>(cert_bytes), cert_len);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_util.h b/quiche/quic/core/crypto/certificate_util.h
new file mode 100644
index 0000000..40c9f87
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_util.h
@@ -0,0 +1,46 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_NO_EXPORT CertificateTimestamp {
+  uint16_t year;
+  uint8_t month;
+  uint8_t day;
+  uint8_t hour;
+  uint8_t minute;
+  uint8_t second;
+};
+
+struct QUIC_NO_EXPORT CertificateOptions {
+  absl::string_view subject;
+  uint64_t serial_number;
+  CertificateTimestamp validity_start;  // a.k.a not_valid_before
+  CertificateTimestamp validity_end;    // a.k.a not_valid_after
+};
+
+// Creates a ECDSA P-256 key pair.
+QUIC_EXPORT_PRIVATE bssl::UniquePtr<EVP_PKEY>
+MakeKeyPairForSelfSignedCertificate();
+
+// Creates a self-signed, DER-encoded X.509 certificate.
+// |key| must be a ECDSA P-256 key.
+// This is mostly stolen from Chromium's net/cert/x509_util.h, with
+// modifications to make it work in QUICHE.
+QUIC_EXPORT_PRIVATE std::string CreateSelfSignedCertificate(
+    EVP_PKEY& key, const CertificateOptions& options);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_
diff --git a/quiche/quic/core/crypto/certificate_util_test.cc b/quiche/quic/core/crypto/certificate_util_test.cc
new file mode 100644
index 0000000..1c67a4a
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_util_test.cc
@@ -0,0 +1,49 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/certificate_util.h"
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_output.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(CertificateUtilTest, CreateSelfSignedCertificate) {
+  bssl::UniquePtr<EVP_PKEY> key = MakeKeyPairForSelfSignedCertificate();
+  ASSERT_NE(key, nullptr);
+
+  CertificatePrivateKey cert_key(std::move(key));
+
+  CertificateOptions options;
+  options.subject = "CN=subject";
+  options.serial_number = 0x12345678;
+  options.validity_start = {2020, 1, 1, 0, 0, 0};
+  options.validity_end = {2049, 12, 31, 0, 0, 0};
+  std::string der_cert =
+      CreateSelfSignedCertificate(*cert_key.private_key(), options);
+  ASSERT_FALSE(der_cert.empty());
+
+  QuicSaveTestOutput("CertificateUtilTest_CreateSelfSignedCert.crt", der_cert);
+
+  std::unique_ptr<CertificateView> cert_view =
+      CertificateView::ParseSingleCertificate(der_cert);
+  ASSERT_NE(cert_view, nullptr);
+  EXPECT_EQ(cert_view->public_key_type(), PublicKeyType::kP256);
+
+  absl::optional<std::string> subject = cert_view->GetHumanReadableSubject();
+  ASSERT_TRUE(subject.has_value());
+  EXPECT_EQ(*subject, options.subject);
+
+  EXPECT_TRUE(
+      cert_key.ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
+  EXPECT_TRUE(cert_key.MatchesPublicKey(*cert_view));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_view.cc b/quiche/quic/core/crypto/certificate_view.cc
new file mode 100644
index 0000000..aa2440b
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view.cc
@@ -0,0 +1,650 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/certificate_view.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/nid.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_time_utils.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+using ::quiche::QuicheTextUtils;
+
+// The literals below were encoded using `ascii2der | xxd -i`.  The comments
+// above the literals are the contents in the der2ascii syntax.
+
+// X.509 version 3 (version numbering starts with zero).
+// INTEGER { 2 }
+constexpr uint8_t kX509Version[] = {0x02, 0x01, 0x02};
+
+// 2.5.29.17
+constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11};
+
+PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) {
+  switch (EVP_PKEY_id(public_key)) {
+    case EVP_PKEY_RSA:
+      return PublicKeyType::kRsa;
+    case EVP_PKEY_EC: {
+      const EC_KEY* key = EVP_PKEY_get0_EC_KEY(public_key);
+      if (key == nullptr) {
+        return PublicKeyType::kUnknown;
+      }
+      const EC_GROUP* group = EC_KEY_get0_group(key);
+      if (group == nullptr) {
+        return PublicKeyType::kUnknown;
+      }
+      const int curve_nid = EC_GROUP_get_curve_name(group);
+      switch (curve_nid) {
+        case NID_X9_62_prime256v1:
+          return PublicKeyType::kP256;
+        case NID_secp384r1:
+          return PublicKeyType::kP384;
+        default:
+          return PublicKeyType::kUnknown;
+      }
+    }
+    case EVP_PKEY_ED25519:
+      return PublicKeyType::kEd25519;
+    default:
+      return PublicKeyType::kUnknown;
+  }
+}
+
+PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
+    uint16_t signature_algorithm) {
+  switch (signature_algorithm) {
+    case SSL_SIGN_RSA_PSS_RSAE_SHA256:
+      return PublicKeyType::kRsa;
+    case SSL_SIGN_ECDSA_SECP256R1_SHA256:
+      return PublicKeyType::kP256;
+    case SSL_SIGN_ECDSA_SECP384R1_SHA384:
+      return PublicKeyType::kP384;
+    case SSL_SIGN_ED25519:
+      return PublicKeyType::kEd25519;
+    default:
+      return PublicKeyType::kUnknown;
+  }
+}
+
+std::string AttributeNameToString(const CBS& oid_cbs) {
+  absl::string_view oid = CbsToStringPiece(oid_cbs);
+
+  // We only handle OIDs of form 2.5.4.N, which have binary encoding of
+  // "55 04 0N".
+  if (oid.length() == 3 && absl::StartsWith(oid, "\x55\x04")) {
+    // clang-format off
+    switch (oid[2]) {
+      case '\x3': return "CN";
+      case '\x7': return "L";
+      case '\x8': return "ST";
+      case '\xa': return "O";
+      case '\xb': return "OU";
+      case '\x6': return "C";
+    }
+    // clang-format on
+  }
+
+  bssl::UniquePtr<char> oid_representation(CBS_asn1_oid_to_text(&oid_cbs));
+  if (oid_representation == nullptr) {
+    return absl::StrCat("(", absl::BytesToHexString(oid), ")");
+  }
+  return std::string(oid_representation.get());
+}
+
+}  // namespace
+
+absl::optional<std::string> X509NameAttributeToString(CBS input) {
+  CBS name, value;
+  unsigned value_tag;
+  if (!CBS_get_asn1(&input, &name, CBS_ASN1_OBJECT) ||
+      !CBS_get_any_asn1(&input, &value, &value_tag) || CBS_len(&input) != 0) {
+    return absl::nullopt;
+  }
+  // Note that this does not process encoding of |input| in any way.  This works
+  // fine for the most cases.
+  return absl::StrCat(AttributeNameToString(name), "=",
+                      absl::CHexEscape(CbsToStringPiece(value)));
+}
+
+namespace {
+
+template <unsigned inner_tag,
+          char separator,
+          absl::optional<std::string> (*parser)(CBS)>
+absl::optional<std::string> ParseAndJoin(CBS input) {
+  std::vector<std::string> pieces;
+  while (CBS_len(&input) != 0) {
+    CBS attribute;
+    if (!CBS_get_asn1(&input, &attribute, inner_tag)) {
+      return absl::nullopt;
+    }
+    absl::optional<std::string> formatted = parser(attribute);
+    if (!formatted.has_value()) {
+      return absl::nullopt;
+    }
+    pieces.push_back(*formatted);
+  }
+
+  return absl::StrJoin(pieces, std::string({separator}));
+}
+
+absl::optional<std::string> RelativeDistinguishedNameToString(CBS input) {
+  return ParseAndJoin<CBS_ASN1_SEQUENCE, '+', X509NameAttributeToString>(input);
+}
+
+absl::optional<std::string> DistinguishedNameToString(CBS input) {
+  return ParseAndJoin<CBS_ASN1_SET, ',', RelativeDistinguishedNameToString>(
+      input);
+}
+
+}  // namespace
+
+std::string PublicKeyTypeToString(PublicKeyType type) {
+  switch (type) {
+    case PublicKeyType::kRsa:
+      return "RSA";
+    case PublicKeyType::kP256:
+      return "ECDSA P-256";
+    case PublicKeyType::kP384:
+      return "ECDSA P-384";
+    case PublicKeyType::kEd25519:
+      return "Ed25519";
+    case PublicKeyType::kUnknown:
+      return "unknown";
+  }
+  return "";
+}
+
+absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag,
+                                                absl::string_view payload) {
+  if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) {
+    QUIC_DLOG(WARNING) << "Invalid tag supplied for a DER timestamp";
+    return absl::nullopt;
+  }
+
+  const size_t year_length = tag == CBS_ASN1_GENERALIZEDTIME ? 4 : 2;
+  uint64_t year, month, day, hour, minute, second;
+  quiche::QuicheDataReader reader(payload);
+  if (!reader.ReadDecimal64(year_length, &year) ||
+      !reader.ReadDecimal64(2, &month) || !reader.ReadDecimal64(2, &day) ||
+      !reader.ReadDecimal64(2, &hour) || !reader.ReadDecimal64(2, &minute) ||
+      !reader.ReadDecimal64(2, &second) ||
+      reader.ReadRemainingPayload() != "Z") {
+    QUIC_DLOG(WARNING) << "Failed to parse the DER timestamp";
+    return absl::nullopt;
+  }
+
+  if (tag == CBS_ASN1_UTCTIME) {
+    QUICHE_DCHECK_LE(year, 100u);
+    year += (year >= 50) ? 1900 : 2000;
+  }
+
+  const absl::optional<int64_t> unix_time =
+      quiche::QuicheUtcDateTimeToUnixSeconds(year, month, day, hour, minute,
+                                             second);
+  if (!unix_time.has_value() || *unix_time < 0) {
+    return absl::nullopt;
+  }
+  return QuicWallTime::FromUNIXSeconds(*unix_time);
+}
+
+PemReadResult ReadNextPemMessage(std::istream* input) {
+  constexpr absl::string_view kPemBegin = "-----BEGIN ";
+  constexpr absl::string_view kPemEnd = "-----END ";
+  constexpr absl::string_view kPemDashes = "-----";
+
+  std::string line_buffer, encoded_message_contents, expected_end;
+  bool pending_message = false;
+  PemReadResult result;
+  while (std::getline(*input, line_buffer)) {
+    absl::string_view line(line_buffer);
+    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line);
+
+    // Handle BEGIN lines.
+    if (!pending_message && absl::StartsWith(line, kPemBegin) &&
+        absl::EndsWith(line, kPemDashes)) {
+      result.type = std::string(
+          line.substr(kPemBegin.size(),
+                      line.size() - kPemDashes.size() - kPemBegin.size()));
+      expected_end = absl::StrCat(kPemEnd, result.type, kPemDashes);
+      pending_message = true;
+      continue;
+    }
+
+    // Handle END lines.
+    if (pending_message && line == expected_end) {
+      absl::optional<std::string> data =
+          QuicheTextUtils::Base64Decode(encoded_message_contents);
+      if (data.has_value()) {
+        result.status = PemReadResult::kOk;
+        result.contents = data.value();
+      } else {
+        result.status = PemReadResult::kError;
+      }
+      return result;
+    }
+
+    if (pending_message) {
+      encoded_message_contents.append(std::string(line));
+    }
+  }
+  bool eof_reached = input->eof() && !pending_message;
+  return PemReadResult{
+      (eof_reached ? PemReadResult::kEof : PemReadResult::kError), "", ""};
+}
+
+std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
+    absl::string_view certificate) {
+  std::unique_ptr<CertificateView> result(new CertificateView());
+  CBS top = StringPieceToCbs(certificate);
+
+  CBS top_certificate, tbs_certificate, signature_algorithm, signature;
+  if (!CBS_get_asn1(&top, &top_certificate, CBS_ASN1_SEQUENCE) ||
+      CBS_len(&top) != 0) {
+    return nullptr;
+  }
+
+  // Certificate  ::=  SEQUENCE  {
+  if (
+      //   tbsCertificate       TBSCertificate,
+      !CBS_get_asn1(&top_certificate, &tbs_certificate, CBS_ASN1_SEQUENCE) ||
+
+      //   signatureAlgorithm   AlgorithmIdentifier,
+      !CBS_get_asn1(&top_certificate, &signature_algorithm,
+                    CBS_ASN1_SEQUENCE) ||
+
+      //   signature            BIT STRING  }
+      !CBS_get_asn1(&top_certificate, &signature, CBS_ASN1_BITSTRING) ||
+      CBS_len(&top_certificate) != 0) {
+    return nullptr;
+  }
+
+  int has_version, has_extensions;
+  CBS version, serial, signature_algorithm_inner, issuer, validity, subject,
+      spki, issuer_id, subject_id, extensions_outer;
+  // TBSCertificate  ::=  SEQUENCE  {
+  if (
+      //   version         [0]  Version DEFAULT v1,
+      !CBS_get_optional_asn1(
+          &tbs_certificate, &version, &has_version,
+          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
+
+      //   serialNumber         CertificateSerialNumber,
+      !CBS_get_asn1(&tbs_certificate, &serial, CBS_ASN1_INTEGER) ||
+
+      //   signature            AlgorithmIdentifier,
+      !CBS_get_asn1(&tbs_certificate, &signature_algorithm_inner,
+                    CBS_ASN1_SEQUENCE) ||
+
+      //   issuer               Name,
+      !CBS_get_asn1(&tbs_certificate, &issuer, CBS_ASN1_SEQUENCE) ||
+
+      //   validity             Validity,
+      !CBS_get_asn1(&tbs_certificate, &validity, CBS_ASN1_SEQUENCE) ||
+
+      //   subject              Name,
+      !CBS_get_asn1(&tbs_certificate, &subject, CBS_ASN1_SEQUENCE) ||
+
+      //   subjectPublicKeyInfo SubjectPublicKeyInfo,
+      !CBS_get_asn1_element(&tbs_certificate, &spki, CBS_ASN1_SEQUENCE) ||
+
+      //   issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
+      //                        -- If present, version MUST be v2 or v3
+      !CBS_get_optional_asn1(&tbs_certificate, &issuer_id, nullptr,
+                             CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
+
+      //   subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+      //                        -- If present, version MUST be v2 or v3
+      !CBS_get_optional_asn1(&tbs_certificate, &subject_id, nullptr,
+                             CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
+
+      //   extensions      [3]  Extensions OPTIONAL
+      //                        -- If present, version MUST be v3 --  }
+      !CBS_get_optional_asn1(
+          &tbs_certificate, &extensions_outer, &has_extensions,
+          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3) ||
+
+      CBS_len(&tbs_certificate) != 0) {
+    return nullptr;
+  }
+
+  result->subject_der_ = CbsToStringPiece(subject);
+
+  unsigned not_before_tag, not_after_tag;
+  CBS not_before, not_after;
+  if (!CBS_get_any_asn1(&validity, &not_before, &not_before_tag) ||
+      !CBS_get_any_asn1(&validity, &not_after, &not_after_tag) ||
+      CBS_len(&validity) != 0) {
+    QUIC_DLOG(WARNING) << "Failed to extract the validity dates";
+    return nullptr;
+  }
+  absl::optional<QuicWallTime> not_before_parsed =
+      ParseDerTime(not_before_tag, CbsToStringPiece(not_before));
+  absl::optional<QuicWallTime> not_after_parsed =
+      ParseDerTime(not_after_tag, CbsToStringPiece(not_after));
+  if (!not_before_parsed.has_value() || !not_after_parsed.has_value()) {
+    QUIC_DLOG(WARNING) << "Failed to parse validity dates";
+    return nullptr;
+  }
+  result->validity_start_ = *not_before_parsed;
+  result->validity_end_ = *not_after_parsed;
+
+  result->public_key_.reset(EVP_parse_public_key(&spki));
+  if (result->public_key_ == nullptr) {
+    QUIC_DLOG(WARNING) << "Failed to parse the public key";
+    return nullptr;
+  }
+  if (!result->ValidatePublicKeyParameters()) {
+    QUIC_DLOG(WARNING) << "Public key has invalid parameters";
+    return nullptr;
+  }
+
+  // Only support X.509v3.
+  if (!has_version ||
+      !CBS_mem_equal(&version, kX509Version, sizeof(kX509Version))) {
+    QUIC_DLOG(WARNING) << "Bad X.509 version";
+    return nullptr;
+  }
+
+  if (!has_extensions) {
+    return nullptr;
+  }
+
+  CBS extensions;
+  if (!CBS_get_asn1(&extensions_outer, &extensions, CBS_ASN1_SEQUENCE) ||
+      CBS_len(&extensions_outer) != 0) {
+    QUIC_DLOG(WARNING) << "Failed to extract the extension sequence";
+    return nullptr;
+  }
+  if (!result->ParseExtensions(extensions)) {
+    QUIC_DLOG(WARNING) << "Failed to parse extensions";
+    return nullptr;
+  }
+
+  return result;
+}
+
+bool CertificateView::ParseExtensions(CBS extensions) {
+  while (CBS_len(&extensions) != 0) {
+    CBS extension, oid, critical, payload;
+    if (
+        // Extension  ::=  SEQUENCE  {
+        !CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
+        //     extnID      OBJECT IDENTIFIER,
+        !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
+        //     critical    BOOLEAN DEFAULT FALSE,
+        !CBS_get_optional_asn1(&extension, &critical, nullptr,
+                               CBS_ASN1_BOOLEAN) ||
+        //     extnValue   OCTET STRING
+        //                 -- contains the DER encoding of an ASN.1 value
+        //                 -- corresponding to the extension type identified
+        //                 -- by extnID
+        !CBS_get_asn1(&extension, &payload, CBS_ASN1_OCTETSTRING) ||
+        CBS_len(&extension) != 0) {
+      QUIC_DLOG(WARNING) << "Bad extension entry";
+      return false;
+    }
+
+    if (CBS_mem_equal(&oid, kSubjectAltNameOid, sizeof(kSubjectAltNameOid))) {
+      CBS alt_names;
+      if (!CBS_get_asn1(&payload, &alt_names, CBS_ASN1_SEQUENCE) ||
+          CBS_len(&payload) != 0) {
+        QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
+        return false;
+      }
+      while (CBS_len(&alt_names) != 0) {
+        CBS alt_name_cbs;
+        unsigned int alt_name_tag;
+        if (!CBS_get_any_asn1(&alt_names, &alt_name_cbs, &alt_name_tag)) {
+          QUIC_DLOG(WARNING) << "Failed to parse subjectAltName";
+          return false;
+        }
+
+        absl::string_view alt_name = CbsToStringPiece(alt_name_cbs);
+        QuicIpAddress ip_address;
+        // GeneralName ::= CHOICE {
+        switch (alt_name_tag) {
+          // dNSName                   [2]  IA5String,
+          case CBS_ASN1_CONTEXT_SPECIFIC | 2:
+            subject_alt_name_domains_.push_back(alt_name);
+            break;
+
+          // iPAddress                 [7]  OCTET STRING,
+          case CBS_ASN1_CONTEXT_SPECIFIC | 7:
+            if (!ip_address.FromPackedString(alt_name.data(),
+                                             alt_name.size())) {
+              QUIC_DLOG(WARNING) << "Failed to parse subjectAltName IP address";
+              return false;
+            }
+            subject_alt_name_ips_.push_back(ip_address);
+            break;
+
+          default:
+            QUIC_DLOG(INFO) << "Unknown subjectAltName tag " << alt_name_tag;
+            continue;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+std::vector<std::string> CertificateView::LoadPemFromStream(
+    std::istream* input) {
+  std::vector<std::string> result;
+  for (;;) {
+    PemReadResult read_result = ReadNextPemMessage(input);
+    if (read_result.status == PemReadResult::kEof) {
+      return result;
+    }
+    if (read_result.status != PemReadResult::kOk) {
+      return std::vector<std::string>();
+    }
+    if (read_result.type != "CERTIFICATE") {
+      continue;
+    }
+    result.emplace_back(std::move(read_result.contents));
+  }
+}
+
+PublicKeyType CertificateView::public_key_type() const {
+  return PublicKeyTypeFromKey(public_key_.get());
+}
+
+bool CertificateView::ValidatePublicKeyParameters() {
+  // The profile here affects what certificates can be used when QUIC is used as
+  // a server library without any custom certificate provider logic.
+  // The goal is to allow at minimum any certificate that would be allowed on a
+  // regular Web session over TLS 1.3 while ensuring we do not expose any
+  // algorithms we don't want to support long-term.
+  PublicKeyType key_type = PublicKeyTypeFromKey(public_key_.get());
+  switch (key_type) {
+    case PublicKeyType::kRsa:
+      return EVP_PKEY_bits(public_key_.get()) >= 2048;
+    case PublicKeyType::kP256:
+    case PublicKeyType::kP384:
+    case PublicKeyType::kEd25519:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool CertificateView::VerifySignature(absl::string_view data,
+                                      absl::string_view signature,
+                                      uint16_t signature_algorithm) const {
+  if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) !=
+      PublicKeyTypeFromKey(public_key_.get())) {
+    QUIC_BUG(quic_bug_10640_1)
+        << "Mismatch between the requested signature algorithm and the "
+           "type of the public key.";
+    return false;
+  }
+
+  bssl::ScopedEVP_MD_CTX md_ctx;
+  EVP_PKEY_CTX* pctx;
+  if (!EVP_DigestVerifyInit(
+          md_ctx.get(), &pctx,
+          SSL_get_signature_algorithm_digest(signature_algorithm), nullptr,
+          public_key_.get())) {
+    return false;
+  }
+  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
+    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
+      return false;
+    }
+  }
+  return EVP_DigestVerify(
+      md_ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
+      signature.size(), reinterpret_cast<const uint8_t*>(data.data()),
+      data.size());
+}
+
+absl::optional<std::string> CertificateView::GetHumanReadableSubject() const {
+  CBS input = StringPieceToCbs(subject_der_);
+  return DistinguishedNameToString(input);
+}
+
+std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadFromDer(
+    absl::string_view private_key) {
+  std::unique_ptr<CertificatePrivateKey> result(new CertificatePrivateKey());
+  CBS private_key_cbs = StringPieceToCbs(private_key);
+  result->private_key_.reset(EVP_parse_private_key(&private_key_cbs));
+  if (result->private_key_ == nullptr || CBS_len(&private_key_cbs) != 0) {
+    return nullptr;
+  }
+  return result;
+}
+
+std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadPemFromStream(
+    std::istream* input) {
+skip:
+  PemReadResult result = ReadNextPemMessage(input);
+  if (result.status != PemReadResult::kOk) {
+    return nullptr;
+  }
+  // RFC 5958 OneAsymmetricKey message.
+  if (result.type == "PRIVATE KEY") {
+    return LoadFromDer(result.contents);
+  }
+  // Legacy OpenSSL format: PKCS#1 (RFC 8017) RSAPrivateKey message.
+  if (result.type == "RSA PRIVATE KEY") {
+    CBS private_key_cbs = StringPieceToCbs(result.contents);
+    bssl::UniquePtr<RSA> rsa(RSA_parse_private_key(&private_key_cbs));
+    if (rsa == nullptr || CBS_len(&private_key_cbs) != 0) {
+      return nullptr;
+    }
+
+    std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
+    key->private_key_.reset(EVP_PKEY_new());
+    EVP_PKEY_assign_RSA(key->private_key_.get(), rsa.release());
+    return key;
+  }
+  // EC keys are sometimes generated with "openssl ecparam -genkey". If the user
+  // forgets -noout, OpenSSL will output a redundant copy of the EC parameters.
+  // Skip those.
+  if (result.type == "EC PARAMETERS") {
+    goto skip;
+  }
+  // Legacy OpenSSL format: RFC 5915 ECPrivateKey message.
+  if (result.type == "EC PRIVATE KEY") {
+    CBS private_key_cbs = StringPieceToCbs(result.contents);
+    bssl::UniquePtr<EC_KEY> ec_key(
+        EC_KEY_parse_private_key(&private_key_cbs, /*group=*/nullptr));
+    if (ec_key == nullptr || CBS_len(&private_key_cbs) != 0) {
+      return nullptr;
+    }
+
+    std::unique_ptr<CertificatePrivateKey> key(new CertificatePrivateKey());
+    key->private_key_.reset(EVP_PKEY_new());
+    EVP_PKEY_assign_EC_KEY(key->private_key_.get(), ec_key.release());
+    return key;
+  }
+  // Unknown format.
+  return nullptr;
+}
+
+std::string CertificatePrivateKey::Sign(absl::string_view input,
+                                        uint16_t signature_algorithm) const {
+  if (!ValidForSignatureAlgorithm(signature_algorithm)) {
+    QUIC_BUG(quic_bug_10640_2)
+        << "Mismatch between the requested signature algorithm and the "
+           "type of the private key.";
+    return "";
+  }
+
+  bssl::ScopedEVP_MD_CTX md_ctx;
+  EVP_PKEY_CTX* pctx;
+  if (!EVP_DigestSignInit(
+          md_ctx.get(), &pctx,
+          SSL_get_signature_algorithm_digest(signature_algorithm),
+          /*e=*/nullptr, private_key_.get())) {
+    return "";
+  }
+  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
+    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
+      return "";
+    }
+  }
+
+  std::string output;
+  size_t output_size;
+  if (!EVP_DigestSign(md_ctx.get(), /*out_sig=*/nullptr, &output_size,
+                      reinterpret_cast<const uint8_t*>(input.data()),
+                      input.size())) {
+    return "";
+  }
+  output.resize(output_size);
+  if (!EVP_DigestSign(
+          md_ctx.get(), reinterpret_cast<uint8_t*>(&output[0]), &output_size,
+          reinterpret_cast<const uint8_t*>(input.data()), input.size())) {
+    return "";
+  }
+  output.resize(output_size);
+  return output;
+}
+
+bool CertificatePrivateKey::MatchesPublicKey(
+    const CertificateView& view) const {
+  return EVP_PKEY_cmp(view.public_key(), private_key_.get()) == 1;
+}
+
+bool CertificatePrivateKey::ValidForSignatureAlgorithm(
+    uint16_t signature_algorithm) const {
+  return PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) ==
+         PublicKeyTypeFromKey(private_key_.get());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/certificate_view.h b/quiche/quic/core/crypto/certificate_view.h
new file mode 100644
index 0000000..347cee9
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view.h
@@ -0,0 +1,151 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
+
+#include <istream>
+#include <memory>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE PemReadResult {
+  enum Status { kOk, kEof, kError };
+  Status status;
+  std::string contents;
+  // The type of the PEM message (e.g., if the message starts with
+  // "-----BEGIN CERTIFICATE-----", the |type| would be "CERTIFICATE").
+  std::string type;
+};
+
+// Reads |input| line-by-line and returns the next available PEM message.
+QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input);
+
+// Cryptograhpic algorithms recognized in X.509.
+enum class PublicKeyType {
+  kRsa,
+  kP256,
+  kP384,
+  kEd25519,
+  kUnknown,
+};
+QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type);
+
+// CertificateView represents a parsed version of a single X.509 certificate. As
+// the word "view" implies, it does not take ownership of the underlying strings
+// and consists primarily of pointers into the certificate that is passed into
+// the parser.
+class QUIC_EXPORT_PRIVATE CertificateView {
+ public:
+  // Parses a single DER-encoded X.509 certificate.  Returns nullptr on parse
+  // error.
+  static std::unique_ptr<CertificateView> ParseSingleCertificate(
+      absl::string_view certificate);
+
+  // Loads all PEM-encoded X.509 certificates found in the |input| stream
+  // without parsing them.  Returns an empty vector if any parsing error occurs.
+  static std::vector<std::string> LoadPemFromStream(std::istream* input);
+
+  QuicWallTime validity_start() const { return validity_start_; }
+  QuicWallTime validity_end() const { return validity_end_; }
+  const EVP_PKEY* public_key() const { return public_key_.get(); }
+
+  const std::vector<absl::string_view>& subject_alt_name_domains() const {
+    return subject_alt_name_domains_;
+  }
+  const std::vector<QuicIpAddress>& subject_alt_name_ips() const {
+    return subject_alt_name_ips_;
+  }
+
+  // Returns a human-readable representation of the Subject field.  The format
+  // is similar to RFC 2253, but does not match it exactly.
+  absl::optional<std::string> GetHumanReadableSubject() const;
+
+  // |signature_algorithm| is a TLS signature algorithm ID.
+  bool VerifySignature(absl::string_view data,
+                       absl::string_view signature,
+                       uint16_t signature_algorithm) const;
+
+  // Returns the type of the key used in the certificate's SPKI.
+  PublicKeyType public_key_type() const;
+
+ private:
+  CertificateView() = default;
+
+  QuicWallTime validity_start_ = QuicWallTime::Zero();
+  QuicWallTime validity_end_ = QuicWallTime::Zero();
+  absl::string_view subject_der_;
+
+  // Public key parsed from SPKI.
+  bssl::UniquePtr<EVP_PKEY> public_key_;
+
+  // SubjectAltName, https://tools.ietf.org/html/rfc5280#section-4.2.1.6
+  std::vector<absl::string_view> subject_alt_name_domains_;
+  std::vector<QuicIpAddress> subject_alt_name_ips_;
+
+  // Called from ParseSingleCertificate().
+  bool ParseExtensions(CBS extensions);
+  bool ValidatePublicKeyParameters();
+};
+
+// CertificatePrivateKey represents a private key that can be used with an X.509
+// certificate.
+class QUIC_EXPORT_PRIVATE CertificatePrivateKey {
+ public:
+  explicit CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY> private_key)
+      : private_key_(std::move(private_key)) {}
+
+  // Loads a DER-encoded PrivateKeyInfo structure (RFC 5958) as a private key.
+  static std::unique_ptr<CertificatePrivateKey> LoadFromDer(
+      absl::string_view private_key);
+
+  // Loads a private key from a PEM file formatted according to RFC 7468.  Also
+  // supports legacy OpenSSL RSA key format ("BEGIN RSA PRIVATE KEY").
+  static std::unique_ptr<CertificatePrivateKey> LoadPemFromStream(
+      std::istream* input);
+
+  // |signature_algorithm| is a TLS signature algorithm ID.
+  std::string Sign(absl::string_view input, uint16_t signature_algorithm) const;
+
+  // Verifies that the private key in question matches the public key of the
+  // certificate |view|.
+  bool MatchesPublicKey(const CertificateView& view) const;
+
+  // Verifies that the private key can be used with the specified TLS signature
+  // algorithm.
+  bool ValidForSignatureAlgorithm(uint16_t signature_algorithm) const;
+
+  EVP_PKEY* private_key() const { return private_key_.get(); }
+
+ private:
+  CertificatePrivateKey() = default;
+
+  bssl::UniquePtr<EVP_PKEY> private_key_;
+};
+
+// Parses a DER-encoded X.509 NameAttribute.  Exposed primarily for testing.
+QUIC_EXPORT_PRIVATE absl::optional<std::string> X509NameAttributeToString(
+    CBS input);
+
+// Parses a DER time based on the specified ASN.1 tag.  Exposed primarily for
+// testing.
+QUIC_EXPORT_PRIVATE absl::optional<quic::QuicWallTime> ParseDerTime(
+    unsigned tag,
+    absl::string_view payload);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
diff --git a/quiche/quic/core/crypto/certificate_view_der_fuzzer.cc b/quiche/quic/core/crypto/certificate_view_der_fuzzer.cc
new file mode 100644
index 0000000..81c91eb
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view_der_fuzzer.cc
@@ -0,0 +1,19 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "quiche/quic/core/crypto/certificate_view.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  std::string input(reinterpret_cast<const char*>(data), size);
+
+  std::unique_ptr<quic::CertificateView> view =
+      quic::CertificateView::ParseSingleCertificate(input);
+  if (view != nullptr) {
+    view->GetHumanReadableSubject();
+  }
+  quic::CertificatePrivateKey::LoadFromDer(input);
+  return 0;
+}
diff --git a/quiche/quic/core/crypto/certificate_view_pem_fuzzer.cc b/quiche/quic/core/crypto/certificate_view_pem_fuzzer.cc
new file mode 100644
index 0000000..e6d70e5
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view_pem_fuzzer.cc
@@ -0,0 +1,18 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <sstream>
+#include <string>
+
+#include "quiche/quic/core/crypto/certificate_view.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  std::string input(reinterpret_cast<const char*>(data), size);
+  std::stringstream stream(input);
+
+  quic::CertificateView::LoadPemFromStream(&stream);
+  stream.seekg(0);
+  quic::CertificatePrivateKey::LoadPemFromStream(&stream);
+  return 0;
+}
diff --git a/quiche/quic/core/crypto/certificate_view_test.cc b/quiche/quic/core/crypto/certificate_view_test.cc
new file mode 100644
index 0000000..009fd8d
--- /dev/null
+++ b/quiche/quic/core/crypto/certificate_view_test.cc
@@ -0,0 +1,214 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/certificate_view.h"
+
+#include <memory>
+#include <sstream>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/boring_utils.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+#include "quiche/common/platform/api/quiche_time_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::HasSubstr;
+using ::testing::Optional;
+
+TEST(CertificateViewTest, PemParser) {
+  std::stringstream stream(kTestCertificatePem);
+  PemReadResult result = ReadNextPemMessage(&stream);
+  EXPECT_EQ(result.status, PemReadResult::kOk);
+  EXPECT_EQ(result.type, "CERTIFICATE");
+  EXPECT_EQ(result.contents, kTestCertificate);
+
+  result = ReadNextPemMessage(&stream);
+  EXPECT_EQ(result.status, PemReadResult::kEof);
+}
+
+TEST(CertificateViewTest, Parse) {
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(kTestCertificate);
+  ASSERT_TRUE(view != nullptr);
+
+  EXPECT_THAT(view->subject_alt_name_domains(),
+              ElementsAre(absl::string_view("www.example.org"),
+                          absl::string_view("mail.example.org"),
+                          absl::string_view("mail.example.com")));
+  EXPECT_THAT(view->subject_alt_name_ips(),
+              ElementsAre(QuicIpAddress::Loopback4()));
+  EXPECT_EQ(EVP_PKEY_id(view->public_key()), EVP_PKEY_RSA);
+
+  const QuicWallTime validity_start = QuicWallTime::FromUNIXSeconds(
+      *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 1, 30, 18, 13, 59));
+  EXPECT_EQ(view->validity_start(), validity_start);
+  const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds(
+      *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59));
+  EXPECT_EQ(view->validity_end(), validity_end);
+  EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa);
+  EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA");
+
+  EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1",
+            view->GetHumanReadableSubject());
+}
+
+TEST(CertificateViewTest, ParseCertWithUnknownSanType) {
+  std::stringstream stream(kTestCertWithUnknownSanTypePem);
+  PemReadResult result = ReadNextPemMessage(&stream);
+  EXPECT_EQ(result.status, PemReadResult::kOk);
+  EXPECT_EQ(result.type, "CERTIFICATE");
+
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(result.contents);
+  EXPECT_TRUE(view != nullptr);
+}
+
+TEST(CertificateViewTest, PemSingleCertificate) {
+  std::stringstream pem_stream(kTestCertificatePem);
+  std::vector<std::string> chain =
+      CertificateView::LoadPemFromStream(&pem_stream);
+  EXPECT_THAT(chain, ElementsAre(kTestCertificate));
+}
+
+TEST(CertificateViewTest, PemMultipleCertificates) {
+  std::stringstream pem_stream(kTestCertificateChainPem);
+  std::vector<std::string> chain =
+      CertificateView::LoadPemFromStream(&pem_stream);
+  EXPECT_THAT(chain,
+              ElementsAre(kTestCertificate, HasSubstr("QUIC Server Root CA")));
+}
+
+TEST(CertificateViewTest, PemNoCertificates) {
+  std::stringstream pem_stream("one\ntwo\nthree\n");
+  std::vector<std::string> chain =
+      CertificateView::LoadPemFromStream(&pem_stream);
+  EXPECT_TRUE(chain.empty());
+}
+
+TEST(CertificateViewTest, SignAndVerify) {
+  std::unique_ptr<CertificatePrivateKey> key =
+      CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
+  ASSERT_TRUE(key != nullptr);
+
+  std::string data = "A really important message";
+  std::string signature = key->Sign(data, SSL_SIGN_RSA_PSS_RSAE_SHA256);
+  ASSERT_FALSE(signature.empty());
+
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(kTestCertificate);
+  ASSERT_TRUE(view != nullptr);
+  EXPECT_TRUE(key->MatchesPublicKey(*view));
+
+  EXPECT_TRUE(
+      view->VerifySignature(data, signature, SSL_SIGN_RSA_PSS_RSAE_SHA256));
+  EXPECT_FALSE(view->VerifySignature("An unimportant message", signature,
+                                     SSL_SIGN_RSA_PSS_RSAE_SHA256));
+  EXPECT_FALSE(view->VerifySignature(data, "Not a signature",
+                                     SSL_SIGN_RSA_PSS_RSAE_SHA256));
+}
+
+TEST(CertificateViewTest, PrivateKeyPem) {
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(kTestCertificate);
+  ASSERT_TRUE(view != nullptr);
+
+  std::stringstream pem_stream(kTestCertificatePrivateKeyPem);
+  std::unique_ptr<CertificatePrivateKey> pem_key =
+      CertificatePrivateKey::LoadPemFromStream(&pem_stream);
+  ASSERT_TRUE(pem_key != nullptr);
+  EXPECT_TRUE(pem_key->MatchesPublicKey(*view));
+
+  std::stringstream legacy_stream(kTestCertificatePrivateKeyLegacyPem);
+  std::unique_ptr<CertificatePrivateKey> legacy_key =
+      CertificatePrivateKey::LoadPemFromStream(&legacy_stream);
+  ASSERT_TRUE(legacy_key != nullptr);
+  EXPECT_TRUE(legacy_key->MatchesPublicKey(*view));
+}
+
+TEST(CertificateViewTest, PrivateKeyEcdsaPem) {
+  std::stringstream pem_stream(kTestEcPrivateKeyLegacyPem);
+  std::unique_ptr<CertificatePrivateKey> key =
+      CertificatePrivateKey::LoadPemFromStream(&pem_stream);
+  ASSERT_TRUE(key != nullptr);
+  EXPECT_TRUE(key->ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256));
+}
+
+TEST(CertificateViewTest, DerTime) {
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(24)));
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19710101000024Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(365 * 86400 + 24)));
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_UTCTIME, "700101000024Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(24)));
+  EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "200101000024Z").has_value());
+
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, ""), absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.001Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Q"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024-0500"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "700101000024ZZ"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.00Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "197O0101000024Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.0O1Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "-9700101000024Z"),
+            absl::nullopt);
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "1970-101000024Z"),
+            absl::nullopt);
+
+  EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "490101000024Z").has_value());
+  // This should parse as 1950, which predates UNIX epoch.
+  EXPECT_FALSE(ParseDerTime(CBS_ASN1_UTCTIME, "500101000024Z").has_value());
+
+  EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101230000Z"),
+              Optional(QuicWallTime::FromUNIXSeconds(23 * 3600)));
+  EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101240000Z"),
+            absl::nullopt);
+}
+
+TEST(CertificateViewTest, NameAttribute) {
+  // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.112411 }
+  // UTF8String { "Test" }
+  std::string unknown_oid =
+      absl::HexStringToBytes("060b2a864886f712040186ee1b0c0454657374");
+  EXPECT_EQ("1.2.840.113554.4.1.112411=Test",
+            X509NameAttributeToString(StringPieceToCbs(unknown_oid)));
+
+  // OBJECT_IDENTIFIER { 2.5.4.3 }
+  // UTF8String { "Bell: \x07" }
+  std::string non_printable =
+      absl::HexStringToBytes("06035504030c0742656c6c3a2007");
+  EXPECT_EQ(R"(CN=Bell: \x07)",
+            X509NameAttributeToString(StringPieceToCbs(non_printable)));
+
+  // OBJECT_IDENTIFIER { "\x55\x80" }
+  // UTF8String { "Test" }
+  std::string invalid_oid = absl::HexStringToBytes("060255800c0454657374");
+  EXPECT_EQ("(5580)=Test",
+            X509NameAttributeToString(StringPieceToCbs(invalid_oid)));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc
new file mode 100644
index 0000000..556998a
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
+    : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
+
+uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
+  return TLS1_CK_CHACHA20_POLY1305_SHA256;
+}
+
+QuicPacketCount ChaCha20Poly1305Decrypter::GetIntegrityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  static_assert(kMaxIncomingPacketSize < 16384,
+                "This key limit requires limits on decryption payload sizes");
+  return 68719476736U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_decrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.h
new file mode 100644
index 0000000..6eb6c87
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_decrypter.h
@@ -0,0 +1,41 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/chacha_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305Decrypter is a QuicDecrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
+// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
+// by calling QuicDecrypter::Create(kCC20).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
+// nonce is four bytes.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Decrypter
+    : public ChaChaBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 12,
+  };
+
+  ChaCha20Poly1305Decrypter();
+  ChaCha20Poly1305Decrypter(const ChaCha20Poly1305Decrypter&) = delete;
+  ChaCha20Poly1305Decrypter& operator=(const ChaCha20Poly1305Decrypter&) =
+      delete;
+  ~ChaCha20Poly1305Decrypter() override;
+
+  uint32_t cipher_id() const override;
+  QuicPacketCount GetIntegrityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
new file mode 100644
index 0000000..019c56b
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
@@ -0,0 +1,178 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestVector test_vectors[] = {
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
+
+     "4c616469657320616e642047656e746c"
+     "656d656e206f662074686520636c6173"
+     "73206f66202739393a20496620492063"
+     "6f756c64206f6666657220796f75206f"
+     "6e6c79206f6e652074697020666f7220"
+     "746865206675747572652c2073756e73"
+     "637265656e20776f756c642062652069"
+     "742e"},
+    // Modify the ciphertext (Poly1305 authenticator).
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecc",  // "d0600691" truncated
+
+     nullptr},
+    // Modify the associated data.
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "60515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
+
+     nullptr},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  uint64_t packet_number;
+  absl::string_view nonce_prefix(nonce.data(),
+                                 nonce.size() - sizeof(packet_number));
+  decrypter->SetNoncePrefix(nonce_prefix);
+  memcpy(&packet_number, nonce.data() + nonce_prefix.size(),
+         sizeof(packet_number));
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success = decrypter->DecryptPacket(
+      packet_number, associated_data, ciphertext, output.get(), &output_length,
+      ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class ChaCha20Poly1305DecrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // If not present then decryption is expected to fail.
+    bool has_pt = test_vectors[i].pt;
+
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+    std::string pt;
+    if (has_pt) {
+      pt = absl::HexStringToBytes(test_vectors[i].pt);
+    }
+
+    ChaCha20Poly1305Decrypter decrypter;
+    ASSERT_TRUE(decrypter.SetKey(key));
+    std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+        &decrypter, fixed + iv,
+        // This deliberately tests that the decrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        ct));
+    if (!decrypted) {
+      EXPECT_FALSE(has_pt);
+      continue;
+    }
+    EXPECT_TRUE(has_pt);
+
+    EXPECT_EQ(12u, ct.size() - decrypted->length());
+    ASSERT_EQ(pt.length(), decrypted->length());
+    quiche::test::CompareCharArraysWithHexError(
+        "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc
new file mode 100644
index 0000000..dcfb523
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305Encrypter::ChaCha20Poly1305Encrypter()
+    : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ false) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305Encrypter::~ChaCha20Poly1305Encrypter() {}
+
+QuicPacketCount ChaCha20Poly1305Encrypter::GetConfidentialityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
+  // number of possible packets (2^62) and so can be disregarded.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_encrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.h
new file mode 100644
index 0000000..d37f26c
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_encrypter.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/chacha_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539, except that
+// it truncates the Poly1305 authenticator to 12 bytes. Create an instance
+// by calling QuicEncrypter::Create(kCC20).
+//
+// It uses an authentication tag of 12 bytes (96 bits). The fixed prefix of the
+// nonce is four bytes.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Encrypter
+    : public ChaChaBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 12,
+  };
+
+  ChaCha20Poly1305Encrypter();
+  ChaCha20Poly1305Encrypter(const ChaCha20Poly1305Encrypter&) = delete;
+  ChaCha20Poly1305Encrypter& operator=(const ChaCha20Poly1305Encrypter&) =
+      delete;
+  ~ChaCha20Poly1305Encrypter() override;
+
+  QuicPacketCount GetConfidentialityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
new file mode 100644
index 0000000..9ae728a
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
@@ -0,0 +1,159 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of five strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* pt;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+};
+
+const TestVector test_vectors[] = {
+    {
+        "808182838485868788898a8b8c8d8e8f"
+        "909192939495969798999a9b9c9d9e9f",
+
+        "4c616469657320616e642047656e746c"
+        "656d656e206f662074686520636c6173"
+        "73206f66202739393a20496620492063"
+        "6f756c64206f6666657220796f75206f"
+        "6e6c79206f6e652074697020666f7220"
+        "746865206675747572652c2073756e73"
+        "637265656e20776f756c642062652069"
+        "742e",
+
+        "4041424344454647",
+
+        "07000000",
+
+        "50515253c0c1c2c3c4c5c6c7",
+
+        "d31a8d34648e60db7b86afbc53ef7ec2"
+        "a4aded51296e08fea9e2b5a736ee62d6"
+        "3dbea45e8ca9671282fafb69da92728b"
+        "1a71de0a9e060b2905d6a5b67ecd3b36"
+        "92ddbd7f2d778b8c9803aee328091b58"
+        "fab324e4fad675945585808b4831d7bc"
+        "3ff4def08e4b7a9de576d26586cec64b"
+        "6116"
+        "1ae10b594f09e26a7e902ecb",  // "d0600691" truncated
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class ChaCha20Poly1305EncrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) {
+  ChaCha20Poly1305Encrypter encrypter;
+  ChaCha20Poly1305Decrypter decrypter;
+
+  std::string key = absl::HexStringToBytes(test_vectors[0].key);
+  ASSERT_TRUE(encrypter.SetKey(key));
+  ASSERT_TRUE(decrypter.SetKey(key));
+  ASSERT_TRUE(encrypter.SetNoncePrefix("abcd"));
+  ASSERT_TRUE(decrypter.SetNoncePrefix("abcd"));
+
+  uint64_t packet_number = UINT64_C(0x123456789ABC);
+  std::string associated_data = "associated_data";
+  std::string plaintext = "plaintext";
+  char encrypted[1024];
+  size_t len;
+  ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
+                                      encrypted, &len,
+                                      ABSL_ARRAYSIZE(encrypted)));
+  absl::string_view ciphertext(encrypted, len);
+  char decrypted[1024];
+  ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
+                                      ciphertext, decrypted, &len,
+                                      ABSL_ARRAYSIZE(decrypted)));
+}
+
+TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+
+    ChaCha20Poly1305Encrypter encrypter;
+    ASSERT_TRUE(encrypter.SetKey(key));
+    std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
+        &encrypter, fixed + iv,
+        // This deliberately tests that the encrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        pt));
+    ASSERT_TRUE(encrypted.get());
+    EXPECT_EQ(12u, ct.size() - pt.size());
+    EXPECT_EQ(12u, encrypted->length() - pt.size());
+
+    quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
+                                                encrypted->length(), ct.data(),
+                                                ct.length());
+  }
+}
+
+TEST_F(ChaCha20Poly1305EncrypterTest, GetMaxPlaintextSize) {
+  ChaCha20Poly1305Encrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+}
+
+TEST_F(ChaCha20Poly1305EncrypterTest, GetCiphertextSize) {
+  ChaCha20Poly1305Encrypter encrypter;
+  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
new file mode 100644
index 0000000..57b5f48
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305TlsDecrypter::ChaCha20Poly1305TlsDecrypter()
+    : ChaChaBaseDecrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305TlsDecrypter::~ChaCha20Poly1305TlsDecrypter() {}
+
+uint32_t ChaCha20Poly1305TlsDecrypter::cipher_id() const {
+  return TLS1_CK_CHACHA20_POLY1305_SHA256;
+}
+
+QuicPacketCount ChaCha20Poly1305TlsDecrypter::GetIntegrityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  static_assert(kMaxIncomingPacketSize < 16384,
+                "This key limit requires limits on decryption payload sizes");
+  return 68719476736U;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
new file mode 100644
index 0000000..f8108f2
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/crypto/chacha_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305TlsDecrypter is a QuicDecrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 bytes IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsDecrypter
+    : public ChaChaBaseDecrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  ChaCha20Poly1305TlsDecrypter();
+  ChaCha20Poly1305TlsDecrypter(const ChaCha20Poly1305TlsDecrypter&) = delete;
+  ChaCha20Poly1305TlsDecrypter& operator=(const ChaCha20Poly1305TlsDecrypter&) =
+      delete;
+  ~ChaCha20Poly1305TlsDecrypter() override;
+
+  uint32_t cipher_id() const override;
+  QuicPacketCount GetIntegrityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
new file mode 100644
index 0000000..0068636
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
@@ -0,0 +1,188 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of six strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  // Input:
+  const char* key;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+
+  // Expected output:
+  const char* pt;  // An empty string "" means decryption succeeded and
+                   // the plaintext is zero-length. nullptr means decryption
+                   // failed.
+};
+
+const TestVector test_vectors[] = {
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecbd0600691",
+
+     "4c616469657320616e642047656e746c"
+     "656d656e206f662074686520636c6173"
+     "73206f66202739393a20496620492063"
+     "6f756c64206f6666657220796f75206f"
+     "6e6c79206f6e652074697020666f7220"
+     "746865206675747572652c2073756e73"
+     "637265656e20776f756c642062652069"
+     "742e"},
+    // Modify the ciphertext (Poly1305 authenticator).
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "50515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902eccd0600691",
+
+     nullptr},
+    // Modify the associated data.
+    {"808182838485868788898a8b8c8d8e8f"
+     "909192939495969798999a9b9c9d9e9f",
+
+     "4041424344454647",
+
+     "07000000",
+
+     "60515253c0c1c2c3c4c5c6c7",
+
+     "d31a8d34648e60db7b86afbc53ef7ec2"
+     "a4aded51296e08fea9e2b5a736ee62d6"
+     "3dbea45e8ca9671282fafb69da92728b"
+     "1a71de0a9e060b2905d6a5b67ecd3b36"
+     "92ddbd7f2d778b8c9803aee328091b58"
+     "fab324e4fad675945585808b4831d7bc"
+     "3ff4def08e4b7a9de576d26586cec64b"
+     "6116"
+     "1ae10b594f09e26a7e902ecbd0600691",
+
+     nullptr},
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the plaintext.
+QuicData* DecryptWithNonce(ChaCha20Poly1305TlsDecrypter* decrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view ciphertext) {
+  decrypter->SetIV(nonce);
+  std::unique_ptr<char[]> output(new char[ciphertext.length()]);
+  size_t output_length = 0;
+  const bool success =
+      decrypter->DecryptPacket(0, associated_data, ciphertext, output.get(),
+                               &output_length, ciphertext.length());
+  if (!success) {
+    return nullptr;
+  }
+  return new QuicData(output.release(), output_length, true);
+}
+
+class ChaCha20Poly1305TlsDecrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // If not present then decryption is expected to fail.
+    bool has_pt = test_vectors[i].pt;
+
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+    std::string pt;
+    if (has_pt) {
+      pt = absl::HexStringToBytes(test_vectors[i].pt);
+    }
+
+    ChaCha20Poly1305TlsDecrypter decrypter;
+    ASSERT_TRUE(decrypter.SetKey(key));
+    std::unique_ptr<QuicData> decrypted(DecryptWithNonce(
+        &decrypter, fixed + iv,
+        // This deliberately tests that the decrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        ct));
+    if (!decrypted) {
+      EXPECT_FALSE(has_pt);
+      continue;
+    }
+    EXPECT_TRUE(has_pt);
+
+    EXPECT_EQ(16u, ct.size() - decrypted->length());
+    ASSERT_EQ(pt.length(), decrypted->length());
+    quiche::test::CompareCharArraysWithHexError(
+        "plaintext", decrypted->data(), pt.length(), pt.data(), pt.length());
+  }
+}
+
+TEST_F(ChaCha20Poly1305TlsDecrypterTest, GenerateHeaderProtectionMask) {
+  ChaCha20Poly1305TlsDecrypter decrypter;
+  std::string key = absl::HexStringToBytes(
+      "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
+  std::string sample =
+      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
+  QuicDataReader sample_reader(sample.data(), sample.size());
+  ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
+  std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
+  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
new file mode 100644
index 0000000..12e3153
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
+
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kKeySize = 32;
+const size_t kNonceSize = 12;
+
+}  // namespace
+
+ChaCha20Poly1305TlsEncrypter::ChaCha20Poly1305TlsEncrypter()
+    : ChaChaBaseEncrypter(EVP_aead_chacha20_poly1305,
+                          kKeySize,
+                          kAuthTagSize,
+                          kNonceSize,
+                          /* use_ietf_nonce_construction */ true) {
+  static_assert(kKeySize <= kMaxKeySize, "key size too big");
+  static_assert(kNonceSize <= kMaxNonceSize, "nonce size too big");
+}
+
+ChaCha20Poly1305TlsEncrypter::~ChaCha20Poly1305TlsEncrypter() {}
+
+QuicPacketCount ChaCha20Poly1305TlsEncrypter::GetConfidentialityLimit() const {
+  // For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the
+  // number of possible packets (2^62) and so can be disregarded.
+  // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-limits-on-aead-usage
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
new file mode 100644
index 0000000..e5d8f37
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
+
+#include "quiche/quic/core/crypto/chacha_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ChaCha20Poly1305Encrypter is a QuicEncrypter that implements the
+// AEAD_CHACHA20_POLY1305 algorithm specified in RFC 7539 for use in IETF QUIC.
+//
+// It uses an authentication tag of 16 bytes (128 bits). It uses a 12 byte IV
+// that is XOR'd with the packet number to compute the nonce.
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305TlsEncrypter
+    : public ChaChaBaseEncrypter {
+ public:
+  enum {
+    kAuthTagSize = 16,
+  };
+
+  ChaCha20Poly1305TlsEncrypter();
+  ChaCha20Poly1305TlsEncrypter(const ChaCha20Poly1305TlsEncrypter&) = delete;
+  ChaCha20Poly1305TlsEncrypter& operator=(const ChaCha20Poly1305TlsEncrypter&) =
+      delete;
+  ~ChaCha20Poly1305TlsEncrypter() override;
+
+  QuicPacketCount GetConfidentialityLimit() const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA20_POLY1305_TLS_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
new file mode 100644
index 0000000..322651b
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
@@ -0,0 +1,173 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace {
+
+// The test vectors come from RFC 7539 Section 2.8.2.
+
+// Each test vector consists of five strings of lowercase hexadecimal digits.
+// The strings may be empty (zero length). A test vector with a nullptr |key|
+// marks the end of an array of test vectors.
+struct TestVector {
+  const char* key;
+  const char* pt;
+  const char* iv;
+  const char* fixed;
+  const char* aad;
+  const char* ct;
+};
+
+const TestVector test_vectors[] = {
+    {
+        "808182838485868788898a8b8c8d8e8f"
+        "909192939495969798999a9b9c9d9e9f",
+
+        "4c616469657320616e642047656e746c"
+        "656d656e206f662074686520636c6173"
+        "73206f66202739393a20496620492063"
+        "6f756c64206f6666657220796f75206f"
+        "6e6c79206f6e652074697020666f7220"
+        "746865206675747572652c2073756e73"
+        "637265656e20776f756c642062652069"
+        "742e",
+
+        "4041424344454647",
+
+        "07000000",
+
+        "50515253c0c1c2c3c4c5c6c7",
+
+        "d31a8d34648e60db7b86afbc53ef7ec2"
+        "a4aded51296e08fea9e2b5a736ee62d6"
+        "3dbea45e8ca9671282fafb69da92728b"
+        "1a71de0a9e060b2905d6a5b67ecd3b36"
+        "92ddbd7f2d778b8c9803aee328091b58"
+        "fab324e4fad675945585808b4831d7bc"
+        "3ff4def08e4b7a9de576d26586cec64b"
+        "6116"
+        "1ae10b594f09e26a7e902ecbd0600691",
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}};
+
+}  // namespace
+
+namespace quic {
+namespace test {
+
+// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
+// in an nonce and also to allocate the buffer needed for the ciphertext.
+QuicData* EncryptWithNonce(ChaCha20Poly1305TlsEncrypter* encrypter,
+                           absl::string_view nonce,
+                           absl::string_view associated_data,
+                           absl::string_view plaintext) {
+  size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
+  std::unique_ptr<char[]> ciphertext(new char[ciphertext_size]);
+
+  if (!encrypter->Encrypt(nonce, associated_data, plaintext,
+                          reinterpret_cast<unsigned char*>(ciphertext.get()))) {
+    return nullptr;
+  }
+
+  return new QuicData(ciphertext.release(), ciphertext_size, true);
+}
+
+class ChaCha20Poly1305TlsEncrypterTest : public QuicTest {};
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  ChaCha20Poly1305TlsDecrypter decrypter;
+
+  std::string key = absl::HexStringToBytes(test_vectors[0].key);
+  ASSERT_TRUE(encrypter.SetKey(key));
+  ASSERT_TRUE(decrypter.SetKey(key));
+  ASSERT_TRUE(encrypter.SetIV("abcdefghijkl"));
+  ASSERT_TRUE(decrypter.SetIV("abcdefghijkl"));
+
+  uint64_t packet_number = UINT64_C(0x123456789ABC);
+  std::string associated_data = "associated_data";
+  std::string plaintext = "plaintext";
+  char encrypted[1024];
+  size_t len;
+  ASSERT_TRUE(encrypter.EncryptPacket(packet_number, associated_data, plaintext,
+                                      encrypted, &len,
+                                      ABSL_ARRAYSIZE(encrypted)));
+  absl::string_view ciphertext(encrypted, len);
+  char decrypted[1024];
+  ASSERT_TRUE(decrypter.DecryptPacket(packet_number, associated_data,
+                                      ciphertext, decrypted, &len,
+                                      ABSL_ARRAYSIZE(decrypted)));
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) {
+  for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
+    // Decode the test vector.
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
+
+    ChaCha20Poly1305TlsEncrypter encrypter;
+    ASSERT_TRUE(encrypter.SetKey(key));
+    std::unique_ptr<QuicData> encrypted(EncryptWithNonce(
+        &encrypter, fixed + iv,
+        // This deliberately tests that the encrypter can handle an AAD that
+        // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
+        absl::string_view(aad.length() ? aad.data() : nullptr, aad.length()),
+        pt));
+    ASSERT_TRUE(encrypted.get());
+    EXPECT_EQ(16u, ct.size() - pt.size());
+    EXPECT_EQ(16u, encrypted->length() - pt.size());
+
+    quiche::test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
+                                                encrypted->length(), ct.data(),
+                                                ct.length());
+  }
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetMaxPlaintextSize) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, GetCiphertextSize) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+}
+
+TEST_F(ChaCha20Poly1305TlsEncrypterTest, GenerateHeaderProtectionMask) {
+  ChaCha20Poly1305TlsEncrypter encrypter;
+  std::string key = absl::HexStringToBytes(
+      "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
+  std::string sample =
+      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
+  ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
+  std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
+  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
+  quiche::test::CompareCharArraysWithHexError(
+      "header protection mask", mask.data(), mask.size(), expected_mask.data(),
+      expected_mask.size());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha_base_decrypter.cc b/quiche/quic/core/crypto/chacha_base_decrypter.cc
new file mode 100644
index 0000000..ec8e8a9
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_decrypter.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha_base_decrypter.h"
+
+#include <cstdint>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/chacha.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+bool ChaChaBaseDecrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10620_1) << "Invalid key size for header protection";
+    return false;
+  }
+  memcpy(pne_key_, key.data(), key.size());
+  return true;
+}
+
+std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask(
+    QuicDataReader* sample_reader) {
+  absl::string_view sample;
+  if (!sample_reader->ReadStringPiece(&sample, 16)) {
+    return std::string();
+  }
+  const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
+  uint32_t counter;
+  QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
+      .ReadUInt32(&counter);
+  const uint8_t zeroes[] = {0, 0, 0, 0, 0};
+  std::string out(ABSL_ARRAYSIZE(zeroes), 0);
+  CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+                   zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
+  return out;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha_base_decrypter.h b/quiche/quic/core/crypto/chacha_base_decrypter.h
new file mode 100644
index 0000000..5cd08c7
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_decrypter.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/aead_base_decrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE ChaChaBaseDecrypter : public AeadBaseDecrypter {
+ public:
+  using AeadBaseDecrypter::AeadBaseDecrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) override;
+
+ private:
+  // The key used for packet number encryption.
+  unsigned char pne_key_[kMaxKeySize];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/chacha_base_encrypter.cc b/quiche/quic/core/crypto/chacha_base_encrypter.cc
new file mode 100644
index 0000000..12c1f55
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_encrypter.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/chacha_base_encrypter.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/chacha.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+bool ChaChaBaseEncrypter::SetHeaderProtectionKey(absl::string_view key) {
+  if (key.size() != GetKeySize()) {
+    QUIC_BUG(quic_bug_10656_1) << "Invalid key size for header protection";
+    return false;
+  }
+  memcpy(pne_key_, key.data(), key.size());
+  return true;
+}
+
+std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask(
+    absl::string_view sample) {
+  if (sample.size() != 16) {
+    return std::string();
+  }
+  const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4;
+  uint32_t counter;
+  QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER)
+      .ReadUInt32(&counter);
+  const uint8_t zeroes[] = {0, 0, 0, 0, 0};
+  std::string out(ABSL_ARRAYSIZE(zeroes), 0);
+  CRYPTO_chacha_20(reinterpret_cast<uint8_t*>(const_cast<char*>(out.data())),
+                   zeroes, ABSL_ARRAYSIZE(zeroes), pne_key_, nonce, counter);
+  return out;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/chacha_base_encrypter.h b/quiche/quic/core/crypto/chacha_base_encrypter.h
new file mode 100644
index 0000000..14773ec
--- /dev/null
+++ b/quiche/quic/core/crypto/chacha_base_encrypter.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/aead_base_encrypter.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE ChaChaBaseEncrypter : public AeadBaseEncrypter {
+ public:
+  using AeadBaseEncrypter::AeadBaseEncrypter;
+
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
+
+ private:
+  // The key used for packet number encryption.
+  unsigned char pne_key_[kMaxKeySize];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHACHA_BASE_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/channel_id.cc b/quiche/quic/core/crypto/channel_id.cc
new file mode 100644
index 0000000..5e222f1
--- /dev/null
+++ b/quiche/quic/core/crypto/channel_id.cc
@@ -0,0 +1,90 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/channel_id.h"
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/nid.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+
+namespace quic {
+
+// static
+const char ChannelIDVerifier::kContextStr[] = "QUIC ChannelID";
+// static
+const char ChannelIDVerifier::kClientToServerStr[] = "client -> server";
+
+// static
+bool ChannelIDVerifier::Verify(absl::string_view key,
+                               absl::string_view signed_data,
+                               absl::string_view signature) {
+  return VerifyRaw(key, signed_data, signature, true);
+}
+
+// static
+bool ChannelIDVerifier::VerifyRaw(absl::string_view key,
+                                  absl::string_view signed_data,
+                                  absl::string_view signature,
+                                  bool is_channel_id_signature) {
+  if (key.size() != 32 * 2 || signature.size() != 32 * 2) {
+    return false;
+  }
+
+  bssl::UniquePtr<EC_GROUP> p256(
+      EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+  if (p256.get() == nullptr) {
+    return false;
+  }
+
+  bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), r(BN_new()), s(BN_new());
+
+  ECDSA_SIG sig;
+  sig.r = r.get();
+  sig.s = s.get();
+
+  const uint8_t* key_bytes = reinterpret_cast<const uint8_t*>(key.data());
+  const uint8_t* signature_bytes =
+      reinterpret_cast<const uint8_t*>(signature.data());
+
+  if (BN_bin2bn(key_bytes + 0, 32, x.get()) == nullptr ||
+      BN_bin2bn(key_bytes + 32, 32, y.get()) == nullptr ||
+      BN_bin2bn(signature_bytes + 0, 32, sig.r) == nullptr ||
+      BN_bin2bn(signature_bytes + 32, 32, sig.s) == nullptr) {
+    return false;
+  }
+
+  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
+  if (point.get() == nullptr ||
+      !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
+                                           y.get(), nullptr)) {
+    return false;
+  }
+
+  bssl::UniquePtr<EC_KEY> ecdsa_key(EC_KEY_new());
+  if (ecdsa_key.get() == nullptr ||
+      !EC_KEY_set_group(ecdsa_key.get(), p256.get()) ||
+      !EC_KEY_set_public_key(ecdsa_key.get(), point.get())) {
+    return false;
+  }
+
+  SHA256_CTX sha256;
+  SHA256_Init(&sha256);
+  if (is_channel_id_signature) {
+    SHA256_Update(&sha256, kContextStr, strlen(kContextStr) + 1);
+    SHA256_Update(&sha256, kClientToServerStr, strlen(kClientToServerStr) + 1);
+  }
+  SHA256_Update(&sha256, signed_data.data(), signed_data.size());
+
+  unsigned char digest[SHA256_DIGEST_LENGTH];
+  SHA256_Final(digest, &sha256);
+
+  return ECDSA_do_verify(digest, sizeof(digest), &sig, ecdsa_key.get()) == 1;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/channel_id.h b/quiche/quic/core/crypto/channel_id.h
new file mode 100644
index 0000000..9d20215
--- /dev/null
+++ b/quiche/quic/core/crypto/channel_id.h
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// ChannelIDVerifier verifies ChannelID signatures.
+class QUIC_EXPORT_PRIVATE ChannelIDVerifier {
+ public:
+  ChannelIDVerifier() = delete;
+
+  // kContextStr is prepended to the data to be signed in order to ensure that
+  // a ChannelID signature cannot be used in a different context. (The
+  // terminating NUL byte is inclued.)
+  static const char kContextStr[];
+  // kClientToServerStr follows kContextStr to specify that the ChannelID is
+  // being used in the client to server direction. (The terminating NUL byte is
+  // included.)
+  static const char kClientToServerStr[];
+
+  // Verify returns true iff |signature| is a valid signature of |signed_data|
+  // by |key|.
+  static bool Verify(absl::string_view key,
+                     absl::string_view signed_data,
+                     absl::string_view signature);
+
+  // FOR TESTING ONLY: VerifyRaw returns true iff |signature| is a valid
+  // signature of |signed_data| by |key|. |is_channel_id_signature| indicates
+  // whether |signature| is a ChannelID signature (with kContextStr prepended
+  // to the data to be signed).
+  static bool VerifyRaw(absl::string_view key,
+                        absl::string_view signed_data,
+                        absl::string_view signature,
+                        bool is_channel_id_signature);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CHANNEL_ID_H_
diff --git a/quiche/quic/core/crypto/channel_id_test.cc b/quiche/quic/core/crypto/channel_id_test.cc
new file mode 100644
index 0000000..40e5090
--- /dev/null
+++ b/quiche/quic/core/crypto/channel_id_test.cc
@@ -0,0 +1,287 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/channel_id.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+// The following ECDSA signature verification test vectors for P-256,SHA-256
+// come from the SigVer.rsp file in
+// http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
+// downloaded on 2013-06-11.
+struct TestVector {
+  // Input:
+  const char* msg;
+  const char* qx;
+  const char* qy;
+  const char* r;
+  const char* s;
+
+  // Expected output:
+  bool result;  // true means "P", false means "F"
+};
+
+const TestVector test_vector[] = {
+    {
+        "e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d"
+        "9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19"
+        "fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c"
+        "24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0",
+        "87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555",
+        "e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9",
+        "d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0",
+        "a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6",
+        false  // F (3 - S changed)
+    },
+    {
+        "069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d6"
+        "83877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae187300"
+        "4565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b"
+        "3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e",
+        "5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2",
+        "ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85",
+        "dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693",
+        "d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c",
+        false  // F (2 - R changed)
+    },
+    {
+        "df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d"
+        "8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af7149598"
+        "96858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd861"
+        "28cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de",
+        "2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb",
+        "5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64",
+        "9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8",
+        "9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc",
+        false  // F (4 - Q changed)
+    },
+    {
+        "e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45f"
+        "d75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217"
+        "ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce4"
+        "70a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3",
+        "e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c",
+        "970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927",
+        "bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f",
+        "17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c",
+        true  // P (0 )
+    },
+    {
+        "73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730f"
+        "b68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f226"
+        "63bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a"
+        "6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08",
+        "e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864",
+        "7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a",
+        "1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407",
+        "cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a",
+        true  // P (0 )
+    },
+    {
+        "666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2"
+        "b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a"
+        "282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9"
+        "c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548",
+        "a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86",
+        "bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471",
+        "25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6",
+        "9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537",
+        false  // F (2 - R changed)
+    },
+    {
+        "7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f89"
+        "4edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25"
+        "b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660ef"
+        "b57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd",
+        "3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df",
+        "f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb",
+        "548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a",
+        "e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75",
+        false  // F (4 - Q changed)
+    },
+    {
+        "1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce1"
+        "3e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f2"
+        "2d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c"
+        "438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169",
+        "69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214",
+        "d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f",
+        "288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790",
+        "247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979",
+        false  // F (1 - Message changed)
+    },
+    {
+        "3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076"
+        "115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788e"
+        "c6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576e"
+        "fc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970",
+        "bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682",
+        "069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03",
+        "f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad",
+        "049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d",
+        false  // F (3 - S changed)
+    },
+    {
+        "983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312"
+        "a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd"
+        "9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a891"
+        "29938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c",
+        "224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de",
+        "178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9",
+        "87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2",
+        "4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66",
+        false  // F (2 - R changed)
+    },
+    {
+        "4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac28733"
+        "9e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfd"
+        "b892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4"
+        "f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af",
+        "43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369",
+        "f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac",
+        "8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce",
+        "cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154",
+        false  // F (3 - S changed)
+    },
+    {
+        "0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0"
+        "718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0"
+        "bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87a"
+        "c8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216",
+        "9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596",
+        "972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405",
+        "dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb",
+        "8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2",
+        false  // F (1 - Message changed)
+    },
+    {
+        "785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc285"
+        "81dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c"
+        "60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c557749"
+        "28c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e",
+        "072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda",
+        "9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5",
+        "09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19",
+        "a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d",
+        false  // F (4 - Q changed)
+    },
+    {
+        "76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e722"
+        "9ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad"
+        "3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212d"
+        "d4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca",
+        "09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24",
+        "f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5",
+        "5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73",
+        "9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7",
+        false  // F (1 - Message changed)
+    },
+    {
+        "60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855"
+        "dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddb"
+        "d1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c0"
+        "03c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84",
+        "2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d",
+        "9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a",
+        "06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959",
+        "62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce",
+        true  // P (0 )
+    },
+    {nullptr, nullptr, nullptr, nullptr, nullptr, false}};
+
+// Returns true if |ch| is a lowercase hexadecimal digit.
+bool IsHexDigit(char ch) {
+  return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f');
+}
+
+// Converts a lowercase hexadecimal digit to its integer value.
+int HexDigitToInt(char ch) {
+  if ('0' <= ch && ch <= '9') {
+    return ch - '0';
+  }
+  return ch - 'a' + 10;
+}
+
+// |in| is a string consisting of lowercase hexadecimal digits, where
+// every two digits represent one byte. |out| is a buffer of size |max_len|.
+// Converts |in| to bytes and stores the bytes in the |out| buffer. The
+// number of bytes converted is returned in |*out_len|. Returns true on
+// success, false on failure.
+bool DecodeHexString(const char* in,
+                     char* out,
+                     size_t* out_len,
+                     size_t max_len) {
+  if (!in) {
+    *out_len = static_cast<size_t>(-1);
+    return true;
+  }
+  *out_len = 0;
+  while (*in != '\0') {
+    if (!IsHexDigit(*in) || !IsHexDigit(*(in + 1))) {
+      return false;
+    }
+    if (*out_len >= max_len) {
+      return false;
+    }
+    out[*out_len] = HexDigitToInt(*in) * 16 + HexDigitToInt(*(in + 1));
+    (*out_len)++;
+    in += 2;
+  }
+  return true;
+}
+
+}  // namespace
+
+class ChannelIDTest : public QuicTest {};
+
+// A known answer test for ChannelIDVerifier.
+TEST_F(ChannelIDTest, VerifyKnownAnswerTest) {
+  char msg[1024];
+  size_t msg_len;
+  char key[64];
+  size_t qx_len;
+  size_t qy_len;
+  char signature[64];
+  size_t r_len;
+  size_t s_len;
+
+  for (size_t i = 0; test_vector[i].msg != nullptr; i++) {
+    SCOPED_TRACE(i);
+    // Decode the test vector.
+    ASSERT_TRUE(
+        DecodeHexString(test_vector[i].msg, msg, &msg_len, sizeof(msg)));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].qx, key, &qx_len, sizeof(key)));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].qy, key + qx_len, &qy_len,
+                                sizeof(key) - qx_len));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].r, signature, &r_len,
+                                sizeof(signature)));
+    ASSERT_TRUE(DecodeHexString(test_vector[i].s, signature + r_len, &s_len,
+                                sizeof(signature) - r_len));
+
+    // The test vector's lengths should look sane.
+    EXPECT_EQ(sizeof(key) / 2, qx_len);
+    EXPECT_EQ(sizeof(key) / 2, qy_len);
+    EXPECT_EQ(sizeof(signature) / 2, r_len);
+    EXPECT_EQ(sizeof(signature) / 2, s_len);
+
+    EXPECT_EQ(test_vector[i].result,
+              ChannelIDVerifier::VerifyRaw(
+                  absl::string_view(key, sizeof(key)),
+                  absl::string_view(msg, msg_len),
+                  absl::string_view(signature, sizeof(signature)), false));
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/client_proof_source.cc b/quiche/quic/core/crypto/client_proof_source.cc
new file mode 100644
index 0000000..9d4795c
--- /dev/null
+++ b/quiche/quic/core/crypto/client_proof_source.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/client_proof_source.h"
+
+#include "absl/strings/match.h"
+
+namespace quic {
+
+bool DefaultClientProofSource::AddCertAndKey(
+    std::vector<std::string> server_hostnames,
+    quiche::QuicheReferenceCountedPointer<Chain> chain,
+    CertificatePrivateKey private_key) {
+  if (!ValidateCertAndKey(chain, private_key)) {
+    return false;
+  }
+
+  auto cert_and_key =
+      std::make_shared<CertAndKey>(std::move(chain), std::move(private_key));
+  for (const std::string& domain : server_hostnames) {
+    cert_and_keys_[domain] = cert_and_key;
+  }
+  return true;
+}
+
+const ClientProofSource::CertAndKey* DefaultClientProofSource::GetCertAndKey(
+    absl::string_view hostname) const {
+  const CertAndKey* result = LookupExact(hostname);
+  if (result != nullptr || hostname == "*") {
+    return result;
+  }
+
+  // Either a full or a wildcard domain lookup failed. In the former case,
+  // derive the wildcard domain and look it up.
+  if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) {
+    auto dot_pos = hostname.find('.');
+    if (dot_pos != std::string::npos) {
+      std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
+      const CertAndKey* result = LookupExact(wildcard);
+      if (result != nullptr) {
+        return result;
+      }
+    }
+  }
+
+  // Return default cert, if any.
+  return LookupExact("*");
+}
+
+const ClientProofSource::CertAndKey* DefaultClientProofSource::LookupExact(
+    absl::string_view map_key) const {
+  const auto it = cert_and_keys_.find(map_key);
+  QUIC_DVLOG(1) << "LookupExact(" << map_key
+                << ") found:" << (it != cert_and_keys_.end());
+  if (it != cert_and_keys_.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/client_proof_source.h b/quiche/quic/core/crypto/client_proof_source.h
new file mode 100644
index 0000000..d1450f7
--- /dev/null
+++ b/quiche/quic/core/crypto/client_proof_source.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
+
+#include <memory>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+
+namespace quic {
+
+// ClientProofSource is the interface for a QUIC client to provide client certs
+// and keys based on server hostname. It is only used by TLS handshakes.
+class QUIC_EXPORT_PRIVATE ClientProofSource {
+ public:
+  using Chain = ProofSource::Chain;
+
+  virtual ~ClientProofSource() {}
+
+  struct QUIC_EXPORT_PRIVATE CertAndKey {
+    CertAndKey(quiche::QuicheReferenceCountedPointer<Chain> chain,
+               CertificatePrivateKey private_key)
+        : chain(std::move(chain)), private_key(std::move(private_key)) {}
+
+    quiche::QuicheReferenceCountedPointer<Chain> chain;
+    CertificatePrivateKey private_key;
+  };
+
+  // Get the client certificate to be sent to the server with |server_hostname|
+  // and its corresponding private key. It returns nullptr if the cert and key
+  // can not be found.
+  //
+  // |server_hostname| is typically a full domain name(www.foo.com), but it
+  // could also be a wildcard domain(*.foo.com), or a "*" which will return the
+  // default cert.
+  virtual const CertAndKey* GetCertAndKey(
+      absl::string_view server_hostname) const = 0;
+};
+
+// DefaultClientProofSource is an implementation that simply keeps an in memory
+// map of server hostnames to certs.
+class QUIC_EXPORT_PRIVATE DefaultClientProofSource : public ClientProofSource {
+ public:
+  ~DefaultClientProofSource() override {}
+
+  // Associate all hostnames in |server_hostnames| with {|chain|,|private_key|}.
+  // Elements of |server_hostnames| can be full domain names(www.foo.com),
+  // wildcard domains(*.foo.com), or "*" which means the given cert chain is the
+  // default one.
+  // If any element of |server_hostnames| is already associated with a cert
+  // chain, it will be updated to be associated with the new cert chain.
+  bool AddCertAndKey(std::vector<std::string> server_hostnames,
+                     quiche::QuicheReferenceCountedPointer<Chain> chain,
+                     CertificatePrivateKey private_key);
+
+  // ClientProofSource implementation
+  const CertAndKey* GetCertAndKey(absl::string_view hostname) const override;
+
+ private:
+  const CertAndKey* LookupExact(absl::string_view map_key) const;
+  absl::flat_hash_map<std::string, std::shared_ptr<CertAndKey>> cert_and_keys_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CLIENT_PROOF_SOURCE_H_
diff --git a/quiche/quic/core/crypto/client_proof_source_test.cc b/quiche/quic/core/crypto/client_proof_source_test.cc
new file mode 100644
index 0000000..a35e0aa
--- /dev/null
+++ b/quiche/quic/core/crypto/client_proof_source_test.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/client_proof_source.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+
+namespace quic {
+namespace test {
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+TestCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+      new ClientProofSource::Chain({std::string(kTestCertificate)}));
+}
+
+CertificatePrivateKey TestPrivateKey() {
+  CBS private_key_cbs;
+  CBS_init(&private_key_cbs,
+           reinterpret_cast<const uint8_t*>(kTestCertificatePrivateKey.data()),
+           kTestCertificatePrivateKey.size());
+
+  return CertificatePrivateKey(
+      bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&private_key_cbs)));
+}
+
+const ClientProofSource::CertAndKey* TestCertAndKey() {
+  static const ClientProofSource::CertAndKey cert_and_key(TestCertChain(),
+                                                          TestPrivateKey());
+  return &cert_and_key;
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+NullCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>();
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+EmptyCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+      new ClientProofSource::Chain(std::vector<std::string>()));
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain> BadCertChain() {
+  return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+      new ClientProofSource::Chain({"This is the content of a bad cert."}));
+}
+
+CertificatePrivateKey EmptyPrivateKey() {
+  return CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY>(EVP_PKEY_new()));
+}
+
+#define VERIFY_CERT_AND_KEY_MATCHES(lhs, rhs) \
+  do {                                        \
+    SCOPED_TRACE(testing::Message());         \
+    VerifyCertAndKeyMatches(lhs, rhs);        \
+  } while (0)
+
+void VerifyCertAndKeyMatches(const ClientProofSource::CertAndKey* lhs,
+                             const ClientProofSource::CertAndKey* rhs) {
+  if (lhs == rhs) {
+    return;
+  }
+
+  if (lhs == nullptr) {
+    ADD_FAILURE() << "lhs is nullptr, but rhs is not";
+    return;
+  }
+
+  if (rhs == nullptr) {
+    ADD_FAILURE() << "rhs is nullptr, but lhs is not";
+    return;
+  }
+
+  if (1 != EVP_PKEY_cmp(lhs->private_key.private_key(),
+                        rhs->private_key.private_key())) {
+    ADD_FAILURE() << "Private keys mismatch";
+    return;
+  }
+
+  const ClientProofSource::Chain* lhs_chain = lhs->chain.get();
+  const ClientProofSource::Chain* rhs_chain = rhs->chain.get();
+
+  if (lhs_chain == rhs_chain) {
+    return;
+  }
+
+  if (lhs_chain == nullptr) {
+    ADD_FAILURE() << "lhs->chain is nullptr, but rhs->chain is not";
+    return;
+  }
+
+  if (rhs_chain == nullptr) {
+    ADD_FAILURE() << "rhs->chain is nullptr, but lhs->chain is not";
+    return;
+  }
+
+  if (lhs_chain->certs.size() != rhs_chain->certs.size()) {
+    ADD_FAILURE() << "Cert chain length differ. lhs:" << lhs_chain->certs.size()
+                  << ", rhs:" << rhs_chain->certs.size();
+    return;
+  }
+
+  for (size_t i = 0; i < lhs_chain->certs.size(); ++i) {
+    if (lhs_chain->certs[i] != rhs_chain->certs[i]) {
+      ADD_FAILURE() << "The " << i << "-th certs differ.";
+      return;
+    }
+  }
+
+  // All good.
+}
+
+TEST(DefaultClientProofSource, FullDomain) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com"}, TestCertChain(),
+                                         TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  EXPECT_EQ(proof_source.GetCertAndKey("*.google.com"), nullptr);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, WildcardDomain) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(proof_source.AddCertAndKey({"*.google.com"}, TestCertChain(),
+                                         TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+                              TestCertAndKey());
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, DefaultDomain) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(
+      proof_source.AddCertAndKey({"*"}, TestCertChain(), TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
+                              TestCertAndKey());
+}
+
+TEST(DefaultClientProofSource, FullAndWildcard) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com", "*.google.com"},
+                                         TestCertChain(), TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
+                              TestCertAndKey());
+  EXPECT_EQ(proof_source.GetCertAndKey("www.example.com"), nullptr);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, FullWildcardAndDefault) {
+  DefaultClientProofSource proof_source;
+  ASSERT_TRUE(
+      proof_source.AddCertAndKey({"www.google.com", "*.google.com", "*"},
+                                 TestCertChain(), TestPrivateKey()));
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.example.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+                              TestCertAndKey());
+  VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
+                              TestCertAndKey());
+}
+
+TEST(DefaultClientProofSource, EmptyCerts) {
+  DefaultClientProofSource proof_source;
+  bool ok;
+  EXPECT_QUIC_BUG(
+      ok = proof_source.AddCertAndKey({"*"}, NullCertChain(), TestPrivateKey()),
+      "Certificate chain is empty");
+  ASSERT_FALSE(ok);
+
+  EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey({"*"}, EmptyCertChain(),
+                                                  TestPrivateKey()),
+                  "Certificate chain is empty");
+  ASSERT_FALSE(ok);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, BadCerts) {
+  DefaultClientProofSource proof_source;
+  bool ok;
+  EXPECT_QUIC_BUG(
+      ok = proof_source.AddCertAndKey({"*"}, BadCertChain(), TestPrivateKey()),
+      "Unabled to parse leaf certificate");
+  ASSERT_FALSE(ok);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, KeyMismatch) {
+  DefaultClientProofSource proof_source;
+  bool ok;
+  EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey(
+                      {"www.google.com"}, TestCertChain(), EmptyPrivateKey()),
+                  "Private key does not match the leaf certificate");
+  ASSERT_FALSE(ok);
+  EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_framer.cc b/quiche/quic/core/crypto/crypto_framer.cc
new file mode 100644
index 0000000..db4e0b0
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_framer.cc
@@ -0,0 +1,358 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_framer.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kQuicTagSize = sizeof(QuicTag);
+const size_t kCryptoEndOffsetSize = sizeof(uint32_t);
+const size_t kNumEntriesSize = sizeof(uint16_t);
+
+// OneShotVisitor is a framer visitor that records a single handshake message.
+class OneShotVisitor : public CryptoFramerVisitorInterface {
+ public:
+  OneShotVisitor() : error_(false) {}
+
+  void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    out_ = std::make_unique<CryptoHandshakeMessage>(message);
+  }
+
+  bool error() const { return error_; }
+
+  std::unique_ptr<CryptoHandshakeMessage> release() { return std::move(out_); }
+
+ private:
+  std::unique_ptr<CryptoHandshakeMessage> out_;
+  bool error_;
+};
+
+}  // namespace
+
+CryptoFramer::CryptoFramer()
+    : visitor_(nullptr),
+      error_detail_(""),
+      num_entries_(0),
+      values_len_(0),
+      process_truncated_messages_(false) {
+  Clear();
+}
+
+CryptoFramer::~CryptoFramer() {}
+
+// static
+std::unique_ptr<CryptoHandshakeMessage> CryptoFramer::ParseMessage(
+    absl::string_view in) {
+  OneShotVisitor visitor;
+  CryptoFramer framer;
+
+  framer.set_visitor(&visitor);
+  if (!framer.ProcessInput(in) || visitor.error() ||
+      framer.InputBytesRemaining()) {
+    return nullptr;
+  }
+
+  return visitor.release();
+}
+
+QuicErrorCode CryptoFramer::error() const {
+  return error_;
+}
+
+const std::string& CryptoFramer::error_detail() const {
+  return error_detail_;
+}
+
+bool CryptoFramer::ProcessInput(absl::string_view input,
+                                EncryptionLevel /*level*/) {
+  return ProcessInput(input);
+}
+
+bool CryptoFramer::ProcessInput(absl::string_view input) {
+  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
+  if (error_ != QUIC_NO_ERROR) {
+    return false;
+  }
+  error_ = Process(input);
+  if (error_ != QUIC_NO_ERROR) {
+    QUICHE_DCHECK(!error_detail_.empty());
+    visitor_->OnError(this);
+    return false;
+  }
+
+  return true;
+}
+
+size_t CryptoFramer::InputBytesRemaining() const {
+  return buffer_.length();
+}
+
+bool CryptoFramer::HasTag(QuicTag tag) const {
+  if (state_ != STATE_READING_VALUES) {
+    return false;
+  }
+  for (const auto& it : tags_and_lengths_) {
+    if (it.first == tag) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void CryptoFramer::ForceHandshake() {
+  QuicDataReader reader(buffer_.data(), buffer_.length(),
+                        quiche::HOST_BYTE_ORDER);
+  for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
+    absl::string_view value;
+    if (reader.BytesRemaining() < item.second) {
+      break;
+    }
+    reader.ReadStringPiece(&value, item.second);
+    message_.SetStringPiece(item.first, value);
+  }
+  visitor_->OnHandshakeMessage(message_);
+}
+
+// static
+std::unique_ptr<QuicData> CryptoFramer::ConstructHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  size_t num_entries = message.tag_value_map().size();
+  size_t pad_length = 0;
+  bool need_pad_tag = false;
+  bool need_pad_value = false;
+
+  size_t len = message.size();
+  if (len < message.minimum_size()) {
+    need_pad_tag = true;
+    need_pad_value = true;
+    num_entries++;
+
+    size_t delta = message.minimum_size() - len;
+    const size_t overhead = kQuicTagSize + kCryptoEndOffsetSize;
+    if (delta > overhead) {
+      pad_length = delta - overhead;
+    }
+    len += overhead + pad_length;
+  }
+
+  if (num_entries > kMaxEntries) {
+    return nullptr;
+  }
+
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get(), quiche::HOST_BYTE_ORDER);
+  if (!writer.WriteTag(message.tag())) {
+    QUICHE_DCHECK(false) << "Failed to write message tag.";
+    return nullptr;
+  }
+  if (!writer.WriteUInt16(static_cast<uint16_t>(num_entries))) {
+    QUICHE_DCHECK(false) << "Failed to write size.";
+    return nullptr;
+  }
+  if (!writer.WriteUInt16(0)) {
+    QUICHE_DCHECK(false) << "Failed to write padding.";
+    return nullptr;
+  }
+
+  uint32_t end_offset = 0;
+  // Tags and offsets
+  for (auto it = message.tag_value_map().begin();
+       it != message.tag_value_map().end(); ++it) {
+    if (it->first == kPAD && need_pad_tag) {
+      // Existing PAD tags are only checked when padding needs to be added
+      // because parts of the code may need to reserialize received messages
+      // and those messages may, legitimately include padding.
+      QUICHE_DCHECK(false)
+          << "Message needed padding but already contained a PAD tag";
+      return nullptr;
+    }
+
+    if (it->first > kPAD && need_pad_tag) {
+      need_pad_tag = false;
+      if (!WritePadTag(&writer, pad_length, &end_offset)) {
+        return nullptr;
+      }
+    }
+
+    if (!writer.WriteTag(it->first)) {
+      QUICHE_DCHECK(false) << "Failed to write tag.";
+      return nullptr;
+    }
+    end_offset += it->second.length();
+    if (!writer.WriteUInt32(end_offset)) {
+      QUICHE_DCHECK(false) << "Failed to write end offset.";
+      return nullptr;
+    }
+  }
+
+  if (need_pad_tag) {
+    if (!WritePadTag(&writer, pad_length, &end_offset)) {
+      return nullptr;
+    }
+  }
+
+  // Values
+  for (auto it = message.tag_value_map().begin();
+       it != message.tag_value_map().end(); ++it) {
+    if (it->first > kPAD && need_pad_value) {
+      need_pad_value = false;
+      if (!writer.WriteRepeatedByte('-', pad_length)) {
+        QUICHE_DCHECK(false) << "Failed to write padding.";
+        return nullptr;
+      }
+    }
+
+    if (!writer.WriteBytes(it->second.data(), it->second.length())) {
+      QUICHE_DCHECK(false) << "Failed to write value.";
+      return nullptr;
+    }
+  }
+
+  if (need_pad_value) {
+    if (!writer.WriteRepeatedByte('-', pad_length)) {
+      QUICHE_DCHECK(false) << "Failed to write padding.";
+      return nullptr;
+    }
+  }
+
+  return std::make_unique<QuicData>(buffer.release(), len, true);
+}
+
+void CryptoFramer::Clear() {
+  message_.Clear();
+  tags_and_lengths_.clear();
+  error_ = QUIC_NO_ERROR;
+  error_detail_ = "";
+  state_ = STATE_READING_TAG;
+}
+
+QuicErrorCode CryptoFramer::Process(absl::string_view input) {
+  // Add this data to the buffer.
+  buffer_.append(input.data(), input.length());
+  QuicDataReader reader(buffer_.data(), buffer_.length(),
+                        quiche::HOST_BYTE_ORDER);
+
+  switch (state_) {
+    case STATE_READING_TAG:
+      if (reader.BytesRemaining() < kQuicTagSize) {
+        break;
+      }
+      QuicTag message_tag;
+      reader.ReadTag(&message_tag);
+      message_.set_tag(message_tag);
+      state_ = STATE_READING_NUM_ENTRIES;
+      ABSL_FALLTHROUGH_INTENDED;
+    case STATE_READING_NUM_ENTRIES:
+      if (reader.BytesRemaining() < kNumEntriesSize + sizeof(uint16_t)) {
+        break;
+      }
+      reader.ReadUInt16(&num_entries_);
+      if (num_entries_ > kMaxEntries) {
+        error_detail_ = absl::StrCat(num_entries_, " entries");
+        return QUIC_CRYPTO_TOO_MANY_ENTRIES;
+      }
+      uint16_t padding;
+      reader.ReadUInt16(&padding);
+
+      tags_and_lengths_.reserve(num_entries_);
+      state_ = STATE_READING_TAGS_AND_LENGTHS;
+      values_len_ = 0;
+      ABSL_FALLTHROUGH_INTENDED;
+    case STATE_READING_TAGS_AND_LENGTHS: {
+      if (reader.BytesRemaining() <
+          num_entries_ * (kQuicTagSize + kCryptoEndOffsetSize)) {
+        break;
+      }
+
+      uint32_t last_end_offset = 0;
+      for (unsigned i = 0; i < num_entries_; ++i) {
+        QuicTag tag;
+        reader.ReadTag(&tag);
+        if (i > 0 && tag <= tags_and_lengths_[i - 1].first) {
+          if (tag == tags_and_lengths_[i - 1].first) {
+            error_detail_ = absl::StrCat("Duplicate tag:", tag);
+            return QUIC_CRYPTO_DUPLICATE_TAG;
+          }
+          error_detail_ = absl::StrCat("Tag ", tag, " out of order");
+          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
+        }
+
+        uint32_t end_offset;
+        reader.ReadUInt32(&end_offset);
+
+        if (end_offset < last_end_offset) {
+          error_detail_ =
+              absl::StrCat("End offset: ", end_offset, " vs ", last_end_offset);
+          return QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
+        }
+        tags_and_lengths_.push_back(std::make_pair(
+            tag, static_cast<size_t>(end_offset - last_end_offset)));
+        last_end_offset = end_offset;
+      }
+      values_len_ = last_end_offset;
+      state_ = STATE_READING_VALUES;
+      ABSL_FALLTHROUGH_INTENDED;
+    }
+    case STATE_READING_VALUES:
+      if (reader.BytesRemaining() < values_len_) {
+        if (!process_truncated_messages_) {
+          break;
+        }
+        QUIC_LOG(ERROR) << "Trunacted message. Missing "
+                        << values_len_ - reader.BytesRemaining() << " bytes.";
+      }
+      for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
+        absl::string_view value;
+        if (!reader.ReadStringPiece(&value, item.second)) {
+          QUICHE_DCHECK(process_truncated_messages_);
+          // Store an empty value.
+          message_.SetStringPiece(item.first, "");
+          continue;
+        }
+        message_.SetStringPiece(item.first, value);
+      }
+      visitor_->OnHandshakeMessage(message_);
+      Clear();
+      state_ = STATE_READING_TAG;
+      break;
+  }
+  // Save any remaining data.
+  buffer_ = std::string(reader.PeekRemainingPayload());
+  return QUIC_NO_ERROR;
+}
+
+// static
+bool CryptoFramer::WritePadTag(QuicDataWriter* writer,
+                               size_t pad_length,
+                               uint32_t* end_offset) {
+  if (!writer->WriteTag(kPAD)) {
+    QUICHE_DCHECK(false) << "Failed to write tag.";
+    return false;
+  }
+  *end_offset += pad_length;
+  if (!writer->WriteUInt32(*end_offset)) {
+    QUICHE_DCHECK(false) << "Failed to write end offset.";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_framer.h b/quiche/quic/core/crypto/crypto_framer.h
new file mode 100644
index 0000000..919ec09
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_framer.h
@@ -0,0 +1,137 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_message_parser.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class CryptoFramer;
+class QuicData;
+class QuicDataWriter;
+
+class QUIC_EXPORT_PRIVATE CryptoFramerVisitorInterface {
+ public:
+  virtual ~CryptoFramerVisitorInterface() {}
+
+  // Called if an error is detected.
+  virtual void OnError(CryptoFramer* framer) = 0;
+
+  // Called when a complete handshake message has been parsed.
+  virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
+};
+
+// A class for framing the crypto messages that are exchanged in a QUIC
+// session.
+class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
+ public:
+  CryptoFramer();
+
+  ~CryptoFramer() override;
+
+  // ParseMessage parses exactly one message from the given
+  // absl::string_view. If there is an error, the message is truncated,
+  // or the message has trailing garbage then nullptr will be returned.
+  static std::unique_ptr<CryptoHandshakeMessage> ParseMessage(
+      absl::string_view in);
+
+  // Set callbacks to be called from the framer.  A visitor must be set, or
+  // else the framer will crash.  It is acceptable for the visitor to do
+  // nothing.  If this is called multiple times, only the last visitor
+  // will be used.  |visitor| will be owned by the framer.
+  void set_visitor(CryptoFramerVisitorInterface* visitor) {
+    visitor_ = visitor;
+  }
+
+  QuicErrorCode error() const override;
+  const std::string& error_detail() const override;
+
+  // Processes input data, which must be delivered in order. Returns
+  // false if there was an error, and true otherwise. ProcessInput optionally
+  // takes an EncryptionLevel, but it is ignored. The variant with the
+  // EncryptionLevel is provided to match the CryptoMessageParser interface.
+  bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
+  bool ProcessInput(absl::string_view input);
+
+  // Returns the number of bytes of buffered input data remaining to be
+  // parsed.
+  size_t InputBytesRemaining() const override;
+
+  // Checks if the specified tag has been seen. Returns |true| if it
+  // has, and |false| if it has not or a CHLO has not been seen.
+  bool HasTag(QuicTag tag) const;
+
+  // Even if the CHLO has not been fully received, force processing of
+  // the handshake message. This is dangerous and should not be used
+  // except as a mechanism of last resort.
+  void ForceHandshake();
+
+  // Returns a new QuicData owned by the caller that contains a serialized
+  // |message|, or nullptr if there was an error.
+  static std::unique_ptr<QuicData> ConstructHandshakeMessage(
+      const CryptoHandshakeMessage& message);
+
+  // Debug only method which permits processing truncated messages.
+  void set_process_truncated_messages(bool process_truncated_messages) {
+    process_truncated_messages_ = process_truncated_messages;
+  }
+
+ private:
+  // Clears per-message state.  Does not clear the visitor.
+  void Clear();
+
+  // Process does does the work of |ProcessInput|, but returns an error code,
+  // doesn't set error_ and doesn't call |visitor_->OnError()|.
+  QuicErrorCode Process(absl::string_view input);
+
+  static bool WritePadTag(QuicDataWriter* writer,
+                          size_t pad_length,
+                          uint32_t* end_offset);
+
+  // Represents the current state of the parsing state machine.
+  enum CryptoFramerState {
+    STATE_READING_TAG,
+    STATE_READING_NUM_ENTRIES,
+    STATE_READING_TAGS_AND_LENGTHS,
+    STATE_READING_VALUES
+  };
+
+  // Visitor to invoke when messages are parsed.
+  CryptoFramerVisitorInterface* visitor_;
+  // Last error.
+  QuicErrorCode error_;
+  // Remaining unparsed data.
+  std::string buffer_;
+  // Current state of the parsing.
+  CryptoFramerState state_;
+  // The message currently being parsed.
+  CryptoHandshakeMessage message_;
+  // The issue which caused |error_|
+  std::string error_detail_;
+  // Number of entires in the message currently being parsed.
+  uint16_t num_entries_;
+  // tags_and_lengths_ contains the tags that are currently being parsed and
+  // their lengths.
+  std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
+  // Cumulative length of all values in the message currently being parsed.
+  size_t values_len_;
+  // Set to true to allow of processing of truncated messages for debugging.
+  bool process_truncated_messages_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
diff --git a/quiche/quic/core/crypto/crypto_framer_test.cc b/quiche/quic/core/crypto/crypto_framer_test.cc
new file mode 100644
index 0000000..558d3e4
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_framer_test.cc
@@ -0,0 +1,466 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_framer.h"
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+char* AsChars(unsigned char* data) {
+  return reinterpret_cast<char*>(data);
+}
+
+class TestCryptoVisitor : public CryptoFramerVisitorInterface {
+ public:
+  TestCryptoVisitor() : error_count_(0) {}
+
+  void OnError(CryptoFramer* framer) override {
+    QUIC_DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
+    ++error_count_;
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    messages_.push_back(message);
+  }
+
+  // Counters from the visitor callbacks.
+  int error_count_;
+
+  std::vector<CryptoHandshakeMessage> messages_;
+};
+
+TEST(CryptoFramerTest, ConstructHandshakeMessage) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x12345678, "abcdef");
+  message.SetStringPiece(0x12345679, "ghijk");
+  message.SetStringPiece(0x1234567A, "lmnopqr");
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x03, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // tag 3
+      0x7A, 0x56, 0x34, 0x12,
+      // end offset 3
+      0x12, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+      // value 3
+      'l', 'm', 'n', 'o', 'p', 'q', 'r',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x12345678, "abcdef");
+  message.SetStringPiece(0x12345679, "ghijk");
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x12345678, "");
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x01, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x00, 0x00, 0x00, 0x00,
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) {
+    message.SetStringPiece(key, "abcdef");
+  }
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  EXPECT_TRUE(data == nullptr);
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(0x01020304, "test");
+  message.set_minimum_size(64);
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      'P', 'A', 'D', 0,
+      // end offset 1
+      0x24, 0x00, 0x00, 0x00,
+      // tag 2
+      0x04, 0x03, 0x02, 0x01,
+      // end offset 2
+      0x28, 0x00, 0x00, 0x00,
+      // 36 bytes of padding.
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-',
+      // value 2
+      't', 'e', 's', 't',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
+  CryptoHandshakeMessage message;
+  message.set_tag(0xFFAA7733);
+  message.SetStringPiece(1, "");
+  message.set_minimum_size(64);
+
+  unsigned char packet[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x01, 0x00, 0x00, 0x00,
+      // end offset 1
+      0x00, 0x00, 0x00, 0x00,
+      // tag 2
+      'P', 'A', 'D', 0,
+      // end offset 2
+      0x28, 0x00, 0x00, 0x00,
+      // 40 bytes of padding.
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
+  };
+
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST(CryptoFramerTest, ProcessInput) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+  };
+
+  EXPECT_TRUE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_EQ(0u, framer.InputBytesRemaining());
+  EXPECT_EQ(0, visitor.error_count_);
+  ASSERT_EQ(1u, visitor.messages_.size());
+  const CryptoHandshakeMessage& message = visitor.messages_[0];
+  EXPECT_EQ(0xFFAA7733, message.tag());
+  EXPECT_EQ(2u, message.tag_value_map().size());
+  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
+  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
+}
+
+TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x03, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // tag 3
+      0x7A, 0x56, 0x34, 0x12,
+      // end offset 3
+      0x12, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+      // value 3
+      'l', 'm', 'n', 'o', 'p', 'q', 'r',
+  };
+
+  EXPECT_TRUE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_EQ(0u, framer.InputBytesRemaining());
+  EXPECT_EQ(0, visitor.error_count_);
+  ASSERT_EQ(1u, visitor.messages_.size());
+  const CryptoHandshakeMessage& message = visitor.messages_[0];
+  EXPECT_EQ(0xFFAA7733, message.tag());
+  EXPECT_EQ(3u, message.tag_value_map().size());
+  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
+  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
+  EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A));
+}
+
+TEST(CryptoFramerTest, ProcessInputIncrementally) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x06, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x0b, 0x00, 0x00, 0x00,
+      // value 1
+      'a', 'b', 'c', 'd', 'e', 'f',
+      // value 2
+      'g', 'h', 'i', 'j', 'k',
+  };
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(input); i++) {
+    EXPECT_TRUE(framer.ProcessInput(absl::string_view(AsChars(input) + i, 1)));
+  }
+  EXPECT_EQ(0u, framer.InputBytesRemaining());
+  ASSERT_EQ(1u, visitor.messages_.size());
+  const CryptoHandshakeMessage& message = visitor.messages_[0];
+  EXPECT_EQ(0xFFAA7733, message.tag());
+  EXPECT_EQ(2u, message.tag_value_map().size());
+  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
+  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
+}
+
+TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x13,
+      // end offset 1
+      0x01, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x02, 0x00, 0x00, 0x00,
+  };
+
+  EXPECT_FALSE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x01, 0x00, 0x00, 0x00,
+      // tag 2
+      0x78, 0x56, 0x34, 0x13,
+      // end offset 2
+      0x00, 0x00, 0x00, 0x00,
+  };
+
+  EXPECT_FALSE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0xA0, 0x00,
+      // padding
+      0x00, 0x00,
+  };
+
+  EXPECT_FALSE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TOO_MANY_ENTRIES));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST(CryptoFramerTest, ProcessInputZeroLength) {
+  test::TestCryptoVisitor visitor;
+  CryptoFramer framer;
+  framer.set_visitor(&visitor);
+
+  unsigned char input[] = {
+      // tag
+      0x33, 0x77, 0xAA, 0xFF,
+      // num entries
+      0x02, 0x00,
+      // padding
+      0x00, 0x00,
+      // tag 1
+      0x78, 0x56, 0x34, 0x12,
+      // end offset 1
+      0x00, 0x00, 0x00, 0x00,
+      // tag 2
+      0x79, 0x56, 0x34, 0x12,
+      // end offset 2
+      0x05, 0x00, 0x00, 0x00,
+  };
+
+  EXPECT_TRUE(framer.ProcessInput(
+      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
+  EXPECT_EQ(0, visitor.error_count_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_handshake.cc b/quiche/quic/core/crypto/crypto_handshake.cc
new file mode 100644
index 0000000..bc17a97
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+
+namespace quic {
+
+QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
+    : key_exchange(0),
+      aead(0),
+      token_binding_key_param(0),
+      sct_supported_by_client(false) {}
+
+QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
+
+CrypterPair::CrypterPair() {}
+
+CrypterPair::~CrypterPair() {}
+
+// static
+const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion";
+
+// static
+const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block";
+
+// static
+const char QuicCryptoConfig::kForwardSecureLabel[] =
+    "QUIC forward secure key expansion";
+
+QuicCryptoConfig::QuicCryptoConfig() = default;
+
+QuicCryptoConfig::~QuicCryptoConfig() = default;
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_handshake.h b/quiche/quic/core/crypto/crypto_handshake.h
new file mode 100644
index 0000000..d44f65e
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake.h
@@ -0,0 +1,189 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class SynchronousKeyExchange;
+class QuicDecrypter;
+class QuicEncrypter;
+
+// HandshakeFailureReason enum values are uploaded to UMA, they cannot be
+// changed.
+enum HandshakeFailureReason {
+  HANDSHAKE_OK = 0,
+
+  // Failure reasons for an invalid client nonce in CHLO.
+  //
+  // The default error value for nonce verification failures from strike
+  // register (covers old strike registers and unknown failures).
+  CLIENT_NONCE_UNKNOWN_FAILURE = 1,
+  // Client nonce had incorrect length.
+  CLIENT_NONCE_INVALID_FAILURE = 2,
+  // Client nonce is not unique.
+  CLIENT_NONCE_NOT_UNIQUE_FAILURE = 3,
+  // Client orbit is invalid or incorrect.
+  CLIENT_NONCE_INVALID_ORBIT_FAILURE = 4,
+  // Client nonce's timestamp is not in the strike register's valid time range.
+  CLIENT_NONCE_INVALID_TIME_FAILURE = 5,
+  // Strike register's RPC call timed out, client nonce couldn't be verified.
+  CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT = 6,
+  // Strike register is down, client nonce couldn't be verified.
+  CLIENT_NONCE_STRIKE_REGISTER_FAILURE = 7,
+
+  // Failure reasons for an invalid server nonce in CHLO.
+  //
+  // Unbox of server nonce failed.
+  SERVER_NONCE_DECRYPTION_FAILURE = 8,
+  // Decrypted server nonce had incorrect length.
+  SERVER_NONCE_INVALID_FAILURE = 9,
+  // Server nonce is not unique.
+  SERVER_NONCE_NOT_UNIQUE_FAILURE = 10,
+  // Server nonce's timestamp is not in the strike register's valid time range.
+  SERVER_NONCE_INVALID_TIME_FAILURE = 11,
+  // The server requires handshake confirmation.
+  SERVER_NONCE_REQUIRED_FAILURE = 20,
+
+  // Failure reasons for an invalid server config in CHLO.
+  //
+  // Missing Server config id (kSCID) tag.
+  SERVER_CONFIG_INCHOATE_HELLO_FAILURE = 12,
+  // Couldn't find the Server config id (kSCID).
+  SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE = 13,
+
+  // Failure reasons for an invalid source-address token.
+  //
+  // Missing Source-address token (kSourceAddressTokenTag) tag.
+  SOURCE_ADDRESS_TOKEN_INVALID_FAILURE = 14,
+  // Unbox of Source-address token failed.
+  SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE = 15,
+  // Couldn't parse the unbox'ed Source-address token.
+  SOURCE_ADDRESS_TOKEN_PARSE_FAILURE = 16,
+  // Source-address token is for a different IP address.
+  SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE = 17,
+  // The source-address token has a timestamp in the future.
+  SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE = 18,
+  // The source-address token has expired.
+  SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE = 19,
+
+  // The expected leaf certificate hash could not be validated.
+  INVALID_EXPECTED_LEAF_CERTIFICATE = 21,
+
+  MAX_FAILURE_REASON = 22,
+};
+
+// These errors will be packed into an uint32_t and we don't want to set the
+// most significant bit, which may be misinterpreted as the sign bit.
+static_assert(MAX_FAILURE_REASON <= 32, "failure reason out of sync");
+
+// A CrypterPair contains the encrypter and decrypter for an encryption level.
+struct QUIC_EXPORT_PRIVATE CrypterPair {
+  CrypterPair();
+  CrypterPair(CrypterPair&&) = default;
+  ~CrypterPair();
+
+  std::unique_ptr<QuicEncrypter> encrypter;
+  std::unique_ptr<QuicDecrypter> decrypter;
+};
+
+// Parameters negotiated by the crypto handshake.
+struct QUIC_EXPORT_PRIVATE QuicCryptoNegotiatedParameters
+    : public quiche::QuicheReferenceCounted {
+  // Initializes the members to 0 or empty values.
+  QuicCryptoNegotiatedParameters();
+
+  QuicTag key_exchange;
+  QuicTag aead;
+  std::string initial_premaster_secret;
+  std::string forward_secure_premaster_secret;
+  // initial_subkey_secret is used as the PRK input to the HKDF used when
+  // performing key extraction that needs to happen before forward-secure keys
+  // are available.
+  std::string initial_subkey_secret;
+  // subkey_secret is used as the PRK input to the HKDF used for key extraction.
+  std::string subkey_secret;
+  CrypterPair initial_crypters;
+  CrypterPair forward_secure_crypters;
+  // Normalized SNI: converted to lower case and trailing '.' removed.
+  std::string sni;
+  std::string client_nonce;
+  std::string server_nonce;
+  // hkdf_input_suffix contains the HKDF input following the label: the
+  // ConnectionId, client hello and server config. This is only populated in the
+  // client because only the client needs to derive the forward secure keys at a
+  // later time from the initial keys.
+  std::string hkdf_input_suffix;
+  // cached_certs contains the cached certificates that a client used when
+  // sending a client hello.
+  std::vector<std::string> cached_certs;
+  // client_key_exchange is used by clients to store the ephemeral KeyExchange
+  // for the connection.
+  std::unique_ptr<SynchronousKeyExchange> client_key_exchange;
+  // channel_id is set by servers to a ChannelID key when the client correctly
+  // proves possession of the corresponding private key. It consists of 32
+  // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
+  // are big-endian and the pair is a P-256 public key.
+  std::string channel_id;
+  QuicTag token_binding_key_param;
+
+  // Used when generating proof signature when sending server config updates.
+
+  // Used to generate cert chain when sending server config updates.
+  std::string client_cached_cert_hashes;
+
+  // Default to false; set to true if the client indicates that it supports sct
+  // by sending CSCT tag with an empty value in client hello.
+  bool sct_supported_by_client;
+
+  // Parameters only populated for TLS handshakes. These will be 0 for
+  // connections not using TLS, or if the TLS handshake is not finished yet.
+  uint16_t cipher_suite = 0;
+  uint16_t key_exchange_group = 0;
+  uint16_t peer_signature_algorithm = 0;
+
+ protected:
+  ~QuicCryptoNegotiatedParameters() override;
+};
+
+// QuicCryptoConfig contains common configuration between clients and servers.
+class QUIC_EXPORT_PRIVATE QuicCryptoConfig {
+ public:
+  // kInitialLabel is a constant that is used when deriving the initial
+  // (non-forward secure) keys for the connection in order to tie the resulting
+  // key to this protocol.
+  static const char kInitialLabel[];
+
+  // kCETVLabel is a constant that is used when deriving the keys for the
+  // encrypted tag/value block in the client hello.
+  static const char kCETVLabel[];
+
+  // kForwardSecureLabel is a constant that is used when deriving the forward
+  // secure keys for the connection in order to tie the resulting key to this
+  // protocol.
+  static const char kForwardSecureLabel[];
+
+  QuicCryptoConfig();
+  QuicCryptoConfig(const QuicCryptoConfig&) = delete;
+  QuicCryptoConfig& operator=(const QuicCryptoConfig&) = delete;
+  ~QuicCryptoConfig();
+
+  // Key exchange methods. The following two members' values correspond by
+  // index.
+  QuicTagVector kexs;
+  // Authenticated encryption with associated data (AEAD) algorithms.
+  QuicTagVector aead;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_H_
diff --git a/quiche/quic/core/crypto/crypto_handshake_message.cc b/quiche/quic/core/crypto/crypto_handshake_message.cc
new file mode 100644
index 0000000..474036e
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake_message.cc
@@ -0,0 +1,382 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0), minimum_size_(0) {}
+
+CryptoHandshakeMessage::CryptoHandshakeMessage(
+    const CryptoHandshakeMessage& other)
+    : tag_(other.tag_),
+      tag_value_map_(other.tag_value_map_),
+      minimum_size_(other.minimum_size_) {
+  // Don't copy serialized_. unique_ptr doesn't have a copy constructor.
+  // The new object can lazily reconstruct serialized_.
+}
+
+CryptoHandshakeMessage::CryptoHandshakeMessage(CryptoHandshakeMessage&& other) =
+    default;
+
+CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
+
+CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
+    const CryptoHandshakeMessage& other) {
+  tag_ = other.tag_;
+  tag_value_map_ = other.tag_value_map_;
+  // Don't copy serialized_. unique_ptr doesn't have an assignment operator.
+  // However, invalidate serialized_.
+  serialized_.reset();
+  minimum_size_ = other.minimum_size_;
+  return *this;
+}
+
+CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
+    CryptoHandshakeMessage&& other) = default;
+
+bool CryptoHandshakeMessage::operator==(
+    const CryptoHandshakeMessage& rhs) const {
+  return tag_ == rhs.tag_ && tag_value_map_ == rhs.tag_value_map_ &&
+         minimum_size_ == rhs.minimum_size_;
+}
+
+bool CryptoHandshakeMessage::operator!=(
+    const CryptoHandshakeMessage& rhs) const {
+  return !(*this == rhs);
+}
+
+void CryptoHandshakeMessage::Clear() {
+  tag_ = 0;
+  tag_value_map_.clear();
+  minimum_size_ = 0;
+  serialized_.reset();
+}
+
+const QuicData& CryptoHandshakeMessage::GetSerialized() const {
+  if (!serialized_) {
+    serialized_ = CryptoFramer::ConstructHandshakeMessage(*this);
+  }
+  return *serialized_;
+}
+
+void CryptoHandshakeMessage::MarkDirty() {
+  serialized_.reset();
+}
+
+void CryptoHandshakeMessage::SetVersionVector(
+    QuicTag tag,
+    ParsedQuicVersionVector versions) {
+  QuicVersionLabelVector version_labels;
+  for (const ParsedQuicVersion& version : versions) {
+    version_labels.push_back(
+        quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
+  }
+  SetVector(tag, version_labels);
+}
+
+void CryptoHandshakeMessage::SetVersion(QuicTag tag,
+                                        ParsedQuicVersion version) {
+  SetValue(tag,
+           quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version)));
+}
+
+void CryptoHandshakeMessage::SetStringPiece(QuicTag tag,
+                                            absl::string_view value) {
+  tag_value_map_[tag] = std::string(value);
+}
+
+void CryptoHandshakeMessage::Erase(QuicTag tag) {
+  tag_value_map_.erase(tag);
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetTaglist(
+    QuicTag tag,
+    QuicTagVector* out_tags) const {
+  auto it = tag_value_map_.find(tag);
+  QuicErrorCode ret = QUIC_NO_ERROR;
+
+  if (it == tag_value_map_.end()) {
+    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  } else if (it->second.size() % sizeof(QuicTag) != 0) {
+    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  if (ret != QUIC_NO_ERROR) {
+    out_tags->clear();
+    return ret;
+  }
+
+  size_t num_tags = it->second.size() / sizeof(QuicTag);
+  out_tags->resize(num_tags);
+  for (size_t i = 0; i < num_tags; ++i) {
+    QuicTag tag;
+    memcpy(&tag, it->second.data() + i * sizeof(tag), sizeof(tag));
+    (*out_tags)[i] = tag;
+  }
+  return ret;
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList(
+    QuicTag tag,
+    QuicVersionLabelVector* out) const {
+  QuicErrorCode error = GetTaglist(tag, out);
+  if (error != QUIC_NO_ERROR) {
+    return error;
+  }
+
+  for (size_t i = 0; i < out->size(); ++i) {
+    (*out)[i] = quiche::QuicheEndian::HostToNet32((*out)[i]);
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetVersionLabel(
+    QuicTag tag,
+    QuicVersionLabel* out) const {
+  QuicErrorCode error = GetUint32(tag, out);
+  if (error != QUIC_NO_ERROR) {
+    return error;
+  }
+
+  *out = quiche::QuicheEndian::HostToNet32(*out);
+  return QUIC_NO_ERROR;
+}
+
+bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag,
+                                            absl::string_view* out) const {
+  auto it = tag_value_map_.find(tag);
+  if (it == tag_value_map_.end()) {
+    return false;
+  }
+  *out = it->second;
+  return true;
+}
+
+bool CryptoHandshakeMessage::HasStringPiece(QuicTag tag) const {
+  return tag_value_map_.find(tag) != tag_value_map_.end();
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetNthValue24(
+    QuicTag tag,
+    unsigned index,
+    absl::string_view* out) const {
+  absl::string_view value;
+  if (!GetStringPiece(tag, &value)) {
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+
+  for (unsigned i = 0;; i++) {
+    if (value.empty()) {
+      return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND;
+    }
+    if (value.size() < 3) {
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    const unsigned char* data =
+        reinterpret_cast<const unsigned char*>(value.data());
+    size_t size = static_cast<size_t>(data[0]) |
+                  (static_cast<size_t>(data[1]) << 8) |
+                  (static_cast<size_t>(data[2]) << 16);
+    value.remove_prefix(3);
+
+    if (value.size() < size) {
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    if (i == index) {
+      *out = absl::string_view(value.data(), size);
+      return QUIC_NO_ERROR;
+    }
+
+    value.remove_prefix(size);
+  }
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
+                                                uint32_t* out) const {
+  return GetPOD(tag, out, sizeof(uint32_t));
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
+                                                uint64_t* out) const {
+  return GetPOD(tag, out, sizeof(uint64_t));
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetStatelessResetToken(
+    QuicTag tag,
+    StatelessResetToken* out) const {
+  return GetPOD(tag, out, kStatelessResetTokenLength);
+}
+
+size_t CryptoHandshakeMessage::size() const {
+  size_t ret = sizeof(QuicTag) + sizeof(uint16_t) /* number of entries */ +
+               sizeof(uint16_t) /* padding */;
+  ret += (sizeof(QuicTag) + sizeof(uint32_t) /* end offset */) *
+         tag_value_map_.size();
+  for (auto i = tag_value_map_.begin(); i != tag_value_map_.end(); ++i) {
+    ret += i->second.size();
+  }
+
+  return ret;
+}
+
+void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
+  if (min_bytes == minimum_size_) {
+    return;
+  }
+  serialized_.reset();
+  minimum_size_ = min_bytes;
+}
+
+size_t CryptoHandshakeMessage::minimum_size() const {
+  return minimum_size_;
+}
+
+std::string CryptoHandshakeMessage::DebugString() const {
+  return DebugStringInternal(0);
+}
+
+QuicErrorCode CryptoHandshakeMessage::GetPOD(QuicTag tag,
+                                             void* out,
+                                             size_t len) const {
+  auto it = tag_value_map_.find(tag);
+  QuicErrorCode ret = QUIC_NO_ERROR;
+
+  if (it == tag_value_map_.end()) {
+    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  } else if (it->second.size() != len) {
+    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  if (ret != QUIC_NO_ERROR) {
+    memset(out, 0, len);
+    return ret;
+  }
+
+  memcpy(out, it->second.data(), len);
+  return ret;
+}
+
+std::string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
+  std::string ret =
+      std::string(2 * indent, ' ') + QuicTagToString(tag_) + "<\n";
+  ++indent;
+  for (auto it = tag_value_map_.begin(); it != tag_value_map_.end(); ++it) {
+    ret += std::string(2 * indent, ' ') + QuicTagToString(it->first) + ": ";
+
+    bool done = false;
+    switch (it->first) {
+      case kICSL:
+      case kCFCW:
+      case kSFCW:
+      case kIRTT:
+      case kMIUS:
+      case kMIBS:
+      case kTCID:
+      case kMAD:
+        // uint32_t value
+        if (it->second.size() == 4) {
+          uint32_t value;
+          memcpy(&value, it->second.data(), sizeof(value));
+          absl::StrAppend(&ret, value);
+          done = true;
+        }
+        break;
+      case kKEXS:
+      case kAEAD:
+      case kCOPT:
+      case kPDMD:
+      case kVER:
+        // tag lists
+        if (it->second.size() % sizeof(QuicTag) == 0) {
+          for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) {
+            QuicTag tag;
+            memcpy(&tag, it->second.data() + j, sizeof(tag));
+            if (j > 0) {
+              ret += ",";
+            }
+            ret += "'" + QuicTagToString(tag) + "'";
+          }
+          done = true;
+        }
+        break;
+      case kRREJ:
+        // uint32_t lists
+        if (it->second.size() % sizeof(uint32_t) == 0) {
+          for (size_t j = 0; j < it->second.size(); j += sizeof(uint32_t)) {
+            uint32_t value;
+            memcpy(&value, it->second.data() + j, sizeof(value));
+            if (j > 0) {
+              ret += ",";
+            }
+            ret += CryptoUtils::HandshakeFailureReasonToString(
+                static_cast<HandshakeFailureReason>(value));
+          }
+          done = true;
+        }
+        break;
+      case kCADR:
+        // IP address and port
+        if (!it->second.empty()) {
+          QuicSocketAddressCoder decoder;
+          if (decoder.Decode(it->second.data(), it->second.size())) {
+            ret += QuicSocketAddress(decoder.ip(), decoder.port()).ToString();
+            done = true;
+          }
+        }
+        break;
+      case kSCFG:
+        // nested messages.
+        if (!it->second.empty()) {
+          std::unique_ptr<CryptoHandshakeMessage> msg(
+              CryptoFramer::ParseMessage(it->second));
+          if (msg) {
+            ret += "\n";
+            ret += msg->DebugStringInternal(indent + 1);
+
+            done = true;
+          }
+        }
+        break;
+      case kPAD:
+        ret += absl::StrFormat("(%d bytes of padding)", it->second.size());
+        done = true;
+        break;
+      case kSNI:
+      case kUAID:
+        ret += "\"" + it->second + "\"";
+        done = true;
+        break;
+    }
+
+    if (!done) {
+      // If there's no specific format for this tag, or the value is invalid,
+      // then just use hex.
+      ret += "0x" + absl::BytesToHexString(it->second);
+    }
+    ret += "\n";
+  }
+  --indent;
+  ret += std::string(2 * indent, ' ') + ">";
+  return ret;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_handshake_message.h b/quiche/quic/core/crypto/crypto_handshake_message.h
new file mode 100644
index 0000000..4785fa8
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake_message.h
@@ -0,0 +1,160 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An intermediate format of a handshake message that's convenient for a
+// CryptoFramer to serialize from or parse into.
+class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage {
+ public:
+  CryptoHandshakeMessage();
+  CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
+  CryptoHandshakeMessage(CryptoHandshakeMessage&& other);
+  ~CryptoHandshakeMessage();
+
+  CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other);
+  CryptoHandshakeMessage& operator=(CryptoHandshakeMessage&& other);
+
+  bool operator==(const CryptoHandshakeMessage& rhs) const;
+  bool operator!=(const CryptoHandshakeMessage& rhs) const;
+
+  // Clears state.
+  void Clear();
+
+  // GetSerialized returns the serialized form of this message and caches the
+  // result. Subsequently altering the message does not invalidate the cache.
+  const QuicData& GetSerialized() const;
+
+  // MarkDirty invalidates the cache created by |GetSerialized|.
+  void MarkDirty();
+
+  // SetValue sets an element with the given tag to the raw, memory contents of
+  // |v|.
+  template <class T>
+  void SetValue(QuicTag tag, const T& v) {
+    tag_value_map_[tag] =
+        std::string(reinterpret_cast<const char*>(&v), sizeof(v));
+  }
+
+  // SetVector sets an element with the given tag to the raw contents of an
+  // array of elements in |v|.
+  template <class T>
+  void SetVector(QuicTag tag, const std::vector<T>& v) {
+    if (v.empty()) {
+      tag_value_map_[tag] = std::string();
+    } else {
+      tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]),
+                                        v.size() * sizeof(T));
+    }
+  }
+
+  // Sets an element with the given tag to the on-the-wire representation of
+  // |version|.
+  void SetVersion(QuicTag tag, ParsedQuicVersion version);
+
+  // Sets an element with the given tag to the on-the-wire representation of
+  // the elements in |versions|.
+  void SetVersionVector(QuicTag tag, ParsedQuicVersionVector versions);
+
+  // Returns the message tag.
+  QuicTag tag() const { return tag_; }
+  // Sets the message tag.
+  void set_tag(QuicTag tag) { tag_ = tag; }
+
+  const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
+
+  void SetStringPiece(QuicTag tag, absl::string_view value);
+
+  // Erase removes a tag/value, if present, from the message.
+  void Erase(QuicTag tag);
+
+  // GetTaglist finds an element with the given tag containing zero or more
+  // tags. If such a tag doesn't exist, it returns an error code. Otherwise it
+  // populates |out_tags| with the tags and returns QUIC_NO_ERROR.
+  QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const;
+
+  // GetVersionLabelList finds an element with the given tag containing zero or
+  // more version labels. If such a tag doesn't exist, it returns an error code.
+  // Otherwise it populates |out| with the labels and returns QUIC_NO_ERROR.
+  QuicErrorCode GetVersionLabelList(QuicTag tag,
+                                    QuicVersionLabelVector* out) const;
+
+  // GetVersionLabel finds an element with the given tag containing a single
+  // version label. If such a tag doesn't exist, it returns an error code.
+  // Otherwise it populates |out| with the label and returns QUIC_NO_ERROR.
+  QuicErrorCode GetVersionLabel(QuicTag tag, QuicVersionLabel* out) const;
+
+  bool GetStringPiece(QuicTag tag, absl::string_view* out) const;
+  bool HasStringPiece(QuicTag tag) const;
+
+  // GetNthValue24 interprets the value with the given tag to be a series of
+  // 24-bit, length prefixed values and it returns the subvalue with the given
+  // index.
+  QuicErrorCode GetNthValue24(QuicTag tag,
+                              unsigned index,
+                              absl::string_view* out) const;
+  QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
+  QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
+
+  QuicErrorCode GetStatelessResetToken(QuicTag tag,
+                                       StatelessResetToken* out) const;
+
+  // size returns 4 (message tag) + 2 (uint16_t, number of entries) +
+  // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
+  size_t size() const;
+
+  // set_minimum_size sets the minimum number of bytes that the message should
+  // consume. The CryptoFramer will add a PAD tag as needed when serializing in
+  // order to ensure this. Setting a value of 0 disables padding.
+  //
+  // Padding is useful in order to ensure that messages are a minimum size. A
+  // QUIC server can require a minimum size in order to reduce the
+  // amplification factor of any mirror DoS attack.
+  void set_minimum_size(size_t min_bytes);
+
+  size_t minimum_size() const;
+
+  // DebugString returns a multi-line, string representation of the message
+  // suitable for including in debug output.
+  std::string DebugString() const;
+
+ private:
+  // GetPOD is a utility function for extracting a plain-old-data value. If
+  // |tag| exists in the message, and has a value of exactly |len| bytes then
+  // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
+  // are zeroed out.
+  //
+  // If used to copy integers then this assumes that the machine is
+  // little-endian.
+  QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
+
+  std::string DebugStringInternal(size_t indent) const;
+
+  QuicTag tag_;
+  QuicTagValueMap tag_value_map_;
+
+  size_t minimum_size_;
+
+  // The serialized form of the handshake message. This member is constructed
+  // lazily.
+  mutable std::unique_ptr<QuicData> serialized_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
diff --git a/quiche/quic/core/crypto/crypto_handshake_message_test.cc b/quiche/quic/core/crypto/crypto_handshake_message_test.cc
new file mode 100644
index 0000000..bdc051c
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_handshake_message_test.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(CryptoHandshakeMessageTest, DebugString) {
+  const char* str = "SHLO<\n>";
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kSHLO);
+  EXPECT_EQ(str, message.DebugString());
+
+  // Test copy
+  CryptoHandshakeMessage message2(message);
+  EXPECT_EQ(str, message2.DebugString());
+
+  // Test move
+  CryptoHandshakeMessage message3(std::move(message));
+  EXPECT_EQ(str, message3.DebugString());
+
+  // Test assign
+  CryptoHandshakeMessage message4 = message3;
+  EXPECT_EQ(str, message4.DebugString());
+
+  // Test move-assign
+  CryptoHandshakeMessage message5 = std::move(message3);
+  EXPECT_EQ(str, message5.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, DebugStringWithUintVector) {
+  const char* str =
+      "REJ <\n  RREJ: "
+      "SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,"
+      "CLIENT_NONCE_NOT_UNIQUE_FAILURE\n>";
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kREJ);
+  std::vector<uint32_t> reasons = {
+      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+      CLIENT_NONCE_NOT_UNIQUE_FAILURE};
+  message.SetVector(kRREJ, reasons);
+  EXPECT_EQ(str, message.DebugString());
+
+  // Test copy
+  CryptoHandshakeMessage message2(message);
+  EXPECT_EQ(str, message2.DebugString());
+
+  // Test move
+  CryptoHandshakeMessage message3(std::move(message));
+  EXPECT_EQ(str, message3.DebugString());
+
+  // Test assign
+  CryptoHandshakeMessage message4 = message3;
+  EXPECT_EQ(str, message4.DebugString());
+
+  // Test move-assign
+  CryptoHandshakeMessage message5 = std::move(message3);
+  EXPECT_EQ(str, message5.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, DebugStringWithTagVector) {
+  const char* str = "CHLO<\n  COPT: 'TBBR','PAD ','BYTE'\n>";
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kCHLO);
+  message.SetVector(kCOPT, QuicTagVector{kTBBR, kPAD, kBYTE});
+  EXPECT_EQ(str, message.DebugString());
+
+  // Test copy
+  CryptoHandshakeMessage message2(message);
+  EXPECT_EQ(str, message2.DebugString());
+
+  // Test move
+  CryptoHandshakeMessage message3(std::move(message));
+  EXPECT_EQ(str, message3.DebugString());
+
+  // Test assign
+  CryptoHandshakeMessage message4 = message3;
+  EXPECT_EQ(str, message4.DebugString());
+
+  // Test move-assign
+  CryptoHandshakeMessage message5 = std::move(message3);
+  EXPECT_EQ(str, message5.DebugString());
+}
+
+TEST(CryptoHandshakeMessageTest, HasStringPiece) {
+  CryptoHandshakeMessage message;
+  EXPECT_FALSE(message.HasStringPiece(kALPN));
+  message.SetStringPiece(kALPN, "foo");
+  EXPECT_TRUE(message.HasStringPiece(kALPN));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_message_parser.h b/quiche/quic/core/crypto/crypto_message_parser.h
new file mode 100644
index 0000000..f819209
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_message_parser.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE CryptoMessageParser {
+ public:
+  virtual ~CryptoMessageParser() {}
+
+  virtual QuicErrorCode error() const = 0;
+  virtual const std::string& error_detail() const = 0;
+
+  // Processes input data, which must be delivered in order. The input data
+  // being processed was received at encryption level |level|. Returns
+  // false if there was an error, and true otherwise.
+  virtual bool ProcessInput(absl::string_view input, EncryptionLevel level) = 0;
+
+  // Returns the number of bytes of buffered input data remaining to be
+  // parsed.
+  virtual size_t InputBytesRemaining() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_MESSAGE_PARSER_H_
diff --git a/quiche/quic/core/crypto/crypto_message_printer_bin.cc b/quiche/quic/core/crypto/crypto_message_printer_bin.cc
new file mode 100644
index 0000000..eb7393d
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_message_printer_bin.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Dumps the contents of a QUIC crypto handshake message in a human readable
+// format.
+//
+// Usage: crypto_message_printer_bin <hex of message>
+
+#include <iostream>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+namespace quic {
+
+class CryptoMessagePrinter : public ::quic::CryptoFramerVisitorInterface {
+ public:
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    cout << message.DebugString() << endl;
+  }
+
+  void OnError(CryptoFramer* framer) override {
+    cerr << "Error code: " << framer->error() << endl;
+    cerr << "Error details: " << framer->error_detail() << endl;
+  }
+};
+
+}  // namespace quic
+
+int main(int argc, char* argv[]) {
+  const char* usage = "Usage: crypto_message_printer <hex>";
+  std::vector<std::string> messages =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (messages.size() != 1) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    exit(0);
+  }
+
+  quic::CryptoMessagePrinter printer;
+  quic::CryptoFramer framer;
+  framer.set_visitor(&printer);
+  framer.set_process_truncated_messages(true);
+  std::string input = absl::HexStringToBytes(messages[0]);
+  if (!framer.ProcessInput(input)) {
+    return 1;
+  }
+  if (framer.InputBytesRemaining() != 0) {
+    cerr << "Input partially consumed. " << framer.InputBytesRemaining()
+         << " bytes remaining." << endl;
+    return 2;
+  }
+  return 0;
+}
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h
new file mode 100644
index 0000000..ab21cb5
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -0,0 +1,512 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
+
+#include <cstddef>
+#include <string>
+
+#include "quiche/quic/core/quic_tag.h"
+
+// Version and Crypto tags are written to the wire with a big-endian
+// representation of the name of the tag.  For example
+// the client hello tag (CHLO) will be written as the
+// following 4 bytes: 'C' 'H' 'L' 'O'.  Since it is
+// stored in memory as a little endian uint32_t, we need
+// to reverse the order of the bytes.
+//
+// We use a macro to ensure that no static initialisers are created. Use the
+// MakeQuicTag function in normal code.
+#define TAG(a, b, c, d) \
+  static_cast<QuicTag>((d << 24) + (c << 16) + (b << 8) + a)
+
+namespace quic {
+
+using ServerConfigID = std::string;
+
+// The following tags have been deprecated and should not be reused:
+// "1CON", "BBQ4", "NCON", "RCID", "SREJ", "TBKP", "TB10", "SCLS", "SMHL",
+// "QNZR", "B2HI", "H2PR", "FIFO", "LIFO", "RRWS", "QNSP", "B2CL", "CHSP",
+// "BPTE", "ACKD", "AKD2", "AKD4", "MAD1", "MAD4", "MAD5", "ACD0", "ACKQ",
+// "TLPR", "CCS\0"
+
+// clang-format off
+const QuicTag kCHLO = TAG('C', 'H', 'L', 'O');   // Client hello
+const QuicTag kSHLO = TAG('S', 'H', 'L', 'O');   // Server hello
+const QuicTag kSCFG = TAG('S', 'C', 'F', 'G');   // Server config
+const QuicTag kREJ  = TAG('R', 'E', 'J', '\0');  // Reject
+const QuicTag kCETV = TAG('C', 'E', 'T', 'V');   // Client encrypted tag-value
+                                                 // pairs
+const QuicTag kPRST = TAG('P', 'R', 'S', 'T');   // Public reset
+const QuicTag kSCUP = TAG('S', 'C', 'U', 'P');   // Server config update
+const QuicTag kALPN = TAG('A', 'L', 'P', 'N');   // Application-layer protocol
+
+// Key exchange methods
+const QuicTag kP256 = TAG('P', '2', '5', '6');   // ECDH, Curve P-256
+const QuicTag kC255 = TAG('C', '2', '5', '5');   // ECDH, Curve25519
+
+// AEAD algorithms
+const QuicTag kAESG = TAG('A', 'E', 'S', 'G');   // AES128 + GCM-12
+const QuicTag kCC20 = TAG('C', 'C', '2', '0');   // ChaCha20 + Poly1305 RFC7539
+
+// Congestion control feedback types
+const QuicTag kQBIC = TAG('Q', 'B', 'I', 'C');   // TCP cubic
+
+// Connection options (COPT) values
+const QuicTag kAFCW = TAG('A', 'F', 'C', 'W');   // Auto-tune flow control
+                                                 // receive windows.
+const QuicTag kIFW5 = TAG('I', 'F', 'W', '5');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 32KB. (2^5 KB).
+const QuicTag kIFW6 = TAG('I', 'F', 'W', '6');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 64KB. (2^6 KB).
+const QuicTag kIFW7 = TAG('I', 'F', 'W', '7');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 128KB. (2^7 KB).
+const QuicTag kIFW8 = TAG('I', 'F', 'W', '8');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 256KB. (2^8 KB).
+const QuicTag kIFW9 = TAG('I', 'F', 'W', '9');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 512KB. (2^9 KB).
+const QuicTag kIFWA = TAG('I', 'F', 'W', 'a');   // Set initial size
+                                                 // of stream flow control
+                                                 // receive window to
+                                                 // 1MB. (2^0xa KB).
+const QuicTag kTBBR = TAG('T', 'B', 'B', 'R');   // Reduced Buffer Bloat TCP
+const QuicTag k1RTT = TAG('1', 'R', 'T', 'T');   // STARTUP in BBR for 1 RTT
+const QuicTag k2RTT = TAG('2', 'R', 'T', 'T');   // STARTUP in BBR for 2 RTTs
+const QuicTag kLRTT = TAG('L', 'R', 'T', 'T');   // Exit STARTUP in BBR on loss
+const QuicTag kBBS1 = TAG('B', 'B', 'S', '1');   // DEPRECATED
+const QuicTag kBBS2 = TAG('B', 'B', 'S', '2');   // More aggressive packet
+                                                 // conservation in BBR STARTUP
+const QuicTag kBBS3 = TAG('B', 'B', 'S', '3');   // Slowstart packet
+                                                 // conservation in BBR STARTUP
+const QuicTag kBBS4 = TAG('B', 'B', 'S', '4');   // DEPRECATED
+const QuicTag kBBS5 = TAG('B', 'B', 'S', '5');   // DEPRECATED
+const QuicTag kBBRR = TAG('B', 'B', 'R', 'R');   // Rate-based recovery in BBR
+const QuicTag kBBR1 = TAG('B', 'B', 'R', '1');   // DEPRECATED
+const QuicTag kBBR2 = TAG('B', 'B', 'R', '2');   // DEPRECATED
+const QuicTag kBBR3 = TAG('B', 'B', 'R', '3');   // Fully drain the queue once
+                                                 // per cycle
+const QuicTag kBBR4 = TAG('B', 'B', 'R', '4');   // 20 RTT ack aggregation
+const QuicTag kBBR5 = TAG('B', 'B', 'R', '5');   // 40 RTT ack aggregation
+const QuicTag kBBR9 = TAG('B', 'B', 'R', '9');   // DEPRECATED
+const QuicTag kBBRA = TAG('B', 'B', 'R', 'A');   // Starts a new ack aggregation
+                                                 // epoch if a full round has
+                                                 // passed
+const QuicTag kBBRB = TAG('B', 'B', 'R', 'B');   // Use send rate in BBR's
+                                                 // MaxAckHeightTracker
+const QuicTag kBBRS = TAG('B', 'B', 'R', 'S');   // DEPRECATED
+const QuicTag kBBQ1 = TAG('B', 'B', 'Q', '1');   // BBR with lower 2.77 STARTUP
+                                                 // pacing and CWND gain.
+const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2');   // BBRv2 with 2.885 STARTUP and
+                                                 // DRAIN CWND gain.
+const QuicTag kBBQ3 = TAG('B', 'B', 'Q', '3');   // BBR with ack aggregation
+                                                 // compensation in STARTUP.
+const QuicTag kBBQ5 = TAG('B', 'B', 'Q', '5');   // Expire ack aggregation upon
+                                                 // bandwidth increase in
+                                                 // STARTUP.
+const QuicTag kBBQ6 = TAG('B', 'B', 'Q', '6');   // Reduce STARTUP gain to 25%
+                                                 // more than BW increase.
+const QuicTag kBBQ7 = TAG('B', 'B', 'Q', '7');   // Reduce bw_lo by
+                                                 // bytes_lost/min_rtt.
+const QuicTag kBBQ8 = TAG('B', 'B', 'Q', '8');   // Reduce bw_lo by
+                                                 // bw_lo * bytes_lost/inflight
+const QuicTag kBBQ9 = TAG('B', 'B', 'Q', '9');   // Reduce bw_lo by
+                                                 // bw_lo * bytes_lost/cwnd
+const QuicTag kBBQ0 = TAG('B', 'B', 'Q', '0');   // Increase bytes_acked in
+                                                 // PROBE_UP when app limited.
+const QuicTag kRENO = TAG('R', 'E', 'N', 'O');   // Reno Congestion Control
+const QuicTag kTPCC = TAG('P', 'C', 'C', '\0');  // Performance-Oriented
+                                                 // Congestion Control
+const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E');   // TCP cubic or reno in bytes
+const QuicTag kIW03 = TAG('I', 'W', '0', '3');   // Force ICWND to 3
+const QuicTag kIW10 = TAG('I', 'W', '1', '0');   // Force ICWND to 10
+const QuicTag kIW20 = TAG('I', 'W', '2', '0');   // Force ICWND to 20
+const QuicTag kIW50 = TAG('I', 'W', '5', '0');   // Force ICWND to 50
+const QuicTag kB2ON = TAG('B', '2', 'O', 'N');   // Enable BBRv2
+const QuicTag kB2NA = TAG('B', '2', 'N', 'A');   // For BBRv2, do not add ack
+                                                 // height to queueing threshold
+const QuicTag kB2NE = TAG('B', '2', 'N', 'E');   // For BBRv2, always exit
+                                                 // STARTUP on loss, even if
+                                                 // bandwidth growth exceeds
+                                                 // threshold.
+const QuicTag kB2RP = TAG('B', '2', 'R', 'P');   // For BBRv2, run PROBE_RTT on
+                                                 // the regular schedule
+const QuicTag kB2LO = TAG('B', '2', 'L', 'O');   // Ignore inflight_lo in BBR2
+const QuicTag kB2HR = TAG('B', '2', 'H', 'R');   // 15% inflight_hi headroom.
+const QuicTag kB2SL = TAG('B', '2', 'S', 'L');   // When exiting STARTUP due to
+                                                 // loss, set inflight_hi to the
+                                                 // max of bdp and max bytes
+                                                 // delivered in round.
+const QuicTag kB2H2 = TAG('B', '2', 'H', '2');   // When exiting PROBE_UP due to
+                                                 // loss, set inflight_hi to the
+                                                 // max of inflight@send and max
+                                                 // bytes delivered in round.
+const QuicTag kB2RC = TAG('B', '2', 'R', 'C');   // Disable Reno-coexistence for
+                                                 // BBR2.
+const QuicTag kBSAO = TAG('B', 'S', 'A', 'O');   // Avoid Overestimation in
+                                                 // Bandwidth Sampler with ack
+                                                 // aggregation
+const QuicTag kB2DL = TAG('B', '2', 'D', 'L');   // Increase inflight_hi based
+                                                 // on delievered, not inflight.
+const QuicTag kB201 = TAG('B', '2', '0', '1');   // In PROBE_UP, check if cwnd
+                                                 // limited before aggregation
+                                                 // epoch, instead of ack event.
+const QuicTag kB202 = TAG('B', '2', '0', '2');   // Do not exit PROBE_UP if
+                                                 // inflight dips below 1.25*BW.
+const QuicTag kB203 = TAG('B', '2', '0', '3');   // Ignore inflight_hi until
+                                                 // PROBE_UP is exited.
+const QuicTag kB204 = TAG('B', '2', '0', '4');   // Reduce extra acked when
+                                                 // MaxBW incrases.
+const QuicTag kB205 = TAG('B', '2', '0', '5');   // Add extra acked to CWND in
+                                                 // STARTUP.
+const QuicTag kB206 = TAG('B', '2', '0', '6');   // Exit STARTUP after 2 losses.
+const QuicTag kB207 = TAG('B', '2', '0', '7');   // Exit STARTUP on persistent
+                                                 // queue
+const QuicTag kNTLP = TAG('N', 'T', 'L', 'P');   // No tail loss probe
+const QuicTag k1TLP = TAG('1', 'T', 'L', 'P');   // 1 tail loss probe
+const QuicTag k1RTO = TAG('1', 'R', 'T', 'O');   // Send 1 packet upon RTO
+const QuicTag kNRTO = TAG('N', 'R', 'T', 'O');   // CWND reduction on loss
+const QuicTag kTIME = TAG('T', 'I', 'M', 'E');   // Time based loss detection
+const QuicTag kATIM = TAG('A', 'T', 'I', 'M');   // Adaptive time loss detection
+const QuicTag kMIN1 = TAG('M', 'I', 'N', '1');   // Min CWND of 1 packet
+const QuicTag kMIN4 = TAG('M', 'I', 'N', '4');   // Min CWND of 4 packets,
+                                                 // with a min rate of 1 BDP.
+const QuicTag kMAD0 = TAG('M', 'A', 'D', '0');   // Ignore ack delay
+const QuicTag kMAD2 = TAG('M', 'A', 'D', '2');   // No min TLP
+const QuicTag kMAD3 = TAG('M', 'A', 'D', '3');   // No min RTO
+const QuicTag k1ACK = TAG('1', 'A', 'C', 'K');   // 1 fast ack for reordering
+const QuicTag kAKD3 = TAG('A', 'K', 'D', '3');   // Ack decimation style acking
+                                                 // with 1/8 RTT acks.
+const QuicTag kAKDU = TAG('A', 'K', 'D', 'U');   // Unlimited number of packets
+                                                 // received before acking
+const QuicTag kAFFE = TAG('A', 'F', 'F', 'E');   // Enable client receiving
+                                                 // AckFrequencyFrame.
+const QuicTag kAFF1 = TAG('A', 'F', 'F', '1');   // Use SRTT in building
+                                                 // AckFrequencyFrame.
+const QuicTag kAFF2 = TAG('A', 'F', 'F', '2');   // Send AckFrequencyFrame upon
+                                                 // handshake completion.
+const QuicTag kSSLR = TAG('S', 'S', 'L', 'R');   // Slow Start Large Reduction.
+const QuicTag kNPRR = TAG('N', 'P', 'R', 'R');   // Pace at unity instead of PRR
+const QuicTag k2RTO = TAG('2', 'R', 'T', 'O');   // Close connection on 2 RTOs
+const QuicTag k3RTO = TAG('3', 'R', 'T', 'O');   // Close connection on 3 RTOs
+const QuicTag k4RTO = TAG('4', 'R', 'T', 'O');   // Close connection on 4 RTOs
+const QuicTag k5RTO = TAG('5', 'R', 'T', 'O');   // Close connection on 5 RTOs
+const QuicTag k6RTO = TAG('6', 'R', 'T', 'O');   // Close connection on 6 RTOs
+const QuicTag kCBHD = TAG('C', 'B', 'H', 'D');   // Client only blackhole
+                                                 // detection.
+const QuicTag kNBHD = TAG('N', 'B', 'H', 'D');   // No blackhole detection.
+const QuicTag kCONH = TAG('C', 'O', 'N', 'H');   // Conservative Handshake
+                                                 // Retransmissions.
+const QuicTag kLFAK = TAG('L', 'F', 'A', 'K');   // Don't invoke FACK on the
+                                                 // first ack.
+const QuicTag kSTMP = TAG('S', 'T', 'M', 'P');   // DEPRECATED
+const QuicTag kEACK = TAG('E', 'A', 'C', 'K');   // Bundle ack-eliciting frame
+                                                 // with an ACK after PTO/RTO
+
+const QuicTag kILD0 = TAG('I', 'L', 'D', '0');   // IETF style loss detection
+                                                 // (default with 1/8 RTT time
+                                                 // threshold)
+const QuicTag kILD1 = TAG('I', 'L', 'D', '1');   // IETF style loss detection
+                                                 // with 1/4 RTT time threshold
+const QuicTag kILD2 = TAG('I', 'L', 'D', '2');   // IETF style loss detection
+                                                 // with adaptive packet
+                                                 // threshold
+const QuicTag kILD3 = TAG('I', 'L', 'D', '3');   // IETF style loss detection
+                                                 // with 1/4 RTT time threshold
+                                                 // and adaptive packet
+                                                 // threshold
+const QuicTag kILD4 = TAG('I', 'L', 'D', '4');   // IETF style loss detection
+                                                 // with both adaptive time
+                                                 // threshold (default 1/4 RTT)
+                                                 // and adaptive packet
+                                                 // threshold
+const QuicTag kRUNT = TAG('R', 'U', 'N', 'T');   // No packet threshold loss
+                                                 // detection for "runt" packet.
+const QuicTag kNSTP = TAG('N', 'S', 'T', 'P');   // No stop waiting frames.
+const QuicTag kNRTT = TAG('N', 'R', 'T', 'T');   // Ignore initial RTT
+
+const QuicTag k1PTO = TAG('1', 'P', 'T', 'O');   // Send 1 packet upon PTO.
+const QuicTag k2PTO = TAG('2', 'P', 'T', 'O');   // Send 2 packets upon PTO.
+
+const QuicTag k6PTO = TAG('6', 'P', 'T', 'O');   // Closes connection on 6
+                                                 // consecutive PTOs.
+const QuicTag k7PTO = TAG('7', 'P', 'T', 'O');   // Closes connection on 7
+                                                 // consecutive PTOs.
+const QuicTag k8PTO = TAG('8', 'P', 'T', 'O');   // Closes connection on 8
+                                                 // consecutive PTOs.
+const QuicTag kPTOS = TAG('P', 'T', 'O', 'S');   // Skip packet number before
+                                                 // sending the last PTO.
+const QuicTag kPTOA = TAG('P', 'T', 'O', 'A');   // Do not add max ack delay
+                                                 // when computing PTO timeout
+                                                 // if an immediate ACK is
+                                                 // expected.
+const QuicTag kPEB1 = TAG('P', 'E', 'B', '1');   // Start exponential backoff
+                                                 // since 1st PTO.
+const QuicTag kPEB2 = TAG('P', 'E', 'B', '2');   // Start exponential backoff
+                                                 // since 2nd PTO.
+const QuicTag kPVS1 = TAG('P', 'V', 'S', '1');   // Use 2 * rttvar when
+                                                 // calculating PTO timeout.
+const QuicTag kPAG1 = TAG('P', 'A', 'G', '1');   // Make 1st PTO more aggressive
+const QuicTag kPAG2 = TAG('P', 'A', 'G', '2');   // Make first 2 PTOs more
+                                                 // aggressive
+const QuicTag kPSDA = TAG('P', 'S', 'D', 'A');   // Use standard deviation when
+                                                 // calculating PTO timeout.
+const QuicTag kPLE1 = TAG('P', 'L', 'E', '1');   // Arm the 1st PTO with
+                                                 // earliest in flight sent time
+                                                 // and at least 0.5*srtt from
+                                                 // last sent packet.
+const QuicTag kPLE2 = TAG('P', 'L', 'E', '2');   // Arm the 1st PTO with
+                                                 // earliest in flight sent time
+                                                 // and at least 1.5*srtt from
+                                                 // last sent packet.
+const QuicTag kAPTO = TAG('A', 'P', 'T', 'O');   // Use 1.5 * initial RTT before
+                                                 // any RTT sample is available.
+
+const QuicTag kELDT = TAG('E', 'L', 'D', 'T');   // Enable Loss Detection Tuning
+
+// TODO(haoyuewang) Remove RVCM option once
+// --quic_remove_connection_migration_connection_option is deprecated.
+const QuicTag kRVCM = TAG('R', 'V', 'C', 'M');   // Validate the new address
+                                                 // upon client address change.
+
+// Optional support of truncated Connection IDs.  If sent by a peer, the value
+// is the minimum number of bytes allowed for the connection ID sent to the
+// peer.
+const QuicTag kTCID = TAG('T', 'C', 'I', 'D');   // Connection ID truncation.
+
+// Multipath option.
+const QuicTag kMPTH = TAG('M', 'P', 'T', 'H');   // Enable multipath.
+
+const QuicTag kNCMR = TAG('N', 'C', 'M', 'R');   // Do not attempt connection
+                                                 // migration.
+
+// Allows disabling defer_send_in_response_to_packets in QuicConnection.
+const QuicTag kDFER = TAG('D', 'F', 'E', 'R');   // Do not defer sending.
+
+// Disable Pacing offload option.
+const QuicTag kNPCO = TAG('N', 'P', 'C', 'O');    // No pacing offload.
+
+// Enable bandwidth resumption experiment.
+const QuicTag kBWRE = TAG('B', 'W', 'R', 'E');  // Bandwidth resumption.
+const QuicTag kBWMX = TAG('B', 'W', 'M', 'X');  // Max bandwidth resumption.
+const QuicTag kBWRS = TAG('B', 'W', 'R', 'S');  // Server bandwidth resumption.
+const QuicTag kBWS2 = TAG('B', 'W', 'S', '2');  // Server bw resumption v2.
+const QuicTag kBWS3 = TAG('B', 'W', 'S', '3');  // QUIC Initial CWND - Control.
+const QuicTag kBWS4 = TAG('B', 'W', 'S', '4');  // QUIC Initial CWND - Enabled.
+const QuicTag kBWS5 = TAG('B', 'W', 'S', '5');  // QUIC Initial CWND up and down
+const QuicTag kBWS6 = TAG('B', 'W', 'S', '6');  // QUIC Initial CWND - Enabled
+                                                // with 0.5 * default
+                                                // multiplier.
+const QuicTag kBWP0 = TAG('B', 'W', 'P', '0');  // QUIC Initial CWND - SPDY
+                                                // priority 0.
+const QuicTag kBWP1 = TAG('B', 'W', 'P', '1');  // QUIC Initial CWND - SPDY
+                                                // priorities 0 and 1.
+const QuicTag kBWP2 = TAG('B', 'W', 'P', '2');  // QUIC Initial CWND - SPDY
+                                                // priorities 0, 1 and 2.
+const QuicTag kBWP3 = TAG('B', 'W', 'P', '3');  // QUIC Initial CWND - SPDY
+                                                // priorities 0, 1, 2 and 3.
+const QuicTag kBWP4 = TAG('B', 'W', 'P', '4');  // QUIC Initial CWND - SPDY
+                                                // priorities >= 0, 1, 2, 3 and
+                                                // 4.
+const QuicTag kBWG4 = TAG('B', 'W', 'G', '4');  // QUIC Initial CWND -
+                                                // Bandwidth model 1.
+const QuicTag kBWG7 = TAG('B', 'W', 'G', '7');  // QUIC Initial CWND -
+                                                // Bandwidth model 2.
+const QuicTag kBWG8 = TAG('B', 'W', 'G', '8');  // QUIC Initial CWND -
+                                                // Bandwidth model 3.
+const QuicTag kBWS7 = TAG('B', 'W', 'S', '7');  // QUIC Initial CWND - Enabled
+                                                // with 0.75 * default
+                                                // multiplier.
+const QuicTag kBWM3 = TAG('B', 'W', 'M', '3');  // Consider overshooting if
+                                                // bytes lost after bandwidth
+                                                // resumption * 3 > IW.
+const QuicTag kBWM4 = TAG('B', 'W', 'M', '4');  // Consider overshooting if
+                                                // bytes lost after bandwidth
+                                                // resumption * 4 > IW.
+const QuicTag kICW1 = TAG('I', 'C', 'W', '1');  // Max initial congestion window
+                                                // 100.
+const QuicTag kDTOS = TAG('D', 'T', 'O', 'S');  // Enable overshooting
+                                                // detection.
+
+const QuicTag kFIDT = TAG('F', 'I', 'D', 'T');  // Extend idle timer by PTO
+                                                // instead of the whole idle
+                                                // timeout.
+
+const QuicTag k3AFF = TAG('3', 'A', 'F', 'F');  // 3 anti amplification factor.
+const QuicTag k10AF = TAG('1', '0', 'A', 'F');  // 10 anti amplification factor.
+
+// Enable path MTU discovery experiment.
+const QuicTag kMTUH = TAG('M', 'T', 'U', 'H');  // High-target MTU discovery.
+const QuicTag kMTUL = TAG('M', 'T', 'U', 'L');  // Low-target MTU discovery.
+
+const QuicTag kNSLC = TAG('N', 'S', 'L', 'C');  // Always send connection close
+                                                // for idle timeout.
+const QuicTag kNCHP = TAG('N', 'C', 'H', 'P');  // No chaos protection.
+const QuicTag kNBPE = TAG('N', 'B', 'P', 'E');  // No BoringSSL Permutes
+                                                // TLS Extensions.
+
+// Proof types (i.e. certificate types)
+// NOTE: although it would be silly to do so, specifying both kX509 and kX59R
+// is allowed and is equivalent to specifying only kX509.
+const QuicTag kX509 = TAG('X', '5', '0', '9');   // X.509 certificate, all key
+                                                 // types
+const QuicTag kX59R = TAG('X', '5', '9', 'R');   // X.509 certificate, RSA keys
+                                                 // only
+const QuicTag kCHID = TAG('C', 'H', 'I', 'D');   // Channel ID.
+
+// Client hello tags
+const QuicTag kVER  = TAG('V', 'E', 'R', '\0');  // Version
+const QuicTag kNONC = TAG('N', 'O', 'N', 'C');   // The client's nonce
+const QuicTag kNONP = TAG('N', 'O', 'N', 'P');   // The client's proof nonce
+const QuicTag kKEXS = TAG('K', 'E', 'X', 'S');   // Key exchange methods
+const QuicTag kAEAD = TAG('A', 'E', 'A', 'D');   // Authenticated
+                                                 // encryption algorithms
+const QuicTag kCOPT = TAG('C', 'O', 'P', 'T');   // Connection options
+const QuicTag kCLOP = TAG('C', 'L', 'O', 'P');   // Client connection options
+const QuicTag kICSL = TAG('I', 'C', 'S', 'L');   // Idle network timeout
+const QuicTag kMIBS = TAG('M', 'I', 'D', 'S');   // Max incoming bidi streams
+const QuicTag kMIUS = TAG('M', 'I', 'U', 'S');   // Max incoming unidi streams
+const QuicTag kADE  = TAG('A', 'D', 'E', 0);     // Ack Delay Exponent (IETF
+                                                 // QUIC ACK Frame Only).
+const QuicTag kIRTT = TAG('I', 'R', 'T', 'T');   // Estimated initial RTT in us.
+const QuicTag kTRTT = TAG('T', 'R', 'T', 'T');   // If server receives an rtt
+                                                 // from an address token, set
+                                                 // it as the initial rtt.
+const QuicTag kSNI  = TAG('S', 'N', 'I', '\0');  // Server name
+                                                 // indication
+const QuicTag kPUBS = TAG('P', 'U', 'B', 'S');   // Public key values
+const QuicTag kSCID = TAG('S', 'C', 'I', 'D');   // Server config id
+const QuicTag kORBT = TAG('O', 'B', 'I', 'T');   // Server orbit.
+const QuicTag kPDMD = TAG('P', 'D', 'M', 'D');   // Proof demand.
+const QuicTag kPROF = TAG('P', 'R', 'O', 'F');   // Proof (signature).
+const QuicTag kCCRT = TAG('C', 'C', 'R', 'T');   // Cached certificate
+const QuicTag kEXPY = TAG('E', 'X', 'P', 'Y');   // Expiry
+const QuicTag kSTTL = TAG('S', 'T', 'T', 'L');   // Server Config TTL
+const QuicTag kSFCW = TAG('S', 'F', 'C', 'W');   // Initial stream flow control
+                                                 // receive window.
+const QuicTag kCFCW = TAG('C', 'F', 'C', 'W');   // Initial session/connection
+                                                 // flow control receive window.
+const QuicTag kUAID = TAG('U', 'A', 'I', 'D');   // Client's User Agent ID.
+const QuicTag kXLCT = TAG('X', 'L', 'C', 'T');   // Expected leaf certificate.
+const QuicTag kQLVE = TAG('Q', 'L', 'V', 'E');   // Legacy Version
+                                                 // Encapsulation.
+
+const QuicTag kPDP1 = TAG('P', 'D', 'P', '1');   // Path degrading triggered
+                                                 // at 1PTO.
+
+const QuicTag kPDP2 = TAG('P', 'D', 'P', '2');   // Path degrading triggered
+                                                 // at 2PTO.
+
+const QuicTag kPDP3 = TAG('P', 'D', 'P', '3');   // Path degrading triggered
+                                                 // at 3PTO.
+
+const QuicTag kPDP4 = TAG('P', 'D', 'P', '4');   // Path degrading triggered
+                                                 // at 4PTO.
+
+const QuicTag kPDP5 = TAG('P', 'D', 'P', '5');   // Path degrading triggered
+                                                 // at 5PTO.
+
+const QuicTag kQNZ2 = TAG('Q', 'N', 'Z', '2');   // Turn off QUIC crypto 0-RTT.
+
+const QuicTag kMAD  = TAG('M', 'A', 'D', 0);     // Max Ack Delay (IETF QUIC)
+
+const QuicTag kIGNP = TAG('I', 'G', 'N', 'P');   // Do not use PING only packet
+                                                 // for RTT measure or
+                                                 // congestion control.
+
+const QuicTag kSRWP = TAG('S', 'R', 'W', 'P');   // Enable retransmittable on
+                                                 // wire PING (ROWP) on the
+                                                 // server side.
+const QuicTag kGSR0 = TAG('G', 'S', 'R', '0');   // Selective Resumption
+
+const QuicTag kINVC = TAG('I', 'N', 'V', 'C');   // Send connection close for
+                                                 // INVALID_VERSION
+
+// Client Hints triggers.
+const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
+const QuicTag kYTCH = TAG('Y', 'T', 'C', 'H');
+const QuicTag kACH0 = TAG('A', 'C', 'H', '0');
+
+// Rejection tags
+const QuicTag kRREJ = TAG('R', 'R', 'E', 'J');   // Reasons for server sending
+
+// Server hello tags
+const QuicTag kCADR = TAG('C', 'A', 'D', 'R');   // Client IP address and port
+const QuicTag kASAD = TAG('A', 'S', 'A', 'D');   // Alternate Server IP address
+                                                 // and port.
+const QuicTag kSRST = TAG('S', 'R', 'S', 'T');   // Stateless reset token used
+                                                 // in IETF public reset packet
+
+// CETV tags
+const QuicTag kCIDK = TAG('C', 'I', 'D', 'K');   // ChannelID key
+const QuicTag kCIDS = TAG('C', 'I', 'D', 'S');   // ChannelID signature
+
+// Public reset tags
+const QuicTag kRNON = TAG('R', 'N', 'O', 'N');   // Public reset nonce proof
+const QuicTag kRSEQ = TAG('R', 'S', 'E', 'Q');   // Rejected packet number
+
+// Universal tags
+const QuicTag kPAD  = TAG('P', 'A', 'D', '\0');  // Padding
+
+// Stats collection tags
+const QuicTag kEPID = TAG('E', 'P', 'I', 'D');  // Endpoint identifier.
+
+// clang-format on
+
+// These tags have a special form so that they appear either at the beginning
+// or the end of a handshake message. Since handshake messages are sorted by
+// tag value, the tags with 0 at the end will sort first and those with 255 at
+// the end will sort last.
+//
+// The certificate chain should have a tag that will cause it to be sorted at
+// the end of any handshake messages because it's likely to be large and the
+// client might be able to get everything that it needs from the small values at
+// the beginning.
+//
+// Likewise tags with random values should be towards the beginning of the
+// message because the server mightn't hold state for a rejected client hello
+// and therefore the client may have issues reassembling the rejection message
+// in the event that it sent two client hellos.
+const QuicTag kServerNonceTag = TAG('S', 'N', 'O', 0);  // The server's nonce
+const QuicTag kSourceAddressTokenTag =
+    TAG('S', 'T', 'K', 0);  // Source-address token
+const QuicTag kCertificateTag = TAG('C', 'R', 'T', 255);  // Certificate chain
+const QuicTag kCertificateSCTTag =
+    TAG('C', 'S', 'C', 'T');  // Signed cert timestamp (RFC6962) of leaf cert.
+
+#undef TAG
+
+const size_t kMaxEntries = 128;  // Max number of entries in a message.
+
+const size_t kNonceSize = 32;  // Size in bytes of the connection nonce.
+
+const size_t kOrbitSize = 8;  // Number of bytes in an orbit value.
+
+// kProofSignatureLabel is prepended to the CHLO hash and server configs before
+// signing to avoid any cross-protocol attacks on the signature.
+const char kProofSignatureLabel[] = "QUIC CHLO and server config signature";
+
+// kClientHelloMinimumSize is the minimum size of a client hello. Client hellos
+// will have PAD tags added in order to ensure this minimum is met and client
+// hellos smaller than this will be an error. This minimum size reduces the
+// amplification factor of any mirror DoS attack.
+//
+// A client may pad an inchoate client hello to a size larger than
+// kClientHelloMinimumSize to make it more likely to receive a complete
+// rejection message.
+const size_t kClientHelloMinimumSize = 1024;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_PROTOCOL_H_
diff --git a/quiche/quic/core/crypto/crypto_secret_boxer.cc b/quiche/quic/core/crypto/crypto_secret_boxer.cc
new file mode 100644
index 0000000..f61a3fc
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_secret_boxer.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// kSIVNonceSize contains the number of bytes of nonce in each AES-GCM-SIV box.
+// AES-GCM-SIV takes a 12-byte nonce and, since the messages are so small, each
+// key is good for more than 2^64 source-address tokens. See table 1 of
+// https://eprint.iacr.org/2017/168.pdf
+static const size_t kSIVNonceSize = 12;
+
+// AES-GCM-SIV comes in AES-128 and AES-256 flavours. The AES-256 version is
+// used here so that the key size matches the 256-bit XSalsa20 keys that we
+// used to use.
+static const size_t kBoxKeySize = 32;
+
+struct CryptoSecretBoxer::State {
+  // ctxs are the initialised AEAD contexts. These objects contain the
+  // scheduled AES state for each of the keys.
+  std::vector<bssl::UniquePtr<EVP_AEAD_CTX>> ctxs;
+};
+
+CryptoSecretBoxer::CryptoSecretBoxer() {}
+
+CryptoSecretBoxer::~CryptoSecretBoxer() {}
+
+// static
+size_t CryptoSecretBoxer::GetKeySize() {
+  return kBoxKeySize;
+}
+
+// kAEAD is the AEAD used for boxing: AES-256-GCM-SIV.
+static const EVP_AEAD* (*const kAEAD)() = EVP_aead_aes_256_gcm_siv;
+
+bool CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) {
+  if (keys.empty()) {
+    QUIC_LOG(DFATAL) << "No keys supplied!";
+    return false;
+  }
+  const EVP_AEAD* const aead = kAEAD();
+  std::unique_ptr<State> new_state(new State);
+
+  for (const std::string& key : keys) {
+    QUICHE_DCHECK_EQ(kBoxKeySize, key.size());
+    bssl::UniquePtr<EVP_AEAD_CTX> ctx(
+        EVP_AEAD_CTX_new(aead, reinterpret_cast<const uint8_t*>(key.data()),
+                         key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH));
+    if (!ctx) {
+      ERR_clear_error();
+      QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_init failed";
+      return false;
+    }
+
+    new_state->ctxs.push_back(std::move(ctx));
+  }
+
+  QuicWriterMutexLock l(&lock_);
+  state_ = std::move(new_state);
+  return true;
+}
+
+std::string CryptoSecretBoxer::Box(QuicRandom* rand,
+                                   absl::string_view plaintext) const {
+  // The box is formatted as:
+  //   12 bytes of random nonce
+  //   n bytes of ciphertext
+  //   16 bytes of authenticator
+  size_t out_len =
+      kSIVNonceSize + plaintext.size() + EVP_AEAD_max_overhead(kAEAD());
+
+  std::string ret;
+  ret.resize(out_len);
+  uint8_t* out = reinterpret_cast<uint8_t*>(const_cast<char*>(ret.data()));
+
+  // Write kSIVNonceSize bytes of random nonce to the beginning of the output
+  // buffer.
+  rand->RandBytes(out, kSIVNonceSize);
+  const uint8_t* const nonce = out;
+  out += kSIVNonceSize;
+  out_len -= kSIVNonceSize;
+
+  size_t bytes_written;
+  {
+    QuicReaderMutexLock l(&lock_);
+    if (!EVP_AEAD_CTX_seal(state_->ctxs[0].get(), out, &bytes_written, out_len,
+                           nonce, kSIVNonceSize,
+                           reinterpret_cast<const uint8_t*>(plaintext.data()),
+                           plaintext.size(), nullptr, 0)) {
+      ERR_clear_error();
+      QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_seal failed";
+      return "";
+    }
+  }
+
+  QUICHE_DCHECK_EQ(out_len, bytes_written);
+  return ret;
+}
+
+bool CryptoSecretBoxer::Unbox(absl::string_view in_ciphertext,
+                              std::string* out_storage,
+                              absl::string_view* out) const {
+  if (in_ciphertext.size() < kSIVNonceSize) {
+    return false;
+  }
+
+  const uint8_t* const nonce =
+      reinterpret_cast<const uint8_t*>(in_ciphertext.data());
+  const uint8_t* const ciphertext = nonce + kSIVNonceSize;
+  const size_t ciphertext_len = in_ciphertext.size() - kSIVNonceSize;
+
+  out_storage->resize(ciphertext_len);
+
+  bool ok = false;
+  {
+    QuicReaderMutexLock l(&lock_);
+    for (const bssl::UniquePtr<EVP_AEAD_CTX>& ctx : state_->ctxs) {
+      size_t bytes_written;
+      if (EVP_AEAD_CTX_open(ctx.get(),
+                            reinterpret_cast<uint8_t*>(
+                                const_cast<char*>(out_storage->data())),
+                            &bytes_written, ciphertext_len, nonce,
+                            kSIVNonceSize, ciphertext, ciphertext_len, nullptr,
+                            0)) {
+        ok = true;
+        *out = absl::string_view(out_storage->data(), bytes_written);
+        break;
+      }
+
+      ERR_clear_error();
+    }
+  }
+
+  return ok;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_secret_boxer.h b/quiche/quic/core/crypto/crypto_secret_boxer.h
new file mode 100644
index 0000000..3010e14
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_secret_boxer.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// CryptoSecretBoxer encrypts small chunks of plaintext (called 'boxing') and
+// then, later, can authenticate+decrypt the resulting boxes. This object is
+// thread-safe.
+class QUIC_EXPORT_PRIVATE CryptoSecretBoxer {
+ public:
+  CryptoSecretBoxer();
+  CryptoSecretBoxer(const CryptoSecretBoxer&) = delete;
+  CryptoSecretBoxer& operator=(const CryptoSecretBoxer&) = delete;
+  ~CryptoSecretBoxer();
+
+  // GetKeySize returns the number of bytes in a key.
+  static size_t GetKeySize();
+
+  // SetKeys sets a list of encryption keys. The first key in the list will be
+  // used by |Box|, but all supplied keys will be tried by |Unbox|, to handle
+  // key skew across the fleet. This must be called before |Box| or |Unbox|.
+  // Keys must be |GetKeySize()| bytes long. No change is made if any key is
+  // invalid, or if there are no keys supplied.
+  bool SetKeys(const std::vector<std::string>& keys);
+
+  // Box encrypts |plaintext| using a random nonce generated from |rand| and
+  // returns the resulting ciphertext. Since an authenticator and nonce are
+  // included, the result will be slightly larger than |plaintext|. The first
+  // key in the vector supplied to |SetKeys| will be used. |SetKeys| must be
+  // called before calling this method.
+  std::string Box(QuicRandom* rand, absl::string_view plaintext) const;
+
+  // Unbox takes the result of a previous call to |Box| in |ciphertext| and
+  // authenticates+decrypts it. If |ciphertext| cannot be decrypted with any of
+  // the supplied keys, the function returns false. Otherwise, |out_storage| is
+  // used to store the result and |out| is set to point into |out_storage| and
+  // contains the original plaintext.
+  bool Unbox(absl::string_view ciphertext,
+             std::string* out_storage,
+             absl::string_view* out) const;
+
+ private:
+  struct State;
+
+  mutable QuicMutex lock_;
+
+  // state_ is an opaque pointer to whatever additional state the concrete
+  // implementation of CryptoSecretBoxer requires.
+  std::unique_ptr<State> state_ QUIC_GUARDED_BY(lock_);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_SECRET_BOXER_H_
diff --git a/quiche/quic/core/crypto/crypto_secret_boxer_test.cc b/quiche/quic/core/crypto/crypto_secret_boxer_test.cc
new file mode 100644
index 0000000..2c499fc
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_secret_boxer_test.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class CryptoSecretBoxerTest : public QuicTest {};
+
+TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) {
+  absl::string_view message("hello world");
+
+  CryptoSecretBoxer boxer;
+  boxer.SetKeys({std::string(CryptoSecretBoxer::GetKeySize(), 0x11)});
+
+  const std::string box = boxer.Box(QuicRandom::GetInstance(), message);
+
+  std::string storage;
+  absl::string_view result;
+  EXPECT_TRUE(boxer.Unbox(box, &storage, &result));
+  EXPECT_EQ(result, message);
+
+  EXPECT_FALSE(boxer.Unbox(std::string(1, 'X') + box, &storage, &result));
+  EXPECT_FALSE(
+      boxer.Unbox(box.substr(1, std::string::npos), &storage, &result));
+  EXPECT_FALSE(boxer.Unbox(std::string(), &storage, &result));
+  EXPECT_FALSE(boxer.Unbox(
+      std::string(1, box[0] ^ 0x80) + box.substr(1, std::string::npos),
+      &storage, &result));
+}
+
+// Helper function to test whether one boxer can decode the output of another.
+static bool CanDecode(const CryptoSecretBoxer& decoder,
+                      const CryptoSecretBoxer& encoder) {
+  absl::string_view message("hello world");
+  const std::string boxed = encoder.Box(QuicRandom::GetInstance(), message);
+  std::string storage;
+  absl::string_view result;
+  bool ok = decoder.Unbox(boxed, &storage, &result);
+  if (ok) {
+    EXPECT_EQ(result, message);
+  }
+  return ok;
+}
+
+TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
+  std::string key_11(CryptoSecretBoxer::GetKeySize(), 0x11);
+  std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12);
+
+  CryptoSecretBoxer boxer_11, boxer_12, boxer;
+  EXPECT_TRUE(boxer_11.SetKeys({key_11}));
+  EXPECT_TRUE(boxer_12.SetKeys({key_12}));
+  EXPECT_TRUE(boxer.SetKeys({key_12, key_11}));
+
+  // Neither single-key boxer can decode the other's tokens.
+  EXPECT_FALSE(CanDecode(boxer_11, boxer_12));
+  EXPECT_FALSE(CanDecode(boxer_12, boxer_11));
+
+  // |boxer| encodes with the first key, which is key_12.
+  EXPECT_TRUE(CanDecode(boxer_12, boxer));
+  EXPECT_FALSE(CanDecode(boxer_11, boxer));
+
+  // The boxer with both keys can decode tokens from either single-key boxer.
+  EXPECT_TRUE(CanDecode(boxer, boxer_11));
+  EXPECT_TRUE(CanDecode(boxer, boxer_12));
+
+  // After we flush key_11 from |boxer|, it can no longer decode tokens from
+  // |boxer_11|.
+  EXPECT_TRUE(boxer.SetKeys({key_12}));
+  EXPECT_FALSE(CanDecode(boxer, boxer_11));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_server_test.cc b/quiche/quic/core/crypto/crypto_server_test.cc
new file mode 100644
index 0000000..3dcf18a
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_server_test.cc
@@ -0,0 +1,1128 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/failing_proof_source.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+class DummyProofVerifierCallback : public ProofVerifierCallback {
+ public:
+  DummyProofVerifierCallback() {}
+  ~DummyProofVerifierCallback() override {}
+
+  void Run(bool /*ok*/,
+           const std::string& /*error_details*/,
+           std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
+    QUICHE_DCHECK(false);
+  }
+};
+
+const char kOldConfigId[] = "old-config-id";
+
+}  // namespace
+
+struct TestParams {
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "  versions: "
+       << ParsedQuicVersionVectorToString(p.supported_versions) << " }";
+    return os;
+  }
+
+  // Versions supported by client and server.
+  ParsedQuicVersionVector supported_versions;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  std::string rv = ParsedQuicVersionVectorToString(p.supported_versions);
+  std::replace(rv.begin(), rv.end(), ',', '_');
+  return rv;
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+
+  // Start with all versions, remove highest on each iteration.
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  while (!supported_versions.empty()) {
+    params.push_back({supported_versions});
+    supported_versions.erase(supported_versions.begin());
+  }
+
+  return params;
+}
+
+class CryptoServerTest : public QuicTestWithParam<TestParams> {
+ public:
+  CryptoServerTest()
+      : rand_(QuicRandom::GetInstance()),
+        client_address_(QuicIpAddress::Loopback4(), 1234),
+        client_version_(UnsupportedQuicVersion()),
+        config_(QuicCryptoServerConfig::TESTING,
+                rand_,
+                crypto_test_utils::ProofSourceForTesting(),
+                KeyExchangeSource::Default()),
+        peer_(&config_),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        params_(new QuicCryptoNegotiatedParameters),
+        signed_config_(new QuicSignedServerConfig),
+        chlo_packet_size_(kDefaultMaxPacketSize) {
+    supported_versions_ = GetParam().supported_versions;
+    config_.set_enable_serving_sct(true);
+
+    client_version_ = supported_versions_.front();
+    client_version_label_ = CreateQuicVersionLabel(client_version_);
+    client_version_string_ =
+        std::string(reinterpret_cast<const char*>(&client_version_label_),
+                    sizeof(client_version_label_));
+  }
+
+  void SetUp() override {
+    QuicCryptoServerConfig::ConfigOptions old_config_options;
+    old_config_options.id = kOldConfigId;
+    config_.AddDefaultConfig(rand_, &clock_, old_config_options);
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+    QuicServerConfigProtobuf primary_config =
+        config_.GenerateConfig(rand_, &clock_, config_options_);
+    primary_config.set_primary_time(clock_.WallNow().ToUNIXSeconds());
+    std::unique_ptr<CryptoHandshakeMessage> msg(
+        config_.AddConfig(primary_config, clock_.WallNow()));
+
+    absl::string_view orbit;
+    QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
+    QUICHE_CHECK_EQ(sizeof(orbit_), orbit.size());
+    memcpy(orbit_, orbit.data(), orbit.size());
+
+    char public_value[32];
+    memset(public_value, 42, sizeof(public_value));
+
+    nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce());
+    pub_hex_ = "#" + absl::BytesToHexString(
+                         absl::string_view(public_value, sizeof(public_value)));
+
+    CryptoHandshakeMessage client_hello =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"AEAD", "AESG"},
+                                       {"KEXS", "C255"},
+                                       {"PUBS", pub_hex_},
+                                       {"NONC", nonce_hex_},
+                                       {"CSCT", ""},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+    ShouldSucceed(client_hello);
+    // The message should be rejected because the source-address token is
+    // missing.
+    CheckRejectTag();
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+    absl::string_view srct;
+    ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
+    srct_hex_ = "#" + absl::BytesToHexString(srct);
+
+    absl::string_view scfg;
+    ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
+    server_config_ = CryptoFramer::ParseMessage(scfg);
+
+    absl::string_view scid;
+    ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
+    scid_hex_ = "#" + absl::BytesToHexString(scid);
+
+    signed_config_ =
+        quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>(
+            new QuicSignedServerConfig());
+    QUICHE_DCHECK(signed_config_->chain.get() == nullptr);
+  }
+
+  // Helper used to accept the result of ValidateClientHello and pass
+  // it on to ProcessClientHello.
+  class ValidateCallback : public ValidateClientHelloResultCallback {
+   public:
+    ValidateCallback(CryptoServerTest* test,
+                     bool should_succeed,
+                     const char* error_substr,
+                     bool* called)
+        : test_(test),
+          should_succeed_(should_succeed),
+          error_substr_(error_substr),
+          called_(called) {
+      *called_ = false;
+    }
+
+    void Run(quiche::QuicheReferenceCountedPointer<Result> result,
+             std::unique_ptr<ProofSource::Details> /* details */) override {
+      ASSERT_FALSE(*called_);
+      test_->ProcessValidationResult(std::move(result), should_succeed_,
+                                     error_substr_);
+      *called_ = true;
+    }
+
+   private:
+    CryptoServerTest* test_;
+    const bool should_succeed_;
+    const char* const error_substr_;
+    bool* called_;
+  };
+
+  void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
+    QuicVersionLabelVector versions;
+    server_hello.GetVersionLabelList(kVER, &versions);
+    ASSERT_EQ(supported_versions_.size(), versions.size());
+    for (size_t i = 0; i < versions.size(); ++i) {
+      EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[i]), versions[i]);
+    }
+
+    absl::string_view address;
+    ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address));
+    QuicSocketAddressCoder decoder;
+    ASSERT_TRUE(decoder.Decode(address.data(), address.size()));
+    EXPECT_EQ(client_address_.host(), decoder.ip());
+    EXPECT_EQ(client_address_.port(), decoder.port());
+  }
+
+  void ShouldSucceed(const CryptoHandshakeMessage& message) {
+    bool called = false;
+    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
+    config_.ValidateClientHello(
+        message, client_address_, server_address,
+        supported_versions_.front().transport_version, &clock_, signed_config_,
+        std::make_unique<ValidateCallback>(this, true, "", &called));
+    EXPECT_TRUE(called);
+  }
+
+  void ShouldFailMentioning(const char* error_substr,
+                            const CryptoHandshakeMessage& message) {
+    bool called = false;
+    ShouldFailMentioning(error_substr, message, &called);
+    EXPECT_TRUE(called);
+  }
+
+  void ShouldFailMentioning(const char* error_substr,
+                            const CryptoHandshakeMessage& message,
+                            bool* called) {
+    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
+    config_.ValidateClientHello(
+        message, client_address_, server_address,
+        supported_versions_.front().transport_version, &clock_, signed_config_,
+        std::make_unique<ValidateCallback>(this, false, error_substr, called));
+  }
+
+  class ProcessCallback : public ProcessClientHelloResultCallback {
+   public:
+    ProcessCallback(
+        quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
+        bool should_succeed, const char* error_substr, bool* called,
+        CryptoHandshakeMessage* out)
+        : result_(std::move(result)),
+          should_succeed_(should_succeed),
+          error_substr_(error_substr),
+          called_(called),
+          out_(out) {
+      *called_ = false;
+    }
+
+    void Run(QuicErrorCode error,
+             const std::string& error_details,
+             std::unique_ptr<CryptoHandshakeMessage> message,
+             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
+             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
+        override {
+      if (should_succeed_) {
+        ASSERT_EQ(error, QUIC_NO_ERROR)
+            << "Message failed with error " << error_details << ": "
+            << result_->client_hello.DebugString();
+      } else {
+        ASSERT_NE(error, QUIC_NO_ERROR)
+            << "Message didn't fail: " << result_->client_hello.DebugString();
+        EXPECT_TRUE(absl::StrContains(error_details, error_substr_))
+            << error_substr_ << " not in " << error_details;
+      }
+      if (message != nullptr) {
+        *out_ = *message;
+      }
+      *called_ = true;
+    }
+
+   private:
+    const quiche::QuicheReferenceCountedPointer<ValidateCallback::Result>
+        result_;
+    const bool should_succeed_;
+    const char* const error_substr_;
+    bool* called_;
+    CryptoHandshakeMessage* out_;
+  };
+
+  void ProcessValidationResult(
+      quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
+      bool should_succeed, const char* error_substr) {
+    QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
+    bool called;
+    config_.ProcessClientHello(
+        result, /*reject_only=*/false,
+        /*connection_id=*/TestConnectionId(1), server_address, client_address_,
+        supported_versions_.front(), supported_versions_, &clock_, rand_,
+        &compressed_certs_cache_, params_, signed_config_,
+        /*total_framing_overhead=*/50, chlo_packet_size_,
+        std::make_unique<ProcessCallback>(result, should_succeed, error_substr,
+                                          &called, &out_));
+    EXPECT_TRUE(called);
+  }
+
+  std::string GenerateNonce() {
+    std::string nonce;
+    CryptoUtils::GenerateNonce(
+        clock_.WallNow(), rand_,
+        absl::string_view(reinterpret_cast<const char*>(orbit_),
+                          sizeof(orbit_)),
+        &nonce);
+    return nonce;
+  }
+
+  void CheckRejectReasons(
+      const HandshakeFailureReason* expected_handshake_failures,
+      size_t expected_count) {
+    QuicTagVector reject_reasons;
+    static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+    QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons);
+    ASSERT_THAT(error_code, IsQuicNoError());
+
+    EXPECT_EQ(expected_count, reject_reasons.size());
+    for (size_t i = 0; i < reject_reasons.size(); ++i) {
+      EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
+                reject_reasons[i]);
+    }
+  }
+
+  void CheckRejectTag() {
+    ASSERT_EQ(kREJ, out_.tag()) << QuicTagToString(out_.tag());
+  }
+
+  std::string XlctHexString() {
+    uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
+    return "#" + absl::BytesToHexString(absl::string_view(
+                     reinterpret_cast<char*>(&xlct), sizeof(xlct)));
+  }
+
+ protected:
+  QuicRandom* const rand_;
+  MockRandom rand_for_id_generation_;
+  MockClock clock_;
+  QuicSocketAddress client_address_;
+  ParsedQuicVersionVector supported_versions_;
+  ParsedQuicVersion client_version_;
+  QuicVersionLabel client_version_label_;
+  std::string client_version_string_;
+  QuicCryptoServerConfig config_;
+  QuicCryptoServerConfigPeer peer_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicCryptoServerConfig::ConfigOptions config_options_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+  CryptoHandshakeMessage out_;
+  uint8_t orbit_[kOrbitSize];
+  size_t chlo_packet_size_;
+
+  // These strings contain hex escaped values from the server suitable for using
+  // when constructing client hello messages.
+  std::string nonce_hex_, pub_hex_, srct_hex_, scid_hex_;
+  std::unique_ptr<CryptoHandshakeMessage> server_config_;
+};
+
+INSTANTIATE_TEST_SUITE_P(CryptoServerTests,
+                         CryptoServerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(CryptoServerTest, BadSNI) {
+  // clang-format off
+  std::vector<std::string> badSNIs = {
+    "",
+    "#00",
+    "#ff00",
+    "127.0.0.1",
+    "ffee::1",
+  };
+  // clang-format on
+
+  for (const std::string& bad_sni : badSNIs) {
+    CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+        {{"PDMD", "X509"}, {"SNI", bad_sni}, {"VER\0", client_version_string_}},
+        kClientHelloMinimumSize);
+    ShouldFailMentioning("SNI", msg);
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+  }
+
+  // Check that SNIs without dots are allowed
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"SNI", "foo"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+  ShouldSucceed(msg);
+}
+
+TEST_P(CryptoServerTest, DefaultCert) {
+  // Check that the server replies with a default certificate when no SNI is
+  // specified. The CHLO is constructed to generate a REJ with certs, so must
+  // not contain a valid STK, and must include PDMD.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  EXPECT_NE(0u, cert.size());
+  EXPECT_NE(0u, proof.size());
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+  EXPECT_LT(0u, cert_sct.size());
+}
+
+TEST_P(CryptoServerTest, RejectTooLarge) {
+  // Check that the server replies with no certificate when a CHLO is
+  // constructed with a PDMD but no SKT when the REJ would be too large.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+  config_.set_chlo_multiplier(1);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, RejectNotTooLarge) {
+  // When the CHLO packet is large enough, ensure that a full REJ is sent.
+  chlo_packet_size_ *= 5;
+
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+  config_.set_chlo_multiplier(1);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
+  // Check that the server replies with no certificate when a CHLO is
+  // constructed with a PDMD but no SKT when the REJ would be too large.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
+  config_.set_chlo_multiplier(1);
+
+  ShouldSucceed(msg);
+  absl::string_view cert, proof, cert_sct;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
+  EXPECT_NE(0u, cert.size());
+  EXPECT_NE(0u, proof.size());
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, BadSourceAddressToken) {
+  // Invalid source-address tokens should be ignored.
+  // clang-format off
+  static const char* const kBadSourceAddressTokens[] = {
+    "",
+    "foo",
+    "#0000",
+    "#0000000000000000000000000000000000000000",
+  };
+  // clang-format on
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSourceAddressTokens); i++) {
+    CryptoHandshakeMessage msg =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"STK", kBadSourceAddressTokens[i]},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+    ShouldSucceed(msg);
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+  }
+}
+
+TEST_P(CryptoServerTest, BadClientNonce) {
+  // clang-format off
+  static const char* const kBadNonces[] = {
+    "",
+    "#0000",
+    "#0000000000000000000000000000000000000000",
+  };
+  // clang-format on
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadNonces); i++) {
+    // Invalid nonces should be ignored, in an inchoate CHLO.
+
+    CryptoHandshakeMessage msg =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"NONC", kBadNonces[i]},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+
+    ShouldSucceed(msg);
+    const HandshakeFailureReason kRejectReasons[] = {
+        SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+    CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+    // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE.
+    CryptoHandshakeMessage msg1 =
+        crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                       {"AEAD", "AESG"},
+                                       {"KEXS", "C255"},
+                                       {"SCID", scid_hex_},
+                                       {"#004b5453", srct_hex_},
+                                       {"PUBS", pub_hex_},
+                                       {"NONC", kBadNonces[i]},
+                                       {"NONP", kBadNonces[i]},
+                                       {"XLCT", XlctHexString()},
+                                       {"VER\0", client_version_string_}},
+                                      kClientHelloMinimumSize);
+
+    ShouldSucceed(msg1);
+
+    CheckRejectTag();
+    const HandshakeFailureReason kRejectReasons1[] = {
+        CLIENT_NONCE_INVALID_FAILURE};
+    CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
+  }
+}
+
+TEST_P(CryptoServerTest, NoClientNonce) {
+  // No client nonces should result in INCHOATE_HELLO_FAILURE.
+
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+  CryptoHandshakeMessage msg1 =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"XLCT", XlctHexString()},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg1);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons1[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
+}
+
+TEST_P(CryptoServerTest, DowngradeAttack) {
+  if (supported_versions_.size() == 1) {
+    // No downgrade attack is possible if the server only supports one version.
+    return;
+  }
+  // Set the client's preferred version to a supported version that
+  // is not the "current" version (supported_versions_.front()).
+  std::string bad_version =
+      ParsedQuicVersionToString(supported_versions_.back());
+
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", bad_version}}, kClientHelloMinimumSize);
+
+  ShouldFailMentioning("Downgrade", msg);
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptServerConfig) {
+  // This tests corrupted server config.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", (std::string(1, 'X') + scid_hex_)},
+       {"#004b5453", srct_hex_},
+       {"PUBS", pub_hex_},
+       {"NONC", nonce_hex_},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
+  // This tests corrupted source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", nonce_hex_},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) {
+  // This tests corrupted source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", nonce_hex_},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  config_.set_validate_source_address_token(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
+  // This test corrupts client nonce and source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", (std::string(1, 'X') + nonce_hex_)},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptMultipleTags) {
+  // This test corrupts client nonce, server nonce and source address token.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"SCID", scid_hex_},
+       {"#004b5453", (std::string(1, 'X') + srct_hex_)},
+       {"PUBS", pub_hex_},
+       {"NONC", (std::string(1, 'X') + nonce_hex_)},
+       {"NONP", (std::string(1, 'X') + nonce_hex_)},
+       {"SNO\0", (std::string(1, 'X') + nonce_hex_)},
+       {"XLCT", XlctHexString()},
+       {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  CheckRejectTag();
+
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, NoServerNonce) {
+  // When no server nonce is present and no strike register is configured,
+  // the CHLO should be rejected.
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"NONP", nonce_hex_},
+                                     {"XLCT", XlctHexString()},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+
+  // Even without a server nonce, this ClientHello should be accepted in
+  // version 33.
+  ASSERT_EQ(kSHLO, out_.tag());
+  CheckServerHello(out_);
+}
+
+TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
+  client_address_ = QuicSocketAddress(QuicIpAddress::Loopback6(), 1234);
+
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"PDMD", "X509"},
+                                     {"SCID", kOldConfigId},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"NONP", "123456789012345678901234567890"},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", XlctHexString()}},
+                                    kClientHelloMinimumSize);
+
+  ShouldSucceed(msg);
+  // The message should be rejected because the source-address token is no
+  // longer valid.
+  CheckRejectTag();
+  const HandshakeFailureReason kRejectReasons[] = {
+      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+
+  absl::string_view cert, proof, scfg_str;
+  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
+  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
+  EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str));
+  std::unique_ptr<CryptoHandshakeMessage> scfg(
+      CryptoFramer::ParseMessage(scfg_str));
+  absl::string_view scid;
+  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
+  EXPECT_NE(scid, kOldConfigId);
+
+  // Get certs from compressed certs.
+  std::vector<std::string> cached_certs;
+
+  std::vector<std::string> certs;
+  ASSERT_TRUE(CertCompressor::DecompressChain(cert, cached_certs, &certs));
+
+  // Check that the proof in the REJ message is valid.
+  std::unique_ptr<ProofVerifier> proof_verifier(
+      crypto_test_utils::ProofVerifierForTesting());
+  std::unique_ptr<ProofVerifyContext> verify_context(
+      crypto_test_utils::ProofVerifyContextForTesting());
+  std::unique_ptr<ProofVerifyDetails> details;
+  std::string error_details;
+  std::unique_ptr<ProofVerifierCallback> callback(
+      new DummyProofVerifierCallback());
+  const std::string chlo_hash =
+      CryptoUtils::HashHandshakeMessage(msg, Perspective::IS_SERVER);
+  EXPECT_EQ(QUIC_SUCCESS,
+            proof_verifier->VerifyProof(
+                "test.example.com", 443, (std::string(scfg_str)),
+                client_version_.transport_version, chlo_hash, certs, "",
+                (std::string(proof)), verify_context.get(), &error_details,
+                &details, std::move(callback)));
+}
+
+TEST_P(CryptoServerTest, RejectInvalidXlct) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", "#0102030405060708"}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+
+  const HandshakeFailureReason kRejectReasons[] = {
+      INVALID_EXPECTED_LEAF_CERTIFICATE};
+
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, ValidXlct) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", XlctHexString()}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTest, NonceInSHLO) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", XlctHexString()}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+
+  absl::string_view nonce;
+  EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce));
+}
+
+TEST_P(CryptoServerTest, ProofSourceFailure) {
+  // Install a ProofSource which will unconditionally fail
+  peer_.ResetProofSource(std::unique_ptr<ProofSource>(new FailingProofSource));
+
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"PDMD", "X509"},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // Just ensure that we don't crash as occurred in b/33916924.
+  ShouldFailMentioning("", msg);
+}
+
+// Regression test for crbug.com/723604
+// For 2RTT, if the first CHLO from the client contains hashes of cached
+// certs (stored in CCRT tag) but the second CHLO does not, then the second REJ
+// from the server should not contain hashes of cached certs.
+TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) {
+  // Send inchoate CHLO to get cert chain from server. This CHLO is only for
+  // the purpose of getting the server's certs; it is not part of the 2RTT
+  // handshake.
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+  ShouldSucceed(msg);
+
+  // Decompress cert chain from server to individual certs.
+  absl::string_view certs_compressed;
+  ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
+  ASSERT_NE(0u, certs_compressed.size());
+  std::vector<std::string> certs;
+  ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
+                                              /*cached_certs=*/{}, &certs));
+
+  // Start 2-RTT. Client sends CHLO with bad source-address token and hashes of
+  // the certs, which tells the server that the client has cached those certs.
+  config_.set_chlo_multiplier(1);
+  const char kBadSourceAddressToken[] = "";
+  msg.SetStringPiece(kSourceAddressTokenTag, kBadSourceAddressToken);
+  std::vector<uint64_t> hashes(certs.size());
+  for (size_t i = 0; i < certs.size(); ++i) {
+    hashes[i] = QuicUtils::QuicUtils::FNV1a_64_Hash(certs[i]);
+  }
+  msg.SetVector(kCCRT, hashes);
+  ShouldSucceed(msg);
+
+  // Server responds with inchoate REJ containing valid source-address token.
+  absl::string_view srct;
+  ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
+
+  // Client now drops cached certs; sends CHLO with updated source-address
+  // token but no hashes of certs.
+  msg.SetStringPiece(kSourceAddressTokenTag, srct);
+  msg.Erase(kCCRT);
+  ShouldSucceed(msg);
+
+  // Server response's cert chain should not contain hashes of
+  // previously-cached certs.
+  ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
+  ASSERT_NE(0u, certs_compressed.size());
+  ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
+                                              /*cached_certs=*/{}, &certs));
+}
+
+class CryptoServerConfigGenerationTest : public QuicTest {};
+
+TEST_F(CryptoServerConfigGenerationTest, Determinism) {
+  // Test that using a deterministic PRNG causes the server-config to be
+  // deterministic.
+
+  MockRandom rand_a, rand_b;
+  const QuicCryptoServerConfig::ConfigOptions options;
+  MockClock clock;
+
+  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  std::unique_ptr<CryptoHandshakeMessage> scfg_a(
+      a.AddDefaultConfig(&rand_a, &clock, options));
+  std::unique_ptr<CryptoHandshakeMessage> scfg_b(
+      b.AddDefaultConfig(&rand_b, &clock, options));
+
+  ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString());
+}
+
+TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) {
+  // This test ensures that the server config ID varies for different server
+  // configs.
+
+  MockRandom rand_a, rand_b;
+  const QuicCryptoServerConfig::ConfigOptions options;
+  MockClock clock;
+
+  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  rand_b.ChangeValue();
+  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  std::unique_ptr<CryptoHandshakeMessage> scfg_a(
+      a.AddDefaultConfig(&rand_a, &clock, options));
+  std::unique_ptr<CryptoHandshakeMessage> scfg_b(
+      b.AddDefaultConfig(&rand_b, &clock, options));
+
+  absl::string_view scid_a, scid_b;
+  EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a));
+  EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b));
+
+  EXPECT_NE(scid_a, scid_b);
+}
+
+TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
+  MockRandom rand_a;
+  const QuicCryptoServerConfig::ConfigOptions options;
+  MockClock clock;
+
+  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
+                           crypto_test_utils::ProofSourceForTesting(),
+                           KeyExchangeSource::Default());
+  std::unique_ptr<CryptoHandshakeMessage> scfg(
+      a.AddDefaultConfig(&rand_a, &clock, options));
+
+  absl::string_view scid;
+  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
+  // Need to take a copy of |scid| has we're about to call |Erase|.
+  const std::string scid_str(scid);
+
+  scfg->Erase(kSCID);
+  scfg->MarkDirty();
+  const QuicData& serialized(scfg->GetSerialized());
+
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
+         serialized.length(), digest);
+
+  // scid is a SHA-256 hash, truncated to 16 bytes.
+  ASSERT_EQ(scid.size(), 16u);
+  EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), scid.size()));
+}
+
+// Those tests were declared incorrectly and thus never ran in first place.
+// TODO(b/147891553): figure out if we should fix or delete those.
+#if 0
+
+class CryptoServerTestNoConfig : public CryptoServerTest {
+ public:
+  void SetUp() override {
+    // Deliberately don't add a config so that we can test this situation.
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(CryptoServerTestsNoConfig,
+                         CryptoServerTestNoConfig,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(CryptoServerTestNoConfig, DontCrash) {
+  CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+      kClientHelloMinimumSize);
+
+  ShouldFailMentioning("No config", msg);
+
+  const HandshakeFailureReason kRejectReasons[] = {
+      SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
+  CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
+}
+
+class CryptoServerTestOldVersion : public CryptoServerTest {
+ public:
+  void SetUp() override {
+    client_version_ = supported_versions_.back();
+    client_version_string_ = ParsedQuicVersionToString(client_version_);
+    CryptoServerTest::SetUp();
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(CryptoServerTestsOldVersion,
+                         CryptoServerTestOldVersion,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_},
+                                     {"XLCT", "#0100000000000000"}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+TEST_P(CryptoServerTestOldVersion, XlctNotRequired) {
+  CryptoHandshakeMessage msg =
+      crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
+                                     {"AEAD", "AESG"},
+                                     {"KEXS", "C255"},
+                                     {"SCID", scid_hex_},
+                                     {"#004b5453", srct_hex_},
+                                     {"PUBS", pub_hex_},
+                                     {"NONC", nonce_hex_},
+                                     {"VER\0", client_version_string_}},
+                                    kClientHelloMinimumSize);
+
+  // If replay protection isn't disabled, then
+  // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
+  // and cause ProcessClientHello to exit early (and generate a REJ message).
+  config_.set_replay_protection(false);
+
+  ShouldSucceed(msg);
+  EXPECT_EQ(kSHLO, out_.tag());
+}
+
+#endif  // 0
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_utils.cc b/quiche/quic/core/crypto/crypto_utils.cc
new file mode 100644
index 0000000..d40c734
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_utils.cc
@@ -0,0 +1,790 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_utils.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/hkdf.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+// Implements the HKDF-Expand-Label function as defined in section 7.1 of RFC
+// 8446. The HKDF-Expand-Label function takes 4 explicit arguments (Secret,
+// Label, Context, and Length), as well as implicit PRF which is the hash
+// function negotiated by TLS. Its use in QUIC (as needed by the QUIC stack,
+// instead of as used internally by the TLS stack) is only for deriving initial
+// secrets for obfuscation, for calculating packet protection keys and IVs from
+// the corresponding packet protection secret and key update in the same quic
+// session. None of these uses need a Context (a zero-length context is
+// provided), so this argument is omitted here.
+//
+// The implicit PRF is explicitly passed into HkdfExpandLabel as |prf|; the
+// Secret, Label, and Length are passed in as |secret|, |label|, and
+// |out_len|, respectively. The resulting expanded secret is returned.
+std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
+                                     const std::vector<uint8_t>& secret,
+                                     const std::string& label, size_t out_len) {
+  bssl::ScopedCBB quic_hkdf_label;
+  CBB inner_label;
+  const char label_prefix[] = "tls13 ";
+  // 20 = size(u16) + size(u8) + len("tls13 ") +
+  //      max_len("client in", "server in", "quicv2 key", ... ) +
+  //      size(u8);
+  static const size_t max_quic_hkdf_label_length = 20;
+  if (!CBB_init(quic_hkdf_label.get(), max_quic_hkdf_label_length) ||
+      !CBB_add_u16(quic_hkdf_label.get(), out_len) ||
+      !CBB_add_u8_length_prefixed(quic_hkdf_label.get(), &inner_label) ||
+      !CBB_add_bytes(&inner_label,
+                     reinterpret_cast<const uint8_t*>(label_prefix),
+                     ABSL_ARRAYSIZE(label_prefix) - 1) ||
+      !CBB_add_bytes(&inner_label,
+                     reinterpret_cast<const uint8_t*>(label.data()),
+                     label.size()) ||
+      // Zero length |Context|.
+      !CBB_add_u8(quic_hkdf_label.get(), 0) ||
+      !CBB_flush(quic_hkdf_label.get())) {
+    QUIC_LOG(ERROR) << "Building HKDF label failed";
+    return std::vector<uint8_t>();
+  }
+  std::vector<uint8_t> out;
+  out.resize(out_len);
+  if (!HKDF_expand(out.data(), out_len, prf, secret.data(), secret.size(),
+                   CBB_data(quic_hkdf_label.get()),
+                   CBB_len(quic_hkdf_label.get()))) {
+    QUIC_LOG(ERROR) << "Running HKDF-Expand-Label failed";
+    return std::vector<uint8_t>();
+  }
+  return out;
+}
+
+}  // namespace
+
+const std::string getLabelForVersion(const ParsedQuicVersion& version,
+                                     const absl::string_view& predicate) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync with HKDF labels");
+  if (version == ParsedQuicVersion::V2Draft01()) {
+    return absl::StrCat("quicv2 ", predicate);
+  } else {
+    return absl::StrCat("quic ", predicate);
+  }
+}
+
+void CryptoUtils::InitializeCrypterSecrets(
+    const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+    const ParsedQuicVersion& version, QuicCrypter* crypter) {
+  SetKeyAndIV(prf, pp_secret, version, crypter);
+  std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey(
+      prf, pp_secret, version, crypter->GetKeySize());
+  crypter->SetHeaderProtectionKey(
+      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
+                        header_protection_key.size()));
+}
+
+void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
+                              const std::vector<uint8_t>& pp_secret,
+                              const ParsedQuicVersion& version,
+                              QuicCrypter* crypter) {
+  std::vector<uint8_t> key =
+      HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"),
+                      crypter->GetKeySize());
+  std::vector<uint8_t> iv = HkdfExpandLabel(
+      prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize());
+  crypter->SetKey(
+      absl::string_view(reinterpret_cast<char*>(key.data()), key.size()));
+  crypter->SetIV(
+      absl::string_view(reinterpret_cast<char*>(iv.data()), iv.size()));
+}
+
+std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
+    const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+    const ParsedQuicVersion& version, size_t out_len) {
+  return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
+                         out_len);
+}
+
+std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
+    const EVP_MD* prf, const ParsedQuicVersion& version,
+    const std::vector<uint8_t>& current_secret) {
+  return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"),
+                         current_secret.size());
+}
+
+namespace {
+
+// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
+const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
+                                       0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
+                                       0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
+const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34,
+                                     0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
+                                     0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a};
+const uint8_t kV2Draft01InitialSalt[] = {
+    0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d,
+    0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3};
+
+// Salts used by deployed versions of QUIC. When introducing a new version,
+// generate a new salt by running `openssl rand -hex 20`.
+
+// Salt to use for initial obfuscators in version Q050.
+const uint8_t kQ050Salt[] = {0x50, 0x45, 0x74, 0xef, 0xd0, 0x66, 0xfe,
+                             0x2f, 0x9d, 0x94, 0x5c, 0xfc, 0xdb, 0xd3,
+                             0xa7, 0xf0, 0xd3, 0xb5, 0x6b, 0x45};
+// Salt to use for initial obfuscators in
+// ParsedQuicVersion::ReservedForNegotiation().
+const uint8_t kReservedForNegotiationSalt[] = {
+    0xf9, 0x64, 0xbf, 0x45, 0x3a, 0x1f, 0x1b, 0x80, 0xa5, 0xf8,
+    0x82, 0x03, 0x77, 0xd4, 0xaf, 0xca, 0x58, 0x0e, 0xe7, 0x43};
+
+const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
+                                     size_t* out_len) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync with initial encryption salts");
+  if (version == ParsedQuicVersion::V2Draft01()) {
+    *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt);
+    return kV2Draft01InitialSalt;
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    *out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt);
+    return kRFCv1InitialSalt;
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    *out_len = ABSL_ARRAYSIZE(kDraft29InitialSalt);
+    return kDraft29InitialSalt;
+  } else if (version == ParsedQuicVersion::Q050()) {
+    *out_len = ABSL_ARRAYSIZE(kQ050Salt);
+    return kQ050Salt;
+  } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
+    *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
+    return kReservedForNegotiationSalt;
+  }
+  QUIC_BUG(quic_bug_10699_1)
+      << "No initial obfuscation salt for version " << version;
+  *out_len = ABSL_ARRAYSIZE(kReservedForNegotiationSalt);
+  return kReservedForNegotiationSalt;
+}
+
+const char kPreSharedKeyLabel[] = "QUIC PSK";
+
+// Retry Integrity Protection Keys and Nonces.
+// https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
+// When introducing a new Google version, generate a new key by running
+// `openssl rand -hex 16`.
+const uint8_t kDraft29RetryIntegrityKey[] = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a,
+                                             0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a,
+                                             0x6c, 0xb9, 0x6b, 0xe1};
+const uint8_t kDraft29RetryIntegrityNonce[] = {
+    0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c};
+const uint8_t kRFCv1RetryIntegrityKey[] = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66,
+                                           0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54,
+                                           0xe3, 0x68, 0xc8, 0x4e};
+const uint8_t kRFCv1RetryIntegrityNonce[] = {
+    0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb};
+const uint8_t kV2Draft01RetryIntegrityKey[] = {
+    0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb,
+    0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb};
+const uint8_t kV2Draft01RetryIntegrityNonce[] = {
+    0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f};
+// Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation().
+const uint8_t kReservedForNegotiationRetryIntegrityKey[] = {
+    0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35,
+    0x03, 0xe6, 0x7c, 0x7b, 0xd2, 0x44, 0xca, 0xd9};
+// When introducing a new Google version, generate a new nonce by running
+// `openssl rand -hex 12`.
+// Retry integrity nonce used by ParsedQuicVersion::ReservedForNegotiation().
+const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = {
+    0x35, 0x9f, 0x16, 0xd1, 0xed, 0x80, 0x90, 0x8e, 0xec, 0x85, 0xc4, 0xd6};
+
+bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
+                                  absl::string_view* key,
+                                  absl::string_view* nonce) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync with retry integrity keys");
+  if (!version.UsesTls()) {
+    QUIC_BUG(quic_bug_10699_2)
+        << "Attempted to get retry integrity keys for invalid version "
+        << version;
+    return false;
+  } else if (version == ParsedQuicVersion::V2Draft01()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey),
+        ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey),
+        ABSL_ARRAYSIZE(kRFCv1RetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(kRFCv1RetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kRFCv1RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
+        ABSL_ARRAYSIZE(kDraft29RetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kDraft29RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::ReservedForNegotiation()) {
+    *key = absl::string_view(
+        reinterpret_cast<const char*>(kReservedForNegotiationRetryIntegrityKey),
+        ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityKey));
+    *nonce = absl::string_view(
+        reinterpret_cast<const char*>(
+            kReservedForNegotiationRetryIntegrityNonce),
+        ABSL_ARRAYSIZE(kReservedForNegotiationRetryIntegrityNonce));
+    return true;
+  }
+  QUIC_BUG(quic_bug_10699_3)
+      << "Attempted to get retry integrity keys for version " << version;
+  return false;
+}
+
+}  // namespace
+
+// static
+void CryptoUtils::CreateInitialObfuscators(Perspective perspective,
+                                           ParsedQuicVersion version,
+                                           QuicConnectionId connection_id,
+                                           CrypterPair* crypters) {
+  QUIC_DLOG(INFO) << "Creating "
+                  << (perspective == Perspective::IS_CLIENT ? "client"
+                                                            : "server")
+                  << " crypters for version " << version << " with CID "
+                  << connection_id;
+  if (!version.UsesInitialObfuscators()) {
+    crypters->encrypter = std::make_unique<NullEncrypter>(perspective);
+    crypters->decrypter = std::make_unique<NullDecrypter>(perspective);
+    return;
+  }
+  QUIC_BUG_IF(quic_bug_12871_1, !QuicUtils::IsConnectionIdValidForVersion(
+                                    connection_id, version.transport_version))
+      << "CreateTlsInitialCrypters: attempted to use connection ID "
+      << connection_id << " which is invalid with version " << version;
+  const EVP_MD* hash = EVP_sha256();
+
+  size_t salt_len;
+  const uint8_t* salt = InitialSaltForVersion(version, &salt_len);
+  std::vector<uint8_t> handshake_secret;
+  handshake_secret.resize(EVP_MAX_MD_SIZE);
+  size_t handshake_secret_len;
+  const bool hkdf_extract_success =
+      HKDF_extract(handshake_secret.data(), &handshake_secret_len, hash,
+                   reinterpret_cast<const uint8_t*>(connection_id.data()),
+                   connection_id.length(), salt, salt_len);
+  QUIC_BUG_IF(quic_bug_12871_2, !hkdf_extract_success)
+      << "HKDF_extract failed when creating initial crypters";
+  handshake_secret.resize(handshake_secret_len);
+
+  const std::string client_label = "client in";
+  const std::string server_label = "server in";
+  std::string encryption_label, decryption_label;
+  if (perspective == Perspective::IS_CLIENT) {
+    encryption_label = client_label;
+    decryption_label = server_label;
+  } else {
+    encryption_label = server_label;
+    decryption_label = client_label;
+  }
+  std::vector<uint8_t> encryption_secret = HkdfExpandLabel(
+      hash, handshake_secret, encryption_label, EVP_MD_size(hash));
+  crypters->encrypter = std::make_unique<Aes128GcmEncrypter>();
+  InitializeCrypterSecrets(hash, encryption_secret, version,
+                           crypters->encrypter.get());
+
+  std::vector<uint8_t> decryption_secret = HkdfExpandLabel(
+      hash, handshake_secret, decryption_label, EVP_MD_size(hash));
+  crypters->decrypter = std::make_unique<Aes128GcmDecrypter>();
+  InitializeCrypterSecrets(hash, decryption_secret, version,
+                           crypters->decrypter.get());
+}
+
+// static
+bool CryptoUtils::ValidateRetryIntegrityTag(
+    ParsedQuicVersion version, QuicConnectionId original_connection_id,
+    absl::string_view retry_without_tag, absl::string_view integrity_tag) {
+  unsigned char computed_integrity_tag[kRetryIntegrityTagLength];
+  if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) {
+    QUIC_BUG(quic_bug_10699_4)
+        << "Invalid retry integrity tag length " << integrity_tag.length();
+    return false;
+  }
+  char retry_pseudo_packet[kMaxIncomingPacketSize + 256];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(retry_pseudo_packet),
+                        retry_pseudo_packet);
+  if (!writer.WriteLengthPrefixedConnectionId(original_connection_id)) {
+    QUIC_BUG(quic_bug_10699_5)
+        << "Failed to write original connection ID in retry pseudo packet";
+    return false;
+  }
+  if (!writer.WriteStringPiece(retry_without_tag)) {
+    QUIC_BUG(quic_bug_10699_6)
+        << "Failed to write retry without tag in retry pseudo packet";
+    return false;
+  }
+  absl::string_view key;
+  absl::string_view nonce;
+  if (!RetryIntegrityKeysForVersion(version, &key, &nonce)) {
+    // RetryIntegrityKeysForVersion already logs failures.
+    return false;
+  }
+  Aes128GcmEncrypter crypter;
+  crypter.SetKey(key);
+  absl::string_view associated_data(writer.data(), writer.length());
+  absl::string_view plaintext;  // Plaintext is empty.
+  if (!crypter.Encrypt(nonce, associated_data, plaintext,
+                       computed_integrity_tag)) {
+    QUIC_BUG(quic_bug_10699_7) << "Failed to compute retry integrity tag";
+    return false;
+  }
+  if (CRYPTO_memcmp(computed_integrity_tag, integrity_tag.data(),
+                    ABSL_ARRAYSIZE(computed_integrity_tag)) != 0) {
+    QUIC_DLOG(ERROR) << "Failed to validate retry integrity tag";
+    return false;
+  }
+  return true;
+}
+
+// static
+void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+                                absl::string_view orbit, std::string* nonce) {
+  // a 4-byte timestamp + 28 random bytes.
+  nonce->reserve(kNonceSize);
+  nonce->resize(kNonceSize);
+
+  uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds());
+  // The time in the nonce must be encoded in big-endian because the
+  // strike-register depends on the nonces being ordered by time.
+  (*nonce)[0] = static_cast<char>(gmt_unix_time >> 24);
+  (*nonce)[1] = static_cast<char>(gmt_unix_time >> 16);
+  (*nonce)[2] = static_cast<char>(gmt_unix_time >> 8);
+  (*nonce)[3] = static_cast<char>(gmt_unix_time);
+  size_t bytes_written = 4;
+
+  if (orbit.size() == 8) {
+    memcpy(&(*nonce)[bytes_written], orbit.data(), orbit.size());
+    bytes_written += orbit.size();
+  }
+
+  random_generator->RandBytes(&(*nonce)[bytes_written],
+                              kNonceSize - bytes_written);
+}
+
+// static
+bool CryptoUtils::DeriveKeys(
+    const ParsedQuicVersion& version, absl::string_view premaster_secret,
+    QuicTag aead, absl::string_view client_nonce,
+    absl::string_view server_nonce, absl::string_view pre_shared_key,
+    const std::string& hkdf_input, Perspective perspective,
+    Diversification diversification, CrypterPair* crypters,
+    std::string* subkey_secret) {
+  // If the connection is using PSK, concatenate it with the pre-master secret.
+  std::unique_ptr<char[]> psk_premaster_secret;
+  if (!pre_shared_key.empty()) {
+    const absl::string_view label(kPreSharedKeyLabel);
+    const size_t psk_premaster_secret_size = label.size() + 1 +
+                                             pre_shared_key.size() + 8 +
+                                             premaster_secret.size() + 8;
+
+    psk_premaster_secret = std::make_unique<char[]>(psk_premaster_secret_size);
+    QuicDataWriter writer(psk_premaster_secret_size, psk_premaster_secret.get(),
+                          quiche::HOST_BYTE_ORDER);
+
+    if (!writer.WriteStringPiece(label) || !writer.WriteUInt8(0) ||
+        !writer.WriteStringPiece(pre_shared_key) ||
+        !writer.WriteUInt64(pre_shared_key.size()) ||
+        !writer.WriteStringPiece(premaster_secret) ||
+        !writer.WriteUInt64(premaster_secret.size()) ||
+        writer.remaining() != 0) {
+      return false;
+    }
+
+    premaster_secret = absl::string_view(psk_premaster_secret.get(),
+                                         psk_premaster_secret_size);
+  }
+
+  crypters->encrypter = QuicEncrypter::Create(version, aead);
+  crypters->decrypter = QuicDecrypter::Create(version, aead);
+
+  size_t key_bytes = crypters->encrypter->GetKeySize();
+  size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize();
+  if (version.UsesInitialObfuscators()) {
+    nonce_prefix_bytes = crypters->encrypter->GetIVSize();
+  }
+  size_t subkey_secret_bytes =
+      subkey_secret == nullptr ? 0 : premaster_secret.length();
+
+  absl::string_view nonce = client_nonce;
+  std::string nonce_storage;
+  if (!server_nonce.empty()) {
+    nonce_storage = std::string(client_nonce) + std::string(server_nonce);
+    nonce = nonce_storage;
+  }
+
+  QuicHKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
+                nonce_prefix_bytes, subkey_secret_bytes);
+
+  // Key derivation depends on the key diversification method being employed.
+  // both the client and the server support never doing key diversification.
+  // The server also supports immediate diversification, and the client
+  // supports pending diversification.
+  switch (diversification.mode()) {
+    case Diversification::NEVER: {
+      if (perspective == Perspective::IS_SERVER) {
+        if (!crypters->encrypter->SetKey(hkdf.server_write_key()) ||
+            !crypters->encrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.server_write_iv()) ||
+            !crypters->encrypter->SetHeaderProtectionKey(
+                hkdf.server_hp_key()) ||
+            !crypters->decrypter->SetKey(hkdf.client_write_key()) ||
+            !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.client_write_iv()) ||
+            !crypters->decrypter->SetHeaderProtectionKey(
+                hkdf.client_hp_key())) {
+          return false;
+        }
+      } else {
+        if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
+            !crypters->encrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.client_write_iv()) ||
+            !crypters->encrypter->SetHeaderProtectionKey(
+                hkdf.client_hp_key()) ||
+            !crypters->decrypter->SetKey(hkdf.server_write_key()) ||
+            !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                     hkdf.server_write_iv()) ||
+            !crypters->decrypter->SetHeaderProtectionKey(
+                hkdf.server_hp_key())) {
+          return false;
+        }
+      }
+      break;
+    }
+    case Diversification::PENDING: {
+      if (perspective == Perspective::IS_SERVER) {
+        QUIC_BUG(quic_bug_10699_8)
+            << "Pending diversification is only for clients.";
+        return false;
+      }
+
+      if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
+          !crypters->encrypter->SetNoncePrefixOrIV(version,
+                                                   hkdf.client_write_iv()) ||
+          !crypters->encrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
+          !crypters->decrypter->SetPreliminaryKey(hkdf.server_write_key()) ||
+          !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                   hkdf.server_write_iv()) ||
+          !crypters->decrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
+        return false;
+      }
+      break;
+    }
+    case Diversification::NOW: {
+      if (perspective == Perspective::IS_CLIENT) {
+        QUIC_BUG(quic_bug_10699_9)
+            << "Immediate diversification is only for servers.";
+        return false;
+      }
+
+      std::string key, nonce_prefix;
+      QuicDecrypter::DiversifyPreliminaryKey(
+          hkdf.server_write_key(), hkdf.server_write_iv(),
+          *diversification.nonce(), key_bytes, nonce_prefix_bytes, &key,
+          &nonce_prefix);
+      if (!crypters->decrypter->SetKey(hkdf.client_write_key()) ||
+          !crypters->decrypter->SetNoncePrefixOrIV(version,
+                                                   hkdf.client_write_iv()) ||
+          !crypters->decrypter->SetHeaderProtectionKey(hkdf.client_hp_key()) ||
+          !crypters->encrypter->SetKey(key) ||
+          !crypters->encrypter->SetNoncePrefixOrIV(version, nonce_prefix) ||
+          !crypters->encrypter->SetHeaderProtectionKey(hkdf.server_hp_key())) {
+        return false;
+      }
+      break;
+    }
+    default:
+      QUICHE_DCHECK(false);
+  }
+
+  if (subkey_secret != nullptr) {
+    *subkey_secret = std::string(hkdf.subkey_secret());
+  }
+
+  return true;
+}
+
+// static
+uint64_t CryptoUtils::ComputeLeafCertHash(absl::string_view cert) {
+  return QuicUtils::FNV1a_64_Hash(cert);
+}
+
+QuicErrorCode CryptoUtils::ValidateServerHello(
+    const CryptoHandshakeMessage& server_hello,
+    const ParsedQuicVersionVector& negotiated_versions,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  if (server_hello.tag() != kSHLO) {
+    *error_details = "Bad tag";
+    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+  }
+
+  QuicVersionLabelVector supported_version_labels;
+  if (server_hello.GetVersionLabelList(kVER, &supported_version_labels) !=
+      QUIC_NO_ERROR) {
+    *error_details = "server hello missing version list";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  return ValidateServerHelloVersions(supported_version_labels,
+                                     negotiated_versions, error_details);
+}
+
+QuicErrorCode CryptoUtils::ValidateServerHelloVersions(
+    const QuicVersionLabelVector& server_versions,
+    const ParsedQuicVersionVector& negotiated_versions,
+    std::string* error_details) {
+  if (!negotiated_versions.empty()) {
+    bool mismatch = server_versions.size() != negotiated_versions.size();
+    for (size_t i = 0; i < server_versions.size() && !mismatch; ++i) {
+      mismatch =
+          server_versions[i] != CreateQuicVersionLabel(negotiated_versions[i]);
+    }
+    // The server sent a list of supported versions, and the connection
+    // reports that there was a version negotiation during the handshake.
+    // Ensure that these two lists are identical.
+    if (mismatch) {
+      *error_details = absl::StrCat(
+          "Downgrade attack detected: ServerVersions(", server_versions.size(),
+          ")[", QuicVersionLabelVectorToString(server_versions, ",", 30),
+          "] NegotiatedVersions(", negotiated_versions.size(), ")[",
+          ParsedQuicVersionVectorToString(negotiated_versions, ",", 30), "]");
+      return QUIC_VERSION_NEGOTIATION_MISMATCH;
+    }
+  }
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode CryptoUtils::ValidateClientHello(
+    const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
+    const ParsedQuicVersionVector& supported_versions,
+    std::string* error_details) {
+  if (client_hello.tag() != kCHLO) {
+    *error_details = "Bad tag";
+    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+  }
+
+  // If the client's preferred version is not the version we are currently
+  // speaking, then the client went through a version negotiation.  In this
+  // case, we need to make sure that we actually do not support this version
+  // and that it wasn't a downgrade attack.
+  QuicVersionLabel client_version_label;
+  if (client_hello.GetVersionLabel(kVER, &client_version_label) !=
+      QUIC_NO_ERROR) {
+    *error_details = "client hello missing version list";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+  return ValidateClientHelloVersion(client_version_label, version,
+                                    supported_versions, error_details);
+}
+
+QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
+    QuicVersionLabel client_version, ParsedQuicVersion connection_version,
+    const ParsedQuicVersionVector& supported_versions,
+    std::string* error_details) {
+  if (client_version != CreateQuicVersionLabel(connection_version)) {
+    // Check to see if |client_version| is actually on the supported versions
+    // list. If not, the server doesn't support that version and it's not a
+    // downgrade attack.
+    for (size_t i = 0; i < supported_versions.size(); ++i) {
+      if (client_version == CreateQuicVersionLabel(supported_versions[i])) {
+        *error_details = absl::StrCat(
+            "Downgrade attack detected: ClientVersion[",
+            QuicVersionLabelToString(client_version), "] ConnectionVersion[",
+            ParsedQuicVersionToString(connection_version),
+            "] SupportedVersions(", supported_versions.size(), ")[",
+            ParsedQuicVersionVectorToString(supported_versions, ",", 30), "]");
+        return QUIC_VERSION_NEGOTIATION_MISMATCH;
+      }
+    }
+  }
+  return QUIC_NO_ERROR;
+}
+
+// static
+bool CryptoUtils::ValidateChosenVersion(
+    const QuicVersionLabel& version_information_chosen_version,
+    const ParsedQuicVersion& session_version, std::string* error_details) {
+  if (version_information_chosen_version !=
+      CreateQuicVersionLabel(session_version)) {
+    *error_details = absl::StrCat(
+        "Detected version mismatch: version_information contained ",
+        QuicVersionLabelToString(version_information_chosen_version),
+        " instead of ", ParsedQuicVersionToString(session_version));
+    return false;
+  }
+  return true;
+}
+
+// static
+bool CryptoUtils::ValidateServerVersions(
+    const QuicVersionLabelVector& version_information_other_versions,
+    const ParsedQuicVersion& session_version,
+    const ParsedQuicVersionVector& client_original_supported_versions,
+    std::string* error_details) {
+  if (client_original_supported_versions.empty()) {
+    // We did not receive a version negotiation packet.
+    return true;
+  }
+  // Parse the server's other versions.
+  ParsedQuicVersionVector parsed_other_versions =
+      ParseQuicVersionLabelVector(version_information_other_versions);
+  // Find the first version that we originally supported that is listed in the
+  // server's other versions.
+  ParsedQuicVersion expected_version = ParsedQuicVersion::Unsupported();
+  for (const ParsedQuicVersion& client_version :
+       client_original_supported_versions) {
+    if (std::find(parsed_other_versions.begin(), parsed_other_versions.end(),
+                  client_version) != parsed_other_versions.end()) {
+      expected_version = client_version;
+      break;
+    }
+  }
+  if (expected_version != session_version) {
+    *error_details = absl::StrCat(
+        "Downgrade attack detected: used ",
+        ParsedQuicVersionToString(session_version), " but ServerVersions(",
+        version_information_other_versions.size(), ")[",
+        QuicVersionLabelVectorToString(version_information_other_versions, ",",
+                                       30),
+        "] ClientOriginalVersions(", client_original_supported_versions.size(),
+        ")[",
+        ParsedQuicVersionVectorToString(client_original_supported_versions, ",",
+                                        30),
+        "]");
+    return false;
+  }
+  return true;
+}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x
+
+// Returns the name of the HandshakeFailureReason as a char*
+// static
+const char* CryptoUtils::HandshakeFailureReasonToString(
+    HandshakeFailureReason reason) {
+  switch (reason) {
+    RETURN_STRING_LITERAL(HANDSHAKE_OK);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_UNKNOWN_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_NOT_UNIQUE_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_ORBIT_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_INVALID_TIME_FAILURE);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT);
+    RETURN_STRING_LITERAL(CLIENT_NONCE_STRIKE_REGISTER_FAILURE);
+
+    RETURN_STRING_LITERAL(SERVER_NONCE_DECRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_NOT_UNIQUE_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_INVALID_TIME_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_NONCE_REQUIRED_FAILURE);
+
+    RETURN_STRING_LITERAL(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+    RETURN_STRING_LITERAL(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_INVALID_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_PARSE_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE);
+    RETURN_STRING_LITERAL(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE);
+
+    RETURN_STRING_LITERAL(INVALID_EXPECTED_LEAF_CERTIFICATE);
+    RETURN_STRING_LITERAL(MAX_FAILURE_REASON);
+  }
+  // Return a default value so that we return this when |reason| doesn't match
+  // any HandshakeFailureReason.. This can happen when the message by the peer
+  // (attacker) has invalid reason.
+  return "INVALID_HANDSHAKE_FAILURE_REASON";
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+// static
+std::string CryptoUtils::EarlyDataReasonToString(
+    ssl_early_data_reason_t reason) {
+  const char* reason_string = SSL_early_data_reason_string(reason);
+  if (reason_string != nullptr) {
+    return std::string("ssl_early_data_") + reason_string;
+  }
+  QUIC_BUG_IF(quic_bug_12871_3,
+              reason < 0 || reason > ssl_early_data_reason_max_value)
+      << "Unknown ssl_early_data_reason_t " << reason;
+  return "unknown ssl_early_data_reason_t";
+}
+
+// static
+std::string CryptoUtils::HashHandshakeMessage(
+    const CryptoHandshakeMessage& message, Perspective /*perspective*/) {
+  std::string output;
+  const QuicData& serialized = message.GetSerialized();
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
+         serialized.length(), digest);
+  output.assign(reinterpret_cast<const char*>(digest), sizeof(digest));
+  return output;
+}
+
+// static
+bool CryptoUtils::GetSSLCapabilities(const SSL* ssl,
+                                     bssl::UniquePtr<uint8_t>* capabilities,
+                                     size_t* capabilities_len) {
+  uint8_t* buffer;
+  CBB cbb;
+
+  if (!CBB_init(&cbb, 128) || !SSL_serialize_capabilities(ssl, &cbb) ||
+      !CBB_finish(&cbb, &buffer, capabilities_len)) {
+    return false;
+  }
+
+  *capabilities = bssl::UniquePtr<uint8_t>(buffer);
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/crypto_utils.h b/quiche/quic/core/crypto/crypto_utils.h
new file mode 100644
index 0000000..1f618d9
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_utils.h
@@ -0,0 +1,255 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Some helpers for quic crypto
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicRandom;
+
+class QUIC_EXPORT_PRIVATE CryptoUtils {
+ public:
+  CryptoUtils() = delete;
+
+  // Diversification is a utility class that's used to act like a union type.
+  // Values can be created by calling the functions like |NoDiversification|,
+  // below.
+  class QUIC_EXPORT_PRIVATE Diversification {
+   public:
+    enum Mode {
+      NEVER,  // Key diversification will never be used. Forward secure
+              // crypters will always use this mode.
+
+      PENDING,  // Key diversification will happen when a nonce is later
+                // received. This should only be used by clients initial
+                // decrypters which are waiting on the divesification nonce
+                // from the server.
+
+      NOW,  // Key diversification will happen immediate based on the nonce.
+            // This should only be used by servers initial encrypters.
+    };
+
+    Diversification(const Diversification& diversification) = default;
+
+    static Diversification Never() { return Diversification(NEVER, nullptr); }
+    static Diversification Pending() {
+      return Diversification(PENDING, nullptr);
+    }
+    static Diversification Now(DiversificationNonce* nonce) {
+      return Diversification(NOW, nonce);
+    }
+
+    Mode mode() const { return mode_; }
+    DiversificationNonce* nonce() const {
+      QUICHE_DCHECK_EQ(mode_, NOW);
+      return nonce_;
+    }
+
+   private:
+    Diversification(Mode mode, DiversificationNonce* nonce)
+        : mode_(mode), nonce_(nonce) {}
+
+    Mode mode_;
+    DiversificationNonce* nonce_;
+  };
+
+  // InitializeCrypterSecrets derives the key and IV and header protection key
+  // from the given packet protection secret |pp_secret| and sets those fields
+  // on the given QuicCrypter |*crypter|.
+  // This follows the derivation described in section 7.3 of RFC 8446, except
+  // with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic "
+  // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as
+  // described in draft-ietf-quic-v2-01.
+  static void InitializeCrypterSecrets(const EVP_MD* prf,
+                                       const std::vector<uint8_t>& pp_secret,
+                                       const ParsedQuicVersion& version,
+                                       QuicCrypter* crypter);
+
+  // Derives the key and IV from the packet protection secret and sets those
+  // fields on the given QuicCrypter |*crypter|, but does not set the header
+  // protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be
+  // called before using |crypter|.
+  static void SetKeyAndIV(const EVP_MD* prf,
+                          const std::vector<uint8_t>& pp_secret,
+                          const ParsedQuicVersion& version,
+                          QuicCrypter* crypter);
+
+  // Derives the header protection key from the packet protection secret.
+  static std::vector<uint8_t> GenerateHeaderProtectionKey(
+      const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+      const ParsedQuicVersion& version, size_t out_len);
+
+  // Given a secret for key phase n, return the secret for phase n+1.
+  static std::vector<uint8_t> GenerateNextKeyPhaseSecret(
+      const EVP_MD* prf, const ParsedQuicVersion& version,
+      const std::vector<uint8_t>& current_secret);
+
+  // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key
+  // (to prevent network observers that are not aware of that QUIC version from
+  // making decisions based on the TLS handshake). This packet protection secret
+  // is derived from the connection ID in the client's Initial packet.
+  //
+  // This function takes that |connection_id| and creates the encrypter and
+  // decrypter (put in |*crypters|) to use for this packet protection, as well
+  // as setting the key and IV on those crypters. For older versions of QUIC
+  // that do not use the new IETF style ENCRYPTION_INITIAL obfuscators, this
+  // function puts a NullEncrypter and NullDecrypter in |*crypters|.
+  static void CreateInitialObfuscators(Perspective perspective,
+                                       ParsedQuicVersion version,
+                                       QuicConnectionId connection_id,
+                                       CrypterPair* crypters);
+
+  // IETF QUIC Retry packets carry a retry integrity tag to detect packet
+  // corruption and make it harder for an attacker to spoof. This function
+  // checks whether a given retry packet is valid.
+  static bool ValidateRetryIntegrityTag(ParsedQuicVersion version,
+                                        QuicConnectionId original_connection_id,
+                                        absl::string_view retry_without_tag,
+                                        absl::string_view integrity_tag);
+
+  // Generates the connection nonce. The nonce is formed as:
+  //   <4 bytes> current time
+  //   <8 bytes> |orbit| (or random if |orbit| is empty)
+  //   <20 bytes> random
+  static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
+                            absl::string_view orbit, std::string* nonce);
+
+  // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and
+  // |subkey_secret| (optional -- may be null) given the contents of
+  // |premaster_secret|, |client_nonce|, |server_nonce| and |hkdf_input|. |aead|
+  // determines which cipher will be used. |perspective| controls whether the
+  // server's keys are assigned to |encrypter| or |decrypter|. |server_nonce| is
+  // optional and, if non-empty, is mixed into the key derivation.
+  // |subkey_secret| will have the same length as |premaster_secret|.
+  //
+  // If |pre_shared_key| is non-empty, it is incorporated into the key
+  // derivation parameters.  If it is empty, the key derivation is unaltered.
+  //
+  // If the mode of |diversification| is NEVER, the the crypters will be
+  // configured to never perform key diversification. If the mode is
+  // NOW (which is only for servers, then the encrypter will be keyed via a
+  // two-step process that uses the nonce from |diversification|.
+  // If the mode is PENDING (which is only for servres), then the
+  // decrypter will only be keyed to a preliminary state: a call to
+  // |SetDiversificationNonce| with a diversification nonce will be needed to
+  // complete keying.
+  static bool DeriveKeys(const ParsedQuicVersion& version,
+                         absl::string_view premaster_secret, QuicTag aead,
+                         absl::string_view client_nonce,
+                         absl::string_view server_nonce,
+                         absl::string_view pre_shared_key,
+                         const std::string& hkdf_input, Perspective perspective,
+                         Diversification diversification, CrypterPair* crypters,
+                         std::string* subkey_secret);
+
+  // Computes the FNV-1a hash of the provided DER-encoded cert for use in the
+  // XLCT tag.
+  static uint64_t ComputeLeafCertHash(absl::string_view cert);
+
+  // Validates that |server_hello| is actually an SHLO message and that it is
+  // not part of a downgrade attack.
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateServerHello(
+      const CryptoHandshakeMessage& server_hello,
+      const ParsedQuicVersionVector& negotiated_versions,
+      std::string* error_details);
+
+  // Validates that the |server_versions| received do not indicate that the
+  // ServerHello is part of a downgrade attack. |negotiated_versions| must
+  // contain the list of versions received in the server's version negotiation
+  // packet (or be empty if no such packet was received).
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateServerHelloVersions(
+      const QuicVersionLabelVector& server_versions,
+      const ParsedQuicVersionVector& negotiated_versions,
+      std::string* error_details);
+
+  // Validates that |client_hello| is actually a CHLO and that this is not part
+  // of a downgrade attack.
+  // This includes verifiying versions and detecting downgrade attacks.
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateClientHello(
+      const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
+      const ParsedQuicVersionVector& supported_versions,
+      std::string* error_details);
+
+  // Validates that the |client_version| received does not indicate that a
+  // downgrade attack has occurred. |connection_version| is the version of the
+  // QuicConnection, and |supported_versions| is all versions that that
+  // QuicConnection supports.
+  //
+  // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error
+  // code and sets |error_details|.
+  static QuicErrorCode ValidateClientHelloVersion(
+      QuicVersionLabel client_version, ParsedQuicVersion connection_version,
+      const ParsedQuicVersionVector& supported_versions,
+      std::string* error_details);
+
+  // Validates that the chosen version from the version_information matches the
+  // version from the session. Returns true if they match, otherwise returns
+  // false and fills in |error_details|.
+  static bool ValidateChosenVersion(
+      const QuicVersionLabel& version_information_chosen_version,
+      const ParsedQuicVersion& session_version, std::string* error_details);
+
+  // Validates that there was no downgrade attack involving a version
+  // negotiation packet. This verifies that if the client was initially
+  // configured with |client_original_supported_versions| and it had received a
+  // version negotiation packet with |version_information_other_versions|, then
+  // it would have selected |session_version|. Returns true if they match (or if
+  // |client_original_supported_versions| is empty indicating no version
+  // negotiation packet was received), otherwise returns
+  // false and fills in |error_details|.
+  static bool ValidateServerVersions(
+      const QuicVersionLabelVector& version_information_other_versions,
+      const ParsedQuicVersion& session_version,
+      const ParsedQuicVersionVector& client_original_supported_versions,
+      std::string* error_details);
+
+  // Returns the name of the HandshakeFailureReason as a char*
+  static const char* HandshakeFailureReasonToString(
+      HandshakeFailureReason reason);
+
+  // Returns the name of an ssl_early_data_reason_t as a char*
+  static std::string EarlyDataReasonToString(ssl_early_data_reason_t reason);
+
+  // Returns a hash of the serialized |message|.
+  static std::string HashHandshakeMessage(const CryptoHandshakeMessage& message,
+                                          Perspective perspective);
+
+  // Wraps SSL_serialize_capabilities. Return nullptr if failed.
+  static bool GetSSLCapabilities(const SSL* ssl,
+                                 bssl::UniquePtr<uint8_t>* capabilities,
+                                 size_t* capabilities_len);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_UTILS_H_
diff --git a/quiche/quic/core/crypto/crypto_utils_test.cc b/quiche/quic/core/crypto/crypto_utils_test.cc
new file mode 100644
index 0000000..6452367
--- /dev/null
+++ b/quiche/quic/core/crypto/crypto_utils_test.cc
@@ -0,0 +1,262 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/crypto_utils.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class CryptoUtilsTest : public QuicTest {};
+
+TEST_F(CryptoUtilsTest, HandshakeFailureReasonToString) {
+  EXPECT_STREQ("HANDSHAKE_OK",
+               CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK));
+  EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_UNKNOWN_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_INVALID_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_NOT_UNIQUE_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_INVALID_ORBIT_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_INVALID_TIME_FAILURE));
+  EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT));
+  EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   CLIENT_NONCE_STRIKE_REGISTER_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_DECRYPTION_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_INVALID_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_NOT_UNIQUE_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_INVALID_TIME_FAILURE));
+  EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_NONCE_REQUIRED_FAILURE));
+  EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_CONFIG_INCHOATE_HELLO_FAILURE));
+  EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_INVALID_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_PARSE_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE));
+  EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE));
+  EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE",
+               CryptoUtils::HandshakeFailureReasonToString(
+                   INVALID_EXPECTED_LEAF_CERTIFICATE));
+  EXPECT_STREQ("MAX_FAILURE_REASON",
+               CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON));
+  EXPECT_STREQ(
+      "INVALID_HANDSHAKE_FAILURE_REASON",
+      CryptoUtils::HandshakeFailureReasonToString(
+          static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1)));
+}
+
+TEST_F(CryptoUtilsTest, AuthTagLengths) {
+  for (const auto& version : AllSupportedVersions()) {
+    for (QuicTag algo : {kAESG, kCC20}) {
+      SCOPED_TRACE(version);
+      std::unique_ptr<QuicEncrypter> encrypter(
+          QuicEncrypter::Create(version, algo));
+      size_t auth_tag_size = 12;
+      if (version.UsesInitialObfuscators()) {
+        auth_tag_size = 16;
+      }
+      EXPECT_EQ(encrypter->GetCiphertextSize(0), auth_tag_size);
+    }
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateChosenVersion) {
+  for (const ParsedQuicVersion& v1 : AllSupportedVersions()) {
+    for (const ParsedQuicVersion& v2 : AllSupportedVersions()) {
+      std::string error_details;
+      bool success = CryptoUtils::ValidateChosenVersion(
+          CreateQuicVersionLabel(v1), v2, &error_details);
+      EXPECT_EQ(success, v1 == v2);
+      EXPECT_EQ(success, error_details.empty());
+    }
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateServerVersionsNoVersionNegotiation) {
+  QuicVersionLabelVector version_information_other_versions;
+  ParsedQuicVersionVector client_original_supported_versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    std::string error_details;
+    EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
+        version_information_other_versions, version,
+        client_original_supported_versions, &error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateServerVersionsWithVersionNegotiation) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicVersionLabelVector version_information_other_versions{
+        CreateQuicVersionLabel(version)};
+    ParsedQuicVersionVector client_original_supported_versions{
+        ParsedQuicVersion::ReservedForNegotiation(), version};
+    std::string error_details;
+    EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
+        version_information_other_versions, version,
+        client_original_supported_versions, &error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+}
+
+TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) {
+  if (AllSupportedVersions().size() <= 1) {
+    // We are not vulnerable to downgrade if we only support one version.
+    return;
+  }
+  ParsedQuicVersion client_version = AllSupportedVersions().front();
+  ParsedQuicVersion server_version = AllSupportedVersions().back();
+  ASSERT_NE(client_version, server_version);
+  QuicVersionLabelVector version_information_other_versions{
+      CreateQuicVersionLabel(client_version)};
+  ParsedQuicVersionVector client_original_supported_versions{
+      ParsedQuicVersion::ReservedForNegotiation(), server_version};
+  std::string error_details;
+  EXPECT_FALSE(CryptoUtils::ValidateServerVersions(
+      version_information_other_versions, server_version,
+      client_original_supported_versions, &error_details));
+  EXPECT_FALSE(error_details.empty());
+}
+
+// Test that the library is using the correct labels for each version, and
+// therefore generating correct obfuscators, using the test vectors in appendix
+// A of each RFC or internet-draft.
+TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
+  // if the number of HTTP/3 QUIC versions has changed, we need to change the
+  // expected_keys hardcoded into this test. Regrettably, this is not a
+  // compile-time constant.
+  EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
+  const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
+                               0x14,
+                               static_cast<char>(0x9d),
+                               0x0b,
+                               0x16,
+                               0x62,
+                               static_cast<char>(0xab),
+                               static_cast<char>(0x87),
+                               0x1f,
+                               static_cast<char>(0xbe),
+                               0x63,
+                               static_cast<char>(0xc4),
+                               static_cast<char>(0x9b),
+                               0x5e,
+                               0x65,
+                               0x5a,
+                               0x5d};
+  const char v1_key[] = {// test vector from RFC 9001, A.1
+                         static_cast<char>(0xcf),
+                         0x3a,
+                         0x53,
+                         0x31,
+                         0x65,
+                         0x3c,
+                         0x36,
+                         0x4c,
+                         static_cast<char>(0x88),
+                         static_cast<char>(0xf0),
+                         static_cast<char>(0xf3),
+                         0x79,
+                         static_cast<char>(0xb6),
+                         0x06,
+                         0x7e,
+                         0x37};
+  const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01
+                            0x15,
+                            static_cast<char>(0xd5),
+                            static_cast<char>(0xb4),
+                            static_cast<char>(0xd9),
+                            static_cast<char>(0xa2),
+                            static_cast<char>(0xb8),
+                            static_cast<char>(0x91),
+                            0x6a,
+                            static_cast<char>(0xa3),
+                            static_cast<char>(0x9b),
+                            0x1b,
+                            static_cast<char>(0xfe),
+                            0x57,
+                            0x4d,
+                            0x2a,
+                            static_cast<char>(0xad)};
+  const char connection_id[] =  // test vector from both docs
+      {static_cast<char>(0x83),
+       static_cast<char>(0x94),
+       static_cast<char>(0xc8),
+       static_cast<char>(0xf0),
+       0x3e,
+       0x51,
+       0x57,
+       0x08};
+  const QuicConnectionId cid(connection_id, sizeof(connection_id));
+  const char* key_str;
+  size_t key_size;
+  for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
+    if (version == ParsedQuicVersion::Draft29()) {
+      key_str = draft_29_key;
+      key_size = sizeof(draft_29_key);
+    } else if (version == ParsedQuicVersion::RFCv1()) {
+      key_str = v1_key;
+      key_size = sizeof(v1_key);
+    } else {  // draft-ietf-quic-v2-01
+      key_str = v2_01_key;
+      key_size = sizeof(v2_01_key);
+    }
+    const absl::string_view expected_key{key_str, key_size};
+
+    CrypterPair crypters;
+    CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
+                                          &crypters);
+    EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/curve25519_key_exchange.cc b/quiche/quic/core/crypto/curve25519_key_exchange.cc
new file mode 100644
index 0000000..f84da2a
--- /dev/null
+++ b/quiche/quic/core/crypto/curve25519_key_exchange.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+
+#include <cstdint>
+#include <cstring>
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/curve25519.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+Curve25519KeyExchange::Curve25519KeyExchange() {}
+
+Curve25519KeyExchange::~Curve25519KeyExchange() {}
+
+// static
+std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
+    QuicRandom* rand) {
+  std::unique_ptr<Curve25519KeyExchange> result =
+      New(Curve25519KeyExchange::NewPrivateKey(rand));
+  QUIC_BUG_IF(quic_bug_12891_1, result == nullptr);
+  return result;
+}
+
+// static
+std::unique_ptr<Curve25519KeyExchange> Curve25519KeyExchange::New(
+    absl::string_view private_key) {
+  // We don't want to #include the BoringSSL headers in the public header file,
+  // so we use literals for the sizes of private_key_ and public_key_. Here we
+  // assert that those values are equal to the values from the BoringSSL
+  // header.
+  static_assert(
+      sizeof(Curve25519KeyExchange::private_key_) == X25519_PRIVATE_KEY_LEN,
+      "header out of sync");
+  static_assert(
+      sizeof(Curve25519KeyExchange::public_key_) == X25519_PUBLIC_VALUE_LEN,
+      "header out of sync");
+
+  if (private_key.size() != X25519_PRIVATE_KEY_LEN) {
+    return nullptr;
+  }
+
+  // Use absl::WrapUnique(new) instead of std::make_unique because
+  // Curve25519KeyExchange has a private constructor.
+  auto ka = absl::WrapUnique(new Curve25519KeyExchange);
+  memcpy(ka->private_key_, private_key.data(), X25519_PRIVATE_KEY_LEN);
+  X25519_public_from_private(ka->public_key_, ka->private_key_);
+  return ka;
+}
+
+// static
+std::string Curve25519KeyExchange::NewPrivateKey(QuicRandom* rand) {
+  uint8_t private_key[X25519_PRIVATE_KEY_LEN];
+  rand->RandBytes(private_key, sizeof(private_key));
+  return std::string(reinterpret_cast<char*>(private_key), sizeof(private_key));
+}
+
+bool Curve25519KeyExchange::CalculateSharedKeySync(
+    absl::string_view peer_public_value,
+    std::string* shared_key) const {
+  if (peer_public_value.size() != X25519_PUBLIC_VALUE_LEN) {
+    return false;
+  }
+
+  uint8_t result[X25519_PUBLIC_VALUE_LEN];
+  if (!X25519(result, private_key_,
+              reinterpret_cast<const uint8_t*>(peer_public_value.data()))) {
+    return false;
+  }
+
+  shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
+  return true;
+}
+
+absl::string_view Curve25519KeyExchange::public_value() const {
+  return absl::string_view(reinterpret_cast<const char*>(public_key_),
+                           sizeof(public_key_));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/curve25519_key_exchange.h b/quiche/quic/core/crypto/curve25519_key_exchange.h
new file mode 100644
index 0000000..34a49f9
--- /dev/null
+++ b/quiche/quic/core/crypto/curve25519_key_exchange.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// Curve25519KeyExchange implements a SynchronousKeyExchange using
+// elliptic-curve Diffie-Hellman on curve25519. See http://cr.yp.to/ecdh.html
+class QUIC_EXPORT_PRIVATE Curve25519KeyExchange
+    : public SynchronousKeyExchange {
+ public:
+  ~Curve25519KeyExchange() override;
+
+  // New generates a private key and then creates new key-exchange object.
+  static std::unique_ptr<Curve25519KeyExchange> New(QuicRandom* rand);
+
+  // New creates a new key-exchange object from a private key. If |private_key|
+  // is invalid, nullptr is returned.
+  static std::unique_ptr<Curve25519KeyExchange> New(
+      absl::string_view private_key);
+
+  // NewPrivateKey returns a private key, generated from |rand|, suitable for
+  // passing to |New|.
+  static std::string NewPrivateKey(QuicRandom* rand);
+
+  // SynchronousKeyExchange interface.
+  bool CalculateSharedKeySync(absl::string_view peer_public_value,
+                              std::string* shared_key) const override;
+  absl::string_view public_value() const override;
+  QuicTag type() const override { return kC255; }
+
+ private:
+  Curve25519KeyExchange();
+
+  uint8_t private_key_[32];
+  uint8_t public_key_[32];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_CURVE25519_KEY_EXCHANGE_H_
diff --git a/quiche/quic/core/crypto/curve25519_key_exchange_test.cc b/quiche/quic/core/crypto/curve25519_key_exchange_test.cc
new file mode 100644
index 0000000..551ee0e
--- /dev/null
+++ b/quiche/quic/core/crypto/curve25519_key_exchange_test.cc
@@ -0,0 +1,104 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class Curve25519KeyExchangeTest : public QuicTest {
+ public:
+  // Holds the result of a key exchange callback.
+  class TestCallbackResult {
+   public:
+    void set_ok(bool ok) { ok_ = ok; }
+    bool ok() { return ok_; }
+
+   private:
+    bool ok_ = false;
+  };
+
+  // Key exchange callback which sets the result into the specified
+  // TestCallbackResult.
+  class TestCallback : public AsynchronousKeyExchange::Callback {
+   public:
+    TestCallback(TestCallbackResult* result) : result_(result) {}
+    virtual ~TestCallback() = default;
+
+    void Run(bool ok) { result_->set_ok(ok); }
+
+   private:
+    TestCallbackResult* result_;
+  };
+};
+
+// SharedKey just tests that the basic key exchange identity holds: that both
+// parties end up with the same key.
+TEST_F(Curve25519KeyExchangeTest, SharedKey) {
+  QuicRandom* const rand = QuicRandom::GetInstance();
+
+  for (int i = 0; i < 5; i++) {
+    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
+    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
+
+    std::unique_ptr<Curve25519KeyExchange> alice(
+        Curve25519KeyExchange::New(alice_key));
+    std::unique_ptr<Curve25519KeyExchange> bob(
+        Curve25519KeyExchange::New(bob_key));
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
+    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
+    ASSERT_EQ(alice_shared, bob_shared);
+  }
+}
+
+// SharedKeyAsync just tests that the basic asynchronous key exchange identity
+// holds: that both parties end up with the same key.
+TEST_F(Curve25519KeyExchangeTest, SharedKeyAsync) {
+  QuicRandom* const rand = QuicRandom::GetInstance();
+
+  for (int i = 0; i < 5; i++) {
+    const std::string alice_key(Curve25519KeyExchange::NewPrivateKey(rand));
+    const std::string bob_key(Curve25519KeyExchange::NewPrivateKey(rand));
+
+    std::unique_ptr<Curve25519KeyExchange> alice(
+        Curve25519KeyExchange::New(alice_key));
+    std::unique_ptr<Curve25519KeyExchange> bob(
+        Curve25519KeyExchange::New(bob_key));
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    TestCallbackResult alice_result;
+    ASSERT_FALSE(alice_result.ok());
+    alice->CalculateSharedKeyAsync(
+        bob_public, &alice_shared,
+        std::make_unique<TestCallback>(&alice_result));
+    ASSERT_TRUE(alice_result.ok());
+    TestCallbackResult bob_result;
+    ASSERT_FALSE(bob_result.ok());
+    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
+                                 std::make_unique<TestCallback>(&bob_result));
+    ASSERT_TRUE(bob_result.ok());
+    ASSERT_EQ(alice_shared, bob_shared);
+    ASSERT_NE(0u, alice_shared.length());
+    ASSERT_NE(0u, bob_shared.length());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/key_exchange.cc b/quiche/quic/core/crypto/key_exchange.cc
new file mode 100644
index 0000000..4a5947b
--- /dev/null
+++ b/quiche/quic/core/crypto/key_exchange.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    absl::string_view private_key) {
+  switch (type) {
+    case kC255:
+      return Curve25519KeyExchange::New(private_key);
+    case kP256:
+      return P256KeyExchange::New(private_key);
+    default:
+      QUIC_BUG(quic_bug_10712_1)
+          << "Unknown key exchange method: " << QuicTagToString(type);
+      return nullptr;
+  }
+}
+
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    QuicRandom* rand) {
+  switch (type) {
+    case kC255:
+      return Curve25519KeyExchange::New(rand);
+    case kP256:
+      return P256KeyExchange::New();
+    default:
+      QUIC_BUG(quic_bug_10712_2)
+          << "Unknown key exchange method: " << QuicTagToString(type);
+      return nullptr;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/key_exchange.h b/quiche/quic/core/crypto/key_exchange.h
new file mode 100644
index 0000000..74c44ee
--- /dev/null
+++ b/quiche/quic/core/crypto/key_exchange.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// Interface for a Diffie-Hellman key exchange with an asynchronous interface.
+// This allows for implementations which hold the private key locally, as well
+// as ones which make an RPC to an external key-exchange service.
+class QUIC_EXPORT_PRIVATE AsynchronousKeyExchange {
+ public:
+  virtual ~AsynchronousKeyExchange() = default;
+
+  // Callback base class for receiving the results of an async call to
+  // CalculateSharedKeys.
+  class QUIC_EXPORT_PRIVATE Callback {
+   public:
+    Callback() = default;
+    virtual ~Callback() = default;
+
+    // Invoked upon completion of CalculateSharedKeysAsync.
+    //
+    // |ok| indicates whether the operation completed successfully.  If false,
+    // then the value pointed to by |shared_key| passed in to
+    // CalculateSharedKeyAsync is undefined.
+    virtual void Run(bool ok) = 0;
+
+   private:
+    Callback(const Callback&) = delete;
+    Callback& operator=(const Callback&) = delete;
+  };
+
+  // CalculateSharedKey computes the shared key between a private key which is
+  // conceptually owned by this object (though it may not be physically located
+  // in this process) and a public value from the peer.  Callers should expect
+  // that |callback| might be invoked synchronously.  Results will be written
+  // into |*shared_key|.
+  virtual void CalculateSharedKeyAsync(
+      absl::string_view peer_public_value,
+      std::string* shared_key,
+      std::unique_ptr<Callback> callback) const = 0;
+
+  // Tag indicating the key-exchange algorithm this object will use.
+  virtual QuicTag type() const = 0;
+};
+
+// Interface for a Diffie-Hellman key exchange with both synchronous and
+// asynchronous interfaces.  Only implementations which hold the private key
+// locally should implement this interface.
+class QUIC_EXPORT_PRIVATE SynchronousKeyExchange
+    : public AsynchronousKeyExchange {
+ public:
+  virtual ~SynchronousKeyExchange() = default;
+
+  // AyncKeyExchange API.  Note that this method is marked 'final.'  Subclasses
+  // should implement CalculateSharedKeySync only.
+  void CalculateSharedKeyAsync(absl::string_view peer_public_value,
+                               std::string* shared_key,
+                               std::unique_ptr<Callback> callback) const final {
+    const bool ok = CalculateSharedKeySync(peer_public_value, shared_key);
+    callback->Run(ok);
+  }
+
+  // CalculateSharedKey computes the shared key between a local private key and
+  // a public value from the peer.  Results will be written into |*shared_key|.
+  virtual bool CalculateSharedKeySync(absl::string_view peer_public_value,
+                                      std::string* shared_key) const = 0;
+
+  // public_value returns the local public key which can be sent to a peer in
+  // order to complete a key exchange. The returned absl::string_view is
+  // a reference to a member of this object and is only valid for as long as it
+  // exists.
+  virtual absl::string_view public_value() const = 0;
+};
+
+// Create a SynchronousKeyExchange object which will use a keypair generated
+// from |private_key|, and a key-exchange algorithm specified by |type|, which
+// must be one of {kC255, kC256}.  Returns nullptr if |private_key| or |type| is
+// invalid.
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    absl::string_view private_key);
+
+// Create a SynchronousKeyExchange object which will use a keypair generated
+// from |rand|, and a key-exchange algorithm specified by |type|, which must be
+// one of {kC255, kC256}.  Returns nullptr if |type| is invalid.
+std::unique_ptr<SynchronousKeyExchange> CreateLocalSynchronousKeyExchange(
+    QuicTag type,
+    QuicRandom* rand);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_KEY_EXCHANGE_H_
diff --git a/quiche/quic/core/crypto/null_decrypter.cc b/quiche/quic/core/crypto/null_decrypter.cc
new file mode 100644
index 0000000..5287ce9
--- /dev/null
+++ b/quiche/quic/core/crypto/null_decrypter.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/null_decrypter.h"
+
+#include <cstdint>
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+NullDecrypter::NullDecrypter(Perspective perspective)
+    : perspective_(perspective) {}
+
+bool NullDecrypter::SetKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  return nonce_prefix.empty();
+}
+
+bool NullDecrypter::SetIV(absl::string_view iv) {
+  return iv.empty();
+}
+
+bool NullDecrypter::SetHeaderProtectionKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullDecrypter::SetPreliminaryKey(absl::string_view /*key*/) {
+  QUIC_BUG(quic_bug_10652_1) << "Should not be called";
+  return false;
+}
+
+bool NullDecrypter::SetDiversificationNonce(
+    const DiversificationNonce& /*nonce*/) {
+  QUIC_BUG(quic_bug_10652_2) << "Should not be called";
+  return true;
+}
+
+bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/,
+                                  absl::string_view associated_data,
+                                  absl::string_view ciphertext,
+                                  char* output,
+                                  size_t* output_length,
+                                  size_t max_output_length) {
+  QuicDataReader reader(ciphertext.data(), ciphertext.length(),
+                        quiche::HOST_BYTE_ORDER);
+  absl::uint128 hash;
+
+  if (!ReadHash(&reader, &hash)) {
+    return false;
+  }
+
+  absl::string_view plaintext = reader.ReadRemainingPayload();
+  if (plaintext.length() > max_output_length) {
+    QUIC_BUG(quic_bug_10652_3)
+        << "Output buffer must be larger than the plaintext.";
+    return false;
+  }
+  if (hash != ComputeHash(associated_data, plaintext)) {
+    return false;
+  }
+  // Copy the plaintext to output.
+  memcpy(output, plaintext.data(), plaintext.length());
+  *output_length = plaintext.length();
+  return true;
+}
+
+std::string NullDecrypter::GenerateHeaderProtectionMask(
+    QuicDataReader* /*sample_reader*/) {
+  return std::string(5, 0);
+}
+
+size_t NullDecrypter::GetKeySize() const {
+  return 0;
+}
+
+size_t NullDecrypter::GetNoncePrefixSize() const {
+  return 0;
+}
+
+size_t NullDecrypter::GetIVSize() const {
+  return 0;
+}
+
+absl::string_view NullDecrypter::GetKey() const {
+  return absl::string_view();
+}
+
+absl::string_view NullDecrypter::GetNoncePrefix() const {
+  return absl::string_view();
+}
+
+uint32_t NullDecrypter::cipher_id() const {
+  return 0;
+}
+
+QuicPacketCount NullDecrypter::GetIntegrityLimit() const {
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+bool NullDecrypter::ReadHash(QuicDataReader* reader, absl::uint128* hash) {
+  uint64_t lo;
+  uint32_t hi;
+  if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
+    return false;
+  }
+  *hash = absl::MakeUint128(hi, lo);
+  return true;
+}
+
+absl::uint128 NullDecrypter::ComputeHash(const absl::string_view data1,
+                                         const absl::string_view data2) const {
+  absl::uint128 correct_hash;
+  if (perspective_ == Perspective::IS_CLIENT) {
+    // Peer is a server.
+    correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Server");
+  } else {
+    // Peer is a client.
+    correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Client");
+  }
+  absl::uint128 mask = absl::MakeUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
+  mask <<= 96;
+  correct_hash &= ~mask;
+  return correct_hash;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/null_decrypter.h b/quiche/quic/core/crypto/null_decrypter.h
new file mode 100644
index 0000000..05e1103
--- /dev/null
+++ b/quiche/quic/core/crypto/null_decrypter.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicDataReader;
+
+// A NullDecrypter is a QuicDecrypter used before a crypto negotiation
+// has occurred.  It does not actually decrypt the payload, but does
+// verify a hash (fnv128) over both the payload and associated data.
+class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
+ public:
+  explicit NullDecrypter(Perspective perspective);
+  NullDecrypter(const NullDecrypter&) = delete;
+  NullDecrypter& operator=(const NullDecrypter&) = delete;
+  ~NullDecrypter() override {}
+
+  // QuicDecrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  bool SetPreliminaryKey(absl::string_view key) override;
+  bool SetDiversificationNonce(const DiversificationNonce& nonce) override;
+  bool DecryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view ciphertext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+  uint32_t cipher_id() const override;
+  QuicPacketCount GetIntegrityLimit() const override;
+
+ private:
+  bool ReadHash(QuicDataReader* reader, absl::uint128* hash);
+  absl::uint128 ComputeHash(absl::string_view data1,
+                            absl::string_view data2) const;
+
+  Perspective perspective_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_NULL_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/null_decrypter_test.cc b/quiche/quic/core/crypto/null_decrypter_test.cc
new file mode 100644
index 0000000..ad06bea
--- /dev/null
+++ b/quiche/quic/core/crypto/null_decrypter_test.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class NullDecrypterTest : public QuicTestWithParam<bool> {};
+
+TEST_F(NullDecrypterTest, DecryptClient) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x97,
+      0xdc,
+      0x27,
+      0x2f,
+      0x18,
+      0xa8,
+      0x56,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0xd0,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_SERVER);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_TRUE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+  EXPECT_LT(0u, length);
+  EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
+}
+
+TEST_F(NullDecrypterTest, DecryptServer) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x63,
+      0x5e,
+      0x08,
+      0x03,
+      0x32,
+      0x80,
+      0x8f,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0x1a,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_CLIENT);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_TRUE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+  EXPECT_LT(0u, length);
+  EXPECT_EQ("goodbye!", absl::string_view(buffer, length));
+}
+
+TEST_F(NullDecrypterTest, BadHash) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x46,
+      0x11,
+      0xea,
+      0x5f,
+      0xcf,
+      0x1d,
+      0x66,
+      0x5b,
+      0xba,
+      0xf0,
+      0xbc,
+      0xfd,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_CLIENT);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_FALSE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+}
+
+TEST_F(NullDecrypterTest, ShortInput) {
+  unsigned char expected[] = {
+      // fnv hash (truncated)
+      0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc,
+  };
+  const char* data = reinterpret_cast<const char*>(expected);
+  size_t len = ABSL_ARRAYSIZE(expected);
+  NullDecrypter decrypter(Perspective::IS_CLIENT);
+  char buffer[256];
+  size_t length = 0;
+  ASSERT_FALSE(decrypter.DecryptPacket(
+      0, "hello world!", absl::string_view(data, len), buffer, &length, 256));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/null_encrypter.cc b/quiche/quic/core/crypto/null_encrypter.cc
new file mode 100644
index 0000000..8df815b
--- /dev/null
+++ b/quiche/quic/core/crypto/null_encrypter.cc
@@ -0,0 +1,103 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+const size_t kHashSizeShort = 12;  // size of uint128 serialized short
+
+NullEncrypter::NullEncrypter(Perspective perspective)
+    : perspective_(perspective) {}
+
+bool NullEncrypter::SetKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullEncrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
+  return nonce_prefix.empty();
+}
+
+bool NullEncrypter::SetIV(absl::string_view iv) {
+  return iv.empty();
+}
+
+bool NullEncrypter::SetHeaderProtectionKey(absl::string_view key) {
+  return key.empty();
+}
+
+bool NullEncrypter::EncryptPacket(uint64_t /*packet_number*/,
+                                  absl::string_view associated_data,
+                                  absl::string_view plaintext,
+                                  char* output,
+                                  size_t* output_length,
+                                  size_t max_output_length) {
+  const size_t len = plaintext.size() + GetHashLength();
+  if (max_output_length < len) {
+    return false;
+  }
+  absl::uint128 hash;
+  if (perspective_ == Perspective::IS_SERVER) {
+    hash =
+        QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Server");
+  } else {
+    hash =
+        QuicUtils::FNV1a_128_Hash_Three(associated_data, plaintext, "Client");
+  }
+  // TODO(ianswett): memmove required for in place encryption.  Placing the
+  // hash at the end would allow use of memcpy, doing nothing for in place.
+  memmove(output + GetHashLength(), plaintext.data(), plaintext.length());
+  QuicUtils::SerializeUint128Short(hash,
+                                   reinterpret_cast<unsigned char*>(output));
+  *output_length = len;
+  return true;
+}
+
+std::string NullEncrypter::GenerateHeaderProtectionMask(
+    absl::string_view /*sample*/) {
+  return std::string(5, 0);
+}
+
+size_t NullEncrypter::GetKeySize() const {
+  return 0;
+}
+
+size_t NullEncrypter::GetNoncePrefixSize() const {
+  return 0;
+}
+
+size_t NullEncrypter::GetIVSize() const {
+  return 0;
+}
+
+size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
+  return ciphertext_size - std::min(ciphertext_size, GetHashLength());
+}
+
+size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const {
+  return plaintext_size + GetHashLength();
+}
+
+QuicPacketCount NullEncrypter::GetConfidentialityLimit() const {
+  return std::numeric_limits<QuicPacketCount>::max();
+}
+
+absl::string_view NullEncrypter::GetKey() const {
+  return absl::string_view();
+}
+
+absl::string_view NullEncrypter::GetNoncePrefix() const {
+  return absl::string_view();
+}
+
+size_t NullEncrypter::GetHashLength() const {
+  return kHashSizeShort;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/null_encrypter.h b/quiche/quic/core/crypto/null_encrypter.h
new file mode 100644
index 0000000..cdcf66c
--- /dev/null
+++ b/quiche/quic/core/crypto/null_encrypter.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
+
+#include <cstddef>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A NullEncrypter is a QuicEncrypter used before a crypto negotiation
+// has occurred.  It does not actually encrypt the payload, but does
+// generate a MAC (fnv128) over both the payload and associated data.
+class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
+ public:
+  explicit NullEncrypter(Perspective perspective);
+  NullEncrypter(const NullEncrypter&) = delete;
+  NullEncrypter& operator=(const NullEncrypter&) = delete;
+  ~NullEncrypter() override {}
+
+  // QuicEncrypter implementation
+  bool SetKey(absl::string_view key) override;
+  bool SetNoncePrefix(absl::string_view nonce_prefix) override;
+  bool SetIV(absl::string_view iv) override;
+  bool SetHeaderProtectionKey(absl::string_view key) override;
+  bool EncryptPacket(uint64_t packet_number,
+                     absl::string_view associated_data,
+                     absl::string_view plaintext,
+                     char* output,
+                     size_t* output_length,
+                     size_t max_output_length) override;
+  std::string GenerateHeaderProtectionMask(absl::string_view sample) override;
+  size_t GetKeySize() const override;
+  size_t GetNoncePrefixSize() const override;
+  size_t GetIVSize() const override;
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
+  size_t GetCiphertextSize(size_t plaintext_size) const override;
+  QuicPacketCount GetConfidentialityLimit() const override;
+  absl::string_view GetKey() const override;
+  absl::string_view GetNoncePrefix() const override;
+
+ private:
+  size_t GetHashLength() const;
+
+  Perspective perspective_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_NULL_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/null_encrypter_test.cc b/quiche/quic/core/crypto/null_encrypter_test.cc
new file mode 100644
index 0000000..26a143e
--- /dev/null
+++ b/quiche/quic/core/crypto/null_encrypter_test.cc
@@ -0,0 +1,102 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class NullEncrypterTest : public QuicTestWithParam<bool> {};
+
+TEST_F(NullEncrypterTest, EncryptClient) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x97,
+      0xdc,
+      0x27,
+      0x2f,
+      0x18,
+      0xa8,
+      0x56,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0xd0,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  char encrypted[256];
+  size_t encrypted_len = 0;
+  NullEncrypter encrypter(Perspective::IS_CLIENT);
+  ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
+                                      &encrypted_len, 256));
+  quiche::test::CompareCharArraysWithHexError(
+      "encrypted data", encrypted, encrypted_len,
+      reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
+}
+
+TEST_F(NullEncrypterTest, EncryptServer) {
+  unsigned char expected[] = {
+      // fnv hash
+      0x63,
+      0x5e,
+      0x08,
+      0x03,
+      0x32,
+      0x80,
+      0x8f,
+      0x73,
+      0xdf,
+      0x8d,
+      0x1d,
+      0x1a,
+      // payload
+      'g',
+      'o',
+      'o',
+      'd',
+      'b',
+      'y',
+      'e',
+      '!',
+  };
+  char encrypted[256];
+  size_t encrypted_len = 0;
+  NullEncrypter encrypter(Perspective::IS_SERVER);
+  ASSERT_TRUE(encrypter.EncryptPacket(0, "hello world!", "goodbye!", encrypted,
+                                      &encrypted_len, 256));
+  quiche::test::CompareCharArraysWithHexError(
+      "encrypted data", encrypted, encrypted_len,
+      reinterpret_cast<const char*>(expected), ABSL_ARRAYSIZE(expected));
+}
+
+TEST_F(NullEncrypterTest, GetMaxPlaintextSize) {
+  NullEncrypter encrypter(Perspective::IS_CLIENT);
+  EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+  EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+  EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+  EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11));
+}
+
+TEST_F(NullEncrypterTest, GetCiphertextSize) {
+  NullEncrypter encrypter(Perspective::IS_CLIENT);
+  EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+  EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+  EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/p256_key_exchange.cc b/quiche/quic/core/crypto/p256_key_exchange.cc
new file mode 100644
index 0000000..3cff503
--- /dev/null
+++ b/quiche/quic/core/crypto/p256_key_exchange.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+
+#include <cstdint>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ecdh.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+P256KeyExchange::P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
+                                 const uint8_t* public_key)
+    : private_key_(std::move(private_key)) {
+  memcpy(public_key_, public_key, sizeof(public_key_));
+}
+
+P256KeyExchange::~P256KeyExchange() {}
+
+// static
+std::unique_ptr<P256KeyExchange> P256KeyExchange::New() {
+  return New(P256KeyExchange::NewPrivateKey());
+}
+
+// static
+std::unique_ptr<P256KeyExchange> P256KeyExchange::New(absl::string_view key) {
+  if (key.empty()) {
+    QUIC_DLOG(INFO) << "Private key is empty";
+    return nullptr;
+  }
+
+  const uint8_t* keyp = reinterpret_cast<const uint8_t*>(key.data());
+  bssl::UniquePtr<EC_KEY> private_key(
+      d2i_ECPrivateKey(nullptr, &keyp, key.size()));
+  if (!private_key.get() || !EC_KEY_check_key(private_key.get())) {
+    QUIC_DLOG(INFO) << "Private key is invalid.";
+    return nullptr;
+  }
+
+  uint8_t public_key[kUncompressedP256PointBytes];
+  if (EC_POINT_point2oct(EC_KEY_get0_group(private_key.get()),
+                         EC_KEY_get0_public_key(private_key.get()),
+                         POINT_CONVERSION_UNCOMPRESSED, public_key,
+                         sizeof(public_key), nullptr) != sizeof(public_key)) {
+    QUIC_DLOG(INFO) << "Can't get public key.";
+    return nullptr;
+  }
+
+  return absl::WrapUnique(
+      new P256KeyExchange(std::move(private_key), public_key));
+}
+
+// static
+std::string P256KeyExchange::NewPrivateKey() {
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  if (!key.get() || !EC_KEY_generate_key(key.get())) {
+    QUIC_DLOG(INFO) << "Can't generate a new private key.";
+    return std::string();
+  }
+
+  int key_len = i2d_ECPrivateKey(key.get(), nullptr);
+  if (key_len <= 0) {
+    QUIC_DLOG(INFO) << "Can't convert private key to string";
+    return std::string();
+  }
+  std::unique_ptr<uint8_t[]> private_key(new uint8_t[key_len]);
+  uint8_t* keyp = private_key.get();
+  if (!i2d_ECPrivateKey(key.get(), &keyp)) {
+    QUIC_DLOG(INFO) << "Can't convert private key to string.";
+    return std::string();
+  }
+  return std::string(reinterpret_cast<char*>(private_key.get()), key_len);
+}
+
+bool P256KeyExchange::CalculateSharedKeySync(
+    absl::string_view peer_public_value,
+    std::string* shared_key) const {
+  if (peer_public_value.size() != kUncompressedP256PointBytes) {
+    QUIC_DLOG(INFO) << "Peer public value is invalid";
+    return false;
+  }
+
+  bssl::UniquePtr<EC_POINT> point(
+      EC_POINT_new(EC_KEY_get0_group(private_key_.get())));
+  if (!point.get() ||
+      !EC_POINT_oct2point(/* also test if point is on curve */
+                          EC_KEY_get0_group(private_key_.get()), point.get(),
+                          reinterpret_cast<const uint8_t*>(
+                              peer_public_value.data()),
+                          peer_public_value.size(), nullptr)) {
+    QUIC_DLOG(INFO) << "Can't convert peer public value to curve point.";
+    return false;
+  }
+
+  uint8_t result[kP256FieldBytes];
+  if (ECDH_compute_key(result, sizeof(result), point.get(), private_key_.get(),
+                       nullptr) != sizeof(result)) {
+    QUIC_DLOG(INFO) << "Can't compute ECDH shared key.";
+    return false;
+  }
+
+  shared_key->assign(reinterpret_cast<char*>(result), sizeof(result));
+  return true;
+}
+
+absl::string_view P256KeyExchange::public_value() const {
+  return absl::string_view(reinterpret_cast<const char*>(public_key_),
+                           sizeof(public_key_));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/p256_key_exchange.h b/quiche/quic/core/crypto/p256_key_exchange.h
new file mode 100644
index 0000000..4b23973
--- /dev/null
+++ b/quiche/quic/core/crypto/p256_key_exchange.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// P256KeyExchange implements a SynchronousKeyExchange using elliptic-curve
+// Diffie-Hellman on NIST P-256.
+class QUIC_EXPORT_PRIVATE P256KeyExchange : public SynchronousKeyExchange {
+ public:
+  ~P256KeyExchange() override;
+
+  // New generates a private key and then creates new key-exchange object.
+  static std::unique_ptr<P256KeyExchange> New();
+
+  // New creates a new key-exchange object from a private key. If |private_key|
+  // is invalid, nullptr is returned.
+  static std::unique_ptr<P256KeyExchange> New(absl::string_view private_key);
+
+  // NewPrivateKey returns a private key, suitable for passing to |New|.
+  // If |NewPrivateKey| can't generate a private key, it returns an empty
+  // string.
+  static std::string NewPrivateKey();
+
+  // SynchronousKeyExchange interface.
+  bool CalculateSharedKeySync(absl::string_view peer_public_value,
+                              std::string* shared_key) const override;
+  absl::string_view public_value() const override;
+  QuicTag type() const override { return kP256; }
+
+ private:
+  enum {
+    // A P-256 field element consists of 32 bytes.
+    kP256FieldBytes = 32,
+    // A P-256 point in uncompressed form consists of 0x04 (to denote
+    // that the point is uncompressed) followed by two, 32-byte field
+    // elements.
+    kUncompressedP256PointBytes = 1 + 2 * kP256FieldBytes,
+    // The first byte in an uncompressed P-256 point.
+    kUncompressedECPointForm = 0x04,
+  };
+
+  // P256KeyExchange wraps |private_key|, and expects |public_key| consists of
+  // |kUncompressedP256PointBytes| bytes.
+  P256KeyExchange(bssl::UniquePtr<EC_KEY> private_key,
+                  const uint8_t* public_key);
+  P256KeyExchange(const P256KeyExchange&) = delete;
+  P256KeyExchange& operator=(const P256KeyExchange&) = delete;
+
+  bssl::UniquePtr<EC_KEY> private_key_;
+  // The public key stored as an uncompressed P-256 point.
+  uint8_t public_key_[kUncompressedP256PointBytes];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_P256_KEY_EXCHANGE_H_
diff --git a/quiche/quic/core/crypto/p256_key_exchange_test.cc b/quiche/quic/core/crypto/p256_key_exchange_test.cc
new file mode 100644
index 0000000..c9bc7d3
--- /dev/null
+++ b/quiche/quic/core/crypto/p256_key_exchange_test.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class P256KeyExchangeTest : public QuicTest {
+ public:
+  // Holds the result of a key exchange callback.
+  class TestCallbackResult {
+   public:
+    void set_ok(bool ok) { ok_ = ok; }
+    bool ok() { return ok_; }
+
+   private:
+    bool ok_ = false;
+  };
+
+  // Key exchange callback which sets the result into the specified
+  // TestCallbackResult.
+  class TestCallback : public AsynchronousKeyExchange::Callback {
+   public:
+    TestCallback(TestCallbackResult* result) : result_(result) {}
+    virtual ~TestCallback() = default;
+
+    void Run(bool ok) { result_->set_ok(ok); }
+
+   private:
+    TestCallbackResult* result_;
+  };
+};
+
+// SharedKeyAsync just tests that the basic asynchronous key exchange identity
+// holds: that both parties end up with the same key.
+TEST_F(P256KeyExchangeTest, SharedKey) {
+  for (int i = 0; i < 5; i++) {
+    std::string alice_private(P256KeyExchange::NewPrivateKey());
+    std::string bob_private(P256KeyExchange::NewPrivateKey());
+
+    ASSERT_FALSE(alice_private.empty());
+    ASSERT_FALSE(bob_private.empty());
+    ASSERT_NE(alice_private, bob_private);
+
+    std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
+    std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
+
+    ASSERT_TRUE(alice != nullptr);
+    ASSERT_TRUE(bob != nullptr);
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    ASSERT_TRUE(alice->CalculateSharedKeySync(bob_public, &alice_shared));
+    ASSERT_TRUE(bob->CalculateSharedKeySync(alice_public, &bob_shared));
+    ASSERT_EQ(alice_shared, bob_shared);
+  }
+}
+
+// SharedKey just tests that the basic key exchange identity holds: that both
+// parties end up with the same key.
+TEST_F(P256KeyExchangeTest, AsyncSharedKey) {
+  for (int i = 0; i < 5; i++) {
+    std::string alice_private(P256KeyExchange::NewPrivateKey());
+    std::string bob_private(P256KeyExchange::NewPrivateKey());
+
+    ASSERT_FALSE(alice_private.empty());
+    ASSERT_FALSE(bob_private.empty());
+    ASSERT_NE(alice_private, bob_private);
+
+    std::unique_ptr<P256KeyExchange> alice(P256KeyExchange::New(alice_private));
+    std::unique_ptr<P256KeyExchange> bob(P256KeyExchange::New(bob_private));
+
+    ASSERT_TRUE(alice != nullptr);
+    ASSERT_TRUE(bob != nullptr);
+
+    const absl::string_view alice_public(alice->public_value());
+    const absl::string_view bob_public(bob->public_value());
+
+    std::string alice_shared, bob_shared;
+    TestCallbackResult alice_result;
+    ASSERT_FALSE(alice_result.ok());
+    alice->CalculateSharedKeyAsync(
+        bob_public, &alice_shared,
+        std::make_unique<TestCallback>(&alice_result));
+    ASSERT_TRUE(alice_result.ok());
+    TestCallbackResult bob_result;
+    ASSERT_FALSE(bob_result.ok());
+    bob->CalculateSharedKeyAsync(alice_public, &bob_shared,
+                                 std::make_unique<TestCallback>(&bob_result));
+    ASSERT_TRUE(bob_result.ok());
+    ASSERT_EQ(alice_shared, bob_shared);
+    ASSERT_NE(0u, alice_shared.length());
+    ASSERT_NE(0u, bob_shared.length());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_source.cc b/quiche/quic/core/crypto/proof_source.cc
new file mode 100644
index 0000000..95fb446
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/proof_source.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+CryptoBuffers::~CryptoBuffers() {
+  for (size_t i = 0; i < value.size(); i++) {
+    CRYPTO_BUFFER_free(value[i]);
+  }
+}
+
+ProofSource::Chain::Chain(const std::vector<std::string>& certs)
+    : certs(certs) {}
+
+ProofSource::Chain::~Chain() {}
+
+CryptoBuffers ProofSource::Chain::ToCryptoBuffers() const {
+  CryptoBuffers crypto_buffers;
+  crypto_buffers.value.reserve(certs.size());
+  for (size_t i = 0; i < certs.size(); i++) {
+    crypto_buffers.value.push_back(
+        CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(certs[i].data()),
+                          certs[i].length(), nullptr));
+  }
+  return crypto_buffers;
+}
+
+bool ValidateCertAndKey(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const CertificatePrivateKey& key) {
+  if (chain.get() == nullptr || chain->certs.empty()) {
+    QUIC_BUG(quic_proof_source_empty_chain) << "Certificate chain is empty";
+    return false;
+  }
+
+  std::unique_ptr<CertificateView> leaf =
+      CertificateView::ParseSingleCertificate(chain->certs[0]);
+  if (leaf == nullptr) {
+    QUIC_BUG(quic_proof_source_unparsable_leaf_cert)
+        << "Unabled to parse leaf certificate";
+    return false;
+  }
+
+  if (!key.MatchesPublicKey(*leaf)) {
+    QUIC_BUG(quic_proof_source_key_mismatch)
+        << "Private key does not match the leaf certificate";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_source.h b/quiche/quic/core/crypto/proof_source.h
new file mode 100644
index 0000000..e725409
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source.h
@@ -0,0 +1,355 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/quic_crypto_proof.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+namespace test {
+class FakeProofSourceHandle;
+}  // namespace test
+
+// CryptoBuffers is a RAII class to own a std::vector<CRYPTO_BUFFER*> and the
+// buffers the elements point to.
+struct QUIC_EXPORT_PRIVATE CryptoBuffers {
+  CryptoBuffers() = default;
+  CryptoBuffers(const CryptoBuffers&) = delete;
+  CryptoBuffers(CryptoBuffers&&) = default;
+  ~CryptoBuffers();
+
+  std::vector<CRYPTO_BUFFER*> value;
+};
+
+// ProofSource is an interface by which a QUIC server can obtain certificate
+// chains and signatures that prove its identity.
+class QUIC_EXPORT_PRIVATE ProofSource {
+ public:
+  // Chain is a reference-counted wrapper for a vector of stringified
+  // certificates.
+  struct QUIC_EXPORT_PRIVATE Chain : public quiche::QuicheReferenceCounted {
+    explicit Chain(const std::vector<std::string>& certs);
+    Chain(const Chain&) = delete;
+    Chain& operator=(const Chain&) = delete;
+
+    CryptoBuffers ToCryptoBuffers() const;
+
+    const std::vector<std::string> certs;
+
+   protected:
+    ~Chain() override;
+  };
+
+  // Details is an abstract class which acts as a container for any
+  // implementation-specific details that a ProofSource wants to return.
+  class QUIC_EXPORT_PRIVATE Details {
+   public:
+    virtual ~Details() {}
+  };
+
+  // Callback base class for receiving the results of an async call to GetProof.
+  class QUIC_EXPORT_PRIVATE Callback {
+   public:
+    Callback() {}
+    virtual ~Callback() {}
+
+    // Invoked upon completion of GetProof.
+    //
+    // |ok| indicates whether the operation completed successfully.  If false,
+    // the values of the remaining three arguments are undefined.
+    //
+    // |chain| is a reference-counted pointer to an object representing the
+    // certificate chain.
+    //
+    // |signature| contains the signature of the server config.
+    //
+    // |leaf_cert_sct| holds the signed timestamp (RFC6962) of the leaf cert.
+    //
+    // |details| holds a pointer to an object representing the statistics, if
+    // any, gathered during the operation of GetProof.  If no stats are
+    // available, this will be nullptr.
+    virtual void Run(bool ok,
+                     const quiche::QuicheReferenceCountedPointer<Chain>& chain,
+                     const QuicCryptoProof& proof,
+                     std::unique_ptr<Details> details) = 0;
+
+   private:
+    Callback(const Callback&) = delete;
+    Callback& operator=(const Callback&) = delete;
+  };
+
+  // Base class for signalling the completion of a call to ComputeTlsSignature.
+  class QUIC_EXPORT_PRIVATE SignatureCallback {
+   public:
+    SignatureCallback() {}
+    virtual ~SignatureCallback() = default;
+
+    // Invoked upon completion of ComputeTlsSignature.
+    //
+    // |ok| indicates whether the operation completed successfully.
+    //
+    // |signature| contains the signature of the data provided to
+    // ComputeTlsSignature. Its value is undefined if |ok| is false.
+    //
+    // |details| holds a pointer to an object representing the statistics, if
+    // any, gathered during the operation of ComputeTlsSignature.  If no stats
+    // are available, this will be nullptr.
+    virtual void Run(bool ok,
+                     std::string signature,
+                     std::unique_ptr<Details> details) = 0;
+
+   private:
+    SignatureCallback(const SignatureCallback&) = delete;
+    SignatureCallback& operator=(const SignatureCallback&) = delete;
+  };
+
+  virtual ~ProofSource() {}
+
+  // GetProof finds a certificate chain for |hostname| (in leaf-first order),
+  // and calculates a signature of |server_config| using that chain.
+  //
+  // The signature uses SHA-256 as the hash function and PSS padding when the
+  // key is RSA.
+  //
+  // The signature uses SHA-256 as the hash function when the key is ECDSA.
+  // The signature may use an ECDSA key.
+  //
+  // The signature depends on |chlo_hash| which means that the signature can not
+  // be cached.
+  //
+  // |hostname| may be empty to signify that a default certificate should be
+  // used.
+  //
+  // This function may be called concurrently.
+  //
+  // Callers should expect that |callback| might be invoked synchronously.
+  virtual void GetProof(const QuicSocketAddress& server_address,
+                        const QuicSocketAddress& client_address,
+                        const std::string& hostname,
+                        const std::string& server_config,
+                        QuicTransportVersion transport_version,
+                        absl::string_view chlo_hash,
+                        std::unique_ptr<Callback> callback) = 0;
+
+  // Returns the certificate chain for |hostname| in leaf-first order.
+  //
+  // Sets *cert_matched_sni to true if the certificate matched the given
+  // hostname, false if a default cert not matching the hostname was used.
+  virtual quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) = 0;
+
+  // Computes a signature using the private key of the certificate for
+  // |hostname|. The value in |in| is signed using the algorithm specified by
+  // |signature_algorithm|, which is an |SSL_SIGN_*| value (as defined in TLS
+  // 1.3). Implementations can only assume that |in| is valid during the call to
+  // ComputeTlsSignature - an implementation computing signatures asynchronously
+  // must copy it if the value to be signed is used outside of this function.
+  //
+  // Callers should expect that |callback| might be invoked synchronously.
+  virtual void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      std::unique_ptr<SignatureCallback> callback) = 0;
+
+  // Return the list of TLS signature algorithms that is acceptable by the
+  // ComputeTlsSignature method. If the entire BoringSSL's default list of
+  // supported signature algorithms are acceptable, return an empty list.
+  //
+  // If returns a non-empty list, ComputeTlsSignature will only be called with a
+  // algorithm in the list.
+  virtual absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const = 0;
+
+  class QUIC_EXPORT_PRIVATE DecryptCallback {
+   public:
+    DecryptCallback() = default;
+    virtual ~DecryptCallback() = default;
+
+    virtual void Run(std::vector<uint8_t> plaintext) = 0;
+
+   private:
+    DecryptCallback(const Callback&) = delete;
+    DecryptCallback& operator=(const Callback&) = delete;
+  };
+
+  // TicketCrypter is an interface for managing encryption and decryption of TLS
+  // session tickets. A TicketCrypter gets used as an
+  // SSL_CTX_set_ticket_aead_method in BoringSSL, which has a synchronous
+  // Encrypt/Seal operation and a potentially asynchronous Decrypt/Open
+  // operation. This interface allows for ticket decryptions to be performed on
+  // a remote service.
+  class QUIC_EXPORT_PRIVATE TicketCrypter {
+   public:
+    TicketCrypter() = default;
+    virtual ~TicketCrypter() = default;
+
+    // MaxOverhead returns the maximum number of bytes of overhead that may get
+    // added when encrypting the ticket.
+    virtual size_t MaxOverhead() = 0;
+
+    // Encrypt takes a serialized TLS session ticket in |in|, encrypts it, and
+    // returns the encrypted ticket. The resulting value must not be larger than
+    // MaxOverhead bytes larger than |in|. If encryption fails, this method
+    // returns an empty vector.
+    //
+    // If |encryption_key| is nonempty, this method should use it for minting
+    // TLS resumption tickets.  If it is empty, this method may use an
+    // internally cached encryption key, if available.
+    virtual std::vector<uint8_t> Encrypt(absl::string_view in,
+                                         absl::string_view encryption_key) = 0;
+
+    // Decrypt takes an encrypted ticket |in|, decrypts it, and calls
+    // |callback->Run| with the decrypted ticket, which must not be larger than
+    // |in|. If decryption fails, the callback is invoked with an empty
+    // vector.
+    virtual void Decrypt(absl::string_view in,
+                         std::unique_ptr<DecryptCallback> callback) = 0;
+  };
+
+  // Returns the TicketCrypter used for encrypting and decrypting TLS
+  // session tickets, or nullptr if that functionality is not supported. The
+  // TicketCrypter returned (if not nullptr) must be valid for the lifetime of
+  // the ProofSource, and the caller does not take ownership of said
+  // TicketCrypter.
+  virtual TicketCrypter* GetTicketCrypter() = 0;
+};
+
+// ProofSourceHandleCallback is an interface that contains the callbacks when
+// the operations in ProofSourceHandle completes.
+// TODO(wub): Consider deprecating ProofSource by moving all functionalities of
+// ProofSource into ProofSourceHandle.
+class QUIC_EXPORT_PRIVATE ProofSourceHandleCallback {
+ public:
+  virtual ~ProofSourceHandleCallback() = default;
+
+  // Called when a ProofSourceHandle::SelectCertificate operation completes.
+  // |ok| indicates whether the operation was successful.
+  // |is_sync| indicates whether the operation completed synchronously, i.e.
+  //      whether it is completed before ProofSourceHandle::SelectCertificate
+  //      returned.
+  // |chain| the certificate chain in leaf-first order.
+  // |handshake_hints| (optional) handshake hints that can be used by
+  //      SSL_set_handshake_hints.
+  // |ticket_encryption_key| (optional) encryption key to be used for minting
+  //      TLS resumption tickets.
+  // |cert_matched_sni| is true if the certificate matched the SNI hostname,
+  //      false if a non-matching default cert was used.
+  // |delayed_ssl_config| contains SSL configs to be applied on the SSL object.
+  //
+  // When called asynchronously(is_sync=false), this method will be responsible
+  // to continue the handshake from where it left off.
+  virtual void OnSelectCertificateDone(
+      bool ok, bool is_sync, const ProofSource::Chain* chain,
+      absl::string_view handshake_hints,
+      absl::string_view ticket_encryption_key, bool cert_matched_sni,
+      QuicDelayedSSLConfig delayed_ssl_config) = 0;
+
+  // Called when a ProofSourceHandle::ComputeSignature operation completes.
+  virtual void OnComputeSignatureDone(
+      bool ok,
+      bool is_sync,
+      std::string signature,
+      std::unique_ptr<ProofSource::Details> details) = 0;
+
+  // Return true iff ProofSourceHandle::ComputeSignature won't be called later.
+  // The handle can use this function to release resources promptly.
+  virtual bool WillNotCallComputeSignature() const = 0;
+};
+
+// ProofSourceHandle is an interface by which a TlsServerHandshaker can obtain
+// certificate chains and signatures that prove its identity.
+// The operations this interface supports are similar to those in ProofSource,
+// the main difference is that ProofSourceHandle is per-handshaker, so
+// an implementation can have states that are shared by multiple calls on the
+// same handle.
+//
+// A handle object is owned by a TlsServerHandshaker. Since there might be an
+// async operation pending when the handle destructs, an implementation must
+// ensure when such operations finish, their corresponding callback method won't
+// be invoked.
+//
+// A handle will have at most one async operation pending at a time.
+class QUIC_EXPORT_PRIVATE ProofSourceHandle {
+ public:
+  virtual ~ProofSourceHandle() = default;
+
+  // Close the handle. Cancel the pending operation, if any.
+  // Once called, any completion method on |callback()| won't be invoked, and
+  // future SelectCertificate and ComputeSignature calls should return failure.
+  virtual void CloseHandle() = 0;
+
+  // Starts a select certificate operation. If the operation is not cancelled
+  // when it completes, callback()->OnSelectCertificateDone will be invoked.
+  //
+  // server_address and client_address should be normalized by the caller before
+  // sending down to this function.
+  //
+  // If the operation is handled synchronously:
+  // - QUIC_SUCCESS or QUIC_FAILURE will be returned.
+  // - callback()->OnSelectCertificateDone should be invoked before the function
+  //   returns.
+  //
+  // If the operation is handled asynchronously:
+  // - QUIC_PENDING will be returned.
+  // - When the operation is done, callback()->OnSelectCertificateDone should be
+  //   invoked.
+  virtual QuicAsyncStatus SelectCertificate(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      absl::string_view ssl_capabilities,
+      const std::string& hostname,
+      absl::string_view client_hello,
+      const std::string& alpn,
+      absl::optional<std::string> alps,
+      const std::vector<uint8_t>& quic_transport_params,
+      const absl::optional<std::vector<uint8_t>>& early_data_context,
+      const QuicSSLConfig& ssl_config) = 0;
+
+  // Starts a compute signature operation. If the operation is not cancelled
+  // when it completes, callback()->OnComputeSignatureDone will be invoked.
+  //
+  // See the comments of SelectCertificate for sync vs. async operations.
+  virtual QuicAsyncStatus ComputeSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      size_t max_signature_size) = 0;
+
+ protected:
+  // Returns the object that will be notified when an operation completes.
+  virtual ProofSourceHandleCallback* callback() = 0;
+
+ private:
+  friend class test::FakeProofSourceHandle;
+};
+
+// Returns true if |chain| contains a parsable DER-encoded X.509 leaf cert and
+// it matches with |key|.
+QUIC_EXPORT_PRIVATE bool ValidateCertAndKey(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const CertificatePrivateKey& key);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_
diff --git a/quiche/quic/core/crypto/proof_source_x509.cc b/quiche/quic/core/crypto/proof_source_x509.cc
new file mode 100644
index 0000000..275efc0
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source_x509.cc
@@ -0,0 +1,149 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/proof_source_x509.h"
+
+#include <memory>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+std::unique_ptr<ProofSourceX509> ProofSourceX509::Create(
+    quiche::QuicheReferenceCountedPointer<Chain> default_chain,
+    CertificatePrivateKey default_key) {
+  std::unique_ptr<ProofSourceX509> result(new ProofSourceX509());
+  if (!result->AddCertificateChain(default_chain, std::move(default_key))) {
+    return nullptr;
+  }
+  result->default_certificate_ = &result->certificates_.front();
+  return result;
+}
+
+void ProofSourceX509::GetProof(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    const std::string& hostname,
+    const std::string& server_config,
+    QuicTransportVersion /*transport_version*/,
+    absl::string_view chlo_hash,
+    std::unique_ptr<ProofSource::Callback> callback) {
+  QuicCryptoProof proof;
+
+  size_t payload_size = sizeof(kProofSignatureLabel) + sizeof(uint32_t) +
+                        chlo_hash.size() + server_config.size();
+  auto payload = std::make_unique<char[]>(payload_size);
+  QuicDataWriter payload_writer(payload_size, payload.get(),
+                                quiche::Endianness::HOST_BYTE_ORDER);
+  bool success = payload_writer.WriteBytes(kProofSignatureLabel,
+                                           sizeof(kProofSignatureLabel)) &&
+                 payload_writer.WriteUInt32(chlo_hash.size()) &&
+                 payload_writer.WriteStringPiece(chlo_hash) &&
+                 payload_writer.WriteStringPiece(server_config);
+  if (!success) {
+    callback->Run(/*ok=*/false, nullptr, proof, nullptr);
+    return;
+  }
+
+  Certificate* certificate = GetCertificate(hostname, &proof.cert_matched_sni);
+  proof.signature =
+      certificate->key.Sign(absl::string_view(payload.get(), payload_size),
+                            SSL_SIGN_RSA_PSS_RSAE_SHA256);
+  callback->Run(/*ok=*/!proof.signature.empty(), certificate->chain, proof,
+                nullptr);
+}
+
+quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
+ProofSourceX509::GetCertChain(const QuicSocketAddress& /*server_address*/,
+                              const QuicSocketAddress& /*client_address*/,
+                              const std::string& hostname,
+                              bool* cert_matched_sni) {
+  return GetCertificate(hostname, cert_matched_sni)->chain;
+}
+
+void ProofSourceX509::ComputeTlsSignature(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in,
+    std::unique_ptr<ProofSource::SignatureCallback> callback) {
+  bool cert_matched_sni;
+  std::string signature = GetCertificate(hostname, &cert_matched_sni)
+                              ->key.Sign(in, signature_algorithm);
+  callback->Run(/*ok=*/!signature.empty(), signature, nullptr);
+}
+
+absl::InlinedVector<uint16_t, 8>
+ProofSourceX509::SupportedTlsSignatureAlgorithms() const {
+  // Let ComputeTlsSignature() report an error if a bad signature algorithm is
+  // requested.
+  return {};
+}
+
+ProofSource::TicketCrypter* ProofSourceX509::GetTicketCrypter() {
+  return nullptr;
+}
+
+bool ProofSourceX509::AddCertificateChain(
+    quiche::QuicheReferenceCountedPointer<Chain> chain,
+    CertificatePrivateKey key) {
+  if (chain->certs.empty()) {
+    QUIC_BUG(quic_bug_10644_1) << "Empty certificate chain supplied.";
+    return false;
+  }
+
+  std::unique_ptr<CertificateView> leaf =
+      CertificateView::ParseSingleCertificate(chain->certs[0]);
+  if (leaf == nullptr) {
+    QUIC_BUG(quic_bug_10644_2)
+        << "Unable to parse X.509 leaf certificate in the supplied chain.";
+    return false;
+  }
+  if (!key.MatchesPublicKey(*leaf)) {
+    QUIC_BUG(quic_bug_10644_3)
+        << "Private key does not match the leaf certificate.";
+    return false;
+  }
+
+  certificates_.push_front(Certificate{
+      chain,
+      std::move(key),
+  });
+  Certificate* certificate = &certificates_.front();
+
+  for (absl::string_view host : leaf->subject_alt_name_domains()) {
+    certificate_map_[std::string(host)] = certificate;
+  }
+  return true;
+}
+
+ProofSourceX509::Certificate* ProofSourceX509::GetCertificate(
+    const std::string& hostname, bool* cert_matched_sni) const {
+  auto it = certificate_map_.find(hostname);
+  if (it != certificate_map_.end()) {
+    *cert_matched_sni = true;
+    return it->second;
+  }
+  auto dot_pos = hostname.find('.');
+  if (dot_pos != std::string::npos) {
+    std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
+    it = certificate_map_.find(wildcard);
+    if (it != certificate_map_.end()) {
+      *cert_matched_sni = true;
+      return it->second;
+    }
+  }
+  *cert_matched_sni = false;
+  return default_certificate_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_source_x509.h b/quiche/quic/core/crypto/proof_source_x509.h
new file mode 100644
index 0000000..107a4c8
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source_x509.h
@@ -0,0 +1,78 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
+#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
+
+#include <forward_list>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/container/node_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+
+namespace quic {
+
+// ProofSourceX509 accepts X.509 certificates with private keys and picks a
+// certificate internally based on its SubjectAltName value.
+class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
+ public:
+  // Creates a proof source that uses |default_chain| when no SubjectAltName
+  // value matches.  Returns nullptr if |default_chain| is invalid.
+  static std::unique_ptr<ProofSourceX509> Create(
+      quiche::QuicheReferenceCountedPointer<Chain> default_chain,
+      CertificatePrivateKey default_key);
+
+  // ProofSource implementation.
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& server_config,
+                QuicTransportVersion transport_version,
+                absl::string_view chlo_hash,
+                std::unique_ptr<Callback> callback) override;
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) override;
+  void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      uint16_t signature_algorithm, absl::string_view in,
+      std::unique_ptr<SignatureCallback> callback) override;
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override;
+  TicketCrypter* GetTicketCrypter() override;
+
+  // Adds a certificate chain to the verifier.  Returns false if the chain is
+  // not valid.  Newer certificates will override older certificates with the
+  // same SubjectAltName value.
+  ABSL_MUST_USE_RESULT bool AddCertificateChain(
+      quiche::QuicheReferenceCountedPointer<Chain> chain,
+      CertificatePrivateKey key);
+
+ private:
+  ProofSourceX509() = default;
+
+  struct QUIC_EXPORT_PRIVATE Certificate {
+    quiche::QuicheReferenceCountedPointer<Chain> chain;
+    CertificatePrivateKey key;
+  };
+
+  // Looks up certficiate for hostname, returns the default if no certificate is
+  // found.
+  Certificate* GetCertificate(const std::string& hostname,
+                              bool* cert_matched_sni) const;
+
+  std::forward_list<Certificate> certificates_;
+  Certificate* default_certificate_;
+  absl::node_hash_map<std::string, Certificate*> certificate_map_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_X509_H_
diff --git a/quiche/quic/core/crypto/proof_source_x509_test.cc b/quiche/quic/core/crypto/proof_source_x509_test.cc
new file mode 100644
index 0000000..63ba310
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_source_x509_test.cc
@@ -0,0 +1,143 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/proof_source_x509.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+quiche::QuicheReferenceCountedPointer<ProofSource::Chain> MakeChain(
+    absl::string_view cert) {
+  return quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
+      new ProofSource::Chain(std::vector<std::string>{std::string(cert)}));
+}
+
+class ProofSourceX509Test : public QuicTest {
+ public:
+  ProofSourceX509Test()
+      : test_chain_(MakeChain(kTestCertificate)),
+        wildcard_chain_(MakeChain(kWildcardCertificate)),
+        test_key_(
+            CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey)),
+        wildcard_key_(CertificatePrivateKey::LoadFromDer(
+            kWildcardCertificatePrivateKey)) {
+    QUICHE_CHECK(test_key_ != nullptr);
+    QUICHE_CHECK(wildcard_key_ != nullptr);
+  }
+
+ protected:
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> test_chain_,
+      wildcard_chain_;
+  std::unique_ptr<CertificatePrivateKey> test_key_, wildcard_key_;
+};
+
+TEST_F(ProofSourceX509Test, AddCertificates) {
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+  EXPECT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
+                                                std::move(*wildcard_key_)));
+}
+
+TEST_F(ProofSourceX509Test, AddCertificateKeyMismatch) {
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+  test_key_ = CertificatePrivateKey::LoadFromDer(kTestCertificatePrivateKey);
+  EXPECT_QUIC_BUG((void)proof_source->AddCertificateChain(
+                      wildcard_chain_, std::move(*test_key_)),
+                  "Private key does not match");
+}
+
+TEST_F(ProofSourceX509Test, CertificateSelection) {
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+  ASSERT_TRUE(proof_source->AddCertificateChain(wildcard_chain_,
+                                                std::move(*wildcard_key_)));
+
+  // Default certificate.
+  bool cert_matched_sni;
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "unknown.test", &cert_matched_sni)
+                ->certs[0],
+            kTestCertificate);
+  EXPECT_FALSE(cert_matched_sni);
+  // mail.example.org is explicitly a SubjectAltName in kTestCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "mail.example.org", &cert_matched_sni)
+                ->certs[0],
+            kTestCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  // www.foo.test is in kWildcardCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "www.foo.test", &cert_matched_sni)
+                ->certs[0],
+            kWildcardCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  // *.wildcard.test is in kWildcardCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "www.wildcard.test", &cert_matched_sni)
+                ->certs[0],
+            kWildcardCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "etc.wildcard.test", &cert_matched_sni)
+                ->certs[0],
+            kWildcardCertificate);
+  EXPECT_TRUE(cert_matched_sni);
+  // wildcard.test itself is not in kWildcardCertificate.
+  EXPECT_EQ(proof_source
+                ->GetCertChain(QuicSocketAddress(), QuicSocketAddress(),
+                               "wildcard.test", &cert_matched_sni)
+                ->certs[0],
+            kTestCertificate);
+  EXPECT_FALSE(cert_matched_sni);
+}
+
+TEST_F(ProofSourceX509Test, TlsSignature) {
+  class Callback : public ProofSource::SignatureCallback {
+   public:
+    void Run(bool ok,
+             std::string signature,
+             std::unique_ptr<ProofSource::Details> /*details*/) override {
+      ASSERT_TRUE(ok);
+      std::unique_ptr<CertificateView> view =
+          CertificateView::ParseSingleCertificate(kTestCertificate);
+      EXPECT_TRUE(view->VerifySignature("Test data", signature,
+                                        SSL_SIGN_RSA_PSS_RSAE_SHA256));
+    }
+  };
+
+  std::unique_ptr<ProofSourceX509> proof_source =
+      ProofSourceX509::Create(test_chain_, std::move(*test_key_));
+  ASSERT_TRUE(proof_source != nullptr);
+
+  proof_source->ComputeTlsSignature(QuicSocketAddress(), QuicSocketAddress(),
+                                    "example.com", SSL_SIGN_RSA_PSS_RSAE_SHA256,
+                                    "Test data", std::make_unique<Callback>());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/proof_verifier.h b/quiche/quic/core/crypto/proof_verifier.h
new file mode 100644
index 0000000..3478ca6
--- /dev/null
+++ b/quiche/quic/core/crypto/proof_verifier.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// ProofVerifyDetails is an abstract class that acts as a container for any
+// implementation specific details that a ProofVerifier wishes to return. These
+// details are saved in the CachedState for the origin in question.
+class QUIC_EXPORT_PRIVATE ProofVerifyDetails {
+ public:
+  virtual ~ProofVerifyDetails() {}
+
+  // Returns an new ProofVerifyDetails object with the same contents
+  // as this one.
+  virtual ProofVerifyDetails* Clone() const = 0;
+};
+
+// ProofVerifyContext is an abstract class that acts as a container for any
+// implementation specific context that a ProofVerifier needs.
+class QUIC_EXPORT_PRIVATE ProofVerifyContext {
+ public:
+  virtual ~ProofVerifyContext() {}
+};
+
+// ProofVerifierCallback provides a generic mechanism for a ProofVerifier to
+// call back after an asynchronous verification.
+class QUIC_EXPORT_PRIVATE ProofVerifierCallback {
+ public:
+  virtual ~ProofVerifierCallback() {}
+
+  // Run is called on the original thread to mark the completion of an
+  // asynchonous verification. If |ok| is true then the certificate is valid
+  // and |error_details| is unused. Otherwise, |error_details| contains a
+  // description of the error. |details| contains implementation-specific
+  // details of the verification. |Run| may take ownership of |details| by
+  // calling |release| on it.
+  virtual void Run(bool ok,
+                   const std::string& error_details,
+                   std::unique_ptr<ProofVerifyDetails>* details) = 0;
+};
+
+// A ProofVerifier checks the signature on a server config, and the certificate
+// chain that backs the public key.
+class QUIC_EXPORT_PRIVATE ProofVerifier {
+ public:
+  virtual ~ProofVerifier() {}
+
+  // VerifyProof checks that |signature| is a valid signature of
+  // |server_config| by the public key in the leaf certificate of |certs|, and
+  // that |certs| is a valid chain for |hostname|. On success, it returns
+  // QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and sets |*error_details|
+  // to a description of the problem. In either case it may set |*details|,
+  // which the caller takes ownership of.
+  //
+  // |context| specifies an implementation specific struct (which may be nullptr
+  // for some implementations) that provides useful information for the
+  // verifier, e.g. logging handles.
+  //
+  // This function may also return QUIC_PENDING, in which case the ProofVerifier
+  // will call back, on the original thread, via |callback| when complete.
+  //
+  // The signature uses SHA-256 as the hash function and PSS padding in the
+  // case of RSA.
+  virtual QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion transport_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) = 0;
+
+  // VerifyCertChain checks that |certs| is a valid chain for |hostname|. On
+  // success, it returns QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and
+  // sets |*error_details| to a description of the problem. In either case it
+  // may set |*details|, which the caller takes ownership of.
+  //
+  // |context| specifies an implementation specific struct (which may be nullptr
+  // for some implementations) that provides useful information for the
+  // verifier, e.g. logging handles.
+  //
+  // If certificate verification fails, a TLS alert will be sent when closing
+  // the connection. This alert defaults to certificate_unknown. By setting
+  // |*out_alert|, a different alert can be sent to provide a more specific
+  // reason why verification failed.
+  //
+  // This function may also return QUIC_PENDING, in which case the ProofVerifier
+  // will call back, on the original thread, via |callback| when complete.
+  // In this case, the ProofVerifier will take ownership of |callback|.
+  virtual QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) = 0;
+
+  // Returns a ProofVerifyContext instance which can be use for subsequent
+  // verifications. Applications may chose create a different context and
+  // supply it for verifications instead.
+  virtual std::unique_ptr<ProofVerifyContext> CreateDefaultContext() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_VERIFIER_H_
diff --git a/quiche/quic/core/crypto/quic_client_session_cache.cc b/quiche/quic/core/crypto/quic_client_session_cache.cc
new file mode 100644
index 0000000..32f115d
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_client_session_cache.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+
+#include "quiche/quic/core/quic_clock.h"
+
+namespace quic {
+
+namespace {
+
+const size_t kDefaultMaxEntries = 1024;
+// Returns false if the SSL |session| doesn't exist or it is expired at |now|.
+bool IsValid(SSL_SESSION* session, uint64_t now) {
+  if (!session) return false;
+
+  // now_u64 may be slightly behind because of differences in how
+  // time is calculated at this layer versus BoringSSL.
+  // Add a second of wiggle room to account for this.
+  return !(now + 1 < SSL_SESSION_get_time(session) ||
+           now >= SSL_SESSION_get_time(session) +
+                      SSL_SESSION_get_timeout(session));
+}
+
+bool DoApplicationStatesMatch(const ApplicationState* state,
+                              ApplicationState* other) {
+  if ((state && !other) || (!state && other)) return false;
+  if ((!state && !other) || *state == *other) return true;
+  return false;
+}
+
+}  // namespace
+
+QuicClientSessionCache::QuicClientSessionCache()
+    : QuicClientSessionCache(kDefaultMaxEntries) {}
+
+QuicClientSessionCache::QuicClientSessionCache(size_t max_entries)
+    : cache_(max_entries) {}
+
+QuicClientSessionCache::~QuicClientSessionCache() { Clear(); }
+
+void QuicClientSessionCache::Insert(const QuicServerId& server_id,
+                                    bssl::UniquePtr<SSL_SESSION> session,
+                                    const TransportParameters& params,
+                                    const ApplicationState* application_state) {
+  QUICHE_DCHECK(session) << "TLS session is not inserted into client cache.";
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) {
+    CreateAndInsertEntry(server_id, std::move(session), params,
+                         application_state);
+    return;
+  }
+
+  QUICHE_DCHECK(iter->second->params);
+  // The states are both the same, so only need to insert sessions.
+  if (params == *iter->second->params &&
+      DoApplicationStatesMatch(application_state,
+                               iter->second->application_state.get())) {
+    iter->second->PushSession(std::move(session));
+    return;
+  }
+  // Erase the existing entry because this Insert call must come from a
+  // different QUIC session.
+  cache_.Erase(iter);
+  CreateAndInsertEntry(server_id, std::move(session), params,
+                       application_state);
+}
+
+std::unique_ptr<QuicResumptionState> QuicClientSessionCache::Lookup(
+    const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* /*ctx*/) {
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) return nullptr;
+
+  if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
+    QUIC_DLOG(INFO) << "TLS Session expired for host:" << server_id.host();
+    cache_.Erase(iter);
+    return nullptr;
+  }
+  auto state = std::make_unique<QuicResumptionState>();
+  state->tls_session = iter->second->PopSession();
+  if (iter->second->params != nullptr) {
+    state->transport_params =
+        std::make_unique<TransportParameters>(*iter->second->params);
+  }
+  if (iter->second->application_state != nullptr) {
+    state->application_state =
+        std::make_unique<ApplicationState>(*iter->second->application_state);
+  }
+  if (!iter->second->token.empty()) {
+    state->token = iter->second->token;
+    // Clear token after use.
+    iter->second->token.clear();
+  }
+
+  return state;
+}
+
+void QuicClientSessionCache::ClearEarlyData(const QuicServerId& server_id) {
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) return;
+  for (auto& session : iter->second->sessions) {
+    if (session) {
+      QUIC_DLOG(INFO) << "Clear early data for for host: " << server_id.host();
+      session.reset(SSL_SESSION_copy_without_early_data(session.get()));
+    }
+  }
+}
+
+void QuicClientSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
+                                                absl::string_view token) {
+  if (token.empty()) {
+    return;
+  }
+  auto iter = cache_.Lookup(server_id);
+  if (iter == cache_.end()) {
+    return;
+  }
+  iter->second->token = std::string(token);
+}
+
+void QuicClientSessionCache::RemoveExpiredEntries(QuicWallTime now) {
+  auto iter = cache_.begin();
+  while (iter != cache_.end()) {
+    if (!IsValid(iter->second->PeekSession(), now.ToUNIXSeconds())) {
+      iter = cache_.Erase(iter);
+    } else {
+      ++iter;
+    }
+  }
+}
+
+void QuicClientSessionCache::Clear() { cache_.Clear(); }
+
+void QuicClientSessionCache::CreateAndInsertEntry(
+    const QuicServerId& server_id, bssl::UniquePtr<SSL_SESSION> session,
+    const TransportParameters& params,
+    const ApplicationState* application_state) {
+  auto entry = std::make_unique<Entry>();
+  entry->PushSession(std::move(session));
+  entry->params = std::make_unique<TransportParameters>(params);
+  if (application_state) {
+    entry->application_state =
+        std::make_unique<ApplicationState>(*application_state);
+  }
+  cache_.Insert(server_id, std::move(entry));
+}
+
+QuicClientSessionCache::Entry::Entry() = default;
+QuicClientSessionCache::Entry::Entry(Entry&&) = default;
+QuicClientSessionCache::Entry::~Entry() = default;
+
+void QuicClientSessionCache::Entry::PushSession(
+    bssl::UniquePtr<SSL_SESSION> session) {
+  if (sessions[0] != nullptr) {
+    sessions[1] = std::move(sessions[0]);
+  }
+  sessions[0] = std::move(session);
+}
+
+bssl::UniquePtr<SSL_SESSION> QuicClientSessionCache::Entry::PopSession() {
+  if (sessions[0] == nullptr) return nullptr;
+  bssl::UniquePtr<SSL_SESSION> session = std::move(sessions[0]);
+  sessions[0] = std::move(sessions[1]);
+  sessions[1] = nullptr;
+  return session;
+}
+
+SSL_SESSION* QuicClientSessionCache::Entry::PeekSession() {
+  return sessions[0].get();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_client_session_cache.h b/quiche/quic/core/crypto/quic_client_session_cache.h
new file mode 100644
index 0000000..e568db6
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_client_session_cache.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
+
+#include <memory>
+
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_lru_cache.h"
+#include "quiche/quic/core/quic_server_id.h"
+
+namespace quic {
+
+namespace test {
+class QuicClientSessionCachePeer;
+}  // namespace test
+
+// QuicClientSessionCache maps from QuicServerId to information used to resume
+// TLS sessions for that server.
+class QUIC_EXPORT_PRIVATE QuicClientSessionCache : public SessionCache {
+ public:
+  QuicClientSessionCache();
+  explicit QuicClientSessionCache(size_t max_entries);
+  ~QuicClientSessionCache() override;
+
+  void Insert(const QuicServerId& server_id,
+              bssl::UniquePtr<SSL_SESSION> session,
+              const TransportParameters& params,
+              const ApplicationState* application_state) override;
+
+  std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
+                                              QuicWallTime now,
+                                              const SSL_CTX* ctx) override;
+
+  void ClearEarlyData(const QuicServerId& server_id) override;
+
+  void OnNewTokenReceived(const QuicServerId& server_id,
+                          absl::string_view token) override;
+
+  void RemoveExpiredEntries(QuicWallTime now) override;
+
+  void Clear() override;
+
+  size_t size() const { return cache_.Size(); }
+
+ private:
+  friend class test::QuicClientSessionCachePeer;
+
+  struct QUIC_EXPORT_PRIVATE Entry {
+    Entry();
+    Entry(Entry&&);
+    ~Entry();
+
+    // Adds a new |session| onto sessions, dropping the oldest one if two are
+    // already stored.
+    void PushSession(bssl::UniquePtr<SSL_SESSION> session);
+
+    // Retrieves the latest session from the entry, meanwhile removing it.
+    bssl::UniquePtr<SSL_SESSION> PopSession();
+
+    SSL_SESSION* PeekSession();
+
+    bssl::UniquePtr<SSL_SESSION> sessions[2];
+    std::unique_ptr<TransportParameters> params;
+    std::unique_ptr<ApplicationState> application_state;
+    std::string token;  // An opaque string received in NEW_TOKEN frame.
+  };
+
+  // Creates a new entry and insert into |cache_|.
+  void CreateAndInsertEntry(const QuicServerId& server_id,
+                            bssl::UniquePtr<SSL_SESSION> session,
+                            const TransportParameters& params,
+                            const ApplicationState* application_state);
+
+  QuicLRUCache<QuicServerId, Entry, QuicServerIdHash> cache_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CLIENT_SESSION_CACHE_H_
diff --git a/quiche/quic/core/crypto/quic_client_session_cache_test.cc b/quiche/quic/core/crypto/quic_client_session_cache_test.cc
new file mode 100644
index 0000000..880770a
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_client_session_cache_test.cc
@@ -0,0 +1,440 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const QuicTime::Delta kTimeout = QuicTime::Delta::FromSeconds(1000);
+const QuicVersionLabel kFakeVersionLabel = 0x01234567;
+const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
+const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
+const uint8_t kFakeStatelessResetTokenData[16] = {
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
+const uint64_t kFakeMaxPacketSize = 9001;
+const uint64_t kFakeInitialMaxData = 101;
+const bool kFakeDisableMigration = true;
+const auto kCustomParameter1 =
+    static_cast<TransportParameters::TransportParameterId>(0xffcd);
+const char* kCustomParameter1Value = "foo";
+const auto kCustomParameter2 =
+    static_cast<TransportParameters::TransportParameterId>(0xff34);
+const char* kCustomParameter2Value = "bar";
+
+std::vector<uint8_t> CreateFakeStatelessResetToken() {
+  return std::vector<uint8_t>(
+      kFakeStatelessResetTokenData,
+      kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData));
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformation() {
+  TransportParameters::LegacyVersionInformation legacy_version_information;
+  legacy_version_information.version = kFakeVersionLabel;
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
+  return legacy_version_information;
+}
+
+TransportParameters::VersionInformation CreateFakeVersionInformation() {
+  TransportParameters::VersionInformation version_information;
+  version_information.chosen_version = kFakeVersionLabel;
+  version_information.other_versions.push_back(kFakeVersionLabel);
+  return version_information;
+}
+
+// Make a TransportParameters that has a few fields set to help test comparison.
+std::unique_ptr<TransportParameters> MakeFakeTransportParams() {
+  auto params = std::make_unique<TransportParameters>();
+  params->perspective = Perspective::IS_CLIENT;
+  params->legacy_version_information = CreateFakeLegacyVersionInformation();
+  params->version_information = CreateFakeVersionInformation();
+  params->max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  params->stateless_reset_token = CreateFakeStatelessResetToken();
+  params->max_udp_payload_size.set_value(kFakeMaxPacketSize);
+  params->initial_max_data.set_value(kFakeInitialMaxData);
+  params->disable_active_migration = kFakeDisableMigration;
+  params->custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  params->custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+  return params;
+}
+
+// Generated by running TlsClientHandshakerTest.ZeroRttResumption and in
+// TlsClientHandshaker::InsertSession calling SSL_SESSION_to_bytes to serialize
+// the received 0-RTT capable ticket.
+static const char kCachedSession[] =
+    "30820ad7020101020203040402130104206594ce84e61a866b56163c4ba09079aebf1d4f"
+    "6cbcbd38dc9d7066a38a76c9cf0420ec9062063582a4cc0a44f9ff93256a195153ba6032"
+    "0cf3c9189990932d838adaa10602046196f7b9a205020302a300a382039f3082039b3082"
+    "0183a00302010202021001300d06092a864886f70d010105050030623111300f06035504"
+    "030c08426f677573204941310b300906035504080c024d41310b30090603550406130255"
+    "533121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d"
+    "3110300e060355040a0c07426f6775734941301e170d3231303132383136323030315a17"
+    "0d3331303132363136323030315a3069311d301b06035504030c14746573745f6563632e"
+    "6578616d706c652e636f6d310b300906035504080c024d41310b30090603550406130255"
+    "53311e301c06092a864886f70d010901160f626f67757340626f6775732e636f6d310e30"
+    "0c060355040a0c05426f6775733059301306072a8648ce3d020106082a8648ce3d030107"
+    "034200041ba5e2b6f24e64990b9f24ae6d23473d8c77fbcfb7f554f36559529a69a57170"
+    "a10a81b7fe4a36ebf37b0a8c5e467a8443d8b8c002892aa5c1194bd843f42c9aa31f301d"
+    "301b0603551d11041430128210746573742e6578616d706c652e636f6d300d06092a8648"
+    "86f70d0101050500038202010019921d54ac06948763d609215f64f5d6540e3da886c6c9"
+    "61bc737a437719b4621416ef1229f39282d7d3234e1a5d57535473066233bd246eec8e96"
+    "1e0633cf4fe014c800e62599981820ec33d92e74ded0fa2953db1d81e19cb6890b6305b6"
+    "3ede8d3e9fcf3c09f3f57283acf08aa57be4ee9a68d00bb3e2ded5920c619b5d83e5194a"
+    "adb77ae5d61ed3e0a5670f0ae61cc3197329f0e71e3364dcab0405e9e4a6646adef8f022"
+    "6415ec16c8046307b1769029fe780bd576114dde2fa9b4a32aa70bc436549a24ee4907a9"
+    "045f6457ce8dfd8d62cc65315afe798ae1a948eefd70b035d415e73569c48fb20085de1a"
+    "87de039e6b0b9a5fcb4069df27f3a7a1409e72d1ac739c72f29ef786134207e61c79855f"
+    "c22e3ee5f6ad59a7b1ff0f18d79776f1c95efaebbebe381664132a58a1e7ff689945b7e0"
+    "88634b0872feeefbf6be020884b994c6a7ff435f2b3f609077ff97cb509cfa17ff479b34"
+    "e633e4b5bc46b20c5f27c80a2e2943f795a928acd5a3fc43c3af8425ad600c048b41d87e"
+    "6361bc72fc4e5e44680a3d325674ba6ffa760d2fc7d9e4847a8e0dd9d35a543324e18b94"
+    "2d42af6391ed1dd54a39e3f4a4c6b32486eb4ba72815dbd89c56fc053743a0b0483ce676"
+    "15defce6800c629b99d0cbc56da162487f475b7c246099eaf1e6d10a022b2f49c6af1da3"
+    "e8ed66096f267c4a76976b9572db7456ef90278330a4020400aa81b60481b3494e534543"
+    "55524500f3439e548c21d2ad6e5634cc1cc0045730819702010102020304040213010400"
+    "0420ec9062063582a4cc0a44f9ff93256a195153ba60320cf3c9189990932d838adaa106"
+    "02046196f7b9a205020302a300a4020400b20302011db5060404130800cdb807020500ff"
+    "ffffffb9050203093a80ba0404026833bb030101ffbc23042100d27d985bfce04833f02d"
+    "38366b219f4def42bc4ba1b01844d1778db11731487dbd020400be020400b20302011db3"
+    "8205da308205d6308203bea00302010202021000300d06092a864886f70d010105050030"
+    "62310b3009060355040613025553310b300906035504080c024d413110300e060355040a"
+    "0c07426f67757343413111300f06035504030c08426f6775732043413121301f06092a86"
+    "4886f70d0109011612626f67757340626f6775732d63612e636f6d3020170d3231303132"
+    "383136313935385a180f32303730303531313136313935385a30623111300f0603550403"
+    "0c08426f677573204941310b300906035504080c024d41310b3009060355040613025553"
+    "3121301f06092a864886f70d0109011612626f67757340626f6775732d69612e636f6d31"
+    "10300e060355040a0c07426f677573494130820222300d06092a864886f70d0101010500"
+    "0382020f003082020a028202010096c03a0ffc61bcedcd5ec9bf6f848b8a066b43f08377"
+    "3af518a6a0044f22e666e24d2ae741954e344302c4be04612185bd53bcd848eb322bf900"
+    "724eb0848047d647033ffbddb00f01d1de7c1cdb684f83c9bf5fd18ff60afad5a53b0d7d"
+    "2c2a50abc38df019cd7f50194d05bc4597a1ef8570ea04069a2c36d74496af126573ca18"
+    "8e470009b56250fadf2a04e837ee3837b36b1f08b7a0cfe2533d05f26484ce4e30203d01"
+    "517fffd3da63d0341079ddce16e9ab4dbf9d4049e5cc52326031e645dd682fe6220d9e0e"
+    "95451f5a82f3e1720dc13e8499466426a0bdbea9f6a76b3c9228dd3c79ab4dcc4c145ef0"
+    "e78d1ee8bfd4650692d7e28a54bed809d8f7b37fe24c586be59cc46638531cb291c8c156"
+    "8f08d67e768e51563e95a639c1f138b275ffad6a6a2a042ba9e26ad63c2ce63b600013f0"
+    "a6f0703ee51c4f457f7bab0391c2fc4c5bb3213742c9cf9941bff68cc2e1cc96139d35ed"
+    "1885244ddde0bf658416c486701841b81f7b17503d08c59a4db08a2a80755e007aa3b6c7"
+    "eadcaa9e07c8325f3689f100de23970b12c9d9f6d0a8fb35ba0fd75c64410318db4a13ac"
+    "3972ad16cdf6408af37013c7bcd7c42f20d6d04c3e39436c7531e8dafa219dd04b784ef0"
+    "3c70ee5a4782b33cafa925aa3deca62a14aed704f179b932efabc2b0c5c15a8a99bfc9e6"
+    "189dce7da50ea303594b6af9c933dd54b6e9d17c472d0203010001a38193308190300f06"
+    "03551d130101ff040530030101ff301d0603551d0e041604141a98e80029a80992b7e5e0"
+    "068ab9b3486cd839d6301f0603551d23041830168014780beeefe2fa419c48a438bdb30b"
+    "e37ef0b7a94e300b0603551d0f0404030202a430130603551d25040c300a06082b060105"
+    "05070301301b0603551d11041430128207426f67757343418207426f6775734941300d06"
+    "092a864886f70d010105050003820201009e822ed8064b1aabaddf1340010ea147f68c06"
+    "5a5a599ea305349f1b0e545a00817d6e55c7bf85560fab429ca72186c4d520b52f5cc121"
+    "abd068b06f3111494431d2522efa54642f907059e7db80b73bb5ecf621377195b8700bba"
+    "df798cece8c67a9571548d0e6592e81ae5d934877cb170aef18d3b97f635600fe0890d98"
+    "f88b33fe3d1fd34c1c915beae4e5c0b133f476c40b21d220f16ce9cdd9e8f97a36a31723"
+    "68875f052c9271648d9cb54687c6fdc3ea96f2908003bc5e5e79de00a21da7b8429f8b08"
+    "af4c4d34641e386d72eabf5f01f106363f2ffd18969bf0bb9a4d17627c6427ff772c4308"
+    "83c276feef5fc6dba9582c22fdbe9df7e8dfca375695f028ed588df54f3c86462dbf4c07"
+    "91d80ca738988a1419c86bb4dd8d738b746921f01f39422e5ffd488b6f00195b996e6392"
+    "3a820a32cd78b5989f339c0fcf4f269103964a30a16347d0ffdc8df1f3653ddc1515fa09"
+    "22c7aef1af1fbcb23e93ae7622ab1ee11fcfa98319bad4c37c091cad46bd0337b3cc78b5"
+    "5b9f1ea7994acc1f89c49a0b4cb540d2137e266fd43e56a9b5b778217b6f77df530e1eaf"
+    "b3417262b5ddb86d3c6c5ac51e3f326c650dcc2434473973b7182c66220d1f3871bde7ee"
+    "47d3f359d3d4c5bdd61baa684c03db4c75f9d6690c9e6e3abe6eaf5fa2c33c4daf26b373"
+    "d85a1e8a7d671ac4a0a97b14e36e81280de4593bbb12da7695b5060404130800cdb60301"
+    "0100b70402020403b807020500ffffffffb9050203093a80ba0404026833bb030101ffbd"
+    "020400be020400";
+
+class QuicClientSessionCacheTest : public QuicTest {
+ public:
+  QuicClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+ protected:
+  bssl::UniquePtr<SSL_SESSION> NewSSLSession() {
+    std::string cached_session =
+        absl::HexStringToBytes(absl::string_view(kCachedSession));
+    SSL_SESSION* session = SSL_SESSION_from_bytes(
+        reinterpret_cast<const uint8_t*>(cached_session.data()),
+        cached_session.size(), ssl_ctx_.get());
+    QUICHE_DCHECK(session);
+    return bssl::UniquePtr<SSL_SESSION>(session);
+  }
+
+  bssl::UniquePtr<SSL_SESSION> MakeTestSession(
+      QuicTime::Delta timeout = kTimeout) {
+    bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
+    SSL_SESSION_set_time(session.get(), clock_.WallNow().ToUNIXSeconds());
+    SSL_SESSION_set_timeout(session.get(), timeout.ToSeconds());
+    return session;
+  }
+
+  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+  MockClock clock_;
+};
+
+// Tests that simple insertion and lookup work correctly.
+TEST_F(QuicClientSessionCacheTest, SingleSession) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+
+  auto params2 = MakeFakeTransportParams();
+  auto session2 = MakeTestSession();
+  SSL_SESSION* unowned2 = session2.get();
+  QuicServerId id2("b.com", 443);
+
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(0u, cache.size());
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  EXPECT_EQ(1u, cache.size());
+  EXPECT_EQ(
+      *params,
+      *(cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->transport_params));
+  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
+  // No session is available for id1, even though the entry exists.
+  EXPECT_EQ(1u, cache.size());
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  // Lookup() will trigger a deletion of invalid entry.
+  EXPECT_EQ(0u, cache.size());
+
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  QuicServerId id3("c.com", 443);
+  cache.Insert(id3, std::move(session3), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params2, nullptr);
+  EXPECT_EQ(2u, cache.size());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(
+      unowned3,
+      cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+
+  // Verify that the cache is cleared after Lookups.
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(0u, cache.size());
+}
+
+TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  SSL_SESSION* unowned2 = session2.get();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id1, std::move(session2), *params, nullptr);
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  // The latest session is popped first.
+  EXPECT_EQ(
+      unowned3,
+      cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  // Only two sessions are cached.
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+// Test that when a different TransportParameter is inserted for
+// the same server id, the existing entry is removed.
+TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id1, std::move(session2), *params, nullptr);
+  // tweak the transport parameters a little bit.
+  params->perspective = Perspective::IS_SERVER;
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
+  EXPECT_EQ(*params.get(), *resumption_state->transport_params);
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  ApplicationState state;
+  state.push_back('a');
+
+  cache.Insert(id1, std::move(session), *params, &state);
+  cache.Insert(id1, std::move(session2), *params, &state);
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
+  EXPECT_EQ(nullptr, resumption_state->application_state);
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  ApplicationState state;
+  state.push_back('a');
+
+  cache.Insert(id1, std::move(session), *params, &state);
+  cache.Insert(id1, std::move(session2), *params, &state);
+  params->perspective = Perspective::IS_SERVER;
+  cache.Insert(id1, std::move(session3), *params, nullptr);
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_EQ(unowned3, resumption_state->tls_session.get());
+  EXPECT_EQ(*params.get(), *resumption_state->transport_params);
+  EXPECT_EQ(nullptr, resumption_state->application_state);
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+// When the size limit is exceeded, the oldest entry should be erased.
+TEST_F(QuicClientSessionCacheTest, SizeLimit) {
+  QuicClientSessionCache cache(2);
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+
+  auto session2 = MakeTestSession();
+  SSL_SESSION* unowned2 = session2.get();
+  QuicServerId id2("b.com", 443);
+
+  auto session3 = MakeTestSession();
+  SSL_SESSION* unowned3 = session3.get();
+  QuicServerId id3("c.com", 443);
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params, nullptr);
+  cache.Insert(id3, std::move(session3), *params, nullptr);
+
+  EXPECT_EQ(2u, cache.size());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(
+      unowned3,
+      cache.Lookup(id3, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+TEST_F(QuicClientSessionCacheTest, ClearEarlyData) {
+  QuicClientSessionCache cache;
+  SSL_CTX_set_early_data_enabled(ssl_ctx_.get(), 1);
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+  auto session2 = MakeTestSession();
+
+  EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
+  EXPECT_TRUE(SSL_SESSION_early_data_capable(session2.get()));
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id1, std::move(session2), *params, nullptr);
+
+  cache.ClearEarlyData(id1);
+
+  auto resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_FALSE(
+      SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
+  resumption_state = cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get());
+  EXPECT_FALSE(
+      SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+}
+
+// Expired session isn't considered valid and nullptr will be returned upon
+// Lookup.
+TEST_F(QuicClientSessionCacheTest, Expiration) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  QuicServerId id1("a.com", 443);
+
+  auto session2 = MakeTestSession(3 * kTimeout);
+  SSL_SESSION* unowned2 = session2.get();
+  QuicServerId id2("b.com", 443);
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params, nullptr);
+
+  EXPECT_EQ(2u, cache.size());
+  // Expire the session.
+  clock_.AdvanceTime(kTimeout * 2);
+  // The entry has not been removed yet.
+  EXPECT_EQ(2u, cache.size());
+
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(1u, cache.size());
+  EXPECT_EQ(
+      unowned2,
+      cache.Lookup(id2, clock_.WallNow(), ssl_ctx_.get())->tls_session.get());
+  EXPECT_EQ(1u, cache.size());
+}
+
+TEST_F(QuicClientSessionCacheTest, RemoveExpiredEntriesAndClear) {
+  QuicClientSessionCache cache;
+
+  auto params = MakeFakeTransportParams();
+  auto session = MakeTestSession();
+  quic::QuicServerId id1("a.com", 443);
+
+  auto session2 = MakeTestSession(3 * kTimeout);
+  quic::QuicServerId id2("b.com", 443);
+
+  cache.Insert(id1, std::move(session), *params, nullptr);
+  cache.Insert(id2, std::move(session2), *params, nullptr);
+
+  EXPECT_EQ(2u, cache.size());
+  // Expire the session.
+  clock_.AdvanceTime(kTimeout * 2);
+  // The entry has not been removed yet.
+  EXPECT_EQ(2u, cache.size());
+
+  // Flush expired sessions.
+  cache.RemoveExpiredEntries(clock_.WallNow());
+
+  // session is expired and should be flushed.
+  EXPECT_EQ(nullptr, cache.Lookup(id1, clock_.WallNow(), ssl_ctx_.get()));
+  EXPECT_EQ(1u, cache.size());
+
+  cache.Clear();
+  EXPECT_EQ(0u, cache.size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_compressed_certs_cache.cc b/quiche/quic/core/crypto/quic_compressed_certs_cache.cc
new file mode 100644
index 0000000..9627aba
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_compressed_certs_cache.cc
@@ -0,0 +1,119 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+
+namespace quic {
+
+namespace {
+
+// Inline helper function for extending a 64-bit |seed| in-place with a 64-bit
+// |value|. Based on Boost's hash_combine function.
+inline void hash_combine(uint64_t* seed, const uint64_t& val) {
+  (*seed) ^= val + 0x9e3779b9 + ((*seed) << 6) + ((*seed) >> 2);
+}
+
+}  // namespace
+
+const size_t QuicCompressedCertsCache::kQuicCompressedCertsCacheSize = 225;
+
+QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts()
+    : chain(nullptr),
+      client_cached_cert_hashes(nullptr) {}
+
+QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string* client_cached_cert_hashes)
+    : chain(chain), client_cached_cert_hashes(client_cached_cert_hashes) {}
+
+QuicCompressedCertsCache::UncompressedCerts::~UncompressedCerts() {}
+
+QuicCompressedCertsCache::CachedCerts::CachedCerts() {}
+
+QuicCompressedCertsCache::CachedCerts::CachedCerts(
+    const UncompressedCerts& uncompressed_certs,
+    const std::string& compressed_cert)
+    : chain_(uncompressed_certs.chain),
+      client_cached_cert_hashes_(*uncompressed_certs.client_cached_cert_hashes),
+      compressed_cert_(compressed_cert) {}
+
+QuicCompressedCertsCache::CachedCerts::CachedCerts(const CachedCerts& other) =
+    default;
+
+QuicCompressedCertsCache::CachedCerts::~CachedCerts() {}
+
+bool QuicCompressedCertsCache::CachedCerts::MatchesUncompressedCerts(
+    const UncompressedCerts& uncompressed_certs) const {
+  return (client_cached_cert_hashes_ ==
+              *uncompressed_certs.client_cached_cert_hashes &&
+          chain_ == uncompressed_certs.chain);
+}
+
+const std::string* QuicCompressedCertsCache::CachedCerts::compressed_cert()
+    const {
+  return &compressed_cert_;
+}
+
+QuicCompressedCertsCache::QuicCompressedCertsCache(int64_t max_num_certs)
+    : certs_cache_(max_num_certs) {}
+
+QuicCompressedCertsCache::~QuicCompressedCertsCache() {
+  // Underlying cache must be cleared before destruction.
+  certs_cache_.Clear();
+}
+
+const std::string* QuicCompressedCertsCache::GetCompressedCert(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes) {
+  UncompressedCerts uncompressed_certs(chain, &client_cached_cert_hashes);
+
+  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
+
+  CachedCerts* cached_value = nullptr;
+  auto iter = certs_cache_.Lookup(key);
+  if (iter != certs_cache_.end()) {
+    cached_value = iter->second.get();
+  }
+  if (cached_value != nullptr &&
+      cached_value->MatchesUncompressedCerts(uncompressed_certs)) {
+    return cached_value->compressed_cert();
+  }
+  return nullptr;
+}
+
+void QuicCompressedCertsCache::Insert(
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes,
+    const std::string& compressed_cert) {
+  UncompressedCerts uncompressed_certs(chain, &client_cached_cert_hashes);
+
+  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);
+
+  // Insert one unit to the cache.
+  std::unique_ptr<CachedCerts> cached_certs(
+      new CachedCerts(uncompressed_certs, compressed_cert));
+  certs_cache_.Insert(key, std::move(cached_certs));
+}
+
+size_t QuicCompressedCertsCache::MaxSize() {
+  return certs_cache_.MaxSize();
+}
+
+size_t QuicCompressedCertsCache::Size() {
+  return certs_cache_.Size();
+}
+
+uint64_t QuicCompressedCertsCache::ComputeUncompressedCertsHash(
+    const UncompressedCerts& uncompressed_certs) {
+  uint64_t hash =
+      std::hash<std::string>()(*uncompressed_certs.client_cached_cert_hashes);
+
+  hash_combine(&hash,
+               reinterpret_cast<uint64_t>(uncompressed_certs.chain.get()));
+  return hash;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_compressed_certs_cache.h b/quiche/quic/core/crypto/quic_compressed_certs_cache.h
new file mode 100644
index 0000000..918981e
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_compressed_certs_cache.h
@@ -0,0 +1,103 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
+
+#include <string>
+#include <vector>
+
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/quic_lru_cache.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicCompressedCertsCache is a cache to track most recently compressed certs.
+class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache {
+ public:
+  explicit QuicCompressedCertsCache(int64_t max_num_certs);
+  ~QuicCompressedCertsCache();
+
+  // Returns the pointer to the cached compressed cert if
+  // |chain, client_cached_cert_hashes| hits cache.
+  // Otherwise, return nullptr.
+  // Returned pointer might become invalid on the next call to Insert().
+  const std::string* GetCompressedCert(
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes);
+
+  // Inserts the specified
+  // |chain, client_cached_cert_hashes, compressed_cert| tuple to the cache.
+  // If the insertion causes the cache to become overfull, entries will
+  // be deleted in an LRU order to make room.
+  void Insert(
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes,
+      const std::string& compressed_cert);
+
+  // Returns max number of cache entries the cache can carry.
+  size_t MaxSize();
+
+  // Returns current number of cache entries in the cache.
+  size_t Size();
+
+  // Default size of the QuicCompressedCertsCache per server side investigation.
+  static const size_t kQuicCompressedCertsCacheSize;
+
+ private:
+  // A wrapper of the tuple:
+  //   |chain, client_cached_cert_hashes|
+  // to identify uncompressed representation of certs.
+  struct QUIC_EXPORT_PRIVATE UncompressedCerts {
+    UncompressedCerts();
+    UncompressedCerts(
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const std::string* client_cached_cert_hashes);
+    ~UncompressedCerts();
+
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
+    const std::string* client_cached_cert_hashes;
+  };
+
+  // Certs stored by QuicCompressedCertsCache where uncompressed certs data is
+  // used to identify the uncompressed representation of certs and
+  // |compressed_cert| is the cached compressed representation.
+  class QUIC_EXPORT_PRIVATE CachedCerts {
+   public:
+    CachedCerts();
+    CachedCerts(const UncompressedCerts& uncompressed_certs,
+                const std::string& compressed_cert);
+    CachedCerts(const CachedCerts& other);
+    ~CachedCerts();
+
+    // Returns true if the |uncompressed_certs| matches uncompressed
+    // representation of this cert.
+    bool MatchesUncompressedCerts(
+        const UncompressedCerts& uncompressed_certs) const;
+
+    const std::string* compressed_cert() const;
+
+   private:
+    // Uncompressed certs data.
+    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain_;
+    const std::string client_cached_cert_hashes_;
+
+    // Cached compressed representation derived from uncompressed certs.
+    const std::string compressed_cert_;
+  };
+
+  // Computes a uint64_t hash for |uncompressed_certs|.
+  uint64_t ComputeUncompressedCertsHash(
+      const UncompressedCerts& uncompressed_certs);
+
+  // Key is a unit64_t hash for UncompressedCerts. Stored associated value is
+  // CachedCerts which has both original uncompressed certs data and the
+  // compressed representation of the certs.
+  QuicLRUCache<uint64_t, CachedCerts> certs_cache_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_COMPRESSED_CERTS_CACHE_H_
diff --git a/quiche/quic/core/crypto/quic_compressed_certs_cache_test.cc b/quiche/quic/core/crypto/quic_compressed_certs_cache_test.cc
new file mode 100644
index 0000000..b98f9f2
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_compressed_certs_cache_test.cc
@@ -0,0 +1,91 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class QuicCompressedCertsCacheTest : public QuicTest {
+ public:
+  QuicCompressedCertsCacheTest()
+      : certs_cache_(QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {}
+
+ protected:
+  QuicCompressedCertsCache certs_cache_;
+};
+
+TEST_F(QuicCompressedCertsCacheTest, CacheHit) {
+  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
+                                    "root cert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+  std::string cached_certs = "cached certs";
+  std::string compressed = "compressed cert";
+
+  certs_cache_.Insert(chain, cached_certs, compressed);
+
+  const std::string* cached_value =
+      certs_cache_.GetCompressedCert(chain, cached_certs);
+  ASSERT_NE(nullptr, cached_value);
+  EXPECT_EQ(*cached_value, compressed);
+}
+
+TEST_F(QuicCompressedCertsCacheTest, CacheMiss) {
+  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
+                                    "root cert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+
+  std::string cached_certs = "cached certs";
+  std::string compressed = "compressed cert";
+
+  certs_cache_.Insert(chain, cached_certs, compressed);
+
+  EXPECT_EQ(nullptr,
+            certs_cache_.GetCompressedCert(chain, "mismatched cached certs"));
+
+  // A different chain though with equivalent certs should get a cache miss.
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
+      new ProofSource::Chain(certs));
+  EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain2, cached_certs));
+}
+
+TEST_F(QuicCompressedCertsCacheTest, CacheMissDueToEviction) {
+  // Test cache returns a miss when a queried uncompressed certs was cached but
+  // then evicted.
+  std::vector<std::string> certs = {"leaf cert", "intermediate cert",
+                                    "root cert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+
+  std::string cached_certs = "cached certs";
+  std::string compressed = "compressed cert";
+  certs_cache_.Insert(chain, cached_certs, compressed);
+
+  // Insert another kQuicCompressedCertsCacheSize certs to evict the first
+  // cached cert.
+  for (unsigned int i = 0;
+       i < QuicCompressedCertsCache::kQuicCompressedCertsCacheSize; i++) {
+    EXPECT_EQ(certs_cache_.Size(), i + 1);
+    certs_cache_.Insert(chain, absl::StrCat(i), absl::StrCat(i));
+  }
+  EXPECT_EQ(certs_cache_.MaxSize(), certs_cache_.Size());
+
+  EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain, cached_certs));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypter.cc b/quiche/quic/core/crypto/quic_crypter.cc
new file mode 100644
index 0000000..05c8e3a
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypter.cc
@@ -0,0 +1,18 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "absl/strings/string_view.h"
+
+namespace quic {
+
+bool QuicCrypter::SetNoncePrefixOrIV(const ParsedQuicVersion& version,
+                                     absl::string_view nonce_prefix_or_iv) {
+  if (version.UsesInitialObfuscators()) {
+    return SetIV(nonce_prefix_or_iv);
+  }
+  return SetNoncePrefix(nonce_prefix_or_iv);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypter.h b/quiche/quic/core/crypto/quic_crypter.h
new file mode 100644
index 0000000..d57a8e6
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypter.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicCrypter is the parent class for QuicEncrypter and QuicDecrypter.
+// Its purpose is to provide an interface for using methods that are common to
+// both classes when operations are being done that apply to both encrypters and
+// decrypters.
+class QUIC_EXPORT_PRIVATE QuicCrypter {
+ public:
+  virtual ~QuicCrypter() {}
+
+  // Sets the symmetric encryption/decryption key. Returns true on success,
+  // false on failure.
+  //
+  // NOTE: The key is the client_write_key or server_write_key derived from
+  // the master secret.
+  virtual bool SetKey(absl::string_view key) = 0;
+
+  // Sets the fixed initial bytes of the nonce. Returns true on success,
+  // false on failure. This method must only be used with Google QUIC crypters.
+  //
+  // NOTE: The nonce prefix is the client_write_iv or server_write_iv
+  // derived from the master secret. A 64-bit packet number will
+  // be appended to form the nonce.
+  //
+  //                          <------------ 64 bits ----------->
+  //   +---------------------+----------------------------------+
+  //   |    Fixed prefix     |      packet number      |
+  //   +---------------------+----------------------------------+
+  //                          Nonce format
+  //
+  // The security of the nonce format requires that QUIC never reuse a
+  // packet number, even when retransmitting a lost packet.
+  virtual bool SetNoncePrefix(absl::string_view nonce_prefix) = 0;
+
+  // Sets |iv| as the initialization vector to use when constructing the nonce.
+  // Returns true on success, false on failure. This method must only be used
+  // with IETF QUIC crypters.
+  //
+  // Google QUIC and IETF QUIC use different nonce constructions. This method
+  // must be used when using IETF QUIC; SetNoncePrefix must be used when using
+  // Google QUIC.
+  //
+  // The nonce is constructed as follows (draft-ietf-quic-tls-14 section 5.2):
+  //
+  //    <---------------- max(8, N_MIN) bytes ----------------->
+  //   +--------------------------------------------------------+
+  //   |                 packet protection IV                   |
+  //   +--------------------------------------------------------+
+  //                             XOR
+  //                          <------------ 64 bits ----------->
+  //   +---------------------+----------------------------------+
+  //   |        zeroes       |   reconstructed packet number    |
+  //   +---------------------+----------------------------------+
+  //
+  // The nonce is the packet protection IV (|iv|) XOR'd with the left-padded
+  // reconstructed packet number.
+  //
+  // The security of the nonce format requires that QUIC never reuse a
+  // packet number, even when retransmitting a lost packet.
+  virtual bool SetIV(absl::string_view iv) = 0;
+
+  // Calls SetNoncePrefix or SetIV depending on whether |version| uses the
+  // Google QUIC crypto or IETF QUIC nonce construction.
+  virtual bool SetNoncePrefixOrIV(const ParsedQuicVersion& version,
+                                  absl::string_view nonce_prefix_or_iv);
+
+  // Sets the key to use for header protection.
+  virtual bool SetHeaderProtectionKey(absl::string_view key) = 0;
+
+  // GetKeySize, GetIVSize, and GetNoncePrefixSize are used to know how many
+  // bytes of key material needs to be derived from the master secret.
+
+  // Returns the size in bytes of a key for the algorithm.
+  virtual size_t GetKeySize() const = 0;
+  // Returns the size in bytes of an IV to use with the algorithm.
+  virtual size_t GetIVSize() const = 0;
+  // Returns the size in bytes of the fixed initial part of the nonce.
+  virtual size_t GetNoncePrefixSize() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTER_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config.cc b/quiche/quic/core/crypto/quic_crypto_client_config.cc
new file mode 100644
index 0000000..e857591
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_client_config.cc
@@ -0,0 +1,857 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/crypto/tls_client_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Tracks the reason (the state of the server config) for sending inchoate
+// ClientHello to the server.
+void RecordInchoateClientHelloReason(
+    QuicCryptoClientConfig::CachedState::ServerConfigState state) {
+  QUIC_CLIENT_HISTOGRAM_ENUM(
+      "QuicInchoateClientHelloReason", state,
+      QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
+}
+
+// Tracks the state of the QUIC server information loaded from the disk cache.
+void RecordDiskCacheServerConfigState(
+    QuicCryptoClientConfig::CachedState::ServerConfigState state) {
+  QUIC_CLIENT_HISTOGRAM_ENUM(
+      "QuicServerInfo.DiskCacheState", state,
+      QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT, "");
+}
+
+}  // namespace
+
+QuicCryptoClientConfig::QuicCryptoClientConfig(
+    std::unique_ptr<ProofVerifier> proof_verifier)
+    : QuicCryptoClientConfig(std::move(proof_verifier), nullptr) {}
+
+QuicCryptoClientConfig::QuicCryptoClientConfig(
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : proof_verifier_(std::move(proof_verifier)),
+      session_cache_(std::move(session_cache)),
+      ssl_ctx_(TlsClientConnection::CreateSslCtx(
+          !GetQuicFlag(FLAGS_quic_disable_client_tls_zero_rtt))) {
+  QUICHE_DCHECK(proof_verifier_.get());
+  SetDefaults();
+}
+
+QuicCryptoClientConfig::~QuicCryptoClientConfig() {}
+
+QuicCryptoClientConfig::CachedState::CachedState()
+    : server_config_valid_(false),
+      expiration_time_(QuicWallTime::Zero()),
+      generation_counter_(0) {}
+
+QuicCryptoClientConfig::CachedState::~CachedState() {}
+
+bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
+  if (server_config_.empty()) {
+    RecordInchoateClientHelloReason(SERVER_CONFIG_EMPTY);
+    return false;
+  }
+
+  if (!server_config_valid_) {
+    RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID);
+    return false;
+  }
+
+  const CryptoHandshakeMessage* scfg = GetServerConfig();
+  if (!scfg) {
+    // Should be impossible short of cache corruption.
+    RecordInchoateClientHelloReason(SERVER_CONFIG_CORRUPTED);
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  if (now.IsBefore(expiration_time_)) {
+    return true;
+  }
+
+  QUIC_CLIENT_HISTOGRAM_TIMES(
+      "QuicClientHelloServerConfig.InvalidDuration",
+      QuicTime::Delta::FromSeconds(now.ToUNIXSeconds() -
+                                   expiration_time_.ToUNIXSeconds()),
+      QuicTime::Delta::FromSeconds(60),              // 1 min.
+      QuicTime::Delta::FromSeconds(20 * 24 * 3600),  // 20 days.
+      50, "");
+  RecordInchoateClientHelloReason(SERVER_CONFIG_EXPIRED);
+  return false;
+}
+
+bool QuicCryptoClientConfig::CachedState::IsEmpty() const {
+  return server_config_.empty();
+}
+
+const CryptoHandshakeMessage*
+QuicCryptoClientConfig::CachedState::GetServerConfig() const {
+  if (server_config_.empty()) {
+    return nullptr;
+  }
+
+  if (!scfg_) {
+    scfg_ = CryptoFramer::ParseMessage(server_config_);
+    QUICHE_DCHECK(scfg_.get());
+  }
+  return scfg_.get();
+}
+
+QuicCryptoClientConfig::CachedState::ServerConfigState
+QuicCryptoClientConfig::CachedState::SetServerConfig(
+    absl::string_view server_config,
+    QuicWallTime now,
+    QuicWallTime expiry_time,
+    std::string* error_details) {
+  const bool matches_existing = server_config == server_config_;
+
+  // Even if the new server config matches the existing one, we still wish to
+  // reject it if it has expired.
+  std::unique_ptr<CryptoHandshakeMessage> new_scfg_storage;
+  const CryptoHandshakeMessage* new_scfg;
+
+  if (!matches_existing) {
+    new_scfg_storage = CryptoFramer::ParseMessage(server_config);
+    new_scfg = new_scfg_storage.get();
+  } else {
+    new_scfg = GetServerConfig();
+  }
+
+  if (!new_scfg) {
+    *error_details = "SCFG invalid";
+    return SERVER_CONFIG_INVALID;
+  }
+
+  if (expiry_time.IsZero()) {
+    uint64_t expiry_seconds;
+    if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
+      *error_details = "SCFG missing EXPY";
+      return SERVER_CONFIG_INVALID_EXPIRY;
+    }
+    expiration_time_ = QuicWallTime::FromUNIXSeconds(expiry_seconds);
+  } else {
+    expiration_time_ = expiry_time;
+  }
+
+  if (now.IsAfter(expiration_time_)) {
+    *error_details = "SCFG has expired";
+    return SERVER_CONFIG_EXPIRED;
+  }
+
+  if (!matches_existing) {
+    server_config_ = std::string(server_config);
+    SetProofInvalid();
+    scfg_ = std::move(new_scfg_storage);
+  }
+  return SERVER_CONFIG_VALID;
+}
+
+void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
+  server_config_.clear();
+  scfg_.reset();
+  SetProofInvalid();
+}
+
+void QuicCryptoClientConfig::CachedState::SetProof(
+    const std::vector<std::string>& certs,
+    absl::string_view cert_sct,
+    absl::string_view chlo_hash,
+    absl::string_view signature) {
+  bool has_changed = signature != server_config_sig_ ||
+                     chlo_hash != chlo_hash_ || certs_.size() != certs.size();
+
+  if (!has_changed) {
+    for (size_t i = 0; i < certs_.size(); i++) {
+      if (certs_[i] != certs[i]) {
+        has_changed = true;
+        break;
+      }
+    }
+  }
+
+  if (!has_changed) {
+    return;
+  }
+
+  // If the proof has changed then it needs to be revalidated.
+  SetProofInvalid();
+  certs_ = certs;
+  cert_sct_ = std::string(cert_sct);
+  chlo_hash_ = std::string(chlo_hash);
+  server_config_sig_ = std::string(signature);
+}
+
+void QuicCryptoClientConfig::CachedState::Clear() {
+  server_config_.clear();
+  source_address_token_.clear();
+  certs_.clear();
+  cert_sct_.clear();
+  chlo_hash_.clear();
+  server_config_sig_.clear();
+  server_config_valid_ = false;
+  proof_verify_details_.reset();
+  scfg_.reset();
+  ++generation_counter_;
+}
+
+void QuicCryptoClientConfig::CachedState::ClearProof() {
+  SetProofInvalid();
+  certs_.clear();
+  cert_sct_.clear();
+  chlo_hash_.clear();
+  server_config_sig_.clear();
+}
+
+void QuicCryptoClientConfig::CachedState::SetProofValid() {
+  server_config_valid_ = true;
+}
+
+void QuicCryptoClientConfig::CachedState::SetProofInvalid() {
+  server_config_valid_ = false;
+  ++generation_counter_;
+}
+
+bool QuicCryptoClientConfig::CachedState::Initialize(
+    absl::string_view server_config,
+    absl::string_view source_address_token,
+    const std::vector<std::string>& certs,
+    const std::string& cert_sct,
+    absl::string_view chlo_hash,
+    absl::string_view signature,
+    QuicWallTime now,
+    QuicWallTime expiration_time) {
+  QUICHE_DCHECK(server_config_.empty());
+
+  if (server_config.empty()) {
+    RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY);
+    return false;
+  }
+
+  std::string error_details;
+  ServerConfigState state =
+      SetServerConfig(server_config, now, expiration_time, &error_details);
+  RecordDiskCacheServerConfigState(state);
+  if (state != SERVER_CONFIG_VALID) {
+    QUIC_DVLOG(1) << "SetServerConfig failed with " << error_details;
+    return false;
+  }
+
+  chlo_hash_.assign(chlo_hash.data(), chlo_hash.size());
+  server_config_sig_.assign(signature.data(), signature.size());
+  source_address_token_.assign(source_address_token.data(),
+                               source_address_token.size());
+  certs_ = certs;
+  cert_sct_ = cert_sct;
+  return true;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::server_config() const {
+  return server_config_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::source_address_token()
+    const {
+  return source_address_token_;
+}
+
+const std::vector<std::string>& QuicCryptoClientConfig::CachedState::certs()
+    const {
+  return certs_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::cert_sct() const {
+  return cert_sct_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::chlo_hash() const {
+  return chlo_hash_;
+}
+
+const std::string& QuicCryptoClientConfig::CachedState::signature() const {
+  return server_config_sig_;
+}
+
+bool QuicCryptoClientConfig::CachedState::proof_valid() const {
+  return server_config_valid_;
+}
+
+uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const {
+  return generation_counter_;
+}
+
+const ProofVerifyDetails*
+QuicCryptoClientConfig::CachedState::proof_verify_details() const {
+  return proof_verify_details_.get();
+}
+
+void QuicCryptoClientConfig::CachedState::set_source_address_token(
+    absl::string_view token) {
+  source_address_token_ = std::string(token);
+}
+
+void QuicCryptoClientConfig::CachedState::set_cert_sct(
+    absl::string_view cert_sct) {
+  cert_sct_ = std::string(cert_sct);
+}
+
+void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
+    ProofVerifyDetails* details) {
+  proof_verify_details_.reset(details);
+}
+
+void QuicCryptoClientConfig::CachedState::InitializeFrom(
+    const QuicCryptoClientConfig::CachedState& other) {
+  QUICHE_DCHECK(server_config_.empty());
+  QUICHE_DCHECK(!server_config_valid_);
+  server_config_ = other.server_config_;
+  source_address_token_ = other.source_address_token_;
+  certs_ = other.certs_;
+  cert_sct_ = other.cert_sct_;
+  chlo_hash_ = other.chlo_hash_;
+  server_config_sig_ = other.server_config_sig_;
+  server_config_valid_ = other.server_config_valid_;
+  expiration_time_ = other.expiration_time_;
+  if (other.proof_verify_details_ != nullptr) {
+    proof_verify_details_.reset(other.proof_verify_details_->Clone());
+  }
+  ++generation_counter_;
+}
+
+void QuicCryptoClientConfig::SetDefaults() {
+  // Key exchange methods.
+  kexs = {kC255, kP256};
+
+  // Authenticated encryption algorithms. Prefer AES-GCM if hardware-supported
+  // fast implementation is available.
+  if (EVP_has_aes_hardware() == 1) {
+    aead = {kAESG, kCC20};
+  } else {
+    aead = {kCC20, kAESG};
+  }
+}
+
+QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate(
+    const QuicServerId& server_id) {
+  auto it = cached_states_.find(server_id);
+  if (it != cached_states_.end()) {
+    return it->second.get();
+  }
+
+  CachedState* cached = new CachedState;
+  cached_states_.insert(std::make_pair(server_id, absl::WrapUnique(cached)));
+  bool cache_populated = PopulateFromCanonicalConfig(server_id, cached);
+  QUIC_CLIENT_HISTOGRAM_BOOL(
+      "QuicCryptoClientConfig.PopulatedFromCanonicalConfig", cache_populated,
+      "");
+  return cached;
+}
+
+void QuicCryptoClientConfig::ClearCachedStates(const ServerIdFilter& filter) {
+  for (auto it = cached_states_.begin(); it != cached_states_.end(); ++it) {
+    if (filter.Matches(it->first))
+      it->second->Clear();
+  }
+}
+
+void QuicCryptoClientConfig::FillInchoateClientHello(
+    const QuicServerId& server_id, const ParsedQuicVersion preferred_version,
+    const CachedState* cached, QuicRandom* rand, bool demand_x509_proof,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    CryptoHandshakeMessage* out) const {
+  out->set_tag(kCHLO);
+  out->set_minimum_size(1);
+
+  // Server name indication. We only send SNI if it's a valid domain name, as
+  // per the spec.
+  if (QuicHostnameUtils::IsValidSNI(server_id.host())) {
+    out->SetStringPiece(kSNI, server_id.host());
+  }
+  out->SetVersion(kVER, preferred_version);
+
+  if (!user_agent_id_.empty()) {
+    out->SetStringPiece(kUAID, user_agent_id_);
+  }
+
+  if (!alpn_.empty()) {
+    out->SetStringPiece(kALPN, alpn_);
+  }
+
+  // Even though this is an inchoate CHLO, send the SCID so that
+  // the STK can be validated by the server.
+  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
+  if (scfg != nullptr) {
+    absl::string_view scid;
+    if (scfg->GetStringPiece(kSCID, &scid)) {
+      out->SetStringPiece(kSCID, scid);
+    }
+  }
+
+  if (!cached->source_address_token().empty()) {
+    out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
+  }
+
+  if (!demand_x509_proof) {
+    return;
+  }
+
+  char proof_nonce[32];
+  rand->RandBytes(proof_nonce, ABSL_ARRAYSIZE(proof_nonce));
+  out->SetStringPiece(
+      kNONP, absl::string_view(proof_nonce, ABSL_ARRAYSIZE(proof_nonce)));
+
+  out->SetVector(kPDMD, QuicTagVector{kX509});
+
+  out->SetStringPiece(kCertificateSCTTag, "");
+
+  const std::vector<std::string>& certs = cached->certs();
+  // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
+  // client config is being used for multiple connections, another connection
+  // doesn't update the cached certificates and cause us to be unable to
+  // process the server's compressed certificate chain.
+  out_params->cached_certs = certs;
+  if (!certs.empty()) {
+    std::vector<uint64_t> hashes;
+    hashes.reserve(certs.size());
+    for (auto i = certs.begin(); i != certs.end(); ++i) {
+      hashes.push_back(QuicUtils::FNV1a_64_Hash(*i));
+    }
+    out->SetVector(kCCRT, hashes);
+  }
+}
+
+QuicErrorCode QuicCryptoClientConfig::FillClientHello(
+    const QuicServerId& server_id, QuicConnectionId connection_id,
+    const ParsedQuicVersion preferred_version,
+    const ParsedQuicVersion actual_version, const CachedState* cached,
+    QuicWallTime now, QuicRandom* rand,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    CryptoHandshakeMessage* out, std::string* error_details) const {
+  QUICHE_DCHECK(error_details != nullptr);
+  QUIC_BUG_IF(quic_bug_12943_2,
+              !QuicUtils::IsConnectionIdValidForVersion(
+                  connection_id, preferred_version.transport_version))
+      << "FillClientHello: attempted to use connection ID " << connection_id
+      << " which is invalid with version " << preferred_version;
+
+  FillInchoateClientHello(server_id, preferred_version, cached, rand,
+                          /* demand_x509_proof= */ true, out_params, out);
+
+  out->set_minimum_size(1);
+
+  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
+  if (!scfg) {
+    // This should never happen as our caller should have checked
+    // cached->IsComplete() before calling this function.
+    *error_details = "Handshake not ready";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+
+  absl::string_view scid;
+  if (!scfg->GetStringPiece(kSCID, &scid)) {
+    *error_details = "SCFG missing SCID";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+  out->SetStringPiece(kSCID, scid);
+
+  out->SetStringPiece(kCertificateSCTTag, "");
+
+  QuicTagVector their_aeads;
+  QuicTagVector their_key_exchanges;
+  if (scfg->GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR ||
+      scfg->GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR) {
+    *error_details = "Missing AEAD or KEXS";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  // AEAD: the work loads on the client and server are symmetric. Since the
+  // client is more likely to be CPU-constrained, break the tie by favoring
+  // the client's preference.
+  // Key exchange: the client does more work than the server, so favor the
+  // client's preference.
+  size_t key_exchange_index;
+  if (!FindMutualQuicTag(aead, their_aeads, &out_params->aead, nullptr) ||
+      !FindMutualQuicTag(kexs, their_key_exchanges, &out_params->key_exchange,
+                         &key_exchange_index)) {
+    *error_details = "Unsupported AEAD or KEXS";
+    return QUIC_CRYPTO_NO_SUPPORT;
+  }
+  out->SetVector(kAEAD, QuicTagVector{out_params->aead});
+  out->SetVector(kKEXS, QuicTagVector{out_params->key_exchange});
+
+  absl::string_view public_value;
+  if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) !=
+      QUIC_NO_ERROR) {
+    *error_details = "Missing public value";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  absl::string_view orbit;
+  if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) {
+    *error_details = "SCFG missing OBIT";
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+
+  CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce);
+  out->SetStringPiece(kNONC, out_params->client_nonce);
+  if (!out_params->server_nonce.empty()) {
+    out->SetStringPiece(kServerNonceTag, out_params->server_nonce);
+  }
+
+  switch (out_params->key_exchange) {
+    case kC255:
+      out_params->client_key_exchange = Curve25519KeyExchange::New(
+          Curve25519KeyExchange::NewPrivateKey(rand));
+      break;
+    case kP256:
+      out_params->client_key_exchange =
+          P256KeyExchange::New(P256KeyExchange::NewPrivateKey());
+      break;
+    default:
+      QUICHE_DCHECK(false);
+      *error_details = "Configured to support an unknown key exchange";
+      return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+
+  if (!out_params->client_key_exchange->CalculateSharedKeySync(
+          public_value, &out_params->initial_premaster_secret)) {
+    *error_details = "Key exchange failure";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+  out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
+
+  const std::vector<std::string>& certs = cached->certs();
+  if (certs.empty()) {
+    *error_details = "No certs to calculate XLCT";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+  out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0]));
+
+  // Derive the symmetric keys and set up the encrypters and decrypters.
+  // Set the following members of out_params:
+  //   out_params->hkdf_input_suffix
+  //   out_params->initial_crypters
+  out_params->hkdf_input_suffix.clear();
+  out_params->hkdf_input_suffix.append(connection_id.data(),
+                                       connection_id.length());
+  const QuicData& client_hello_serialized = out->GetSerialized();
+  out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
+                                       client_hello_serialized.length());
+  out_params->hkdf_input_suffix.append(cached->server_config());
+  if (certs.empty()) {
+    *error_details = "No certs found to include in KDF";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+  out_params->hkdf_input_suffix.append(certs[0]);
+
+  std::string hkdf_input;
+  const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
+  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
+  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
+  hkdf_input.append(out_params->hkdf_input_suffix);
+
+  std::string* subkey_secret = &out_params->initial_subkey_secret;
+
+  if (!CryptoUtils::DeriveKeys(
+          actual_version, out_params->initial_premaster_secret,
+          out_params->aead, out_params->client_nonce, out_params->server_nonce,
+          pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
+          CryptoUtils::Diversification::Pending(),
+          &out_params->initial_crypters, subkey_secret)) {
+    *error_details = "Symmetric key setup failed";
+    return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig(
+    const CryptoHandshakeMessage& message,
+    QuicWallTime now,
+    QuicTransportVersion /*version*/,
+    absl::string_view chlo_hash,
+    const std::vector<std::string>& cached_certs,
+    CachedState* cached,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  absl::string_view scfg;
+  if (!message.GetStringPiece(kSCFG, &scfg)) {
+    *error_details = "Missing SCFG";
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+
+  QuicWallTime expiration_time = QuicWallTime::Zero();
+  uint64_t expiry_seconds;
+  if (message.GetUint64(kSTTL, &expiry_seconds) == QUIC_NO_ERROR) {
+    // Only cache configs for a maximum of 1 week.
+    expiration_time = now.Add(QuicTime::Delta::FromSeconds(
+        std::min(expiry_seconds, kNumSecondsPerWeek)));
+  }
+
+  CachedState::ServerConfigState state =
+      cached->SetServerConfig(scfg, now, expiration_time, error_details);
+  if (state == CachedState::SERVER_CONFIG_EXPIRED) {
+    return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
+  }
+  // TODO(rtenneti): Return more specific error code than returning
+  // QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER.
+  if (state != CachedState::SERVER_CONFIG_VALID) {
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  absl::string_view token;
+  if (message.GetStringPiece(kSourceAddressTokenTag, &token)) {
+    cached->set_source_address_token(token);
+  }
+
+  absl::string_view proof, cert_bytes, cert_sct;
+  bool has_proof = message.GetStringPiece(kPROF, &proof);
+  bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes);
+  if (has_proof && has_cert) {
+    std::vector<std::string> certs;
+    if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, &certs)) {
+      *error_details = "Certificate data invalid";
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    message.GetStringPiece(kCertificateSCTTag, &cert_sct);
+    cached->SetProof(certs, cert_sct, chlo_hash, proof);
+  } else {
+    // Secure QUIC: clear existing proof as we have been sent a new SCFG
+    // without matching proof/certs.
+    cached->ClearProof();
+
+    if (has_proof && !has_cert) {
+      *error_details = "Certificate missing";
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+
+    if (!has_proof && has_cert) {
+      *error_details = "Proof missing";
+      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+    }
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
+    const CryptoHandshakeMessage& rej, QuicWallTime now,
+    const QuicTransportVersion version, absl::string_view chlo_hash,
+    CachedState* cached,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  if (rej.tag() != kREJ) {
+    *error_details = "Message is not REJ";
+    return QUIC_CRYPTO_INTERNAL_ERROR;
+  }
+
+  QuicErrorCode error =
+      CacheNewServerConfig(rej, now, version, chlo_hash,
+                           out_params->cached_certs, cached, error_details);
+  if (error != QUIC_NO_ERROR) {
+    return error;
+  }
+
+  absl::string_view nonce;
+  if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
+    out_params->server_nonce = std::string(nonce);
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
+    const CryptoHandshakeMessage& server_hello,
+    QuicConnectionId /*connection_id*/, ParsedQuicVersion version,
+    const ParsedQuicVersionVector& negotiated_versions, CachedState* cached,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  QuicErrorCode valid = CryptoUtils::ValidateServerHello(
+      server_hello, negotiated_versions, error_details);
+  if (valid != QUIC_NO_ERROR) {
+    return valid;
+  }
+
+  // Learn about updated source address tokens.
+  absl::string_view token;
+  if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) {
+    cached->set_source_address_token(token);
+  }
+
+  absl::string_view shlo_nonce;
+  if (!server_hello.GetStringPiece(kServerNonceTag, &shlo_nonce)) {
+    *error_details = "server hello missing server nonce";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  // TODO(agl):
+  //   learn about updated SCFGs.
+
+  absl::string_view public_value;
+  if (!server_hello.GetStringPiece(kPUBS, &public_value)) {
+    *error_details = "server hello missing forward secure public value";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  if (!out_params->client_key_exchange->CalculateSharedKeySync(
+          public_value, &out_params->forward_secure_premaster_secret)) {
+    *error_details = "Key exchange failure";
+    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
+  }
+
+  std::string hkdf_input;
+  const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
+  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
+  hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len);
+  hkdf_input.append(out_params->hkdf_input_suffix);
+
+  if (!CryptoUtils::DeriveKeys(
+          version, out_params->forward_secure_premaster_secret,
+          out_params->aead, out_params->client_nonce,
+          shlo_nonce.empty() ? out_params->server_nonce : shlo_nonce,
+          pre_shared_key_, hkdf_input, Perspective::IS_CLIENT,
+          CryptoUtils::Diversification::Never(),
+          &out_params->forward_secure_crypters, &out_params->subkey_secret)) {
+    *error_details = "Symmetric key setup failed";
+    return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate(
+    const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
+    const QuicTransportVersion version, absl::string_view chlo_hash,
+    CachedState* cached,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        out_params,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  if (server_config_update.tag() != kSCUP) {
+    *error_details = "ServerConfigUpdate must have kSCUP tag.";
+    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+  }
+  return CacheNewServerConfig(server_config_update, now, version, chlo_hash,
+                              out_params->cached_certs, cached, error_details);
+}
+
+ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
+  return proof_verifier_.get();
+}
+
+SessionCache* QuicCryptoClientConfig::session_cache() const {
+  return session_cache_.get();
+}
+
+ClientProofSource* QuicCryptoClientConfig::proof_source() const {
+  return proof_source_.get();
+}
+
+void QuicCryptoClientConfig::set_proof_source(
+    std::unique_ptr<ClientProofSource> proof_source) {
+  proof_source_ = std::move(proof_source);
+}
+
+SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const {
+  return ssl_ctx_.get();
+}
+
+void QuicCryptoClientConfig::InitializeFrom(
+    const QuicServerId& server_id,
+    const QuicServerId& canonical_server_id,
+    QuicCryptoClientConfig* canonical_crypto_config) {
+  CachedState* canonical_cached =
+      canonical_crypto_config->LookupOrCreate(canonical_server_id);
+  if (!canonical_cached->proof_valid()) {
+    return;
+  }
+  CachedState* cached = LookupOrCreate(server_id);
+  cached->InitializeFrom(*canonical_cached);
+}
+
+void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) {
+  canonical_suffixes_.push_back(suffix);
+}
+
+bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
+    const QuicServerId& server_id, CachedState* cached) {
+  QUICHE_DCHECK(cached->IsEmpty());
+  size_t i = 0;
+  for (; i < canonical_suffixes_.size(); ++i) {
+    if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) {
+      break;
+    }
+  }
+  if (i == canonical_suffixes_.size()) {
+    return false;
+  }
+
+  QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
+                                server_id.privacy_mode_enabled());
+  auto it = canonical_server_map_.lower_bound(suffix_server_id);
+  if (it == canonical_server_map_.end() || it->first != suffix_server_id) {
+    // This is the first host we've seen which matches the suffix, so make it
+    // canonical.  Use |it| as position hint for faster insertion.
+    canonical_server_map_.insert(
+        it, std::make_pair(std::move(suffix_server_id), std::move(server_id)));
+    return false;
+  }
+
+  const QuicServerId& canonical_server_id = it->second;
+  CachedState* canonical_state = cached_states_[canonical_server_id].get();
+  if (!canonical_state->proof_valid()) {
+    return false;
+  }
+
+  // Update canonical version to point at the "most recent" entry.
+  it->second = server_id;
+
+  cached->InitializeFrom(*canonical_state);
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config.h b/quiche/quic/core/crypto/quic_crypto_client_config.h
new file mode 100644
index 0000000..8b66ad5
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_client_config.h
@@ -0,0 +1,473 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/client_proof_source.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+class CryptoHandshakeMessage;
+class ProofVerifier;
+class ProofVerifyDetails;
+class QuicRandom;
+
+// QuicResumptionState stores the state a client needs for performing connection
+// resumption.
+struct QUIC_EXPORT_PRIVATE QuicResumptionState {
+  // |tls_session| holds the cryptographic state necessary for a resumption. It
+  // includes the ALPN negotiated on the connection where the ticket was
+  // received.
+  bssl::UniquePtr<SSL_SESSION> tls_session;
+
+  // If the application using QUIC doesn't support 0-RTT handshakes or the
+  // client didn't receive a 0-RTT capable session ticket from the server,
+  // |transport_params| will be null. Otherwise, it will contain the transport
+  // parameters received from the server on the original connection.
+  std::unique_ptr<TransportParameters> transport_params = nullptr;
+
+  // If |transport_params| is null, then |application_state| is ignored and
+  // should be empty. |application_state| contains serialized state that the
+  // client received from the server at the application layer that the client
+  // needs to remember when performing a 0-RTT handshake.
+  std::unique_ptr<ApplicationState> application_state = nullptr;
+
+  // Opaque token received in NEW_TOKEN frame if any.
+  std::string token;
+};
+
+// SessionCache is an interface for managing storing and retrieving
+// QuicResumptionState structs.
+class QUIC_EXPORT_PRIVATE SessionCache {
+ public:
+  virtual ~SessionCache() {}
+
+  // Inserts |session|, |params|, and |application_states| into the cache, keyed
+  // by |server_id|. Insert is first called after all three values are present.
+  // The ownership of |session| is transferred to the cache, while other two are
+  // copied. Multiple sessions might need to be inserted for a connection.
+  // SessionCache implementations should support storing
+  // multiple entries per server ID.
+  virtual void Insert(const QuicServerId& server_id,
+                      bssl::UniquePtr<SSL_SESSION> session,
+                      const TransportParameters& params,
+                      const ApplicationState* application_state) = 0;
+
+  // Lookup is called once at the beginning of each TLS handshake to potentially
+  // provide the saved state both for the TLS handshake and for sending 0-RTT
+  // data (if supported). Lookup may return a nullptr. Implementations should
+  // delete cache entries after returning them in Lookup so that session tickets
+  // are used only once.
+  virtual std::unique_ptr<QuicResumptionState> Lookup(
+      const QuicServerId& server_id, QuicWallTime now, const SSL_CTX* ctx) = 0;
+
+  // Called when 0-RTT is rejected. Disables early data for all the TLS tickets
+  // associated with |server_id|.
+  virtual void ClearEarlyData(const QuicServerId& server_id) = 0;
+
+  // Called when NEW_TOKEN frame is received.
+  virtual void OnNewTokenReceived(const QuicServerId& server_id,
+                                  absl::string_view token) = 0;
+
+  // Called to remove expired entries.
+  virtual void RemoveExpiredEntries(QuicWallTime now) = 0;
+
+  // Clear the session cache.
+  virtual void Clear() = 0;
+};
+
+// QuicCryptoClientConfig contains crypto-related configuration settings for a
+// client. Note that this object isn't thread-safe. It's designed to be used on
+// a single thread at a time.
+class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
+ public:
+  // A CachedState contains the information that the client needs in order to
+  // perform a 0-RTT handshake with a server. This information can be reused
+  // over several connections to the same server.
+  class QUIC_EXPORT_PRIVATE CachedState {
+   public:
+    // Enum to track if the server config is valid or not. If it is not valid,
+    // it specifies why it is invalid.
+    enum ServerConfigState {
+      // WARNING: Do not change the numerical values of any of server config
+      // state. Do not remove deprecated server config states - just comment
+      // them as deprecated.
+      SERVER_CONFIG_EMPTY = 0,
+      SERVER_CONFIG_INVALID = 1,
+      SERVER_CONFIG_CORRUPTED = 2,
+      SERVER_CONFIG_EXPIRED = 3,
+      SERVER_CONFIG_INVALID_EXPIRY = 4,
+      SERVER_CONFIG_VALID = 5,
+      // NOTE: Add new server config states only immediately above this line.
+      // Make sure to update the QuicServerConfigState enum in
+      // tools/metrics/histograms/histograms.xml accordingly.
+      SERVER_CONFIG_COUNT
+    };
+
+    CachedState();
+    CachedState(const CachedState&) = delete;
+    CachedState& operator=(const CachedState&) = delete;
+    ~CachedState();
+
+    // IsComplete returns true if this object contains enough information to
+    // perform a handshake with the server. |now| is used to judge whether any
+    // cached server config has expired.
+    bool IsComplete(QuicWallTime now) const;
+
+    // IsEmpty returns true if |server_config_| is empty.
+    bool IsEmpty() const;
+
+    // GetServerConfig returns the parsed contents of |server_config|, or
+    // nullptr if |server_config| is empty. The return value is owned by this
+    // object and is destroyed when this object is.
+    const CryptoHandshakeMessage* GetServerConfig() const;
+
+    // SetServerConfig checks that |server_config| parses correctly and stores
+    // it in |server_config_|. |now| is used to judge whether |server_config|
+    // has expired.
+    ServerConfigState SetServerConfig(absl::string_view server_config,
+                                      QuicWallTime now,
+                                      QuicWallTime expiry_time,
+                                      std::string* error_details);
+
+    // InvalidateServerConfig clears the cached server config (if any).
+    void InvalidateServerConfig();
+
+    // SetProof stores a cert chain, cert signed timestamp and signature.
+    void SetProof(const std::vector<std::string>& certs,
+                  absl::string_view cert_sct,
+                  absl::string_view chlo_hash,
+                  absl::string_view signature);
+
+    // Clears all the data.
+    void Clear();
+
+    // Clears the certificate chain and signature and invalidates the proof.
+    void ClearProof();
+
+    // SetProofValid records that the certificate chain and signature have been
+    // validated and that it's safe to assume that the server is legitimate.
+    // (Note: this does not check the chain or signature.)
+    void SetProofValid();
+
+    // If the server config or the proof has changed then it needs to be
+    // revalidated. Helper function to keep server_config_valid_ and
+    // generation_counter_ in sync.
+    void SetProofInvalid();
+
+    const std::string& server_config() const;
+    const std::string& source_address_token() const;
+    const std::vector<std::string>& certs() const;
+    const std::string& cert_sct() const;
+    const std::string& chlo_hash() const;
+    const std::string& signature() const;
+    bool proof_valid() const;
+    uint64_t generation_counter() const;
+    const ProofVerifyDetails* proof_verify_details() const;
+
+    void set_source_address_token(absl::string_view token);
+
+    void set_cert_sct(absl::string_view cert_sct);
+
+    // SetProofVerifyDetails takes ownership of |details|.
+    void SetProofVerifyDetails(ProofVerifyDetails* details);
+
+    // Copy the |server_config_|, |source_address_token_|, |certs_|,
+    // |expiration_time_|, |cert_sct_|, |chlo_hash_| and |server_config_sig_|
+    // from the |other|.  The remaining fields, |generation_counter_|,
+    // |proof_verify_details_|, and |scfg_| remain unchanged.
+    void InitializeFrom(const CachedState& other);
+
+    // Initializes this cached state based on the arguments provided.
+    // Returns false if there is a problem parsing the server config.
+    bool Initialize(absl::string_view server_config,
+                    absl::string_view source_address_token,
+                    const std::vector<std::string>& certs,
+                    const std::string& cert_sct,
+                    absl::string_view chlo_hash,
+                    absl::string_view signature,
+                    QuicWallTime now,
+                    QuicWallTime expiration_time);
+
+   private:
+    std::string server_config_;         // A serialized handshake message.
+    std::string source_address_token_;  // An opaque proof of IP ownership.
+    std::vector<std::string> certs_;    // A list of certificates in leaf-first
+                                        // order.
+    std::string cert_sct_;              // Signed timestamp of the leaf cert.
+    std::string chlo_hash_;             // Hash of the CHLO message.
+    std::string server_config_sig_;     // A signature of |server_config_|.
+    bool server_config_valid_;          // True if |server_config_| is correctly
+                                // signed and |certs_| has been validated.
+    QuicWallTime expiration_time_;  // Time when the config is no longer valid.
+    // Generation counter associated with the |server_config_|, |certs_| and
+    // |server_config_sig_| combination. It is incremented whenever we set
+    // server_config_valid_ to false.
+    uint64_t generation_counter_;
+
+    std::unique_ptr<ProofVerifyDetails> proof_verify_details_;
+
+    // scfg contains the cached, parsed value of |server_config|.
+    mutable std::unique_ptr<CryptoHandshakeMessage> scfg_;
+  };
+
+  // Used to filter server ids for partial config deletion.
+  class QUIC_EXPORT_PRIVATE ServerIdFilter {
+   public:
+    virtual ~ServerIdFilter() {}
+
+    // Returns true if |server_id| matches the filter.
+    virtual bool Matches(const QuicServerId& server_id) const = 0;
+  };
+
+  // DEPRECATED: Use the constructor below instead.
+  explicit QuicCryptoClientConfig(
+      std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier,
+                         std::unique_ptr<SessionCache> session_cache);
+  QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete;
+  QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete;
+  ~QuicCryptoClientConfig();
+
+  // LookupOrCreate returns a CachedState for the given |server_id|. If no such
+  // CachedState currently exists, it will be created and cached.
+  CachedState* LookupOrCreate(const QuicServerId& server_id);
+
+  // Delete CachedState objects whose server ids match |filter| from
+  // cached_states.
+  void ClearCachedStates(const ServerIdFilter& filter);
+
+  // FillInchoateClientHello sets |out| to be a CHLO message that elicits a
+  // source-address token or SCFG from a server. If |cached| is non-nullptr, the
+  // source-address token will be taken from it. |out_params| is used in order
+  // to store the cached certs that were sent as hints to the server in
+  // |out_params->cached_certs|. |preferred_version| is the version of the
+  // QUIC protocol that this client chose to use initially. This allows the
+  // server to detect downgrade attacks.  If |demand_x509_proof| is true,
+  // then |out| will include an X509 proof demand, and the associated
+  // certificate related fields.
+  void FillInchoateClientHello(
+      const QuicServerId& server_id, const ParsedQuicVersion preferred_version,
+      const CachedState* cached, QuicRandom* rand, bool demand_x509_proof,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      CryptoHandshakeMessage* out) const;
+
+  // FillClientHello sets |out| to be a CHLO message based on the configuration
+  // of this object. This object must have cached enough information about
+  // the server's hostname in order to perform a handshake. This can be checked
+  // with the |IsComplete| member of |CachedState|.
+  //
+  // |now| and |rand| are used to generate the nonce and |out_params| is
+  // filled with the results of the handshake that the server is expected to
+  // accept. |preferred_version| is the version of the QUIC protocol that this
+  // client chose to use initially. This allows the server to detect downgrade
+  // attacks.
+  //
+  // If |channel_id_key| is not null, it is used to sign a secret value derived
+  // from the client and server's keys, and the Channel ID public key and the
+  // signature are placed in the CETV value of the CHLO.
+  QuicErrorCode FillClientHello(
+      const QuicServerId& server_id, QuicConnectionId connection_id,
+      const ParsedQuicVersion preferred_version,
+      const ParsedQuicVersion actual_version, const CachedState* cached,
+      QuicWallTime now, QuicRandom* rand,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      CryptoHandshakeMessage* out, std::string* error_details) const;
+
+  // ProcessRejection processes a REJ message from a server and updates the
+  // cached information about that server. After this, |IsComplete| may return
+  // true for that server's CachedState. If the rejection message contains state
+  // about a future handshake (i.e. an nonce value from the server), then it
+  // will be saved in |out_params|. |now| is used to judge whether the server
+  // config in the rejection message has expired.
+  QuicErrorCode ProcessRejection(
+      const CryptoHandshakeMessage& rej, QuicWallTime now,
+      QuicTransportVersion version, absl::string_view chlo_hash,
+      CachedState* cached,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      std::string* error_details);
+
+  // ProcessServerHello processes the message in |server_hello|, updates the
+  // cached information about that server, writes the negotiated parameters to
+  // |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable
+  // then it puts an error message in |error_details| and returns an error
+  // code. |version| is the QUIC version for the current connection.
+  // |negotiated_versions| contains the list of version, if any, that were
+  // present in a version negotiation packet previously received from the
+  // server. The contents of this list will be compared against the list of
+  // versions provided in the VER tag of the server hello.
+  QuicErrorCode ProcessServerHello(
+      const CryptoHandshakeMessage& server_hello,
+      QuicConnectionId connection_id, ParsedQuicVersion version,
+      const ParsedQuicVersionVector& negotiated_versions, CachedState* cached,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      std::string* error_details);
+
+  // Processes the message in |server_config_update|, updating the cached source
+  // address token, and server config.
+  // If |server_config_update| is invalid then |error_details| will contain an
+  // error message, and an error code will be returned. If all has gone well
+  // QUIC_NO_ERROR is returned.
+  QuicErrorCode ProcessServerConfigUpdate(
+      const CryptoHandshakeMessage& server_config_update, QuicWallTime now,
+      const QuicTransportVersion version, absl::string_view chlo_hash,
+      CachedState* cached,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          out_params,
+      std::string* error_details);
+
+  ProofVerifier* proof_verifier() const;
+  SessionCache* session_cache() const;
+  ClientProofSource* proof_source() const;
+  void set_proof_source(std::unique_ptr<ClientProofSource> proof_source);
+  SSL_CTX* ssl_ctx() const;
+
+  // Initialize the CachedState from |canonical_crypto_config| for the
+  // |canonical_server_id| as the initial CachedState for |server_id|. We will
+  // copy config data only if |canonical_crypto_config| has valid proof.
+  void InitializeFrom(const QuicServerId& server_id,
+                      const QuicServerId& canonical_server_id,
+                      QuicCryptoClientConfig* canonical_crypto_config);
+
+  // Adds |suffix| as a domain suffix for which the server's crypto config
+  // is expected to be shared among servers with the domain suffix. If a server
+  // matches this suffix, then the server config from another server with the
+  // suffix will be used to initialize the cached state for this server.
+  void AddCanonicalSuffix(const std::string& suffix);
+
+  // Saves the |user_agent_id| that will be passed in QUIC's CHLO message.
+  void set_user_agent_id(const std::string& user_agent_id) {
+    user_agent_id_ = user_agent_id;
+  }
+
+  // Returns the user_agent_id that will be provided in the client hello
+  // handshake message.
+  const std::string& user_agent_id() const { return user_agent_id_; }
+
+  void set_tls_signature_algorithms(std::string signature_algorithms) {
+    tls_signature_algorithms_ = std::move(signature_algorithms);
+  }
+
+  const absl::optional<std::string>& tls_signature_algorithms() const {
+    return tls_signature_algorithms_;
+  }
+
+  // Saves the |alpn| that will be passed in QUIC's CHLO message.
+  void set_alpn(const std::string& alpn) { alpn_ = alpn; }
+
+  // Saves the pre-shared key used during the handshake.
+  void set_pre_shared_key(absl::string_view psk) {
+    pre_shared_key_ = std::string(psk);
+  }
+
+  // Returns the pre-shared key used during the handshake.
+  const std::string& pre_shared_key() const { return pre_shared_key_; }
+
+  bool pad_inchoate_hello() const { return pad_inchoate_hello_; }
+  void set_pad_inchoate_hello(bool new_value) {
+    pad_inchoate_hello_ = new_value;
+  }
+
+  bool pad_full_hello() const { return pad_full_hello_; }
+  void set_pad_full_hello(bool new_value) { pad_full_hello_ = new_value; }
+
+  SessionCache* mutable_session_cache() { return session_cache_.get(); }
+
+ private:
+  // Sets the members to reasonable, default values.
+  void SetDefaults();
+
+  // CacheNewServerConfig checks for SCFG, STK, PROF, and CRT tags in |message|,
+  // verifies them, and stores them in the cached state if they validate.
+  // This is used on receipt of a REJ from a server, or when a server sends
+  // updated server config during a connection.
+  QuicErrorCode CacheNewServerConfig(
+      const CryptoHandshakeMessage& message,
+      QuicWallTime now,
+      QuicTransportVersion version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& cached_certs,
+      CachedState* cached,
+      std::string* error_details);
+
+  // If the suffix of the hostname in |server_id| is in |canonical_suffixes_|,
+  // then populate |cached| with the canonical cached state from
+  // |canonical_server_map_| for that suffix. Returns true if |cached| is
+  // initialized with canonical cached state.
+  bool PopulateFromCanonicalConfig(const QuicServerId& server_id,
+                                   CachedState* cached);
+
+  // cached_states_ maps from the server_id to the cached information about
+  // that server.
+  std::map<QuicServerId, std::unique_ptr<CachedState>> cached_states_;
+
+  // Contains a map of servers which could share the same server config. Map
+  // from a canonical host suffix/port/scheme to a representative server with
+  // the canonical suffix, which has a plausible set of initial certificates
+  // (or at least server public key).
+  std::map<QuicServerId, QuicServerId> canonical_server_map_;
+
+  // Contains list of suffixes (for exmaple ".c.youtube.com",
+  // ".googlevideo.com") of canonical hostnames.
+  std::vector<std::string> canonical_suffixes_;
+
+  std::unique_ptr<ProofVerifier> proof_verifier_;
+  std::unique_ptr<SessionCache> session_cache_;
+  std::unique_ptr<ClientProofSource> proof_source_;
+
+  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+
+  // The |user_agent_id_| passed in QUIC's CHLO message.
+  std::string user_agent_id_;
+
+  // The |alpn_| passed in QUIC's CHLO message.
+  std::string alpn_;
+
+  // If non-empty, the client will operate in the pre-shared key mode by
+  // incorporating |pre_shared_key_| into the key schedule.
+  std::string pre_shared_key_;
+
+  // If set, configure the client to use the specified signature algorithms, via
+  // SSL_set1_sigalgs_list. TLS only.
+  absl::optional<std::string> tls_signature_algorithms_;
+
+  // In QUIC, technically, client hello should be fully padded.
+  // However, fully padding on slow network connection (e.g. 50kbps) can add
+  // 150ms latency to one roundtrip. Therefore, you can disable padding of
+  // individual messages. It is recommend to leave at least one message in
+  // each direction fully padded (e.g. full CHLO and SHLO), but if you know
+  // the lower-bound MTU, you don't need to pad all of them (keep in mind that
+  // it's not OK to do it according to the standard).
+  //
+  // Also, if you disable padding, you must disable (change) the
+  // anti-amplification protection. You should only do so if you have some
+  // other means of verifying the client.
+  bool pad_inchoate_hello_ = true;
+  bool pad_full_hello_ = true;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_client_config_test.cc b/quiche/quic/core/crypto/quic_crypto_client_config_test.cc
new file mode 100644
index 0000000..7556592
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_client_config_test.cc
@@ -0,0 +1,550 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::StartsWith;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestProofVerifyDetails : public ProofVerifyDetails {
+  ~TestProofVerifyDetails() override {}
+
+  // ProofVerifyDetails implementation
+  ProofVerifyDetails* Clone() const override {
+    return new TestProofVerifyDetails;
+  }
+};
+
+class OneServerIdFilter : public QuicCryptoClientConfig::ServerIdFilter {
+ public:
+  explicit OneServerIdFilter(const QuicServerId* server_id)
+      : server_id_(*server_id) {}
+
+  bool Matches(const QuicServerId& server_id) const override {
+    return server_id == server_id_;
+  }
+
+ private:
+  const QuicServerId server_id_;
+};
+
+class AllServerIdsFilter : public QuicCryptoClientConfig::ServerIdFilter {
+ public:
+  bool Matches(const QuicServerId& /*server_id*/) const override {
+    return true;
+  }
+};
+
+}  // namespace
+
+class QuicCryptoClientConfigTest : public QuicTest {};
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_IsEmpty) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_TRUE(state.IsEmpty());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_IsComplete) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_FALSE(state.IsComplete(QuicWallTime::FromUNIXSeconds(0)));
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_GenerationCounter) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_EQ(0u, state.generation_counter());
+  state.SetProofInvalid();
+  EXPECT_EQ(1u, state.generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) {
+  QuicCryptoClientConfig::CachedState state;
+  EXPECT_TRUE(state.proof_verify_details() == nullptr);
+  ProofVerifyDetails* details = new TestProofVerifyDetails;
+  state.SetProofVerifyDetails(details);
+  EXPECT_EQ(details, state.proof_verify_details());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig::CachedState other;
+  state.set_source_address_token("TOKEN");
+  // TODO(rch): Populate other fields of |state|.
+  other.InitializeFrom(state);
+  EXPECT_EQ(state.server_config(), other.server_config());
+  EXPECT_EQ(state.source_address_token(), other.source_address_token());
+  EXPECT_EQ(state.certs(), other.certs());
+  EXPECT_EQ(1u, other.generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.set_user_agent_id("quic-tester");
+  config.set_alpn("hq");
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  QuicVersionLabel cver;
+  EXPECT_THAT(msg.GetVersionLabel(kVER, &cver), IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
+  absl::string_view proof_nonce;
+  EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce));
+  EXPECT_EQ(std::string(32, 'r'), proof_nonce);
+  absl::string_view user_agent_id;
+  EXPECT_TRUE(msg.GetStringPiece(kUAID, &user_agent_id));
+  EXPECT_EQ("quic-tester", user_agent_id);
+  absl::string_view alpn;
+  EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn));
+  EXPECT_EQ("hq", alpn);
+  EXPECT_EQ(msg.minimum_size(), 1u);
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloIsNotPadded) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.set_pad_inchoate_hello(false);
+  config.set_user_agent_id("quic-tester");
+  config.set_alpn("hq");
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  EXPECT_EQ(msg.minimum_size(), 1u);
+}
+
+// Make sure AES-GCM is the preferred encryption algorithm if it has hardware
+// acceleration.
+TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  if (EVP_has_aes_hardware() == 1) {
+    EXPECT_EQ(kAESG, config.aead[0]);
+  } else {
+    EXPECT_EQ(kCC20, config.aead[0]);
+  }
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  QuicTag pdmd;
+  EXPECT_THAT(msg.GetUint32(kPDMD, &pdmd), IsQuicNoError());
+  EXPECT_EQ(kX509, pdmd);
+  absl::string_view scid;
+  EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid));
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) {
+  // Test that a config with no EXPY is still valid when a non-zero
+  // expiry time is passed in.
+  QuicCryptoClientConfig::CachedState state;
+  CryptoHandshakeMessage scfg;
+  scfg.set_tag(kSCFG);
+  scfg.SetStringPiece(kSCID, "12345678");
+  std::string details;
+  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
+  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
+  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
+                        &details);
+  EXPECT_FALSE(state.IsEmpty());
+
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  absl::string_view scid;
+  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
+  EXPECT_EQ("12345678", scid);
+}
+
+TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
+  QuicCryptoClientConfig::CachedState state;
+  CryptoHandshakeMessage scfg;
+  scfg.set_tag(kSCFG);
+  uint64_t future = 1;
+  scfg.SetValue(kEXPY, future);
+  scfg.SetStringPiece(kSCID, "12345678");
+  std::string details;
+  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(),
+                        QuicWallTime::FromUNIXSeconds(1),
+                        QuicWallTime::FromUNIXSeconds(0), &details);
+  EXPECT_FALSE(state.IsEmpty());
+
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  CryptoHandshakeMessage msg;
+  QuicServerId server_id("www.google.com", 443, false);
+  MockRandom rand;
+  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+                                 /* demand_x509_proof= */ true, params, &msg);
+
+  absl::string_view scid;
+  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
+  EXPECT_EQ("12345678", scid);
+}
+
+TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  QuicConnectionId kConnectionId = TestConnectionId(1234);
+  std::string error_details;
+  MockRandom rand;
+  CryptoHandshakeMessage chlo;
+  QuicServerId server_id("www.google.com", 443, false);
+  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
+                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
+                         params, &chlo, &error_details);
+
+  // Verify that the version label has been set correctly in the CHLO.
+  QuicVersionLabel cver;
+  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
+}
+
+TEST_F(QuicCryptoClientConfigTest, FillClientHelloNoPadding) {
+  QuicCryptoClientConfig::CachedState state;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.set_pad_full_hello(false);
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
+      new QuicCryptoNegotiatedParameters);
+  QuicConnectionId kConnectionId = TestConnectionId(1234);
+  std::string error_details;
+  MockRandom rand;
+  CryptoHandshakeMessage chlo;
+  QuicServerId server_id("www.google.com", 443, false);
+  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
+                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
+                         params, &chlo, &error_details);
+
+  // Verify that the version label has been set correctly in the CHLO.
+  QuicVersionLabel cver;
+  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
+  EXPECT_EQ(chlo.minimum_size(), 1u);
+}
+
+TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  if (supported_versions.size() == 1) {
+    // No downgrade attack is possible if the client only supports one version.
+    return;
+  }
+
+  ParsedQuicVersionVector supported_version_vector;
+  for (size_t i = supported_versions.size(); i > 0; --i) {
+    supported_version_vector.push_back(supported_versions[i - 1]);
+  }
+
+  CryptoHandshakeMessage msg;
+  msg.set_tag(kSHLO);
+  msg.SetVersionVector(kVER, supported_version_vector);
+
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  EXPECT_THAT(config.ProcessServerHello(
+                  msg, EmptyQuicConnectionId(), supported_versions.front(),
+                  supported_versions, &cached, out_params, &error),
+              IsError(QUIC_VERSION_NEGOTIATION_MISMATCH));
+  EXPECT_THAT(error, StartsWith("Downgrade attack detected: ServerVersions"));
+}
+
+TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  QuicServerId canonical_server_id("www.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state =
+      config.LookupOrCreate(canonical_server_id);
+  // TODO(rch): Populate other fields of |state|.
+  state->set_source_address_token("TOKEN");
+  state->SetProofValid();
+
+  QuicServerId other_server_id("mail.google.com", 443, false);
+  config.InitializeFrom(other_server_id, canonical_server_id, &config);
+  QuicCryptoClientConfig::CachedState* other =
+      config.LookupOrCreate(other_server_id);
+
+  EXPECT_EQ(state->server_config(), other->server_config());
+  EXPECT_EQ(state->source_address_token(), other->source_address_token());
+  EXPECT_EQ(state->certs(), other->certs());
+  EXPECT_EQ(1u, other->generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, Canonical) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.AddCanonicalSuffix(".google.com");
+  QuicServerId canonical_id1("www.google.com", 443, false);
+  QuicServerId canonical_id2("mail.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state =
+      config.LookupOrCreate(canonical_id1);
+  // TODO(rch): Populate other fields of |state|.
+  state->set_source_address_token("TOKEN");
+  state->SetProofValid();
+
+  QuicCryptoClientConfig::CachedState* other =
+      config.LookupOrCreate(canonical_id2);
+
+  EXPECT_TRUE(state->IsEmpty());
+  EXPECT_EQ(state->server_config(), other->server_config());
+  EXPECT_EQ(state->source_address_token(), other->source_address_token());
+  EXPECT_EQ(state->certs(), other->certs());
+  EXPECT_EQ(1u, other->generation_counter());
+
+  QuicServerId different_id("mail.google.org", 443, false);
+  EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty());
+}
+
+TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.AddCanonicalSuffix(".google.com");
+  QuicServerId canonical_id1("www.google.com", 443, false);
+  QuicServerId canonical_id2("mail.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state =
+      config.LookupOrCreate(canonical_id1);
+  // TODO(rch): Populate other fields of |state|.
+  state->set_source_address_token("TOKEN");
+
+  // Do not set the proof as valid, and check that it is not used
+  // as a canonical entry.
+  EXPECT_TRUE(config.LookupOrCreate(canonical_id2)->IsEmpty());
+}
+
+TEST_F(QuicCryptoClientConfigTest, ClearCachedStates) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+
+  // Create two states on different origins.
+  struct TestCase {
+    TestCase(const std::string& host, QuicCryptoClientConfig* config)
+        : server_id(host, 443, false),
+          state(config->LookupOrCreate(server_id)) {
+      // TODO(rch): Populate other fields of |state|.
+      CryptoHandshakeMessage scfg;
+      scfg.set_tag(kSCFG);
+      uint64_t future = 1;
+      scfg.SetValue(kEXPY, future);
+      scfg.SetStringPiece(kSCID, "12345678");
+      std::string details;
+      state->SetServerConfig(scfg.GetSerialized().AsStringPiece(),
+                             QuicWallTime::FromUNIXSeconds(0),
+                             QuicWallTime::FromUNIXSeconds(future), &details);
+
+      std::vector<std::string> certs(1);
+      certs[0] = "Hello Cert for " + host;
+      state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
+      state->set_source_address_token("TOKEN");
+      state->SetProofValid();
+
+      // The generation counter starts at 2, because proof has been once
+      // invalidated in SetServerConfig().
+      EXPECT_EQ(2u, state->generation_counter());
+    }
+
+    QuicServerId server_id;
+    QuicCryptoClientConfig::CachedState* state;
+  } test_cases[] = {TestCase("www.google.com", &config),
+                    TestCase("www.example.com", &config)};
+
+  // Verify LookupOrCreate returns the same data.
+  for (const TestCase& test_case : test_cases) {
+    QuicCryptoClientConfig::CachedState* other =
+        config.LookupOrCreate(test_case.server_id);
+    EXPECT_EQ(test_case.state, other);
+    EXPECT_EQ(2u, other->generation_counter());
+  }
+
+  // Clear the cached state for www.google.com.
+  OneServerIdFilter google_com_filter(&test_cases[0].server_id);
+  config.ClearCachedStates(google_com_filter);
+
+  // Verify LookupOrCreate doesn't have any data for google.com.
+  QuicCryptoClientConfig::CachedState* cleared_cache =
+      config.LookupOrCreate(test_cases[0].server_id);
+
+  EXPECT_EQ(test_cases[0].state, cleared_cache);
+  EXPECT_FALSE(cleared_cache->proof_valid());
+  EXPECT_TRUE(cleared_cache->server_config().empty());
+  EXPECT_TRUE(cleared_cache->certs().empty());
+  EXPECT_TRUE(cleared_cache->cert_sct().empty());
+  EXPECT_TRUE(cleared_cache->signature().empty());
+  EXPECT_EQ(3u, cleared_cache->generation_counter());
+
+  // But it still does for www.example.com.
+  QuicCryptoClientConfig::CachedState* existing_cache =
+      config.LookupOrCreate(test_cases[1].server_id);
+
+  EXPECT_EQ(test_cases[1].state, existing_cache);
+  EXPECT_TRUE(existing_cache->proof_valid());
+  EXPECT_FALSE(existing_cache->server_config().empty());
+  EXPECT_FALSE(existing_cache->certs().empty());
+  EXPECT_FALSE(existing_cache->cert_sct().empty());
+  EXPECT_FALSE(existing_cache->signature().empty());
+  EXPECT_EQ(2u, existing_cache->generation_counter());
+
+  // Clear all cached states.
+  AllServerIdsFilter all_server_ids;
+  config.ClearCachedStates(all_server_ids);
+
+  // The data for www.example.com should now be cleared as well.
+  cleared_cache = config.LookupOrCreate(test_cases[1].server_id);
+
+  EXPECT_EQ(test_cases[1].state, cleared_cache);
+  EXPECT_FALSE(cleared_cache->proof_valid());
+  EXPECT_TRUE(cleared_cache->server_config().empty());
+  EXPECT_TRUE(cleared_cache->certs().empty());
+  EXPECT_TRUE(cleared_cache->cert_sct().empty());
+  EXPECT_TRUE(cleared_cache->signature().empty());
+  EXPECT_EQ(3u, cleared_cache->generation_counter());
+}
+
+TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej);
+
+  // Now process the rejection.
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  EXPECT_THAT(
+      config.ProcessRejection(
+          rej, QuicWallTime::FromUNIXSeconds(0),
+          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
+          &cached, out_params, &error),
+      IsQuicNoError());
+}
+
+TEST_F(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) {
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej);
+  QuicTime::Delta one_week = QuicTime::Delta::FromSeconds(kNumSecondsPerWeek);
+  int64_t long_ttl = 3 * one_week.ToSeconds();
+  rej.SetValue(kSTTL, long_ttl);
+
+  // Now process the rejection.
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error;
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  EXPECT_THAT(
+      config.ProcessRejection(
+          rej, QuicWallTime::FromUNIXSeconds(0),
+          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
+          &cached, out_params, &error),
+      IsQuicNoError());
+  cached.SetProofValid();
+  EXPECT_FALSE(cached.IsComplete(QuicWallTime::FromUNIXSeconds(long_ttl)));
+  EXPECT_FALSE(
+      cached.IsComplete(QuicWallTime::FromUNIXSeconds(one_week.ToSeconds())));
+  EXPECT_TRUE(cached.IsComplete(
+      QuicWallTime::FromUNIXSeconds(one_week.ToSeconds() - 1)));
+}
+
+TEST_F(QuicCryptoClientConfigTest, ServerNonceinSHLO) {
+  // Test that the server must include a nonce in the SHLO.
+  CryptoHandshakeMessage msg;
+  msg.set_tag(kSHLO);
+  // Choose the latest version.
+  ParsedQuicVersionVector supported_versions;
+  ParsedQuicVersion version = AllSupportedVersions().front();
+  supported_versions.push_back(version);
+  msg.SetVersionVector(kVER, supported_versions);
+
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  QuicCryptoClientConfig::CachedState cached;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      out_params(new QuicCryptoNegotiatedParameters);
+  std::string error_details;
+  EXPECT_THAT(config.ProcessServerHello(msg, EmptyQuicConnectionId(), version,
+                                        supported_versions, &cached, out_params,
+                                        &error_details),
+              IsError(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER));
+  EXPECT_EQ("server hello missing server nonce", error_details);
+}
+
+// Test that PopulateFromCanonicalConfig() handles the case of multiple entries
+// in |canonical_server_map_|.
+TEST_F(QuicCryptoClientConfigTest, MultipleCanonicalEntries) {
+  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+  config.AddCanonicalSuffix(".google.com");
+  QuicServerId canonical_server_id1("www.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state1 =
+      config.LookupOrCreate(canonical_server_id1);
+
+  CryptoHandshakeMessage scfg;
+  scfg.set_tag(kSCFG);
+  scfg.SetStringPiece(kSCID, "12345678");
+  std::string details;
+  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
+  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
+  state1->SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
+                          &details);
+  state1->set_source_address_token("TOKEN");
+  state1->SetProofValid();
+  EXPECT_FALSE(state1->IsEmpty());
+
+  // This will have the same |suffix_server_id| as |canonical_server_id1|,
+  // therefore |*state2| will be initialized from |*state1|.
+  QuicServerId canonical_server_id2("mail.google.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state2 =
+      config.LookupOrCreate(canonical_server_id2);
+  EXPECT_FALSE(state2->IsEmpty());
+  const CryptoHandshakeMessage* const scfg2 = state2->GetServerConfig();
+  ASSERT_TRUE(scfg2);
+  EXPECT_EQ(kSCFG, scfg2->tag());
+
+  // With a different |suffix_server_id|, this will return an empty CachedState.
+  config.AddCanonicalSuffix(".example.com");
+  QuicServerId canonical_server_id3("www.example.com", 443, false);
+  QuicCryptoClientConfig::CachedState* state3 =
+      config.LookupOrCreate(canonical_server_id3);
+  EXPECT_TRUE(state3->IsEmpty());
+  const CryptoHandshakeMessage* const scfg3 = state3->GetServerConfig();
+  EXPECT_FALSE(scfg3);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_proof.cc b/quiche/quic/core/crypto/quic_crypto_proof.cc
new file mode 100644
index 0000000..a449c26
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_proof.cc
@@ -0,0 +1,12 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_crypto_proof.h"
+
+namespace quic {
+
+QuicCryptoProof::QuicCryptoProof()
+    : send_expect_ct_header(false), cert_matched_sni(false) {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_proof.h b/quiche/quic/core/crypto/quic_crypto_proof.h
new file mode 100644
index 0000000..579d264
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_proof.h
@@ -0,0 +1,32 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Contains the crypto-related data provided by ProofSource
+struct QUIC_EXPORT_PRIVATE QuicCryptoProof {
+  QuicCryptoProof();
+
+  // Signature generated by ProofSource
+  std::string signature;
+  // SCTList (RFC6962) to be sent to the client, if it supports receiving it.
+  std::string leaf_cert_scts;
+  // Should the Expect-CT header be sent on the connection where the
+  // certificate is used.
+  bool send_expect_ct_header;
+  // Did the selected leaf certificate contain a SubjectAltName that included
+  // the requested SNI.
+  bool cert_matched_sni;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_PROOF_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config.cc b/quiche/quic/core/crypto/quic_crypto_server_config.cc
new file mode 100644
index 0000000..aa2d6e0
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_server_config.cc
@@ -0,0 +1,1918 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/channel_id.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/p256_key_exchange.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/crypto/tls_server_connection.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/proto/source_address_token_proto.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+namespace {
+
+// kMultiplier is the multiple of the CHLO message size that a REJ message
+// must stay under when the client doesn't present a valid source-address
+// token. This is used to protect QUIC from amplification attacks.
+// TODO(rch): Reduce this to 2 again once b/25933682 is fixed.
+const size_t kMultiplier = 3;
+
+const int kMaxTokenAddresses = 4;
+
+std::string DeriveSourceAddressTokenKey(
+    absl::string_view source_address_token_secret) {
+  QuicHKDF hkdf(source_address_token_secret, absl::string_view() /* no salt */,
+                "QUIC source address token key",
+                CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */,
+                0 /* no subkey secret */);
+  return std::string(hkdf.server_write_key());
+}
+
+// Default source for creating KeyExchange objects.
+class DefaultKeyExchangeSource : public KeyExchangeSource {
+ public:
+  DefaultKeyExchangeSource() = default;
+  ~DefaultKeyExchangeSource() override = default;
+
+  std::unique_ptr<AsynchronousKeyExchange> Create(
+      std::string /*server_config_id*/,
+      bool /* is_fallback */,
+      QuicTag type,
+      absl::string_view private_key) override {
+    if (private_key.empty()) {
+      QUIC_LOG(WARNING) << "Server config contains key exchange method without "
+                           "corresponding private key of type "
+                        << QuicTagToString(type);
+      return nullptr;
+    }
+
+    std::unique_ptr<SynchronousKeyExchange> ka =
+        CreateLocalSynchronousKeyExchange(type, private_key);
+    if (!ka) {
+      QUIC_LOG(WARNING) << "Failed to create key exchange method of type "
+                        << QuicTagToString(type);
+    }
+    return ka;
+  }
+};
+
+// Returns true if the PDMD field from the client hello demands an X509
+// certificate.
+bool ClientDemandsX509Proof(const CryptoHandshakeMessage& client_hello) {
+  QuicTagVector their_proof_demands;
+
+  if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) {
+    return false;
+  }
+
+  for (const QuicTag tag : their_proof_demands) {
+    if (tag == kX509) {
+      return true;
+    }
+  }
+  return false;
+}
+
+std::string FormatCryptoHandshakeMessageForTrace(
+    const CryptoHandshakeMessage* message) {
+  if (message == nullptr) {
+    return "<null message>";
+  }
+
+  std::string s = QuicTagToString(message->tag());
+
+  // Append the reasons for REJ.
+  if (const auto it = message->tag_value_map().find(kRREJ);
+      it != message->tag_value_map().end()) {
+    const std::string& value = it->second;
+    // The value is a vector of uint32_t(s).
+    if (value.size() % sizeof(uint32_t) == 0) {
+      absl::StrAppend(&s, " RREJ:[");
+      // Append comma-separated list of reasons to |s|.
+      for (size_t j = 0; j < value.size(); j += sizeof(uint32_t)) {
+        uint32_t reason;
+        memcpy(&reason, value.data() + j, sizeof(reason));
+        if (j > 0) {
+          absl::StrAppend(&s, ",");
+        }
+        absl::StrAppend(&s, CryptoUtils::HandshakeFailureReasonToString(
+                                static_cast<HandshakeFailureReason>(reason)));
+      }
+      absl::StrAppend(&s, "]");
+    } else {
+      absl::StrAppendFormat(&s, " RREJ:[unexpected length:%u]", value.size());
+    }
+  }
+
+  return s;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<KeyExchangeSource> KeyExchangeSource::Default() {
+  return std::make_unique<DefaultKeyExchangeSource>();
+}
+
+class ValidateClientHelloHelper {
+ public:
+  // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when
+  // ValidationComplete is called.
+  ValidateClientHelloHelper(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          result,
+      std::unique_ptr<ValidateClientHelloResultCallback>* done_cb)
+      : result_(std::move(result)), done_cb_(done_cb) {}
+  ValidateClientHelloHelper(const ValidateClientHelloHelper&) = delete;
+  ValidateClientHelloHelper& operator=(const ValidateClientHelloHelper&) =
+      delete;
+
+  ~ValidateClientHelloHelper() {
+    QUIC_BUG_IF(quic_bug_12963_1, done_cb_ != nullptr)
+        << "Deleting ValidateClientHelloHelper with a pending callback.";
+  }
+
+  void ValidationComplete(
+      QuicErrorCode error_code,
+      const char* error_details,
+      std::unique_ptr<ProofSource::Details> proof_source_details) {
+    result_->error_code = error_code;
+    result_->error_details = error_details;
+    (*done_cb_)->Run(std::move(result_), std::move(proof_source_details));
+    DetachCallback();
+  }
+
+  void DetachCallback() {
+    QUIC_BUG_IF(quic_bug_10630_1, done_cb_ == nullptr)
+        << "Callback already detached.";
+    done_cb_ = nullptr;
+  }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result_;
+  std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_;
+};
+
+// static
+const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
+
+ClientHelloInfo::ClientHelloInfo(const QuicIpAddress& in_client_ip,
+                                 QuicWallTime in_now)
+    : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
+
+ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default;
+
+ClientHelloInfo::~ClientHelloInfo() {}
+
+PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {}
+
+PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {}
+
+ValidateClientHelloResultCallback::Result::Result(
+    const CryptoHandshakeMessage& in_client_hello,
+    QuicIpAddress in_client_ip,
+    QuicWallTime in_now)
+    : client_hello(in_client_hello),
+      info(in_client_ip, in_now),
+      error_code(QUIC_NO_ERROR) {}
+
+ValidateClientHelloResultCallback::Result::~Result() {}
+
+ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {}
+
+ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {}
+
+ProcessClientHelloResultCallback::ProcessClientHelloResultCallback() {}
+
+ProcessClientHelloResultCallback::~ProcessClientHelloResultCallback() {}
+
+QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
+    : expiry_time(QuicWallTime::Zero()),
+      channel_id_enabled(false),
+      p256(false) {}
+
+QuicCryptoServerConfig::ConfigOptions::ConfigOptions(
+    const ConfigOptions& other) = default;
+
+QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {}
+
+QuicCryptoServerConfig::ProcessClientHelloContext::
+    ~ProcessClientHelloContext() {
+  if (done_cb_ != nullptr) {
+    QUIC_LOG(WARNING)
+        << "Deleting ProcessClientHelloContext with a pending callback.";
+  }
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloContext::Fail(
+    QuicErrorCode error,
+    const std::string& error_details) {
+  QUIC_TRACEPRINTF("ProcessClientHello failed: error=%s, details=%s",
+                   QuicErrorCodeToString(error), error_details);
+  done_cb_->Run(error, error_details, nullptr, nullptr, nullptr);
+  done_cb_ = nullptr;
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloContext::Succeed(
+    std::unique_ptr<CryptoHandshakeMessage> message,
+    std::unique_ptr<DiversificationNonce> diversification_nonce,
+    std::unique_ptr<ProofSource::Details> proof_source_details) {
+  QUIC_TRACEPRINTF("ProcessClientHello succeeded: %s",
+                   FormatCryptoHandshakeMessageForTrace(message.get()));
+
+  done_cb_->Run(QUIC_NO_ERROR, std::string(), std::move(message),
+                std::move(diversification_nonce),
+                std::move(proof_source_details));
+  done_cb_ = nullptr;
+}
+
+QuicCryptoServerConfig::QuicCryptoServerConfig(
+    absl::string_view source_address_token_secret,
+    QuicRandom* server_nonce_entropy,
+    std::unique_ptr<ProofSource> proof_source,
+    std::unique_ptr<KeyExchangeSource> key_exchange_source)
+    : replay_protection_(true),
+      chlo_multiplier_(kMultiplier),
+      configs_lock_(),
+      primary_config_(nullptr),
+      next_config_promotion_time_(QuicWallTime::Zero()),
+      proof_source_(std::move(proof_source)),
+      key_exchange_source_(std::move(key_exchange_source)),
+      ssl_ctx_(TlsServerConnection::CreateSslCtx(proof_source_.get())),
+      source_address_token_future_secs_(3600),
+      source_address_token_lifetime_secs_(86400),
+      enable_serving_sct_(false),
+      rejection_observer_(nullptr),
+      pad_rej_(true),
+      pad_shlo_(true),
+      validate_chlo_size_(true),
+      validate_source_address_token_(true) {
+  QUICHE_DCHECK(proof_source_.get());
+  source_address_token_boxer_.SetKeys(
+      {DeriveSourceAddressTokenKey(source_address_token_secret)});
+
+  // Generate a random key and orbit for server nonces.
+  server_nonce_entropy->RandBytes(server_nonce_orbit_,
+                                  sizeof(server_nonce_orbit_));
+  const size_t key_size = server_nonce_boxer_.GetKeySize();
+  std::unique_ptr<uint8_t[]> key_bytes(new uint8_t[key_size]);
+  server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
+
+  server_nonce_boxer_.SetKeys(
+      {std::string(reinterpret_cast<char*>(key_bytes.get()), key_size)});
+}
+
+QuicCryptoServerConfig::~QuicCryptoServerConfig() {}
+
+// static
+QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig(
+    QuicRandom* rand,
+    const QuicClock* clock,
+    const ConfigOptions& options) {
+  CryptoHandshakeMessage msg;
+
+  const std::string curve25519_private_key =
+      Curve25519KeyExchange::NewPrivateKey(rand);
+  std::unique_ptr<Curve25519KeyExchange> curve25519 =
+      Curve25519KeyExchange::New(curve25519_private_key);
+  absl::string_view curve25519_public_value = curve25519->public_value();
+
+  std::string encoded_public_values;
+  // First three bytes encode the length of the public value.
+  QUICHE_DCHECK_LT(curve25519_public_value.size(), (1U << 24));
+  encoded_public_values.push_back(
+      static_cast<char>(curve25519_public_value.size()));
+  encoded_public_values.push_back(
+      static_cast<char>(curve25519_public_value.size() >> 8));
+  encoded_public_values.push_back(
+      static_cast<char>(curve25519_public_value.size() >> 16));
+  encoded_public_values.append(curve25519_public_value.data(),
+                               curve25519_public_value.size());
+
+  std::string p256_private_key;
+  if (options.p256) {
+    p256_private_key = P256KeyExchange::NewPrivateKey();
+    std::unique_ptr<P256KeyExchange> p256(
+        P256KeyExchange::New(p256_private_key));
+    absl::string_view p256_public_value = p256->public_value();
+
+    QUICHE_DCHECK_LT(p256_public_value.size(), (1U << 24));
+    encoded_public_values.push_back(
+        static_cast<char>(p256_public_value.size()));
+    encoded_public_values.push_back(
+        static_cast<char>(p256_public_value.size() >> 8));
+    encoded_public_values.push_back(
+        static_cast<char>(p256_public_value.size() >> 16));
+    encoded_public_values.append(p256_public_value.data(),
+                                 p256_public_value.size());
+  }
+
+  msg.set_tag(kSCFG);
+  if (options.p256) {
+    msg.SetVector(kKEXS, QuicTagVector{kC255, kP256});
+  } else {
+    msg.SetVector(kKEXS, QuicTagVector{kC255});
+  }
+  msg.SetVector(kAEAD, QuicTagVector{kAESG, kCC20});
+  msg.SetStringPiece(kPUBS, encoded_public_values);
+
+  if (options.expiry_time.IsZero()) {
+    const QuicWallTime now = clock->WallNow();
+    const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds(
+        60 * 60 * 24 * 180 /* 180 days, ~six months */));
+    const uint64_t expiry_seconds = expiry.ToUNIXSeconds();
+    msg.SetValue(kEXPY, expiry_seconds);
+  } else {
+    msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds());
+  }
+
+  char orbit_bytes[kOrbitSize];
+  if (options.orbit.size() == sizeof(orbit_bytes)) {
+    memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes));
+  } else {
+    QUICHE_DCHECK(options.orbit.empty());
+    rand->RandBytes(orbit_bytes, sizeof(orbit_bytes));
+  }
+  msg.SetStringPiece(kORBT,
+                     absl::string_view(orbit_bytes, sizeof(orbit_bytes)));
+
+  if (options.channel_id_enabled) {
+    msg.SetVector(kPDMD, QuicTagVector{kCHID});
+  }
+
+  if (options.id.empty()) {
+    // We need to ensure that the SCID changes whenever the server config does
+    // thus we make it a hash of the rest of the server config.
+    std::unique_ptr<QuicData> serialized =
+        CryptoFramer::ConstructHandshakeMessage(msg);
+
+    uint8_t scid_bytes[SHA256_DIGEST_LENGTH];
+    SHA256(reinterpret_cast<const uint8_t*>(serialized->data()),
+           serialized->length(), scid_bytes);
+    // The SCID is a truncated SHA-256 digest.
+    static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high.");
+    msg.SetStringPiece(
+        kSCID,
+        absl::string_view(reinterpret_cast<const char*>(scid_bytes), 16));
+  } else {
+    msg.SetStringPiece(kSCID, options.id);
+  }
+  // Don't put new tags below this point. The SCID generation should hash over
+  // everything but itself and so extra tags should be added prior to the
+  // preceding if block.
+
+  std::unique_ptr<QuicData> serialized =
+      CryptoFramer::ConstructHandshakeMessage(msg);
+
+  QuicServerConfigProtobuf config;
+  config.set_config(std::string(serialized->AsStringPiece()));
+  QuicServerConfigProtobuf::PrivateKey* curve25519_key = config.add_key();
+  curve25519_key->set_tag(kC255);
+  curve25519_key->set_private_key(curve25519_private_key);
+
+  if (options.p256) {
+    QuicServerConfigProtobuf::PrivateKey* p256_key = config.add_key();
+    p256_key->set_tag(kP256);
+    p256_key->set_private_key(p256_private_key);
+  }
+
+  return config;
+}
+
+std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig(
+    const QuicServerConfigProtobuf& protobuf,
+    const QuicWallTime now) {
+  std::unique_ptr<CryptoHandshakeMessage> msg =
+      CryptoFramer::ParseMessage(protobuf.config());
+
+  if (!msg) {
+    QUIC_LOG(WARNING) << "Failed to parse server config message";
+    return nullptr;
+  }
+
+  quiche::QuicheReferenceCountedPointer<Config> config =
+      ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
+  if (!config) {
+    QUIC_LOG(WARNING) << "Failed to parse server config message";
+    return nullptr;
+  }
+
+  {
+    QuicWriterMutexLock locked(&configs_lock_);
+    if (configs_.find(config->id) != configs_.end()) {
+      QUIC_LOG(WARNING) << "Failed to add config because another with the same "
+                           "server config id already exists: "
+                        << absl::BytesToHexString(config->id);
+      return nullptr;
+    }
+
+    configs_[config->id] = config;
+    SelectNewPrimaryConfig(now);
+    QUICHE_DCHECK(primary_config_.get());
+    QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
+                     primary_config_.get());
+  }
+
+  return msg;
+}
+
+std::unique_ptr<CryptoHandshakeMessage>
+QuicCryptoServerConfig::AddDefaultConfig(QuicRandom* rand,
+                                         const QuicClock* clock,
+                                         const ConfigOptions& options) {
+  return AddConfig(GenerateConfig(rand, clock, options), clock->WallNow());
+}
+
+bool QuicCryptoServerConfig::SetConfigs(
+    const std::vector<QuicServerConfigProtobuf>& protobufs,
+    const QuicServerConfigProtobuf* fallback_protobuf,
+    const QuicWallTime now) {
+  std::vector<quiche::QuicheReferenceCountedPointer<Config>> parsed_configs;
+  for (auto& protobuf : protobufs) {
+    quiche::QuicheReferenceCountedPointer<Config> config =
+        ParseConfigProtobuf(protobuf, /* is_fallback = */ false);
+    if (!config) {
+      QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
+      return false;
+    }
+
+    parsed_configs.push_back(config);
+  }
+
+  quiche::QuicheReferenceCountedPointer<Config> fallback_config;
+  if (fallback_protobuf != nullptr) {
+    fallback_config =
+        ParseConfigProtobuf(*fallback_protobuf, /* is_fallback = */ true);
+    if (!fallback_config) {
+      QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors";
+      return false;
+    }
+    QUIC_LOG(INFO) << "Fallback config has scid "
+                   << absl::BytesToHexString(fallback_config->id);
+    parsed_configs.push_back(fallback_config);
+  } else {
+    QUIC_LOG(INFO) << "No fallback config provided";
+  }
+
+  if (parsed_configs.empty()) {
+    QUIC_LOG(WARNING)
+        << "Rejecting QUIC configs because new config list is empty.";
+    return false;
+  }
+
+  QUIC_LOG(INFO) << "Updating configs:";
+
+  QuicWriterMutexLock locked(&configs_lock_);
+  ConfigMap new_configs;
+
+  for (const quiche::QuicheReferenceCountedPointer<Config>& config :
+       parsed_configs) {
+    auto it = configs_.find(config->id);
+    if (it != configs_.end()) {
+      QUIC_LOG(INFO) << "Keeping scid: " << absl::BytesToHexString(config->id)
+                     << " orbit: "
+                     << absl::BytesToHexString(absl::string_view(
+                            reinterpret_cast<const char*>(config->orbit),
+                            kOrbitSize))
+                     << " new primary_time "
+                     << config->primary_time.ToUNIXSeconds()
+                     << " old primary_time "
+                     << it->second->primary_time.ToUNIXSeconds()
+                     << " new priority " << config->priority << " old priority "
+                     << it->second->priority;
+      // Update primary_time and priority.
+      it->second->primary_time = config->primary_time;
+      it->second->priority = config->priority;
+      new_configs.insert(*it);
+    } else {
+      QUIC_LOG(INFO) << "Adding scid: " << absl::BytesToHexString(config->id)
+                     << " orbit: "
+                     << absl::BytesToHexString(absl::string_view(
+                            reinterpret_cast<const char*>(config->orbit),
+                            kOrbitSize))
+                     << " primary_time " << config->primary_time.ToUNIXSeconds()
+                     << " priority " << config->priority;
+      new_configs.emplace(config->id, config);
+    }
+  }
+
+  configs_ = std::move(new_configs);
+  fallback_config_ = fallback_config;
+  SelectNewPrimaryConfig(now);
+  QUICHE_DCHECK(primary_config_.get());
+  QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
+                   primary_config_.get());
+
+  return true;
+}
+
+void QuicCryptoServerConfig::SetSourceAddressTokenKeys(
+    const std::vector<std::string>& keys) {
+  // TODO(b/208866709)
+  source_address_token_boxer_.SetKeys(keys);
+}
+
+std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const {
+  QuicReaderMutexLock locked(&configs_lock_);
+  std::vector<std::string> scids;
+  for (auto it = configs_.begin(); it != configs_.end(); ++it) {
+    scids.push_back(it->first);
+  }
+  return scids;
+}
+
+void QuicCryptoServerConfig::ValidateClientHello(
+    const CryptoHandshakeMessage& client_hello,
+    const QuicSocketAddress& client_address,
+    const QuicSocketAddress& server_address, QuicTransportVersion version,
+    const QuicClock* clock,
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+    std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
+  const QuicWallTime now(clock->WallNow());
+
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result(new ValidateClientHelloResultCallback::Result(
+          client_hello, client_address.host(), now));
+
+  absl::string_view requested_scid;
+  // We ignore here the return value from GetStringPiece. If there is no SCID
+  // tag, EvaluateClientHello will discover that because GetCurrentConfigs will
+  // not have found the requested config (i.e. because none of the configs will
+  // have an empty string as its id).
+  client_hello.GetStringPiece(kSCID, &requested_scid);
+  Configs configs;
+  if (!GetCurrentConfigs(now, requested_scid,
+                         /* old_primary_config = */ nullptr, &configs)) {
+    result->error_code = QUIC_CRYPTO_INTERNAL_ERROR;
+    result->error_details = "No configurations loaded";
+  }
+  signed_config->config = configs.primary;
+
+  if (result->error_code == QUIC_NO_ERROR) {
+    // QUIC requires a new proof for each CHLO so clear any existing proof.
+    signed_config->chain = nullptr;
+    signed_config->proof.signature = "";
+    signed_config->proof.leaf_cert_scts = "";
+    EvaluateClientHello(server_address, client_address, version, configs,
+                        result, std::move(done_cb));
+  } else {
+    done_cb->Run(result, /* details = */ nullptr);
+  }
+}
+
+class QuicCryptoServerConfig::ProcessClientHelloCallback
+    : public ProofSource::Callback {
+ public:
+  ProcessClientHelloCallback(const QuicCryptoServerConfig* config,
+                             std::unique_ptr<ProcessClientHelloContext> context,
+                             const Configs& configs)
+      : config_(config), context_(std::move(context)), configs_(configs) {}
+
+  void Run(
+      bool ok,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const QuicCryptoProof& proof,
+      std::unique_ptr<ProofSource::Details> details) override {
+    if (ok) {
+      context_->signed_config()->chain = chain;
+      context_->signed_config()->proof = proof;
+    }
+    config_->ProcessClientHelloAfterGetProof(!ok, std::move(details),
+                                             std::move(context_), configs_);
+  }
+
+ private:
+  const QuicCryptoServerConfig* config_;
+  std::unique_ptr<ProcessClientHelloContext> context_;
+  const Configs configs_;
+};
+
+class QuicCryptoServerConfig::ProcessClientHelloAfterGetProofCallback
+    : public AsynchronousKeyExchange::Callback {
+ public:
+  ProcessClientHelloAfterGetProofCallback(
+      const QuicCryptoServerConfig* config,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      QuicTag key_exchange_type,
+      std::unique_ptr<CryptoHandshakeMessage> out,
+      absl::string_view public_value,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      const Configs& configs)
+      : config_(config),
+        proof_source_details_(std::move(proof_source_details)),
+        key_exchange_type_(key_exchange_type),
+        out_(std::move(out)),
+        public_value_(public_value),
+        context_(std::move(context)),
+        configs_(configs) {}
+
+  void Run(bool ok) override {
+    config_->ProcessClientHelloAfterCalculateSharedKeys(
+        !ok, std::move(proof_source_details_), key_exchange_type_,
+        std::move(out_), public_value_, std::move(context_), configs_);
+  }
+
+ private:
+  const QuicCryptoServerConfig* config_;
+  std::unique_ptr<ProofSource::Details> proof_source_details_;
+  const QuicTag key_exchange_type_;
+  std::unique_ptr<CryptoHandshakeMessage> out_;
+  const std::string public_value_;
+  std::unique_ptr<ProcessClientHelloContext> context_;
+  const Configs configs_;
+  std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
+};
+
+class QuicCryptoServerConfig::SendRejectWithFallbackConfigCallback
+    : public ProofSource::Callback {
+ public:
+  SendRejectWithFallbackConfigCallback(
+      const QuicCryptoServerConfig* config,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      quiche::QuicheReferenceCountedPointer<Config> fallback_config)
+      : config_(config),
+        context_(std::move(context)),
+        fallback_config_(fallback_config) {}
+
+  // Capture |chain| and |proof| into the signed config, and then invoke
+  // SendRejectWithFallbackConfigAfterGetProof.
+  void Run(
+      bool ok,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const QuicCryptoProof& proof,
+      std::unique_ptr<ProofSource::Details> details) override {
+    if (ok) {
+      context_->signed_config()->chain = chain;
+      context_->signed_config()->proof = proof;
+    }
+    config_->SendRejectWithFallbackConfigAfterGetProof(
+        !ok, std::move(details), std::move(context_), fallback_config_);
+  }
+
+ private:
+  const QuicCryptoServerConfig* config_;
+  std::unique_ptr<ProcessClientHelloContext> context_;
+  quiche::QuicheReferenceCountedPointer<Config> fallback_config_;
+};
+
+void QuicCryptoServerConfig::ProcessClientHello(
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        validate_chlo_result,
+    bool reject_only, QuicConnectionId connection_id,
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address, ParsedQuicVersion version,
+    const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
+    QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        params,
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+    QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
+    std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const {
+  QUICHE_DCHECK(done_cb);
+  auto context = std::make_unique<ProcessClientHelloContext>(
+      validate_chlo_result, reject_only, connection_id, server_address,
+      client_address, version, supported_versions, clock, rand,
+      compressed_certs_cache, params, signed_config, total_framing_overhead,
+      chlo_packet_size, std::move(done_cb));
+
+  // Verify that various parts of the CHLO are valid
+  std::string error_details;
+  QuicErrorCode valid = CryptoUtils::ValidateClientHello(
+      context->client_hello(), context->version(),
+      context->supported_versions(), &error_details);
+  if (valid != QUIC_NO_ERROR) {
+    context->Fail(valid, error_details);
+    return;
+  }
+
+  absl::string_view requested_scid;
+  context->client_hello().GetStringPiece(kSCID, &requested_scid);
+  Configs configs;
+  if (!GetCurrentConfigs(context->clock()->WallNow(), requested_scid,
+                         signed_config->config, &configs)) {
+    context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded");
+    return;
+  }
+
+  if (context->validate_chlo_result()->error_code != QUIC_NO_ERROR) {
+    context->Fail(context->validate_chlo_result()->error_code,
+                  context->validate_chlo_result()->error_details);
+    return;
+  }
+
+  if (!ClientDemandsX509Proof(context->client_hello())) {
+    context->Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD");
+    return;
+  }
+
+  // No need to get a new proof if one was already generated.
+  if (!context->signed_config()->chain) {
+    const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
+        context->client_hello(), Perspective::IS_SERVER);
+    const QuicSocketAddress server_address = context->server_address();
+    const std::string sni = std::string(context->info().sni);
+    const QuicTransportVersion transport_version = context->transport_version();
+
+    auto cb = std::make_unique<ProcessClientHelloCallback>(
+        this, std::move(context), configs);
+
+    QUICHE_DCHECK(proof_source_.get());
+    proof_source_->GetProof(server_address, client_address, sni,
+                            configs.primary->serialized, transport_version,
+                            chlo_hash, std::move(cb));
+    return;
+  }
+
+  ProcessClientHelloAfterGetProof(
+      /* found_error = */ false, /* proof_source_details = */ nullptr,
+      std::move(context), configs);
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
+    bool found_error,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    std::unique_ptr<ProcessClientHelloContext> context,
+    const Configs& configs) const {
+  QUIC_BUG_IF(quic_bug_12963_2,
+              !QuicUtils::IsConnectionIdValidForVersion(
+                  context->connection_id(), context->transport_version()))
+      << "ProcessClientHelloAfterGetProof: attempted to use connection ID "
+      << context->connection_id() << " which is invalid with version "
+      << context->version();
+
+  if (context->info().reject_reasons.empty()) {
+    if (!context->signed_config() || !context->signed_config()->chain) {
+      // No chain.
+      context->validate_chlo_result()->info.reject_reasons.push_back(
+          SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+    } else if (!ValidateExpectedLeafCertificate(
+                   context->client_hello(),
+                   context->signed_config()->chain->certs)) {
+      // Has chain but leaf is invalid.
+      context->validate_chlo_result()->info.reject_reasons.push_back(
+          INVALID_EXPECTED_LEAF_CERTIFICATE);
+    }
+  }
+
+  if (found_error) {
+    context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
+    return;
+  }
+
+  auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
+
+  absl::string_view cert_sct;
+  if (context->client_hello().GetStringPiece(kCertificateSCTTag, &cert_sct) &&
+      cert_sct.empty()) {
+    context->params()->sct_supported_by_client = true;
+  }
+
+  auto out = std::make_unique<CryptoHandshakeMessage>();
+  if (!context->info().reject_reasons.empty() || !configs.requested) {
+    BuildRejectionAndRecordStats(*context, *configs.primary,
+                                 context->info().reject_reasons, out.get());
+    context->Succeed(std::move(out), std::move(out_diversification_nonce),
+                     std::move(proof_source_details));
+    return;
+  }
+
+  if (context->reject_only()) {
+    context->Succeed(std::move(out), std::move(out_diversification_nonce),
+                     std::move(proof_source_details));
+    return;
+  }
+
+  QuicTagVector their_aeads;
+  QuicTagVector their_key_exchanges;
+  if (context->client_hello().GetTaglist(kAEAD, &their_aeads) !=
+          QUIC_NO_ERROR ||
+      context->client_hello().GetTaglist(kKEXS, &their_key_exchanges) !=
+          QUIC_NO_ERROR ||
+      their_aeads.size() != 1 || their_key_exchanges.size() != 1) {
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Missing or invalid AEAD or KEXS");
+    return;
+  }
+
+  size_t key_exchange_index;
+  if (!FindMutualQuicTag(configs.requested->aead, their_aeads,
+                         &context->params()->aead, nullptr) ||
+      !FindMutualQuicTag(configs.requested->kexs, their_key_exchanges,
+                         &context->params()->key_exchange,
+                         &key_exchange_index)) {
+    context->Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS");
+    return;
+  }
+
+  absl::string_view public_value;
+  if (!context->client_hello().GetStringPiece(kPUBS, &public_value)) {
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Missing public value");
+    return;
+  }
+
+  // Allow testing a specific adversarial case in which a client sends a public
+  // value of incorrect size.
+  AdjustTestValue("quic::QuicCryptoServerConfig::public_value_adjust",
+                  &public_value);
+
+  const AsynchronousKeyExchange* key_exchange =
+      configs.requested->key_exchanges[key_exchange_index].get();
+  std::string* initial_premaster_secret =
+      &context->params()->initial_premaster_secret;
+  auto cb = std::make_unique<ProcessClientHelloAfterGetProofCallback>(
+      this, std::move(proof_source_details), key_exchange->type(),
+      std::move(out), public_value, std::move(context), configs);
+  key_exchange->CalculateSharedKeyAsync(public_value, initial_premaster_secret,
+                                        std::move(cb));
+}
+
+void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys(
+    bool found_error,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    QuicTag key_exchange_type,
+    std::unique_ptr<CryptoHandshakeMessage> out,
+    absl::string_view public_value,
+    std::unique_ptr<ProcessClientHelloContext> context,
+    const Configs& configs) const {
+  QUIC_BUG_IF(quic_bug_12963_3,
+              !QuicUtils::IsConnectionIdValidForVersion(
+                  context->connection_id(), context->transport_version()))
+      << "ProcessClientHelloAfterCalculateSharedKeys:"
+         " attempted to use connection ID "
+      << context->connection_id() << " which is invalid with version "
+      << context->version();
+
+  if (found_error) {
+    // If we are already using the fallback config, or there is no fallback
+    // config to use, just bail out of the handshake.
+    if (configs.fallback == nullptr ||
+        context->signed_config()->config == configs.fallback) {
+      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                    "Failed to calculate shared key");
+    } else {
+      SendRejectWithFallbackConfig(std::move(context), configs.fallback);
+    }
+    return;
+  }
+
+  if (!context->info().sni.empty()) {
+    context->params()->sni =
+        QuicHostnameUtils::NormalizeHostname(context->info().sni);
+  }
+
+  std::string hkdf_suffix;
+  const QuicData& client_hello_serialized =
+      context->client_hello().GetSerialized();
+  hkdf_suffix.reserve(context->connection_id().length() +
+                      client_hello_serialized.length() +
+                      configs.requested->serialized.size());
+  hkdf_suffix.append(context->connection_id().data(),
+                     context->connection_id().length());
+  hkdf_suffix.append(client_hello_serialized.data(),
+                     client_hello_serialized.length());
+  hkdf_suffix.append(configs.requested->serialized);
+  QUICHE_DCHECK(proof_source_.get());
+  if (context->signed_config()->chain->certs.empty()) {
+    context->Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs");
+    return;
+  }
+  hkdf_suffix.append(context->signed_config()->chain->certs.at(0));
+
+  absl::string_view cetv_ciphertext;
+  if (configs.requested->channel_id_enabled &&
+      context->client_hello().GetStringPiece(kCETV, &cetv_ciphertext)) {
+    CryptoHandshakeMessage client_hello_copy(context->client_hello());
+    client_hello_copy.Erase(kCETV);
+    client_hello_copy.Erase(kPAD);
+
+    const QuicData& client_hello_copy_serialized =
+        client_hello_copy.GetSerialized();
+    std::string hkdf_input;
+    hkdf_input.append(QuicCryptoConfig::kCETVLabel,
+                      strlen(QuicCryptoConfig::kCETVLabel) + 1);
+    hkdf_input.append(context->connection_id().data(),
+                      context->connection_id().length());
+    hkdf_input.append(client_hello_copy_serialized.data(),
+                      client_hello_copy_serialized.length());
+    hkdf_input.append(configs.requested->serialized);
+
+    CrypterPair crypters;
+    if (!CryptoUtils::DeriveKeys(
+            context->version(), context->params()->initial_premaster_secret,
+            context->params()->aead, context->info().client_nonce,
+            context->info().server_nonce, pre_shared_key_, hkdf_input,
+            Perspective::IS_SERVER, CryptoUtils::Diversification::Never(),
+            &crypters, nullptr /* subkey secret */)) {
+      context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
+                    "Symmetric key setup failed");
+      return;
+    }
+
+    char plaintext[kMaxOutgoingPacketSize];
+    size_t plaintext_length = 0;
+    const bool success = crypters.decrypter->DecryptPacket(
+        0 /* packet number */, absl::string_view() /* associated data */,
+        cetv_ciphertext, plaintext, &plaintext_length, kMaxOutgoingPacketSize);
+    if (!success) {
+      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                    "CETV decryption failure");
+      return;
+    }
+    std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage(
+        absl::string_view(plaintext, plaintext_length)));
+    if (!cetv) {
+      context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error");
+      return;
+    }
+
+    absl::string_view key, signature;
+    if (cetv->GetStringPiece(kCIDK, &key) &&
+        cetv->GetStringPiece(kCIDS, &signature)) {
+      if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) {
+        context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                      "ChannelID signature failure");
+        return;
+      }
+
+      context->params()->channel_id = std::string(key);
+    }
+  }
+
+  std::string hkdf_input;
+  size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
+  hkdf_input.reserve(label_len + hkdf_suffix.size());
+  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
+  hkdf_input.append(hkdf_suffix);
+
+  auto out_diversification_nonce = std::make_unique<DiversificationNonce>();
+  context->rand()->RandBytes(out_diversification_nonce->data(),
+                             out_diversification_nonce->size());
+  CryptoUtils::Diversification diversification =
+      CryptoUtils::Diversification::Now(out_diversification_nonce.get());
+  if (!CryptoUtils::DeriveKeys(
+          context->version(), context->params()->initial_premaster_secret,
+          context->params()->aead, context->info().client_nonce,
+          context->info().server_nonce, pre_shared_key_, hkdf_input,
+          Perspective::IS_SERVER, diversification,
+          &context->params()->initial_crypters,
+          &context->params()->initial_subkey_secret)) {
+    context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
+                  "Symmetric key setup failed");
+    return;
+  }
+
+  std::string forward_secure_public_value;
+  std::unique_ptr<SynchronousKeyExchange> forward_secure_key_exchange =
+      CreateLocalSynchronousKeyExchange(key_exchange_type, context->rand());
+  if (!forward_secure_key_exchange) {
+    QUIC_DLOG(WARNING) << "Failed to create keypair";
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Failed to create keypair");
+    return;
+  }
+
+  forward_secure_public_value =
+      std::string(forward_secure_key_exchange->public_value());
+  if (!forward_secure_key_exchange->CalculateSharedKeySync(
+          public_value, &context->params()->forward_secure_premaster_secret)) {
+    context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                  "Invalid public value");
+    return;
+  }
+
+  std::string forward_secure_hkdf_input;
+  label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
+  forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size());
+  forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel,
+                                   label_len);
+  forward_secure_hkdf_input.append(hkdf_suffix);
+
+  std::string shlo_nonce;
+  shlo_nonce = NewServerNonce(context->rand(), context->info().now);
+  out->SetStringPiece(kServerNonceTag, shlo_nonce);
+
+  if (!CryptoUtils::DeriveKeys(
+          context->version(),
+          context->params()->forward_secure_premaster_secret,
+          context->params()->aead, context->info().client_nonce,
+          shlo_nonce.empty() ? context->info().server_nonce : shlo_nonce,
+          pre_shared_key_, forward_secure_hkdf_input, Perspective::IS_SERVER,
+          CryptoUtils::Diversification::Never(),
+          &context->params()->forward_secure_crypters,
+          &context->params()->subkey_secret)) {
+    context->Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED,
+                  "Symmetric key setup failed");
+    return;
+  }
+
+  out->set_tag(kSHLO);
+  out->SetVersionVector(kVER, context->supported_versions());
+  out->SetStringPiece(
+      kSourceAddressTokenTag,
+      NewSourceAddressToken(*configs.requested->source_address_token_boxer,
+                            context->info().source_address_tokens,
+                            context->client_address().host(), context->rand(),
+                            context->info().now, nullptr));
+  QuicSocketAddressCoder address_coder(context->client_address());
+  out->SetStringPiece(kCADR, address_coder.Encode());
+  out->SetStringPiece(kPUBS, forward_secure_public_value);
+
+  context->Succeed(std::move(out), std::move(out_diversification_nonce),
+                   std::move(proof_source_details));
+}
+
+void QuicCryptoServerConfig::SendRejectWithFallbackConfig(
+    std::unique_ptr<ProcessClientHelloContext> context,
+    quiche::QuicheReferenceCountedPointer<Config> fallback_config) const {
+  // We failed to calculate a shared initial key, likely because we tried to use
+  // a remote key-exchange service which could not be reached.  We want to send
+  // a REJ which tells the client to use a different ServerConfig which
+  // corresponds to a local keypair.  To generate the REJ we need to request a
+  // new proof.
+  const std::string chlo_hash = CryptoUtils::HashHandshakeMessage(
+      context->client_hello(), Perspective::IS_SERVER);
+  const QuicSocketAddress server_address = context->server_address();
+  const std::string sni(context->info().sni);
+  const QuicTransportVersion transport_version = context->transport_version();
+
+  const QuicSocketAddress& client_address = context->client_address();
+  auto cb = std::make_unique<SendRejectWithFallbackConfigCallback>(
+      this, std::move(context), fallback_config);
+  proof_source_->GetProof(server_address, client_address, sni,
+                          fallback_config->serialized, transport_version,
+                          chlo_hash, std::move(cb));
+}
+
+void QuicCryptoServerConfig::SendRejectWithFallbackConfigAfterGetProof(
+    bool found_error,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    std::unique_ptr<ProcessClientHelloContext> context,
+    quiche::QuicheReferenceCountedPointer<Config> fallback_config) const {
+  if (found_error) {
+    context->Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof");
+    return;
+  }
+
+  auto out = std::make_unique<CryptoHandshakeMessage>();
+  BuildRejectionAndRecordStats(*context, *fallback_config,
+                               {SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE},
+                               out.get());
+
+  context->Succeed(std::move(out), std::make_unique<DiversificationNonce>(),
+                   std::move(proof_source_details));
+}
+
+quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+QuicCryptoServerConfig::GetConfigWithScid(
+    absl::string_view requested_scid) const {
+  configs_lock_.AssertReaderHeld();
+
+  if (!requested_scid.empty()) {
+    auto it = configs_.find((std::string(requested_scid)));
+    if (it != configs_.end()) {
+      // We'll use the config that the client requested in order to do
+      // key-agreement.
+      return quiche::QuicheReferenceCountedPointer<Config>(it->second);
+    }
+  }
+
+  return quiche::QuicheReferenceCountedPointer<Config>();
+}
+
+bool QuicCryptoServerConfig::GetCurrentConfigs(
+    const QuicWallTime& now, absl::string_view requested_scid,
+    quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
+    Configs* configs) const {
+  QuicReaderMutexLock locked(&configs_lock_);
+
+  if (!primary_config_) {
+    return false;
+  }
+
+  if (IsNextConfigReady(now)) {
+    configs_lock_.ReaderUnlock();
+    configs_lock_.WriterLock();
+    SelectNewPrimaryConfig(now);
+    QUICHE_DCHECK(primary_config_.get());
+    QUICHE_DCHECK_EQ(configs_.find(primary_config_->id)->second.get(),
+                     primary_config_.get());
+    configs_lock_.WriterUnlock();
+    configs_lock_.ReaderLock();
+  }
+
+  if (old_primary_config != nullptr) {
+    configs->primary = old_primary_config;
+  } else {
+    configs->primary = primary_config_;
+  }
+  configs->requested = GetConfigWithScid(requested_scid);
+  configs->fallback = fallback_config_;
+
+  return true;
+}
+
+// ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
+// Config's based on their primary_time.
+// static
+bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
+    const quiche::QuicheReferenceCountedPointer<Config>& a,
+    const quiche::QuicheReferenceCountedPointer<Config>& b) {
+  if (a->primary_time.IsBefore(b->primary_time) ||
+      b->primary_time.IsBefore(a->primary_time)) {
+    // Primary times differ.
+    return a->primary_time.IsBefore(b->primary_time);
+  } else if (a->priority != b->priority) {
+    // Primary times are equal, sort backwards by priority.
+    return a->priority < b->priority;
+  } else {
+    // Primary times and priorities are equal, sort by config id.
+    return a->id < b->id;
+  }
+}
+
+void QuicCryptoServerConfig::SelectNewPrimaryConfig(
+    const QuicWallTime now) const {
+  std::vector<quiche::QuicheReferenceCountedPointer<Config>> configs;
+  configs.reserve(configs_.size());
+
+  for (auto it = configs_.begin(); it != configs_.end(); ++it) {
+    // TODO(avd) Exclude expired configs?
+    configs.push_back(it->second);
+  }
+
+  if (configs.empty()) {
+    if (primary_config_ != nullptr) {
+      QUIC_BUG(quic_bug_10630_2)
+          << "No valid QUIC server config. Keeping the current config.";
+    } else {
+      QUIC_BUG(quic_bug_10630_3) << "No valid QUIC server config.";
+    }
+    return;
+  }
+
+  std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan);
+
+  quiche::QuicheReferenceCountedPointer<Config> best_candidate = configs[0];
+
+  for (size_t i = 0; i < configs.size(); ++i) {
+    const quiche::QuicheReferenceCountedPointer<Config> config(configs[i]);
+    if (!config->primary_time.IsAfter(now)) {
+      if (config->primary_time.IsAfter(best_candidate->primary_time)) {
+        best_candidate = config;
+      }
+      continue;
+    }
+
+    // This is the first config with a primary_time in the future. Thus the
+    // previous Config should be the primary and this one should determine the
+    // next_config_promotion_time_.
+    quiche::QuicheReferenceCountedPointer<Config> new_primary = best_candidate;
+    if (i == 0) {
+      // We need the primary_time of the next config.
+      if (configs.size() > 1) {
+        next_config_promotion_time_ = configs[1]->primary_time;
+      } else {
+        next_config_promotion_time_ = QuicWallTime::Zero();
+      }
+    } else {
+      next_config_promotion_time_ = config->primary_time;
+    }
+
+    if (primary_config_) {
+      primary_config_->is_primary = false;
+    }
+    primary_config_ = new_primary;
+    new_primary->is_primary = true;
+    QUIC_DLOG(INFO) << "New primary config.  orbit: "
+                    << absl::BytesToHexString(
+                           absl::string_view(reinterpret_cast<const char*>(
+                                                 primary_config_->orbit),
+                                             kOrbitSize));
+    if (primary_config_changed_cb_ != nullptr) {
+      primary_config_changed_cb_->Run(primary_config_->id);
+    }
+
+    return;
+  }
+
+  // All config's primary times are in the past. We should make the most recent
+  // and highest priority candidate primary.
+  quiche::QuicheReferenceCountedPointer<Config> new_primary = best_candidate;
+  if (primary_config_) {
+    primary_config_->is_primary = false;
+  }
+  primary_config_ = new_primary;
+  new_primary->is_primary = true;
+  QUIC_DLOG(INFO) << "New primary config.  orbit: "
+                  << absl::BytesToHexString(absl::string_view(
+                         reinterpret_cast<const char*>(primary_config_->orbit),
+                         kOrbitSize))
+                  << " scid: " << absl::BytesToHexString(primary_config_->id);
+  next_config_promotion_time_ = QuicWallTime::Zero();
+  if (primary_config_changed_cb_ != nullptr) {
+    primary_config_changed_cb_->Run(primary_config_->id);
+  }
+}
+
+void QuicCryptoServerConfig::EvaluateClientHello(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    QuicTransportVersion /*version*/, const Configs& configs,
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        client_hello_state,
+    std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const {
+  ValidateClientHelloHelper helper(client_hello_state, &done_cb);
+
+  const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello;
+  ClientHelloInfo* info = &(client_hello_state->info);
+
+  if (client_hello.GetStringPiece(kSNI, &info->sni) &&
+      !QuicHostnameUtils::IsValidSNI(info->sni)) {
+    helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
+                              "Invalid SNI name", nullptr);
+    return;
+  }
+
+  client_hello.GetStringPiece(kUAID, &info->user_agent_id);
+
+  HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON;
+  if (validate_source_address_token_) {
+    absl::string_view srct;
+    if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
+      Config& config =
+          configs.requested != nullptr ? *configs.requested : *configs.primary;
+      source_address_token_error =
+          ParseSourceAddressToken(*config.source_address_token_boxer, srct,
+                                  info->source_address_tokens);
+
+      if (source_address_token_error == HANDSHAKE_OK) {
+        source_address_token_error = ValidateSourceAddressTokens(
+            info->source_address_tokens, info->client_ip, info->now,
+            &client_hello_state->cached_network_params);
+      }
+      info->valid_source_address_token =
+          (source_address_token_error == HANDSHAKE_OK);
+    } else {
+      source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
+    }
+  } else {
+    source_address_token_error = HANDSHAKE_OK;
+    info->valid_source_address_token = true;
+  }
+
+  if (!configs.requested) {
+    absl::string_view requested_scid;
+    if (client_hello.GetStringPiece(kSCID, &requested_scid)) {
+      info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
+    } else {
+      info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+    }
+    // No server config with the requested ID.
+    helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
+    return;
+  }
+
+  if (!client_hello.GetStringPiece(kNONC, &info->client_nonce)) {
+    info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
+    // Report no client nonce as INCHOATE_HELLO_FAILURE.
+    helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr);
+    return;
+  }
+
+  if (source_address_token_error != HANDSHAKE_OK) {
+    info->reject_reasons.push_back(source_address_token_error);
+    // No valid source address token.
+  }
+
+  if (info->client_nonce.size() != kNonceSize) {
+    info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
+    // Invalid client nonce.
+    QUIC_LOG_FIRST_N(ERROR, 2)
+        << "Invalid client nonce: " << client_hello.DebugString();
+    QUIC_DLOG(INFO) << "Invalid client nonce.";
+  }
+
+  // Server nonce is optional, and used for key derivation if present.
+  client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
+
+  // If the server nonce is empty and we're requiring handshake confirmation
+  // for DoS reasons then we must reject the CHLO.
+  if (GetQuicReloadableFlag(quic_require_handshake_confirmation) &&
+      info->server_nonce.empty()) {
+    info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
+  }
+  helper.ValidationComplete(QUIC_NO_ERROR, "",
+                            std::unique_ptr<ProofSource::Details>());
+}
+
+void QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
+    QuicTransportVersion version,
+    absl::string_view chlo_hash,
+    const SourceAddressTokens& previous_source_address_tokens,
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const QuicClock* clock,
+    QuicRandom* rand,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const QuicCryptoNegotiatedParameters& params,
+    const CachedNetworkParameters* cached_network_params,
+    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
+  std::string serialized;
+  std::string source_address_token;
+  {
+    QuicReaderMutexLock locked(&configs_lock_);
+    serialized = primary_config_->serialized;
+    source_address_token = NewSourceAddressToken(
+        *primary_config_->source_address_token_boxer,
+        previous_source_address_tokens, client_address.host(), rand,
+        clock->WallNow(), cached_network_params);
+  }
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kSCUP);
+  message.SetStringPiece(kSCFG, serialized);
+  message.SetStringPiece(kSourceAddressTokenTag, source_address_token);
+
+  auto proof_source_cb =
+      std::make_unique<BuildServerConfigUpdateMessageProofSourceCallback>(
+          this, compressed_certs_cache, params, std::move(message),
+          std::move(cb));
+
+  proof_source_->GetProof(server_address, client_address, params.sni,
+                          serialized, version, chlo_hash,
+                          std::move(proof_source_cb));
+}
+
+QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
+    ~BuildServerConfigUpdateMessageProofSourceCallback() {}
+
+QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
+    BuildServerConfigUpdateMessageProofSourceCallback(
+        const QuicCryptoServerConfig* config,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        const QuicCryptoNegotiatedParameters& params,
+        CryptoHandshakeMessage message,
+        std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb)
+    : config_(config),
+      compressed_certs_cache_(compressed_certs_cache),
+      client_cached_cert_hashes_(params.client_cached_cert_hashes),
+      sct_supported_by_client_(params.sct_supported_by_client),
+      sni_(params.sni),
+      message_(std::move(message)),
+      cb_(std::move(cb)) {}
+
+void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
+    Run(bool ok,
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const QuicCryptoProof& proof,
+        std::unique_ptr<ProofSource::Details> details) {
+  config_->FinishBuildServerConfigUpdateMessage(
+      compressed_certs_cache_, client_cached_cert_hashes_,
+      sct_supported_by_client_, sni_, ok, chain, proof.signature,
+      proof.leaf_cert_scts, std::move(details), std::move(message_),
+      std::move(cb_));
+}
+
+void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage(
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const std::string& client_cached_cert_hashes, bool sct_supported_by_client,
+    const std::string& sni, bool ok,
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& signature, const std::string& leaf_cert_sct,
+    std::unique_ptr<ProofSource::Details> /*details*/,
+    CryptoHandshakeMessage message,
+    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const {
+  if (!ok) {
+    cb->Run(false, message);
+    return;
+  }
+
+  const std::string compressed =
+      CompressChain(compressed_certs_cache, chain, client_cached_cert_hashes);
+
+  message.SetStringPiece(kCertificateTag, compressed);
+  message.SetStringPiece(kPROF, signature);
+  if (sct_supported_by_client && enable_serving_sct_) {
+    if (leaf_cert_sct.empty()) {
+      QUIC_LOG_EVERY_N_SEC(WARNING, 60)
+          << "SCT is expected but it is empty. SNI: " << sni;
+    } else {
+      message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct);
+    }
+  }
+
+  cb->Run(true, message);
+}
+
+void QuicCryptoServerConfig::BuildRejectionAndRecordStats(
+    const ProcessClientHelloContext& context,
+    const Config& config,
+    const std::vector<uint32_t>& reject_reasons,
+    CryptoHandshakeMessage* out) const {
+  BuildRejection(context, config, reject_reasons, out);
+  if (rejection_observer_ != nullptr) {
+    rejection_observer_->OnRejectionBuilt(reject_reasons, out);
+  }
+}
+
+void QuicCryptoServerConfig::BuildRejection(
+    const ProcessClientHelloContext& context,
+    const Config& config,
+    const std::vector<uint32_t>& reject_reasons,
+    CryptoHandshakeMessage* out) const {
+  const QuicWallTime now = context.clock()->WallNow();
+
+  out->set_tag(kREJ);
+  out->SetStringPiece(kSCFG, config.serialized);
+  out->SetStringPiece(
+      kSourceAddressTokenTag,
+      NewSourceAddressToken(
+          *config.source_address_token_boxer,
+          context.info().source_address_tokens, context.info().client_ip,
+          context.rand(), context.info().now,
+          &context.validate_chlo_result()->cached_network_params));
+  out->SetValue(kSTTL, config.expiry_time.AbsoluteDifference(now).ToSeconds());
+  if (replay_protection_) {
+    out->SetStringPiece(kServerNonceTag,
+                        NewServerNonce(context.rand(), context.info().now));
+  }
+
+  // Send client the reject reason for debugging purposes.
+  QUICHE_DCHECK_LT(0u, reject_reasons.size());
+  out->SetVector(kRREJ, reject_reasons);
+
+  // The client may have requested a certificate chain.
+  if (!ClientDemandsX509Proof(context.client_hello())) {
+    QUIC_BUG(quic_bug_10630_4)
+        << "x509 certificates not supported in proof demand";
+    return;
+  }
+
+  absl::string_view client_cached_cert_hashes;
+  if (context.client_hello().GetStringPiece(kCCRT,
+                                            &client_cached_cert_hashes)) {
+    context.params()->client_cached_cert_hashes =
+        std::string(client_cached_cert_hashes);
+  } else {
+    context.params()->client_cached_cert_hashes.clear();
+  }
+
+  const std::string compressed = CompressChain(
+      context.compressed_certs_cache(), context.signed_config()->chain,
+      context.params()->client_cached_cert_hashes);
+
+  QUICHE_DCHECK_GT(context.chlo_packet_size(), context.client_hello().size());
+  // kREJOverheadBytes is a very rough estimate of how much of a REJ
+  // message is taken up by things other than the certificates.
+  // STK: 56 bytes
+  // SNO: 56 bytes
+  // SCFG
+  //   SCID: 16 bytes
+  //   PUBS: 38 bytes
+  const size_t kREJOverheadBytes = 166;
+  // max_unverified_size is the number of bytes that the certificate chain,
+  // signature, and (optionally) signed certificate timestamp can consume before
+  // we will demand a valid source-address token.
+  const size_t max_unverified_size =
+      chlo_multiplier_ *
+          (context.chlo_packet_size() - context.total_framing_overhead()) -
+      kREJOverheadBytes;
+  static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
+                "overhead calculation may underflow");
+  bool should_return_sct =
+      context.params()->sct_supported_by_client && enable_serving_sct_;
+  const std::string& cert_sct = context.signed_config()->proof.leaf_cert_scts;
+  const size_t sct_size = should_return_sct ? cert_sct.size() : 0;
+  const size_t total_size = context.signed_config()->proof.signature.size() +
+                            compressed.size() + sct_size;
+  if (context.info().valid_source_address_token ||
+      total_size < max_unverified_size) {
+    out->SetStringPiece(kCertificateTag, compressed);
+    out->SetStringPiece(kPROF, context.signed_config()->proof.signature);
+    if (should_return_sct) {
+      if (cert_sct.empty()) {
+        // Log SNI and subject name for the leaf cert if its SCT is empty.
+        // This is for debugging b/28342827.
+        const std::vector<std::string>& certs =
+            context.signed_config()->chain->certs;
+        std::string ca_subject;
+        if (!certs.empty()) {
+            std::unique_ptr<CertificateView> view =
+                CertificateView::ParseSingleCertificate(certs[0]);
+            if (view != nullptr) {
+              absl::optional<std::string> maybe_ca_subject =
+                  view->GetHumanReadableSubject();
+              if (maybe_ca_subject.has_value()) {
+                ca_subject = *maybe_ca_subject;
+              }
+            }
+        }
+        QUIC_LOG_EVERY_N_SEC(WARNING, 60)
+            << "SCT is expected but it is empty. sni: '"
+            << context.params()->sni << "' cert subject: '" << ca_subject
+            << "'";
+      } else {
+        out->SetStringPiece(kCertificateSCTTag, cert_sct);
+      }
+    }
+  } else {
+    QUIC_LOG_EVERY_N_SEC(WARNING, 60)
+        << "Sending inchoate REJ for hostname: " << context.info().sni
+        << " signature: " << context.signed_config()->proof.signature.size()
+        << " cert: " << compressed.size() << " sct:" << sct_size
+        << " total: " << total_size << " max: " << max_unverified_size;
+  }
+}
+
+std::string QuicCryptoServerConfig::CompressChain(
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes) {
+  // Check whether the compressed certs is available in the cache.
+  QUICHE_DCHECK(compressed_certs_cache);
+  const std::string* cached_value = compressed_certs_cache->GetCompressedCert(
+      chain, client_cached_cert_hashes);
+  if (cached_value) {
+    return *cached_value;
+  }
+  std::string compressed =
+      CertCompressor::CompressChain(chain->certs, client_cached_cert_hashes);
+  // Insert the newly compressed cert to cache.
+  compressed_certs_cache->Insert(chain, client_cached_cert_hashes, compressed);
+  return compressed;
+}
+
+quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+QuicCryptoServerConfig::ParseConfigProtobuf(
+    const QuicServerConfigProtobuf& protobuf, bool is_fallback) const {
+  std::unique_ptr<CryptoHandshakeMessage> msg =
+      CryptoFramer::ParseMessage(protobuf.config());
+
+  if (!msg) {
+    QUIC_LOG(WARNING) << "Failed to parse server config message";
+    return nullptr;
+  }
+
+  if (msg->tag() != kSCFG) {
+    QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag()
+                      << ", but expected " << kSCFG;
+    return nullptr;
+  }
+
+  quiche::QuicheReferenceCountedPointer<Config> config(new Config);
+  config->serialized = protobuf.config();
+  config->source_address_token_boxer = &source_address_token_boxer_;
+
+  if (protobuf.has_primary_time()) {
+    config->primary_time =
+        QuicWallTime::FromUNIXSeconds(protobuf.primary_time());
+  }
+
+  config->priority = protobuf.priority();
+
+  absl::string_view scid;
+  if (!msg->GetStringPiece(kSCID, &scid)) {
+    QUIC_LOG(WARNING) << "Server config message is missing SCID";
+    return nullptr;
+  }
+  QUICHE_DCHECK(!scid.empty());
+  config->id = std::string(scid);
+
+  if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
+    QUIC_LOG(WARNING) << "Server config message is missing AEAD";
+    return nullptr;
+  }
+
+  QuicTagVector kexs_tags;
+  if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) {
+    QUIC_LOG(WARNING) << "Server config message is missing KEXS";
+    return nullptr;
+  }
+
+  absl::string_view orbit;
+  if (!msg->GetStringPiece(kORBT, &orbit)) {
+    QUIC_LOG(WARNING) << "Server config message is missing ORBT";
+    return nullptr;
+  }
+
+  if (orbit.size() != kOrbitSize) {
+    QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length."
+                         " Got "
+                      << orbit.size() << " want " << kOrbitSize;
+    return nullptr;
+  }
+  static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size");
+  memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
+
+  QuicTagVector proof_demand_tags;
+  if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) {
+    for (QuicTag tag : proof_demand_tags) {
+      if (tag == kCHID) {
+        config->channel_id_enabled = true;
+        break;
+      }
+    }
+  }
+
+  for (size_t i = 0; i < kexs_tags.size(); i++) {
+    const QuicTag tag = kexs_tags[i];
+    std::string private_key;
+
+    config->kexs.push_back(tag);
+
+    for (int j = 0; j < protobuf.key_size(); j++) {
+      const QuicServerConfigProtobuf::PrivateKey& key = protobuf.key(i);
+      if (key.tag() == tag) {
+        private_key = key.private_key();
+        break;
+      }
+    }
+
+    std::unique_ptr<AsynchronousKeyExchange> ka =
+        key_exchange_source_->Create(config->id, is_fallback, tag, private_key);
+    if (!ka) {
+      return nullptr;
+    }
+    for (const auto& key_exchange : config->key_exchanges) {
+      if (key_exchange->type() == tag) {
+        QUIC_LOG(WARNING) << "Duplicate key exchange in config: " << tag;
+        return nullptr;
+      }
+    }
+
+    config->key_exchanges.push_back(std::move(ka));
+  }
+
+  uint64_t expiry_seconds;
+  if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
+    QUIC_LOG(WARNING) << "Server config message is missing EXPY";
+    return nullptr;
+  }
+  config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds);
+
+  return config;
+}
+
+void QuicCryptoServerConfig::set_replay_protection(bool on) {
+  replay_protection_ = on;
+}
+
+void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) {
+  chlo_multiplier_ = multiplier;
+}
+
+void QuicCryptoServerConfig::set_source_address_token_future_secs(
+    uint32_t future_secs) {
+  source_address_token_future_secs_ = future_secs;
+}
+
+void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
+    uint32_t lifetime_secs) {
+  source_address_token_lifetime_secs_ = lifetime_secs;
+}
+
+void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
+  enable_serving_sct_ = enable_serving_sct;
+}
+
+void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
+    std::unique_ptr<PrimaryConfigChangedCallback> cb) {
+  QuicWriterMutexLock locked(&configs_lock_);
+  primary_config_changed_cb_ = std::move(cb);
+}
+
+std::string QuicCryptoServerConfig::NewSourceAddressToken(
+    const CryptoSecretBoxer& crypto_secret_boxer,
+    const SourceAddressTokens& previous_tokens,
+    const QuicIpAddress& ip,
+    QuicRandom* rand,
+    QuicWallTime now,
+    const CachedNetworkParameters* cached_network_params) const {
+  SourceAddressTokens source_address_tokens;
+  SourceAddressToken* source_address_token = source_address_tokens.add_tokens();
+  source_address_token->set_ip(ip.DualStacked().ToPackedString());
+  source_address_token->set_timestamp(now.ToUNIXSeconds());
+  if (cached_network_params != nullptr) {
+    *(source_address_token->mutable_cached_network_parameters()) =
+        *cached_network_params;
+  }
+
+  // Append previous tokens.
+  for (const SourceAddressToken& token : previous_tokens.tokens()) {
+    if (source_address_tokens.tokens_size() > kMaxTokenAddresses) {
+      break;
+    }
+
+    if (token.ip() == source_address_token->ip()) {
+      // It's for the same IP address.
+      continue;
+    }
+
+    if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) {
+      continue;
+    }
+
+    *(source_address_tokens.add_tokens()) = token;
+  }
+
+  return crypto_secret_boxer.Box(rand,
+                                 source_address_tokens.SerializeAsString());
+}
+
+int QuicCryptoServerConfig::NumberOfConfigs() const {
+  QuicReaderMutexLock locked(&configs_lock_);
+  return configs_.size();
+}
+
+ProofSource* QuicCryptoServerConfig::proof_source() const {
+  return proof_source_.get();
+}
+
+SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const {
+  return ssl_ctx_.get();
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
+    const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
+    SourceAddressTokens& tokens) const {
+  std::string storage;
+  absl::string_view plaintext;
+  if (!crypto_secret_boxer.Unbox(token, &storage, &plaintext)) {
+    return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
+  }
+
+  if (!tokens.ParseFromArray(plaintext.data(), plaintext.size())) {
+    // Some clients might still be using the old source token format so
+    // attempt to parse that format.
+    // TODO(rch): remove this code once the new format is ubiquitous.
+    SourceAddressToken token;
+    if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
+      return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
+    }
+    *tokens.add_tokens() = token;
+  }
+
+  return HANDSHAKE_OK;
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
+    const SourceAddressTokens& source_address_tokens,
+    const QuicIpAddress& ip,
+    QuicWallTime now,
+    CachedNetworkParameters* cached_network_params) const {
+  HandshakeFailureReason reason =
+      SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
+  for (const SourceAddressToken& token : source_address_tokens.tokens()) {
+    reason = ValidateSingleSourceAddressToken(token, ip, now);
+    if (reason == HANDSHAKE_OK) {
+      if (cached_network_params != nullptr &&
+          token.has_cached_network_parameters()) {
+        *cached_network_params = token.cached_network_parameters();
+      }
+      break;
+    }
+  }
+  return reason;
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
+    const SourceAddressToken& source_address_token,
+    const QuicIpAddress& ip,
+    QuicWallTime now) const {
+  if (source_address_token.ip() != ip.DualStacked().ToPackedString()) {
+    // It's for a different IP address.
+    return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
+  }
+
+  return ValidateSourceAddressTokenTimestamp(source_address_token, now);
+}
+
+HandshakeFailureReason
+QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
+    const SourceAddressToken& source_address_token,
+    QuicWallTime now) const {
+  const QuicWallTime timestamp(
+      QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
+  const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
+
+  if (now.IsBefore(timestamp) &&
+      delta.ToSeconds() > source_address_token_future_secs_) {
+    return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
+  }
+
+  if (now.IsAfter(timestamp) &&
+      delta.ToSeconds() > source_address_token_lifetime_secs_) {
+    return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
+  }
+
+  return HANDSHAKE_OK;
+}
+
+// kServerNoncePlaintextSize is the number of bytes in an unencrypted server
+// nonce.
+static const size_t kServerNoncePlaintextSize =
+    4 /* timestamp */ + 20 /* random bytes */;
+
+std::string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
+                                                   QuicWallTime now) const {
+  const uint32_t timestamp = static_cast<uint32_t>(now.ToUNIXSeconds());
+
+  uint8_t server_nonce[kServerNoncePlaintextSize];
+  static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small");
+  server_nonce[0] = static_cast<uint8_t>(timestamp >> 24);
+  server_nonce[1] = static_cast<uint8_t>(timestamp >> 16);
+  server_nonce[2] = static_cast<uint8_t>(timestamp >> 8);
+  server_nonce[3] = static_cast<uint8_t>(timestamp);
+  rand->RandBytes(&server_nonce[sizeof(timestamp)],
+                  sizeof(server_nonce) - sizeof(timestamp));
+
+  return server_nonce_boxer_.Box(
+      rand, absl::string_view(reinterpret_cast<char*>(server_nonce),
+                              sizeof(server_nonce)));
+}
+
+bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
+    const CryptoHandshakeMessage& client_hello,
+    const std::vector<std::string>& certs) const {
+  if (certs.empty()) {
+    return false;
+  }
+
+  uint64_t hash_from_client;
+  if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
+    return false;
+  }
+  return CryptoUtils::ComputeLeafCertHash(certs.at(0)) == hash_from_client;
+}
+
+bool QuicCryptoServerConfig::IsNextConfigReady(QuicWallTime now) const {
+  return !next_config_promotion_time_.IsZero() &&
+         !next_config_promotion_time_.IsAfter(now);
+}
+
+QuicCryptoServerConfig::Config::Config()
+    : channel_id_enabled(false),
+      is_primary(false),
+      primary_time(QuicWallTime::Zero()),
+      expiry_time(QuicWallTime::Zero()),
+      priority(0),
+      source_address_token_boxer(nullptr) {}
+
+QuicCryptoServerConfig::Config::~Config() {}
+
+QuicSignedServerConfig::QuicSignedServerConfig() {}
+QuicSignedServerConfig::~QuicSignedServerConfig() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config.h b/quiche/quic/core/crypto/quic_crypto_server_config.h
new file mode 100644
index 0000000..3d79ad7
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_server_config.h
@@ -0,0 +1,965 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+#include "quiche/quic/core/crypto/key_exchange.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_crypto_proof.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/proto/source_address_token_proto.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+class CryptoHandshakeMessage;
+class ProofSource;
+class QuicClock;
+class QuicRandom;
+class QuicServerConfigProtobuf;
+struct QuicSignedServerConfig;
+
+// ClientHelloInfo contains information about a client hello message that is
+// only kept for as long as it's being processed.
+struct QUIC_EXPORT_PRIVATE ClientHelloInfo {
+  ClientHelloInfo(const QuicIpAddress& in_client_ip, QuicWallTime in_now);
+  ClientHelloInfo(const ClientHelloInfo& other);
+  ~ClientHelloInfo();
+
+  // Inputs to EvaluateClientHello.
+  const QuicIpAddress client_ip;
+  const QuicWallTime now;
+
+  // Outputs from EvaluateClientHello.
+  bool valid_source_address_token;
+  absl::string_view sni;
+  absl::string_view client_nonce;
+  absl::string_view server_nonce;
+  absl::string_view user_agent_id;
+  SourceAddressTokens source_address_tokens;
+
+  // Errors from EvaluateClientHello.
+  std::vector<uint32_t> reject_reasons;
+  static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+};
+
+namespace test {
+class QuicCryptoServerConfigPeer;
+}  // namespace test
+
+// Hook that allows application code to subscribe to primary config changes.
+class QUIC_EXPORT_PRIVATE PrimaryConfigChangedCallback {
+ public:
+  PrimaryConfigChangedCallback();
+  PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete;
+  PrimaryConfigChangedCallback& operator=(const PrimaryConfigChangedCallback&) =
+      delete;
+  virtual ~PrimaryConfigChangedCallback();
+  virtual void Run(const std::string& scid) = 0;
+};
+
+// Callback used to accept the result of the |client_hello| validation step.
+class QUIC_EXPORT_PRIVATE ValidateClientHelloResultCallback {
+ public:
+  // Opaque token that holds information about the client_hello and
+  // its validity.  Can be interpreted by calling ProcessClientHello.
+  struct QUIC_EXPORT_PRIVATE Result : public quiche::QuicheReferenceCounted {
+    Result(const CryptoHandshakeMessage& in_client_hello,
+           QuicIpAddress in_client_ip,
+           QuicWallTime in_now);
+
+    CryptoHandshakeMessage client_hello;
+    ClientHelloInfo info;
+    QuicErrorCode error_code;
+    std::string error_details;
+
+    // Populated if the CHLO STK contained a CachedNetworkParameters proto.
+    CachedNetworkParameters cached_network_params;
+
+   protected:
+    ~Result() override;
+  };
+
+  ValidateClientHelloResultCallback();
+  ValidateClientHelloResultCallback(const ValidateClientHelloResultCallback&) =
+      delete;
+  ValidateClientHelloResultCallback& operator=(
+      const ValidateClientHelloResultCallback&) = delete;
+  virtual ~ValidateClientHelloResultCallback();
+  virtual void Run(quiche::QuicheReferenceCountedPointer<Result> result,
+                   std::unique_ptr<ProofSource::Details> details) = 0;
+};
+
+// Callback used to accept the result of the ProcessClientHello method.
+class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback {
+ public:
+  ProcessClientHelloResultCallback();
+  ProcessClientHelloResultCallback(const ProcessClientHelloResultCallback&) =
+      delete;
+  ProcessClientHelloResultCallback& operator=(
+      const ProcessClientHelloResultCallback&) = delete;
+  virtual ~ProcessClientHelloResultCallback();
+  virtual void Run(QuicErrorCode error,
+                   const std::string& error_details,
+                   std::unique_ptr<CryptoHandshakeMessage> message,
+                   std::unique_ptr<DiversificationNonce> diversification_nonce,
+                   std::unique_ptr<ProofSource::Details> details) = 0;
+};
+
+// Callback used to receive the results of a call to
+// BuildServerConfigUpdateMessage.
+class QUIC_EXPORT_PRIVATE BuildServerConfigUpdateMessageResultCallback {
+ public:
+  BuildServerConfigUpdateMessageResultCallback() = default;
+  virtual ~BuildServerConfigUpdateMessageResultCallback() {}
+  BuildServerConfigUpdateMessageResultCallback(
+      const BuildServerConfigUpdateMessageResultCallback&) = delete;
+  BuildServerConfigUpdateMessageResultCallback& operator=(
+      const BuildServerConfigUpdateMessageResultCallback&) = delete;
+  virtual void Run(bool ok, const CryptoHandshakeMessage& message) = 0;
+};
+
+// Object that is interested in built rejections (which include REJ, SREJ and
+// cheap SREJ).
+class QUIC_EXPORT_PRIVATE RejectionObserver {
+ public:
+  RejectionObserver() = default;
+  virtual ~RejectionObserver() {}
+  RejectionObserver(const RejectionObserver&) = delete;
+  RejectionObserver& operator=(const RejectionObserver&) = delete;
+  // Called after a rejection is built.
+  virtual void OnRejectionBuilt(const std::vector<uint32_t>& reasons,
+                                CryptoHandshakeMessage* out) const = 0;
+};
+
+// Factory for creating KeyExchange objects.
+class QUIC_EXPORT_PRIVATE KeyExchangeSource {
+ public:
+  virtual ~KeyExchangeSource() = default;
+
+  // Returns the default KeyExchangeSource.
+  static std::unique_ptr<KeyExchangeSource> Default();
+
+  // Create a new KeyExchange using the curve specified by |type| using the
+  // specified private key.  |private_key| may be empty for key-exchange
+  // mechanisms which do not hold the private key in-process.  If |is_fallback|
+  // is set, |private_key| is required to be set, and a local key-exchange
+  // object should be returned.
+  virtual std::unique_ptr<AsynchronousKeyExchange> Create(
+      std::string server_config_id,
+      bool is_fallback,
+      QuicTag type,
+      absl::string_view private_key) = 0;
+};
+
+// QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
+// Unlike a client, a QUIC server can have multiple configurations active in
+// order to support clients resuming with a previous configuration.
+// TODO(agl): when adding configurations at runtime is added, this object will
+// need to consider locking.
+class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
+ public:
+  // ConfigOptions contains options for generating server configs.
+  struct QUIC_EXPORT_PRIVATE ConfigOptions {
+    ConfigOptions();
+    ConfigOptions(const ConfigOptions& other);
+    ~ConfigOptions();
+
+    // expiry_time is the time, in UNIX seconds, when the server config will
+    // expire. If unset, it defaults to the current time plus six months.
+    QuicWallTime expiry_time;
+    // channel_id_enabled controls whether the server config will indicate
+    // support for ChannelIDs.
+    bool channel_id_enabled;
+    // id contains the server config id for the resulting config. If empty, a
+    // random id is generated.
+    std::string id;
+    // orbit contains the kOrbitSize bytes of the orbit value for the server
+    // config. If |orbit| is empty then a random orbit is generated.
+    std::string orbit;
+    // p256 determines whether a P-256 public key will be included in the
+    // server config. Note that this breaks deterministic server-config
+    // generation since P-256 key generation doesn't use the QuicRandom given
+    // to GenerateConfig().
+    bool p256;
+  };
+
+  // |source_address_token_secret|: secret key material used for encrypting and
+  //     decrypting source address tokens. It can be of any length as it is fed
+  //     into a KDF before use. In tests, use TESTING.
+  // |server_nonce_entropy|: an entropy source used to generate the orbit and
+  //     key for server nonces, which are always local to a given instance of a
+  //     server. Not owned.
+  // |proof_source|: provides certificate chains and signatures.
+  // |key_exchange_source|: provides key-exchange functionality.
+  QuicCryptoServerConfig(
+      absl::string_view source_address_token_secret,
+      QuicRandom* server_nonce_entropy,
+      std::unique_ptr<ProofSource> proof_source,
+      std::unique_ptr<KeyExchangeSource> key_exchange_source);
+  QuicCryptoServerConfig(const QuicCryptoServerConfig&) = delete;
+  QuicCryptoServerConfig& operator=(const QuicCryptoServerConfig&) = delete;
+  ~QuicCryptoServerConfig();
+
+  // TESTING is a magic parameter for passing to the constructor in tests.
+  static const char TESTING[];
+
+  // Generates a QuicServerConfigProtobuf protobuf suitable for
+  // AddConfig and SetConfigs.
+  static QuicServerConfigProtobuf GenerateConfig(QuicRandom* rand,
+                                                 const QuicClock* clock,
+                                                 const ConfigOptions& options);
+
+  // AddConfig adds a QuicServerConfigProtobuf to the available configurations.
+  // It returns the SCFG message from the config if successful. |now| is used in
+  // conjunction with |protobuf->primary_time()| to determine whether the
+  // config should be made primary.
+  std::unique_ptr<CryptoHandshakeMessage> AddConfig(
+      const QuicServerConfigProtobuf& protobuf,
+      QuicWallTime now);
+
+  // AddDefaultConfig calls GenerateConfig to create a config and then calls
+  // AddConfig to add it. See the comment for |GenerateConfig| for details of
+  // the arguments.
+  std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig(
+      QuicRandom* rand,
+      const QuicClock* clock,
+      const ConfigOptions& options);
+
+  // SetConfigs takes a vector of config protobufs and the current time.
+  // Configs are assumed to be uniquely identified by their server config ID.
+  // Previously unknown configs are added and possibly made the primary config
+  // depending on their |primary_time| and the value of |now|. Configs that are
+  // known, but are missing from the protobufs are deleted, unless they are
+  // currently the primary config. SetConfigs returns false if any errors were
+  // encountered and no changes to the QuicCryptoServerConfig will occur.
+  bool SetConfigs(const std::vector<QuicServerConfigProtobuf>& protobufs,
+                  const QuicServerConfigProtobuf* fallback_protobuf,
+                  QuicWallTime now);
+
+  // SetSourceAddressTokenKeys sets the keys to be tried, in order, when
+  // decrypting a source address token.  Note that these keys are used *without*
+  // passing them through a KDF, in contradistinction to the
+  // |source_address_token_secret| argument to the constructor.
+  void SetSourceAddressTokenKeys(const std::vector<std::string>& keys);
+
+  // Get the server config ids for all known configs.
+  std::vector<std::string> GetConfigIds() const;
+
+  // Checks |client_hello| for gross errors and determines whether it can be
+  // shown to be fresh (i.e. not a replay).  The result of the validation step
+  // must be interpreted by calling QuicCryptoServerConfig::ProcessClientHello
+  // from the done_cb.
+  //
+  // ValidateClientHello may invoke the done_cb before unrolling the
+  // stack if it is able to assess the validity of the client_nonce
+  // without asynchronous operations.
+  //
+  // client_hello: the incoming client hello message.
+  // client_ip: the IP address of the client, which is used to generate and
+  //     validate source-address tokens.
+  // server_address: the IP address and port of the server. The IP address and
+  //     port may be used for certificate selection.
+  // version: protocol version used for this connection.
+  // clock: used to validate client nonces and ephemeral keys.
+  // signed_config: in/out parameter to which will be written the crypto proof
+  //     used in reply to a proof demand.  The pointed-to-object must live until
+  //     the callback is invoked.
+  // done_cb: single-use callback that accepts an opaque
+  //     ValidatedClientHelloMsg token that holds information about
+  //     the client hello.  The callback will always be called exactly
+  //     once, either under the current call stack, or after the
+  //     completion of an asynchronous operation.
+  void ValidateClientHello(
+      const CryptoHandshakeMessage& client_hello,
+      const QuicSocketAddress& client_address,
+      const QuicSocketAddress& server_address, QuicTransportVersion version,
+      const QuicClock* clock,
+      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+          signed_config,
+      std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
+
+  // ProcessClientHello processes |client_hello| and decides whether to accept
+  // or reject the connection. If the connection is to be accepted, |done_cb| is
+  // invoked with the contents of the ServerHello and QUIC_NO_ERROR. Otherwise
+  // |done_cb| is called with a REJ or SREJ message and QUIC_NO_ERROR.
+  //
+  // validate_chlo_result: Output from the asynchronous call to
+  //     ValidateClientHello.  Contains the client hello message and
+  //     information about it.
+  // reject_only: Only generate rejections, not server hello messages.
+  // connection_id: the ConnectionId for the connection, which is used in key
+  //     derivation.
+  // server_ip: the IP address of the server. The IP address may be used for
+  //     certificate selection.
+  // client_address: the IP address and port of the client. The IP address is
+  //     used to generate and validate source-address tokens.
+  // version: version of the QUIC protocol in use for this connection
+  // supported_versions: versions of the QUIC protocol that this server
+  //     supports.
+  // clock: used to validate client nonces and ephemeral keys.
+  // rand: an entropy source
+  // compressed_certs_cache: the cache that caches a set of most recently used
+  //     certs. Owned by QuicDispatcher.
+  // params: the state of the handshake. This may be updated with a server
+  //     nonce when we send a rejection.
+  // signed_config: output structure containing the crypto proof used in reply
+  //     to a proof demand.
+  // total_framing_overhead: the total per-packet overhead for a stream frame
+  // chlo_packet_size: the size, in bytes, of the CHLO packet
+  // done_cb: the callback invoked on completion
+  void ProcessClientHello(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          validate_chlo_result,
+      bool reject_only, QuicConnectionId connection_id,
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, ParsedQuicVersion version,
+      const ParsedQuicVersionVector& supported_versions, const QuicClock* clock,
+      QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
+      quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+          params,
+      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+          signed_config,
+      QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
+      std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const;
+
+  // BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing
+  // the current primary config, an up to date source-address token, and cert
+  // chain and proof in the case of secure QUIC. Passes true to |cb| if the
+  // message was generated successfully, and false otherwise.  This method
+  // assumes ownership of |cb|.
+  //
+  // |cached_network_params| is optional, and can be nullptr.
+  void BuildServerConfigUpdateMessage(
+      QuicTransportVersion version,
+      absl::string_view chlo_hash,
+      const SourceAddressTokens& previous_source_address_tokens,
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const QuicClock* clock,
+      QuicRandom* rand,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const QuicCryptoNegotiatedParameters& params,
+      const CachedNetworkParameters* cached_network_params,
+      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
+
+  // set_replay_protection controls whether replay protection is enabled. If
+  // replay protection is disabled then no strike registers are needed and
+  // frontends can share an orbit value without a shared strike-register.
+  // However, an attacker can duplicate a handshake and cause a client's
+  // request to be processed twice.
+  void set_replay_protection(bool on);
+
+  // set_chlo_multiplier specifies the multiple of the CHLO message size
+  // that a REJ message must stay under when the client doesn't present a
+  // valid source-address token.
+  void set_chlo_multiplier(size_t multiplier);
+
+  // When sender is allowed to not pad client hello (not standards compliant),
+  // we need to disable the client hello check.
+  void set_validate_chlo_size(bool new_value) {
+    validate_chlo_size_ = new_value;
+  }
+
+  // Returns whether the sender is allowed to not pad the client hello.
+  bool validate_chlo_size() const { return validate_chlo_size_; }
+
+  // When QUIC is tunneled through some other mechanism, source token validation
+  // may be disabled. Do not disable it if you are not providing other
+  // protection. (|true| protects against UDP amplification attack.).
+  void set_validate_source_address_token(bool new_value) {
+    validate_source_address_token_ = new_value;
+  }
+
+  // set_source_address_token_future_secs sets the number of seconds into the
+  // future that source-address tokens will be accepted from. Since
+  // source-address tokens are authenticated, this should only happen if
+  // another, valid server has clock-skew.
+  void set_source_address_token_future_secs(uint32_t future_secs);
+
+  // set_source_address_token_lifetime_secs sets the number of seconds that a
+  // source-address token will be valid for.
+  void set_source_address_token_lifetime_secs(uint32_t lifetime_secs);
+
+  // set_enable_serving_sct enables or disables serving signed cert timestamp
+  // (RFC6962) in server hello.
+  void set_enable_serving_sct(bool enable_serving_sct);
+
+  // Set and take ownership of the callback to invoke on primary config changes.
+  void AcquirePrimaryConfigChangedCb(
+      std::unique_ptr<PrimaryConfigChangedCallback> cb);
+
+  // Returns the number of configs this object owns.
+  int NumberOfConfigs() const;
+
+  // NewSourceAddressToken returns a fresh source address token for the given
+  // IP address. |previous_tokens| is the received tokens, and can be empty.
+  // |cached_network_params| is optional, and can be nullptr.
+  std::string NewSourceAddressToken(
+      const CryptoSecretBoxer& crypto_secret_boxer,
+      const SourceAddressTokens& previous_tokens,
+      const QuicIpAddress& ip,
+      QuicRandom* rand,
+      QuicWallTime now,
+      const CachedNetworkParameters* cached_network_params) const;
+
+  // ParseSourceAddressToken parses the source address tokens contained in
+  // the encrypted |token|, and populates |tokens| with the parsed tokens.
+  // Returns HANDSHAKE_OK if |token| could be parsed, or the reason for the
+  // failure.
+  HandshakeFailureReason ParseSourceAddressToken(
+      const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
+      SourceAddressTokens& tokens) const;
+
+  // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address
+  // tokens in |tokens| contain a valid and timely token for the IP address
+  // |ip| given that the current time is |now|. Otherwise it returns the
+  // reason for failure. |cached_network_params| is populated if the valid
+  // token contains a CachedNetworkParameters proto.
+  HandshakeFailureReason ValidateSourceAddressTokens(
+      const SourceAddressTokens& tokens,
+      const QuicIpAddress& ip,
+      QuicWallTime now,
+      CachedNetworkParameters* cached_network_params) const;
+
+  // Callers retain the ownership of |rejection_observer| which must outlive the
+  // config.
+  void set_rejection_observer(RejectionObserver* rejection_observer) {
+    rejection_observer_ = rejection_observer;
+  }
+
+  ProofSource* proof_source() const;
+
+  SSL_CTX* ssl_ctx() const;
+
+  // Pre-shared key used during the handshake.
+  const std::string& pre_shared_key() const { return pre_shared_key_; }
+  void set_pre_shared_key(absl::string_view psk) {
+    pre_shared_key_ = std::string(psk);
+  }
+
+  bool pad_rej() const { return pad_rej_; }
+  void set_pad_rej(bool new_value) { pad_rej_ = new_value; }
+
+  bool pad_shlo() const { return pad_shlo_; }
+  void set_pad_shlo(bool new_value) { pad_shlo_ = new_value; }
+
+  const CryptoSecretBoxer& source_address_token_boxer() const {
+    return source_address_token_boxer_;
+  }
+
+ private:
+  friend class test::QuicCryptoServerConfigPeer;
+  friend struct QuicSignedServerConfig;
+
+  // Config represents a server config: a collection of preferences and
+  // Diffie-Hellman public values.
+  class QUIC_EXPORT_PRIVATE Config : public QuicCryptoConfig,
+                                     public quiche::QuicheReferenceCounted {
+   public:
+    Config();
+    Config(const Config&) = delete;
+    Config& operator=(const Config&) = delete;
+
+    // TODO(rtenneti): since this is a class, we should probably do
+    // getters/setters here.
+    // |serialized| contains the bytes of this server config, suitable for
+    // sending on the wire.
+    std::string serialized;
+    // id contains the SCID of this server config.
+    std::string id;
+    // orbit contains the orbit value for this config: an opaque identifier
+    // used to identify clusters of server frontends.
+    unsigned char orbit[kOrbitSize];
+
+    // key_exchanges contains key exchange objects. The values correspond,
+    // one-to-one, with the tags in |kexs| from the parent class.
+    std::vector<std::unique_ptr<AsynchronousKeyExchange>> key_exchanges;
+
+    // channel_id_enabled is true if the config in |serialized| specifies that
+    // ChannelIDs are supported.
+    bool channel_id_enabled;
+
+    // is_primary is true if this config is the one that we'll give out to
+    // clients as the current one.
+    bool is_primary;
+
+    // primary_time contains the timestamp when this config should become the
+    // primary config. A value of QuicWallTime::Zero() means that this config
+    // will not be promoted at a specific time.
+    QuicWallTime primary_time;
+
+    // expiry_time contains the timestamp when this config expires.
+    QuicWallTime expiry_time;
+
+    // Secondary sort key for use when selecting primary configs and
+    // there are multiple configs with the same primary time.
+    // Smaller numbers mean higher priority.
+    uint64_t priority;
+
+    // source_address_token_boxer_ is used to protect the
+    // source-address tokens that are given to clients.
+    // Points to either source_address_token_boxer_storage or the
+    // default boxer provided by QuicCryptoServerConfig.
+    const CryptoSecretBoxer* source_address_token_boxer;
+
+    // Holds the override source_address_token_boxer instance if the
+    // Config is not using the default source address token boxer
+    // instance provided by QuicCryptoServerConfig.
+    std::unique_ptr<CryptoSecretBoxer> source_address_token_boxer_storage;
+
+   private:
+    ~Config() override;
+  };
+
+  using ConfigMap =
+      std::map<ServerConfigID, quiche::QuicheReferenceCountedPointer<Config>>;
+
+  // Get a ref to the config with a given server config id.
+  quiche::QuicheReferenceCountedPointer<Config> GetConfigWithScid(
+      absl::string_view requested_scid) const
+      QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
+
+  // A snapshot of the configs associated with an in-progress handshake.
+  struct QUIC_EXPORT_PRIVATE Configs {
+    quiche::QuicheReferenceCountedPointer<Config> requested;
+    quiche::QuicheReferenceCountedPointer<Config> primary;
+    quiche::QuicheReferenceCountedPointer<Config> fallback;
+  };
+
+  // Get a snapshot of the current configs associated with a handshake.  If this
+  // method was called earlier in this handshake |old_primary_config| should be
+  // set to the primary config returned from that invocation, otherwise nullptr.
+  //
+  // Returns true if any configs are loaded.  If false is returned, |configs| is
+  // not modified.
+  bool GetCurrentConfigs(
+      const QuicWallTime& now, absl::string_view requested_scid,
+      quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
+      Configs* configs) const;
+
+  // ConfigPrimaryTimeLessThan returns true if a->primary_time <
+  // b->primary_time.
+  static bool ConfigPrimaryTimeLessThan(
+      const quiche::QuicheReferenceCountedPointer<Config>& a,
+      const quiche::QuicheReferenceCountedPointer<Config>& b);
+
+  // SelectNewPrimaryConfig reevaluates the primary config based on the
+  // "primary_time" deadlines contained in each.
+  void SelectNewPrimaryConfig(QuicWallTime now) const
+      QUIC_EXCLUSIVE_LOCKS_REQUIRED(configs_lock_);
+
+  // EvaluateClientHello checks |client_hello_state->client_hello| for gross
+  // errors and determines whether it is fresh (i.e. not a replay). The results
+  // are written to |client_hello_state->info|.
+  void EvaluateClientHello(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, QuicTransportVersion version,
+      const Configs& configs,
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          client_hello_state,
+      std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const;
+
+  // Convenience class which carries the arguments passed to
+  // |ProcessClientHellp| along.
+  class QUIC_EXPORT_PRIVATE ProcessClientHelloContext {
+   public:
+    ProcessClientHelloContext(
+        quiche::QuicheReferenceCountedPointer<
+            ValidateClientHelloResultCallback::Result>
+            validate_chlo_result,
+        bool reject_only, QuicConnectionId connection_id,
+        const QuicSocketAddress& server_address,
+        const QuicSocketAddress& client_address, ParsedQuicVersion version,
+        const ParsedQuicVersionVector& supported_versions,
+        const QuicClock* clock, QuicRandom* rand,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+            params,
+        quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+            signed_config,
+        QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
+        std::unique_ptr<ProcessClientHelloResultCallback> done_cb)
+        : validate_chlo_result_(validate_chlo_result),
+          reject_only_(reject_only),
+          connection_id_(connection_id),
+          server_address_(server_address),
+          client_address_(client_address),
+          version_(version),
+          supported_versions_(supported_versions),
+          clock_(clock),
+          rand_(rand),
+          compressed_certs_cache_(compressed_certs_cache),
+          params_(params),
+          signed_config_(signed_config),
+          total_framing_overhead_(total_framing_overhead),
+          chlo_packet_size_(chlo_packet_size),
+          done_cb_(std::move(done_cb)) {}
+
+    ~ProcessClientHelloContext();
+
+    // Invoke |done_cb_| with an error status
+    void Fail(QuicErrorCode error, const std::string& error_details);
+
+    // Invoke |done_cb_| with a success status
+    void Succeed(std::unique_ptr<CryptoHandshakeMessage> message,
+                 std::unique_ptr<DiversificationNonce> diversification_nonce,
+                 std::unique_ptr<ProofSource::Details> proof_source_details);
+
+    // Member accessors
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+    validate_chlo_result() const {
+      return validate_chlo_result_;
+    }
+    bool reject_only() const { return reject_only_; }
+    QuicConnectionId connection_id() const { return connection_id_; }
+    QuicSocketAddress server_address() const { return server_address_; }
+    QuicSocketAddress client_address() const { return client_address_; }
+    ParsedQuicVersion version() const { return version_; }
+    ParsedQuicVersionVector supported_versions() const {
+      return supported_versions_;
+    }
+    const QuicClock* clock() const { return clock_; }
+    QuicRandom* rand() const { return rand_; }  // NOLINT
+    QuicCompressedCertsCache* compressed_certs_cache() const {
+      return compressed_certs_cache_;
+    }
+    quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+    params() const {
+      return params_;
+    }
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+    signed_config() const {
+      return signed_config_;
+    }
+    QuicByteCount total_framing_overhead() const {
+      return total_framing_overhead_;
+    }
+    QuicByteCount chlo_packet_size() const { return chlo_packet_size_; }
+
+    // Derived value accessors
+    const CryptoHandshakeMessage& client_hello() const {
+      return validate_chlo_result()->client_hello;
+    }
+    const ClientHelloInfo& info() const { return validate_chlo_result()->info; }
+    QuicTransportVersion transport_version() const {
+      return version().transport_version;
+    }
+
+   private:
+    const quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        validate_chlo_result_;
+    const bool reject_only_;
+    const QuicConnectionId connection_id_;
+    const QuicSocketAddress server_address_;
+    const QuicSocketAddress client_address_;
+    const ParsedQuicVersion version_;
+    const ParsedQuicVersionVector supported_versions_;
+    const QuicClock* const clock_;
+    QuicRandom* const rand_;
+    QuicCompressedCertsCache* const compressed_certs_cache_;
+    const quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+        params_;
+    const quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+        signed_config_;
+    const QuicByteCount total_framing_overhead_;
+    const QuicByteCount chlo_packet_size_;
+    std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
+  };
+
+  // Callback class for bridging between ProcessClientHello and
+  // ProcessClientHelloAfterGetProof.
+  class ProcessClientHelloCallback;
+  friend class ProcessClientHelloCallback;
+
+  // Portion of ProcessClientHello which executes after GetProof.
+  void ProcessClientHelloAfterGetProof(
+      bool found_error,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      const Configs& configs) const;
+
+  // Callback class for bridging between ProcessClientHelloAfterGetProof and
+  // ProcessClientHelloAfterCalculateSharedKeys.
+  class ProcessClientHelloAfterGetProofCallback;
+  friend class ProcessClientHelloAfterGetProofCallback;
+
+  // Portion of ProcessClientHello which executes after CalculateSharedKeys.
+  void ProcessClientHelloAfterCalculateSharedKeys(
+      bool found_error,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      QuicTag key_exchange_type,
+      std::unique_ptr<CryptoHandshakeMessage> out,
+      absl::string_view public_value,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      const Configs& configs) const;
+
+  // Send a REJ which contains a different ServerConfig than the one the client
+  // originally used.  This is necessary in cases where we discover in the
+  // middle of the handshake that the private key for the ServerConfig the
+  // client used is not accessible.
+  void SendRejectWithFallbackConfig(
+      std::unique_ptr<ProcessClientHelloContext> context,
+      quiche::QuicheReferenceCountedPointer<Config> fallback_config) const;
+
+  // Callback class for bridging between SendRejectWithFallbackConfig and
+  // SendRejectWithFallbackConfigAfterGetProof.
+  class SendRejectWithFallbackConfigCallback;
+  friend class SendRejectWithFallbackConfigCallback;
+
+  // Portion of ProcessClientHello which executes after GetProof in the case
+  // where we have received a CHLO but need to reject it due to the ServerConfig
+  // private keys being inaccessible.
+  void SendRejectWithFallbackConfigAfterGetProof(
+      bool found_error,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      std::unique_ptr<ProcessClientHelloContext> context,
+      quiche::QuicheReferenceCountedPointer<Config> fallback_config) const;
+
+  // BuildRejectionAndRecordStats calls |BuildRejection| below and also informs
+  // the RejectionObserver.
+  void BuildRejectionAndRecordStats(const ProcessClientHelloContext& context,
+                                    const Config& config,
+                                    const std::vector<uint32_t>& reject_reasons,
+                                    CryptoHandshakeMessage* out) const;
+
+  // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
+  void BuildRejection(const ProcessClientHelloContext& context,
+                      const Config& config,
+                      const std::vector<uint32_t>& reject_reasons,
+                      CryptoHandshakeMessage* out) const;
+
+  // CompressChain compresses the certificates in |chain->certs| and returns a
+  // compressed representation. |client_cached_cert_hashes| contains
+  // 64-bit, FNV-1a hashes of certificates that the peer already possesses.
+  static std::string CompressChain(
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes);
+
+  // ParseConfigProtobuf parses the given config protobuf and returns a
+  // quiche::QuicheReferenceCountedPointer<Config> if successful. The caller
+  // adopts the reference to the Config. On error, ParseConfigProtobuf returns
+  // nullptr.
+  quiche::QuicheReferenceCountedPointer<Config> ParseConfigProtobuf(
+      const QuicServerConfigProtobuf& protobuf, bool is_fallback) const;
+
+  // ValidateSingleSourceAddressToken returns HANDSHAKE_OK if the source
+  // address token in |token| is a timely token for the IP address |ip|
+  // given that the current time is |now|. Otherwise it returns the reason
+  // for failure.
+  HandshakeFailureReason ValidateSingleSourceAddressToken(
+      const SourceAddressToken& token,
+      const QuicIpAddress& ip,
+      QuicWallTime now) const;
+
+  // Returns HANDSHAKE_OK if the source address token in |token| is a timely
+  // token given that the current time is |now|. Otherwise it returns the
+  // reason for failure.
+  HandshakeFailureReason ValidateSourceAddressTokenTimestamp(
+      const SourceAddressToken& token,
+      QuicWallTime now) const;
+
+  // NewServerNonce generates and encrypts a random nonce.
+  std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
+
+  // ValidateExpectedLeafCertificate checks the |client_hello| to see if it has
+  // an XLCT tag, and if so, verifies that its value matches the hash of the
+  // server's leaf certificate. |certs| is used to compare against the XLCT
+  // value.  This method returns true if the XLCT tag is not present, or if the
+  // XLCT tag is present and valid. It returns false otherwise.
+  bool ValidateExpectedLeafCertificate(
+      const CryptoHandshakeMessage& client_hello,
+      const std::vector<std::string>& certs) const;
+
+  // Callback to receive the results of ProofSource::GetProof.  Note: this
+  // callback has no cancellation support, since the lifetime of the ProofSource
+  // is controlled by this object via unique ownership.  If that ownership
+  // stricture changes, this decision may need to be revisited.
+  class BuildServerConfigUpdateMessageProofSourceCallback
+      : public ProofSource::Callback {
+   public:
+    BuildServerConfigUpdateMessageProofSourceCallback(
+        const BuildServerConfigUpdateMessageProofSourceCallback&) = delete;
+    ~BuildServerConfigUpdateMessageProofSourceCallback() override;
+    void operator=(const BuildServerConfigUpdateMessageProofSourceCallback&) =
+        delete;
+    BuildServerConfigUpdateMessageProofSourceCallback(
+        const QuicCryptoServerConfig* config,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        const QuicCryptoNegotiatedParameters& params,
+        CryptoHandshakeMessage message,
+        std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb);
+
+    void Run(
+        bool ok,
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const QuicCryptoProof& proof,
+        std::unique_ptr<ProofSource::Details> details) override;
+
+   private:
+    const QuicCryptoServerConfig* config_;
+    QuicCompressedCertsCache* compressed_certs_cache_;
+    const std::string client_cached_cert_hashes_;
+    const bool sct_supported_by_client_;
+    const std::string sni_;
+    CryptoHandshakeMessage message_;
+    std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb_;
+  };
+
+  // Invoked by BuildServerConfigUpdateMessageProofSourceCallback::Run once
+  // the proof has been acquired.  Finishes building the server config update
+  // message and invokes |cb|.
+  void FinishBuildServerConfigUpdateMessage(
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const std::string& client_cached_cert_hashes,
+      bool sct_supported_by_client, const std::string& sni, bool ok,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& signature, const std::string& leaf_cert_sct,
+      std::unique_ptr<ProofSource::Details> details,
+      CryptoHandshakeMessage message,
+      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const;
+
+  // Returns true if the next config promotion should happen now.
+  bool IsNextConfigReady(QuicWallTime now) const
+      QUIC_SHARED_LOCKS_REQUIRED(configs_lock_);
+
+  // replay_protection_ controls whether the server enforces that handshakes
+  // aren't replays.
+  bool replay_protection_;
+
+  // The multiple of the CHLO message size that a REJ message must stay under
+  // when the client doesn't present a valid source-address token. This is
+  // used to protect QUIC from amplification attacks.
+  size_t chlo_multiplier_;
+
+  // configs_ satisfies the following invariants:
+  //   1) configs_.empty() <-> primary_config_ == nullptr
+  //   2) primary_config_ != nullptr -> primary_config_->is_primary
+  //   3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
+  mutable QuicMutex configs_lock_;
+
+  // configs_ contains all active server configs. It's expected that there are
+  // about half-a-dozen configs active at any one time.
+  ConfigMap configs_ QUIC_GUARDED_BY(configs_lock_);
+
+  // primary_config_ points to a Config (which is also in |configs_|) which is
+  // the primary config - i.e. the one that we'll give out to new clients.
+  mutable quiche::QuicheReferenceCountedPointer<Config> primary_config_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // fallback_config_ points to a Config (which is also in |configs_|) which is
+  // the fallback config, which will be used if the other configs are unuseable
+  // for some reason.
+  //
+  // TODO(b/112548056): This is currently always nullptr.
+  quiche::QuicheReferenceCountedPointer<Config> fallback_config_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // next_config_promotion_time_ contains the nearest, future time when an
+  // active config will be promoted to primary.
+  mutable QuicWallTime next_config_promotion_time_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // Callback to invoke when the primary config changes.
+  std::unique_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_
+      QUIC_GUARDED_BY(configs_lock_);
+
+  // Used to protect the source-address tokens that are given to clients.
+  CryptoSecretBoxer source_address_token_boxer_;
+
+  // server_nonce_boxer_ is used to encrypt and validate suggested server
+  // nonces.
+  CryptoSecretBoxer server_nonce_boxer_;
+
+  // server_nonce_orbit_ contains the random, per-server orbit values that this
+  // server will use to generate server nonces (the moral equivalent of a SYN
+  // cookies).
+  uint8_t server_nonce_orbit_[8];
+
+  // proof_source_ contains an object that can provide certificate chains and
+  // signatures.
+  std::unique_ptr<ProofSource> proof_source_;
+
+  // key_exchange_source_ contains an object that can provide key exchange
+  // objects.
+  std::unique_ptr<KeyExchangeSource> key_exchange_source_;
+
+  // ssl_ctx_ contains the server configuration for doing TLS handshakes.
+  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+
+  // These fields store configuration values. See the comments for their
+  // respective setter functions.
+  uint32_t source_address_token_future_secs_;
+  uint32_t source_address_token_lifetime_secs_;
+
+  // Enable serving SCT or not.
+  bool enable_serving_sct_;
+
+  // Does not own this observer.
+  RejectionObserver* rejection_observer_;
+
+  // If non-empty, the server will operate in the pre-shared key mode by
+  // incorporating |pre_shared_key_| into the key schedule.
+  std::string pre_shared_key_;
+
+  // Whether REJ message should be padded to max packet size.
+  bool pad_rej_;
+
+  // Whether SHLO message should be padded to max packet size.
+  bool pad_shlo_;
+
+  // If client is allowed to send a small client hello (by disabling padding),
+  // server MUST not check for the client hello size.
+  // DO NOT disable this unless you have some other way of validating client.
+  // (e.g. in realtime scenarios, where quic is tunneled through ICE, ICE will
+  // do its own peer validation using STUN pings with ufrag/upass).
+  bool validate_chlo_size_;
+
+  // When source address is validated by some other means (e.g. when using ICE),
+  // source address token validation may be disabled.
+  bool validate_source_address_token_;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig
+    : public quiche::QuicheReferenceCounted {
+  QuicSignedServerConfig();
+
+  QuicCryptoProof proof;
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
+  // The server config that is used for this proof (and the rest of the
+  // request).
+  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config> config;
+  std::string primary_scid;
+
+ protected:
+  ~QuicSignedServerConfig() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
diff --git a/quiche/quic/core/crypto/quic_crypto_server_config_test.cc b/quiche/quic/core/crypto/quic_crypto_server_config_test.cc
new file mode 100644
index 0000000..5a24881
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -0,0 +1,500 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+
+#include <stdarg.h>
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/cert_compressor.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_secret_boxer.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+using ::testing::Not;
+
+// NOTE: This matcher depends on the wire format of serialzied protocol buffers,
+// which may change in the future.
+// Switch to ::testing::EqualsProto once it is available in Chromium.
+MATCHER_P(SerializedProtoEquals, message, "") {
+  std::string expected_serialized, actual_serialized;
+  message.SerializeToString(&expected_serialized);
+  arg.SerializeToString(&actual_serialized);
+  return expected_serialized == actual_serialized;
+}
+
+class QuicCryptoServerConfigTest : public QuicTest {};
+
+TEST_F(QuicCryptoServerConfigTest, ServerConfig) {
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  MockClock clock;
+
+  std::unique_ptr<CryptoHandshakeMessage> message(server.AddDefaultConfig(
+      rand, &clock, QuicCryptoServerConfig::ConfigOptions()));
+
+  // The default configuration should have AES-GCM and at least one ChaCha20
+  // cipher.
+  QuicTagVector aead;
+  ASSERT_THAT(message->GetTaglist(kAEAD, &aead), IsQuicNoError());
+  EXPECT_THAT(aead, ::testing::Contains(kAESG));
+  EXPECT_LE(1u, aead.size());
+}
+
+TEST_F(QuicCryptoServerConfigTest, CompressCerts) {
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  QuicCryptoServerConfigPeer peer(&server);
+
+  std::vector<std::string> certs = {"testcert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+
+  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, "");
+
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+}
+
+TEST_F(QuicCryptoServerConfigTest, CompressSameCertsTwice) {
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  QuicCryptoServerConfigPeer peer(&server);
+
+  // Compress the certs for the first time.
+  std::vector<std::string> certs = {"testcert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+  std::string cached_certs = "";
+
+  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, cached_certs);
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+
+  // Compress the same certs, should use cache if available.
+  std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, cached_certs);
+  EXPECT_EQ(compressed, compressed2);
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+}
+
+TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) {
+  // This test compresses a set of similar but not identical certs. Cache if
+  // used should return cache miss and add all the compressed certs.
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
+                                crypto_test_utils::ProofSourceForTesting(),
+                                KeyExchangeSource::Default());
+  QuicCryptoServerConfigPeer peer(&server);
+
+  std::vector<std::string> certs = {"testcert"};
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
+      new ProofSource::Chain(certs));
+  std::string cached_certs = "";
+
+  std::string compressed = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain, cached_certs);
+  EXPECT_EQ(compressed_certs_cache.Size(), 1u);
+
+  // Compress a similar certs which only differs in the chain.
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
+      new ProofSource::Chain(certs));
+
+  std::string compressed2 = QuicCryptoServerConfigPeer::CompressChain(
+      &compressed_certs_cache, chain2, cached_certs);
+  EXPECT_EQ(compressed_certs_cache.Size(), 2u);
+}
+
+class SourceAddressTokenTest : public QuicTest {
+ public:
+  SourceAddressTokenTest()
+      : ip4_(QuicIpAddress::Loopback4()),
+        ip4_dual_(ip4_.DualStacked()),
+        ip6_(QuicIpAddress::Loopback6()),
+        original_time_(QuicWallTime::Zero()),
+        rand_(QuicRandom::GetInstance()),
+        server_(QuicCryptoServerConfig::TESTING,
+                rand_,
+                crypto_test_utils::ProofSourceForTesting(),
+                KeyExchangeSource::Default()),
+        peer_(&server_) {
+    // Advance the clock to some non-zero time.
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
+    original_time_ = clock_.WallNow();
+
+    primary_config_ = server_.AddDefaultConfig(
+        rand_, &clock_, QuicCryptoServerConfig::ConfigOptions());
+  }
+
+  std::string NewSourceAddressToken(std::string config_id,
+                                    const QuicIpAddress& ip) {
+    return NewSourceAddressToken(config_id, ip, nullptr);
+  }
+
+  std::string NewSourceAddressToken(
+      std::string config_id,
+      const QuicIpAddress& ip,
+      const SourceAddressTokens& previous_tokens) {
+    return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
+                                       clock_.WallNow(), nullptr);
+  }
+
+  std::string NewSourceAddressToken(
+      std::string config_id,
+      const QuicIpAddress& ip,
+      CachedNetworkParameters* cached_network_params) {
+    SourceAddressTokens previous_tokens;
+    return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
+                                       clock_.WallNow(), cached_network_params);
+  }
+
+  HandshakeFailureReason ValidateSourceAddressTokens(std::string config_id,
+                                                     absl::string_view srct,
+                                                     const QuicIpAddress& ip) {
+    return ValidateSourceAddressTokens(config_id, srct, ip, nullptr);
+  }
+
+  HandshakeFailureReason ValidateSourceAddressTokens(
+      std::string config_id,
+      absl::string_view srct,
+      const QuicIpAddress& ip,
+      CachedNetworkParameters* cached_network_params) {
+    return peer_.ValidateSourceAddressTokens(
+        config_id, srct, ip, clock_.WallNow(), cached_network_params);
+  }
+
+  const std::string kPrimary = "<primary>";
+  const std::string kOverride = "Config with custom source address token key";
+
+  QuicIpAddress ip4_;
+  QuicIpAddress ip4_dual_;
+  QuicIpAddress ip6_;
+
+  MockClock clock_;
+  QuicWallTime original_time_;
+  QuicRandom* rand_ = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server_;
+  QuicCryptoServerConfigPeer peer_;
+  // Stores the primary config.
+  std::unique_ptr<CryptoHandshakeMessage> primary_config_;
+  std::unique_ptr<QuicServerConfigProtobuf> override_config_protobuf_;
+};
+
+// Test basic behavior of source address tokens including being specific
+// to a single IP address and server config.
+TEST_F(SourceAddressTokenTest, SourceAddressToken) {
+  // Primary config generates configs that validate successfully.
+  const std::string token4 = NewSourceAddressToken(kPrimary, ip4_);
+  const std::string token4d = NewSourceAddressToken(kPrimary, ip4_dual_);
+  const std::string token6 = NewSourceAddressToken(kPrimary, ip6_);
+  EXPECT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4, ip4_));
+  ASSERT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4, ip4_dual_));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token4, ip6_));
+  ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4d, ip4_));
+  ASSERT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4d, ip4_dual_));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token4d, ip6_));
+  ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token6, ip6_));
+}
+
+TEST_F(SourceAddressTokenTest, SourceAddressTokenExpiration) {
+  const std::string token = NewSourceAddressToken(kPrimary, ip4_);
+
+  // Validation fails if the token is from the future.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(-3600 * 2));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token, ip4_));
+
+  // Validation fails after tokens expire.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400 * 7));
+  ASSERT_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
+            ValidateSourceAddressTokens(kPrimary, token, ip4_));
+}
+
+TEST_F(SourceAddressTokenTest, SourceAddressTokenWithNetworkParams) {
+  // Make sure that if the source address token contains CachedNetworkParameters
+  // that this gets written to ValidateSourceAddressToken output argument.
+  CachedNetworkParameters cached_network_params_input;
+  cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
+  const std::string token4_with_cached_network_params =
+      NewSourceAddressToken(kPrimary, ip4_, &cached_network_params_input);
+
+  CachedNetworkParameters cached_network_params_output;
+  EXPECT_THAT(cached_network_params_output,
+              Not(SerializedProtoEquals(cached_network_params_input)));
+  ValidateSourceAddressTokens(kPrimary, token4_with_cached_network_params, ip4_,
+                              &cached_network_params_output);
+  EXPECT_THAT(cached_network_params_output,
+              SerializedProtoEquals(cached_network_params_input));
+}
+
+// Test the ability for a source address token to be valid for multiple
+// addresses.
+TEST_F(SourceAddressTokenTest, SourceAddressTokenMultipleAddresses) {
+  QuicWallTime now = clock_.WallNow();
+
+  // Now create a token which is usable for both addresses.
+  SourceAddressToken previous_token;
+  previous_token.set_ip(ip6_.DualStacked().ToPackedString());
+  previous_token.set_timestamp(now.ToUNIXSeconds());
+  SourceAddressTokens previous_tokens;
+  (*previous_tokens.add_tokens()) = previous_token;
+  const std::string token4or6 =
+      NewSourceAddressToken(kPrimary, ip4_, previous_tokens);
+
+  EXPECT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4or6, ip4_));
+  ASSERT_EQ(HANDSHAKE_OK,
+            ValidateSourceAddressTokens(kPrimary, token4or6, ip6_));
+}
+
+class CryptoServerConfigsTest : public QuicTest {
+ public:
+  CryptoServerConfigsTest()
+      : rand_(QuicRandom::GetInstance()),
+        config_(QuicCryptoServerConfig::TESTING,
+                rand_,
+                crypto_test_utils::ProofSourceForTesting(),
+                KeyExchangeSource::Default()),
+        test_peer_(&config_) {}
+
+  void SetUp() override {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
+  }
+
+  // SetConfigs constructs suitable config protobufs and calls SetConfigs on
+  // |config_|.
+  // Each struct in the input vector contains 3 elements.
+  // The first is the server config ID of a Config. The second is
+  // the |primary_time| of that Config, given in epoch seconds. (Although note
+  // that, in these tests, time is set to 1000 seconds since the epoch.).
+  // The third is the priority.
+  //
+  // For example:
+  //   SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());  // calls
+  //   |config_.SetConfigs| with no protobufs.
+  //
+  //   // Calls |config_.SetConfigs| with two protobufs: one for a Config with
+  //   // a |primary_time| of 900 and priority 1, and another with
+  //   // a |primary_time| of 1000 and priority 2.
+
+  //   CheckConfigs(
+  //     {{"id1", 900,  1},
+  //      {"id2", 1000, 2}});
+  //
+  // If the server config id starts with "INVALID" then the generated protobuf
+  // will be invalid.
+  struct ServerConfigIDWithTimeAndPriority {
+    ServerConfigID server_config_id;
+    int primary_time;
+    int priority;
+  };
+  void SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority> configs) {
+    const char kOrbit[] = "12345678";
+
+    bool has_invalid = false;
+
+    std::vector<QuicServerConfigProtobuf> protobufs;
+    for (const auto& config : configs) {
+      const ServerConfigID& server_config_id = config.server_config_id;
+      const int primary_time = config.primary_time;
+      const int priority = config.priority;
+
+      QuicCryptoServerConfig::ConfigOptions options;
+      options.id = server_config_id;
+      options.orbit = kOrbit;
+      QuicServerConfigProtobuf protobuf =
+          QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options);
+      protobuf.set_primary_time(primary_time);
+      protobuf.set_priority(priority);
+      if (absl::StartsWith(std::string(server_config_id), "INVALID")) {
+        protobuf.clear_key();
+        has_invalid = true;
+      }
+      protobufs.push_back(std::move(protobuf));
+    }
+
+    ASSERT_EQ(!has_invalid && !configs.empty(),
+              config_.SetConfigs(protobufs, /* fallback_protobuf = */ nullptr,
+                                 clock_.WallNow()));
+  }
+
+ protected:
+  QuicRandom* const rand_;
+  MockClock clock_;
+  QuicCryptoServerConfig config_;
+  QuicCryptoServerConfigPeer test_peer_;
+};
+
+TEST_F(CryptoServerConfigsTest, NoConfigs) {
+  test_peer_.CheckConfigs(std::vector<std::pair<std::string, bool>>());
+}
+
+TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
+  // Make sure that "b" is primary even though "a" comes first.
+  SetConfigs({{"a", 1100, 1}, {"b", 900, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
+  // Make sure that a remains primary after b is added.
+  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, Delete) {
+  // Ensure that configs get deleted when removed.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+  SetConfigs({{"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"b", true}, {"c", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, DeletePrimary) {
+  // Ensure that deleting the primary config works.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+  SetConfigs({{"a", 800, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", true}, {"c", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
+  // Ensure that configs get deleted when removed.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+  SetConfigs(std::vector<ServerConfigIDWithTimeAndPriority>());
+  // Config change is rejected, still using old configs.
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
+  // Check that updates to primary time get picked up.
+  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
+  test_peer_.SelectNewPrimaryConfig(500);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+  SetConfigs({{"a", 1200, 1}, {"b", 800, 1}, {"c", 400, 1}});
+  test_peer_.SelectNewPrimaryConfig(500);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
+  // Check that the most recent config is selected.
+  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
+  test_peer_.SelectNewPrimaryConfig(1500);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
+  // Check that the first config is selected.
+  SetConfigs({{"a", 400, 1}, {"b", 800, 1}, {"c", 1200, 1}});
+  test_peer_.SelectNewPrimaryConfig(100);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+}
+
+TEST_F(CryptoServerConfigsTest, SortByPriority) {
+  // Check that priority is used to decide on a primary config when
+  // configs have the same primary time.
+  SetConfigs({{"a", 900, 1}, {"b", 900, 2}, {"c", 900, 3}});
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+  test_peer_.SelectNewPrimaryConfig(800);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}, {"c", false}});
+
+  // Change priorities and expect sort order to change.
+  SetConfigs({{"a", 900, 2}, {"b", 900, 1}, {"c", 900, 0}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+  test_peer_.SelectNewPrimaryConfig(800);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", false}, {"b", false}, {"c", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
+  // Check that a new primary config is enabled at the right time.
+  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
+  test_peer_.SelectNewPrimaryConfig(1101);
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+class ValidateCallback : public ValidateClientHelloResultCallback {
+ public:
+  void Run(quiche::QuicheReferenceCountedPointer<Result> /*result*/,
+           std::unique_ptr<ProofSource::Details> /*details*/) override {}
+};
+
+TEST_F(CryptoServerConfigsTest, AdvancePrimaryViaValidate) {
+  // Check that a new primary config is enabled at the right time.
+  SetConfigs({{"a", 900, 1}, {"b", 1100, 1}});
+  test_peer_.SelectNewPrimaryConfig(1000);
+  test_peer_.CheckConfigs({{"a", true}, {"b", false}});
+  CryptoHandshakeMessage client_hello;
+  QuicSocketAddress client_address;
+  QuicSocketAddress server_address;
+  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      transport_version = version.transport_version;
+      break;
+    }
+  }
+  ASSERT_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
+  MockClock clock;
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config(
+      new QuicSignedServerConfig);
+  std::unique_ptr<ValidateClientHelloResultCallback> done_cb(
+      new ValidateCallback);
+  clock.AdvanceTime(QuicTime::Delta::FromSeconds(1100));
+  config_.ValidateClientHello(client_hello, client_address, server_address,
+                              transport_version, &clock, signed_config,
+                              std::move(done_cb));
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}});
+}
+
+TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
+  // Ensure that invalid configs don't change anything.
+  SetConfigs({{"a", 800, 1}, {"b", 900, 1}, {"c", 1100, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+  SetConfigs({{"a", 800, 1}, {"c", 1100, 1}, {"INVALID1", 1000, 1}});
+  test_peer_.CheckConfigs({{"a", false}, {"b", true}, {"c", false}});
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_decrypter.cc b/quiche/quic/core/crypto/quic_decrypter.cc
new file mode 100644
index 0000000..f91a786
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_decrypter.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
+#include "quiche/quic/core/crypto/aes_256_gcm_decrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_decrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// static
+std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(
+    const ParsedQuicVersion& version,
+    QuicTag algorithm) {
+  switch (algorithm) {
+    case kAESG:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<Aes128GcmDecrypter>();
+      } else {
+        return std::make_unique<Aes128Gcm12Decrypter>();
+      }
+    case kCC20:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
+      } else {
+        return std::make_unique<ChaCha20Poly1305Decrypter>();
+      }
+    default:
+      QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
+      return nullptr;
+  }
+}
+
+// static
+std::unique_ptr<QuicDecrypter> QuicDecrypter::CreateFromCipherSuite(
+    uint32_t cipher_suite) {
+  switch (cipher_suite) {
+    case TLS1_CK_AES_128_GCM_SHA256:
+      return std::make_unique<Aes128GcmDecrypter>();
+    case TLS1_CK_AES_256_GCM_SHA384:
+      return std::make_unique<Aes256GcmDecrypter>();
+    case TLS1_CK_CHACHA20_POLY1305_SHA256:
+      return std::make_unique<ChaCha20Poly1305TlsDecrypter>();
+    default:
+      QUIC_BUG(quic_bug_10660_1) << "TLS cipher suite is unknown to QUIC";
+      return nullptr;
+  }
+}
+
+// static
+void QuicDecrypter::DiversifyPreliminaryKey(absl::string_view preliminary_key,
+                                            absl::string_view nonce_prefix,
+                                            const DiversificationNonce& nonce,
+                                            size_t key_size,
+                                            size_t nonce_prefix_size,
+                                            std::string* out_key,
+                                            std::string* out_nonce_prefix) {
+  QuicHKDF hkdf((std::string(preliminary_key)) + (std::string(nonce_prefix)),
+                absl::string_view(nonce.data(), nonce.size()),
+                "QUIC key diversification", 0, key_size, 0, nonce_prefix_size,
+                0);
+  *out_key = std::string(hkdf.server_write_key());
+  *out_nonce_prefix = std::string(hkdf.server_write_iv());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_decrypter.h b/quiche/quic/core/crypto/quic_decrypter.h
new file mode 100644
index 0000000..2cd799c
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_decrypter.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicDecrypter : public QuicCrypter {
+ public:
+  virtual ~QuicDecrypter() {}
+
+  static std::unique_ptr<QuicDecrypter> Create(const ParsedQuicVersion& version,
+                                               QuicTag algorithm);
+
+  // Creates an IETF QuicDecrypter based on |cipher_suite| which must be an id
+  // returned by SSL_CIPHER_get_id. The caller is responsible for taking
+  // ownership of the new QuicDecrypter.
+  static std::unique_ptr<QuicDecrypter> CreateFromCipherSuite(
+      uint32_t cipher_suite);
+
+  // Sets the encryption key. Returns true on success, false on failure.
+  // |DecryptPacket| may not be called until |SetDiversificationNonce| is
+  // called and the preliminary keying material will be combined with that
+  // nonce in order to create the actual key and nonce-prefix.
+  //
+  // If this function is called, neither |SetKey| nor |SetNoncePrefix| may be
+  // called.
+  virtual bool SetPreliminaryKey(absl::string_view key) = 0;
+
+  // SetDiversificationNonce uses |nonce| to derive final keys based on the
+  // input keying material given by calling |SetPreliminaryKey|.
+  //
+  // Calling this function is a no-op if |SetPreliminaryKey| hasn't been
+  // called.
+  virtual bool SetDiversificationNonce(const DiversificationNonce& nonce) = 0;
+
+  // Populates |output| with the decrypted |ciphertext| and populates
+  // |output_length| with the length.  Returns 0 if there is an error.
+  // |output| size is specified by |max_output_length| and must be
+  // at least as large as the ciphertext.  |packet_number| is
+  // appended to the |nonce_prefix| value provided in SetNoncePrefix()
+  // to form the nonce.
+  // TODO(wtc): add a way for DecryptPacket to report decryption failure due
+  // to non-authentic inputs, as opposed to other reasons for failure.
+  virtual bool DecryptPacket(uint64_t packet_number,
+                             absl::string_view associated_data,
+                             absl::string_view ciphertext,
+                             char* output,
+                             size_t* output_length,
+                             size_t max_output_length) = 0;
+
+  // Reads a sample of ciphertext from |sample_reader| and uses the header
+  // protection key to generate a mask to use for header protection. If
+  // successful, this function returns this mask, which is at least 5 bytes
+  // long. Callers can detect failure by checking if the output string is empty.
+  virtual std::string GenerateHeaderProtectionMask(
+      QuicDataReader* sample_reader) = 0;
+
+  // The ID of the cipher. Return 0x03000000 ORed with the 'cryptographic suite
+  // selector'.
+  virtual uint32_t cipher_id() const = 0;
+
+  // Returns the maximum number of packets that can safely fail decryption with
+  // this decrypter.
+  virtual QuicPacketCount GetIntegrityLimit() const = 0;
+
+  // For use by unit tests only.
+  virtual absl::string_view GetKey() const = 0;
+  virtual absl::string_view GetNoncePrefix() const = 0;
+
+  static void DiversifyPreliminaryKey(absl::string_view preliminary_key,
+                                      absl::string_view nonce_prefix,
+                                      const DiversificationNonce& nonce,
+                                      size_t key_size,
+                                      size_t nonce_prefix_size,
+                                      std::string* out_key,
+                                      std::string* out_nonce_prefix);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_DECRYPTER_H_
diff --git a/quiche/quic/core/crypto/quic_encrypter.cc b/quiche/quic/core/crypto/quic_encrypter.cc
new file mode 100644
index 0000000..4ae5232
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_encrypter.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+
+#include <utility>
+
+#include "third_party/boringssl/src/include/openssl/tls1.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
+#include "quiche/quic/core/crypto/aes_256_gcm_encrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// static
+std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(
+    const ParsedQuicVersion& version,
+    QuicTag algorithm) {
+  switch (algorithm) {
+    case kAESG:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<Aes128GcmEncrypter>();
+      } else {
+        return std::make_unique<Aes128Gcm12Encrypter>();
+      }
+    case kCC20:
+      if (version.UsesInitialObfuscators()) {
+        return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
+      } else {
+        return std::make_unique<ChaCha20Poly1305Encrypter>();
+      }
+    default:
+      QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
+      return nullptr;
+  }
+}
+
+// static
+std::unique_ptr<QuicEncrypter> QuicEncrypter::CreateFromCipherSuite(
+    uint32_t cipher_suite) {
+  switch (cipher_suite) {
+    case TLS1_CK_AES_128_GCM_SHA256:
+      return std::make_unique<Aes128GcmEncrypter>();
+    case TLS1_CK_AES_256_GCM_SHA384:
+      return std::make_unique<Aes256GcmEncrypter>();
+    case TLS1_CK_CHACHA20_POLY1305_SHA256:
+      return std::make_unique<ChaCha20Poly1305TlsEncrypter>();
+    default:
+      QUIC_BUG(quic_bug_10711_1) << "TLS cipher suite is unknown to QUIC";
+      return nullptr;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_encrypter.h b/quiche/quic/core/crypto/quic_encrypter.h
new file mode 100644
index 0000000..6caf51b
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_encrypter.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_crypter.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicEncrypter : public QuicCrypter {
+ public:
+  virtual ~QuicEncrypter() {}
+
+  static std::unique_ptr<QuicEncrypter> Create(const ParsedQuicVersion& version,
+                                               QuicTag algorithm);
+
+  // Creates an IETF QuicEncrypter based on |cipher_suite| which must be an id
+  // returned by SSL_CIPHER_get_id. The caller is responsible for taking
+  // ownership of the new QuicEncrypter.
+  static std::unique_ptr<QuicEncrypter> CreateFromCipherSuite(
+      uint32_t cipher_suite);
+
+  // Writes encrypted |plaintext| and a MAC over |plaintext| and
+  // |associated_data| into output. Sets |output_length| to the number of
+  // bytes written. Returns true on success or false if there was an error.
+  // |packet_number| is appended to the |nonce_prefix| value provided in
+  // SetNoncePrefix() to form the nonce. |output| must not overlap with
+  // |associated_data|. If |output| overlaps with |plaintext| then
+  // |plaintext| must be <= |output|.
+  virtual bool EncryptPacket(uint64_t packet_number,
+                             absl::string_view associated_data,
+                             absl::string_view plaintext,
+                             char* output,
+                             size_t* output_length,
+                             size_t max_output_length) = 0;
+
+  // Takes a |sample| of ciphertext and uses the header protection key to
+  // generate a mask to use for header protection, and returns that mask. On
+  // success, the mask will be at least 5 bytes long; on failure the string will
+  // be empty.
+  virtual std::string GenerateHeaderProtectionMask(
+      absl::string_view sample) = 0;
+
+  // Returns the maximum length of plaintext that can be encrypted
+  // to ciphertext no larger than |ciphertext_size|.
+  virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const = 0;
+
+  // Returns the length of the ciphertext that would be generated by encrypting
+  // to plaintext of size |plaintext_size|.
+  virtual size_t GetCiphertextSize(size_t plaintext_size) const = 0;
+
+  // Returns the maximum number of packets that can be safely encrypted with
+  // this encrypter.
+  virtual QuicPacketCount GetConfidentialityLimit() const = 0;
+
+  // For use by unit tests only.
+  virtual absl::string_view GetKey() const = 0;
+  virtual absl::string_view GetNoncePrefix() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
diff --git a/quiche/quic/core/crypto/quic_hkdf.cc b/quiche/quic/core/crypto/quic_hkdf.cc
new file mode 100644
index 0000000..2ad00f2
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_hkdf.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/hkdf.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+const size_t kSHA256HashLength = 32;
+const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256;
+
+QuicHKDF::QuicHKDF(absl::string_view secret,
+                   absl::string_view salt,
+                   absl::string_view info,
+                   size_t key_bytes_to_generate,
+                   size_t iv_bytes_to_generate,
+                   size_t subkey_secret_bytes_to_generate)
+    : QuicHKDF(secret,
+               salt,
+               info,
+               key_bytes_to_generate,
+               key_bytes_to_generate,
+               iv_bytes_to_generate,
+               iv_bytes_to_generate,
+               subkey_secret_bytes_to_generate) {}
+
+QuicHKDF::QuicHKDF(absl::string_view secret,
+                   absl::string_view salt,
+                   absl::string_view info,
+                   size_t client_key_bytes_to_generate,
+                   size_t server_key_bytes_to_generate,
+                   size_t client_iv_bytes_to_generate,
+                   size_t server_iv_bytes_to_generate,
+                   size_t subkey_secret_bytes_to_generate) {
+  const size_t material_length =
+      2 * client_key_bytes_to_generate + client_iv_bytes_to_generate +
+      2 * server_key_bytes_to_generate + server_iv_bytes_to_generate +
+      subkey_secret_bytes_to_generate;
+  QUICHE_DCHECK_LT(material_length, kMaxKeyMaterialSize);
+
+  output_.resize(material_length);
+  // On Windows, when the size of output_ is zero, dereference of 0'th element
+  // results in a crash. C++11 solves this problem by adding a data() getter
+  // method to std::vector.
+  if (output_.empty()) {
+    return;
+  }
+
+  ::HKDF(&output_[0], output_.size(), ::EVP_sha256(),
+         reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
+         reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
+         reinterpret_cast<const uint8_t*>(info.data()), info.size());
+
+  size_t j = 0;
+  if (client_key_bytes_to_generate) {
+    client_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                          client_key_bytes_to_generate);
+    j += client_key_bytes_to_generate;
+  }
+
+  if (server_key_bytes_to_generate) {
+    server_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                          server_key_bytes_to_generate);
+    j += server_key_bytes_to_generate;
+  }
+
+  if (client_iv_bytes_to_generate) {
+    client_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                         client_iv_bytes_to_generate);
+    j += client_iv_bytes_to_generate;
+  }
+
+  if (server_iv_bytes_to_generate) {
+    server_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                         server_iv_bytes_to_generate);
+    j += server_iv_bytes_to_generate;
+  }
+
+  if (subkey_secret_bytes_to_generate) {
+    subkey_secret_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                       subkey_secret_bytes_to_generate);
+    j += subkey_secret_bytes_to_generate;
+  }
+  // Repeat client and server key bytes for header protection keys.
+  if (client_key_bytes_to_generate) {
+    client_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                       client_key_bytes_to_generate);
+    j += client_key_bytes_to_generate;
+  }
+
+  if (server_key_bytes_to_generate) {
+    server_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
+                                       server_key_bytes_to_generate);
+    j += server_key_bytes_to_generate;
+  }
+}
+
+QuicHKDF::~QuicHKDF() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_hkdf.h b/quiche/quic/core/crypto/quic_hkdf.h
new file mode 100644
index 0000000..0040447
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_hkdf.h
@@ -0,0 +1,76 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicHKDF implements the key derivation function specified in RFC 5869
+// (using SHA-256) and outputs key material, as needed by QUIC.
+// See https://tools.ietf.org/html/rfc5869 for details.
+class QUIC_EXPORT_PRIVATE QuicHKDF {
+ public:
+  // |secret|: the input shared secret (or, from RFC 5869, the IKM).
+  // |salt|: an (optional) public salt / non-secret random value. While
+  // optional, callers are strongly recommended to provide a salt. There is no
+  // added security value in making this larger than the SHA-256 block size of
+  // 64 bytes.
+  // |info|: an (optional) label to distinguish different uses of HKDF. It is
+  // optional context and application specific information (can be a zero-length
+  // string).
+  // |key_bytes_to_generate|: the number of bytes of key material to generate
+  // for both client and server.
+  // |iv_bytes_to_generate|: the number of bytes of IV to generate for both
+  // client and server.
+  // |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to
+  // generate, shared between client and server.
+  QuicHKDF(absl::string_view secret,
+           absl::string_view salt,
+           absl::string_view info,
+           size_t key_bytes_to_generate,
+           size_t iv_bytes_to_generate,
+           size_t subkey_secret_bytes_to_generate);
+
+  // An alternative constructor that allows the client and server key/IV
+  // lengths to be different.
+  QuicHKDF(absl::string_view secret,
+           absl::string_view salt,
+           absl::string_view info,
+           size_t client_key_bytes_to_generate,
+           size_t server_key_bytes_to_generate,
+           size_t client_iv_bytes_to_generate,
+           size_t server_iv_bytes_to_generate,
+           size_t subkey_secret_bytes_to_generate);
+
+  ~QuicHKDF();
+
+  absl::string_view client_write_key() const { return client_write_key_; }
+  absl::string_view client_write_iv() const { return client_write_iv_; }
+  absl::string_view server_write_key() const { return server_write_key_; }
+  absl::string_view server_write_iv() const { return server_write_iv_; }
+  absl::string_view subkey_secret() const { return subkey_secret_; }
+  absl::string_view client_hp_key() const { return client_hp_key_; }
+  absl::string_view server_hp_key() const { return server_hp_key_; }
+
+ private:
+  std::vector<uint8_t> output_;
+
+  absl::string_view client_write_key_;
+  absl::string_view server_write_key_;
+  absl::string_view client_write_iv_;
+  absl::string_view server_write_iv_;
+  absl::string_view subkey_secret_;
+  absl::string_view client_hp_key_;
+  absl::string_view server_hp_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_HKDF_H_
diff --git a/quiche/quic/core/crypto/quic_hkdf_test.cc b/quiche/quic/core/crypto/quic_hkdf_test.cc
new file mode 100644
index 0000000..48f041f
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_hkdf_test.cc
@@ -0,0 +1,91 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_hkdf.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct HKDFInput {
+  const char* key_hex;
+  const char* salt_hex;
+  const char* info_hex;
+  const char* output_hex;
+};
+
+// These test cases are taken from
+// https://tools.ietf.org/html/rfc5869#appendix-A.
+static const HKDFInput kHKDFInputs[] = {
+    {
+        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+        "000102030405060708090a0b0c",
+        "f0f1f2f3f4f5f6f7f8f9",
+        "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf340072"
+        "08d5"
+        "b887185865",
+    },
+    {
+        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122"
+        "2324"
+        "25262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647"
+        "4849"
+        "4a4b4c4d4e4f",
+        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182"
+        "8384"
+        "85868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7"
+        "a8a9"
+        "aaabacadaeaf",
+        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2"
+        "d3d4"
+        "d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7"
+        "f8f9"
+        "fafbfcfdfeff",
+        "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a"
+        "99ca"
+        "c7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87"
+        "c14c"
+        "01d5c1f3434f1d87",
+    },
+    {
+        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+        "",
+        "",
+        "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d2013"
+        "95fa"
+        "a4b61a96c8",
+    },
+};
+
+class QuicHKDFTest : public QuicTest {};
+
+TEST_F(QuicHKDFTest, HKDF) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kHKDFInputs); i++) {
+    const HKDFInput& test(kHKDFInputs[i]);
+    SCOPED_TRACE(i);
+
+    const std::string key = absl::HexStringToBytes(test.key_hex);
+    const std::string salt = absl::HexStringToBytes(test.salt_hex);
+    const std::string info = absl::HexStringToBytes(test.info_hex);
+    const std::string expected = absl::HexStringToBytes(test.output_hex);
+
+    // We set the key_length to the length of the expected output and then take
+    // the result from the first key, which is the client write key.
+    QuicHKDF hkdf(key, salt, info, expected.size(), 0, 0);
+
+    ASSERT_EQ(expected.size(), hkdf.client_write_key().size());
+    EXPECT_EQ(0, memcmp(expected.data(), hkdf.client_write_key().data(),
+                        expected.size()));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_random.cc b/quiche/quic/core/crypto/quic_random.cc
new file mode 100644
index 0000000..22eed48
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_random.cc
@@ -0,0 +1,100 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include <cstdint>
+#include <cstring>
+
+#include "third_party/boringssl/src/include/openssl/rand.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Insecure randomness in DefaultRandom uses an implementation of
+// xoshiro256++ 1.0 based on code in the public domain from
+// <http://prng.di.unimi.it/xoshiro256plusplus.c>.
+
+inline uint64_t Xoshiro256InitializeRngStateMember() {
+  uint64_t result;
+  RAND_bytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
+  return result;
+}
+
+inline uint64_t Xoshiro256PlusPlusRotLeft(uint64_t x, int k) {
+  return (x << k) | (x >> (64 - k));
+}
+
+uint64_t Xoshiro256PlusPlus() {
+  static thread_local uint64_t rng_state[4] = {
+      Xoshiro256InitializeRngStateMember(),
+      Xoshiro256InitializeRngStateMember(),
+      Xoshiro256InitializeRngStateMember(),
+      Xoshiro256InitializeRngStateMember()};
+  const uint64_t result =
+      Xoshiro256PlusPlusRotLeft(rng_state[0] + rng_state[3], 23) + rng_state[0];
+  const uint64_t t = rng_state[1] << 17;
+  rng_state[2] ^= rng_state[0];
+  rng_state[3] ^= rng_state[1];
+  rng_state[1] ^= rng_state[2];
+  rng_state[0] ^= rng_state[3];
+  rng_state[2] ^= t;
+  rng_state[3] = Xoshiro256PlusPlusRotLeft(rng_state[3], 45);
+  return result;
+}
+
+class DefaultRandom : public QuicRandom {
+ public:
+  DefaultRandom() {}
+  DefaultRandom(const DefaultRandom&) = delete;
+  DefaultRandom& operator=(const DefaultRandom&) = delete;
+  ~DefaultRandom() override {}
+
+  // QuicRandom implementation
+  void RandBytes(void* data, size_t len) override;
+  uint64_t RandUint64() override;
+  void InsecureRandBytes(void* data, size_t len) override;
+  uint64_t InsecureRandUint64() override;
+};
+
+void DefaultRandom::RandBytes(void* data, size_t len) {
+  RAND_bytes(reinterpret_cast<uint8_t*>(data), len);
+}
+
+uint64_t DefaultRandom::RandUint64() {
+  uint64_t value;
+  RandBytes(&value, sizeof(value));
+  return value;
+}
+
+void DefaultRandom::InsecureRandBytes(void* data, size_t len) {
+  while (len >= sizeof(uint64_t)) {
+    uint64_t random_bytes64 = Xoshiro256PlusPlus();
+    memcpy(data, &random_bytes64, sizeof(uint64_t));
+    data = reinterpret_cast<char*>(data) + sizeof(uint64_t);
+    len -= sizeof(uint64_t);
+  }
+  if (len > 0) {
+    QUICHE_DCHECK_LT(len, sizeof(uint64_t));
+    uint64_t random_bytes64 = Xoshiro256PlusPlus();
+    memcpy(data, &random_bytes64, len);
+  }
+}
+
+uint64_t DefaultRandom::InsecureRandUint64() {
+  return Xoshiro256PlusPlus();
+}
+
+}  // namespace
+
+// static
+QuicRandom* QuicRandom::GetInstance() {
+  static DefaultRandom* random = new DefaultRandom();
+  return random;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/quic_random.h b/quiche/quic/core/crypto/quic_random.h
new file mode 100644
index 0000000..47722cb
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_random.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
+#define QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The interface for a random number generator.
+class QUIC_EXPORT_PRIVATE QuicRandom {
+ public:
+  virtual ~QuicRandom() {}
+
+  // Returns the default random number generator, which is cryptographically
+  // secure and thread-safe.
+  static QuicRandom* GetInstance();
+
+  // Generates |len| random bytes in the |data| buffer.
+  virtual void RandBytes(void* data, size_t len) = 0;
+
+  // Returns a random number in the range [0, kuint64max].
+  virtual uint64_t RandUint64() = 0;
+
+  // Generates |len| random bytes in the |data| buffer. This MUST NOT be used
+  // for any application that requires cryptographically-secure randomness.
+  virtual void InsecureRandBytes(void* data, size_t len) = 0;
+
+  // Returns a random number in the range [0, kuint64max]. This MUST NOT be used
+  // for any application that requires cryptographically-secure randomness.
+  virtual uint64_t InsecureRandUint64() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_RANDOM_H_
diff --git a/quiche/quic/core/crypto/quic_random_test.cc b/quiche/quic/core/crypto/quic_random_test.cc
new file mode 100644
index 0000000..2a43c29
--- /dev/null
+++ b/quiche/quic/core/crypto/quic_random_test.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/quic_random.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicRandomTest : public QuicTest {};
+
+TEST_F(QuicRandomTest, RandBytes) {
+  unsigned char buf1[16];
+  unsigned char buf2[16];
+  memset(buf1, 0xaf, sizeof(buf1));
+  memset(buf2, 0xaf, sizeof(buf2));
+  ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
+
+  QuicRandom* rng = QuicRandom::GetInstance();
+  rng->RandBytes(buf1, sizeof(buf1));
+  EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
+}
+
+TEST_F(QuicRandomTest, RandUint64) {
+  QuicRandom* rng = QuicRandom::GetInstance();
+  uint64_t value1 = rng->RandUint64();
+  uint64_t value2 = rng->RandUint64();
+  EXPECT_NE(value1, value2);
+}
+
+TEST_F(QuicRandomTest, InsecureRandBytes) {
+  unsigned char buf1[16];
+  unsigned char buf2[16];
+  memset(buf1, 0xaf, sizeof(buf1));
+  memset(buf2, 0xaf, sizeof(buf2));
+  ASSERT_EQ(0, memcmp(buf1, buf2, sizeof(buf1)));
+
+  QuicRandom* rng = QuicRandom::GetInstance();
+  rng->InsecureRandBytes(buf1, sizeof(buf1));
+  EXPECT_NE(0, memcmp(buf1, buf2, sizeof(buf1)));
+}
+
+TEST_F(QuicRandomTest, InsecureRandUint64) {
+  QuicRandom* rng = QuicRandom::GetInstance();
+  uint64_t value1 = rng->InsecureRandUint64();
+  uint64_t value2 = rng->InsecureRandUint64();
+  EXPECT_NE(value1, value2);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_client_connection.cc b/quiche/quic/core/crypto/tls_client_connection.cc
new file mode 100644
index 0000000..9140527
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_client_connection.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/tls_client_connection.h"
+
+namespace quic {
+
+TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx,
+                                         Delegate* delegate,
+                                         QuicSSLConfig ssl_config)
+    : TlsConnection(ssl_ctx,
+                    delegate->ConnectionDelegate(),
+                    std::move(ssl_config)),
+      delegate_(delegate) {}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx(
+    bool enable_early_data) {
+  bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
+  // Configure certificate verification.
+  SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback);
+  int reverify_on_resume_enabled = 1;
+  SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled);
+
+  // Configure session caching.
+  SSL_CTX_set_session_cache_mode(
+      ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
+  SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+
+  // TODO(wub): Always enable early data on the SSL_CTX, but allow it to be
+  // overridden on the SSL object, via QuicSSLConfig.
+  SSL_CTX_set_early_data_enabled(ssl_ctx.get(), enable_early_data);
+  return ssl_ctx;
+}
+
+void TlsClientConnection::SetCertChain(
+    const std::vector<CRYPTO_BUFFER*>& cert_chain, EVP_PKEY* privkey) {
+  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), privkey,
+                        /*privkey_method=*/nullptr);
+}
+
+// static
+int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
+  static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl))
+      ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session));
+  return 1;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_client_connection.h b/quiche/quic/core/crypto/tls_client_connection.h
new file mode 100644
index 0000000..1c98a70
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_client_connection.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
+
+#include "quiche/quic/core/crypto/tls_connection.h"
+
+namespace quic {
+
+// TlsClientConnection receives calls for client-specific BoringSSL callbacks
+// and calls its Delegate for the implementation of those callbacks.
+class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection {
+ public:
+  // A TlsClientConnection::Delegate implements the client-specific methods that
+  // are set as callbacks for an SSL object.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+   protected:
+    // Called when a NewSessionTicket is received from the server.
+    virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0;
+
+    // Provides the delegate for callbacks that are shared between client and
+    // server.
+    virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
+
+    friend class TlsClientConnection;
+  };
+
+  TlsClientConnection(SSL_CTX* ssl_ctx,
+                      Delegate* delegate,
+                      QuicSSLConfig ssl_config);
+
+  // Creates and configures an SSL_CTX that is appropriate for clients to use.
+  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data);
+
+  // Set the client cert and private key to be used on this connection, if
+  // requested by the server.
+  void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain,
+                    EVP_PKEY* privkey);
+
+ private:
+  // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls
+  // Delegate::InsertSession.
+  static int NewSessionCallback(SSL* ssl, SSL_SESSION* session);
+
+  Delegate* delegate_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CLIENT_CONNECTION_H_
diff --git a/quiche/quic/core/crypto/tls_connection.cc b/quiche/quic/core/crypto/tls_connection.cc
new file mode 100644
index 0000000..d1be900
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_connection.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/tls_connection.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+
+// BoringSSL allows storing extra data off of some of its data structures,
+// including the SSL struct. To allow for multiple callers to store data, each
+// caller can use a different index for setting and getting data. These indices
+// are globals handed out by calling SSL_get_ex_new_index.
+//
+// SslIndexSingleton calls SSL_get_ex_new_index on its construction, and then
+// provides this index to be used in calls to SSL_get_ex_data/SSL_set_ex_data.
+// This is used to store in the SSL struct a pointer to the TlsConnection which
+// owns it.
+class SslIndexSingleton {
+ public:
+  static SslIndexSingleton* GetInstance() {
+    static SslIndexSingleton* instance = new SslIndexSingleton();
+    return instance;
+  }
+
+  int ssl_ex_data_index_connection() const {
+    return ssl_ex_data_index_connection_;
+  }
+
+ private:
+  SslIndexSingleton() {
+    CRYPTO_library_init();
+    ssl_ex_data_index_connection_ =
+        SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
+    QUICHE_CHECK_LE(0, ssl_ex_data_index_connection_);
+  }
+
+  SslIndexSingleton(const SslIndexSingleton&) = delete;
+  SslIndexSingleton& operator=(const SslIndexSingleton&) = delete;
+
+  // The index to supply to SSL_get_ex_data/SSL_set_ex_data for getting/setting
+  // the TlsConnection pointer.
+  int ssl_ex_data_index_connection_;
+};
+
+}  // namespace
+
+// static
+EncryptionLevel TlsConnection::QuicEncryptionLevel(
+    enum ssl_encryption_level_t level) {
+  switch (level) {
+    case ssl_encryption_initial:
+      return ENCRYPTION_INITIAL;
+    case ssl_encryption_early_data:
+      return ENCRYPTION_ZERO_RTT;
+    case ssl_encryption_handshake:
+      return ENCRYPTION_HANDSHAKE;
+    case ssl_encryption_application:
+      return ENCRYPTION_FORWARD_SECURE;
+    default:
+      QUIC_BUG(quic_bug_10698_1)
+          << "Invalid ssl_encryption_level_t " << static_cast<int>(level);
+      return ENCRYPTION_INITIAL;
+  }
+}
+
+// static
+enum ssl_encryption_level_t TlsConnection::BoringEncryptionLevel(
+    EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return ssl_encryption_initial;
+    case ENCRYPTION_HANDSHAKE:
+      return ssl_encryption_handshake;
+    case ENCRYPTION_ZERO_RTT:
+      return ssl_encryption_early_data;
+    case ENCRYPTION_FORWARD_SECURE:
+      return ssl_encryption_application;
+    default:
+      QUIC_BUG(quic_bug_10698_2)
+          << "Invalid encryption level " << static_cast<int>(level);
+      return ssl_encryption_initial;
+  }
+}
+
+TlsConnection::TlsConnection(SSL_CTX* ssl_ctx,
+                             TlsConnection::Delegate* delegate,
+                             QuicSSLConfig ssl_config)
+    : delegate_(delegate),
+      ssl_(SSL_new(ssl_ctx)),
+      ssl_config_(std::move(ssl_config)) {
+  SSL_set_ex_data(
+      ssl(), SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection(),
+      this);
+  if (ssl_config_.early_data_enabled.has_value()) {
+    const int early_data_enabled = *ssl_config_.early_data_enabled ? 1 : 0;
+    SSL_set_early_data_enabled(ssl(), early_data_enabled);
+  }
+  if (ssl_config_.signing_algorithm_prefs.has_value()) {
+    SSL_set_signing_algorithm_prefs(
+        ssl(), ssl_config_.signing_algorithm_prefs->data(),
+        ssl_config_.signing_algorithm_prefs->size());
+  }
+  if (ssl_config_.disable_ticket_support.has_value()) {
+    if (*ssl_config_.disable_ticket_support) {
+      SSL_set_options(ssl(), SSL_OP_NO_TICKET);
+    }
+  }
+}
+
+void TlsConnection::EnableInfoCallback() {
+  SSL_set_info_callback(
+      ssl(), +[](const SSL* ssl, int type, int value) {
+        ConnectionFromSsl(ssl)->delegate_->InfoCallback(type, value);
+      });
+}
+
+void TlsConnection::DisableTicketSupport() {
+  ssl_config_.disable_ticket_support = true;
+  SSL_set_options(ssl(), SSL_OP_NO_TICKET);
+}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() {
+  CRYPTO_library_init();
+  bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
+  SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
+  SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
+  SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod);
+  return ssl_ctx;
+}
+
+// static
+TlsConnection* TlsConnection::ConnectionFromSsl(const SSL* ssl) {
+  return reinterpret_cast<TlsConnection*>(SSL_get_ex_data(
+      ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection()));
+}
+
+// static
+enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl,
+                                                       uint8_t* out_alert) {
+  return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert);
+}
+
+const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{
+    TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback,
+    TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback,
+    TlsConnection::SendAlertCallback};
+
+// static
+int TlsConnection::SetReadSecretCallback(SSL* ssl,
+                                         enum ssl_encryption_level_t level,
+                                         const SSL_CIPHER* cipher,
+                                         const uint8_t* secret,
+                                         size_t secret_length) {
+  // TODO(nharper): replace this vector with a span (which unfortunately doesn't
+  // yet exist in quic/platform/api).
+  std::vector<uint8_t> secret_vec(secret, secret + secret_length);
+  TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
+  if (!delegate->SetReadSecret(QuicEncryptionLevel(level), cipher,
+                               secret_vec)) {
+    return 0;
+  }
+  return 1;
+}
+
+// static
+int TlsConnection::SetWriteSecretCallback(SSL* ssl,
+                                          enum ssl_encryption_level_t level,
+                                          const SSL_CIPHER* cipher,
+                                          const uint8_t* secret,
+                                          size_t secret_length) {
+  // TODO(nharper): replace this vector with a span (which unfortunately doesn't
+  // yet exist in quic/platform/api).
+  std::vector<uint8_t> secret_vec(secret, secret + secret_length);
+  TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
+  delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher, secret_vec);
+  return 1;
+}
+
+// static
+int TlsConnection::WriteMessageCallback(SSL* ssl,
+                                        enum ssl_encryption_level_t level,
+                                        const uint8_t* data,
+                                        size_t len) {
+  ConnectionFromSsl(ssl)->delegate_->WriteMessage(
+      QuicEncryptionLevel(level),
+      absl::string_view(reinterpret_cast<const char*>(data), len));
+  return 1;
+}
+
+// static
+int TlsConnection::FlushFlightCallback(SSL* ssl) {
+  ConnectionFromSsl(ssl)->delegate_->FlushFlight();
+  return 1;
+}
+
+// static
+int TlsConnection::SendAlertCallback(SSL* ssl,
+                                     enum ssl_encryption_level_t level,
+                                     uint8_t desc) {
+  ConnectionFromSsl(ssl)->delegate_->SendAlert(QuicEncryptionLevel(level),
+                                               desc);
+  return 1;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_connection.h b/quiche/quic/core/crypto/tls_connection.h
new file mode 100644
index 0000000..c7f7758
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_connection.h
@@ -0,0 +1,162 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// TlsConnection wraps BoringSSL's SSL object which represents a single TLS
+// connection. Callbacks set in BoringSSL which are called with an SSL* argument
+// will get dispatched to the TlsConnection object owning that SSL. In turn, the
+// TlsConnection will delegate the implementation of that callback to its
+// Delegate.
+//
+// The owner of the TlsConnection is responsible for driving the TLS handshake
+// (and other interactions with the SSL*). This class only handles mapping
+// callbacks to the correct instance.
+class QUIC_EXPORT_PRIVATE TlsConnection {
+ public:
+  // A TlsConnection::Delegate implements the methods that are set as callbacks
+  // of TlsConnection.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+   protected:
+    // Certificate management functions:
+
+    // Verifies the peer's certificate chain. It may use
+    // SSL_get0_peer_certificates to get the cert chain. This method returns
+    // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid,
+    // or ssl_verify_retry if verification is happening asynchronously.
+    virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0;
+
+    // QUIC-TLS interface functions:
+
+    // SetWriteSecret provides the encryption secret used to encrypt messages at
+    // encryption level |level|. The secret provided here is the one from the
+    // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
+    // traffic secrets and application traffic secrets. The provided write
+    // secret must be used with the provided cipher suite |cipher|.
+    virtual void SetWriteSecret(EncryptionLevel level,
+                                const SSL_CIPHER* cipher,
+                                const std::vector<uint8_t>& write_secret) = 0;
+
+    // SetReadSecret is similar to SetWriteSecret, except that it is used for
+    // decrypting messages. SetReadSecret at a particular level is always called
+    // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT,
+    // where the EncryptionLevel for SetWriteSecret is
+    // ENCRYPTION_FORWARD_SECURE.
+    virtual bool SetReadSecret(EncryptionLevel level,
+                               const SSL_CIPHER* cipher,
+                               const std::vector<uint8_t>& read_secret) = 0;
+
+    // WriteMessage is called when there is |data| from the TLS stack ready for
+    // the QUIC stack to write in a crypto frame. The data must be transmitted
+    // at encryption level |level|.
+    virtual void WriteMessage(EncryptionLevel level,
+                              absl::string_view data) = 0;
+
+    // FlushFlight is called to signal that the current flight of messages have
+    // all been written (via calls to WriteMessage) and can be flushed to the
+    // underlying transport.
+    virtual void FlushFlight() = 0;
+
+    // SendAlert causes this TlsConnection to close the QUIC connection with an
+    // error code corersponding to the TLS alert description |desc| sent at
+    // level |level|.
+    virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
+
+    // Informational callback from BoringSSL. This callback is disabled by
+    // default, but can be enabled by TlsConnection::EnableInfoCallback.
+    //
+    // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
+    virtual void InfoCallback(int type, int value) = 0;
+
+    friend class TlsConnection;
+  };
+
+  TlsConnection(const TlsConnection&) = delete;
+  TlsConnection& operator=(const TlsConnection&) = delete;
+
+  // Configure the SSL such that delegate_->InfoCallback will be called.
+  void EnableInfoCallback();
+
+  // Configure the SSL to disable session ticket support. Note that, this
+  // function simply sets the |SSL_OP_NO_TICKET| option on the SSL object, it
+  // does not check whether it is too late to do so.
+  void DisableTicketSupport();
+
+  // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
+  // QUIC's EncryptionLevel.
+  static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
+  static enum ssl_encryption_level_t BoringEncryptionLevel(
+      EncryptionLevel level);
+
+  SSL* ssl() const { return ssl_.get(); }
+
+  const QuicSSLConfig& ssl_config() const { return ssl_config_; }
+
+ protected:
+  // TlsConnection does not take ownership of |ssl_ctx| or |delegate|; they must
+  // outlive the TlsConnection object.
+  TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate, QuicSSLConfig ssl_config);
+
+  // Creates an SSL_CTX and configures it with the options that are appropriate
+  // for both client and server. The caller is responsible for ownership of the
+  // newly created struct.
+  static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
+
+  // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
+  // belongs to. This helper method allows the callbacks set in BoringSSL to be
+  // dispatched to the correct TlsConnection from the SSL* passed into the
+  // callback.
+  static TlsConnection* ConnectionFromSsl(const SSL* ssl);
+
+  // Registered as the callback for SSL(_CTX)_set_custom_verify. The
+  // implementation is delegated to Delegate::VerifyCert.
+  static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
+
+  QuicSSLConfig& mutable_ssl_config() { return ssl_config_; }
+
+ private:
+  // TlsConnection implements SSL_QUIC_METHOD, which provides the interface
+  // between BoringSSL's TLS stack and a QUIC implementation.
+  static const SSL_QUIC_METHOD kSslQuicMethod;
+
+  // The following static functions make up the members of kSslQuicMethod:
+  static int SetReadSecretCallback(SSL* ssl,
+                                   enum ssl_encryption_level_t level,
+                                   const SSL_CIPHER* cipher,
+                                   const uint8_t* secret,
+                                   size_t secret_len);
+  static int SetWriteSecretCallback(SSL* ssl,
+                                    enum ssl_encryption_level_t level,
+                                    const SSL_CIPHER* cipher,
+                                    const uint8_t* secret,
+                                    size_t secret_len);
+  static int WriteMessageCallback(SSL* ssl,
+                                  enum ssl_encryption_level_t level,
+                                  const uint8_t* data,
+                                  size_t len);
+  static int FlushFlightCallback(SSL* ssl);
+  static int SendAlertCallback(SSL* ssl,
+                               enum ssl_encryption_level_t level,
+                               uint8_t desc);
+
+  Delegate* delegate_;
+  bssl::UniquePtr<SSL> ssl_;
+  QuicSSLConfig ssl_config_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
diff --git a/quiche/quic/core/crypto/tls_server_connection.cc b/quiche/quic/core/crypto/tls_server_connection.cc
new file mode 100644
index 0000000..1e63d3f
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_server_connection.cc
@@ -0,0 +1,186 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/tls_server_connection.h"
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate,
+                                         QuicSSLConfig ssl_config)
+    : TlsConnection(ssl_ctx, delegate->ConnectionDelegate(),
+                    std::move(ssl_config)),
+      delegate_(delegate) {
+  // By default, cert verify callback is not installed on ssl(), so only need to
+  // UpdateCertVerifyCallback() if client_cert_mode is not kNone.
+  if (TlsConnection::ssl_config().client_cert_mode != ClientCertMode::kNone) {
+    UpdateCertVerifyCallback();
+  }
+}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
+    ProofSource* proof_source) {
+  bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
+
+  // Server does not request/verify client certs by default. Individual server
+  // connections may call SSL_set_custom_verify on their SSL object to request
+  // client certs.
+
+  SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
+                                         &TlsExtServernameCallback);
+  SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
+  // We don't actually need the TicketCrypter here, but we need to know
+  // whether it's set.
+  if (proof_source->GetTicketCrypter()) {
+    QUIC_CODE_COUNT(quic_session_tickets_enabled);
+    SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
+                                   &TlsServerConnection::kSessionTicketMethod);
+  } else {
+    QUIC_CODE_COUNT(quic_session_tickets_disabled);
+  }
+
+  SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
+
+  SSL_CTX_set_select_certificate_cb(
+      ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
+  SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
+  return ssl_ctx;
+}
+
+void TlsServerConnection::SetCertChain(
+    const std::vector<CRYPTO_BUFFER*>& cert_chain) {
+  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
+                        &TlsServerConnection::kPrivateKeyMethod);
+}
+
+void TlsServerConnection::SetClientCertMode(ClientCertMode client_cert_mode) {
+  if (ssl_config().client_cert_mode == client_cert_mode) {
+    return;
+  }
+
+  mutable_ssl_config().client_cert_mode = client_cert_mode;
+  UpdateCertVerifyCallback();
+}
+
+void TlsServerConnection::UpdateCertVerifyCallback() {
+  const ClientCertMode client_cert_mode = ssl_config().client_cert_mode;
+  if (client_cert_mode == ClientCertMode::kNone) {
+    SSL_set_custom_verify(ssl(), SSL_VERIFY_NONE, nullptr);
+    return;
+  }
+
+  int mode = SSL_VERIFY_PEER;
+  if (client_cert_mode == ClientCertMode::kRequire) {
+    mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+  } else {
+    QUICHE_DCHECK_EQ(client_cert_mode, ClientCertMode::kRequest);
+  }
+  SSL_set_custom_verify(ssl(), mode, &VerifyCallback);
+}
+
+const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
+    &TlsServerConnection::PrivateKeySign,
+    nullptr,  // decrypt
+    &TlsServerConnection::PrivateKeyComplete,
+};
+
+// static
+TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
+  return static_cast<TlsServerConnection*>(
+      TlsConnection::ConnectionFromSsl(ssl));
+}
+
+// static
+ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
+    const SSL_CLIENT_HELLO* client_hello) {
+  return ConnectionFromSsl(client_hello->ssl)
+      ->delegate_->EarlySelectCertCallback(client_hello);
+}
+
+// static
+int TlsServerConnection::TlsExtServernameCallback(SSL* ssl,
+                                                  int* out_alert,
+                                                  void* /*arg*/) {
+  return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
+}
+
+// static
+int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
+                                            const uint8_t** out,
+                                            uint8_t* out_len,
+                                            const uint8_t* in,
+                                            unsigned in_len,
+                                            void* /*arg*/) {
+  return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
+                                                       in_len);
+}
+
+// static
+ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
+                                                             uint8_t* out,
+                                                             size_t* out_len,
+                                                             size_t max_out,
+                                                             uint16_t sig_alg,
+                                                             const uint8_t* in,
+                                                             size_t in_len) {
+  return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
+      out, out_len, max_out, sig_alg,
+      absl::string_view(reinterpret_cast<const char*>(in), in_len));
+}
+
+// static
+ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
+    SSL* ssl,
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out) {
+  return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
+                                                               max_out);
+}
+
+// static
+const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
+    TlsServerConnection::SessionTicketMaxOverhead,
+    TlsServerConnection::SessionTicketSeal,
+    TlsServerConnection::SessionTicketOpen,
+};
+
+// static
+size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
+  return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
+}
+
+// static
+int TlsServerConnection::SessionTicketSeal(SSL* ssl,
+                                           uint8_t* out,
+                                           size_t* out_len,
+                                           size_t max_out_len,
+                                           const uint8_t* in,
+                                           size_t in_len) {
+  return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
+      out, out_len, max_out_len,
+      absl::string_view(reinterpret_cast<const char*>(in), in_len));
+}
+
+// static
+enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
+    SSL* ssl,
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out_len,
+    const uint8_t* in,
+    size_t in_len) {
+  return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
+      out, out_len, max_out_len,
+      absl::string_view(reinterpret_cast<const char*>(in), in_len));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/tls_server_connection.h b/quiche/quic/core/crypto/tls_server_connection.h
new file mode 100644
index 0000000..85dddd0
--- /dev/null
+++ b/quiche/quic/core/crypto/tls_server_connection.h
@@ -0,0 +1,200 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/tls_connection.h"
+
+namespace quic {
+
+// TlsServerConnection receives calls for client-specific BoringSSL callbacks
+// and calls its Delegate for the implementation of those callbacks.
+class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection {
+ public:
+  // A TlsServerConnection::Delegate implement the server-specific methods that
+  // are set as callbacks for an SSL object.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+   protected:
+    // Called from BoringSSL right after SNI is extracted, which is very early
+    // in the handshake process.
+    virtual ssl_select_cert_result_t EarlySelectCertCallback(
+        const SSL_CLIENT_HELLO* client_hello) = 0;
+
+    // Called after the ClientHello extensions have been successfully parsed.
+    // Returns an SSL_TLSEXT_ERR_* value (see
+    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_tlsext_servername_callback).
+    //
+    // On success, return SSL_TLSEXT_ERR_OK causes the server_name extension to
+    // be acknowledged in the ServerHello, or return SSL_TLSEXT_ERR_NOACK which
+    // causes it to be not acknowledged.
+    //
+    // If the function returns SSL_TLSEXT_ERR_ALERT_FATAL, then it puts in
+    // |*out_alert| the TLS alert value that the server will send.
+    //
+    virtual int TlsExtServernameCallback(int* out_alert) = 0;
+
+    // Selects which ALPN to use based on the list sent by the client.
+    virtual int SelectAlpn(const uint8_t** out,
+                           uint8_t* out_len,
+                           const uint8_t* in,
+                           unsigned in_len) = 0;
+
+    // Signs |in| using the signature algorithm specified by |sig_alg| (an
+    // SSL_SIGN_* value). If the signing operation cannot be completed
+    // synchronously, ssl_private_key_retry is returned. If there is an error
+    // signing, or if the signature is longer than |max_out|, then
+    // ssl_private_key_failure is returned. Otherwise, ssl_private_key_success
+    // is returned with the signature put in |*out| and the length in
+    // |*out_len|.
+    virtual ssl_private_key_result_t PrivateKeySign(uint8_t* out,
+                                                    size_t* out_len,
+                                                    size_t max_out,
+                                                    uint16_t sig_alg,
+                                                    absl::string_view in) = 0;
+
+    // When PrivateKeySign returns ssl_private_key_retry, PrivateKeyComplete
+    // will be called after the async sign operation has completed.
+    // PrivateKeyComplete puts the resulting signature in |*out| and length in
+    // |*out_len|. If the length is greater than |max_out| or if there was an
+    // error in signing, then ssl_private_key_failure is returned. Otherwise,
+    // ssl_private_key_success is returned.
+    virtual ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
+                                                        size_t* out_len,
+                                                        size_t max_out) = 0;
+
+    // The following functions are used to implement an SSL_TICKET_AEAD_METHOD.
+    // See
+    // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#ssl_ticket_aead_result_t
+    // for details on the BoringSSL API.
+
+    // SessionTicketMaxOverhead returns the maximum number of bytes of overhead
+    // that SessionTicketSeal may add when encrypting a session ticket.
+    virtual size_t SessionTicketMaxOverhead() = 0;
+
+    // SessionTicketSeal encrypts the session ticket in |in|, putting the
+    // resulting encrypted ticket in |out|, writing the length of the bytes
+    // written to |*out_len|, which is no larger than |max_out_len|. It returns
+    // 1 on success and 0 on error.
+    virtual int SessionTicketSeal(uint8_t* out,
+                                  size_t* out_len,
+                                  size_t max_out_len,
+                                  absl::string_view in) = 0;
+
+    // SessionTicketOpen is called when BoringSSL has an encrypted session
+    // ticket |in| and wants the ticket decrypted. This decryption operation can
+    // happen synchronously or asynchronously.
+    //
+    // If the decrypted ticket is not available at the time of the function
+    // call, this function returns ssl_ticket_aead_retry. If this function
+    // returns ssl_ticket_aead_retry, then SSL_do_handshake will return
+    // SSL_ERROR_PENDING_TICKET. Once the pending ticket decryption has
+    // completed, SSL_do_handshake needs to be called again.
+    //
+    // When this function is called and the decrypted ticket is available
+    // (either the ticket was decrypted synchronously, or an asynchronous
+    // operation has completed and SSL_do_handshake has been called again), the
+    // decrypted ticket is put in |out|, and the length of that output is
+    // written to |*out_len|, not to exceed |max_out_len|, and
+    // ssl_ticket_aead_success is returned. If the ticket cannot be decrypted
+    // and should be ignored, this function returns
+    // ssl_ticket_aead_ignore_ticket and a full handshake will be performed
+    // instead. If a fatal error occurs, ssl_ticket_aead_error can be returned
+    // which will terminate the handshake.
+    virtual enum ssl_ticket_aead_result_t SessionTicketOpen(
+        uint8_t* out,
+        size_t* out_len,
+        size_t max_out_len,
+        absl::string_view in) = 0;
+
+    // Provides the delegate for callbacks that are shared between client and
+    // server.
+    virtual TlsConnection::Delegate* ConnectionDelegate() = 0;
+
+    friend class TlsServerConnection;
+  };
+
+  TlsServerConnection(SSL_CTX* ssl_ctx,
+                      Delegate* delegate,
+                      QuicSSLConfig ssl_config);
+
+  // Creates and configures an SSL_CTX that is appropriate for servers to use.
+  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(ProofSource* proof_source);
+
+  void SetCertChain(const std::vector<CRYPTO_BUFFER*>& cert_chain);
+
+  // Set the client cert mode to be used on this connection. This should be
+  // called right after cert selection at the latest, otherwise it is too late
+  // to has an effect.
+  void SetClientCertMode(ClientCertMode client_cert_mode);
+
+ private:
+  // Specialization of TlsConnection::ConnectionFromSsl.
+  static TlsServerConnection* ConnectionFromSsl(SSL* ssl);
+
+  static ssl_select_cert_result_t EarlySelectCertCallback(
+      const SSL_CLIENT_HELLO* client_hello);
+
+  // These functions are registered as callbacks in BoringSSL and delegate their
+  // implementation to the matching methods in Delegate above.
+  static int TlsExtServernameCallback(SSL* ssl, int* out_alert, void* arg);
+  static int SelectAlpnCallback(SSL* ssl,
+                                const uint8_t** out,
+                                uint8_t* out_len,
+                                const uint8_t* in,
+                                unsigned in_len,
+                                void* arg);
+
+  // |kPrivateKeyMethod| is a vtable pointing to PrivateKeySign and
+  // PrivateKeyComplete used by the TLS stack to compute the signature for the
+  // CertificateVerify message (using the server's private key).
+  static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
+
+  // The following functions make up the contents of |kPrivateKeyMethod|.
+  static ssl_private_key_result_t PrivateKeySign(SSL* ssl,
+                                                 uint8_t* out,
+                                                 size_t* out_len,
+                                                 size_t max_out,
+                                                 uint16_t sig_alg,
+                                                 const uint8_t* in,
+                                                 size_t in_len);
+  static ssl_private_key_result_t PrivateKeyComplete(SSL* ssl,
+                                                     uint8_t* out,
+                                                     size_t* out_len,
+                                                     size_t max_out);
+
+  // Implementation of SSL_TICKET_AEAD_METHOD which delegates to corresponding
+  // methods in TlsServerConnection::Delegate (a.k.a. TlsServerHandshaker).
+  static const SSL_TICKET_AEAD_METHOD kSessionTicketMethod;
+
+  // The following functions make up the contents of |kSessionTicketMethod|.
+  static size_t SessionTicketMaxOverhead(SSL* ssl);
+  static int SessionTicketSeal(SSL* ssl,
+                               uint8_t* out,
+                               size_t* out_len,
+                               size_t max_out_len,
+                               const uint8_t* in,
+                               size_t in_len);
+  static enum ssl_ticket_aead_result_t SessionTicketOpen(SSL* ssl,
+                                                         uint8_t* out,
+                                                         size_t* out_len,
+                                                         size_t max_out_len,
+                                                         const uint8_t* in,
+                                                         size_t in_len);
+
+  // Install custom verify callback on ssl() if |ssl_config().client_cert_mode|
+  // is not ClientCertMode::kNone. Uninstall otherwise.
+  void UpdateCertVerifyCallback();
+
+  Delegate* delegate_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_SERVER_CONNECTION_H_
diff --git a/quiche/quic/core/crypto/transport_parameters.cc b/quiche/quic/core/crypto/transport_parameters.cc
new file mode 100644
index 0000000..04db561
--- /dev/null
+++ b/quiche/quic/core/crypto/transport_parameters.cc
@@ -0,0 +1,1590 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/transport_parameters.h"
+
+#include <cstdint>
+#include <cstring>
+#include <forward_list>
+#include <memory>
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+// Values of the TransportParameterId enum as defined in the
+// "Transport Parameter Encoding" section of draft-ietf-quic-transport.
+// When parameters are encoded, one of these enum values is used to indicate
+// which parameter is encoded. The supported draft version is noted in
+// transport_parameters.h.
+enum TransportParameters::TransportParameterId : uint64_t {
+  kOriginalDestinationConnectionId = 0,
+  kMaxIdleTimeout = 1,
+  kStatelessResetToken = 2,
+  kMaxPacketSize = 3,
+  kInitialMaxData = 4,
+  kInitialMaxStreamDataBidiLocal = 5,
+  kInitialMaxStreamDataBidiRemote = 6,
+  kInitialMaxStreamDataUni = 7,
+  kInitialMaxStreamsBidi = 8,
+  kInitialMaxStreamsUni = 9,
+  kAckDelayExponent = 0xa,
+  kMaxAckDelay = 0xb,
+  kDisableActiveMigration = 0xc,
+  kPreferredAddress = 0xd,
+  kActiveConnectionIdLimit = 0xe,
+  kInitialSourceConnectionId = 0xf,
+  kRetrySourceConnectionId = 0x10,
+
+  kMaxDatagramFrameSize = 0x20,
+
+  kInitialRoundTripTime = 0x3127,
+  kGoogleConnectionOptions = 0x3128,
+  // 0x3129 was used to convey the user agent string.
+  // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
+  // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
+  // 0x4751 was used for non-standard Google-specific parameters encoded as a
+  // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
+  kGoogleQuicVersion =
+      0x4752,  // Used to transmit version and supported_versions.
+
+  kMinAckDelay = 0xDE1A,           // draft-iyengar-quic-delayed-ack.
+  kVersionInformation = 0xFF73DB,  // draft-ietf-quic-version-negotiation.
+};
+
+namespace {
+
+// The following constants define minimum and maximum allowed values for some of
+// the parameters. These come from the "Transport Parameter Definitions"
+// section of draft-ietf-quic-transport.
+constexpr uint64_t kMinMaxPacketSizeTransportParam = 1200;
+constexpr uint64_t kMaxAckDelayExponentTransportParam = 20;
+constexpr uint64_t kDefaultAckDelayExponentTransportParam = 3;
+constexpr uint64_t kMaxMaxAckDelayTransportParam = 16383;
+constexpr uint64_t kDefaultMaxAckDelayTransportParam = 25;
+constexpr uint64_t kMinActiveConnectionIdLimitTransportParam = 2;
+constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;
+
+std::string TransportParameterIdToString(
+    TransportParameters::TransportParameterId param_id) {
+  switch (param_id) {
+    case TransportParameters::kOriginalDestinationConnectionId:
+      return "original_destination_connection_id";
+    case TransportParameters::kMaxIdleTimeout:
+      return "max_idle_timeout";
+    case TransportParameters::kStatelessResetToken:
+      return "stateless_reset_token";
+    case TransportParameters::kMaxPacketSize:
+      return "max_udp_payload_size";
+    case TransportParameters::kInitialMaxData:
+      return "initial_max_data";
+    case TransportParameters::kInitialMaxStreamDataBidiLocal:
+      return "initial_max_stream_data_bidi_local";
+    case TransportParameters::kInitialMaxStreamDataBidiRemote:
+      return "initial_max_stream_data_bidi_remote";
+    case TransportParameters::kInitialMaxStreamDataUni:
+      return "initial_max_stream_data_uni";
+    case TransportParameters::kInitialMaxStreamsBidi:
+      return "initial_max_streams_bidi";
+    case TransportParameters::kInitialMaxStreamsUni:
+      return "initial_max_streams_uni";
+    case TransportParameters::kAckDelayExponent:
+      return "ack_delay_exponent";
+    case TransportParameters::kMaxAckDelay:
+      return "max_ack_delay";
+    case TransportParameters::kDisableActiveMigration:
+      return "disable_active_migration";
+    case TransportParameters::kPreferredAddress:
+      return "preferred_address";
+    case TransportParameters::kActiveConnectionIdLimit:
+      return "active_connection_id_limit";
+    case TransportParameters::kInitialSourceConnectionId:
+      return "initial_source_connection_id";
+    case TransportParameters::kRetrySourceConnectionId:
+      return "retry_source_connection_id";
+    case TransportParameters::kMaxDatagramFrameSize:
+      return "max_datagram_frame_size";
+    case TransportParameters::kInitialRoundTripTime:
+      return "initial_round_trip_time";
+    case TransportParameters::kGoogleConnectionOptions:
+      return "google_connection_options";
+    case TransportParameters::kGoogleQuicVersion:
+      return "google-version";
+    case TransportParameters::kMinAckDelay:
+      return "min_ack_delay_us";
+    case TransportParameters::kVersionInformation:
+      return "version_information";
+  }
+  return absl::StrCat("Unknown(", param_id, ")");
+}
+
+bool TransportParameterIdIsKnown(
+    TransportParameters::TransportParameterId param_id) {
+  switch (param_id) {
+    case TransportParameters::kOriginalDestinationConnectionId:
+    case TransportParameters::kMaxIdleTimeout:
+    case TransportParameters::kStatelessResetToken:
+    case TransportParameters::kMaxPacketSize:
+    case TransportParameters::kInitialMaxData:
+    case TransportParameters::kInitialMaxStreamDataBidiLocal:
+    case TransportParameters::kInitialMaxStreamDataBidiRemote:
+    case TransportParameters::kInitialMaxStreamDataUni:
+    case TransportParameters::kInitialMaxStreamsBidi:
+    case TransportParameters::kInitialMaxStreamsUni:
+    case TransportParameters::kAckDelayExponent:
+    case TransportParameters::kMaxAckDelay:
+    case TransportParameters::kDisableActiveMigration:
+    case TransportParameters::kPreferredAddress:
+    case TransportParameters::kActiveConnectionIdLimit:
+    case TransportParameters::kInitialSourceConnectionId:
+    case TransportParameters::kRetrySourceConnectionId:
+    case TransportParameters::kMaxDatagramFrameSize:
+    case TransportParameters::kInitialRoundTripTime:
+    case TransportParameters::kGoogleConnectionOptions:
+    case TransportParameters::kGoogleQuicVersion:
+    case TransportParameters::kMinAckDelay:
+    case TransportParameters::kVersionInformation:
+      return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+TransportParameters::IntegerParameter::IntegerParameter(
+    TransportParameters::TransportParameterId param_id,
+    uint64_t default_value,
+    uint64_t min_value,
+    uint64_t max_value)
+    : param_id_(param_id),
+      value_(default_value),
+      default_value_(default_value),
+      min_value_(min_value),
+      max_value_(max_value),
+      has_been_read_(false) {
+  QUICHE_DCHECK_LE(min_value, default_value);
+  QUICHE_DCHECK_LE(default_value, max_value);
+  QUICHE_DCHECK_LE(max_value, kVarInt62MaxValue);
+}
+
+TransportParameters::IntegerParameter::IntegerParameter(
+    TransportParameters::TransportParameterId param_id)
+    : TransportParameters::IntegerParameter::IntegerParameter(
+          param_id,
+          0,
+          0,
+          kVarInt62MaxValue) {}
+
+void TransportParameters::IntegerParameter::set_value(uint64_t value) {
+  value_ = value;
+}
+
+uint64_t TransportParameters::IntegerParameter::value() const {
+  return value_;
+}
+
+bool TransportParameters::IntegerParameter::IsValid() const {
+  return min_value_ <= value_ && value_ <= max_value_;
+}
+
+bool TransportParameters::IntegerParameter::Write(
+    QuicDataWriter* writer) const {
+  QUICHE_DCHECK(IsValid());
+  if (value_ == default_value_) {
+    // Do not write if the value is default.
+    return true;
+  }
+  if (!writer->WriteVarInt62(param_id_)) {
+    QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
+    return false;
+  }
+  const QuicVariableLengthIntegerLength value_length =
+      QuicDataWriter::GetVarInt62Len(value_);
+  if (!writer->WriteVarInt62(value_length)) {
+    QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
+    return false;
+  }
+  if (!writer->WriteVarInt62(value_, value_length)) {
+    QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
+    return false;
+  }
+  return true;
+}
+
+bool TransportParameters::IntegerParameter::Read(QuicDataReader* reader,
+                                                 std::string* error_details) {
+  if (has_been_read_) {
+    *error_details =
+        "Received a second " + TransportParameterIdToString(param_id_);
+    return false;
+  }
+  has_been_read_ = true;
+
+  if (!reader->ReadVarInt62(&value_)) {
+    *error_details =
+        "Failed to parse value for " + TransportParameterIdToString(param_id_);
+    return false;
+  }
+  if (!reader->IsDoneReading()) {
+    *error_details =
+        absl::StrCat("Received unexpected ", reader->BytesRemaining(),
+                     " bytes after parsing ", this->ToString(false));
+    return false;
+  }
+  return true;
+}
+
+std::string TransportParameters::IntegerParameter::ToString(
+    bool for_use_in_list) const {
+  if (for_use_in_list && value_ == default_value_) {
+    return "";
+  }
+  std::string rv = for_use_in_list ? " " : "";
+  absl::StrAppend(&rv, TransportParameterIdToString(param_id_), " ", value_);
+  if (!IsValid()) {
+    rv += " (Invalid)";
+  }
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TransportParameters::IntegerParameter& param) {
+  os << param.ToString(/*for_use_in_list=*/false);
+  return os;
+}
+
+TransportParameters::PreferredAddress::PreferredAddress()
+    : ipv4_socket_address(QuicIpAddress::Any4(), 0),
+      ipv6_socket_address(QuicIpAddress::Any6(), 0),
+      connection_id(EmptyQuicConnectionId()),
+      stateless_reset_token(kStatelessResetTokenLength, 0) {}
+
+TransportParameters::PreferredAddress::~PreferredAddress() {}
+
+bool TransportParameters::PreferredAddress::operator==(
+    const PreferredAddress& rhs) const {
+  return ipv4_socket_address == rhs.ipv4_socket_address &&
+         ipv6_socket_address == rhs.ipv6_socket_address &&
+         connection_id == rhs.connection_id &&
+         stateless_reset_token == rhs.stateless_reset_token;
+}
+
+bool TransportParameters::PreferredAddress::operator!=(
+    const PreferredAddress& rhs) const {
+  return !(*this == rhs);
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const TransportParameters::PreferredAddress& preferred_address) {
+  os << preferred_address.ToString();
+  return os;
+}
+
+std::string TransportParameters::PreferredAddress::ToString() const {
+  return "[" + ipv4_socket_address.ToString() + " " +
+         ipv6_socket_address.ToString() + " connection_id " +
+         connection_id.ToString() + " stateless_reset_token " +
+         absl::BytesToHexString(absl::string_view(
+             reinterpret_cast<const char*>(stateless_reset_token.data()),
+             stateless_reset_token.size())) +
+         "]";
+}
+
+TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
+    : version(0) {}
+
+bool TransportParameters::LegacyVersionInformation::operator==(
+    const LegacyVersionInformation& rhs) const {
+  return version == rhs.version && supported_versions == rhs.supported_versions;
+}
+
+bool TransportParameters::LegacyVersionInformation::operator!=(
+    const LegacyVersionInformation& rhs) const {
+  return !(*this == rhs);
+}
+
+std::string TransportParameters::LegacyVersionInformation::ToString() const {
+  std::string rv =
+      absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
+  if (!supported_versions.empty()) {
+    absl::StrAppend(&rv,
+                    " supported_versions " +
+                        QuicVersionLabelVectorToString(supported_versions));
+  }
+  absl::StrAppend(&rv, "]");
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TransportParameters::LegacyVersionInformation&
+                             legacy_version_information) {
+  os << legacy_version_information.ToString();
+  return os;
+}
+
+TransportParameters::VersionInformation::VersionInformation()
+    : chosen_version(0) {}
+
+bool TransportParameters::VersionInformation::operator==(
+    const VersionInformation& rhs) const {
+  return chosen_version == rhs.chosen_version &&
+         other_versions == rhs.other_versions;
+}
+
+bool TransportParameters::VersionInformation::operator!=(
+    const VersionInformation& rhs) const {
+  return !(*this == rhs);
+}
+
+std::string TransportParameters::VersionInformation::ToString() const {
+  std::string rv = absl::StrCat("[chosen_version ",
+                                QuicVersionLabelToString(chosen_version));
+  if (!other_versions.empty()) {
+    absl::StrAppend(&rv, " other_versions " +
+                             QuicVersionLabelVectorToString(other_versions));
+  }
+  absl::StrAppend(&rv, "]");
+  return rv;
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const TransportParameters::VersionInformation& version_information) {
+  os << version_information.ToString();
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
+  os << params.ToString();
+  return os;
+}
+
+std::string TransportParameters::ToString() const {
+  std::string rv = "[";
+  if (perspective == Perspective::IS_SERVER) {
+    rv += "Server";
+  } else {
+    rv += "Client";
+  }
+  if (legacy_version_information.has_value()) {
+    rv += " " + legacy_version_information.value().ToString();
+  }
+  if (version_information.has_value()) {
+    rv += " " + version_information.value().ToString();
+  }
+  if (original_destination_connection_id.has_value()) {
+    rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
+          " " + original_destination_connection_id.value().ToString();
+  }
+  rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
+  if (!stateless_reset_token.empty()) {
+    rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
+          absl::BytesToHexString(absl::string_view(
+              reinterpret_cast<const char*>(stateless_reset_token.data()),
+              stateless_reset_token.size()));
+  }
+  rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_data.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_stream_data_uni.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_streams_bidi.ToString(/*for_use_in_list=*/true);
+  rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
+  rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
+  rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
+  rv += min_ack_delay_us.ToString(/*for_use_in_list=*/true);
+  if (disable_active_migration) {
+    rv += " " + TransportParameterIdToString(kDisableActiveMigration);
+  }
+  if (preferred_address) {
+    rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
+          preferred_address->ToString();
+  }
+  rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
+  if (initial_source_connection_id.has_value()) {
+    rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
+          initial_source_connection_id.value().ToString();
+  }
+  if (retry_source_connection_id.has_value()) {
+    rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
+          retry_source_connection_id.value().ToString();
+  }
+  rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
+  rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
+  if (google_connection_options.has_value()) {
+    rv += " " + TransportParameterIdToString(kGoogleConnectionOptions) + " ";
+    bool first = true;
+    for (const QuicTag& connection_option : google_connection_options.value()) {
+      if (first) {
+        first = false;
+      } else {
+        rv += ",";
+      }
+      rv += QuicTagToString(connection_option);
+    }
+  }
+  for (const auto& kv : custom_parameters) {
+    absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
+                    "=");
+    static constexpr size_t kMaxPrintableLength = 32;
+    if (kv.second.length() <= kMaxPrintableLength) {
+      rv += absl::BytesToHexString(kv.second);
+    } else {
+      absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
+      rv += absl::StrCat(absl::BytesToHexString(truncated), "...(length ",
+                         kv.second.length(), ")");
+    }
+  }
+  rv += "]";
+  return rv;
+}
+
+TransportParameters::TransportParameters()
+    : max_idle_timeout_ms(kMaxIdleTimeout),
+      max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
+                           kMinMaxPacketSizeTransportParam, kVarInt62MaxValue),
+      initial_max_data(kInitialMaxData),
+      initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
+      initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
+      initial_max_stream_data_uni(kInitialMaxStreamDataUni),
+      initial_max_streams_bidi(kInitialMaxStreamsBidi),
+      initial_max_streams_uni(kInitialMaxStreamsUni),
+      ack_delay_exponent(kAckDelayExponent,
+                         kDefaultAckDelayExponentTransportParam, 0,
+                         kMaxAckDelayExponentTransportParam),
+      max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
+                    kMaxMaxAckDelayTransportParam),
+      min_ack_delay_us(kMinAckDelay, 0, 0,
+                       kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
+      disable_active_migration(false),
+      active_connection_id_limit(kActiveConnectionIdLimit,
+                                 kDefaultActiveConnectionIdLimitTransportParam,
+                                 kMinActiveConnectionIdLimitTransportParam,
+                                 kVarInt62MaxValue),
+      max_datagram_frame_size(kMaxDatagramFrameSize),
+      initial_round_trip_time_us(kInitialRoundTripTime)
+// Important note: any new transport parameters must be added
+// to TransportParameters::AreValid, SerializeTransportParameters and
+// ParseTransportParameters, TransportParameters's custom copy constructor, the
+// operator==, and TransportParametersTest.Comparator.
+{}
+
+TransportParameters::TransportParameters(const TransportParameters& other)
+    : perspective(other.perspective),
+      legacy_version_information(other.legacy_version_information),
+      version_information(other.version_information),
+      original_destination_connection_id(
+          other.original_destination_connection_id),
+      max_idle_timeout_ms(other.max_idle_timeout_ms),
+      stateless_reset_token(other.stateless_reset_token),
+      max_udp_payload_size(other.max_udp_payload_size),
+      initial_max_data(other.initial_max_data),
+      initial_max_stream_data_bidi_local(
+          other.initial_max_stream_data_bidi_local),
+      initial_max_stream_data_bidi_remote(
+          other.initial_max_stream_data_bidi_remote),
+      initial_max_stream_data_uni(other.initial_max_stream_data_uni),
+      initial_max_streams_bidi(other.initial_max_streams_bidi),
+      initial_max_streams_uni(other.initial_max_streams_uni),
+      ack_delay_exponent(other.ack_delay_exponent),
+      max_ack_delay(other.max_ack_delay),
+      min_ack_delay_us(other.min_ack_delay_us),
+      disable_active_migration(other.disable_active_migration),
+      active_connection_id_limit(other.active_connection_id_limit),
+      initial_source_connection_id(other.initial_source_connection_id),
+      retry_source_connection_id(other.retry_source_connection_id),
+      max_datagram_frame_size(other.max_datagram_frame_size),
+      initial_round_trip_time_us(other.initial_round_trip_time_us),
+      google_connection_options(other.google_connection_options),
+      custom_parameters(other.custom_parameters) {
+  if (other.preferred_address) {
+    preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
+        *other.preferred_address);
+  }
+}
+
+bool TransportParameters::operator==(const TransportParameters& rhs) const {
+  if (!(perspective == rhs.perspective &&
+        legacy_version_information == rhs.legacy_version_information &&
+        version_information == rhs.version_information &&
+        original_destination_connection_id ==
+            rhs.original_destination_connection_id &&
+        max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
+        stateless_reset_token == rhs.stateless_reset_token &&
+        max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
+        initial_max_data.value() == rhs.initial_max_data.value() &&
+        initial_max_stream_data_bidi_local.value() ==
+            rhs.initial_max_stream_data_bidi_local.value() &&
+        initial_max_stream_data_bidi_remote.value() ==
+            rhs.initial_max_stream_data_bidi_remote.value() &&
+        initial_max_stream_data_uni.value() ==
+            rhs.initial_max_stream_data_uni.value() &&
+        initial_max_streams_bidi.value() ==
+            rhs.initial_max_streams_bidi.value() &&
+        initial_max_streams_uni.value() ==
+            rhs.initial_max_streams_uni.value() &&
+        ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
+        max_ack_delay.value() == rhs.max_ack_delay.value() &&
+        min_ack_delay_us.value() == rhs.min_ack_delay_us.value() &&
+        disable_active_migration == rhs.disable_active_migration &&
+        active_connection_id_limit.value() ==
+            rhs.active_connection_id_limit.value() &&
+        initial_source_connection_id == rhs.initial_source_connection_id &&
+        retry_source_connection_id == rhs.retry_source_connection_id &&
+        max_datagram_frame_size.value() ==
+            rhs.max_datagram_frame_size.value() &&
+        initial_round_trip_time_us.value() ==
+            rhs.initial_round_trip_time_us.value() &&
+        google_connection_options == rhs.google_connection_options &&
+        custom_parameters == rhs.custom_parameters)) {
+    return false;
+  }
+
+  if ((!preferred_address && rhs.preferred_address) ||
+      (preferred_address && !rhs.preferred_address)) {
+    return false;
+  }
+  if (preferred_address && rhs.preferred_address &&
+      *preferred_address != *rhs.preferred_address) {
+    return false;
+  }
+
+  return true;
+}
+
+bool TransportParameters::operator!=(const TransportParameters& rhs) const {
+  return !(*this == rhs);
+}
+
+bool TransportParameters::AreValid(std::string* error_details) const {
+  QUICHE_DCHECK(perspective == Perspective::IS_CLIENT ||
+                perspective == Perspective::IS_SERVER);
+  if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
+    *error_details = "Client cannot send stateless reset token";
+    return false;
+  }
+  if (perspective == Perspective::IS_CLIENT &&
+      original_destination_connection_id.has_value()) {
+    *error_details = "Client cannot send original_destination_connection_id";
+    return false;
+  }
+  if (!stateless_reset_token.empty() &&
+      stateless_reset_token.size() != kStatelessResetTokenLength) {
+    *error_details = absl::StrCat("Stateless reset token has bad length ",
+                                  stateless_reset_token.size());
+    return false;
+  }
+  if (perspective == Perspective::IS_CLIENT && preferred_address) {
+    *error_details = "Client cannot send preferred address";
+    return false;
+  }
+  if (preferred_address && preferred_address->stateless_reset_token.size() !=
+                               kStatelessResetTokenLength) {
+    *error_details =
+        absl::StrCat("Preferred address stateless reset token has bad length ",
+                     preferred_address->stateless_reset_token.size());
+    return false;
+  }
+  if (preferred_address &&
+      (!preferred_address->ipv4_socket_address.host().IsIPv4() ||
+       !preferred_address->ipv6_socket_address.host().IsIPv6())) {
+    QUIC_BUG(quic_bug_10743_4) << "Preferred address family failure";
+    *error_details = "Internal preferred address family failure";
+    return false;
+  }
+  if (perspective == Perspective::IS_CLIENT &&
+      retry_source_connection_id.has_value()) {
+    *error_details = "Client cannot send retry_source_connection_id";
+    return false;
+  }
+  for (const auto& kv : custom_parameters) {
+    if (TransportParameterIdIsKnown(kv.first)) {
+      *error_details = absl::StrCat("Using custom_parameters with known ID ",
+                                    TransportParameterIdToString(kv.first),
+                                    " is not allowed");
+      return false;
+    }
+  }
+  if (perspective == Perspective::IS_SERVER &&
+      initial_round_trip_time_us.value() > 0) {
+    *error_details = "Server cannot send initial round trip time";
+    return false;
+  }
+  if (version_information.has_value()) {
+    const QuicVersionLabel& chosen_version =
+        version_information.value().chosen_version;
+    const QuicVersionLabelVector& other_versions =
+        version_information.value().other_versions;
+    if (chosen_version == 0) {
+      *error_details = "Invalid chosen version";
+      return false;
+    }
+    if (perspective == Perspective::IS_CLIENT &&
+        std::find(other_versions.begin(), other_versions.end(),
+                  chosen_version) == other_versions.end()) {
+      // When sent by the client, chosen_version needs to be present in
+      // other_versions because other_versions lists the compatible versions and
+      // the chosen version is part of that list. When sent by the server,
+      // other_version contains the list of fully-deployed versions which is
+      // generally equal to the list of supported versions but can slightly
+      // differ during removal of versions across a server fleet. See
+      // draft-ietf-quic-version-negotiation for details.
+      *error_details = "Client chosen version not in other versions";
+      return false;
+    }
+  }
+  const bool ok =
+      max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
+      initial_max_data.IsValid() &&
+      initial_max_stream_data_bidi_local.IsValid() &&
+      initial_max_stream_data_bidi_remote.IsValid() &&
+      initial_max_stream_data_uni.IsValid() &&
+      initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() &&
+      ack_delay_exponent.IsValid() && max_ack_delay.IsValid() &&
+      min_ack_delay_us.IsValid() && active_connection_id_limit.IsValid() &&
+      max_datagram_frame_size.IsValid() && initial_round_trip_time_us.IsValid();
+  if (!ok) {
+    *error_details = "Invalid transport parameters " + this->ToString();
+  }
+  return ok;
+}
+
+TransportParameters::~TransportParameters() = default;
+
+bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
+                                  const TransportParameters& in,
+                                  std::vector<uint8_t>* out) {
+  std::string error_details;
+  if (!in.AreValid(&error_details)) {
+    QUIC_BUG(invalid transport parameters)
+        << "Not serializing invalid transport parameters: " << error_details;
+    return false;
+  }
+  if (!in.legacy_version_information.has_value() ||
+      in.legacy_version_information.value().version == 0 ||
+      (in.perspective == Perspective::IS_SERVER &&
+       in.legacy_version_information.value().supported_versions.empty())) {
+    QUIC_BUG(missing versions) << "Refusing to serialize without versions";
+    return false;
+  }
+  TransportParameters::ParameterMap custom_parameters = in.custom_parameters;
+  for (const auto& kv : custom_parameters) {
+    if (kv.first % 31 == 27) {
+      // See the "Reserved Transport Parameters" section of RFC 9000.
+      QUIC_BUG(custom_parameters with GREASE)
+          << "Serializing custom_parameters with GREASE ID " << kv.first
+          << " is not allowed";
+      return false;
+    }
+  }
+
+  // Maximum length of the GREASE transport parameter (see below).
+  static constexpr size_t kMaxGreaseLength = 16;
+
+  // Empirically transport parameters generally fit within 128 bytes, but we
+  // need to allocate the size up front. Integer transport parameters
+  // have a maximum encoded length of 24 bytes (3 variable length integers),
+  // other transport parameters have a length of 16 + the maximum value length.
+  static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
+  static constexpr size_t kIntegerParameterLength =
+      kTypeAndValueLength + sizeof(uint64_t);
+  static constexpr size_t kStatelessResetParameterLength =
+      kTypeAndValueLength + 16 /* stateless reset token length */;
+  static constexpr size_t kConnectionIdParameterLength =
+      kTypeAndValueLength + 255 /* maximum connection ID length */;
+  static constexpr size_t kPreferredAddressParameterLength =
+      kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
+      16 /* IPv6 address */ + 1 /* Connection ID length */ +
+      255 /* maximum connection ID length */ + 16 /* stateless reset token */;
+  static constexpr size_t kKnownTransportParamLength =
+      kConnectionIdParameterLength +      // original_destination_connection_id
+      kIntegerParameterLength +           // max_idle_timeout
+      kStatelessResetParameterLength +    // stateless_reset_token
+      kIntegerParameterLength +           // max_udp_payload_size
+      kIntegerParameterLength +           // initial_max_data
+      kIntegerParameterLength +           // initial_max_stream_data_bidi_local
+      kIntegerParameterLength +           // initial_max_stream_data_bidi_remote
+      kIntegerParameterLength +           // initial_max_stream_data_uni
+      kIntegerParameterLength +           // initial_max_streams_bidi
+      kIntegerParameterLength +           // initial_max_streams_uni
+      kIntegerParameterLength +           // ack_delay_exponent
+      kIntegerParameterLength +           // max_ack_delay
+      kIntegerParameterLength +           // min_ack_delay_us
+      kTypeAndValueLength +               // disable_active_migration
+      kPreferredAddressParameterLength +  // preferred_address
+      kIntegerParameterLength +           // active_connection_id_limit
+      kConnectionIdParameterLength +      // initial_source_connection_id
+      kConnectionIdParameterLength +      // retry_source_connection_id
+      kIntegerParameterLength +           // max_datagram_frame_size
+      kIntegerParameterLength +           // initial_round_trip_time_us
+      kTypeAndValueLength +               // google_connection_options
+      kTypeAndValueLength;                // google-version
+
+  std::vector<TransportParameters::TransportParameterId> parameter_ids = {
+      TransportParameters::kOriginalDestinationConnectionId,
+      TransportParameters::kMaxIdleTimeout,
+      TransportParameters::kStatelessResetToken,
+      TransportParameters::kMaxPacketSize,
+      TransportParameters::kInitialMaxData,
+      TransportParameters::kInitialMaxStreamDataBidiLocal,
+      TransportParameters::kInitialMaxStreamDataBidiRemote,
+      TransportParameters::kInitialMaxStreamDataUni,
+      TransportParameters::kInitialMaxStreamsBidi,
+      TransportParameters::kInitialMaxStreamsUni,
+      TransportParameters::kAckDelayExponent,
+      TransportParameters::kMaxAckDelay,
+      TransportParameters::kMinAckDelay,
+      TransportParameters::kActiveConnectionIdLimit,
+      TransportParameters::kMaxDatagramFrameSize,
+      TransportParameters::kInitialRoundTripTime,
+      TransportParameters::kDisableActiveMigration,
+      TransportParameters::kPreferredAddress,
+      TransportParameters::kInitialSourceConnectionId,
+      TransportParameters::kRetrySourceConnectionId,
+      TransportParameters::kGoogleConnectionOptions,
+      TransportParameters::kGoogleQuicVersion,
+      TransportParameters::kVersionInformation,
+  };
+
+  size_t max_transport_param_length = kKnownTransportParamLength;
+  // google_connection_options.
+  if (in.google_connection_options.has_value()) {
+    max_transport_param_length +=
+        in.google_connection_options.value().size() * sizeof(QuicTag);
+  }
+  // Google-specific version extension.
+  if (in.legacy_version_information.has_value()) {
+    max_transport_param_length +=
+        sizeof(in.legacy_version_information.value().version) +
+        1 /* versions length */ +
+        in.legacy_version_information.value().supported_versions.size() *
+            sizeof(QuicVersionLabel);
+  }
+  // version_information.
+  if (in.version_information.has_value()) {
+    max_transport_param_length +=
+        sizeof(in.version_information.value().chosen_version) +
+        // Add one for the added GREASE version.
+        (in.version_information.value().other_versions.size() + 1) *
+            sizeof(QuicVersionLabel);
+  }
+
+  // Add a random GREASE transport parameter, as defined in the
+  // "Reserved Transport Parameters" section of RFC 9000.
+  // This forces receivers to support unexpected input.
+  QuicRandom* random = QuicRandom::GetInstance();
+  // Transport parameter identifiers are 62 bits long so we need to
+  // ensure that the output of the computation below fits in 62 bits.
+  uint64_t grease_id64 = random->RandUint64() % ((1ULL << 62) - 31);
+  // Make sure grease_id % 31 == 27. Note that this is not uniformely
+  // distributed but is acceptable since no security depends on this
+  // randomness.
+  grease_id64 = (grease_id64 / 31) * 31 + 27;
+  TransportParameters::TransportParameterId grease_id =
+      static_cast<TransportParameters::TransportParameterId>(grease_id64);
+  const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
+  QUICHE_DCHECK_GE(kMaxGreaseLength, grease_length);
+  char grease_contents[kMaxGreaseLength];
+  random->RandBytes(grease_contents, grease_length);
+  custom_parameters[grease_id] = std::string(grease_contents, grease_length);
+
+  // Custom parameters.
+  for (const auto& kv : custom_parameters) {
+    max_transport_param_length += kTypeAndValueLength + kv.second.length();
+    parameter_ids.push_back(kv.first);
+  }
+
+  // Randomize order of sent transport parameters by walking the array
+  // backwards and swapping each element with a random earlier one.
+  for (size_t i = parameter_ids.size() - 1; i > 0; i--) {
+    std::swap(parameter_ids[i],
+              parameter_ids[random->InsecureRandUint64() % (i + 1)]);
+  }
+
+  out->resize(max_transport_param_length);
+  QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));
+
+  for (TransportParameters::TransportParameterId parameter_id : parameter_ids) {
+    switch (parameter_id) {
+      // original_destination_connection_id
+      case TransportParameters::kOriginalDestinationConnectionId: {
+        if (in.original_destination_connection_id.has_value()) {
+          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+          QuicConnectionId original_destination_connection_id =
+              in.original_destination_connection_id.value();
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kOriginalDestinationConnectionId) ||
+              !writer.WriteStringPieceVarInt62(absl::string_view(
+                  original_destination_connection_id.data(),
+                  original_destination_connection_id.length()))) {
+            QUIC_BUG(Failed to write original_destination_connection_id)
+                << "Failed to write original_destination_connection_id "
+                << original_destination_connection_id << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // max_idle_timeout
+      case TransportParameters::kMaxIdleTimeout: {
+        if (!in.max_idle_timeout_ms.Write(&writer)) {
+          QUIC_BUG(Failed to write idle_timeout)
+              << "Failed to write idle_timeout for " << in;
+          return false;
+        }
+      } break;
+      // stateless_reset_token
+      case TransportParameters::kStatelessResetToken: {
+        if (!in.stateless_reset_token.empty()) {
+          QUICHE_DCHECK_EQ(kStatelessResetTokenLength,
+                           in.stateless_reset_token.size());
+          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kStatelessResetToken) ||
+              !writer.WriteStringPieceVarInt62(
+                  absl::string_view(reinterpret_cast<const char*>(
+                                        in.stateless_reset_token.data()),
+                                    in.stateless_reset_token.size()))) {
+            QUIC_BUG(Failed to write stateless_reset_token)
+                << "Failed to write stateless_reset_token of length "
+                << in.stateless_reset_token.size() << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // max_udp_payload_size
+      case TransportParameters::kMaxPacketSize: {
+        if (!in.max_udp_payload_size.Write(&writer)) {
+          QUIC_BUG(Failed to write max_udp_payload_size)
+              << "Failed to write max_udp_payload_size for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_data
+      case TransportParameters::kInitialMaxData: {
+        if (!in.initial_max_data.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_data)
+              << "Failed to write initial_max_data for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_stream_data_bidi_local
+      case TransportParameters::kInitialMaxStreamDataBidiLocal: {
+        if (!in.initial_max_stream_data_bidi_local.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_stream_data_bidi_local)
+              << "Failed to write initial_max_stream_data_bidi_local for "
+              << in;
+          return false;
+        }
+      } break;
+      // initial_max_stream_data_bidi_remote
+      case TransportParameters::kInitialMaxStreamDataBidiRemote: {
+        if (!in.initial_max_stream_data_bidi_remote.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_stream_data_bidi_remote)
+              << "Failed to write initial_max_stream_data_bidi_remote for "
+              << in;
+          return false;
+        }
+      } break;
+      // initial_max_stream_data_uni
+      case TransportParameters::kInitialMaxStreamDataUni: {
+        if (!in.initial_max_stream_data_uni.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_stream_data_uni)
+              << "Failed to write initial_max_stream_data_uni for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_streams_bidi
+      case TransportParameters::kInitialMaxStreamsBidi: {
+        if (!in.initial_max_streams_bidi.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_streams_bidi)
+              << "Failed to write initial_max_streams_bidi for " << in;
+          return false;
+        }
+      } break;
+      // initial_max_streams_uni
+      case TransportParameters::kInitialMaxStreamsUni: {
+        if (!in.initial_max_streams_uni.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_max_streams_uni)
+              << "Failed to write initial_max_streams_uni for " << in;
+          return false;
+        }
+      } break;
+      // ack_delay_exponent
+      case TransportParameters::kAckDelayExponent: {
+        if (!in.ack_delay_exponent.Write(&writer)) {
+          QUIC_BUG(Failed to write ack_delay_exponent)
+              << "Failed to write ack_delay_exponent for " << in;
+          return false;
+        }
+      } break;
+      // max_ack_delay
+      case TransportParameters::kMaxAckDelay: {
+        if (!in.max_ack_delay.Write(&writer)) {
+          QUIC_BUG(Failed to write max_ack_delay)
+              << "Failed to write max_ack_delay for " << in;
+          return false;
+        }
+      } break;
+      // min_ack_delay_us
+      case TransportParameters::kMinAckDelay: {
+        if (!in.min_ack_delay_us.Write(&writer)) {
+          QUIC_BUG(Failed to write min_ack_delay_us)
+              << "Failed to write min_ack_delay_us for " << in;
+          return false;
+        }
+      } break;
+      // active_connection_id_limit
+      case TransportParameters::kActiveConnectionIdLimit: {
+        if (!in.active_connection_id_limit.Write(&writer)) {
+          QUIC_BUG(Failed to write active_connection_id_limit)
+              << "Failed to write active_connection_id_limit for " << in;
+          return false;
+        }
+      } break;
+      // max_datagram_frame_size
+      case TransportParameters::kMaxDatagramFrameSize: {
+        if (!in.max_datagram_frame_size.Write(&writer)) {
+          QUIC_BUG(Failed to write max_datagram_frame_size)
+              << "Failed to write max_datagram_frame_size for " << in;
+          return false;
+        }
+      } break;
+      // initial_round_trip_time_us
+      case TransportParameters::kInitialRoundTripTime: {
+        if (!in.initial_round_trip_time_us.Write(&writer)) {
+          QUIC_BUG(Failed to write initial_round_trip_time_us)
+              << "Failed to write initial_round_trip_time_us for " << in;
+          return false;
+        }
+      } break;
+      // disable_active_migration
+      case TransportParameters::kDisableActiveMigration: {
+        if (in.disable_active_migration) {
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kDisableActiveMigration) ||
+              !writer.WriteVarInt62(/* transport parameter length */ 0)) {
+            QUIC_BUG(Failed to write disable_active_migration)
+                << "Failed to write disable_active_migration for " << in;
+            return false;
+          }
+        }
+      } break;
+      // preferred_address
+      case TransportParameters::kPreferredAddress: {
+        if (in.preferred_address) {
+          std::string v4_address_bytes =
+              in.preferred_address->ipv4_socket_address.host().ToPackedString();
+          std::string v6_address_bytes =
+              in.preferred_address->ipv6_socket_address.host().ToPackedString();
+          if (v4_address_bytes.length() != 4 ||
+              v6_address_bytes.length() != 16 ||
+              in.preferred_address->stateless_reset_token.size() !=
+                  kStatelessResetTokenLength) {
+            QUIC_BUG(quic_bug_10743_12)
+                << "Bad lengths " << *in.preferred_address;
+            return false;
+          }
+          const uint64_t preferred_address_length =
+              v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
+              v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
+              /* connection ID length byte */ sizeof(uint8_t) +
+              in.preferred_address->connection_id.length() +
+              in.preferred_address->stateless_reset_token.size();
+          if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
+              !writer.WriteVarInt62(
+                  /* transport parameter length */ preferred_address_length) ||
+              !writer.WriteStringPiece(v4_address_bytes) ||
+              !writer.WriteUInt16(
+                  in.preferred_address->ipv4_socket_address.port()) ||
+              !writer.WriteStringPiece(v6_address_bytes) ||
+              !writer.WriteUInt16(
+                  in.preferred_address->ipv6_socket_address.port()) ||
+              !writer.WriteUInt8(
+                  in.preferred_address->connection_id.length()) ||
+              !writer.WriteBytes(
+                  in.preferred_address->connection_id.data(),
+                  in.preferred_address->connection_id.length()) ||
+              !writer.WriteBytes(
+                  in.preferred_address->stateless_reset_token.data(),
+                  in.preferred_address->stateless_reset_token.size())) {
+            QUIC_BUG(Failed to write preferred_address)
+                << "Failed to write preferred_address for " << in;
+            return false;
+          }
+        }
+      } break;
+      // initial_source_connection_id
+      case TransportParameters::kInitialSourceConnectionId: {
+        if (in.initial_source_connection_id.has_value()) {
+          QuicConnectionId initial_source_connection_id =
+              in.initial_source_connection_id.value();
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kInitialSourceConnectionId) ||
+              !writer.WriteStringPieceVarInt62(
+                  absl::string_view(initial_source_connection_id.data(),
+                                    initial_source_connection_id.length()))) {
+            QUIC_BUG(Failed to write initial_source_connection_id)
+                << "Failed to write initial_source_connection_id "
+                << initial_source_connection_id << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // retry_source_connection_id
+      case TransportParameters::kRetrySourceConnectionId: {
+        if (in.retry_source_connection_id.has_value()) {
+          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+          QuicConnectionId retry_source_connection_id =
+              in.retry_source_connection_id.value();
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kRetrySourceConnectionId) ||
+              !writer.WriteStringPieceVarInt62(
+                  absl::string_view(retry_source_connection_id.data(),
+                                    retry_source_connection_id.length()))) {
+            QUIC_BUG(Failed to write retry_source_connection_id)
+                << "Failed to write retry_source_connection_id "
+                << retry_source_connection_id << " for " << in;
+            return false;
+          }
+        }
+      } break;
+      // Google-specific connection options.
+      case TransportParameters::kGoogleConnectionOptions: {
+        if (in.google_connection_options.has_value()) {
+          static_assert(
+              sizeof(in.google_connection_options.value().front()) == 4,
+              "bad size");
+          uint64_t connection_options_length =
+              in.google_connection_options.value().size() * 4;
+          if (!writer.WriteVarInt62(
+                  TransportParameters::kGoogleConnectionOptions) ||
+              !writer.WriteVarInt62(
+                  /* transport parameter length */ connection_options_length)) {
+            QUIC_BUG(Failed to write google_connection_options)
+                << "Failed to write google_connection_options of length "
+                << connection_options_length << " for " << in;
+            return false;
+          }
+          for (const QuicTag& connection_option :
+               in.google_connection_options.value()) {
+            if (!writer.WriteTag(connection_option)) {
+              QUIC_BUG(Failed to write google_connection_option)
+                  << "Failed to write google_connection_option "
+                  << QuicTagToString(connection_option) << " for " << in;
+              return false;
+            }
+          }
+        }
+      } break;
+      // Google-specific version extension.
+      case TransportParameters::kGoogleQuicVersion: {
+        if (!in.legacy_version_information.has_value()) {
+          break;
+        }
+        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
+                      "bad length");
+        uint64_t google_version_length =
+            sizeof(in.legacy_version_information.value().version);
+        if (in.perspective == Perspective::IS_SERVER) {
+          google_version_length +=
+              /* versions length */ sizeof(uint8_t) +
+              sizeof(QuicVersionLabel) * in.legacy_version_information.value()
+                                             .supported_versions.size();
+        }
+        if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
+            !writer.WriteVarInt62(
+                /* transport parameter length */ google_version_length) ||
+            !writer.WriteUInt32(
+                in.legacy_version_information.value().version)) {
+          QUIC_BUG(Failed to write Google version extension)
+              << "Failed to write Google version extension for " << in;
+          return false;
+        }
+        if (in.perspective == Perspective::IS_SERVER) {
+          if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
+                                 in.legacy_version_information.value()
+                                     .supported_versions.size())) {
+            QUIC_BUG(Failed to write versions length)
+                << "Failed to write versions length for " << in;
+            return false;
+          }
+          for (QuicVersionLabel version_label :
+               in.legacy_version_information.value().supported_versions) {
+            if (!writer.WriteUInt32(version_label)) {
+              QUIC_BUG(Failed to write supported version)
+                  << "Failed to write supported version for " << in;
+              return false;
+            }
+          }
+        }
+      } break;
+      // version_information.
+      case TransportParameters::kVersionInformation: {
+        if (!in.version_information.has_value()) {
+          break;
+        }
+        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
+                      "bad length");
+        QuicVersionLabelVector other_versions =
+            in.version_information.value().other_versions;
+        // Insert one GREASE version at a random index.
+        const size_t grease_index =
+            random->InsecureRandUint64() % (other_versions.size() + 1);
+        other_versions.insert(
+            other_versions.begin() + grease_index,
+            CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
+        const uint64_t version_information_length =
+            sizeof(in.version_information.value().chosen_version) +
+            sizeof(QuicVersionLabel) * other_versions.size();
+        if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
+            !writer.WriteVarInt62(
+                /* transport parameter length */ version_information_length) ||
+            !writer.WriteUInt32(
+                in.version_information.value().chosen_version)) {
+          QUIC_BUG(Failed to write chosen version)
+              << "Failed to write chosen version for " << in;
+          return false;
+        }
+        for (QuicVersionLabel version_label : other_versions) {
+          if (!writer.WriteUInt32(version_label)) {
+            QUIC_BUG(Failed to write other version)
+                << "Failed to write other version for " << in;
+            return false;
+          }
+        }
+      } break;
+      // Custom parameters and GREASE.
+      default: {
+        auto it = custom_parameters.find(parameter_id);
+        if (it == custom_parameters.end()) {
+          QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
+          return false;
+        }
+        if (!writer.WriteVarInt62(parameter_id) ||
+            !writer.WriteStringPieceVarInt62(it->second)) {
+          QUIC_BUG(Failed to write custom parameter)
+              << "Failed to write custom parameter " << parameter_id;
+          return false;
+        }
+      } break;
+    }
+  }
+
+  out->resize(writer.length());
+
+  QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
+                  << " bytes";
+
+  return true;
+}
+
+bool ParseTransportParameters(ParsedQuicVersion version,
+                              Perspective perspective,
+                              const uint8_t* in,
+                              size_t in_len,
+                              TransportParameters* out,
+                              std::string* error_details) {
+  out->perspective = perspective;
+  QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);
+
+  while (!reader.IsDoneReading()) {
+    uint64_t param_id64;
+    if (!reader.ReadVarInt62(&param_id64)) {
+      *error_details = "Failed to parse transport parameter ID";
+      return false;
+    }
+    TransportParameters::TransportParameterId param_id =
+        static_cast<TransportParameters::TransportParameterId>(param_id64);
+    absl::string_view value;
+    if (!reader.ReadStringPieceVarInt62(&value)) {
+      *error_details =
+          "Failed to read length and value of transport parameter " +
+          TransportParameterIdToString(param_id);
+      return false;
+    }
+    QuicDataReader value_reader(value);
+    bool parse_success = true;
+    switch (param_id) {
+      case TransportParameters::kOriginalDestinationConnectionId: {
+        if (out->original_destination_connection_id.has_value()) {
+          *error_details =
+              "Received a second original_destination_connection_id";
+          return false;
+        }
+        const size_t connection_id_length = value_reader.BytesRemaining();
+        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+                connection_id_length, version.transport_version)) {
+          *error_details = absl::StrCat(
+              "Received original_destination_connection_id of invalid length ",
+              connection_id_length);
+          return false;
+        }
+        QuicConnectionId original_destination_connection_id;
+        if (!value_reader.ReadConnectionId(&original_destination_connection_id,
+                                           connection_id_length)) {
+          *error_details = "Failed to read original_destination_connection_id";
+          return false;
+        }
+        out->original_destination_connection_id =
+            original_destination_connection_id;
+      } break;
+      case TransportParameters::kMaxIdleTimeout:
+        parse_success =
+            out->max_idle_timeout_ms.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kStatelessResetToken: {
+        if (!out->stateless_reset_token.empty()) {
+          *error_details = "Received a second stateless_reset_token";
+          return false;
+        }
+        absl::string_view stateless_reset_token =
+            value_reader.ReadRemainingPayload();
+        if (stateless_reset_token.length() != kStatelessResetTokenLength) {
+          *error_details =
+              absl::StrCat("Received stateless_reset_token of invalid length ",
+                           stateless_reset_token.length());
+          return false;
+        }
+        out->stateless_reset_token.assign(
+            stateless_reset_token.data(),
+            stateless_reset_token.data() + stateless_reset_token.length());
+      } break;
+      case TransportParameters::kMaxPacketSize:
+        parse_success =
+            out->max_udp_payload_size.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxData:
+        parse_success =
+            out->initial_max_data.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamDataBidiLocal:
+        parse_success = out->initial_max_stream_data_bidi_local.Read(
+            &value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamDataBidiRemote:
+        parse_success = out->initial_max_stream_data_bidi_remote.Read(
+            &value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamDataUni:
+        parse_success =
+            out->initial_max_stream_data_uni.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamsBidi:
+        parse_success =
+            out->initial_max_streams_bidi.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialMaxStreamsUni:
+        parse_success =
+            out->initial_max_streams_uni.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kAckDelayExponent:
+        parse_success =
+            out->ack_delay_exponent.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kMaxAckDelay:
+        parse_success = out->max_ack_delay.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kDisableActiveMigration:
+        if (out->disable_active_migration) {
+          *error_details = "Received a second disable_active_migration";
+          return false;
+        }
+        out->disable_active_migration = true;
+        break;
+      case TransportParameters::kPreferredAddress: {
+        TransportParameters::PreferredAddress preferred_address;
+        uint16_t ipv4_port, ipv6_port;
+        in_addr ipv4_address;
+        in6_addr ipv6_address;
+        preferred_address.stateless_reset_token.resize(
+            kStatelessResetTokenLength);
+        if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
+            !value_reader.ReadUInt16(&ipv4_port) ||
+            !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
+            !value_reader.ReadUInt16(&ipv6_port) ||
+            !value_reader.ReadLengthPrefixedConnectionId(
+                &preferred_address.connection_id) ||
+            !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
+                                    kStatelessResetTokenLength)) {
+          *error_details = "Failed to read preferred_address";
+          return false;
+        }
+        preferred_address.ipv4_socket_address =
+            QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
+        preferred_address.ipv6_socket_address =
+            QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
+        if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
+            !preferred_address.ipv6_socket_address.host().IsIPv6()) {
+          *error_details = "Received preferred_address of bad families " +
+                           preferred_address.ToString();
+          return false;
+        }
+        if (!QuicUtils::IsConnectionIdValidForVersion(
+                preferred_address.connection_id, version.transport_version)) {
+          *error_details = "Received invalid preferred_address connection ID " +
+                           preferred_address.ToString();
+          return false;
+        }
+        out->preferred_address =
+            std::make_unique<TransportParameters::PreferredAddress>(
+                preferred_address);
+      } break;
+      case TransportParameters::kActiveConnectionIdLimit:
+        parse_success =
+            out->active_connection_id_limit.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialSourceConnectionId: {
+        if (out->initial_source_connection_id.has_value()) {
+          *error_details = "Received a second initial_source_connection_id";
+          return false;
+        }
+        const size_t connection_id_length = value_reader.BytesRemaining();
+        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+                connection_id_length, version.transport_version)) {
+          *error_details = absl::StrCat(
+              "Received initial_source_connection_id of invalid length ",
+              connection_id_length);
+          return false;
+        }
+        QuicConnectionId initial_source_connection_id;
+        if (!value_reader.ReadConnectionId(&initial_source_connection_id,
+                                           connection_id_length)) {
+          *error_details = "Failed to read initial_source_connection_id";
+          return false;
+        }
+        out->initial_source_connection_id = initial_source_connection_id;
+      } break;
+      case TransportParameters::kRetrySourceConnectionId: {
+        if (out->retry_source_connection_id.has_value()) {
+          *error_details = "Received a second retry_source_connection_id";
+          return false;
+        }
+        const size_t connection_id_length = value_reader.BytesRemaining();
+        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+                connection_id_length, version.transport_version)) {
+          *error_details = absl::StrCat(
+              "Received retry_source_connection_id of invalid length ",
+              connection_id_length);
+          return false;
+        }
+        QuicConnectionId retry_source_connection_id;
+        if (!value_reader.ReadConnectionId(&retry_source_connection_id,
+                                           connection_id_length)) {
+          *error_details = "Failed to read retry_source_connection_id";
+          return false;
+        }
+        out->retry_source_connection_id = retry_source_connection_id;
+      } break;
+      case TransportParameters::kMaxDatagramFrameSize:
+        parse_success =
+            out->max_datagram_frame_size.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kInitialRoundTripTime:
+        parse_success =
+            out->initial_round_trip_time_us.Read(&value_reader, error_details);
+        break;
+      case TransportParameters::kGoogleConnectionOptions: {
+        if (out->google_connection_options.has_value()) {
+          *error_details = "Received a second google_connection_options";
+          return false;
+        }
+        out->google_connection_options = QuicTagVector{};
+        while (!value_reader.IsDoneReading()) {
+          QuicTag connection_option;
+          if (!value_reader.ReadTag(&connection_option)) {
+            *error_details = "Failed to read a google_connection_options";
+            return false;
+          }
+          out->google_connection_options.value().push_back(connection_option);
+        }
+      } break;
+      case TransportParameters::kGoogleQuicVersion: {
+        if (!out->legacy_version_information.has_value()) {
+          out->legacy_version_information =
+              TransportParameters::LegacyVersionInformation();
+        }
+        if (!value_reader.ReadUInt32(
+                &out->legacy_version_information.value().version)) {
+          *error_details = "Failed to read Google version extension version";
+          return false;
+        }
+        if (perspective == Perspective::IS_SERVER) {
+          uint8_t versions_length;
+          if (!value_reader.ReadUInt8(&versions_length)) {
+            *error_details = "Failed to parse Google supported versions length";
+            return false;
+          }
+          const uint8_t num_versions = versions_length / sizeof(uint32_t);
+          for (uint8_t i = 0; i < num_versions; ++i) {
+            QuicVersionLabel version;
+            if (!value_reader.ReadUInt32(&version)) {
+              *error_details = "Failed to parse Google supported version";
+              return false;
+            }
+            out->legacy_version_information.value()
+                .supported_versions.push_back(version);
+          }
+        }
+      } break;
+      case TransportParameters::kVersionInformation: {
+        if (out->version_information.has_value()) {
+          *error_details = "Received a second version_information";
+          return false;
+        }
+        out->version_information = TransportParameters::VersionInformation();
+        if (!value_reader.ReadUInt32(
+                &out->version_information.value().chosen_version)) {
+          *error_details = "Failed to read chosen version";
+          return false;
+        }
+        while (!value_reader.IsDoneReading()) {
+          QuicVersionLabel other_version;
+          if (!value_reader.ReadUInt32(&other_version)) {
+            *error_details = "Failed to parse other version";
+            return false;
+          }
+          out->version_information.value().other_versions.push_back(
+              other_version);
+        }
+      } break;
+      case TransportParameters::kMinAckDelay:
+        parse_success =
+            out->min_ack_delay_us.Read(&value_reader, error_details);
+        break;
+      default:
+        if (out->custom_parameters.find(param_id) !=
+            out->custom_parameters.end()) {
+          *error_details = "Received a second unknown parameter" +
+                           TransportParameterIdToString(param_id);
+          return false;
+        }
+        out->custom_parameters[param_id] =
+            std::string(value_reader.ReadRemainingPayload());
+        break;
+    }
+    if (!parse_success) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+    if (!value_reader.IsDoneReading()) {
+      *error_details = absl::StrCat(
+          "Received unexpected ", value_reader.BytesRemaining(),
+          " bytes after parsing ", TransportParameterIdToString(param_id));
+      return false;
+    }
+  }
+
+  if (!out->AreValid(error_details)) {
+    QUICHE_DCHECK(!error_details->empty());
+    return false;
+  }
+
+  QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
+                  << in_len << " bytes";
+
+  return true;
+}
+
+namespace {
+
+bool DigestUpdateIntegerParam(
+    EVP_MD_CTX* hash_ctx,
+    const TransportParameters::IntegerParameter& param) {
+  uint64_t value = param.value();
+  return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
+}
+
+}  // namespace
+
+bool SerializeTransportParametersForTicket(
+    const TransportParameters& in,
+    const std::vector<uint8_t>& application_data,
+    std::vector<uint8_t>* out) {
+  std::string error_details;
+  if (!in.AreValid(&error_details)) {
+    QUIC_BUG(quic_bug_10743_26)
+        << "Not serializing invalid transport parameters: " << error_details;
+    return false;
+  }
+
+  out->resize(SHA256_DIGEST_LENGTH + 1);
+  const uint8_t serialization_version = 0;
+  (*out)[0] = serialization_version;
+
+  bssl::ScopedEVP_MD_CTX hash_ctx;
+  // Write application data:
+  uint64_t app_data_len = application_data.size();
+  const uint64_t parameter_version = 0;
+  // The format of the input to the hash function is as follows:
+  // - The application data, prefixed with a 64-bit length field.
+  // - Transport parameters:
+  //   - A 64-bit version field indicating which version of encoding is used
+  //     for transport parameters.
+  //   - A list of 64-bit integers representing the relevant parameters.
+  //
+  //   When changing which parameters are included, additional parameters can be
+  //   added to the end of the list without changing the version field. New
+  //   parameters that are variable length must be length prefixed. If
+  //   parameters are removed from the list, the version field must be
+  //   incremented.
+  //
+  // Integers happen to be written in host byte order, not network byte order.
+  if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
+      !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
+      !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
+                        application_data.size()) ||
+      !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
+                        sizeof(parameter_version))) {
+    QUIC_BUG(quic_bug_10743_27)
+        << "Unexpected failure of EVP_Digest functions when hashing "
+           "Transport Parameters for ticket";
+    return false;
+  }
+
+  // Write transport parameters specified by draft-ietf-quic-transport-28,
+  // section 7.4.1, that are remembered for 0-RTT.
+  if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.initial_max_stream_data_bidi_local) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.initial_max_stream_data_bidi_remote) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.initial_max_stream_data_uni) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
+      !DigestUpdateIntegerParam(hash_ctx.get(),
+                                in.active_connection_id_limit)) {
+    QUIC_BUG(quic_bug_10743_28)
+        << "Unexpected failure of EVP_Digest functions when hashing "
+           "Transport Parameters for ticket";
+    return false;
+  }
+  uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
+  if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
+                        sizeof(disable_active_migration)) ||
+      !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
+    QUIC_BUG(quic_bug_10743_29)
+        << "Unexpected failure of EVP_Digest functions when hashing "
+           "Transport Parameters for ticket";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/transport_parameters.h b/quiche/quic/core/crypto/transport_parameters.h
new file mode 100644
index 0000000..7ccd557
--- /dev/null
+++ b/quiche/quic/core/crypto/transport_parameters.h
@@ -0,0 +1,314 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
+#define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// TransportParameters contains parameters for QUIC's transport layer that are
+// exchanged during the TLS handshake. This struct is a mirror of the struct in
+// the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
+// This struct currently uses the values from draft 29.
+struct QUIC_EXPORT_PRIVATE TransportParameters {
+  // The identifier used to differentiate transport parameters.
+  enum TransportParameterId : uint64_t;
+  // A map used to specify custom parameters.
+  using ParameterMap = absl::flat_hash_map<TransportParameterId, std::string>;
+  // Represents an individual QUIC transport parameter that only encodes a
+  // variable length integer. Can only be created inside the constructor for
+  // TransportParameters.
+  class QUIC_EXPORT_PRIVATE IntegerParameter {
+   public:
+    // Forbid constructing and copying apart from TransportParameters.
+    IntegerParameter() = delete;
+    IntegerParameter& operator=(const IntegerParameter&) = delete;
+    // Sets the value of this transport parameter.
+    void set_value(uint64_t value);
+    // Gets the value of this transport parameter.
+    uint64_t value() const;
+    // Validates whether the current value is valid.
+    bool IsValid() const;
+    // Writes to a crypto byte buffer, used during serialization. Does not write
+    // anything if the value is equal to the parameter's default value.
+    // Returns whether the write was successful.
+    bool Write(QuicDataWriter* writer) const;
+    // Reads from a crypto byte string, used during parsing.
+    // Returns whether the read was successful.
+    // On failure, this method will write a human-readable error message to
+    // |error_details|.
+    bool Read(QuicDataReader* reader, std::string* error_details);
+    // operator<< allows easily logging integer transport parameters.
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const IntegerParameter& param);
+
+   private:
+    friend struct TransportParameters;
+    // Constructors for initial setup used by TransportParameters only.
+    // This constructor sets |default_value| and |min_value| to 0, and
+    // |max_value| to kVarInt62MaxValue.
+    explicit IntegerParameter(TransportParameterId param_id);
+    IntegerParameter(TransportParameterId param_id,
+                     uint64_t default_value,
+                     uint64_t min_value,
+                     uint64_t max_value);
+    IntegerParameter(const IntegerParameter& other) = default;
+    IntegerParameter(IntegerParameter&& other) = default;
+    // Human-readable string representation.
+    std::string ToString(bool for_use_in_list) const;
+
+    // Number used to indicate this transport parameter.
+    TransportParameterId param_id_;
+    // Current value of the transport parameter.
+    uint64_t value_;
+    // Default value of this transport parameter, as per IETF specification.
+    const uint64_t default_value_;
+    // Minimum value of this transport parameter, as per IETF specification.
+    const uint64_t min_value_;
+    // Maximum value of this transport parameter, as per IETF specification.
+    const uint64_t max_value_;
+    // Ensures this parameter is not parsed twice in the same message.
+    bool has_been_read_;
+  };
+
+  // Represents the preferred_address transport parameter that a server can
+  // send to clients.
+  struct QUIC_EXPORT_PRIVATE PreferredAddress {
+    PreferredAddress();
+    PreferredAddress(const PreferredAddress& other) = default;
+    PreferredAddress(PreferredAddress&& other) = default;
+    ~PreferredAddress();
+    bool operator==(const PreferredAddress& rhs) const;
+    bool operator!=(const PreferredAddress& rhs) const;
+
+    QuicSocketAddress ipv4_socket_address;
+    QuicSocketAddress ipv6_socket_address;
+    QuicConnectionId connection_id;
+    std::vector<uint8_t> stateless_reset_token;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const TransportParameters& params);
+  };
+
+  // LegacyVersionInformation represents the Google QUIC downgrade prevention
+  // mechanism ported to QUIC+TLS. It is exchanged using transport parameter ID
+  // 0x4752 and will eventually be deprecated in favor of
+  // draft-ietf-quic-version-negotiation.
+  struct QUIC_EXPORT_PRIVATE LegacyVersionInformation {
+    LegacyVersionInformation();
+    LegacyVersionInformation(const LegacyVersionInformation& other) = default;
+    LegacyVersionInformation& operator=(const LegacyVersionInformation& other) =
+        default;
+    LegacyVersionInformation& operator=(LegacyVersionInformation&& other) =
+        default;
+    LegacyVersionInformation(LegacyVersionInformation&& other) = default;
+    ~LegacyVersionInformation() = default;
+    bool operator==(const LegacyVersionInformation& rhs) const;
+    bool operator!=(const LegacyVersionInformation& rhs) const;
+    // When sent by the client, |version| is the initial version offered by the
+    // client (before any version negotiation packets) for this connection. When
+    // sent by the server, |version| is the version that is in use.
+    QuicVersionLabel version;
+
+    // When sent by the server, |supported_versions| contains a list of all
+    // versions that the server would send in a version negotiation packet. When
+    // sent by the client, this is empty.
+    QuicVersionLabelVector supported_versions;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os,
+        const LegacyVersionInformation& legacy_version_information);
+  };
+
+  // Version information used for version downgrade prevention and compatible
+  // version negotiation. See draft-ietf-quic-version-negotiation-05.
+  struct QUIC_EXPORT_PRIVATE VersionInformation {
+    VersionInformation();
+    VersionInformation(const VersionInformation& other) = default;
+    VersionInformation& operator=(const VersionInformation& other) = default;
+    VersionInformation& operator=(VersionInformation&& other) = default;
+    VersionInformation(VersionInformation&& other) = default;
+    ~VersionInformation() = default;
+    bool operator==(const VersionInformation& rhs) const;
+    bool operator!=(const VersionInformation& rhs) const;
+
+    // Version that the sender has chosen to use on this connection.
+    QuicVersionLabel chosen_version;
+
+    // When sent by the client, |other_versions| contains all the versions that
+    // this first flight is compatible with. When sent by the server,
+    // |other_versions| contains all of the versions supported by the server.
+    QuicVersionLabelVector other_versions;
+
+    // Allows easily logging.
+    std::string ToString() const;
+    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+        std::ostream& os, const VersionInformation& version_information);
+  };
+
+  TransportParameters();
+  TransportParameters(const TransportParameters& other);
+  ~TransportParameters();
+  bool operator==(const TransportParameters& rhs) const;
+  bool operator!=(const TransportParameters& rhs) const;
+
+  // Represents the sender of the transport parameters. When |perspective| is
+  // Perspective::IS_CLIENT, this struct is being used in the client_hello
+  // handshake message; when it is Perspective::IS_SERVER, it is being used in
+  // the encrypted_extensions handshake message.
+  Perspective perspective;
+
+  // Google QUIC downgrade prevention mechanism sent over QUIC+TLS.
+  absl::optional<LegacyVersionInformation> legacy_version_information;
+
+  // IETF downgrade prevention and compatible version negotiation, see
+  // draft-ietf-quic-version-negotiation.
+  absl::optional<VersionInformation> version_information;
+
+  // The value of the Destination Connection ID field from the first
+  // Initial packet sent by the client.
+  absl::optional<QuicConnectionId> original_destination_connection_id;
+
+  // Maximum idle timeout expressed in milliseconds.
+  IntegerParameter max_idle_timeout_ms;
+
+  // Stateless reset token used in verifying stateless resets.
+  std::vector<uint8_t> stateless_reset_token;
+
+  // Limits the size of packets that the endpoint is willing to receive.
+  // This indicates that packets larger than this limit will be dropped.
+  IntegerParameter max_udp_payload_size;
+
+  // Contains the initial value for the maximum amount of data that can
+  // be sent on the connection.
+  IntegerParameter initial_max_data;
+
+  // Initial flow control limit for locally-initiated bidirectional streams.
+  IntegerParameter initial_max_stream_data_bidi_local;
+
+  // Initial flow control limit for peer-initiated bidirectional streams.
+  IntegerParameter initial_max_stream_data_bidi_remote;
+
+  // Initial flow control limit for unidirectional streams.
+  IntegerParameter initial_max_stream_data_uni;
+
+  // Initial maximum number of bidirectional streams the peer may initiate.
+  IntegerParameter initial_max_streams_bidi;
+
+  // Initial maximum number of unidirectional streams the peer may initiate.
+  IntegerParameter initial_max_streams_uni;
+
+  // Exponent used to decode the ACK Delay field in ACK frames.
+  IntegerParameter ack_delay_exponent;
+
+  // Maximum amount of time in milliseconds by which the endpoint will
+  // delay sending acknowledgments.
+  IntegerParameter max_ack_delay;
+
+  // Minimum amount of time in microseconds by which the endpoint will
+  // delay sending acknowledgments. Used to enable sender control of ack delay.
+  IntegerParameter min_ack_delay_us;
+
+  // Indicates lack of support for connection migration.
+  bool disable_active_migration;
+
+  // Used to effect a change in server address at the end of the handshake.
+  std::unique_ptr<PreferredAddress> preferred_address;
+
+  // Maximum number of connection IDs from the peer that an endpoint is willing
+  // to store.
+  IntegerParameter active_connection_id_limit;
+
+  // The value that the endpoint included in the Source Connection ID field of
+  // the first Initial packet it sent.
+  absl::optional<QuicConnectionId> initial_source_connection_id;
+
+  // The value that the server included in the Source Connection ID field of a
+  // Retry packet it sent.
+  absl::optional<QuicConnectionId> retry_source_connection_id;
+
+  // Indicates support for the DATAGRAM frame and the maximum frame size that
+  // the sender accepts. See draft-ietf-quic-datagram.
+  IntegerParameter max_datagram_frame_size;
+
+  // Google-specific transport parameter that carries an estimate of the
+  // initial round-trip time in microseconds.
+  IntegerParameter initial_round_trip_time_us;
+
+  // Google-specific connection options.
+  absl::optional<QuicTagVector> google_connection_options;
+
+  // Validates whether transport parameters are valid according to
+  // the specification. If the transport parameters are not valid, this method
+  // will write a human-readable error message to |error_details|.
+  bool AreValid(std::string* error_details) const;
+
+  // Custom parameters that may be specific to application protocol.
+  ParameterMap custom_parameters;
+
+  // Allows easily logging transport parameters.
+  std::string ToString() const;
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const TransportParameters& params);
+};
+
+// Serializes a TransportParameters struct into the format for sending it in a
+// TLS extension. The serialized bytes are written to |*out|. Returns if the
+// parameters are valid and serialization succeeded.
+QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
+    ParsedQuicVersion version,
+    const TransportParameters& in,
+    std::vector<uint8_t>* out);
+
+// Parses bytes from the quic_transport_parameters TLS extension and writes the
+// parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
+// |perspective| indicates whether the input came from a client or a server.
+// This method returns true if the input was successfully parsed.
+// On failure, this method will write a human-readable error message to
+// |error_details|.
+QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
+                                                  Perspective perspective,
+                                                  const uint8_t* in,
+                                                  size_t in_len,
+                                                  TransportParameters* out,
+                                                  std::string* error_details);
+
+// Serializes |in| and |application_data| in a deterministic format so that
+// multiple calls to SerializeTransportParametersForTicket with the same inputs
+// will generate the same output, and if the inputs differ, then the output will
+// differ. The output of this function is used by the server in
+// SSL_set_quic_early_data_context to determine whether early data should be
+// accepted: Early data will only be accepted if the inputs to this function
+// match what they were on the connection that issued an early data capable
+// ticket.
+QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
+    const TransportParameters& in,
+    const std::vector<uint8_t>& application_data,
+    std::vector<uint8_t>* out);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
diff --git a/quiche/quic/core/crypto/transport_parameters_test.cc b/quiche/quic/core/crypto/transport_parameters_test.cc
new file mode 100644
index 0000000..fea6608
--- /dev/null
+++ b/quiche/quic/core/crypto/transport_parameters_test.cc
@@ -0,0 +1,1131 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/transport_parameters.h"
+
+#include <cstring>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const QuicVersionLabel kFakeVersionLabel = 0x01234567;
+const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
+const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
+const uint64_t kFakeInitialMaxData = 101;
+const uint64_t kFakeInitialMaxStreamDataBidiLocal = 2001;
+const uint64_t kFakeInitialMaxStreamDataBidiRemote = 2002;
+const uint64_t kFakeInitialMaxStreamDataUni = 3000;
+const uint64_t kFakeInitialMaxStreamsBidi = 21;
+const uint64_t kFakeInitialMaxStreamsUni = 22;
+const bool kFakeDisableMigration = true;
+const uint64_t kFakeInitialRoundTripTime = 53;
+const uint8_t kFakePreferredStatelessResetTokenData[16] = {
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
+
+const auto kCustomParameter1 =
+    static_cast<TransportParameters::TransportParameterId>(0xffcd);
+const char* kCustomParameter1Value = "foo";
+const auto kCustomParameter2 =
+    static_cast<TransportParameters::TransportParameterId>(0xff34);
+const char* kCustomParameter2Value = "bar";
+
+QuicConnectionId CreateFakeOriginalDestinationConnectionId() {
+  return TestConnectionId(0x1337);
+}
+
+QuicConnectionId CreateFakeInitialSourceConnectionId() {
+  return TestConnectionId(0x2345);
+}
+
+QuicConnectionId CreateFakeRetrySourceConnectionId() {
+  return TestConnectionId(0x9876);
+}
+
+QuicConnectionId CreateFakePreferredConnectionId() {
+  return TestConnectionId(0xBEEF);
+}
+
+std::vector<uint8_t> CreateFakePreferredStatelessResetToken() {
+  return std::vector<uint8_t>(
+      kFakePreferredStatelessResetTokenData,
+      kFakePreferredStatelessResetTokenData +
+          sizeof(kFakePreferredStatelessResetTokenData));
+}
+
+QuicSocketAddress CreateFakeV4SocketAddress() {
+  QuicIpAddress ipv4_address;
+  if (!ipv4_address.FromString("65.66.67.68")) {  // 0x41, 0x42, 0x43, 0x44
+    QUIC_LOG(FATAL) << "Failed to create IPv4 address";
+    return QuicSocketAddress();
+  }
+  return QuicSocketAddress(ipv4_address, 0x4884);
+}
+
+QuicSocketAddress CreateFakeV6SocketAddress() {
+  QuicIpAddress ipv6_address;
+  if (!ipv6_address.FromString("6061:6263:6465:6667:6869:6A6B:6C6D:6E6F")) {
+    QUIC_LOG(FATAL) << "Failed to create IPv6 address";
+    return QuicSocketAddress();
+  }
+  return QuicSocketAddress(ipv6_address, 0x6336);
+}
+
+std::unique_ptr<TransportParameters::PreferredAddress>
+CreateFakePreferredAddress() {
+  TransportParameters::PreferredAddress preferred_address;
+  preferred_address.ipv4_socket_address = CreateFakeV4SocketAddress();
+  preferred_address.ipv6_socket_address = CreateFakeV6SocketAddress();
+  preferred_address.connection_id = CreateFakePreferredConnectionId();
+  preferred_address.stateless_reset_token =
+      CreateFakePreferredStatelessResetToken();
+  return std::make_unique<TransportParameters::PreferredAddress>(
+      preferred_address);
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformationClient() {
+  TransportParameters::LegacyVersionInformation legacy_version_information;
+  legacy_version_information.version = kFakeVersionLabel;
+  return legacy_version_information;
+}
+
+TransportParameters::LegacyVersionInformation
+CreateFakeLegacyVersionInformationServer() {
+  TransportParameters::LegacyVersionInformation legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel);
+  legacy_version_information.supported_versions.push_back(kFakeVersionLabel2);
+  return legacy_version_information;
+}
+
+TransportParameters::VersionInformation CreateFakeVersionInformation() {
+  TransportParameters::VersionInformation version_information;
+  version_information.chosen_version = kFakeVersionLabel;
+  version_information.other_versions.push_back(kFakeVersionLabel);
+  version_information.other_versions.push_back(kFakeVersionLabel2);
+  return version_information;
+}
+
+QuicTagVector CreateFakeGoogleConnectionOptions() {
+  return {kALPN, MakeQuicTag('E', 'F', 'G', 0x00),
+          MakeQuicTag('H', 'I', 'J', 0xff)};
+}
+
+void RemoveGreaseParameters(TransportParameters* params) {
+  std::vector<TransportParameters::TransportParameterId> grease_params;
+  for (const auto& kv : params->custom_parameters) {
+    if (kv.first % 31 == 27) {
+      grease_params.push_back(kv.first);
+    }
+  }
+  EXPECT_EQ(grease_params.size(), 1u);
+  for (TransportParameters::TransportParameterId param_id : grease_params) {
+    params->custom_parameters.erase(param_id);
+  }
+  // Remove all GREASE versions from version_information.other_versions.
+  if (params->version_information.has_value()) {
+    QuicVersionLabelVector& other_versions =
+        params->version_information.value().other_versions;
+    for (auto it = other_versions.begin(); it != other_versions.end();) {
+      if ((*it & 0x0f0f0f0f) == 0x0a0a0a0a) {
+        it = other_versions.erase(it);
+      } else {
+        ++it;
+      }
+    }
+  }
+}
+
+}  // namespace
+
+class TransportParametersTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  TransportParametersTest() : version_(GetParam()) {}
+
+  ParsedQuicVersion version_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TransportParametersTests,
+                         TransportParametersTest,
+                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TransportParametersTest, Comparator) {
+  TransportParameters orig_params;
+  TransportParameters new_params;
+  // Test comparison on primitive members.
+  orig_params.perspective = Perspective::IS_CLIENT;
+  new_params.perspective = Perspective::IS_SERVER;
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  new_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.version_information = CreateFakeVersionInformation();
+  new_params.version_information = CreateFakeVersionInformation();
+  orig_params.disable_active_migration = true;
+  new_params.disable_active_migration = true;
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on vectors.
+  orig_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel);
+  new_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel2);
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.legacy_version_information.value().supported_versions.pop_back();
+  new_params.legacy_version_information.value().supported_versions.push_back(
+      kFakeVersionLabel);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  new_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on IntegerParameters.
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest + 1);
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on PreferredAddress
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.preferred_address = CreateFakePreferredAddress();
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on CustomMap
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  new_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+  new_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+
+  // Test comparison on connection IDs.
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  new_params.initial_source_connection_id = absl::nullopt;
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.initial_source_connection_id = TestConnectionId(0xbadbad);
+  EXPECT_NE(orig_params, new_params);
+  EXPECT_FALSE(orig_params == new_params);
+  EXPECT_TRUE(orig_params != new_params);
+  new_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  EXPECT_EQ(orig_params, new_params);
+  EXPECT_TRUE(orig_params == new_params);
+  EXPECT_FALSE(orig_params != new_params);
+}
+
+TEST_P(TransportParametersTest, CopyConstructor) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.version_information = CreateFakeVersionInformation();
+  orig_params.original_destination_connection_id =
+      CreateFakeOriginalDestinationConnectionId();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
+  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  TransportParameters new_params(orig_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, RoundTripClient) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.version_information = CreateFakeVersionInformation();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                       serialized.data(), serialized.size(),
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  RemoveGreaseParameters(&new_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, RoundTripServer) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_SERVER;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationServer();
+  orig_params.version_information = CreateFakeVersionInformation();
+  orig_params.original_destination_connection_id =
+      CreateFakeOriginalDestinationConnectionId();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.preferred_address = CreateFakePreferredAddress();
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                       serialized.data(), serialized.size(),
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  RemoveGreaseParameters(&new_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, AreValid) {
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_idle_timeout_ms.set_value(601000);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(1200);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(65535);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(9999999);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.max_udp_payload_size.set_value(0);
+    error_details = "";
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client max_udp_payload_size 0 "
+              "(Invalid)]");
+    params.max_udp_payload_size.set_value(1199);
+    error_details = "";
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client max_udp_payload_size 1199 "
+              "(Invalid)]");
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.ack_delay_exponent.set_value(0);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.ack_delay_exponent.set_value(20);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.ack_delay_exponent.set_value(21);
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client ack_delay_exponent 21 "
+              "(Invalid)]");
+  }
+  {
+    TransportParameters params;
+    std::string error_details;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.active_connection_id_limit.set_value(2);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.active_connection_id_limit.set_value(999999);
+    EXPECT_TRUE(params.AreValid(&error_details));
+    EXPECT_TRUE(error_details.empty());
+    params.active_connection_id_limit.set_value(1);
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client active_connection_id_limit"
+              " 1 (Invalid)]");
+    params.active_connection_id_limit.set_value(0);
+    EXPECT_FALSE(params.AreValid(&error_details));
+    EXPECT_EQ(error_details,
+              "Invalid transport parameters [Client active_connection_id_limit"
+              " 0 (Invalid)]");
+  }
+}
+
+TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+
+  std::vector<uint8_t> out;
+  bool ok = true;
+  EXPECT_QUIC_BUG(
+      ok = SerializeTransportParameters(version_, orig_params, &out),
+      "Not serializing invalid transport parameters: Client cannot send "
+      "stateless reset token");
+  EXPECT_FALSE(ok);
+}
+
+TEST_P(TransportParametersTest, ParseClientParams) {
+  // clang-format off
+  const uint8_t kClientParams[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+      // initial_max_stream_data_bidi_local
+      0x05,  // parameter id
+      0x02,  // length
+      0x47, 0xD1,  // value
+      // initial_max_stream_data_bidi_remote
+      0x06,  // parameter id
+      0x02,  // length
+      0x47, 0xD2,  // value
+      // initial_max_stream_data_uni
+      0x07,  // parameter id
+      0x02,  // length
+      0x4B, 0xB8,  // value
+      // initial_max_streams_bidi
+      0x08,  // parameter id
+      0x01,  // length
+      0x15,  // value
+      // initial_max_streams_uni
+      0x09,  // parameter id
+      0x01,  // length
+      0x16,  // value
+      // ack_delay_exponent
+      0x0a,  // parameter id
+      0x01,  // length
+      0x0a,  // value
+      // max_ack_delay
+      0x0b,  // parameter id
+      0x01,  // length
+      0x33,  // value
+      // min_ack_delay_us
+      0x80, 0x00, 0xde, 0x1a,  // parameter id
+      0x02,  // length
+      0x43, 0xe8,  // value
+      // disable_active_migration
+      0x0c,  // parameter id
+      0x00,  // length
+      // active_connection_id_limit
+      0x0e,  // parameter id
+      0x01,  // length
+      0x34,  // value
+      // initial_source_connection_id
+      0x0f,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
+      // initial_round_trip_time_us
+      0x71, 0x27,  // parameter id
+      0x01,  // length
+      0x35,  // value
+      // google_connection_options
+      0x71, 0x28,  // parameter id
+      0x0c,  // length
+      'A', 'L', 'P', 'N',  // value
+      'E', 'F', 'G', 0x00,
+      'H', 'I', 'J', 0xff,
+      // Google version extension
+      0x80, 0x00, 0x47, 0x52,  // parameter id
+      0x04,  // length
+      0x01, 0x23, 0x45, 0x67,  // initial version
+      // version_information
+      0x80, 0xFF, 0x73, 0xDB,  // parameter id
+      0x0C,  // length
+      0x01, 0x23, 0x45, 0x67,  // chosen version
+      0x01, 0x23, 0x45, 0x67,  // other version 1
+      0x89, 0xab, 0xcd, 0xef,  // other version 2
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParams);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParams);
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                       client_params, client_params_length,
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
+  ASSERT_TRUE(new_params.legacy_version_information.has_value());
+  EXPECT_EQ(kFakeVersionLabel,
+            new_params.legacy_version_information.value().version);
+  EXPECT_TRUE(
+      new_params.legacy_version_information.value().supported_versions.empty());
+  ASSERT_TRUE(new_params.version_information.has_value());
+  EXPECT_EQ(new_params.version_information.value(),
+            CreateFakeVersionInformation());
+  EXPECT_FALSE(new_params.original_destination_connection_id.has_value());
+  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
+            new_params.max_idle_timeout_ms.value());
+  EXPECT_TRUE(new_params.stateless_reset_token.empty());
+  EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
+  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
+            new_params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
+            new_params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
+            new_params.initial_max_stream_data_uni.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
+            new_params.initial_max_streams_bidi.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsUni,
+            new_params.initial_max_streams_uni.value());
+  EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
+  EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
+  EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
+  EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
+  EXPECT_EQ(kActiveConnectionIdLimitForTest,
+            new_params.active_connection_id_limit.value());
+  ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
+  EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
+            new_params.initial_source_connection_id.value());
+  EXPECT_FALSE(new_params.retry_source_connection_id.has_value());
+  EXPECT_EQ(kFakeInitialRoundTripTime,
+            new_params.initial_round_trip_time_us.value());
+  ASSERT_TRUE(new_params.google_connection_options.has_value());
+  EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
+            new_params.google_connection_options.value());
+}
+
+TEST_P(TransportParametersTest,
+       ParseClientParamsFailsWithFullStatelessResetToken) {
+  // clang-format off
+  const uint8_t kClientParamsWithFullToken[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParamsWithFullToken);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithFullToken);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                        client_params, client_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details, "Client cannot send stateless reset token");
+}
+
+TEST_P(TransportParametersTest,
+       ParseClientParamsFailsWithEmptyStatelessResetToken) {
+  // clang-format off
+  const uint8_t kClientParamsWithEmptyToken[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x00,  // length
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParamsWithEmptyToken);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsWithEmptyToken);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                        client_params, client_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details,
+            "Received stateless_reset_token of invalid length 0");
+}
+
+TEST_P(TransportParametersTest, ParseClientParametersRepeated) {
+  // clang-format off
+  const uint8_t kClientParamsRepeated[] = {
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // max_idle_timeout (repeated)
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+  };
+  // clang-format on
+  const uint8_t* client_params =
+      reinterpret_cast<const uint8_t*>(kClientParamsRepeated);
+  size_t client_params_length = ABSL_ARRAYSIZE(kClientParamsRepeated);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                        client_params, client_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details, "Received a second max_idle_timeout");
+}
+
+TEST_P(TransportParametersTest, ParseServerParams) {
+  // clang-format off
+  const uint8_t kServerParams[] = {
+      // original_destination_connection_id
+      0x00,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+      // max_udp_payload_size
+      0x03,  // parameter id
+      0x02,  // length
+      0x63, 0x29,  // value
+      // initial_max_data
+      0x04,  // parameter id
+      0x02,  // length
+      0x40, 0x65,  // value
+      // initial_max_stream_data_bidi_local
+      0x05,  // parameter id
+      0x02,  // length
+      0x47, 0xD1,  // value
+      // initial_max_stream_data_bidi_remote
+      0x06,  // parameter id
+      0x02,  // length
+      0x47, 0xD2,  // value
+      // initial_max_stream_data_uni
+      0x07,  // parameter id
+      0x02,  // length
+      0x4B, 0xB8,  // value
+      // initial_max_streams_bidi
+      0x08,  // parameter id
+      0x01,  // length
+      0x15,  // value
+      // initial_max_streams_uni
+      0x09,  // parameter id
+      0x01,  // length
+      0x16,  // value
+      // ack_delay_exponent
+      0x0a,  // parameter id
+      0x01,  // length
+      0x0a,  // value
+      // max_ack_delay
+      0x0b,  // parameter id
+      0x01,  // length
+      0x33,  // value
+      // min_ack_delay_us
+      0x80, 0x00, 0xde, 0x1a,  // parameter id
+      0x02,  // length
+      0x43, 0xe8,  // value
+      // disable_active_migration
+      0x0c,  // parameter id
+      0x00,  // length
+      // preferred_address
+      0x0d,  // parameter id
+      0x31,  // length
+      0x41, 0x42, 0x43, 0x44,  // IPv4 address
+      0x48, 0x84,  // IPv4 port
+      0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  // IPv6 address
+      0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+      0x63, 0x36,  // IPv6 port
+      0x08,        // connection ID length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF,  // connection ID
+      0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // stateless reset token
+      0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+      // active_connection_id_limit
+      0x0e,  // parameter id
+      0x01,  // length
+      0x34,  // value
+      // initial_source_connection_id
+      0x0f,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
+      // retry_source_connection_id
+      0x10,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x76,
+      // google_connection_options
+      0x71, 0x28,  // parameter id
+      0x0c,  // length
+      'A', 'L', 'P', 'N',  // value
+      'E', 'F', 'G', 0x00,
+      'H', 'I', 'J', 0xff,
+      // Google version extension
+      0x80, 0x00, 0x47, 0x52,  // parameter id
+      0x0d,  // length
+      0x01, 0x23, 0x45, 0x67,  // negotiated_version
+      0x08,  // length of supported versions array
+      0x01, 0x23, 0x45, 0x67,
+      0x89, 0xab, 0xcd, 0xef,
+      // version_information
+      0x80, 0xFF, 0x73, 0xDB,  // parameter id
+      0x0C,  // length
+      0x01, 0x23, 0x45, 0x67,  // chosen version
+      0x01, 0x23, 0x45, 0x67,  // other version 1
+      0x89, 0xab, 0xcd, 0xef,  // other version 2
+  };
+  // clang-format on
+  const uint8_t* server_params =
+      reinterpret_cast<const uint8_t*>(kServerParams);
+  size_t server_params_length = ABSL_ARRAYSIZE(kServerParams);
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                       server_params, server_params_length,
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
+  ASSERT_TRUE(new_params.legacy_version_information.has_value());
+  EXPECT_EQ(kFakeVersionLabel,
+            new_params.legacy_version_information.value().version);
+  ASSERT_EQ(
+      2u,
+      new_params.legacy_version_information.value().supported_versions.size());
+  EXPECT_EQ(
+      kFakeVersionLabel,
+      new_params.legacy_version_information.value().supported_versions[0]);
+  EXPECT_EQ(
+      kFakeVersionLabel2,
+      new_params.legacy_version_information.value().supported_versions[1]);
+  ASSERT_TRUE(new_params.version_information.has_value());
+  EXPECT_EQ(new_params.version_information.value(),
+            CreateFakeVersionInformation());
+  ASSERT_TRUE(new_params.original_destination_connection_id.has_value());
+  EXPECT_EQ(CreateFakeOriginalDestinationConnectionId(),
+            new_params.original_destination_connection_id.value());
+  EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
+            new_params.max_idle_timeout_ms.value());
+  EXPECT_EQ(CreateStatelessResetTokenForTest(),
+            new_params.stateless_reset_token);
+  EXPECT_EQ(kMaxPacketSizeForTest, new_params.max_udp_payload_size.value());
+  EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
+            new_params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
+            new_params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(kFakeInitialMaxStreamDataUni,
+            new_params.initial_max_stream_data_uni.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsBidi,
+            new_params.initial_max_streams_bidi.value());
+  EXPECT_EQ(kFakeInitialMaxStreamsUni,
+            new_params.initial_max_streams_uni.value());
+  EXPECT_EQ(kAckDelayExponentForTest, new_params.ack_delay_exponent.value());
+  EXPECT_EQ(kMaxAckDelayForTest, new_params.max_ack_delay.value());
+  EXPECT_EQ(kMinAckDelayUsForTest, new_params.min_ack_delay_us.value());
+  EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
+  ASSERT_NE(nullptr, new_params.preferred_address.get());
+  EXPECT_EQ(CreateFakeV4SocketAddress(),
+            new_params.preferred_address->ipv4_socket_address);
+  EXPECT_EQ(CreateFakeV6SocketAddress(),
+            new_params.preferred_address->ipv6_socket_address);
+  EXPECT_EQ(CreateFakePreferredConnectionId(),
+            new_params.preferred_address->connection_id);
+  EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
+            new_params.preferred_address->stateless_reset_token);
+  EXPECT_EQ(kActiveConnectionIdLimitForTest,
+            new_params.active_connection_id_limit.value());
+  ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
+  EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
+            new_params.initial_source_connection_id.value());
+  ASSERT_TRUE(new_params.retry_source_connection_id.has_value());
+  EXPECT_EQ(CreateFakeRetrySourceConnectionId(),
+            new_params.retry_source_connection_id.value());
+  ASSERT_TRUE(new_params.google_connection_options.has_value());
+  EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
+            new_params.google_connection_options.value());
+}
+
+TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
+  // clang-format off
+  const uint8_t kServerParamsRepeated[] = {
+      // original_destination_connection_id
+      0x00,  // parameter id
+      0x08,  // length
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+      0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+      // max_idle_timeout (repeated)
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+  };
+  // clang-format on
+  const uint8_t* server_params =
+      reinterpret_cast<const uint8_t*>(kServerParamsRepeated);
+  size_t server_params_length = ABSL_ARRAYSIZE(kServerParamsRepeated);
+  TransportParameters out_params;
+  std::string error_details;
+  EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                        server_params, server_params_length,
+                                        &out_params, &error_details));
+  EXPECT_EQ(error_details, "Received a second max_idle_timeout");
+}
+
+TEST_P(TransportParametersTest,
+       ParseServerParametersEmptyOriginalConnectionId) {
+  // clang-format off
+  const uint8_t kServerParamsEmptyOriginalConnectionId[] = {
+      // original_destination_connection_id
+      0x00,  // parameter id
+      0x00,  // length
+      // max_idle_timeout
+      0x01,  // parameter id
+      0x02,  // length
+      0x6e, 0xec,  // value
+      // stateless_reset_token
+      0x02,  // parameter id
+      0x10,  // length
+      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+      0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+  };
+  // clang-format on
+  const uint8_t* server_params =
+      reinterpret_cast<const uint8_t*>(kServerParamsEmptyOriginalConnectionId);
+  size_t server_params_length =
+      ABSL_ARRAYSIZE(kServerParamsEmptyOriginalConnectionId);
+  TransportParameters out_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_SERVER,
+                                       server_params, server_params_length,
+                                       &out_params, &error_details))
+      << error_details;
+  ASSERT_TRUE(out_params.original_destination_connection_id.has_value());
+  EXPECT_EQ(out_params.original_destination_connection_id.value(),
+            EmptyQuicConnectionId());
+}
+
+TEST_P(TransportParametersTest, VeryLongCustomParameter) {
+  // Ensure we can handle a 70KB custom parameter on both send and receive.
+  std::string custom_value(70000, '?');
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.custom_parameters[kCustomParameter1] = custom_value;
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+  TransportParameters new_params;
+  std::string error_details;
+  ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+                                       serialized.data(), serialized.size(),
+                                       &new_params, &error_details))
+      << error_details;
+  EXPECT_TRUE(error_details.empty());
+  RemoveGreaseParameters(&new_params);
+  EXPECT_EQ(new_params, orig_params);
+}
+
+TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.legacy_version_information =
+      CreateFakeLegacyVersionInformationClient();
+  orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+  orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  orig_params.initial_max_data.set_value(kFakeInitialMaxData);
+  orig_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal);
+  orig_params.initial_max_stream_data_bidi_remote.set_value(
+      kFakeInitialMaxStreamDataBidiRemote);
+  orig_params.initial_max_stream_data_uni.set_value(
+      kFakeInitialMaxStreamDataUni);
+  orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
+  orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
+  orig_params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  orig_params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  orig_params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  orig_params.disable_active_migration = kFakeDisableMigration;
+  orig_params.active_connection_id_limit.set_value(
+      kActiveConnectionIdLimitForTest);
+  orig_params.initial_source_connection_id =
+      CreateFakeInitialSourceConnectionId();
+  orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
+  orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
+  orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
+  orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
+
+  std::vector<uint8_t> first_serialized;
+  ASSERT_TRUE(
+      SerializeTransportParameters(version_, orig_params, &first_serialized));
+  // Test that a subsequent serialization is different from the first.
+  // Run in a loop to avoid a failure in the unlikely event that randomization
+  // produces the same result multiple times.
+  for (int i = 0; i < 1000; i++) {
+    std::vector<uint8_t> serialized;
+    ASSERT_TRUE(
+        SerializeTransportParameters(version_, orig_params, &serialized));
+    if (serialized != first_serialized) {
+      return;
+    }
+  }
+}
+
+class TransportParametersTicketSerializationTest : public QuicTest {
+ protected:
+  void SetUp() override {
+    original_params_.perspective = Perspective::IS_SERVER;
+    original_params_.legacy_version_information =
+        CreateFakeLegacyVersionInformationServer();
+    original_params_.original_destination_connection_id =
+        CreateFakeOriginalDestinationConnectionId();
+    original_params_.max_idle_timeout_ms.set_value(
+        kFakeIdleTimeoutMilliseconds);
+    original_params_.stateless_reset_token = CreateStatelessResetTokenForTest();
+    original_params_.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+    original_params_.initial_max_data.set_value(kFakeInitialMaxData);
+    original_params_.initial_max_stream_data_bidi_local.set_value(
+        kFakeInitialMaxStreamDataBidiLocal);
+    original_params_.initial_max_stream_data_bidi_remote.set_value(
+        kFakeInitialMaxStreamDataBidiRemote);
+    original_params_.initial_max_stream_data_uni.set_value(
+        kFakeInitialMaxStreamDataUni);
+    original_params_.initial_max_streams_bidi.set_value(
+        kFakeInitialMaxStreamsBidi);
+    original_params_.initial_max_streams_uni.set_value(
+        kFakeInitialMaxStreamsUni);
+    original_params_.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+    original_params_.max_ack_delay.set_value(kMaxAckDelayForTest);
+    original_params_.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+    original_params_.disable_active_migration = kFakeDisableMigration;
+    original_params_.preferred_address = CreateFakePreferredAddress();
+    original_params_.active_connection_id_limit.set_value(
+        kActiveConnectionIdLimitForTest);
+    original_params_.initial_source_connection_id =
+        CreateFakeInitialSourceConnectionId();
+    original_params_.retry_source_connection_id =
+        CreateFakeRetrySourceConnectionId();
+    original_params_.google_connection_options =
+        CreateFakeGoogleConnectionOptions();
+
+    ASSERT_TRUE(SerializeTransportParametersForTicket(
+        original_params_, application_state_, &original_serialized_params_));
+  }
+
+  TransportParameters original_params_;
+  std::vector<uint8_t> application_state_ = {0, 1};
+  std::vector<uint8_t> original_serialized_params_;
+};
+
+TEST_F(TransportParametersTicketSerializationTest,
+       StatelessResetTokenDoesntChangeOutput) {
+  // Test that changing the stateless reset token doesn't change the ticket
+  // serialization.
+  TransportParameters new_params = original_params_;
+  new_params.stateless_reset_token = CreateFakePreferredStatelessResetToken();
+  EXPECT_NE(new_params, original_params_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      new_params, application_state_, &serialized));
+  EXPECT_EQ(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest,
+       ConnectionIDDoesntChangeOutput) {
+  // Changing original destination CID doesn't change serialization.
+  TransportParameters new_params = original_params_;
+  new_params.original_destination_connection_id = TestConnectionId(0xCAFE);
+  EXPECT_NE(new_params, original_params_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      new_params, application_state_, &serialized));
+  EXPECT_EQ(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest, StreamLimitChangesOutput) {
+  // Changing a stream limit does change the serialization.
+  TransportParameters new_params = original_params_;
+  new_params.initial_max_stream_data_bidi_local.set_value(
+      kFakeInitialMaxStreamDataBidiLocal + 1);
+  EXPECT_NE(new_params, original_params_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      new_params, application_state_, &serialized));
+  EXPECT_NE(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest,
+       ApplicationStateChangesOutput) {
+  // Changing the application state changes the serialization.
+  std::vector<uint8_t> new_application_state = {0};
+  EXPECT_NE(new_application_state, application_state_);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParametersForTicket(
+      original_params_, new_application_state, &serialized));
+  EXPECT_NE(original_serialized_params_, serialized);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc
new file mode 100644
index 0000000..1353137
--- /dev/null
+++ b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc
@@ -0,0 +1,229 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
+
+#include <cstdint>
+#include <memory>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_replace.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+constexpr size_t kFingerprintLength = SHA256_DIGEST_LENGTH * 3 - 1;
+
+// Assumes that the character is normalized to lowercase beforehand.
+bool IsNormalizedHexDigit(char c) {
+  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
+}
+
+void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
+  fingerprint.fingerprint =
+      quiche::QuicheTextUtils::ToLower(fingerprint.fingerprint);
+}
+
+}  // namespace
+
+constexpr char CertificateFingerprint::kSha256[];
+constexpr char WebTransportHash::kSha256[];
+
+ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
+    const {
+  return new Details(*this);
+}
+
+WebTransportFingerprintProofVerifier::WebTransportFingerprintProofVerifier(
+    const QuicClock* clock, int max_validity_days)
+    : clock_(clock),
+      max_validity_days_(max_validity_days),
+      // Add an extra second to max validity to accomodate various edge cases.
+      max_validity_(
+          QuicTime::Delta::FromSeconds(max_validity_days * 86400 + 1)) {}
+
+bool WebTransportFingerprintProofVerifier::AddFingerprint(
+    CertificateFingerprint fingerprint) {
+  NormalizeFingerprint(fingerprint);
+  if (fingerprint.algorithm != CertificateFingerprint::kSha256) {
+    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
+    return false;
+  }
+  if (fingerprint.fingerprint.size() != kFingerprintLength) {
+    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
+    return false;
+  }
+  for (size_t i = 0; i < fingerprint.fingerprint.size(); i++) {
+    char current = fingerprint.fingerprint[i];
+    if (i % 3 == 2) {
+      if (current != ':') {
+        QUIC_DLOG(WARNING)
+            << "Missing colon separator between the bytes of the hash";
+        return false;
+      }
+    } else {
+      if (!IsNormalizedHexDigit(current)) {
+        QUIC_DLOG(WARNING) << "Fingerprint must be in hexadecimal";
+        return false;
+      }
+    }
+  }
+
+  std::string normalized =
+      absl::StrReplaceAll(fingerprint.fingerprint, {{":", ""}});
+  hashes_.push_back(WebTransportHash{fingerprint.algorithm,
+                                     absl::HexStringToBytes(normalized)});
+  return true;
+}
+
+bool WebTransportFingerprintProofVerifier::AddFingerprint(
+    WebTransportHash hash) {
+  if (hash.algorithm != CertificateFingerprint::kSha256) {
+    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
+    return false;
+  }
+  if (hash.value.size() != SHA256_DIGEST_LENGTH) {
+    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
+    return false;
+  }
+  hashes_.push_back(std::move(hash));
+  return true;
+}
+
+QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyProof(
+    const std::string& /*hostname*/, const uint16_t /*port*/,
+    const std::string& /*server_config*/,
+    QuicTransportVersion /*transport_version*/, absl::string_view /*chlo_hash*/,
+    const std::vector<std::string>& /*certs*/, const std::string& /*cert_sct*/,
+    const std::string& /*signature*/, const ProofVerifyContext* /*context*/,
+    std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
+    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+  *error_details =
+      "QUIC crypto certificate verification is not supported in "
+      "WebTransportFingerprintProofVerifier";
+  QUIC_BUG(quic_bug_10879_1) << *error_details;
+  *details = std::make_unique<Details>(Status::kInternalError);
+  return QUIC_FAILURE;
+}
+
+QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
+    const std::string& /*hostname*/, const uint16_t /*port*/,
+    const std::vector<std::string>& certs, const std::string& /*ocsp_response*/,
+    const std::string& /*cert_sct*/, const ProofVerifyContext* /*context*/,
+    std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
+    uint8_t* /*out_alert*/,
+    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+  if (certs.empty()) {
+    *details = std::make_unique<Details>(Status::kInternalError);
+    *error_details = "No certificates provided";
+    return QUIC_FAILURE;
+  }
+
+  if (!HasKnownFingerprint(certs[0])) {
+    *details = std::make_unique<Details>(Status::kUnknownFingerprint);
+    *error_details = "Certificate does not match any fingerprint";
+    return QUIC_FAILURE;
+  }
+
+  std::unique_ptr<CertificateView> view =
+      CertificateView::ParseSingleCertificate(certs[0]);
+  if (view == nullptr) {
+    *details = std::make_unique<Details>(Status::kCertificateParseFailure);
+    *error_details = "Failed to parse the certificate";
+    return QUIC_FAILURE;
+  }
+
+  if (!HasValidExpiry(*view)) {
+    *details = std::make_unique<Details>(Status::kExpiryTooLong);
+    *error_details =
+        absl::StrCat("Certificate expiry exceeds the configured limit of ",
+                     max_validity_days_, " days");
+    return QUIC_FAILURE;
+  }
+
+  if (!IsWithinValidityPeriod(*view)) {
+    *details = std::make_unique<Details>(Status::kExpired);
+    *error_details =
+        "Certificate has expired or has validity listed in the future";
+    return QUIC_FAILURE;
+  }
+
+  if (!IsKeyTypeAllowedByPolicy(*view)) {
+    *details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm);
+    *error_details =
+        absl::StrCat("Certificate uses a disallowed public key type (",
+                     PublicKeyTypeToString(view->public_key_type()), ")");
+    return QUIC_FAILURE;
+  }
+
+  *details = std::make_unique<Details>(Status::kValidCertificate);
+  return QUIC_SUCCESS;
+}
+
+std::unique_ptr<ProofVerifyContext>
+WebTransportFingerprintProofVerifier::CreateDefaultContext() {
+  return nullptr;
+}
+
+bool WebTransportFingerprintProofVerifier::HasKnownFingerprint(
+    absl::string_view der_certificate) {
+  // https://w3c.github.io/webtransport/#verify-a-certificate-hash
+  const std::string hash = RawSha256(der_certificate);
+  for (const WebTransportHash& reference : hashes_) {
+    if (reference.algorithm != WebTransportHash::kSha256) {
+      QUIC_BUG(quic_bug_10879_2) << "Unexpected non-SHA-256 hash";
+      continue;
+    }
+    if (hash == reference.value) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool WebTransportFingerprintProofVerifier::HasValidExpiry(
+    const CertificateView& certificate) {
+  if (!certificate.validity_start().IsBefore(certificate.validity_end())) {
+    return false;
+  }
+
+  const QuicTime::Delta duration_seconds =
+      certificate.validity_end() - certificate.validity_start();
+  return duration_seconds <= max_validity_;
+}
+
+bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
+    const CertificateView& certificate) {
+  QuicWallTime now = clock_->WallNow();
+  return now.IsAfter(certificate.validity_start()) &&
+         now.IsBefore(certificate.validity_end());
+}
+
+bool WebTransportFingerprintProofVerifier::IsKeyTypeAllowedByPolicy(
+    const CertificateView& certificate) {
+  switch (certificate.public_key_type()) {
+    // https://github.com/w3c/webtransport/pull/375 defines P-256 as an MTI
+    // algorithm, and prohibits RSA.  We also allow P-384 and Ed25519.
+    case PublicKeyType::kP256:
+    case PublicKeyType::kP384:
+    case PublicKeyType::kEd25519:
+      return true;
+    case PublicKeyType::kRsa:
+      // TODO(b/213614428): this should be false by default.
+      return true;
+    default:
+      return false;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h
new file mode 100644
index 0000000..87ecf2a
--- /dev/null
+++ b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h
@@ -0,0 +1,135 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Represents a fingerprint of an X.509 certificate in a format based on
+// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
+// TODO(vasilvv): remove this once all consumers of this API use
+// WebTransportHash.
+struct QUIC_EXPORT_PRIVATE CertificateFingerprint {
+  static constexpr char kSha256[] = "sha-256";
+
+  // An algorithm described by one of the names in
+  // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
+  std::string algorithm;
+  // Hex-encoded, colon-separated fingerprint of the certificate.  For example,
+  // "12:3d:5b:71:8c:54:df:85:7e:bd:e3:7c:66:da:f9:db:6a:94:8f:85:cb:6e:44:7f:09:3e:05:f2:dd:d4:f7:86"
+  std::string fingerprint;
+};
+
+// Represents a fingerprint of an X.509 certificate in a format based on
+// https://w3c.github.io/webtransport/#dictdef-webtransporthash.
+struct QUIC_EXPORT_PRIVATE WebTransportHash {
+  static constexpr char kSha256[] = "sha-256";
+
+  // An algorithm described by one of the names in
+  // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
+  std::string algorithm;
+  // Raw bytes of the hash.
+  std::string value;
+};
+
+// WebTransportFingerprintProofVerifier verifies the server leaf certificate
+// against a supplied list of certificate fingerprints following the procedure
+// described in the WebTransport specification.  The certificate is deemed
+// trusted if it matches a fingerprint in the list, has expiry dates that are
+// not too long and has not expired.  Only the leaf is checked, the rest of the
+// chain is ignored. Reference specification:
+// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
+class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
+    : public ProofVerifier {
+ public:
+  // Note: the entries in this list may be logged into a UMA histogram, and thus
+  // should not be renumbered.
+  enum class Status {
+    kValidCertificate = 0,
+    kUnknownFingerprint = 1,
+    kCertificateParseFailure = 2,
+    kExpiryTooLong = 3,
+    kExpired = 4,
+    kInternalError = 5,
+    kDisallowedKeyAlgorithm = 6,
+
+    kMaxValue = kDisallowedKeyAlgorithm,
+  };
+
+  class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
+   public:
+    explicit Details(Status status) : status_(status) {}
+    Status status() const { return status_; }
+
+    ProofVerifyDetails* Clone() const override;
+
+   private:
+    const Status status_;
+  };
+
+  // |clock| is used to check if the certificate has expired.  It is not owned
+  // and must outlive the object.  |max_validity_days| is the maximum time for
+  // which the certificate is allowed to be valid.
+  WebTransportFingerprintProofVerifier(const QuicClock* clock,
+                                       int max_validity_days);
+
+  // Adds a certificate fingerprint to be trusted.  The fingerprints are
+  // case-insensitive and are validated internally; the function returns true if
+  // the validation passes.
+  bool AddFingerprint(CertificateFingerprint fingerprint);
+  bool AddFingerprint(WebTransportHash hash);
+
+  // ProofVerifier implementation.
+  QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion transport_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
+
+ protected:
+  virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate);
+
+ private:
+  bool HasKnownFingerprint(absl::string_view der_certificate);
+  bool HasValidExpiry(const CertificateView& certificate);
+  bool IsWithinValidityPeriod(const CertificateView& certificate);
+
+  const QuicClock* clock_;  // Unowned.
+  const int max_validity_days_;
+  const QuicTime::Delta max_validity_;
+  std::vector<WebTransportHash> hashes_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
diff --git a/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc
new file mode 100644
index 0000000..11c769d
--- /dev/null
+++ b/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc
@@ -0,0 +1,183 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
+
+#include <memory>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::HasSubstr;
+
+// 2020-02-01 12:35:56 UTC
+constexpr QuicTime::Delta kValidTime = QuicTime::Delta::FromSeconds(1580560556);
+
+struct VerifyResult {
+  QuicAsyncStatus status;
+  WebTransportFingerprintProofVerifier::Status detailed_status;
+  std::string error;
+};
+
+class WebTransportFingerprintProofVerifierTest : public QuicTest {
+ public:
+  WebTransportFingerprintProofVerifierTest() {
+    clock_.AdvanceTime(kValidTime);
+    verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+        &clock_, /*max_validity_days=*/365);
+    AddTestCertificate();
+  }
+
+ protected:
+  VerifyResult Verify(absl::string_view certificate) {
+    VerifyResult result;
+    std::unique_ptr<ProofVerifyDetails> details;
+    uint8_t tls_alert;
+    result.status = verifier_->VerifyCertChain(
+        /*hostname=*/"", /*port=*/0,
+        std::vector<std::string>{std::string(certificate)},
+        /*ocsp_response=*/"",
+        /*cert_sct=*/"",
+        /*context=*/nullptr, &result.error, &details, &tls_alert,
+        /*callback=*/nullptr);
+    result.detailed_status =
+        static_cast<WebTransportFingerprintProofVerifier::Details*>(
+            details.get())
+            ->status();
+    return result;
+  }
+
+  void AddTestCertificate() {
+    EXPECT_TRUE(verifier_->AddFingerprint(WebTransportHash{
+        WebTransportHash::kSha256, RawSha256(kTestCertificate)}));
+  }
+
+  MockClock clock_;
+  std::unique_ptr<WebTransportFingerprintProofVerifier> verifier_;
+};
+
+TEST_F(WebTransportFingerprintProofVerifierTest, Sha256Fingerprint) {
+  // Computed using `openssl x509 -fingerprint -sha256`.
+  EXPECT_EQ(absl::BytesToHexString(RawSha256(kTestCertificate)),
+            "f2e5465e2bf7ecd6f63066a5a37511734aa0eb7c4701"
+            "0e86d6758ed4f4fa1b0f");
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, SimpleFingerprint) {
+  VerifyResult result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_SUCCESS);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+  result = Verify(kWildcardCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kUnknownFingerprint);
+
+  result = Verify("Some random text");
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, Validity) {
+  // Validity periods of kTestCertificate, according to `openssl x509 -text`:
+  //     Not Before: Jan 30 18:13:59 2020 GMT
+  //     Not After : Feb  2 18:13:59 2020 GMT
+
+  // 2020-01-29 19:00:00 UTC
+  constexpr QuicTime::Delta kStartTime =
+      QuicTime::Delta::FromSeconds(1580324400);
+  clock_.Reset();
+  clock_.AdvanceTime(kStartTime);
+
+  VerifyResult result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kExpired);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400));
+  result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_SUCCESS);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(4 * 86400));
+  result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kExpired);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, MaxValidity) {
+  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+      &clock_, /*max_validity_days=*/2);
+  AddTestCertificate();
+  VerifyResult result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kExpiryTooLong);
+  EXPECT_THAT(result.error, HasSubstr("limit of 2 days"));
+
+  // kTestCertificate is valid for exactly four days.
+  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+      &clock_, /*max_validity_days=*/4);
+  AddTestCertificate();
+  result = Verify(kTestCertificate);
+  EXPECT_EQ(result.status, QUIC_SUCCESS);
+  EXPECT_EQ(result.detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) {
+  constexpr absl::string_view kInvalidCertificate = "Hello, world!";
+  ASSERT_TRUE(verifier_->AddFingerprint(WebTransportHash{
+      WebTransportHash::kSha256, RawSha256(kInvalidCertificate)}));
+
+  VerifyResult result = Verify(kInvalidCertificate);
+  EXPECT_EQ(result.status, QUIC_FAILURE);
+  EXPECT_EQ(
+      result.detailed_status,
+      WebTransportFingerprintProofVerifier::Status::kCertificateParseFailure);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, AddCertificate) {
+  // Accept all-uppercase fingerprints.
+  verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+      &clock_, /*max_validity_days=*/365);
+  EXPECT_TRUE(verifier_->AddFingerprint(CertificateFingerprint{
+      CertificateFingerprint::kSha256,
+      "F2:E5:46:5E:2B:F7:EC:D6:F6:30:66:A5:A3:75:11:73:4A:A0:EB:"
+      "7C:47:01:0E:86:D6:75:8E:D4:F4:FA:1B:0F"}));
+  EXPECT_EQ(Verify(kTestCertificate).detailed_status,
+            WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+  // Reject unknown hash algorithms.
+  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
+      "sha-1", "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"}));
+  // Reject invalid length.
+  EXPECT_FALSE(verifier_->AddFingerprint(
+      CertificateFingerprint{CertificateFingerprint::kSha256, "00:00:00:00"}));
+  // Reject missing colons.
+  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
+      CertificateFingerprint::kSha256,
+      "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00."
+      "00.00.00.00.00.00.00.00.00.00.00.00.00"}));
+  // Reject non-hex symbols.
+  EXPECT_FALSE(verifier_->AddFingerprint(CertificateFingerprint{
+      CertificateFingerprint::kSha256,
+      "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:"
+      "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz"}));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ack_frame.cc b/quiche/quic/core/frames/quic_ack_frame.cc
new file mode 100644
index 0000000..c61594b
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frame.cc
@@ -0,0 +1,190 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_ack_frame.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+
+const QuicPacketCount kMaxPrintRange = 128;
+
+}  // namespace
+
+bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
+                      QuicPacketNumber packet_number,
+                      QuicPacketNumber peer_least_packet_awaiting_ack) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  return (!peer_least_packet_awaiting_ack.IsInitialized() ||
+          packet_number >= peer_least_packet_awaiting_ack) &&
+         !ack_frame.packets.Contains(packet_number);
+}
+
+QuicAckFrame::QuicAckFrame() = default;
+
+QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
+
+QuicAckFrame::~QuicAckFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) {
+  os << "{ largest_acked: " << LargestAcked(ack_frame)
+     << ", ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds()
+     << ", packets: [ " << ack_frame.packets << " ]"
+     << ", received_packets: [ ";
+  for (const std::pair<QuicPacketNumber, QuicTime>& p :
+       ack_frame.received_packet_times) {
+    os << p.first << " at " << p.second.ToDebuggingValue() << " ";
+  }
+  os << " ]";
+  os << ", ecn_counters_populated: " << ack_frame.ecn_counters_populated;
+  if (ack_frame.ecn_counters_populated) {
+    os << ", ect_0_count: " << ack_frame.ect_0_count
+       << ", ect_1_count: " << ack_frame.ect_1_count
+       << ", ecn_ce_count: " << ack_frame.ecn_ce_count;
+  }
+
+  os << " }\n";
+  return os;
+}
+
+void QuicAckFrame::Clear() {
+  largest_acked.Clear();
+  ack_delay_time = QuicTime::Delta::Infinite();
+  received_packet_times.clear();
+  packets.Clear();
+}
+
+PacketNumberQueue::PacketNumberQueue() {}
+PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
+PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
+PacketNumberQueue::~PacketNumberQueue() {}
+
+PacketNumberQueue& PacketNumberQueue::operator=(
+    const PacketNumberQueue& other) = default;
+PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) =
+    default;
+
+void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
+  if (!packet_number.IsInitialized()) {
+    return;
+  }
+  packet_number_intervals_.AddOptimizedForAppend(packet_number,
+                                                 packet_number + 1);
+}
+
+void PacketNumberQueue::AddRange(QuicPacketNumber lower,
+                                 QuicPacketNumber higher) {
+  if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) {
+    return;
+  }
+
+  packet_number_intervals_.AddOptimizedForAppend(lower, higher);
+}
+
+bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
+  if (!higher.IsInitialized() || Empty()) {
+    return false;
+  }
+  return packet_number_intervals_.TrimLessThan(higher);
+}
+
+void PacketNumberQueue::RemoveSmallestInterval() {
+  // TODO(wub): Move this QUIC_BUG to upper level.
+  QUIC_BUG_IF(quic_bug_12614_1, packet_number_intervals_.Size() < 2)
+      << (Empty() ? "No intervals to remove."
+                  : "Can't remove the last interval.");
+  packet_number_intervals_.PopFront();
+}
+
+void PacketNumberQueue::Clear() {
+  packet_number_intervals_.Clear();
+}
+
+bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
+  if (!packet_number.IsInitialized()) {
+    return false;
+  }
+  return packet_number_intervals_.Contains(packet_number);
+}
+
+bool PacketNumberQueue::Empty() const {
+  return packet_number_intervals_.Empty();
+}
+
+QuicPacketNumber PacketNumberQueue::Min() const {
+  QUICHE_DCHECK(!Empty());
+  return packet_number_intervals_.begin()->min();
+}
+
+QuicPacketNumber PacketNumberQueue::Max() const {
+  QUICHE_DCHECK(!Empty());
+  return packet_number_intervals_.rbegin()->max() - 1;
+}
+
+QuicPacketCount PacketNumberQueue::NumPacketsSlow() const {
+  QuicPacketCount n_packets = 0;
+  for (const auto& interval : packet_number_intervals_) {
+    n_packets += interval.Length();
+  }
+  return n_packets;
+}
+
+size_t PacketNumberQueue::NumIntervals() const {
+  return packet_number_intervals_.Size();
+}
+
+PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
+  return packet_number_intervals_.begin();
+}
+
+PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
+  return packet_number_intervals_.end();
+}
+
+PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const {
+  return packet_number_intervals_.rbegin();
+}
+
+PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const {
+  return packet_number_intervals_.rend();
+}
+
+QuicPacketCount PacketNumberQueue::LastIntervalLength() const {
+  QUICHE_DCHECK(!Empty());
+  return packet_number_intervals_.rbegin()->Length();
+}
+
+// Largest min...max range for packet numbers where we print the numbers
+// explicitly. If bigger than this, we print as a range  [a,d] rather
+// than [a b c d]
+
+std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) {
+  for (const QuicInterval<QuicPacketNumber>& interval : q) {
+    // Print as a range if there is a pathological condition.
+    if ((interval.min() >= interval.max()) ||
+        (interval.max() - interval.min() > kMaxPrintRange)) {
+      // If min>max, it's really a bug, so QUIC_BUG it to
+      // catch it in development.
+      QUIC_BUG_IF(quic_bug_12614_2, interval.min() >= interval.max())
+          << "Ack Range minimum (" << interval.min() << "Not less than max ("
+          << interval.max() << ")";
+      // print range as min...max rather than full list.
+      // in the event of a bug, the list could be very big.
+      os << interval.min() << "..." << (interval.max() - 1) << " ";
+    } else {
+      for (QuicPacketNumber packet_number = interval.min();
+           packet_number < interval.max(); ++packet_number) {
+        os << packet_number << " ";
+      }
+    }
+  }
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ack_frame.h b/quiche/quic/core/frames/quic_ack_frame.h
new file mode 100644
index 0000000..9d66375
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frame.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+// A sequence of packet numbers where each number is unique. Intended to be used
+// in a sliding window fashion, where smaller old packet numbers are removed and
+// larger new packet numbers are added, with the occasional random access.
+class QUIC_EXPORT_PRIVATE PacketNumberQueue {
+ public:
+  PacketNumberQueue();
+  PacketNumberQueue(const PacketNumberQueue& other);
+  PacketNumberQueue(PacketNumberQueue&& other);
+  ~PacketNumberQueue();
+
+  PacketNumberQueue& operator=(const PacketNumberQueue& other);
+  PacketNumberQueue& operator=(PacketNumberQueue&& other);
+
+  using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator;
+  using const_reverse_iterator =
+      QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator;
+
+  // Adds |packet_number| to the set of packets in the queue.
+  void Add(QuicPacketNumber packet_number);
+
+  // Adds packets between [lower, higher) to the set of packets in the queue.
+  // No-op if |higher| < |lower|.
+  // NOTE(wub): Only used in tests as of Nov 2019.
+  void AddRange(QuicPacketNumber lower, QuicPacketNumber higher);
+
+  // Removes packets with values less than |higher| from the set of packets in
+  // the queue. Returns true if packets were removed.
+  bool RemoveUpTo(QuicPacketNumber higher);
+
+  // Removes the smallest interval in the queue.
+  void RemoveSmallestInterval();
+
+  // Clear this packet number queue.
+  void Clear();
+
+  // Returns true if the queue contains |packet_number|.
+  bool Contains(QuicPacketNumber packet_number) const;
+
+  // Returns true if the queue is empty.
+  bool Empty() const;
+
+  // Returns the minimum packet number stored in the queue. It is undefined
+  // behavior to call this if the queue is empty.
+  QuicPacketNumber Min() const;
+
+  // Returns the maximum packet number stored in the queue. It is undefined
+  // behavior to call this if the queue is empty.
+  QuicPacketNumber Max() const;
+
+  // Returns the number of unique packets stored in the queue. Inefficient; only
+  // exposed for testing.
+  QuicPacketCount NumPacketsSlow() const;
+
+  // Returns the number of disjoint packet number intervals contained in the
+  // queue.
+  size_t NumIntervals() const;
+
+  // Returns the length of last interval.
+  QuicPacketCount LastIntervalLength() const;
+
+  // Returns iterators over the packet number intervals.
+  const_iterator begin() const;
+  const_iterator end() const;
+  const_reverse_iterator rbegin() const;
+  const_reverse_iterator rend() const;
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const PacketNumberQueue& q);
+
+ private:
+  QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicAckFrame {
+  QuicAckFrame();
+  QuicAckFrame(const QuicAckFrame& other);
+  ~QuicAckFrame();
+
+  void Clear();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicAckFrame& ack_frame);
+
+  // The highest packet number we've observed from the peer. When |packets| is
+  // not empty, it should always be equal to packets.Max(). The |LargestAcked|
+  // function ensures this invariant in debug mode.
+  QuicPacketNumber largest_acked;
+
+  // Time elapsed since largest_observed() was received until this Ack frame was
+  // sent.
+  QuicTime::Delta ack_delay_time = QuicTime::Delta::Infinite();
+
+  // Vector of <packet_number, time> for when packets arrived.
+  // For IETF versions, packet numbers and timestamps in this vector are both in
+  // ascending orders. Packets received out of order are not saved here.
+  PacketTimeVector received_packet_times;
+
+  // Set of packets.
+  PacketNumberQueue packets;
+
+  // ECN counters, used only in version 99's ACK frame and valid only when
+  // |ecn_counters_populated| is true.
+  bool ecn_counters_populated = false;
+  QuicPacketCount ect_0_count = 0;
+  QuicPacketCount ect_1_count = 0;
+  QuicPacketCount ecn_ce_count = 0;
+};
+
+// The highest acked packet number we've observed from the peer. If no packets
+// have been observed, return 0.
+inline QUIC_EXPORT_PRIVATE QuicPacketNumber
+LargestAcked(const QuicAckFrame& frame) {
+  QUICHE_DCHECK(frame.packets.Empty() ||
+                frame.packets.Max() == frame.largest_acked);
+  return frame.largest_acked;
+}
+
+// True if the packet number is greater than largest_observed or is listed
+// as missing.
+// Always returns false for packet numbers less than least_unacked.
+QUIC_EXPORT_PRIVATE bool IsAwaitingPacket(
+    const QuicAckFrame& ack_frame,
+    QuicPacketNumber packet_number,
+    QuicPacketNumber peer_least_packet_awaiting_ack);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_ack_frequency_frame.cc b/quiche/quic/core/frames/quic_ack_frequency_frame.cc
new file mode 100644
index 0000000..472b882
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frequency_frame.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include <cstdint>
+#include <limits>
+
+namespace quic {
+
+QuicAckFrequencyFrame::QuicAckFrequencyFrame(
+    QuicControlFrameId control_frame_id,
+    uint64_t sequence_number,
+    uint64_t packet_tolerance,
+    QuicTime::Delta max_ack_delay)
+    : control_frame_id(control_frame_id),
+      sequence_number(sequence_number),
+      packet_tolerance(packet_tolerance),
+      max_ack_delay(max_ack_delay) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicAckFrequencyFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", sequence_number: " << frame.sequence_number
+     << ", packet_tolerance: " << frame.packet_tolerance
+     << ", max_ack_delay_ms: " << frame.max_ack_delay.ToMilliseconds()
+     << ", ignore_order: " << frame.ignore_order << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ack_frequency_frame.h b/quiche/quic/core/frames/quic_ack_frequency_frame.h
new file mode 100644
index 0000000..f69351a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ack_frequency_frame.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A frame that allows sender control of acknowledgement delays.
+struct QUIC_EXPORT_PRIVATE QuicAckFrequencyFrame {
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  QuicAckFrequencyFrame() = default;
+  QuicAckFrequencyFrame(QuicControlFrameId control_frame_id,
+                        uint64_t sequence_number,
+                        uint64_t packet_tolerance,
+                        QuicTime::Delta max_ack_delay);
+
+  // A unique identifier of this control frame. 0 when this frame is
+  // received, and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // If true, do not ack immediately upon observeation of packet reordering.
+  bool ignore_order = false;
+
+  // Sequence number assigned to the ACK_FREQUENCY frame by the sender to allow
+  // receivers to ignore obsolete frames.
+  uint64_t sequence_number = 0;
+
+  // The maximum number of ack-eliciting packets after which the receiver sends
+  // an acknowledgement. Invald if == 0.
+  uint64_t packet_tolerance = 2;
+
+  // The maximum time that ack packets can be delayed.
+  QuicTime::Delta max_ack_delay =
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_blocked_frame.cc b/quiche/quic/core/frames/quic_blocked_frame.cc
new file mode 100644
index 0000000..a3e8ebe
--- /dev/null
+++ b/quiche/quic/core/frames/quic_blocked_frame.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_blocked_frame.h"
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicBlockedFrame::QuicBlockedFrame() : QuicInlinedFrame(BLOCKED_FRAME) {}
+
+QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
+                                   QuicStreamId stream_id)
+    : QuicInlinedFrame(BLOCKED_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      offset(0) {}
+
+QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
+                                   QuicStreamId stream_id,
+                                   QuicStreamOffset offset)
+    : QuicInlinedFrame(BLOCKED_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      offset(offset) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicBlockedFrame& blocked_frame) {
+  os << "{ control_frame_id: " << blocked_frame.control_frame_id
+     << ", stream_id: " << blocked_frame.stream_id << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_blocked_frame.h b/quiche/quic/core/frames/quic_blocked_frame.h
new file mode 100644
index 0000000..32a515e
--- /dev/null
+++ b/quiche/quic/core/frames/quic_blocked_frame.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// The BLOCKED frame is used to indicate to the remote endpoint that this
+// endpoint believes itself to be flow-control blocked but otherwise ready to
+// send data. The BLOCKED frame is purely advisory and optional.
+// Based on SPDY's BLOCKED frame (undocumented as of 2014-01-28).
+struct QUIC_EXPORT_PRIVATE QuicBlockedFrame
+    : public QuicInlinedFrame<QuicBlockedFrame> {
+  QuicBlockedFrame();
+  QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id);
+  QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id,
+                   QuicStreamOffset offset);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicBlockedFrame& b);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // 0 is a special case meaning the connection is blocked, rather than a
+  // stream.  So stream_id 0 corresponds to a BLOCKED frame and non-0
+  // corresponds to a STREAM_BLOCKED.
+  // TODO(fkastenholz): This should be converted to use
+  // QuicUtils::GetInvalidStreamId to get the correct invalid stream id value
+  // and not rely on 0.
+  QuicStreamId stream_id = 0;
+
+  // For Google QUIC, the offset is ignored.
+  QuicStreamOffset offset = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_connection_close_frame.cc b/quiche/quic/core/frames/quic_connection_close_frame.cc
new file mode 100644
index 0000000..44fa18a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_connection_close_frame.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+
+#include <memory>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicConnectionCloseFrame::QuicConnectionCloseFrame(
+    QuicTransportVersion transport_version,
+    QuicErrorCode error_code,
+    QuicIetfTransportErrorCodes ietf_error,
+    std::string error_phrase,
+    uint64_t frame_type)
+    : quic_error_code(error_code), error_details(error_phrase) {
+  if (!VersionHasIetfQuicFrames(transport_version)) {
+    close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
+    wire_error_code = error_code;
+    transport_close_frame_type = 0;
+    return;
+  }
+  QuicErrorCodeToIetfMapping mapping =
+      QuicErrorCodeToTransportErrorCode(error_code);
+  if (ietf_error != NO_IETF_QUIC_ERROR) {
+    wire_error_code = ietf_error;
+  } else {
+    wire_error_code = mapping.error_code;
+  }
+  if (mapping.is_transport_close) {
+    // Maps to a transport close
+    close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
+    transport_close_frame_type = frame_type;
+    return;
+  }
+  // Maps to an application close.
+  close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
+  transport_close_frame_type = 0;
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const QuicConnectionCloseFrame& connection_close_frame) {
+  os << "{ Close type: " << connection_close_frame.close_type;
+  switch (connection_close_frame.close_type) {
+    case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+      os << ", wire_error_code: "
+         << static_cast<QuicIetfTransportErrorCodes>(
+                connection_close_frame.wire_error_code);
+      break;
+    case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+      os << ", wire_error_code: " << connection_close_frame.wire_error_code;
+      break;
+    case GOOGLE_QUIC_CONNECTION_CLOSE:
+      // Do not log, value same as |quic_error_code|.
+      break;
+  }
+  os << ", quic_error_code: "
+     << QuicErrorCodeToString(connection_close_frame.quic_error_code)
+     << ", error_details: '" << connection_close_frame.error_details << "'";
+  if (connection_close_frame.close_type ==
+      IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    os << ", frame_type: "
+       << static_cast<QuicIetfFrameType>(
+              connection_close_frame.transport_close_frame_type);
+  }
+  os << "}\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_connection_close_frame.h b/quiche/quic/core/frames/quic_connection_close_frame.h
new file mode 100644
index 0000000..15e83d3
--- /dev/null
+++ b/quiche/quic/core/frames/quic_connection_close_frame.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
+
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame {
+  QuicConnectionCloseFrame() = default;
+
+  // Builds a connection close frame based on the transport version
+  // and the mapping of error_code. THIS IS THE PREFERRED C'TOR
+  // TO USE IF YOU NEED TO CREATE A CONNECTION-CLOSE-FRAME AND
+  // HAVE IT BE CORRECT FOR THE VERSION AND CODE MAPPINGS.
+  // |ietf_error| may optionally be be used to directly specify the wire
+  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
+  // QuicErrorCodeToTransportErrorCode mapping of |error_code| will be used.
+  QuicConnectionCloseFrame(QuicTransportVersion transport_version,
+                           QuicErrorCode error_code,
+                           QuicIetfTransportErrorCodes ietf_error,
+                           std::string error_phrase,
+                           uint64_t transport_close_frame_type);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConnectionCloseFrame& c);
+
+  // Indicates whether the the frame is a Google QUIC CONNECTION_CLOSE frame,
+  // an IETF QUIC CONNECTION_CLOSE frame with transport error code,
+  // or an IETF QUIC CONNECTION_CLOSE frame with application error code.
+  QuicConnectionCloseType close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
+
+  // The error code on the wire.  For Google QUIC frames, this has the same
+  // value as |quic_error_code|.
+  uint64_t wire_error_code = QUIC_NO_ERROR;
+
+  // The underlying error.  For Google QUIC frames, this has the same value as
+  // |wire_error_code|.  For sent IETF QUIC frames, this is the error that
+  // triggered the closure of the connection.  For received IETF QUIC frames,
+  // this is parsed from the Reason Phrase field of the CONNECTION_CLOSE frame,
+  // or QUIC_IETF_GQUIC_ERROR_MISSING.
+  QuicErrorCode quic_error_code = QUIC_NO_ERROR;
+
+  // String with additional error details. |quic_error_code| and a colon will be
+  // prepended to the error details when sending IETF QUIC frames, and parsed
+  // into |quic_error_code| upon receipt, when present.
+  std::string error_details;
+
+  // The frame type present in the IETF transport connection close frame.
+  // Not populated for the Google QUIC or application connection close frames.
+  // Contains the type of frame that triggered the connection close. Made a
+  // uint64, as opposed to the QuicIetfFrameType, to support possible
+  // extensions as well as reporting invalid frame types received from the peer.
+  uint64_t transport_close_frame_type = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_CONNECTION_CLOSE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_crypto_frame.cc b/quiche/quic/core/frames/quic_crypto_frame.cc
new file mode 100644
index 0000000..4f27dab
--- /dev/null
+++ b/quiche/quic/core/frames/quic_crypto_frame.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
+                                 QuicStreamOffset offset,
+                                 QuicPacketLength data_length)
+    : QuicCryptoFrame(level, offset, nullptr, data_length) {}
+
+QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
+                                 QuicStreamOffset offset,
+                                 absl::string_view data)
+    : QuicCryptoFrame(level, offset, data.data(), data.length()) {}
+
+QuicCryptoFrame::QuicCryptoFrame(EncryptionLevel level,
+                                 QuicStreamOffset offset,
+                                 const char* data_buffer,
+                                 QuicPacketLength data_length)
+    : level(level),
+      data_length(data_length),
+      data_buffer(data_buffer),
+      offset(offset) {}
+
+QuicCryptoFrame::~QuicCryptoFrame() {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicCryptoFrame& stream_frame) {
+  os << "{ level: " << stream_frame.level << ", offset: " << stream_frame.offset
+     << ", length: " << stream_frame.data_length << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_crypto_frame.h b/quiche/quic/core/frames/quic_crypto_frame.h
new file mode 100644
index 0000000..2d1c776
--- /dev/null
+++ b/quiche/quic/core/frames/quic_crypto_frame.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicCryptoFrame {
+  QuicCryptoFrame() = default;
+  QuicCryptoFrame(EncryptionLevel level,
+                  QuicStreamOffset offset,
+                  QuicPacketLength data_length);
+  QuicCryptoFrame(EncryptionLevel level,
+                  QuicStreamOffset offset,
+                  absl::string_view data);
+  ~QuicCryptoFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicCryptoFrame& s);
+
+  // When writing a crypto frame to a packet, the packet must be encrypted at
+  // |level|. When a crypto frame is read, the encryption level of the packet it
+  // was received in is put in |level|.
+  EncryptionLevel level = ENCRYPTION_INITIAL;
+  QuicPacketLength data_length = 0;
+  // When reading, |data_buffer| points to the data that was received in the
+  // frame. |data_buffer| is not used when writing.
+  const char* data_buffer = nullptr;
+  QuicStreamOffset offset = 0;  // Location of this data in the stream.
+
+  QuicCryptoFrame(EncryptionLevel level,
+                  QuicStreamOffset offset,
+                  const char* data_buffer,
+                  QuicPacketLength data_length);
+};
+static_assert(sizeof(QuicCryptoFrame) <= 64,
+              "Keep the QuicCryptoFrame size to a cacheline.");
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_CRYPTO_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_frame.cc b/quiche/quic/core/frames/quic_frame.cc
new file mode 100644
index 0000000..6200eb2
--- /dev/null
+++ b/quiche/quic/core/frames/quic_frame.cc
@@ -0,0 +1,527 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_frame.h"
+
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+QuicFrame::QuicFrame() {}
+
+QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
+    : padding_frame(padding_frame) {}
+
+QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
+    : stream_frame(stream_frame) {}
+
+QuicFrame::QuicFrame(QuicHandshakeDoneFrame handshake_done_frame)
+    : handshake_done_frame(handshake_done_frame) {}
+
+QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
+    : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}
+
+QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
+    : mtu_discovery_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
+    : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
+    : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
+    : type(GOAWAY_FRAME), goaway_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicWindowUpdateFrame frame)
+    : window_update_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicBlockedFrame frame) : blocked_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
+    : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
+    : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
+    : streams_blocked_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
+    : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
+    : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicStopSendingFrame frame) : stop_sending_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicMessageFrame* frame)
+    : type(MESSAGE_FRAME), message_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
+    : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}
+
+QuicFrame::QuicFrame(QuicAckFrequencyFrame* frame)
+    : type(ACK_FREQUENCY_FRAME), ack_frequency_frame(frame) {}
+
+void DeleteFrames(QuicFrames* frames) {
+  for (QuicFrame& frame : *frames) {
+    DeleteFrame(&frame);
+  }
+  frames->clear();
+}
+
+void DeleteFrame(QuicFrame* frame) {
+#if QUIC_FRAME_DEBUG
+  // If the frame is not inlined, check that it can be safely deleted.
+  if (frame->type != PADDING_FRAME && frame->type != MTU_DISCOVERY_FRAME &&
+      frame->type != PING_FRAME && frame->type != MAX_STREAMS_FRAME &&
+      frame->type != STOP_WAITING_FRAME &&
+      frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
+      frame->type != HANDSHAKE_DONE_FRAME &&
+      frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME &&
+      frame->type != STOP_SENDING_FRAME) {
+    QUICHE_CHECK(!frame->delete_forbidden) << *frame;
+  }
+#endif  // QUIC_FRAME_DEBUG
+  switch (frame->type) {
+    // Frames smaller than a pointer are inlined, so don't need to be deleted.
+    case PADDING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case PING_FRAME:
+    case MAX_STREAMS_FRAME:
+    case STOP_WAITING_FRAME:
+    case STREAMS_BLOCKED_FRAME:
+    case STREAM_FRAME:
+    case HANDSHAKE_DONE_FRAME:
+    case WINDOW_UPDATE_FRAME:
+    case BLOCKED_FRAME:
+    case STOP_SENDING_FRAME:
+      break;
+    case ACK_FRAME:
+      delete frame->ack_frame;
+      break;
+    case RST_STREAM_FRAME:
+      delete frame->rst_stream_frame;
+      break;
+    case CONNECTION_CLOSE_FRAME:
+      delete frame->connection_close_frame;
+      break;
+    case GOAWAY_FRAME:
+      delete frame->goaway_frame;
+      break;
+    case PATH_CHALLENGE_FRAME:
+      delete frame->path_challenge_frame;
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      delete frame->new_connection_id_frame;
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      delete frame->retire_connection_id_frame;
+      break;
+    case PATH_RESPONSE_FRAME:
+      delete frame->path_response_frame;
+      break;
+    case MESSAGE_FRAME:
+      delete frame->message_frame;
+      break;
+    case CRYPTO_FRAME:
+      delete frame->crypto_frame;
+      break;
+    case NEW_TOKEN_FRAME:
+      delete frame->new_token_frame;
+      break;
+    case ACK_FREQUENCY_FRAME:
+      delete frame->ack_frequency_frame;
+      break;
+    case NUM_FRAME_TYPES:
+      QUICHE_DCHECK(false) << "Cannot delete type: " << frame->type;
+  }
+}
+
+void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
+  auto it = frames->begin();
+  while (it != frames->end()) {
+    if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
+      ++it;
+      continue;
+    }
+    it = frames->erase(it);
+  }
+}
+
+bool IsControlFrame(QuicFrameType type) {
+  switch (type) {
+    case RST_STREAM_FRAME:
+    case GOAWAY_FRAME:
+    case WINDOW_UPDATE_FRAME:
+    case BLOCKED_FRAME:
+    case STREAMS_BLOCKED_FRAME:
+    case MAX_STREAMS_FRAME:
+    case PING_FRAME:
+    case STOP_SENDING_FRAME:
+    case NEW_CONNECTION_ID_FRAME:
+    case RETIRE_CONNECTION_ID_FRAME:
+    case HANDSHAKE_DONE_FRAME:
+    case ACK_FREQUENCY_FRAME:
+    case NEW_TOKEN_FRAME:
+      return true;
+    default:
+      return false;
+  }
+}
+
+QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
+  switch (frame.type) {
+    case RST_STREAM_FRAME:
+      return frame.rst_stream_frame->control_frame_id;
+    case GOAWAY_FRAME:
+      return frame.goaway_frame->control_frame_id;
+    case WINDOW_UPDATE_FRAME:
+      return frame.window_update_frame.control_frame_id;
+    case BLOCKED_FRAME:
+      return frame.blocked_frame.control_frame_id;
+    case STREAMS_BLOCKED_FRAME:
+      return frame.streams_blocked_frame.control_frame_id;
+    case MAX_STREAMS_FRAME:
+      return frame.max_streams_frame.control_frame_id;
+    case PING_FRAME:
+      return frame.ping_frame.control_frame_id;
+    case STOP_SENDING_FRAME:
+      return frame.stop_sending_frame.control_frame_id;
+    case NEW_CONNECTION_ID_FRAME:
+      return frame.new_connection_id_frame->control_frame_id;
+    case RETIRE_CONNECTION_ID_FRAME:
+      return frame.retire_connection_id_frame->control_frame_id;
+    case HANDSHAKE_DONE_FRAME:
+      return frame.handshake_done_frame.control_frame_id;
+    case ACK_FREQUENCY_FRAME:
+      return frame.ack_frequency_frame->control_frame_id;
+    case NEW_TOKEN_FRAME:
+      return frame.new_token_frame->control_frame_id;
+    default:
+      return kInvalidControlFrameId;
+  }
+}
+
+void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
+  switch (frame->type) {
+    case RST_STREAM_FRAME:
+      frame->rst_stream_frame->control_frame_id = control_frame_id;
+      return;
+    case GOAWAY_FRAME:
+      frame->goaway_frame->control_frame_id = control_frame_id;
+      return;
+    case WINDOW_UPDATE_FRAME:
+      frame->window_update_frame.control_frame_id = control_frame_id;
+      return;
+    case BLOCKED_FRAME:
+      frame->blocked_frame.control_frame_id = control_frame_id;
+      return;
+    case PING_FRAME:
+      frame->ping_frame.control_frame_id = control_frame_id;
+      return;
+    case STREAMS_BLOCKED_FRAME:
+      frame->streams_blocked_frame.control_frame_id = control_frame_id;
+      return;
+    case MAX_STREAMS_FRAME:
+      frame->max_streams_frame.control_frame_id = control_frame_id;
+      return;
+    case STOP_SENDING_FRAME:
+      frame->stop_sending_frame.control_frame_id = control_frame_id;
+      return;
+    case NEW_CONNECTION_ID_FRAME:
+      frame->new_connection_id_frame->control_frame_id = control_frame_id;
+      return;
+    case RETIRE_CONNECTION_ID_FRAME:
+      frame->retire_connection_id_frame->control_frame_id = control_frame_id;
+      return;
+    case HANDSHAKE_DONE_FRAME:
+      frame->handshake_done_frame.control_frame_id = control_frame_id;
+      return;
+    case ACK_FREQUENCY_FRAME:
+      frame->ack_frequency_frame->control_frame_id = control_frame_id;
+      return;
+    case NEW_TOKEN_FRAME:
+      frame->new_token_frame->control_frame_id = control_frame_id;
+      return;
+    default:
+      QUIC_BUG(quic_bug_12594_1)
+          << "Try to set control frame id of a frame without control frame id";
+  }
+}
+
+QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
+  QuicFrame copy;
+  switch (frame.type) {
+    case RST_STREAM_FRAME:
+      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
+      break;
+    case GOAWAY_FRAME:
+      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
+      break;
+    case WINDOW_UPDATE_FRAME:
+      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
+      break;
+    case BLOCKED_FRAME:
+      copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
+      break;
+    case PING_FRAME:
+      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
+      break;
+    case STOP_SENDING_FRAME:
+      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
+      break;
+    case MAX_STREAMS_FRAME:
+      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      copy = QuicFrame(
+          QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
+      break;
+    case ACK_FREQUENCY_FRAME:
+      copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
+      break;
+    case NEW_TOKEN_FRAME:
+      copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
+      break;
+    default:
+      QUIC_BUG(quic_bug_10533_1)
+          << "Try to copy a non-retransmittable control frame: " << frame;
+      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
+      break;
+  }
+  return copy;
+}
+
+QuicFrame CopyQuicFrame(quiche::QuicheBufferAllocator* allocator,
+                        const QuicFrame& frame) {
+  QuicFrame copy;
+  switch (frame.type) {
+    case PADDING_FRAME:
+      copy = QuicFrame(QuicPaddingFrame(frame.padding_frame));
+      break;
+    case RST_STREAM_FRAME:
+      copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
+      break;
+    case CONNECTION_CLOSE_FRAME:
+      copy = QuicFrame(
+          new QuicConnectionCloseFrame(*frame.connection_close_frame));
+      break;
+    case GOAWAY_FRAME:
+      copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
+      break;
+    case WINDOW_UPDATE_FRAME:
+      copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
+      break;
+    case BLOCKED_FRAME:
+      copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
+      break;
+    case STOP_WAITING_FRAME:
+      copy = QuicFrame(QuicStopWaitingFrame(frame.stop_waiting_frame));
+      break;
+    case PING_FRAME:
+      copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
+      break;
+    case CRYPTO_FRAME:
+      copy = QuicFrame(new QuicCryptoFrame(*frame.crypto_frame));
+      break;
+    case STREAM_FRAME:
+      copy = QuicFrame(QuicStreamFrame(frame.stream_frame));
+      break;
+    case ACK_FRAME:
+      copy = QuicFrame(new QuicAckFrame(*frame.ack_frame));
+      break;
+    case MTU_DISCOVERY_FRAME:
+      copy = QuicFrame(QuicMtuDiscoveryFrame(frame.mtu_discovery_frame));
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
+      break;
+    case MAX_STREAMS_FRAME:
+      copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
+      break;
+    case PATH_RESPONSE_FRAME:
+      copy = QuicFrame(new QuicPathResponseFrame(*frame.path_response_frame));
+      break;
+    case PATH_CHALLENGE_FRAME:
+      copy = QuicFrame(new QuicPathChallengeFrame(*frame.path_challenge_frame));
+      break;
+    case STOP_SENDING_FRAME:
+      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
+      break;
+    case MESSAGE_FRAME:
+      copy = QuicFrame(new QuicMessageFrame(frame.message_frame->message_id));
+      copy.message_frame->data = frame.message_frame->data;
+      copy.message_frame->message_length = frame.message_frame->message_length;
+      for (const auto& slice : frame.message_frame->message_data) {
+        quiche::QuicheBuffer buffer =
+            quiche::QuicheBuffer::Copy(allocator, slice.AsStringView());
+        copy.message_frame->message_data.push_back(
+            quiche::QuicheMemSlice(std::move(buffer)));
+      }
+      break;
+    case NEW_TOKEN_FRAME:
+      copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      copy = QuicFrame(
+          new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      copy = QuicFrame(
+          QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
+      break;
+    case ACK_FREQUENCY_FRAME:
+      copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
+      break;
+    default:
+      QUIC_BUG(quic_bug_10533_2) << "Cannot copy frame: " << frame;
+      copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
+      break;
+  }
+  return copy;
+}
+
+QuicFrames CopyQuicFrames(quiche::QuicheBufferAllocator* allocator,
+                          const QuicFrames& frames) {
+  QuicFrames copy;
+  for (const auto& frame : frames) {
+    copy.push_back(CopyQuicFrame(allocator, frame));
+  }
+  return copy;
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
+  switch (frame.type) {
+    case PADDING_FRAME: {
+      os << "type { PADDING_FRAME } " << frame.padding_frame;
+      break;
+    }
+    case RST_STREAM_FRAME: {
+      os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
+      break;
+    }
+    case CONNECTION_CLOSE_FRAME: {
+      os << "type { CONNECTION_CLOSE_FRAME } "
+         << *(frame.connection_close_frame);
+      break;
+    }
+    case GOAWAY_FRAME: {
+      os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
+      break;
+    }
+    case WINDOW_UPDATE_FRAME: {
+      os << "type { WINDOW_UPDATE_FRAME } " << frame.window_update_frame;
+      break;
+    }
+    case BLOCKED_FRAME: {
+      os << "type { BLOCKED_FRAME } " << frame.blocked_frame;
+      break;
+    }
+    case STREAM_FRAME: {
+      os << "type { STREAM_FRAME } " << frame.stream_frame;
+      break;
+    }
+    case ACK_FRAME: {
+      os << "type { ACK_FRAME } " << *(frame.ack_frame);
+      break;
+    }
+    case STOP_WAITING_FRAME: {
+      os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
+      break;
+    }
+    case PING_FRAME: {
+      os << "type { PING_FRAME } " << frame.ping_frame;
+      break;
+    }
+    case CRYPTO_FRAME: {
+      os << "type { CRYPTO_FRAME } " << *(frame.crypto_frame);
+      break;
+    }
+    case MTU_DISCOVERY_FRAME: {
+      os << "type { MTU_DISCOVERY_FRAME } ";
+      break;
+    }
+    case NEW_CONNECTION_ID_FRAME:
+      os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      os << "type { RETIRE_CONNECTION_ID } "
+         << *(frame.retire_connection_id_frame);
+      break;
+    case MAX_STREAMS_FRAME:
+      os << "type { MAX_STREAMS } " << frame.max_streams_frame;
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
+      break;
+    case PATH_RESPONSE_FRAME:
+      os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
+      break;
+    case PATH_CHALLENGE_FRAME:
+      os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
+      break;
+    case STOP_SENDING_FRAME:
+      os << "type { STOP_SENDING } " << frame.stop_sending_frame;
+      break;
+    case MESSAGE_FRAME:
+      os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
+      break;
+    case NEW_TOKEN_FRAME:
+      os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      os << "type { HANDSHAKE_DONE_FRAME } " << frame.handshake_done_frame;
+      break;
+    case ACK_FREQUENCY_FRAME:
+      os << "type { ACK_FREQUENCY_FRAME } " << *(frame.ack_frequency_frame);
+      break;
+    default: {
+      QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
+      break;
+    }
+  }
+  return os;
+}
+
+std::string QuicFramesToString(const QuicFrames& frames) {
+  std::ostringstream os;
+  for (const QuicFrame& frame : frames) {
+    os << frame;
+  }
+  return os.str();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_frame.h b/quiche/quic/core/frames/quic_frame.h
new file mode 100644
index 0000000..ce82ea7
--- /dev/null
+++ b/quiche/quic/core/frames/quic_frame.h
@@ -0,0 +1,177 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
+
+#include <ostream>
+#include <type_traits>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/quic/core/frames/quic_ack_frame.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_blocked_frame.h"
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_goaway_frame.h"
+#include "quiche/quic/core/frames/quic_handshake_done_frame.h"
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+#include "quiche/quic/core/frames/quic_message_frame.h"
+#include "quiche/quic/core/frames/quic_mtu_discovery_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_new_token_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+#include "quiche/quic/core/frames/quic_path_response_frame.h"
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/frames/quic_stop_sending_frame.h"
+#include "quiche/quic/core/frames/quic_stop_waiting_frame.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+#ifndef QUIC_FRAME_DEBUG
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define QUIC_FRAME_DEBUG 1
+#else  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define QUIC_FRAME_DEBUG 0
+#endif  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#endif  // QUIC_FRAME_DEBUG
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicFrame {
+  QuicFrame();
+  // Please keep the constructors in the same order as the union below.
+  explicit QuicFrame(QuicPaddingFrame padding_frame);
+  explicit QuicFrame(QuicMtuDiscoveryFrame frame);
+  explicit QuicFrame(QuicPingFrame frame);
+  explicit QuicFrame(QuicMaxStreamsFrame frame);
+  explicit QuicFrame(QuicStopWaitingFrame frame);
+  explicit QuicFrame(QuicStreamsBlockedFrame frame);
+  explicit QuicFrame(QuicStreamFrame stream_frame);
+  explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame);
+  explicit QuicFrame(QuicWindowUpdateFrame frame);
+  explicit QuicFrame(QuicBlockedFrame frame);
+  explicit QuicFrame(QuicStopSendingFrame frame);
+
+  explicit QuicFrame(QuicAckFrame* frame);
+  explicit QuicFrame(QuicRstStreamFrame* frame);
+  explicit QuicFrame(QuicConnectionCloseFrame* frame);
+  explicit QuicFrame(QuicGoAwayFrame* frame);
+  explicit QuicFrame(QuicNewConnectionIdFrame* frame);
+  explicit QuicFrame(QuicRetireConnectionIdFrame* frame);
+  explicit QuicFrame(QuicNewTokenFrame* frame);
+  explicit QuicFrame(QuicPathResponseFrame* frame);
+  explicit QuicFrame(QuicPathChallengeFrame* frame);
+  explicit QuicFrame(QuicMessageFrame* message_frame);
+  explicit QuicFrame(QuicCryptoFrame* crypto_frame);
+  explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const QuicFrame& frame);
+
+  union {
+    // Inlined frames.
+    // Overlapping inlined frames have a |type| field at the same 0 offset as
+    // QuicFrame does for out of line frames below, allowing use of the
+    // remaining 7 bytes after offset for frame-type specific fields.
+    QuicPaddingFrame padding_frame;
+    QuicMtuDiscoveryFrame mtu_discovery_frame;
+    QuicPingFrame ping_frame;
+    QuicMaxStreamsFrame max_streams_frame;
+    QuicStopWaitingFrame stop_waiting_frame;
+    QuicStreamsBlockedFrame streams_blocked_frame;
+    QuicStreamFrame stream_frame;
+    QuicHandshakeDoneFrame handshake_done_frame;
+    QuicWindowUpdateFrame window_update_frame;
+    QuicBlockedFrame blocked_frame;
+    QuicStopSendingFrame stop_sending_frame;
+
+    // Out of line frames.
+    struct {
+      QuicFrameType type;
+
+#if QUIC_FRAME_DEBUG
+      bool delete_forbidden = false;
+#endif  // QUIC_FRAME_DEBUG
+
+      // TODO(wub): These frames can also be inlined without increasing the size
+      // of QuicFrame:
+      // QuicPathResponseFrame, QuicPathChallengeFrame.
+      union {
+        QuicAckFrame* ack_frame;
+        QuicRstStreamFrame* rst_stream_frame;
+        QuicConnectionCloseFrame* connection_close_frame;
+        QuicGoAwayFrame* goaway_frame;
+        QuicNewConnectionIdFrame* new_connection_id_frame;
+        QuicRetireConnectionIdFrame* retire_connection_id_frame;
+        QuicPathResponseFrame* path_response_frame;
+        QuicPathChallengeFrame* path_challenge_frame;
+        QuicMessageFrame* message_frame;
+        QuicCryptoFrame* crypto_frame;
+        QuicAckFrequencyFrame* ack_frequency_frame;
+        QuicNewTokenFrame* new_token_frame;
+      };
+    };
+  };
+};
+
+static_assert(std::is_standard_layout<QuicFrame>::value,
+              "QuicFrame must have a standard layout");
+static_assert(sizeof(QuicFrame) <= 24,
+              "Frames larger than 24 bytes should be referenced by pointer.");
+static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type),
+              "Offset of |type| must match in QuicFrame and QuicStreamFrame");
+
+// A inline size of 1 is chosen to optimize the typical use case of
+// 1-stream-frame in QuicTransmissionInfo.retransmittable_frames.
+using QuicFrames = absl::InlinedVector<QuicFrame, 1>;
+
+// Deletes all the sub-frames contained in |frames|.
+QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames);
+
+// Delete the sub-frame contained in |frame|.
+QUIC_EXPORT_PRIVATE void DeleteFrame(QuicFrame* frame);
+
+// Deletes all the QuicStreamFrames for the specified |stream_id|.
+QUIC_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames,
+                                               QuicStreamId stream_id);
+
+// Returns true if |type| is a retransmittable control frame.
+QUIC_EXPORT_PRIVATE bool IsControlFrame(QuicFrameType type);
+
+// Returns control_frame_id of |frame|. Returns kInvalidControlFrameId if
+// |frame| does not have a valid control_frame_id.
+QUIC_EXPORT_PRIVATE QuicControlFrameId
+GetControlFrameId(const QuicFrame& frame);
+
+// Sets control_frame_id of |frame| to |control_frame_id|.
+QUIC_EXPORT_PRIVATE void SetControlFrameId(QuicControlFrameId control_frame_id,
+                                           QuicFrame* frame);
+
+// Returns a copy of |frame|.
+QUIC_EXPORT_PRIVATE QuicFrame
+CopyRetransmittableControlFrame(const QuicFrame& frame);
+
+// Returns a copy of |frame|.
+QUIC_EXPORT_PRIVATE QuicFrame
+CopyQuicFrame(quiche::QuicheBufferAllocator* allocator, const QuicFrame& frame);
+
+// Returns a copy of |frames|.
+QUIC_EXPORT_PRIVATE QuicFrames CopyQuicFrames(
+    quiche::QuicheBufferAllocator* allocator, const QuicFrames& frames);
+
+// Human-readable description suitable for logging.
+QUIC_EXPORT_PRIVATE std::string QuicFramesToString(const QuicFrames& frames);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_frames_test.cc b/quiche/quic/core/frames/quic_frames_test.cc
new file mode 100644
index 0000000..19c50f5
--- /dev/null
+++ b/quiche/quic/core/frames/quic_frames_test.cc
@@ -0,0 +1,832 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_ack_frame.h"
+#include "quiche/quic/core/frames/quic_blocked_frame.h"
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_goaway_frame.h"
+#include "quiche/quic/core/frames/quic_mtu_discovery_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/frames/quic_stop_waiting_frame.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicFramesTest : public QuicTest {};
+
+TEST_F(QuicFramesTest, AckFrameToString) {
+  QuicAckFrame frame;
+  frame.largest_acked = QuicPacketNumber(5);
+  frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
+  frame.packets.Add(QuicPacketNumber(4));
+  frame.packets.Add(QuicPacketNumber(5));
+  frame.received_packet_times = {
+      {QuicPacketNumber(6),
+       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ(
+      "{ largest_acked: 5, ack_delay_time: 3, packets: [ 4 5  ], "
+      "received_packets: [ 6 at 7  ], ecn_counters_populated: 0 }\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, BigAckFrameToString) {
+  QuicAckFrame frame;
+  frame.largest_acked = QuicPacketNumber(500);
+  frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
+  frame.packets.AddRange(QuicPacketNumber(4), QuicPacketNumber(501));
+  frame.received_packet_times = {
+      {QuicPacketNumber(500),
+       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ(
+      "{ largest_acked: 500, ack_delay_time: 3, packets: [ 4...500  ], "
+      "received_packets: [ 500 at 7  ], ecn_counters_populated: 0 }\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, PaddingFrameToString) {
+  QuicPaddingFrame frame;
+  frame.num_padding_bytes = 1;
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ("{ num_padding_bytes: 1 }\n", stream.str());
+  QuicFrame quic_frame(frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, RstStreamFrameToString) {
+  QuicRstStreamFrame rst_stream;
+  QuicFrame frame(&rst_stream);
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  rst_stream.stream_id = 1;
+  rst_stream.byte_offset = 3;
+  rst_stream.error_code = QUIC_STREAM_CANCELLED;
+  std::ostringstream stream;
+  stream << rst_stream;
+  EXPECT_EQ(
+      "{ control_frame_id: 1, stream_id: 1, byte_offset: 3, error_code: 6, "
+      "ietf_error_code: 0 }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, StopSendingFrameToString) {
+  QuicFrame frame((QuicStopSendingFrame()));
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  frame.stop_sending_frame.stream_id = 321;
+  frame.stop_sending_frame.error_code = QUIC_STREAM_CANCELLED;
+  frame.stop_sending_frame.ietf_error_code =
+      static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+  std::ostringstream stream;
+  stream << frame.stop_sending_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 1, stream_id: 321, error_code: 6, ietf_error_code: "
+      "268 }\n",
+      stream.str());
+}
+
+TEST_F(QuicFramesTest, NewConnectionIdFrameToString) {
+  QuicNewConnectionIdFrame new_connection_id_frame;
+  QuicFrame frame(&new_connection_id_frame);
+  SetControlFrameId(1, &frame);
+  QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame_copy));
+  new_connection_id_frame.connection_id = TestConnectionId(2);
+  new_connection_id_frame.sequence_number = 2u;
+  new_connection_id_frame.retire_prior_to = 1u;
+  new_connection_id_frame.stateless_reset_token =
+      StatelessResetToken{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+  std::ostringstream stream;
+  stream << new_connection_id_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 1, connection_id: 0000000000000002, "
+      "sequence_number: 2, retire_prior_to: 1 }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame_copy.type));
+  DeleteFrame(&frame_copy);
+}
+
+TEST_F(QuicFramesTest, RetireConnectionIdFrameToString) {
+  QuicRetireConnectionIdFrame retire_connection_id_frame;
+  QuicFrame frame(&retire_connection_id_frame);
+  SetControlFrameId(1, &frame);
+  QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame_copy));
+  retire_connection_id_frame.sequence_number = 1u;
+  std::ostringstream stream;
+  stream << retire_connection_id_frame;
+  EXPECT_EQ("{ control_frame_id: 1, sequence_number: 1 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame_copy.type));
+  DeleteFrame(&frame_copy);
+}
+
+TEST_F(QuicFramesTest, StreamsBlockedFrameToString) {
+  QuicStreamsBlockedFrame streams_blocked;
+  QuicFrame frame(streams_blocked);
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  // QuicStreamsBlocked is copied into a QuicFrame (as opposed to putting a
+  // pointer to it into QuicFrame) so need to work with the copy in |frame| and
+  // not the original one, streams_blocked.
+  frame.streams_blocked_frame.stream_count = 321;
+  frame.streams_blocked_frame.unidirectional = false;
+  std::ostringstream stream;
+  stream << frame.streams_blocked_frame;
+  EXPECT_EQ("{ control_frame_id: 1, stream count: 321, bidirectional }\n",
+            stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, MaxStreamsFrameToString) {
+  QuicMaxStreamsFrame max_streams;
+  QuicFrame frame(max_streams);
+  SetControlFrameId(1, &frame);
+  EXPECT_EQ(1u, GetControlFrameId(frame));
+  // QuicMaxStreams is copied into a QuicFrame (as opposed to putting a
+  // pointer to it into QuicFrame) so need to work with the copy in |frame| and
+  // not the original one, max_streams.
+  frame.max_streams_frame.stream_count = 321;
+  frame.max_streams_frame.unidirectional = true;
+  std::ostringstream stream;
+  stream << frame.max_streams_frame;
+  EXPECT_EQ("{ control_frame_id: 1, stream_count: 321, unidirectional }\n",
+            stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, ConnectionCloseFrameToString) {
+  QuicConnectionCloseFrame frame;
+  frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  frame.error_details = "No recent network activity.";
+  std::ostringstream stream;
+  stream << frame;
+  // Note that "extracted_error_code: 122" is QUIC_IETF_GQUIC_ERROR_MISSING,
+  // indicating that, in fact, no extended error code was available from the
+  // underlying frame.
+  EXPECT_EQ(
+      "{ Close type: GOOGLE_QUIC_CONNECTION_CLOSE, "
+      "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
+      "error_details: 'No recent network activity.'}\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, TransportConnectionCloseFrameToString) {
+  QuicConnectionCloseFrame frame;
+  frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
+  frame.wire_error_code = FINAL_SIZE_ERROR;
+  frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  frame.error_details = "No recent network activity.";
+  frame.transport_close_frame_type = IETF_STREAM;
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ(
+      "{ Close type: IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, "
+      "wire_error_code: FINAL_SIZE_ERROR, "
+      "quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
+      "error_details: 'No recent "
+      "network activity.', "
+      "frame_type: IETF_STREAM"
+      "}\n",
+      stream.str());
+  QuicFrame quic_frame(&frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, GoAwayFrameToString) {
+  QuicGoAwayFrame goaway_frame;
+  QuicFrame frame(&goaway_frame);
+  SetControlFrameId(2, &frame);
+  EXPECT_EQ(2u, GetControlFrameId(frame));
+  goaway_frame.error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  goaway_frame.last_good_stream_id = 2;
+  goaway_frame.reason_phrase = "Reason";
+  std::ostringstream stream;
+  stream << goaway_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 2, error_code: 25, last_good_stream_id: 2, "
+      "reason_phrase: "
+      "'Reason' }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, WindowUpdateFrameToString) {
+  QuicFrame frame((QuicWindowUpdateFrame()));
+  SetControlFrameId(3, &frame);
+  EXPECT_EQ(3u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  frame.window_update_frame.stream_id = 1;
+  frame.window_update_frame.max_data = 2;
+  stream << frame.window_update_frame;
+  EXPECT_EQ("{ control_frame_id: 3, stream_id: 1, max_data: 2 }\n",
+            stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, BlockedFrameToString) {
+  QuicFrame frame((QuicBlockedFrame()));
+  SetControlFrameId(4, &frame);
+  EXPECT_EQ(4u, GetControlFrameId(frame));
+  frame.blocked_frame.stream_id = 1;
+  std::ostringstream stream;
+  stream << frame.blocked_frame;
+  EXPECT_EQ("{ control_frame_id: 4, stream_id: 1 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, PingFrameToString) {
+  QuicPingFrame ping;
+  QuicFrame frame(ping);
+  SetControlFrameId(5, &frame);
+  EXPECT_EQ(5u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  stream << frame.ping_frame;
+  EXPECT_EQ("{ control_frame_id: 5 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, HandshakeDoneFrameToString) {
+  QuicHandshakeDoneFrame handshake_done;
+  QuicFrame frame(handshake_done);
+  SetControlFrameId(6, &frame);
+  EXPECT_EQ(6u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  stream << frame.handshake_done_frame;
+  EXPECT_EQ("{ control_frame_id: 6 }\n", stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, QuicAckFreuqncyFrameToString) {
+  QuicAckFrequencyFrame ack_frequency_frame;
+  ack_frequency_frame.sequence_number = 1;
+  ack_frequency_frame.packet_tolerance = 2;
+  ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(25);
+  ack_frequency_frame.ignore_order = false;
+  QuicFrame frame(&ack_frequency_frame);
+  ASSERT_EQ(ACK_FREQUENCY_FRAME, frame.type);
+  SetControlFrameId(6, &frame);
+  EXPECT_EQ(6u, GetControlFrameId(frame));
+  std::ostringstream stream;
+  stream << *frame.ack_frequency_frame;
+  EXPECT_EQ(
+      "{ control_frame_id: 6, sequence_number: 1, packet_tolerance: 2, "
+      "max_ack_delay_ms: 25, ignore_order: 0 }\n",
+      stream.str());
+  EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, StreamFrameToString) {
+  QuicStreamFrame frame;
+  frame.stream_id = 1;
+  frame.fin = false;
+  frame.offset = 2;
+  frame.data_length = 3;
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ("{ stream_id: 1, fin: 0, offset: 2, length: 3 }\n", stream.str());
+  EXPECT_FALSE(IsControlFrame(frame.type));
+}
+
+TEST_F(QuicFramesTest, StopWaitingFrameToString) {
+  QuicStopWaitingFrame frame;
+  frame.least_unacked = QuicPacketNumber(2);
+  std::ostringstream stream;
+  stream << frame;
+  EXPECT_EQ("{ least_unacked: 2 }\n", stream.str());
+  QuicFrame quic_frame(frame);
+  EXPECT_FALSE(IsControlFrame(quic_frame.type));
+}
+
+TEST_F(QuicFramesTest, IsAwaitingPacket) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.largest_acked = QuicPacketNumber(10u);
+  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(11));
+  EXPECT_TRUE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
+  EXPECT_FALSE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(1u), QuicPacketNumber()));
+
+  ack_frame1.packets.Add(QuicPacketNumber(12));
+  EXPECT_TRUE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
+
+  QuicAckFrame ack_frame2;
+  ack_frame2.largest_acked = QuicPacketNumber(100u);
+  ack_frame2.packets.AddRange(QuicPacketNumber(21), QuicPacketNumber(100));
+  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(11u),
+                                QuicPacketNumber(20u)));
+  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(80u),
+                                QuicPacketNumber(20u)));
+  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
+                               QuicPacketNumber(20u)));
+
+  ack_frame2.packets.AddRange(QuicPacketNumber(102), QuicPacketNumber(200));
+  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
+                               QuicPacketNumber(20u)));
+}
+
+TEST_F(QuicFramesTest, AddPacket) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.Add(QuicPacketNumber(1));
+  ack_frame1.packets.Add(QuicPacketNumber(99));
+
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+
+  ack_frame1.packets.Add(QuicPacketNumber(20));
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
+  expected_intervals2.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(21)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
+
+  EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(expected_intervals2, actual_intervals2);
+
+  ack_frame1.packets.Add(QuicPacketNumber(19));
+  ack_frame1.packets.Add(QuicPacketNumber(21));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals3(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals3;
+  expected_intervals3.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(19), QuicPacketNumber(22)));
+  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
+
+  EXPECT_EQ(expected_intervals3, actual_intervals3);
+
+  ack_frame1.packets.Add(QuicPacketNumber(20));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals4(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals3, actual_intervals4);
+
+  QuicAckFrame ack_frame2;
+  ack_frame2.packets.Add(QuicPacketNumber(20));
+  ack_frame2.packets.Add(QuicPacketNumber(40));
+  ack_frame2.packets.Add(QuicPacketNumber(60));
+  ack_frame2.packets.Add(QuicPacketNumber(10));
+  ack_frame2.packets.Add(QuicPacketNumber(80));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals5(
+      ack_frame2.packets.begin(), ack_frame2.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals5;
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(10), QuicPacketNumber(11)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(21)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(40), QuicPacketNumber(41)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(60), QuicPacketNumber(61)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(80), QuicPacketNumber(81)));
+
+  EXPECT_EQ(expected_intervals5, actual_intervals5);
+}
+
+TEST_F(QuicFramesTest, AddInterval) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
+
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals{
+      {QuicPacketNumber(1), QuicPacketNumber(10)},
+      {QuicPacketNumber(50), QuicPacketNumber(100)},
+  };
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+
+  // Add a range in the middle.
+  ack_frame1.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2{
+      {QuicPacketNumber(1), QuicPacketNumber(10)},
+      {QuicPacketNumber(20), QuicPacketNumber(30)},
+      {QuicPacketNumber(50), QuicPacketNumber(100)},
+  };
+
+  EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(expected_intervals2, actual_intervals2);
+
+  // Add ranges at both ends.
+  QuicAckFrame ack_frame2;
+  ack_frame2.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(25));
+  ack_frame2.packets.AddRange(QuicPacketNumber(40), QuicPacketNumber(45));
+  ack_frame2.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(65));
+  ack_frame2.packets.AddRange(QuicPacketNumber(10), QuicPacketNumber(15));
+  ack_frame2.packets.AddRange(QuicPacketNumber(80), QuicPacketNumber(85));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals8(
+      ack_frame2.packets.begin(), ack_frame2.packets.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals8{
+      {QuicPacketNumber(10), QuicPacketNumber(15)},
+      {QuicPacketNumber(20), QuicPacketNumber(25)},
+      {QuicPacketNumber(40), QuicPacketNumber(45)},
+      {QuicPacketNumber(60), QuicPacketNumber(65)},
+      {QuicPacketNumber(80), QuicPacketNumber(85)},
+  };
+
+  EXPECT_EQ(expected_intervals8, actual_intervals8);
+}
+
+TEST_F(QuicFramesTest, AddAdjacentForward) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.Add(QuicPacketNumber(49));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
+  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
+  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(49), QuicPacketNumber(100)));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+}
+
+TEST_F(QuicFramesTest, AddAdjacentReverse) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
+  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
+  ack_frame1.packets.Add(QuicPacketNumber(49));
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(49), QuicPacketNumber(100)));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      ack_frame1.packets.begin(), ack_frame1.packets.end());
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+}
+
+TEST_F(QuicFramesTest, RemoveSmallestInterval) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.largest_acked = QuicPacketNumber(100u);
+  ack_frame1.packets.AddRange(QuicPacketNumber(51), QuicPacketNumber(60));
+  ack_frame1.packets.AddRange(QuicPacketNumber(71), QuicPacketNumber(80));
+  ack_frame1.packets.AddRange(QuicPacketNumber(91), QuicPacketNumber(100));
+  ack_frame1.packets.RemoveSmallestInterval();
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(71u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+
+  ack_frame1.packets.RemoveSmallestInterval();
+  EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(91u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
+}
+
+TEST_F(QuicFramesTest, CopyQuicFrames) {
+  QuicFrames frames;
+  QuicMessageFrame* message_frame =
+      new QuicMessageFrame(1, MemSliceFromString("message"));
+  // Construct a frame list.
+  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
+    switch (i) {
+      case PADDING_FRAME:
+        frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+        break;
+      case RST_STREAM_FRAME:
+        frames.push_back(QuicFrame(new QuicRstStreamFrame()));
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        frames.push_back(QuicFrame(new QuicConnectionCloseFrame()));
+        break;
+      case GOAWAY_FRAME:
+        frames.push_back(QuicFrame(new QuicGoAwayFrame()));
+        break;
+      case WINDOW_UPDATE_FRAME:
+        frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
+        break;
+      case BLOCKED_FRAME:
+        frames.push_back(QuicFrame(QuicBlockedFrame()));
+        break;
+      case STOP_WAITING_FRAME:
+        frames.push_back(QuicFrame(QuicStopWaitingFrame()));
+        break;
+      case PING_FRAME:
+        frames.push_back(QuicFrame(QuicPingFrame()));
+        break;
+      case CRYPTO_FRAME:
+        frames.push_back(QuicFrame(new QuicCryptoFrame()));
+        break;
+      case STREAM_FRAME:
+        frames.push_back(QuicFrame(QuicStreamFrame()));
+        break;
+      case ACK_FRAME:
+        frames.push_back(QuicFrame(new QuicAckFrame()));
+        break;
+      case MTU_DISCOVERY_FRAME:
+        frames.push_back(QuicFrame(QuicMtuDiscoveryFrame()));
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        frames.push_back(QuicFrame(new QuicNewConnectionIdFrame()));
+        break;
+      case MAX_STREAMS_FRAME:
+        frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
+        break;
+      case STREAMS_BLOCKED_FRAME:
+        frames.push_back(QuicFrame(QuicStreamsBlockedFrame()));
+        break;
+      case PATH_RESPONSE_FRAME:
+        frames.push_back(QuicFrame(new QuicPathResponseFrame()));
+        break;
+      case PATH_CHALLENGE_FRAME:
+        frames.push_back(QuicFrame(new QuicPathChallengeFrame()));
+        break;
+      case STOP_SENDING_FRAME:
+        frames.push_back(QuicFrame(QuicStopSendingFrame()));
+        break;
+      case MESSAGE_FRAME:
+        frames.push_back(QuicFrame(message_frame));
+        break;
+      case NEW_TOKEN_FRAME:
+        frames.push_back(QuicFrame(new QuicNewTokenFrame()));
+        break;
+      case RETIRE_CONNECTION_ID_FRAME:
+        frames.push_back(QuicFrame(new QuicRetireConnectionIdFrame()));
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
+        break;
+      case ACK_FREQUENCY_FRAME:
+        frames.push_back(QuicFrame(new QuicAckFrequencyFrame()));
+        break;
+      default:
+        ASSERT_TRUE(false)
+            << "Please fix CopyQuicFrames if a new frame type is added.";
+        break;
+    }
+  }
+
+  QuicFrames copy =
+      CopyQuicFrames(quiche::SimpleBufferAllocator::Get(), frames);
+  ASSERT_EQ(NUM_FRAME_TYPES, copy.size());
+  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
+    EXPECT_EQ(i, copy[i].type);
+    if (i != MESSAGE_FRAME) {
+      continue;
+    }
+    // Verify message frame is correctly copied.
+    EXPECT_EQ(1u, copy[i].message_frame->message_id);
+    EXPECT_EQ(nullptr, copy[i].message_frame->data);
+    EXPECT_EQ(7u, copy[i].message_frame->message_length);
+    ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
+    EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
+                        frames[i].message_frame->message_data[0].data(), 7));
+  }
+  DeleteFrames(&frames);
+  DeleteFrames(&copy);
+}
+
+class PacketNumberQueueTest : public QuicTest {};
+
+// Tests that a queue contains the expected data after calls to Add().
+TEST_F(PacketNumberQueueTest, AddRange) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(51));
+  queue.Add(QuicPacketNumber(53));
+
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  for (int i = 1; i < 51; ++i) {
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
+  }
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(52)));
+  EXPECT_TRUE(queue.Contains(QuicPacketNumber(53)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(54)));
+  EXPECT_EQ(51u, queue.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(1u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(53u), queue.Max());
+
+  queue.Add(QuicPacketNumber(70));
+  EXPECT_EQ(QuicPacketNumber(70u), queue.Max());
+}
+
+// Tests Contains function
+TEST_F(PacketNumberQueueTest, Contains) {
+  PacketNumberQueue queue;
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  queue.AddRange(QuicPacketNumber(5), QuicPacketNumber(10));
+  queue.Add(QuicPacketNumber(20));
+
+  for (int i = 1; i < 5; ++i) {
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
+  }
+
+  for (int i = 5; i < 10; ++i) {
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
+  }
+  for (int i = 10; i < 20; ++i) {
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
+  }
+  EXPECT_TRUE(queue.Contains(QuicPacketNumber(20)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(21)));
+
+  PacketNumberQueue queue2;
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(1)));
+  for (int i = 1; i < 51; ++i) {
+    queue2.Add(QuicPacketNumber(2 * i));
+  }
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber()));
+  for (int i = 1; i < 51; ++i) {
+    if (i % 2 == 0) {
+      EXPECT_TRUE(queue2.Contains(QuicPacketNumber(i)));
+    } else {
+      EXPECT_FALSE(queue2.Contains(QuicPacketNumber(i)));
+    }
+  }
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(101)));
+}
+
+// Tests that a queue contains the expected data after calls to RemoveUpTo().
+TEST_F(PacketNumberQueueTest, Removal) {
+  PacketNumberQueue queue;
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(51)));
+  EXPECT_FALSE(queue.RemoveUpTo(QuicPacketNumber(51)));
+
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  for (int i = 1; i < 51; ++i) {
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
+  }
+  for (int i = 51; i < 100; ++i) {
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
+  }
+  EXPECT_EQ(49u, queue.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(51u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), queue.Max());
+
+  PacketNumberQueue queue2;
+  queue2.AddRange(QuicPacketNumber(1), QuicPacketNumber(5));
+  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(3)));
+  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(50)));
+  EXPECT_TRUE(queue2.Empty());
+}
+
+// Tests that a queue is empty when all of its elements are removed.
+TEST_F(PacketNumberQueueTest, Empty) {
+  PacketNumberQueue queue;
+  EXPECT_TRUE(queue.Empty());
+  EXPECT_EQ(0u, queue.NumPacketsSlow());
+
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(100)));
+  EXPECT_TRUE(queue.Empty());
+  EXPECT_EQ(0u, queue.NumPacketsSlow());
+}
+
+// Tests that logging the state of a PacketNumberQueue does not crash.
+TEST_F(PacketNumberQueueTest, LogDoesNotCrash) {
+  std::ostringstream oss;
+  PacketNumberQueue queue;
+  oss << queue;
+
+  queue.Add(QuicPacketNumber(1));
+  queue.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
+  oss << queue;
+}
+
+// Tests that the iterators returned from a packet queue iterate over the queue.
+TEST_F(PacketNumberQueueTest, Iterators) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      queue.begin(), queue.end());
+
+  PacketNumberQueue queue2;
+  for (int i = 1; i < 100; i++) {
+    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
+  }
+
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      queue2.begin(), queue2.end());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(100)));
+  EXPECT_EQ(expected_intervals, actual_intervals);
+  EXPECT_EQ(expected_intervals, actual_intervals2);
+  EXPECT_EQ(actual_intervals, actual_intervals2);
+}
+
+TEST_F(PacketNumberQueueTest, ReversedIterators) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+  PacketNumberQueue queue2;
+  for (int i = 1; i < 100; i++) {
+    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
+  }
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
+      queue.rbegin(), queue.rend());
+  const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
+      queue2.rbegin(), queue2.rend());
+
+  std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(100)));
+
+  EXPECT_EQ(expected_intervals, actual_intervals);
+  EXPECT_EQ(expected_intervals, actual_intervals2);
+  EXPECT_EQ(actual_intervals, actual_intervals2);
+
+  PacketNumberQueue queue3;
+  for (int i = 1; i < 20; i++) {
+    queue3.Add(QuicPacketNumber(2 * i));
+  }
+
+  auto begin = queue3.begin();
+  auto end = queue3.end();
+  --end;
+  auto rbegin = queue3.rbegin();
+  auto rend = queue3.rend();
+  --rend;
+
+  EXPECT_EQ(*begin, *rend);
+  EXPECT_EQ(*rbegin, *end);
+}
+
+TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
+  PacketNumberQueue queue;
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
+  queue.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
+  queue.AddRange(QuicPacketNumber(40), QuicPacketNumber(50));
+  EXPECT_EQ(3u, queue.NumIntervals());
+  EXPECT_EQ(10u, queue.LastIntervalLength());
+
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(25)));
+  EXPECT_EQ(2u, queue.NumIntervals());
+  EXPECT_EQ(10u, queue.LastIntervalLength());
+  EXPECT_EQ(QuicPacketNumber(25u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(49u), queue.Max());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_goaway_frame.cc b/quiche/quic/core/frames/quic_goaway_frame.cc
new file mode 100644
index 0000000..277d84d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_goaway_frame.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "quiche/quic/core/frames/quic_goaway_frame.h"
+
+namespace quic {
+
+QuicGoAwayFrame::QuicGoAwayFrame(QuicControlFrameId control_frame_id,
+                                 QuicErrorCode error_code,
+                                 QuicStreamId last_good_stream_id,
+                                 const std::string& reason)
+    : control_frame_id(control_frame_id),
+      error_code(error_code),
+      last_good_stream_id(last_good_stream_id),
+      reason_phrase(reason) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicGoAwayFrame& goaway_frame) {
+  os << "{ control_frame_id: " << goaway_frame.control_frame_id
+     << ", error_code: " << goaway_frame.error_code
+     << ", last_good_stream_id: " << goaway_frame.last_good_stream_id
+     << ", reason_phrase: '" << goaway_frame.reason_phrase << "' }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_goaway_frame.h b/quiche/quic/core/frames/quic_goaway_frame.h
new file mode 100644
index 0000000..ac31dbc
--- /dev/null
+++ b/quiche/quic/core/frames/quic_goaway_frame.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
+
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicGoAwayFrame {
+  QuicGoAwayFrame() = default;
+  QuicGoAwayFrame(QuicControlFrameId control_frame_id,
+                  QuicErrorCode error_code,
+                  QuicStreamId last_good_stream_id,
+                  const std::string& reason);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicGoAwayFrame& g);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicErrorCode error_code = QUIC_NO_ERROR;
+  QuicStreamId last_good_stream_id = 0;
+  std::string reason_phrase;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_GOAWAY_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_handshake_done_frame.cc b/quiche/quic/core/frames/quic_handshake_done_frame.cc
new file mode 100644
index 0000000..e8a7110
--- /dev/null
+++ b/quiche/quic/core/frames/quic_handshake_done_frame.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_handshake_done_frame.h"
+
+namespace quic {
+
+QuicHandshakeDoneFrame::QuicHandshakeDoneFrame()
+    : QuicInlinedFrame(HANDSHAKE_DONE_FRAME) {}
+
+QuicHandshakeDoneFrame::QuicHandshakeDoneFrame(
+    QuicControlFrameId control_frame_id)
+    : QuicInlinedFrame(HANDSHAKE_DONE_FRAME),
+      control_frame_id(control_frame_id) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicHandshakeDoneFrame& handshake_done_frame) {
+  os << "{ control_frame_id: " << handshake_done_frame.control_frame_id
+     << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_handshake_done_frame.h b/quiche/quic/core/frames/quic_handshake_done_frame.h
new file mode 100644
index 0000000..7c9639a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_handshake_done_frame.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A HANDSHAKE_DONE frame contains no payload, and it is retransmittable,
+// and ACK'd just like other normal frames.
+struct QUIC_EXPORT_PRIVATE QuicHandshakeDoneFrame
+    : public QuicInlinedFrame<QuicHandshakeDoneFrame> {
+  QuicHandshakeDoneFrame();
+  explicit QuicHandshakeDoneFrame(QuicControlFrameId control_frame_id);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicHandshakeDoneFrame& handshake_done_frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_HANDSHAKE_DONE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_inlined_frame.h b/quiche/quic/core/frames/quic_inlined_frame.h
new file mode 100644
index 0000000..8cab158
--- /dev/null
+++ b/quiche/quic/core/frames/quic_inlined_frame.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
+
+#include <type_traits>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicInlinedFrame is the base class of all frame types that is inlined in the
+// QuicFrame class. It gurantees all inlined frame types contain a 'type' field
+// at offset 0, such that QuicFrame.type can get the correct frame type for both
+// inline and out-of-line frame types.
+template <typename DerivedT>
+struct QUIC_EXPORT_PRIVATE QuicInlinedFrame {
+  QuicInlinedFrame(QuicFrameType type) {
+    static_cast<DerivedT*>(this)->type = type;
+    static_assert(std::is_standard_layout<DerivedT>::value,
+                  "Inlined frame must have a standard layout");
+    static_assert(offsetof(DerivedT, type) == 0,
+                  "type must be the first field.");
+    static_assert(sizeof(DerivedT) <= 24,
+                  "Frames larger than 24 bytes should not be inlined.");
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_max_streams_frame.cc b/quiche/quic/core/frames/quic_max_streams_frame.cc
new file mode 100644
index 0000000..594224b
--- /dev/null
+++ b/quiche/quic/core/frames/quic_max_streams_frame.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+
+namespace quic {
+
+QuicMaxStreamsFrame::QuicMaxStreamsFrame()
+    : QuicInlinedFrame(MAX_STREAMS_FRAME) {}
+
+QuicMaxStreamsFrame::QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
+                                         QuicStreamCount stream_count,
+                                         bool unidirectional)
+    : QuicInlinedFrame(MAX_STREAMS_FRAME),
+      control_frame_id(control_frame_id),
+      stream_count(stream_count),
+      unidirectional(unidirectional) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicMaxStreamsFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", stream_count: " << frame.stream_count
+     << ((frame.unidirectional) ? ", unidirectional }\n"
+                                : ", bidirectional }\n");
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_max_streams_frame.h b/quiche/quic/core/frames/quic_max_streams_frame.h
new file mode 100644
index 0000000..97434c7
--- /dev/null
+++ b/quiche/quic/core/frames/quic_max_streams_frame.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// IETF format MAX_STREAMS frame.
+// This frame is used by the sender to inform the peer of the number of
+// streams that the peer may open and that the sender will accept.
+struct QUIC_EXPORT_PRIVATE QuicMaxStreamsFrame
+    : public QuicInlinedFrame<QuicMaxStreamsFrame> {
+  QuicMaxStreamsFrame();
+  QuicMaxStreamsFrame(QuicControlFrameId control_frame_id,
+                      QuicStreamCount stream_count,
+                      bool unidirectional);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicMaxStreamsFrame& frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // The number of streams that may be opened.
+  QuicStreamCount stream_count = 0;
+  // Whether uni- or bi-directional streams
+  bool unidirectional = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MAX_STREAMS_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_message_frame.cc b/quiche/quic/core/frames/quic_message_frame.cc
new file mode 100644
index 0000000..935d7ce
--- /dev/null
+++ b/quiche/quic/core/frames/quic_message_frame.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_message_frame.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id)
+    : message_id(message_id), data(nullptr), message_length(0) {}
+
+QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
+                                   absl::Span<quiche::QuicheMemSlice> span)
+    : message_id(message_id), data(nullptr), message_length(0) {
+  for (quiche::QuicheMemSlice& slice : span) {
+    if (slice.empty()) {
+      continue;
+    }
+    message_length += slice.length();
+    message_data.push_back(std::move(slice));
+  }
+}
+QuicMessageFrame::QuicMessageFrame(QuicMessageId message_id,
+                                   quiche::QuicheMemSlice slice)
+    : QuicMessageFrame(message_id, absl::MakeSpan(&slice, 1)) {}
+
+QuicMessageFrame::QuicMessageFrame(const char* data, QuicPacketLength length)
+    : message_id(0), data(data), message_length(length) {}
+
+QuicMessageFrame::~QuicMessageFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicMessageFrame& s) {
+  os << " message_id: " << s.message_id
+     << ", message_length: " << s.message_length << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_message_frame.h b/quiche/quic/core/frames/quic_message_frame.h
new file mode 100644
index 0000000..30c40a0
--- /dev/null
+++ b/quiche/quic/core/frames/quic_message_frame.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+using QuicMessageData = absl::InlinedVector<quiche::QuicheMemSlice, 1>;
+
+struct QUIC_EXPORT_PRIVATE QuicMessageFrame {
+  QuicMessageFrame() = default;
+  explicit QuicMessageFrame(QuicMessageId message_id);
+  QuicMessageFrame(QuicMessageId message_id,
+                   absl::Span<quiche::QuicheMemSlice> span);
+  QuicMessageFrame(QuicMessageId message_id, quiche::QuicheMemSlice slice);
+  QuicMessageFrame(const char* data, QuicPacketLength length);
+
+  QuicMessageFrame(const QuicMessageFrame& other) = delete;
+  QuicMessageFrame& operator=(const QuicMessageFrame& other) = delete;
+
+  QuicMessageFrame(QuicMessageFrame&& other) = default;
+  QuicMessageFrame& operator=(QuicMessageFrame&& other) = default;
+
+  ~QuicMessageFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicMessageFrame& s);
+
+  // message_id is only used on the sender side and does not get serialized on
+  // wire.
+  QuicMessageId message_id = 0;
+  // Not owned, only used on read path.
+  const char* data = nullptr;
+  // Total length of message_data, must be fit into one packet.
+  QuicPacketLength message_length = 0;
+
+  // The actual message data which is reference counted, used on write path.
+  QuicMessageData message_data;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MESSAGE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_mtu_discovery_frame.h b/quiche/quic/core/frames/quic_mtu_discovery_frame.h
new file mode 100644
index 0000000..7189463
--- /dev/null
+++ b/quiche/quic/core/frames/quic_mtu_discovery_frame.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A path MTU discovery frame contains no payload and is serialized as a ping
+// frame.
+struct QUIC_EXPORT_PRIVATE QuicMtuDiscoveryFrame
+    : public QuicInlinedFrame<QuicMtuDiscoveryFrame> {
+  QuicMtuDiscoveryFrame() : QuicInlinedFrame(MTU_DISCOVERY_FRAME) {}
+
+  QuicFrameType type;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_new_connection_id_frame.cc b/quiche/quic/core/frames/quic_new_connection_id_frame.cc
new file mode 100644
index 0000000..cf5511b
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_connection_id_frame.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+
+namespace quic {
+
+QuicNewConnectionIdFrame::QuicNewConnectionIdFrame(
+    QuicControlFrameId control_frame_id,
+    QuicConnectionId connection_id,
+    QuicConnectionIdSequenceNumber sequence_number,
+    StatelessResetToken stateless_reset_token,
+    uint64_t retire_prior_to)
+    : control_frame_id(control_frame_id),
+      connection_id(connection_id),
+      sequence_number(sequence_number),
+      stateless_reset_token(stateless_reset_token),
+      retire_prior_to(retire_prior_to) {
+  QUICHE_DCHECK(retire_prior_to <= sequence_number);
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicNewConnectionIdFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", connection_id: " << frame.connection_id
+     << ", sequence_number: " << frame.sequence_number
+     << ", retire_prior_to: " << frame.retire_prior_to << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_new_connection_id_frame.h b/quiche/quic/core/frames/quic_new_connection_id_frame.h
new file mode 100644
index 0000000..6221b03
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_connection_id_frame.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicNewConnectionIdFrame {
+  QuicNewConnectionIdFrame() = default;
+  QuicNewConnectionIdFrame(QuicControlFrameId control_frame_id,
+                           QuicConnectionId connection_id,
+                           QuicConnectionIdSequenceNumber sequence_number,
+                           StatelessResetToken stateless_reset_token,
+                           uint64_t retire_prior_to);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicNewConnectionIdFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicConnectionId connection_id = EmptyQuicConnectionId();
+  QuicConnectionIdSequenceNumber sequence_number = 0;
+  StatelessResetToken stateless_reset_token;
+  uint64_t retire_prior_to = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_CONNECTION_ID_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_new_token_frame.cc b/quiche/quic/core/frames/quic_new_token_frame.cc
new file mode 100644
index 0000000..7b5190d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_token_frame.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_new_token_frame.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id,
+                                     absl::string_view token)
+    : control_frame_id(control_frame_id),
+      token(std::string(token.data(), token.length())) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
+  os << "{ control_frame_id: " << s.control_frame_id
+     << ", token: " << absl::BytesToHexString(s.token) << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_new_token_frame.h b/quiche/quic/core/frames/quic_new_token_frame.h
new file mode 100644
index 0000000..7900149
--- /dev/null
+++ b/quiche/quic/core/frames/quic_new_token_frame.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicNewTokenFrame {
+  QuicNewTokenFrame() = default;
+  QuicNewTokenFrame(QuicControlFrameId control_frame_id,
+                    absl::string_view token);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicNewTokenFrame& s);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  std::string token;
+};
+static_assert(sizeof(QuicNewTokenFrame) <= 64,
+              "Keep the QuicNewTokenFrame size to a cacheline.");
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_NEW_TOKEN_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_padding_frame.cc b/quiche/quic/core/frames/quic_padding_frame.cc
new file mode 100644
index 0000000..2170835
--- /dev/null
+++ b/quiche/quic/core/frames/quic_padding_frame.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicPaddingFrame& padding_frame) {
+  os << "{ num_padding_bytes: " << padding_frame.num_padding_bytes << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_padding_frame.h b/quiche/quic/core/frames/quic_padding_frame.h
new file mode 100644
index 0000000..25edc3f
--- /dev/null
+++ b/quiche/quic/core/frames/quic_padding_frame.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A padding frame contains no payload.
+struct QUIC_EXPORT_PRIVATE QuicPaddingFrame
+    : public QuicInlinedFrame<QuicPaddingFrame> {
+  QuicPaddingFrame() : QuicInlinedFrame(PADDING_FRAME) {}
+  explicit QuicPaddingFrame(int num_padding_bytes)
+      : QuicInlinedFrame(PADDING_FRAME), num_padding_bytes(num_padding_bytes) {}
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPaddingFrame& padding_frame);
+
+  QuicFrameType type;
+
+  // -1: full padding to the end of a max-sized packet
+  // otherwise: only pad up to num_padding_bytes bytes
+  int num_padding_bytes = -1;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PADDING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_path_challenge_frame.cc b/quiche/quic/core/frames/quic_path_challenge_frame.cc
new file mode 100644
index 0000000..c4781a0
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_challenge_frame.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicPathChallengeFrame::QuicPathChallengeFrame(
+    QuicControlFrameId control_frame_id,
+    const QuicPathFrameBuffer& data_buff)
+    : control_frame_id(control_frame_id) {
+  memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
+}
+
+QuicPathChallengeFrame::~QuicPathChallengeFrame() {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicPathChallengeFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
+     << absl::BytesToHexString(absl::string_view(
+            reinterpret_cast<const char*>(frame.data_buffer.data()),
+            frame.data_buffer.size()))
+     << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_path_challenge_frame.h b/quiche/quic/core/frames/quic_path_challenge_frame.h
new file mode 100644
index 0000000..fb0ad24
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_challenge_frame.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame {
+  QuicPathChallengeFrame() = default;
+  QuicPathChallengeFrame(QuicControlFrameId control_frame_id,
+                         const QuicPathFrameBuffer& data_buff);
+  ~QuicPathChallengeFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPathChallengeFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  QuicPathFrameBuffer data_buffer{};
+};
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_path_response_frame.cc b/quiche/quic/core/frames/quic_path_response_frame.cc
new file mode 100644
index 0000000..384387d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_response_frame.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_path_response_frame.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicPathResponseFrame::QuicPathResponseFrame(
+    QuicControlFrameId control_frame_id,
+    const QuicPathFrameBuffer& data_buff)
+    : control_frame_id(control_frame_id) {
+  memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
+}
+
+QuicPathResponseFrame::~QuicPathResponseFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
+     << absl::BytesToHexString(absl::string_view(
+            reinterpret_cast<const char*>(frame.data_buffer.data()),
+            frame.data_buffer.size()))
+     << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_path_response_frame.h b/quiche/quic/core/frames/quic_path_response_frame.h
new file mode 100644
index 0000000..df2391f
--- /dev/null
+++ b/quiche/quic/core/frames/quic_path_response_frame.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame {
+  QuicPathResponseFrame() = default;
+  QuicPathResponseFrame(QuicControlFrameId control_frame_id,
+                        const QuicPathFrameBuffer& data_buff);
+  ~QuicPathResponseFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPathResponseFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  QuicPathFrameBuffer data_buffer{};
+};
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_ping_frame.cc b/quiche/quic/core/frames/quic_ping_frame.cc
new file mode 100644
index 0000000..c28e671
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ping_frame.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+
+namespace quic {
+
+QuicPingFrame::QuicPingFrame() : QuicInlinedFrame(PING_FRAME) {}
+
+QuicPingFrame::QuicPingFrame(QuicControlFrameId control_frame_id)
+    : QuicInlinedFrame(PING_FRAME), control_frame_id(control_frame_id) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPingFrame& ping_frame) {
+  os << "{ control_frame_id: " << ping_frame.control_frame_id << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_ping_frame.h b/quiche/quic/core/frames/quic_ping_frame.h
new file mode 100644
index 0000000..d39bf6d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_ping_frame.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A ping frame contains no payload, though it is retransmittable,
+// and ACK'd just like other normal frames.
+struct QUIC_EXPORT_PRIVATE QuicPingFrame
+    : public QuicInlinedFrame<QuicPingFrame> {
+  QuicPingFrame();
+  explicit QuicPingFrame(QuicControlFrameId control_frame_id);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPingFrame& ping_frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_retire_connection_id_frame.cc b/quiche/quic/core/frames/quic_retire_connection_id_frame.cc
new file mode 100644
index 0000000..93e7e49
--- /dev/null
+++ b/quiche/quic/core/frames/quic_retire_connection_id_frame.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+
+namespace quic {
+
+QuicRetireConnectionIdFrame::QuicRetireConnectionIdFrame(
+    QuicControlFrameId control_frame_id,
+    QuicConnectionIdSequenceNumber sequence_number)
+    : control_frame_id(control_frame_id), sequence_number(sequence_number) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicRetireConnectionIdFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", sequence_number: " << frame.sequence_number << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_retire_connection_id_frame.h b/quiche/quic/core/frames/quic_retire_connection_id_frame.h
new file mode 100644
index 0000000..41ce972
--- /dev/null
+++ b/quiche/quic/core/frames/quic_retire_connection_id_frame.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicRetireConnectionIdFrame {
+  QuicRetireConnectionIdFrame() = default;
+  QuicRetireConnectionIdFrame(QuicControlFrameId control_frame_id,
+                              QuicConnectionIdSequenceNumber sequence_number);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicRetireConnectionIdFrame& frame);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicConnectionIdSequenceNumber sequence_number = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_RETIRE_CONNECTION_ID_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_rst_stream_frame.cc b/quiche/quic/core/frames/quic_rst_stream_frame.cc
new file mode 100644
index 0000000..a6d3052
--- /dev/null
+++ b/quiche/quic/core/frames/quic_rst_stream_frame.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+
+#include "quiche/quic/core/quic_error_codes.h"
+
+namespace quic {
+
+QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                                       QuicStreamId stream_id,
+                                       QuicRstStreamErrorCode error_code,
+                                       QuicStreamOffset bytes_written)
+    : control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      error_code(error_code),
+      ietf_error_code(RstStreamErrorCodeToIetfResetStreamErrorCode(error_code)),
+      byte_offset(bytes_written) {}
+
+QuicRstStreamFrame::QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                                       QuicStreamId stream_id,
+                                       QuicResetStreamError error,
+                                       QuicStreamOffset bytes_written)
+    : control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      error_code(error.internal_code()),
+      ietf_error_code(error.ietf_application_code()),
+      byte_offset(bytes_written) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicRstStreamFrame& rst_frame) {
+  os << "{ control_frame_id: " << rst_frame.control_frame_id
+     << ", stream_id: " << rst_frame.stream_id
+     << ", byte_offset: " << rst_frame.byte_offset
+     << ", error_code: " << rst_frame.error_code
+     << ", ietf_error_code: " << rst_frame.ietf_error_code << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_rst_stream_frame.h b/quiche/quic/core/frames/quic_rst_stream_frame.h
new file mode 100644
index 0000000..c346aff
--- /dev/null
+++ b/quiche/quic/core/frames/quic_rst_stream_frame.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicRstStreamFrame {
+  QuicRstStreamFrame() = default;
+  QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                     QuicStreamId stream_id, QuicRstStreamErrorCode error_code,
+                     QuicStreamOffset bytes_written);
+  QuicRstStreamFrame(QuicControlFrameId control_frame_id,
+                     QuicStreamId stream_id, QuicResetStreamError error,
+                     QuicStreamOffset bytes_written);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const QuicRstStreamFrame& r);
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  QuicStreamId stream_id = 0;
+
+  // When using Google QUIC: the RST_STREAM error code on the wire.
+  // When using IETF QUIC: for an outgoing RESET_STREAM frame, the error code
+  // generated by the application that determines |ietf_error_code| to be sent
+  // on the wire; for an incoming RESET_STREAM frame, the error code inferred
+  // from the |ietf_error_code| received on the wire.
+  QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
+
+  // Application error code of RESET_STREAM frame.  Used for IETF QUIC only.
+  uint64_t ietf_error_code = 0;
+
+  // Used to update flow control windows. On termination of a stream, both
+  // endpoints must inform the peer of the number of bytes they have sent on
+  // that stream. This can be done through normal termination (data packet with
+  // FIN) or through a RST.
+  QuicStreamOffset byte_offset = 0;
+
+  // Returns a tuple of both |error_code| and |ietf_error_code|.
+  QuicResetStreamError error() const {
+    return QuicResetStreamError(error_code, ietf_error_code);
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_stop_sending_frame.cc b/quiche/quic/core/frames/quic_stop_sending_frame.cc
new file mode 100644
index 0000000..f70b785
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_sending_frame.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_stop_sending_frame.h"
+
+#include "quiche/quic/core/quic_error_codes.h"
+
+namespace quic {
+
+QuicStopSendingFrame::QuicStopSendingFrame()
+    : QuicInlinedFrame(STOP_SENDING_FRAME) {}
+
+QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                                           QuicStreamId stream_id,
+                                           QuicRstStreamErrorCode error_code)
+    : QuicStopSendingFrame(control_frame_id, stream_id,
+                           QuicResetStreamError::FromInternal(error_code)) {}
+
+QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                                           QuicStreamId stream_id,
+                                           QuicResetStreamError error)
+    : QuicInlinedFrame(STOP_SENDING_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      error_code(error.internal_code()),
+      ietf_error_code(error.ietf_application_code()) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicStopSendingFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", stream_id: " << frame.stream_id
+     << ", error_code: " << frame.error_code
+     << ", ietf_error_code: " << frame.ietf_error_code << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_stop_sending_frame.h b/quiche/quic/core/frames/quic_stop_sending_frame.h
new file mode 100644
index 0000000..e21937d
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_sending_frame.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame
+    : public QuicInlinedFrame<QuicStopSendingFrame> {
+  QuicStopSendingFrame();
+  QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                       QuicStreamId stream_id,
+                       QuicRstStreamErrorCode error_code);
+  QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+                       QuicStreamId stream_id, QuicResetStreamError error);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicStopSendingFrame& frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+  QuicStreamId stream_id = 0;
+
+  // For an outgoing frame, the error code generated by the application that
+  // determines |ietf_error_code| to be sent on the wire; for an incoming frame,
+  // the error code inferred from |ietf_error_code| received on the wire.
+  QuicRstStreamErrorCode error_code = QUIC_STREAM_NO_ERROR;
+
+  // On-the-wire application error code of the frame.
+  uint64_t ietf_error_code = 0;
+
+  // Returns a tuple of both |error_code| and |ietf_error_code|.
+  QuicResetStreamError error() const {
+    return QuicResetStreamError(error_code, ietf_error_code);
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_stop_waiting_frame.cc b/quiche/quic/core/frames/quic_stop_waiting_frame.cc
new file mode 100644
index 0000000..32941aa
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_waiting_frame.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_stop_waiting_frame.h"
+
+#include "quiche/quic/core/quic_constants.h"
+
+namespace quic {
+
+QuicStopWaitingFrame::QuicStopWaitingFrame()
+    : QuicInlinedFrame(STOP_WAITING_FRAME) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicStopWaitingFrame& sent_info) {
+  os << "{ least_unacked: " << sent_info.least_unacked << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_stop_waiting_frame.h b/quiche/quic/core/frames/quic_stop_waiting_frame.h
new file mode 100644
index 0000000..d04f57a
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stop_waiting_frame.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicStopWaitingFrame
+    : public QuicInlinedFrame<QuicStopWaitingFrame> {
+  QuicStopWaitingFrame();
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicStopWaitingFrame& s);
+
+  QuicFrameType type;
+
+  // The lowest packet we've sent which is unacked, and we expect an ack for.
+  QuicPacketNumber least_unacked;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_stream_frame.cc b/quiche/quic/core/frames/quic_stream_frame.cc
new file mode 100644
index 0000000..81fbe04
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stream_frame.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicStreamFrame::QuicStreamFrame() : QuicInlinedFrame(STREAM_FRAME) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+                                 bool fin,
+                                 QuicStreamOffset offset,
+                                 absl::string_view data)
+    : QuicStreamFrame(stream_id, fin, offset, data.data(), data.length()) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+                                 bool fin,
+                                 QuicStreamOffset offset,
+                                 QuicPacketLength data_length)
+    : QuicStreamFrame(stream_id, fin, offset, nullptr, data_length) {}
+
+QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
+                                 bool fin,
+                                 QuicStreamOffset offset,
+                                 const char* data_buffer,
+                                 QuicPacketLength data_length)
+    : QuicInlinedFrame(STREAM_FRAME),
+      fin(fin),
+      data_length(data_length),
+      stream_id(stream_id),
+      data_buffer(data_buffer),
+      offset(offset) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicStreamFrame& stream_frame) {
+  os << "{ stream_id: " << stream_frame.stream_id
+     << ", fin: " << stream_frame.fin << ", offset: " << stream_frame.offset
+     << ", length: " << stream_frame.data_length << " }\n";
+  return os;
+}
+
+bool QuicStreamFrame::operator==(const QuicStreamFrame& rhs) const {
+  return fin == rhs.fin && data_length == rhs.data_length &&
+         stream_id == rhs.stream_id && data_buffer == rhs.data_buffer &&
+         offset == rhs.offset;
+}
+
+bool QuicStreamFrame::operator!=(const QuicStreamFrame& rhs) const {
+  return !(*this == rhs);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_stream_frame.h b/quiche/quic/core/frames/quic_stream_frame.h
new file mode 100644
index 0000000..6bcd41e
--- /dev/null
+++ b/quiche/quic/core/frames/quic_stream_frame.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+struct QUIC_EXPORT_PRIVATE QuicStreamFrame
+    : public QuicInlinedFrame<QuicStreamFrame> {
+  QuicStreamFrame();
+  QuicStreamFrame(QuicStreamId stream_id,
+                  bool fin,
+                  QuicStreamOffset offset,
+                  absl::string_view data);
+  QuicStreamFrame(QuicStreamId stream_id,
+                  bool fin,
+                  QuicStreamOffset offset,
+                  QuicPacketLength data_length);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicStreamFrame& s);
+
+  bool operator==(const QuicStreamFrame& rhs) const;
+
+  bool operator!=(const QuicStreamFrame& rhs) const;
+
+  QuicFrameType type;
+  bool fin = false;
+  QuicPacketLength data_length = 0;
+  // TODO(wub): Change to a QuicUtils::GetInvalidStreamId when it is not version
+  // dependent.
+  QuicStreamId stream_id = -1;
+  const char* data_buffer = nullptr;  // Not owned.
+  QuicStreamOffset offset = 0;        // Location of this data in the stream.
+
+  QuicStreamFrame(QuicStreamId stream_id,
+                  bool fin,
+                  QuicStreamOffset offset,
+                  const char* data_buffer,
+                  QuicPacketLength data_length);
+};
+static_assert(sizeof(QuicStreamFrame) <= 64,
+              "Keep the QuicStreamFrame size to a cacheline.");
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAM_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_streams_blocked_frame.cc b/quiche/quic/core/frames/quic_streams_blocked_frame.cc
new file mode 100644
index 0000000..2ca554e
--- /dev/null
+++ b/quiche/quic/core/frames/quic_streams_blocked_frame.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
+
+namespace quic {
+
+QuicStreamsBlockedFrame::QuicStreamsBlockedFrame()
+    : QuicInlinedFrame(STREAMS_BLOCKED_FRAME) {}
+
+QuicStreamsBlockedFrame::QuicStreamsBlockedFrame(
+    QuicControlFrameId control_frame_id,
+    QuicStreamCount stream_count,
+    bool unidirectional)
+    : QuicInlinedFrame(STREAMS_BLOCKED_FRAME),
+      control_frame_id(control_frame_id),
+      stream_count(stream_count),
+      unidirectional(unidirectional) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicStreamsBlockedFrame& frame) {
+  os << "{ control_frame_id: " << frame.control_frame_id
+     << ", stream count: " << frame.stream_count
+     << ((frame.unidirectional) ? ", unidirectional }\n"
+                                : ", bidirectional }\n");
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_streams_blocked_frame.h b/quiche/quic/core/frames/quic_streams_blocked_frame.h
new file mode 100644
index 0000000..05eb1cc
--- /dev/null
+++ b/quiche/quic/core/frames/quic_streams_blocked_frame.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// IETF format STREAMS_BLOCKED frame.
+// The sender uses this to inform the peer that the sender wished to
+// open a new stream, exceeding the limit on the number of streams.
+struct QUIC_EXPORT_PRIVATE QuicStreamsBlockedFrame
+    : public QuicInlinedFrame<QuicStreamsBlockedFrame> {
+  QuicStreamsBlockedFrame();
+  QuicStreamsBlockedFrame(QuicControlFrameId control_frame_id,
+                          QuicStreamCount stream_count,
+                          bool unidirectional);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicStreamsBlockedFrame& frame);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // The number of streams that the sender wishes to exceed
+  QuicStreamCount stream_count = 0;
+
+  // Whether uni- or bi-directional streams
+  bool unidirectional = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_STREAMS_BLOCKED_FRAME_H_
diff --git a/quiche/quic/core/frames/quic_window_update_frame.cc b/quiche/quic/core/frames/quic_window_update_frame.cc
new file mode 100644
index 0000000..3c13454
--- /dev/null
+++ b/quiche/quic/core/frames/quic_window_update_frame.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicWindowUpdateFrame::QuicWindowUpdateFrame()
+    : QuicInlinedFrame(WINDOW_UPDATE_FRAME) {}
+
+QuicWindowUpdateFrame::QuicWindowUpdateFrame(
+    QuicControlFrameId control_frame_id, QuicStreamId stream_id,
+    QuicByteCount max_data)
+    : QuicInlinedFrame(WINDOW_UPDATE_FRAME),
+      control_frame_id(control_frame_id),
+      stream_id(stream_id),
+      max_data(max_data) {}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicWindowUpdateFrame& window_update_frame) {
+  os << "{ control_frame_id: " << window_update_frame.control_frame_id
+     << ", stream_id: " << window_update_frame.stream_id
+     << ", max_data: " << window_update_frame.max_data << " }\n";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/frames/quic_window_update_frame.h b/quiche/quic/core/frames/quic_window_update_frame.h
new file mode 100644
index 0000000..1cbd7ff
--- /dev/null
+++ b/quiche/quic/core/frames/quic_window_update_frame.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
+
+#include <ostream>
+
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// Flow control updates per-stream and at the connection level.
+// Based on SPDY's WINDOW_UPDATE frame, but uses an absolute max data bytes
+// rather than a window delta.
+struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame
+    : public QuicInlinedFrame<QuicWindowUpdateFrame> {
+  QuicWindowUpdateFrame();
+  QuicWindowUpdateFrame(QuicControlFrameId control_frame_id,
+                        QuicStreamId stream_id, QuicByteCount max_data);
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const QuicWindowUpdateFrame& w);
+
+  QuicFrameType type;
+
+  // A unique identifier of this control frame. 0 when this frame is received,
+  // and non-zero when sent.
+  QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+  // The stream this frame applies to.  0 is a special case meaning the overall
+  // connection rather than a specific stream.
+  QuicStreamId stream_id = 0;
+
+  // Maximum data allowed in the stream or connection. The receiver of this
+  // frame must not send data which would exceedes this restriction.
+  QuicByteCount max_data = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
diff --git a/quiche/quic/core/handshaker_delegate_interface.h b/quiche/quic/core/handshaker_delegate_interface.h
new file mode 100644
index 0000000..d6e2501
--- /dev/null
+++ b/quiche/quic/core/handshaker_delegate_interface.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
+#define QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
+
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+class QuicDecrypter;
+class QuicEncrypter;
+
+// Pure virtual class to get notified when particular handshake events occurred.
+class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
+ public:
+  virtual ~HandshakerDelegateInterface() {}
+
+  // Called when new decryption key of |level| is available. Returns true if
+  // decrypter is set successfully, otherwise, returns false.
+  virtual bool OnNewDecryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+      bool set_alternative_decrypter, bool latch_once_used) = 0;
+
+  // Called when new encryption key of |level| is available.
+  virtual void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) = 0;
+
+  // Called to set default encryption level to |level|. Only used in QUIC
+  // crypto.
+  virtual void SetDefaultEncryptionLevel(EncryptionLevel level) = 0;
+
+  // Called when both 1-RTT read and write keys are available. Only used in TLS
+  // handshake.
+  virtual void OnTlsHandshakeComplete() = 0;
+
+  // Called to discard old decryption keys to stop processing packets of
+  // encryption |level|.
+  virtual void DiscardOldDecryptionKey(EncryptionLevel level) = 0;
+
+  // Called to discard old encryption keys (and neuter obsolete data).
+  // TODO(fayang): consider to combine this with DiscardOldDecryptionKey.
+  virtual void DiscardOldEncryptionKey(EncryptionLevel level) = 0;
+
+  // Called to neuter ENCRYPTION_INITIAL data (without discarding initial keys).
+  virtual void NeuterUnencryptedData() = 0;
+
+  // Called to neuter data of HANDSHAKE_DATA packet number space. Only used in
+  // QUIC crypto. This is called 1) when a client switches to forward secure
+  // encryption level and 2) a server successfully processes a forward secure
+  // packet.
+  virtual void NeuterHandshakeData() = 0;
+
+  // Called when 0-RTT data is rejected by the server. This is only called in
+  // TLS handshakes and only called on clients.
+  virtual void OnZeroRttRejected(int reason) = 0;
+
+  // Fills in |params| with values from the delegate's QuicConfig.
+  // Returns whether the operation succeeded.
+  virtual bool FillTransportParameters(TransportParameters* params) = 0;
+
+  // Read |params| and apply the values to the delegate's QuicConfig.
+  // On failure, returns a QuicErrorCode and saves a detailed error in
+  // |error_details|.
+  virtual QuicErrorCode ProcessTransportParameters(
+      const TransportParameters& params, bool is_resumption,
+      std::string* error_details) = 0;
+
+  // Called at the end of an handshake operation callback.
+  virtual void OnHandshakeCallbackDone() = 0;
+
+  // Whether a packet flusher is currently attached.
+  virtual bool PacketFlusherAttached() const = 0;
+
+  // Get the QUIC version currently in use. tls_handshaker needs this to pass
+  // to crypto_utils to apply version-dependent HKDF labels.
+  virtual ParsedQuicVersion parsed_version() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
diff --git a/quiche/quic/core/http/capsule.cc b/quiche/quic/core/http/capsule.cc
new file mode 100644
index 0000000..f17c769
--- /dev/null
+++ b/quiche/quic/core/http/capsule.cc
@@ -0,0 +1,749 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/capsule.h"
+
+#include <type_traits>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+std::string CapsuleTypeToString(CapsuleType capsule_type) {
+  switch (capsule_type) {
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      return "REGISTER_DATAGRAM_CONTEXT";
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      return "CLOSE_DATAGRAM_CONTEXT";
+    case CapsuleType::LEGACY_DATAGRAM:
+      return "LEGACY_DATAGRAM";
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      return "DATAGRAM_WITH_CONTEXT";
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      return "DATAGRAM_WITHOUT_CONTEXT";
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      return "REGISTER_DATAGRAM_NO_CONTEXT";
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      return "CLOSE_WEBTRANSPORT_SESSION";
+  }
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(capsule_type), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
+  os << CapsuleTypeToString(capsule_type);
+  return os;
+}
+
+std::string DatagramFormatTypeToString(
+    DatagramFormatType datagram_format_type) {
+  switch (datagram_format_type) {
+    case DatagramFormatType::UDP_PAYLOAD:
+      return "UDP_PAYLOAD";
+    case DatagramFormatType::WEBTRANSPORT:
+      return "WEBTRANSPORT";
+  }
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(datagram_format_type),
+                      ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const DatagramFormatType& datagram_format_type) {
+  os << DatagramFormatTypeToString(datagram_format_type);
+  return os;
+}
+
+std::string ContextCloseCodeToString(ContextCloseCode context_close_code) {
+  switch (context_close_code) {
+    case ContextCloseCode::CLOSE_NO_ERROR:
+      return "NO_ERROR";
+    case ContextCloseCode::UNKNOWN_FORMAT:
+      return "UNKNOWN_FORMAT";
+    case ContextCloseCode::DENIED:
+      return "DENIED";
+    case ContextCloseCode::RESOURCE_LIMIT:
+      return "RESOURCE_LIMIT";
+  }
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(context_close_code),
+                      ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ContextCloseCode& context_close_code) {
+  os << ContextCloseCodeToString(context_close_code);
+  return os;
+}
+
+Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
+  switch (capsule_type) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      static_assert(
+          std::is_standard_layout<LegacyDatagramCapsule>::value &&
+              std::is_trivially_destructible<LegacyDatagramCapsule>::value,
+          "All capsule structs must have these properties");
+      legacy_datagram_capsule_ = LegacyDatagramCapsule();
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      static_assert(
+          std::is_standard_layout<DatagramWithContextCapsule>::value &&
+              std::is_trivially_destructible<DatagramWithContextCapsule>::value,
+          "All capsule structs must have these properties");
+      datagram_with_context_capsule_ = DatagramWithContextCapsule();
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      static_assert(
+          std::is_standard_layout<DatagramWithoutContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  DatagramWithoutContextCapsule>::value,
+          "All capsule structs must have these properties");
+      datagram_without_context_capsule_ = DatagramWithoutContextCapsule();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      static_assert(
+          std::is_standard_layout<RegisterDatagramContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  RegisterDatagramContextCapsule>::value,
+          "All capsule structs must have these properties");
+      register_datagram_context_capsule_ = RegisterDatagramContextCapsule();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      static_assert(
+          std::is_standard_layout<RegisterDatagramNoContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  RegisterDatagramNoContextCapsule>::value,
+          "All capsule structs must have these properties");
+      register_datagram_no_context_capsule_ =
+          RegisterDatagramNoContextCapsule();
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      static_assert(
+          std::is_standard_layout<CloseDatagramContextCapsule>::value &&
+              std::is_trivially_destructible<
+                  CloseDatagramContextCapsule>::value,
+          "All capsule structs must have these properties");
+      close_datagram_context_capsule_ = CloseDatagramContextCapsule();
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      static_assert(
+          std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
+              std::is_trivially_destructible<
+                  CloseWebTransportSessionCapsule>::value,
+          "All capsule structs must have these properties");
+      close_web_transport_session_capsule_ = CloseWebTransportSessionCapsule();
+      break;
+    default:
+      unknown_capsule_data_ = absl::string_view();
+      break;
+  }
+}
+
+// static
+Capsule Capsule::LegacyDatagram(
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view http_datagram_payload) {
+  Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
+  capsule.legacy_datagram_capsule().context_id = context_id;
+  capsule.legacy_datagram_capsule().http_datagram_payload =
+      http_datagram_payload;
+  return capsule;
+}
+
+// static
+Capsule Capsule::DatagramWithContext(QuicDatagramContextId context_id,
+                                     absl::string_view http_datagram_payload) {
+  Capsule capsule(CapsuleType::DATAGRAM_WITH_CONTEXT);
+  capsule.datagram_with_context_capsule().context_id = context_id;
+  capsule.datagram_with_context_capsule().http_datagram_payload =
+      http_datagram_payload;
+  return capsule;
+}
+
+// static
+Capsule Capsule::DatagramWithoutContext(
+    absl::string_view http_datagram_payload) {
+  Capsule capsule(CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
+  capsule.datagram_without_context_capsule().http_datagram_payload =
+      http_datagram_payload;
+  return capsule;
+}
+
+// static
+Capsule Capsule::RegisterDatagramContext(
+    QuicDatagramContextId context_id, DatagramFormatType format_type,
+    absl::string_view format_additional_data) {
+  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_CONTEXT);
+  capsule.register_datagram_context_capsule().context_id = context_id;
+  capsule.register_datagram_context_capsule().format_type = format_type;
+  capsule.register_datagram_context_capsule().format_additional_data =
+      format_additional_data;
+  return capsule;
+}
+
+// static
+Capsule Capsule::RegisterDatagramNoContext(
+    DatagramFormatType format_type, absl::string_view format_additional_data) {
+  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
+  capsule.register_datagram_no_context_capsule().format_type = format_type;
+  capsule.register_datagram_no_context_capsule().format_additional_data =
+      format_additional_data;
+  return capsule;
+}
+
+// static
+Capsule Capsule::CloseDatagramContext(QuicDatagramContextId context_id,
+                                      ContextCloseCode close_code,
+                                      absl::string_view close_details) {
+  Capsule capsule(CapsuleType::CLOSE_DATAGRAM_CONTEXT);
+  capsule.close_datagram_context_capsule().context_id = context_id;
+  capsule.close_datagram_context_capsule().close_code = close_code;
+  capsule.close_datagram_context_capsule().close_details = close_details;
+  return capsule;
+}
+
+// static
+Capsule Capsule::CloseWebTransportSession(WebTransportSessionError error_code,
+                                          absl::string_view error_message) {
+  Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
+  capsule.close_web_transport_session_capsule().error_code = error_code;
+  capsule.close_web_transport_session_capsule().error_message = error_message;
+  return capsule;
+}
+
+// static
+Capsule Capsule::Unknown(uint64_t capsule_type,
+                         absl::string_view unknown_capsule_data) {
+  Capsule capsule(static_cast<CapsuleType>(capsule_type));
+  capsule.unknown_capsule_data() = unknown_capsule_data;
+  return capsule;
+}
+
+Capsule& Capsule::operator=(const Capsule& other) {
+  capsule_type_ = other.capsule_type_;
+  switch (capsule_type_) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      datagram_with_context_capsule_ = other.datagram_with_context_capsule_;
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      datagram_without_context_capsule_ =
+          other.datagram_without_context_capsule_;
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      register_datagram_context_capsule_ =
+          other.register_datagram_context_capsule_;
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      register_datagram_no_context_capsule_ =
+          other.register_datagram_no_context_capsule_;
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      close_datagram_context_capsule_ = other.close_datagram_context_capsule_;
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      close_web_transport_session_capsule_ =
+          other.close_web_transport_session_capsule_;
+      break;
+    default:
+      unknown_capsule_data_ = other.unknown_capsule_data_;
+      break;
+  }
+  return *this;
+}
+
+Capsule::Capsule(const Capsule& other) : Capsule(other.capsule_type_) {
+  *this = other;
+}
+
+bool Capsule::operator==(const Capsule& other) const {
+  if (capsule_type_ != other.capsule_type_) {
+    return false;
+  }
+  switch (capsule_type_) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      return legacy_datagram_capsule_.context_id ==
+                 other.legacy_datagram_capsule_.context_id &&
+             legacy_datagram_capsule_.http_datagram_payload ==
+                 other.legacy_datagram_capsule_.http_datagram_payload;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      return datagram_with_context_capsule_.context_id ==
+                 other.datagram_with_context_capsule_.context_id &&
+             datagram_with_context_capsule_.http_datagram_payload ==
+                 other.datagram_with_context_capsule_.http_datagram_payload;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      return datagram_without_context_capsule_.http_datagram_payload ==
+             other.datagram_without_context_capsule_.http_datagram_payload;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      return register_datagram_context_capsule_.context_id ==
+                 other.register_datagram_context_capsule_.context_id &&
+             register_datagram_context_capsule_.format_type ==
+                 other.register_datagram_context_capsule_.format_type &&
+             register_datagram_context_capsule_.format_additional_data ==
+                 other.register_datagram_context_capsule_
+                     .format_additional_data;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      return register_datagram_no_context_capsule_.format_type ==
+                 other.register_datagram_no_context_capsule_.format_type &&
+             register_datagram_no_context_capsule_.format_additional_data ==
+                 other.register_datagram_no_context_capsule_
+                     .format_additional_data;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      return close_datagram_context_capsule_.context_id ==
+                 other.close_datagram_context_capsule_.context_id &&
+             close_datagram_context_capsule_.close_code ==
+                 other.close_datagram_context_capsule_.close_code &&
+             close_datagram_context_capsule_.close_details ==
+                 other.close_datagram_context_capsule_.close_details;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      return close_web_transport_session_capsule_.error_code ==
+                 other.close_web_transport_session_capsule_.error_code &&
+             close_web_transport_session_capsule_.error_message ==
+                 other.close_web_transport_session_capsule_.error_message;
+    default:
+      return unknown_capsule_data_ == other.unknown_capsule_data_;
+  }
+}
+
+std::string Capsule::ToString() const {
+  std::string rv = CapsuleTypeToString(capsule_type_);
+  switch (capsule_type_) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      if (legacy_datagram_capsule_.context_id.has_value()) {
+        absl::StrAppend(&rv, "(", legacy_datagram_capsule_.context_id.value(),
+                        ")");
+      }
+      absl::StrAppend(&rv, "[",
+                      absl::BytesToHexString(
+                          legacy_datagram_capsule_.http_datagram_payload),
+                      "]");
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      absl::StrAppend(&rv, "(", datagram_with_context_capsule_.context_id, ")[",
+                      absl::BytesToHexString(
+                          datagram_with_context_capsule_.http_datagram_payload),
+                      "]");
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      absl::StrAppend(
+          &rv, "[",
+          absl::BytesToHexString(
+              datagram_without_context_capsule_.http_datagram_payload),
+          "]");
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      absl::StrAppend(
+          &rv, "(context_id=", register_datagram_context_capsule_.context_id,
+          ",format_type=",
+          DatagramFormatTypeToString(
+              register_datagram_context_capsule_.format_type),
+          "){",
+          absl::BytesToHexString(
+              register_datagram_context_capsule_.format_additional_data),
+          "}");
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      absl::StrAppend(
+          &rv, "(format_type=",
+          DatagramFormatTypeToString(
+              register_datagram_no_context_capsule_.format_type),
+          "){",
+          absl::BytesToHexString(
+              register_datagram_no_context_capsule_.format_additional_data),
+          "}");
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      absl::StrAppend(
+          &rv, "(context_id=", close_datagram_context_capsule_.context_id,
+          ",close_code=",
+          ContextCloseCodeToString(close_datagram_context_capsule_.close_code),
+          ",close_details=\"",
+          absl::BytesToHexString(close_datagram_context_capsule_.close_details),
+          "\")");
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      absl::StrAppend(
+          &rv, "(error_code=", close_web_transport_session_capsule_.error_code,
+          ",error_message=\"",
+          close_web_transport_session_capsule_.error_message, "\")");
+      break;
+    default:
+      absl::StrAppend(&rv, "[", absl::BytesToHexString(unknown_capsule_data_),
+                      "]");
+      break;
+  }
+  return rv;
+}
+
+std::ostream& operator<<(std::ostream& os, const Capsule& capsule) {
+  os << capsule.ToString();
+  return os;
+}
+
+CapsuleParser::CapsuleParser(Visitor* visitor) : visitor_(visitor) {
+  QUICHE_DCHECK_NE(visitor_, nullptr);
+}
+
+quiche::QuicheBuffer SerializeCapsule(
+    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator) {
+  QuicByteCount capsule_type_length = QuicDataWriter::GetVarInt62Len(
+      static_cast<uint64_t>(capsule.capsule_type()));
+  QuicByteCount capsule_data_length;
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      capsule_data_length =
+          capsule.legacy_datagram_capsule().http_datagram_payload.length();
+      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
+        capsule_data_length += QuicDataWriter::GetVarInt62Len(
+            capsule.legacy_datagram_capsule().context_id.value());
+      }
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(
+              capsule.datagram_with_context_capsule().context_id) +
+          capsule.datagram_with_context_capsule()
+              .http_datagram_payload.length();
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      capsule_data_length = capsule.datagram_without_context_capsule()
+                                .http_datagram_payload.length();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(
+              capsule.register_datagram_context_capsule().context_id) +
+          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
+              capsule.register_datagram_context_capsule().format_type)) +
+          capsule.register_datagram_context_capsule()
+              .format_additional_data.length();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
+              capsule.register_datagram_no_context_capsule().format_type)) +
+          capsule.register_datagram_no_context_capsule()
+              .format_additional_data.length();
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      capsule_data_length =
+          QuicDataWriter::GetVarInt62Len(
+              capsule.close_datagram_context_capsule().context_id) +
+          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
+              capsule.close_datagram_context_capsule().close_code)) +
+          capsule.close_datagram_context_capsule().close_details.length();
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      capsule_data_length =
+          sizeof(WebTransportSessionError) +
+          capsule.close_web_transport_session_capsule().error_message.size();
+      break;
+    default:
+      capsule_data_length = capsule.unknown_capsule_data().length();
+      break;
+  }
+  QuicByteCount capsule_length_length =
+      QuicDataWriter::GetVarInt62Len(capsule_data_length);
+  QuicByteCount total_capsule_length =
+      capsule_type_length + capsule_length_length + capsule_data_length;
+  quiche::QuicheBuffer buffer(allocator, total_capsule_length);
+  QuicDataWriter writer(buffer.size(), buffer.data());
+  if (!writer.WriteVarInt62(static_cast<uint64_t>(capsule.capsule_type()))) {
+    QUIC_BUG(capsule type write fail) << "Failed to write CAPSULE type";
+    return {};
+  }
+  if (!writer.WriteVarInt62(capsule_data_length)) {
+    QUIC_BUG(capsule length write fail) << "Failed to write CAPSULE length";
+    return {};
+  }
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
+        if (!writer.WriteVarInt62(
+                capsule.legacy_datagram_capsule().context_id.value())) {
+          QUIC_BUG(datagram capsule context ID write fail)
+              << "Failed to write LEGACY_DATAGRAM CAPSULE context ID";
+          return {};
+        }
+      }
+      if (!writer.WriteStringPiece(
+              capsule.legacy_datagram_capsule().http_datagram_payload)) {
+        QUIC_BUG(datagram capsule payload write fail)
+            << "Failed to write LEGACY_DATAGRAM CAPSULE payload";
+        return {};
+      }
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      if (!writer.WriteVarInt62(
+              capsule.datagram_with_context_capsule().context_id)) {
+        QUIC_BUG(datagram capsule context ID write fail)
+            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE context ID";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.datagram_with_context_capsule().http_datagram_payload)) {
+        QUIC_BUG(datagram capsule payload write fail)
+            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE payload";
+        return {};
+      }
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
+                                       .http_datagram_payload)) {
+        QUIC_BUG(datagram capsule payload write fail)
+            << "Failed to write DATAGRAM_WITHOUT_CONTEXT CAPSULE payload";
+        return {};
+      }
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      if (!writer.WriteVarInt62(
+              capsule.register_datagram_context_capsule().context_id)) {
+        QUIC_BUG(register context capsule context ID write fail)
+            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE context ID";
+        return {};
+      }
+      if (!writer.WriteVarInt62(static_cast<uint64_t>(
+              capsule.register_datagram_context_capsule().format_type))) {
+        QUIC_BUG(register context capsule format type write fail)
+            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE format type";
+        return {};
+      }
+      if (!writer.WriteStringPiece(capsule.register_datagram_context_capsule()
+                                       .format_additional_data)) {
+        QUIC_BUG(register context capsule additional data write fail)
+            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE additional "
+               "data";
+        return {};
+      }
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      if (!writer.WriteVarInt62(static_cast<uint64_t>(
+              capsule.register_datagram_no_context_capsule().format_type))) {
+        QUIC_BUG(register no context capsule format type write fail)
+            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE format "
+               "type";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.register_datagram_no_context_capsule()
+                  .format_additional_data)) {
+        QUIC_BUG(register no context capsule additional data write fail)
+            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE "
+               "additional data";
+        return {};
+      }
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      if (!writer.WriteVarInt62(
+              capsule.close_datagram_context_capsule().context_id)) {
+        QUIC_BUG(close context capsule context ID write fail)
+            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE context ID";
+        return {};
+      }
+      if (!writer.WriteVarInt62(static_cast<uint64_t>(
+              capsule.close_datagram_context_capsule().close_code))) {
+        QUIC_BUG(close context capsule close code write fail)
+            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close code";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.close_datagram_context_capsule().close_details)) {
+        QUIC_BUG(close context capsule close details write fail)
+            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close details";
+        return {};
+      }
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      if (!writer.WriteUInt32(
+              capsule.close_web_transport_session_capsule().error_code)) {
+        QUIC_BUG(close webtransport session capsule error code write fail)
+            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error code";
+        return {};
+      }
+      if (!writer.WriteStringPiece(
+              capsule.close_web_transport_session_capsule().error_message)) {
+        QUIC_BUG(close webtransport session capsule error message write fail)
+            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error message";
+        return {};
+      }
+      break;
+    default:
+      if (!writer.WriteStringPiece(capsule.unknown_capsule_data())) {
+        QUIC_BUG(capsule data write fail) << "Failed to write CAPSULE data";
+        return {};
+      }
+      break;
+  }
+  if (writer.remaining() != 0) {
+    QUIC_BUG(capsule write length mismatch)
+        << "CAPSULE serialization wrote " << writer.length() << " instead of "
+        << writer.capacity();
+    return {};
+  }
+  return buffer;
+}
+
+bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
+  if (parsing_error_occurred_) {
+    return false;
+  }
+  absl::StrAppend(&buffered_data_, capsule_fragment);
+  while (true) {
+    const size_t buffered_data_read = AttemptParseCapsule();
+    if (parsing_error_occurred_) {
+      QUICHE_DCHECK_EQ(buffered_data_read, 0u);
+      buffered_data_.clear();
+      return false;
+    }
+    if (buffered_data_read == 0) {
+      break;
+    }
+    buffered_data_.erase(0, buffered_data_read);
+  }
+  static constexpr size_t kMaxCapsuleBufferSize = 1024 * 1024;
+  if (buffered_data_.size() > kMaxCapsuleBufferSize) {
+    buffered_data_.clear();
+    ReportParseFailure("Refusing to buffer too much capsule data");
+    return false;
+  }
+  return true;
+}
+
+size_t CapsuleParser::AttemptParseCapsule() {
+  QUICHE_DCHECK(!parsing_error_occurred_);
+  if (buffered_data_.empty()) {
+    return 0;
+  }
+  QuicDataReader capsule_fragment_reader(buffered_data_);
+  uint64_t capsule_type64;
+  if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
+    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule type";
+    return 0;
+  }
+  absl::string_view capsule_data;
+  if (!capsule_fragment_reader.ReadStringPieceVarInt62(&capsule_data)) {
+    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule length or "
+                     "full capsule data";
+    return 0;
+  }
+  QuicDataReader capsule_data_reader(capsule_data);
+  Capsule capsule(static_cast<CapsuleType>(capsule_type64));
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM:
+      if (datagram_context_id_present_) {
+        uint64_t context_id;
+        if (!capsule_data_reader.ReadVarInt62(&context_id)) {
+          ReportParseFailure(
+              "Unable to parse capsule LEGACY_DATAGRAM context ID");
+          return 0;
+        }
+        capsule.legacy_datagram_capsule().context_id = context_id;
+      }
+      capsule.legacy_datagram_capsule().http_datagram_payload =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT:
+      uint64_t context_id;
+      if (!capsule_data_reader.ReadVarInt62(&context_id)) {
+        ReportParseFailure(
+            "Unable to parse capsule DATAGRAM_WITH_CONTEXT context ID");
+        return 0;
+      }
+      capsule.datagram_with_context_capsule().context_id = context_id;
+      capsule.datagram_with_context_capsule().http_datagram_payload =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
+      capsule.datagram_without_context_capsule().http_datagram_payload =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
+      if (!capsule_data_reader.ReadVarInt62(
+              &capsule.register_datagram_context_capsule().context_id)) {
+        ReportParseFailure(
+            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT context ID");
+        return 0;
+      }
+      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
+              &capsule.register_datagram_context_capsule().format_type))) {
+        ReportParseFailure(
+            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT format type");
+        return 0;
+      }
+      capsule.register_datagram_context_capsule().format_additional_data =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
+      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
+              &capsule.register_datagram_no_context_capsule().format_type))) {
+        ReportParseFailure(
+            "Unable to parse capsule REGISTER_DATAGRAM_NO_CONTEXT format type");
+        return 0;
+      }
+      capsule.register_datagram_no_context_capsule().format_additional_data =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
+      if (!capsule_data_reader.ReadVarInt62(
+              &capsule.close_datagram_context_capsule().context_id)) {
+        ReportParseFailure(
+            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT context ID");
+        return 0;
+      }
+      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
+              &capsule.close_datagram_context_capsule().close_code))) {
+        ReportParseFailure(
+            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT close code");
+        return 0;
+      }
+      capsule.close_datagram_context_capsule().close_details =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
+      if (!capsule_data_reader.ReadUInt32(
+              &capsule.close_web_transport_session_capsule().error_code)) {
+        ReportParseFailure(
+            "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
+        return 0;
+      }
+      capsule.close_web_transport_session_capsule().error_message =
+          capsule_data_reader.ReadRemainingPayload();
+      break;
+    default:
+      capsule.unknown_capsule_data() =
+          capsule_data_reader.ReadRemainingPayload();
+  }
+  if (!visitor_->OnCapsule(capsule)) {
+    ReportParseFailure("Visitor failed to process capsule");
+    return 0;
+  }
+  return capsule_fragment_reader.PreviouslyReadPayload().length();
+}
+
+void CapsuleParser::ReportParseFailure(const std::string& error_message) {
+  if (parsing_error_occurred_) {
+    QUIC_BUG(multiple parse errors) << "Experienced multiple parse failures";
+    return;
+  }
+  parsing_error_occurred_ = true;
+  visitor_->OnCapsuleParseFailure(error_message);
+}
+
+void CapsuleParser::ErrorIfThereIsRemainingBufferedData() {
+  if (parsing_error_occurred_) {
+    return;
+  }
+  if (!buffered_data_.empty()) {
+    ReportParseFailure("Incomplete capsule left at the end of the stream");
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/capsule.h b/quiche/quic/core/http/capsule.h
new file mode 100644
index 0000000..5a93bd3
--- /dev/null
+++ b/quiche/quic/core/http/capsule.h
@@ -0,0 +1,291 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
+#define QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+enum class CapsuleType : uint64_t {
+  // Casing in this enum matches the IETF specification.
+  LEGACY_DATAGRAM = 0xff37a0,  // draft-ietf-masque-h3-datagram-04
+  REGISTER_DATAGRAM_CONTEXT = 0xff37a1,
+  REGISTER_DATAGRAM_NO_CONTEXT = 0xff37a2,
+  CLOSE_DATAGRAM_CONTEXT = 0xff37a3,
+  DATAGRAM_WITH_CONTEXT = 0xff37a4,
+  DATAGRAM_WITHOUT_CONTEXT = 0xff37a5,
+  CLOSE_WEBTRANSPORT_SESSION = 0x2843,
+};
+
+QUIC_EXPORT_PRIVATE std::string CapsuleTypeToString(CapsuleType capsule_type);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const CapsuleType& capsule_type);
+
+enum class DatagramFormatType : uint64_t {
+  // Casing in this enum matches the IETF specification.
+  UDP_PAYLOAD = 0xff6f00,
+  WEBTRANSPORT = 0xff7c00,
+};
+
+QUIC_EXPORT_PRIVATE std::string DatagramFormatTypeToString(
+    DatagramFormatType datagram_format_type);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const DatagramFormatType& datagram_format_type);
+
+enum class ContextCloseCode : uint64_t {
+  // Casing in this enum matches the IETF specification.
+  CLOSE_NO_ERROR = 0xff78a0,  // NO_ERROR already exists in winerror.h.
+  UNKNOWN_FORMAT = 0xff78a1,
+  DENIED = 0xff78a2,
+  RESOURCE_LIMIT = 0xff78a3,
+};
+
+QUIC_EXPORT_PRIVATE std::string ContextCloseCodeToString(
+    ContextCloseCode context_close_code);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ContextCloseCode& context_close_code);
+
+struct QUIC_EXPORT_PRIVATE LegacyDatagramCapsule {
+  absl::optional<QuicDatagramContextId> context_id;
+  absl::string_view http_datagram_payload;
+};
+struct QUIC_EXPORT_PRIVATE DatagramWithContextCapsule {
+  QuicDatagramContextId context_id;
+  absl::string_view http_datagram_payload;
+};
+struct QUIC_EXPORT_PRIVATE DatagramWithoutContextCapsule {
+  absl::string_view http_datagram_payload;
+};
+struct QUIC_EXPORT_PRIVATE RegisterDatagramContextCapsule {
+  QuicDatagramContextId context_id;
+  DatagramFormatType format_type;
+  absl::string_view format_additional_data;
+};
+struct QUIC_EXPORT_PRIVATE RegisterDatagramNoContextCapsule {
+  DatagramFormatType format_type;
+  absl::string_view format_additional_data;
+};
+struct QUIC_EXPORT_PRIVATE CloseDatagramContextCapsule {
+  QuicDatagramContextId context_id;
+  ContextCloseCode close_code;
+  absl::string_view close_details;
+};
+struct QUIC_EXPORT_PRIVATE CloseWebTransportSessionCapsule {
+  WebTransportSessionError error_code;
+  absl::string_view error_message;
+};
+
+// Capsule from draft-ietf-masque-h3-datagram.
+// IMPORTANT NOTE: Capsule does not own any of the absl::string_view memory it
+// points to. Strings saved into a capsule must outlive the capsule object. Any
+// code that sees a capsule in a callback needs to either process it immediately
+// or perform its own deep copy.
+class QUIC_EXPORT_PRIVATE Capsule {
+ public:
+  static Capsule LegacyDatagram(
+      absl::optional<QuicDatagramContextId> context_id = absl::nullopt,
+      absl::string_view http_datagram_payload = absl::string_view());
+  static Capsule DatagramWithContext(
+      QuicDatagramContextId context_id,
+      absl::string_view http_datagram_payload = absl::string_view());
+  static Capsule DatagramWithoutContext(
+      absl::string_view http_datagram_payload = absl::string_view());
+  static Capsule RegisterDatagramContext(
+      QuicDatagramContextId context_id, DatagramFormatType format_type,
+      absl::string_view format_additional_data = absl::string_view());
+  static Capsule RegisterDatagramNoContext(
+      DatagramFormatType format_type,
+      absl::string_view format_additional_data = absl::string_view());
+  static Capsule CloseDatagramContext(
+      QuicDatagramContextId context_id,
+      ContextCloseCode close_code = ContextCloseCode::CLOSE_NO_ERROR,
+      absl::string_view close_details = absl::string_view());
+  static Capsule CloseWebTransportSession(
+      WebTransportSessionError error_code = 0,
+      absl::string_view error_message = "");
+  static Capsule Unknown(
+      uint64_t capsule_type,
+      absl::string_view unknown_capsule_data = absl::string_view());
+
+  explicit Capsule(CapsuleType capsule_type);
+  Capsule(const Capsule& other);
+  Capsule& operator=(const Capsule& other);
+  bool operator==(const Capsule& other) const;
+
+  // Human-readable information string for debugging purposes.
+  std::string ToString() const;
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const Capsule& capsule);
+
+  CapsuleType capsule_type() const { return capsule_type_; }
+  LegacyDatagramCapsule& legacy_datagram_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
+    return legacy_datagram_capsule_;
+  }
+  const LegacyDatagramCapsule& legacy_datagram_capsule() const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
+    return legacy_datagram_capsule_;
+  }
+  DatagramWithContextCapsule& datagram_with_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
+    return datagram_with_context_capsule_;
+  }
+  const DatagramWithContextCapsule& datagram_with_context_capsule() const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
+    return datagram_with_context_capsule_;
+  }
+  DatagramWithoutContextCapsule& datagram_without_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
+    return datagram_without_context_capsule_;
+  }
+  const DatagramWithoutContextCapsule& datagram_without_context_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
+    return datagram_without_context_capsule_;
+  }
+  RegisterDatagramContextCapsule& register_datagram_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
+    return register_datagram_context_capsule_;
+  }
+  const RegisterDatagramContextCapsule& register_datagram_context_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
+    return register_datagram_context_capsule_;
+  }
+  RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
+    return register_datagram_no_context_capsule_;
+  }
+  const RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
+    return register_datagram_no_context_capsule_;
+  }
+  CloseDatagramContextCapsule& close_datagram_context_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
+    return close_datagram_context_capsule_;
+  }
+  const CloseDatagramContextCapsule& close_datagram_context_capsule() const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
+    return close_datagram_context_capsule_;
+  }
+  CloseWebTransportSessionCapsule& close_web_transport_session_capsule() {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
+    return close_web_transport_session_capsule_;
+  }
+  const CloseWebTransportSessionCapsule& close_web_transport_session_capsule()
+      const {
+    QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
+    return close_web_transport_session_capsule_;
+  }
+  absl::string_view& unknown_capsule_data() {
+    QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
+        << capsule_type_;
+    return unknown_capsule_data_;
+  }
+  const absl::string_view& unknown_capsule_data() const {
+    QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
+                  capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
+                  capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
+        << capsule_type_;
+    return unknown_capsule_data_;
+  }
+
+ private:
+  CapsuleType capsule_type_;
+  union {
+    LegacyDatagramCapsule legacy_datagram_capsule_;
+    DatagramWithContextCapsule datagram_with_context_capsule_;
+    DatagramWithoutContextCapsule datagram_without_context_capsule_;
+    RegisterDatagramContextCapsule register_datagram_context_capsule_;
+    RegisterDatagramNoContextCapsule register_datagram_no_context_capsule_;
+    CloseDatagramContextCapsule close_datagram_context_capsule_;
+    CloseWebTransportSessionCapsule close_web_transport_session_capsule_;
+    absl::string_view unknown_capsule_data_;
+  };
+};
+
+namespace test {
+class CapsuleParserPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE CapsuleParser {
+ public:
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called when a capsule has been successfully parsed. The return value
+    // indicates whether the contents of the capsule are valid: if false is
+    // returned, the parse operation will be considered failed and
+    // OnCapsuleParseFailure will be called. Note that since Capsule does not
+    // own the memory backing its string_views, that memory is only valid until
+    // this callback returns. Visitors that wish to access the capsule later
+    // MUST make a deep copy before this returns.
+    virtual bool OnCapsule(const Capsule& capsule) = 0;
+
+    virtual void OnCapsuleParseFailure(const std::string& error_message) = 0;
+  };
+
+  // |visitor| must be non-null, and must outlive CapsuleParser.
+  explicit CapsuleParser(Visitor* visitor);
+
+  void set_datagram_context_id_present(bool datagram_context_id_present) {
+    datagram_context_id_present_ = datagram_context_id_present;
+  }
+
+  // Ingests a capsule fragment (any fragment of bytes from the capsule data
+  // stream) and parses and complete capsules it encounters. Returns false if a
+  // parsing error occurred.
+  bool IngestCapsuleFragment(absl::string_view capsule_fragment);
+
+  void ErrorIfThereIsRemainingBufferedData();
+
+  friend class test::CapsuleParserPeer;
+
+ private:
+  // Attempts to parse a single capsule from |buffered_data_|. If a full capsule
+  // is not available, returns 0. If a parsing error occurs, returns 0.
+  // Otherwise, returns the number of bytes in the parsed capsule.
+  size_t AttemptParseCapsule();
+  void ReportParseFailure(const std::string& error_message);
+
+  // Whether HTTP Datagram Context IDs are present.
+  bool datagram_context_id_present_ = false;
+  // Whether a parsing error has occurred.
+  bool parsing_error_occurred_ = false;
+  // Visitor which will receive callbacks, unowned.
+  Visitor* visitor_;
+
+  std::string buffered_data_;
+};
+
+// Serializes |capsule| into a newly allocated buffer.
+QUIC_EXPORT_PRIVATE quiche::QuicheBuffer SerializeCapsule(
+    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_CAPSULE_H_
diff --git a/quiche/quic/core/http/capsule_test.cc b/quiche/quic/core/http/capsule_test.cc
new file mode 100644
index 0000000..895f275
--- /dev/null
+++ b/quiche/quic/core/http/capsule_test.cc
@@ -0,0 +1,364 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/capsule.h"
+
+#include <cstddef>
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Return;
+
+namespace quic {
+namespace test {
+
+class CapsuleParserPeer {
+ public:
+  static std::string* buffered_data(CapsuleParser* capsule_parser) {
+    return &capsule_parser->buffered_data_;
+  }
+};
+
+namespace {
+
+constexpr DatagramFormatType kFakeFormatType =
+    static_cast<DatagramFormatType>(0x123456);
+constexpr ContextCloseCode kFakeCloseCode =
+    static_cast<ContextCloseCode>(0x654321);
+
+class MockCapsuleParserVisitor : public CapsuleParser::Visitor {
+ public:
+  MockCapsuleParserVisitor() {
+    ON_CALL(*this, OnCapsule(_)).WillByDefault(Return(true));
+  }
+  ~MockCapsuleParserVisitor() override = default;
+  MOCK_METHOD(bool, OnCapsule, (const Capsule& capsule), (override));
+  MOCK_METHOD(void, OnCapsuleParseFailure, (const std::string& error_message),
+              (override));
+};
+
+class CapsuleTest : public QuicTest {
+ public:
+  CapsuleTest() : capsule_parser_(&visitor_) {}
+
+  void ValidateParserIsEmpty() {
+    EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+    EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
+    capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+    EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+  }
+
+  void TestSerialization(const Capsule& capsule,
+                         const std::string& expected_bytes) {
+    quiche::QuicheBuffer serialized_capsule =
+        SerializeCapsule(capsule, quiche::SimpleBufferAllocator::Get());
+    quiche::test::CompareCharArraysWithHexError(
+        "Serialized capsule", serialized_capsule.data(),
+        serialized_capsule.size(), expected_bytes.data(),
+        expected_bytes.size());
+  }
+
+  ::testing::StrictMock<MockCapsuleParserVisitor> visitor_;
+  CapsuleParser capsule_parser_;
+};
+
+TEST_F(CapsuleTest, LegacyDatagramCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a0"          // LEGACY_DATAGRAM capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule =
+      Capsule::LegacyDatagram(/*context_id=*/absl::nullopt, datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, LegacyDatagramCapsuleWithContext) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a0"          // LEGACY_DATAGRAM capsule type
+      "09"                // capsule length
+      "04"                // context ID
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  capsule_parser_.set_datagram_context_id_present(true);
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule =
+      Capsule::LegacyDatagram(/*context_id=*/4, datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, DatagramWithoutContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule = Capsule::DatagramWithoutContext(datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, DatagramWithContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a4"          // DATAGRAM_WITH_CONTEXT capsule type
+      "09"                // capsule length
+      "04"                // context ID
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule =
+      Capsule::DatagramWithContext(/*context_id=*/4, datagram_payload);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, RegisterContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a1"          // REGISTER_DATAGRAM_CONTEXT capsule type
+      "0d"                // capsule length
+      "04"                // context ID
+      "80123456"          // 0x123456 datagram format type
+      "f1f2f3f4f5f6f7f8"  // format additional data
+  );
+  std::string format_additional_data =
+      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
+  Capsule expected_capsule = Capsule::RegisterDatagramContext(
+      /*context_id=*/4, kFakeFormatType, format_additional_data);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, RegisterNoContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a2"          // REGISTER_DATAGRAM_NO_CONTEXT capsule type
+      "0c"                // capsule length
+      "80123456"          // 0x123456 datagram format type
+      "f1f2f3f4f5f6f7f8"  // format additional data
+  );
+  std::string format_additional_data =
+      absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
+  Capsule expected_capsule = Capsule::RegisterDatagramNoContext(
+      kFakeFormatType, format_additional_data);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, CloseContextCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a3"  // CLOSE_DATAGRAM_CONTEXT capsule type
+      "27"        // capsule length
+      "04"        // context ID
+      "80654321"  // 0x654321 close code
+  );
+  std::string close_details = "All your contexts are belong to us";
+  capsule_fragment += close_details;
+  Capsule expected_capsule = Capsule::CloseDatagramContext(
+      /*context_id=*/4, kFakeCloseCode, close_details);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, CloseWebTransportStreamCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "6843"        // CLOSE_WEBTRANSPORT_STREAM capsule type
+      "09"          // capsule length
+      "00001234"    // 0x1234 error code
+      "68656c6c6f"  // "hello" error message
+  );
+  Capsule expected_capsule = Capsule::CloseWebTransportSession(
+      /*error_code=*/0x1234, /*error_message=*/"hello");
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, UnknownCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "33"                // unknown capsule type of 0x33
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // unknown capsule data
+  );
+  std::string unknown_capsule_data = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  Capsule expected_capsule = Capsule::Unknown(0x33, unknown_capsule_data);
+  {
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+  TestSerialization(expected_capsule, capsule_fragment);
+}
+
+TEST_F(CapsuleTest, TwoCapsules) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
+  Capsule expected_capsule1 =
+      Capsule::DatagramWithoutContext(datagram_payload1);
+  Capsule expected_capsule2 =
+      Capsule::DatagramWithoutContext(datagram_payload2);
+  {
+    InSequence s;
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  ValidateParserIsEmpty();
+}
+
+TEST_F(CapsuleTest, TwoCapsulesPartialReads) {
+  std::string capsule_fragment1 = absl::HexStringToBytes(
+      "80ff37a5"  // first capsule DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"        // frist capsule length
+      "a1a2a3a4"  // first half of HTTP Datagram payload of first capsule
+  );
+  std::string capsule_fragment2 = absl::HexStringToBytes(
+      "a5a6a7a8"  // second half of HTTP Datagram payload 1
+      "80ff37a5"  // second capsule DATAGRAM_WITHOUT_CONTEXT capsule type
+  );
+  std::string capsule_fragment3 = absl::HexStringToBytes(
+      "08"                // second capsule length
+      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload of second capsule
+  );
+  capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
+  Capsule expected_capsule1 =
+      Capsule::DatagramWithoutContext(datagram_payload1);
+  Capsule expected_capsule2 =
+      Capsule::DatagramWithoutContext(datagram_payload2);
+  {
+    InSequence s;
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
+    EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment1));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment2));
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment3));
+  }
+  ValidateParserIsEmpty();
+}
+
+TEST_F(CapsuleTest, TwoCapsulesOneByteAtATime) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "a1a2a3a4a5a6a7a8"  // HTTP Datagram payload
+      "80ff37a5"          // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"                // capsule length
+      "b1b2b3b4b5b6b7b8"  // HTTP Datagram payload
+  );
+  std::string datagram_payload1 = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
+  std::string datagram_payload2 = absl::HexStringToBytes("b1b2b3b4b5b6b7b8");
+  Capsule expected_capsule1 =
+      Capsule::DatagramWithoutContext(datagram_payload1);
+  Capsule expected_capsule2 =
+      Capsule::DatagramWithoutContext(datagram_payload2);
+  for (size_t i = 0; i < capsule_fragment.size(); i++) {
+    if (i < capsule_fragment.size() / 2 - 1) {
+      EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+    } else if (i == capsule_fragment.size() / 2 - 1) {
+      EXPECT_CALL(visitor_, OnCapsule(expected_capsule1));
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+      EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+    } else if (i < capsule_fragment.size() - 1) {
+      EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+    } else {
+      EXPECT_CALL(visitor_, OnCapsule(expected_capsule2));
+      ASSERT_TRUE(
+          capsule_parser_.IngestCapsuleFragment(capsule_fragment.substr(i, 1)));
+      EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+    }
+  }
+  capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+  EXPECT_TRUE(CapsuleParserPeer::buffered_data(&capsule_parser_)->empty());
+}
+
+TEST_F(CapsuleTest, PartialCapsuleThenError) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+      "80ff37a5"  // DATAGRAM_WITHOUT_CONTEXT capsule type
+      "08"        // capsule length
+      "a1a2a3a4"  // first half of HTTP Datagram payload
+  );
+  EXPECT_CALL(visitor_, OnCapsule(_)).Times(0);
+  {
+    EXPECT_CALL(visitor_, OnCapsuleParseFailure(_)).Times(0);
+    ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+  }
+  {
+    EXPECT_CALL(visitor_,
+                OnCapsuleParseFailure(
+                    "Incomplete capsule left at the end of the stream"));
+    capsule_parser_.ErrorIfThereIsRemainingBufferedData();
+  }
+}
+
+TEST_F(CapsuleTest, RejectOverlyLongCapsule) {
+  std::string capsule_fragment = absl::HexStringToBytes(
+                                     "33"        // unknown capsule type of 0x33
+                                     "80123456"  // capsule length
+                                     ) +
+                                 std::string(1111111, '?');
+  EXPECT_CALL(visitor_, OnCapsuleParseFailure(
+                            "Refusing to buffer too much capsule data"));
+  EXPECT_FALSE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
new file mode 100644
index 0000000..9338295
--- /dev/null
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -0,0 +1,6908 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/test_tools/bad_packet_writer.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/packet_dropping_test_writer.h"
+#include "quiche/quic/test_tools/packet_reordering_writer.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/quic/test_tools/quic_client_peer.h"
+#include "quiche/quic/test_tools/quic_client_session_cache_peer.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_server_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_backend.h"
+#include "quiche/quic/test_tools/quic_test_client.h"
+#include "quiche/quic/test_tools/quic_test_server.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+#include "quiche/quic/test_tools/server_thread.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_client.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_server.h"
+#include "quiche/quic/tools/quic_simple_client_stream.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+using spdy::kV3LowestPriority;
+using spdy::SpdyFramer;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsIR;
+using ::testing::_;
+using ::testing::Assign;
+using ::testing::Invoke;
+using ::testing::NiceMock;
+using ::testing::UnorderedElementsAreArray;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kFooResponseBody[] = "Artichoke hearts make me happy.";
+const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
+const char kTestUserAgentId[] = "quic/core/http/end_to_end_test.cc";
+const float kSessionToStreamRatio = 1.5;
+
+// Run all tests with the cross products of all versions.
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, QuicTag congestion_control_tag)
+      : version(version), congestion_control_tag(congestion_control_tag) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
+    os << "{ version: " << ParsedQuicVersionToString(p.version);
+    os << " congestion_control_tag: "
+       << QuicTagToString(p.congestion_control_tag) << " }";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  QuicTag congestion_control_tag;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  std::string rv = absl::StrCat(ParsedQuicVersionToString(p.version), "_",
+                                QuicTagToString(p.congestion_control_tag));
+  std::replace(rv.begin(), rv.end(), ',', '_');
+  std::replace(rv.begin(), rv.end(), ' ', '_');
+  return rv;
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC, kB2ON}) {
+    if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
+        congestion_control_tag == kB2ON) {
+      continue;
+    }
+    for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+      params.push_back(TestParams(version, congestion_control_tag));
+    }  // End of outer version loop.
+  }    // End of congestion_control_tag loop.
+
+  return params;
+}
+
+void WriteHeadersOnStream(QuicSpdyStream* stream) {
+  // Since QuicSpdyStream uses QuicHeaderList::empty() to detect too large
+  // headers, it also fails when receiving empty headers.
+  SpdyHeaderBlock headers;
+  headers[":authority"] = "test.example.com:443";
+  headers[":path"] = "/path";
+  headers[":method"] = "GET";
+  headers[":scheme"] = "https";
+  stream->WriteHeaders(std::move(headers), /* fin = */ false, nullptr);
+}
+
+class ServerDelegate : public PacketDroppingTestWriter::Delegate {
+ public:
+  explicit ServerDelegate(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  ~ServerDelegate() override = default;
+  void OnCanWrite() override { dispatcher_->OnCanWrite(); }
+
+ private:
+  QuicDispatcher* dispatcher_;
+};
+
+class ClientDelegate : public PacketDroppingTestWriter::Delegate {
+ public:
+  explicit ClientDelegate(QuicClient* client) : client_(client) {}
+  ~ClientDelegate() override = default;
+  void OnCanWrite() override {
+    QuicEpollEvent event(EPOLLOUT);
+    client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
+  }
+
+ private:
+  QuicClient* client_;
+};
+
+class EndToEndTest : public QuicTestWithParam<TestParams> {
+ protected:
+  EndToEndTest()
+      : initialized_(false),
+        connect_to_server_on_initialize_(true),
+        server_address_(QuicSocketAddress(TestLoopback(), 0)),
+        server_hostname_("test.example.com"),
+        client_writer_(nullptr),
+        server_writer_(nullptr),
+        version_(GetParam().version),
+        client_supported_versions_({version_}),
+        server_supported_versions_(CurrentSupportedVersions()),
+        chlo_multiplier_(0),
+        stream_factory_(nullptr),
+        expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
+    QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
+
+    // Use different flow control windows for client/server.
+    client_config_.SetInitialStreamFlowControlWindowToSend(
+        2 * kInitialStreamFlowControlWindowForTest);
+    client_config_.SetInitialSessionFlowControlWindowToSend(
+        2 * kInitialSessionFlowControlWindowForTest);
+    server_config_.SetInitialStreamFlowControlWindowToSend(
+        3 * kInitialStreamFlowControlWindowForTest);
+    server_config_.SetInitialSessionFlowControlWindowToSend(
+        3 * kInitialSessionFlowControlWindowForTest);
+
+    // The default idle timeouts can be too strict when running on a busy
+    // machine.
+    const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
+    client_config_.set_max_time_before_crypto_handshake(timeout);
+    client_config_.set_max_idle_time_before_crypto_handshake(timeout);
+    server_config_.set_max_time_before_crypto_handshake(timeout);
+    server_config_.set_max_idle_time_before_crypto_handshake(timeout);
+
+    AddToCache("/foo", 200, kFooResponseBody);
+    AddToCache("/bar", 200, kBarResponseBody);
+    // Enable fixes for bugs found in tests and prod.
+  }
+
+  virtual void CreateClientWithWriter() {
+    client_.reset(CreateQuicClient(client_writer_));
+  }
+
+  QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
+    QuicTestClient* client =
+        new QuicTestClient(server_address_, server_hostname_, client_config_,
+                           client_supported_versions_,
+                           crypto_test_utils::ProofVerifierForTesting(),
+                           std::make_unique<QuicClientSessionCache>());
+    client->SetUserAgentID(kTestUserAgentId);
+    client->UseWriter(writer);
+    if (!pre_shared_key_client_.empty()) {
+      client->client()->SetPreSharedKey(pre_shared_key_client_);
+    }
+    client->UseConnectionIdLength(override_server_connection_id_length_);
+    client->UseClientConnectionIdLength(override_client_connection_id_length_);
+    client->client()->set_connection_debug_visitor(connection_debug_visitor_);
+    client->client()->set_enable_web_transport(enable_web_transport_);
+    client->client()->set_use_datagram_contexts(use_datagram_contexts_);
+    client->Connect();
+    return client;
+  }
+
+  void set_smaller_flow_control_receive_window() {
+    const uint32_t kClientIFCW = 64 * 1024;
+    const uint32_t kServerIFCW = 1024 * 1024;
+    set_client_initial_stream_flow_control_receive_window(kClientIFCW);
+    set_client_initial_session_flow_control_receive_window(
+        kSessionToStreamRatio * kClientIFCW);
+    set_server_initial_stream_flow_control_receive_window(kServerIFCW);
+    set_server_initial_session_flow_control_receive_window(
+        kSessionToStreamRatio * kServerIFCW);
+  }
+
+  void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
+                    << window;
+    client_config_.SetInitialStreamFlowControlWindowToSend(window);
+  }
+
+  void set_client_initial_session_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
+                    << window;
+    client_config_.SetInitialSessionFlowControlWindowToSend(window);
+  }
+
+  void set_client_initial_max_stream_data_incoming_bidirectional(
+      uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO)
+        << "Setting client initial max stream data incoming bidirectional: "
+        << window;
+    client_config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+        window);
+  }
+
+  void set_server_initial_max_stream_data_outgoing_bidirectional(
+      uint32_t window) {
+    ASSERT_TRUE(client_ == nullptr);
+    QUIC_DLOG(INFO)
+        << "Setting server initial max stream data outgoing bidirectional: "
+        << window;
+    server_config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+        window);
+  }
+
+  void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(server_thread_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
+                    << window;
+    server_config_.SetInitialStreamFlowControlWindowToSend(window);
+  }
+
+  void set_server_initial_session_flow_control_receive_window(uint32_t window) {
+    ASSERT_TRUE(server_thread_ == nullptr);
+    QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
+                    << window;
+    server_config_.SetInitialSessionFlowControlWindowToSend(window);
+  }
+
+  const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
+    QuicConnection* server_connection = GetServerConnection();
+    if (server_connection == nullptr) {
+      ADD_FAILURE() << "Missing server connection";
+      return nullptr;
+    }
+    return &server_connection->sent_packet_manager();
+  }
+
+  const QuicSentPacketManager* GetSentPacketManagerFromClientSession() {
+    QuicConnection* client_connection = GetClientConnection();
+    if (client_connection == nullptr) {
+      ADD_FAILURE() << "Missing client connection";
+      return nullptr;
+    }
+    return &client_connection->sent_packet_manager();
+  }
+
+  QuicSpdyClientSession* GetClientSession() {
+    if (!client_) {
+      ADD_FAILURE() << "Missing QuicTestClient";
+      return nullptr;
+    }
+    if (client_->client() == nullptr) {
+      ADD_FAILURE() << "Missing MockableQuicClient";
+      return nullptr;
+    }
+    return client_->client()->client_session();
+  }
+
+  QuicConnection* GetClientConnection() {
+    QuicSpdyClientSession* client_session = GetClientSession();
+    if (client_session == nullptr) {
+      ADD_FAILURE() << "Missing client session";
+      return nullptr;
+    }
+    return client_session->connection();
+  }
+
+  QuicConnection* GetServerConnection() {
+    QuicSpdySession* server_session = GetServerSession();
+    if (server_session == nullptr) {
+      ADD_FAILURE() << "Missing server session";
+      return nullptr;
+    }
+    return server_session->connection();
+  }
+
+  QuicSpdySession* GetServerSession() {
+    if (!server_thread_) {
+      ADD_FAILURE() << "Missing server thread";
+      return nullptr;
+    }
+    QuicServer* quic_server = server_thread_->server();
+    if (quic_server == nullptr) {
+      ADD_FAILURE() << "Missing server";
+      return nullptr;
+    }
+    QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(quic_server);
+    if (dispatcher == nullptr) {
+      ADD_FAILURE() << "Missing dispatcher";
+      return nullptr;
+    }
+    if (dispatcher->NumSessions() == 0) {
+      ADD_FAILURE() << "Empty dispatcher session map";
+      return nullptr;
+    }
+    EXPECT_EQ(1u, dispatcher->NumSessions());
+    return static_cast<QuicSpdySession*>(
+        QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher));
+  }
+
+  bool Initialize() {
+    if (enable_web_transport_) {
+      memory_cache_backend_.set_enable_webtransport(true);
+    }
+    if (use_datagram_contexts_) {
+      memory_cache_backend_.set_use_datagram_contexts(true);
+    }
+
+    QuicTagVector copt;
+    server_config_.SetConnectionOptionsToSend(copt);
+    copt = client_extra_copts_;
+
+    // TODO(nimia): Consider setting the congestion control algorithm for the
+    // client as well according to the test parameter.
+    copt.push_back(GetParam().congestion_control_tag);
+    copt.push_back(k2PTO);
+    if (version_.HasIetfQuicFrames()) {
+      copt.push_back(kILD0);
+    }
+    copt.push_back(kPLE1);
+    if (!GetQuicReloadableFlag(
+            quic_remove_connection_migration_connection_option)) {
+      copt.push_back(kRVCM);
+    }
+    client_config_.SetConnectionOptionsToSend(copt);
+
+    // Start the server first, because CreateQuicClient() attempts
+    // to connect to the server.
+    StartServer();
+
+    if (!connect_to_server_on_initialize_) {
+      initialized_ = true;
+      return true;
+    }
+
+    CreateClientWithWriter();
+    if (!client_) {
+      ADD_FAILURE() << "Missing QuicTestClient";
+      return false;
+    }
+    MockableQuicClient* client = client_->client();
+    if (client == nullptr) {
+      ADD_FAILURE() << "Missing MockableQuicClient";
+      return false;
+    }
+    static QuicEpollEvent event(EPOLLOUT);
+    if (client_writer_ != nullptr) {
+      QuicConnection* client_connection = GetClientConnection();
+      if (client_connection == nullptr) {
+        ADD_FAILURE() << "Missing client connection";
+        return false;
+      }
+      client_writer_->Initialize(
+          QuicConnectionPeer::GetHelper(client_connection),
+          QuicConnectionPeer::GetAlarmFactory(client_connection),
+          std::make_unique<ClientDelegate>(client));
+    }
+    initialized_ = true;
+    return client->connected();
+  }
+
+  void SetUp() override {
+    // The ownership of these gets transferred to the QuicPacketWriterWrapper
+    // when Initialize() is executed.
+    client_writer_ = new PacketDroppingTestWriter();
+    server_writer_ = new PacketDroppingTestWriter();
+  }
+
+  void TearDown() override {
+    EXPECT_TRUE(initialized_) << "You must call Initialize() in every test "
+                              << "case. Otherwise, your test will leak memory.";
+    QuicConnection* client_connection = GetClientConnection();
+    if (client_connection != nullptr) {
+      client_connection->set_debug_visitor(nullptr);
+    } else {
+      ADD_FAILURE() << "Missing client connection";
+    }
+    StopServer();
+  }
+
+  void StartServer() {
+    auto* test_server = new QuicTestServer(
+        crypto_test_utils::ProofSourceForTesting(), server_config_,
+        server_supported_versions_, &memory_cache_backend_,
+        expected_server_connection_id_length_);
+    server_thread_ =
+        std::make_unique<ServerThread>(test_server, server_address_);
+    if (chlo_multiplier_ != 0) {
+      server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
+    }
+    if (!pre_shared_key_server_.empty()) {
+      server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
+    }
+    server_thread_->Initialize();
+    server_address_ =
+        QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
+    QuicDispatcher* dispatcher =
+        QuicServerPeer::GetDispatcher(server_thread_->server());
+    QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
+
+    server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
+                               QuicDispatcherPeer::GetAlarmFactory(dispatcher),
+                               std::make_unique<ServerDelegate>(dispatcher));
+    if (stream_factory_ != nullptr) {
+      static_cast<QuicTestServer*>(server_thread_->server())
+          ->SetSpdyStreamFactory(stream_factory_);
+    }
+
+    server_thread_->Start();
+  }
+
+  void StopServer() {
+    if (server_thread_) {
+      server_thread_->Quit();
+      server_thread_->Join();
+    }
+  }
+
+  void AddToCache(absl::string_view path, int response_code,
+                  absl::string_view body) {
+    memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
+                                            response_code, body);
+  }
+
+  void SetPacketLossPercentage(int32_t loss) {
+    client_writer_->set_fake_packet_loss_percentage(loss);
+    server_writer_->set_fake_packet_loss_percentage(loss);
+  }
+
+  void SetPacketSendDelay(QuicTime::Delta delay) {
+    client_writer_->set_fake_packet_delay(delay);
+    server_writer_->set_fake_packet_delay(delay);
+  }
+
+  void SetReorderPercentage(int32_t reorder) {
+    client_writer_->set_fake_reorder_percentage(reorder);
+    server_writer_->set_fake_reorder_percentage(reorder);
+  }
+
+  // Verifies that the client and server connections were both free of packets
+  // being discarded, based on connection stats.
+  // Calls server_thread_ Pause() and Resume(), which may only be called once
+  // per test.
+  void VerifyCleanConnection(bool had_packet_loss) {
+    QuicConnection* client_connection = GetClientConnection();
+    if (client_connection == nullptr) {
+      ADD_FAILURE() << "Missing client connection";
+      return;
+    }
+    QuicConnectionStats client_stats = client_connection->GetStats();
+    // TODO(ianswett): Determine why this becomes even more flaky with BBR
+    // enabled.  b/62141144
+    if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
+      EXPECT_EQ(0u, client_stats.packets_lost);
+    }
+    EXPECT_EQ(0u, client_stats.packets_discarded);
+    // When client starts with an unsupported version, the version negotiation
+    // packet sent by server for the old connection (respond for the connection
+    // close packet) will be dropped by the client.
+    if (!ServerSendsVersionNegotiation()) {
+      EXPECT_EQ(0u, client_stats.packets_dropped);
+    }
+    if (!version_.UsesTls()) {
+      // Only enforce this for QUIC crypto because accounting of number of
+      // packets received, processed gets complicated with packets coalescing
+      // and key dropping. For example, a received undecryptable coalesced
+      // packet can be processed later and each sub-packet increases
+      // packets_processed.
+      EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
+    }
+
+    if (!server_thread_) {
+      ADD_FAILURE() << "Missing server thread";
+      return;
+    }
+    server_thread_->Pause();
+    QuicSpdySession* server_session = GetServerSession();
+    if (server_session != nullptr) {
+      QuicConnection* server_connection = server_session->connection();
+      if (server_connection != nullptr) {
+        QuicConnectionStats server_stats = server_connection->GetStats();
+        if (!had_packet_loss) {
+          EXPECT_EQ(0u, server_stats.packets_lost);
+        }
+        EXPECT_EQ(0u, server_stats.packets_discarded);
+      } else {
+        ADD_FAILURE() << "Missing server connection";
+      }
+    } else {
+      ADD_FAILURE() << "Missing server session";
+    }
+    // TODO(ianswett): Restore the check for packets_dropped equals 0.
+    // The expect for packets received is equal to packets processed fails
+    // due to version negotiation packets.
+    server_thread_->Resume();
+  }
+
+  // Returns true when client starts with an unsupported version, and client
+  // closes connection when version negotiation is received.
+  bool ServerSendsVersionNegotiation() {
+    return client_supported_versions_[0] != version_;
+  }
+
+  bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
+    return version.HasIetfInvariantHeader() &&
+           version.handshake_protocol == PROTOCOL_TLS1_3;
+  }
+
+  static void ExpectFlowControlsSynced(QuicSession* client,
+                                       QuicSession* server) {
+    EXPECT_EQ(
+        QuicFlowControllerPeer::SendWindowSize(client->flow_controller()),
+        QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller()));
+    EXPECT_EQ(
+        QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()),
+        QuicFlowControllerPeer::SendWindowSize(server->flow_controller()));
+  }
+
+  static void ExpectFlowControlsSynced(QuicStream* client, QuicStream* server) {
+    EXPECT_EQ(QuicStreamPeer::SendWindowSize(client),
+              QuicStreamPeer::ReceiveWindowSize(server));
+    EXPECT_EQ(QuicStreamPeer::ReceiveWindowSize(client),
+              QuicStreamPeer::SendWindowSize(server));
+  }
+
+  // Must be called before Initialize to have effect.
+  void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
+    stream_factory_ = factory;
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        version_.transport_version, n);
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return GetNthServerInitiatedBidirectionalStreamId(
+        version_.transport_version, n);
+  }
+
+  bool CheckResponseHeaders(QuicTestClient* client,
+                            const std::string& expected_status) {
+    const spdy::SpdyHeaderBlock* response_headers = client->response_headers();
+    auto it = response_headers->find(":status");
+    if (it == response_headers->end()) {
+      ADD_FAILURE() << "Did not find :status header in response";
+      return false;
+    }
+    if (it->second != expected_status) {
+      ADD_FAILURE() << "Got bad :status response: \"" << it->second << "\"";
+      return false;
+    }
+    return true;
+  }
+
+  bool CheckResponseHeaders(QuicTestClient* client) {
+    return CheckResponseHeaders(client, "200");
+  }
+
+  bool CheckResponseHeaders(const std::string& expected_status) {
+    return CheckResponseHeaders(client_.get(), expected_status);
+  }
+
+  bool CheckResponseHeaders() { return CheckResponseHeaders(client_.get()); }
+
+  bool CheckResponse(QuicTestClient* client,
+                     const std::string& received_response,
+                     const std::string& expected_response) {
+    EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
+    EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+
+    if (received_response.empty() && !expected_response.empty()) {
+      ADD_FAILURE() << "Failed to get any response for request";
+      return false;
+    }
+    if (received_response != expected_response) {
+      ADD_FAILURE() << "Got wrong response: \"" << received_response << "\"";
+      return false;
+    }
+    return CheckResponseHeaders(client);
+  }
+
+  bool SendSynchronousRequestAndCheckResponse(
+      QuicTestClient* client, const std::string& request,
+      const std::string& expected_response) {
+    std::string received_response = client->SendSynchronousRequest(request);
+    return CheckResponse(client, received_response, expected_response);
+  }
+
+  bool SendSynchronousRequestAndCheckResponse(
+      const std::string& request, const std::string& expected_response) {
+    return SendSynchronousRequestAndCheckResponse(client_.get(), request,
+                                                  expected_response);
+  }
+
+  bool SendSynchronousFooRequestAndCheckResponse(QuicTestClient* client) {
+    return SendSynchronousRequestAndCheckResponse(client, "/foo",
+                                                  kFooResponseBody);
+  }
+
+  bool SendSynchronousFooRequestAndCheckResponse() {
+    return SendSynchronousFooRequestAndCheckResponse(client_.get());
+  }
+
+  bool SendSynchronousBarRequestAndCheckResponse() {
+    std::string received_response = client_->SendSynchronousRequest("/bar");
+    return CheckResponse(client_.get(), received_response, kBarResponseBody);
+  }
+
+  bool WaitForFooResponseAndCheckIt(QuicTestClient* client) {
+    client->WaitForResponse();
+    std::string received_response = client->response_body();
+    return CheckResponse(client_.get(), received_response, kFooResponseBody);
+  }
+
+  bool WaitForFooResponseAndCheckIt() {
+    return WaitForFooResponseAndCheckIt(client_.get());
+  }
+
+  WebTransportHttp3* CreateWebTransportSession(
+      const std::string& path, bool wait_for_server_response,
+      QuicSpdyStream** connect_stream_out = nullptr) {
+    // Wait until we receive the settings from the server indicating
+    // WebTransport support.
+    client_->WaitUntil(
+        2000, [this]() { return GetClientSession()->SupportsWebTransport(); });
+    if (!GetClientSession()->SupportsWebTransport()) {
+      return nullptr;
+    }
+
+    spdy::SpdyHeaderBlock headers;
+    headers[":scheme"] = "https";
+    headers[":authority"] = "localhost";
+    headers[":path"] = path;
+    headers[":method"] = "CONNECT";
+    headers[":protocol"] = "webtransport";
+
+    client_->SendMessage(headers, "", /*fin=*/false);
+    QuicSpdyStream* stream = client_->latest_created_stream();
+    if (stream->web_transport() == nullptr) {
+      return nullptr;
+    }
+    WebTransportSessionId id = client_->latest_created_stream()->id();
+    QuicSpdySession* client_session = GetClientSession();
+    if (client_session->GetWebTransportSession(id) == nullptr) {
+      return nullptr;
+    }
+    WebTransportHttp3* session = client_session->GetWebTransportSession(id);
+    if (wait_for_server_response) {
+      client_->WaitUntil(-1,
+                         [stream]() { return stream->headers_decompressed(); });
+      EXPECT_TRUE(session->ready());
+    }
+    if (connect_stream_out != nullptr) {
+      *connect_stream_out = stream;
+    }
+    return session;
+  }
+
+  NiceMock<MockClientVisitor>& SetupWebTransportVisitor(
+      WebTransportHttp3* session) {
+    auto visitor_owned = std::make_unique<NiceMock<MockClientVisitor>>();
+    NiceMock<MockClientVisitor>& visitor = *visitor_owned;
+    session->SetVisitor(std::move(visitor_owned));
+    return visitor;
+  }
+
+  std::string ReadDataFromWebTransportStreamUntilFin(
+      WebTransportStream* stream, MockStreamVisitor* visitor = nullptr) {
+    QuicStreamId id = stream->GetStreamId();
+    std::string buffer;
+
+    // Try reading data if immediately available.
+    WebTransportStream::ReadResult result = stream->Read(&buffer);
+    if (result.fin) {
+      return buffer;
+    }
+
+    while (true) {
+      bool can_read = false;
+      if (visitor == nullptr) {
+        auto visitor_owned = std::make_unique<MockStreamVisitor>();
+        visitor = visitor_owned.get();
+        stream->SetVisitor(std::move(visitor_owned));
+      }
+      EXPECT_CALL(*visitor, OnCanRead()).WillOnce(Assign(&can_read, true));
+      client_->WaitUntil(5000 /*ms*/, [&can_read]() { return can_read; });
+      if (!can_read) {
+        ADD_FAILURE() << "Waiting for readable data on stream " << id
+                      << " timed out";
+        return buffer;
+      }
+      if (GetClientSession()->GetOrCreateSpdyDataStream(id) == nullptr) {
+        ADD_FAILURE() << "Stream " << id
+                      << " was deleted while waiting for incoming data";
+        return buffer;
+      }
+
+      result = stream->Read(&buffer);
+      if (result.fin) {
+        return buffer;
+      }
+      if (result.bytes_read == 0) {
+        ADD_FAILURE() << "No progress made while reading from stream "
+                      << stream->GetStreamId();
+        return buffer;
+      }
+    }
+  }
+
+  void ReadAllIncomingWebTransportUnidirectionalStreams(
+      WebTransportSession* session) {
+    while (true) {
+      WebTransportStream* received_stream =
+          session->AcceptIncomingUnidirectionalStream();
+      if (received_stream == nullptr) {
+        break;
+      }
+      received_webtransport_unidirectional_streams_.push_back(
+          ReadDataFromWebTransportStreamUntilFin(received_stream));
+    }
+  }
+
+  void WaitForNewConnectionIds() {
+    // Wait until a new server CID is available for another migration.
+    const auto* client_connection = GetClientConnection();
+    while (!QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
+               client_connection) ||
+           (!client_connection->client_connection_id().IsEmpty() &&
+            !QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
+                client_connection))) {
+      client_->client()->WaitForEvents();
+    }
+  }
+
+  ScopedEnvironmentForThreads environment_;
+  bool initialized_;
+  // If true, the Initialize() function will create |client_| and starts to
+  // connect to the server.
+  // Default is true.
+  bool connect_to_server_on_initialize_;
+  QuicSocketAddress server_address_;
+  std::string server_hostname_;
+  QuicTestBackend memory_cache_backend_;
+  std::unique_ptr<ServerThread> server_thread_;
+  std::unique_ptr<QuicTestClient> client_;
+  QuicConnectionDebugVisitor* connection_debug_visitor_ = nullptr;
+  PacketDroppingTestWriter* client_writer_;
+  PacketDroppingTestWriter* server_writer_;
+  QuicConfig client_config_;
+  QuicConfig server_config_;
+  ParsedQuicVersion version_;
+  ParsedQuicVersionVector client_supported_versions_;
+  ParsedQuicVersionVector server_supported_versions_;
+  QuicTagVector client_extra_copts_;
+  size_t chlo_multiplier_;
+  QuicTestServer::StreamFactory* stream_factory_;
+  std::string pre_shared_key_client_;
+  std::string pre_shared_key_server_;
+  int override_server_connection_id_length_ = -1;
+  int override_client_connection_id_length_ = -1;
+  uint8_t expected_server_connection_id_length_;
+  bool enable_web_transport_ = false;
+  bool use_datagram_contexts_ = false;
+  std::vector<std::string> received_webtransport_unidirectional_streams_;
+};
+
+// Run all end to end tests with all supported versions.
+INSTANTIATE_TEST_SUITE_P(EndToEndTests, EndToEndTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(EndToEndTest, HandshakeSuccessful) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicCryptoStream* client_crypto_stream =
+      QuicSessionPeer::GetMutableCryptoStream(client_session);
+  ASSERT_TRUE(client_crypto_stream);
+  QuicStreamSequencer* client_sequencer =
+      QuicStreamPeer::sequencer(client_crypto_stream);
+  ASSERT_TRUE(client_sequencer);
+  EXPECT_FALSE(
+      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(client_sequencer));
+
+  // We've had bugs in the past where the connections could end up on the wrong
+  // version. This was never diagnosed but could have been due to in-connection
+  // version negotiation back when that existed. At this point in time, our test
+  // setup ensures that connections here always use |version_|, but we add this
+  // sanity check out of paranoia to catch a regression of this type.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->version(), version_);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicConnection* server_connection = nullptr;
+  QuicCryptoStream* server_crypto_stream = nullptr;
+  QuicStreamSequencer* server_sequencer = nullptr;
+  if (server_session != nullptr) {
+    server_connection = server_session->connection();
+    server_crypto_stream =
+        QuicSessionPeer::GetMutableCryptoStream(server_session);
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  if (server_crypto_stream != nullptr) {
+    server_sequencer = QuicStreamPeer::sequencer(server_crypto_stream);
+  } else {
+    ADD_FAILURE() << "Missing server crypto stream";
+  }
+  if (server_sequencer != nullptr) {
+    EXPECT_FALSE(
+        QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(server_sequencer));
+  } else {
+    ADD_FAILURE() << "Missing server sequencer";
+  }
+  if (server_connection != nullptr) {
+    EXPECT_EQ(server_connection->version(), version_);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ExportKeyingMaterial) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.UsesTls()) {
+    return;
+  }
+  const char* kExportLabel = "label";
+  const int kExportLen = 30;
+  std::string client_keying_material_export, server_keying_material_export;
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicCryptoStream* server_crypto_stream = nullptr;
+  if (server_session != nullptr) {
+    server_crypto_stream =
+        QuicSessionPeer::GetMutableCryptoStream(server_session);
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  if (server_crypto_stream != nullptr) {
+    ASSERT_TRUE(server_crypto_stream->ExportKeyingMaterial(
+        kExportLabel, /*context=*/"", kExportLen,
+        &server_keying_material_export));
+
+  } else {
+    ADD_FAILURE() << "Missing server crypto stream";
+  }
+  server_thread_->Resume();
+
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicCryptoStream* client_crypto_stream =
+      QuicSessionPeer::GetMutableCryptoStream(client_session);
+  ASSERT_TRUE(client_crypto_stream);
+  ASSERT_TRUE(client_crypto_stream->ExportKeyingMaterial(
+      kExportLabel, /*context=*/"", kExportLen,
+      &client_keying_material_export));
+  ASSERT_EQ(client_keying_material_export.size(),
+            static_cast<size_t>(kExportLen));
+  EXPECT_EQ(client_keying_material_export, server_keying_material_export);
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponse) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  if (version_.UsesHttp3()) {
+    QuicSpdyClientSession* client_session = GetClientSession();
+    ASSERT_TRUE(client_session);
+    EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(client_session));
+    EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(client_session));
+    server_thread_->Pause();
+    QuicSpdySession* server_session = GetServerSession();
+    if (server_session != nullptr) {
+      EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(server_session));
+      EXPECT_TRUE(QuicSpdySessionPeer::GetReceiveControlStream(server_session));
+    } else {
+      ADD_FAILURE() << "Missing server session";
+    }
+    server_thread_->Resume();
+  }
+  QuicConnectionStats client_stats = GetClientConnection()->GetStats();
+  EXPECT_TRUE(client_stats.handshake_completion_time.IsInitialized());
+}
+
+TEST_P(EndToEndTest, HandshakeConfirmed) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.UsesTls()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+  // Verify handshake state.
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(HANDSHAKE_CONFIRMED, client_session->GetHandshakeState());
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_session->GetHandshakeState());
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+  client_->Disconnect();
+}
+
+TEST_P(EndToEndTest, SendAndReceiveCoalescedPackets) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.CanSendCoalescedPackets()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+  // Verify client successfully processes coalesced packets.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionStats client_stats = client_connection->GetStats();
+  EXPECT_LT(0u, client_stats.num_coalesced_packets_received);
+  EXPECT_EQ(client_stats.num_coalesced_packets_processed,
+            client_stats.num_coalesced_packets_received);
+  // TODO(fayang): verify server successfully processes coalesced packets.
+}
+
+// Simple transaction, but set a non-default ack delay at the client
+// and ensure it gets to the server.
+TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
+  // Force the ACK delay to be something other than the default.
+  constexpr uint32_t kClientMaxAckDelay = kDefaultDelayedAckTimeMs + 100u;
+  client_config_.SetMaxAckDelayToSendMs(kClientMaxAckDelay);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  server_thread_->Pause();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(
+        kClientMaxAckDelay,
+        server_sent_packet_manager->peer_max_ack_delay().ToMilliseconds());
+  } else {
+    ADD_FAILURE() << "Missing server sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+// Simple transaction, but set a non-default ack exponent at the client
+// and ensure it gets to the server.
+TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
+  const uint32_t kClientAckDelayExponent = 19;
+  EXPECT_NE(kClientAckDelayExponent, kDefaultAckDelayExponent);
+  // Force the ACK exponent to be something other than the default.
+  // Note that it is sent only with QUIC+TLS.
+  client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    if (version_.UsesTls()) {
+      // Should be only sent with QUIC+TLS.
+      EXPECT_EQ(kClientAckDelayExponent,
+                server_connection->framer().peer_ack_delay_exponent());
+    } else {
+      // No change for QUIC_CRYPTO.
+      EXPECT_EQ(kDefaultAckDelayExponent,
+                server_connection->framer().peer_ack_delay_exponent());
+    }
+    // No change, regardless of version.
+    EXPECT_EQ(kDefaultAckDelayExponent,
+              server_connection->framer().local_ack_delay_exponent());
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  EXPECT_CALL(visitor, OnVersionNegotiationPacket(_)).Times(1);
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiation) {
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 0;
+  expected_server_connection_id_length_ = 0;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->connection_id(),
+            QuicUtils::CreateZeroConnectionId(version_.transport_version));
+}
+
+TEST_P(EndToEndTest, ZeroConnectionID) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 0;
+  expected_server_connection_id_length_ = 0;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->connection_id(),
+            QuicUtils::CreateZeroConnectionId(version_.transport_version));
+}
+
+TEST_P(EndToEndTest, BadConnectionIdLength) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 9;
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+// Tests a very long (16-byte) initial destination connection ID to make
+// sure the dispatcher properly replaces it with an 8-byte one.
+TEST_P(EndToEndTest, LongBadConnectionIdLength) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 16;
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+TEST_P(EndToEndTest, ClientConnectionId) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(override_client_connection_id_length_, client_->client()
+                                                       ->client_session()
+                                                       ->connection()
+                                                       ->client_connection_id()
+                                                       .length());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(override_client_connection_id_length_, client_->client()
+                                                       ->client_session()
+                                                       ->connection()
+                                                       ->client_connection_id()
+                                                       .length());
+}
+
+TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  override_server_connection_id_length_ = 9;
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+// Forced Version Negotiation with a client connection ID and a long
+// connection ID.
+TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
+  if (!version_.SupportsClientConnectionIds() ||
+      !version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  override_server_connection_id_length_ = 16;
+  override_client_connection_id_length_ = 18;
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(ServerSendsVersionNegotiation());
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+  EXPECT_EQ(override_client_connection_id_length_, client_->client()
+                                                       ->client_session()
+                                                       ->connection()
+                                                       ->client_connection_id()
+                                                       .length());
+}
+
+TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  // Start client_ which will use a bad connection ID length.
+  override_server_connection_id_length_ = 9;
+  ASSERT_TRUE(Initialize());
+  override_server_connection_id_length_ = -1;
+
+  // Start client2 which will use a good connection ID length.
+  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+  client2->SendMessage(headers, "", /*fin=*/false);
+  client2->SendData("eep", true);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+
+  WaitForFooResponseAndCheckIt(client2.get());
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
+                                                ->client_session()
+                                                ->connection()
+                                                ->connection_id()
+                                                .length());
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseWithIetfDraftSupport) {
+  if (!version_.HasIetfQuicFrames()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  QuicVersionInitializeSupportForIetfDraft();
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
+  chlo_multiplier_ = 1;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  if (version_.UsesTls()) {
+    // REJ messages are a QUIC crypto feature, so TLS always returns false.
+    EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  } else {
+    EXPECT_TRUE(client_->client()->ReceivedInchoateReject());
+  }
+}
+
+TEST_P(EndToEndTest, SimpleRequestResponsev6) {
+  server_address_ =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest,
+       ClientDoesNotAllowServerDataOnServerInitiatedBidirectionalStreams) {
+  set_client_initial_max_stream_data_incoming_bidirectional(0);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest,
+       ServerDoesNotAllowClientDataOnServerInitiatedBidirectionalStreams) {
+  set_server_initial_max_stream_data_outgoing_bidirectional(0);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest,
+       BothEndpointsDisallowDataOnServerInitiatedBidirectionalStreams) {
+  set_client_initial_max_stream_data_incoming_bidirectional(0);
+  set_server_initial_max_stream_data_outgoing_bidirectional(0);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// Regression test for a bug where we would always fail to decrypt the first
+// initial packet. Undecryptable packets can be seen after the handshake
+// is complete due to dropping the initial keys at that point, so we only test
+// for undecryptable packets before then.
+TEST_P(EndToEndTest, NoUndecryptablePacketsBeforeHandshakeComplete) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionStats client_stats = client_connection->GetStats();
+  EXPECT_EQ(
+      0u,
+      client_stats.undecryptable_packets_received_before_handshake_complete);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(
+        0u,
+        server_stats.undecryptable_packets_received_before_handshake_complete);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, SeparateFinPacket) {
+  ASSERT_TRUE(Initialize());
+
+  // Send a request in two parts: the request and then an empty packet with FIN.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->SendData("", true);
+  WaitForFooResponseAndCheckIt();
+
+  // Now do the same thing but with a content length.
+  headers["content-length"] = "3";
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->SendData("foo", true);
+  WaitForFooResponseAndCheckIt();
+}
+
+TEST_P(EndToEndTest, MultipleRequestResponse) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  SendSynchronousBarRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_server_connection_id_length_ = 0;
+  expected_server_connection_id_length_ = 0;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  SendSynchronousBarRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, MultipleStreams) {
+  // Verifies quic_test_client can track responses of all active streams.
+  ASSERT_TRUE(Initialize());
+
+  const int kNumRequests = 10;
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  for (int i = 0; i < kNumRequests; ++i) {
+    client_->SendMessage(headers, "bar", /*fin=*/true);
+  }
+
+  while (kNumRequests > client_->num_responses()) {
+    client_->ClearPerRequestState();
+    ASSERT_TRUE(WaitForFooResponseAndCheckIt());
+  }
+}
+
+TEST_P(EndToEndTest, MultipleClients) {
+  ASSERT_TRUE(Initialize());
+  std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client2->SendMessage(headers, "", /*fin=*/false);
+
+  client_->SendData("bar", true);
+  WaitForFooResponseAndCheckIt();
+
+  client2->SendData("eep", true);
+  WaitForFooResponseAndCheckIt(client2.get());
+}
+
+TEST_P(EndToEndTest, RequestOverMultiplePackets) {
+  // Send a large enough request to guarantee fragmentation.
+  std::string huge_request =
+      "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
+  AddToCache(huge_request, 200, kBarResponseBody);
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
+}
+
+TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
+  // Send a large enough request to guarantee fragmentation.
+  std::string huge_request =
+      "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
+  AddToCache(huge_request, 200, kBarResponseBody);
+
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(50);
+
+  SendSynchronousRequestAndCheckResponse(huge_request, kBarResponseBody);
+}
+
+TEST_P(EndToEndTest, PostMissingBytes) {
+  ASSERT_TRUE(Initialize());
+
+  // Add a content length header with no body.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  // This should be detected as stream fin without complete request,
+  // triggering an error response.
+  client_->SendCustomSynchronousRequest(headers, "");
+  EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
+            client_->response_body());
+  CheckResponseHeaders("500");
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLoss) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // TODO(ianswett): There should not be packet loss in this test, but on some
+  // platforms the receive buffer overflows.
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // 100 KB body.
+  std::string body(100 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, LargePostWithPacketLoss) {
+  // Connect with lower fake packet loss than we'd like to test.
+  // Until b/10126687 is fixed, losing handshake packets is pretty
+  // brutal.
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  SetPacketLossPercentage(5);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+
+  // 10 KB body.
+  std::string body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(true);
+}
+
+// Regression test for b/80090281.
+TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Normally server only bundles a retransmittable frame once every other
+  // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
+  // to 0 to reliably reproduce b/80090281.
+  server_thread_->Schedule([this]() {
+    QuicConnection* server_connection = GetServerConnection();
+    if (server_connection != nullptr) {
+      QuicConnectionPeer::
+          SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
+              server_connection, 0);
+    } else {
+      ADD_FAILURE() << "Missing server connection";
+    }
+  });
+
+  SetPacketLossPercentage(30);
+
+  // 10 KB body.
+  std::string body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
+  // Connect with lower fake packet loss than we'd like to test.  Until
+  // b/10126687 is fixed, losing handshake packets is pretty brutal.
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  SetPacketLossPercentage(5);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(10);
+  client_writer_->set_fake_blocked_socket_percentage(10);
+
+  // 10 KB body.
+  std::string body(1024 * 10, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+}
+
+TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  // Both of these must be called when the writer is not actively used.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+}
+
+TEST_P(EndToEndTest, AddressToken) {
+  client_extra_copts_.push_back(kTRTT);
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames()) {
+    return;
+  }
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  ASSERT_TRUE(client_->client()->connected());
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_session != nullptr && server_connection != nullptr) {
+    // Verify address is validated via validating token received in INITIAL
+    // packet.
+    EXPECT_FALSE(
+        server_connection->GetStats().address_validated_via_decrypting_packet);
+    EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
+
+    // Verify the server received a cached min_rtt from the token and used it as
+    // the initial rtt.
+    const CachedNetworkParameters* server_received_network_params =
+        static_cast<const QuicCryptoServerStreamBase*>(
+            server_session->GetCryptoStream())
+            ->PreviousCachedNetworkParams();
+
+    ASSERT_NE(server_received_network_params, nullptr);
+    // QuicSentPacketManager::SetInitialRtt clamps the initial_rtt to between
+    // [min_initial_rtt, max_initial_rtt].
+    const QuicTime::Delta min_initial_rtt =
+        server_connection->sent_packet_manager().use_lower_min_irtt()
+            ? QuicTime::Delta::FromMicroseconds(
+                  kMinTrustedInitialRoundTripTimeUs)
+            : QuicTime::Delta::FromMicroseconds(
+                  kMinUntrustedInitialRoundTripTimeUs);
+    const QuicTime::Delta max_initial_rtt =
+        QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
+    const QuicTime::Delta expected_initial_rtt =
+        std::max(min_initial_rtt,
+                 std::min(max_initial_rtt,
+                          QuicTime::Delta::FromMilliseconds(
+                              server_received_network_params->min_rtt_ms())));
+    EXPECT_EQ(
+        server_connection->sent_packet_manager().GetRttStats()->initial_rtt(),
+        expected_initial_rtt);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+
+  server_thread_->Resume();
+
+  client_->Disconnect();
+
+  // Regression test for b/206087883.
+  // Mock server crash.
+  StopServer();
+
+  // The handshake fails due to idle timeout.
+  client_->Connect();
+  ASSERT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_FALSE(client_->client()->connected());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_NETWORK_IDLE_TIMEOUT));
+
+  // Server restarts.
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  // Client re-connect.
+  client_->Connect();
+  ASSERT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_TRUE(client_->client()->connected());
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  server_thread_->Pause();
+  server_session = GetServerSession();
+  server_connection = GetServerConnection();
+  // Verify address token is only used once.
+  if (server_session != nullptr && server_connection != nullptr) {
+    // Verify address is validated via decrypting packet.
+    EXPECT_TRUE(
+        server_connection->GetStats().address_validated_via_decrypting_packet);
+    EXPECT_FALSE(server_connection->GetStats().address_validated_via_token);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+
+  client_->Disconnect();
+}
+
+// Verify that client does not reuse a source address token.
+TEST_P(EndToEndTest, AddressTokenNotReusedByClient) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames()) {
+    return;
+  }
+
+  QuicCryptoClientConfig* client_crypto_config =
+      client_->client()->crypto_config();
+  QuicServerId server_id = client_->client()->server_id();
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  QuicClientSessionCache* session_cache = static_cast<QuicClientSessionCache*>(
+      client_crypto_config->mutable_session_cache());
+  ASSERT_TRUE(
+      !QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
+
+  // Pause the server thread again to blackhole packets from client.
+  server_thread_->Pause();
+  client_->Connect();
+  EXPECT_FALSE(client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_FALSE(client_->client()->connected());
+
+  // Verify address token gets cleared.
+  ASSERT_TRUE(
+      QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  std::string body(20480, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+  VerifyCleanConnection(false);
+}
+
+// Regression test for b/168020146.
+TEST_P(EndToEndTest, MultipleZeroRtt) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+}
+
+TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  VerifyCleanConnection(false);
+}
+
+TEST_P(EndToEndTest, LargePostSynchronousRequest) {
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  ASSERT_TRUE(Initialize());
+
+  std::string body(20480, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  VerifyCleanConnection(false);
+}
+
+// This is a regression test for b/162595387
+TEST_P(EndToEndTest, PostZeroRTTRequestDuringHandshake) {
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // The 0-RTT handshake should succeed.
+  ON_CALL(visitor, OnCryptoFrame(_))
+      .WillByDefault(Invoke([this](const QuicCryptoFrame& frame) {
+        if (frame.level != ENCRYPTION_HANDSHAKE) {
+          return;
+        }
+        // At this point in the handshake, the client should have derived
+        // ENCRYPTION_ZERO_RTT keys (thus set encryption_established). It
+        // should also have set ENCRYPTION_HANDSHAKE keys after receiving
+        // the server's ENCRYPTION_INITIAL flight.
+        EXPECT_TRUE(
+            GetClientSession()->GetCryptoStream()->encryption_established());
+        EXPECT_TRUE(
+            GetClientConnection()->framer().HasEncrypterOfEncryptionLevel(
+                ENCRYPTION_HANDSHAKE));
+        SpdyHeaderBlock headers;
+        headers[":method"] = "POST";
+        headers[":path"] = "/foo";
+        headers[":scheme"] = "https";
+        headers[":authority"] = server_hostname_;
+        EXPECT_GT(
+            client_->SendMessage(headers, "", /*fin*/ true, /*flush*/ false),
+            0);
+      }));
+  client_->Connect();
+  ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+}
+
+// Regression test for b/166836136.
+TEST_P(EndToEndTest, RetransmissionAfterZeroRTTRejectBeforeOneRtt) {
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Send a request and then disconnect. This prepares the client to attempt
+  // a 0-RTT handshake for the next request.
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  client_->Disconnect();
+
+  // Restart the server so that the 0-RTT handshake will take 1 RTT.
+  StopServer();
+  server_writer_ = new PacketDroppingTestWriter();
+  StartServer();
+
+  ON_CALL(visitor, OnZeroRttRejected(_)).WillByDefault(Invoke([this]() {
+    EXPECT_FALSE(GetClientSession()->IsEncryptionEstablished());
+  }));
+
+  // The 0-RTT handshake should fail.
+  client_->Connect();
+  ASSERT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForWriteToFlush();
+  client_->WaitForResponse();
+  ASSERT_TRUE(client_->client()->connected());
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+}
+
+TEST_P(EndToEndTest, RejectWithPacketLoss) {
+  // In this test, we intentionally drop the first packet from the
+  // server, which corresponds with the initial REJ response from
+  // the server.
+  server_writer_->set_fake_drop_first_n_packets(1);
+  ASSERT_TRUE(Initialize());
+}
+
+TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
+  QuicTagVector initial_received_options;
+  initial_received_options.push_back(kTBBR);
+  initial_received_options.push_back(kIW10);
+  initial_received_options.push_back(kPRST);
+  EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
+      initial_received_options));
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
+      initial_received_options));
+
+  // Verify that server's configuration is correct.
+  server_thread_->Pause();
+  EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
+  EXPECT_TRUE(
+      ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
+}
+
+TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
+  ASSERT_TRUE(Initialize());
+  SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
+  // 256KB per second with a 256KB buffer from server to client.  Wireless
+  // clients commonly have larger buffers, but our max CWND is 200.
+  server_writer_->set_max_bandwidth_and_buffer_size(
+      QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  // This connection may drop packets, because the buffer is smaller than the
+  // max CWND.
+  VerifyCleanConnection(true);
+}
+
+TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
+  // Regression test for b/14677858.
+  // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
+  // if currently connection level flow control blocked. If set, this results in
+  // an infinite loop in the EpollServer, as the alarm fires and is immediately
+  // rescheduled.
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Ensure both stream and connection level are flow control blocked by setting
+  // the send window offset to 0.
+  const uint64_t flow_control_window =
+      server_config_.GetInitialStreamFlowControlWindowToSend();
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  QuicSession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  QuicStreamPeer::SetSendWindowOffset(stream, 0);
+  QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
+  EXPECT_TRUE(stream->IsFlowControlBlocked());
+  EXPECT_TRUE(session->flow_controller()->IsBlocked());
+
+  // Make sure that the stream has data pending so that it will be marked as
+  // write blocked when it receives a stream level WINDOW_UPDATE.
+  stream->WriteOrBufferBody("hello", false);
+
+  // The stream now attempts to write, fails because it is still connection
+  // level flow control blocked, and is added to the write blocked list.
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
+                                      2 * flow_control_window);
+  stream->OnWindowUpdateFrame(window_update);
+
+  // Prior to fixing b/14677858 this call would result in an infinite loop in
+  // Chromium. As a proxy for detecting this, we now check whether the
+  // send alarm is set after OnCanWrite. It should not be, as the
+  // connection is still flow control blocked.
+  session->connection()->OnCanWrite();
+
+  QuicAlarm* send_alarm =
+      QuicConnectionPeer::GetSendAlarm(session->connection());
+  EXPECT_FALSE(send_alarm->IsSet());
+}
+
+TEST_P(EndToEndTest, InvalidStream) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string body(kMaxOutgoingPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  // Force the client to write with a stream ID belonging to a nonexistent
+  // server-side stream.
+  QuicSpdySession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
+      session, GetNthServerInitiatedBidirectionalId(0));
+
+  client_->SendCustomSynchronousRequest(headers, body);
+  EXPECT_THAT(client_->stream_error(),
+              IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_INVALID_STREAM_ID));
+}
+
+// Test that the server resets the stream if the client sends a request
+// with overly large headers.
+TEST_P(EndToEndTest, LargeHeaders) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string body(kMaxOutgoingPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["key1"] = std::string(15 * 1024, 'a');
+  headers["key2"] = std::string(15 * 1024, 'a');
+  headers["key3"] = std::string(15 * 1024, 'a');
+
+  client_->SendCustomSynchronousRequest(headers, body);
+
+  if (version_.UsesHttp3()) {
+    // QuicSpdyStream::OnHeadersTooLarge() resets the stream with
+    // QUIC_HEADERS_TOO_LARGE.  This is sent as H3_EXCESSIVE_LOAD, the closest
+    // HTTP/3 error code, and translated back to QUIC_STREAM_EXCESSIVE_LOAD on
+    // the receiving side.
+    EXPECT_THAT(client_->stream_error(),
+                IsStreamError(QUIC_STREAM_EXCESSIVE_LOAD));
+  } else {
+    EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
+  }
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string large_body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  // Insert an invalid content_length field in request to trigger an early
+  // response from server.
+  headers["content-length"] = "-3";
+
+  client_->SendCustomSynchronousRequest(headers, large_body);
+  EXPECT_EQ("bad", client_->response_body());
+  CheckResponseHeaders("500");
+  EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+// TODO(rch): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
+  ASSERT_TRUE(Initialize());
+
+  // Set the offset so we won't frame.  Otherwise when we pick up termination
+  // before HTTP framing is complete, we send an error and close the stream,
+  // and the second write is picked up as writing on a closed stream.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamPeer::SetStreamBytesWritten(3, stream);
+
+  client_->SendData("bar", true);
+  client_->WaitForWriteToFlush();
+
+  // By default the stream protects itself from writes after terminte is set.
+  // Override this to test the server handling buggy clients.
+  QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
+
+  EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
+}
+
+TEST_P(EndToEndTest, Timeout) {
+  client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500));
+  // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
+  // that's enough to validate timeout in this case.
+  Initialize();
+  while (client_->client()->connected()) {
+    client_->client()->WaitForEvents();
+  }
+}
+
+TEST_P(EndToEndTest, MaxDynamicStreamsLimitRespected) {
+  // Set a limit on maximum number of incoming dynamic streams.
+  // Make sure the limit is respected by the peer.
+  const uint32_t kServerMaxDynamicStreams = 1;
+  server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
+  ASSERT_TRUE(Initialize());
+  if (version_.HasIetfQuicFrames()) {
+    // Do not run this test for /IETF QUIC. This test relies on the fact that
+    // Google QUIC allows a small number of additional streams beyond the
+    // negotiated limit, which is not supported in IETF QUIC. Note that the test
+    // needs to be here, after calling Initialize(), because all tests end up
+    // calling EndToEndTest::TearDown(), which asserts that Initialize has been
+    // called and then proceeds to tear things down -- which fails if they are
+    // not properly set up.
+    return;
+  }
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Make the client misbehave after negotiation.
+  const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicSessionPeer::SetMaxOpenOutgoingStreams(client_session,
+                                             kServerMaxStreams + 1);
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "3";
+
+  // The server supports a small number of additional streams beyond the
+  // negotiated limit. Open enough streams to go beyond that limit.
+  for (int i = 0; i < kServerMaxStreams + 1; ++i) {
+    client_->SendMessage(headers, "", /*fin=*/false);
+  }
+  client_->WaitForResponse();
+
+  EXPECT_TRUE(client_->connected());
+  EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_REFUSED_STREAM));
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) {
+  // Each endpoint can set max dynamic streams independently.
+  const uint32_t kClientMaxDynamicStreams = 4;
+  const uint32_t kServerMaxDynamicStreams = 3;
+  client_config_.SetMaxBidirectionalStreamsToSend(kClientMaxDynamicStreams);
+  server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
+  client_config_.SetMaxUnidirectionalStreamsToSend(kClientMaxDynamicStreams);
+  server_config_.SetMaxUnidirectionalStreamsToSend(kServerMaxDynamicStreams);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // The client has received the server's limit and vice versa.
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  // The value returned by max_allowed... includes the Crypto and Header
+  // stream (created as a part of initialization). The config. values,
+  // above, are treated as "number of requests/responses" - that is, they do
+  // not include the static Crypto and Header streams. Reduce the value
+  // returned by max_allowed... by 2 to remove the static streams from the
+  // count.
+  size_t client_max_open_outgoing_bidirectional_streams =
+      version_.HasIetfQuicFrames()
+          ? QuicSessionPeer::ietf_streamid_manager(client_session)
+                ->max_outgoing_bidirectional_streams()
+          : QuicSessionPeer::GetStreamIdManager(client_session)
+                ->max_open_outgoing_streams();
+  size_t client_max_open_outgoing_unidirectional_streams =
+      version_.HasIetfQuicFrames()
+          ? QuicSessionPeer::ietf_streamid_manager(client_session)
+                    ->max_outgoing_unidirectional_streams() -
+                kHttp3StaticUnidirectionalStreamCount
+          : QuicSessionPeer::GetStreamIdManager(client_session)
+                ->max_open_outgoing_streams();
+  EXPECT_EQ(kServerMaxDynamicStreams,
+            client_max_open_outgoing_bidirectional_streams);
+  EXPECT_EQ(kServerMaxDynamicStreams,
+            client_max_open_outgoing_unidirectional_streams);
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    size_t server_max_open_outgoing_bidirectional_streams =
+        version_.HasIetfQuicFrames()
+            ? QuicSessionPeer::ietf_streamid_manager(server_session)
+                  ->max_outgoing_bidirectional_streams()
+            : QuicSessionPeer::GetStreamIdManager(server_session)
+                  ->max_open_outgoing_streams();
+    size_t server_max_open_outgoing_unidirectional_streams =
+        version_.HasIetfQuicFrames()
+            ? QuicSessionPeer::ietf_streamid_manager(server_session)
+                      ->max_outgoing_unidirectional_streams() -
+                  kHttp3StaticUnidirectionalStreamCount
+            : QuicSessionPeer::GetStreamIdManager(server_session)
+                  ->max_open_outgoing_streams();
+    EXPECT_EQ(kClientMaxDynamicStreams,
+              server_max_open_outgoing_bidirectional_streams);
+    EXPECT_EQ(kClientMaxDynamicStreams,
+              server_max_open_outgoing_unidirectional_streams);
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, NegotiateCongestionControl) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  CongestionControlType expected_congestion_control_type = kRenoBytes;
+  switch (GetParam().congestion_control_tag) {
+    case kRENO:
+      expected_congestion_control_type = kRenoBytes;
+      break;
+    case kTBBR:
+      expected_congestion_control_type = kBBR;
+      break;
+    case kQBIC:
+      expected_congestion_control_type = kCubicBytes;
+      break;
+    case kB2ON:
+      expected_congestion_control_type = kBBRv2;
+      break;
+    default:
+      QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
+  }
+
+  server_thread_->Pause();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(
+        expected_congestion_control_type,
+        QuicSentPacketManagerPeer::GetSendAlgorithm(*server_sent_packet_manager)
+            ->GetCongestionControlType());
+  } else {
+    ADD_FAILURE() << "Missing server sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ClientSuggestsRTT) {
+  // Client suggests initial RTT, verify it is used.
+  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(kInitialRTT,
+              client_sent_packet_manager->GetRttStats()->initial_rtt());
+    EXPECT_EQ(kInitialRTT,
+              server_sent_packet_manager->GetRttStats()->initial_rtt());
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
+  // Client suggests initial RTT, but also specifies NRTT, so it's not used.
+  const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
+  QuicTagVector options;
+  options.push_back(kNRTT);
+  client_config_.SetConnectionOptionsToSend(options);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    EXPECT_EQ(kInitialRTT,
+              client_sent_packet_manager->GetRttStats()->initial_rtt());
+    EXPECT_EQ(kInitialRTT,
+              server_sent_packet_manager->GetRttStats()->initial_rtt());
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+// Regression test for b/171378845
+TEST_P(EndToEndTest, ClientDisablesGQuicZeroRtt) {
+  if (version_.UsesTls()) {
+    // This feature is gQUIC only.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  QuicTagVector options;
+  options.push_back(kQNZ2);
+  client_config_.SetClientConnectionOptions(options);
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_session->ReceivedInchoateReject());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
+
+  client_->Disconnect();
+
+  // Make sure that the request succeeds but 0-RTT was not used.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_FALSE(client_->client()->EarlyDataAccepted());
+}
+
+TEST_P(EndToEndTest, MaxInitialRTT) {
+  // Client tries to suggest twice the server's max initial rtt and the server
+  // uses the max.
+  client_config_.SetInitialRoundTripTimeUsToSend(2 *
+                                                 kMaxInitialRoundTripTimeUs);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(server_thread_);
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    // Now that acks have been exchanged, the RTT estimate has decreased on the
+    // server and is not infinite on the client.
+    EXPECT_FALSE(
+        client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
+    const RttStats* server_rtt_stats =
+        server_sent_packet_manager->GetRttStats();
+    EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
+              server_rtt_stats->initial_rtt().ToMicroseconds());
+    EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
+              server_rtt_stats->smoothed_rtt().ToMicroseconds());
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, MinInitialRTT) {
+  // Client tries to suggest 0 and the server uses the default.
+  client_config_.SetInitialRoundTripTimeUsToSend(0);
+
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  const QuicSentPacketManager* client_sent_packet_manager =
+      GetSentPacketManagerFromClientSession();
+  const QuicSentPacketManager* server_sent_packet_manager =
+      GetSentPacketManagerFromFirstServerSession();
+  if (client_sent_packet_manager != nullptr &&
+      server_sent_packet_manager != nullptr) {
+    // Now that acks have been exchanged, the RTT estimate has decreased on the
+    // server and is not infinite on the client.
+    EXPECT_FALSE(
+        client_sent_packet_manager->GetRttStats()->smoothed_rtt().IsInfinite());
+    // Expect the default rtt of 100ms.
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
+              server_sent_packet_manager->GetRttStats()->initial_rtt());
+    // Ensure the bandwidth is valid.
+    client_sent_packet_manager->BandwidthEstimate();
+    server_sent_packet_manager->BandwidthEstimate();
+  } else {
+    ADD_FAILURE() << "Missing sent packet manager";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, 0ByteConnectionId) {
+  if (version_.HasIetfInvariantHeader()) {
+    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetBytesForConnectionIdToSend(0);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
+}
+
+TEST_P(EndToEndTest, 8ByteConnectionId) {
+  if (version_.HasIetfInvariantHeader()) {
+    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetBytesForConnectionIdToSend(8);
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
+}
+
+TEST_P(EndToEndTest, 15ByteConnectionId) {
+  if (version_.HasIetfInvariantHeader()) {
+    // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetBytesForConnectionIdToSend(15);
+  ASSERT_TRUE(Initialize());
+
+  // Our server is permissive and allows for out of bounds values.
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicPacketHeader* header =
+      QuicConnectionPeer::GetLastHeader(client_connection);
+  EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
+}
+
+TEST_P(EndToEndTest, ResetConnection) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  client_->ResetConnection();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SendSynchronousBarRequestAndCheckResponse();
+}
+
+// Regression test for b/180737158.
+TEST_P(
+    EndToEndTest,
+    HalfRttResponseBlocksShloRetransmissionWithoutTokenBasedAddressValidation) {
+  // Turn off token based address validation to make the server get constrained
+  // by amplification factor during handshake.
+  SetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet, true);
+  ASSERT_TRUE(Initialize());
+  if (!version_.SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  // Perform a full 1-RTT handshake to get the new session ticket such that the
+  // next connection will perform a 0-RTT handshake.
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  client_->Disconnect();
+
+  server_thread_->Pause();
+  // Drop the 1st server packet which is the coalesced INITIAL + HANDSHAKE +
+  // 1RTT.
+  PacketDroppingTestWriter* writer = new PacketDroppingTestWriter();
+  writer->set_fake_drop_first_n_packets(1);
+  QuicDispatcherPeer::UseWriter(
+      QuicServerPeer::GetDispatcher(server_thread_->server()), writer);
+  server_thread_->Resume();
+
+  // Large response (100KB) for 0-RTT request.
+  std::string large_body(102400, 'a');
+  AddToCache("/large_response", 200, large_body);
+  SendSynchronousRequestAndCheckResponse(client_.get(), "/large_response",
+                                         large_body);
+}
+
+TEST_P(EndToEndTest, MaxStreamsUberTest) {
+  // Connect with lower fake packet loss than we'd like to test.  Until
+  // b/10126687 is fixed, losing handshake packets is pretty brutal.
+  SetPacketLossPercentage(1);
+  ASSERT_TRUE(Initialize());
+  std::string large_body(10240, 'a');
+  int max_streams = 100;
+
+  AddToCache("/large_response", 200, large_body);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SetPacketLossPercentage(10);
+
+  for (int i = 0; i < max_streams; ++i) {
+    EXPECT_LT(0, client_->SendRequest("/large_response"));
+  }
+
+  // WaitForEvents waits 50ms and returns true if there are outstanding
+  // requests.
+  while (client_->client()->WaitForEvents()) {
+    ASSERT_TRUE(client_->connected());
+  }
+}
+
+TEST_P(EndToEndTest, StreamCancelErrorTest) {
+  ASSERT_TRUE(Initialize());
+  std::string small_body(256, 'a');
+
+  AddToCache("/small_response", 200, small_body);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  QuicSession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  // Lose the request.
+  SetPacketLossPercentage(100);
+  EXPECT_LT(0, client_->SendRequest("/small_response"));
+  client_->client()->WaitForEvents();
+  // Transmit the cancel, and ensure the connection is torn down properly.
+  SetPacketLossPercentage(0);
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  const QuicPacketCount packets_sent_before =
+      client_connection->GetStats().packets_sent;
+  session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
+  const QuicPacketCount packets_sent_now =
+      client_connection->GetStats().packets_sent;
+
+  if (version_.UsesHttp3()) {
+    // Make sure 2 packets were sent, one for QPACK instructions, another for
+    // RESET_STREAM and STOP_SENDING.
+    EXPECT_EQ(packets_sent_before + 2, packets_sent_now);
+  }
+
+  // WaitForEvents waits 50ms and returns true if there are outstanding
+  // requests.
+  while (client_->client()->WaitForEvents()) {
+    ASSERT_TRUE(client_->connected());
+  }
+  // It should be completely fine to RST a stream before any data has been
+  // received for that stream.
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->validate_client_address()) {
+    return;
+  }
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request.
+  SendSynchronousBarRequestAndCheckResponse();
+  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
+  // received by the server.
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_FALSE(server_connection->HasPendingPathValidation());
+    EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, IetfConnectionMigrationClientIPChangedMultipleTimes) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress host0 =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection != nullptr);
+
+  // Migrate socket to a new IP address.
+  QuicIpAddress host1 = TestLoopback(2);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  EXPECT_FALSE(server_cid1.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid1);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request and wait for response making sure path response is
+  // received at server.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Migrate socket to a new IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  QuicIpAddress host2 = TestLoopback(3);
+  EXPECT_NE(host0, host2);
+  EXPECT_NE(host1, host2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host2));
+  QuicConnectionId server_cid2 = client_connection->connection_id();
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid2);
+  EXPECT_NE(server_cid1, server_cid2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request using the new socket and wait for response making sure
+  // path response is received at server.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(2u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Migrate socket back to an old IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid3 = client_connection->connection_id();
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid3);
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  const auto* client_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(client_connection);
+  EXPECT_TRUE(client_packet_creator->GetClientConnectionId().IsEmpty());
+  EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
+
+  // Send another request using the new socket and wait for response making sure
+  // path response is received at server.
+  SendSynchronousBarRequestAndCheckResponse();
+  // Even this is an old path, server has forgotten about it and thus needs to
+  // validate the path again.
+  EXPECT_EQ(3u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
+  // received by the server.
+  EXPECT_FALSE(server_connection->HasPendingPathValidation());
+  EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
+  EXPECT_EQ(server_cid3, server_connection->connection_id());
+  const auto* server_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(server_connection);
+  EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  server_connection)
+                  .IsEmpty());
+  EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest,
+       ConnectionMigrationWithNonZeroConnectionIDClientIPChangedMultipleTimes) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress host0 =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection != nullptr);
+
+  // Migrate socket to a new IP address.
+  QuicIpAddress host1 = TestLoopback(2);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+  QuicConnectionId client_cid0 = client_connection->client_connection_id();
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  QuicConnectionId client_cid1 = client_connection->client_connection_id();
+  EXPECT_FALSE(server_cid1.IsEmpty());
+  EXPECT_FALSE(client_cid1.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid1);
+  EXPECT_NE(client_cid0, client_cid1);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Migrate socket to a new IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
+  QuicIpAddress host2 = TestLoopback(3);
+  EXPECT_NE(host0, host2);
+  EXPECT_NE(host1, host2);
+  EXPECT_TRUE(client_->client()->MigrateSocket(host2));
+  QuicConnectionId server_cid2 = client_connection->connection_id();
+  QuicConnectionId client_cid2 = client_connection->client_connection_id();
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid2);
+  EXPECT_NE(server_cid1, server_cid2);
+  EXPECT_FALSE(client_cid2.IsEmpty());
+  EXPECT_NE(client_cid0, client_cid2);
+  EXPECT_NE(client_cid1, client_cid2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_TRUE(QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+  EXPECT_EQ(2u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Migrate socket back to an old IP address.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
+  EXPECT_TRUE(client_->client()->MigrateSocket(host1));
+  QuicConnectionId server_cid3 = client_connection->connection_id();
+  QuicConnectionId client_cid3 = client_connection->client_connection_id();
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid0, server_cid3);
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  EXPECT_FALSE(client_cid3.IsEmpty());
+  EXPECT_NE(client_cid0, client_cid3);
+  EXPECT_NE(client_cid1, client_cid3);
+  EXPECT_NE(client_cid2, client_cid3);
+  const auto* client_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(client_connection);
+  EXPECT_EQ(client_cid3, client_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid3, client_packet_creator->GetServerConnectionId());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+  // Even this is an old path, server has forgotten about it and thus needs to
+  // validate the path again.
+  EXPECT_EQ(3u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(3u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(4u, client_connection->GetStats().num_new_connection_id_sent);
+
+  server_thread_->Pause();
+  // By the time the 2nd request is completed, the PATH_RESPONSE must have been
+  // received by the server.
+  QuicConnection* server_connection = GetServerConnection();
+  EXPECT_FALSE(server_connection->HasPendingPathValidation());
+  EXPECT_EQ(3u, server_connection->GetStats().num_validated_peer_migration);
+  EXPECT_EQ(server_cid3, server_connection->connection_id());
+  EXPECT_EQ(client_cid3, server_connection->client_connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  server_connection)
+                  .IsEmpty());
+  const auto* server_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(server_connection);
+  EXPECT_EQ(client_cid3, server_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid3, server_packet_creator->GetServerConnectionId());
+  EXPECT_EQ(3u, server_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(4u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationNewTokenForNewIp) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->validate_client_address()) {
+    return;
+  }
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request to ensure that the server will have time to finish the
+  // reverse path validation and send address token.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  client_->Disconnect();
+  // The 0-RTT handshake should succeed.
+  client_->Connect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+  SendSynchronousFooRequestAndCheckResponse();
+
+  EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    // Verify address is validated via validating token received in INITIAL
+    // packet.
+    EXPECT_FALSE(
+        server_connection->GetStats().address_validated_via_decrypting_packet);
+    EXPECT_TRUE(server_connection->GetStats().address_validated_via_token);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+  client_->Disconnect();
+}
+
+// A writer which copies the packet and send the copy with a specified self
+// address and then send the same packet with the original self address.
+class DuplicatePacketWithSpoofedSelfAddressWriter
+    : public QuicPacketWriterWrapper {
+ public:
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    if (self_address_to_overwrite_.IsInitialized()) {
+      // Send the same packet on the overwriting address before sending on the
+      // actual self address.
+      QuicPacketWriterWrapper::WritePacket(
+          buffer, buf_len, self_address_to_overwrite_, peer_address, options);
+    }
+    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                peer_address, options);
+  }
+
+  void set_self_address_to_overwrite(const QuicIpAddress& self_address) {
+    self_address_to_overwrite_ = self_address;
+  }
+
+ private:
+  QuicIpAddress self_address_to_overwrite_;
+};
+
+TEST_P(EndToEndTest, ClientAddressSpoofedForSomePeriod) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  auto writer = new DuplicatePacketWithSpoofedSelfAddressWriter();
+  client_.reset(CreateQuicClient(writer));
+
+  // Make sure client has unused peer connection ID before migration.
+  SendSynchronousFooRequestAndCheckResponse();
+  ASSERT_TRUE(QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
+      GetClientConnection()));
+
+  QuicIpAddress real_host =
+      client_->client()->session()->connection()->self_address().host();
+  ASSERT_TRUE(client_->MigrateSocket(real_host));
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(
+      0u, GetClientConnection()->GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(
+      real_host,
+      client_->client()->network_helper()->GetLatestClientAddress().host());
+  client_->WaitForDelayedAcks();
+
+  std::string large_body(10240, 'a');
+  AddToCache("/large_response", 200, large_body);
+
+  QuicIpAddress spoofed_host = TestLoopback(2);
+  writer->set_self_address_to_overwrite(spoofed_host);
+
+  client_->SendRequest("/large_response");
+  QuicConnection* client_connection = GetClientConnection();
+  QuicPacketCount num_packets_received =
+      client_connection->GetStats().packets_received;
+
+  while (client_->client()->WaitForEvents() && client_->connected()) {
+    if (client_connection->GetStats().packets_received > num_packets_received) {
+      // Ideally the client won't receive any packets till the server finds out
+      // the new client address is not working. But there are 2 corner cases:
+      // 1) Before the server received the packet from spoofed address, it might
+      // send packets to the real client address. So the client will immediately
+      // switch back to use the original address;
+      // 2) Between the server fails reverse path validation and the client
+      // receives packets again, the client might sent some packets with the
+      // spoofed address and triggers another migration.
+      // In both corner cases, the attempted migration should fail and fall back
+      // to the working path.
+      writer->set_self_address_to_overwrite(QuicIpAddress());
+    }
+  }
+  client_->WaitForResponse();
+  EXPECT_EQ(large_body, client_->response_body());
+}
+
+TEST_P(EndToEndTest,
+       AsynchronousConnectionMigrationClientIPChangedMultipleTimes) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  client_.reset(CreateQuicClient(nullptr));
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress host0 =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  QuicConnection* client_connection = GetClientConnection();
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+  // Server should have one new connection ID upon handshake completion.
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+
+  // Migrate socket to new IP address #1.
+  QuicIpAddress host1 = TestLoopback(2);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host1, client_->client()->session()->self_address().host());
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  EXPECT_NE(server_cid0, server_cid1);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Migrate socket to new IP address #2.
+  WaitForNewConnectionIds();
+  QuicIpAddress host2 = TestLoopback(3);
+  EXPECT_NE(host0, host1);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
+
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host2, client_->client()->session()->self_address().host());
+  EXPECT_EQ(2u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId server_cid2 = client_connection->connection_id();
+  EXPECT_NE(server_cid0, server_cid2);
+  EXPECT_NE(server_cid1, server_cid2);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Migrate socket back to IP address #1.
+  WaitForNewConnectionIds();
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host1));
+
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host1, client_->client()->session()->self_address().host());
+  EXPECT_EQ(3u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId server_cid3 = client_connection->connection_id();
+  EXPECT_NE(server_cid0, server_cid3);
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+  server_thread_->Pause();
+  const QuicConnection* server_connection = GetServerConnection();
+  EXPECT_EQ(server_connection->connection_id(), server_cid3);
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  server_connection)
+                  .IsEmpty());
+  server_thread_->Resume();
+
+  // There should be 1 new connection ID issued by the server.
+  WaitForNewConnectionIds();
+}
+
+TEST_P(EndToEndTest,
+       AsynchronousConnectionMigrationClientIPChangedWithNonEmptyClientCID) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+  client_.reset(CreateQuicClient(nullptr));
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+  auto* client_connection = GetClientConnection();
+  QuicConnectionId client_cid0 = client_connection->client_connection_id();
+  QuicConnectionId server_cid0 = client_connection->connection_id();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
+
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(new_host, client_->client()->session()->self_address().host());
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+  QuicConnectionId client_cid1 = client_connection->client_connection_id();
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  const auto* client_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(client_connection);
+  EXPECT_EQ(client_cid1, client_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid1, client_packet_creator->GetServerConnectionId());
+  // Send a request using the new socket.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  EXPECT_EQ(client_cid1, server_connection->client_connection_id());
+  EXPECT_EQ(server_cid1, server_connection->connection_id());
+  const auto* server_packet_creator =
+      QuicConnectionPeer::GetPacketCreator(server_connection);
+  EXPECT_EQ(client_cid1, server_packet_creator->GetClientConnectionId());
+  EXPECT_EQ(server_cid1, server_packet_creator->GetServerConnectionId());
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
+  // Tests that the client's port can change during an established QUIC
+  // connection, and that doing so does not result in the connection being
+  // closed by the server.
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client address which was used to send the first request.
+  QuicSocketAddress old_address =
+      client_->client()->network_helper()->GetLatestClientAddress();
+  int old_fd = client_->client()->GetLatestFD();
+
+  // Create a new socket before closing the old one, which will result in a new
+  // ephemeral port.
+  QuicClientPeer::CreateUDPSocketAndBind(client_->client());
+
+  // Stop listening and close the old FD.
+  QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
+
+  // The packet writer needs to be updated to use the new FD.
+  client_->client()->network_helper()->CreateQuicPacketWriter();
+
+  // Change the internal state of the client and connection to use the new port,
+  // this is done because in a real NAT rebinding the client wouldn't see any
+  // port change, and so expects no change to incoming port.
+  // This is kind of ugly, but needed as we are simply swapping out the client
+  // FD rather than any more complex NAT rebinding simulation.
+  int new_port =
+      client_->client()->network_helper()->GetLatestClientAddress().port();
+  QuicClientPeer::SetClientPort(client_->client(), new_port);
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionPeer::SetSelfAddress(
+      client_connection,
+      QuicSocketAddress(client_connection->self_address().host(), new_port));
+
+  // Register the new FD for epoll events.
+  int new_fd = client_->client()->GetLatestFD();
+  QuicEpollServer* eps = client_->epoll_server();
+  eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
+                  EPOLLIN | EPOLLOUT | EPOLLET);
+
+  // Send a second request, using the new FD.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Verify that the client's ephemeral port is different.
+  QuicSocketAddress new_address =
+      client_->client()->network_helper()->GetLatestClientAddress();
+  EXPECT_EQ(old_address.host(), new_address.host());
+  EXPECT_NE(old_address.port(), new_address.port());
+
+  if (!version_.HasIetfQuicFrames() ||
+      !GetClientConnection()->validate_client_address()) {
+    return;
+  }
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_FALSE(server_connection->HasPendingPathValidation());
+    EXPECT_EQ(1u, server_connection->GetStats().num_validated_peer_migration);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
+  SetQuicReloadableFlag(quic_unified_iw_options, true);
+  client_extra_copts_.push_back(kIW03);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    QuicPacketCount cwnd =
+        server_connection->sent_packet_manager().initial_congestion_window();
+    EXPECT_EQ(3u, cwnd);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, DifferentFlowControlWindows) {
+  // Client and server can set different initial flow control receive windows.
+  // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
+  // in the crypto handshake.
+  const uint32_t kClientStreamIFCW = 123456;
+  const uint32_t kClientSessionIFCW = 234567;
+  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
+
+  uint32_t kServerStreamIFCW = 32 * 1024;
+  uint32_t kServerSessionIFCW = 48 * 1024;
+  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Open a data stream to make sure the stream level flow control is updated.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  WriteHeadersOnStream(stream);
+  stream->WriteOrBufferBody("hello", false);
+
+  if (!version_.UsesTls()) {
+    // IFWA only exists with QUIC_CRYPTO.
+    // Client should have the right values for server's receive window.
+    ASSERT_TRUE(client_->client()
+                    ->client_session()
+                    ->config()
+                    ->HasReceivedInitialStreamFlowControlWindowBytes());
+    EXPECT_EQ(kServerStreamIFCW,
+              client_->client()
+                  ->client_session()
+                  ->config()
+                  ->ReceivedInitialStreamFlowControlWindowBytes());
+    ASSERT_TRUE(client_->client()
+                    ->client_session()
+                    ->config()
+                    ->HasReceivedInitialSessionFlowControlWindowBytes());
+    EXPECT_EQ(kServerSessionIFCW,
+              client_->client()
+                  ->client_session()
+                  ->config()
+                  ->ReceivedInitialSessionFlowControlWindowBytes());
+  }
+  EXPECT_EQ(kServerStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                    client_session->flow_controller()));
+
+  // Server should have the right values for client's receive window.
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  if (server_session == nullptr) {
+    ADD_FAILURE() << "Missing server session";
+    server_thread_->Resume();
+    return;
+  }
+  QuicConfig server_config = *server_session->config();
+  EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                    server_session->flow_controller()));
+  server_thread_->Resume();
+  if (version_.UsesTls()) {
+    // IFWA only exists with QUIC_CRYPTO.
+    return;
+  }
+  ASSERT_TRUE(server_config.HasReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_EQ(kClientStreamIFCW,
+            server_config.ReceivedInitialStreamFlowControlWindowBytes());
+  ASSERT_TRUE(server_config.HasReceivedInitialSessionFlowControlWindowBytes());
+  EXPECT_EQ(kClientSessionIFCW,
+            server_config.ReceivedInitialSessionFlowControlWindowBytes());
+}
+
+// Test negotiation of IFWA connection option.
+TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
+  const uint32_t kClientStreamIFCW = 123456;
+  const uint32_t kClientSessionIFCW = 234567;
+  set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
+
+  uint32_t kServerStreamIFCW = 32 * 1024;
+  uint32_t kServerSessionIFCW = 48 * 1024;
+  set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
+
+  // Bump the window.
+  const uint32_t kExpectedStreamIFCW = 1024 * 1024;
+  const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
+  client_extra_copts_.push_back(kIFWA);
+
+  ASSERT_TRUE(Initialize());
+
+  // Values are exchanged during crypto handshake, so wait for that to finish.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  // Open a data stream to make sure the stream level flow control is updated.
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  WriteHeadersOnStream(stream);
+  stream->WriteOrBufferBody("hello", false);
+
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+
+  if (!version_.UsesTls()) {
+    // IFWA only exists with QUIC_CRYPTO.
+    // Client should have the right values for server's receive window.
+    ASSERT_TRUE(client_session->config()
+                    ->HasReceivedInitialStreamFlowControlWindowBytes());
+    EXPECT_EQ(kExpectedStreamIFCW,
+              client_session->config()
+                  ->ReceivedInitialStreamFlowControlWindowBytes());
+    ASSERT_TRUE(client_session->config()
+                    ->HasReceivedInitialSessionFlowControlWindowBytes());
+    EXPECT_EQ(kExpectedSessionIFCW,
+              client_session->config()
+                  ->ReceivedInitialSessionFlowControlWindowBytes());
+  }
+  EXPECT_EQ(kExpectedStreamIFCW, QuicStreamPeer::SendWindowOffset(stream));
+  EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
+                                      client_session->flow_controller()));
+}
+
+TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
+  // The special headers and crypto streams should be subject to per-stream flow
+  // control limits, but should not be subject to connection level flow control
+  const uint32_t kStreamIFCW = 32 * 1024;
+  const uint32_t kSessionIFCW = 48 * 1024;
+  set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
+  set_client_initial_session_flow_control_receive_window(kSessionIFCW);
+  set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
+  set_server_initial_session_flow_control_receive_window(kSessionIFCW);
+
+  ASSERT_TRUE(Initialize());
+
+  // Wait for crypto handshake to finish. This should have contributed to the
+  // crypto stream flow control window, but not affected the session flow
+  // control window.
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicCryptoStream* crypto_stream =
+      QuicSessionPeer::GetMutableCryptoStream(client_session);
+  ASSERT_TRUE(crypto_stream);
+  // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
+  // subject to flow control.
+  if (!version_.UsesCryptoFrames()) {
+    EXPECT_LT(QuicStreamPeer::SendWindowSize(crypto_stream), kStreamIFCW);
+  }
+  // When stream type is enabled, control streams will send settings and
+  // contribute to flow control windows, so this expectation is no longer valid.
+  if (!version_.UsesHttp3()) {
+    EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
+                                client_session->flow_controller()));
+  }
+
+  // Send a request with no body, and verify that the connection level window
+  // has not been affected.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // No headers stream in IETF QUIC.
+  if (version_.UsesHttp3()) {
+    return;
+  }
+
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(client_session);
+  ASSERT_TRUE(headers_stream);
+  EXPECT_LT(QuicStreamPeer::SendWindowSize(headers_stream), kStreamIFCW);
+  EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
+                              client_session->flow_controller()));
+
+  // Server should be in a similar state: connection flow control window should
+  // not have any bytes marked as received.
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    QuicFlowController* server_connection_flow_controller =
+        server_session->flow_controller();
+    EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
+                                server_connection_flow_controller));
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, FlowControlsSynced) {
+  set_smaller_flow_control_receive_window();
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  server_thread_->WaitForCryptoHandshakeConfirmed();
+
+  QuicSpdySession* const client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+
+  if (version_.UsesHttp3()) {
+    // Make sure that the client has received the initial SETTINGS frame, which
+    // is sent in the first packet on the control stream.
+    while (!QuicSpdySessionPeer::GetReceiveControlStream(client_session)) {
+      client_->client()->WaitForEvents();
+      ASSERT_TRUE(client_->connected());
+    }
+  }
+
+  // Make sure that all data sent by the client has been received by the server
+  // (and the ack received by the client).
+  while (client_session->HasUnackedStreamData()) {
+    client_->client()->WaitForEvents();
+    ASSERT_TRUE(client_->connected());
+  }
+
+  server_thread_->Pause();
+
+  QuicSpdySession* const server_session = GetServerSession();
+  if (server_session == nullptr) {
+    ADD_FAILURE() << "Missing server session";
+    server_thread_->Resume();
+    return;
+  }
+  ExpectFlowControlsSynced(client_session, server_session);
+
+  // Check control streams.
+  if (version_.UsesHttp3()) {
+    ExpectFlowControlsSynced(
+        QuicSpdySessionPeer::GetReceiveControlStream(client_session),
+        QuicSpdySessionPeer::GetSendControlStream(server_session));
+    ExpectFlowControlsSynced(
+        QuicSpdySessionPeer::GetSendControlStream(client_session),
+        QuicSpdySessionPeer::GetReceiveControlStream(server_session));
+  }
+
+  // Check crypto stream.
+  if (!version_.UsesCryptoFrames()) {
+    ExpectFlowControlsSynced(
+        QuicSessionPeer::GetMutableCryptoStream(client_session),
+        QuicSessionPeer::GetMutableCryptoStream(server_session));
+  }
+
+  // Check headers stream.
+  if (!version_.UsesHttp3()) {
+    SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
+    SpdySettingsIR settings_frame;
+    settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
+                              kDefaultMaxUncompressedHeaderSize);
+    SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
+
+    QuicHeadersStream* client_header_stream =
+        QuicSpdySessionPeer::GetHeadersStream(client_session);
+    QuicHeadersStream* server_header_stream =
+        QuicSpdySessionPeer::GetHeadersStream(server_session);
+    // Both client and server are sending this SETTINGS frame, and the send
+    // window is consumed. But because of timing issue, the server may send or
+    // not send the frame, and the client may send/ not send / receive / not
+    // receive the frame.
+    // TODO(fayang): Rewrite this part because it is hacky.
+    QuicByteCount win_difference1 =
+        QuicStreamPeer::ReceiveWindowSize(server_header_stream) -
+        QuicStreamPeer::SendWindowSize(client_header_stream);
+    if (win_difference1 != 0) {
+      EXPECT_EQ(frame.size(), win_difference1);
+    }
+
+    QuicByteCount win_difference2 =
+        QuicStreamPeer::ReceiveWindowSize(client_header_stream) -
+        QuicStreamPeer::SendWindowSize(server_header_stream);
+    if (win_difference2 != 0) {
+      EXPECT_EQ(frame.size(), win_difference2);
+    }
+
+    // Client *may* have received the SETTINGs frame.
+    // TODO(fayang): Rewrite this part because it is hacky.
+    float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
+                       client_session->flow_controller())) /
+                   QuicStreamPeer::ReceiveWindowSize(
+                       QuicSpdySessionPeer::GetHeadersStream(client_session));
+    float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
+                       client_session->flow_controller())) /
+                   (QuicStreamPeer::ReceiveWindowSize(
+                        QuicSpdySessionPeer::GetHeadersStream(client_session)) +
+                    frame.size());
+    EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
+                ratio2 == kSessionToStreamRatio);
+  }
+
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
+  // A stream created on receipt of a simple request with no body will never get
+  // a stream frame with a FIN. Verify that we don't keep track of the stream in
+  // the locally closed streams map: it will never be removed if so.
+  ASSERT_TRUE(Initialize());
+
+  // Send a simple headers only request, and receive response.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Now verify that the server is not waiting for a final FIN or RST.
+  server_thread_->Pause();
+  QuicSession* server_session = GetServerSession();
+  if (server_session != nullptr) {
+    EXPECT_EQ(0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(
+                      server_session)
+                      .size());
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  server_thread_->Resume();
+}
+
+// TestAckListener counts how many bytes are acked during its lifetime.
+class TestAckListener : public QuicAckListenerInterface {
+ public:
+  TestAckListener() {}
+
+  void OnPacketAcked(int acked_bytes,
+                     QuicTime::Delta /*delta_largest_observed*/) override {
+    total_bytes_acked_ += acked_bytes;
+  }
+
+  void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
+
+  int total_bytes_acked() const { return total_bytes_acked_; }
+
+ protected:
+  // Object is ref counted.
+  ~TestAckListener() override {}
+
+ private:
+  int total_bytes_acked_ = 0;
+};
+
+class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
+ public:
+  void OnCompleteResponse(QuicStreamId id,
+                          const SpdyHeaderBlock& response_headers,
+                          const std::string& response_body) override {
+    QUIC_DVLOG(1) << "response for stream " << id << " "
+                  << response_headers.DebugString() << "\n"
+                  << response_body;
+  }
+};
+
+TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
+  // Verify that even in the presence of packet loss and occasionally blocked
+  // socket, an AckNotifierDelegate will get informed that the data it is
+  // interested in has been ACKed. This tests end-to-end ACK notification, and
+  // demonstrates that retransmissions do not break this functionality.
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  SetPacketLossPercentage(5);
+  ASSERT_TRUE(Initialize());
+  // Wait for the server SHLO before upping the packet loss.
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+  client_writer_->set_fake_blocked_socket_percentage(10);
+
+  // Wait for SETTINGS frame from server that sets QPACK dynamic table capacity
+  // to make sure request headers will be compressed using the dynamic table.
+  if (version_.UsesHttp3()) {
+    while (true) {
+      // Waits for up to 50 ms.
+      client_->client()->WaitForEvents();
+      ASSERT_TRUE(client_->connected());
+      QuicSpdyClientSession* client_session = GetClientSession();
+      if (client_session == nullptr) {
+        ADD_FAILURE() << "Missing client session";
+        return;
+      }
+      QpackEncoder* qpack_encoder = client_session->qpack_encoder();
+      if (qpack_encoder == nullptr) {
+        ADD_FAILURE() << "Missing QPACK encoder";
+        return;
+      }
+      QpackEncoderHeaderTable* header_table =
+          QpackEncoderPeer::header_table(qpack_encoder);
+      if (header_table == nullptr) {
+        ADD_FAILURE() << "Missing header table";
+        return;
+      }
+      if (header_table->dynamic_table_capacity() > 0) {
+        break;
+      }
+    }
+  }
+
+  // Create a POST request and send the headers only.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+
+  // Size of headers on the request stream. This is zero if headers are sent on
+  // the header stream.
+  size_t header_size = 0;
+  if (version_.UsesHttp3()) {
+    // Determine size of headers after QPACK compression.
+    NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
+    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+    QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
+    qpack_encoder.set_qpack_stream_sender_delegate(
+        &encoder_stream_sender_delegate);
+
+    qpack_encoder.SetMaximumDynamicTableCapacity(
+        kDefaultQpackMaxDynamicTableCapacity);
+    qpack_encoder.SetDynamicTableCapacity(kDefaultQpackMaxDynamicTableCapacity);
+    qpack_encoder.SetMaximumBlockedStreams(kDefaultMaximumBlockedStreams);
+
+    std::string encoded_headers = qpack_encoder.EncodeHeaderList(
+        /* stream_id = */ 0, headers, nullptr);
+    header_size = encoded_headers.size();
+  }
+
+  // Test the AckNotifier's ability to track multiple packets by making the
+  // request body exceed the size of a single packet.
+  std::string request_string = "a request body bigger than one packet" +
+                               std::string(kMaxOutgoingPacketSize, '.');
+
+  const int expected_bytes_acked = header_size + request_string.length();
+
+  // The TestAckListener will cause a failure if not notified.
+  quiche::QuicheReferenceCountedPointer<TestAckListener> ack_listener(
+      new TestAckListener());
+
+  // Send the request, and register the delegate for ACKs.
+  client_->SendData(request_string, true, ack_listener);
+  WaitForFooResponseAndCheckIt();
+
+  // Send another request to flush out any pending ACKs on the server.
+  SendSynchronousBarRequestAndCheckResponse();
+
+  // Make sure the delegate does get the notification it expects.
+  while (ack_listener->total_bytes_acked() < expected_bytes_acked) {
+    // Waits for up to 50 ms.
+    client_->client()->WaitForEvents();
+    ASSERT_TRUE(client_->connected());
+  }
+  EXPECT_EQ(ack_listener->total_bytes_acked(), expected_bytes_acked)
+      << " header_size " << header_size << " request length "
+      << request_string.length();
+}
+
+// Send a public reset from the server.
+TEST_P(EndToEndTest, ServerSendPublicReset) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSpdySession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConfig* config = client_session->config();
+  ASSERT_TRUE(config);
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  StatelessResetToken stateless_reset_token =
+      config->ReceivedStatelessResetToken();
+
+  // Send the public reset.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId connection_id = client_connection->connection_id();
+  QuicPublicResetPacket header;
+  header.connection_id = connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet;
+  if (version_.HasIetfInvariantHeader()) {
+    packet = framer.BuildIetfStatelessResetPacket(
+        connection_id, /*received_packet_length=*/100, stateless_reset_token);
+  } else {
+    packet = framer.BuildPublicResetPacket(header);
+  }
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  auto client_address = client_connection->self_address();
+  server_writer_->WritePacket(packet->data(), packet->length(),
+                              server_address_.host(), client_address, nullptr);
+  server_thread_->Resume();
+
+  // The request should fail.
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  EXPECT_TRUE(client_->response_headers()->empty());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
+}
+
+// Send a public reset from the server for a different connection ID.
+// It should be ignored.
+TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSpdySession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConfig* config = client_session->config();
+  ASSERT_TRUE(config);
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  StatelessResetToken stateless_reset_token =
+      config->ReceivedStatelessResetToken();
+  // Send the public reset.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  QuicPublicResetPacket header;
+  header.connection_id = incorrect_connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet;
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  client_connection->set_debug_visitor(&visitor);
+  if (version_.HasIetfInvariantHeader()) {
+    packet = framer.BuildIetfStatelessResetPacket(
+        incorrect_connection_id, /*received_packet_length=*/100,
+        stateless_reset_token);
+    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+        .Times(0);
+  } else {
+    packet = framer.BuildPublicResetPacket(header);
+    EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+        .Times(1);
+  }
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  auto client_address = client_connection->self_address();
+  server_writer_->WritePacket(packet->data(), packet->length(),
+                              server_address_.host(), client_address, nullptr);
+  server_thread_->Resume();
+
+  if (version_.HasIetfInvariantHeader()) {
+    // The request should fail. IETF stateless reset does not include connection
+    // ID.
+    EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+    EXPECT_TRUE(client_->response_headers()->empty());
+    EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
+  } else {
+    // The connection should be unaffected.
+    SendSynchronousFooRequestAndCheckResponse();
+  }
+
+  client_connection->set_debug_visitor(nullptr);
+}
+
+// Send a public reset from the client for a different connection ID.
+// It should be ignored.
+TEST_P(EndToEndTest, ClientSendPublicResetWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  // Send the public reset.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  QuicPublicResetPacket header;
+  header.connection_id = incorrect_connection_id;
+  QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
+                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      framer.BuildPublicResetPacket(header));
+  client_writer_->WritePacket(
+      packet->data(), packet->length(),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+
+  // The connection should be unaffected.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// Send a version negotiation packet from the server for a different
+// connection ID.  It should be ignored.
+TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Send the version negotiation packet.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionId incorrect_connection_id = TestConnectionId(
+      TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          incorrect_connection_id, EmptyQuicConnectionId(),
+          version_.HasIetfInvariantHeader(),
+          version_.HasLengthPrefixedConnectionIds(),
+          server_supported_versions_));
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  client_connection->set_debug_visitor(&visitor);
+  EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
+      .Times(1);
+  // We must pause the server's thread in order to call WritePacket without
+  // race conditions.
+  server_thread_->Pause();
+  server_writer_->WritePacket(
+      packet->data(), packet->length(), server_address_.host(),
+      client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+  server_thread_->Resume();
+
+  // The connection should be unaffected.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_connection->set_debug_visitor(nullptr);
+}
+
+// DowngradePacketWriter is a client writer which will intercept all the client
+// writes for |target_version| and reply to them with version negotiation
+// packets to attempt a version downgrade attack. Once the client has downgraded
+// to a different version, the writer stops intercepting. |server_thread| must
+// start off paused, and will be resumed once interception is done.
+class DowngradePacketWriter : public PacketDroppingTestWriter {
+ public:
+  explicit DowngradePacketWriter(
+      const ParsedQuicVersion& target_version,
+      const ParsedQuicVersionVector& supported_versions, QuicTestClient* client,
+      QuicPacketWriter* server_writer, ServerThread* server_thread)
+      : target_version_(target_version),
+        supported_versions_(supported_versions),
+        client_(client),
+        server_writer_(server_writer),
+        server_thread_(server_thread) {}
+  ~DowngradePacketWriter() override {}
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    if (!intercept_enabled_) {
+      return PacketDroppingTestWriter::WritePacket(
+          buffer, buf_len, self_address, peer_address, options);
+    }
+    PacketHeaderFormat format;
+    QuicLongHeaderType long_packet_type;
+    bool version_present, has_length_prefix;
+    QuicVersionLabel version_label;
+    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+    QuicConnectionId destination_connection_id, source_connection_id;
+    absl::optional<absl::string_view> retry_token;
+    std::string detailed_error;
+    if (QuicFramer::ParsePublicHeaderDispatcher(
+            QuicEncryptedPacket(buffer, buf_len),
+            kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+            &version_present, &has_length_prefix, &version_label,
+            &parsed_version, &destination_connection_id, &source_connection_id,
+            &retry_token, &detailed_error) != QUIC_NO_ERROR) {
+      ADD_FAILURE() << "Failed to parse our own packet: " << detailed_error;
+      return WriteResult(WRITE_STATUS_ERROR, 0);
+    }
+    if (!version_present || parsed_version != target_version_) {
+      // Client is sending with another version, the attack has succeeded so we
+      // can stop intercepting.
+      intercept_enabled_ = false;
+      server_thread_->Resume();
+      // Pass the client-sent packet through.
+      return WritePacket(buffer, buf_len, self_address, peer_address, options);
+    }
+    // Send a version negotiation packet.
+    std::unique_ptr<QuicEncryptedPacket> packet(
+        QuicFramer::BuildVersionNegotiationPacket(
+            destination_connection_id, source_connection_id,
+            parsed_version.HasIetfInvariantHeader(), has_length_prefix,
+            supported_versions_));
+    server_writer_->WritePacket(
+        packet->data(), packet->length(), peer_address.host(),
+        client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+    // Drop the client-sent packet but pretend it was sent.
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+ private:
+  bool intercept_enabled_ = true;
+  ParsedQuicVersion target_version_;
+  ParsedQuicVersionVector supported_versions_;
+  QuicTestClient* client_;           // Unowned.
+  QuicPacketWriter* server_writer_;  // Unowned.
+  ServerThread* server_thread_;      // Unowned.
+};
+
+TEST_P(EndToEndTest, VersionNegotiationDowngradeAttackIsDetected) {
+  ParsedQuicVersion target_version = server_supported_versions_.back();
+  if (!version_.UsesTls() || target_version == version_) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  connect_to_server_on_initialize_ = false;
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    target_version);
+  ParsedQuicVersionVector downgrade_versions{version_};
+  ASSERT_TRUE(Initialize());
+  ASSERT_TRUE(server_thread_);
+  // Pause the server thread to allow our DowngradePacketWriter to write version
+  // negotiation packets in a thread-safe manner. It will be resumed by the
+  // DowngradePacketWriter.
+  server_thread_->Pause();
+  client_.reset(new QuicTestClient(server_address_, server_hostname_,
+                                   client_config_, client_supported_versions_,
+                                   crypto_test_utils::ProofVerifierForTesting(),
+                                   std::make_unique<QuicClientSessionCache>()));
+  delete client_writer_;
+  client_writer_ = new DowngradePacketWriter(target_version, downgrade_versions,
+                                             client_.get(), server_writer_,
+                                             server_thread_.get());
+  client_->UseWriter(client_writer_);
+  // Have the client attempt to send a request.
+  client_->Connect();
+  EXPECT_TRUE(client_->SendSynchronousRequest("/foo").empty());
+  // Make sure the downgrade is detected and the handshake fails.
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
+}
+
+// A bad header shouldn't tear down the connection, because the receiver can't
+// tell the connection ID.
+TEST_P(EndToEndTest, BadPacketHeaderTruncated) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Packet with invalid public flags.
+  char packet[] = {// public flags (8 byte connection_id)
+                   0x3C,
+                   // truncated connection ID
+                   0x11};
+  client_writer_->WritePacket(
+      &packet[0], sizeof(packet),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  EXPECT_TRUE(server_thread_->WaitUntil(
+      [&] {
+        return QuicDispatcherPeer::GetAndClearLastError(
+                   QuicServerPeer::GetDispatcher(server_thread_->server())) ==
+               QUIC_INVALID_PACKET_HEADER;
+      },
+      QuicTime::Delta::FromSeconds(5)));
+
+  // The connection should not be terminated.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// A bad header shouldn't tear down the connection, because the receiver can't
+// tell the connection ID.
+TEST_P(EndToEndTest, BadPacketHeaderFlags) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Packet with invalid public flags.
+  uint8_t packet[] = {
+      // invalid public flags
+      0xFF,
+      // connection_id
+      0x10,
+      0x32,
+      0x54,
+      0x76,
+      0x98,
+      0xBA,
+      0xDC,
+      0xFE,
+      // packet sequence number
+      0xBC,
+      0x9A,
+      0x78,
+      0x56,
+      0x34,
+      0x12,
+      // private flags
+      0x00,
+  };
+  client_writer_->WritePacket(
+      reinterpret_cast<const char*>(packet), sizeof(packet),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+
+  EXPECT_TRUE(server_thread_->WaitUntil(
+      [&] {
+        return QuicDispatcherPeer::GetAndClearLastError(
+                   QuicServerPeer::GetDispatcher(server_thread_->server())) ==
+               QUIC_INVALID_PACKET_HEADER;
+      },
+      QuicTime::Delta::FromSeconds(5)));
+
+  // The connection should not be terminated.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// Send a packet from the client with bad encrypted data.  The server should not
+// tear down the connection.
+TEST_P(EndToEndTest, BadEncryptedData) {
+  ASSERT_TRUE(Initialize());
+
+  // Start the connection.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      client_connection->connection_id(), EmptyQuicConnectionId(), false, false,
+      1, "At least 20 characters.", CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
+      PACKET_4BYTE_PACKET_NUMBER));
+  // Damage the encrypted data.
+  std::string damaged_packet(packet->data(), packet->length());
+  damaged_packet[30] ^= 0x01;
+  QUIC_DLOG(INFO) << "Sending bad packet.";
+  client_writer_->WritePacket(
+      damaged_packet.data(), damaged_packet.length(),
+      client_->client()->network_helper()->GetLatestClientAddress().host(),
+      server_address_, nullptr);
+  // Give the server time to process the packet.
+  absl::SleepFor(absl::Seconds(1));
+  // This error is sent to the connection's OnError (which ignores it), so the
+  // dispatcher doesn't see it.
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher != nullptr) {
+    EXPECT_THAT(QuicDispatcherPeer::GetAndClearLastError(dispatcher),
+                IsQuicNoError());
+  } else {
+    ADD_FAILURE() << "Missing dispatcher";
+  }
+  server_thread_->Resume();
+
+  // The connection should not be terminated.
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  // Lose the request.
+  SetPacketLossPercentage(100);
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "test_body", /*fin=*/false);
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+
+  // Cancel the stream.
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  QuicSession* session = GetClientSession();
+  ASSERT_TRUE(session);
+  // Verify canceled stream does not become zombie.
+  EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
+}
+
+// A test stream that gives |response_body_| as an error response body.
+class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
+ public:
+  ServerStreamWithErrorResponseBody(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend,
+      std::string response_body)
+      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
+                               quic_simple_server_backend),
+        response_body_(std::move(response_body)) {}
+
+  ~ServerStreamWithErrorResponseBody() override = default;
+
+ protected:
+  void SendErrorResponse() override {
+    QUIC_DLOG(INFO) << "Sending error response for stream " << id();
+    SpdyHeaderBlock headers;
+    headers[":status"] = "500";
+    headers["content-length"] = absl::StrCat(response_body_.size());
+    // This method must call CloseReadSide to cause the test case, StopReading
+    // is not sufficient.
+    QuicStreamPeer::CloseReadSide(this);
+    SendHeadersAndBody(std::move(headers), response_body_);
+  }
+
+  std::string response_body_;
+};
+
+class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
+ public:
+  explicit StreamWithErrorFactory(std::string response_body)
+      : response_body_(std::move(response_body)) {}
+
+  ~StreamWithErrorFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamWithErrorResponseBody(
+        id, session, quic_simple_server_backend, response_body_);
+  }
+
+  QuicSimpleServerStream* CreateStream(
+      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
+      QuicSimpleServerBackend* /*response_cache*/) override {
+    return nullptr;
+  }
+
+ private:
+  std::string response_body_;
+};
+
+// A test server stream that drops all received body.
+class ServerStreamThatDropsBody : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatDropsBody(QuicStreamId id, QuicSpdySession* session,
+                            QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
+                               quic_simple_server_backend) {}
+
+  ~ServerStreamThatDropsBody() override = default;
+
+ protected:
+  void OnBodyAvailable() override {
+    while (HasBytesToRead()) {
+      struct iovec iov;
+      if (GetReadableRegions(&iov, 1) == 0) {
+        // No more data to read.
+        break;
+      }
+      QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
+                    << id();
+      MarkConsumed(iov.iov_len);
+    }
+
+    if (!sequencer()->IsClosed()) {
+      sequencer()->SetUnblocked();
+      return;
+    }
+
+    // If the sequencer is closed, then all the body, including the fin, has
+    // been consumed.
+    OnFinRead();
+
+    if (write_side_closed() || fin_buffered()) {
+      return;
+    }
+
+    SendResponse();
+  }
+};
+
+class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
+ public:
+  ServerStreamThatDropsBodyFactory() = default;
+
+  ~ServerStreamThatDropsBodyFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamThatDropsBody(id, session,
+                                         quic_simple_server_backend);
+  }
+
+  QuicSimpleServerStream* CreateStream(
+      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
+      QuicSimpleServerBackend* /*response_cache*/) override {
+    return nullptr;
+  }
+};
+
+// A test server stream that sends response with body size greater than 4GB.
+class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatSendsHugeResponse(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend, int64_t body_bytes)
+      : QuicSimpleServerStream(id, session, BIDIRECTIONAL,
+                               quic_simple_server_backend),
+        body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponse() override = default;
+
+ protected:
+  void SendResponse() override {
+    QuicBackendResponse response;
+    std::string body(body_bytes_, 'a');
+    response.set_body(body);
+    SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
+                                  response.trailers().Clone());
+  }
+
+ private:
+  // Use a explicit int64_t rather than size_t to simulate a 64-bit server
+  // talking to a 32-bit client.
+  int64_t body_bytes_;
+};
+
+class ServerStreamThatSendsHugeResponseFactory
+    : public QuicTestServer::StreamFactory {
+ public:
+  explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
+      : body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponseFactory() override = default;
+
+  QuicSimpleServerStream* CreateStream(
+      QuicStreamId id, QuicSpdySession* session,
+      QuicSimpleServerBackend* quic_simple_server_backend) override {
+    return new ServerStreamThatSendsHugeResponse(
+        id, session, quic_simple_server_backend, body_bytes_);
+  }
+
+  QuicSimpleServerStream* CreateStream(
+      PendingStream* /*pending*/, QuicSpdySession* /*session*/,
+      QuicSimpleServerBackend* /*response_cache*/) override {
+    return nullptr;
+  }
+
+  int64_t body_bytes_;
+};
+
+TEST_P(EndToEndTest, EarlyResponseFinRecording) {
+  set_smaller_flow_control_receive_window();
+
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_close_streams_highest_offset_ (which will never be deleted).
+  // To set up the test condition, the server must do the following in order:
+  // start sending the response and call CloseReadSide
+  // receive the FIN of the request
+  // send the FIN of the response
+
+  // The response body must be larger than the flow control window so the server
+  // must receive a window update from the client before it can finish sending
+  // it.
+  uint32_t response_body_size =
+      2 * client_config_.GetInitialStreamFlowControlWindowToSend();
+  std::string response_body(response_body_size, 'a');
+
+  StreamWithErrorFactory stream_factory(response_body);
+  SetSpdyStreamFactory(&stream_factory);
+
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // A POST that gets an early error response, after the headers are received
+  // and before the body is received, due to invalid content-length.
+  // Set an invalid content-length, so the request will receive an early 500
+  // response.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/garbage";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = "-1";
+
+  // The body must be large enough that the FIN will be in a different packet
+  // than the end of the headers, but short enough to not require a flow control
+  // update.  This allows headers processing to trigger the error response
+  // before the request FIN is processed but receive the request FIN before the
+  // response is sent completely.
+  const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
+  std::string request_body(kRequestBodySize, 'a');
+
+  // Send the request.
+  client_->SendMessage(headers, request_body);
+  client_->WaitForResponse();
+  CheckResponseHeaders("500");
+
+  // Pause the server so we can access the server's internals without races.
+  server_thread_->Pause();
+
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  QuicSession* server_session =
+      QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
+  EXPECT_TRUE(server_session != nullptr);
+
+  // The stream is not waiting for the arrival of the peer's final offset.
+  EXPECT_EQ(
+      0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
+              .size());
+
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, Trailers) {
+  // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  // Set reordering to ensure that Trailers arriving before body is ok.
+  SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
+  SetReorderPercentage(30);
+
+  // Add a response with headers, body, and trailers.
+  const std::string kBody = "body content";
+
+  SpdyHeaderBlock headers;
+  headers[":status"] = "200";
+  headers["content-length"] = absl::StrCat(kBody.size());
+
+  SpdyHeaderBlock trailers;
+  trailers["some-trailing-header"] = "trailing-header-value";
+
+  memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
+                                    std::move(headers), kBody,
+                                    trailers.Clone());
+
+  SendSynchronousRequestAndCheckResponse("/trailer_url", kBody);
+  EXPECT_EQ(trailers, client_->response_trailers());
+}
+
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
+  // This test tests a huge post with introduced packet loss from client to
+  // server and body size greater than 4GB, making sure QUIC code does not break
+  // for 32-bit builds.
+  ServerStreamThatDropsBodyFactory stream_factory;
+  SetSpdyStreamFactory(&stream_factory);
+  ASSERT_TRUE(Initialize());
+  // Set client's epoll server's time out to 0 to make this test be finished
+  // within a short time.
+  client_->epoll_server()->set_timeout_in_us(0);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SetPacketLossPercentage(1);
+  // To avoid storing the whole request body in memory, use a loop to repeatedly
+  // send body size of kSizeBytes until the whole request body size is reached.
+  const int kSizeBytes = 128 * 1024;
+  // Request body size is 4G plus one more kSizeBytes.
+  int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
+  std::string body(kSizeBytes, 'a');
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["content-length"] = absl::StrCat(request_body_size_bytes);
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+
+  for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
+    bool fin = (i == request_body_size_bytes - 1);
+    client_->SendData(std::string(body.data(), kSizeBytes), fin);
+    client_->client()->WaitForEvents();
+  }
+  VerifyCleanConnection(true);
+}
+
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
+  // This test tests a huge response with introduced loss from server to client
+  // and body size greater than 4GB, making sure QUIC code does not break for
+  // 32-bit builds.
+  const int kSizeBytes = 128 * 1024;
+  int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(4294967296, response_body_size_bytes);
+  ServerStreamThatSendsHugeResponseFactory stream_factory(
+      response_body_size_bytes);
+  SetSpdyStreamFactory(&stream_factory);
+
+  StartServer();
+
+  // Use a quic client that drops received body.
+  QuicTestClient* client =
+      new QuicTestClient(server_address_, server_hostname_, client_config_,
+                         client_supported_versions_);
+  client->client()->set_drop_response_body(true);
+  client->UseWriter(client_writer_);
+  client->Connect();
+  client_.reset(client);
+  static QuicEpollEvent event(EPOLLOUT);
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  client_writer_->Initialize(
+      QuicConnectionPeer::GetHelper(client_connection),
+      QuicConnectionPeer::GetAlarmFactory(client_connection),
+      std::make_unique<ClientDelegate>(client_->client()));
+  initialized_ = true;
+  ASSERT_TRUE(client_->client()->connected());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  SetPacketLossPercentage(1);
+  client_->SendRequest("/huge_response");
+  client_->WaitForResponse();
+  VerifyCleanConnection(true);
+}
+
+// Regression test for b/111515567
+TEST_P(EndToEndTest, AgreeOnStopWaiting) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    // Verify client and server connections agree on the value of
+    // no_stop_waiting_frames.
+    EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
+              QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+// Regression test for b/111515567
+TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
+  QuicTagVector options;
+  options.push_back(kNSTP);
+  client_config_.SetConnectionOptionsToSend(options);
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    // Verify client and server connections agree on the value of
+    // no_stop_waiting_frames.
+    EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
+              QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
+  // Tests that when client side has no active request and no waiting
+  // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
+  ASSERT_TRUE(Initialize());
+  client_->SendSynchronousRequest("/foo");
+  if (version_.UsesHttp3()) {
+    return;
+  }
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(client_session);
+  ASSERT_TRUE(headers_stream);
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
+  ASSERT_TRUE(sequencer);
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+// A single large header value causes a different error than the total size of
+// headers exceeding a smaller limit, tested at EndToEndTest.LargeHeaders.
+TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
+  ASSERT_TRUE(Initialize());
+
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  headers["key"] = std::string(2 * 1024 * 1024, 'a');
+
+  client_->SendMessage(headers, "");
+  client_->WaitForResponse();
+  if (version_.UsesHttp3()) {
+    EXPECT_THAT(client_->connection_error(),
+                IsError(QUIC_QPACK_DECOMPRESSION_FAILED));
+  } else {
+    EXPECT_THAT(client_->connection_error(),
+                IsError(QUIC_HPACK_VALUE_TOO_LONG));
+  }
+}
+
+class WindowUpdateObserver : public QuicConnectionDebugVisitor {
+ public:
+  WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
+
+  size_t num_window_update_frames() const { return num_window_update_frames_; }
+
+  size_t num_ping_frames() const { return num_ping_frames_; }
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
+                           const QuicTime& /*receive_time*/) override {
+    ++num_window_update_frames_;
+  }
+
+  void OnPingFrame(const QuicPingFrame& /*frame*/,
+                   const QuicTime::Delta /*ping_received_delay*/) override {
+    ++num_ping_frames_;
+  }
+
+ private:
+  size_t num_window_update_frames_;
+  size_t num_ping_frames_;
+};
+
+TEST_P(EndToEndTest, WindowUpdateInAck) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  WindowUpdateObserver observer;
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  client_connection->set_debug_visitor(&observer);
+  // 100KB body.
+  std::string body(100 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  EXPECT_EQ(kFooResponseBody,
+            client_->SendCustomSynchronousRequest(headers, body));
+  client_->Disconnect();
+  EXPECT_LT(0u, observer.num_window_update_frames());
+  EXPECT_EQ(0u, observer.num_ping_frames());
+  client_connection->set_debug_visitor(nullptr);
+}
+
+TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConfig* config = client_session->config();
+  ASSERT_TRUE(config);
+  EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+  QuicConnection* client_connection = client_session->connection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
+                client_connection->connection_id()),
+            config->ReceivedStatelessResetToken());
+  client_->Disconnect();
+}
+
+// Regression test for b/116200989.
+TEST_P(EndToEndTest,
+       SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+
+  ASSERT_TRUE(server_thread_);
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This cause the first server-sent packet, a.k.a REJ, to fail.
+      new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
+}
+
+// Regression test for b/116200989.
+TEST_P(EndToEndTest,
+       SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
+  // Prevent the connection from expiring in the time wait list.
+  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+
+  // big_response_body is 64K, which is about 48 full-sized packets.
+  const size_t kBigResponseBodySize = 65536;
+  QuicData big_response_body(new char[kBigResponseBodySize](),
+                             kBigResponseBodySize, /*owns_buffer=*/true);
+  AddToCache("/big_response", 200, big_response_body.AsStringPiece());
+
+  ASSERT_TRUE(server_thread_);
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This will cause an server write error with EPERM, while sending the
+      // response for /big_response.
+      new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+
+  // First, a /foo request with small response should succeed.
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Second, a /big_response request with big response should fail.
+  EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
+            kBigResponseBodySize);
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
+}
+
+// Regression test of b/70782529.
+TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
+  ASSERT_TRUE(Initialize());
+  BadPacketWriter* bad_writer =
+      new BadPacketWriter(/*packet_causing_write_error=*/5,
+                          /*error_code=*/90);
+  std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
+
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client->SendCustomSynchronousRequest(headers, body);
+}
+
+// Regression test for b/71711996. This test sends a connectivity probing packet
+// as its last sent packet, and makes sure the server's ACK of that packet does
+// not cause the client to fail.
+TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Wait for the client's ACK (of the response) to be received by the server.
+  client_->WaitForDelayedAcks();
+
+  // We are sending a connectivity probing packet from an unchanged client
+  // address, so the server will not respond to us with a connectivity probing
+  // packet, however the server should send an ack-only packet to us.
+  client_->SendConnectivityProbing();
+
+  // Wait for the server's last ACK to be received by the client.
+  client_->WaitForDelayedAcks();
+}
+
+TEST_P(EndToEndTest, PreSharedKey) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(5));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(5));
+  pre_shared_key_client_ = "foobar";
+  pre_shared_key_server_ = "foobar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC client pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foo";
+  pre_shared_key_server_ = "bar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC client pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  // One of two things happens when Initialize() returns:
+  // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
+  //    returns false.
+  // 2. Crypto handshake has not completed, Initialize() returns true. The call
+  //    to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
+  //    return whether it is successful.
+  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_server_ = "foobar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC server pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
+}
+
+// TODO: reenable once we have a way to make this run faster.
+TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
+  client_config_.set_max_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  client_config_.set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta::FromSeconds(1));
+  pre_shared_key_client_ = "foobar";
+
+  if (version_.UsesTls()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    bool ok = true;
+    EXPECT_QUIC_BUG(ok = Initialize(),
+                    "QUIC client pre-shared keys not yet supported with TLS");
+    EXPECT_FALSE(ok);
+    return;
+  }
+
+  ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
+}
+
+TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
+  // Regression test for b/80234898.
+  ASSERT_TRUE(Initialize());
+
+  // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
+  // (and the FIN) after the response body.
+  std::string response_body(1305, 'a');
+  SpdyHeaderBlock response_headers;
+  response_headers[":status"] = absl::StrCat(200);
+  response_headers["content-length"] = absl::StrCat(response_body.length());
+  memory_cache_backend_.AddSpecialResponse(
+      server_hostname_, "/test_url", std::move(response_headers), response_body,
+      QuicBackendResponse::INCOMPLETE_RESPONSE);
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  client_->WaitForDelayedAcks();
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  const QuicPacketCount packets_sent_before =
+      client_connection->GetStats().packets_sent;
+
+  client_->SendRequestAndRstTogether("/test_url");
+
+  // Expect exactly one packet is sent from the block above.
+  ASSERT_EQ(packets_sent_before + 1,
+            client_connection->GetStats().packets_sent);
+
+  // Wait for the connection to become idle.
+  client_->WaitForDelayedAcks();
+
+  // The real expectation is the test does not crash or timeout.
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+  SetPacketLossPercentage(30);
+
+  QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+  // Set a TTL which expires immediately.
+  stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
+
+  WriteHeadersOnStream(stream);
+  // 1 MB body.
+  std::string body(1024 * 1024, 'a');
+  stream->WriteOrBufferBody(body, true);
+  client_->WaitForResponse();
+  EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_STREAM_TTL_EXPIRED));
+}
+
+TEST_P(EndToEndTest, SendMessages) {
+  if (!version_.SupportsMessageFrames()) {
+    Initialize();
+    return;
+  }
+  ASSERT_TRUE(Initialize());
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  QuicSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicConnection* client_connection = client_session->connection();
+  ASSERT_TRUE(client_connection);
+
+  SetPacketLossPercentage(30);
+  ASSERT_GT(kMaxOutgoingPacketSize,
+            client_session->GetCurrentLargestMessagePayload());
+  ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
+
+  std::string message_string(kMaxOutgoingPacketSize, 'a');
+  QuicRandom* random =
+      QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
+  {
+    QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
+    // Verify the largest message gets successfully sent.
+    EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
+              client_session->SendMessage(MemSliceFromString(absl::string_view(
+                  message_string.data(),
+                  client_session->GetCurrentLargestMessagePayload()))));
+    // Send more messages with size (0, largest_payload] until connection is
+    // write blocked.
+    const int kTestMaxNumberOfMessages = 100;
+    for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
+      size_t message_length =
+          random->RandUint64() %
+              client_session->GetGuaranteedLargestMessagePayload() +
+          1;
+      MessageResult result = client_session->SendMessage(MemSliceFromString(
+          absl::string_view(message_string.data(), message_length)));
+      if (result.status == MESSAGE_STATUS_BLOCKED) {
+        // Connection is write blocked.
+        break;
+      }
+      EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
+    }
+  }
+
+  client_->WaitForDelayedAcks();
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            client_session
+                ->SendMessage(MemSliceFromString(absl::string_view(
+                    message_string.data(),
+                    client_session->GetCurrentLargestMessagePayload() + 1)))
+                .status);
+  EXPECT_THAT(client_->connection_error(), IsQuicNoError());
+}
+
+class EndToEndPacketReorderingTest : public EndToEndTest {
+ public:
+  void CreateClientWithWriter() override {
+    QUIC_LOG(ERROR) << "create client with reorder_writer_";
+    reorder_writer_ = new PacketReorderingWriter();
+    client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
+  }
+
+  void SetUp() override {
+    // Don't initialize client writer in base class.
+    server_writer_ = new PacketDroppingTestWriter();
+  }
+
+ protected:
+  PacketReorderingWriter* reorder_writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
+                         EndToEndPacketReorderingTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
+  ASSERT_TRUE(Initialize());
+  if (version_.HasIetfQuicFrames()) {
+    return;
+  }
+
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr =
+      client_->client()->network_helper()->GetLatestClientAddress();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+  ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
+
+  // Write a connectivity probing after the next /foo request.
+  reorder_writer_->SetDelay(1);
+  client_->SendConnectivityProbing();
+
+  ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
+                                                      old_addr.port()));
+
+  // The (delayed) connectivity probing will be sent after this request.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Send yet another request after the connectivity probing, when this request
+  // returns, the probing is guaranteed to have been received by the server, and
+  // the server's response to probing is guaranteed to have been received by the
+  // client.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(1u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+
+  // Server definitely responded to the connectivity probing. Sometime it also
+  // sends a padded ping that is not a connectivity probing, which is recognized
+  // as connectivity probing because client's self address is ANY.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_LE(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+}
+
+// A writer which holds the next packet to be sent till ReleasePacket() is
+// called.
+class PacketHoldingWriter : public QuicPacketWriterWrapper {
+ public:
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    if (!hold_next_packet_) {
+      return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                  peer_address, options);
+    }
+    QUIC_DLOG(INFO) << "Packet is held by the writer";
+    packet_content_ = std::string(buffer, buf_len);
+    self_address_ = self_address;
+    peer_address_ = peer_address;
+    options_ = (options == nullptr ? nullptr : options->Clone());
+    hold_next_packet_ = false;
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  void HoldNextPacket() {
+    QUICHE_DCHECK(packet_content_.empty())
+        << "There is already one packet on hold.";
+    hold_next_packet_ = true;
+  }
+
+  void ReleasePacket() {
+    QUIC_DLOG(INFO) << "Release packet";
+    ASSERT_EQ(WRITE_STATUS_OK,
+              QuicPacketWriterWrapper::WritePacket(
+                  packet_content_.data(), packet_content_.length(),
+                  self_address_, peer_address_, options_.release())
+                  .status);
+    packet_content_.clear();
+  }
+
+ private:
+  bool hold_next_packet_{false};
+  std::string packet_content_;
+  QuicIpAddress self_address_;
+  QuicSocketAddress peer_address_;
+  std::unique_ptr<PerPacketOptions> options_;
+};
+
+TEST_P(EndToEndTest, ClientValidateNewNetwork) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !GetClientConnection()->validate_client_address()) {
+    return;
+  }
+  client_.reset(EndToEndTest::CreateQuicClient(nullptr));
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Store the client IP address which was used to send the first request.
+  QuicIpAddress old_host =
+      client_->client()->network_helper()->GetLatestClientAddress().host();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_host, new_host);
+
+  client_->client()->ValidateNewNetwork(new_host);
+  // Send a request using the old socket.
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  // Client should have received a PATH_CHALLENGE.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(1u,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  // Send another request to make sure THE server will receive PATH_RESPONSE.
+  client_->SendSynchronousRequest("/eep");
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(1u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndPacketReorderingTest, ReorderedPathChallenge) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->use_path_validator()) {
+    return;
+  }
+  client_.reset(EndToEndTest::CreateQuicClient(nullptr));
+
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr =
+      client_->client()->network_helper()->GetLatestClientAddress();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+
+  // Setup writer wrapper to hold the probing packet.
+  auto holding_writer = new PacketHoldingWriter();
+  client_->UseWriter(holding_writer);
+  // Write a connectivity probing after the next /foo request.
+  holding_writer->HoldNextPacket();
+
+  // A packet with PATH_CHALLENGE will be held in the writer.
+  client_->client()->ValidateNewNetwork(new_host);
+
+  // Send (on-hold) PATH_CHALLENGE after this request.
+  client_->SendRequest("/foo");
+  holding_writer->ReleasePacket();
+
+  client_->WaitForResponse();
+
+  EXPECT_EQ(kFooResponseBody, client_->response_body());
+  // Send yet another request after the PATH_CHALLENGE, when this request
+  // returns, the probing is guaranteed to have been received by the server, and
+  // the server's response to probing is guaranteed to have been received by the
+  // client.
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  // Client should have received a PATH_CHALLENGE.
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(client_connection->validate_client_address() ? 1u : 0,
+            client_connection->GetStats().num_connectivity_probing_received);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(1u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndPacketReorderingTest, PathValidationFailure) {
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames() ||
+      !client_->client()->session()->connection()->use_path_validator()) {
+    return;
+  }
+
+  client_.reset(CreateQuicClient(nullptr));
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress old_addr = client_->client()->session()->self_address();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress new_host = TestLoopback(2);
+  EXPECT_NE(old_addr.host(), new_host);
+
+  // Drop PATH_RESPONSE packets to timeout the path validation.
+  server_writer_->set_fake_packet_loss_percentage(100);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(new_host));
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(old_addr, client_->client()->session()->self_address());
+  server_writer_->set_fake_packet_loss_percentage(0);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(3u,
+              server_connection->GetStats().num_connectivity_probing_received);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndPacketReorderingTest, MigrateAgainAfterPathValidationFailure) {
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+
+  client_.reset(CreateQuicClient(nullptr));
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress addr1 = client_->client()->session()->self_address();
+  QuicConnection* client_connection = GetClientConnection();
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress host2 = TestLoopback(2);
+  EXPECT_NE(addr1.host(), host2);
+
+  // Drop PATH_RESPONSE packets to timeout the path validation.
+  server_writer_->set_fake_packet_loss_percentage(100);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
+
+  QuicConnectionId server_cid2 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid2, server_cid1);
+  // Wait until path validation fails at the client.
+  while (client_->client()->HasPendingPathValidation()) {
+    EXPECT_EQ(server_cid2,
+              QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection));
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(addr1, client_->client()->session()->self_address());
+  EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
+
+  server_writer_->set_fake_packet_loss_percentage(0);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  // Server has received 3 path challenges.
+  EXPECT_EQ(3u,
+            server_connection->GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(server_cid1, server_connection->connection_id());
+  EXPECT_EQ(0u, server_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+
+  // Migrate socket to a new IP address again.
+  QuicIpAddress host3 = TestLoopback(3);
+  EXPECT_NE(addr1.host(), host3);
+  EXPECT_NE(host2, host3);
+
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
+
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
+  QuicConnectionId server_cid3 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host3, client_->client()->session()->self_address().host());
+  EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  // Server should send a new connection ID to client.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(0u, client_connection->GetStats().num_new_connection_id_sent);
+}
+
+TEST_P(EndToEndPacketReorderingTest,
+       MigrateAgainAfterPathValidationFailureWithNonZeroClientCid) {
+  if (!version_.SupportsClientConnectionIds()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  SetQuicReloadableFlag(quic_retire_cid_on_reverse_path_validation_failure,
+                        true);
+  override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
+  ASSERT_TRUE(Initialize());
+  if (!GetClientConnection()->connection_migration_use_new_cid()) {
+    return;
+  }
+
+  client_.reset(CreateQuicClient(nullptr));
+  // Finish one request to make sure handshake established.
+  EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+
+  // Wait for the connection to become idle, to make sure the packet gets
+  // delayed is the connectivity probing packet.
+  client_->WaitForDelayedAcks();
+
+  QuicSocketAddress addr1 = client_->client()->session()->self_address();
+  QuicConnection* client_connection = GetClientConnection();
+  QuicConnectionId server_cid1 = client_connection->connection_id();
+  QuicConnectionId client_cid1 = client_connection->client_connection_id();
+
+  // Migrate socket to the new IP address.
+  QuicIpAddress host2 = TestLoopback(2);
+  EXPECT_NE(addr1.host(), host2);
+
+  // Drop PATH_RESPONSE packets to timeout the path validation.
+  server_writer_->set_fake_packet_loss_percentage(100);
+  ASSERT_TRUE(
+      QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(client_connection));
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host2));
+  QuicConnectionId server_cid2 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid2.IsEmpty());
+  EXPECT_NE(server_cid2, server_cid1);
+  QuicConnectionId client_cid2 =
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(client_cid2.IsEmpty());
+  EXPECT_NE(client_cid2, client_cid1);
+  while (client_->client()->HasPendingPathValidation()) {
+    EXPECT_EQ(server_cid2,
+              QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection));
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(addr1, client_->client()->session()->self_address());
+  EXPECT_EQ(server_cid1, GetClientConnection()->connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  server_writer_->set_fake_packet_loss_percentage(0);
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+  WaitForNewConnectionIds();
+  EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, client_connection->GetStats().num_new_connection_id_sent);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection != nullptr) {
+    EXPECT_EQ(3u,
+              server_connection->GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(server_cid1, server_connection->connection_id());
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  EXPECT_EQ(1u, server_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(2u, server_connection->GetStats().num_new_connection_id_sent);
+  server_thread_->Resume();
+
+  // Migrate socket to a new IP address again.
+  QuicIpAddress host3 = TestLoopback(3);
+  EXPECT_NE(addr1.host(), host3);
+  EXPECT_NE(host2, host3);
+  ASSERT_TRUE(client_->client()->ValidateAndMigrateSocket(host3));
+
+  QuicConnectionId server_cid3 =
+      QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_FALSE(server_cid3.IsEmpty());
+  EXPECT_NE(server_cid1, server_cid3);
+  EXPECT_NE(server_cid2, server_cid3);
+  QuicConnectionId client_cid3 =
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+          client_connection);
+  EXPECT_NE(client_cid1, client_cid3);
+  EXPECT_NE(client_cid2, client_cid3);
+  while (client_->client()->HasPendingPathValidation()) {
+    client_->client()->WaitForEvents();
+  }
+  EXPECT_EQ(host3, client_->client()->session()->self_address().host());
+  EXPECT_EQ(server_cid3, GetClientConnection()->connection_id());
+  EXPECT_TRUE(QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+                  client_connection)
+                  .IsEmpty());
+  EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
+
+  // Server should send new server connection ID to client and retires old
+  // client connection ID.
+  WaitForNewConnectionIds();
+  EXPECT_EQ(2u, client_connection->GetStats().num_retire_connection_id_sent);
+  EXPECT_EQ(3u, client_connection->GetStats().num_new_connection_id_sent);
+}
+
+TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
+  ASSERT_TRUE(Initialize());
+  // Finish one request to make sure handshake established.
+  client_->SendSynchronousRequest("/foo");
+  // Disconnect for next 0-rtt request.
+  client_->Disconnect();
+
+  // Client get valid STK now. Do a 0-rtt request.
+  // Buffer a CHLO till another packets sent out.
+  reorder_writer_->SetDelay(1);
+  // Only send out a CHLO.
+  client_->client()->Initialize();
+  client_->client()->StartConnect();
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+  ASSERT_TRUE(client_->client()->connected());
+
+  // Send a request before handshake finishes.
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/bar";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  client_->SendMessage(headers, "");
+  client_->WaitForResponse();
+  EXPECT_EQ(kBarResponseBody, client_->response_body());
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  QuicConnectionStats client_stats = client_connection->GetStats();
+  // Client sends CHLO in packet 1 and retransmitted in packet 2. Because of
+  // the delay, server processes packet 2 and later drops packet 1. ACK is
+  // bundled with SHLO, such that 1 can be detected loss by time threshold.
+  EXPECT_LE(0u, client_stats.packets_lost);
+  EXPECT_TRUE(client_->client()->EarlyDataAccepted());
+}
+
+TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
+  ASSERT_TRUE(Initialize());
+
+  // Send a request without a fin, to keep the stream open
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+  client_->SendMessage(headers, "", /*fin=*/false);
+  // Stream should be open
+  ASSERT_NE(nullptr, client_->latest_created_stream());
+  EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
+  EXPECT_FALSE(
+      QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
+
+  // Send a RST_STREAM+STOP_SENDING on the stream
+  // Code is not important.
+  client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  client_->WaitForResponse();
+
+  // Stream should be gone.
+  ASSERT_EQ(nullptr, client_->latest_created_stream());
+}
+
+class BadShloPacketWriter : public QuicPacketWriterWrapper {
+ public:
+  BadShloPacketWriter(ParsedQuicVersion version)
+      : error_returned_(false), version_(version) {}
+  ~BadShloPacketWriter() override {}
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    const WriteResult result = QuicPacketWriterWrapper::WritePacket(
+        buffer, buf_len, self_address, peer_address, options);
+    const uint8_t type_byte = buffer[0];
+    if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
+        TypeByteIsServerHello(type_byte)) {
+      QUIC_DVLOG(1) << "Return write error for packet containing ServerHello";
+      error_returned_ = true;
+      return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
+    }
+    return result;
+  }
+
+  bool TypeByteIsServerHello(uint8_t type_byte) {
+    if (version_.UsesV2PacketTypes()) {
+      return ((type_byte & 0x30) >> 4) == 3;
+    }
+    if (version_.UsesQuicCrypto()) {
+      // ENCRYPTION_ZERO_RTT packet.
+      return ((type_byte & 0x30) >> 4) == 1;
+    }
+    // ENCRYPTION_HANDSHAKE packet.
+    return ((type_byte & 0x30) >> 4) == 2;
+  }
+
+ private:
+  bool error_returned_;
+  ParsedQuicVersion version_;
+};
+
+TEST_P(EndToEndTest, ConnectionCloseBeforeHandshakeComplete) {
+  if (!version_.HasIetfInvariantHeader()) {
+    // Only runs for IETF QUIC header.
+    Initialize();
+    return;
+  }
+  // This test ensures ZERO_RTT_PROTECTED connection close could close a client
+  // which has switched to forward secure.
+  connect_to_server_on_initialize_ = false;
+  ASSERT_TRUE(Initialize());
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
+      // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
+      // ZERO_RTT_PROTECTED connection close would be sent to a client with
+      // encryption level FORWARD_SECURE.
+      new BadShloPacketWriter(version_));
+  server_thread_->Resume();
+
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
+  // client which switches to FORWARD_SECURE.
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
+ public:
+  BadShloPacketWriter2(ParsedQuicVersion version)
+      : error_returned_(false), version_(version) {}
+  ~BadShloPacketWriter2() override {}
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          quic::PerPacketOptions* options) override {
+    const uint8_t type_byte = buffer[0];
+
+    if (type_byte & FLAGS_LONG_HEADER) {
+      if (((type_byte & 0x30 >> 4) == (version_.UsesV2PacketTypes() ? 2 : 1)) ||
+          ((type_byte & 0x7F) == 0x7C)) {
+        QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
+        return WriteResult(WRITE_STATUS_OK, buf_len);
+      }
+    } else if (!error_returned_) {
+      QUIC_DVLOG(1) << "Return write error for short header packet";
+      error_returned_ = true;
+      return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
+    }
+    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                peer_address, options);
+  }
+
+ private:
+  bool error_returned_;
+  ParsedQuicVersion version_;
+};
+
+TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
+  // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
+  // which has ZERO_RTT_PROTECTED encryption level.
+  connect_to_server_on_initialize_ = !version_.HasIetfInvariantHeader();
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfInvariantHeader()) {
+    // Only runs for IETF QUIC header.
+    return;
+  }
+  server_thread_->Pause();
+  QuicDispatcher* dispatcher =
+      QuicServerPeer::GetDispatcher(server_thread_->server());
+  if (dispatcher == nullptr) {
+    ADD_FAILURE() << "Missing dispatcher";
+    server_thread_->Resume();
+    return;
+  }
+  if (dispatcher->NumSessions() > 0) {
+    ADD_FAILURE() << "Dispatcher session map not empty";
+    server_thread_->Resume();
+    return;
+  }
+  // Note: this writer will only used by the server connection, not the time
+  // wait list.
+  QuicDispatcherPeer::UseWriter(
+      dispatcher,
+      // This causes the all server sent ZERO_RTT_PROTECTED packets to be
+      // dropped, and first short header packet causes write error.
+      new BadShloPacketWriter2(version_));
+  server_thread_->Resume();
+  client_.reset(CreateQuicClient(client_writer_));
+  EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
+  // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
+  // client.
+  EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+// Test that the stream id manager closes the connection if a stream
+// in excess of the allowed maximum.
+TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
+  // Has to be before version test, see EndToEndTest::TearDown()
+  ASSERT_TRUE(Initialize());
+  if (!version_.HasIetfQuicFrames()) {
+    // Only runs for IETF QUIC.
+    return;
+  }
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  std::string body(kMaxOutgoingPacketSize, 'a');
+  SpdyHeaderBlock headers;
+  headers[":method"] = "POST";
+  headers[":path"] = "/foo";
+  headers[":scheme"] = "https";
+  headers[":authority"] = server_hostname_;
+
+  // Force the client to write with a stream ID that exceeds the limit.
+  QuicSpdySession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  QuicStreamIdManager* stream_id_manager =
+      QuicSessionPeer::ietf_bidirectional_stream_id_manager(client_session);
+  ASSERT_TRUE(stream_id_manager);
+  QuicStreamCount max_number_of_streams =
+      stream_id_manager->outgoing_max_streams();
+  QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
+      client_session,
+      GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
+  client_->SendCustomSynchronousRequest(headers, body);
+  EXPECT_THAT(client_->stream_error(),
+              IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
+  EXPECT_THAT(client_session->error(), IsError(QUIC_INVALID_STREAM_ID));
+  EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, client_session->close_type());
+  EXPECT_TRUE(
+      IS_IETF_STREAM_FRAME(client_session->transport_close_frame_type()));
+}
+
+TEST_P(EndToEndTest, CustomTransportParameters) {
+  if (!version_.UsesTls()) {
+    // Custom transport parameters are only supported with TLS.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  constexpr auto kCustomParameter =
+      static_cast<TransportParameters::TransportParameterId>(0xff34);
+  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
+      "test";
+  NiceMock<MockQuicConnectionDebugVisitor> visitor;
+  connection_debug_visitor_ = &visitor;
+  EXPECT_CALL(visitor, OnTransportParametersSent(_))
+      .WillOnce(Invoke([kCustomParameter](
+                           const TransportParameters& transport_parameters) {
+        ASSERT_NE(transport_parameters.custom_parameters.find(kCustomParameter),
+                  transport_parameters.custom_parameters.end());
+        EXPECT_EQ(transport_parameters.custom_parameters.at(kCustomParameter),
+                  "test");
+      }));
+  EXPECT_CALL(visitor, OnTransportParametersReceived(_)).Times(1);
+  ASSERT_TRUE(Initialize());
+
+  EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  QuicConfig* server_config = nullptr;
+  if (server_session != nullptr) {
+    server_config = server_session->config();
+  } else {
+    ADD_FAILURE() << "Missing server session";
+  }
+  if (server_config != nullptr) {
+    if (server_config->received_custom_transport_parameters().find(
+            kCustomParameter) !=
+        server_config->received_custom_transport_parameters().end()) {
+      EXPECT_EQ(server_config->received_custom_transport_parameters().at(
+                    kCustomParameter),
+                "test");
+    } else {
+      ADD_FAILURE() << "Did not find custom parameter";
+    }
+  } else {
+    ADD_FAILURE() << "Missing server config";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  if (!version_.UsesTls()) {
+    // This test uses custom transport parameters to increase the size of the
+    // CHLO, and those are only supported with TLS.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  constexpr auto kCustomParameter =
+      static_cast<TransportParameters::TransportParameterId>(0xff34);
+  client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
+      std::string(2000, '?');
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  client_supported_versions_.insert(client_supported_versions_.begin(),
+                                    QuicVersionReservedForNegotiation());
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  SetPacketLossPercentage(30);
+  client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  // Disable blackhole detection as this test is testing loss recovery.
+  client_extra_copts_.push_back(kNBHD);
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_GT(
+      client_connection->GetStats().sent_legacy_version_encapsulated_packets,
+      0u);
+}
+
+// Testing packet writer that makes a copy of the first sent packets before
+// sending them. Useful for tests that need access to sent packets.
+class CopyingPacketWriter : public PacketDroppingTestWriter {
+ public:
+  explicit CopyingPacketWriter(int num_packets_to_copy)
+      : num_packets_to_copy_(num_packets_to_copy) {}
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    if (num_packets_to_copy_ > 0) {
+      num_packets_to_copy_--;
+      packets_.push_back(
+          QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
+    }
+    return PacketDroppingTestWriter::WritePacket(buffer, buf_len, self_address,
+                                                 peer_address, options);
+  }
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>& packets() {
+    return packets_;
+  }
+
+ private:
+  int num_packets_to_copy_;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
+};
+
+TEST_P(EndToEndTest, ChaosProtectionDisabled) {
+  if (!version_.UsesCryptoFrames()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Replace the client's writer with one that'll save the first packet.
+  auto copying_writer = new CopyingPacketWriter(1);
+  delete client_writer_;
+  client_writer_ = copying_writer;
+  // Disable chaos protection and perform an HTTP request.
+  client_config_.SetClientConnectionOptions(QuicTagVector{kNCHP});
+  ASSERT_TRUE(Initialize());
+  SendSynchronousFooRequestAndCheckResponse();
+  // Parse the saved packet to make sure it's valid.
+  SimpleQuicFramer validation_framer({version_});
+  validation_framer.framer()->SetInitialObfuscators(
+      GetClientConnection()->connection_id());
+  ASSERT_GT(copying_writer->packets().size(), 0u);
+  EXPECT_TRUE(validation_framer.ProcessPacket(*copying_writer->packets()[0]));
+  // TODO(dschinazi) figure out a way to use a MockRandom in this test so we
+  // can inspect the contents of this packet.
+}
+
+TEST_P(EndToEndTest, DisablePermuteTlsExtensions) {
+  if (!version_.UsesTls()) {
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+  // Disable TLS extension permutation and perform an HTTP request.
+  client_config_.SetClientConnectionOptions(QuicTagVector{kNBPE});
+  ASSERT_TRUE(Initialize());
+  EXPECT_FALSE(GetClientSession()->permutes_tls_extensions());
+  SendSynchronousFooRequestAndCheckResponse();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByClient) {
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
+
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(2u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByServer) {
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
+
+  // Use WaitUntil to ensure the server had executed the key update predicate
+  // before sending the Foo request, otherwise the test can be flaky if it
+  // receives the Foo request before executing the key update.
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            // Server may not have received ack from client yet for the current
+            // key phase, wait a bit and try again.
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(2u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByBoth) {
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  SendSynchronousFooRequestAndCheckResponse();
+
+  // Use WaitUntil to ensure the server had executed the key update predicate
+  // before the client sends the Foo request, otherwise the Foo request from
+  // the client could trigger the server key update before the server can
+  // initiate the key update locally. That would mean the test is no longer
+  // hitting the intended test state of both sides locally initiating a key
+  // update before receiving a packet in the new key phase from the other side.
+  // Additionally the test would fail since InitiateKeyUpdate() would not allow
+  // to do another key update yet and return false.
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            // Server may not have received ack from client yet for the current
+            // key phase, wait a bit and try again.
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(1u, client_connection->GetStats().key_update_count);
+
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          if (!server_connection->IsKeyUpdateAllowed()) {
+            return false;
+          }
+          EXPECT_TRUE(server_connection->InitiateKeyUpdate(
+              KeyUpdateReason::kLocalForTests));
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  EXPECT_TRUE(
+      client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  SendSynchronousFooRequestAndCheckResponse();
+  EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_EQ(2u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, KeyUpdateInitiatedByConfidentialityLimit) {
+  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 16U);
+
+  if (!version_.UsesTls()) {
+    // Key Update is only supported in TLS handshake.
+    ASSERT_TRUE(Initialize());
+    return;
+  }
+
+  ASSERT_TRUE(Initialize());
+
+  QuicConnection* client_connection = GetClientConnection();
+  ASSERT_TRUE(client_connection);
+  EXPECT_EQ(0u, client_connection->GetStats().key_update_count);
+
+  server_thread_->WaitUntil(
+      [this]() {
+        QuicConnection* server_connection = GetServerConnection();
+        if (server_connection != nullptr) {
+          EXPECT_EQ(0u, server_connection->GetStats().key_update_count);
+        } else {
+          ADD_FAILURE() << "Missing server connection";
+        }
+        return true;
+      },
+      QuicTime::Delta::FromSeconds(5));
+
+  for (uint64_t i = 0;
+       i < GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit); ++i) {
+    SendSynchronousFooRequestAndCheckResponse();
+  }
+
+  // Don't know exactly how many packets will be sent in each request/response,
+  // so just test that at least one key update occurred.
+  EXPECT_LE(1u, client_connection->GetStats().key_update_count);
+
+  server_thread_->Pause();
+  QuicConnection* server_connection = GetServerConnection();
+  if (server_connection) {
+    QuicConnectionStats server_stats = server_connection->GetStats();
+    EXPECT_LE(1u, server_stats.key_update_count);
+  } else {
+    ADD_FAILURE() << "Missing server connection";
+  }
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, TlsResumptionEnabledOnTheFly) {
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    return;
+  }
+
+  // Send the first request. Client should not have a resumption ticket.
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+            ssl_early_data_no_session_offered);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
+
+  // Send the second request. Client should still have no resumption ticket, but
+  // it will receive one which can be used by the next request.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+            ssl_early_data_no_session_offered);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  // Send the third request in 0RTT.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+}
+
+TEST_P(EndToEndTest, TlsResumptionDisabledOnTheFly) {
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, false);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesTls()) {
+    // This test is TLS specific.
+    return;
+  }
+
+  // Send the first request and then disconnect.
+  SendSynchronousFooRequestAndCheckResponse();
+  QuicSpdyClientSession* client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  // Send the second request in 0RTT.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_TRUE(client_session->EarlyDataAccepted());
+  client_->Disconnect();
+
+  SetQuicFlag(FLAGS_quic_disable_server_tls_resumption, true);
+
+  // Send the third request. The client should try resumption but server should
+  // decline it.
+  client_->Connect();
+  SendSynchronousFooRequestAndCheckResponse();
+
+  client_session = GetClientSession();
+  ASSERT_TRUE(client_session);
+  EXPECT_FALSE(client_session->EarlyDataAccepted());
+  EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+            ssl_early_data_session_not_resumed);
+  client_->Disconnect();
+
+  // Keep sending until the client runs out of resumption tickets.
+  for (int i = 0; i < 10; ++i) {
+    client_->Connect();
+    SendSynchronousFooRequestAndCheckResponse();
+
+    client_session = GetClientSession();
+    ASSERT_TRUE(client_session);
+    EXPECT_FALSE(client_session->EarlyDataAccepted());
+    const auto early_data_reason =
+        client_session->GetCryptoStream()->EarlyDataReason();
+    client_->Disconnect();
+
+    if (early_data_reason != ssl_early_data_session_not_resumed) {
+      EXPECT_EQ(early_data_reason, ssl_early_data_unsupported_for_session);
+      return;
+    }
+  }
+
+  ADD_FAILURE() << "Client should not have 10 resumption tickets.";
+}
+
+TEST_P(EndToEndTest, WebTransportSessionSetup) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* web_transport =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_NE(web_transport, nullptr);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
+              nullptr);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, WebTransportSessionSetupWithEchoWithSuffix) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  // "/echoFoo" should be accepted as "echo" with "set-header" query.
+  WebTransportHttp3* web_transport = CreateWebTransportSession(
+      "/echoFoo?set-header=bar:baz", /*wait_for_server_response=*/true);
+  ASSERT_NE(web_transport, nullptr);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
+              nullptr);
+  server_thread_->Resume();
+  const spdy::SpdyHeaderBlock* response_headers = client_->response_headers();
+  auto it = response_headers->find("bar");
+  EXPECT_NE(it, response_headers->end());
+  EXPECT_EQ(it->second, "baz");
+}
+
+TEST_P(EndToEndTest, WebTransportSessionWithLoss) {
+  enable_web_transport_ = true;
+  // Enable loss to verify all permutations of receiving SETTINGS and
+  // request/response data.
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* web_transport =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_NE(web_transport, nullptr);
+
+  server_thread_->Pause();
+  QuicSpdySession* server_session = GetServerSession();
+  EXPECT_TRUE(server_session->GetWebTransportSession(web_transport->id()) !=
+              nullptr);
+  server_thread_->Resume();
+}
+
+TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStream) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* outgoing_stream =
+      session->OpenOutgoingUnidirectionalStream();
+  ASSERT_TRUE(outgoing_stream != nullptr);
+
+  auto stream_visitor = std::make_unique<NiceMock<MockStreamVisitor>>();
+  bool data_acknowledged = false;
+  EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
+      .WillOnce(Assign(&data_acknowledged, true));
+  outgoing_stream->SetVisitor(std::move(stream_visitor));
+
+  EXPECT_TRUE(outgoing_stream->Write("test"));
+  EXPECT_TRUE(outgoing_stream->SendFin());
+
+  bool stream_received = false;
+  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
+      .WillOnce(Assign(&stream_received, true));
+  client_->WaitUntil(2000, [&stream_received]() { return stream_received; });
+  EXPECT_TRUE(stream_received);
+  WebTransportStream* received_stream =
+      session->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(received_stream != nullptr);
+  std::string received_data;
+  WebTransportStream::ReadResult result = received_stream->Read(&received_data);
+  EXPECT_EQ(received_data, "test");
+  EXPECT_TRUE(result.fin);
+
+  client_->WaitUntil(2000,
+                     [&data_acknowledged]() { return data_acknowledged; });
+  EXPECT_TRUE(data_acknowledged);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionUnidirectionalStreamSentEarly) {
+  enable_web_transport_ = true;
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* outgoing_stream =
+      session->OpenOutgoingUnidirectionalStream();
+  ASSERT_TRUE(outgoing_stream != nullptr);
+  EXPECT_TRUE(outgoing_stream->Write("test"));
+  EXPECT_TRUE(outgoing_stream->SendFin());
+
+  bool stream_received = false;
+  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
+      .WillOnce(Assign(&stream_received, true));
+  client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
+  EXPECT_TRUE(stream_received);
+  WebTransportStream* received_stream =
+      session->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(received_stream != nullptr);
+  std::string received_data;
+  WebTransportStream::ReadResult result = received_stream->Read(&received_data);
+  EXPECT_EQ(received_data, "test");
+  EXPECT_TRUE(result.fin);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionBidirectionalStream) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+
+  auto stream_visitor_owned = std::make_unique<NiceMock<MockStreamVisitor>>();
+  MockStreamVisitor* stream_visitor = stream_visitor_owned.get();
+  bool data_acknowledged = false;
+  EXPECT_CALL(*stream_visitor, OnWriteSideInDataRecvdState())
+      .WillOnce(Assign(&data_acknowledged, true));
+  stream->SetVisitor(std::move(stream_visitor_owned));
+
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  std::string received_data =
+      ReadDataFromWebTransportStreamUntilFin(stream, stream_visitor);
+  EXPECT_EQ(received_data, "test");
+
+  client_->WaitUntil(2000,
+                     [&data_acknowledged]() { return data_acknowledged; });
+  EXPECT_TRUE(data_acknowledged);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionBidirectionalStreamWithBuffering) {
+  enable_web_transport_ = true;
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
+  EXPECT_EQ(received_data, "test");
+}
+
+TEST_P(EndToEndTest, WebTransportSessionServerBidirectionalStream) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  bool stream_received = false;
+  EXPECT_CALL(visitor, OnIncomingBidirectionalStreamAvailable())
+      .WillOnce(Assign(&stream_received, true));
+  client_->WaitUntil(5000, [&stream_received]() { return stream_received; });
+  EXPECT_TRUE(stream_received);
+
+  WebTransportStream* stream = session->AcceptIncomingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
+  EXPECT_EQ(received_data, "test");
+}
+
+TEST_P(EndToEndTest, WebTransportDatagrams) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  quiche::SimpleBufferAllocator allocator;
+  for (int i = 0; i < 10; i++) {
+    session->SendOrQueueDatagram(MemSliceFromString("test"));
+  }
+
+  int received = 0;
+  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
+    received++;
+  });
+  client_->WaitUntil(5000, [&received]() { return received > 0; });
+  EXPECT_GT(received, 0);
+}
+
+TEST_P(EndToEndTest, WebTransportDatagramsWithContexts) {
+  enable_web_transport_ = true;
+  use_datagram_contexts_ = true;
+  SetPacketLossPercentage(30);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  QuicSpdyStream* connect_stream = nullptr;
+  WebTransportHttp3* session = CreateWebTransportSession(
+      "/echo", /*wait_for_server_response=*/true, &connect_stream);
+  ASSERT_TRUE(session != nullptr);
+  ASSERT_TRUE(connect_stream != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  quiche::SimpleBufferAllocator allocator;
+  for (int i = 0; i < 10; i++) {
+    session->SendOrQueueDatagram(MemSliceFromString("test"));
+  }
+
+  int received = 0;
+  EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
+    received++;
+  });
+  client_->WaitUntil(5000, [&received]() { return received > 0; });
+  EXPECT_GT(received, 0);
+  EXPECT_TRUE(QuicSpdyStreamPeer::use_datagram_contexts(connect_stream));
+}
+
+TEST_P(EndToEndTest, WebTransportSessionClose) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+  EXPECT_TRUE(stream->Write("test"));
+  // Keep stream open.
+
+  bool close_received = false;
+  EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
+      .WillOnce(Assign(&close_received, true));
+  session->CloseSession(42, "test error");
+  client_->WaitUntil(2000, [&]() { return close_received; });
+  EXPECT_TRUE(close_received);
+
+  QuicSpdyStream* spdy_stream =
+      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
+  EXPECT_TRUE(spdy_stream == nullptr);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionCloseWithoutCapsule) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/echo", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+  EXPECT_TRUE(stream->Write("test"));
+  // Keep stream open.
+
+  bool close_received = false;
+  EXPECT_CALL(visitor, OnSessionClosed(0, ""))
+      .WillOnce(Assign(&close_received, true));
+  session->CloseSessionWithFinOnlyForTests();
+  client_->WaitUntil(2000, [&]() { return close_received; });
+  EXPECT_TRUE(close_received);
+
+  QuicSpdyStream* spdy_stream =
+      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
+  EXPECT_TRUE(spdy_stream == nullptr);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionReceiveClose) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session = CreateWebTransportSession(
+      "/session-close", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+
+  WebTransportStream* stream = session->OpenOutgoingUnidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+  EXPECT_TRUE(stream->Write("42 test error"));
+  EXPECT_TRUE(stream->SendFin());
+
+  // Have some other streams open pending, to ensure they are closed properly.
+  stream = session->OpenOutgoingUnidirectionalStream();
+  stream = session->OpenOutgoingBidirectionalStream();
+
+  bool close_received = false;
+  EXPECT_CALL(visitor, OnSessionClosed(42, "test error"))
+      .WillOnce(Assign(&close_received, true));
+  client_->WaitUntil(2000, [&]() { return close_received; });
+  EXPECT_TRUE(close_received);
+
+  QuicSpdyStream* spdy_stream =
+      GetClientSession()->GetOrCreateSpdyDataStream(stream_id);
+  EXPECT_TRUE(spdy_stream == nullptr);
+}
+
+TEST_P(EndToEndTest, WebTransportSessionStreamTermination) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session =
+      CreateWebTransportSession("/resets", /*wait_for_server_response=*/true);
+  ASSERT_TRUE(session != nullptr);
+
+  NiceMock<MockClientVisitor>& visitor = SetupWebTransportVisitor(session);
+  EXPECT_CALL(visitor, OnIncomingUnidirectionalStreamAvailable())
+      .WillRepeatedly([this, session]() {
+        ReadAllIncomingWebTransportUnidirectionalStreams(session);
+      });
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  QuicStreamId id1 = stream->GetStreamId();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  stream->ResetWithUserCode(42);
+
+  // This read fails if the stream is closed in both directions, since that
+  // results in stream object being deleted.
+  std::string received_data = ReadDataFromWebTransportStreamUntilFin(stream);
+  EXPECT_LE(received_data.size(), 4u);
+
+  stream = session->OpenOutgoingBidirectionalStream();
+  QuicStreamId id2 = stream->GetStreamId();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  stream->SendStopSending(24);
+
+  std::array<std::string, 2> expected_log = {
+      absl::StrCat("Received reset for stream ", id1, " with error code 42"),
+      absl::StrCat("Received stop sending for stream ", id2,
+                   " with error code 24"),
+  };
+  client_->WaitUntil(2000, [this, &expected_log]() {
+    return received_webtransport_unidirectional_streams_.size() >=
+           expected_log.size();
+  });
+  EXPECT_THAT(received_webtransport_unidirectional_streams_,
+              UnorderedElementsAreArray(expected_log));
+
+  // Since we closed the read side, cleanly closing the write side should result
+  // in the stream getting deleted.
+  ASSERT_TRUE(GetClientSession()->GetOrCreateSpdyDataStream(id2) != nullptr);
+  EXPECT_TRUE(stream->SendFin());
+  EXPECT_TRUE(client_->WaitUntil(2000, [this, id2]() {
+    return GetClientSession()->GetOrCreateSpdyDataStream(id2) == nullptr;
+  }));
+}
+
+TEST_P(EndToEndTest, WebTransportSession404) {
+  enable_web_transport_ = true;
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+
+  WebTransportHttp3* session = CreateWebTransportSession(
+      "/does-not-exist", /*wait_for_server_response=*/false);
+  ASSERT_TRUE(session != nullptr);
+  QuicSpdyStream* connect_stream = client_->latest_created_stream();
+  QuicStreamId connect_stream_id = connect_stream->id();
+
+  WebTransportStream* stream = session->OpenOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_TRUE(stream->Write("test"));
+  EXPECT_TRUE(stream->SendFin());
+
+  EXPECT_TRUE(client_->WaitUntil(-1, [this, connect_stream_id]() {
+    return GetClientSession()->GetOrCreateSpdyDataStream(connect_stream_id) ==
+           nullptr;
+  }));
+}
+
+TEST_P(EndToEndTest, InvalidExtendedConnect) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+  // Missing :path header.
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "webtransport";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  // An early response should be received.
+  CheckResponseHeaders("400");
+}
+
+TEST_P(EndToEndTest, RejectExtendedConnect) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // Disable extended CONNECT.
+  memory_cache_backend_.set_enable_extended_connect(false);
+  ASSERT_TRUE(Initialize());
+
+  if (!version_.UsesHttp3()) {
+    return;
+  }
+  // This extended CONNECT should be rejected.
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "CONNECT";
+  headers[":path"] = "/echo";
+  headers[":protocol"] = "webtransport";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+
+  // Vanilla CONNECT should be accepted.
+  spdy::SpdyHeaderBlock headers2;
+  headers2[":authority"] = "localhost";
+  headers2[":method"] = "CONNECT";
+
+  client_->SendMessage(headers2, "body", /*fin=*/true);
+  client_->WaitForResponse();
+  // No :path header, so 404.
+  CheckResponseHeaders("404");
+}
+
+TEST_P(EndToEndTest, RejectInvalidRequestHeader) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "GET";
+  headers[":path"] = "/echo";
+  // transfer-encoding header is not allowed.
+  headers["transfer-encoding"] = "chunk";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+}
+
+TEST_P(EndToEndTest, RejectTransferEncodingResponse) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  // Add a response with transfer-encoding headers.
+  SpdyHeaderBlock headers;
+  headers[":status"] = "200";
+  headers["transfer-encoding"] = "gzip";
+
+  SpdyHeaderBlock trailers;
+  trailers["some-trailing-header"] = "trailing-header-value";
+
+  memory_cache_backend_.AddResponse(server_hostname_, "/eep",
+                                    std::move(headers), "", trailers.Clone());
+
+  std::string received_response = client_->SendSynchronousRequest("/eep");
+  EXPECT_THAT(client_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(EndToEndTest, RejectUpperCaseRequest) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "GET";
+  headers[":path"] = "/echo";
+  headers["UpperCaseHeader"] = "foo";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+}
+
+TEST_P(EndToEndTest, RejectRequestWithInvalidToken) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  ASSERT_TRUE(Initialize());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":scheme"] = "https";
+  headers[":authority"] = "localhost";
+  headers[":method"] = "GET";
+  headers[":path"] = "/echo";
+  headers["invalid,header"] = "foo";
+
+  client_->SendMessage(headers, "", /*fin=*/false);
+  client_->WaitForResponse();
+  CheckResponseHeaders("400");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_constants.cc b/quiche/quic/core/http/http_constants.cc
new file mode 100644
index 0000000..ea372cd
--- /dev/null
+++ b/quiche/quic/core/http/http_constants.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/http_constants.h"
+
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+std::string H3SettingsToString(Http3AndQpackSettingsIdentifiers identifier) {
+  switch (identifier) {
+    RETURN_STRING_LITERAL(SETTINGS_QPACK_MAX_TABLE_CAPACITY);
+    RETURN_STRING_LITERAL(SETTINGS_MAX_FIELD_SECTION_SIZE);
+    RETURN_STRING_LITERAL(SETTINGS_QPACK_BLOCKED_STREAMS);
+    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT00);
+    RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT04);
+    RETURN_STRING_LITERAL(SETTINGS_WEBTRANS_DRAFT00);
+    RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
+  }
+  return absl::StrCat("UNSUPPORTED_SETTINGS_TYPE(", identifier, ")");
+}
+
+const absl::string_view kUserAgentHeaderName = "user-agent";
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_constants.h b/quiche/quic/core/http/http_constants.h
new file mode 100644
index 0000000..097b2a3
--- /dev/null
+++ b/quiche/quic/core/http/http_constants.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Unidirectional stream types.
+enum : uint64_t {
+  // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#unidirectional-streams
+  kControlStream = 0x00,
+  kServerPushStream = 0x01,
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#enc-dec-stream-def
+  kQpackEncoderStream = 0x02,
+  kQpackDecoderStream = 0x03,
+  // https://ietf-wg-webtrans.github.io/draft-ietf-webtrans-http3/draft-ietf-webtrans-http3.html#name-unidirectional-streams
+  kWebTransportUnidirectionalStream = 0x54,
+};
+
+// This includes control stream, QPACK encoder stream, and QPACK decoder stream.
+enum : QuicStreamCount { kHttp3StaticUnidirectionalStreamCount = 3 };
+
+// HTTP/3 and QPACK settings identifiers.
+// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#settings-parameters
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#configuration
+enum Http3AndQpackSettingsIdentifiers : uint64_t {
+  // Same value as spdy::SETTINGS_HEADER_TABLE_SIZE.
+  SETTINGS_QPACK_MAX_TABLE_CAPACITY = 0x01,
+  // Same value as spdy::SETTINGS_MAX_HEADER_LIST_SIZE.
+  SETTINGS_MAX_FIELD_SECTION_SIZE = 0x06,
+  SETTINGS_QPACK_BLOCKED_STREAMS = 0x07,
+  // draft-ietf-masque-h3-datagram-00.
+  SETTINGS_H3_DATAGRAM_DRAFT00 = 0x276,
+  // draft-ietf-masque-h3-datagram-04.
+  SETTINGS_H3_DATAGRAM_DRAFT04 = 0xffd277,
+  // draft-ietf-webtrans-http3-00
+  SETTINGS_WEBTRANS_DRAFT00 = 0x2b603742,
+  // draft-ietf-httpbis-h3-websockets
+  SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
+};
+
+// Returns HTTP/3 SETTINGS identifier as a string.
+QUIC_EXPORT std::string H3SettingsToString(
+    Http3AndQpackSettingsIdentifiers identifier);
+
+// Default maximum dynamic table capacity, communicated via
+// SETTINGS_QPACK_MAX_TABLE_CAPACITY.
+enum : QuicByteCount {
+  kDefaultQpackMaxDynamicTableCapacity = 64 * 1024  // 64 KB
+};
+
+// Default limit on the size of uncompressed headers,
+// communicated via SETTINGS_MAX_HEADER_LIST_SIZE.
+enum : QuicByteCount {
+  kDefaultMaxUncompressedHeaderSize = 16 * 1024  // 16 KB
+};
+
+// Default limit on number of blocked streams, communicated via
+// SETTINGS_QPACK_BLOCKED_STREAMS.
+enum : uint64_t { kDefaultMaximumBlockedStreams = 100 };
+
+ABSL_CONST_INIT QUIC_EXPORT_PRIVATE extern const absl::string_view
+    kUserAgentHeaderName;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
diff --git a/quiche/quic/core/http/http_decoder.cc b/quiche/quic/core/http/http_decoder.cc
new file mode 100644
index 0000000..23bc5df
--- /dev/null
+++ b/quiche/quic/core/http/http_decoder.cc
@@ -0,0 +1,674 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/http_decoder.h"
+
+#include <cstdint>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Limit on the payload length for frames that are buffered by HttpDecoder.
+// If a frame header indicating a payload length exceeding this limit is
+// received, HttpDecoder closes the connection.  Does not apply to frames that
+// are not buffered here but each payload fragment is immediately passed to
+// Visitor, like HEADERS, DATA, and unknown frames.
+constexpr QuicByteCount kPayloadLengthLimit = 1024 * 1024;
+
+}  // anonymous namespace
+
+HttpDecoder::HttpDecoder(Visitor* visitor) : HttpDecoder(visitor, Options()) {}
+HttpDecoder::HttpDecoder(Visitor* visitor, Options options)
+    : visitor_(visitor),
+      allow_web_transport_stream_(options.allow_web_transport_stream),
+      state_(STATE_READING_FRAME_TYPE),
+      current_frame_type_(0),
+      current_length_field_length_(0),
+      remaining_length_field_length_(0),
+      current_frame_length_(0),
+      remaining_frame_length_(0),
+      current_type_field_length_(0),
+      remaining_type_field_length_(0),
+      error_(QUIC_NO_ERROR),
+      error_detail_("") {
+  QUICHE_DCHECK(visitor_);
+}
+
+HttpDecoder::~HttpDecoder() {}
+
+// static
+bool HttpDecoder::DecodeSettings(const char* data,
+                                 QuicByteCount len,
+                                 SettingsFrame* frame) {
+  QuicDataReader reader(data, len);
+  uint64_t frame_type;
+  if (!reader.ReadVarInt62(&frame_type)) {
+    QUIC_DLOG(ERROR) << "Unable to read frame type.";
+    return false;
+  }
+
+  if (frame_type != static_cast<uint64_t>(HttpFrameType::SETTINGS)) {
+    QUIC_DLOG(ERROR) << "Invalid frame type " << frame_type;
+    return false;
+  }
+
+  absl::string_view frame_contents;
+  if (!reader.ReadStringPieceVarInt62(&frame_contents)) {
+    QUIC_DLOG(ERROR) << "Failed to read SETTINGS frame contents";
+    return false;
+  }
+
+  QuicDataReader frame_reader(frame_contents);
+
+  while (!frame_reader.IsDoneReading()) {
+    uint64_t id;
+    if (!frame_reader.ReadVarInt62(&id)) {
+      QUIC_DLOG(ERROR) << "Unable to read setting identifier.";
+      return false;
+    }
+    uint64_t content;
+    if (!frame_reader.ReadVarInt62(&content)) {
+      QUIC_DLOG(ERROR) << "Unable to read setting value.";
+      return false;
+    }
+    auto result = frame->values.insert({id, content});
+    if (!result.second) {
+      QUIC_DLOG(ERROR) << "Duplicate setting identifier.";
+      return false;
+    }
+  }
+  return true;
+}
+
+QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
+  QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
+  QUICHE_DCHECK_NE(STATE_ERROR, state_);
+
+  QuicDataReader reader(data, len);
+  bool continue_processing = true;
+  // BufferOrParsePayload() and FinishParsing() may need to be called even if
+  // there is no more data so that they can finish processing the current frame.
+  while (continue_processing && (reader.BytesRemaining() != 0 ||
+                                 state_ == STATE_BUFFER_OR_PARSE_PAYLOAD ||
+                                 state_ == STATE_FINISH_PARSING)) {
+    // |continue_processing| must have been set to false upon error.
+    QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
+    QUICHE_DCHECK_NE(STATE_ERROR, state_);
+
+    switch (state_) {
+      case STATE_READING_FRAME_TYPE:
+        continue_processing = ReadFrameType(&reader);
+        break;
+      case STATE_READING_FRAME_LENGTH:
+        continue_processing = ReadFrameLength(&reader);
+        break;
+      case STATE_BUFFER_OR_PARSE_PAYLOAD:
+        continue_processing = BufferOrParsePayload(&reader);
+        break;
+      case STATE_READING_FRAME_PAYLOAD:
+        continue_processing = ReadFramePayload(&reader);
+        break;
+      case STATE_FINISH_PARSING:
+        continue_processing = FinishParsing();
+        break;
+      case STATE_PARSING_NO_LONGER_POSSIBLE:
+        continue_processing = false;
+        QUIC_BUG(HttpDecoder PARSING_NO_LONGER_POSSIBLE)
+            << "HttpDecoder called after an indefinite-length frame has been "
+               "received";
+        RaiseError(QUIC_INTERNAL_ERROR,
+                   "HttpDecoder called after an indefinite-length frame has "
+                   "been received");
+        break;
+      case STATE_ERROR:
+        break;
+      default:
+        QUIC_BUG(quic_bug_10411_1) << "Invalid state: " << state_;
+    }
+  }
+
+  return len - reader.BytesRemaining();
+}
+
+bool HttpDecoder::ReadFrameType(QuicDataReader* reader) {
+  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  if (current_type_field_length_ == 0) {
+    // A new frame is coming.
+    current_type_field_length_ = reader->PeekVarInt62Length();
+    QUICHE_DCHECK_NE(0u, current_type_field_length_);
+    if (current_type_field_length_ > reader->BytesRemaining()) {
+      // Buffer a new type field.
+      remaining_type_field_length_ = current_type_field_length_;
+      BufferFrameType(reader);
+      return true;
+    }
+    // The reader has all type data needed, so no need to buffer.
+    bool success = reader->ReadVarInt62(&current_frame_type_);
+    QUICHE_DCHECK(success);
+  } else {
+    // Buffer the existing type field.
+    BufferFrameType(reader);
+    // The frame is still not buffered completely.
+    if (remaining_type_field_length_ != 0) {
+      return true;
+    }
+    QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
+    bool success = type_reader.ReadVarInt62(&current_frame_type_);
+    QUICHE_DCHECK(success);
+  }
+
+  // https://tools.ietf.org/html/draft-ietf-quic-http-31#section-7.2.8
+  // specifies that the following frames are treated as errors.
+  if (current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::PRIORITY) ||
+      current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::PING) ||
+      current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::WINDOW_UPDATE) ||
+      current_frame_type_ ==
+          static_cast<uint64_t>(http2::Http2FrameType::CONTINUATION)) {
+    RaiseError(QUIC_HTTP_RECEIVE_SPDY_FRAME,
+               absl::StrCat("HTTP/2 frame received in a HTTP/3 connection: ",
+                            current_frame_type_));
+    return false;
+  }
+
+  if (current_frame_type_ ==
+      static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH)) {
+    RaiseError(QUIC_HTTP_FRAME_ERROR, "CANCEL_PUSH frame received.");
+    return false;
+  }
+  if (current_frame_type_ ==
+      static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE)) {
+    RaiseError(QUIC_HTTP_FRAME_ERROR, "PUSH_PROMISE frame received.");
+    return false;
+  }
+
+  state_ = STATE_READING_FRAME_LENGTH;
+  return true;
+}
+
+bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
+  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  if (current_length_field_length_ == 0) {
+    // A new frame is coming.
+    current_length_field_length_ = reader->PeekVarInt62Length();
+    QUICHE_DCHECK_NE(0u, current_length_field_length_);
+    if (current_length_field_length_ > reader->BytesRemaining()) {
+      // Buffer a new length field.
+      remaining_length_field_length_ = current_length_field_length_;
+      BufferFrameLength(reader);
+      return true;
+    }
+    // The reader has all length data needed, so no need to buffer.
+    bool success = reader->ReadVarInt62(&current_frame_length_);
+    QUICHE_DCHECK(success);
+  } else {
+    // Buffer the existing length field.
+    BufferFrameLength(reader);
+    // The frame is still not buffered completely.
+    if (remaining_length_field_length_ != 0) {
+      return true;
+    }
+    QuicDataReader length_reader(length_buffer_.data(),
+                                 current_length_field_length_);
+    bool success = length_reader.ReadVarInt62(&current_frame_length_);
+    QUICHE_DCHECK(success);
+  }
+
+  // WEBTRANSPORT_STREAM frames are indefinitely long, and thus require
+  // special handling; the number after the frame type is actually the
+  // WebTransport session ID, and not the length.
+  if (allow_web_transport_stream_ &&
+      current_frame_type_ ==
+          static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM)) {
+    visitor_->OnWebTransportStreamFrameType(
+        current_length_field_length_ + current_type_field_length_,
+        current_frame_length_);
+    state_ = STATE_PARSING_NO_LONGER_POSSIBLE;
+    return false;
+  }
+
+  if (IsFrameBuffered() &&
+      current_frame_length_ > MaxFrameLength(current_frame_type_)) {
+    RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
+    return false;
+  }
+
+  // Calling the following visitor methods does not require parsing of any
+  // frame payload.
+  bool continue_processing = true;
+  const QuicByteCount header_length =
+      current_length_field_length_ + current_type_field_length_;
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::DATA):
+      continue_processing =
+          visitor_->OnDataFrameStart(header_length, current_frame_length_);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::HEADERS):
+      continue_processing =
+          visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
+      QUICHE_NOTREACHED();
+      break;
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
+      continue_processing = visitor_->OnSettingsFrameStart(header_length);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
+      QUICHE_NOTREACHED();
+      break;
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
+      break;
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
+      break;
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
+      continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
+      break;
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
+      continue_processing = visitor_->OnAcceptChFrameStart(header_length);
+      break;
+    default:
+      continue_processing = visitor_->OnUnknownFrameStart(
+          current_frame_type_, header_length, current_frame_length_);
+      break;
+  }
+
+  remaining_frame_length_ = current_frame_length_;
+
+  if (IsFrameBuffered()) {
+    state_ = STATE_BUFFER_OR_PARSE_PAYLOAD;
+    return continue_processing;
+  }
+
+  state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
+                                          : STATE_READING_FRAME_PAYLOAD;
+  return continue_processing;
+}
+
+bool HttpDecoder::IsFrameBuffered() {
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
+      return true;
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
+      return true;
+  }
+
+  // Other defined frame types as well as unknown frames are not buffered.
+  return false;
+}
+
+bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
+  QUICHE_DCHECK(!IsFrameBuffered());
+  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  QUICHE_DCHECK_NE(0u, remaining_frame_length_);
+
+  bool continue_processing = true;
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::DATA): {
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      absl::string_view payload;
+      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+      QUICHE_DCHECK(success);
+      QUICHE_DCHECK(!payload.empty());
+      continue_processing = visitor_->OnDataFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      absl::string_view payload;
+      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+      QUICHE_DCHECK(success);
+      QUICHE_DCHECK(!payload.empty());
+      continue_processing = visitor_->OnHeadersFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    default: {
+      continue_processing = HandleUnknownFramePayload(reader);
+      break;
+    }
+  }
+
+  if (remaining_frame_length_ == 0) {
+    state_ = STATE_FINISH_PARSING;
+  }
+
+  return continue_processing;
+}
+
+bool HttpDecoder::FinishParsing() {
+  QUICHE_DCHECK(!IsFrameBuffered());
+  QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
+
+  bool continue_processing = true;
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::DATA): {
+      continue_processing = visitor_->OnDataFrameEnd();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
+      continue_processing = visitor_->OnHeadersFrameEnd();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
+      QUICHE_NOTREACHED();
+      break;
+    }
+    default:
+      continue_processing = visitor_->OnUnknownFrameEnd();
+  }
+
+  ResetForNextFrame();
+  return continue_processing;
+}
+
+void HttpDecoder::ResetForNextFrame() {
+  current_length_field_length_ = 0;
+  current_type_field_length_ = 0;
+  state_ = STATE_READING_FRAME_TYPE;
+}
+
+bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  absl::string_view payload;
+  bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+  QUICHE_DCHECK(success);
+  QUICHE_DCHECK(!payload.empty());
+  remaining_frame_length_ -= payload.length();
+  return visitor_->OnUnknownFramePayload(payload);
+}
+
+bool HttpDecoder::BufferOrParsePayload(QuicDataReader* reader) {
+  QUICHE_DCHECK(IsFrameBuffered());
+  QUICHE_DCHECK_EQ(current_frame_length_,
+                   buffer_.size() + remaining_frame_length_);
+
+  if (buffer_.empty() && reader->BytesRemaining() >= current_frame_length_) {
+    // |*reader| contains entire payload, which might be empty.
+    remaining_frame_length_ = 0;
+    QuicDataReader current_payload_reader(reader->PeekRemainingPayload().data(),
+                                          current_frame_length_);
+    bool continue_processing = ParseEntirePayload(&current_payload_reader);
+
+    reader->Seek(current_frame_length_);
+    ResetForNextFrame();
+    return continue_processing;
+  }
+
+  // Buffer as much of the payload as |*reader| contains.
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  absl::StrAppend(&buffer_, reader->PeekRemainingPayload().substr(
+                                /* pos = */ 0, bytes_to_read));
+  reader->Seek(bytes_to_read);
+  remaining_frame_length_ -= bytes_to_read;
+
+  QUICHE_DCHECK_EQ(current_frame_length_,
+                   buffer_.size() + remaining_frame_length_);
+
+  if (remaining_frame_length_ > 0) {
+    QUICHE_DCHECK(reader->IsDoneReading());
+    return false;
+  }
+
+  QuicDataReader buffer_reader(buffer_);
+  bool continue_processing = ParseEntirePayload(&buffer_reader);
+  buffer_.clear();
+
+  ResetForNextFrame();
+  return continue_processing;
+}
+
+bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
+  QUICHE_DCHECK(IsFrameBuffered());
+  QUICHE_DCHECK_EQ(current_frame_length_, reader->BytesRemaining());
+  QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
+
+  switch (current_frame_type_) {
+    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
+      QUICHE_NOTREACHED();
+      return false;
+    }
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
+      SettingsFrame frame;
+      if (!ParseSettingsFrame(reader, &frame)) {
+        return false;
+      }
+      return visitor_->OnSettingsFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
+      GoAwayFrame frame;
+      if (!reader->ReadVarInt62(&frame.id)) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY ID.");
+        return false;
+      }
+      if (!reader->IsDoneReading()) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
+        return false;
+      }
+      return visitor_->OnGoAwayFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
+      MaxPushIdFrame frame;
+      if (!reader->ReadVarInt62(&frame.push_id)) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR,
+                   "Unable to read MAX_PUSH_ID push_id.");
+        return false;
+      }
+      if (!reader->IsDoneReading()) {
+        RaiseError(QUIC_HTTP_FRAME_ERROR,
+                   "Superfluous data in MAX_PUSH_ID frame.");
+        return false;
+      }
+      return visitor_->OnMaxPushIdFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
+      PriorityUpdateFrame frame;
+      if (!ParsePriorityUpdateFrame(reader, &frame)) {
+        return false;
+      }
+      return visitor_->OnPriorityUpdateFrame(frame);
+    }
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
+      AcceptChFrame frame;
+      if (!ParseAcceptChFrame(reader, &frame)) {
+        return false;
+      }
+      return visitor_->OnAcceptChFrame(frame);
+    }
+    default:
+      // Only above frame types are parsed by ParseEntirePayload().
+      QUICHE_NOTREACHED();
+      return false;
+  }
+}
+
+void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_length_field_length_, reader->BytesRemaining());
+  bool success =
+      reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
+                            remaining_length_field_length_,
+                        bytes_to_read);
+  QUICHE_DCHECK(success);
+  remaining_length_field_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_type_field_length_, reader->BytesRemaining());
+  bool success =
+      reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
+                            remaining_type_field_length_,
+                        bytes_to_read);
+  QUICHE_DCHECK(success);
+  remaining_type_field_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
+  state_ = STATE_ERROR;
+  error_ = error;
+  error_detail_ = std::move(error_detail);
+  visitor_->OnError(this);
+}
+
+bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
+                                     SettingsFrame* frame) {
+  while (!reader->IsDoneReading()) {
+    uint64_t id;
+    if (!reader->ReadVarInt62(&id)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
+      return false;
+    }
+    uint64_t content;
+    if (!reader->ReadVarInt62(&content)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
+      return false;
+    }
+    auto result = frame->values.insert({id, content});
+    if (!result.second) {
+      RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
+                 "Duplicate setting identifier.");
+      return false;
+    }
+  }
+  return true;
+}
+
+bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
+                                              PriorityUpdateFrame* frame) {
+  frame->prioritized_element_type = REQUEST_STREAM;
+
+  if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
+    RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
+    return false;
+  }
+
+  absl::string_view priority_field_value = reader->ReadRemainingPayload();
+  frame->priority_field_value =
+      std::string(priority_field_value.data(), priority_field_value.size());
+
+  return true;
+}
+
+bool HttpDecoder::ParseAcceptChFrame(QuicDataReader* reader,
+                                     AcceptChFrame* frame) {
+  absl::string_view origin;
+  absl::string_view value;
+  while (!reader->IsDoneReading()) {
+    if (!reader->ReadStringPieceVarInt62(&origin)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH origin.");
+      return false;
+    }
+    if (!reader->ReadStringPieceVarInt62(&value)) {
+      RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH value.");
+      return false;
+    }
+    // Copy data.
+    frame->entries.push_back({std::string(origin.data(), origin.size()),
+                              std::string(value.data(), value.size())});
+  }
+  return true;
+}
+
+QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
+  QUICHE_DCHECK(IsFrameBuffered());
+
+  switch (frame_type) {
+    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
+      return kPayloadLengthLimit;
+    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
+      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
+      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+    case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
+      return kPayloadLengthLimit;
+    case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
+      return kPayloadLengthLimit;
+    default:
+      QUICHE_NOTREACHED();
+      return 0;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_decoder.h b/quiche/quic/core/http/http_decoder.h
new file mode 100644
index 0000000..59553a3
--- /dev/null
+++ b/quiche/quic/core/http/http_decoder.h
@@ -0,0 +1,278 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+
+class HttpDecoderPeer;
+
+}  // namespace test
+
+class QuicDataReader;
+
+// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpDecoder {
+ public:
+  struct QUIC_EXPORT_PRIVATE Options {
+    // Indicates that WEBTRANSPORT_STREAM should be parsed.
+    bool allow_web_transport_stream = false;
+  };
+
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called if an error is detected.
+    virtual void OnError(HttpDecoder* decoder) = 0;
+
+    // All the following methods return true to continue decoding,
+    // and false to pause it.
+    // On*FrameStart() methods are called after the frame header is completely
+    // processed.  At that point it is safe to consume |header_length| bytes.
+
+    // Called when a MAX_PUSH_ID frame has been successfully parsed.
+    virtual bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
+
+    // Called when a GOAWAY frame has been successfully parsed.
+    virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
+
+    // Called when a SETTINGS frame has been received.
+    virtual bool OnSettingsFrameStart(QuicByteCount header_length) = 0;
+
+    // Called when a SETTINGS frame has been successfully parsed.
+    virtual bool OnSettingsFrame(const SettingsFrame& frame) = 0;
+
+    // Called when a DATA frame has been received.
+    // |header_length| and |payload_length| are the length of DATA frame header
+    // and payload, respectively.
+    virtual bool OnDataFrameStart(QuicByteCount header_length,
+                                  QuicByteCount payload_length) = 0;
+    // Called when part of the payload of a DATA frame has been read.  May be
+    // called multiple times for a single frame.  |payload| is guaranteed to be
+    // non-empty.
+    virtual bool OnDataFramePayload(absl::string_view payload) = 0;
+    // Called when a DATA frame has been completely processed.
+    virtual bool OnDataFrameEnd() = 0;
+
+    // Called when a HEADERS frame has been received.
+    // |header_length| and |payload_length| are the length of HEADERS frame
+    // header and payload, respectively.
+    virtual bool OnHeadersFrameStart(QuicByteCount header_length,
+                                     QuicByteCount payload_length) = 0;
+    // Called when part of the payload of a HEADERS frame has been read.  May be
+    // called multiple times for a single frame.  |payload| is guaranteed to be
+    // non-empty.
+    virtual bool OnHeadersFramePayload(absl::string_view payload) = 0;
+    // Called when a HEADERS frame has been completely processed.
+    virtual bool OnHeadersFrameEnd() = 0;
+
+    // Called when a PRIORITY_UPDATE frame has been received.
+    // |header_length| contains PRIORITY_UPDATE frame length and payload length.
+    virtual bool OnPriorityUpdateFrameStart(QuicByteCount header_length) = 0;
+
+    // Called when a PRIORITY_UPDATE frame has been successfully parsed.
+    virtual bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) = 0;
+
+    // Called when an ACCEPT_CH frame has been received.
+    // |header_length| contains ACCEPT_CH frame length and payload length.
+    virtual bool OnAcceptChFrameStart(QuicByteCount header_length) = 0;
+
+    // Called when an ACCEPT_CH frame has been successfully parsed.
+    virtual bool OnAcceptChFrame(const AcceptChFrame& frame) = 0;
+
+    // Called when a WEBTRANSPORT_STREAM frame type and the session ID varint
+    // immediately following it has been received.  Any further parsing should
+    // be done by the stream itself, and not the parser. Note that this does not
+    // return bool, because WEBTRANSPORT_STREAM always causes the parsing
+    // process to cease.
+    virtual void OnWebTransportStreamFrameType(
+        QuicByteCount header_length,
+        WebTransportSessionId session_id) = 0;
+
+    // Called when a frame of unknown type |frame_type| has been received.
+    // Frame type might be reserved, Visitor must make sure to ignore.
+    // |header_length| and |payload_length| are the length of the frame header
+    // and payload, respectively.
+    virtual bool OnUnknownFrameStart(uint64_t frame_type,
+                                     QuicByteCount header_length,
+                                     QuicByteCount payload_length) = 0;
+    // Called when part of the payload of the unknown frame has been read.  May
+    // be called multiple times for a single frame.  |payload| is guaranteed to
+    // be non-empty.
+    virtual bool OnUnknownFramePayload(absl::string_view payload) = 0;
+    // Called when the unknown frame has been completely processed.
+    virtual bool OnUnknownFrameEnd() = 0;
+  };
+
+  // |visitor| must be non-null, and must outlive HttpDecoder.
+  explicit HttpDecoder(Visitor* visitor);
+  explicit HttpDecoder(Visitor* visitor, Options options);
+
+  ~HttpDecoder();
+
+  // Processes the input and invokes the appropriate visitor methods, until a
+  // visitor method returns false or an error occurs.  Returns the number of
+  // bytes processed.  Does not process any input if called after an error.
+  // Paused processing can be resumed by calling ProcessInput() again with the
+  // unprocessed portion of data.  Must not be called after an error has
+  // occurred.
+  QuicByteCount ProcessInput(const char* data, QuicByteCount len);
+
+  // Decode settings frame from |data|.
+  // Upon successful decoding, |frame| will be populated, and returns true.
+  // This method is not used for regular processing of incoming data.
+  static bool DecodeSettings(const char* data,
+                             QuicByteCount len,
+                             SettingsFrame* frame);
+
+  // Returns an error code other than QUIC_NO_ERROR if and only if
+  // Visitor::OnError() has been called.
+  QuicErrorCode error() const { return error_; }
+
+  const std::string& error_detail() const { return error_detail_; }
+
+  // Returns true if input data processed so far ends on a frame boundary.
+  bool AtFrameBoundary() const { return state_ == STATE_READING_FRAME_TYPE; }
+
+ private:
+  friend test::HttpDecoderPeer;
+
+  // Represents the current state of the parsing state machine.
+  enum HttpDecoderState {
+    STATE_READING_FRAME_LENGTH,
+    STATE_READING_FRAME_TYPE,
+
+    // States used for buffered frame types
+    STATE_BUFFER_OR_PARSE_PAYLOAD,
+
+    // States used for non-buffered frame types
+    STATE_READING_FRAME_PAYLOAD,
+    STATE_FINISH_PARSING,
+
+    STATE_PARSING_NO_LONGER_POSSIBLE,
+    STATE_ERROR
+  };
+
+  // Reads the type of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.  Also calls OnDataFrameStart() or
+  // OnHeadersFrameStart() for appropriate frame types. Returns whether the
+  // processing should continue.
+  bool ReadFrameType(QuicDataReader* reader);
+
+  // Reads the length of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.  Returns whether processing should continue.
+  bool ReadFrameLength(QuicDataReader* reader);
+
+  // Returns whether the current frame is of a buffered type.
+  // The payload of buffered frames is buffered by HttpDecoder, and parsed by
+  // HttpDecoder after the entire frame has been received.  (Copying to the
+  // buffer is skipped if the ProcessInput() call covers the entire payload.)
+  // Frames that are not buffered have every payload fragment synchronously
+  // passed to the Visitor without buffering.
+  bool IsFrameBuffered();
+
+  // For buffered frame types, calls BufferOrParsePayload().  For other frame
+  // types, reads the payload of the current frame from |reader| and calls
+  // visitor methods.  Returns whether processing should continue.
+  bool ReadFramePayload(QuicDataReader* reader);
+
+  // For buffered frame types, this method is only called if frame payload is
+  // empty, and it calls BufferOrParsePayload().  For other frame types, this
+  // method directly calls visitor methods to signal that frame had been
+  // received completely.  Returns whether processing should continue.
+  bool FinishParsing();
+
+  // Reset internal fields to prepare for reading next frame.
+  void ResetForNextFrame();
+
+  // Read payload of unknown frame from |reader| and call
+  // Visitor::OnUnknownFramePayload().  Returns true decoding should continue,
+  // false if it should be paused.
+  bool HandleUnknownFramePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame payload from |*reader| into |buffer_| if
+  // necessary.  Parses the frame payload if complete.  Parses out of |*reader|
+  // without unnecessary copy if |*reader| contains entire payload.
+  // Returns whether processing should continue.
+  // Must only be called when current frame type is buffered.
+  bool BufferOrParsePayload(QuicDataReader* reader);
+
+  // Parses the entire payload of certain kinds of frames that are parsed in a
+  // single pass.  |reader| must have at least |current_frame_length_| bytes.
+  // Returns whether processing should continue.
+  // Must only be called when current frame type is buffered.
+  bool ParseEntirePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame length field from |reader| into
+  // |length_buffer_|.
+  void BufferFrameLength(QuicDataReader* reader);
+
+  // Buffers any remaining frame type field from |reader| into |type_buffer_|.
+  void BufferFrameType(QuicDataReader* reader);
+
+  // Sets |error_| and |error_detail_| accordingly.
+  void RaiseError(QuicErrorCode error, std::string error_detail);
+
+  // Parses the payload of a SETTINGS frame from |reader| into |frame|.
+  bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
+
+  // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
+  // from |reader| into |frame|.
+  bool ParsePriorityUpdateFrame(QuicDataReader* reader,
+                                PriorityUpdateFrame* frame);
+
+  // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
+  bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
+
+  // Returns the max frame size of a given |frame_type|.
+  QuicByteCount MaxFrameLength(uint64_t frame_type);
+
+  // Visitor to invoke when messages are parsed.
+  Visitor* const visitor_;  // Unowned.
+  // Whether WEBTRANSPORT_STREAM should be parsed.
+  bool allow_web_transport_stream_;
+  // Current state of the parsing.
+  HttpDecoderState state_;
+  // Type of the frame currently being parsed.
+  uint64_t current_frame_type_;
+  // Size of the frame's length field.
+  QuicByteCount current_length_field_length_;
+  // Remaining length that's needed for the frame's length field.
+  QuicByteCount remaining_length_field_length_;
+  // Length of the payload of the frame currently being parsed.
+  QuicByteCount current_frame_length_;
+  // Remaining payload bytes to be parsed.
+  QuicByteCount remaining_frame_length_;
+  // Length of the frame's type field.
+  QuicByteCount current_type_field_length_;
+  // Remaining length that's needed for the frame's type field.
+  QuicByteCount remaining_type_field_length_;
+  // Last error.
+  QuicErrorCode error_;
+  // The issue which caused |error_|
+  std::string error_detail_;
+  // Remaining unparsed data.
+  std::string buffer_;
+  // Remaining unparsed length field data.
+  std::array<char, sizeof(uint64_t)> length_buffer_;
+  // Remaining unparsed type field data.
+  std::array<char, sizeof(uint64_t)> type_buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
diff --git a/quiche/quic/core/http/http_decoder_test.cc b/quiche/quic/core/http/http_decoder_test.cc
new file mode 100644
index 0000000..962f53c
--- /dev/null
+++ b/quiche/quic/core/http/http_decoder_test.cc
@@ -0,0 +1,1136 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/http_decoder.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Eq;
+using ::testing::InSequence;
+using ::testing::Return;
+
+namespace quic {
+namespace test {
+
+class HttpDecoderPeer {
+ public:
+  static uint64_t current_frame_type(HttpDecoder* decoder) {
+    return decoder->current_frame_type_;
+  }
+};
+
+namespace {
+
+class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
+ public:
+  ~MockHttpDecoderVisitor() override = default;
+
+  // Called if an error is detected.
+  MOCK_METHOD(void, OnError, (HttpDecoder*), (override));
+
+  MOCK_METHOD(bool,
+              OnMaxPushIdFrame,
+              (const MaxPushIdFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnGoAwayFrame, (const GoAwayFrame& frame), (override));
+  MOCK_METHOD(bool,
+              OnSettingsFrameStart,
+              (QuicByteCount header_length),
+              (override));
+  MOCK_METHOD(bool, OnSettingsFrame, (const SettingsFrame& frame), (override));
+
+  MOCK_METHOD(bool,
+              OnDataFrameStart,
+              (QuicByteCount header_length, QuicByteCount payload_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnDataFramePayload,
+              (absl::string_view payload),
+              (override));
+  MOCK_METHOD(bool, OnDataFrameEnd, (), (override));
+
+  MOCK_METHOD(bool,
+              OnHeadersFrameStart,
+              (QuicByteCount header_length, QuicByteCount payload_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnHeadersFramePayload,
+              (absl::string_view payload),
+              (override));
+  MOCK_METHOD(bool, OnHeadersFrameEnd, (), (override));
+
+  MOCK_METHOD(bool,
+              OnPriorityUpdateFrameStart,
+              (QuicByteCount header_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnPriorityUpdateFrame,
+              (const PriorityUpdateFrame& frame),
+              (override));
+
+  MOCK_METHOD(bool,
+              OnAcceptChFrameStart,
+              (QuicByteCount header_length),
+              (override));
+  MOCK_METHOD(bool, OnAcceptChFrame, (const AcceptChFrame& frame), (override));
+  MOCK_METHOD(void,
+              OnWebTransportStreamFrameType,
+              (QuicByteCount header_length, WebTransportSessionId session_id),
+              (override));
+
+  MOCK_METHOD(bool,
+              OnUnknownFrameStart,
+              (uint64_t frame_type,
+               QuicByteCount header_length,
+               QuicByteCount payload_length),
+              (override));
+  MOCK_METHOD(bool,
+              OnUnknownFramePayload,
+              (absl::string_view payload),
+              (override));
+  MOCK_METHOD(bool, OnUnknownFrameEnd, (), (override));
+};
+
+class HttpDecoderTest : public QuicTest {
+ public:
+  HttpDecoderTest() : decoder_(&visitor_) {
+    ON_CALL(visitor_, OnMaxPushIdFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnGoAwayFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnSettingsFrameStart(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnSettingsFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnDataFrameStart(_, _)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnDataFramePayload(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnDataFrameEnd()).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnHeadersFrameStart(_, _)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnHeadersFramePayload(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnHeadersFrameEnd()).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnPriorityUpdateFrameStart(_))
+        .WillByDefault(Return(true));
+    ON_CALL(visitor_, OnPriorityUpdateFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnAcceptChFrameStart(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnAcceptChFrame(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnUnknownFrameStart(_, _, _)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnUnknownFramePayload(_)).WillByDefault(Return(true));
+    ON_CALL(visitor_, OnUnknownFrameEnd()).WillByDefault(Return(true));
+  }
+  ~HttpDecoderTest() override = default;
+
+  uint64_t current_frame_type() {
+    return HttpDecoderPeer::current_frame_type(&decoder_);
+  }
+
+  // Process |input| in a single call to HttpDecoder::ProcessInput().
+  QuicByteCount ProcessInput(absl::string_view input) {
+    return decoder_.ProcessInput(input.data(), input.size());
+  }
+
+  // Feed |input| to |decoder_| one character at a time,
+  // verifying that each character gets processed.
+  void ProcessInputCharByChar(absl::string_view input) {
+    for (char c : input) {
+      EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+    }
+  }
+
+  // Append garbage to |input|, then process it in a single call to
+  // HttpDecoder::ProcessInput().  Verify that garbage is not read.
+  QuicByteCount ProcessInputWithGarbageAppended(absl::string_view input) {
+    std::string input_with_garbage_appended = absl::StrCat(input, "blahblah");
+    QuicByteCount processed_bytes = ProcessInput(input_with_garbage_appended);
+
+    // Guaranteed by HttpDecoder::ProcessInput() contract.
+    QUICHE_DCHECK_LE(processed_bytes, input_with_garbage_appended.size());
+
+    // Caller should set up visitor to pause decoding
+    // before HttpDecoder would read garbage.
+    EXPECT_LE(processed_bytes, input.size());
+
+    return processed_bytes;
+  }
+
+  testing::StrictMock<MockHttpDecoderVisitor> visitor_;
+  HttpDecoder decoder_;
+};
+
+TEST_F(HttpDecoderTest, InitialState) {
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, UnknownFrame) {
+  std::unique_ptr<char[]> input;
+
+  const QuicByteCount payload_lengths[] = {0, 14, 100};
+  const uint64_t frame_types[] = {
+      0x21, 0x40, 0x5f, 0x7e, 0x9d,  // some reserved frame types
+      0x6f, 0x14                     // some unknown, not reserved frame types
+  };
+
+  for (auto payload_length : payload_lengths) {
+    std::string data(payload_length, 'a');
+
+    for (auto frame_type : frame_types) {
+      const QuicByteCount total_length =
+          QuicDataWriter::GetVarInt62Len(frame_type) +
+          QuicDataWriter::GetVarInt62Len(payload_length) + payload_length;
+      input = std::make_unique<char[]>(total_length);
+
+      QuicDataWriter writer(total_length, input.get());
+      writer.WriteVarInt62(frame_type);
+      writer.WriteVarInt62(payload_length);
+      const QuicByteCount header_length = writer.length();
+      if (payload_length > 0) {
+        writer.WriteStringPiece(data);
+      }
+
+      EXPECT_CALL(visitor_, OnUnknownFrameStart(frame_type, header_length,
+                                                payload_length));
+      if (payload_length > 0) {
+        EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq(data)));
+      }
+      EXPECT_CALL(visitor_, OnUnknownFrameEnd());
+
+      EXPECT_EQ(total_length, decoder_.ProcessInput(input.get(), total_length));
+
+      EXPECT_THAT(decoder_.error(), IsQuicNoError());
+      ASSERT_EQ("", decoder_.error_detail());
+      EXPECT_EQ(frame_type, current_frame_type());
+    }
+  }
+}
+
+TEST_F(HttpDecoderTest, CancelPush) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "03"    // type (CANCEL_PUSH)
+      "01"    // length
+      "01");  // Push Id
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(1u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("CANCEL_PUSH frame received.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PushPromiseFrame) {
+  InSequence s;
+  std::string input =
+      absl::StrCat(absl::HexStringToBytes("05"    // type (PUSH PROMISE)
+                                          "08"    // length
+                                          "1f"),  // push id 31
+                   "Headers");                    // headers
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(1u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("PUSH_PROMISE frame received.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, MaxPushId) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "0D"    // type (MAX_PUSH_ID)
+      "01"    // length
+      "01");  // Push Id
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})))
+      .WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, SettingsFrame) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "07"    // length
+      "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+      "02"    // content
+      "06"    // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+      "05"    // content
+      "4100"  // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
+      "04");  // content
+
+  SettingsFrame frame;
+  frame.values[1] = 2;
+  frame.values[6] = 5;
+  frame.values[256] = 4;
+
+  // Visitor pauses processing.
+  absl::string_view remaining_input(input);
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2)).WillOnce(Return(false));
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(2u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame)).WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnSettingsFrame(frame));
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, CorruptSettingsFrame) {
+  const char* const kPayload =
+      "\x42\x11"                           // two-byte id
+      "\x80\x22\x33\x44"                   // four-byte value
+      "\x58\x39"                           // two-byte id
+      "\xf0\x22\x33\x44\x55\x66\x77\x88";  // eight-byte value
+  struct {
+    size_t payload_length;
+    const char* const error_message;
+  } kTestData[] = {
+      {1, "Unable to read setting identifier."},
+      {5, "Unable to read setting value."},
+      {7, "Unable to read setting identifier."},
+      {12, "Unable to read setting value."},
+  };
+
+  for (const auto& test_data : kTestData) {
+    std::string input;
+    input.push_back(4u);  // type SETTINGS
+    input.push_back(test_data.payload_length);
+    const size_t header_length = input.size();
+    input.append(kPayload, test_data.payload_length);
+
+    HttpDecoder decoder(&visitor_);
+    EXPECT_CALL(visitor_, OnSettingsFrameStart(header_length));
+    EXPECT_CALL(visitor_, OnError(&decoder));
+
+    QuicByteCount processed_bytes =
+        decoder.ProcessInput(input.data(), input.size());
+    EXPECT_EQ(input.size(), processed_bytes);
+    EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+    EXPECT_EQ(test_data.error_message, decoder.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) {
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "04"    // length
+      "01"    // identifier
+      "01"    // content
+      "01"    // identifier
+      "02");  // content
+
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+
+  EXPECT_EQ(input.size(), ProcessInput(input));
+
+  EXPECT_THAT(decoder_.error(),
+              IsError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER));
+  EXPECT_EQ("Duplicate setting identifier.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, DataFrame) {
+  InSequence s;
+  std::string input = absl::StrCat(absl::HexStringToBytes("00"    // type (DATA)
+                                                          "05"),  // length
+                                   "Data!");                      // data
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)).WillOnce(Return(false));
+  absl::string_view remaining_input(input);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(2u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+
+  EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("D")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("t")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("a")));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, FrameHeaderPartialDelivery) {
+  InSequence s;
+  // A large input that will occupy more than 1 byte in the length field.
+  std::string input(2048, 'x');
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      input.length(), quiche::SimpleBufferAllocator::Get());
+  // Partially send only 1 byte of the header to process.
+  EXPECT_EQ(1u, decoder_.ProcessInput(header.data(), 1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Send the rest of the header.
+  EXPECT_CALL(visitor_, OnDataFrameStart(3, input.length()));
+  EXPECT_EQ(header.size() - 1,
+            decoder_.ProcessInput(header.data() + 1, header.size() - 1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Send data.
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view(input)));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(2048u, decoder_.ProcessInput(input.data(), 2048));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PartialDeliveryOfLargeFrameType) {
+  // Use a reserved type that takes four bytes as a varint.
+  const uint64_t frame_type = 0x1f * 0x222 + 0x21;
+  const QuicByteCount payload_length = 0;
+  const QuicByteCount header_length =
+      QuicDataWriter::GetVarInt62Len(frame_type) +
+      QuicDataWriter::GetVarInt62Len(payload_length);
+
+  auto input = std::make_unique<char[]>(header_length);
+  QuicDataWriter writer(header_length, input.get());
+  writer.WriteVarInt62(frame_type);
+  writer.WriteVarInt62(payload_length);
+
+  EXPECT_CALL(visitor_,
+              OnUnknownFrameStart(frame_type, header_length, payload_length));
+  EXPECT_CALL(visitor_, OnUnknownFrameEnd());
+
+  auto raw_input = input.get();
+  for (uint64_t i = 0; i < header_length; ++i) {
+    char c = raw_input[i];
+    EXPECT_EQ(1u, decoder_.ProcessInput(&c, 1));
+  }
+
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+  EXPECT_EQ(frame_type, current_frame_type());
+}
+
+TEST_F(HttpDecoderTest, GoAway) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "07"    // type (GOAWAY)
+      "01"    // length
+      "01");  // ID
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})))
+      .WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnGoAwayFrame(GoAwayFrame({1})));
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, HeadersFrame) {
+  InSequence s;
+  std::string input =
+      absl::StrCat(absl::HexStringToBytes("01"    // type (HEADERS)
+                                          "07"),  // length
+                   "Headers");                    // headers
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)).WillOnce(Return(false));
+  absl::string_view remaining_input(input);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(2u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("H")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("a")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("d")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("e")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("r")));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("s")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyDataFrame) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "00"    // type (DATA)
+      "00");  // length
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0)).WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+
+  EXPECT_CALL(visitor_, OnDataFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyHeadersFrame) {
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "01"    // type (HEADERS)
+      "00");  // length
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0)).WillOnce(Return(false));
+  EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
+
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
+  EXPECT_EQ(0u, ProcessInputWithGarbageAppended(""));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 0));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd());
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, GoawayWithOverlyLargePayload) {
+  std::string input = absl::HexStringToBytes(
+      "07"    // type (GOAWAY)
+      "10");  // length exceeding the maximum possible length for GOAWAY frame
+  // Process all data at once.
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(2u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
+  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, MaxPushIdWithOverlyLargePayload) {
+  std::string input = absl::HexStringToBytes(
+      "0d"    // type (MAX_PUSH_ID)
+      "10");  // length exceeding the maximum possible length for MAX_PUSH_ID
+              // frame
+  // Process all data at once.
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(2u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
+  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, FrameWithOverlyLargePayload) {
+  // Regression test for b/193919867: Ensure that reading frames with incredibly
+  // large payload lengths does not lead to allocating unbounded memory.
+  constexpr size_t max_input_length =
+      /*max frame type varint length*/ sizeof(uint64_t) +
+      /*max frame length varint length*/ sizeof(uint64_t) +
+      /*one byte of payload*/ sizeof(uint8_t);
+  char input[max_input_length];
+  for (uint64_t frame_type = 0; frame_type < 1025; frame_type++) {
+    ::testing::NiceMock<MockHttpDecoderVisitor> visitor;
+    HttpDecoder decoder(&visitor);
+    QuicDataWriter writer(max_input_length, input);
+    ASSERT_TRUE(writer.WriteVarInt62(frame_type));         // frame type.
+    ASSERT_TRUE(writer.WriteVarInt62(kVarInt62MaxValue));  // frame length.
+    ASSERT_TRUE(writer.WriteUInt8(0x00));  // one byte of payload.
+    EXPECT_NE(decoder.ProcessInput(input, writer.length()), 0u) << frame_type;
+  }
+}
+
+TEST_F(HttpDecoderTest, MalformedSettingsFrame) {
+  char input[30];
+  QuicDataWriter writer(30, input);
+  // Write type SETTINGS.
+  writer.WriteUInt8(0x04);
+  // Write length.
+  writer.WriteVarInt62(2048 * 1024);
+
+  writer.WriteStringPiece("Malformed payload");
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(5u, decoder_.ProcessInput(input, ABSL_ARRAYSIZE(input)));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_TOO_LARGE));
+  EXPECT_EQ("Frame is too large.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, Http2Frame) {
+  std::string input = absl::HexStringToBytes(
+      "06"    // PING in HTTP/2 but not supported in HTTP/3.
+      "05"    // length
+      "15");  // random payload
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(1u, ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_RECEIVE_SPDY_FRAME));
+  EXPECT_EQ("HTTP/2 frame received in a HTTP/3 connection: 6",
+            decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, HeadersPausedThenData) {
+  InSequence s;
+  std::string input =
+      absl::StrCat(absl::HexStringToBytes("01"    // type (HEADERS)
+                                          "07"),  // length
+                   "Headers",                     // headers
+                   absl::HexStringToBytes("00"    // type (DATA)
+                                          "05"),  // length
+                   "Data!");                      // data
+
+  // Visitor pauses processing, maybe because header decompression is blocked.
+  EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
+  EXPECT_CALL(visitor_, OnHeadersFramePayload(absl::string_view("Headers")));
+  EXPECT_CALL(visitor_, OnHeadersFrameEnd()).WillOnce(Return(false));
+  absl::string_view remaining_input(input);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(9u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  // Process DATA frame.
+  EXPECT_CALL(visitor_, OnDataFrameStart(2, 5));
+  EXPECT_CALL(visitor_, OnDataFramePayload(absl::string_view("Data!")));
+  EXPECT_CALL(visitor_, OnDataFrameEnd());
+
+  processed_bytes = ProcessInput(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, CorruptFrame) {
+  InSequence s;
+
+  struct {
+    const char* const input;
+    const char* const error_message;
+  } kTestData[] = {{"\x0D"   // type (MAX_PUSH_ID)
+                    "\x01"   // length
+                    "\x40",  // first byte of two-byte varint push id
+                    "Unable to read MAX_PUSH_ID push_id."},
+                   {"\x0D"  // type (MAX_PUSH_ID)
+                    "\x04"  // length
+                    "\x05"  // valid push id
+                    "foo",  // superfluous data
+                    "Superfluous data in MAX_PUSH_ID frame."},
+                   {"\x07"   // type (GOAWAY)
+                    "\x01"   // length
+                    "\x40",  // first byte of two-byte varint stream id
+                    "Unable to read GOAWAY ID."},
+                   {"\x07"  // type (GOAWAY)
+                    "\x04"  // length
+                    "\x05"  // valid stream id
+                    "foo",  // superfluous data
+                    "Superfluous data in GOAWAY frame."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x01"      // length
+                    "\x40",     // first byte of two-byte varint origin length
+                    "Unable to read ACCEPT_CH origin."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x01"      // length
+                    "\x05",     // valid origin length but no origin string
+                    "Unable to read ACCEPT_CH origin."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x04"      // length
+                    "\x05"      // valid origin length
+                    "foo",      // payload ends before origin ends
+                    "Unable to read ACCEPT_CH origin."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x04"      // length
+                    "\x03"      // valid origin length
+                    "foo",      // payload ends at end of origin: no value
+                    "Unable to read ACCEPT_CH value."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x05"      // length
+                    "\x03"      // valid origin length
+                    "foo"       // payload ends at end of origin: no value
+                    "\x40",     // first byte of two-byte varint value length
+                    "Unable to read ACCEPT_CH value."},
+                   {"\x40\x89"  // type (ACCEPT_CH)
+                    "\x08"      // length
+                    "\x03"      // valid origin length
+                    "foo"       // origin
+                    "\x05"      // valid value length
+                    "bar",      // payload ends before value ends
+                    "Unable to read ACCEPT_CH value."}};
+
+  for (const auto& test_data : kTestData) {
+    {
+      HttpDecoder decoder(&visitor_);
+      EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
+      EXPECT_CALL(visitor_, OnError(&decoder));
+
+      absl::string_view input(test_data.input);
+      decoder.ProcessInput(input.data(), input.size());
+      EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+      EXPECT_EQ(test_data.error_message, decoder.error_detail());
+    }
+    {
+      HttpDecoder decoder(&visitor_);
+      EXPECT_CALL(visitor_, OnAcceptChFrameStart(_)).Times(AnyNumber());
+      EXPECT_CALL(visitor_, OnError(&decoder));
+
+      absl::string_view input(test_data.input);
+      for (auto c : input) {
+        decoder.ProcessInput(&c, 1);
+      }
+      EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+      EXPECT_EQ(test_data.error_message, decoder.error_detail());
+    }
+  }
+}
+
+TEST_F(HttpDecoderTest, EmptySettingsFrame) {
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "00");  // frame length
+
+  EXPECT_CALL(visitor_, OnSettingsFrameStart(2));
+
+  SettingsFrame empty_frame;
+  EXPECT_CALL(visitor_, OnSettingsFrame(empty_frame));
+
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyGoAwayFrame) {
+  std::string input = absl::HexStringToBytes(
+      "07"    // type (GOAWAY)
+      "00");  // frame length
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("Unable to read GOAWAY ID.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, EmptyMaxPushIdFrame) {
+  std::string input = absl::HexStringToBytes(
+      "0d"    // type (MAX_PUSH_ID)
+      "00");  // frame length
+
+  EXPECT_CALL(visitor_, OnError(&decoder_));
+  EXPECT_EQ(input.size(), ProcessInput(input));
+  EXPECT_THAT(decoder_.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+  EXPECT_EQ("Unable to read MAX_PUSH_ID push_id.", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, LargeStreamIdInGoAway) {
+  GoAwayFrame frame;
+  frame.id = 1ull << 60;
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
+  EXPECT_CALL(visitor_, OnGoAwayFrame(frame));
+  EXPECT_GT(length, 0u);
+  EXPECT_EQ(length, decoder_.ProcessInput(buffer.get(), length));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+// Old PRIORITY_UPDATE frame is parsed as unknown frame.
+TEST_F(HttpDecoderTest, ObsoletePriorityUpdateFrame) {
+  const QuicByteCount header_length = 2;
+  const QuicByteCount payload_length = 3;
+  InSequence s;
+  std::string input = absl::HexStringToBytes(
+      "0f"        // type (obsolete PRIORITY_UPDATE)
+      "03"        // length
+      "666f6f");  // payload "foo"
+
+  // Process frame as a whole.
+  EXPECT_CALL(visitor_,
+              OnUnknownFrameStart(0x0f, header_length, payload_length));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("foo")));
+  EXPECT_CALL(visitor_, OnUnknownFrameEnd()).WillOnce(Return(false));
+
+  EXPECT_EQ(header_length + payload_length,
+            ProcessInputWithGarbageAppended(input));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process frame byte by byte.
+  EXPECT_CALL(visitor_,
+              OnUnknownFrameStart(0x0f, header_length, payload_length));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("f")));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
+  EXPECT_CALL(visitor_, OnUnknownFramePayload(Eq("o")));
+  EXPECT_CALL(visitor_, OnUnknownFrameEnd());
+
+  ProcessInputCharByChar(input);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, PriorityUpdateFrame) {
+  InSequence s;
+  std::string input1 = absl::HexStringToBytes(
+      "800f0700"  // type (PRIORITY_UPDATE)
+      "01"        // length
+      "03");      // prioritized element id
+
+  PriorityUpdateFrame priority_update1;
+  priority_update1.prioritized_element_type = REQUEST_STREAM;
+  priority_update1.prioritized_element_id = 0x03;
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
+  absl::string_view remaining_input(input1);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(5u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
+  EXPECT_EQ(input1.size(), ProcessInput(input1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update1));
+  ProcessInputCharByChar(input1);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  std::string input2 = absl::HexStringToBytes(
+      "800f0700"  // type (PRIORITY_UPDATE)
+      "04"        // length
+      "05"        // prioritized element id
+      "666f6f");  // priority field value: "foo"
+
+  PriorityUpdateFrame priority_update2;
+  priority_update2.prioritized_element_type = REQUEST_STREAM;
+  priority_update2.prioritized_element_id = 0x05;
+  priority_update2.priority_field_value = "foo";
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5)).WillOnce(Return(false));
+  remaining_input = input2;
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(5u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2))
+      .WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
+  EXPECT_EQ(input2.size(), ProcessInput(input2));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(5));
+  EXPECT_CALL(visitor_, OnPriorityUpdateFrame(priority_update2));
+  ProcessInputCharByChar(input2);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) {
+  std::string payload =
+      absl::HexStringToBytes("4005");  // prioritized element id
+  struct {
+    size_t payload_length;
+    const char* const error_message;
+  } kTestData[] = {
+      {0, "Unable to read prioritized element id."},
+      {1, "Unable to read prioritized element id."},
+  };
+
+  for (const auto& test_data : kTestData) {
+    std::string input =
+        absl::HexStringToBytes("800f0700");  // type PRIORITY_UPDATE
+    input.push_back(test_data.payload_length);
+    size_t header_length = input.size();
+    input.append(payload.data(), test_data.payload_length);
+
+    HttpDecoder decoder(&visitor_);
+    EXPECT_CALL(visitor_, OnPriorityUpdateFrameStart(header_length));
+    EXPECT_CALL(visitor_, OnError(&decoder));
+
+    QuicByteCount processed_bytes =
+        decoder.ProcessInput(input.data(), input.size());
+    EXPECT_EQ(input.size(), processed_bytes);
+    EXPECT_THAT(decoder.error(), IsError(QUIC_HTTP_FRAME_ERROR));
+    EXPECT_EQ(test_data.error_message, decoder.error_detail());
+  }
+}
+
+TEST_F(HttpDecoderTest, AcceptChFrame) {
+  InSequence s;
+  std::string input1 = absl::HexStringToBytes(
+      "4089"  // type (ACCEPT_CH)
+      "00");  // length
+
+  AcceptChFrame accept_ch1;
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
+  absl::string_view remaining_input(input1);
+  QuicByteCount processed_bytes =
+      ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(3u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1)).WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
+  EXPECT_EQ(input1.size(), ProcessInput(input1));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch1));
+  ProcessInputCharByChar(input1);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  std::string input2 = absl::HexStringToBytes(
+      "4089"      // type (ACCEPT_CH)
+      "08"        // length
+      "03"        // length of origin
+      "666f6f"    // origin "foo"
+      "03"        // length of value
+      "626172");  // value "bar"
+
+  AcceptChFrame accept_ch2;
+  accept_ch2.entries.push_back({"foo", "bar"});
+
+  // Visitor pauses processing.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3)).WillOnce(Return(false));
+  remaining_input = input2;
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(3u, processed_bytes);
+  remaining_input = remaining_input.substr(processed_bytes);
+
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2)).WillOnce(Return(false));
+  processed_bytes = ProcessInputWithGarbageAppended(remaining_input);
+  EXPECT_EQ(remaining_input.size(), processed_bytes);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the full frame.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
+  EXPECT_EQ(input2.size(), ProcessInput(input2));
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+
+  // Process the frame incrementally.
+  EXPECT_CALL(visitor_, OnAcceptChFrameStart(3));
+  EXPECT_CALL(visitor_, OnAcceptChFrame(accept_ch2));
+  ProcessInputCharByChar(input2);
+  EXPECT_THAT(decoder_.error(), IsQuicNoError());
+  EXPECT_EQ("", decoder_.error_detail());
+}
+
+TEST_F(HttpDecoderTest, WebTransportStreamDisabled) {
+  InSequence s;
+
+  // Unknown frame of type 0x41 and length 0x104.
+  std::string input = absl::HexStringToBytes("40414104");
+  EXPECT_CALL(visitor_, OnUnknownFrameStart(0x41, input.size(), 0x104));
+  EXPECT_EQ(ProcessInput(input), input.size());
+}
+
+TEST(HttpDecoderTestNoFixture, WebTransportStream) {
+  HttpDecoder::Options options;
+  options.allow_web_transport_stream = true;
+  testing::StrictMock<MockHttpDecoderVisitor> visitor;
+  HttpDecoder decoder(&visitor, options);
+
+  // WebTransport stream for session ID 0x104, with four bytes of extra data.
+  std::string input = absl::HexStringToBytes("40414104ffffffff");
+  EXPECT_CALL(visitor, OnWebTransportStreamFrameType(4, 0x104));
+  QuicByteCount bytes = decoder.ProcessInput(input.data(), input.size());
+  EXPECT_EQ(bytes, 4u);
+}
+
+TEST(HttpDecoderTestNoFixture, WebTransportStreamError) {
+  HttpDecoder::Options options;
+  options.allow_web_transport_stream = true;
+  testing::StrictMock<MockHttpDecoderVisitor> visitor;
+  HttpDecoder decoder(&visitor, options);
+
+  std::string input = absl::HexStringToBytes("404100");
+  EXPECT_CALL(visitor, OnWebTransportStreamFrameType(_, _));
+  decoder.ProcessInput(input.data(), input.size());
+
+  EXPECT_CALL(visitor, OnError(_));
+  EXPECT_QUIC_BUG(decoder.ProcessInput(input.data(), input.size()),
+                  "HttpDecoder called after an indefinite-length frame");
+}
+
+TEST_F(HttpDecoderTest, DecodeSettings) {
+  std::string input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "07"    // length
+      "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+      "02"    // content
+      "06"    // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+      "05"    // content
+      "4100"  // identifier, encoded on 2 bytes (0x40), value is 256 (0x100)
+      "04");  // content
+
+  SettingsFrame frame;
+  frame.values[1] = 2;
+  frame.values[6] = 5;
+  frame.values[256] = 4;
+
+  SettingsFrame out;
+  EXPECT_TRUE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
+  EXPECT_EQ(frame, out);
+
+  // non-settings frame.
+  input = absl::HexStringToBytes(
+      "0D"    // type (MAX_PUSH_ID)
+      "01"    // length
+      "01");  // Push Id
+
+  EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
+
+  // Corrupt SETTINGS.
+  input = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "01"    // length
+      "42");  // First byte of setting identifier, indicating a 2-byte varint62.
+
+  EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_encoder.cc b/quiche/quic/core/http/http_encoder.cc
new file mode 100644
index 0000000..fa9c154
--- /dev/null
+++ b/quiche/quic/core/http/http_encoder.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/http_encoder.h"
+#include <cstdint>
+#include <memory>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+bool WriteFrameHeader(QuicByteCount length,
+                      HttpFrameType type,
+                      QuicDataWriter* writer) {
+  return writer->WriteVarInt62(static_cast<uint64_t>(type)) &&
+         writer->WriteVarInt62(length);
+}
+
+QuicByteCount GetTotalLength(QuicByteCount payload_length, HttpFrameType type) {
+  return QuicDataWriter::GetVarInt62Len(payload_length) +
+         QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(type)) +
+         payload_length;
+}
+
+}  // namespace
+
+// static
+QuicByteCount HttpEncoder::GetDataFrameHeaderLength(
+    QuicByteCount payload_length) {
+  QUICHE_DCHECK_NE(0u, payload_length);
+  return QuicDataWriter::GetVarInt62Len(payload_length) +
+         QuicDataWriter::GetVarInt62Len(
+             static_cast<uint64_t>(HttpFrameType::DATA));
+}
+
+// static
+quiche::QuicheBuffer HttpEncoder::SerializeDataFrameHeader(
+    QuicByteCount payload_length, quiche::QuicheBufferAllocator* allocator) {
+  QUICHE_DCHECK_NE(0u, payload_length);
+  QuicByteCount header_length = GetDataFrameHeaderLength(payload_length);
+
+  quiche::QuicheBuffer header(allocator, header_length);
+  QuicDataWriter writer(header.size(), header.data());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::DATA, &writer)) {
+    return header;
+  }
+  QUIC_DLOG(ERROR)
+      << "Http encoder failed when attempting to serialize data frame header.";
+  return quiche::QuicheBuffer();
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeHeadersFrameHeader(
+    QuicByteCount payload_length,
+    std::unique_ptr<char[]>* output) {
+  QUICHE_DCHECK_NE(0u, payload_length);
+  QuicByteCount header_length =
+      QuicDataWriter::GetVarInt62Len(payload_length) +
+      QuicDataWriter::GetVarInt62Len(
+          static_cast<uint64_t>(HttpFrameType::HEADERS));
+
+  output->reset(new char[header_length]);
+  QuicDataWriter writer(header_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::HEADERS, &writer)) {
+    return header_length;
+  }
+  QUIC_DLOG(ERROR)
+      << "Http encoder failed when attempting to serialize headers "
+         "frame header.";
+  return 0;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeSettingsFrame(
+    const SettingsFrame& settings,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length = 0;
+  std::vector<std::pair<uint64_t, uint64_t>> ordered_settings{
+      settings.values.begin(), settings.values.end()};
+  std::sort(ordered_settings.begin(), ordered_settings.end());
+  // Calculate the payload length.
+  for (const auto& p : ordered_settings) {
+    payload_length += QuicDataWriter::GetVarInt62Len(p.first);
+    payload_length += QuicDataWriter::GetVarInt62Len(p.second);
+  }
+
+  QuicByteCount total_length =
+      GetTotalLength(payload_length, HttpFrameType::SETTINGS);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (!WriteFrameHeader(payload_length, HttpFrameType::SETTINGS, &writer)) {
+    QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                        "settings frame header.";
+    return 0;
+  }
+
+  for (const auto& p : ordered_settings) {
+    if (!writer.WriteVarInt62(p.first) || !writer.WriteVarInt62(p.second)) {
+      QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                          "settings frame payload.";
+      return 0;
+    }
+  }
+
+  return total_length;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeGoAwayFrame(
+    const GoAwayFrame& goaway,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length = QuicDataWriter::GetVarInt62Len(goaway.id);
+  QuicByteCount total_length =
+      GetTotalLength(payload_length, HttpFrameType::GOAWAY);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length, HttpFrameType::GOAWAY, &writer) &&
+      writer.WriteVarInt62(goaway.id)) {
+    return total_length;
+  }
+  QUIC_DLOG(ERROR)
+      << "Http encoder failed when attempting to serialize goaway frame.";
+  return 0;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializePriorityUpdateFrame(
+    const PriorityUpdateFrame& priority_update,
+    std::unique_ptr<char[]>* output) {
+  if (priority_update.prioritized_element_type != REQUEST_STREAM) {
+    QUIC_BUG(quic_bug_10402_1)
+        << "PRIORITY_UPDATE for push streams not implemented";
+    return 0;
+  }
+
+  QuicByteCount payload_length =
+      QuicDataWriter::GetVarInt62Len(priority_update.prioritized_element_id) +
+      priority_update.priority_field_value.size();
+  QuicByteCount total_length = GetTotalLength(
+      payload_length, HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (WriteFrameHeader(payload_length,
+                       HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM,
+                       &writer) &&
+      writer.WriteVarInt62(priority_update.prioritized_element_id) &&
+      writer.WriteBytes(priority_update.priority_field_value.data(),
+                        priority_update.priority_field_value.size())) {
+    return total_length;
+  }
+
+  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                      "PRIORITY_UPDATE frame.";
+  return 0;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeAcceptChFrame(
+    const AcceptChFrame& accept_ch,
+    std::unique_ptr<char[]>* output) {
+  QuicByteCount payload_length = 0;
+  for (const auto& entry : accept_ch.entries) {
+    payload_length += QuicDataWriter::GetVarInt62Len(entry.origin.size());
+    payload_length += entry.origin.size();
+    payload_length += QuicDataWriter::GetVarInt62Len(entry.value.size());
+    payload_length += entry.value.size();
+  }
+
+  QuicByteCount total_length =
+      GetTotalLength(payload_length, HttpFrameType::ACCEPT_CH);
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  if (!WriteFrameHeader(payload_length, HttpFrameType::ACCEPT_CH, &writer)) {
+    QUIC_DLOG(ERROR)
+        << "Http encoder failed to serialize ACCEPT_CH frame header.";
+    return 0;
+  }
+
+  for (const auto& entry : accept_ch.entries) {
+    if (!writer.WriteStringPieceVarInt62(entry.origin) ||
+        !writer.WriteStringPieceVarInt62(entry.value)) {
+      QUIC_DLOG(ERROR)
+          << "Http encoder failed to serialize ACCEPT_CH frame payload.";
+      return 0;
+    }
+  }
+
+  return total_length;
+}
+
+// static
+QuicByteCount HttpEncoder::SerializeGreasingFrame(
+    std::unique_ptr<char[]>* output) {
+  uint64_t frame_type;
+  QuicByteCount payload_length;
+  std::string payload;
+  if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
+    frame_type = 0x40;
+    payload_length = 1;
+    payload = "a";
+  } else {
+    uint32_t result;
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+    frame_type = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
+
+    // The payload length is random but within [0, 3];
+    payload_length = result % 4;
+
+    if (payload_length > 0) {
+      std::unique_ptr<char[]> buffer(new char[payload_length]);
+      QuicRandom::GetInstance()->RandBytes(buffer.get(), payload_length);
+      payload = std::string(buffer.get(), payload_length);
+    }
+  }
+  QuicByteCount total_length = QuicDataWriter::GetVarInt62Len(frame_type) +
+                               QuicDataWriter::GetVarInt62Len(payload_length) +
+                               payload_length;
+
+  output->reset(new char[total_length]);
+  QuicDataWriter writer(total_length, output->get());
+
+  bool success =
+      writer.WriteVarInt62(frame_type) && writer.WriteVarInt62(payload_length);
+
+  if (payload_length > 0) {
+    success &= writer.WriteBytes(payload.data(), payload_length);
+  }
+
+  if (success) {
+    return total_length;
+  }
+
+  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                      "greasing frame.";
+  return 0;
+}
+
+QuicByteCount HttpEncoder::SerializeWebTransportStreamFrameHeader(
+    WebTransportSessionId session_id,
+    std::unique_ptr<char[]>* output) {
+  uint64_t stream_type =
+      static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM);
+  QuicByteCount header_length = QuicDataWriter::GetVarInt62Len(stream_type) +
+                                QuicDataWriter::GetVarInt62Len(session_id);
+
+  *output = std::make_unique<char[]>(header_length);
+  QuicDataWriter writer(header_length, output->get());
+  bool success =
+      writer.WriteVarInt62(stream_type) && writer.WriteVarInt62(session_id);
+  if (success && writer.remaining() == 0) {
+    return header_length;
+  }
+
+  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
+                      "WEBTRANSPORT_STREAM frame header.";
+  return 0;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_encoder.h b/quiche/quic/core/http/http_encoder.h
new file mode 100644
index 0000000..eba0e55
--- /dev/null
+++ b/quiche/quic/core/http/http_encoder.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
+
+#include <memory>
+
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+class QuicDataWriter;
+
+// A class for encoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpEncoder {
+ public:
+  HttpEncoder() = delete;
+
+  // Returns the length of the header for a DATA frame.
+  static QuicByteCount GetDataFrameHeaderLength(QuicByteCount payload_length);
+
+  // Serializes a DATA frame header into a QuicheBuffer; returns said
+  // QuicheBuffer on success, empty buffer otherwise.
+  static quiche::QuicheBuffer SerializeDataFrameHeader(
+      QuicByteCount payload_length, quiche::QuicheBufferAllocator* allocator);
+
+  // Serializes a HEADERS frame header into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeHeadersFrameHeader(
+      QuicByteCount payload_length,
+      std::unique_ptr<char[]>* output);
+
+  // Serializes a SETTINGS frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeSettingsFrame(const SettingsFrame& settings,
+                                              std::unique_ptr<char[]>* output);
+
+  // Serializes a GOAWAY frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeGoAwayFrame(const GoAwayFrame& goaway,
+                                            std::unique_ptr<char[]>* output);
+
+  // Serializes a PRIORITY_UPDATE frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializePriorityUpdateFrame(
+      const PriorityUpdateFrame& priority_update,
+      std::unique_ptr<char[]>* output);
+
+  // Serializes an ACCEPT_CH frame into a new buffer stored in |output|.
+  // Returns the length of the buffer on success, or 0 otherwise.
+  static QuicByteCount SerializeAcceptChFrame(const AcceptChFrame& accept_ch,
+                                              std::unique_ptr<char[]>* output);
+
+  // Serializes a frame with reserved frame type specified in
+  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9.
+  static QuicByteCount SerializeGreasingFrame(std::unique_ptr<char[]>* output);
+
+  // Serializes a WEBTRANSPORT_STREAM frame header as specified in
+  // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html#name-client-initiated-bidirectio
+  static QuicByteCount SerializeWebTransportStreamFrameHeader(
+      WebTransportSessionId session_id,
+      std::unique_ptr<char[]>* output);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_ENCODER_H_
diff --git a/quiche/quic/core/http/http_encoder_test.cc b/quiche/quic/core/http/http_encoder_test.cc
new file mode 100644
index 0000000..217d98a
--- /dev/null
+++ b/quiche/quic/core/http/http_encoder_test.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/http_encoder.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+TEST(HttpEncoderTest, SerializeDataFrameHeader) {
+  quiche::QuicheBuffer buffer = HttpEncoder::SerializeDataFrameHeader(
+      /* payload_length = */ 5, quiche::SimpleBufferAllocator::Get());
+  char output[] = {// type (DATA)
+                   0x00,
+                   // length
+                   0x05};
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), buffer.size());
+  quiche::test::CompareCharArraysWithHexError(
+      "DATA", buffer.data(), buffer.size(), output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializeHeadersFrameHeader) {
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeHeadersFrameHeader(
+      /* payload_length = */ 7, &buffer);
+  char output[] = {// type (HEADERS)
+                   0x01,
+                   // length
+                   0x07};
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+  quiche::test::CompareCharArraysWithHexError("HEADERS", buffer.get(), length,
+                                              output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializeSettingsFrame) {
+  SettingsFrame settings;
+  settings.values[1] = 2;
+  settings.values[6] = 5;
+  settings.values[256] = 4;
+  char output[] = {// type (SETTINGS)
+                   0x04,
+                   // length
+                   0x07,
+                   // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+                   0x01,
+                   // content
+                   0x02,
+                   // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+                   0x06,
+                   // content
+                   0x05,
+                   // identifier (256 in variable length integer)
+                   0x40 + 0x01, 0x00,
+                   // content
+                   0x04};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+  quiche::test::CompareCharArraysWithHexError("SETTINGS", buffer.get(), length,
+                                              output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializeGoAwayFrame) {
+  GoAwayFrame goaway;
+  goaway.id = 0x1;
+  char output[] = {// type (GOAWAY)
+                   0x07,
+                   // length
+                   0x1,
+                   // ID
+                   0x01};
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output), length);
+  quiche::test::CompareCharArraysWithHexError("GOAWAY", buffer.get(), length,
+                                              output, ABSL_ARRAYSIZE(output));
+}
+
+TEST(HttpEncoderTest, SerializePriorityUpdateFrame) {
+  PriorityUpdateFrame priority_update1;
+  priority_update1.prioritized_element_type = REQUEST_STREAM;
+  priority_update1.prioritized_element_id = 0x03;
+  uint8_t output1[] = {0x80, 0x0f, 0x07, 0x00,  // type (PRIORITY_UPDATE)
+                       0x01,                    // length
+                       0x03};                   // prioritized element id
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      HttpEncoder::SerializePriorityUpdateFrame(priority_update1, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
+  quiche::test::CompareCharArraysWithHexError(
+      "PRIORITY_UPDATE", buffer.get(), length, reinterpret_cast<char*>(output1),
+      ABSL_ARRAYSIZE(output1));
+}
+
+TEST(HttpEncoderTest, SerializeAcceptChFrame) {
+  AcceptChFrame accept_ch;
+  uint8_t output1[] = {0x40, 0x89,  // type (ACCEPT_CH)
+                       0x00};       // length
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output1), length);
+  quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
+                                              reinterpret_cast<char*>(output1),
+                                              ABSL_ARRAYSIZE(output1));
+
+  accept_ch.entries.push_back({"foo", "bar"});
+  uint8_t output2[] = {0x40, 0x89,               // type (ACCEPT_CH)
+                       0x08,                     // payload length
+                       0x03, 0x66, 0x6f, 0x6f,   // length of "foo"; "foo"
+                       0x03, 0x62, 0x61, 0x72};  // length of "bar"; "bar"
+
+  length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
+  EXPECT_EQ(ABSL_ARRAYSIZE(output2), length);
+  quiche::test::CompareCharArraysWithHexError("ACCEPT_CH", buffer.get(), length,
+                                              reinterpret_cast<char*>(output2),
+                                              ABSL_ARRAYSIZE(output2));
+}
+
+TEST(HttpEncoderTest, SerializeWebTransportStreamFrameHeader) {
+  WebTransportSessionId session_id = 0x17;
+  char output[] = {0x40, 0x41,  // type (WEBTRANSPORT_STREAM)
+                   0x17};       // session ID
+
+  std::unique_ptr<char[]> buffer;
+  uint64_t length =
+      HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &buffer);
+  EXPECT_EQ(sizeof(output), length);
+  quiche::test::CompareCharArraysWithHexError(
+      "WEBTRANSPORT_STREAM", buffer.get(), length, output, sizeof(output));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/http_frames.h b/quiche/quic/core/http/http_frames.h
new file mode 100644
index 0000000..c452a7d
--- /dev/null
+++ b/quiche/quic/core/http/http_frames.h
@@ -0,0 +1,187 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <ostream>
+#include <sstream>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+// TODO(b/171463363): Remove.
+using PushId = uint64_t;
+
+enum class HttpFrameType {
+  DATA = 0x0,
+  HEADERS = 0x1,
+  CANCEL_PUSH = 0X3,
+  SETTINGS = 0x4,
+  PUSH_PROMISE = 0x5,
+  GOAWAY = 0x7,
+  MAX_PUSH_ID = 0xD,
+  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
+  ACCEPT_CH = 0x89,
+  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-03
+  PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700,
+  // https://www.ietf.org/archive/id/draft-ietf-webtrans-http3-00.html
+  WEBTRANSPORT_STREAM = 0x41,
+};
+
+// 7.2.1.  DATA
+//
+//   DATA frames (type=0x0) convey arbitrary, variable-length sequences of
+//   octets associated with an HTTP request or response payload.
+struct QUIC_EXPORT_PRIVATE DataFrame {
+  absl::string_view data;
+};
+
+// 7.2.2.  HEADERS
+//
+//   The HEADERS frame (type=0x1) is used to carry a header block,
+//   compressed using QPACK.
+struct QUIC_EXPORT_PRIVATE HeadersFrame {
+  absl::string_view headers;
+};
+
+// 7.2.4.  SETTINGS
+//
+//   The SETTINGS frame (type=0x4) conveys configuration parameters that
+//   affect how endpoints communicate, such as preferences and constraints
+//   on peer behavior
+
+using SettingsMap = absl::flat_hash_map<uint64_t, uint64_t>;
+
+struct QUIC_EXPORT_PRIVATE SettingsFrame {
+  SettingsMap values;
+
+  bool operator==(const SettingsFrame& rhs) const {
+    return values == rhs.values;
+  }
+
+  std::string ToString() const {
+    std::string s;
+    for (auto it : values) {
+      std::string setting = absl::StrCat(
+          H3SettingsToString(
+              static_cast<Http3AndQpackSettingsIdentifiers>(it.first)),
+          " = ", it.second, "; ");
+      absl::StrAppend(&s, setting);
+    }
+    return s;
+  }
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const SettingsFrame& s) {
+    os << s.ToString();
+    return os;
+  }
+};
+
+// 7.2.6.  GOAWAY
+//
+//   The GOAWAY frame (type=0x7) is used to initiate shutdown of a connection by
+//   either endpoint.
+struct QUIC_EXPORT_PRIVATE GoAwayFrame {
+  // When sent from server to client, |id| is a stream ID that should refer to
+  // a client-initiated bidirectional stream.
+  // When sent from client to server, |id| is a push ID.
+  uint64_t id;
+
+  bool operator==(const GoAwayFrame& rhs) const { return id == rhs.id; }
+};
+
+// 7.2.7.  MAX_PUSH_ID
+//
+//   The MAX_PUSH_ID frame (type=0xD) is used by clients to control the
+//   number of server pushes that the server can initiate.
+struct QUIC_EXPORT_PRIVATE MaxPushIdFrame {
+  PushId push_id;
+
+  bool operator==(const MaxPushIdFrame& rhs) const {
+    return push_id == rhs.push_id;
+  }
+};
+
+// https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html
+//
+// The PRIORITY_UPDATE frame specifies the sender-advised priority of a stream.
+// Frame type 0xf0700 (called PRIORITY_UPDATE_REQUEST_STREAM in the
+// implementation) is used for for request streams.
+// Frame type 0xf0701 is used for push streams and is not implemented.
+
+// Length of a priority frame's first byte.
+const QuicByteCount kPriorityFirstByteLength = 1;
+
+enum PrioritizedElementType : uint8_t {
+  REQUEST_STREAM = 0x00,
+  PUSH_STREAM = 0x80,
+};
+
+struct QUIC_EXPORT_PRIVATE PriorityUpdateFrame {
+  PrioritizedElementType prioritized_element_type = REQUEST_STREAM;
+  uint64_t prioritized_element_id = 0;
+  std::string priority_field_value;
+
+  bool operator==(const PriorityUpdateFrame& rhs) const {
+    return std::tie(prioritized_element_type, prioritized_element_id,
+                    priority_field_value) ==
+           std::tie(rhs.prioritized_element_type, rhs.prioritized_element_id,
+                    rhs.priority_field_value);
+  }
+  std::string ToString() const {
+    return absl::StrCat("Priority Frame : {prioritized_element_type: ",
+                        static_cast<int>(prioritized_element_type),
+                        ", prioritized_element_id: ", prioritized_element_id,
+                        ", priority_field_value: ", priority_field_value, "}");
+  }
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const PriorityUpdateFrame& s) {
+    os << s.ToString();
+    return os;
+  }
+};
+
+// ACCEPT_CH
+// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02
+//
+struct QUIC_EXPORT_PRIVATE AcceptChFrame {
+  std::vector<spdy::AcceptChOriginValuePair> entries;
+
+  bool operator==(const AcceptChFrame& rhs) const {
+    return entries.size() == rhs.entries.size() &&
+           std::equal(entries.begin(), entries.end(), rhs.entries.begin());
+  }
+
+  std::string ToString() const {
+    std::stringstream s;
+    s << *this;
+    return s.str();
+  }
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const AcceptChFrame& frame) {
+    os << "ACCEPT_CH frame with " << frame.entries.size() << " entries: ";
+    for (auto& entry : frame.entries) {
+      os << "origin: " << entry.origin << "; value: " << entry.value;
+    }
+    return os;
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
diff --git a/quiche/quic/core/http/http_frames_test.cc b/quiche/quic/core/http/http_frames_test.cc
new file mode 100644
index 0000000..1eefd7e
--- /dev/null
+++ b/quiche/quic/core/http/http_frames_test.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/http_frames.h"
+
+#include <sstream>
+
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+TEST(HttpFramesTest, SettingsFrame) {
+  SettingsFrame a;
+  EXPECT_TRUE(a == a);
+  EXPECT_EQ("", a.ToString());
+
+  SettingsFrame b;
+  b.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  EXPECT_FALSE(a == b);
+  EXPECT_TRUE(b == b);
+
+  a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+  EXPECT_FALSE(a == b);
+  a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  EXPECT_TRUE(a == b);
+
+  EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", b.ToString());
+  std::stringstream s;
+  s << b;
+  EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", s.str());
+}
+
+TEST(HttpFramesTest, GoAwayFrame) {
+  GoAwayFrame a{1};
+  EXPECT_TRUE(a == a);
+
+  GoAwayFrame b{2};
+  EXPECT_FALSE(a == b);
+
+  b.id = 1;
+  EXPECT_TRUE(a == b);
+}
+
+TEST(HttpFramesTest, MaxPushIdFrame) {
+  MaxPushIdFrame a{1};
+  EXPECT_TRUE(a == a);
+
+  MaxPushIdFrame b{2};
+  EXPECT_FALSE(a == b);
+
+  b.push_id = 1;
+  EXPECT_TRUE(a == b);
+}
+
+TEST(HttpFramesTest, PriorityUpdateFrame) {
+  PriorityUpdateFrame a{REQUEST_STREAM, 0, ""};
+  EXPECT_TRUE(a == a);
+  PriorityUpdateFrame b{REQUEST_STREAM, 4, ""};
+  EXPECT_FALSE(a == b);
+  a.prioritized_element_id = 4;
+  EXPECT_TRUE(a == b);
+
+  a.prioritized_element_type = PUSH_STREAM;
+  EXPECT_FALSE(a == b);
+  b.prioritized_element_type = PUSH_STREAM;
+  EXPECT_TRUE(a == b);
+
+  a.priority_field_value = "foo";
+  EXPECT_FALSE(a == b);
+
+  EXPECT_EQ(
+      "Priority Frame : {prioritized_element_type: 128, "
+      "prioritized_element_id: 4, priority_field_value: foo}",
+      a.ToString());
+  std::stringstream s;
+  s << a;
+  EXPECT_EQ(
+      "Priority Frame : {prioritized_element_type: 128, "
+      "prioritized_element_id: 4, priority_field_value: foo}",
+      s.str());
+}
+
+TEST(HttpFramesTest, AcceptChFrame) {
+  AcceptChFrame a;
+  EXPECT_TRUE(a == a);
+  EXPECT_EQ("ACCEPT_CH frame with 0 entries: ", a.ToString());
+
+  AcceptChFrame b{{{"foo", "bar"}}};
+  EXPECT_FALSE(a == b);
+
+  a.entries.push_back({"foo", "bar"});
+  EXPECT_TRUE(a == b);
+
+  EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar",
+            a.ToString());
+  std::stringstream s;
+  s << a;
+  EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar", s.str());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_promised_info.cc b/quiche/quic/core/http/quic_client_promised_info.cc
new file mode 100644
index 0000000..18bb5dd
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_promised_info.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicClientPromisedInfo::QuicClientPromisedInfo(
+    QuicSpdyClientSessionBase* session,
+    QuicStreamId id,
+    std::string url)
+    : session_(session),
+      id_(id),
+      url_(std::move(url)),
+      client_request_delegate_(nullptr) {}
+
+QuicClientPromisedInfo::~QuicClientPromisedInfo() {
+  if (cleanup_alarm_ != nullptr) {
+    cleanup_alarm_->PermanentCancel();
+  }
+}
+
+void QuicClientPromisedInfo::CleanupAlarm::OnAlarm() {
+  QUIC_DVLOG(1) << "self GC alarm for stream " << promised_->id_;
+  promised_->session()->OnPushStreamTimedOut(promised_->id_);
+  promised_->Reset(QUIC_PUSH_STREAM_TIMED_OUT);
+}
+
+void QuicClientPromisedInfo::Init() {
+  cleanup_alarm_.reset(session_->connection()->alarm_factory()->CreateAlarm(
+      new QuicClientPromisedInfo::CleanupAlarm(this)));
+  cleanup_alarm_->Set(
+      session_->connection()->helper()->GetClock()->ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs));
+}
+
+bool QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
+  // RFC7540, Section 8.2, requests MUST be safe [RFC7231], Section
+  // 4.2.1.  GET and HEAD are the methods that are safe and required.
+  SpdyHeaderBlock::const_iterator it = headers.find(spdy::kHttp2MethodHeader);
+  if (it == headers.end()) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has no method";
+    Reset(QUIC_INVALID_PROMISE_METHOD);
+    return false;
+  }
+  if (!(it->second == "GET" || it->second == "HEAD")) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid method "
+                  << it->second;
+    Reset(QUIC_INVALID_PROMISE_METHOD);
+    return false;
+  }
+  if (!SpdyServerPushUtils::PromisedUrlIsValid(headers)) {
+    QUIC_DVLOG(1) << "Promise for stream " << id_ << " has invalid URL "
+                  << url_;
+    Reset(QUIC_INVALID_PROMISE_URL);
+    return false;
+  }
+  if (!session_->IsAuthorized(
+          SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers))) {
+    Reset(QUIC_UNAUTHORIZED_PROMISE_URL);
+    return false;
+  }
+  request_headers_ = headers.Clone();
+  return true;
+}
+
+void QuicClientPromisedInfo::OnResponseHeaders(const SpdyHeaderBlock& headers) {
+  response_headers_ = std::make_unique<SpdyHeaderBlock>(headers.Clone());
+  if (client_request_delegate_) {
+    // We already have a client request waiting.
+    FinalValidation();
+  }
+}
+
+void QuicClientPromisedInfo::Reset(QuicRstStreamErrorCode error_code) {
+  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
+  session_->ResetPromised(id_, error_code);
+  session_->DeletePromised(this);
+  if (delegate) {
+    delegate->OnRendezvousResult(nullptr);
+  }
+}
+
+QuicAsyncStatus QuicClientPromisedInfo::FinalValidation() {
+  if (!client_request_delegate_->CheckVary(
+          client_request_headers_, request_headers_, *response_headers_)) {
+    Reset(QUIC_PROMISE_VARY_MISMATCH);
+    return QUIC_FAILURE;
+  }
+  QuicSpdyStream* stream = session_->GetPromisedStream(id_);
+  if (!stream) {
+    // This shouldn't be possible, as |ClientRequest| guards against
+    // closed stream for the synchronous case.  And in the
+    // asynchronous case, a RST can only be caught by |OnAlarm()|.
+    QUIC_BUG(quic_bug_10378_1) << "missing promised stream" << id_;
+  }
+  QuicClientPushPromiseIndex::Delegate* delegate = client_request_delegate_;
+  session_->DeletePromised(this);
+  // Stream can start draining now
+  if (delegate) {
+    delegate->OnRendezvousResult(stream);
+  }
+  return QUIC_SUCCESS;
+}
+
+QuicAsyncStatus QuicClientPromisedInfo::HandleClientRequest(
+    const SpdyHeaderBlock& request_headers,
+    QuicClientPushPromiseIndex::Delegate* delegate) {
+  if (session_->IsClosedStream(id_)) {
+    // There was a RST on the response stream.
+    session_->DeletePromised(this);
+    return QUIC_FAILURE;
+  }
+
+  if (is_validating()) {
+    // The push promise has already been matched to another request though
+    // pending for validation. Returns QUIC_FAILURE to the caller as it couldn't
+    // match a new request any more. This will not affect the validation of the
+    // other request.
+    return QUIC_FAILURE;
+  }
+
+  client_request_delegate_ = delegate;
+  client_request_headers_ = request_headers.Clone();
+  if (response_headers_ == nullptr) {
+    return QUIC_PENDING;
+  }
+  return FinalValidation();
+}
+
+void QuicClientPromisedInfo::Cancel() {
+  // Don't fire OnRendezvousResult() for client initiated cancel.
+  client_request_delegate_ = nullptr;
+  Reset(QUIC_STREAM_CANCELLED);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_promised_info.h b/quiche/quic/core/http/quic_client_promised_info.h
new file mode 100644
index 0000000..77d32af
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_promised_info.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
+
+#include <cstddef>
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+namespace test {
+class QuicClientPromisedInfoPeer;
+}  // namespace test
+
+// QuicClientPromisedInfo tracks the client state of a server push
+// stream from the time a PUSH_PROMISE is received until rendezvous
+// between the promised response and the corresponding client request
+// is complete.
+class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
+    : public QuicClientPushPromiseIndex::TryHandle {
+ public:
+  // Interface to QuicSpdyClientStream
+  QuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
+                         QuicStreamId id,
+                         std::string url);
+  QuicClientPromisedInfo(const QuicClientPromisedInfo&) = delete;
+  QuicClientPromisedInfo& operator=(const QuicClientPromisedInfo&) = delete;
+  virtual ~QuicClientPromisedInfo();
+
+  void Init();
+
+  // Validate promise headers etc. Returns true if headers are valid.
+  bool OnPromiseHeaders(const spdy::SpdyHeaderBlock& headers);
+
+  // Store response, possibly proceed with final validation.
+  void OnResponseHeaders(const spdy::SpdyHeaderBlock& headers);
+
+  // Rendezvous between this promised stream and a client request that
+  // has a matching URL.
+  virtual QuicAsyncStatus HandleClientRequest(
+      const spdy::SpdyHeaderBlock& headers,
+      QuicClientPushPromiseIndex::Delegate* delegate);
+
+  void Cancel() override;
+
+  void Reset(QuicRstStreamErrorCode error_code);
+
+  // Client requests are initially associated to promises by matching
+  // URL in the client request against the URL in the promise headers,
+  // uing the |promised_by_url| map.  The push can be cross-origin, so
+  // the client should validate that the session is authoritative for
+  // the promised URL.  If not, it should call |RejectUnauthorized|.
+  QuicSpdyClientSessionBase* session() { return session_; }
+
+  // If the promised response contains Vary header, then the fields
+  // specified by Vary must match between the client request header
+  // and the promise headers (see https://crbug.com//554220).  Vary
+  // validation requires the response headers (for the actual Vary
+  // field list), the promise headers (taking the role of the "cached"
+  // request), and the client request headers.
+  spdy::SpdyHeaderBlock* request_headers() { return &request_headers_; }
+
+  spdy::SpdyHeaderBlock* response_headers() { return response_headers_.get(); }
+
+  // After validation, client will use this to access the pushed stream.
+
+  QuicStreamId id() const { return id_; }
+
+  const std::string url() const { return url_; }
+
+  // Return true if there's a request pending matching this push promise.
+  bool is_validating() const { return client_request_delegate_ != nullptr; }
+
+ private:
+  friend class test::QuicClientPromisedInfoPeer;
+
+  class QUIC_EXPORT_PRIVATE CleanupAlarm
+      : public QuicAlarm::DelegateWithoutContext {
+   public:
+    explicit CleanupAlarm(QuicClientPromisedInfo* promised)
+        : promised_(promised) {}
+
+    void OnAlarm() override;
+
+    QuicClientPromisedInfo* promised_;
+  };
+
+  QuicAsyncStatus FinalValidation();
+
+  QuicSpdyClientSessionBase* session_;
+  QuicStreamId id_;
+  std::string url_;
+  spdy::SpdyHeaderBlock request_headers_;
+  std::unique_ptr<spdy::SpdyHeaderBlock> response_headers_;
+  spdy::SpdyHeaderBlock client_request_headers_;
+  QuicClientPushPromiseIndex::Delegate* client_request_delegate_;
+
+  // The promise will commit suicide eventually if it is not claimed by a GET
+  // first.
+  std::unique_ptr<QuicAlarm> cleanup_alarm_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/quiche/quic/core/http/quic_client_promised_info_test.cc b/quiche/quic/core/http/quic_client_promised_info_test.cc
new file mode 100644
index 0000000..287e961
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_promised_info_test.cc
@@ -0,0 +1,356 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_client_promised_info_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+        authorized_(true) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override {}
+
+  bool IsAuthorized(const std::string& /*authority*/) override {
+    return authorized_;
+  }
+
+  void set_authorized(bool authorized) { authorized_ = authorized; }
+
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+
+  bool authorized_;
+};
+
+class QuicClientPromisedInfoTest : public QuicTest {
+ public:
+  class StreamVisitor;
+
+  QuicClientPromisedInfoTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       Perspective::IS_CLIENT)),
+        session_(connection_->supported_versions(),
+                 connection_,
+                 &push_promise_index_),
+        body_("hello world"),
+        promise_id_(
+            QuicUtils::GetInvalidStreamId(connection_->transport_version())) {
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_.Initialize();
+
+    headers_[":status"] = "200";
+    headers_["content-length"] = "11";
+
+    stream_ = std::make_unique<QuicSpdyClientStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    stream_visitor_ = std::make_unique<StreamVisitor>();
+    stream_->set_visitor(stream_visitor_.get());
+
+    push_promise_[":path"] = "/bar";
+    push_promise_[":authority"] = "www.google.com";
+    push_promise_[":method"] = "GET";
+    push_promise_[":scheme"] = "https";
+
+    promise_url_ =
+        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
+
+    client_request_ = push_promise_.Clone();
+    promise_id_ = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 0);
+  }
+
+  class StreamVisitor : public QuicSpdyClientStream::Visitor {
+    void OnClose(QuicSpdyStream* stream) override {
+      QUIC_DVLOG(1) << "stream " << stream->id();
+    }
+  };
+
+  void ReceivePromise(QuicStreamId id) {
+    auto headers = AsHeaderList(push_promise_);
+    stream_->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
+                                 headers);
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  MockQuicSpdyClientSession session_;
+  std::unique_ptr<QuicSpdyClientStream> stream_;
+  std::unique_ptr<StreamVisitor> stream_visitor_;
+  std::unique_ptr<QuicSpdyClientStream> promised_stream_;
+  SpdyHeaderBlock headers_;
+  std::string body_;
+  SpdyHeaderBlock push_promise_;
+  QuicStreamId promise_id_;
+  std::string promise_url_;
+  SpdyHeaderBlock client_request_;
+};
+
+TEST_F(QuicClientPromisedInfoTest, PushPromise) {
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise is in the unclaimed streams map.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) {
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise is in the unclaimed streams map.
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Fire the alarm that will cancel the promised stream.
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
+  alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
+
+  // Verify that the promise is gone after the alarm fires.
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) {
+  // Promise with an unsafe method
+  push_promise_[":method"] = "PUT";
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) {
+  // Promise with a missing method
+  push_promise_.erase(":method");
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
+  // Remove required header field to make URL invalid
+  push_promise_.erase(":authority");
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
+  ReceivePromise(promise_id_);
+
+  // Verify that the promise headers were ignored
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  EXPECT_EQ(session_.GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
+  session_.set_authorized(false);
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
+
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_EQ(promised, nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Need to send the promised response headers and initiate the
+  // rendezvous for secondary validation to proceed.
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  TestPushPromiseDelegate delegate(/*match=*/false);
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
+
+  promised->HandleClientRequest(client_request_, &delegate);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryWaits) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  EXPECT_FALSE(promised->is_validating());
+  ASSERT_NE(promised, nullptr);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+  EXPECT_TRUE(promised->is_validating());
+
+  // Promise is still there, waiting for response.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+
+  // Send Response, should trigger promise validation and complete rendezvous
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseVaryNoWait) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+
+  // Send Response, should trigger promise validation and complete rendezvous
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+  // Have a push stream
+  EXPECT_TRUE(delegate.rendezvous_fired());
+
+  EXPECT_NE(delegate.rendezvous_stream(), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  promised->HandleClientRequest(client_request_, &delegate);
+
+  // Promise is still there, waiting for response.
+  EXPECT_NE(session_.GetPromisedById(promise_id_), nullptr);
+
+  // Create response stream, but no data yet.
+  session_.GetOrCreateStream(promise_id_);
+
+  // Cancel the promised stream.
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
+  promised->Cancel();
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
+  ReceivePromise(promise_id_);
+
+  QuicClientPromisedInfo* promised = session_.GetPromisedById(promise_id_);
+  ASSERT_NE(promised, nullptr);
+
+  QuicSpdyClientStream* promise_stream = static_cast<QuicSpdyClientStream*>(
+      session_.GetOrCreateStream(promise_id_));
+  ASSERT_NE(promise_stream, nullptr);
+
+  // Send response, rendezvous will be able to finish synchronously.
+  auto headers = AsHeaderList(headers_);
+  promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                                     headers);
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
+  session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY);
+
+  // Now initiate rendezvous.
+  TestPushPromiseDelegate delegate(/*match=*/true);
+  EXPECT_EQ(promised->HandleClientRequest(client_request_, &delegate),
+            QUIC_FAILURE);
+
+  // Got an indication of the stream failure, client should retry
+  // request.
+  EXPECT_FALSE(delegate.rendezvous_fired());
+  EXPECT_EQ(delegate.rendezvous_stream(), nullptr);
+
+  // Promise is gone
+  EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_push_promise_index.cc b/quiche/quic/core/http/quic_client_push_promise_index.cc
new file mode 100644
index 0000000..d1e0cf4
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_push_promise_index.cc
@@ -0,0 +1,48 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicClientPushPromiseIndex::QuicClientPushPromiseIndex() {}
+
+QuicClientPushPromiseIndex::~QuicClientPushPromiseIndex() {}
+
+QuicClientPushPromiseIndex::TryHandle::~TryHandle() {}
+
+QuicClientPromisedInfo* QuicClientPushPromiseIndex::GetPromised(
+    const std::string& url) {
+  auto it = promised_by_url_.find(url);
+  if (it == promised_by_url_.end()) {
+    return nullptr;
+  }
+  return it->second;
+}
+
+QuicAsyncStatus QuicClientPushPromiseIndex::Try(
+    const spdy::SpdyHeaderBlock& request,
+    QuicClientPushPromiseIndex::Delegate* delegate,
+    TryHandle** handle) {
+  std::string url(SpdyServerPushUtils::GetPromisedUrlFromHeaders(request));
+  auto it = promised_by_url_.find(url);
+  if (it != promised_by_url_.end()) {
+    QuicClientPromisedInfo* promised = it->second;
+    QuicAsyncStatus rv = promised->HandleClientRequest(request, delegate);
+    if (rv == QUIC_PENDING) {
+      *handle = promised;
+    }
+    return rv;
+  }
+  return QUIC_FAILURE;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_client_push_promise_index.h b/quiche/quic/core/http/quic_client_push_promise_index.h
new file mode 100644
index 0000000..66570b9
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_push_promise_index.h
@@ -0,0 +1,99 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicClientPushPromiseIndex is the interface to support rendezvous
+// between client requests and resources delivered via server push.
+// The same index can be shared across multiple sessions (e.g. for the
+// same browser users profile), since cross-origin pushes are allowed
+// (subject to authority constraints).
+
+class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
+ public:
+  // Delegate is used to complete the rendezvous that began with
+  // |Try()|.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // The primary lookup matched request with push promise by URL.  A
+    // secondary match is necessary to ensure Vary (RFC 2616, 14.14)
+    // is honored.  If Vary is not present, return true.  If Vary is
+    // present, return whether designated header fields of
+    // |promise_request| and |client_request| match.
+    virtual bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
+                           const spdy::SpdyHeaderBlock& promise_request,
+                           const spdy::SpdyHeaderBlock& promise_response) = 0;
+
+    // On rendezvous success, provides the promised |stream|.  Callee
+    // does not inherit ownership of |stream|.  On rendezvous failure,
+    // |stream| is |nullptr| and the client should retry the request.
+    // Rendezvous can fail due to promise validation failure or RST on
+    // promised stream.  |url| will have been removed from the index
+    // before |OnRendezvousResult()| is invoked, so a recursive call to
+    // |Try()| will return |QUIC_FAILURE|, which may be convenient for
+    // retry purposes.
+    virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
+  };
+
+  class QUIC_EXPORT_PRIVATE TryHandle {
+   public:
+    // Cancel the request.
+    virtual void Cancel() = 0;
+
+   protected:
+    TryHandle() {}
+    TryHandle(const TryHandle&) = delete;
+    TryHandle& operator=(const TryHandle&) = delete;
+    ~TryHandle();
+  };
+
+  QuicClientPushPromiseIndex();
+  QuicClientPushPromiseIndex(const QuicClientPushPromiseIndex&) = delete;
+  QuicClientPushPromiseIndex& operator=(const QuicClientPushPromiseIndex&) =
+      delete;
+  virtual ~QuicClientPushPromiseIndex();
+
+  // Called by client code, used to enforce affinity between requests
+  // for promised streams and the session the promise came from.
+  QuicClientPromisedInfo* GetPromised(const std::string& url);
+
+  // Called by client code, to initiate rendezvous between a request
+  // and a server push stream.  If |request|'s url is in the index,
+  // rendezvous will be attempted and may complete immediately or
+  // asynchronously.  If the matching promise and response headers
+  // have already arrived, the delegate's methods will fire
+  // recursively from within |Try()|.  Returns |QUIC_SUCCESS| if the
+  // rendezvous was a success. Returns |QUIC_FAILURE| if there was no
+  // matching promise, or if there was but the rendezvous has failed.
+  // Returns QUIC_PENDING if a matching promise was found, but the
+  // rendezvous needs to complete asynchronously because the promised
+  // response headers are not yet available.  If result is
+  // QUIC_PENDING, then |*handle| will set so that the caller may
+  // cancel the request if need be.  The caller does not inherit
+  // ownership of |*handle|, and it ceases to be valid if the caller
+  // invokes |handle->Cancel()| or if |delegate->OnReponse()| fires.
+  QuicAsyncStatus Try(const spdy::SpdyHeaderBlock& request,
+                      Delegate* delegate,
+                      TryHandle** handle);
+
+  QuicPromisedByUrlMap* promised_by_url() { return &promised_by_url_; }
+
+ private:
+  QuicPromisedByUrlMap promised_by_url_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_CLIENT_PUSH_PROMISE_INDEX_H_
diff --git a/quiche/quic/core/http/quic_client_push_promise_index_test.cc b/quiche/quic/core/http/quic_client_push_promise_index_test.cc
new file mode 100644
index 0000000..6f7c3ac
--- /dev/null
+++ b/quiche/quic/core/http/quic_client_push_promise_index_test.cc
@@ -0,0 +1,113 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_quic_client_promised_info.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override {}
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+};
+
+class QuicClientPushPromiseIndexTest : public QuicTest {
+ public:
+  QuicClientPushPromiseIndexTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       Perspective::IS_CLIENT)),
+        session_(connection_->supported_versions(), connection_, &index_),
+        promised_(&session_,
+                  GetNthServerInitiatedUnidirectionalStreamId(
+                      connection_->transport_version(),
+                      0),
+                  url_) {
+    request_[":path"] = "/bar";
+    request_[":authority"] = "www.google.com";
+    request_[":method"] = "GET";
+    request_[":scheme"] = "https";
+    url_ = SpdyServerPushUtils::GetPromisedUrlFromHeaders(request_);
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  MockQuicSpdyClientSession session_;
+  QuicClientPushPromiseIndex index_;
+  spdy::SpdyHeaderBlock request_;
+  std::string url_;
+  MockQuicClientPromisedInfo promised_;
+  QuicClientPushPromiseIndex::TryHandle* handle_;
+};
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestSuccess) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_SUCCESS));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_SUCCESS);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestPending) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_PENDING));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_PENDING);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryRequestFailure) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_CALL(promised_, HandleClientRequest(_, _))
+      .WillOnce(Return(QUIC_FAILURE));
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, TryNoPromise) {
+  EXPECT_EQ(index_.Try(request_, nullptr, &handle_), QUIC_FAILURE);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, GetNoPromise) {
+  EXPECT_EQ(index_.GetPromised(url_), nullptr);
+}
+
+TEST_F(QuicClientPushPromiseIndexTest, GetPromise) {
+  (*index_.promised_by_url())[url_] = &promised_;
+  EXPECT_EQ(index_.GetPromised(url_), &promised_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_header_list.cc b/quiche/quic/core/http/quic_header_list.cc
new file mode 100644
index 0000000..771e617
--- /dev/null
+++ b/quiche/quic/core/http/quic_header_list.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_header_list.h"
+
+#include <limits>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicHeaderList::QuicHeaderList()
+    : max_header_list_size_(std::numeric_limits<size_t>::max()),
+      current_header_list_size_(0),
+      uncompressed_header_bytes_(0),
+      compressed_header_bytes_(0) {}
+
+QuicHeaderList::QuicHeaderList(QuicHeaderList&& other) = default;
+
+QuicHeaderList::QuicHeaderList(const QuicHeaderList& other) = default;
+
+QuicHeaderList& QuicHeaderList::operator=(const QuicHeaderList& other) =
+    default;
+
+QuicHeaderList& QuicHeaderList::operator=(QuicHeaderList&& other) = default;
+
+QuicHeaderList::~QuicHeaderList() {}
+
+void QuicHeaderList::OnHeaderBlockStart() {
+  QUIC_BUG_IF(quic_bug_12518_1, current_header_list_size_ != 0)
+      << "OnHeaderBlockStart called more than once!";
+}
+
+void QuicHeaderList::OnHeader(absl::string_view name, absl::string_view value) {
+  // Avoid infinite buffering of headers. No longer store headers
+  // once the current headers are over the limit.
+  if (current_header_list_size_ < max_header_list_size_) {
+    current_header_list_size_ += name.size();
+    current_header_list_size_ += value.size();
+    current_header_list_size_ += kQpackEntrySizeOverhead;
+    header_list_.emplace_back(std::string(name), std::string(value));
+  }
+}
+
+void QuicHeaderList::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                                      size_t compressed_header_bytes) {
+  uncompressed_header_bytes_ = uncompressed_header_bytes;
+  compressed_header_bytes_ = compressed_header_bytes;
+  if (current_header_list_size_ > max_header_list_size_) {
+    Clear();
+  }
+}
+
+void QuicHeaderList::Clear() {
+  header_list_.clear();
+  current_header_list_size_ = 0;
+  uncompressed_header_bytes_ = 0;
+  compressed_header_bytes_ = 0;
+}
+
+std::string QuicHeaderList::DebugString() const {
+  std::string s = "{ ";
+  for (const auto& p : *this) {
+    s.append(p.first + "=" + p.second + ", ");
+  }
+  s.append("}");
+  return s;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_header_list.h b/quiche/quic/core/http/quic_header_list.h
new file mode 100644
index 0000000..9cccf02
--- /dev/null
+++ b/quiche/quic/core/http/quic_header_list.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
+
+#include <algorithm>
+#include <functional>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+
+namespace quic {
+
+// A simple class that accumulates header pairs
+class QUIC_EXPORT_PRIVATE QuicHeaderList
+    : public spdy::SpdyHeadersHandlerInterface {
+ public:
+  using ListType =
+      quiche::QuicheCircularDeque<std::pair<std::string, std::string>>;
+  using value_type = ListType::value_type;
+  using const_iterator = ListType::const_iterator;
+
+  QuicHeaderList();
+  QuicHeaderList(QuicHeaderList&& other);
+  QuicHeaderList(const QuicHeaderList& other);
+  QuicHeaderList& operator=(QuicHeaderList&& other);
+  QuicHeaderList& operator=(const QuicHeaderList& other);
+  ~QuicHeaderList() override;
+
+  // From SpdyHeadersHandlerInteface.
+  void OnHeaderBlockStart() override;
+  void OnHeader(absl::string_view name, absl::string_view value) override;
+  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                        size_t compressed_header_bytes) override;
+
+  void Clear();
+
+  const_iterator begin() const { return header_list_.begin(); }
+  const_iterator end() const { return header_list_.end(); }
+
+  bool empty() const { return header_list_.empty(); }
+  size_t uncompressed_header_bytes() const {
+    return uncompressed_header_bytes_;
+  }
+  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
+
+  // Deprecated.  TODO(b/145909215): remove.
+  void set_max_header_list_size(size_t max_header_list_size) {
+    max_header_list_size_ = max_header_list_size;
+  }
+
+  std::string DebugString() const;
+
+ private:
+  quiche::QuicheCircularDeque<std::pair<std::string, std::string>> header_list_;
+
+  // The limit on the size of the header list (defined by spec as name + value +
+  // overhead for each header field). Headers over this limit will not be
+  // buffered, and the list will be cleared upon OnHeaderBlockEnd.
+  size_t max_header_list_size_;
+
+  // Defined per the spec as the size of all header fields with an additional
+  // overhead for each field.
+  size_t current_header_list_size_;
+
+  // TODO(dahollings) Are these fields necessary?
+  size_t uncompressed_header_bytes_;
+  size_t compressed_header_bytes_;
+};
+
+inline bool operator==(const QuicHeaderList& l1, const QuicHeaderList& l2) {
+  auto pred = [](const std::pair<std::string, std::string>& p1,
+                 const std::pair<std::string, std::string>& p2) {
+    return p1.first == p2.first && p1.second == p2.second;
+  };
+  return std::equal(l1.begin(), l1.end(), l2.begin(), pred);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADER_LIST_H_
diff --git a/quiche/quic/core/http/quic_header_list_test.cc b/quiche/quic/core/http/quic_header_list_test.cc
new file mode 100644
index 0000000..6007bcc
--- /dev/null
+++ b/quiche/quic/core/http/quic_header_list_test.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_header_list.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
+namespace quic {
+
+class QuicHeaderListTest : public QuicTest {};
+
+// This test verifies that QuicHeaderList accumulates header pairs in order.
+TEST_F(QuicHeaderListTest, OnHeader) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
+                                   Pair("beep", "")));
+}
+
+TEST_F(QuicHeaderListTest, DebugString) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers.DebugString());
+}
+
+TEST_F(QuicHeaderListTest, TooLarge) {
+  const size_t kMaxHeaderListSize = 256;
+
+  QuicHeaderList headers;
+  headers.set_max_header_list_size(kMaxHeaderListSize);
+  std::string key = "key";
+  std::string value(kMaxHeaderListSize, '1');
+  // Send a header that exceeds max_header_list_size.
+  headers.OnHeader(key, value);
+  // Send a second header exceeding max_header_list_size.
+  headers.OnHeader(key + "2", value);
+  // We should not allocate more memory after exceeding max_header_list_size.
+  EXPECT_LT(headers.DebugString().size(), 2 * value.size());
+  size_t total_bytes = 2 * (key.size() + value.size()) + 1;
+  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
+
+  EXPECT_TRUE(headers.empty());
+  EXPECT_EQ("{ }", headers.DebugString());
+}
+
+TEST_F(QuicHeaderListTest, NotTooLarge) {
+  QuicHeaderList headers;
+  headers.set_max_header_list_size(1 << 20);
+  std::string key = "key";
+  std::string value(1 << 18, '1');
+  headers.OnHeader(key, value);
+  size_t total_bytes = key.size() + value.size();
+  headers.OnHeaderBlockEnd(total_bytes, total_bytes);
+  EXPECT_FALSE(headers.empty());
+}
+
+// This test verifies that QuicHeaderList is copyable and assignable.
+TEST_F(QuicHeaderListTest, IsCopyableAndAssignable) {
+  QuicHeaderList headers;
+  headers.OnHeader("foo", "bar");
+  headers.OnHeader("april", "fools");
+  headers.OnHeader("beep", "");
+
+  QuicHeaderList headers2(headers);
+  QuicHeaderList headers3 = headers;
+
+  EXPECT_THAT(headers2, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
+                                    Pair("beep", "")));
+  EXPECT_THAT(headers3, ElementsAre(Pair("foo", "bar"), Pair("april", "fools"),
+                                    Pair("beep", "")));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_headers_stream.cc b/quiche/quic/core/http/quic_headers_stream.cc
new file mode 100644
index 0000000..81ebaef
--- /dev/null
+++ b/quiche/quic/core/http/quic_headers_stream.cc
@@ -0,0 +1,164 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_headers_stream.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
+    QuicStreamOffset headers_stream_offset, QuicStreamOffset full_length,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener)
+    : headers_stream_offset(headers_stream_offset),
+      full_length(full_length),
+      unacked_length(full_length),
+      ack_listener(std::move(ack_listener)) {}
+
+QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
+    const CompressedHeaderInfo& other) = default;
+
+QuicHeadersStream::CompressedHeaderInfo::~CompressedHeaderInfo() {}
+
+QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
+    : QuicStream(QuicUtils::GetHeadersStreamId(session->transport_version()),
+                 session,
+                 /*is_static=*/true,
+                 BIDIRECTIONAL),
+      spdy_session_(session) {
+  // The headers stream is exempt from connection level flow control.
+  DisableConnectionFlowControlForThisStream();
+}
+
+QuicHeadersStream::~QuicHeadersStream() {}
+
+void QuicHeadersStream::OnDataAvailable() {
+  struct iovec iov;
+  while (sequencer()->GetReadableRegion(&iov)) {
+    if (spdy_session_->ProcessHeaderData(iov) != iov.iov_len) {
+      // Error processing data.
+      return;
+    }
+    sequencer()->MarkConsumed(iov.iov_len);
+    MaybeReleaseSequencerBuffer();
+  }
+}
+
+void QuicHeadersStream::MaybeReleaseSequencerBuffer() {
+  if (spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
+    sequencer()->ReleaseBufferIfEmpty();
+  }
+}
+
+bool QuicHeadersStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                           QuicByteCount data_length,
+                                           bool fin_acked,
+                                           QuicTime::Delta ack_delay_time,
+                                           QuicTime receive_timestamp,
+                                           QuicByteCount* newly_acked_length) {
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Difference(bytes_acked());
+  for (const auto& acked : newly_acked) {
+    QuicStreamOffset acked_offset = acked.min();
+    QuicByteCount acked_length = acked.max() - acked.min();
+    for (CompressedHeaderInfo& header : unacked_headers_) {
+      if (acked_offset < header.headers_stream_offset) {
+        // This header frame offset belongs to headers with smaller offset, stop
+        // processing.
+        break;
+      }
+
+      if (acked_offset >= header.headers_stream_offset + header.full_length) {
+        // This header frame belongs to headers with larger offset.
+        continue;
+      }
+
+      QuicByteCount header_offset = acked_offset - header.headers_stream_offset;
+      QuicByteCount header_length =
+          std::min(acked_length, header.full_length - header_offset);
+
+      if (header.unacked_length < header_length) {
+        QUIC_BUG(quic_bug_10416_1)
+            << "Unsent stream data is acked. unacked_length: "
+            << header.unacked_length << " acked_length: " << header_length;
+        OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                             "Unsent stream data is acked");
+        return false;
+      }
+      if (header.ack_listener != nullptr && header_length > 0) {
+        header.ack_listener->OnPacketAcked(header_length, ack_delay_time);
+      }
+      header.unacked_length -= header_length;
+      acked_offset += header_length;
+      acked_length -= header_length;
+    }
+  }
+  // Remove headers which are fully acked. Please note, header frames can be
+  // acked out of order, but unacked_headers_ is cleaned up in order.
+  while (!unacked_headers_.empty() &&
+         unacked_headers_.front().unacked_length == 0) {
+    unacked_headers_.pop_front();
+  }
+  return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
+                                        ack_delay_time, receive_timestamp,
+                                        newly_acked_length);
+}
+
+void QuicHeadersStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                                   QuicByteCount data_length,
+                                                   bool /*fin_retransmitted*/) {
+  QuicStream::OnStreamFrameRetransmitted(offset, data_length, false);
+  for (CompressedHeaderInfo& header : unacked_headers_) {
+    if (offset < header.headers_stream_offset) {
+      // This header frame offset belongs to headers with smaller offset, stop
+      // processing.
+      break;
+    }
+
+    if (offset >= header.headers_stream_offset + header.full_length) {
+      // This header frame belongs to headers with larger offset.
+      continue;
+    }
+
+    QuicByteCount header_offset = offset - header.headers_stream_offset;
+    QuicByteCount retransmitted_length =
+        std::min(data_length, header.full_length - header_offset);
+    if (header.ack_listener != nullptr && retransmitted_length > 0) {
+      header.ack_listener->OnPacketRetransmitted(retransmitted_length);
+    }
+    offset += retransmitted_length;
+    data_length -= retransmitted_length;
+  }
+}
+
+void QuicHeadersStream::OnDataBuffered(
+    QuicStreamOffset offset, QuicByteCount data_length,
+    const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
+        ack_listener) {
+  // Populate unacked_headers_.
+  if (!unacked_headers_.empty() &&
+      (offset == unacked_headers_.back().headers_stream_offset +
+                     unacked_headers_.back().full_length) &&
+      ack_listener == unacked_headers_.back().ack_listener) {
+    // Try to combine with latest inserted entry if they belong to the same
+    // header (i.e., having contiguous offset and the same ack listener).
+    unacked_headers_.back().full_length += data_length;
+    unacked_headers_.back().unacked_length += data_length;
+  } else {
+    unacked_headers_.push_back(
+        CompressedHeaderInfo(offset, data_length, ack_listener));
+  }
+}
+
+void QuicHeadersStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
+                                   "Attempt to reset headers stream");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_headers_stream.h b/quiche/quic/core/http/quic_headers_stream.h
new file mode 100644
index 0000000..a5dbe38
--- /dev/null
+++ b/quiche/quic/core/http/quic_headers_stream.h
@@ -0,0 +1,99 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+namespace test {
+class QuicHeadersStreamPeer;
+}  // namespace test
+
+// Headers in QUIC are sent as HTTP/2 HEADERS or PUSH_PROMISE frames over a
+// reserved stream with the id 3.  Each endpoint (client and server) will
+// allocate an instance of QuicHeadersStream to send and receive headers.
+class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
+ public:
+  explicit QuicHeadersStream(QuicSpdySession* session);
+  QuicHeadersStream(const QuicHeadersStream&) = delete;
+  QuicHeadersStream& operator=(const QuicHeadersStream&) = delete;
+  ~QuicHeadersStream() override;
+
+  // QuicStream implementation
+  void OnDataAvailable() override;
+
+  // Release underlying buffer if allowed.
+  void MaybeReleaseSequencerBuffer();
+
+  bool OnStreamFrameAcked(QuicStreamOffset offset,
+                          QuicByteCount data_length,
+                          bool fin_acked,
+                          QuicTime::Delta ack_delay_time,
+                          QuicTime receive_timestamp,
+                          QuicByteCount* newly_acked_length) override;
+
+  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_retransmitted) override;
+
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+ private:
+  friend class test::QuicHeadersStreamPeer;
+
+  // CompressedHeaderInfo includes simple information of a header, including
+  // offset in headers stream, unacked length and ack listener of this header.
+  struct QUIC_EXPORT_PRIVATE CompressedHeaderInfo {
+    CompressedHeaderInfo(
+        QuicStreamOffset headers_stream_offset, QuicStreamOffset full_length,
+        quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+            ack_listener);
+    CompressedHeaderInfo(const CompressedHeaderInfo& other);
+    ~CompressedHeaderInfo();
+
+    // Offset the header was sent on the headers stream.
+    QuicStreamOffset headers_stream_offset;
+    // The full length of the header.
+    QuicByteCount full_length;
+    // The remaining bytes to be acked.
+    QuicByteCount unacked_length;
+    // Ack listener of this header, and it is notified once any of the bytes has
+    // been acked or retransmitted.
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener;
+  };
+
+  // Returns true if the session is still connected.
+  bool IsConnected();
+
+  // Override to store mapping from offset, length to ack_listener. This
+  // ack_listener is notified once data within [offset, offset + length] is
+  // acked or retransmitted.
+  void OnDataBuffered(
+      QuicStreamOffset offset, QuicByteCount data_length,
+      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
+          ack_listener) override;
+
+  QuicSpdySession* spdy_session_;
+
+  // Headers that have not been fully acked.
+  quiche::QuicheCircularDeque<CompressedHeaderInfo> unacked_headers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_HEADERS_STREAM_H_
diff --git a/quiche/quic/core/http/quic_headers_stream_test.cc b/quiche/quic/core/http/quic_headers_stream_test.cc
new file mode 100644
index 0000000..30d9147
--- /dev/null
+++ b/quiche/quic/core/http/quic_headers_stream_test.cc
@@ -0,0 +1,972 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_headers_stream.h"
+
+#include <cstdint>
+#include <ostream>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/recording_headers_handler.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+using spdy::ERROR_CODE_PROTOCOL_ERROR;
+using spdy::RecordingHeadersHandler;
+using spdy::SETTINGS_ENABLE_PUSH;
+using spdy::SETTINGS_HEADER_TABLE_SIZE;
+using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
+using spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
+using spdy::SETTINGS_MAX_FRAME_SIZE;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyAltSvcWireFormat;
+using spdy::SpdyDataIR;
+using spdy::SpdyErrorCode;
+using spdy::SpdyFramer;
+using spdy::SpdyFramerVisitorInterface;
+using spdy::SpdyGoAwayIR;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersHandlerInterface;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyPingId;
+using spdy::SpdyPingIR;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdyRstStreamIR;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsId;
+using spdy::SpdySettingsIR;
+using spdy::SpdyStreamId;
+using spdy::SpdyWindowUpdateIR;
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockVisitor : public SpdyFramerVisitorInterface {
+ public:
+  MOCK_METHOD(void,
+              OnError,
+              (http2::Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error),
+              (override));
+  MOCK_METHOD(void,
+              OnDataFrameHeader,
+              (SpdyStreamId stream_id, size_t length, bool fin),
+              (override));
+  MOCK_METHOD(void,
+              OnStreamFrameData,
+              (SpdyStreamId stream_id, const char*, size_t len),
+              (override));
+  MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnStreamPadding,
+              (SpdyStreamId stream_id, size_t len),
+              (override));
+  MOCK_METHOD(SpdyHeadersHandlerInterface*,
+              OnHeaderFrameStart,
+              (SpdyStreamId stream_id),
+              (override));
+  MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnRstStream,
+              (SpdyStreamId stream_id, SpdyErrorCode error_code),
+              (override));
+  MOCK_METHOD(void, OnSettings, (), (override));
+  MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
+  MOCK_METHOD(void, OnSettingsAck, (), (override));
+  MOCK_METHOD(void, OnSettingsEnd, (), (override));
+  MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
+  MOCK_METHOD(void,
+              OnGoAway,
+              (SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
+              (override));
+  MOCK_METHOD(void,
+              OnHeaders,
+              (SpdyStreamId stream_id,
+               bool has_priority,
+               int weight,
+               SpdyStreamId parent_stream_id,
+               bool exclusive,
+               bool fin,
+               bool end),
+              (override));
+  MOCK_METHOD(void,
+              OnWindowUpdate,
+              (SpdyStreamId stream_id, int delta_window_size),
+              (override));
+  MOCK_METHOD(void,
+              OnPushPromise,
+              (SpdyStreamId stream_id,
+               SpdyStreamId promised_stream_id,
+               bool end),
+              (override));
+  MOCK_METHOD(void,
+              OnContinuation,
+              (SpdyStreamId stream_id, bool end),
+              (override));
+  MOCK_METHOD(
+      void,
+      OnAltSvc,
+      (SpdyStreamId stream_id,
+       absl::string_view origin,
+       const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
+      (override));
+  MOCK_METHOD(void,
+              OnPriority,
+              (SpdyStreamId stream_id,
+               SpdyStreamId parent_stream_id,
+               int weight,
+               bool exclusive),
+              (override));
+  MOCK_METHOD(void,
+              OnPriorityUpdate,
+              (SpdyStreamId prioritized_stream_id,
+               absl::string_view priority_field_value),
+              (override));
+  MOCK_METHOD(bool,
+              OnUnknownFrame,
+              (SpdyStreamId stream_id, uint8_t frame_type),
+              (override));
+};
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams:  " << *this;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
+    os << "{ version: " << ParsedQuicVersionToString(tp.version)
+       << ", perspective: "
+       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
+       << "}";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    if (VersionUsesHttp3(all_supported_versions[i].transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(all_supported_versions[i], p);
+    }
+  }
+  return params;
+}
+
+class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicHeadersStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(&helper_,
+                                                       &alarm_factory_,
+                                                       perspective(),
+                                                       GetVersion())),
+        session_(connection_),
+        body_("hello world"),
+        stream_frame_(
+            QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+            /*fin=*/false,
+            /*offset=*/0,
+            ""),
+        next_promised_stream_id_(2) {
+    QuicSpdySessionPeer::SetMaxInboundHeaderListSize(&session_, 256 * 1024);
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        quic::ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<quic::NullEncrypter>(connection_->perspective()));
+    headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
+    headers_[":status"] = "200 Ok";
+    headers_["content-length"] = "11";
+    framer_ = std::unique_ptr<SpdyFramer>(
+        new SpdyFramer(SpdyFramer::ENABLE_COMPRESSION));
+    deframer_ = std::unique_ptr<http2::Http2DecoderAdapter>(
+        new http2::Http2DecoderAdapter());
+    deframer_->set_visitor(&visitor_);
+    EXPECT_EQ(transport_version(), session_.transport_version());
+    EXPECT_TRUE(headers_stream_ != nullptr);
+    connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    client_id_1_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 0);
+    client_id_2_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 1);
+    client_id_3_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 2);
+    next_stream_id_ =
+        QuicUtils::StreamIdDelta(connection_->transport_version());
+  }
+
+  QuicStreamId GetNthClientInitiatedId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  QuicConsumedData SaveIov(size_t write_length) {
+    char* buf = new char[write_length];
+    QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER);
+    headers_stream_->WriteStreamData(headers_stream_->stream_bytes_written(),
+                                     write_length, &writer);
+    saved_data_.append(buf, write_length);
+    delete[] buf;
+    return QuicConsumedData(write_length, false);
+  }
+
+  void SavePayload(const char* data, size_t len) {
+    saved_payloads_.append(data, len);
+  }
+
+  bool SaveHeaderData(const char* data, int len) {
+    saved_header_data_.append(data, len);
+    return true;
+  }
+
+  void SaveHeaderDataStringPiece(absl::string_view data) {
+    saved_header_data_.append(data.data(), data.length());
+  }
+
+  void SavePromiseHeaderList(QuicStreamId /* stream_id */,
+                             QuicStreamId /* promised_stream_id */,
+                             size_t size,
+                             const QuicHeaderList& header_list) {
+    SaveToHandler(size, header_list);
+  }
+
+  void SaveHeaderList(QuicStreamId /* stream_id */,
+                      bool /* fin */,
+                      size_t size,
+                      const QuicHeaderList& header_list) {
+    SaveToHandler(size, header_list);
+  }
+
+  void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
+    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+    headers_handler_->OnHeaderBlockStart();
+    for (const auto& p : header_list) {
+      headers_handler_->OnHeader(p.first, p.second);
+    }
+    headers_handler_->OnHeaderBlockEnd(size, size);
+  }
+
+  void WriteAndExpectRequestHeaders(QuicStreamId stream_id,
+                                    bool fin,
+                                    SpdyPriority priority) {
+    WriteHeadersAndCheckData(stream_id, fin, priority, true /*is_request*/);
+  }
+
+  void WriteAndExpectResponseHeaders(QuicStreamId stream_id, bool fin) {
+    WriteHeadersAndCheckData(stream_id, fin, 0, false /*is_request*/);
+  }
+
+  void WriteHeadersAndCheckData(QuicStreamId stream_id,
+                                bool fin,
+                                SpdyPriority priority,
+                                bool is_request) {
+    // Write the headers and capture the outgoing data
+    EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                         connection_->transport_version()),
+                                     _, _, NO_FIN, _, _))
+        .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+    QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
+        &session_, stream_id, headers_.Clone(), fin,
+        spdy::SpdyStreamPrecedence(priority), nullptr);
+
+    // Parse the outgoing data and check that it matches was was written.
+    if (is_request) {
+      EXPECT_CALL(visitor_,
+                  OnHeaders(stream_id, kHasPriority,
+                            Spdy3PriorityToHttp2Weight(priority),
+                            /*parent_stream_id=*/0,
+                            /*exclusive=*/false, fin, kFrameComplete));
+    } else {
+      EXPECT_CALL(visitor_,
+                  OnHeaders(stream_id, !kHasPriority,
+                            /*weight=*/0,
+                            /*parent_stream_id=*/0,
+                            /*exclusive=*/false, fin, kFrameComplete));
+    }
+    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+    EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
+        .WillOnce(Return(headers_handler_.get()));
+    EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
+    if (fin) {
+      EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
+    }
+    deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
+    EXPECT_FALSE(deframer_->HasError())
+        << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+
+    CheckHeaders();
+    saved_data_.clear();
+  }
+
+  void CheckHeaders() {
+    ASSERT_TRUE(headers_handler_);
+    EXPECT_EQ(headers_, headers_handler_->decoded_block());
+    headers_handler_.reset();
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  QuicTransportVersion transport_version() const {
+    return GetParam().version.transport_version;
+  }
+
+  ParsedQuicVersionVector GetVersion() {
+    ParsedQuicVersionVector versions;
+    versions.push_back(GetParam().version);
+    return versions;
+  }
+
+  void TearDownLocalConnectionState() {
+    QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  }
+
+  QuicStreamId NextPromisedStreamId() {
+    return next_promised_stream_id_ += next_stream_id_;
+  }
+
+  static constexpr bool kFrameComplete = true;
+  static constexpr bool kHasPriority = true;
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicHeadersStream* headers_stream_;
+  SpdyHeaderBlock headers_;
+  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
+  std::string body_;
+  std::string saved_data_;
+  std::string saved_header_data_;
+  std::string saved_payloads_;
+  std::unique_ptr<SpdyFramer> framer_;
+  std::unique_ptr<http2::Http2DecoderAdapter> deframer_;
+  StrictMock<MockVisitor> visitor_;
+  QuicStreamFrame stream_frame_;
+  QuicStreamId next_promised_stream_id_;
+  QuicStreamId client_id_1_;
+  QuicStreamId client_id_2_;
+  QuicStreamId client_id_3_;
+  QuicStreamId next_stream_id_;
+};
+
+// Run all tests with each version and perspective (client or server).
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicHeadersStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicHeadersStreamTest, StreamId) {
+  EXPECT_EQ(QuicUtils::GetHeadersStreamId(connection_->transport_version()),
+            headers_stream_->id());
+}
+
+TEST_P(QuicHeadersStreamTest, WriteHeaders) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      if (perspective() == Perspective::IS_SERVER) {
+        WriteAndExpectResponseHeaders(stream_id, fin);
+      } else {
+        for (SpdyPriority priority = 0; priority < 7; ++priority) {
+          // TODO(rch): implement priorities correctly.
+          WriteAndExpectRequestHeaders(stream_id, fin, 0);
+        }
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, WritePushPromises) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    QuicStreamId promised_stream_id = NextPromisedStreamId();
+    if (perspective() == Perspective::IS_SERVER) {
+      // Write the headers and capture the outgoing data
+      EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                           connection_->transport_version()),
+                                       _, _, NO_FIN, _, _))
+          .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
+      session_.WritePushPromise(stream_id, promised_stream_id,
+                                headers_.Clone());
+
+      // Parse the outgoing data and check that it matches was was written.
+      EXPECT_CALL(visitor_,
+                  OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+      EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
+          .WillOnce(Return(headers_handler_.get()));
+      EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
+      deframer_->ProcessInput(saved_data_.data(), saved_data_.length());
+      EXPECT_FALSE(deframer_->HasError())
+          << http2::Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+      CheckHeaders();
+      saved_data_.clear();
+    } else {
+      EXPECT_QUIC_BUG(session_.WritePushPromise(stream_id, promised_stream_id,
+                                                headers_.Clone()),
+                      "Client shouldn't send PUSH_PROMISE");
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessRawData) {
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(
+                                    stream_id, spdy::SpdyStreamPrecedence(0)));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
+  if (perspective() == Perspective::IS_SERVER) {
+    return;
+  }
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    QuicStreamId promised_stream_id = NextPromisedStreamId();
+    SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
+                                   headers_.Clone());
+    SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
+    bool connection_closed = false;
+    if (perspective() == Perspective::IS_SERVER) {
+      EXPECT_CALL(*connection_,
+                  CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                  "PUSH_PROMISE not supported.", _))
+          .WillRepeatedly(InvokeWithoutArgs(
+              this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+    } else {
+      ON_CALL(*connection_, CloseConnection(_, _, _))
+          .WillByDefault(testing::Assign(&connection_closed, true));
+      EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id,
+                                                frame.size(), _))
+          .WillOnce(
+              Invoke(this, &QuicHeadersStreamTest::SavePromiseHeaderList));
+    }
+    stream_frame_.data_buffer = frame.data();
+    stream_frame_.data_length = frame.size();
+    headers_stream_->OnStreamFrame(stream_frame_);
+    if (perspective() == Perspective::IS_CLIENT) {
+      stream_frame_.offset += frame.size();
+      // CheckHeaders crashes if the connection is closed so this ensures we
+      // fail the test instead of crashing.
+      ASSERT_FALSE(connection_closed);
+      CheckHeaders();
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPriorityFrame) {
+  QuicStreamId parent_stream_id = 0;
+  for (SpdyPriority priority = 0; priority < 7; ++priority) {
+    for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+         stream_id += next_stream_id_) {
+      int weight = Spdy3PriorityToHttp2Weight(priority);
+      SpdyPriorityIR priority_frame(stream_id, parent_stream_id, weight, true);
+      SpdySerializedFrame frame(framer_->SerializeFrame(priority_frame));
+      parent_stream_id = stream_id;
+      if (perspective() == Perspective::IS_CLIENT) {
+        EXPECT_CALL(*connection_,
+                    CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                    "Server must not send PRIORITY frames.", _))
+            .WillRepeatedly(InvokeWithoutArgs(
+                this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+      } else {
+        EXPECT_CALL(
+            session_,
+            OnPriorityFrame(stream_id, spdy::SpdyStreamPrecedence(priority)))
+            .Times(1);
+      }
+      stream_frame_.data_buffer = frame.data();
+      stream_frame_.data_length = frame.size();
+      headers_stream_->OnStreamFrame(stream_frame_);
+      stream_frame_.offset += frame.size();
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
+  if (perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+
+  session_.OnConfigNegotiated();
+  SpdySettingsIR data;
+  // Respect supported settings frames SETTINGS_ENABLE_PUSH.
+  data.AddSetting(SETTINGS_ENABLE_PUSH, 0);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                      "Unsupported field of HTTP/2 SETTINGS frame: 2", _));
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
+  // We want to create a frame that is more than the SPDY Framer's max control
+  // frame size, which is 16K, but less than the HPACK decoders max decode
+  // buffer size, which is 32K.
+  headers_["key0"] = std::string(1 << 13, '.');
+  headers_["key1"] = std::string(1 << 13, '.');
+  headers_["key2"] = std::string(1 << 13, '.');
+  for (QuicStreamId stream_id = client_id_1_; stream_id < client_id_3_;
+       stream_id += next_stream_id_) {
+    for (bool fin : {false, true}) {
+      for (SpdyPriority priority = 0; priority < 7; ++priority) {
+        // Replace with "WriteHeadersAndSaveData"
+        SpdySerializedFrame frame;
+        if (perspective() == Perspective::IS_SERVER) {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          headers_frame.set_has_priority(true);
+          headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
+          frame = framer_->SerializeFrame(headers_frame);
+          EXPECT_CALL(session_, OnStreamHeadersPriority(
+                                    stream_id, spdy::SpdyStreamPrecedence(0)));
+        } else {
+          SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
+          headers_frame.set_fin(fin);
+          frame = framer_->SerializeFrame(headers_frame);
+        }
+        EXPECT_CALL(session_,
+                    OnStreamHeaderList(stream_id, fin, frame.size(), _))
+            .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
+        stream_frame_.data_buffer = frame.data();
+        stream_frame_.data_length = frame.size();
+        headers_stream_->OnStreamFrame(stream_frame_);
+        stream_frame_.offset += frame.size();
+        CheckHeaders();
+      }
+    }
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessBadData) {
+  const char kBadData[] = "blah blah blah";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(::testing::AnyNumber());
+  stream_frame_.data_buffer = kBadData;
+  stream_frame_.data_length = strlen(kBadData);
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
+  SpdyDataIR data(/* stream_id = */ 2, "ping");
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY DATA frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
+  SpdyRstStreamIR data(/* stream_id = */ 2, ERROR_CODE_PROTOCOL_ERROR);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                              "SPDY RST_STREAM frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
+  const uint32_t kTestHeaderTableSize = 1000;
+  SpdySettingsIR data;
+  // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
+  // SETTINGS_MAX_HEADER_LIST_SIZE.
+  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kTestHeaderTableSize);
+  data.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE, 2000);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+  EXPECT_EQ(kTestHeaderTableSize, QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                                      ->header_encoder_table_size());
+}
+
+// Regression bug for b/208997000.
+TEST_P(QuicHeadersStreamTest, LimitEncoderDynamicTableSize) {
+  const uint32_t kVeryLargeTableSizeLimit = 1024 * 1024 * 1024;
+  SpdySettingsIR data;
+  data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, kVeryLargeTableSizeLimit);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+    EXPECT_EQ(16384u, QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                          ->header_encoder_table_size());
+  } else {
+    EXPECT_EQ(kVeryLargeTableSizeLimit,
+              QuicSpdySessionPeer::GetSpdyFramer(&session_)
+                  ->header_encoder_table_size());
+  }
+}
+
+TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
+  SpdySettingsIR data;
+  // Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
+  // SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
+  // SETTINGS_MAX_FRAME_SIZE.
+  data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 100);
+  data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 100);
+  data.AddSetting(SETTINGS_ENABLE_PUSH, 1);
+  data.AddSetting(SETTINGS_MAX_FRAME_SIZE, 1250);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_HEADERS_STREAM_DATA,
+                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_MAX_CONCURRENT_STREAMS),
+                  _));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_HEADERS_STREAM_DATA,
+                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_INITIAL_WINDOW_SIZE),
+                  _));
+  if (session_.perspective() == Perspective::IS_CLIENT) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_INVALID_HEADERS_STREAM_DATA,
+                    absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                                 SETTINGS_ENABLE_PUSH),
+                    _));
+  }
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_HEADERS_STREAM_DATA,
+                  absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ",
+                               SETTINGS_MAX_FRAME_SIZE),
+                  _));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
+  SpdyPingIR data(1);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY PING frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
+  SpdyGoAwayIR data(/* last_good_stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR,
+                    "go away");
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "SPDY GOAWAY frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
+  SpdyWindowUpdateIR data(/* stream_id = */ 1, /* delta = */ 1);
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                              "SPDY WINDOW_UPDATE frame received.", _))
+      .WillOnce(InvokeWithoutArgs(
+          this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
+  EXPECT_FALSE(QuicStreamPeer::StreamContributesToConnectionFlowControl(
+      headers_stream_));
+}
+
+TEST_P(QuicHeadersStreamTest, AckSentData) {
+  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN, _, _))
+      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  // Packet 1.
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+
+  // Packet 2.
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+
+  // Packet 3.
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Packet 2 gets retransmitted.
+  EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
+  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
+  headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
+  headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
+
+  // Packets are acked in order: 2, 3, 1.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      21, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      28, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      35, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      7, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+  // Unsent data is acked.
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      14, 10, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(7u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
+  // In this test, a stream frame can contain multiple headers.
+  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN, _, _))
+      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Frame 1 is retransmitted.
+  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
+  EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
+  headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
+
+  // Frames are acked in order: 2, 3, 1.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(2, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      17, 13, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(13u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      30, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(12u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(14, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(3, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 17, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(17u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
+  EXPECT_CALL(session_, WritevData(QuicUtils::GetHeadersStreamId(
+                                       connection_->transport_version()),
+                                   _, _, NO_FIN, _, _))
+      .WillRepeatedly(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener3(
+      new MockAckListener());
+
+  // Send [0, 42).
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header5", false, ack_listener1);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+  headers_stream_->WriteOrBufferData("Header7", false, ack_listener2);
+  headers_stream_->WriteOrBufferData("Header9", false, ack_listener3);
+
+  // Ack [15, 20), [5, 25), [10, 17), [0, 12) and [22, 42).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      15, 5, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(5u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(9, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(1, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(4, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      5, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(15u, newly_acked_length);
+
+  // Duplicate ack.
+  EXPECT_FALSE(headers_stream_->OnStreamFrameAcked(
+      10, 7, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      0, 12, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(5u, newly_acked_length);
+
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(3, _));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
+  EXPECT_TRUE(headers_stream_->OnStreamFrameAcked(
+      22, 20, false, QuicTime::Delta::Zero(), QuicTime::Zero(),
+      &newly_acked_length));
+  EXPECT_EQ(17u, newly_acked_length);
+}
+
+TEST_P(QuicHeadersStreamTest, CloseOnPushPromiseToServer) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    return;
+  }
+  QuicStreamId promised_id = 1;
+  SpdyPushPromiseIR push_promise(client_id_1_, promised_id, headers_.Clone());
+  SpdySerializedFrame frame = framer_->SerializeFrame(push_promise);
+  stream_frame_.data_buffer = frame.data();
+  stream_frame_.data_length = frame.size();
+  EXPECT_CALL(session_, OnStreamHeaderList(_, _, _, _));
+  // TODO(lassey): Check for HTTP_WRONG_STREAM error code.
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "PUSH_PROMISE not supported.", _));
+  headers_stream_->OnStreamFrame(stream_frame_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_receive_control_stream.cc b/quiche/quic/core/http/quic_receive_control_stream.cc
new file mode 100644
index 0000000..5c624b2
--- /dev/null
+++ b/quiche/quic/core/http/quic_receive_control_stream.cc
@@ -0,0 +1,274 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_receive_control_stream.h"
+
+#include <utility>
+
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+QuicReceiveControlStream::QuicReceiveControlStream(
+    PendingStream* pending,
+    QuicSpdySession* spdy_session)
+    : QuicStream(pending,
+                 spdy_session,
+                 /*is_static=*/true),
+      settings_frame_received_(false),
+      decoder_(this),
+      spdy_session_(spdy_session) {
+  sequencer()->set_level_triggered(true);
+}
+
+QuicReceiveControlStream::~QuicReceiveControlStream() {}
+
+void QuicReceiveControlStream::OnStreamReset(
+    const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "RESET_STREAM received for receive control stream");
+}
+
+void QuicReceiveControlStream::OnDataAvailable() {
+  iovec iov;
+  while (!reading_stopped() && decoder_.error() == QUIC_NO_ERROR &&
+         sequencer()->GetReadableRegion(&iov)) {
+    QUICHE_DCHECK(!sequencer()->IsClosed());
+
+    QuicByteCount processed_bytes = decoder_.ProcessInput(
+        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
+    sequencer()->MarkConsumed(processed_bytes);
+
+    if (!session()->connection()->connected()) {
+      return;
+    }
+
+    // The only reason QuicReceiveControlStream pauses HttpDecoder is an error,
+    // in which case the connection would have already been closed.
+    QUICHE_DCHECK_EQ(iov.iov_len, processed_bytes);
+  }
+}
+
+void QuicReceiveControlStream::OnError(HttpDecoder* decoder) {
+  stream_delegate()->OnStreamError(decoder->error(), decoder->error_detail());
+}
+
+bool QuicReceiveControlStream::OnMaxPushIdFrame(const MaxPushIdFrame& frame) {
+  if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_ignore_max_push_id);
+    return ValidateFrameType(HttpFrameType::MAX_PUSH_ID);
+  }
+
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnMaxPushIdFrameReceived(frame);
+  }
+
+  if (!ValidateFrameType(HttpFrameType::MAX_PUSH_ID)) {
+    return false;
+  }
+
+  return spdy_session()->OnMaxPushIdFrame(frame.push_id);
+}
+
+bool QuicReceiveControlStream::OnGoAwayFrame(const GoAwayFrame& frame) {
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnGoAwayFrameReceived(frame);
+  }
+
+  if (!ValidateFrameType(HttpFrameType::GOAWAY)) {
+    return false;
+  }
+
+  spdy_session()->OnHttp3GoAway(frame.id);
+  return true;
+}
+
+bool QuicReceiveControlStream::OnSettingsFrameStart(
+    QuicByteCount /*header_length*/) {
+  return ValidateFrameType(HttpFrameType::SETTINGS);
+}
+
+bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& frame) {
+  QUIC_DVLOG(1) << "Control Stream " << id()
+                << " received settings frame: " << frame;
+  return spdy_session_->OnSettingsFrame(frame);
+}
+
+bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/,
+                                                QuicByteCount
+                                                /*payload_length*/) {
+  return ValidateFrameType(HttpFrameType::DATA);
+}
+
+bool QuicReceiveControlStream::OnDataFramePayload(
+    absl::string_view /*payload*/) {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnDataFrameEnd() {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFrameStart(
+    QuicByteCount /*header_length*/,
+    QuicByteCount
+    /*payload_length*/) {
+  return ValidateFrameType(HttpFrameType::HEADERS);
+}
+
+bool QuicReceiveControlStream::OnHeadersFramePayload(
+    absl::string_view /*payload*/) {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFrameEnd() {
+  QUICHE_NOTREACHED();
+  return false;
+}
+
+bool QuicReceiveControlStream::OnPriorityUpdateFrameStart(
+    QuicByteCount /*header_length*/) {
+  return ValidateFrameType(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM);
+}
+
+bool QuicReceiveControlStream::OnPriorityUpdateFrame(
+    const PriorityUpdateFrame& frame) {
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnPriorityUpdateFrameReceived(frame);
+  }
+
+  // TODO(b/147306124): Use a proper structured headers parser instead.
+  for (absl::string_view key_value :
+       absl::StrSplit(frame.priority_field_value, ',')) {
+    std::vector<absl::string_view> key_and_value =
+        absl::StrSplit(key_value, '=');
+    if (key_and_value.size() != 2) {
+      continue;
+    }
+
+    absl::string_view key = key_and_value[0];
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&key);
+    if (key != "u") {
+      continue;
+    }
+
+    absl::string_view value = key_and_value[1];
+    int urgency;
+    if (!absl::SimpleAtoi(value, &urgency) || urgency < 0 || urgency > 7) {
+      stream_delegate()->OnStreamError(
+          QUIC_INVALID_PRIORITY_UPDATE,
+          "Invalid value for PRIORITY_UPDATE urgency parameter.");
+      return false;
+    }
+
+    if (frame.prioritized_element_type == REQUEST_STREAM) {
+      return spdy_session_->OnPriorityUpdateForRequestStream(
+          frame.prioritized_element_id, urgency);
+    } else {
+      return spdy_session_->OnPriorityUpdateForPushStream(
+          frame.prioritized_element_id, urgency);
+    }
+  }
+
+  // Ignore frame if no urgency parameter can be parsed.
+  return true;
+}
+
+bool QuicReceiveControlStream::OnAcceptChFrameStart(
+    QuicByteCount /* header_length */) {
+  return ValidateFrameType(HttpFrameType::ACCEPT_CH);
+}
+
+bool QuicReceiveControlStream::OnAcceptChFrame(const AcceptChFrame& frame) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, spdy_session()->perspective());
+
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnAcceptChFrameReceived(frame);
+  }
+
+  spdy_session()->OnAcceptChFrame(frame);
+  return true;
+}
+
+void QuicReceiveControlStream::OnWebTransportStreamFrameType(
+    QuicByteCount /*header_length*/,
+    WebTransportSessionId /*session_id*/) {
+  QUIC_BUG(WEBTRANSPORT_STREAM on Control Stream)
+      << "Parsed WEBTRANSPORT_STREAM on a control stream.";
+}
+
+bool QuicReceiveControlStream::OnUnknownFrameStart(
+    uint64_t frame_type,
+    QuicByteCount /*header_length*/,
+    QuicByteCount payload_length) {
+  if (spdy_session()->debug_visitor()) {
+    spdy_session()->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
+                                                            payload_length);
+  }
+
+  return ValidateFrameType(static_cast<HttpFrameType>(frame_type));
+}
+
+bool QuicReceiveControlStream::OnUnknownFramePayload(
+    absl::string_view /*payload*/) {
+  // Ignore unknown frame types.
+  return true;
+}
+
+bool QuicReceiveControlStream::OnUnknownFrameEnd() {
+  // Ignore unknown frame types.
+  return true;
+}
+
+bool QuicReceiveControlStream::ValidateFrameType(HttpFrameType frame_type) {
+  // Certain frame types are forbidden.
+  if (frame_type == HttpFrameType::DATA ||
+      frame_type == HttpFrameType::HEADERS ||
+      (spdy_session()->perspective() == Perspective::IS_CLIENT &&
+       frame_type == HttpFrameType::MAX_PUSH_ID) ||
+      (spdy_session()->perspective() == Perspective::IS_SERVER &&
+       frame_type == HttpFrameType::ACCEPT_CH)) {
+    stream_delegate()->OnStreamError(
+        QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+        absl::StrCat("Invalid frame type ", static_cast<int>(frame_type),
+                     " received on control stream."));
+    return false;
+  }
+
+  if (settings_frame_received_) {
+    if (frame_type == HttpFrameType::SETTINGS) {
+      // SETTINGS frame may only be the first frame on the control stream.
+      stream_delegate()->OnStreamError(
+          QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
+          "SETTINGS frame can only be received once.");
+      return false;
+    }
+    return true;
+  }
+
+  if (frame_type == HttpFrameType::SETTINGS) {
+    settings_frame_received_ = true;
+    return true;
+  }
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_MISSING_SETTINGS_FRAME,
+      absl::StrCat("First frame received on control stream is type ",
+                   static_cast<int>(frame_type), ", but it must be SETTINGS."));
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_receive_control_stream.h b/quiche/quic/core/http/quic_receive_control_stream.h
new file mode 100644
index 0000000..70fa63a
--- /dev/null
+++ b/quiche/quic/core/http/quic_receive_control_stream.h
@@ -0,0 +1,79 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
+
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+// 3.2.1 Control Stream.
+// The receive control stream is peer initiated and is read only.
+class QUIC_EXPORT_PRIVATE QuicReceiveControlStream
+    : public QuicStream,
+      public HttpDecoder::Visitor {
+ public:
+  explicit QuicReceiveControlStream(PendingStream* pending,
+                                    QuicSpdySession* spdy_session);
+  QuicReceiveControlStream(const QuicReceiveControlStream&) = delete;
+  QuicReceiveControlStream& operator=(const QuicReceiveControlStream&) = delete;
+  ~QuicReceiveControlStream() override;
+
+  // Overriding QuicStream::OnStreamReset to make sure control stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // Implementation of QuicStream.
+  void OnDataAvailable() override;
+
+  // HttpDecoder::Visitor implementation.
+  void OnError(HttpDecoder* decoder) override;
+  bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override;
+  bool OnGoAwayFrame(const GoAwayFrame& frame) override;
+  bool OnSettingsFrameStart(QuicByteCount header_length) override;
+  bool OnSettingsFrame(const SettingsFrame& frame) override;
+  bool OnDataFrameStart(QuicByteCount header_length,
+                        QuicByteCount payload_length) override;
+  bool OnDataFramePayload(absl::string_view payload) override;
+  bool OnDataFrameEnd() override;
+  bool OnHeadersFrameStart(QuicByteCount header_length,
+                           QuicByteCount payload_length) override;
+  bool OnHeadersFramePayload(absl::string_view payload) override;
+  bool OnHeadersFrameEnd() override;
+  bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override;
+  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override;
+  bool OnAcceptChFrameStart(QuicByteCount header_length) override;
+  bool OnAcceptChFrame(const AcceptChFrame& frame) override;
+  void OnWebTransportStreamFrameType(QuicByteCount header_length,
+                                     WebTransportSessionId session_id) override;
+  bool OnUnknownFrameStart(uint64_t frame_type,
+                           QuicByteCount header_length,
+                           QuicByteCount payload_length) override;
+  bool OnUnknownFramePayload(absl::string_view payload) override;
+  bool OnUnknownFrameEnd() override;
+
+  QuicSpdySession* spdy_session() { return spdy_session_; }
+
+ private:
+  // Called when a frame of allowed type is received.  Returns true if the frame
+  // is allowed in this position.  Returns false and resets the stream
+  // otherwise.
+  bool ValidateFrameType(HttpFrameType frame_type);
+
+  // False until a SETTINGS frame is received.
+  bool settings_frame_received_;
+
+  HttpDecoder decoder_;
+  QuicSpdySession* const spdy_session_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_RECEIVE_CONTROL_STREAM_H_
diff --git a/quiche/quic/core/http/quic_receive_control_stream_test.cc b/quiche/quic/core/http/quic_receive_control_stream_test.cc
new file mode 100644
index 0000000..4ef68c4
--- /dev/null
+++ b/quiche/quic/core/http/quic_receive_control_stream_test.cc
@@ -0,0 +1,483 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_receive_control_stream.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+class QpackEncoder;
+
+namespace test {
+
+namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: " << *this;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
+    os << "{ version: " << ParsedQuicVersionToString(tp.version)
+       << ", perspective: "
+       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
+       << "}";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session)
+      : QuicSpdyStream(id, session, BIDIRECTIONAL) {}
+  ~TestStream() override = default;
+
+  void OnBodyAvailable() override {}
+};
+
+class QuicReceiveControlStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicReceiveControlStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_,
+            &alarm_factory_,
+            perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    QuicStreamId id = perspective() == Perspective::IS_SERVER
+                          ? GetNthClientInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3)
+                          : GetNthServerInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3);
+    char type[] = {kControlStream};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+
+    receive_control_stream_ =
+        QuicSpdySessionPeer::GetReceiveControlStream(&session_);
+
+    stream_ = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
+                                 GetParam().version.transport_version, 0),
+                             &session_);
+    session_.ActivateStream(absl::WrapUnique(stream_));
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  std::string EncodeSettings(const SettingsFrame& settings) {
+    std::unique_ptr<char[]> buffer;
+    QuicByteCount settings_frame_length =
+        HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+    return std::string(buffer.get(), settings_frame_length);
+  }
+
+  std::string SerializePriorityUpdateFrame(
+      const PriorityUpdateFrame& priority_update) {
+    std::unique_ptr<char[]> priority_buffer;
+    QuicByteCount priority_frame_length =
+        HttpEncoder::SerializePriorityUpdateFrame(priority_update,
+                                                  &priority_buffer);
+    return std::string(priority_buffer.get(), priority_frame_length);
+  }
+
+  QuicStreamOffset NumBytesConsumed() {
+    return QuicStreamPeer::sequencer(receive_control_stream_)
+        ->NumBytesConsumed();
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicReceiveControlStream* receive_control_stream_;
+  TestStream* stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicReceiveControlStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicReceiveControlStreamTest, ResetControlStream) {
+  EXPECT_TRUE(receive_control_stream_->is_static());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
+                               receive_control_stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  receive_control_stream_->OnStreamReset(rst_frame);
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveSettings) {
+  SettingsFrame settings;
+  settings.values[10] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 12;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 37;
+  std::string data = EncodeSettings(settings);
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data);
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(qpack_encoder);
+  EXPECT_EQ(std::numeric_limits<size_t>::max(),
+            session_.max_outbound_header_list_size());
+  EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+  EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
+
+  receive_control_stream_->OnStreamFrame(frame);
+
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+  EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+  EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
+}
+
+// Regression test for https://crbug.com/982648.
+// QuicReceiveControlStream::OnDataAvailable() must stop processing input as
+// soon as OnSettingsFrameStart() is called by HttpDecoder for the second frame.
+TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsTwice) {
+  SettingsFrame settings;
+  // Reserved identifiers, must be ignored.
+  settings.values[0x21] = 100;
+  settings.values[0x40] = 200;
+
+  std::string settings_frame = EncodeSettings(settings);
+
+  QuicStreamOffset offset = 1;
+  EXPECT_EQ(offset, NumBytesConsumed());
+
+  // Receive first SETTINGS frame.
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+  offset += settings_frame.length();
+
+  // First SETTINGS frame is consumed.
+  EXPECT_EQ(offset, NumBytesConsumed());
+
+  // Second SETTINGS frame causes the connection to be closed.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
+                      "SETTINGS frame can only be received once.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  // Receive second SETTINGS frame.
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+
+  // Frame header of second SETTINGS frame is consumed, but not frame payload.
+  QuicByteCount settings_frame_header_length = 2;
+  EXPECT_EQ(offset + settings_frame_header_length, NumBytesConsumed());
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveSettingsFragments) {
+  SettingsFrame settings;
+  settings.values[10] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  std::string data = EncodeSettings(settings);
+  std::string data1 = data.substr(0, 1);
+  std::string data2 = data.substr(1, data.length() - 1);
+
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data1);
+  QuicStreamFrame frame2(receive_control_stream_->id(), false, 2, data2);
+  EXPECT_NE(5u, session_.max_outbound_header_list_size());
+  receive_control_stream_->OnStreamFrame(frame);
+  receive_control_stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveWrongFrame) {
+  // DATA frame header without payload.
+  quiche::QuicheBuffer data = HttpEncoder::SerializeDataFrameHeader(
+      /* payload_length = */ 2, quiche::SimpleBufferAllocator::Get());
+
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
+                        data.AsStringView());
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM, _, _));
+  receive_control_stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicReceiveControlStreamTest,
+       ReceivePriorityUpdateFrameBeforeSettingsFrame) {
+  std::string serialized_frame = SerializePriorityUpdateFrame({});
+  QuicStreamFrame data(receive_control_stream_->id(), /* fin = */ false,
+                       /* offset = */ 1, serialized_frame);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
+                              "First frame received on control stream is type "
+                              "984832, but it must be SETTINGS.",
+                              _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(data);
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveGoAwayFrame) {
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+  offset += settings_frame.length();
+
+  GoAwayFrame goaway{/* id = */ 0};
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
+  std::string data = std::string(buffer.get(), header_length);
+
+  QuicStreamFrame frame(receive_control_stream_->id(), false, offset, data);
+  EXPECT_FALSE(session_.goaway_received());
+
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameReceived(goaway));
+
+  receive_control_stream_->OnStreamFrame(frame);
+  EXPECT_TRUE(session_.goaway_received());
+}
+
+TEST_P(QuicReceiveControlStreamTest, PushPromiseOnControlStreamShouldClose) {
+  std::string push_promise_frame = absl::HexStringToBytes(
+      "05"    // PUSH_PROMISE
+      "01"    // length
+      "00");  // push ID
+  QuicStreamFrame frame(receive_control_stream_->id(), false, 1,
+                        push_promise_frame);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+  receive_control_stream_->OnStreamFrame(frame);
+}
+
+// Regression test for b/137554973: unknown frames should be consumed.
+TEST_P(QuicReceiveControlStreamTest, ConsumeUnknownFrame) {
+  EXPECT_EQ(1u, NumBytesConsumed());
+
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  std::string settings_frame = EncodeSettings({});
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false, offset,
+                      settings_frame));
+  offset += settings_frame.length();
+
+  // SETTINGS frame is consumed.
+  EXPECT_EQ(offset, NumBytesConsumed());
+
+  // Receive unknown frame.
+  std::string unknown_frame = absl::HexStringToBytes(
+      "21"        // reserved frame type
+      "03"        // payload length
+      "666f6f");  // payload "foo"
+
+  receive_control_stream_->OnStreamFrame(QuicStreamFrame(
+      receive_control_stream_->id(), /* fin = */ false, offset, unknown_frame));
+  offset += unknown_frame.size();
+
+  // Unknown frame is consumed.
+  EXPECT_EQ(offset, NumBytesConsumed());
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveUnknownFrame) {
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId id = receive_control_stream_->id();
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
+  offset += settings_frame.length();
+
+  // Receive unknown frame.
+  std::string unknown_frame = absl::HexStringToBytes(
+      "21"        // reserved frame type
+      "03"        // payload length
+      "666f6f");  // payload "foo"
+
+  EXPECT_CALL(debug_visitor, OnUnknownFrameReceived(id, /* frame_type = */ 0x21,
+                                                    /* payload_length = */ 3));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, unknown_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) {
+  std::string cancel_push_frame = absl::HexStringToBytes(
+      "03"    // type CANCEL_PUSH
+      "01"    // payload length
+      "01");  // push ID
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
+                                            "CANCEL_PUSH frame received.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
+                      /* offset = */ 1, cancel_push_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, AcceptChFrameBeforeSettings) {
+  std::string accept_ch_frame = absl::HexStringToBytes(
+      "4089"  // type (ACCEPT_CH)
+      "00");  // length
+
+  if (perspective() == Perspective::IS_SERVER) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+                    "Invalid frame type 137 received on control stream.", _))
+        .WillOnce(
+            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
+                                "First frame received on control stream is "
+                                "type 137, but it must be SETTINGS.",
+                                _))
+        .WillOnce(
+            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  }
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
+                      /* offset = */ 1, accept_ch_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, ReceiveAcceptChFrame) {
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId id = receive_control_stream_->id();
+  QuicStreamOffset offset = 1;
+
+  // Receive SETTINGS frame.
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, settings_frame));
+  offset += settings_frame.length();
+
+  // Receive ACCEPT_CH frame.
+  std::string accept_ch_frame = absl::HexStringToBytes(
+      "4089"  // type (ACCEPT_CH)
+      "00");  // length
+
+  if (perspective() == Perspective::IS_CLIENT) {
+    EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(_));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+                    "Invalid frame type 137 received on control stream.", _))
+        .WillOnce(
+            Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+    EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+    EXPECT_CALL(session_, OnConnectionClosed(_, _));
+  }
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(id, /* fin = */ false, offset, accept_ch_frame));
+}
+
+TEST_P(QuicReceiveControlStreamTest, UnknownFrameBeforeSettings) {
+  std::string unknown_frame = absl::HexStringToBytes(
+      "21"        // reserved frame type
+      "03"        // payload length
+      "666f6f");  // payload "foo"
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_MISSING_SETTINGS_FRAME,
+                              "First frame received on control stream is type "
+                              "33, but it must be SETTINGS.",
+                              _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(session_, OnConnectionClosed(_, _));
+
+  receive_control_stream_->OnStreamFrame(
+      QuicStreamFrame(receive_control_stream_->id(), /* fin = */ false,
+                      /* offset = */ 1, unknown_frame));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_send_control_stream.cc b/quiche/quic/core/http/quic_send_control_stream.cc
new file mode 100644
index 0000000..f021f3d
--- /dev/null
+++ b/quiche/quic/core/http/quic_send_control_stream.cc
@@ -0,0 +1,124 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_send_control_stream.h"
+#include <cstdint>
+#include <memory>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSendControlStream::QuicSendControlStream(QuicStreamId id,
+                                             QuicSpdySession* spdy_session,
+                                             const SettingsFrame& settings)
+    : QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
+      settings_sent_(false),
+      settings_(settings),
+      spdy_session_(spdy_session) {}
+
+void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  QUIC_BUG(quic_bug_10382_1)
+      << "OnStreamReset() called for write unidirectional stream.";
+}
+
+bool QuicSendControlStream::OnStopSending(QuicResetStreamError /* code */) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "STOP_SENDING received for send control stream");
+  return false;
+}
+
+void QuicSendControlStream::MaybeSendSettingsFrame() {
+  if (settings_sent_) {
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  // Send the stream type on so the peer knows about this stream.
+  char data[sizeof(kControlStream)];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
+  writer.WriteVarInt62(kControlStream);
+  WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
+                    nullptr);
+
+  SettingsFrame settings = settings_;
+  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1
+  // specifies that setting identifiers of 0x1f * N + 0x21 are reserved and
+  // greasing should be attempted.
+  if (!GetQuicFlag(FLAGS_quic_enable_http3_grease_randomness)) {
+    settings.values[0x40] = 20;
+  } else {
+    uint32_t result;
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+    uint64_t setting_id = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+    settings.values[setting_id] = result;
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+  QUIC_DVLOG(1) << "Control stream " << id() << " is writing settings frame "
+                << settings;
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnSettingsFrameSent(settings);
+  }
+  WriteOrBufferData(absl::string_view(buffer.get(), frame_length),
+                    /*fin = */ false, nullptr);
+  settings_sent_ = true;
+
+  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9
+  // specifies that a reserved frame type has no semantic meaning and should be
+  // discarded. A greasing frame is added here.
+  std::unique_ptr<char[]> grease;
+  QuicByteCount grease_length = HttpEncoder::SerializeGreasingFrame(&grease);
+  WriteOrBufferData(absl::string_view(grease.get(), grease_length),
+                    /*fin = */ false, nullptr);
+}
+
+void QuicSendControlStream::WritePriorityUpdate(
+    const PriorityUpdateFrame& priority_update) {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendSettingsFrame();
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnPriorityUpdateFrameSent(priority_update);
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializePriorityUpdateFrame(priority_update, &buffer);
+  QUIC_DVLOG(1) << "Control Stream " << id() << " is writing "
+                << priority_update;
+  WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
+                    nullptr);
+}
+
+void QuicSendControlStream::SendGoAway(QuicStreamId id) {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendSettingsFrame();
+
+  GoAwayFrame frame;
+  frame.id = id;
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnGoAwayFrameSent(id);
+  }
+
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializeGoAwayFrame(frame, &buffer);
+  WriteOrBufferData(absl::string_view(buffer.get(), frame_length), false,
+                    nullptr);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_send_control_stream.h b/quiche/quic/core/http/quic_send_control_stream.h
new file mode 100644
index 0000000..49076bb
--- /dev/null
+++ b/quiche/quic/core/http/quic_send_control_stream.h
@@ -0,0 +1,64 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
+
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+class QuicSpdySession;
+
+// 6.2.1 Control Stream.
+// The send control stream is self initiated and is write only.
+class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
+ public:
+  // |session| can't be nullptr, and the ownership is not passed. The stream can
+  // only be accessed through the session.
+  QuicSendControlStream(QuicStreamId id,
+                        QuicSpdySession* session,
+                        const SettingsFrame& settings);
+  QuicSendControlStream(const QuicSendControlStream&) = delete;
+  QuicSendControlStream& operator=(const QuicSendControlStream&) = delete;
+  ~QuicSendControlStream() override = default;
+
+  // Overriding QuicStream::OnStopSending() to make sure control stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  bool OnStopSending(QuicResetStreamError code) override;
+
+  // Send SETTINGS frame if it hasn't been sent yet. Settings frame must be the
+  // first frame sent on this stream.
+  void MaybeSendSettingsFrame();
+
+  // Send a PRIORITY_UPDATE frame on this stream, and a SETTINGS frame
+  // beforehand if one has not been already sent.
+  void WritePriorityUpdate(const PriorityUpdateFrame& priority_update);
+
+  // Send a GOAWAY frame on this stream, and a SETTINGS frame beforehand if one
+  // has not been already sent.
+  void SendGoAway(QuicStreamId id);
+
+  // The send control stream is write unidirectional, so this method should
+  // never be called.
+  void OnDataAvailable() override { QUIC_NOTREACHED(); }
+
+ private:
+  // Track if a settings frame is already sent.
+  bool settings_sent_;
+
+  // SETTINGS values to send.
+  const SettingsFrame settings_;
+
+  QuicSpdySession* const spdy_session_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SEND_CONTROL_STREAM_H_
diff --git a/quiche/quic/core/http/quic_send_control_stream_test.cc b/quiche/quic/core/http/quic_send_control_stream_test.cc
new file mode 100644
index 0000000..aa7606f
--- /dev/null
+++ b/quiche/quic/core/http/quic_send_control_stream_test.cc
@@ -0,0 +1,300 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_send_control_stream.h"
+
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: " << *this;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const TestParams& tp) {
+    os << "{ version: " << ParsedQuicVersionToString(tp.version)
+       << ", perspective: "
+       << (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")
+       << "}";
+    return os;
+  }
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class QuicSendControlStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QuicSendControlStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_, &alarm_factory_, perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    ON_CALL(session_, WritevData(_, _, _, _, _, _))
+        .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  }
+
+  void Initialize() {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    send_control_stream_ = QuicSpdySessionPeer::GetSendControlStream(&session_);
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
+    session_.OnConfigNegotiated();
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QuicSendControlStream* send_control_stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSendControlStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSendControlStreamTest, WriteSettings) {
+  SetQuicFlag(FLAGS_quic_enable_http3_grease_randomness, false);
+  session_.set_qpack_maximum_dynamic_table_capacity(255);
+  session_.set_qpack_maximum_blocked_streams(16);
+  session_.set_max_inbound_header_list_size(1024);
+
+  Initialize();
+  testing::InSequence s;
+
+  std::string expected_write_data = absl::HexStringToBytes(
+      "00"    // stream type: control stream
+      "04"    // frame type: SETTINGS frame
+      "0b"    // frame length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "40ff"  // 255
+      "06"    // SETTINGS_MAX_HEADER_LIST_SIZE
+      "4400"  // 1024
+      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+      "10"    // 16
+      "4040"  // 0x40 as the reserved settings id
+      "14"    // 20
+      "4040"  // 0x40 as the reserved frame type
+      "01"    // 1 byte frame length
+      "61");  //  payload "a"
+  if ((!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+       perspective() == Perspective::IS_CLIENT) &&
+      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
+          HttpDatagramSupport::kDraft00And04) {
+    expected_write_data = absl::HexStringToBytes(
+        "00"         // stream type: control stream
+        "04"         // frame type: SETTINGS frame
+        "0e"         // frame length
+        "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+        "40ff"       // 255
+        "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
+        "4400"       // 1024
+        "07"         // SETTINGS_QPACK_BLOCKED_STREAMS
+        "10"         // 16
+        "4040"       // 0x40 as the reserved settings id
+        "14"         // 20
+        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
+        "01"         // 1
+        "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
+        "01"         // 1
+        "4040"       // 0x40 as the reserved frame type
+        "01"         // 1 byte frame length
+        "61");       //  payload "a"
+  }
+  if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+      perspective() == Perspective::IS_SERVER &&
+      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
+          HttpDatagramSupport::kNone) {
+    expected_write_data = absl::HexStringToBytes(
+        "00"    // stream type: control stream
+        "04"    // frame type: SETTINGS frame
+        "0d"    // frame length
+        "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+        "40ff"  // 255
+        "06"    // SETTINGS_MAX_HEADER_LIST_SIZE
+        "4400"  // 1024
+        "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+        "10"    // 16
+        "08"    // SETTINGS_ENABLE_CONNECT_PROTOCOL
+        "01"    // 1
+        "4040"  // 0x40 as the reserved settings id
+        "14"    // 20
+        "4040"  // 0x40 as the reserved frame type
+        "01"    // 1 byte frame length
+        "61");  //  payload "a"
+  }
+  if (GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+      perspective() == Perspective::IS_SERVER &&
+      QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) !=
+          HttpDatagramSupport::kNone) {
+    expected_write_data = absl::HexStringToBytes(
+        "00"         // stream type: control stream
+        "04"         // frame type: SETTINGS frame
+        "11"         // frame length
+        "01"         // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+        "40ff"       // 255
+        "06"         // SETTINGS_MAX_HEADER_LIST_SIZE
+        "4400"       // 1024
+        "07"         // SETTINGS_QPACK_BLOCKED_STREAMS
+        "10"         // 16
+        "08"         // SETTINGS_ENABLE_CONNECT_PROTOCOL
+        "01"         // 1
+        "4040"       // 0x40 as the reserved settings id
+        "14"         // 20
+        "4276"       // SETTINGS_H3_DATAGRAM_DRAFT00
+        "01"         // 1
+        "800ffd277"  // SETTINGS_H3_DATAGRAM_DRAFT04
+        "01"         // 1
+        "4040"       // 0x40 as the reserved frame type
+        "01"         // 1 byte frame length
+        "61");       //  payload "a"
+  }
+
+  auto buffer = std::make_unique<char[]>(expected_write_data.size());
+  QuicDataWriter writer(expected_write_data.size(), buffer.get());
+
+  // A lambda to save and consume stream data when QuicSession::WritevData() is
+  // called.
+  auto save_write_data =
+      [&writer, this](QuicStreamId /*id*/, size_t write_length,
+                      QuicStreamOffset offset, StreamSendingState /*state*/,
+                      TransmissionType /*type*/,
+                      absl::optional<EncryptionLevel> /*level*/) {
+        send_control_stream_->WriteStreamData(offset, write_length, &writer);
+        return QuicConsumedData(/* bytes_consumed = */ write_length,
+                                /* fin_consumed = */ false);
+      };
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _))
+      .WillOnce(Invoke(save_write_data));
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(),
+                                   expected_write_data.size() - 5, _, _, _, _))
+      .WillOnce(Invoke(save_write_data));
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 4, _, _, _, _))
+      .WillOnce(Invoke(save_write_data));
+
+  send_control_stream_->MaybeSendSettingsFrame();
+  quiche::test::CompareCharArraysWithHexError(
+      "settings", writer.data(), writer.length(), expected_write_data.data(),
+      expected_write_data.length());
+}
+
+TEST_P(QuicSendControlStreamTest, WriteSettingsOnlyOnce) {
+  Initialize();
+  testing::InSequence s;
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _));
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+      .Times(2);
+  send_control_stream_->MaybeSendSettingsFrame();
+
+  // No data should be written the second time MaybeSendSettingsFrame() is
+  // called.
+  send_control_stream_->MaybeSendSettingsFrame();
+}
+
+// Send stream type and SETTINGS frame if WritePriorityUpdate() is called first.
+TEST_P(QuicSendControlStreamTest, WritePriorityBeforeSettings) {
+  Initialize();
+  testing::InSequence s;
+
+  // The first write will trigger the control stream to write stream type, a
+  // SETTINGS frame, and a greased frame before the PRIORITY_UPDATE frame.
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+      .Times(4);
+  PriorityUpdateFrame frame;
+  send_control_stream_->WritePriorityUpdate(frame);
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _));
+  send_control_stream_->WritePriorityUpdate(frame);
+}
+
+TEST_P(QuicSendControlStreamTest, CloseControlStream) {
+  Initialize();
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  send_control_stream_->OnStopSending(
+      QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
+}
+
+TEST_P(QuicSendControlStreamTest, ReceiveDataOnSendControlStream) {
+  Initialize();
+  QuicStreamFrame frame(send_control_stream_->id(), false, 0, "test");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
+  send_control_stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSendControlStreamTest, SendGoAway) {
+  Initialize();
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  QuicStreamId stream_id = 4;
+
+  EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(stream_id));
+
+  send_control_stream_->SendGoAway(stream_id);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc b/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc
new file mode 100644
index 0000000..da63760
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc
@@ -0,0 +1,43 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_server_initiated_spdy_stream.h"
+#include "quiche/quic/core/quic_error_codes.h"
+
+namespace quic {
+
+void QuicServerInitiatedSpdyStream::OnBodyAvailable() {
+  QUIC_BUG(Body received in QuicServerInitiatedSpdyStream)
+      << "Received body data in QuicServerInitiatedSpdyStream.";
+  OnUnrecoverableError(
+      QUIC_INTERNAL_ERROR,
+      "Received HTTP/3 body data in a server-initiated bidirectional stream");
+}
+
+size_t QuicServerInitiatedSpdyStream::WriteHeaders(
+    spdy::SpdyHeaderBlock /*header_block*/, bool /*fin*/,
+    quiche::QuicheReferenceCountedPointer<
+        QuicAckListenerInterface> /*ack_listener*/) {
+  QUIC_BUG(Writing headers in QuicServerInitiatedSpdyStream)
+      << "Attempting to write headers in QuicServerInitiatedSpdyStream";
+  OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                       "Attempted to send HTTP/3 headers in a server-initiated "
+                       "bidirectional stream");
+  return 0;
+}
+
+void QuicServerInitiatedSpdyStream::OnInitialHeadersComplete(
+    bool /*fin*/,
+    size_t /*frame_len*/,
+    const QuicHeaderList& /*header_list*/) {
+  QUIC_PEER_BUG(Reading headers in QuicServerInitiatedSpdyStream)
+      << "Attempting to receive headers in QuicServerInitiatedSpdyStream";
+
+  OnUnrecoverableError(IETF_QUIC_PROTOCOL_VIOLATION,
+                       "Received HTTP/3 headers in a server-initiated "
+                       "bidirectional stream without an extension setting "
+                       "explicitly allowing those");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_server_initiated_spdy_stream.h b/quiche/quic/core/http/quic_server_initiated_spdy_stream.h
new file mode 100644
index 0000000..d60296c
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_initiated_spdy_stream.h
@@ -0,0 +1,32 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+
+namespace quic {
+
+// QuicServerInitiatedSpdyStream is a subclass of QuicSpdyStream meant to handle
+// WebTransport traffic on server-initiated bidirectional streams.  Receiving or
+// sending any other traffic on this stream will result in a CONNECTION_CLOSE.
+class QUIC_EXPORT_PRIVATE QuicServerInitiatedSpdyStream
+    : public QuicSpdyStream {
+ public:
+  using QuicSpdyStream::QuicSpdyStream;
+
+  void OnBodyAvailable() override;
+  size_t WriteHeaders(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener) override;
+  void OnInitialHeadersComplete(bool fin,
+                                size_t frame_len,
+                                const QuicHeaderList& header_list) override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_INITIATED_SPDY_STREAM_H_
diff --git a/quiche/quic/core/http/quic_server_session_base.cc b/quiche/quic/core/http/quic_server_session_base.cc
new file mode 100644
index 0000000..b636e4c
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_session_base.cc
@@ -0,0 +1,374 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_server_session_base.h"
+
+#include <string>
+
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicServerSessionBase::QuicServerSessionBase(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    Visitor* visitor,
+    QuicCryptoServerStreamBase::Helper* helper,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache)
+    : QuicSpdySession(connection, visitor, config, supported_versions),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(compressed_certs_cache),
+      helper_(helper),
+      bandwidth_resumption_enabled_(false),
+      bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
+      last_scup_time_(QuicTime::Zero()) {}
+
+QuicServerSessionBase::~QuicServerSessionBase() {}
+
+void QuicServerSessionBase::Initialize() {
+  crypto_stream_ =
+      CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_);
+  QuicSpdySession::Initialize();
+  SendSettingsToCryptoStream();
+}
+
+void QuicServerSessionBase::OnConfigNegotiated() {
+  QuicSpdySession::OnConfigNegotiated();
+
+  const bool use_lower_min_irtt =
+      connection()->sent_packet_manager().use_lower_min_irtt();
+
+  if (!use_lower_min_irtt) {
+    if (!config()->HasReceivedConnectionOptions()) {
+      return;
+    }
+  }
+
+  const CachedNetworkParameters* cached_network_params =
+      crypto_stream_->PreviousCachedNetworkParams();
+
+  // Set the initial rtt from cached_network_params.min_rtt_ms, which comes from
+  // a validated address token. This will override the initial rtt that may have
+  // been set by the transport parameters.
+  if (version().UsesTls() && cached_network_params != nullptr) {
+    if (cached_network_params->serving_region() == serving_region_) {
+      QUIC_CODE_COUNT(quic_server_received_network_params_at_same_region);
+      if ((!use_lower_min_irtt || config()->HasReceivedConnectionOptions()) &&
+          ContainsQuicTag(config()->ReceivedConnectionOptions(), kTRTT)) {
+        QUIC_DLOG(INFO)
+            << "Server: Setting initial rtt to "
+            << cached_network_params->min_rtt_ms()
+            << "ms which is received from a validated address token";
+        connection()->sent_packet_manager().SetInitialRtt(
+            QuicTime::Delta::FromMilliseconds(
+                cached_network_params->min_rtt_ms()),
+            /*trusted=*/use_lower_min_irtt);
+      }
+    } else {
+      QUIC_CODE_COUNT(quic_server_received_network_params_at_different_region);
+    }
+  }
+
+  if (use_lower_min_irtt) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 1, 2);
+    if (!config()->HasReceivedConnectionOptions()) {
+      return;
+    }
+  }
+
+  // Enable bandwidth resumption if peer sent correct connection options.
+  const bool last_bandwidth_resumption =
+      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
+  const bool max_bandwidth_resumption =
+      ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWMX);
+  bandwidth_resumption_enabled_ =
+      last_bandwidth_resumption || max_bandwidth_resumption;
+
+  // If the client has provided a bandwidth estimate from the same serving
+  // region as this server, then decide whether to use the data for bandwidth
+  // resumption.
+  if (cached_network_params != nullptr &&
+      cached_network_params->serving_region() == serving_region_) {
+    if (!version().UsesTls()) {
+      // Log the received connection parameters, regardless of how they
+      // get used for bandwidth resumption.
+      connection()->OnReceiveConnectionState(*cached_network_params);
+    }
+
+    if (bandwidth_resumption_enabled_) {
+      // Only do bandwidth resumption if estimate is recent enough.
+      const uint64_t seconds_since_estimate =
+          connection()->clock()->WallNow().ToUNIXSeconds() -
+          cached_network_params->timestamp();
+      if (seconds_since_estimate <= kNumSecondsPerHour) {
+        connection()->ResumeConnectionState(*cached_network_params,
+                                            max_bandwidth_resumption);
+      }
+    }
+  }
+}
+
+void QuicServerSessionBase::OnConnectionClosed(
+    const QuicConnectionCloseFrame& frame,
+    ConnectionCloseSource source) {
+  QuicSession::OnConnectionClosed(frame, source);
+  // In the unlikely event we get a connection close while doing an asynchronous
+  // crypto event, make sure we cancel the callback.
+  if (crypto_stream_ != nullptr) {
+    crypto_stream_->CancelOutstandingCallbacks();
+  }
+}
+
+void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
+  if (!bandwidth_resumption_enabled_) {
+    return;
+  }
+  // Only send updates when the application has no data to write.
+  if (HasDataToWrite()) {
+    return;
+  }
+
+  // If not enough time has passed since the last time we sent an update to the
+  // client, or not enough packets have been sent, then return early.
+  const QuicSentPacketManager& sent_packet_manager =
+      connection()->sent_packet_manager();
+  int64_t srtt_ms =
+      sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
+  int64_t now_ms = (now - last_scup_time_).ToMilliseconds();
+  int64_t packets_since_last_scup = 0;
+  const QuicPacketNumber largest_sent_packet =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+  if (largest_sent_packet.IsInitialized()) {
+    packets_since_last_scup =
+        last_scup_packet_number_.IsInitialized()
+            ? largest_sent_packet - last_scup_packet_number_
+            : largest_sent_packet.ToUint64();
+  }
+  if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
+      now_ms < kMinIntervalBetweenServerConfigUpdatesMs ||
+      packets_since_last_scup < kMinPacketsBetweenServerConfigUpdates) {
+    return;
+  }
+
+  // If the bandwidth recorder does not have a valid estimate, return early.
+  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
+      sent_packet_manager.SustainedBandwidthRecorder();
+  if (bandwidth_recorder == nullptr || !bandwidth_recorder->HasEstimate()) {
+    return;
+  }
+
+  // The bandwidth recorder has recorded at least one sustained bandwidth
+  // estimate. Check that it's substantially different from the last one that
+  // we sent to the client, and if so, send the new one.
+  QuicBandwidth new_bandwidth_estimate =
+      bandwidth_recorder->BandwidthEstimate();
+
+  int64_t bandwidth_delta =
+      std::abs(new_bandwidth_estimate.ToBitsPerSecond() -
+               bandwidth_estimate_sent_to_client_.ToBitsPerSecond());
+
+  // Define "substantial" difference as a 50% increase or decrease from the
+  // last estimate.
+  bool substantial_difference =
+      bandwidth_delta >
+      0.5 * bandwidth_estimate_sent_to_client_.ToBitsPerSecond();
+  if (!substantial_difference) {
+    return;
+  }
+
+  if (version().UsesTls()) {
+    if (version().HasIetfQuicFrames() && MaybeSendAddressToken()) {
+      bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
+    }
+  } else {
+    absl::optional<CachedNetworkParameters> cached_network_params =
+        GenerateCachedNetworkParameters();
+
+    if (cached_network_params.has_value()) {
+      bandwidth_estimate_sent_to_client_ = new_bandwidth_estimate;
+      QUIC_DVLOG(1) << "Server: sending new bandwidth estimate (KBytes/s): "
+                    << bandwidth_estimate_sent_to_client_.ToKBytesPerSecond();
+
+      QUICHE_DCHECK_EQ(
+          BandwidthToCachedParameterBytesPerSecond(
+              bandwidth_estimate_sent_to_client_),
+          cached_network_params->bandwidth_estimate_bytes_per_second());
+
+      crypto_stream_->SendServerConfigUpdate(&cached_network_params.value());
+
+      connection()->OnSendConnectionState(*cached_network_params);
+    }
+  }
+
+  last_scup_time_ = now;
+  last_scup_packet_number_ =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+}
+
+bool QuicServerSessionBase::ShouldCreateIncomingStream(QuicStreamId id) {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_10393_2)
+        << "ShouldCreateIncomingStream called when disconnected";
+    return false;
+  }
+
+  if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
+    QUIC_BUG(quic_bug_10393_3)
+        << "ShouldCreateIncomingStream called with server initiated "
+           "stream ID.";
+    return false;
+  }
+
+  if (QuicUtils::IsServerInitiatedStreamId(transport_version(), id)) {
+    QUIC_DLOG(INFO) << "Invalid incoming even stream_id:" << id;
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Client created even numbered stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  return true;
+}
+
+bool QuicServerSessionBase::ShouldCreateOutgoingBidirectionalStream() {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_12513_2)
+        << "ShouldCreateOutgoingBidirectionalStream called when disconnected";
+    return false;
+  }
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG(quic_bug_10393_4)
+        << "Encryption not established so no outgoing stream created.";
+    return false;
+  }
+
+  return CanOpenNextOutgoingBidirectionalStream();
+}
+
+bool QuicServerSessionBase::ShouldCreateOutgoingUnidirectionalStream() {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_12513_3)
+        << "ShouldCreateOutgoingUnidirectionalStream called when disconnected";
+    return false;
+  }
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG(quic_bug_10393_5)
+        << "Encryption not established so no outgoing stream created.";
+    return false;
+  }
+
+  return CanOpenNextOutgoingUnidirectionalStream();
+}
+
+QuicCryptoServerStreamBase* QuicServerSessionBase::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
+    const QuicBandwidth& bandwidth) const {
+  return static_cast<int32_t>(std::min<int64_t>(
+      bandwidth.ToBytesPerSecond(), std::numeric_limits<uint32_t>::max()));
+}
+
+void QuicServerSessionBase::SendSettingsToCryptoStream() {
+  if (!version().UsesTls()) {
+    return;
+  }
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount buffer_size =
+      HttpEncoder::SerializeSettingsFrame(settings(), &buffer);
+
+  std::unique_ptr<ApplicationState> serialized_settings =
+      std::make_unique<ApplicationState>(buffer.get(),
+                                         buffer.get() + buffer_size);
+  GetMutableCryptoStream()->SetServerApplicationStateForResumption(
+      std::move(serialized_settings));
+}
+
+QuicSSLConfig QuicServerSessionBase::GetSSLConfig() const {
+  QUICHE_DCHECK(crypto_config_ && crypto_config_->proof_source());
+
+  QuicSSLConfig ssl_config = QuicSpdySession::GetSSLConfig();
+
+  ssl_config.disable_ticket_support =
+      GetQuicFlag(FLAGS_quic_disable_server_tls_resumption);
+
+  if (!crypto_config_ || !crypto_config_->proof_source()) {
+    return ssl_config;
+  }
+
+  absl::InlinedVector<uint16_t, 8> signature_algorithms =
+      crypto_config_->proof_source()->SupportedTlsSignatureAlgorithms();
+  if (!signature_algorithms.empty()) {
+    ssl_config.signing_algorithm_prefs = std::move(signature_algorithms);
+  }
+
+  return ssl_config;
+}
+
+absl::optional<CachedNetworkParameters>
+QuicServerSessionBase::GenerateCachedNetworkParameters() const {
+  const QuicSentPacketManager& sent_packet_manager =
+      connection()->sent_packet_manager();
+  const QuicSustainedBandwidthRecorder* bandwidth_recorder =
+      sent_packet_manager.SustainedBandwidthRecorder();
+
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_timestamp(
+      connection()->clock()->WallNow().ToUNIXSeconds());
+
+  if (!sent_packet_manager.GetRttStats()->min_rtt().IsZero()) {
+    cached_network_params.set_min_rtt_ms(
+        sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds());
+  }
+
+  // Populate bandwidth estimates if any.
+  if (bandwidth_recorder != nullptr && bandwidth_recorder->HasEstimate()) {
+    const int32_t bw_estimate_bytes_per_second =
+        BandwidthToCachedParameterBytesPerSecond(
+            bandwidth_recorder->BandwidthEstimate());
+    const int32_t max_bw_estimate_bytes_per_second =
+        BandwidthToCachedParameterBytesPerSecond(
+            bandwidth_recorder->MaxBandwidthEstimate());
+    QUIC_BUG_IF(quic_bug_12513_1, max_bw_estimate_bytes_per_second < 0)
+        << max_bw_estimate_bytes_per_second;
+    QUIC_BUG_IF(quic_bug_10393_1, bw_estimate_bytes_per_second < 0)
+        << bw_estimate_bytes_per_second;
+
+    cached_network_params.set_bandwidth_estimate_bytes_per_second(
+        bw_estimate_bytes_per_second);
+    cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
+        max_bw_estimate_bytes_per_second);
+    cached_network_params.set_max_bandwidth_timestamp_seconds(
+        bandwidth_recorder->MaxBandwidthTimestamp());
+
+    cached_network_params.set_previous_connection_state(
+        bandwidth_recorder->EstimateRecordedDuringSlowStart()
+            ? CachedNetworkParameters::SLOW_START
+            : CachedNetworkParameters::CONGESTION_AVOIDANCE);
+  }
+
+  if (!serving_region_.empty()) {
+    cached_network_params.set_serving_region(serving_region_);
+  }
+
+  return cached_network_params;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_server_session_base.h b/quiche/quic/core/http/quic_server_session_base.h
new file mode 100644
index 0000000..d30b9dd
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_session_base.h
@@ -0,0 +1,151 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A server specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
+
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicConfig;
+class QuicConnection;
+class QuicCryptoServerConfig;
+
+namespace test {
+class QuicServerSessionBasePeer;
+class QuicSimpleServerSessionPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
+ public:
+  // Does not take ownership of |connection|. |crypto_config| must outlive the
+  // session. |helper| must outlive any created crypto streams.
+  QuicServerSessionBase(const QuicConfig& config,
+                        const ParsedQuicVersionVector& supported_versions,
+                        QuicConnection* connection,
+                        QuicSession::Visitor* visitor,
+                        QuicCryptoServerStreamBase::Helper* helper,
+                        const QuicCryptoServerConfig* crypto_config,
+                        QuicCompressedCertsCache* compressed_certs_cache);
+  QuicServerSessionBase(const QuicServerSessionBase&) = delete;
+  QuicServerSessionBase& operator=(const QuicServerSessionBase&) = delete;
+
+  // Override the base class to cancel any ongoing asychronous crypto.
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+
+  // Sends a server config update to the client, containing new bandwidth
+  // estimate.
+  void OnCongestionWindowChange(QuicTime now) override;
+
+  ~QuicServerSessionBase() override;
+
+  void Initialize() override;
+
+  const QuicCryptoServerStreamBase* crypto_stream() const {
+    return crypto_stream_.get();
+  }
+
+  // Override base class to process bandwidth related config received from
+  // client.
+  void OnConfigNegotiated() override;
+
+  void set_serving_region(const std::string& serving_region) {
+    serving_region_ = serving_region;
+  }
+
+  const std::string& serving_region() const { return serving_region_; }
+
+  QuicSSLConfig GetSSLConfig() const override;
+
+ protected:
+  // QuicSession methods(override them with return type of QuicSpdyStream*):
+  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
+
+  const QuicCryptoServerStreamBase* GetCryptoStream() const override;
+
+  absl::optional<CachedNetworkParameters> GenerateCachedNetworkParameters()
+      const override;
+
+  // If an outgoing stream can be created, return true.
+  // Return false when connection is closed or forward secure encryption hasn't
+  // established yet or number of server initiated streams already reaches the
+  // upper limit.
+  bool ShouldCreateOutgoingBidirectionalStream() override;
+  bool ShouldCreateOutgoingUnidirectionalStream() override;
+
+  // If we should create an incoming stream, returns true. Otherwise
+  // does error handling, including communicating the error to the client and
+  // possibly closing the connection, and returns false.
+  bool ShouldCreateIncomingStream(QuicStreamId id) override;
+
+  virtual std::unique_ptr<QuicCryptoServerStreamBase>
+  CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) = 0;
+
+  const QuicCryptoServerConfig* crypto_config() { return crypto_config_; }
+
+  QuicCryptoServerStreamBase::Helper* stream_helper() { return helper_; }
+
+ private:
+  friend class test::QuicServerSessionBasePeer;
+  friend class test::QuicSimpleServerSessionPeer;
+
+  // Informs the QuicCryptoStream of the SETTINGS that will be used on this
+  // connection, so that the server crypto stream knows whether to accept 0-RTT
+  // data.
+  void SendSettingsToCryptoStream();
+
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // The cache which contains most recently compressed certs.
+  // Owned by QuicDispatcher.
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
+
+  // Pointer to the helper used to create crypto server streams. Must outlive
+  // streams created via CreateQuicCryptoServerStream.
+  QuicCryptoServerStreamBase::Helper* helper_;
+
+  // Whether bandwidth resumption is enabled for this connection.
+  bool bandwidth_resumption_enabled_;
+
+  // The most recent bandwidth estimate sent to the client.
+  QuicBandwidth bandwidth_estimate_sent_to_client_;
+
+  // Text describing server location. Sent to the client as part of the bandwith
+  // estimate in the source-address token. Optional, can be left empty.
+  std::string serving_region_;
+
+  // Time at which we send the last SCUP to the client.
+  QuicTime last_scup_time_;
+
+  // Number of packets sent to the peer, at the time we last sent a SCUP.
+  QuicPacketNumber last_scup_packet_number_;
+
+  // Converts QuicBandwidth to an int32 bytes/second that can be
+  // stored in CachedNetworkParameters.  TODO(jokulik): This function
+  // should go away once we fix http://b//27897982
+  int32_t BandwidthToCachedParameterBytesPerSecond(
+      const QuicBandwidth& bandwidth) const;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SERVER_SESSION_BASE_H_
diff --git a/quiche/quic/core/http/quic_server_session_base_test.cc b/quiche/quic/core/http/quic_server_session_base_test.cc
new file mode 100644
index 0000000..9b8dbcf
--- /dev/null
+++ b/quiche/quic/core/http/quic_server_session_base_test.cc
@@ -0,0 +1,809 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_server_session_base.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_crypto_server_stream.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/tls_server_handshaker.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_server_session_base_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+using testing::_;
+using testing::StrictMock;
+
+using testing::AtLeast;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Data to be sent on a request stream.  In Google QUIC, this is interpreted as
+// DATA payload (there is no framing on request streams).  In IETF QUIC, this is
+// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z').  Since
+// no payload is included, QPACK decoder will not be invoked.
+const char* const kStreamData = "\1z";
+
+class TestServerSession : public QuicServerSessionBase {
+ public:
+  TestServerSession(const QuicConfig& config,
+                    QuicConnection* connection,
+                    QuicSession::Visitor* visitor,
+                    QuicCryptoServerStreamBase::Helper* helper,
+                    const QuicCryptoServerConfig* crypto_config,
+                    QuicCompressedCertsCache* compressed_certs_cache,
+                    QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicServerSessionBase(config,
+                              CurrentSupportedVersions(),
+                              connection,
+                              visitor,
+                              helper,
+                              crypto_config,
+                              compressed_certs_cache),
+        quic_simple_server_backend_(quic_simple_server_backend) {}
+
+  ~TestServerSession() override { DeleteConnection(); }
+
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+
+ protected:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        id, this, BIDIRECTIONAL, quic_simple_server_backend_);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override {
+    QuicSpdyStream* stream =
+        new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  QuicSpdyStream* CreateOutgoingBidirectionalStream() override {
+    QUICHE_DCHECK(false);
+    return nullptr;
+  }
+
+  QuicSpdyStream* CreateOutgoingUnidirectionalStream() override {
+    if (!ShouldCreateOutgoingUnidirectionalStream()) {
+      return nullptr;
+    }
+
+    QuicSpdyStream* stream = new QuicSimpleServerStream(
+        GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
+        quic_simple_server_backend_);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override {
+    return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
+                                    stream_helper());
+  }
+
+ private:
+  QuicSimpleServerBackend*
+      quic_simple_server_backend_;  // Owned by QuicServerSessionBaseTest
+};
+
+const size_t kMaxStreamsForTest = 10;
+
+class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicServerSessionBaseTest()
+      : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
+
+  explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
+      : crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(),
+                       std::move(proof_source),
+                       KeyExchangeSource::Default()),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
+    config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
+    QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
+                                                       kMaxStreamsForTest);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
+                                                        kMaxStreamsForTest);
+    config_.SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+
+    ParsedQuicVersionVector supported_versions = SupportedVersions(version());
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<TestServerSession>(
+        config_, connection_, &owner_, &stream_helper_, &crypto_config_,
+        &compressed_certs_cache_, &memory_cache_backend_);
+    MockClock clock;
+    handshake_message_ = crypto_config_.AddDefaultConfig(
+        QuicRandom::GetInstance(), &clock,
+        QuicCryptoServerConfig::ConfigOptions());
+    session_->Initialize();
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_->config(), kMinimumFlowControlSendWindow);
+    session_->OnConfigNegotiated();
+    if (version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
+        transport_version(), n);
+  }
+
+  ParsedQuicVersion version() const { return GetParam(); }
+
+  QuicTransportVersion transport_version() const {
+    return version().transport_version;
+  }
+
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close. This method can be used to inject a STOP_SENDING, which
+  // would cause a close in the opposite direction. This allows tests to do the
+  // extra work to get a two-way (full) close where desired. Also sets up
+  // expects needed to ensure that the STOP_SENDING worked as expected.
+  void InjectStopSendingFrame(QuicStreamId stream_id) {
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      // Only needed for version 99/IETF QUIC. Noop otherwise.
+      return;
+    }
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
+                                      QUIC_ERROR_PROCESSING_STREAM);
+    EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM));
+    session_->OnStopSendingFrame(stop_sending);
+  }
+
+  StrictMock<MockQuicSessionVisitor> owner_;
+  StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicConfig config_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicMemoryCacheBackend memory_cache_backend_;
+  std::unique_ptr<TestServerSession> session_;
+  std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
+};
+
+// Compares CachedNetworkParameters.
+MATCHER_P(EqualsProto, network_params, "") {
+  CachedNetworkParameters reference(network_params);
+  return (arg->bandwidth_estimate_bytes_per_second() ==
+              reference.bandwidth_estimate_bytes_per_second() &&
+          arg->bandwidth_estimate_bytes_per_second() ==
+              reference.bandwidth_estimate_bytes_per_second() &&
+          arg->max_bandwidth_estimate_bytes_per_second() ==
+              reference.max_bandwidth_estimate_bytes_per_second() &&
+          arg->max_bandwidth_timestamp_seconds() ==
+              reference.max_bandwidth_timestamp_seconds() &&
+          arg->min_rtt_ms() == reference.min_rtt_ms() &&
+          arg->previous_connection_state() ==
+              reference.previous_connection_state());
+}
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicServerSessionBaseTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
+  // Send some data open a stream, then reset it.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst1);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  // Send the same two bytes of payload in a new packet.
+  session_->OnStreamFrame(data1);
+
+  // The stream should not be re-opened.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst1);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
+  // Send some data to open two streams.
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         kStreamData);
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         kStreamData);
+  session_->OnStreamFrame(frame1);
+  session_->OnStreamFrame(frame2);
+  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst(kInvalidControlFrameId,
+                         GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, the RESET_STREAM will do the full close.
+    // Set up expects accordingly.
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst);
+
+  // For version-99 will create and receive a stop-sending, completing
+  // the full-close expected by this test.
+  InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
+
+  // If we were tracking, we'd probably want to reject this because it's data
+  // past the reset point of stream 3.  As it's a closed stream we just drop the
+  // data on the floor, but accept the packet because it has data for stream 5.
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
+                         kStreamData);
+  QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
+                         kStreamData);
+  session_->OnStreamFrame(frame3);
+  session_->OnStreamFrame(frame4);
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
+  // Test that the server refuses if a client attempts to open too many data
+  // streams.  For versions other than version 99, the server accepts slightly
+  // more than the negotiated stream limit to deal with rare cases where a
+  // client FIN/RST is lost.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // The slightly increased stream limit is set during config negotiation.  It
+    // is either an increase of 10 over negotiated limit, or a fixed percentage
+    // scaling, whichever is larger. Test both before continuing.
+    EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
+              kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
+    EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
+              session_->max_open_incoming_bidirectional_streams());
+  }
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  // Open the max configured number of streams, should be no problem.
+  for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
+    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
+                                                             stream_id));
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Open more streams: server should accept slightly more than the limit.
+    // Excess streams are for non-version-99 only.
+    for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
+      EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
+                                                               stream_id));
+      stream_id += QuicUtils::StreamIdDelta(transport_version());
+    }
+  }
+  // Now violate the server's internal stream limit.
+  stream_id += QuicUtils::StreamIdDelta(transport_version());
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For non-version 99, QUIC responds to an attempt to exceed the stream
+    // limit by resetting the stream.
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
+  } else {
+    // In version 99 QUIC responds to an attempt to exceed the stream limit by
+    // closing the connection.
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  }
+  // Even if the connection remains open, the stream creation should fail.
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::GetOrCreateStream(session_.get(), stream_id));
+}
+
+TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
+  // Test that the server closes the connection if a client makes too many data
+  // streams available.  The server accepts slightly more than the negotiated
+  // stream limit to deal with rare cases where a client FIN/RST is lost.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  const size_t kAvailableStreamLimit =
+      session_->MaxAvailableBidirectionalStreams();
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
+      session_.get(), GetNthClientInitiatedBidirectionalId(0)));
+
+  // Establish available streams up to the server's limit.
+  QuicStreamId next_id = QuicUtils::StreamIdDelta(transport_version());
+  const int kLimitingStreamId =
+      GetNthClientInitiatedBidirectionalId(kAvailableStreamLimit + 1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // This exceeds the stream limit. In versions other than 99
+    // this is allowed. Version 99 hews to the IETF spec and does
+    // not allow it.
+    EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
+        session_.get(), kLimitingStreamId));
+    // A further available stream will result in connection close.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  } else {
+    // A further available stream will result in connection close.
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  }
+
+  // This forces stream kLimitingStreamId + 2 to become available, which
+  // violates the quota.
+  EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateStream(
+      session_.get(), kLimitingStreamId + 2 * next_id));
+}
+
+TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
+  // Incoming streams on the server session must be odd.
+  const QuicErrorCode expected_error =
+      VersionHasIetfQuicFrames(transport_version())
+          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+          : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(*connection_, CloseConnection(expected_error, _, _));
+  EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateStream(
+                         session_.get(),
+                         session_->next_outgoing_unidirectional_stream_id()));
+}
+
+TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (version() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Don't create new streams if the connection is disconnected.
+  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateStream(
+                      session_.get(), GetNthClientInitiatedBidirectionalId(0)),
+                  "ShouldCreateIncomingStream called when disconnected");
+}
+
+class MockQuicCryptoServerStream : public QuicCryptoServerStream {
+ public:
+  explicit MockQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicServerSessionBase* session,
+      QuicCryptoServerStreamBase::Helper* helper)
+      : QuicCryptoServerStream(crypto_config,
+                               compressed_certs_cache,
+                               session,
+                               helper) {}
+  MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
+  MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
+      delete;
+  ~MockQuicCryptoServerStream() override {}
+
+  MOCK_METHOD(void,
+              SendServerConfigUpdate,
+              (const CachedNetworkParameters*),
+              (override));
+};
+
+class MockTlsServerHandshaker : public TlsServerHandshaker {
+ public:
+  explicit MockTlsServerHandshaker(QuicServerSessionBase* session,
+                                   const QuicCryptoServerConfig* crypto_config)
+      : TlsServerHandshaker(session, crypto_config) {}
+  MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
+  MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
+  ~MockTlsServerHandshaker() override {}
+
+  MOCK_METHOD(void, SendServerConfigUpdate, (const CachedNetworkParameters*),
+              (override));
+
+  MOCK_METHOD(std::string, GetAddressToken, (const CachedNetworkParameters*),
+              (const, override));
+};
+
+TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
+  if (version().UsesTls() && !version().HasIetfQuicFrames()) {
+    // Skip the Txxx versions.
+    return;
+  }
+
+  // Test that bandwidth estimate updates are sent to the client, only when
+  // bandwidth resumption is enabled, the bandwidth estimate has changed
+  // sufficiently, enough time has passed,
+  // and we don't have any other data to write.
+
+  // Client has sent kBWRE connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWRE);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  EXPECT_TRUE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+
+  int32_t bandwidth_estimate_kbytes_per_second = 123;
+  int32_t max_bandwidth_estimate_kbytes_per_second = 134;
+  int32_t max_bandwidth_estimate_timestamp = 1122334455;
+  const std::string serving_region = "not a real region";
+  session_->set_serving_region(serving_region);
+
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->UnregisterStreamPriority(
+        QuicUtils::GetHeadersStreamId(transport_version()),
+        /*is_static=*/true);
+  }
+  QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
+  MockQuicCryptoServerStream* quic_crypto_stream = nullptr;
+  MockTlsServerHandshaker* tls_server_stream = nullptr;
+  if (version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    quic_crypto_stream = new MockQuicCryptoServerStream(
+        &crypto_config_, &compressed_certs_cache_, session_.get(),
+        &stream_helper_);
+    QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
+                                               quic_crypto_stream);
+  } else {
+    tls_server_stream =
+        new MockTlsServerHandshaker(session_.get(), &crypto_config_);
+    QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
+                                               tls_server_stream);
+  }
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->RegisterStreamPriority(
+        QuicUtils::GetHeadersStreamId(transport_version()),
+        /*is_static=*/true,
+        spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
+  }
+
+  // Set some initial bandwidth values.
+  QuicSentPacketManager* sent_packet_manager =
+      QuicConnectionPeer::GetSentPacketManager(session_->connection());
+  QuicSustainedBandwidthRecorder& bandwidth_recorder =
+      QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
+  // Seed an rtt measurement equal to the initial default rtt.
+  RttStats* rtt_stats =
+      const_cast<RttStats*>(sent_packet_manager->GetRttStats());
+  rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(),
+                       QuicTime::Zero());
+  QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
+      &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
+  QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
+      &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
+      max_bandwidth_estimate_timestamp);
+  // Queue up some pending data.
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetHeadersStreamId(transport_version()));
+  } else {
+    session_->MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                  Perspective::IS_SERVER));
+  }
+  EXPECT_TRUE(session_->HasDataToWrite());
+
+  // There will be no update sent yet - not enough time has passed.
+  QuicTime now = QuicTime::Zero();
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently but not enough time has
+  // passed to send a Server Config Update.
+  bandwidth_estimate_kbytes_per_second =
+      bandwidth_estimate_kbytes_per_second * 1.6;
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently and enough time has passed,
+  // but not enough packets have been sent.
+  int64_t srtt_ms =
+      sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
+  now = now + QuicTime::Delta::FromMilliseconds(
+                  kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms);
+  session_->OnCongestionWindowChange(now);
+
+  // The connection no longer has pending data to be written.
+  session_->OnCanWrite();
+  EXPECT_FALSE(session_->HasDataToWrite());
+  session_->OnCongestionWindowChange(now);
+
+  // Bandwidth estimate has now changed sufficiently, enough time has passed,
+  // and enough packets have been sent.
+  SerializedPacket packet(
+      QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
+      PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
+  sent_packet_manager->OnPacketSent(&packet, now, NOT_RETRANSMISSION,
+                                    HAS_RETRANSMITTABLE_DATA, true);
+
+  // Verify that the proto has exactly the values we expect.
+  CachedNetworkParameters expected_network_params;
+  expected_network_params.set_bandwidth_estimate_bytes_per_second(
+      bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
+  expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
+      bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
+  expected_network_params.set_max_bandwidth_timestamp_seconds(
+      bandwidth_recorder.MaxBandwidthTimestamp());
+  expected_network_params.set_min_rtt_ms(session_->connection()
+                                             ->sent_packet_manager()
+                                             .GetRttStats()
+                                             ->min_rtt()
+                                             .ToMilliseconds());
+  expected_network_params.set_previous_connection_state(
+      CachedNetworkParameters::CONGESTION_AVOIDANCE);
+  expected_network_params.set_timestamp(
+      session_->connection()->clock()->WallNow().ToUNIXSeconds());
+  expected_network_params.set_serving_region(serving_region);
+
+  if (quic_crypto_stream) {
+    EXPECT_CALL(*quic_crypto_stream,
+                SendServerConfigUpdate(EqualsProto(expected_network_params)))
+        .Times(1);
+  } else {
+    EXPECT_CALL(*tls_server_stream,
+                GetAddressToken(EqualsProto(expected_network_params)))
+        .WillOnce(testing::Return("Test address token"));
+  }
+  EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
+  session_->OnCongestionWindowChange(now);
+}
+
+TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
+  if (version().UsesTls()) {
+    if (!version().HasIetfQuicFrames()) {
+      // Skip the Txxx versions.
+      return;
+    }
+    // Avoid a QUIC_BUG in QuicSession::OnConfigNegotiated.
+    connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  }
+
+  // Test that if a client provides a CachedNetworkParameters with the same
+  // serving region as the current server, and which was made within an hour of
+  // now, that this data is passed down to the send algorithm.
+
+  // Client has sent kBWRE connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWRE);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+
+  const std::string kTestServingRegion = "a serving region";
+  session_->set_serving_region(kTestServingRegion);
+
+  // Set the time to be one hour + one second from the 0 baseline.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
+
+  QuicCryptoServerStreamBase* crypto_stream =
+      static_cast<QuicCryptoServerStreamBase*>(
+          QuicSessionPeer::GetMutableCryptoStream(session_.get()));
+
+  // No effect if no CachedNetworkParameters provided.
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // No effect if CachedNetworkParameters provided, but different serving
+  // regions.
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
+  cached_network_params.set_serving_region("different serving region");
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // Same serving region, but timestamp is too old, should have no effect.
+  cached_network_params.set_serving_region(kTestServingRegion);
+  cached_network_params.set_timestamp(0);
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
+  session_->OnConfigNegotiated();
+
+  // Same serving region, and timestamp is recent: estimate is stored.
+  cached_network_params.set_timestamp(
+      connection_->clock()->WallNow().ToUNIXSeconds());
+  crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
+  EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
+  session_->OnConfigNegotiated();
+}
+
+TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+
+  // Client has sent kBWMX connection option to trigger bandwidth resumption.
+  QuicTagVector copt;
+  copt.push_back(kBWMX);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  EXPECT_TRUE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+}
+
+TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_->OnConfigNegotiated();
+  EXPECT_FALSE(
+      QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+}
+
+// Tests which check the lifetime management of data members of
+// QuicCryptoServerStream objects when async GetProof is in use.
+class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
+ public:
+  StreamMemberLifetimeTest()
+      : QuicServerSessionBaseTest(
+            std::unique_ptr<FakeProofSource>(new FakeProofSource())),
+        crypto_config_peer_(&crypto_config_) {
+    GetFakeProofSource()->Activate();
+  }
+
+  FakeProofSource* GetFakeProofSource() const {
+    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
+  }
+
+ private:
+  QuicCryptoServerConfigPeer crypto_config_peer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(StreamMemberLifetimeTests,
+                         StreamMemberLifetimeTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Trigger an operation which causes an async invocation of
+// ProofSource::GetProof.  Delay the completion of the operation until after the
+// stream has been destroyed, and verify that there are no memory bugs.
+TEST_P(StreamMemberLifetimeTest, Basic) {
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test depends on the QUIC crypto protocol, so it is disabled for the
+    // TLS handshake.
+    // TODO(nharper): Fix this test so it doesn't rely on QUIC crypto.
+    return;
+  }
+
+  const QuicClock* clock = helper_.GetClock();
+  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
+      clock, transport_version(), &crypto_config_);
+  chlo.SetVector(kCOPT, QuicTagVector{kREJ});
+  std::vector<ParsedQuicVersion> packet_version_list = {version()};
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      TestConnectionId(1), EmptyQuicConnectionId(), true, false, 1,
+      std::string(chlo.GetSerialized().AsStringPiece()), CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &packet_version_list));
+
+  EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+
+  // Set the current packet
+  QuicConnectionPeer::SetCurrentPacket(session_->connection(),
+                                       packet->AsStringPiece());
+
+  // Yes, this is horrible.  But it's the easiest way to trigger the behavior we
+  // need to exercise.
+  QuicCryptoServerStreamBase* crypto_stream =
+      const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
+
+  // Feed the CHLO into the crypto stream, which will trigger a call to
+  // ProofSource::GetProof
+  crypto_test_utils::SendHandshakeMessageToStream(crypto_stream, chlo,
+                                                  Perspective::IS_CLIENT);
+  ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+  // Destroy the stream
+  session_.reset();
+
+  // Allow the async ProofSource::GetProof call to complete.  Verify (under
+  // memory access checkers) that this does not result in accesses to any
+  // freed memory from the session or its subobjects.
+  GetFakeProofSource()->InvokePendingCallback(0);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_session.cc b/quiche/quic/core/http/quic_spdy_client_session.cc
new file mode 100644
index 0000000..ed02803
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session.cc
@@ -0,0 +1,223 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/http/quic_server_initiated_spdy_stream.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSpdyClientSession::QuicSpdyClientSession(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index)
+    : QuicSpdyClientSessionBase(connection,
+                                push_promise_index,
+                                config,
+                                supported_versions),
+      server_id_(server_id),
+      crypto_config_(crypto_config),
+      respect_goaway_(true) {}
+
+QuicSpdyClientSession::~QuicSpdyClientSession() = default;
+
+void QuicSpdyClientSession::Initialize() {
+  crypto_stream_ = CreateQuicCryptoStream();
+  if (config()->HasClientRequestedIndependentOption(kQLVE,
+                                                    Perspective::IS_CLIENT)) {
+    connection()->EnableLegacyVersionEncapsulation(server_id_.host());
+  }
+  QuicSpdyClientSessionBase::Initialize();
+}
+
+void QuicSpdyClientSession::OnProofValid(
+    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
+
+void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& /*verify_details*/) {}
+
+bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
+    return false;
+  }
+  if (goaway_received() && respect_goaway_) {
+    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                    << "Already received goaway.";
+    return false;
+  }
+  return CanOpenNextOutgoingBidirectionalStream();
+}
+
+bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
+  QUIC_BUG(quic_bug_10396_1)
+      << "Try to create outgoing unidirectional client data streams";
+  return false;
+}
+
+QuicSpdyClientStream*
+QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
+  if (!ShouldCreateOutgoingBidirectionalStream()) {
+    return nullptr;
+  }
+  std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
+  QuicSpdyClientStream* stream_ptr = stream.get();
+  ActivateStream(std::move(stream));
+  return stream_ptr;
+}
+
+QuicSpdyClientStream*
+QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
+  QUIC_BUG(quic_bug_10396_2)
+      << "Try to create outgoing unidirectional client data streams";
+  return nullptr;
+}
+
+std::unique_ptr<QuicSpdyClientStream>
+QuicSpdyClientSession::CreateClientStream() {
+  return std::make_unique<QuicSpdyClientStream>(
+      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+}
+
+QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+bool QuicSpdyClientSession::IsKnownServerAddress(
+    const QuicSocketAddress& address) const {
+  return std::find(known_server_addresses_.cbegin(),
+                   known_server_addresses_.cend(),
+                   address) != known_server_addresses_.cend();
+}
+
+void QuicSpdyClientSession::AddKnownServerAddress(
+    const QuicSocketAddress& address) {
+  known_server_addresses_.push_back(address);
+}
+
+void QuicSpdyClientSession::CryptoConnect() {
+  QUICHE_DCHECK(flow_controller());
+  crypto_stream_->CryptoConnect();
+}
+
+int QuicSpdyClientSession::GetNumSentClientHellos() const {
+  return crypto_stream_->num_sent_client_hellos();
+}
+
+bool QuicSpdyClientSession::IsResumption() const {
+  return crypto_stream_->IsResumption();
+}
+
+bool QuicSpdyClientSession::EarlyDataAccepted() const {
+  return crypto_stream_->EarlyDataAccepted();
+}
+
+bool QuicSpdyClientSession::ReceivedInchoateReject() const {
+  return crypto_stream_->ReceivedInchoateReject();
+}
+
+int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
+  return crypto_stream_->num_scup_messages_received();
+}
+
+bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
+  if (!connection()->connected()) {
+    QUIC_BUG(quic_bug_10396_3)
+        << "ShouldCreateIncomingStream called when disconnected";
+    return false;
+  }
+  if (goaway_received() && respect_goaway_) {
+    QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
+                    << "Already received goaway.";
+    return false;
+  }
+
+  if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
+    QUIC_BUG(quic_bug_10396_4)
+        << "ShouldCreateIncomingStream called with client initiated "
+           "stream ID.";
+    return false;
+  }
+
+  if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id)) {
+    QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Server created non write unidirectional stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::IsBidirectionalStreamId(id, version()) &&
+      !WillNegotiateWebTransport()) {
+    connection()->CloseConnection(
+        QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM,
+        "Server created bidirectional stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  return true;
+}
+
+QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
+    PendingStream* pending) {
+  QuicSpdyStream* stream = new QuicSpdyClientStream(pending, this);
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
+  if (!ShouldCreateIncomingStream(id)) {
+    return nullptr;
+  }
+  QuicSpdyStream* stream;
+  if (version().UsesHttp3() &&
+      QuicUtils::IsBidirectionalStreamId(id, version())) {
+    QUIC_BUG_IF(QuicServerInitiatedSpdyStream but no WebTransport support,
+                !WillNegotiateWebTransport())
+        << "QuicServerInitiatedSpdyStream created but no WebTransport support";
+    stream = new QuicServerInitiatedSpdyStream(id, this, BIDIRECTIONAL);
+  } else {
+    stream = new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
+  }
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+std::unique_ptr<QuicCryptoClientStreamBase>
+QuicSpdyClientSession::CreateQuicCryptoStream() {
+  return std::make_unique<QuicCryptoClientStream>(
+      server_id_, this,
+      crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
+      this, /*has_application_state = */ version().UsesHttp3());
+}
+
+bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_session.h b/quiche/quic/core/http/quic_spdy_client_session.h
new file mode 100644
index 0000000..ceab083
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A client specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
+
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+class QuicConnection;
+class QuicServerId;
+
+class QUIC_EXPORT_PRIVATE QuicSpdyClientSession
+    : public QuicSpdyClientSessionBase {
+ public:
+  // Takes ownership of |connection|. Caller retains ownership of
+  // |promised_by_url|.
+  QuicSpdyClientSession(const QuicConfig& config,
+                        const ParsedQuicVersionVector& supported_versions,
+                        QuicConnection* connection,
+                        const QuicServerId& server_id,
+                        QuicCryptoClientConfig* crypto_config,
+                        QuicClientPushPromiseIndex* push_promise_index);
+  QuicSpdyClientSession(const QuicSpdyClientSession&) = delete;
+  QuicSpdyClientSession& operator=(const QuicSpdyClientSession&) = delete;
+  ~QuicSpdyClientSession() override;
+  // Set up the QuicSpdyClientSession. Must be called prior to use.
+  void Initialize() override;
+
+  // QuicSession methods:
+  QuicSpdyClientStream* CreateOutgoingBidirectionalStream() override;
+  QuicSpdyClientStream* CreateOutgoingUnidirectionalStream() override;
+  QuicCryptoClientStreamBase* GetMutableCryptoStream() override;
+  const QuicCryptoClientStreamBase* GetCryptoStream() const override;
+  bool IsKnownServerAddress(const QuicSocketAddress& address) const override;
+
+  void AddKnownServerAddress(const QuicSocketAddress& address);
+
+  bool IsAuthorized(const std::string& authority) override;
+
+  // QuicSpdyClientSessionBase methods:
+  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // Performs a crypto handshake with the server.
+  virtual void CryptoConnect();
+
+  // Returns the number of client hello messages that have been sent on the
+  // crypto stream. If the handshake has completed then this is one greater
+  // than the number of round-trips needed for the handshake.
+  int GetNumSentClientHellos() const;
+
+  // Return true if the handshake performed is a TLS resumption.
+  // Always return false for QUIC Crypto.
+  bool IsResumption() const;
+
+  // Returns true if early data (0-RTT data) was sent and the server accepted
+  // it.
+  bool EarlyDataAccepted() const;
+
+  // Returns true if the handshake was delayed one round trip by the server
+  // because the server wanted proof the client controls its source address
+  // before progressing further. In Google QUIC, this would be due to an
+  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
+  // to a Retry packet.
+  // TODO(nharper): Consider a better name for this method.
+  bool ReceivedInchoateReject() const;
+
+  int GetNumReceivedServerConfigUpdates() const;
+
+  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
+
+  void set_respect_goaway(bool respect_goaway) {
+    respect_goaway_ = respect_goaway;
+  }
+
+ protected:
+  // QuicSession methods:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
+  // If an outgoing stream can be created, return true.
+  bool ShouldCreateOutgoingBidirectionalStream() override;
+  bool ShouldCreateOutgoingUnidirectionalStream() override;
+
+  // If an incoming stream can be created, return true.
+  // TODO(fayang): move this up to QuicSpdyClientSessionBase.
+  bool ShouldCreateIncomingStream(QuicStreamId id) override;
+
+  // Create the crypto stream. Called by Initialize().
+  virtual std::unique_ptr<QuicCryptoClientStreamBase> CreateQuicCryptoStream();
+
+  // Unlike CreateOutgoingBidirectionalStream, which applies a bunch of
+  // sanity checks, this simply returns a new QuicSpdyClientStream. This may be
+  // used by subclasses which want to use a subclass of QuicSpdyClientStream for
+  // streams but wish to use the sanity checks in
+  // CreateOutgoingBidirectionalStream.
+  virtual std::unique_ptr<QuicSpdyClientStream> CreateClientStream();
+
+  const QuicServerId& server_id() const { return server_id_; }
+  QuicCryptoClientConfig* crypto_config() { return crypto_config_; }
+
+ private:
+  std::unique_ptr<QuicCryptoClientStreamBase> crypto_stream_;
+  QuicServerId server_id_;
+  QuicCryptoClientConfig* crypto_config_;
+  // Server addresses that are known to the client.
+  std::vector<QuicSocketAddress> known_server_addresses_;
+
+  // If this is set to false, the client will ignore server GOAWAYs and allow
+  // the creation of streams regardless of the high chance they will fail.
+  bool respect_goaway_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_H_
diff --git a/quiche/quic/core/http/quic_spdy_client_session_base.cc b/quiche/quic/core/http/quic_spdy_client_session_base.cc
new file mode 100644
index 0000000..559764c
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session_base.cc
@@ -0,0 +1,279 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_client_session_base.h"
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicSpdyClientSessionBase::QuicSpdyClientSessionBase(
+    QuicConnection* connection,
+    QuicClientPushPromiseIndex* push_promise_index,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions)
+    : QuicSpdySession(connection, nullptr, config, supported_versions),
+      push_promise_index_(push_promise_index),
+      largest_promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())) {}
+
+QuicSpdyClientSessionBase::~QuicSpdyClientSessionBase() {
+  //  all promised streams for this session
+  for (auto& it : promised_by_id_) {
+    QUIC_DVLOG(1) << "erase stream " << it.first << " url " << it.second->url();
+    push_promise_index_->promised_by_url()->erase(it.second->url());
+  }
+  DeleteConnection();
+}
+
+void QuicSpdyClientSessionBase::OnConfigNegotiated() {
+  QuicSpdySession::OnConfigNegotiated();
+}
+
+void QuicSpdyClientSessionBase::OnInitialHeadersComplete(
+    QuicStreamId stream_id,
+    const SpdyHeaderBlock& response_headers) {
+  // Note that the strong ordering of the headers stream means that
+  // QuicSpdyClientStream::OnPromiseHeadersComplete must have already
+  // been called (on the associated stream) if this is a promised
+  // stream. However, this stream may not have existed at this time,
+  // hence the need to query the session.
+  QuicClientPromisedInfo* promised = GetPromisedById(stream_id);
+  if (!promised)
+    return;
+
+  promised->OnResponseHeaders(response_headers);
+}
+
+void QuicSpdyClientSessionBase::OnPromiseHeaderList(
+    QuicStreamId stream_id,
+    QuicStreamId promised_stream_id,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  if (IsStaticStream(stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  // In HTTP3, push promises are received on individual streams, so they could
+  // be arrive out of order.
+  if (!VersionUsesHttp3(transport_version()) &&
+      promised_stream_id !=
+          QuicUtils::GetInvalidStreamId(transport_version()) &&
+      largest_promised_stream_id_ !=
+          QuicUtils::GetInvalidStreamId(transport_version()) &&
+      promised_stream_id <= largest_promised_stream_id_) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Received push stream id lesser or equal to the"
+        " last accepted before",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (!IsIncomingStream(promised_stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received push stream id for outgoing stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    // Received push stream id is higher than MAX_PUSH_ID
+    // because no MAX_PUSH_ID frame is ever sent.
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "Received push stream id higher than MAX_PUSH_ID.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  largest_promised_stream_id_ = promised_stream_id;
+
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
+}
+
+bool QuicSpdyClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
+                                               QuicStreamId promised_id,
+                                               const SpdyHeaderBlock& headers) {
+  // TODO(b/136295430): Do not treat |promised_id| as a stream ID when using
+  // IETF QUIC.
+  // Due to pathalogical packet re-ordering, it is possible that
+  // frames for the promised stream have already arrived, and the
+  // promised stream could be active or closed.
+  if (IsClosedStream(promised_id)) {
+    // There was a RST on the data stream already, perhaps
+    // QUIC_REFUSED_STREAM?
+    QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id
+                  << " that is already closed";
+    return false;
+  }
+
+  if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
+    QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream "
+                  << promised_id;
+    ResetPromised(promised_id, QUIC_REFUSED_STREAM);
+    return false;
+  }
+
+  const std::string url =
+      SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers);
+  QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
+  if (old_promised) {
+    QUIC_DVLOG(1) << "Promise for stream " << promised_id
+                  << " is duplicate URL " << url
+                  << " of previous promise for stream " << old_promised->id();
+    ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL);
+    return false;
+  }
+
+  if (GetPromisedById(promised_id)) {
+    // OnPromiseHeadersComplete() would have closed the connection if
+    // promised id is a duplicate.
+    QUIC_BUG(quic_bug_10412_1) << "Duplicate promise for id " << promised_id;
+    return false;
+  }
+
+  QuicClientPromisedInfo* promised =
+      new QuicClientPromisedInfo(this, promised_id, url);
+  std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
+  promised->Init();
+  QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url;
+  (*push_promise_index_->promised_by_url())[url] = promised;
+  promised_by_id_[promised_id] = std::move(promised_owner);
+  bool result = promised->OnPromiseHeaders(headers);
+  if (result) {
+    QUICHE_DCHECK(promised_by_id_.find(promised_id) != promised_by_id_.end());
+  }
+  return result;
+}
+
+QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedByUrl(
+    const std::string& url) {
+  auto it = push_promise_index_->promised_by_url()->find(url);
+  if (it != push_promise_index_->promised_by_url()->end()) {
+    return it->second;
+  }
+  return nullptr;
+}
+
+QuicClientPromisedInfo* QuicSpdyClientSessionBase::GetPromisedById(
+    const QuicStreamId id) {
+  auto it = promised_by_id_.find(id);
+  if (it != promised_by_id_.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+QuicSpdyStream* QuicSpdyClientSessionBase::GetPromisedStream(
+    const QuicStreamId id) {
+  QuicStream* stream = GetActiveStream(id);
+  if (stream != nullptr) {
+    return static_cast<QuicSpdyStream*>(stream);
+  }
+  return nullptr;
+}
+
+void QuicSpdyClientSessionBase::DeletePromised(
+    QuicClientPromisedInfo* promised) {
+  push_promise_index_->promised_by_url()->erase(promised->url());
+  // Since promised_by_id_ contains the unique_ptr, this will destroy
+  // promised.
+  // ToDo: Consider implementing logic to send a new MAX_PUSH_ID frame to allow
+  // another stream to be promised.
+  promised_by_id_.erase(promised->id());
+  if (!VersionUsesHttp3(transport_version())) {
+    headers_stream()->MaybeReleaseSequencerBuffer();
+  }
+}
+
+void QuicSpdyClientSessionBase::OnPushStreamTimedOut(
+    QuicStreamId /*stream_id*/) {}
+
+void QuicSpdyClientSessionBase::ResetPromised(
+    QuicStreamId id,
+    QuicRstStreamErrorCode error_code) {
+  QUICHE_DCHECK(QuicUtils::IsServerInitiatedStreamId(transport_version(), id));
+  ResetStream(id, error_code);
+  if (!IsOpenStream(id) && !IsClosedStream(id)) {
+    MaybeIncreaseLargestPeerStreamId(id);
+  }
+}
+
+void QuicSpdyClientSessionBase::OnStreamClosed(QuicStreamId stream_id) {
+  QuicSpdySession::OnStreamClosed(stream_id);
+  if (!VersionUsesHttp3(transport_version())) {
+    headers_stream()->MaybeReleaseSequencerBuffer();
+  }
+}
+
+bool QuicSpdyClientSessionBase::ShouldReleaseHeadersStreamSequencerBuffer() {
+  return !HasActiveRequestStreams() && promised_by_id_.empty();
+}
+
+bool QuicSpdyClientSessionBase::ShouldKeepConnectionAlive() const {
+  return QuicSpdySession::ShouldKeepConnectionAlive() ||
+         num_outgoing_draining_streams() > 0;
+}
+
+bool QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
+  if (!was_zero_rtt_rejected()) {
+    if (max_outbound_header_list_size() != std::numeric_limits<size_t>::max() &&
+        frame.values.find(SETTINGS_MAX_FIELD_SECTION_SIZE) ==
+            frame.values.end()) {
+      CloseConnectionWithDetails(
+          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+          "Server accepted 0-RTT but omitted non-default "
+          "SETTINGS_MAX_FIELD_SECTION_SIZE");
+      return false;
+    }
+
+    if (qpack_encoder()->maximum_blocked_streams() != 0 &&
+        frame.values.find(SETTINGS_QPACK_BLOCKED_STREAMS) ==
+            frame.values.end()) {
+      CloseConnectionWithDetails(
+          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+          "Server accepted 0-RTT but omitted non-default "
+          "SETTINGS_QPACK_BLOCKED_STREAMS");
+      return false;
+    }
+
+    if (qpack_encoder()->MaximumDynamicTableCapacity() != 0 &&
+        frame.values.find(SETTINGS_QPACK_MAX_TABLE_CAPACITY) ==
+            frame.values.end()) {
+      CloseConnectionWithDetails(
+          QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+          "Server accepted 0-RTT but omitted non-default "
+          "SETTINGS_QPACK_MAX_TABLE_CAPACITY");
+      return false;
+    }
+  }
+
+  if (!QuicSpdySession::OnSettingsFrame(frame)) {
+    return false;
+  }
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount frame_length =
+      HttpEncoder::SerializeSettingsFrame(frame, &buffer);
+  auto serialized_data = std::make_unique<ApplicationState>(
+      buffer.get(), buffer.get() + frame_length);
+  GetMutableCryptoStream()->SetServerApplicationStateForResumption(
+      std::move(serialized_data));
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_session_base.h b/quiche/quic/core/http/quic_spdy_client_session_base.h
new file mode 100644
index 0000000..426d28d
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session_base.h
@@ -0,0 +1,146 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
+
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicClientPromisedInfo;
+class QuicClientPushPromiseIndex;
+class QuicSpdyClientStream;
+
+// For client/http layer code. Lookup promised streams based on
+// matching promised request url. The same map can be shared across
+// multiple sessions, since cross-origin pushes are allowed (subject
+// to authority constraints).  Clients should use this map to enforce
+// session affinity for requests corresponding to cross-origin push
+// promised streams.
+using QuicPromisedByUrlMap =
+    absl::flat_hash_map<std::string, QuicClientPromisedInfo*>;
+
+// The maximum time a promises stream can be reserved without being
+// claimed by a client request.
+const int64_t kPushPromiseTimeoutSecs = 60;
+
+// Base class for all client-specific QuicSession subclasses.
+class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
+    : public QuicSpdySession,
+      public QuicCryptoClientStream::ProofHandler {
+ public:
+  // Takes ownership of |connection|. Caller retains ownership of
+  // |promised_by_url|.
+  QuicSpdyClientSessionBase(QuicConnection* connection,
+                            QuicClientPushPromiseIndex* push_promise_index,
+                            const QuicConfig& config,
+                            const ParsedQuicVersionVector& supported_versions);
+  QuicSpdyClientSessionBase(const QuicSpdyClientSessionBase&) = delete;
+  QuicSpdyClientSessionBase& operator=(const QuicSpdyClientSessionBase&) =
+      delete;
+
+  ~QuicSpdyClientSessionBase() override;
+
+  void OnConfigNegotiated() override;
+
+  // Called by |headers_stream_| when push promise headers have been
+  // completely received.
+  void OnPromiseHeaderList(QuicStreamId stream_id,
+                           QuicStreamId promised_stream_id,
+                           size_t frame_len,
+                           const QuicHeaderList& header_list) override;
+
+  // Called by |QuicSpdyClientStream| on receipt of response headers,
+  // needed to detect promised server push streams, as part of
+  // client-request to push-stream rendezvous.
+  void OnInitialHeadersComplete(QuicStreamId stream_id,
+                                const spdy::SpdyHeaderBlock& response_headers);
+
+  // Called by |QuicSpdyClientStream| on receipt of PUSH_PROMISE, does
+  // some session level validation and creates the
+  // |QuicClientPromisedInfo| inserting into maps by (promised) id and
+  // url. Returns true if a new push promise is accepted. Resets the promised
+  // stream and returns false otherwise.
+  virtual bool HandlePromised(QuicStreamId associated_id,
+                              QuicStreamId promised_id,
+                              const spdy::SpdyHeaderBlock& headers);
+
+  // For cross-origin server push, this should verify the server is
+  // authoritative per [RFC2818], Section 3.  Roughly, subjectAltName
+  // list in the certificate should contain a matching DNS name, or IP
+  // address.  |hostname| is derived from the ":authority" header field of
+  // the PUSH_PROMISE frame, port if present there will be dropped.
+  virtual bool IsAuthorized(const std::string& hostname) = 0;
+
+  // Session retains ownership.
+  QuicClientPromisedInfo* GetPromisedByUrl(const std::string& url);
+  // Session retains ownership.
+  QuicClientPromisedInfo* GetPromisedById(const QuicStreamId id);
+
+  //
+  QuicSpdyStream* GetPromisedStream(const QuicStreamId id);
+
+  // Removes |promised| from the maps by url.
+  void ErasePromisedByUrl(QuicClientPromisedInfo* promised);
+
+  // Removes |promised| from the maps by url and id and destroys
+  // promised.
+  virtual void DeletePromised(QuicClientPromisedInfo* promised);
+
+  virtual void OnPushStreamTimedOut(QuicStreamId stream_id);
+
+  // Sends Rst for the stream, and makes sure that future calls to
+  // IsClosedStream(id) return true, which ensures that any subsequent
+  // frames related to this stream will be ignored (modulo flow
+  // control accounting).
+  void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
+
+  // Release headers stream's sequencer buffer if it's empty.
+  void OnStreamClosed(QuicStreamId stream_id) override;
+
+  // Returns true if there are no active requests and no promised streams.
+  bool ShouldReleaseHeadersStreamSequencerBuffer() override;
+
+  // Override to wait for all received responses to be consumed by application.
+  bool ShouldKeepConnectionAlive() const override;
+
+  size_t get_max_promises() const {
+    return max_open_incoming_unidirectional_streams() *
+           kMaxPromisedStreamsMultiplier;
+  }
+
+  QuicClientPushPromiseIndex* push_promise_index() {
+    return push_promise_index_;
+  }
+
+  // Override to serialize the settings and pass it down to the handshaker.
+  bool OnSettingsFrame(const SettingsFrame& frame) override;
+
+ private:
+  // For QuicSpdyClientStream to detect that a response corresponds to a
+  // promise.
+  using QuicPromisedByIdMap =
+      absl::flat_hash_map<QuicStreamId,
+                          std::unique_ptr<QuicClientPromisedInfo>>;
+
+  // As per rfc7540, section 10.5: track promise streams in "reserved
+  // (remote)".  The primary key is URL from the promise request
+  // headers.  The promised stream id is a secondary key used to get
+  // promise info when the response headers of the promised stream
+  // arrive.
+  QuicClientPushPromiseIndex* push_promise_index_;
+  QuicPromisedByIdMap promised_by_id_;
+  QuicStreamId largest_promised_stream_id_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_SESSION_BASE_H_
diff --git a/quiche/quic/core/http/quic_spdy_client_session_test.cc b/quiche/quic/core/http/quic_spdy_client_session_test.cc
new file mode 100644
index 0000000..346341c
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_session_test.cc
@@ -0,0 +1,1345 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_quic_spdy_client_stream.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+
+using spdy::SpdyHeaderBlock;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::AtMost;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+using ::testing::Truly;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kPort = 443;
+
+class TestQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit TestQuicSpdyClientSession(
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      const QuicServerId& server_id,
+      QuicCryptoClientConfig* crypto_config,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(config,
+                              supported_versions,
+                              connection,
+                              server_id,
+                              crypto_config,
+                              push_promise_index) {}
+
+  std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override {
+    return std::make_unique<MockQuicSpdyClientStream>(
+        GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+  }
+
+  MockQuicSpdyClientStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    MockQuicSpdyClientStream* stream =
+        new MockQuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+};
+
+class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSpdyClientSessionTest()
+      : promised_stream_id_(
+            QuicUtils::GetInvalidStreamId(GetParam().transport_version)),
+        associated_stream_id_(
+            QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
+    auto client_cache = std::make_unique<test::SimpleSessionCache>();
+    client_session_cache_ = client_cache.get();
+    client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+        crypto_test_utils::ProofVerifierForTesting(), std::move(client_cache));
+    server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
+    Initialize();
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  ~QuicSpdyClientSessionTest() override {
+    // Session must be destroyed before promised_by_url_
+    session_.reset(nullptr);
+  }
+
+  void Initialize() {
+    session_.reset();
+    connection_ = new ::testing::NiceMock<PacketSavingConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_CLIENT,
+        SupportedVersions(GetParam()));
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
+        QuicServerId(kServerHostname, kPort, false),
+        client_crypto_config_.get(), &push_promise_index_);
+    session_->Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+        session_->GetMutableCryptoStream());
+    push_promise_[":path"] = "/bar";
+    push_promise_[":authority"] = "www.google.com";
+    push_promise_[":method"] = "GET";
+    push_promise_[":scheme"] = "https";
+    promise_url_ =
+        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_);
+    promised_stream_id_ = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 0);
+    associated_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), 0);
+  }
+
+  // The function ensures that A) the MAX_STREAMS frames get properly deleted
+  // (since the test uses a 'did we leak memory' check ... if we just lose the
+  // frame, the test fails) and B) returns true (instead of the default, false)
+  // which ensures that the rest of the system thinks that the frame actually
+  // was transmitted.
+  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAMS_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ public:
+  bool ClearStreamsBlockedControlFrame(const QuicFrame& frame) {
+    if (frame.type == STREAMS_BLOCKED_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  void CompleteCryptoHandshake() {
+    CompleteCryptoHandshake(kDefaultMaxStreamsPerConnection);
+  }
+
+  void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
+    if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(::testing::AnyNumber())
+          .WillRepeatedly(Invoke(
+              this, &QuicSpdyClientSessionTest::ClearMaxStreamsControlFrame));
+    }
+    session_->CryptoConnect();
+    QuicConfig config = DefaultQuicConfig();
+    if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+      config.SetMaxUnidirectionalStreamsToSend(server_max_incoming_streams);
+      config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
+    } else {
+      config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
+    }
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+        connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+  }
+
+  void CreateConnection() {
+    connection_ = new ::testing::NiceMock<PacketSavingConnection>(
+        &helper_, &alarm_factory_, Perspective::IS_CLIENT,
+        SupportedVersions(GetParam()));
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
+        QuicServerId(kServerHostname, kPort, false),
+        client_crypto_config_.get(), &push_promise_index_);
+    session_->Initialize();
+    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+        session_->GetMutableCryptoStream());
+  }
+
+  void CompleteFirstConnection() {
+    CompleteCryptoHandshake();
+    EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
+    if (session_->version().UsesHttp3()) {
+      SettingsFrame settings;
+      settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+      settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+      settings.values[256] = 4;  // unknown setting
+      session_->OnSettingsFrame(settings);
+    }
+  }
+
+  // Owned by |session_|.
+  QuicCryptoClientStream* crypto_stream_;
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  ::testing::NiceMock<PacketSavingConnection>* connection_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicClientPushPromiseIndex push_promise_index_;
+  SpdyHeaderBlock push_promise_;
+  std::string promise_url_;
+  QuicStreamId promised_stream_id_;
+  QuicStreamId associated_stream_id_;
+  test::SimpleSessionCache* client_session_cache_;
+};
+
+std::string ParamNameFormatter(
+    const testing::TestParamInfo<QuicSpdyClientSessionTest::ParamType>& info) {
+  return ParsedQuicVersionToString(info.param);
+}
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdyClientSessionTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ParamNameFormatter);
+
+TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
+  CompleteCryptoHandshake();
+}
+
+TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test relies on resumption and is QUIC crypto specific, so it is
+    // disabled for TLS.
+    return;
+  }
+  // Complete a handshake in order to prime the crypto config for 0-RTT.
+  CompleteCryptoHandshake();
+
+  // Now create a second session using the same crypto config.
+  Initialize();
+
+  // Starting the handshake should move immediately to encryption
+  // established and will allow streams to be created.
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_FALSE(QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+                                           stream->id()));
+
+  // Process an "inchoate" REJ from the server which will cause
+  // an inchoate CHLO to be sent and will leave the encryption level
+  // at NONE.
+  CryptoHandshakeMessage rej;
+  crypto_test_utils::FillInDummyReject(&rej);
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  crypto_test_utils::SendHandshakeMessageToStream(
+      session_->GetMutableCryptoStream(), rej, Perspective::IS_CLIENT);
+  EXPECT_FALSE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_INITIAL,
+            QuicPacketCreatorPeer::GetEncryptionLevel(
+                QuicConnectionPeer::GetPacketCreator(connection_)));
+  // Verify that no new streams may be created.
+  EXPECT_TRUE(session_->CreateOutgoingBidirectionalStream() == nullptr);
+  // Verify that no data may be send on existing streams.
+  char data[] = "hello world";
+  QuicConsumedData consumed =
+      session_->WritevData(stream->id(), ABSL_ARRAYSIZE(data), 0, NO_FIN,
+                           NOT_RETRANSMISSION, ENCRYPTION_INITIAL);
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+}
+
+TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
+  uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  EXPECT_FALSE(session_->CreateOutgoingBidirectionalStream());
+
+  // Close the stream, but without having received a FIN or a RST_STREAM
+  // or MAX_STREAMS (IETF QUIC) and check that a new one can not be created.
+  session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_FALSE(stream);
+}
+
+TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
+  uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+
+  // Close the stream and receive an RST frame to remove the unfinished stream
+  session_->ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
+  session_->OnRstStream(QuicRstStreamFrame(kInvalidControlFrameId, stream->id(),
+                                           QUIC_RST_ACKNOWLEDGEMENT, 0));
+  // Check that a new one can be created.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // In IETF QUIC the stream limit increases only if we get a MAX_STREAMS
+    // frame; pretend we got one.
+
+    QuicMaxStreamsFrame frame(0, 2,
+                              /*unidirectional=*/false);
+    session_->OnMaxStreamsFrame(frame);
+  }
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_NE(nullptr, stream);
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // Ensure that we have 2 total streams, 1 open and 1 closed.
+    QuicStreamCount expected_stream_count = 2;
+    EXPECT_EQ(expected_stream_count,
+              QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
+                  ->outgoing_stream_count());
+  }
+}
+
+TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
+  // Tests the situation in which the client sends a RST at the same time that
+  // the server sends trailing headers (trailers). Receipt of the trailers by
+  // the client should result in all outstanding stream state being tidied up
+  // (including flow control, and number of available outgoing streams).
+  uint32_t kServerMaxIncomingStreams = 1;
+  CompleteCryptoHandshake(kServerMaxIncomingStreams);
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // For IETF QUIC, trying to open a stream and failing due to lack
+    // of stream ids will result in a STREAMS_BLOCKED. Make
+    // sure we get one. Also clear out the frame because if it's
+    // left sitting, the later SendRstStream will not actually
+    // transmit the RST_STREAM because the connection will be in write-blocked
+    // state. This means that the SendControlFrame that is expected w.r.t. the
+    // RST_STREAM, below, will not be satisfied.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(
+            this, &QuicSpdyClientSessionTest::ClearStreamsBlockedControlFrame));
+  }
+
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+
+  QuicStreamId stream_id = stream->id();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
+
+  // A new stream cannot be created as the reset stream still counts as an open
+  // outgoing stream until closed by the server.
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(nullptr, stream);
+
+  // The stream receives trailers with final byte offset: this is one of three
+  // ways that a peer can signal the end of a stream (the others being RST,
+  // stream data + FIN).
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
+
+  // The stream is now complete from the client's perspective, and it should
+  // be able to create a new outgoing stream.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    QuicMaxStreamsFrame frame(0, 2,
+                              /*unidirectional=*/false);
+
+    session_->OnMaxStreamsFrame(frame);
+  }
+  stream = session_->CreateOutgoingBidirectionalStream();
+  EXPECT_NE(nullptr, stream);
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // Ensure that we have 2 open streams.
+    QuicStreamCount expected_stream_count = 2;
+    EXPECT_EQ(expected_stream_count,
+              QuicSessionPeer::ietf_bidirectional_stream_id_manager(&*session_)
+                  ->outgoing_stream_count());
+  }
+}
+
+TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
+  // Tests the situation where the client has sent a RST to the server, and has
+  // received trailing headers with a malformed final byte offset value.
+  CompleteCryptoHandshake();
+
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_NE(nullptr, stream);
+
+  // Send the RST, which results in the stream being closed locally (but some
+  // state remains while the client waits for a response from the server).
+  QuicStreamId stream_id = stream->id();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY);
+
+  // The stream receives trailers with final byte offset, but the header value
+  // is non-numeric and should be treated as malformed.
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "invalid non-numeric value");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->OnStreamHeaderList(stream_id, /*fin=*/false, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnStreamHeaderListWithStaticStream) {
+  // Test situation where OnStreamHeaderList is called by stream with static id.
+  CompleteCryptoHandshake();
+
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  // Initialize H/3 control stream.
+  QuicStreamId id;
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    id = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 3);
+    char type[] = {0x00};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_->OnStreamFrame(data1);
+  } else {
+    id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
+  }
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "stream is static", _))
+      .Times(1);
+  session_->OnStreamHeaderList(id,
+                               /*fin=*/false, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) {
+  // Test situation where OnPromiseHeaderList is called by stream with static
+  // id.
+  CompleteCryptoHandshake();
+
+  QuicHeaderList trailers;
+  trailers.OnHeaderBlockStart();
+  trailers.OnHeader(kFinalOffsetHeaderKey, "0");
+  trailers.OnHeaderBlockEnd(0, 0);
+
+  // Initialize H/3 control stream.
+  QuicStreamId id;
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    id = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), 3);
+    char type[] = {0x00};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_->OnStreamFrame(data1);
+  } else {
+    id = QuicUtils::GetHeadersStreamId(connection_->transport_version());
+  }
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                            "stream is static", _))
+      .Times(1);
+  session_->OnPromiseHeaderList(id, promised_stream_id_, 0, trailers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, GoAwayReceived) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+  CompleteCryptoHandshake();
+
+  // After receiving a GoAway, I should no longer be able to create outgoing
+  // streams.
+  session_->connection()->OnGoAwayFrame(QuicGoAwayFrame(
+      kInvalidControlFrameId, QUIC_PEER_GOING_AWAY, 1u, "Going away."));
+  EXPECT_EQ(nullptr, session_->CreateOutgoingBidirectionalStream());
+}
+
+static bool CheckForDecryptionError(QuicFramer* framer) {
+  return framer->error() == QUIC_DECRYPTION_FAILURE;
+}
+
+// Various sorts of invalid packets that should not cause a connection
+// to be closed.
+TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
+  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
+  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
+
+  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
+      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
+                             &MockQuicConnection::ReallyProcessUdpPacket));
+  EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
+  EXPECT_CALL(*connection_, OnError(_)).Times(1);
+
+  // Verify that empty packets don't close the connection.
+  QuicReceivedPacket zero_length_packet(nullptr, 0, QuicTime::Zero(), false);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_->ProcessUdpPacket(client_address, server_address,
+                             zero_length_packet);
+
+  // Verifiy that small, invalid packets don't close the connection.
+  char buf[2] = {0x00, 0x01};
+  QuicConnectionId connection_id = session_->connection()->connection_id();
+  QuicReceivedPacket valid_packet(buf, 2, QuicTime::Zero(), false);
+  // Close connection shouldn't be called.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, OnError(_)).Times(AtMost(1));
+  session_->ProcessUdpPacket(client_address, server_address, valid_packet);
+
+  // Verify that a non-decryptable packet doesn't close the connection.
+  QuicFramerPeer::SetLastSerializedServerConnectionId(
+      QuicConnectionPeer::GetFramer(connection_), connection_id);
+  ParsedQuicVersionVector versions = SupportedVersions(GetParam());
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId source_connection_id = connection_id;
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      destination_connection_id, source_connection_id, false, false, 100,
+      "data", true, CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT,
+      PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  // Change the last byte of the encrypted data.
+  *(const_cast<char*>(received->data() + received->length() - 1)) += 1;
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
+  session_->ProcessUdpPacket(client_address, server_address, *received);
+}
+
+// A packet with invalid framing should cause a connection to be closed.
+TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
+  const ParsedQuicVersion version = GetParam();
+  QuicSocketAddress server_address(TestPeerIPAddress(), kTestPort);
+  QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
+  if (version.KnowsWhichDecrypterToUse()) {
+    connection_->InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+  } else {
+    connection_->SetDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+  }
+
+  EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
+      .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
+                             &MockQuicConnection::ReallyProcessUdpPacket));
+  EXPECT_CALL(*connection_, OnError(_)).Times(1);
+
+  // Verify that a decryptable packet with bad frames does close the connection.
+  QuicConnectionId destination_connection_id =
+      session_->connection()->connection_id();
+  QuicConnectionId source_connection_id = EmptyQuicConnectionId();
+  QuicFramerPeer::SetLastSerializedServerConnectionId(
+      QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
+  bool version_flag = false;
+  QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
+  if (version.HasIetfInvariantHeader()) {
+    version_flag = true;
+    source_connection_id = destination_connection_id;
+    scid_included = CONNECTION_ID_PRESENT;
+  }
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
+      destination_connection_id, source_connection_id, version_flag, false, 100,
+      "data", CONNECTION_ID_ABSENT, scid_included, PACKET_4BYTE_PACKET_NUMBER,
+      version, Perspective::IS_SERVER));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
+  session_->ProcessUdpPacket(client_address, server_address, *received);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeaders) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  EXPECT_CALL(*stream, OnPromiseHeaderList(_, _, _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseStreamIdTooHigh) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  QuicStreamId stream_id =
+      QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
+  QuicSessionPeer::ActivateStream(
+      session_.get(), std::make_unique<QuicSpdyClientStream>(
+                          stream_id, session_.get(), BIDIRECTIONAL));
+
+  QuicHeaderList headers;
+  headers.OnHeaderBlockStart();
+  headers.OnHeader(":path", "/bar");
+  headers.OnHeader(":authority", "www.google.com");
+  headers.OnHeader(":method", "GET");
+  headers.OnHeader(":scheme", "https");
+  headers.OnHeaderBlockEnd(0, 0);
+
+  const QuicStreamId promise_id = GetNthServerInitiatedUnidirectionalStreamId(
+      connection_->transport_version(), 11);
+  session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOutOfOrder) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  EXPECT_CALL(*stream, OnPromiseHeaderList(promised_stream_id_, _, _));
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+  associated_stream_id_ +=
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  if (!VersionUsesHttp3(session_->transport_version())) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_INVALID_STREAM_ID,
+                                "Received push stream id lesser or equal to the"
+                                " last accepted before",
+                                _));
+  }
+  session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseOutgoingStreamId) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  MockQuicSpdyClientStream* stream = static_cast<MockQuicSpdyClientStream*>(
+      session_->CreateOutgoingBidirectionalStream());
+
+  // Promise an illegal (outgoing) stream id.
+  promised_stream_id_ = GetNthClientInitiatedBidirectionalStreamId(
+      connection_->transport_version(), 0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received push stream id for outgoing stream.", _));
+
+  session_->OnPromiseHeaderList(stream->id(), promised_stream_id_, 0,
+                                QuicHeaderList());
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseHandlePromise) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+  session_->GetOrCreateStream(promised_stream_id_);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  SpdyHeaderBlock promise_headers;
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, promise_headers));
+
+  // Verify that the promise was not created.
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  promised_stream_id_ +=
+      QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
+
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  // Verify that the promise was not created.
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
+  CompleteCryptoHandshake();
+  for (size_t i = 0u; i < session_->get_max_promises(); i++) {
+    push_promise_[":path"] = absl::StrCat("/bar", i);
+
+    QuicStreamId id =
+        promised_stream_id_ +
+        i * QuicUtils::StreamIdDelta(connection_->transport_version());
+
+    EXPECT_TRUE(
+        session_->HandlePromised(associated_stream_id_, id, push_promise_));
+
+    // Verify that the promise is in the unclaimed streams map.
+    std::string promise_url(
+        SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
+    EXPECT_NE(session_->GetPromisedByUrl(promise_url), nullptr);
+    EXPECT_NE(session_->GetPromisedById(id), nullptr);
+  }
+
+  // One more promise, this should be refused.
+  int i = session_->get_max_promises();
+  push_promise_[":path"] = absl::StrCat("/bar", i);
+
+  QuicStreamId id =
+      promised_stream_id_ +
+      i * QuicUtils::StreamIdDelta(connection_->transport_version());
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
+  EXPECT_FALSE(
+      session_->HandlePromised(associated_stream_id_, id, push_promise_));
+
+  // Verify that the promise was not created.
+  std::string promise_url(
+      SpdyServerPushUtils::GetPromisedUrlFromHeaders(push_promise_));
+  EXPECT_EQ(session_->GetPromisedById(id), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
+}
+
+TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
+  session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
+  EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsPush) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  EXPECT_NE(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
+}
+
+TEST_P(QuicSpdyClientSessionTest, OnInitialHeadersCompleteIsNotPush) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->CreateOutgoingBidirectionalStream();
+  session_->OnInitialHeadersComplete(promised_stream_id_, SpdyHeaderBlock());
+}
+
+TEST_P(QuicSpdyClientSessionTest, DeletePromised) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  QuicClientPromisedInfo* promised =
+      session_->GetPromisedById(promised_stream_id_);
+  EXPECT_NE(promised, nullptr);
+  EXPECT_NE(session_->GetPromisedStream(promised_stream_id_), nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+
+  session_->DeletePromised(promised);
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  session_->GetOrCreateStream(promised_stream_id_);
+  EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
+                                       promised_stream_id_, push_promise_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
+  session_->ResetStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY);
+  QuicClientPromisedInfo* promised =
+      session_->GetPromisedById(promised_stream_id_);
+  EXPECT_NE(promised, nullptr);
+  EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
+  EXPECT_EQ(session_->GetPromisedStream(promised_stream_id_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
+
+  push_promise_[":method"] = "POST";
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+
+  session_->CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
+
+  push_promise_[":authority"] = "";
+  EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
+                                        promised_stream_id_, push_promise_));
+
+  EXPECT_EQ(session_->GetPromisedById(promised_stream_id_), nullptr);
+  EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       TryToCreateServerInitiatedBidirectionalStream) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM, _, _));
+  } else {
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  }
+  session_->GetOrCreateStream(GetNthServerInitiatedBidirectionalStreamId(
+      connection_->transport_version(), 0));
+}
+
+TEST_P(QuicSpdyClientSessionTest, TooManyPushPromises) {
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    return;
+  }
+
+  // Initialize crypto before the client session will create a stream.
+  CompleteCryptoHandshake();
+  QuicStreamId stream_id =
+      QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(session_.get());
+  QuicSessionPeer::ActivateStream(
+      session_.get(), std::make_unique<QuicSpdyClientStream>(
+                          stream_id, session_.get(), BIDIRECTIONAL));
+
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM));
+
+  for (size_t promise_count = 0; promise_count <= session_->get_max_promises();
+       promise_count++) {
+    auto promise_id = GetNthServerInitiatedUnidirectionalStreamId(
+        connection_->transport_version(), promise_count);
+    auto headers = QuicHeaderList();
+    headers.OnHeaderBlockStart();
+    headers.OnHeader(":path", absl::StrCat("/", promise_count));
+    headers.OnHeader(":authority", "www.google.com");
+    headers.OnHeader(":method", "GET");
+    headers.OnHeader(":scheme", "https");
+    headers.OnHeaderBlockEnd(0, 0);
+    session_->OnPromiseHeaderList(stream_id, promise_id, 0, headers);
+  }
+}
+
+// Test that upon receiving HTTP/3 SETTINGS, the settings are serialized and
+// stored into client session cache.
+TEST_P(QuicSpdyClientSessionTest, OnSettingsFrame) {
+  // This feature is HTTP/3 only
+  if (!VersionUsesHttp3(session_->transport_version())) {
+    return;
+  }
+  CompleteCryptoHandshake();
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[256] = 4;   // unknown setting
+  char application_state[] = {// type (SETTINGS)
+                              0x04,
+                              // length
+                              0x07,
+                              // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+                              0x01,
+                              // content
+                              0x02,
+                              // identifier (SETTINGS_MAX_FIELD_SECTION_SIZE)
+                              0x06,
+                              // content
+                              0x05,
+                              // identifier (256 in variable length integer)
+                              0x40 + 0x01, 0x00,
+                              // content
+                              0x04};
+  ApplicationState expected(std::begin(application_state),
+                            std::end(application_state));
+  session_->OnSettingsFrame(settings);
+  EXPECT_EQ(expected, *client_session_cache_
+                           ->Lookup(QuicServerId(kServerHostname, kPort, false),
+                                    session_->GetClock()->WallNow(), nullptr)
+                           ->application_state);
+}
+
+TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  // Session configs should be in initial state.
+  if (session_->version().UsesHttp3()) {
+    EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
+    EXPECT_EQ(std::numeric_limits<size_t>::max(),
+              session_->max_outbound_header_list_size());
+  } else {
+    EXPECT_EQ(kMinimumFlowControlSendWindow,
+              session_->flow_controller()->send_window_offset());
+  }
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+
+  // The client session should have a basic setup ready before the handshake
+  // succeeds.
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            session_->flow_controller()->send_window_offset());
+  if (session_->version().UsesHttp3()) {
+    auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+              id_manager->max_outgoing_bidirectional_streams());
+    EXPECT_EQ(
+        kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
+        id_manager->max_outgoing_unidirectional_streams());
+    auto* control_stream =
+        QuicSpdySessionPeer::GetSendControlStream(session_.get());
+    EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
+              QuicStreamPeer::SendWindowOffset(control_stream));
+    EXPECT_EQ(5u, session_->max_outbound_header_list_size());
+  } else {
+    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+              id_manager->max_open_outgoing_streams());
+  }
+
+  // Complete the handshake with a different config.
+  QuicConfig config = DefaultQuicConfig();
+  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
+      kInitialStreamFlowControlWindowForTest + 1);
+  config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest + 1);
+  config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
+  config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+
+  EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1,
+            session_->flow_controller()->send_window_offset());
+  if (session_->version().UsesHttp3()) {
+    auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
+    auto* control_stream =
+        QuicSpdySessionPeer::GetSendControlStream(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+              id_manager->max_outgoing_bidirectional_streams());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection +
+                  kHttp3StaticUnidirectionalStreamCount + 1,
+              id_manager->max_outgoing_unidirectional_streams());
+    EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
+              QuicStreamPeer::SendWindowOffset(control_stream));
+  } else {
+    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+              id_manager->max_open_outgoing_streams());
+  }
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  // Let the session receive a new SETTINGS frame to complete the second
+  // connection.
+  if (session_->version().UsesHttp3()) {
+    SettingsFrame settings;
+    settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+    settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+    settings.values[256] = 4;  // unknown setting
+    session_->OnSettingsFrame(settings);
+  }
+}
+
+// Regression test for b/159168475
+TEST_P(QuicSpdyClientSessionTest, RetransmitDataOnZeroRttReject) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  ON_CALL(*connection_, OnCanWrite())
+      .WillByDefault(
+          testing::Invoke(connection_, &MockQuicConnection::ReallyOnCanWrite));
+  EXPECT_CALL(*connection_, OnCanWrite()).Times(0);
+
+  QuicConfig config = DefaultQuicConfig();
+  config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+
+  // Packets will be written: CHLO, HTTP/3 SETTINGS (H/3 only), and request
+  // data.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION))
+      .Times(session_->version().UsesHttp3() ? 2 : 1);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  stream->WriteOrBufferData("hello", true, nullptr);
+
+  // When handshake is done, the client sends 2 packet: HANDSHAKE FINISHED, and
+  // coalesced retransmission of HTTP/3 SETTINGS and request data.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+  // TODO(b/158027651): change transmission type to ALL_ZERO_RTT_RETRANSMISSION.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+  EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+}
+
+// When IETF QUIC 0-RTT is rejected, a server-sent fresh transport params is
+// available. If the new transport params reduces stream/flow control limit to
+// lower than what the client has already used, connection will be closed.
+TEST_P(QuicSpdyClientSessionTest, ZeroRttRejectReducesStreamLimitTooMuch) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  QuicConfig config = DefaultQuicConfig();
+  // Server doesn't allow any bidirectional streams.
+  config.SetMaxBidirectionalStreamsToSend(0);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+
+  if (session_->version().UsesHttp3()) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(
+            QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+            "Server rejected 0-RTT, aborting because new bidirectional initial "
+            "stream limit 0 is less than current open streams: 1",
+            _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+  } else {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INTERNAL_ERROR,
+                        "Server rejected 0-RTT, aborting because new stream "
+                        "limit 0 is less than current open streams: 1",
+                        _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+  }
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       ZeroRttRejectReducesStreamFlowControlTooMuch) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  QuicConfig config = DefaultQuicConfig();
+  // Server doesn't allow any outgoing streams.
+  config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(2);
+  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(1);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  // Let the stream write more than 1 byte of data.
+  stream->WriteOrBufferData("hello", true, nullptr);
+
+  if (session_->version().UsesHttp3()) {
+    // Both control stream and the request stream will report errors.
+    // Open question: should both streams be closed with the same error code?
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection))
+        .RetiresOnSaturation();
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(
+                    QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+                    "Server rejected 0-RTT, aborting because new stream max "
+                    "data 2 for stream 3 is less than currently used: 5",
+                    _))
+        .Times(1)
+        .WillOnce(testing::Invoke(connection_,
+                                  &MockQuicConnection::ReallyCloseConnection));
+  }
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+       ZeroRttRejectReducesSessionFlowControlTooMuch) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  // Create a second connection, but disable 0-RTT on the server.
+  CreateConnection();
+  QuicConfig config = DefaultQuicConfig();
+  // Server doesn't allow minimum data in session.
+  config.SetInitialSessionFlowControlWindowToSend(
+      kMinimumFlowControlSendWindow);
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+  ASSERT_TRUE(stream);
+  std::string data_to_send(kMinimumFlowControlSendWindow + 1, 'x');
+  // Let the stream write some data.
+  stream->WriteOrBufferData(data_to_send, true, nullptr);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttResumption) {
+  if (!session_->version().UsesHttp3()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  CompleteCryptoHandshake();
+  EXPECT_TRUE(session_->GetCryptoStream()->EarlyDataAccepted());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Let the session receive a different SETTINGS frame.
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[256] = 4;  // unknown setting
+  session_->OnSettingsFrame(settings);
+}
+
+TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttRejection) {
+  if (!session_->version().UsesHttp3()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  session_->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+  QuicConfig config = DefaultQuicConfig();
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+      connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+  EXPECT_FALSE(session_->GetCryptoStream()->EarlyDataAccepted());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Let the session receive a different SETTINGS frame.
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+  // setting on SETTINGS_MAX_FIELD_SECTION_SIZE is reduced.
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 4;
+  settings.values[256] = 4;  // unknown setting
+  session_->OnSettingsFrame(settings);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ServerAcceptsZeroRttButOmitSetting) {
+  if (!session_->version().UsesHttp3()) {
+    return;
+  }
+
+  CompleteFirstConnection();
+
+  CreateConnection();
+  CompleteCryptoHandshake();
+  EXPECT_TRUE(session_->GetMutableCryptoStream()->EarlyDataAccepted());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Let the session receive a different SETTINGS frame.
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+  // Intentionally omit SETTINGS_MAX_FIELD_SECTION_SIZE which was previously
+  // sent with a non-zero value.
+  settings.values[256] = 4;  // unknown setting
+  session_->OnSettingsFrame(settings);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_stream.cc b/quiche/quic/core/http/quic_spdy_client_stream.cc
new file mode 100644
index 0000000..e1677fb
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_stream.cc
@@ -0,0 +1,219 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+QuicSpdyClientStream::QuicSpdyClientStream(QuicStreamId id,
+                                           QuicSpdyClientSession* session,
+                                           StreamType type)
+    : QuicSpdyStream(id, session, type),
+      content_length_(-1),
+      response_code_(0),
+      header_bytes_read_(0),
+      header_bytes_written_(0),
+      session_(session),
+      has_preliminary_headers_(false) {}
+
+QuicSpdyClientStream::QuicSpdyClientStream(PendingStream* pending,
+                                           QuicSpdyClientSession* session)
+    : QuicSpdyStream(pending, session),
+      content_length_(-1),
+      response_code_(0),
+      header_bytes_read_(0),
+      header_bytes_written_(0),
+      session_(session),
+      has_preliminary_headers_(false) {}
+
+QuicSpdyClientStream::~QuicSpdyClientStream() = default;
+
+void QuicSpdyClientStream::OnInitialHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
+
+  QUICHE_DCHECK(headers_decompressed());
+  header_bytes_read_ += frame_len;
+  if (rst_sent()) {
+    // QuicSpdyStream::OnInitialHeadersComplete already rejected invalid
+    // response header.
+    return;
+  }
+
+  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
+                                         &response_headers_)) {
+    QUIC_DLOG(ERROR) << "Failed to parse header list: "
+                     << header_list.DebugString() << " on stream " << id();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (web_transport() != nullptr) {
+    web_transport()->HeadersReceived(response_headers_);
+    if (!web_transport()->ready()) {
+      // The request was rejected by WebTransport, typically due to not having a
+      // 2xx status.  The reason we're using Reset() here rather than closing
+      // cleanly is that even if the server attempts to send us any form of body
+      // with a 4xx request, we've already set up the capsule parser, and we
+      // don't have any way to process anything from the response body in
+      // question.
+      Reset(QUIC_STREAM_CANCELLED);
+      return;
+    }
+  }
+
+  if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
+    QUIC_DLOG(ERROR) << "Received invalid response code: "
+                     << response_headers_[":status"].as_string()
+                     << " on stream " << id();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (response_code_ == 101) {
+    // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
+    // "HTTP Upgrade" section of draft-ietf-quic-http.
+    QUIC_DLOG(ERROR) << "Received forbidden 101 response code"
+                     << " on stream " << id();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  if (response_code_ >= 100 && response_code_ < 200) {
+    // These are Informational 1xx headers, not the actual response headers.
+    QUIC_DLOG(INFO) << "Received informational response code: "
+                    << response_headers_[":status"].as_string() << " on stream "
+                    << id();
+    set_headers_decompressed(false);
+    if (response_code_ == 100 && !has_preliminary_headers_) {
+      // This is 100 Continue, save it to enable "Expect: 100-continue".
+      has_preliminary_headers_ = true;
+      preliminary_headers_ = std::move(response_headers_);
+    } else {
+      response_headers_.clear();
+    }
+  }
+
+  ConsumeHeaderList();
+  QUIC_DVLOG(1) << "headers complete for stream " << id();
+
+  session_->OnInitialHeadersComplete(id(), response_headers_);
+}
+
+void QuicSpdyClientStream::OnTrailingHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
+  MarkTrailersConsumed();
+}
+
+void QuicSpdyClientStream::OnPromiseHeaderList(
+    QuicStreamId promised_id,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  header_bytes_read_ += frame_len;
+  int64_t content_length = -1;
+  SpdyHeaderBlock promise_headers;
+  if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length,
+                                         &promise_headers)) {
+    QUIC_DLOG(ERROR) << "Failed to parse promise headers: "
+                     << header_list.DebugString();
+    Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+
+  session_->HandlePromised(id(), promised_id, promise_headers);
+  if (visitor() != nullptr) {
+    visitor()->OnPromiseHeadersComplete(promised_id, frame_len);
+  }
+}
+
+void QuicSpdyClientStream::OnBodyAvailable() {
+  // For push streams, visitor will not be set until the rendezvous
+  // between server promise and client request is complete.
+  if (visitor() == nullptr)
+    return;
+
+  while (HasBytesToRead()) {
+    struct iovec iov;
+    if (GetReadableRegions(&iov, 1) == 0) {
+      // No more data to read.
+      break;
+    }
+    QUIC_DVLOG(1) << "Client processed " << iov.iov_len << " bytes for stream "
+                  << id();
+    data_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
+
+    if (content_length_ >= 0 &&
+        data_.size() > static_cast<uint64_t>(content_length_)) {
+      QUIC_DLOG(ERROR) << "Invalid content length (" << content_length_
+                       << ") with data of size " << data_.size();
+      Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+      return;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  if (sequencer()->IsClosed()) {
+    OnFinRead();
+  } else {
+    sequencer()->SetUnblocked();
+  }
+}
+
+size_t QuicSpdyClientStream::SendRequest(SpdyHeaderBlock headers,
+                                         absl::string_view body,
+                                         bool fin) {
+  QuicConnection::ScopedPacketFlusher flusher(session_->connection());
+  bool send_fin_with_headers = fin && body.empty();
+  size_t bytes_sent = body.size();
+  header_bytes_written_ =
+      WriteHeaders(std::move(headers), send_fin_with_headers, nullptr);
+  bytes_sent += header_bytes_written_;
+
+  if (!body.empty()) {
+    WriteOrBufferBody(body, fin);
+  }
+
+  return bytes_sent;
+}
+
+bool QuicSpdyClientStream::AreHeadersValid(
+    const QuicHeaderList& header_list) const {
+  if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+    return true;
+  }
+  if (!QuicSpdyStream::AreHeadersValid(header_list)) {
+    return false;
+  }
+  // Verify the presence of :status header.
+  bool saw_status = false;
+  for (const std::pair<std::string, std::string>& pair : header_list) {
+    if (pair.first == ":status") {
+      saw_status = true;
+    } else if (absl::StrContains(pair.first, ":")) {
+      QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
+      return false;
+    }
+  }
+  return saw_status;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_client_stream.h b/quiche/quic/core/http/quic_spdy_client_stream.h
new file mode 100644
index 0000000..ebda141
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_stream.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
+
+#include <cstddef>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicSpdyClientSession;
+
+// All this does right now is send an SPDY request, and aggregate the
+// SPDY response.
+class QUIC_EXPORT_PRIVATE QuicSpdyClientStream : public QuicSpdyStream {
+ public:
+  QuicSpdyClientStream(QuicStreamId id,
+                       QuicSpdyClientSession* session,
+                       StreamType type);
+  QuicSpdyClientStream(PendingStream* pending,
+                       QuicSpdyClientSession* spdy_session);
+  QuicSpdyClientStream(const QuicSpdyClientStream&) = delete;
+  QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete;
+  ~QuicSpdyClientStream() override;
+
+  // Override the base class to parse and store headers.
+  void OnInitialHeadersComplete(bool fin,
+                                size_t frame_len,
+                                const QuicHeaderList& header_list) override;
+
+  // Override the base class to parse and store trailers.
+  void OnTrailingHeadersComplete(bool fin,
+                                 size_t frame_len,
+                                 const QuicHeaderList& header_list) override;
+
+  // Override the base class to handle creation of the push stream.
+  void OnPromiseHeaderList(QuicStreamId promised_id,
+                           size_t frame_len,
+                           const QuicHeaderList& header_list) override;
+
+  // QuicStream implementation called by the session when there's data for us.
+  void OnBodyAvailable() override;
+
+  // Serializes the headers and body, sends it to the server, and
+  // returns the number of bytes sent.
+  size_t SendRequest(spdy::SpdyHeaderBlock headers,
+                     absl::string_view body,
+                     bool fin);
+
+  // Returns the response data.
+  const std::string& data() { return data_; }
+
+  // Returns whatever headers have been received for this stream.
+  const spdy::SpdyHeaderBlock& response_headers() { return response_headers_; }
+
+  const spdy::SpdyHeaderBlock& preliminary_headers() {
+    return preliminary_headers_;
+  }
+
+  size_t header_bytes_read() const { return header_bytes_read_; }
+
+  size_t header_bytes_written() const { return header_bytes_written_; }
+
+  int response_code() const { return response_code_; }
+
+  // While the server's SetPriority shouldn't be called externally, the creator
+  // of client-side streams should be able to set the priority.
+  using QuicSpdyStream::SetPriority;
+
+ protected:
+  bool AreHeadersValid(const QuicHeaderList& header_list) const override;
+
+ private:
+  // The parsed headers received from the server.
+  spdy::SpdyHeaderBlock response_headers_;
+
+  // The parsed content-length, or -1 if none is specified.
+  int64_t content_length_;
+  int response_code_;
+  std::string data_;
+  size_t header_bytes_read_;
+  size_t header_bytes_written_;
+
+  QuicSpdyClientSession* session_;
+
+  // These preliminary headers are used for the 100 Continue headers
+  // that may arrive before the response headers when the request has
+  // Expect: 100-continue.
+  bool has_preliminary_headers_;
+  spdy::SpdyHeaderBlock preliminary_headers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/quiche/quic/core/http/quic_spdy_client_stream_test.cc b/quiche/quic/core/http/quic_spdy_client_stream_test.cc
new file mode 100644
index 0000000..0470f41
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_client_stream_test.cc
@@ -0,0 +1,324 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+class MockQuicSpdyClientSession : public QuicSpdyClientSession {
+ public:
+  explicit MockQuicSpdyClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicClientPushPromiseIndex* push_promise_index)
+      : QuicSpdyClientSession(DefaultQuicConfig(),
+                              supported_versions,
+                              connection,
+                              QuicServerId("example.com", 443, false),
+                              &crypto_config_,
+                              push_promise_index),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+  MockQuicSpdyClientSession(const MockQuicSpdyClientSession&) = delete;
+  MockQuicSpdyClientSession& operator=(const MockQuicSpdyClientSession&) =
+      delete;
+  ~MockQuicSpdyClientSession() override = default;
+
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+
+  using QuicSession::ActivateStream;
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+};
+
+class QuicSpdyClientStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  class StreamVisitor;
+
+  QuicSpdyClientStreamTest()
+      : connection_(
+            new StrictMock<MockQuicConnection>(&helper_,
+                                               &alarm_factory_,
+                                               Perspective::IS_CLIENT,
+                                               SupportedVersions(GetParam()))),
+        session_(connection_->supported_versions(),
+                 connection_,
+                 &push_promise_index_),
+        body_("hello world") {
+    session_.Initialize();
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    headers_[":status"] = "200";
+    headers_["content-length"] = "11";
+
+    auto stream = std::make_unique<QuicSpdyClientStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL);
+    stream_ = stream.get();
+    session_.ActivateStream(std::move(stream));
+
+    stream_visitor_ = std::make_unique<StreamVisitor>();
+    stream_->set_visitor(stream_visitor_.get());
+  }
+
+  class StreamVisitor : public QuicSpdyClientStream::Visitor {
+    void OnClose(QuicSpdyStream* stream) override {
+      QUIC_DVLOG(1) << "stream " << stream->id();
+    }
+  };
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  MockQuicSpdyClientSession session_;
+  QuicSpdyClientStream* stream_;
+  std::unique_ptr<StreamVisitor> stream_visitor_;
+  SpdyHeaderBlock headers_;
+  std::string body_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSpdyClientStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
+  headers_[":status"] = "200 ok";
+
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, InvalidResponseHeader) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  auto headers = AsHeaderList(std::vector<std::pair<std::string, std::string>>{
+      {":status", "200"}, {":path", "/foo"}});
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, MissingStatusCode) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  auto headers = AsHeaderList(
+      std::vector<std::pair<std::string, std::string>>{{"key", "value"}});
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFraming) {
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest, Test100ContinueBeforeSuccessful) {
+  // First send 100 Continue.
+  headers_[":status"] = "100";
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
+  EXPECT_EQ(0u, stream_->response_headers().size());
+  EXPECT_EQ(100, stream_->response_code());
+  EXPECT_EQ("", stream_->data());
+  // Then send 200 OK.
+  headers_[":status"] = "200";
+  headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  // Make sure the 200 response got parsed correctly.
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+  // Make sure the 100 response is still available.
+  EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestUnknownInformationalBeforeSuccessful) {
+  // First send 199, an unknown Informational (1XX).
+  headers_[":status"] = "199";
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_EQ(0u, stream_->response_headers().size());
+  EXPECT_EQ(199, stream_->response_code());
+  EXPECT_EQ("", stream_->data());
+  // Then send 200 OK.
+  headers_[":status"] = "200";
+  headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  // Make sure the 200 response got parsed correctly.
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestReceiving101) {
+  // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
+  // "HTTP Upgrade" section of draft-ietf-quic-http.
+  headers_[":status"] = "101";
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  EXPECT_THAT(stream_->stream_error(),
+              IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  EXPECT_EQ(body_, stream_->data());
+}
+
+TEST_P(QuicSpdyClientStreamTest,
+       QUIC_TEST_DISABLED_IN_CHROME(TestFramingExtraData)) {
+  std::string large_body = "hello world!!!!!!";
+
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  // The headers should parse successfully.
+  EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
+  EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+  EXPECT_EQ(200, stream_->response_code());
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      large_body.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), large_body)
+                         : large_body;
+  EXPECT_CALL(session_, WriteControlFrame(_, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+
+  EXPECT_NE(QUIC_STREAM_NO_ERROR, stream_->stream_error());
+}
+
+// Test that receiving trailing headers (on the headers stream), containing a
+// final offset, results in the stream being closed at that byte offset.
+TEST_P(QuicSpdyClientStreamTest, ReceivingTrailers) {
+  // There is no kFinalOffsetHeaderKey if trailers are sent on the
+  // request/response stream.
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    return;
+  }
+
+  // Send headers as usual.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+
+  // Send trailers before sending the body. Even though a FIN has been received
+  // the stream should not be closed, as it does not yet have all the data bytes
+  // promised by the final offset field.
+  SpdyHeaderBlock trailer_block;
+  trailer_block["trailer key"] = "trailer value";
+  trailer_block[kFinalOffsetHeaderKey] = absl::StrCat(body_.size());
+  auto trailers = AsHeaderList(trailer_block);
+  stream_->OnStreamHeaderList(true, trailers.uncompressed_header_bytes(),
+                              trailers);
+
+  // Now send the body, which should close the stream as the FIN has been
+  // received, as well as all data.
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data = VersionUsesHttp3(connection_->transport_version())
+                         ? absl::StrCat(header.AsStringView(), body_)
+                         : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_TRUE(stream_->reading_stopped());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_server_stream_base.cc b/quiche/quic/core/http/quic_spdy_server_stream_base.cc
new file mode 100644
index 0000000..9852302
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_server_stream_base.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_server_stream_base.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(QuicStreamId id,
+                                                   QuicSpdySession* session,
+                                                   StreamType type)
+    : QuicSpdyStream(id, session, type) {}
+
+QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(PendingStream* pending,
+                                                   QuicSpdySession* session)
+    : QuicSpdyStream(pending, session) {}
+
+void QuicSpdyServerStreamBase::CloseWriteSide() {
+  if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
+      !rst_sent()) {
+    // Early cancel the stream if it has stopped reading before receiving FIN
+    // or RST.
+    QUICHE_DCHECK(fin_sent() || !session()->connection()->connected());
+    // Tell the peer to stop sending further data.
+    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
+    MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
+  }
+
+  QuicSpdyStream::CloseWriteSide();
+}
+
+void QuicSpdyServerStreamBase::StopReading() {
+  if (!fin_received() && !rst_received() && write_side_closed() &&
+      !rst_sent()) {
+    QUICHE_DCHECK(fin_sent());
+    // Tell the peer to stop sending further data.
+    QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id();
+    MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
+  }
+  QuicSpdyStream::StopReading();
+}
+
+bool QuicSpdyServerStreamBase::AreHeadersValid(
+    const QuicHeaderList& header_list) const {
+  if (!GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+    return true;
+  }
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 2, 3);
+  if (!QuicSpdyStream::AreHeadersValid(header_list)) {
+    return false;
+  }
+
+  bool saw_connect = false;
+  bool saw_protocol = false;
+  bool saw_path = false;
+  bool saw_scheme = false;
+  bool saw_method = false;
+  bool saw_authority = false;
+  bool is_extended_connect = false;
+  // Check if it is missing any required headers and if there is any disallowed
+  // ones.
+  for (const std::pair<std::string, std::string>& pair : header_list) {
+    if (pair.first == ":method") {
+      saw_method = true;
+      if (pair.second == "CONNECT") {
+        saw_connect = true;
+        if (saw_protocol) {
+          is_extended_connect = true;
+        }
+      }
+    } else if (pair.first == ":protocol") {
+      saw_protocol = true;
+      if (saw_connect) {
+        is_extended_connect = true;
+      }
+    } else if (pair.first == ":scheme") {
+      saw_scheme = true;
+    } else if (pair.first == ":path") {
+      saw_path = true;
+    } else if (pair.first == ":authority") {
+      saw_authority = true;
+    } else if (absl::StrContains(pair.first, ":")) {
+      QUIC_DLOG(ERROR) << "Unexpected ':' in header " << pair.first << ".";
+      return false;
+    }
+    if (is_extended_connect) {
+      if (!spdy_session()->allow_extended_connect()) {
+        QUIC_DLOG(ERROR)
+            << "Received extended-CONNECT request while it is disabled.";
+        return false;
+      }
+    } else if (saw_method && !saw_connect) {
+      if (saw_protocol) {
+        QUIC_DLOG(ERROR) << "Receive non-CONNECT request with :protocol.";
+        return false;
+      }
+    }
+  }
+
+  if (is_extended_connect) {
+    if (saw_scheme && saw_path && saw_authority) {
+      // Saw all the required pseudo headers.
+      return true;
+    }
+    QUIC_DLOG(ERROR) << "Missing required pseudo headers for extended-CONNECT.";
+    return false;
+  }
+  // This is a vanilla CONNECT or non-CONNECT request.
+  if (saw_connect) {
+    // Check vanilla CONNECT.
+    if (saw_path || saw_scheme) {
+      QUIC_DLOG(ERROR)
+          << "Received invalid CONNECT request with disallowed pseudo header.";
+      return false;
+    }
+    return true;
+  }
+  // Check non-CONNECT request.
+  if (saw_method && saw_authority && saw_path && saw_scheme) {
+    return true;
+  }
+  QUIC_LOG(ERROR) << "Missing required pseudo headers.";
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_server_stream_base.h b/quiche/quic/core/http/quic_spdy_server_stream_base.h
new file mode 100644
index 0000000..22fb65d
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_server_stream_base.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+
+namespace quic {
+
+class QUIC_NO_EXPORT QuicSpdyServerStreamBase : public QuicSpdyStream {
+ public:
+  QuicSpdyServerStreamBase(QuicStreamId id,
+                           QuicSpdySession* session,
+                           StreamType type);
+  QuicSpdyServerStreamBase(PendingStream* pending, QuicSpdySession* session);
+  QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete;
+  QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete;
+
+  // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
+  // when the stream has not received all the data.
+  void CloseWriteSide() override;
+  void StopReading() override;
+
+ protected:
+  bool AreHeadersValid(const QuicHeaderList& header_list) const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SERVER_STREAM_BASE_H_
diff --git a/quiche/quic/core/http/quic_spdy_server_stream_base_test.cc b/quiche/quic/core/http/quic_spdy_server_stream_base_test.cc
new file mode 100644
index 0000000..ff14bb7
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_server_stream_base_test.cc
@@ -0,0 +1,339 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_server_stream_base.h"
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestQuicSpdyServerStream : public QuicSpdyServerStreamBase {
+ public:
+  TestQuicSpdyServerStream(QuicStreamId id, QuicSpdySession* session,
+                           StreamType type)
+      : QuicSpdyServerStreamBase(id, session, type) {}
+
+  void OnBodyAvailable() override {}
+};
+
+class QuicSpdyServerStreamBaseTest : public QuicTest {
+ protected:
+  QuicSpdyServerStreamBaseTest()
+      : session_(new MockQuicConnection(&helper_, &alarm_factory_,
+                                        Perspective::IS_SERVER)) {
+    session_.Initialize();
+    session_.connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session_.perspective()));
+    stream_ =
+        new TestQuicSpdyServerStream(GetNthClientInitiatedBidirectionalStreamId(
+                                         session_.transport_version(), 0),
+                                     &session_, BIDIRECTIONAL);
+    session_.ActivateStream(absl::WrapUnique(stream_));
+    helper_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  QuicSpdyServerStreamBase* stream_ = nullptr;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicSpdySession session_;
+};
+
+TEST_F(QuicSpdyServerStreamBaseTest,
+       SendQuicRstStreamNoErrorWithEarlyResponse) {
+  stream_->StopReading();
+
+  if (session_.version().UsesHttp3()) {
+    EXPECT_CALL(session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_NO_ERROR)))
+        .Times(1);
+  } else {
+    EXPECT_CALL(
+        session_,
+        MaybeSendRstStreamFrame(
+            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
+        .Times(1);
+  }
+  QuicStreamPeer::SetFinSent(stream_);
+  stream_->CloseWriteSide();
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest,
+       DoNotSendQuicRstStreamNoErrorWithRstReceived) {
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_CALL(session_,
+              MaybeSendRstStreamFrame(
+                  _,
+                  QuicResetStreamError::FromInternal(
+                      VersionHasIetfQuicFrames(session_.transport_version())
+                          ? QUIC_STREAM_CANCELLED
+                          : QUIC_RST_ACKNOWLEDGEMENT),
+                  _))
+      .Times(1);
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(session_.transport_version())) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_TRUE(stream_->reading_stopped());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnect) {
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+                GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
+                !session_.allow_extended_connect(),
+            stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, AllowExtendedConnectProtocolFirst) {
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_EQ(GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+                GetQuicReloadableFlag(quic_act_upon_invalid_header) &&
+                !session_.allow_extended_connect(),
+            stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidExtendedConnect) {
+  if (!session_.version().UsesHttp3()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, VanillaConnectAllowed) {
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeaderBlockEnd(128, 128);
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_FALSE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidVanillaConnect) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidNonConnectWithProtocol) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "GET");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeader(":protocol", "webtransport");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutScheme) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :scheme should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "GET");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutAuthority) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :authority should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":method", "GET");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutMethod) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :method should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":path", "/path");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestWithoutPath) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :path should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":method", "POST");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, InvalidRequestHeader) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  // A request without :path should be rejected.
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":scheme", "http");
+  header_list.OnHeader(":method", "POST");
+  header_list.OnHeader("invalid:header", "value");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamHeaderList(/*fin=*/false, 0, header_list);
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+TEST_F(QuicSpdyServerStreamBaseTest, EmptyHeaders) {
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  spdy::SpdyHeaderBlock empty_header;
+  quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+  quic::test::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
+  auto qpack_encoder =
+      std::make_unique<quic::QpackEncoder>(&decoder_stream_error_delegate);
+  qpack_encoder->set_qpack_stream_sender_delegate(
+      &encoder_stream_sender_delegate);
+  std::string payload =
+      qpack_encoder->EncodeHeaderList(stream_->id(), empty_header, nullptr);
+  std::unique_ptr<char[]> headers_buffer;
+  quic::QuicByteCount headers_frame_header_length =
+      quic::HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
+                                                     &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD),
+          _));
+  stream_->OnStreamFrame(QuicStreamFrame(
+      stream_->id(), true, 0, absl::StrCat(headers_frame_header, payload)));
+  EXPECT_TRUE(stream_->rst_sent());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc
new file mode 100644
index 0000000..14550db
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -0,0 +1,1949 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_session.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_headers_stream.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+
+using http2::Http2DecoderAdapter;
+using spdy::Http2WeightToSpdy3Priority;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyErrorCode;
+using spdy::SpdyFramer;
+using spdy::SpdyFramerDebugVisitorInterface;
+using spdy::SpdyFramerVisitorInterface;
+using spdy::SpdyFrameType;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyHeadersHandlerInterface;
+using spdy::SpdyHeadersIR;
+using spdy::SpdyPingId;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdyPushPromiseIR;
+using spdy::SpdySerializedFrame;
+using spdy::SpdySettingsId;
+using spdy::SpdyStreamId;
+
+namespace quic {
+
+ABSL_CONST_INIT const size_t kMaxUnassociatedWebTransportStreams = 24;
+
+namespace {
+
+// Limit on HPACK encoder dynamic table size.
+// Only used for Google QUIC, not IETF QUIC.
+constexpr uint64_t kHpackEncoderDynamicTableSizeLimit = 16384;
+
+#define ENDPOINT \
+  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+// Class to forward ACCEPT_CH frame to QuicSpdySession,
+// and ignore every other frame.
+class AlpsFrameDecoder : public HttpDecoder::Visitor {
+ public:
+  explicit AlpsFrameDecoder(QuicSpdySession* session) : session_(session) {}
+  ~AlpsFrameDecoder() override = default;
+
+  // HttpDecoder::Visitor implementation.
+  void OnError(HttpDecoder* /*decoder*/) override {}
+  bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
+    error_detail_ = "MAX_PUSH_ID frame forbidden";
+    return false;
+  }
+  bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
+    error_detail_ = "GOAWAY frame forbidden";
+    return false;
+  }
+  bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
+    return true;
+  }
+  bool OnSettingsFrame(const SettingsFrame& frame) override {
+    if (settings_frame_received_via_alps_) {
+      error_detail_ = "multiple SETTINGS frames";
+      return false;
+    }
+
+    settings_frame_received_via_alps_ = true;
+
+    error_detail_ = session_->OnSettingsFrameViaAlps(frame);
+    return !error_detail_;
+  }
+  bool OnDataFrameStart(QuicByteCount /*header_length*/, QuicByteCount
+                        /*payload_length*/) override {
+    error_detail_ = "DATA frame forbidden";
+    return false;
+  }
+  bool OnDataFramePayload(absl::string_view /*payload*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnDataFrameEnd() override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnHeadersFrameStart(QuicByteCount /*header_length*/,
+                           QuicByteCount /*payload_length*/) override {
+    error_detail_ = "HEADERS frame forbidden";
+    return false;
+  }
+  bool OnHeadersFramePayload(absl::string_view /*payload*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnHeadersFrameEnd() override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
+    error_detail_ = "PRIORITY_UPDATE frame forbidden";
+    return false;
+  }
+  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+  bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
+    return true;
+  }
+  bool OnAcceptChFrame(const AcceptChFrame& frame) override {
+    session_->OnAcceptChFrameReceivedViaAlps(frame);
+    return true;
+  }
+  void OnWebTransportStreamFrameType(
+      QuicByteCount /*header_length*/,
+      WebTransportSessionId /*session_id*/) override {
+    QUICHE_NOTREACHED();
+  }
+  bool OnUnknownFrameStart(uint64_t /*frame_type*/,
+                           QuicByteCount
+                           /*header_length*/,
+                           QuicByteCount /*payload_length*/) override {
+    return true;
+  }
+  bool OnUnknownFramePayload(absl::string_view /*payload*/) override {
+    return true;
+  }
+  bool OnUnknownFrameEnd() override { return true; }
+
+  const absl::optional<std::string>& error_detail() const {
+    return error_detail_;
+  }
+
+ private:
+  QuicSpdySession* const session_;
+  absl::optional<std::string> error_detail_;
+
+  // True if SETTINGS frame has been received via ALPS.
+  bool settings_frame_received_via_alps_ = false;
+};
+
+}  // namespace
+
+// A SpdyFramerVisitor that passes HEADERS frames to the QuicSpdyStream, and
+// closes the connection if any unexpected frames are received.
+class QuicSpdySession::SpdyFramerVisitor
+    : public SpdyFramerVisitorInterface,
+      public SpdyFramerDebugVisitorInterface {
+ public:
+  explicit SpdyFramerVisitor(QuicSpdySession* session) : session_(session) {}
+  SpdyFramerVisitor(const SpdyFramerVisitor&) = delete;
+  SpdyFramerVisitor& operator=(const SpdyFramerVisitor&) = delete;
+
+  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId /* stream_id */) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    return &header_list_;
+  }
+
+  void OnHeaderFrameEnd(SpdyStreamId /* stream_id */) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+
+    LogHeaderCompressionRatioHistogram(
+        /* using_qpack = */ false,
+        /* is_sent = */ false, header_list_.compressed_header_bytes(),
+        header_list_.uncompressed_header_bytes());
+
+    if (session_->IsConnected()) {
+      session_->OnHeaderList(header_list_);
+    }
+    header_list_.Clear();
+  }
+
+  void OnStreamFrameData(SpdyStreamId /*stream_id*/, const char* /*data*/,
+                         size_t /*len*/) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    CloseConnection("SPDY DATA frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnStreamEnd(SpdyStreamId /*stream_id*/) override {
+    // The framer invokes OnStreamEnd after processing a frame that had the fin
+    // bit set.
+  }
+
+  void OnStreamPadding(SpdyStreamId /*stream_id*/, size_t /*len*/) override {
+    CloseConnection("SPDY frame padding received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnError(Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error) override {
+    QuicErrorCode code;
+    switch (error) {
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INDEX_VARINT_ERROR:
+        code = QUIC_HPACK_INDEX_VARINT_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
+        code = QUIC_HPACK_NAME_LENGTH_VARINT_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
+        code = QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG:
+        code = QUIC_HPACK_NAME_TOO_LONG;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG:
+        code = QUIC_HPACK_VALUE_TOO_LONG;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_HUFFMAN_ERROR:
+        code = QUIC_HPACK_NAME_HUFFMAN_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_HUFFMAN_ERROR:
+        code = QUIC_HPACK_VALUE_HUFFMAN_ERROR;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
+        code = QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX:
+        code = QUIC_HPACK_INVALID_INDEX;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_NAME_INDEX:
+        code = QUIC_HPACK_INVALID_NAME_INDEX;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
+        code = QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
+        code = QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
+        code = QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK:
+        code = QUIC_HPACK_TRUNCATED_BLOCK;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG:
+        code = QUIC_HPACK_FRAGMENT_TOO_LONG;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
+        code = QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
+        break;
+      case Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE:
+        code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE;
+        break;
+      default:
+        code = QUIC_INVALID_HEADERS_STREAM_DATA;
+    }
+    CloseConnection(
+        absl::StrCat("SPDY framing error: ", detailed_error,
+                     Http2DecoderAdapter::SpdyFramerErrorToString(error)),
+        code);
+  }
+
+  void OnDataFrameHeader(SpdyStreamId /*stream_id*/, size_t /*length*/,
+                         bool /*fin*/) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    CloseConnection("SPDY DATA frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnRstStream(SpdyStreamId /*stream_id*/,
+                   SpdyErrorCode /*error_code*/) override {
+    CloseConnection("SPDY RST_STREAM frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnSetting(SpdySettingsId id, uint32_t value) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    session_->OnSetting(id, value);
+  }
+
+  void OnSettingsEnd() override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+  }
+
+  void OnPing(SpdyPingId /*unique_id*/, bool /*is_ack*/) override {
+    CloseConnection("SPDY PING frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnGoAway(SpdyStreamId /*last_accepted_stream_id*/,
+                SpdyErrorCode /*error_code*/) override {
+    CloseConnection("SPDY GOAWAY frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
+                 SpdyStreamId /* parent_stream_id */, bool /* exclusive */,
+                 bool fin, bool /*end*/) override {
+    if (!session_->IsConnected()) {
+      return;
+    }
+
+    if (VersionUsesHttp3(session_->transport_version())) {
+      CloseConnection("HEADERS frame not allowed on headers stream.",
+                      QUIC_INVALID_HEADERS_STREAM_DATA);
+      return;
+    }
+
+    QUIC_BUG_IF(quic_bug_12477_1,
+                session_->destruction_indicator() != 123456789)
+        << "QuicSpdyStream use after free. "
+        << session_->destruction_indicator() << QuicStackTrace();
+
+    SpdyPriority priority =
+        has_priority ? Http2WeightToSpdy3Priority(weight) : 0;
+    session_->OnHeaders(stream_id, has_priority,
+                        spdy::SpdyStreamPrecedence(priority), fin);
+  }
+
+  void OnWindowUpdate(SpdyStreamId /*stream_id*/,
+                      int /*delta_window_size*/) override {
+    CloseConnection("SPDY WINDOW_UPDATE frame received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+  }
+
+  void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
+                     bool /*end*/) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    if (session_->perspective() != Perspective::IS_CLIENT) {
+      CloseConnection("PUSH_PROMISE not supported.",
+                      QUIC_INVALID_HEADERS_STREAM_DATA);
+      return;
+    }
+    if (!session_->IsConnected()) {
+      return;
+    }
+    session_->OnPushPromise(stream_id, promised_stream_id);
+  }
+
+  void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
+
+  void OnPriority(SpdyStreamId stream_id, SpdyStreamId /* parent_id */,
+                  int weight, bool /* exclusive */) override {
+    QUICHE_DCHECK(!VersionUsesHttp3(session_->transport_version()));
+    if (!session_->IsConnected()) {
+      return;
+    }
+    SpdyPriority priority = Http2WeightToSpdy3Priority(weight);
+    session_->OnPriority(stream_id, spdy::SpdyStreamPrecedence(priority));
+  }
+
+  void OnPriorityUpdate(SpdyStreamId /*prioritized_stream_id*/,
+                        absl::string_view /*priority_field_value*/) override {
+    // TODO(b/171470299): Parse and call
+    // QuicSpdySession::OnPriorityUpdateForRequestStream().
+  }
+
+  bool OnUnknownFrame(SpdyStreamId /*stream_id*/,
+                      uint8_t /*frame_type*/) override {
+    CloseConnection("Unknown frame type received.",
+                    QUIC_INVALID_HEADERS_STREAM_DATA);
+    return false;
+  }
+
+  // SpdyFramerDebugVisitorInterface implementation
+  void OnSendCompressedFrame(SpdyStreamId /*stream_id*/, SpdyFrameType /*type*/,
+                             size_t payload_len, size_t frame_len) override {
+    if (payload_len == 0) {
+      QUIC_BUG(quic_bug_10360_1) << "Zero payload length.";
+      return;
+    }
+    int compression_pct = 100 - (100 * frame_len) / payload_len;
+    QUIC_DVLOG(1) << "Net.QuicHpackCompressionPercentage: " << compression_pct;
+  }
+
+  void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
+                                SpdyFrameType /*type*/,
+                                size_t frame_len) override {
+    if (session_->IsConnected()) {
+      session_->OnCompressedFrameSize(frame_len);
+    }
+  }
+
+  void set_max_header_list_size(size_t max_header_list_size) {
+    header_list_.set_max_header_list_size(max_header_list_size);
+  }
+
+ private:
+  void CloseConnection(const std::string& details, QuicErrorCode code) {
+    if (session_->IsConnected()) {
+      session_->CloseConnectionWithDetails(code, details);
+    }
+  }
+
+  QuicSpdySession* session_;
+  QuicHeaderList header_list_;
+};
+
+Http3DebugVisitor::Http3DebugVisitor() {}
+
+Http3DebugVisitor::~Http3DebugVisitor() {}
+
+// Expected unidirectional static streams Requirement can be found at
+// https://tools.ietf.org/html/draft-ietf-quic-http-22#section-6.2.
+QuicSpdySession::QuicSpdySession(
+    QuicConnection* connection, QuicSession::Visitor* visitor,
+    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions)
+    : QuicSession(connection, visitor, config, supported_versions,
+                  /*num_expected_unidirectional_static_streams = */
+                  VersionUsesHttp3(connection->transport_version())
+                      ? static_cast<QuicStreamCount>(
+                            kHttp3StaticUnidirectionalStreamCount)
+                      : 0u,
+                  std::make_unique<DatagramObserver>(this)),
+      send_control_stream_(nullptr),
+      receive_control_stream_(nullptr),
+      qpack_encoder_receive_stream_(nullptr),
+      qpack_decoder_receive_stream_(nullptr),
+      qpack_encoder_send_stream_(nullptr),
+      qpack_decoder_send_stream_(nullptr),
+      qpack_maximum_dynamic_table_capacity_(
+          kDefaultQpackMaxDynamicTableCapacity),
+      qpack_maximum_blocked_streams_(kDefaultMaximumBlockedStreams),
+      max_inbound_header_list_size_(kDefaultMaxUncompressedHeaderSize),
+      max_outbound_header_list_size_(std::numeric_limits<size_t>::max()),
+      stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      frame_len_(0),
+      fin_(false),
+      spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
+      spdy_framer_visitor_(new SpdyFramerVisitor(this)),
+      debug_visitor_(nullptr),
+      destruction_indicator_(123456789),
+      allow_extended_connect_(
+          GetQuicReloadableFlag(quic_verify_request_headers_2) &&
+          perspective() == Perspective::IS_SERVER &&
+          VersionUsesHttp3(transport_version())) {
+  h2_deframer_.set_visitor(spdy_framer_visitor_.get());
+  h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get());
+  spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
+}
+
+QuicSpdySession::~QuicSpdySession() {
+  QUIC_BUG_IF(quic_bug_12477_2, destruction_indicator_ != 123456789)
+      << "QuicSpdySession use after free. " << destruction_indicator_
+      << QuicStackTrace();
+  destruction_indicator_ = 987654321;
+}
+
+void QuicSpdySession::Initialize() {
+  QuicSession::Initialize();
+
+  FillSettingsFrame();
+  if (!VersionUsesHttp3(transport_version())) {
+    if (perspective() == Perspective::IS_SERVER) {
+      set_largest_peer_created_stream_id(
+          QuicUtils::GetHeadersStreamId(transport_version()));
+    } else {
+      QuicStreamId headers_stream_id = GetNextOutgoingBidirectionalStreamId();
+      QUICHE_DCHECK_EQ(headers_stream_id,
+                       QuicUtils::GetHeadersStreamId(transport_version()));
+    }
+    auto headers_stream = std::make_unique<QuicHeadersStream>((this));
+    QUICHE_DCHECK_EQ(QuicUtils::GetHeadersStreamId(transport_version()),
+                     headers_stream->id());
+
+    headers_stream_ = headers_stream.get();
+    ActivateStream(std::move(headers_stream));
+  } else {
+    qpack_encoder_ = std::make_unique<QpackEncoder>(this);
+    qpack_decoder_ =
+        std::make_unique<QpackDecoder>(qpack_maximum_dynamic_table_capacity_,
+                                       qpack_maximum_blocked_streams_, this);
+    MaybeInitializeHttp3UnidirectionalStreams();
+  }
+
+  spdy_framer_visitor_->set_max_header_list_size(max_inbound_header_list_size_);
+
+  // Limit HPACK buffering to 2x header list size limit.
+  h2_deframer_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
+      2 * max_inbound_header_list_size_);
+}
+
+void QuicSpdySession::FillSettingsFrame() {
+  settings_.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
+      qpack_maximum_dynamic_table_capacity_;
+  settings_.values[SETTINGS_QPACK_BLOCKED_STREAMS] =
+      qpack_maximum_blocked_streams_;
+  settings_.values[SETTINGS_MAX_FIELD_SECTION_SIZE] =
+      max_inbound_header_list_size_;
+  if (version().UsesHttp3()) {
+    HttpDatagramSupport local_http_datagram_support =
+        LocalHttpDatagramSupport();
+    if (local_http_datagram_support == HttpDatagramSupport::kDraft00 ||
+        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
+      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+    }
+    if (local_http_datagram_support == HttpDatagramSupport::kDraft04 ||
+        local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
+      settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+    }
+  }
+  if (WillNegotiateWebTransport()) {
+    settings_.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
+  }
+  if (allow_extended_connect()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_verify_request_headers_2, 1, 3);
+    settings_.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
+  }
+}
+
+void QuicSpdySession::OnDecoderStreamError(QuicErrorCode error_code,
+                                           absl::string_view error_message) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  CloseConnectionWithDetails(
+      error_code, absl::StrCat("Decoder stream error: ", error_message));
+}
+
+void QuicSpdySession::OnEncoderStreamError(QuicErrorCode error_code,
+                                           absl::string_view error_message) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  CloseConnectionWithDetails(
+      error_code, absl::StrCat("Encoder stream error: ", error_message));
+}
+
+void QuicSpdySession::OnStreamHeadersPriority(
+    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnStreamHeadersPriority(precedence);
+}
+
+void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id, bool fin,
+                                         size_t frame_len,
+                                         const QuicHeaderList& header_list) {
+  if (IsStaticStream(stream_id)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (stream == nullptr) {
+    // The stream no longer exists, but trailing headers may contain the final
+    // byte offset necessary for flow control and open stream accounting.
+    size_t final_byte_offset = 0;
+    for (const auto& header : header_list) {
+      const std::string& header_key = header.first;
+      const std::string& header_value = header.second;
+      if (header_key == kFinalOffsetHeaderKey) {
+        if (!absl::SimpleAtoi(header_value, &final_byte_offset)) {
+          connection()->CloseConnection(
+              QUIC_INVALID_HEADERS_STREAM_DATA,
+              "Trailers are malformed (no final offset)",
+              ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+          return;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Received final byte offset in trailers for stream "
+                      << stream_id << ", which no longer exists.";
+        OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+      }
+    }
+
+    // It's quite possible to receive headers after a stream has been reset.
+    return;
+  }
+  stream->OnStreamHeaderList(fin, frame_len, header_list);
+}
+
+void QuicSpdySession::OnPriorityFrame(
+    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
+  QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+  if (!stream) {
+    // It's quite possible to receive a PRIORITY frame after a stream has been
+    // reset.
+    return;
+  }
+  stream->OnPriorityFrame(precedence);
+}
+
+bool QuicSpdySession::OnPriorityUpdateForRequestStream(QuicStreamId stream_id,
+                                                       int urgency) {
+  if (perspective() == Perspective::IS_CLIENT ||
+      !QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
+      !QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
+    return true;
+  }
+
+  QuicStreamCount advertised_max_incoming_bidirectional_streams =
+      GetAdvertisedMaxIncomingBidirectionalStreams();
+  if (advertised_max_incoming_bidirectional_streams == 0 ||
+      stream_id > QuicUtils::GetFirstBidirectionalStreamId(
+                      transport_version(), Perspective::IS_CLIENT) +
+                      QuicUtils::StreamIdDelta(transport_version()) *
+                          (advertised_max_incoming_bidirectional_streams - 1)) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        "PRIORITY_UPDATE frame received for invalid stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (MaybeSetStreamPriority(stream_id, spdy::SpdyStreamPrecedence(urgency))) {
+    return true;
+  }
+
+  if (IsClosedStream(stream_id)) {
+    return true;
+  }
+
+  buffered_stream_priorities_[stream_id] = urgency;
+
+  if (buffered_stream_priorities_.size() >
+      10 * max_open_incoming_bidirectional_streams()) {
+    // This should never happen, because |buffered_stream_priorities_| should
+    // only contain entries for streams that are allowed to be open by the peer
+    // but have not been opened yet.
+    std::string error_message =
+        absl::StrCat("Too many stream priority values buffered: ",
+                     buffered_stream_priorities_.size(),
+                     ", which should not exceed the incoming stream limit of ",
+                     max_open_incoming_bidirectional_streams());
+    QUIC_BUG(quic_bug_10360_2) << error_message;
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, error_message,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicSpdySession::OnPriorityUpdateForPushStream(QuicStreamId /*push_id*/,
+                                                    int /*urgency*/) {
+  // TODO(b/147306124): Implement PRIORITY_UPDATE frames for pushed streams.
+  return true;
+}
+
+size_t QuicSpdySession::ProcessHeaderData(const struct iovec& iov) {
+  QUIC_BUG_IF(quic_bug_12477_4, destruction_indicator_ != 123456789)
+      << "QuicSpdyStream use after free. " << destruction_indicator_
+      << QuicStackTrace();
+  return h2_deframer_.ProcessInput(static_cast<char*>(iov.iov_base),
+                                   iov.iov_len);
+}
+
+size_t QuicSpdySession::WriteHeadersOnHeadersStream(
+    QuicStreamId id, SpdyHeaderBlock headers, bool fin,
+    const spdy::SpdyStreamPrecedence& precedence,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+
+  return WriteHeadersOnHeadersStreamImpl(
+      id, std::move(headers), fin,
+      /* parent_stream_id = */ 0,
+      Spdy3PriorityToHttp2Weight(precedence.spdy3_priority()),
+      /* exclusive = */ false, std::move(ack_listener));
+}
+
+size_t QuicSpdySession::WritePriority(QuicStreamId id,
+                                      QuicStreamId parent_stream_id, int weight,
+                                      bool exclusive) {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+  SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame));
+  headers_stream()->WriteOrBufferData(
+      absl::string_view(frame.data(), frame.size()), false, nullptr);
+  return frame.size();
+}
+
+void QuicSpdySession::WriteHttp3PriorityUpdate(
+    const PriorityUpdateFrame& priority_update) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  send_control_stream_->WritePriorityUpdate(priority_update);
+}
+
+void QuicSpdySession::OnHttp3GoAway(uint64_t id) {
+  QUIC_BUG_IF(quic_bug_12477_5, !version().UsesHttp3())
+      << "HTTP/3 GOAWAY received on version " << version();
+
+  if (last_received_http3_goaway_id_.has_value() &&
+      id > last_received_http3_goaway_id_.value()) {
+    CloseConnectionWithDetails(
+        QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+        absl::StrCat("GOAWAY received with ID ", id,
+                     " greater than previously received ID ",
+                     last_received_http3_goaway_id_.value()));
+    return;
+  }
+  last_received_http3_goaway_id_ = id;
+
+  if (perspective() == Perspective::IS_SERVER) {
+    // TODO(b/151749109): Cancel server pushes with push ID larger than |id|.
+    return;
+  }
+
+  // QuicStreamId is uint32_t.  Casting to this narrower type is well-defined
+  // and preserves the lower 32 bits.  Both IsBidirectionalStreamId() and
+  // IsIncomingStream() give correct results, because their return value is
+  // determined by the least significant two bits.
+  QuicStreamId stream_id = static_cast<QuicStreamId>(id);
+  if (!QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
+      IsIncomingStream(stream_id)) {
+    CloseConnectionWithDetails(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
+                               "GOAWAY with invalid stream ID");
+    return;
+  }
+
+  // TODO(b/161252736): Cancel client requests with ID larger than |id|.
+  // If |id| is larger than numeric_limits<QuicStreamId>::max(), then use
+  // max() instead of downcast value.
+}
+
+bool QuicSpdySession::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame) {
+  if (!QuicSession::OnStreamsBlockedFrame(frame)) {
+    return false;
+  }
+
+  // The peer asked for stream space more than this implementation has. Send
+  // goaway.
+  if (perspective() == Perspective::IS_SERVER &&
+      frame.stream_count >= QuicUtils::GetMaxStreamCount()) {
+    QUICHE_DCHECK_EQ(frame.stream_count, QuicUtils::GetMaxStreamCount());
+    SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "stream count too large");
+  }
+  return true;
+}
+
+void QuicSpdySession::SendHttp3GoAway(QuicErrorCode error_code,
+                                      const std::string& reason) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  if (!IsEncryptionEstablished()) {
+    QUIC_CODE_COUNT(quic_h3_goaway_before_encryption_established);
+    connection()->CloseConnection(
+        error_code, reason,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicStreamId stream_id;
+
+  stream_id = QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
+      transport_version());
+  if (last_sent_http3_goaway_id_.has_value()) {
+    if (last_sent_http3_goaway_id_.value() == stream_id) {
+      // Do not send GOAWAY twice.
+      return;
+    }
+    if (last_sent_http3_goaway_id_.value() < stream_id) {
+      // A previous GOAWAY frame was sent with smaller stream ID.  This is not
+      // possible, because the only time a GOAWAY frame with non-maximal
+      // stream ID is sent is right before closing connection.
+      QUIC_BUG(quic_bug_10360_3)
+          << "Not sending GOAWAY frame with " << stream_id
+          << " because one with " << last_sent_http3_goaway_id_.value()
+          << " already sent on connection " << connection()->connection_id();
+      return;
+    }
+  }
+
+  send_control_stream_->SendGoAway(stream_id);
+  last_sent_http3_goaway_id_ = stream_id;
+}
+
+void QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id,
+                                       QuicStreamId promised_stream_id,
+                                       SpdyHeaderBlock headers) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    QUIC_BUG(quic_bug_10360_4) << "Client shouldn't send PUSH_PROMISE";
+    return;
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    QUIC_BUG(quic_bug_12477_6)
+        << "Support for server push over HTTP/3 has been removed.";
+    return;
+  }
+
+  SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id,
+                                 std::move(headers));
+  // PUSH_PROMISE must not be the last frame sent out, at least followed by
+  // response headers.
+  push_promise.set_fin(false);
+
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
+  headers_stream()->WriteOrBufferData(
+      absl::string_view(frame.data(), frame.size()), false, nullptr);
+}
+
+void QuicSpdySession::SendInitialData() {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  QuicConnection::ScopedPacketFlusher flusher(connection());
+  send_control_stream_->MaybeSendSettingsFrame();
+}
+
+QpackEncoder* QuicSpdySession::qpack_encoder() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  return qpack_encoder_.get();
+}
+
+QpackDecoder* QuicSpdySession::qpack_decoder() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  return qpack_decoder_.get();
+}
+
+void QuicSpdySession::OnStreamCreated(QuicSpdyStream* stream) {
+  auto it = buffered_stream_priorities_.find(stream->id());
+  if (it == buffered_stream_priorities_.end()) {
+    return;
+  }
+
+  stream->SetPriority(spdy::SpdyStreamPrecedence(it->second));
+  buffered_stream_priorities_.erase(it);
+}
+
+QuicSpdyStream* QuicSpdySession::GetOrCreateSpdyDataStream(
+    const QuicStreamId stream_id) {
+  QuicStream* stream = GetOrCreateStream(stream_id);
+  if (stream && stream->is_static()) {
+    QUIC_BUG(quic_bug_10360_5)
+        << "GetOrCreateSpdyDataStream returns static stream " << stream_id
+        << " in version " << transport_version() << "\n"
+        << QuicStackTrace();
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID,
+        absl::StrCat("stream ", stream_id, " is static"),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return nullptr;
+  }
+  return static_cast<QuicSpdyStream*>(stream);
+}
+
+void QuicSpdySession::OnNewEncryptionKeyAvailable(
+    EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
+  QuicSession::OnNewEncryptionKeyAvailable(level, std::move(encrypter));
+  if (IsEncryptionEstablished()) {
+    // Send H3 SETTINGs once encryption is established.
+    SendInitialData();
+  }
+}
+
+bool QuicSpdySession::ShouldNegotiateWebTransport() { return false; }
+
+bool QuicSpdySession::ShouldNegotiateDatagramContexts() { return false; }
+
+bool QuicSpdySession::ShouldValidateWebTransportVersion() const { return true; }
+
+bool QuicSpdySession::WillNegotiateWebTransport() {
+  return LocalHttpDatagramSupport() != HttpDatagramSupport::kNone &&
+         version().UsesHttp3() && ShouldNegotiateWebTransport();
+}
+
+// True if there are open HTTP requests.
+bool QuicSpdySession::ShouldKeepConnectionAlive() const {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()) ||
+                0u == pending_streams_size());
+  return GetNumActiveStreams() + pending_streams_size() > 0;
+}
+
+bool QuicSpdySession::UsesPendingStreamForFrame(QuicFrameType type,
+                                                QuicStreamId stream_id) const {
+  // Pending streams can only be used to handle unidirectional stream with
+  // STREAM & RESET_STREAM frames in IETF QUIC.
+  return VersionUsesHttp3(transport_version()) &&
+         (type == STREAM_FRAME || type == RST_STREAM_FRAME) &&
+         QuicUtils::GetStreamType(stream_id, perspective(),
+                                  IsIncomingStream(stream_id),
+                                  version()) == READ_UNIDIRECTIONAL;
+}
+
+size_t QuicSpdySession::WriteHeadersOnHeadersStreamImpl(
+    QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
+    QuicStreamId parent_stream_id, int weight, bool exclusive,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+
+  const QuicByteCount uncompressed_size = headers.TotalBytesUsed();
+  SpdyHeadersIR headers_frame(id, std::move(headers));
+  headers_frame.set_fin(fin);
+  if (perspective() == Perspective::IS_CLIENT) {
+    headers_frame.set_has_priority(true);
+    headers_frame.set_parent_stream_id(parent_stream_id);
+    headers_frame.set_weight(weight);
+    headers_frame.set_exclusive(exclusive);
+  }
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
+  headers_stream()->WriteOrBufferData(
+      absl::string_view(frame.data(), frame.size()), false,
+      std::move(ack_listener));
+
+  // Calculate compressed header block size without framing overhead.
+  QuicByteCount compressed_size = frame.size();
+  compressed_size -= spdy::kFrameHeaderSize;
+  if (perspective() == Perspective::IS_CLIENT) {
+    // Exclusive bit and Stream Dependency are four bytes, weight is one more.
+    compressed_size -= 5;
+  }
+
+  LogHeaderCompressionRatioHistogram(
+      /* using_qpack = */ false,
+      /* is_sent = */ true, compressed_size, uncompressed_size);
+
+  return frame.size();
+}
+
+void QuicSpdySession::OnPromiseHeaderList(
+    QuicStreamId /*stream_id*/, QuicStreamId /*promised_stream_id*/,
+    size_t /*frame_len*/, const QuicHeaderList& /*header_list*/) {
+  std::string error =
+      "OnPromiseHeaderList should be overridden in client code.";
+  QUIC_BUG(quic_bug_10360_6) << error;
+  connection()->CloseConnection(QUIC_INTERNAL_ERROR, error,
+                                ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+bool QuicSpdySession::ResumeApplicationState(ApplicationState* cached_state) {
+  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_CLIENT);
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  SettingsFrame out;
+  if (!HttpDecoder::DecodeSettings(
+          reinterpret_cast<char*>(cached_state->data()), cached_state->size(),
+          &out)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSettingsFrameResumed(out);
+  }
+  QUICHE_DCHECK(streams_waiting_for_settings_.empty());
+  for (const auto& setting : out.values) {
+    OnSetting(setting.first, setting.second);
+  }
+  return true;
+}
+
+absl::optional<std::string> QuicSpdySession::OnAlpsData(
+    const uint8_t* alps_data, size_t alps_length) {
+  AlpsFrameDecoder alps_frame_decoder(this);
+  HttpDecoder decoder(&alps_frame_decoder);
+  decoder.ProcessInput(reinterpret_cast<const char*>(alps_data), alps_length);
+  if (alps_frame_decoder.error_detail()) {
+    return alps_frame_decoder.error_detail();
+  }
+
+  if (decoder.error() != QUIC_NO_ERROR) {
+    return decoder.error_detail();
+  }
+
+  if (!decoder.AtFrameBoundary()) {
+    return "incomplete HTTP/3 frame";
+  }
+
+  return absl::nullopt;
+}
+
+void QuicSpdySession::OnAcceptChFrameReceivedViaAlps(
+    const AcceptChFrame& frame) {
+  if (debug_visitor_) {
+    debug_visitor_->OnAcceptChFrameReceivedViaAlps(frame);
+  }
+}
+
+bool QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSettingsFrameReceived(frame);
+  }
+  for (const auto& setting : frame.values) {
+    if (!OnSetting(setting.first, setting.second)) {
+      return false;
+    }
+  }
+  for (QuicStreamId stream_id : streams_waiting_for_settings_) {
+    QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
+    QuicSpdyStream* stream = GetOrCreateSpdyDataStream(stream_id);
+    if (stream == nullptr) {
+      // The stream may no longer exist, since it is possible for a stream to
+      // get reset while waiting for the SETTINGS frame.
+      continue;
+    }
+    stream->OnDataAvailable();
+  }
+  streams_waiting_for_settings_.clear();
+  return true;
+}
+
+absl::optional<std::string> QuicSpdySession::OnSettingsFrameViaAlps(
+    const SettingsFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSettingsFrameReceivedViaAlps(frame);
+  }
+  for (const auto& setting : frame.values) {
+    if (!OnSetting(setting.first, setting.second)) {
+      // Do not bother adding the setting identifier or value to the error
+      // message, because OnSetting() already closed the connection, therefore
+      // the error message will be ignored.
+      return "error parsing setting";
+    }
+  }
+  return absl::nullopt;
+}
+
+bool QuicSpdySession::VerifySettingIsZeroOrOne(uint64_t id, uint64_t value) {
+  if (value == 0 || value == 1) {
+    return true;
+  }
+  std::string error_details = absl::StrCat(
+      "Received ",
+      H3SettingsToString(static_cast<Http3AndQpackSettingsIdentifiers>(id)),
+      " with invalid value ", value);
+  QUIC_PEER_BUG(bad received setting) << ENDPOINT << error_details;
+  CloseConnectionWithDetails(QUIC_HTTP_INVALID_SETTING_VALUE, error_details);
+  return false;
+}
+
+bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
+  any_settings_received_ = true;
+
+  if (VersionUsesHttp3(transport_version())) {
+    // SETTINGS frame received on the control stream.
+    switch (id) {
+      case SETTINGS_QPACK_MAX_TABLE_CAPACITY: {
+        QUIC_DVLOG(1)
+            << ENDPOINT
+            << "SETTINGS_QPACK_MAX_TABLE_CAPACITY received with value "
+            << value;
+        // Communicate |value| to encoder, because it is used for encoding
+        // Required Insert Count.
+        if (!qpack_encoder_->SetMaximumDynamicTableCapacity(value)) {
+          CloseConnectionWithDetails(
+              was_zero_rtt_rejected()
+                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+              absl::StrCat(was_zero_rtt_rejected()
+                               ? "Server rejected 0-RTT, aborting because "
+                               : "",
+                           "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: ",
+                           value, " while current value is: ",
+                           qpack_encoder_->MaximumDynamicTableCapacity()));
+          return false;
+        }
+        // However, limit the dynamic table capacity to
+        // |qpack_maximum_dynamic_table_capacity_|.
+        qpack_encoder_->SetDynamicTableCapacity(
+            std::min(value, qpack_maximum_dynamic_table_capacity_));
+        break;
+      }
+      case SETTINGS_MAX_FIELD_SECTION_SIZE:
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_MAX_FIELD_SECTION_SIZE received with value "
+                      << value;
+        if (max_outbound_header_list_size_ !=
+                std::numeric_limits<size_t>::max() &&
+            max_outbound_header_list_size_ > value) {
+          CloseConnectionWithDetails(
+              was_zero_rtt_rejected()
+                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+              absl::StrCat(was_zero_rtt_rejected()
+                               ? "Server rejected 0-RTT, aborting because "
+                               : "",
+                           "Server sent an SETTINGS_MAX_FIELD_SECTION_SIZE: ",
+                           value, " which reduces current value: ",
+                           max_outbound_header_list_size_));
+          return false;
+        }
+        max_outbound_header_list_size_ = value;
+        break;
+      case SETTINGS_QPACK_BLOCKED_STREAMS: {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_QPACK_BLOCKED_STREAMS received with value "
+                      << value;
+        if (!qpack_encoder_->SetMaximumBlockedStreams(value)) {
+          CloseConnectionWithDetails(
+              was_zero_rtt_rejected()
+                  ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+                  : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+              absl::StrCat(was_zero_rtt_rejected()
+                               ? "Server rejected 0-RTT, aborting because "
+                               : "",
+                           "Server sent an SETTINGS_QPACK_BLOCKED_STREAMS: ",
+                           value, " which reduces current value: ",
+                           qpack_encoder_->maximum_blocked_streams()));
+          return false;
+        }
+        break;
+      }
+      case SETTINGS_ENABLE_CONNECT_PROTOCOL: {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_ENABLE_CONNECT_PROTOCOL received with value "
+                      << value;
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        if (perspective() == Perspective::IS_CLIENT) {
+          allow_extended_connect_ = value != 0;
+        }
+        break;
+      }
+      case spdy::SETTINGS_ENABLE_PUSH:
+        ABSL_FALLTHROUGH_INTENDED;
+      case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
+        ABSL_FALLTHROUGH_INTENDED;
+      case spdy::SETTINGS_INITIAL_WINDOW_SIZE:
+        ABSL_FALLTHROUGH_INTENDED;
+      case spdy::SETTINGS_MAX_FRAME_SIZE:
+        CloseConnectionWithDetails(
+            QUIC_HTTP_RECEIVE_SPDY_SETTING,
+            absl::StrCat("received HTTP/2 specific setting in HTTP/3 session: ",
+                         id));
+        return false;
+      case SETTINGS_H3_DATAGRAM_DRAFT00: {
+        HttpDatagramSupport local_http_datagram_support =
+            LocalHttpDatagramSupport();
+        if (local_http_datagram_support != HttpDatagramSupport::kDraft00 &&
+            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+          break;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_H3_DATAGRAM_DRAFT00 received with value "
+                      << value;
+        if (!version().UsesHttp3()) {
+          break;
+        }
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        if (value && http_datagram_support_ != HttpDatagramSupport::kDraft04) {
+          // If both draft-00 and draft-04 are supported, use draft-04.
+          http_datagram_support_ = HttpDatagramSupport::kDraft00;
+        }
+        break;
+      }
+      case SETTINGS_H3_DATAGRAM_DRAFT04: {
+        HttpDatagramSupport local_http_datagram_support =
+            LocalHttpDatagramSupport();
+        if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
+            local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+          break;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_H3_DATAGRAM_DRAFT04 received with value "
+                      << value;
+        if (!version().UsesHttp3()) {
+          break;
+        }
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        if (value) {
+          http_datagram_support_ = HttpDatagramSupport::kDraft04;
+        }
+        break;
+      }
+      case SETTINGS_WEBTRANS_DRAFT00:
+        if (!WillNegotiateWebTransport()) {
+          break;
+        }
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "SETTINGS_ENABLE_WEBTRANSPORT received with value "
+                      << value;
+        if (!VerifySettingIsZeroOrOne(id, value)) {
+          return false;
+        }
+        peer_supports_webtransport_ = (value == 1);
+        if (perspective() == Perspective::IS_CLIENT && value == 1) {
+          allow_extended_connect_ = true;
+        }
+        break;
+      default:
+        QUIC_DVLOG(1) << ENDPOINT << "Unknown setting identifier " << id
+                      << " received with value " << value;
+        // Ignore unknown settings.
+        break;
+    }
+    return true;
+  }
+
+  // SETTINGS frame received on the headers stream.
+  switch (id) {
+    case spdy::SETTINGS_HEADER_TABLE_SIZE:
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "SETTINGS_HEADER_TABLE_SIZE received with value "
+                    << value;
+      if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+        QUIC_RELOADABLE_FLAG_COUNT(quic_limit_encoder_dynamic_table_size);
+        spdy_framer_.UpdateHeaderEncoderTableSize(
+            std::min<uint64_t>(value, kHpackEncoderDynamicTableSizeLimit));
+        break;
+      }
+      spdy_framer_.UpdateHeaderEncoderTableSize(value);
+      break;
+    case spdy::SETTINGS_ENABLE_PUSH:
+      if (perspective() == Perspective::IS_SERVER) {
+        // See rfc7540, Section 6.5.2.
+        if (value > 1) {
+          QUIC_DLOG(ERROR) << ENDPOINT << "Invalid value " << value
+                           << " received for SETTINGS_ENABLE_PUSH.";
+          if (IsConnected()) {
+            CloseConnectionWithDetails(
+                QUIC_INVALID_HEADERS_STREAM_DATA,
+                absl::StrCat("Invalid value for SETTINGS_ENABLE_PUSH: ",
+                             value));
+          }
+          return true;
+        }
+        QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_ENABLE_PUSH received with value "
+                      << value << ", ignoring.";
+        break;
+      } else {
+        QUIC_DLOG(ERROR)
+            << ENDPOINT
+            << "Invalid SETTINGS_ENABLE_PUSH received by client with value "
+            << value;
+        if (IsConnected()) {
+          CloseConnectionWithDetails(
+              QUIC_INVALID_HEADERS_STREAM_DATA,
+              absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
+        }
+      }
+      break;
+    case spdy::SETTINGS_MAX_HEADER_LIST_SIZE:
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "SETTINGS_MAX_HEADER_LIST_SIZE received with value "
+                    << value;
+      max_outbound_header_list_size_ = value;
+      break;
+    default:
+      QUIC_DLOG(ERROR) << ENDPOINT << "Unknown setting identifier " << id
+                       << " received with value " << value;
+      if (IsConnected()) {
+        CloseConnectionWithDetails(
+            QUIC_INVALID_HEADERS_STREAM_DATA,
+            absl::StrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id));
+      }
+  }
+  return true;
+}
+
+bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() {
+  return false;
+}
+
+void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, bool has_priority,
+                                const spdy::SpdyStreamPrecedence& precedence,
+                                bool fin) {
+  if (has_priority) {
+    if (perspective() == Perspective::IS_CLIENT) {
+      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                 "Server must not send priorities.");
+      return;
+    }
+    OnStreamHeadersPriority(stream_id, precedence);
+  } else {
+    if (perspective() == Perspective::IS_SERVER) {
+      CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                 "Client must send priorities.");
+      return;
+    }
+  }
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   stream_id_);
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   promised_stream_id_);
+  stream_id_ = stream_id;
+  fin_ = fin;
+}
+
+void QuicSpdySession::OnPushPromise(SpdyStreamId stream_id,
+                                    SpdyStreamId promised_stream_id) {
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   stream_id_);
+  QUICHE_DCHECK_EQ(QuicUtils::GetInvalidStreamId(transport_version()),
+                   promised_stream_id_);
+  stream_id_ = stream_id;
+  promised_stream_id_ = promised_stream_id;
+}
+
+// TODO (wangyix): Why is SpdyStreamId used instead of QuicStreamId?
+// This occurs in many places in this file.
+void QuicSpdySession::OnPriority(SpdyStreamId stream_id,
+                                 const spdy::SpdyStreamPrecedence& precedence) {
+  if (perspective() == Perspective::IS_CLIENT) {
+    CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
+                               "Server must not send PRIORITY frames.");
+    return;
+  }
+  OnPriorityFrame(stream_id, precedence);
+}
+
+void QuicSpdySession::OnHeaderList(const QuicHeaderList& header_list) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received header list for stream " << stream_id_
+                << ": " << header_list.DebugString();
+  // This code path is only executed for push promise in IETF QUIC.
+  if (VersionUsesHttp3(transport_version())) {
+    QUICHE_DCHECK(promised_stream_id_ !=
+                  QuicUtils::GetInvalidStreamId(transport_version()));
+  }
+  if (promised_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(transport_version())) {
+    OnStreamHeaderList(stream_id_, fin_, frame_len_, header_list);
+  } else {
+    OnPromiseHeaderList(stream_id_, promised_stream_id_, frame_len_,
+                        header_list);
+  }
+  // Reset state for the next frame.
+  promised_stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
+  stream_id_ = QuicUtils::GetInvalidStreamId(transport_version());
+  fin_ = false;
+  frame_len_ = 0;
+}
+
+void QuicSpdySession::OnCompressedFrameSize(size_t frame_len) {
+  frame_len_ += frame_len;
+}
+
+void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error,
+                                                 const std::string& details) {
+  connection()->CloseConnection(
+      error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+bool QuicSpdySession::HasActiveRequestStreams() const {
+  return GetNumActiveStreams() + num_draining_streams() > 0;
+}
+
+QuicStream* QuicSpdySession::ProcessPendingStream(PendingStream* pending) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK(connection()->connected());
+  struct iovec iov;
+  if (!pending->sequencer()->GetReadableRegion(&iov)) {
+    // The first byte hasn't been received yet.
+    return nullptr;
+  }
+
+  QuicDataReader reader(static_cast<char*>(iov.iov_base), iov.iov_len);
+  uint8_t stream_type_length = reader.PeekVarInt62Length();
+  uint64_t stream_type = 0;
+  if (!reader.ReadVarInt62(&stream_type)) {
+    if (pending->sequencer()->NumBytesBuffered() ==
+        pending->sequencer()->close_offset()) {
+      // Stream received FIN but there are not enough bytes for stream type.
+      // Mark all bytes consumed in order to close stream.
+      pending->MarkConsumed(pending->sequencer()->close_offset());
+    }
+    return nullptr;
+  }
+  pending->MarkConsumed(stream_type_length);
+
+  switch (stream_type) {
+    case kControlStream: {  // HTTP/3 control stream.
+      if (receive_control_stream_) {
+        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("Control");
+        return nullptr;
+      }
+      auto receive_stream =
+          std::make_unique<QuicReceiveControlStream>(pending, this);
+      receive_control_stream_ = receive_stream.get();
+      ActivateStream(std::move(receive_stream));
+      QUIC_DVLOG(1) << ENDPOINT << "Receive Control stream is created";
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPeerControlStreamCreated(
+            receive_control_stream_->id());
+      }
+      return receive_control_stream_;
+    }
+    case kServerPushStream: {  // Push Stream.
+      CloseConnectionWithDetails(QUIC_HTTP_RECEIVE_SERVER_PUSH,
+                                 "Received server push stream");
+      return nullptr;
+    }
+    case kQpackEncoderStream: {  // QPACK encoder stream.
+      if (qpack_encoder_receive_stream_) {
+        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK encoder");
+        return nullptr;
+      }
+      auto encoder_receive = std::make_unique<QpackReceiveStream>(
+          pending, this, qpack_decoder_->encoder_stream_receiver());
+      qpack_encoder_receive_stream_ = encoder_receive.get();
+      ActivateStream(std::move(encoder_receive));
+      QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Encoder stream is created";
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPeerQpackEncoderStreamCreated(
+            qpack_encoder_receive_stream_->id());
+      }
+      return qpack_encoder_receive_stream_;
+    }
+    case kQpackDecoderStream: {  // QPACK decoder stream.
+      if (qpack_decoder_receive_stream_) {
+        CloseConnectionOnDuplicateHttp3UnidirectionalStreams("QPACK decoder");
+        return nullptr;
+      }
+      auto decoder_receive = std::make_unique<QpackReceiveStream>(
+          pending, this, qpack_encoder_->decoder_stream_receiver());
+      qpack_decoder_receive_stream_ = decoder_receive.get();
+      ActivateStream(std::move(decoder_receive));
+      QUIC_DVLOG(1) << ENDPOINT << "Receive QPACK Decoder stream is created";
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPeerQpackDecoderStreamCreated(
+            qpack_decoder_receive_stream_->id());
+      }
+      return qpack_decoder_receive_stream_;
+    }
+    case kWebTransportUnidirectionalStream: {
+      // Note that this checks whether WebTransport is enabled on the receiver
+      // side, as we may receive WebTransport streams before peer's SETTINGS are
+      // received.
+      // TODO(b/184156476): consider whether this means we should drop buffered
+      // streams if we don't receive indication of WebTransport support.
+      if (!WillNegotiateWebTransport()) {
+        // Treat as unknown stream type.
+        break;
+      }
+      QUIC_DVLOG(1) << ENDPOINT << "Created an incoming WebTransport stream "
+                    << pending->id();
+      auto stream_owned =
+          std::make_unique<WebTransportHttp3UnidirectionalStream>(pending,
+                                                                  this);
+      WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
+      ActivateStream(std::move(stream_owned));
+      return stream;
+    }
+    default:
+      break;
+  }
+  MaybeSendStopSendingFrame(
+      pending->id(),
+      QuicResetStreamError::FromInternal(QUIC_STREAM_STREAM_CREATION_ERROR));
+  pending->StopReading();
+  return nullptr;
+}
+
+void QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  if (!send_control_stream_ && CanOpenNextOutgoingUnidirectionalStream()) {
+    auto send_control = std::make_unique<QuicSendControlStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, settings_);
+    send_control_stream_ = send_control.get();
+    ActivateStream(std::move(send_control));
+    if (debug_visitor_) {
+      debug_visitor_->OnControlStreamCreated(send_control_stream_->id());
+    }
+  }
+
+  if (!qpack_decoder_send_stream_ &&
+      CanOpenNextOutgoingUnidirectionalStream()) {
+    auto decoder_send = std::make_unique<QpackSendStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, kQpackDecoderStream);
+    qpack_decoder_send_stream_ = decoder_send.get();
+    ActivateStream(std::move(decoder_send));
+    qpack_decoder_->set_qpack_stream_sender_delegate(
+        qpack_decoder_send_stream_);
+    if (debug_visitor_) {
+      debug_visitor_->OnQpackDecoderStreamCreated(
+          qpack_decoder_send_stream_->id());
+    }
+  }
+
+  if (!qpack_encoder_send_stream_ &&
+      CanOpenNextOutgoingUnidirectionalStream()) {
+    auto encoder_send = std::make_unique<QpackSendStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, kQpackEncoderStream);
+    qpack_encoder_send_stream_ = encoder_send.get();
+    ActivateStream(std::move(encoder_send));
+    qpack_encoder_->set_qpack_stream_sender_delegate(
+        qpack_encoder_send_stream_);
+    if (debug_visitor_) {
+      debug_visitor_->OnQpackEncoderStreamCreated(
+          qpack_encoder_send_stream_->id());
+    }
+  }
+}
+
+void QuicSpdySession::BeforeConnectionCloseSent() {
+  if (!VersionUsesHttp3(transport_version()) || !IsEncryptionEstablished()) {
+    return;
+  }
+
+  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
+
+  QuicStreamId stream_id =
+      GetLargestPeerCreatedStreamId(/*unidirectional = */ false);
+
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    // No client-initiated bidirectional streams received yet.
+    // Send 0 to let client know that all requests can be retried.
+    stream_id = 0;
+  } else {
+    // Tell client that streams starting with the next after the largest
+    // received one can be retried.
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+  if (last_sent_http3_goaway_id_.has_value() &&
+      last_sent_http3_goaway_id_.value() <= stream_id) {
+    // A previous GOAWAY frame was sent with smaller stream ID.  This is not
+    // possible, because this is the only method sending a GOAWAY frame with
+    // non-maximal stream ID, and this must only be called once, right
+    // before closing connection.
+    QUIC_BUG(QuicGoawayFrameAlreadySent)
+        << "Not sending GOAWAY frame with " << stream_id << " because one with "
+        << last_sent_http3_goaway_id_.value() << " already sent on connection "
+        << connection()->connection_id();
+
+    // MUST not send GOAWAY with identifier larger than previously sent.
+    // Do not bother sending one with same identifier as before, since GOAWAY
+    // frames on the control stream are guaranteed to be processed in order.
+    return;
+  }
+
+  send_control_stream_->SendGoAway(stream_id);
+  last_sent_http3_goaway_id_ = stream_id;
+}
+
+void QuicSpdySession::OnCanCreateNewOutgoingStream(bool unidirectional) {
+  if (unidirectional && VersionUsesHttp3(transport_version())) {
+    MaybeInitializeHttp3UnidirectionalStreams();
+  }
+}
+
+bool QuicSpdySession::OnMaxPushIdFrame(PushId max_push_id) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective());
+
+  if (max_push_id_.has_value()) {
+    QUIC_DVLOG(1) << "Setting max_push_id to:  " << max_push_id
+                  << " from: " << max_push_id_.value();
+  } else {
+    QUIC_DVLOG(1) << "Setting max_push_id to:  " << max_push_id
+                  << " from unset";
+  }
+  absl::optional<PushId> old_max_push_id = max_push_id_;
+  max_push_id_ = max_push_id;
+
+  if (!old_max_push_id.has_value() || max_push_id > old_max_push_id.value()) {
+    OnCanCreateNewOutgoingStream(true);
+    return true;
+  }
+
+  // Equal value is not considered an error.
+  if (max_push_id < old_max_push_id.value()) {
+    CloseConnectionWithDetails(
+        QUIC_HTTP_INVALID_MAX_PUSH_ID,
+        absl::StrCat("MAX_PUSH_ID received with value ", max_push_id,
+                     " which is smaller that previously received value ",
+                     old_max_push_id.value()));
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicSpdySession::goaway_received() const {
+  return VersionUsesHttp3(transport_version())
+             ? last_received_http3_goaway_id_.has_value()
+             : transport_goaway_received();
+}
+
+bool QuicSpdySession::goaway_sent() const {
+  return VersionUsesHttp3(transport_version())
+             ? last_sent_http3_goaway_id_.has_value()
+             : transport_goaway_sent();
+}
+
+void QuicSpdySession::CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
+    absl::string_view type) {
+  QUIC_PEER_BUG(quic_peer_bug_10360_9) << absl::StrCat(
+      "Received a duplicate ", type, " stream: Closing connection.");
+  CloseConnectionWithDetails(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                             absl::StrCat(type, " stream is received twice."));
+}
+
+// static
+void QuicSpdySession::LogHeaderCompressionRatioHistogram(
+    bool using_qpack, bool is_sent, QuicByteCount compressed,
+    QuicByteCount uncompressed) {
+  if (compressed <= 0 || uncompressed <= 0) {
+    return;
+  }
+
+  int ratio = 100 * (compressed) / (uncompressed);
+  if (ratio < 1) {
+    ratio = 1;
+  } else if (ratio > 200) {
+    ratio = 200;
+  }
+
+  // Note that when using histogram macros in Chromium, the histogram name must
+  // be the same across calls for any given call site.
+  if (using_qpack) {
+    if (is_sent) {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackSent",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for sent "
+                            "headers using QPACK.");
+    } else {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioQpackReceived",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for "
+                            "received headers using QPACK.");
+    }
+  } else {
+    if (is_sent) {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackSent",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for sent "
+                            "headers using HPACK.");
+    } else {
+      QUIC_HISTOGRAM_COUNTS("QuicSession.HeaderCompressionRatioHpackReceived",
+                            ratio, 1, 200, 200,
+                            "Header compression ratio as percentage for "
+                            "received headers using HPACK.");
+    }
+  }
+}
+
+MessageStatus QuicSpdySession::SendHttp3Datagram(
+    QuicDatagramStreamId stream_id,
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  if (!SupportsH3Datagram()) {
+    QUIC_BUG(send http datagram too early)
+        << "Refusing to send HTTP Datagram before SETTINGS received";
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+  uint64_t stream_id_to_write = stream_id;
+  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
+    // Stream ID is sent divided by four as per the specification.
+    stream_id_to_write /= kHttpDatagramStreamIdDivisor;
+  }
+  size_t slice_length =
+      QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
+  if (context_id.has_value()) {
+    slice_length += QuicDataWriter::GetVarInt62Len(context_id.value());
+  }
+  quiche::QuicheBuffer buffer(
+      connection()->helper()->GetStreamSendBufferAllocator(), slice_length);
+  QuicDataWriter writer(slice_length, buffer.data());
+  if (!writer.WriteVarInt62(stream_id_to_write)) {
+    QUIC_BUG(h3 datagram stream ID write fail)
+        << "Failed to write HTTP/3 datagram stream ID";
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+  if (context_id.has_value()) {
+    if (!writer.WriteVarInt62(context_id.value())) {
+      QUIC_BUG(h3 datagram context ID write fail)
+          << "Failed to write HTTP/3 datagram context ID";
+      return MESSAGE_STATUS_INTERNAL_ERROR;
+    }
+  }
+  if (!writer.WriteBytes(payload.data(), payload.length())) {
+    QUIC_BUG(h3 datagram payload write fail)
+        << "Failed to write HTTP/3 datagram payload";
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+
+  quiche::QuicheMemSlice slice(std::move(buffer));
+  return datagram_queue()->SendOrQueueDatagram(std::move(slice));
+}
+
+void QuicSpdySession::SetMaxDatagramTimeInQueueForStreamId(
+    QuicStreamId /*stream_id*/, QuicTime::Delta max_time_in_queue) {
+  // TODO(b/184598230): implement this in a way that works for multiple sessions
+  // on a same connection.
+  datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
+}
+
+void QuicSpdySession::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
+                                                  QuicStreamId stream_id) {
+  h3_datagram_flow_id_to_stream_id_map_[flow_id] = stream_id;
+}
+
+void QuicSpdySession::UnregisterHttp3DatagramFlowId(
+    QuicDatagramStreamId flow_id) {
+  h3_datagram_flow_id_to_stream_id_map_.erase(flow_id);
+}
+
+void QuicSpdySession::OnMessageReceived(absl::string_view message) {
+  QuicSession::OnMessageReceived(message);
+  if (!SupportsH3Datagram()) {
+    QUIC_DLOG(INFO) << "Ignoring unexpected received HTTP/3 datagram";
+    return;
+  }
+  QuicDataReader reader(message);
+  uint64_t stream_id64;
+  if (!reader.ReadVarInt62(&stream_id64)) {
+    QUIC_DLOG(ERROR) << "Failed to parse stream ID in received HTTP/3 datagram";
+    return;
+  }
+  if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
+    // Stream ID is sent divided by four as per the specification.
+    stream_id64 *= kHttpDatagramStreamIdDivisor;
+  }
+  if (perspective() == Perspective::IS_SERVER &&
+      http_datagram_support_ == HttpDatagramSupport::kDraft00) {
+    auto it = h3_datagram_flow_id_to_stream_id_map_.find(stream_id64);
+    if (it == h3_datagram_flow_id_to_stream_id_map_.end()) {
+      QUIC_DLOG(INFO) << "Received unknown HTTP/3 datagram flow ID "
+                      << stream_id64;
+      return;
+    }
+    stream_id64 = it->second;
+  }
+  if (stream_id64 > std::numeric_limits<QuicStreamId>::max()) {
+    // TODO(b/181256914) make this a connection close once we deprecate
+    // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+    QUIC_DLOG(ERROR) << "Received unexpectedly high HTTP/3 datagram stream ID "
+                     << stream_id64;
+    return;
+  }
+  QuicStreamId stream_id = static_cast<QuicStreamId>(stream_id64);
+  QuicSpdyStream* stream =
+      static_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
+  if (stream == nullptr) {
+    QUIC_DLOG(INFO) << "Received HTTP/3 datagram for unknown stream ID "
+                    << stream_id;
+    // TODO(b/181256914) buffer unknown HTTP/3 datagram flow IDs for a short
+    // period of time in case they were reordered.
+    return;
+  }
+  stream->OnDatagramReceived(&reader);
+}
+
+bool QuicSpdySession::SupportsWebTransport() {
+  return WillNegotiateWebTransport() && SupportsH3Datagram() &&
+         peer_supports_webtransport_ &&
+         (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+          allow_extended_connect_);
+}
+
+bool QuicSpdySession::SupportsH3Datagram() const {
+  return http_datagram_support_ != HttpDatagramSupport::kNone;
+}
+
+WebTransportHttp3* QuicSpdySession::GetWebTransportSession(
+    WebTransportSessionId id) {
+  if (!SupportsWebTransport()) {
+    return nullptr;
+  }
+  if (!IsValidWebTransportSessionId(id, version())) {
+    return nullptr;
+  }
+  QuicSpdyStream* connect_stream = GetOrCreateSpdyDataStream(id);
+  if (connect_stream == nullptr) {
+    return nullptr;
+  }
+  return connect_stream->web_transport();
+}
+
+bool QuicSpdySession::ShouldProcessIncomingRequests() {
+  if (!ShouldBufferRequestsUntilSettings()) {
+    return true;
+  }
+
+  return any_settings_received_;
+}
+
+void QuicSpdySession::OnStreamWaitingForClientSettings(QuicStreamId id) {
+  QUICHE_DCHECK(ShouldBufferRequestsUntilSettings());
+  QUICHE_DCHECK(QuicUtils::IsBidirectionalStreamId(id, version()));
+  streams_waiting_for_settings_.insert(id);
+}
+
+void QuicSpdySession::AssociateIncomingWebTransportStreamWithSession(
+    WebTransportSessionId session_id, QuicStreamId stream_id) {
+  if (QuicUtils::IsOutgoingStreamId(version(), stream_id, perspective())) {
+    QUIC_BUG(AssociateIncomingWebTransportStreamWithSession got outgoing stream)
+        << ENDPOINT
+        << "AssociateIncomingWebTransportStreamWithSession() got an outgoing "
+           "stream ID: "
+        << stream_id;
+    return;
+  }
+  WebTransportHttp3* session = GetWebTransportSession(session_id);
+  if (session != nullptr) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Successfully associated incoming WebTransport stream "
+                  << stream_id << " with session ID " << session_id;
+
+    session->AssociateStream(stream_id);
+    return;
+  }
+  // Evict the oldest streams until we are under the limit.
+  while (buffered_streams_.size() >= kMaxUnassociatedWebTransportStreams) {
+    QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
+                  << buffered_streams_.front().stream_id
+                  << " from buffered streams as the queue is full.";
+    ResetStream(buffered_streams_.front().stream_id,
+                QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
+    buffered_streams_.pop_front();
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Received a WebTransport stream " << stream_id
+                << " for session ID " << session_id
+                << " but cannot associate it; buffering instead.";
+  buffered_streams_.push_back(
+      BufferedWebTransportStream{session_id, stream_id});
+}
+
+void QuicSpdySession::ProcessBufferedWebTransportStreamsForSession(
+    WebTransportHttp3* session) {
+  const WebTransportSessionId session_id = session->id();
+  QUIC_DVLOG(1) << "Processing buffered WebTransport streams for "
+                << session_id;
+  auto it = buffered_streams_.begin();
+  while (it != buffered_streams_.end()) {
+    if (it->session_id == session_id) {
+      QUIC_DVLOG(1) << "Unbuffered and associated WebTransport stream "
+                    << it->stream_id << " with session " << it->session_id;
+      session->AssociateStream(it->stream_id);
+      it = buffered_streams_.erase(it);
+    } else {
+      it++;
+    }
+  }
+}
+
+WebTransportHttp3UnidirectionalStream*
+QuicSpdySession::CreateOutgoingUnidirectionalWebTransportStream(
+    WebTransportHttp3* session) {
+  if (!CanOpenNextOutgoingUnidirectionalStream()) {
+    return nullptr;
+  }
+
+  QuicStreamId stream_id = GetNextOutgoingUnidirectionalStreamId();
+  auto stream_owned = std::make_unique<WebTransportHttp3UnidirectionalStream>(
+      stream_id, this, session->id());
+  WebTransportHttp3UnidirectionalStream* stream = stream_owned.get();
+  ActivateStream(std::move(stream_owned));
+  stream->WritePreamble();
+  session->AssociateStream(stream_id);
+  return stream;
+}
+
+QuicSpdyStream* QuicSpdySession::CreateOutgoingBidirectionalWebTransportStream(
+    WebTransportHttp3* session) {
+  QuicSpdyStream* stream = CreateOutgoingBidirectionalStream();
+  if (stream == nullptr) {
+    return nullptr;
+  }
+  QuicStreamId stream_id = stream->id();
+  stream->ConvertToWebTransportDataStream(session->id());
+  if (stream->web_transport_stream() == nullptr) {
+    // An error in ConvertToWebTransportDataStream() would result in
+    // CONNECTION_CLOSE, thus we don't need to do anything here.
+    return nullptr;
+  }
+  session->AssociateStream(stream_id);
+  return stream;
+}
+
+void QuicSpdySession::OnDatagramProcessed(
+    absl::optional<MessageStatus> /*status*/) {
+  // TODO(b/184598230): make this work with multiple datagram flows.
+}
+
+void QuicSpdySession::DatagramObserver::OnDatagramProcessed(
+    absl::optional<MessageStatus> status) {
+  session_->OnDatagramProcessed(status);
+}
+
+HttpDatagramSupport QuicSpdySession::LocalHttpDatagramSupport() {
+  return HttpDatagramSupport::kNone;
+}
+
+std::string HttpDatagramSupportToString(
+    HttpDatagramSupport http_datagram_support) {
+  switch (http_datagram_support) {
+    case HttpDatagramSupport::kNone:
+      return "None";
+    case HttpDatagramSupport::kDraft00:
+      return "Draft00";
+    case HttpDatagramSupport::kDraft04:
+      return "Draft04";
+    case HttpDatagramSupport::kDraft00And04:
+      return "Draft00And04";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(http_datagram_support), ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const HttpDatagramSupport& http_datagram_support) {
+  os << HttpDatagramSupportToString(http_datagram_support);
+  return os;
+}
+
+// Must not be called after Initialize().
+void QuicSpdySession::set_allow_extended_connect(bool allow_extended_connect) {
+  QUIC_BUG_IF(extended connect wrong version,
+              !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+                  !VersionUsesHttp3(transport_version()))
+      << "Try to enable/disable extended CONNECT in Google QUIC";
+  QUIC_BUG_IF(extended connect on client,
+              !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+                  perspective() == Perspective::IS_CLIENT)
+      << "Enabling/disabling extended CONNECT on the client side has no effect";
+  if (ShouldNegotiateWebTransport()) {
+    QUIC_BUG_IF(disable extended connect, !allow_extended_connect)
+        << "Disabling extended CONNECT with web transport enabled has no "
+           "effect.";
+    return;
+  }
+  allow_extended_connect_ = allow_extended_connect;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_session.h b/quiche/quic/core/http/quic_spdy_session.h
new file mode 100644
index 0000000..b603803
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_session.h
@@ -0,0 +1,706 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/quic_headers_stream.h"
+#include "quiche/quic/core/http/quic_receive_control_stream.h"
+#include "quiche/quic/core/http/quic_send_control_stream.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_receive_stream.h"
+#include "quiche/quic/core/qpack/qpack_send_stream.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+
+namespace quic {
+
+namespace test {
+class QuicSpdySessionPeer;
+}  // namespace test
+
+class WebTransportHttp3UnidirectionalStream;
+
+QUIC_EXPORT_PRIVATE extern const size_t kMaxUnassociatedWebTransportStreams;
+
+class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
+ public:
+  Http3DebugVisitor();
+  Http3DebugVisitor(const Http3DebugVisitor&) = delete;
+  Http3DebugVisitor& operator=(const Http3DebugVisitor&) = delete;
+
+  virtual ~Http3DebugVisitor();
+
+  // TODO(https://crbug.com/1062700): Remove default implementation of all
+  // methods after Chrome's QuicHttp3Logger has overrides.  This is to make sure
+  // QUICHE merge is not blocked on having to add those overrides, they can
+  // happen asynchronously.
+
+  // Creation of unidirectional streams.
+
+  // Called when locally-initiated control stream is created.
+  virtual void OnControlStreamCreated(QuicStreamId /*stream_id*/) {}
+  // Called when locally-initiated QPACK encoder stream is created.
+  virtual void OnQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) {}
+  // Called when locally-initiated QPACK decoder stream is created.
+  virtual void OnQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) {}
+  // Called when peer's control stream type is received.
+  virtual void OnPeerControlStreamCreated(QuicStreamId /*stream_id*/) = 0;
+  // Called when peer's QPACK encoder stream type is received.
+  virtual void OnPeerQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
+  // Called when peer's QPACK decoder stream type is received.
+  virtual void OnPeerQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
+
+  // Incoming HTTP/3 frames in ALPS TLS extension.
+  virtual void OnSettingsFrameReceivedViaAlps(const SettingsFrame& /*frame*/) {}
+  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/) {}
+
+  // Incoming HTTP/3 frames on the control stream.
+  virtual void OnSettingsFrameReceived(const SettingsFrame& /*frame*/) = 0;
+  virtual void OnGoAwayFrameReceived(const GoAwayFrame& /*frame*/) {}
+  // TODO(b/171463363): Remove.
+  virtual void OnMaxPushIdFrameReceived(const MaxPushIdFrame& /*frame*/) {}
+  virtual void OnPriorityUpdateFrameReceived(
+      const PriorityUpdateFrame& /*frame*/) {}
+  virtual void OnAcceptChFrameReceived(const AcceptChFrame& /*frame*/) {}
+
+  // Incoming HTTP/3 frames on request or push streams.
+  virtual void OnDataFrameReceived(QuicStreamId /*stream_id*/,
+                                   QuicByteCount /*payload_length*/) {}
+  virtual void OnHeadersFrameReceived(
+      QuicStreamId /*stream_id*/, QuicByteCount /*compressed_headers_length*/) {
+  }
+  virtual void OnHeadersDecoded(QuicStreamId /*stream_id*/,
+                                QuicHeaderList /*headers*/) {}
+
+  // Incoming HTTP/3 frames of unknown type on any stream.
+  virtual void OnUnknownFrameReceived(QuicStreamId /*stream_id*/,
+                                      uint64_t /*frame_type*/,
+                                      QuicByteCount /*payload_length*/) {}
+
+  // Outgoing HTTP/3 frames on the control stream.
+  virtual void OnSettingsFrameSent(const SettingsFrame& /*frame*/) = 0;
+  virtual void OnGoAwayFrameSent(QuicStreamId /*stream_id*/) {}
+  virtual void OnPriorityUpdateFrameSent(const PriorityUpdateFrame& /*frame*/) {
+  }
+
+  // Outgoing HTTP/3 frames on request or push streams.
+  virtual void OnDataFrameSent(QuicStreamId /*stream_id*/,
+                               QuicByteCount /*payload_length*/) {}
+  virtual void OnHeadersFrameSent(
+      QuicStreamId /*stream_id*/,
+      const spdy::SpdyHeaderBlock& /*header_block*/) {}
+
+  // 0-RTT related events.
+  virtual void OnSettingsFrameResumed(const SettingsFrame& /*frame*/) {}
+};
+
+// Whether draft-ietf-masque-h3-datagram is supported on this session and if so
+// which draft is currently in use.
+enum class HttpDatagramSupport : uint8_t {
+  kNone = 0,  // HTTP Datagrams are not supported for this session.
+  kDraft00 = 1,
+  kDraft04 = 2,
+  kDraft00And04 = 3,  // only used locally, we only negotiate one draft.
+};
+
+QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
+    HttpDatagramSupport http_datagram_support);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const HttpDatagramSupport& http_datagram_support);
+
+// A QUIC session for HTTP.
+class QUIC_EXPORT_PRIVATE QuicSpdySession
+    : public QuicSession,
+      public QpackEncoder::DecoderStreamErrorDelegate,
+      public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  // Does not take ownership of |connection| or |visitor|.
+  QuicSpdySession(QuicConnection* connection, QuicSession::Visitor* visitor,
+                  const QuicConfig& config,
+                  const ParsedQuicVersionVector& supported_versions);
+  QuicSpdySession(const QuicSpdySession&) = delete;
+  QuicSpdySession& operator=(const QuicSpdySession&) = delete;
+
+  ~QuicSpdySession() override;
+
+  void Initialize() override;
+
+  // QpackEncoder::DecoderStreamErrorDelegate implementation.
+  void OnDecoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+
+  // QpackDecoder::EncoderStreamErrorDelegate implementation.
+  void OnEncoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+
+  // Called by |headers_stream_| when headers with a priority have been
+  // received for a stream.  This method will only be called for server streams.
+  virtual void OnStreamHeadersPriority(
+      QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence);
+
+  // Called by |headers_stream_| when headers have been completely received
+  // for a stream.  |fin| will be true if the fin flag was set in the headers
+  // frame.
+  virtual void OnStreamHeaderList(QuicStreamId stream_id, bool fin,
+                                  size_t frame_len,
+                                  const QuicHeaderList& header_list);
+
+  // Called by |headers_stream_| when push promise headers have been
+  // completely received.  |fin| will be true if the fin flag was set
+  // in the headers.
+  virtual void OnPromiseHeaderList(QuicStreamId stream_id,
+                                   QuicStreamId promised_stream_id,
+                                   size_t frame_len,
+                                   const QuicHeaderList& header_list);
+
+  // Called by |headers_stream_| when a PRIORITY frame has been received for a
+  // stream. This method will only be called for server streams.
+  virtual void OnPriorityFrame(QuicStreamId stream_id,
+                               const spdy::SpdyStreamPrecedence& precedence);
+
+  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a request
+  // stream.  Returns false and closes connection if |stream_id| is invalid.
+  bool OnPriorityUpdateForRequestStream(QuicStreamId stream_id, int urgency);
+
+  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a push
+  // stream.  Returns false and closes connection if |push_id| is invalid.
+  bool OnPriorityUpdateForPushStream(QuicStreamId push_id, int urgency);
+
+  // Called when an HTTP/3 ACCEPT_CH frame has been received.
+  // This method will only be called for client sessions.
+  virtual void OnAcceptChFrame(const AcceptChFrame& /*frame*/) {}
+
+  // Sends contents of |iov| to h2_deframer_, returns number of bytes processed.
+  size_t ProcessHeaderData(const struct iovec& iov);
+
+  // Writes |headers| for the stream |id| to the dedicated headers stream.
+  // If |fin| is true, then no more data will be sent for the stream |id|.
+  // If provided, |ack_notifier_delegate| will be registered to be notified when
+  // we have seen ACKs for all packets resulting from this call.
+  virtual size_t WriteHeadersOnHeadersStream(
+      QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
+      const spdy::SpdyStreamPrecedence& precedence,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Writes an HTTP/2 PRIORITY frame the to peer. Returns the size in bytes of
+  // the resulting PRIORITY frame.
+  size_t WritePriority(QuicStreamId id, QuicStreamId parent_stream_id,
+                       int weight, bool exclusive);
+
+  // Writes an HTTP/3 PRIORITY_UPDATE frame to the peer.
+  void WriteHttp3PriorityUpdate(const PriorityUpdateFrame& priority_update);
+
+  // Process received HTTP/3 GOAWAY frame.  When sent from server to client,
+  // |id| is a stream ID.  When sent from client to server, |id| is a push ID.
+  virtual void OnHttp3GoAway(uint64_t id);
+
+  // Send GOAWAY if the peer is blocked on the implementation max.
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+
+  // Write GOAWAY frame with maximum stream ID on the control stream.  Called to
+  // initite graceful connection shutdown.  Do not use smaller stream ID, in
+  // case client does not implement retry on GOAWAY.  Do not send GOAWAY if one
+  // has already been sent. Send connection close with |error_code| and |reason|
+  // before encryption gets established.
+  void SendHttp3GoAway(QuicErrorCode error_code, const std::string& reason);
+
+  // Write |headers| for |promised_stream_id| on |original_stream_id| in a
+  // PUSH_PROMISE frame to peer.
+  virtual void WritePushPromise(QuicStreamId original_stream_id,
+                                QuicStreamId promised_stream_id,
+                                spdy::SpdyHeaderBlock headers);
+
+  QpackEncoder* qpack_encoder();
+  QpackDecoder* qpack_decoder();
+  QuicHeadersStream* headers_stream() { return headers_stream_; }
+
+  const QuicHeadersStream* headers_stream() const { return headers_stream_; }
+
+  // Called when the control stream receives HTTP/3 SETTINGS.
+  // Returns false in case of 0-RTT if received settings are incompatible with
+  // cached values, true otherwise.
+  virtual bool OnSettingsFrame(const SettingsFrame& frame);
+
+  // Called when an HTTP/3 SETTINGS frame is received via ALPS.
+  // Returns an error message if an error has occurred, or nullopt otherwise.
+  // May or may not close the connection on error.
+  absl::optional<std::string> OnSettingsFrameViaAlps(
+      const SettingsFrame& frame);
+
+  // Called when a setting is parsed from a SETTINGS frame received on the
+  // control stream or from cached application state.
+  // Returns true on success.
+  // Returns false if received setting is incompatible with cached value (in
+  // case of 0-RTT) or with previously received value (in case of ALPS).
+  // Also closes the connection on error.
+  bool OnSetting(uint64_t id, uint64_t value);
+
+  // Return true if this session wants to release headers stream's buffer
+  // aggressively.
+  virtual bool ShouldReleaseHeadersStreamSequencerBuffer();
+
+  void CloseConnectionWithDetails(QuicErrorCode error,
+                                  const std::string& details);
+
+  // Must not be called after Initialize().
+  // TODO(bnc): Move to constructor argument.
+  void set_qpack_maximum_dynamic_table_capacity(
+      uint64_t qpack_maximum_dynamic_table_capacity) {
+    qpack_maximum_dynamic_table_capacity_ =
+        qpack_maximum_dynamic_table_capacity;
+  }
+
+  // Must not be called after Initialize().
+  // TODO(bnc): Move to constructor argument.
+  void set_qpack_maximum_blocked_streams(
+      uint64_t qpack_maximum_blocked_streams) {
+    qpack_maximum_blocked_streams_ = qpack_maximum_blocked_streams;
+  }
+
+  // Should only be used by IETF QUIC server side.
+  // Must not be called after Initialize().
+  // TODO(bnc): Move to constructor argument.
+  void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) {
+    max_inbound_header_list_size_ = max_inbound_header_list_size;
+  }
+
+  // Must not be called after Initialize().
+  void set_allow_extended_connect(bool allow_extended_connect);
+
+  size_t max_outbound_header_list_size() const {
+    return max_outbound_header_list_size_;
+  }
+
+  size_t max_inbound_header_list_size() const {
+    return max_inbound_header_list_size_;
+  }
+
+  bool allow_extended_connect() const { return allow_extended_connect_; }
+
+  // Returns true if the session has active request streams.
+  bool HasActiveRequestStreams() const;
+
+  // Called when the size of the compressed frame payload is available.
+  void OnCompressedFrameSize(size_t frame_len);
+
+  // Called when a PUSH_PROMISE frame has been received.
+  // TODO(b/171463363): Remove.
+  void OnPushPromise(spdy::SpdyStreamId stream_id,
+                     spdy::SpdyStreamId promised_stream_id);
+
+  // Called when the complete list of headers is available.
+  void OnHeaderList(const QuicHeaderList& header_list);
+
+  QuicStreamId promised_stream_id() const { return promised_stream_id_; }
+
+  // Initialze HTTP/3 unidirectional streams if |unidirectional| is true and
+  // those streams are not initialized yet.
+  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
+
+  // Sets |max_push_id_|.
+  // This method must only be called if protocol is IETF QUIC and perspective is
+  // server.  It must only be called if a MAX_PUSH_ID frame is received.
+  // Returns whether |max_push_id| is greater than or equal to current
+  // |max_push_id_|.
+  // TODO(b/171463363): Remove.
+  bool OnMaxPushIdFrame(PushId max_push_id);
+
+  int32_t destruction_indicator() const { return destruction_indicator_; }
+
+  void set_debug_visitor(Http3DebugVisitor* debug_visitor) {
+    debug_visitor_ = debug_visitor;
+  }
+
+  Http3DebugVisitor* debug_visitor() { return debug_visitor_; }
+
+  // When using Google QUIC, return whether a transport layer GOAWAY frame has
+  // been received or sent.
+  // When using IETF QUIC, return whether an HTTP/3 GOAWAY frame has been
+  // received or sent.
+  bool goaway_received() const;
+  bool goaway_sent() const;
+
+  // Log header compression ratio histogram.
+  // |using_qpack| is true for QPACK, false for HPACK.
+  // |is_sent| is true for sent headers, false for received ones.
+  // Ratio is recorded as percentage.  Smaller value means more efficient
+  // compression.  Compressed size might be larger than uncompressed size, but
+  // recorded ratio is trunckated at 200%.
+  // Uncompressed size can be zero for an empty header list, and compressed size
+  // can be zero for an empty header list when using HPACK.  (QPACK always emits
+  // a header block prefix of at least two bytes.)  This method records nothing
+  // if either |compressed| or |uncompressed| is not positive.
+  // In order for measurements for different protocol to be comparable, the
+  // caller must ensure that uncompressed size is the total length of header
+  // names and values without any overhead.
+  static void LogHeaderCompressionRatioHistogram(bool using_qpack, bool is_sent,
+                                                 QuicByteCount compressed,
+                                                 QuicByteCount uncompressed);
+
+  // True if any dynamic table entries have been referenced from either a sent
+  // or received header block.  Used for stats.
+  bool dynamic_table_entry_referenced() const {
+    return (qpack_encoder_ &&
+            qpack_encoder_->dynamic_table_entry_referenced()) ||
+           (qpack_decoder_ && qpack_decoder_->dynamic_table_entry_referenced());
+  }
+
+  void OnStreamCreated(QuicSpdyStream* stream);
+
+  // Decode SETTINGS from |cached_state| and apply it to the session.
+  bool ResumeApplicationState(ApplicationState* cached_state) override;
+
+  absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
+                                         size_t alps_length) override;
+
+  // Called when ACCEPT_CH frame is parsed out of data received in TLS ALPS
+  // extension.
+  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/);
+
+  // Whether HTTP datagrams are supported on this session and which draft is in
+  // use, based on received SETTINGS.
+  HttpDatagramSupport http_datagram_support() const {
+    return http_datagram_support_;
+  }
+
+  // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
+  MessageStatus SendHttp3Datagram(
+      QuicDatagramStreamId stream_id,
+      absl::optional<QuicDatagramContextId> context_id,
+      absl::string_view payload);
+  // This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
+  void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
+                                            QuicTime::Delta max_time_in_queue);
+  // This must not be used except by
+  // QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders.
+  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
+                                   QuicStreamId stream_id);
+  // This must not be used except by QuicSpdyStream::OnClose.
+  void UnregisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
+
+  // Override from QuicSession to support HTTP/3 datagrams.
+  void OnMessageReceived(absl::string_view message) override;
+
+  // Indicates whether the HTTP/3 session supports WebTransport.
+  bool SupportsWebTransport();
+
+  // Indicates whether both the peer and us support HTTP/3 Datagrams.
+  bool SupportsH3Datagram() const;
+
+  // Indicates whether the HTTP/3 session will indicate WebTransport support to
+  // the peer.
+  bool WillNegotiateWebTransport();
+
+  // Returns a WebTransport session by its session ID.  Returns nullptr if no
+  // session is associated with the given ID.
+  WebTransportHttp3* GetWebTransportSession(WebTransportSessionId id);
+
+  // If true, no data on bidirectional streams will be processed by the server
+  // until the SETTINGS are received.  Only works for HTTP/3.
+  bool ShouldBufferRequestsUntilSettings() {
+    return version().UsesHttp3() && perspective() == Perspective::IS_SERVER &&
+           LocalHttpDatagramSupport() != HttpDatagramSupport::kNone;
+  }
+
+  // Returns if the incoming bidirectional streams should process data.  This is
+  // usually true, but in certain cases we would want to wait until the settings
+  // are received.
+  bool ShouldProcessIncomingRequests();
+
+  void OnStreamWaitingForClientSettings(QuicStreamId id);
+
+  // Links the specified stream with a WebTransport session.  If the session is
+  // not present, it is buffered until a corresponding stream is found.
+  void AssociateIncomingWebTransportStreamWithSession(
+      WebTransportSessionId session_id, QuicStreamId stream_id);
+
+  void ProcessBufferedWebTransportStreamsForSession(WebTransportHttp3* session);
+
+  bool CanOpenOutgoingUnidirectionalWebTransportStream(
+      WebTransportSessionId /*id*/) {
+    return CanOpenNextOutgoingUnidirectionalStream();
+  }
+  bool CanOpenOutgoingBidirectionalWebTransportStream(
+      WebTransportSessionId /*id*/) {
+    return CanOpenNextOutgoingBidirectionalStream();
+  }
+
+  // Creates an outgoing unidirectional WebTransport stream.  Returns nullptr if
+  // the stream cannot be created due to flow control or some other reason.
+  WebTransportHttp3UnidirectionalStream*
+  CreateOutgoingUnidirectionalWebTransportStream(WebTransportHttp3* session);
+
+  // Creates an outgoing bidirectional WebTransport stream.  Returns nullptr if
+  // the stream cannot be created due to flow control or some other reason.
+  QuicSpdyStream* CreateOutgoingBidirectionalWebTransportStream(
+      WebTransportHttp3* session);
+
+  QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id);
+
+  // Indicates whether we will try to negotiate datagram contexts on newly
+  // created WebTransport sessions over HTTP/3.
+  virtual bool ShouldNegotiateDatagramContexts();
+
+  // Indicates whether the client should check that the
+  // `Sec-Webtransport-Http3-Draft` header is valid.
+  // TODO(vasilvv): remove this once this is enabled in Chromium.
+  virtual bool ShouldValidateWebTransportVersion() const;
+
+ protected:
+  // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
+  // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to
+  // make sure that all data streams are QuicSpdyStreams.
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0;
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override = 0;
+  virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0;
+  virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0;
+
+  // If an incoming stream can be created, return true.
+  virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0;
+
+  // If an outgoing bidirectional/unidirectional stream can be created, return
+  // true.
+  virtual bool ShouldCreateOutgoingBidirectionalStream() = 0;
+  virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0;
+
+  // Indicates whether the underlying backend can accept and process
+  // WebTransport sessions over HTTP/3.
+  virtual bool ShouldNegotiateWebTransport();
+
+  // Returns true if there are open HTTP requests.
+  bool ShouldKeepConnectionAlive() const override;
+
+  // Overridden to buffer incoming unidirectional streams for version 99.
+  bool UsesPendingStreamForFrame(QuicFrameType type,
+                                 QuicStreamId stream_id) const override;
+
+  // Processes incoming unidirectional streams; parses the stream type, and
+  // creates a new stream of the corresponding type.  Returns the pointer to the
+  // newly created stream, or nullptr if the stream type is not yet available.
+  QuicStream* ProcessPendingStream(PendingStream* pending) override;
+
+  size_t WriteHeadersOnHeadersStreamImpl(
+      QuicStreamId id, spdy::SpdyHeaderBlock headers, bool fin,
+      QuicStreamId parent_stream_id, int weight, bool exclusive,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
+
+  // Sets the maximum size of the header compression table spdy_framer_ is
+  // willing to use to encode header blocks.
+  void UpdateHeaderEncoderTableSize(uint32_t value);
+
+  bool IsConnected() { return connection()->connected(); }
+
+  const QuicReceiveControlStream* receive_control_stream() const {
+    return receive_control_stream_;
+  }
+
+  const SettingsFrame& settings() const { return settings_; }
+
+  // Initializes HTTP/3 unidirectional streams if not yet initialzed.
+  virtual void MaybeInitializeHttp3UnidirectionalStreams();
+
+  // QuicConnectionVisitorInterface method.
+  void BeforeConnectionCloseSent() override;
+
+  // Called whenever a datagram is dequeued or dropped from datagram_queue().
+  virtual void OnDatagramProcessed(absl::optional<MessageStatus> status);
+
+  // Returns which version of the HTTP/3 datagram extension we should advertise
+  // in settings and accept remote settings for.
+  virtual HttpDatagramSupport LocalHttpDatagramSupport();
+
+ private:
+  friend class test::QuicSpdySessionPeer;
+
+  class SpdyFramerVisitor;
+
+  // Proxies OnDatagramProcessed() calls to the session.
+  class QUIC_EXPORT_PRIVATE DatagramObserver
+      : public QuicDatagramQueue::Observer {
+   public:
+    explicit DatagramObserver(QuicSpdySession* session) : session_(session) {}
+    void OnDatagramProcessed(absl::optional<MessageStatus> status) override;
+
+   private:
+    QuicSpdySession* session_;  // not owned
+  };
+
+  struct QUIC_EXPORT_PRIVATE BufferedWebTransportStream {
+    WebTransportSessionId session_id;
+    QuicStreamId stream_id;
+  };
+
+  // The following methods are called by the SimpleVisitor.
+
+  // Called when a HEADERS frame has been received.
+  void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
+                 const spdy::SpdyStreamPrecedence& precedence, bool fin);
+
+  // Called when a PRIORITY frame has been received.
+  void OnPriority(spdy::SpdyStreamId stream_id,
+                  const spdy::SpdyStreamPrecedence& precedence);
+
+  void CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
+      absl::string_view type);
+
+  // Sends any data which should be sent at the start of a connection, including
+  // the initial SETTINGS frame, and (when IETF QUIC is used) also a MAX_PUSH_ID
+  // frame if SetMaxPushId() had been called before encryption was established.
+  // When using 0-RTT, this method is called twice: once when encryption is
+  // established, and again when 1-RTT keys are available.
+  void SendInitialData();
+
+  void FillSettingsFrame();
+
+  bool VerifySettingIsZeroOrOne(uint64_t id, uint64_t value);
+
+  std::unique_ptr<QpackEncoder> qpack_encoder_;
+  std::unique_ptr<QpackDecoder> qpack_decoder_;
+
+  // Pointer to the header stream in stream_map_.
+  QuicHeadersStream* headers_stream_;
+
+  // HTTP/3 control streams. They are owned by QuicSession inside
+  // stream map, and can be accessed by those unowned pointers below.
+  QuicSendControlStream* send_control_stream_;
+  QuicReceiveControlStream* receive_control_stream_;
+
+  // Pointers to HTTP/3 QPACK streams in stream map.
+  QpackReceiveStream* qpack_encoder_receive_stream_;
+  QpackReceiveStream* qpack_decoder_receive_stream_;
+  QpackSendStream* qpack_encoder_send_stream_;
+  QpackSendStream* qpack_decoder_send_stream_;
+
+  SettingsFrame settings_;
+
+  // Maximum dynamic table capacity as defined at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity
+  // for the decoding context.  Value will be sent via
+  // SETTINGS_QPACK_MAX_TABLE_CAPACITY.
+  // |qpack_maximum_dynamic_table_capacity_| also serves as an upper bound for
+  // the dynamic table capacity of the encoding context, to limit memory usage
+  // if a larger SETTINGS_QPACK_MAX_TABLE_CAPACITY value is received.
+  uint64_t qpack_maximum_dynamic_table_capacity_;
+
+  // Maximum number of blocked streams as defined at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams
+  // for the decoding context.  Value will be sent via
+  // SETTINGS_QPACK_BLOCKED_STREAMS.
+  uint64_t qpack_maximum_blocked_streams_;
+
+  // The maximum size of a header block that will be accepted from the peer,
+  // defined per spec as key + value + overhead per field (uncompressed).
+  // Value will be sent via SETTINGS_MAX_HEADER_LIST_SIZE.
+  size_t max_inbound_header_list_size_;
+
+  // The maximum size of a header block that can be sent to the peer. This field
+  // is informed and set by the peer via SETTINGS frame.
+  // TODO(b/148616439): Honor this field when sending headers.
+  size_t max_outbound_header_list_size_;
+
+  // Data about the stream whose headers are being processed.
+  QuicStreamId stream_id_;
+  QuicStreamId promised_stream_id_;
+  size_t frame_len_;
+  bool fin_;
+
+  spdy::SpdyFramer spdy_framer_;
+  http2::Http2DecoderAdapter h2_deframer_;
+  std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
+
+  // Used in IETF QUIC only.
+  // For a server:
+  //   the push ID in the most recently received MAX_PUSH_ID frame,
+  //   or unset if no MAX_PUSH_ID frame has been received.
+  // For a client:
+  //   unset until SetMaxPushId() is called;
+  //   before encryption is established, the push ID to be sent in the initial
+  //   MAX_PUSH_ID frame;
+  //   after encryption is established, the push ID in the most recently sent
+  //   MAX_PUSH_ID frame.
+  // Once set, never goes back to unset.
+  // TODO(b/171463363): Remove.
+  absl::optional<PushId> max_push_id_;
+
+  // Not owned by the session.
+  Http3DebugVisitor* debug_visitor_;
+
+  // Priority values received in PRIORITY_UPDATE frames for streams that are not
+  // open yet.
+  absl::flat_hash_map<QuicStreamId, int> buffered_stream_priorities_;
+
+  // An integer used for live check. The indicator is assigned a value in
+  // constructor. As long as it is not the assigned value, that would indicate
+  // an use-after-free.
+  int32_t destruction_indicator_;
+
+  // The identifier in the most recently received GOAWAY frame.  Unset if no
+  // GOAWAY frame has been received yet.
+  absl::optional<uint64_t> last_received_http3_goaway_id_;
+  // The identifier in the most recently sent GOAWAY frame.  Unset if no GOAWAY
+  // frame has been sent yet.
+  absl::optional<uint64_t> last_sent_http3_goaway_id_;
+
+  // Whether both this endpoint and our peer support HTTP datagrams and which
+  // draft is in use for this session.
+  HttpDatagramSupport http_datagram_support_ = HttpDatagramSupport::kNone;
+
+  // Whether the peer has indicated WebTransport support.
+  bool peer_supports_webtransport_ = false;
+
+  // This maps from draft-ietf-masque-h3-datagram-00 flow IDs to stream IDs.
+  // TODO(b/181256914) remove this when we deprecate support for that draft in
+  // favor of more recent ones.
+  absl::flat_hash_map<uint64_t, QuicStreamId>
+      h3_datagram_flow_id_to_stream_id_map_;
+
+  // Whether any settings have been received, either from the peer or from a
+  // session ticket.
+  bool any_settings_received_ = false;
+
+  // If ShouldBufferRequestsUntilSettings() is true, all streams that are
+  // blocked by that are tracked here.
+  absl::flat_hash_set<QuicStreamId> streams_waiting_for_settings_;
+
+  // WebTransport streams that do not have a session associated with them.
+  // Limited to kMaxUnassociatedWebTransportStreams; when the list is full,
+  // oldest streams are evicated first.
+  std::list<BufferedWebTransportStream> buffered_streams_;
+
+  // On the server side, if true, advertise and accept extended CONNECT method.
+  // On the client side, true if the peer advertised extended CONNECT.
+  bool allow_extended_connect_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
diff --git a/quiche/quic/core/http/quic_spdy_session_test.cc b/quiche/quic/core/http/quic_spdy_session_test.cc
new file mode 100644
index 0000000..0a767c1
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_session_test.cc
@@ -0,0 +1,3890 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_session.h"
+
+#include <cstdint>
+#include <limits>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+using spdy::kV3HighestPriority;
+using spdy::Spdy3PriorityToHttp2Weight;
+using spdy::SpdyFramer;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+using spdy::SpdyPriorityIR;
+using spdy::SpdySerializedFrame;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::ElementsAre;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+bool VerifyAndClearStopSendingFrame(const QuicFrame& frame) {
+  EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
+  return ClearControlFrame(frame);
+}
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        one_rtt_keys_available_(false),
+        params_(new QuicCryptoNegotiatedParameters) {
+    // Simulate a negotiated cipher_suite with a fake value.
+    params_->cipher_suite = 1;
+  }
+
+  void EstablishZeroRttEncryption() {
+    encryption_established_ = true;
+    session()->connection()->SetEncrypter(
+        ENCRYPTION_ZERO_RTT,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    one_rtt_keys_available_ = true;
+    QuicErrorCode error;
+    std::string error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (session()->version().UsesTls()) {
+      if (session()->perspective() == Perspective::IS_CLIENT) {
+        session()->config()->SetOriginalConnectionIdToSend(
+            session()->connection()->connection_id());
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->connection_id());
+      } else {
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->client_connection_id());
+      }
+      TransportParameters transport_parameters;
+      EXPECT_TRUE(
+          session()->config()->FillTransportParameters(&transport_parameters));
+      error = session()->config()->ProcessTransportParameters(
+          transport_parameters, /* is_resumption = */ false, &error_details);
+    } else {
+      CryptoHandshakeMessage msg;
+      session()->config()->ToHandshakeMessage(&msg, transport_version());
+      error =
+          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    }
+    EXPECT_THAT(error, IsQuicNoError());
+    session()->OnNewEncryptionKeyAvailable(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+    session()->OnConfigNegotiated();
+    if (session()->connection()->version().handshake_protocol ==
+        PROTOCOL_TLS1_3) {
+      session()->OnTlsHandshakeComplete();
+    } else {
+      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  }
+
+  // QuicCryptoStream implementation
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool one_rtt_keys_available() const override {
+    return one_rtt_keys_available_;
+  }
+  HandshakeState GetHandshakeState() const override {
+    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+  }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_params*/) const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+
+  bool HasPendingCryptoRetransmission() const override { return false; }
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  SSL* GetSsl() const override { return nullptr; }
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestHeadersStream : public QuicHeadersStream {
+ public:
+  explicit TestHeadersStream(QuicSpdySession* session)
+      : QuicHeadersStream(session) {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+};
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
+      : QuicSpdyStream(id, session, type) {}
+
+  TestStream(PendingStream* pending, QuicSpdySession* session)
+      : QuicSpdyStream(pending, session) {}
+
+  using QuicStream::CloseWriteSide;
+
+  void OnBodyAvailable() override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool, RetransmitStreamData,
+              (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
+              (override));
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+ protected:
+  bool AreHeadersValid(const QuicHeaderList& /*header_list*/) const override {
+    return true;
+  }
+};
+
+class TestSession : public QuicSpdySession {
+ public:
+  explicit TestSession(QuicConnection* connection)
+      : QuicSpdySession(connection, nullptr, DefaultQuicConfig(),
+                        CurrentSupportedVersions()),
+        crypto_stream_(this),
+        writev_consumes_all_data_(false) {
+    this->connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection->perspective()));
+    if (this->connection()->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(this->connection());
+    }
+  }
+
+  ~TestSession() override { DeleteConnection(); }
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  TestStream* CreateOutgoingBidirectionalStream() override {
+    TestStream* stream = new TestStream(GetNextOutgoingBidirectionalStreamId(),
+                                        this, BIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateOutgoingUnidirectionalStream() override {
+    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
+                                        this, WRITE_UNIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(QuicStreamId id) override {
+    // Enforce the limit on the number of open streams.
+    if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
+        stream_id_manager().num_open_incoming_streams() + 1 >
+            max_open_incoming_bidirectional_streams()) {
+      connection()->CloseConnection(
+          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return nullptr;
+    } else {
+      TestStream* stream = new TestStream(
+          id, this,
+          DetermineStreamType(id, connection()->version(), perspective(),
+                              /*is_incoming=*/true, BIDIRECTIONAL));
+      ActivateStream(absl::WrapUnique(stream));
+      return stream;
+    }
+  }
+
+  TestStream* CreateIncomingStream(PendingStream* pending) override {
+    TestStream* stream = new TestStream(pending, this);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  bool ShouldCreateIncomingStream(QuicStreamId /*id*/) override { return true; }
+
+  bool ShouldCreateOutgoingBidirectionalStream() override { return true; }
+  bool ShouldCreateOutgoingUnidirectionalStream() override { return true; }
+
+  bool IsClosedStream(QuicStreamId id) {
+    return QuicSession::IsClosedStream(id);
+  }
+
+  QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
+    return QuicSpdySession::GetOrCreateStream(stream_id);
+  }
+
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override {
+    bool fin = state != NO_FIN;
+    QuicConsumedData consumed(write_length, fin);
+    if (!writev_consumes_all_data_) {
+      consumed =
+          QuicSession::WritevData(id, write_length, offset, state, type, level);
+    }
+    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
+        id, consumed.bytes_consumed);
+    return consumed;
+  }
+
+  void set_writev_consumes_all_data(bool val) {
+    writev_consumes_all_data_ = val;
+  }
+
+  QuicConsumedData SendStreamData(QuicStream* stream) {
+    if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
+                                     stream->id()) &&
+        connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
+    QuicConsumedData consumed =
+        WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
+                   GetEncryptionLevelToSendApplicationData());
+    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
+        consumed.bytes_consumed);
+    return consumed;
+  }
+
+  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
+    QUICHE_DCHECK(writev_consumes_all_data_);
+    return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
+                      GetEncryptionLevelToSendApplicationData());
+  }
+
+  bool ShouldNegotiateWebTransport() override { return supports_webtransport_; }
+  void set_supports_webtransport(bool value) { supports_webtransport_ = value; }
+
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    return local_http_datagram_support_;
+  }
+  void set_local_http_datagram_support(HttpDatagramSupport value) {
+    local_http_datagram_support_ = value;
+  }
+
+  MOCK_METHOD(void, OnAcceptChFrame, (const AcceptChFrame&), (override));
+
+  using QuicSession::closed_streams;
+  using QuicSession::ShouldKeepConnectionAlive;
+  using QuicSpdySession::ProcessPendingStream;
+  using QuicSpdySession::UsesPendingStreamForFrame;
+
+ private:
+  StrictMock<TestCryptoStream> crypto_stream_;
+
+  bool writev_consumes_all_data_;
+  bool supports_webtransport_ = false;
+  HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
+};
+
+class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAMS_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  explicit QuicSpdySessionTestBase(Perspective perspective,
+                                   bool allow_extended_connect)
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_, &alarm_factory_, perspective,
+            SupportedVersions(GetParam()))),
+        session_(connection_) {
+    if (perspective == Perspective::IS_SERVER &&
+        VersionUsesHttp3(transport_version()) &&
+        GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+      session_.set_allow_extended_connect(allow_extended_connect);
+    }
+    session_.Initialize();
+    session_.config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session_.config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (VersionUsesHttp3(transport_version())) {
+      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+          session_.config(), kHttp3StaticUnidirectionalStreamCount);
+    }
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    session_.OnConfigNegotiated();
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .Times(testing::AnyNumber());
+    writer_ = static_cast<MockPacketWriter*>(
+        QuicConnectionPeer::GetWriter(session_.connection()));
+  }
+
+  void CheckClosedStreams() {
+    QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        transport_version(), Perspective::IS_CLIENT);
+    if (!QuicVersionUsesCryptoFrames(transport_version())) {
+      first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
+    }
+    for (QuicStreamId i = first_stream_id; i < 100; i++) {
+      if (closed_streams_.find(i) == closed_streams_.end()) {
+        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
+      } else {
+        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
+      }
+    }
+  }
+
+  void CloseStream(QuicStreamId id) {
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    } else {
+      // IETF QUIC has two frames, RST_STREAM and STOP_SENDING
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .Times(2)
+          .WillRepeatedly(Invoke(&ClearControlFrame));
+    }
+    EXPECT_CALL(*connection_, OnStreamReset(id, _));
+
+    // QPACK streams might write data upon stream reset. Let the test session
+    // handle the data.
+    session_.set_writev_consumes_all_data(true);
+
+    session_.ResetStream(id, QUIC_STREAM_CANCELLED);
+    closed_streams_.insert(id);
+  }
+
+  ParsedQuicVersion version() const { return connection_->version(); }
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return GetNthServerInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId IdDelta() {
+    return QuicUtils::StreamIdDelta(transport_version());
+  }
+
+  std::string EncodeSettings(const SettingsFrame& settings) {
+    std::unique_ptr<char[]> buffer;
+    auto header_length = HttpEncoder::SerializeSettingsFrame(settings, &buffer);
+    return std::string(buffer.get(), header_length);
+  }
+
+  std::string SerializePriorityUpdateFrame(
+      const PriorityUpdateFrame& priority_update) {
+    std::unique_ptr<char[]> priority_buffer;
+    QuicByteCount priority_frame_length =
+        HttpEncoder::SerializePriorityUpdateFrame(priority_update,
+                                                  &priority_buffer);
+    return std::string(priority_buffer.get(), priority_frame_length);
+  }
+
+  // TODO(b/171463363): Remove.
+  std::string SerializeMaxPushIdFrame(PushId push_id) {
+    const QuicByteCount payload_length =
+        QuicDataWriter::GetVarInt62Len(push_id);
+
+    const QuicByteCount total_length =
+        QuicDataWriter::GetVarInt62Len(
+            static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)) +
+        QuicDataWriter::GetVarInt62Len(payload_length) +
+        QuicDataWriter::GetVarInt62Len(push_id);
+
+    std::string max_push_id_frame(total_length, '\0');
+    QuicDataWriter writer(total_length, &*max_push_id_frame.begin());
+
+    QUICHE_CHECK(writer.WriteVarInt62(
+        static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)));
+    QUICHE_CHECK(writer.WriteVarInt62(payload_length));
+    QUICHE_CHECK(writer.WriteVarInt62(push_id));
+    QUICHE_CHECK_EQ(0u, writer.remaining());
+
+    return max_push_id_frame;
+  }
+
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective, bool bidirectional) {
+    // Calculate and build up stream ID rather than use
+    // GetFirst... because the test that relies on this method
+    // needs to do the stream count where #1 is 0/1/2/3, and not
+    // take into account that stream 0 is special.
+    QuicStreamId id =
+        ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
+    if (!bidirectional) {
+      id |= 0x2;
+    }
+    if (perspective == Perspective::IS_SERVER) {
+      id |= 0x1;
+    }
+    return id;
+  }
+
+  void CompleteHandshake() {
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+          .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+    }
+    if (connection_->version().UsesTls() &&
+        connection_->perspective() == Perspective::IS_SERVER) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    }
+
+    CryptoHandshakeMessage message;
+    session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
+    testing::Mock::VerifyAndClearExpectations(writer_);
+    testing::Mock::VerifyAndClearExpectations(connection_);
+  }
+
+  void ReceiveWebTransportSettings() {
+    SettingsFrame settings;
+    settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+    settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
+    settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
+    std::string data =
+        std::string(1, kControlStream) + EncodeSettings(settings);
+    QuicStreamId control_stream_id =
+        session_.perspective() == Perspective::IS_SERVER
+            ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(),
+                                                          3)
+            : GetNthServerInitiatedUnidirectionalStreamId(transport_version(),
+                                                          3);
+    QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
+    session_.OnStreamFrame(frame);
+  }
+
+  void ReceiveWebTransportSession(WebTransportSessionId session_id) {
+    QuicStreamFrame frame(session_id, /*fin=*/false, /*offset=*/0,
+                          absl::string_view());
+    session_.OnStreamFrame(frame);
+    QuicSpdyStream* stream =
+        static_cast<QuicSpdyStream*>(session_.GetOrCreateStream(session_id));
+    QuicHeaderList headers;
+    headers.OnHeaderBlockStart();
+    headers.OnHeader(":method", "CONNECT");
+    headers.OnHeader(":protocol", "webtransport");
+    if (session_.http_datagram_support() == HttpDatagramSupport::kDraft00) {
+      headers.OnHeader("datagram-flow-id", absl::StrCat(session_id));
+    } else {
+      headers.OnHeader("sec-webtransport-http3-draft02", "1");
+    }
+    stream->OnStreamHeaderList(/*fin=*/true, 0, headers);
+    if (session_.http_datagram_support() != HttpDatagramSupport::kDraft00) {
+      stream->OnCapsule(
+          Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
+    }
+    WebTransportHttp3* web_transport =
+        session_.GetWebTransportSession(session_id);
+    ASSERT_TRUE(web_transport != nullptr);
+    spdy::SpdyHeaderBlock header_block;
+    web_transport->HeadersReceived(header_block);
+  }
+
+  void ReceiveWebTransportUnidirectionalStream(WebTransportSessionId session_id,
+                                               QuicStreamId stream_id) {
+    char buffer[256];
+    QuicDataWriter data_writer(sizeof(buffer), buffer);
+    ASSERT_TRUE(data_writer.WriteVarInt62(kWebTransportUnidirectionalStream));
+    ASSERT_TRUE(data_writer.WriteVarInt62(session_id));
+    ASSERT_TRUE(data_writer.WriteStringPiece("test data"));
+    std::string data(buffer, data_writer.length());
+    QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
+    session_.OnStreamFrame(frame);
+  }
+
+  void TestHttpDatagramSetting(HttpDatagramSupport local_support,
+                               HttpDatagramSupport remote_support,
+                               HttpDatagramSupport expected_support,
+                               bool expected_datagram_supported);
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  TestSession session_;
+  std::set<QuicStreamId> closed_streams_;
+  MockPacketWriter* writer_;
+};
+
+class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
+ protected:
+  QuicSpdySessionTestServer()
+      : QuicSpdySessionTestBase(Perspective::IS_SERVER, true) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServer,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdySessionTestServer, UsesPendingStreamsForFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                        transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_SERVER)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                              transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
+                            transport_version(), Perspective::IS_CLIENT)));
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerAddress) {
+  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
+            session_.peer_address());
+}
+
+TEST_P(QuicSpdySessionTestServer, SelfAddress) {
+  EXPECT_TRUE(session_.self_address().IsInitialized());
+}
+
+TEST_P(QuicSpdySessionTestServer, OneRttKeysAvailable) {
+  EXPECT_FALSE(session_.OneRttKeysAvailable());
+  CompleteHandshake();
+  EXPECT_TRUE(session_.OneRttKeysAvailable());
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
+  // Ensure that no streams are initially closed.
+  QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
+  }
+  for (QuicStreamId i = first_stream_id; i < 100; i++) {
+    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
+  // Both client initiated streams with smaller stream IDs are available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(0)) != nullptr);
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
+  QuicSpdyStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
+  CompleteHandshake();
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  session_.GetOrCreateStream(stream_id1);
+  session_.GetOrCreateStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateStream(stream_id2 + 4);
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // For IETF QUIC, we should be able to obtain the max allowed
+    // stream ID, the next ID should fail. Since the actual limit
+    // is not the number of open streams, we allocate the max and the max+2.
+    // Get the max allowed stream ID, this should succeed.
+    QuicStreamId stream_id = StreamCountToId(
+        QuicSessionPeer::ietf_streamid_manager(&session_)
+            ->max_incoming_bidirectional_streams(),
+        Perspective::IS_CLIENT,  // Client initates stream, allocs stream id.
+        /*bidirectional=*/true);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    stream_id =
+        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                            ->max_incoming_unidirectional_streams(),
+                        Perspective::IS_CLIENT,
+                        /*bidirectional=*/false);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(2);
+    // Get the (max allowed stream ID)++. These should all fail.
+    stream_id =
+        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                                ->max_incoming_bidirectional_streams() +
+                            1,
+                        Perspective::IS_CLIENT,
+                        /*bidirectional=*/true);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
+
+    stream_id =
+        StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                                ->max_incoming_unidirectional_streams() +
+                            1,
+                        Perspective::IS_CLIENT,
+                        /*bidirectional=*/false);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id));
+  } else {
+    QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+    session_.GetOrCreateStream(stream_id);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    EXPECT_NE(
+        nullptr,
+        session_.GetOrCreateStream(
+            stream_id +
+            IdDelta() *
+                (session_.max_open_incoming_bidirectional_streams() - 1)));
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedBidirectionalId(
+      2 * session_.MaxAvailableBidirectionalStreams() + 4);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
+}
+
+TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  }
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  // Create one stream.
+  session_.GetOrCreateStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  // Stream count is 200, GetNth... starts counting at 0, so the 200'th stream
+  // is 199. BUT actually we need to do 198 because the crypto stream (Stream
+  // ID 0) has not been registered, but GetNth... assumes that it has.
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                         GetNthClientInitiatedBidirectionalId(198)));
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+  CompleteHandshake();
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId closed_stream_id = stream2->id();
+  // Close the stream.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
+  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  std::string msg =
+      absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
+  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
+                  msg);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWrite) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  InSequence s;
+
+  // Reregister, to test the loop limit.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  // 2 will get called a second time as it didn't finish its block
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  // 4 will not get called, as we exceeded the loop limit.
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, TooLargeStreamBlocked) {
+  // STREAMS_BLOCKED frame is IETF QUIC only.
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Simualte the situation where the incoming stream count is at its limit and
+  // the peer is blocked.
+  QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
+      static_cast<QuicSession*>(&session_), QuicUtils::GetMaxStreamCount());
+  QuicStreamsBlockedFrame frame;
+  frame.stream_count = QuicUtils::GetMaxStreamCount();
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_));
+  session_.OnStreamsBlockedFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestServer, TestBatchedWrites) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.set_writev_consumes_all_data(true);
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // With two sessions blocked, we should get two write calls.  They should both
+  // go to the first stream as it will only write 6k and mark itself blocked
+  // again.
+  InSequence s;
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+
+  // We should get one more call for stream2, at which point it has used its
+  // write quota and we move over to stream 4.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  session_.OnCanWrite();
+
+  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
+  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
+  // will cede back to 4.
+  stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_CALL(*stream4, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendLargeFakeData(stream4, 6000);
+        session_.MarkConnectionLevelWriteBlocked(stream4->id());
+        session_.MarkConnectionLevelWriteBlocked(stream6->id());
+      }));
+  EXPECT_CALL(*stream6, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendStreamData(stream6);
+        session_.SendLargeFakeData(stream4, 6000);
+      }));
+  session_.OnCanWrite();
+
+  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
+  // cede and 2 should resume.
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 12000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
+  // Encryption needs to be established before data can be sent.
+  CompleteHandshake();
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
+      .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
+  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+
+  // Expect that we only send one packet, the writes from different streams
+  // should be bundled together.
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  // stream4->OnCanWrite is not called.
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Still congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // stream4->OnCanWrite is called once the connection stops being
+  // congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
+  CompleteHandshake();
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Drive packet writer manually.
+  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)).Times(0);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
+  // This tests prioritization of the crypto stream when flow control limits are
+  // reached. When CRYPTO frames are in use, there is no flow control for the
+  // crypto handshake, so this test is irrelevant.
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return;
+  }
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
+
+  // Test that blocking other streams does not change our status.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream3->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  // Blocking (due to buffering of) the Crypto stream is detected.
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetCryptoStreamId(transport_version()));
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  InSequence s;
+  // Force most streams to re-register, which is common scenario when we block
+  // the Crypto stream, and only the crypto stream can "really" write.
+
+  // Due to prioritization, we *should* be asked to write the crypto stream
+  // first.
+  // Don't re-register the crypto stream (which signals complete writing).
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
+    session_.SendStreamData(stream3);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
+}
+
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  CloseStream(stream6->id());
+
+  InSequence s;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+  CompleteHandshake();
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+
+  // Mark the crypto and headers streams as write blocked, we expect them to be
+  // allowed to write later.
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    session_.MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetCryptoStreamId(transport_version()));
+  }
+
+  // Create a data stream, and although it is write blocked we never expect it
+  // to be allowed to write as we are connection level flow control blocked.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream->id());
+  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
+
+  // The crypto and headers streams should be called even though we are
+  // connection flow control blocked.
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    TestHeadersStream* headers_stream;
+    QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+    headers_stream = new TestHeadersStream(&session_);
+    QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+    session_.MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetHeadersStreamId(transport_version()));
+    EXPECT_CALL(*headers_stream, OnCanWrite());
+  }
+
+  // After the crypto and header streams perform a write, the connection will be
+  // blocked by the flow control, hence it should become application-limited.
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendGoAway) {
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY has different semantic and thus has its own test.
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  const QuicStreamId kTestStreamId = 5u;
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  EXPECT_CALL(*connection_,
+              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
+      .Times(0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+}
+
+TEST_P(QuicSpdySessionTestServer, SendGoAwayWithoutEncryption) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY has different semantic and thus has its own test.
+    return;
+  }
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_PEER_GOING_AWAY, "Going Away.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_FALSE(session_.goaway_sent());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendHttp3GoAway) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Send max stream id (currently 32 bits).
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  // New incoming stream is not reset.
+  const QuicStreamId kTestStreamId =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  EXPECT_CALL(*connection_, OnStreamReset(kTestStreamId, _)).Times(0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+
+  // No more GOAWAY frames are sent because they could not convey new
+  // information to the client.
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+}
+
+TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayWithoutEncryption) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_PEER_GOING_AWAY, "Goaway",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+  EXPECT_FALSE(session_.goaway_sent());
+}
+
+TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId kTestStreamId =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Send max stream id (currently 32 bits).
+  EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+  EXPECT_TRUE(session_.goaway_sent());
+
+  // No more GOAWAY frames are sent because they could not convey new
+  // information to the client.
+  session_.SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
+}
+
+TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY doesn't have such restriction.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.goaway_sent());
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // HTTP/3 GOAWAY has different semantics and thus has its own test.
+    return;
+  }
+  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
+                          session_.next_outgoing_bidirectional_stream_id(), "");
+  session_.OnGoAway(go_away);
+}
+
+TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.goaway_received());
+  PushId push_id1 = 0;
+  session_.OnHttp3GoAway(push_id1);
+  EXPECT_TRUE(session_.goaway_received());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+          "GOAWAY received with ID 1 greater than previously received ID 0",
+          _));
+  PushId push_id2 = 1;
+  session_.OnHttp3GoAway(push_id2);
+}
+
+// Test that server session will send a connectivity probe in response to a
+// connectivity probe on the same path.
+TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicSocketAddress old_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+
+  QuicSocketAddress new_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
+
+    EXPECT_CALL(*connection_,
+                SendConnectivityProbingPacket(nullptr, new_peer_address));
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Need to explicitly do this to emulate the reception of a PathChallenge,
+    // which stores its payload for use in generating the response.
+    connection_->OnPathChallengeFrame(
+        QuicPathChallengeFrame(0, {{0, 1, 2, 3, 4, 5, 6, 7}}));
+  }
+  session_.OnPacketReceived(session_.self_address(), new_peer_address,
+                            /*is_connectivity_probe=*/true);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+}
+
+TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+  CompleteHandshake();
+  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+}
+
+TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
+  CompleteHandshake();
+  // Send two bytes of payload.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For version99, OnStreamReset gets called because of the STOP_SENDING,
+    // below. EXPECT the call there.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0), _));
+  }
+
+  // In HTTP/3, Qpack stream will send data on stream reset and cause packet to
+  // be flushed.
+  if (VersionUsesHttp3(transport_version())) {
+    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+        .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  session_.OnRstStream(rst1);
+
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId,
+                                      GetNthClientInitiatedBidirectionalId(0),
+                                      QUIC_ERROR_PROCESSING_STREAM);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_ERROR_PROCESSING_STREAM));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  // Connection should remain alive.
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
+  QuicStreamId id;
+  // Initialize HTTP/3 control stream.
+  if (VersionUsesHttp3(transport_version())) {
+    id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+    char type[] = {kControlStream};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+  } else {
+    id = QuicUtils::GetHeadersStreamId(transport_version());
+  }
+
+  // Send two bytes of payload.
+  QuicStreamFrame data1(id, true, 0, absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
+  QuicStreamId id;
+  QuicErrorCode expected_error;
+  std::string error_message;
+  // Initialize HTTP/3 control stream.
+  if (VersionUsesHttp3(transport_version())) {
+    id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+    char type[] = {kControlStream};
+
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+    expected_error = QUIC_HTTP_CLOSED_CRITICAL_STREAM;
+    error_message = "RESET_STREAM received for receive control stream";
+  } else {
+    id = QuicUtils::GetHeadersStreamId(transport_version());
+    expected_error = QUIC_INVALID_STREAM_ID;
+    error_message = "Attempt to reset headers stream";
+  }
+
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(kInvalidControlFrameId, id,
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(expected_error, error_message,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(QuicUtils::GetInvalidStreamId(transport_version()),
+                        true, 0, absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          QuicUtils::GetInvalidStreamId(transport_version()),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test requires Google QUIC crypto because it assumes streams start
+    // off unblocked.
+    return;
+  }
+  // Test that if a stream is flow control blocked, then on receipt of the SHLO
+  // containing a suitable send window offset, the stream becomes unblocked.
+
+  // Ensure that Writev consumes all the data it is given (simulate no socket
+  // blocking).
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+  session_.set_writev_consumes_all_data(true);
+
+  // Create a stream, and send enough data to make it flow control blocked.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(kMinimumFlowControlSendWindow, '.');
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
+  stream2->WriteOrBufferBody(body, false);
+  EXPECT_TRUE(stream2->IsFlowControlBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CompleteHandshake();
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+#if !defined(OS_IOS)
+// This test is failing flakily for iOS bots.
+// http://crbug.com/425050
+// NOTE: It's not possible to use the standard MAYBE_ convention to disable
+// this test on iOS because when this test gets instantiated it ends up with
+// various names that are dependent on the parameters passed.
+TEST_P(QuicSpdySessionTestServer,
+       HandshakeUnblocksFlowControlBlockedHeadersStream) {
+  // This test depends on stream-level flow control for the crypto stream, which
+  // doesn't exist when CRYPTO frames are used.
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return;
+  }
+
+  // This test depends on the headers stream, which does not exist when QPACK is
+  // used.
+  if (VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  // Test that if the header stream is flow control blocked, then if the SHLO
+  // contains a larger send window offset, the stream becomes unblocked.
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+  session_.set_writev_consumes_all_data(true);
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  QuicStreamId stream_id = 5;
+  // Write until the header stream is flow control blocked.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  SpdyHeaderBlock headers;
+  SimpleRandom random;
+  while (!headers_stream->IsFlowControlBlocked() && stream_id < 2000) {
+    EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+    EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+    headers["header"] = absl::StrCat(random.RandUint64(), random.RandUint64(),
+                                     random.RandUint64());
+    session_.WriteHeadersOnHeadersStream(stream_id, headers.Clone(), true,
+                                         spdy::SpdyStreamPrecedence(0),
+                                         nullptr);
+    stream_id += IdDelta();
+  }
+  // Write once more to ensure that the headers stream has buffered data. The
+  // random headers may have exactly filled the flow control window.
+  session_.WriteHeadersOnHeadersStream(stream_id, std::move(headers), true,
+                                       spdy::SpdyStreamPrecedence(0), nullptr);
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+
+  EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+  EXPECT_FALSE(session_.HasDataToWrite());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CompleteHandshake();
+
+  // Stream is now unblocked and will no longer have buffered data.
+  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
+      &session_, QuicUtils::GetHeadersStreamId(transport_version())));
+}
+#endif  // !defined(OS_IOS)
+
+TEST_P(QuicSpdySessionTestServer,
+       ConnectionFlowControlAccountingRstOutOfOrder) {
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  CompleteHandshake();
+  // Test that when we receive an out of order stream RST we correctly adjust
+  // our connection level flow control receive window.
+  // On close, the stream should mark as consumed all bytes between the highest
+  // byte consumed so far and the final byte offset from the RST frame.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      1 + kInitialSessionFlowControlWindowForTest / 2;
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For version99 the call to OnStreamReset happens as a result of receiving
+    // the STOP_SENDING, so set up the EXPECT there.
+    EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+  } else {
+    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+        .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  }
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
+  // one-way close.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream->id(),
+                                      QUIC_STREAM_CANCELLED);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream->id(), QUIC_STREAM_CANCELLED));
+    EXPECT_CALL(*connection_, SendControlFrame(_));
+    session_.OnStopSendingFrame(stop_sending);
+  }
+
+  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+  if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
+    // IETF Quic doesn't require a minimum flow control window.
+    return;
+  }
+  // Test that receipt of an invalid (< default) stream flow control window from
+  // the peer results in the connection being torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
+                                                            kInvalidWindow);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+  QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          _, "new unidirectional limit 2 decreases the current limit: 3", _));
+  session_.OnConfigNegotiated();
+}
+
+// Test negotiation of custom server initial flow control window.
+TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
+  QuicTagVector copt;
+  copt.push_back(kIFW7);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
+                             session_.flow_controller()));
+}
+
+TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
+  if (VersionUsesHttp3(transport_version())) {
+    // The test relies on headers stream, which no longer exists in IETF QUIC.
+    return;
+  }
+
+  // Test that a flow control blocked headers stream gets unblocked on recipt of
+  // a WINDOW_UPDATE frame.
+
+  // Set the headers stream to be flow control blocked.
+  QuicHeadersStream* headers_stream =
+      QuicSpdySessionPeer::GetHeadersStream(&session_);
+  QuicStreamPeer::SetSendWindowOffset(headers_stream, 0);
+  EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Unblock the headers stream by supplying a WINDOW_UPDATE.
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId,
+                                            headers_stream->id(),
+                                            2 * kMinimumFlowControlSendWindow);
+  session_.OnWindowUpdateFrame(window_update_frame);
+  EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       TooManyUnfinishedStreamsCauseServerRejectStream) {
+  // If a buggy/malicious peer creates too many streams that are not ended
+  // with a FIN or RST then we send an RST to refuse streams for versions other
+  // than version 99. In version 99 the connection gets closed.
+  CompleteHandshake();
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+  // GetNth assumes that both the crypto and header streams have been
+  // open, but the stream id manager, using GetFirstBidirectional... only
+  // assumes that the crypto stream is open. This means that GetNth...(0)
+  // Will return stream ID == 8 (with id ==0 for crypto and id==4 for headers).
+  // It also means that GetNth(kMax..=5) returns 28 (streams 0/1/2/3/4 are ids
+  // 8, 12, 16, 20, 24, respectively, so stream#5 is stream id 28).
+  // However, the stream ID manager does not assume stream 4 is for headers.
+  // The ID manager would assume that stream#5 is streamid 24.
+  // In order to make this all work out properly, kFinalStreamId will
+  // be set to GetNth...(kMaxStreams-1)... but only for IETF QUIC
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams);
+  // Create kMaxStreams data streams, and close them all without receiving a
+  // FIN or a RST_STREAM from the client.
+  const QuicStreamId kNextId = QuicUtils::StreamIdDelta(transport_version());
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) {
+    QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    CloseStream(i);
+  }
+  // Try and open a stream that exceeds the limit.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // On versions other than 99, opening such a stream results in a
+    // RST_STREAM.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+    EXPECT_CALL(*connection_,
+                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+        .Times(1);
+  } else {
+    // On version 99 opening such a stream results in a connection close.
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID,
+                        testing::MatchesRegex(
+                            "Stream id \\d+ would exceed stream count limit 5"),
+                        _));
+  }
+  // Create one more data streams to exceed limit of open stream.
+  QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Simulate receiving a config. so that MAX_STREAMS/etc frames may
+    // be transmitted
+    QuicSessionPeer::set_is_configured(&session_, true);
+    // Version 99 will result in a MAX_STREAMS frame as streams are consumed
+    // (via the OnStreamFrame call) and then released (via
+    // StreamDraining). Eventually this node will believe that the peer is
+    // running low on available stream ids and then send a MAX_STREAMS frame,
+    // caught by this EXPECT_CALL.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+
+  // Create kMaxStreams + 1 data streams, and mark them draining.
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams + 1);
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) {
+    QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+    session_.StreamDraining(i, /*unidirectional=*/false);
+    EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  }
+}
+
+// TODO(b/171463363): Remove.
+TEST_P(QuicSpdySessionTestServer, ReduceMaxPushId) {
+  if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
+    return;
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Use an arbitrary stream id for incoming control stream.
+  QuicStreamId stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(stream_id, false, offset, stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  SettingsFrame settings;
+  std::string settings_frame = EncodeSettings(settings);
+  QuicStreamFrame data2(stream_id, false, offset, settings_frame);
+  offset += settings_frame.length();
+
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  session_.OnStreamFrame(data2);
+
+  std::string max_push_id_frame1 = SerializeMaxPushIdFrame(/* push_id = */ 3);
+  QuicStreamFrame data3(stream_id, false, offset, max_push_id_frame1);
+  offset += max_push_id_frame1.length();
+
+  EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
+  session_.OnStreamFrame(data3);
+
+  std::string max_push_id_frame2 = SerializeMaxPushIdFrame(/* push_id = */ 1);
+  QuicStreamFrame data4(stream_id, false, offset, max_push_id_frame2);
+
+  EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_INVALID_MAX_PUSH_ID,
+                              "MAX_PUSH_ID received with value 1 which is "
+                              "smaller that previously received value 3",
+                              _));
+  session_.OnStreamFrame(data4);
+}
+
+class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
+ protected:
+  QuicSpdySessionTestClient()
+      : QuicSpdySessionTestBase(Perspective::IS_CLIENT, false) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestClient,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdySessionTestClient, UsesPendingStreamsForFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                        transport_version(), Perspective::IS_SERVER)));
+  EXPECT_TRUE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_SERVER)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                            transport_version(), Perspective::IS_CLIENT)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
+                              transport_version(), Perspective::IS_SERVER)));
+  EXPECT_FALSE(session_.UsesPendingStreamForFrame(
+      RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
+                            transport_version(), Perspective::IS_SERVER)));
+}
+
+// Regression test for crbug.com/977581.
+TEST_P(QuicSpdySessionTestClient, BadStreamFramePendingStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  QuicStreamId stream_id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  // A bad stream frame with no data and no fin.
+  QuicStreamFrame data1(stream_id1, false, 0, 0);
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestClient, PendingStreamKeepsConnectionAlive) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_SERVER);
+
+  QuicStreamFrame frame(stream_id, false, 1, "test");
+  EXPECT_FALSE(session_.ShouldKeepConnectionAlive());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_TRUE(session_.ShouldKeepConnectionAlive());
+}
+
+TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
+  // Both server initiated streams with smaller stream IDs should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
+  // And client initiated stream ID should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(0)));
+}
+
+// Regression test for b/130740258 and https://crbug.com/971779.
+// If headers that are too large or empty are received (these cases are handled
+// the same way, as QuicHeaderList clears itself when headers exceed the limit),
+// then the stream is reset.  No more frames must be sent in this case.
+TEST_P(QuicSpdySessionTestClient, TooLargeHeadersMustNotCauseWriteAfterReset) {
+  // In IETF QUIC, HEADERS do not carry FIN flag, and OnStreamHeaderList() is
+  // never called after an error, including too large headers.
+  if (VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Write headers with FIN set to close write side of stream.
+  // Header block does not matter.
+  stream->WriteHeaders(SpdyHeaderBlock(), /* fin = */ true, nullptr);
+
+  // Receive headers that are too large or empty, with FIN set.
+  // This causes the stream to be reset.  No frames must be written after this.
+  QuicHeaderList headers;
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream->id(), QUIC_HEADERS_TOO_LARGE));
+  stream->OnStreamHeaderList(/* fin = */ true,
+                             headers.uncompressed_header_bytes(), headers);
+}
+
+TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_closed_streams_highest_offset_ (which will never be deleted).
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+
+  // Close the read side manually.
+  QuicStreamPeer::CloseReadSide(stream);
+
+  // Receive a stream data frame with FIN.
+  QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(stream->fin_received());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  EXPECT_TRUE(connection_->connected());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
+  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
+
+  // The stream is not waiting for the arrival of the peer's final offset as it
+  // was received with the FIN earlier.
+  EXPECT_EQ(
+      0u,
+      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
+}
+
+TEST_P(QuicSpdySessionTestClient, WritePriority) {
+  if (VersionUsesHttp3(transport_version())) {
+    // IETF QUIC currently doesn't support PRIORITY.
+    return;
+  }
+  CompleteHandshake();
+
+  TestHeadersStream* headers_stream;
+  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+  headers_stream = new TestHeadersStream(&session_);
+  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+
+  // Make packet writer blocked so |headers_stream| will buffer its write data.
+  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
+
+  const QuicStreamId id = 4;
+  const QuicStreamId parent_stream_id = 9;
+  const SpdyPriority priority = kV3HighestPriority;
+  const bool exclusive = true;
+  session_.WritePriority(id, parent_stream_id,
+                         Spdy3PriorityToHttp2Weight(priority), exclusive);
+
+  QuicStreamSendBuffer& send_buffer =
+      QuicStreamPeer::SendBuffer(headers_stream);
+  ASSERT_EQ(1u, send_buffer.size());
+
+  SpdyPriorityIR priority_frame(
+      id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive);
+  SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
+  SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame);
+
+  const quiche::QuicheMemSlice& slice =
+      QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
+  EXPECT_EQ(absl::string_view(frame.data(), frame.size()),
+            absl::string_view(slice.data(), slice.length()));
+}
+
+TEST_P(QuicSpdySessionTestClient, Http3ServerPush) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  // Push unidirectional stream is type 0x01.
+  std::string frame_type1 = absl::HexStringToBytes("01");
+  QuicStreamId stream_id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
+      .Times(1);
+  session_.OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false,
+                                         /* offset = */ 0, frame_type1));
+}
+
+TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  // Push unidirectional stream is type 0x01.
+  std::string frame_type = absl::HexStringToBytes("01");
+  // The first field of a push stream is the Push ID.
+  std::string push_id = absl::HexStringToBytes("4000");
+
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  QuicStreamFrame data1(stream_id,
+                        /* fin = */ false, /* offset = */ 0, frame_type);
+  QuicStreamFrame data2(stream_id,
+                        /* fin = */ false, /* offset = */ frame_type.size(),
+                        push_id);
+
+  // Receiving some stream data without stream type does not open the stream.
+  session_.OnStreamFrame(data2);
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
+      .Times(1);
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
+  CompleteHandshake();
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+  // Lost data on cryption stream, streams 2 and 4.
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(true));
+  }
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    QuicStreamFrame frame1(QuicUtils::GetCryptoStreamId(transport_version()),
+                           false, 0, 1300);
+    session_.OnFrameLost(QuicFrame(frame1));
+  } else {
+    QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
+    session_.OnFrameLost(QuicFrame(&crypto_frame));
+  }
+  session_.OnFrameLost(QuicFrame(frame2));
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Mark streams 2 and 4 write blocked.
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // Lost data is retransmitted before new data, and retransmissions for crypto
+  // stream go first.
+  // Do not check congestion window when crypto stream has lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(false));
+  }
+  // Check congestion window for non crypto streams.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+  // Connection is blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Unblock connection.
+  // Stream 2 retransmits lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  // Stream 2 sends new data.
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
+  // Resetting a stream will send a QPACK Stream Cancellation instruction on the
+  // decoder stream.  For simplicity, ignore writes on this stream.
+  CompleteHandshake();
+  NoopQpackStreamSenderDelegate qpack_stream_sender_delegate;
+  if (VersionUsesHttp3(transport_version())) {
+    session_.qpack_decoder()->set_qpack_stream_sender_delegate(
+        &qpack_stream_sender_delegate);
+  }
+
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  session_.OnFrameLost(QuicFrame(frame2));
+  session_.OnFrameLost(QuicFrame(frame1));
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  // Reset stream 4 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 4 is removed from streams with lost data list.
+  EXPECT_CALL(*stream6, OnCanWrite());
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
+  CompleteHandshake();
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendWindowUpdate(stream2->id(), 9);
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1));
+  frames.push_back(QuicFrame(window_update));
+  frames.push_back(QuicFrame(frame2));
+  frames.push_back(QuicFrame(frame3));
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+  session_.OnPriorityFrame(stream_id,
+                           spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
+            stream->precedence());
+}
+
+TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // Send SETTINGS frame.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  session_.OnStreamFrame(data2);
+
+  // PRIORITY_UPDATE frame for first request stream.
+  const QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  struct PriorityUpdateFrame priority_update1;
+  priority_update1.prioritized_element_type = REQUEST_STREAM;
+  priority_update1.prioritized_element_id = stream_id1;
+  priority_update1.priority_field_value = "u=2";
+  std::string serialized_priority_update1 =
+      SerializePriorityUpdateFrame(priority_update1);
+  QuicStreamFrame data3(receive_control_stream_id,
+                        /* fin = */ false, offset, serialized_priority_update1);
+  offset += serialized_priority_update1.size();
+
+  // PRIORITY_UPDATE frame arrives after stream creation.
+  TestStream* stream1 = session_.CreateIncomingStream(stream_id1);
+  EXPECT_EQ(QuicStream::kDefaultUrgency,
+            stream1->precedence().spdy3_priority());
+  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update1));
+  session_.OnStreamFrame(data3);
+  EXPECT_EQ(2u, stream1->precedence().spdy3_priority());
+
+  // PRIORITY_UPDATE frame for second request stream.
+  const QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  struct PriorityUpdateFrame priority_update2;
+  priority_update2.prioritized_element_type = REQUEST_STREAM;
+  priority_update2.prioritized_element_id = stream_id2;
+  priority_update2.priority_field_value = "u=2";
+  std::string serialized_priority_update2 =
+      SerializePriorityUpdateFrame(priority_update2);
+  QuicStreamFrame stream_frame3(receive_control_stream_id,
+                                /* fin = */ false, offset,
+                                serialized_priority_update2);
+
+  // PRIORITY_UPDATE frame arrives before stream creation,
+  // priority value is buffered.
+  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update2));
+  session_.OnStreamFrame(stream_frame3);
+  // Priority is applied upon stream construction.
+  TestStream* stream2 = session_.CreateIncomingStream(stream_id2);
+  EXPECT_EQ(2u, stream2->precedence().spdy3_priority());
+}
+
+TEST_P(QuicSpdySessionTestServer, SimplePendingStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  char input[] = {0x04,            // type
+                  'a', 'b', 'c'};  // data
+  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
+
+  // This is a server test with a client-initiated unidirectional stream.
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+
+  for (bool fin : {true, false}) {
+    QuicStreamFrame frame(stream_id, fin, /* offset = */ 0, payload);
+
+    // A STOP_SENDING frame is sent in response to the unknown stream type.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke([stream_id](const QuicFrame& frame) {
+          EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
+
+          const QuicStopSendingFrame& stop_sending = frame.stop_sending_frame;
+          EXPECT_EQ(stream_id, stop_sending.stream_id);
+          EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR, stop_sending.error_code);
+          EXPECT_EQ(
+              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
+              stop_sending.ietf_error_code);
+
+          return ClearControlFrame(frame);
+        }));
+    session_.OnStreamFrame(frame);
+
+    PendingStream* pending =
+        QuicSessionPeer::GetPendingStream(&session_, stream_id);
+    if (fin) {
+      // Stream is closed if FIN is received.
+      EXPECT_FALSE(pending);
+    } else {
+      ASSERT_TRUE(pending);
+      // The pending stream must ignore read data.
+      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+    }
+
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, SimplePendingStreamTypeOutOfOrderDelivery) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  char input[] = {0x04,            // type
+                  'a', 'b', 'c'};  // data
+  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
+
+  // This is a server test with a client-initiated unidirectional stream.
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+
+  for (bool fin : {true, false}) {
+    QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
+                           payload.substr(0, 1));
+    QuicStreamFrame frame2(stream_id, fin, /* offset = */ 1, payload.substr(1));
+
+    // Deliver frames out of order.
+    session_.OnStreamFrame(frame2);
+    // A STOP_SENDING frame is sent in response to the unknown stream type.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+    session_.OnStreamFrame(frame1);
+
+    PendingStream* pending =
+        QuicSessionPeer::GetPendingStream(&session_, stream_id);
+    if (fin) {
+      // Stream is closed if FIN is received.
+      EXPECT_FALSE(pending);
+    } else {
+      ASSERT_TRUE(pending);
+      // The pending stream must ignore read data.
+      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+    }
+
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       MultipleBytesPendingStreamTypeOutOfOrderDelivery) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  char input[] = {0x41, 0x00,      // type (256)
+                  'a', 'b', 'c'};  // data
+  absl::string_view payload(input, ABSL_ARRAYSIZE(input));
+
+  // This is a server test with a client-initiated unidirectional stream.
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+
+  for (bool fin : {true, false}) {
+    QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
+                           payload.substr(0, 1));
+    QuicStreamFrame frame2(stream_id, /* fin = */ false, /* offset = */ 1,
+                           payload.substr(1, 1));
+    QuicStreamFrame frame3(stream_id, fin, /* offset = */ 2, payload.substr(2));
+
+    // Deliver frames out of order.
+    session_.OnStreamFrame(frame3);
+    // The first byte does not contain the entire type varint.
+    session_.OnStreamFrame(frame1);
+    // A STOP_SENDING frame is sent in response to the unknown stream type.
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+    session_.OnStreamFrame(frame2);
+
+    PendingStream* pending =
+        QuicSessionPeer::GetPendingStream(&session_, stream_id);
+    if (fin) {
+      // Stream is closed if FIN is received.
+      EXPECT_FALSE(pending);
+    } else {
+      ASSERT_TRUE(pending);
+      // The pending stream must ignore read data.
+      EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+    }
+
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  CompleteHandshake();
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Use an arbitrary stream id.
+  QuicStreamId stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+
+  QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  SettingsFrame settings;
+  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 512;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42;
+  std::string data = EncodeSettings(settings);
+  QuicStreamFrame frame(stream_id, false, 1, absl::string_view(data));
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(qpack_encoder);
+
+  EXPECT_NE(512u, header_table->maximum_dynamic_table_capacity());
+  EXPECT_NE(5u, session_.max_outbound_header_list_size());
+  EXPECT_NE(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  session_.OnStreamFrame(frame);
+
+  EXPECT_EQ(512u, header_table->maximum_dynamic_table_capacity());
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+  EXPECT_EQ(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+}
+
+TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  // Use an arbitrary stream id.
+  QuicStreamId stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  SettingsFrame settings;
+  settings.values[10] = 2;
+  settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  std::string data = EncodeSettings(settings);
+
+  QuicStreamFrame data1(stream_id, false, 1, absl::string_view(data));
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view(type, 1));
+
+  session_.OnStreamFrame(data1);
+  EXPECT_NE(5u, session_.max_outbound_header_list_size());
+  session_.OnStreamFrame(data2);
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+}
+
+// Regression test for https://crbug.com/1009551.
+TEST_P(QuicSpdySessionTestServer, StreamClosedWhileHeaderDecodingBlocked) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string headers_payload = absl::HexStringToBytes("020080");
+  std::unique_ptr<char[]> headers_buffer;
+  QuicByteCount headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
+                                               &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+  std::string headers = absl::StrCat(headers_frame_header, headers_payload);
+  stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream->headers_decompressed());
+
+  // Stream is closed and destroyed.
+  CloseStream(stream_id);
+  session_.CleanUpClosedStreams();
+
+  // Dynamic table entry arrived on the decoder stream.
+  // The destroyed stream object must not be referenced.
+  session_.qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+}
+
+// Regression test for https://crbug.com/1011294.
+TEST_P(QuicSpdySessionTestServer, SessionDestroyedWhileHeaderDecodingBlocked) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  TestStream* stream = session_.CreateIncomingStream(stream_id);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string headers_payload = absl::HexStringToBytes("020080");
+  std::unique_ptr<char[]> headers_buffer;
+  QuicByteCount headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
+                                               &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+  std::string headers = absl::StrCat(headers_frame_header, headers_payload);
+  stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream->headers_decompressed());
+
+  // |session_| gets destoyed.  That destroys QpackDecoder, a member of
+  // QuicSpdySession (derived class), which destroys QpackDecoderHeaderTable.
+  // Then |*stream|, owned by QuicSession (base class) get destroyed, which
+  // destroys QpackProgessiveDecoder, a registered Observer of
+  // QpackDecoderHeaderTable.  This must not cause a crash.
+}
+
+TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload consists of two bytes.  The first byte is an unknown unidirectional
+  // stream type.  The second one would be the type of a push stream, but it
+  // must not be interpreted as stream type.
+  std::string payload = absl::HexStringToBytes("3f01");
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
+                        payload);
+
+  // A STOP_SENDING frame is sent in response to the unknown stream type.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+  session_.OnStreamFrame(frame);
+
+  // There are no active streams.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  // The pending stream is still around, because it did not receive a FIN.
+  PendingStream* pending =
+      QuicSessionPeer::GetPendingStream(&session_, stream_id);
+  ASSERT_TRUE(pending);
+
+  // The pending stream must ignore read data.
+  EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+
+  // If the stream frame is received again, it should be ignored.
+  session_.OnStreamFrame(frame);
+
+  // Receive RESET_STREAM.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
+                               QUIC_STREAM_CANCELLED,
+                               /* bytes_written = */ payload.size());
+
+  session_.OnRstStream(rst_frame);
+
+  // The stream is closed.
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload consists of two bytes.  The first byte is an unknown unidirectional
+  // stream type.  The second one would be the type of a push stream, but it
+  // must not be interpreted as stream type.
+  std::string payload = absl::HexStringToBytes("3f01");
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
+                        payload);
+
+  // A STOP_SENDING frame is sent in response to the unknown stream type.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
+  session_.OnStreamFrame(frame);
+
+  // The pending stream is still around, because it did not receive a FIN.
+  PendingStream* pending =
+      QuicSessionPeer::GetPendingStream(&session_, stream_id);
+  EXPECT_TRUE(pending);
+
+  // The pending stream must ignore read data.
+  EXPECT_TRUE(pending->sequencer()->ignore_read_data());
+
+  // If the stream frame is received again, it should be ignored.
+  session_.OnStreamFrame(frame);
+
+  // Receive FIN.
+  session_.OnStreamFrame(QuicStreamFrame(stream_id, /* fin = */ true,
+                                         /* offset = */ payload.size(), ""));
+
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, ResetInMiddleOfStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload is the first byte of a two byte varint encoding.
+  std::string payload = absl::HexStringToBytes("40");
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
+                        payload);
+
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+
+  // Receive RESET_STREAM.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
+                               QUIC_STREAM_CANCELLED,
+                               /* bytes_written = */ payload.size());
+
+  session_.OnRstStream(rst_frame);
+
+  // The stream is closed.
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, FinInMiddleOfStreamType) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  const QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  ASSERT_TRUE(session_.UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
+
+  // Payload is the first byte of a two byte varint encoding with a FIN.
+  std::string payload = absl::HexStringToBytes("40");
+  QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload);
+
+  session_.OnStreamFrame(frame);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+}
+
+TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  QuicStreamId id1 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  char type1[] = {kControlStream};
+
+  QuicStreamFrame data1(id1, false, 0, absl::string_view(type1, 1));
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id1));
+  session_.OnStreamFrame(data1);
+  QuicStreamId id2 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
+  QuicStreamFrame data2(id2, false, 0, absl::string_view(type1, 1));
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id2)).Times(0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                              "Control stream is received twice.", _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(data2),
+      "Received a duplicate Control stream: Closing connection.");
+
+  QuicStreamId id3 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 2);
+  char type2[]{kQpackEncoderStream};
+
+  QuicStreamFrame data3(id3, false, 0, absl::string_view(type2, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id3));
+  session_.OnStreamFrame(data3);
+
+  QuicStreamId id4 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame data4(id4, false, 0, absl::string_view(type2, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id4)).Times(0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                              "QPACK encoder stream is received twice.", _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(data4),
+      "Received a duplicate QPACK encoder stream: Closing connection.");
+
+  QuicStreamId id5 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 4);
+  char type3[]{kQpackDecoderStream};
+
+  QuicStreamFrame data5(id5, false, 0, absl::string_view(type3, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id5));
+  session_.OnStreamFrame(data5);
+
+  QuicStreamId id6 =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5);
+  QuicStreamFrame data6(id6, false, 0, absl::string_view(type3, 1));
+  EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id6)).Times(0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+                              "QPACK decoder stream is received twice.", _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(data6),
+      "Received a duplicate QPACK decoder stream: Closing connection.");
+}
+
+TEST_P(QuicSpdySessionTestClient, EncoderStreamError) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string data = absl::HexStringToBytes(
+      "02"    // Encoder stream.
+      "00");  // Duplicate entry 0, but no entries exist.
+
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
+                  "Encoder stream error: Invalid relative index.", _));
+  session_.OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestClient, DecoderStreamError) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string data = absl::HexStringToBytes(
+      "03"    // Decoder stream.
+      "00");  // Insert Count Increment with forbidden increment value of zero.
+
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
+                      "Decoder stream error: Invalid increment value 0.", _));
+  session_.OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestClient, InvalidHttp3GoAway) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
+                              "GOAWAY with invalid stream ID", _));
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  session_.OnHttp3GoAway(stream_id);
+}
+
+TEST_P(QuicSpdySessionTestClient, Http3GoAwayLargerIdThanBefore) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.goaway_received());
+  QuicStreamId stream_id1 =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
+  session_.OnHttp3GoAway(stream_id1);
+  EXPECT_TRUE(session_.goaway_received());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
+          "GOAWAY received with ID 4 greater than previously received ID 0",
+          _));
+  QuicStreamId stream_id2 =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+  session_.OnHttp3GoAway(stream_id2);
+}
+
+TEST_P(QuicSpdySessionTestClient, CloseConnectionOnCancelPush) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
+                        stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // First frame has to be SETTINGS.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  session_.OnStreamFrame(data2);
+
+  std::string cancel_push_frame = absl::HexStringToBytes(
+      "03"    // CANCEL_PUSH
+      "01"    // length
+      "00");  // push ID
+  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
+                        cancel_push_frame);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
+                                            "CANCEL_PUSH frame received.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_,
+              SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
+                                        "CANCEL_PUSH frame received."));
+  session_.OnStreamFrame(data3);
+}
+
+TEST_P(QuicSpdySessionTestServer, OnSetting) {
+  CompleteHandshake();
+  if (VersionUsesHttp3(transport_version())) {
+    EXPECT_EQ(std::numeric_limits<size_t>::max(),
+              session_.max_outbound_header_list_size());
+    session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
+    EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+
+    EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+        .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+    QpackEncoder* qpack_encoder = session_.qpack_encoder();
+    EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+    session_.OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12);
+    EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
+
+    QpackEncoderHeaderTable* header_table =
+        QpackEncoderPeer::header_table(qpack_encoder);
+    EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
+    session_.OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37);
+    EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
+
+    return;
+  }
+
+  EXPECT_EQ(std::numeric_limits<size_t>::max(),
+            session_.max_outbound_header_list_size());
+  session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
+  EXPECT_EQ(5u, session_.max_outbound_header_list_size());
+
+  spdy::HpackEncoder* hpack_encoder =
+      QuicSpdySessionPeer::GetSpdyFramer(&session_)->GetHpackEncoder();
+  EXPECT_EQ(4096u, hpack_encoder->CurrentHeaderTableSizeSetting());
+  session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 59);
+  EXPECT_EQ(59u, hpack_encoder->CurrentHeaderTableSizeSetting());
+}
+
+TEST_P(QuicSpdySessionTestServer, FineGrainedHpackErrorCodes) {
+  if (VersionUsesHttp3(transport_version())) {
+    // HPACK is not used in HTTP/3.
+    return;
+  }
+
+  QuicStreamId request_stream_id = 5;
+  session_.CreateIncomingStream(request_stream_id);
+
+  // Index 126 does not exist (static table has 61 entries and dynamic table is
+  // empty).
+  std::string headers_frame = absl::HexStringToBytes(
+      "000006"    // length
+      "01"        // type
+      "24"        // flags: PRIORITY | END_HEADERS
+      "00000005"  // stream_id
+      "00000000"  // stream dependency
+      "10"        // weight
+      "fe");      // payload: reference to index 126.
+  QuicStreamId headers_stream_id =
+      QuicUtils::GetHeadersStreamId(transport_version());
+  QuicStreamFrame data(headers_stream_id, false, 0, headers_frame);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HPACK_INVALID_INDEX,
+                      "SPDY framing error: HPACK_INVALID_INDEX",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data);
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  struct {
+    char type;
+    const char* error_details;
+  } kTestData[] = {
+      {kControlStream, "RESET_STREAM received for receive control stream"},
+      {kQpackEncoderStream, "RESET_STREAM received for QPACK receive stream"},
+      {kQpackDecoderStream, "RESET_STREAM received for QPACK receive stream"},
+  };
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
+    QuicStreamId stream_id =
+        GetNthClientInitiatedUnidirectionalStreamId(transport_version(), i + 1);
+    const QuicByteCount data_length = 1;
+    QuicStreamFrame data(stream_id, false, 0,
+                         absl::string_view(&kTestData[i].type, data_length));
+    session_.OnStreamFrame(data);
+
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                                              kTestData[i].error_details, _));
+
+    QuicRstStreamFrame rst(kInvalidControlFrameId, stream_id,
+                           QUIC_STREAM_CANCELLED, data_length);
+    session_.OnRstStream(rst);
+  }
+}
+
+TEST_P(QuicSpdySessionTestServer,
+       H3ControlStreamsLimitedByConnectionFlowControl) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+
+  QuicSendControlStream* send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(&session_);
+  // Mark send_control stream write blocked.
+  session_.MarkConnectionLevelWriteBlocked(send_control_stream->id());
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalSendStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QuicSendControlStream* control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(&session_);
+  ASSERT_TRUE(control_stream);
+
+  QuicStopSendingFrame stop_sending_control_stream(
+      kInvalidControlFrameId, control_stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                      "STOP_SENDING received for send control stream", _));
+  session_.OnStopSendingFrame(stop_sending_control_stream);
+
+  QpackSendStream* decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
+  ASSERT_TRUE(decoder_stream);
+
+  QuicStopSendingFrame stop_sending_decoder_stream(
+      kInvalidControlFrameId, decoder_stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                      "STOP_SENDING received for QPACK send stream", _));
+  session_.OnStopSendingFrame(stop_sending_decoder_stream);
+
+  QpackSendStream* encoder_stream =
+      QuicSpdySessionPeer::GetQpackEncoderSendStream(&session_);
+  ASSERT_TRUE(encoder_stream);
+
+  QuicStopSendingFrame stop_sending_encoder_stream(
+      kInvalidControlFrameId, encoder_stream->id(), QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+                      "STOP_SENDING received for QPACK send stream", _));
+  session_.OnStopSendingFrame(stop_sending_encoder_stream);
+}
+
+TEST_P(QuicSpdySessionTestServer, CloseConnectionOnCancelPush) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
+                        stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // First frame has to be SETTINGS.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  session_.OnStreamFrame(data2);
+
+  std::string cancel_push_frame = absl::HexStringToBytes(
+      "03"    // CANCEL_PUSH
+      "01"    // length
+      "00");  // push ID
+  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
+                        cancel_push_frame);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
+                                            "CANCEL_PUSH frame received.", _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_,
+              SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
+                                        "CANCEL_PUSH frame received."));
+  session_.OnStreamFrame(data3);
+}
+
+TEST_P(QuicSpdySessionTestServer, Http3GoAwayWhenClosingConnection) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  CompleteHandshake();
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+
+  // Create stream by receiving some data (CreateIncomingStream() would not
+  // update the session's largest peer created stream ID).
+  const size_t headers_payload_length = 10;
+  std::unique_ptr<char[]> headers_buffer;
+  QuicByteCount headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(headers_payload_length,
+                                               &headers_buffer);
+  absl::string_view headers_frame_header(headers_buffer.get(),
+                                         headers_frame_header_length);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_id, headers_payload_length));
+  session_.OnStreamFrame(
+      QuicStreamFrame(stream_id, false, 0, headers_frame_header));
+
+  EXPECT_EQ(stream_id, QuicSessionPeer::GetLargestPeerCreatedStreamId(
+                           &session_, /*unidirectional = */ false));
+
+  // Stream with stream_id is already received and potentially processed,
+  // therefore a GOAWAY frame is sent with the next stream ID.
+  EXPECT_CALL(debug_visitor,
+              OnGoAwayFrameSent(stream_id +
+                                QuicUtils::StreamIdDelta(transport_version())));
+
+  // Close connection.
+  EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(QUIC_NO_ERROR, _, _))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::ReallySendConnectionClosePacket));
+  connection_->CloseConnection(
+      QUIC_NO_ERROR, "closing connection",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+TEST_P(QuicSpdySessionTestClient, DoNotSendInitialMaxPushIdIfNotSet) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  InSequence s;
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+
+  CompleteHandshake();
+}
+
+TEST_P(QuicSpdySessionTestClient, ReceiveSpdySettingInHttp3) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  SettingsFrame frame;
+  frame.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
+  // https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-30#section-7.2.4.1
+  // specifies the presence of HTTP/2 setting as error.
+  frame.values[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 100;
+
+  CompleteHandshake();
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_RECEIVE_SPDY_SETTING, _, _));
+  session_.OnSettingsFrame(frame);
+}
+
+TEST_P(QuicSpdySessionTestClient, ReceiveAcceptChFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  // Create control stream.
+  QuicStreamId receive_control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  char type[] = {kControlStream};
+  absl::string_view stream_type(type, 1);
+  QuicStreamOffset offset = 0;
+  QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
+                        stream_type);
+  offset += stream_type.length();
+  EXPECT_CALL(debug_visitor,
+              OnPeerControlStreamCreated(receive_control_stream_id));
+
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(receive_control_stream_id,
+            QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
+
+  // First frame has to be SETTINGS.
+  std::string serialized_settings = EncodeSettings({});
+  QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
+                        serialized_settings);
+  offset += serialized_settings.length();
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+
+  session_.OnStreamFrame(data2);
+
+  // Receive ACCEPT_CH frame.
+  AcceptChFrame accept_ch;
+  accept_ch.entries.push_back({"foo", "bar"});
+  std::unique_ptr<char[]> buffer;
+  auto frame_length = HttpEncoder::SerializeAcceptChFrame(accept_ch, &buffer);
+  QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
+                        absl::string_view(buffer.get(), frame_length));
+
+  EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(accept_ch));
+  EXPECT_CALL(session_, OnAcceptChFrame(accept_ch));
+
+  session_.OnStreamFrame(data3);
+}
+
+TEST_P(QuicSpdySessionTestClient, AcceptChViaAlps) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  std::string serialized_accept_ch_frame = absl::HexStringToBytes(
+      "4089"      // type (ACCEPT_CH)
+      "08"        // length
+      "03"        // length of origin
+      "666f6f"    // origin "foo"
+      "03"        // length of value
+      "626172");  // value "bar"
+
+  AcceptChFrame expected_accept_ch_frame{{{"foo", "bar"}}};
+  EXPECT_CALL(debug_visitor,
+              OnAcceptChFrameReceivedViaAlps(expected_accept_ch_frame));
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(serialized_accept_ch_frame.data()),
+      serialized_accept_ch_frame.size());
+  EXPECT_FALSE(error);
+}
+
+TEST_P(QuicSpdySessionTestClient, AlpsForbiddenFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string forbidden_frame = absl::HexStringToBytes(
+      "00"        // type (DATA)
+      "03"        // length
+      "66666f");  // "foo"
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(forbidden_frame.data()),
+      forbidden_frame.size());
+  ASSERT_TRUE(error);
+  EXPECT_EQ("DATA frame forbidden", error.value());
+}
+
+TEST_P(QuicSpdySessionTestClient, AlpsIncompleteFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string incomplete_frame = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "03");  // non-zero length but empty payload
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(incomplete_frame.data()),
+      incomplete_frame.size());
+  ASSERT_TRUE(error);
+  EXPECT_EQ("incomplete HTTP/3 frame", error.value());
+}
+
+// After receiving a SETTINGS frame via ALPS,
+// another SETTINGS frame is still allowed on control frame.
+TEST_P(QuicSpdySessionTestClient, SettingsViaAlpsThenOnControlStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
+  EXPECT_EQ(0u, qpack_encoder->maximum_blocked_streams());
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+
+  std::string serialized_settings_frame1 = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "05"    // length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "4400"  // 0x0400 = 1024
+      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+      "20");  // 0x20 = 32
+
+  SettingsFrame expected_settings_frame1{
+      {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
+       {SETTINGS_QPACK_BLOCKED_STREAMS, 32}}};
+  EXPECT_CALL(debug_visitor,
+              OnSettingsFrameReceivedViaAlps(expected_settings_frame1));
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
+      serialized_settings_frame1.size());
+  EXPECT_FALSE(error);
+
+  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
+  EXPECT_EQ(32u, qpack_encoder->maximum_blocked_streams());
+
+  const QuicStreamId control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(control_stream_id));
+
+  std::string stream_type = absl::HexStringToBytes("00");
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ 0, stream_type));
+
+  // SETTINGS_QPACK_MAX_TABLE_CAPACITY, if advertised again, MUST have identical
+  // value.
+  // SETTINGS_QPACK_BLOCKED_STREAMS is a limit.  Limits MUST NOT be reduced, but
+  // increasing is okay.
+  SettingsFrame expected_settings_frame2{
+      {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
+       {SETTINGS_QPACK_BLOCKED_STREAMS, 48}}};
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(expected_settings_frame2));
+  std::string serialized_settings_frame2 = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "05"    // length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "4400"  // 0x0400 = 1024
+      "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
+      "30");  // 0x30 = 48
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ stream_type.length(),
+                                         serialized_settings_frame2));
+
+  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
+  EXPECT_EQ(48u, qpack_encoder->maximum_blocked_streams());
+}
+
+// A SETTINGS frame received via ALPS and another one on the control stream
+// cannot have conflicting values.
+TEST_P(QuicSpdySessionTestClient,
+       SettingsViaAlpsConflictsSettingsViaControlStream) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  QpackEncoder* qpack_encoder = session_.qpack_encoder();
+  EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
+
+  std::string serialized_settings_frame1 = absl::HexStringToBytes(
+      "04"      // type (SETTINGS)
+      "03"      // length
+      "01"      // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "4400");  // 0x0400 = 1024
+
+  auto error = session_.OnAlpsData(
+      reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
+      serialized_settings_frame1.size());
+  EXPECT_FALSE(error);
+
+  EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
+
+  const QuicStreamId control_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
+
+  std::string stream_type = absl::HexStringToBytes("00");
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ 0, stream_type));
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+                      "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: "
+                      "32 while current value is: 1024",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  std::string serialized_settings_frame2 = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "02"    // length
+      "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
+      "20");  // 0x20 = 32
+  session_.OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
+                                         /* offset = */ stream_type.length(),
+                                         serialized_settings_frame2));
+}
+
+TEST_P(QuicSpdySessionTestClient, AlpsTwoSettingsFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  std::string banned_frame = absl::HexStringToBytes(
+      "04"    // type (SETTINGS)
+      "00"    // length
+      "04"    // type (SETTINGS)
+      "00");  // length
+
+  auto error =
+      session_.OnAlpsData(reinterpret_cast<const uint8_t*>(banned_frame.data()),
+                          banned_frame.size());
+  ASSERT_TRUE(error);
+  EXPECT_EQ("multiple SETTINGS frames", error.value());
+}
+
+void QuicSpdySessionTestBase::TestHttpDatagramSetting(
+    HttpDatagramSupport local_support, HttpDatagramSupport remote_support,
+    HttpDatagramSupport expected_support, bool expected_datagram_supported) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(local_support);
+  // HTTP/3 datagrams aren't supported before SETTINGS are received.
+  EXPECT_FALSE(session_.SupportsH3Datagram());
+  EXPECT_EQ(session_.http_datagram_support(), HttpDatagramSupport::kNone);
+  // Receive SETTINGS.
+  SettingsFrame settings;
+  switch (remote_support) {
+    case HttpDatagramSupport::kNone:
+      break;
+    case HttpDatagramSupport::kDraft00:
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+      break;
+    case HttpDatagramSupport::kDraft04:
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+      break;
+    case HttpDatagramSupport::kDraft00And04:
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+      settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+      break;
+  }
+  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
+  session_.OnStreamFrame(frame);
+  EXPECT_EQ(session_.http_datagram_support(), expected_support);
+  EXPECT_EQ(session_.SupportsH3Datagram(), expected_datagram_supported);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00,
+      /*remote_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00,
+      /*remote_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_support=*/HttpDatagramSupport::kNone,
+      /*expected_datagram_supported=*/false);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00And04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00,
+      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
+      /*expected_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_support=*/HttpDatagramSupport::kNone,
+      /*expected_datagram_supported=*/false);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft04,
+      /*remote_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00And04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote00) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00And04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_support=*/HttpDatagramSupport::kDraft00,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00And04,
+      /*remote_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient,
+       HttpDatagramSettingLocal00And04Remote00And04) {
+  TestHttpDatagramSetting(
+      /*local_support=*/HttpDatagramSupport::kDraft00And04,
+      /*remote_support=*/HttpDatagramSupport::kDraft00And04,
+      /*expected_support=*/HttpDatagramSupport::kDraft04,
+      /*expected_datagram_supported=*/true);
+}
+
+TEST_P(QuicSpdySessionTestClient, WebTransportSetting) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  // Note that this does not actually fill out correct settings because the
+  // settings are filled in at the construction time.
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  session_.set_debug_visitor(&debug_visitor);
+  CompleteHandshake();
+
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(_));
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
+  ReceiveWebTransportSettings();
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+  EXPECT_TRUE(session_.SupportsWebTransport());
+}
+
+TEST_P(QuicSpdySessionTestClient, WebTransportSettingSetToZero) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  // Note that this does not actually fill out correct settings because the
+  // settings are filled in at the construction time.
+  EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+  session_.set_debug_visitor(&debug_visitor);
+  CompleteHandshake();
+
+  SettingsFrame server_settings;
+  server_settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+  server_settings.values[SETTINGS_WEBTRANS_DRAFT00] = 0;
+  std::string data =
+      std::string(1, kControlStream) + EncodeSettings(server_settings);
+  QuicStreamId stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
+  EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
+  EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(server_settings));
+  session_.OnStreamFrame(frame);
+  EXPECT_FALSE(session_.SupportsWebTransport());
+}
+
+TEST_P(QuicSpdySessionTestServer, WebTransportSetting) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_FALSE(session_.ShouldProcessIncomingRequests());
+
+  CompleteHandshake();
+
+  ReceiveWebTransportSettings();
+  EXPECT_TRUE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreams) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  CompleteHandshake();
+  QuicStreamId session_id =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+
+  QuicStreamId data_stream_id =
+      GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4);
+  ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
+
+  ReceiveWebTransportSettings();
+
+  ReceiveWebTransportSession(session_id);
+  WebTransportHttp3* web_transport =
+      session_.GetWebTransportSession(session_id);
+  ASSERT_TRUE(web_transport != nullptr);
+
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
+  EXPECT_CALL(
+      *connection_,
+      OnStreamReset(data_stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
+  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
+}
+
+TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsLimit) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  CompleteHandshake();
+  QuicStreamId session_id =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+
+  const int streams_to_send = kMaxUnassociatedWebTransportStreams + 4;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(
+                  _, QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED))
+      .Times(4);
+  for (int i = 0; i < streams_to_send; i++) {
+    QuicStreamId data_stream_id =
+        GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4 + i);
+    ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
+  }
+
+  ReceiveWebTransportSettings();
+
+  ReceiveWebTransportSession(session_id);
+  WebTransportHttp3* web_transport =
+      session_.GetWebTransportSession(session_id);
+  ASSERT_TRUE(web_transport != nullptr);
+
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(),
+            kMaxUnassociatedWebTransportStreams);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(_, _))
+      .Times(kMaxUnassociatedWebTransportStreams + 1);
+  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
+}
+
+TEST_P(QuicSpdySessionTestServer, ResetOutgoingWebTransportStreams) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  CompleteHandshake();
+  QuicStreamId session_id =
+      GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
+
+  ReceiveWebTransportSettings();
+  ReceiveWebTransportSession(session_id);
+  WebTransportHttp3* web_transport =
+      session_.GetWebTransportSession(session_id);
+  ASSERT_TRUE(web_transport != nullptr);
+
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_TRUE(web_transport->CanOpenNextOutgoingUnidirectionalStream());
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
+  WebTransportStream* stream =
+      web_transport->OpenOutgoingUnidirectionalStream();
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
+  ASSERT_TRUE(stream != nullptr);
+  QuicStreamId stream_id = stream->GetStreamId();
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
+  session_.ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
+  EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
+}
+
+TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+  session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_.set_supports_webtransport(true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  CompleteHandshake();
+
+  SettingsFrame settings;
+  settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+  settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
+  // No SETTINGS_ENABLE_CONNECT_PROTOCOL here.
+  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
+  QuicStreamId control_stream_id =
+      session_.perspective() == Perspective::IS_SERVER
+          ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
+          : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
+  session_.OnStreamFrame(frame);
+
+  EXPECT_TRUE(session_.SupportsWebTransport());
+}
+
+// Regression bug for b/208997000.
+TEST_P(QuicSpdySessionTestClient, LimitEncoderDynamicTableSize) {
+  if (version().UsesHttp3()) {
+    return;
+  }
+  CompleteHandshake();
+
+  QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
+  TestHeadersStream* headers_stream =
+      new StrictMock<TestHeadersStream>(&session_);
+  QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+  session_.MarkConnectionLevelWriteBlocked(headers_stream->id());
+
+  // Peer sends very large value.
+  session_.OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 1024 * 1024 * 1024);
+
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";  // entry with index 2 in HPACK static table
+  stream->WriteHeaders(std::move(headers), /* fin = */ true, nullptr);
+
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+  QuicStreamSendBuffer& send_buffer =
+      QuicStreamPeer::SendBuffer(headers_stream);
+  ASSERT_EQ(1u, send_buffer.size());
+
+  const quiche::QuicheMemSlice& slice =
+      QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
+  absl::string_view stream_data(slice.data(), slice.length());
+
+  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+    EXPECT_EQ(absl::HexStringToBytes(
+                  "000009"  // frame length
+                  "01"      // frame type HEADERS
+                  "25"),    // flags END_STREAM | END_HEADERS | PRIORITY
+              stream_data.substr(0, 5));
+    stream_data.remove_prefix(5);
+  } else {
+    EXPECT_EQ(absl::HexStringToBytes(
+                  "00000c"  // frame length
+                  "01"      // frame type HEADERS
+                  "25"),    // flags END_STREAM | END_HEADERS | PRIORITY
+              stream_data.substr(0, 5));
+    stream_data.remove_prefix(5);
+  }
+
+  // Ignore stream ID as it might differ between QUIC versions.
+  stream_data.remove_prefix(4);
+
+  // Ignore stream dependency and weight.
+  EXPECT_EQ(absl::HexStringToBytes("00000000"  // stream dependency
+                                   "92"),      // stream weight
+            stream_data.substr(0, 5));
+  stream_data.remove_prefix(5);
+
+  if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
+    EXPECT_EQ(absl::HexStringToBytes(
+                  "3fe17f"  // Dynamic Table Size Update to 16384
+                  "82"),    // Indexed Header Field Representation with index 2
+              stream_data);
+  } else {
+    EXPECT_EQ(
+        absl::HexStringToBytes(
+            "3fe1ffffff03"  // Dynamic Table Size Update to 1024 * 1024 * 1024
+            "82"),          // Indexed Header Field Representation with index 2
+        stream_data);
+  }
+}
+
+class QuicSpdySessionTestServerNoExtendedConnect
+    : public QuicSpdySessionTestBase {
+ public:
+  QuicSpdySessionTestServerNoExtendedConnect()
+      : QuicSpdySessionTestBase(Perspective::IS_SERVER, false) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServerNoExtendedConnect,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Tests that receiving SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 doesn't enable
+// server session to support extended CONNECT.
+TEST_P(QuicSpdySessionTestServerNoExtendedConnect,
+       WebTransportSettingNoEffect) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+
+  CompleteHandshake();
+
+  ReceiveWebTransportSettings();
+  EXPECT_FALSE(session_.allow_extended_connect());
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+}
+
+TEST_P(QuicSpdySessionTestServerNoExtendedConnect, BadExtendedConnectSetting) {
+  if (!version().UsesHttp3()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_verify_request_headers_2, true);
+  SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
+
+  EXPECT_FALSE(session_.SupportsWebTransport());
+  EXPECT_TRUE(session_.ShouldProcessIncomingRequests());
+
+  CompleteHandshake();
+
+  // ENABLE_CONNECT_PROTOCOL setting value has to be 1 or 0;
+  SettingsFrame settings;
+  settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 2;
+  std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
+  QuicStreamId control_stream_id =
+      session_.perspective() == Perspective::IS_SERVER
+          ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
+          : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
+  QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_INVALID_SETTING_VALUE, _, _));
+  EXPECT_QUIC_PEER_BUG(
+      session_.OnStreamFrame(frame),
+      "Received SETTINGS_ENABLE_CONNECT_PROTOCOL with invalid value");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream.cc b/quiche/quic/core/http/quic_spdy_stream.cc
new file mode 100644
index 0000000..82077cd
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream.cc
@@ -0,0 +1,1942 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/quic/core/http/capsule.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+
+namespace quic {
+
+// Visitor of HttpDecoder that passes data frame to QuicSpdyStream and closes
+// the connection on unexpected frames.
+class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor {
+ public:
+  explicit HttpDecoderVisitor(QuicSpdyStream* stream) : stream_(stream) {}
+  HttpDecoderVisitor(const HttpDecoderVisitor&) = delete;
+  HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
+
+  void OnError(HttpDecoder* decoder) override {
+    stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
+  }
+
+  bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Max Push Id");
+    return false;
+  }
+
+  bool OnGoAwayFrame(const GoAwayFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Goaway");
+    return false;
+  }
+
+  bool OnSettingsFrameStart(QuicByteCount /*header_length*/) override {
+    CloseConnectionOnWrongFrame("Settings");
+    return false;
+  }
+
+  bool OnSettingsFrame(const SettingsFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Settings");
+    return false;
+  }
+
+  bool OnDataFrameStart(QuicByteCount header_length,
+                        QuicByteCount payload_length) override {
+    return stream_->OnDataFrameStart(header_length, payload_length);
+  }
+
+  bool OnDataFramePayload(absl::string_view payload) override {
+    QUICHE_DCHECK(!payload.empty());
+    return stream_->OnDataFramePayload(payload);
+  }
+
+  bool OnDataFrameEnd() override { return stream_->OnDataFrameEnd(); }
+
+  bool OnHeadersFrameStart(QuicByteCount header_length,
+                           QuicByteCount payload_length) override {
+    if (!VersionUsesHttp3(stream_->transport_version())) {
+      CloseConnectionOnWrongFrame("Headers");
+      return false;
+    }
+    return stream_->OnHeadersFrameStart(header_length, payload_length);
+  }
+
+  bool OnHeadersFramePayload(absl::string_view payload) override {
+    QUICHE_DCHECK(!payload.empty());
+    if (!VersionUsesHttp3(stream_->transport_version())) {
+      CloseConnectionOnWrongFrame("Headers");
+      return false;
+    }
+    return stream_->OnHeadersFramePayload(payload);
+  }
+
+  bool OnHeadersFrameEnd() override {
+    if (!VersionUsesHttp3(stream_->transport_version())) {
+      CloseConnectionOnWrongFrame("Headers");
+      return false;
+    }
+    return stream_->OnHeadersFrameEnd();
+  }
+
+  bool OnPriorityUpdateFrameStart(QuicByteCount /*header_length*/) override {
+    CloseConnectionOnWrongFrame("Priority update");
+    return false;
+  }
+
+  bool OnPriorityUpdateFrame(const PriorityUpdateFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("Priority update");
+    return false;
+  }
+
+  bool OnAcceptChFrameStart(QuicByteCount /*header_length*/) override {
+    CloseConnectionOnWrongFrame("ACCEPT_CH");
+    return false;
+  }
+
+  bool OnAcceptChFrame(const AcceptChFrame& /*frame*/) override {
+    CloseConnectionOnWrongFrame("ACCEPT_CH");
+    return false;
+  }
+
+  void OnWebTransportStreamFrameType(
+      QuicByteCount header_length, WebTransportSessionId session_id) override {
+    stream_->OnWebTransportStreamFrameType(header_length, session_id);
+  }
+
+  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
+                           QuicByteCount payload_length) override {
+    return stream_->OnUnknownFrameStart(frame_type, header_length,
+                                        payload_length);
+  }
+
+  bool OnUnknownFramePayload(absl::string_view payload) override {
+    return stream_->OnUnknownFramePayload(payload);
+  }
+
+  bool OnUnknownFrameEnd() override { return stream_->OnUnknownFrameEnd(); }
+
+ private:
+  void CloseConnectionOnWrongFrame(absl::string_view frame_type) {
+    stream_->OnUnrecoverableError(
+        QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM,
+        absl::StrCat(frame_type, " frame received on data stream"));
+  }
+
+  QuicSpdyStream* stream_;
+};
+
+#define ENDPOINT                                                   \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                      : "Client:"  \
+                                                        " ")
+
+namespace {
+HttpDecoder::Options HttpDecoderOptionsForBidiStream(
+    QuicSpdySession* spdy_session) {
+  HttpDecoder::Options options;
+  options.allow_web_transport_stream =
+      spdy_session->WillNegotiateWebTransport();
+  return options;
+}
+}  // namespace
+
+QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
+                               StreamType type)
+    : QuicStream(id, spdy_session, /*is_static=*/false, type),
+      spdy_session_(spdy_session),
+      on_body_available_called_because_sequencer_is_closed_(false),
+      visitor_(nullptr),
+      blocked_on_decoding_headers_(false),
+      headers_decompressed_(false),
+      header_list_size_limit_exceeded_(false),
+      headers_payload_length_(0),
+      trailers_decompressed_(false),
+      trailers_consumed_(false),
+      qpack_decoded_headers_accumulator_reset_reason_(
+          QpackDecodedHeadersAccumulatorResetReason::kUnSet),
+      http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
+      decoder_(http_decoder_visitor_.get(),
+               HttpDecoderOptionsForBidiStream(spdy_session)),
+      sequencer_offset_(0),
+      is_decoder_processing_input_(false),
+      ack_listener_(nullptr),
+      last_sent_urgency_(kDefaultUrgency),
+      datagram_next_available_context_id_(spdy_session->perspective() ==
+                                                  Perspective::IS_SERVER
+                                              ? kFirstDatagramContextIdServer
+                                              : kFirstDatagramContextIdClient) {
+  QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
+  QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
+  QUICHE_DCHECK_EQ(0u, sequencer()->NumBytesConsumed());
+  // If headers are sent on the headers stream, then do not receive any
+  // callbacks from the sequencer until headers are complete.
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->SetBlockedUntilFlush();
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    sequencer()->set_level_triggered(true);
+  }
+
+  spdy_session_->OnStreamCreated(this);
+}
+
+QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
+                               QuicSpdySession* spdy_session)
+    : QuicStream(pending, spdy_session, /*is_static=*/false),
+      spdy_session_(spdy_session),
+      on_body_available_called_because_sequencer_is_closed_(false),
+      visitor_(nullptr),
+      blocked_on_decoding_headers_(false),
+      headers_decompressed_(false),
+      header_list_size_limit_exceeded_(false),
+      headers_payload_length_(0),
+      trailers_decompressed_(false),
+      trailers_consumed_(false),
+      qpack_decoded_headers_accumulator_reset_reason_(
+          QpackDecodedHeadersAccumulatorResetReason::kUnSet),
+      http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
+      decoder_(http_decoder_visitor_.get()),
+      sequencer_offset_(sequencer()->NumBytesConsumed()),
+      is_decoder_processing_input_(false),
+      ack_listener_(nullptr),
+      last_sent_urgency_(kDefaultUrgency) {
+  QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
+  QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id()));
+  // If headers are sent on the headers stream, then do not receive any
+  // callbacks from the sequencer until headers are complete.
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->SetBlockedUntilFlush();
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    sequencer()->set_level_triggered(true);
+  }
+
+  spdy_session_->OnStreamCreated(this);
+}
+
+QuicSpdyStream::~QuicSpdyStream() {}
+
+bool QuicSpdyStream::ShouldUseDatagramContexts() const {
+  return spdy_session_->SupportsH3Datagram() &&
+         spdy_session_->http_datagram_support() !=
+             HttpDatagramSupport::kDraft00 &&
+         use_datagram_contexts_;
+}
+
+size_t QuicSpdyStream::WriteHeaders(
+    SpdyHeaderBlock header_block, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (!AssertNotWebTransportDataStream("writing headers")) {
+    return 0;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+  // Send stream type for server push stream
+  if (VersionUsesHttp3(transport_version()) && type() == WRITE_UNIDIRECTIONAL &&
+      send_buffer().stream_offset() == 0) {
+    char data[sizeof(kServerPushStream)];
+    QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
+    writer.WriteVarInt62(kServerPushStream);
+
+    // Similar to frame headers, stream type byte shouldn't be exposed to upper
+    // layer applications.
+    unacked_frame_headers_offsets_.Add(0, writer.length());
+
+    QUIC_LOG(INFO) << ENDPOINT << "Stream " << id()
+                   << " is writing type as server push";
+    WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
+                      nullptr);
+  }
+
+  MaybeProcessSentWebTransportHeaders(header_block);
+
+  if (ShouldUseDatagramContexts()) {
+    // RegisterHttp3DatagramRegistrationVisitor caller wishes to use contexts,
+    // inform the peer.
+    header_block["sec-use-datagram-contexts"] = "?1";
+  }
+
+  if (web_transport_ != nullptr &&
+      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
+      spdy_session_->perspective() == Perspective::IS_SERVER) {
+    header_block["sec-webtransport-http3-draft"] = "draft02";
+  }
+
+  size_t bytes_written =
+      WriteHeadersImpl(std::move(header_block), fin, std::move(ack_listener));
+  if (!VersionUsesHttp3(transport_version()) && fin) {
+    // If HEADERS are sent on the headers stream, then |fin_sent_| needs to be
+    // set and write side needs to be closed without actually sending a FIN on
+    // this stream.
+    // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
+    SetFinSent();
+    CloseWriteSide();
+  }
+
+  if (web_transport_ != nullptr &&
+      session()->perspective() == Perspective::IS_CLIENT) {
+    // This will send a capsule and therefore needs to happen after headers have
+    // been sent.
+    RegisterHttp3DatagramContextId(
+        web_transport_->context_id(), DatagramFormatType::WEBTRANSPORT,
+        /*format_additional_data=*/absl::string_view(), web_transport_.get());
+  }
+
+  return bytes_written;
+}
+
+void QuicSpdyStream::WriteOrBufferBody(absl::string_view data, bool fin) {
+  if (!AssertNotWebTransportDataStream("writing body data")) {
+    return;
+  }
+  if (!VersionUsesHttp3(transport_version()) || data.length() == 0) {
+    WriteOrBufferData(data, fin, nullptr);
+    return;
+  }
+  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnDataFrameSent(id(), data.length());
+  }
+
+  const bool success =
+      WriteDataFrameHeader(data.length(), /*force_write=*/true);
+  QUICHE_DCHECK(success);
+
+  // Write body.
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing DATA frame payload of length "
+                  << data.length() << " with fin " << fin;
+  WriteOrBufferData(data, fin, nullptr);
+}
+
+size_t QuicSpdyStream::WriteTrailers(
+    SpdyHeaderBlock trailer_block,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (fin_sent()) {
+    QUIC_BUG(quic_bug_10410_1)
+        << "Trailers cannot be sent after a FIN, on stream " << id();
+    return 0;
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    // The header block must contain the final offset for this stream, as the
+    // trailers may be processed out of order at the peer.
+    const QuicStreamOffset final_offset =
+        stream_bytes_written() + BufferedDataBytes();
+    QUIC_DLOG(INFO) << ENDPOINT << "Inserting trailer: ("
+                    << kFinalOffsetHeaderKey << ", " << final_offset << ")";
+    trailer_block.insert(
+        std::make_pair(kFinalOffsetHeaderKey, absl::StrCat(final_offset)));
+  }
+
+  // Write the trailing headers with a FIN, and close stream for writing:
+  // trailers are the last thing to be sent on a stream.
+  const bool kFin = true;
+  size_t bytes_written =
+      WriteHeadersImpl(std::move(trailer_block), kFin, std::move(ack_listener));
+
+  // If trailers are sent on the headers stream, then |fin_sent_| needs to be
+  // set without actually sending a FIN on this stream.
+  if (!VersionUsesHttp3(transport_version())) {
+    SetFinSent();
+
+    // Also, write side of this stream needs to be closed.  However, only do
+    // this if there is no more buffered data, otherwise it will never be sent.
+    if (BufferedDataBytes() == 0) {
+      CloseWriteSide();
+    }
+  }
+
+  return bytes_written;
+}
+
+QuicConsumedData QuicSpdyStream::WritevBody(const struct iovec* iov, int count,
+                                            bool fin) {
+  quiche::QuicheMemSliceStorage storage(
+      iov, count,
+      session()->connection()->helper()->GetStreamSendBufferAllocator(),
+      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size));
+  return WriteBodySlices(storage.ToSpan(), fin);
+}
+
+bool QuicSpdyStream::WriteDataFrameHeader(QuicByteCount data_length,
+                                          bool force_write) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK_GT(data_length, 0u);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      data_length,
+      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
+  const bool can_write = CanWriteNewDataAfterData(header.size());
+  if (!can_write && !force_write) {
+    return false;
+  }
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnDataFrameSent(id(), data_length);
+  }
+
+  unacked_frame_headers_offsets_.Add(
+      send_buffer().stream_offset(),
+      send_buffer().stream_offset() + header.size());
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing DATA frame header of length "
+                  << header.size();
+  if (can_write) {
+    // Save one copy and allocation if send buffer can accomodate the header.
+    quiche::QuicheMemSlice header_slice(std::move(header));
+    WriteMemSlices(absl::MakeSpan(&header_slice, 1), false);
+  } else {
+    QUICHE_DCHECK(force_write);
+    WriteOrBufferData(header.AsStringView(), false, nullptr);
+  }
+  return true;
+}
+
+QuicConsumedData QuicSpdyStream::WriteBodySlices(
+    absl::Span<quiche::QuicheMemSlice> slices, bool fin) {
+  if (!VersionUsesHttp3(transport_version()) || slices.empty()) {
+    return WriteMemSlices(slices, fin);
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+  const QuicByteCount data_size = MemSliceSpanTotalSize(slices);
+  if (!WriteDataFrameHeader(data_size, /*force_write=*/false)) {
+    return {0, false};
+  }
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing DATA frame payload of length " << data_size;
+  return WriteMemSlices(slices, fin);
+}
+
+size_t QuicSpdyStream::Readv(const struct iovec* iov, size_t iov_len) {
+  QUICHE_DCHECK(FinishedReadingHeaders());
+  if (!VersionUsesHttp3(transport_version())) {
+    return sequencer()->Readv(iov, iov_len);
+  }
+  size_t bytes_read = 0;
+  sequencer()->MarkConsumed(body_manager_.ReadBody(iov, iov_len, &bytes_read));
+
+  return bytes_read;
+}
+
+int QuicSpdyStream::GetReadableRegions(iovec* iov, size_t iov_len) const {
+  QUICHE_DCHECK(FinishedReadingHeaders());
+  if (!VersionUsesHttp3(transport_version())) {
+    return sequencer()->GetReadableRegions(iov, iov_len);
+  }
+  return body_manager_.PeekBody(iov, iov_len);
+}
+
+void QuicSpdyStream::MarkConsumed(size_t num_bytes) {
+  QUICHE_DCHECK(FinishedReadingHeaders());
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->MarkConsumed(num_bytes);
+    return;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnBodyConsumed(num_bytes));
+}
+
+bool QuicSpdyStream::IsDoneReading() const {
+  bool done_reading_headers = FinishedReadingHeaders();
+  bool done_reading_body = sequencer()->IsClosed();
+  bool done_reading_trailers = FinishedReadingTrailers();
+  return done_reading_headers && done_reading_body && done_reading_trailers;
+}
+
+bool QuicSpdyStream::HasBytesToRead() const {
+  if (!VersionUsesHttp3(transport_version())) {
+    return sequencer()->HasBytesToRead();
+  }
+  return body_manager_.HasBytesToRead();
+}
+
+void QuicSpdyStream::MarkTrailersConsumed() { trailers_consumed_ = true; }
+
+uint64_t QuicSpdyStream::total_body_bytes_read() const {
+  if (VersionUsesHttp3(transport_version())) {
+    return body_manager_.total_body_bytes_received();
+  }
+  return sequencer()->NumBytesConsumed();
+}
+
+void QuicSpdyStream::ConsumeHeaderList() {
+  header_list_.Clear();
+
+  if (!FinishedReadingHeaders()) {
+    return;
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    sequencer()->SetUnblocked();
+    return;
+  }
+
+  if (body_manager_.HasBytesToRead()) {
+    HandleBodyAvailable();
+    return;
+  }
+
+  if (sequencer()->IsClosed() &&
+      !on_body_available_called_because_sequencer_is_closed_) {
+    on_body_available_called_because_sequencer_is_closed_ = true;
+    HandleBodyAvailable();
+  }
+}
+
+void QuicSpdyStream::OnStreamHeadersPriority(
+    const spdy::SpdyStreamPrecedence& precedence) {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
+                   session()->connection()->perspective());
+  SetPriority(precedence);
+}
+
+void QuicSpdyStream::OnStreamHeaderList(bool fin, size_t frame_len,
+                                        const QuicHeaderList& header_list) {
+  if (!spdy_session()->user_agent_id().has_value()) {
+    std::string uaid;
+    for (const auto& kv : header_list) {
+      if (quiche::QuicheTextUtils::ToLower(kv.first) == kUserAgentHeaderName) {
+        uaid = kv.second;
+        break;
+      }
+    }
+    spdy_session()->SetUserAgentId(std::move(uaid));
+  }
+
+  // TODO(b/134706391): remove |fin| argument.
+  // When using Google QUIC, an empty header list indicates that the size limit
+  // has been exceeded.
+  // When using IETF QUIC, there is an explicit signal from
+  // QpackDecodedHeadersAccumulator.
+  if ((VersionUsesHttp3(transport_version()) &&
+       header_list_size_limit_exceeded_) ||
+      (!VersionUsesHttp3(transport_version()) && header_list.empty())) {
+    OnHeadersTooLarge();
+    if (IsDoneReading()) {
+      return;
+    }
+  }
+  if (!headers_decompressed_) {
+    OnInitialHeadersComplete(fin, frame_len, header_list);
+  } else {
+    OnTrailingHeadersComplete(fin, frame_len, header_list);
+  }
+}
+
+void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
+                                      bool header_list_size_limit_exceeded) {
+  header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
+  qpack_decoded_headers_accumulator_.reset();
+  qpack_decoded_headers_accumulator_reset_reason_ =
+      QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeadersDecoded;
+
+  QuicSpdySession::LogHeaderCompressionRatioHistogram(
+      /* using_qpack = */ true,
+      /* is_sent = */ false, headers.compressed_header_bytes(),
+      headers.uncompressed_header_bytes());
+
+  const QuicStreamId promised_stream_id = spdy_session()->promised_stream_id();
+  Http3DebugVisitor* const debug_visitor = spdy_session()->debug_visitor();
+  if (promised_stream_id ==
+      QuicUtils::GetInvalidStreamId(transport_version())) {
+    if (debug_visitor) {
+      debug_visitor->OnHeadersDecoded(id(), headers);
+    }
+
+    OnStreamHeaderList(/* fin = */ false, headers_payload_length_, headers);
+  } else {
+    spdy_session_->OnHeaderList(headers);
+  }
+
+  if (blocked_on_decoding_headers_) {
+    blocked_on_decoding_headers_ = false;
+    // Continue decoding HTTP/3 frames.
+    OnDataAvailable();
+  }
+}
+
+void QuicSpdyStream::OnHeaderDecodingError(QuicErrorCode error_code,
+                                           absl::string_view error_message) {
+  qpack_decoded_headers_accumulator_.reset();
+  qpack_decoded_headers_accumulator_reset_reason_ =
+      QpackDecodedHeadersAccumulatorResetReason::kResetInOnHeaderDecodingError;
+
+  std::string connection_close_error_message = absl::StrCat(
+      "Error decoding ", headers_decompressed_ ? "trailers" : "headers",
+      " on stream ", id(), ": ", error_message);
+  OnUnrecoverableError(error_code, connection_close_error_message);
+}
+
+void QuicSpdyStream::MaybeSendPriorityUpdateFrame() {
+  if (!VersionUsesHttp3(transport_version()) ||
+      session()->perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+
+  // Value between 0 and 7, inclusive.  Lower value means higher priority.
+  int urgency = precedence().spdy3_priority();
+  if (last_sent_urgency_ == urgency) {
+    return;
+  }
+  last_sent_urgency_ = urgency;
+
+  PriorityUpdateFrame priority_update;
+  priority_update.prioritized_element_type = REQUEST_STREAM;
+  priority_update.prioritized_element_id = id();
+  priority_update.priority_field_value = absl::StrCat("u=", urgency);
+  spdy_session_->WriteHttp3PriorityUpdate(priority_update);
+}
+
+void QuicSpdyStream::OnHeadersTooLarge() { Reset(QUIC_HEADERS_TOO_LARGE); }
+
+void QuicSpdyStream::OnInitialHeadersComplete(
+    bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
+  // TODO(b/134706391): remove |fin| argument.
+  headers_decompressed_ = true;
+  header_list_ = header_list;
+  bool header_too_large = VersionUsesHttp3(transport_version())
+                              ? header_list_size_limit_exceeded_
+                              : header_list.empty();
+  // Validate request headers if it did not exceed size limit. If it did,
+  // OnHeadersTooLarge() should have already handled it previously.
+  if (!header_too_large && !AreHeadersValid(header_list)) {
+    QUIC_CODE_COUNT_N(quic_validate_request_header, 1, 2);
+    if (GetQuicReloadableFlag(quic_act_upon_invalid_header)) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_act_upon_invalid_header);
+      OnInvalidHeaders();
+      return;
+    }
+  }
+  QUIC_CODE_COUNT_N(quic_validate_request_header, 2, 2);
+
+  if (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+      !header_too_large) {
+    MaybeProcessReceivedWebTransportHeaders();
+    if (ShouldUseDatagramContexts()) {
+      bool peer_wishes_to_use_datagram_contexts = false;
+      for (const auto& header : header_list_) {
+        if (header.first == "sec-use-datagram-contexts" &&
+            header.second == "?1") {
+          peer_wishes_to_use_datagram_contexts = true;
+          break;
+        }
+      }
+      if (!peer_wishes_to_use_datagram_contexts) {
+        use_datagram_contexts_ = false;
+      }
+    }
+  }
+
+  if (VersionUsesHttp3(transport_version())) {
+    if (fin) {
+      OnStreamFrame(QuicStreamFrame(id(), /* fin = */ true,
+                                    highest_received_byte_offset(),
+                                    absl::string_view()));
+    }
+    return;
+  }
+
+  if (fin && !rst_sent()) {
+    OnStreamFrame(
+        QuicStreamFrame(id(), fin, /* offset = */ 0, absl::string_view()));
+  }
+  if (FinishedReadingHeaders()) {
+    sequencer()->SetUnblocked();
+  }
+}
+
+void QuicSpdyStream::OnPromiseHeaderList(
+    QuicStreamId /* promised_id */, size_t /* frame_len */,
+    const QuicHeaderList& /*header_list */) {
+  // To be overridden in QuicSpdyClientStream.  Not supported on
+  // server side.
+  stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                   "Promise headers received by server");
+}
+
+void QuicSpdyStream::OnTrailingHeadersComplete(
+    bool fin, size_t /*frame_len*/, const QuicHeaderList& header_list) {
+  // TODO(b/134706391): remove |fin| argument.
+  QUICHE_DCHECK(!trailers_decompressed_);
+  if (!VersionUsesHttp3(transport_version()) && fin_received()) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Received Trailers after FIN, on stream: " << id();
+    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                     "Trailers after fin");
+    return;
+  }
+
+  if (!VersionUsesHttp3(transport_version()) && !fin) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Trailers must have FIN set, on stream: " << id();
+    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                     "Fin missing from trailers");
+    return;
+  }
+
+  size_t final_byte_offset = 0;
+  const bool expect_final_byte_offset = !VersionUsesHttp3(transport_version());
+  if (!SpdyUtils::CopyAndValidateTrailers(header_list, expect_final_byte_offset,
+                                          &final_byte_offset,
+                                          &received_trailers_)) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Trailers for stream " << id()
+                     << " are malformed.";
+    stream_delegate()->OnStreamError(QUIC_INVALID_HEADERS_STREAM_DATA,
+                                     "Trailers are malformed");
+    return;
+  }
+  trailers_decompressed_ = true;
+  if (fin) {
+    const QuicStreamOffset offset = VersionUsesHttp3(transport_version())
+                                        ? highest_received_byte_offset()
+                                        : final_byte_offset;
+    OnStreamFrame(QuicStreamFrame(id(), fin, offset, absl::string_view()));
+  }
+}
+
+void QuicSpdyStream::OnPriorityFrame(
+    const spdy::SpdyStreamPrecedence& precedence) {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER,
+                   session()->connection()->perspective());
+  SetPriority(precedence);
+}
+
+void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
+  if (web_transport_data_ != nullptr) {
+    WebTransportStreamVisitor* webtransport_visitor =
+        web_transport_data_->adapter.visitor();
+    if (webtransport_visitor != nullptr) {
+      webtransport_visitor->OnResetStreamReceived(
+          Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
+    }
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+
+  // TODO(bnc): Merge the two blocks below when both
+  // quic_abort_qpack_on_stream_reset and quic_fix_on_stream_reset are
+  // deprecated.
+  if (frame.error_code != QUIC_STREAM_NO_ERROR) {
+    if (VersionUsesHttp3(transport_version()) && !fin_received() &&
+        spdy_session_->qpack_decoder()) {
+      QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
+      spdy_session_->qpack_decoder()->OnStreamReset(id());
+      if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+        QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 1, 2);
+        qpack_decoded_headers_accumulator_.reset();
+        qpack_decoded_headers_accumulator_reset_reason_ =
+            QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset1;
+      }
+    }
+
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+
+  if (GetQuicReloadableFlag(quic_fix_on_stream_reset) &&
+      VersionUsesHttp3(transport_version())) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_fix_on_stream_reset);
+    if (!fin_received() && spdy_session_->qpack_decoder()) {
+      spdy_session_->qpack_decoder()->OnStreamReset(id());
+      qpack_decoded_headers_accumulator_.reset();
+      qpack_decoded_headers_accumulator_reset_reason_ =
+          QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
+    }
+
+    QuicStream::OnStreamReset(frame);
+    return;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Received QUIC_STREAM_NO_ERROR, not discarding response";
+  set_rst_received(true);
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  set_stream_error(frame.error());
+  CloseWriteSide();
+}
+
+void QuicSpdyStream::ResetWithError(QuicResetStreamError error) {
+  if (VersionUsesHttp3(transport_version()) && !fin_received() &&
+      spdy_session_->qpack_decoder() && web_transport_data_ == nullptr) {
+    QUIC_CODE_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
+    spdy_session_->qpack_decoder()->OnStreamReset(id());
+    if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_abort_qpack_on_stream_reset, 2, 2);
+      qpack_decoded_headers_accumulator_.reset();
+      qpack_decoded_headers_accumulator_reset_reason_ =
+          QpackDecodedHeadersAccumulatorResetReason::kResetInResetWithError;
+    }
+  }
+
+  QuicStream::ResetWithError(error);
+}
+
+bool QuicSpdyStream::OnStopSending(QuicResetStreamError error) {
+  if (web_transport_data_ != nullptr) {
+    WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
+    if (visitor != nullptr) {
+      visitor->OnStopSendingReceived(
+          Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
+    }
+  }
+
+  return QuicStream::OnStopSending(error);
+}
+
+void QuicSpdyStream::OnWriteSideInDataRecvdState() {
+  if (web_transport_data_ != nullptr) {
+    WebTransportStreamVisitor* visitor = web_transport_data_->adapter.visitor();
+    if (visitor != nullptr) {
+      visitor->OnWriteSideInDataRecvdState();
+    }
+  }
+
+  QuicStream::OnWriteSideInDataRecvdState();
+}
+
+void QuicSpdyStream::OnDataAvailable() {
+  if (!VersionUsesHttp3(transport_version())) {
+    // Sequencer must be blocked until headers are consumed.
+    QUICHE_DCHECK(FinishedReadingHeaders());
+  }
+
+  if (!VersionUsesHttp3(transport_version())) {
+    HandleBodyAvailable();
+    return;
+  }
+
+  if (web_transport_data_ != nullptr) {
+    web_transport_data_->adapter.OnDataAvailable();
+    return;
+  }
+
+  if (!spdy_session()->ShouldProcessIncomingRequests()) {
+    spdy_session()->OnStreamWaitingForClientSettings(id());
+    return;
+  }
+
+  if (is_decoder_processing_input_) {
+    // Let the outermost nested OnDataAvailable() call do the work.
+    return;
+  }
+
+  if (blocked_on_decoding_headers_) {
+    return;
+  }
+
+  iovec iov;
+  while (session()->connection()->connected() && !reading_stopped() &&
+         decoder_.error() == QUIC_NO_ERROR) {
+    QUICHE_DCHECK_GE(sequencer_offset_, sequencer()->NumBytesConsumed());
+    if (!sequencer()->PeekRegion(sequencer_offset_, &iov)) {
+      break;
+    }
+
+    QUICHE_DCHECK(!sequencer()->IsClosed());
+    is_decoder_processing_input_ = true;
+    QuicByteCount processed_bytes = decoder_.ProcessInput(
+        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len);
+    is_decoder_processing_input_ = false;
+    sequencer_offset_ += processed_bytes;
+    if (blocked_on_decoding_headers_) {
+      return;
+    }
+    if (web_transport_data_ != nullptr) {
+      return;
+    }
+  }
+
+  // Do not call HandleBodyAvailable() until headers are consumed.
+  if (!FinishedReadingHeaders()) {
+    return;
+  }
+
+  if (body_manager_.HasBytesToRead()) {
+    HandleBodyAvailable();
+    return;
+  }
+
+  if (sequencer()->IsClosed() &&
+      !on_body_available_called_because_sequencer_is_closed_) {
+    on_body_available_called_because_sequencer_is_closed_ = true;
+    HandleBodyAvailable();
+  }
+}
+
+void QuicSpdyStream::OnClose() {
+  QuicStream::OnClose();
+
+  qpack_decoded_headers_accumulator_.reset();
+  qpack_decoded_headers_accumulator_reset_reason_ =
+      QpackDecodedHeadersAccumulatorResetReason::kResetInOnClose;
+
+  if (visitor_) {
+    Visitor* visitor = visitor_;
+    // Calling Visitor::OnClose() may result the destruction of the visitor,
+    // so we need to ensure we don't call it again.
+    visitor_ = nullptr;
+    visitor->OnClose(this);
+  }
+
+  if (datagram_flow_id_.has_value()) {
+    spdy_session_->UnregisterHttp3DatagramFlowId(datagram_flow_id_.value());
+  }
+
+  if (web_transport_ != nullptr) {
+    web_transport_->OnConnectStreamClosing();
+  }
+  if (web_transport_data_ != nullptr) {
+    WebTransportHttp3* web_transport =
+        spdy_session_->GetWebTransportSession(web_transport_data_->session_id);
+    if (web_transport == nullptr) {
+      // Since there is no guaranteed destruction order for streams, the session
+      // could be already removed from the stream map by the time we reach here.
+      QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
+                         << " attempted to notify parent session "
+                         << web_transport_data_->session_id
+                         << ", but the session could not be found.";
+      return;
+    }
+    web_transport->OnStreamClosed(id());
+  }
+}
+
+void QuicSpdyStream::OnCanWrite() {
+  QuicStream::OnCanWrite();
+
+  // Trailers (and hence a FIN) may have been sent ahead of queued body bytes.
+  if (!HasBufferedData() && fin_sent()) {
+    CloseWriteSide();
+  }
+}
+
+bool QuicSpdyStream::FinishedReadingHeaders() const {
+  return headers_decompressed_ && header_list_.empty();
+}
+
+// static
+bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header,
+                                           int* status_code) {
+  SpdyHeaderBlock::const_iterator it = header.find(spdy::kHttp2StatusHeader);
+  if (it == header.end()) {
+    return false;
+  }
+  const absl::string_view status(it->second);
+  if (status.size() != 3) {
+    return false;
+  }
+  // First character must be an integer in range [1,5].
+  if (status[0] < '1' || status[0] > '5') {
+    return false;
+  }
+  // The remaining two characters must be integers.
+  if (!isdigit(status[1]) || !isdigit(status[2])) {
+    return false;
+  }
+  return absl::SimpleAtoi(status, status_code);
+}
+
+bool QuicSpdyStream::FinishedReadingTrailers() const {
+  // If no further trailing headers are expected, and the decompressed trailers
+  // (if any) have been consumed, then reading of trailers is finished.
+  if (!fin_received()) {
+    return false;
+  } else if (!trailers_decompressed_) {
+    return true;
+  } else {
+    return trailers_consumed_;
+  }
+}
+
+bool QuicSpdyStream::OnDataFrameStart(QuicByteCount header_length,
+                                      QuicByteCount payload_length) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnDataFrameReceived(id(), payload_length);
+  }
+
+  if (!headers_decompressed_ || trailers_decompressed_) {
+    stream_delegate()->OnStreamError(
+        QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+        "Unexpected DATA frame received.");
+    return false;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
+
+  return true;
+}
+
+bool QuicSpdyStream::OnDataFramePayload(absl::string_view payload) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  body_manager_.OnBody(payload);
+
+  return true;
+}
+
+bool QuicSpdyStream::OnDataFrameEnd() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Reaches the end of a data frame. Total bytes received are "
+                << body_manager_.total_body_bytes_received();
+  return true;
+}
+
+bool QuicSpdyStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        bool fin_acked,
+                                        QuicTime::Delta ack_delay_time,
+                                        QuicTime receive_timestamp,
+                                        QuicByteCount* newly_acked_length) {
+  const bool new_data_acked = QuicStream::OnStreamFrameAcked(
+      offset, data_length, fin_acked, ack_delay_time, receive_timestamp,
+      newly_acked_length);
+
+  const QuicByteCount newly_acked_header_length =
+      GetNumFrameHeadersInInterval(offset, data_length);
+  QUICHE_DCHECK_LE(newly_acked_header_length, *newly_acked_length);
+  unacked_frame_headers_offsets_.Difference(offset, offset + data_length);
+  if (ack_listener_ != nullptr && new_data_acked) {
+    ack_listener_->OnPacketAcked(
+        *newly_acked_length - newly_acked_header_length, ack_delay_time);
+  }
+  return new_data_acked;
+}
+
+void QuicSpdyStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                                QuicByteCount data_length,
+                                                bool fin_retransmitted) {
+  QuicStream::OnStreamFrameRetransmitted(offset, data_length,
+                                         fin_retransmitted);
+
+  const QuicByteCount retransmitted_header_length =
+      GetNumFrameHeadersInInterval(offset, data_length);
+  QUICHE_DCHECK_LE(retransmitted_header_length, data_length);
+
+  if (ack_listener_ != nullptr) {
+    ack_listener_->OnPacketRetransmitted(data_length -
+                                         retransmitted_header_length);
+  }
+}
+
+QuicByteCount QuicSpdyStream::GetNumFrameHeadersInInterval(
+    QuicStreamOffset offset, QuicByteCount data_length) const {
+  QuicByteCount header_acked_length = 0;
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Intersection(unacked_frame_headers_offsets_);
+  for (const auto& interval : newly_acked) {
+    header_acked_length += interval.Length();
+  }
+  return header_acked_length;
+}
+
+bool QuicSpdyStream::OnHeadersFrameStart(QuicByteCount header_length,
+                                         QuicByteCount payload_length) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QUICHE_DCHECK(!qpack_decoded_headers_accumulator_);
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnHeadersFrameReceived(id(),
+                                                           payload_length);
+  }
+
+  headers_payload_length_ = payload_length;
+
+  if (trailers_decompressed_) {
+    stream_delegate()->OnStreamError(
+        QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+        "HEADERS frame received after trailing HEADERS.");
+    return false;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
+
+  qpack_decoded_headers_accumulator_ =
+      std::make_unique<QpackDecodedHeadersAccumulator>(
+          id(), spdy_session_->qpack_decoder(), this,
+          spdy_session_->max_inbound_header_list_size());
+
+  return true;
+}
+
+bool QuicSpdyStream::OnHeadersFramePayload(absl::string_view payload) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (!qpack_decoded_headers_accumulator_) {
+    QUIC_BUG(b215142466_OnHeadersFramePayload)
+        << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+    OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+                          "qpack_decoded_headers_accumulator_ is nullptr");
+    return false;
+  }
+
+  qpack_decoded_headers_accumulator_->Decode(payload);
+
+  // |qpack_decoded_headers_accumulator_| is reset if an error is detected.
+  if (!qpack_decoded_headers_accumulator_) {
+    return false;
+  }
+
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
+  return true;
+}
+
+bool QuicSpdyStream::OnHeadersFrameEnd() {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+
+  if (!qpack_decoded_headers_accumulator_) {
+    QUIC_BUG(b215142466_OnHeadersFrameEnd)
+        << static_cast<int>(qpack_decoded_headers_accumulator_reset_reason_);
+    OnHeaderDecodingError(QUIC_INTERNAL_ERROR,
+                          "qpack_decoded_headers_accumulator_ is nullptr");
+    return false;
+  }
+
+  qpack_decoded_headers_accumulator_->EndHeaderBlock();
+
+  // If decoding is complete or an error is detected, then
+  // |qpack_decoded_headers_accumulator_| is already reset.
+  if (qpack_decoded_headers_accumulator_) {
+    blocked_on_decoding_headers_ = true;
+    return false;
+  }
+
+  return !sequencer()->IsClosed() && !reading_stopped();
+}
+
+void QuicSpdyStream::OnWebTransportStreamFrameType(
+    QuicByteCount header_length, WebTransportSessionId session_id) {
+  QUIC_DVLOG(1) << ENDPOINT << " Received WEBTRANSPORT_STREAM on stream "
+                << id() << " for session " << session_id;
+  sequencer()->MarkConsumed(header_length);
+
+  if (headers_payload_length_ > 0 || headers_decompressed_) {
+    QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on HTTP request)
+        << ENDPOINT << "Stream " << id()
+        << " tried to convert to WebTransport, but it already "
+           "has HTTP data on it";
+    Reset(QUIC_STREAM_FRAME_UNEXPECTED);
+  }
+  if (QuicUtils::IsOutgoingStreamId(spdy_session_->version(), id(),
+                                    spdy_session_->perspective())) {
+    QUIC_PEER_BUG(WEBTRANSPORT_STREAM received on outgoing request)
+        << ENDPOINT << "Stream " << id()
+        << " tried to convert to WebTransport, but only the "
+           "initiator of the stream can do it.";
+    Reset(QUIC_STREAM_FRAME_UNEXPECTED);
+  }
+
+  QUICHE_DCHECK(web_transport_ == nullptr);
+  web_transport_data_ =
+      std::make_unique<WebTransportDataStream>(this, session_id);
+  spdy_session_->AssociateIncomingWebTransportStreamWithSession(session_id,
+                                                                id());
+}
+
+bool QuicSpdyStream::OnUnknownFrameStart(uint64_t frame_type,
+                                         QuicByteCount header_length,
+                                         QuicByteCount payload_length) {
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
+                                                           payload_length);
+  }
+
+  // Ignore unknown frames, but consume frame header.
+  QUIC_DVLOG(1) << ENDPOINT << "Discarding " << header_length
+                << " byte long frame header of frame of unknown type "
+                << frame_type << ".";
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(header_length));
+  return true;
+}
+
+bool QuicSpdyStream::OnUnknownFramePayload(absl::string_view payload) {
+  // Ignore unknown frames, but consume frame payload.
+  QUIC_DVLOG(1) << ENDPOINT << "Discarding " << payload.size()
+                << " bytes of payload of frame of unknown type.";
+  sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
+  return true;
+}
+
+bool QuicSpdyStream::OnUnknownFrameEnd() { return true; }
+
+size_t QuicSpdyStream::WriteHeadersImpl(
+    spdy::SpdyHeaderBlock header_block, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return spdy_session_->WriteHeadersOnHeadersStream(
+        id(), std::move(header_block), fin, precedence(),
+        std::move(ack_listener));
+  }
+
+  // Encode header list.
+  QuicByteCount encoder_stream_sent_byte_count;
+  std::string encoded_headers =
+      spdy_session_->qpack_encoder()->EncodeHeaderList(
+          id(), header_block, &encoder_stream_sent_byte_count);
+
+  if (spdy_session_->debug_visitor()) {
+    spdy_session_->debug_visitor()->OnHeadersFrameSent(id(), header_block);
+  }
+
+  // Write HEADERS frame.
+  std::unique_ptr<char[]> headers_frame_header;
+  const size_t headers_frame_header_length =
+      HttpEncoder::SerializeHeadersFrameHeader(encoded_headers.size(),
+                                               &headers_frame_header);
+  unacked_frame_headers_offsets_.Add(
+      send_buffer().stream_offset(),
+      send_buffer().stream_offset() + headers_frame_header_length);
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing HEADERS frame header of length "
+                  << headers_frame_header_length;
+  WriteOrBufferData(absl::string_view(headers_frame_header.get(),
+                                      headers_frame_header_length),
+                    /* fin = */ false, /* ack_listener = */ nullptr);
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id()
+                  << " is writing HEADERS frame payload of length "
+                  << encoded_headers.length() << " with fin " << fin;
+  WriteOrBufferData(encoded_headers, fin, nullptr);
+
+  QuicSpdySession::LogHeaderCompressionRatioHistogram(
+      /* using_qpack = */ true,
+      /* is_sent = */ true,
+      encoded_headers.size() + encoder_stream_sent_byte_count,
+      header_block.TotalBytesUsed());
+
+  return encoded_headers.size();
+}
+
+bool QuicSpdyStream::CanWriteNewBodyData(QuicByteCount write_size) const {
+  QUICHE_DCHECK_NE(0u, write_size);
+  if (!VersionUsesHttp3(transport_version())) {
+    return CanWriteNewData();
+  }
+
+  return CanWriteNewDataAfterData(
+      HttpEncoder::GetDataFrameHeaderLength(write_size));
+}
+
+void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
+  if (!spdy_session_->SupportsWebTransport()) {
+    return;
+  }
+  if (session()->perspective() != Perspective::IS_SERVER) {
+    return;
+  }
+  QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
+
+  std::string method;
+  std::string protocol;
+  absl::optional<QuicDatagramStreamId> flow_id;
+  bool version_indicated = false;
+  for (const auto& [header_name, header_value] : header_list_) {
+    if (header_name == ":method") {
+      if (!method.empty() || header_value.empty()) {
+        return;
+      }
+      method = header_value;
+    }
+    if (header_name == ":protocol") {
+      if (!protocol.empty() || header_value.empty()) {
+        return;
+      }
+      protocol = header_value;
+    }
+    if (header_name == "datagram-flow-id") {
+      if (spdy_session_->http_datagram_support() !=
+          HttpDatagramSupport::kDraft00) {
+        QUIC_DLOG(ERROR) << ENDPOINT
+                         << "Rejecting WebTransport due to unexpected "
+                            "Datagram-Flow-Id header";
+        return;
+      }
+      if (flow_id.has_value() || header_value.empty()) {
+        return;
+      }
+      QuicDatagramStreamId flow_id_out;
+      if (!absl::SimpleAtoi(header_value, &flow_id_out)) {
+        return;
+      }
+      flow_id = flow_id_out;
+    }
+    if (header_name == "sec-webtransport-http3-draft02") {
+      if (header_value != "1") {
+        QUIC_DLOG(ERROR) << ENDPOINT
+                         << "Rejecting WebTransport due to invalid value of "
+                            "Sec-Webtransport-Http3-Draft02 header";
+        return;
+      }
+      version_indicated = true;
+    }
+  }
+
+  if (method != "CONNECT" || protocol != "webtransport") {
+    return;
+  }
+
+  if (!version_indicated &&
+      spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
+    QUIC_DLOG(ERROR)
+        << ENDPOINT
+        << "WebTransport request rejected due to missing version header.";
+    return;
+  }
+
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
+    if (!flow_id.has_value()) {
+      QUIC_DLOG(ERROR)
+          << ENDPOINT
+          << "Rejecting WebTransport due to missing Datagram-Flow-Id header";
+      return;
+    }
+    RegisterHttp3DatagramFlowId(*flow_id);
+  }
+
+  web_transport_ = std::make_unique<WebTransportHttp3>(
+      spdy_session_, this, id(),
+      spdy_session_->ShouldNegotiateDatagramContexts());
+
+  if (spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
+    return;
+  }
+  // If we're in draft-ietf-masque-h3-datagram-00 mode, pretend we also received
+  // a REGISTER_DATAGRAM_NO_CONTEXT capsule.
+  // TODO(b/181256914) remove this when we remove support for
+  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+  RegisterHttp3DatagramContextId(
+      /*context_id=*/absl::nullopt, DatagramFormatType::WEBTRANSPORT,
+      /*format_additional_data=*/absl::string_view(), web_transport_.get());
+}
+
+void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
+    spdy::SpdyHeaderBlock& headers) {
+  if (!spdy_session_->SupportsWebTransport()) {
+    return;
+  }
+  if (session()->perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+  QUICHE_DCHECK(IsValidWebTransportSessionId(id(), version()));
+
+  const auto method_it = headers.find(":method");
+  const auto protocol_it = headers.find(":protocol");
+  if (method_it == headers.end() || protocol_it == headers.end()) {
+    return;
+  }
+  if (method_it->second != "CONNECT" && protocol_it->second != "webtransport") {
+    return;
+  }
+
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
+    headers["datagram-flow-id"] = absl::StrCat(id());
+  } else {
+    headers["sec-webtransport-http3-draft02"] = "1";
+  }
+
+  web_transport_ = std::make_unique<WebTransportHttp3>(
+      spdy_session_, this, id(),
+      spdy_session_->ShouldNegotiateDatagramContexts());
+}
+
+void QuicSpdyStream::OnCanWriteNewData() {
+  if (web_transport_data_ != nullptr) {
+    web_transport_data_->adapter.OnCanWriteNewData();
+  }
+}
+
+bool QuicSpdyStream::AssertNotWebTransportDataStream(
+    absl::string_view operation) {
+  if (web_transport_data_ != nullptr) {
+    QUIC_BUG(Invalid operation on WebTransport stream)
+        << "Attempted to " << operation << " on WebTransport data stream "
+        << id() << " associated with session "
+        << web_transport_data_->session_id;
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         absl::StrCat("Attempted to ", operation,
+                                      " on WebTransport data stream"));
+    return false;
+  }
+  return true;
+}
+
+void QuicSpdyStream::ConvertToWebTransportDataStream(
+    WebTransportSessionId session_id) {
+  if (send_buffer().stream_offset() != 0) {
+    QUIC_BUG(Sending WEBTRANSPORT_STREAM when data already sent)
+        << "Attempted to send a WEBTRANSPORT_STREAM frame when other data has "
+           "already been sent on the stream.";
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Attempted to send a WEBTRANSPORT_STREAM frame when "
+                         "other data has already been sent on the stream.");
+    return;
+  }
+
+  std::unique_ptr<char[]> header;
+  QuicByteCount header_size =
+      HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id, &header);
+  if (header_size == 0) {
+    QUIC_BUG(Failed to serialize WEBTRANSPORT_STREAM)
+        << "Failed to serialize a WEBTRANSPORT_STREAM frame.";
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Failed to serialize a WEBTRANSPORT_STREAM frame.");
+    return;
+  }
+
+  WriteOrBufferData(absl::string_view(header.get(), header_size), /*fin=*/false,
+                    nullptr);
+  web_transport_data_ =
+      std::make_unique<WebTransportDataStream>(this, session_id);
+  QUIC_DVLOG(1) << ENDPOINT << "Successfully opened WebTransport data stream "
+                << id() << " for session " << session_id;
+}
+
+QuicSpdyStream::WebTransportDataStream::WebTransportDataStream(
+    QuicSpdyStream* stream, WebTransportSessionId session_id)
+    : session_id(session_id),
+      adapter(stream->spdy_session_, stream, stream->sequencer()) {}
+
+void QuicSpdyStream::HandleReceivedDatagram(
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  Http3DatagramVisitor* visitor;
+  if (context_id.has_value()) {
+    auto it = datagram_context_visitors_.find(context_id.value());
+    if (it == datagram_context_visitors_.end()) {
+      QUIC_DLOG(ERROR) << ENDPOINT
+                       << "Received datagram without any visitor for context "
+                       << context_id.value();
+      return;
+    }
+    visitor = it->second;
+  } else {
+    if (datagram_no_context_visitor_ == nullptr) {
+      QUIC_DLOG(ERROR)
+          << ENDPOINT << "Received datagram without any visitor for no context";
+      return;
+    }
+    visitor = datagram_no_context_visitor_;
+  }
+  visitor->OnHttp3Datagram(id(), context_id, payload);
+}
+
+bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " received capsule "
+                  << capsule;
+  if (!headers_decompressed_) {
+    QUIC_PEER_BUG(capsule before headers)
+        << ENDPOINT << "Stream " << id() << " received capsule " << capsule
+        << " before headers";
+    return false;
+  }
+  if (web_transport_ != nullptr && web_transport_->close_received()) {
+    QUIC_PEER_BUG(capsule after close)
+        << ENDPOINT << "Stream " << id() << " received capsule " << capsule
+        << " after CLOSE_WEBTRANSPORT_SESSION.";
+    return false;
+  }
+  switch (capsule.capsule_type()) {
+    case CapsuleType::LEGACY_DATAGRAM: {
+      HandleReceivedDatagram(
+          capsule.legacy_datagram_capsule().context_id,
+          capsule.legacy_datagram_capsule().http_datagram_payload);
+    } break;
+    case CapsuleType::DATAGRAM_WITH_CONTEXT: {
+      HandleReceivedDatagram(
+          capsule.datagram_with_context_capsule().context_id,
+          capsule.datagram_with_context_capsule().http_datagram_payload);
+    } break;
+    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT: {
+      absl::optional<QuicDatagramContextId> context_id;
+      if (use_datagram_contexts_) {
+        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
+        // DATAGRAM_WITHOUT_CONTEXT.
+        context_id = 0;
+      }
+      HandleReceivedDatagram(
+          context_id,
+          capsule.datagram_without_context_capsule().http_datagram_payload);
+    } break;
+    case CapsuleType::REGISTER_DATAGRAM_CONTEXT: {
+      if (datagram_registration_visitor_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " without any registration visitor";
+        return false;
+      }
+      datagram_registration_visitor_->OnContextReceived(
+          id(), capsule.register_datagram_context_capsule().context_id,
+          capsule.register_datagram_context_capsule().format_type,
+          capsule.register_datagram_context_capsule().format_additional_data);
+    } break;
+    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT: {
+      if (datagram_registration_visitor_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " without any registration visitor";
+        return false;
+      }
+      absl::optional<QuicDatagramContextId> context_id;
+      if (use_datagram_contexts_) {
+        // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
+        // REGISTER_DATAGRAM_NO_CONTEXT.
+        context_id = 0;
+      }
+      datagram_registration_visitor_->OnContextReceived(
+          id(), context_id,
+          capsule.register_datagram_no_context_capsule().format_type,
+          capsule.register_datagram_no_context_capsule()
+              .format_additional_data);
+    } break;
+    case CapsuleType::CLOSE_DATAGRAM_CONTEXT: {
+      if (datagram_registration_visitor_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " without any registration visitor";
+        return false;
+      }
+      datagram_registration_visitor_->OnContextClosed(
+          id(), capsule.close_datagram_context_capsule().context_id,
+          capsule.close_datagram_context_capsule().close_code,
+          capsule.close_datagram_context_capsule().close_details);
+    } break;
+    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION: {
+      if (web_transport_ == nullptr) {
+        QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
+                         << " for a non-WebTransport stream.";
+        return false;
+      }
+      web_transport_->OnCloseReceived(
+          capsule.close_web_transport_session_capsule().error_code,
+          capsule.close_web_transport_session_capsule().error_message);
+    } break;
+  }
+  return true;
+}
+
+void QuicSpdyStream::OnCapsuleParseFailure(const std::string& error_message) {
+  QUIC_DLOG(ERROR) << ENDPOINT << "Capsule parse failure: " << error_message;
+  Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+}
+
+void QuicSpdyStream::WriteCapsule(const Capsule& capsule, bool fin) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Stream " << id() << " sending capsule "
+                  << capsule;
+  quiche::QuicheBuffer serialized_capsule = SerializeCapsule(
+      capsule,
+      spdy_session_->connection()->helper()->GetStreamSendBufferAllocator());
+  QUICHE_DCHECK_GT(serialized_capsule.size(), 0u);
+  WriteOrBufferBody(serialized_capsule.AsStringView(), /*fin=*/fin);
+}
+
+void QuicSpdyStream::WriteGreaseCapsule() {
+  // GREASE capsulde IDs have a form of 41 * N + 23.
+  QuicRandom* random = spdy_session_->connection()->random_generator();
+  uint64_t type = random->InsecureRandUint64() >> 4;
+  type = (type / 41) * 41 + 23;
+  QUICHE_DCHECK_EQ((type - 23) % 41, 0u);
+
+  constexpr size_t kMaxLength = 64;
+  size_t length = random->InsecureRandUint64() % kMaxLength;
+  std::string bytes(length, '\0');
+  random->InsecureRandBytes(&bytes[0], bytes.size());
+  Capsule capsule = Capsule::Unknown(type, bytes);
+  WriteCapsule(capsule, /*fin=*/false);
+}
+
+MessageStatus QuicSpdyStream::SendHttp3Datagram(
+    absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  QuicDatagramStreamId stream_id =
+      datagram_flow_id_.has_value() ? datagram_flow_id_.value() : id();
+  return spdy_session_->SendHttp3Datagram(stream_id, context_id, payload);
+}
+
+void QuicSpdyStream::RegisterHttp3DatagramRegistrationVisitor(
+    Http3DatagramRegistrationVisitor* visitor, bool use_datagram_contexts) {
+  if (visitor == nullptr) {
+    QUIC_BUG(null datagram registration visitor)
+        << ENDPOINT << "Null datagram registration visitor for" << id();
+    return;
+  }
+  if (datagram_registration_visitor_ != nullptr) {
+    QUIC_BUG(double datagram registration visitor)
+        << ENDPOINT << "Double datagram registration visitor for" << id();
+    return;
+  }
+  use_datagram_contexts_ = use_datagram_contexts;
+  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram stream ID " << id()
+                  << " with" << (use_datagram_contexts_ ? "" : "out")
+                  << " contexts";
+  datagram_registration_visitor_ = visitor;
+  QUICHE_DCHECK(!capsule_parser_);
+  capsule_parser_.reset(new CapsuleParser(this));
+}
+
+void QuicSpdyStream::UnregisterHttp3DatagramRegistrationVisitor() {
+  QUIC_BUG_IF(h3 datagram unregister unknown stream ID,
+              datagram_registration_visitor_ == nullptr)
+      << ENDPOINT
+      << "Attempted to unregister unknown HTTP/3 datagram stream ID " << id();
+  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram stream ID " << id();
+  datagram_registration_visitor_ = nullptr;
+}
+
+void QuicSpdyStream::MoveHttp3DatagramRegistration(
+    Http3DatagramRegistrationVisitor* visitor) {
+  QUIC_BUG_IF(h3 datagram move unknown stream ID,
+              datagram_registration_visitor_ == nullptr)
+      << ENDPOINT << "Attempted to move unknown HTTP/3 datagram stream ID "
+      << id();
+  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram stream ID " << id();
+  datagram_registration_visitor_ = visitor;
+}
+
+void QuicSpdyStream::RegisterHttp3DatagramContextId(
+    absl::optional<QuicDatagramContextId> context_id,
+    DatagramFormatType format_type, absl::string_view format_additional_data,
+    Http3DatagramVisitor* visitor) {
+  if (visitor == nullptr) {
+    QUIC_BUG(null datagram visitor)
+        << ENDPOINT << "Null datagram visitor for stream ID " << id()
+        << " context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none");
+    return;
+  }
+  if (datagram_registration_visitor_ == nullptr) {
+    QUIC_BUG(context registration without registration visitor)
+        << ENDPOINT << "Cannot register context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " without registration visitor for stream ID " << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram context ID "
+                  << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                             : "none")
+                  << " with stream ID " << id();
+
+  if (context_id.has_value()) {
+    if (datagram_no_context_visitor_ != nullptr) {
+      QUIC_BUG(h3 datagram context ID mix1)
+          << ENDPOINT
+          << "Attempted to mix registrations without and with context IDs "
+             "for stream ID "
+          << id();
+      return;
+    }
+    auto insertion_result =
+        datagram_context_visitors_.insert({context_id.value(), visitor});
+    if (!insertion_result.second) {
+      QUIC_BUG(h3 datagram double context registration)
+          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
+          << id() << " context ID " << context_id.value();
+      return;
+    }
+    capsule_parser_->set_datagram_context_id_present(true);
+  } else {
+    // Registration without a context ID.
+    if (!datagram_context_visitors_.empty()) {
+      QUIC_BUG(h3 datagram context ID mix2)
+          << ENDPOINT
+          << "Attempted to mix registrations with and without context IDs "
+             "for stream ID "
+          << id();
+      return;
+    }
+    if (datagram_no_context_visitor_ != nullptr) {
+      QUIC_BUG(h3 datagram double no context registration)
+          << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
+          << id() << " with no context ID";
+      return;
+    }
+    datagram_no_context_visitor_ = visitor;
+    capsule_parser_->set_datagram_context_id_present(false);
+  }
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04) {
+    const bool is_client = session()->perspective() == Perspective::IS_CLIENT;
+    if (context_id.has_value()) {
+      const bool is_client_context = context_id.value() % 2 == 0;
+      if (is_client == is_client_context) {
+        QuicConnection::ScopedPacketFlusher flusher(
+            spdy_session_->connection());
+        WriteGreaseCapsule();
+        if (context_id.value() != 0) {
+          WriteCapsule(Capsule::RegisterDatagramContext(
+              context_id.value(), format_type, format_additional_data));
+        } else {
+          // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
+          // REGISTER_DATAGRAM_NO_CONTEXT.
+          WriteCapsule(Capsule::RegisterDatagramNoContext(
+              format_type, format_additional_data));
+        }
+        WriteGreaseCapsule();
+      }
+    } else if (is_client) {
+      QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
+      WriteGreaseCapsule();
+      WriteCapsule(Capsule::RegisterDatagramNoContext(format_type,
+                                                      format_additional_data));
+      WriteGreaseCapsule();
+    }
+  }
+}
+
+void QuicSpdyStream::UnregisterHttp3DatagramContextId(
+    absl::optional<QuicDatagramContextId> context_id) {
+  if (datagram_registration_visitor_ == nullptr) {
+    QUIC_BUG(context unregistration without registration visitor)
+        << ENDPOINT << "Cannot unregister context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " without registration visitor for stream ID " << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram context ID "
+                  << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                             : "none")
+                  << " with stream ID " << id();
+  if (context_id.has_value()) {
+    size_t num_erased = datagram_context_visitors_.erase(context_id.value());
+    QUIC_BUG_IF(h3 datagram unregister unknown context, num_erased != 1)
+        << "Attempted to unregister unknown HTTP/3 context ID "
+        << context_id.value() << " on stream ID " << id();
+  } else {
+    // Unregistration without a context ID.
+    QUIC_BUG_IF(h3 datagram unknown context unregistration,
+                datagram_no_context_visitor_ == nullptr)
+        << "Attempted to unregister unknown no context on HTTP/3 stream ID "
+        << id();
+    datagram_no_context_visitor_ = nullptr;
+  }
+  if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04 &&
+      context_id.has_value()) {
+    WriteCapsule(Capsule::CloseDatagramContext(context_id.value()));
+  }
+}
+
+void QuicSpdyStream::MoveHttp3DatagramContextIdRegistration(
+    absl::optional<QuicDatagramContextId> context_id,
+    Http3DatagramVisitor* visitor) {
+  if (datagram_registration_visitor_ == nullptr) {
+    QUIC_BUG(context move without registration visitor)
+        << ENDPOINT << "Cannot move context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " without registration visitor for stream ID " << id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram context ID "
+                  << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                             : "none")
+                  << " with stream ID " << id();
+  if (context_id.has_value()) {
+    QUIC_BUG_IF(h3 datagram move unknown context,
+                !datagram_context_visitors_.contains(context_id.value()))
+        << ENDPOINT << "Attempted to move unknown context ID "
+        << context_id.value() << " on stream ID " << id();
+    datagram_context_visitors_[context_id.value()] = visitor;
+    return;
+  }
+  // Move without a context ID.
+  QUIC_BUG_IF(h3 datagram unknown context move,
+              datagram_no_context_visitor_ == nullptr)
+      << "Attempted to move unknown no context on HTTP/3 stream ID " << id();
+  datagram_no_context_visitor_ = visitor;
+}
+
+void QuicSpdyStream::SetMaxDatagramTimeInQueue(
+    QuicTime::Delta max_time_in_queue) {
+  spdy_session_->SetMaxDatagramTimeInQueueForStreamId(id(), max_time_in_queue);
+}
+
+QuicDatagramContextId QuicSpdyStream::GetNextDatagramContextId() {
+  QuicDatagramContextId result = datagram_next_available_context_id_;
+  datagram_next_available_context_id_ += kDatagramContextIdIncrement;
+  return result;
+}
+
+void QuicSpdyStream::OnDatagramReceived(QuicDataReader* reader) {
+  if (!headers_decompressed_) {
+    QUIC_DLOG(INFO) << "Dropping datagram received before headers on stream ID "
+                    << id();
+    return;
+  }
+  absl::optional<QuicDatagramContextId> context_id;
+  if (use_datagram_contexts_) {
+    QuicDatagramContextId parsed_context_id;
+    if (!reader->ReadVarInt62(&parsed_context_id)) {
+      QUIC_DLOG(ERROR) << "Failed to parse context ID in received HTTP/3 "
+                          "datagram on stream ID "
+                       << id();
+      return;
+    }
+    context_id = parsed_context_id;
+  }
+  absl::string_view payload = reader->ReadRemainingPayload();
+  HandleReceivedDatagram(context_id, payload);
+}
+
+QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
+    absl::optional<QuicDatagramContextId> context_id) const {
+  QuicByteCount prefix_size = 0;
+  switch (spdy_session_->http_datagram_support()) {
+    case HttpDatagramSupport::kDraft00:
+      if (!datagram_flow_id_.has_value()) {
+        QUIC_BUG(GetMaxDatagramSize with no flow ID)
+            << "GetMaxDatagramSize() called when no flow ID available";
+        break;
+      }
+      prefix_size = QuicDataWriter::GetVarInt62Len(*datagram_flow_id_);
+      break;
+    case HttpDatagramSupport::kDraft04:
+      prefix_size =
+          QuicDataWriter::GetVarInt62Len(id() / kHttpDatagramStreamIdDivisor);
+      break;
+    case HttpDatagramSupport::kNone:
+    case HttpDatagramSupport::kDraft00And04:
+      QUIC_BUG(GetMaxDatagramSize called with no datagram support)
+          << "GetMaxDatagramSize() called when no HTTP/3 datagram support has "
+             "been negotiated.  Support value: "
+          << spdy_session_->http_datagram_support();
+      break;
+  }
+  // If the logic above fails, use the largest possible value as the safe one.
+  if (prefix_size == 0) {
+    prefix_size = 8;
+  }
+
+  if (context_id.has_value()) {
+    QUIC_BUG_IF(
+        context_id with draft00 in GetMaxDatagramSize,
+        spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00)
+        << "GetMaxDatagramSize() called with a context ID specified, but "
+           "draft00 does not support contexts.";
+    prefix_size += QuicDataWriter::GetVarInt62Len(*context_id);
+  }
+
+  QuicByteCount max_datagram_size =
+      session()->GetGuaranteedLargestMessagePayload();
+  if (max_datagram_size < prefix_size) {
+    QUIC_BUG(max_datagram_size smaller than prefix_size)
+        << "GetGuaranteedLargestMessagePayload() returned a datagram size that "
+           "is not sufficient to fit stream and/or context ID into it.";
+    return 0;
+  }
+  return max_datagram_size - prefix_size;
+}
+
+void QuicSpdyStream::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id) {
+  datagram_flow_id_ = flow_id;
+  spdy_session_->RegisterHttp3DatagramFlowId(datagram_flow_id_.value(), id());
+}
+
+void QuicSpdyStream::HandleBodyAvailable() {
+  if (!capsule_parser_) {
+    OnBodyAvailable();
+    return;
+  }
+  while (body_manager_.HasBytesToRead()) {
+    iovec iov;
+    int num_iov = GetReadableRegions(&iov, /*iov_len=*/1);
+    if (num_iov == 0) {
+      break;
+    }
+    if (!capsule_parser_->IngestCapsuleFragment(absl::string_view(
+            reinterpret_cast<const char*>(iov.iov_base), iov.iov_len))) {
+      break;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  // If we received a FIN, make sure that there isn't a partial capsule buffered
+  // in the capsule parser.
+  if (sequencer()->IsClosed()) {
+    capsule_parser_->ErrorIfThereIsRemainingBufferedData();
+    if (web_transport_ != nullptr) {
+      web_transport_->OnConnectStreamFinReceived();
+    }
+    OnFinRead();
+  }
+}
+
+namespace {
+// Return true if |c| is not allowed in an HTTP/3 wire-encoded header and
+// pseudo-header names according to
+// https://datatracker.ietf.org/doc/html/draft-ietf-quic-http#section-4.1.1 and
+// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-semantics-19#section-5.6.2
+constexpr bool isInvalidHeaderNameCharacter(unsigned char c) {
+  if (c == '!' || c == '|' || c == '~' || c == '*' || c == '+' || c == '-' ||
+      c == '.' ||
+      // #, $, %, &, '
+      (c >= '#' && c <= '\'') ||
+      // [0-9], :
+      (c >= '0' && c <= ':') ||
+      // ^, _, `, [a-z]
+      (c >= '^' && c <= 'z')) {
+    return false;
+  }
+  return true;
+}
+}  // namespace
+
+bool QuicSpdyStream::AreHeadersValid(const QuicHeaderList& header_list) const {
+  QUICHE_DCHECK(GetQuicReloadableFlag(quic_verify_request_headers_2));
+  for (const std::pair<std::string, std::string>& pair : header_list) {
+    const std::string& name = pair.first;
+    if (std::any_of(name.begin(), name.end(), isInvalidHeaderNameCharacter)) {
+      QUIC_DLOG(ERROR) << "Invalid request header " << name;
+      return false;
+    }
+    if (http2::GetInvalidHttp2HeaderSet().contains(name)) {
+      QUIC_DLOG(ERROR) << name << " header is not allowed";
+      return false;
+    }
+  }
+  return true;
+}
+
+void QuicSpdyStream::OnInvalidHeaders() { Reset(QUIC_BAD_APPLICATION_PAYLOAD); }
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream.h b/quiche/quic/core/http/quic_spdy_stream.h
new file mode 100644
index 0000000..b7fc714
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream.h
@@ -0,0 +1,540 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The base class for streams which deliver data to/from an application.
+// In each direction, the data on such a stream first contains compressed
+// headers then body data.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
+
+#include <sys/types.h>
+
+#include <cstddef>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/http/capsule.h"
+#include "quiche/quic/core/http/http_decoder.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
+#include "quiche/quic/core/http/web_transport_stream_adapter.h"
+#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/spdy_framer.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+namespace test {
+class QuicSpdyStreamPeer;
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicSpdySession;
+class WebTransportHttp3;
+
+// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
+class QUIC_EXPORT_PRIVATE QuicSpdyStream
+    : public QuicStream,
+      public CapsuleParser::Visitor,
+      public QpackDecodedHeadersAccumulator::Visitor {
+ public:
+  // Visitor receives callbacks from the stream.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    Visitor() {}
+    Visitor(const Visitor&) = delete;
+    Visitor& operator=(const Visitor&) = delete;
+
+    // Called when the stream is closed.
+    virtual void OnClose(QuicSpdyStream* stream) = 0;
+
+    // Allows subclasses to override and do work.
+    virtual void OnPromiseHeadersComplete(QuicStreamId /*promised_id*/,
+                                          size_t /*frame_len*/) {}
+
+   protected:
+    virtual ~Visitor() {}
+  };
+
+  QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
+                 StreamType type);
+  QuicSpdyStream(PendingStream* pending, QuicSpdySession* spdy_session);
+  QuicSpdyStream(const QuicSpdyStream&) = delete;
+  QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
+  ~QuicSpdyStream() override;
+
+  // QuicStream implementation
+  void OnClose() override;
+
+  // Override to maybe close the write side after writing.
+  void OnCanWrite() override;
+
+  // Called by the session when headers with a priority have been received
+  // for this stream.  This method will only be called for server streams.
+  virtual void OnStreamHeadersPriority(
+      const spdy::SpdyStreamPrecedence& precedence);
+
+  // Called by the session when decompressed headers have been completely
+  // delivered to this stream.  If |fin| is true, then this stream
+  // should be closed; no more data will be sent by the peer.
+  virtual void OnStreamHeaderList(bool fin, size_t frame_len,
+                                  const QuicHeaderList& header_list);
+
+  // Called by the session when decompressed push promise headers have
+  // been completely delivered to this stream.
+  virtual void OnPromiseHeaderList(QuicStreamId promised_id, size_t frame_len,
+                                   const QuicHeaderList& header_list);
+
+  // Called by the session when a PRIORITY frame has been been received for this
+  // stream. This method will only be called for server streams.
+  void OnPriorityFrame(const spdy::SpdyStreamPrecedence& precedence);
+
+  // Override the base class to not discard response when receiving
+  // QUIC_STREAM_NO_ERROR.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  void ResetWithError(QuicResetStreamError error) override;
+  bool OnStopSending(QuicResetStreamError error) override;
+
+  // Called by the sequencer when new data is available. Decodes the data and
+  // calls OnBodyAvailable() to pass to the upper layer.
+  void OnDataAvailable() override;
+
+  // Called in OnDataAvailable() after it finishes the decoding job.
+  virtual void OnBodyAvailable() = 0;
+
+  // Writes the headers contained in |header_block| on the dedicated headers
+  // stream or on this stream, depending on VersionUsesHttp3().  Returns the
+  // number of bytes sent, including data sent on the encoder stream when using
+  // QPACK.
+  virtual size_t WriteHeaders(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Sends |data| to the peer, or buffers if it can't be sent immediately.
+  void WriteOrBufferBody(absl::string_view data, bool fin);
+
+  // Writes the trailers contained in |trailer_block| on the dedicated headers
+  // stream or on this stream, depending on VersionUsesHttp3().  Trailers will
+  // always have the FIN flag set.  Returns the number of bytes sent, including
+  // data sent on the encoder stream when using QPACK.
+  virtual size_t WriteTrailers(
+      spdy::SpdyHeaderBlock trailer_block,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Override to report newly acked bytes via ack_listener_.
+  bool OnStreamFrameAcked(QuicStreamOffset offset, QuicByteCount data_length,
+                          bool fin_acked, QuicTime::Delta ack_delay_time,
+                          QuicTime receive_timestamp,
+                          QuicByteCount* newly_acked_length) override;
+
+  // Override to report bytes retransmitted via ack_listener_.
+  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_retransmitted) override;
+
+  // Does the same thing as WriteOrBufferBody except this method takes iovec
+  // as the data input. Right now it only calls WritevData.
+  QuicConsumedData WritevBody(const struct iovec* iov, int count, bool fin);
+
+  // Does the same thing as WriteOrBufferBody except this method takes
+  // memslicespan as the data input. Right now it only calls WriteMemSlices.
+  QuicConsumedData WriteBodySlices(absl::Span<quiche::QuicheMemSlice> slices,
+                                   bool fin);
+
+  // Marks the trailers as consumed. This applies to the case where this object
+  // receives headers and trailers as QuicHeaderLists via calls to
+  // OnStreamHeaderList(). Trailer data will be consumed from the sequencer only
+  // once all body data has been consumed.
+  void MarkTrailersConsumed();
+
+  // Clears |header_list_|.
+  void ConsumeHeaderList();
+
+  // This block of functions wraps the sequencer's functions of the same
+  // name.  These methods return uncompressed data until that has
+  // been fully processed.  Then they simply delegate to the sequencer.
+  virtual size_t Readv(const struct iovec* iov, size_t iov_len);
+  virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
+  void MarkConsumed(size_t num_bytes);
+
+  // Returns true if header contains a valid 3-digit status and parse the status
+  // code to |status_code|.
+  static bool ParseHeaderStatusCode(const spdy::SpdyHeaderBlock& header,
+                                    int* status_code);
+
+  // Returns true when all data from the peer has been read and consumed,
+  // including the fin.
+  bool IsDoneReading() const;
+  bool HasBytesToRead() const;
+
+  void set_visitor(Visitor* visitor) { visitor_ = visitor; }
+
+  bool headers_decompressed() const { return headers_decompressed_; }
+
+  // Returns total amount of body bytes that have been read.
+  uint64_t total_body_bytes_read() const;
+
+  const QuicHeaderList& header_list() const { return header_list_; }
+
+  bool trailers_decompressed() const { return trailers_decompressed_; }
+
+  // Returns whatever trailers have been received for this stream.
+  const spdy::SpdyHeaderBlock& received_trailers() const {
+    return received_trailers_;
+  }
+
+  // Returns true if headers have been fully read and consumed.
+  bool FinishedReadingHeaders() const;
+
+  // Returns true if FIN has been received and either trailers have been fully
+  // read and consumed or there are no trailers.
+  bool FinishedReadingTrailers() const;
+
+  // Returns true if the sequencer has delivered the FIN, and no more body bytes
+  // will be available.
+  bool IsSequencerClosed() { return sequencer()->IsClosed(); }
+
+  // QpackDecodedHeadersAccumulator::Visitor implementation.
+  void OnHeadersDecoded(QuicHeaderList headers,
+                        bool header_list_size_limit_exceeded) override;
+  void OnHeaderDecodingError(QuicErrorCode error_code,
+                             absl::string_view error_message) override;
+
+  QuicSpdySession* spdy_session() const { return spdy_session_; }
+
+  // Send PRIORITY_UPDATE frame and update |last_sent_urgency_| if
+  // |last_sent_urgency_| is different from current priority.
+  void MaybeSendPriorityUpdateFrame() override;
+
+  // Returns the WebTransport session owned by this stream, if one exists.
+  WebTransportHttp3* web_transport() { return web_transport_.get(); }
+
+  // Returns the WebTransport data stream associated with this QUIC stream, or
+  // null if this is not a WebTransport data stream.
+  WebTransportStream* web_transport_stream() {
+    if (web_transport_data_ == nullptr) {
+      return nullptr;
+    }
+    return &web_transport_data_->adapter;
+  }
+
+  // Sends a WEBTRANSPORT_STREAM frame and sets up the appropriate metadata.
+  void ConvertToWebTransportDataStream(WebTransportSessionId session_id);
+
+  void OnCanWriteNewData() override;
+
+  // If this stream is a WebTransport data stream, closes the connection with an
+  // error, and returns false.
+  bool AssertNotWebTransportDataStream(absl::string_view operation);
+
+  // Indicates whether a call to WriteBodySlices will be successful and not
+  // rejected due to buffer being full.  |write_size| must be non-zero.
+  bool CanWriteNewBodyData(QuicByteCount write_size) const;
+
+  // From CapsuleParser::Visitor.
+  bool OnCapsule(const Capsule& capsule) override;
+  void OnCapsuleParseFailure(const std::string& error_message) override;
+
+  // Sends an HTTP/3 datagram. The stream and context IDs are not part of
+  // |payload|.
+  MessageStatus SendHttp3Datagram(
+      absl::optional<QuicDatagramContextId> context_id,
+      absl::string_view payload);
+
+  class QUIC_EXPORT_PRIVATE Http3DatagramVisitor {
+   public:
+    virtual ~Http3DatagramVisitor() {}
+
+    // Called when an HTTP/3 datagram is received. |payload| does not contain
+    // the stream or context IDs. Note that this contains the stream ID even if
+    // flow IDs from draft-ietf-masque-h3-datagram-00 are in use.
+    virtual void OnHttp3Datagram(
+        QuicStreamId stream_id,
+        absl::optional<QuicDatagramContextId> context_id,
+        absl::string_view payload) = 0;
+  };
+
+  class QUIC_EXPORT_PRIVATE Http3DatagramRegistrationVisitor {
+   public:
+    virtual ~Http3DatagramRegistrationVisitor() {}
+
+    // Called when a REGISTER_DATAGRAM_CONTEXT or REGISTER_DATAGRAM_NO_CONTEXT
+    // capsule is received. Note that this contains the stream ID even if flow
+    // IDs from draft-ietf-masque-h3-datagram-00 are in use.
+    virtual void OnContextReceived(
+        QuicStreamId stream_id,
+        absl::optional<QuicDatagramContextId> context_id,
+        DatagramFormatType format_type,
+        absl::string_view format_additional_data) = 0;
+
+    // Called when a CLOSE_DATAGRAM_CONTEXT capsule is received. Note that this
+    // contains the stream ID even if flow IDs from
+    // draft-ietf-masque-h3-datagram-00 are in use.
+    virtual void OnContextClosed(
+        QuicStreamId stream_id,
+        absl::optional<QuicDatagramContextId> context_id,
+        ContextCloseCode close_code, absl::string_view close_details) = 0;
+  };
+
+  // Registers |visitor| to receive HTTP/3 datagram context registrations. This
+  // must not be called without first calling
+  // UnregisterHttp3DatagramRegistrationVisitor. |visitor| must be valid until a
+  // corresponding call to UnregisterHttp3DatagramRegistrationVisitor.
+  void RegisterHttp3DatagramRegistrationVisitor(
+      Http3DatagramRegistrationVisitor* visitor,
+      bool use_datagram_contexts = false);
+
+  // Unregisters for HTTP/3 datagram context registrations. Must not be called
+  // unless previously registered.
+  void UnregisterHttp3DatagramRegistrationVisitor();
+
+  // Moves an HTTP/3 datagram registration to a different visitor. Mainly meant
+  // to be used by the visitors' move operators.
+  void MoveHttp3DatagramRegistration(Http3DatagramRegistrationVisitor* visitor);
+
+  // Registers |visitor| to receive HTTP/3 datagrams for optional context ID
+  // |context_id|. This must not be called on a previously registered context ID
+  // without first calling UnregisterHttp3DatagramContextId. |visitor| must be
+  // valid until a corresponding call to UnregisterHttp3DatagramContextId. If
+  // this method is called multiple times, the context ID MUST either be always
+  // present, or always absent.
+  void RegisterHttp3DatagramContextId(
+      absl::optional<QuicDatagramContextId> context_id,
+      DatagramFormatType format_type, absl::string_view format_additional_data,
+      Http3DatagramVisitor* visitor);
+
+  // Unregisters an HTTP/3 datagram context ID. Must be called on a previously
+  // registered context.
+  void UnregisterHttp3DatagramContextId(
+      absl::optional<QuicDatagramContextId> context_id);
+
+  // Moves an HTTP/3 datagram context ID to a different visitor. Mainly meant
+  // to be used by the visitors' move operators.
+  void MoveHttp3DatagramContextIdRegistration(
+      absl::optional<QuicDatagramContextId> context_id,
+      Http3DatagramVisitor* visitor);
+
+  // Sets max datagram time in queue.
+  void SetMaxDatagramTimeInQueue(QuicTime::Delta max_time_in_queue);
+
+  // Generates a new HTTP/3 datagram context ID for this stream. A datagram
+  // registration visitor must be currently registered on this stream.
+  QuicDatagramContextId GetNextDatagramContextId();
+
+  void OnDatagramReceived(QuicDataReader* reader);
+
+  void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
+
+  QuicByteCount GetMaxDatagramSize(
+      absl::optional<QuicDatagramContextId> context_id) const;
+
+  // Writes |capsule| onto the DATA stream.
+  void WriteCapsule(const Capsule& capsule, bool fin = false);
+
+  void WriteGreaseCapsule();
+
+ protected:
+  // Called when the received headers are too large. By default this will
+  // reset the stream.
+  virtual void OnHeadersTooLarge();
+
+  virtual void OnInitialHeadersComplete(bool fin, size_t frame_len,
+                                        const QuicHeaderList& header_list);
+  virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len,
+                                         const QuicHeaderList& header_list);
+  virtual size_t WriteHeadersImpl(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  Visitor* visitor() { return visitor_; }
+
+  void set_headers_decompressed(bool val) { headers_decompressed_ = val; }
+
+  void set_ack_listener(
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener) {
+    ack_listener_ = std::move(ack_listener);
+  }
+
+  void OnWriteSideInDataRecvdState() override;
+
+  virtual bool AreHeadersValid(const QuicHeaderList& header_list) const;
+
+  // Reset stream upon invalid request headers.
+  virtual void OnInvalidHeaders();
+
+ private:
+  friend class test::QuicSpdyStreamPeer;
+  friend class test::QuicStreamPeer;
+  friend class QuicStreamUtils;
+  class HttpDecoderVisitor;
+
+  struct QUIC_EXPORT_PRIVATE WebTransportDataStream {
+    WebTransportDataStream(QuicSpdyStream* stream,
+                           WebTransportSessionId session_id);
+
+    WebTransportSessionId session_id;
+    WebTransportStreamAdapter adapter;
+  };
+
+  // Reason codes for `qpack_decoded_headers_accumulator_` being nullptr.
+  enum class QpackDecodedHeadersAccumulatorResetReason {
+    // `qpack_decoded_headers_accumulator_` was default constructed to nullptr.
+    kUnSet = 0,
+    // `qpack_decoded_headers_accumulator_` was reset in the corresponding
+    // method.
+    kResetInOnHeadersDecoded = 1,
+    kResetInOnHeaderDecodingError = 2,
+    kResetInOnStreamReset1 = 3,
+    kResetInOnStreamReset2 = 4,
+    kResetInResetWithError = 5,
+    kResetInOnClose = 6,
+  };
+
+  // Called by HttpDecoderVisitor.
+  bool OnDataFrameStart(QuicByteCount header_length,
+                        QuicByteCount payload_length);
+  bool OnDataFramePayload(absl::string_view payload);
+  bool OnDataFrameEnd();
+  bool OnHeadersFrameStart(QuicByteCount header_length,
+                           QuicByteCount payload_length);
+  bool OnHeadersFramePayload(absl::string_view payload);
+  bool OnHeadersFrameEnd();
+  void OnWebTransportStreamFrameType(QuicByteCount header_length,
+                                     WebTransportSessionId session_id);
+  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
+                           QuicByteCount payload_length);
+  bool OnUnknownFramePayload(absl::string_view payload);
+  bool OnUnknownFrameEnd();
+
+  // Given the interval marked by [|offset|, |offset| + |data_length|), return
+  // the number of frame header bytes contained in it.
+  QuicByteCount GetNumFrameHeadersInInterval(QuicStreamOffset offset,
+                                             QuicByteCount data_length) const;
+
+  void MaybeProcessSentWebTransportHeaders(spdy::SpdyHeaderBlock& headers);
+  void MaybeProcessReceivedWebTransportHeaders();
+
+  // Writes HTTP/3 DATA frame header. If |force_write| is true, use
+  // WriteOrBufferData if send buffer cannot accomodate the header + data.
+  ABSL_MUST_USE_RESULT bool WriteDataFrameHeader(QuicByteCount data_length,
+                                                 bool force_write);
+
+  // Simply calls OnBodyAvailable() unless capsules are in use, in which case
+  // pass the capsule fragments to the capsule manager.
+  void HandleBodyAvailable();
+
+  // Called when a datagram frame or capsule is received.
+  void HandleReceivedDatagram(absl::optional<QuicDatagramContextId> context_id,
+                              absl::string_view payload);
+
+  // Whether datagram contexts should be used on this stream.
+  bool ShouldUseDatagramContexts() const;
+
+  QuicSpdySession* spdy_session_;
+
+  bool on_body_available_called_because_sequencer_is_closed_;
+
+  Visitor* visitor_;
+
+  // True if read side processing is blocked while waiting for callback from
+  // QPACK decoder.
+  bool blocked_on_decoding_headers_;
+  // True if the headers have been completely decompressed.
+  bool headers_decompressed_;
+  // True if uncompressed headers or trailers exceed maximum allowed size
+  // advertised to peer via SETTINGS_MAX_HEADER_LIST_SIZE.
+  bool header_list_size_limit_exceeded_;
+  // Contains a copy of the decompressed header (name, value) pairs until they
+  // are consumed via Readv.
+  QuicHeaderList header_list_;
+  // Length of most recently received HEADERS frame payload.
+  QuicByteCount headers_payload_length_;
+
+  // True if the trailers have been completely decompressed.
+  bool trailers_decompressed_;
+  // True if the trailers have been consumed.
+  bool trailers_consumed_;
+
+  // The parsed trailers received from the peer.
+  spdy::SpdyHeaderBlock received_trailers_;
+
+  // Headers accumulator for decoding HEADERS frame payload.
+  std::unique_ptr<QpackDecodedHeadersAccumulator>
+      qpack_decoded_headers_accumulator_;
+  // Reason for `qpack_decoded_headers_accumulator_` being nullptr.
+  QpackDecodedHeadersAccumulatorResetReason
+      qpack_decoded_headers_accumulator_reset_reason_;
+  // Visitor of the HttpDecoder.
+  std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
+  // HttpDecoder for processing raw incoming stream frames.
+  HttpDecoder decoder_;
+  // Object that manages references to DATA frame payload fragments buffered by
+  // the sequencer and calculates how much data should be marked consumed with
+  // the sequencer each time new stream data is processed.
+  QuicSpdyStreamBodyManager body_manager_;
+
+  std::unique_ptr<CapsuleParser> capsule_parser_;
+
+  // Sequencer offset keeping track of how much data HttpDecoder has processed.
+  // Initial value is zero for fresh streams, or sequencer()->NumBytesConsumed()
+  // at time of construction if a PendingStream is converted to account for the
+  // length of the unidirectional stream type at the beginning of the stream.
+  QuicStreamOffset sequencer_offset_;
+
+  // True when inside an HttpDecoder::ProcessInput() call.
+  // Used for detecting reentrancy.
+  bool is_decoder_processing_input_;
+
+  // Ack listener of this stream, and it is notified when any of written bytes
+  // are acked or retransmitted.
+  quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;
+
+  // Offset of unacked frame headers.
+  QuicIntervalSet<QuicStreamOffset> unacked_frame_headers_offsets_;
+
+  // Urgency value sent in the last PRIORITY_UPDATE frame, or default urgency
+  // defined by the spec if no PRIORITY_UPDATE frame has been sent.
+  int last_sent_urgency_;
+
+  // If this stream is a WebTransport extended CONNECT stream, contains the
+  // WebTransport session associated with this stream.
+  std::unique_ptr<WebTransportHttp3> web_transport_;
+
+  // If this stream is a WebTransport data stream, |web_transport_data_|
+  // contains all of the associated metadata.
+  std::unique_ptr<WebTransportDataStream> web_transport_data_;
+
+  // HTTP/3 Datagram support.
+  Http3DatagramRegistrationVisitor* datagram_registration_visitor_ = nullptr;
+  Http3DatagramVisitor* datagram_no_context_visitor_ = nullptr;
+  absl::optional<QuicDatagramStreamId> datagram_flow_id_;
+  QuicDatagramContextId datagram_next_available_context_id_;
+  absl::flat_hash_map<QuicDatagramContextId, Http3DatagramVisitor*>
+      datagram_context_visitors_;
+  bool use_datagram_contexts_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
diff --git a/quiche/quic/core/http/quic_spdy_stream_body_manager.cc b/quiche/quic/core/http/quic_spdy_stream_body_manager.cc
new file mode 100644
index 0000000..d1ba5d2
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_body_manager.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
+
+#include <algorithm>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSpdyStreamBodyManager::QuicSpdyStreamBodyManager()
+    : total_body_bytes_received_(0) {}
+
+size_t QuicSpdyStreamBodyManager::OnNonBody(QuicByteCount length) {
+  QUICHE_DCHECK_NE(0u, length);
+
+  if (fragments_.empty()) {
+    // Non-body bytes can be consumed immediately, because all previously
+    // received body bytes have been read.
+    return length;
+  }
+
+  // Non-body bytes will be consumed after last body fragment is read.
+  fragments_.back().trailing_non_body_byte_count += length;
+  return 0;
+}
+
+void QuicSpdyStreamBodyManager::OnBody(absl::string_view body) {
+  QUICHE_DCHECK(!body.empty());
+
+  fragments_.push_back({body, 0});
+  total_body_bytes_received_ += body.length();
+}
+
+size_t QuicSpdyStreamBodyManager::OnBodyConsumed(size_t num_bytes) {
+  QuicByteCount bytes_to_consume = 0;
+  size_t remaining_bytes = num_bytes;
+
+  while (remaining_bytes > 0) {
+    if (fragments_.empty()) {
+      QUIC_BUG(quic_bug_10394_1) << "Not enough available body to consume.";
+      return 0;
+    }
+
+    Fragment& fragment = fragments_.front();
+    const absl::string_view body = fragment.body;
+
+    if (body.length() > remaining_bytes) {
+      // Consume leading |remaining_bytes| bytes of body.
+      bytes_to_consume += remaining_bytes;
+      fragment.body = body.substr(remaining_bytes);
+      return bytes_to_consume;
+    }
+
+    // Consume entire fragment and the following
+    // |trailing_non_body_byte_count| bytes.
+    remaining_bytes -= body.length();
+    bytes_to_consume += body.length() + fragment.trailing_non_body_byte_count;
+    fragments_.pop_front();
+  }
+
+  return bytes_to_consume;
+}
+
+int QuicSpdyStreamBodyManager::PeekBody(iovec* iov, size_t iov_len) const {
+  QUICHE_DCHECK(iov);
+  QUICHE_DCHECK_GT(iov_len, 0u);
+
+  // TODO(bnc): Is this really necessary?
+  if (fragments_.empty()) {
+    iov[0].iov_base = nullptr;
+    iov[0].iov_len = 0;
+    return 0;
+  }
+
+  size_t iov_filled = 0;
+  while (iov_filled < fragments_.size() && iov_filled < iov_len) {
+    absl::string_view body = fragments_[iov_filled].body;
+    iov[iov_filled].iov_base = const_cast<char*>(body.data());
+    iov[iov_filled].iov_len = body.size();
+    iov_filled++;
+  }
+
+  return iov_filled;
+}
+
+size_t QuicSpdyStreamBodyManager::ReadBody(const struct iovec* iov,
+                                           size_t iov_len,
+                                           size_t* total_bytes_read) {
+  *total_bytes_read = 0;
+  QuicByteCount bytes_to_consume = 0;
+
+  // The index of iovec to write to.
+  size_t index = 0;
+  // Address to write to within current iovec.
+  char* dest = reinterpret_cast<char*>(iov[index].iov_base);
+  // Remaining space in current iovec.
+  size_t dest_remaining = iov[index].iov_len;
+
+  while (!fragments_.empty()) {
+    Fragment& fragment = fragments_.front();
+    const absl::string_view body = fragment.body;
+
+    const size_t bytes_to_copy =
+        std::min<size_t>(body.length(), dest_remaining);
+    memcpy(dest, body.data(), bytes_to_copy);
+    bytes_to_consume += bytes_to_copy;
+    *total_bytes_read += bytes_to_copy;
+
+    if (bytes_to_copy == body.length()) {
+      // Entire fragment read.
+      bytes_to_consume += fragment.trailing_non_body_byte_count;
+      fragments_.pop_front();
+    } else {
+      // Consume leading |bytes_to_copy| bytes of body.
+      fragment.body = body.substr(bytes_to_copy);
+    }
+
+    if (bytes_to_copy == dest_remaining) {
+      // Current iovec full.
+      ++index;
+      if (index == iov_len) {
+        break;
+      }
+      dest = reinterpret_cast<char*>(iov[index].iov_base);
+      dest_remaining = iov[index].iov_len;
+    } else {
+      // Advance destination parameters within this iovec.
+      dest += bytes_to_copy;
+      dest_remaining -= bytes_to_copy;
+    }
+  }
+
+  return bytes_to_consume;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream_body_manager.h b/quiche/quic/core/http/quic_spdy_stream_body_manager.h
new file mode 100644
index 0000000..fbd4420
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_body_manager.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
+#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+// All data that a request stream receives falls into one of two categories:
+//  * "body", that is, DATA frame payload, which the QuicStreamSequencer must
+//    buffer until it is read;
+//  * everything else, which QuicSpdyStream immediately processes and thus could
+//    be marked as consumed with QuicStreamSequencer, unless there is some piece
+//    of body received prior that still needs to be buffered.
+// QuicSpdyStreamBodyManager does two things: it keeps references to body
+// fragments (owned by QuicStreamSequencer) and offers methods to read them; and
+// it calculates the total number of bytes (including non-body bytes) the caller
+// needs to mark consumed (with QuicStreamSequencer) when non-body bytes are
+// received or when body is consumed.
+class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager {
+ public:
+  QuicSpdyStreamBodyManager();
+  ~QuicSpdyStreamBodyManager() = default;
+
+  // One of the following two methods must be called every time data is received
+  // on the request stream.
+
+  // Called when data that could immediately be marked consumed with the
+  // sequencer (provided that all previous body fragments are consumed) is
+  // received.  |length| must be positive.  Returns number of bytes the caller
+  // must mark consumed, which might be zero.
+  ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length);
+
+  // Called when body is received.  |body| is added to |fragments_|.  The data
+  // pointed to by |body| must be kept alive until an OnBodyConsumed() or
+  // ReadBody() call consumes it.  |body| must not be empty.
+  void OnBody(absl::string_view body);
+
+  // Internally marks |num_bytes| of body consumed.  |num_bytes| might be zero.
+  // Returns the number of bytes that the caller should mark consumed with the
+  // sequencer, which is the sum of |num_bytes| for body, and the number of any
+  // interleaving or immediately trailing non-body bytes.
+  ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes);
+
+  // Set up to |iov_len| elements of iov[] to point to available bodies: each
+  // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be
+  // set to its length.  No data is copied, no data is consumed.  Returns the
+  // number of iov set.
+  int PeekBody(iovec* iov, size_t iov_len) const;
+
+  // Copies data from available bodies into at most |iov_len| elements of iov[].
+  // Internally consumes copied body bytes as well as all interleaving and
+  // immediately trailing non-body bytes.  |iov.iov_base| and |iov.iov_len| are
+  // preassigned and will not be changed.  Returns the total number of bytes the
+  // caller shall mark consumed.  Sets |*total_bytes_read| to the total number
+  // of body bytes read.
+  ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov,
+                                       size_t iov_len,
+                                       size_t* total_bytes_read);
+
+  bool HasBytesToRead() const { return !fragments_.empty(); }
+
+  uint64_t total_body_bytes_received() const {
+    return total_body_bytes_received_;
+  }
+
+ private:
+  // A Fragment instance represents a body fragment with a count of bytes
+  // received afterwards but before the next body fragment that can be marked
+  // consumed as soon as all of the body fragment is read.
+  struct QUIC_EXPORT_PRIVATE Fragment {
+    // |body| must not be empty.
+    absl::string_view body;
+    // Might be zero.
+    QuicByteCount trailing_non_body_byte_count;
+  };
+  // Queue of body fragments and trailing non-body byte counts.
+  quiche::QuicheCircularDeque<Fragment> fragments_;
+  // Total body bytes received.
+  QuicByteCount total_body_bytes_received_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
diff --git a/quiche/quic/core/http/quic_spdy_stream_body_manager_test.cc b/quiche/quic/core/http/quic_spdy_stream_body_manager_test.cc
new file mode 100644
index 0000000..7eca731
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_body_manager_test.cc
@@ -0,0 +1,286 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
+
+#include <algorithm>
+#include <numeric>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class QuicSpdyStreamBodyManagerTest : public QuicTest {
+ protected:
+  QuicSpdyStreamBodyManager body_manager_;
+};
+
+TEST_F(QuicSpdyStreamBodyManagerTest, HasBytesToRead) {
+  EXPECT_FALSE(body_manager_.HasBytesToRead());
+  EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
+
+  const QuicByteCount header_length = 3;
+  EXPECT_EQ(header_length, body_manager_.OnNonBody(header_length));
+
+  EXPECT_FALSE(body_manager_.HasBytesToRead());
+  EXPECT_EQ(0u, body_manager_.total_body_bytes_received());
+
+  std::string body(1024, 'a');
+  body_manager_.OnBody(body);
+
+  EXPECT_TRUE(body_manager_.HasBytesToRead());
+  EXPECT_EQ(1024u, body_manager_.total_body_bytes_received());
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, ConsumeMoreThanAvailable) {
+  std::string body(1024, 'a');
+  body_manager_.OnBody(body);
+  size_t bytes_to_consume = 0;
+  EXPECT_QUIC_BUG(bytes_to_consume = body_manager_.OnBodyConsumed(2048),
+                  "Not enough available body to consume.");
+  EXPECT_EQ(0u, bytes_to_consume);
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, OnBodyConsumed) {
+  struct {
+    std::vector<QuicByteCount> frame_header_lengths;
+    std::vector<const char*> frame_payloads;
+    std::vector<QuicByteCount> body_bytes_to_read;
+    std::vector<QuicByteCount> expected_return_values;
+  } const kOnBodyConsumedTestData[] = {
+      // One frame consumed in one call.
+      {{2}, {"foobar"}, {6}, {6}},
+      // Two frames consumed in one call.
+      {{3, 5}, {"foobar", "baz"}, {9}, {14}},
+      // One frame consumed in two calls.
+      {{2}, {"foobar"}, {4, 2}, {4, 2}},
+      // Two frames consumed in two calls matching frame boundaries.
+      {{3, 5}, {"foobar", "baz"}, {6, 3}, {11, 3}},
+      // Two frames consumed in two calls,
+      // the first call only consuming part of the first frame.
+      {{3, 5}, {"foobar", "baz"}, {5, 4}, {5, 9}},
+      // Two frames consumed in two calls,
+      // the first call consuming the entire first frame and part of the second.
+      {{3, 5}, {"foobar", "baz"}, {7, 2}, {12, 2}},
+  };
+
+  for (size_t test_case_index = 0;
+       test_case_index < ABSL_ARRAYSIZE(kOnBodyConsumedTestData);
+       ++test_case_index) {
+    const std::vector<QuicByteCount>& frame_header_lengths =
+        kOnBodyConsumedTestData[test_case_index].frame_header_lengths;
+    const std::vector<const char*>& frame_payloads =
+        kOnBodyConsumedTestData[test_case_index].frame_payloads;
+    const std::vector<QuicByteCount>& body_bytes_to_read =
+        kOnBodyConsumedTestData[test_case_index].body_bytes_to_read;
+    const std::vector<QuicByteCount>& expected_return_values =
+        kOnBodyConsumedTestData[test_case_index].expected_return_values;
+
+    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
+         ++frame_index) {
+      // Frame header of first frame can immediately be consumed, but not the
+      // other frames.  Each test case start with an empty
+      // QuicSpdyStreamBodyManager.
+      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
+                body_manager_.OnNonBody(frame_header_lengths[frame_index]));
+      body_manager_.OnBody(frame_payloads[frame_index]);
+    }
+
+    for (size_t call_index = 0; call_index < body_bytes_to_read.size();
+         ++call_index) {
+      EXPECT_EQ(expected_return_values[call_index],
+                body_manager_.OnBodyConsumed(body_bytes_to_read[call_index]));
+    }
+
+    EXPECT_FALSE(body_manager_.HasBytesToRead());
+  }
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, PeekBody) {
+  struct {
+    std::vector<QuicByteCount> frame_header_lengths;
+    std::vector<const char*> frame_payloads;
+    size_t iov_len;
+  } const kPeekBodyTestData[] = {
+      // No frames, more iovecs than frames.
+      {{}, {}, 1},
+      // One frame, same number of iovecs.
+      {{3}, {"foobar"}, 1},
+      // One frame, more iovecs than frames.
+      {{3}, {"foobar"}, 2},
+      // Two frames, fewer iovecs than frames.
+      {{3, 5}, {"foobar", "baz"}, 1},
+      // Two frames, same number of iovecs.
+      {{3, 5}, {"foobar", "baz"}, 2},
+      // Two frames, more iovecs than frames.
+      {{3, 5}, {"foobar", "baz"}, 3},
+  };
+
+  for (size_t test_case_index = 0;
+       test_case_index < ABSL_ARRAYSIZE(kPeekBodyTestData); ++test_case_index) {
+    const std::vector<QuicByteCount>& frame_header_lengths =
+        kPeekBodyTestData[test_case_index].frame_header_lengths;
+    const std::vector<const char*>& frame_payloads =
+        kPeekBodyTestData[test_case_index].frame_payloads;
+    size_t iov_len = kPeekBodyTestData[test_case_index].iov_len;
+
+    QuicSpdyStreamBodyManager body_manager;
+
+    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
+         ++frame_index) {
+      // Frame header of first frame can immediately be consumed, but not the
+      // other frames.  Each test case uses a new QuicSpdyStreamBodyManager
+      // instance.
+      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
+                body_manager.OnNonBody(frame_header_lengths[frame_index]));
+      body_manager.OnBody(frame_payloads[frame_index]);
+    }
+
+    std::vector<iovec> iovecs;
+    iovecs.resize(iov_len);
+    size_t iovs_filled = std::min(frame_payloads.size(), iov_len);
+    ASSERT_EQ(iovs_filled,
+              static_cast<size_t>(body_manager.PeekBody(&iovecs[0], iov_len)));
+    for (size_t iovec_index = 0; iovec_index < iovs_filled; ++iovec_index) {
+      EXPECT_EQ(frame_payloads[iovec_index],
+                absl::string_view(
+                    static_cast<const char*>(iovecs[iovec_index].iov_base),
+                    iovecs[iovec_index].iov_len));
+    }
+  }
+}
+
+TEST_F(QuicSpdyStreamBodyManagerTest, ReadBody) {
+  struct {
+    std::vector<QuicByteCount> frame_header_lengths;
+    std::vector<const char*> frame_payloads;
+    std::vector<std::vector<QuicByteCount>> iov_lengths;
+    std::vector<QuicByteCount> expected_total_bytes_read;
+    std::vector<QuicByteCount> expected_return_values;
+  } const kReadBodyTestData[] = {
+      // One frame, one read with smaller iovec.
+      {{4}, {"foo"}, {{2}}, {2}, {2}},
+      // One frame, one read with same size iovec.
+      {{4}, {"foo"}, {{3}}, {3}, {3}},
+      // One frame, one read with larger iovec.
+      {{4}, {"foo"}, {{5}}, {3}, {3}},
+      // One frame, one read with two iovecs, smaller total size.
+      {{4}, {"foobar"}, {{2, 3}}, {5}, {5}},
+      // One frame, one read with two iovecs, same total size.
+      {{4}, {"foobar"}, {{2, 4}}, {6}, {6}},
+      // One frame, one read with two iovecs, larger total size in last iovec.
+      {{4}, {"foobar"}, {{2, 6}}, {6}, {6}},
+      // One frame, one read with extra iovecs, body ends at iovec boundary.
+      {{4}, {"foobar"}, {{2, 4, 4, 3}}, {6}, {6}},
+      // One frame, one read with extra iovecs, body ends not at iovec boundary.
+      {{4}, {"foobar"}, {{2, 7, 4, 3}}, {6}, {6}},
+      // One frame, two reads with two iovecs each, smaller total size.
+      {{4}, {"foobarbaz"}, {{2, 1}, {3, 2}}, {3, 5}, {3, 5}},
+      // One frame, two reads with two iovecs each, same total size.
+      {{4}, {"foobarbaz"}, {{2, 1}, {4, 2}}, {3, 6}, {3, 6}},
+      // One frame, two reads with two iovecs each, larger total size.
+      {{4}, {"foobarbaz"}, {{2, 1}, {4, 10}}, {3, 6}, {3, 6}},
+      // Two frames, one read with smaller iovec.
+      {{4, 3}, {"foobar", "baz"}, {{8}}, {8}, {11}},
+      // Two frames, one read with same size iovec.
+      {{4, 3}, {"foobar", "baz"}, {{9}}, {9}, {12}},
+      // Two frames, one read with larger iovec.
+      {{4, 3}, {"foobar", "baz"}, {{10}}, {9}, {12}},
+      // Two frames, one read with two iovecs, smaller total size.
+      {{4, 3}, {"foobar", "baz"}, {{4, 3}}, {7}, {10}},
+      // Two frames, one read with two iovecs, same total size.
+      {{4, 3}, {"foobar", "baz"}, {{4, 5}}, {9}, {12}},
+      // Two frames, one read with two iovecs, larger total size in last iovec.
+      {{4, 3}, {"foobar", "baz"}, {{4, 6}}, {9}, {12}},
+      // Two frames, one read with extra iovecs, body ends at iovec boundary.
+      {{4, 3}, {"foobar", "baz"}, {{4, 6, 4, 3}}, {9}, {12}},
+      // Two frames, one read with extra iovecs, body ends not at iovec
+      // boundary.
+      {{4, 3}, {"foobar", "baz"}, {{4, 7, 4, 3}}, {9}, {12}},
+      // Two frames, two reads with two iovecs each, reads end on frame
+      // boundary.
+      {{4, 3}, {"foobar", "baz"}, {{2, 4}, {2, 1}}, {6, 3}, {9, 3}},
+      // Three frames, three reads, extra iovecs, no iovec ends on frame
+      // boundary.
+      {{4, 3, 6},
+       {"foobar", "bazquux", "qux"},
+       {{4, 3}, {2, 3}, {5, 3}},
+       {7, 5, 4},
+       {10, 5, 10}},
+  };
+
+  for (size_t test_case_index = 0;
+       test_case_index < ABSL_ARRAYSIZE(kReadBodyTestData); ++test_case_index) {
+    const std::vector<QuicByteCount>& frame_header_lengths =
+        kReadBodyTestData[test_case_index].frame_header_lengths;
+    const std::vector<const char*>& frame_payloads =
+        kReadBodyTestData[test_case_index].frame_payloads;
+    const std::vector<std::vector<QuicByteCount>>& iov_lengths =
+        kReadBodyTestData[test_case_index].iov_lengths;
+    const std::vector<QuicByteCount>& expected_total_bytes_read =
+        kReadBodyTestData[test_case_index].expected_total_bytes_read;
+    const std::vector<QuicByteCount>& expected_return_values =
+        kReadBodyTestData[test_case_index].expected_return_values;
+
+    QuicSpdyStreamBodyManager body_manager;
+
+    std::string received_body;
+
+    for (size_t frame_index = 0; frame_index < frame_header_lengths.size();
+         ++frame_index) {
+      // Frame header of first frame can immediately be consumed, but not the
+      // other frames.  Each test case uses a new QuicSpdyStreamBodyManager
+      // instance.
+      EXPECT_EQ(frame_index == 0 ? frame_header_lengths[frame_index] : 0u,
+                body_manager.OnNonBody(frame_header_lengths[frame_index]));
+      body_manager.OnBody(frame_payloads[frame_index]);
+      received_body.append(frame_payloads[frame_index]);
+    }
+
+    std::string read_body;
+
+    for (size_t call_index = 0; call_index < iov_lengths.size(); ++call_index) {
+      // Allocate single buffer for iovecs.
+      size_t total_iov_length = std::accumulate(iov_lengths[call_index].begin(),
+                                                iov_lengths[call_index].end(),
+                                                static_cast<size_t>(0));
+      std::string buffer(total_iov_length, 'z');
+
+      // Construct iovecs pointing to contiguous areas in the buffer.
+      std::vector<iovec> iovecs;
+      size_t offset = 0;
+      for (size_t iov_length : iov_lengths[call_index]) {
+        QUICHE_CHECK(offset + iov_length <= buffer.size());
+        iovecs.push_back({&buffer[offset], iov_length});
+        offset += iov_length;
+      }
+
+      // Make sure |total_bytes_read| differs from |expected_total_bytes_read|.
+      size_t total_bytes_read = expected_total_bytes_read[call_index] + 12;
+      EXPECT_EQ(
+          expected_return_values[call_index],
+          body_manager.ReadBody(&iovecs[0], iovecs.size(), &total_bytes_read));
+      read_body.append(buffer.substr(0, total_bytes_read));
+    }
+
+    EXPECT_EQ(received_body.substr(0, read_body.size()), read_body);
+    EXPECT_EQ(read_body.size() < received_body.size(),
+              body_manager.HasBytesToRead());
+  }
+}
+
+}  // anonymous namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/quic_spdy_stream_test.cc b/quiche/quic/core/http/quic_spdy_stream_test.cc
new file mode 100644
index 0000000..b0c972d
--- /dev/null
+++ b/quiche/quic/core/http/quic_spdy_stream_test.cc
@@ -0,0 +1,3456 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using spdy::kV3HighestPriority;
+using spdy::kV3LowestPriority;
+using spdy::SpdyHeaderBlock;
+using spdy::SpdyPriority;
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::DoAll;
+using testing::ElementsAre;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::MatchesRegex;
+using testing::Pair;
+using testing::Return;
+using testing::SaveArg;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const bool kShouldProcessData = true;
+const char kDataFramePayload[] = "some data";
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        one_rtt_keys_available_(false),
+        params_(new QuicCryptoNegotiatedParameters) {
+    // Simulate a negotiated cipher_suite with a fake value.
+    params_->cipher_suite = 1;
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    one_rtt_keys_available_ = true;
+    QuicErrorCode error;
+    std::string error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (session()->version().UsesTls()) {
+      if (session()->perspective() == Perspective::IS_CLIENT) {
+        session()->config()->SetOriginalConnectionIdToSend(
+            session()->connection()->connection_id());
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->connection_id());
+      } else {
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->client_connection_id());
+      }
+      TransportParameters transport_parameters;
+      EXPECT_TRUE(
+          session()->config()->FillTransportParameters(&transport_parameters));
+      error = session()->config()->ProcessTransportParameters(
+          transport_parameters, /* is_resumption = */ false, &error_details);
+    } else {
+      CryptoHandshakeMessage msg;
+      session()->config()->ToHandshakeMessage(&msg, transport_version());
+      error =
+          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    }
+    EXPECT_THAT(error, IsQuicNoError());
+    session()->OnNewEncryptionKeyAvailable(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+    session()->OnConfigNegotiated();
+    if (session()->version().UsesTls()) {
+      session()->OnTlsHandshakeComplete();
+    } else {
+      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    if (session()->version().UsesTls()) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*this, HasPendingRetransmission());
+    }
+    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  }
+
+  // QuicCryptoStream implementation
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool one_rtt_keys_available() const override {
+    return one_rtt_keys_available_;
+  }
+  HandshakeState GetHandshakeState() const override {
+    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+  }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+
+  bool HasPendingCryptoRetransmission() const override { return false; }
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestStream : public QuicSpdyStream {
+ public:
+  TestStream(QuicStreamId id, QuicSpdySession* session,
+             bool should_process_data)
+      : QuicSpdyStream(id, session, BIDIRECTIONAL),
+        should_process_data_(should_process_data),
+        headers_payload_length_(0) {}
+  ~TestStream() override = default;
+
+  using QuicSpdyStream::set_ack_listener;
+  using QuicStream::CloseWriteSide;
+  using QuicStream::WriteOrBufferData;
+
+  void OnBodyAvailable() override {
+    if (!should_process_data_) {
+      return;
+    }
+    char buffer[2048];
+    struct iovec vec;
+    vec.iov_base = buffer;
+    vec.iov_len = ABSL_ARRAYSIZE(buffer);
+    size_t bytes_read = Readv(&vec, 1);
+    data_ += std::string(buffer, bytes_read);
+  }
+
+  MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
+
+  size_t WriteHeadersImpl(
+      spdy::SpdyHeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+      /*ack_listener*/) override {
+    saved_headers_ = std::move(header_block);
+    WriteHeadersMock(fin);
+    if (VersionUsesHttp3(transport_version())) {
+      // In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
+      // actual work of closing the stream.
+      return QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin,
+                                              nullptr);
+    }
+    return 0;
+  }
+
+  const std::string& data() const { return data_; }
+  const spdy::SpdyHeaderBlock& saved_headers() const { return saved_headers_; }
+
+  // Expose protected accessor.
+  const QuicStreamSequencer* sequencer() const {
+    return QuicStream::sequencer();
+  }
+
+  void OnStreamHeaderList(bool fin, size_t frame_len,
+                          const QuicHeaderList& header_list) override {
+    headers_payload_length_ = frame_len;
+    QuicSpdyStream::OnStreamHeaderList(fin, frame_len, header_list);
+  }
+
+  size_t headers_payload_length() const { return headers_payload_length_; }
+
+  bool AreHeadersValid(const QuicHeaderList& header_list) const override {
+    return !GetQuicReloadableFlag(quic_verify_request_headers_2) ||
+           QuicSpdyStream::AreHeadersValid(header_list);
+  }
+
+ private:
+  bool should_process_data_;
+  spdy::SpdyHeaderBlock saved_headers_;
+  std::string data_;
+  size_t headers_payload_length_;
+};
+
+class TestSession : public MockQuicSpdySession {
+ public:
+  explicit TestSession(QuicConnection* connection)
+      : MockQuicSpdySession(connection, /*create_mock_crypto_stream=*/false),
+        crypto_stream_(this) {}
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  bool ShouldNegotiateWebTransport() override { return enable_webtransport_; }
+  void EnableWebTransport() { enable_webtransport_ = true; }
+
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    return local_http_datagram_support_;
+  }
+  void set_local_http_datagram_support(HttpDatagramSupport value) {
+    local_http_datagram_support_ = value;
+  }
+
+ private:
+  bool enable_webtransport_ = false;
+  HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
+  StrictMock<TestCryptoStream> crypto_stream_;
+};
+
+class TestMockUpdateStreamSession : public MockQuicSpdySession {
+ public:
+  explicit TestMockUpdateStreamSession(QuicConnection* connection)
+      : MockQuicSpdySession(connection),
+        expected_precedence_(
+            spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority)) {}
+
+  void UpdateStreamPriority(
+      QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence) override {
+    EXPECT_EQ(id, expected_stream_->id());
+    EXPECT_EQ(expected_precedence_, precedence);
+    EXPECT_EQ(expected_precedence_, expected_stream_->precedence());
+  }
+
+  void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
+  void SetExpectedPriority(const spdy::SpdyStreamPrecedence& precedence) {
+    expected_precedence_ = precedence;
+  }
+
+ private:
+  QuicSpdyStream* expected_stream_;
+  spdy::SpdyStreamPrecedence expected_precedence_;
+};
+
+class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSpdyStreamTest() {
+    headers_[":host"] = "www.google.com";
+    headers_[":path"] = "/index.hml";
+    headers_[":scheme"] = "https";
+    headers_["cookie"] =
+        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
+        "__utmc=160408618; "
+        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
+        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
+        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
+        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
+        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
+        "1zFMi5vzcns38-8_Sns; "
+        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
+        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
+        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
+        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
+        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
+        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
+        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
+        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
+        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
+        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
+        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
+        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
+        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
+        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
+        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
+  }
+
+  ~QuicSpdyStreamTest() override = default;
+
+  // Return QPACK-encoded header block without using the dynamic table.
+  std::string EncodeQpackHeaders(
+      std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
+    SpdyHeaderBlock header_block;
+    for (const auto& header_field : headers) {
+      header_block.AppendValueOrAddHeader(header_field.first,
+                                          header_field.second);
+    }
+
+    return EncodeQpackHeaders(header_block);
+  }
+
+  // Return QPACK-encoded header block without using the dynamic table.
+  std::string EncodeQpackHeaders(const SpdyHeaderBlock& header) {
+    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+    auto qpack_encoder = std::make_unique<QpackEncoder>(session_.get());
+    qpack_encoder->set_qpack_stream_sender_delegate(
+        &encoder_stream_sender_delegate);
+    // QpackEncoder does not use the dynamic table by default,
+    // therefore the value of |stream_id| does not matter.
+    return qpack_encoder->EncodeHeaderList(/* stream_id = */ 0, header,
+                                           nullptr);
+  }
+
+  void Initialize(bool stream_should_process_data) {
+    InitializeWithPerspective(stream_should_process_data,
+                              Perspective::IS_SERVER);
+  }
+
+  void InitializeWithPerspective(bool stream_should_process_data,
+                                 Perspective perspective) {
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, perspective, SupportedVersions(GetParam()));
+    session_ = std::make_unique<StrictMock<TestSession>>(connection_);
+    EXPECT_CALL(*session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_->Initialize();
+    if (connection_->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    ON_CALL(*session_, WritevData(_, _, _, _, _, _))
+        .WillByDefault(
+            Invoke(session_.get(), &MockQuicSpdySession::ConsumeData));
+
+    stream_ =
+        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
+                                   session_.get(), stream_should_process_data);
+    session_->ActivateStream(absl::WrapUnique(stream_));
+    stream2_ =
+        new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
+                                   session_.get(), stream_should_process_data);
+    session_->ActivateStream(absl::WrapUnique(stream2_));
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
+    session_->OnConfigNegotiated();
+    if (UsesHttp3()) {
+      // The control stream will write the stream type, a greased frame, and
+      // SETTINGS frame.
+      int num_control_stream_writes = 3;
+      auto send_control_stream =
+          QuicSpdySessionPeer::GetSendControlStream(session_.get());
+      EXPECT_CALL(*session_,
+                  WritevData(send_control_stream->id(), _, _, _, _, _))
+          .Times(num_control_stream_writes);
+    }
+    TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission()).Times(AnyNumber());
+
+    if (connection_->version().UsesTls() &&
+        session_->perspective() == Perspective::IS_SERVER) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    }
+    CryptoHandshakeMessage message;
+    session_->GetMutableCryptoStream()->OnHandshakeMessage(message);
+  }
+
+  QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) {
+    QuicHeaderList h = AsHeaderList(headers);
+    stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
+    return h;
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(
+        connection_->transport_version(), n);
+  }
+
+  bool UsesHttp3() const {
+    return VersionUsesHttp3(GetParam().transport_version);
+  }
+
+  // Construct HEADERS frame with QPACK-encoded |headers| without using the
+  // dynamic table.
+  std::string HeadersFrame(
+      std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
+    return HeadersFrame(EncodeQpackHeaders(headers));
+  }
+
+  // Construct HEADERS frame with QPACK-encoded |headers| without using the
+  // dynamic table.
+  std::string HeadersFrame(const SpdyHeaderBlock& headers) {
+    return HeadersFrame(EncodeQpackHeaders(headers));
+  }
+
+  // Construct HEADERS frame with given payload.
+  std::string HeadersFrame(absl::string_view payload) {
+    std::unique_ptr<char[]> headers_buffer;
+    QuicByteCount headers_frame_header_length =
+        HttpEncoder::SerializeHeadersFrameHeader(payload.length(),
+                                                 &headers_buffer);
+    absl::string_view headers_frame_header(headers_buffer.get(),
+                                           headers_frame_header_length);
+    return absl::StrCat(headers_frame_header, payload);
+  }
+
+  std::string DataFrame(absl::string_view payload) {
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        payload.length(), quiche::SimpleBufferAllocator::Get());
+    return absl::StrCat(header.AsStringView(), payload);
+  }
+
+  std::string UnknownFrame(uint64_t frame_type, absl::string_view payload) {
+    std::string frame;
+    const size_t length = QuicDataWriter::GetVarInt62Len(frame_type) +
+                          QuicDataWriter::GetVarInt62Len(payload.size()) +
+                          payload.size();
+    frame.resize(length);
+
+    QuicDataWriter writer(length, const_cast<char*>(frame.data()));
+    writer.WriteVarInt62(frame_type);
+    writer.WriteStringPieceVarInt62(payload);
+    // Even though integers can be encoded with different lengths,
+    // QuicDataWriter is expected to produce an encoding in Write*() of length
+    // promised in GetVarInt62Len().
+    QUICHE_DCHECK_EQ(length, writer.length());
+
+    return frame;
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<TestSession> session_;
+
+  // Owned by the |session_|.
+  TestStream* stream_;
+  TestStream* stream2_;
+
+  SpdyHeaderBlock headers_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
+  Initialize(kShouldProcessData);
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
+  Initialize(kShouldProcessData);
+
+  if (!UsesHttp3()) {
+    QuicHeaderList headers;
+    stream_->OnStreamHeadersPriority(
+        spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+    EXPECT_CALL(
+        *session_,
+        MaybeSendRstStreamFrame(
+            stream_->id(),
+            QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
+    stream_->OnStreamHeaderList(false, 1 << 20, headers);
+
+    EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
+
+    return;
+  }
+
+  // Header list size includes 32 bytes for overhead per header field.
+  session_->set_max_inbound_header_list_size(40);
+  std::string headers =
+      HeadersFrame({std::make_pair("foo", "too long headers")});
+
+  QuicStreamFrame frame(stream_->id(), false, 0, headers);
+
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             stream_->id(), QuicResetStreamError::FromInternal(
+                                                QUIC_HEADERS_TOO_LARGE)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
+
+  auto qpack_decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  // Stream type and stream cancellation.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), _, _, NO_FIN, _, _))
+      .Times(2);
+
+  stream_->OnStreamFrame(frame);
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
+}
+
+TEST_P(QuicSpdyStreamTest, QpackProcessLargeHeaderListDiscountOverhead) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  // Setting this flag to false causes no per-entry overhead to be included
+  // in the header size.
+  SetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead, false);
+  Initialize(kShouldProcessData);
+  session_->set_max_inbound_header_list_size(40);
+  std::string headers =
+      HeadersFrame({std::make_pair("foo", "too long headers")});
+
+  QuicStreamFrame frame(stream_->id(), false, 0, headers);
+  stream_->OnStreamFrame(frame);
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_NO_ERROR));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
+  Initialize(kShouldProcessData);
+
+  size_t total_bytes = 0;
+  QuicHeaderList headers;
+  for (auto p : headers_) {
+    headers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  stream_->OnStreamHeaderList(true, total_bytes, headers);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+// A valid status code should be 3-digit integer. The first digit should be in
+// the range of [1, 5]. All the others are invalid.
+TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
+  Initialize(kShouldProcessData);
+  int status_code = 0;
+
+  // Valid status codes.
+  headers_[":status"] = "404";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(404, status_code);
+
+  headers_[":status"] = "100";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(100, status_code);
+
+  headers_[":status"] = "599";
+  EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+  EXPECT_EQ(599, status_code);
+
+  // Invalid status codes.
+  headers_[":status"] = "010";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "600";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "200 ok";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "2000";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "+200";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "+20";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "-10";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "-100";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  // Leading or trailing spaces are also invalid.
+  headers_[":status"] = " 200";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "200 ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = " 200 ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+
+  headers_[":status"] = "  ";
+  EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
+}
+
+TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
+  Initialize(kShouldProcessData);
+
+  std::string body = "this is the body";
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+
+  stream_->ConsumeHeaderList();
+  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  GoAwayFrame goaway;
+  goaway.id = 0x1;
+  std::unique_ptr<char[]> buffer;
+  QuicByteCount header_length =
+      HttpEncoder::SerializeGoAwayFrame(goaway, &buffer);
+  std::string data = std::string(buffer.get(), header_length);
+
+  EXPECT_EQ("", stream_->data());
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+  stream_->ConsumeHeaderList();
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
+      .WillOnce(
+          (Invoke([this](QuicErrorCode error, const std::string& error_details,
+                         ConnectionCloseBehavior connection_close_behavior) {
+            connection_->ReallyCloseConnection(error, error_details,
+                                               connection_close_behavior);
+          })));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(*session_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
+                              ConnectionCloseSource source) {
+        session_->ReallyOnConnectionClosed(frame, source);
+      }));
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
+
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, Http3FrameError) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // PUSH_PROMISE frame with empty payload is considered invalid.
+  std::string invalid_http3_frame = absl::HexStringToBytes("0500");
+  QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
+                               /* offset = */ 0, invalid_http3_frame);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _));
+  stream_->OnStreamFrame(stream_frame);
+}
+
+TEST_P(QuicSpdyStreamTest, UnexpectedHttp3Frame) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // SETTINGS frame with empty payload.
+  std::string settings = absl::HexStringToBytes("0400");
+  QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
+                               /* offset = */ 0, settings);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _));
+  stream_->OnStreamFrame(stream_frame);
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
+  Initialize(kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  EXPECT_EQ("", stream_->data());
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  EXPECT_EQ(headers, stream_->header_list());
+  stream_->ConsumeHeaderList();
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(QuicHeaderList(), stream_->header_list());
+  EXPECT_EQ(body, stream_->data());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
+    Initialize(kShouldProcessData);
+    QuicHeaderList headers = ProcessHeaders(false, headers_);
+    ASSERT_EQ(headers, stream_->header_list());
+    stream_->ConsumeHeaderList();
+    for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
+      size_t remaining_data = data.size() - offset;
+      absl::string_view fragment(data.data() + offset,
+                                 std::min(fragment_size, remaining_data));
+      QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
+                            offset, absl::string_view(fragment));
+      stream_->OnStreamFrame(frame);
+    }
+    ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
+    Initialize(kShouldProcessData);
+    QuicHeaderList headers = ProcessHeaders(false, headers_);
+    ASSERT_EQ(headers, stream_->header_list());
+    stream_->ConsumeHeaderList();
+
+    absl::string_view fragment1(data.data(), split_point);
+    QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                           absl::string_view(fragment1));
+    stream_->OnStreamFrame(frame1);
+
+    absl::string_view fragment2(data.data() + split_point,
+                                data.size() - split_point);
+    QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                           split_point, absl::string_view(fragment2));
+    stream_->OnStreamFrame(frame2);
+
+    ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer[2048];
+  ASSERT_LT(data.length(), ABSL_ARRAYSIZE(buffer));
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = ABSL_ARRAYSIZE(buffer);
+
+  size_t bytes_read = stream_->Readv(&vec, 1);
+  QuicStreamPeer::CloseReadSide(stream_);
+  EXPECT_EQ(body.length(), bytes_read);
+  EXPECT_EQ(body, std::string(buffer, bytes_read));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
+  Initialize(kShouldProcessData);
+  std::string body(12 * 1024, 'a');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+  char buffer[2048];
+  char buffer2[2048];
+  struct iovec vec[2];
+  vec[0].iov_base = buffer;
+  vec[0].iov_len = ABSL_ARRAYSIZE(buffer);
+  vec[1].iov_base = buffer2;
+  vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
+  size_t bytes_read = stream_->Readv(vec, 2);
+  EXPECT_EQ(2048u * 2, bytes_read);
+  EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
+  EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  struct iovec vec;
+
+  EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
+  EXPECT_EQ(body.length(), vec.iov_len);
+  EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
+
+  stream_->MarkConsumed(body.length());
+  EXPECT_EQ(data.length(), QuicStreamPeer::bytes_consumed(stream_));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
+  Initialize(!kShouldProcessData);
+  std::string body1 = "this is body 1";
+  std::string data1 = UsesHttp3() ? DataFrame(body1) : body1;
+  std::string body2 = "body 2";
+  std::string data2 = UsesHttp3() ? DataFrame(body2) : body2;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data1));
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         data1.length(), absl::string_view(data2));
+  stream_->OnStreamFrame(frame1);
+  stream_->OnStreamFrame(frame2);
+  stream_->ConsumeHeaderList();
+
+  stream_->MarkConsumed(body1.length() + body2.length());
+  EXPECT_EQ(data1.length() + data2.length(),
+            QuicStreamPeer::bytes_consumed(stream_));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer[1];
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = ABSL_ARRAYSIZE(buffer);
+
+  for (size_t i = 0; i < body.length(); ++i) {
+    size_t bytes_read = stream_->Readv(&vec, 1);
+    ASSERT_EQ(1u, bytes_read);
+    EXPECT_EQ(body.data()[i], buffer[0]);
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
+  Initialize(!kShouldProcessData);
+
+  std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  ProcessHeaders(false, headers_);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  stream_->OnStreamFrame(frame);
+  stream_->ConsumeHeaderList();
+
+  char buffer1[1];
+  char buffer2[1];
+  struct iovec vec[2];
+  vec[0].iov_base = buffer1;
+  vec[0].iov_len = ABSL_ARRAYSIZE(buffer1);
+  vec[1].iov_base = buffer2;
+  vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
+
+  for (size_t i = 0; i < body.length(); i += 2) {
+    size_t bytes_read = stream_->Readv(vec, 2);
+    ASSERT_EQ(2u, bytes_read) << i;
+    ASSERT_EQ(body.data()[i], buffer1[0]) << i;
+    ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
+  }
+}
+
+// Tests that we send a BLOCKED frame to the peer when we attempt to write, but
+// are flow control blocked.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
+  Initialize(kShouldProcessData);
+  testing::InSequence seq;
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetSendWindowOffset(stream_, kWindow);
+  EXPECT_EQ(kWindow, QuicStreamPeer::SendWindowOffset(stream_));
+
+  // Try to send more data than the flow control limit allows.
+  const uint64_t kOverflow = 15;
+  std::string body(kWindow + kOverflow, 'a');
+
+  const uint64_t kHeaderLength = UsesHttp3() ? 2 : 0;
+  if (UsesHttp3()) {
+    EXPECT_CALL(*session_, WritevData(_, kHeaderLength, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
+  EXPECT_CALL(*session_, SendBlocked(_));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  stream_->WriteOrBufferBody(body, false);
+
+  // Should have sent as much as possible, resulting in no send window left.
+  EXPECT_EQ(0u, QuicStreamPeer::SendWindowSize(stream_));
+
+  // And we should have queued the overflowed data.
+  EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes());
+}
+
+// The flow control receive window decreases whenever we add new bytes to the
+// sequencer, whether they are consumed immediately or buffered. However we only
+// send WINDOW_UPDATE frames based on increasing number of bytes consumed.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
+  // Don't process data - it will be buffered instead.
+  Initialize(!kShouldProcessData);
+
+  // Expect no WINDOW_UPDATE frames to be sent.
+  EXPECT_CALL(*session_, SendWindowUpdate(_, _)).Times(0);
+
+  // Set a small flow control receive window.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
+
+  // Stream receives enough data to fill a fraction of the receive window.
+  std::string body(kWindow / 3, 'a');
+  QuicByteCount header_length = 0;
+  std::string data;
+
+  if (UsesHttp3()) {
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data = absl::StrCat(header.AsStringView(), body);
+    header_length = header.size();
+  } else {
+    data = body;
+  }
+
+  ProcessHeaders(false, headers_);
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data));
+  stream_->OnStreamFrame(frame1);
+  EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
+            QuicStreamPeer::ReceiveWindowSize(stream_));
+
+  // Now receive another frame which results in the receive window being over
+  // half full. This should all be buffered, decreasing the receive window but
+  // not sending WINDOW_UPDATE.
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         kWindow / 3 + header_length, absl::string_view(data));
+  stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length,
+            QuicStreamPeer::ReceiveWindowSize(stream_));
+}
+
+// Tests that on receipt of data, the stream updates its receive window offset
+// appropriately, and sends WINDOW_UPDATE frames when its receive window drops
+// too low.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
+
+  // Stream receives enough data to fill a fraction of the receive window.
+  std::string body(kWindow / 3, 'a');
+  QuicByteCount header_length = 0;
+  std::string data;
+
+  if (UsesHttp3()) {
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data = absl::StrCat(header.AsStringView(), body);
+    header_length = header.size();
+  } else {
+    data = body;
+  }
+
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data));
+  stream_->OnStreamFrame(frame1);
+  EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
+            QuicStreamPeer::ReceiveWindowSize(stream_));
+
+  // Now receive another frame which results in the receive window being over
+  // half full.  This will trigger the stream to increase its receive window
+  // offset and send a WINDOW_UPDATE. The result will be again an available
+  // window of kWindow bytes.
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
+                         kWindow / 3 + header_length, absl::string_view(data));
+  EXPECT_CALL(*session_, SendWindowUpdate(_, _));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  stream_->OnStreamFrame(frame2);
+  EXPECT_EQ(kWindow, QuicStreamPeer::ReceiveWindowSize(stream_));
+}
+
+// Tests that on receipt of data, the connection updates its receive window
+// offset appropriately, and sends WINDOW_UPDATE frames when its receive window
+// drops too low.
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit for streams and connection.
+  const uint64_t kWindow = 36;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
+  QuicStreamPeer::SetReceiveWindowOffset(stream2_, kWindow);
+  QuicStreamPeer::SetMaxReceiveWindow(stream2_, kWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
+                                              kWindow);
+
+  // Supply headers to both streams so that they are happy to receive data.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                              headers);
+  stream_->ConsumeHeaderList();
+  stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+                               headers);
+  stream2_->ConsumeHeaderList();
+
+  // Each stream gets a quarter window of data. This should not trigger a
+  // WINDOW_UPDATE for either stream, nor for the connection.
+  QuicByteCount header_length = 0;
+  std::string body;
+  std::string data;
+  std::string data2;
+  std::string body2(1, 'a');
+
+  if (UsesHttp3()) {
+    body = std::string(kWindow / 4 - 2, 'a');
+    quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data = absl::StrCat(header.AsStringView(), body);
+    header_length = header.size();
+    quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
+        body.length(), quiche::SimpleBufferAllocator::Get());
+    data2 = absl::StrCat(header2.AsStringView(), body2);
+  } else {
+    body = std::string(kWindow / 4, 'a');
+    data = body;
+    data2 = body2;
+  }
+
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         absl::string_view(data));
+  stream_->OnStreamFrame(frame1);
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         absl::string_view(data));
+  stream2_->OnStreamFrame(frame2);
+
+  // Now receive a further single byte on one stream - again this does not
+  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
+  // is over half full and thus a connection WINDOW_UPDATE is sent.
+  EXPECT_CALL(*session_, SendWindowUpdate(_, _));
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
+                         body.length() + header_length,
+                         absl::string_view(data2));
+  stream_->OnStreamFrame(frame3);
+}
+
+// Tests that on if the peer sends too much data (i.e. violates the flow control
+// protocol), then we terminate the connection.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control limit.
+  const uint64_t kWindow = 50;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
+
+  ProcessHeaders(false, headers_);
+
+  // Receive data to overflow the window, violating flow control.
+  std::string body(kWindow + 1, 'a');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
+  Initialize(kShouldProcessData);
+  ProcessHeaders(false, headers_);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
+
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
+
+  if (GetQuicReloadableFlag(quic_fix_on_stream_reset) && UsesHttp3()) {
+    // RESET_STREAM should close the read side but not the write side.
+    EXPECT_TRUE(stream_->read_side_closed());
+    EXPECT_FALSE(stream_->write_side_closed());
+  } else {
+    EXPECT_TRUE(stream_->write_side_closed());
+    EXPECT_FALSE(stream_->reading_stopped());
+  }
+}
+
+// Tests that on if the peer sends too much data (i.e. violates the flow control
+// protocol), at the connection level (rather than the stream level) then we
+// terminate the connection.
+TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control window on streams, and connection.
+  const uint64_t kStreamWindow = 50;
+  const uint64_t kConnectionWindow = 10;
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kStreamWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kConnectionWindow);
+
+  ProcessHeaders(false, headers_);
+
+  // Send enough data to overflow the connection level flow control window.
+  std::string body(kConnectionWindow + 1, 'a');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  EXPECT_LT(data.size(), kStreamWindow);
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        absl::string_view(data));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+// An attempt to write a FIN with no data should not be flow control blocked,
+// even if the send window is 0.
+TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
+  Initialize(kShouldProcessData);
+
+  // Set a flow control limit of zero.
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, 0);
+
+  // Send a frame with a FIN but no data. This should not be blocked.
+  std::string body = "";
+  bool fin = true;
+
+  EXPECT_CALL(*session_, SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
+      .Times(0);
+  EXPECT_CALL(*session_, WritevData(_, 0, _, FIN, _, _));
+
+  stream_->WriteOrBufferBody(body, fin);
+}
+
+// Test that receiving trailing headers from the peer via OnStreamHeaderList()
+// works, and can be read from the stream and consumed.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  size_t total_bytes = 0;
+  QuicHeaderList headers;
+  for (const auto& p : headers_) {
+    headers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  SpdyHeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
+  if (!UsesHttp3()) {
+    // :final-offset pseudo-header is only added if trailers are sent
+    // on the headers stream.
+    trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
+  }
+  total_bytes = 0;
+  QuicHeaderList trailers;
+  for (const auto& p : trailers_block_with_final_offset) {
+    trailers.OnHeader(p.first, p.second);
+    total_bytes += p.first.size() + p.second.size();
+  }
+  stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
+
+  // The trailers should be decompressed, and readable from the stream.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  // IsDoneReading() returns false until trailers marked consumed.
+  EXPECT_FALSE(stream_->IsDoneReading());
+  stream_->MarkTrailersConsumed();
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+// Test that when receiving trailing headers with an offset before response
+// body, stream is closed at the right offset.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
+  // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
+  // request/response stream.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  QuicHeaderList headers = ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  const std::string body = "this is the body";
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  // Receive trailing headers.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  trailers_block[kFinalOffsetHeaderKey] = absl::StrCat(data.size());
+
+  QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
+
+  // The trailers should be decompressed, and readable from the stream.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // The final offset trailer will be consumed by QUIC.
+  trailers_block.erase(kFinalOffsetHeaderKey);
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  // Consuming the trailers erases them from the stream.
+  stream_->MarkTrailersConsumed();
+  EXPECT_TRUE(stream_->FinishedReadingTrailers());
+
+  EXPECT_FALSE(stream_->IsDoneReading());
+  // Receive and consume body.
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
+                        0, data);
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(body, stream_->data());
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+// Test that receiving trailers without a final offset field is an error.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
+  // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
+  // request/response stream.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers, without kFinalOffsetHeaderKey.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = "value1";
+  trailers_block["key2"] = "value2";
+  trailers_block["key3"] = "value3";
+  auto trailers = AsHeaderList(trailers_block);
+
+  // Verify that the trailers block didn't contain a final offset.
+  EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
+
+  // Receipt of the malformed trailers will close the connection.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  stream_->OnStreamHeaderList(/*fin=*/true,
+                              trailers.uncompressed_header_bytes(), trailers);
+}
+
+// Test that received Trailers must always have the FIN set.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
+  // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
+  // HEADERS frame.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers.
+  auto headers = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(/*fin=*/false,
+                              headers.uncompressed_header_bytes(), headers);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers with FIN deliberately set to false.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  auto trailers = AsHeaderList(trailers_block);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  stream_->OnStreamHeaderList(/*fin=*/false,
+                              trailers.uncompressed_header_bytes(), trailers);
+}
+
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
+  // If headers are received with a FIN, no trailers should then arrive.
+  Initialize(kShouldProcessData);
+
+  // If HEADERS frames are sent on the request/response stream, then the
+  // sequencer will signal an error if any stream data arrives after a FIN,
+  // so QuicSpdyStream does not need to.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  // Receive initial headers with FIN set.
+  ProcessHeaders(true, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive trailing headers after FIN already received.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  ProcessHeaders(true, trailers_block);
+}
+
+// If body data are received with a FIN, no trailers should then arrive.
+TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
+  // If HEADERS frames are sent on the request/response stream,
+  // then the sequencer will block them from reaching QuicSpdyStream
+  // after the stream is closed.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive initial headers without FIN set.
+  ProcessHeaders(false, headers_);
+  stream_->ConsumeHeaderList();
+
+  // Receive body data, with FIN.
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
+                        0, "body");
+  stream_->OnStreamFrame(frame);
+
+  // Receive trailing headers after FIN already received.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["foo"] = "bar";
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
+      .Times(1);
+  ProcessHeaders(true, trailers_block);
+}
+
+TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
+  // Verify that a stream receiving headers, body, and no trailers is correctly
+  // marked as done reading on consumption of headers and body.
+  Initialize(kShouldProcessData);
+
+  // Receive and consume initial headers with FIN not set.
+  auto h = AsHeaderList(headers_);
+  stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
+  stream_->ConsumeHeaderList();
+
+  // Receive and consume body with FIN set, and no trailers.
+  std::string body(1024, 'x');
+  std::string data = UsesHttp3() ? DataFrame(body) : body;
+
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
+                        0, data);
+  stream_->OnStreamFrame(frame);
+
+  EXPECT_TRUE(stream_->IsDoneReading());
+}
+
+// Test that writing trailers will send a FIN, as Trailers are the last thing to
+// be sent on a stream.
+TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
+  Initialize(kShouldProcessData);
+
+  if (UsesHttp3()) {
+    // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
+    // Four writes on the request stream: HEADERS frame header and payload both
+    // for headers and trailers.
+    EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
+  }
+
+  // Write the initial headers, without a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Writing trailers implicitly sends a FIN.
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+}
+
+TEST_P(QuicSpdyStreamTest, DoNotSendPriorityUpdateWithDefaultUrgency) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // Four writes on the request stream: HEADERS frame header and payload both
+  // for headers and trailers.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(4);
+
+  // No PRIORITY_UPDATE frames on the control stream,
+  // because the stream has default priority.
+  auto send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _))
+      .Times(0);
+
+  // Write the initial headers, without a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Writing trailers implicitly sends a FIN.
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+}
+
+TEST_P(QuicSpdyStreamTest, ChangePriority) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // Two writes on the request stream: HEADERS frame header and payload.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // PRIORITY_UPDATE frame on the control stream.
+  auto send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
+  PriorityUpdateFrame priority_update;
+  priority_update.prioritized_element_id = 0;
+  priority_update.priority_field_value = "u=0";
+  EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameSent(priority_update));
+  stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+}
+
+TEST_P(QuicSpdyStreamTest, ChangePriorityBeforeWritingHeaders) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+
+  // PRIORITY_UPDATE frame sent on the control stream as soon as SetPriority()
+  // is called, before HEADERS frame is sent.
+  auto send_control_stream =
+      QuicSpdySessionPeer::GetSendControlStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
+
+  stream_->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  testing::Mock::VerifyAndClearExpectations(session_.get());
+
+  // Two writes on the request stream: HEADERS frame header and payload.
+  // PRIORITY_UPDATE frame is not sent this time, because one is already sent.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
+}
+
+// Test that when writing trailers, the trailers that are actually sent to the
+// peer contain the final offset field indicating last byte of data.
+TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
+  Initialize(kShouldProcessData);
+
+  if (UsesHttp3()) {
+    // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
+    // HEADERS frame header and payload on the request stream.
+    EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
+  }
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data to force a non-zero final offset.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  std::string body(1024, 'x');  // 1 kB
+  QuicByteCount header_length = 0;
+  if (UsesHttp3()) {
+    header_length = HttpEncoder::SerializeDataFrameHeader(
+                        body.length(), quiche::SimpleBufferAllocator::Get())
+                        .size();
+  }
+
+  stream_->WriteOrBufferBody(body, false);
+
+  // The final offset field in the trailing headers is populated with the
+  // number of body bytes written (including queued bytes).
+  SpdyHeaderBlock trailers;
+  trailers["trailer key"] = "trailer value";
+
+  SpdyHeaderBlock expected_trailers(trailers.Clone());
+  // :final-offset pseudo-header is only added if trailers are sent
+  // on the headers stream.
+  if (!UsesHttp3()) {
+    expected_trailers[kFinalOffsetHeaderKey] =
+        absl::StrCat(body.length() + header_length);
+  }
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(std::move(trailers), nullptr);
+  EXPECT_EQ(expected_trailers, stream_->saved_headers());
+}
+
+// Test that if trailers are written after all other data has been written
+// (headers and body), that this closes the stream for writing.
+TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
+  Initialize(kShouldProcessData);
+
+  // Expect data being written on the stream.  In addition to that, headers are
+  // also written on the stream in case of IETF QUIC.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data.
+  const int kBodySize = 1 * 1024;  // 1 kB
+  stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
+  EXPECT_EQ(0u, stream_->BufferedDataBytes());
+
+  // Headers and body have been fully written, there is no queued data. Writing
+  // trailers marks the end of this stream, and thus the write side is closed.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+// Test that the stream is not closed for writing when trailers are sent while
+// there are still body bytes queued.
+TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
+  // This test exercises sending trailers on the headers stream while data is
+  // still queued on the response/request stream.  In IETF QUIC, data and
+  // trailers are sent on the same stream, so this test does not apply.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  testing::InSequence seq;
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers.
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/false, nullptr);
+
+  // Write non-zero body data, but only consume partially, ensuring queueing.
+  const int kBodySize = 1 * 1024;  // 1 kB
+  if (UsesHttp3()) {
+    EXPECT_CALL(*session_, WritevData(_, 3, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(*session_, WritevData(_, kBodySize, _, NO_FIN, _, _))
+      .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
+  stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+
+  // Writing trailers will send a FIN, but not close the write side of the
+  // stream as there are queued bytes.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteTrailers(SpdyHeaderBlock(), nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+  EXPECT_FALSE(stream_->write_side_closed());
+
+  // Writing the queued bytes will close the write side of the stream.
+  EXPECT_CALL(*session_, WritevData(_, 1, _, NO_FIN, _, _));
+  stream_->OnCanWrite();
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+// Test that it is not possible to write Trailers after a FIN has been sent.
+TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
+  // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
+  // HEADERS frame.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Write the initial headers, with a FIN.
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+  stream_->WriteHeaders(SpdyHeaderBlock(), /*fin=*/true, nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+
+  // Writing Trailers should fail, as the FIN has already been sent.
+  // populated with the number of body bytes written.
+  EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr),
+                  "Trailers cannot be sent after a FIN");
+}
+
+TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
+  // There is no headers stream if QPACK is used.
+  if (UsesHttp3()) {
+    return;
+  }
+
+  const char kHeader1[] = "Header1";
+  const char kHeader2[] = "Header2";
+  const char kBody1[] = "Test1";
+  const char kBody2[] = "Test2";
+
+  Initialize(kShouldProcessData);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  testing::InSequence s;
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
+      new MockAckListener());
+  quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
+      new MockAckListener());
+  stream_->set_ack_listener(ack_listener1);
+  stream2_->set_ack_listener(ack_listener2);
+
+  session_->headers_stream()->WriteOrBufferData(kHeader1, false, ack_listener1);
+  stream_->WriteOrBufferBody(kBody1, true);
+
+  session_->headers_stream()->WriteOrBufferData(kHeader2, false, ack_listener2);
+  stream2_->WriteOrBufferBody(kBody2, false);
+
+  QuicStreamFrame frame1(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
+      kHeader1);
+
+  std::string data1 = UsesHttp3() ? DataFrame(kBody1) : kBody1;
+  QuicStreamFrame frame2(stream_->id(), true, 0, data1);
+  QuicStreamFrame frame3(
+      QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
+      kHeader2);
+  std::string data2 = UsesHttp3() ? DataFrame(kBody2) : kBody2;
+  QuicStreamFrame frame4(stream2_->id(), false, 0, data2);
+
+  EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
+  session_->OnStreamFrameRetransmitted(frame1);
+
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+  EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+  EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+}
+
+TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
+  Initialize(kShouldProcessData);
+  stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
+            stream_->precedence());
+}
+
+TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
+  Initialize(kShouldProcessData);
+  testing::InSequence seq;
+
+  if (UsesHttp3()) {
+    EXPECT_CALL(*session_, WritevData(_, 2, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(*session_, WritevData(_, 4, _, FIN, _, _));
+  stream_->WriteOrBufferBody("data", true);
+  stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_EQ(spdy::SpdyStreamPrecedence(kV3HighestPriority),
+            stream_->precedence());
+}
+
+TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
+  MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
+      &helper_, &alarm_factory_, Perspective::IS_SERVER,
+      SupportedVersions(GetParam()));
+  std::unique_ptr<TestMockUpdateStreamSession> session(
+      new StrictMock<TestMockUpdateStreamSession>(connection));
+  auto stream =
+      new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalStreamId(
+                                     session->transport_version(), 0),
+                                 session.get(),
+                                 /*should_process_data=*/true);
+  session->ActivateStream(absl::WrapUnique(stream));
+
+  // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
+  // on the session. Make sure stream->priority() returns the updated priority
+  // if called within UpdateStreamPriority(). This expectation is enforced in
+  // TestMockUpdateStreamSession::UpdateStreamPriority().
+  session->SetExpectedStream(stream);
+  session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  stream->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  session->SetExpectedPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  stream->SetPriority(spdy::SpdyStreamPrecedence(kV3LowestPriority));
+}
+
+TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  // Stream is not waiting for acks initially.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData1.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  // Stream is not waiting for acks as all sent data is acked.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData2.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Send FIN.
+  stream_->WriteOrBufferData("", true, nullptr);
+  // Fin only frame is not stored in send buffer.
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // kData2 is retransmitted.
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
+  stream_->OnStreamFrameRetransmitted(9, 9, false);
+
+  // kData2 is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  // Stream is waiting for acks as FIN is not acked.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // FIN is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  // Send [0, 27) and fin.
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  stream_->WriteOrBufferData("FooAndBar", false, nullptr);
+  stream_->WriteOrBufferData("FooAndBar", true, nullptr);
+
+  // Ack [0, 9), [5, 22) and [18, 26)
+  // Verify [0, 9) 9 bytes are acked.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [9, 22) 13 bytes are acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [22, 26) 4 bytes are acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Ack [0, 27).
+  // Verify [26, 27) 1 byte is acked.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Ack Fin. Verify OnPacketAcked is called.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+
+  // Ack [10, 27) and fin.
+  // No new data is acked, verify OnPacketAcked is not called.
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
+  EXPECT_FALSE(
+      stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
+                                  QuicTime::Zero(), &newly_acked_length));
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  std::string body = "Test1";
+  std::string body2(100, 'x');
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteOrBufferBody(body, false);
+  stream_->WriteOrBufferBody(body2, true);
+
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body.length(), quiche::SimpleBufferAllocator::Get());
+  quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
+      body2.length(), quiche::SimpleBufferAllocator::Get());
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
+  QuicStreamFrame frame(stream_->id(), false, 0,
+                        absl::StrCat(header.AsStringView(), body));
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
+  QuicStreamFrame frame2(stream_->id(), false, header.size() + body.length(),
+                         header2.AsStringView());
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
+  QuicStreamFrame frame3(stream_->id(), true,
+                         header.size() + body.length() + header2.size(), body2);
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_TRUE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  std::string body1 = "Test1";
+  std::string body2(100, 'x');
+  struct iovec body1_iov = {const_cast<char*>(body1.data()), body1.length()};
+  struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
+  quiche::QuicheMemSliceStorage storage(
+      &body1_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
+  quiche::QuicheMemSliceStorage storage2(
+      &body2_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteBodySlices(storage.ToSpan(), false);
+  stream_->WriteBodySlices(storage2.ToSpan(), true);
+
+  std::string data1 = DataFrame(body1);
+  std::string data2 = DataFrame(body2);
+
+  EXPECT_CALL(*mock_ack_listener,
+              OnPacketAcked(body1.length() + body2.length(), _));
+  QuicStreamFrame frame(stream_->id(), true, 0, data1 + data2);
+  EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
+                                     QuicTime::Zero()));
+
+  EXPECT_TRUE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+// HTTP/3 only.
+TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
+      new StrictMock<MockAckListener>);
+  stream_->set_ack_listener(mock_ack_listener);
+  std::string body1 = "Test1";
+  std::string body2(100, 'x');
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
+  stream_->WriteOrBufferBody(body1, false);
+  stream_->WriteOrBufferBody(body2, true);
+
+  std::string data1 = DataFrame(body1);
+  std::string data2 = DataFrame(body2);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body1.length()));
+  QuicStreamFrame frame(stream_->id(), false, 0, data1);
+  session_->OnStreamFrameRetransmitted(frame);
+
+  EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
+  QuicStreamFrame frame2(stream_->id(), true, data1.length(), data2);
+  session_->OnStreamFrameRetransmitted(frame2);
+
+  EXPECT_FALSE(
+      QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
+}
+
+TEST_P(QuicSpdyStreamTest, HeadersFrameOnRequestStream) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  std::string data = DataFrame(kDataFramePayload);
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+
+  std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
+  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
+  stream_->OnStreamFrame(frame);
+
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+
+  // QuicSpdyStream only calls OnBodyAvailable()
+  // after the header list has been consumed.
+  EXPECT_EQ("", stream_->data());
+  stream_->ConsumeHeaderList();
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessBodyAfterTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(!kShouldProcessData);
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  std::string data = DataFrame(kDataFramePayload);
+
+  // A header block that will take more than one block of sequencer buffer.
+  // This ensures that when the trailers are consumed, some buffer buckets will
+  // be freed.
+  SpdyHeaderBlock trailers_block;
+  trailers_block["key1"] = std::string(10000, 'x');
+  std::string trailers = HeadersFrame(trailers_block);
+
+  // Feed all three HTTP/3 frames in a single stream frame.
+  std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
+  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
+  stream_->OnStreamFrame(frame);
+
+  stream_->ConsumeHeaderList();
+  stream_->MarkTrailersConsumed();
+
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_EQ(trailers_block, stream_->received_trailers());
+
+  EXPECT_TRUE(stream_->HasBytesToRead());
+
+  // Consume data.
+  char buffer[2048];
+  struct iovec vec;
+  vec.iov_base = buffer;
+  vec.iov_len = ABSL_ARRAYSIZE(buffer);
+  size_t bytes_read = stream_->Readv(&vec, 1);
+  EXPECT_EQ(kDataFramePayload, absl::string_view(buffer, bytes_read));
+
+  EXPECT_FALSE(stream_->HasBytesToRead());
+}
+
+// The test stream will receive a stream frame containing malformed headers and
+// normal body. Make sure the http decoder stops processing body after the
+// connection shuts down.
+TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  // Random bad headers.
+  std::string headers =
+      HeadersFrame(absl::HexStringToBytes("00002a94e7036261"));
+  std::string data = DataFrame(kDataFramePayload);
+
+  std::string stream_frame_payload = absl::StrCat(headers, data);
+  QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding headers on stream \\d+: "
+                                   "Incomplete header block."),
+                      _))
+      .WillOnce(
+          (Invoke([this](QuicErrorCode error, const std::string& error_details,
+                         ConnectionCloseBehavior connection_close_behavior) {
+            connection_->ReallyCloseConnection(error, error_details,
+                                               connection_close_behavior);
+          })));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(*session_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
+                              ConnectionCloseSource source) {
+        session_->ReallyOnConnectionClosed(frame, source);
+      }));
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
+  stream_->OnStreamFrame(frame);
+}
+
+// Regression test for https://crbug.com/1027895: a HEADERS frame triggers an
+// error in QuicSpdyStream::OnHeadersFramePayload().  This closes the
+// connection, freeing the buffer of QuicStreamSequencer.  Therefore
+// QuicStreamSequencer::MarkConsumed() must not be called from
+// QuicSpdyStream::OnHeadersFramePayload().
+TEST_P(QuicSpdyStreamTest, DoNotMarkConsumedAfterQpackDecodingError) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  {
+    testing::InSequence s;
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                        MatchesRegex("Error decoding headers on stream \\d+: "
+                                     "Invalid relative index."),
+                        _))
+        .WillOnce((
+            Invoke([this](QuicErrorCode error, const std::string& error_details,
+                          ConnectionCloseBehavior connection_close_behavior) {
+              connection_->ReallyCloseConnection(error, error_details,
+                                                 connection_close_behavior);
+            })));
+    EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+    EXPECT_CALL(*session_, OnConnectionClosed(_, _))
+        .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
+                                ConnectionCloseSource source) {
+          session_->ReallyOnConnectionClosed(frame, source);
+        }));
+  }
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream2_->id(), _, _));
+
+  // Invalid headers: Required Insert Count is zero, but the header block
+  // contains a dynamic table reference.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("000080"));
+  QuicStreamFrame frame(stream_->id(), false, 0, headers);
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  // Decoder stream type.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Headers can be decoded immediately.
+  EXPECT_TRUE(stream_->headers_decompressed());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  std::string data = DataFrame(kDataFramePayload);
+  EXPECT_CALL(debug_visitor,
+              OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
+                                         headers.length(), data));
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Deliver second dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
+
+  // Trailing HEADERS frame referencing second dynamic table entry.
+  std::string encoded_trailers = absl::HexStringToBytes("030080");
+  std::string trailers = HeadersFrame(encoded_trailers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
+                                         headers.length() + data.length(),
+                                         trailers));
+
+  // Trailers can be decoded immediately.
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("trailing", "foobar")));
+  stream_->MarkTrailersConsumed();
+}
+
+TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+
+  // Decoder stream type.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+  EXPECT_TRUE(stream_->headers_decompressed());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  std::string data = DataFrame(kDataFramePayload);
+  EXPECT_CALL(debug_visitor,
+              OnDataFrameReceived(stream_->id(), strlen(kDataFramePayload)));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
+                                         headers.length(), data));
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Trailing HEADERS frame referencing second dynamic table entry.
+  std::string encoded_trailers = absl::HexStringToBytes("030080");
+  std::string trailers = HeadersFrame(encoded_trailers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
+                                         headers.length() + data.length(),
+                                         trailers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->trailers_decompressed());
+
+  // Header acknowledgement.
+  EXPECT_CALL(*session_, WritevData(decoder_send_stream->id(), _, _, _, _, _));
+  EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  // Deliver second dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
+  EXPECT_TRUE(stream_->trailers_decompressed());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("trailing", "foobar")));
+  stream_->MarkTrailersConsumed();
+}
+
+TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingHeaders) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  // HEADERS frame only referencing entry with absolute index 0 but with
+  // Required Insert Count = 2, which is incorrect.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("030081"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Even though entire header block is received and every referenced entry is
+  // available, decoding is blocked until insert count reaches the Required
+  // Insert Count value advertised in the header block prefix.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding headers on stream \\d+: "
+                                   "Required Insert Count too large."),
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  // Deliver two dynamic table entries to decoder
+  // to trigger decoding of header block.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+}
+
+// Regression test for https://crbug.com/1024263 and for
+// https://crbug.com/1025209#c11.
+TEST_P(QuicSpdyStreamTest, BlockedHeaderDecodingUnblockedWithBufferedError) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  // Relative index 2 is invalid because it is larger than or equal to the Base.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("020082"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding headers on stream \\d+: "
+                                   "Invalid relative index."),
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  // Deliver one dynamic table entry to decoder
+  // to trigger decoding of header block.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+}
+
+TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string headers = HeadersFrame(absl::HexStringToBytes("020080"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+
+  // Decoder stream type.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Header acknowledgement.
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+  EXPECT_TRUE(stream_->headers_decompressed());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  std::string data = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
+                                         headers.length(), data));
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Trailing HEADERS frame only referencing entry with absolute index 0 but
+  // with Required Insert Count = 2, which is incorrect.
+  std::string trailers = HeadersFrame(absl::HexStringToBytes("030081"));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
+                                         headers.length() + data.length(),
+                                         trailers));
+
+  // Even though entire header block is received and every referenced entry is
+  // available, decoding is blocked until insert count reaches the Required
+  // Insert Count value advertised in the header block prefix.
+  EXPECT_FALSE(stream_->trailers_decompressed());
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
+                      MatchesRegex("Error decoding trailers on stream \\d+: "
+                                   "Required Insert Count too large."),
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  // Deliver second dynamic table entry to decoder
+  // to trigger decoding of trailing header block.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
+}
+
+// Regression test for b/132603592: QPACK decoding unblocked after stream is
+// closed.
+TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  // Decoder stream type and stream cancellation instruction.
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+
+  // Reset stream by this endpoint, for example, due to stream cancellation.
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             stream_->id(), QuicResetStreamError::FromInternal(
+                                                QUIC_STREAM_CANCELLED)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+
+  EXPECT_FALSE(stream_->headers_decompressed());
+}
+
+TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterResetReceived) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+  session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  // HEADERS frame referencing first dynamic table entry.
+  std::string encoded_headers = absl::HexStringToBytes("020080");
+  std::string headers = HeadersFrame(encoded_headers);
+  EXPECT_CALL(debug_visitor,
+              OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Decoding is blocked because dynamic table entry has not been received yet.
+  EXPECT_FALSE(stream_->headers_decompressed());
+
+  // Decoder stream type and stream cancellation instruction.
+  auto decoder_send_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  EXPECT_CALL(*session_,
+              WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+
+  // OnStreamReset() is called when RESET_STREAM frame is received from peer.
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
+
+  if (!GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+    // Header acknowledgement.
+    EXPECT_CALL(*session_,
+                WritevData(decoder_send_stream->id(), /* write_length = */ 1,
+                           /* offset = */ 2, _, _, _));
+    EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
+  }
+
+  // Deliver dynamic table entry to decoder.
+  session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
+
+  if (GetQuicReloadableFlag(quic_abort_qpack_on_stream_reset)) {
+    EXPECT_FALSE(stream_->headers_decompressed());
+  } else {
+    // Verify headers.
+    EXPECT_TRUE(stream_->headers_decompressed());
+    EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  }
+}
+
+class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest {
+ protected:
+  QuicSpdyStreamIncrementalConsumptionTest() : offset_(0), consumed_bytes_(0) {}
+  ~QuicSpdyStreamIncrementalConsumptionTest() override = default;
+
+  // Create QuicStreamFrame with |payload|
+  // and pass it to stream_->OnStreamFrame().
+  void OnStreamFrame(absl::string_view payload) {
+    QuicStreamFrame frame(stream_->id(), /* fin = */ false, offset_, payload);
+    stream_->OnStreamFrame(frame);
+    offset_ += payload.size();
+  }
+
+  // Return number of bytes marked consumed with sequencer
+  // since last NewlyConsumedBytes() call.
+  QuicStreamOffset NewlyConsumedBytes() {
+    QuicStreamOffset previously_consumed_bytes = consumed_bytes_;
+    consumed_bytes_ = stream_->sequencer()->NumBytesConsumed();
+    return consumed_bytes_ - previously_consumed_bytes;
+  }
+
+  // Read |size| bytes from the stream.
+  std::string ReadFromStream(QuicByteCount size) {
+    std::string buffer;
+    buffer.resize(size);
+
+    struct iovec vec;
+    vec.iov_base = const_cast<char*>(buffer.data());
+    vec.iov_len = size;
+
+    size_t bytes_read = stream_->Readv(&vec, 1);
+    EXPECT_EQ(bytes_read, size);
+
+    return buffer;
+  }
+
+ private:
+  QuicStreamOffset offset_;
+  QuicStreamOffset consumed_bytes_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamIncrementalConsumptionTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Test that stream bytes are consumed (by calling
+// sequencer()->MarkConsumed()) incrementally, as soon as possible.
+TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(!kShouldProcessData);
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+
+  // All HEADERS frame bytes are consumed even if the frame is not received
+  // completely.
+  OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
+  EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
+
+  // The rest of the HEADERS frame is also consumed immediately.
+  OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // DATA frame.
+  absl::string_view data_payload(kDataFramePayload);
+  std::string data_frame = DataFrame(data_payload);
+  QuicByteCount data_frame_header_length =
+      data_frame.size() - data_payload.size();
+
+  // DATA frame header is consumed.
+  // DATA frame payload is not consumed because payload has to be buffered.
+  OnStreamFrame(data_frame);
+  EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
+
+  // Consume all but last byte of data.
+  EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
+            ReadFromStream(data_payload.size() - 1));
+  EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
+
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+
+  // No bytes are consumed, because last byte of DATA payload is still buffered.
+  OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
+  EXPECT_EQ(0u, NewlyConsumedBytes());
+
+  // Reading last byte of DATA payload triggers consumption of all data received
+  // so far, even though last HEADERS frame has not been received completely.
+  EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
+  EXPECT_EQ(1 + trailers.size() - 1, NewlyConsumedBytes());
+
+  // Last byte of trailers is immediately consumed.
+  OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+}
+
+TEST_P(QuicSpdyStreamIncrementalConsumptionTest, ReceiveUnknownFrame) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  StrictMock<MockHttp3DebugVisitor> debug_visitor;
+  session_->set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(debug_visitor,
+              OnUnknownFrameReceived(stream_->id(), /* frame_type = */ 0x21,
+                                     /* payload_length = */ 3));
+  std::string unknown_frame = UnknownFrame(0x21, "foo");
+  OnStreamFrame(unknown_frame);
+}
+
+TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(!kShouldProcessData);
+
+  // Unknown frame of reserved type before HEADERS is consumed immediately.
+  std::string unknown_frame1 = UnknownFrame(0x21, "foo");
+  OnStreamFrame(unknown_frame1);
+  EXPECT_EQ(unknown_frame1.size(), NewlyConsumedBytes());
+
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+
+  // All HEADERS frame bytes are consumed even if the frame is not received
+  // completely.
+  OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
+  EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
+
+  // The rest of the HEADERS frame is also consumed immediately.
+  OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify headers.
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // Frame of unknown, not reserved type between HEADERS and DATA is consumed
+  // immediately.
+  std::string unknown_frame2 = UnknownFrame(0x3a, "");
+  OnStreamFrame(unknown_frame2);
+  EXPECT_EQ(unknown_frame2.size(), NewlyConsumedBytes());
+
+  // DATA frame.
+  absl::string_view data_payload(kDataFramePayload);
+  std::string data_frame = DataFrame(data_payload);
+  QuicByteCount data_frame_header_length =
+      data_frame.size() - data_payload.size();
+
+  // DATA frame header is consumed.
+  // DATA frame payload is not consumed because payload has to be buffered.
+  OnStreamFrame(data_frame);
+  EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
+
+  // Frame of unknown, not reserved type is not consumed because DATA payload is
+  // still buffered.
+  std::string unknown_frame3 = UnknownFrame(0x39, "bar");
+  OnStreamFrame(unknown_frame3);
+  EXPECT_EQ(0u, NewlyConsumedBytes());
+
+  // Consume all but last byte of data.
+  EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
+            ReadFromStream(data_payload.size() - 1));
+  EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
+
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+
+  // No bytes are consumed, because last byte of DATA payload is still buffered.
+  OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
+  EXPECT_EQ(0u, NewlyConsumedBytes());
+
+  // Reading last byte of DATA payload triggers consumption of all data received
+  // so far, even though last HEADERS frame has not been received completely.
+  EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
+  EXPECT_EQ(1 + unknown_frame3.size() + trailers.size() - 1,
+            NewlyConsumedBytes());
+
+  // Last byte of trailers is immediately consumed.
+  OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
+  EXPECT_EQ(1u, NewlyConsumedBytes());
+
+  // Verify trailers.
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+
+  // Unknown frame of reserved type after trailers is consumed immediately.
+  std::string unknown_frame4 = UnknownFrame(0x40, "");
+  OnStreamFrame(unknown_frame4);
+  EXPECT_EQ(unknown_frame4.size(), NewlyConsumedBytes());
+}
+
+// Close connection if a DATA frame is received before a HEADERS frame.
+TEST_P(QuicSpdyStreamTest, DataBeforeHeaders) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Closing the connection is mocked out in tests.  Instead, simply stop
+  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+                      "Unexpected DATA frame received.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
+
+  std::string data = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, data));
+}
+
+// Close connection if a HEADERS frame is received after the trailing HEADERS.
+TEST_P(QuicSpdyStreamTest, TrailersAfterTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive and consume headers.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  QuicStreamOffset offset = 0;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, headers));
+  offset += headers.size();
+
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // Receive data.  It is consumed by TestStream.
+  std::string data = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data));
+  offset += data.size();
+
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Receive and consume trailers.
+  std::string trailers1 =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, trailers1));
+  offset += trailers1.size();
+
+  EXPECT_TRUE(stream_->trailers_decompressed());
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+
+  // Closing the connection is mocked out in tests.  Instead, simply stop
+  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+                      "HEADERS frame received after trailing HEADERS.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
+
+  // Receive another HEADERS frame, with no header fields.
+  std::string trailers2 = HeadersFrame(SpdyHeaderBlock());
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, trailers2));
+}
+
+// Regression test for https://crbug.com/978733.
+// Close connection if a DATA frame is received after the trailing HEADERS.
+TEST_P(QuicSpdyStreamTest, DataAfterTrailers) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Receive and consume headers.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  QuicStreamOffset offset = 0;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, headers));
+  offset += headers.size();
+
+  EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
+  stream_->ConsumeHeaderList();
+
+  // Receive data.  It is consumed by TestStream.
+  std::string data1 = DataFrame(kDataFramePayload);
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data1));
+  offset += data1.size();
+  EXPECT_EQ(kDataFramePayload, stream_->data());
+
+  // Receive trailers, with single header field "custom-key: custom-value".
+  std::string trailers =
+      HeadersFrame({std::make_pair("custom-key", "custom-value")});
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), false, offset, trailers));
+  offset += trailers.size();
+
+  EXPECT_THAT(stream_->received_trailers(),
+              ElementsAre(Pair("custom-key", "custom-value")));
+
+  // Closing the connection is mocked out in tests.  Instead, simply stop
+  // reading data at the stream level to prevent QuicSpdyStream from blowing up.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
+                      "Unexpected DATA frame received.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+      .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
+
+  // Receive more data.
+  std::string data2 = DataFrame("This payload should not be proccessed.");
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data2));
+}
+
+// SETTINGS frames are invalid on bidirectional streams.  If one is received,
+// the connection is closed.  No more data should be processed.
+TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // SETTINGS frame with empty payload.
+  std::string settings = absl::HexStringToBytes("0400");
+
+  // HEADERS frame.
+  // Since it arrives after a SETTINGS frame, it should never be read.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+
+  // Combine the two frames to make sure they are processed in a single
+  // QuicSpdyStream::OnDataAvailable() call.
+  std::string frames = absl::StrCat(settings, headers);
+
+  EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+  EXPECT_CALL(*session_, OnConnectionClosed(_, _));
+
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), /* fin = */ false,
+                                         /* offset = */ 0, frames));
+
+  EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
+}
+
+// Stream Cancellation instruction is sent on QPACK decoder stream
+// when stream is reset.
+TEST_P(QuicSpdyStreamTest, StreamCancellationWhenStreamReset) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  auto qpack_decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  // Stream type.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Stream cancellation.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             stream_->id(), QuicResetStreamError::FromInternal(
+                                                QUIC_STREAM_CANCELLED)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
+
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+}
+
+// Stream Cancellation instruction is sent on QPACK decoder stream
+// when RESET_STREAM frame is received.
+TEST_P(QuicSpdyStreamTest, StreamCancellationOnResetReceived) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  auto qpack_decoder_stream =
+      QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
+  // Stream type.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 0, _, _, _));
+  // Stream cancellation.
+  EXPECT_CALL(*session_,
+              WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
+                         /* offset = */ 1, _, _, _));
+
+  stream_->OnStreamReset(QuicRstStreamFrame(
+      kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
+}
+
+TEST_P(QuicSpdyStreamTest, WriteHeadersReturnValue) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  testing::InSequence s;
+
+  // Enable QPACK dynamic table.
+  session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024);
+  session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 1);
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(true));
+
+  QpackSendStream* encoder_stream =
+      QuicSpdySessionPeer::GetQpackEncoderSendStream(session_.get());
+  EXPECT_CALL(*session_, WritevData(encoder_stream->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+
+  // HEADERS frame header.
+  EXPECT_CALL(*session_,
+              WritevData(stream_->id(), _, /* offset = */ 0, _, _, _));
+  // HEADERS frame payload.
+  size_t headers_frame_payload_length = 0;
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .WillOnce(
+          DoAll(SaveArg<1>(&headers_frame_payload_length),
+                Invoke(session_.get(), &MockQuicSpdySession::ConsumeData)));
+
+  SpdyHeaderBlock request_headers;
+  request_headers["foo"] = "bar";
+  size_t write_headers_return_value =
+      stream_->WriteHeaders(std::move(request_headers), /*fin=*/true, nullptr);
+  EXPECT_TRUE(stream_->fin_sent());
+
+  EXPECT_EQ(headers_frame_payload_length, write_headers_return_value);
+}
+
+// Regression test for https://crbug.com/1177662.
+// RESET_STREAM with QUIC_STREAM_NO_ERROR should not be treated in a special
+// way: it should close the read side but not the write side.
+TEST_P(QuicSpdyStreamTest, TwoResetStreamFrames) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
+
+  QuicRstStreamFrame rst_frame1(kInvalidControlFrameId, stream_->id(),
+                                QUIC_STREAM_CANCELLED, /* bytes_written = */ 0);
+  stream_->OnStreamReset(rst_frame1);
+  EXPECT_TRUE(stream_->read_side_closed());
+  EXPECT_FALSE(stream_->write_side_closed());
+
+  QuicRstStreamFrame rst_frame2(kInvalidControlFrameId, stream_->id(),
+                                QUIC_STREAM_NO_ERROR, /* bytes_written = */ 0);
+  if (GetQuicReloadableFlag(quic_fix_on_stream_reset)) {
+    stream_->OnStreamReset(rst_frame2);
+    EXPECT_TRUE(stream_->read_side_closed());
+    EXPECT_FALSE(stream_->write_side_closed());
+  } else {
+    EXPECT_CALL(
+        *session_,
+        MaybeSendRstStreamFrame(
+            stream_->id(),
+            QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), _));
+    EXPECT_QUIC_BUG(
+        stream_->OnStreamReset(rst_frame2),
+        "The stream should've already sent RST in response to STOP_SENDING");
+  }
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft00) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "webtransport";
+  headers["datagram-flow-id"] = absl::StrCat(stream_->id());
+  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft04) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AnyNumber());
+
+  spdy::SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "webtransport";
+  stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft04) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["sec-webtransport-http3-draft02"] = "1";
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  stream_->OnCapsule(
+      Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft00) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest,
+       ProcessIncomingWebTransportHeadersWithMismatchedFlowId) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  // TODO(b/181256914) Remove this test when we deprecate
+  // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  session_->EnableWebTransport();
+  QuicSpdySessionPeer::EnableWebTransport(session_.get());
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["datagram-flow-id"] = "2";
+
+  stream_->OnStreamHeadersPriority(
+      spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  ProcessHeaders(false, headers_);
+  EXPECT_EQ("", stream_->data());
+  EXPECT_FALSE(stream_->header_list().empty());
+  EXPECT_FALSE(stream_->IsDoneReading());
+  ASSERT_TRUE(stream_->web_transport() != nullptr);
+  EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
+}
+
+TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdClient) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
+  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 0u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 2u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 4u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 6u);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+}
+
+TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdServer) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_SERVER);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
+  stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 1u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 3u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 5u);
+  EXPECT_EQ(stream_->GetNextDatagramContextId(), 7u);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+}
+
+TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithoutContextDraft00) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft00);
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
+  ProcessHeaders(false, headers_);
+  session_->RegisterHttp3DatagramFlowId(stream_->id(), stream_->id());
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor;
+  SavingHttp3DatagramVisitor h3_datagram_visitor;
+  absl::optional<QuicDatagramContextId> context_id;
+  absl::string_view format_additional_data;
+  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
+  std::array<char, 256> datagram;
+  datagram[0] = stream_->id();
+  for (size_t i = 1; i < datagram.size(); i++) {
+    datagram[i] = i;
+  }
+  stream_->RegisterHttp3DatagramRegistrationVisitor(
+      &h3_datagram_registration_visitor);
+  stream_->RegisterHttp3DatagramContextId(
+      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
+      &h3_datagram_visitor);
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Test move.
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor2;
+  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
+  SavingHttp3DatagramVisitor h3_datagram_visitor2;
+  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
+                                                  &h3_datagram_visitor2);
+  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Cleanup.
+  stream_->UnregisterHttp3DatagramContextId(context_id);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  session_->UnregisterHttp3DatagramFlowId(stream_->id());
+}
+
+TEST_P(QuicSpdyStreamTest, H3DatagramRegistrationWithoutContextDraft04) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  ProcessHeaders(false, headers_);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor;
+  SavingHttp3DatagramVisitor h3_datagram_visitor;
+  absl::optional<QuicDatagramContextId> context_id;
+  absl::string_view format_additional_data;
+  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
+  std::array<char, 256> datagram;
+  datagram[0] = stream_->id();
+  for (size_t i = 1; i < datagram.size(); i++) {
+    datagram[i] = i;
+  }
+  stream_->RegisterHttp3DatagramRegistrationVisitor(
+      &h3_datagram_registration_visitor);
+
+  // Expect us to send a REGISTER_DATAGRAM_NO_CONTEXT capsule.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+
+  stream_->RegisterHttp3DatagramContextId(
+      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
+      &h3_datagram_visitor);
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Test move.
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor2;
+  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
+  SavingHttp3DatagramVisitor h3_datagram_visitor2;
+  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
+                                                  &h3_datagram_visitor2);
+  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[1], datagram.size() - 1)}));
+  // Cleanup.
+  stream_->UnregisterHttp3DatagramContextId(context_id);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+}
+
+TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithContext) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor;
+  SavingHttp3DatagramVisitor h3_datagram_visitor;
+  absl::optional<QuicDatagramContextId> context_id = 42;
+  absl::string_view format_additional_data;
+  ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
+  std::array<char, 256> datagram;
+  datagram[0] = stream_->id();
+  datagram[1] = context_id.value();
+  for (size_t i = 2; i < datagram.size(); i++) {
+    datagram[i] = i;
+  }
+  stream_->RegisterHttp3DatagramRegistrationVisitor(
+      &h3_datagram_registration_visitor, /*use_datagram_contexts=*/true);
+  headers_[":method"] = "CONNECT";
+  headers_[":protocol"] = "webtransport";
+  headers_["sec-use-datagram-contexts"] = "?1";
+  ProcessHeaders(false, headers_);
+
+  // Expect us to send a REGISTER_DATAGRAM_CONTEXT capsule.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+
+  stream_->RegisterHttp3DatagramContextId(
+      context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
+      &h3_datagram_visitor);
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[2], datagram.size() - 2)}));
+  // Test move.
+  ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
+      h3_datagram_registration_visitor2;
+  stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
+  SavingHttp3DatagramVisitor h3_datagram_visitor2;
+  stream_->MoveHttp3DatagramContextIdRegistration(context_id,
+                                                  &h3_datagram_visitor2);
+  EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
+  session_->OnMessageReceived(
+      absl::string_view(datagram.data(), datagram.size()));
+  EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
+              ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+                  stream_->id(), context_id,
+                  std::string(&datagram[2], datagram.size() - 2)}));
+  // Cleanup.
+
+  // Expect us to send a CLOSE_DATAGRAM_CONTEXT capsule.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(AtLeast(1));
+  stream_->UnregisterHttp3DatagramContextId(context_id);
+  stream_->UnregisterHttp3DatagramRegistrationVisitor();
+  session_->UnregisterHttp3DatagramFlowId(stream_->id());
+}
+
+TEST_P(QuicSpdyStreamTest, SendHttp3Datagram) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+  absl::optional<QuicDatagramContextId> context_id;
+  std::string h3_datagram_payload = {1, 2, 3, 4, 5, 6};
+  EXPECT_CALL(*connection_, SendMessage(1, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  EXPECT_EQ(stream_->SendHttp3Datagram(context_id, h3_datagram_payload),
+            MESSAGE_STATUS_SUCCESS);
+}
+
+TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
+  if (!UsesHttp3()) {
+    return;
+  }
+  Initialize(kShouldProcessData);
+  session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+  QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
+                                              HttpDatagramSupport::kDraft04);
+
+  QuicByteCount size = stream_->GetMaxDatagramSize(absl::nullopt);
+  QuicByteCount size_with_context =
+      stream_->GetMaxDatagramSize(/*context_id=*/1);
+  EXPECT_GT(size, 512u);
+  EXPECT_EQ(size - 1, size_with_context);
+}
+
+TEST_P(QuicSpdyStreamTest,
+       QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
+  if (!UsesHttp3()) {
+    return;
+  }
+
+  Initialize(kShouldProcessData);
+
+  // Creates QpackDecodedHeadersAccumulator in
+  // `qpack_decoded_headers_accumulator_`.
+  std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
+  stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
+
+  // Resets `qpack_decoded_headers_accumulator_`.
+  stream_->OnHeadersDecoded({}, false);
+
+  // This private method should never be called when
+  // `qpack_decoded_headers_accumulator_` is nullptr.  The number 1 identifies
+  // the site where `qpack_decoded_headers_accumulator_` was last reset.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _));
+  bool result = true;
+  EXPECT_QUIC_BUG(result = QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_),
+                  "b215142466_OnHeadersFrameEnd.: 1$");
+  EXPECT_FALSE(result);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_server_push_utils.cc b/quiche/quic/core/http/spdy_server_push_utils.cc
new file mode 100644
index 0000000..103f6dd
--- /dev/null
+++ b/quiche/quic/core/http/spdy_server_push_utils.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+// static
+std::string SpdyServerPushUtils::GetPromisedUrlFromHeaders(
+    const SpdyHeaderBlock& headers) {
+  // RFC 7540, Section 8.1.2.3: All HTTP/2 requests MUST include exactly
+  // one valid value for the ":method", ":scheme", and ":path" pseudo-header
+  // fields, unless it is a CONNECT request.
+
+  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
+  // subsequent CONTINUATION frames MUST be a valid and complete set of request
+  // header fields (Section 8.1.2.3).  The server MUST include a method in the
+  // ":method" pseudo-header field that is safe and cacheable.
+  //
+  // RFC 7231, Section  4.2.1: Of the request methods defined by this
+  // specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be
+  // safe.
+  //
+  // RFC 7231, Section  4.2.1: ... this specification defines GET, HEAD, and
+  // POST as cacheable, ...
+  //
+  // So the only methods allowed in a PUSH_PROMISE are GET and HEAD.
+  SpdyHeaderBlock::const_iterator it = headers.find(":method");
+  if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) {
+    return std::string();
+  }
+
+  it = headers.find(":scheme");
+  if (it == headers.end() || it->second.empty()) {
+    return std::string();
+  }
+  absl::string_view scheme = it->second;
+
+  // RFC 7540, Section 8.2: The server MUST include a value in the
+  // ":authority" pseudo-header field for which the server is authoritative
+  // (see Section 10.1).
+  it = headers.find(":authority");
+  if (it == headers.end() || it->second.empty()) {
+    return std::string();
+  }
+  absl::string_view authority = it->second;
+
+  // RFC 7540, Section 8.1.2.3 requires that the ":path" pseudo-header MUST
+  // NOT be empty for "http" or "https" URIs;
+  //
+  // However, to ensure the scheme is consistently canonicalized, that check
+  // is deferred to implementations in QuicUrlUtils::GetPushPromiseUrl().
+  it = headers.find(":path");
+  if (it == headers.end()) {
+    return std::string();
+  }
+  absl::string_view path = it->second;
+
+  return GetPushPromiseUrl(scheme, authority, path);
+}
+
+// static
+std::string SpdyServerPushUtils::GetPromisedHostNameFromHeaders(
+    const SpdyHeaderBlock& headers) {
+  // TODO(fayang): Consider just checking out the value of the ":authority" key
+  // in headers.
+  return GURL(GetPromisedUrlFromHeaders(headers)).host();
+}
+
+// static
+bool SpdyServerPushUtils::PromisedUrlIsValid(const SpdyHeaderBlock& headers) {
+  std::string url(GetPromisedUrlFromHeaders(headers));
+  return !url.empty() && GURL(url).is_valid();
+}
+
+// static
+std::string SpdyServerPushUtils::GetPushPromiseUrl(absl::string_view scheme,
+                                                   absl::string_view authority,
+                                                   absl::string_view path) {
+  // RFC 7540, Section 8.1.2.3: The ":path" pseudo-header field includes the
+  // path and query parts of the target URI (the "path-absolute" production
+  // and optionally a '?' character followed by the "query" production (see
+  // Sections 3.3 and 3.4 of RFC3986). A request in asterisk form includes the
+  // value '*' for the ":path" pseudo-header field.
+  //
+  // This pseudo-header field MUST NOT be empty for "http" or "https" URIs;
+  // "http" or "https" URIs that do not contain a path MUST include a value of
+  // '/'. The exception to this rule is an OPTIONS request for an "http" or
+  // "https" URI that does not include a path component; these MUST include a
+  // ":path" pseudo-header with a value of '*' (see RFC7230, Section 5.3.4).
+  //
+  // In addition to the above restriction from RFC 7540, note that RFC3986
+  // defines the "path-absolute" construction as starting with "/" but not "//".
+  //
+  // RFC 7540, Section  8.2.1:  The header fields in PUSH_PROMISE and any
+  // subsequent CONTINUATION frames MUST be a valid and complete set of request
+  // header fields (Section 8.1.2.3).  The server MUST include a method in the
+  // ":method" pseudo-header field that is safe and cacheable.
+  //
+  // RFC 7231, Section  4.2.1:
+  // ... this specification defines GET, HEAD, and POST as cacheable, ...
+  //
+  // Since the OPTIONS method is not cacheable, it cannot be the method of a
+  // PUSH_PROMISE. Therefore, the exception mentioned in RFC 7540, Section
+  // 8.1.2.3 about OPTIONS requests does not apply here (i.e. ":path" cannot be
+  // "*").
+  if (path.empty() || path[0] != '/' || (path.size() >= 2 && path[1] == '/')) {
+    return std::string();
+  }
+
+  // Validate the scheme; this is to ensure a scheme of "foo://bar" is not
+  // parsed as a URL of "foo://bar://baz" when combined with a host of "baz".
+  std::string canonical_scheme;
+  url::StdStringCanonOutput canon_scheme_output(&canonical_scheme);
+  url::Component canon_component;
+  url::Component scheme_component(0, scheme.size());
+
+  if (!url::CanonicalizeScheme(scheme.data(), scheme_component,
+                               &canon_scheme_output, &canon_component) ||
+      !canon_component.is_nonempty() || canon_component.begin != 0) {
+    return std::string();
+  }
+  canonical_scheme.resize(canon_component.len + 1);
+
+  // Validate the authority; this is to ensure an authority such as
+  // "host/path" is not accepted, as when combined with a scheme like
+  // "http://", could result in a URL of "http://host/path".
+  url::Component auth_component(0, authority.size());
+  url::Component username_component;
+  url::Component password_component;
+  url::Component host_component;
+  url::Component port_component;
+
+  url::ParseAuthority(authority.data(), auth_component, &username_component,
+                      &password_component, &host_component, &port_component);
+
+  // RFC 7540, Section 8.1.2.3: The authority MUST NOT include the deprecated
+  // "userinfo" subcomponent for "http" or "https" schemed URIs.
+  //
+  // Note: Although |canonical_scheme| has not yet been checked for that, as
+  // it is performed later in processing, only "http" and "https" schemed
+  // URIs are supported for PUSH.
+  if (username_component.is_valid() || password_component.is_valid()) {
+    return std::string();
+  }
+
+  // Failed parsing or no host present. ParseAuthority() will ensure that
+  // host_component + port_component cover the entire string, if
+  // username_component and password_component are not present.
+  if (!host_component.is_nonempty()) {
+    return std::string();
+  }
+
+  // Validate the port (if present; it's optional).
+  int parsed_port_number = url::PORT_INVALID;
+  if (port_component.is_nonempty()) {
+    parsed_port_number = url::ParsePort(authority.data(), port_component);
+    if (parsed_port_number < 0 && parsed_port_number != url::PORT_UNSPECIFIED) {
+      return std::string();
+    }
+  }
+
+  // Validate the host by attempting to canonicalize it. Invalid characters
+  // will result in a canonicalization failure (e.g. '/')
+  std::string canon_host;
+  url::StdStringCanonOutput canon_host_output(&canon_host);
+  canon_component.reset();
+  if (!url::CanonicalizeHost(authority.data(), host_component,
+                             &canon_host_output, &canon_component) ||
+      !canon_component.is_nonempty() || canon_component.begin != 0) {
+    return std::string();
+  }
+
+  // At this point, "authority" has been validated to either be of the form
+  // 'host:port' or 'host', with 'host' being a valid domain or IP address,
+  // and 'port' (if present), being a valid port. Attempt to construct a
+  // URL of just the (scheme, host, port), which should be safe and will not
+  // result in ambiguous parsing.
+  //
+  // This also enforces that all PUSHed URLs are either HTTP or HTTPS-schemed
+  // URIs, consistent with the other restrictions enforced above.
+  //
+  // Note: url::CanonicalizeScheme() will have added the ':' to
+  // |canonical_scheme|.
+  GURL origin_url(canonical_scheme + "//" + std::string(authority));
+  if (!origin_url.is_valid() || !origin_url.SchemeIsHTTPOrHTTPS() ||
+      // The following checks are merely defense in depth.
+      origin_url.has_username() || origin_url.has_password() ||
+      (origin_url.has_path() && origin_url.path_piece() != "/") ||
+      origin_url.has_query() || origin_url.has_ref()) {
+    return std::string();
+  }
+
+  // Attempt to parse the path.
+  std::string spec = origin_url.GetWithEmptyPath().spec();
+  spec.pop_back();  // Remove the '/', as ":path" must contain it.
+  spec.append(std::string(path));
+
+  // Attempt to parse the full URL, with the path as well. Ensure there is no
+  // fragment to the query.
+  GURL full_url(spec);
+  if (!full_url.is_valid() || full_url.has_ref()) {
+    return std::string();
+  }
+
+  return full_url.spec();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_server_push_utils.h b/quiche/quic/core/http/spdy_server_push_utils.h
new file mode 100644
index 0000000..c79f52c
--- /dev/null
+++ b/quiche/quic/core/http/spdy_server_push_utils.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
+#define QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE SpdyServerPushUtils {
+ public:
+  SpdyServerPushUtils() = delete;
+
+  // Returns a canonicalized URL composed from the :scheme, :authority, and
+  // :path headers of a PUSH_PROMISE. Returns empty string if the headers do not
+  // conform to HTTP/2 spec or if the ":method" header contains a forbidden
+  // method for PUSH_PROMISE.
+  static std::string GetPromisedUrlFromHeaders(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Returns hostname, or empty string if missing.
+  static std::string GetPromisedHostNameFromHeaders(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Returns true if result of |GetPromisedUrlFromHeaders()| is non-empty
+  // and is a well-formed URL.
+  static bool PromisedUrlIsValid(const spdy::SpdyHeaderBlock& headers);
+
+  // Returns a canonical, valid URL for a PUSH_PROMISE with the specified
+  // ":scheme", ":authority", and ":path" header fields, or an empty
+  // string if the resulting URL is not valid or supported.
+  static std::string GetPushPromiseUrl(absl::string_view scheme,
+                                       absl::string_view authority,
+                                       absl::string_view path);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_SERVER_PUSH_UTILS_H_
diff --git a/quiche/quic/core/http/spdy_server_push_utils_test.cc b/quiche/quic/core/http/spdy_server_push_utils_test.cc
new file mode 100644
index 0000000..d9aff41
--- /dev/null
+++ b/quiche/quic/core/http/spdy_server_push_utils_test.cc
@@ -0,0 +1,217 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/spdy_server_push_utils.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+namespace test {
+
+using GetPromisedUrlFromHeaders = QuicTest;
+
+TEST_F(GetPromisedUrlFromHeaders, Basic) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":path"] = "/index.html";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
+            "https://www.google.com/index.html");
+  headers["key1"] = "value1";
+  headers["key2"] = "value2";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers),
+            "https://www.google.com/index.html");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, Connect) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+  headers[":path"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, InvalidUserinfo) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":authority"] = "user@www.google.com";
+  headers[":scheme"] = "https";
+  headers[":path"] = "/";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+TEST_F(GetPromisedUrlFromHeaders, InvalidPath) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  headers[":authority"] = "www.google.com";
+  headers[":scheme"] = "https";
+  headers[":path"] = "";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedUrlFromHeaders(headers), "");
+}
+
+using GetPromisedHostNameFromHeaders = QuicTest;
+
+TEST_F(GetPromisedHostNameFromHeaders, NormalUsage) {
+  SpdyHeaderBlock headers;
+  headers[":method"] = "GET";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":scheme"] = "https";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":authority"] = "www.google.com";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers), "");
+  headers[":path"] = "/index.html";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers["key1"] = "value1";
+  headers["key2"] = "value2";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers[":authority"] = "www.google.com:6666";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "www.google.com");
+  headers[":authority"] = "192.168.1.1";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "192.168.1.1");
+  headers[":authority"] = "192.168.1.1:6666";
+  EXPECT_EQ(SpdyServerPushUtils::GetPromisedHostNameFromHeaders(headers),
+            "192.168.1.1");
+}
+
+using PushPromiseUrlTest = QuicTest;
+
+TEST_F(PushPromiseUrlTest, GetPushPromiseUrl) {
+  // Test rejection of various inputs.
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("file", "localhost",
+                                                       "/etc/password"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
+                    "file", "", "/C:/Windows/System32/Config/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl(
+                    "", "https://www.google.com", "/"));
+
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://www.google.com",
+                                                       "www.google.com", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https://",
+                                                       "www.google.com", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "",
+                                                       "www.google.com/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
+                                                       "www.google.com/", "/"));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https",
+                                                       "www.google.com", ""));
+  EXPECT_EQ("", SpdyServerPushUtils::GetPushPromiseUrl("https", "www.google",
+                                                       ".com/"));
+
+  // Test acception/rejection of various input combinations.
+  // |input_headers| is an array of pairs. The first value of each pair is a
+  // string that will be used as one of the inputs of GetPushPromiseUrl(). The
+  // second value of each pair is a bitfield where the lowest 3 bits indicate
+  // for which headers that string is valid (in a PUSH_PROMISE). For example,
+  // the string "http" would be valid for both the ":scheme" and ":authority"
+  // headers, so the bitfield paired with it is set to SCHEME | AUTH.
+  const unsigned char SCHEME = (1u << 0);
+  const unsigned char AUTH = (1u << 1);
+  const unsigned char PATH = (1u << 2);
+  const std::pair<const char*, unsigned char> input_headers[] = {
+      {"http", SCHEME | AUTH},
+      {"https", SCHEME | AUTH},
+      {"hTtP", SCHEME | AUTH},
+      {"HTTPS", SCHEME | AUTH},
+      {"www.google.com", AUTH},
+      {"90af90e0", AUTH},
+      {"12foo%20-bar:00001233", AUTH},
+      {"GOO\u200b\u2060\ufeffgoo", AUTH},
+      {"192.168.0.5", AUTH},
+      {"[::ffff:192.168.0.1.]", AUTH},
+      {"http:", AUTH},
+      {"bife l", AUTH},
+      {"/", PATH},
+      {"/foo/bar/baz", PATH},
+      {"/%20-2DVdkj.cie/foe_.iif/", PATH},
+      {"http://", 0},
+      {":443", 0},
+      {":80/eddd", 0},
+      {"google.com:-0", 0},
+      {"google.com:65536", 0},
+      {"http://google.com", 0},
+      {"http://google.com:39", 0},
+      {"//google.com/foo", 0},
+      {".com/", 0},
+      {"http://www.google.com/", 0},
+      {"http://foo:439", 0},
+      {"[::ffff:192.168", 0},
+      {"]/", 0},
+      {"//", 0}};
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(input_headers); ++i) {
+    bool should_accept = (input_headers[i].second & SCHEME);
+    for (size_t j = 0; j < ABSL_ARRAYSIZE(input_headers); ++j) {
+      bool should_accept_2 = should_accept && (input_headers[j].second & AUTH);
+      for (size_t k = 0; k < ABSL_ARRAYSIZE(input_headers); ++k) {
+        // |should_accept_3| indicates whether or not GetPushPromiseUrl() is
+        // expected to accept this input combination.
+        bool should_accept_3 =
+            should_accept_2 && (input_headers[k].second & PATH);
+
+        std::string url = SpdyServerPushUtils::GetPushPromiseUrl(
+            input_headers[i].first, input_headers[j].first,
+            input_headers[k].first);
+
+        ::testing::AssertionResult result = ::testing::AssertionSuccess();
+        if (url.empty() == should_accept_3) {
+          result = ::testing::AssertionFailure()
+                   << "GetPushPromiseUrl() accepted/rejected the inputs when "
+                      "it shouldn't have."
+                   << std::endl
+                   << "     scheme: " << input_headers[i].first << std::endl
+                   << "  authority: " << input_headers[j].first << std::endl
+                   << "       path: " << input_headers[k].first << std::endl
+                   << "Output: " << url << std::endl;
+        }
+        ASSERT_TRUE(result);
+      }
+    }
+  }
+
+  // Test canonicalization of various valid inputs.
+  EXPECT_EQ("http://www.google.com/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                          "http", "www.google.com", "/"));
+  EXPECT_EQ("https://www.goo-gle.com/fOOo/baRR",
+            SpdyServerPushUtils::GetPushPromiseUrl("hTtPs", "wWw.gOo-gLE.cOm",
+                                                   "/fOOo/baRR"));
+  EXPECT_EQ("https://www.goo-gle.com:3278/pAth/To/reSOurce",
+            SpdyServerPushUtils::GetPushPromiseUrl(
+                "hTtPs", "Www.gOo-Gle.Com:000003278", "/pAth/To/reSOurce"));
+  EXPECT_EQ("https://foo%20bar/foo/bar/baz",
+            SpdyServerPushUtils::GetPushPromiseUrl("https", "foo bar",
+                                                   "/foo/bar/baz"));
+  EXPECT_EQ("http://foo.com:70/e/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                        "http", "foo.com:0000070", "/e/"));
+  EXPECT_EQ("http://192.168.0.1:70/e/",
+            SpdyServerPushUtils::GetPushPromiseUrl(
+                "http", "0300.0250.00.01:0070", "/e/"));
+  EXPECT_EQ("http://192.168.0.1/e/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                         "http", "0xC0a80001", "/e/"));
+  EXPECT_EQ("http://[::c0a8:1]/", SpdyServerPushUtils::GetPushPromiseUrl(
+                                      "http", "[::192.168.0.1]", "/"));
+  EXPECT_EQ("https://[::ffff:c0a8:1]/",
+            SpdyServerPushUtils::GetPushPromiseUrl(
+                "https", "[::ffff:0xC0.0Xa8.0x0.0x1]", "/"));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_utils.cc b/quiche/quic/core/http/spdy_utils.cc
new file mode 100644
index 0000000..d0eac9f
--- /dev/null
+++ b/quiche/quic/core/http/spdy_utils.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/spdy_utils.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::SpdyHeaderBlock;
+
+namespace quic {
+
+// static
+bool SpdyUtils::ExtractContentLengthFromHeaders(int64_t* content_length,
+                                                SpdyHeaderBlock* headers) {
+  auto it = headers->find("content-length");
+  if (it == headers->end()) {
+    return false;
+  } else {
+    // Check whether multiple values are consistent.
+    absl::string_view content_length_header = it->second;
+    std::vector<absl::string_view> values =
+        absl::StrSplit(content_length_header, '\0');
+    for (const absl::string_view& value : values) {
+      uint64_t new_value;
+      if (!absl::SimpleAtoi(value, &new_value) ||
+          !quiche::QuicheTextUtils::IsAllDigits(value)) {
+        QUIC_DLOG(ERROR)
+            << "Content length was either unparseable or negative.";
+        return false;
+      }
+      if (*content_length < 0) {
+        *content_length = new_value;
+        continue;
+      }
+      if (new_value != static_cast<uint64_t>(*content_length)) {
+        QUIC_DLOG(ERROR)
+            << "Parsed content length " << new_value << " is "
+            << "inconsistent with previously detected content length "
+            << *content_length;
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
+                                       int64_t* content_length,
+                                       SpdyHeaderBlock* headers) {
+  for (const auto& p : header_list) {
+    const std::string& name = p.first;
+    if (name.empty()) {
+      QUIC_DLOG(ERROR) << "Header name must not be empty.";
+      return false;
+    }
+
+    if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
+      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
+                       << " contains upper-case characters.";
+      return false;
+    }
+
+    headers->AppendValueOrAddHeader(name, p.second);
+  }
+
+  if (headers->contains("content-length") &&
+      !ExtractContentLengthFromHeaders(content_length, headers)) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
+  return true;
+}
+
+bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
+                                        bool expect_final_byte_offset,
+                                        size_t* final_byte_offset,
+                                        SpdyHeaderBlock* trailers) {
+  bool found_final_byte_offset = false;
+  for (const auto& p : header_list) {
+    const std::string& name = p.first;
+
+    // Pull out the final offset pseudo header which indicates the number of
+    // response body bytes expected.
+    if (expect_final_byte_offset && !found_final_byte_offset &&
+        name == kFinalOffsetHeaderKey &&
+        absl::SimpleAtoi(p.second, final_byte_offset)) {
+      found_final_byte_offset = true;
+      continue;
+    }
+
+    if (name.empty() || name[0] == ':') {
+      QUIC_DLOG(ERROR)
+          << "Trailers must not be empty, and must not contain pseudo-"
+          << "headers. Found: '" << name << "'";
+      return false;
+    }
+
+    if (quiche::QuicheTextUtils::ContainsUpperCase(name)) {
+      QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
+                       << " contains upper-case characters.";
+      return false;
+    }
+
+    trailers->AppendValueOrAddHeader(name, p.second);
+  }
+
+  if (expect_final_byte_offset && !found_final_byte_offset) {
+    QUIC_DLOG(ERROR) << "Required key '" << kFinalOffsetHeaderKey
+                     << "' not present";
+    return false;
+  }
+
+  // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
+
+  QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
+  return true;
+}
+
+// static
+// TODO(danzh): Move it to quic/tools/ and switch to use GURL.
+bool SpdyUtils::PopulateHeaderBlockFromUrl(const std::string url,
+                                           SpdyHeaderBlock* headers) {
+  (*headers)[":method"] = "GET";
+  size_t pos = url.find("://");
+  if (pos == std::string::npos) {
+    return false;
+  }
+  (*headers)[":scheme"] = url.substr(0, pos);
+  size_t start = pos + 3;
+  pos = url.find('/', start);
+  if (pos == std::string::npos) {
+    (*headers)[":authority"] = url.substr(start);
+    (*headers)[":path"] = "/";
+    return true;
+  }
+  (*headers)[":authority"] = url.substr(start, pos - start);
+  (*headers)[":path"] = url.substr(pos);
+  return true;
+}
+
+// static
+absl::optional<QuicDatagramStreamId> SpdyUtils::ParseDatagramFlowIdHeader(
+    const spdy::SpdyHeaderBlock& headers) {
+  auto flow_id_pair = headers.find("datagram-flow-id");
+  if (flow_id_pair == headers.end()) {
+    return absl::nullopt;
+  }
+  std::vector<absl::string_view> flow_id_strings =
+      absl::StrSplit(flow_id_pair->second, ',');
+  absl::optional<QuicDatagramStreamId> first_named_flow_id;
+  for (absl::string_view flow_id_string : flow_id_strings) {
+    std::vector<absl::string_view> flow_id_components =
+        absl::StrSplit(flow_id_string, ';');
+    if (flow_id_components.empty()) {
+      continue;
+    }
+    absl::string_view flow_id_value_string = flow_id_components[0];
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
+        &flow_id_value_string);
+    QuicDatagramStreamId flow_id;
+    if (!absl::SimpleAtoi(flow_id_value_string, &flow_id)) {
+      continue;
+    }
+    if (flow_id_components.size() == 1) {
+      // This flow ID is unnamed, return this one.
+      return flow_id;
+    }
+    // Otherwise this is a named flow ID.
+    if (!first_named_flow_id.has_value()) {
+      first_named_flow_id = flow_id;
+    }
+  }
+  return first_named_flow_id;
+}
+
+// static
+void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
+                                        QuicDatagramStreamId flow_id) {
+  (*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
+}
+
+// static
+ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+    const spdy::SpdyAltSvcWireFormat::AlternativeService&
+        alternative_service_entry,
+    const ParsedQuicVersionVector& supported_versions) {
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version.AlpnDeferToRFCv1()) {
+      // Versions with share an ALPN with v1 are currently unable to be
+      // advertised with Alt-Svc.
+      continue;
+    }
+    if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
+      return version;
+    }
+  }
+
+  return ParsedQuicVersion::Unsupported();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/spdy_utils.h b/quiche/quic/core/http/spdy_utils.h
new file mode 100644
index 0000000..5654b2f
--- /dev/null
+++ b/quiche/quic/core/http/spdy_utils.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
+#define QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE SpdyUtils {
+ public:
+  SpdyUtils() = delete;
+
+  // Populate |content length| with the value of the content-length header.
+  // Returns true on success, false if parsing fails or content-length header is
+  // missing.
+  static bool ExtractContentLengthFromHeaders(int64_t* content_length,
+                                              spdy::SpdyHeaderBlock* headers);
+
+  // Copies a list of headers to a SpdyHeaderBlock.
+  static bool CopyAndValidateHeaders(const QuicHeaderList& header_list,
+                                     int64_t* content_length,
+                                     spdy::SpdyHeaderBlock* headers);
+
+  // Copies a list of headers to a SpdyHeaderBlock.
+  // If |expect_final_byte_offset| is true, requires exactly one header field
+  // with key kFinalOffsetHeaderKey and an integer value.
+  // If |expect_final_byte_offset| is false, no kFinalOffsetHeaderKey may be
+  // present.
+  // Returns true if parsing is successful.  Returns false if the presence of
+  // kFinalOffsetHeaderKey does not match the value of
+  // |expect_final_byte_offset|, the kFinalOffsetHeaderKey value cannot be
+  // parsed, any other pseudo-header is present, an empty header key is present,
+  // or a header key contains an uppercase character.
+  static bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
+                                      bool expect_final_byte_offset,
+                                      size_t* final_byte_offset,
+                                      spdy::SpdyHeaderBlock* trailers);
+
+  // Populates the fields of |headers| to make a GET request of |url|,
+  // which must be fully-qualified.
+  static bool PopulateHeaderBlockFromUrl(const std::string url,
+                                         spdy::SpdyHeaderBlock* headers);
+
+  // Parses the "datagram-flow-id" header, returns the flow ID on success, or
+  // returns absl::nullopt if the header was not present or failed to parse.
+  static absl::optional<QuicDatagramStreamId> ParseDatagramFlowIdHeader(
+      const spdy::SpdyHeaderBlock& headers);
+
+  // Adds the "datagram-flow-id" header.
+  static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
+                                      QuicDatagramStreamId flow_id);
+
+  // Returns the advertised QUIC version from the specified alternative service
+  // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
+  // is advertised.
+  static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
+      const spdy::SpdyAltSvcWireFormat::AlternativeService&
+          alternative_service_entry,
+      const ParsedQuicVersionVector& supported_versions);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_SPDY_UTILS_H_
diff --git a/quiche/quic/core/http/spdy_utils_test.cc b/quiche/quic/core/http/spdy_utils_test.cc
new file mode 100644
index 0000000..d22a0e8
--- /dev/null
+++ b/quiche/quic/core/http/spdy_utils_test.cc
@@ -0,0 +1,442 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/spdy_utils.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using spdy::SpdyHeaderBlock;
+using testing::Pair;
+using testing::UnorderedElementsAre;
+
+namespace quic {
+namespace test {
+namespace {
+
+const bool kExpectFinalByteOffset = true;
+const bool kDoNotExpectFinalByteOffset = false;
+
+static std::unique_ptr<QuicHeaderList> FromList(
+    const QuicHeaderList::ListType& src) {
+  std::unique_ptr<QuicHeaderList> headers(new QuicHeaderList);
+  headers->OnHeaderBlockStart();
+  for (const auto& p : src) {
+    headers->OnHeader(p.first, p.second);
+  }
+  headers->OnHeaderBlockEnd(0, 0);
+  return headers;
+}
+
+static void ValidateDatagramFlowId(
+    const std::string& header_value,
+    absl::optional<QuicDatagramStreamId> expected_flow_id) {
+  SpdyHeaderBlock headers;
+  headers["datagram-flow-id"] = header_value;
+  ASSERT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), expected_flow_id);
+}
+
+}  // anonymous namespace
+
+using CopyAndValidateHeaders = QuicTest;
+
+TEST_F(CopyAndValidateHeaders, NormalUsage) {
+  auto headers = FromList({// All cookie crumbs are joined.
+                           {"cookie", " part 1"},
+                           {"cookie", "part 2 "},
+                           {"cookie", "part3"},
+
+                           // Already-delimited headers are passed through.
+                           {"passed-through", std::string("foo\0baz", 7)},
+
+                           // Other headers are joined on \0.
+                           {"joined", "value 1"},
+                           {"joined", "value 2"},
+
+                           // Empty headers remain empty.
+                           {"empty", ""},
+
+                           // Joined empty headers work as expected.
+                           {"empty-joined", ""},
+                           {"empty-joined", "foo"},
+                           {"empty-joined", ""},
+                           {"empty-joined", ""},
+
+                           // Non-continguous cookie crumb.
+                           {"cookie", " fin!"}});
+
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block,
+              UnorderedElementsAre(
+                  Pair("cookie", " part 1; part 2 ; part3;  fin!"),
+                  Pair("passed-through", absl::string_view("foo\0baz", 7)),
+                  Pair("joined", absl::string_view("value 1\0value 2", 15)),
+                  Pair("empty", ""),
+                  Pair("empty-joined", absl::string_view("\0foo\0\0", 6))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, EmptyName) {
+  auto headers = FromList({{"foo", "foovalue"}, {"", "barvalue"}, {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, UpperCaseName) {
+  auto headers =
+      FromList({{"foo", "foovalue"}, {"bar", "barvalue"}, {"bAz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleContentLengths) {
+  auto headers = FromList({{"content-length", "9"},
+                           {"foo", "foovalue"},
+                           {"content-length", "9"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("content-length", absl::string_view("9\09", 3)),
+                         Pair("baz", "")));
+  EXPECT_EQ(9, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, InconsistentContentLengths) {
+  auto headers = FromList({{"content-length", "9"},
+                           {"foo", "foovalue"},
+                           {"content-length", "8"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, LargeContentLength) {
+  auto headers = FromList({{"content-length", "9000000000"},
+                           {"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block,
+              UnorderedElementsAre(
+                  Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                  Pair("content-length", absl::string_view("9000000000")),
+                  Pair("baz", "")));
+  EXPECT_EQ(9000000000, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, NonDigitContentLength) {
+  // Section 3.3.2 of RFC 7230 defines content-length as being only digits.
+  // Number parsers might accept symbols like a leading plus; test that this
+  // fails to parse.
+  auto headers = FromList({{"content-length", "+123"},
+                           {"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleValues) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"baz", ""},
+                           {"foo", "boo"},
+                           {"baz", "buzz"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", absl::string_view("foovalue\0boo", 12)),
+                         Pair("bar", "barvalue"),
+                         Pair("baz", absl::string_view("\0buzz", 5))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MoreThanTwoValues) {
+  auto headers = FromList({{"set-cookie", "value1"},
+                           {"set-cookie", "value2"},
+                           {"set-cookie", "value3"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(Pair(
+                         "set-cookie",
+                         absl::string_view("value1\0value2\0value3", 20))));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, Cookie) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"cookie", "value1"},
+                           {"baz", ""}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("cookie", "value1"), Pair("baz", "")));
+  EXPECT_EQ(-1, content_length);
+}
+
+TEST_F(CopyAndValidateHeaders, MultipleCookies) {
+  auto headers = FromList({{"foo", "foovalue"},
+                           {"bar", "barvalue"},
+                           {"cookie", "value1"},
+                           {"baz", ""},
+                           {"cookie", "value2"}});
+  int64_t content_length = -1;
+  SpdyHeaderBlock block;
+  ASSERT_TRUE(
+      SpdyUtils::CopyAndValidateHeaders(*headers, &content_length, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(
+                         Pair("foo", "foovalue"), Pair("bar", "barvalue"),
+                         Pair("cookie", "value1; value2"), Pair("baz", "")));
+  EXPECT_EQ(-1, content_length);
+}
+
+using CopyAndValidateTrailers = QuicTest;
+
+TEST_F(CopyAndValidateTrailers, SimplestValidList) {
+  // Verify that the simplest trailers are valid: just a final byte offset that
+  // gets parsed successfully.
+  auto trailers = FromList({{kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_EQ(1234u, final_byte_offset);
+}
+
+TEST_F(CopyAndValidateTrailers, EmptyTrailerListWithFinalByteOffsetExpected) {
+  // An empty trailer list will fail as expected key kFinalOffsetHeaderKey is
+  // not present.
+  QuicHeaderList trailers;
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers,
+       EmptyTrailerListWithFinalByteOffsetNotExpected) {
+  // An empty trailer list will pass successfully if kFinalOffsetHeaderKey is
+  // not expected.
+  QuicHeaderList trailers;
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_TRUE(block.empty());
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetExpectedButNotPresent) {
+  // Validation fails if expected kFinalOffsetHeaderKey is not present, even if
+  // the rest of the header block is valid.
+  auto trailers = FromList({{"key", "value"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedButPresent) {
+  // Validation fails if kFinalOffsetHeaderKey is present but should not be,
+  // even if the rest of the header block is valid.
+  auto trailers = FromList({{"key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, FinalByteOffsetNotExpectedAndNotPresent) {
+  // Validation succeeds if kFinalOffsetHeaderKey is not expected and not
+  // present.
+  auto trailers = FromList({{"key", "value"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kDoNotExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_THAT(block, UnorderedElementsAre(Pair("key", "value")));
+}
+
+TEST_F(CopyAndValidateTrailers, EmptyName) {
+  // Trailer validation will fail with an empty header key, in an otherwise
+  // valid block of trailers.
+  auto trailers = FromList({{"", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, PseudoHeaderInTrailers) {
+  // Pseudo headers are illegal in trailers.
+  auto trailers =
+      FromList({{":pseudo_key", "value"}, {kFinalOffsetHeaderKey, "1234"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_FALSE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+}
+
+TEST_F(CopyAndValidateTrailers, DuplicateTrailers) {
+  // Duplicate trailers are allowed, and their values are concatenated into a
+  // single string delimted with '\0'. Some of the duplicate headers
+  // deliberately have an empty value.
+  auto trailers = FromList({{"key", "value0"},
+                            {"key", "value1"},
+                            {"key", ""},
+                            {"key", ""},
+                            {"key", "value2"},
+                            {"key", ""},
+                            {kFinalOffsetHeaderKey, "1234"},
+                            {"other_key", "value"},
+                            {"key", "non_contiguous_duplicate"}});
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *trailers, kExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_THAT(
+      block,
+      UnorderedElementsAre(
+          Pair("key",
+               absl::string_view(
+                   "value0\0value1\0\0\0value2\0\0non_contiguous_duplicate",
+                   48)),
+          Pair("other_key", "value")));
+}
+
+TEST_F(CopyAndValidateTrailers, DuplicateCookies) {
+  // Duplicate cookie headers in trailers should be concatenated into a single
+  //  "; " delimted string.
+  auto headers = FromList({{"cookie", " part 1"},
+                           {"cookie", "part 2 "},
+                           {"cookie", "part3"},
+                           {"key", "value"},
+                           {kFinalOffsetHeaderKey, "1234"},
+                           {"cookie", " non_contiguous_cookie!"}});
+
+  size_t final_byte_offset = 0;
+  SpdyHeaderBlock block;
+  EXPECT_TRUE(SpdyUtils::CopyAndValidateTrailers(
+      *headers, kExpectFinalByteOffset, &final_byte_offset, &block));
+  EXPECT_THAT(
+      block,
+      UnorderedElementsAre(
+          Pair("cookie", " part 1; part 2 ; part3;  non_contiguous_cookie!"),
+          Pair("key", "value")));
+}
+
+using PopulateHeaderBlockFromUrl = QuicTest;
+
+TEST_F(PopulateHeaderBlockFromUrl, NormalUsage) {
+  std::string url = "https://www.google.com/index.html";
+  SpdyHeaderBlock headers;
+  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
+  EXPECT_EQ("https", headers[":scheme"].as_string());
+  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
+  EXPECT_EQ("/index.html", headers[":path"].as_string());
+}
+
+TEST_F(PopulateHeaderBlockFromUrl, UrlWithNoPath) {
+  std::string url = "https://www.google.com";
+  SpdyHeaderBlock headers;
+  EXPECT_TRUE(SpdyUtils::PopulateHeaderBlockFromUrl(url, &headers));
+  EXPECT_EQ("https", headers[":scheme"].as_string());
+  EXPECT_EQ("www.google.com", headers[":authority"].as_string());
+  EXPECT_EQ("/", headers[":path"].as_string());
+}
+
+TEST_F(PopulateHeaderBlockFromUrl, Failure) {
+  SpdyHeaderBlock headers;
+  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/", &headers));
+  EXPECT_FALSE(SpdyUtils::PopulateHeaderBlockFromUrl("/index.html", &headers));
+  EXPECT_FALSE(
+      SpdyUtils::PopulateHeaderBlockFromUrl("www.google.com/", &headers));
+}
+
+using DatagramFlowIdTest = QuicTest;
+
+TEST_F(DatagramFlowIdTest, DatagramFlowId) {
+  // Test missing header.
+  SpdyHeaderBlock headers;
+  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), absl::nullopt);
+  // Add header and verify it parses.
+  QuicDatagramStreamId flow_id = 123;
+  SpdyUtils::AddDatagramFlowIdHeader(&headers, flow_id);
+  EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), flow_id);
+  // Test empty header.
+  ValidateDatagramFlowId("", absl::nullopt);
+  // Test invalid header.
+  ValidateDatagramFlowId("M4SQU3", absl::nullopt);
+  // Test simple header.
+  ValidateDatagramFlowId("42", 42);
+  // Test with parameter.
+  ValidateDatagramFlowId("42; abc=def", 42);
+  // Test list.
+  ValidateDatagramFlowId("42, 44; ecn-ect0, 46; ecn-ect1, 48; ecn-ce", 42);
+  // Test reordered list.
+  ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
+}
+
+using ExtractQuicVersionFromAltSvcEntry = QuicTest;
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+  for (const ParsedQuicVersion& version : supported_versions) {
+    entry.protocol_id = AlpnForVersion(version);
+    ParsedQuicVersion expected_version = version;
+    // Versions with share an ALPN with v1 are currently unable to be
+    // advertised with Alt-Svc.
+    if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
+        version != ParsedQuicVersion::RFCv1()) {
+      expected_version = ParsedQuicVersion::RFCv1();
+    }
+    EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+                                    entry, supported_versions))
+        << "version: " << version;
+  }
+}
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
+  spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+  entry.protocol_id = "quic";
+  EXPECT_EQ(ParsedQuicVersion::Unsupported(),
+            SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+                entry, AllSupportedVersions()));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_http3.cc b/quiche/quic/core/http/web_transport_http3.cc
new file mode 100644
index 0000000..f0e3849
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_http3.cc
@@ -0,0 +1,546 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/web_transport_http3.h"
+
+#include <limits>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/capsule.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+#define ENDPOINT \
+  (session_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+namespace quic {
+
+namespace {
+class QUIC_NO_EXPORT NoopWebTransportVisitor : public WebTransportVisitor {
+  void OnSessionReady(const spdy::SpdyHeaderBlock&) override {}
+  void OnSessionClosed(WebTransportSessionError /*error_code*/,
+                       const std::string& /*error_message*/) override {}
+  void OnIncomingBidirectionalStreamAvailable() override {}
+  void OnIncomingUnidirectionalStreamAvailable() override {}
+  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
+  void OnCanCreateNewOutgoingBidirectionalStream() override {}
+  void OnCanCreateNewOutgoingUnidirectionalStream() override {}
+};
+}  // namespace
+
+WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
+                                     QuicSpdyStream* connect_stream,
+                                     WebTransportSessionId id,
+                                     bool attempt_to_use_datagram_contexts)
+    : session_(session),
+      connect_stream_(connect_stream),
+      id_(id),
+      visitor_(std::make_unique<NoopWebTransportVisitor>()) {
+  QUICHE_DCHECK(session_->SupportsWebTransport());
+  QUICHE_DCHECK(IsValidWebTransportSessionId(id, session_->version()));
+  QUICHE_DCHECK_EQ(connect_stream_->id(), id);
+  connect_stream_->RegisterHttp3DatagramRegistrationVisitor(
+      this, attempt_to_use_datagram_contexts);
+  if (session_->perspective() == Perspective::IS_CLIENT) {
+    context_is_known_ = true;
+    context_currently_registered_ = true;
+    if (attempt_to_use_datagram_contexts) {
+      context_id_ = connect_stream_->GetNextDatagramContextId();
+    }
+  }
+}
+
+void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
+  streams_.insert(stream_id);
+
+  ParsedQuicVersion version = session_->version();
+  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
+                                    session_->perspective())) {
+    return;
+  }
+  if (QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
+    incoming_bidirectional_streams_.push_back(stream_id);
+    visitor_->OnIncomingBidirectionalStreamAvailable();
+  } else {
+    incoming_unidirectional_streams_.push_back(stream_id);
+    visitor_->OnIncomingUnidirectionalStreamAvailable();
+  }
+}
+
+void WebTransportHttp3::OnConnectStreamClosing() {
+  // Copy the stream list before iterating over it, as calls to ResetStream()
+  // can potentially mutate the |session_| list.
+  std::vector<QuicStreamId> streams(streams_.begin(), streams_.end());
+  streams_.clear();
+  for (QuicStreamId id : streams) {
+    session_->ResetStream(id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
+  }
+  if (context_currently_registered_) {
+    context_currently_registered_ = false;
+    connect_stream_->UnregisterHttp3DatagramContextId(context_id_);
+  }
+  connect_stream_->UnregisterHttp3DatagramRegistrationVisitor();
+
+  MaybeNotifyClose();
+}
+
+void WebTransportHttp3::CloseSession(WebTransportSessionError error_code,
+                                     absl::string_view error_message) {
+  if (close_sent_) {
+    QUIC_BUG(WebTransportHttp3 close sent twice)
+        << "Calling WebTransportHttp3::CloseSession() more than once is not "
+           "allowed.";
+    return;
+  }
+  close_sent_ = true;
+
+  // There can be a race between us trying to send our close and peer sending
+  // one.  If we received a close, however, we cannot send ours since we already
+  // closed the stream in response.
+  if (close_received_) {
+    QUIC_DLOG(INFO) << "Not sending CLOSE_WEBTRANSPORT_SESSION as we've "
+                       "already sent one from peer.";
+    return;
+  }
+
+  error_code_ = error_code;
+  error_message_ = std::string(error_message);
+  QuicConnection::ScopedPacketFlusher flusher(
+      connect_stream_->spdy_session()->connection());
+  connect_stream_->WriteCapsule(
+      Capsule::CloseWebTransportSession(error_code, error_message),
+      /*fin=*/true);
+}
+
+void WebTransportHttp3::OnCloseReceived(WebTransportSessionError error_code,
+                                        absl::string_view error_message) {
+  if (close_received_) {
+    QUIC_BUG(WebTransportHttp3 notified of close received twice)
+        << "WebTransportHttp3::OnCloseReceived() may be only called once.";
+  }
+  close_received_ = true;
+
+  // If the peer has sent a close after we sent our own, keep the local error.
+  if (close_sent_) {
+    QUIC_DLOG(INFO) << "Ignoring received CLOSE_WEBTRANSPORT_SESSION as we've "
+                       "already sent our own.";
+    return;
+  }
+
+  error_code_ = error_code;
+  error_message_ = std::string(error_message);
+  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
+  MaybeNotifyClose();
+}
+
+void WebTransportHttp3::OnConnectStreamFinReceived() {
+  // If we already received a CLOSE_WEBTRANSPORT_SESSION capsule, we don't need
+  // to do anything about receiving a FIN, since we already sent one in
+  // response.
+  if (close_received_) {
+    return;
+  }
+  close_received_ = true;
+  if (close_sent_) {
+    QUIC_DLOG(INFO) << "Ignoring received FIN as we've already sent our close.";
+    return;
+  }
+
+  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
+  MaybeNotifyClose();
+}
+
+void WebTransportHttp3::CloseSessionWithFinOnlyForTests() {
+  QUICHE_DCHECK(!close_sent_);
+  close_sent_ = true;
+  if (close_received_) {
+    return;
+  }
+
+  connect_stream_->WriteOrBufferBody("", /*fin=*/true);
+}
+
+void WebTransportHttp3::HeadersReceived(const spdy::SpdyHeaderBlock& headers) {
+  if (session_->perspective() == Perspective::IS_CLIENT) {
+    int status_code;
+    if (!QuicSpdyStream::ParseHeaderStatusCode(headers, &status_code)) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Received WebTransport headers from server without "
+                       "a valid status code, rejecting.";
+      rejection_reason_ = WebTransportHttp3RejectionReason::kNoStatusCode;
+      return;
+    }
+    bool valid_status = status_code >= 200 && status_code <= 299;
+    if (!valid_status) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Received WebTransport headers from server with "
+                       "status code "
+                    << status_code << ", rejecting.";
+      rejection_reason_ = WebTransportHttp3RejectionReason::kWrongStatusCode;
+      return;
+    }
+    bool should_validate_version =
+        session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
+        session_->ShouldValidateWebTransportVersion();
+    if (should_validate_version) {
+      auto draft_version_it = headers.find("sec-webtransport-http3-draft");
+      if (draft_version_it == headers.end()) {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Received WebTransport headers from server without "
+                         "a draft version, rejecting.";
+        rejection_reason_ =
+            WebTransportHttp3RejectionReason::kMissingDraftVersion;
+        return;
+      }
+      if (draft_version_it->second != "draft02") {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Received WebTransport headers from server with "
+                         "an unknown draft version ("
+                      << draft_version_it->second << "), rejecting.";
+        rejection_reason_ =
+            WebTransportHttp3RejectionReason::kUnsupportedDraftVersion;
+        return;
+      }
+    }
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "WebTransport session " << id_ << " ready.";
+  ready_ = true;
+  visitor_->OnSessionReady(headers);
+  session_->ProcessBufferedWebTransportStreamsForSession(this);
+}
+
+WebTransportStream* WebTransportHttp3::AcceptIncomingBidirectionalStream() {
+  while (!incoming_bidirectional_streams_.empty()) {
+    QuicStreamId id = incoming_bidirectional_streams_.front();
+    incoming_bidirectional_streams_.pop_front();
+    QuicSpdyStream* stream = session_->GetOrCreateSpdyDataStream(id);
+    if (stream == nullptr) {
+      // Skip the streams that were reset in between the time they were
+      // receieved and the time the client has polled for them.
+      continue;
+    }
+    return stream->web_transport_stream();
+  }
+  return nullptr;
+}
+
+WebTransportStream* WebTransportHttp3::AcceptIncomingUnidirectionalStream() {
+  while (!incoming_unidirectional_streams_.empty()) {
+    QuicStreamId id = incoming_unidirectional_streams_.front();
+    incoming_unidirectional_streams_.pop_front();
+    QuicStream* stream = session_->GetOrCreateStream(id);
+    if (stream == nullptr) {
+      // Skip the streams that were reset in between the time they were
+      // receieved and the time the client has polled for them.
+      continue;
+    }
+    return static_cast<WebTransportHttp3UnidirectionalStream*>(stream)
+        ->interface();
+  }
+  return nullptr;
+}
+
+bool WebTransportHttp3::CanOpenNextOutgoingBidirectionalStream() {
+  return session_->CanOpenOutgoingBidirectionalWebTransportStream(id_);
+}
+bool WebTransportHttp3::CanOpenNextOutgoingUnidirectionalStream() {
+  return session_->CanOpenOutgoingUnidirectionalWebTransportStream(id_);
+}
+WebTransportStream* WebTransportHttp3::OpenOutgoingBidirectionalStream() {
+  QuicSpdyStream* stream =
+      session_->CreateOutgoingBidirectionalWebTransportStream(this);
+  if (stream == nullptr) {
+    // If stream cannot be created due to flow control or other errors, return
+    // nullptr.
+    return nullptr;
+  }
+  return stream->web_transport_stream();
+}
+
+WebTransportStream* WebTransportHttp3::OpenOutgoingUnidirectionalStream() {
+  WebTransportHttp3UnidirectionalStream* stream =
+      session_->CreateOutgoingUnidirectionalWebTransportStream(this);
+  if (stream == nullptr) {
+    // If stream cannot be created due to flow control, return nullptr.
+    return nullptr;
+  }
+  return stream->interface();
+}
+
+MessageStatus WebTransportHttp3::SendOrQueueDatagram(
+    quiche::QuicheMemSlice datagram) {
+  return connect_stream_->SendHttp3Datagram(
+      context_id_, absl::string_view(datagram.data(), datagram.length()));
+}
+
+QuicByteCount WebTransportHttp3::GetMaxDatagramSize() const {
+  return connect_stream_->GetMaxDatagramSize(context_id_);
+}
+
+void WebTransportHttp3::SetDatagramMaxTimeInQueue(
+    QuicTime::Delta max_time_in_queue) {
+  connect_stream_->SetMaxDatagramTimeInQueue(max_time_in_queue);
+}
+
+void WebTransportHttp3::OnHttp3Datagram(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  QUICHE_DCHECK_EQ(stream_id, connect_stream_->id());
+  QUICHE_DCHECK(context_id == context_id_);
+  visitor_->OnDatagramReceived(payload);
+}
+
+void WebTransportHttp3::OnContextReceived(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    DatagramFormatType format_type, absl::string_view format_additional_data) {
+  if (stream_id != connect_stream_->id()) {
+    QUIC_BUG(WT3 bad datagram context registration)
+        << ENDPOINT << "Registered stream ID " << stream_id << ", expected "
+        << connect_stream_->id();
+    return;
+  }
+  if (format_type != DatagramFormatType::WEBTRANSPORT) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected datagram format type "
+                    << DatagramFormatTypeToString(format_type);
+    return;
+  }
+  if (!format_additional_data.empty()) {
+    QUIC_DLOG(ERROR)
+        << ENDPOINT
+        << "Received non-empty format additional data for context ID "
+        << (context_id_.has_value() ? context_id_.value() : 0)
+        << " on stream ID " << connect_stream_->id();
+    session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
+    return;
+  }
+  if (!context_is_known_) {
+    context_is_known_ = true;
+    context_id_ = context_id;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected context ID "
+                    << (context_id.has_value() ? context_id.value() : 0)
+                    << " instead of "
+                    << (context_id_.has_value() ? context_id_.value() : 0)
+                    << " on stream ID " << connect_stream_->id();
+    return;
+  }
+  if (session_->perspective() == Perspective::IS_SERVER) {
+    if (context_currently_registered_) {
+      QUIC_DLOG(ERROR) << ENDPOINT << "Received duplicate context ID "
+                       << (context_id_.has_value() ? context_id_.value() : 0)
+                       << " on stream ID " << connect_stream_->id();
+      session_->ResetStream(connect_stream_->id(), QUIC_STREAM_CANCELLED);
+      return;
+    }
+    context_currently_registered_ = true;
+    connect_stream_->RegisterHttp3DatagramContextId(
+        context_id_, format_type, format_additional_data, this);
+  }
+}
+
+void WebTransportHttp3::OnContextClosed(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    ContextCloseCode close_code, absl::string_view close_details) {
+  if (stream_id != connect_stream_->id()) {
+    QUIC_BUG(WT3 bad datagram context registration)
+        << ENDPOINT << "Closed context on stream ID " << stream_id
+        << ", expected " << connect_stream_->id();
+    return;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected close of context ID "
+                    << (context_id.has_value() ? context_id.value() : 0)
+                    << " instead of "
+                    << (context_id_.has_value() ? context_id_.value() : 0)
+                    << " on stream ID " << connect_stream_->id();
+    return;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "Received datagram context close with close code "
+                  << close_code << " close details \"" << close_details
+                  << "\" on stream ID " << connect_stream_->id()
+                  << ", resetting stream";
+  session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
+}
+
+void WebTransportHttp3::MaybeNotifyClose() {
+  if (close_notified_) {
+    return;
+  }
+  close_notified_ = true;
+  visitor_->OnSessionClosed(error_code_, error_message_);
+}
+
+WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
+    PendingStream* pending, QuicSpdySession* session)
+    : QuicStream(pending, session, /*is_static=*/false),
+      session_(session),
+      adapter_(session, this, sequencer()),
+      needs_to_send_preamble_(false) {}
+
+WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
+    QuicStreamId id, QuicSpdySession* session, WebTransportSessionId session_id)
+    : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL),
+      session_(session),
+      adapter_(session, this, sequencer()),
+      session_id_(session_id),
+      needs_to_send_preamble_(true) {}
+
+void WebTransportHttp3UnidirectionalStream::WritePreamble() {
+  if (!needs_to_send_preamble_ || !session_id_.has_value()) {
+    QUIC_BUG(WebTransportHttp3UnidirectionalStream duplicate preamble)
+        << ENDPOINT << "Sending preamble on stream ID " << id()
+        << " at the wrong time.";
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Attempting to send a WebTransport unidirectional "
+                         "stream preamble at the wrong time.");
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(session_->connection());
+  char buffer[sizeof(uint64_t) * 2];  // varint62, varint62
+  QuicDataWriter writer(sizeof(buffer), buffer);
+  bool success = true;
+  success = success && writer.WriteVarInt62(kWebTransportUnidirectionalStream);
+  success = success && writer.WriteVarInt62(*session_id_);
+  QUICHE_DCHECK(success);
+  WriteOrBufferData(absl::string_view(buffer, writer.length()), /*fin=*/false,
+                    /*ack_listener=*/nullptr);
+  QUIC_DVLOG(1) << ENDPOINT << "Sent stream type and session ID ("
+                << *session_id_ << ") on WebTransport stream " << id();
+  needs_to_send_preamble_ = false;
+}
+
+bool WebTransportHttp3UnidirectionalStream::ReadSessionId() {
+  iovec iov;
+  if (!sequencer()->GetReadableRegion(&iov)) {
+    return false;
+  }
+  QuicDataReader reader(static_cast<const char*>(iov.iov_base), iov.iov_len);
+  WebTransportSessionId session_id;
+  uint8_t session_id_length = reader.PeekVarInt62Length();
+  if (!reader.ReadVarInt62(&session_id)) {
+    // If all of the data has been received, and we still cannot associate the
+    // stream with a session, consume all of the data so that the stream can
+    // be closed.
+    if (sequencer()->NumBytesConsumed() + sequencer()->NumBytesBuffered() >=
+        sequencer()->close_offset()) {
+      QUIC_DLOG(WARNING)
+          << ENDPOINT << "Failed to associate WebTransport stream " << id()
+          << " with a session because the stream ended prematurely.";
+      sequencer()->MarkConsumed(sequencer()->NumBytesBuffered());
+    }
+    return false;
+  }
+  sequencer()->MarkConsumed(session_id_length);
+  session_id_ = session_id;
+  session_->AssociateIncomingWebTransportStreamWithSession(session_id, id());
+  return true;
+}
+
+void WebTransportHttp3UnidirectionalStream::OnDataAvailable() {
+  if (!session_id_.has_value()) {
+    if (!ReadSessionId()) {
+      return;
+    }
+  }
+
+  adapter_.OnDataAvailable();
+}
+
+void WebTransportHttp3UnidirectionalStream::OnCanWriteNewData() {
+  adapter_.OnCanWriteNewData();
+}
+
+void WebTransportHttp3UnidirectionalStream::OnClose() {
+  QuicStream::OnClose();
+
+  if (!session_id_.has_value()) {
+    return;
+  }
+  WebTransportHttp3* session = session_->GetWebTransportSession(*session_id_);
+  if (session == nullptr) {
+    QUIC_DLOG(WARNING) << ENDPOINT << "WebTransport stream " << id()
+                       << " attempted to notify parent session " << *session_id_
+                       << ", but the session could not be found.";
+    return;
+  }
+  session->OnStreamClosed(id());
+}
+
+void WebTransportHttp3UnidirectionalStream::OnStreamReset(
+    const QuicRstStreamFrame& frame) {
+  if (adapter_.visitor() != nullptr) {
+    adapter_.visitor()->OnResetStreamReceived(
+        Http3ErrorToWebTransportOrDefault(frame.ietf_error_code));
+  }
+  QuicStream::OnStreamReset(frame);
+}
+bool WebTransportHttp3UnidirectionalStream::OnStopSending(
+    QuicResetStreamError error) {
+  if (adapter_.visitor() != nullptr) {
+    adapter_.visitor()->OnStopSendingReceived(
+        Http3ErrorToWebTransportOrDefault(error.ietf_application_code()));
+  }
+  return QuicStream::OnStopSending(error);
+}
+void WebTransportHttp3UnidirectionalStream::OnWriteSideInDataRecvdState() {
+  if (adapter_.visitor() != nullptr) {
+    adapter_.visitor()->OnWriteSideInDataRecvdState();
+  }
+
+  QuicStream::OnWriteSideInDataRecvdState();
+}
+
+namespace {
+constexpr uint64_t kWebTransportMappedErrorCodeFirst = 0x52e4a40fa8db;
+constexpr uint64_t kWebTransportMappedErrorCodeLast = 0x52e4a40fa9e2;
+constexpr WebTransportStreamError kDefaultWebTransportError = 0;
+}  // namespace
+
+absl::optional<WebTransportStreamError> Http3ErrorToWebTransport(
+    uint64_t http3_error_code) {
+  // Ensure the code is within the valid range.
+  if (http3_error_code < kWebTransportMappedErrorCodeFirst ||
+      http3_error_code > kWebTransportMappedErrorCodeLast) {
+    return absl::nullopt;
+  }
+  // Exclude GREASE codepoints.
+  if ((http3_error_code - 0x21) % 0x1f == 0) {
+    return absl::nullopt;
+  }
+
+  uint64_t shifted = http3_error_code - kWebTransportMappedErrorCodeFirst;
+  uint64_t result = shifted - shifted / 0x1f;
+  QUICHE_DCHECK_LE(result, std::numeric_limits<uint8_t>::max());
+  return result;
+}
+
+WebTransportStreamError Http3ErrorToWebTransportOrDefault(
+    uint64_t http3_error_code) {
+  absl::optional<WebTransportStreamError> result =
+      Http3ErrorToWebTransport(http3_error_code);
+  return result.has_value() ? *result : kDefaultWebTransportError;
+}
+
+uint64_t WebTransportErrorToHttp3(
+    WebTransportStreamError webtransport_error_code) {
+  return kWebTransportMappedErrorCodeFirst + webtransport_error_code +
+         webtransport_error_code / 0x1e;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_http3.h b/quiche/quic/core/http/web_transport_http3.h
new file mode 100644
index 0000000..03ed764
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_http3.h
@@ -0,0 +1,198 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
+#define QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
+
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/http/web_transport_stream_adapter.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+class QuicSpdySession;
+class QuicSpdyStream;
+
+enum class WebTransportHttp3RejectionReason {
+  kNone,
+  kNoStatusCode,
+  kWrongStatusCode,
+  kMissingDraftVersion,
+  kUnsupportedDraftVersion,
+};
+
+// A session of WebTransport over HTTP/3.  The session is owned by
+// QuicSpdyStream object for the CONNECT stream that established it.
+//
+// WebTransport over HTTP/3 specification:
+// <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3>
+class QUIC_EXPORT_PRIVATE WebTransportHttp3
+    : public WebTransportSession,
+      public QuicSpdyStream::Http3DatagramRegistrationVisitor,
+      public QuicSpdyStream::Http3DatagramVisitor {
+ public:
+  WebTransportHttp3(QuicSpdySession* session, QuicSpdyStream* connect_stream,
+                    WebTransportSessionId id,
+                    bool attempt_to_use_datagram_contexts);
+
+  void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
+  void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
+    visitor_ = std::move(visitor);
+  }
+
+  WebTransportSessionId id() { return id_; }
+  bool ready() { return ready_; }
+  absl::optional<QuicDatagramContextId> context_id() const {
+    return context_id_;
+  }
+
+  void AssociateStream(QuicStreamId stream_id);
+  void OnStreamClosed(QuicStreamId stream_id) { streams_.erase(stream_id); }
+  void OnConnectStreamClosing();
+
+  size_t NumberOfAssociatedStreams() { return streams_.size(); }
+
+  void CloseSession(WebTransportSessionError error_code,
+                    absl::string_view error_message) override;
+  void OnCloseReceived(WebTransportSessionError error_code,
+                       absl::string_view error_message);
+  void OnConnectStreamFinReceived();
+
+  // It is legal for WebTransport to be closed without a
+  // CLOSE_WEBTRANSPORT_SESSION capsule.  We always send a capsule, but we still
+  // need to ensure we handle this case correctly.
+  void CloseSessionWithFinOnlyForTests();
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.
+  WebTransportStream* AcceptIncomingBidirectionalStream() override;
+  WebTransportStream* AcceptIncomingUnidirectionalStream() override;
+
+  bool CanOpenNextOutgoingBidirectionalStream() override;
+  bool CanOpenNextOutgoingUnidirectionalStream() override;
+  WebTransportStream* OpenOutgoingBidirectionalStream() override;
+  WebTransportStream* OpenOutgoingUnidirectionalStream() override;
+
+  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram) override;
+  QuicByteCount GetMaxDatagramSize() const override;
+  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override;
+
+  // From QuicSpdyStream::Http3DatagramVisitor.
+  void OnHttp3Datagram(QuicStreamId stream_id,
+                       absl::optional<QuicDatagramContextId> context_id,
+                       absl::string_view payload) override;
+
+  // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
+  void OnContextReceived(QuicStreamId stream_id,
+                         absl::optional<QuicDatagramContextId> context_id,
+                         DatagramFormatType format_type,
+                         absl::string_view format_additional_data) override;
+  void OnContextClosed(QuicStreamId stream_id,
+                       absl::optional<QuicDatagramContextId> context_id,
+                       ContextCloseCode close_code,
+                       absl::string_view close_details) override;
+
+  bool close_received() const { return close_received_; }
+  WebTransportHttp3RejectionReason rejection_reason() const {
+    return rejection_reason_;
+  }
+
+ private:
+  // Notifies the visitor that the connection has been closed.  Ensures that the
+  // visitor is only ever called once.
+  void MaybeNotifyClose();
+
+  QuicSpdySession* const session_;        // Unowned.
+  QuicSpdyStream* const connect_stream_;  // Unowned.
+  const WebTransportSessionId id_;
+  absl::optional<QuicDatagramContextId> context_id_;
+  // |ready_| is set to true when the peer has seen both sets of headers.
+  bool ready_ = false;
+  // Whether we know which |context_id_| to use. On the client this is always
+  // true, and on the server it becomes true when we receive a context
+  // registration capsule.
+  bool context_is_known_ = false;
+  // Whether |context_id_| is currently registered with |connect_stream_|.
+  bool context_currently_registered_ = false;
+  std::unique_ptr<WebTransportVisitor> visitor_;
+  absl::flat_hash_set<QuicStreamId> streams_;
+  quiche::QuicheCircularDeque<QuicStreamId> incoming_bidirectional_streams_;
+  quiche::QuicheCircularDeque<QuicStreamId> incoming_unidirectional_streams_;
+
+  bool close_sent_ = false;
+  bool close_received_ = false;
+  bool close_notified_ = false;
+
+  WebTransportHttp3RejectionReason rejection_reason_ =
+      WebTransportHttp3RejectionReason::kNone;
+  // Those are set to default values, which are used if the session is not
+  // closed cleanly using an appropriate capsule.
+  WebTransportSessionError error_code_ = 0;
+  std::string error_message_ = "";
+};
+
+class QUIC_EXPORT_PRIVATE WebTransportHttp3UnidirectionalStream
+    : public QuicStream {
+ public:
+  // Incoming stream.
+  WebTransportHttp3UnidirectionalStream(PendingStream* pending,
+                                        QuicSpdySession* session);
+  // Outgoing stream.
+  WebTransportHttp3UnidirectionalStream(QuicStreamId id,
+                                        QuicSpdySession* session,
+                                        WebTransportSessionId session_id);
+
+  // Sends the stream type and the session ID on the stream.
+  void WritePreamble();
+
+  // Implementation of QuicStream.
+  void OnDataAvailable() override;
+  void OnCanWriteNewData() override;
+  void OnClose() override;
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  bool OnStopSending(QuicResetStreamError error) override;
+  void OnWriteSideInDataRecvdState() override;
+
+  WebTransportStream* interface() { return &adapter_; }
+  void SetUnblocked() { sequencer()->SetUnblocked(); }
+
+ private:
+  QuicSpdySession* session_;
+  WebTransportStreamAdapter adapter_;
+  absl::optional<WebTransportSessionId> session_id_;
+  bool needs_to_send_preamble_;
+
+  bool ReadSessionId();
+  // Closes the stream if all of the data has been received.
+  void MaybeCloseIncompleteStream();
+};
+
+// Remaps HTTP/3 error code into a WebTransport error code.  Returns nullopt if
+// the provided code is outside of valid range.
+QUIC_EXPORT_PRIVATE absl::optional<WebTransportStreamError>
+Http3ErrorToWebTransport(uint64_t http3_error_code);
+
+// Same as above, but returns default error value (zero) when none could be
+// mapped.
+QUIC_EXPORT_PRIVATE WebTransportStreamError
+Http3ErrorToWebTransportOrDefault(uint64_t http3_error_code);
+
+// Remaps WebTransport error code into an HTTP/3 error code.
+QUIC_EXPORT_PRIVATE uint64_t
+WebTransportErrorToHttp3(WebTransportStreamError webtransport_error_code);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_WEB_TRANSPORT_HTTP3_H_
diff --git a/quiche/quic/core/http/web_transport_http3_test.cc b/quiche/quic/core/http/web_transport_http3_test.cc
new file mode 100644
index 0000000..87cd0d3
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_http3_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/web_transport_http3.h"
+
+#include <cstdint>
+#include <limits>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+using ::testing::Optional;
+
+TEST(WebTransportHttp3Test, ErrorCodesToHttp3) {
+  EXPECT_EQ(0x52e4a40fa8dbu, WebTransportErrorToHttp3(0x00));
+  EXPECT_EQ(0x52e4a40fa9e2u, WebTransportErrorToHttp3(0xff));
+
+  EXPECT_EQ(0x52e4a40fa8f7u, WebTransportErrorToHttp3(0x1c));
+  EXPECT_EQ(0x52e4a40fa8f8u, WebTransportErrorToHttp3(0x1d));
+  //        0x52e4a40fa8f9 is a GREASE codepoint
+  EXPECT_EQ(0x52e4a40fa8fau, WebTransportErrorToHttp3(0x1e));
+}
+
+TEST(WebTransportHttp3Test, ErrorCodesToWebTransport) {
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8db), Optional(0x00));
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa9e2), Optional(0xff));
+
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f7), Optional(0x1cu));
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f8), Optional(0x1du));
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8f9), absl::nullopt);
+  EXPECT_THAT(Http3ErrorToWebTransport(0x52e4a40fa8fa), Optional(0x1eu));
+
+  EXPECT_EQ(Http3ErrorToWebTransport(0), absl::nullopt);
+  EXPECT_EQ(Http3ErrorToWebTransport(std::numeric_limits<uint64_t>::max()),
+            absl::nullopt);
+}
+
+TEST(WebTransportHttp3Test, ErrorCodeRoundTrip) {
+  for (int error = 0; error < 256; error++) {
+    uint64_t http_error = WebTransportErrorToHttp3(error);
+    absl::optional<WebTransportStreamError> mapped_back =
+        quic::Http3ErrorToWebTransport(http_error);
+    EXPECT_THAT(mapped_back, Optional(error));
+  }
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_stream_adapter.cc b/quiche/quic/core/http/web_transport_stream_adapter.cc
new file mode 100644
index 0000000..ff19214
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_stream_adapter.cc
@@ -0,0 +1,128 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/http/web_transport_stream_adapter.h"
+
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+WebTransportStreamAdapter::WebTransportStreamAdapter(
+    QuicSession* session,
+    QuicStream* stream,
+    QuicStreamSequencer* sequencer)
+    : session_(session), stream_(stream), sequencer_(sequencer) {}
+
+WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
+    char* buffer,
+    size_t buffer_size) {
+  iovec iov;
+  iov.iov_base = buffer;
+  iov.iov_len = buffer_size;
+  const size_t result = sequencer_->Readv(&iov, 1);
+  if (!fin_read_ && sequencer_->IsClosed()) {
+    fin_read_ = true;
+    stream_->OnFinRead();
+  }
+  return ReadResult{result, sequencer_->IsClosed()};
+}
+
+WebTransportStream::ReadResult WebTransportStreamAdapter::Read(
+    std::string* output) {
+  const size_t old_size = output->size();
+  const size_t bytes_to_read = ReadableBytes();
+  output->resize(old_size + bytes_to_read);
+  ReadResult result = Read(&(*output)[old_size], bytes_to_read);
+  QUICHE_DCHECK_EQ(bytes_to_read, result.bytes_read);
+  output->resize(old_size + result.bytes_read);
+  return result;
+}
+
+bool WebTransportStreamAdapter::Write(absl::string_view data) {
+  if (!CanWrite()) {
+    return false;
+  }
+
+  quiche::QuicheMemSlice memslice(quiche::QuicheBuffer::Copy(
+      session_->connection()->helper()->GetStreamSendBufferAllocator(), data));
+  QuicConsumedData consumed =
+      stream_->WriteMemSlices(absl::MakeSpan(&memslice, 1), /*fin=*/false);
+
+  if (consumed.bytes_consumed == data.size()) {
+    return true;
+  }
+  if (consumed.bytes_consumed == 0) {
+    return false;
+  }
+  // WebTransportStream::Write() is an all-or-nothing write API.  To achieve
+  // that property, it relies on WriteMemSlices() being an all-or-nothing API.
+  // If WriteMemSlices() fails to provide that guarantee, we have no way to
+  // communicate a partial write to the caller, and thus it's safer to just
+  // close the connection.
+  QUIC_BUG(WebTransportStreamAdapter partial write)
+      << "WriteMemSlices() unexpectedly partially consumed the input "
+         "data, provided: "
+      << data.size() << ", written: " << consumed.bytes_consumed;
+  stream_->OnUnrecoverableError(
+      QUIC_INTERNAL_ERROR,
+      "WriteMemSlices() unexpectedly partially consumed the input data");
+  return false;
+}
+
+bool WebTransportStreamAdapter::SendFin() {
+  if (!CanWrite()) {
+    return false;
+  }
+
+  quiche::QuicheMemSlice empty;
+  QuicConsumedData consumed =
+      stream_->WriteMemSlices(absl::MakeSpan(&empty, 1), /*fin=*/true);
+  QUICHE_DCHECK_EQ(consumed.bytes_consumed, 0u);
+  return consumed.fin_consumed;
+}
+
+bool WebTransportStreamAdapter::CanWrite() const {
+  return stream_->CanWriteNewData() && !stream_->write_side_closed();
+}
+
+size_t WebTransportStreamAdapter::ReadableBytes() const {
+  return sequencer_->ReadableBytes();
+}
+
+void WebTransportStreamAdapter::OnDataAvailable() {
+  if (visitor_ == nullptr) {
+    return;
+  }
+  const bool fin_readable = sequencer_->IsClosed() && !fin_read_;
+  if (ReadableBytes() == 0 && !fin_readable) {
+    return;
+  }
+  visitor_->OnCanRead();
+}
+
+void WebTransportStreamAdapter::OnCanWriteNewData() {
+  // Ensure the origin check has been completed, as the stream can be notified
+  // about being writable before that.
+  if (!CanWrite()) {
+    return;
+  }
+  if (visitor_ != nullptr) {
+    visitor_->OnCanWrite();
+  }
+}
+
+void WebTransportStreamAdapter::ResetWithUserCode(
+    WebTransportStreamError error) {
+  stream_->ResetWriteSide(QuicResetStreamError(
+      QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
+}
+
+void WebTransportStreamAdapter::SendStopSending(WebTransportStreamError error) {
+  stream_->SendStopSending(QuicResetStreamError(
+      QUIC_STREAM_CANCELLED, WebTransportErrorToHttp3(error)));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/http/web_transport_stream_adapter.h b/quiche/quic/core/http/web_transport_stream_adapter.h
new file mode 100644
index 0000000..5549cba
--- /dev/null
+++ b/quiche/quic/core/http/web_transport_stream_adapter.h
@@ -0,0 +1,66 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
+#define QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
+
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+
+namespace quic {
+
+// Converts WebTransportStream API calls into QuicStream API calls.  The users
+// of this class can either subclass it, or wrap around it.
+class QUIC_EXPORT_PRIVATE WebTransportStreamAdapter
+    : public WebTransportStream {
+ public:
+  WebTransportStreamAdapter(QuicSession* session,
+                            QuicStream* stream,
+                            QuicStreamSequencer* sequencer);
+
+  // WebTransportStream implementation.
+  ABSL_MUST_USE_RESULT ReadResult Read(char* buffer,
+                                       size_t buffer_size) override;
+  ABSL_MUST_USE_RESULT ReadResult Read(std::string* output) override;
+  ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
+  ABSL_MUST_USE_RESULT bool SendFin() override;
+  bool CanWrite() const override;
+  size_t ReadableBytes() const override;
+  void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
+    visitor_ = std::move(visitor);
+  }
+  QuicStreamId GetStreamId() const override { return stream_->id(); }
+
+  void ResetWithUserCode(WebTransportStreamError error) override;
+  void ResetDueToInternalError() override {
+    stream_->Reset(QUIC_STREAM_INTERNAL_ERROR);
+  }
+  void SendStopSending(WebTransportStreamError error) override;
+  void MaybeResetDueToStreamObjectGone() override {
+    if (stream_->write_side_closed() && stream_->read_side_closed()) {
+      return;
+    }
+    stream_->Reset(QUIC_STREAM_CANCELLED);
+  }
+
+  WebTransportStreamVisitor* visitor() override { return visitor_.get(); }
+
+  // Calls that need to be passed from the corresponding QuicStream methods.
+  void OnDataAvailable();
+  void OnCanWriteNewData();
+
+ private:
+  QuicSession* session_;            // Unowned.
+  QuicStream* stream_;              // Unowned.
+  QuicStreamSequencer* sequencer_;  // Unowned.
+  std::unique_ptr<WebTransportStreamVisitor> visitor_;
+  bool fin_read_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_STREAM_ADAPTER_H_
diff --git a/quiche/quic/core/legacy_quic_stream_id_manager.cc b/quiche/quic/core/legacy_quic_stream_id_manager.cc
new file mode 100644
index 0000000..1afefaa
--- /dev/null
+++ b/quiche/quic/core/legacy_quic_stream_id_manager.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "quiche/quic/core/legacy_quic_stream_id_manager.h"
+
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+LegacyQuicStreamIdManager::LegacyQuicStreamIdManager(
+    Perspective perspective,
+    QuicTransportVersion transport_version,
+    size_t max_open_outgoing_streams,
+    size_t max_open_incoming_streams)
+    : perspective_(perspective),
+      transport_version_(transport_version),
+      max_open_outgoing_streams_(max_open_outgoing_streams),
+      max_open_incoming_streams_(max_open_incoming_streams),
+      next_outgoing_stream_id_(
+          QuicUtils::GetFirstBidirectionalStreamId(transport_version_,
+                                                   perspective_)),
+      largest_peer_created_stream_id_(
+          perspective_ == Perspective::IS_SERVER
+              ? (QuicVersionUsesCryptoFrames(transport_version_)
+                     ? QuicUtils::GetInvalidStreamId(transport_version_)
+                     : QuicUtils::GetCryptoStreamId(transport_version_))
+              : QuicUtils::GetInvalidStreamId(transport_version_)),
+      num_open_incoming_streams_(0),
+      num_open_outgoing_streams_(0) {}
+
+LegacyQuicStreamIdManager::~LegacyQuicStreamIdManager() {}
+
+bool LegacyQuicStreamIdManager::CanOpenNextOutgoingStream() const {
+  QUICHE_DCHECK_LE(num_open_outgoing_streams_, max_open_outgoing_streams_);
+  QUIC_DLOG_IF(INFO, num_open_outgoing_streams_ == max_open_outgoing_streams_)
+      << "Failed to create a new outgoing stream. "
+      << "Already " << num_open_outgoing_streams_ << " open.";
+  return num_open_outgoing_streams_ < max_open_outgoing_streams_;
+}
+
+bool LegacyQuicStreamIdManager::CanOpenIncomingStream() const {
+  return num_open_incoming_streams_ < max_open_incoming_streams_;
+}
+
+bool LegacyQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
+    const QuicStreamId stream_id) {
+  available_streams_.erase(stream_id);
+
+  if (largest_peer_created_stream_id_ !=
+          QuicUtils::GetInvalidStreamId(transport_version_) &&
+      stream_id <= largest_peer_created_stream_id_) {
+    return true;
+  }
+
+  // Check if the new number of available streams would cause the number of
+  // available streams to exceed the limit.  Note that the peer can create
+  // only alternately-numbered streams.
+  size_t additional_available_streams =
+      (stream_id - largest_peer_created_stream_id_) / 2 - 1;
+  if (largest_peer_created_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(transport_version_)) {
+    additional_available_streams = (stream_id + 1) / 2 - 1;
+  }
+  size_t new_num_available_streams =
+      GetNumAvailableStreams() + additional_available_streams;
+  if (new_num_available_streams > MaxAvailableStreams()) {
+    QUIC_DLOG(INFO) << perspective_
+                    << "Failed to create a new incoming stream with id:"
+                    << stream_id << ".  There are already "
+                    << GetNumAvailableStreams()
+                    << " streams available, which would become "
+                    << new_num_available_streams << ", which exceeds the limit "
+                    << MaxAvailableStreams() << ".";
+    return false;
+  }
+  QuicStreamId first_available_stream = largest_peer_created_stream_id_ + 2;
+  if (largest_peer_created_stream_id_ ==
+      QuicUtils::GetInvalidStreamId(transport_version_)) {
+    first_available_stream = QuicUtils::GetFirstBidirectionalStreamId(
+        transport_version_, QuicUtils::InvertPerspective(perspective_));
+  }
+  for (QuicStreamId id = first_available_stream; id < stream_id; id += 2) {
+    available_streams_.insert(id);
+  }
+  largest_peer_created_stream_id_ = stream_id;
+
+  return true;
+}
+
+QuicStreamId LegacyQuicStreamIdManager::GetNextOutgoingStreamId() {
+  QuicStreamId id = next_outgoing_stream_id_;
+  next_outgoing_stream_id_ += 2;
+  return id;
+}
+
+void LegacyQuicStreamIdManager::ActivateStream(bool is_incoming) {
+  if (is_incoming) {
+    ++num_open_incoming_streams_;
+    return;
+  }
+  ++num_open_outgoing_streams_;
+}
+
+void LegacyQuicStreamIdManager::OnStreamClosed(bool is_incoming) {
+  if (is_incoming) {
+    QUIC_BUG_IF(quic_bug_12720_1, num_open_incoming_streams_ == 0);
+    --num_open_incoming_streams_;
+    return;
+  }
+  QUIC_BUG_IF(quic_bug_12720_2, num_open_outgoing_streams_ == 0);
+  --num_open_outgoing_streams_;
+}
+
+bool LegacyQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
+  if (!IsIncomingStream(id)) {
+    // Stream IDs under next_ougoing_stream_id_ are either open or previously
+    // open but now closed.
+    return id >= next_outgoing_stream_id_;
+  }
+  // For peer created streams, we also need to consider available streams.
+  return largest_peer_created_stream_id_ ==
+             QuicUtils::GetInvalidStreamId(transport_version_) ||
+         id > largest_peer_created_stream_id_ ||
+         available_streams_.contains(id);
+}
+
+bool LegacyQuicStreamIdManager::IsIncomingStream(QuicStreamId id) const {
+  return id % 2 != next_outgoing_stream_id_ % 2;
+}
+
+size_t LegacyQuicStreamIdManager::GetNumAvailableStreams() const {
+  return available_streams_.size();
+}
+
+size_t LegacyQuicStreamIdManager::MaxAvailableStreams() const {
+  return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/legacy_quic_stream_id_manager.h b/quiche/quic/core/legacy_quic_stream_id_manager.h
new file mode 100644
index 0000000..3c67028
--- /dev/null
+++ b/quiche/quic/core/legacy_quic_stream_id_manager.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
+
+#include "absl/container/flat_hash_set.h"
+#include "quiche/quic/core/quic_stream_id_manager.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+namespace test {
+class QuicSessionPeer;
+}  // namespace test
+
+class QuicSession;
+
+// Manages Google QUIC stream IDs. This manager is responsible for two
+// questions: 1) can next outgoing stream ID be allocated (if yes, what is the
+// next outgoing stream ID) and 2) can a new incoming stream be opened.
+class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
+ public:
+  LegacyQuicStreamIdManager(Perspective perspective,
+                            QuicTransportVersion transport_version,
+                            size_t max_open_outgoing_streams,
+                            size_t max_open_incoming_streams);
+
+  ~LegacyQuicStreamIdManager();
+
+  // Returns true if the next outgoing stream ID can be allocated.
+  bool CanOpenNextOutgoingStream() const;
+
+  // Returns true if a new incoming stream can be opened.
+  bool CanOpenIncomingStream() const;
+
+  // Returns false when increasing the largest created stream id to |id| would
+  // violate the limit, so the connection should be closed.
+  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId id);
+
+  // Returns true if |id| is still available.
+  bool IsAvailableStream(QuicStreamId id) const;
+
+  // Returns the stream ID for a new outgoing stream, and increments the
+  // underlying counter.
+  QuicStreamId GetNextOutgoingStreamId();
+
+  // Called when a new stream is open.
+  void ActivateStream(bool is_incoming);
+
+  // Called when a stream ID is closed.
+  void OnStreamClosed(bool is_incoming);
+
+  // Return true if |id| is peer initiated.
+  bool IsIncomingStream(QuicStreamId id) const;
+
+  size_t MaxAvailableStreams() const;
+
+  void set_max_open_incoming_streams(size_t max_open_incoming_streams) {
+    max_open_incoming_streams_ = max_open_incoming_streams;
+  }
+
+  void set_max_open_outgoing_streams(size_t max_open_outgoing_streams) {
+    max_open_outgoing_streams_ = max_open_outgoing_streams;
+  }
+
+  void set_largest_peer_created_stream_id(
+      QuicStreamId largest_peer_created_stream_id) {
+    largest_peer_created_stream_id_ = largest_peer_created_stream_id;
+  }
+
+  size_t max_open_incoming_streams() const {
+    return max_open_incoming_streams_;
+  }
+
+  size_t max_open_outgoing_streams() const {
+    return max_open_outgoing_streams_;
+  }
+
+  QuicStreamId next_outgoing_stream_id() const {
+    return next_outgoing_stream_id_;
+  }
+
+  QuicStreamId largest_peer_created_stream_id() const {
+    return largest_peer_created_stream_id_;
+  }
+
+  size_t GetNumAvailableStreams() const;
+
+  size_t num_open_incoming_streams() const {
+    return num_open_incoming_streams_;
+  }
+  size_t num_open_outgoing_streams() const {
+    return num_open_outgoing_streams_;
+  }
+
+ private:
+  friend class test::QuicSessionPeer;
+
+  const Perspective perspective_;
+  const QuicTransportVersion transport_version_;
+
+  // The maximum number of outgoing streams this connection can open.
+  size_t max_open_outgoing_streams_;
+
+  // The maximum number of incoming streams this connection will allow.
+  size_t max_open_incoming_streams_;
+
+  // The ID to use for the next outgoing stream.
+  QuicStreamId next_outgoing_stream_id_;
+
+  // Set of stream ids that are less than the largest stream id that has been
+  // received, but are nonetheless available to be created.
+  absl::flat_hash_set<QuicStreamId> available_streams_;
+
+  QuicStreamId largest_peer_created_stream_id_;
+
+  // A counter for peer initiated open streams.
+  size_t num_open_incoming_streams_;
+
+  // A counter for self initiated open streams.
+  size_t num_open_outgoing_streams_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quiche/quic/core/legacy_quic_stream_id_manager_test.cc b/quiche/quic/core/legacy_quic_stream_id_manager_test.cc
new file mode 100644
index 0000000..5ab742c
--- /dev/null
+++ b/quiche/quic/core/legacy_quic_stream_id_manager_test.cc
@@ -0,0 +1,180 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/legacy_quic_stream_id_manager.h"
+
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::StrictMock;
+
+struct TestParams {
+  TestParams(ParsedQuicVersion version, Perspective perspective)
+      : version(version), perspective(perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version),
+      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (ParsedQuicVersion version : AllSupportedVersions()) {
+    for (auto perspective : {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
+      // LegacyQuicStreamIdManager is only used when IETF QUIC frames are not
+      // presented.
+      if (!VersionHasIetfQuicFrames(version.transport_version)) {
+        params.push_back(TestParams(version, perspective));
+      }
+    }
+  }
+  return params;
+}
+
+class LegacyQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
+ public:
+  LegacyQuicStreamIdManagerTest()
+      : manager_(GetParam().perspective,
+                 GetParam().version.transport_version,
+                 kDefaultMaxStreamsPerConnection,
+                 kDefaultMaxStreamsPerConnection) {}
+
+ protected:
+  QuicStreamId GetNthPeerInitiatedId(int n) {
+    if (GetParam().perspective == Perspective::IS_SERVER) {
+      return QuicUtils::GetFirstBidirectionalStreamId(
+                 GetParam().version.transport_version, Perspective::IS_CLIENT) +
+             2 * n;
+    } else {
+      return 2 + 2 * n;
+    }
+  }
+
+  LegacyQuicStreamIdManager manager_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         LegacyQuicStreamIdManagerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(LegacyQuicStreamIdManagerTest, CanOpenNextOutgoingStream) {
+  for (size_t i = 0; i < manager_.max_open_outgoing_streams() - 1; ++i) {
+    manager_.ActivateStream(/*is_incoming=*/false);
+  }
+  EXPECT_TRUE(manager_.CanOpenNextOutgoingStream());
+  manager_.ActivateStream(/*is_incoming=*/false);
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingStream());
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, CanOpenIncomingStream) {
+  for (size_t i = 0; i < manager_.max_open_incoming_streams() - 1; ++i) {
+    manager_.ActivateStream(/*is_incoming=*/true);
+  }
+  EXPECT_TRUE(manager_.CanOpenIncomingStream());
+  manager_.ActivateStream(/*is_incoming=*/true);
+  EXPECT_FALSE(manager_.CanOpenIncomingStream());
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, AvailableStreams) {
+  ASSERT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(3)));
+  EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(1)));
+  EXPECT_TRUE(manager_.IsAvailableStream(GetNthPeerInitiatedId(2)));
+  ASSERT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(2)));
+  ASSERT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(1)));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, MaxAvailableStreams) {
+  // Test that the server closes the connection if a client makes too many data
+  // streams available.  The server accepts slightly more than the negotiated
+  // stream limit to deal with rare cases where a client FIN/RST is lost.
+  const size_t kMaxStreamsForTest = 10;
+  const size_t kAvailableStreamLimit = manager_.MaxAvailableStreams();
+  EXPECT_EQ(
+      manager_.max_open_incoming_streams() * kMaxAvailableStreamsMultiplier,
+      manager_.MaxAvailableStreams());
+  // The protocol specification requires that there can be at least 10 times
+  // as many available streams as the connection's maximum open streams.
+  EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit);
+
+  EXPECT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(0)));
+
+  // Establish available streams up to the server's limit.
+  const int kLimitingStreamId =
+      GetNthPeerInitiatedId(kAvailableStreamLimit + 1);
+  // This exceeds the stream limit. In versions other than 99
+  // this is allowed. Version 99 hews to the IETF spec and does
+  // not allow it.
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId));
+
+  // This forces stream kLimitingStreamId + 2 to become available, which
+  // violates the quota.
+  EXPECT_FALSE(
+      manager_.MaybeIncreaseLargestPeerStreamId(kLimitingStreamId + 2 * 2));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, MaximumAvailableOpenedStreams) {
+  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      stream_id + 2 * (manager_.max_open_incoming_streams() - 1)));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, TooManyAvailableStreams) {
+  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+
+  // A stream ID which is too large to create.
+  QuicStreamId stream_id2 =
+      GetNthPeerInitiatedId(2 * manager_.MaxAvailableStreams() + 4);
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id2));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest, ManyAvailableStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  manager_.set_max_open_incoming_streams(200);
+  QuicStreamId stream_id = GetNthPeerInitiatedId(0);
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+
+  // Create the largest stream ID of a threatened total of 200 streams.
+  // GetNth... starts at 0, so for 200 streams, get the 199th.
+  EXPECT_TRUE(
+      manager_.MaybeIncreaseLargestPeerStreamId(GetNthPeerInitiatedId(199)));
+}
+
+TEST_P(LegacyQuicStreamIdManagerTest,
+       TestMaxIncomingAndOutgoingStreamsAllowed) {
+  EXPECT_EQ(manager_.max_open_incoming_streams(),
+            kDefaultMaxStreamsPerConnection);
+  EXPECT_EQ(manager_.max_open_outgoing_streams(),
+            kDefaultMaxStreamsPerConnection);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/packet_number_indexed_queue.h b/quiche/quic/core/packet_number_indexed_queue.h
new file mode 100644
index 0000000..ef48bd1
--- /dev/null
+++ b/quiche/quic/core/packet_number_indexed_queue.h
@@ -0,0 +1,252 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
+#define QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+// PacketNumberIndexedQueue is a queue of mostly continuous numbered entries
+// which supports the following operations:
+// - adding elements to the end of the queue, or at some point past the end
+// - removing elements in any order
+// - retrieving elements
+// If all elements are inserted in order, all of the operations above are
+// amortized O(1) time.
+//
+// Internally, the data structure is a deque where each element is marked as
+// present or not.  The deque starts at the lowest present index.  Whenever an
+// element is removed, it's marked as not present, and the front of the deque is
+// cleared of elements that are not present.
+//
+// The tail of the queue is not cleared due to the assumption of entries being
+// inserted in order, though removing all elements of the queue will return it
+// to its initial state.
+//
+// Note that this data structure is inherently hazardous, since an addition of
+// just two entries will cause it to consume all of the memory available.
+// Because of that, it is not a general-purpose container and should not be used
+// as one.
+// TODO(wub): Update the comments when deprecating
+// --quic_bw_sampler_remove_packets_once_per_congestion_event.
+template <typename T>
+class QUIC_NO_EXPORT PacketNumberIndexedQueue {
+ public:
+  PacketNumberIndexedQueue() : number_of_present_entries_(0) {}
+
+  // Retrieve the entry associated with the packet number.  Returns the pointer
+  // to the entry in case of success, or nullptr if the entry does not exist.
+  T* GetEntry(QuicPacketNumber packet_number);
+  const T* GetEntry(QuicPacketNumber packet_number) const;
+
+  // Inserts data associated |packet_number| into (or past) the end of the
+  // queue, filling up the missing intermediate entries as necessary.  Returns
+  // true if the element has been inserted successfully, false if it was already
+  // in the queue or inserted out of order.
+  template <typename... Args>
+  bool Emplace(QuicPacketNumber packet_number, Args&&... args);
+
+  // Removes data associated with |packet_number| and frees the slots in the
+  // queue as necessary.
+  bool Remove(QuicPacketNumber packet_number);
+
+  // Same as above, but if an entry is present in the queue, also call f(entry)
+  // before removing it.
+  template <typename Function>
+  bool Remove(QuicPacketNumber packet_number, Function f);
+
+  // Remove up to, but not including |packet_number|.
+  // Unused slots in the front are also removed, which means when the function
+  // returns, |first_packet()| can be larger than |packet_number|.
+  void RemoveUpTo(QuicPacketNumber packet_number);
+
+  bool IsEmpty() const { return number_of_present_entries_ == 0; }
+
+  // Returns the number of entries in the queue.
+  size_t number_of_present_entries() const {
+    return number_of_present_entries_;
+  }
+
+  // Returns the number of entries allocated in the underlying deque.  This is
+  // proportional to the memory usage of the queue.
+  size_t entry_slots_used() const { return entries_.size(); }
+
+  // Packet number of the first entry in the queue.
+  QuicPacketNumber first_packet() const { return first_packet_; }
+
+  // Packet number of the last entry ever inserted in the queue.  Note that the
+  // entry in question may have already been removed.  Zero if the queue is
+  // empty.
+  QuicPacketNumber last_packet() const {
+    if (IsEmpty()) {
+      return QuicPacketNumber();
+    }
+    return first_packet_ + entries_.size() - 1;
+  }
+
+ private:
+  // Wrapper around T used to mark whether the entry is actually in the map.
+  struct QUIC_NO_EXPORT EntryWrapper : T {
+    // NOTE(wub): When quic_bw_sampler_remove_packets_once_per_congestion_event
+    // is enabled, |present| is false if and only if this is a placeholder entry
+    // for holes in the parent's |entries|.
+    bool present;
+
+    EntryWrapper() : present(false) {}
+
+    template <typename... Args>
+    explicit EntryWrapper(Args&&... args)
+        : T(std::forward<Args>(args)...), present(true) {}
+  };
+
+  // Cleans up unused slots in the front after removing an element.
+  void Cleanup();
+
+  const EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) const;
+  EntryWrapper* GetEntryWrapper(QuicPacketNumber offset) {
+    const auto* const_this = this;
+    return const_cast<EntryWrapper*>(const_this->GetEntryWrapper(offset));
+  }
+
+  quiche::QuicheCircularDeque<EntryWrapper> entries_;
+  // NOTE(wub): When --quic_bw_sampler_remove_packets_once_per_congestion_event
+  // is enabled, |number_of_present_entries_| only represents number of holes,
+  // which does not include number of acked or lost packets.
+  size_t number_of_present_entries_;
+  QuicPacketNumber first_packet_;
+};
+
+template <typename T>
+T* PacketNumberIndexedQueue<T>::GetEntry(QuicPacketNumber packet_number) {
+  EntryWrapper* entry = GetEntryWrapper(packet_number);
+  if (entry == nullptr) {
+    return nullptr;
+  }
+  return entry;
+}
+
+template <typename T>
+const T* PacketNumberIndexedQueue<T>::GetEntry(
+    QuicPacketNumber packet_number) const {
+  const EntryWrapper* entry = GetEntryWrapper(packet_number);
+  if (entry == nullptr) {
+    return nullptr;
+  }
+  return entry;
+}
+
+template <typename T>
+template <typename... Args>
+bool PacketNumberIndexedQueue<T>::Emplace(QuicPacketNumber packet_number,
+                                          Args&&... args) {
+  if (!packet_number.IsInitialized()) {
+    QUIC_BUG(quic_bug_10359_1)
+        << "Try to insert an uninitialized packet number";
+    return false;
+  }
+
+  if (IsEmpty()) {
+    QUICHE_DCHECK(entries_.empty());
+    QUICHE_DCHECK(!first_packet_.IsInitialized());
+
+    entries_.emplace_back(std::forward<Args>(args)...);
+    number_of_present_entries_ = 1;
+    first_packet_ = packet_number;
+    return true;
+  }
+
+  // Do not allow insertion out-of-order.
+  if (packet_number <= last_packet()) {
+    return false;
+  }
+
+  // Handle potentially missing elements.
+  size_t offset = packet_number - first_packet_;
+  if (offset > entries_.size()) {
+    entries_.resize(offset);
+  }
+
+  number_of_present_entries_++;
+  entries_.emplace_back(std::forward<Args>(args)...);
+  QUICHE_DCHECK_EQ(packet_number, last_packet());
+  return true;
+}
+
+template <typename T>
+bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number) {
+  return Remove(packet_number, [](const T&) {});
+}
+
+template <typename T>
+template <typename Function>
+bool PacketNumberIndexedQueue<T>::Remove(QuicPacketNumber packet_number,
+                                         Function f) {
+  EntryWrapper* entry = GetEntryWrapper(packet_number);
+  if (entry == nullptr) {
+    return false;
+  }
+  f(*static_cast<const T*>(entry));
+  entry->present = false;
+  number_of_present_entries_--;
+
+  if (packet_number == first_packet()) {
+    Cleanup();
+  }
+  return true;
+}
+
+template <typename T>
+void PacketNumberIndexedQueue<T>::RemoveUpTo(QuicPacketNumber packet_number) {
+  while (!entries_.empty() && first_packet_.IsInitialized() &&
+         first_packet_ < packet_number) {
+    if (entries_.front().present) {
+      number_of_present_entries_--;
+    }
+    entries_.pop_front();
+    first_packet_++;
+  }
+  Cleanup();
+}
+
+template <typename T>
+void PacketNumberIndexedQueue<T>::Cleanup() {
+  while (!entries_.empty() && !entries_.front().present) {
+    entries_.pop_front();
+    first_packet_++;
+  }
+  if (entries_.empty()) {
+    first_packet_.Clear();
+  }
+}
+
+template <typename T>
+auto PacketNumberIndexedQueue<T>::GetEntryWrapper(
+    QuicPacketNumber packet_number) const -> const EntryWrapper* {
+  if (!packet_number.IsInitialized() || IsEmpty() ||
+      packet_number < first_packet_) {
+    return nullptr;
+  }
+
+  uint64_t offset = packet_number - first_packet_;
+  if (offset >= entries_.size()) {
+    return nullptr;
+  }
+
+  const EntryWrapper* entry = &entries_[offset];
+  if (!entry->present) {
+    return nullptr;
+  }
+
+  return entry;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_PACKET_NUMBER_INDEXED_QUEUE_H_
diff --git a/quiche/quic/core/packet_number_indexed_queue_test.cc b/quiche/quic/core/packet_number_indexed_queue_test.cc
new file mode 100644
index 0000000..b8a5b2a
--- /dev/null
+++ b/quiche/quic/core/packet_number_indexed_queue_test.cc
@@ -0,0 +1,205 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/packet_number_indexed_queue.h"
+
+#include <limits>
+#include <map>
+#include <string>
+
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+class PacketNumberIndexedQueueTest : public QuicTest {
+ public:
+  PacketNumberIndexedQueueTest() {}
+
+ protected:
+  PacketNumberIndexedQueue<std::string> queue_;
+};
+
+TEST_F(PacketNumberIndexedQueueTest, InitialState) {
+  EXPECT_TRUE(queue_.IsEmpty());
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_FALSE(queue_.last_packet().IsInitialized());
+  EXPECT_EQ(0u, queue_.number_of_present_entries());
+  EXPECT_EQ(0u, queue_.entry_slots_used());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingContinuousElements) {
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1001), "one"));
+  EXPECT_EQ("one", *queue_.GetEntry(QuicPacketNumber(1001)));
+
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+  EXPECT_EQ("two", *queue_.GetEntry(QuicPacketNumber(1002)));
+
+  EXPECT_FALSE(queue_.IsEmpty());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1002u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(2u, queue_.entry_slots_used());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingOutOfOrder) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1003), "three"));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
+  EXPECT_EQ("three", *queue_.GetEntry(QuicPacketNumber(1003)));
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(3u, queue_.entry_slots_used());
+
+  ASSERT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingIntoPast) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1000), "zero"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, InsertingDuplicate) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1001), "one"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveInTheMiddle) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "two");
+  queue_.Emplace(QuicPacketNumber(1003), "three");
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(3u, queue_.entry_slots_used());
+
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveAtImmediateEdges) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "two");
+  queue_.Emplace(QuicPacketNumber(1003), "three");
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1001)));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1003)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1003)));
+
+  EXPECT_EQ(QuicPacketNumber(1002u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+  EXPECT_EQ(2u, queue_.entry_slots_used());
+
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantFront) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "one (kinda)");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+  EXPECT_EQ(3u, queue_.number_of_present_entries());
+  EXPECT_EQ(1001u, queue_.entry_slots_used());
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+  EXPECT_EQ(1001u, queue_.entry_slots_used());
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+  EXPECT_EQ(1u, queue_.entry_slots_used());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantBack) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, ClearAndRepopulate) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
+  EXPECT_TRUE(queue_.IsEmpty());
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_FALSE(queue_.last_packet().IsInitialized());
+
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(101), "one"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(201), "two"));
+  EXPECT_EQ(QuicPacketNumber(101u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(201u), queue_.last_packet());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsThatNeverExisted) {
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1002)));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsTwice) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
+}
+
+TEST_F(PacketNumberIndexedQueueTest, RemoveUpTo) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+
+  queue_.RemoveUpTo(QuicPacketNumber(1001));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(2u, queue_.number_of_present_entries());
+
+  // Remove up to 1100, since [1100, 2001) are !present, they should be cleaned
+  // up from the front.
+  queue_.RemoveUpTo(QuicPacketNumber(1100));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+
+  queue_.RemoveUpTo(QuicPacketNumber(2001));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(1u, queue_.number_of_present_entries());
+
+  queue_.RemoveUpTo(QuicPacketNumber(2002));
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_EQ(0u, queue_.number_of_present_entries());
+}
+
+TEST_F(PacketNumberIndexedQueueTest, ConstGetter) {
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  const auto& const_queue = queue_;
+
+  EXPECT_EQ("one", *const_queue.GetEntry(QuicPacketNumber(1001)));
+  EXPECT_EQ(nullptr, const_queue.GetEntry(QuicPacketNumber(1002)));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quic/core/proto/cached_network_parameters.proto b/quiche/quic/core/proto/cached_network_parameters.proto
similarity index 100%
rename from quic/core/proto/cached_network_parameters.proto
rename to quiche/quic/core/proto/cached_network_parameters.proto
diff --git a/quiche/quic/core/proto/cached_network_parameters_proto.h b/quiche/quic/core/proto/cached_network_parameters_proto.h
new file mode 100644
index 0000000..90c9156
--- /dev/null
+++ b/quiche/quic/core/proto/cached_network_parameters_proto.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
+#define QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "quiche/quic/core/proto/cached_network_parameters.pb.h"
+
+#pragma clang diagnostic pop
+
+#endif  // QUICHE_QUIC_CORE_PROTO_CACHED_NETWORK_PARAMETERS_PROTO_H_
diff --git a/quic/core/proto/crypto_server_config.proto b/quiche/quic/core/proto/crypto_server_config.proto
similarity index 100%
rename from quic/core/proto/crypto_server_config.proto
rename to quiche/quic/core/proto/crypto_server_config.proto
diff --git a/quiche/quic/core/proto/crypto_server_config_proto.h b/quiche/quic/core/proto/crypto_server_config_proto.h
new file mode 100644
index 0000000..5d50ff8
--- /dev/null
+++ b/quiche/quic/core/proto/crypto_server_config_proto.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
+#define QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "quiche/quic/core/proto/crypto_server_config.pb.h"
+
+#pragma clang diagnostic pop
+
+#endif  // QUICHE_QUIC_CORE_PROTO_CRYPTO_SERVER_CONFIG_PROTO_H_
diff --git a/quiche/quic/core/proto/source_address_token.proto b/quiche/quic/core/proto/source_address_token.proto
new file mode 100644
index 0000000..d261d46
--- /dev/null
+++ b/quiche/quic/core/proto/source_address_token.proto
@@ -0,0 +1,32 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+import "quiche/quic/core/proto/cached_network_parameters.proto";
+
+package quic;
+
+// A SourceAddressToken is serialised, encrypted and sent to clients so that
+// they can prove ownership of an IP address.
+message SourceAddressToken {
+  // ip contains either 4 (IPv4) or 16 (IPv6) bytes of IP address in network
+  // byte order.
+  required bytes ip = 1;
+  // timestamp contains a UNIX timestamp value of the time when the token was
+  // created.
+  required int64 timestamp = 2;
+  // The server can provide estimated network parameters to be used for
+  // initial parameter selection in future connections.
+  optional CachedNetworkParameters cached_network_parameters = 3;
+};
+
+// SourceAddressTokens are simply lists of SourceAddressToken messages.
+message SourceAddressTokens {
+  // This field has id 4 to avoid ambiguity between the serialized form of
+  // SourceAddressToken vs SourceAddressTokens.
+  repeated SourceAddressToken tokens = 4;
+};
diff --git a/quiche/quic/core/proto/source_address_token_proto.h b/quiche/quic/core/proto/source_address_token_proto.h
new file mode 100644
index 0000000..3144ca1
--- /dev/null
+++ b/quiche/quic/core/proto/source_address_token_proto.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
+#define QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "quiche/quic/core/proto/source_address_token.pb.h"
+
+#pragma clang diagnostic pop
+
+#endif  // QUICHE_QUIC_CORE_PROTO_SOURCE_ADDRESS_TOKEN_PROTO_H_
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
new file mode 100644
index 0000000..93ce0a9
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_decoder_fuzzer.cc
@@ -0,0 +1,191 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+namespace quic {
+namespace test {
+
+struct DecoderAndHandler {
+  std::unique_ptr<QpackProgressiveDecoder> decoder;
+  std::unique_ptr<QpackProgressiveDecoder::HeadersHandlerInterface> handler;
+};
+
+using DecoderAndHandlerMap = std::map<QuicStreamId, DecoderAndHandler>;
+
+// Class that sets externally owned |error_detected| to true
+// on encoder stream error.
+class ErrorDelegate : public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  ErrorDelegate(bool* error_detected) : error_detected_(error_detected) {}
+  ~ErrorDelegate() override = default;
+
+  void OnEncoderStreamError(QuicErrorCode /*error_code*/,
+                            absl::string_view /*error_message*/) override {
+    *error_detected_ = true;
+  }
+
+ private:
+  bool* const error_detected_;
+};
+
+// Class that destroys DecoderAndHandler when decoding completes, and sets
+// externally owned |error_detected| to true on encoder stream error.
+class HeadersHandler : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  HeadersHandler(QuicStreamId stream_id,
+                 DecoderAndHandlerMap* processing_decoders,
+                 bool* error_detected)
+      : stream_id_(stream_id),
+        processing_decoders_(processing_decoders),
+        error_detected_(error_detected) {}
+  ~HeadersHandler() override = default;
+
+  void OnHeaderDecoded(absl::string_view /*name*/,
+                       absl::string_view /*value*/) override {}
+
+  // Remove DecoderAndHandler from |*processing_decoders|.
+  void OnDecodingCompleted() override {
+    // Will delete |this|.
+    size_t result = processing_decoders_->erase(stream_id_);
+    QUICHE_CHECK_EQ(1u, result);
+  }
+
+  void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
+                               absl::string_view /*error_message*/) override {
+    *error_detected_ = true;
+  }
+
+ private:
+  const QuicStreamId stream_id_;
+  DecoderAndHandlerMap* const processing_decoders_;
+  bool* const error_detected_;
+};
+
+// This fuzzer exercises QpackDecoder.  It should be able to cover all possible
+// code paths.  There is no point in encoding QpackDecoder's output to turn this
+// into a roundtrip test, because the same header list can be encoded in many
+// different ways, so the output could not be expected to match the original
+// input.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider provider(data, size);
+
+  // Maximum 256 byte dynamic table.  Such a small size helps test draining
+  // entries and eviction.
+  const uint64_t maximum_dynamic_table_capacity =
+      provider.ConsumeIntegral<uint8_t>();
+  // Maximum 256 blocked streams.
+  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();
+
+  // |error_detected| will be set to true if an error is encountered either in a
+  // header block or on the encoder stream.
+  bool error_detected = false;
+
+  ErrorDelegate encoder_stream_error_delegate(&error_detected);
+  QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
+                       &encoder_stream_error_delegate);
+
+  NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
+  decoder.set_qpack_stream_sender_delegate(&decoder_stream_sender_delegate);
+
+  // Decoders still reading the header block, with corresponding handlers.
+  DecoderAndHandlerMap reading_decoders;
+
+  // Decoders still processing the completely read header block,
+  // with corresponding handlers.
+  DecoderAndHandlerMap processing_decoders;
+
+  // Maximum 256 data fragments to limit runtime and memory usage.
+  auto fragment_count = provider.ConsumeIntegral<uint8_t>();
+  while (fragment_count > 0 && !error_detected &&
+         provider.remaining_bytes() > 0) {
+    --fragment_count;
+    switch (provider.ConsumeIntegralInRange<uint8_t>(0, 3)) {
+      // Feed encoder stream data to QpackDecoder.
+      case 0: {
+        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
+        std::string data = provider.ConsumeRandomLengthString(fragment_size);
+        decoder.encoder_stream_receiver()->Decode(data);
+
+        continue;
+      }
+
+      // Create new progressive decoder.
+      case 1: {
+        QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
+        if (reading_decoders.find(stream_id) != reading_decoders.end() ||
+            processing_decoders.find(stream_id) != processing_decoders.end()) {
+          continue;
+        }
+
+        DecoderAndHandler decoder_and_handler;
+        decoder_and_handler.handler = std::make_unique<HeadersHandler>(
+            stream_id, &processing_decoders, &error_detected);
+        decoder_and_handler.decoder = decoder.CreateProgressiveDecoder(
+            stream_id, decoder_and_handler.handler.get());
+        reading_decoders.insert({stream_id, std::move(decoder_and_handler)});
+
+        continue;
+      }
+
+      // Feed header block data to existing decoder.
+      case 2: {
+        if (reading_decoders.empty()) {
+          continue;
+        }
+
+        auto it = reading_decoders.begin();
+        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
+            0, reading_decoders.size() - 1);
+        std::advance(it, distance);
+
+        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
+        std::string data = provider.ConsumeRandomLengthString(fragment_size);
+        it->second.decoder->Decode(data);
+
+        continue;
+      }
+
+      // End header block.
+      case 3: {
+        if (reading_decoders.empty()) {
+          continue;
+        }
+
+        auto it = reading_decoders.begin();
+        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
+            0, reading_decoders.size() - 1);
+        std::advance(it, distance);
+
+        QpackProgressiveDecoder* decoder = it->second.decoder.get();
+
+        // Move DecoderAndHandler to |reading_decoders| first, because
+        // EndHeaderBlock() might synchronously call OnDecodingCompleted().
+        QuicStreamId stream_id = it->first;
+        processing_decoders.insert({stream_id, std::move(it->second)});
+        reading_decoders.erase(it);
+
+        decoder->EndHeaderBlock();
+
+        continue;
+      }
+    }
+  }
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc
new file mode 100644
index 0000000..7d8542e
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_receiver_fuzzer.cc
@@ -0,0 +1,62 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// A QpackDecoderStreamReceiver::Delegate implementation that ignores all
+// decoded instructions but keeps track of whether an error has been detected.
+class NoOpDelegate : public QpackDecoderStreamReceiver::Delegate {
+ public:
+  NoOpDelegate() : error_detected_(false) {}
+  ~NoOpDelegate() override = default;
+
+  void OnInsertCountIncrement(uint64_t /*increment*/) override {}
+  void OnHeaderAcknowledgement(QuicStreamId /*stream_id*/) override {}
+  void OnStreamCancellation(QuicStreamId /*stream_id*/) override {}
+  void OnErrorDetected(QuicErrorCode /*error_code*/,
+                       absl::string_view /*error_message*/) override {
+    error_detected_ = true;
+  }
+
+  bool error_detected() const { return error_detected_; }
+
+ private:
+  bool error_detected_;
+};
+
+}  // namespace
+
+// This fuzzer exercises QpackDecoderStreamReceiver.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoOpDelegate delegate;
+  QpackDecoderStreamReceiver receiver(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+
+  while (!delegate.error_detected() && provider.remaining_bytes() != 0) {
+    // Process up to 64 kB fragments at a time.  Too small upper bound might not
+    // provide enough coverage, too large might make fuzzing too inefficient.
+    size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>(
+        0, std::numeric_limits<uint16_t>::max());
+    receiver.Decode(provider.ConsumeRandomLengthString(fragment_size));
+  }
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc
new file mode 100644
index 0000000..57fe718
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_decoder_stream_sender_fuzzer.cc
@@ -0,0 +1,54 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// This fuzzer exercises QpackDecoderStreamSender.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoopQpackStreamSenderDelegate delegate;
+  QpackDecoderStreamSender sender;
+  sender.set_qpack_stream_sender_delegate(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+
+  while (provider.remaining_bytes() != 0) {
+    switch (provider.ConsumeIntegral<uint8_t>() % 4) {
+      case 0: {
+        uint64_t increment = provider.ConsumeIntegral<uint64_t>();
+        sender.SendInsertCountIncrement(increment);
+        break;
+      }
+      case 1: {
+        QuicStreamId stream_id = provider.ConsumeIntegral<QuicStreamId>();
+        sender.SendHeaderAcknowledgement(stream_id);
+        break;
+      }
+      case 2: {
+        QuicStreamId stream_id = provider.ConsumeIntegral<QuicStreamId>();
+        sender.SendStreamCancellation(stream_id);
+        break;
+      }
+      case 3: {
+        sender.Flush();
+        break;
+      }
+    }
+  }
+
+  sender.Flush();
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc
new file mode 100644
index 0000000..8030bb9
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_receiver_fuzzer.cc
@@ -0,0 +1,68 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// A QpackEncoderStreamReceiver::Delegate implementation that ignores all
+// decoded instructions but keeps track of whether an error has been detected.
+class NoOpDelegate : public QpackEncoderStreamReceiver::Delegate {
+ public:
+  NoOpDelegate() : error_detected_(false) {}
+  ~NoOpDelegate() override = default;
+
+  void OnInsertWithNameReference(bool /*is_static*/,
+                                 uint64_t /*name_index*/,
+                                 absl::string_view /*value*/) override {}
+  void OnInsertWithoutNameReference(absl::string_view /*name*/,
+                                    absl::string_view /*value*/) override {}
+  void OnDuplicate(uint64_t /*index*/) override {}
+  void OnSetDynamicTableCapacity(uint64_t /*capacity*/) override {}
+  void OnErrorDetected(QuicErrorCode /*error_code*/,
+                       absl::string_view /*error_message*/) override {
+    error_detected_ = true;
+  }
+
+  bool error_detected() const { return error_detected_; }
+
+ private:
+  bool error_detected_;
+};
+
+}  // namespace
+
+// This fuzzer exercises QpackEncoderStreamReceiver.
+// Note that since string literals may be encoded with or without Huffman
+// encoding, one could not expect identical encoded data if the decoded
+// instructions were fed into QpackEncoderStreamSender.  Therefore there is no
+// point in extending this fuzzer into a round-trip test.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoOpDelegate delegate;
+  QpackEncoderStreamReceiver receiver(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+
+  while (!delegate.error_detected() && provider.remaining_bytes() != 0) {
+    // Process up to 64 kB fragments at a time.  Too small upper bound might not
+    // provide enough coverage, too large might make fuzzing too inefficient.
+    size_t fragment_size = provider.ConsumeIntegralInRange<uint16_t>(
+        0, std::numeric_limits<uint16_t>::max());
+    receiver.Decode(provider.ConsumeRandomLengthString(fragment_size));
+  }
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
new file mode 100644
index 0000000..bc68536
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
@@ -0,0 +1,73 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <string>
+
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// This fuzzer exercises QpackEncoderStreamSender.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  NoopQpackStreamSenderDelegate delegate;
+  QpackEncoderStreamSender sender;
+  sender.set_qpack_stream_sender_delegate(&delegate);
+
+  FuzzedDataProvider provider(data, size);
+  // Limit string literal length to 2 kB for efficiency.
+  const uint16_t kMaxStringLength = 2048;
+
+  while (provider.remaining_bytes() != 0) {
+    switch (provider.ConsumeIntegral<uint8_t>() % 5) {
+      case 0: {
+        bool is_static = provider.ConsumeBool();
+        uint64_t name_index = provider.ConsumeIntegral<uint64_t>();
+        uint16_t value_length =
+            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
+        std::string value = provider.ConsumeRandomLengthString(value_length);
+
+        sender.SendInsertWithNameReference(is_static, name_index, value);
+        break;
+      }
+      case 1: {
+        uint16_t name_length =
+            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
+        std::string name = provider.ConsumeRandomLengthString(name_length);
+        uint16_t value_length =
+            provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
+        std::string value = provider.ConsumeRandomLengthString(value_length);
+        sender.SendInsertWithoutNameReference(name, value);
+        break;
+      }
+      case 2: {
+        uint64_t index = provider.ConsumeIntegral<uint64_t>();
+        sender.SendDuplicate(index);
+        break;
+      }
+      case 3: {
+        uint64_t capacity = provider.ConsumeIntegral<uint64_t>();
+        sender.SendSetDynamicTableCapacity(capacity);
+        break;
+      }
+      case 4: {
+        sender.Flush();
+        break;
+      }
+    }
+  }
+
+  sender.Flush();
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc b/quiche/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
new file mode 100644
index 0000000..2d7cd88
--- /dev/null
+++ b/quiche/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
@@ -0,0 +1,665 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/qpack/value_splitting_header_list.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Find the first occurrence of invalid characters NUL, LF, CR in |*value| and
+// remove that and the remaining of the string.
+void TruncateValueOnInvalidChars(std::string* value) {
+  for (auto it = value->begin(); it != value->end(); ++it) {
+    if (*it == '\0' || *it == '\n' || *it == '\r') {
+      value->erase(it, value->end());
+      return;
+    }
+  }
+}
+
+}  // anonymous namespace
+
+// Class to hold QpackEncoder and its DecoderStreamErrorDelegate.
+class EncodingEndpoint {
+ public:
+  EncodingEndpoint(uint64_t maximum_dynamic_table_capacity,
+                   uint64_t maximum_blocked_streams)
+      : encoder_(&decoder_stream_error_delegate) {
+    encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+    encoder_.SetMaximumBlockedStreams(maximum_blocked_streams);
+  }
+
+  ~EncodingEndpoint() {
+    // Every reference should be acknowledged.
+    QUICHE_CHECK_EQ(std::numeric_limits<uint64_t>::max(),
+                    QpackEncoderPeer::smallest_blocking_index(&encoder_));
+  }
+
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    encoder_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  void SetDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity) {
+    encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
+  }
+
+  QpackStreamReceiver* decoder_stream_receiver() {
+    return encoder_.decoder_stream_receiver();
+  }
+
+  std::string EncodeHeaderList(QuicStreamId stream_id,
+                               const spdy::Http2HeaderBlock& header_list) {
+    return encoder_.EncodeHeaderList(stream_id, header_list, nullptr);
+  }
+
+ private:
+  // DecoderStreamErrorDelegate implementation that crashes on error.
+  class CrashingDecoderStreamErrorDelegate
+      : public QpackEncoder::DecoderStreamErrorDelegate {
+   public:
+    ~CrashingDecoderStreamErrorDelegate() override = default;
+
+    void OnDecoderStreamError(QuicErrorCode error_code,
+                              absl::string_view error_message) override {
+      QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
+                          << error_message;
+    }
+  };
+
+  CrashingDecoderStreamErrorDelegate decoder_stream_error_delegate;
+  QpackEncoder encoder_;
+};
+
+// Class that receives all header blocks from the encoding endpoint and passes
+// them to the decoding endpoint, with delay determined by fuzzer data,
+// preserving order within each stream but not among streams.
+class DelayedHeaderBlockTransmitter {
+ public:
+  class Visitor {
+   public:
+    virtual ~Visitor() = default;
+
+    // If decoding of the previous header block is still in progress, then
+    // DelayedHeaderBlockTransmitter will not start transmitting the next header
+    // block.
+    virtual bool IsDecodingInProgressOnStream(QuicStreamId stream_id) = 0;
+
+    // Called when a header block starts.
+    virtual void OnHeaderBlockStart(QuicStreamId stream_id) = 0;
+    // Called when part or all of a header block is transmitted.
+    virtual void OnHeaderBlockFragment(QuicStreamId stream_id,
+                                       absl::string_view data) = 0;
+    // Called when transmission of a header block is complete.
+    virtual void OnHeaderBlockEnd(QuicStreamId stream_id) = 0;
+  };
+
+  DelayedHeaderBlockTransmitter(Visitor* visitor, FuzzedDataProvider* provider)
+      : visitor_(visitor), provider_(provider) {}
+
+  ~DelayedHeaderBlockTransmitter() { QUICHE_CHECK(header_blocks_.empty()); }
+
+  // Enqueues |encoded_header_block| for delayed transmission.
+  void SendEncodedHeaderBlock(QuicStreamId stream_id,
+                              std::string encoded_header_block) {
+    auto it = header_blocks_.lower_bound(stream_id);
+    if (it == header_blocks_.end() || it->first != stream_id) {
+      it = header_blocks_.insert(it, {stream_id, {}});
+    }
+    QUICHE_CHECK_EQ(stream_id, it->first);
+    it->second.push(HeaderBlock(std::move(encoded_header_block)));
+  }
+
+  // Release some (possibly none) header block data.
+  void MaybeTransmitSomeData() {
+    if (header_blocks_.empty()) {
+      return;
+    }
+
+    auto index =
+        provider_->ConsumeIntegralInRange<size_t>(0, header_blocks_.size() - 1);
+    auto it = header_blocks_.begin();
+    std::advance(it, index);
+    const QuicStreamId stream_id = it->first;
+
+    // Do not start new header block if processing of previous header block is
+    // blocked.
+    if (visitor_->IsDecodingInProgressOnStream(stream_id)) {
+      return;
+    }
+
+    auto& header_block_queue = it->second;
+    HeaderBlock& header_block = header_block_queue.front();
+
+    if (header_block.ConsumedLength() == 0) {
+      visitor_->OnHeaderBlockStart(stream_id);
+    }
+
+    QUICHE_DCHECK_NE(0u, header_block.RemainingLength());
+
+    size_t length = provider_->ConsumeIntegralInRange<size_t>(
+        1, header_block.RemainingLength());
+    visitor_->OnHeaderBlockFragment(stream_id, header_block.Consume(length));
+
+    QUICHE_DCHECK_NE(0u, header_block.ConsumedLength());
+
+    if (header_block.RemainingLength() == 0) {
+      visitor_->OnHeaderBlockEnd(stream_id);
+
+      header_block_queue.pop();
+      if (header_block_queue.empty()) {
+        header_blocks_.erase(it);
+      }
+    }
+  }
+
+  // Release all header block data.  Must be called before destruction.  All
+  // encoder stream data must have been released before calling Flush() so that
+  // all header blocks can be decoded synchronously.
+  void Flush() {
+    while (!header_blocks_.empty()) {
+      auto it = header_blocks_.begin();
+      const QuicStreamId stream_id = it->first;
+
+      auto& header_block_queue = it->second;
+      HeaderBlock& header_block = header_block_queue.front();
+
+      if (header_block.ConsumedLength() == 0) {
+        QUICHE_CHECK(!visitor_->IsDecodingInProgressOnStream(stream_id));
+        visitor_->OnHeaderBlockStart(stream_id);
+      }
+
+      QUICHE_DCHECK_NE(0u, header_block.RemainingLength());
+
+      visitor_->OnHeaderBlockFragment(stream_id,
+                                      header_block.ConsumeRemaining());
+
+      QUICHE_DCHECK_NE(0u, header_block.ConsumedLength());
+      QUICHE_DCHECK_EQ(0u, header_block.RemainingLength());
+
+      visitor_->OnHeaderBlockEnd(stream_id);
+      QUICHE_CHECK(!visitor_->IsDecodingInProgressOnStream(stream_id));
+
+      header_block_queue.pop();
+      if (header_block_queue.empty()) {
+        header_blocks_.erase(it);
+      }
+    }
+  }
+
+ private:
+  // Helper class that allows the header block to be consumed in parts.
+  class HeaderBlock {
+   public:
+    explicit HeaderBlock(std::string data)
+        : data_(std::move(data)), offset_(0) {
+      // Valid QPACK header block cannot be empty.
+      QUICHE_DCHECK(!data_.empty());
+    }
+
+    size_t ConsumedLength() const { return offset_; }
+
+    size_t RemainingLength() const { return data_.length() - offset_; }
+
+    absl::string_view Consume(size_t length) {
+      QUICHE_DCHECK_NE(0u, length);
+      QUICHE_DCHECK_LE(length, RemainingLength());
+
+      absl::string_view consumed = absl::string_view(&data_[offset_], length);
+      offset_ += length;
+      return consumed;
+    }
+
+    absl::string_view ConsumeRemaining() { return Consume(RemainingLength()); }
+
+   private:
+    // Complete header block.
+    const std::string data_;
+
+    // Offset of the part not consumed yet.  Same as number of consumed bytes.
+    size_t offset_;
+  };
+
+  Visitor* const visitor_;
+  FuzzedDataProvider* const provider_;
+
+  std::map<QuicStreamId, std::queue<HeaderBlock>> header_blocks_;
+};
+
+// Class to decode and verify a header block, and in case of blocked decoding,
+// keep necessary decoding context while waiting for decoding to complete.
+class VerifyingDecoder : public QpackDecodedHeadersAccumulator::Visitor {
+ public:
+  class Visitor {
+   public:
+    virtual ~Visitor() = default;
+
+    // Called when header block is decoded, either synchronously or
+    // asynchronously.  Might destroy VerifyingDecoder.
+    virtual void OnHeaderBlockDecoded(QuicStreamId stream_id) = 0;
+  };
+
+  VerifyingDecoder(QuicStreamId stream_id,
+                   Visitor* visitor,
+                   QpackDecoder* qpack_decoder,
+                   QuicHeaderList expected_header_list)
+      : stream_id_(stream_id),
+        visitor_(visitor),
+        accumulator_(
+            stream_id,
+            qpack_decoder,
+            this,
+            /* max_header_list_size = */ std::numeric_limits<size_t>::max()),
+        expected_header_list_(std::move(expected_header_list)) {}
+
+  VerifyingDecoder(const VerifyingDecoder&) = delete;
+  VerifyingDecoder& operator=(const VerifyingDecoder&) = delete;
+  // VerifyingDecoder must not be moved because it passes |this| to
+  // |accumulator_| upon construction.
+  VerifyingDecoder(VerifyingDecoder&&) = delete;
+  VerifyingDecoder& operator=(VerifyingDecoder&&) = delete;
+
+  virtual ~VerifyingDecoder() = default;
+
+  // QpackDecodedHeadersAccumulator::Visitor implementation.
+  void OnHeadersDecoded(QuicHeaderList headers,
+                        bool header_list_size_limit_exceeded) override {
+    // Verify headers.
+    QUICHE_CHECK(!header_list_size_limit_exceeded);
+    QUICHE_CHECK(expected_header_list_ == headers);
+
+    // Might destroy |this|.
+    visitor_->OnHeaderBlockDecoded(stream_id_);
+  }
+
+  void OnHeaderDecodingError(QuicErrorCode error_code,
+                             absl::string_view error_message) override {
+    QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
+                        << error_message;
+  }
+
+  void Decode(absl::string_view data) { accumulator_.Decode(data); }
+
+  void EndHeaderBlock() { accumulator_.EndHeaderBlock(); }
+
+ private:
+  QuicStreamId stream_id_;
+  Visitor* const visitor_;
+  QpackDecodedHeadersAccumulator accumulator_;
+  QuicHeaderList expected_header_list_;
+};
+
+// Class that holds QpackDecoder and its EncoderStreamErrorDelegate, and creates
+// and keeps VerifyingDecoders for each received header block until decoding is
+// complete.
+class DecodingEndpoint : public DelayedHeaderBlockTransmitter::Visitor,
+                         public VerifyingDecoder::Visitor {
+ public:
+  DecodingEndpoint(uint64_t maximum_dynamic_table_capacity,
+                   uint64_t maximum_blocked_streams)
+      : decoder_(maximum_dynamic_table_capacity,
+                 maximum_blocked_streams,
+                 &encoder_stream_error_delegate_) {}
+
+  ~DecodingEndpoint() override {
+    // All decoding must have been completed.
+    QUICHE_CHECK(expected_header_lists_.empty());
+    QUICHE_CHECK(verifying_decoders_.empty());
+  }
+
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    decoder_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  QpackStreamReceiver* encoder_stream_receiver() {
+    return decoder_.encoder_stream_receiver();
+  }
+
+  void AddExpectedHeaderList(QuicStreamId stream_id,
+                             QuicHeaderList expected_header_list) {
+    auto it = expected_header_lists_.lower_bound(stream_id);
+    if (it == expected_header_lists_.end() || it->first != stream_id) {
+      it = expected_header_lists_.insert(it, {stream_id, {}});
+    }
+    QUICHE_CHECK_EQ(stream_id, it->first);
+    it->second.push(std::move(expected_header_list));
+  }
+
+  // VerifyingDecoder::Visitor implementation.
+  void OnHeaderBlockDecoded(QuicStreamId stream_id) override {
+    auto result = verifying_decoders_.erase(stream_id);
+    QUICHE_CHECK_EQ(1u, result);
+  }
+
+  // DelayedHeaderBlockTransmitter::Visitor implementation.
+  bool IsDecodingInProgressOnStream(QuicStreamId stream_id) override {
+    return verifying_decoders_.find(stream_id) != verifying_decoders_.end();
+  }
+
+  void OnHeaderBlockStart(QuicStreamId stream_id) override {
+    QUICHE_CHECK(!IsDecodingInProgressOnStream(stream_id));
+    auto it = expected_header_lists_.find(stream_id);
+    QUICHE_CHECK(it != expected_header_lists_.end());
+
+    auto& header_list_queue = it->second;
+    QuicHeaderList expected_header_list = std::move(header_list_queue.front());
+
+    header_list_queue.pop();
+    if (header_list_queue.empty()) {
+      expected_header_lists_.erase(it);
+    }
+
+    auto verifying_decoder = std::make_unique<VerifyingDecoder>(
+        stream_id, this, &decoder_, std::move(expected_header_list));
+    auto result =
+        verifying_decoders_.insert({stream_id, std::move(verifying_decoder)});
+    QUICHE_CHECK(result.second);
+  }
+
+  void OnHeaderBlockFragment(QuicStreamId stream_id,
+                             absl::string_view data) override {
+    auto it = verifying_decoders_.find(stream_id);
+    QUICHE_CHECK(it != verifying_decoders_.end());
+    it->second->Decode(data);
+  }
+
+  void OnHeaderBlockEnd(QuicStreamId stream_id) override {
+    auto it = verifying_decoders_.find(stream_id);
+    QUICHE_CHECK(it != verifying_decoders_.end());
+    it->second->EndHeaderBlock();
+  }
+
+ private:
+  // EncoderStreamErrorDelegate implementation that crashes on error.
+  class CrashingEncoderStreamErrorDelegate
+      : public QpackDecoder::EncoderStreamErrorDelegate {
+   public:
+    ~CrashingEncoderStreamErrorDelegate() override = default;
+
+    void OnEncoderStreamError(QuicErrorCode error_code,
+                              absl::string_view error_message) override {
+      QUICHE_CHECK(false) << QuicErrorCodeToString(error_code) << " "
+                          << error_message;
+    }
+  };
+
+  CrashingEncoderStreamErrorDelegate encoder_stream_error_delegate_;
+  QpackDecoder decoder_;
+
+  // Expected header lists in order for each stream.
+  std::map<QuicStreamId, std::queue<QuicHeaderList>> expected_header_lists_;
+
+  // A VerifyingDecoder object keeps context necessary for asynchronously
+  // decoding blocked header blocks.  It is destroyed as soon as it signals that
+  // decoding is completed, which might happen synchronously within an
+  // EndHeaderBlock() call.
+  std::map<QuicStreamId, std::unique_ptr<VerifyingDecoder>> verifying_decoders_;
+};
+
+// Class that receives encoder stream data from the encoder and passes it to the
+// decoder, or receives decoder stream data from the decoder and passes it to
+// the encoder, with delay determined by fuzzer data.
+class DelayedStreamDataTransmitter : public QpackStreamSenderDelegate {
+ public:
+  DelayedStreamDataTransmitter(QpackStreamReceiver* receiver,
+                               FuzzedDataProvider* provider)
+      : receiver_(receiver), provider_(provider) {}
+
+  ~DelayedStreamDataTransmitter() { QUICHE_CHECK(stream_data.empty()); }
+
+  // QpackStreamSenderDelegate implementation.
+  void WriteStreamData(absl::string_view data) override {
+    stream_data.push_back(std::string(data.data(), data.size()));
+  }
+  uint64_t NumBytesBuffered() const override { return 0; }
+
+  // Release some (possibly none) delayed stream data.
+  void MaybeTransmitSomeData() {
+    auto count = provider_->ConsumeIntegral<uint8_t>();
+    while (!stream_data.empty() && count > 0) {
+      receiver_->Decode(stream_data.front());
+      stream_data.pop_front();
+      --count;
+    }
+  }
+
+  // Release all delayed stream data.  Must be called before destruction.
+  void Flush() {
+    while (!stream_data.empty()) {
+      receiver_->Decode(stream_data.front());
+      stream_data.pop_front();
+    }
+  }
+
+ private:
+  QpackStreamReceiver* const receiver_;
+  FuzzedDataProvider* const provider_;
+  quiche::QuicheCircularDeque<std::string> stream_data;
+};
+
+// Generate header list using fuzzer data.
+spdy::Http2HeaderBlock GenerateHeaderList(FuzzedDataProvider* provider) {
+  spdy::Http2HeaderBlock header_list;
+  uint8_t header_count = provider->ConsumeIntegral<uint8_t>();
+  for (uint8_t header_index = 0; header_index < header_count; ++header_index) {
+    if (provider->remaining_bytes() == 0) {
+      // Do not add more headers if there is no more fuzzer data.
+      break;
+    }
+
+    std::string name;
+    std::string value;
+    switch (provider->ConsumeIntegral<uint8_t>()) {
+      case 0:
+        // Static table entry with no header value.
+        name = ":authority";
+        break;
+      case 1:
+        // Static table entry with no header value, using non-empty header
+        // value.
+        name = ":authority";
+        value = "www.example.org";
+        break;
+      case 2:
+        // Static table entry with header value, using that header value.
+        name = ":accept-encoding";
+        value = "gzip, deflate";
+        break;
+      case 3:
+        // Static table entry with header value, using empty header value.
+        name = ":accept-encoding";
+        break;
+      case 4:
+        // Static table entry with header value, using different, non-empty
+        // header value.
+        name = ":accept-encoding";
+        value = "brotli";
+        break;
+      case 5:
+        // Header name that has multiple entries in the static table,
+        // using header value from one of them.
+        name = ":method";
+        value = "GET";
+        break;
+      case 6:
+        // Header name that has multiple entries in the static table,
+        // using empty header value.
+        name = ":method";
+        break;
+      case 7:
+        // Header name that has multiple entries in the static table,
+        // using different, non-empty header value.
+        name = ":method";
+        value = "CONNECT";
+        break;
+      case 8:
+        // Header name not in the static table, empty header value.
+        name = "foo";
+        value = "";
+        break;
+      case 9:
+        // Header name not in the static table, non-empty fixed header value.
+        name = "foo";
+        value = "bar";
+        break;
+      case 10:
+        // Header name not in the static table, fuzzed header value.
+        name = "foo";
+        value = provider->ConsumeRandomLengthString(128);
+        TruncateValueOnInvalidChars(&value);
+        break;
+      case 11:
+        // Another header name not in the static table, empty header value.
+        name = "bar";
+        value = "";
+        break;
+      case 12:
+        // Another header name not in the static table, non-empty fixed header
+        // value.
+        name = "bar";
+        value = "baz";
+        break;
+      case 13:
+        // Another header name not in the static table, fuzzed header value.
+        name = "bar";
+        value = provider->ConsumeRandomLengthString(128);
+        TruncateValueOnInvalidChars(&value);
+        break;
+      default:
+        // Fuzzed header name and header value.
+        name = provider->ConsumeRandomLengthString(128);
+        value = provider->ConsumeRandomLengthString(128);
+        TruncateValueOnInvalidChars(&value);
+    }
+
+    header_list.AppendValueOrAddHeader(name, value);
+  }
+
+  return header_list;
+}
+
+// Splits |*header_list| header values along '\0' or ';' separators.
+QuicHeaderList SplitHeaderList(const spdy::Http2HeaderBlock& header_list) {
+  QuicHeaderList split_header_list;
+  split_header_list.OnHeaderBlockStart();
+
+  size_t total_size = 0;
+  ValueSplittingHeaderList splitting_header_list(&header_list);
+  for (const auto& header : splitting_header_list) {
+    split_header_list.OnHeader(header.first, header.second);
+    total_size += header.first.size() + header.second.size();
+  }
+
+  split_header_list.OnHeaderBlockEnd(total_size, total_size);
+
+  return split_header_list;
+}
+
+// This fuzzer exercises QpackEncoder and QpackDecoder.  It should be able to
+// cover all possible code paths of QpackEncoder.  However, since the resulting
+// header block is always valid and is encoded in a particular way, this fuzzer
+// is not expected to cover all code paths of QpackDecoder.  On the other hand,
+// encoding then decoding is expected to result in the original header list, and
+// this fuzzer checks for that.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider provider(data, size);
+
+  // Maximum 256 byte dynamic table.  Such a small size helps test draining
+  // entries and eviction.
+  const uint64_t maximum_dynamic_table_capacity =
+      provider.ConsumeIntegral<uint8_t>();
+  // Maximum 256 blocked streams.
+  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();
+
+  // Set up encoder.
+  EncodingEndpoint encoder(maximum_dynamic_table_capacity,
+                           maximum_blocked_streams);
+
+  // Set up decoder.
+  DecodingEndpoint decoder(maximum_dynamic_table_capacity,
+                           maximum_blocked_streams);
+
+  // Transmit encoder stream data from encoder to decoder.
+  DelayedStreamDataTransmitter encoder_stream_transmitter(
+      decoder.encoder_stream_receiver(), &provider);
+  encoder.set_qpack_stream_sender_delegate(&encoder_stream_transmitter);
+
+  // Use a dynamic table as large as the peer allows.  This sends data on the
+  // encoder stream, so it can only be done after delegate is set.
+  encoder.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
+
+  // Transmit decoder stream data from encoder to decoder.
+  DelayedStreamDataTransmitter decoder_stream_transmitter(
+      encoder.decoder_stream_receiver(), &provider);
+  decoder.set_qpack_stream_sender_delegate(&decoder_stream_transmitter);
+
+  // Transmit header blocks from encoder to decoder.
+  DelayedHeaderBlockTransmitter header_block_transmitter(&decoder, &provider);
+
+  // Maximum 256 header lists to limit runtime and memory usage.
+  auto header_list_count = provider.ConsumeIntegral<uint8_t>();
+  while (header_list_count > 0 && provider.remaining_bytes() > 0) {
+    const QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
+
+    // Generate header list.
+    spdy::Http2HeaderBlock header_list = GenerateHeaderList(&provider);
+
+    // Encode header list.
+    std::string encoded_header_block =
+        encoder.EncodeHeaderList(stream_id, header_list);
+
+    // TODO(bnc): Randomly cancel the stream.
+
+    // Encoder splits |header_list| header values along '\0' or ';' separators.
+    // Do the same here so that we get matching results.
+    QuicHeaderList expected_header_list = SplitHeaderList(header_list);
+    decoder.AddExpectedHeaderList(stream_id, std::move(expected_header_list));
+
+    header_block_transmitter.SendEncodedHeaderBlock(
+        stream_id, std::move(encoded_header_block));
+
+    // Transmit some encoder stream data, decoder stream data, or header blocks
+    // on the request stream, repeating a few times.
+    for (auto transmit_data_count = provider.ConsumeIntegralInRange(1, 5);
+         transmit_data_count > 0; --transmit_data_count) {
+      encoder_stream_transmitter.MaybeTransmitSomeData();
+      decoder_stream_transmitter.MaybeTransmitSomeData();
+      header_block_transmitter.MaybeTransmitSomeData();
+    }
+
+    --header_list_count;
+  }
+
+  // Release all delayed encoder stream data so that remaining header blocks can
+  // be decoded synchronously.
+  encoder_stream_transmitter.Flush();
+  // Release all delayed header blocks.
+  header_block_transmitter.Flush();
+  // Release all delayed decoder stream data.
+  decoder_stream_transmitter.Flush();
+
+  return 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_blocking_manager.cc b/quiche/quic/core/qpack/qpack_blocking_manager.cc
new file mode 100644
index 0000000..6ab7307
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_blocking_manager.cc
@@ -0,0 +1,159 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_blocking_manager.h"
+
+#include <limits>
+#include <utility>
+
+namespace quic {
+
+QpackBlockingManager::QpackBlockingManager() : known_received_count_(0) {}
+
+bool QpackBlockingManager::OnHeaderAcknowledgement(QuicStreamId stream_id) {
+  auto it = header_blocks_.find(stream_id);
+  if (it == header_blocks_.end()) {
+    return false;
+  }
+
+  QUICHE_DCHECK(!it->second.empty());
+
+  const IndexSet& indices = it->second.front();
+  QUICHE_DCHECK(!indices.empty());
+
+  const uint64_t required_index_count = RequiredInsertCount(indices);
+  if (known_received_count_ < required_index_count) {
+    known_received_count_ = required_index_count;
+  }
+
+  DecreaseReferenceCounts(indices);
+
+  it->second.pop_front();
+  if (it->second.empty()) {
+    header_blocks_.erase(it);
+  }
+
+  return true;
+}
+
+void QpackBlockingManager::OnStreamCancellation(QuicStreamId stream_id) {
+  auto it = header_blocks_.find(stream_id);
+  if (it == header_blocks_.end()) {
+    return;
+  }
+
+  for (const IndexSet& indices : it->second) {
+    DecreaseReferenceCounts(indices);
+  }
+
+  header_blocks_.erase(it);
+}
+
+bool QpackBlockingManager::OnInsertCountIncrement(uint64_t increment) {
+  if (increment >
+      std::numeric_limits<uint64_t>::max() - known_received_count_) {
+    return false;
+  }
+
+  known_received_count_ += increment;
+  return true;
+}
+
+void QpackBlockingManager::OnHeaderBlockSent(QuicStreamId stream_id,
+                                             IndexSet indices) {
+  QUICHE_DCHECK(!indices.empty());
+
+  IncreaseReferenceCounts(indices);
+  header_blocks_[stream_id].push_back(std::move(indices));
+}
+
+bool QpackBlockingManager::blocking_allowed_on_stream(
+    QuicStreamId stream_id,
+    uint64_t maximum_blocked_streams) const {
+  // This should be the most common case: the limit is larger than the number of
+  // streams that have unacknowledged header blocks (regardless of whether they
+  // are blocked or not) plus one for stream |stream_id|.
+  if (header_blocks_.size() + 1 <= maximum_blocked_streams) {
+    return true;
+  }
+
+  // This should be another common case: no blocked stream allowed.
+  if (maximum_blocked_streams == 0) {
+    return false;
+  }
+
+  uint64_t blocked_stream_count = 0;
+  for (const auto& header_blocks_for_stream : header_blocks_) {
+    for (const IndexSet& indices : header_blocks_for_stream.second) {
+      if (RequiredInsertCount(indices) > known_received_count_) {
+        if (header_blocks_for_stream.first == stream_id) {
+          // Sending blocking references is allowed if stream |stream_id| is
+          // already blocked.
+          return true;
+        }
+        ++blocked_stream_count;
+        // If stream |stream_id| is already blocked, then it is not counted yet,
+        // therefore the number of blocked streams is at least
+        // |blocked_stream_count + 1|, which cannot be more than
+        // |maximum_blocked_streams| by API contract.
+        // If stream |stream_id| is not blocked, then blocking will increase the
+        // blocked stream count to at least |blocked_stream_count + 1|.  If that
+        // is larger than |maximum_blocked_streams|, then blocking is not
+        // allowed on stream |stream_id|.
+        if (blocked_stream_count + 1 > maximum_blocked_streams) {
+          return false;
+        }
+        break;
+      }
+    }
+  }
+
+  // Stream |stream_id| is not blocked.
+  // If there are no blocked streams, then
+  // |blocked_stream_count + 1 <= maximum_blocked_streams| because
+  // |maximum_blocked_streams| is larger than zero.
+  // If there are are blocked streams, then
+  // |blocked_stream_count + 1 <= maximum_blocked_streams| otherwise the method
+  // would have returned false when |blocked_stream_count| was incremented.
+  // Therefore blocking on |stream_id| is allowed.
+  return true;
+}
+
+uint64_t QpackBlockingManager::smallest_blocking_index() const {
+  return entry_reference_counts_.empty()
+             ? std::numeric_limits<uint64_t>::max()
+             : entry_reference_counts_.begin()->first;
+}
+
+// static
+uint64_t QpackBlockingManager::RequiredInsertCount(const IndexSet& indices) {
+  return *indices.rbegin() + 1;
+}
+
+void QpackBlockingManager::IncreaseReferenceCounts(const IndexSet& indices) {
+  for (const uint64_t index : indices) {
+    auto it = entry_reference_counts_.lower_bound(index);
+    if (it != entry_reference_counts_.end() && it->first == index) {
+      ++it->second;
+    } else {
+      entry_reference_counts_.insert(it, {index, 1});
+    }
+  }
+}
+
+void QpackBlockingManager::DecreaseReferenceCounts(const IndexSet& indices) {
+  for (const uint64_t index : indices) {
+    auto it = entry_reference_counts_.find(index);
+    QUICHE_DCHECK(it != entry_reference_counts_.end());
+    QUICHE_DCHECK_NE(0u, it->second);
+
+    if (it->second == 1) {
+      entry_reference_counts_.erase(it);
+    } else {
+      --it->second;
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_blocking_manager.h b/quiche/quic/core/qpack/qpack_blocking_manager.h
new file mode 100644
index 0000000..4fc1029
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_blocking_manager.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
+
+#include <cstdint>
+#include <map>
+#include <set>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+
+class QpackBlockingManagerPeer;
+
+}  // namespace test
+
+// Class to keep track of blocked streams and blocking dynamic table entries:
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-decoding
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-insertion
+class QUIC_EXPORT_PRIVATE QpackBlockingManager {
+ public:
+  using IndexSet = std::multiset<uint64_t>;
+
+  QpackBlockingManager();
+
+  // Called when a Header Acknowledgement instruction is received on the decoder
+  // stream.  Returns false if there are no outstanding header blocks to be
+  // acknowledged on |stream_id|.
+  bool OnHeaderAcknowledgement(QuicStreamId stream_id);
+
+  // Called when a Stream Cancellation instruction is received on the decoder
+  // stream.
+  void OnStreamCancellation(QuicStreamId stream_id);
+
+  // Called when an Insert Count Increment instruction is received on the
+  // decoder stream.  Returns true if Known Received Count is successfully
+  // updated.  Returns false on overflow.
+  bool OnInsertCountIncrement(uint64_t increment);
+
+  // Called when sending a header block containing references to dynamic table
+  // entries with |indices|.  |indices| must not be empty.
+  void OnHeaderBlockSent(QuicStreamId stream_id, IndexSet indices);
+
+  // Returns true if sending blocking references on stream |stream_id| would not
+  // increase the total number of blocked streams above
+  // |maximum_blocked_streams|.  Note that if |stream_id| is already blocked
+  // then it is always allowed to send more blocking references on it.
+  // Behavior is undefined if |maximum_blocked_streams| is smaller than number
+  // of currently blocked streams.
+  bool blocking_allowed_on_stream(QuicStreamId stream_id,
+                                  uint64_t maximum_blocked_streams) const;
+
+  // Returns the index of the blocking entry with the smallest index,
+  // or std::numeric_limits<uint64_t>::max() if there are no blocking entries.
+  uint64_t smallest_blocking_index() const;
+
+  // Returns the Known Received Count as defined at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
+  uint64_t known_received_count() const { return known_received_count_; }
+
+  // Required Insert Count for set of indices.
+  static uint64_t RequiredInsertCount(const IndexSet& indices);
+
+ private:
+  friend test::QpackBlockingManagerPeer;
+
+  // A stream typically has only one header block, except for the rare cases of
+  // 1xx responses, trailers, or push promises.  Even if there are multiple
+  // header blocks sent on a single stream, they might not be blocked at the
+  // same time.  Use std::list instead of quiche::QuicheCircularDeque because it
+  // has lower memory footprint when holding few elements.
+  using HeaderBlocksForStream = std::list<IndexSet>;
+  using HeaderBlocks = absl::flat_hash_map<QuicStreamId, HeaderBlocksForStream>;
+
+  // Increase or decrease the reference count for each index in |indices|.
+  void IncreaseReferenceCounts(const IndexSet& indices);
+  void DecreaseReferenceCounts(const IndexSet& indices);
+
+  // Multiset of indices in each header block for each stream.
+  // Must not contain a stream id with an empty queue.
+  HeaderBlocks header_blocks_;
+
+  // Number of references in |header_blocks_| for each entry index.
+  std::map<uint64_t, uint64_t> entry_reference_counts_;
+
+  uint64_t known_received_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_BLOCKING_MANAGER_H_
diff --git a/quiche/quic/core/qpack/qpack_blocking_manager_test.cc b/quiche/quic/core/qpack/qpack_blocking_manager_test.cc
new file mode 100644
index 0000000..670264e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_blocking_manager_test.cc
@@ -0,0 +1,319 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_blocking_manager.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QpackBlockingManagerPeer {
+ public:
+  static bool stream_is_blocked(const QpackBlockingManager* manager,
+                                QuicStreamId stream_id) {
+    for (const auto& header_blocks_for_stream : manager->header_blocks_) {
+      if (header_blocks_for_stream.first != stream_id) {
+        continue;
+      }
+      for (const auto& indices : header_blocks_for_stream.second) {
+        if (QpackBlockingManager::RequiredInsertCount(indices) >
+            manager->known_received_count_) {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+};
+
+namespace {
+
+class QpackBlockingManagerTest : public QuicTest {
+ protected:
+  QpackBlockingManagerTest() = default;
+  ~QpackBlockingManagerTest() override = default;
+
+  bool stream_is_blocked(QuicStreamId stream_id) const {
+    return QpackBlockingManagerPeer::stream_is_blocked(&manager_, stream_id);
+  }
+
+  QpackBlockingManager manager_;
+};
+
+TEST_F(QpackBlockingManagerTest, Empty) {
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(1));
+}
+
+TEST_F(QpackBlockingManagerTest, NotBlockedByInsertCountIncrement) {
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+
+  // Stream 0 is not blocked, because it only references entries that are
+  // already acknowledged by an Insert Count Increment instruction.
+  manager_.OnHeaderBlockSent(0, {1, 0});
+  EXPECT_FALSE(stream_is_blocked(0));
+}
+
+TEST_F(QpackBlockingManagerTest, UnblockedByInsertCountIncrement) {
+  manager_.OnHeaderBlockSent(0, {1, 0});
+  EXPECT_TRUE(stream_is_blocked(0));
+
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+  EXPECT_FALSE(stream_is_blocked(0));
+}
+
+TEST_F(QpackBlockingManagerTest, NotBlockedByHeaderAcknowledgement) {
+  manager_.OnHeaderBlockSent(0, {2, 1, 1});
+  EXPECT_TRUE(stream_is_blocked(0));
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_FALSE(stream_is_blocked(0));
+
+  // Stream 1 is not blocked, because it only references entries that are
+  // already acknowledged by a Header Acknowledgement instruction.
+  manager_.OnHeaderBlockSent(1, {2, 2});
+  EXPECT_FALSE(stream_is_blocked(1));
+}
+
+TEST_F(QpackBlockingManagerTest, UnblockedByHeaderAcknowledgement) {
+  manager_.OnHeaderBlockSent(0, {2, 1, 1});
+  manager_.OnHeaderBlockSent(1, {2, 2});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_TRUE(stream_is_blocked(1));
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_FALSE(stream_is_blocked(1));
+}
+
+TEST_F(QpackBlockingManagerTest, KnownReceivedCount) {
+  EXPECT_EQ(0u, manager_.known_received_count());
+
+  // Sending a header block does not change Known Received Count.
+  manager_.OnHeaderBlockSent(0, {0});
+  EXPECT_EQ(0u, manager_.known_received_count());
+
+  manager_.OnHeaderBlockSent(1, {1});
+  EXPECT_EQ(0u, manager_.known_received_count());
+
+  // Header Acknowledgement might increase Known Received Count.
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(1u, manager_.known_received_count());
+
+  manager_.OnHeaderBlockSent(2, {5});
+  EXPECT_EQ(1u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
+  EXPECT_EQ(2u, manager_.known_received_count());
+
+  // Insert Count Increment increases Known Received Count.
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+  EXPECT_EQ(4u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(2));
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  // Stream Cancellation does not change Known Received Count.
+  manager_.OnStreamCancellation(0);
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  // Header Acknowledgement of a block with smaller Required Insert Count does
+  // not increase Known Received Count.
+  manager_.OnHeaderBlockSent(0, {3});
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  // Header Acknowledgement of a block with equal Required Insert Count does not
+  // increase Known Received Count.
+  manager_.OnHeaderBlockSent(1, {5});
+  EXPECT_EQ(6u, manager_.known_received_count());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
+  EXPECT_EQ(6u, manager_.known_received_count());
+}
+
+TEST_F(QpackBlockingManagerTest, SmallestBlockingIndex) {
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {0});
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(1, {2});
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(1, {1});
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  // Insert Count Increment does not change smallest blocking index.
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(2));
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  manager_.OnStreamCancellation(1);
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+}
+
+TEST_F(QpackBlockingManagerTest, HeaderAcknowledgementsOnSingleStream) {
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {2, 1, 1});
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(1u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {1, 0});
+  EXPECT_EQ(0u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(3u, manager_.known_received_count());
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {3});
+  EXPECT_EQ(3u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(3u, manager_.known_received_count());
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(3u, manager_.smallest_blocking_index());
+
+  EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
+  EXPECT_EQ(4u, manager_.known_received_count());
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+
+  EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
+}
+
+TEST_F(QpackBlockingManagerTest, CancelStream) {
+  manager_.OnHeaderBlockSent(0, {3});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(3u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(0, {2});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+  manager_.OnHeaderBlockSent(1, {4});
+  EXPECT_TRUE(stream_is_blocked(0));
+  EXPECT_TRUE(stream_is_blocked(1));
+  EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+  manager_.OnStreamCancellation(0);
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_TRUE(stream_is_blocked(1));
+  EXPECT_EQ(4u, manager_.smallest_blocking_index());
+
+  manager_.OnStreamCancellation(1);
+  EXPECT_FALSE(stream_is_blocked(0));
+  EXPECT_FALSE(stream_is_blocked(1));
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+            manager_.smallest_blocking_index());
+}
+
+TEST_F(QpackBlockingManagerTest, BlockingAllowedOnStream) {
+  const QuicStreamId kStreamId1 = 1;
+  const QuicStreamId kStreamId2 = 2;
+  const QuicStreamId kStreamId3 = 3;
+
+  // No stream can block if limit is 0.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
+
+  // Either stream can block if limit is larger.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+
+  // Doubly block first stream.
+  manager_.OnHeaderBlockSent(kStreamId1, {0});
+  manager_.OnHeaderBlockSent(kStreamId1, {1});
+
+  // First stream is already blocked so it can carry more blocking references.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  // Second stream is not allowed to block if limit is already reached.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+
+  // Either stream can block if limit is larger than number of blocked streams.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Block second stream.
+  manager_.OnHeaderBlockSent(kStreamId2, {2});
+
+  // Streams are already blocked so either can carry more blocking references.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Third, unblocked stream is not allowed to block unless limit is strictly
+  // larger than number of blocked streams.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId3, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId3, 3));
+
+  // Acknowledge decoding of first header block on first stream.
+  // Stream is still blocked on its second header block.
+  manager_.OnHeaderAcknowledgement(kStreamId1);
+
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Acknowledge decoding of second header block on first stream.
+  // This unblocks the stream.
+  manager_.OnHeaderAcknowledgement(kStreamId1);
+
+  // First stream is not allowed to block if limit is already reached.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  // Second stream is already blocked so it can carry more blocking references.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+
+  // Either stream can block if limit is larger than number of blocked streams.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
+
+  // Unblock second stream.
+  manager_.OnHeaderAcknowledgement(kStreamId2);
+
+  // No stream can block if limit is 0.
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
+  EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
+
+  // Either stream can block if limit is larger.
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
+  EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
+}
+
+TEST_F(QpackBlockingManagerTest, InsertCountIncrementOverflow) {
+  EXPECT_TRUE(manager_.OnInsertCountIncrement(10));
+  EXPECT_EQ(10u, manager_.known_received_count());
+
+  EXPECT_FALSE(manager_.OnInsertCountIncrement(
+      std::numeric_limits<uint64_t>::max() - 5));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc
new file mode 100644
index 0000000..9e87f20
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QpackDecodedHeadersAccumulator::QpackDecodedHeadersAccumulator(
+    QuicStreamId id,
+    QpackDecoder* qpack_decoder,
+    Visitor* visitor,
+    size_t max_header_list_size)
+    : decoder_(qpack_decoder->CreateProgressiveDecoder(id, this)),
+      visitor_(visitor),
+      max_header_list_size_(max_header_list_size),
+      uncompressed_header_bytes_including_overhead_(0),
+      uncompressed_header_bytes_without_overhead_(0),
+      compressed_header_bytes_(0),
+      header_list_size_limit_exceeded_(false),
+      headers_decoded_(false),
+      error_detected_(false) {
+  quic_header_list_.OnHeaderBlockStart();
+}
+
+void QpackDecodedHeadersAccumulator::OnHeaderDecoded(absl::string_view name,
+                                                     absl::string_view value) {
+  QUICHE_DCHECK(!error_detected_);
+
+  uncompressed_header_bytes_without_overhead_ += name.size() + value.size();
+
+  if (header_list_size_limit_exceeded_) {
+    return;
+  }
+
+  uncompressed_header_bytes_including_overhead_ +=
+      name.size() + value.size() + kQpackEntrySizeOverhead;
+
+  const size_t uncompressed_header_bytes =
+      GetQuicFlag(FLAGS_quic_header_size_limit_includes_overhead)
+          ? uncompressed_header_bytes_including_overhead_
+          : uncompressed_header_bytes_without_overhead_;
+  if (uncompressed_header_bytes > max_header_list_size_) {
+    header_list_size_limit_exceeded_ = true;
+    quic_header_list_.Clear();
+  } else {
+    quic_header_list_.OnHeader(name, value);
+  }
+}
+
+void QpackDecodedHeadersAccumulator::OnDecodingCompleted() {
+  QUICHE_DCHECK(!headers_decoded_);
+  QUICHE_DCHECK(!error_detected_);
+
+  headers_decoded_ = true;
+
+  quic_header_list_.OnHeaderBlockEnd(
+      uncompressed_header_bytes_without_overhead_, compressed_header_bytes_);
+
+  // Might destroy |this|.
+  visitor_->OnHeadersDecoded(std::move(quic_header_list_),
+                             header_list_size_limit_exceeded_);
+}
+
+void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected(
+    QuicErrorCode error_code, absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+  QUICHE_DCHECK(!headers_decoded_);
+
+  error_detected_ = true;
+  // Might destroy |this|.
+  visitor_->OnHeaderDecodingError(error_code, error_message);
+}
+
+void QpackDecodedHeadersAccumulator::Decode(absl::string_view data) {
+  QUICHE_DCHECK(!error_detected_);
+
+  compressed_header_bytes_ += data.size();
+  // Might destroy |this|.
+  decoder_->Decode(data);
+}
+
+void QpackDecodedHeadersAccumulator::EndHeaderBlock() {
+  QUICHE_DCHECK(!error_detected_);
+  QUICHE_DCHECK(!headers_decoded_);
+
+  if (!decoder_) {
+    QUIC_BUG(b215142466_EndHeaderBlock);
+    return;
+  }
+
+  // Might destroy |this|.
+  decoder_->EndHeaderBlock();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h
new file mode 100644
index 0000000..27c94bd
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
+
+#include <cstddef>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QpackDecoder;
+
+// A class that creates and owns a QpackProgressiveDecoder instance, accumulates
+// decoded headers in a QuicHeaderList, and keeps track of uncompressed and
+// compressed size so that it can be passed to
+// QuicHeaderList::OnHeaderBlockEnd().
+class QUIC_EXPORT_PRIVATE QpackDecodedHeadersAccumulator
+    : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  // Visitor interface to signal success or error.
+  // Exactly one method will be called.
+  // Methods may be called synchronously from Decode() and EndHeaderBlock(),
+  // or asynchronously.
+  // Method implementations are allowed to destroy |this|.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() = default;
+
+    // Called when headers are successfully decoded.  If the uncompressed header
+    // list size including an overhead for each header field exceeds the limit
+    // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator
+    // constructor, then |header_list_size_limit_exceeded| will be true, and
+    // |headers| will be empty but will still have the correct compressed and
+    // uncompressed size
+    // information.
+    virtual void OnHeadersDecoded(QuicHeaderList headers,
+                                  bool header_list_size_limit_exceeded) = 0;
+
+    // Called when an error has occurred.
+    virtual void OnHeaderDecodingError(QuicErrorCode error_code,
+                                       absl::string_view error_message) = 0;
+  };
+
+  QpackDecodedHeadersAccumulator(QuicStreamId id,
+                                 QpackDecoder* qpack_decoder,
+                                 Visitor* visitor,
+                                 size_t max_header_list_size);
+  virtual ~QpackDecodedHeadersAccumulator() = default;
+
+  // QpackProgressiveDecoder::HeadersHandlerInterface implementation.
+  // These methods should only be called by |decoder_|.
+  void OnHeaderDecoded(absl::string_view name,
+                       absl::string_view value) override;
+  void OnDecodingCompleted() override;
+  void OnDecodingErrorDetected(QuicErrorCode error_code,
+                               absl::string_view error_message) override;
+
+  // Decode payload data.
+  // Must not be called if an error has been detected.
+  // Must not be called after EndHeaderBlock().
+  void Decode(absl::string_view data);
+
+  // Signal end of HEADERS frame.
+  // Must not be called if an error has been detected.
+  // Must not be called more that once.
+  void EndHeaderBlock();
+
+ private:
+  std::unique_ptr<QpackProgressiveDecoder> decoder_;
+  Visitor* visitor_;
+  // Maximum header list size including overhead.
+  size_t max_header_list_size_;
+  // Uncompressed header list size including overhead, for enforcing the limit.
+  size_t uncompressed_header_bytes_including_overhead_;
+  QuicHeaderList quic_header_list_;
+  // Uncompressed header list size with overhead,
+  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
+  size_t uncompressed_header_bytes_without_overhead_;
+  // Compressed header list size
+  // for passing in to QuicHeaderList::OnHeaderBlockEnd().
+  size_t compressed_header_bytes_;
+
+  // True if the header size limit has been exceeded.
+  // Input data is still fed to QpackProgressiveDecoder.
+  bool header_list_size_limit_exceeded_;
+
+  // The following two members are only used for QUICHE_DCHECKs.
+
+  // True if headers have been completedly and successfully decoded.
+  bool headers_decoded_;
+  // True if an error has been detected during decoding.
+  bool error_detected_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODED_HEADERS_ACCUMULATOR_H_
diff --git a/quiche/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
new file mode 100644
index 0000000..92d7511
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
@@ -0,0 +1,253 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
+
+#include <cstring>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::Pair;
+using ::testing::SaveArg;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Arbitrary stream ID used for testing.
+QuicStreamId kTestStreamId = 1;
+
+// Limit on header list size.
+const size_t kMaxHeaderListSize = 100;
+
+// Maximum dynamic table capacity.
+const size_t kMaxDynamicTableCapacity = 100;
+
+// Maximum number of blocked streams.
+const uint64_t kMaximumBlockedStreams = 1;
+
+// Header Acknowledgement decoder stream instruction with stream_id = 1.
+const char* const kHeaderAcknowledgement = "\x81";
+
+class MockVisitor : public QpackDecodedHeadersAccumulator::Visitor {
+ public:
+  ~MockVisitor() override = default;
+  MOCK_METHOD(void,
+              OnHeadersDecoded,
+              (QuicHeaderList headers, bool header_list_size_limit_exceeded),
+              (override));
+  MOCK_METHOD(void, OnHeaderDecodingError,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+}  // anonymous namespace
+
+class QpackDecodedHeadersAccumulatorTest : public QuicTest {
+ protected:
+  QpackDecodedHeadersAccumulatorTest()
+      : qpack_decoder_(kMaxDynamicTableCapacity,
+                       kMaximumBlockedStreams,
+                       &encoder_stream_error_delegate_),
+        accumulator_(kTestStreamId,
+                     &qpack_decoder_,
+                     &visitor_,
+                     kMaxHeaderListSize) {
+    qpack_decoder_.set_qpack_stream_sender_delegate(
+        &decoder_stream_sender_delegate_);
+  }
+
+  NoopEncoderStreamErrorDelegate encoder_stream_error_delegate_;
+  StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
+  QpackDecoder qpack_decoder_;
+  StrictMock<MockVisitor> visitor_;
+  QpackDecodedHeadersAccumulator accumulator_;
+};
+
+// HEADERS frame payload must have a complete Header Block Prefix.
+TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyPayload) {
+  EXPECT_CALL(visitor_,
+              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                    Eq("Incomplete header data prefix.")));
+  accumulator_.EndHeaderBlock();
+}
+
+// HEADERS frame payload must have a complete Header Block Prefix.
+TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) {
+  accumulator_.Decode(absl::HexStringToBytes("00"));
+
+  EXPECT_CALL(visitor_,
+              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                    Eq("Incomplete header data prefix.")));
+  accumulator_.EndHeaderBlock();
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) {
+  std::string encoded_data(absl::HexStringToBytes("0000"));
+  accumulator_.Decode(encoded_data);
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  accumulator_.EndHeaderBlock();
+
+  EXPECT_EQ(0u, header_list.uncompressed_header_bytes());
+  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
+  EXPECT_TRUE(header_list.empty());
+}
+
+// This payload is the prefix of a valid payload, but EndHeaderBlock() is called
+// before it can be completely decoded.
+TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) {
+  accumulator_.Decode(absl::HexStringToBytes("00002366"));
+
+  EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                              Eq("Incomplete header block.")));
+  accumulator_.EndHeaderBlock();
+}
+
+// This payload is invalid because it refers to a non-existing static entry.
+TEST_F(QpackDecodedHeadersAccumulatorTest, InvalidPayload) {
+  EXPECT_CALL(visitor_,
+              OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                    Eq("Static table entry not found.")));
+  accumulator_.Decode(absl::HexStringToBytes("0000ff23ff24"));
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest, Success) {
+  std::string encoded_data(absl::HexStringToBytes("000023666f6f03626172"));
+  accumulator_.Decode(encoded_data);
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  accumulator_.EndHeaderBlock();
+
+  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
+  EXPECT_EQ(strlen("foo") + strlen("bar"),
+            header_list.uncompressed_header_bytes());
+  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
+}
+
+// Test that Decode() calls are not ignored after header list limit is exceeded,
+// otherwise decoding could fail with "incomplete header block" error.
+TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) {
+  // Total length of header list exceeds kMaxHeaderListSize.
+  accumulator_.Decode(absl::HexStringToBytes(
+      "0000"                                      // header block prefix
+      "26666f6f626172"                            // header key: "foobar"
+      "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "61616161616161616161616161616161616161616161616161616161616161616161"
+      "ff"));  // first byte of a two-byte long Indexed Header Field instruction
+  accumulator_.Decode(absl::HexStringToBytes(
+      "0f"  // second byte of a two-byte long Indexed Header Field instruction
+      ));
+
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
+  accumulator_.EndHeaderBlock();
+}
+
+// Test that header list limit enforcement works with blocked encoding.
+TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) {
+  // Total length of header list exceeds kMaxHeaderListSize.
+  accumulator_.Decode(absl::HexStringToBytes(
+      "0200"            // header block prefix
+      "80"              // reference to dynamic table entry not yet received
+      "26666f6f626172"  // header key: "foobar"
+      "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "616161616161616161616161616161616161616161616161616161616161616161616161"
+      "61616161616161616161616161616161616161616161616161616161616161616161"));
+  accumulator_.EndHeaderBlock();
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+  // Adding dynamic table entry unblocks decoding.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) {
+  // Reference to dynamic table entry not yet received.
+  std::string encoded_data(absl::HexStringToBytes("020080"));
+  accumulator_.Decode(encoded_data);
+  accumulator_.EndHeaderBlock();
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+  // Adding dynamic table entry unblocks decoding.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+
+  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
+  EXPECT_EQ(strlen("foo") + strlen("bar"),
+            header_list.uncompressed_header_bytes());
+  EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
+}
+
+TEST_F(QpackDecodedHeadersAccumulatorTest,
+       BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
+  // Reference to dynamic table entry not yet received.
+  accumulator_.Decode(absl::HexStringToBytes("020080"));
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+  // Adding dynamic table entry unblocks decoding.
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+
+  // Rest of header block: same entry again.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+  accumulator_.Decode(absl::HexStringToBytes("80"));
+
+  QuicHeaderList header_list;
+  EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+      .WillOnce(SaveArg<0>(&header_list));
+  accumulator_.EndHeaderBlock();
+
+  EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar"), Pair("foo", "bar")));
+}
+
+// Regression test for https://crbug.com/1024263.
+TEST_F(QpackDecodedHeadersAccumulatorTest,
+       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
+  // Required Insert Count higher than number of entries causes decoding to be
+  // blocked.
+  accumulator_.Decode(absl::HexStringToBytes("0200"));
+  // Indexed Header Field instruction addressing dynamic table entry with
+  // relative index 0, absolute index 0.
+  accumulator_.Decode(absl::HexStringToBytes("80"));
+  // Relative index larger than or equal to Base is invalid.
+  accumulator_.Decode(absl::HexStringToBytes("81"));
+
+  // Set dynamic table capacity.
+  qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
+
+  // Adding dynamic table entry unblocks decoding.  Error is detected.
+  EXPECT_CALL(visitor_, OnHeaderDecodingError(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                              Eq("Invalid relative index.")));
+  qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder.cc b/quiche/quic/core/qpack/qpack_decoder.cc
new file mode 100644
index 0000000..e93db67
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackDecoder::QpackDecoder(
+    uint64_t maximum_dynamic_table_capacity,
+    uint64_t maximum_blocked_streams,
+    EncoderStreamErrorDelegate* encoder_stream_error_delegate)
+    : encoder_stream_error_delegate_(encoder_stream_error_delegate),
+      encoder_stream_receiver_(this),
+      maximum_blocked_streams_(maximum_blocked_streams),
+      known_received_count_(0) {
+  QUICHE_DCHECK(encoder_stream_error_delegate_);
+
+  header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+}
+
+QpackDecoder::~QpackDecoder() {}
+
+void QpackDecoder::OnStreamReset(QuicStreamId stream_id) {
+  if (header_table_.maximum_dynamic_table_capacity() > 0) {
+    decoder_stream_sender_.SendStreamCancellation(stream_id);
+    decoder_stream_sender_.Flush();
+  }
+}
+
+bool QpackDecoder::OnStreamBlocked(QuicStreamId stream_id) {
+  auto result = blocked_streams_.insert(stream_id);
+  QUICHE_DCHECK(result.second);
+  return blocked_streams_.size() <= maximum_blocked_streams_;
+}
+
+void QpackDecoder::OnStreamUnblocked(QuicStreamId stream_id) {
+  size_t result = blocked_streams_.erase(stream_id);
+  QUICHE_DCHECK_EQ(1u, result);
+}
+
+void QpackDecoder::OnDecodingCompleted(QuicStreamId stream_id,
+                                       uint64_t required_insert_count) {
+  if (required_insert_count > 0) {
+    decoder_stream_sender_.SendHeaderAcknowledgement(stream_id);
+
+    if (known_received_count_ < required_insert_count) {
+      known_received_count_ = required_insert_count;
+    }
+  }
+
+  // Send an Insert Count Increment instruction if not all dynamic table entries
+  // have been acknowledged yet.  This is necessary for efficient compression in
+  // case the encoder chooses not to reference unacknowledged dynamic table
+  // entries, otherwise inserted entries would never be acknowledged.
+  if (known_received_count_ < header_table_.inserted_entry_count()) {
+    decoder_stream_sender_.SendInsertCountIncrement(
+        header_table_.inserted_entry_count() - known_received_count_);
+    known_received_count_ = header_table_.inserted_entry_count();
+  }
+
+  decoder_stream_sender_.Flush();
+}
+
+void QpackDecoder::OnInsertWithNameReference(bool is_static,
+                                             uint64_t name_index,
+                                             absl::string_view value) {
+  if (is_static) {
+    auto entry = header_table_.LookupEntry(/* is_static = */ true, name_index);
+    if (!entry) {
+      OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
+                      "Invalid static table entry.");
+      return;
+    }
+
+    if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
+      OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC,
+                      "Error inserting entry with name reference.");
+      return;
+    }
+    header_table_.InsertEntry(entry->name(), value);
+    return;
+  }
+
+  uint64_t absolute_index;
+  if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+          name_index, header_table_.inserted_entry_count(), &absolute_index)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
+                    "Invalid relative index.");
+    return;
+  }
+
+  const QpackEntry* entry =
+      header_table_.LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND,
+                    "Dynamic table entry not found.");
+    return;
+  }
+  if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(), value)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC,
+                    "Error inserting entry with name reference.");
+    return;
+  }
+  header_table_.InsertEntry(entry->name(), value);
+}
+
+void QpackDecoder::OnInsertWithoutNameReference(absl::string_view name,
+                                                absl::string_view value) {
+  if (!header_table_.EntryFitsDynamicTableCapacity(name, value)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
+                    "Error inserting literal entry.");
+    return;
+  }
+  header_table_.InsertEntry(name, value);
+}
+
+void QpackDecoder::OnDuplicate(uint64_t index) {
+  uint64_t absolute_index;
+  if (!QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+          index, header_table_.inserted_entry_count(), &absolute_index)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
+                    "Invalid relative index.");
+    return;
+  }
+
+  const QpackEntry* entry =
+      header_table_.LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND,
+                    "Dynamic table entry not found.");
+    return;
+  }
+  if (!header_table_.EntryFitsDynamicTableCapacity(entry->name(),
+                                                   entry->value())) {
+    // This is impossible since entry was retrieved from the dynamic table.
+    OnErrorDetected(QUIC_INTERNAL_ERROR, "Error inserting duplicate entry.");
+    return;
+  }
+  header_table_.InsertEntry(entry->name(), entry->value());
+}
+
+void QpackDecoder::OnSetDynamicTableCapacity(uint64_t capacity) {
+  if (!header_table_.SetDynamicTableCapacity(capacity)) {
+    OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
+                    "Error updating dynamic table capacity.");
+  }
+}
+
+void QpackDecoder::OnErrorDetected(QuicErrorCode error_code,
+                                   absl::string_view error_message) {
+  encoder_stream_error_delegate_->OnEncoderStreamError(error_code,
+                                                       error_message);
+}
+
+std::unique_ptr<QpackProgressiveDecoder> QpackDecoder::CreateProgressiveDecoder(
+    QuicStreamId stream_id,
+    QpackProgressiveDecoder::HeadersHandlerInterface* handler) {
+  return std::make_unique<QpackProgressiveDecoder>(stream_id, this, this,
+                                                   &header_table_, handler);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder.h b/quiche/quic/core/qpack/qpack_decoder.h
new file mode 100644
index 0000000..940535d
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
+
+#include <cstdint>
+#include <memory>
+#include <set>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QPACK decoder class.  Exactly one instance should exist per QUIC connection.
+// This class vends a new QpackProgressiveDecoder instance for each new header
+// list to be encoded.
+// QpackProgressiveDecoder detects and signals errors with header blocks, which
+// are stream errors.
+// The only input of QpackDecoder is the encoder stream.  Any error QpackDecoder
+// signals is an encoder stream error, which is fatal to the connection.
+class QUIC_EXPORT_PRIVATE QpackDecoder
+    : public QpackEncoderStreamReceiver::Delegate,
+      public QpackProgressiveDecoder::BlockedStreamLimitEnforcer,
+      public QpackProgressiveDecoder::DecodingCompletedVisitor {
+ public:
+  // Interface for receiving notification that an error has occurred on the
+  // encoder stream.  This MUST be treated as a connection error of type
+  // HTTP_QPACK_ENCODER_STREAM_ERROR.
+  class QUIC_EXPORT_PRIVATE EncoderStreamErrorDelegate {
+   public:
+    virtual ~EncoderStreamErrorDelegate() {}
+
+    virtual void OnEncoderStreamError(QuicErrorCode error_code,
+                                      absl::string_view error_message) = 0;
+  };
+
+  QpackDecoder(uint64_t maximum_dynamic_table_capacity,
+               uint64_t maximum_blocked_streams,
+               EncoderStreamErrorDelegate* encoder_stream_error_delegate);
+  ~QpackDecoder() override;
+
+  // Signal to the peer's encoder that a stream is reset.  This lets the peer's
+  // encoder know that no more header blocks will be processed on this stream,
+  // therefore references to dynamic table entries shall not prevent their
+  // eviction.
+  // This method should be called regardless of whether a header block is being
+  // decoded on that stream, because a header block might be in flight from the
+  // peer.
+  // This method should be called every time a request or push stream is reset
+  // for any reason: for example, client cancels request, or a decoding error
+  // occurs and HeadersHandlerInterface::OnDecodingErrorDetected() is called.
+  // This method should also be called if the stream is reset by the peer,
+  // because the peer's encoder can only evict entries referenced by header
+  // blocks once it receives acknowledgement from this endpoint that the stream
+  // is reset.
+  // However, this method should not be called if the stream is closed normally
+  // using the FIN bit.
+  void OnStreamReset(QuicStreamId stream_id);
+
+  // QpackProgressiveDecoder::BlockedStreamLimitEnforcer implementation.
+  bool OnStreamBlocked(QuicStreamId stream_id) override;
+  void OnStreamUnblocked(QuicStreamId stream_id) override;
+
+  // QpackProgressiveDecoder::DecodingCompletedVisitor implementation.
+  void OnDecodingCompleted(QuicStreamId stream_id,
+                           uint64_t required_insert_count) override;
+
+  // Factory method to create a QpackProgressiveDecoder for decoding a header
+  // block.  |handler| must remain valid until the returned
+  // QpackProgressiveDecoder instance is destroyed or the decoder calls
+  // |handler->OnHeaderBlockEnd()|.
+  std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
+      QuicStreamId stream_id,
+      QpackProgressiveDecoder::HeadersHandlerInterface* handler);
+
+  // QpackEncoderStreamReceiver::Delegate implementation
+  void OnInsertWithNameReference(bool is_static,
+                                 uint64_t name_index,
+                                 absl::string_view value) override;
+  void OnInsertWithoutNameReference(absl::string_view name,
+                                    absl::string_view value) override;
+  void OnDuplicate(uint64_t index) override;
+  void OnSetDynamicTableCapacity(uint64_t capacity) override;
+  void OnErrorDetected(QuicErrorCode error_code,
+                       absl::string_view error_message) override;
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    decoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  QpackStreamReceiver* encoder_stream_receiver() {
+    return &encoder_stream_receiver_;
+  }
+
+  // True if any dynamic table entries have been referenced from a header block.
+  bool dynamic_table_entry_referenced() const {
+    return header_table_.dynamic_table_entry_referenced();
+  }
+
+ private:
+  EncoderStreamErrorDelegate* const encoder_stream_error_delegate_;
+  QpackEncoderStreamReceiver encoder_stream_receiver_;
+  QpackDecoderStreamSender decoder_stream_sender_;
+  QpackDecoderHeaderTable header_table_;
+  std::set<QuicStreamId> blocked_streams_;
+  const uint64_t maximum_blocked_streams_;
+
+  // Known Received Count is the number of insertions the encoder has received
+  // acknowledgement for (through Header Acknowledgement and Insert Count
+  // Increment instructions).  The encoder must keep track of it in order to be
+  // able to send Insert Count Increment instructions.  See
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#known-received-count.
+  uint64_t known_received_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_H_
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc
new file mode 100644
index 0000000..699eb4f
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+
+namespace quic {
+
+QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate)
+    : instruction_decoder_(QpackDecoderStreamLanguage(), this),
+      delegate_(delegate),
+      error_detected_(false) {
+  QUICHE_DCHECK(delegate_);
+}
+
+void QpackDecoderStreamReceiver::Decode(absl::string_view data) {
+  if (data.empty() || error_detected_) {
+    return;
+  }
+
+  instruction_decoder_.Decode(data);
+}
+
+bool QpackDecoderStreamReceiver::OnInstructionDecoded(
+    const QpackInstruction* instruction) {
+  if (instruction == InsertCountIncrementInstruction()) {
+    delegate_->OnInsertCountIncrement(instruction_decoder_.varint());
+    return true;
+  }
+
+  if (instruction == HeaderAcknowledgementInstruction()) {
+    delegate_->OnHeaderAcknowledgement(instruction_decoder_.varint());
+    return true;
+  }
+
+  QUICHE_DCHECK_EQ(instruction, StreamCancellationInstruction());
+  delegate_->OnStreamCancellation(instruction_decoder_.varint());
+  return true;
+}
+
+void QpackDecoderStreamReceiver::OnInstructionDecodingError(
+    QpackInstructionDecoder::ErrorCode error_code,
+    absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+
+  // There is no string literals on the decoder stream,
+  // the only possible error is INTEGER_TOO_LARGE.
+  QuicErrorCode quic_error_code =
+      (error_code == QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE)
+          ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE
+          : QUIC_INTERNAL_ERROR;
+  delegate_->OnErrorDetected(quic_error_code, error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_receiver.h b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.h
new file mode 100644
index 0000000..f78fca9
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_receiver.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_receiver.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class decodes data received on the decoder stream,
+// and passes it along to its Delegate.
+class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver
+    : public QpackInstructionDecoder::Delegate,
+      public QpackStreamReceiver {
+ public:
+  // An interface for handling instructions decoded from the decoder stream, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // 5.3.1 Insert Count Increment
+    virtual void OnInsertCountIncrement(uint64_t increment) = 0;
+    // 5.3.2 Header Acknowledgement
+    virtual void OnHeaderAcknowledgement(QuicStreamId stream_id) = 0;
+    // 5.3.3 Stream Cancellation
+    virtual void OnStreamCancellation(QuicStreamId stream_id) = 0;
+    // Decoding error
+    virtual void OnErrorDetected(QuicErrorCode error_code,
+                                 absl::string_view error_message) = 0;
+  };
+
+  explicit QpackDecoderStreamReceiver(Delegate* delegate);
+  QpackDecoderStreamReceiver() = delete;
+  QpackDecoderStreamReceiver(const QpackDecoderStreamReceiver&) = delete;
+  QpackDecoderStreamReceiver& operator=(const QpackDecoderStreamReceiver&) =
+      delete;
+
+  // Implements QpackStreamReceiver::Decode().
+  // Decode data and call appropriate Delegate method after each decoded
+  // instruction.  Once an error occurs, Delegate::OnErrorDetected() is called,
+  // and all further data is ignored.
+  void Decode(absl::string_view data) override;
+
+  // QpackInstructionDecoder::Delegate implementation.
+  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
+  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
+                                  absl::string_view error_message) override;
+
+ private:
+  QpackInstructionDecoder instruction_decoder_;
+  Delegate* const delegate_;
+
+  // True if a decoding error has been detected.
+  bool error_detected_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_receiver_test.cc b/quiche/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
new file mode 100644
index 0000000..c78cbe7
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
@@ -0,0 +1,102 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using testing::Eq;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockDelegate : public QpackDecoderStreamReceiver::Delegate {
+ public:
+  ~MockDelegate() override = default;
+
+  MOCK_METHOD(void, OnInsertCountIncrement, (uint64_t increment), (override));
+  MOCK_METHOD(void,
+              OnHeaderAcknowledgement,
+              (QuicStreamId stream_id),
+              (override));
+  MOCK_METHOD(void, OnStreamCancellation, (QuicStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnErrorDetected,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+class QpackDecoderStreamReceiverTest : public QuicTest {
+ protected:
+  QpackDecoderStreamReceiverTest() : stream_(&delegate_) {}
+  ~QpackDecoderStreamReceiverTest() override = default;
+
+  QpackDecoderStreamReceiver stream_;
+  StrictMock<MockDelegate> delegate_;
+};
+
+TEST_F(QpackDecoderStreamReceiverTest, InsertCountIncrement) {
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(0));
+  stream_.Decode(absl::HexStringToBytes("00"));
+
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(10));
+  stream_.Decode(absl::HexStringToBytes("0a"));
+
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(63));
+  stream_.Decode(absl::HexStringToBytes("3f00"));
+
+  EXPECT_CALL(delegate_, OnInsertCountIncrement(200));
+  stream_.Decode(absl::HexStringToBytes("3f8901"));
+
+  EXPECT_CALL(delegate_,
+              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+  stream_.Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
+}
+
+TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
+  stream_.Decode(absl::HexStringToBytes("80"));
+
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
+  stream_.Decode(absl::HexStringToBytes("a5"));
+
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
+  stream_.Decode(absl::HexStringToBytes("ff00"));
+
+  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
+  stream_.Decode(absl::HexStringToBytes("fff802"));
+
+  EXPECT_CALL(delegate_,
+              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+  stream_.Decode(absl::HexStringToBytes("ffffffffffffffffffffff"));
+}
+
+TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
+  EXPECT_CALL(delegate_, OnStreamCancellation(0));
+  stream_.Decode(absl::HexStringToBytes("40"));
+
+  EXPECT_CALL(delegate_, OnStreamCancellation(19));
+  stream_.Decode(absl::HexStringToBytes("53"));
+
+  EXPECT_CALL(delegate_, OnStreamCancellation(63));
+  stream_.Decode(absl::HexStringToBytes("7f00"));
+
+  EXPECT_CALL(delegate_, OnStreamCancellation(110));
+  stream_.Decode(absl::HexStringToBytes("7f2f"));
+
+  EXPECT_CALL(delegate_,
+              OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+  stream_.Decode(absl::HexStringToBytes("7fffffffffffffffffffff"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc b/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc
new file mode 100644
index 0000000..cc48587
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+
+#include <cstddef>
+#include <limits>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackDecoderStreamSender::QpackDecoderStreamSender() : delegate_(nullptr) {}
+
+void QpackDecoderStreamSender::SendInsertCountIncrement(uint64_t increment) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::InsertCountIncrement(increment), &buffer_);
+}
+
+void QpackDecoderStreamSender::SendHeaderAcknowledgement(
+    QuicStreamId stream_id) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::HeaderAcknowledgement(stream_id), &buffer_);
+}
+
+void QpackDecoderStreamSender::SendStreamCancellation(QuicStreamId stream_id) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::StreamCancellation(stream_id), &buffer_);
+}
+
+void QpackDecoderStreamSender::Flush() {
+  if (buffer_.empty()) {
+    return;
+  }
+
+  delegate_->WriteStreamData(buffer_);
+  buffer_.clear();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_sender.h b/quiche/quic/core/qpack/qpack_decoder_stream_sender.h
new file mode 100644
index 0000000..443e850
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_sender.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class serializes instructions for transmission on the decoder stream.
+// Serialized instructions are buffered until Flush() is called.
+class QUIC_EXPORT_PRIVATE QpackDecoderStreamSender {
+ public:
+  QpackDecoderStreamSender();
+  QpackDecoderStreamSender(const QpackDecoderStreamSender&) = delete;
+  QpackDecoderStreamSender& operator=(const QpackDecoderStreamSender&) = delete;
+
+  // Methods for serializing and buffering instructions, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
+
+  // 5.3.1 Insert Count Increment
+  void SendInsertCountIncrement(uint64_t increment);
+  // 5.3.2 Header Acknowledgement
+  void SendHeaderAcknowledgement(QuicStreamId stream_id);
+  // 5.3.3 Stream Cancellation
+  void SendStreamCancellation(QuicStreamId stream_id);
+
+  // Writes all buffered instructions on the decoder stream.
+  void Flush();
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    delegate_ = delegate;
+  }
+
+ private:
+  QpackStreamSenderDelegate* delegate_;
+  QpackInstructionEncoder instruction_encoder_;
+  std::string buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_SENDER_H_
diff --git a/quiche/quic/core/qpack/qpack_decoder_stream_sender_test.cc b/quiche/quic/core/qpack/qpack_decoder_stream_sender_test.cc
new file mode 100644
index 0000000..8c43af5
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_stream_sender_test.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoder_stream_sender.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::Eq;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QpackDecoderStreamSenderTest : public QuicTest {
+ protected:
+  QpackDecoderStreamSenderTest() {
+    stream_.set_qpack_stream_sender_delegate(&delegate_);
+  }
+  ~QpackDecoderStreamSenderTest() override = default;
+
+  StrictMock<MockQpackStreamSenderDelegate> delegate_;
+  QpackDecoderStreamSender stream_;
+};
+
+TEST_F(QpackDecoderStreamSenderTest, InsertCountIncrement) {
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("00"))));
+  stream_.SendInsertCountIncrement(0);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0a"))));
+  stream_.SendInsertCountIncrement(10);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f00"))));
+  stream_.SendInsertCountIncrement(63);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f8901"))));
+  stream_.SendInsertCountIncrement(200);
+  stream_.Flush();
+}
+
+TEST_F(QpackDecoderStreamSenderTest, HeaderAcknowledgement) {
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("80"))));
+  stream_.SendHeaderAcknowledgement(0);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("a5"))));
+  stream_.SendHeaderAcknowledgement(37);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("ff00"))));
+  stream_.SendHeaderAcknowledgement(127);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("fff802"))));
+  stream_.SendHeaderAcknowledgement(503);
+  stream_.Flush();
+}
+
+TEST_F(QpackDecoderStreamSenderTest, StreamCancellation) {
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("40"))));
+  stream_.SendStreamCancellation(0);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("53"))));
+  stream_.SendStreamCancellation(19);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f00"))));
+  stream_.SendStreamCancellation(63);
+  stream_.Flush();
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f2f"))));
+  stream_.SendStreamCancellation(110);
+  stream_.Flush();
+}
+
+TEST_F(QpackDecoderStreamSenderTest, Coalesce) {
+  stream_.SendInsertCountIncrement(10);
+  stream_.SendHeaderAcknowledgement(37);
+  stream_.SendStreamCancellation(0);
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0aa540"))));
+  stream_.Flush();
+
+  stream_.SendInsertCountIncrement(63);
+  stream_.SendStreamCancellation(110);
+
+  EXPECT_CALL(delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes("3f007f2f"))));
+  stream_.Flush();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_decoder_test.cc b/quiche/quic/core/qpack/qpack_decoder_test.cc
new file mode 100644
index 0000000..f15b3e8
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_decoder_test.cc
@@ -0,0 +1,984 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+
+#include <algorithm>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::Mock;
+using ::testing::Sequence;
+using ::testing::StrictMock;
+using ::testing::Values;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Header Acknowledgement decoder stream instruction with stream_id = 1.
+const char* const kHeaderAcknowledgement = "\x81";
+
+const uint64_t kMaximumDynamicTableCapacity = 1024;
+const uint64_t kMaximumBlockedStreams = 1;
+
+class QpackDecoderTest : public QuicTestWithParam<FragmentMode> {
+ protected:
+  QpackDecoderTest()
+      : qpack_decoder_(kMaximumDynamicTableCapacity,
+                       kMaximumBlockedStreams,
+                       &encoder_stream_error_delegate_),
+        fragment_mode_(GetParam()) {
+    qpack_decoder_.set_qpack_stream_sender_delegate(
+        &decoder_stream_sender_delegate_);
+  }
+
+  ~QpackDecoderTest() override = default;
+
+  void SetUp() override {
+    // Destroy QpackProgressiveDecoder on error to test that it does not crash.
+    // See https://crbug.com/1025209.
+    ON_CALL(handler_, OnDecodingErrorDetected(_, _))
+        .WillByDefault(Invoke([this](QuicErrorCode /* error_code */,
+                                     absl::string_view /* error_message */) {
+          progressive_decoder_.reset();
+        }));
+  }
+
+  void DecodeEncoderStreamData(absl::string_view data) {
+    qpack_decoder_.encoder_stream_receiver()->Decode(data);
+  }
+
+  std::unique_ptr<QpackProgressiveDecoder> CreateProgressiveDecoder(
+      QuicStreamId stream_id) {
+    return qpack_decoder_.CreateProgressiveDecoder(stream_id, &handler_);
+  }
+
+  // Set up |progressive_decoder_|.
+  void StartDecoding() {
+    progressive_decoder_ = CreateProgressiveDecoder(/* stream_id = */ 1);
+  }
+
+  // Pass header block data to QpackProgressiveDecoder::Decode()
+  // in fragments dictated by |fragment_mode_|.
+  void DecodeData(absl::string_view data) {
+    auto fragment_size_generator =
+        FragmentModeToFragmentSizeGenerator(fragment_mode_);
+    while (progressive_decoder_ && !data.empty()) {
+      size_t fragment_size = std::min(fragment_size_generator(), data.size());
+      progressive_decoder_->Decode(data.substr(0, fragment_size));
+      data = data.substr(fragment_size);
+    }
+  }
+
+  // Signal end of header block to QpackProgressiveDecoder.
+  void EndDecoding() {
+    if (progressive_decoder_) {
+      progressive_decoder_->EndHeaderBlock();
+    }
+    // If no error was detected, |*progressive_decoder_| is kept alive so that
+    // it can handle callbacks later in case of blocked decoding.
+  }
+
+  // Decode an entire header block.
+  void DecodeHeaderBlock(absl::string_view data) {
+    StartDecoding();
+    DecodeData(data);
+    EndDecoding();
+  }
+
+  StrictMock<MockEncoderStreamErrorDelegate> encoder_stream_error_delegate_;
+  StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
+  StrictMock<MockHeadersHandler> handler_;
+
+ private:
+  QpackDecoder qpack_decoder_;
+  const FragmentMode fragment_mode_;
+  std::unique_ptr<QpackProgressiveDecoder> progressive_decoder_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         QpackDecoderTest,
+                         Values(FragmentMode::kSingleChunk,
+                                FragmentMode::kOctetByOctet));
+
+TEST_P(QpackDecoderTest, NoPrefix) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Incomplete header data prefix.")));
+
+  // Header Data Prefix is at least two bytes long.
+  DecodeHeaderBlock(absl::HexStringToBytes("00"));
+}
+
+// Regression test for https://1025209: QpackProgressiveDecoder must not crash
+// in Decode() if it is destroyed by handler_.OnDecodingErrorDetected().
+TEST_P(QpackDecoderTest, InvalidPrefix) {
+  StartDecoding();
+
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Encoded integer too large.")));
+
+  // Encoded Required Insert Count in Header Data Prefix is too large.
+  DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff"));
+}
+
+TEST_P(QpackDecoderTest, EmptyHeaderBlock) {
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("0000"));
+}
+
+TEST_P(QpackDecoderTest, LiteralEntryEmptyName) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f"));
+}
+
+TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00"));
+}
+
+TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("00002000"));
+}
+
+TEST_P(QpackDecoderTest, SimpleLiteralEntry) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172"));
+}
+
+TEST_P(QpackDecoderTest, MultipleLiteralEntries) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  std::string str(127, 'a');
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str)));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0000"                // prefix
+      "23666f6f03626172"    // foo: bar
+      "2700666f6f62616172"  // 7 octet long header name, the smallest number
+                            // that does not fit on a 3-bit prefix.
+      "7f0061616161616161"  // 127 octet long header value, the smallest number
+      "616161616161616161"  // that does not fit on a 7-bit prefix.
+      "6161616161616161616161616161616161616161616161616161616161616161616161"
+      "6161616161616161616161616161616161616161616161616161616161616161616161"
+      "6161616161616161616161616161616161616161616161616161616161616161616161"
+      "616161616161"));
+}
+
+// Name Length value is too large for varint decoder to decode.
+TEST_P(QpackDecoderTest, NameLenTooLargeForVarintDecoder) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Encoded integer too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff"));
+}
+
+// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_P(QpackDecoderTest, NameLenExceedsLimit) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("String literal too long.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f"));
+}
+
+// Value Length value is too large for varint decoder to decode.
+TEST_P(QpackDecoderTest, ValueLenTooLargeForVarintDecoder) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Encoded integer too large.")));
+
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff"));
+}
+
+// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_P(QpackDecoderTest, ValueLenExceedsLimit) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("String literal too long.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f"));
+}
+
+TEST_P(QpackDecoderTest, LineFeedInValue) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
+                                      "Invalid character in field value."));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f0462610a72"));
+}
+
+TEST_P(QpackDecoderTest, IncompleteHeaderBlock) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Incomplete header block.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("00002366"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanSimple) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
+}
+
+TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) {
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")))
+      .Times(4);
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0000"                        // Prefix.
+      "2f0125a849e95ba97d7f"        // Huffman-encoded name.
+      "8925a849e95bb8e8b4bf"        // Huffman-encoded value.
+      "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
+      "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
+      "2f0125a849e95ba97d7f"        // Huffman-encoded name.
+      "0c637573746f6d2d76616c7565"  // Non-Huffman encoded value.
+      "2703637573746f6d2d6b6579"    // Non-Huffman encoded name.
+      "8925a849e95bb8e8b4bf"));     // Huffman-encoded value.
+}
+
+TEST_P(QpackDecoderTest, HuffmanNameDoesNotHaveEOSPrefix) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // 'y' ends in 0b0 on the most significant bit of the last byte.
+  // The remaining 7 bits must be a prefix of EOS, which is all 1s.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte.
+  // The remaining 5 bits must be a prefix of EOS, which is all 1s.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
+  // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a
+  // prefix of EOS.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
+}
+
+TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) {
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Error in Huffman-encoded string.")));
+
+  // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
+  // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a
+  // prefix of EOS.
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
+}
+
+TEST_P(QpackDecoderTest, StaticTable) {
+  // A header name that has multiple entries with different values.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("POST")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("TRACE")));
+
+  // A header name that has a single entry with non-empty value.
+  EXPECT_CALL(handler_,
+              OnHeaderDecoded(Eq("accept-encoding"), Eq("gzip, deflate, br")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("compress")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("accept-encoding"), Eq("")));
+
+  // A header name that has a single entry with empty value.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("location"), Eq("foo")));
+
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000"));
+}
+
+TEST_P(QpackDecoderTest, TooHighStaticTableIndex) {
+  // This is the last entry in the static table with index 98.
+  EXPECT_CALL(handler_,
+              OnHeaderDecoded(Eq("x-frame-options"), Eq("sameorigin")));
+
+  // Addressing entry 99 should trigger an error.
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Static table entry not found.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24"));
+}
+
+TEST_P(QpackDecoderTest, DynamicTable) {
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "80035a5a5a"      // Add entry with name of dynamic table entry index 0
+                        // (relative index) and value "ZZZ".
+      "cf8294e7"        // Add entry with name of static table entry index 15
+                        // and value "foo".
+      "01"));           // Duplicate entry with relative index 1.
+
+  // Now there are four entries in the dynamic table.
+  // Entry 0: "foo", "bar"
+  // Entry 1: "foo", "ZZZ"
+  // Entry 2: ":method", "foo"
+  // Entry 3: "foo", "ZZZ"
+
+  // Use a Sequence to test that mock methods are called in order.
+  Sequence s;
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0500"  // Required Insert Count 4 and Delta Base 0.
+              // Base is 4 + 0 = 4.
+      "83"    // Dynamic table entry with relative index 3, absolute index 0.
+      "82"    // Dynamic table entry with relative index 2, absolute index 1.
+      "81"    // Dynamic table entry with relative index 1, absolute index 2.
+      "80"    // Dynamic table entry with relative index 0, absolute index 3.
+      "41025a5a"));  // Name of entry 1 (relative index) from dynamic table,
+                     // with value "ZZ".
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0502"  // Required Insert Count 4 and Delta Base 2.
+              // Base is 4 + 2 = 6.
+      "85"    // Dynamic table entry with relative index 5, absolute index 0.
+      "84"    // Dynamic table entry with relative index 4, absolute index 1.
+      "83"    // Dynamic table entry with relative index 3, absolute index 2.
+      "82"    // Dynamic table entry with relative index 2, absolute index 3.
+      "43025a5a"));  // Name of entry 3 (relative index) from dynamic table,
+                     // with value "ZZ".
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("foo")))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("ZZZ"))).InSequence(s);
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("ZZ"))).InSequence(s);
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)))
+      .InSequence(s);
+  EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0582"  // Required Insert Count 4 and Delta Base 2 with sign bit set.
+              // Base is 4 - 2 - 1 = 1.
+      "80"    // Dynamic table entry with relative index 0, absolute index 0.
+      "10"    // Dynamic table entry with post-base index 0, absolute index 1.
+      "11"    // Dynamic table entry with post-base index 1, absolute index 2.
+      "12"    // Dynamic table entry with post-base index 2, absolute index 3.
+      "01025a5a"));  // Name of entry 1 (post-base index) from dynamic table,
+                     // with value "ZZ".
+}
+
+TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
+
+  // Change dynamic table capacity to 32 bytes, smaller than the entry.
+  // This must cause the entry to be evicted.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f01"));
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorEntryTooLarge) {
+  EXPECT_CALL(
+      encoder_stream_error_delegate_,
+      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL,
+                           Eq("Error inserting literal entry.")));
+
+  // Set dynamic table capacity to 34.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f03"));
+  // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38.
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) {
+  EXPECT_CALL(
+      encoder_stream_error_delegate_,
+      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY,
+                           Eq("Invalid static table entry.")));
+
+  // Address invalid static table entry index 99.
+  DecodeEncoderStreamData(absl::HexStringToBytes("ff2400"));
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) {
+  EXPECT_CALL(encoder_stream_error_delegate_,
+              OnEncoderStreamError(
+                  QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX,
+                  Eq("Invalid relative index.")));
+
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "8100"));  // Address dynamic table entry with relative index 1.  Such
+                 // entry does not exist.  The most recently added and only
+                 // dynamic table entry has relative index 0.
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorDuplicateInvalidEntry) {
+  EXPECT_CALL(encoder_stream_error_delegate_,
+              OnEncoderStreamError(
+                  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
+                  Eq("Invalid relative index.")));
+
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "01"));  // Duplicate dynamic table entry with relative index 1.  Such
+               // entry does not exist.  The most recently added and only
+               // dynamic table entry has relative index 0.
+}
+
+TEST_P(QpackDecoderTest, EncoderStreamErrorTooLargeInteger) {
+  EXPECT_CALL(encoder_stream_error_delegate_,
+              OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                                   Eq("Encoded integer too large.")));
+
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff"));
+}
+
+TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) {
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0280"   // Required Insert Count is 1.  Base 1 - 1 - 0 = 0 is explicitly
+               // permitted by the spec.
+      "80"));  // However, addressing entry with relative index 0 would point to
+               // absolute index -1, which is invalid.
+}
+
+TEST_P(QpackDecoderTest, InvalidNegativeBase) {
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Error calculating Base.")));
+
+  // Required Insert Count 1, Delta Base 1 with sign bit set, Base would
+  // be 1 - 1 - 1 = -1, but it is not allowed to be negative.
+  DecodeHeaderBlock(absl::HexStringToBytes("0281"));
+}
+
+TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "81"));  // Indexed Header Field instruction addressing relative index 1.
+               // This is absolute index -1, which is invalid.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"     // Required Insert Count 1 and Delta Base 0.
+                 // Base is 1 + 0 = 1.
+      "4100"));  // Literal Header Field with Name Reference instruction
+                 // addressing relative index 1.  This is absolute index -1,
+                 // which is invalid.
+}
+
+TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) {
+  // Update dynamic table capacity to 128.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
+
+  // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38.
+  // This fits in the table three times.
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+  // Duplicate entry four times.  This evicts the first two instances.
+  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0500"   // Required Insert Count 4 and Delta Base 0.
+               // Base is 4 + 0 = 4.
+      "82"));  // Indexed Header Field instruction addressing relative index 2.
+               // This is absolute index 1. Such entry does not exist.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0500"     // Required Insert Count 4 and Delta Base 0.
+                 // Base is 4 + 0 = 4.
+      "4200"));  // Literal Header Field with Name Reference instruction
+                 // addressing relative index 2.  This is absolute index 1. Such
+                 // entry does not exist.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0380"   // Required Insert Count 2 and Delta Base 0 with sign bit set.
+               // Base is 2 - 0 - 1 = 1
+      "10"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with post-base index 0, absolute index 1.  Such entry
+               // does not exist.
+
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Dynamic table entry already evicted.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0380"     // Required Insert Count 2 and Delta Base 0 with sign bit set.
+                 // Base is 2 - 0 - 1 = 1
+      "0000"));  // Literal Header Field With Name Reference instruction
+                 // addressing dynamic table entry with post-base index 0,
+                 // absolute index 1.  Such entry does not exist.
+}
+
+TEST_P(QpackDecoderTest, TableCapacityMustNotExceedMaximum) {
+  EXPECT_CALL(
+      encoder_stream_error_delegate_,
+      OnEncoderStreamError(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY,
+                           Eq("Error updating dynamic table capacity.")));
+
+  // Try to update dynamic table capacity to 2048, which exceeds the maximum.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f"));
+}
+
+TEST_P(QpackDecoderTest, SetDynamicTableCapacity) {
+  // Update dynamic table capacity to 128, which does not exceed the maximum.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
+}
+
+TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) {
+  // Maximum dynamic table capacity is 1024.
+  // MaxEntries is 1024 / 32 = 32.
+  // Required Insert Count is decoded modulo 2 * MaxEntries, that is, modulo 64.
+  // A value of 1 cannot be encoded as 65 even though it has the same remainder.
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Error decoding Required Insert Count.")));
+  DecodeHeaderBlock(absl::HexStringToBytes("4100"));
+}
+
+// Regression test for https://crbug.com/970218:  Decoder must stop processing
+// after a Header Block Prefix with an invalid Encoded Required Insert Count.
+TEST_P(QpackDecoderTest, DataAfterInvalidEncodedRequiredInsertCount) {
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(
+                            QUIC_QPACK_DECOMPRESSION_FAILED,
+                            Eq("Error decoding Required Insert Count.")));
+  // Header Block Prefix followed by some extra data.
+  DecodeHeaderBlock(absl::HexStringToBytes("410000"));
+}
+
+TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) {
+  // Maximum dynamic table capacity is 1024.
+  // MaxEntries is 1024 / 32 = 32.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and a 600 byte long value.  This will fit
+  // in the dynamic table once but not twice.
+  DecodeEncoderStreamData(
+      absl::HexStringToBytes("6294e7"     // Name "foo".
+                             "7fd903"));  // Value length 600.
+  std::string header_value(600, 'Z');
+  DecodeEncoderStreamData(header_value);
+
+  // Duplicate most recent entry 200 times.
+  DecodeEncoderStreamData(std::string(200, '\x00'));
+
+  // Now there is only one entry in the dynamic table, with absolute index 200.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq(header_value)));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  // Send header block with Required Insert Count = 201.
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0a00"   // Encoded Required Insert Count 10, Required Insert Count 201,
+               // Delta Base 0, Base 201.
+      "80"));  // Emit dynamic table entry with relative index 0.
+}
+
+TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count is 1.
+      "d1"));  // But the only instruction references the static table.
+}
+
+TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0201"   // Required Insert Count 1 and Delta Base 1.
+               // Base is 1 + 1 = 2.
+      "80"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 1.  This is not
+               // allowed by Required Insert Count.
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0201"     // Required Insert Count 1 and Delta Base 1.
+                 // Base is 1 + 1 = 2.
+      "4000"));  // Literal Header Field with Name Reference instruction
+                 // addressing dynamic table entry with relative index 0,
+                 // absolute index 1.  This is not allowed by Required Index
+                 // Count.
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "10"));  // Indexed Header Field with Post-Base Index instruction
+               // addressing dynamic table entry with post-base index 0,
+               // absolute index 1.  This is not allowed by Required Insert
+               // Count.
+
+  EXPECT_CALL(
+      handler_,
+      OnDecodingErrorDetected(
+          QUIC_QPACK_DECOMPRESSION_FAILED,
+          Eq("Absolute Index must be smaller than Required Insert Count.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"     // Required Insert Count 1 and Delta Base 0.
+                 // Base is 1 + 0 = 1.
+      "0000"));  // Literal Header Field with Post-Base Name Reference
+                 // instruction addressing dynamic table entry with post-base
+                 // index 0, absolute index 1.  This is not allowed by Required
+                 // Index Count.
+}
+
+TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) {
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+  // Duplicate entry twice so that decoding of header blocks with Required
+  // Insert Count not exceeding 3 is not blocked.
+  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0300"   // Required Insert Count 2 and Delta Base 0.
+               // Base is 2 + 0 = 2.
+      "81"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 1, absolute index 0.  Header block
+               // requires insert count of 1, even though Required Insert Count
+               // is 2.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0300"     // Required Insert Count 2 and Delta Base 0.
+                 // Base is 2 + 0 = 2.
+      "4100"));  // Literal Header Field with Name Reference instruction
+                 // addressing dynamic table entry with relative index 1,
+                 // absolute index 0.  Header block requires insert count of 1,
+                 // even though Required Insert Count is 2.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0481"   // Required Insert Count 3 and Delta Base 1 with sign bit set.
+               // Base is 3 - 1 - 1 = 1.
+      "10"));  // Indexed Header Field with Post-Base Index instruction
+               // addressing dynamic table entry with post-base index 0,
+               // absolute index 1.  Header block requires insert count of 2,
+               // even though Required Insert Count is 3.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                      Eq("Required Insert Count too large.")));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0481"     // Required Insert Count 3 and Delta Base 1 with sign bit set.
+                 // Base is 3 - 1 - 1 = 1.
+      "0000"));  // Literal Header Field with Post-Base Name Reference
+                 // instruction addressing dynamic table entry with post-base
+                 // index 0, absolute index 1.  Header block requires insert
+                 // count of 2, even though Required Insert Count is 3.
+}
+
+TEST_P(QpackDecoderTest, BlockedDecoding) {
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+}
+
+TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
+  StartDecoding();
+  DecodeData(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "d1"));  // Static table entry with index 17.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+
+  // Add literal entry with name "foo" and value "bar".  Decoding is now
+  // unblocked because dynamic table Insert Count reached the Required Insert
+  // Count of the header block.  |handler_| methods are called immediately for
+  // the already consumed part of the header block.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+  Mock::VerifyAndClearExpectations(&handler_);
+
+  // Rest of header block is processed by QpackProgressiveDecoder
+  // in the unblocked state.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https")));
+  DecodeData(absl::HexStringToBytes(
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "d7"));  // Static table entry with index 23.
+  Mock::VerifyAndClearExpectations(&handler_);
+
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+  EndDecoding();
+}
+
+// Regression test for https://crbug.com/1024263.
+TEST_P(QpackDecoderTest,
+       BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
+  StartDecoding();
+  DecodeData(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"     // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 0.
+      "81"));  // Relative index 1 is equal to Base, therefore invalid.
+
+  // Set dynamic table capacity to 1024.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
+
+  // Add literal entry with name "foo" and value "bar".  Decoding is now
+  // unblocked because dynamic table Insert Count reached the Required Insert
+  // Count of the header block.  |handler_| methods are called immediately for
+  // the already consumed part of the header block.
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingErrorDetected(QUIC_QPACK_DECOMPRESSION_FAILED,
+                                                Eq("Invalid relative index.")));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+}
+
+// Make sure that Required Insert Count is compared to Insert Count,
+// not size of dynamic table.
+TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {
+  // Update dynamic table capacity to 128.
+  // At most three non-empty entries fit in the dynamic table.
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0700"   // Required Insert Count 6 and Delta Base 0.
+               // Base is 6 + 0 = 6.
+      "80"));  // Indexed Header Field instruction addressing dynamic table
+               // entry with relative index 0, absolute index 5.
+
+  // Add literal entry with name "foo" and value "bar".
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
+
+  // Duplicate entry four times.  This evicts the first two instances.
+  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(kHeaderAcknowledgement)));
+
+  // Add literal entry with name "foo" and value "bar".
+  // Insert Count is now 6, reaching Required Insert Count of the header block.
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a"));
+}
+
+TEST_P(QpackDecoderTest, TooManyBlockedStreams) {
+  // Required Insert Count 1 and Delta Base 0.
+  // Without any dynamic table entries received, decoding is blocked.
+  std::string data = absl::HexStringToBytes("0200");
+
+  auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1);
+  progressive_decoder1->Decode(data);
+
+  EXPECT_CALL(handler_,
+              OnDecodingErrorDetected(
+                  QUIC_QPACK_DECOMPRESSION_FAILED,
+                  Eq("Limit on number of blocked streams exceeded.")));
+
+  auto progressive_decoder2 = CreateProgressiveDecoder(/* stream_id = */ 2);
+  progressive_decoder2->Decode(data);
+}
+
+TEST_P(QpackDecoderTest, InsertCountIncrement) {
+  DecodeEncoderStreamData(absl::HexStringToBytes(
+      "3fe107"          // Set dynamic table capacity to 1024.
+      "6294e703626172"  // Add literal entry with name "foo" and value "bar".
+      "00"));           // Duplicate entry.
+
+  EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
+  EXPECT_CALL(handler_, OnDecodingCompleted());
+
+  // Decoder received two insertions, but Header Acknowledgement only increases
+  // Known Insert Count to one.  Decoder should send an Insert Count Increment
+  // instruction with increment of one to update Known Insert Count to two.
+  EXPECT_CALL(decoder_stream_sender_delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes(
+                  "81"       // Header Acknowledgement on stream 1
+                  "01"))));  // Insert Count Increment with increment of one
+
+  DecodeHeaderBlock(absl::HexStringToBytes(
+      "0200"   // Required Insert Count 1 and Delta Base 0.
+               // Base is 1 + 0 = 1.
+      "80"));  // Dynamic table entry with relative index 0, absolute index 0.
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder.cc b/quiche/quic/core/qpack/qpack_encoder.cc
new file mode 100644
index 0000000..db3f803
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder.cc
@@ -0,0 +1,461 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+#include "quiche/quic/core/qpack/qpack_required_insert_count.h"
+#include "quiche/quic/core/qpack/value_splitting_header_list.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Fraction to calculate draining index.  The oldest |kDrainingFraction| entries
+// will not be referenced in header blocks.  A new entry (duplicate or literal
+// with name reference) will be added to the dynamic table instead.  This allows
+// the number of references to the draining entry to go to zero faster, so that
+// it can be evicted.  See
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
+// TODO(bnc): Fine tune.
+const float kDrainingFraction = 0.25;
+
+}  // anonymous namespace
+
+QpackEncoder::QpackEncoder(
+    DecoderStreamErrorDelegate* decoder_stream_error_delegate)
+    : decoder_stream_error_delegate_(decoder_stream_error_delegate),
+      decoder_stream_receiver_(this),
+      maximum_blocked_streams_(0),
+      header_list_count_(0) {
+  QUICHE_DCHECK(decoder_stream_error_delegate_);
+}
+
+QpackEncoder::~QpackEncoder() {}
+
+// static
+QpackEncoder::Representation QpackEncoder::EncodeIndexedHeaderField(
+    bool is_static,
+    uint64_t index,
+    QpackBlockingManager::IndexSet* referred_indices) {
+  // Add |index| to |*referred_indices| only if entry is in the dynamic table.
+  if (!is_static) {
+    referred_indices->insert(index);
+  }
+  return Representation::IndexedHeaderField(is_static, index);
+}
+
+// static
+QpackEncoder::Representation
+QpackEncoder::EncodeLiteralHeaderFieldWithNameReference(
+    bool is_static,
+    uint64_t index,
+    absl::string_view value,
+    QpackBlockingManager::IndexSet* referred_indices) {
+  // Add |index| to |*referred_indices| only if entry is in the dynamic table.
+  if (!is_static) {
+    referred_indices->insert(index);
+  }
+  return Representation::LiteralHeaderFieldNameReference(is_static, index,
+                                                         value);
+}
+
+// static
+QpackEncoder::Representation QpackEncoder::EncodeLiteralHeaderField(
+    absl::string_view name,
+    absl::string_view value) {
+  return Representation::LiteralHeaderField(name, value);
+}
+
+QpackEncoder::Representations QpackEncoder::FirstPassEncode(
+    QuicStreamId stream_id,
+    const spdy::Http2HeaderBlock& header_list,
+    QpackBlockingManager::IndexSet* referred_indices,
+    QuicByteCount* encoder_stream_sent_byte_count) {
+  // If previous instructions are buffered in |encoder_stream_sender_|,
+  // do not count them towards the current header block.
+  const QuicByteCount initial_encoder_stream_buffered_byte_count =
+      encoder_stream_sender_.BufferedByteCount();
+
+  const bool can_write_to_encoder_stream = encoder_stream_sender_.CanWrite();
+
+  Representations representations;
+  representations.reserve(header_list.size());
+
+  // The index of the oldest entry that must not be evicted.
+  uint64_t smallest_blocking_index =
+      blocking_manager_.smallest_blocking_index();
+  // Entries with index larger than or equal to |known_received_count| are
+  // blocking.
+  const uint64_t known_received_count =
+      blocking_manager_.known_received_count();
+  // Only entries with index greater than or equal to |draining_index| are
+  // allowed to be referenced.
+  const uint64_t draining_index =
+      header_table_.draining_index(kDrainingFraction);
+  // Blocking references are allowed if the number of blocked streams is less
+  // than the limit.
+  const bool blocking_allowed = blocking_manager_.blocking_allowed_on_stream(
+      stream_id, maximum_blocked_streams_);
+
+  // Track events for histograms.
+  bool dynamic_table_insertion_blocked = false;
+  bool blocked_stream_limit_exhausted = false;
+
+  for (const auto& header : ValueSplittingHeaderList(&header_list)) {
+    // These strings are owned by |header_list|.
+    absl::string_view name = header.first;
+    absl::string_view value = header.second;
+
+    bool is_static;
+    uint64_t index;
+
+    auto match_type =
+        header_table_.FindHeaderField(name, value, &is_static, &index);
+
+    switch (match_type) {
+      case QpackEncoderHeaderTable::MatchType::kNameAndValue:
+        if (is_static) {
+          // Refer to entry directly.
+          representations.push_back(
+              EncodeIndexedHeaderField(is_static, index, referred_indices));
+
+          break;
+        }
+
+        if (index >= draining_index) {
+          // If allowed, refer to entry directly.
+          if (!blocking_allowed && index >= known_received_count) {
+            blocked_stream_limit_exhausted = true;
+          } else {
+            representations.push_back(
+                EncodeIndexedHeaderField(is_static, index, referred_indices));
+            smallest_blocking_index = std::min(smallest_blocking_index, index);
+            header_table_.set_dynamic_table_entry_referenced();
+
+            break;
+          }
+        } else {
+          // Entry is draining, needs to be duplicated.
+          if (!blocking_allowed) {
+            blocked_stream_limit_exhausted = true;
+          } else if (QpackEntry::Size(name, value) >
+                     header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                         std::min(smallest_blocking_index, index))) {
+            dynamic_table_insertion_blocked = true;
+          } else {
+            if (can_write_to_encoder_stream) {
+              // If allowed, duplicate entry and refer to it.
+              encoder_stream_sender_.SendDuplicate(
+                  QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+                      index, header_table_.inserted_entry_count()));
+              uint64_t new_index = header_table_.InsertEntry(name, value);
+              representations.push_back(EncodeIndexedHeaderField(
+                  is_static, new_index, referred_indices));
+              smallest_blocking_index =
+                  std::min(smallest_blocking_index, index);
+              header_table_.set_dynamic_table_entry_referenced();
+
+              break;
+            }
+          }
+        }
+
+        // Encode entry as string literals.
+        // TODO(b/112770235): Use already acknowledged entry with lower index if
+        // exists.
+        // TODO(b/112770235): Use static entry name with literal value if
+        // dynamic entry exists but cannot be used.
+        representations.push_back(EncodeLiteralHeaderField(name, value));
+
+        break;
+
+      case QpackEncoderHeaderTable::MatchType::kName:
+        if (is_static) {
+          if (blocking_allowed &&
+              QpackEntry::Size(name, value) <=
+                  header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                      smallest_blocking_index)) {
+            // If allowed, insert entry into dynamic table and refer to it.
+            if (can_write_to_encoder_stream) {
+              encoder_stream_sender_.SendInsertWithNameReference(is_static,
+                                                                 index, value);
+              uint64_t new_index = header_table_.InsertEntry(name, value);
+              representations.push_back(EncodeIndexedHeaderField(
+                  /* is_static = */ false, new_index, referred_indices));
+              smallest_blocking_index =
+                  std::min<uint64_t>(smallest_blocking_index, new_index);
+
+              break;
+            }
+          }
+
+          // Emit literal field with name reference.
+          representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
+              is_static, index, value, referred_indices));
+
+          break;
+        }
+
+        if (!blocking_allowed) {
+          blocked_stream_limit_exhausted = true;
+        } else if (QpackEntry::Size(name, value) >
+                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                       std::min(smallest_blocking_index, index))) {
+          dynamic_table_insertion_blocked = true;
+        } else {
+          // If allowed, insert entry with name reference and refer to it.
+          if (can_write_to_encoder_stream) {
+            encoder_stream_sender_.SendInsertWithNameReference(
+                is_static,
+                QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+                    index, header_table_.inserted_entry_count()),
+                value);
+            uint64_t new_index = header_table_.InsertEntry(name, value);
+            representations.push_back(EncodeIndexedHeaderField(
+                is_static, new_index, referred_indices));
+            smallest_blocking_index = std::min(smallest_blocking_index, index);
+            header_table_.set_dynamic_table_entry_referenced();
+
+            break;
+          }
+        }
+
+        if ((blocking_allowed || index < known_received_count) &&
+            index >= draining_index) {
+          // If allowed, refer to entry name directly, with literal value.
+          representations.push_back(EncodeLiteralHeaderFieldWithNameReference(
+              is_static, index, value, referred_indices));
+          smallest_blocking_index = std::min(smallest_blocking_index, index);
+          header_table_.set_dynamic_table_entry_referenced();
+
+          break;
+        }
+
+        // Encode entry as string literals.
+        // TODO(b/112770235): Use already acknowledged entry with lower index if
+        // exists.
+        // TODO(b/112770235): Use static entry name with literal value if
+        // dynamic entry exists but cannot be used.
+        representations.push_back(EncodeLiteralHeaderField(name, value));
+
+        break;
+
+      case QpackEncoderHeaderTable::MatchType::kNoMatch:
+        // If allowed, insert entry and refer to it.
+        if (!blocking_allowed) {
+          blocked_stream_limit_exhausted = true;
+        } else if (QpackEntry::Size(name, value) >
+                   header_table_.MaxInsertSizeWithoutEvictingGivenEntry(
+                       smallest_blocking_index)) {
+          dynamic_table_insertion_blocked = true;
+        } else {
+          if (can_write_to_encoder_stream) {
+            encoder_stream_sender_.SendInsertWithoutNameReference(name, value);
+            uint64_t new_index = header_table_.InsertEntry(name, value);
+            representations.push_back(EncodeIndexedHeaderField(
+                /* is_static = */ false, new_index, referred_indices));
+            smallest_blocking_index =
+                std::min<uint64_t>(smallest_blocking_index, new_index);
+
+            break;
+          }
+        }
+
+        // Encode entry as string literals.
+        // TODO(b/112770235): Consider also adding to dynamic table to improve
+        // compression ratio for subsequent header blocks with peers that do not
+        // allow any blocked streams.
+        representations.push_back(EncodeLiteralHeaderField(name, value));
+
+        break;
+    }
+  }
+
+  const QuicByteCount encoder_stream_buffered_byte_count =
+      encoder_stream_sender_.BufferedByteCount();
+  QUICHE_DCHECK_GE(encoder_stream_buffered_byte_count,
+                   initial_encoder_stream_buffered_byte_count);
+
+  if (encoder_stream_sent_byte_count) {
+    *encoder_stream_sent_byte_count =
+        encoder_stream_buffered_byte_count -
+        initial_encoder_stream_buffered_byte_count;
+  }
+  if (can_write_to_encoder_stream) {
+    encoder_stream_sender_.Flush();
+  } else {
+    QUICHE_DCHECK_EQ(encoder_stream_buffered_byte_count,
+                     initial_encoder_stream_buffered_byte_count);
+  }
+
+  ++header_list_count_;
+
+  if (dynamic_table_insertion_blocked) {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenInsertionBlocked",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which at least one dynamic table insertion was "
+        "blocked.");
+  } else {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenInsertionNotBlocked",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which no dynamic table insertion was blocked.");
+  }
+
+  if (blocked_stream_limit_exhausted) {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenBlockedStreamLimited",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which unacknowledged dynamic table entries could not be "
+        "referenced due to the limit on the number of blocked streams.");
+  } else {
+    QUIC_HISTOGRAM_COUNTS(
+        "QuicSession.Qpack.HeaderListCountWhenNotBlockedStreamLimited",
+        header_list_count_, /* min = */ 1, /* max = */ 1000,
+        /* bucket_count = */ 50,
+        "The ordinality of a header list within a connection during the "
+        "encoding of which the limit on the number of blocked streams did "
+        "not "
+        "prevent referencing unacknowledged dynamic table entries.");
+  }
+
+  return representations;
+}
+
+std::string QpackEncoder::SecondPassEncode(
+    QpackEncoder::Representations representations,
+    uint64_t required_insert_count) const {
+  QpackInstructionEncoder instruction_encoder;
+  std::string encoded_headers;
+
+  // Header block prefix.
+  instruction_encoder.Encode(
+      Representation::Prefix(QpackEncodeRequiredInsertCount(
+          required_insert_count, header_table_.max_entries())),
+      &encoded_headers);
+
+  const uint64_t base = required_insert_count;
+
+  for (auto& representation : representations) {
+    // Dynamic table references must be transformed from absolute to relative
+    // indices.
+    if ((representation.instruction() == QpackIndexedHeaderFieldInstruction() ||
+         representation.instruction() ==
+             QpackLiteralHeaderFieldNameReferenceInstruction()) &&
+        !representation.s_bit()) {
+      representation.set_varint(QpackAbsoluteIndexToRequestStreamRelativeIndex(
+          representation.varint(), base));
+    }
+    instruction_encoder.Encode(representation, &encoded_headers);
+  }
+
+  return encoded_headers;
+}
+
+std::string QpackEncoder::EncodeHeaderList(
+    QuicStreamId stream_id,
+    const spdy::Http2HeaderBlock& header_list,
+    QuicByteCount* encoder_stream_sent_byte_count) {
+  // Keep track of all dynamic table indices that this header block refers to so
+  // that it can be passed to QpackBlockingManager.
+  QpackBlockingManager::IndexSet referred_indices;
+
+  // First pass: encode into |representations|.
+  Representations representations =
+      FirstPassEncode(stream_id, header_list, &referred_indices,
+                      encoder_stream_sent_byte_count);
+
+  const uint64_t required_insert_count =
+      referred_indices.empty()
+          ? 0
+          : QpackBlockingManager::RequiredInsertCount(referred_indices);
+  if (!referred_indices.empty()) {
+    blocking_manager_.OnHeaderBlockSent(stream_id, std::move(referred_indices));
+  }
+
+  // Second pass.
+  return SecondPassEncode(std::move(representations), required_insert_count);
+}
+
+bool QpackEncoder::SetMaximumDynamicTableCapacity(
+    uint64_t maximum_dynamic_table_capacity) {
+  return header_table_.SetMaximumDynamicTableCapacity(
+      maximum_dynamic_table_capacity);
+}
+
+void QpackEncoder::SetDynamicTableCapacity(uint64_t dynamic_table_capacity) {
+  encoder_stream_sender_.SendSetDynamicTableCapacity(dynamic_table_capacity);
+  // Do not flush encoder stream.  This write can safely be delayed until more
+  // instructions are written.
+
+  bool success = header_table_.SetDynamicTableCapacity(dynamic_table_capacity);
+  QUICHE_DCHECK(success);
+}
+
+bool QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
+  if (maximum_blocked_streams < maximum_blocked_streams_) {
+    return false;
+  }
+  maximum_blocked_streams_ = maximum_blocked_streams;
+  return true;
+}
+
+void QpackEncoder::OnInsertCountIncrement(uint64_t increment) {
+  if (increment == 0) {
+    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
+                    "Invalid increment value 0.");
+    return;
+  }
+
+  if (!blocking_manager_.OnInsertCountIncrement(increment)) {
+    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
+                    "Insert Count Increment instruction causes overflow.");
+  }
+
+  if (blocking_manager_.known_received_count() >
+      header_table_.inserted_entry_count()) {
+    OnErrorDetected(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
+                    absl::StrCat("Increment value ", increment,
+                                 " raises known received count to ",
+                                 blocking_manager_.known_received_count(),
+                                 " exceeding inserted entry count ",
+                                 header_table_.inserted_entry_count()));
+  }
+}
+
+void QpackEncoder::OnHeaderAcknowledgement(QuicStreamId stream_id) {
+  if (!blocking_manager_.OnHeaderAcknowledgement(stream_id)) {
+    OnErrorDetected(
+        QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
+        absl::StrCat("Header Acknowledgement received for stream ", stream_id,
+                     " with no outstanding header blocks."));
+  }
+}
+
+void QpackEncoder::OnStreamCancellation(QuicStreamId stream_id) {
+  blocking_manager_.OnStreamCancellation(stream_id);
+}
+
+void QpackEncoder::OnErrorDetected(QuicErrorCode error_code,
+                                   absl::string_view error_message) {
+  decoder_stream_error_delegate_->OnDecoderStreamError(error_code,
+                                                       error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder.h b/quiche/quic/core/qpack/qpack_encoder.h
new file mode 100644
index 0000000..fedf628
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder.h
@@ -0,0 +1,164 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_blocking_manager.h"
+#include "quiche/quic/core/qpack/qpack_decoder_stream_receiver.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+namespace test {
+
+class QpackEncoderPeer;
+
+}  // namespace test
+
+// QPACK encoder class.  Exactly one instance should exist per QUIC connection.
+class QUIC_EXPORT_PRIVATE QpackEncoder
+    : public QpackDecoderStreamReceiver::Delegate {
+ public:
+  // Interface for receiving notification that an error has occurred on the
+  // decoder stream.  This MUST be treated as a connection error of type
+  // HTTP_QPACK_DECODER_STREAM_ERROR.
+  class QUIC_EXPORT_PRIVATE DecoderStreamErrorDelegate {
+   public:
+    virtual ~DecoderStreamErrorDelegate() {}
+
+    virtual void OnDecoderStreamError(QuicErrorCode error_code,
+                                      absl::string_view error_message) = 0;
+  };
+
+  QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate);
+  ~QpackEncoder() override;
+
+  // Encode a header list.  If |encoder_stream_sent_byte_count| is not null,
+  // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent
+  // on the encoder stream to insert dynamic table entries.
+  std::string EncodeHeaderList(QuicStreamId stream_id,
+                               const spdy::Http2HeaderBlock& header_list,
+                               QuicByteCount* encoder_stream_sent_byte_count);
+
+  // Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|,
+  // measured in bytes.  Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
+  // received.  Encoder needs to know this value so that it can calculate
+  // MaxEntries, used as a modulus to encode Required Insert Count.
+  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
+  // or if it doesn't change current value. The setting is not changed when
+  // returning false.
+  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+
+  // Set dynamic table capacity to |dynamic_table_capacity|.
+  // |dynamic_table_capacity| must not exceed maximum dynamic table capacity.
+  // Also sends Set Dynamic Table Capacity instruction on encoder stream.
+  void SetDynamicTableCapacity(uint64_t dynamic_table_capacity);
+
+  // Set maximum number of blocked streams.
+  // Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
+  // Returns true if |maximum_blocked_streams| doesn't decrease current value.
+  // The setting is not changed when returning false.
+  bool SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
+
+  // QpackDecoderStreamReceiver::Delegate implementation
+  void OnInsertCountIncrement(uint64_t increment) override;
+  void OnHeaderAcknowledgement(QuicStreamId stream_id) override;
+  void OnStreamCancellation(QuicStreamId stream_id) override;
+  void OnErrorDetected(QuicErrorCode error_code,
+                       absl::string_view error_message) override;
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    encoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
+  }
+
+  QpackStreamReceiver* decoder_stream_receiver() {
+    return &decoder_stream_receiver_;
+  }
+
+  // True if any dynamic table entries have been referenced from a header block.
+  bool dynamic_table_entry_referenced() const {
+    return header_table_.dynamic_table_entry_referenced();
+  }
+
+  uint64_t maximum_blocked_streams() const { return maximum_blocked_streams_; }
+
+  uint64_t MaximumDynamicTableCapacity() const {
+    return header_table_.maximum_dynamic_table_capacity();
+  }
+
+ private:
+  friend class test::QpackEncoderPeer;
+
+  using Representation = QpackInstructionWithValues;
+  using Representations = std::vector<Representation>;
+
+  // Generate indexed header field representation
+  // and optionally update |*referred_indices|.
+  static Representation EncodeIndexedHeaderField(
+      bool is_static,
+      uint64_t index,
+      QpackBlockingManager::IndexSet* referred_indices);
+
+  // Generate literal header field with name reference representation
+  // and optionally update |*referred_indices|.
+  static Representation EncodeLiteralHeaderFieldWithNameReference(
+      bool is_static,
+      uint64_t index,
+      absl::string_view value,
+      QpackBlockingManager::IndexSet* referred_indices);
+
+  // Generate literal header field representation.
+  static Representation EncodeLiteralHeaderField(absl::string_view name,
+                                                 absl::string_view value);
+
+  // Performs first pass of two-pass encoding: represent each header field in
+  // |*header_list| as a reference to an existing entry, the name of an existing
+  // entry with a literal value, or a literal name and value pair.  Sends
+  // necessary instructions on the encoder stream coalesced in a single write.
+  // Records absolute indices of referred dynamic table entries in
+  // |*referred_indices|.  If |encoder_stream_sent_byte_count| is not null, then
+  // sets |*encoder_stream_sent_byte_count| to the number of bytes sent on the
+  // encoder stream to insert dynamic table entries.  Returns list of header
+  // field representations, with all dynamic table entries referred to with
+  // absolute indices.  Returned representation objects may have
+  // absl::string_views pointing to strings owned by |*header_list|.
+  Representations FirstPassEncode(
+      QuicStreamId stream_id,
+      const spdy::Http2HeaderBlock& header_list,
+      QpackBlockingManager::IndexSet* referred_indices,
+      QuicByteCount* encoder_stream_sent_byte_count);
+
+  // Performs second pass of two-pass encoding: serializes representations
+  // generated in first pass, transforming absolute indices of dynamic table
+  // entries to relative indices.
+  std::string SecondPassEncode(Representations representations,
+                               uint64_t required_insert_count) const;
+
+  DecoderStreamErrorDelegate* const decoder_stream_error_delegate_;
+  QpackDecoderStreamReceiver decoder_stream_receiver_;
+  QpackEncoderStreamSender encoder_stream_sender_;
+  QpackEncoderHeaderTable header_table_;
+  uint64_t maximum_blocked_streams_;
+  QpackBlockingManager blocking_manager_;
+  int header_list_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc
new file mode 100644
index 0000000..579efc2
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate)
+    : instruction_decoder_(QpackEncoderStreamLanguage(), this),
+      delegate_(delegate),
+      error_detected_(false) {
+  QUICHE_DCHECK(delegate_);
+}
+
+void QpackEncoderStreamReceiver::Decode(absl::string_view data) {
+  if (data.empty() || error_detected_) {
+    return;
+  }
+
+  instruction_decoder_.Decode(data);
+}
+
+bool QpackEncoderStreamReceiver::OnInstructionDecoded(
+    const QpackInstruction* instruction) {
+  if (instruction == InsertWithNameReferenceInstruction()) {
+    delegate_->OnInsertWithNameReference(instruction_decoder_.s_bit(),
+                                         instruction_decoder_.varint(),
+                                         instruction_decoder_.value());
+    return true;
+  }
+
+  if (instruction == InsertWithoutNameReferenceInstruction()) {
+    delegate_->OnInsertWithoutNameReference(instruction_decoder_.name(),
+                                            instruction_decoder_.value());
+    return true;
+  }
+
+  if (instruction == DuplicateInstruction()) {
+    delegate_->OnDuplicate(instruction_decoder_.varint());
+    return true;
+  }
+
+  QUICHE_DCHECK_EQ(instruction, SetDynamicTableCapacityInstruction());
+  delegate_->OnSetDynamicTableCapacity(instruction_decoder_.varint());
+  return true;
+}
+
+void QpackEncoderStreamReceiver::OnInstructionDecodingError(
+    QpackInstructionDecoder::ErrorCode error_code,
+    absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+
+  QuicErrorCode quic_error_code;
+  switch (error_code) {
+    case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE:
+      quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE;
+      break;
+    case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG:
+      quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG;
+      break;
+    case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR:
+      quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR;
+      break;
+    default:
+      quic_error_code = QUIC_INTERNAL_ERROR;
+  }
+
+  delegate_->OnErrorDetected(quic_error_code, error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_receiver.h b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.h
new file mode 100644
index 0000000..879c1b4
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_receiver.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_receiver.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class decodes data received on the encoder stream.
+class QUIC_EXPORT_PRIVATE QpackEncoderStreamReceiver
+    : public QpackInstructionDecoder::Delegate,
+      public QpackStreamReceiver {
+ public:
+  // An interface for handling instructions decoded from the encoder stream, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // 5.2.1. Insert With Name Reference
+    virtual void OnInsertWithNameReference(bool is_static,
+                                           uint64_t name_index,
+                                           absl::string_view value) = 0;
+    // 5.2.2. Insert Without Name Reference
+    virtual void OnInsertWithoutNameReference(absl::string_view name,
+                                              absl::string_view value) = 0;
+    // 5.2.3. Duplicate
+    virtual void OnDuplicate(uint64_t index) = 0;
+    // 5.2.4. Set Dynamic Table Capacity
+    virtual void OnSetDynamicTableCapacity(uint64_t capacity) = 0;
+    // Decoding error
+    virtual void OnErrorDetected(QuicErrorCode error_code,
+                                 absl::string_view error_message) = 0;
+  };
+
+  explicit QpackEncoderStreamReceiver(Delegate* delegate);
+  QpackEncoderStreamReceiver() = delete;
+  QpackEncoderStreamReceiver(const QpackEncoderStreamReceiver&) = delete;
+  QpackEncoderStreamReceiver& operator=(const QpackEncoderStreamReceiver&) =
+      delete;
+  ~QpackEncoderStreamReceiver() override = default;
+
+  // Implements QpackStreamReceiver::Decode().
+  // Decode data and call appropriate Delegate method after each decoded
+  // instruction.  Once an error occurs, Delegate::OnErrorDetected() is called,
+  // and all further data is ignored.
+  void Decode(absl::string_view data) override;
+
+  // QpackInstructionDecoder::Delegate implementation.
+  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
+  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
+                                  absl::string_view error_message) override;
+
+ private:
+  QpackInstructionDecoder instruction_decoder_;
+  Delegate* const delegate_;
+
+  // True if a decoding error has been detected.
+  bool error_detected_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_RECEIVER_H_
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_receiver_test.cc b/quiche/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
new file mode 100644
index 0000000..77103df
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using testing::Eq;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockDelegate : public QpackEncoderStreamReceiver::Delegate {
+ public:
+  ~MockDelegate() override = default;
+
+  MOCK_METHOD(void,
+              OnInsertWithNameReference,
+              (bool is_static, uint64_t name_index, absl::string_view value),
+              (override));
+  MOCK_METHOD(void,
+              OnInsertWithoutNameReference,
+              (absl::string_view name, absl::string_view value),
+              (override));
+  MOCK_METHOD(void, OnDuplicate, (uint64_t index), (override));
+  MOCK_METHOD(void, OnSetDynamicTableCapacity, (uint64_t capacity), (override));
+  MOCK_METHOD(void,
+              OnErrorDetected,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+class QpackEncoderStreamReceiverTest : public QuicTest {
+ protected:
+  QpackEncoderStreamReceiverTest() : stream_(&delegate_) {}
+  ~QpackEncoderStreamReceiverTest() override = default;
+
+  void Decode(absl::string_view data) { stream_.Decode(data); }
+  StrictMock<MockDelegate>* delegate() { return &delegate_; }
+
+ private:
+  QpackEncoderStreamReceiver stream_;
+  StrictMock<MockDelegate> delegate_;
+};
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) {
+  // Static, index fits in prefix, empty value.
+  EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 5, Eq("")));
+  // Static, index fits in prefix, Huffman encoded value.
+  EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 2, Eq("foo")));
+  // Not static, index does not fit in prefix, not Huffman encoded value.
+  EXPECT_CALL(*delegate(), OnInsertWithNameReference(false, 137, Eq("bar")));
+  // Value length does not fit in prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  EXPECT_CALL(*delegate(),
+              OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z'))));
+
+  Decode(absl::HexStringToBytes(
+      "c500"
+      "c28294e7"
+      "bf4a03626172"
+      "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceIndexTooLarge) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("bfffffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("c57fffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) {
+  // Empty name and value.
+  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq(""), Eq("")));
+  // Huffman encoded short strings.
+  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("bar"), Eq("bar")));
+  // Not Huffman encoded short strings.
+  EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("foo"), Eq("foo")));
+  // Not Huffman encoded long strings; length does not fit on prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  EXPECT_CALL(*delegate(),
+              OnInsertWithoutNameReference(Eq(std::string(31, 'Z')),
+                                           Eq(std::string(127, 'Z'))));
+
+  Decode(absl::HexStringToBytes(
+      "4000"
+      "4362617203626172"
+      "6294e78294e7"
+      "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f005a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
+}
+
+// Name Length value is too large for varint decoder to decode.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceNameTooLongForVarintDecoder) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("5fffffffffffffffffffff"));
+}
+
+// Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceNameExceedsLimit) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
+                              Eq("String literal too long.")));
+
+  Decode(absl::HexStringToBytes("5fffff7f"));
+}
+
+// Value Length value is too large for varint decoder to decode.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceValueTooLongForVarintDecoder) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff"));
+}
+
+// Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
+TEST_F(QpackEncoderStreamReceiverTest,
+       InsertWithoutNameReferenceValueExceedsLimit) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
+                              Eq("String literal too long.")));
+
+  Decode(absl::HexStringToBytes("436261727fffff7f"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, Duplicate) {
+  // Small index fits in prefix.
+  EXPECT_CALL(*delegate(), OnDuplicate(17));
+  // Large index requires two extension bytes.
+  EXPECT_CALL(*delegate(), OnDuplicate(500));
+
+  Decode(absl::HexStringToBytes("111fd503"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("1fffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) {
+  // Small capacity fits in prefix.
+  EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(17));
+  // Large capacity requires two extension bytes.
+  EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500));
+
+  Decode(absl::HexStringToBytes("313fd503"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
+                              Eq("Encoded integer too large.")));
+
+  Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) {
+  EXPECT_CALL(*delegate(),
+              OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR,
+                              Eq("Error in Huffman-encoded string.")));
+
+  Decode(absl::HexStringToBytes("c281ff"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc b/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc
new file mode 100644
index 0000000..e9e64b3
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+
+#include <cstddef>
+#include <limits>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// If QUIC stream bufferes more that this number of bytes,
+// CanWrite() will return false.
+constexpr uint64_t kMaxBytesBufferedByStream = 64 * 1024;
+
+}  // anonymous namespace
+
+QpackEncoderStreamSender::QpackEncoderStreamSender() : delegate_(nullptr) {}
+
+void QpackEncoderStreamSender::SendInsertWithNameReference(
+    bool is_static,
+    uint64_t name_index,
+    absl::string_view value) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::InsertWithNameReference(is_static, name_index,
+                                                          value),
+      &buffer_);
+}
+
+void QpackEncoderStreamSender::SendInsertWithoutNameReference(
+    absl::string_view name,
+    absl::string_view value) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::InsertWithoutNameReference(name, value),
+      &buffer_);
+}
+
+void QpackEncoderStreamSender::SendDuplicate(uint64_t index) {
+  instruction_encoder_.Encode(QpackInstructionWithValues::Duplicate(index),
+                              &buffer_);
+}
+
+void QpackEncoderStreamSender::SendSetDynamicTableCapacity(uint64_t capacity) {
+  instruction_encoder_.Encode(
+      QpackInstructionWithValues::SetDynamicTableCapacity(capacity), &buffer_);
+}
+
+bool QpackEncoderStreamSender::CanWrite() const {
+  return delegate_ && delegate_->NumBytesBuffered() + buffer_.size() <=
+                          kMaxBytesBufferedByStream;
+}
+
+void QpackEncoderStreamSender::Flush() {
+  if (buffer_.empty()) {
+    return;
+  }
+
+  delegate_->WriteStreamData(buffer_);
+  buffer_.clear();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_sender.h b/quiche/quic/core/qpack/qpack_encoder_stream_sender.h
new file mode 100644
index 0000000..8ad5a13
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_sender.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This class serializes instructions for transmission on the encoder stream.
+// Serialized instructions are buffered until Flush() is called.
+class QUIC_EXPORT_PRIVATE QpackEncoderStreamSender {
+ public:
+  QpackEncoderStreamSender();
+  QpackEncoderStreamSender(const QpackEncoderStreamSender&) = delete;
+  QpackEncoderStreamSender& operator=(const QpackEncoderStreamSender&) = delete;
+
+  // Methods for serializing and buffering instructions, see
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.2
+
+  // 5.2.1. Insert With Name Reference
+  void SendInsertWithNameReference(bool is_static,
+                                   uint64_t name_index,
+                                   absl::string_view value);
+  // 5.2.2. Insert Without Name Reference
+  void SendInsertWithoutNameReference(absl::string_view name,
+                                      absl::string_view value);
+  // 5.2.3. Duplicate
+  void SendDuplicate(uint64_t index);
+  // 5.2.4. Set Dynamic Table Capacity
+  void SendSetDynamicTableCapacity(uint64_t capacity);
+
+  // Returns number of bytes buffered by this object.
+  // There is no limit on how much data this object is willing to buffer.
+  QuicByteCount BufferedByteCount() const { return buffer_.size(); }
+
+  // Returns whether writing to the encoder stream is allowed.  Writing is
+  // disallowed if the amount of data buffered by the underlying stream exceeds
+  // a hardcoded limit, in order to limit memory consumption in case the encoder
+  // stream is blocked.  CanWrite() returning true does not mean that the
+  // encoder stream is not blocked, it just means the blocked data does not
+  // exceed the threshold.
+  bool CanWrite() const;
+
+  // Writes all buffered instructions on the encoder stream.
+  void Flush();
+
+  // delegate must be set if dynamic table capacity is not zero.
+  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
+    delegate_ = delegate;
+  }
+
+ private:
+  QpackStreamSenderDelegate* delegate_;
+  QpackInstructionEncoder instruction_encoder_;
+  std::string buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_STREAM_SENDER_H_
diff --git a/quiche/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/quiche/quic/core/qpack/qpack_encoder_stream_sender_test.cc
new file mode 100644
index 0000000..5f90e74
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_stream_sender_test.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
+
+#include "absl/strings/escaping.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::Eq;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QpackEncoderStreamSenderTest : public QuicTest {
+ protected:
+  QpackEncoderStreamSenderTest() {
+    stream_.set_qpack_stream_sender_delegate(&delegate_);
+  }
+  ~QpackEncoderStreamSenderTest() override = default;
+
+  StrictMock<MockQpackStreamSenderDelegate> delegate_;
+  QpackEncoderStreamSender stream_;
+};
+
+TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Static, index fits in prefix, empty value.
+  std::string expected_encoded_data = absl::HexStringToBytes("c500");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(true, 5, "");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Static, index fits in prefix, Huffman encoded value.
+  expected_encoded_data = absl::HexStringToBytes("c28294e7");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(true, 2, "foo");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Not static, index does not fit in prefix, not Huffman encoded value.
+  expected_encoded_data = absl::HexStringToBytes("bf4a03626172");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(false, 137, "bar");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Value length does not fit in prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  expected_encoded_data = absl::HexStringToBytes(
+      "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+}
+
+TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Empty name and value.
+  std::string expected_encoded_data = absl::HexStringToBytes("4000");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference("", "");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Huffman encoded short strings.
+  expected_encoded_data = absl::HexStringToBytes("6294e78294e7");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference("foo", "foo");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Not Huffman encoded short strings.
+  expected_encoded_data = absl::HexStringToBytes("4362617203626172");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference("bar", "bar");
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Not Huffman encoded long strings; length does not fit on prefix.
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  expected_encoded_data = absl::HexStringToBytes(
+      "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
+      "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+      "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
+                                         std::string(127, 'Z'));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+}
+
+TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Small index fits in prefix.
+  std::string expected_encoded_data = absl::HexStringToBytes("11");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendDuplicate(17);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+
+  // Large index requires two extension bytes.
+  expected_encoded_data = absl::HexStringToBytes("1fd503");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendDuplicate(500);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+}
+
+TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Small capacity fits in prefix.
+  std::string expected_encoded_data = absl::HexStringToBytes("31");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendSetDynamicTableCapacity(17);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+
+  // Large capacity requires two extension bytes.
+  expected_encoded_data = absl::HexStringToBytes("3fd503");
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  stream_.SendSetDynamicTableCapacity(500);
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+}
+
+// No writes should happen until Flush is called.
+TEST_F(QpackEncoderStreamSenderTest, Coalesce) {
+  // Insert entry with static name reference, empty value.
+  stream_.SendInsertWithNameReference(true, 5, "");
+
+  // Insert entry with static name reference, Huffman encoded value.
+  stream_.SendInsertWithNameReference(true, 2, "foo");
+
+  // Insert literal entry, Huffman encoded short strings.
+  stream_.SendInsertWithoutNameReference("foo", "foo");
+
+  // Duplicate entry.
+  stream_.SendDuplicate(17);
+
+  std::string expected_encoded_data = absl::HexStringToBytes(
+      "c500"          // Insert entry with static name reference.
+      "c28294e7"      // Insert entry with static name reference.
+      "6294e78294e7"  // Insert literal entry.
+      "11");          // Duplicate entry.
+
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
+  EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+}
+
+// No writes should happen if QpackEncoderStreamSender::Flush() is called
+// when the buffer is empty.
+TEST_F(QpackEncoderStreamSenderTest, FlushEmpty) {
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+  stream_.Flush();
+  EXPECT_EQ(0u, stream_.BufferedByteCount());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_encoder_test.cc b/quiche/quic/core/qpack/qpack_encoder_test.cc
new file mode 100644
index 0000000..ba3fa29
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_encoder_test.cc
@@ -0,0 +1,623 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+
+#include <limits>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// A number larger than kMaxBytesBufferedByStream in
+// qpack_encoder_stream_sender.cc.  Returning this value from NumBytesBuffered()
+// will instruct QpackEncoder not to generate any instructions for the encoder
+// stream.
+constexpr uint64_t kTooManyBytesBuffered = 1024 * 1024;
+
+class QpackEncoderTest : public QuicTest {
+ protected:
+  QpackEncoderTest()
+      : encoder_(&decoder_stream_error_delegate_),
+        encoder_stream_sent_byte_count_(0) {
+    encoder_.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
+    encoder_.SetMaximumBlockedStreams(1);
+  }
+
+  ~QpackEncoderTest() override = default;
+
+  std::string Encode(const spdy::Http2HeaderBlock& header_list) {
+    return encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list,
+                                     &encoder_stream_sent_byte_count_);
+  }
+
+  StrictMock<MockDecoderStreamErrorDelegate> decoder_stream_error_delegate_;
+  StrictMock<MockQpackStreamSenderDelegate> encoder_stream_sender_delegate_;
+  QpackEncoder encoder_;
+  QuicByteCount encoder_stream_sent_byte_count_;
+};
+
+TEST_F(QpackEncoderTest, Empty) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"), output);
+}
+
+TEST_F(QpackEncoderTest, EmptyName) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list[""] = "foo";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("0000208294e7"), output);
+}
+
+TEST_F(QpackEncoderTest, EmptyValue) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("00002a94e700"), output);
+}
+
+TEST_F(QpackEncoderTest, EmptyNameAndValue) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list[""] = "";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("00002000"), output);
+}
+
+TEST_F(QpackEncoderTest, Simple) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("00002a94e703626172"), output);
+}
+
+TEST_F(QpackEncoderTest, Multiple) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
+  header_list["ZZZZZZZ"] = std::string(127, 'Z');
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(
+      absl::HexStringToBytes(
+          "0000"                // prefix
+          "2a94e703626172"      // foo: bar
+          "27005a5a5a5a5a5a5a"  // 7 octet long header name, the smallest number
+                                // that does not fit on a 3-bit prefix.
+          "7f005a5a5a5a5a5a5a"  // 127 octet long header value, the smallest
+          "5a5a5a5a5a5a5a5a5a"  // number that does not fit on a 7-bit prefix.
+          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+          "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
+          "5a5a5a5a5a5a5a5a5a"),
+      output);
+}
+
+TEST_F(QpackEncoderTest, StaticTable) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "GET";
+    header_list["accept-encoding"] = "gzip, deflate, br";
+    header_list["location"] = "";
+
+    std::string output = Encode(header_list);
+    EXPECT_EQ(absl::HexStringToBytes("0000d1dfcc"), output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "POST";
+    header_list["accept-encoding"] = "compress";
+    header_list["location"] = "foo";
+
+    std::string output = Encode(header_list);
+    EXPECT_EQ(absl::HexStringToBytes("0000d45f108621e9aec2a11f5c8294e7"),
+              output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "TRACE";
+    header_list["accept-encoding"] = "";
+
+    std::string output = Encode(header_list);
+    EXPECT_EQ(absl::HexStringToBytes("00005f000554524143455f1000"), output);
+  }
+}
+
+TEST_F(QpackEncoderTest, DecoderStreamError) {
+  EXPECT_CALL(decoder_stream_error_delegate_,
+              OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
+                                   Eq("Encoded integer too large.")));
+
+  QpackEncoder encoder(&decoder_stream_error_delegate_);
+  encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
+  encoder.decoder_stream_receiver()->Decode(
+      absl::HexStringToBytes("ffffffffffffffffffffff"));
+}
+
+TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
+  std::string output = Encode(header_list);
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"            // prefix
+                                   "2a94e703626172"  // foo: bar
+                                   "2a94e703626172"  // foo: bar
+                                   "2a94e70362617a"  // foo: baz
+                                   ),
+            output);
+}
+
+TEST_F(QpackEncoderTest, ZeroInsertCountIncrement) {
+  // Encoder receives insert count increment with forbidden value 0.
+  EXPECT_CALL(
+      decoder_stream_error_delegate_,
+      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
+                           Eq("Invalid increment value 0.")));
+  encoder_.OnInsertCountIncrement(0);
+}
+
+TEST_F(QpackEncoderTest, TooLargeInsertCountIncrement) {
+  // Encoder receives insert count increment with value that increases Known
+  // Received Count to a value (one) which is larger than the number of dynamic
+  // table insertions sent (zero).
+  EXPECT_CALL(
+      decoder_stream_error_delegate_,
+      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT,
+                           Eq("Increment value 1 raises known received count "
+                              "to 1 exceeding inserted entry count 0")));
+  encoder_.OnInsertCountIncrement(1);
+}
+
+// Regression test for https://crbug.com/1014372.
+TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) {
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(&encoder_);
+
+  // Set dynamic table capacity large enough to hold one entry.
+  header_table->SetMaximumDynamicTableCapacity(4096);
+  header_table->SetDynamicTableCapacity(4096);
+  // Insert one entry into the header table.
+  header_table->InsertEntry("foo", "bar");
+
+  // Receive Insert Count Increment instruction with increment value 1.
+  encoder_.OnInsertCountIncrement(1);
+
+  // Receive Insert Count Increment instruction that overflows the known
+  // received count.  This must result in an error instead of a crash.
+  EXPECT_CALL(decoder_stream_error_delegate_,
+              OnDecoderStreamError(
+                  QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW,
+                  Eq("Insert Count Increment instruction causes overflow.")));
+  encoder_.OnInsertCountIncrement(std::numeric_limits<uint64_t>::max());
+}
+
+TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) {
+  // Encoder receives header acknowledgement for a stream on which no header
+  // block with dynamic table entries was ever sent.
+  EXPECT_CALL(
+      decoder_stream_error_delegate_,
+      OnDecoderStreamError(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT,
+                           Eq("Header Acknowledgement received for stream 0 "
+                              "with no outstanding header blocks.")));
+  encoder_.OnHeaderAcknowledgement(/* stream_id = */ 0);
+}
+
+TEST_F(QpackEncoderTest, DynamicTable) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list.AppendValueOrAddHeader("foo",
+                                     "baz");  // name matches dynamic entry
+  header_list["cookie"] = "baz";              // name matches static entry
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172"    // value "bar"
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+  EXPECT_EQ(absl::HexStringToBytes(
+                "0400"      // prefix
+                "828180"),  // dynamic entries with relative index 0, 1, and 2
+            Encode(header_list));
+
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+}
+
+// There is no room in the dynamic table after inserting the first entry.
+TEST_F(QpackEncoderTest, SmallDynamicTable) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
+  encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
+
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list.AppendValueOrAddHeader("foo",
+                                     "baz");  // name matches dynamic entry
+  header_list["cookie"] = "baz";              // name matches static entry
+  header_list["bar"] = "baz";                 // no match
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3f07");
+  // Insert one entry into the dynamic table.
+  std::string insert_entry = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172");  // value "bar"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(
+                  Eq(absl::StrCat(set_dyanamic_table_capacity, insert_entry))));
+
+  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
+                                   "80"    // dynamic entry 0
+                                   "40"    // reference to dynamic entry 0 name
+                                   "0362617a"  // with literal value "baz"
+                                   "55"  // reference to static entry 5 name
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            Encode(header_list));
+
+  EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, BlockedStream) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["foo"] = "bar";
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert one entry into the dynamic table.
+  std::string insert_entry1 = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172");  // value "bar"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entry1))));
+
+  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
+                                   "80"),  // dynamic entry 0
+            encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_);
+
+  // Stream 1 is blocked.  Stream 2 is not allowed to block.
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["foo"] = "bar";  // name and value match dynamic entry
+  header_list2.AppendValueOrAddHeader("foo",
+                                      "baz");  // name matches dynamic entry
+  header_list2["cookie"] = "baz";              // name matches static entry
+  header_list2["bar"] = "baz";                 // no match
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2a94e7"      // literal name "foo"
+                                   "03626172"    // with literal value "bar"
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "55"          // name of static entry 5
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // Peer acknowledges receipt of one dynamic table entry.
+  // Stream 1 is no longer blocked.
+  encoder_.OnInsertCountIncrement(1);
+
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a"    // value "baz"
+      "43"          // insert without name reference
+      "626172"      // name "bar"
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(insert_entries)));
+
+  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
+                                   "83828180"),  // dynamic entries
+            encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+
+  // Stream 3 is blocked.  Stream 4 is not allowed to block, but it can
+  // reference already acknowledged dynamic entry 0.
+  EXPECT_EQ(absl::HexStringToBytes("0200"        // prefix
+                                   "80"          // dynamic entry 0
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "2c21cfd4c5"  // literal name "cookie"
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // Peer acknowledges receipt of two more dynamic table entries.
+  // Stream 3 is still blocked.
+  encoder_.OnInsertCountIncrement(2);
+
+  // Stream 5 is not allowed to block, but it can reference already acknowledged
+  // dynamic entries 0, 1, and 2.
+  EXPECT_EQ(absl::HexStringToBytes("0400"        // prefix
+                                   "828180"      // dynamic entries
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
+            encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // Peer acknowledges decoding header block on stream 3.
+  // Stream 3 is not blocked any longer.
+  encoder_.OnHeaderAcknowledgement(3);
+
+  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
+                                   "83828180"),  // dynamic entries
+            encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2,
+                                      &encoder_stream_sent_byte_count_));
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, Draining) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["one"] = "foo";
+  header_list1["two"] = "foo";
+  header_list1["three"] = "foo";
+  header_list1["four"] = "foo";
+  header_list1["five"] = "foo";
+  header_list1["six"] = "foo";
+  header_list1["seven"] = "foo";
+  header_list1["eight"] = "foo";
+  header_list1["nine"] = "foo";
+  header_list1["ten"] = "foo";
+
+  // Make just enough room in the dynamic table for the header list plus the
+  // first entry duplicated.  This will ensure that the oldest entries are
+  // draining.
+  uint64_t maximum_dynamic_table_capacity = 0;
+  for (const auto& header_field : header_list1) {
+    maximum_dynamic_table_capacity +=
+        QpackEntry::Size(header_field.first, header_field.second);
+  }
+  maximum_dynamic_table_capacity += QpackEntry::Size("one", "foo");
+  encoder_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+  encoder_.SetDynamicTableCapacity(maximum_dynamic_table_capacity);
+
+  // Set Dynamic Table Capacity instruction and insert ten entries into the
+  // dynamic table.
+  EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(_));
+
+  EXPECT_EQ(absl::HexStringToBytes("0b00"                    // prefix
+                                   "89888786858483828180"),  // dynamic entries
+            Encode(header_list1));
+
+  // Entry is identical to oldest one, which is draining.  It will be
+  // duplicated and referenced.
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["one"] = "foo";
+
+  // Duplicate oldest entry.
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes("09"))));
+
+  EXPECT_EQ(absl::HexStringToBytes("0c00"  // prefix
+                                   "80"),  // most recent dynamic table entry
+            Encode(header_list2));
+
+  spdy::Http2HeaderBlock header_list3;
+  // Entry is identical to second oldest one, which is draining.  There is no
+  // room to duplicate, it will be encoded with string literals.
+  header_list3.AppendValueOrAddHeader("two", "foo");
+  // Entry has name identical to second oldest one, which is draining.  There is
+  // no room to insert new entry, it will be encoded with string literals.
+  header_list3.AppendValueOrAddHeader("two", "bar");
+
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2374776f"    // literal name "two"
+                                   "8294e7"      // literal value "foo"
+                                   "2374776f"    // literal name "two"
+                                   "03626172"),  // literal value "bar"
+            Encode(header_list3));
+}
+
+TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
+  encoder_.SetMaximumDynamicTableCapacity(1024);
+  encoder_.SetDynamicTableCapacity(30);
+
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(&encoder_);
+
+  EXPECT_EQ(1024u, header_table->maximum_dynamic_table_capacity());
+  EXPECT_EQ(30u, header_table->dynamic_table_capacity());
+}
+
+TEST_F(QpackEncoderTest, EncoderStreamWritesDisallowedThenAllowed) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(kTooManyBytesBuffered));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["foo"] = "bar";
+  header_list1.AppendValueOrAddHeader("foo", "baz");
+  header_list1["cookie"] = "baz";  // name matches static entry
+
+  // Encoder is not allowed to write on the encoder stream.
+  // No Set Dynamic Table Capacity or Insert instructions are sent.
+  // Headers are encoded as string literals.
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2a94e7"      // literal name "foo"
+                                   "03626172"    // with literal value "bar"
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "55"          // name of static entry 5
+                                   "0362617a"),  // with literal value "baz"
+            Encode(header_list1));
+
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+  // If number of bytes buffered by encoder stream goes under the threshold,
+  // then QpackEncoder will resume emitting encoder stream instructions.
+  ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["foo"] = "bar";
+  header_list2.AppendValueOrAddHeader("foo",
+                                      "baz");  // name matches dynamic entry
+  header_list2["cookie"] = "baz";              // name matches static entry
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172"    // value "bar"
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+  EXPECT_EQ(absl::HexStringToBytes(
+                "0400"      // prefix
+                "828180"),  // dynamic entries with relative index 0, 1, and 2
+            Encode(header_list2));
+
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, EncoderStreamWritesAllowedThenDisallowed) {
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(0));
+  encoder_.SetMaximumBlockedStreams(1);
+  encoder_.SetMaximumDynamicTableCapacity(4096);
+  encoder_.SetDynamicTableCapacity(4096);
+
+  spdy::Http2HeaderBlock header_list1;
+  header_list1["foo"] = "bar";
+  header_list1.AppendValueOrAddHeader("foo",
+                                      "baz");  // name matches dynamic entry
+  header_list1["cookie"] = "baz";              // name matches static entry
+
+  // Set Dynamic Table Capacity instruction.
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+  // Insert three entries into the dynamic table.
+  std::string insert_entries = absl::HexStringToBytes(
+      "62"          // insert without name reference
+      "94e7"        // Huffman-encoded name "foo"
+      "03626172"    // value "bar"
+      "80"          // insert with name reference, dynamic index 0
+      "0362617a"    // value "baz"
+      "c5"          // insert with name reference, static index 5
+      "0362617a");  // value "baz"
+  EXPECT_CALL(encoder_stream_sender_delegate_,
+              WriteStreamData(Eq(
+                  absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+  EXPECT_EQ(absl::HexStringToBytes(
+                "0400"      // prefix
+                "828180"),  // dynamic entries with relative index 0, 1, and 2
+            Encode(header_list1));
+
+  EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+
+  // If number of bytes buffered by encoder stream goes over the threshold,
+  // then QpackEncoder will stop emitting encoder stream instructions.
+  ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+  EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+      .WillRepeatedly(Return(kTooManyBytesBuffered));
+
+  spdy::Http2HeaderBlock header_list2;
+  header_list2["foo"] = "bar";  // matches previously inserted dynamic entry
+  header_list2["bar"] = "baz";
+  header_list2["cookie"] = "baz";  // name matches static entry
+
+  // Encoder is not allowed to write on the encoder stream.
+  // No Set Dynamic Table Capacity or Insert instructions are sent.
+  // Headers are encoded as string literals.
+  EXPECT_EQ(
+      absl::HexStringToBytes("0400"      // prefix
+                             "82"        // dynamic entry with relative index 0
+                             "23626172"  // literal name "bar"
+                             "0362617a"  // with literal value "baz"
+                             "80"),      // dynamic entry with relative index 2
+      Encode(header_list2));
+
+  EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_header_table.cc b/quiche/quic/core/qpack/qpack_header_table.cc
new file mode 100644
index 0000000..5ee41f6
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_header_table.cc
@@ -0,0 +1,240 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_static_table.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackEncoderHeaderTable::QpackEncoderHeaderTable()
+    : static_index_(ObtainQpackStaticTable().GetStaticIndex()),
+      static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()) {}
+
+uint64_t QpackEncoderHeaderTable::InsertEntry(absl::string_view name,
+                                              absl::string_view value) {
+  const uint64_t index =
+      QpackHeaderTableBase<QpackEncoderDynamicTable>::InsertEntry(name, value);
+
+  // Make name and value point to the new entry.
+  name = dynamic_entries().back().name();
+  value = dynamic_entries().back().value();
+
+  auto index_result = dynamic_index_.insert(
+      std::make_pair(QpackLookupEntry{name, value}, index));
+  if (!index_result.second) {
+    // An entry with the same name and value already exists.  It needs to be
+    // replaced, because |dynamic_index_| tracks the most recent entry for a
+    // given name and value.
+    QUICHE_DCHECK_GT(index, index_result.first->second);
+    dynamic_index_.erase(index_result.first);
+    auto result = dynamic_index_.insert(
+        std::make_pair(QpackLookupEntry{name, value}, index));
+    QUICHE_CHECK(result.second);
+  }
+
+  auto name_result = dynamic_name_index_.insert({name, index});
+  if (!name_result.second) {
+    // An entry with the same name already exists.  It needs to be replaced,
+    // because |dynamic_name_index_| tracks the most recent entry for a given
+    // name.
+    QUICHE_DCHECK_GT(index, name_result.first->second);
+    dynamic_name_index_.erase(name_result.first);
+    auto result = dynamic_name_index_.insert({name, index});
+    QUICHE_CHECK(result.second);
+  }
+
+  return index;
+}
+
+QpackEncoderHeaderTable::MatchType QpackEncoderHeaderTable::FindHeaderField(
+    absl::string_view name,
+    absl::string_view value,
+    bool* is_static,
+    uint64_t* index) const {
+  QpackLookupEntry query{name, value};
+
+  // Look for exact match in static table.
+  auto index_it = static_index_.find(query);
+  if (index_it != static_index_.end()) {
+    *index = index_it->second;
+    *is_static = true;
+    return MatchType::kNameAndValue;
+  }
+
+  // Look for exact match in dynamic table.
+  index_it = dynamic_index_.find(query);
+  if (index_it != dynamic_index_.end()) {
+    *index = index_it->second;
+    *is_static = false;
+    return MatchType::kNameAndValue;
+  }
+
+  // Look for name match in static table.
+  auto name_index_it = static_name_index_.find(name);
+  if (name_index_it != static_name_index_.end()) {
+    *index = name_index_it->second;
+    *is_static = true;
+    return MatchType::kName;
+  }
+
+  // Look for name match in dynamic table.
+  name_index_it = dynamic_name_index_.find(name);
+  if (name_index_it != dynamic_name_index_.end()) {
+    *index = name_index_it->second;
+    *is_static = false;
+    return MatchType::kName;
+  }
+
+  return MatchType::kNoMatch;
+}
+
+uint64_t QpackEncoderHeaderTable::MaxInsertSizeWithoutEvictingGivenEntry(
+    uint64_t index) const {
+  QUICHE_DCHECK_LE(dropped_entry_count(), index);
+
+  if (index > inserted_entry_count()) {
+    // All entries are allowed to be evicted.
+    return dynamic_table_capacity();
+  }
+
+  // Initialize to current available capacity.
+  uint64_t max_insert_size = dynamic_table_capacity() - dynamic_table_size();
+
+  uint64_t entry_index = dropped_entry_count();
+  for (const auto& entry : dynamic_entries()) {
+    if (entry_index >= index) {
+      break;
+    }
+    ++entry_index;
+    max_insert_size += entry.Size();
+  }
+
+  return max_insert_size;
+}
+
+uint64_t QpackEncoderHeaderTable::draining_index(
+    float draining_fraction) const {
+  QUICHE_DCHECK_LE(0.0, draining_fraction);
+  QUICHE_DCHECK_LE(draining_fraction, 1.0);
+
+  const uint64_t required_space = draining_fraction * dynamic_table_capacity();
+  uint64_t space_above_draining_index =
+      dynamic_table_capacity() - dynamic_table_size();
+
+  if (dynamic_entries().empty() ||
+      space_above_draining_index >= required_space) {
+    return dropped_entry_count();
+  }
+
+  auto it = dynamic_entries().begin();
+  uint64_t entry_index = dropped_entry_count();
+  while (space_above_draining_index < required_space) {
+    space_above_draining_index += it->Size();
+    ++it;
+    ++entry_index;
+    if (it == dynamic_entries().end()) {
+      return inserted_entry_count();
+    }
+  }
+
+  return entry_index;
+}
+
+void QpackEncoderHeaderTable::RemoveEntryFromEnd() {
+  const QpackEntry* const entry = &dynamic_entries().front();
+  const uint64_t index = dropped_entry_count();
+
+  auto index_it = dynamic_index_.find({entry->name(), entry->value()});
+  // Remove |dynamic_index_| entry only if it points to the same
+  // QpackEntry in dynamic_entries().
+  if (index_it != dynamic_index_.end() && index_it->second == index) {
+    dynamic_index_.erase(index_it);
+  }
+
+  auto name_it = dynamic_name_index_.find(entry->name());
+  // Remove |dynamic_name_index_| entry only if it points to the same
+  // QpackEntry in dynamic_entries().
+  if (name_it != dynamic_name_index_.end() && name_it->second == index) {
+    dynamic_name_index_.erase(name_it);
+  }
+
+  QpackHeaderTableBase<QpackEncoderDynamicTable>::RemoveEntryFromEnd();
+}
+
+QpackDecoderHeaderTable::QpackDecoderHeaderTable()
+    : static_entries_(ObtainQpackStaticTable().GetStaticEntries()) {}
+
+QpackDecoderHeaderTable::~QpackDecoderHeaderTable() {
+  for (auto& entry : observers_) {
+    entry.second->Cancel();
+  }
+}
+
+uint64_t QpackDecoderHeaderTable::InsertEntry(absl::string_view name,
+                                              absl::string_view value) {
+  const uint64_t index =
+      QpackHeaderTableBase<QpackDecoderDynamicTable>::InsertEntry(name, value);
+
+  // Notify and deregister observers whose threshold is met, if any.
+  while (!observers_.empty()) {
+    auto it = observers_.begin();
+    if (it->first > inserted_entry_count()) {
+      break;
+    }
+    Observer* observer = it->second;
+    observers_.erase(it);
+    observer->OnInsertCountReachedThreshold();
+  }
+
+  return index;
+}
+
+const QpackEntry* QpackDecoderHeaderTable::LookupEntry(bool is_static,
+                                                       uint64_t index) const {
+  if (is_static) {
+    if (index >= static_entries_.size()) {
+      return nullptr;
+    }
+
+    return &static_entries_[index];
+  }
+
+  if (index < dropped_entry_count()) {
+    return nullptr;
+  }
+
+  index -= dropped_entry_count();
+
+  if (index >= dynamic_entries().size()) {
+    return nullptr;
+  }
+
+  return &dynamic_entries()[index];
+}
+
+void QpackDecoderHeaderTable::RegisterObserver(uint64_t required_insert_count,
+                                               Observer* observer) {
+  QUICHE_DCHECK_GT(required_insert_count, 0u);
+  observers_.insert({required_insert_count, observer});
+}
+
+void QpackDecoderHeaderTable::UnregisterObserver(uint64_t required_insert_count,
+                                                 Observer* observer) {
+  auto it = observers_.lower_bound(required_insert_count);
+  while (it != observers_.end() && it->first == required_insert_count) {
+    if (it->second == observer) {
+      observers_.erase(it);
+      return;
+    }
+    ++it;
+  }
+
+  // |observer| must have been registered.
+  QUIC_NOTREACHED();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_header_table.h b/quiche/quic/core/qpack/qpack_header_table.h
new file mode 100644
index 0000000..75b66a4
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_header_table.h
@@ -0,0 +1,346 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
+
+#include <cstdint>
+#include <deque>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+
+namespace quic {
+
+using QpackEntry = spdy::HpackEntry;
+using QpackLookupEntry = spdy::HpackLookupEntry;
+constexpr size_t kQpackEntrySizeOverhead = spdy::kHpackEntrySizeOverhead;
+
+// Encoder needs pointer stability for |dynamic_index_| and
+// |dynamic_name_index_|.  However, it does not need random access.
+// TODO(b/182349990): Change to a more memory efficient container.
+using QpackEncoderDynamicTable = std::deque<QpackEntry>;
+
+// Decoder needs random access for LookupEntry().
+// However, it does not need pointer stability.
+using QpackDecoderDynamicTable = quiche::QuicheCircularDeque<QpackEntry>;
+
+// This is a base class for encoder and decoder classes that manage the QPACK
+// static and dynamic tables.  For dynamic entries, it only has a concept of
+// absolute indices.  The caller needs to perform the necessary transformations
+// to and from relative indices and post-base indices.
+template <typename DynamicEntryTable>
+class QUIC_EXPORT_PRIVATE QpackHeaderTableBase {
+ public:
+  QpackHeaderTableBase();
+  QpackHeaderTableBase(const QpackHeaderTableBase&) = delete;
+  QpackHeaderTableBase& operator=(const QpackHeaderTableBase&) = delete;
+
+  virtual ~QpackHeaderTableBase() = default;
+
+  // Returns whether an entry with |name| and |value| has a size (including
+  // overhead) that is smaller than or equal to the capacity of the dynamic
+  // table.
+  bool EntryFitsDynamicTableCapacity(absl::string_view name,
+                                     absl::string_view value) const;
+
+  // Inserts (name, value) into the dynamic table.  Entry must not be larger
+  // than the capacity of the dynamic table.  May evict entries.  |name| and
+  // |value| are copied first, therefore it is safe for them to point to an
+  // entry in the dynamic table, even if it is about to be evicted, or even if
+  // the underlying container might move entries around when resizing for
+  // insertion.
+  // Returns the absolute index of the inserted dynamic table entry.
+  virtual uint64_t InsertEntry(absl::string_view name, absl::string_view value);
+
+  // Change dynamic table capacity to |capacity|.  Returns true on success.
+  // Returns false is |capacity| exceeds maximum dynamic table capacity.
+  bool SetDynamicTableCapacity(uint64_t capacity);
+
+  // Set |maximum_dynamic_table_capacity_|.  The initial value is zero.  The
+  // final value is determined by the decoder and is sent to the encoder as
+  // SETTINGS_HEADER_TABLE_SIZE.  Therefore in the decoding context the final
+  // value can be set upon connection establishment, whereas in the encoding
+  // context it can be set when the SETTINGS frame is received.
+  // This method must only be called at most once.
+  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
+  // or if it doesn't change current value. The setting is not changed when
+  // returning false.
+  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+
+  uint64_t dynamic_table_size() const { return dynamic_table_size_; }
+  uint64_t dynamic_table_capacity() const { return dynamic_table_capacity_; }
+  uint64_t maximum_dynamic_table_capacity() const {
+    return maximum_dynamic_table_capacity_;
+  }
+  uint64_t max_entries() const { return max_entries_; }
+
+  // The number of entries inserted to the dynamic table (including ones that
+  // were dropped since).  Used for relative indexing on the encoder stream.
+  uint64_t inserted_entry_count() const {
+    return dynamic_entries_.size() + dropped_entry_count_;
+  }
+
+  // The number of entries dropped from the dynamic table.
+  uint64_t dropped_entry_count() const { return dropped_entry_count_; }
+
+  void set_dynamic_table_entry_referenced() {
+    dynamic_table_entry_referenced_ = true;
+  }
+  bool dynamic_table_entry_referenced() const {
+    return dynamic_table_entry_referenced_;
+  }
+
+ protected:
+  // Removes a single entry from the end of the dynamic table, updates
+  // |dynamic_table_size_| and |dropped_entry_count_|.
+  virtual void RemoveEntryFromEnd();
+
+  const DynamicEntryTable& dynamic_entries() const { return dynamic_entries_; }
+
+ private:
+  // Evict entries from the dynamic table until table size is less than or equal
+  // to |capacity|.
+  void EvictDownToCapacity(uint64_t capacity);
+
+  // Dynamic Table entries.
+  DynamicEntryTable dynamic_entries_;
+
+  // Size of the dynamic table.  This is the sum of the size of its entries.
+  uint64_t dynamic_table_size_;
+
+  // Dynamic Table Capacity is the maximum allowed value of
+  // |dynamic_table_size_|.  Entries are evicted if necessary before inserting a
+  // new entry to ensure that dynamic table size never exceeds capacity.
+  // Initial value is |maximum_dynamic_table_capacity_|.  Capacity can be
+  // changed by the encoder, as long as it does not exceed
+  // |maximum_dynamic_table_capacity_|.
+  uint64_t dynamic_table_capacity_;
+
+  // Maximum allowed value of |dynamic_table_capacity|.  The initial value is
+  // zero.  Can be changed by SetMaximumDynamicTableCapacity().
+  uint64_t maximum_dynamic_table_capacity_;
+
+  // MaxEntries, see Section 3.2.2.  Calculated based on
+  // |maximum_dynamic_table_capacity_|.  Used on request streams to encode and
+  // decode Required Insert Count.
+  uint64_t max_entries_;
+
+  // The number of entries dropped from the dynamic table.
+  uint64_t dropped_entry_count_;
+
+  // True if any dynamic table entries have been referenced from a header block.
+  // Set directly by the encoder or decoder.  Used for stats.
+  bool dynamic_table_entry_referenced_;
+};
+
+template <typename DynamicEntryTable>
+QpackHeaderTableBase<DynamicEntryTable>::QpackHeaderTableBase()
+    : dynamic_table_size_(0),
+      dynamic_table_capacity_(0),
+      maximum_dynamic_table_capacity_(0),
+      max_entries_(0),
+      dropped_entry_count_(0),
+      dynamic_table_entry_referenced_(false) {}
+
+template <typename DynamicEntryTable>
+bool QpackHeaderTableBase<DynamicEntryTable>::EntryFitsDynamicTableCapacity(
+    absl::string_view name,
+    absl::string_view value) const {
+  return QpackEntry::Size(name, value) <= dynamic_table_capacity_;
+}
+
+template <typename DynamicEntryTable>
+uint64_t QpackHeaderTableBase<DynamicEntryTable>::InsertEntry(
+    absl::string_view name,
+    absl::string_view value) {
+  QUICHE_DCHECK(EntryFitsDynamicTableCapacity(name, value));
+
+  const uint64_t index = dropped_entry_count_ + dynamic_entries_.size();
+
+  // Copy name and value before modifying the container, because evicting
+  // entries or even inserting a new one might invalidate |name| or |value| if
+  // they point to an entry.
+  QpackEntry new_entry((std::string(name)), (std::string(value)));
+  const size_t entry_size = new_entry.Size();
+
+  EvictDownToCapacity(dynamic_table_capacity_ - entry_size);
+
+  dynamic_table_size_ += entry_size;
+  dynamic_entries_.push_back(std::move(new_entry));
+
+  return index;
+}
+
+template <typename DynamicEntryTable>
+bool QpackHeaderTableBase<DynamicEntryTable>::SetDynamicTableCapacity(
+    uint64_t capacity) {
+  if (capacity > maximum_dynamic_table_capacity_) {
+    return false;
+  }
+
+  dynamic_table_capacity_ = capacity;
+  EvictDownToCapacity(capacity);
+
+  QUICHE_DCHECK_LE(dynamic_table_size_, dynamic_table_capacity_);
+
+  return true;
+}
+
+template <typename DynamicEntryTable>
+bool QpackHeaderTableBase<DynamicEntryTable>::SetMaximumDynamicTableCapacity(
+    uint64_t maximum_dynamic_table_capacity) {
+  if (maximum_dynamic_table_capacity_ == 0) {
+    maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
+    max_entries_ = maximum_dynamic_table_capacity / 32;
+    return true;
+  }
+  // If the value is already set, it should not be changed.
+  return maximum_dynamic_table_capacity == maximum_dynamic_table_capacity_;
+}
+
+template <typename DynamicEntryTable>
+void QpackHeaderTableBase<DynamicEntryTable>::RemoveEntryFromEnd() {
+  const uint64_t entry_size = dynamic_entries_.front().Size();
+  QUICHE_DCHECK_GE(dynamic_table_size_, entry_size);
+  dynamic_table_size_ -= entry_size;
+
+  dynamic_entries_.pop_front();
+  ++dropped_entry_count_;
+}
+
+template <typename DynamicEntryTable>
+void QpackHeaderTableBase<DynamicEntryTable>::EvictDownToCapacity(
+    uint64_t capacity) {
+  while (dynamic_table_size_ > capacity) {
+    QUICHE_DCHECK(!dynamic_entries_.empty());
+    RemoveEntryFromEnd();
+  }
+}
+
+class QUIC_EXPORT_PRIVATE QpackEncoderHeaderTable
+    : public QpackHeaderTableBase<QpackEncoderDynamicTable> {
+ public:
+  // Result of header table lookup.
+  enum class MatchType { kNameAndValue, kName, kNoMatch };
+
+  QpackEncoderHeaderTable();
+  ~QpackEncoderHeaderTable() override = default;
+
+  uint64_t InsertEntry(absl::string_view name,
+                       absl::string_view value) override;
+
+  // Returns the absolute index of an entry with matching name and value if such
+  // exists, otherwise one with matching name is such exists.  |index| is zero
+  // based for both the static and the dynamic table.
+  MatchType FindHeaderField(absl::string_view name,
+                            absl::string_view value,
+                            bool* is_static,
+                            uint64_t* index) const;
+
+  // Returns the size of the largest entry that could be inserted into the
+  // dynamic table without evicting entry |index|.  |index| might be larger than
+  // inserted_entry_count(), in which case the capacity of the table is
+  // returned.  |index| must not be smaller than dropped_entry_count().
+  uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const;
+
+  // Returns the draining index described at
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#avoiding-blocked-insertions.
+  // Entries with an index larger than or equal to the draining index take up
+  // approximately |1.0 - draining_fraction| of dynamic table capacity.  The
+  // remaining capacity is taken up by draining entries and unused space.
+  // The returned index might not be the index of a valid entry.
+  uint64_t draining_index(float draining_fraction) const;
+
+ protected:
+  void RemoveEntryFromEnd() override;
+
+ private:
+  using NameValueToEntryMap = spdy::HpackHeaderTable::NameValueToEntryMap;
+  using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap;
+
+  // Static Table
+
+  // |static_index_| and |static_name_index_| are owned by QpackStaticTable
+  // singleton.
+
+  // Tracks the unique static entry for a given header name and value.
+  const NameValueToEntryMap& static_index_;
+
+  // Tracks the first static entry for a given header name.
+  const NameToEntryMap& static_name_index_;
+
+  // Dynamic Table
+
+  // An unordered set of QpackEntry pointers with a comparison operator that
+  // only cares about name and value.  This allows fast lookup of the most
+  // recently inserted dynamic entry for a given header name and value pair.
+  // Entries point to entries owned by |QpackHeaderTableBase::dynamic_entries_|.
+  NameValueToEntryMap dynamic_index_;
+
+  // An unordered map of QpackEntry pointers keyed off header name.  This allows
+  // fast lookup of the most recently inserted dynamic entry for a given header
+  // name.  Entries point to entries owned by
+  // |QpackHeaderTableBase::dynamic_entries_|.
+  NameToEntryMap dynamic_name_index_;
+};
+
+class QUIC_EXPORT_PRIVATE QpackDecoderHeaderTable
+    : public QpackHeaderTableBase<QpackDecoderDynamicTable> {
+ public:
+  // Observer interface for dynamic table insertion.
+  class QUIC_EXPORT_PRIVATE Observer {
+   public:
+    virtual ~Observer() = default;
+
+    // Called when inserted_entry_count() reaches the threshold the Observer was
+    // registered with.  After this call the Observer automatically gets
+    // deregistered.
+    virtual void OnInsertCountReachedThreshold() = 0;
+
+    // Called when QpackDecoderHeaderTable is destroyed to let the Observer know
+    // that it must not call UnregisterObserver().
+    virtual void Cancel() = 0;
+  };
+
+  QpackDecoderHeaderTable();
+  ~QpackDecoderHeaderTable() override;
+
+  uint64_t InsertEntry(absl::string_view name,
+                       absl::string_view value) override;
+
+  // Returns the entry at absolute index |index| from the static or dynamic
+  // table according to |is_static|.  |index| is zero based for both the static
+  // and the dynamic table.  The returned pointer is valid until the entry is
+  // evicted, even if other entries are inserted into the dynamic table.
+  // Returns nullptr if entry does not exist.
+  const QpackEntry* LookupEntry(bool is_static, uint64_t index) const;
+
+  // Register an observer to be notified when inserted_entry_count() reaches
+  // |required_insert_count|.  After the notification, |observer| automatically
+  // gets unregistered.  Each observer must only be registered at most once.
+  void RegisterObserver(uint64_t required_insert_count, Observer* observer);
+
+  // Unregister previously registered observer.  Must be called with the same
+  // |required_insert_count| value that |observer| was registered with.  Must be
+  // called before an observer still waiting for notification is destroyed,
+  // unless QpackDecoderHeaderTable already called Observer::Cancel(), in which
+  // case this method must not be called.
+  void UnregisterObserver(uint64_t required_insert_count, Observer* observer);
+
+ private:
+  // Static Table entries.  Owned by QpackStaticTable singleton.
+  using StaticEntryTable = spdy::HpackHeaderTable::StaticEntryTable;
+  const StaticEntryTable& static_entries_;
+
+  // Observers waiting to be notified, sorted by required insert count.
+  std::multimap<uint64_t, Observer*> observers_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
diff --git a/quiche/quic/core/qpack/qpack_header_table_test.cc b/quiche/quic/core/qpack/qpack_header_table_test.cc
new file mode 100644
index 0000000..82dd39b
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_header_table_test.cc
@@ -0,0 +1,655 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_static_table.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+
+using ::testing::Mock;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const uint64_t kMaximumDynamicTableCapacityForTesting = 1024 * 1024;
+
+template <typename T>
+class QpackHeaderTableTest : public QuicTest {
+ protected:
+  ~QpackHeaderTableTest() override = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(table_.SetMaximumDynamicTableCapacity(
+        kMaximumDynamicTableCapacityForTesting));
+    ASSERT_TRUE(
+        table_.SetDynamicTableCapacity(kMaximumDynamicTableCapacityForTesting));
+  }
+
+  bool EntryFitsDynamicTableCapacity(absl::string_view name,
+                                     absl::string_view value) const {
+    return table_.EntryFitsDynamicTableCapacity(name, value);
+  }
+
+  void InsertEntry(absl::string_view name, absl::string_view value) {
+    table_.InsertEntry(name, value);
+  }
+
+  bool SetDynamicTableCapacity(uint64_t capacity) {
+    return table_.SetDynamicTableCapacity(capacity);
+  }
+
+  uint64_t max_entries() const { return table_.max_entries(); }
+  uint64_t inserted_entry_count() const {
+    return table_.inserted_entry_count();
+  }
+  uint64_t dropped_entry_count() const { return table_.dropped_entry_count(); }
+
+  T table_;
+};
+
+using MyTypes =
+    ::testing::Types<QpackEncoderHeaderTable, QpackDecoderHeaderTable>;
+TYPED_TEST_SUITE(QpackHeaderTableTest, MyTypes);
+
+// MaxEntries is determined by maximum dynamic table capacity,
+// which is set at construction time.
+TYPED_TEST(QpackHeaderTableTest, MaxEntries) {
+  TypeParam table1;
+  table1.SetMaximumDynamicTableCapacity(1024);
+  EXPECT_EQ(32u, table1.max_entries());
+
+  TypeParam table2;
+  table2.SetMaximumDynamicTableCapacity(500);
+  EXPECT_EQ(15u, table2.max_entries());
+}
+
+TYPED_TEST(QpackHeaderTableTest, SetDynamicTableCapacity) {
+  // Dynamic table capacity does not affect MaxEntries.
+  EXPECT_TRUE(this->SetDynamicTableCapacity(1024));
+  EXPECT_EQ(32u * 1024, this->max_entries());
+
+  EXPECT_TRUE(this->SetDynamicTableCapacity(500));
+  EXPECT_EQ(32u * 1024, this->max_entries());
+
+  // Dynamic table capacity cannot exceed maximum dynamic table capacity.
+  EXPECT_FALSE(this->SetDynamicTableCapacity(
+      2 * kMaximumDynamicTableCapacityForTesting));
+}
+
+TYPED_TEST(QpackHeaderTableTest, EntryFitsDynamicTableCapacity) {
+  EXPECT_TRUE(this->SetDynamicTableCapacity(39));
+
+  EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar"));
+  EXPECT_TRUE(this->EntryFitsDynamicTableCapacity("foo", "bar2"));
+  EXPECT_FALSE(this->EntryFitsDynamicTableCapacity("foo", "bar12"));
+}
+
+class QpackEncoderHeaderTableTest
+    : public QpackHeaderTableTest<QpackEncoderHeaderTable> {
+ protected:
+  ~QpackEncoderHeaderTableTest() override = default;
+
+  void ExpectMatch(absl::string_view name,
+                   absl::string_view value,
+                   QpackEncoderHeaderTable::MatchType expected_match_type,
+                   bool expected_is_static,
+                   uint64_t expected_index) const {
+    // Initialize outparams to a value different from the expected to ensure
+    // that FindHeaderField() sets them.
+    bool is_static = !expected_is_static;
+    uint64_t index = expected_index + 1;
+
+    QpackEncoderHeaderTable::MatchType matchtype =
+        table_.FindHeaderField(name, value, &is_static, &index);
+
+    EXPECT_EQ(expected_match_type, matchtype) << name << ": " << value;
+    EXPECT_EQ(expected_is_static, is_static) << name << ": " << value;
+    EXPECT_EQ(expected_index, index) << name << ": " << value;
+  }
+
+  void ExpectNoMatch(absl::string_view name, absl::string_view value) const {
+    bool is_static = false;
+    uint64_t index = 0;
+
+    QpackEncoderHeaderTable::MatchType matchtype =
+        table_.FindHeaderField(name, value, &is_static, &index);
+
+    EXPECT_EQ(QpackEncoderHeaderTable::MatchType::kNoMatch, matchtype)
+        << name << ": " << value;
+  }
+
+  uint64_t MaxInsertSizeWithoutEvictingGivenEntry(uint64_t index) const {
+    return table_.MaxInsertSizeWithoutEvictingGivenEntry(index);
+  }
+
+  uint64_t draining_index(float draining_fraction) const {
+    return table_.draining_index(draining_fraction);
+  }
+};
+
+TEST_F(QpackEncoderHeaderTableTest, FindStaticHeaderField) {
+  // A header name that has multiple entries with different values.
+  ExpectMatch(":method", "GET",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
+
+  ExpectMatch(":method", "POST",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 20u);
+
+  ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
+              true, 15u);
+
+  // A header name that has a single entry with non-empty value.
+  ExpectMatch("accept-encoding", "gzip, deflate, br",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 31u);
+
+  ExpectMatch("accept-encoding", "compress",
+              QpackEncoderHeaderTable::MatchType::kName, true, 31u);
+
+  ExpectMatch("accept-encoding", "", QpackEncoderHeaderTable::MatchType::kName,
+              true, 31u);
+
+  // A header name that has a single entry with empty value.
+  ExpectMatch("location", "", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              true, 12u);
+
+  ExpectMatch("location", "foo", QpackEncoderHeaderTable::MatchType::kName,
+              true, 12u);
+
+  // No matching header name.
+  ExpectNoMatch("foo", "");
+  ExpectNoMatch("foo", "bar");
+}
+
+TEST_F(QpackEncoderHeaderTableTest, FindDynamicHeaderField) {
+  // Dynamic table is initially entry.
+  ExpectNoMatch("foo", "bar");
+  ExpectNoMatch("foo", "baz");
+
+  // Insert one entry.
+  InsertEntry("foo", "bar");
+
+  // Match name and value.
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              false, 0u);
+
+  // Match name only.
+  ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
+              0u);
+
+  // Insert an identical entry.  FindHeaderField() should return the index of
+  // the most recently inserted matching entry.
+  InsertEntry("foo", "bar");
+
+  // Match name and value.
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              false, 1u);
+
+  // Match name only.
+  ExpectMatch("foo", "baz", QpackEncoderHeaderTable::MatchType::kName, false,
+              1u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, FindHeaderFieldPrefersStaticTable) {
+  // Insert an entry to the dynamic table that exists in the static table.
+  InsertEntry(":method", "GET");
+
+  // FindHeaderField() prefers static table if both have name-and-value match.
+  ExpectMatch(":method", "GET",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, true, 17u);
+
+  // FindHeaderField() prefers static table if both have name match but no value
+  // match, and prefers the first entry with matching name.
+  ExpectMatch(":method", "TRACE", QpackEncoderHeaderTable::MatchType::kName,
+              true, 15u);
+
+  // Add new entry to the dynamic table.
+  InsertEntry(":method", "TRACE");
+
+  // FindHeaderField prefers name-and-value match in dynamic table over name
+  // only match in static table.
+  ExpectMatch(":method", "TRACE",
+              QpackEncoderHeaderTable::MatchType::kNameAndValue, false, 1u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictByInsertion) {
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(1u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 0u);
+
+  // Inserting second entry evicts the first one.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoMatch("foo", "bar");
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictByUpdateTableSize) {
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 0u);
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoMatch("foo", "bar");
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+
+  EXPECT_TRUE(SetDynamicTableCapacity(20));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(2u, dropped_entry_count());
+
+  ExpectNoMatch("foo", "bar");
+  ExpectNoMatch("baz", "qux");
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfIdentical) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert same entry twice.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  // Find most recently inserted entry.
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectMatch("foo", "bar", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 1u);
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 2u);
+}
+
+TEST_F(QpackEncoderHeaderTableTest, EvictOldestOfSameName) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert two entries with same name but different values.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "baz");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  // Find most recently inserted entry with matching name.
+  ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
+              /* expected_is_static = */ false, 1u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectMatch("foo", "foo", QpackEncoderHeaderTable::MatchType::kName,
+              /* expected_is_static = */ false, 1u);
+  ExpectMatch("baz", "qux", QpackEncoderHeaderTable::MatchType::kNameAndValue,
+              /* expected_is_static = */ false, 2u);
+}
+
+// Returns the size of the largest entry that could be inserted into the
+// dynamic table without evicting entry |index|.
+TEST_F(QpackEncoderHeaderTableTest, MaxInsertSizeWithoutEvictingGivenEntry) {
+  const uint64_t dynamic_table_capacity = 100;
+  EXPECT_TRUE(SetDynamicTableCapacity(dynamic_table_capacity));
+
+  // Empty table can take an entry up to its capacity.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(0));
+
+  const uint64_t entry_size1 = QpackEntry::Size("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(dynamic_table_capacity - entry_size1,
+            MaxInsertSizeWithoutEvictingGivenEntry(0));
+  // Table can take an entry up to its capacity if all entries are allowed to be
+  // evicted.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(1));
+
+  const uint64_t entry_size2 = QpackEntry::Size("baz", "foobar");
+  InsertEntry("baz", "foobar");
+  // Table can take an entry up to its capacity if all entries are allowed to be
+  // evicted.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(2));
+  // Second entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size2,
+            MaxInsertSizeWithoutEvictingGivenEntry(1));
+  // First and second entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size2 - entry_size1,
+            MaxInsertSizeWithoutEvictingGivenEntry(0));
+
+  // Third entry evicts first one.
+  const uint64_t entry_size3 = QpackEntry::Size("last", "entry");
+  InsertEntry("last", "entry");
+  EXPECT_EQ(1u, dropped_entry_count());
+  // Table can take an entry up to its capacity if all entries are allowed to be
+  // evicted.
+  EXPECT_EQ(dynamic_table_capacity, MaxInsertSizeWithoutEvictingGivenEntry(3));
+  // Third entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size3,
+            MaxInsertSizeWithoutEvictingGivenEntry(2));
+  // Second and third entry must stay.
+  EXPECT_EQ(dynamic_table_capacity - entry_size3 - entry_size2,
+            MaxInsertSizeWithoutEvictingGivenEntry(1));
+}
+
+TEST_F(QpackEncoderHeaderTableTest, DrainingIndex) {
+  EXPECT_TRUE(SetDynamicTableCapacity(4 * QpackEntry::Size("foo", "bar")));
+
+  // Empty table: no draining entry.
+  EXPECT_EQ(0u, draining_index(0.0));
+  EXPECT_EQ(0u, draining_index(1.0));
+
+  // Table with one entry.
+  InsertEntry("foo", "bar");
+  // Any entry can be referenced if none of the table is draining.
+  EXPECT_EQ(0u, draining_index(0.0));
+  // No entry can be referenced if all of the table is draining.
+  EXPECT_EQ(1u, draining_index(1.0));
+
+  // Table with two entries is at half capacity.
+  InsertEntry("foo", "bar");
+  // Any entry can be referenced if at most half of the table is draining,
+  // because current entries only take up half of total capacity.
+  EXPECT_EQ(0u, draining_index(0.0));
+  EXPECT_EQ(0u, draining_index(0.5));
+  // No entry can be referenced if all of the table is draining.
+  EXPECT_EQ(2u, draining_index(1.0));
+
+  // Table with four entries is full.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  // Any entry can be referenced if none of the table is draining.
+  EXPECT_EQ(0u, draining_index(0.0));
+  // In a full table with identically sized entries, |draining_fraction| of all
+  // entries are draining.
+  EXPECT_EQ(2u, draining_index(0.5));
+  // No entry can be referenced if all of the table is draining.
+  EXPECT_EQ(4u, draining_index(1.0));
+}
+
+class MockObserver : public QpackDecoderHeaderTable::Observer {
+ public:
+  ~MockObserver() override = default;
+
+  MOCK_METHOD(void, OnInsertCountReachedThreshold, (), (override));
+  MOCK_METHOD(void, Cancel, (), (override));
+};
+
+class QpackDecoderHeaderTableTest
+    : public QpackHeaderTableTest<QpackDecoderHeaderTable> {
+ protected:
+  ~QpackDecoderHeaderTableTest() override = default;
+
+  void ExpectEntryAtIndex(bool is_static,
+                          uint64_t index,
+                          absl::string_view expected_name,
+                          absl::string_view expected_value) const {
+    const auto* entry = table_.LookupEntry(is_static, index);
+    ASSERT_TRUE(entry);
+    EXPECT_EQ(expected_name, entry->name());
+    EXPECT_EQ(expected_value, entry->value());
+  }
+
+  void ExpectNoEntryAtIndex(bool is_static, uint64_t index) const {
+    EXPECT_FALSE(table_.LookupEntry(is_static, index));
+  }
+
+  void RegisterObserver(uint64_t required_insert_count,
+                        QpackDecoderHeaderTable::Observer* observer) {
+    table_.RegisterObserver(required_insert_count, observer);
+  }
+
+  void UnregisterObserver(uint64_t required_insert_count,
+                          QpackDecoderHeaderTable::Observer* observer) {
+    table_.UnregisterObserver(required_insert_count, observer);
+  }
+};
+
+TEST_F(QpackDecoderHeaderTableTest, LookupStaticEntry) {
+  ExpectEntryAtIndex(/* is_static = */ true, 0, ":authority", "");
+
+  ExpectEntryAtIndex(/* is_static = */ true, 1, ":path", "/");
+
+  // 98 is the last entry.
+  ExpectEntryAtIndex(/* is_static = */ true, 98, "x-frame-options",
+                     "sameorigin");
+
+  ASSERT_EQ(99u, QpackStaticTableVector().size());
+  ExpectNoEntryAtIndex(/* is_static = */ true, 99);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, InsertAndLookupDynamicEntry) {
+  // Dynamic table is initially entry.
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+
+  // Insert one entry.
+  InsertEntry("foo", "bar");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+
+  // Insert a different entry.
+  InsertEntry("baz", "bing");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+
+  // Insert an entry identical to the most recently inserted one.
+  InsertEntry("baz", "bing");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0, "foo", "bar");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 1, "baz", "bing");
+
+  ExpectEntryAtIndex(/* is_static = */ false, 2, "baz", "bing");
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 3);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictByInsertion) {
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(1u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+
+  // Inserting second entry evicts the first one.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictByUpdateTableSize) {
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
+
+  // Entry size is 3 + 3 + 32 = 38.
+  InsertEntry("foo", "bar");
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
+
+  EXPECT_TRUE(SetDynamicTableCapacity(40));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "baz", "qux");
+
+  EXPECT_TRUE(SetDynamicTableCapacity(20));
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(2u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectNoEntryAtIndex(/* is_static = */ false, 1u);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfIdentical) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert same entry twice.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
+}
+
+TEST_F(QpackDecoderHeaderTableTest, EvictOldestOfSameName) {
+  EXPECT_TRUE(SetDynamicTableCapacity(80));
+
+  // Entry size is 3 + 3 + 32 = 38.
+  // Insert two entries with same name but different values.
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "baz");
+  EXPECT_EQ(2u, inserted_entry_count());
+  EXPECT_EQ(0u, dropped_entry_count());
+
+  ExpectEntryAtIndex(/* is_static = */ false, 0u, "foo", "bar");
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
+  ExpectNoEntryAtIndex(/* is_static = */ false, 2u);
+
+  // Inserting third entry evicts the first one, not the second.
+  InsertEntry("baz", "qux");
+  EXPECT_EQ(3u, inserted_entry_count());
+  EXPECT_EQ(1u, dropped_entry_count());
+
+  ExpectNoEntryAtIndex(/* is_static = */ false, 0u);
+  ExpectEntryAtIndex(/* is_static = */ false, 1u, "foo", "baz");
+  ExpectEntryAtIndex(/* is_static = */ false, 2u, "baz", "qux");
+}
+
+TEST_F(QpackDecoderHeaderTableTest, RegisterObserver) {
+  StrictMock<MockObserver> observer1;
+  RegisterObserver(1, &observer1);
+  EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(1u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer1);
+
+  // Registration order does not matter.
+  StrictMock<MockObserver> observer2;
+  StrictMock<MockObserver> observer3;
+  RegisterObserver(3, &observer3);
+  RegisterObserver(2, &observer2);
+
+  EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(2u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer3);
+
+  EXPECT_CALL(observer3, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(3u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer2);
+
+  // Multiple observers with identical |required_insert_count| should all be
+  // notified.
+  StrictMock<MockObserver> observer4;
+  StrictMock<MockObserver> observer5;
+  RegisterObserver(4, &observer4);
+  RegisterObserver(4, &observer5);
+
+  EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
+  EXPECT_CALL(observer5, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(4u, inserted_entry_count());
+  Mock::VerifyAndClearExpectations(&observer4);
+  Mock::VerifyAndClearExpectations(&observer5);
+}
+
+TEST_F(QpackDecoderHeaderTableTest, UnregisterObserver) {
+  StrictMock<MockObserver> observer1;
+  StrictMock<MockObserver> observer2;
+  StrictMock<MockObserver> observer3;
+  StrictMock<MockObserver> observer4;
+  RegisterObserver(1, &observer1);
+  RegisterObserver(2, &observer2);
+  RegisterObserver(2, &observer3);
+  RegisterObserver(3, &observer4);
+
+  UnregisterObserver(2, &observer3);
+
+  EXPECT_CALL(observer1, OnInsertCountReachedThreshold);
+  EXPECT_CALL(observer2, OnInsertCountReachedThreshold);
+  EXPECT_CALL(observer4, OnInsertCountReachedThreshold);
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  InsertEntry("foo", "bar");
+  EXPECT_EQ(3u, inserted_entry_count());
+}
+
+TEST_F(QpackDecoderHeaderTableTest, Cancel) {
+  StrictMock<MockObserver> observer;
+  auto table = std::make_unique<QpackDecoderHeaderTable>();
+  table->RegisterObserver(1, &observer);
+
+  EXPECT_CALL(observer, Cancel);
+  table.reset();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_index_conversions.cc b/quiche/quic/core/qpack/qpack_index_conversions.cc
new file mode 100644
index 0000000..b71d024
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_index_conversions.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+uint64_t QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+    uint64_t absolute_index,
+    uint64_t inserted_entry_count) {
+  QUICHE_DCHECK_LT(absolute_index, inserted_entry_count);
+
+  return inserted_entry_count - absolute_index - 1;
+}
+
+uint64_t QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
+                                                        uint64_t base) {
+  QUICHE_DCHECK_LT(absolute_index, base);
+
+  return base - absolute_index - 1;
+}
+
+bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+    uint64_t relative_index,
+    uint64_t inserted_entry_count,
+    uint64_t* absolute_index) {
+  if (relative_index >= inserted_entry_count) {
+    return false;
+  }
+
+  *absolute_index = inserted_entry_count - relative_index - 1;
+  return true;
+}
+
+bool QpackRequestStreamRelativeIndexToAbsoluteIndex(uint64_t relative_index,
+                                                    uint64_t base,
+                                                    uint64_t* absolute_index) {
+  if (relative_index >= base) {
+    return false;
+  }
+
+  *absolute_index = base - relative_index - 1;
+  return true;
+}
+
+bool QpackPostBaseIndexToAbsoluteIndex(uint64_t post_base_index,
+                                       uint64_t base,
+                                       uint64_t* absolute_index) {
+  if (post_base_index >= std::numeric_limits<uint64_t>::max() - base) {
+    return false;
+  }
+
+  *absolute_index = base + post_base_index;
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_index_conversions.h b/quiche/quic/core/qpack/qpack_index_conversions.h
new file mode 100644
index 0000000..d5d02c8
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_index_conversions.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Utility methods to convert between absolute indexing (used in the dynamic
+// table), relative indexing used on the encoder stream, and relative indexing
+// and post-base indexing used on request streams (in header blocks).  See:
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#indexing
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#relative-indexing
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#post-base
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Conversion functions used in the encoder do not check for overflow/underflow.
+// Since the maximum index is limited by maximum dynamic table capacity
+// (represented on uint64_t) divided by minimum header field size (defined to be
+// 32 bytes), overflow is not possible.  The caller is responsible for providing
+// input that does not underflow.
+
+QUIC_EXPORT_PRIVATE uint64_t
+QpackAbsoluteIndexToEncoderStreamRelativeIndex(uint64_t absolute_index,
+                                               uint64_t inserted_entry_count);
+
+QUIC_EXPORT_PRIVATE uint64_t
+QpackAbsoluteIndexToRequestStreamRelativeIndex(uint64_t absolute_index,
+                                               uint64_t base);
+
+// Conversion functions used in the decoder operate on input received from the
+// network.  These functions return false on overflow or underflow.
+
+QUIC_EXPORT_PRIVATE bool QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+    uint64_t relative_index,
+    uint64_t inserted_entry_count,
+    uint64_t* absolute_index);
+
+// On success, |*absolute_index| is guaranteed to be strictly less than
+// std::numeric_limits<uint64_t>::max().
+QUIC_EXPORT_PRIVATE bool QpackRequestStreamRelativeIndexToAbsoluteIndex(
+    uint64_t relative_index,
+    uint64_t base,
+    uint64_t* absolute_index);
+
+// On success, |*absolute_index| is guaranteed to be strictly less than
+// std::numeric_limits<uint64_t>::max().
+QUIC_EXPORT_PRIVATE bool QpackPostBaseIndexToAbsoluteIndex(
+    uint64_t post_base_index,
+    uint64_t base,
+    uint64_t* absolute_index);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INDEX_CONVERSIONS_H_
diff --git a/quiche/quic/core/qpack/qpack_index_conversions_test.cc b/quiche/quic/core/qpack/qpack_index_conversions_test.cc
new file mode 100644
index 0000000..80162df
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_index_conversions_test.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct {
+  uint64_t relative_index;
+  uint64_t inserted_entry_count;
+  uint64_t expected_absolute_index;
+} kEncoderStreamRelativeIndexTestData[] = {{0, 1, 0},  {0, 2, 1},  {1, 2, 0},
+                                           {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
+
+TEST(QpackIndexConversions, EncoderStreamRelativeIndex) {
+  for (const auto& test_data : kEncoderStreamRelativeIndexTestData) {
+    uint64_t absolute_index = 42;
+    EXPECT_TRUE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+        test_data.relative_index, test_data.inserted_entry_count,
+        &absolute_index));
+    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
+
+    EXPECT_EQ(test_data.relative_index,
+              QpackAbsoluteIndexToEncoderStreamRelativeIndex(
+                  absolute_index, test_data.inserted_entry_count));
+  }
+}
+
+struct {
+  uint64_t relative_index;
+  uint64_t base;
+  uint64_t expected_absolute_index;
+} kRequestStreamRelativeIndexTestData[] = {{0, 1, 0},  {0, 2, 1},  {1, 2, 0},
+                                           {0, 10, 9}, {5, 10, 4}, {9, 10, 0}};
+
+TEST(QpackIndexConversions, RequestStreamRelativeIndex) {
+  for (const auto& test_data : kRequestStreamRelativeIndexTestData) {
+    uint64_t absolute_index = 42;
+    EXPECT_TRUE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
+        test_data.relative_index, test_data.base, &absolute_index));
+    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
+
+    EXPECT_EQ(test_data.relative_index,
+              QpackAbsoluteIndexToRequestStreamRelativeIndex(absolute_index,
+                                                             test_data.base));
+  }
+}
+
+struct {
+  uint64_t post_base_index;
+  uint64_t base;
+  uint64_t expected_absolute_index;
+} kPostBaseIndexTestData[] = {{0, 1, 1}, {1, 0, 1}, {2, 0, 2},
+                              {1, 1, 2}, {0, 2, 2}, {1, 2, 3}};
+
+TEST(QpackIndexConversions, PostBaseIndex) {
+  for (const auto& test_data : kPostBaseIndexTestData) {
+    uint64_t absolute_index = 42;
+    EXPECT_TRUE(QpackPostBaseIndexToAbsoluteIndex(
+        test_data.post_base_index, test_data.base, &absolute_index));
+    EXPECT_EQ(test_data.expected_absolute_index, absolute_index);
+  }
+}
+
+TEST(QpackIndexConversions, EncoderStreamRelativeIndexUnderflow) {
+  uint64_t absolute_index;
+  EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 10,
+      /* inserted_entry_count = */ 10, &absolute_index));
+  EXPECT_FALSE(QpackEncoderStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 12,
+      /* inserted_entry_count = */ 10, &absolute_index));
+}
+
+TEST(QpackIndexConversions, RequestStreamRelativeIndexUnderflow) {
+  uint64_t absolute_index;
+  EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 10,
+      /* base = */ 10, &absolute_index));
+  EXPECT_FALSE(QpackRequestStreamRelativeIndexToAbsoluteIndex(
+      /* relative_index = */ 12,
+      /* base = */ 10, &absolute_index));
+}
+
+TEST(QpackIndexConversions, QpackPostBaseIndexToAbsoluteIndexOverflow) {
+  uint64_t absolute_index;
+  EXPECT_FALSE(QpackPostBaseIndexToAbsoluteIndex(
+      /* post_base_index = */ 20,
+      /* base = */ std::numeric_limits<uint64_t>::max() - 10, &absolute_index));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_decoder.cc b/quiche/quic/core/qpack/qpack_instruction_decoder.cc
new file mode 100644
index 0000000..bc22db0
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_decoder.cc
@@ -0,0 +1,332 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Maximum length of header name and header value.  This limits the amount of
+// memory the peer can make the decoder allocate when sending string literals.
+const size_t kStringLiteralLengthLimit = 1024 * 1024;
+
+}  // namespace
+
+QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language,
+                                                 Delegate* delegate)
+    : language_(language),
+      delegate_(delegate),
+      s_bit_(false),
+      varint_(0),
+      varint2_(0),
+      is_huffman_encoded_(false),
+      string_length_(0),
+      error_detected_(false),
+      state_(State::kStartInstruction) {}
+
+bool QpackInstructionDecoder::Decode(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(!error_detected_);
+
+  while (true) {
+    bool success = true;
+    size_t bytes_consumed = 0;
+
+    switch (state_) {
+      case State::kStartInstruction:
+        success = DoStartInstruction(data);
+        break;
+      case State::kStartField:
+        success = DoStartField();
+        break;
+      case State::kReadBit:
+        success = DoReadBit(data);
+        break;
+      case State::kVarintStart:
+        success = DoVarintStart(data, &bytes_consumed);
+        break;
+      case State::kVarintResume:
+        success = DoVarintResume(data, &bytes_consumed);
+        break;
+      case State::kVarintDone:
+        success = DoVarintDone();
+        break;
+      case State::kReadString:
+        success = DoReadString(data, &bytes_consumed);
+        break;
+      case State::kReadStringDone:
+        success = DoReadStringDone();
+        break;
+    }
+
+    if (!success) {
+      return false;
+    }
+
+    // |success| must be false if an error is detected.
+    QUICHE_DCHECK(!error_detected_);
+
+    QUICHE_DCHECK_LE(bytes_consumed, data.size());
+
+    data = absl::string_view(data.data() + bytes_consumed,
+                             data.size() - bytes_consumed);
+
+    // Stop processing if no more data but next state would require it.
+    if (data.empty() && (state_ != State::kStartField) &&
+        (state_ != State::kVarintDone) && (state_ != State::kReadStringDone)) {
+      return true;
+    }
+  }
+}
+
+bool QpackInstructionDecoder::AtInstructionBoundary() const {
+  return state_ == State::kStartInstruction;
+}
+
+bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+
+  instruction_ = LookupOpcode(data[0]);
+  field_ = instruction_->fields.begin();
+
+  state_ = State::kStartField;
+  return true;
+}
+
+bool QpackInstructionDecoder::DoStartField() {
+  if (field_ == instruction_->fields.end()) {
+    // Completed decoding this instruction.
+
+    if (!delegate_->OnInstructionDecoded(instruction_)) {
+      return false;
+    }
+
+    state_ = State::kStartInstruction;
+    return true;
+  }
+
+  switch (field_->type) {
+    case QpackInstructionFieldType::kSbit:
+    case QpackInstructionFieldType::kName:
+    case QpackInstructionFieldType::kValue:
+      state_ = State::kReadBit;
+      return true;
+    case QpackInstructionFieldType::kVarint:
+    case QpackInstructionFieldType::kVarint2:
+      state_ = State::kVarintStart;
+      return true;
+    default:
+      QUIC_BUG(quic_bug_10767_1) << "Invalid field type.";
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoReadBit(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+
+  switch (field_->type) {
+    case QpackInstructionFieldType::kSbit: {
+      const uint8_t bitmask = field_->param;
+      s_bit_ = (data[0] & bitmask) == bitmask;
+
+      ++field_;
+      state_ = State::kStartField;
+
+      return true;
+    }
+    case QpackInstructionFieldType::kName:
+    case QpackInstructionFieldType::kValue: {
+      const uint8_t prefix_length = field_->param;
+      QUICHE_DCHECK_GE(7, prefix_length);
+      const uint8_t bitmask = 1 << prefix_length;
+      is_huffman_encoded_ = (data[0] & bitmask) == bitmask;
+
+      state_ = State::kVarintStart;
+
+      return true;
+    }
+    default:
+      QUIC_BUG(quic_bug_10767_2) << "Invalid field type.";
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoVarintStart(absl::string_view data,
+                                            size_t* bytes_consumed) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  http2::DecodeBuffer buffer(data.data() + 1, data.size() - 1);
+  http2::DecodeStatus status =
+      varint_decoder_.Start(data[0], field_->param, &buffer);
+
+  *bytes_consumed = 1 + buffer.Offset();
+  switch (status) {
+    case http2::DecodeStatus::kDecodeDone:
+      state_ = State::kVarintDone;
+      return true;
+    case http2::DecodeStatus::kDecodeInProgress:
+      state_ = State::kVarintResume;
+      return true;
+    case http2::DecodeStatus::kDecodeError:
+      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
+      return false;
+    default:
+      QUIC_BUG(quic_bug_10767_3) << "Unknown decode status " << status;
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoVarintResume(absl::string_view data,
+                                             size_t* bytes_consumed) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  http2::DecodeBuffer buffer(data);
+  http2::DecodeStatus status = varint_decoder_.Resume(&buffer);
+
+  *bytes_consumed = buffer.Offset();
+  switch (status) {
+    case http2::DecodeStatus::kDecodeDone:
+      state_ = State::kVarintDone;
+      return true;
+    case http2::DecodeStatus::kDecodeInProgress:
+      QUICHE_DCHECK_EQ(*bytes_consumed, data.size());
+      QUICHE_DCHECK(buffer.Empty());
+      return true;
+    case http2::DecodeStatus::kDecodeError:
+      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
+      return false;
+    default:
+      QUIC_BUG(quic_bug_10767_4) << "Unknown decode status " << status;
+      return false;
+  }
+}
+
+bool QpackInstructionDecoder::DoVarintDone() {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  if (field_->type == QpackInstructionFieldType::kVarint) {
+    varint_ = varint_decoder_.value();
+
+    ++field_;
+    state_ = State::kStartField;
+    return true;
+  }
+
+  if (field_->type == QpackInstructionFieldType::kVarint2) {
+    varint2_ = varint_decoder_.value();
+
+    ++field_;
+    state_ = State::kStartField;
+    return true;
+  }
+
+  string_length_ = varint_decoder_.value();
+  if (string_length_ > kStringLiteralLengthLimit) {
+    OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long.");
+    return false;
+  }
+
+  std::string* const string =
+      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
+  string->clear();
+
+  if (string_length_ == 0) {
+    ++field_;
+    state_ = State::kStartField;
+    return true;
+  }
+
+  string->reserve(string_length_);
+
+  state_ = State::kReadString;
+  return true;
+}
+
+bool QpackInstructionDecoder::DoReadString(absl::string_view data,
+                                           size_t* bytes_consumed) {
+  QUICHE_DCHECK(!data.empty());
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  std::string* const string =
+      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
+  QUICHE_DCHECK_LT(string->size(), string_length_);
+
+  *bytes_consumed = std::min(string_length_ - string->size(), data.size());
+  string->append(data.data(), *bytes_consumed);
+
+  QUICHE_DCHECK_LE(string->size(), string_length_);
+  if (string->size() == string_length_) {
+    state_ = State::kReadStringDone;
+  }
+  return true;
+}
+
+bool QpackInstructionDecoder::DoReadStringDone() {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  std::string* const string =
+      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
+  QUICHE_DCHECK_EQ(string->size(), string_length_);
+
+  if (is_huffman_encoded_) {
+    huffman_decoder_.Reset();
+    // HpackHuffmanDecoder::Decode() cannot perform in-place decoding.
+    std::string decoded_value;
+    huffman_decoder_.Decode(*string, &decoded_value);
+    if (!huffman_decoder_.InputProperlyTerminated()) {
+      OnError(ErrorCode::HUFFMAN_ENCODING_ERROR,
+              "Error in Huffman-encoded string.");
+      return false;
+    }
+    *string = std::move(decoded_value);
+  }
+
+  ++field_;
+  state_ = State::kStartField;
+  return true;
+}
+
+const QpackInstruction* QpackInstructionDecoder::LookupOpcode(
+    uint8_t byte) const {
+  for (const auto* instruction : *language_) {
+    if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
+      return instruction;
+    }
+  }
+  // |language_| should be defined such that instruction opcodes cover every
+  // possible input.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+void QpackInstructionDecoder::OnError(ErrorCode error_code,
+                                      absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+  delegate_->OnInstructionDecodingError(error_code, error_message);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_decoder.h b/quiche/quic/core/qpack/qpack_instruction_decoder.h
new file mode 100644
index 0000000..e8aa5ef
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_decoder.h
@@ -0,0 +1,161 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_decoder.h"
+#include "quiche/http2/hpack/varint/hpack_varint_decoder.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Generic instruction decoder class.  Takes a QpackLanguage that describes a
+// language, that is, a set of instruction opcodes together with a list of
+// fields that follow each instruction.
+class QUIC_EXPORT_PRIVATE QpackInstructionDecoder {
+ public:
+  enum class ErrorCode {
+    INTEGER_TOO_LARGE,
+    STRING_LITERAL_TOO_LONG,
+    HUFFMAN_ENCODING_ERROR,
+  };
+
+  // Delegate is notified each time an instruction is decoded or when an error
+  // occurs.
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // Called when an instruction (including all its fields) is decoded.
+    // |instruction| points to an entry in |language|.
+    // Returns true if decoded fields are valid.
+    // Returns false otherwise, in which case QpackInstructionDecoder stops
+    // decoding: Delegate methods will not be called, and Decode() must not be
+    // called.  Implementations are allowed to destroy the
+    // QpackInstructionDecoder instance synchronously if OnInstructionDecoded()
+    // returns false.
+    virtual bool OnInstructionDecoded(const QpackInstruction* instruction) = 0;
+
+    // Called by QpackInstructionDecoder if an error has occurred.
+    // No more data is processed afterwards.
+    // Implementations are allowed to destroy the QpackInstructionDecoder
+    // instance synchronously.
+    virtual void OnInstructionDecodingError(
+        ErrorCode error_code,
+        absl::string_view error_message) = 0;
+  };
+
+  // Both |*language| and |*delegate| must outlive this object.
+  QpackInstructionDecoder(const QpackLanguage* language, Delegate* delegate);
+  QpackInstructionDecoder() = delete;
+  QpackInstructionDecoder(const QpackInstructionDecoder&) = delete;
+  QpackInstructionDecoder& operator=(const QpackInstructionDecoder&) = delete;
+
+  // Provide a data fragment to decode.  Must not be called after an error has
+  // occurred.  Must not be called with empty |data|.  Return true on success,
+  // false on error (in which case Delegate::OnInstructionDecodingError() is
+  // called synchronously).
+  bool Decode(absl::string_view data);
+
+  // Returns true if no decoding has taken place yet or if the last instruction
+  // has been entirely parsed.
+  bool AtInstructionBoundary() const;
+
+  // Accessors for decoded values.  Should only be called for fields that are
+  // part of the most recently decoded instruction, and only after |this| calls
+  // Delegate::OnInstructionDecoded() but before Decode() is called again.
+  bool s_bit() const { return s_bit_; }
+  uint64_t varint() const { return varint_; }
+  uint64_t varint2() const { return varint2_; }
+  const std::string& name() const { return name_; }
+  const std::string& value() const { return value_; }
+
+ private:
+  enum class State {
+    // Identify instruction.
+    kStartInstruction,
+    // Start decoding next field.
+    kStartField,
+    // Read a single bit.
+    kReadBit,
+    // Start reading integer.
+    kVarintStart,
+    // Resume reading integer.
+    kVarintResume,
+    // Done reading integer.
+    kVarintDone,
+    // Read string.
+    kReadString,
+    // Done reading string.
+    kReadStringDone
+  };
+
+  // One method for each state.  They each return true on success, false on
+  // error (in which case |this| might already be destroyed).  Some take input
+  // data and set |*bytes_consumed| to the number of octets processed.  Some
+  // take input data but do not consume any bytes.  Some do not take any
+  // arguments because they only change internal state.
+  bool DoStartInstruction(absl::string_view data);
+  bool DoStartField();
+  bool DoReadBit(absl::string_view data);
+  bool DoVarintStart(absl::string_view data, size_t* bytes_consumed);
+  bool DoVarintResume(absl::string_view data, size_t* bytes_consumed);
+  bool DoVarintDone();
+  bool DoReadString(absl::string_view data, size_t* bytes_consumed);
+  bool DoReadStringDone();
+
+  // Identify instruction based on opcode encoded in |byte|.
+  // Returns a pointer to an element of |*language_|.
+  const QpackInstruction* LookupOpcode(uint8_t byte) const;
+
+  // Stops decoding and calls Delegate::OnInstructionDecodingError().
+  void OnError(ErrorCode error_code, absl::string_view error_message);
+
+  // Describes the language used for decoding.
+  const QpackLanguage* const language_;
+
+  // The Delegate to notify of decoded instructions and errors.
+  Delegate* const delegate_;
+
+  // Storage for decoded field values.
+  bool s_bit_;
+  uint64_t varint_;
+  uint64_t varint2_;
+  std::string name_;
+  std::string value_;
+  // Whether the currently decoded header name or value is Huffman encoded.
+  bool is_huffman_encoded_;
+  // Length of string being read into |name_| or |value_|.
+  size_t string_length_;
+
+  // Decoder instance for decoding integers.
+  http2::HpackVarintDecoder varint_decoder_;
+
+  // Decoder instance for decoding Huffman encoded strings.
+  http2::HpackHuffmanDecoder huffman_decoder_;
+
+  // True if a decoding error has been detected by QpackInstructionDecoder.
+  // Only used in QUICHE_DCHECKs.
+  bool error_detected_;
+
+  // Decoding state.
+  State state_;
+
+  // Instruction currently being decoded.
+  const QpackInstruction* instruction_;
+
+  // Field currently being decoded.
+  QpackInstructionFields::const_iterator field_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_DECODER_H_
diff --git a/quiche/quic/core/qpack/qpack_instruction_decoder_test.cc b/quiche/quic/core/qpack/qpack_instruction_decoder_test.cc
new file mode 100644
index 0000000..d5c753d
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_decoder_test.cc
@@ -0,0 +1,226 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+
+#include <algorithm>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Expectation;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Return;
+using ::testing::StrictMock;
+using ::testing::Values;
+
+namespace quic {
+namespace test {
+namespace {
+
+// This instruction has three fields: an S bit and two varints.
+const QpackInstruction* TestInstruction1() {
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{QpackInstructionOpcode{0x00, 0x80},
+                           {{QpackInstructionFieldType::kSbit, 0x40},
+                            {QpackInstructionFieldType::kVarint, 6},
+                            {QpackInstructionFieldType::kVarint2, 8}}};
+  return instruction;
+}
+
+// This instruction has two fields: a header name with a 6-bit prefix, and a
+// header value with a 7-bit prefix, both preceded by a Huffman bit.
+const QpackInstruction* TestInstruction2() {
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{QpackInstructionOpcode{0x80, 0x80},
+                           {{QpackInstructionFieldType::kName, 6},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackLanguage* TestLanguage() {
+  static const QpackLanguage* const language =
+      new QpackLanguage{TestInstruction1(), TestInstruction2()};
+  return language;
+}
+
+class MockDelegate : public QpackInstructionDecoder::Delegate {
+ public:
+  MockDelegate() {
+    ON_CALL(*this, OnInstructionDecoded(_)).WillByDefault(Return(true));
+  }
+
+  MockDelegate(const MockDelegate&) = delete;
+  MockDelegate& operator=(const MockDelegate&) = delete;
+  ~MockDelegate() override = default;
+
+  MOCK_METHOD(bool,
+              OnInstructionDecoded,
+              (const QpackInstruction*),
+              (override));
+  MOCK_METHOD(void,
+              OnInstructionDecodingError,
+              (QpackInstructionDecoder::ErrorCode error_code,
+               absl::string_view error_message),
+              (override));
+};
+
+class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> {
+ protected:
+  QpackInstructionDecoderTest()
+      : decoder_(std::make_unique<QpackInstructionDecoder>(TestLanguage(),
+                                                           &delegate_)),
+        fragment_mode_(GetParam()) {}
+  ~QpackInstructionDecoderTest() override = default;
+
+  void SetUp() override {
+    // Destroy QpackInstructionDecoder on error to test that it does not crash.
+    // See https://crbug.com/1025209.
+    ON_CALL(delegate_, OnInstructionDecodingError(_, _))
+        .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); }));
+  }
+
+  // Decode one full instruction with fragment sizes dictated by
+  // |fragment_mode_|.
+  // Assumes that |data| is a single complete instruction, and accordingly
+  // verifies that AtInstructionBoundary() returns true before and after the
+  // instruction, and returns false while decoding is in progress.
+  // Assumes that delegate methods destroy |decoder_| if they return false.
+  void DecodeInstruction(absl::string_view data) {
+    EXPECT_TRUE(decoder_->AtInstructionBoundary());
+
+    FragmentSizeGenerator fragment_size_generator =
+        FragmentModeToFragmentSizeGenerator(fragment_mode_);
+
+    while (!data.empty()) {
+      size_t fragment_size = std::min(fragment_size_generator(), data.size());
+      bool success = decoder_->Decode(data.substr(0, fragment_size));
+      if (!decoder_) {
+        EXPECT_FALSE(success);
+        return;
+      }
+      EXPECT_TRUE(success);
+      data = data.substr(fragment_size);
+      if (!data.empty()) {
+        EXPECT_FALSE(decoder_->AtInstructionBoundary());
+      }
+    }
+
+    EXPECT_TRUE(decoder_->AtInstructionBoundary());
+  }
+
+  StrictMock<MockDelegate> delegate_;
+  std::unique_ptr<QpackInstructionDecoder> decoder_;
+
+ private:
+  const FragmentMode fragment_mode_;
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         QpackInstructionDecoderTest,
+                         Values(FragmentMode::kSingleChunk,
+                                FragmentMode::kOctetByOctet));
+
+TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
+  DecodeInstruction(absl::HexStringToBytes("7f01ff65"));
+
+  EXPECT_TRUE(decoder_->s_bit());
+  EXPECT_EQ(64u, decoder_->varint());
+  EXPECT_EQ(356u, decoder_->varint2());
+
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
+  DecodeInstruction(absl::HexStringToBytes("05c8"));
+
+  EXPECT_FALSE(decoder_->s_bit());
+  EXPECT_EQ(5u, decoder_->varint());
+  EXPECT_EQ(200u, decoder_->varint2());
+}
+
+TEST_P(QpackInstructionDecoderTest, NameAndValue) {
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
+  DecodeInstruction(absl::HexStringToBytes("83666f6f03626172"));
+
+  EXPECT_EQ("foo", decoder_->name());
+  EXPECT_EQ("bar", decoder_->value());
+
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
+  DecodeInstruction(absl::HexStringToBytes("8000"));
+
+  EXPECT_EQ("", decoder_->name());
+  EXPECT_EQ("", decoder_->value());
+
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
+  DecodeInstruction(absl::HexStringToBytes("c294e7838c767f"));
+
+  EXPECT_EQ("foo", decoder_->name());
+  EXPECT_EQ("bar", decoder_->value());
+}
+
+TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) {
+  EXPECT_CALL(delegate_,
+              OnInstructionDecodingError(
+                  QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR,
+                  Eq("Error in Huffman-encoded string.")));
+  DecodeInstruction(absl::HexStringToBytes("c1ff"));
+}
+
+TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
+  EXPECT_CALL(delegate_,
+              OnInstructionDecodingError(
+                  QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE,
+                  Eq("Encoded integer too large.")));
+  DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff"));
+}
+
+TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
+  EXPECT_CALL(delegate_,
+              OnInstructionDecodingError(
+                  QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG,
+                  Eq("String literal too long.")));
+  DecodeInstruction(absl::HexStringToBytes("bfffff7f"));
+}
+
+TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
+  // First instruction is valid.
+  Expectation first_call =
+      EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
+          .WillOnce(InvokeWithoutArgs([this]() -> bool {
+            EXPECT_EQ(1u, decoder_->varint());
+            return true;
+          }));
+
+  // Second instruction is invalid.  Decoding must halt.
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
+      .After(first_call)
+      .WillOnce(InvokeWithoutArgs([this]() -> bool {
+        EXPECT_EQ(2u, decoder_->varint());
+        return false;
+      }));
+
+  EXPECT_FALSE(
+      decoder_->Decode(absl::HexStringToBytes("01000200030004000500")));
+}
+
+// QpackInstructionDecoder must not crash if it is destroyed from a
+// Delegate::OnInstructionDecoded() call as long as it returns false.
+TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) {
+  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
+      .WillOnce(InvokeWithoutArgs([this]() -> bool {
+        EXPECT_EQ(1u, decoder_->varint());
+        decoder_.reset();
+        return false;
+      }));
+  DecodeInstruction(absl::HexStringToBytes("0100"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_encoder.cc b/quiche/quic/core/qpack/qpack_instruction_encoder.cc
new file mode 100644
index 0000000..2922c00
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_encoder.cc
@@ -0,0 +1,177 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+#include "quiche/http2/hpack/varint/hpack_varint_encoder.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QpackInstructionEncoder::QpackInstructionEncoder()
+    : use_huffman_(false),
+      string_length_(0),
+      byte_(0),
+      state_(State::kOpcode),
+      instruction_(nullptr) {}
+
+void QpackInstructionEncoder::Encode(
+    const QpackInstructionWithValues& instruction_with_values,
+    std::string* output) {
+  QUICHE_DCHECK(instruction_with_values.instruction());
+
+  state_ = State::kOpcode;
+  instruction_ = instruction_with_values.instruction();
+  field_ = instruction_->fields.begin();
+
+  // Field list must not be empty.
+  QUICHE_DCHECK(field_ != instruction_->fields.end());
+
+  do {
+    switch (state_) {
+      case State::kOpcode:
+        DoOpcode();
+        break;
+      case State::kStartField:
+        DoStartField();
+        break;
+      case State::kSbit:
+        DoSBit(instruction_with_values.s_bit());
+        break;
+      case State::kVarintEncode:
+        DoVarintEncode(instruction_with_values.varint(),
+                       instruction_with_values.varint2(), output);
+        break;
+      case State::kStartString:
+        DoStartString(instruction_with_values.name(),
+                      instruction_with_values.value());
+        break;
+      case State::kWriteString:
+        DoWriteString(instruction_with_values.name(),
+                      instruction_with_values.value(), output);
+        break;
+    }
+  } while (field_ != instruction_->fields.end());
+
+  QUICHE_DCHECK(state_ == State::kStartField);
+}
+
+void QpackInstructionEncoder::DoOpcode() {
+  QUICHE_DCHECK_EQ(0u, byte_);
+
+  byte_ = instruction_->opcode.value;
+
+  state_ = State::kStartField;
+}
+
+void QpackInstructionEncoder::DoStartField() {
+  switch (field_->type) {
+    case QpackInstructionFieldType::kSbit:
+      state_ = State::kSbit;
+      return;
+    case QpackInstructionFieldType::kVarint:
+    case QpackInstructionFieldType::kVarint2:
+      state_ = State::kVarintEncode;
+      return;
+    case QpackInstructionFieldType::kName:
+    case QpackInstructionFieldType::kValue:
+      state_ = State::kStartString;
+      return;
+  }
+}
+
+void QpackInstructionEncoder::DoSBit(bool s_bit) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kSbit);
+
+  if (s_bit) {
+    QUICHE_DCHECK_EQ(0, byte_ & field_->param);
+
+    byte_ |= field_->param;
+  }
+
+  ++field_;
+  state_ = State::kStartField;
+}
+
+void QpackInstructionEncoder::DoVarintEncode(uint64_t varint,
+                                             uint64_t varint2,
+                                             std::string* output) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
+                field_->type == QpackInstructionFieldType::kVarint2 ||
+                field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+  uint64_t integer_to_encode;
+  switch (field_->type) {
+    case QpackInstructionFieldType::kVarint:
+      integer_to_encode = varint;
+      break;
+    case QpackInstructionFieldType::kVarint2:
+      integer_to_encode = varint2;
+      break;
+    default:
+      integer_to_encode = string_length_;
+      break;
+  }
+
+  http2::HpackVarintEncoder::Encode(byte_, field_->param, integer_to_encode,
+                                    output);
+  byte_ = 0;
+
+  if (field_->type == QpackInstructionFieldType::kVarint ||
+      field_->type == QpackInstructionFieldType::kVarint2) {
+    ++field_;
+    state_ = State::kStartField;
+    return;
+  }
+
+  state_ = State::kWriteString;
+}
+
+void QpackInstructionEncoder::DoStartString(absl::string_view name,
+                                            absl::string_view value) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  absl::string_view string_to_write =
+      (field_->type == QpackInstructionFieldType::kName) ? name : value;
+  string_length_ = string_to_write.size();
+
+  size_t encoded_size = http2::HuffmanSize(string_to_write);
+  use_huffman_ = encoded_size < string_length_;
+
+  if (use_huffman_) {
+    QUICHE_DCHECK_EQ(0, byte_ & (1 << field_->param));
+    byte_ |= (1 << field_->param);
+
+    string_length_ = encoded_size;
+  }
+
+  state_ = State::kVarintEncode;
+}
+
+void QpackInstructionEncoder::DoWriteString(absl::string_view name,
+                                            absl::string_view value,
+                                            std::string* output) {
+  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
+                field_->type == QpackInstructionFieldType::kValue);
+
+  absl::string_view string_to_write =
+      (field_->type == QpackInstructionFieldType::kName) ? name : value;
+  if (use_huffman_) {
+    http2::HuffmanEncodeFast(string_to_write, string_length_, output);
+  } else {
+    absl::StrAppend(output, string_to_write);
+  }
+
+  ++field_;
+  state_ = State::kStartField;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instruction_encoder.h b/quiche/quic/core/qpack/qpack_instruction_encoder.h
new file mode 100644
index 0000000..25f707a
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_encoder.h
@@ -0,0 +1,84 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Generic instruction encoder class.  Takes a QpackLanguage that describes a
+// language, that is, a set of instruction opcodes together with a list of
+// fields that follow each instruction.
+class QUIC_EXPORT_PRIVATE QpackInstructionEncoder {
+ public:
+  QpackInstructionEncoder();
+  QpackInstructionEncoder(const QpackInstructionEncoder&) = delete;
+  QpackInstructionEncoder& operator=(const QpackInstructionEncoder&) = delete;
+
+  // Append encoded instruction to |output|.
+  void Encode(const QpackInstructionWithValues& instruction_with_values,
+              std::string* output);
+
+ private:
+  enum class State {
+    // Write instruction opcode to |byte_|.
+    kOpcode,
+    // Select state based on type of current field.
+    kStartField,
+    // Write static bit to |byte_|.
+    kSbit,
+    // Encode an integer (|varint_| or |varint2_| or string length) with a
+    // prefix, using |byte_| for the high bits.
+    kVarintEncode,
+    // Determine if Huffman encoding should be used for the header name or
+    // value, set |use_huffman_| and |string_length_| appropriately, write the
+    // Huffman bit to |byte_|.
+    kStartString,
+    // Write header name or value, performing Huffman encoding if |use_huffman_|
+    // is true.
+    kWriteString
+  };
+
+  // One method for each state.  Some append encoded bytes to |output|.
+  // Some only change internal state.
+  void DoOpcode();
+  void DoStartField();
+  void DoSBit(bool s_bit);
+  void DoVarintEncode(uint64_t varint, uint64_t varint2, std::string* output);
+  void DoStartString(absl::string_view name, absl::string_view value);
+  void DoWriteString(absl::string_view name,
+                     absl::string_view value,
+                     std::string* output);
+
+  // True if name or value should be Huffman encoded.
+  bool use_huffman_;
+
+  // Length of name or value string to be written.
+  // If |use_huffman_| is true, length is after Huffman encoding.
+  size_t string_length_;
+
+  // Storage for a single byte that contains multiple fields, that is, multiple
+  // states are writing it.
+  uint8_t byte_;
+
+  // Encoding state.
+  State state_;
+
+  // Instruction currently being decoded.
+  const QpackInstruction* instruction_;
+
+  // Field currently being decoded.
+  QpackInstructionFields::const_iterator field_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTION_ENCODER_H_
diff --git a/quiche/quic/core/qpack/qpack_instruction_encoder_test.cc b/quiche/quic/core/qpack/qpack_instruction_encoder_test.cc
new file mode 100644
index 0000000..dfdec9e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instruction_encoder_test.cc
@@ -0,0 +1,204 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_instruction_encoder.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QpackInstructionWithValuesPeer {
+ public:
+  static QpackInstructionWithValues CreateQpackInstructionWithValues(
+      const QpackInstruction* instruction) {
+    QpackInstructionWithValues instruction_with_values;
+    instruction_with_values.instruction_ = instruction;
+    return instruction_with_values;
+  }
+
+  static void set_s_bit(QpackInstructionWithValues* instruction_with_values,
+                        bool s_bit) {
+    instruction_with_values->s_bit_ = s_bit;
+  }
+
+  static void set_varint(QpackInstructionWithValues* instruction_with_values,
+                         uint64_t varint) {
+    instruction_with_values->varint_ = varint;
+  }
+
+  static void set_varint2(QpackInstructionWithValues* instruction_with_values,
+                          uint64_t varint2) {
+    instruction_with_values->varint2_ = varint2;
+  }
+
+  static void set_name(QpackInstructionWithValues* instruction_with_values,
+                       absl::string_view name) {
+    instruction_with_values->name_ = name;
+  }
+
+  static void set_value(QpackInstructionWithValues* instruction_with_values,
+                        absl::string_view value) {
+    instruction_with_values->value_ = value;
+  }
+};
+
+namespace {
+
+class QpackInstructionEncoderTest : public QuicTest {
+ protected:
+  QpackInstructionEncoderTest() : verified_position_(0) {}
+  ~QpackInstructionEncoderTest() override = default;
+
+  // Append encoded |instruction| to |output_|.
+  void EncodeInstruction(
+      const QpackInstructionWithValues& instruction_with_values) {
+    encoder_.Encode(instruction_with_values, &output_);
+  }
+
+  // Compare substring appended to |output_| since last EncodedSegmentMatches()
+  // call against hex-encoded argument.
+  bool EncodedSegmentMatches(absl::string_view hex_encoded_expected_substring) {
+    auto recently_encoded =
+        absl::string_view(output_).substr(verified_position_);
+    auto expected = absl::HexStringToBytes(hex_encoded_expected_substring);
+    verified_position_ = output_.size();
+    return recently_encoded == expected;
+  }
+
+ private:
+  QpackInstructionEncoder encoder_;
+  std::string output_;
+  std::string::size_type verified_position_;
+};
+
+TEST_F(QpackInstructionEncoderTest, Varint) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80},
+                                     {{QpackInstructionFieldType::kVarint, 7}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("05"));
+
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 127);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("7f00"));
+}
+
+TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
+  const QpackInstruction instruction{
+      QpackInstructionOpcode{0x80, 0xc0},
+      {{QpackInstructionFieldType::kSbit, 0x20},
+       {QpackInstructionFieldType::kVarint, 5},
+       {QpackInstructionFieldType::kVarint2, 8}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 5);
+  QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 200);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("a5c8"));
+
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 31);
+  QpackInstructionWithValuesPeer::set_varint2(&instruction_with_values, 356);
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("9f00ff65"));
+}
+
+TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0},
+                                     {{QpackInstructionFieldType::kSbit, 0x20},
+                                      {QpackInstructionFieldType::kVarint, 5},
+                                      {QpackInstructionFieldType::kValue, 7}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 100);
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("ff458294e7"));
+
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
+  QpackInstructionWithValuesPeer::set_varint(&instruction_with_values, 3);
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("c303626172"));
+}
+
+TEST_F(QpackInstructionEncoderTest, Name) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0},
+                                     {{QpackInstructionFieldType::kName, 4}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("e0"));
+
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f294e7"));
+
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("e3626172"));
+}
+
+TEST_F(QpackInstructionEncoderTest, Value) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
+                                     {{QpackInstructionFieldType::kValue, 3}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f0"));
+
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "foo");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("fa94e7"));
+
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f3626172"));
+}
+
+TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) {
+  const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
+                                     {{QpackInstructionFieldType::kSbit, 0x08},
+                                      {QpackInstructionFieldType::kName, 2},
+                                      {QpackInstructionFieldType::kValue, 7}}};
+
+  auto instruction_with_values =
+      QpackInstructionWithValuesPeer::CreateQpackInstructionWithValues(
+          &instruction);
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, false);
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "");
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("f000"));
+
+  QpackInstructionWithValuesPeer::set_s_bit(&instruction_with_values, true);
+  QpackInstructionWithValuesPeer::set_name(&instruction_with_values, "foo");
+  QpackInstructionWithValuesPeer::set_value(&instruction_with_values, "bar");
+  EncodeInstruction(instruction_with_values);
+  EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instructions.cc b/quiche/quic/core/qpack/qpack_instructions.cc
new file mode 100644
index 0000000..ee80897
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instructions.cc
@@ -0,0 +1,333 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// Validate that
+//  * in each instruction, the bits of |value| that are zero in |mask| are zero;
+//  * every byte matches exactly one opcode.
+void ValidateLangague(const QpackLanguage* language) {
+#ifndef NDEBUG
+  for (const auto* instruction : *language) {
+    QUICHE_DCHECK_EQ(0, instruction->opcode.value & ~instruction->opcode.mask);
+  }
+
+  for (uint8_t byte = 0; byte < std::numeric_limits<uint8_t>::max(); ++byte) {
+    size_t match_count = 0;
+    for (const auto* instruction : *language) {
+      if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
+        ++match_count;
+      }
+    }
+    QUICHE_DCHECK_EQ(1u, match_count) << static_cast<int>(byte);
+  }
+#else
+  (void)language;
+#endif
+}
+
+}  // namespace
+
+bool operator==(const QpackInstructionOpcode& a,
+                const QpackInstructionOpcode& b) {
+  return std::tie(a.value, a.mask) == std::tie(b.value, b.mask);
+}
+
+const QpackInstruction* InsertWithNameReferenceInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b10000000, 0b10000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kSbit, 0b01000000},
+                            {QpackInstructionFieldType::kVarint, 6},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* InsertWithoutNameReferenceInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b01000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kName, 5},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* DuplicateInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b11100000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
+  return instruction;
+}
+
+const QpackInstruction* SetDynamicTableCapacityInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00100000, 0b11100000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 5}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackEncoderStreamLanguage() {
+  static const QpackLanguage* const language = new QpackLanguage{
+      InsertWithNameReferenceInstruction(),
+      InsertWithoutNameReferenceInstruction(), DuplicateInstruction(),
+      SetDynamicTableCapacityInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+const QpackInstruction* InsertCountIncrementInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
+  return instruction;
+}
+
+const QpackInstruction* HeaderAcknowledgementInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b10000000, 0b10000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* StreamCancellationInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b01000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 6}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackDecoderStreamLanguage() {
+  static const QpackLanguage* const language = new QpackLanguage{
+      InsertCountIncrementInstruction(), HeaderAcknowledgementInstruction(),
+      StreamCancellationInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+const QpackInstruction* QpackPrefixInstruction() {
+  // This opcode matches every input.
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b00000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kVarint, 8},
+                            {QpackInstructionFieldType::kSbit, 0b10000000},
+                            {QpackInstructionFieldType::kVarint2, 7}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackPrefixLanguage() {
+  static const QpackLanguage* const language =
+      new QpackLanguage{QpackPrefixInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+const QpackInstruction* QpackIndexedHeaderFieldInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b10000000, 0b10000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kSbit, 0b01000000},
+                            {QpackInstructionFieldType::kVarint, 6}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00010000, 0b11110000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode, {{QpackInstructionFieldType::kVarint, 4}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b01000000, 0b11000000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kSbit, 0b00010000},
+                            {QpackInstructionFieldType::kVarint, 4},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00000000, 0b11110000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kVarint, 3},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackInstruction* QpackLiteralHeaderFieldInstruction() {
+  static const QpackInstructionOpcode* const opcode =
+      new QpackInstructionOpcode{0b00100000, 0b11100000};
+  static const QpackInstruction* const instruction =
+      new QpackInstruction{*opcode,
+                           {{QpackInstructionFieldType::kName, 3},
+                            {QpackInstructionFieldType::kValue, 7}}};
+  return instruction;
+}
+
+const QpackLanguage* QpackRequestStreamLanguage() {
+  static const QpackLanguage* const language =
+      new QpackLanguage{QpackIndexedHeaderFieldInstruction(),
+                        QpackIndexedHeaderFieldPostBaseInstruction(),
+                        QpackLiteralHeaderFieldNameReferenceInstruction(),
+                        QpackLiteralHeaderFieldPostBaseInstruction(),
+                        QpackLiteralHeaderFieldInstruction()};
+  ValidateLangague(language);
+  return language;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::InsertWithNameReference(
+    bool is_static,
+    uint64_t name_index,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = InsertWithNameReferenceInstruction();
+  instruction_with_values.s_bit_ = is_static;
+  instruction_with_values.varint_ = name_index;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues
+QpackInstructionWithValues::InsertWithoutNameReference(
+    absl::string_view name,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ =
+      InsertWithoutNameReferenceInstruction();
+  instruction_with_values.name_ = name;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::Duplicate(
+    uint64_t index) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = DuplicateInstruction();
+  instruction_with_values.varint_ = index;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::SetDynamicTableCapacity(
+    uint64_t capacity) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = SetDynamicTableCapacityInstruction();
+  instruction_with_values.varint_ = capacity;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::InsertCountIncrement(
+    uint64_t increment) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = InsertCountIncrementInstruction();
+  instruction_with_values.varint_ = increment;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::HeaderAcknowledgement(
+    uint64_t stream_id) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = HeaderAcknowledgementInstruction();
+  instruction_with_values.varint_ = stream_id;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::StreamCancellation(
+    uint64_t stream_id) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = StreamCancellationInstruction();
+  instruction_with_values.varint_ = stream_id;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::Prefix(
+    uint64_t required_insert_count) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = QpackPrefixInstruction();
+  instruction_with_values.varint_ = required_insert_count;
+  instruction_with_values.varint2_ = 0;    // Delta Base.
+  instruction_with_values.s_bit_ = false;  // Delta Base sign.
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::IndexedHeaderField(
+    bool is_static,
+    uint64_t index) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = QpackIndexedHeaderFieldInstruction();
+  instruction_with_values.s_bit_ = is_static;
+  instruction_with_values.varint_ = index;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues
+QpackInstructionWithValues::LiteralHeaderFieldNameReference(
+    bool is_static,
+    uint64_t index,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ =
+      QpackLiteralHeaderFieldNameReferenceInstruction();
+  instruction_with_values.s_bit_ = is_static;
+  instruction_with_values.varint_ = index;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+// static
+QpackInstructionWithValues QpackInstructionWithValues::LiteralHeaderField(
+    absl::string_view name,
+    absl::string_view value) {
+  QpackInstructionWithValues instruction_with_values;
+  instruction_with_values.instruction_ = QpackLiteralHeaderFieldInstruction();
+  instruction_with_values.name_ = name;
+  instruction_with_values.value_ = value;
+
+  return instruction_with_values;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_instructions.h b/quiche/quic/core/qpack/qpack_instructions.h
new file mode 100644
index 0000000..e66651e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_instructions.h
@@ -0,0 +1,207 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QpackInstructionWithValuesPeer;
+}  // namespace test
+
+// Each instruction is identified with an opcode in the first byte.
+// |mask| determines which bits are part of the opcode.
+// |value| is the value of these bits.  (Other bits in value must be zero.)
+struct QUIC_EXPORT_PRIVATE QpackInstructionOpcode {
+  uint8_t value;
+  uint8_t mask;
+};
+
+bool operator==(const QpackInstructionOpcode& a,
+                const QpackInstructionOpcode& b);
+
+// Possible types of an instruction field.  Decoding a static bit does not
+// consume the current byte.  Decoding an integer or a length-prefixed string
+// literal consumes all bytes containing the field value.
+enum class QpackInstructionFieldType {
+  // A single bit indicating whether the index refers to the static table, or
+  // indicating the sign of Delta Base.  Called "S" bit because both "static"
+  // and "sign" start with the letter "S".
+  kSbit,
+  // An integer encoded with variable length encoding.  This could be an index,
+  // stream ID, maximum size, or Encoded Required Insert Count.
+  kVarint,
+  // A second integer encoded with variable length encoding.  This could be
+  // Delta Base.
+  kVarint2,
+  // A header name or header value encoded as:
+  //   a bit indicating whether it is Huffman encoded;
+  //   the encoded length of the string;
+  //   the header name or value optionally Huffman encoded.
+  kName,
+  kValue
+};
+
+// Each instruction field has a type and a parameter.
+// The meaning of the parameter depends on the field type.
+struct QUIC_EXPORT_PRIVATE QpackInstructionField {
+  QpackInstructionFieldType type;
+  // For a kSbit field, |param| is a mask with exactly one bit set.
+  // For kVarint fields, |param| is the prefix length of the integer encoding.
+  // For kName and kValue fields, |param| is the prefix length of the length of
+  // the string, and the bit immediately preceding the prefix is interpreted as
+  // the Huffman bit.
+  uint8_t param;
+};
+
+using QpackInstructionFields = std::vector<QpackInstructionField>;
+
+// A QPACK instruction consists of an opcode identifying the instruction,
+// followed by a non-empty list of fields.  The last field must be integer or
+// string literal type to guarantee that all bytes of the instruction are
+// consumed.
+struct QUIC_EXPORT_PRIVATE QpackInstruction {
+  QpackInstruction(const QpackInstruction&) = delete;
+  const QpackInstruction& operator=(const QpackInstruction&) = delete;
+
+  QpackInstructionOpcode opcode;
+  QpackInstructionFields fields;
+};
+
+// A language is a collection of instructions.  The order does not matter.
+// Every possible input must match exactly one instruction.
+using QpackLanguage = std::vector<const QpackInstruction*>;
+
+// Wire format defined in
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5
+
+// 5.2 Encoder stream instructions
+
+// 5.2.1 Insert With Name Reference
+const QpackInstruction* InsertWithNameReferenceInstruction();
+
+// 5.2.2 Insert Without Name Reference
+const QpackInstruction* InsertWithoutNameReferenceInstruction();
+
+// 5.2.3 Duplicate
+const QpackInstruction* DuplicateInstruction();
+
+// 5.2.4 Dynamic Table Size Update
+const QpackInstruction* SetDynamicTableCapacityInstruction();
+
+// Encoder stream language.
+const QpackLanguage* QpackEncoderStreamLanguage();
+
+// 5.3 Decoder stream instructions
+
+// 5.3.1 Insert Count Increment
+const QpackInstruction* InsertCountIncrementInstruction();
+
+// 5.3.2 Header Acknowledgement
+const QpackInstruction* HeaderAcknowledgementInstruction();
+
+// 5.3.3 Stream Cancellation
+const QpackInstruction* StreamCancellationInstruction();
+
+// Decoder stream language.
+const QpackLanguage* QpackDecoderStreamLanguage();
+
+// 5.4.1. Header data prefix instructions
+
+const QpackInstruction* QpackPrefixInstruction();
+
+const QpackLanguage* QpackPrefixLanguage();
+
+// 5.4.2. Request and push stream instructions
+
+// 5.4.2.1. Indexed Header Field
+const QpackInstruction* QpackIndexedHeaderFieldInstruction();
+
+// 5.4.2.2. Indexed Header Field With Post-Base Index
+const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction();
+
+// 5.4.2.3. Literal Header Field With Name Reference
+const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction();
+
+// 5.4.2.4. Literal Header Field With Post-Base Name Reference
+const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction();
+
+// 5.4.2.5. Literal Header Field Without Name Reference
+const QpackInstruction* QpackLiteralHeaderFieldInstruction();
+
+// Request and push stream language.
+const QpackLanguage* QpackRequestStreamLanguage();
+
+// Storage for instruction and field values to be encoded.
+// This class can only be instantiated using factory methods that take exactly
+// the arguments that the corresponding instruction needs.
+class QUIC_EXPORT_PRIVATE QpackInstructionWithValues {
+ public:
+  // 5.2 Encoder stream instructions
+  static QpackInstructionWithValues InsertWithNameReference(
+      bool is_static,
+      uint64_t name_index,
+      absl::string_view value);
+  static QpackInstructionWithValues InsertWithoutNameReference(
+      absl::string_view name,
+      absl::string_view value);
+  static QpackInstructionWithValues Duplicate(uint64_t index);
+  static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity);
+
+  // 5.3 Decoder stream instructions
+  static QpackInstructionWithValues InsertCountIncrement(uint64_t increment);
+  static QpackInstructionWithValues HeaderAcknowledgement(uint64_t stream_id);
+  static QpackInstructionWithValues StreamCancellation(uint64_t stream_id);
+
+  // 5.4.1. Header data prefix.  Delta Base is hardcoded to be zero.
+  static QpackInstructionWithValues Prefix(uint64_t required_insert_count);
+
+  // 5.4.2. Request and push stream instructions
+  static QpackInstructionWithValues IndexedHeaderField(bool is_static,
+                                                       uint64_t index);
+  static QpackInstructionWithValues LiteralHeaderFieldNameReference(
+      bool is_static,
+      uint64_t index,
+      absl::string_view value);
+  static QpackInstructionWithValues LiteralHeaderField(absl::string_view name,
+                                                       absl::string_view value);
+
+  const QpackInstruction* instruction() const { return instruction_; }
+  bool s_bit() const { return s_bit_; }
+  uint64_t varint() const { return varint_; }
+  uint64_t varint2() const { return varint2_; }
+  absl::string_view name() const { return name_; }
+  absl::string_view value() const { return value_; }
+
+  // Used by QpackEncoder, because in the first pass it stores absolute indices,
+  // which are converted into relative indices in the second pass after base is
+  // determined.
+  void set_varint(uint64_t varint) { varint_ = varint; }
+
+ private:
+  friend test::QpackInstructionWithValuesPeer;
+
+  QpackInstructionWithValues() = default;
+
+  // |*instruction| is not owned.
+  const QpackInstruction* instruction_ = nullptr;
+  bool s_bit_ = false;
+  uint64_t varint_ = 0;
+  uint64_t varint2_ = 0;
+  absl::string_view name_;
+  absl::string_view value_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
diff --git a/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc b/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc
new file mode 100644
index 0000000..a5cbc85
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+#include <iostream>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/qpack/qpack_offline_decoder.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+int main(int argc, char* argv[]) {
+  const char* usage =
+      "Usage: qpack_offline_decoder input_filename expected_headers_filename "
+      "....";
+  std::vector<std::string> args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+
+  if (args.size() < 2 || args.size() % 2 != 0) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    return 1;
+  }
+
+  size_t i;
+  size_t success_count = 0;
+  for (i = 0; 2 * i < args.size(); ++i) {
+    const absl::string_view input_filename(args[2 * i]);
+    const absl::string_view expected_headers_filename(args[2 * i + 1]);
+
+    // Every file represents a different connection,
+    // therefore every file needs a fresh decoding context.
+    quic::QpackOfflineDecoder decoder;
+    if (decoder.DecodeAndVerifyOfflineData(input_filename,
+                                           expected_headers_filename)) {
+      ++success_count;
+    }
+  }
+
+  std::cout << "Processed " << i << " pairs of input files, " << success_count
+            << " passed, " << (i - success_count) << " failed." << std::endl;
+
+  // Return success if all input files pass.
+  return (success_count == i) ? 0 : 1;
+}
diff --git a/quiche/quic/core/qpack/qpack_progressive_decoder.cc b/quiche/quic/core/qpack/qpack_progressive_decoder.cc
new file mode 100644
index 0000000..1a326d5
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_progressive_decoder.cc
@@ -0,0 +1,428 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_index_conversions.h"
+#include "quiche/quic/core/qpack/qpack_instructions.h"
+#include "quiche/quic/core/qpack/qpack_required_insert_count.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// The value argument passed to OnHeaderDecoded() is from an entry in the static
+// table.
+constexpr bool kValueFromStaticTable = true;
+
+}  // anonymous namespace
+
+QpackProgressiveDecoder::QpackProgressiveDecoder(
+    QuicStreamId stream_id, BlockedStreamLimitEnforcer* enforcer,
+    DecodingCompletedVisitor* visitor, QpackDecoderHeaderTable* header_table,
+    HeadersHandlerInterface* handler)
+    : stream_id_(stream_id),
+      prefix_decoder_(std::make_unique<QpackInstructionDecoder>(
+          QpackPrefixLanguage(), this)),
+      instruction_decoder_(QpackRequestStreamLanguage(), this),
+      enforcer_(enforcer),
+      visitor_(visitor),
+      header_table_(header_table),
+      handler_(handler),
+      required_insert_count_(0),
+      base_(0),
+      required_insert_count_so_far_(0),
+      prefix_decoded_(false),
+      blocked_(false),
+      decoding_(true),
+      error_detected_(false),
+      cancelled_(false) {}
+
+QpackProgressiveDecoder::~QpackProgressiveDecoder() {
+  if (blocked_ && !cancelled_) {
+    header_table_->UnregisterObserver(required_insert_count_, this);
+  }
+}
+
+void QpackProgressiveDecoder::Decode(absl::string_view data) {
+  QUICHE_DCHECK(decoding_);
+
+  if (data.empty() || error_detected_) {
+    return;
+  }
+
+  // Decode prefix byte by byte until the first (and only) instruction is
+  // decoded.
+  while (!prefix_decoded_) {
+    QUICHE_DCHECK(!blocked_);
+
+    if (!prefix_decoder_->Decode(data.substr(0, 1))) {
+      return;
+    }
+
+    // |prefix_decoder_->Decode()| must return false if an error is detected.
+    QUICHE_DCHECK(!error_detected_);
+
+    data = data.substr(1);
+    if (data.empty()) {
+      return;
+    }
+  }
+
+  if (blocked_) {
+    buffer_.append(data.data(), data.size());
+  } else {
+    QUICHE_DCHECK(buffer_.empty());
+
+    instruction_decoder_.Decode(data);
+  }
+}
+
+void QpackProgressiveDecoder::EndHeaderBlock() {
+  QUICHE_DCHECK(decoding_);
+  decoding_ = false;
+
+  if (!blocked_) {
+    FinishDecoding();
+  }
+}
+
+bool QpackProgressiveDecoder::OnInstructionDecoded(
+    const QpackInstruction* instruction) {
+  if (instruction == QpackPrefixInstruction()) {
+    return DoPrefixInstruction();
+  }
+
+  QUICHE_DCHECK(prefix_decoded_);
+  QUICHE_DCHECK_LE(required_insert_count_,
+                   header_table_->inserted_entry_count());
+
+  if (instruction == QpackIndexedHeaderFieldInstruction()) {
+    return DoIndexedHeaderFieldInstruction();
+  }
+  if (instruction == QpackIndexedHeaderFieldPostBaseInstruction()) {
+    return DoIndexedHeaderFieldPostBaseInstruction();
+  }
+  if (instruction == QpackLiteralHeaderFieldNameReferenceInstruction()) {
+    return DoLiteralHeaderFieldNameReferenceInstruction();
+  }
+  if (instruction == QpackLiteralHeaderFieldPostBaseInstruction()) {
+    return DoLiteralHeaderFieldPostBaseInstruction();
+  }
+  QUICHE_DCHECK_EQ(instruction, QpackLiteralHeaderFieldInstruction());
+  return DoLiteralHeaderFieldInstruction();
+}
+
+void QpackProgressiveDecoder::OnInstructionDecodingError(
+    QpackInstructionDecoder::ErrorCode /* error_code */,
+    absl::string_view error_message) {
+  // Ignore |error_code| and always use QUIC_QPACK_DECOMPRESSION_FAILED to avoid
+  // having to define a new QuicErrorCode for every instruction decoder error.
+  OnError(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
+}
+
+void QpackProgressiveDecoder::OnInsertCountReachedThreshold() {
+  QUICHE_DCHECK(blocked_);
+
+  // Clear |blocked_| before calling instruction_decoder_.Decode() below,
+  // because that might destroy |this| and ~QpackProgressiveDecoder() needs to
+  // know not to call UnregisterObserver().
+  blocked_ = false;
+  enforcer_->OnStreamUnblocked(stream_id_);
+
+  if (!buffer_.empty()) {
+    std::string buffer(std::move(buffer_));
+    buffer_.clear();
+    if (!instruction_decoder_.Decode(buffer)) {
+      // |this| might be destroyed.
+      return;
+    }
+  }
+
+  if (!decoding_) {
+    FinishDecoding();
+  }
+}
+
+void QpackProgressiveDecoder::Cancel() {
+  cancelled_ = true;
+}
+
+bool QpackProgressiveDecoder::DoIndexedHeaderFieldInstruction() {
+  if (!instruction_decoder_.s_bit()) {
+    uint64_t absolute_index;
+    if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
+            instruction_decoder_.varint(), base_, &absolute_index)) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
+      return false;
+    }
+
+    if (absolute_index >= required_insert_count_) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Absolute Index must be smaller than Required Insert Count.");
+      return false;
+    }
+
+    QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+    required_insert_count_so_far_ =
+        std::max(required_insert_count_so_far_, absolute_index + 1);
+
+    auto entry =
+        header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+    if (!entry) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Dynamic table entry already evicted.");
+      return false;
+    }
+
+    header_table_->set_dynamic_table_entry_referenced();
+    return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
+                           entry->value());
+  }
+
+  auto entry = header_table_->LookupEntry(/* is_static = */ true,
+                                          instruction_decoder_.varint());
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
+    return false;
+  }
+
+  return OnHeaderDecoded(kValueFromStaticTable, entry->name(), entry->value());
+}
+
+bool QpackProgressiveDecoder::DoIndexedHeaderFieldPostBaseInstruction() {
+  uint64_t absolute_index;
+  if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
+                                         &absolute_index)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
+    return false;
+  }
+
+  if (absolute_index >= required_insert_count_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Absolute Index must be smaller than Required Insert Count.");
+    return false;
+  }
+
+  QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+  required_insert_count_so_far_ =
+      std::max(required_insert_count_so_far_, absolute_index + 1);
+
+  auto entry =
+      header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Dynamic table entry already evicted.");
+    return false;
+  }
+
+  header_table_->set_dynamic_table_entry_referenced();
+  return OnHeaderDecoded(!kValueFromStaticTable, entry->name(), entry->value());
+}
+
+bool QpackProgressiveDecoder::DoLiteralHeaderFieldNameReferenceInstruction() {
+  if (!instruction_decoder_.s_bit()) {
+    uint64_t absolute_index;
+    if (!QpackRequestStreamRelativeIndexToAbsoluteIndex(
+            instruction_decoder_.varint(), base_, &absolute_index)) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid relative index.");
+      return false;
+    }
+
+    if (absolute_index >= required_insert_count_) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Absolute Index must be smaller than Required Insert Count.");
+      return false;
+    }
+
+    QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+    required_insert_count_so_far_ =
+        std::max(required_insert_count_so_far_, absolute_index + 1);
+
+    auto entry =
+        header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+    if (!entry) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Dynamic table entry already evicted.");
+      return false;
+    }
+
+    header_table_->set_dynamic_table_entry_referenced();
+    return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
+                           instruction_decoder_.value());
+  }
+
+  auto entry = header_table_->LookupEntry(/* is_static = */ true,
+                                          instruction_decoder_.varint());
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Static table entry not found.");
+    return false;
+  }
+
+  return OnHeaderDecoded(kValueFromStaticTable, entry->name(),
+                         instruction_decoder_.value());
+}
+
+bool QpackProgressiveDecoder::DoLiteralHeaderFieldPostBaseInstruction() {
+  uint64_t absolute_index;
+  if (!QpackPostBaseIndexToAbsoluteIndex(instruction_decoder_.varint(), base_,
+                                         &absolute_index)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Invalid post-base index.");
+    return false;
+  }
+
+  if (absolute_index >= required_insert_count_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Absolute Index must be smaller than Required Insert Count.");
+    return false;
+  }
+
+  QUICHE_DCHECK_LT(absolute_index, std::numeric_limits<uint64_t>::max());
+  required_insert_count_so_far_ =
+      std::max(required_insert_count_so_far_, absolute_index + 1);
+
+  auto entry =
+      header_table_->LookupEntry(/* is_static = */ false, absolute_index);
+  if (!entry) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Dynamic table entry already evicted.");
+    return false;
+  }
+
+  header_table_->set_dynamic_table_entry_referenced();
+  return OnHeaderDecoded(!kValueFromStaticTable, entry->name(),
+                         instruction_decoder_.value());
+}
+
+bool QpackProgressiveDecoder::DoLiteralHeaderFieldInstruction() {
+  return OnHeaderDecoded(!kValueFromStaticTable, instruction_decoder_.name(),
+                         instruction_decoder_.value());
+}
+
+bool QpackProgressiveDecoder::DoPrefixInstruction() {
+  QUICHE_DCHECK(!prefix_decoded_);
+
+  if (!QpackDecodeRequiredInsertCount(
+          prefix_decoder_->varint(), header_table_->max_entries(),
+          header_table_->inserted_entry_count(), &required_insert_count_)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Error decoding Required Insert Count.");
+    return false;
+  }
+
+  const bool sign = prefix_decoder_->s_bit();
+  const uint64_t delta_base = prefix_decoder_->varint2();
+  if (!DeltaBaseToBase(sign, delta_base, &base_)) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Error calculating Base.");
+    return false;
+  }
+
+  prefix_decoded_ = true;
+
+  if (required_insert_count_ > header_table_->inserted_entry_count()) {
+    if (!enforcer_->OnStreamBlocked(stream_id_)) {
+      OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+              "Limit on number of blocked streams exceeded.");
+      return false;
+    }
+    blocked_ = true;
+    header_table_->RegisterObserver(required_insert_count_, this);
+  }
+
+  return true;
+}
+
+bool QpackProgressiveDecoder::OnHeaderDecoded(bool value_from_static_table,
+                                              absl::string_view name,
+                                              absl::string_view value) {
+  // Skip test for static table entries as they are all known to be valid.
+  if (!value_from_static_table) {
+    // According to Section 10.3 of
+    // https://quicwg.org/base-drafts/draft-ietf-quic-http.html,
+    // "[...] HTTP/3 can transport field values that are not valid. While most
+    // values that can be encoded will not alter field parsing, carriage return
+    // (CR, ASCII 0x0d), line feed (LF, ASCII 0x0a), and the zero character
+    // (NUL, ASCII 0x00) might be exploited by an attacker if they are
+    // translated verbatim. Any request or response that contains a character
+    // not permitted in a field value MUST be treated as malformed [...]"
+    for (const auto c : value) {
+      if (c == '\0' || c == '\n' || c == '\r') {
+        OnError(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE,
+                "Invalid character in field value.");
+        return false;
+      }
+    }
+  }
+
+  handler_->OnHeaderDecoded(name, value);
+  return true;
+}
+
+void QpackProgressiveDecoder::FinishDecoding() {
+  QUICHE_DCHECK(buffer_.empty());
+  QUICHE_DCHECK(!blocked_);
+  QUICHE_DCHECK(!decoding_);
+
+  if (error_detected_) {
+    return;
+  }
+
+  if (!instruction_decoder_.AtInstructionBoundary()) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header block.");
+    return;
+  }
+
+  if (!prefix_decoded_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED, "Incomplete header data prefix.");
+    return;
+  }
+
+  if (required_insert_count_ != required_insert_count_so_far_) {
+    OnError(QUIC_QPACK_DECOMPRESSION_FAILED,
+            "Required Insert Count too large.");
+    return;
+  }
+
+  visitor_->OnDecodingCompleted(stream_id_, required_insert_count_);
+  handler_->OnDecodingCompleted();
+}
+
+void QpackProgressiveDecoder::OnError(QuicErrorCode error_code,
+                                      absl::string_view error_message) {
+  QUICHE_DCHECK(!error_detected_);
+
+  error_detected_ = true;
+  // Might destroy |this|.
+  handler_->OnDecodingErrorDetected(error_code, error_message);
+}
+
+bool QpackProgressiveDecoder::DeltaBaseToBase(bool sign,
+                                              uint64_t delta_base,
+                                              uint64_t* base) {
+  if (sign) {
+    if (delta_base == std::numeric_limits<uint64_t>::max() ||
+        required_insert_count_ < delta_base + 1) {
+      return false;
+    }
+    *base = required_insert_count_ - delta_base - 1;
+    return true;
+  }
+
+  if (delta_base >
+      std::numeric_limits<uint64_t>::max() - required_insert_count_) {
+    return false;
+  }
+  *base = required_insert_count_ + delta_base;
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_progressive_decoder.h b/quiche/quic/core/qpack/qpack_progressive_decoder.h
new file mode 100644
index 0000000..7616376
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_progressive_decoder.h
@@ -0,0 +1,183 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
+#include "quiche/quic/core/qpack/qpack_header_table.h"
+#include "quiche/quic/core/qpack/qpack_instruction_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QpackDecoderHeaderTable;
+
+// Class to decode a single header block.
+class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder
+    : public QpackInstructionDecoder::Delegate,
+      public QpackDecoderHeaderTable::Observer {
+ public:
+  // Interface for receiving decoded header block from the decoder.
+  class QUIC_EXPORT_PRIVATE HeadersHandlerInterface {
+   public:
+    virtual ~HeadersHandlerInterface() {}
+
+    // Called when a new header name-value pair is decoded.  Multiple values for
+    // a given name will be emitted as multiple calls to OnHeader.
+    virtual void OnHeaderDecoded(absl::string_view name,
+                                 absl::string_view value) = 0;
+
+    // Called when the header block is completely decoded.
+    // Indicates the total number of bytes in this block.
+    // The decoder will not access the handler after this call.
+    // Note that this method might not be called synchronously when the header
+    // block is received on the wire, in case decoding is blocked on receiving
+    // entries on the encoder stream.
+    virtual void OnDecodingCompleted() = 0;
+
+    // Called when a decoding error has occurred.  No other methods will be
+    // called afterwards.  Implementations are allowed to destroy
+    // the QpackProgressiveDecoder instance synchronously.
+    virtual void OnDecodingErrorDetected(QuicErrorCode error_code,
+                                         absl::string_view error_message) = 0;
+  };
+
+  // Interface for keeping track of blocked streams for the purpose of enforcing
+  // the limit communicated to peer via QPACK_BLOCKED_STREAMS settings.
+  class QUIC_EXPORT_PRIVATE BlockedStreamLimitEnforcer {
+   public:
+    virtual ~BlockedStreamLimitEnforcer() {}
+
+    // Called when the stream becomes blocked.  Returns true if allowed. Returns
+    // false if limit is violated, in which case QpackProgressiveDecoder signals
+    // an error.
+    // Stream must not be already blocked.
+    virtual bool OnStreamBlocked(QuicStreamId stream_id) = 0;
+
+    // Called when the stream becomes unblocked.
+    // Stream must be blocked.
+    virtual void OnStreamUnblocked(QuicStreamId stream_id) = 0;
+  };
+
+  // Visitor to be notified when decoding is completed.
+  class QUIC_EXPORT_PRIVATE DecodingCompletedVisitor {
+   public:
+    virtual ~DecodingCompletedVisitor() = default;
+
+    // Called when decoding is completed, with Required Insert Count of the
+    // decoded header block.  Required Insert Count is defined at
+    // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams.
+    virtual void OnDecodingCompleted(QuicStreamId stream_id,
+                                     uint64_t required_insert_count) = 0;
+  };
+
+  QpackProgressiveDecoder() = delete;
+  QpackProgressiveDecoder(QuicStreamId stream_id,
+                          BlockedStreamLimitEnforcer* enforcer,
+                          DecodingCompletedVisitor* visitor,
+                          QpackDecoderHeaderTable* header_table,
+                          HeadersHandlerInterface* handler);
+  QpackProgressiveDecoder(const QpackProgressiveDecoder&) = delete;
+  QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
+  ~QpackProgressiveDecoder() override;
+
+  // Provide a data fragment to decode.
+  void Decode(absl::string_view data);
+
+  // Signal that the entire header block has been received and passed in
+  // through Decode().  No methods must be called afterwards.
+  void EndHeaderBlock();
+
+  // QpackInstructionDecoder::Delegate implementation.
+  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
+  void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
+                                  absl::string_view error_message) override;
+
+  // QpackDecoderHeaderTable::Observer implementation.
+  void OnInsertCountReachedThreshold() override;
+  void Cancel() override;
+
+ private:
+  bool DoIndexedHeaderFieldInstruction();
+  bool DoIndexedHeaderFieldPostBaseInstruction();
+  bool DoLiteralHeaderFieldNameReferenceInstruction();
+  bool DoLiteralHeaderFieldPostBaseInstruction();
+  bool DoLiteralHeaderFieldInstruction();
+  bool DoPrefixInstruction();
+
+  // Called when an entry is decoded.  Performs validation and calls
+  // HeadersHandlerInterface::OnHeaderDecoded() or OnError() as needed.  Returns
+  // true if header value is valid, false otherwise.  Skips validation if
+  // |value_from_static_table| is true, because static table entries are always
+  // valid.
+  bool OnHeaderDecoded(bool value_from_static_table, absl::string_view name,
+                       absl::string_view value);
+
+  // Called as soon as EndHeaderBlock() is called and decoding is not blocked.
+  void FinishDecoding();
+
+  // Called on error.
+  void OnError(QuicErrorCode error_code, absl::string_view error_message);
+
+  // Calculates Base from |required_insert_count_|, which must be set before
+  // calling this method, and sign bit and Delta Base in the Header Data Prefix,
+  // which are passed in as arguments.  Returns true on success, false on
+  // failure due to overflow/underflow.
+  bool DeltaBaseToBase(bool sign, uint64_t delta_base, uint64_t* base);
+
+  const QuicStreamId stream_id_;
+
+  // |prefix_decoder_| only decodes a handful of bytes then it can be
+  // destroyed to conserve memory.  |instruction_decoder_|, on the other hand,
+  // is used until the entire header block is decoded.
+  std::unique_ptr<QpackInstructionDecoder> prefix_decoder_;
+  QpackInstructionDecoder instruction_decoder_;
+
+  BlockedStreamLimitEnforcer* const enforcer_;
+  DecodingCompletedVisitor* const visitor_;
+  QpackDecoderHeaderTable* const header_table_;
+  HeadersHandlerInterface* const handler_;
+
+  // Required Insert Count and Base are decoded from the Header Data Prefix.
+  uint64_t required_insert_count_;
+  uint64_t base_;
+
+  // Required Insert Count is one larger than the largest absolute index of all
+  // referenced dynamic table entries, or zero if no dynamic table entries are
+  // referenced.  |required_insert_count_so_far_| starts out as zero and keeps
+  // track of the Required Insert Count based on entries decoded so far.
+  // After decoding is completed, it is compared to |required_insert_count_|.
+  uint64_t required_insert_count_so_far_;
+
+  // False until prefix is fully read and decoded.
+  bool prefix_decoded_;
+
+  // True if waiting for dynamic table entries to arrive.
+  bool blocked_;
+
+  // Buffer the entire header block after the prefix while decoding is blocked.
+  std::string buffer_;
+
+  // True until EndHeaderBlock() is called.
+  bool decoding_;
+
+  // True if a decoding error has been detected.
+  bool error_detected_;
+
+  // True if QpackDecoderHeaderTable has been destroyed
+  // while decoding is still blocked.
+  bool cancelled_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
diff --git a/quiche/quic/core/qpack/qpack_receive_stream.cc b/quiche/quic/core/qpack/qpack_receive_stream.cc
new file mode 100644
index 0000000..b00a06f
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_receive_stream.cc
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_receive_stream.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_session.h"
+
+namespace quic {
+QpackReceiveStream::QpackReceiveStream(PendingStream* pending,
+                                       QuicSession* session,
+                                       QpackStreamReceiver* receiver)
+    : QuicStream(pending, session, /*is_static=*/true), receiver_(receiver) {}
+
+void QpackReceiveStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "RESET_STREAM received for QPACK receive stream");
+}
+
+void QpackReceiveStream::OnDataAvailable() {
+  iovec iov;
+  while (!reading_stopped() && sequencer()->GetReadableRegion(&iov)) {
+    QUICHE_DCHECK(!sequencer()->IsClosed());
+
+    receiver_->Decode(absl::string_view(
+        reinterpret_cast<const char*>(iov.iov_base), iov.iov_len));
+    sequencer()->MarkConsumed(iov.iov_len);
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_receive_stream.h b/quiche/quic/core/qpack/qpack_receive_stream.h
new file mode 100644
index 0000000..0509fae
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_receive_stream.h
@@ -0,0 +1,42 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
+
+#include "quiche/quic/core/qpack/qpack_stream_receiver.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicSession;
+
+// QPACK 4.2.1 Encoder and Decoder Streams.
+// The QPACK receive stream is peer initiated and is read only.
+class QUIC_EXPORT_PRIVATE QpackReceiveStream : public QuicStream {
+ public:
+  // Construct receive stream from pending stream, the |pending| object needs
+  // to be deleted after the construction.
+  QpackReceiveStream(PendingStream* pending,
+                     QuicSession* session,
+                     QpackStreamReceiver* receiver);
+  QpackReceiveStream(const QpackReceiveStream&) = delete;
+  QpackReceiveStream& operator=(const QpackReceiveStream&) = delete;
+  ~QpackReceiveStream() override = default;
+
+  // Overriding QuicStream::OnStreamReset to make sure QPACK stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // Implementation of QuicStream.
+  void OnDataAvailable() override;
+
+ private:
+  QpackStreamReceiver* receiver_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_RECEIVE_STREAM_H_
diff --git a/quiche/quic/core/qpack/qpack_receive_stream_test.cc b/quiche/quic/core/qpack/qpack_receive_stream_test.cc
new file mode 100644
index 0000000..c148510
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_receive_stream_test.cc
@@ -0,0 +1,98 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_receive_stream.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: version: "
+                   << ParsedQuicVersionToString(version)
+                   << ", perspective: " << perspective;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class QpackReceiveStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QpackReceiveStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_,
+            &alarm_factory_,
+            perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    QuicStreamId id = perspective() == Perspective::IS_SERVER
+                          ? GetNthClientInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3)
+                          : GetNthServerInitiatedUnidirectionalStreamId(
+                                session_.transport_version(), 3);
+    char type[] = {0x03};
+    QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
+    session_.OnStreamFrame(data1);
+    qpack_receive_stream_ =
+        QuicSpdySessionPeer::GetQpackDecoderReceiveStream(&session_);
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QpackReceiveStream* qpack_receive_stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QpackReceiveStreamTest,
+                         ::testing::ValuesIn(GetTestParams()));
+
+TEST_P(QpackReceiveStreamTest, ResetQpackReceiveStream) {
+  EXPECT_TRUE(qpack_receive_stream_->is_static());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId,
+                               qpack_receive_stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  qpack_receive_stream_->OnStreamReset(rst_frame);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_required_insert_count.cc b/quiche/quic/core/qpack/qpack_required_insert_count.cc
new file mode 100644
index 0000000..544dffe
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_required_insert_count.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_required_insert_count.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+uint64_t QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
+                                        uint64_t max_entries) {
+  if (required_insert_count == 0) {
+    return 0;
+  }
+
+  return required_insert_count % (2 * max_entries) + 1;
+}
+
+bool QpackDecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
+                                    uint64_t max_entries,
+                                    uint64_t total_number_of_inserts,
+                                    uint64_t* required_insert_count) {
+  if (encoded_required_insert_count == 0) {
+    *required_insert_count = 0;
+    return true;
+  }
+
+  // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
+  // precluding all calculations in this method from overflowing.
+  QUICHE_DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
+
+  if (encoded_required_insert_count > 2 * max_entries) {
+    return false;
+  }
+
+  *required_insert_count = encoded_required_insert_count - 1;
+  QUICHE_DCHECK_LT(*required_insert_count,
+                   std::numeric_limits<uint64_t>::max() / 16);
+
+  uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
+  QUICHE_DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
+
+  if (current_wrapped >= *required_insert_count + max_entries) {
+    // Required Insert Count wrapped around 1 extra time.
+    *required_insert_count += 2 * max_entries;
+  } else if (current_wrapped + max_entries < *required_insert_count) {
+    // Decoder wrapped around 1 extra time.
+    current_wrapped += 2 * max_entries;
+  }
+
+  if (*required_insert_count >
+      std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
+    return false;
+  }
+
+  *required_insert_count += total_number_of_inserts;
+
+  // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
+  if (current_wrapped >= *required_insert_count) {
+    return false;
+  }
+
+  *required_insert_count -= current_wrapped;
+
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_required_insert_count.h b/quiche/quic/core/qpack/qpack_required_insert_count.h
new file mode 100644
index 0000000..9b4252e
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_required_insert_count.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
+#define QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Calculate Encoded Required Insert Count from Required Insert Count and
+// MaxEntries according to
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.
+QUIC_EXPORT_PRIVATE uint64_t
+QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
+                               uint64_t max_entries);
+
+// Calculate Required Insert Count from Encoded Required Insert Count,
+// MaxEntries, and total number of dynamic table insertions according to
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.  Returns true
+// on success, false on invalid input or overflow/underflow.
+QUIC_EXPORT_PRIVATE bool QpackDecodeRequiredInsertCount(
+    uint64_t encoded_required_insert_count,
+    uint64_t max_entries,
+    uint64_t total_number_of_inserts,
+    uint64_t* required_insert_count);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
diff --git a/quiche/quic/core/qpack/qpack_required_insert_count_test.cc b/quiche/quic/core/qpack/qpack_required_insert_count_test.cc
new file mode 100644
index 0000000..95456b9
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_required_insert_count_test.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_required_insert_count.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(QpackRequiredInsertCountTest, QpackEncodeRequiredInsertCount) {
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 0));
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 8));
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 1024));
+
+  EXPECT_EQ(2u, QpackEncodeRequiredInsertCount(1, 8));
+  EXPECT_EQ(5u, QpackEncodeRequiredInsertCount(20, 8));
+  EXPECT_EQ(7u, QpackEncodeRequiredInsertCount(106, 10));
+}
+
+// For testing valid decodings, the Encoded Required Insert Count is calculated
+// from Required Insert Count, so that there is an expected value to compare
+// the decoded value against, and so that intricate inequalities can be
+// documented.
+struct {
+  uint64_t required_insert_count;
+  uint64_t max_entries;
+  uint64_t total_number_of_inserts;
+} kTestData[] = {
+    // Maximum dynamic table capacity is zero.
+    {0, 0, 0},
+    // No dynamic entries in header.
+    {0, 100, 0},
+    {0, 100, 500},
+    // Required Insert Count has not wrapped around yet, no entries evicted.
+    {15, 100, 25},
+    {20, 100, 10},
+    // Required Insert Count has not wrapped around yet, some entries evicted.
+    {90, 100, 110},
+    // Required Insert Count has wrapped around.
+    {234, 100, 180},
+    // Required Insert Count has wrapped around many times.
+    {5678, 100, 5701},
+    // Lowest and highest possible Required Insert Count values
+    // for given MaxEntries and total number of insertions.
+    {401, 100, 500},
+    {600, 100, 500}};
+
+TEST(QpackRequiredInsertCountTest, QpackDecodeRequiredInsertCount) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
+    const uint64_t required_insert_count = kTestData[i].required_insert_count;
+    const uint64_t max_entries = kTestData[i].max_entries;
+    const uint64_t total_number_of_inserts =
+        kTestData[i].total_number_of_inserts;
+
+    if (required_insert_count != 0) {
+      // Dynamic entries cannot be referenced if dynamic table capacity is zero.
+      ASSERT_LT(0u, max_entries) << i;
+      // Entry |total_number_of_inserts - 1 - max_entries| and earlier entries
+      // are evicted.  Entry |required_insert_count - 1| is referenced.  No
+      // evicted entry can be referenced.
+      ASSERT_LT(total_number_of_inserts, required_insert_count + max_entries)
+          << i;
+      // Entry |required_insert_count - 1 - max_entries| and earlier entries are
+      // evicted, entry |total_number_of_inserts - 1| is the last acknowledged
+      // entry.  Every evicted entry must be acknowledged.
+      ASSERT_LE(required_insert_count, total_number_of_inserts + max_entries)
+          << i;
+    }
+
+    uint64_t encoded_required_insert_count =
+        QpackEncodeRequiredInsertCount(required_insert_count, max_entries);
+
+    // Initialize to a value different from the expected output to confirm that
+    // QpackDecodeRequiredInsertCount() modifies the value of
+    // |decoded_required_insert_count|.
+    uint64_t decoded_required_insert_count = required_insert_count + 1;
+    EXPECT_TRUE(QpackDecodeRequiredInsertCount(
+        encoded_required_insert_count, max_entries, total_number_of_inserts,
+        &decoded_required_insert_count))
+        << i;
+
+    EXPECT_EQ(decoded_required_insert_count, required_insert_count) << i;
+  }
+}
+
+// Failures are tested with hardcoded values for encoded required insert count,
+// to provide test coverage for values that would never be produced by a well
+// behaved encoding function.
+struct {
+  uint64_t encoded_required_insert_count;
+  uint64_t max_entries;
+  uint64_t total_number_of_inserts;
+} kInvalidTestData[] = {
+    // Maximum dynamic table capacity is zero, yet header block
+    // claims to have a reference to a dynamic table entry.
+    {1, 0, 0},
+    {9, 0, 0},
+    // Examples from
+    // https://github.com/quicwg/base-drafts/issues/2112#issue-389626872.
+    {1, 10, 2},
+    {18, 10, 2},
+    // Encoded Required Insert Count value too small or too large
+    // for given MaxEntries and total number of insertions.
+    {400, 100, 500},
+    {601, 100, 500}};
+
+TEST(QpackRequiredInsertCountTest, DecodeRequiredInsertCountError) {
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kInvalidTestData); ++i) {
+    uint64_t decoded_required_insert_count = 0;
+    EXPECT_FALSE(QpackDecodeRequiredInsertCount(
+        kInvalidTestData[i].encoded_required_insert_count,
+        kInvalidTestData[i].max_entries,
+        kInvalidTestData[i].total_number_of_inserts,
+        &decoded_required_insert_count))
+        << i;
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_round_trip_test.cc b/quiche/quic/core/qpack/qpack_round_trip_test.cc
new file mode 100644
index 0000000..d729793
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_round_trip_test.cc
@@ -0,0 +1,137 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <tuple>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+using ::testing::Values;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QpackRoundTripTest : public QuicTestWithParam<FragmentMode> {
+ public:
+  QpackRoundTripTest() = default;
+  ~QpackRoundTripTest() override = default;
+
+  spdy::Http2HeaderBlock EncodeThenDecode(
+      const spdy::Http2HeaderBlock& header_list) {
+    NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
+    NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
+    QpackEncoder encoder(&decoder_stream_error_delegate);
+    encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate);
+    std::string encoded_header_block =
+        encoder.EncodeHeaderList(/* stream_id = */ 1, header_list, nullptr);
+
+    TestHeadersHandler handler;
+    NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;
+    NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
+    // TODO(b/112770235): Test dynamic table and blocked streams.
+    QpackDecode(
+        /* maximum_dynamic_table_capacity = */ 0,
+        /* maximum_blocked_streams = */ 0, &encoder_stream_error_delegate,
+        &decoder_stream_sender_delegate, &handler,
+        FragmentModeToFragmentSizeGenerator(GetParam()), encoded_header_block);
+
+    EXPECT_TRUE(handler.decoding_completed());
+    EXPECT_FALSE(handler.decoding_error_detected());
+
+    return handler.ReleaseHeaderList();
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         QpackRoundTripTest,
+                         Values(FragmentMode::kSingleChunk,
+                                FragmentMode::kOctetByOctet));
+
+TEST_P(QpackRoundTripTest, Empty) {
+  spdy::Http2HeaderBlock header_list;
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, EmptyName) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list[""] = "bar";
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, EmptyValue) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "";
+  header_list[""] = "";
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, MultipleWithLongEntries) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = "bar";
+  header_list[":path"] = "/";
+  header_list["foobaar"] = std::string(127, 'Z');
+  header_list[std::string(1000, 'b')] = std::string(1000, 'c');
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+TEST_P(QpackRoundTripTest, StaticTable) {
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "GET";
+    header_list["accept-encoding"] = "gzip, deflate";
+    header_list["cache-control"] = "";
+    header_list["foo"] = "bar";
+    header_list[":path"] = "/";
+
+    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+    EXPECT_EQ(header_list, output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "POST";
+    header_list["accept-encoding"] = "brotli";
+    header_list["cache-control"] = "foo";
+    header_list["foo"] = "bar";
+    header_list[":path"] = "/";
+
+    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+    EXPECT_EQ(header_list, output);
+  }
+  {
+    spdy::Http2HeaderBlock header_list;
+    header_list[":method"] = "CONNECT";
+    header_list["accept-encoding"] = "";
+    header_list["foo"] = "bar";
+    header_list[":path"] = "/";
+
+    spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+    EXPECT_EQ(header_list, output);
+  }
+}
+
+TEST_P(QpackRoundTripTest, ValueHasNullCharacter) {
+  spdy::Http2HeaderBlock header_list;
+  header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
+
+  spdy::Http2HeaderBlock output = EncodeThenDecode(header_list);
+  EXPECT_EQ(header_list, output);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_send_stream.cc b/quiche/quic/core/qpack/qpack_send_stream.cc
new file mode 100644
index 0000000..c7be858
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_send_stream.cc
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_send_stream.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_session.h"
+
+namespace quic {
+QpackSendStream::QpackSendStream(QuicStreamId id,
+                                 QuicSession* session,
+                                 uint64_t http3_stream_type)
+    : QuicStream(id, session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
+      http3_stream_type_(http3_stream_type),
+      stream_type_sent_(false) {}
+
+void QpackSendStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  QUIC_BUG(quic_bug_10805_1)
+      << "OnStreamReset() called for write unidirectional stream.";
+}
+
+bool QpackSendStream::OnStopSending(QuicResetStreamError /* code */) {
+  stream_delegate()->OnStreamError(
+      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
+      "STOP_SENDING received for QPACK send stream");
+  return false;
+}
+
+void QpackSendStream::WriteStreamData(absl::string_view data) {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendStreamType();
+  WriteOrBufferData(data, false, nullptr);
+}
+
+uint64_t QpackSendStream::NumBytesBuffered() const {
+  return QuicStream::BufferedDataBytes();
+}
+
+void QpackSendStream::MaybeSendStreamType() {
+  if (!stream_type_sent_) {
+    char type[sizeof(http3_stream_type_)];
+    QuicDataWriter writer(ABSL_ARRAYSIZE(type), type);
+    writer.WriteVarInt62(http3_stream_type_);
+    WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
+                      nullptr);
+    stream_type_sent_ = true;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_send_stream.h b/quiche/quic/core/qpack/qpack_send_stream.h
new file mode 100644
index 0000000..51cb25f
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_send_stream.h
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QuicSession;
+
+// QPACK 4.2.1 Encoder and Decoder Streams.
+// The QPACK send stream is self initiated and is write only.
+class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream,
+                                            public QpackStreamSenderDelegate {
+ public:
+  // |session| can't be nullptr, and the ownership is not passed. |session| owns
+  // this stream.
+  QpackSendStream(QuicStreamId id,
+                  QuicSession* session,
+                  uint64_t http3_stream_type);
+  QpackSendStream(const QpackSendStream&) = delete;
+  QpackSendStream& operator=(const QpackSendStream&) = delete;
+  ~QpackSendStream() override = default;
+
+  // Overriding QuicStream::OnStopSending() to make sure QPACK stream is never
+  // closed before connection.
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+  bool OnStopSending(QuicResetStreamError code) override;
+
+  // The send QPACK stream is write unidirectional, so this method
+  // should never be called.
+  void OnDataAvailable() override { QUIC_NOTREACHED(); }
+
+  // Writes the instructions to peer. The stream type will be sent
+  // before the first instruction so that the peer can open an qpack stream.
+  void WriteStreamData(absl::string_view data) override;
+
+  // Return the number of bytes buffered due to underlying stream being blocked.
+  uint64_t NumBytesBuffered() const override;
+
+  // TODO(b/112770235): Remove this method once QuicStreamIdManager supports
+  // creating HTTP/3 unidirectional streams dynamically.
+  void MaybeSendStreamType();
+
+ private:
+  const uint64_t http3_stream_type_;
+  bool stream_type_sent_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_SEND_STREAM_H_
diff --git a/quiche/quic/core/qpack/qpack_send_stream_test.cc b/quiche/quic/core/qpack/qpack_send_stream_test.cc
new file mode 100644
index 0000000..40d679d
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_send_stream_test.cc
@@ -0,0 +1,136 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_send_stream.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+
+struct TestParams {
+  TestParams(const ParsedQuicVersion& version, Perspective perspective)
+      : version(version), perspective(perspective) {
+    QUIC_LOG(INFO) << "TestParams: version: "
+                   << ParsedQuicVersionToString(version)
+                   << ", perspective: " << perspective;
+  }
+
+  TestParams(const TestParams& other)
+      : version(other.version), perspective(other.perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& tp) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(tp.version), "_",
+      (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (const auto& version : AllSupportedVersions()) {
+    if (!VersionUsesHttp3(version.transport_version)) {
+      continue;
+    }
+    for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+      params.emplace_back(version, p);
+    }
+  }
+  return params;
+}
+
+class QpackSendStreamTest : public QuicTestWithParam<TestParams> {
+ public:
+  QpackSendStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_,
+            &alarm_factory_,
+            perspective(),
+            SupportedVersions(GetParam().version))),
+        session_(connection_) {
+    EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    if (connection_->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
+    session_.OnConfigNegotiated();
+
+    qpack_send_stream_ =
+        QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
+
+    ON_CALL(session_, WritevData(_, _, _, _, _, _))
+        .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  }
+
+  Perspective perspective() const { return GetParam().perspective; }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSpdySession> session_;
+  QpackSendStream* qpack_send_stream_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QpackSendStreamTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) {
+  std::string data = "data";
+  EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _));
+  EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
+  qpack_send_stream_->WriteStreamData(absl::string_view(data));
+
+  EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
+  qpack_send_stream_->WriteStreamData(absl::string_view(data));
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
+  qpack_send_stream_->MaybeSendStreamType();
+}
+
+TEST_P(QpackSendStreamTest, StopSendingQpackStream) {
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
+  qpack_send_stream_->OnStopSending(
+      QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
+}
+
+TEST_P(QpackSendStreamTest, ReceiveDataOnSendStream) {
+  QuicStreamFrame frame(qpack_send_stream_->id(), false, 0, "test");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
+  qpack_send_stream_->OnStreamFrame(frame);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_static_table.cc b/quiche/quic/core/qpack/qpack_static_table.cc
new file mode 100644
index 0000000..fc85667
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_static_table.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_static_table.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// The "constructor" for a QpackStaticEntry that computes the lengths at
+// compile time.
+#define STATIC_ENTRY(name, value) \
+  { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 }
+
+const std::vector<QpackStaticEntry>& QpackStaticTableVector() {
+  static const auto* kQpackStaticTable = new std::vector<QpackStaticEntry>{
+      STATIC_ENTRY(":authority", ""),                                     // 0
+      STATIC_ENTRY(":path", "/"),                                         // 1
+      STATIC_ENTRY("age", "0"),                                           // 2
+      STATIC_ENTRY("content-disposition", ""),                            // 3
+      STATIC_ENTRY("content-length", "0"),                                // 4
+      STATIC_ENTRY("cookie", ""),                                         // 5
+      STATIC_ENTRY("date", ""),                                           // 6
+      STATIC_ENTRY("etag", ""),                                           // 7
+      STATIC_ENTRY("if-modified-since", ""),                              // 8
+      STATIC_ENTRY("if-none-match", ""),                                  // 9
+      STATIC_ENTRY("last-modified", ""),                                  // 10
+      STATIC_ENTRY("link", ""),                                           // 11
+      STATIC_ENTRY("location", ""),                                       // 12
+      STATIC_ENTRY("referer", ""),                                        // 13
+      STATIC_ENTRY("set-cookie", ""),                                     // 14
+      STATIC_ENTRY(":method", "CONNECT"),                                 // 15
+      STATIC_ENTRY(":method", "DELETE"),                                  // 16
+      STATIC_ENTRY(":method", "GET"),                                     // 17
+      STATIC_ENTRY(":method", "HEAD"),                                    // 18
+      STATIC_ENTRY(":method", "OPTIONS"),                                 // 19
+      STATIC_ENTRY(":method", "POST"),                                    // 20
+      STATIC_ENTRY(":method", "PUT"),                                     // 21
+      STATIC_ENTRY(":scheme", "http"),                                    // 22
+      STATIC_ENTRY(":scheme", "https"),                                   // 23
+      STATIC_ENTRY(":status", "103"),                                     // 24
+      STATIC_ENTRY(":status", "200"),                                     // 25
+      STATIC_ENTRY(":status", "304"),                                     // 26
+      STATIC_ENTRY(":status", "404"),                                     // 27
+      STATIC_ENTRY(":status", "503"),                                     // 28
+      STATIC_ENTRY("accept", "*/*"),                                      // 29
+      STATIC_ENTRY("accept", "application/dns-message"),                  // 30
+      STATIC_ENTRY("accept-encoding", "gzip, deflate, br"),               // 31
+      STATIC_ENTRY("accept-ranges", "bytes"),                             // 32
+      STATIC_ENTRY("access-control-allow-headers", "cache-control"),      // 33
+      STATIC_ENTRY("access-control-allow-headers", "content-type"),       // 35
+      STATIC_ENTRY("access-control-allow-origin", "*"),                   // 35
+      STATIC_ENTRY("cache-control", "max-age=0"),                         // 36
+      STATIC_ENTRY("cache-control", "max-age=2592000"),                   // 37
+      STATIC_ENTRY("cache-control", "max-age=604800"),                    // 38
+      STATIC_ENTRY("cache-control", "no-cache"),                          // 39
+      STATIC_ENTRY("cache-control", "no-store"),                          // 40
+      STATIC_ENTRY("cache-control", "public, max-age=31536000"),          // 41
+      STATIC_ENTRY("content-encoding", "br"),                             // 42
+      STATIC_ENTRY("content-encoding", "gzip"),                           // 43
+      STATIC_ENTRY("content-type", "application/dns-message"),            // 44
+      STATIC_ENTRY("content-type", "application/javascript"),             // 45
+      STATIC_ENTRY("content-type", "application/json"),                   // 46
+      STATIC_ENTRY("content-type", "application/x-www-form-urlencoded"),  // 47
+      STATIC_ENTRY("content-type", "image/gif"),                          // 48
+      STATIC_ENTRY("content-type", "image/jpeg"),                         // 49
+      STATIC_ENTRY("content-type", "image/png"),                          // 50
+      STATIC_ENTRY("content-type", "text/css"),                           // 51
+      STATIC_ENTRY("content-type", "text/html; charset=utf-8"),           // 52
+      STATIC_ENTRY("content-type", "text/plain"),                         // 53
+      STATIC_ENTRY("content-type", "text/plain;charset=utf-8"),           // 54
+      STATIC_ENTRY("range", "bytes=0-"),                                  // 55
+      STATIC_ENTRY("strict-transport-security", "max-age=31536000"),      // 56
+      STATIC_ENTRY("strict-transport-security",
+                   "max-age=31536000; includesubdomains"),  // 57
+      STATIC_ENTRY("strict-transport-security",
+                   "max-age=31536000; includesubdomains; preload"),        // 58
+      STATIC_ENTRY("vary", "accept-encoding"),                             // 59
+      STATIC_ENTRY("vary", "origin"),                                      // 60
+      STATIC_ENTRY("x-content-type-options", "nosniff"),                   // 61
+      STATIC_ENTRY("x-xss-protection", "1; mode=block"),                   // 62
+      STATIC_ENTRY(":status", "100"),                                      // 63
+      STATIC_ENTRY(":status", "204"),                                      // 64
+      STATIC_ENTRY(":status", "206"),                                      // 65
+      STATIC_ENTRY(":status", "302"),                                      // 66
+      STATIC_ENTRY(":status", "400"),                                      // 67
+      STATIC_ENTRY(":status", "403"),                                      // 68
+      STATIC_ENTRY(":status", "421"),                                      // 69
+      STATIC_ENTRY(":status", "425"),                                      // 70
+      STATIC_ENTRY(":status", "500"),                                      // 71
+      STATIC_ENTRY("accept-language", ""),                                 // 72
+      STATIC_ENTRY("access-control-allow-credentials", "FALSE"),           // 73
+      STATIC_ENTRY("access-control-allow-credentials", "TRUE"),            // 74
+      STATIC_ENTRY("access-control-allow-headers", "*"),                   // 75
+      STATIC_ENTRY("access-control-allow-methods", "get"),                 // 76
+      STATIC_ENTRY("access-control-allow-methods", "get, post, options"),  // 77
+      STATIC_ENTRY("access-control-allow-methods", "options"),             // 78
+      STATIC_ENTRY("access-control-expose-headers", "content-length"),     // 79
+      STATIC_ENTRY("access-control-request-headers", "content-type"),      // 80
+      STATIC_ENTRY("access-control-request-method", "get"),                // 81
+      STATIC_ENTRY("access-control-request-method", "post"),               // 82
+      STATIC_ENTRY("alt-svc", "clear"),                                    // 83
+      STATIC_ENTRY("authorization", ""),                                   // 84
+      STATIC_ENTRY(
+          "content-security-policy",
+          "script-src 'none'; object-src 'none'; base-uri 'none'"),  // 85
+      STATIC_ENTRY("early-data", "1"),                               // 86
+      STATIC_ENTRY("expect-ct", ""),                                 // 87
+      STATIC_ENTRY("forwarded", ""),                                 // 88
+      STATIC_ENTRY("if-range", ""),                                  // 89
+      STATIC_ENTRY("origin", ""),                                    // 90
+      STATIC_ENTRY("purpose", "prefetch"),                           // 91
+      STATIC_ENTRY("server", ""),                                    // 92
+      STATIC_ENTRY("timing-allow-origin", "*"),                      // 93
+      STATIC_ENTRY("upgrade-insecure-requests", "1"),                // 94
+      STATIC_ENTRY("user-agent", ""),                                // 95
+      STATIC_ENTRY("x-forwarded-for", ""),                           // 96
+      STATIC_ENTRY("x-frame-options", "deny"),                       // 97
+      STATIC_ENTRY("x-frame-options", "sameorigin"),                 // 98
+  };
+  return *kQpackStaticTable;
+}
+
+#undef STATIC_ENTRY
+
+const QpackStaticTable& ObtainQpackStaticTable() {
+  static const QpackStaticTable* const shared_static_table = []() {
+    auto* table = new QpackStaticTable();
+    table->Initialize(QpackStaticTableVector().data(),
+                      QpackStaticTableVector().size());
+    QUICHE_CHECK(table->IsInitialized());
+    return table;
+  }();
+  return *shared_static_table;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_static_table.h b/quiche/quic/core/qpack/qpack_static_table.h
new file mode 100644
index 0000000..43fd297
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_static_table.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
+
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+namespace quic {
+
+using QpackStaticEntry = spdy::HpackStaticEntry;
+using QpackStaticTable = spdy::HpackStaticTable;
+
+// QPACK static table defined at
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#static-table.
+QUIC_EXPORT_PRIVATE const std::vector<QpackStaticEntry>&
+QpackStaticTableVector();
+
+// Returns a QpackStaticTable instance initialized with kQpackStaticTable.
+// The instance is read-only, has static lifetime, and is safe to share amoung
+// threads. This function is thread-safe.
+QUIC_EXPORT_PRIVATE const QpackStaticTable& ObtainQpackStaticTable();
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STATIC_TABLE_H_
diff --git a/quiche/quic/core/qpack/qpack_static_table_test.cc b/quiche/quic/core/qpack/qpack_static_table_test.cc
new file mode 100644
index 0000000..67cd9c0
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_static_table_test.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/qpack_static_table.h"
+
+#include <set>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+// Check that an initialized instance has the right number of entries.
+TEST(QpackStaticTableTest, Initialize) {
+  QpackStaticTable table;
+  EXPECT_FALSE(table.IsInitialized());
+
+  table.Initialize(QpackStaticTableVector().data(),
+                   QpackStaticTableVector().size());
+  EXPECT_TRUE(table.IsInitialized());
+
+  const auto& static_entries = table.GetStaticEntries();
+  EXPECT_EQ(QpackStaticTableVector().size(), static_entries.size());
+
+  const auto& static_index = table.GetStaticIndex();
+  EXPECT_EQ(QpackStaticTableVector().size(), static_index.size());
+
+  const auto& static_name_index = table.GetStaticNameIndex();
+  // Count distinct names in static table.
+  std::set<absl::string_view> names;
+  for (const auto& entry : static_entries) {
+    names.insert(entry.name());
+  }
+  EXPECT_EQ(names.size(), static_name_index.size());
+}
+
+// Test that ObtainQpackStaticTable returns the same instance every time.
+TEST(QpackStaticTableTest, IsSingleton) {
+  const QpackStaticTable* static_table_one = &ObtainQpackStaticTable();
+  const QpackStaticTable* static_table_two = &ObtainQpackStaticTable();
+  EXPECT_EQ(static_table_one, static_table_two);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/qpack_stream_receiver.h b/quiche/quic/core/qpack/qpack_stream_receiver.h
new file mode 100644
index 0000000..ad95cce
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_stream_receiver.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This interface decodes QPACK data that are received on a QpackReceiveStream.
+class QUIC_EXPORT_PRIVATE QpackStreamReceiver {
+ public:
+  virtual ~QpackStreamReceiver() = default;
+
+  // Decode data.
+  virtual void Decode(absl::string_view data) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_RECEIVER_H_
diff --git a/quiche/quic/core/qpack/qpack_stream_sender_delegate.h b/quiche/quic/core/qpack/qpack_stream_sender_delegate.h
new file mode 100644
index 0000000..8e267db
--- /dev/null
+++ b/quiche/quic/core/qpack/qpack_stream_sender_delegate.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// This interface writes encoder/decoder data to peer.
+class QUIC_EXPORT_PRIVATE QpackStreamSenderDelegate {
+ public:
+  virtual ~QpackStreamSenderDelegate() = default;
+
+  // Write data on the unidirectional stream.
+  virtual void WriteStreamData(absl::string_view data) = 0;
+
+  // Return the number of bytes buffered due to underlying stream being blocked.
+  virtual uint64_t NumBytesBuffered() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_STREAM_SENDER_DELEGATE_H_
diff --git a/quiche/quic/core/qpack/value_splitting_header_list.cc b/quiche/quic/core/qpack/value_splitting_header_list.cc
new file mode 100644
index 0000000..41fd4c0
--- /dev/null
+++ b/quiche/quic/core/qpack/value_splitting_header_list.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/value_splitting_header_list.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+
+const char kCookieKey[] = "cookie";
+const char kCookieSeparator = ';';
+const char kOptionalSpaceAfterCookieSeparator = ' ';
+const char kNonCookieSeparator = '\0';
+
+}  // namespace
+
+ValueSplittingHeaderList::const_iterator::const_iterator(
+    const spdy::Http2HeaderBlock* header_list,
+    spdy::Http2HeaderBlock::const_iterator header_list_iterator)
+    : header_list_(header_list),
+      header_list_iterator_(header_list_iterator),
+      value_start_(0) {
+  UpdateHeaderField();
+}
+
+bool ValueSplittingHeaderList::const_iterator::operator==(
+    const const_iterator& other) const {
+  return header_list_iterator_ == other.header_list_iterator_ &&
+         value_start_ == other.value_start_;
+}
+
+bool ValueSplittingHeaderList::const_iterator::operator!=(
+    const const_iterator& other) const {
+  return !(*this == other);
+}
+
+const ValueSplittingHeaderList::const_iterator&
+ValueSplittingHeaderList::const_iterator::operator++() {
+  if (value_end_ == absl::string_view::npos) {
+    // This was the last frament within |*header_list_iterator_|,
+    // move on to the next header element of |header_list_|.
+    ++header_list_iterator_;
+    value_start_ = 0;
+  } else {
+    // Find the next fragment within |*header_list_iterator_|.
+    value_start_ = value_end_ + 1;
+  }
+  UpdateHeaderField();
+
+  return *this;
+}
+
+const ValueSplittingHeaderList::value_type&
+    ValueSplittingHeaderList::const_iterator::operator*() const {
+  return header_field_;
+}
+const ValueSplittingHeaderList::value_type*
+    ValueSplittingHeaderList::const_iterator::operator->() const {
+  return &header_field_;
+}
+
+void ValueSplittingHeaderList::const_iterator::UpdateHeaderField() {
+  QUICHE_DCHECK(value_start_ != absl::string_view::npos);
+
+  if (header_list_iterator_ == header_list_->end()) {
+    return;
+  }
+
+  const absl::string_view name = header_list_iterator_->first;
+  const absl::string_view original_value = header_list_iterator_->second;
+
+  if (name == kCookieKey) {
+    value_end_ = original_value.find(kCookieSeparator, value_start_);
+  } else {
+    value_end_ = original_value.find(kNonCookieSeparator, value_start_);
+  }
+
+  const absl::string_view value =
+      original_value.substr(value_start_, value_end_ - value_start_);
+  header_field_ = std::make_pair(name, value);
+
+  // Skip character after ';' separator if it is a space.
+  if (name == kCookieKey && value_end_ != absl::string_view::npos &&
+      value_end_ + 1 < original_value.size() &&
+      original_value[value_end_ + 1] == kOptionalSpaceAfterCookieSeparator) {
+    ++value_end_;
+  }
+}
+
+ValueSplittingHeaderList::ValueSplittingHeaderList(
+    const spdy::Http2HeaderBlock* header_list)
+    : header_list_(header_list) {
+  QUICHE_DCHECK(header_list_);
+}
+
+ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::begin()
+    const {
+  return const_iterator(header_list_, header_list_->begin());
+}
+
+ValueSplittingHeaderList::const_iterator ValueSplittingHeaderList::end() const {
+  return const_iterator(header_list_, header_list_->end());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/qpack/value_splitting_header_list.h b/quiche/quic/core/qpack/value_splitting_header_list.h
new file mode 100644
index 0000000..cc9939a
--- /dev/null
+++ b/quiche/quic/core/qpack/value_splitting_header_list.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
+#define QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+// A wrapper class around Http2HeaderBlock that splits header values along ';'
+// separators (while also removing optional space following separator) for
+// cookies and along '\0' separators for other header fields.
+class QUIC_EXPORT_PRIVATE ValueSplittingHeaderList {
+ public:
+  using value_type = spdy::Http2HeaderBlock::value_type;
+
+  class QUIC_EXPORT_PRIVATE const_iterator {
+   public:
+    // |header_list| must outlive this object.
+    const_iterator(const spdy::Http2HeaderBlock* header_list,
+                   spdy::Http2HeaderBlock::const_iterator header_list_iterator);
+    const_iterator(const const_iterator&) = default;
+    const_iterator& operator=(const const_iterator&) = delete;
+
+    bool operator==(const const_iterator& other) const;
+    bool operator!=(const const_iterator& other) const;
+
+    const const_iterator& operator++();
+
+    const value_type& operator*() const;
+    const value_type* operator->() const;
+
+   private:
+    // Find next separator; update |value_end_| and |header_field_|.
+    void UpdateHeaderField();
+
+    const spdy::Http2HeaderBlock* const header_list_;
+    spdy::Http2HeaderBlock::const_iterator header_list_iterator_;
+    absl::string_view::size_type value_start_;
+    absl::string_view::size_type value_end_;
+    value_type header_field_;
+  };
+
+  // |header_list| must outlive this object.
+  explicit ValueSplittingHeaderList(const spdy::Http2HeaderBlock* header_list);
+  ValueSplittingHeaderList(const ValueSplittingHeaderList&) = delete;
+  ValueSplittingHeaderList& operator=(const ValueSplittingHeaderList&) = delete;
+
+  const_iterator begin() const;
+  const_iterator end() const;
+
+ private:
+  const spdy::Http2HeaderBlock* const header_list_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_VALUE_SPLITTING_HEADER_LIST_H_
diff --git a/quiche/quic/core/qpack/value_splitting_header_list_test.cc b/quiche/quic/core/qpack/value_splitting_header_list_test.cc
new file mode 100644
index 0000000..a3aae0a
--- /dev/null
+++ b/quiche/quic/core/qpack/value_splitting_header_list_test.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/qpack/value_splitting_header_list.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
+TEST(ValueSplittingHeaderListTest, Comparison) {
+  spdy::Http2HeaderBlock block;
+  block["foo"] = absl::string_view("bar\0baz", 7);
+  block["baz"] = "qux";
+  block["cookie"] = "foo; bar";
+
+  ValueSplittingHeaderList headers(&block);
+  ValueSplittingHeaderList::const_iterator it1 = headers.begin();
+  const int kEnd = 6;
+  for (int i = 0; i < kEnd; ++i) {
+    // Compare to begin().
+    if (i == 0) {
+      EXPECT_TRUE(it1 == headers.begin());
+      EXPECT_TRUE(headers.begin() == it1);
+      EXPECT_FALSE(it1 != headers.begin());
+      EXPECT_FALSE(headers.begin() != it1);
+    } else {
+      EXPECT_FALSE(it1 == headers.begin());
+      EXPECT_FALSE(headers.begin() == it1);
+      EXPECT_TRUE(it1 != headers.begin());
+      EXPECT_TRUE(headers.begin() != it1);
+    }
+
+    // Compare to end().
+    if (i == kEnd - 1) {
+      EXPECT_TRUE(it1 == headers.end());
+      EXPECT_TRUE(headers.end() == it1);
+      EXPECT_FALSE(it1 != headers.end());
+      EXPECT_FALSE(headers.end() != it1);
+    } else {
+      EXPECT_FALSE(it1 == headers.end());
+      EXPECT_FALSE(headers.end() == it1);
+      EXPECT_TRUE(it1 != headers.end());
+      EXPECT_TRUE(headers.end() != it1);
+    }
+
+    // Compare to another iterator walking through the container.
+    ValueSplittingHeaderList::const_iterator it2 = headers.begin();
+    for (int j = 0; j < kEnd; ++j) {
+      if (i == j) {
+        EXPECT_TRUE(it1 == it2);
+        EXPECT_FALSE(it1 != it2);
+      } else {
+        EXPECT_FALSE(it1 == it2);
+        EXPECT_TRUE(it1 != it2);
+      }
+      if (j < kEnd - 1) {
+        ASSERT_NE(it2, headers.end());
+        ++it2;
+      }
+    }
+
+    if (i < kEnd - 1) {
+      ASSERT_NE(it1, headers.end());
+      ++it1;
+    }
+  }
+}
+
+TEST(ValueSplittingHeaderListTest, Empty) {
+  spdy::Http2HeaderBlock block;
+
+  ValueSplittingHeaderList headers(&block);
+  EXPECT_THAT(headers, ElementsAre());
+  EXPECT_EQ(headers.begin(), headers.end());
+}
+
+TEST(ValueSplittingHeaderListTest, Split) {
+  struct {
+    const char* name;
+    absl::string_view value;
+    std::vector<const char*> expected_values;
+  } kTestData[]{
+      // Empty value.
+      {"foo", "", {""}},
+      // Trivial case.
+      {"foo", "bar", {"bar"}},
+      // Simple split.
+      {"foo", {"bar\0baz", 7}, {"bar", "baz"}},
+      {"cookie", "foo;bar", {"foo", "bar"}},
+      {"cookie", "foo; bar", {"foo", "bar"}},
+      // Empty fragments with \0 separator.
+      {"foo", {"\0", 1}, {"", ""}},
+      {"bar", {"foo\0", 4}, {"foo", ""}},
+      {"baz", {"\0bar", 4}, {"", "bar"}},
+      {"qux", {"\0foobar\0", 8}, {"", "foobar", ""}},
+      // Empty fragments with ";" separator.
+      {"cookie", ";", {"", ""}},
+      {"cookie", "foo;", {"foo", ""}},
+      {"cookie", ";bar", {"", "bar"}},
+      {"cookie", ";foobar;", {"", "foobar", ""}},
+      // Empty fragments with "; " separator.
+      {"cookie", "; ", {"", ""}},
+      {"cookie", "foo; ", {"foo", ""}},
+      {"cookie", "; bar", {"", "bar"}},
+      {"cookie", "; foobar; ", {"", "foobar", ""}},
+  };
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
+    spdy::Http2HeaderBlock block;
+    block[kTestData[i].name] = kTestData[i].value;
+
+    ValueSplittingHeaderList headers(&block);
+    auto it = headers.begin();
+    for (const char* expected_value : kTestData[i].expected_values) {
+      ASSERT_NE(it, headers.end());
+      EXPECT_EQ(it->first, kTestData[i].name);
+      EXPECT_EQ(it->second, expected_value);
+      ++it;
+    }
+    EXPECT_EQ(it, headers.end());
+  }
+}
+
+TEST(ValueSplittingHeaderListTest, MultipleFields) {
+  spdy::Http2HeaderBlock block;
+  block["foo"] = absl::string_view("bar\0baz\0", 8);
+  block["cookie"] = "foo; bar";
+  block["bar"] = absl::string_view("qux\0foo", 7);
+
+  ValueSplittingHeaderList headers(&block);
+  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("foo", "baz"),
+                                   Pair("foo", ""), Pair("cookie", "foo"),
+                                   Pair("cookie", "bar"), Pair("bar", "qux"),
+                                   Pair("bar", "foo")));
+}
+
+TEST(ValueSplittingHeaderListTest, CookieStartsWithSpace) {
+  spdy::Http2HeaderBlock block;
+  block["foo"] = "bar";
+  block["cookie"] = " foo";
+  block["bar"] = "baz";
+
+  ValueSplittingHeaderList headers(&block);
+  EXPECT_THAT(headers, ElementsAre(Pair("foo", "bar"), Pair("cookie", " foo"),
+                                   Pair("bar", "baz")));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_ack_listener_interface.cc b/quiche/quic/core/quic_ack_listener_interface.cc
new file mode 100644
index 0000000..f3c9d14
--- /dev/null
+++ b/quiche/quic/core/quic_ack_listener_interface.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_ack_listener_interface.h"
+
+namespace quic {
+
+QuicAckListenerInterface::~QuicAckListenerInterface() {}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_ack_listener_interface.h b/quiche/quic/core/quic_ack_listener_interface.h
new file mode 100644
index 0000000..edf4fd3
--- /dev/null
+++ b/quiche/quic/core/quic_ack_listener_interface.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
+#define QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+
+namespace quic {
+
+// Pure virtual class to listen for packet acknowledgements.
+class QUIC_EXPORT_PRIVATE QuicAckListenerInterface
+    : public quiche::QuicheReferenceCounted {
+ public:
+  QuicAckListenerInterface() {}
+
+  // Called when a packet is acked.  Called once per packet.
+  // |acked_bytes| is the number of data bytes acked.
+  virtual void OnPacketAcked(int acked_bytes,
+                             QuicTime::Delta ack_delay_time) = 0;
+
+  // Called when a packet is retransmitted.  Called once per packet.
+  // |retransmitted_bytes| is the number of data bytes retransmitted.
+  virtual void OnPacketRetransmitted(int retransmitted_bytes) = 0;
+
+ protected:
+  // Delegates are ref counted.
+  ~QuicAckListenerInterface() override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ACK_LISTENER_INTERFACE_H_
diff --git a/quiche/quic/core/quic_alarm.cc b/quiche/quic/core/quic_alarm.cc
new file mode 100644
index 0000000..f53b987
--- /dev/null
+++ b/quiche/quic/core/quic_alarm.cc
@@ -0,0 +1,107 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_alarm.h"
+
+#include <atomic>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+QuicAlarm::QuicAlarm(QuicArenaScopedPtr<Delegate> delegate)
+    : delegate_(std::move(delegate)), deadline_(QuicTime::Zero()) {}
+
+QuicAlarm::~QuicAlarm() {
+  if (IsSet()) {
+    QUIC_CODE_COUNT(quic_alarm_not_cancelled_in_dtor);
+  }
+}
+
+void QuicAlarm::Set(QuicTime new_deadline) {
+  QUICHE_DCHECK(!IsSet());
+  QUICHE_DCHECK(new_deadline.IsInitialized());
+
+  if (IsPermanentlyCancelled()) {
+    QUIC_BUG(quic_alarm_illegal_set)
+        << "Set called after alarm is permanently cancelled. new_deadline:"
+        << new_deadline;
+    return;
+  }
+
+  deadline_ = new_deadline;
+  SetImpl();
+}
+
+void QuicAlarm::CancelInternal(bool permanent) {
+  if (IsSet()) {
+    deadline_ = QuicTime::Zero();
+    CancelImpl();
+  }
+
+  if (permanent) {
+    delegate_.reset();
+  }
+}
+
+bool QuicAlarm::IsPermanentlyCancelled() const { return delegate_ == nullptr; }
+
+void QuicAlarm::Update(QuicTime new_deadline, QuicTime::Delta granularity) {
+  if (IsPermanentlyCancelled()) {
+    QUIC_BUG(quic_alarm_illegal_update)
+        << "Update called after alarm is permanently cancelled. new_deadline:"
+        << new_deadline << ", granularity:" << granularity;
+    return;
+  }
+
+  if (!new_deadline.IsInitialized()) {
+    Cancel();
+    return;
+  }
+  if (std::abs((new_deadline - deadline_).ToMicroseconds()) <
+      granularity.ToMicroseconds()) {
+    return;
+  }
+  const bool was_set = IsSet();
+  deadline_ = new_deadline;
+  if (was_set) {
+    UpdateImpl();
+  } else {
+    SetImpl();
+  }
+}
+
+bool QuicAlarm::IsSet() const {
+  return deadline_.IsInitialized();
+}
+
+void QuicAlarm::Fire() {
+  if (!IsSet()) {
+    return;
+  }
+
+  deadline_ = QuicTime::Zero();
+  if (!IsPermanentlyCancelled()) {
+    QuicConnectionContextSwitcher context_switcher(
+        delegate_->GetConnectionContext());
+    delegate_->OnAlarm();
+  }
+}
+
+void QuicAlarm::UpdateImpl() {
+  // CancelImpl and SetImpl take the new deadline by way of the deadline_
+  // member, so save and restore deadline_ before canceling.
+  const QuicTime new_deadline = deadline_;
+
+  deadline_ = QuicTime::Zero();
+  CancelImpl();
+
+  deadline_ = new_deadline;
+  SetImpl();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_alarm.h b/quiche/quic/core/quic_alarm.h
new file mode 100644
index 0000000..4352a44
--- /dev/null
+++ b/quiche/quic/core/quic_alarm.h
@@ -0,0 +1,125 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ALARM_H_
+#define QUICHE_QUIC_CORE_QUIC_ALARM_H_
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Abstract class which represents an alarm which will go off at a
+// scheduled time, and execute the |OnAlarm| method of the delegate.
+// An alarm may be cancelled, in which case it may or may not be
+// removed from the underlying scheduling system, but in either case
+// the task will not be executed.
+class QUIC_EXPORT_PRIVATE QuicAlarm {
+ public:
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // If the alarm belongs to a single QuicConnection, return the corresponding
+    // QuicConnection.context_. Note the context_ is the first member of
+    // QuicConnection, so it should outlive the delegate.
+    // Otherwise return nullptr.
+    // The OnAlarm function will be called under the connection context, if any.
+    virtual QuicConnectionContext* GetConnectionContext() = 0;
+
+    // Invoked when the alarm fires.
+    virtual void OnAlarm() = 0;
+  };
+
+  // DelegateWithContext is a Delegate with a QuicConnectionContext* stored as a
+  // member variable.
+  class QUIC_EXPORT_PRIVATE DelegateWithContext : public Delegate {
+   public:
+    explicit DelegateWithContext(QuicConnectionContext* context)
+        : context_(context) {}
+    ~DelegateWithContext() override {}
+    QuicConnectionContext* GetConnectionContext() override { return context_; }
+
+   private:
+    QuicConnectionContext* context_;
+  };
+
+  // DelegateWithoutContext is a Delegate that does not have a corresponding
+  // context. Typically this means one object of the child class deals with many
+  // connections.
+  class QUIC_EXPORT_PRIVATE DelegateWithoutContext : public Delegate {
+   public:
+    ~DelegateWithoutContext() override {}
+    QuicConnectionContext* GetConnectionContext() override { return nullptr; }
+  };
+
+  explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate);
+  QuicAlarm(const QuicAlarm&) = delete;
+  QuicAlarm& operator=(const QuicAlarm&) = delete;
+  virtual ~QuicAlarm();
+
+  // Sets the alarm to fire at |deadline|.  Must not be called while
+  // the alarm is set.  To reschedule an alarm, call Cancel() first,
+  // then Set().
+  void Set(QuicTime new_deadline);
+
+  // Both PermanentCancel() and Cancel() can cancel the alarm. If permanent,
+  // future calls to Set() and Update() will become no-op except emitting an
+  // error log.
+  //
+  // Both may be called repeatedly.  Does not guarantee that the underlying
+  // scheduling system will remove the alarm's associated task, but guarantees
+  // that the delegates OnAlarm method will not be called.
+  void PermanentCancel() { CancelInternal(true); }
+  void Cancel() { CancelInternal(false); }
+
+  // Return true if PermanentCancel() has been called.
+  bool IsPermanentlyCancelled() const;
+
+  // Cancels and sets the alarm if the |deadline| is farther from the current
+  // deadline than |granularity|, and otherwise does nothing.  If |deadline| is
+  // not initialized, the alarm is cancelled.
+  void Update(QuicTime new_deadline, QuicTime::Delta granularity);
+
+  // Returns true if |deadline_| has been set to a non-zero time.
+  bool IsSet() const;
+
+  QuicTime deadline() const { return deadline_; }
+
+ protected:
+  // Subclasses implement this method to perform the platform-specific
+  // scheduling of the alarm.  Is called from Set() or Fire(), after the
+  // deadline has been updated.
+  virtual void SetImpl() = 0;
+
+  // Subclasses implement this method to perform the platform-specific
+  // cancelation of the alarm.
+  virtual void CancelImpl() = 0;
+
+  // Subclasses implement this method to perform the platform-specific update of
+  // the alarm if there exists a more optimal implementation than calling
+  // CancelImpl() and SetImpl().
+  virtual void UpdateImpl();
+
+  // Called by subclasses when the alarm fires.  Invokes the
+  // delegates |OnAlarm| if a delegate is set, and if the deadline
+  // has been exceeded.  Implementations which do not remove the
+  // alarm from the underlying scheduler on Cancel() may need to handle
+  // the situation where the task executes before the deadline has been
+  // reached, in which case they need to reschedule the task and must not
+  // call invoke this method.
+  void Fire();
+
+ private:
+  void CancelInternal(bool permanent);
+
+  QuicArenaScopedPtr<Delegate> delegate_;
+  QuicTime deadline_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ALARM_H_
diff --git a/quiche/quic/core/quic_alarm_factory.h b/quiche/quic/core/quic_alarm_factory.h
new file mode 100644
index 0000000..b1ce54c
--- /dev/null
+++ b/quiche/quic/core/quic_alarm_factory.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
+#define QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Creates platform-specific alarms used throughout QUIC.
+class QUIC_EXPORT_PRIVATE QuicAlarmFactory {
+ public:
+  virtual ~QuicAlarmFactory() {}
+
+  // Creates a new platform-specific alarm which will be configured to notify
+  // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
+  // Caller takes ownership of the new alarm, which will not yet be "set" to
+  // fire.
+  virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
+
+  // Creates a new platform-specific alarm which will be configured to notify
+  // |delegate| when the alarm fires. Caller takes ownership of the new alarm,
+  // which will not yet be "set" to fire. If |arena| is null, then the alarm
+  // will be created on the heap. Otherwise, it will be created in |arena|.
+  virtual QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ALARM_FACTORY_H_
diff --git a/quiche/quic/core/quic_alarm_test.cc b/quiche/quic/core/quic_alarm_test.cc
new file mode 100644
index 0000000..d9980eb
--- /dev/null
+++ b/quiche/quic/core/quic_alarm_test.cc
@@ -0,0 +1,261 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_alarm.h"
+
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using testing::ElementsAre;
+using testing::Invoke;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TraceCollector : public QuicConnectionTracer {
+ public:
+  ~TraceCollector() override = default;
+
+  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
+
+  void PrintString(absl::string_view s) override {
+    trace_.push_back(std::string(s));
+  }
+
+  const std::vector<std::string>& trace() const { return trace_; }
+
+ private:
+  std::vector<std::string> trace_;
+};
+
+class MockDelegate : public QuicAlarm::Delegate {
+ public:
+  MOCK_METHOD(QuicConnectionContext*, GetConnectionContext, (), (override));
+  MOCK_METHOD(void, OnAlarm, (), (override));
+};
+
+class DestructiveDelegate : public QuicAlarm::DelegateWithoutContext {
+ public:
+  DestructiveDelegate() : alarm_(nullptr) {}
+
+  void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; }
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(alarm_);
+    delete alarm_;
+  }
+
+ private:
+  QuicAlarm* alarm_;
+};
+
+class TestAlarm : public QuicAlarm {
+ public:
+  explicit TestAlarm(QuicAlarm::Delegate* delegate)
+      : QuicAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)) {}
+
+  bool scheduled() const { return scheduled_; }
+
+  void FireAlarm() {
+    scheduled_ = false;
+    Fire();
+  }
+
+ protected:
+  void SetImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    scheduled_ = true;
+  }
+
+  void CancelImpl() override {
+    QUICHE_DCHECK(!deadline().IsInitialized());
+    scheduled_ = false;
+  }
+
+ private:
+  bool scheduled_;
+};
+
+class DestructiveAlarm : public QuicAlarm {
+ public:
+  explicit DestructiveAlarm(DestructiveDelegate* delegate)
+      : QuicAlarm(QuicArenaScopedPtr<DestructiveDelegate>(delegate)) {}
+
+  void FireAlarm() { Fire(); }
+
+ protected:
+  void SetImpl() override {}
+
+  void CancelImpl() override {}
+};
+
+class QuicAlarmTest : public QuicTest {
+ public:
+  QuicAlarmTest()
+      : delegate_(new MockDelegate()),
+        alarm_(delegate_),
+        deadline_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(7)),
+        deadline2_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(14)),
+        new_deadline_(QuicTime::Zero()) {}
+
+  void ResetAlarm() { alarm_.Set(new_deadline_); }
+
+  MockDelegate* delegate_;  // not owned
+  TestAlarm alarm_;
+  QuicTime deadline_;
+  QuicTime deadline2_;
+  QuicTime new_deadline_;
+};
+
+TEST_F(QuicAlarmTest, IsSet) {
+  EXPECT_FALSE(alarm_.IsSet());
+}
+
+TEST_F(QuicAlarmTest, Set) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  EXPECT_TRUE(alarm_.IsSet());
+  EXPECT_TRUE(alarm_.scheduled());
+  EXPECT_EQ(deadline, alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, Cancel) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  alarm_.Cancel();
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, PermanentCancel) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  alarm_.PermanentCancel();
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+
+  EXPECT_QUIC_BUG(alarm_.Set(deadline),
+                  "Set called after alarm is permanently cancelled");
+  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+
+  EXPECT_QUIC_BUG(alarm_.Update(deadline, QuicTime::Delta::Zero()),
+                  "Update called after alarm is permanently cancelled");
+  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, Update) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  QuicTime new_deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(8);
+  alarm_.Update(new_deadline, QuicTime::Delta::Zero());
+  EXPECT_TRUE(alarm_.IsSet());
+  EXPECT_TRUE(alarm_.scheduled());
+  EXPECT_EQ(new_deadline, alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, UpdateWithZero) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  alarm_.Update(QuicTime::Zero(), QuicTime::Delta::Zero());
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, Fire) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+  EXPECT_CALL(*delegate_, OnAlarm());
+  alarm_.FireAlarm();
+  EXPECT_FALSE(alarm_.IsSet());
+  EXPECT_FALSE(alarm_.scheduled());
+  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, FireAndResetViaSet) {
+  alarm_.Set(deadline_);
+  new_deadline_ = deadline2_;
+  EXPECT_CALL(*delegate_, OnAlarm())
+      .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm));
+  alarm_.FireAlarm();
+  EXPECT_TRUE(alarm_.IsSet());
+  EXPECT_TRUE(alarm_.scheduled());
+  EXPECT_EQ(deadline2_, alarm_.deadline());
+}
+
+TEST_F(QuicAlarmTest, FireDestroysAlarm) {
+  DestructiveDelegate* delegate(new DestructiveDelegate);
+  DestructiveAlarm* alarm = new DestructiveAlarm(delegate);
+  delegate->set_alarm(alarm);
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm->Set(deadline);
+  // This should not crash, even though it will destroy alarm.
+  alarm->FireAlarm();
+}
+
+TEST_F(QuicAlarmTest, NullAlarmContext) {
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+
+  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(nullptr));
+
+  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
+    QUIC_TRACELITERAL("Alarm fired.");
+  }));
+  alarm_.FireAlarm();
+}
+
+TEST_F(QuicAlarmTest, AlarmContextWithNullTracer) {
+  QuicConnectionContext context;
+  ASSERT_EQ(context.tracer, nullptr);
+
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+
+  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
+
+  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
+    QUIC_TRACELITERAL("Alarm fired.");
+  }));
+  alarm_.FireAlarm();
+}
+
+TEST_F(QuicAlarmTest, AlarmContextWithTracer) {
+  QuicConnectionContext context;
+  std::unique_ptr<TraceCollector> tracer = std::make_unique<TraceCollector>();
+  const TraceCollector& tracer_ref = *tracer;
+  context.tracer = std::move(tracer);
+
+  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
+  alarm_.Set(deadline);
+
+  EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
+
+  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
+    QUIC_TRACELITERAL("Alarm fired.");
+  }));
+
+  // Since |context| is not installed in the current thread, the messages before
+  // and after FireAlarm() should not be collected by |tracer|.
+  QUIC_TRACELITERAL("Should not be collected before alarm.");
+  alarm_.FireAlarm();
+  QUIC_TRACELITERAL("Should not be collected after alarm.");
+
+  EXPECT_THAT(tracer_ref.trace(), ElementsAre("Alarm fired."));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_arena_scoped_ptr.h b/quiche/quic/core/quic_arena_scoped_ptr.h
new file mode 100644
index 0000000..a0c4ed8
--- /dev/null
+++ b/quiche/quic/core/quic_arena_scoped_ptr.h
@@ -0,0 +1,208 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// unique_ptr-style pointer that stores values that may be from an arena. Takes
+// up the same storage as the platform's native pointer type. Takes ownership
+// of the value it's constructed with; if holding a value in an arena, and the
+// type has a non-trivial destructor, the arena must outlive the
+// QuicArenaScopedPtr. Does not support array overloads.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
+#define QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
+
+#include <cstdint>  // for uintptr_t
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_NO_EXPORT QuicArenaScopedPtr {
+  static_assert(alignof(T*) > 1,
+                "QuicArenaScopedPtr can only store objects that are aligned to "
+                "greater than 1 byte.");
+
+ public:
+  // Constructs an empty QuicArenaScopedPtr.
+  QuicArenaScopedPtr();
+
+  // Constructs a QuicArenaScopedPtr referencing the heap-allocated memory
+  // provided.
+  explicit QuicArenaScopedPtr(T* value);
+
+  template <typename U>
+  QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other);  // NOLINT
+  template <typename U>
+  QuicArenaScopedPtr& operator=(QuicArenaScopedPtr<U>&& other);
+  ~QuicArenaScopedPtr();
+
+  // Returns a pointer to the value.
+  T* get() const;
+
+  // Returns a reference to the value.
+  T& operator*() const;
+
+  // Returns a pointer to the value.
+  T* operator->() const;
+
+  // Swaps the value of this pointer with |other|.
+  void swap(QuicArenaScopedPtr& other);
+
+  // Resets the held value to |value|.
+  void reset(T* value = nullptr);
+
+  // Returns true if |this| came from an arena. Primarily exposed for testing
+  // and assertions.
+  bool is_from_arena();
+
+ private:
+  // Friends with other derived types of QuicArenaScopedPtr, to support the
+  // derived-types case.
+  template <typename U>
+  friend class QuicArenaScopedPtr;
+  // Also befriend all known arenas, only to prevent misuse.
+  template <uint32_t ArenaSize>
+  friend class QuicOneBlockArena;
+
+  // Tag to denote that a QuicArenaScopedPtr is being explicitly created by an
+  // arena.
+  enum class ConstructFrom { kHeap, kArena };
+
+  // Constructs a QuicArenaScopedPtr with the given representation.
+  QuicArenaScopedPtr(void* value, ConstructFrom from);
+  QuicArenaScopedPtr(const QuicArenaScopedPtr&) = delete;
+  QuicArenaScopedPtr& operator=(const QuicArenaScopedPtr&) = delete;
+
+  // Low-order bits of value_ that determine if the pointer came from an arena.
+  static const uintptr_t kFromArenaMask = 0x1;
+
+  // Every platform we care about has at least 4B aligned integers, so store the
+  // is_from_arena bit in the least significant bit.
+  void* value_;
+};
+
+template <typename T>
+bool operator==(const QuicArenaScopedPtr<T>& left,
+                const QuicArenaScopedPtr<T>& right) {
+  return left.get() == right.get();
+}
+
+template <typename T>
+bool operator!=(const QuicArenaScopedPtr<T>& left,
+                const QuicArenaScopedPtr<T>& right) {
+  return left.get() != right.get();
+}
+
+template <typename T>
+bool operator==(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
+  return nullptr == right.get();
+}
+
+template <typename T>
+bool operator!=(std::nullptr_t, const QuicArenaScopedPtr<T>& right) {
+  return nullptr != right.get();
+}
+
+template <typename T>
+bool operator==(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
+  return left.get() == nullptr;
+}
+
+template <typename T>
+bool operator!=(const QuicArenaScopedPtr<T>& left, std::nullptr_t) {
+  return left.get() != nullptr;
+}
+
+template <typename T>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr() : value_(nullptr) {}
+
+template <typename T>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr(T* value)
+    : QuicArenaScopedPtr(value, ConstructFrom::kHeap) {}
+
+template <typename T>
+template <typename U>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr(QuicArenaScopedPtr<U>&& other)
+    : value_(other.value_) {
+  static_assert(
+      std::is_base_of<T, U>::value || std::is_same<T, U>::value,
+      "Cannot construct QuicArenaScopedPtr; type is not derived or same.");
+  other.value_ = nullptr;
+}
+
+template <typename T>
+template <typename U>
+QuicArenaScopedPtr<T>& QuicArenaScopedPtr<T>::operator=(
+    QuicArenaScopedPtr<U>&& other) {
+  static_assert(
+      std::is_base_of<T, U>::value || std::is_same<T, U>::value,
+      "Cannot assign QuicArenaScopedPtr; type is not derived or same.");
+  swap(other);
+  return *this;
+}
+
+template <typename T>
+QuicArenaScopedPtr<T>::~QuicArenaScopedPtr() {
+  reset();
+}
+
+template <typename T>
+T* QuicArenaScopedPtr<T>::get() const {
+  return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(value_) &
+                              ~kFromArenaMask);
+}
+
+template <typename T>
+T& QuicArenaScopedPtr<T>::operator*() const {
+  return *get();
+}
+
+template <typename T>
+T* QuicArenaScopedPtr<T>::operator->() const {
+  return get();
+}
+
+template <typename T>
+void QuicArenaScopedPtr<T>::swap(QuicArenaScopedPtr& other) {
+  using std::swap;
+  swap(value_, other.value_);
+}
+
+template <typename T>
+bool QuicArenaScopedPtr<T>::is_from_arena() {
+  return (reinterpret_cast<uintptr_t>(value_) & kFromArenaMask) != 0;
+}
+
+template <typename T>
+void QuicArenaScopedPtr<T>::reset(T* value) {
+  if (value_ != nullptr) {
+    if (is_from_arena()) {
+      // Manually invoke the destructor.
+      get()->~T();
+    } else {
+      delete get();
+    }
+  }
+  QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value) & kFromArenaMask);
+  value_ = value;
+}
+
+template <typename T>
+QuicArenaScopedPtr<T>::QuicArenaScopedPtr(void* value, ConstructFrom from_arena)
+    : value_(value) {
+  QUICHE_DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(value_) & kFromArenaMask);
+  switch (from_arena) {
+    case ConstructFrom::kHeap:
+      break;
+    case ConstructFrom::kArena:
+      value_ = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(value_) |
+                                       QuicArenaScopedPtr<T>::kFromArenaMask);
+      break;
+  }
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ARENA_SCOPED_PTR_H_
diff --git a/quiche/quic/core/quic_arena_scoped_ptr_test.cc b/quiche/quic/core/quic_arena_scoped_ptr_test.cc
new file mode 100644
index 0000000..18d4fdf
--- /dev/null
+++ b/quiche/quic/core/quic_arena_scoped_ptr_test.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+enum class TestParam { kFromHeap, kFromArena };
+
+struct TestObject {
+  explicit TestObject(uintptr_t value) : value(value) { buffer.resize(1024); }
+  uintptr_t value;
+
+  // Ensure that we have a non-trivial destructor that will leak memory if it's
+  // not called.
+  std::vector<char> buffer;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParam& p) {
+  switch (p) {
+    case TestParam::kFromHeap:
+      return "heap";
+    case TestParam::kFromArena:
+      return "arena";
+  }
+  QUICHE_DCHECK(false);
+  return "?";
+}
+
+class QuicArenaScopedPtrParamTest : public QuicTestWithParam<TestParam> {
+ protected:
+  QuicArenaScopedPtr<TestObject> CreateObject(uintptr_t value) {
+    QuicArenaScopedPtr<TestObject> ptr;
+    switch (GetParam()) {
+      case TestParam::kFromHeap:
+        ptr = QuicArenaScopedPtr<TestObject>(new TestObject(value));
+        QUICHE_CHECK(!ptr.is_from_arena());
+        break;
+      case TestParam::kFromArena:
+        ptr = arena_.New<TestObject>(value);
+        QUICHE_CHECK(ptr.is_from_arena());
+        break;
+    }
+    return ptr;
+  }
+
+ private:
+  QuicOneBlockArena<1024> arena_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicArenaScopedPtrParamTest,
+                         QuicArenaScopedPtrParamTest,
+                         testing::Values(TestParam::kFromHeap,
+                                         TestParam::kFromArena),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicArenaScopedPtrParamTest, NullObjects) {
+  QuicArenaScopedPtr<TestObject> def;
+  QuicArenaScopedPtr<TestObject> null(nullptr);
+  EXPECT_EQ(def, null);
+  EXPECT_EQ(def, nullptr);
+  EXPECT_EQ(null, nullptr);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, FromArena) {
+  QuicOneBlockArena<1024> arena_;
+  EXPECT_TRUE(arena_.New<TestObject>(0).is_from_arena());
+  EXPECT_FALSE(
+      QuicArenaScopedPtr<TestObject>(new TestObject(0)).is_from_arena());
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Assign) {
+  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
+  ptr = CreateObject(54321);
+  EXPECT_EQ(54321u, ptr->value);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, MoveConstruct) {
+  QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
+  QuicArenaScopedPtr<TestObject> ptr2(std::move(ptr1));
+  EXPECT_EQ(nullptr, ptr1);
+  EXPECT_EQ(12345u, ptr2->value);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Accessors) {
+  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
+  EXPECT_EQ(12345u, (*ptr).value);
+  EXPECT_EQ(12345u, ptr->value);
+  // We explicitly want to test that get() returns a valid pointer to the data,
+  // but the call looks redundant.
+  EXPECT_EQ(12345u, ptr.get()->value);  // NOLINT
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Reset) {
+  QuicArenaScopedPtr<TestObject> ptr = CreateObject(12345);
+  ptr.reset(new TestObject(54321));
+  EXPECT_EQ(54321u, ptr->value);
+}
+
+TEST_P(QuicArenaScopedPtrParamTest, Swap) {
+  QuicArenaScopedPtr<TestObject> ptr1 = CreateObject(12345);
+  QuicArenaScopedPtr<TestObject> ptr2 = CreateObject(54321);
+  ptr1.swap(ptr2);
+  EXPECT_EQ(12345u, ptr2->value);
+  EXPECT_EQ(54321u, ptr1->value);
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_bandwidth.cc b/quiche/quic/core/quic_bandwidth.cc
new file mode 100644
index 0000000..4b25432
--- /dev/null
+++ b/quiche/quic/core/quic_bandwidth.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_bandwidth.h"
+
+#include <cinttypes>
+#include <string>
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+
+namespace quic {
+
+std::string QuicBandwidth::ToDebuggingValue() const {
+  if (bits_per_second_ < 80000) {
+    return absl::StrFormat("%d bits/s (%d bytes/s)", bits_per_second_,
+                           bits_per_second_ / 8);
+  }
+
+  double divisor;
+  char unit;
+  if (bits_per_second_ < 8 * 1000 * 1000) {
+    divisor = 1e3;
+    unit = 'k';
+  } else if (bits_per_second_ < INT64_C(8) * 1000 * 1000 * 1000) {
+    divisor = 1e6;
+    unit = 'M';
+  } else {
+    divisor = 1e9;
+    unit = 'G';
+  }
+
+  double bits_per_second_with_unit = bits_per_second_ / divisor;
+  double bytes_per_second_with_unit = bits_per_second_with_unit / 8;
+  return absl::StrFormat("%.2f %cbits/s (%.2f %cbytes/s)",
+                         bits_per_second_with_unit, unit,
+                         bytes_per_second_with_unit, unit);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_bandwidth.h b/quiche/quic/core/quic_bandwidth.h
new file mode 100644
index 0000000..26956b2
--- /dev/null
+++ b/quiche/quic/core/quic_bandwidth.h
@@ -0,0 +1,164 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// QuicBandwidth represents a bandwidth, stored in bits per second resolution.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
+#define QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicBandwidth {
+ public:
+  // Creates a new QuicBandwidth with an internal value of 0.
+  static constexpr QuicBandwidth Zero() { return QuicBandwidth(0); }
+
+  // Creates a new QuicBandwidth with an internal value of INT64_MAX.
+  static constexpr QuicBandwidth Infinite() {
+    return QuicBandwidth(std::numeric_limits<int64_t>::max());
+  }
+
+  // Create a new QuicBandwidth holding the bits per second.
+  static constexpr QuicBandwidth FromBitsPerSecond(int64_t bits_per_second) {
+    return QuicBandwidth(bits_per_second);
+  }
+
+  // Create a new QuicBandwidth holding the kilo bits per second.
+  static constexpr QuicBandwidth FromKBitsPerSecond(int64_t k_bits_per_second) {
+    return QuicBandwidth(k_bits_per_second * 1000);
+  }
+
+  // Create a new QuicBandwidth holding the bytes per second.
+  static constexpr QuicBandwidth FromBytesPerSecond(int64_t bytes_per_second) {
+    return QuicBandwidth(bytes_per_second * 8);
+  }
+
+  // Create a new QuicBandwidth holding the kilo bytes per second.
+  static constexpr QuicBandwidth FromKBytesPerSecond(
+      int64_t k_bytes_per_second) {
+    return QuicBandwidth(k_bytes_per_second * 8000);
+  }
+
+  // Create a new QuicBandwidth based on the bytes per the elapsed delta.
+  static QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes,
+                                             QuicTime::Delta delta) {
+    if (bytes == 0) {
+      return QuicBandwidth(0);
+    }
+
+    // 1 bit is 1000000 micro bits.
+    int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond;
+    if (num_micro_bits < delta.ToMicroseconds()) {
+      return QuicBandwidth(1);
+    }
+
+    return QuicBandwidth(num_micro_bits / delta.ToMicroseconds());
+  }
+
+  int64_t ToBitsPerSecond() const { return bits_per_second_; }
+
+  int64_t ToKBitsPerSecond() const { return bits_per_second_ / 1000; }
+
+  int64_t ToBytesPerSecond() const { return bits_per_second_ / 8; }
+
+  int64_t ToKBytesPerSecond() const { return bits_per_second_ / 8000; }
+
+  QuicByteCount ToBytesPerPeriod(QuicTime::Delta time_period) const {
+    return bits_per_second_ * time_period.ToMicroseconds() / 8 /
+           kNumMicrosPerSecond;
+  }
+
+  int64_t ToKBytesPerPeriod(QuicTime::Delta time_period) const {
+    return bits_per_second_ * time_period.ToMicroseconds() / 8000 /
+           kNumMicrosPerSecond;
+  }
+
+  bool IsZero() const { return bits_per_second_ == 0; }
+  bool IsInfinite() const {
+    return bits_per_second_ == Infinite().ToBitsPerSecond();
+  }
+
+  QuicTime::Delta TransferTime(QuicByteCount bytes) const {
+    if (bits_per_second_ == 0) {
+      return QuicTime::Delta::Zero();
+    }
+    return QuicTime::Delta::FromMicroseconds(bytes * 8 * kNumMicrosPerSecond /
+                                             bits_per_second_);
+  }
+
+  std::string ToDebuggingValue() const;
+
+ private:
+  explicit constexpr QuicBandwidth(int64_t bits_per_second)
+      : bits_per_second_(bits_per_second >= 0 ? bits_per_second : 0) {}
+
+  int64_t bits_per_second_;
+
+  friend QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs);
+  friend QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs);
+  friend QuicBandwidth operator*(QuicBandwidth lhs, float factor);
+};
+
+// Non-member relational operators for QuicBandwidth.
+inline bool operator==(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return lhs.ToBitsPerSecond() == rhs.ToBitsPerSecond();
+}
+inline bool operator!=(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return lhs.ToBitsPerSecond() < rhs.ToBitsPerSecond();
+}
+inline bool operator>(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return !(lhs < rhs);
+}
+
+// Non-member arithmetic operators for QuicBandwidth.
+inline QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return QuicBandwidth(lhs.bits_per_second_ + rhs.bits_per_second_);
+}
+inline QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs) {
+  return QuicBandwidth(lhs.bits_per_second_ - rhs.bits_per_second_);
+}
+inline QuicBandwidth operator*(QuicBandwidth lhs, float rhs) {
+  return QuicBandwidth(
+      static_cast<int64_t>(std::llround(lhs.bits_per_second_ * rhs)));
+}
+inline QuicBandwidth operator*(float lhs, QuicBandwidth rhs) {
+  return rhs * lhs;
+}
+inline QuicByteCount operator*(QuicBandwidth lhs, QuicTime::Delta rhs) {
+  return lhs.ToBytesPerPeriod(rhs);
+}
+inline QuicByteCount operator*(QuicTime::Delta lhs, QuicBandwidth rhs) {
+  return rhs * lhs;
+}
+
+// Override stream output operator for gtest.
+inline std::ostream& operator<<(std::ostream& output,
+                                const QuicBandwidth bandwidth) {
+  output << bandwidth.ToDebuggingValue();
+  return output;
+}
+
+}  // namespace quic
+#endif  // QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_
diff --git a/quiche/quic/core/quic_bandwidth_test.cc b/quiche/quic/core/quic_bandwidth_test.cc
new file mode 100644
index 0000000..5f32f11
--- /dev/null
+++ b/quiche/quic/core/quic_bandwidth_test.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_bandwidth.h"
+
+#include <limits>
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicBandwidthTest : public QuicTest {};
+
+TEST_F(QuicBandwidthTest, FromTo) {
+  EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(1),
+            QuicBandwidth::FromBitsPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1),
+            QuicBandwidth::FromBytesPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(8000),
+            QuicBandwidth::FromBytesPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromKBitsPerSecond(8),
+            QuicBandwidth::FromKBytesPerSecond(1));
+
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToKBitsPerSecond());
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToBytesPerSecond());
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToKBytesPerSecond());
+
+  EXPECT_EQ(1, QuicBandwidth::FromBitsPerSecond(1000).ToKBitsPerSecond());
+  EXPECT_EQ(1000, QuicBandwidth::FromKBitsPerSecond(1).ToBitsPerSecond());
+  EXPECT_EQ(1, QuicBandwidth::FromBytesPerSecond(1000).ToKBytesPerSecond());
+  EXPECT_EQ(1000, QuicBandwidth::FromKBytesPerSecond(1).ToBytesPerSecond());
+}
+
+TEST_F(QuicBandwidthTest, Add) {
+  QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
+  QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
+
+  EXPECT_EQ(9000, (bandwidht_1 + bandwidht_2).ToBitsPerSecond());
+  EXPECT_EQ(9000, (bandwidht_2 + bandwidht_1).ToBitsPerSecond());
+}
+
+TEST_F(QuicBandwidthTest, Subtract) {
+  QuicBandwidth bandwidht_1 = QuicBandwidth::FromKBitsPerSecond(1);
+  QuicBandwidth bandwidht_2 = QuicBandwidth::FromKBytesPerSecond(1);
+
+  EXPECT_EQ(7000, (bandwidht_2 - bandwidht_1).ToBitsPerSecond());
+}
+
+TEST_F(QuicBandwidthTest, TimeDelta) {
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1000),
+            QuicBandwidth::FromBytesAndTimeDelta(
+                1000, QuicTime::Delta::FromMilliseconds(1)));
+
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(10),
+            QuicBandwidth::FromBytesAndTimeDelta(
+                1000, QuicTime::Delta::FromMilliseconds(100)));
+
+  EXPECT_EQ(QuicBandwidth::Zero(), QuicBandwidth::FromBytesAndTimeDelta(
+                                       0, QuicTime::Delta::FromSeconds(9)));
+
+  EXPECT_EQ(
+      QuicBandwidth::FromBitsPerSecond(1),
+      QuicBandwidth::FromBytesAndTimeDelta(1, QuicTime::Delta::FromSeconds(9)));
+}
+
+TEST_F(QuicBandwidthTest, Scale) {
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(500),
+            QuicBandwidth::FromKBytesPerSecond(1000) * 0.5f);
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(750),
+            0.75f * QuicBandwidth::FromKBytesPerSecond(1000));
+  EXPECT_EQ(QuicBandwidth::FromKBytesPerSecond(1250),
+            QuicBandwidth::FromKBytesPerSecond(1000) * 1.25f);
+
+  // Ensure we are rounding correctly within a 1bps level of precision.
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(5),
+            QuicBandwidth::FromBitsPerSecond(9) * 0.5f);
+  EXPECT_EQ(QuicBandwidth::FromBitsPerSecond(2),
+            QuicBandwidth::FromBitsPerSecond(12) * 0.2f);
+}
+
+TEST_F(QuicBandwidthTest, BytesPerPeriod) {
+  EXPECT_EQ(2000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
+                       QuicTime::Delta::FromMilliseconds(1)));
+  EXPECT_EQ(2u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
+                    QuicTime::Delta::FromMilliseconds(1)));
+  EXPECT_EQ(200000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
+                         QuicTime::Delta::FromMilliseconds(100)));
+  EXPECT_EQ(200u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
+                      QuicTime::Delta::FromMilliseconds(100)));
+
+  // 1599 * 1001 = 1600599 bits/ms = 200.074875 bytes/s.
+  EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToBytesPerPeriod(
+                      QuicTime::Delta::FromMilliseconds(1001)));
+
+  EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToKBytesPerPeriod(
+                      QuicTime::Delta::FromSeconds(1001)));
+}
+
+TEST_F(QuicBandwidthTest, TransferTime) {
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            QuicBandwidth::FromKBytesPerSecond(1).TransferTime(1000));
+  EXPECT_EQ(QuicTime::Delta::Zero(), QuicBandwidth::Zero().TransferTime(1000));
+}
+
+TEST_F(QuicBandwidthTest, RelOps) {
+  const QuicBandwidth b1 = QuicBandwidth::FromKBitsPerSecond(1);
+  const QuicBandwidth b2 = QuicBandwidth::FromKBytesPerSecond(2);
+  EXPECT_EQ(b1, b1);
+  EXPECT_NE(b1, b2);
+  EXPECT_LT(b1, b2);
+  EXPECT_GT(b2, b1);
+  EXPECT_LE(b1, b1);
+  EXPECT_LE(b1, b2);
+  EXPECT_GE(b1, b1);
+  EXPECT_GE(b2, b1);
+}
+
+TEST_F(QuicBandwidthTest, DebuggingValue) {
+  EXPECT_EQ("128 bits/s (16 bytes/s)",
+            QuicBandwidth::FromBytesPerSecond(16).ToDebuggingValue());
+  EXPECT_EQ("4096 bits/s (512 bytes/s)",
+            QuicBandwidth::FromBytesPerSecond(512).ToDebuggingValue());
+
+  QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000 * 50);
+  EXPECT_EQ("400.00 kbits/s (50.00 kbytes/s)", bandwidth.ToDebuggingValue());
+
+  bandwidth = bandwidth * 1000;
+  EXPECT_EQ("400.00 Mbits/s (50.00 Mbytes/s)", bandwidth.ToDebuggingValue());
+
+  bandwidth = bandwidth * 1000;
+  EXPECT_EQ("400.00 Gbits/s (50.00 Gbytes/s)", bandwidth.ToDebuggingValue());
+}
+
+TEST_F(QuicBandwidthTest, SpecialValues) {
+  EXPECT_EQ(0, QuicBandwidth::Zero().ToBitsPerSecond());
+  EXPECT_EQ(std::numeric_limits<int64_t>::max(),
+            QuicBandwidth::Infinite().ToBitsPerSecond());
+
+  EXPECT_TRUE(QuicBandwidth::Zero().IsZero());
+  EXPECT_FALSE(QuicBandwidth::Zero().IsInfinite());
+
+  EXPECT_TRUE(QuicBandwidth::Infinite().IsInfinite());
+  EXPECT_FALSE(QuicBandwidth::Infinite().IsZero());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_blocked_writer_interface.h b/quiche/quic/core/quic_blocked_writer_interface.h
new file mode 100644
index 0000000..062b5cc
--- /dev/null
+++ b/quiche/quic/core/quic_blocked_writer_interface.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is an interface for all objects that want to be notified that
+// the underlying UDP socket is available for writing (not write blocked
+// anymore).
+
+#ifndef QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
+#define QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicBlockedWriterInterface {
+ public:
+  virtual ~QuicBlockedWriterInterface() {}
+
+  // Called by the PacketWriter when the underlying socket becomes writable
+  // so that the BlockedWriter can go ahead and try writing.
+  virtual void OnBlockedWriterCanWrite() = 0;
+
+  virtual bool IsWriterBlocked() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_BLOCKED_WRITER_INTERFACE_H_
diff --git a/quiche/quic/core/quic_buffered_packet_store.cc b/quiche/quic/core/quic_buffered_packet_store.cc
new file mode 100644
index 0000000..f9c6cf6
--- /dev/null
+++ b/quiche/quic/core/quic_buffered_packet_store.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_buffered_packet_store.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
+using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
+using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+
+// Max number of connections this store can keep track.
+static const size_t kDefaultMaxConnectionsInStore = 100;
+// Up to half of the capacity can be used for storing non-CHLO packets.
+static const size_t kMaxConnectionsWithoutCHLO =
+    kDefaultMaxConnectionsInStore / 2;
+
+namespace {
+
+// This alarm removes expired entries in map each time this alarm fires.
+class ConnectionExpireAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit ConnectionExpireAlarm(QuicBufferedPacketStore* store)
+      : connection_store_(store) {}
+
+  void OnAlarm() override { connection_store_->OnExpirationTimeout(); }
+
+  ConnectionExpireAlarm(const ConnectionExpireAlarm&) = delete;
+  ConnectionExpireAlarm& operator=(const ConnectionExpireAlarm&) = delete;
+
+ private:
+  QuicBufferedPacketStore* connection_store_;
+};
+
+}  // namespace
+
+BufferedPacket::BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
+                               QuicSocketAddress self_address,
+                               QuicSocketAddress peer_address)
+    : packet(std::move(packet)),
+      self_address(self_address),
+      peer_address(peer_address) {}
+
+BufferedPacket::BufferedPacket(BufferedPacket&& other) = default;
+
+BufferedPacket& BufferedPacket::operator=(BufferedPacket&& other) = default;
+
+BufferedPacket::~BufferedPacket() {}
+
+BufferedPacketList::BufferedPacketList()
+    : creation_time(QuicTime::Zero()),
+      ietf_quic(false),
+      version(ParsedQuicVersion::Unsupported()) {}
+
+BufferedPacketList::BufferedPacketList(BufferedPacketList&& other) = default;
+
+BufferedPacketList& BufferedPacketList::operator=(BufferedPacketList&& other) =
+    default;
+
+BufferedPacketList::~BufferedPacketList() {}
+
+QuicBufferedPacketStore::QuicBufferedPacketStore(
+    VisitorInterface* visitor,
+    const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory)
+    : connection_life_span_(
+          QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)),
+      visitor_(visitor),
+      clock_(clock),
+      expiration_alarm_(
+          alarm_factory->CreateAlarm(new ConnectionExpireAlarm(this))) {}
+
+QuicBufferedPacketStore::~QuicBufferedPacketStore() {
+  if (expiration_alarm_ != nullptr) {
+    expiration_alarm_->PermanentCancel();
+  }
+}
+
+EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket(
+    QuicConnectionId connection_id, bool ietf_quic,
+    const QuicReceivedPacket& packet, QuicSocketAddress self_address,
+    QuicSocketAddress peer_address, const ParsedQuicVersion& version,
+    absl::optional<ParsedClientHello> parsed_chlo) {
+  const bool is_chlo = parsed_chlo.has_value();
+  QUIC_BUG_IF(quic_bug_12410_1, !GetQuicFlag(FLAGS_quic_allow_chlo_buffering))
+      << "Shouldn't buffer packets if disabled via flag.";
+  QUIC_BUG_IF(quic_bug_12410_2,
+              is_chlo && connections_with_chlo_.contains(connection_id))
+      << "Shouldn't buffer duplicated CHLO on connection " << connection_id;
+  QUIC_BUG_IF(quic_bug_12410_4, is_chlo && !version.IsKnown())
+      << "Should have version for CHLO packet.";
+
+  const bool is_first_packet = !undecryptable_packets_.contains(connection_id);
+  if (is_first_packet) {
+    if (ShouldNotBufferPacket(is_chlo)) {
+      // Drop the packet if the upper limit of undecryptable packets has been
+      // reached or the whole capacity of the store has been reached.
+      return TOO_MANY_CONNECTIONS;
+    }
+    undecryptable_packets_.emplace(
+        std::make_pair(connection_id, BufferedPacketList()));
+    undecryptable_packets_.back().second.ietf_quic = ietf_quic;
+    undecryptable_packets_.back().second.version = version;
+  }
+  QUICHE_CHECK(undecryptable_packets_.contains(connection_id));
+  BufferedPacketList& queue =
+      undecryptable_packets_.find(connection_id)->second;
+
+  if (!is_chlo) {
+    // If current packet is not CHLO, it might not be buffered because store
+    // only buffers certain number of undecryptable packets per connection.
+    size_t num_non_chlo_packets = connections_with_chlo_.contains(connection_id)
+                                      ? (queue.buffered_packets.size() - 1)
+                                      : queue.buffered_packets.size();
+    if (num_non_chlo_packets >= kDefaultMaxUndecryptablePackets) {
+      // If there are kMaxBufferedPacketsPerConnection packets buffered up for
+      // this connection, drop the current packet.
+      return TOO_MANY_PACKETS;
+    }
+  }
+
+  if (queue.buffered_packets.empty()) {
+    // If this is the first packet arrived on a new connection, initialize the
+    // creation time.
+    queue.creation_time = clock_->ApproximateNow();
+  }
+
+  BufferedPacket new_entry(std::unique_ptr<QuicReceivedPacket>(packet.Clone()),
+                           self_address, peer_address);
+  if (is_chlo) {
+    // Add CHLO to the beginning of buffered packets so that it can be delivered
+    // first later.
+    queue.buffered_packets.push_front(std::move(new_entry));
+    queue.parsed_chlo = std::move(parsed_chlo);
+    connections_with_chlo_[connection_id] = false;  // Dummy value.
+    // Set the version of buffered packets of this connection on CHLO.
+    queue.version = version;
+  } else {
+    // Buffer non-CHLO packets in arrival order.
+    queue.buffered_packets.push_back(std::move(new_entry));
+
+    // Attempt to parse multi-packet TLS CHLOs.
+    if (is_first_packet) {
+      queue.tls_chlo_extractor.IngestPacket(version, packet);
+      // Since this is the first packet and it's not a CHLO, the
+      // TlsChloExtractor should not have the entire CHLO.
+      QUIC_BUG_IF(quic_bug_12410_5,
+                  queue.tls_chlo_extractor.HasParsedFullChlo())
+          << "First packet in list should not contain full CHLO";
+    }
+    // TODO(b/154857081) Reorder CHLO packets ahead of other ones.
+  }
+
+  MaybeSetExpirationAlarm();
+  return SUCCESS;
+}
+
+bool QuicBufferedPacketStore::HasBufferedPackets(
+    QuicConnectionId connection_id) const {
+  return undecryptable_packets_.contains(connection_id);
+}
+
+bool QuicBufferedPacketStore::HasChlosBuffered() const {
+  return !connections_with_chlo_.empty();
+}
+
+BufferedPacketList QuicBufferedPacketStore::DeliverPackets(
+    QuicConnectionId connection_id) {
+  BufferedPacketList packets_to_deliver;
+  auto it = undecryptable_packets_.find(connection_id);
+  if (it != undecryptable_packets_.end()) {
+    packets_to_deliver = std::move(it->second);
+    undecryptable_packets_.erase(connection_id);
+  }
+  return packets_to_deliver;
+}
+
+void QuicBufferedPacketStore::DiscardPackets(QuicConnectionId connection_id) {
+  undecryptable_packets_.erase(connection_id);
+  connections_with_chlo_.erase(connection_id);
+}
+
+void QuicBufferedPacketStore::DiscardAllPackets() {
+  undecryptable_packets_.clear();
+  connections_with_chlo_.clear();
+  expiration_alarm_->Cancel();
+}
+
+void QuicBufferedPacketStore::OnExpirationTimeout() {
+  QuicTime expiration_time = clock_->ApproximateNow() - connection_life_span_;
+  while (!undecryptable_packets_.empty()) {
+    auto& entry = undecryptable_packets_.front();
+    if (entry.second.creation_time > expiration_time) {
+      break;
+    }
+    QuicConnectionId connection_id = entry.first;
+    visitor_->OnExpiredPackets(connection_id, std::move(entry.second));
+    undecryptable_packets_.pop_front();
+    connections_with_chlo_.erase(connection_id);
+  }
+  if (!undecryptable_packets_.empty()) {
+    MaybeSetExpirationAlarm();
+  }
+}
+
+void QuicBufferedPacketStore::MaybeSetExpirationAlarm() {
+  if (!expiration_alarm_->IsSet()) {
+    expiration_alarm_->Set(clock_->ApproximateNow() + connection_life_span_);
+  }
+}
+
+bool QuicBufferedPacketStore::ShouldNotBufferPacket(bool is_chlo) {
+  bool is_store_full =
+      undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore;
+
+  if (is_chlo) {
+    return is_store_full;
+  }
+
+  size_t num_connections_without_chlo =
+      undecryptable_packets_.size() - connections_with_chlo_.size();
+  bool reach_non_chlo_limit =
+      num_connections_without_chlo >= kMaxConnectionsWithoutCHLO;
+
+  return is_store_full || reach_non_chlo_limit;
+}
+
+BufferedPacketList QuicBufferedPacketStore::DeliverPacketsForNextConnection(
+    QuicConnectionId* connection_id) {
+  if (connections_with_chlo_.empty()) {
+    // Returns empty list if no CHLO has been buffered.
+    return BufferedPacketList();
+  }
+  *connection_id = connections_with_chlo_.front().first;
+  connections_with_chlo_.pop_front();
+
+  BufferedPacketList packets = DeliverPackets(*connection_id);
+  QUICHE_DCHECK(!packets.buffered_packets.empty() &&
+                packets.parsed_chlo.has_value())
+      << "Try to deliver connectons without CHLO. # packets:"
+      << packets.buffered_packets.size()
+      << ", has_parsed_chlo:" << packets.parsed_chlo.has_value();
+  return packets;
+}
+
+bool QuicBufferedPacketStore::HasChloForConnection(
+    QuicConnectionId connection_id) {
+  return connections_with_chlo_.contains(connection_id);
+}
+
+bool QuicBufferedPacketStore::IngestPacketForTlsChloExtraction(
+    const QuicConnectionId& connection_id, const ParsedQuicVersion& version,
+    const QuicReceivedPacket& packet, std::vector<std::string>* out_alpns,
+    std::string* out_sni, bool* out_resumption_attempted,
+    bool* out_early_data_attempted) {
+  QUICHE_DCHECK_NE(out_alpns, nullptr);
+  QUICHE_DCHECK_NE(out_sni, nullptr);
+  QUICHE_DCHECK_EQ(version.handshake_protocol, PROTOCOL_TLS1_3);
+  auto it = undecryptable_packets_.find(connection_id);
+  if (it == undecryptable_packets_.end()) {
+    QUIC_BUG(quic_bug_10838_1)
+        << "Cannot ingest packet for unknown connection ID " << connection_id;
+    return false;
+  }
+  it->second.tls_chlo_extractor.IngestPacket(version, packet);
+  if (!it->second.tls_chlo_extractor.HasParsedFullChlo()) {
+    return false;
+  }
+  const TlsChloExtractor& tls_chlo_extractor = it->second.tls_chlo_extractor;
+  *out_alpns = tls_chlo_extractor.alpns();
+  *out_sni = tls_chlo_extractor.server_name();
+  *out_resumption_attempted = tls_chlo_extractor.resumption_attempted();
+  *out_early_data_attempted = tls_chlo_extractor.early_data_attempted();
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_buffered_packet_store.h b/quiche/quic/core/quic_buffered_packet_store.h
new file mode 100644
index 0000000..34fd1ab
--- /dev/null
+++ b/quiche/quic/core/quic_buffered_packet_store.h
@@ -0,0 +1,194 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
+#define QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
+
+#include <list>
+#include <string>
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/tls_chlo_extractor.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+namespace test {
+class QuicBufferedPacketStorePeer;
+}  // namespace test
+
+// This class buffers packets for each connection until either
+// 1) They are requested to be delivered via
+//    DeliverPacket()/DeliverPacketsForNextConnection(), or
+// 2) They expire after exceeding their lifetime in the store.
+//
+// It can only buffer packets on certain number of connections. It has two pools
+// of connections: connections with CHLO buffered and those without CHLO. The
+// latter has its own upper limit along with the max number of connections this
+// store can hold. The former pool can grow till this store is full.
+class QUIC_NO_EXPORT QuicBufferedPacketStore {
+ public:
+  enum EnqueuePacketResult {
+    SUCCESS = 0,
+    TOO_MANY_PACKETS,  // Too many packets stored up for a certain connection.
+    TOO_MANY_CONNECTIONS  // Too many connections stored up in the store.
+  };
+
+  struct QUIC_NO_EXPORT BufferedPacket {
+    BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
+                   QuicSocketAddress self_address,
+                   QuicSocketAddress peer_address);
+    BufferedPacket(BufferedPacket&& other);
+
+    BufferedPacket& operator=(BufferedPacket&& other);
+
+    ~BufferedPacket();
+
+    std::unique_ptr<QuicReceivedPacket> packet;
+    QuicSocketAddress self_address;
+    QuicSocketAddress peer_address;
+  };
+
+  // A queue of BufferedPackets for a connection.
+  struct QUIC_NO_EXPORT BufferedPacketList {
+    BufferedPacketList();
+    BufferedPacketList(BufferedPacketList&& other);
+
+    BufferedPacketList& operator=(BufferedPacketList&& other);
+
+    ~BufferedPacketList();
+
+    std::list<BufferedPacket> buffered_packets;
+    QuicTime creation_time;
+    // |parsed_chlo| is set iff the entire CHLO has been received.
+    absl::optional<ParsedClientHello> parsed_chlo;
+    // Indicating whether this is an IETF QUIC connection.
+    bool ietf_quic;
+    // If buffered_packets contains the CHLO, it is the version of the CHLO.
+    // Otherwise, it is the version of the first packet in |buffered_packets|.
+    ParsedQuicVersion version;
+    TlsChloExtractor tls_chlo_extractor;
+  };
+
+  using BufferedPacketMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
+                                                        BufferedPacketList,
+                                                        QuicConnectionIdHash>;
+
+  class QUIC_NO_EXPORT VisitorInterface {
+   public:
+    virtual ~VisitorInterface() {}
+
+    // Called for each expired connection when alarm fires.
+    virtual void OnExpiredPackets(QuicConnectionId connection_id,
+                                  BufferedPacketList early_arrived_packets) = 0;
+  };
+
+  QuicBufferedPacketStore(VisitorInterface* visitor, const QuicClock* clock,
+                          QuicAlarmFactory* alarm_factory);
+
+  QuicBufferedPacketStore(const QuicBufferedPacketStore&) = delete;
+
+  ~QuicBufferedPacketStore();
+
+  QuicBufferedPacketStore& operator=(const QuicBufferedPacketStore&) = delete;
+
+  // Adds a copy of packet into the packet queue for given connection. If the
+  // packet is the last one of the CHLO, |parsed_chlo| will contain a parsed
+  // version of the CHLO.
+  EnqueuePacketResult EnqueuePacket(
+      QuicConnectionId connection_id, bool ietf_quic,
+      const QuicReceivedPacket& packet, QuicSocketAddress self_address,
+      QuicSocketAddress peer_address, const ParsedQuicVersion& version,
+      absl::optional<ParsedClientHello> parsed_chlo);
+
+  // Returns true if there are any packets buffered for |connection_id|.
+  bool HasBufferedPackets(QuicConnectionId connection_id) const;
+
+  // Ingests this packet into the corresponding TlsChloExtractor. This should
+  // only be called when HasBufferedPackets(connection_id) is true.
+  // Returns whether we've now parsed a full multi-packet TLS CHLO.
+  // When this returns true, |out_alpns| is populated with the list of ALPNs
+  // extracted from the CHLO. |out_sni| is populated with the SNI tag in CHLO.
+  // |out_resumption_attempted| is populated if the CHLO has the
+  // 'pre_shared_key' TLS extension. |out_early_data_attempted| is populated if
+  // the CHLO has the 'early_data' TLS extension.
+  bool IngestPacketForTlsChloExtraction(const QuicConnectionId& connection_id,
+                                        const ParsedQuicVersion& version,
+                                        const QuicReceivedPacket& packet,
+                                        std::vector<std::string>* out_alpns,
+                                        std::string* out_sni,
+                                        bool* out_resumption_attempted,
+                                        bool* out_early_data_attempted);
+
+  // Returns the list of buffered packets for |connection_id| and removes them
+  // from the store. Returns an empty list if no early arrived packets for this
+  // connection are present.
+  BufferedPacketList DeliverPackets(QuicConnectionId connection_id);
+
+  // Discards packets buffered for |connection_id|, if any.
+  void DiscardPackets(QuicConnectionId connection_id);
+
+  // Discards all the packets.
+  void DiscardAllPackets();
+
+  // Examines how long packets have been buffered in the store for each
+  // connection. If they stay too long, removes them for new coming packets and
+  // calls |visitor_|'s OnPotentialConnectionExpire().
+  // Resets the alarm at the end.
+  void OnExpirationTimeout();
+
+  // Delivers buffered packets for next connection with CHLO to open.
+  // Return connection id for next connection in |connection_id|
+  // and all buffered packets including CHLO.
+  // The returned list should at least has one packet(CHLO) if
+  // store does have any connection to open. If no connection in the store has
+  // received CHLO yet, empty list will be returned.
+  BufferedPacketList DeliverPacketsForNextConnection(
+      QuicConnectionId* connection_id);
+
+  // Is given connection already buffered in the store?
+  bool HasChloForConnection(QuicConnectionId connection_id);
+
+  // Is there any CHLO buffered in the store?
+  bool HasChlosBuffered() const;
+
+ private:
+  friend class test::QuicBufferedPacketStorePeer;
+
+  // Set expiration alarm if it hasn't been set.
+  void MaybeSetExpirationAlarm();
+
+  // Return true if add an extra packet will go beyond allowed max connection
+  // limit. The limit for non-CHLO packet and CHLO packet is different.
+  bool ShouldNotBufferPacket(bool is_chlo);
+
+  // A map to store packet queues with creation time for each connection.
+  BufferedPacketMap undecryptable_packets_;
+
+  // The max time the packets of a connection can be buffer in the store.
+  const QuicTime::Delta connection_life_span_;
+
+  VisitorInterface* visitor_;  // Unowned.
+
+  const QuicClock* clock_;  // Unowned.
+
+  // This alarm fires every |connection_life_span_| to clean up
+  // packets staying in the store for too long.
+  std::unique_ptr<QuicAlarm> expiration_alarm_;
+
+  // Keeps track of connection with CHLO buffered up already and the order they
+  // arrive.
+  quiche::QuicheLinkedHashMap<QuicConnectionId, bool, QuicConnectionIdHash>
+      connections_with_chlo_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
diff --git a/quiche/quic/core/quic_buffered_packet_store_test.cc b/quiche/quic/core/quic_buffered_packet_store_test.cc
new file mode 100644
index 0000000..b6d65e1
--- /dev/null
+++ b/quiche/quic/core/quic_buffered_packet_store_test.cc
@@ -0,0 +1,502 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_buffered_packet_store.h"
+
+#include <list>
+#include <string>
+
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_buffered_packet_store_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+static const size_t kDefaultMaxConnectionsInStore = 100;
+static const size_t kMaxConnectionsWithoutCHLO =
+    kDefaultMaxConnectionsInStore / 2;
+
+namespace test {
+namespace {
+
+const absl::optional<ParsedClientHello> kNoParsedChlo;
+const absl::optional<ParsedClientHello> kDefaultParsedChlo =
+    absl::make_optional<ParsedClientHello>();
+
+using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
+using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
+using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+using ::testing::ElementsAre;
+class QuicBufferedPacketStoreVisitor
+    : public QuicBufferedPacketStore::VisitorInterface {
+ public:
+  QuicBufferedPacketStoreVisitor() {}
+
+  ~QuicBufferedPacketStoreVisitor() override {}
+
+  void OnExpiredPackets(QuicConnectionId /*connection_id*/,
+                        BufferedPacketList early_arrived_packets) override {
+    last_expired_packet_queue_ = std::move(early_arrived_packets);
+  }
+
+  // The packets queue for most recently expirect connection.
+  BufferedPacketList last_expired_packet_queue_;
+};
+
+class QuicBufferedPacketStoreTest : public QuicTest {
+ public:
+  QuicBufferedPacketStoreTest()
+      : store_(&visitor_, &clock_, &alarm_factory_),
+        self_address_(QuicIpAddress::Any6(), 65535),
+        peer_address_(QuicIpAddress::Any6(), 65535),
+        packet_content_("some encrypted content"),
+        packet_time_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(42)),
+        packet_(packet_content_.data(), packet_content_.size(), packet_time_),
+        invalid_version_(UnsupportedQuicVersion()),
+        valid_version_(CurrentSupportedVersions().front()) {}
+
+ protected:
+  QuicBufferedPacketStoreVisitor visitor_;
+  MockClock clock_;
+  MockAlarmFactory alarm_factory_;
+  QuicBufferedPacketStore store_;
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  std::string packet_content_;
+  QuicTime packet_time_;
+  QuicReceivedPacket packet_;
+  const ParsedQuicVersion invalid_version_;
+  const ParsedQuicVersion valid_version_;
+};
+
+TEST_F(QuicBufferedPacketStoreTest, SimpleEnqueueAndDeliverPacket) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  auto packets = store_.DeliverPackets(connection_id);
+  const std::list<BufferedPacket>& queue = packets.buffered_packets;
+  ASSERT_EQ(1u, queue.size());
+  ASSERT_FALSE(packets.parsed_chlo.has_value());
+  // There is no valid version because CHLO has not arrived.
+  EXPECT_EQ(invalid_version_, packets.version);
+  // Check content of the only packet in the queue.
+  EXPECT_EQ(packet_content_, queue.front().packet->AsStringPiece());
+  EXPECT_EQ(packet_time_, queue.front().packet->receipt_time());
+  EXPECT_EQ(peer_address_, queue.front().peer_address);
+  EXPECT_EQ(self_address_, queue.front().self_address);
+  // No more packets on connection 1 should remain in the store.
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+}
+
+TEST_F(QuicBufferedPacketStoreTest, DifferentPacketAddressOnOneConnection) {
+  QuicSocketAddress addr_with_new_port(QuicIpAddress::Any4(), 256);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       addr_with_new_port, invalid_version_, kNoParsedChlo);
+  std::list<BufferedPacket> queue =
+      store_.DeliverPackets(connection_id).buffered_packets;
+  ASSERT_EQ(2u, queue.size());
+  // The address migration path should be preserved.
+  EXPECT_EQ(peer_address_, queue.front().peer_address);
+  EXPECT_EQ(addr_with_new_port, queue.back().peer_address);
+}
+
+TEST_F(QuicBufferedPacketStoreTest,
+       EnqueueAndDeliverMultiplePacketsOnMultipleConnections) {
+  size_t num_connections = 10;
+  for (uint64_t conn_id = 1; conn_id <= num_connections; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                         peer_address_, invalid_version_, kNoParsedChlo);
+    store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                         peer_address_, invalid_version_, kNoParsedChlo);
+  }
+
+  // Deliver packets in reversed order.
+  for (uint64_t conn_id = num_connections; conn_id > 0; --conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    std::list<BufferedPacket> queue =
+        store_.DeliverPackets(connection_id).buffered_packets;
+    ASSERT_EQ(2u, queue.size());
+  }
+}
+
+TEST_F(QuicBufferedPacketStoreTest,
+       FailToBufferTooManyPacketsOnExistingConnection) {
+  // Tests that for one connection, only limited number of packets can be
+  // buffered.
+  size_t num_packets = kDefaultMaxUndecryptablePackets + 1;
+  QuicConnectionId connection_id = TestConnectionId(1);
+  // Arrived CHLO packet shouldn't affect how many non-CHLO pacekts store can
+  // keep.
+  EXPECT_EQ(
+      QuicBufferedPacketStore::SUCCESS,
+      store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                           peer_address_, valid_version_, kDefaultParsedChlo));
+  for (size_t i = 1; i <= num_packets; ++i) {
+    // Only first |kDefaultMaxUndecryptablePackets packets| will be buffered.
+    EnqueuePacketResult result =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, invalid_version_, kNoParsedChlo);
+    if (i <= kDefaultMaxUndecryptablePackets) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
+    } else {
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_PACKETS, result);
+    }
+  }
+
+  // Only first |kDefaultMaxUndecryptablePackets| non-CHLO packets and CHLO are
+  // buffered.
+  EXPECT_EQ(kDefaultMaxUndecryptablePackets + 1,
+            store_.DeliverPackets(connection_id).buffered_packets.size());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, ReachNonChloConnectionUpperLimit) {
+  // Tests that store can only keep early arrived packets for limited number of
+  // connections.
+  const size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
+  for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EnqueuePacketResult result =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, invalid_version_, kNoParsedChlo);
+    if (conn_id <= kMaxConnectionsWithoutCHLO) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
+    } else {
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
+    }
+  }
+  // Store only keeps early arrived packets upto |kNumConnections| connections.
+  for (uint64_t conn_id = 1; conn_id <= kNumConnections; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    std::list<BufferedPacket> queue =
+        store_.DeliverPackets(connection_id).buffered_packets;
+    if (conn_id <= kMaxConnectionsWithoutCHLO) {
+      EXPECT_EQ(1u, queue.size());
+    } else {
+      EXPECT_EQ(0u, queue.size());
+    }
+  }
+}
+
+TEST_F(QuicBufferedPacketStoreTest,
+       FullStoreFailToBufferDataPacketOnNewConnection) {
+  // Send enough CHLOs so that store gets full before number of connections
+  // without CHLO reaches its upper limit.
+  size_t num_chlos =
+      kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
+  for (uint64_t conn_id = 1; conn_id <= num_chlos; ++conn_id) {
+    EXPECT_EQ(EnqueuePacketResult::SUCCESS,
+              store_.EnqueuePacket(TestConnectionId(conn_id), false, packet_,
+                                   self_address_, peer_address_, valid_version_,
+                                   kDefaultParsedChlo));
+  }
+
+  // Send data packets on another |kMaxConnectionsWithoutCHLO| connections.
+  // Store should only be able to buffer till it's full.
+  for (uint64_t conn_id = num_chlos + 1;
+       conn_id <= (kDefaultMaxConnectionsInStore + 1); ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EnqueuePacketResult result =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, valid_version_, kDefaultParsedChlo);
+    if (conn_id <= kDefaultMaxConnectionsInStore) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
+    } else {
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result);
+    }
+  }
+}
+
+TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
+  // Buffer data packets on different connections upto limit.
+  for (uint64_t conn_id = 1; conn_id <= kMaxConnectionsWithoutCHLO; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_EQ(
+        EnqueuePacketResult::SUCCESS,
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, invalid_version_, kNoParsedChlo));
+  }
+
+  // Buffer CHLOs on other connections till store is full.
+  for (size_t i = kMaxConnectionsWithoutCHLO + 1;
+       i <= kDefaultMaxConnectionsInStore + 1; ++i) {
+    QuicConnectionId connection_id = TestConnectionId(i);
+    EnqueuePacketResult rs =
+        store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                             peer_address_, valid_version_, kDefaultParsedChlo);
+    if (i <= kDefaultMaxConnectionsInStore) {
+      EXPECT_EQ(EnqueuePacketResult::SUCCESS, rs);
+      EXPECT_TRUE(store_.HasChloForConnection(connection_id));
+    } else {
+      // Last CHLO can't be buffered because store is full.
+      EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, rs);
+      EXPECT_FALSE(store_.HasChloForConnection(connection_id));
+    }
+  }
+
+  // But buffering a CHLO belonging to a connection already has data packet
+  // buffered in the store should success. This is the connection should be
+  // delivered at last.
+  EXPECT_EQ(
+      EnqueuePacketResult::SUCCESS,
+      store_.EnqueuePacket(
+          /*connection_id=*/TestConnectionId(1), false, packet_, self_address_,
+          peer_address_, valid_version_, kDefaultParsedChlo));
+  EXPECT_TRUE(store_.HasChloForConnection(
+      /*connection_id=*/TestConnectionId(1)));
+
+  QuicConnectionId delivered_conn_id;
+  for (size_t i = 0;
+       i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
+       ++i) {
+    if (i < kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO) {
+      // Only CHLO is buffered.
+      EXPECT_EQ(1u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
+                        .buffered_packets.size());
+      EXPECT_EQ(TestConnectionId(i + kMaxConnectionsWithoutCHLO + 1),
+                delivered_conn_id);
+    } else {
+      EXPECT_EQ(2u, store_.DeliverPacketsForNextConnection(&delivered_conn_id)
+                        .buffered_packets.size());
+      EXPECT_EQ(TestConnectionId(1u), delivered_conn_id);
+    }
+  }
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+// Tests that store expires long-staying connections appropriately for
+// connections both with and without CHLOs.
+TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_EQ(
+      EnqueuePacketResult::SUCCESS,
+      store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                           peer_address_, valid_version_, kDefaultParsedChlo));
+  QuicConnectionId connection_id2 = TestConnectionId(2);
+  EXPECT_EQ(
+      EnqueuePacketResult::SUCCESS,
+      store_.EnqueuePacket(connection_id2, false, packet_, self_address_,
+                           peer_address_, invalid_version_, kNoParsedChlo));
+
+  // CHLO on connection 3 arrives 1ms later.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  QuicConnectionId connection_id3 = TestConnectionId(3);
+  // Use different client address to differetiate packets from different
+  // connections.
+  QuicSocketAddress another_client_address(QuicIpAddress::Any4(), 255);
+  store_.EnqueuePacket(connection_id3, false, packet_, self_address_,
+                       another_client_address, valid_version_,
+                       kDefaultParsedChlo);
+
+  // Advance clock to the time when connection 1 and 2 expires.
+  clock_.AdvanceTime(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
+      clock_.ApproximateNow());
+  ASSERT_GE(clock_.ApproximateNow(),
+            QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline());
+  // Fire alarm to remove long-staying connection 1 and 2 packets.
+  alarm_factory_.FireAlarm(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_));
+  EXPECT_EQ(1u, visitor_.last_expired_packet_queue_.buffered_packets.size());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id2));
+
+  // Try to deliver packets, but packet queue has been removed so no
+  // packets can be returned.
+  ASSERT_EQ(0u, store_.DeliverPackets(connection_id).buffered_packets.size());
+  ASSERT_EQ(0u, store_.DeliverPackets(connection_id2).buffered_packets.size());
+  QuicConnectionId delivered_conn_id;
+  auto queue = store_.DeliverPacketsForNextConnection(&delivered_conn_id)
+                   .buffered_packets;
+  // Connection 3 is the next to be delivered as connection 1 already expired.
+  EXPECT_EQ(connection_id3, delivered_conn_id);
+  ASSERT_EQ(1u, queue.size());
+  // Packets in connection 3 should use another peer address.
+  EXPECT_EQ(another_client_address, queue.front().peer_address);
+
+  // Test the alarm is reset by enqueueing 2 packets for 4th connection and wait
+  // for them to expire.
+  QuicConnectionId connection_id4 = TestConnectionId(4);
+  store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id4, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  clock_.AdvanceTime(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
+      clock_.ApproximateNow());
+  alarm_factory_.FireAlarm(
+      QuicBufferedPacketStorePeer::expiration_alarm(&store_));
+  // |last_expired_packet_queue_| should be updated.
+  EXPECT_EQ(2u, visitor_.last_expired_packet_queue_.buffered_packets.size());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, SimpleDiscardPackets) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  // Enqueue some packets
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+
+  // Dicard the packets
+  store_.DiscardPackets(connection_id);
+
+  // No packets on connection 1 should remain in the store
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+
+  // Check idempotency
+  store_.DiscardPackets(connection_id);
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, DiscardWithCHLOs) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  // Enqueue some packets, which include a CHLO
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, valid_version_, kDefaultParsedChlo);
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Dicard the packets
+  store_.DiscardPackets(connection_id);
+
+  // No packets on connection 1 should remain in the store
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+
+  // Check idempotency
+  store_.DiscardPackets(connection_id);
+  EXPECT_TRUE(store_.DeliverPackets(connection_id).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, MultipleDiscardPackets) {
+  QuicConnectionId connection_id_1 = TestConnectionId(1);
+  QuicConnectionId connection_id_2 = TestConnectionId(2);
+
+  // Enqueue some packets for two connection IDs
+  store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id_1, false, packet_, self_address_,
+                       peer_address_, invalid_version_, kNoParsedChlo);
+
+  ParsedClientHello parsed_chlo;
+  parsed_chlo.alpns.push_back("h3");
+  parsed_chlo.sni = TestHostname();
+  store_.EnqueuePacket(connection_id_2, false, packet_, self_address_,
+                       peer_address_, valid_version_, parsed_chlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_1));
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Discard the packets for connection 1
+  store_.DiscardPackets(connection_id_1);
+
+  // No packets on connection 1 should remain in the store
+  EXPECT_TRUE(store_.DeliverPackets(connection_id_1).buffered_packets.empty());
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id_1));
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Packets on connection 2 should remain
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
+  auto packets = store_.DeliverPackets(connection_id_2);
+  EXPECT_EQ(1u, packets.buffered_packets.size());
+  ASSERT_EQ(1u, packets.parsed_chlo->alpns.size());
+  EXPECT_EQ("h3", packets.parsed_chlo->alpns[0]);
+  EXPECT_EQ(TestHostname(), packets.parsed_chlo->sni);
+  // Since connection_id_2's chlo arrives, verify version is set.
+  EXPECT_EQ(valid_version_, packets.version);
+  EXPECT_TRUE(store_.HasChlosBuffered());
+
+  // Discard the packets for connection 2
+  store_.DiscardPackets(connection_id_2);
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, DiscardPacketsEmpty) {
+  // Check that DiscardPackets on an unknown connection ID is safe and does
+  // nothing.
+  QuicConnectionId connection_id = TestConnectionId(11235);
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+  store_.DiscardPackets(connection_id);
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.HasChlosBuffered());
+}
+
+TEST_F(QuicBufferedPacketStoreTest, IngestPacketForTlsChloExtraction) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  std::vector<std::string> alpns;
+  std::string sni;
+  bool resumption_attempted = false;
+  bool early_data_attempted = false;
+  QuicConfig config;
+
+  EXPECT_FALSE(store_.HasBufferedPackets(connection_id));
+  store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+                       peer_address_, valid_version_, kNoParsedChlo);
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+
+  // The packet in 'packet_' is not a TLS CHLO packet.
+  EXPECT_FALSE(store_.IngestPacketForTlsChloExtraction(
+      connection_id, valid_version_, packet_, &alpns, &sni,
+      &resumption_attempted, &early_data_attempted));
+
+  store_.DiscardPackets(connection_id);
+
+  // Force the TLS CHLO to span multiple packets.
+  constexpr auto kCustomParameterId =
+      static_cast<TransportParameters::TransportParameterId>(0xff33);
+  std::string kCustomParameterValue(2000, '-');
+  config.custom_transport_parameters_to_send()[kCustomParameterId] =
+      kCustomParameterValue;
+  auto packets = GetFirstFlightOfPackets(valid_version_, config);
+  ASSERT_EQ(packets.size(), 2u);
+
+  store_.EnqueuePacket(connection_id, false, *packets[0], self_address_,
+                       peer_address_, valid_version_, kNoParsedChlo);
+  store_.EnqueuePacket(connection_id, false, *packets[1], self_address_,
+                       peer_address_, valid_version_, kNoParsedChlo);
+
+  EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
+  EXPECT_FALSE(store_.IngestPacketForTlsChloExtraction(
+      connection_id, valid_version_, *packets[0], &alpns, &sni,
+      &resumption_attempted, &early_data_attempted));
+  EXPECT_TRUE(store_.IngestPacketForTlsChloExtraction(
+      connection_id, valid_version_, *packets[1], &alpns, &sni,
+      &resumption_attempted, &early_data_attempted));
+
+  EXPECT_THAT(alpns, ElementsAre(AlpnForVersion(valid_version_)));
+  EXPECT_EQ(sni, TestHostname());
+
+  EXPECT_FALSE(resumption_attempted);
+  EXPECT_FALSE(early_data_attempted);
+}
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_chaos_protector.cc b/quiche/quic/core/quic_chaos_protector.cc
new file mode 100644
index 0000000..dd25b9e
--- /dev/null
+++ b/quiche/quic/core/quic_chaos_protector.cc
@@ -0,0 +1,232 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_chaos_protector.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
+#include "quiche/quic/core/frames/quic_ping_frame.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+QuicChaosProtector::QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
+                                       int num_padding_bytes,
+                                       size_t packet_size,
+                                       QuicFramer* framer,
+                                       QuicRandom* random)
+    : packet_size_(packet_size),
+      crypto_data_length_(crypto_frame.data_length),
+      crypto_buffer_offset_(crypto_frame.offset),
+      level_(crypto_frame.level),
+      remaining_padding_bytes_(num_padding_bytes),
+      framer_(framer),
+      random_(random) {
+  QUICHE_DCHECK_NE(framer_, nullptr);
+  QUICHE_DCHECK_NE(framer_->data_producer(), nullptr);
+  QUICHE_DCHECK_NE(random_, nullptr);
+}
+
+QuicChaosProtector::~QuicChaosProtector() {
+  DeleteFrames(&frames_);
+}
+
+absl::optional<size_t> QuicChaosProtector::BuildDataPacket(
+    const QuicPacketHeader& header,
+    char* buffer) {
+  if (!CopyCryptoDataToLocalBuffer()) {
+    return absl::nullopt;
+  }
+  SplitCryptoFrame();
+  AddPingFrames();
+  SpreadPadding();
+  ReorderFrames();
+  return BuildPacket(header, buffer);
+}
+
+WriteStreamDataResult QuicChaosProtector::WriteStreamData(
+    QuicStreamId id,
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    QuicDataWriter* /*writer*/) {
+  QUIC_BUG(chaos stream) << "This should never be called; id " << id
+                         << " offset " << offset << " data_length "
+                         << data_length;
+  return STREAM_MISSING;
+}
+
+bool QuicChaosProtector::WriteCryptoData(EncryptionLevel level,
+                                         QuicStreamOffset offset,
+                                         QuicByteCount data_length,
+                                         QuicDataWriter* writer) {
+  if (level != level_) {
+    QUIC_BUG(chaos bad level) << "Unexpected " << level << " != " << level_;
+    return false;
+  }
+  // This is `offset + data_length > buffer_offset_ + buffer_length_`
+  // but with integer overflow protection.
+  if (offset < crypto_buffer_offset_ || data_length > crypto_data_length_ ||
+      offset - crypto_buffer_offset_ > crypto_data_length_ - data_length) {
+    QUIC_BUG(chaos bad lengths)
+        << "Unexpected buffer_offset_ " << crypto_buffer_offset_ << " offset "
+        << offset << " buffer_length_ " << crypto_data_length_
+        << " data_length " << data_length;
+    return false;
+  }
+  writer->WriteBytes(&crypto_data_buffer_[offset - crypto_buffer_offset_],
+                     data_length);
+  return true;
+}
+
+bool QuicChaosProtector::CopyCryptoDataToLocalBuffer() {
+  crypto_frame_buffer_ = std::make_unique<char[]>(packet_size_);
+  frames_.push_back(QuicFrame(
+      new QuicCryptoFrame(level_, crypto_buffer_offset_, crypto_data_length_)));
+  // We use |framer_| to serialize the CRYPTO frame in order to extract its
+  // data from the crypto data producer. This ensures that we reuse the
+  // usual serialization code path, but has the downside that we then need to
+  // parse the offset and length in order to skip over those fields.
+  QuicDataWriter writer(packet_size_, crypto_frame_buffer_.get());
+  if (!framer_->AppendCryptoFrame(*frames_.front().crypto_frame, &writer)) {
+    QUIC_BUG(chaos write crypto data);
+    return false;
+  }
+  QuicDataReader reader(crypto_frame_buffer_.get(), writer.length());
+  uint64_t parsed_offset, parsed_length;
+  if (!reader.ReadVarInt62(&parsed_offset) ||
+      !reader.ReadVarInt62(&parsed_length)) {
+    QUIC_BUG(chaos parse crypto frame);
+    return false;
+  }
+
+  absl::string_view crypto_data = reader.ReadRemainingPayload();
+  crypto_data_buffer_ = crypto_data.data();
+
+  QUICHE_DCHECK_EQ(parsed_offset, crypto_buffer_offset_);
+  QUICHE_DCHECK_EQ(parsed_length, crypto_data_length_);
+  QUICHE_DCHECK_EQ(parsed_length, crypto_data.length());
+
+  return true;
+}
+
+void QuicChaosProtector::SplitCryptoFrame() {
+  const int max_overhead_of_adding_a_crypto_frame =
+      static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+          crypto_buffer_offset_ + crypto_data_length_, crypto_data_length_));
+  // Pick a random number of CRYPTO frames to add.
+  constexpr uint64_t kMaxAddedCryptoFrames = 10;
+  const uint64_t num_added_crypto_frames =
+      random_->InsecureRandUint64() % (kMaxAddedCryptoFrames + 1);
+  for (uint64_t i = 0; i < num_added_crypto_frames; i++) {
+    if (remaining_padding_bytes_ < max_overhead_of_adding_a_crypto_frame) {
+      break;
+    }
+    // Pick a random frame and split it by shrinking the picked frame and
+    // moving the second half of its data to a new frame that is then appended
+    // to |frames|.
+    size_t frame_to_split_index =
+        random_->InsecureRandUint64() % frames_.size();
+    QuicCryptoFrame* frame_to_split =
+        frames_[frame_to_split_index].crypto_frame;
+    if (frame_to_split->data_length <= 1) {
+      continue;
+    }
+    const int frame_to_split_old_overhead =
+        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+            frame_to_split->offset, frame_to_split->data_length));
+    const QuicPacketLength frame_to_split_new_data_length =
+        1 + (random_->InsecureRandUint64() % (frame_to_split->data_length - 1));
+    const QuicPacketLength new_frame_data_length =
+        frame_to_split->data_length - frame_to_split_new_data_length;
+    const QuicStreamOffset new_frame_offset =
+        frame_to_split->offset + frame_to_split_new_data_length;
+    frame_to_split->data_length -= new_frame_data_length;
+    frames_.push_back(QuicFrame(
+        new QuicCryptoFrame(level_, new_frame_offset, new_frame_data_length)));
+    const int frame_to_split_new_overhead =
+        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+            frame_to_split->offset, frame_to_split->data_length));
+    const int new_frame_overhead =
+        static_cast<int>(QuicFramer::GetMinCryptoFrameSize(
+            new_frame_offset, new_frame_data_length));
+    QUICHE_DCHECK_LE(frame_to_split_new_overhead, frame_to_split_old_overhead);
+    // Readjust padding based on increased overhead.
+    remaining_padding_bytes_ -= new_frame_overhead;
+    remaining_padding_bytes_ -= frame_to_split_new_overhead;
+    remaining_padding_bytes_ += frame_to_split_old_overhead;
+  }
+}
+
+void QuicChaosProtector::AddPingFrames() {
+  if (remaining_padding_bytes_ == 0) {
+    return;
+  }
+  constexpr uint64_t kMaxAddedPingFrames = 10;
+  const uint64_t num_ping_frames =
+      random_->InsecureRandUint64() %
+      std::min<uint64_t>(kMaxAddedPingFrames, remaining_padding_bytes_);
+  for (uint64_t i = 0; i < num_ping_frames; i++) {
+    frames_.push_back(QuicFrame(QuicPingFrame()));
+  }
+  remaining_padding_bytes_ -= static_cast<int>(num_ping_frames);
+}
+
+void QuicChaosProtector::ReorderFrames() {
+  // Walk the array backwards and swap each frame with a random earlier one.
+  for (size_t i = frames_.size() - 1; i > 0; i--) {
+    std::swap(frames_[i], frames_[random_->InsecureRandUint64() % (i + 1)]);
+  }
+}
+
+void QuicChaosProtector::SpreadPadding() {
+  for (auto it = frames_.begin(); it != frames_.end(); ++it) {
+    const int padding_bytes_in_this_frame =
+        random_->InsecureRandUint64() % (remaining_padding_bytes_ + 1);
+    if (padding_bytes_in_this_frame <= 0) {
+      continue;
+    }
+    it = frames_.insert(
+        it, QuicFrame(QuicPaddingFrame(padding_bytes_in_this_frame)));
+    ++it;  // Skip over the padding frame we just added.
+    remaining_padding_bytes_ -= padding_bytes_in_this_frame;
+  }
+  if (remaining_padding_bytes_ > 0) {
+    frames_.push_back(QuicFrame(QuicPaddingFrame(remaining_padding_bytes_)));
+  }
+}
+
+absl::optional<size_t> QuicChaosProtector::BuildPacket(
+    const QuicPacketHeader& header,
+    char* buffer) {
+  QuicStreamFrameDataProducer* original_data_producer =
+      framer_->data_producer();
+  framer_->set_data_producer(this);
+
+  size_t length =
+      framer_->BuildDataPacket(header, frames_, buffer, packet_size_, level_);
+
+  framer_->set_data_producer(original_data_producer);
+  if (length == 0) {
+    return absl::nullopt;
+  }
+  return length;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_chaos_protector.h b/quiche/quic/core/quic_chaos_protector.h
new file mode 100644
index 0000000..e5fec03
--- /dev/null
+++ b/quiche/quic/core/quic_chaos_protector.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
+#define QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+namespace test {
+class QuicChaosProtectorTest;
+}
+
+// QuicChaosProtector will take a crypto frame and an amount of padding and
+// build a data packet that will parse to something equivalent.
+class QUIC_EXPORT_PRIVATE QuicChaosProtector
+    : public QuicStreamFrameDataProducer {
+ public:
+  // |framer| and |random| must be valid for the lifetime of QuicChaosProtector.
+  explicit QuicChaosProtector(const QuicCryptoFrame& crypto_frame,
+                              int num_padding_bytes,
+                              size_t packet_size,
+                              QuicFramer* framer,
+                              QuicRandom* random);
+
+  ~QuicChaosProtector() override;
+
+  QuicChaosProtector(const QuicChaosProtector&) = delete;
+  QuicChaosProtector(QuicChaosProtector&&) = delete;
+  QuicChaosProtector& operator=(const QuicChaosProtector&) = delete;
+  QuicChaosProtector& operator=(QuicChaosProtector&&) = delete;
+
+  // Attempts to build a data packet with chaos protection. If an error occurs,
+  // then absl::nullopt is returned. Otherwise returns the serialized length.
+  absl::optional<size_t> BuildDataPacket(const QuicPacketHeader& header,
+                                         char* buffer);
+
+  // From QuicStreamFrameDataProducer.
+  WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* /*writer*/) override;
+  bool WriteCryptoData(EncryptionLevel level,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override;
+
+ private:
+  friend class test::QuicChaosProtectorTest;
+
+  // Allocate the crypto data buffer, create the CRYPTO frame and write the
+  // crypto data to our buffer.
+  bool CopyCryptoDataToLocalBuffer();
+
+  // Split the CRYPTO frame in |frames_| into one or more CRYPTO frames that
+  // collectively represent the same data. Adjusts padding to compensate.
+  void SplitCryptoFrame();
+
+  // Add a random number of PING frames to |frames_| and adjust padding.
+  void AddPingFrames();
+
+  // Randomly reorder |frames_|.
+  void ReorderFrames();
+
+  // Add PADDING frames randomly between all other frames.
+  void SpreadPadding();
+
+  // Serialize |frames_| using |framer_|.
+  absl::optional<size_t> BuildPacket(const QuicPacketHeader& header,
+                                     char* buffer);
+
+  size_t packet_size_;
+  std::unique_ptr<char[]> crypto_frame_buffer_;
+  const char* crypto_data_buffer_ = nullptr;
+  QuicByteCount crypto_data_length_;
+  QuicStreamOffset crypto_buffer_offset_;
+  EncryptionLevel level_;
+  int remaining_padding_bytes_;
+  QuicFrames frames_;   // Inner frames owned, will be deleted by destructor.
+  QuicFramer* framer_;  // Unowned.
+  QuicRandom* random_;  // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CHAOS_PROTECTOR_H_
diff --git a/quiche/quic/core/quic_chaos_protector_test.cc b/quiche/quic/core/quic_chaos_protector_test.cc
new file mode 100644
index 0000000..2ea3cd2
--- /dev/null
+++ b/quiche/quic/core/quic_chaos_protector_test.cc
@@ -0,0 +1,230 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_chaos_protector.h"
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+
+namespace quic {
+namespace test {
+
+class QuicChaosProtectorTest : public QuicTestWithParam<ParsedQuicVersion>,
+                               public QuicStreamFrameDataProducer {
+ public:
+  QuicChaosProtectorTest()
+      : version_(GetParam()),
+        framer_({version_}, QuicTime::Zero(), Perspective::IS_CLIENT,
+                kQuicDefaultConnectionIdLength),
+        validation_framer_({version_}),
+        random_(/*base=*/3),
+        level_(ENCRYPTION_INITIAL),
+        crypto_offset_(0),
+        crypto_data_length_(100),
+        crypto_frame_(level_, crypto_offset_, crypto_data_length_),
+        num_padding_bytes_(50),
+        packet_size_(1000),
+        packet_buffer_(std::make_unique<char[]>(packet_size_)) {
+    ReCreateChaosProtector();
+  }
+
+  void ReCreateChaosProtector() {
+    chaos_protector_ = std::make_unique<QuicChaosProtector>(
+        crypto_frame_, num_padding_bytes_, packet_size_,
+        SetupHeaderAndFramers(), &random_);
+  }
+
+  // From QuicStreamFrameDataProducer.
+  WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
+                                        QuicStreamOffset /*offset*/,
+                                        QuicByteCount /*data_length*/,
+                                        QuicDataWriter* /*writer*/) override {
+    ADD_FAILURE() << "This should never be called";
+    return STREAM_MISSING;
+  }
+
+  // From QuicStreamFrameDataProducer.
+  bool WriteCryptoData(EncryptionLevel level,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override {
+    EXPECT_EQ(level, level);
+    EXPECT_EQ(offset, crypto_offset_);
+    EXPECT_EQ(data_length, crypto_data_length_);
+    for (QuicByteCount i = 0; i < data_length; i++) {
+      EXPECT_TRUE(writer->WriteUInt8(static_cast<uint8_t>(i & 0xFF)));
+    }
+    return true;
+  }
+
+ protected:
+  QuicFramer* SetupHeaderAndFramers() {
+    // Setup header.
+    header_.destination_connection_id = TestConnectionId();
+    header_.destination_connection_id_included = CONNECTION_ID_PRESENT;
+    header_.source_connection_id = EmptyQuicConnectionId();
+    header_.source_connection_id_included = CONNECTION_ID_PRESENT;
+    header_.reset_flag = false;
+    header_.version_flag = true;
+    header_.has_possible_stateless_reset_token = false;
+    header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+    header_.version = version_;
+    header_.packet_number = QuicPacketNumber(1);
+    header_.form = IETF_QUIC_LONG_HEADER_PACKET;
+    header_.long_packet_type = INITIAL;
+    header_.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header_.length_length = kQuicDefaultLongHeaderLengthLength;
+    // Setup validation framer.
+    validation_framer_.framer()->SetInitialObfuscators(
+        header_.destination_connection_id);
+    // Setup framer.
+    framer_.SetInitialObfuscators(header_.destination_connection_id);
+    framer_.set_data_producer(this);
+    return &framer_;
+  }
+
+  void BuildEncryptAndParse() {
+    absl::optional<size_t> length =
+        chaos_protector_->BuildDataPacket(header_, packet_buffer_.get());
+    ASSERT_TRUE(length.has_value());
+    ASSERT_GT(length.value(), 0u);
+    size_t encrypted_length = framer_.EncryptInPlace(
+        level_, header_.packet_number,
+        GetStartOfEncryptedData(framer_.transport_version(), header_),
+        length.value(), packet_size_, packet_buffer_.get());
+    ASSERT_GT(encrypted_length, 0u);
+    ASSERT_TRUE(validation_framer_.ProcessPacket(QuicEncryptedPacket(
+        absl::string_view(packet_buffer_.get(), encrypted_length))));
+  }
+
+  void ResetOffset(QuicStreamOffset offset) {
+    crypto_offset_ = offset;
+    crypto_frame_.offset = offset;
+    ReCreateChaosProtector();
+  }
+
+  void ResetLength(QuicByteCount length) {
+    crypto_data_length_ = length;
+    crypto_frame_.data_length = length;
+    ReCreateChaosProtector();
+  }
+
+  ParsedQuicVersion version_;
+  QuicPacketHeader header_;
+  QuicFramer framer_;
+  SimpleQuicFramer validation_framer_;
+  MockRandom random_;
+  EncryptionLevel level_;
+  QuicStreamOffset crypto_offset_;
+  QuicByteCount crypto_data_length_;
+  QuicCryptoFrame crypto_frame_;
+  int num_padding_bytes_;
+  size_t packet_size_;
+  std::unique_ptr<char[]> packet_buffer_;
+  std::unique_ptr<QuicChaosProtector> chaos_protector_;
+};
+
+namespace {
+
+ParsedQuicVersionVector TestVersions() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.UsesCryptoFrames()) {
+      versions.push_back(version);
+    }
+  }
+  return versions;
+}
+
+INSTANTIATE_TEST_SUITE_P(QuicChaosProtectorTests,
+                         QuicChaosProtectorTest,
+                         ::testing::ValuesIn(TestVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicChaosProtectorTest, Main) {
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, 0u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
+  EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
+}
+
+TEST_P(QuicChaosProtectorTest, DifferentRandom) {
+  random_.ResetBase(4);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 4u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 8u);
+}
+
+TEST_P(QuicChaosProtectorTest, RandomnessZero) {
+  random_.ResetBase(0);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
+            crypto_data_length_);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
+}
+
+TEST_P(QuicChaosProtectorTest, Offset) {
+  ResetOffset(123);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 4u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 1u);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 3u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 7u);
+  EXPECT_EQ(validation_framer_.padding_frames()[0].num_padding_bytes, 3);
+}
+
+TEST_P(QuicChaosProtectorTest, OffsetAndRandomnessZero) {
+  ResetOffset(123);
+  random_.ResetBase(0);
+  BuildEncryptAndParse();
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 1u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length,
+            crypto_data_length_);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
+  ASSERT_EQ(validation_framer_.padding_frames().size(), 1u);
+}
+
+TEST_P(QuicChaosProtectorTest, ZeroRemainingBytesAfterSplit) {
+  QuicPacketLength new_length = 63;
+  num_padding_bytes_ = QuicFramer::GetMinCryptoFrameSize(
+      crypto_frame_.offset + new_length, new_length);
+  ResetLength(new_length);
+  BuildEncryptAndParse();
+
+  ASSERT_EQ(validation_framer_.crypto_frames().size(), 2u);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->offset, crypto_offset_);
+  EXPECT_EQ(validation_framer_.crypto_frames()[0]->data_length, 4);
+  EXPECT_EQ(validation_framer_.crypto_frames()[1]->offset, crypto_offset_ + 4);
+  EXPECT_EQ(validation_framer_.crypto_frames()[1]->data_length,
+            crypto_data_length_ - 4);
+  ASSERT_EQ(validation_framer_.ping_frames().size(), 0u);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_clock.cc b/quiche/quic/core/quic_clock.cc
new file mode 100644
index 0000000..94ca72f
--- /dev/null
+++ b/quiche/quic/core/quic_clock.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_clock.h"
+
+#include <limits>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicClock::QuicClock()
+    : is_calibrated_(false), calibration_offset_(QuicTime::Delta::Zero()) {}
+
+QuicClock::~QuicClock() {}
+
+QuicTime::Delta QuicClock::ComputeCalibrationOffset() const {
+  // In the ideal world, all we need to do is to return the difference of
+  // WallNow() and Now(). In the real world, things like context switch may
+  // happen between the calls to WallNow() and Now(), causing their difference
+  // to be arbitrarily large, so we repeat the calculation many times and use
+  // the one with the minimum difference as the true offset.
+  int64_t min_offset_us = std::numeric_limits<int64_t>::max();
+
+  for (int i = 0; i < 128; ++i) {
+    int64_t now_in_us = (Now() - QuicTime::Zero()).ToMicroseconds();
+    int64_t wallnow_in_us =
+        static_cast<int64_t>(WallNow().ToUNIXMicroseconds());
+
+    int64_t offset_us = wallnow_in_us - now_in_us;
+    if (offset_us < min_offset_us) {
+      min_offset_us = offset_us;
+    }
+  }
+
+  return QuicTime::Delta::FromMicroseconds(min_offset_us);
+}
+
+void QuicClock::SetCalibrationOffset(QuicTime::Delta offset) {
+  QUICHE_DCHECK(!is_calibrated_) << "A clock should only be calibrated once";
+  calibration_offset_ = offset;
+  is_calibrated_ = true;
+}
+
+QuicTime QuicClock::ConvertWallTimeToQuicTime(
+    const QuicWallTime& walltime) const {
+  if (is_calibrated_) {
+    int64_t time_in_us = static_cast<int64_t>(walltime.ToUNIXMicroseconds()) -
+                         calibration_offset_.ToMicroseconds();
+    return QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(time_in_us);
+  }
+
+  //     ..........................
+  //     |            |           |
+  // unix epoch   |walltime|   WallNow()
+  //     ..........................
+  //            |     |           |
+  //     clock epoch  |         Now()
+  //               result
+  //
+  // result = Now() - (WallNow() - walltime)
+  return Now() - QuicTime::Delta::FromMicroseconds(
+                     WallNow()
+                         .Subtract(QuicTime::Delta::FromMicroseconds(
+                             walltime.ToUNIXMicroseconds()))
+                         .ToUNIXMicroseconds());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_clock.h b/quiche/quic/core/quic_clock.h
new file mode 100644
index 0000000..f128f9e
--- /dev/null
+++ b/quiche/quic/core/quic_clock.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CLOCK_H_
+#define QUICHE_QUIC_CORE_QUIC_CLOCK_H_
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+/* API_DESCRIPTION
+ QuicClock is used by QUIC core to get current time. Its instance is created by
+ applications and passed into QuicDispatcher and QuicConnectionHelperInterface.
+ API-DESCRIPTION */
+
+namespace quic {
+
+// Interface for retrieving the current time.
+class QUIC_EXPORT_PRIVATE QuicClock {
+ public:
+  QuicClock();
+  virtual ~QuicClock();
+
+  QuicClock(const QuicClock&) = delete;
+  QuicClock& operator=(const QuicClock&) = delete;
+
+  // Compute the offset between this clock with the Unix Epoch clock.
+  // Return the calibrated offset between WallNow() and Now(), in the form of
+  // (wallnow_in_us - now_in_us).
+  // The return value can be used by SetCalibrationOffset() to actually
+  // calibrate the clock, or all instances of this clock type.
+  QuicTime::Delta ComputeCalibrationOffset() const;
+
+  // Calibrate this clock. A calibrated clock guarantees that the
+  // ConvertWallTimeToQuicTime() function always return the same result for the
+  // same walltime.
+  // Should not be called more than once for each QuicClock.
+  void SetCalibrationOffset(QuicTime::Delta offset);
+
+  // Returns the approximate current time as a QuicTime object.
+  virtual QuicTime ApproximateNow() const = 0;
+
+  // Returns the current time as a QuicTime object.
+  // Note: this use significant resources please use only if needed.
+  virtual QuicTime Now() const = 0;
+
+  // WallNow returns the current wall-time - a time that is consistent across
+  // different clocks.
+  virtual QuicWallTime WallNow() const = 0;
+
+  // Converts |walltime| to a QuicTime relative to this clock's epoch.
+  virtual QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const;
+
+ protected:
+  // Creates a new QuicTime using |time_us| as the internal value.
+  QuicTime CreateTimeFromMicroseconds(uint64_t time_us) const {
+    return QuicTime(time_us);
+  }
+
+ private:
+  // True if |calibration_offset_| is valid.
+  bool is_calibrated_;
+  // If |is_calibrated_|, |calibration_offset_| is the (fixed) offset between
+  // the Unix Epoch clock and this clock.
+  // In other words, the offset between WallNow() and Now().
+  QuicTime::Delta calibration_offset_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CLOCK_H_
diff --git a/quiche/quic/core/quic_coalesced_packet.cc b/quiche/quic/core/quic_coalesced_packet.cc
new file mode 100644
index 0000000..1983b2c
--- /dev/null
+++ b/quiche/quic/core/quic_coalesced_packet.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_coalesced_packet.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicCoalescedPacket::QuicCoalescedPacket()
+    : length_(0), max_packet_length_(0) {}
+
+QuicCoalescedPacket::~QuicCoalescedPacket() {
+  Clear();
+}
+
+bool QuicCoalescedPacket::MaybeCoalescePacket(
+    const SerializedPacket& packet, const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    quiche::QuicheBufferAllocator* allocator,
+    QuicPacketLength current_max_packet_length) {
+  if (packet.encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10611_1) << "Trying to coalesce an empty packet";
+    return true;
+  }
+  if (length_ == 0) {
+#ifndef NDEBUG
+    for (const auto& buffer : encrypted_buffers_) {
+      QUICHE_DCHECK(buffer.empty());
+    }
+#endif
+    QUICHE_DCHECK(initial_packet_ == nullptr);
+    // This is the first packet, set max_packet_length and self/peer
+    // addresses.
+    max_packet_length_ = current_max_packet_length;
+    self_address_ = self_address;
+    peer_address_ = peer_address;
+  } else {
+    if (self_address_ != self_address || peer_address_ != peer_address) {
+      // Do not coalesce packet with different self/peer addresses.
+      QUIC_DLOG(INFO)
+          << "Cannot coalesce packet because self/peer address changed";
+      return false;
+    }
+    if (max_packet_length_ != current_max_packet_length) {
+      QUIC_BUG(quic_bug_10611_2)
+          << "Max packet length changes in the middle of the write path";
+      return false;
+    }
+    if (ContainsPacketOfEncryptionLevel(packet.encryption_level)) {
+      // Do not coalesce packets of the same encryption level.
+      return false;
+    }
+  }
+
+  if (length_ + packet.encrypted_length > max_packet_length_) {
+    // Packet does not fit.
+    return false;
+  }
+  QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
+                << packet.encryption_level
+                << ", encrypted_length: " << packet.encrypted_length
+                << ", current length: " << length_
+                << ", max_packet_length: " << max_packet_length_;
+  if (length_ > 0) {
+    QUIC_CODE_COUNT(QUIC_SUCCESSFULLY_COALESCED_MULTIPLE_PACKETS);
+  }
+  length_ += packet.encrypted_length;
+  transmission_types_[packet.encryption_level] = packet.transmission_type;
+  if (packet.encryption_level == ENCRYPTION_INITIAL) {
+    // Save a copy of ENCRYPTION_INITIAL packet (excluding encrypted buffer, as
+    // the packet will be re-serialized later).
+    initial_packet_ = absl::WrapUnique<SerializedPacket>(
+        CopySerializedPacket(packet, allocator, /*copy_buffer=*/false));
+    return true;
+  }
+  // Copy encrypted buffer of packets with other encryption levels.
+  encrypted_buffers_[packet.encryption_level] =
+      std::string(packet.encrypted_buffer, packet.encrypted_length);
+  return true;
+}
+
+void QuicCoalescedPacket::Clear() {
+  self_address_ = QuicSocketAddress();
+  peer_address_ = QuicSocketAddress();
+  length_ = 0;
+  max_packet_length_ = 0;
+  for (auto& packet : encrypted_buffers_) {
+    packet.clear();
+  }
+  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    transmission_types_[i] = NOT_RETRANSMISSION;
+  }
+  initial_packet_ = nullptr;
+}
+
+void QuicCoalescedPacket::NeuterInitialPacket() {
+  if (initial_packet_ == nullptr) {
+    return;
+  }
+  if (length_ < initial_packet_->encrypted_length) {
+    QUIC_BUG(quic_bug_10611_3)
+        << "length_: " << length_ << ", is less than initial packet length: "
+        << initial_packet_->encrypted_length;
+    Clear();
+    return;
+  }
+  length_ -= initial_packet_->encrypted_length;
+  if (length_ == 0) {
+    Clear();
+    return;
+  }
+  transmission_types_[ENCRYPTION_INITIAL] = NOT_RETRANSMISSION;
+  initial_packet_ = nullptr;
+}
+
+bool QuicCoalescedPacket::CopyEncryptedBuffers(char* buffer,
+                                               size_t buffer_len,
+                                               size_t* length_copied) const {
+  *length_copied = 0;
+  for (const auto& packet : encrypted_buffers_) {
+    if (packet.empty()) {
+      continue;
+    }
+    if (packet.length() > buffer_len) {
+      return false;
+    }
+    memcpy(buffer, packet.data(), packet.length());
+    buffer += packet.length();
+    buffer_len -= packet.length();
+    *length_copied += packet.length();
+  }
+  return true;
+}
+
+bool QuicCoalescedPacket::ContainsPacketOfEncryptionLevel(
+    EncryptionLevel level) const {
+  return !encrypted_buffers_[level].empty() ||
+         (level == ENCRYPTION_INITIAL && initial_packet_ != nullptr);
+}
+
+TransmissionType QuicCoalescedPacket::TransmissionTypeOfPacket(
+    EncryptionLevel level) const {
+  if (!ContainsPacketOfEncryptionLevel(level)) {
+    QUIC_BUG(quic_bug_10611_4)
+        << "Coalesced packet does not contain packet of encryption level: "
+        << EncryptionLevelToString(level);
+    return NOT_RETRANSMISSION;
+  }
+  return transmission_types_[level];
+}
+
+size_t QuicCoalescedPacket::NumberOfPackets() const {
+  size_t num_of_packets = 0;
+  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
+      ++num_of_packets;
+    }
+  }
+  return num_of_packets;
+}
+
+std::string QuicCoalescedPacket::ToString(size_t serialized_length) const {
+  // Total length and padding size.
+  std::string info = absl::StrCat(
+      "total_length: ", serialized_length,
+      " padding_size: ", serialized_length - length_, " packets: {");
+  // Packets' encryption levels.
+  bool first_packet = true;
+  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
+      absl::StrAppend(&info, first_packet ? "" : ", ",
+                      EncryptionLevelToString(static_cast<EncryptionLevel>(i)));
+      first_packet = false;
+    }
+  }
+  absl::StrAppend(&info, "}");
+  return info;
+}
+
+std::vector<size_t> QuicCoalescedPacket::packet_lengths() const {
+  std::vector<size_t> lengths;
+  for (const auto& packet : encrypted_buffers_) {
+    if (lengths.empty()) {
+      lengths.push_back(
+          initial_packet_ == nullptr ? 0 : initial_packet_->encrypted_length);
+    } else {
+      lengths.push_back(packet.length());
+    }
+  }
+  return lengths;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_coalesced_packet.h b/quiche/quic/core/quic_coalesced_packet.h
new file mode 100644
index 0000000..364d3aa
--- /dev/null
+++ b/quiche/quic/core/quic_coalesced_packet.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
+#define QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+namespace test {
+class QuicCoalescedPacketPeer;
+}
+
+// QuicCoalescedPacket is used to buffer multiple packets which can be coalesced
+// into the same UDP datagram.
+class QUIC_EXPORT_PRIVATE QuicCoalescedPacket {
+ public:
+  QuicCoalescedPacket();
+  ~QuicCoalescedPacket();
+
+  // Returns true if |packet| is successfully coalesced with existing packets.
+  // Returns false otherwise.
+  bool MaybeCoalescePacket(const SerializedPacket& packet,
+                           const QuicSocketAddress& self_address,
+                           const QuicSocketAddress& peer_address,
+                           quiche::QuicheBufferAllocator* allocator,
+                           QuicPacketLength current_max_packet_length);
+
+  // Clears this coalesced packet.
+  void Clear();
+
+  // Clears all state associated with initial_packet_.
+  void NeuterInitialPacket();
+
+  // Copies encrypted_buffers_ to |buffer| and sets |length_copied| to the
+  // copied amount. Returns false if copy fails (i.e., |buffer_len| is not
+  // enough).
+  bool CopyEncryptedBuffers(char* buffer,
+                            size_t buffer_len,
+                            size_t* length_copied) const;
+
+  std::string ToString(size_t serialized_length) const;
+
+  // Returns true if this coalesced packet contains packet of |level|.
+  bool ContainsPacketOfEncryptionLevel(EncryptionLevel level) const;
+
+  // Returns transmission type of packet of |level|. This should only be called
+  // when this coalesced packet contains packet of |level|.
+  TransmissionType TransmissionTypeOfPacket(EncryptionLevel level) const;
+
+  // Returns number of packets contained in this coalesced packet.
+  size_t NumberOfPackets() const;
+
+  const SerializedPacket* initial_packet() const {
+    return initial_packet_.get();
+  }
+
+  const QuicSocketAddress& self_address() const { return self_address_; }
+
+  const QuicSocketAddress& peer_address() const { return peer_address_; }
+
+  QuicPacketLength length() const { return length_; }
+
+  QuicPacketLength max_packet_length() const { return max_packet_length_; }
+
+  std::vector<size_t> packet_lengths() const;
+
+ private:
+  friend class test::QuicCoalescedPacketPeer;
+
+  // self/peer addresses are set when trying to coalesce the first packet.
+  // Packets with different self/peer addresses cannot be coalesced.
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  // Length of this coalesced packet.
+  QuicPacketLength length_;
+  // Max packet length. Do not try to coalesce packet when max packet length
+  // changes (e.g., with MTU discovery).
+  QuicPacketLength max_packet_length_;
+  // Copies of packets' encrypted buffers according to different encryption
+  // levels.
+  std::string encrypted_buffers_[NUM_ENCRYPTION_LEVELS];
+  // Recorded transmission type according to different encryption levels.
+  TransmissionType transmission_types_[NUM_ENCRYPTION_LEVELS];
+
+  // A copy of ENCRYPTION_INITIAL packet if this coalesced packet contains one.
+  // Null otherwise. Please note, the encrypted_buffer field is not copied. The
+  // frames are copied to allow it be re-serialized when this coalesced packet
+  // gets sent.
+  std::unique_ptr<SerializedPacket> initial_packet_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_COALESCED_PACKET_H_
diff --git a/quiche/quic/core/quic_coalesced_packet_test.cc b/quiche/quic/core/quic_coalesced_packet_test.cc
new file mode 100644
index 0000000..eb69372
--- /dev/null
+++ b/quiche/quic/core/quic_coalesced_packet_test.cc
@@ -0,0 +1,213 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_coalesced_packet.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(QuicCoalescedPacketTest, MaybeCoalescePacket) {
+  QuicCoalescedPacket coalesced;
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+  quiche::SimpleBufferAllocator allocator;
+  EXPECT_EQ(0u, coalesced.length());
+  EXPECT_EQ(0u, coalesced.NumberOfPackets());
+  char buffer[1000];
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet1.transmission_type = PTO_RETRANSMISSION;
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
+  packet1.retransmittable_frames.push_back(
+      QuicFrame(QuicStreamFrame(1, true, 0, 100)));
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(PTO_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(500u, coalesced.length());
+  EXPECT_EQ(1u, coalesced.NumberOfPackets());
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
+      coalesced.ToString(1500));
+
+  // Cannot coalesce packet of the same encryption level.
+  SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet2, self_address,
+                                             peer_address, &allocator, 1500));
+
+  SerializedPacket packet3(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet3.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  packet3.encryption_level = ENCRYPTION_ZERO_RTT;
+  packet3.transmission_type = LOSS_RETRANSMISSION;
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(2u, coalesced.NumberOfPackets());
+  EXPECT_EQ(LOSS_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
+      "ENCRYPTION_ZERO_RTT}",
+      coalesced.ToString(1500));
+
+  SerializedPacket packet4(QuicPacketNumber(4), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  // Cannot coalesce packet of changed self/peer address.
+  EXPECT_FALSE(coalesced.MaybeCoalescePacket(
+      packet4, QuicSocketAddress(QuicIpAddress::Loopback4(), 3), peer_address,
+      &allocator, 1500));
+
+  // Packet does not fit.
+  SerializedPacket packet5(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 501, false, false);
+  packet5.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  EXPECT_FALSE(coalesced.MaybeCoalescePacket(packet5, self_address,
+                                             peer_address, &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(2u, coalesced.NumberOfPackets());
+
+  // Max packet number length changed.
+  SerializedPacket packet6(QuicPacketNumber(6), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 100, false, false);
+  packet6.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  EXPECT_QUIC_BUG(coalesced.MaybeCoalescePacket(packet6, self_address,
+                                                peer_address, &allocator, 1000),
+                  "Max packet length changes in the middle of the write path");
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(2u, coalesced.NumberOfPackets());
+}
+
+TEST(QuicCoalescedPacketTest, CopyEncryptedBuffers) {
+  QuicCoalescedPacket coalesced;
+  quiche::SimpleBufferAllocator allocator;
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  std::string buffer(500, 'a');
+  std::string buffer2(500, 'b');
+  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer.data(), 500,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false);
+  packet1.encryption_level = ENCRYPTION_ZERO_RTT;
+  SerializedPacket packet2(QuicPacketNumber(2), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer2.data(), 500,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false);
+  packet2.encryption_level = ENCRYPTION_FORWARD_SECURE;
+
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1000u, coalesced.length());
+
+  char copy_buffer[1000];
+  size_t length_copied = 0;
+  EXPECT_FALSE(
+      coalesced.CopyEncryptedBuffers(copy_buffer, 900, &length_copied));
+  ASSERT_TRUE(
+      coalesced.CopyEncryptedBuffers(copy_buffer, 1000, &length_copied));
+  EXPECT_EQ(1000u, length_copied);
+  char expected[1000];
+  memset(expected, 'a', 500);
+  memset(expected + 500, 'b', 500);
+  quiche::test::CompareCharArraysWithHexError("copied buffers", copy_buffer,
+                                              length_copied, expected, 1000);
+}
+
+TEST(QuicCoalescedPacketTest, NeuterInitialPacket) {
+  QuicCoalescedPacket coalesced;
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+  // Noop when neutering initial packet on a empty coalescer.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+
+  quiche::SimpleBufferAllocator allocator;
+  EXPECT_EQ(0u, coalesced.length());
+  char buffer[1000];
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  SerializedPacket packet1(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet1.transmission_type = PTO_RETRANSMISSION;
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  packet1.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
+  packet1.retransmittable_frames.push_back(
+      QuicFrame(QuicStreamFrame(1, true, 0, 100)));
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(PTO_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_INITIAL));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(500u, coalesced.length());
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_INITIAL}",
+      coalesced.ToString(1500));
+  // Neuter initial packet.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ(0u, coalesced.max_packet_length());
+  EXPECT_EQ(0u, coalesced.length());
+  EXPECT_EQ("total_length: 0 padding_size: 0 packets: {}",
+            coalesced.ToString(0));
+
+  // Coalesce initial packet again.
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet1, self_address, peer_address,
+                                            &allocator, 1500));
+
+  SerializedPacket packet2(QuicPacketNumber(3), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 500, false, false);
+  packet2.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  packet2.encryption_level = ENCRYPTION_ZERO_RTT;
+  packet2.transmission_type = LOSS_RETRANSMISSION;
+  ASSERT_TRUE(coalesced.MaybeCoalescePacket(packet2, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1000u, coalesced.length());
+  EXPECT_EQ(LOSS_RETRANSMISSION,
+            coalesced.TransmissionTypeOfPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 500 packets: {ENCRYPTION_INITIAL, "
+      "ENCRYPTION_ZERO_RTT}",
+      coalesced.ToString(1500));
+
+  // Neuter initial packet.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(500u, coalesced.length());
+  EXPECT_EQ(
+      "total_length: 1500 padding_size: 1000 packets: {ENCRYPTION_ZERO_RTT}",
+      coalesced.ToString(1500));
+
+  SerializedPacket packet3(QuicPacketNumber(5), PACKET_4BYTE_PACKET_NUMBER,
+                           buffer, 501, false, false);
+  packet3.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  EXPECT_TRUE(coalesced.MaybeCoalescePacket(packet3, self_address, peer_address,
+                                            &allocator, 1500));
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1001u, coalesced.length());
+  // Neuter initial packet.
+  coalesced.NeuterInitialPacket();
+  EXPECT_EQ(1500u, coalesced.max_packet_length());
+  EXPECT_EQ(1001u, coalesced.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_config.cc b/quiche/quic/core/quic_config.cc
new file mode 100644
index 0000000..d6f2acd
--- /dev/null
+++ b/quiche/quic/core/quic_config.cc
@@ -0,0 +1,1424 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_config.h"
+
+#include <algorithm>
+#include <cstring>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Reads the value corresponding to |name_| from |msg| into |out|. If the
+// |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
+// to |default_value|.
+QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
+                         QuicTag tag,
+                         QuicConfigPresence presence,
+                         uint32_t default_value,
+                         uint32_t* out,
+                         std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  QuicErrorCode error = msg.GetUint32(tag, out);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence == PRESENCE_REQUIRED) {
+        *error_details = "Missing " + QuicTagToString(tag);
+        break;
+      }
+      error = QUIC_NO_ERROR;
+      *out = default_value;
+      break;
+    case QUIC_NO_ERROR:
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag);
+      break;
+  }
+  return error;
+}
+
+QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
+    : tag_(tag), presence_(presence) {}
+QuicConfigValue::~QuicConfigValue() {}
+
+QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
+    : QuicConfigValue(tag, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+QuicFixedUint32::~QuicFixedUint32() {}
+
+bool QuicFixedUint32::HasSendValue() const {
+  return has_send_value_;
+}
+
+uint32_t QuicFixedUint32::GetSendValue() const {
+  QUIC_BUG_IF(quic_bug_12743_1, !has_send_value_)
+      << "No send value to get for tag:" << QuicTagToString(tag_);
+  return send_value_;
+}
+
+void QuicFixedUint32::SetSendValue(uint32_t value) {
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedUint32::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+uint32_t QuicFixedUint32::GetReceivedValue() const {
+  QUIC_BUG_IF(quic_bug_12743_2, !has_receive_value_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_value_;
+}
+
+void QuicFixedUint32::SetReceivedValue(uint32_t value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+  if (tag_ == 0) {
+    QUIC_BUG(quic_bug_12743_3)
+        << "This parameter does not support writing to CryptoHandshakeMessage";
+    return;
+  }
+  if (has_send_value_) {
+    out->SetValue(tag_, send_value_);
+  }
+}
+
+QuicErrorCode QuicFixedUint32::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  if (tag_ == 0) {
+    *error_details =
+        "This parameter does not support reading from CryptoHandshakeMessage";
+    QUIC_BUG(quic_bug_10575_1) << *error_details;
+    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+  }
+  QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      has_receive_value_ = true;
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
+    : QuicConfigValue(name, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+
+QuicFixedUint62::~QuicFixedUint62() {}
+
+bool QuicFixedUint62::HasSendValue() const {
+  return has_send_value_;
+}
+
+uint64_t QuicFixedUint62::GetSendValue() const {
+  if (!has_send_value_) {
+    QUIC_BUG(quic_bug_10575_2)
+        << "No send value to get for tag:" << QuicTagToString(tag_);
+    return 0;
+  }
+  return send_value_;
+}
+
+void QuicFixedUint62::SetSendValue(uint64_t value) {
+  if (value > kVarInt62MaxValue) {
+    QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
+    value = kVarInt62MaxValue;
+  }
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedUint62::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+uint64_t QuicFixedUint62::GetReceivedValue() const {
+  if (!has_receive_value_) {
+    QUIC_BUG(quic_bug_10575_4)
+        << "No receive value to get for tag:" << QuicTagToString(tag_);
+    return 0;
+  }
+  return receive_value_;
+}
+
+void QuicFixedUint62::SetReceivedValue(uint64_t value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+  if (!has_send_value_) {
+    return;
+  }
+  uint32_t send_value32;
+  if (send_value_ > std::numeric_limits<uint32_t>::max()) {
+    QUIC_BUG(quic_bug_10575_5) << "Attempting to send " << send_value_
+                               << " for tag:" << QuicTagToString(tag_);
+    send_value32 = std::numeric_limits<uint32_t>::max();
+  } else {
+    send_value32 = static_cast<uint32_t>(send_value_);
+  }
+  out->SetValue(tag_, send_value32);
+}
+
+QuicErrorCode QuicFixedUint62::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  uint32_t receive_value32;
+  QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
+  // GetUint32 is guaranteed to always initialize receive_value32.
+  receive_value_ = receive_value32;
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      has_receive_value_ = true;
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedStatelessResetToken::QuicFixedStatelessResetToken(
+    QuicTag tag,
+    QuicConfigPresence presence)
+    : QuicConfigValue(tag, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+QuicFixedStatelessResetToken::~QuicFixedStatelessResetToken() {}
+
+bool QuicFixedStatelessResetToken::HasSendValue() const {
+  return has_send_value_;
+}
+
+const StatelessResetToken& QuicFixedStatelessResetToken::GetSendValue() const {
+  QUIC_BUG_IF(quic_bug_12743_4, !has_send_value_)
+      << "No send value to get for tag:" << QuicTagToString(tag_);
+  return send_value_;
+}
+
+void QuicFixedStatelessResetToken::SetSendValue(
+    const StatelessResetToken& value) {
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedStatelessResetToken::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+const StatelessResetToken& QuicFixedStatelessResetToken::GetReceivedValue()
+    const {
+  QUIC_BUG_IF(quic_bug_12743_5, !has_receive_value_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_value_;
+}
+
+void QuicFixedStatelessResetToken::SetReceivedValue(
+    const StatelessResetToken& value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedStatelessResetToken::ToHandshakeMessage(
+    CryptoHandshakeMessage* out) const {
+  if (has_send_value_) {
+    out->SetValue(tag_, send_value_);
+  }
+}
+
+QuicErrorCode QuicFixedStatelessResetToken::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  QuicErrorCode error =
+      peer_hello.GetStatelessResetToken(tag_, &receive_value_);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      has_receive_value_ = true;
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
+                                       QuicConfigPresence presence)
+    : QuicConfigValue(name, presence),
+      has_send_values_(false),
+      has_receive_values_(false) {}
+
+QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
+    default;
+
+QuicFixedTagVector::~QuicFixedTagVector() {}
+
+bool QuicFixedTagVector::HasSendValues() const {
+  return has_send_values_;
+}
+
+const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
+  QUIC_BUG_IF(quic_bug_12743_6, !has_send_values_)
+      << "No send values to get for tag:" << QuicTagToString(tag_);
+  return send_values_;
+}
+
+void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
+  has_send_values_ = true;
+  send_values_ = values;
+}
+
+bool QuicFixedTagVector::HasReceivedValues() const {
+  return has_receive_values_;
+}
+
+const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
+  QUIC_BUG_IF(quic_bug_12743_7, !has_receive_values_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_values_;
+}
+
+void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
+  has_receive_values_ = true;
+  receive_values_ = values;
+}
+
+void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
+  if (has_send_values_) {
+    out->SetVector(tag_, send_values_);
+  }
+}
+
+QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+  QuicTagVector values;
+  QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
+  switch (error) {
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      if (presence_ == PRESENCE_OPTIONAL) {
+        return QUIC_NO_ERROR;
+      }
+      *error_details = "Missing " + QuicTagToString(tag_);
+      break;
+    case QUIC_NO_ERROR:
+      QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
+      has_receive_values_ = true;
+      receive_values_.insert(receive_values_.end(), values.begin(),
+                             values.end());
+      break;
+    default:
+      *error_details = "Bad " + QuicTagToString(tag_);
+      break;
+  }
+  return error;
+}
+
+QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
+                                               QuicConfigPresence presence)
+    : QuicConfigValue(tag, presence),
+      has_send_value_(false),
+      has_receive_value_(false) {}
+
+QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
+
+bool QuicFixedSocketAddress::HasSendValue() const {
+  return has_send_value_;
+}
+
+const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
+  QUIC_BUG_IF(quic_bug_12743_8, !has_send_value_)
+      << "No send value to get for tag:" << QuicTagToString(tag_);
+  return send_value_;
+}
+
+void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
+  has_send_value_ = true;
+  send_value_ = value;
+}
+
+bool QuicFixedSocketAddress::HasReceivedValue() const {
+  return has_receive_value_;
+}
+
+const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
+  QUIC_BUG_IF(quic_bug_12743_9, !has_receive_value_)
+      << "No receive value to get for tag:" << QuicTagToString(tag_);
+  return receive_value_;
+}
+
+void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
+  has_receive_value_ = true;
+  receive_value_ = value;
+}
+
+void QuicFixedSocketAddress::ToHandshakeMessage(
+    CryptoHandshakeMessage* out) const {
+  if (has_send_value_) {
+    QuicSocketAddressCoder address_coder(send_value_);
+    out->SetStringPiece(tag_, address_coder.Encode());
+  }
+}
+
+QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType /*hello_type*/,
+    std::string* error_details) {
+  absl::string_view address;
+  if (!peer_hello.GetStringPiece(tag_, &address)) {
+    if (presence_ == PRESENCE_REQUIRED) {
+      *error_details = "Missing " + QuicTagToString(tag_);
+      return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
+    }
+  } else {
+    QuicSocketAddressCoder address_coder;
+    if (address_coder.Decode(address.data(), address.length())) {
+      SetReceivedValue(
+          QuicSocketAddress(address_coder.ip(), address_coder.port()));
+    }
+  }
+  return QUIC_NO_ERROR;
+}
+
+QuicConfig::QuicConfig()
+    : negotiated_(false),
+      max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
+      max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
+      max_undecryptable_packets_(0),
+      connection_options_(kCOPT, PRESENCE_OPTIONAL),
+      client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
+      max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
+      max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
+      max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
+      bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
+      initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
+      initial_max_stream_data_bytes_incoming_bidirectional_(0,
+                                                            PRESENCE_OPTIONAL),
+      initial_max_stream_data_bytes_outgoing_bidirectional_(0,
+                                                            PRESENCE_OPTIONAL),
+      initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
+      initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
+      initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
+      connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
+      alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
+      alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
+      stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
+      max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
+      min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
+      ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
+      max_udp_payload_size_(0, PRESENCE_OPTIONAL),
+      max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
+      active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
+  SetDefaults();
+}
+
+QuicConfig::QuicConfig(const QuicConfig& other) = default;
+
+QuicConfig::~QuicConfig() {}
+
+bool QuicConfig::SetInitialReceivedConnectionOptions(
+    const QuicTagVector& tags) {
+  if (HasReceivedConnectionOptions()) {
+    // If we have already received connection options (via handshake or due to
+    // a previous call), don't re-initialize.
+    return false;
+  }
+  connection_options_.SetReceivedValues(tags);
+  return true;
+}
+
+void QuicConfig::SetConnectionOptionsToSend(
+    const QuicTagVector& connection_options) {
+  connection_options_.SetSendValues(connection_options);
+}
+
+bool QuicConfig::HasReceivedConnectionOptions() const {
+  return connection_options_.HasReceivedValues();
+}
+
+const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
+  return connection_options_.GetReceivedValues();
+}
+
+bool QuicConfig::HasSendConnectionOptions() const {
+  return connection_options_.HasSendValues();
+}
+
+const QuicTagVector& QuicConfig::SendConnectionOptions() const {
+  return connection_options_.GetSendValues();
+}
+
+bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
+                                               Perspective perspective) const {
+  if (perspective == Perspective::IS_SERVER) {
+    if (HasReceivedConnectionOptions() &&
+        ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
+      return true;
+    }
+  } else if (HasSendConnectionOptions() &&
+             ContainsQuicTag(SendConnectionOptions(), tag)) {
+    return true;
+  }
+  return false;
+}
+
+void QuicConfig::SetClientConnectionOptions(
+    const QuicTagVector& client_connection_options) {
+  client_connection_options_.SetSendValues(client_connection_options);
+}
+
+bool QuicConfig::HasClientRequestedIndependentOption(
+    QuicTag tag,
+    Perspective perspective) const {
+  if (perspective == Perspective::IS_SERVER) {
+    return (HasReceivedConnectionOptions() &&
+            ContainsQuicTag(ReceivedConnectionOptions(), tag));
+  }
+
+  return (client_connection_options_.HasSendValues() &&
+          ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
+}
+
+const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
+    Perspective perspective) const {
+  static const QuicTagVector* no_options = new QuicTagVector;
+  if (perspective == Perspective::IS_SERVER) {
+    return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
+                                          : *no_options;
+  }
+
+  return client_connection_options_.HasSendValues()
+             ? client_connection_options_.GetSendValues()
+             : *no_options;
+}
+
+void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
+  if (idle_network_timeout.ToMicroseconds() <= 0) {
+    QUIC_BUG(quic_bug_10575_6)
+        << "Invalid idle network timeout " << idle_network_timeout;
+    return;
+  }
+  max_idle_timeout_to_send_ = idle_network_timeout;
+}
+
+QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
+  // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
+  // received the peer's values. This is true in production code but not in all
+  // of our tests that use a fake QuicConfig.
+  if (!received_max_idle_timeout_.has_value()) {
+    return max_idle_timeout_to_send_;
+  }
+  return received_max_idle_timeout_.value();
+}
+
+void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
+  max_bidirectional_streams_.SetSendValue(max_streams);
+}
+
+uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
+  return max_bidirectional_streams_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
+  return max_bidirectional_streams_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
+  return max_bidirectional_streams_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
+  max_unidirectional_streams_.SetSendValue(max_streams);
+}
+
+uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
+  return max_unidirectional_streams_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
+  return max_unidirectional_streams_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
+  return max_unidirectional_streams_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
+  max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
+}
+
+uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
+  return max_ack_delay_ms_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxAckDelayMs() const {
+  return max_ack_delay_ms_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
+  return max_ack_delay_ms_.GetReceivedValue();
+}
+
+void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
+  min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
+}
+
+uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
+  return min_ack_delay_ms_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMinAckDelayMs() const {
+  return min_ack_delay_ms_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
+  return min_ack_delay_ms_.GetReceivedValue();
+}
+
+void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
+  ack_delay_exponent_.SetSendValue(exponent);
+}
+
+uint32_t QuicConfig::GetAckDelayExponentToSend() const {
+  return ack_delay_exponent_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedAckDelayExponent() const {
+  return ack_delay_exponent_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedAckDelayExponent() const {
+  return ack_delay_exponent_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
+  max_udp_payload_size_.SetSendValue(max_udp_payload_size);
+}
+
+uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
+  return max_udp_payload_size_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxPacketSize() const {
+  return max_udp_payload_size_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedMaxPacketSize() const {
+  return max_udp_payload_size_.GetReceivedValue();
+}
+
+void QuicConfig::SetMaxDatagramFrameSizeToSend(
+    uint64_t max_datagram_frame_size) {
+  max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
+}
+
+uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
+  return max_datagram_frame_size_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
+  return max_datagram_frame_size_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
+  return max_datagram_frame_size_.GetReceivedValue();
+}
+
+void QuicConfig::SetActiveConnectionIdLimitToSend(
+    uint64_t active_connection_id_limit) {
+  active_connection_id_limit_.SetSendValue(active_connection_id_limit);
+}
+
+uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
+  return active_connection_id_limit_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
+  return active_connection_id_limit_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
+  return active_connection_id_limit_.GetReceivedValue();
+}
+
+bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
+  return bytes_for_connection_id_.HasSendValue();
+}
+
+void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
+  bytes_for_connection_id_.SetSendValue(bytes);
+}
+
+bool QuicConfig::HasReceivedBytesForConnectionId() const {
+  return bytes_for_connection_id_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
+  return bytes_for_connection_id_.GetReceivedValue();
+}
+
+void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
+  initial_round_trip_time_us_.SetSendValue(rtt);
+}
+
+bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
+  return initial_round_trip_time_us_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
+  return initial_round_trip_time_us_.GetReceivedValue();
+}
+
+bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
+  return initial_round_trip_time_us_.HasSendValue();
+}
+
+uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
+  return initial_round_trip_time_us_.GetSendValue();
+}
+
+void QuicConfig::SetInitialStreamFlowControlWindowToSend(
+    uint64_t window_bytes) {
+  if (window_bytes < kMinimumFlowControlSendWindow) {
+    QUIC_BUG(quic_bug_10575_7)
+        << "Initial stream flow control receive window (" << window_bytes
+        << ") cannot be set lower than minimum ("
+        << kMinimumFlowControlSendWindow << ").";
+    window_bytes = kMinimumFlowControlSendWindow;
+  }
+  initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
+  return initial_stream_flow_control_window_bytes_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
+  return initial_stream_flow_control_window_bytes_.GetReceivedValue();
+}
+
+void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+    uint64_t window_bytes) {
+  initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
+      window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
+    const {
+  if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_incoming_bidirectional_
+      .HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_incoming_bidirectional_
+      .GetReceivedValue();
+}
+
+void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+    uint64_t window_bytes) {
+  initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
+      window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
+    const {
+  if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_outgoing_bidirectional_
+      .HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
+    const {
+  return initial_max_stream_data_bytes_outgoing_bidirectional_
+      .GetReceivedValue();
+}
+
+void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
+    uint64_t window_bytes) {
+  initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
+  if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
+  return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
+  return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
+}
+
+void QuicConfig::SetInitialSessionFlowControlWindowToSend(
+    uint64_t window_bytes) {
+  if (window_bytes < kMinimumFlowControlSendWindow) {
+    QUIC_BUG(quic_bug_10575_8)
+        << "Initial session flow control receive window (" << window_bytes
+        << ") cannot be set lower than default ("
+        << kMinimumFlowControlSendWindow << ").";
+    window_bytes = kMinimumFlowControlSendWindow;
+  }
+  initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
+}
+
+uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
+  return initial_session_flow_control_window_bytes_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
+  return initial_session_flow_control_window_bytes_.HasReceivedValue();
+}
+
+uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
+  return initial_session_flow_control_window_bytes_.GetReceivedValue();
+}
+
+void QuicConfig::SetDisableConnectionMigration() {
+  connection_migration_disabled_.SetSendValue(1);
+}
+
+bool QuicConfig::DisableConnectionMigration() const {
+  return connection_migration_disabled_.HasReceivedValue();
+}
+
+void QuicConfig::SetIPv6AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv6) {
+  if (!alternate_server_address_ipv6.host().IsIPv6()) {
+    QUIC_BUG(quic_bug_10575_9)
+        << "Cannot use SetIPv6AlternateServerAddressToSend with "
+        << alternate_server_address_ipv6;
+    return;
+  }
+  alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
+}
+
+void QuicConfig::SetIPv6AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv6,
+    const QuicConnectionId& connection_id,
+    const StatelessResetToken& stateless_reset_token) {
+  if (!alternate_server_address_ipv6.host().IsIPv6()) {
+    QUIC_BUG(quic_bug_10575_10)
+        << "Cannot use SetIPv6AlternateServerAddressToSend with "
+        << alternate_server_address_ipv6;
+    return;
+  }
+  alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
+  preferred_address_connection_id_and_token_ =
+      std::make_pair(connection_id, stateless_reset_token);
+}
+
+bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
+  return alternate_server_address_ipv6_.HasReceivedValue();
+}
+
+const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
+    const {
+  return alternate_server_address_ipv6_.GetReceivedValue();
+}
+
+void QuicConfig::SetIPv4AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv4) {
+  if (!alternate_server_address_ipv4.host().IsIPv4()) {
+    QUIC_BUG(quic_bug_10575_11)
+        << "Cannot use SetIPv4AlternateServerAddressToSend with "
+        << alternate_server_address_ipv4;
+    return;
+  }
+  alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
+}
+
+void QuicConfig::SetIPv4AlternateServerAddressToSend(
+    const QuicSocketAddress& alternate_server_address_ipv4,
+    const QuicConnectionId& connection_id,
+    const StatelessResetToken& stateless_reset_token) {
+  if (!alternate_server_address_ipv4.host().IsIPv4()) {
+    QUIC_BUG(quic_bug_10575_12)
+        << "Cannot use SetIPv4AlternateServerAddressToSend with "
+        << alternate_server_address_ipv4;
+    return;
+  }
+  alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
+  preferred_address_connection_id_and_token_ =
+      std::make_pair(connection_id, stateless_reset_token);
+}
+
+bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
+  return alternate_server_address_ipv4_.HasReceivedValue();
+}
+
+const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
+    const {
+  return alternate_server_address_ipv4_.GetReceivedValue();
+}
+
+bool QuicConfig::HasReceivedPreferredAddressConnectionIdAndToken() const {
+  return (HasReceivedIPv6AlternateServerAddress() ||
+          HasReceivedIPv4AlternateServerAddress()) &&
+         preferred_address_connection_id_and_token_.has_value();
+}
+
+const std::pair<QuicConnectionId, StatelessResetToken>&
+QuicConfig::ReceivedPreferredAddressConnectionIdAndToken() const {
+  QUICHE_DCHECK(HasReceivedPreferredAddressConnectionIdAndToken());
+  return *preferred_address_connection_id_and_token_;
+}
+
+void QuicConfig::SetOriginalConnectionIdToSend(
+    const QuicConnectionId& original_destination_connection_id) {
+  original_destination_connection_id_to_send_ =
+      original_destination_connection_id;
+}
+
+bool QuicConfig::HasReceivedOriginalConnectionId() const {
+  return received_original_destination_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
+  if (!HasReceivedOriginalConnectionId()) {
+    QUIC_BUG(quic_bug_10575_13) << "No received original connection ID";
+    return EmptyQuicConnectionId();
+  }
+  return received_original_destination_connection_id_.value();
+}
+
+void QuicConfig::SetInitialSourceConnectionIdToSend(
+    const QuicConnectionId& initial_source_connection_id) {
+  initial_source_connection_id_to_send_ = initial_source_connection_id;
+}
+
+bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
+  return received_initial_source_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
+  if (!HasReceivedInitialSourceConnectionId()) {
+    QUIC_BUG(quic_bug_10575_14) << "No received initial source connection ID";
+    return EmptyQuicConnectionId();
+  }
+  return received_initial_source_connection_id_.value();
+}
+
+void QuicConfig::SetRetrySourceConnectionIdToSend(
+    const QuicConnectionId& retry_source_connection_id) {
+  retry_source_connection_id_to_send_ = retry_source_connection_id;
+}
+
+bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
+  return received_retry_source_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
+  if (!HasReceivedRetrySourceConnectionId()) {
+    QUIC_BUG(quic_bug_10575_15) << "No received retry source connection ID";
+    return EmptyQuicConnectionId();
+  }
+  return received_retry_source_connection_id_.value();
+}
+
+void QuicConfig::SetStatelessResetTokenToSend(
+    const StatelessResetToken& stateless_reset_token) {
+  stateless_reset_token_.SetSendValue(stateless_reset_token);
+}
+
+bool QuicConfig::HasReceivedStatelessResetToken() const {
+  return stateless_reset_token_.HasReceivedValue();
+}
+
+const StatelessResetToken& QuicConfig::ReceivedStatelessResetToken() const {
+  return stateless_reset_token_.GetReceivedValue();
+}
+
+bool QuicConfig::negotiated() const {
+  return negotiated_;
+}
+
+void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
+  create_session_tag_indicators_ = std::move(tags);
+}
+
+const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
+  return create_session_tag_indicators_;
+}
+
+void QuicConfig::SetDefaults() {
+  SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+  max_time_before_crypto_handshake_ =
+      QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
+  max_idle_time_before_crypto_handshake_ =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
+  max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
+
+  SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
+  SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
+  SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
+  SetAckDelayExponentToSend(kDefaultAckDelayExponent);
+  SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
+  SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
+}
+
+void QuicConfig::ToHandshakeMessage(
+    CryptoHandshakeMessage* out,
+    QuicTransportVersion transport_version) const {
+  // Idle timeout has custom rules that are different from other values.
+  // We configure ourselves with the minumum value between the one sent and
+  // the one received. Additionally, when QUIC_CRYPTO is used, the server
+  // MUST send an idle timeout no greater than the idle timeout it received
+  // from the client. We therefore send the received value if it is lower.
+  QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
+  uint32_t max_idle_timeout_to_send_seconds =
+      max_idle_timeout_to_send_.ToSeconds();
+  if (received_max_idle_timeout_.has_value() &&
+      received_max_idle_timeout_->ToSeconds() <
+          max_idle_timeout_to_send_seconds) {
+    max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
+  }
+  max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
+  max_idle_timeout_seconds.ToHandshakeMessage(out);
+
+  // Do not need a version check here, max...bi... will encode
+  // as "MIDS" -- the max initial dynamic streams tag -- if
+  // doing some version other than IETF QUIC.
+  max_bidirectional_streams_.ToHandshakeMessage(out);
+  if (VersionHasIetfQuicFrames(transport_version)) {
+    max_unidirectional_streams_.ToHandshakeMessage(out);
+    ack_delay_exponent_.ToHandshakeMessage(out);
+  }
+  if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
+    // Only send max ack delay if it is using a non-default value, because
+    // the default value is used by QuicSentPacketManager if it is not
+    // sent during the handshake, and we want to save bytes.
+    max_ack_delay_ms_.ToHandshakeMessage(out);
+  }
+  bytes_for_connection_id_.ToHandshakeMessage(out);
+  initial_round_trip_time_us_.ToHandshakeMessage(out);
+  initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
+  initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
+  connection_migration_disabled_.ToHandshakeMessage(out);
+  connection_options_.ToHandshakeMessage(out);
+  if (alternate_server_address_ipv6_.HasSendValue()) {
+    alternate_server_address_ipv6_.ToHandshakeMessage(out);
+  } else {
+    alternate_server_address_ipv4_.ToHandshakeMessage(out);
+  }
+  stateless_reset_token_.ToHandshakeMessage(out);
+}
+
+QuicErrorCode QuicConfig::ProcessPeerHello(
+    const CryptoHandshakeMessage& peer_hello,
+    HelloType hello_type,
+    std::string* error_details) {
+  QUICHE_DCHECK(error_details != nullptr);
+
+  QuicErrorCode error = QUIC_NO_ERROR;
+  if (error == QUIC_NO_ERROR) {
+    // Idle timeout has custom rules that are different from other values.
+    // We configure ourselves with the minumum value between the one sent and
+    // the one received. Additionally, when QUIC_CRYPTO is used, the server
+    // MUST send an idle timeout no greater than the idle timeout it received
+    // from the client.
+    QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
+    error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
+                                                      error_details);
+    if (error == QUIC_NO_ERROR) {
+      if (max_idle_timeout_seconds.GetReceivedValue() >
+          max_idle_timeout_to_send_.ToSeconds()) {
+        // The received value is higher than ours, ignore it if from the client
+        // and raise an error if from the server.
+        if (hello_type == SERVER) {
+          error = QUIC_INVALID_NEGOTIATED_VALUE;
+          *error_details =
+              "Invalid value received for " + QuicTagToString(kICSL);
+        }
+      } else {
+        received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
+            max_idle_timeout_seconds.GetReceivedValue());
+      }
+    }
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
+                                                        error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
+                                                         error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
+                                                      error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
+                                                         error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
+        peer_hello, hello_type, error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
+        peer_hello, hello_type, error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = connection_migration_disabled_.ProcessPeerHello(
+        peer_hello, hello_type, error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
+                                                 error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
+    error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
+                                                      error_details);
+    if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
+      const QuicSocketAddress& received_address =
+          alternate_server_address.GetReceivedValue();
+      if (received_address.host().IsIPv6()) {
+        alternate_server_address_ipv6_.SetReceivedValue(received_address);
+      } else if (received_address.host().IsIPv4()) {
+        alternate_server_address_ipv4_.SetReceivedValue(received_address);
+      }
+    }
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
+                                                    error_details);
+  }
+
+  if (error == QUIC_NO_ERROR) {
+    error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
+                                               error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
+                                                 error_details);
+  }
+  if (error == QUIC_NO_ERROR) {
+    negotiated_ = true;
+  }
+  return error;
+}
+
+bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
+  if (original_destination_connection_id_to_send_.has_value()) {
+    params->original_destination_connection_id =
+        original_destination_connection_id_to_send_.value();
+  }
+
+  params->max_idle_timeout_ms.set_value(
+      max_idle_timeout_to_send_.ToMilliseconds());
+
+  if (stateless_reset_token_.HasSendValue()) {
+    StatelessResetToken stateless_reset_token =
+        stateless_reset_token_.GetSendValue();
+    params->stateless_reset_token.assign(
+        reinterpret_cast<const char*>(&stateless_reset_token),
+        reinterpret_cast<const char*>(&stateless_reset_token) +
+            sizeof(stateless_reset_token));
+  }
+
+  params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
+  params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
+  params->initial_max_data.set_value(
+      GetInitialSessionFlowControlWindowToSend());
+  // The max stream data bidirectional transport parameters can be either local
+  // or remote. A stream is local iff it is initiated by the endpoint that sent
+  // the transport parameter (see the Transport Parameter Definitions section of
+  // draft-ietf-quic-transport). In this function we are sending transport
+  // parameters, so a local stream is one we initiated, which means an outgoing
+  // stream.
+  params->initial_max_stream_data_bidi_local.set_value(
+      GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  params->initial_max_stream_data_bidi_remote.set_value(
+      GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  params->initial_max_stream_data_uni.set_value(
+      GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  params->initial_max_streams_bidi.set_value(
+      GetMaxBidirectionalStreamsToSend());
+  params->initial_max_streams_uni.set_value(
+      GetMaxUnidirectionalStreamsToSend());
+  params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
+  if (min_ack_delay_ms_.HasSendValue()) {
+    params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
+                                       kNumMicrosPerMilli);
+  }
+  params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
+  params->disable_active_migration =
+      connection_migration_disabled_.HasSendValue() &&
+      connection_migration_disabled_.GetSendValue() != 0;
+
+  if (alternate_server_address_ipv6_.HasSendValue() ||
+      alternate_server_address_ipv4_.HasSendValue()) {
+    TransportParameters::PreferredAddress preferred_address;
+    if (alternate_server_address_ipv6_.HasSendValue()) {
+      preferred_address.ipv6_socket_address =
+          alternate_server_address_ipv6_.GetSendValue();
+    }
+    if (alternate_server_address_ipv4_.HasSendValue()) {
+      preferred_address.ipv4_socket_address =
+          alternate_server_address_ipv4_.GetSendValue();
+    }
+    if (preferred_address_connection_id_and_token_) {
+      preferred_address.connection_id =
+          preferred_address_connection_id_and_token_->first;
+      auto* begin = reinterpret_cast<const char*>(
+          &preferred_address_connection_id_and_token_->second);
+      auto* end =
+          begin + sizeof(preferred_address_connection_id_and_token_->second);
+      preferred_address.stateless_reset_token.assign(begin, end);
+    }
+    params->preferred_address =
+        std::make_unique<TransportParameters::PreferredAddress>(
+            preferred_address);
+  }
+
+  if (active_connection_id_limit_.HasSendValue()) {
+    params->active_connection_id_limit.set_value(
+        active_connection_id_limit_.GetSendValue());
+  }
+
+  if (initial_source_connection_id_to_send_.has_value()) {
+    params->initial_source_connection_id =
+        initial_source_connection_id_to_send_.value();
+  }
+
+  if (retry_source_connection_id_to_send_.has_value()) {
+    params->retry_source_connection_id =
+        retry_source_connection_id_to_send_.value();
+  }
+
+  if (initial_round_trip_time_us_.HasSendValue()) {
+    params->initial_round_trip_time_us.set_value(
+        initial_round_trip_time_us_.GetSendValue());
+  }
+  if (connection_options_.HasSendValues() &&
+      !connection_options_.GetSendValues().empty()) {
+    params->google_connection_options = connection_options_.GetSendValues();
+  }
+
+  params->custom_parameters = custom_transport_parameters_to_send_;
+
+  return true;
+}
+
+QuicErrorCode QuicConfig::ProcessTransportParameters(
+    const TransportParameters& params,
+    bool is_resumption,
+    std::string* error_details) {
+  if (!is_resumption && params.original_destination_connection_id.has_value()) {
+    received_original_destination_connection_id_ =
+        params.original_destination_connection_id.value();
+  }
+
+  if (params.max_idle_timeout_ms.value() > 0 &&
+      params.max_idle_timeout_ms.value() <
+          static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
+    // An idle timeout of zero indicates it is disabled.
+    // We also ignore values higher than ours which will cause us to use the
+    // smallest value between ours and our peer's.
+    received_max_idle_timeout_ =
+        QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
+  }
+
+  if (!is_resumption && !params.stateless_reset_token.empty()) {
+    StatelessResetToken stateless_reset_token;
+    if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
+      QUIC_BUG(quic_bug_10575_16) << "Bad stateless reset token length "
+                                  << params.stateless_reset_token.size();
+      *error_details = "Bad stateless reset token length";
+      return QUIC_INTERNAL_ERROR;
+    }
+    memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
+           params.stateless_reset_token.size());
+    stateless_reset_token_.SetReceivedValue(stateless_reset_token);
+  }
+
+  if (params.max_udp_payload_size.IsValid()) {
+    max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
+  }
+
+  if (params.max_datagram_frame_size.IsValid()) {
+    max_datagram_frame_size_.SetReceivedValue(
+        params.max_datagram_frame_size.value());
+  }
+
+  initial_session_flow_control_window_bytes_.SetReceivedValue(
+      params.initial_max_data.value());
+
+  // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
+  // our implementation uses uint32_t to represent them to save memory.
+  max_bidirectional_streams_.SetReceivedValue(
+      std::min<uint64_t>(params.initial_max_streams_bidi.value(),
+                         std::numeric_limits<uint32_t>::max()));
+  max_unidirectional_streams_.SetReceivedValue(
+      std::min<uint64_t>(params.initial_max_streams_uni.value(),
+                         std::numeric_limits<uint32_t>::max()));
+
+  // The max stream data bidirectional transport parameters can be either local
+  // or remote. A stream is local iff it is initiated by the endpoint that sent
+  // the transport parameter (see the Transport Parameter Definitions section of
+  // draft-ietf-quic-transport). However in this function we are processing
+  // received transport parameters, so a local stream is one initiated by our
+  // peer, which means an incoming stream.
+  initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
+      params.initial_max_stream_data_bidi_local.value());
+  initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
+      params.initial_max_stream_data_bidi_remote.value());
+  initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
+      params.initial_max_stream_data_uni.value());
+
+  if (!is_resumption) {
+    max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
+    if (params.ack_delay_exponent.IsValid()) {
+      ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
+    }
+    if (params.preferred_address != nullptr) {
+      if (params.preferred_address->ipv6_socket_address.port() != 0) {
+        alternate_server_address_ipv6_.SetReceivedValue(
+            params.preferred_address->ipv6_socket_address);
+      }
+      if (params.preferred_address->ipv4_socket_address.port() != 0) {
+        alternate_server_address_ipv4_.SetReceivedValue(
+            params.preferred_address->ipv4_socket_address);
+      }
+      // TODO(haoyuewang) Treat 0 length connection ID sent in preferred_address
+      // as a connection error of type TRANSPORT_PARAMETER_ERROR when server
+      // fully supports it.
+      if (!params.preferred_address->connection_id.IsEmpty()) {
+        preferred_address_connection_id_and_token_ = std::make_pair(
+            params.preferred_address->connection_id,
+            *reinterpret_cast<const StatelessResetToken*>(
+                &params.preferred_address->stateless_reset_token.front()));
+      }
+    }
+    if (params.min_ack_delay_us.value() != 0) {
+      if (params.min_ack_delay_us.value() >
+          params.max_ack_delay.value() * kNumMicrosPerMilli) {
+        *error_details = "MinAckDelay is greater than MaxAckDelay.";
+        return IETF_QUIC_PROTOCOL_VIOLATION;
+      }
+      min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
+                                         kNumMicrosPerMilli);
+    }
+  }
+
+  if (params.disable_active_migration) {
+    connection_migration_disabled_.SetReceivedValue(1u);
+  }
+
+  active_connection_id_limit_.SetReceivedValue(
+      params.active_connection_id_limit.value());
+
+  if (!is_resumption) {
+    if (params.initial_source_connection_id.has_value()) {
+      received_initial_source_connection_id_ =
+          params.initial_source_connection_id.value();
+    }
+    if (params.retry_source_connection_id.has_value()) {
+      received_retry_source_connection_id_ =
+          params.retry_source_connection_id.value();
+    }
+  }
+
+  if (params.initial_round_trip_time_us.value() > 0) {
+    initial_round_trip_time_us_.SetReceivedValue(
+        params.initial_round_trip_time_us.value());
+  }
+  if (params.google_connection_options.has_value()) {
+    connection_options_.SetReceivedValues(
+        params.google_connection_options.value());
+  }
+
+  received_custom_transport_parameters_ = params.custom_parameters;
+
+  if (!is_resumption) {
+    negotiated_ = true;
+  }
+  *error_details = "";
+  return QUIC_NO_ERROR;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_config.h b/quiche/quic/core/quic_config.h
new file mode 100644
index 0000000..71257d7
--- /dev/null
+++ b/quiche/quic/core/quic_config.h
@@ -0,0 +1,665 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONFIG_H_
+#define QUICHE_QUIC_CORE_QUIC_CONFIG_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicConfigPeer;
+}  // namespace test
+
+class CryptoHandshakeMessage;
+
+// Describes whether or not a given QuicTag is required or optional in the
+// handshake message.
+enum QuicConfigPresence : uint8_t {
+  // This negotiable value can be absent from the handshake message. Default
+  // value is selected as the negotiated value in such a case.
+  PRESENCE_OPTIONAL,
+  // This negotiable value is required in the handshake message otherwise the
+  // Process*Hello function returns an error.
+  PRESENCE_REQUIRED,
+};
+
+// Whether the CryptoHandshakeMessage is from the client or server.
+enum HelloType {
+  CLIENT,
+  SERVER,
+};
+
+// An abstract base class that stores a value that can be sent in CHLO/SHLO
+// message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
+class QUIC_EXPORT_PRIVATE QuicConfigValue {
+ public:
+  QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
+  virtual ~QuicConfigValue();
+
+  // Serialises tag name and value(s) to |out|.
+  virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0;
+
+  // Selects a mutually acceptable value from those offered in |peer_hello|
+  // and those defined in the subclass.
+  virtual QuicErrorCode ProcessPeerHello(
+      const CryptoHandshakeMessage& peer_hello,
+      HelloType hello_type,
+      std::string* error_details) = 0;
+
+ protected:
+  const QuicTag tag_;
+  const QuicConfigPresence presence_;
+};
+
+// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
+ public:
+  QuicFixedUint32(QuicTag tag, QuicConfigPresence presence);
+  ~QuicFixedUint32() override;
+
+  bool HasSendValue() const;
+
+  uint32_t GetSendValue() const;
+
+  void SetSendValue(uint32_t value);
+
+  bool HasReceivedValue() const;
+
+  uint32_t GetReceivedValue() const;
+
+  void SetReceivedValue(uint32_t value);
+
+  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  uint32_t send_value_;
+  uint32_t receive_value_;
+};
+
+// Stores 62bit numbers from handshake messages that unilaterally shared by each
+// endpoint. IMPORTANT: these are serialized as 32-bit unsigned integers when
+// using QUIC_CRYPTO versions and CryptoHandshakeMessage.
+class QUIC_EXPORT_PRIVATE QuicFixedUint62 : public QuicConfigValue {
+ public:
+  QuicFixedUint62(QuicTag name, QuicConfigPresence presence);
+  ~QuicFixedUint62() override;
+
+  bool HasSendValue() const;
+
+  uint64_t GetSendValue() const;
+
+  void SetSendValue(uint64_t value);
+
+  bool HasReceivedValue() const;
+
+  uint64_t GetReceivedValue() const;
+
+  void SetReceivedValue(uint64_t value);
+
+  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
+  // IMPORTANT: this method serializes |send_value_| as an unsigned 32bit
+  // integer.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  uint64_t send_value_;
+  uint64_t receive_value_;
+};
+
+// Stores StatelessResetToken from CHLO or SHLO messages that are not
+// negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedStatelessResetToken
+    : public QuicConfigValue {
+ public:
+  QuicFixedStatelessResetToken(QuicTag tag, QuicConfigPresence presence);
+  ~QuicFixedStatelessResetToken() override;
+
+  bool HasSendValue() const;
+
+  const StatelessResetToken& GetSendValue() const;
+
+  void SetSendValue(const StatelessResetToken& value);
+
+  bool HasReceivedValue() const;
+
+  const StatelessResetToken& GetReceivedValue() const;
+
+  void SetReceivedValue(const StatelessResetToken& value);
+
+  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  StatelessResetToken send_value_;
+  StatelessResetToken receive_value_;
+};
+
+// Stores tag from CHLO or SHLO messages that are not negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
+ public:
+  QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
+  QuicFixedTagVector(const QuicFixedTagVector& other);
+  ~QuicFixedTagVector() override;
+
+  bool HasSendValues() const;
+
+  const QuicTagVector& GetSendValues() const;
+
+  void SetSendValues(const QuicTagVector& values);
+
+  bool HasReceivedValues() const;
+
+  const QuicTagVector& GetReceivedValues() const;
+
+  void SetReceivedValues(const QuicTagVector& values);
+
+  // If has_send_value is true, serialises |tag_vector_| and |send_value_| to
+  // |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  // Sets |receive_values_| to the corresponding value from |client_hello_| if
+  // it exists.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_values_;
+  bool has_receive_values_;
+  QuicTagVector send_values_;
+  QuicTagVector receive_values_;
+};
+
+// Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
+class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
+ public:
+  QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
+  ~QuicFixedSocketAddress() override;
+
+  bool HasSendValue() const;
+
+  const QuicSocketAddress& GetSendValue() const;
+
+  void SetSendValue(const QuicSocketAddress& value);
+
+  bool HasReceivedValue() const;
+
+  const QuicSocketAddress& GetReceivedValue() const;
+
+  void SetReceivedValue(const QuicSocketAddress& value);
+
+  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
+
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details) override;
+
+ private:
+  bool has_send_value_;
+  bool has_receive_value_;
+  QuicSocketAddress send_value_;
+  QuicSocketAddress receive_value_;
+};
+
+// QuicConfig contains non-crypto configuration options that are negotiated in
+// the crypto handshake.
+class QUIC_EXPORT_PRIVATE QuicConfig {
+ public:
+  QuicConfig();
+  QuicConfig(const QuicConfig& other);
+  ~QuicConfig();
+
+  void SetConnectionOptionsToSend(const QuicTagVector& connection_options);
+
+  bool HasReceivedConnectionOptions() const;
+
+  // Sets initial received connection options.  All received connection options
+  // will be initialized with these fields. Initial received options may only be
+  // set once per config, prior to the setting of any other options.  If options
+  // have already been set (either by previous calls or via handshake), this
+  // function does nothing and returns false.
+  bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags);
+
+  const QuicTagVector& ReceivedConnectionOptions() const;
+
+  bool HasSendConnectionOptions() const;
+
+  const QuicTagVector& SendConnectionOptions() const;
+
+  // Returns true if the client is sending or the server has received a
+  // connection option.
+  // TODO(ianswett): Rename to HasClientRequestedSharedOption
+  bool HasClientSentConnectionOption(QuicTag tag,
+                                     Perspective perspective) const;
+
+  void SetClientConnectionOptions(
+      const QuicTagVector& client_connection_options);
+
+  // Returns true if the client has requested the specified connection option.
+  // Checks the client connection options if the |perspective| is client and
+  // connection options if the |perspective| is the server.
+  bool HasClientRequestedIndependentOption(QuicTag tag,
+                                           Perspective perspective) const;
+
+  const QuicTagVector& ClientRequestedIndependentOptions(
+      Perspective perspective) const;
+
+  void SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout);
+
+  QuicTime::Delta IdleNetworkTimeout() const;
+
+  // Sets the max bidirectional stream count that this endpoint supports.
+  void SetMaxBidirectionalStreamsToSend(uint32_t max_streams);
+  uint32_t GetMaxBidirectionalStreamsToSend() const;
+
+  bool HasReceivedMaxBidirectionalStreams() const;
+  // Gets the max bidirectional stream limit imposed by the peer.
+  uint32_t ReceivedMaxBidirectionalStreams() const;
+
+  // Sets the max unidirectional stream count that this endpoint supports.
+  void SetMaxUnidirectionalStreamsToSend(uint32_t max_streams);
+  uint32_t GetMaxUnidirectionalStreamsToSend() const;
+
+  bool HasReceivedMaxUnidirectionalStreams() const;
+  // Gets the max unidirectional stream limit imposed by the peer.
+  uint32_t ReceivedMaxUnidirectionalStreams() const;
+
+  void set_max_time_before_crypto_handshake(
+      QuicTime::Delta max_time_before_crypto_handshake) {
+    max_time_before_crypto_handshake_ = max_time_before_crypto_handshake;
+  }
+
+  QuicTime::Delta max_time_before_crypto_handshake() const {
+    return max_time_before_crypto_handshake_;
+  }
+
+  void set_max_idle_time_before_crypto_handshake(
+      QuicTime::Delta max_idle_time_before_crypto_handshake) {
+    max_idle_time_before_crypto_handshake_ =
+        max_idle_time_before_crypto_handshake;
+  }
+
+  QuicTime::Delta max_idle_time_before_crypto_handshake() const {
+    return max_idle_time_before_crypto_handshake_;
+  }
+
+  void set_max_undecryptable_packets(size_t max_undecryptable_packets) {
+    max_undecryptable_packets_ = max_undecryptable_packets;
+  }
+
+  size_t max_undecryptable_packets() const {
+    return max_undecryptable_packets_;
+  }
+
+  // Peer's connection id length, in bytes. Only used in Q043 and Q046.
+  bool HasSetBytesForConnectionIdToSend() const;
+  void SetBytesForConnectionIdToSend(uint32_t bytes);
+  bool HasReceivedBytesForConnectionId() const;
+  uint32_t ReceivedBytesForConnectionId() const;
+
+  // Estimated initial round trip time in us.
+  void SetInitialRoundTripTimeUsToSend(uint64_t rtt_us);
+  bool HasReceivedInitialRoundTripTimeUs() const;
+  uint64_t ReceivedInitialRoundTripTimeUs() const;
+  bool HasInitialRoundTripTimeUsToSend() const;
+  uint64_t GetInitialRoundTripTimeUsToSend() const;
+
+  // Sets an initial stream flow control window size to transmit to the peer.
+  void SetInitialStreamFlowControlWindowToSend(uint64_t window_bytes);
+  uint64_t GetInitialStreamFlowControlWindowToSend() const;
+  bool HasReceivedInitialStreamFlowControlWindowBytes() const;
+  uint64_t ReceivedInitialStreamFlowControlWindowBytes() const;
+
+  // Specifies the initial flow control window (max stream data) for
+  // incoming bidirectional streams. Incoming means streams initiated by our
+  // peer. If not set, GetInitialMaxStreamDataBytesIncomingBidirectionalToSend
+  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
+  void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      uint64_t window_bytes);
+  uint64_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const;
+  bool HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
+  uint64_t ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
+
+  // Specifies the initial flow control window (max stream data) for
+  // outgoing bidirectional streams. Outgoing means streams initiated by us.
+  // If not set, GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend
+  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
+  void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+      uint64_t window_bytes);
+  uint64_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const;
+  bool HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
+  uint64_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
+
+  // Specifies the initial flow control window (max stream data) for
+  // unidirectional streams. If not set,
+  // GetInitialMaxStreamDataBytesUnidirectionalToSend returns the value passed
+  // to SetInitialStreamFlowControlWindowToSend.
+  void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint64_t window_bytes);
+  uint64_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const;
+  bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const;
+  uint64_t ReceivedInitialMaxStreamDataBytesUnidirectional() const;
+
+  // Sets an initial session flow control window size to transmit to the peer.
+  void SetInitialSessionFlowControlWindowToSend(uint64_t window_bytes);
+  uint64_t GetInitialSessionFlowControlWindowToSend() const;
+  bool HasReceivedInitialSessionFlowControlWindowBytes() const;
+  uint64_t ReceivedInitialSessionFlowControlWindowBytes() const;
+
+  // Disable connection migration.
+  void SetDisableConnectionMigration();
+  bool DisableConnectionMigration() const;
+
+  // IPv6 alternate server address.
+  void SetIPv6AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv6);
+  void SetIPv6AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv6,
+      const QuicConnectionId& connection_id,
+      const StatelessResetToken& stateless_reset_token);
+  bool HasReceivedIPv6AlternateServerAddress() const;
+  const QuicSocketAddress& ReceivedIPv6AlternateServerAddress() const;
+
+  // IPv4 alternate server address.
+  void SetIPv4AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv4);
+  void SetIPv4AlternateServerAddressToSend(
+      const QuicSocketAddress& alternate_server_address_ipv4,
+      const QuicConnectionId& connection_id,
+      const StatelessResetToken& stateless_reset_token);
+  bool HasReceivedIPv4AlternateServerAddress() const;
+  const QuicSocketAddress& ReceivedIPv4AlternateServerAddress() const;
+
+  // Preferred Address Connection ID and Token.
+  bool HasReceivedPreferredAddressConnectionIdAndToken() const;
+  const std::pair<QuicConnectionId, StatelessResetToken>&
+  ReceivedPreferredAddressConnectionIdAndToken() const;
+
+  // Original destination connection ID.
+  void SetOriginalConnectionIdToSend(
+      const QuicConnectionId& original_destination_connection_id);
+  bool HasReceivedOriginalConnectionId() const;
+  QuicConnectionId ReceivedOriginalConnectionId() const;
+
+  // Stateless reset token.
+  void SetStatelessResetTokenToSend(
+      const StatelessResetToken& stateless_reset_token);
+  bool HasReceivedStatelessResetToken() const;
+  const StatelessResetToken& ReceivedStatelessResetToken() const;
+
+  // Manage the IETF QUIC Max ACK Delay transport parameter.
+  // The sent value is the delay that this node uses
+  // (QuicSentPacketManager::local_max_ack_delay_).
+  // The received delay is the value received from
+  // the peer (QuicSentPacketManager::peer_max_ack_delay_).
+  void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
+  uint32_t GetMaxAckDelayToSendMs() const;
+  bool HasReceivedMaxAckDelayMs() const;
+  uint32_t ReceivedMaxAckDelayMs() const;
+
+  // Manage the IETF QUIC extension Min Ack Delay transport parameter.
+  // An endpoint uses min_ack_delay to advsertise its support for
+  // AckFrequencyFrame sent by peer.
+  void SetMinAckDelayMs(uint32_t min_ack_delay_ms);
+  uint32_t GetMinAckDelayToSendMs() const;
+  bool HasReceivedMinAckDelayMs() const;
+  uint32_t ReceivedMinAckDelayMs() const;
+
+  void SetAckDelayExponentToSend(uint32_t exponent);
+  uint32_t GetAckDelayExponentToSend() const;
+  bool HasReceivedAckDelayExponent() const;
+  uint32_t ReceivedAckDelayExponent() const;
+
+  // IETF QUIC max_udp_payload_size transport parameter.
+  void SetMaxPacketSizeToSend(uint64_t max_udp_payload_size);
+  uint64_t GetMaxPacketSizeToSend() const;
+  bool HasReceivedMaxPacketSize() const;
+  uint64_t ReceivedMaxPacketSize() const;
+
+  // IETF QUIC max_datagram_frame_size transport parameter.
+  void SetMaxDatagramFrameSizeToSend(uint64_t max_datagram_frame_size);
+  uint64_t GetMaxDatagramFrameSizeToSend() const;
+  bool HasReceivedMaxDatagramFrameSize() const;
+  uint64_t ReceivedMaxDatagramFrameSize() const;
+
+  // IETF QUIC active_connection_id_limit transport parameter.
+  void SetActiveConnectionIdLimitToSend(uint64_t active_connection_id_limit);
+  uint64_t GetActiveConnectionIdLimitToSend() const;
+  bool HasReceivedActiveConnectionIdLimit() const;
+  uint64_t ReceivedActiveConnectionIdLimit() const;
+
+  // Initial source connection ID.
+  void SetInitialSourceConnectionIdToSend(
+      const QuicConnectionId& initial_source_connection_id);
+  bool HasReceivedInitialSourceConnectionId() const;
+  QuicConnectionId ReceivedInitialSourceConnectionId() const;
+
+  // Retry source connection ID.
+  void SetRetrySourceConnectionIdToSend(
+      const QuicConnectionId& retry_source_connection_id);
+  bool HasReceivedRetrySourceConnectionId() const;
+  QuicConnectionId ReceivedRetrySourceConnectionId() const;
+
+  bool negotiated() const;
+
+  void SetCreateSessionTagIndicators(QuicTagVector tags);
+
+  const QuicTagVector& create_session_tag_indicators() const;
+
+  // ToHandshakeMessage serialises the settings in this object as a series of
+  // tags /value pairs and adds them to |out|.
+  void ToHandshakeMessage(CryptoHandshakeMessage* out,
+                          QuicTransportVersion transport_version) const;
+
+  // Calls ProcessPeerHello on each negotiable parameter. On failure returns
+  // the corresponding QuicErrorCode and sets detailed error in |error_details|.
+  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
+                                 HelloType hello_type,
+                                 std::string* error_details);
+
+  // FillTransportParameters writes the values to send for ICSL, MIDS, CFCW, and
+  // SFCW to |*params|, returning true if the values could be written and false
+  // if something prevents them from being written (e.g. a value is too large).
+  bool FillTransportParameters(TransportParameters* params) const;
+
+  // ProcessTransportParameters reads from |params| which were received from a
+  // peer. If |is_resumption|, some configs will not be processed.
+  // On failure, it returns a QuicErrorCode and puts a detailed error in
+  // |*error_details|.
+  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
+                                           bool is_resumption,
+                                           std::string* error_details);
+
+  TransportParameters::ParameterMap& custom_transport_parameters_to_send() {
+    return custom_transport_parameters_to_send_;
+  }
+  const TransportParameters::ParameterMap&
+  received_custom_transport_parameters() const {
+    return received_custom_transport_parameters_;
+  }
+
+ private:
+  friend class test::QuicConfigPeer;
+
+  // SetDefaults sets the members to sensible, default values.
+  void SetDefaults();
+
+  // Whether we've received the peer's config.
+  bool negotiated_;
+
+  // Configurations options that are not negotiated.
+  // Maximum time the session can be alive before crypto handshake is finished.
+  QuicTime::Delta max_time_before_crypto_handshake_;
+  // Maximum idle time before the crypto handshake has completed.
+  QuicTime::Delta max_idle_time_before_crypto_handshake_;
+  // Maximum number of undecryptable packets stored before CHLO/SHLO.
+  size_t max_undecryptable_packets_;
+
+  // Connection options which affect the server side.  May also affect the
+  // client side in cases when identical behavior is desirable.
+  QuicFixedTagVector connection_options_;
+  // Connection options which only affect the client side.
+  QuicFixedTagVector client_connection_options_;
+  // Maximum idle network timeout.
+  // Uses the max_idle_timeout transport parameter in IETF QUIC.
+  // Note that received_max_idle_timeout_ is only populated if we receive the
+  // peer's value, which isn't guaranteed in IETF QUIC as sending is optional.
+  QuicTime::Delta max_idle_timeout_to_send_;
+  absl::optional<QuicTime::Delta> received_max_idle_timeout_;
+  // Maximum number of dynamic streams that a Google QUIC connection
+  // can support or the maximum number of bidirectional streams that
+  // an IETF QUIC connection can support.
+  // The SendValue is the limit on peer-created streams that this endpoint is
+  // advertising.
+  // The ReceivedValue is the limit on locally-created streams that
+  // the peer advertised.
+  // Uses the initial_max_streams_bidi transport parameter in IETF QUIC.
+  QuicFixedUint32 max_bidirectional_streams_;
+  // Maximum number of unidirectional streams that the connection can
+  // support.
+  // The SendValue is the limit on peer-created streams that this endpoint is
+  // advertising.
+  // The ReceivedValue is the limit on locally-created streams that the peer
+  // advertised.
+  // Uses the initial_max_streams_uni transport parameter in IETF QUIC.
+  QuicFixedUint32 max_unidirectional_streams_;
+  // The number of bytes required for the connection ID. This is only used in
+  // the legacy header format used only by Q043 at this point.
+  QuicFixedUint32 bytes_for_connection_id_;
+  // Initial round trip time estimate in microseconds.
+  QuicFixedUint62 initial_round_trip_time_us_;
+
+  // Initial IETF QUIC stream flow control receive windows in bytes.
+  // Incoming bidirectional streams.
+  // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
+  // in IETF QUIC, depending on whether we're sending or receiving.
+  QuicFixedUint62 initial_max_stream_data_bytes_incoming_bidirectional_;
+  // Outgoing bidirectional streams.
+  // Uses the initial_max_stream_data_bidi_{local,remote} transport parameter
+  // in IETF QUIC, depending on whether we're sending or receiving.
+  QuicFixedUint62 initial_max_stream_data_bytes_outgoing_bidirectional_;
+  // Unidirectional streams.
+  // Uses the initial_max_stream_data_uni transport parameter in IETF QUIC.
+  QuicFixedUint62 initial_max_stream_data_bytes_unidirectional_;
+
+  // Initial Google QUIC stream flow control receive window in bytes.
+  QuicFixedUint62 initial_stream_flow_control_window_bytes_;
+
+  // Initial session flow control receive window in bytes.
+  // Uses the initial_max_data transport parameter in IETF QUIC.
+  QuicFixedUint62 initial_session_flow_control_window_bytes_;
+
+  // Whether active connection migration is allowed.
+  // Uses the disable_active_migration transport parameter in IETF QUIC.
+  QuicFixedUint32 connection_migration_disabled_;
+
+  // Alternate server addresses the client could connect to.
+  // Uses the preferred_address transport parameter in IETF QUIC.
+  // Note that when QUIC_CRYPTO is in use, only one of the addresses is sent.
+  QuicFixedSocketAddress alternate_server_address_ipv6_;
+  QuicFixedSocketAddress alternate_server_address_ipv4_;
+  // Connection Id data to send from the server or receive at the client as part
+  // of the preferred address transport parameter.
+  absl::optional<std::pair<QuicConnectionId, StatelessResetToken>>
+      preferred_address_connection_id_and_token_;
+
+  // Stateless reset token used in IETF public reset packet.
+  // Uses the stateless_reset_token transport parameter in IETF QUIC.
+  QuicFixedStatelessResetToken stateless_reset_token_;
+
+  // List of QuicTags whose presence immediately causes the session to
+  // be created. This allows for CHLOs that are larger than a single
+  // packet to be processed.
+  QuicTagVector create_session_tag_indicators_;
+
+  // Maximum ack delay. The sent value is the value used on this node.
+  // The received value is the value received from the peer and used by
+  // the peer.
+  // Uses the max_ack_delay transport parameter in IETF QUIC.
+  QuicFixedUint32 max_ack_delay_ms_;
+
+  // Minimum ack delay. Used to enable sender control of max_ack_delay.
+  // Uses the min_ack_delay transport parameter in IETF QUIC extension.
+  QuicFixedUint32 min_ack_delay_ms_;
+
+  // The sent exponent is the exponent that this node uses when serializing an
+  // ACK frame (and the peer should use when deserializing the frame);
+  // the received exponent is the value the peer uses to serialize frames and
+  // this node uses to deserialize them.
+  // Uses the ack_delay_exponent transport parameter in IETF QUIC.
+  QuicFixedUint32 ack_delay_exponent_;
+
+  // Maximum packet size in bytes.
+  // Uses the max_udp_payload_size transport parameter in IETF QUIC.
+  QuicFixedUint62 max_udp_payload_size_;
+
+  // Maximum DATAGRAM/MESSAGE frame size in bytes.
+  // Uses the max_datagram_frame_size transport parameter in IETF QUIC.
+  QuicFixedUint62 max_datagram_frame_size_;
+
+  // Maximum number of connection IDs from the peer.
+  // Uses the active_connection_id_limit transport parameter in IETF QUIC.
+  QuicFixedUint62 active_connection_id_limit_;
+
+  // The value of the Destination Connection ID field from the first
+  // Initial packet sent by the client.
+  // Uses the original_destination_connection_id transport parameter in
+  // IETF QUIC.
+  absl::optional<QuicConnectionId> original_destination_connection_id_to_send_;
+  absl::optional<QuicConnectionId> received_original_destination_connection_id_;
+
+  // The value that the endpoint included in the Source Connection ID field of
+  // the first Initial packet it sent.
+  // Uses the initial_source_connection_id transport parameter in IETF QUIC.
+  absl::optional<QuicConnectionId> initial_source_connection_id_to_send_;
+  absl::optional<QuicConnectionId> received_initial_source_connection_id_;
+
+  // The value that the server included in the Source Connection ID field of a
+  // Retry packet it sent.
+  // Uses the retry_source_connection_id transport parameter in IETF QUIC.
+  absl::optional<QuicConnectionId> retry_source_connection_id_to_send_;
+  absl::optional<QuicConnectionId> received_retry_source_connection_id_;
+
+  // Custom transport parameters that can be sent and received in the TLS
+  // handshake.
+  TransportParameters::ParameterMap custom_transport_parameters_to_send_;
+  TransportParameters::ParameterMap received_custom_transport_parameters_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONFIG_H_
diff --git a/quiche/quic/core/quic_config_test.cc b/quiche/quic/core/quic_config_test.cc
new file mode 100644
index 0000000..9c42158
--- /dev/null
+++ b/quiche/quic/core/quic_config_test.cc
@@ -0,0 +1,727 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_config.h"
+
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicConfigTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicConfigTest() : version_(GetParam()) {}
+
+ protected:
+  ParsedQuicVersion version_;
+  QuicConfig config_;
+};
+
+// Run all tests with all versions of QUIC.
+INSTANTIATE_TEST_SUITE_P(QuicConfigTests,
+                         QuicConfigTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicConfigTest, SetDefaults) {
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  EXPECT_FALSE(config_.HasReceivedInitialStreamFlowControlWindowBytes());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+  EXPECT_EQ(kMaxIncomingPacketSize, config_.GetMaxPacketSizeToSend());
+  EXPECT_FALSE(config_.HasReceivedMaxPacketSize());
+}
+
+TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  static const uint32_t kTestWindowSize = 1234567;
+  config_.SetInitialStreamFlowControlWindowToSend(kTestWindowSize);
+  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  static const uint32_t kTestWindowSizeTwo = 2345678;
+  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      kTestWindowSizeTwo);
+  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kTestWindowSizeTwo,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+}
+
+TEST_P(QuicConfigTest, ToHandshakeMessage) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  config_.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config_.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5));
+  CryptoHandshakeMessage msg;
+  config_.ToHandshakeMessage(&msg, version_.transport_version);
+
+  uint32_t value;
+  QuicErrorCode error = msg.GetUint32(kICSL, &value);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_EQ(5u, value);
+
+  error = msg.GetUint32(kSFCW, &value);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
+
+  error = msg.GetUint32(kCFCW, &value);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
+}
+
+TEST_P(QuicConfigTest, ProcessClientHello) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  const uint32_t kTestMaxAckDelayMs =
+      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
+  QuicConfig client_config;
+  QuicTagVector cgst;
+  cgst.push_back(kQBIC);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
+  client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      2 * kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      2 * kInitialSessionFlowControlWindowForTest);
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetConnectionOptionsToSend(copt);
+  client_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  QuicTagVector initial_received_options;
+  initial_received_options.push_back(kIW50);
+  EXPECT_TRUE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options));
+  EXPECT_FALSE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options))
+      << "You can only set initial options once.";
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_FALSE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options))
+      << "You cannot set initial options after the hello.";
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
+            config_.IdleNetworkTimeout());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
+  EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
+  EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
+  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+            2 * kInitialStreamFlowControlWindowForTest);
+  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+            2 * kInitialSessionFlowControlWindowForTest);
+  EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
+
+  // IETF QUIC stream limits should not be received in QUIC crypto messages.
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+}
+
+TEST_P(QuicConfigTest, ProcessServerHello) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicIpAddress host;
+  host.FromString("127.0.3.1");
+  const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  const StatelessResetToken kTestStatelessResetToken{
+      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
+  const uint32_t kTestMaxAckDelayMs =
+      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
+  QuicConfig server_config;
+  QuicTagVector cgst;
+  cgst.push_back(kQBIC);
+  server_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
+  server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+  server_config.SetInitialStreamFlowControlWindowToSend(
+      2 * kInitialStreamFlowControlWindowForTest);
+  server_config.SetInitialSessionFlowControlWindowToSend(
+      2 * kInitialSessionFlowControlWindowForTest);
+  server_config.SetIPv4AlternateServerAddressToSend(kTestServerAddress);
+  server_config.SetStatelessResetTokenToSend(kTestStatelessResetToken);
+  server_config.SetMaxAckDelayToSendMs(kTestMaxAckDelayMs);
+  CryptoHandshakeMessage msg;
+  server_config.ToHandshakeMessage(&msg, version_.transport_version);
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
+            config_.IdleNetworkTimeout());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+            2 * kInitialStreamFlowControlWindowForTest);
+  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+            2 * kInitialSessionFlowControlWindowForTest);
+  EXPECT_TRUE(config_.HasReceivedIPv4AlternateServerAddress());
+  EXPECT_EQ(kTestServerAddress, config_.ReceivedIPv4AlternateServerAddress());
+  EXPECT_FALSE(config_.HasReceivedIPv6AlternateServerAddress());
+  EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
+  EXPECT_EQ(kTestStatelessResetToken, config_.ReceivedStatelessResetToken());
+  EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
+
+  // IETF QUIC stream limits should not be received in QUIC crypto messages.
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_FALSE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+}
+
+TEST_P(QuicConfigTest, MissingOptionalValuesInCHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  CryptoHandshakeMessage msg;
+  msg.SetValue(kICSL, 1);
+
+  // Set all REQUIRED tags.
+  msg.SetValue(kICSL, 1);
+  msg.SetValue(kMIBS, 1);
+
+  // No error, as rest are optional.
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_P(QuicConfigTest, MissingOptionalValuesInSHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  CryptoHandshakeMessage msg;
+
+  // Set all REQUIRED tags.
+  msg.SetValue(kICSL, 1);
+  msg.SetValue(kMIBS, 1);
+
+  // No error, as rest are optional.
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_P(QuicConfigTest, MissingValueInCHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  // Server receives CHLO with missing kICSL.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
+}
+
+TEST_P(QuicConfigTest, MissingValueInSHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  // Client receives SHLO with missing kICSL.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsError(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND));
+}
+
+TEST_P(QuicConfigTest, OutOfBoundSHLO) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig server_config;
+  server_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
+
+  CryptoHandshakeMessage msg;
+  server_config.ToHandshakeMessage(&msg, version_.transport_version);
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_THAT(error, IsError(QUIC_INVALID_NEGOTIATED_VALUE));
+}
+
+TEST_P(QuicConfigTest, InvalidFlowControlWindow) {
+  // QuicConfig should not accept an invalid flow control window to send to the
+  // peer: the receive window must be at least the default of 16 Kb.
+  QuicConfig config;
+  const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  EXPECT_QUIC_BUG(
+      config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
+      "Initial stream flow control receive window");
+
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config.GetInitialStreamFlowControlWindowToSend());
+}
+
+TEST_P(QuicConfigTest, HasClientSentConnectionOption) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetConnectionOptionsToSend(copt);
+  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+      kTBBR, Perspective::IS_CLIENT));
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+  EXPECT_TRUE(
+      config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
+}
+
+TEST_P(QuicConfigTest, DontSendClientConnectionOptions) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetClientConnectionOptions(copt);
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_FALSE(config_.HasReceivedConnectionOptions());
+}
+
+TEST_P(QuicConfigTest, HasClientRequestedIndependentOption) {
+  if (version_.UsesTls()) {
+    // CryptoHandshakeMessage is only used for QUIC_CRYPTO.
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector client_opt;
+  client_opt.push_back(kRENO);
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetClientConnectionOptions(client_opt);
+  client_config.SetConnectionOptionsToSend(copt);
+  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+      kTBBR, Perspective::IS_CLIENT));
+  EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
+      kRENO, Perspective::IS_CLIENT));
+  EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
+      kTBBR, Perspective::IS_CLIENT));
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg, version_.transport_version);
+
+  std::string error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+  EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
+      kRENO, Perspective::IS_SERVER));
+  EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
+      kTBBR, Perspective::IS_SERVER));
+}
+
+TEST_P(QuicConfigTest, IncomingLargeIdleTimeoutTransportParameter) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  // Configure our idle timeout to 60s, then receive 120s from peer.
+  // Since the received value is above ours, we should then use ours.
+  config_.SetIdleNetworkTimeout(quic::QuicTime::Delta::FromSeconds(60));
+  TransportParameters params;
+  params.max_idle_timeout_ms.set_value(120000);
+
+  std::string error_details = "foobar";
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  EXPECT_EQ("", error_details);
+  EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(60),
+            config_.IdleNetworkTimeout());
+}
+
+TEST_P(QuicConfigTest, ReceivedInvalidMinAckDelayInTransportParameter) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  TransportParameters params;
+
+  params.max_ack_delay.set_value(25 /*ms*/);
+  params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli + 1);
+  std::string error_details = "foobar";
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("MinAckDelay is greater than MaxAckDelay.", error_details);
+
+  params.max_ack_delay.set_value(25 /*ms*/);
+  params.min_ack_delay_us.set_value(25 * kNumMicrosPerMilli);
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  EXPECT_TRUE(error_details.empty());
+}
+
+TEST_P(QuicConfigTest, FillTransportParams) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      2 * kMinimumFlowControlSendWindow);
+  config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+      3 * kMinimumFlowControlSendWindow);
+  config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
+      4 * kMinimumFlowControlSendWindow);
+  config_.SetMaxPacketSizeToSend(kMaxPacketSizeForTest);
+  config_.SetMaxDatagramFrameSizeToSend(kMaxDatagramFrameSizeForTest);
+  config_.SetActiveConnectionIdLimitToSend(kActiveConnectionIdLimitForTest);
+
+  config_.SetOriginalConnectionIdToSend(TestConnectionId(0x1111));
+  config_.SetInitialSourceConnectionIdToSend(TestConnectionId(0x2222));
+  config_.SetRetrySourceConnectionIdToSend(TestConnectionId(0x3333));
+  config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
+
+  QuicIpAddress host;
+  host.FromString("127.0.3.1");
+  QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  QuicConnectionId new_connection_id = TestConnectionId(5);
+  StatelessResetToken new_stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(new_connection_id);
+  config_.SetIPv4AlternateServerAddressToSend(
+      kTestServerAddress, new_connection_id, new_stateless_reset_token);
+
+  TransportParameters params;
+  config_.FillTransportParameters(&params);
+
+  EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
+            params.initial_max_stream_data_bidi_remote.value());
+  EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
+            params.initial_max_stream_data_bidi_local.value());
+  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
+            params.initial_max_stream_data_uni.value());
+
+  EXPECT_EQ(static_cast<uint64_t>(kMaximumIdleTimeoutSecs * 1000),
+            params.max_idle_timeout_ms.value());
+
+  EXPECT_EQ(kMaxPacketSizeForTest, params.max_udp_payload_size.value());
+  EXPECT_EQ(kMaxDatagramFrameSizeForTest,
+            params.max_datagram_frame_size.value());
+  EXPECT_EQ(kActiveConnectionIdLimitForTest,
+            params.active_connection_id_limit.value());
+
+  ASSERT_TRUE(params.original_destination_connection_id.has_value());
+  EXPECT_EQ(TestConnectionId(0x1111),
+            params.original_destination_connection_id.value());
+  ASSERT_TRUE(params.initial_source_connection_id.has_value());
+  EXPECT_EQ(TestConnectionId(0x2222),
+            params.initial_source_connection_id.value());
+  ASSERT_TRUE(params.retry_source_connection_id.has_value());
+  EXPECT_EQ(TestConnectionId(0x3333),
+            params.retry_source_connection_id.value());
+
+  EXPECT_EQ(
+      static_cast<uint64_t>(kDefaultMinAckDelayTimeMs) * kNumMicrosPerMilli,
+      params.min_ack_delay_us.value());
+
+  EXPECT_EQ(params.preferred_address->ipv4_socket_address, kTestServerAddress);
+  EXPECT_EQ(*reinterpret_cast<StatelessResetToken*>(
+                &params.preferred_address->stateless_reset_token.front()),
+            new_stateless_reset_token);
+}
+
+TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  TransportParameters params;
+
+  params.initial_max_stream_data_bidi_local.set_value(
+      2 * kMinimumFlowControlSendWindow);
+  params.initial_max_stream_data_bidi_remote.set_value(
+      3 * kMinimumFlowControlSendWindow);
+  params.initial_max_stream_data_uni.set_value(4 *
+                                               kMinimumFlowControlSendWindow);
+  params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
+  params.max_datagram_frame_size.set_value(kMaxDatagramFrameSizeForTest);
+  params.initial_max_streams_bidi.set_value(kDefaultMaxStreamsPerConnection);
+  params.stateless_reset_token = CreateStatelessResetTokenForTest();
+  params.max_ack_delay.set_value(kMaxAckDelayForTest);
+  params.min_ack_delay_us.set_value(kMinAckDelayUsForTest);
+  params.ack_delay_exponent.set_value(kAckDelayExponentForTest);
+  params.active_connection_id_limit.set_value(kActiveConnectionIdLimitForTest);
+  params.original_destination_connection_id = TestConnectionId(0x1111);
+  params.initial_source_connection_id = TestConnectionId(0x2222);
+  params.retry_source_connection_id = TestConnectionId(0x3333);
+
+  std::string error_details;
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ true, &error_details),
+              IsQuicNoError())
+      << error_details;
+
+  EXPECT_FALSE(config_.negotiated());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_EQ(2 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_EQ(3 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
+  EXPECT_EQ(kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
+  EXPECT_EQ(kMaxDatagramFrameSizeForTest,
+            config_.ReceivedMaxDatagramFrameSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            config_.ReceivedMaxBidirectionalStreams());
+
+  EXPECT_FALSE(config_.DisableConnectionMigration());
+
+  // The following config shouldn't be processed because of resumption.
+  EXPECT_FALSE(config_.HasReceivedStatelessResetToken());
+  EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_FALSE(config_.HasReceivedAckDelayExponent());
+  EXPECT_FALSE(config_.HasReceivedMinAckDelayMs());
+  EXPECT_FALSE(config_.HasReceivedOriginalConnectionId());
+  EXPECT_FALSE(config_.HasReceivedInitialSourceConnectionId());
+  EXPECT_FALSE(config_.HasReceivedRetrySourceConnectionId());
+
+  // Let the config process another slightly tweaked transport paramters.
+  // Note that the values for flow control and stream limit cannot be smaller
+  // than before. This rule is enforced in QuicSession::OnConfigNegotiated().
+  params.initial_max_stream_data_bidi_local.set_value(
+      2 * kMinimumFlowControlSendWindow + 1);
+  params.initial_max_stream_data_bidi_remote.set_value(
+      4 * kMinimumFlowControlSendWindow);
+  params.initial_max_stream_data_uni.set_value(5 *
+                                               kMinimumFlowControlSendWindow);
+  params.max_udp_payload_size.set_value(2 * kMaxPacketSizeForTest);
+  params.max_datagram_frame_size.set_value(2 * kMaxDatagramFrameSizeForTest);
+  params.initial_max_streams_bidi.set_value(2 *
+                                            kDefaultMaxStreamsPerConnection);
+  params.disable_active_migration = true;
+
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError())
+      << error_details;
+
+  EXPECT_TRUE(config_.negotiated());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+  EXPECT_EQ(2 * kMinimumFlowControlSendWindow + 1,
+            config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+
+  ASSERT_TRUE(
+      config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+  EXPECT_EQ(4 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
+  EXPECT_EQ(5 * kMinimumFlowControlSendWindow,
+            config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
+
+  ASSERT_TRUE(config_.HasReceivedMaxPacketSize());
+  EXPECT_EQ(2 * kMaxPacketSizeForTest, config_.ReceivedMaxPacketSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxDatagramFrameSize());
+  EXPECT_EQ(2 * kMaxDatagramFrameSizeForTest,
+            config_.ReceivedMaxDatagramFrameSize());
+
+  ASSERT_TRUE(config_.HasReceivedMaxBidirectionalStreams());
+  EXPECT_EQ(2 * kDefaultMaxStreamsPerConnection,
+            config_.ReceivedMaxBidirectionalStreams());
+
+  EXPECT_TRUE(config_.DisableConnectionMigration());
+
+  ASSERT_TRUE(config_.HasReceivedStatelessResetToken());
+
+  ASSERT_TRUE(config_.HasReceivedMaxAckDelayMs());
+  EXPECT_EQ(config_.ReceivedMaxAckDelayMs(), kMaxAckDelayForTest);
+
+  ASSERT_TRUE(config_.HasReceivedMinAckDelayMs());
+  EXPECT_EQ(config_.ReceivedMinAckDelayMs(),
+            kMinAckDelayUsForTest / kNumMicrosPerMilli);
+
+  ASSERT_TRUE(config_.HasReceivedAckDelayExponent());
+  EXPECT_EQ(config_.ReceivedAckDelayExponent(), kAckDelayExponentForTest);
+
+  ASSERT_TRUE(config_.HasReceivedActiveConnectionIdLimit());
+  EXPECT_EQ(config_.ReceivedActiveConnectionIdLimit(),
+            kActiveConnectionIdLimitForTest);
+
+  ASSERT_TRUE(config_.HasReceivedOriginalConnectionId());
+  EXPECT_EQ(config_.ReceivedOriginalConnectionId(), TestConnectionId(0x1111));
+  ASSERT_TRUE(config_.HasReceivedInitialSourceConnectionId());
+  EXPECT_EQ(config_.ReceivedInitialSourceConnectionId(),
+            TestConnectionId(0x2222));
+  ASSERT_TRUE(config_.HasReceivedRetrySourceConnectionId());
+  EXPECT_EQ(config_.ReceivedRetrySourceConnectionId(),
+            TestConnectionId(0x3333));
+}
+
+TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+  TransportParameters params;
+  params.disable_active_migration = true;
+  std::string error_details;
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  EXPECT_TRUE(config_.DisableConnectionMigration());
+}
+
+TEST_P(QuicConfigTest, SendPreferredIPv4Address) {
+  if (!version_.UsesTls()) {
+    // TransportParameters are only used for QUIC+TLS.
+    return;
+  }
+
+  EXPECT_FALSE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
+
+  TransportParameters params;
+  QuicIpAddress host;
+  host.FromString("::ffff:192.0.2.128");
+  QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  QuicConnectionId new_connection_id = TestConnectionId(5);
+  StatelessResetToken new_stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(new_connection_id);
+  auto preferred_address =
+      std::make_unique<TransportParameters::PreferredAddress>();
+  preferred_address->ipv6_socket_address = kTestServerAddress;
+  preferred_address->connection_id = new_connection_id;
+  preferred_address->stateless_reset_token.assign(
+      reinterpret_cast<const char*>(&new_stateless_reset_token),
+      reinterpret_cast<const char*>(&new_stateless_reset_token) +
+          sizeof(new_stateless_reset_token));
+  params.preferred_address = std::move(preferred_address);
+
+  std::string error_details;
+  EXPECT_THAT(config_.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+
+  EXPECT_TRUE(config_.HasReceivedIPv6AlternateServerAddress());
+  EXPECT_EQ(config_.ReceivedIPv6AlternateServerAddress(), kTestServerAddress);
+  EXPECT_TRUE(config_.HasReceivedPreferredAddressConnectionIdAndToken());
+  const std::pair<QuicConnectionId, StatelessResetToken>&
+      preferred_address_connection_id_and_token =
+          config_.ReceivedPreferredAddressConnectionIdAndToken();
+  EXPECT_EQ(preferred_address_connection_id_and_token.first, new_connection_id);
+  EXPECT_EQ(preferred_address_connection_id_and_token.second,
+            new_stateless_reset_token);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
new file mode 100644
index 0000000..9865f61
--- /dev/null
+++ b/quiche/quic/core/quic_connection.cc
@@ -0,0 +1,7118 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection.h"
+
+#include <string.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <optional>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_legacy_version_encapsulator.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+class QuicDecrypter;
+class QuicEncrypter;
+
+namespace {
+
+// Maximum number of consecutive sent nonretransmittable packets.
+const QuicPacketCount kMaxConsecutiveNonRetransmittablePackets = 19;
+
+// The minimum release time into future in ms.
+const int kMinReleaseTimeIntoFutureMs = 1;
+
+// Base class of all alarms owned by a QuicConnection.
+class QuicConnectionAlarmDelegate : public QuicAlarm::Delegate {
+ public:
+  explicit QuicConnectionAlarmDelegate(QuicConnection* connection)
+      : connection_(connection) {}
+  QuicConnectionAlarmDelegate(const QuicConnectionAlarmDelegate&) = delete;
+  QuicConnectionAlarmDelegate& operator=(const QuicConnectionAlarmDelegate&) =
+      delete;
+
+  QuicConnectionContext* GetConnectionContext() override {
+    return (connection_ == nullptr) ? nullptr : connection_->context();
+  }
+
+ protected:
+  QuicConnection* connection_;
+};
+
+// An alarm that is scheduled to send an ack if a timeout occurs.
+class AckAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->ack_frame_updated());
+    QUICHE_DCHECK(connection_->connected());
+    QuicConnection::ScopedPacketFlusher flusher(connection_);
+    if (connection_->SupportsMultiplePacketNumberSpaces()) {
+      connection_->SendAllPendingAcks();
+    } else {
+      connection_->SendAck();
+    }
+  }
+};
+
+// This alarm will be scheduled any time a data-bearing packet is sent out.
+// When the alarm goes off, the connection checks to see if the oldest packets
+// have been acked, and retransmit them if they have not.
+class RetransmissionAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->OnRetransmissionTimeout();
+  }
+};
+
+// An alarm that is scheduled when the SentPacketManager requires a delay
+// before sending packets and fires when the packet may be sent.
+class SendAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->WriteIfNotBlocked();
+  }
+};
+
+class PingAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->OnPingTimeout();
+  }
+};
+
+class MtuDiscoveryAlarmDelegate : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->DiscoverMtu();
+  }
+};
+
+class ProcessUndecryptablePacketsAlarmDelegate
+    : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    QuicConnection::ScopedPacketFlusher flusher(connection_);
+    connection_->MaybeProcessUndecryptablePackets();
+  }
+};
+
+class DiscardPreviousOneRttKeysAlarmDelegate
+    : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    connection_->DiscardPreviousOneRttKeys();
+  }
+};
+
+class DiscardZeroRttDecryptionKeysAlarmDelegate
+    : public QuicConnectionAlarmDelegate {
+ public:
+  using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
+
+  void OnAlarm() override {
+    QUICHE_DCHECK(connection_->connected());
+    QUIC_DLOG(INFO) << "0-RTT discard alarm fired";
+    connection_->RemoveDecrypter(ENCRYPTION_ZERO_RTT);
+  }
+};
+
+// When the clearer goes out of scope, the coalesced packet gets cleared.
+class ScopedCoalescedPacketClearer {
+ public:
+  explicit ScopedCoalescedPacketClearer(QuicCoalescedPacket* coalesced)
+      : coalesced_(coalesced) {}
+  ~ScopedCoalescedPacketClearer() { coalesced_->Clear(); }
+
+ private:
+  QuicCoalescedPacket* coalesced_;  // Unowned.
+};
+
+// Whether this incoming packet is allowed to replace our connection ID.
+bool PacketCanReplaceServerConnectionId(const QuicPacketHeader& header,
+                                        Perspective perspective) {
+  return perspective == Perspective::IS_CLIENT &&
+         header.form == IETF_QUIC_LONG_HEADER_PACKET &&
+         header.version.IsKnown() &&
+         header.version.AllowsVariableLengthConnectionIds() &&
+         (header.long_packet_type == INITIAL ||
+          header.long_packet_type == RETRY);
+}
+
+CongestionControlType GetDefaultCongestionControlType() {
+  if (GetQuicReloadableFlag(quic_default_to_bbr_v2)) {
+    return kBBRv2;
+  }
+
+  if (GetQuicReloadableFlag(quic_default_to_bbr)) {
+    return kBBR;
+  }
+
+  return kCubicBytes;
+}
+
+}  // namespace
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicConnection::QuicConnection(
+    QuicConnectionId server_connection_id,
+    QuicSocketAddress initial_self_address,
+    QuicSocketAddress initial_peer_address,
+    QuicConnectionHelperInterface* helper, QuicAlarmFactory* alarm_factory,
+    QuicPacketWriter* writer, bool owns_writer, Perspective perspective,
+    const ParsedQuicVersionVector& supported_versions)
+    : framer_(supported_versions, helper->GetClock()->ApproximateNow(),
+              perspective, server_connection_id.length()),
+      current_packet_content_(NO_FRAMES_RECEIVED),
+      is_current_packet_connectivity_probing_(false),
+      has_path_challenge_in_current_packet_(false),
+      current_effective_peer_migration_type_(NO_CHANGE),
+      helper_(helper),
+      alarm_factory_(alarm_factory),
+      per_packet_options_(nullptr),
+      writer_(writer),
+      owns_writer_(owns_writer),
+      encryption_level_(ENCRYPTION_INITIAL),
+      clock_(helper->GetClock()),
+      random_generator_(helper->GetRandomGenerator()),
+      client_connection_id_is_set_(false),
+      direct_peer_address_(initial_peer_address),
+      default_path_(initial_self_address, QuicSocketAddress(),
+                    /*client_connection_id=*/EmptyQuicConnectionId(),
+                    server_connection_id,
+                    /*stateless_reset_token=*/absl::nullopt),
+      active_effective_peer_migration_type_(NO_CHANGE),
+      support_key_update_for_connection_(false),
+      last_packet_decrypted_(false),
+      last_size_(0),
+      current_packet_data_(nullptr),
+      last_decrypted_packet_level_(ENCRYPTION_INITIAL),
+      should_last_packet_instigate_acks_(false),
+      max_undecryptable_packets_(0),
+      max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
+      idle_timeout_connection_close_behavior_(
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET),
+      num_rtos_for_blackhole_detection_(0),
+      uber_received_packet_manager_(&stats_),
+      stop_waiting_count_(0),
+      pending_retransmission_alarm_(false),
+      defer_send_in_response_to_packets_(false),
+      ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
+      initial_retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
+      consecutive_retransmittable_on_wire_ping_count_(0),
+      retransmittable_on_wire_ping_count_(0),
+      arena_(),
+      ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this),
+                                             &arena_)),
+      retransmission_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<RetransmissionAlarmDelegate>(this), &arena_)),
+      send_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<SendAlarmDelegate>(this), &arena_)),
+      ping_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<PingAlarmDelegate>(this), &arena_)),
+      mtu_discovery_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<MtuDiscoveryAlarmDelegate>(this), &arena_)),
+      process_undecryptable_packets_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<ProcessUndecryptablePacketsAlarmDelegate>(this), &arena_)),
+      discard_previous_one_rtt_keys_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<DiscardPreviousOneRttKeysAlarmDelegate>(this), &arena_)),
+      discard_zero_rtt_decryption_keys_alarm_(alarm_factory_->CreateAlarm(
+          arena_.New<DiscardZeroRttDecryptionKeysAlarmDelegate>(this),
+          &arena_)),
+      visitor_(nullptr),
+      debug_visitor_(nullptr),
+      packet_creator_(server_connection_id, &framer_, random_generator_, this),
+      last_received_packet_info_(clock_->ApproximateNow()),
+      sent_packet_manager_(perspective, clock_, random_generator_, &stats_,
+                           GetDefaultCongestionControlType()),
+      version_negotiated_(false),
+      perspective_(perspective),
+      connected_(true),
+      can_truncate_connection_ids_(perspective == Perspective::IS_SERVER),
+      mtu_probe_count_(0),
+      previous_validated_mtu_(0),
+      peer_max_packet_size_(kDefaultMaxPacketSizeTransportParam),
+      largest_received_packet_size_(0),
+      write_error_occurred_(false),
+      no_stop_waiting_frames_(version().HasIetfInvariantHeader()),
+      consecutive_num_packets_with_no_retransmittable_frames_(0),
+      max_consecutive_num_packets_with_no_retransmittable_frames_(
+          kMaxConsecutiveNonRetransmittablePackets),
+      bundle_retransmittable_with_pto_ack_(false),
+      fill_up_link_during_probing_(false),
+      probing_retransmission_pending_(false),
+      last_control_frame_id_(kInvalidControlFrameId),
+      is_path_degrading_(false),
+      processing_ack_frame_(false),
+      supports_release_time_(false),
+      release_time_into_future_(QuicTime::Delta::Zero()),
+      blackhole_detector_(this, &arena_, alarm_factory_, &context_),
+      idle_network_detector_(this, clock_->ApproximateNow(), &arena_,
+                             alarm_factory_, &context_),
+      path_validator_(alarm_factory_, &arena_, this, random_generator_,
+                      &context_),
+      most_recent_frame_type_(NUM_FRAME_TYPES) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
+                default_path_.self_address.IsInitialized());
+
+  QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
+                  << server_connection_id
+                  << " and version: " << ParsedQuicVersionToString(version());
+
+  QUIC_BUG_IF(quic_bug_12714_2, !QuicUtils::IsConnectionIdValidForVersion(
+                                    server_connection_id, transport_version()))
+      << "QuicConnection: attempted to use server connection ID "
+      << server_connection_id << " which is invalid with version " << version();
+  framer_.set_visitor(this);
+  stats_.connection_creation_time = clock_->ApproximateNow();
+  // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
+  // and make it required non-null, because it's always used.
+  sent_packet_manager_.SetNetworkChangeVisitor(this);
+  if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) {
+    sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero());
+    release_time_into_future_ =
+        QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs);
+  }
+  // Allow the packet writer to potentially reduce the packet size to a value
+  // even smaller than kDefaultMaxPacketSize.
+  SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
+                         ? kDefaultServerMaxPacketSize
+                         : kDefaultMaxPacketSize);
+  uber_received_packet_manager_.set_max_ack_ranges(255);
+  MaybeEnableMultiplePacketNumberSpacesSupport();
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
+                supported_versions.size() == 1);
+  InstallInitialCrypters(default_path_.server_connection_id);
+
+  // On the server side, version negotiation has been done by the dispatcher,
+  // and the server connection is created with the right version.
+  if (perspective_ == Perspective::IS_SERVER) {
+    SetVersionNegotiated();
+  }
+  if (default_enable_5rto_blackhole_detection_) {
+    num_rtos_for_blackhole_detection_ = 5;
+    if (GetQuicReloadableFlag(quic_disable_server_blackhole_detection) &&
+        perspective_ == Perspective::IS_SERVER) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_disable_server_blackhole_detection);
+      blackhole_detection_disabled_ = true;
+    }
+  }
+  packet_creator_.SetDefaultPeerAddress(initial_peer_address);
+}
+
+void QuicConnection::InstallInitialCrypters(QuicConnectionId connection_id) {
+  CrypterPair crypters;
+  CryptoUtils::CreateInitialObfuscators(perspective_, version(), connection_id,
+                                        &crypters);
+  SetEncrypter(ENCRYPTION_INITIAL, std::move(crypters.encrypter));
+  if (version().KnowsWhichDecrypterToUse()) {
+    InstallDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
+  } else {
+    SetDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
+  }
+}
+
+QuicConnection::~QuicConnection() {
+  QUICHE_DCHECK_GE(stats_.max_egress_mtu, long_term_mtu_);
+  if (owns_writer_) {
+    delete writer_;
+  }
+  ClearQueuedPackets();
+  if (stats_
+          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter >
+      0) {
+    QUIC_CODE_COUNT_N(
+        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 2,
+        3);
+  } else {
+    QUIC_CODE_COUNT_N(
+        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 3,
+        3);
+  }
+}
+
+void QuicConnection::ClearQueuedPackets() {
+  buffered_packets_.clear();
+}
+
+bool QuicConnection::ValidateConfigConnectionIds(const QuicConfig& config) {
+  QUICHE_DCHECK(config.negotiated());
+  if (!version().UsesTls()) {
+    // QUIC+TLS is required to transmit connection ID transport parameters.
+    return true;
+  }
+  // This function validates connection IDs as defined in IETF draft-28 and
+  // later.
+
+  // Validate initial_source_connection_id.
+  QuicConnectionId expected_initial_source_connection_id;
+  if (perspective_ == Perspective::IS_CLIENT) {
+    expected_initial_source_connection_id = default_path_.server_connection_id;
+  } else {
+    expected_initial_source_connection_id = default_path_.client_connection_id;
+  }
+  if (!config.HasReceivedInitialSourceConnectionId() ||
+      config.ReceivedInitialSourceConnectionId() !=
+          expected_initial_source_connection_id) {
+    std::string received_value;
+    if (config.HasReceivedInitialSourceConnectionId()) {
+      received_value = config.ReceivedInitialSourceConnectionId().ToString();
+    } else {
+      received_value = "none";
+    }
+    std::string error_details =
+        absl::StrCat("Bad initial_source_connection_id: expected ",
+                     expected_initial_source_connection_id.ToString(),
+                     ", received ", received_value);
+    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    // Validate original_destination_connection_id.
+    if (!config.HasReceivedOriginalConnectionId() ||
+        config.ReceivedOriginalConnectionId() !=
+            GetOriginalDestinationConnectionId()) {
+      std::string received_value;
+      if (config.HasReceivedOriginalConnectionId()) {
+        received_value = config.ReceivedOriginalConnectionId().ToString();
+      } else {
+        received_value = "none";
+      }
+      std::string error_details =
+          absl::StrCat("Bad original_destination_connection_id: expected ",
+                       GetOriginalDestinationConnectionId().ToString(),
+                       ", received ", received_value);
+      CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return false;
+    }
+    // Validate retry_source_connection_id.
+    if (retry_source_connection_id_.has_value()) {
+      // We received a RETRY packet, validate that the retry source
+      // connection ID from the config matches the one from the RETRY.
+      if (!config.HasReceivedRetrySourceConnectionId() ||
+          config.ReceivedRetrySourceConnectionId() !=
+              retry_source_connection_id_.value()) {
+        std::string received_value;
+        if (config.HasReceivedRetrySourceConnectionId()) {
+          received_value = config.ReceivedRetrySourceConnectionId().ToString();
+        } else {
+          received_value = "none";
+        }
+        std::string error_details =
+            absl::StrCat("Bad retry_source_connection_id: expected ",
+                         retry_source_connection_id_.value().ToString(),
+                         ", received ", received_value);
+        CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
+    } else {
+      // We did not receive a RETRY packet, make sure we did not receive the
+      // retry_source_connection_id transport parameter.
+      if (config.HasReceivedRetrySourceConnectionId()) {
+        std::string error_details = absl::StrCat(
+            "Bad retry_source_connection_id: did not receive RETRY but "
+            "received ",
+            config.ReceivedRetrySourceConnectionId().ToString());
+        CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+void QuicConnection::SetFromConfig(const QuicConfig& config) {
+  if (config.negotiated()) {
+    // Handshake complete, set handshake timeout to Infinite.
+    SetNetworkTimeouts(QuicTime::Delta::Infinite(),
+                       config.IdleNetworkTimeout());
+    idle_timeout_connection_close_behavior_ =
+        ConnectionCloseBehavior::SILENT_CLOSE;
+    if (perspective_ == Perspective::IS_SERVER) {
+      idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior::
+          SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED;
+    }
+    if (config.HasClientRequestedIndependentOption(kNSLC, perspective_)) {
+      idle_timeout_connection_close_behavior_ =
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET;
+    }
+    if (!ValidateConfigConnectionIds(config)) {
+      return;
+    }
+    support_key_update_for_connection_ = version().UsesTls();
+    framer_.SetKeyUpdateSupportForConnection(
+        support_key_update_for_connection_);
+  } else {
+    SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
+                       config.max_idle_time_before_crypto_handshake());
+    if (config.HasClientRequestedIndependentOption(kNCHP, perspective_)) {
+      packet_creator_.set_chaos_protection_enabled(false);
+    }
+  }
+
+  if (version().HasIetfQuicFrames() &&
+      config.HasReceivedPreferredAddressConnectionIdAndToken()) {
+    QuicNewConnectionIdFrame frame;
+    std::tie(frame.connection_id, frame.stateless_reset_token) =
+        config.ReceivedPreferredAddressConnectionIdAndToken();
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    OnNewConnectionIdFrameInner(frame);
+  }
+
+  sent_packet_manager_.SetFromConfig(config);
+  if (perspective_ == Perspective::IS_SERVER &&
+      config.HasClientSentConnectionOption(kAFF2, perspective_)) {
+    send_ack_frequency_on_handshake_completion_ = true;
+  }
+  if (config.HasReceivedBytesForConnectionId() &&
+      can_truncate_connection_ids_) {
+    packet_creator_.SetServerConnectionIdLength(
+        config.ReceivedBytesForConnectionId());
+  }
+  max_undecryptable_packets_ = config.max_undecryptable_packets();
+
+  if (!GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
+    if (config.HasClientRequestedIndependentOption(kMTUH, perspective_)) {
+      SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
+    }
+  }
+  if (config.HasClientRequestedIndependentOption(kMTUL, perspective_)) {
+    SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
+  }
+  if (default_enable_5rto_blackhole_detection_) {
+    if (config.HasClientRequestedIndependentOption(kCBHD, perspective_)) {
+      QUIC_CODE_COUNT(quic_client_only_blackhole_detection);
+      blackhole_detection_disabled_ = true;
+    }
+    if (config.HasClientSentConnectionOption(kNBHD, perspective_)) {
+      blackhole_detection_disabled_ = true;
+    }
+    if (config.HasClientSentConnectionOption(k2RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_2rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 2;
+    }
+    if (config.HasClientSentConnectionOption(k3RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_3rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 3;
+    }
+    if (config.HasClientSentConnectionOption(k4RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_4rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 4;
+    }
+    if (config.HasClientSentConnectionOption(k6RTO, perspective_)) {
+      QUIC_CODE_COUNT(quic_6rto_blackhole_detection);
+      num_rtos_for_blackhole_detection_ = 6;
+    }
+  }
+
+  if (config.HasClientRequestedIndependentOption(kFIDT, perspective_)) {
+    idle_network_detector_.enable_shorter_idle_timeout_on_sent_packet();
+  }
+  if (config.HasClientRequestedIndependentOption(k3AFF, perspective_)) {
+    anti_amplification_factor_ = 3;
+  }
+  if (config.HasClientRequestedIndependentOption(k10AF, perspective_)) {
+    anti_amplification_factor_ = 10;
+  }
+
+  if (GetQuicReloadableFlag(quic_enable_server_on_wire_ping) &&
+      perspective_ == Perspective::IS_SERVER &&
+      config.HasClientSentConnectionOption(kSRWP, perspective_)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_server_on_wire_ping);
+    set_initial_retransmittable_on_wire_timeout(
+        QuicTime::Delta::FromMilliseconds(200));
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSetFromConfig(config);
+  }
+  uber_received_packet_manager_.SetFromConfig(config, perspective_);
+  if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
+    num_rtos_for_blackhole_detection_ = 5;
+  }
+  if (sent_packet_manager_.pto_enabled()) {
+    if (config.HasClientSentConnectionOption(k6PTO, perspective_) ||
+        config.HasClientSentConnectionOption(k7PTO, perspective_) ||
+        config.HasClientSentConnectionOption(k8PTO, perspective_)) {
+      num_rtos_for_blackhole_detection_ = 5;
+    }
+  }
+  if (config.HasClientSentConnectionOption(kNSTP, perspective_)) {
+    no_stop_waiting_frames_ = true;
+  }
+  if (config.HasReceivedStatelessResetToken()) {
+    default_path_.stateless_reset_token = config.ReceivedStatelessResetToken();
+  }
+  if (config.HasReceivedAckDelayExponent()) {
+    framer_.set_peer_ack_delay_exponent(config.ReceivedAckDelayExponent());
+  }
+  if (config.HasClientSentConnectionOption(kEACK, perspective_)) {
+    bundle_retransmittable_with_pto_ack_ = true;
+  }
+  if (config.HasClientSentConnectionOption(kDFER, perspective_)) {
+    defer_send_in_response_to_packets_ = false;
+  }
+
+  if (config.HasClientRequestedIndependentOption(kINVC, perspective_)) {
+    send_connection_close_for_invalid_version_ = true;
+  }
+  const bool remove_connection_migration_connection_option =
+      GetQuicReloadableFlag(quic_remove_connection_migration_connection_option);
+  if (remove_connection_migration_connection_option) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_remove_connection_migration_connection_option);
+  }
+  if (framer_.version().HasIetfQuicFrames() && use_path_validator_ &&
+      count_bytes_on_alternative_path_separately_ &&
+      GetQuicReloadableFlag(quic_server_reverse_validate_new_path3) &&
+      (remove_connection_migration_connection_option ||
+       config.HasClientSentConnectionOption(kRVCM, perspective_))) {
+    QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 6, 6);
+    validate_client_addresses_ = true;
+  }
+  // Having connection_migration_use_new_cid_ depends on the same set of flags
+  // and connection option on both client and server sides has the advantage of:
+  // 1) Less chance of skew in using new connection ID or not between client
+  //    and server in unit tests with random flag combinations.
+  // 2) Client side's rollout can be protected by the same connection option.
+  connection_migration_use_new_cid_ =
+      validate_client_addresses_ &&
+      GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
+  if (config.HasReceivedMaxPacketSize()) {
+    peer_max_packet_size_ = config.ReceivedMaxPacketSize();
+    MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+  }
+  if (config.HasReceivedMaxDatagramFrameSize()) {
+    packet_creator_.SetMaxDatagramFrameSize(
+        config.ReceivedMaxDatagramFrameSize());
+  }
+
+  supports_release_time_ =
+      writer_ != nullptr && writer_->SupportsReleaseTime() &&
+      !config.HasClientSentConnectionOption(kNPCO, perspective_);
+
+  if (supports_release_time_) {
+    UpdateReleaseTimeIntoFuture();
+  }
+}
+
+void QuicConnection::EnableLegacyVersionEncapsulation(
+    const std::string& server_name) {
+  if (perspective_ != Perspective::IS_CLIENT) {
+    QUIC_BUG(quic_bug_10511_1)
+        << "Cannot enable Legacy Version Encapsulation on the server";
+    return;
+  }
+  if (legacy_version_encapsulation_enabled_) {
+    QUIC_BUG(quic_bug_10511_2)
+        << "Do not call EnableLegacyVersionEncapsulation twice";
+    return;
+  }
+  if (!QuicHostnameUtils::IsValidSNI(server_name)) {
+    // Legacy Version Encapsulation is only used when SNI is transmitted.
+    QUIC_DLOG(INFO)
+        << "Refusing to use Legacy Version Encapsulation with invalid SNI \""
+        << server_name << "\"";
+    return;
+  }
+  QUIC_DLOG(INFO) << "Enabling Legacy Version Encapsulation with SNI \""
+                  << server_name << "\"";
+  legacy_version_encapsulation_enabled_ = true;
+  legacy_version_encapsulation_sni_ = server_name;
+}
+
+bool QuicConnection::MaybeTestLiveness() {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
+    return false;
+  }
+  const QuicTime idle_network_deadline =
+      idle_network_detector_.GetIdleNetworkDeadline();
+  if (!idle_network_deadline.IsInitialized()) {
+    return false;
+  }
+  const QuicTime now = clock_->ApproximateNow();
+  if (now > idle_network_deadline) {
+    QUIC_DLOG(WARNING) << "Idle network deadline has passed";
+    return false;
+  }
+  const QuicTime::Delta timeout = idle_network_deadline - now;
+  if (2 * timeout > idle_network_detector_.idle_network_timeout()) {
+    // Do not test liveness if timeout is > half timeout. This is used to
+    // prevent an infinite loop for short idle timeout.
+    return false;
+  }
+  if (!sent_packet_manager_.IsLessThanThreePTOs(timeout)) {
+    return false;
+  }
+  SendConnectivityProbingPacket(writer_, peer_address());
+  return true;
+}
+
+void QuicConnection::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  sent_packet_manager_.ApplyConnectionOptions(connection_options);
+}
+
+void QuicConnection::OnSendConnectionState(
+    const CachedNetworkParameters& cached_network_params) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSendConnectionState(cached_network_params);
+  }
+}
+
+void QuicConnection::OnReceiveConnectionState(
+    const CachedNetworkParameters& cached_network_params) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnReceiveConnectionState(cached_network_params);
+  }
+}
+
+void QuicConnection::ResumeConnectionState(
+    const CachedNetworkParameters& cached_network_params,
+    bool max_bandwidth_resumption) {
+  sent_packet_manager_.ResumeConnectionState(cached_network_params,
+                                             max_bandwidth_resumption);
+}
+
+void QuicConnection::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
+  sent_packet_manager_.SetMaxPacingRate(max_pacing_rate);
+}
+
+void QuicConnection::AdjustNetworkParameters(
+    const SendAlgorithmInterface::NetworkParams& params) {
+  sent_packet_manager_.AdjustNetworkParameters(params);
+}
+
+void QuicConnection::SetLossDetectionTuner(
+    std::unique_ptr<LossDetectionTunerInterface> tuner) {
+  sent_packet_manager_.SetLossDetectionTuner(std::move(tuner));
+}
+
+void QuicConnection::OnConfigNegotiated() {
+  sent_packet_manager_.OnConfigNegotiated();
+
+  if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server) &&
+      perspective_ == Perspective::IS_SERVER) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_mtu_discovery_at_server);
+    SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
+  }
+}
+
+QuicBandwidth QuicConnection::MaxPacingRate() const {
+  return sent_packet_manager_.MaxPacingRate();
+}
+
+bool QuicConnection::SelectMutualVersion(
+    const ParsedQuicVersionVector& available_versions) {
+  // Try to find the highest mutual version by iterating over supported
+  // versions, starting with the highest, and breaking out of the loop once we
+  // find a matching version in the provided available_versions vector.
+  const ParsedQuicVersionVector& supported_versions =
+      framer_.supported_versions();
+  for (size_t i = 0; i < supported_versions.size(); ++i) {
+    const ParsedQuicVersion& version = supported_versions[i];
+    if (std::find(available_versions.begin(), available_versions.end(),
+                  version) != available_versions.end()) {
+      framer_.set_version(version);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void QuicConnection::OnError(QuicFramer* framer) {
+  // Packets that we can not or have not decrypted are dropped.
+  // TODO(rch): add stats to measure this.
+  if (!connected_ || last_packet_decrypted_ == false) {
+    return;
+  }
+  CloseConnection(framer->error(), framer->detailed_error(),
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicConnection::OnPacket() {
+  last_packet_decrypted_ = false;
+}
+
+void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
+  // Check that any public reset packet with a different connection ID that was
+  // routed to this QuicConnection has been redirected before control reaches
+  // here.  (Check for a bug regression.)
+  QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  QUICHE_DCHECK(!version().HasIetfInvariantHeader());
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPublicResetPacket(packet);
+  }
+  std::string error_details = "Received public reset.";
+  if (perspective_ == Perspective::IS_CLIENT && !packet.endpoint_id.empty()) {
+    absl::StrAppend(&error_details, " From ", packet.endpoint_id, ".");
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << error_details;
+  QUIC_CODE_COUNT(quic_tear_down_local_connection_on_public_reset);
+  TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
+                               error_details, ConnectionCloseSource::FROM_PEER);
+}
+
+bool QuicConnection::OnProtocolVersionMismatch(
+    ParsedQuicVersion received_version) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
+                  << ParsedQuicVersionToString(received_version);
+  if (perspective_ == Perspective::IS_CLIENT) {
+    const std::string error_details = "Protocol version mismatch.";
+    QUIC_BUG(quic_bug_10511_3) << ENDPOINT << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+  }
+
+  // Server drops old packets that were sent by the client before the version
+  // was negotiated.
+  return false;
+}
+
+// Handles version negotiation for client connection.
+void QuicConnection::OnVersionNegotiationPacket(
+    const QuicVersionNegotiationPacket& packet) {
+  // Check that any public reset packet with a different connection ID that was
+  // routed to this QuicConnection has been redirected before control reaches
+  // here.  (Check for a bug regression.)
+  QUICHE_DCHECK_EQ(default_path_.server_connection_id, packet.connection_id);
+  if (perspective_ == Perspective::IS_SERVER) {
+    const std::string error_details =
+        "Server received version negotiation packet.";
+    QUIC_BUG(quic_bug_10511_4) << error_details;
+    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_version_negotiation);
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnVersionNegotiationPacket(packet);
+  }
+
+  if (version_negotiated_) {
+    // Possibly a duplicate version negotiation packet.
+    return;
+  }
+
+  if (std::find(packet.versions.begin(), packet.versions.end(), version()) !=
+      packet.versions.end()) {
+    const std::string error_details = absl::StrCat(
+        "Server already supports client's version ",
+        ParsedQuicVersionToString(version()),
+        " and should have accepted the connection instead of sending {",
+        ParsedQuicVersionVectorToString(packet.versions), "}.");
+    QUIC_DLOG(WARNING) << error_details;
+    CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, error_details,
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+
+  server_supported_versions_ = packet.versions;
+  CloseConnection(
+      QUIC_INVALID_VERSION,
+      absl::StrCat(
+          "Client may support one of the versions in the server's list, but "
+          "it's going to close the connection anyway. Supported versions: {",
+          ParsedQuicVersionVectorToString(framer_.supported_versions()),
+          "}, peer supported versions: {",
+          ParsedQuicVersionVectorToString(packet.versions), "}"),
+      send_connection_close_for_invalid_version_
+          ? ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET
+          : ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+// Handles retry for client connection.
+void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
+                                   QuicConnectionId new_connection_id,
+                                   absl::string_view retry_token,
+                                   absl::string_view retry_integrity_tag,
+                                   absl::string_view retry_without_tag) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+  if (version().UsesTls()) {
+    if (!CryptoUtils::ValidateRetryIntegrityTag(
+            version(), default_path_.server_connection_id, retry_without_tag,
+            retry_integrity_tag)) {
+      QUIC_DLOG(ERROR) << "Ignoring RETRY with invalid integrity tag";
+      return;
+    }
+  } else {
+    if (original_connection_id != default_path_.server_connection_id) {
+      QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
+                       << original_connection_id << " not matching expected "
+                       << default_path_.server_connection_id << " token "
+                       << absl::BytesToHexString(retry_token);
+      return;
+    }
+  }
+  framer_.set_drop_incoming_retry_packets(true);
+  stats_.retry_packet_processed = true;
+  QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
+                  << default_path_.server_connection_id << " with "
+                  << new_connection_id << ", received token "
+                  << absl::BytesToHexString(retry_token);
+  if (!original_destination_connection_id_.has_value()) {
+    original_destination_connection_id_ = default_path_.server_connection_id;
+  }
+  QUICHE_DCHECK(!retry_source_connection_id_.has_value())
+      << retry_source_connection_id_.value();
+  retry_source_connection_id_ = new_connection_id;
+  ReplaceInitialServerConnectionId(new_connection_id);
+  packet_creator_.SetRetryToken(retry_token);
+
+  // Reinstall initial crypters because the connection ID changed.
+  InstallInitialCrypters(default_path_.server_connection_id);
+
+  sent_packet_manager_.MarkInitialPacketsForRetransmission();
+}
+
+void QuicConnection::SetOriginalDestinationConnectionId(
+    const QuicConnectionId& original_destination_connection_id) {
+  QUIC_DLOG(INFO) << "Setting original_destination_connection_id to "
+                  << original_destination_connection_id
+                  << " on connection with server_connection_id "
+                  << default_path_.server_connection_id;
+  QUICHE_DCHECK_NE(original_destination_connection_id,
+                   default_path_.server_connection_id);
+  InstallInitialCrypters(original_destination_connection_id);
+  QUICHE_DCHECK(!original_destination_connection_id_.has_value())
+      << original_destination_connection_id_.value();
+  original_destination_connection_id_ = original_destination_connection_id;
+  original_destination_connection_id_replacement_ =
+      default_path_.server_connection_id;
+}
+
+QuicConnectionId QuicConnection::GetOriginalDestinationConnectionId() {
+  if (original_destination_connection_id_.has_value()) {
+    return original_destination_connection_id_.value();
+  }
+  return default_path_.server_connection_id;
+}
+
+bool QuicConnection::ValidateServerConnectionId(
+    const QuicPacketHeader& header) const {
+  if (perspective_ == Perspective::IS_CLIENT &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return true;
+  }
+
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsRecipient(header, perspective_);
+
+  if (server_connection_id == default_path_.server_connection_id ||
+      server_connection_id == original_destination_connection_id_) {
+    return true;
+  }
+
+  if (PacketCanReplaceServerConnectionId(header, perspective_)) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
+                    << server_connection_id << " instead of "
+                    << default_path_.server_connection_id;
+    return true;
+  }
+
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_SERVER &&
+      self_issued_cid_manager_ != nullptr &&
+      self_issued_cid_manager_->IsConnectionIdInUse(server_connection_id)) {
+    return true;
+  }
+
+  return false;
+}
+
+bool QuicConnection::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& header) {
+  last_packet_destination_connection_id_ = header.destination_connection_id;
+  // If last packet destination connection ID is the original server
+  // connection ID chosen by client, replaces it with the connection ID chosen
+  // by server.
+  if (perspective_ == Perspective::IS_SERVER &&
+      original_destination_connection_id_.has_value() &&
+      last_packet_destination_connection_id_ ==
+          *original_destination_connection_id_) {
+    last_packet_destination_connection_id_ =
+        original_destination_connection_id_replacement_;
+  }
+
+  // As soon as we receive an initial we start ignoring subsequent retries.
+  if (header.version_flag && header.long_packet_type == INITIAL) {
+    framer_.set_drop_incoming_retry_packets(true);
+  }
+
+  if (!ValidateServerConnectionId(header)) {
+    ++stats_.packets_dropped;
+    QuicConnectionId server_connection_id =
+        GetServerConnectionIdAsRecipient(header, perspective_);
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Ignoring packet from unexpected server connection ID "
+                    << server_connection_id << " instead of "
+                    << default_path_.server_connection_id;
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnIncorrectConnectionId(server_connection_id);
+    }
+    // If this is a server, the dispatcher routes each packet to the
+    // QuicConnection responsible for the packet's connection ID.  So if control
+    // arrives here and this is a server, the dispatcher must be malfunctioning.
+    QUICHE_DCHECK_NE(Perspective::IS_SERVER, perspective_);
+    return false;
+  }
+
+  if (!version().SupportsClientConnectionIds()) {
+    return true;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return true;
+  }
+
+  QuicConnectionId client_connection_id =
+      GetClientConnectionIdAsRecipient(header, perspective_);
+
+  if (client_connection_id == default_path_.client_connection_id) {
+    return true;
+  }
+
+  if (!client_connection_id_is_set_ && perspective_ == Perspective::IS_SERVER) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Setting client connection ID from first packet to "
+                    << client_connection_id;
+    set_client_connection_id(client_connection_id);
+    return true;
+  }
+
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      self_issued_cid_manager_ != nullptr &&
+      self_issued_cid_manager_->IsConnectionIdInUse(client_connection_id)) {
+    return true;
+  }
+
+  ++stats_.packets_dropped;
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "Ignoring packet from unexpected client connection ID "
+                  << client_connection_id << " instead of "
+                  << default_path_.client_connection_id;
+  return false;
+}
+
+bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnUnauthenticatedHeader(header);
+  }
+
+  // Sanity check on the server connection ID in header.
+  QUICHE_DCHECK(ValidateServerConnectionId(header));
+
+  if (packet_creator_.HasPendingFrames()) {
+    // Incoming packets may change a queued ACK frame.
+    const std::string error_details =
+        "Pending frames must be serialized before incoming packets are "
+        "processed.";
+    QUIC_BUG(quic_pending_frames_not_serialized)
+        << error_details << ", received header: " << header;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  return true;
+}
+
+void QuicConnection::OnSuccessfulVersionNegotiation() {
+  visitor_->OnSuccessfulVersionNegotiation(version());
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnSuccessfulVersionNegotiation(version());
+  }
+}
+
+void QuicConnection::OnSuccessfulMigration(bool is_port_change) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  if (IsPathDegrading()) {
+    // If path was previously degrading, and migration is successful after
+    // probing, restart the path degrading and blackhole detection.
+    OnForwardProgressMade();
+  }
+  if (IsAlternativePath(default_path_.self_address,
+                        default_path_.peer_address)) {
+    // Reset alternative path state even if it is still under validation.
+    alternative_path_.Clear();
+  }
+  // TODO(b/159074035): notify SentPacketManger with RTT sample from probing.
+  if (version().HasIetfQuicFrames() && !is_port_change) {
+    sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+  }
+}
+
+void QuicConnection::OnTransportParametersSent(
+    const TransportParameters& transport_parameters) const {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnTransportParametersSent(transport_parameters);
+  }
+}
+
+void QuicConnection::OnTransportParametersReceived(
+    const TransportParameters& transport_parameters) const {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnTransportParametersReceived(transport_parameters);
+  }
+}
+
+void QuicConnection::OnTransportParametersResumed(
+    const TransportParameters& transport_parameters) const {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnTransportParametersResumed(transport_parameters);
+  }
+}
+
+bool QuicConnection::HasPendingAcks() const {
+  return ack_alarm_->IsSet();
+}
+
+void QuicConnection::OnUserAgentIdKnown(const std::string& /*user_agent_id*/) {
+  sent_packet_manager_.OnUserAgentIdKnown();
+}
+
+void QuicConnection::OnDecryptedPacket(size_t /*length*/,
+                                       EncryptionLevel level) {
+  last_decrypted_packet_level_ = level;
+  last_packet_decrypted_ = true;
+  if (level == ENCRYPTION_FORWARD_SECURE &&
+      !have_decrypted_first_one_rtt_packet_) {
+    have_decrypted_first_one_rtt_packet_ = true;
+    if (version().UsesTls() && perspective_ == Perspective::IS_SERVER) {
+      // Servers MAY temporarily retain 0-RTT keys to allow decrypting reordered
+      // packets without requiring their contents to be retransmitted with 1-RTT
+      // keys. After receiving a 1-RTT packet, servers MUST discard 0-RTT keys
+      // within a short time; the RECOMMENDED time period is three times the
+      // Probe Timeout.
+      // https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-discarding-0-rtt-keys
+      discard_zero_rtt_decryption_keys_alarm_->Set(
+          clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
+    }
+  }
+  if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
+      (last_decrypted_packet_level_ == ENCRYPTION_HANDSHAKE ||
+       last_decrypted_packet_level_ == ENCRYPTION_FORWARD_SECURE)) {
+    // Address is validated by successfully processing a HANDSHAKE or 1-RTT
+    // packet.
+    default_path_.validated = true;
+    stats_.address_validated_via_decrypting_packet = true;
+  }
+  idle_network_detector_.OnPacketReceived(
+      last_received_packet_info_.receipt_time);
+
+  visitor_->OnPacketDecrypted(level);
+}
+
+QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
+    const {
+  // By default, the connection is not proxied, and the effective peer address
+  // is the packet's source address, i.e. the direct peer address.
+  return last_received_packet_info_.source_address;
+}
+
+bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPacketHeader(header, clock_->ApproximateNow(),
+                                   last_decrypted_packet_level_);
+  }
+
+  // Will be decremented below if we fall through to return true.
+  ++stats_.packets_dropped;
+
+  if (!ProcessValidatedPacket(header)) {
+    return false;
+  }
+
+  // Initialize the current packet content state.
+  most_recent_frame_type_ = NUM_FRAME_TYPES;
+  current_packet_content_ = NO_FRAMES_RECEIVED;
+  is_current_packet_connectivity_probing_ = false;
+  has_path_challenge_in_current_packet_ = false;
+  current_effective_peer_migration_type_ = NO_CHANGE;
+
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (!GetLargestReceivedPacket().IsInitialized() ||
+        header.packet_number > GetLargestReceivedPacket()) {
+      // Update direct_peer_address_ and default path peer_address immediately
+      // for client connections.
+      // TODO(fayang): only change peer addresses in application data packet
+      // number space.
+      UpdatePeerAddress(last_received_packet_info_.source_address);
+      default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
+    }
+  } else {
+    // At server, remember the address change type of effective_peer_address
+    // in current_effective_peer_migration_type_. But this variable alone
+    // doesn't necessarily starts a migration. A migration will be started
+    // later, once the current packet is confirmed to meet the following
+    // conditions:
+    // 1) current_effective_peer_migration_type_ is not NO_CHANGE.
+    // 2) The current packet is not a connectivity probing.
+    // 3) The current packet is not reordered, i.e. its packet number is the
+    //    largest of this connection so far.
+    // Once the above conditions are confirmed, a new migration will start
+    // even if there is an active migration underway.
+    current_effective_peer_migration_type_ =
+        QuicUtils::DetermineAddressChangeType(
+            default_path_.peer_address,
+            GetEffectivePeerAddressFromCurrentPacket());
+
+    if (connection_migration_use_new_cid_) {
+      auto effective_peer_address = GetEffectivePeerAddressFromCurrentPacket();
+      // Since server does not send new connection ID to client before handshake
+      // completion and source connection ID is omitted in short header packet,
+      // the server_connection_id on PathState on the server side does not
+      // affect the packets server writes after handshake completion. On the
+      // other hand, it is still desirable to have the "correct" server
+      // connection ID set on path.
+      // 1) If client uses 1 unique server connection ID per path and the packet
+      // is received from an existing path, then
+      // last_packet_destination_connection_id_ will always be the same as the
+      // server connection ID on path. Server side will maintain the 1-to-1
+      // mapping from server connection ID to path.
+      // 2) If client uses multiple server connection IDs on the same path,
+      // compared to the server_connection_id on path,
+      // last_packet_destination_connection_id_ has the advantage that it is
+      // still present in the session map since the packet can be routed here
+      // regardless of packet reordering.
+      if (IsDefaultPath(last_received_packet_info_.destination_address,
+                        effective_peer_address)) {
+        default_path_.server_connection_id =
+            last_packet_destination_connection_id_;
+      } else if (IsAlternativePath(
+                     last_received_packet_info_.destination_address,
+                     effective_peer_address)) {
+        alternative_path_.server_connection_id =
+            last_packet_destination_connection_id_;
+      }
+    }
+
+    if (last_packet_destination_connection_id_ !=
+            default_path_.server_connection_id &&
+        (!original_destination_connection_id_.has_value() ||
+         last_packet_destination_connection_id_ !=
+             *original_destination_connection_id_)) {
+      QUIC_CODE_COUNT(quic_connection_id_change);
+    }
+
+    QUIC_DLOG_IF(INFO, current_effective_peer_migration_type_ != NO_CHANGE)
+        << ENDPOINT << "Effective peer's ip:port changed from "
+        << default_path_.peer_address.ToString() << " to "
+        << GetEffectivePeerAddressFromCurrentPacket().ToString()
+        << ", active_effective_peer_migration_type is "
+        << active_effective_peer_migration_type_;
+  }
+
+  --stats_.packets_dropped;
+  QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
+  last_header_ = header;
+  if (!stats_.first_decrypted_packet.IsInitialized()) {
+    stats_.first_decrypted_packet = last_header_.packet_number;
+  }
+
+  // Record packet receipt to populate ack info before processing stream
+  // frames, since the processing may result in sending a bundled ack.
+  QuicTime receipt_time = idle_network_detector_.time_of_last_received_packet();
+  if (SupportsMultiplePacketNumberSpaces()) {
+    receipt_time = last_received_packet_info_.receipt_time;
+  }
+  uber_received_packet_manager_.RecordPacketReceived(
+      last_decrypted_packet_level_, last_header_, receipt_time);
+  if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
+      !header.retry_token.empty() &&
+      visitor_->ValidateToken(header.retry_token)) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Address validated via token.";
+    QUIC_CODE_COUNT(quic_address_validated_via_token);
+    default_path_.validated = true;
+    stats_.address_validated_via_token = true;
+  }
+  QUICHE_DCHECK(connected_);
+  return true;
+}
+
+bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_3, !connected_)
+      << "Processing STREAM frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a stream frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(STREAM_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStreamFrame(frame);
+  }
+  if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
+      last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
+    if (MaybeConsiderAsMemoryCorruption(frame)) {
+      CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
+                      "Received crypto frame on non crypto stream.",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return false;
+    }
+
+    QUIC_PEER_BUG(quic_peer_bug_10511_6)
+        << ENDPOINT << "Received an unencrypted data frame: closing connection"
+        << " packet_number:" << last_header_.packet_number
+        << " stream_id:" << frame.stream_id
+        << " received_packets:" << ack_frame();
+    CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
+                    "Unencrypted stream data seen.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  // TODO(fayang): Consider moving UpdatePacketContent and
+  // MaybeUpdateAckTimeout to a stand-alone function instead of calling them for
+  // all frames.
+  MaybeUpdateAckTimeout();
+  visitor_->OnStreamFrame(frame);
+  stats_.stream_bytes_received += frame.data_length;
+  consecutive_retransmittable_on_wire_ping_count_ = 0;
+  return connected_;
+}
+
+bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_4, !connected_)
+      << "Processing CRYPTO frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a CRYPTO frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(CRYPTO_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnCryptoFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  visitor_->OnCryptoFrame(frame);
+  return connected_;
+}
+
+bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
+                                     QuicTime::Delta ack_delay_time) {
+  QUIC_BUG_IF(quic_bug_12714_5, !connected_)
+      << "Processing ACK frame start when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  if (processing_ack_frame_) {
+    CloseConnection(QUIC_INVALID_ACK_DATA,
+                    "Received a new ack while processing an ack frame.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  // Since an ack frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(ACK_FRAME)) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT
+                << "OnAckFrameStart, largest_acked: " << largest_acked;
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+
+  if (!sent_packet_manager_.GetLargestSentPacket().IsInitialized() ||
+      largest_acked > sent_packet_manager_.GetLargestSentPacket()) {
+    QUIC_DLOG(WARNING) << ENDPOINT
+                       << "Peer's observed unsent packet:" << largest_acked
+                       << " vs " << sent_packet_manager_.GetLargestSentPacket()
+                       << ". SupportsMultiplePacketNumberSpaces():"
+                       << SupportsMultiplePacketNumberSpaces()
+                       << ", last_decrypted_packet_level_:"
+                       << last_decrypted_packet_level_;
+    // We got an ack for data we have not sent.
+    CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  processing_ack_frame_ = true;
+  sent_packet_manager_.OnAckFrameStart(
+      largest_acked, ack_delay_time,
+      idle_network_detector_.time_of_last_received_packet());
+  return true;
+}
+
+bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
+  QUIC_BUG_IF(quic_bug_12714_6, !connected_)
+      << "Processing ACK frame range when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+
+  sent_packet_manager_.OnAckRange(start, end);
+  return true;
+}
+
+bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
+                                    QuicTime timestamp) {
+  QUIC_BUG_IF(quic_bug_10511_7, !connected_)
+      << "Processing ACK frame time stamp when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
+                << timestamp.ToDebuggingValue() << ")";
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+
+  sent_packet_manager_.OnAckTimestamp(packet_number, timestamp);
+  return true;
+}
+
+bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
+  QUIC_BUG_IF(quic_bug_12714_7, !connected_)
+      << "Processing ACK frame end when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
+
+  if (GetLargestReceivedPacketWithAck().IsInitialized() &&
+      last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
+    return true;
+  }
+  const bool one_rtt_packet_was_acked =
+      sent_packet_manager_.one_rtt_packet_acked();
+  const bool zero_rtt_packet_was_acked =
+      sent_packet_manager_.zero_rtt_packet_acked();
+  const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
+      idle_network_detector_.time_of_last_received_packet(),
+      last_header_.packet_number, last_decrypted_packet_level_);
+  if (ack_result != PACKETS_NEWLY_ACKED &&
+      ack_result != NO_PACKETS_NEWLY_ACKED) {
+    // Error occurred (e.g., this ACK tries to ack packets in wrong packet
+    // number space), and this would cause the connection to be closed.
+    QUIC_DLOG(ERROR) << ENDPOINT
+                     << "Error occurred when processing an ACK frame: "
+                     << QuicUtils::AckResultToString(ack_result);
+    return false;
+  }
+  if (SupportsMultiplePacketNumberSpaces() && !one_rtt_packet_was_acked &&
+      sent_packet_manager_.one_rtt_packet_acked()) {
+    visitor_->OnOneRttPacketAcknowledged();
+  }
+  if (debug_visitor_ != nullptr && version().UsesTls() &&
+      !zero_rtt_packet_was_acked &&
+      sent_packet_manager_.zero_rtt_packet_acked()) {
+    debug_visitor_->OnZeroRttPacketAcked();
+  }
+  // Cancel the send alarm because new packets likely have been acked, which
+  // may change the congestion window and/or pacing rate.  Canceling the alarm
+  // causes CanWrite to recalculate the next send time.
+  if (send_alarm_->IsSet()) {
+    send_alarm_->Cancel();
+  }
+  if (supports_release_time_) {
+    // Update pace time into future because smoothed RTT is likely updated.
+    UpdateReleaseTimeIntoFuture();
+  }
+  SetLargestReceivedPacketWithAck(last_header_.packet_number);
+  // If the incoming ack's packets set expresses missing packets: peer is still
+  // waiting for a packet lower than a packet that we are no longer planning to
+  // send.
+  // If the incoming ack's packets set expresses received packets: peer is still
+  // acking packets which we never care about.
+  // Send an ack to raise the high water mark.
+  const bool send_stop_waiting =
+      no_stop_waiting_frames_ ? false : GetLeastUnacked() > start;
+  PostProcessAfterAckFrame(send_stop_waiting,
+                           ack_result == PACKETS_NEWLY_ACKED);
+  processing_ack_frame_ = false;
+  return connected_;
+}
+
+bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_8, !connected_)
+      << "Processing STOP_WAITING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a stop waiting frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(STOP_WAITING_FRAME)) {
+    return false;
+  }
+
+  if (no_stop_waiting_frames_) {
+    return true;
+  }
+  if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Received an old stop waiting frame: ignoring";
+    return true;
+  }
+
+  const char* error = ValidateStopWaitingFrame(frame);
+  if (error != nullptr) {
+    CloseConnection(QUIC_INVALID_STOP_WAITING_DATA, error,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStopWaitingFrame(frame);
+  }
+
+  largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
+  uber_received_packet_manager_.DontWaitForPacketsBefore(
+      last_decrypted_packet_level_, frame.least_unacked);
+  return connected_;
+}
+
+bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_9, !connected_)
+      << "Processing PADDING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(PADDING_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPaddingFrame(frame);
+  }
+  return true;
+}
+
+bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_10, !connected_)
+      << "Processing PING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(PING_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    QuicTime::Delta ping_received_delay = QuicTime::Delta::Zero();
+    const QuicTime now = clock_->ApproximateNow();
+    if (now > stats_.connection_creation_time) {
+      ping_received_delay = now - stats_.connection_creation_time;
+    }
+    debug_visitor_->OnPingFrame(frame, ping_received_delay);
+  }
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+const char* QuicConnection::ValidateStopWaitingFrame(
+    const QuicStopWaitingFrame& stop_waiting) {
+  const QuicPacketNumber peer_least_packet_awaiting_ack =
+      uber_received_packet_manager_.peer_least_packet_awaiting_ack();
+  if (peer_least_packet_awaiting_ack.IsInitialized() &&
+      stop_waiting.least_unacked < peer_least_packet_awaiting_ack) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
+                     << stop_waiting.least_unacked << " vs "
+                     << peer_least_packet_awaiting_ack;
+    // We never process old ack frames, so this number should only increase.
+    return "Least unacked too small.";
+  }
+
+  if (stop_waiting.least_unacked > last_header_.packet_number) {
+    QUIC_DLOG(ERROR) << ENDPOINT
+                     << "Peer sent least_unacked:" << stop_waiting.least_unacked
+                     << " greater than the enclosing packet number:"
+                     << last_header_.packet_number;
+    return "Least unacked too large.";
+  }
+
+  return nullptr;
+}
+
+bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_11, !connected_)
+      << "Processing RST_STREAM frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a reset stream frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(RST_STREAM_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnRstStreamFrame(frame);
+  }
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "RST_STREAM_FRAME received for stream: " << frame.stream_id
+                  << " with error: "
+                  << QuicRstStreamErrorCodeToString(frame.error_code);
+  MaybeUpdateAckTimeout();
+  visitor_->OnRstStream(frame);
+  return connected_;
+}
+
+bool QuicConnection::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_12, !connected_)
+      << "Processing STOP_SENDING frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a reset stream frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(STOP_SENDING_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStopSendingFrame(frame);
+  }
+
+  QUIC_DLOG(INFO) << ENDPOINT << "STOP_SENDING frame received for stream: "
+                  << frame.stream_id
+                  << " with error: " << frame.ietf_error_code;
+  MaybeUpdateAckTimeout();
+  visitor_->OnStopSendingFrame(frame);
+  return connected_;
+}
+
+class ReversePathValidationContext : public QuicPathValidationContext {
+ public:
+  ReversePathValidationContext(const QuicSocketAddress& self_address,
+                               const QuicSocketAddress& peer_address,
+                               const QuicSocketAddress& effective_peer_address,
+                               QuicConnection* connection)
+      : QuicPathValidationContext(self_address,
+                                  peer_address,
+                                  effective_peer_address),
+        connection_(connection) {}
+
+  QuicPacketWriter* WriterToUse() override { return connection_->writer(); }
+
+ private:
+  QuicConnection* connection_;
+};
+
+bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_8, !connected_)
+      << "Processing PATH_CHALLENGE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (has_path_challenge_in_current_packet_) {
+    // Only respond to the 1st PATH_CHALLENGE in the packet.
+    return true;
+  }
+  if (!validate_client_addresses_) {
+    return OnPathChallengeFrameInternal(frame);
+  }
+  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 1, 6);
+  {
+    // TODO(danzh) inline OnPathChallengeFrameInternal() once
+    // validate_client_addresses_ is deprecated.
+    if (!OnPathChallengeFrameInternal(frame)) {
+      return false;
+    }
+  }
+  return connected_;
+}
+
+bool QuicConnection::OnPathChallengeFrameInternal(
+    const QuicPathChallengeFrame& frame) {
+  should_proactively_validate_peer_address_on_path_challenge_ = false;
+  // UpdatePacketContent() may start reverse path validation.
+  if (!UpdatePacketContent(PATH_CHALLENGE_FRAME)) {
+    return false;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPathChallengeFrame(frame);
+  }
+
+  const QuicSocketAddress current_effective_peer_address =
+      GetEffectivePeerAddressFromCurrentPacket();
+  QuicConnectionId client_cid, server_cid;
+  FindOnPathConnectionIds(last_received_packet_info_.destination_address,
+                          current_effective_peer_address, &client_cid,
+                          &server_cid);
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &packet_creator_, last_received_packet_info_.source_address, client_cid,
+      server_cid, connection_migration_use_new_cid_);
+  if (should_proactively_validate_peer_address_on_path_challenge_) {
+    // Conditions to proactively validate peer address:
+    // The perspective is server
+    // The PATH_CHALLENGE is received on an unvalidated alternative path.
+    // The connection isn't validating migrated peer address, which is of
+    // higher prority.
+    QUIC_DVLOG(1) << "Proactively validate the effective peer address "
+                  << current_effective_peer_address;
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 2, 6);
+    ValidatePath(std::make_unique<ReversePathValidationContext>(
+                     default_path_.self_address,
+                     last_received_packet_info_.source_address,
+                     current_effective_peer_address, this),
+                 std::make_unique<ReversePathValidationResultDelegate>(
+                     this, peer_address()));
+  }
+  has_path_challenge_in_current_packet_ = true;
+  MaybeUpdateAckTimeout();
+  // Queue or send PATH_RESPONSE. Send PATH_RESPONSE to the source address of
+  // the current incoming packet, even if it's not the default path or the
+  // alternative path.
+  if (!SendPathResponse(frame.data_buffer,
+                        last_received_packet_info_.source_address,
+                        current_effective_peer_address)) {
+    QUIC_CODE_COUNT(quic_failed_to_send_path_response);
+  }
+  // TODO(b/150095588): change the stats to
+  // num_valid_path_challenge_received.
+  ++stats_.num_connectivity_probing_received;
+
+  // SendPathResponse() might cause connection to be closed.
+  return connected_;
+}
+
+bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_9, !connected_)
+      << "Processing PATH_RESPONSE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(PATH_RESPONSE_FRAME)) {
+    return false;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPathResponseFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  if (use_path_validator_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 1, 4);
+    path_validator_.OnPathResponse(
+        frame.data_buffer, last_received_packet_info_.destination_address);
+  } else {
+    if (!transmitted_connectivity_probe_payload_ ||
+        *transmitted_connectivity_probe_payload_ != frame.data_buffer) {
+      // Is not for the probe we sent, ignore it.
+      return true;
+    }
+    // Have received the matching PATH RESPONSE, saved payload no longer valid.
+    transmitted_connectivity_probe_payload_ = nullptr;
+  }
+  return connected_;
+}
+
+bool QuicConnection::OnConnectionCloseFrame(
+    const QuicConnectionCloseFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_10, !connected_)
+      << "Processing CONNECTION_CLOSE frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a connection close frame was received, this is not a connectivity
+  // probe. A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(CONNECTION_CLOSE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnConnectionCloseFrame(frame);
+  }
+  switch (frame.close_type) {
+    case GOOGLE_QUIC_CONNECTION_CLOSE:
+      QUIC_DLOG(INFO) << ENDPOINT << "Received ConnectionClose for connection: "
+                      << connection_id() << ", with error: "
+                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
+                      << frame.error_details << ")";
+      break;
+    case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "Received Transport ConnectionClose for connection: "
+                      << connection_id() << ", with error: "
+                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
+                      << frame.error_details << ")"
+                      << ", transport error code: "
+                      << QuicIetfTransportErrorCodeString(
+                             static_cast<QuicIetfTransportErrorCodes>(
+                                 frame.wire_error_code))
+                      << ", error frame type: "
+                      << frame.transport_close_frame_type;
+      break;
+    case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "Received Application ConnectionClose for connection: "
+                      << connection_id() << ", with error: "
+                      << QuicErrorCodeToString(frame.quic_error_code) << " ("
+                      << frame.error_details << ")"
+                      << ", application error code: " << frame.wire_error_code;
+      break;
+  }
+
+  if (frame.quic_error_code == QUIC_BAD_MULTIPATH_FLAG) {
+    QUIC_LOG_FIRST_N(ERROR, 10) << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
+                                << " last_received_header: " << last_header_
+                                << " encryption_level: " << encryption_level_;
+  }
+  TearDownLocalConnectionState(frame, ConnectionCloseSource::FROM_PEER);
+  return connected_;
+}
+
+bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_13, !connected_)
+      << "Processing MAX_STREAMS frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(MAX_STREAMS_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnMaxStreamsFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  return visitor_->OnMaxStreamsFrame(frame) && connected_;
+}
+
+bool QuicConnection::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_11, !connected_)
+      << "Processing STREAMS_BLOCKED frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(STREAMS_BLOCKED_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnStreamsBlockedFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  return visitor_->OnStreamsBlockedFrame(frame) && connected_;
+}
+
+bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_14, !connected_)
+      << "Processing GOAWAY frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a go away frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(GOAWAY_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnGoAwayFrame(frame);
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
+                  << frame.last_good_stream_id
+                  << " and error: " << QuicErrorCodeToString(frame.error_code)
+                  << " and reason: " << frame.reason_phrase;
+  MaybeUpdateAckTimeout();
+  visitor_->OnGoAway(frame);
+  return connected_;
+}
+
+bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_12, !connected_)
+      << "Processing WINDOW_UPDATE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a window update frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(WINDOW_UPDATE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnWindowUpdateFrame(
+        frame, idle_network_detector_.time_of_last_received_packet());
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "WINDOW_UPDATE_FRAME received " << frame;
+  MaybeUpdateAckTimeout();
+  visitor_->OnWindowUpdateFrame(frame);
+  return connected_;
+}
+
+void QuicConnection::OnClientConnectionIdAvailable() {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
+  if (!peer_issued_cid_manager_->HasUnusedConnectionId()) {
+    return;
+  }
+  if (default_path_.client_connection_id.IsEmpty()) {
+    // Count client connection ID patched onto the default path.
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 3,
+                                 6);
+    const QuicConnectionIdData* unused_cid_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
+                  << unused_cid_data->connection_id << " to default path";
+    default_path_.client_connection_id = unused_cid_data->connection_id;
+    default_path_.stateless_reset_token =
+        unused_cid_data->stateless_reset_token;
+    QUICHE_DCHECK(!packet_creator_.HasPendingFrames());
+    QUICHE_DCHECK(packet_creator_.GetDestinationConnectionId().IsEmpty());
+    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+    return;
+  }
+  if (alternative_path_.peer_address.IsInitialized() &&
+      alternative_path_.client_connection_id.IsEmpty()) {
+    // Count client connection ID patched onto the alternative path.
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 4,
+                                 6);
+    const QuicConnectionIdData* unused_cid_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    QUIC_DVLOG(1) << ENDPOINT << "Patch connection ID "
+                  << unused_cid_data->connection_id << " to alternative path";
+    alternative_path_.client_connection_id = unused_cid_data->connection_id;
+    alternative_path_.stateless_reset_token =
+        unused_cid_data->stateless_reset_token;
+  }
+}
+
+bool QuicConnection::ShouldSetRetransmissionAlarmOnPacketSent(
+    bool in_flight, EncryptionLevel level) const {
+  QUICHE_DCHECK(!sent_packet_manager_.simplify_set_retransmission_alarm());
+  if (!retransmission_alarm_->IsSet()) {
+    return true;
+  }
+  if (!in_flight) {
+    return false;
+  }
+
+  if (!SupportsMultiplePacketNumberSpaces()) {
+    return true;
+  }
+  // Before handshake gets confirmed, do not re-arm PTO timer on application
+  // data. Think about this scenario: on the client side, the CHLO gets
+  // acknowledged and the SHLO is not received yet. The PTO alarm is set when
+  // the CHLO acknowledge is received (and there is no in flight INITIAL
+  // packet). Re-arming PTO alarm on 0-RTT packet would keep postponing the PTO
+  // alarm.
+  return IsHandshakeConfirmed() || level == ENCRYPTION_INITIAL ||
+         level == ENCRYPTION_HANDSHAKE;
+}
+
+bool QuicConnection::OnNewConnectionIdFrameInner(
+    const QuicNewConnectionIdFrame& frame) {
+  if (peer_issued_cid_manager_ == nullptr) {
+    CloseConnection(
+        IETF_QUIC_PROTOCOL_VIOLATION,
+        "Receives NEW_CONNECTION_ID while peer uses zero length connection ID",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  std::string error_detail;
+  QuicErrorCode error =
+      peer_issued_cid_manager_->OnNewConnectionIdFrame(frame, &error_detail);
+  if (error != QUIC_NO_ERROR) {
+    CloseConnection(error, error_detail,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  if (perspective_ == Perspective::IS_SERVER) {
+    OnClientConnectionIdAvailable();
+  }
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+bool QuicConnection::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& frame) {
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  QUIC_BUG_IF(quic_bug_10511_13, !connected_)
+      << "Processing NEW_CONNECTION_ID frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(NEW_CONNECTION_ID_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnNewConnectionIdFrame(frame);
+  }
+  return OnNewConnectionIdFrameInner(frame);
+}
+
+bool QuicConnection::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& frame) {
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  QUIC_BUG_IF(quic_bug_10511_14, !connected_)
+      << "Processing RETIRE_CONNECTION_ID frame when "
+         "connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnRetireConnectionIdFrame(frame);
+  }
+  if (!connection_migration_use_new_cid_) {
+    // Do not respond to RetireConnectionId frame.
+    return true;
+  }
+  if (self_issued_cid_manager_ == nullptr) {
+    CloseConnection(
+        IETF_QUIC_PROTOCOL_VIOLATION,
+        "Receives RETIRE_CONNECTION_ID while new connection ID is never issued",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  std::string error_detail;
+  QuicErrorCode error = self_issued_cid_manager_->OnRetireConnectionIdFrame(
+      frame, sent_packet_manager_.GetPtoDelay(), &error_detail);
+  if (error != QUIC_NO_ERROR) {
+    CloseConnection(error, error_detail,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  // Count successfully received RETIRE_CONNECTION_ID frames.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 5, 6);
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_15, !connected_)
+      << "Processing NEW_TOKEN frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!UpdatePacketContent(NEW_TOKEN_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnNewTokenFrame(frame);
+  }
+  if (perspective_ == Perspective::IS_SERVER) {
+    CloseConnection(QUIC_INVALID_NEW_TOKEN, "Server received new token frame.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  // NEW_TOKEN frame should insitgate ACKs.
+  MaybeUpdateAckTimeout();
+  visitor_->OnNewTokenReceived(frame.token);
+  return true;
+}
+
+bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_16, !connected_)
+      << "Processing MESSAGE frame when connection is closed. Last frame: "
+      << most_recent_frame_type_;
+
+  // Since a message frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(MESSAGE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnMessageFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  visitor_->OnMessageReceived(
+      absl::string_view(frame.data, frame.message_length));
+  return connected_;
+}
+
+bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_15, !connected_)
+      << "Processing HANDSHAKE_DONE frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (!version().UsesTls()) {
+    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
+                    "Handshake done frame is unsupported",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER) {
+    CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
+                    "Server received handshake done frame.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+
+  // Since a handshake done frame was received, this is not a connectivity
+  // probe. A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(HANDSHAKE_DONE_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnHandshakeDoneFrame(frame);
+  }
+  MaybeUpdateAckTimeout();
+  visitor_->OnHandshakeDoneReceived();
+  return connected_;
+}
+
+bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) {
+  QUIC_BUG_IF(quic_bug_10511_16, !connected_)
+      << "Processing ACK_FREQUENCY frame when connection "
+         "is closed. Last frame: "
+      << most_recent_frame_type_;
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnAckFrequencyFrame(frame);
+  }
+  if (!UpdatePacketContent(ACK_FREQUENCY_FRAME)) {
+    return false;
+  }
+
+  if (!can_receive_ack_frequency_frame_) {
+    QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame.";
+    return false;
+  }
+  if (auto packet_number_space =
+          QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_) ==
+          APPLICATION_DATA) {
+    uber_received_packet_manager_.OnAckFrequencyFrame(frame);
+  } else {
+    QUIC_LOG_EVERY_N_SEC(ERROR, 120)
+        << "Get AckFrequencyFrame in packet number space "
+        << packet_number_space;
+  }
+  MaybeUpdateAckTimeout();
+  return true;
+}
+
+bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12714_17, !connected_)
+      << "Processing BLOCKED frame when connection is closed. Last frame was "
+      << most_recent_frame_type_;
+
+  // Since a blocked frame was received, this is not a connectivity probe.
+  // A probe only contains a PING and full padding.
+  if (!UpdatePacketContent(BLOCKED_FRAME)) {
+    return false;
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnBlockedFrame(frame);
+  }
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "BLOCKED_FRAME received for stream: " << frame.stream_id;
+  MaybeUpdateAckTimeout();
+  visitor_->OnBlockedFrame(frame);
+  stats_.blocked_frames_received++;
+  return connected_;
+}
+
+void QuicConnection::OnPacketComplete() {
+  // Don't do anything if this packet closed the connection.
+  if (!connected_) {
+    ClearLastFrames();
+    return;
+  }
+
+  if (IsCurrentPacketConnectivityProbing()) {
+    QUICHE_DCHECK(!version().HasIetfQuicFrames());
+    ++stats_.num_connectivity_probing_received;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Got"
+                << (SupportsMultiplePacketNumberSpaces()
+                        ? (" " + EncryptionLevelToString(
+                                     last_decrypted_packet_level_))
+                        : "")
+                << " packet " << last_header_.packet_number << " for "
+                << GetServerConnectionIdAsRecipient(last_header_, perspective_);
+
+  QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
+      << ENDPOINT << "Received a padded PING packet. is_probing: "
+      << IsCurrentPacketConnectivityProbing();
+
+  if (!version().HasIetfQuicFrames()) {
+    MaybeRespondToConnectivityProbingOrMigration();
+  }
+
+  current_effective_peer_migration_type_ = NO_CHANGE;
+
+  // For IETF QUIC, it is guaranteed that TLS will give connection the
+  // corresponding write key before read key. In other words, connection should
+  // never process a packet while an ACK for it cannot be encrypted.
+  if (!should_last_packet_instigate_acks_) {
+    uber_received_packet_manager_.MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks_, last_decrypted_packet_level_,
+        last_header_.packet_number, last_received_packet_info_.receipt_time,
+        clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+  }
+
+  ClearLastFrames();
+  CloseIfTooManyOutstandingSentPackets();
+}
+
+void QuicConnection::MaybeRespondToConnectivityProbingOrMigration() {
+  QUICHE_DCHECK(!version().HasIetfQuicFrames());
+  if (IsCurrentPacketConnectivityProbing()) {
+    visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
+                               last_received_packet_info_.source_address,
+                               /*is_connectivity_probe=*/true);
+    return;
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    // This node is a client, notify that a speculative connectivity probing
+    // packet has been received anyway.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received a speculative connectivity probing packet for "
+                  << GetServerConnectionIdAsRecipient(last_header_,
+                                                      perspective_)
+                  << " from ip:port: "
+                  << last_received_packet_info_.source_address.ToString()
+                  << " to ip:port: "
+                  << last_received_packet_info_.destination_address.ToString();
+    visitor_->OnPacketReceived(last_received_packet_info_.destination_address,
+                               last_received_packet_info_.source_address,
+                               /*is_connectivity_probe=*/false);
+    return;
+  }
+}
+
+bool QuicConnection::IsValidStatelessResetToken(
+    const StatelessResetToken& token) const {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  return default_path_.stateless_reset_token.has_value() &&
+         QuicUtils::AreStatelessResetTokensEqual(
+             token, *default_path_.stateless_reset_token);
+}
+
+void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
+    const QuicIetfStatelessResetPacket& /*packet*/) {
+  // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
+  // debug_visitor_.
+  QUICHE_DCHECK(version().HasIetfInvariantHeader());
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+
+  if (use_path_validator_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 4, 4);
+    if (!IsDefaultPath(last_received_packet_info_.destination_address,
+                       last_received_packet_info_.source_address)) {
+      // This packet is received on a probing path. Do not close connection.
+      if (IsAlternativePath(last_received_packet_info_.destination_address,
+                            GetEffectivePeerAddressFromCurrentPacket())) {
+        QUIC_BUG_IF(quic_bug_12714_18, alternative_path_.validated)
+            << "STATELESS_RESET received on alternate path after it's "
+               "validated.";
+        path_validator_.CancelPathValidation();
+      } else {
+        QUIC_BUG(quic_bug_10511_17)
+            << "Received Stateless Reset on unknown socket.";
+      }
+      return;
+    }
+  } else if (!visitor_->ValidateStatelessReset(
+                 last_received_packet_info_.destination_address,
+                 last_received_packet_info_.source_address)) {
+    // This packet is received on a probing path. Do not close connection.
+    return;
+  }
+
+  const std::string error_details = "Received stateless reset.";
+  QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
+  TearDownLocalConnectionState(QUIC_PUBLIC_RESET, NO_IETF_QUIC_ERROR,
+                               error_details, ConnectionCloseSource::FROM_PEER);
+}
+
+void QuicConnection::OnKeyUpdate(KeyUpdateReason reason) {
+  QUICHE_DCHECK(support_key_update_for_connection_);
+  QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated for " << reason;
+
+  lowest_packet_sent_in_current_key_phase_.Clear();
+  stats_.key_update_count++;
+
+  // If another key update triggers while the previous
+  // discard_previous_one_rtt_keys_alarm_ hasn't fired yet, cancel it since the
+  // old keys would already be discarded.
+  discard_previous_one_rtt_keys_alarm_->Cancel();
+
+  visitor_->OnKeyUpdate(reason);
+}
+
+void QuicConnection::OnDecryptedFirstPacketInKeyPhase() {
+  QUIC_DLOG(INFO) << ENDPOINT << "OnDecryptedFirstPacketInKeyPhase";
+  // An endpoint SHOULD retain old read keys for no more than three times the
+  // PTO after having received a packet protected using the new keys. After this
+  // period, old read keys and their corresponding secrets SHOULD be discarded.
+  //
+  // Note that this will cause an unnecessary
+  // discard_previous_one_rtt_keys_alarm_ on the first packet in the 1RTT
+  // encryption level, but this is harmless.
+  discard_previous_one_rtt_keys_alarm_->Set(
+      clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay() * 3);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicConnection::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  QUIC_DLOG(INFO) << ENDPOINT << "AdvanceKeysAndCreateCurrentOneRttDecrypter";
+  return visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter> QuicConnection::CreateCurrentOneRttEncrypter() {
+  QUIC_DLOG(INFO) << ENDPOINT << "CreateCurrentOneRttEncrypter";
+  return visitor_->CreateCurrentOneRttEncrypter();
+}
+
+void QuicConnection::ClearLastFrames() {
+  should_last_packet_instigate_acks_ = false;
+}
+
+void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
+  // This occurs if we don't discard old packets we've seen fast enough. It's
+  // possible largest observed is less than leaset unacked.
+  const bool should_close =
+      sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
+      sent_packet_manager_.GetLargestSentPacket() >
+          sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_;
+
+  if (should_close) {
+    CloseConnection(
+        QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
+        absl::StrCat("More than ", max_tracked_packets_,
+                     " outstanding, least_unacked: ",
+                     sent_packet_manager_.GetLeastUnacked().ToUint64(),
+                     ", packets_processed: ", stats_.packets_processed,
+                     ", last_decrypted_packet_level: ",
+                     EncryptionLevelToString(last_decrypted_packet_level_)),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+}
+
+const QuicFrame QuicConnection::GetUpdatedAckFrame() {
+  QUICHE_DCHECK(!uber_received_packet_manager_.IsAckFrameEmpty(
+      QuicUtils::GetPacketNumberSpace(encryption_level_)))
+      << "Try to retrieve an empty ACK frame";
+  return uber_received_packet_manager_.GetUpdatedAckFrame(
+      QuicUtils::GetPacketNumberSpace(encryption_level_),
+      clock_->ApproximateNow());
+}
+
+void QuicConnection::PopulateStopWaitingFrame(
+    QuicStopWaitingFrame* stop_waiting) {
+  stop_waiting->least_unacked = GetLeastUnacked();
+}
+
+QuicPacketNumber QuicConnection::GetLeastUnacked() const {
+  return sent_packet_manager_.GetLeastUnacked();
+}
+
+bool QuicConnection::HandleWriteBlocked() {
+  if (!writer_->IsWriteBlocked()) {
+    return false;
+  }
+
+  visitor_->OnWriteBlocked();
+  return true;
+}
+
+void QuicConnection::MaybeSendInResponseToPacket() {
+  if (!connected_) {
+    return;
+  }
+
+  // If the writer is blocked, don't attempt to send packets now or in the send
+  // alarm. When the writer unblocks, OnCanWrite() will be called for this
+  // connection to send.
+  if (HandleWriteBlocked()) {
+    return;
+  }
+
+  // Now that we have received an ack, we might be able to send packets which
+  // are queued locally, or drain streams which are blocked.
+  if (defer_send_in_response_to_packets_) {
+    send_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
+  } else {
+    WriteIfNotBlocked();
+  }
+}
+
+void QuicConnection::MaybeActivateLegacyVersionEncapsulation() {
+  if (!legacy_version_encapsulation_enabled_) {
+    return;
+  }
+  QUICHE_DCHECK(!legacy_version_encapsulation_in_progress_);
+  QUIC_BUG_IF(quic_bug_12714_19, !packet_creator_.CanSetMaxPacketLength())
+      << "Cannot activate Legacy Version Encapsulation mid-packet";
+  QUIC_BUG_IF(quic_bug_12714_20, coalesced_packet_.length() != 0u)
+      << "Cannot activate Legacy Version Encapsulation mid-coalesced-packet";
+  legacy_version_encapsulation_in_progress_ = true;
+  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+void QuicConnection::MaybeDisactivateLegacyVersionEncapsulation() {
+  if (!legacy_version_encapsulation_in_progress_) {
+    return;
+  }
+  // Flush any remaining packet before disactivating encapsulation.
+  packet_creator_.FlushCurrentPacket();
+  QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
+  legacy_version_encapsulation_in_progress_ = false;
+  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+
+size_t QuicConnection::SendCryptoData(EncryptionLevel level,
+                                      size_t write_length,
+                                      QuicStreamOffset offset) {
+  if (write_length == 0) {
+    QUIC_BUG(quic_bug_10511_18) << "Attempt to send empty crypto frame";
+    return 0;
+  }
+  if (level == ENCRYPTION_INITIAL) {
+    MaybeActivateLegacyVersionEncapsulation();
+  }
+  size_t consumed_length;
+  {
+    ScopedPacketFlusher flusher(this);
+    consumed_length =
+        packet_creator_.ConsumeCryptoData(level, write_length, offset);
+  }  // Added scope ensures packets are flushed before continuing.
+  MaybeDisactivateLegacyVersionEncapsulation();
+  return consumed_length;
+}
+
+QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
+                                                size_t write_length,
+                                                QuicStreamOffset offset,
+                                                StreamSendingState state) {
+  if (state == NO_FIN && write_length == 0) {
+    QUIC_BUG(quic_bug_10511_19) << "Attempt to send empty stream frame";
+    return QuicConsumedData(0, false);
+  }
+
+  if (packet_creator_.encryption_level() == ENCRYPTION_INITIAL &&
+      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    MaybeActivateLegacyVersionEncapsulation();
+  }
+  if (perspective_ == Perspective::IS_SERVER &&
+      version().CanSendCoalescedPackets() && !IsHandshakeConfirmed()) {
+    if (in_on_retransmission_time_out_ &&
+        coalesced_packet_.NumberOfPackets() == 0u) {
+      // PTO fires while handshake is not confirmed. Do not preempt handshake
+      // data with stream data.
+      QUIC_CODE_COUNT(quic_try_to_send_half_rtt_data_when_pto_fires);
+      return QuicConsumedData(0, false);
+    }
+    if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
+        coalesced_packet_.NumberOfPackets() == 1u) {
+      // Handshake is not confirmed yet, if there is only an initial packet in
+      // the coalescer, try to bundle an ENCRYPTION_HANDSHAKE packet before
+      // sending stream data.
+      sent_packet_manager_.RetransmitDataOfSpaceIfAny(HANDSHAKE_DATA);
+    }
+  }
+  QuicConsumedData consumed_data(0, false);
+  {
+    // Opportunistically bundle an ack with every outgoing packet.
+    // Particularly, we want to bundle with handshake packets since we don't
+    // know which decrypter will be used on an ack packet following a handshake
+    // packet (a handshake packet from client to server could result in a REJ or
+    // a SHLO from the server, leading to two different decrypters at the
+    // server.)
+    ScopedPacketFlusher flusher(this);
+    consumed_data =
+        packet_creator_.ConsumeData(id, write_length, offset, state);
+  }  // Added scope ensures packets are flushed before continuing.
+  MaybeDisactivateLegacyVersionEncapsulation();
+  return consumed_data;
+}
+
+bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
+  if (SupportsMultiplePacketNumberSpaces() &&
+      (encryption_level_ == ENCRYPTION_INITIAL ||
+       encryption_level_ == ENCRYPTION_HANDSHAKE) &&
+      frame.type != PING_FRAME) {
+    // Allow PING frame to be sent without APPLICATION key. For example, when
+    // anti-amplification limit is used, client needs to send something to avoid
+    // handshake deadlock.
+    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame
+                  << " at encryption level: " << encryption_level_;
+    return false;
+  }
+  ScopedPacketFlusher flusher(this);
+  const bool consumed =
+      packet_creator_.ConsumeRetransmittableControlFrame(frame);
+  if (!consumed) {
+    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
+    return false;
+  }
+  if (frame.type == PING_FRAME) {
+    // Flush PING frame immediately.
+    packet_creator_.FlushCurrentPacket();
+    stats_.ping_frames_sent++;
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnPingSent();
+    }
+  }
+  if (frame.type == BLOCKED_FRAME) {
+    stats_.blocked_frames_sent++;
+  }
+  return true;
+}
+
+void QuicConnection::OnStreamReset(QuicStreamId id,
+                                   QuicRstStreamErrorCode error) {
+  if (error == QUIC_STREAM_NO_ERROR) {
+    // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
+    // be received by the peer.
+    return;
+  }
+  // Flush stream frames of reset stream.
+  if (packet_creator_.HasPendingStreamFramesOfStream(id)) {
+    ScopedPacketFlusher flusher(this);
+    packet_creator_.FlushCurrentPacket();
+  }
+  // TODO(ianswett): Consider checking for 3 RTOs when the last stream is
+  // cancelled as well.
+}
+
+const QuicConnectionStats& QuicConnection::GetStats() {
+  const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
+
+  // Update rtt and estimated bandwidth.
+  QuicTime::Delta min_rtt = rtt_stats->min_rtt();
+  if (min_rtt.IsZero()) {
+    // If min RTT has not been set, use initial RTT instead.
+    min_rtt = rtt_stats->initial_rtt();
+  }
+  stats_.min_rtt_us = min_rtt.ToMicroseconds();
+
+  QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt();
+  stats_.srtt_us = srtt.ToMicroseconds();
+
+  stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
+  sent_packet_manager_.GetSendAlgorithm()->PopulateConnectionStats(&stats_);
+  stats_.egress_mtu = long_term_mtu_;
+  stats_.ingress_mtu = largest_received_packet_size_;
+  return stats_;
+}
+
+void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
+  QueueCoalescedPacket(packet);
+}
+
+void QuicConnection::OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                                           EncryptionLevel decryption_level,
+                                           bool has_decryption_key) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received undecryptable packet of length "
+                << packet.length() << " with"
+                << (has_decryption_key ? "" : "out") << " key at level "
+                << decryption_level
+                << " while connection is at encryption level "
+                << encryption_level_;
+  QUICHE_DCHECK(EncryptionLevelIsValid(decryption_level));
+  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
+    ++stats_.undecryptable_packets_received_before_handshake_complete;
+  }
+
+  const bool should_enqueue =
+      ShouldEnqueueUnDecryptablePacket(decryption_level, has_decryption_key);
+  if (should_enqueue) {
+    QueueUndecryptablePacket(packet, decryption_level);
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnUndecryptablePacket(decryption_level,
+                                          /*dropped=*/!should_enqueue);
+  }
+
+  if (has_decryption_key) {
+    stats_.num_failed_authentication_packets_received++;
+    if (version().UsesTls()) {
+      // Should always be non-null if has_decryption_key is true.
+      QUICHE_DCHECK(framer_.GetDecrypter(decryption_level));
+      const QuicPacketCount integrity_limit =
+          framer_.GetDecrypter(decryption_level)->GetIntegrityLimit();
+      QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD integrity limits:"
+                    << " num_failed_authentication_packets_received="
+                    << stats_.num_failed_authentication_packets_received
+                    << " integrity_limit=" << integrity_limit;
+      if (stats_.num_failed_authentication_packets_received >=
+          integrity_limit) {
+        const std::string error_details = absl::StrCat(
+            "decrypter integrity limit reached:"
+            " num_failed_authentication_packets_received=",
+            stats_.num_failed_authentication_packets_received,
+            " integrity_limit=", integrity_limit);
+        CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      }
+    }
+  }
+
+  if (version().UsesTls() && perspective_ == Perspective::IS_SERVER &&
+      decryption_level == ENCRYPTION_ZERO_RTT && !has_decryption_key &&
+      had_zero_rtt_decrypter_) {
+    QUIC_CODE_COUNT_N(
+        quic_server_received_tls_zero_rtt_packet_after_discarding_decrypter, 1,
+        3);
+    stats_
+        .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter++;
+  }
+}
+
+bool QuicConnection::ShouldEnqueueUnDecryptablePacket(
+    EncryptionLevel decryption_level, bool has_decryption_key) const {
+  if (has_decryption_key) {
+    // We already have the key for this decryption level, therefore no
+    // future keys will allow it be decrypted.
+    return false;
+  }
+  if (IsHandshakeComplete()) {
+    // We do not expect to install any further keys.
+    return false;
+  }
+  if (undecryptable_packets_.size() >= max_undecryptable_packets_) {
+    // We do not queue more than max_undecryptable_packets_ packets.
+    return false;
+  }
+  if (version().KnowsWhichDecrypterToUse() &&
+      decryption_level == ENCRYPTION_INITIAL) {
+    // When the corresponding decryption key is not available, all
+    // non-Initial packets should be buffered until the handshake is complete.
+    return false;
+  }
+  if (perspective_ == Perspective::IS_CLIENT && version().UsesTls() &&
+      decryption_level == ENCRYPTION_ZERO_RTT) {
+    // Only clients send Zero RTT packets in IETF QUIC.
+    QUIC_PEER_BUG(quic_peer_bug_client_received_zero_rtt)
+        << "Client received a Zero RTT packet, not buffering.";
+    return false;
+  }
+  return true;
+}
+
+std::string QuicConnection::UndecryptablePacketsInfo() const {
+  std::string info = absl::StrCat(
+      "num_undecryptable_packets: ", undecryptable_packets_.size(), " {");
+  for (const auto& packet : undecryptable_packets_) {
+    absl::StrAppend(&info, "[",
+                    EncryptionLevelToString(packet.encryption_level), ", ",
+                    packet.packet->length(), "]");
+  }
+  absl::StrAppend(&info, "}");
+  return info;
+}
+
+void QuicConnection::MaybeUpdatePacketCreatorMaxPacketLengthAndPadding() {
+  QuicByteCount max_packet_length = GetLimitedMaxPacketSize(long_term_mtu_);
+  if (legacy_version_encapsulation_in_progress_) {
+    QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
+    const QuicByteCount minimum_overhead =
+        QuicLegacyVersionEncapsulator::GetMinimumOverhead(
+            legacy_version_encapsulation_sni_);
+    if (max_packet_length < minimum_overhead) {
+      QUIC_BUG(quic_bug_10511_20)
+          << "Cannot apply Legacy Version Encapsulation overhead because "
+          << "max_packet_length " << max_packet_length << " < minimum_overhead "
+          << minimum_overhead;
+      legacy_version_encapsulation_in_progress_ = false;
+      legacy_version_encapsulation_enabled_ = false;
+      MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+      return;
+    }
+    max_packet_length -= minimum_overhead;
+  }
+  packet_creator_.SetMaxPacketLength(max_packet_length);
+}
+
+void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                      const QuicSocketAddress& peer_address,
+                                      const QuicReceivedPacket& packet) {
+  if (!connected_) {
+    return;
+  }
+  QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length()
+                << " bytes:" << std::endl
+                << quiche::QuicheTextUtils::HexDump(
+                       absl::string_view(packet.data(), packet.length()));
+  QUIC_BUG_IF(quic_bug_12714_21, current_packet_data_ != nullptr)
+      << "ProcessUdpPacket must not be called while processing a packet.";
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
+  }
+  last_received_packet_info_ =
+      ReceivedPacketInfo(self_address, peer_address, packet.receipt_time());
+  last_size_ = packet.length();
+  current_packet_data_ = packet.data();
+
+  if (!default_path_.self_address.IsInitialized()) {
+    default_path_.self_address = last_received_packet_info_.destination_address;
+  }
+
+  if (!direct_peer_address_.IsInitialized()) {
+    UpdatePeerAddress(last_received_packet_info_.source_address);
+  }
+
+  if (!default_path_.peer_address.IsInitialized()) {
+    const QuicSocketAddress effective_peer_addr =
+        GetEffectivePeerAddressFromCurrentPacket();
+
+    // The default path peer_address must be initialized at the beginning of the
+    // first packet processed(here). If effective_peer_addr is uninitialized,
+    // just set effective_peer_address_ to the direct peer address.
+    default_path_.peer_address = effective_peer_addr.IsInitialized()
+                                     ? effective_peer_addr
+                                     : direct_peer_address_;
+  }
+
+  stats_.bytes_received += packet.length();
+  ++stats_.packets_received;
+  if (!count_bytes_on_alternative_path_separately_) {
+    if (EnforceAntiAmplificationLimit()) {
+      default_path_.bytes_received_before_address_validation += last_size_;
+    }
+  } else if (IsDefaultPath(last_received_packet_info_.destination_address,
+                           last_received_packet_info_.source_address) &&
+             EnforceAntiAmplificationLimit()) {
+    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 1, 5);
+    last_received_packet_info_.received_bytes_counted = true;
+    default_path_.bytes_received_before_address_validation += last_size_;
+  }
+
+  // Ensure the time coming from the packet reader is within 2 minutes of now.
+  if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
+      2 * 60) {
+    QUIC_BUG(quic_bug_10511_21)
+        << "Packet receipt time:" << packet.receipt_time().ToDebuggingValue()
+        << " too far from current time:"
+        << clock_->ApproximateNow().ToDebuggingValue();
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
+                << packet.receipt_time().ToDebuggingValue() << " from peer "
+                << last_received_packet_info_.source_address;
+
+  ScopedPacketFlusher flusher(this);
+  if (!framer_.ProcessPacket(packet)) {
+    // If we are unable to decrypt this packet, it might be
+    // because the CHLO or SHLO packet was lost.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Unable to process packet.  Last packet processed: "
+                  << last_header_.packet_number;
+    current_packet_data_ = nullptr;
+    is_current_packet_connectivity_probing_ = false;
+
+    MaybeProcessCoalescedPackets();
+    return;
+  }
+
+  ++stats_.packets_processed;
+
+  QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
+      << "sent_packet_manager_.GetLargestObserved() = "
+      << sent_packet_manager_.GetLargestObserved()
+      << ", highest_packet_sent_before_effective_peer_migration_ = "
+      << highest_packet_sent_before_effective_peer_migration_;
+  if (!validate_client_addresses_ &&
+      active_effective_peer_migration_type_ != NO_CHANGE &&
+      sent_packet_manager_.GetLargestObserved().IsInitialized() &&
+      (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
+       sent_packet_manager_.GetLargestObserved() >
+           highest_packet_sent_before_effective_peer_migration_)) {
+    if (perspective_ == Perspective::IS_SERVER) {
+      OnEffectivePeerMigrationValidated();
+    }
+  }
+
+  if (!MaybeProcessCoalescedPackets()) {
+    MaybeProcessUndecryptablePackets();
+    MaybeSendInResponseToPacket();
+  }
+  SetPingAlarm();
+  RetirePeerIssuedConnectionIdsNoLongerOnPath();
+  current_packet_data_ = nullptr;
+  is_current_packet_connectivity_probing_ = false;
+}
+
+void QuicConnection::OnBlockedWriterCanWrite() {
+  writer_->SetWritable();
+  OnCanWrite();
+}
+
+void QuicConnection::OnCanWrite() {
+  if (!connected_) {
+    return;
+  }
+  if (writer_->IsWriteBlocked()) {
+    const std::string error_details =
+        "Writer is blocked while calling OnCanWrite.";
+    QUIC_BUG(quic_bug_10511_22) << ENDPOINT << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  ScopedPacketFlusher flusher(this);
+
+  WriteQueuedPackets();
+  const QuicTime ack_timeout =
+      uber_received_packet_manager_.GetEarliestAckTimeout();
+  if (ack_timeout.IsInitialized() && ack_timeout <= clock_->ApproximateNow()) {
+    // Send an ACK now because either 1) we were write blocked when we last
+    // tried to send an ACK, or 2) both ack alarm and send alarm were set to
+    // go off together.
+    if (SupportsMultiplePacketNumberSpaces()) {
+      SendAllPendingAcks();
+    } else {
+      SendAck();
+    }
+  }
+
+  // Sending queued packets may have caused the socket to become write blocked,
+  // or the congestion manager to prohibit sending.
+  if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    return;
+  }
+
+  // Tell the session it can write.
+  visitor_->OnCanWrite();
+
+  // After the visitor writes, it may have caused the socket to become write
+  // blocked or the congestion manager to prohibit sending, so check again.
+  if (visitor_->WillingAndAbleToWrite() && !send_alarm_->IsSet() &&
+      CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    // We're not write blocked, but some data wasn't written. Register for
+    // 'immediate' resumption so we'll keep writing after other connections.
+    send_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::WriteIfNotBlocked() {
+  if (framer().is_processing_packet()) {
+    QUIC_BUG(connection_write_mid_packet_processing)
+        << ENDPOINT << "Tried to write in mid of packet processing";
+    return;
+  }
+  if (!HandleWriteBlocked()) {
+    OnCanWrite();
+  }
+}
+
+void QuicConnection::MaybeClearQueuedPacketsOnPathChange() {
+  if (connection_migration_use_new_cid_ &&
+      peer_issued_cid_manager_ != nullptr && HasQueuedPackets()) {
+    // Discard packets serialized with the connection ID on the old code path.
+    // It is possible to clear queued packets only if connection ID changes.
+    // However, the case where connection ID is unchanged and queued packets are
+    // non-empty is quite rare.
+    ClearQueuedPackets();
+  }
+}
+
+void QuicConnection::ReplaceInitialServerConnectionId(
+    const QuicConnectionId& new_server_connection_id) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+  if (version().HasIetfQuicFrames()) {
+    if (new_server_connection_id.IsEmpty()) {
+      peer_issued_cid_manager_ = nullptr;
+    } else {
+      if (peer_issued_cid_manager_ != nullptr) {
+        QUIC_BUG_IF(quic_bug_12714_22,
+                    !peer_issued_cid_manager_->IsConnectionIdActive(
+                        default_path_.server_connection_id))
+            << "Connection ID replaced header is no longer active. old id: "
+            << default_path_.server_connection_id
+            << " new_id: " << new_server_connection_id;
+        peer_issued_cid_manager_->ReplaceConnectionId(
+            default_path_.server_connection_id, new_server_connection_id);
+      } else {
+        peer_issued_cid_manager_ =
+            std::make_unique<QuicPeerIssuedConnectionIdManager>(
+                kMinNumOfActiveConnectionIds, new_server_connection_id, clock_,
+                alarm_factory_, this, context());
+      }
+    }
+  }
+  default_path_.server_connection_id = new_server_connection_id;
+  packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
+}
+
+void QuicConnection::FindMatchingOrNewClientConnectionIdOrToken(
+    const PathState& default_path, const PathState& alternative_path,
+    const QuicConnectionId& server_connection_id,
+    QuicConnectionId* client_connection_id,
+    absl::optional<StatelessResetToken>* stateless_reset_token) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
+  if (peer_issued_cid_manager_ == nullptr ||
+      server_connection_id == default_path.server_connection_id) {
+    *client_connection_id = default_path.client_connection_id;
+    *stateless_reset_token = default_path.stateless_reset_token;
+    return;
+  }
+  if (server_connection_id == alternative_path_.server_connection_id) {
+    *client_connection_id = alternative_path.client_connection_id;
+    *stateless_reset_token = alternative_path.stateless_reset_token;
+    return;
+  }
+  if (!connection_migration_use_new_cid_) {
+    QUIC_BUG(quic_bug_46004) << "Cannot find matching connection ID.";
+    return;
+  }
+  auto* connection_id_data =
+      peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+  if (connection_id_data == nullptr) {
+    return;
+  }
+  *client_connection_id = connection_id_data->connection_id;
+  *stateless_reset_token = connection_id_data->stateless_reset_token;
+}
+
+bool QuicConnection::FindOnPathConnectionIds(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId* client_connection_id,
+    QuicConnectionId* server_connection_id) const {
+  if (IsDefaultPath(self_address, peer_address)) {
+    *client_connection_id = default_path_.client_connection_id,
+    *server_connection_id = default_path_.server_connection_id;
+    return true;
+  }
+  if (IsAlternativePath(self_address, peer_address)) {
+    *client_connection_id = alternative_path_.client_connection_id,
+    *server_connection_id = alternative_path_.server_connection_id;
+    return true;
+  }
+  return false;
+}
+
+void QuicConnection::SetDefaultPathState(PathState new_path_state) {
+  default_path_ = std::move(new_path_state);
+  if (connection_migration_use_new_cid_) {
+    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+    packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
+  }
+}
+
+bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
+  if (perspective_ == Perspective::IS_CLIENT && version().HasIetfQuicFrames() &&
+      direct_peer_address_.IsInitialized() &&
+      last_received_packet_info_.source_address.IsInitialized() &&
+      direct_peer_address_ != last_received_packet_info_.source_address &&
+      !visitor_->IsKnownServerAddress(
+          last_received_packet_info_.source_address)) {
+    // TODO(haoyuewang) Revisit this when preferred_address transport parameter
+    // is used on the client side.
+    // Discard packets received from unseen server addresses.
+    return false;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      default_path_.self_address.IsInitialized() &&
+      last_received_packet_info_.destination_address.IsInitialized() &&
+      default_path_.self_address !=
+          last_received_packet_info_.destination_address) {
+    // Allow change between pure IPv4 and equivalent mapped IPv4 address.
+    if (default_path_.self_address.port() !=
+            last_received_packet_info_.destination_address.port() ||
+        default_path_.self_address.host().Normalized() !=
+            last_received_packet_info_.destination_address.host()
+                .Normalized()) {
+      if (!visitor_->AllowSelfAddressChange()) {
+        const std::string error_details = absl::StrCat(
+            "Self address migration is not supported at the server, current "
+            "address: ",
+            default_path_.self_address.ToString(),
+            ", received packet address: ",
+            last_received_packet_info_.destination_address.ToString(),
+            ", size: ", last_size_,
+            ", packet number: ", header.packet_number.ToString(),
+            ", encryption level: ",
+            EncryptionLevelToString(last_decrypted_packet_level_));
+        if (GetQuicReloadableFlag(
+                quic_drop_packets_with_changed_server_address)) {
+          QUIC_LOG_EVERY_N_SEC(INFO, 100) << error_details;
+          QUIC_CODE_COUNT(quic_dropped_packets_with_changed_server_address);
+          return false;
+        }
+        QUIC_PEER_BUG(Server self address change) << error_details;
+        CloseConnection(QUIC_ERROR_MIGRATING_ADDRESS, error_details,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
+    }
+    default_path_.self_address = last_received_packet_info_.destination_address;
+  }
+
+  if (PacketCanReplaceServerConnectionId(header, perspective_) &&
+      default_path_.server_connection_id != header.source_connection_id) {
+    QUICHE_DCHECK_EQ(header.long_packet_type, INITIAL);
+    if (server_connection_id_replaced_by_initial_) {
+      QUIC_DLOG(ERROR) << ENDPOINT << "Refusing to replace connection ID "
+                       << default_path_.server_connection_id << " with "
+                       << header.source_connection_id;
+      return false;
+    }
+    server_connection_id_replaced_by_initial_ = true;
+    QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
+                    << default_path_.server_connection_id << " with "
+                    << header.source_connection_id;
+    if (!original_destination_connection_id_.has_value()) {
+      original_destination_connection_id_ = default_path_.server_connection_id;
+    }
+    ReplaceInitialServerConnectionId(header.source_connection_id);
+  }
+
+  if (!ValidateReceivedPacketNumber(header.packet_number)) {
+    return false;
+  }
+
+  if (!version_negotiated_) {
+    if (perspective_ == Perspective::IS_CLIENT) {
+      QUICHE_DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
+      if (!version().HasIetfInvariantHeader()) {
+        // If the client gets a packet without the version flag from the server
+        // it should stop sending version since the version negotiation is done.
+        // IETF QUIC stops sending version once encryption level switches to
+        // forward secure.
+        packet_creator_.StopSendingVersion();
+      }
+      version_negotiated_ = true;
+      OnSuccessfulVersionNegotiation();
+    }
+  }
+
+  if (last_size_ > largest_received_packet_size_) {
+    largest_received_packet_size_ = last_size_;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      encryption_level_ == ENCRYPTION_INITIAL &&
+      last_size_ > packet_creator_.max_packet_length()) {
+    if (GetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test)) {
+      SetMaxPacketLength(std::min(last_size_, QuicByteCount(1250)));
+    } else {
+      SetMaxPacketLength(last_size_);
+    }
+  }
+  return true;
+}
+
+bool QuicConnection::ValidateReceivedPacketNumber(
+    QuicPacketNumber packet_number) {
+  // If this packet has already been seen, or the sender has told us that it
+  // will not be retransmitted, then stop processing the packet.
+  if (!uber_received_packet_manager_.IsAwaitingPacket(
+          last_decrypted_packet_level_, packet_number)) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
+                    << " no longer being waited for at level "
+                    << static_cast<int>(last_decrypted_packet_level_)
+                    << ".  Discarding.";
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnDuplicatePacket(packet_number);
+    }
+    return false;
+  }
+
+  return true;
+}
+
+void QuicConnection::WriteQueuedPackets() {
+  QUICHE_DCHECK(!writer_->IsWriteBlocked());
+
+  QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsBeforeWrite",
+                               buffered_packets_.size(), 1, 1000, 50, "");
+
+  while (!buffered_packets_.empty()) {
+    if (HandleWriteBlocked()) {
+      break;
+    }
+    const BufferedPacket& packet = buffered_packets_.front();
+    WriteResult result = writer_->WritePacket(
+        packet.encrypted_buffer.data(), packet.encrypted_buffer.length(),
+        packet.self_address.host(), packet.peer_address, per_packet_options_);
+    QUIC_DVLOG(1) << ENDPOINT << "Sending buffered packet, result: " << result;
+    if (IsMsgTooBig(writer_, result) &&
+        packet.encrypted_buffer.length() > long_term_mtu_) {
+      // When MSG_TOO_BIG is returned, the system typically knows what the
+      // actual MTU is, so there is no need to probe further.
+      // TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
+      mtu_discoverer_.Disable();
+      mtu_discovery_alarm_->Cancel();
+      buffered_packets_.pop_front();
+      continue;
+    }
+    if (IsWriteError(result.status)) {
+      OnWriteError(result.error_code);
+      break;
+    }
+    if (result.status == WRITE_STATUS_OK ||
+        result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      buffered_packets_.pop_front();
+    }
+    if (IsWriteBlockedStatus(result.status)) {
+      visitor_->OnWriteBlocked();
+      break;
+    }
+  }
+}
+
+void QuicConnection::SendProbingRetransmissions() {
+  while (sent_packet_manager_.GetSendAlgorithm()->ShouldSendProbingPacket() &&
+         CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    if (!visitor_->SendProbingData()) {
+      QUIC_DVLOG(1)
+          << "Cannot send probing retransmissions: nothing to retransmit.";
+      break;
+    }
+  }
+}
+
+void QuicConnection::MarkZeroRttPacketsForRetransmission(int reject_reason) {
+  sent_packet_manager_.MarkZeroRttPacketsForRetransmission();
+  if (debug_visitor_ != nullptr && version().UsesTls()) {
+    debug_visitor_->OnZeroRttRejected(reject_reason);
+  }
+}
+
+void QuicConnection::NeuterUnencryptedPackets() {
+  sent_packet_manager_.NeuterUnencryptedPackets();
+  // This may have changed the retransmission timer, so re-arm it.
+  SetRetransmissionAlarm();
+  if (default_enable_5rto_blackhole_detection_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+                                 1, 3);
+    // Consider this as forward progress since this is called when initial key
+    // gets discarded (or previous unencrypted data is not needed anymore).
+    OnForwardProgressMade();
+  }
+  if (SupportsMultiplePacketNumberSpaces()) {
+    // Stop sending ack of initial packet number space.
+    uber_received_packet_manager_.ResetAckStates(ENCRYPTION_INITIAL);
+    // Re-arm ack alarm.
+    ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
+                       kAlarmGranularity);
+  }
+}
+
+bool QuicConnection::ShouldGeneratePacket(
+    HasRetransmittableData retransmittable,
+    IsHandshake handshake) {
+  QUICHE_DCHECK(handshake != IS_HANDSHAKE ||
+                QuicVersionUsesCryptoFrames(transport_version()))
+      << ENDPOINT
+      << "Handshake in STREAM frames should not check ShouldGeneratePacket";
+  if (peer_issued_cid_manager_ != nullptr &&
+      packet_creator_.GetDestinationConnectionId().IsEmpty()) {
+    QUICHE_DCHECK(version().HasIetfQuicFrames());
+    QUIC_CODE_COUNT(quic_generate_packet_blocked_by_no_connection_id);
+    QUIC_BUG_IF(quic_bug_90265_1, perspective_ == Perspective::IS_CLIENT);
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "There is no destination connection ID available to "
+                       "generate packet.";
+    return false;
+  }
+  if (!count_bytes_on_alternative_path_separately_) {
+    return CanWrite(retransmittable);
+  }
+  QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 4, 5);
+  if (IsDefaultPath(default_path_.self_address,
+                    packet_creator_.peer_address())) {
+    return CanWrite(retransmittable);
+  }
+  // This is checking on the alternative path with a different peer address. The
+  // self address and the writer used are the same as the default path. In the
+  // case of different self address and writer, writing packet would use a
+  // differnt code path without checking the states of the default writer.
+  return connected_ && !HandleWriteBlocked();
+}
+
+const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
+  if (!ack_frequency_sent_ && sent_packet_manager_.CanSendAckFrequency()) {
+    if (packet_creator_.NextSendingPacketNumber() >=
+        FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 3, 3);
+      ack_frequency_sent_ = true;
+      auto frame = sent_packet_manager_.GetUpdatedAckFrequencyFrame();
+      visitor_->SendAckFrequency(frame);
+    }
+  }
+
+  QuicFrames frames;
+  const bool has_pending_ack =
+      uber_received_packet_manager_
+          .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
+          .IsInitialized();
+  if (!has_pending_ack && stop_waiting_count_ <= 1) {
+    // No need to send an ACK.
+    return frames;
+  }
+  ResetAckStates();
+
+  QUIC_DVLOG(1) << ENDPOINT << "Bundle an ACK opportunistically";
+  QuicFrame updated_ack_frame = GetUpdatedAckFrame();
+  QUIC_BUG_IF(quic_bug_12714_23, updated_ack_frame.ack_frame->packets.Empty())
+      << ENDPOINT << "Attempted to opportunistically bundle an empty "
+      << encryption_level_ << " ACK, " << (has_pending_ack ? "" : "!")
+      << "has_pending_ack, stop_waiting_count_ " << stop_waiting_count_;
+  frames.push_back(updated_ack_frame);
+
+  if (!no_stop_waiting_frames_) {
+    QuicStopWaitingFrame stop_waiting;
+    PopulateStopWaitingFrame(&stop_waiting);
+    frames.push_back(QuicFrame(stop_waiting));
+  }
+  return frames;
+}
+
+bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
+  if (!connected_) {
+    return false;
+  }
+
+  if (version().CanSendCoalescedPackets() &&
+      framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL) &&
+      framer_.is_processing_packet()) {
+    // While we still have initial keys, suppress sending in mid of packet
+    // processing.
+    // TODO(fayang): always suppress sending while in the mid of packet
+    // processing.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Suppress sending in the mid of packet processing";
+    return false;
+  }
+
+  if (fill_coalesced_packet_) {
+    // Try to coalesce packet, only allow to write when creator is on soft max
+    // packet length. Given the next created packet is going to fill current
+    // coalesced packet, do not check amplification factor.
+    return packet_creator_.HasSoftMaxPacketLength();
+  }
+
+  if (sent_packet_manager_.pending_timer_transmission_count() > 0) {
+    // Allow sending if there are pending tokens, which occurs when:
+    // 1) firing PTO,
+    // 2) bundling CRYPTO data with ACKs,
+    // 3) coalescing CRYPTO data of higher space.
+    return true;
+  }
+
+  if (LimitedByAmplificationFactor()) {
+    // Server is constrained by the amplification restriction.
+    QUIC_CODE_COUNT(quic_throttled_by_amplification_limit);
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Constrained by amplification restriction to peer address "
+                  << default_path_.peer_address << " bytes received "
+                  << default_path_.bytes_received_before_address_validation
+                  << ", bytes sent"
+                  << default_path_.bytes_sent_before_address_validation;
+    ++stats_.num_amplification_throttling;
+    return false;
+  }
+
+  if (HandleWriteBlocked()) {
+    return false;
+  }
+
+  // Allow acks and probing frames to be sent immediately.
+  if (retransmittable == NO_RETRANSMITTABLE_DATA) {
+    return true;
+  }
+  // If the send alarm is set, wait for it to fire.
+  if (send_alarm_->IsSet()) {
+    return false;
+  }
+
+  QuicTime now = clock_->Now();
+  QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(now);
+  if (delay.IsInfinite()) {
+    send_alarm_->Cancel();
+    return false;
+  }
+
+  // Scheduler requires a delay.
+  if (!delay.IsZero()) {
+    if (delay <= release_time_into_future_) {
+      // Required delay is within pace time into future, send now.
+      return true;
+    }
+    // Cannot send packet now because delay is too far in the future.
+    send_alarm_->Update(now + delay, kAlarmGranularity);
+    QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
+                  << "ms";
+    return false;
+  }
+  return true;
+}
+
+QuicTime QuicConnection::CalculatePacketSentTime() {
+  const QuicTime now = clock_->Now();
+  if (!supports_release_time_ || per_packet_options_ == nullptr) {
+    // Don't change the release delay.
+    return now;
+  }
+
+  auto next_release_time_result = sent_packet_manager_.GetNextReleaseTime();
+
+  // Release before |now| is impossible.
+  QuicTime next_release_time =
+      std::max(now, next_release_time_result.release_time);
+  per_packet_options_->release_time_delay = next_release_time - now;
+  per_packet_options_->allow_burst = next_release_time_result.allow_burst;
+  return next_release_time;
+}
+
+bool QuicConnection::WritePacket(SerializedPacket* packet) {
+  if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
+      packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
+    QUIC_BUG(quic_bug_10511_23)
+        << "Attempt to write packet:" << packet->packet_number
+        << " after:" << sent_packet_manager_.GetLargestSentPacket();
+    CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return true;
+  }
+  const bool is_mtu_discovery = QuicUtils::ContainsFrameType(
+      packet->nonretransmittable_frames, MTU_DISCOVERY_FRAME);
+  const SerializedPacketFate fate = packet->fate;
+  // Termination packets are encrypted and saved, so don't exit early.
+  QuicErrorCode error_code = QUIC_NO_ERROR;
+  const bool is_termination_packet = IsTerminationPacket(*packet, &error_code);
+  QuicPacketNumber packet_number = packet->packet_number;
+  QuicPacketLength encrypted_length = packet->encrypted_length;
+  // Termination packets are eventually owned by TimeWaitListManager.
+  // Others are deleted at the end of this call.
+  if (is_termination_packet) {
+    if (termination_packets_ == nullptr) {
+      termination_packets_.reset(
+          new std::vector<std::unique_ptr<QuicEncryptedPacket>>);
+    }
+    // Copy the buffer so it's owned in the future.
+    char* buffer_copy = CopyBuffer(*packet);
+    termination_packets_->emplace_back(
+        new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
+    if (error_code == QUIC_SILENT_IDLE_TIMEOUT) {
+      QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+      // TODO(fayang): populate histogram indicating the time elapsed from this
+      // connection gets closed to following client packets get received.
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Added silent connection close to termination packets, "
+                       "num of termination packets: "
+                    << termination_packets_->size();
+      return true;
+    }
+  }
+
+  QUICHE_DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
+  QUICHE_DCHECK(is_mtu_discovery ||
+                encrypted_length <= packet_creator_.max_packet_length())
+      << " encrypted_length=" << encrypted_length
+      << " > packet_creator max_packet_length="
+      << packet_creator_.max_packet_length();
+  QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
+                << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
+                        ? "data bearing "
+                        : " ack or probing only ")
+                << ", encryption level: " << packet->encryption_level
+                << ", encrypted length:" << encrypted_length
+                << ", fate: " << fate << " to peer " << packet->peer_address;
+  QUIC_DVLOG(2) << ENDPOINT << packet->encryption_level << " packet number "
+                << packet_number << " of length " << encrypted_length << ": "
+                << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       packet->encrypted_buffer, encrypted_length));
+
+  // Measure the RTT from before the write begins to avoid underestimating the
+  // min_rtt_, especially in cases where the thread blocks or gets swapped out
+  // during the WritePacket below.
+  QuicTime packet_send_time = CalculatePacketSentTime();
+  WriteResult result(WRITE_STATUS_OK, encrypted_length);
+  QuicSocketAddress send_to_address = packet->peer_address;
+  // Self address is always the default self address on this code path.
+  bool send_on_current_path = send_to_address == peer_address();
+  switch (fate) {
+    case DISCARD:
+      ++stats_.packets_discarded;
+      if (debug_visitor_ != nullptr) {
+        debug_visitor_->OnPacketDiscarded(*packet);
+      }
+      return true;
+    case COALESCE:
+      QUIC_BUG_IF(quic_bug_12714_24,
+                  !version().CanSendCoalescedPackets() || coalescing_done_);
+      if (!coalesced_packet_.MaybeCoalescePacket(
+              *packet, self_address(), send_to_address,
+              helper_->GetStreamSendBufferAllocator(),
+              packet_creator_.max_packet_length())) {
+        // Failed to coalesce packet, flush current coalesced packet.
+        if (!FlushCoalescedPacket()) {
+          QUIC_BUG_IF(quic_connection_connected_after_flush_coalesced_failure,
+                      connected_)
+              << "QUIC connection is still connected after failing to flush "
+                 "coalesced packet.";
+          // Failed to flush coalesced packet, write error has been handled.
+          return false;
+        }
+        if (!coalesced_packet_.MaybeCoalescePacket(
+                *packet, self_address(), send_to_address,
+                helper_->GetStreamSendBufferAllocator(),
+                packet_creator_.max_packet_length())) {
+          // Failed to coalesce packet even it is the only packet, raise a write
+          // error.
+          QUIC_DLOG(ERROR) << ENDPOINT << "Failed to coalesce packet";
+          result.error_code = WRITE_STATUS_FAILED_TO_COALESCE_PACKET;
+          break;
+        }
+      }
+      if (coalesced_packet_.length() < coalesced_packet_.max_packet_length()) {
+        QUIC_DVLOG(1) << ENDPOINT << "Trying to set soft max packet length to "
+                      << coalesced_packet_.max_packet_length() -
+                             coalesced_packet_.length();
+        packet_creator_.SetSoftMaxPacketLength(
+            coalesced_packet_.max_packet_length() - coalesced_packet_.length());
+      }
+      break;
+    case BUFFER:
+      QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
+                    << " to buffered packets";
+      buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
+      break;
+    case SEND_TO_WRITER:
+      // Stop using coalescer from now on.
+      coalescing_done_ = true;
+      // At this point, packet->release_encrypted_buffer is either nullptr,
+      // meaning |packet->encrypted_buffer| is a stack buffer, or not-nullptr,
+      /// meaning it's a writer-allocated buffer. Note that connectivity probing
+      // packets do not use this function, so setting release_encrypted_buffer
+      // to nullptr will not cause probing packets to be leaked.
+      //
+      // writer_->WritePacket transfers buffer ownership back to the writer.
+      packet->release_encrypted_buffer = nullptr;
+      result = writer_->WritePacket(packet->encrypted_buffer, encrypted_length,
+                                    self_address().host(), send_to_address,
+                                    per_packet_options_);
+      // This is a work around for an issue with linux UDP GSO batch writers.
+      // When sending a GSO packet with 2 segments, if the first segment is
+      // larger than the path MTU, instead of EMSGSIZE, the linux kernel returns
+      // EINVAL, which translates to WRITE_STATUS_ERROR and causes conneciton to
+      // be closed. By manually flush the writer here, the MTU probe is sent in
+      // a normal(non-GSO) packet, so the kernel can return EMSGSIZE and we will
+      // not close the connection.
+      if (is_mtu_discovery && writer_->IsBatchMode()) {
+        result = writer_->Flush();
+      }
+      break;
+    case LEGACY_VERSION_ENCAPSULATE: {
+      QUICHE_DCHECK(!is_mtu_discovery);
+      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+      QUICHE_DCHECK_EQ(packet->encryption_level, ENCRYPTION_INITIAL);
+      QUICHE_DCHECK(legacy_version_encapsulation_enabled_);
+      QUICHE_DCHECK(legacy_version_encapsulation_in_progress_);
+      QuicPacketLength encapsulated_length =
+          QuicLegacyVersionEncapsulator::Encapsulate(
+              legacy_version_encapsulation_sni_,
+              absl::string_view(packet->encrypted_buffer,
+                                packet->encrypted_length),
+              default_path_.server_connection_id, framer_.creation_time(),
+              GetLimitedMaxPacketSize(long_term_mtu_),
+              const_cast<char*>(packet->encrypted_buffer));
+      if (encapsulated_length != 0) {
+        stats_.sent_legacy_version_encapsulated_packets++;
+        packet->encrypted_length = encapsulated_length;
+        encrypted_length = encapsulated_length;
+        QUIC_DVLOG(2)
+            << ENDPOINT
+            << "Successfully performed Legacy Version Encapsulation on "
+            << packet->encryption_level << " packet number " << packet_number
+            << " of length " << encrypted_length << ": " << std::endl
+            << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                   packet->encrypted_buffer, encrypted_length));
+      } else {
+        QUIC_BUG(quic_bug_10511_24)
+            << ENDPOINT << "Failed to perform Legacy Version Encapsulation on "
+            << packet->encryption_level << " packet number " << packet_number
+            << " of length " << encrypted_length;
+      }
+      if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+        // Buffer the packet.
+        buffered_packets_.emplace_back(*packet, self_address(),
+                                       send_to_address);
+      } else {  // Send the packet to the writer.
+        // writer_->WritePacket transfers buffer ownership back to the writer.
+        packet->release_encrypted_buffer = nullptr;
+        result = writer_->WritePacket(packet->encrypted_buffer,
+                                      encrypted_length, self_address().host(),
+                                      send_to_address, per_packet_options_);
+      }
+    } break;
+    default:
+      QUICHE_DCHECK(false);
+      break;
+  }
+
+  QUIC_HISTOGRAM_ENUM(
+      "QuicConnection.WritePacketStatus", result.status,
+      WRITE_STATUS_NUM_VALUES,
+      "Status code returned by writer_->WritePacket() in QuicConnection.");
+
+  if (IsWriteBlockedStatus(result.status)) {
+    // Ensure the writer is still write blocked, otherwise QUIC may continue
+    // trying to write when it will not be able to.
+    QUICHE_DCHECK(writer_->IsWriteBlocked());
+    visitor_->OnWriteBlocked();
+    // If the socket buffers the data, then the packet should not
+    // be queued and sent again, which would result in an unnecessary
+    // duplicate packet being sent.  The helper must call OnCanWrite
+    // when the write completes, and OnWriteError if an error occurs.
+    if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      QUIC_DVLOG(1) << ENDPOINT << "Adding packet: " << packet->packet_number
+                    << " to buffered packets";
+      buffered_packets_.emplace_back(*packet, self_address(), send_to_address);
+    }
+  }
+
+  // In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
+  // MTU discovery is permanently unsuccessful.
+  if (IsMsgTooBig(writer_, result)) {
+    if (is_mtu_discovery) {
+      // When MSG_TOO_BIG is returned, the system typically knows what the
+      // actual MTU is, so there is no need to probe further.
+      // TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
+      QUIC_DVLOG(1) << ENDPOINT
+                    << " MTU probe packet too big, size:" << encrypted_length
+                    << ", long_term_mtu_:" << long_term_mtu_;
+      mtu_discoverer_.Disable();
+      mtu_discovery_alarm_->Cancel();
+      // The write failed, but the writer is not blocked, so return true.
+      return true;
+    }
+    if (use_path_validator_ && !send_on_current_path) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 2, 4);
+      // Only handle MSG_TOO_BIG as error on current path.
+      return true;
+    }
+  }
+
+  if (IsWriteError(result.status)) {
+    QUIC_LOG_FIRST_N(ERROR, 10)
+        << ENDPOINT << "Failed writing packet " << packet_number << " of "
+        << encrypted_length << " bytes from " << self_address().host() << " to "
+        << send_to_address << ", with error code " << result.error_code
+        << ". long_term_mtu_:" << long_term_mtu_
+        << ", previous_validated_mtu_:" << previous_validated_mtu_
+        << ", max_packet_length():" << max_packet_length()
+        << ", is_mtu_discovery:" << is_mtu_discovery;
+    if (MaybeRevertToPreviousMtu()) {
+      return true;
+    }
+
+    OnWriteError(result.error_code);
+    return false;
+  }
+
+  if (result.status == WRITE_STATUS_OK) {
+    // packet_send_time is the ideal send time, if allow_burst is true, writer
+    // may have sent it earlier than that.
+    packet_send_time = packet_send_time + result.send_time_offset;
+  }
+
+  if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA &&
+      !is_termination_packet) {
+    // Start blackhole/path degrading detections if the sent packet is not
+    // termination packet and contains retransmittable data.
+    // Do not restart detection if detection is in progress indicating no
+    // forward progress has been made since last event (i.e., packet was sent
+    // or new packets were acknowledged).
+    if (!blackhole_detector_.IsDetectionInProgress()) {
+      // Try to start detections if no detection in progress. This could
+      // because either both detections are inactive when sending last packet
+      // or this connection just gets out of quiescence.
+      blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
+                                           GetNetworkBlackholeDeadline(),
+                                           GetPathMtuReductionDeadline());
+    }
+    idle_network_detector_.OnPacketSent(packet_send_time,
+                                        sent_packet_manager_.GetPtoDelay());
+  }
+
+  MaybeSetMtuAlarm(packet_number);
+  QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
+                << packet_send_time.ToDebuggingValue();
+
+  if (!count_bytes_on_alternative_path_separately_) {
+    if (EnforceAntiAmplificationLimit()) {
+      // Include bytes sent even if they are not in flight.
+      default_path_.bytes_sent_before_address_validation += encrypted_length;
+    }
+  } else {
+    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 2, 5);
+    if (IsDefaultPath(default_path_.self_address, send_to_address)) {
+      if (EnforceAntiAmplificationLimit()) {
+        // Include bytes sent even if they are not in flight.
+        default_path_.bytes_sent_before_address_validation += encrypted_length;
+      }
+    } else {
+      MaybeUpdateBytesSentToAlternativeAddress(send_to_address,
+                                               encrypted_length);
+    }
+  }
+
+  // Do not measure rtt of this packet if it's not sent on current path.
+  QUIC_DLOG_IF(INFO, !send_on_current_path)
+      << ENDPOINT << " Sent packet " << packet->packet_number
+      << " on a different path with remote address " << send_to_address
+      << " while current path has peer address " << peer_address();
+  const bool in_flight = sent_packet_manager_.OnPacketSent(
+      packet, packet_send_time, packet->transmission_type,
+      IsRetransmittable(*packet), /*measure_rtt=*/send_on_current_path);
+  QUIC_BUG_IF(quic_bug_12714_25,
+              perspective_ == Perspective::IS_SERVER &&
+                  default_enable_5rto_blackhole_detection_ &&
+                  blackhole_detector_.IsDetectionInProgress() &&
+                  !sent_packet_manager_.HasInFlightPackets())
+      << ENDPOINT
+      << "Trying to start blackhole detection without no bytes in flight";
+
+  if (debug_visitor_ != nullptr) {
+    if (sent_packet_manager_.unacked_packets().empty()) {
+      QUIC_BUG(quic_bug_10511_25)
+          << "Unacked map is empty right after packet is sent";
+    } else {
+      debug_visitor_->OnPacketSent(
+          packet->packet_number, packet->encrypted_length,
+          packet->has_crypto_handshake, packet->transmission_type,
+          packet->encryption_level,
+          sent_packet_manager_.unacked_packets()
+              .rbegin()
+              ->retransmittable_frames,
+          packet->nonretransmittable_frames, packet_send_time);
+    }
+  }
+  if (packet->encryption_level == ENCRYPTION_HANDSHAKE) {
+    handshake_packet_sent_ = true;
+  }
+
+  if (packet->encryption_level == ENCRYPTION_FORWARD_SECURE) {
+    if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "lowest_packet_sent_in_current_key_phase_ = "
+                      << packet_number;
+      lowest_packet_sent_in_current_key_phase_ = packet_number;
+    }
+    if (!is_termination_packet &&
+        MaybeHandleAeadConfidentialityLimits(*packet)) {
+      return true;
+    }
+  }
+  if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 1, 2);
+    if (in_flight || !retransmission_alarm_->IsSet()) {
+      SetRetransmissionAlarm();
+    }
+  } else if (ShouldSetRetransmissionAlarmOnPacketSent(
+                 in_flight, packet->encryption_level)) {
+    SetRetransmissionAlarm();
+  }
+  SetPingAlarm();
+  RetirePeerIssuedConnectionIdsNoLongerOnPath();
+
+  // The packet number length must be updated after OnPacketSent, because it
+  // may change the packet number length in packet.
+  packet_creator_.UpdatePacketNumberLength(
+      sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
+      sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
+
+  stats_.bytes_sent += result.bytes_written;
+  ++stats_.packets_sent;
+  if (packet->transmission_type != NOT_RETRANSMISSION) {
+    stats_.bytes_retransmitted += result.bytes_written;
+    ++stats_.packets_retransmitted;
+  }
+
+  return true;
+}
+
+bool QuicConnection::MaybeHandleAeadConfidentialityLimits(
+    const SerializedPacket& packet) {
+  if (!version().UsesTls()) {
+    return false;
+  }
+
+  if (packet.encryption_level != ENCRYPTION_FORWARD_SECURE) {
+    QUIC_BUG(quic_bug_12714_26)
+        << "MaybeHandleAeadConfidentialityLimits called on non 1-RTT packet";
+    return false;
+  }
+  if (!lowest_packet_sent_in_current_key_phase_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10511_26)
+        << "lowest_packet_sent_in_current_key_phase_ must be initialized "
+           "before calling MaybeHandleAeadConfidentialityLimits";
+    return false;
+  }
+
+  // Calculate the number of packets encrypted from the packet number, which is
+  // simpler than keeping another counter. The packet number space may be
+  // sparse, so this might overcount, but doing a key update earlier than
+  // necessary would only improve security and has negligible cost.
+  if (packet.packet_number < lowest_packet_sent_in_current_key_phase_) {
+    const std::string error_details =
+        absl::StrCat("packet_number(", packet.packet_number.ToString(),
+                     ") < lowest_packet_sent_in_current_key_phase_ (",
+                     lowest_packet_sent_in_current_key_phase_.ToString(), ")");
+    QUIC_BUG(quic_bug_10511_27) << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return true;
+  }
+  const QuicPacketCount num_packets_encrypted_in_current_key_phase =
+      packet.packet_number - lowest_packet_sent_in_current_key_phase_ + 1;
+
+  const QuicPacketCount confidentiality_limit =
+      framer_.GetOneRttEncrypterConfidentialityLimit();
+
+  // Attempt to initiate a key update before reaching the AEAD
+  // confidentiality limit when the number of packets sent in the current
+  // key phase gets within |kKeyUpdateConfidentialityLimitOffset| packets of
+  // the limit, unless overridden by
+  // FLAGS_quic_key_update_confidentiality_limit.
+  constexpr QuicPacketCount kKeyUpdateConfidentialityLimitOffset = 1000;
+  QuicPacketCount key_update_limit = 0;
+  if (confidentiality_limit > kKeyUpdateConfidentialityLimitOffset) {
+    key_update_limit =
+        confidentiality_limit - kKeyUpdateConfidentialityLimitOffset;
+  }
+  const QuicPacketCount key_update_limit_override =
+      GetQuicFlag(FLAGS_quic_key_update_confidentiality_limit);
+  if (key_update_limit_override) {
+    key_update_limit = key_update_limit_override;
+  }
+
+  QUIC_DVLOG(2) << ENDPOINT << "Checking AEAD confidentiality limits: "
+                << "num_packets_encrypted_in_current_key_phase="
+                << num_packets_encrypted_in_current_key_phase
+                << " key_update_limit=" << key_update_limit
+                << " confidentiality_limit=" << confidentiality_limit
+                << " IsKeyUpdateAllowed()=" << IsKeyUpdateAllowed();
+
+  if (num_packets_encrypted_in_current_key_phase >= confidentiality_limit) {
+    // Reached the confidentiality limit without initiating a key update,
+    // must close the connection.
+    const std::string error_details = absl::StrCat(
+        "encrypter confidentiality limit reached: "
+        "num_packets_encrypted_in_current_key_phase=",
+        num_packets_encrypted_in_current_key_phase,
+        " key_update_limit=", key_update_limit,
+        " confidentiality_limit=", confidentiality_limit,
+        " IsKeyUpdateAllowed()=", IsKeyUpdateAllowed());
+    CloseConnection(QUIC_AEAD_LIMIT_REACHED, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return true;
+  }
+
+  if (IsKeyUpdateAllowed() &&
+      num_packets_encrypted_in_current_key_phase >= key_update_limit) {
+    // Approaching the confidentiality limit, initiate key update so that
+    // the next set of keys will be ready for the next packet before the
+    // limit is reached.
+    KeyUpdateReason reason = KeyUpdateReason::kLocalAeadConfidentialityLimit;
+    if (key_update_limit_override) {
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "reached FLAGS_quic_key_update_confidentiality_limit, "
+                         "initiating key update: "
+                      << "num_packets_encrypted_in_current_key_phase="
+                      << num_packets_encrypted_in_current_key_phase
+                      << " key_update_limit=" << key_update_limit
+                      << " confidentiality_limit=" << confidentiality_limit;
+      reason = KeyUpdateReason::kLocalKeyUpdateLimitOverride;
+    } else {
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "approaching AEAD confidentiality limit, "
+                         "initiating key update: "
+                      << "num_packets_encrypted_in_current_key_phase="
+                      << num_packets_encrypted_in_current_key_phase
+                      << " key_update_limit=" << key_update_limit
+                      << " confidentiality_limit=" << confidentiality_limit;
+    }
+    InitiateKeyUpdate(reason);
+  }
+
+  return false;
+}
+
+void QuicConnection::FlushPackets() {
+  if (!connected_) {
+    return;
+  }
+
+  if (!writer_->IsBatchMode()) {
+    return;
+  }
+
+  if (HandleWriteBlocked()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "FlushPackets called while blocked.";
+    return;
+  }
+
+  WriteResult result = writer_->Flush();
+
+  QUIC_HISTOGRAM_ENUM("QuicConnection.FlushPacketStatus", result.status,
+                      WRITE_STATUS_NUM_VALUES,
+                      "Status code returned by writer_->Flush() in "
+                      "QuicConnection::FlushPackets.");
+
+  if (HandleWriteBlocked()) {
+    QUICHE_DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status)
+        << "Unexpected flush result:" << result;
+    QUIC_DLOG(INFO) << ENDPOINT << "Write blocked in FlushPackets.";
+    return;
+  }
+
+  if (IsWriteError(result.status) && !MaybeRevertToPreviousMtu()) {
+    OnWriteError(result.error_code);
+  }
+}
+
+bool QuicConnection::IsMsgTooBig(const QuicPacketWriter* writer,
+                                 const WriteResult& result) {
+  absl::optional<int> writer_error_code = writer->MessageTooBigErrorCode();
+  return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
+         (writer_error_code.has_value() && IsWriteError(result.status) &&
+          result.error_code == *writer_error_code);
+}
+
+bool QuicConnection::ShouldDiscardPacket(EncryptionLevel encryption_level) {
+  if (!connected_) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Not sending packet as connection is disconnected.";
+    return true;
+  }
+
+  if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
+      encryption_level == ENCRYPTION_INITIAL) {
+    // Drop packets that are NULL encrypted since the peer won't accept them
+    // anymore.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Dropping NULL encrypted packet since the connection is "
+                       "forward secure.";
+    return true;
+  }
+
+  return false;
+}
+
+QuicTime QuicConnection::GetPathMtuReductionDeadline() const {
+  if (previous_validated_mtu_ == 0) {
+    return QuicTime::Zero();
+  }
+  QuicTime::Delta delay = sent_packet_manager_.GetMtuReductionDelay(
+      num_rtos_for_blackhole_detection_);
+  if (delay.IsZero()) {
+    return QuicTime::Zero();
+  }
+  return clock_->ApproximateNow() + delay;
+}
+
+bool QuicConnection::MaybeRevertToPreviousMtu() {
+  if (previous_validated_mtu_ == 0) {
+    return false;
+  }
+
+  SetMaxPacketLength(previous_validated_mtu_);
+  mtu_discoverer_.Disable();
+  mtu_discovery_alarm_->Cancel();
+  previous_validated_mtu_ = 0;
+  return true;
+}
+
+void QuicConnection::OnWriteError(int error_code) {
+  if (write_error_occurred_) {
+    // A write error already occurred. The connection is being closed.
+    return;
+  }
+  write_error_occurred_ = true;
+
+  const std::string error_details = absl::StrCat(
+      "Write failed with error: ", error_code, " (", strerror(error_code), ")");
+  QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details;
+  absl::optional<int> writer_error_code = writer_->MessageTooBigErrorCode();
+  if (writer_error_code.has_value() && error_code == *writer_error_code) {
+    CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  // We can't send an error as the socket is presumably borked.
+  if (version().HasIetfInvariantHeader()) {
+    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
+  } else {
+    QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_non_ietf);
+  }
+  CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
+                  ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+QuicPacketBuffer QuicConnection::GetPacketBuffer() {
+  if (version().CanSendCoalescedPackets() && !coalescing_done_) {
+    // Do not use writer's packet buffer for coalesced packets which may
+    // contain multiple QUIC packets.
+    return {nullptr, nullptr};
+  }
+  return writer_->GetNextWriteLocation(self_address().host(), peer_address());
+}
+
+void QuicConnection::OnSerializedPacket(SerializedPacket serialized_packet) {
+  if (serialized_packet.encrypted_buffer == nullptr) {
+    // We failed to serialize the packet, so close the connection.
+    // Specify that the close is silent, that no packet be sent, so no infinite
+    // loop here.
+    // TODO(ianswett): This is actually an internal error, not an
+    // encryption failure.
+    if (version().HasIetfInvariantHeader()) {
+      QUIC_CODE_COUNT(
+          quic_tear_down_local_connection_on_serialized_packet_ietf);
+    } else {
+      QUIC_CODE_COUNT(
+          quic_tear_down_local_connection_on_serialized_packet_non_ietf);
+    }
+    CloseConnection(QUIC_ENCRYPTION_FAILURE,
+                    "Serialized packet does not have an encrypted buffer.",
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+
+  if (serialized_packet.retransmittable_frames.empty()) {
+    // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
+    // this packet is a new transmission with no retransmittable frames.
+    ++consecutive_num_packets_with_no_retransmittable_frames_;
+  } else {
+    consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+  }
+  SendOrQueuePacket(std::move(serialized_packet));
+}
+
+void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
+                                          const std::string& error_details) {
+  // The packet creator or generator encountered an unrecoverable error: tear
+  // down local connection state immediately.
+  if (version().HasIetfInvariantHeader()) {
+    QUIC_CODE_COUNT(
+        quic_tear_down_local_connection_on_unrecoverable_error_ietf);
+  } else {
+    QUIC_CODE_COUNT(
+        quic_tear_down_local_connection_on_unrecoverable_error_non_ietf);
+  }
+  CloseConnection(error, error_details, ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+void QuicConnection::OnCongestionChange() {
+  visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
+
+  // Uses the connection's smoothed RTT. If zero, uses initial_rtt.
+  QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt();
+  if (rtt.IsZero()) {
+    rtt = sent_packet_manager_.GetRttStats()->initial_rtt();
+  }
+
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnRttChanged(rtt);
+  }
+}
+
+void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) {
+  if (packet_size > max_packet_length()) {
+    previous_validated_mtu_ = max_packet_length();
+    SetMaxPacketLength(packet_size);
+    mtu_discoverer_.OnMaxPacketLengthUpdated(previous_validated_mtu_,
+                                             max_packet_length());
+  }
+}
+
+std::unique_ptr<QuicSelfIssuedConnectionIdManager>
+QuicConnection::MakeSelfIssuedConnectionIdManager() {
+  QUICHE_DCHECK((perspective_ == Perspective::IS_CLIENT &&
+                 !default_path_.client_connection_id.IsEmpty()) ||
+                (perspective_ == Perspective::IS_SERVER &&
+                 !default_path_.server_connection_id.IsEmpty()));
+  return std::make_unique<QuicSelfIssuedConnectionIdManager>(
+      kMinNumOfActiveConnectionIds,
+      perspective_ == Perspective::IS_CLIENT
+          ? default_path_.client_connection_id
+          : default_path_.server_connection_id,
+      clock_, alarm_factory_, this, context());
+}
+
+void QuicConnection::MaybeSendConnectionIdToClient() {
+  if (perspective_ == Perspective::IS_CLIENT) {
+    return;
+  }
+  QUICHE_DCHECK(self_issued_cid_manager_ != nullptr);
+  self_issued_cid_manager_->MaybeSendNewConnectionIds();
+}
+
+void QuicConnection::OnHandshakeComplete() {
+  sent_packet_manager_.SetHandshakeConfirmed();
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_SERVER &&
+      self_issued_cid_manager_ != nullptr) {
+    self_issued_cid_manager_->MaybeSendNewConnectionIds();
+  }
+  if (send_ack_frequency_on_handshake_completion_ &&
+      sent_packet_manager_.CanSendAckFrequency()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 2, 3);
+    auto ack_frequency_frame =
+        sent_packet_manager_.GetUpdatedAckFrequencyFrame();
+    // This AckFrequencyFrame is meant to only update the max_ack_delay. Set
+    // packet tolerance to the default value for now.
+    ack_frequency_frame.packet_tolerance =
+        kDefaultRetransmittablePacketsBeforeAck;
+    visitor_->SendAckFrequency(ack_frequency_frame);
+    if (!connected_) {
+      return;
+    }
+  }
+  // This may have changed the retransmission timer, so re-arm it.
+  SetRetransmissionAlarm();
+  if (default_enable_5rto_blackhole_detection_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+                                 2, 3);
+    OnForwardProgressMade();
+  }
+  if (!SupportsMultiplePacketNumberSpaces()) {
+    // The client should immediately ack the SHLO to confirm the handshake is
+    // complete with the server.
+    if (perspective_ == Perspective::IS_CLIENT && ack_frame_updated()) {
+      ack_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
+    }
+    return;
+  }
+  // Stop sending ack of handshake packet number space.
+  uber_received_packet_manager_.ResetAckStates(ENCRYPTION_HANDSHAKE);
+  // Re-arm ack alarm.
+  ack_alarm_->Update(uber_received_packet_manager_.GetEarliestAckTimeout(),
+                     kAlarmGranularity);
+}
+
+void QuicConnection::SendOrQueuePacket(SerializedPacket packet) {
+  // The caller of this function is responsible for checking CanWrite().
+  WritePacket(&packet);
+}
+
+void QuicConnection::OnPingTimeout() {
+  if (retransmission_alarm_->IsSet() ||
+      !visitor_->ShouldKeepConnectionAlive()) {
+    return;
+  }
+  SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
+}
+
+void QuicConnection::SendAck() {
+  QUICHE_DCHECK(!SupportsMultiplePacketNumberSpaces());
+  QUIC_DVLOG(1) << ENDPOINT << "Sending an ACK proactively";
+  QuicFrames frames;
+  frames.push_back(GetUpdatedAckFrame());
+  if (!no_stop_waiting_frames_) {
+    QuicStopWaitingFrame stop_waiting;
+    PopulateStopWaitingFrame(&stop_waiting);
+    frames.push_back(QuicFrame(stop_waiting));
+  }
+  if (!packet_creator_.FlushAckFrame(frames)) {
+    return;
+  }
+  ResetAckStates();
+  if (!ShouldBundleRetransmittableFrameWithAck()) {
+    return;
+  }
+  consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+  if (packet_creator_.HasPendingRetransmittableFrames() ||
+      visitor_->WillingAndAbleToWrite()) {
+    // There are pending retransmittable frames.
+    return;
+  }
+
+  visitor_->OnAckNeedsRetransmittableFrame();
+}
+
+void QuicConnection::OnRetransmissionTimeout() {
+  ScopedRetransmissionTimeoutIndicator indicator(this);
+#ifndef NDEBUG
+  if (sent_packet_manager_.unacked_packets().empty()) {
+    QUICHE_DCHECK(sent_packet_manager_.handshake_mode_disabled());
+    QUICHE_DCHECK(!IsHandshakeComplete());
+  }
+#endif
+  if (!connected_) {
+    return;
+  }
+
+  QuicPacketNumber previous_created_packet_number =
+      packet_creator_.packet_number();
+  const auto retransmission_mode =
+      sent_packet_manager_.OnRetransmissionTimeout();
+  if (sent_packet_manager_.skip_packet_number_for_pto() &&
+      retransmission_mode == QuicSentPacketManager::PTO_MODE &&
+      sent_packet_manager_.pending_timer_transmission_count() == 1) {
+    // Skip a packet number when a single PTO packet is sent to elicit an
+    // immediate ACK.
+    const QuicPacketCount num_packet_numbers_to_skip = 1;
+    packet_creator_.SkipNPacketNumbers(
+        num_packet_numbers_to_skip,
+        sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
+        sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
+    previous_created_packet_number += num_packet_numbers_to_skip;
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnNPacketNumbersSkipped(num_packet_numbers_to_skip,
+                                              clock_->Now());
+    }
+  }
+  if (default_enable_5rto_blackhole_detection_ &&
+      !sent_packet_manager_.HasInFlightPackets() &&
+      blackhole_detector_.IsDetectionInProgress()) {
+    // Stop detection in quiescence.
+    QUICHE_DCHECK_EQ(QuicSentPacketManager::LOSS_MODE, retransmission_mode);
+    blackhole_detector_.StopDetection(/*permanent=*/false);
+  }
+  WriteIfNotBlocked();
+
+  // A write failure can result in the connection being closed, don't attempt to
+  // write further packets, or to set alarms.
+  if (!connected_) {
+    return;
+  }
+
+  // In the PTO and TLP cases, the SentPacketManager gives the connection the
+  // opportunity to send new data before retransmitting.
+  if (sent_packet_manager_.pto_enabled()) {
+    sent_packet_manager_.MaybeSendProbePackets();
+  } else if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) {
+    // Send the pending retransmission now that it's been queued.
+    WriteIfNotBlocked();
+  }
+
+  if (packet_creator_.packet_number() == previous_created_packet_number &&
+      (retransmission_mode == QuicSentPacketManager::TLP_MODE ||
+       retransmission_mode == QuicSentPacketManager::RTO_MODE ||
+       retransmission_mode == QuicSentPacketManager::PTO_MODE) &&
+      !visitor_->WillingAndAbleToWrite()) {
+    // Send PING if timer fires in TLP/RTO/PTO mode but there is no data to
+    // send.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "No packet gets sent when timer fires in mode "
+                    << retransmission_mode << ", send PING";
+    QUICHE_DCHECK_LT(0u,
+                     sent_packet_manager_.pending_timer_transmission_count());
+    if (SupportsMultiplePacketNumberSpaces()) {
+      // Based on https://datatracker.ietf.org/doc/html/rfc9002#appendix-A.9
+      PacketNumberSpace packet_number_space;
+      if (sent_packet_manager_
+              .GetEarliestPacketSentTimeForPto(&packet_number_space)
+              .IsInitialized()) {
+        SendPingAtLevel(QuicUtils::GetEncryptionLevel(packet_number_space));
+      } else {
+        // The client must PTO when there is nothing in flight if the server
+        // could be blocked from sending by the amplification limit
+        QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+        if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE)) {
+          SendPingAtLevel(ENCRYPTION_HANDSHAKE);
+        } else if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+          SendPingAtLevel(ENCRYPTION_INITIAL);
+        } else {
+          QUIC_BUG(quic_bug_no_pto) << "PTO fired but nothing was sent.";
+        }
+      }
+    } else {
+      SendPingAtLevel(encryption_level_);
+    }
+  }
+  if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
+    sent_packet_manager_.AdjustPendingTimerTransmissions();
+  }
+  if (retransmission_mode != QuicSentPacketManager::LOSS_MODE &&
+      retransmission_mode != QuicSentPacketManager::HANDSHAKE_MODE) {
+    // When timer fires in TLP/RTO/PTO mode, ensure 1) at least one packet is
+    // created, or there is data to send and available credit (such that
+    // packets will be sent eventually).
+    QUIC_BUG_IF(
+        quic_bug_12714_27,
+        packet_creator_.packet_number() == previous_created_packet_number &&
+            (!visitor_->WillingAndAbleToWrite() ||
+             sent_packet_manager_.pending_timer_transmission_count() == 0u))
+        << "retransmission_mode: " << retransmission_mode
+        << ", packet_number: " << packet_creator_.packet_number()
+        << ", session has data to write: " << visitor_->WillingAndAbleToWrite()
+        << ", writer is blocked: " << writer_->IsWriteBlocked()
+        << ", pending_timer_transmission_count: "
+        << sent_packet_manager_.pending_timer_transmission_count();
+  }
+
+  // Ensure the retransmission alarm is always set if there are unacked packets
+  // and nothing waiting to be sent.
+  // This happens if the loss algorithm invokes a timer based loss, but the
+  // packet doesn't need to be retransmitted.
+  if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
+    SetRetransmissionAlarm();
+  }
+}
+
+void QuicConnection::SetEncrypter(EncryptionLevel level,
+                                  std::unique_ptr<QuicEncrypter> encrypter) {
+  packet_creator_.SetEncrypter(level, std::move(encrypter));
+}
+
+void QuicConnection::RemoveEncrypter(EncryptionLevel level) {
+  framer_.RemoveEncrypter(level);
+}
+
+void QuicConnection::SetDiversificationNonce(
+    const DiversificationNonce& nonce) {
+  QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+  packet_creator_.SetDiversificationNonce(nonce);
+}
+
+void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
+  QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from "
+                << encryption_level_ << " to " << level;
+  const bool changing_level = level != encryption_level_;
+  if (changing_level && packet_creator_.HasPendingFrames()) {
+    // Flush all queued frames when encryption level changes.
+    ScopedPacketFlusher flusher(this);
+    packet_creator_.FlushCurrentPacket();
+  }
+  encryption_level_ = level;
+  packet_creator_.set_encryption_level(level);
+  QUIC_BUG_IF(quic_bug_12714_28, !framer_.HasEncrypterOfEncryptionLevel(level))
+      << ENDPOINT << "Trying to set encryption level to "
+      << EncryptionLevelToString(level) << " while the key is missing";
+
+  if (!changing_level) {
+    return;
+  }
+  // The least packet awaited by the peer depends on the encryption level so
+  // we recalculate it here.
+  packet_creator_.UpdatePacketNumberLength(
+      sent_packet_manager_.GetLeastPacketAwaitedByPeer(encryption_level_),
+      sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
+}
+
+void QuicConnection::SetDecrypter(EncryptionLevel level,
+                                  std::unique_ptr<QuicDecrypter> decrypter) {
+  framer_.SetDecrypter(level, std::move(decrypter));
+
+  if (!undecryptable_packets_.empty() &&
+      !process_undecryptable_packets_alarm_->IsSet()) {
+    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::SetAlternativeDecrypter(
+    EncryptionLevel level,
+    std::unique_ptr<QuicDecrypter> decrypter,
+    bool latch_once_used) {
+  framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
+
+  if (!undecryptable_packets_.empty() &&
+      !process_undecryptable_packets_alarm_->IsSet()) {
+    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::InstallDecrypter(
+    EncryptionLevel level,
+    std::unique_ptr<QuicDecrypter> decrypter) {
+  if (level == ENCRYPTION_ZERO_RTT) {
+    had_zero_rtt_decrypter_ = true;
+  }
+  framer_.InstallDecrypter(level, std::move(decrypter));
+  if (!undecryptable_packets_.empty() &&
+      !process_undecryptable_packets_alarm_->IsSet()) {
+    process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
+  framer_.RemoveDecrypter(level);
+}
+
+void QuicConnection::DiscardPreviousOneRttKeys() {
+  framer_.DiscardPreviousOneRttKeys();
+}
+
+bool QuicConnection::IsKeyUpdateAllowed() const {
+  return support_key_update_for_connection_ &&
+         GetLargestAckedPacket().IsInitialized() &&
+         lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
+         GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_;
+}
+
+bool QuicConnection::HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const {
+  return lowest_packet_sent_in_current_key_phase_.IsInitialized() &&
+         (!GetLargestAckedPacket().IsInitialized() ||
+          GetLargestAckedPacket() < lowest_packet_sent_in_current_key_phase_);
+}
+
+QuicPacketCount QuicConnection::PotentialPeerKeyUpdateAttemptCount() const {
+  return framer_.PotentialPeerKeyUpdateAttemptCount();
+}
+
+bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) {
+  QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate";
+  if (!IsKeyUpdateAllowed()) {
+    QUIC_BUG(quic_bug_10511_28) << "key update not allowed";
+    return false;
+  }
+  return framer_.DoKeyUpdate(reason);
+}
+
+const QuicDecrypter* QuicConnection::decrypter() const {
+  return framer_.decrypter();
+}
+
+const QuicDecrypter* QuicConnection::alternative_decrypter() const {
+  return framer_.alternative_decrypter();
+}
+
+void QuicConnection::QueueUndecryptablePacket(
+    const QuicEncryptedPacket& packet,
+    EncryptionLevel decryption_level) {
+  for (const auto& saved_packet : undecryptable_packets_) {
+    if (packet.data() == saved_packet.packet->data() &&
+        packet.length() == saved_packet.packet->length()) {
+      QUIC_DVLOG(1) << ENDPOINT << "Not queueing known undecryptable packet";
+      return;
+    }
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet.";
+  undecryptable_packets_.emplace_back(packet, decryption_level,
+                                      last_received_packet_info_);
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
+      SetRetransmissionAlarm();
+    } else if (!retransmission_alarm_->IsSet() ||
+               GetRetransmissionDeadline() <
+                   retransmission_alarm_->deadline()) {
+      // Re-arm PTO only if we can make it sooner to speed up recovery.
+      SetRetransmissionAlarm();
+    }
+  }
+}
+
+void QuicConnection::MaybeProcessUndecryptablePackets() {
+  process_undecryptable_packets_alarm_->Cancel();
+
+  if (undecryptable_packets_.empty() ||
+      encryption_level_ == ENCRYPTION_INITIAL) {
+    return;
+  }
+
+  auto iter = undecryptable_packets_.begin();
+  while (connected_ && iter != undecryptable_packets_.end()) {
+    // Making sure there is no pending frames when processing next undecrypted
+    // packet because the queued ack frame may change.
+    packet_creator_.FlushCurrentPacket();
+    if (!connected_) {
+      return;
+    }
+    UndecryptablePacket* undecryptable_packet = &*iter;
+    QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
+    if (debug_visitor_ != nullptr) {
+      debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
+          undecryptable_packet->encryption_level);
+    }
+    last_received_packet_info_ = undecryptable_packet->packet_info;
+    last_size_ = undecryptable_packet->packet->length();
+    current_packet_data_ = undecryptable_packet->packet->data();
+    const bool processed = framer_.ProcessPacket(*undecryptable_packet->packet);
+    current_packet_data_ = nullptr;
+
+    if (processed) {
+      QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
+      iter = undecryptable_packets_.erase(iter);
+      ++stats_.packets_processed;
+      continue;
+    }
+    const bool has_decryption_key = version().KnowsWhichDecrypterToUse() &&
+                                    framer_.HasDecrypterOfEncryptionLevel(
+                                        undecryptable_packet->encryption_level);
+    if (framer_.error() == QUIC_DECRYPTION_FAILURE &&
+        ShouldEnqueueUnDecryptablePacket(undecryptable_packet->encryption_level,
+                                         has_decryption_key)) {
+      QUIC_DVLOG(1)
+          << ENDPOINT
+          << "Need to attempt to process this undecryptable packet later";
+      ++iter;
+      continue;
+    }
+    iter = undecryptable_packets_.erase(iter);
+  }
+
+  // Once handshake is complete, there will be no new keys installed and hence
+  // any undecryptable packets will never be able to be decrypted.
+  if (IsHandshakeComplete()) {
+    if (debug_visitor_ != nullptr) {
+      for (const auto& undecryptable_packet : undecryptable_packets_) {
+        debug_visitor_->OnUndecryptablePacket(
+            undecryptable_packet.encryption_level, /*dropped=*/true);
+      }
+    }
+    undecryptable_packets_.clear();
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
+      SetRetransmissionAlarm();
+    } else if (!retransmission_alarm_->IsSet() ||
+               undecryptable_packets_.empty() ||
+               GetRetransmissionDeadline() <
+                   retransmission_alarm_->deadline()) {
+      // 1) If there is still undecryptable packet, only re-arm PTO to make it
+      // sooner to speed up recovery.
+      // 2) If all undecryptable packets get processed, re-arm (which may
+      // postpone) PTO since no immediate recovery is needed.
+      SetRetransmissionAlarm();
+    }
+  }
+}
+
+void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) {
+  QUIC_DVLOG(1) << ENDPOINT << "Queueing coalesced packet.";
+  received_coalesced_packets_.push_back(packet.Clone());
+  ++stats_.num_coalesced_packets_received;
+}
+
+bool QuicConnection::MaybeProcessCoalescedPackets() {
+  bool processed = false;
+  while (connected_ && !received_coalesced_packets_.empty()) {
+    // Making sure there are no pending frames when processing the next
+    // coalesced packet because the queued ack frame may change.
+    packet_creator_.FlushCurrentPacket();
+    if (!connected_) {
+      return processed;
+    }
+
+    std::unique_ptr<QuicEncryptedPacket> packet =
+        std::move(received_coalesced_packets_.front());
+    received_coalesced_packets_.pop_front();
+
+    QUIC_DVLOG(1) << ENDPOINT << "Processing coalesced packet";
+    if (framer_.ProcessPacket(*packet)) {
+      processed = true;
+      ++stats_.num_coalesced_packets_processed;
+    } else {
+      // If we are unable to decrypt this packet, it might be
+      // because the CHLO or SHLO packet was lost.
+    }
+  }
+  if (processed) {
+    MaybeProcessUndecryptablePackets();
+    MaybeSendInResponseToPacket();
+  }
+  return processed;
+}
+
+void QuicConnection::CloseConnection(
+    QuicErrorCode error,
+    const std::string& details,
+    ConnectionCloseBehavior connection_close_behavior) {
+  CloseConnection(error, NO_IETF_QUIC_ERROR, details,
+                  connection_close_behavior);
+}
+
+void QuicConnection::CloseConnection(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& error_details,
+    ConnectionCloseBehavior connection_close_behavior) {
+  QUICHE_DCHECK(!error_details.empty());
+  if (!connected_) {
+    QUIC_DLOG(INFO) << "Connection is already closed.";
+    return;
+  }
+
+  if (ietf_error != NO_IETF_QUIC_ERROR) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
+                    << ", with wire error: " << ietf_error
+                    << ", error: " << QuicErrorCodeToString(error)
+                    << ", and details:  " << error_details;
+  } else {
+    QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
+                    << ", with error: " << QuicErrorCodeToString(error) << " ("
+                    << error << "), and details:  " << error_details;
+  }
+
+  if (connection_close_behavior != ConnectionCloseBehavior::SILENT_CLOSE) {
+    SendConnectionClosePacket(error, ietf_error, error_details);
+  }
+
+  TearDownLocalConnectionState(error, ietf_error, error_details,
+                               ConnectionCloseSource::FROM_SELF);
+}
+
+void QuicConnection::SendConnectionClosePacket(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& details) {
+  // Always use the current path to send CONNECTION_CLOSE.
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &packet_creator_, peer_address(), default_path_.client_connection_id,
+      default_path_.server_connection_id, connection_migration_use_new_cid_);
+  if (!SupportsMultiplePacketNumberSpaces()) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
+    ScopedEncryptionLevelContext context(this,
+                                         GetConnectionCloseEncryptionLevel());
+    if (version().CanSendCoalescedPackets()) {
+      coalesced_packet_.Clear();
+    }
+    ClearQueuedPackets();
+    // If there was a packet write error, write the smallest close possible.
+    ScopedPacketFlusher flusher(this);
+    // Always bundle an ACK with connection close for debugging purpose.
+    if (error != QUIC_PACKET_WRITE_ERROR &&
+        !uber_received_packet_manager_.IsAckFrameEmpty(
+            QuicUtils::GetPacketNumberSpace(encryption_level_)) &&
+        !packet_creator_.has_ack()) {
+      SendAck();
+    }
+    QuicConnectionCloseFrame* frame;
+
+    frame = new QuicConnectionCloseFrame(transport_version(), error, ietf_error,
+                                         details,
+                                         framer_.current_received_frame_type());
+    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
+    packet_creator_.FlushCurrentPacket();
+    if (version().CanSendCoalescedPackets()) {
+      FlushCoalescedPacket();
+    }
+    ClearQueuedPackets();
+    return;
+  }
+  ScopedPacketFlusher flusher(this);
+
+  // Now that the connection is being closed, discard any unsent packets
+  // so the only packets to be sent will be connection close packets.
+  if (version().CanSendCoalescedPackets()) {
+    coalesced_packet_.Clear();
+  }
+  ClearQueuedPackets();
+
+  for (EncryptionLevel level :
+       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+        ENCRYPTION_FORWARD_SECURE}) {
+    if (!framer_.HasEncrypterOfEncryptionLevel(level)) {
+      continue;
+    }
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Sending connection close packet at level: " << level;
+    ScopedEncryptionLevelContext context(this, level);
+    // Bundle an ACK of the corresponding packet number space for debugging
+    // purpose.
+    if (error != QUIC_PACKET_WRITE_ERROR &&
+        !uber_received_packet_manager_.IsAckFrameEmpty(
+            QuicUtils::GetPacketNumberSpace(encryption_level_)) &&
+        !packet_creator_.has_ack()) {
+      QuicFrames frames;
+      frames.push_back(GetUpdatedAckFrame());
+      packet_creator_.FlushAckFrame(frames);
+    }
+
+    if (level == ENCRYPTION_FORWARD_SECURE &&
+        perspective_ == Perspective::IS_SERVER) {
+      visitor_->BeforeConnectionCloseSent();
+    }
+
+    auto* frame = new QuicConnectionCloseFrame(
+        transport_version(), error, ietf_error, details,
+        framer_.current_received_frame_type());
+    if (level == ENCRYPTION_FORWARD_SECURE) {
+      if (connection_close_frame_sent_.has_value()) {
+        QUIC_BUG(quic_send_multiple_connection_closes)
+            << ENDPOINT << "Already sent connection close: "
+            << connection_close_frame_sent_.value()
+            << ", going to send connection close: " << *frame;
+      } else {
+        connection_close_frame_sent_ = *frame;
+      }
+    }
+    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
+    packet_creator_.FlushCurrentPacket();
+  }
+  if (version().CanSendCoalescedPackets()) {
+    FlushCoalescedPacket();
+  }
+  // Since the connection is closing, if the connection close packets were not
+  // sent, then they should be discarded.
+  ClearQueuedPackets();
+}
+
+void QuicConnection::TearDownLocalConnectionState(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& error_details,
+    ConnectionCloseSource source) {
+  QuicConnectionCloseFrame frame(transport_version(), error, ietf_error,
+                                 error_details,
+                                 framer_.current_received_frame_type());
+  return TearDownLocalConnectionState(frame, source);
+}
+
+void QuicConnection::TearDownLocalConnectionState(
+    const QuicConnectionCloseFrame& frame,
+    ConnectionCloseSource source) {
+  if (!connected_) {
+    QUIC_DLOG(INFO) << "Connection is already closed.";
+    return;
+  }
+
+  // If we are using a batch writer, flush packets queued in it, if any.
+  FlushPackets();
+  connected_ = false;
+  QUICHE_DCHECK(visitor_ != nullptr);
+  visitor_->OnConnectionClosed(frame, source);
+  // LossDetectionTunerInterface::Finish() may be called from
+  // sent_packet_manager_.OnConnectionClosed. Which may require the session to
+  // finish its business first.
+  sent_packet_manager_.OnConnectionClosed();
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnConnectionClosed(frame, source);
+  }
+  // Cancel the alarms so they don't trigger any action now that the
+  // connection is closed.
+  CancelAllAlarms();
+  if (use_path_validator_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_pass_path_response_to_validator, 3, 4);
+    CancelPathValidation();
+  }
+  peer_issued_cid_manager_.reset();
+  self_issued_cid_manager_.reset();
+}
+
+void QuicConnection::CancelAllAlarms() {
+  QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
+
+  ack_alarm_->PermanentCancel();
+  ping_alarm_->PermanentCancel();
+  retransmission_alarm_->PermanentCancel();
+  send_alarm_->PermanentCancel();
+  mtu_discovery_alarm_->PermanentCancel();
+  process_undecryptable_packets_alarm_->PermanentCancel();
+  discard_previous_one_rtt_keys_alarm_->PermanentCancel();
+  discard_zero_rtt_decryption_keys_alarm_->PermanentCancel();
+  blackhole_detector_.StopDetection(/*permanent=*/true);
+  idle_network_detector_.StopDetection();
+}
+
+QuicByteCount QuicConnection::max_packet_length() const {
+  return packet_creator_.max_packet_length();
+}
+
+void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
+  long_term_mtu_ = length;
+  stats_.max_egress_mtu = std::max(stats_.max_egress_mtu, long_term_mtu_);
+  MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+
+bool QuicConnection::HasQueuedData() const {
+  return packet_creator_.HasPendingFrames() || !buffered_packets_.empty();
+}
+
+void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
+                                        QuicTime::Delta idle_timeout) {
+  QUIC_BUG_IF(quic_bug_12714_29, idle_timeout > handshake_timeout)
+      << "idle_timeout:" << idle_timeout.ToMilliseconds()
+      << " handshake_timeout:" << handshake_timeout.ToMilliseconds();
+  // Adjust the idle timeout on client and server to prevent clients from
+  // sending requests to servers which have already closed the connection.
+  if (perspective_ == Perspective::IS_SERVER) {
+    idle_timeout = idle_timeout + QuicTime::Delta::FromSeconds(3);
+  } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) {
+    idle_timeout = idle_timeout - QuicTime::Delta::FromSeconds(1);
+  }
+  idle_network_detector_.SetTimeouts(handshake_timeout, idle_timeout);
+}
+
+void QuicConnection::SetPingAlarm() {
+  if (!connected_) {
+    return;
+  }
+  if (perspective_ == Perspective::IS_SERVER &&
+      initial_retransmittable_on_wire_timeout_.IsInfinite()) {
+    // The PING alarm exists to support two features:
+    // 1) clients send PINGs every 15s to prevent NAT timeouts,
+    // 2) both clients and servers can send retransmittable on the wire PINGs
+    // (ROWP) while ShouldKeepConnectionAlive is true and there is no packets in
+    // flight.
+    return;
+  }
+  if (!visitor_->ShouldKeepConnectionAlive()) {
+    ping_alarm_->Cancel();
+    // Don't send a ping unless the application (ie: HTTP/3) says to, usually
+    // because it is expecting a response from the server.
+    return;
+  }
+  if (initial_retransmittable_on_wire_timeout_.IsInfinite() ||
+      sent_packet_manager_.HasInFlightPackets() ||
+      retransmittable_on_wire_ping_count_ >
+          GetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count)) {
+    if (perspective_ == Perspective::IS_CLIENT) {
+      // Clients send 15s PINGs to avoid NATs from timing out.
+      ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
+                          QuicTime::Delta::FromSeconds(1));
+    } else {
+      // Servers do not send 15s PINGs.
+      ping_alarm_->Cancel();
+    }
+    return;
+  }
+  QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_, ping_timeout_);
+  QuicTime::Delta retransmittable_on_wire_timeout =
+      initial_retransmittable_on_wire_timeout_;
+  int max_aggressive_retransmittable_on_wire_ping_count =
+      GetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count);
+  QUICHE_DCHECK_LE(0, max_aggressive_retransmittable_on_wire_ping_count);
+  if (consecutive_retransmittable_on_wire_ping_count_ >
+      max_aggressive_retransmittable_on_wire_ping_count) {
+    // Exponentially back off the timeout if the number of consecutive
+    // retransmittable on wire pings has exceeds the allowance.
+    int shift = consecutive_retransmittable_on_wire_ping_count_ -
+                max_aggressive_retransmittable_on_wire_ping_count;
+    retransmittable_on_wire_timeout =
+        initial_retransmittable_on_wire_timeout_ * (1 << shift);
+  }
+  // If it's already set to an earlier time, then don't update it.
+  if (ping_alarm_->IsSet() &&
+      ping_alarm_->deadline() <
+          clock_->ApproximateNow() + retransmittable_on_wire_timeout) {
+    return;
+  }
+
+  if (retransmittable_on_wire_timeout < ping_timeout_) {
+    // Use a shorter timeout if there are open streams, but nothing on the wire.
+    ping_alarm_->Update(
+        clock_->ApproximateNow() + retransmittable_on_wire_timeout,
+        kAlarmGranularity);
+    if (max_aggressive_retransmittable_on_wire_ping_count != 0) {
+      consecutive_retransmittable_on_wire_ping_count_++;
+    }
+    retransmittable_on_wire_ping_count_++;
+    return;
+  }
+
+  ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
+                      kAlarmGranularity);
+}
+
+void QuicConnection::SetRetransmissionAlarm() {
+  if (!connected_) {
+    if (retransmission_alarm_->IsSet()) {
+      QUIC_BUG(quic_bug_10511_29)
+          << ENDPOINT << "Retransmission alarm is set while disconnected";
+      retransmission_alarm_->Cancel();
+    }
+    return;
+  }
+  if (packet_creator_.PacketFlusherAttached()) {
+    pending_retransmission_alarm_ = true;
+    return;
+  }
+  if (LimitedByAmplificationFactor()) {
+    // Do not set retransmission timer if connection is anti-amplification limit
+    // throttled. Otherwise, nothing can be sent when timer fires.
+    retransmission_alarm_->Cancel();
+    return;
+  }
+  PacketNumberSpace packet_number_space;
+  if (sent_packet_manager_.simplify_set_retransmission_alarm() &&
+      SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
+      !sent_packet_manager_
+           .GetEarliestPacketSentTimeForPto(&packet_number_space)
+           .IsInitialized()) {
+    // Before handshake gets confirmed, GetEarliestPacketSentTimeForPto
+    // returning 0 indicates no packets are in flight or only application data
+    // is in flight.
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 2, 2);
+    if (perspective_ == Perspective::IS_SERVER) {
+      // No need to arm PTO on server side.
+      retransmission_alarm_->Cancel();
+      return;
+    }
+    if (retransmission_alarm_->IsSet() &&
+        GetRetransmissionDeadline() > retransmission_alarm_->deadline()) {
+      // Do not postpone armed PTO on the client side.
+      return;
+    }
+  }
+
+  retransmission_alarm_->Update(GetRetransmissionDeadline(), kAlarmGranularity);
+}
+
+void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
+  if (mtu_discovery_alarm_->IsSet() ||
+      !mtu_discoverer_.ShouldProbeMtu(sent_packet_number)) {
+    return;
+  }
+  mtu_discovery_alarm_->Set(clock_->ApproximateNow());
+}
+
+QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
+    QuicConnection* connection)
+    : connection_(connection),
+      flush_and_set_pending_retransmission_alarm_on_delete_(false),
+      handshake_packet_sent_(connection != nullptr &&
+                             connection->handshake_packet_sent_) {
+  if (connection_ == nullptr) {
+    return;
+  }
+
+  if (!connection_->packet_creator_.PacketFlusherAttached()) {
+    flush_and_set_pending_retransmission_alarm_on_delete_ = true;
+    connection->packet_creator_.AttachPacketFlusher();
+  }
+}
+
+QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
+  if (connection_ == nullptr || !connection_->connected()) {
+    return;
+  }
+
+  if (flush_and_set_pending_retransmission_alarm_on_delete_) {
+    const QuicTime ack_timeout =
+        connection_->uber_received_packet_manager_.GetEarliestAckTimeout();
+    if (ack_timeout.IsInitialized()) {
+      if (ack_timeout <= connection_->clock_->ApproximateNow() &&
+          !connection_->CanWrite(NO_RETRANSMITTABLE_DATA)) {
+        // Cancel ACK alarm if connection is write blocked, and ACK will be
+        // sent when connection gets unblocked.
+        connection_->ack_alarm_->Cancel();
+      } else if (!connection_->ack_alarm_->IsSet() ||
+                 connection_->ack_alarm_->deadline() > ack_timeout) {
+        connection_->ack_alarm_->Update(ack_timeout, QuicTime::Delta::Zero());
+      }
+    }
+    if (connection_->ack_alarm_->IsSet() &&
+        connection_->ack_alarm_->deadline() <=
+            connection_->clock_->ApproximateNow()) {
+      // An ACK needs to be sent right now. This ACK did not get bundled
+      // because either there was no data to write or packets were marked as
+      // received after frames were queued in the generator.
+      if (connection_->send_alarm_->IsSet() &&
+          connection_->send_alarm_->deadline() <=
+              connection_->clock_->ApproximateNow()) {
+        // If send alarm will go off soon, let send alarm send the ACK.
+        connection_->ack_alarm_->Cancel();
+      } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
+        connection_->SendAllPendingAcks();
+      } else {
+        connection_->SendAck();
+      }
+    }
+
+    if (connection_->flush_after_coalesce_higher_space_packets_) {
+      // INITIAL or HANDSHAKE retransmission could cause peer to derive new
+      // keys, such that the buffered undecryptable packets may be processed.
+      // This endpoint would derive an inflated RTT sample when receiving ACKs
+      // of those undecryptable packets. To mitigate this, tries to coalesce as
+      // many higher space packets as possible (via for loop inside
+      // MaybeCoalescePacketOfHigherSpace) to fill the remaining space in the
+      // coalescer.
+      QUIC_RELOADABLE_FLAG_COUNT(
+          quic_flush_after_coalesce_higher_space_packets);
+      if (connection_->version().CanSendCoalescedPackets()) {
+        connection_->MaybeCoalescePacketOfHigherSpace();
+      }
+      connection_->packet_creator_.Flush();
+      if (connection_->version().CanSendCoalescedPackets()) {
+        connection_->FlushCoalescedPacket();
+      }
+    } else {
+      connection_->packet_creator_.Flush();
+      if (connection_->version().CanSendCoalescedPackets()) {
+        connection_->MaybeCoalescePacketOfHigherSpace();
+        connection_->FlushCoalescedPacket();
+      }
+    }
+    connection_->FlushPackets();
+    if (!handshake_packet_sent_ && connection_->handshake_packet_sent_) {
+      // This would cause INITIAL key to be dropped. Drop keys here to avoid
+      // missing the write keys in the middle of writing.
+      connection_->visitor_->OnHandshakePacketSent();
+    }
+    // Reset transmission type.
+    connection_->SetTransmissionType(NOT_RETRANSMISSION);
+
+    // Once all transmissions are done, check if there is any outstanding data
+    // to send and notify the congestion controller if not.
+    //
+    // Note that this means that the application limited check will happen as
+    // soon as the last flusher gets destroyed, which is typically after a
+    // single stream write is finished.  This means that if all the data from a
+    // single write goes through the connection, the application-limited signal
+    // will fire even if the caller does a write operation immediately after.
+    // There are two important approaches to remedy this situation:
+    // (1) Instantiate ScopedPacketFlusher before performing multiple subsequent
+    //     writes, thus deferring this check until all writes are done.
+    // (2) Write data in chunks sufficiently large so that they cause the
+    //     connection to be limited by the congestion control.  Typically, this
+    //     would mean writing chunks larger than the product of the current
+    //     pacing rate and the pacer granularity.  So, for instance, if the
+    //     pacing rate of the connection is 1 Gbps, and the pacer granularity is
+    //     1 ms, the caller should send at least 125k bytes in order to not
+    //     be marked as application-limited.
+    connection_->CheckIfApplicationLimited();
+
+    if (connection_->pending_retransmission_alarm_) {
+      connection_->SetRetransmissionAlarm();
+      connection_->pending_retransmission_alarm_ = false;
+    }
+  }
+  QUICHE_DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
+                   !connection_->packet_creator_.PacketFlusherAttached());
+}
+
+QuicConnection::ScopedEncryptionLevelContext::ScopedEncryptionLevelContext(
+    QuicConnection* connection,
+    EncryptionLevel encryption_level)
+    : connection_(connection), latched_encryption_level_(ENCRYPTION_INITIAL) {
+  if (connection_ == nullptr) {
+    return;
+  }
+  latched_encryption_level_ = connection_->encryption_level_;
+  connection_->SetDefaultEncryptionLevel(encryption_level);
+}
+
+QuicConnection::ScopedEncryptionLevelContext::~ScopedEncryptionLevelContext() {
+  if (connection_ == nullptr || !connection_->connected_) {
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(latched_encryption_level_);
+}
+
+QuicConnection::BufferedPacket::BufferedPacket(
+    const SerializedPacket& packet,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address)
+    : encrypted_buffer(CopyBuffer(packet), packet.encrypted_length),
+      self_address(self_address),
+      peer_address(peer_address) {}
+
+QuicConnection::BufferedPacket::BufferedPacket(
+    char* encrypted_buffer,
+    QuicPacketLength encrypted_length,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address)
+    : encrypted_buffer(CopyBuffer(encrypted_buffer, encrypted_length),
+                       encrypted_length),
+      self_address(self_address),
+      peer_address(peer_address) {}
+
+QuicConnection::BufferedPacket::~BufferedPacket() {
+  delete[] encrypted_buffer.data();
+}
+
+HasRetransmittableData QuicConnection::IsRetransmittable(
+    const SerializedPacket& packet) {
+  // Retransmitted packets retransmittable frames are owned by the unacked
+  // packet map, but are not present in the serialized packet.
+  if (packet.transmission_type != NOT_RETRANSMISSION ||
+      !packet.retransmittable_frames.empty()) {
+    return HAS_RETRANSMITTABLE_DATA;
+  } else {
+    return NO_RETRANSMITTABLE_DATA;
+  }
+}
+
+bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet,
+                                         QuicErrorCode* error_code) {
+  if (packet.retransmittable_frames.empty()) {
+    return false;
+  }
+  for (const QuicFrame& frame : packet.retransmittable_frames) {
+    if (frame.type == CONNECTION_CLOSE_FRAME) {
+      *error_code = frame.connection_close_frame->quic_error_code;
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
+  QUIC_DVLOG(2) << ENDPOINT << "SetMtuDiscoveryTarget: " << target;
+  mtu_discoverer_.Disable();
+  mtu_discoverer_.Enable(max_packet_length(), GetLimitedMaxPacketSize(target));
+}
+
+QuicByteCount QuicConnection::GetLimitedMaxPacketSize(
+    QuicByteCount suggested_max_packet_size) {
+  if (!peer_address().IsInitialized()) {
+    QUIC_BUG(quic_bug_10511_30)
+        << "Attempted to use a connection without a valid peer address";
+    return suggested_max_packet_size;
+  }
+
+  const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
+
+  QuicByteCount max_packet_size = suggested_max_packet_size;
+  if (max_packet_size > writer_limit) {
+    max_packet_size = writer_limit;
+  }
+  if (max_packet_size > peer_max_packet_size_) {
+    max_packet_size = peer_max_packet_size_;
+  }
+  if (max_packet_size > kMaxOutgoingPacketSize) {
+    max_packet_size = kMaxOutgoingPacketSize;
+  }
+  return max_packet_size;
+}
+
+void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
+  // Currently, this limit is ensured by the caller.
+  QUICHE_DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
+
+  // Send the probe.
+  packet_creator_.GenerateMtuDiscoveryPacket(target_mtu);
+}
+
+// TODO(zhongyi): change this method to generate a connectivity probing packet
+// and let the caller to call writer to write the packet and handle write
+// status.
+bool QuicConnection::SendConnectivityProbingPacket(
+    QuicPacketWriter* probing_writer,
+    const QuicSocketAddress& peer_address) {
+  QUICHE_DCHECK(peer_address.IsInitialized());
+  if (!connected_) {
+    QUIC_BUG(quic_bug_10511_31)
+        << "Not sending connectivity probing packet as connection is "
+        << "disconnected.";
+    return false;
+  }
+  if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
+    // Server can use default packet writer to write packet.
+    probing_writer = writer_;
+  }
+  QUICHE_DCHECK(probing_writer);
+
+  if (probing_writer->IsWriteBlocked()) {
+    QUIC_DLOG(INFO)
+        << ENDPOINT
+        << "Writer blocked when sending connectivity probing packet.";
+    if (probing_writer == writer_) {
+      // Visitor should not be write blocked if the probing writer is not the
+      // default packet writer.
+      visitor_->OnWriteBlocked();
+    }
+    return true;
+  }
+
+  QUIC_DLOG(INFO) << ENDPOINT
+                  << "Sending path probe packet for connection_id = "
+                  << default_path_.server_connection_id;
+
+  std::unique_ptr<SerializedPacket> probing_packet;
+  if (!version().HasIetfQuicFrames()) {
+    // Non-IETF QUIC, generate a padded ping regardless of whether this is a
+    // request or a response.
+    probing_packet = packet_creator_.SerializeConnectivityProbingPacket();
+  } else {
+    // IETF QUIC path challenge.
+    // Send a path probe request using IETF QUIC PATH_CHALLENGE frame.
+    transmitted_connectivity_probe_payload_ =
+        std::make_unique<QuicPathFrameBuffer>();
+    random_generator_->RandBytes(transmitted_connectivity_probe_payload_.get(),
+                                 sizeof(QuicPathFrameBuffer));
+    probing_packet =
+        packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+            *transmitted_connectivity_probe_payload_);
+    if (!probing_packet) {
+      transmitted_connectivity_probe_payload_ = nullptr;
+    }
+  }
+  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
+  return WritePacketUsingWriter(std::move(probing_packet), probing_writer,
+                                self_address(), peer_address,
+                                /*measure_rtt=*/true);
+}
+
+bool QuicConnection::WritePacketUsingWriter(
+    std::unique_ptr<SerializedPacket> packet,
+    QuicPacketWriter* writer,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    bool measure_rtt) {
+  const QuicTime packet_send_time = clock_->Now();
+  QUIC_DVLOG(2) << ENDPOINT
+                << "Sending path probe packet for server connection ID "
+                << default_path_.server_connection_id << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       packet->encrypted_buffer, packet->encrypted_length));
+  WriteResult result = writer->WritePacket(
+      packet->encrypted_buffer, packet->encrypted_length, self_address.host(),
+      peer_address, per_packet_options_);
+
+  // If using a batch writer and the probing packet is buffered, flush it.
+  if (writer->IsBatchMode() && result.status == WRITE_STATUS_OK &&
+      result.bytes_written == 0) {
+    result = writer->Flush();
+  }
+
+  if (IsWriteError(result.status)) {
+    // Write error for any connectivity probe should not affect the connection
+    // as it is sent on a different path.
+    QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
+                    << result.error_code;
+    return false;
+  }
+
+  // Send in currrent path. Call OnPacketSent regardless of the write result.
+  sent_packet_manager_.OnPacketSent(packet.get(), packet_send_time,
+                                    packet->transmission_type,
+                                    NO_RETRANSMITTABLE_DATA, measure_rtt);
+
+  if (debug_visitor_ != nullptr) {
+    if (sent_packet_manager_.unacked_packets().empty()) {
+      QUIC_BUG(quic_bug_10511_32)
+          << "Unacked map is empty right after packet is sent";
+    } else {
+      debug_visitor_->OnPacketSent(
+          packet->packet_number, packet->encrypted_length,
+          packet->has_crypto_handshake, packet->transmission_type,
+          packet->encryption_level,
+          sent_packet_manager_.unacked_packets()
+              .rbegin()
+              ->retransmittable_frames,
+          packet->nonretransmittable_frames, packet_send_time);
+    }
+  }
+
+  if (IsWriteBlockedStatus(result.status)) {
+    if (writer == writer_) {
+      // Visitor should not be write blocked if the probing writer is not the
+      // default packet writer.
+      visitor_->OnWriteBlocked();
+    }
+    if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
+    }
+  }
+
+  return true;
+}
+
+void QuicConnection::DisableMtuDiscovery() {
+  mtu_discoverer_.Disable();
+  mtu_discovery_alarm_->Cancel();
+}
+
+void QuicConnection::DiscoverMtu() {
+  QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
+
+  const QuicPacketNumber largest_sent_packet =
+      sent_packet_manager_.GetLargestSentPacket();
+  if (mtu_discoverer_.ShouldProbeMtu(largest_sent_packet)) {
+    ++mtu_probe_count_;
+    SendMtuDiscoveryPacket(
+        mtu_discoverer_.GetUpdatedMtuProbeSize(largest_sent_packet));
+  }
+  QUICHE_DCHECK(!mtu_discovery_alarm_->IsSet());
+}
+
+void QuicConnection::OnEffectivePeerMigrationValidated() {
+  if (active_effective_peer_migration_type_ == NO_CHANGE) {
+    QUIC_BUG(quic_bug_10511_33) << "No migration underway.";
+    return;
+  }
+  highest_packet_sent_before_effective_peer_migration_.Clear();
+  const bool send_address_token =
+      active_effective_peer_migration_type_ != PORT_CHANGE;
+  active_effective_peer_migration_type_ = NO_CHANGE;
+  ++stats_.num_validated_peer_migration;
+  if (!validate_client_addresses_) {
+    return;
+  }
+  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 2, 6);
+  if (debug_visitor_ != nullptr) {
+    const QuicTime now = clock_->ApproximateNow();
+    if (now >= stats_.handshake_completion_time) {
+      debug_visitor_->OnPeerMigrationValidated(
+          now - stats_.handshake_completion_time);
+    } else {
+      QUIC_BUG(quic_bug_10511_34)
+          << "Handshake completion time is larger than current time.";
+    }
+  }
+
+  // Lift anti-amplification limit.
+  default_path_.validated = true;
+  alternative_path_.Clear();
+  if (send_address_token) {
+    visitor_->MaybeSendAddressToken();
+  }
+}
+
+void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
+  // TODO(fayang): Currently, all peer address change type are allowed. Need to
+  // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
+  // determine whether |type| is allowed.
+  if (!validate_client_addresses_) {
+    if (type == NO_CHANGE) {
+      QUIC_BUG(quic_bug_10511_35)
+          << "EffectivePeerMigration started without address change.";
+      return;
+    }
+    QUIC_DLOG(INFO)
+        << ENDPOINT << "Effective peer's ip:port changed from "
+        << default_path_.peer_address.ToString() << " to "
+        << GetEffectivePeerAddressFromCurrentPacket().ToString()
+        << ", address change type is " << type
+        << ", migrating connection without validating new client address.";
+
+    highest_packet_sent_before_effective_peer_migration_ =
+        sent_packet_manager_.GetLargestSentPacket();
+    default_path_.peer_address = GetEffectivePeerAddressFromCurrentPacket();
+    active_effective_peer_migration_type_ = type;
+
+    OnConnectionMigration();
+    return;
+  }
+
+  QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 3, 6);
+  if (type == NO_CHANGE) {
+    UpdatePeerAddress(last_received_packet_info_.source_address);
+    QUIC_BUG(quic_bug_10511_36)
+        << "EffectivePeerMigration started without address change.";
+    return;
+  }
+  if (GetQuicReloadableFlag(
+          quic_flush_pending_frames_and_padding_bytes_on_migration)) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_flush_pending_frames_and_padding_bytes_on_migration);
+    // There could be pending NEW_TOKEN_FRAME triggered by non-probing
+    // PATH_RESPONSE_FRAME in the same packet or pending padding bytes in the
+    // packet creator.
+    packet_creator_.FlushCurrentPacket();
+    packet_creator_.SendRemainingPendingPadding();
+    if (!connected_) {
+      return;
+    }
+  } else {
+    if (packet_creator_.HasPendingFrames()) {
+      packet_creator_.FlushCurrentPacket();
+      if (!connected_) {
+        return;
+      }
+    }
+  }
+
+  // Action items:
+  //   1. Switch congestion controller;
+  //   2. Update default_path_ (addresses, validation and bytes accounting);
+  //   3. Save previous default path if needed;
+  //   4. Kick off reverse path validation if needed.
+  // Items 1 and 2 are must-to-do. Items 3 and 4 depends on if the new address
+  // is validated or not and which path the incoming packet is on.
+
+  const QuicSocketAddress current_effective_peer_address =
+      GetEffectivePeerAddressFromCurrentPacket();
+  QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
+                  << default_path_.peer_address.ToString() << " to "
+                  << current_effective_peer_address.ToString()
+                  << ", address change type is " << type
+                  << ", migrating connection.";
+
+  const QuicSocketAddress previous_direct_peer_address = direct_peer_address_;
+  PathState previous_default_path = std::move(default_path_);
+  active_effective_peer_migration_type_ = type;
+  MaybeClearQueuedPacketsOnPathChange();
+  OnConnectionMigration();
+
+  // Update congestion controller if the address change type is not PORT_CHANGE.
+  if (type == PORT_CHANGE) {
+    QUICHE_DCHECK(previous_default_path.validated ||
+                  (alternative_path_.validated &&
+                   alternative_path_.send_algorithm != nullptr));
+    // No need to store previous congestion controller because either the new
+    // default path is validated or the alternative path is validated and
+    // already has associated congestion controller.
+  } else {
+    previous_default_path.rtt_stats.emplace();
+    previous_default_path.rtt_stats->CloneFrom(
+        *sent_packet_manager_.GetRttStats());
+    // If the new peer address share the same IP with the alternative path, the
+    // connection should switch to the congestion controller of the alternative
+    // path. Otherwise, the connection should use a brand new one.
+    // In order to re-use existing code in sent_packet_manager_, reset
+    // congestion controller to initial state first and then change to the one
+    // on alternative path.
+    // TODO(danzh) combine these two steps into one after deprecating gQUIC.
+    previous_default_path.send_algorithm = OnPeerIpAddressChanged();
+
+    if (alternative_path_.peer_address.host() ==
+            current_effective_peer_address.host() &&
+        alternative_path_.send_algorithm != nullptr) {
+      // Update the default path with the congestion controller of the
+      // alternative path.
+      sent_packet_manager_.SetSendAlgorithm(
+          alternative_path_.send_algorithm.release());
+      sent_packet_manager_.SetRttStats(
+          std::move(alternative_path_.rtt_stats).value());
+    }
+  }
+  // Update to the new peer address.
+  UpdatePeerAddress(last_received_packet_info_.source_address);
+  // Update the default path.
+  if (IsAlternativePath(last_received_packet_info_.destination_address,
+                        current_effective_peer_address)) {
+    SetDefaultPathState(std::move(alternative_path_));
+  } else {
+    QuicConnectionId client_connection_id;
+    absl::optional<StatelessResetToken> stateless_reset_token;
+    FindMatchingOrNewClientConnectionIdOrToken(
+        previous_default_path, alternative_path_,
+        last_packet_destination_connection_id_, &client_connection_id,
+        &stateless_reset_token);
+    SetDefaultPathState(PathState(
+        last_received_packet_info_.destination_address,
+        current_effective_peer_address, client_connection_id,
+        last_packet_destination_connection_id_, stateless_reset_token));
+    // The path is considered validated if its peer IP address matches any
+    // validated path's peer IP address.
+    default_path_.validated =
+        (alternative_path_.peer_address.host() ==
+             current_effective_peer_address.host() &&
+         alternative_path_.validated) ||
+        (previous_default_path.validated && type == PORT_CHANGE);
+  }
+  if (!last_received_packet_info_.received_bytes_counted) {
+    // Increment bytes counting on the new default path.
+    default_path_.bytes_received_before_address_validation += last_size_;
+    last_received_packet_info_.received_bytes_counted = true;
+  }
+
+  if (!previous_default_path.validated) {
+    // If the old address is under validation, cancel and fail it. Failing to
+    // validate the old path shouldn't take any effect.
+    QUIC_DVLOG(1) << "Cancel validation of previous peer address change to "
+                  << previous_default_path.peer_address
+                  << " upon peer migration to " << default_path_.peer_address;
+    path_validator_.CancelPathValidation();
+    ++stats_.num_peer_migration_while_validating_default_path;
+  }
+
+  // Clear alternative path if the new default path shares the same IP as the
+  // alternative path.
+  if (alternative_path_.peer_address.host() ==
+      default_path_.peer_address.host()) {
+    alternative_path_.Clear();
+  }
+
+  if (default_path_.validated) {
+    QUIC_DVLOG(1) << "Peer migrated to a validated address.";
+    // No need to save previous default path, validate new peer address or
+    // update bytes sent/received.
+    if (!(previous_default_path.validated && type == PORT_CHANGE)) {
+      // The alternative path was validated because of proactive reverse path
+      // validation.
+      ++stats_.num_peer_migration_to_proactively_validated_address;
+    }
+    OnEffectivePeerMigrationValidated();
+    return;
+  }
+
+  // The new default address is not validated yet. Anti-amplification limit is
+  // enforced.
+  QUICHE_DCHECK(EnforceAntiAmplificationLimit());
+  QUIC_DVLOG(1) << "Apply anti-amplification limit to effective peer address "
+                << default_path_.peer_address << " with "
+                << default_path_.bytes_sent_before_address_validation
+                << " bytes sent and "
+                << default_path_.bytes_received_before_address_validation
+                << " bytes received.";
+
+  QUICHE_DCHECK(!alternative_path_.peer_address.IsInitialized() ||
+                alternative_path_.peer_address.host() !=
+                    default_path_.peer_address.host());
+
+  // Save previous default path to the altenative path.
+  if (previous_default_path.validated) {
+    // The old path is a validated path which the connection might revert back
+    // to later. Store it as the alternative path.
+    alternative_path_ = std::move(previous_default_path);
+    QUICHE_DCHECK(alternative_path_.send_algorithm != nullptr);
+  }
+
+  // If the new address is not validated and the connection is not already
+  // validating that address, a new reverse path validation is needed.
+  if (!path_validator_.IsValidatingPeerAddress(
+          current_effective_peer_address)) {
+    ++stats_.num_reverse_path_validtion_upon_migration;
+    ValidatePath(std::make_unique<ReversePathValidationContext>(
+                     default_path_.self_address, peer_address(),
+                     default_path_.peer_address, this),
+                 std::make_unique<ReversePathValidationResultDelegate>(
+                     this, previous_direct_peer_address));
+  } else {
+    QUIC_DVLOG(1) << "Peer address " << default_path_.peer_address
+                  << " is already under validation, wait for result.";
+    ++stats_.num_peer_migration_to_proactively_validated_address;
+  }
+}
+
+void QuicConnection::OnConnectionMigration() {
+  if (debug_visitor_ != nullptr) {
+    const QuicTime now = clock_->ApproximateNow();
+    if (now >= stats_.handshake_completion_time) {
+      debug_visitor_->OnPeerAddressChange(
+          active_effective_peer_migration_type_,
+          now - stats_.handshake_completion_time);
+    }
+  }
+  visitor_->OnConnectionMigration(active_effective_peer_migration_type_);
+  if (active_effective_peer_migration_type_ != PORT_CHANGE &&
+      active_effective_peer_migration_type_ != IPV4_SUBNET_CHANGE &&
+      !validate_client_addresses_) {
+    sent_packet_manager_.OnConnectionMigration(/*reset_send_algorithm=*/false);
+  }
+}
+
+bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
+  return is_current_packet_connectivity_probing_;
+}
+
+bool QuicConnection::ack_frame_updated() const {
+  return uber_received_packet_manager_.IsAckFrameUpdated();
+}
+
+absl::string_view QuicConnection::GetCurrentPacket() {
+  if (current_packet_data_ == nullptr) {
+    return absl::string_view();
+  }
+  return absl::string_view(current_packet_data_, last_size_);
+}
+
+bool QuicConnection::MaybeConsiderAsMemoryCorruption(
+    const QuicStreamFrame& frame) {
+  if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
+      last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
+    return false;
+  }
+
+  if (perspective_ == Perspective::IS_SERVER &&
+      frame.data_length >= sizeof(kCHLO) &&
+      strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kCHLO),
+              sizeof(kCHLO)) == 0) {
+    return true;
+  }
+
+  if (perspective_ == Perspective::IS_CLIENT &&
+      frame.data_length >= sizeof(kREJ) &&
+      strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kREJ),
+              sizeof(kREJ)) == 0) {
+    return true;
+  }
+
+  return false;
+}
+
+void QuicConnection::MaybeSendProbingRetransmissions() {
+  QUICHE_DCHECK(fill_up_link_during_probing_);
+
+  // Don't send probing retransmissions until the handshake has completed.
+  if (!IsHandshakeComplete() ||
+      sent_packet_manager().HasUnackedCryptoPackets()) {
+    return;
+  }
+
+  if (probing_retransmission_pending_) {
+    QUIC_BUG(quic_bug_10511_37)
+        << "MaybeSendProbingRetransmissions is called while another call "
+           "to it is already in progress";
+    return;
+  }
+
+  probing_retransmission_pending_ = true;
+  SendProbingRetransmissions();
+  probing_retransmission_pending_ = false;
+}
+
+void QuicConnection::CheckIfApplicationLimited() {
+  if (!connected_ || probing_retransmission_pending_) {
+    return;
+  }
+
+  bool application_limited =
+      buffered_packets_.empty() && !visitor_->WillingAndAbleToWrite();
+
+  if (!application_limited) {
+    return;
+  }
+
+  if (fill_up_link_during_probing_) {
+    MaybeSendProbingRetransmissions();
+    if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+      return;
+    }
+  }
+
+  sent_packet_manager_.OnApplicationLimited();
+}
+
+bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
+  most_recent_frame_type_ = type;
+  if (version().HasIetfQuicFrames()) {
+    if (!QuicUtils::IsProbingFrame(type)) {
+      MaybeStartIetfPeerMigration();
+      return connected_;
+    }
+    QuicSocketAddress current_effective_peer_address =
+        GetEffectivePeerAddressFromCurrentPacket();
+    if (!count_bytes_on_alternative_path_separately_ ||
+        IsDefaultPath(last_received_packet_info_.destination_address,
+                      last_received_packet_info_.source_address)) {
+      return connected_;
+    }
+    QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 3, 5);
+    if (perspective_ == Perspective::IS_SERVER &&
+        type == PATH_CHALLENGE_FRAME &&
+        !IsAlternativePath(last_received_packet_info_.destination_address,
+                           current_effective_peer_address)) {
+      QUIC_DVLOG(1)
+          << "The peer is probing a new path with effective peer address "
+          << current_effective_peer_address << ",  self address "
+          << last_received_packet_info_.destination_address;
+      if (!validate_client_addresses_) {
+        QuicConnectionId client_cid;
+        absl::optional<StatelessResetToken> stateless_reset_token;
+        FindMatchingOrNewClientConnectionIdOrToken(
+            default_path_, alternative_path_,
+            last_packet_destination_connection_id_, &client_cid,
+            &stateless_reset_token);
+        alternative_path_ = PathState(
+            last_received_packet_info_.destination_address,
+            current_effective_peer_address, client_cid,
+            last_packet_destination_connection_id_, stateless_reset_token);
+      } else if (!default_path_.validated) {
+        QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 4, 6);
+        // Skip reverse path validation because either handshake hasn't
+        // completed or the connection is validating the default path. Using
+        // PATH_CHALLENGE to validate alternative client address before
+        // handshake gets comfirmed is meaningless because anyone can respond to
+        // it. If the connection is validating the default path, this
+        // alternative path is currently the only validated path which shouldn't
+        // be overridden.
+        QUIC_DVLOG(1) << "The connection hasn't finished handshake or is "
+                         "validating a recent peer address change.";
+        QUIC_BUG_IF(quic_bug_12714_30,
+                    IsHandshakeConfirmed() && !alternative_path_.validated)
+            << "No validated peer address to send after handshake comfirmed.";
+      } else if (!IsReceivedPeerAddressValidated()) {
+        QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 5, 6);
+        QuicConnectionId client_connection_id;
+        absl::optional<StatelessResetToken> stateless_reset_token;
+        FindMatchingOrNewClientConnectionIdOrToken(
+            default_path_, alternative_path_,
+            last_packet_destination_connection_id_, &client_connection_id,
+            &stateless_reset_token);
+        // Only override alternative path state upon receiving a PATH_CHALLENGE
+        // from an unvalidated peer address, and the connection isn't validating
+        // a recent peer migration.
+        alternative_path_ = PathState(
+            last_received_packet_info_.destination_address,
+            current_effective_peer_address, client_connection_id,
+            last_packet_destination_connection_id_, stateless_reset_token);
+        should_proactively_validate_peer_address_on_path_challenge_ = true;
+      }
+    }
+    MaybeUpdateBytesReceivedFromAlternativeAddress(last_size_);
+    return connected_;
+  }
+  // Packet content is tracked to identify connectivity probe in non-IETF
+  // version, where a connectivity probe is defined as
+  // - a padded PING packet with peer address change received by server,
+  // - a padded PING packet on new path received by client.
+
+  if (current_packet_content_ == NOT_PADDED_PING) {
+    // We have already learned the current packet is not a connectivity
+    // probing packet. Peer migration should have already been started earlier
+    // if needed.
+    return connected_;
+  }
+
+  if (type == PING_FRAME) {
+    if (current_packet_content_ == NO_FRAMES_RECEIVED) {
+      current_packet_content_ = FIRST_FRAME_IS_PING;
+      return connected_;
+    }
+  }
+
+  // In Google QUIC, we look for a packet with just a PING and PADDING.
+  // If the condition is met, mark things as connectivity-probing, causing
+  // later processing to generate the correct response.
+  if (type == PADDING_FRAME && current_packet_content_ == FIRST_FRAME_IS_PING) {
+    current_packet_content_ = SECOND_FRAME_IS_PADDING;
+    if (perspective_ == Perspective::IS_SERVER) {
+      is_current_packet_connectivity_probing_ =
+          current_effective_peer_migration_type_ != NO_CHANGE;
+      QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
+          << ENDPOINT
+          << "Detected connectivity probing packet. "
+             "current_effective_peer_migration_type_:"
+          << current_effective_peer_migration_type_;
+    } else {
+      is_current_packet_connectivity_probing_ =
+          (last_received_packet_info_.source_address != peer_address()) ||
+          (last_received_packet_info_.destination_address !=
+           default_path_.self_address);
+      QUIC_DLOG_IF(INFO, is_current_packet_connectivity_probing_)
+          << ENDPOINT
+          << "Detected connectivity probing packet. "
+             "last_packet_source_address:"
+          << last_received_packet_info_.source_address
+          << ", peer_address_:" << peer_address()
+          << ", last_packet_destination_address:"
+          << last_received_packet_info_.destination_address
+          << ", default path self_address :" << default_path_.self_address;
+    }
+    return connected_;
+  }
+
+  current_packet_content_ = NOT_PADDED_PING;
+  if (GetLargestReceivedPacket().IsInitialized() &&
+      last_header_.packet_number == GetLargestReceivedPacket()) {
+    UpdatePeerAddress(last_received_packet_info_.source_address);
+    if (current_effective_peer_migration_type_ != NO_CHANGE) {
+      // Start effective peer migration immediately when the current packet is
+      // confirmed not a connectivity probing packet.
+      StartEffectivePeerMigration(current_effective_peer_migration_type_);
+    }
+  }
+  current_effective_peer_migration_type_ = NO_CHANGE;
+  return connected_;
+}
+
+void QuicConnection::MaybeStartIetfPeerMigration() {
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  if (current_effective_peer_migration_type_ != NO_CHANGE &&
+      !IsHandshakeConfirmed()) {
+    QUIC_LOG_EVERY_N_SEC(INFO, 60)
+        << ENDPOINT << "Effective peer's ip:port changed from "
+        << default_path_.peer_address.ToString() << " to "
+        << GetEffectivePeerAddressFromCurrentPacket().ToString()
+        << " before handshake confirmed, "
+           "current_effective_peer_migration_type_: "
+        << current_effective_peer_migration_type_;
+    // Peer migrated before handshake gets confirmed.
+    CloseConnection((current_effective_peer_migration_type_ == PORT_CHANGE
+                         ? QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED
+                         : QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED),
+                    "Peer address changed before handshake is confirmed.",
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (GetLargestReceivedPacket().IsInitialized() &&
+      last_header_.packet_number == GetLargestReceivedPacket()) {
+    if (current_effective_peer_migration_type_ != NO_CHANGE) {
+      // Start effective peer migration when the current packet contains a
+      // non-probing frame.
+      // TODO(fayang): When multiple packet number spaces is supported, only
+      // start peer migration for the application data.
+      if (!validate_client_addresses_) {
+        UpdatePeerAddress(last_received_packet_info_.source_address);
+      }
+      StartEffectivePeerMigration(current_effective_peer_migration_type_);
+    } else {
+      UpdatePeerAddress(last_received_packet_info_.source_address);
+    }
+  }
+  current_effective_peer_migration_type_ = NO_CHANGE;
+}
+
+void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
+                                              bool acked_new_packet) {
+  if (no_stop_waiting_frames_ && !packet_creator_.has_ack()) {
+    uber_received_packet_manager_.DontWaitForPacketsBefore(
+        last_decrypted_packet_level_,
+        SupportsMultiplePacketNumberSpaces()
+            ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
+                  last_decrypted_packet_level_)
+            : sent_packet_manager_.largest_packet_peer_knows_is_acked());
+  }
+  // Always reset the retransmission alarm when an ack comes in, since we now
+  // have a better estimate of the current rtt than when it was set.
+  SetRetransmissionAlarm();
+  if (acked_new_packet) {
+    OnForwardProgressMade();
+  } else if (default_enable_5rto_blackhole_detection_ &&
+             !sent_packet_manager_.HasInFlightPackets() &&
+             blackhole_detector_.IsDetectionInProgress()) {
+    // In case no new packets get acknowledged, it is possible packets are
+    // detected lost because of time based loss detection. Cancel blackhole
+    // detection if there is no packets in flight.
+    blackhole_detector_.StopDetection(/*permanent=*/false);
+  }
+
+  if (send_stop_waiting) {
+    ++stop_waiting_count_;
+  } else {
+    stop_waiting_count_ = 0;
+  }
+}
+
+void QuicConnection::SetSessionNotifier(
+    SessionNotifierInterface* session_notifier) {
+  sent_packet_manager_.SetSessionNotifier(session_notifier);
+}
+
+void QuicConnection::SetDataProducer(
+    QuicStreamFrameDataProducer* data_producer) {
+  framer_.set_data_producer(data_producer);
+}
+
+void QuicConnection::SetTransmissionType(TransmissionType type) {
+  packet_creator_.SetTransmissionType(type);
+}
+
+void QuicConnection::UpdateReleaseTimeIntoFuture() {
+  QUICHE_DCHECK(supports_release_time_);
+
+  const QuicTime::Delta prior_max_release_time = release_time_into_future_;
+  release_time_into_future_ = std::max(
+      QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
+      std::min(
+          QuicTime::Delta::FromMilliseconds(
+              GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
+          sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
+              GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
+  QUIC_DVLOG(3) << "Updated max release time delay from "
+                << prior_max_release_time << " to "
+                << release_time_into_future_;
+}
+
+void QuicConnection::ResetAckStates() {
+  ack_alarm_->Cancel();
+  stop_waiting_count_ = 0;
+  uber_received_packet_manager_.ResetAckStates(encryption_level_);
+}
+
+MessageStatus QuicConnection::SendMessage(
+    QuicMessageId message_id, absl::Span<quiche::QuicheMemSlice> message,
+    bool flush) {
+  if (!VersionSupportsMessageFrames(transport_version())) {
+    QUIC_BUG(quic_bug_10511_38)
+        << "MESSAGE frame is not supported for version " << transport_version();
+    return MESSAGE_STATUS_UNSUPPORTED;
+  }
+  if (MemSliceSpanTotalSize(message) > GetCurrentLargestMessagePayload()) {
+    return MESSAGE_STATUS_TOO_LARGE;
+  }
+  if (!connected_ || (!flush && !CanWrite(HAS_RETRANSMITTABLE_DATA))) {
+    return MESSAGE_STATUS_BLOCKED;
+  }
+  ScopedPacketFlusher flusher(this);
+  return packet_creator_.AddMessageFrame(message_id, message);
+}
+
+QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
+  return packet_creator_.GetCurrentLargestMessagePayload();
+}
+
+QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
+  return packet_creator_.GetGuaranteedLargestMessagePayload();
+}
+
+uint32_t QuicConnection::cipher_id() const {
+  if (version().KnowsWhichDecrypterToUse()) {
+    return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
+  }
+  return framer_.decrypter()->cipher_id();
+}
+
+EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
+  if (perspective_ == Perspective::IS_CLIENT) {
+    return encryption_level_;
+  }
+  if (IsHandshakeComplete()) {
+    // A forward secure packet has been received.
+    QUIC_BUG_IF(quic_bug_12714_31,
+                encryption_level_ != ENCRYPTION_FORWARD_SECURE)
+        << ENDPOINT << "Unexpected connection close encryption level "
+        << encryption_level_;
+    return ENCRYPTION_FORWARD_SECURE;
+  }
+  if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
+    if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
+      if (version().HasIetfInvariantHeader()) {
+        QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
+      } else {
+        QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
+      }
+    }
+    return ENCRYPTION_ZERO_RTT;
+  }
+  return ENCRYPTION_INITIAL;
+}
+
+void QuicConnection::MaybeBundleCryptoDataWithAcks() {
+  QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
+  if (IsHandshakeConfirmed()) {
+    return;
+  }
+  PacketNumberSpace space = HANDSHAKE_DATA;
+  if (perspective() == Perspective::IS_SERVER &&
+      framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+    // On the server side, sends INITIAL data with INITIAL ACK if initial key is
+    // available.
+    space = INITIAL_DATA;
+  }
+  const QuicTime ack_timeout =
+      uber_received_packet_manager_.GetAckTimeout(space);
+  if (!ack_timeout.IsInitialized() ||
+      (ack_timeout > clock_->ApproximateNow() &&
+       ack_timeout > uber_received_packet_manager_.GetEarliestAckTimeout())) {
+    // No pending ACK of space.
+    return;
+  }
+  if (coalesced_packet_.length() > 0) {
+    // Do not bundle CRYPTO data if the ACK could be coalesced with other
+    // packets.
+    return;
+  }
+
+  if (!framer_.HasAnEncrypterForSpace(space)) {
+    QUIC_BUG(quic_bug_10511_39)
+        << ENDPOINT
+        << "Try to bundle crypto with ACK with missing key of space "
+        << PacketNumberSpaceToString(space);
+    return;
+  }
+
+  sent_packet_manager_.RetransmitDataOfSpaceIfAny(space);
+}
+
+void QuicConnection::SendAllPendingAcks() {
+  QUICHE_DCHECK(SupportsMultiplePacketNumberSpaces());
+  QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
+  ack_alarm_->Cancel();
+  QuicTime earliest_ack_timeout =
+      uber_received_packet_manager_.GetEarliestAckTimeout();
+  QUIC_BUG_IF(quic_bug_12714_32, !earliest_ack_timeout.IsInitialized());
+  MaybeBundleCryptoDataWithAcks();
+  earliest_ack_timeout = uber_received_packet_manager_.GetEarliestAckTimeout();
+  if (!earliest_ack_timeout.IsInitialized()) {
+    return;
+  }
+  for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
+    const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
+        static_cast<PacketNumberSpace>(i));
+    if (!ack_timeout.IsInitialized()) {
+      continue;
+    }
+    if (!framer_.HasAnEncrypterForSpace(static_cast<PacketNumberSpace>(i))) {
+      // The key has been dropped.
+      continue;
+    }
+    if (ack_timeout > clock_->ApproximateNow() &&
+        ack_timeout > earliest_ack_timeout) {
+      // Always send the earliest ACK to make forward progress in case alarm
+      // fires early.
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space "
+                  << PacketNumberSpaceToString(
+                         static_cast<PacketNumberSpace>(i));
+    ScopedEncryptionLevelContext context(
+        this, QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+    QuicFrames frames;
+    frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
+        static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
+    const bool flushed = packet_creator_.FlushAckFrame(frames);
+    if (!flushed) {
+      // Connection is write blocked.
+      QUIC_BUG_IF(quic_bug_12714_33,
+                  !writer_->IsWriteBlocked() && !LimitedByAmplificationFactor())
+          << "Writer not blocked and not throttled by amplification factor, "
+             "but ACK not flushed for packet space:"
+          << i;
+      break;
+    }
+    ResetAckStates();
+  }
+
+  const QuicTime timeout =
+      uber_received_packet_manager_.GetEarliestAckTimeout();
+  if (timeout.IsInitialized()) {
+    // If there are ACKs pending, re-arm ack alarm.
+    ack_alarm_->Update(timeout, kAlarmGranularity);
+  }
+  // Only try to bundle retransmittable data with ACK frame if default
+  // encryption level is forward secure.
+  if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
+      !ShouldBundleRetransmittableFrameWithAck()) {
+    return;
+  }
+  consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+  if (packet_creator_.HasPendingRetransmittableFrames() ||
+      visitor_->WillingAndAbleToWrite()) {
+    // There are pending retransmittable frames.
+    return;
+  }
+
+  visitor_->OnAckNeedsRetransmittableFrame();
+}
+
+bool QuicConnection::ShouldBundleRetransmittableFrameWithAck() const {
+  if (consecutive_num_packets_with_no_retransmittable_frames_ >=
+      max_consecutive_num_packets_with_no_retransmittable_frames_) {
+    return true;
+  }
+  if (bundle_retransmittable_with_pto_ack_ &&
+      (sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
+       sent_packet_manager_.GetConsecutivePtoCount() > 0)) {
+    // Bundle a retransmittable frame with an ACK if the PTO or RTO has fired
+    // in order to recover more quickly in cases of temporary network outage.
+    return true;
+  }
+  return false;
+}
+
+void QuicConnection::MaybeCoalescePacketOfHigherSpace() {
+  if (!connected() || !packet_creator_.HasSoftMaxPacketLength()) {
+    return;
+  }
+  if (fill_coalesced_packet_) {
+    // Make sure MaybeCoalescePacketOfHigherSpace is not re-entrant.
+    QUIC_BUG_IF(quic_coalesce_packet_reentrant,
+                flush_after_coalesce_higher_space_packets_);
+    return;
+  }
+  for (EncryptionLevel retransmission_level :
+       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE}) {
+    // Coalesce HANDSHAKE with INITIAL retransmission, and coalesce 1-RTT with
+    // HANDSHAKE retransmission.
+    const EncryptionLevel coalesced_level =
+        retransmission_level == ENCRYPTION_INITIAL ? ENCRYPTION_HANDSHAKE
+                                                   : ENCRYPTION_FORWARD_SECURE;
+    if (coalesced_packet_.ContainsPacketOfEncryptionLevel(
+            retransmission_level) &&
+        coalesced_packet_.TransmissionTypeOfPacket(retransmission_level) !=
+            NOT_RETRANSMISSION &&
+        framer_.HasEncrypterOfEncryptionLevel(coalesced_level) &&
+        !coalesced_packet_.ContainsPacketOfEncryptionLevel(coalesced_level)) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Trying to coalesce packet of encryption level: "
+                    << EncryptionLevelToString(coalesced_level);
+      fill_coalesced_packet_ = true;
+      sent_packet_manager_.RetransmitDataOfSpaceIfAny(
+          QuicUtils::GetPacketNumberSpace(coalesced_level));
+      fill_coalesced_packet_ = false;
+    }
+  }
+}
+
+bool QuicConnection::FlushCoalescedPacket() {
+  ScopedCoalescedPacketClearer clearer(&coalesced_packet_);
+  if (!connected_) {
+    return false;
+  }
+  if (!version().CanSendCoalescedPackets()) {
+    QUIC_BUG_IF(quic_bug_12714_34, coalesced_packet_.length() > 0);
+    return true;
+  }
+  if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_INITIAL) &&
+      !framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL)) {
+    // Initial packet will be re-serialized. Neuter it in case initial key has
+    // been dropped.
+    QUIC_BUG(quic_bug_10511_40)
+        << ENDPOINT
+        << "Coalescer contains initial packet while initial key has "
+           "been dropped.";
+    coalesced_packet_.NeuterInitialPacket();
+  }
+  if (coalesced_packet_.length() == 0) {
+    return true;
+  }
+
+  char buffer[kMaxOutgoingPacketSize];
+  const size_t length = packet_creator_.SerializeCoalescedPacket(
+      coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
+  if (length == 0) {
+    if (packet_creator_
+            .close_connection_if_fail_to_serialzie_coalesced_packet() &&
+        connected_) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 2, 2);
+      CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                      "Failed to serialize coalesced packet.",
+                      ConnectionCloseBehavior::SILENT_CLOSE);
+    }
+    return false;
+  }
+  if (debug_visitor_ != nullptr) {
+    debug_visitor_->OnCoalescedPacketSent(coalesced_packet_, length);
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet "
+                << coalesced_packet_.ToString(length);
+
+  if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Buffering coalesced packet of len: " << length;
+    buffered_packets_.emplace_back(
+        buffer, static_cast<QuicPacketLength>(length),
+        coalesced_packet_.self_address(), coalesced_packet_.peer_address());
+    return true;
+  }
+
+  WriteResult result = writer_->WritePacket(
+      buffer, length, coalesced_packet_.self_address().host(),
+      coalesced_packet_.peer_address(), per_packet_options_);
+  if (IsWriteError(result.status)) {
+    OnWriteError(result.error_code);
+    return false;
+  }
+  if (IsWriteBlockedStatus(result.status)) {
+    visitor_->OnWriteBlocked();
+    if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "Buffering coalesced packet of len: " << length;
+      buffered_packets_.emplace_back(
+          buffer, static_cast<QuicPacketLength>(length),
+          coalesced_packet_.self_address(), coalesced_packet_.peer_address());
+    }
+  }
+  // Account for added padding.
+  if (length > coalesced_packet_.length()) {
+    size_t padding_size = length - coalesced_packet_.length();
+    if (!count_bytes_on_alternative_path_separately_) {
+      if (EnforceAntiAmplificationLimit()) {
+        default_path_.bytes_sent_before_address_validation += padding_size;
+      }
+    } else {
+      QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 5, 5);
+      if (IsDefaultPath(coalesced_packet_.self_address(),
+                        coalesced_packet_.peer_address())) {
+        if (EnforceAntiAmplificationLimit()) {
+          // Include bytes sent even if they are not in flight.
+          default_path_.bytes_sent_before_address_validation += padding_size;
+        }
+      } else {
+        MaybeUpdateBytesSentToAlternativeAddress(
+            coalesced_packet_.peer_address(), padding_size);
+      }
+    }
+    stats_.bytes_sent += padding_size;
+    if (coalesced_packet_.initial_packet() != nullptr &&
+        coalesced_packet_.initial_packet()->transmission_type !=
+            NOT_RETRANSMISSION) {
+      stats_.bytes_retransmitted += padding_size;
+    }
+  }
+  return true;
+}
+
+void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
+  if (version().handshake_protocol != PROTOCOL_TLS1_3) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
+                << " supports multiple packet number spaces";
+  framer_.EnableMultiplePacketNumberSpacesSupport();
+  sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
+  uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport(
+      perspective_);
+}
+
+bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
+  return sent_packet_manager_.supports_multiple_packet_number_spaces();
+}
+
+void QuicConnection::SetLargestReceivedPacketWithAck(
+    QuicPacketNumber new_value) {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
+        last_decrypted_packet_level_)] = new_value;
+  } else {
+    largest_seen_packet_with_ack_ = new_value;
+  }
+}
+
+void QuicConnection::OnForwardProgressMade() {
+  if (!connected_) {
+    return;
+  }
+  if (is_path_degrading_) {
+    visitor_->OnForwardProgressMadeAfterPathDegrading();
+    is_path_degrading_ = false;
+  }
+  if (sent_packet_manager_.HasInFlightPackets()) {
+    // Restart detections if forward progress has been made.
+    blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
+                                         GetNetworkBlackholeDeadline(),
+                                         GetPathMtuReductionDeadline());
+  } else {
+    // Stop detections in quiecense.
+    blackhole_detector_.StopDetection(/*permanent=*/false);
+  }
+  QUIC_BUG_IF(quic_bug_12714_35,
+              perspective_ == Perspective::IS_SERVER &&
+                  default_enable_5rto_blackhole_detection_ &&
+                  blackhole_detector_.IsDetectionInProgress() &&
+                  !sent_packet_manager_.HasInFlightPackets())
+      << ENDPOINT
+      << "Trying to start blackhole detection without no bytes in flight";
+}
+
+QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
+        last_decrypted_packet_level_)];
+  }
+  return largest_seen_packet_with_ack_;
+}
+
+QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    return sent_packet_manager_.GetLargestAckedPacket(
+        last_decrypted_packet_level_);
+  }
+  return sent_packet_manager_.GetLargestObserved();
+}
+
+QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
+  return uber_received_packet_manager_.GetLargestObserved(
+      last_decrypted_packet_level_);
+}
+
+bool QuicConnection::EnforceAntiAmplificationLimit() const {
+  return version().SupportsAntiAmplificationLimit() &&
+         perspective_ == Perspective::IS_SERVER && !default_path_.validated;
+}
+
+// TODO(danzh) Pass in path object or its reference of some sort to use this
+// method to check anti-amplification limit on non-default path.
+bool QuicConnection::LimitedByAmplificationFactor() const {
+  return EnforceAntiAmplificationLimit() &&
+         default_path_.bytes_sent_before_address_validation >=
+             anti_amplification_factor_ *
+                 default_path_.bytes_received_before_address_validation;
+}
+
+SerializedPacketFate QuicConnection::GetSerializedPacketFate(
+    bool is_mtu_discovery,
+    EncryptionLevel encryption_level) {
+  if (ShouldDiscardPacket(encryption_level)) {
+    return DISCARD;
+  }
+  if (legacy_version_encapsulation_in_progress_) {
+    QUICHE_DCHECK(!is_mtu_discovery);
+    return LEGACY_VERSION_ENCAPSULATE;
+  }
+  if (version().CanSendCoalescedPackets() && !coalescing_done_ &&
+      !is_mtu_discovery) {
+    if (!IsHandshakeConfirmed()) {
+      // Before receiving ACK for any 1-RTT packets, always try to coalesce
+      // packet (except MTU discovery packet).
+      return COALESCE;
+    }
+    if (coalesced_packet_.length() > 0) {
+      // If the coalescer is not empty, let this packet go through coalescer
+      // to avoid potential out of order sending.
+      return COALESCE;
+    }
+  }
+  if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+    return BUFFER;
+  }
+  return SEND_TO_WRITER;
+}
+
+bool QuicConnection::IsHandshakeComplete() const {
+  return visitor_->GetHandshakeState() >= HANDSHAKE_COMPLETE;
+}
+
+bool QuicConnection::IsHandshakeConfirmed() const {
+  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, version().handshake_protocol);
+  return visitor_->GetHandshakeState() == HANDSHAKE_CONFIRMED;
+}
+
+size_t QuicConnection::min_received_before_ack_decimation() const {
+  return uber_received_packet_manager_.min_received_before_ack_decimation();
+}
+
+void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
+  uber_received_packet_manager_.set_min_received_before_ack_decimation(
+      new_value);
+}
+
+const QuicAckFrame& QuicConnection::ack_frame() const {
+  if (SupportsMultiplePacketNumberSpaces()) {
+    return uber_received_packet_manager_.GetAckFrame(
+        QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
+  }
+  return uber_received_packet_manager_.ack_frame();
+}
+
+void QuicConnection::set_client_connection_id(
+    QuicConnectionId client_connection_id) {
+  if (!version().SupportsClientConnectionIds()) {
+    QUIC_BUG_IF(quic_bug_12714_36, !client_connection_id.IsEmpty())
+        << ENDPOINT << "Attempted to use client connection ID "
+        << client_connection_id << " with unsupported version " << version();
+    return;
+  }
+  default_path_.client_connection_id = client_connection_id;
+
+  client_connection_id_is_set_ = true;
+  if (version().HasIetfQuicFrames() && !client_connection_id.IsEmpty()) {
+    if (perspective_ == Perspective::IS_SERVER) {
+      QUICHE_DCHECK(peer_issued_cid_manager_ == nullptr);
+      peer_issued_cid_manager_ =
+          std::make_unique<QuicPeerIssuedConnectionIdManager>(
+              kMinNumOfActiveConnectionIds, client_connection_id, clock_,
+              alarm_factory_, this, context());
+    } else {
+      // Note in Chromium client, set_client_connection_id is not called and
+      // thus self_issued_cid_manager_ should be null.
+      self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
+    }
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
+                  << default_path_.client_connection_id
+                  << " for connection with server connection ID "
+                  << default_path_.server_connection_id;
+  packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+  framer_.SetExpectedClientConnectionIdLength(
+      default_path_.client_connection_id.length());
+}
+
+void QuicConnection::OnPathDegradingDetected() {
+  is_path_degrading_ = true;
+  visitor_->OnPathDegrading();
+}
+
+void QuicConnection::OnBlackholeDetected() {
+  if (default_enable_5rto_blackhole_detection_ &&
+      !sent_packet_manager_.HasInFlightPackets()) {
+    QUIC_BUG(quic_bug_10511_41)
+        << ENDPOINT
+        << "Blackhole detected, but there is no bytes in flight, version: "
+        << version();
+    // Do not close connection if there is no bytes in flight.
+    return;
+  }
+  CloseConnection(QUIC_TOO_MANY_RTOS, "Network blackhole detected",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicConnection::OnPathMtuReductionDetected() {
+  MaybeRevertToPreviousMtu();
+}
+
+void QuicConnection::OnHandshakeTimeout() {
+  const QuicTime::Delta duration =
+      clock_->ApproximateNow() - stats_.connection_creation_time;
+  std::string error_details = absl::StrCat(
+      "Handshake timeout expired after ", duration.ToDebuggingValue(),
+      ". Timeout:",
+      idle_network_detector_.handshake_timeout().ToDebuggingValue());
+  if (perspective() == Perspective::IS_CLIENT && version().UsesTls()) {
+    absl::StrAppend(&error_details, UndecryptablePacketsInfo());
+  }
+  QUIC_DVLOG(1) << ENDPOINT << error_details;
+  CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicConnection::OnIdleNetworkDetected() {
+  const QuicTime::Delta duration =
+      clock_->ApproximateNow() -
+      idle_network_detector_.last_network_activity_time();
+  std::string error_details = absl::StrCat(
+      "No recent network activity after ", duration.ToDebuggingValue(),
+      ". Timeout:",
+      idle_network_detector_.idle_network_timeout().ToDebuggingValue());
+  if (perspective() == Perspective::IS_CLIENT && version().UsesTls() &&
+      !IsHandshakeComplete()) {
+    absl::StrAppend(&error_details, UndecryptablePacketsInfo());
+  }
+  QUIC_DVLOG(1) << ENDPOINT << error_details;
+  const bool has_consecutive_pto =
+      sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
+      sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
+      sent_packet_manager_.GetConsecutivePtoCount() > 0;
+  if (has_consecutive_pto || visitor_->ShouldKeepConnectionAlive()) {
+    if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail) &&
+        !has_consecutive_pto) {
+      // Include stream information in error detail if there are open streams.
+      QUIC_RELOADABLE_FLAG_COUNT(quic_add_stream_info_to_idle_close_detail);
+      absl::StrAppend(&error_details, ", ",
+                      visitor_->GetStreamsInfoForLogging());
+    }
+    CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
+                    ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicErrorCode error_code = QUIC_NETWORK_IDLE_TIMEOUT;
+  if (idle_timeout_connection_close_behavior_ ==
+      ConnectionCloseBehavior::
+          SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED) {
+    error_code = QUIC_SILENT_IDLE_TIMEOUT;
+  }
+  CloseConnection(error_code, error_details,
+                  idle_timeout_connection_close_behavior_);
+}
+
+void QuicConnection::OnPeerIssuedConnectionIdRetired() {
+  QUICHE_DCHECK(peer_issued_cid_manager_ != nullptr);
+  QuicConnectionId* default_path_cid =
+      perspective_ == Perspective::IS_CLIENT
+          ? &default_path_.server_connection_id
+          : &default_path_.client_connection_id;
+  QuicConnectionId* alternative_path_cid =
+      perspective_ == Perspective::IS_CLIENT
+          ? &alternative_path_.server_connection_id
+          : &alternative_path_.client_connection_id;
+  bool default_path_and_alternative_path_use_the_same_peer_connection_id =
+      *default_path_cid == *alternative_path_cid;
+  if (!default_path_cid->IsEmpty() &&
+      !peer_issued_cid_manager_->IsConnectionIdActive(*default_path_cid)) {
+    *default_path_cid = QuicConnectionId();
+  }
+  // TODO(haoyuewang) Handle the change for default_path_ & alternatvie_path_
+  // via the same helper function.
+  if (default_path_cid->IsEmpty()) {
+    // Try setting a new connection ID now such that subsequent
+    // RetireConnectionId frames can be sent on the default path.
+    const QuicConnectionIdData* unused_connection_id_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    if (unused_connection_id_data != nullptr) {
+      *default_path_cid = unused_connection_id_data->connection_id;
+      default_path_.stateless_reset_token =
+          unused_connection_id_data->stateless_reset_token;
+      if (perspective_ == Perspective::IS_CLIENT) {
+        packet_creator_.SetServerConnectionId(
+            unused_connection_id_data->connection_id);
+      } else {
+        packet_creator_.SetClientConnectionId(
+            unused_connection_id_data->connection_id);
+      }
+    }
+  }
+  if (default_path_and_alternative_path_use_the_same_peer_connection_id) {
+    *alternative_path_cid = *default_path_cid;
+    alternative_path_.stateless_reset_token =
+        default_path_.stateless_reset_token;
+  } else if (!alternative_path_cid->IsEmpty() &&
+             !peer_issued_cid_manager_->IsConnectionIdActive(
+                 *alternative_path_cid)) {
+    *alternative_path_cid = EmptyQuicConnectionId();
+    const QuicConnectionIdData* unused_connection_id_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    if (unused_connection_id_data != nullptr) {
+      *alternative_path_cid = unused_connection_id_data->connection_id;
+      alternative_path_.stateless_reset_token =
+          unused_connection_id_data->stateless_reset_token;
+    }
+  }
+
+  std::vector<uint64_t> retired_cid_sequence_numbers =
+      peer_issued_cid_manager_->ConsumeToBeRetiredConnectionIdSequenceNumbers();
+  QUICHE_DCHECK(!retired_cid_sequence_numbers.empty());
+  for (const auto& sequence_number : retired_cid_sequence_numbers) {
+    ++stats_.num_retire_connection_id_sent;
+    visitor_->SendRetireConnectionId(sequence_number);
+  }
+}
+
+bool QuicConnection::SendNewConnectionId(
+    const QuicNewConnectionIdFrame& frame) {
+  visitor_->SendNewConnectionId(frame);
+  ++stats_.num_new_connection_id_sent;
+  return connected_;
+}
+
+void QuicConnection::OnNewConnectionIdIssued(
+    const QuicConnectionId& connection_id) {
+  if (perspective_ == Perspective::IS_SERVER) {
+    visitor_->OnServerConnectionIdIssued(connection_id);
+  }
+}
+
+void QuicConnection::OnSelfIssuedConnectionIdRetired(
+    const QuicConnectionId& connection_id) {
+  if (perspective_ == Perspective::IS_SERVER) {
+    visitor_->OnServerConnectionIdRetired(connection_id);
+  }
+}
+
+void QuicConnection::MaybeUpdateAckTimeout() {
+  if (should_last_packet_instigate_acks_) {
+    return;
+  }
+  should_last_packet_instigate_acks_ = true;
+  uber_received_packet_manager_.MaybeUpdateAckTimeout(
+      /*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_,
+      last_header_.packet_number, last_received_packet_info_.receipt_time,
+      clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+}
+
+QuicTime QuicConnection::GetPathDegradingDeadline() const {
+  if (!ShouldDetectPathDegrading()) {
+    return QuicTime::Zero();
+  }
+  return clock_->ApproximateNow() +
+         sent_packet_manager_.GetPathDegradingDelay();
+}
+
+bool QuicConnection::ShouldDetectPathDegrading() const {
+  if (!connected_) {
+    return false;
+  }
+  // No path degrading detection before handshake completes.
+  if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
+    return false;
+  }
+  return perspective_ == Perspective::IS_CLIENT && !is_path_degrading_;
+}
+
+QuicTime QuicConnection::GetNetworkBlackholeDeadline() const {
+  if (!ShouldDetectBlackhole()) {
+    return QuicTime::Zero();
+  }
+  QUICHE_DCHECK_LT(0u, num_rtos_for_blackhole_detection_);
+  return clock_->ApproximateNow() +
+         sent_packet_manager_.GetNetworkBlackholeDelay(
+             num_rtos_for_blackhole_detection_);
+}
+
+bool QuicConnection::ShouldDetectBlackhole() const {
+  if (!connected_ || blackhole_detection_disabled_) {
+    return false;
+  }
+  // No blackhole detection before handshake completes.
+  if (default_enable_5rto_blackhole_detection_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+                                 3, 3);
+    return IsHandshakeComplete();
+  }
+
+  if (!idle_network_detector_.handshake_timeout().IsInfinite()) {
+    return false;
+  }
+  return num_rtos_for_blackhole_detection_ > 0;
+}
+
+QuicTime QuicConnection::GetRetransmissionDeadline() const {
+  if (perspective_ == Perspective::IS_CLIENT &&
+      SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
+      stats_.pto_count == 0 &&
+      !framer_.HasDecrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE) &&
+      !undecryptable_packets_.empty()) {
+    // Retransmits ClientHello quickly when a Handshake or 1-RTT packet is
+    // received prior to having Handshake keys. Adding kAlarmGranulary will
+    // avoid spurious retransmissions in the case of small-scale reordering.
+    return clock_->ApproximateNow() + kAlarmGranularity;
+  }
+  return sent_packet_manager_.GetRetransmissionTime();
+}
+
+bool QuicConnection::SendPathChallenge(
+    const QuicPathFrameBuffer& data_buffer,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const QuicSocketAddress& effective_peer_address,
+    QuicPacketWriter* writer) {
+  if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
+    return connected_;
+  }
+  if (connection_migration_use_new_cid_) {
+    {
+      QuicConnectionId client_cid, server_cid;
+      FindOnPathConnectionIds(self_address, effective_peer_address, &client_cid,
+                              &server_cid);
+      QuicPacketCreator::ScopedPeerAddressContext context(
+          &packet_creator_, peer_address, client_cid, server_cid,
+          connection_migration_use_new_cid_);
+      if (writer == writer_) {
+        ScopedPacketFlusher flusher(this);
+        // It's on current path, add the PATH_CHALLENGE the same way as other
+        // frames. This may cause connection to be closed.
+        packet_creator_.AddPathChallengeFrame(data_buffer);
+      } else {
+        std::unique_ptr<SerializedPacket> probing_packet =
+            packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+                data_buffer);
+        QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet),
+                         NO_RETRANSMITTABLE_DATA);
+        QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
+        WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
+                               peer_address, /*measure_rtt=*/false);
+      }
+    }
+    return connected_;
+  }
+  if (writer == writer_) {
+    ScopedPacketFlusher flusher(this);
+    {
+      // It's on current path, add the PATH_CHALLENGE the same way as other
+      // frames.
+      QuicPacketCreator::ScopedPeerAddressContext context(
+          &packet_creator_, peer_address, /*update_connection_id=*/false);
+      // This may cause connection to be closed.
+      packet_creator_.AddPathChallengeFrame(data_buffer);
+    }
+    // Return outside of the scope so that the flush result can be reflected.
+    return connected_;
+  }
+  std::unique_ptr<SerializedPacket> probing_packet =
+      packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+          data_buffer);
+  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
+  QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
+  WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
+                         peer_address, /*measure_rtt=*/false);
+  return true;
+}
+
+QuicTime QuicConnection::GetRetryTimeout(
+    const QuicSocketAddress& peer_address_to_use,
+    QuicPacketWriter* writer_to_use) const {
+  if (writer_to_use == writer_ && peer_address_to_use == peer_address()) {
+    return clock_->ApproximateNow() + sent_packet_manager_.GetPtoDelay();
+  }
+  return clock_->ApproximateNow() +
+         QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+}
+
+void QuicConnection::ValidatePath(
+    std::unique_ptr<QuicPathValidationContext> context,
+    std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
+  QUICHE_DCHECK(use_path_validator_);
+  if (!connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      !IsDefaultPath(context->self_address(), context->peer_address())) {
+    alternative_path_ = PathState(
+        context->self_address(), context->peer_address(),
+        default_path_.client_connection_id, default_path_.server_connection_id,
+        default_path_.stateless_reset_token);
+  }
+  if (path_validator_.HasPendingPathValidation()) {
+    // Cancel and fail any earlier validation.
+    path_validator_.CancelPathValidation();
+  }
+  if (connection_migration_use_new_cid_ &&
+      perspective_ == Perspective::IS_CLIENT &&
+      !IsDefaultPath(context->self_address(), context->peer_address())) {
+    if (self_issued_cid_manager_ != nullptr) {
+      self_issued_cid_manager_->MaybeSendNewConnectionIds();
+      if (!connected_) {
+        return;
+      }
+    }
+    if ((self_issued_cid_manager_ != nullptr &&
+         !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
+        (peer_issued_cid_manager_ != nullptr &&
+         !peer_issued_cid_manager_->HasUnusedConnectionId())) {
+      QUIC_DVLOG(1) << "Client cannot start new path validation as there is no "
+                       "requried connection ID is available.";
+      result_delegate->OnPathValidationFailure(std::move(context));
+      return;
+    }
+    QuicConnectionId client_connection_id, server_connection_id;
+    absl::optional<StatelessResetToken> stateless_reset_token;
+    if (self_issued_cid_manager_ != nullptr) {
+      client_connection_id =
+          *self_issued_cid_manager_->ConsumeOneConnectionId();
+    }
+    if (peer_issued_cid_manager_ != nullptr) {
+      const auto* connection_id_data =
+          peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+      server_connection_id = connection_id_data->connection_id;
+      stateless_reset_token = connection_id_data->stateless_reset_token;
+    }
+    alternative_path_ = PathState(context->self_address(),
+                                  context->peer_address(), client_connection_id,
+                                  server_connection_id, stateless_reset_token);
+  }
+  path_validator_.StartPathValidation(std::move(context),
+                                      std::move(result_delegate));
+}
+
+bool QuicConnection::SendPathResponse(
+    const QuicPathFrameBuffer& data_buffer,
+    const QuicSocketAddress& peer_address_to_send,
+    const QuicSocketAddress& effective_peer_address) {
+  if (!framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
+    return false;
+  }
+  QuicConnectionId client_cid, server_cid;
+  if (connection_migration_use_new_cid_) {
+    FindOnPathConnectionIds(last_received_packet_info_.destination_address,
+                            effective_peer_address, &client_cid, &server_cid);
+  }
+  // Send PATH_RESPONSE using the provided peer address. If the creator has been
+  // using a different peer address, it will flush before and after serializing
+  // the current PATH_RESPONSE.
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &packet_creator_, peer_address_to_send, client_cid, server_cid,
+      connection_migration_use_new_cid_);
+  QUIC_DVLOG(1) << ENDPOINT << "Send PATH_RESPONSE to " << peer_address_to_send;
+  if (default_path_.self_address ==
+      last_received_packet_info_.destination_address) {
+    // The PATH_CHALLENGE is received on the default socket. Respond on the same
+    // socket.
+    return packet_creator_.AddPathResponseFrame(data_buffer);
+  }
+
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+  // This PATH_CHALLENGE is received on an alternative socket which should be
+  // used to send PATH_RESPONSE.
+  if (!path_validator_.HasPendingPathValidation() ||
+      path_validator_.GetContext()->self_address() !=
+          last_received_packet_info_.destination_address) {
+    // Ignore this PATH_CHALLENGE if it's received from an uninteresting
+    // socket.
+    return true;
+  }
+  QuicPacketWriter* writer = path_validator_.GetContext()->WriterToUse();
+
+  std::unique_ptr<SerializedPacket> probing_packet =
+      packet_creator_.SerializePathResponseConnectivityProbingPacket(
+          {data_buffer}, /*is_padded=*/true);
+  QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Send PATH_RESPONSE from alternative socket with address "
+                << last_received_packet_info_.destination_address;
+  // Ignore the return value to treat write error on the alternative writer as
+  // part of network error. If the writer becomes blocked, wait for the peer to
+  // send another PATH_CHALLENGE.
+  WritePacketUsingWriter(std::move(probing_packet), writer,
+                         last_received_packet_info_.destination_address,
+                         peer_address_to_send,
+                         /*measure_rtt=*/false);
+  return true;
+}
+
+void QuicConnection::UpdatePeerAddress(QuicSocketAddress peer_address) {
+  direct_peer_address_ = peer_address;
+  packet_creator_.SetDefaultPeerAddress(peer_address);
+}
+
+void QuicConnection::SendPingAtLevel(EncryptionLevel level) {
+  ScopedEncryptionLevelContext context(this, level);
+  SendControlFrame(QuicFrame(QuicPingFrame()));
+}
+
+bool QuicConnection::HasPendingPathValidation() const {
+  QUICHE_DCHECK(use_path_validator_);
+  return path_validator_.HasPendingPathValidation();
+}
+
+QuicPathValidationContext* QuicConnection::GetPathValidationContext() const {
+  QUICHE_DCHECK(use_path_validator_);
+  return path_validator_.GetContext();
+}
+
+void QuicConnection::CancelPathValidation() {
+  QUICHE_DCHECK(use_path_validator_);
+  path_validator_.CancelPathValidation();
+}
+
+bool QuicConnection::UpdateConnectionIdsOnClientMigration(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+  if (IsAlternativePath(self_address, peer_address)) {
+    // Client migration is after path validation.
+    default_path_.client_connection_id = alternative_path_.client_connection_id;
+    default_path_.server_connection_id = alternative_path_.server_connection_id;
+    default_path_.stateless_reset_token =
+        alternative_path_.stateless_reset_token;
+    return true;
+  }
+  // Client migration is without path validation.
+  if (self_issued_cid_manager_ != nullptr) {
+    self_issued_cid_manager_->MaybeSendNewConnectionIds();
+    if (!connected_) {
+      return false;
+    }
+  }
+  if ((self_issued_cid_manager_ != nullptr &&
+       !self_issued_cid_manager_->HasConnectionIdToConsume()) ||
+      (peer_issued_cid_manager_ != nullptr &&
+       !peer_issued_cid_manager_->HasUnusedConnectionId())) {
+    return false;
+  }
+  if (self_issued_cid_manager_ != nullptr) {
+    default_path_.client_connection_id =
+        *self_issued_cid_manager_->ConsumeOneConnectionId();
+  }
+  if (peer_issued_cid_manager_ != nullptr) {
+    const auto* connection_id_data =
+        peer_issued_cid_manager_->ConsumeOneUnusedConnectionId();
+    default_path_.server_connection_id = connection_id_data->connection_id;
+    default_path_.stateless_reset_token =
+        connection_id_data->stateless_reset_token;
+  }
+  return true;
+}
+
+void QuicConnection::RetirePeerIssuedConnectionIdsNoLongerOnPath() {
+  if (!connection_migration_use_new_cid_ ||
+      peer_issued_cid_manager_ == nullptr) {
+    return;
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
+        {default_path_.server_connection_id,
+         alternative_path_.server_connection_id});
+  } else {
+    peer_issued_cid_manager_->MaybeRetireUnusedConnectionIds(
+        {default_path_.client_connection_id,
+         alternative_path_.client_connection_id});
+  }
+}
+
+void QuicConnection::RetirePeerIssuedConnectionIdsOnPathValidationFailure() {
+  // The alarm to retire connection IDs no longer on paths is scheduled at the
+  // end of writing and reading packet. On path validation failure, there could
+  // be no packet to write or read. Hence the retirement alarm for the
+  // connection ID associated with the failed path needs to be proactively
+  // scheduled here.
+  if (GetQuicReloadableFlag(
+          quic_retire_cid_on_reverse_path_validation_failure) ||
+      perspective_ == Perspective::IS_CLIENT) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_retire_cid_on_reverse_path_validation_failure);
+    RetirePeerIssuedConnectionIdsNoLongerOnPath();
+  }
+}
+
+bool QuicConnection::MigratePath(const QuicSocketAddress& self_address,
+                                 const QuicSocketAddress& peer_address,
+                                 QuicPacketWriter* writer,
+                                 bool owns_writer) {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+  if (!connected_) {
+    if (owns_writer) {
+      delete writer;
+    }
+    return false;
+  }
+  QUICHE_DCHECK(!version().UsesHttp3() || IsHandshakeConfirmed());
+
+  if (connection_migration_use_new_cid_) {
+    if (!UpdateConnectionIdsOnClientMigration(self_address, peer_address)) {
+      if (owns_writer) {
+        delete writer;
+      }
+      return false;
+    }
+    if (packet_creator_.GetServerConnectionId().length() !=
+        default_path_.server_connection_id.length()) {
+      packet_creator_.FlushCurrentPacket();
+    }
+    packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+    packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
+  }
+
+  const auto self_address_change_type = QuicUtils::DetermineAddressChangeType(
+      default_path_.self_address, self_address);
+  const auto peer_address_change_type = QuicUtils::DetermineAddressChangeType(
+      default_path_.peer_address, peer_address);
+  QUICHE_DCHECK(self_address_change_type != NO_CHANGE ||
+                peer_address_change_type != NO_CHANGE);
+  const bool is_port_change = (self_address_change_type == PORT_CHANGE ||
+                               self_address_change_type == NO_CHANGE) &&
+                              (peer_address_change_type == PORT_CHANGE ||
+                               peer_address_change_type == NO_CHANGE);
+  SetSelfAddress(self_address);
+  UpdatePeerAddress(peer_address);
+  SetQuicPacketWriter(writer, owns_writer);
+  MaybeClearQueuedPacketsOnPathChange();
+  OnSuccessfulMigration(is_port_change);
+  return true;
+}
+
+void QuicConnection::OnPathValidationFailureAtClient() {
+  if (connection_migration_use_new_cid_) {
+    QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
+    alternative_path_.Clear();
+  }
+  RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+}
+
+QuicConnectionId QuicConnection::GetOneActiveServerConnectionId() const {
+  if (perspective_ == Perspective::IS_CLIENT ||
+      self_issued_cid_manager_ == nullptr) {
+    return connection_id();
+  }
+  auto active_connection_ids = GetActiveServerConnectionIds();
+  QUIC_BUG_IF(quic_bug_6944, active_connection_ids.empty());
+  if (active_connection_ids.empty() ||
+      std::find(active_connection_ids.begin(), active_connection_ids.end(),
+                connection_id()) != active_connection_ids.end()) {
+    return connection_id();
+  }
+  QUICHE_CODE_COUNT(connection_id_on_default_path_has_been_retired);
+  auto active_connection_id =
+      self_issued_cid_manager_->GetOneActiveConnectionId();
+  return active_connection_id;
+}
+
+std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
+    const {
+  if (self_issued_cid_manager_ == nullptr) {
+    return {default_path_.server_connection_id};
+  }
+  QUICHE_DCHECK(version().HasIetfQuicFrames());
+  return self_issued_cid_manager_->GetUnretiredConnectionIds();
+}
+
+void QuicConnection::CreateConnectionIdManager() {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (!default_path_.server_connection_id.IsEmpty()) {
+      peer_issued_cid_manager_ =
+          std::make_unique<QuicPeerIssuedConnectionIdManager>(
+              kMinNumOfActiveConnectionIds, default_path_.server_connection_id,
+              clock_, alarm_factory_, this, context());
+    }
+  } else {
+    if (!default_path_.server_connection_id.IsEmpty()) {
+      self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager();
+    }
+  }
+}
+
+void QuicConnection::SetUnackedMapInitialCapacity() {
+  sent_packet_manager_.ReserveUnackedPacketsInitialCapacity(
+      GetUnackedMapInitialCapacity());
+}
+
+void QuicConnection::SetSourceAddressTokenToSend(absl::string_view token) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  if (!packet_creator_.HasRetryToken()) {
+    // Ignore received tokens (via NEW_TOKEN frame) from previous connections
+    // when a RETRY token has been received.
+    packet_creator_.SetRetryToken(std::string(token.data(), token.length()));
+  }
+}
+
+void QuicConnection::MaybeUpdateBytesSentToAlternativeAddress(
+    const QuicSocketAddress& peer_address,
+    QuicByteCount sent_packet_size) {
+  if (!version().SupportsAntiAmplificationLimit() ||
+      perspective_ != Perspective::IS_SERVER) {
+    return;
+  }
+  QUICHE_DCHECK(!IsDefaultPath(default_path_.self_address, peer_address));
+  if (!IsAlternativePath(default_path_.self_address, peer_address)) {
+    QUIC_DLOG(INFO) << "Wrote to uninteresting peer address: " << peer_address
+                    << " default direct_peer_address_ " << direct_peer_address_
+                    << " alternative path peer address "
+                    << alternative_path_.peer_address;
+    return;
+  }
+  if (alternative_path_.validated) {
+    return;
+  }
+  if (alternative_path_.bytes_sent_before_address_validation >=
+      anti_amplification_factor_ *
+          alternative_path_.bytes_received_before_address_validation) {
+    QUIC_LOG_FIRST_N(WARNING, 100)
+        << "Server sent more data than allowed to unverified alternative "
+           "peer address "
+        << peer_address << " bytes sent "
+        << alternative_path_.bytes_sent_before_address_validation
+        << ", bytes received "
+        << alternative_path_.bytes_received_before_address_validation;
+  }
+  alternative_path_.bytes_sent_before_address_validation += sent_packet_size;
+}
+
+void QuicConnection::MaybeUpdateBytesReceivedFromAlternativeAddress(
+    QuicByteCount received_packet_size) {
+  if (!version().SupportsAntiAmplificationLimit() ||
+      perspective_ != Perspective::IS_SERVER ||
+      !IsAlternativePath(last_received_packet_info_.destination_address,
+                         GetEffectivePeerAddressFromCurrentPacket()) ||
+      last_received_packet_info_.received_bytes_counted) {
+    return;
+  }
+  // Only update bytes received if this probing frame is received on the most
+  // recent alternative path.
+  QUICHE_DCHECK(!IsDefaultPath(last_received_packet_info_.destination_address,
+                               GetEffectivePeerAddressFromCurrentPacket()));
+  if (!alternative_path_.validated) {
+    alternative_path_.bytes_received_before_address_validation +=
+        received_packet_size;
+  }
+  last_received_packet_info_.received_bytes_counted = true;
+}
+
+bool QuicConnection::IsDefaultPath(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) const {
+  return direct_peer_address_ == peer_address &&
+         default_path_.self_address == self_address;
+}
+
+bool QuicConnection::IsAlternativePath(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) const {
+  return alternative_path_.peer_address == peer_address &&
+         alternative_path_.self_address == self_address;
+}
+
+void QuicConnection::PathState::Clear() {
+  self_address = QuicSocketAddress();
+  peer_address = QuicSocketAddress();
+  client_connection_id = {};
+  server_connection_id = {};
+  validated = false;
+  bytes_received_before_address_validation = 0;
+  bytes_sent_before_address_validation = 0;
+  send_algorithm = nullptr;
+  rtt_stats = absl::nullopt;
+  stateless_reset_token.reset();
+}
+
+QuicConnection::PathState::PathState(PathState&& other) {
+  *this = std::move(other);
+}
+
+QuicConnection::PathState& QuicConnection::PathState::operator=(
+    QuicConnection::PathState&& other) {
+  if (this != &other) {
+    self_address = other.self_address;
+    peer_address = other.peer_address;
+    client_connection_id = other.client_connection_id;
+    server_connection_id = other.server_connection_id;
+    stateless_reset_token = other.stateless_reset_token;
+    validated = other.validated;
+    bytes_received_before_address_validation =
+        other.bytes_received_before_address_validation;
+    bytes_sent_before_address_validation =
+        other.bytes_sent_before_address_validation;
+    send_algorithm = std::move(other.send_algorithm);
+    if (other.rtt_stats.has_value()) {
+      rtt_stats.emplace();
+      rtt_stats->CloneFrom(other.rtt_stats.value());
+    } else {
+      rtt_stats.reset();
+    }
+    other.Clear();
+  }
+  return *this;
+}
+
+bool QuicConnection::IsReceivedPeerAddressValidated() const {
+  QuicSocketAddress current_effective_peer_address =
+      GetEffectivePeerAddressFromCurrentPacket();
+  QUICHE_DCHECK(current_effective_peer_address.IsInitialized());
+  return (alternative_path_.peer_address.host() ==
+              current_effective_peer_address.host() &&
+          alternative_path_.validated) ||
+         (default_path_.validated && default_path_.peer_address.host() ==
+                                         current_effective_peer_address.host());
+}
+
+QuicConnection::ReversePathValidationResultDelegate::
+    ReversePathValidationResultDelegate(
+        QuicConnection* connection,
+        const QuicSocketAddress& direct_peer_address)
+    : QuicPathValidator::ResultDelegate(),
+      connection_(connection),
+      original_direct_peer_address_(direct_peer_address),
+      peer_address_default_path_(connection->direct_peer_address_),
+      peer_address_alternative_path_(
+          connection_->alternative_path_.peer_address),
+      active_effective_peer_migration_type_(
+          connection_->active_effective_peer_migration_type_) {}
+
+void QuicConnection::ReversePathValidationResultDelegate::
+    OnPathValidationSuccess(
+        std::unique_ptr<QuicPathValidationContext> context) {
+  QUIC_DLOG(INFO) << "Successfully validated new path " << *context;
+  if (connection_->IsDefaultPath(context->self_address(),
+                                 context->peer_address())) {
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 3, 6);
+    if (connection_->active_effective_peer_migration_type_ == NO_CHANGE) {
+      connection_->quic_bug_10511_43_timestamp_ =
+          connection_->clock_->WallNow();
+      connection_->quic_bug_10511_43_error_detail_ = absl::StrCat(
+          "Reverse path validation on default path from ",
+          context->self_address().ToString(), " to ",
+          context->peer_address().ToString(),
+          " completed without active peer address change: current "
+          "peer address on default path ",
+          connection_->direct_peer_address_.ToString(),
+          ", peer address on default path when the reverse path "
+          "validation was kicked off ",
+          peer_address_default_path_.ToString(),
+          ", peer address on alternative path when the reverse "
+          "path validation was kicked off ",
+          peer_address_alternative_path_.ToString(),
+          ", with active_effective_peer_migration_type_ = ",
+          AddressChangeTypeToString(active_effective_peer_migration_type_),
+          ". The last received packet number ",
+          connection_->last_header_.packet_number.ToString(),
+          " Connection is connected: ", connection_->connected_);
+      QUIC_BUG(quic_bug_10511_43)
+          << connection_->quic_bug_10511_43_error_detail_;
+    }
+    connection_->OnEffectivePeerMigrationValidated();
+  } else {
+    QUICHE_DCHECK(connection_->IsAlternativePath(
+        context->self_address(), context->effective_peer_address()));
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 4, 6);
+    QUIC_DVLOG(1) << "Mark alternative peer address "
+                  << context->effective_peer_address() << " validated.";
+    connection_->alternative_path_.validated = true;
+  }
+}
+
+void QuicConnection::ReversePathValidationResultDelegate::
+    OnPathValidationFailure(
+        std::unique_ptr<QuicPathValidationContext> context) {
+  if (!connection_->connected()) {
+    return;
+  }
+  QUIC_DLOG(INFO) << "Fail to validate new path " << *context;
+  if (connection_->IsDefaultPath(context->self_address(),
+                                 context->peer_address())) {
+    // Only act upon validation failure on the default path.
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 5, 6);
+    connection_->RestoreToLastValidatedPath(original_direct_peer_address_);
+  } else if (connection_->IsAlternativePath(
+                 context->self_address(), context->effective_peer_address())) {
+    QUIC_CODE_COUNT_N(quic_kick_off_client_address_validation, 6, 6);
+    connection_->alternative_path_.Clear();
+  }
+  connection_->RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+}
+
+QuicConnection::ScopedRetransmissionTimeoutIndicator::
+    ScopedRetransmissionTimeoutIndicator(QuicConnection* connection)
+    : connection_(connection) {
+  QUICHE_DCHECK(!connection_->in_on_retransmission_time_out_)
+      << "ScopedRetransmissionTimeoutIndicator is not supposed to be nested";
+  connection_->in_on_retransmission_time_out_ = true;
+}
+
+QuicConnection::ScopedRetransmissionTimeoutIndicator::
+    ~ScopedRetransmissionTimeoutIndicator() {
+  QUICHE_DCHECK(connection_->in_on_retransmission_time_out_);
+  connection_->in_on_retransmission_time_out_ = false;
+}
+
+void QuicConnection::RestoreToLastValidatedPath(
+    QuicSocketAddress original_direct_peer_address) {
+  QUIC_DLOG(INFO) << "Switch back to use the old peer address "
+                  << alternative_path_.peer_address;
+  if (!alternative_path_.validated) {
+    // If not validated by now, close connection silently so that the following
+    // packets received will be rejected.
+    CloseConnection(QUIC_INTERNAL_ERROR,
+                    "No validated peer address to use after reverse path "
+                    "validation failure.",
+                    ConnectionCloseBehavior::SILENT_CLOSE);
+    return;
+  }
+  MaybeClearQueuedPacketsOnPathChange();
+
+  // Revert congestion control context to old state.
+  OnPeerIpAddressChanged();
+
+  if (alternative_path_.send_algorithm != nullptr) {
+    sent_packet_manager_.SetSendAlgorithm(
+        alternative_path_.send_algorithm.release());
+    sent_packet_manager_.SetRttStats(alternative_path_.rtt_stats.value());
+  } else {
+    QUIC_BUG(quic_bug_10511_42)
+        << "Fail to store congestion controller before migration.";
+  }
+
+  UpdatePeerAddress(original_direct_peer_address);
+  SetDefaultPathState(std::move(alternative_path_));
+
+  active_effective_peer_migration_type_ = NO_CHANGE;
+  ++stats_.num_invalid_peer_migration;
+  // The reverse path validation failed because of alarm firing, flush all the
+  // pending writes previously throttled by anti-amplification limit.
+  WriteIfNotBlocked();
+}
+
+std::unique_ptr<SendAlgorithmInterface>
+QuicConnection::OnPeerIpAddressChanged() {
+  QUICHE_DCHECK(validate_client_addresses_);
+  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
+      sent_packet_manager_.OnConnectionMigration(
+          /*reset_send_algorithm=*/true);
+  // OnConnectionMigration() should have marked in-flight packets to be
+  // retransmitted if there is any.
+  QUICHE_DCHECK(!sent_packet_manager_.HasInFlightPackets());
+  // OnConnectionMigration() may have changed the retransmission timer, so
+  // re-arm it.
+  SetRetransmissionAlarm();
+  // Stop detections in quiecense.
+  blackhole_detector_.StopDetection(/*permanent=*/false);
+  return old_send_algorithm;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
new file mode 100644
index 0000000..23b78be
--- /dev/null
+++ b/quiche/quic/core/quic_connection.h
@@ -0,0 +1,2290 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The entity that handles framing writes for a Quic client or server.
+// Each QuicSession will have a connection associated with it.
+//
+// On the server side, the Dispatcher handles the raw reads, and hands off
+// packets via ProcessUdpPacket for framing and processing.
+//
+// On the client side, the Connection handles the raw reads, as well as the
+// processing.
+//
+// Note: this class is not thread-safe.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_blocked_writer_interface.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_connection_id_manager.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_idle_network_detector.h"
+#include "quiche/quic/core/quic_mtu_discovery.h"
+#include "quiche/quic/core/quic_network_blackhole_detector.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/uber_received_packet_manager.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+class QuicClock;
+class QuicConfig;
+class QuicConnection;
+class QuicRandom;
+
+namespace test {
+class QuicConnectionPeer;
+}  // namespace test
+
+// Class that receives callbacks from the connection when frames are received
+// and when other interesting events happen.
+class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
+ public:
+  virtual ~QuicConnectionVisitorInterface() {}
+
+  // A simple visitor interface for dealing with a data frame.
+  virtual void OnStreamFrame(const QuicStreamFrame& frame) = 0;
+
+  // Called when a CRYPTO frame containing handshake data is received.
+  virtual void OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
+
+  // The session should process the WINDOW_UPDATE frame, adjusting both stream
+  // and connection level flow control windows.
+  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
+
+  // A BLOCKED frame indicates the peer is flow control blocked
+  // on a specified stream.
+  virtual void OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
+
+  // Called when the stream is reset by the peer.
+  virtual void OnRstStream(const QuicRstStreamFrame& frame) = 0;
+
+  // Called when the connection is going away according to the peer.
+  virtual void OnGoAway(const QuicGoAwayFrame& frame) = 0;
+
+  // Called when |message| has been received.
+  virtual void OnMessageReceived(absl::string_view message) = 0;
+
+  // Called when a HANDSHAKE_DONE frame has been received.
+  virtual void OnHandshakeDoneReceived() = 0;
+
+  // Called when a NEW_TOKEN frame has been received.
+  virtual void OnNewTokenReceived(absl::string_view token) = 0;
+
+  // Called when a MAX_STREAMS frame has been received from the peer.
+  virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
+
+  // Called when a STREAMS_BLOCKED frame has been received from the peer.
+  virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
+
+  // Called when the connection is closed either locally by the framer, or
+  // remotely by the peer.
+  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                                  ConnectionCloseSource source) = 0;
+
+  // Called when the connection failed to write because the socket was blocked.
+  virtual void OnWriteBlocked() = 0;
+
+  // Called once a specific QUIC version is agreed by both endpoints.
+  virtual void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& version) = 0;
+
+  // Called when a packet has been received by the connection, after being
+  // validated and parsed. Only called when the client receives a valid packet
+  // or the server receives a connectivity probing packet.
+  // |is_connectivity_probe| is true if the received packet is a connectivity
+  // probe.
+  virtual void OnPacketReceived(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                bool is_connectivity_probe) = 0;
+
+  // Called when a blocked socket becomes writable.
+  virtual void OnCanWrite() = 0;
+
+  // Called when the connection needs more data to probe for additional
+  // bandwidth.  Returns true if data was sent, false otherwise.
+  virtual bool SendProbingData() = 0;
+
+  // Called when stateless reset packet is received. Returns true if the
+  // connection needs to be closed.
+  virtual bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& self_address,
+      const quic::QuicSocketAddress& peer_address) = 0;
+
+  // Called when the connection experiences a change in congestion window.
+  virtual void OnCongestionWindowChange(QuicTime now) = 0;
+
+  // Called when the connection receives a packet from a migrated client.
+  virtual void OnConnectionMigration(AddressChangeType type) = 0;
+
+  // Called when the peer seems unreachable over the current path.
+  virtual void OnPathDegrading() = 0;
+
+  // Called when forward progress made after path degrading.
+  virtual void OnForwardProgressMadeAfterPathDegrading() = 0;
+
+  // Called when the connection sends ack after
+  // max_consecutive_num_packets_with_no_retransmittable_frames_ consecutive not
+  // retransmittable packets sent. To instigate an ack from peer, a
+  // retransmittable frame needs to be added.
+  virtual void OnAckNeedsRetransmittableFrame() = 0;
+
+  // Called when an AckFrequency frame need to be sent.
+  virtual void SendAckFrequency(const QuicAckFrequencyFrame& frame) = 0;
+
+  // Called to send a NEW_CONNECTION_ID frame.
+  virtual void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
+
+  // Called to send a RETIRE_CONNECTION_ID frame.
+  virtual void SendRetireConnectionId(uint64_t sequence_number) = 0;
+
+  // Called when server starts to use a server issued connection ID.
+  virtual void OnServerConnectionIdIssued(
+      const QuicConnectionId& server_connection_id) = 0;
+
+  // Called when server stops to use a server issued connection ID.
+  virtual void OnServerConnectionIdRetired(
+      const QuicConnectionId& server_connection_id) = 0;
+
+  // Called to ask if the visitor wants to schedule write resumption as it both
+  // has pending data to write, and is able to write (e.g. based on flow control
+  // limits).
+  // Writes may be pending because they were write-blocked, congestion-throttled
+  // or yielded to other connections.
+  virtual bool WillingAndAbleToWrite() const = 0;
+
+  // Called to ask if the connection should be kept alive and prevented
+  // from timing out, for example if there are outstanding application
+  // transactions expecting a response.
+  virtual bool ShouldKeepConnectionAlive() const = 0;
+
+  // Called to retrieve streams information for logging purpose.
+  virtual std::string GetStreamsInfoForLogging() const = 0;
+
+  // Called when a self address change is observed. Returns true if self address
+  // change is allowed.
+  virtual bool AllowSelfAddressChange() const = 0;
+
+  // Called to get current handshake state.
+  virtual HandshakeState GetHandshakeState() const = 0;
+
+  // Called when a STOP_SENDING frame has been received.
+  virtual void OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
+
+  // Called when a packet of encryption |level| has been successfully decrypted.
+  virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
+
+  // Called when a 1RTT packet has been acknowledged.
+  virtual void OnOneRttPacketAcknowledged() = 0;
+
+  // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+  virtual void OnHandshakePacketSent() = 0;
+
+  // Called when a key update has occurred.
+  virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
+
+  // Called to generate a decrypter for the next key phase. Each call should
+  // generate the key for phase n+1.
+  virtual std::unique_ptr<QuicDecrypter>
+  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+  // Called to generate an encrypter for the same key phase of the last
+  // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
+  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+
+  // Called when connection is being closed right before a CONNECTION_CLOSE
+  // frame is serialized, but only on the server and only if forward secure
+  // encryption has already been established.
+  virtual void BeforeConnectionCloseSent() = 0;
+
+  // Called by the server to validate |token| in received INITIAL packets.
+  // Consider the client address gets validated (and therefore remove
+  // amplification factor) once the |token| gets successfully validated.
+  virtual bool ValidateToken(absl::string_view token) = 0;
+
+  // Called by the server to send another token.
+  // Return false if the crypto stream fail to generate one.
+  virtual bool MaybeSendAddressToken() = 0;
+
+  // Whether the server address is known to the connection.
+  virtual bool IsKnownServerAddress(const QuicSocketAddress& address) const = 0;
+};
+
+// Interface which gets callbacks from the QuicConnection at interesting
+// points.  Implementations must not mutate the state of the connection
+// as a result of these callbacks.
+class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
+    : public QuicSentPacketManager::DebugDelegate {
+ public:
+  ~QuicConnectionDebugVisitor() override {}
+
+  // Called when a packet has been sent.
+  virtual void OnPacketSent(QuicPacketNumber /*packet_number*/,
+                            QuicPacketLength /*packet_length*/,
+                            bool /*has_crypto_handshake*/,
+                            TransmissionType /*transmission_type*/,
+                            EncryptionLevel /*encryption_level*/,
+                            const QuicFrames& /*retransmittable_frames*/,
+                            const QuicFrames& /*nonretransmittable_frames*/,
+                            QuicTime /*sent_time*/) {}
+
+  // Called when a coalesced packet is successfully serialized.
+  virtual void OnCoalescedPacketSent(
+      const QuicCoalescedPacket& /*coalesced_packet*/, size_t /*length*/) {}
+
+  // Called when a PING frame has been sent.
+  virtual void OnPingSent() {}
+
+  // Called when a packet has been received, but before it is
+  // validated or parsed.
+  virtual void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
+                                const QuicSocketAddress& /*peer_address*/,
+                                const QuicEncryptedPacket& /*packet*/) {}
+
+  // Called when the unauthenticated portion of the header has been parsed.
+  virtual void OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) {}
+
+  // Called when a packet is received with a connection id that does not
+  // match the ID of this connection.
+  virtual void OnIncorrectConnectionId(QuicConnectionId /*connection_id*/) {}
+
+  // Called when an undecryptable packet has been received. If |dropped| is
+  // true, the packet has been dropped. Otherwise, the packet will be queued and
+  // connection will attempt to process it later.
+  virtual void OnUndecryptablePacket(EncryptionLevel /*decryption_level*/,
+                                     bool /*dropped*/) {}
+
+  // Called when attempting to process a previously undecryptable packet.
+  virtual void OnAttemptingToProcessUndecryptablePacket(
+      EncryptionLevel /*decryption_level*/) {}
+
+  // Called when a duplicate packet has been received.
+  virtual void OnDuplicatePacket(QuicPacketNumber /*packet_number*/) {}
+
+  // Called when the protocol version on the received packet doensn't match
+  // current protocol version of the connection.
+  virtual void OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) {}
+
+  // Called when the complete header of a packet has been parsed.
+  virtual void OnPacketHeader(const QuicPacketHeader& /*header*/,
+                              QuicTime /*receive_time*/,
+                              EncryptionLevel /*level*/) {}
+
+  // Called when a StreamFrame has been parsed.
+  virtual void OnStreamFrame(const QuicStreamFrame& /*frame*/) {}
+
+  // Called when a CRYPTO frame containing handshake data is received.
+  virtual void OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
+
+  // Called when a StopWaitingFrame has been parsed.
+  virtual void OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) {}
+
+  // Called when a QuicPaddingFrame has been parsed.
+  virtual void OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {}
+
+  // Called when a Ping has been parsed.
+  virtual void OnPingFrame(const QuicPingFrame& /*frame*/,
+                           QuicTime::Delta /*ping_received_delay*/) {}
+
+  // Called when a GoAway has been parsed.
+  virtual void OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {}
+
+  // Called when a RstStreamFrame has been parsed.
+  virtual void OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {}
+
+  // Called when a ConnectionCloseFrame has been parsed. All forms
+  // of CONNECTION CLOSE are handled, Google QUIC, IETF QUIC
+  // CONNECTION CLOSE/Transport and IETF QUIC CONNECTION CLOSE/Application
+  virtual void OnConnectionCloseFrame(
+      const QuicConnectionCloseFrame& /*frame*/) {}
+
+  // Called when a WindowUpdate has been parsed.
+  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
+                                   const QuicTime& /*receive_time*/) {}
+
+  // Called when a BlockedFrame has been parsed.
+  virtual void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {}
+
+  // Called when a NewConnectionIdFrame has been parsed.
+  virtual void OnNewConnectionIdFrame(
+      const QuicNewConnectionIdFrame& /*frame*/) {}
+
+  // Called when a RetireConnectionIdFrame has been parsed.
+  virtual void OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& /*frame*/) {}
+
+  // Called when a NewTokenFrame has been parsed.
+  virtual void OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {}
+
+  // Called when a MessageFrame has been parsed.
+  virtual void OnMessageFrame(const QuicMessageFrame& /*frame*/) {}
+
+  // Called when a HandshakeDoneFrame has been parsed.
+  virtual void OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) {}
+
+  // Called when a public reset packet has been received.
+  virtual void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) {}
+
+  // Called when a version negotiation packet has been received.
+  virtual void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) {}
+
+  // Called when the connection is closed.
+  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
+                                  ConnectionCloseSource /*source*/) {}
+
+  // Called when the version negotiation is successful.
+  virtual void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& /*version*/) {}
+
+  // Called when a CachedNetworkParameters is sent to the client.
+  virtual void OnSendConnectionState(
+      const CachedNetworkParameters& /*cached_network_params*/) {}
+
+  // Called when a CachedNetworkParameters are received from the client.
+  virtual void OnReceiveConnectionState(
+      const CachedNetworkParameters& /*cached_network_params*/) {}
+
+  // Called when the connection parameters are set from the supplied
+  // |config|.
+  virtual void OnSetFromConfig(const QuicConfig& /*config*/) {}
+
+  // Called when RTT may have changed, including when an RTT is read from
+  // the config.
+  virtual void OnRttChanged(QuicTime::Delta /*rtt*/) const {}
+
+  // Called when a StopSendingFrame has been parsed.
+  virtual void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) {}
+
+  // Called when a PathChallengeFrame has been parsed.
+  virtual void OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) {}
+
+  // Called when a PathResponseFrame has been parsed.
+  virtual void OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) {}
+
+  // Called when a StreamsBlockedFrame has been parsed.
+  virtual void OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& /*frame*/) {
+  }
+
+  // Called when a MaxStreamsFrame has been parsed.
+  virtual void OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) {}
+
+  // Called when an AckFrequencyFrame has been parsed.
+  virtual void OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) {}
+
+  // Called when |count| packet numbers have been skipped.
+  virtual void OnNPacketNumbersSkipped(QuicPacketCount /*count*/,
+                                       QuicTime /*now*/) {}
+
+  // Called when a packet is serialized but discarded (i.e. not sent).
+  virtual void OnPacketDiscarded(const SerializedPacket& /*packet*/) {}
+
+  // Called for QUIC+TLS versions when we send transport parameters.
+  virtual void OnTransportParametersSent(
+      const TransportParameters& /*transport_parameters*/) {}
+
+  // Called for QUIC+TLS versions when we receive transport parameters.
+  virtual void OnTransportParametersReceived(
+      const TransportParameters& /*transport_parameters*/) {}
+
+  // Called for QUIC+TLS versions when we resume cached transport parameters for
+  // 0-RTT.
+  virtual void OnTransportParametersResumed(
+      const TransportParameters& /*transport_parameters*/) {}
+
+  // Called for QUIC+TLS versions when 0-RTT is rejected.
+  virtual void OnZeroRttRejected(int /*reject_reason*/) {}
+
+  // Called for QUIC+TLS versions when 0-RTT packet gets acked.
+  virtual void OnZeroRttPacketAcked() {}
+
+  // Called on peer address change.
+  virtual void OnPeerAddressChange(AddressChangeType /*type*/,
+                                   QuicTime::Delta /*connection_time*/) {}
+
+  // Called after peer migration is validated.
+  virtual void OnPeerMigrationValidated(QuicTime::Delta /*connection_time*/) {}
+};
+
+class QUIC_EXPORT_PRIVATE QuicConnectionHelperInterface {
+ public:
+  virtual ~QuicConnectionHelperInterface() {}
+
+  // Returns a QuicClock to be used for all time related functions.
+  virtual const QuicClock* GetClock() const = 0;
+
+  // Returns a QuicRandom to be used for all random number related functions.
+  virtual QuicRandom* GetRandomGenerator() = 0;
+
+  // Returns a QuicheBufferAllocator to be used for stream send buffers.
+  virtual quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() = 0;
+};
+
+class QUIC_EXPORT_PRIVATE QuicConnection
+    : public QuicFramerVisitorInterface,
+      public QuicBlockedWriterInterface,
+      public QuicPacketCreator::DelegateInterface,
+      public QuicSentPacketManager::NetworkChangeVisitor,
+      public QuicNetworkBlackholeDetector::Delegate,
+      public QuicIdleNetworkDetector::Delegate,
+      public QuicPathValidator::SendDelegate,
+      public QuicConnectionIdManagerVisitorInterface {
+ public:
+  // Constructs a new QuicConnection for |connection_id| and
+  // |initial_peer_address| using |writer| to write packets. |owns_writer|
+  // specifies whether the connection takes ownership of |writer|. |helper| must
+  // outlive this connection.
+  QuicConnection(QuicConnectionId server_connection_id,
+                 QuicSocketAddress initial_self_address,
+                 QuicSocketAddress initial_peer_address,
+                 QuicConnectionHelperInterface* helper,
+                 QuicAlarmFactory* alarm_factory,
+                 QuicPacketWriter* writer,
+                 bool owns_writer,
+                 Perspective perspective,
+                 const ParsedQuicVersionVector& supported_versions);
+  QuicConnection(const QuicConnection&) = delete;
+  QuicConnection& operator=(const QuicConnection&) = delete;
+  ~QuicConnection() override;
+
+  // Sets connection parameters from the supplied |config|.
+  void SetFromConfig(const QuicConfig& config);
+
+  // Apply |connection_options| for this connection. Unlike SetFromConfig, this
+  // can happen at anytime in the life of a connection.
+  // Note there is no guarantee that all options can be applied. Components will
+  // only apply cherrypicked options that make sense at the time of the call.
+  void ApplyConnectionOptions(const QuicTagVector& connection_options);
+
+  // Called by the session when sending connection state to the client.
+  virtual void OnSendConnectionState(
+      const CachedNetworkParameters& cached_network_params);
+
+  // Called by the session when receiving connection state from the client.
+  virtual void OnReceiveConnectionState(
+      const CachedNetworkParameters& cached_network_params);
+
+  // Called by the Session when the client has provided CachedNetworkParameters.
+  virtual void ResumeConnectionState(
+      const CachedNetworkParameters& cached_network_params,
+      bool max_bandwidth_resumption);
+
+  // Called by the Session when a max pacing rate for the connection is needed.
+  virtual void SetMaxPacingRate(QuicBandwidth max_pacing_rate);
+
+  // Allows the client to adjust network parameters based on external
+  // information.
+  void AdjustNetworkParameters(
+      const SendAlgorithmInterface::NetworkParams& params);
+  void AdjustNetworkParameters(QuicBandwidth bandwidth,
+                               QuicTime::Delta rtt,
+                               bool allow_cwnd_to_decrease);
+
+  // Install a loss detection tuner. Must be called before OnConfigNegotiated.
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner);
+  // Called by the session when session->is_configured() becomes true.
+  void OnConfigNegotiated();
+
+  // Returns the max pacing rate for the connection.
+  virtual QuicBandwidth MaxPacingRate() const;
+
+  // Sends crypto handshake messages of length |write_length| to the peer in as
+  // few packets as possible. Returns the number of bytes consumed from the
+  // data.
+  virtual size_t SendCryptoData(EncryptionLevel level,
+                                size_t write_length,
+                                QuicStreamOffset offset);
+
+  // Send the data of length |write_length| to the peer in as few packets as
+  // possible. Returns the number of bytes consumed from data, and a boolean
+  // indicating if the fin bit was consumed.  This does not indicate the data
+  // has been sent on the wire: it may have been turned into a packet and queued
+  // if the socket was unexpectedly blocked.
+  virtual QuicConsumedData SendStreamData(QuicStreamId id,
+                                          size_t write_length,
+                                          QuicStreamOffset offset,
+                                          StreamSendingState state);
+
+  // Send |frame| to the peer. Returns true if frame is consumed, false
+  // otherwise.
+  virtual bool SendControlFrame(const QuicFrame& frame);
+
+  // Called when stream |id| is reset because of |error|.
+  virtual void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
+
+  // Closes the connection.
+  // |connection_close_behavior| determines whether or not a connection close
+  // packet is sent to the peer.
+  virtual void CloseConnection(
+      QuicErrorCode error,
+      const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior);
+  // Closes the connection, specifying the wire error code |ietf_error|
+  // explicitly.
+  virtual void CloseConnection(
+      QuicErrorCode error,
+      QuicIetfTransportErrorCodes ietf_error,
+      const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior);
+
+  QuicConnectionStats& mutable_stats() { return stats_; }
+
+  int retransmittable_on_wire_ping_count() const {
+    return retransmittable_on_wire_ping_count_;
+  }
+
+  // Returns statistics tracked for this connection.
+  const QuicConnectionStats& GetStats();
+
+  // Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from
+  // the peer.
+  // In a client, the packet may be "stray" and have a different connection ID
+  // than that of this connection.
+  virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                const QuicReceivedPacket& packet);
+
+  // QuicBlockedWriterInterface
+  // Called when the underlying connection becomes writable to allow queued
+  // writes to happen.
+  void OnBlockedWriterCanWrite() override;
+
+  bool IsWriterBlocked() const override {
+    return writer_ != nullptr && writer_->IsWriteBlocked();
+  }
+
+  // Called when the caller thinks it's worth a try to write.
+  // TODO(fayang): consider unifying this with QuicSession::OnCanWrite.
+  virtual void OnCanWrite();
+
+  // Called when an error occurs while attempting to write a packet to the
+  // network.
+  void OnWriteError(int error_code);
+
+  // Whether |result| represents a MSG TOO BIG write error.
+  bool IsMsgTooBig(const QuicPacketWriter* writer, const WriteResult& result);
+
+  // If the socket is not blocked, writes queued packets.
+  void WriteIfNotBlocked();
+
+  // Set the packet writer.
+  void SetQuicPacketWriter(QuicPacketWriter* writer, bool owns_writer) {
+    QUICHE_DCHECK(writer != nullptr);
+    if (writer_ != nullptr && owns_writer_) {
+      delete writer_;
+    }
+    writer_ = writer;
+    owns_writer_ = owns_writer;
+  }
+
+  // Set self address.
+  void SetSelfAddress(QuicSocketAddress address) {
+    default_path_.self_address = address;
+  }
+
+  // The version of the protocol this connection is using.
+  QuicTransportVersion transport_version() const {
+    return framer_.transport_version();
+  }
+
+  ParsedQuicVersion version() const { return framer_.version(); }
+
+  // The versions of the protocol that this connection supports.
+  const ParsedQuicVersionVector& supported_versions() const {
+    return framer_.supported_versions();
+  }
+
+  // Mark version negotiated for this connection. Once called, the connection
+  // will ignore received version negotiation packets.
+  void SetVersionNegotiated() {
+    version_negotiated_ = true;
+    if (perspective_ == Perspective::IS_SERVER) {
+      framer_.InferPacketHeaderTypeFromVersion();
+    }
+  }
+
+  // From QuicFramerVisitorInterface
+  void OnError(QuicFramer* framer) override;
+  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
+  void OnPacket() override;
+  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) override;
+  void OnRetryPacket(QuicConnectionId original_connection_id,
+                     QuicConnectionId new_connection_id,
+                     absl::string_view retry_token,
+                     absl::string_view retry_integrity_tag,
+                     absl::string_view retry_without_tag) override;
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
+  void OnDecryptedPacket(size_t length, EncryptionLevel level) override;
+  bool OnPacketHeader(const QuicPacketHeader& header) override;
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override;
+  bool OnStreamFrame(const QuicStreamFrame& frame) override;
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override;
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override;
+  bool OnAckFrameEnd(QuicPacketNumber start) override;
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
+  bool OnPingFrame(const QuicPingFrame& frame) override;
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override;
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
+  bool OnMessageFrame(const QuicMessageFrame& frame) override;
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
+  void OnPacketComplete() override;
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override;
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override;
+  void OnKeyUpdate(KeyUpdateReason reason) override;
+  void OnDecryptedFirstPacketInKeyPhase() override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+
+  // QuicPacketCreator::DelegateInterface
+  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+                            IsHandshake handshake) override;
+  const QuicFrames MaybeBundleAckOpportunistically() override;
+  QuicPacketBuffer GetPacketBuffer() override;
+  void OnSerializedPacket(SerializedPacket packet) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& error_details) override;
+  SerializedPacketFate GetSerializedPacketFate(
+      bool is_mtu_discovery,
+      EncryptionLevel encryption_level) override;
+
+  // QuicSentPacketManager::NetworkChangeVisitor
+  void OnCongestionChange() override;
+  void OnPathMtuIncreased(QuicPacketLength packet_size) override;
+
+  // QuicNetworkBlackholeDetector::Delegate
+  void OnPathDegradingDetected() override;
+  void OnBlackholeDetected() override;
+  void OnPathMtuReductionDetected() override;
+
+  // QuicIdleNetworkDetector::Delegate
+  void OnHandshakeTimeout() override;
+  void OnIdleNetworkDetected() override;
+
+  // QuicConnectionIdManagerVisitorInterface
+  void OnPeerIssuedConnectionIdRetired() override;
+  bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
+  void OnNewConnectionIdIssued(const QuicConnectionId& connection_id) override;
+  void OnSelfIssuedConnectionIdRetired(
+      const QuicConnectionId& connection_id) override;
+
+  // Please note, this is not a const function. For logging purpose, please use
+  // ack_frame().
+  const QuicFrame GetUpdatedAckFrame();
+
+  // Called to send a new connection ID to client if the # of connection ID has
+  // not exceeded the active connection ID limits.
+  void MaybeSendConnectionIdToClient();
+
+  // Called when the handshake completes. On the client side, handshake
+  // completes on receipt of SHLO. On the server side, handshake completes when
+  // SHLO gets ACKed (or a forward secure packet gets decrypted successfully).
+  // TODO(fayang): Add a guard that this only gets called once.
+  void OnHandshakeComplete();
+
+  // Accessors
+  void set_visitor(QuicConnectionVisitorInterface* visitor) {
+    visitor_ = visitor;
+  }
+  void set_debug_visitor(QuicConnectionDebugVisitor* debug_visitor) {
+    debug_visitor_ = debug_visitor;
+    sent_packet_manager_.SetDebugDelegate(debug_visitor);
+  }
+  // Used in Chromium, but not internally.
+  // Must only be called before ping_alarm_ is set.
+  void set_ping_timeout(QuicTime::Delta ping_timeout) {
+    QUICHE_DCHECK(!ping_alarm_->IsSet());
+    ping_timeout_ = ping_timeout;
+  }
+  const QuicTime::Delta ping_timeout() const { return ping_timeout_; }
+  // Sets an initial timeout for the ping alarm when there is no retransmittable
+  // data in flight, allowing for a more aggressive ping alarm in that case.
+  void set_initial_retransmittable_on_wire_timeout(
+      QuicTime::Delta retransmittable_on_wire_timeout) {
+    QUICHE_DCHECK(!ping_alarm_->IsSet());
+    initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
+  }
+  const QuicTime::Delta initial_retransmittable_on_wire_timeout() const {
+    return initial_retransmittable_on_wire_timeout_;
+  }
+  // Used in Chromium, but not internally.
+  void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
+    packet_creator_.set_debug_delegate(visitor);
+  }
+  const QuicSocketAddress& self_address() const {
+    return default_path_.self_address;
+  }
+  const QuicSocketAddress& peer_address() const { return direct_peer_address_; }
+  const QuicSocketAddress& effective_peer_address() const {
+    return default_path_.peer_address;
+  }
+
+  // Returns the server connection ID used on the default path.
+  const QuicConnectionId& connection_id() const {
+    return default_path_.server_connection_id;
+  }
+
+  const QuicConnectionId& client_connection_id() const {
+    return default_path_.client_connection_id;
+  }
+  void set_client_connection_id(QuicConnectionId client_connection_id);
+  const QuicClock* clock() const { return clock_; }
+  QuicRandom* random_generator() const { return random_generator_; }
+  QuicByteCount max_packet_length() const;
+  void SetMaxPacketLength(QuicByteCount length);
+
+  size_t mtu_probe_count() const { return mtu_probe_count_; }
+
+  bool connected() const { return connected_; }
+
+  // Must only be called on client connections.
+  const ParsedQuicVersionVector& server_supported_versions() const {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+    return server_supported_versions_;
+  }
+
+  bool HasQueuedPackets() const { return !buffered_packets_.empty(); }
+  // Testing only. TODO(ianswett): Use a peer instead.
+  size_t NumQueuedPackets() const { return buffered_packets_.size(); }
+
+  // Returns true if the connection has queued packets or frames.
+  bool HasQueuedData() const;
+
+  // Sets the handshake and idle state connection timeouts.
+  void SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
+                          QuicTime::Delta idle_timeout);
+
+  // Called when the ping alarm fires. Causes a ping frame to be sent only
+  // if the retransmission alarm is not running.
+  void OnPingTimeout();
+
+  // Sets up a packet with an QuicAckFrame and sends it out.
+  void SendAck();
+
+  // Called when an RTO fires.  Resets the retransmission alarm if there are
+  // remaining unacked packets.
+  void OnRetransmissionTimeout();
+
+  // Mark all sent 0-RTT encrypted packets for retransmission. Called when new
+  // 0-RTT or 1-RTT key is available in gQUIC, or when 0-RTT is rejected in IETF
+  // QUIC. |reject_reason| is used in TLS-QUIC to log why 0-RTT was rejected.
+  void MarkZeroRttPacketsForRetransmission(int reject_reason);
+
+  // Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the
+  // connection becomes forward secure and hasn't received acks for all packets.
+  void NeuterUnencryptedPackets();
+
+  // Changes the encrypter used for level |level| to |encrypter|.
+  void SetEncrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicEncrypter> encrypter);
+
+  // Called to remove encrypter of encryption |level|.
+  void RemoveEncrypter(EncryptionLevel level);
+
+  // SetNonceForPublicHeader sets the nonce that will be transmitted in the
+  // header of each packet encrypted at the initial encryption level decrypted.
+  // This should only be called on the server side.
+  void SetDiversificationNonce(const DiversificationNonce& nonce);
+
+  // SetDefaultEncryptionLevel sets the encryption level that will be applied
+  // to new packets.
+  void SetDefaultEncryptionLevel(EncryptionLevel level);
+
+  // SetDecrypter sets the primary decrypter, replacing any that already exists.
+  // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
+  // This is intended for cases where one knows that future packets will be
+  // using the new decrypter and the previous decrypter is now obsolete. |level|
+  // indicates the encryption level of the new decrypter.
+  void SetDecrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicDecrypter> decrypter);
+
+  // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
+  // future packets. |level| indicates the encryption level of the decrypter. If
+  // |latch_once_used| is true, then the first time that the decrypter is
+  // successful it will replace the primary decrypter.  Otherwise both
+  // decrypters will remain active and the primary decrypter will be the one
+  // last used.
+  void SetAlternativeDecrypter(EncryptionLevel level,
+                               std::unique_ptr<QuicDecrypter> decrypter,
+                               bool latch_once_used);
+
+  void InstallDecrypter(EncryptionLevel level,
+                        std::unique_ptr<QuicDecrypter> decrypter);
+  void RemoveDecrypter(EncryptionLevel level);
+
+  // Discard keys for the previous key phase.
+  void DiscardPreviousOneRttKeys();
+
+  // Returns true if it is currently allowed to initiate a key update.
+  bool IsKeyUpdateAllowed() const;
+
+  // Returns true if packets have been sent in the current 1-RTT key phase but
+  // none of these packets have been acked.
+  bool HaveSentPacketsInCurrentKeyPhaseButNoneAcked() const;
+
+  // Returns the count of packets received that appeared to attempt a key
+  // update but failed decryption that have been received since the last
+  // successfully decrypted packet.
+  QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
+
+  // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed()
+  // is false. Returns false on error.
+  bool InitiateKeyUpdate(KeyUpdateReason reason);
+
+  const QuicDecrypter* decrypter() const;
+  const QuicDecrypter* alternative_decrypter() const;
+
+  Perspective perspective() const { return perspective_; }
+
+  // Allow easy overriding of truncated connection IDs.
+  void set_can_truncate_connection_ids(bool can) {
+    can_truncate_connection_ids_ = can;
+  }
+
+  // Returns the underlying sent packet manager.
+  const QuicSentPacketManager& sent_packet_manager() const {
+    return sent_packet_manager_;
+  }
+
+  // Returns the underlying sent packet manager.
+  QuicSentPacketManager& sent_packet_manager() { return sent_packet_manager_; }
+
+  UberReceivedPacketManager& received_packet_manager() {
+    return uber_received_packet_manager_;
+  }
+
+  bool CanWrite(HasRetransmittableData retransmittable);
+
+  // When the flusher is out of scope, only the outermost flusher will cause a
+  // flush of the connection and set the retransmission alarm if there is one
+  // pending.  In addition, this flusher can be configured to ensure that an ACK
+  // frame is included in the first packet created, if there's new ack
+  // information to be sent.
+  class QUIC_EXPORT_PRIVATE ScopedPacketFlusher {
+   public:
+    explicit ScopedPacketFlusher(QuicConnection* connection);
+    ~ScopedPacketFlusher();
+
+   private:
+    QuicConnection* connection_;
+    // If true, when this flusher goes out of scope, flush connection and set
+    // retransmission alarm if there is one pending.
+    bool flush_and_set_pending_retransmission_alarm_on_delete_;
+    // Latched connection's handshake_packet_sent_ on creation of this flusher.
+    const bool handshake_packet_sent_;
+  };
+
+  class QUIC_EXPORT_PRIVATE ScopedEncryptionLevelContext {
+   public:
+    ScopedEncryptionLevelContext(QuicConnection* connection,
+                                 EncryptionLevel level);
+    ~ScopedEncryptionLevelContext();
+
+   private:
+    QuicConnection* connection_;
+    // Latched current write encryption level on creation of this context.
+    EncryptionLevel latched_encryption_level_;
+  };
+
+  QuicPacketWriter* writer() { return writer_; }
+  const QuicPacketWriter* writer() const { return writer_; }
+
+  // Sends an MTU discovery packet of size |target_mtu|.  If the packet is
+  // acknowledged by the peer, the maximum packet size will be increased to
+  // |target_mtu|.
+  void SendMtuDiscoveryPacket(QuicByteCount target_mtu);
+
+  // Sends a connectivity probing packet to |peer_address| with
+  // |probing_writer|. If |probing_writer| is nullptr, will use default
+  // packet writer to write the packet. Returns true if subsequent packets can
+  // be written to the probing writer. If connection is V99, a padded IETF QUIC
+  // PATH_CHALLENGE packet is transmitted; if not V99, a Google QUIC padded PING
+  // packet is transmitted.
+  virtual bool SendConnectivityProbingPacket(
+      QuicPacketWriter* probing_writer,
+      const QuicSocketAddress& peer_address);
+
+  // Disable MTU discovery on this connection.
+  void DisableMtuDiscovery();
+
+  // Sends an MTU discovery packet and updates the MTU discovery alarm.
+  void DiscoverMtu();
+
+  // Sets the session notifier on the SentPacketManager.
+  void SetSessionNotifier(SessionNotifierInterface* session_notifier);
+
+  // Set data producer in framer.
+  void SetDataProducer(QuicStreamFrameDataProducer* data_producer);
+
+  // Set transmission type of next sending packets.
+  void SetTransmissionType(TransmissionType type);
+
+  // Tries to send |message| and returns the message status.
+  // If |flush| is false, this will return a MESSAGE_STATUS_BLOCKED
+  // when the connection is deemed unwritable.
+  virtual MessageStatus SendMessage(QuicMessageId message_id,
+                                    absl::Span<quiche::QuicheMemSlice> message,
+                                    bool flush);
+
+  // Returns the largest payload that will fit into a single MESSAGE frame.
+  // Because overhead can vary during a connection, this method should be
+  // checked for every message.
+  QuicPacketLength GetCurrentLargestMessagePayload() const;
+  // Returns the largest payload that will fit into a single MESSAGE frame at
+  // any point during the connection.  This assumes the version and
+  // connection ID lengths do not change.
+  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
+
+  void SetUnackedMapInitialCapacity();
+
+  virtual int GetUnackedMapInitialCapacity() const {
+    return kDefaultUnackedPacketsInitialCapacity;
+  }
+
+  // Returns the id of the cipher last used for decrypting packets.
+  uint32_t cipher_id() const;
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets() {
+    return termination_packets_.get();
+  }
+
+  bool ack_frame_updated() const;
+
+  QuicConnectionHelperInterface* helper() { return helper_; }
+  const QuicConnectionHelperInterface* helper() const { return helper_; }
+  QuicAlarmFactory* alarm_factory() { return alarm_factory_; }
+
+  absl::string_view GetCurrentPacket();
+
+  const QuicFramer& framer() const { return framer_; }
+
+  const QuicPacketCreator& packet_creator() const { return packet_creator_; }
+
+  EncryptionLevel encryption_level() const { return encryption_level_; }
+  EncryptionLevel last_decrypted_level() const {
+    return last_decrypted_packet_level_;
+  }
+
+  const QuicSocketAddress& last_packet_source_address() const {
+    return last_received_packet_info_.source_address;
+  }
+
+  bool fill_up_link_during_probing() const {
+    return fill_up_link_during_probing_;
+  }
+  void set_fill_up_link_during_probing(bool new_value) {
+    fill_up_link_during_probing_ = new_value;
+  }
+
+  // This setting may be changed during the crypto handshake in order to
+  // enable/disable padding of different packets in the crypto handshake.
+  //
+  // This setting should never be set to false in public facing endpoints. It
+  // can only be set to false if there is some other mechanism of preventing
+  // amplification attacks, such as ICE (plus its a non-standard quic).
+  void set_fully_pad_crypto_handshake_packets(bool new_value) {
+    packet_creator_.set_fully_pad_crypto_handshake_packets(new_value);
+  }
+
+  bool fully_pad_during_crypto_handshake() const {
+    return packet_creator_.fully_pad_crypto_handshake_packets();
+  }
+
+  size_t min_received_before_ack_decimation() const;
+  void set_min_received_before_ack_decimation(size_t new_value);
+
+  // If |defer| is true, configures the connection to defer sending packets in
+  // response to an ACK to the SendAlarm. If |defer| is false, packets may be
+  // sent immediately after receiving an ACK.
+  void set_defer_send_in_response_to_packets(bool defer) {
+    defer_send_in_response_to_packets_ = defer;
+  }
+
+  // Sets the current per-packet options for the connection. The QuicConnection
+  // does not take ownership of |options|; |options| must live for as long as
+  // the QuicConnection is in use.
+  void set_per_packet_options(PerPacketOptions* options) {
+    per_packet_options_ = options;
+  }
+
+  bool IsPathDegrading() const { return is_path_degrading_; }
+
+  // Attempts to process any queued undecryptable packets.
+  void MaybeProcessUndecryptablePackets();
+
+  // Queue a coalesced packet.
+  void QueueCoalescedPacket(const QuicEncryptedPacket& packet);
+
+  // Process previously queued coalesced packets. Returns true if any coalesced
+  // packets have been successfully processed.
+  bool MaybeProcessCoalescedPackets();
+
+  enum PacketContent : uint8_t {
+    NO_FRAMES_RECEIVED,
+    // TODO(fkastenholz): Change name when we get rid of padded ping/
+    // pre-version-99.
+    // Also PATH CHALLENGE and PATH RESPONSE.
+    FIRST_FRAME_IS_PING,
+    SECOND_FRAME_IS_PADDING,
+    NOT_PADDED_PING,  // Set if the packet is not {PING, PADDING}.
+  };
+
+  // Whether the handshake completes from this connection's perspective.
+  bool IsHandshakeComplete() const;
+
+  // Whether peer completes handshake. Only used with TLS handshake.
+  bool IsHandshakeConfirmed() const;
+
+  // Returns the largest received packet number sent by peer.
+  QuicPacketNumber GetLargestReceivedPacket() const;
+
+  // Sets the original destination connection ID on the connection.
+  // This is called by QuicDispatcher when it has replaced the connection ID.
+  void SetOriginalDestinationConnectionId(
+      const QuicConnectionId& original_destination_connection_id);
+
+  // Returns the original destination connection ID used for this connection.
+  QuicConnectionId GetOriginalDestinationConnectionId();
+
+  // Called when ACK alarm goes off. Sends ACKs of those packet number spaces
+  // which have expired ACK timeout. Only used when this connection supports
+  // multiple packet number spaces.
+  void SendAllPendingAcks();
+
+  // Returns true if this connection supports multiple packet number spaces.
+  bool SupportsMultiplePacketNumberSpaces() const;
+
+  // For logging purpose.
+  const QuicAckFrame& ack_frame() const;
+
+  // Install encrypter and decrypter for ENCRYPTION_INITIAL using
+  // |connection_id| as the first client-sent destination connection ID,
+  // or the one sent after an IETF Retry.
+  void InstallInitialCrypters(QuicConnectionId connection_id);
+
+  // Called when version is considered negotiated.
+  void OnSuccessfulVersionNegotiation();
+
+  // Called when self migration succeeds after probing.
+  void OnSuccessfulMigration(bool is_port_change);
+
+  // Called for QUIC+TLS versions when we send transport parameters.
+  void OnTransportParametersSent(
+      const TransportParameters& transport_parameters) const;
+
+  // Called for QUIC+TLS versions when we receive transport parameters.
+  void OnTransportParametersReceived(
+      const TransportParameters& transport_parameters) const;
+
+  // Called for QUIC+TLS versions when we resume cached transport parameters for
+  // 0-RTT.
+  void OnTransportParametersResumed(
+      const TransportParameters& transport_parameters) const;
+
+  // Returns true if ack_alarm_ is set.
+  bool HasPendingAcks() const;
+
+  virtual void OnUserAgentIdKnown(const std::string& user_agent_id);
+
+  // Enables Legacy Version Encapsulation using |server_name| as SNI.
+  // Can only be set if this is a client connection.
+  void EnableLegacyVersionEncapsulation(const std::string& server_name);
+
+  bool use_path_validator() const { return use_path_validator_; }
+
+  // If now is close to idle timeout, returns true and sends a connectivity
+  // probing packet to test the connection for liveness. Otherwise, returns
+  // false.
+  bool MaybeTestLiveness();
+
+  // QuicPathValidator::SendDelegate
+  // Send PATH_CHALLENGE using the given path information. If |writer| is the
+  // default writer, PATH_CHALLENGE can be bundled with other frames, and the
+  // containing packet can be buffered if the writer is blocked. Otherwise,
+  // PATH_CHALLENGE will be written in an individual packet and it will be
+  // dropped if write fails. |data_buffer| will be populated with the payload
+  // for future validation.
+  // Return false if the connection is closed thus the caller will not continue
+  // the validation, otherwise return true.
+  bool SendPathChallenge(const QuicPathFrameBuffer& data_buffer,
+                         const QuicSocketAddress& self_address,
+                         const QuicSocketAddress& peer_address,
+                         const QuicSocketAddress& effective_peer_address,
+                         QuicPacketWriter* writer) override;
+  // If |writer| is the default writer and |peer_address| is the same as
+  // peer_address(), return the PTO of this connection. Otherwise, return 3 *
+  // kInitialRtt.
+  QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address_to_use,
+                           QuicPacketWriter* writer_to_use) const override;
+
+  // Start vaildating the path defined by |context| asynchronously and call the
+  // |result_delegate| after validation finishes. If the connection is
+  // validating another path, cancel and fail that validation before starting
+  // this one.
+  void ValidatePath(
+      std::unique_ptr<QuicPathValidationContext> context,
+      std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
+
+  bool can_receive_ack_frequency_frame() const {
+    return can_receive_ack_frequency_frame_;
+  }
+
+  void set_can_receive_ack_frequency_frame() {
+    can_receive_ack_frequency_frame_ = true;
+  }
+
+  bool is_processing_packet() const { return framer_.is_processing_packet(); }
+
+  bool HasPendingPathValidation() const;
+
+  QuicPathValidationContext* GetPathValidationContext() const;
+
+  void CancelPathValidation();
+
+  // Returns true if the migration succeeds, otherwise returns false (e.g., no
+  // available CIDs, connection disconnected, etc).
+  bool MigratePath(const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address,
+                   QuicPacketWriter* writer,
+                   bool owns_writer);
+
+  // Called to clear the alternative_path_ when path validation failed on the
+  // client side.
+  void OnPathValidationFailureAtClient();
+
+  void SetSourceAddressTokenToSend(absl::string_view token);
+
+  void SendPing() {
+    SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
+  }
+
+  // Returns one server connection ID that associates the current session in the
+  // session map.
+  virtual QuicConnectionId GetOneActiveServerConnectionId() const;
+
+  // Returns all server connection IDs that have not been removed from the
+  // session map.
+  virtual std::vector<QuicConnectionId> GetActiveServerConnectionIds() const;
+
+  bool validate_client_address() const { return validate_client_addresses_; }
+
+  bool connection_migration_use_new_cid() const {
+    return connection_migration_use_new_cid_;
+  }
+
+  bool count_bytes_on_alternative_path_separately() const {
+    return count_bytes_on_alternative_path_separately_;
+  }
+
+  // Instantiates connection ID manager.
+  void CreateConnectionIdManager();
+
+  QuicConnectionContext* context() { return &context_; }
+  const QuicConnectionContext* context() const { return &context_; }
+
+  void set_tracer(std::unique_ptr<QuicConnectionTracer> tracer) {
+    context_.tracer.swap(tracer);
+  }
+
+  void set_bug_listener(std::unique_ptr<QuicBugListener> bug_listener) {
+    context_.bug_listener.swap(bug_listener);
+  }
+
+  absl::optional<QuicWallTime> quic_bug_10511_43_timestamp() const {
+    return quic_bug_10511_43_timestamp_;
+  }
+
+  const std::string& quic_bug_10511_43_error_detail() const {
+    return quic_bug_10511_43_error_detail_;
+  }
+
+ protected:
+  // Calls cancel() on all the alarms owned by this connection.
+  void CancelAllAlarms();
+
+  // Send a packet to the peer, and takes ownership of the packet if the packet
+  // cannot be written immediately.
+  virtual void SendOrQueuePacket(SerializedPacket packet);
+
+  // Called after a packet is received from a new effective peer address and is
+  // decrypted. Starts validation of effective peer's address change. Calls
+  // OnConnectionMigration as soon as the address changed.
+  void StartEffectivePeerMigration(AddressChangeType type);
+
+  // Called when a effective peer address migration is validated.
+  virtual void OnEffectivePeerMigrationValidated();
+
+  // Get the effective peer address from the packet being processed. For proxied
+  // connections, effective peer address is the address of the endpoint behind
+  // the proxy. For non-proxied connections, effective peer address is the same
+  // as peer address.
+  //
+  // Notes for implementations in subclasses:
+  // - If the connection is not proxied, the overridden method should use the
+  //   base implementation:
+  //
+  //       return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
+  //
+  // - If the connection is proxied, the overridden method may return either of
+  //   the following:
+  //   a) The address of the endpoint behind the proxy. The address is used to
+  //      drive effective peer migration.
+  //   b) An uninitialized address, meaning the effective peer address does not
+  //      change.
+  virtual QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const;
+
+  // Selects and updates the version of the protocol being used by selecting a
+  // version from |available_versions| which is also supported. Returns true if
+  // such a version exists, false otherwise.
+  bool SelectMutualVersion(const ParsedQuicVersionVector& available_versions);
+
+  // Returns the current per-packet options for the connection.
+  PerPacketOptions* per_packet_options() { return per_packet_options_; }
+
+  AddressChangeType active_effective_peer_migration_type() const {
+    return active_effective_peer_migration_type_;
+  }
+
+  // Sends a connection close packet to the peer and includes an ACK if the ACK
+  // is not empty, the |error| is not PACKET_WRITE_ERROR, and it fits.
+  // |ietf_error| may optionally be be used to directly specify the wire
+  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
+  // QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
+  virtual void SendConnectionClosePacket(QuicErrorCode error,
+                                         QuicIetfTransportErrorCodes ietf_error,
+                                         const std::string& details);
+
+  // Returns true if the packet should be discarded and not sent.
+  virtual bool ShouldDiscardPacket(EncryptionLevel encryption_level);
+
+  // Retransmits packets continuously until blocked by the congestion control.
+  // If there are no packets to retransmit, does not do anything.
+  void SendProbingRetransmissions();
+
+  // Decides whether to send probing retransmissions, and does so if required.
+  void MaybeSendProbingRetransmissions();
+
+  // Notify various components(Session etc.) that this connection has been
+  // migrated.
+  virtual void OnConnectionMigration();
+
+  // Return whether the packet being processed is a connectivity probing.
+  // A packet is a connectivity probing if it is a padded ping packet with self
+  // and/or peer address changes.
+  bool IsCurrentPacketConnectivityProbing() const;
+
+  // Return true iff the writer is blocked, if blocked, call
+  // visitor_->OnWriteBlocked() to add the connection into the write blocked
+  // list.
+  bool HandleWriteBlocked();
+
+  // Whether connection enforces anti-amplification limit.
+  bool EnforceAntiAmplificationLimit() const;
+
+  void AddBytesReceivedBeforeAddressValidation(size_t length) {
+    default_path_.bytes_received_before_address_validation += length;
+  }
+
+  void set_validate_client_addresses(bool value) {
+    validate_client_addresses_ = value;
+  }
+
+ private:
+  friend class test::QuicConnectionPeer;
+
+  struct QUIC_EXPORT_PRIVATE PendingPathChallenge {
+    QuicPathFrameBuffer received_path_challenge;
+    QuicSocketAddress peer_address;
+  };
+
+  struct QUIC_EXPORT_PRIVATE PathState {
+    PathState() = default;
+
+    PathState(const QuicSocketAddress& alternative_self_address,
+              const QuicSocketAddress& alternative_peer_address,
+              const QuicConnectionId& client_connection_id,
+              const QuicConnectionId& server_connection_id,
+              absl::optional<StatelessResetToken> stateless_reset_token)
+        : self_address(alternative_self_address),
+          peer_address(alternative_peer_address),
+          client_connection_id(client_connection_id),
+          server_connection_id(server_connection_id),
+          stateless_reset_token(stateless_reset_token) {}
+
+    PathState(PathState&& other);
+
+    PathState& operator=(PathState&& other);
+
+    // Reset all the members.
+    void Clear();
+
+    QuicSocketAddress self_address;
+    // The actual peer address behind the proxy if there is any.
+    QuicSocketAddress peer_address;
+    QuicConnectionId client_connection_id;
+    QuicConnectionId server_connection_id;
+    absl::optional<StatelessResetToken> stateless_reset_token;
+    // True if the peer address has been validated. Address is considered
+    // validated when 1) an address token of the peer address is received and
+    // validated, or 2) a HANDSHAKE packet has been successfully processed on
+    // this path, or 3) a path validation on this path has succeeded.
+    bool validated = false;
+    // Used by the sever to apply anti-amplification limit after this path
+    // becomes the default path if |peer_address| hasn't been validated.
+    QuicByteCount bytes_received_before_address_validation = 0;
+    QuicByteCount bytes_sent_before_address_validation = 0;
+    // Points to the send algorithm on the old default path while connection is
+    // validating migrated peer address. Nullptr otherwise.
+    std::unique_ptr<SendAlgorithmInterface> send_algorithm;
+    absl::optional<RttStats> rtt_stats;
+  };
+
+  using QueuedPacketList = std::list<SerializedPacket>;
+
+  // BufferedPacket stores necessary information (encrypted buffer and self/peer
+  // addresses) of those packets which are serialized but failed to send because
+  // socket is blocked. From unacked packet map and send algorithm's
+  // perspective, buffered packets are treated as sent.
+  struct QUIC_EXPORT_PRIVATE BufferedPacket {
+    BufferedPacket(const SerializedPacket& packet,
+                   const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address);
+    BufferedPacket(char* encrypted_buffer,
+                   QuicPacketLength encrypted_length,
+                   const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address);
+    BufferedPacket(const BufferedPacket& other) = delete;
+    BufferedPacket(const BufferedPacket&& other) = delete;
+
+    ~BufferedPacket();
+
+    // encrypted_buffer is owned by buffered packet.
+    absl::string_view encrypted_buffer;
+    // Self and peer addresses when the packet is serialized.
+    const QuicSocketAddress self_address;
+    const QuicSocketAddress peer_address;
+  };
+
+  // ReceivedPacketInfo comprises the received packet information, which can be
+  // retrieved before the packet gets successfully decrypted.
+  struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
+    explicit ReceivedPacketInfo(QuicTime receipt_time)
+        : received_bytes_counted(false), receipt_time(receipt_time) {}
+    ReceivedPacketInfo(const QuicSocketAddress& destination_address,
+                       const QuicSocketAddress& source_address,
+                       QuicTime receipt_time)
+        : received_bytes_counted(false),
+          destination_address(destination_address),
+          source_address(source_address),
+          receipt_time(receipt_time) {}
+
+    bool received_bytes_counted;
+    QuicSocketAddress destination_address;
+    QuicSocketAddress source_address;
+    QuicTime receipt_time;
+  };
+
+  // UndecrytablePacket comprises a undecryptable packet and related
+  // information.
+  struct QUIC_EXPORT_PRIVATE UndecryptablePacket {
+    UndecryptablePacket(const QuicEncryptedPacket& packet,
+                        EncryptionLevel encryption_level,
+                        const ReceivedPacketInfo& packet_info)
+        : packet(packet.Clone()),
+          encryption_level(encryption_level),
+          packet_info(packet_info) {}
+
+    std::unique_ptr<QuicEncryptedPacket> packet;
+    EncryptionLevel encryption_level;
+    ReceivedPacketInfo packet_info;
+  };
+
+  // Handles the reverse path validation result depending on connection state:
+  // whether the connection is validating a migrated peer address or is
+  // validating an alternative path.
+  class ReversePathValidationResultDelegate
+      : public QuicPathValidator::ResultDelegate {
+   public:
+    ReversePathValidationResultDelegate(
+        QuicConnection* connection,
+        const QuicSocketAddress& direct_peer_address);
+
+    void OnPathValidationSuccess(
+        std::unique_ptr<QuicPathValidationContext> context) override;
+
+    void OnPathValidationFailure(
+        std::unique_ptr<QuicPathValidationContext> context) override;
+
+   private:
+    QuicConnection* connection_;
+    QuicSocketAddress original_direct_peer_address_;
+    // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
+    // fixed.
+    QuicSocketAddress peer_address_default_path_;
+    QuicSocketAddress peer_address_alternative_path_;
+    AddressChangeType active_effective_peer_migration_type_;
+  };
+
+  // A class which sets and clears in_on_retransmission_time_out_ when entering
+  // and exiting OnRetransmissionTimeout, respectively.
+  class QUIC_EXPORT_PRIVATE ScopedRetransmissionTimeoutIndicator {
+   public:
+    // |connection| must outlive this indicator.
+    explicit ScopedRetransmissionTimeoutIndicator(QuicConnection* connection);
+
+    ~ScopedRetransmissionTimeoutIndicator();
+
+   private:
+    QuicConnection* connection_;  // Not owned.
+  };
+
+  // If peer uses non-empty connection ID, discards any buffered packets on path
+  // change in IETF QUIC.
+  void MaybeClearQueuedPacketsOnPathChange();
+
+  // Notifies the visitor of the close and marks the connection as disconnected.
+  // Does not send a connection close frame to the peer. It should only be
+  // called by CloseConnection or OnConnectionCloseFrame, OnPublicResetPacket,
+  // and OnAuthenticatedIetfStatelessResetPacket.
+  // |ietf_error| may optionally be be used to directly specify the wire
+  // error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
+  // QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
+  void TearDownLocalConnectionState(QuicErrorCode error,
+                                    QuicIetfTransportErrorCodes ietf_error,
+                                    const std::string& details,
+                                    ConnectionCloseSource source);
+  void TearDownLocalConnectionState(const QuicConnectionCloseFrame& frame,
+                                    ConnectionCloseSource source);
+
+  // Replace server connection ID on the client side from retry packet or
+  // initial packets with a different source connection ID.
+  void ReplaceInitialServerConnectionId(
+      const QuicConnectionId& new_server_connection_id);
+
+  // Given the server_connection_id find if there is already a corresponding
+  // client connection ID used on default/alternative path. If not, find if
+  // there is an unused connection ID.
+  void FindMatchingOrNewClientConnectionIdOrToken(
+      const PathState& default_path, const PathState& alternative_path,
+      const QuicConnectionId& server_connection_id,
+      QuicConnectionId* client_connection_id,
+      absl::optional<StatelessResetToken>* stateless_reset_token);
+
+  // Returns true and sets connection IDs if (self_address, peer_address)
+  // corresponds to either the default path or alternative path. Returns false
+  // otherwise.
+  bool FindOnPathConnectionIds(const QuicSocketAddress& self_address,
+                               const QuicSocketAddress& peer_address,
+                               QuicConnectionId* client_connection_id,
+                               QuicConnectionId* server_connection_id) const;
+
+  // Set default_path_ to the new_path_state and update the connection IDs in
+  // packet creator accordingly.
+  void SetDefaultPathState(PathState new_path_state);
+
+  // Returns true if header contains valid server connection ID.
+  bool ValidateServerConnectionId(const QuicPacketHeader& header) const;
+
+  // Update the connection IDs when client migrates with/without validation.
+  // Returns false if required connection ID is not available.
+  bool UpdateConnectionIdsOnClientMigration(
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address);
+
+  // Retire active peer issued connection IDs after they are no longer used on
+  // any path.
+  void RetirePeerIssuedConnectionIdsNoLongerOnPath();
+
+  // When path validation fails, proactively retire peer issued connection IDs
+  // no longer used on any path.
+  void RetirePeerIssuedConnectionIdsOnPathValidationFailure();
+
+  // Writes the given packet to socket, encrypted with packet's
+  // encryption_level. Returns true on successful write, and false if the writer
+  // was blocked and the write needs to be tried again. Notifies the
+  // SentPacketManager when the write is successful and sets
+  // retransmittable frames to nullptr.
+  // Saves the connection close packet for later transmission, even if the
+  // writer is write blocked.
+  bool WritePacket(SerializedPacket* packet);
+
+  // Enforce AEAD Confidentiality limits by iniating key update or closing
+  // connection if too many packets have been encrypted with the current key.
+  // Returns true if the connection was closed. Should not be called for
+  // termination packets.
+  bool MaybeHandleAeadConfidentialityLimits(const SerializedPacket& packet);
+
+  // Flush packets buffered in the writer, if any.
+  void FlushPackets();
+
+  // Make sure a stop waiting we got from our peer is sane.
+  // Returns nullptr if the frame is valid or an error string if it was invalid.
+  const char* ValidateStopWaitingFrame(
+      const QuicStopWaitingFrame& stop_waiting);
+
+  // Sends a version negotiation packet to the peer.
+  void SendVersionNegotiationPacket(bool ietf_quic, bool has_length_prefix);
+
+  // Clears any accumulated frames from the last received packet.
+  void ClearLastFrames();
+
+  // Deletes and clears any queued packets.
+  void ClearQueuedPackets();
+
+  // Closes the connection if the sent packet manager is tracking too many
+  // outstanding packets.
+  void CloseIfTooManyOutstandingSentPackets();
+
+  // Writes as many queued packets as possible.  The connection must not be
+  // blocked when this is called.
+  void WriteQueuedPackets();
+
+  // Queues |packet| in the hopes that it can be decrypted in the
+  // future, when a new key is installed.
+  void QueueUndecryptablePacket(const QuicEncryptedPacket& packet,
+                                EncryptionLevel decryption_level);
+
+  // Sends any packets which are a response to the last packet, including both
+  // acks and pending writes if an ack opened the congestion window.
+  void MaybeSendInResponseToPacket();
+
+  // Gets the least unacked packet number, which is the next packet number to be
+  // sent if there are no outstanding packets.
+  QuicPacketNumber GetLeastUnacked() const;
+
+  // Sets the ping alarm to the appropriate value, if any.
+  void SetPingAlarm();
+
+  // Sets the retransmission alarm based on SentPacketManager.
+  void SetRetransmissionAlarm();
+
+  // Sets the MTU discovery alarm if necessary.
+  // |sent_packet_number| is the recently sent packet number.
+  void MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number);
+
+  HasRetransmittableData IsRetransmittable(const SerializedPacket& packet);
+  bool IsTerminationPacket(const SerializedPacket& packet,
+                           QuicErrorCode* error_code);
+
+  // Set the size of the packet we are targeting while doing path MTU discovery.
+  void SetMtuDiscoveryTarget(QuicByteCount target);
+
+  // Returns |suggested_max_packet_size| clamped to any limits set by the
+  // underlying writer, connection, or protocol.
+  QuicByteCount GetLimitedMaxPacketSize(
+      QuicByteCount suggested_max_packet_size);
+
+  // Do any work which logically would be done in OnPacket but can not be
+  // safely done until the packet is validated. Returns true if packet can be
+  // handled, false otherwise.
+  bool ProcessValidatedPacket(const QuicPacketHeader& header);
+
+  // Returns true if received |packet_number| can be processed. Please note,
+  // this is called after packet got decrypted successfully.
+  bool ValidateReceivedPacketNumber(QuicPacketNumber packet_number);
+
+  // Consider receiving crypto frame on non crypto stream as memory corruption.
+  bool MaybeConsiderAsMemoryCorruption(const QuicStreamFrame& frame);
+
+  // Check if the connection has no outstanding data to send and notify
+  // congestion controller if it is the case.
+  void CheckIfApplicationLimited();
+
+  // Sets |current_packet_content_| to |type| if applicable. And
+  // starts effective peer migration if current packet is confirmed not a
+  // connectivity probe and |current_effective_peer_migration_type_| indicates
+  // effective peer address change.
+  // Returns true if connection is still alive.
+  ABSL_MUST_USE_RESULT bool UpdatePacketContent(QuicFrameType type);
+
+  // Called when last received ack frame has been processed.
+  // |send_stop_waiting| indicates whether a stop waiting needs to be sent.
+  // |acked_new_packet| is true if a previously-unacked packet was acked.
+  void PostProcessAfterAckFrame(bool send_stop_waiting, bool acked_new_packet);
+
+  // Updates the release time into the future.
+  void UpdateReleaseTimeIntoFuture();
+
+  // Sends generic path probe packet to the peer. If we are not IETF QUIC, will
+  // always send a padded ping, regardless of whether this is a request or not.
+  bool SendGenericPathProbePacket(QuicPacketWriter* probing_writer,
+                                  const QuicSocketAddress& peer_address);
+
+  // Called when an ACK is about to send. Resets ACK related internal states,
+  // e.g., cancels ack_alarm_, resets
+  // num_retransmittable_packets_received_since_last_ack_sent_ etc.
+  void ResetAckStates();
+
+  // Returns true if the ACK frame should be bundled with ACK-eliciting frame.
+  bool ShouldBundleRetransmittableFrameWithAck() const;
+
+  void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting);
+
+  // Enables multiple packet number spaces support based on handshake protocol
+  // and flags.
+  void MaybeEnableMultiplePacketNumberSpacesSupport();
+
+  // Called to update ACK timeout when an retransmittable frame has been parsed.
+  void MaybeUpdateAckTimeout();
+
+  // Tries to fill coalesced packet with data of higher packet space.
+  void MaybeCoalescePacketOfHigherSpace();
+
+  // Serialize and send coalesced_packet. Returns false if serialization fails
+  // or the write causes errors, otherwise, returns true.
+  bool FlushCoalescedPacket();
+
+  // Returns the encryption level the connection close packet should be sent at,
+  // which is the highest encryption level that peer can guarantee to process.
+  EncryptionLevel GetConnectionCloseEncryptionLevel() const;
+
+  // Called after an ACK frame is successfully processed to update largest
+  // received packet number which contains an ACK frame.
+  void SetLargestReceivedPacketWithAck(QuicPacketNumber new_value);
+
+  // Called when new packets have been acknowledged or old keys have been
+  // discarded.
+  void OnForwardProgressMade();
+
+  // Returns largest received packet number which contains an ACK frame.
+  QuicPacketNumber GetLargestReceivedPacketWithAck() const;
+
+  // Returns the largest packet number that has been sent.
+  QuicPacketNumber GetLargestSentPacket() const;
+
+  // Returns the largest sent packet number that has been ACKed by peer.
+  QuicPacketNumber GetLargestAckedPacket() const;
+
+  // Whether connection is limited by amplification factor.
+  bool LimitedByAmplificationFactor() const;
+
+  // Called before sending a packet to get packet send time and to set the
+  // release time delay in |per_packet_options_|. Return the time when the
+  // packet is scheduled to be released(a.k.a send time), which is NOW + delay.
+  // Returns Now() and does not update release time delay if
+  // |supports_release_time_| is false.
+  QuicTime CalculatePacketSentTime();
+
+  // If we have a previously validate MTU value, e.g. due to a write error,
+  // revert to it and disable MTU discovery.
+  // Return true iff we reverted to a previously validate MTU.
+  bool MaybeRevertToPreviousMtu();
+
+  QuicTime GetPathMtuReductionDeadline() const;
+
+  // Returns path degrading deadline. QuicTime::Zero() means no path degrading
+  // detection is needed.
+  QuicTime GetPathDegradingDeadline() const;
+
+  // Returns true if path degrading should be detected.
+  bool ShouldDetectPathDegrading() const;
+
+  // Returns network blackhole deadline. QuicTime::Zero() means no blackhole
+  // detection is needed.
+  QuicTime GetNetworkBlackholeDeadline() const;
+
+  // Returns true if network blackhole should be detected.
+  bool ShouldDetectBlackhole() const;
+
+  // Returns retransmission deadline.
+  QuicTime GetRetransmissionDeadline() const;
+
+  // Validate connection IDs used during the handshake. Closes the connection
+  // on validation failure.
+  bool ValidateConfigConnectionIds(const QuicConfig& config);
+
+  // Called when ACK alarm goes off. Try to bundle crypto data with ACKs.
+  void MaybeBundleCryptoDataWithAcks();
+
+  // Returns true if an undecryptable packet of |decryption_level| should be
+  // buffered (such that connection can try to decrypt it later).
+  bool ShouldEnqueueUnDecryptablePacket(EncryptionLevel decryption_level,
+                                        bool has_decryption_key) const;
+
+  // Returns string which contains undecryptable packets information.
+  std::string UndecryptablePacketsInfo() const;
+
+  // Sets the max packet length on the packet creator if needed.
+  void MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+
+  // Sets internal state to enable or disable Legacy Version Encapsulation.
+  void MaybeActivateLegacyVersionEncapsulation();
+  void MaybeDisactivateLegacyVersionEncapsulation();
+
+  // For Google Quic, if the current packet is connectivity probing packet, call
+  // session OnPacketReceived() which eventually sends connectivity probing
+  // response on server side. And no-op on client side. And for both Google Quic
+  // and IETF Quic, start migration if the current packet is a non-probing
+  // packet.
+  // TODO(danzh) rename to MaybeRespondToPeerMigration() when Google Quic is
+  // deprecated.
+  void MaybeRespondToConnectivityProbingOrMigration();
+
+  // Called in IETF QUIC. Start peer migration if a non-probing frame is
+  // received and the current packet number is largest received so far.
+  void MaybeStartIetfPeerMigration();
+
+  // Send PATH_RESPONSE to the given peer address.
+  bool SendPathResponse(const QuicPathFrameBuffer& data_buffer,
+                        const QuicSocketAddress& peer_address_to_send,
+                        const QuicSocketAddress& effective_peer_address);
+
+  // Update both connection's and packet creator's peer address.
+  void UpdatePeerAddress(QuicSocketAddress peer_address);
+
+  // Send PING at encryption level.
+  void SendPingAtLevel(EncryptionLevel level);
+
+  // Write the given packet with |self_address| and |peer_address| using
+  // |writer|.
+  bool WritePacketUsingWriter(std::unique_ptr<SerializedPacket> packet,
+                              QuicPacketWriter* writer,
+                              const QuicSocketAddress& self_address,
+                              const QuicSocketAddress& peer_address,
+                              bool measure_rtt);
+
+  // Increment bytes sent/received on the alternative path if the current packet
+  // is sent/received on that path.
+  void MaybeUpdateBytesSentToAlternativeAddress(
+      const QuicSocketAddress& peer_address,
+      QuicByteCount sent_packet_size);
+  void MaybeUpdateBytesReceivedFromAlternativeAddress(
+      QuicByteCount received_packet_size);
+
+  // TODO(danzh) pass in PathState of the incoming packet or the packet sent
+  // once PathState is used in packet creator. Return true if the given self
+  // address and peer address is the same as the self address and peer address
+  // of the default path.
+  bool IsDefaultPath(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address) const;
+
+  // Return true if the |self_address| and |peer_address| is the same as the
+  // self address and peer address of the alternative path.
+  bool IsAlternativePath(const QuicSocketAddress& self_address,
+                         const QuicSocketAddress& peer_address) const;
+
+  // Restore connection default path and congestion control state to the last
+  // validated path and its state. Called after fail to validate peer address
+  // upon detecting a peer migration.
+  void RestoreToLastValidatedPath(
+      QuicSocketAddress original_direct_peer_address);
+
+  // Return true if the current incoming packet is from a peer address that is
+  // validated.
+  bool IsReceivedPeerAddressValidated() const;
+
+  // Called after receiving PATH_CHALLENGE. Update packet content and
+  // alternative path state if the current packet is from a non-default path.
+  // Return true if framer should continue processing the packet.
+  bool OnPathChallengeFrameInternal(const QuicPathChallengeFrame& frame);
+
+  virtual std::unique_ptr<QuicSelfIssuedConnectionIdManager>
+  MakeSelfIssuedConnectionIdManager();
+
+  // Called on peer IP change or restoring to previous address to reset
+  // congestion window, RTT stats, retransmission timer, etc. Only used in IETF
+  // QUIC.
+  std::unique_ptr<SendAlgorithmInterface> OnPeerIpAddressChanged();
+
+  // Process NewConnectionIdFrame either sent from peer or synsthesized from
+  // preferred_address transport parameter.
+  bool OnNewConnectionIdFrameInner(const QuicNewConnectionIdFrame& frame);
+
+  // Called to patch missing client connection ID on default/alternative paths
+  // when a new client connection ID is received.
+  void OnClientConnectionIdAvailable();
+
+  // Returns true if connection needs to set retransmission alarm after a packet
+  // gets sent.
+  bool ShouldSetRetransmissionAlarmOnPacketSent(bool in_flight,
+                                                EncryptionLevel level) const;
+
+  QuicConnectionContext context_;
+
+  QuicFramer framer_;
+
+  // Contents received in the current packet, especially used to identify
+  // whether the current packet is a padded PING packet.
+  PacketContent current_packet_content_;
+  // Set to true as soon as the packet currently being processed has been
+  // detected as a connectivity probing.
+  // Always false outside the context of ProcessUdpPacket().
+  bool is_current_packet_connectivity_probing_;
+
+  bool has_path_challenge_in_current_packet_;
+
+  // Caches the current effective peer migration type if a effective peer
+  // migration might be initiated. As soon as the current packet is confirmed
+  // not a connectivity probe, effective peer migration will start.
+  AddressChangeType current_effective_peer_migration_type_;
+  QuicConnectionHelperInterface* helper_;  // Not owned.
+  QuicAlarmFactory* alarm_factory_;        // Not owned.
+  PerPacketOptions* per_packet_options_;   // Not owned.
+  QuicPacketWriter* writer_;  // Owned or not depending on |owns_writer_|.
+  bool owns_writer_;
+  // Encryption level for new packets. Should only be changed via
+  // SetDefaultEncryptionLevel().
+  EncryptionLevel encryption_level_;
+  const QuicClock* clock_;
+  QuicRandom* random_generator_;
+
+  // On the server, the connection ID is set when receiving the first packet.
+  // This variable ensures we only set it this way once.
+  bool client_connection_id_is_set_;
+
+  // Whether we've already replaced our server connection ID due to receiving an
+  // INITIAL packet with a different source connection ID. Only used on client.
+  bool server_connection_id_replaced_by_initial_ = false;
+  // Address on the last successfully processed packet received from the
+  // direct peer.
+
+  // Other than initialization, do not modify it directly, use
+  // UpdatePeerAddress() instead.
+  QuicSocketAddress direct_peer_address_;
+  // The default path on which the endpoint sends non-probing packets.
+  // The send algorithm and RTT stats of this path are stored in
+  // |sent_packet_manager_| instead of in this object.
+  PathState default_path_;
+
+  // Records change type when the effective peer initiates migration to a new
+  // address. Reset to NO_CHANGE after effective peer migration is validated.
+  AddressChangeType active_effective_peer_migration_type_;
+
+  // Records highest sent packet number when effective peer migration is
+  // started.
+  QuicPacketNumber highest_packet_sent_before_effective_peer_migration_;
+
+  // True if Key Update is supported on this connection.
+  bool support_key_update_for_connection_;
+
+  // Tracks the lowest packet sent in the current key phase. Will be
+  // uninitialized before the first one-RTT packet has been sent or after a
+  // key update but before the first packet has been sent.
+  QuicPacketNumber lowest_packet_sent_in_current_key_phase_;
+
+  // True if the last packet has gotten far enough in the framer to be
+  // decrypted.
+  bool last_packet_decrypted_;
+  QuicByteCount last_size_;  // Size of the last received packet.
+  // TODO(rch): remove this when b/27221014 is fixed.
+  const char* current_packet_data_;  // UDP payload of packet currently being
+                                     // parsed or nullptr.
+  EncryptionLevel last_decrypted_packet_level_;
+  QuicPacketHeader last_header_;
+  bool should_last_packet_instigate_acks_;
+
+  // Track some peer state so we can do less bookkeeping
+  // Largest sequence sent by the peer which had an ack frame (latest ack info).
+  // Do not read or write directly, use GetLargestReceivedPacketWithAck() and
+  // SetLargestReceivedPacketWithAck() instead.
+  QuicPacketNumber largest_seen_packet_with_ack_;
+  // Largest packet number sent by the peer which had an ACK frame per packet
+  // number space. Only used when this connection supports multiple packet
+  // number spaces.
+  QuicPacketNumber largest_seen_packets_with_ack_[NUM_PACKET_NUMBER_SPACES];
+
+  // Largest packet number sent by the peer which had a stop waiting frame.
+  QuicPacketNumber largest_seen_packet_with_stop_waiting_;
+
+  // Collection of packets which were received before encryption was
+  // established, but which could not be decrypted.  We buffer these on
+  // the assumption that they could not be processed because they were
+  // sent with the INITIAL encryption and the CHLO message was lost.
+  std::deque<UndecryptablePacket> undecryptable_packets_;
+
+  // Collection of coalesced packets which were received while processing
+  // the current packet.
+  quiche::QuicheCircularDeque<std::unique_ptr<QuicEncryptedPacket>>
+      received_coalesced_packets_;
+
+  // Maximum number of undecryptable packets the connection will store.
+  size_t max_undecryptable_packets_;
+
+  // Maximum number of tracked packets.
+  QuicPacketCount max_tracked_packets_;
+
+  // Contains the connection close packets if the connection has been closed.
+  std::unique_ptr<std::vector<std::unique_ptr<QuicEncryptedPacket>>>
+      termination_packets_;
+
+  // Determines whether or not a connection close packet is sent to the peer
+  // after idle timeout due to lack of network activity. During the handshake,
+  // a connection close packet is sent, but not after.
+  ConnectionCloseBehavior idle_timeout_connection_close_behavior_;
+
+  // When > 0, close the QUIC connection after this number of RTOs.
+  size_t num_rtos_for_blackhole_detection_;
+
+  // Statistics for this session.
+  QuicConnectionStats stats_;
+
+  UberReceivedPacketManager uber_received_packet_manager_;
+
+  // Indicates how many consecutive times an ack has arrived which indicates
+  // the peer needs to stop waiting for some packets.
+  // TODO(fayang): remove this when deprecating Q043.
+  int stop_waiting_count_;
+
+  // Indicates the retransmission alarm needs to be set.
+  bool pending_retransmission_alarm_;
+
+  // If true, defer sending data in response to received packets to the
+  // SendAlarm.
+  bool defer_send_in_response_to_packets_;
+
+  // The timeout for PING.
+  QuicTime::Delta ping_timeout_;
+
+  // Initial timeout for how long the wire can have no retransmittable packets.
+  QuicTime::Delta initial_retransmittable_on_wire_timeout_;
+
+  // Indicates how many retransmittable-on-wire pings have been emitted without
+  // receiving any new data in between.
+  int consecutive_retransmittable_on_wire_ping_count_;
+
+  // Indicates how many retransmittable-on-wire pings have been emitted.
+  int retransmittable_on_wire_ping_count_;
+
+  // Arena to store class implementations within the QuicConnection.
+  QuicConnectionArena arena_;
+
+  // An alarm that fires when an ACK should be sent to the peer.
+  QuicArenaScopedPtr<QuicAlarm> ack_alarm_;
+  // An alarm that fires when a packet needs to be retransmitted.
+  QuicArenaScopedPtr<QuicAlarm> retransmission_alarm_;
+  // An alarm that is scheduled when the SentPacketManager requires a delay
+  // before sending packets and fires when the packet may be sent.
+  QuicArenaScopedPtr<QuicAlarm> send_alarm_;
+  // An alarm that fires when a ping should be sent.
+  QuicArenaScopedPtr<QuicAlarm> ping_alarm_;
+  // An alarm that fires when an MTU probe should be sent.
+  QuicArenaScopedPtr<QuicAlarm> mtu_discovery_alarm_;
+  // An alarm that fires to process undecryptable packets when new decyrption
+  // keys are available.
+  QuicArenaScopedPtr<QuicAlarm> process_undecryptable_packets_alarm_;
+  // An alarm that fires to discard keys for the previous key phase some time
+  // after a key update has completed.
+  QuicArenaScopedPtr<QuicAlarm> discard_previous_one_rtt_keys_alarm_;
+  // An alarm that fires to discard 0-RTT decryption keys some time after the
+  // first 1-RTT packet has been decrypted. Only used on server connections with
+  // TLS handshaker.
+  QuicArenaScopedPtr<QuicAlarm> discard_zero_rtt_decryption_keys_alarm_;
+  // Neither visitor is owned by this class.
+  QuicConnectionVisitorInterface* visitor_;
+  QuicConnectionDebugVisitor* debug_visitor_;
+
+  QuicPacketCreator packet_creator_;
+
+  // Information about the last received QUIC packet, which may not have been
+  // successfully decrypted and processed.
+  ReceivedPacketInfo last_received_packet_info_;
+
+  // Sent packet manager which tracks the status of packets sent by this
+  // connection and contains the send and receive algorithms to determine when
+  // to send packets.
+  QuicSentPacketManager sent_packet_manager_;
+
+  // Indicates whether connection version has been negotiated.
+  // Always true for server connections.
+  bool version_negotiated_;
+
+  // Tracks if the connection was created by the server or the client.
+  Perspective perspective_;
+
+  // True by default.  False if we've received or sent an explicit connection
+  // close.
+  bool connected_;
+
+  // Destination connection ID of the last received packet. If this ID is the
+  // original server connection ID chosen by client and server replaces it with
+  // a different ID, last_packet_destination_connection_id_ is set to the
+  // replacement connection ID on the server side.
+  QuicConnectionId last_packet_destination_connection_id_;
+
+  // Set to false if the connection should not send truncated connection IDs to
+  // the peer, even if the peer supports it.
+  bool can_truncate_connection_ids_;
+
+  // If non-empty this contains the set of versions received in a
+  // version negotiation packet.
+  ParsedQuicVersionVector server_supported_versions_;
+
+  // The number of MTU probes already sent.
+  size_t mtu_probe_count_;
+
+  // The value of |long_term_mtu_| prior to the last successful MTU increase.
+  // 0 means either
+  // - MTU discovery has never been enabled, or
+  // - MTU discovery has been enabled, but the connection got a packet write
+  //   error with a new (successfully probed) MTU, so it reverted
+  //   |long_term_mtu_| to the value before the last increase.
+  QuicPacketLength previous_validated_mtu_;
+  // The value of the MTU regularly used by the connection. This is different
+  // from the value returned by max_packet_size(), as max_packet_size() returns
+  // the value of the MTU as currently used by the serializer, so if
+  // serialization of an MTU probe is in progress, those two values will be
+  // different.
+  QuicByteCount long_term_mtu_;
+
+  // The maximum UDP payload size that our peer has advertised support for.
+  // Defaults to kDefaultMaxPacketSizeTransportParam until received from peer.
+  QuicByteCount peer_max_packet_size_;
+
+  // The size of the largest packet received from peer.
+  QuicByteCount largest_received_packet_size_;
+
+  // Indicates whether a write error is encountered currently. This is used to
+  // avoid infinite write errors.
+  bool write_error_occurred_;
+
+  // Indicates not to send or process stop waiting frames.
+  bool no_stop_waiting_frames_;
+
+  // Consecutive number of sent packets which have no retransmittable frames.
+  size_t consecutive_num_packets_with_no_retransmittable_frames_;
+
+  // After this many packets sent without retransmittable frames, an artificial
+  // retransmittable frame(a WINDOW_UPDATE) will be created to solicit an ack
+  // from the peer. Default to kMaxConsecutiveNonRetransmittablePackets.
+  size_t max_consecutive_num_packets_with_no_retransmittable_frames_;
+
+  // If true, bundle an ack-eliciting frame with an ACK if the PTO or RTO alarm
+  // have previously fired.
+  bool bundle_retransmittable_with_pto_ack_;
+
+  // If true, the connection will fill up the pipe with extra data whenever the
+  // congestion controller needs it in order to make a bandwidth estimate.  This
+  // is useful if the application pesistently underutilizes the link, but still
+  // relies on having a reasonable bandwidth estimate from the connection, e.g.
+  // for real time applications.
+  bool fill_up_link_during_probing_;
+
+  // If true, the probing retransmission will not be started again.  This is
+  // used to safeguard against an accidental tail recursion in probing
+  // retransmission code.
+  bool probing_retransmission_pending_;
+
+  // Id of latest sent control frame. 0 if no control frame has been sent.
+  QuicControlFrameId last_control_frame_id_;
+
+  // True if the peer is unreachable on the current path.
+  bool is_path_degrading_;
+
+  // True if an ack frame is being processed.
+  bool processing_ack_frame_;
+
+  // True if the writer supports release timestamp.
+  bool supports_release_time_;
+
+  std::unique_ptr<QuicPeerIssuedConnectionIdManager> peer_issued_cid_manager_;
+  std::unique_ptr<QuicSelfIssuedConnectionIdManager> self_issued_cid_manager_;
+
+  // Time this connection can release packets into the future.
+  QuicTime::Delta release_time_into_future_;
+
+  // Payload of most recently transmitted IETF QUIC connectivity
+  // probe packet (the PATH_CHALLENGE payload). This implementation transmits
+  // only one PATH_CHALLENGE per connectivity probe, so only one
+  // QuicPathFrameBuffer is needed.
+  std::unique_ptr<QuicPathFrameBuffer> transmitted_connectivity_probe_payload_;
+
+  // Payloads that were received in the most recent probe. This needs to be a
+  // Deque because the peer might no be using this implementation, and others
+  // might send a packet with more than one PATH_CHALLENGE, so all need to be
+  // saved and responded to.
+  // TODO(danzh) deprecate this field when deprecating
+  // --quic_send_path_response.
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer>
+      received_path_challenge_payloads_;
+
+  // When we receive a RETRY packet or some INITIAL packets, we replace
+  // |server_connection_id_| with the value from that packet and save off the
+  // original value of |server_connection_id_| into
+  // |original_destination_connection_id_| for validation.
+  absl::optional<QuicConnectionId> original_destination_connection_id_;
+
+  // The connection ID that replaces original_destination_connection_id_.
+  QuicConnectionId original_destination_connection_id_replacement_;
+
+  // After we receive a RETRY packet, |retry_source_connection_id_| contains
+  // the source connection ID from that packet.
+  absl::optional<QuicConnectionId> retry_source_connection_id_;
+
+  // Used to store content of packets which cannot be sent because of write
+  // blocked. Packets' encrypted buffers are copied and owned by
+  // buffered_packets_. From unacked_packet_map (and congestion control)'s
+  // perspective, those packets are considered sent.
+  std::list<BufferedPacket> buffered_packets_;
+
+  // Used to coalesce packets of different encryption level into the same UDP
+  // datagram. Connection stops trying to coalesce packets if a forward secure
+  // packet gets acknowledged.
+  QuicCoalescedPacket coalesced_packet_;
+
+  QuicConnectionMtuDiscoverer mtu_discoverer_;
+
+  QuicNetworkBlackholeDetector blackhole_detector_;
+
+  QuicIdleNetworkDetector idle_network_detector_;
+
+  bool blackhole_detection_disabled_ = false;
+
+  const bool default_enable_5rto_blackhole_detection_ =
+      GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2);
+
+  // Whether the Legacy Version Encapsulation feature is enabled.
+  bool legacy_version_encapsulation_enabled_ = false;
+  // Whether we are in the middle of sending a packet using Legacy Version
+  // Encapsulation.
+  bool legacy_version_encapsulation_in_progress_ = false;
+  // SNI to send when using Legacy Version Encapsulation.
+  std::string legacy_version_encapsulation_sni_;
+  // True if next packet is intended to consume remaining space in the
+  // coalescer.
+  bool fill_coalesced_packet_ = false;
+
+  size_t anti_amplification_factor_ =
+      GetQuicFlag(FLAGS_quic_anti_amplification_factor);
+
+  bool use_path_validator_ =
+      GetQuicReloadableFlag(quic_pass_path_response_to_validator);
+
+  // True if AckFrequencyFrame is supported.
+  bool can_receive_ack_frequency_frame_ = false;
+
+  // Indicate whether coalescing is done.
+  bool coalescing_done_ = false;
+
+  // Indicate whether any ENCRYPTION_HANDSHAKE packet has been sent.
+  bool handshake_packet_sent_ = false;
+
+  // Indicate whether to send an AckFrequencyFrame upon handshake completion.
+  // The AckFrequencyFrame sent will updates client's max_ack_delay, which if
+  // chosen properly can reduce the CPU and bandwidth usage for ACK frames.
+  bool send_ack_frequency_on_handshake_completion_ = false;
+
+  // Indicate whether AckFrequency frame has been sent.
+  bool ack_frequency_sent_ = false;
+
+  // True if a 0-RTT decrypter was or is installed at some point in the
+  // connection's lifetime.
+  bool had_zero_rtt_decrypter_ = false;
+
+  // True after the first 1-RTT packet has successfully decrypted.
+  bool have_decrypted_first_one_rtt_packet_ = false;
+
+  // True if we are currently processing OnRetransmissionTimeout.
+  bool in_on_retransmission_time_out_ = false;
+
+  QuicPathValidator path_validator_;
+
+  // Stores information of a path which maybe used as default path in the
+  // future. On the client side, it gets created when the client starts
+  // validating a new path and gets cleared once it becomes the default path or
+  // the path validation fails or replaced by a newer path of interest. On the
+  // server side, alternative_path gets created when server: 1) receives
+  // PATH_CHALLENGE on non-default path, or 2) switches to a not yet validated
+  // default path such that it needs to store the previous validated default
+  // path.
+  // Note that if alternative_path_ stores a validated path information (case
+  // 2), do not override it on receiving PATH_CHALLENGE (case 1).
+  PathState alternative_path_;
+
+  // This field is used to debug b/177312785.
+  QuicFrameType most_recent_frame_type_;
+
+  bool count_bytes_on_alternative_path_separately_ =
+      GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately);
+
+  // If true, upon seeing a new client address, validate the client address.
+  bool validate_client_addresses_ = false;
+
+  // Indicates whether we should proactively validate peer address on a
+  // PATH_CHALLENGE received.
+  bool should_proactively_validate_peer_address_on_path_challenge_ = false;
+
+  // Enable this via reloadable flag once this feature is complete.
+  bool connection_migration_use_new_cid_ = false;
+
+  const bool flush_after_coalesce_higher_space_packets_ =
+      GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets);
+
+  // Records the 1-RTT connection close frame sent.
+  // TODO(b/180103273): remove this after the bug gets fixed.
+  absl::optional<QuicConnectionCloseFrame> connection_close_frame_sent_;
+
+  // If true, send connection close packet on INVALID_VERSION.
+  bool send_connection_close_for_invalid_version_ = false;
+
+  // TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
+  // fixed.
+  absl::optional<QuicWallTime> quic_bug_10511_43_timestamp_;
+  std::string quic_bug_10511_43_error_detail_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_H_
diff --git a/quiche/quic/core/quic_connection_context.cc b/quiche/quic/core/quic_connection_context.cc
new file mode 100644
index 0000000..d8dfbac
--- /dev/null
+++ b/quiche/quic/core/quic_connection_context.cc
@@ -0,0 +1,36 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_context.h"
+
+#include "quiche/common/platform/api/quiche_thread_local.h"
+
+namespace quic {
+namespace {
+DEFINE_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, QuicConnectionContext);
+}  // namespace
+
+// static
+QuicConnectionContext* QuicConnectionContext::Current() {
+  return GET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext);
+}
+
+QuicConnectionContextSwitcher::QuicConnectionContextSwitcher(
+    QuicConnectionContext* new_context)
+    : old_context_(QuicConnectionContext::Current()) {
+  SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, new_context);
+  if (new_context && new_context->tracer) {
+    new_context->tracer->Activate();
+  }
+}
+
+QuicConnectionContextSwitcher::~QuicConnectionContextSwitcher() {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->Deactivate();
+  }
+  SET_QUICHE_THREAD_LOCAL_POINTER(CurrentContext, old_context_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_context.h b/quiche/quic/core/quic_connection_context.h
new file mode 100644
index 0000000..192002e
--- /dev/null
+++ b/quiche/quic/core/quic_connection_context.h
@@ -0,0 +1,133 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+// QuicConnectionTracer is responsible for emit trace messages for a single
+// QuicConnection.
+// QuicConnectionTracer is part of the QuicConnectionContext.
+class QUIC_EXPORT_PRIVATE QuicConnectionTracer {
+ public:
+  virtual ~QuicConnectionTracer() = default;
+
+  // Emit a trace message from a string literal. The trace may simply remember
+  // the address of the literal in this function and read it at a later time.
+  virtual void PrintLiteral(const char* literal) = 0;
+
+  // Emit a trace message from a string_view. Unlike PrintLiteral, this function
+  // will not read |s| after it returns.
+  virtual void PrintString(absl::string_view s) = 0;
+
+  // Emit a trace message from printf-style arguments.
+  template <typename... Args>
+  void Printf(const absl::FormatSpec<Args...>& format, const Args&... args) {
+    std::string s = absl::StrFormat(format, args...);
+    PrintString(s);
+  }
+
+ private:
+  friend class QuicConnectionContextSwitcher;
+
+  // Called by QuicConnectionContextSwitcher, when |this| becomes the current
+  // thread's QUIC connection tracer.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Activate() {}
+
+  // Called by QuicConnectionContextSwitcher, when |this| stops from being the
+  // current thread's QUIC connection tracer.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Deactivate() {}
+};
+
+// QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
+// implementation can send the bug information into quic::CurrentBugListener().
+class QUIC_EXPORT_PRIVATE QuicBugListener {
+ public:
+  virtual ~QuicBugListener() = default;
+  virtual void OnQuicBug(const char* bug_id, const char* file, int line,
+                         absl::string_view bug_message) = 0;
+};
+
+// QuicConnectionContext is a per-QuicConnection context that includes
+// facilities useable by any part of a QuicConnection. A QuicConnectionContext
+// is owned by a QuicConnection.
+//
+// The 'top-level' QuicConnection functions are responsible for maintaining the
+// thread-local QuicConnectionContext pointer, such that any function called by
+// them(directly or indirectly) can access the context.
+//
+// Like QuicConnection, all facilities in QuicConnectionContext are assumed to
+// be called from a single thread at a time, they are NOT thread-safe.
+struct QUIC_EXPORT_PRIVATE QuicConnectionContext final {
+  // Get the context on the current executing thread. nullptr if the current
+  // function is not called from a 'top-level' QuicConnection function.
+  static QuicConnectionContext* Current();
+
+  std::unique_ptr<QuicConnectionTracer> tracer;
+  std::unique_ptr<QuicBugListener> bug_listener;
+};
+
+// QuicConnectionContextSwitcher is a RAII object used for maintaining the
+// thread-local QuicConnectionContext pointer.
+class QUIC_EXPORT_PRIVATE QuicConnectionContextSwitcher final {
+ public:
+  // The constructor switches from QuicConnectionContext::Current() to
+  // |new_context|.
+  explicit QuicConnectionContextSwitcher(QuicConnectionContext* new_context);
+
+  // The destructor switches from QuicConnectionContext::Current() back to the
+  // old context.
+  ~QuicConnectionContextSwitcher();
+
+ private:
+  QuicConnectionContext* old_context_;
+};
+
+// Emit a trace message from a string literal to the current tracer(if any).
+inline void QUIC_TRACELITERAL(const char* literal) {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->PrintLiteral(literal);
+  }
+}
+
+// Emit a trace message from a string_view to the current tracer(if any).
+inline void QUIC_TRACESTRING(absl::string_view s) {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->PrintString(s);
+  }
+}
+
+// Emit a trace message from printf-style arguments to the current tracer(if
+// any).
+template <typename... Args>
+void QUIC_TRACEPRINTF(const absl::FormatSpec<Args...>& format,
+                      const Args&... args) {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  if (current && current->tracer) {
+    current->tracer->Printf(format, args...);
+  }
+}
+
+inline QuicBugListener* CurrentBugListener() {
+  QuicConnectionContext* current = QuicConnectionContext::Current();
+  return (current != nullptr) ? current->bug_listener.get() : nullptr;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
diff --git a/quiche/quic/core/quic_connection_context_test.cc b/quiche/quic/core/quic_connection_context_test.cc
new file mode 100644
index 0000000..0b87d01
--- /dev/null
+++ b/quiche/quic/core/quic_connection_context_test.cc
@@ -0,0 +1,173 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_context.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_thread.h"
+
+using testing::ElementsAre;
+
+namespace quic {
+namespace {
+
+class TraceCollector : public QuicConnectionTracer {
+ public:
+  ~TraceCollector() override = default;
+
+  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }
+
+  void PrintString(absl::string_view s) override {
+    trace_.push_back(std::string(s));
+  }
+
+  const std::vector<std::string>& trace() const { return trace_; }
+
+ private:
+  std::vector<std::string> trace_;
+};
+
+struct FakeConnection {
+  FakeConnection() { context.tracer = std::make_unique<TraceCollector>(); }
+
+  const std::vector<std::string>& trace() const {
+    return static_cast<const TraceCollector*>(context.tracer.get())->trace();
+  }
+
+  QuicConnectionContext context;
+};
+
+void SimpleSwitch() {
+  FakeConnection connection;
+
+  // These should be ignored since current context is nullptr.
+  EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
+  QUIC_TRACELITERAL("before switch: literal");
+  QUIC_TRACESTRING(std::string("before switch: string"));
+  QUIC_TRACEPRINTF("%s: %s", "before switch", "printf");
+
+  {
+    QuicConnectionContextSwitcher switcher(&connection.context);
+    QUIC_TRACELITERAL("literal");
+    QUIC_TRACESTRING(std::string("string"));
+    QUIC_TRACEPRINTF("%s", "printf");
+  }
+
+  EXPECT_EQ(QuicConnectionContext::Current(), nullptr);
+  QUIC_TRACELITERAL("after switch: literal");
+  QUIC_TRACESTRING(std::string("after switch: string"));
+  QUIC_TRACEPRINTF("%s: %s", "after switch", "printf");
+
+  EXPECT_THAT(connection.trace(), ElementsAre("literal", "string", "printf"));
+}
+
+void NestedSwitch() {
+  FakeConnection outer, inner;
+
+  {
+    QuicConnectionContextSwitcher switcher(&outer.context);
+    QUIC_TRACELITERAL("outer literal 0");
+    QUIC_TRACESTRING(std::string("outer string 0"));
+    QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 0);
+
+    {
+      QuicConnectionContextSwitcher switcher(&inner.context);
+      QUIC_TRACELITERAL("inner literal");
+      QUIC_TRACESTRING(std::string("inner string"));
+      QUIC_TRACEPRINTF("%s %s", "inner", "printf");
+    }
+
+    QUIC_TRACELITERAL("outer literal 1");
+    QUIC_TRACESTRING(std::string("outer string 1"));
+    QUIC_TRACEPRINTF("%s %s %d", "outer", "printf", 1);
+  }
+
+  EXPECT_THAT(outer.trace(), ElementsAre("outer literal 0", "outer string 0",
+                                         "outer printf 0", "outer literal 1",
+                                         "outer string 1", "outer printf 1"));
+
+  EXPECT_THAT(inner.trace(),
+              ElementsAre("inner literal", "inner string", "inner printf"));
+}
+
+void AlternatingSwitch() {
+  FakeConnection zero, one, two;
+  for (int i = 0; i < 15; ++i) {
+    FakeConnection* connection =
+        ((i % 3) == 0) ? &zero : (((i % 3) == 1) ? &one : &two);
+
+    QuicConnectionContextSwitcher switcher(&connection->context);
+    QUIC_TRACEPRINTF("%d", i);
+  }
+
+  EXPECT_THAT(zero.trace(), ElementsAre("0", "3", "6", "9", "12"));
+  EXPECT_THAT(one.trace(), ElementsAre("1", "4", "7", "10", "13"));
+  EXPECT_THAT(two.trace(), ElementsAre("2", "5", "8", "11", "14"));
+}
+
+typedef void (*ThreadFunction)();
+
+template <ThreadFunction func>
+class TestThread : public QuicThread {
+ public:
+  TestThread() : QuicThread("TestThread") {}
+  ~TestThread() override = default;
+
+ protected:
+  void Run() override { func(); }
+};
+
+template <ThreadFunction func>
+void RunInThreads(size_t n_threads) {
+  using ThreadType = TestThread<func>;
+  std::vector<ThreadType> threads(n_threads);
+
+  for (ThreadType& t : threads) {
+    t.Start();
+  }
+
+  for (ThreadType& t : threads) {
+    t.Join();
+  }
+}
+
+class QuicConnectionContextTest : public QuicTest {
+ protected:
+};
+
+TEST_F(QuicConnectionContextTest, NullTracerOK) {
+  FakeConnection connection;
+  std::unique_ptr<QuicConnectionTracer> tracer;
+
+  {
+    QuicConnectionContextSwitcher switcher(&connection.context);
+    QUIC_TRACELITERAL("msg 1 recorded");
+  }
+
+  connection.context.tracer.swap(tracer);
+
+  {
+    QuicConnectionContextSwitcher switcher(&connection.context);
+    // Should be a no-op since connection.context.tracer is nullptr.
+    QUIC_TRACELITERAL("msg 2 ignored");
+  }
+
+  EXPECT_THAT(static_cast<TraceCollector*>(tracer.get())->trace(),
+              ElementsAre("msg 1 recorded"));
+}
+
+TEST_F(QuicConnectionContextTest, TestSimpleSwitch) {
+  RunInThreads<SimpleSwitch>(10);
+}
+
+TEST_F(QuicConnectionContextTest, TestNestedSwitch) {
+  RunInThreads<NestedSwitch>(10);
+}
+
+TEST_F(QuicConnectionContextTest, TestAlternatingSwitch) {
+  RunInThreads<AlternatingSwitch>(10);
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id.cc b/quiche/quic/core/quic_connection_id.cc
new file mode 100644
index 0000000..3103cf2
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id.cc
@@ -0,0 +1,180 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_id.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iomanip>
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "third_party/boringssl/src/include/openssl/siphash.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+// QuicConnectionIdHasher can be used to generate a stable connection ID hash
+// function that will return the same value for two equal connection IDs for
+// the duration of process lifetime. It is meant to be used as input to data
+// structures that do not outlast process lifetime. A new key is generated once
+// per process to prevent attackers from crafting connection IDs in such a way
+// that they always land in the same hash bucket.
+class QuicConnectionIdHasher {
+ public:
+  inline QuicConnectionIdHasher()
+      : QuicConnectionIdHasher(QuicRandom::GetInstance()) {}
+
+  explicit inline QuicConnectionIdHasher(QuicRandom* random) {
+    random->RandBytes(&sip_hash_key_, sizeof(sip_hash_key_));
+  }
+
+  inline size_t Hash(const char* input, size_t input_len) const {
+    return static_cast<size_t>(SIPHASH_24(
+        sip_hash_key_, reinterpret_cast<const uint8_t*>(input), input_len));
+  }
+
+ private:
+  uint64_t sip_hash_key_[2];
+};
+
+}  // namespace
+
+QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {
+  static_assert(offsetof(QuicConnectionId, padding_) ==
+                    offsetof(QuicConnectionId, length_),
+                "bad offset");
+  static_assert(sizeof(QuicConnectionId) <= 16, "bad size");
+}
+
+QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
+  length_ = length;
+  if (length_ == 0) {
+    return;
+  }
+  if (length_ <= sizeof(data_short_)) {
+    memcpy(data_short_, data, length_);
+    return;
+  }
+  data_long_ = reinterpret_cast<char*>(malloc(length_));
+  QUICHE_CHECK_NE(nullptr, data_long_);
+  memcpy(data_long_, data, length_);
+}
+
+QuicConnectionId::QuicConnectionId(const absl::Span<const uint8_t> data)
+    : QuicConnectionId(reinterpret_cast<const char*>(data.data()),
+                       data.length()) {}
+
+QuicConnectionId::~QuicConnectionId() {
+  if (length_ > sizeof(data_short_)) {
+    free(data_long_);
+    data_long_ = nullptr;
+  }
+}
+
+QuicConnectionId::QuicConnectionId(const QuicConnectionId& other)
+    : QuicConnectionId(other.data(), other.length()) {}
+
+QuicConnectionId& QuicConnectionId::operator=(const QuicConnectionId& other) {
+  set_length(other.length());
+  memcpy(mutable_data(), other.data(), length_);
+  return *this;
+}
+
+const char* QuicConnectionId::data() const {
+  if (length_ <= sizeof(data_short_)) {
+    return data_short_;
+  }
+  return data_long_;
+}
+
+char* QuicConnectionId::mutable_data() {
+  if (length_ <= sizeof(data_short_)) {
+    return data_short_;
+  }
+  return data_long_;
+}
+
+uint8_t QuicConnectionId::length() const { return length_; }
+
+void QuicConnectionId::set_length(uint8_t length) {
+  char temporary_data[sizeof(data_short_)];
+  if (length > sizeof(data_short_)) {
+    if (length_ <= sizeof(data_short_)) {
+      // Copy data from data_short_ to data_long_.
+      memcpy(temporary_data, data_short_, length_);
+      data_long_ = reinterpret_cast<char*>(malloc(length));
+      QUICHE_CHECK_NE(nullptr, data_long_);
+      memcpy(data_long_, temporary_data, length_);
+    } else {
+      // Resize data_long_.
+      char* realloc_result =
+          reinterpret_cast<char*>(realloc(data_long_, length));
+      QUICHE_CHECK_NE(nullptr, realloc_result);
+      data_long_ = realloc_result;
+    }
+  } else if (length_ > sizeof(data_short_)) {
+    // Copy data from data_long_ to data_short_.
+    memcpy(temporary_data, data_long_, length);
+    free(data_long_);
+    data_long_ = nullptr;
+    memcpy(data_short_, temporary_data, length);
+  }
+  length_ = length;
+}
+
+bool QuicConnectionId::IsEmpty() const { return length_ == 0; }
+
+size_t QuicConnectionId::Hash() const {
+  static const QuicConnectionIdHasher hasher = QuicConnectionIdHasher();
+  return hasher.Hash(data(), length_);
+}
+
+std::string QuicConnectionId::ToString() const {
+  if (IsEmpty()) {
+    return std::string("0");
+  }
+  return absl::BytesToHexString(absl::string_view(data(), length_));
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) {
+  os << v.ToString();
+  return os;
+}
+
+bool QuicConnectionId::operator==(const QuicConnectionId& v) const {
+  return length_ == v.length_ && memcmp(data(), v.data(), length_) == 0;
+}
+
+bool QuicConnectionId::operator!=(const QuicConnectionId& v) const {
+  return !(v == *this);
+}
+
+bool QuicConnectionId::operator<(const QuicConnectionId& v) const {
+  if (length_ < v.length_) {
+    return true;
+  }
+  if (length_ > v.length_) {
+    return false;
+  }
+  return memcmp(data(), v.data(), length_) < 0;
+}
+
+QuicConnectionId EmptyQuicConnectionId() { return QuicConnectionId(); }
+
+static_assert(kQuicDefaultConnectionIdLength == sizeof(uint64_t),
+              "kQuicDefaultConnectionIdLength changed");
+static_assert(kQuicDefaultConnectionIdLength == PACKET_8BYTE_CONNECTION_ID,
+              "kQuicDefaultConnectionIdLength changed");
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id.h b/quiche/quic/core/quic_connection_id.h
new file mode 100644
index 0000000..52f1501
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id.h
@@ -0,0 +1,142 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/types/span.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+enum QuicConnectionIdLength {
+  PACKET_0BYTE_CONNECTION_ID = 0,
+  PACKET_8BYTE_CONNECTION_ID = 8,
+};
+
+// This is a property of QUIC headers, it indicates whether the connection ID
+// should actually be sent over the wire (or was sent on received packets).
+enum QuicConnectionIdIncluded : uint8_t {
+  CONNECTION_ID_PRESENT = 1,
+  CONNECTION_ID_ABSENT = 2,
+};
+
+// Maximum connection ID length supported by versions that use the encoding from
+// draft-ietf-quic-invariants-06.
+const uint8_t kQuicMaxConnectionIdWithLengthPrefixLength = 20;
+
+// Maximum connection ID length supported by versions that use the encoding from
+// draft-ietf-quic-invariants-05.
+const uint8_t kQuicMaxConnectionId4BitLength = 18;
+
+// kQuicDefaultConnectionIdLength is the only supported length for QUIC
+// versions < v99, and is the default picked for all versions.
+const uint8_t kQuicDefaultConnectionIdLength = 8;
+
+// According to the IETF spec, the initial server connection ID generated by
+// the client must be at least this long.
+const uint8_t kQuicMinimumInitialConnectionIdLength = 8;
+
+class QUIC_EXPORT_PRIVATE QuicConnectionId {
+ public:
+  // Creates a connection ID of length zero.
+  QuicConnectionId();
+
+  // Creates a connection ID from network order bytes.
+  QuicConnectionId(const char* data, uint8_t length);
+  QuicConnectionId(const absl::Span<const uint8_t> data);
+
+  // Creates a connection ID from another connection ID.
+  QuicConnectionId(const QuicConnectionId& other);
+
+  // Assignment operator.
+  QuicConnectionId& operator=(const QuicConnectionId& other);
+
+  ~QuicConnectionId();
+
+  // Returns the length of the connection ID, in bytes.
+  uint8_t length() const;
+
+  // Sets the length of the connection ID, in bytes.
+  // WARNING: Calling set_length() can change the in-memory location of the
+  // connection ID. Callers must therefore ensure they call data() or
+  // mutable_data() after they call set_length().
+  void set_length(uint8_t length);
+
+  // Returns a pointer to the connection ID bytes, in network byte order.
+  const char* data() const;
+
+  // Returns a mutable pointer to the connection ID bytes,
+  // in network byte order.
+  char* mutable_data();
+
+  // Returns whether the connection ID has length zero.
+  bool IsEmpty() const;
+
+  // Hash() is required to use connection IDs as keys in hash tables.
+  // During the lifetime of a process, the output of Hash() is guaranteed to be
+  // the same for connection IDs that are equal to one another. Note however
+  // that this property is not guaranteed across process lifetimes. This makes
+  // Hash() suitable for data structures such as hash tables but not for sending
+  // a hash over the network.
+  size_t Hash() const;
+
+  // Generates an ASCII string that represents
+  // the contents of the connection ID, or "0" if it is empty.
+  std::string ToString() const;
+
+  // operator<< allows easily logging connection IDs.
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const QuicConnectionId& v);
+
+  bool operator==(const QuicConnectionId& v) const;
+  bool operator!=(const QuicConnectionId& v) const;
+  // operator< is required to use connection IDs as keys in hash tables.
+  bool operator<(const QuicConnectionId& v) const;
+
+ private:
+  // The connection ID is represented in network byte order.
+  union {
+    // If the connection ID fits in |data_short_|, it is stored in the
+    // first |length_| bytes of |data_short_|.
+    // Otherwise it is stored in |data_long_| which is guaranteed to have a size
+    // equal to |length_|.
+    // A value of 11 was chosen because our commonly used connection ID length
+    // is 8 and with the length, the class is padded to at least 12 bytes
+    // anyway.
+    struct {
+      uint8_t padding_;  // Match length_ field of the other union member.
+      char data_short_[11];
+    };
+    struct {
+      uint8_t length_;  // length of the connection ID, in bytes.
+      char* data_long_;
+    };
+  };
+};
+
+// Creates a connection ID of length zero, unless the restart flag
+// quic_connection_ids_network_byte_order is false in which case
+// it returns an 8-byte all-zeroes connection ID.
+QUIC_EXPORT_PRIVATE QuicConnectionId EmptyQuicConnectionId();
+
+// QuicConnectionIdHash can be passed as hash argument to hash tables.
+// During the lifetime of a process, the output of QuicConnectionIdHash is
+// guaranteed to be the same for connection IDs that are equal to one another.
+// Note however that this property is not guaranteed across process lifetimes.
+// This makes QuicConnectionIdHash suitable for data structures such as hash
+// tables but not for sending a hash over the network.
+class QUIC_EXPORT_PRIVATE QuicConnectionIdHash {
+ public:
+  size_t operator()(QuicConnectionId const& connection_id) const noexcept {
+    return connection_id.Hash();
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
diff --git a/quiche/quic/core/quic_connection_id_manager.cc b/quiche/quic/core/quic_connection_id_manager.cc
new file mode 100644
index 0000000..db9d097
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_manager.cc
@@ -0,0 +1,460 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_id_manager.h"
+
+#include <cstdio>
+
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+QuicConnectionIdData::QuicConnectionIdData(
+    const QuicConnectionId& connection_id,
+    uint64_t sequence_number,
+    const StatelessResetToken& stateless_reset_token)
+    : connection_id(connection_id),
+      sequence_number(sequence_number),
+      stateless_reset_token(stateless_reset_token) {}
+
+namespace {
+
+class RetirePeerIssuedConnectionIdAlarm
+    : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit RetirePeerIssuedConnectionIdAlarm(
+      QuicConnectionIdManagerVisitorInterface* visitor,
+      QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context), visitor_(visitor) {}
+  RetirePeerIssuedConnectionIdAlarm(const RetirePeerIssuedConnectionIdAlarm&) =
+      delete;
+  RetirePeerIssuedConnectionIdAlarm& operator=(
+      const RetirePeerIssuedConnectionIdAlarm&) = delete;
+
+  void OnAlarm() override { visitor_->OnPeerIssuedConnectionIdRetired(); }
+
+ private:
+  QuicConnectionIdManagerVisitorInterface* visitor_;
+};
+
+std::vector<QuicConnectionIdData>::const_iterator FindConnectionIdData(
+    const std::vector<QuicConnectionIdData>& cid_data_vector,
+    const QuicConnectionId& cid) {
+  return std::find_if(cid_data_vector.begin(), cid_data_vector.end(),
+                      [&cid](const QuicConnectionIdData& cid_data) {
+                        return cid == cid_data.connection_id;
+                      });
+}
+
+std::vector<QuicConnectionIdData>::iterator FindConnectionIdData(
+    std::vector<QuicConnectionIdData>* cid_data_vector,
+    const QuicConnectionId& cid) {
+  return std::find_if(cid_data_vector->begin(), cid_data_vector->end(),
+                      [&cid](const QuicConnectionIdData& cid_data) {
+                        return cid == cid_data.connection_id;
+                      });
+}
+
+}  // namespace
+
+QuicPeerIssuedConnectionIdManager::QuicPeerIssuedConnectionIdManager(
+    size_t active_connection_id_limit,
+    const QuicConnectionId& initial_peer_issued_connection_id,
+    const QuicClock* clock, QuicAlarmFactory* alarm_factory,
+    QuicConnectionIdManagerVisitorInterface* visitor,
+    QuicConnectionContext* context)
+    : active_connection_id_limit_(active_connection_id_limit),
+      clock_(clock),
+      retire_connection_id_alarm_(alarm_factory->CreateAlarm(
+          new RetirePeerIssuedConnectionIdAlarm(visitor, context))) {
+  QUICHE_DCHECK_GE(active_connection_id_limit_, 2u);
+  QUICHE_DCHECK(!initial_peer_issued_connection_id.IsEmpty());
+  active_connection_id_data_.emplace_back<const QuicConnectionId&, uint64_t,
+                                          const StatelessResetToken&>(
+      initial_peer_issued_connection_id,
+      /*sequence_number=*/0u, {});
+  recent_new_connection_id_sequence_numbers_.Add(0u, 1u);
+}
+
+QuicPeerIssuedConnectionIdManager::~QuicPeerIssuedConnectionIdManager() {
+  retire_connection_id_alarm_->Cancel();
+}
+
+bool QuicPeerIssuedConnectionIdManager::IsConnectionIdNew(
+    const QuicNewConnectionIdFrame& frame) {
+  auto is_old_connection_id = [&frame](const QuicConnectionIdData& cid_data) {
+    return cid_data.connection_id == frame.connection_id;
+  };
+  if (std::any_of(active_connection_id_data_.begin(),
+                  active_connection_id_data_.end(), is_old_connection_id)) {
+    return false;
+  }
+  if (std::any_of(unused_connection_id_data_.begin(),
+                  unused_connection_id_data_.end(), is_old_connection_id)) {
+    return false;
+  }
+  if (std::any_of(to_be_retired_connection_id_data_.begin(),
+                  to_be_retired_connection_id_data_.end(),
+                  is_old_connection_id)) {
+    return false;
+  }
+  return true;
+}
+
+void QuicPeerIssuedConnectionIdManager::PrepareToRetireConnectionIdPriorTo(
+    uint64_t retire_prior_to,
+    std::vector<QuicConnectionIdData>* cid_data_vector) {
+  auto it2 = cid_data_vector->begin();
+  for (auto it = cid_data_vector->begin(); it != cid_data_vector->end(); ++it) {
+    if (it->sequence_number >= retire_prior_to) {
+      *it2++ = *it;
+    } else {
+      to_be_retired_connection_id_data_.push_back(*it);
+      if (!retire_connection_id_alarm_->IsSet()) {
+        retire_connection_id_alarm_->Set(clock_->ApproximateNow());
+      }
+    }
+  }
+  cid_data_vector->erase(it2, cid_data_vector->end());
+}
+
+QuicErrorCode QuicPeerIssuedConnectionIdManager::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& frame,
+    std::string* error_detail) {
+  if (recent_new_connection_id_sequence_numbers_.Contains(
+          frame.sequence_number)) {
+    // This frame has a recently seen sequence number. Ignore.
+    return QUIC_NO_ERROR;
+  }
+  if (!IsConnectionIdNew(frame)) {
+    *error_detail =
+        "Received a NEW_CONNECTION_ID frame that reuses a previously seen Id.";
+    return IETF_QUIC_PROTOCOL_VIOLATION;
+  }
+
+  recent_new_connection_id_sequence_numbers_.AddOptimizedForAppend(
+      frame.sequence_number, frame.sequence_number + 1);
+
+  if (recent_new_connection_id_sequence_numbers_.Size() >
+      kMaxNumConnectionIdSequenceNumberIntervals) {
+    *error_detail =
+        "Too many disjoint connection Id sequence number intervals.";
+    return IETF_QUIC_PROTOCOL_VIOLATION;
+  }
+
+  // QuicFramer::ProcessNewConnectionIdFrame guarantees that
+  // frame.sequence_number >= frame.retire_prior_to, and hence there is no need
+  // to check that.
+  if (frame.sequence_number < max_new_connection_id_frame_retire_prior_to_) {
+    // Later frames have asked for retirement of the current frame.
+    to_be_retired_connection_id_data_.emplace_back(frame.connection_id,
+                                                   frame.sequence_number,
+                                                   frame.stateless_reset_token);
+    if (!retire_connection_id_alarm_->IsSet()) {
+      retire_connection_id_alarm_->Set(clock_->ApproximateNow());
+    }
+    return QUIC_NO_ERROR;
+  }
+  if (frame.retire_prior_to > max_new_connection_id_frame_retire_prior_to_) {
+    max_new_connection_id_frame_retire_prior_to_ = frame.retire_prior_to;
+    PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
+                                       &active_connection_id_data_);
+    PrepareToRetireConnectionIdPriorTo(frame.retire_prior_to,
+                                       &unused_connection_id_data_);
+  }
+
+  if (active_connection_id_data_.size() + unused_connection_id_data_.size() >=
+      active_connection_id_limit_) {
+    *error_detail = "Peer provides more connection IDs than the limit.";
+    return QUIC_CONNECTION_ID_LIMIT_ERROR;
+  }
+
+  unused_connection_id_data_.emplace_back(
+      frame.connection_id, frame.sequence_number, frame.stateless_reset_token);
+  return QUIC_NO_ERROR;
+}
+
+const QuicConnectionIdData*
+QuicPeerIssuedConnectionIdManager::ConsumeOneUnusedConnectionId() {
+  if (unused_connection_id_data_.empty()) {
+    return nullptr;
+  }
+  active_connection_id_data_.push_back(unused_connection_id_data_.back());
+  unused_connection_id_data_.pop_back();
+  return &active_connection_id_data_.back();
+}
+
+void QuicPeerIssuedConnectionIdManager::PrepareToRetireActiveConnectionId(
+    const QuicConnectionId& cid) {
+  auto it = FindConnectionIdData(active_connection_id_data_, cid);
+  if (it == active_connection_id_data_.end()) {
+    // The cid has already been retired.
+    return;
+  }
+  to_be_retired_connection_id_data_.push_back(*it);
+  active_connection_id_data_.erase(it);
+  if (!retire_connection_id_alarm_->IsSet()) {
+    retire_connection_id_alarm_->Set(clock_->ApproximateNow());
+  }
+}
+
+void QuicPeerIssuedConnectionIdManager::MaybeRetireUnusedConnectionIds(
+    const std::vector<QuicConnectionId>& active_connection_ids_on_path) {
+  std::vector<QuicConnectionId> cids_to_retire;
+  for (const auto& cid_data : active_connection_id_data_) {
+    if (std::find(active_connection_ids_on_path.begin(),
+                  active_connection_ids_on_path.end(),
+                  cid_data.connection_id) ==
+        active_connection_ids_on_path.end()) {
+      cids_to_retire.push_back(cid_data.connection_id);
+    }
+  }
+  for (const auto& cid : cids_to_retire) {
+    PrepareToRetireActiveConnectionId(cid);
+  }
+}
+
+bool QuicPeerIssuedConnectionIdManager::IsConnectionIdActive(
+    const QuicConnectionId& cid) const {
+  return FindConnectionIdData(active_connection_id_data_, cid) !=
+         active_connection_id_data_.end();
+}
+
+std::vector<uint64_t> QuicPeerIssuedConnectionIdManager::
+    ConsumeToBeRetiredConnectionIdSequenceNumbers() {
+  std::vector<uint64_t> result;
+  for (auto const& cid_data : to_be_retired_connection_id_data_) {
+    result.push_back(cid_data.sequence_number);
+  }
+  to_be_retired_connection_id_data_.clear();
+  return result;
+}
+
+void QuicPeerIssuedConnectionIdManager::ReplaceConnectionId(
+    const QuicConnectionId& old_connection_id,
+    const QuicConnectionId& new_connection_id) {
+  auto it1 =
+      FindConnectionIdData(&active_connection_id_data_, old_connection_id);
+  if (it1 != active_connection_id_data_.end()) {
+    it1->connection_id = new_connection_id;
+    return;
+  }
+  auto it2 = FindConnectionIdData(&to_be_retired_connection_id_data_,
+                                  old_connection_id);
+  if (it2 != to_be_retired_connection_id_data_.end()) {
+    it2->connection_id = new_connection_id;
+  }
+}
+
+namespace {
+
+class RetireSelfIssuedConnectionIdAlarmDelegate
+    : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit RetireSelfIssuedConnectionIdAlarmDelegate(
+      QuicSelfIssuedConnectionIdManager* connection_id_manager,
+      QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context),
+        connection_id_manager_(connection_id_manager) {}
+  RetireSelfIssuedConnectionIdAlarmDelegate(
+      const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
+  RetireSelfIssuedConnectionIdAlarmDelegate& operator=(
+      const RetireSelfIssuedConnectionIdAlarmDelegate&) = delete;
+
+  void OnAlarm() override { connection_id_manager_->RetireConnectionId(); }
+
+ private:
+  QuicSelfIssuedConnectionIdManager* connection_id_manager_;
+};
+
+}  // namespace
+
+QuicSelfIssuedConnectionIdManager::QuicSelfIssuedConnectionIdManager(
+    size_t active_connection_id_limit,
+    const QuicConnectionId& initial_connection_id, const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory,
+    QuicConnectionIdManagerVisitorInterface* visitor,
+    QuicConnectionContext* context)
+    : active_connection_id_limit_(active_connection_id_limit),
+      clock_(clock),
+      visitor_(visitor),
+      retire_connection_id_alarm_(alarm_factory->CreateAlarm(
+          new RetireSelfIssuedConnectionIdAlarmDelegate(this, context))),
+      last_connection_id_(initial_connection_id),
+      next_connection_id_sequence_number_(1u),
+      last_connection_id_consumed_by_self_sequence_number_(0u) {
+  active_connection_ids_.emplace_back(initial_connection_id, 0u);
+}
+
+QuicSelfIssuedConnectionIdManager::~QuicSelfIssuedConnectionIdManager() {
+  retire_connection_id_alarm_->Cancel();
+}
+
+QuicConnectionId QuicSelfIssuedConnectionIdManager::GenerateNewConnectionId(
+    const QuicConnectionId& old_connection_id) const {
+  return QuicUtils::CreateReplacementConnectionId(old_connection_id);
+}
+
+QuicNewConnectionIdFrame
+QuicSelfIssuedConnectionIdManager::IssueNewConnectionId() {
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = GenerateNewConnectionId(last_connection_id_);
+  frame.sequence_number = next_connection_id_sequence_number_++;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  visitor_->OnNewConnectionIdIssued(frame.connection_id);
+  active_connection_ids_.emplace_back(frame.connection_id,
+                                      frame.sequence_number);
+  frame.retire_prior_to = active_connection_ids_.front().second;
+  last_connection_id_ = frame.connection_id;
+  return frame;
+}
+
+QuicNewConnectionIdFrame
+QuicSelfIssuedConnectionIdManager::IssueNewConnectionIdForPreferredAddress() {
+  QuicNewConnectionIdFrame frame = IssueNewConnectionId();
+  QUICHE_DCHECK_EQ(frame.sequence_number, 1u);
+  return frame;
+}
+
+QuicErrorCode QuicSelfIssuedConnectionIdManager::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& frame,
+    QuicTime::Delta pto_delay,
+    std::string* error_detail) {
+  QUICHE_DCHECK(!active_connection_ids_.empty());
+  if (frame.sequence_number > active_connection_ids_.back().second) {
+    *error_detail = "To be retired connecton ID is never issued.";
+    return IETF_QUIC_PROTOCOL_VIOLATION;
+  }
+
+  auto it =
+      std::find_if(active_connection_ids_.begin(), active_connection_ids_.end(),
+                   [&frame](const std::pair<QuicConnectionId, uint64_t>& p) {
+                     return p.second == frame.sequence_number;
+                   });
+  // The corresponding connection ID has been retired. Ignore.
+  if (it == active_connection_ids_.end()) {
+    return QUIC_NO_ERROR;
+  }
+
+  if (to_be_retired_connection_ids_.size() + active_connection_ids_.size() >=
+      kMaxNumConnectonIdsInUse) {
+    // Close connection if the number of connection IDs in use will exeed the
+    // limit, i.e., peer retires connection ID too fast.
+    *error_detail = "There are too many connection IDs in use.";
+    return QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE;
+  }
+
+  QuicTime retirement_time = clock_->ApproximateNow() + 3 * pto_delay;
+  if (!to_be_retired_connection_ids_.empty()) {
+    retirement_time =
+        std::max(retirement_time, to_be_retired_connection_ids_.back().second);
+  }
+
+  to_be_retired_connection_ids_.emplace_back(it->first, retirement_time);
+  if (!retire_connection_id_alarm_->IsSet()) {
+    retire_connection_id_alarm_->Set(retirement_time);
+  }
+
+  active_connection_ids_.erase(it);
+  MaybeSendNewConnectionIds();
+
+  return QUIC_NO_ERROR;
+}
+
+std::vector<QuicConnectionId>
+QuicSelfIssuedConnectionIdManager::GetUnretiredConnectionIds() const {
+  std::vector<QuicConnectionId> unretired_ids;
+  for (const auto& cid_pair : to_be_retired_connection_ids_) {
+    unretired_ids.push_back(cid_pair.first);
+  }
+  for (const auto& cid_pair : active_connection_ids_) {
+    unretired_ids.push_back(cid_pair.first);
+  }
+  return unretired_ids;
+}
+
+QuicConnectionId QuicSelfIssuedConnectionIdManager::GetOneActiveConnectionId()
+    const {
+  QUICHE_DCHECK(!active_connection_ids_.empty());
+  return active_connection_ids_.front().first;
+}
+
+void QuicSelfIssuedConnectionIdManager::RetireConnectionId() {
+  if (to_be_retired_connection_ids_.empty()) {
+    QUIC_BUG(quic_bug_12420_1)
+        << "retire_connection_id_alarm fired but there is no connection ID "
+           "to be retired.";
+    return;
+  }
+  QuicTime now = clock_->ApproximateNow();
+  auto it = to_be_retired_connection_ids_.begin();
+  do {
+    visitor_->OnSelfIssuedConnectionIdRetired(it->first);
+    ++it;
+  } while (it != to_be_retired_connection_ids_.end() && it->second <= now);
+  to_be_retired_connection_ids_.erase(to_be_retired_connection_ids_.begin(),
+                                      it);
+  // Set the alarm again if there is another connection ID to be removed.
+  if (!to_be_retired_connection_ids_.empty()) {
+    retire_connection_id_alarm_->Set(
+        to_be_retired_connection_ids_.front().second);
+  }
+}
+
+void QuicSelfIssuedConnectionIdManager::MaybeSendNewConnectionIds() {
+  while (active_connection_ids_.size() < active_connection_id_limit_) {
+    QuicNewConnectionIdFrame frame = IssueNewConnectionId();
+    if (!visitor_->SendNewConnectionId(frame)) {
+      break;
+    }
+  }
+}
+
+bool QuicSelfIssuedConnectionIdManager::HasConnectionIdToConsume() const {
+  for (const auto& active_cid_data : active_connection_ids_) {
+    if (active_cid_data.second >
+        last_connection_id_consumed_by_self_sequence_number_) {
+      return true;
+    }
+  }
+  return false;
+}
+
+absl::optional<QuicConnectionId>
+QuicSelfIssuedConnectionIdManager::ConsumeOneConnectionId() {
+  for (const auto& active_cid_data : active_connection_ids_) {
+    if (active_cid_data.second >
+        last_connection_id_consumed_by_self_sequence_number_) {
+      // Since connection IDs in active_connection_ids_ has monotonically
+      // increasing sequence numbers, the returned connection ID has the
+      // smallest sequence number among all unconsumed active connection IDs.
+      last_connection_id_consumed_by_self_sequence_number_ =
+          active_cid_data.second;
+      return active_cid_data.first;
+    }
+  }
+  return absl::nullopt;
+}
+
+bool QuicSelfIssuedConnectionIdManager::IsConnectionIdInUse(
+    const QuicConnectionId& cid) const {
+  for (const auto& active_cid_data : active_connection_ids_) {
+    if (active_cid_data.first == cid) {
+      return true;
+    }
+  }
+  for (const auto& to_be_retired_cid_data : to_be_retired_connection_ids_) {
+    if (to_be_retired_cid_data.first == cid) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id_manager.h b/quiche/quic/core/quic_connection_id_manager.h
new file mode 100644
index 0000000..11454df
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_manager.h
@@ -0,0 +1,195 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// QuicPeerIssuedConnectionIdManager handles the states associated with receving
+// and retiring peer issued connection Ids.
+// QuicSelfIssuedConnectionIdManager handles the states associated with
+// connection Ids issued by the current end point.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionIdManagerPeer;
+}  // namespace test
+
+struct QUIC_EXPORT_PRIVATE QuicConnectionIdData {
+  QuicConnectionIdData(const QuicConnectionId& connection_id,
+                       uint64_t sequence_number,
+                       const StatelessResetToken& stateless_reset_token);
+
+  QuicConnectionId connection_id;
+  uint64_t sequence_number;
+  StatelessResetToken stateless_reset_token;
+};
+
+// Used by QuicSelfIssuedConnectionIdManager
+// and QuicPeerIssuedConnectionIdManager.
+class QUIC_EXPORT_PRIVATE QuicConnectionIdManagerVisitorInterface {
+ public:
+  virtual ~QuicConnectionIdManagerVisitorInterface() = default;
+  virtual void OnPeerIssuedConnectionIdRetired() = 0;
+  virtual bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0;
+  virtual void OnNewConnectionIdIssued(
+      const QuicConnectionId& connection_id) = 0;
+  virtual void OnSelfIssuedConnectionIdRetired(
+      const QuicConnectionId& connection_id) = 0;
+};
+
+class QUIC_EXPORT_PRIVATE QuicPeerIssuedConnectionIdManager {
+ public:
+  // QuicPeerIssuedConnectionIdManager should be instantiated only when a peer
+  // issued-non empty connection ID is received.
+  QuicPeerIssuedConnectionIdManager(
+      size_t active_connection_id_limit,
+      const QuicConnectionId& initial_peer_issued_connection_id,
+      const QuicClock* clock, QuicAlarmFactory* alarm_factory,
+      QuicConnectionIdManagerVisitorInterface* visitor,
+      QuicConnectionContext* context);
+
+  ~QuicPeerIssuedConnectionIdManager();
+
+  QuicErrorCode OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
+                                       std::string* error_detail);
+
+  bool HasUnusedConnectionId() const {
+    return !unused_connection_id_data_.empty();
+  }
+
+  // Returns the data associated with an unused connection Id. After the call,
+  // the Id is marked as used. Returns nullptr if there is no unused connection
+  // Id.
+  const QuicConnectionIdData* ConsumeOneUnusedConnectionId();
+
+  // Add each active connection Id that is no longer on path to the pending
+  // retirement connection Id list.
+  void MaybeRetireUnusedConnectionIds(
+      const std::vector<QuicConnectionId>& active_connection_ids_on_path);
+
+  bool IsConnectionIdActive(const QuicConnectionId& cid) const;
+
+  // Get the sequence numbers of all the connection Ids pending retirement when
+  // it is safe to retires these Ids.
+  std::vector<uint64_t> ConsumeToBeRetiredConnectionIdSequenceNumbers();
+
+  // If old_connection_id is still tracked by QuicPeerIssuedConnectionIdManager,
+  // replace it with new_connection_id. Otherwise, this is a no-op.
+  void ReplaceConnectionId(const QuicConnectionId& old_connection_id,
+                           const QuicConnectionId& new_connection_id);
+
+ private:
+  friend class test::QuicConnectionIdManagerPeer;
+
+  // Add the connection Id to the pending retirement connection Id list and
+  // schedule an alarm if needed.
+  void PrepareToRetireActiveConnectionId(const QuicConnectionId& cid);
+
+  bool IsConnectionIdNew(const QuicNewConnectionIdFrame& frame);
+
+  void PrepareToRetireConnectionIdPriorTo(
+      uint64_t retire_prior_to,
+      std::vector<QuicConnectionIdData>* cid_data_vector);
+
+  size_t active_connection_id_limit_;
+  const QuicClock* clock_;
+  std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
+  std::vector<QuicConnectionIdData> active_connection_id_data_;
+  std::vector<QuicConnectionIdData> unused_connection_id_data_;
+  std::vector<QuicConnectionIdData> to_be_retired_connection_id_data_;
+  // Track sequence numbers of recent NEW_CONNECTION_ID frames received from
+  // the peer.
+  QuicIntervalSet<uint64_t> recent_new_connection_id_sequence_numbers_;
+  uint64_t max_new_connection_id_frame_retire_prior_to_ = 0u;
+};
+
+class QUIC_EXPORT_PRIVATE QuicSelfIssuedConnectionIdManager {
+ public:
+  QuicSelfIssuedConnectionIdManager(
+      size_t active_connection_id_limit,
+      const QuicConnectionId& initial_connection_id, const QuicClock* clock,
+      QuicAlarmFactory* alarm_factory,
+      QuicConnectionIdManagerVisitorInterface* visitor,
+      QuicConnectionContext* context);
+
+  virtual ~QuicSelfIssuedConnectionIdManager();
+
+  QuicNewConnectionIdFrame IssueNewConnectionIdForPreferredAddress();
+
+  QuicErrorCode OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame,
+      QuicTime::Delta pto_delay,
+      std::string* error_detail);
+
+  std::vector<QuicConnectionId> GetUnretiredConnectionIds() const;
+
+  QuicConnectionId GetOneActiveConnectionId() const;
+
+  // Called when the retire_connection_id alarm_ fires. Removes the to be
+  // retired connection ID locally.
+  void RetireConnectionId();
+
+  // Sends new connection IDs if more can be sent.
+  void MaybeSendNewConnectionIds();
+
+  // The two functions are called on the client side to associate a client
+  // connection ID with a new probing/migration path when client uses
+  // non-empty connection ID.
+  bool HasConnectionIdToConsume() const;
+  absl::optional<QuicConnectionId> ConsumeOneConnectionId();
+
+  // Returns true if the given connection ID is issued by the
+  // QuicSelfIssuedConnectionIdManager and not retired locally yet. Called to
+  // tell if a received packet has a valid connection ID.
+  bool IsConnectionIdInUse(const QuicConnectionId& cid) const;
+
+  virtual QuicConnectionId GenerateNewConnectionId(
+      const QuicConnectionId& old_connection_id) const;
+
+ private:
+  friend class test::QuicConnectionIdManagerPeer;
+
+  QuicNewConnectionIdFrame IssueNewConnectionId();
+
+  // This should be set to the min of:
+  // (1) # of active connection IDs that peer can maintain.
+  // (2) maximum # of active connection IDs self plans to issue.
+  size_t active_connection_id_limit_;
+  const QuicClock* clock_;
+  QuicConnectionIdManagerVisitorInterface* visitor_;
+  // This tracks connection IDs issued to the peer but not retired by the peer.
+  // Each pair is a connection ID and its sequence number.
+  std::vector<std::pair<QuicConnectionId, uint64_t>> active_connection_ids_;
+  // This tracks connection IDs retired by the peer but has not been retired
+  // locally. Each pair is a connection ID and the time by which it should be
+  // retired.
+  std::vector<std::pair<QuicConnectionId, QuicTime>>
+      to_be_retired_connection_ids_;
+  // An alarm that fires when a connection ID should be retired.
+  std::unique_ptr<QuicAlarm> retire_connection_id_alarm_;
+  // State of the last issued connection Id.
+  QuicConnectionId last_connection_id_;
+  uint64_t next_connection_id_sequence_number_;
+  // The sequence number of last connection ID consumed.
+  uint64_t last_connection_id_consumed_by_self_sequence_number_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_
diff --git a/quiche/quic/core/quic_connection_id_manager_test.cc b/quiche/quic/core/quic_connection_id_manager_test.cc
new file mode 100644
index 0000000..57e6b87
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_manager_test.cc
@@ -0,0 +1,964 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_id_manager.h"
+#include <cstddef>
+
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_connection_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace {
+
+using ::quic::test::IsError;
+using ::quic::test::IsQuicNoError;
+using ::quic::test::QuicConnectionIdManagerPeer;
+using ::quic::test::TestConnectionId;
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::IsNull;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+class TestPeerIssuedConnectionIdManagerVisitor
+    : public QuicConnectionIdManagerVisitorInterface {
+ public:
+  void SetPeerIssuedConnectionIdManager(
+      QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager) {
+    peer_issued_connection_id_manager_ = peer_issued_connection_id_manager;
+  }
+
+  void OnPeerIssuedConnectionIdRetired() override {
+    // Replace current connection Id if it has been retired.
+    if (!peer_issued_connection_id_manager_->IsConnectionIdActive(
+            current_peer_issued_connection_id_)) {
+      current_peer_issued_connection_id_ =
+          peer_issued_connection_id_manager_->ConsumeOneUnusedConnectionId()
+              ->connection_id;
+    }
+    // Retire all the to-be-retired connection Ids.
+    most_recent_retired_connection_id_sequence_numbers_ =
+        peer_issued_connection_id_manager_
+            ->ConsumeToBeRetiredConnectionIdSequenceNumbers();
+  }
+
+  const std::vector<uint64_t>&
+  most_recent_retired_connection_id_sequence_numbers() {
+    return most_recent_retired_connection_id_sequence_numbers_;
+  }
+
+  void SetCurrentPeerConnectionId(QuicConnectionId cid) {
+    current_peer_issued_connection_id_ = cid;
+  }
+
+  const QuicConnectionId& GetCurrentPeerConnectionId() {
+    return current_peer_issued_connection_id_;
+  }
+
+  bool SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
+    return false;
+  }
+  void OnNewConnectionIdIssued(
+      const QuicConnectionId& /*connection_id*/) override {}
+  void OnSelfIssuedConnectionIdRetired(
+      const QuicConnectionId& /*connection_id*/) override {}
+
+ private:
+  QuicPeerIssuedConnectionIdManager* peer_issued_connection_id_manager_ =
+      nullptr;
+  QuicConnectionId current_peer_issued_connection_id_;
+  std::vector<uint64_t> most_recent_retired_connection_id_sequence_numbers_;
+};
+
+class QuicPeerIssuedConnectionIdManagerTest : public QuicTest {
+ public:
+  QuicPeerIssuedConnectionIdManagerTest()
+      : peer_issued_cid_manager_(
+            /*active_connection_id_limit=*/2, initial_connection_id_, &clock_,
+            &alarm_factory_, &cid_manager_visitor_, /*context=*/nullptr) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    cid_manager_visitor_.SetPeerIssuedConnectionIdManager(
+        &peer_issued_cid_manager_);
+    cid_manager_visitor_.SetCurrentPeerConnectionId(initial_connection_id_);
+    retire_peer_issued_cid_alarm_ =
+        QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
+            &peer_issued_cid_manager_);
+  }
+
+ protected:
+  MockClock clock_;
+  test::MockAlarmFactory alarm_factory_;
+  TestPeerIssuedConnectionIdManagerVisitor cid_manager_visitor_;
+  QuicConnectionId initial_connection_id_ = TestConnectionId(0);
+  QuicPeerIssuedConnectionIdManager peer_issued_cid_manager_;
+  QuicAlarm* retire_peer_issued_cid_alarm_ = nullptr;
+  std::string error_details_;
+};
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ConnectionIdSequenceWhenMigrationSucceed) {
+  {
+    // Receives CID #1 from peer.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+
+    // Start to use CID #1 for alternative path.
+    const QuicConnectionIdData* aternative_connection_id_data =
+        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    ASSERT_THAT(aternative_connection_id_data, testing::NotNull());
+    EXPECT_EQ(aternative_connection_id_data->connection_id,
+              TestConnectionId(1));
+    EXPECT_EQ(aternative_connection_id_data->stateless_reset_token,
+              frame.stateless_reset_token);
+
+    // Connection migration succeed. Prepares to retire CID #0.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(1)});
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(1));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(0u));
+  }
+
+  {
+    // Receives CID #2 from peer since CID #0 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 1u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #2 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration succeed. Prepares to retire CID #1.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(2)});
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(2));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(1u));
+  }
+
+  {
+    // Receives CID #3 from peer since CID #1 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(3);
+    frame.sequence_number = 3u;
+    frame.retire_prior_to = 2u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #3 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration succeed. Prepares to retire CID #2.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(3)});
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(2u));
+  }
+
+  {
+    // Receives CID #4 from peer since CID #2 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(4);
+    frame.sequence_number = 4u;
+    frame.retire_prior_to = 3u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ConnectionIdSequenceWhenMigrationFail) {
+  {
+    // Receives CID #1 from peer.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #1 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration fails. Prepares to retire CID #1.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {initial_connection_id_});
+    // Actually retires CID #1.
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(1u));
+  }
+
+  {
+    // Receives CID #2 from peer since CID #1 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #2 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration fails again. Prepares to retire CID #2.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {initial_connection_id_});
+    // Actually retires CID #2.
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(2u));
+  }
+
+  {
+    // Receives CID #3 from peer since CID #2 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(3);
+    frame.sequence_number = 3u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #3 for alternative path.
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+    // Connection migration succeed. Prepares to retire CID #0.
+    peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+        {TestConnectionId(3)});
+    // After CID #3 is default (i.e., when there is no pending frame to write
+    // associated with CID #0), #0 can actually be retired.
+    cid_manager_visitor_.SetCurrentPeerConnectionId(TestConnectionId(3));
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(0u));
+  }
+
+  {
+    // Receives CID #4 from peer since CID #0 is retired.
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(4);
+    frame.sequence_number = 4u;
+    frame.retire_prior_to = 3u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    EXPECT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    EXPECT_FALSE(retire_peer_issued_cid_alarm_->IsSet());
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ReceivesNewConnectionIdOutOfOrder) {
+  {
+    // Receives new CID #1 that retires prior to #0.
+    // Outcome: (active: #0 unused: #1)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    // Start to use CID #1 for alternative path.
+    // Outcome: (active: #0 #1 unused: None)
+    peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+  }
+
+  {
+    // Receives new CID #3 that retires prior to #2.
+    // Outcome: (active: None unused: #3)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(3);
+    frame.sequence_number = 3u;
+    frame.retire_prior_to = 2u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    // Receives new CID #2 that retires prior to #1.
+    // Outcome: (active: None unused: #3, #2)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 1u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    EXPECT_FALSE(
+        peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(0)));
+    EXPECT_FALSE(
+        peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
+    // When there is no frame associated with #0 and #1 to write, replace the
+    // in-use CID with an unused CID (#2) and retires #0 & #1.
+    ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+    alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+    EXPECT_THAT(cid_manager_visitor_
+                    .most_recent_retired_connection_id_sequence_numbers(),
+                ElementsAre(0u, 1u));
+    EXPECT_EQ(cid_manager_visitor_.GetCurrentPeerConnectionId(),
+              TestConnectionId(2));
+    // Get another unused CID for path validation.
+    EXPECT_EQ(
+        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
+        TestConnectionId(3));
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       VisitedNewConnectionIdFrameIsIgnored) {
+  // Receives new CID #1 that retires prior to #0.
+  // Outcome: (active: #0 unused: #1)
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = TestConnectionId(1);
+  frame.sequence_number = 1u;
+  frame.retire_prior_to = 0u;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  ASSERT_THAT(
+      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+      IsQuicNoError());
+  // Start to use CID #1 for alternative path.
+  // Outcome: (active: #0 #1 unused: None)
+  peer_issued_cid_manager_.ConsumeOneUnusedConnectionId();
+  // Prepare to retire CID #1 as path validation fails.
+  peer_issued_cid_manager_.MaybeRetireUnusedConnectionIds(
+      {initial_connection_id_});
+  // Actually retires CID #1.
+  ASSERT_TRUE(retire_peer_issued_cid_alarm_->IsSet());
+  alarm_factory_.FireAlarm(retire_peer_issued_cid_alarm_);
+  EXPECT_THAT(
+      cid_manager_visitor_.most_recent_retired_connection_id_sequence_numbers(),
+      ElementsAre(1u));
+  // Receives the same frame again. Should be a no-op.
+  ASSERT_THAT(
+      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+      IsQuicNoError());
+  EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
+              testing::IsNull());
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ErrorWhenActiveConnectionIdLimitExceeded) {
+  {
+    // Receives new CID #1 that retires prior to #0.
+    // Outcome: (active: #0 unused: #1)
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsError(QUIC_CONNECTION_ID_LIMIT_ERROR));
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ErrorWhenTheSameConnectionIdIsSeenWithDifferentSequenceNumbers) {
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 2u;
+    frame.retire_prior_to = 1u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       NewConnectionIdFrameWithTheSameSequenceNumberIsIgnored) {
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(1);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(2);
+    frame.sequence_number = 1u;
+    frame.retire_prior_to = 0u;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(TestConnectionId(2));
+    EXPECT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+    EXPECT_EQ(
+        peer_issued_cid_manager_.ConsumeOneUnusedConnectionId()->connection_id,
+        TestConnectionId(1));
+    EXPECT_THAT(peer_issued_cid_manager_.ConsumeOneUnusedConnectionId(),
+                IsNull());
+  }
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest,
+       ErrorWhenThereAreTooManyGapsInIssuedConnectionIdSequenceNumbers) {
+  // Add 20 intervals: [0, 1), [2, 3), ..., [38,39)
+  for (int i = 2; i <= 38; i += 2) {
+    QuicNewConnectionIdFrame frame;
+    frame.connection_id = TestConnectionId(i);
+    frame.sequence_number = i;
+    frame.retire_prior_to = i;
+    frame.stateless_reset_token =
+        QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+    ASSERT_THAT(
+        peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+        IsQuicNoError());
+  }
+
+  // Interval [40, 41) goes over the limit.
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = TestConnectionId(40);
+  frame.sequence_number = 40u;
+  frame.retire_prior_to = 40u;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  ASSERT_THAT(
+      peer_issued_cid_manager_.OnNewConnectionIdFrame(frame, &error_details_),
+      IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_F(QuicPeerIssuedConnectionIdManagerTest, ReplaceConnectionId) {
+  ASSERT_TRUE(
+      peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
+  peer_issued_cid_manager_.ReplaceConnectionId(initial_connection_id_,
+                                               TestConnectionId(1));
+  EXPECT_FALSE(
+      peer_issued_cid_manager_.IsConnectionIdActive(initial_connection_id_));
+  EXPECT_TRUE(
+      peer_issued_cid_manager_.IsConnectionIdActive(TestConnectionId(1)));
+}
+
+class TestSelfIssuedConnectionIdManagerVisitor
+    : public QuicConnectionIdManagerVisitorInterface {
+ public:
+  void OnPeerIssuedConnectionIdRetired() override {}
+
+  MOCK_METHOD(bool,
+              SendNewConnectionId,
+              (const QuicNewConnectionIdFrame& frame),
+              (override));
+  MOCK_METHOD(void,
+              OnNewConnectionIdIssued,
+              (const QuicConnectionId& connection_id),
+              (override));
+  MOCK_METHOD(void,
+              OnSelfIssuedConnectionIdRetired,
+              (const QuicConnectionId& connection_id),
+              (override));
+};
+
+class QuicSelfIssuedConnectionIdManagerTest : public QuicTest {
+ public:
+  QuicSelfIssuedConnectionIdManagerTest()
+      : cid_manager_(/*active_connection_id_limit*/ 2, initial_connection_id_,
+                     &clock_, &alarm_factory_, &cid_manager_visitor_,
+                     /*context=*/nullptr) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+    retire_self_issued_cid_alarm_ =
+        QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
+            &cid_manager_);
+  }
+
+ protected:
+  MockClock clock_;
+  test::MockAlarmFactory alarm_factory_;
+  TestSelfIssuedConnectionIdManagerVisitor cid_manager_visitor_;
+  QuicConnectionId initial_connection_id_ = TestConnectionId(0);
+  StrictMock<QuicSelfIssuedConnectionIdManager> cid_manager_;
+  QuicAlarm* retire_self_issued_cid_alarm_ = nullptr;
+  std::string error_details_;
+  QuicTime::Delta pto_delay_ = QuicTime::Delta::FromMilliseconds(10);
+};
+
+MATCHER_P3(ExpectedNewConnectionIdFrame,
+           connection_id,
+           sequence_number,
+           retire_prior_to,
+           "") {
+  return (arg.connection_id == connection_id) &&
+         (arg.sequence_number == sequence_number) &&
+         (arg.retire_prior_to == retire_prior_to);
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       RetireSelfIssuedConnectionIdInOrder) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
+  QuicConnectionId cid5 = cid_manager_.GenerateNewConnectionId(cid4);
+
+  // Sends CID #1 to peer.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
+  EXPECT_CALL(cid_manager_visitor_,
+              SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  {
+    // Peer retires CID #0;
+    // Sends CID #2 and asks peer to retire CIDs prior to #1.
+    // Outcome: (#1, #2) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 1u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 0u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #1;
+    // Sends CID #3 and asks peer to retire CIDs prior to #2.
+    // Outcome: (#2, #3) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 1u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #2;
+    // Sends CID #4 and asks peer to retire CIDs prior to #3.
+    // Outcome: (#3, #4) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 3u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 2u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #3;
+    // Sends CID #5 and asks peer to retire CIDs prior to #4.
+    // Outcome: (#4, #5) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid5));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid5, 5u, 4u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 3u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       RetireSelfIssuedConnectionIdOutOfOrder) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  QuicConnectionId cid4 = cid_manager_.GenerateNewConnectionId(cid3);
+
+  // Sends CID #1 to peer.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
+  EXPECT_CALL(cid_manager_visitor_,
+              SendNewConnectionId(ExpectedNewConnectionIdFrame(cid1, 1u, 0u)))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  {
+    // Peer retires CID #1;
+    // Sends CID #2 and asks peer to retire CIDs prior to #0.
+    // Outcome: (#0, #2) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid2));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid2, 2u, 0u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 1u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #1 again. This is a no-op.
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 1u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #0;
+    // Sends CID #3 and asks peer to retire CIDs prior to #2.
+    // Outcome: (#2, #3) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid3));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid3, 3u, 2u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 0u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #3;
+    // Sends CID #4 and asks peer to retire CIDs prior to #2.
+    // Outcome: (#2, #4) are active.
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid4));
+    EXPECT_CALL(cid_manager_visitor_,
+                SendNewConnectionId(ExpectedNewConnectionIdFrame(cid4, 4u, 2u)))
+        .WillOnce(Return(true));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 3u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+
+  {
+    // Peer retires CID #0 again. This is a no-op.
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = 0u;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+  }
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ScheduleConnectionIdRetirementOneAtATime) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
+  QuicRetireConnectionIdFrame retire_cid_frame;
+
+  // CID #1 is sent to peer.
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // CID #0's retirement is scheduled and CID #2 is sent to peer.
+  retire_cid_frame.sequence_number = 0u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+  // While CID #0's retirement is scheduled, it is not retired yet.
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid0, cid1, cid2));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout);
+
+  // CID #0 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
+  clock_.AdvanceTime(connection_id_expire_timeout);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid1, cid2));
+  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+
+  // CID #1's retirement is scheduled and CID #3 is sent to peer.
+  retire_cid_frame.sequence_number = 1u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+  // While CID #1's retirement is scheduled, it is not retired yet.
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid1, cid2, cid3));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout);
+
+  // CID #1 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
+  clock_.AdvanceTime(connection_id_expire_timeout);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid2, cid3));
+  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ScheduleMultipleConnectionIdRetirement) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
+  QuicRetireConnectionIdFrame retire_cid_frame;
+
+  // CID #1 is sent to peer.
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // CID #0's retirement is scheduled and CID #2 is sent to peer.
+  retire_cid_frame.sequence_number = 0u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
+
+  // CID #1's retirement is scheduled and CID #3 is sent to peer.
+  retire_cid_frame.sequence_number = 1u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsQuicNoError());
+
+  // While CID #0, #1s retirement is scheduled, they are not retired yet.
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid0, cid1, cid2, cid3));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout * 0.75);
+
+  // CID #0 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.75);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid1, cid2, cid3));
+  EXPECT_TRUE(retire_self_issued_cid_alarm_->IsSet());
+  EXPECT_EQ(retire_self_issued_cid_alarm_->deadline(),
+            clock_.ApproximateNow() + connection_id_expire_timeout * 0.25);
+
+  // CID #1 is actually retired.
+  EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.25);
+  alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid2, cid3));
+  EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       AllExpiredConnectionIdsAreRetiredInOneBatch) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  QuicConnectionId cid2 = cid_manager_.GenerateNewConnectionId(cid1);
+  QuicConnectionId cid3 = cid_manager_.GenerateNewConnectionId(cid2);
+  QuicConnectionId cid;
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(3);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .Times(3)
+      .WillRepeatedly(Return(true));
+  QuicTime::Delta connection_id_expire_timeout = 3 * pto_delay_;
+  QuicRetireConnectionIdFrame retire_cid_frame;
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
+  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
+  EXPECT_FALSE(cid_manager_.ConsumeOneConnectionId().has_value());
+
+  // CID #1 is sent to peer.
+  cid_manager_.MaybeSendNewConnectionIds();
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
+  EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
+  cid = *cid_manager_.ConsumeOneConnectionId();
+  EXPECT_EQ(cid1, cid);
+  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
+
+  // CID #0's retirement is scheduled and CID #2 is sent to peer.
+  retire_cid_frame.sequence_number = 0u;
+  cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
+                                         &error_details_);
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid0));
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid1));
+  EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
+  EXPECT_TRUE(cid_manager_.HasConnectionIdToConsume());
+  cid = *cid_manager_.ConsumeOneConnectionId();
+  EXPECT_EQ(cid2, cid);
+  EXPECT_FALSE(cid_manager_.HasConnectionIdToConsume());
+
+  clock_.AdvanceTime(connection_id_expire_timeout * 0.1);
+
+  // CID #1's retirement is scheduled and CID #3 is sent to peer.
+  retire_cid_frame.sequence_number = 1u;
+  cid_manager_.OnRetireConnectionIdFrame(retire_cid_frame, pto_delay_,
+                                         &error_details_);
+
+  {
+    // CID #0 & #1 are retired in a single alarm fire.
+    clock_.AdvanceTime(connection_id_expire_timeout);
+    testing::InSequence s;
+    EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid0));
+    EXPECT_CALL(cid_manager_visitor_, OnSelfIssuedConnectionIdRetired(cid1));
+    alarm_factory_.FireAlarm(retire_self_issued_cid_alarm_);
+    EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid0));
+    EXPECT_FALSE(cid_manager_.IsConnectionIdInUse(cid1));
+    EXPECT_TRUE(cid_manager_.IsConnectionIdInUse(cid2));
+    EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+                ElementsAre(cid2, cid3));
+    EXPECT_FALSE(retire_self_issued_cid_alarm_->IsSet());
+  }
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ErrorWhenRetireConnectionIdNeverIssued) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+
+  // CID #1 is sent to peer.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(1);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // CID #2 is never issued.
+  QuicRetireConnectionIdFrame retire_cid_frame;
+  retire_cid_frame.sequence_number = 2u;
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       ErrorWhenTooManyConnectionIdWaitingToBeRetired) {
+  // CID #0 & #1 are issued.
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_))
+      .WillOnce(Return(true));
+  cid_manager_.MaybeSendNewConnectionIds();
+
+  // Add 8 connection IDs to the to-be-retired list.
+  QuicConnectionId last_connection_id =
+      cid_manager_.GenerateNewConnectionId(initial_connection_id_);
+  for (int i = 0; i < 8; ++i) {
+    EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_));
+    EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_));
+    QuicRetireConnectionIdFrame retire_cid_frame;
+    retire_cid_frame.sequence_number = i;
+    ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                    retire_cid_frame, pto_delay_, &error_details_),
+                IsQuicNoError());
+    last_connection_id =
+        cid_manager_.GenerateNewConnectionId(last_connection_id);
+  }
+  QuicRetireConnectionIdFrame retire_cid_frame;
+  retire_cid_frame.sequence_number = 8u;
+  // This would have push the number of to-be-retired connection IDs over its
+  // limit.
+  ASSERT_THAT(cid_manager_.OnRetireConnectionIdFrame(
+                  retire_cid_frame, pto_delay_, &error_details_),
+              IsError(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE));
+}
+
+TEST_F(QuicSelfIssuedConnectionIdManagerTest,
+       DoNotIssueConnectionIdVoluntarilyIfOneHasIssuedForPerferredAddress) {
+  QuicConnectionId cid0 = initial_connection_id_;
+  QuicConnectionId cid1 = cid_manager_.GenerateNewConnectionId(cid0);
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(cid1));
+  ASSERT_THAT(cid_manager_.IssueNewConnectionIdForPreferredAddress(),
+              ExpectedNewConnectionIdFrame(cid1, 1u, 0u));
+  EXPECT_THAT(cid_manager_.GetUnretiredConnectionIds(),
+              ElementsAre(cid0, cid1));
+
+  EXPECT_CALL(cid_manager_visitor_, OnNewConnectionIdIssued(_)).Times(0);
+  EXPECT_CALL(cid_manager_visitor_, SendNewConnectionId(_)).Times(0);
+  cid_manager_.MaybeSendNewConnectionIds();
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_id_test.cc b/quiche/quic/core/quic_connection_id_test.cc
new file mode 100644
index 0000000..f421e95
--- /dev/null
+++ b/quiche/quic/core/quic_connection_id_test.cc
@@ -0,0 +1,181 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_id.h"
+
+#include <cstdint>
+#include <cstring>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace {
+
+class QuicConnectionIdTest : public QuicTest {};
+
+TEST_F(QuicConnectionIdTest, Empty) {
+  QuicConnectionId connection_id_empty = EmptyQuicConnectionId();
+  EXPECT_TRUE(connection_id_empty.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, DefaultIsEmpty) {
+  QuicConnectionId connection_id_empty = QuicConnectionId();
+  EXPECT_TRUE(connection_id_empty.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, NotEmpty) {
+  QuicConnectionId connection_id = test::TestConnectionId(1);
+  EXPECT_FALSE(connection_id.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, ZeroIsNotEmpty) {
+  QuicConnectionId connection_id = test::TestConnectionId(0);
+  EXPECT_FALSE(connection_id.IsEmpty());
+}
+
+TEST_F(QuicConnectionIdTest, Data) {
+  char connection_id_data[kQuicDefaultConnectionIdLength];
+  memset(connection_id_data, 0x42, sizeof(connection_id_data));
+  QuicConnectionId connection_id1 =
+      QuicConnectionId(connection_id_data, sizeof(connection_id_data));
+  QuicConnectionId connection_id2 =
+      QuicConnectionId(connection_id_data, sizeof(connection_id_data));
+  EXPECT_EQ(connection_id1, connection_id2);
+  EXPECT_EQ(connection_id1.length(), kQuicDefaultConnectionIdLength);
+  EXPECT_EQ(connection_id1.data(), connection_id1.mutable_data());
+  EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id2.data(),
+                      sizeof(connection_id_data)));
+  EXPECT_EQ(0, memcmp(connection_id1.data(), connection_id_data,
+                      sizeof(connection_id_data)));
+  connection_id2.mutable_data()[0] = 0x33;
+  EXPECT_NE(connection_id1, connection_id2);
+  static const uint8_t kNewLength = 4;
+  connection_id2.set_length(kNewLength);
+  EXPECT_EQ(kNewLength, connection_id2.length());
+}
+
+TEST_F(QuicConnectionIdTest, SpanData) {
+  QuicConnectionId connection_id = QuicConnectionId({0x01, 0x02, 0x03});
+  EXPECT_EQ(connection_id.length(), 3);
+  QuicConnectionId empty_connection_id =
+      QuicConnectionId(absl::Span<uint8_t>());
+  EXPECT_EQ(empty_connection_id.length(), 0);
+  QuicConnectionId connection_id2 = QuicConnectionId({
+      0x01,
+      0x02,
+      0x03,
+      0x04,
+      0x05,
+      0x06,
+      0x07,
+      0x08,
+      0x09,
+      0x0a,
+      0x0b,
+      0x0c,
+      0x0d,
+      0x0e,
+      0x0f,
+      0x10,
+  });
+  EXPECT_EQ(connection_id2.length(), 16);
+}
+
+TEST_F(QuicConnectionIdTest, DoubleConvert) {
+  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
+  QuicConnectionId connection_id64_3 =
+      test::TestConnectionId(UINT64_C(0xfedcba9876543210));
+  EXPECT_EQ(connection_id64_1,
+            test::TestConnectionId(
+                test::TestConnectionIdToUInt64(connection_id64_1)));
+  EXPECT_EQ(connection_id64_2,
+            test::TestConnectionId(
+                test::TestConnectionIdToUInt64(connection_id64_2)));
+  EXPECT_EQ(connection_id64_3,
+            test::TestConnectionId(
+                test::TestConnectionIdToUInt64(connection_id64_3)));
+  EXPECT_NE(connection_id64_1, connection_id64_2);
+  EXPECT_NE(connection_id64_1, connection_id64_3);
+  EXPECT_NE(connection_id64_2, connection_id64_3);
+}
+
+TEST_F(QuicConnectionIdTest, Hash) {
+  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_1b = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_2 = test::TestConnectionId(42);
+  QuicConnectionId connection_id64_3 =
+      test::TestConnectionId(UINT64_C(0xfedcba9876543210));
+  EXPECT_EQ(connection_id64_1.Hash(), connection_id64_1b.Hash());
+  EXPECT_NE(connection_id64_1.Hash(), connection_id64_2.Hash());
+  EXPECT_NE(connection_id64_1.Hash(), connection_id64_3.Hash());
+  EXPECT_NE(connection_id64_2.Hash(), connection_id64_3.Hash());
+
+  // Verify that any two all-zero connection IDs of different lengths never
+  // have the same hash.
+  const char connection_id_bytes[255] = {};
+  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
+    QuicConnectionId connection_id_i(connection_id_bytes, i);
+    for (uint8_t j = i + 1; j < sizeof(connection_id_bytes); ++j) {
+      QuicConnectionId connection_id_j(connection_id_bytes, j);
+      EXPECT_NE(connection_id_i.Hash(), connection_id_j.Hash());
+    }
+  }
+}
+
+TEST_F(QuicConnectionIdTest, AssignAndCopy) {
+  QuicConnectionId connection_id = test::TestConnectionId(1);
+  QuicConnectionId connection_id2 = test::TestConnectionId(2);
+  connection_id = connection_id2;
+  EXPECT_EQ(connection_id, test::TestConnectionId(2));
+  EXPECT_NE(connection_id, test::TestConnectionId(1));
+  connection_id = QuicConnectionId(test::TestConnectionId(1));
+  EXPECT_EQ(connection_id, test::TestConnectionId(1));
+  EXPECT_NE(connection_id, test::TestConnectionId(2));
+}
+
+TEST_F(QuicConnectionIdTest, ChangeLength) {
+  QuicConnectionId connection_id64_1 = test::TestConnectionId(1);
+  QuicConnectionId connection_id64_2 = test::TestConnectionId(2);
+  QuicConnectionId connection_id136_2 = test::TestConnectionId(2);
+  connection_id136_2.set_length(17);
+  memset(connection_id136_2.mutable_data() + 8, 0, 9);
+  char connection_id136_2_bytes[17] = {0, 0, 0, 0, 0, 0, 0, 2, 0,
+                                       0, 0, 0, 0, 0, 0, 0, 0};
+  QuicConnectionId connection_id136_2b(connection_id136_2_bytes,
+                                       sizeof(connection_id136_2_bytes));
+  EXPECT_EQ(connection_id136_2, connection_id136_2b);
+  QuicConnectionId connection_id = connection_id64_1;
+  connection_id.set_length(17);
+  EXPECT_NE(connection_id64_1, connection_id);
+  // Check resizing big to small.
+  connection_id.set_length(8);
+  EXPECT_EQ(connection_id64_1, connection_id);
+  // Check resizing small to big.
+  connection_id.set_length(17);
+  memset(connection_id.mutable_data(), 0, connection_id.length());
+  memcpy(connection_id.mutable_data(), connection_id64_2.data(),
+         connection_id64_2.length());
+  EXPECT_EQ(connection_id136_2, connection_id);
+  EXPECT_EQ(connection_id136_2b, connection_id);
+  QuicConnectionId connection_id120(connection_id136_2_bytes, 15);
+  connection_id.set_length(15);
+  EXPECT_EQ(connection_id120, connection_id);
+  // Check resizing big to big.
+  QuicConnectionId connection_id2 = connection_id120;
+  connection_id2.set_length(17);
+  connection_id2.mutable_data()[15] = 0;
+  connection_id2.mutable_data()[16] = 0;
+  EXPECT_EQ(connection_id136_2, connection_id2);
+  EXPECT_EQ(connection_id136_2b, connection_id2);
+}
+
+}  // namespace
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_stats.cc b/quiche/quic/core/quic_connection_stats.cc
new file mode 100644
index 0000000..bb53ca5
--- /dev/null
+++ b/quiche/quic/core/quic_connection_stats.cc
@@ -0,0 +1,72 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection_stats.h"
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os, const QuicConnectionStats& s) {
+  os << "{ bytes_sent: " << s.bytes_sent;
+  os << " packets_sent: " << s.packets_sent;
+  os << " stream_bytes_sent: " << s.stream_bytes_sent;
+  os << " packets_discarded: " << s.packets_discarded;
+  os << " bytes_received: " << s.bytes_received;
+  os << " packets_received: " << s.packets_received;
+  os << " packets_processed: " << s.packets_processed;
+  os << " stream_bytes_received: " << s.stream_bytes_received;
+  os << " bytes_retransmitted: " << s.bytes_retransmitted;
+  os << " packets_retransmitted: " << s.packets_retransmitted;
+  os << " bytes_spuriously_retransmitted: " << s.bytes_spuriously_retransmitted;
+  os << " packets_spuriously_retransmitted: "
+     << s.packets_spuriously_retransmitted;
+  os << " packets_lost: " << s.packets_lost;
+  os << " slowstart_packets_sent: " << s.slowstart_packets_sent;
+  os << " slowstart_packets_lost: " << s.slowstart_packets_lost;
+  os << " slowstart_bytes_lost: " << s.slowstart_bytes_lost;
+  os << " packets_dropped: " << s.packets_dropped;
+  os << " undecryptable_packets_received_before_handshake_complete: "
+     << s.undecryptable_packets_received_before_handshake_complete;
+  os << " crypto_retransmit_count: " << s.crypto_retransmit_count;
+  os << " loss_timeout_count: " << s.loss_timeout_count;
+  os << " tlp_count: " << s.tlp_count;
+  os << " rto_count: " << s.rto_count;
+  os << " pto_count: " << s.pto_count;
+  os << " min_rtt_us: " << s.min_rtt_us;
+  os << " srtt_us: " << s.srtt_us;
+  os << " egress_mtu: " << s.egress_mtu;
+  os << " max_egress_mtu: " << s.max_egress_mtu;
+  os << " ingress_mtu: " << s.ingress_mtu;
+  os << " estimated_bandwidth: " << s.estimated_bandwidth;
+  os << " packets_reordered: " << s.packets_reordered;
+  os << " max_sequence_reordering: " << s.max_sequence_reordering;
+  os << " max_time_reordering_us: " << s.max_time_reordering_us;
+  os << " tcp_loss_events: " << s.tcp_loss_events;
+  os << " connection_creation_time: "
+     << s.connection_creation_time.ToDebuggingValue();
+  os << " blocked_frames_received: " << s.blocked_frames_received;
+  os << " blocked_frames_sent: " << s.blocked_frames_sent;
+  os << " num_connectivity_probing_received: "
+     << s.num_connectivity_probing_received;
+  os << " retry_packet_processed: "
+     << (s.retry_packet_processed ? "yes" : "no");
+  os << " num_coalesced_packets_received: " << s.num_coalesced_packets_received;
+  os << " num_coalesced_packets_processed: "
+     << s.num_coalesced_packets_processed;
+  os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs;
+  os << " sent_legacy_version_encapsulated_packets: "
+     << s.sent_legacy_version_encapsulated_packets;
+  os << " key_update_count: " << s.key_update_count;
+  os << " num_failed_authentication_packets_received: "
+     << s.num_failed_authentication_packets_received;
+  os << " num_tls_server_zero_rtt_packets_received_after_discarding_decrypter: "
+     << s.num_tls_server_zero_rtt_packets_received_after_discarding_decrypter;
+  os << " address_validated_via_decrypting_packet: "
+     << s.address_validated_via_decrypting_packet;
+  os << " address_validated_via_token: " << s.address_validated_via_token;
+  os << " }";
+
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_connection_stats.h b/quiche/quic/core/quic_connection_stats.h
new file mode 100644
index 0000000..46ccf3e
--- /dev/null
+++ b/quiche/quic/core/quic_connection_stats.h
@@ -0,0 +1,241 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
+#define QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Structure to hold stats for a QuicConnection.
+struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConnectionStats& s);
+
+  QuicByteCount bytes_sent = 0;  // Includes retransmissions.
+  QuicPacketCount packets_sent = 0;
+  // Non-retransmitted bytes sent in a stream frame.
+  QuicByteCount stream_bytes_sent = 0;
+  // Packets serialized and discarded before sending.
+  QuicPacketCount packets_discarded = 0;
+
+  // These include version negotiation and public reset packets, which do not
+  // have packet numbers or frame data.
+  QuicByteCount bytes_received = 0;  // Includes duplicate data for a stream.
+  // Includes packets which were not processable.
+  QuicPacketCount packets_received = 0;
+  // Excludes packets which were not processable.
+  QuicPacketCount packets_processed = 0;
+  QuicByteCount stream_bytes_received = 0;  // Bytes received in a stream frame.
+
+  QuicByteCount bytes_retransmitted = 0;
+  QuicPacketCount packets_retransmitted = 0;
+
+  QuicByteCount bytes_spuriously_retransmitted = 0;
+  QuicPacketCount packets_spuriously_retransmitted = 0;
+  // Number of packets abandoned as lost by the loss detection algorithm.
+  QuicPacketCount packets_lost = 0;
+  QuicPacketCount packet_spuriously_detected_lost = 0;
+
+  // The sum of loss detection response times of all lost packets, in number of
+  // round trips.
+  // Given a packet detected as lost:
+  //   T(S)                            T(1Rtt)    T(D)
+  //     |_________________________________|_______|
+  // Where
+  //   T(S) is the time when the packet is sent.
+  //   T(1Rtt) is one rtt after T(S), using the rtt at the time of detection.
+  //   T(D) is the time of detection, i.e. when the packet is declared as lost.
+  // The loss detection response time is defined as
+  //     (T(D) - T(S)) / (T(1Rtt) - T(S))
+  //
+  // The average loss detection response time is this number divided by
+  // |packets_lost|. Smaller result means detection is faster.
+  float total_loss_detection_response_time = 0.0;
+
+  // Number of times this connection went through the slow start phase.
+  uint32_t slowstart_count = 0;
+  // Number of round trips spent in slow start.
+  uint32_t slowstart_num_rtts = 0;
+  // Number of packets sent in slow start.
+  QuicPacketCount slowstart_packets_sent = 0;
+  // Number of bytes sent in slow start.
+  QuicByteCount slowstart_bytes_sent = 0;
+  // Number of packets lost exiting slow start.
+  QuicPacketCount slowstart_packets_lost = 0;
+  // Number of bytes lost exiting slow start.
+  QuicByteCount slowstart_bytes_lost = 0;
+  // Time spent in slow start. Populated for BBRv1 and BBRv2.
+  QuicTimeAccumulator slowstart_duration;
+
+  // Number of PROBE_BW cycles. Populated for BBRv1 and BBRv2.
+  uint32_t bbr_num_cycles = 0;
+  // Number of PROBE_BW cycles shortened for reno coexistence. BBRv2 only.
+  uint32_t bbr_num_short_cycles_for_reno_coexistence = 0;
+  // Whether BBR exited STARTUP due to excessive loss. Populated for BBRv1 and
+  // BBRv2.
+  bool bbr_exit_startup_due_to_loss = false;
+
+  QuicPacketCount packets_dropped = 0;  // Duplicate or less than least unacked.
+
+  // Packets that failed to decrypt when they were first received,
+  // before the handshake was complete.
+  QuicPacketCount undecryptable_packets_received_before_handshake_complete = 0;
+
+  size_t crypto_retransmit_count = 0;
+  // Count of times the loss detection alarm fired.  At least one packet should
+  // be lost when the alarm fires.
+  size_t loss_timeout_count = 0;
+  size_t tlp_count = 0;
+  size_t rto_count = 0;  // Count of times the rto timer fired.
+  size_t pto_count = 0;
+
+  int64_t min_rtt_us = 0;  // Minimum RTT in microseconds.
+  int64_t srtt_us = 0;     // Smoothed RTT in microseconds.
+  int64_t cwnd_bootstrapping_rtt_us = 0;  // RTT used in cwnd_bootstrapping.
+  // The connection's |long_term_mtu_| used for sending packets, populated by
+  // QuicConnection::GetStats().
+  QuicByteCount egress_mtu = 0;
+  // The maximum |long_term_mtu_| the connection ever used.
+  QuicByteCount max_egress_mtu = 0;
+  // Size of the largest packet received from the peer, populated by
+  // QuicConnection::GetStats().
+  QuicByteCount ingress_mtu = 0;
+  QuicBandwidth estimated_bandwidth = QuicBandwidth::Zero();
+
+  // Reordering stats for received packets.
+  // Number of packets received out of packet number order.
+  QuicPacketCount packets_reordered = 0;
+  // Maximum reordering observed in packet number space.
+  QuicPacketCount max_sequence_reordering = 0;
+  // Maximum reordering observed in microseconds
+  int64_t max_time_reordering_us = 0;
+
+  // Maximum sequence reordering observed from acked packets.
+  QuicPacketCount sent_packets_max_sequence_reordering = 0;
+  // Number of times that a packet is not detected as lost per reordering_shift,
+  // but would have been if the reordering_shift increases by one.
+  QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
+
+  // The following stats are used only in TcpCubicSender.
+  // The number of loss events from TCP's perspective.  Each loss event includes
+  // one or more lost packets.
+  uint32_t tcp_loss_events = 0;
+
+  // Creation time, as reported by the QuicClock.
+  QuicTime connection_creation_time = QuicTime::Zero();
+
+  // Handshake completion time.
+  QuicTime handshake_completion_time = QuicTime::Zero();
+
+  uint64_t blocked_frames_received = 0;
+  uint64_t blocked_frames_sent = 0;
+
+  // Number of connectivity probing packets received by this connection.
+  uint64_t num_connectivity_probing_received = 0;
+
+  // Whether a RETRY packet was successfully processed.
+  bool retry_packet_processed = false;
+
+  // Number of received coalesced packets.
+  uint64_t num_coalesced_packets_received = 0;
+  // Number of successfully processed coalesced packets.
+  uint64_t num_coalesced_packets_processed = 0;
+  // Number of ack aggregation epochs. For the same number of bytes acked, the
+  // smaller this value, the more ack aggregation is going on.
+  uint64_t num_ack_aggregation_epochs = 0;
+
+  // Whether overshooting is detected (and pacing rate decreases) during start
+  // up with network parameters adjusted.
+  bool overshooting_detected_with_network_parameters_adjusted = false;
+
+  // Whether there is any non app-limited bandwidth sample.
+  bool has_non_app_limited_sample = false;
+
+  // Packet number of first decrypted packet.
+  QuicPacketNumber first_decrypted_packet;
+
+  // Max consecutive retransmission timeout before making forward progress.
+  size_t max_consecutive_rto_with_forward_progress = 0;
+
+  // Number of sent packets that were encapsulated using Legacy Version
+  // Encapsulation.
+  QuicPacketCount sent_legacy_version_encapsulated_packets = 0;
+
+  // Number of times when the connection tries to send data but gets throttled
+  // by amplification factor.
+  size_t num_amplification_throttling = 0;
+
+  // Number of key phase updates that have occurred. In the case of a locally
+  // initiated key update, this is incremented when the keys are updated, before
+  // the peer has acknowledged the key update.
+  uint32_t key_update_count = 0;
+
+  // Counts the number of undecryptable packets received across all keys. Does
+  // not include packets where a decryption key for that level was absent.
+  QuicPacketCount num_failed_authentication_packets_received = 0;
+
+  // Counts the number of QUIC+TLS 0-RTT packets received after 0-RTT decrypter
+  // was discarded, only on server connections.
+  QuicPacketCount
+      num_tls_server_zero_rtt_packets_received_after_discarding_decrypter = 0;
+
+  // True if address is validated via decrypting HANDSHAKE or 1-RTT packet.
+  bool address_validated_via_decrypting_packet = false;
+
+  // True if address is validated via validating token received in INITIAL
+  // packet.
+  bool address_validated_via_token = false;
+
+  size_t ping_frames_sent = 0;
+
+  // Number of detected peer address changes which changes to a peer address
+  // validated by earlier path validation.
+  size_t num_peer_migration_to_proactively_validated_address = 0;
+  // Number of detected peer address changes which triggers reverse path
+  // validation.
+  size_t num_reverse_path_validtion_upon_migration = 0;
+  // Number of detected peer migrations which either succeed reverse path
+  // validation or no need to be validated.
+  size_t num_validated_peer_migration = 0;
+  // Number of detected peer migrations which triggered reverse path validation
+  // and failed and fell back to the old path.
+  size_t num_invalid_peer_migration = 0;
+  // Number of detected peer migrations which triggered reverse path validation
+  // which was canceled because the peer migrated again. Such migration is also
+  // counted as invalid peer migration.
+  size_t num_peer_migration_while_validating_default_path = 0;
+  // Number of NEW_CONNECTION_ID frames sent.
+  size_t num_new_connection_id_sent = 0;
+  // Number of RETIRE_CONNECTION_ID frames sent.
+  size_t num_retire_connection_id_sent = 0;
+
+  struct QUIC_NO_EXPORT TlsServerOperationStats {
+    bool success = false;
+    // If the operation is performed asynchronously, how long did it take.
+    // Zero() for synchronous operations.
+    QuicTime::Delta async_latency = QuicTime::Delta::Zero();
+  };
+
+  // The TLS server op stats only have values when the corresponding operation
+  // is performed by TlsServerHandshaker. If an operation is done within
+  // BoringSSL, e.g. ticket decrypted without using
+  // TlsServerHandshaker::SessionTicketOpen, it will not be recorded here.
+  absl::optional<TlsServerOperationStats> tls_server_select_cert_stats;
+  absl::optional<TlsServerOperationStats> tls_server_compute_signature_stats;
+  absl::optional<TlsServerOperationStats> tls_server_decrypt_ticket_stats;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_STATS_H_
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
new file mode 100644
index 0000000..1311afe
--- /dev/null
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -0,0 +1,15834 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_connection.h"
+
+#include <errno.h>
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/frames/quic_connection_close_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_path_response_frame.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_coalesced_packet_peer.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+#include "quiche/quic/test_tools/quic_path_validator_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+#include "quiche/quic/test_tools/simple_session_notifier.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::DoAll;
+using testing::ElementsAre;
+using testing::Ge;
+using testing::IgnoreResult;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Lt;
+using testing::Ref;
+using testing::Return;
+using testing::SaveArg;
+using testing::SetArgPointee;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char data1[] = "foo data";
+const char data2[] = "bar data";
+
+const bool kHasStopWaiting = true;
+
+const int kDefaultRetransmissionTimeMs = 500;
+
+DiversificationNonce kTestDiversificationNonce = {
+    'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a',
+    'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
+    'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b',
+};
+
+const StatelessResetToken kTestStatelessResetToken{
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
+
+const QuicSocketAddress kPeerAddress =
+    QuicSocketAddress(QuicIpAddress::Loopback6(),
+                      /*port=*/12345);
+const QuicSocketAddress kSelfAddress =
+    QuicSocketAddress(QuicIpAddress::Loopback6(),
+                      /*port=*/443);
+
+QuicStreamId GetNthClientInitiatedStreamId(int n,
+                                           QuicTransportVersion version) {
+  return QuicUtils::GetFirstBidirectionalStreamId(version,
+                                                  Perspective::IS_CLIENT) +
+         n * 2;
+}
+
+QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return INITIAL;
+    case ENCRYPTION_HANDSHAKE:
+      return HANDSHAKE;
+    case ENCRYPTION_ZERO_RTT:
+      return ZERO_RTT_PROTECTED;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUICHE_DCHECK(false);
+      return INVALID_PACKET_TYPE;
+    default:
+      QUICHE_DCHECK(false);
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+// A NullEncrypterWithConfidentialityLimit is a NullEncrypter that allows
+// specifying the confidentiality limit on the maximum number of packets that
+// may be encrypted per key phase in TLS+QUIC.
+class NullEncrypterWithConfidentialityLimit : public NullEncrypter {
+ public:
+  NullEncrypterWithConfidentialityLimit(Perspective perspective,
+                                        QuicPacketCount confidentiality_limit)
+      : NullEncrypter(perspective),
+        confidentiality_limit_(confidentiality_limit) {}
+
+  QuicPacketCount GetConfidentialityLimit() const override {
+    return confidentiality_limit_;
+  }
+
+ private:
+  QuicPacketCount confidentiality_limit_;
+};
+
+class StrictTaggingDecrypterWithIntegrityLimit : public StrictTaggingDecrypter {
+ public:
+  StrictTaggingDecrypterWithIntegrityLimit(uint8_t tag,
+                                           QuicPacketCount integrity_limit)
+      : StrictTaggingDecrypter(tag), integrity_limit_(integrity_limit) {}
+
+  QuicPacketCount GetIntegrityLimit() const override {
+    return integrity_limit_;
+  }
+
+ private:
+  QuicPacketCount integrity_limit_;
+};
+
+class TestConnectionHelper : public QuicConnectionHelperInterface {
+ public:
+  TestConnectionHelper(MockClock* clock, MockRandom* random_generator)
+      : clock_(clock), random_generator_(random_generator) {
+    clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+  TestConnectionHelper(const TestConnectionHelper&) = delete;
+  TestConnectionHelper& operator=(const TestConnectionHelper&) = delete;
+
+  // QuicConnectionHelperInterface
+  const QuicClock* GetClock() const override { return clock_; }
+
+  QuicRandom* GetRandomGenerator() override { return random_generator_; }
+
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override {
+    return &buffer_allocator_;
+  }
+
+ private:
+  MockClock* clock_;
+  MockRandom* random_generator_;
+  quiche::SimpleBufferAllocator buffer_allocator_;
+};
+
+class TestConnection : public QuicConnection {
+ public:
+  TestConnection(QuicConnectionId connection_id,
+                 QuicSocketAddress initial_self_address,
+                 QuicSocketAddress initial_peer_address,
+                 TestConnectionHelper* helper, TestAlarmFactory* alarm_factory,
+                 TestPacketWriter* writer, Perspective perspective,
+                 ParsedQuicVersion version)
+      : QuicConnection(connection_id, initial_self_address,
+                       initial_peer_address, helper, alarm_factory, writer,
+                       /* owns_writer= */ false, perspective,
+                       SupportedVersions(version)),
+        notifier_(nullptr) {
+    writer->set_perspective(perspective);
+    SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                 std::make_unique<NullEncrypter>(perspective));
+    SetDataProducer(&producer_);
+    ON_CALL(*this, OnSerializedPacket(_))
+        .WillByDefault([this](SerializedPacket packet) {
+          QuicConnection::OnSerializedPacket(std::move(packet));
+        });
+  }
+  TestConnection(const TestConnection&) = delete;
+  TestConnection& operator=(const TestConnection&) = delete;
+
+  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket packet), (override));
+
+  void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
+    QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
+  }
+
+  void SetLossAlgorithm(LossDetectionInterface* loss_algorithm) {
+    QuicConnectionPeer::SetLossAlgorithm(this, loss_algorithm);
+  }
+
+  void SendPacket(EncryptionLevel /*level*/, uint64_t packet_number,
+                  std::unique_ptr<QuicPacket> packet,
+                  HasRetransmittableData retransmittable, bool has_ack,
+                  bool has_pending_frames) {
+    ScopedPacketFlusher flusher(this);
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        QuicConnectionPeer::GetFramer(this)->EncryptPayload(
+            ENCRYPTION_INITIAL, QuicPacketNumber(packet_number), *packet,
+            buffer, kMaxOutgoingPacketSize);
+    SerializedPacket serialized_packet(
+        QuicPacketNumber(packet_number), PACKET_4BYTE_PACKET_NUMBER, buffer,
+        encrypted_length, has_ack, has_pending_frames);
+    serialized_packet.peer_address = kPeerAddress;
+    if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
+      serialized_packet.retransmittable_frames.push_back(
+          QuicFrame(QuicPingFrame()));
+    }
+    OnSerializedPacket(std::move(serialized_packet));
+  }
+
+  QuicConsumedData SaveAndSendStreamData(QuicStreamId id,
+                                         absl::string_view data,
+                                         QuicStreamOffset offset,
+                                         StreamSendingState state) {
+    ScopedPacketFlusher flusher(this);
+    producer_.SaveStreamData(id, data);
+    if (notifier_ != nullptr) {
+      return notifier_->WriteOrBufferData(id, data.length(), state);
+    }
+    return QuicConnection::SendStreamData(id, data.length(), offset, state);
+  }
+
+  QuicConsumedData SendStreamDataWithString(QuicStreamId id,
+                                            absl::string_view data,
+                                            QuicStreamOffset offset,
+                                            StreamSendingState state) {
+    ScopedPacketFlusher flusher(this);
+    if (!QuicUtils::IsCryptoStreamId(transport_version(), id) &&
+        this->encryption_level() == ENCRYPTION_INITIAL) {
+      this->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+      if (perspective() == Perspective::IS_CLIENT && !IsHandshakeComplete()) {
+        OnHandshakeComplete();
+      }
+      if (version().SupportsAntiAmplificationLimit()) {
+        QuicConnectionPeer::SetAddressValidated(this);
+      }
+    }
+    return SaveAndSendStreamData(id, data, offset, state);
+  }
+
+  QuicConsumedData SendApplicationDataAtLevel(EncryptionLevel encryption_level,
+                                              QuicStreamId id,
+                                              absl::string_view data,
+                                              QuicStreamOffset offset,
+                                              StreamSendingState state) {
+    ScopedPacketFlusher flusher(this);
+    QUICHE_DCHECK(encryption_level >= ENCRYPTION_ZERO_RTT);
+    SetEncrypter(encryption_level, std::make_unique<TaggingEncrypter>(0x01));
+    SetDefaultEncryptionLevel(encryption_level);
+    return SaveAndSendStreamData(id, data, offset, state);
+  }
+
+  QuicConsumedData SendStreamData3() {
+    return SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, transport_version()), "food", 0,
+        NO_FIN);
+  }
+
+  QuicConsumedData SendStreamData5() {
+    return SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(2, transport_version()), "food2", 0,
+        NO_FIN);
+  }
+
+  // Ensures the connection can write stream data before writing.
+  QuicConsumedData EnsureWritableAndSendStreamData5() {
+    EXPECT_TRUE(CanWrite(HAS_RETRANSMITTABLE_DATA));
+    return SendStreamData5();
+  }
+
+  // The crypto stream has special semantics so that it is not blocked by a
+  // congestion window limitation, and also so that it gets put into a separate
+  // packet (so that it is easier to reason about a crypto frame not being
+  // split needlessly across packet boundaries).  As a result, we have separate
+  // tests for some cases for this stream.
+  QuicConsumedData SendCryptoStreamData() {
+    QuicStreamOffset offset = 0;
+    absl::string_view data("chlo");
+    if (!QuicVersionUsesCryptoFrames(transport_version())) {
+      return SendCryptoDataWithString(data, offset);
+    }
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, offset, data);
+    size_t bytes_written;
+    if (notifier_) {
+      bytes_written =
+          notifier_->WriteCryptoData(ENCRYPTION_INITIAL, data.length(), offset);
+    } else {
+      bytes_written = QuicConnection::SendCryptoData(ENCRYPTION_INITIAL,
+                                                     data.length(), offset);
+    }
+    return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
+  }
+
+  QuicConsumedData SendCryptoDataWithString(absl::string_view data,
+                                            QuicStreamOffset offset) {
+    return SendCryptoDataWithString(data, offset, ENCRYPTION_INITIAL);
+  }
+
+  QuicConsumedData SendCryptoDataWithString(absl::string_view data,
+                                            QuicStreamOffset offset,
+                                            EncryptionLevel encryption_level) {
+    if (!QuicVersionUsesCryptoFrames(transport_version())) {
+      return SendStreamDataWithString(
+          QuicUtils::GetCryptoStreamId(transport_version()), data, offset,
+          NO_FIN);
+    }
+    producer_.SaveCryptoData(encryption_level, offset, data);
+    size_t bytes_written;
+    if (notifier_) {
+      bytes_written =
+          notifier_->WriteCryptoData(encryption_level, data.length(), offset);
+    } else {
+      bytes_written = QuicConnection::SendCryptoData(encryption_level,
+                                                     data.length(), offset);
+    }
+    return QuicConsumedData(bytes_written, /*fin_consumed*/ false);
+  }
+
+  void set_version(ParsedQuicVersion version) {
+    QuicConnectionPeer::GetFramer(this)->set_version(version);
+  }
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    QuicConnectionPeer::GetFramer(this)->SetSupportedVersions(versions);
+    writer()->SetSupportedVersions(versions);
+  }
+
+  // This should be called before setting customized encrypters/decrypters for
+  // connection and peer creator.
+  void set_perspective(Perspective perspective) {
+    writer()->set_perspective(perspective);
+    QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(this);
+    QuicConnectionPeer::SetPerspective(this, perspective);
+    QuicSentPacketManagerPeer::SetPerspective(
+        QuicConnectionPeer::GetSentPacketManager(this), perspective);
+    QuicConnectionPeer::GetFramer(this)->SetInitialObfuscators(
+        TestConnectionId());
+    for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
+                                  ENCRYPTION_FORWARD_SECURE}) {
+      if (QuicConnectionPeer::GetFramer(this)->HasEncrypterOfEncryptionLevel(
+              level)) {
+        SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
+      }
+      if (QuicConnectionPeer::GetFramer(this)->HasDecrypterOfEncryptionLevel(
+              level)) {
+        InstallDecrypter(level, std::make_unique<NullDecrypter>(perspective));
+      }
+    }
+  }
+
+  // Enable path MTU discovery.  Assumes that the test is performed from the
+  // server perspective and the higher value of MTU target is used.
+  void EnablePathMtuDiscovery(MockSendAlgorithm* send_algorithm) {
+    ASSERT_EQ(Perspective::IS_SERVER, perspective());
+
+    if (GetQuicReloadableFlag(quic_enable_mtu_discovery_at_server)) {
+      OnConfigNegotiated();
+    } else {
+      QuicConfig config;
+      QuicTagVector connection_options;
+      connection_options.push_back(kMTUH);
+      config.SetInitialReceivedConnectionOptions(connection_options);
+      EXPECT_CALL(*send_algorithm, SetFromConfig(_, _));
+      SetFromConfig(config);
+    }
+
+    // Normally, the pacing would be disabled in the test, but calling
+    // SetFromConfig enables it.  Set nearly-infinite bandwidth to make the
+    // pacing algorithm work.
+    EXPECT_CALL(*send_algorithm, PacingRate(_))
+        .WillRepeatedly(Return(QuicBandwidth::Infinite()));
+  }
+
+  TestAlarmFactory::TestAlarm* GetAckAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetAckAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetPingAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetPingAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetRetransmissionAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetRetransmissionAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetSendAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetSendAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetTimeoutAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetIdleNetworkDetectorAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetMtuDiscoveryAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetProcessUndecryptablePacketsAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetDiscardPreviousOneRttKeysAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetDiscardZeroRttDecryptionKeysAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetBlackholeDetectorAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetBlackholeDetectorAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetRetirePeerIssuedConnectionIdAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(this));
+  }
+
+  TestAlarmFactory::TestAlarm* GetRetireSelfIssuedConnectionIdAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(this));
+  }
+
+  void PathDegradingTimeout() {
+    QUICHE_DCHECK(PathDegradingDetectionInProgress());
+    GetBlackholeDetectorAlarm()->Fire();
+  }
+
+  bool PathDegradingDetectionInProgress() {
+    return QuicConnectionPeer::GetPathDegradingDeadline(this).IsInitialized();
+  }
+
+  bool BlackholeDetectionInProgress() {
+    return QuicConnectionPeer::GetBlackholeDetectionDeadline(this)
+        .IsInitialized();
+  }
+
+  bool PathMtuReductionDetectionInProgress() {
+    return QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(this)
+        .IsInitialized();
+  }
+
+  void SetMaxTailLossProbes(size_t max_tail_loss_probes) {
+    QuicSentPacketManagerPeer::SetMaxTailLossProbes(
+        QuicConnectionPeer::GetSentPacketManager(this), max_tail_loss_probes);
+  }
+
+  QuicByteCount GetBytesInFlight() {
+    return QuicConnectionPeer::GetSentPacketManager(this)->GetBytesInFlight();
+  }
+
+  void set_notifier(SimpleSessionNotifier* notifier) { notifier_ = notifier; }
+
+  void ReturnEffectivePeerAddressForNextPacket(const QuicSocketAddress& addr) {
+    next_effective_peer_addr_ = std::make_unique<QuicSocketAddress>(addr);
+  }
+
+  bool PtoEnabled() {
+    if (QuicConnectionPeer::GetSentPacketManager(this)->pto_enabled()) {
+      // TLP/RTO related tests are stale when PTO is enabled.
+      QUICHE_DCHECK(PROTOCOL_TLS1_3 == version().handshake_protocol ||
+                    GetQuicRestartFlag(quic_default_on_pto2));
+      return true;
+    }
+    return false;
+  }
+
+  void SendOrQueuePacket(SerializedPacket packet) override {
+    QuicConnection::SendOrQueuePacket(std::move(packet));
+    self_address_on_default_path_while_sending_packet_ = self_address();
+  }
+
+  QuicSocketAddress self_address_on_default_path_while_sending_packet() {
+    return self_address_on_default_path_while_sending_packet_;
+  }
+
+  SimpleDataProducer* producer() { return &producer_; }
+
+  using QuicConnection::active_effective_peer_migration_type;
+  using QuicConnection::IsCurrentPacketConnectivityProbing;
+  using QuicConnection::SelectMutualVersion;
+  using QuicConnection::SendProbingRetransmissions;
+  using QuicConnection::set_defer_send_in_response_to_packets;
+
+ protected:
+  QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const override {
+    if (next_effective_peer_addr_) {
+      return *std::move(next_effective_peer_addr_);
+    }
+    return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
+  }
+
+ private:
+  TestPacketWriter* writer() {
+    return static_cast<TestPacketWriter*>(QuicConnection::writer());
+  }
+
+  SimpleDataProducer producer_;
+
+  SimpleSessionNotifier* notifier_;
+
+  std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_;
+
+  QuicSocketAddress self_address_on_default_path_while_sending_packet_;
+};
+
+enum class AckResponse { kDefer, kImmediate };
+
+// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
+struct TestParams {
+  TestParams(ParsedQuicVersion version, AckResponse ack_response,
+             bool no_stop_waiting)
+      : version(version),
+        ack_response(ack_response),
+        no_stop_waiting(no_stop_waiting) {}
+
+  ParsedQuicVersion version;
+  AckResponse ack_response;
+  bool no_stop_waiting;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.ack_response == AckResponse::kDefer ? "defer" : "immediate"), "_",
+      (p.no_stop_waiting ? "No" : ""), "StopWaiting");
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  QuicFlagSaver flags;
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    for (AckResponse ack_response :
+         {AckResponse::kDefer, AckResponse::kImmediate}) {
+      params.push_back(
+          TestParams(all_supported_versions[i], ack_response, true));
+      if (!all_supported_versions[i].HasIetfInvariantHeader()) {
+        params.push_back(
+            TestParams(all_supported_versions[i], ack_response, false));
+      }
+    }
+  }
+  return params;
+}
+
+class QuicConnectionTest : public QuicTestWithParam<TestParams> {
+ public:
+  // For tests that do silent connection closes, no such packet is generated. In
+  // order to verify the contents of the OnConnectionClosed upcall, EXPECTs
+  // should invoke this method, saving the frame, and then the test can verify
+  // the contents.
+  void SaveConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+                                ConnectionCloseSource /*source*/) {
+    saved_connection_close_frame_ = frame;
+    connection_close_frame_count_++;
+  }
+
+ protected:
+  QuicConnectionTest()
+      : connection_id_(TestConnectionId()),
+        framer_(SupportedVersions(version()), QuicTime::Zero(),
+                Perspective::IS_CLIENT, connection_id_.length()),
+        send_algorithm_(new StrictMock<MockSendAlgorithm>),
+        loss_algorithm_(new MockLossAlgorithm()),
+        helper_(new TestConnectionHelper(&clock_, &random_generator_)),
+        alarm_factory_(new TestAlarmFactory()),
+        peer_framer_(SupportedVersions(version()), QuicTime::Zero(),
+                     Perspective::IS_SERVER, connection_id_.length()),
+        peer_creator_(connection_id_, &peer_framer_,
+                      /*delegate=*/nullptr),
+        writer_(
+            new TestPacketWriter(version(), &clock_, Perspective::IS_CLIENT)),
+        connection_(connection_id_, kSelfAddress, kPeerAddress, helper_.get(),
+                    alarm_factory_.get(), writer_.get(), Perspective::IS_CLIENT,
+                    version()),
+        creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
+        manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
+        frame1_(0, false, 0, absl::string_view(data1)),
+        frame2_(0, false, 3, absl::string_view(data2)),
+        crypto_frame_(ENCRYPTION_INITIAL, 0, absl::string_view(data1)),
+        packet_number_length_(PACKET_4BYTE_PACKET_NUMBER),
+        connection_id_included_(CONNECTION_ID_PRESENT),
+        notifier_(&connection_),
+        connection_close_frame_count_(0) {
+    QUIC_DVLOG(2) << "QuicConnectionTest(" << PrintToString(GetParam()) << ")";
+    connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
+                                                      AckResponse::kDefer);
+    framer_.SetInitialObfuscators(TestConnectionId());
+    connection_.InstallInitialCrypters(TestConnectionId());
+    CrypterPair crypters;
+    CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version(),
+                                          TestConnectionId(), &crypters);
+    peer_creator_.SetEncrypter(ENCRYPTION_INITIAL,
+                               std::move(crypters.encrypter));
+    if (version().KnowsWhichDecrypterToUse()) {
+      peer_framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+                                    std::move(crypters.decrypter));
+    } else {
+      peer_framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                                std::move(crypters.decrypter));
+    }
+    for (EncryptionLevel level :
+         {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
+      peer_creator_.SetEncrypter(
+          level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
+    }
+    QuicFramerPeer::SetLastSerializedServerConnectionId(
+        QuicConnectionPeer::GetFramer(&connection_), connection_id_);
+    QuicFramerPeer::SetLastWrittenPacketNumberLength(
+        QuicConnectionPeer::GetFramer(&connection_), packet_number_length_);
+    if (version().HasIetfInvariantHeader()) {
+      EXPECT_TRUE(QuicConnectionPeer::GetNoStopWaitingFrames(&connection_));
+    } else {
+      QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
+                                                 GetParam().no_stop_waiting);
+    }
+    QuicStreamId stream_id;
+    if (QuicVersionUsesCryptoFrames(version().transport_version)) {
+      stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+          version().transport_version, Perspective::IS_CLIENT);
+    } else {
+      stream_id = QuicUtils::GetCryptoStreamId(version().transport_version);
+    }
+    frame1_.stream_id = stream_id;
+    frame2_.stream_id = stream_id;
+    connection_.set_visitor(&visitor_);
+    connection_.SetSessionNotifier(&notifier_);
+    connection_.set_notifier(&notifier_);
+    connection_.SetSendAlgorithm(send_algorithm_);
+    connection_.SetLossAlgorithm(loss_algorithm_.get());
+    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+        .WillRepeatedly(Return(kDefaultTCPMSS));
+    EXPECT_CALL(*send_algorithm_, PacingRate(_))
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_))
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+        .Times(AnyNumber());
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnCanWrite())
+        .WillRepeatedly(Invoke(&notifier_, &SimpleSessionNotifier::OnCanWrite));
+    EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged())
+        .Times(testing::AtMost(1));
+    EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
+        .WillRepeatedly(Return(QuicTime::Zero()));
+    EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+        .Times(AnyNumber());
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_START));
+    if (connection_.version().KnowsWhichDecrypterToUse()) {
+      connection_.InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    }
+    peer_creator_.SetDefaultPeerAddress(kSelfAddress);
+  }
+
+  QuicConnectionTest(const QuicConnectionTest&) = delete;
+  QuicConnectionTest& operator=(const QuicConnectionTest&) = delete;
+
+  ParsedQuicVersion version() { return GetParam().version; }
+
+  QuicStopWaitingFrame* stop_waiting() {
+    QuicConnectionPeer::PopulateStopWaitingFrame(&connection_, &stop_waiting_);
+    return &stop_waiting_;
+  }
+
+  QuicPacketNumber least_unacked() {
+    if (writer_->stop_waiting_frames().empty()) {
+      return QuicPacketNumber();
+    }
+    return writer_->stop_waiting_frames()[0].least_unacked;
+  }
+
+  void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
+
+  void SetClientConnectionId(const QuicConnectionId& client_connection_id) {
+    connection_.set_client_connection_id(client_connection_id);
+    writer_->framer()->framer()->SetExpectedClientConnectionIdLength(
+        client_connection_id.length());
+  }
+
+  void SetDecrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicDecrypter> decrypter) {
+    if (connection_.version().KnowsWhichDecrypterToUse()) {
+      connection_.InstallDecrypter(level, std::move(decrypter));
+    } else {
+      connection_.SetDecrypter(level, std::move(decrypter));
+    }
+  }
+
+  void ProcessPacket(uint64_t number) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacket(number);
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+  }
+
+  void ProcessReceivedPacket(const QuicSocketAddress& self_address,
+                             const QuicSocketAddress& peer_address,
+                             const QuicReceivedPacket& packet) {
+    connection_.ProcessUdpPacket(self_address, peer_address, packet);
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+  }
+
+  QuicFrame MakeCryptoFrame() const {
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      return QuicFrame(new QuicCryptoFrame(crypto_frame_));
+    }
+    return QuicFrame(QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+        0u, absl::string_view()));
+  }
+
+  void ProcessFramePacket(QuicFrame frame) {
+    ProcessFramePacketWithAddresses(frame, kSelfAddress, kPeerAddress,
+                                    ENCRYPTION_FORWARD_SECURE);
+  }
+
+  void ProcessFramePacketWithAddresses(QuicFrame frame,
+                                       QuicSocketAddress self_address,
+                                       QuicSocketAddress peer_address,
+                                       EncryptionLevel level) {
+    QuicFrames frames;
+    frames.push_back(QuicFrame(frame));
+    return ProcessFramesPacketWithAddresses(frames, self_address, peer_address,
+                                            level);
+  }
+
+  std::unique_ptr<QuicReceivedPacket> ConstructPacket(QuicFrames frames,
+                                                      EncryptionLevel level,
+                                                      char* buffer,
+                                                      size_t buffer_len) {
+    QUICHE_DCHECK(peer_framer_.HasEncrypterOfEncryptionLevel(level));
+    peer_creator_.set_encryption_level(level);
+    QuicPacketCreatorPeer::SetSendVersionInPacket(
+        &peer_creator_,
+        level < ENCRYPTION_FORWARD_SECURE &&
+            connection_.perspective() == Perspective::IS_SERVER);
+
+    SerializedPacket serialized_packet =
+        QuicPacketCreatorPeer::SerializeAllFrames(&peer_creator_, frames,
+                                                  buffer, buffer_len);
+    return std::make_unique<QuicReceivedPacket>(
+        serialized_packet.encrypted_buffer, serialized_packet.encrypted_length,
+        clock_.Now());
+  }
+
+  void ProcessFramesPacketWithAddresses(QuicFrames frames,
+                                        QuicSocketAddress self_address,
+                                        QuicSocketAddress peer_address,
+                                        EncryptionLevel level) {
+    char buffer[kMaxOutgoingPacketSize];
+    connection_.ProcessUdpPacket(
+        self_address, peer_address,
+        *ConstructPacket(std::move(frames), level, buffer,
+                         kMaxOutgoingPacketSize));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+  }
+
+  // Bypassing the packet creator is unrealistic, but allows us to process
+  // packets the QuicPacketCreator won't allow us to create.
+  void ForceProcessFramePacket(QuicFrame frame) {
+    QuicFrames frames;
+    frames.push_back(QuicFrame(frame));
+    bool send_version = connection_.perspective() == Perspective::IS_SERVER;
+    if (connection_.version().KnowsWhichDecrypterToUse()) {
+      send_version = true;
+    }
+    QuicPacketCreatorPeer::SetSendVersionInPacket(&peer_creator_, send_version);
+    QuicPacketHeader header;
+    QuicPacketCreatorPeer::FillPacketHeader(&peer_creator_, &header);
+    char encrypted_buffer[kMaxOutgoingPacketSize];
+    size_t length = peer_framer_.BuildDataPacket(
+        header, frames, encrypted_buffer, kMaxOutgoingPacketSize,
+        ENCRYPTION_INITIAL);
+    QUICHE_DCHECK_GT(length, 0u);
+
+    const size_t encrypted_length = peer_framer_.EncryptInPlace(
+        ENCRYPTION_INITIAL, header.packet_number,
+        GetStartOfEncryptedData(peer_framer_.version().transport_version,
+                                header),
+        length, kMaxOutgoingPacketSize, encrypted_buffer);
+    QUICHE_DCHECK_GT(encrypted_length, 0u);
+
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
+  }
+
+  size_t ProcessFramePacketAtLevel(uint64_t number, QuicFrame frame,
+                                   EncryptionLevel level) {
+    QuicFrames frames;
+    frames.push_back(frame);
+    return ProcessFramesPacketAtLevel(number, frames, level);
+  }
+
+  size_t ProcessFramesPacketAtLevel(uint64_t number, const QuicFrames& frames,
+                                    EncryptionLevel level) {
+    QuicPacketHeader header = ConstructPacketHeader(number, level);
+    // Set the correct encryption level and encrypter on peer_creator and
+    // peer_framer, respectively.
+    peer_creator_.set_encryption_level(level);
+    if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
+        ENCRYPTION_INITIAL) {
+      peer_framer_.SetEncrypter(
+          QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+          std::make_unique<TaggingEncrypter>(0x01));
+      // Set the corresponding decrypter.
+      if (connection_.version().KnowsWhichDecrypterToUse()) {
+        connection_.InstallDecrypter(
+            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+            std::make_unique<StrictTaggingDecrypter>(0x01));
+      } else {
+        connection_.SetDecrypter(
+            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+            std::make_unique<StrictTaggingDecrypter>(0x01));
+      }
+    }
+    std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+                                    buffer, kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return encrypted_length;
+  }
+
+  struct PacketInfo {
+    PacketInfo(uint64_t packet_number, QuicFrames frames, EncryptionLevel level)
+        : packet_number(packet_number), frames(frames), level(level) {}
+
+    uint64_t packet_number;
+    QuicFrames frames;
+    EncryptionLevel level;
+  };
+
+  size_t ProcessCoalescedPacket(std::vector<PacketInfo> packets) {
+    char coalesced_buffer[kMaxOutgoingPacketSize];
+    size_t coalesced_size = 0;
+    bool contains_initial = false;
+    for (const auto& packet : packets) {
+      QuicPacketHeader header =
+          ConstructPacketHeader(packet.packet_number, packet.level);
+      // Set the correct encryption level and encrypter on peer_creator and
+      // peer_framer, respectively.
+      peer_creator_.set_encryption_level(packet.level);
+      if (packet.level == ENCRYPTION_INITIAL) {
+        contains_initial = true;
+      }
+      if (QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_) >
+          ENCRYPTION_INITIAL) {
+        peer_framer_.SetEncrypter(
+            QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+            std::make_unique<TaggingEncrypter>(0x01));
+        // Set the corresponding decrypter.
+        if (connection_.version().KnowsWhichDecrypterToUse()) {
+          connection_.InstallDecrypter(
+              QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+              std::make_unique<StrictTaggingDecrypter>(0x01));
+        } else {
+          connection_.SetDecrypter(
+              QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+              std::make_unique<StrictTaggingDecrypter>(0x01));
+        }
+      }
+      std::unique_ptr<QuicPacket> constructed_packet(
+          ConstructPacket(header, packet.frames));
+
+      char buffer[kMaxOutgoingPacketSize];
+      size_t encrypted_length = peer_framer_.EncryptPayload(
+          packet.level, QuicPacketNumber(packet.packet_number),
+          *constructed_packet, buffer, kMaxOutgoingPacketSize);
+      QUICHE_DCHECK_LE(coalesced_size + encrypted_length,
+                       kMaxOutgoingPacketSize);
+      memcpy(coalesced_buffer + coalesced_size, buffer, encrypted_length);
+      coalesced_size += encrypted_length;
+    }
+    if (contains_initial) {
+      // Padded coalesced packet to full if it contains initial packet.
+      memset(coalesced_buffer + coalesced_size, '0',
+             kMaxOutgoingPacketSize - coalesced_size);
+    }
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(coalesced_buffer, coalesced_size, clock_.Now(),
+                           false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return coalesced_size;
+  }
+
+  size_t ProcessDataPacket(uint64_t number) {
+    return ProcessDataPacketAtLevel(number, false, ENCRYPTION_FORWARD_SECURE);
+  }
+
+  size_t ProcessDataPacket(QuicPacketNumber packet_number) {
+    return ProcessDataPacketAtLevel(packet_number, false,
+                                    ENCRYPTION_FORWARD_SECURE);
+  }
+
+  size_t ProcessDataPacketAtLevel(QuicPacketNumber packet_number,
+                                  bool has_stop_waiting,
+                                  EncryptionLevel level) {
+    return ProcessDataPacketAtLevel(packet_number.ToUint64(), has_stop_waiting,
+                                    level);
+  }
+
+  size_t ProcessCryptoPacketAtLevel(uint64_t number, EncryptionLevel level) {
+    QuicPacketHeader header = ConstructPacketHeader(number, level);
+    QuicFrames frames;
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      frames.push_back(QuicFrame(&crypto_frame_));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+    }
+    if (level == ENCRYPTION_INITIAL) {
+      frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+    }
+    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+    char buffer[kMaxOutgoingPacketSize];
+    peer_creator_.set_encryption_level(level);
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+                                    buffer, kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return encrypted_length;
+  }
+
+  size_t ProcessDataPacketAtLevel(uint64_t number, bool has_stop_waiting,
+                                  EncryptionLevel level) {
+    std::unique_ptr<QuicPacket> packet(
+        ConstructDataPacket(number, has_stop_waiting, level));
+    char buffer[kMaxOutgoingPacketSize];
+    peer_creator_.set_encryption_level(level);
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+                                    buffer, kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+    if (connection_.GetSendAlarm()->IsSet()) {
+      connection_.GetSendAlarm()->Fire();
+    }
+    return encrypted_length;
+  }
+
+  void ProcessClosePacket(uint64_t number) {
+    std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number));
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length = peer_framer_.EncryptPayload(
+        ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(number), *packet, buffer,
+        kMaxOutgoingPacketSize);
+    connection_.ProcessUdpPacket(
+        kSelfAddress, kPeerAddress,
+        QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
+  }
+
+  QuicByteCount SendStreamDataToPeer(QuicStreamId id, absl::string_view data,
+                                     QuicStreamOffset offset,
+                                     StreamSendingState state,
+                                     QuicPacketNumber* last_packet) {
+    QuicByteCount packet_size;
+    // Save the last packet's size.
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(SaveArg<3>(&packet_size));
+    connection_.SendStreamDataWithString(id, data, offset, state);
+    if (last_packet != nullptr) {
+      *last_packet = creator_->packet_number();
+    }
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber());
+    return packet_size;
+  }
+
+  void SendAckPacketToPeer() {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    {
+      QuicConnection::ScopedPacketFlusher flusher(&connection_);
+      connection_.SendAck();
+    }
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AnyNumber());
+  }
+
+  void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error,
+                     QuicStreamOffset bytes_written) {
+    notifier_.WriteOrBufferRstStream(id, error, bytes_written);
+    connection_.OnStreamReset(id, error);
+  }
+
+  void SendPing() { notifier_.WriteOrBufferPing(); }
+
+  MessageStatus SendMessage(absl::string_view message) {
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    quiche::QuicheMemSlice slice(quiche::QuicheBuffer::Copy(
+        connection_.helper()->GetStreamSendBufferAllocator(), message));
+    return connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false);
+  }
+
+  void ProcessAckPacket(uint64_t packet_number, QuicAckFrame* frame) {
+    if (packet_number > 1) {
+      QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, packet_number - 1);
+    } else {
+      QuicPacketCreatorPeer::ClearPacketNumber(&peer_creator_);
+    }
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  void ProcessAckPacket(QuicAckFrame* frame) {
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  void ProcessStopWaitingPacket(QuicStopWaitingFrame frame) {
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  size_t ProcessStopWaitingPacketAtLevel(uint64_t number,
+                                         QuicStopWaitingFrame frame,
+                                         EncryptionLevel /*level*/) {
+    return ProcessFramePacketAtLevel(number, QuicFrame(frame),
+                                     ENCRYPTION_ZERO_RTT);
+  }
+
+  void ProcessGoAwayPacket(QuicGoAwayFrame* frame) {
+    ProcessFramePacket(QuicFrame(frame));
+  }
+
+  bool IsMissing(uint64_t number) {
+    return IsAwaitingPacket(connection_.ack_frame(), QuicPacketNumber(number),
+                            QuicPacketNumber());
+  }
+
+  std::unique_ptr<QuicPacket> ConstructPacket(const QuicPacketHeader& header,
+                                              const QuicFrames& frames) {
+    auto packet = BuildUnsizedDataPacket(&peer_framer_, header, frames);
+    EXPECT_NE(nullptr, packet.get());
+    return packet;
+  }
+
+  QuicPacketHeader ConstructPacketHeader(uint64_t number,
+                                         EncryptionLevel level) {
+    QuicPacketHeader header;
+    if (peer_framer_.version().HasIetfInvariantHeader() &&
+        level < ENCRYPTION_FORWARD_SECURE) {
+      // Set long header type accordingly.
+      header.version_flag = true;
+      header.form = IETF_QUIC_LONG_HEADER_PACKET;
+      header.long_packet_type = EncryptionlevelToLongHeaderType(level);
+      if (QuicVersionHasLongHeaderLengths(
+              peer_framer_.version().transport_version)) {
+        header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+        if (header.long_packet_type == INITIAL) {
+          header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+        }
+      }
+    }
+    // Set connection_id to peer's in memory representation as this data packet
+    // is created by peer_framer.
+    if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
+      header.source_connection_id_included = connection_id_included_;
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    } else {
+      header.destination_connection_id = connection_id_;
+      header.destination_connection_id_included = connection_id_included_;
+    }
+    if (peer_framer_.version().HasIetfInvariantHeader() &&
+        peer_framer_.perspective() == Perspective::IS_SERVER) {
+      if (!connection_.client_connection_id().IsEmpty()) {
+        header.destination_connection_id = connection_.client_connection_id();
+        header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+      } else {
+        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      }
+      if (header.version_flag) {
+        header.source_connection_id = connection_id_;
+        header.source_connection_id_included = CONNECTION_ID_PRESENT;
+        if (GetParam().version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+            header.long_packet_type == ZERO_RTT_PROTECTED) {
+          header.nonce = &kTestDiversificationNonce;
+        }
+      }
+    }
+    header.packet_number_length = packet_number_length_;
+    header.packet_number = QuicPacketNumber(number);
+    return header;
+  }
+
+  std::unique_ptr<QuicPacket> ConstructDataPacket(uint64_t number,
+                                                  bool has_stop_waiting,
+                                                  EncryptionLevel level) {
+    QuicPacketHeader header = ConstructPacketHeader(number, level);
+    QuicFrames frames;
+    if (VersionHasIetfQuicFrames(version().transport_version) &&
+        (level == ENCRYPTION_INITIAL || level == ENCRYPTION_HANDSHAKE)) {
+      frames.push_back(QuicFrame(QuicPingFrame()));
+      frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+      if (has_stop_waiting) {
+        frames.push_back(QuicFrame(stop_waiting_));
+      }
+    }
+    return ConstructPacket(header, frames);
+  }
+
+  std::unique_ptr<SerializedPacket> ConstructProbingPacket() {
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    if (VersionHasIetfQuicFrames(version().transport_version)) {
+      QuicPathFrameBuffer payload = {
+          {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+      return QuicPacketCreatorPeer::
+          SerializePathChallengeConnectivityProbingPacket(&peer_creator_,
+                                                          payload);
+    }
+    return QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
+        &peer_creator_);
+  }
+
+  std::unique_ptr<QuicPacket> ConstructClosePacket(uint64_t number) {
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    QuicPacketHeader header;
+    // Set connection_id to peer's in memory representation as this connection
+    // close packet is created by peer_framer.
+    if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+      header.source_connection_id = connection_id_;
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      if (!peer_framer_.version().HasIetfInvariantHeader()) {
+        header.source_connection_id_included = CONNECTION_ID_PRESENT;
+      }
+    } else {
+      header.destination_connection_id = connection_id_;
+      if (peer_framer_.version().HasIetfInvariantHeader()) {
+        header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+      }
+    }
+
+    header.packet_number = QuicPacketNumber(number);
+
+    QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
+    QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
+                                  kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
+                                  /*transport_close_frame_type=*/0);
+    QuicFrames frames;
+    frames.push_back(QuicFrame(&qccf));
+    return ConstructPacket(header, frames);
+  }
+
+  QuicTime::Delta DefaultRetransmissionTime() {
+    return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
+  }
+
+  QuicTime::Delta DefaultDelayedAckTime() {
+    return QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  }
+
+  const QuicStopWaitingFrame InitStopWaitingFrame(uint64_t least_unacked) {
+    QuicStopWaitingFrame frame;
+    frame.least_unacked = QuicPacketNumber(least_unacked);
+    return frame;
+  }
+
+  // Construct a ack_frame that acks all packet numbers between 1 and
+  // |largest_acked|, except |missing|.
+  // REQUIRES: 1 <= |missing| < |largest_acked|
+  QuicAckFrame ConstructAckFrame(uint64_t largest_acked, uint64_t missing) {
+    return ConstructAckFrame(QuicPacketNumber(largest_acked),
+                             QuicPacketNumber(missing));
+  }
+
+  QuicAckFrame ConstructAckFrame(QuicPacketNumber largest_acked,
+                                 QuicPacketNumber missing) {
+    if (missing == QuicPacketNumber(1)) {
+      return InitAckFrame({{missing + 1, largest_acked + 1}});
+    }
+    return InitAckFrame(
+        {{QuicPacketNumber(1), missing}, {missing + 1, largest_acked + 1}});
+  }
+
+  // Undo nacking a packet within the frame.
+  void AckPacket(QuicPacketNumber arrived, QuicAckFrame* frame) {
+    EXPECT_FALSE(frame->packets.Contains(arrived));
+    frame->packets.Add(arrived);
+  }
+
+  void TriggerConnectionClose() {
+    // Send an erroneous packet to close the connection.
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+
+    EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+    // Triggers a connection by receiving ACK of unsent packet.
+    QuicAckFrame frame = InitAckFrame(10000);
+    ProcessAckPacket(1, &frame);
+    EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
+                 nullptr);
+    EXPECT_EQ(1, connection_close_frame_count_);
+    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+                IsError(QUIC_INVALID_ACK_DATA));
+  }
+
+  void BlockOnNextWrite() {
+    writer_->BlockOnNextWrite();
+    EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  }
+
+  void SimulateNextPacketTooLarge() { writer_->SimulateNextPacketTooLarge(); }
+
+  void AlwaysGetPacketTooLarge() { writer_->AlwaysGetPacketTooLarge(); }
+
+  void SetWritePauseTimeDelta(QuicTime::Delta delta) {
+    writer_->SetWritePauseTimeDelta(delta);
+  }
+
+  void CongestionBlockWrites() {
+    EXPECT_CALL(*send_algorithm_, CanSend(_))
+        .WillRepeatedly(testing::Return(false));
+  }
+
+  void CongestionUnblockWrites() {
+    EXPECT_CALL(*send_algorithm_, CanSend(_))
+        .WillRepeatedly(testing::Return(true));
+  }
+
+  void set_perspective(Perspective perspective) {
+    connection_.set_perspective(perspective);
+    if (perspective == Perspective::IS_SERVER) {
+      QuicConfig config;
+      if (!GetQuicReloadableFlag(
+              quic_remove_connection_migration_connection_option)) {
+        QuicTagVector connection_options;
+        connection_options.push_back(kRVCM);
+        config.SetInitialReceivedConnectionOptions(connection_options);
+      }
+      EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+      connection_.SetFromConfig(config);
+
+      connection_.set_can_truncate_connection_ids(true);
+      QuicConnectionPeer::SetNegotiatedVersion(&connection_);
+      connection_.OnSuccessfulVersionNegotiation();
+    }
+    QuicFramerPeer::SetPerspective(&peer_framer_,
+                                   QuicUtils::InvertPerspective(perspective));
+    peer_framer_.SetInitialObfuscators(TestConnectionId());
+    for (EncryptionLevel level : {ENCRYPTION_ZERO_RTT, ENCRYPTION_HANDSHAKE,
+                                  ENCRYPTION_FORWARD_SECURE}) {
+      if (peer_framer_.HasEncrypterOfEncryptionLevel(level)) {
+        peer_creator_.SetEncrypter(
+            level, std::make_unique<NullEncrypter>(peer_framer_.perspective()));
+      }
+    }
+  }
+
+  void set_packets_between_probes_base(
+      const QuicPacketCount packets_between_probes_base) {
+    QuicConnectionPeer::ReInitializeMtuDiscoverer(
+        &connection_, packets_between_probes_base,
+        QuicPacketNumber(packets_between_probes_base));
+  }
+
+  bool IsDefaultTestConfiguration() {
+    TestParams p = GetParam();
+    return p.ack_response == AckResponse::kImmediate &&
+           p.version == AllSupportedVersions()[0] && p.no_stop_waiting;
+  }
+
+  void TestConnectionCloseQuicErrorCode(QuicErrorCode expected_code) {
+    // Not strictly needed for this test, but is commonly done.
+    EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
+                 nullptr);
+    const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
+        writer_->connection_close_frames();
+    ASSERT_EQ(1u, connection_close_frames.size());
+
+    EXPECT_THAT(connection_close_frames[0].quic_error_code,
+                IsError(expected_code));
+
+    if (!VersionHasIetfQuicFrames(version().transport_version)) {
+      EXPECT_THAT(connection_close_frames[0].wire_error_code,
+                  IsError(expected_code));
+      EXPECT_EQ(GOOGLE_QUIC_CONNECTION_CLOSE,
+                connection_close_frames[0].close_type);
+      return;
+    }
+
+    QuicErrorCodeToIetfMapping mapping =
+        QuicErrorCodeToTransportErrorCode(expected_code);
+
+    if (mapping.is_transport_close) {
+      // This Google QUIC Error Code maps to a transport close,
+      EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
+                connection_close_frames[0].close_type);
+    } else {
+      // This maps to an application close.
+      EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+                connection_close_frames[0].close_type);
+    }
+    EXPECT_EQ(mapping.error_code, connection_close_frames[0].wire_error_code);
+  }
+
+  void MtuDiscoveryTestInit() {
+    set_perspective(Perspective::IS_SERVER);
+    QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+    if (version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(&connection_);
+    }
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    // QuicFramer::GetMaxPlaintextSize uses the smallest max plaintext size
+    // across all encrypters. The initial encrypter used with IETF QUIC has a
+    // 16-byte overhead, while the NullEncrypter used throughout this test has a
+    // 12-byte overhead. This test tests behavior that relies on computing the
+    // packet size correctly, so by unsetting the initial encrypter, we avoid
+    // having a mismatch between the overheads for the encrypters used. In
+    // non-test scenarios all encrypters used for a given connection have the
+    // same overhead, either 12 bytes for ones using Google QUIC crypto, or 16
+    // bytes for ones using TLS.
+    connection_.SetEncrypter(ENCRYPTION_INITIAL, nullptr);
+    // Prevent packets from being coalesced.
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+    EXPECT_TRUE(connection_.connected());
+  }
+
+  void PathProbeTestInit(Perspective perspective,
+                         bool receive_new_server_connection_id = true) {
+    set_perspective(perspective);
+    connection_.CreateConnectionIdManager();
+    EXPECT_EQ(connection_.perspective(), perspective);
+    if (perspective == Perspective::IS_SERVER) {
+      QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+    }
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    // Discard INITIAL key.
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+    // Prevent packets from being coalesced.
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+    if (version().SupportsAntiAmplificationLimit() &&
+        perspective == Perspective::IS_SERVER) {
+      QuicConnectionPeer::SetAddressValidated(&connection_);
+    }
+    // Clear direct_peer_address.
+    QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+    // Clear effective_peer_address, it is the same as direct_peer_address for
+    // this test.
+    QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                                QuicSocketAddress());
+    EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+    } else {
+      EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+    }
+    QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+    ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                    kPeerAddress, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+    if (perspective == Perspective::IS_CLIENT &&
+        receive_new_server_connection_id && version().HasIetfQuicFrames()) {
+      QuicNewConnectionIdFrame frame;
+      frame.connection_id = TestConnectionId(1234);
+      ASSERT_NE(frame.connection_id, connection_.connection_id());
+      frame.stateless_reset_token =
+          QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+      frame.retire_prior_to = 0u;
+      frame.sequence_number = 1u;
+      connection_.OnNewConnectionIdFrame(frame);
+    }
+  }
+
+  void TestClientRetryHandling(bool invalid_retry_tag,
+                               bool missing_original_id_in_config,
+                               bool wrong_original_id_in_config,
+                               bool missing_retry_id_in_config,
+                               bool wrong_retry_id_in_config);
+
+  void TestReplaceConnectionIdFromInitial();
+
+  QuicConnectionId connection_id_;
+  QuicFramer framer_;
+
+  MockSendAlgorithm* send_algorithm_;
+  std::unique_ptr<MockLossAlgorithm> loss_algorithm_;
+  MockClock clock_;
+  MockRandom random_generator_;
+  quiche::SimpleBufferAllocator buffer_allocator_;
+  std::unique_ptr<TestConnectionHelper> helper_;
+  std::unique_ptr<TestAlarmFactory> alarm_factory_;
+  QuicFramer peer_framer_;
+  QuicPacketCreator peer_creator_;
+  std::unique_ptr<TestPacketWriter> writer_;
+  TestConnection connection_;
+  QuicPacketCreator* creator_;
+  QuicSentPacketManager* manager_;
+  StrictMock<MockQuicConnectionVisitor> visitor_;
+
+  QuicStreamFrame frame1_;
+  QuicStreamFrame frame2_;
+  QuicCryptoFrame crypto_frame_;
+  QuicAckFrame ack_;
+  QuicStopWaitingFrame stop_waiting_;
+  QuicPacketNumberLength packet_number_length_;
+  QuicConnectionIdIncluded connection_id_included_;
+
+  SimpleSessionNotifier notifier_;
+
+  QuicConnectionCloseFrame saved_connection_close_frame_;
+  int connection_close_frame_count_;
+};
+
+// Run all end to end tests with all supported versions.
+INSTANTIATE_TEST_SUITE_P(QuicConnectionTests, QuicConnectionTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+// These two tests ensure that the QuicErrorCode mapping works correctly.
+// Both tests expect to see a Google QUIC close if not running IETF QUIC.
+// If running IETF QUIC, the first will generate a transport connection
+// close, the second an application connection close.
+// The connection close codes for the two tests are manually chosen;
+// they are expected to always map to transport- and application-
+// closes, respectively. If that changes, new codes should be chosen.
+TEST_P(QuicConnectionTest, CloseErrorCodeTestTransport) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(
+      IETF_QUIC_PROTOCOL_VIOLATION, "Should be transport close",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
+// Test that the IETF QUIC Error code mapping function works
+// properly for application connection close codes.
+TEST_P(QuicConnectionTest, CloseErrorCodeTestApplication) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(
+      QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
+      "Should be application close",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
+}
+
+TEST_P(QuicConnectionTest, SelfAddressChangeAtClient) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  EXPECT_TRUE(connection_.connected());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_));
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_));
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  // Cause change in self_address.
+  QuicIpAddress host;
+  host.FromString("1.1.1.1");
+  QuicSocketAddress self_address(host, 123);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_));
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_));
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  EXPECT_TRUE(connection_.connected());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_));
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_));
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  // Cause change in self_address.
+  QuicIpAddress host;
+  host.FromString("1.1.1.1");
+  QuicSocketAddress self_address(host, 123);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
+  if (GetQuicReloadableFlag(quic_drop_packets_with_changed_server_address)) {
+    ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
+                                    kPeerAddress, ENCRYPTION_INITIAL);
+    EXPECT_TRUE(connection_.connected());
+    EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+    return;
+  }
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  EXPECT_QUIC_PEER_BUG(
+      ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
+                                      kPeerAddress, ENCRYPTION_INITIAL),
+      "Self address migration is not supported at the server");
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_ERROR_MIGRATING_ADDRESS);
+  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+}
+
+TEST_P(QuicConnectionTest, AllowSelfAddressChangeToMappedIpv4AddressAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  EXPECT_TRUE(connection_.connected());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+  }
+  QuicIpAddress host;
+  host.FromString("1.1.1.1");
+  QuicSocketAddress self_address1(host, 443);
+  connection_.SetSelfAddress(self_address1);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
+                                  kPeerAddress, ENCRYPTION_INITIAL);
+  // Cause self_address change to mapped Ipv4 address.
+  QuicIpAddress host2;
+  host2.FromString(
+      absl::StrCat("::ffff:", connection_.self_address().host().ToString()));
+  QuicSocketAddress self_address2(host2, connection_.self_address().port());
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address2,
+                                  kPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.connected());
+  // self_address change back to Ipv4 address.
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address1,
+                                  kPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(),
+                        /*port=*/23456);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+
+  // Decrease packet number to simulate out-of-order packets.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
+  // This is an old packet, do not migrate.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, PeerPortChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
+  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
+  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  // PORT_CHANGE shouldn't state change in sent packet manager.
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+  EXPECT_EQ(manager_->GetSendAlgorithm(), send_algorithm_);
+  if (connection_.validate_client_address()) {
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+    EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+  }
+}
+
+TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.OnHandshakeComplete();
+
+  // Enable 5 RTO
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k5RTO);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
+                                                  connection_.connection_id());
+  QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                       QuicConnectionId());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Send some data to make connection has packets in flight.
+  connection_.SendStreamData3();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  // Do not propagate OnCanWrite() to session notifier.
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
+
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+  EXPECT_FALSE(writer_->path_challenge_frames().empty());
+  QuicPathFrameBuffer payload =
+      writer_->path_challenge_frames().front().data_buffer;
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+
+  // PATH_CHALLENGE is expanded upto the max packet size which may exceeds the
+  // anti-amplification limit.
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(1u,
+            connection_.GetStats().num_reverse_path_validtion_upon_migration);
+
+  // Verify server is throttled by anti-amplification limit.
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receiving an ACK to the packet sent after changing peer address doesn't
+  // finish migration validation.
+  QuicAckFrame ack_frame = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+
+  // Receiving PATH_RESPONSE should lift the anti-amplification limit.
+  QuicFrames frames3;
+  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  EXPECT_CALL(visitor_, MaybeSendAddressToken());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(testing::AtLeast(1u));
+  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+
+  // Verify the anti-amplification limit is lifted by sending a packet larger
+  // than the anti-amplification limit.
+  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+}
+
+TEST_P(QuicConnectionTest, PeerIpAddressChangeAtServerWithMissingConnectionId) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+
+  QuicConnectionId client_cid0 = TestConnectionId(1);
+  QuicConnectionId client_cid1 = TestConnectionId(3);
+  QuicConnectionId server_cid1;
+  SetClientConnectionId(client_cid0);
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.OnHandshakeComplete();
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Send some data to make connection has packets in flight.
+  connection_.SendStreamData3();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  peer_creator_.SetServerConnectionId(server_cid1);
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // Do not propagate OnCanWrite() to session notifier.
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
+
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+
+  // Writing path response & reverse path challenge is blocked due to missing
+  // client connection ID, i.e., packets_write_attempts is unchanged.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Receives new client CID from client would unblock write.
+  QuicNewConnectionIdFrame new_cid_frame;
+  new_cid_frame.connection_id = client_cid1;
+  new_cid_frame.sequence_number = 1u;
+  new_cid_frame.retire_prior_to = 0u;
+  connection_.OnNewConnectionIdFrame(new_cid_frame);
+  connection_.SendStreamData3();
+
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is different from direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  const QuicSocketAddress kEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/43210);
+  connection_.ReturnEffectivePeerAddressForNextPacket(kEffectivePeerAddress);
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with the same direct peer address and different
+  // effective peer address on server side will start connection migration.
+  const QuicSocketAddress kNewEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321);
+  connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+  if (connection_.validate_client_address()) {
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+    EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+  }
+
+  // Process another packet with a different direct peer address and the same
+  // effective peer address on server side will not start connection migration.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+
+  if (!connection_.validate_client_address()) {
+    // ack_frame is used to complete the migration started by the last packet,
+    // we need to make sure a new migration does not start after the previous
+    // one is completed.
+    QuicAckFrame ack_frame = InitAckFrame(1);
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+    ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
+                                    kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  }
+
+  // Process another packet with different direct peer address and different
+  // effective peer address on server side will start connection migration.
+  const QuicSocketAddress kNewerEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/65432);
+  const QuicSocketAddress kFinalPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/34567);
+  connection_.ReturnEffectivePeerAddressForNextPacket(
+      kNewerEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewerEffectivePeerAddress, connection_.effective_peer_address());
+  if (connection_.validate_client_address()) {
+    EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+    EXPECT_EQ(send_algorithm_,
+              connection_.sent_packet_manager().GetSendAlgorithm());
+    EXPECT_EQ(2u, connection_.GetStats().num_validated_peer_migration);
+  }
+
+  // While the previous migration is ongoing, process another packet with the
+  // same direct peer address and different effective peer address on server
+  // side will start a new connection migration.
+  const QuicSocketAddress kNewestEffectivePeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/65430);
+  connection_.ReturnEffectivePeerAddressForNextPacket(
+      kNewestEffectivePeerAddress);
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  if (!connection_.validate_client_address()) {
+    EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(1);
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kFinalPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewestEffectivePeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  if (connection_.validate_client_address()) {
+    EXPECT_NE(send_algorithm_,
+              connection_.sent_packet_manager().GetSendAlgorithm());
+    EXPECT_EQ(kFinalPeerAddress, writer_->last_write_peer_address());
+    EXPECT_FALSE(writer_->path_challenge_frames().empty());
+    EXPECT_EQ(0u, connection_.GetStats()
+                      .num_peer_migration_while_validating_default_path);
+    EXPECT_TRUE(connection_.HasPendingPathValidation());
+  }
+}
+
+// Regression test for b/200020764.
+TEST_P(QuicConnectionTest, ConnectionMigrationWithPendingPaddingBytes) {
+  // TODO(haoyuewang) Move these test setup code to a common member function.
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+
+  // Sends new server CID to client.
+  QuicConnectionId new_cid;
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  packet_creator->FlushCurrentPacket();
+  packet_creator->AddPendingPadding(50u);
+  const QuicSocketAddress kPeerAddress3 =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
+  auto ack_frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  ProcessFramesPacketWithAddresses({QuicFrame(&ack_frame)}, kSelfAddress,
+                                   kPeerAddress3, ENCRYPTION_FORWARD_SECURE);
+  if (GetQuicReloadableFlag(
+          quic_flush_pending_frames_and_padding_bytes_on_migration)) {
+    // Any pending frames/padding should be flushed before default_path_ is
+    // temporarily reset.
+    ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
+                  .host()
+                  .address_family(),
+              IpAddressFamily::IP_V6);
+  } else {
+    ASSERT_EQ(connection_.self_address_on_default_path_while_sending_packet()
+                  .host()
+                  .address_family(),
+              IpAddressFamily::IP_UNSPEC);
+  }
+}
+
+// Regression test for b/196208556.
+TEST_P(QuicConnectionTest,
+       ReversePathValidationResponseReceivedFromUnexpectedPeerAddress) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicConnectionPeer::SetPeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_, kPeerAddress);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Sends new server CID to client.
+  QuicConnectionId new_cid;
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke([&](const QuicConnectionId& cid) { new_cid = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  // Process a non-probing packet to migrate to path 2 and kick off reverse path
+  // validation.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  const QuicSocketAddress kPeerAddress2 =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  peer_creator_.SetServerConnectionId(new_cid);
+  ProcessFramesPacketWithAddresses({QuicFrame(QuicPingFrame())}, kSelfAddress,
+                                   kPeerAddress2, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(writer_->path_challenge_frames().empty());
+  QuicPathFrameBuffer reverse_path_challenge_payload =
+      writer_->path_challenge_frames().front().data_buffer;
+
+  // Receiveds a packet from path 3 with PATH_RESPONSE frame intended to
+  // validate path 2 and a non-probing frame.
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    const QuicSocketAddress kPeerAddress3 =
+        QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
+    auto ack_frame = InitAckFrame(1);
+    EXPECT_CALL(visitor_, OnConnectionMigration(IPV4_TO_IPV6_CHANGE)).Times(1);
+    EXPECT_CALL(visitor_, MaybeSendAddressToken()).WillOnce(Invoke([this]() {
+      connection_.SendControlFrame(
+          QuicFrame(new QuicNewTokenFrame(1, "new_token")));
+      return true;
+    }));
+    ProcessFramesPacketWithAddresses({QuicFrame(new QuicPathResponseFrame(
+                                          0, reverse_path_challenge_payload)),
+                                      QuicFrame(&ack_frame)},
+                                     kSelfAddress, kPeerAddress3,
+                                     ENCRYPTION_FORWARD_SECURE);
+  }
+}
+
+TEST_P(QuicConnectionTest, ReversePathValidationFailureAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  SetClientConnectionId(TestConnectionId(1));
+  connection_.CreateConnectionIdManager();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Prevent packets from being coalesced.
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+
+  QuicConnectionId client_cid0 = connection_.client_connection_id();
+  QuicConnectionId client_cid1 = TestConnectionId(2);
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId server_cid1;
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.OnHandshakeComplete();
+  // Receives new client CID from client.
+  QuicNewConnectionIdFrame new_cid_frame;
+  new_cid_frame.connection_id = client_cid1;
+  new_cid_frame.sequence_number = 1u;
+  new_cid_frame.retire_prior_to = 0u;
+  connection_.OnNewConnectionIdFrame(new_cid_frame);
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kPeerAddress, connection_.peer_address()); }))
+      .WillOnce(Invoke(
+          [=]() { EXPECT_EQ(kNewPeerAddress, connection_.peer_address()); }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration()).Times(0);
+
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  QuicPaddingFrame padding;
+  frames2.push_back(QuicFrame(padding));
+  peer_creator_.SetServerConnectionId(server_cid1);
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_LT(0u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid1);
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
+
+  for (size_t i = 0; i < QuicPathValidator::kMaxRetryTimes; ++i) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+    static_cast<TestAlarmFactory::TestAlarm*>(
+        QuicPathValidatorPeer::retry_timer(
+            QuicConnectionPeer::path_validator(&connection_)))
+        ->Fire();
+  }
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+
+  // Make sure anti-amplification limit is not reached.
+  ProcessFramesPacketWithAddresses(
+      {QuicFrame(QuicPingFrame()), QuicFrame(QuicPaddingFrame())}, kSelfAddress,
+      kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Advance the time so that the reverse path validation times out.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  static_cast<TestAlarmFactory::TestAlarm*>(
+      QuicPathValidatorPeer::retry_timer(
+          QuicConnectionPeer::path_validator(&connection_)))
+      ->Fire();
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Verify that default_path_ is reverted and alternative_path_ is cleared.
+  EXPECT_EQ(default_path->client_connection_id, client_cid0);
+  EXPECT_EQ(default_path->server_connection_id, server_cid0);
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+}
+
+TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  EXPECT_CALL(visitor_, OnPacketReceived(_, _, false)).Times(0);
+
+  // Process a padded PING packet with no peer address change on server side
+  // will be ignored. But a PATH CHALLENGE packet with no peer address change
+  // will be considered as path probing.
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
+
+  EXPECT_EQ(
+      num_probing_received + (GetParam().version.HasIetfQuicFrames() ? 1u : 0u),
+      connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+// Regression test for b/150161358.
+TEST_P(QuicConnectionTest, BufferedMtuPacketTooBig) {
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  writer_->SetWriteBlocked();
+
+  // Send a MTU packet while blocked. It should be buffered.
+  connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+
+  writer_->AlwaysGetPacketTooLarge();
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, WriteOutOfOrderQueuedPackets) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_CLIENT);
+
+  BlockOnNextWrite();
+
+  QuicStreamId stream_id = 2;
+  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  writer_->SetWritable();
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
+  // Regression test for b/74073386.
+  {
+    InSequence seq;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AtLeast(1));
+    EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(AtLeast(1));
+  }
+
+  set_perspective(Perspective::IS_CLIENT);
+
+  writer_->SimulateNextPacketTooLarge();
+
+  // This packet write should fail, which should cause the connection to close
+  // after sending a connection close packet, then the failed packet should be
+  // queued.
+  connection_.SendStreamDataWithString(/*id=*/2, "foo", 0, NO_FIN);
+
+  EXPECT_FALSE(connection_.connected());
+  // No need to buffer packets.
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+}
+
+class TestQuicPathValidationContext : public QuicPathValidationContext {
+ public:
+  TestQuicPathValidationContext(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+
+                                QuicPacketWriter* writer)
+      : QuicPathValidationContext(self_address, peer_address),
+        writer_(writer) {}
+
+  QuicPacketWriter* WriterToUse() override { return writer_; }
+
+ private:
+  QuicPacketWriter* writer_;
+};
+
+class TestValidationResultDelegate : public QuicPathValidator::ResultDelegate {
+ public:
+  TestValidationResultDelegate(QuicConnection* connection,
+                               const QuicSocketAddress& expected_self_address,
+                               const QuicSocketAddress& expected_peer_address,
+                               bool* success)
+      : QuicPathValidator::ResultDelegate(),
+        connection_(connection),
+        expected_self_address_(expected_self_address),
+        expected_peer_address_(expected_peer_address),
+        success_(success) {}
+  void OnPathValidationSuccess(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    EXPECT_EQ(expected_self_address_, context->self_address());
+    EXPECT_EQ(expected_peer_address_, context->peer_address());
+    *success_ = true;
+  }
+
+  void OnPathValidationFailure(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    EXPECT_EQ(expected_self_address_, context->self_address());
+    EXPECT_EQ(expected_peer_address_, context->peer_address());
+    if (connection_->perspective() == Perspective::IS_CLIENT) {
+      connection_->OnPathValidationFailureAtClient();
+    }
+    *success_ = false;
+  }
+
+ private:
+  QuicConnection* connection_;
+  QuicSocketAddress expected_self_address_;
+  QuicSocketAddress expected_peer_address_;
+  bool* success_;
+};
+
+// Receive a path probe request at the server side, i.e.,
+// in non-IETF version: receive a padded PING packet with a peer addess change;
+// in IETF version: receive a packet contains PATH CHALLENGE with peer address
+// change.
+TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  QuicPathFrameBuffer payload;
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+    if (connection_.validate_client_address()) {
+      EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+          .Times(AtLeast(1u))
+          .WillOnce(Invoke([&]() {
+            EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+            EXPECT_EQ(1u, writer_->path_response_frames().size());
+            payload = writer_->path_challenge_frames().front().data_buffer;
+          }));
+    }
+  }
+  // Process a probing packet from a new peer address on server side
+  // is effectively receiving a connectivity probing.
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+  EXPECT_EQ(num_probing_received + 1,
+            connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  if (GetParam().version.HasIetfQuicFrames() &&
+      connection_.use_path_validator() &&
+      GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately)) {
+    QuicByteCount bytes_sent =
+        QuicConnectionPeer::BytesSentOnAlternativePath(&connection_);
+    EXPECT_LT(0u, bytes_sent);
+    EXPECT_EQ(received->length(),
+              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+
+    // Receiving one more probing packet should update the bytes count.
+    probing_packet = ConstructProbingPacket();
+    received.reset(ConstructReceivedPacket(
+        QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                            probing_packet->encrypted_length),
+        clock_.Now()));
+    ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+    EXPECT_EQ(num_probing_received + 2,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(2 * bytes_sent,
+              QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
+    EXPECT_EQ(2 * received->length(),
+              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+
+    bool success = false;
+    if (!connection_.validate_client_address()) {
+      EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+          .Times(AtLeast(1u))
+          .WillOnce(Invoke([&]() {
+            EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+            payload = writer_->path_challenge_frames().front().data_buffer;
+          }));
+
+      connection_.ValidatePath(
+          std::make_unique<TestQuicPathValidationContext>(
+              connection_.self_address(), kNewPeerAddress, writer_.get()),
+          std::make_unique<TestValidationResultDelegate>(
+              &connection_, connection_.self_address(), kNewPeerAddress,
+              &success));
+    }
+    EXPECT_EQ((connection_.validate_client_address() ? 2 : 3) * bytes_sent,
+              QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
+    QuicFrames frames;
+    frames.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+    ProcessFramesPacketWithAddresses(frames, connection_.self_address(),
+                                     kNewPeerAddress,
+                                     ENCRYPTION_FORWARD_SECURE);
+    EXPECT_LT(2 * received->length(),
+              QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+    if (connection_.validate_client_address()) {
+      EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+    }
+    // Receiving another probing packet from a newer address with a different
+    // port shouldn't trigger another reverse path validation.
+    QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
+                                        /*port=*/34567);
+    probing_packet = ConstructProbingPacket();
+    received.reset(ConstructReceivedPacket(
+        QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                            probing_packet->encrypted_length),
+        clock_.Now()));
+    ProcessReceivedPacket(kSelfAddress, kNewerPeerAddress, *received);
+    EXPECT_FALSE(connection_.HasPendingPathValidation());
+    EXPECT_EQ(connection_.validate_client_address(),
+              QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+  }
+
+  // Process another packet with the old peer address on server side will not
+  // start peer migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+// Receive a padded PING packet with a port change on server side.
+TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  if (GetParam().version.UsesCryptoFrames()) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  if (GetParam().version.HasIetfQuicFrames()) {
+    // In IETF version, a padded PING packet with port change is not taken as
+    // connectivity probe.
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  } else {
+    // In non-IETF version, process a padded PING packet from a new peer
+    // address on server side is effectively receiving a connectivity probing.
+    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  }
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  QuicFrames frames;
+  // Write a PING frame, which has no data payload.
+  QuicPingFrame ping_frame;
+  frames.push_back(QuicFrame(ping_frame));
+
+  // Add padding to the rest of the packet.
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(padding_frame));
+
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_INITIAL);
+
+  if (GetParam().version.HasIetfQuicFrames()) {
+    // Padded PING with port changen is not considered as connectivity probe but
+    // a PORT CHANGE.
+    EXPECT_EQ(num_probing_received,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  } else {
+    EXPECT_EQ(num_probing_received + 1,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  }
+
+  if (GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+  }
+  // Process another packet with the old peer address on server side. gQUIC
+  // shouldn't regard this as a peer migration.
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  // Decrease packet number to simulate out-of-order packets.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  }
+
+  // Process a padded PING packet from a new peer address on server side
+  // is effectively receiving a connectivity probing, even if a newer packet has
+  // been received before this one.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+  EXPECT_EQ(num_probing_received + 1,
+            connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  }
+
+  // Process a padded PING packet from a new peer address on server side
+  // is effectively receiving a connectivity probing.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another non-probing packet with the new peer address on server
+  // side will start peer migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, ReceiveConnectivityProbingPacketAtClient) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Client takes all padded PING packet as speculative connectivity
+  // probing packet, and reports to visitor.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
+
+  EXPECT_EQ(
+      num_probing_received + (GetParam().version.HasIetfQuicFrames() ? 1u : 0u),
+      connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, ReceiveConnectivityProbingResponseAtClient) {
+  // TODO(b/150095484): add test coverage for IETF to verify that client takes
+  // PATH RESPONSE with peer address change as correct validation on the new
+  // path.
+  if (GetParam().version.HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Process a padded PING packet with a different self address on client side
+  // is effectively receiving a connectivity probing.
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+  }
+
+  const QuicSocketAddress kNewSelfAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  uint64_t num_probing_received =
+      connection_.GetStats().num_connectivity_probing_received;
+  ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+  EXPECT_EQ(num_probing_received + 1,
+            connection_.GetStats().num_connectivity_probing_received);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+}
+
+TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  set_perspective(Perspective::IS_CLIENT);
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on client side will
+  // only update peer address.
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  if (connection_.version().HasIetfQuicFrames()) {
+    // IETF QUIC disallows server initiated address change.
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  } else {
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  }
+}
+
+TEST_P(QuicConnectionTest, MaxPacketSize) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  EXPECT_EQ(1250u, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, PeerLowersMaxPacketSize) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  constexpr uint32_t kTestMaxPacketSize = 1233u;
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
+  connection_.SetFromConfig(config);
+
+  EXPECT_EQ(kTestMaxPacketSize, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, PeerCannotRaiseMaxPacketSize) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  constexpr uint32_t kTestMaxPacketSize = 1450u;
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMaxPacketSize(&config, kTestMaxPacketSize);
+  connection_.SetFromConfig(config);
+
+  EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
+  TestConnection connection(TestConnectionId(), kSelfAddress, kPeerAddress,
+                            helper_.get(), alarm_factory_.get(), writer_.get(),
+                            Perspective::IS_SERVER, version());
+  EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
+  EXPECT_EQ(1000u, connection.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, LowerServerResponseMtuTest) {
+  set_perspective(Perspective::IS_SERVER);
+  connection_.SetMaxPacketLength(1000);
+  EXPECT_EQ(1000u, connection_.max_packet_length());
+
+  SetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test, true);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(::testing::AtMost(1));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(::testing::AtMost(1));
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_EQ(1250u, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
+  set_perspective(Perspective::IS_SERVER);
+  connection_.SetMaxPacketLength(1000);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = connection_id_;
+  header.version_flag = true;
+  header.packet_number = QuicPacketNumber(12);
+
+  if (QuicVersionHasLongHeaderLengths(
+          peer_framer_.version().transport_version)) {
+    header.long_packet_type = INITIAL;
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicFrames frames;
+  QuicPaddingFrame padding;
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    frames.push_back(QuicFrame(&crypto_frame_));
+  } else {
+    frames.push_back(QuicFrame(frame1_));
+  }
+  frames.push_back(QuicFrame(padding));
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
+
+  framer_.set_version(version());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.ApproximateNow(),
+                         false));
+
+  EXPECT_EQ(kMaxOutgoingPacketSize, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
+  const QuicByteCount lower_max_packet_size = 1240;
+  writer_->set_max_packet_size(lower_max_packet_size);
+  set_perspective(Perspective::IS_SERVER);
+  connection_.SetMaxPacketLength(1000);
+  EXPECT_EQ(1000u, connection_.max_packet_length());
+
+  QuicPacketHeader header;
+  header.destination_connection_id = connection_id_;
+  header.version_flag = true;
+  header.packet_number = QuicPacketNumber(12);
+
+  if (QuicVersionHasLongHeaderLengths(
+          peer_framer_.version().transport_version)) {
+    header.long_packet_type = INITIAL;
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicFrames frames;
+  QuicPaddingFrame padding;
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    frames.push_back(QuicFrame(&crypto_frame_));
+  } else {
+    frames.push_back(QuicFrame(frame1_));
+  }
+  frames.push_back(QuicFrame(padding));
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(12),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  EXPECT_EQ(kMaxOutgoingPacketSize, encrypted_length);
+
+  framer_.set_version(version());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.ApproximateNow(),
+                         false));
+
+  // Here, the limit imposed by the writer is lower than the size of the packet
+  // received, so the writer max packet size is used.
+  EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriter) {
+  const QuicByteCount lower_max_packet_size = 1240;
+  writer_->set_max_packet_size(lower_max_packet_size);
+
+  static_assert(lower_max_packet_size < kDefaultMaxPacketSize,
+                "Default maximum packet size is too low");
+  connection_.SetMaxPacketLength(kDefaultMaxPacketSize);
+
+  EXPECT_EQ(lower_max_packet_size, connection_.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) {
+  const QuicConnectionId connection_id = TestConnectionId(17);
+  const QuicByteCount lower_max_packet_size = 1240;
+  writer_->set_max_packet_size(lower_max_packet_size);
+  TestConnection connection(connection_id, kSelfAddress, kPeerAddress,
+                            helper_.get(), alarm_factory_.get(), writer_.get(),
+                            Perspective::IS_CLIENT, version());
+  EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
+  EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
+}
+
+TEST_P(QuicConnectionTest, PacketsInOrder) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1u), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+}
+
+TEST_P(QuicConnectionTest, PacketsOutOfOrder) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_FALSE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(1);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_FALSE(IsMissing(2));
+  EXPECT_FALSE(IsMissing(1));
+}
+
+TEST_P(QuicConnectionTest, DuplicatePacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  // Send packet 3 again, but do not set the expectation that
+  // the visitor OnStreamFrame() will be called.
+  ProcessDataPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+}
+
+TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(2));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(1));
+
+  ProcessPacket(5);
+  EXPECT_EQ(QuicPacketNumber(5u), LargestAcked(connection_.ack_frame()));
+  EXPECT_TRUE(IsMissing(1));
+  EXPECT_TRUE(IsMissing(4));
+
+  // Pretend at this point the client has gotten acks for 2 and 3 and 1 is a
+  // packet the peer will not retransmit.  It indicates this by sending 'least
+  // awaiting' is 4.  The connection should then realize 1 will not be
+  // retransmitted, and will remove it from the missing list.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessAckPacket(6, &frame);
+
+  // Force an ack to be sent.
+  SendAckPacketToPeer();
+  EXPECT_TRUE(IsMissing(4));
+}
+
+TEST_P(QuicConnectionTest, RejectUnencryptedStreamData) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration() ||
+      VersionHasIetfQuicFrames(version().transport_version)) {
+    return;
+  }
+
+  // Process an unencrypted packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_QUIC_PEER_BUG(ProcessDataPacketAtLevel(1, false, ENCRYPTION_INITIAL),
+                       "");
+  TestConnectionCloseQuicErrorCode(QUIC_UNENCRYPTED_STREAM_DATA);
+}
+
+TEST_P(QuicConnectionTest, OutOfOrderReceiptCausesAckSend) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(3);
+  // Should not cause an ack.
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  ProcessPacket(2);
+  // Should ack immediately, since this fills the last hole.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  ProcessPacket(1);
+  // Should ack immediately, since this fills the last hole.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  ProcessPacket(4);
+  // Should not cause an ack.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, OutOfOrderAckReceiptCausesNoAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  QuicAckFrame ack1 = InitAckFrame(1);
+  QuicAckFrame ack2 = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(1);
+  }
+  ProcessAckPacket(2, &ack2);
+  // Should ack immediately since we have missing packets.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(0);
+  }
+  ProcessAckPacket(1, &ack1);
+  // Should not ack an ack filling a missing packet.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  QuicPacketNumber original, second;
+
+  QuicByteCount packet_size =
+      SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original);  // 1st packet.
+  SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second);        // 2nd packet.
+
+  QuicAckFrame frame = InitAckFrame({{second, second + 1}});
+  // First nack triggers early retransmit.
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicPacketNumber retransmission;
+  // Packet 1 is short header for IETF QUIC because the encryption level
+  // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _,
+                           GetParam().version.HasIetfInvariantHeader()
+                               ? packet_size
+                               : packet_size - kQuicVersionSize,
+                           _))
+      .WillOnce(SaveArg<2>(&retransmission));
+
+  ProcessAckPacket(&frame);
+
+  QuicAckFrame frame2 = ConstructAckFrame(retransmission, original);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  ProcessAckPacket(&frame2);
+
+  // Now if the peer sends an ack which still reports the retransmitted packet
+  // as missing, that will bundle an ack with data after two acks in a row
+  // indicate the high water mark needs to be raised.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
+  connection_.SendStreamDataWithString(3, "foo", 6, NO_FIN);
+  // No ack sent.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+
+  // No more packet loss for the rest of the test.
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&frame2);
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
+  connection_.SendStreamDataWithString(3, "foofoofoo", 9, NO_FIN);
+  // Ack bundled.
+  if (GetParam().no_stop_waiting) {
+    // Do not ACK acks.
+    EXPECT_EQ(1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+  }
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_TRUE(writer_->ack_frames().empty());
+  } else {
+    EXPECT_FALSE(writer_->ack_frames().empty());
+  }
+
+  // But an ack with no missing packets will not send an ack.
+  AckPacket(original, &frame2);
+  ProcessAckPacket(&frame2);
+  ProcessAckPacket(&frame2);
+}
+
+TEST_P(QuicConnectionTest, AckFrequencyUpdatedFromAckFrequencyFrame) {
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.set_can_receive_ack_frequency_frame();
+
+  // Expect 13 acks, every 3rd packet including the first packet with
+  // AckFrequencyFrame.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(13);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicAckFrequencyFrame ack_frequency_frame;
+  ack_frequency_frame.packet_tolerance = 3;
+  ProcessFramePacketAtLevel(1, QuicFrame(&ack_frequency_frame),
+                            ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(38);
+  // Receives packets 2 - 39.
+  for (size_t i = 2; i <= 39; ++i) {
+    ProcessDataPacket(i);
+  }
+}
+
+TEST_P(QuicConnectionTest, AckDecimationReducesAcks) {
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+
+  // Start ack decimation from 10th packet.
+  connection_.set_min_received_before_ack_decimation(10);
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(30);
+
+  // Expect 6 acks: 5 acks between packets 1-10, and ack at 20.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
+  // Receives packets 1 - 29.
+  for (size_t i = 1; i <= 29; ++i) {
+    ProcessDataPacket(i);
+  }
+
+  // We now receive the 30th packet, and so we send an ack.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(30);
+}
+
+TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(99);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
+  // Receives packets 1 - 39.
+  for (size_t i = 1; i <= 39; ++i) {
+    ProcessDataPacket(i);
+  }
+  // Receiving Packet 40 causes 20th ack to send. Session is informed and adds
+  // WINDOW_UPDATE.
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+      .WillOnce(Invoke([this]() {
+        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_EQ(0u, writer_->window_update_frames().size());
+  ProcessDataPacket(40);
+  EXPECT_EQ(1u, writer_->window_update_frames().size());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
+  // Receives packets 41 - 59.
+  for (size_t i = 41; i <= 59; ++i) {
+    ProcessDataPacket(i);
+  }
+  // Send a packet containing stream frame.
+  SendStreamDataToPeer(
+      QuicUtils::GetFirstBidirectionalStreamId(
+          connection_.version().transport_version, Perspective::IS_CLIENT),
+      "bar", 0, NO_FIN, nullptr);
+
+  // Session will not be informed until receiving another 20 packets.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(19);
+  for (size_t i = 60; i <= 98; ++i) {
+    ProcessDataPacket(i);
+    EXPECT_EQ(0u, writer_->window_update_frames().size());
+  }
+  // Session does not add a retransmittable frame.
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+      .WillOnce(Invoke([this]() {
+        connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_EQ(0u, writer_->ping_frames().size());
+  ProcessDataPacket(99);
+  EXPECT_EQ(0u, writer_->window_update_frames().size());
+  // A ping frame will be added.
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, AckNeedsRetransmittableFramesAfterPto) {
+  // Disable TLP so the RTO fires immediately.
+  connection_.SetMaxTailLossProbes(0);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kEACK);
+  config.SetConnectionOptionsToSend(connection_options);
+  connection_.SetFromConfig(config);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.OnHandshakeComplete();
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(10);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
+  // Receive packets 1 - 9.
+  for (size_t i = 1; i <= 9; ++i) {
+    ProcessDataPacket(i);
+  }
+
+  // Send a ping and fire the retransmission alarm.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  SendPing();
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+  ASSERT_TRUE(manager_->GetConsecutiveRtoCount() > 0 ||
+              manager_->GetConsecutivePtoCount() > 0);
+
+  // Process a packet, which requests a retransmittable frame be bundled
+  // with the ACK.
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+      .WillOnce(Invoke([this]() {
+        connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(11);
+  EXPECT_EQ(1u, writer_->window_update_frames().size());
+}
+
+TEST_P(QuicConnectionTest, LeastUnackedLower) {
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
+
+  // Start out saying the least unacked is 2.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
+  ProcessStopWaitingPacket(InitStopWaitingFrame(2));
+
+  // Change it to 1, but lower the packet number to fake out-of-order packets.
+  // This should be fine.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
+  // The scheduler will not process out of order acks, but all packet processing
+  // causes the connection to try to write.
+  if (!GetParam().no_stop_waiting) {
+    EXPECT_CALL(visitor_, OnCanWrite());
+  }
+  ProcessStopWaitingPacket(InitStopWaitingFrame(1));
+
+  // Now claim it's one, but set the ordering so it was sent "after" the first
+  // one.  This should cause a connection error.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 7);
+  if (!GetParam().no_stop_waiting) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AtLeast(1));
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .Times(AtLeast(1));
+  }
+  ProcessStopWaitingPacket(InitStopWaitingFrame(1));
+  if (!GetParam().no_stop_waiting) {
+    TestConnectionCloseQuicErrorCode(QUIC_INVALID_STOP_WAITING_DATA);
+  }
+}
+
+TEST_P(QuicConnectionTest, TooManySentPackets) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicPacketCount max_tracked_packets = 50;
+  QuicConnectionPeer::SetMaxTrackedPackets(&connection_, max_tracked_packets);
+
+  const int num_packets = max_tracked_packets + 5;
+
+  for (int i = 0; i < num_packets; ++i) {
+    SendStreamDataToPeer(1, "foo", 3 * i, NO_FIN, nullptr);
+  }
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+
+  ProcessFramePacket(QuicFrame(QuicPingFrame()));
+
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
+}
+
+TEST_P(QuicConnectionTest, LargestObservedLower) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
+  SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Start out saying the largest observed is 2.
+  QuicAckFrame frame1 = InitAckFrame(1);
+  QuicAckFrame frame2 = InitAckFrame(2);
+  ProcessAckPacket(&frame2);
+
+  EXPECT_CALL(visitor_, OnCanWrite());
+  ProcessAckPacket(&frame1);
+}
+
+TEST_P(QuicConnectionTest, AckUnsentData) {
+  // Ack a packet which has not been sent.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
+  ProcessAckPacket(&frame);
+  TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
+}
+
+TEST_P(QuicConnectionTest, BasicSending) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  const QuicConnectionStats& stats = connection_.GetStats();
+  EXPECT_FALSE(stats.first_decrypted_packet.IsInitialized());
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  SendAckPacketToPeer();  // Packet 2
+
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
+  }
+
+  SendAckPacketToPeer();  // Packet 3
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
+  }
+
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, &last_packet);  // Packet 4
+  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
+  SendAckPacketToPeer();  // Packet 5
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
+  }
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Peer acks up to packet 3.
+  QuicAckFrame frame = InitAckFrame(3);
+  ProcessAckPacket(&frame);
+  SendAckPacketToPeer();  // Packet 6
+
+  // As soon as we've acked one, we skip ack packets 2 and 3 and note lack of
+  // ack for 4.
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
+  }
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Peer acks up to packet 4, the last packet.
+  QuicAckFrame frame2 = InitAckFrame(6);
+  ProcessAckPacket(&frame2);  // Acks don't instigate acks.
+
+  // Verify that we did not send an ack.
+  EXPECT_EQ(QuicPacketNumber(6u), writer_->header().packet_number);
+
+  // So the last ack has not changed.
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
+  }
+
+  // If we force an ack, we shouldn't change our retransmit state.
+  SendAckPacketToPeer();  // Packet 7
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
+  }
+
+  // But if we send more data it should.
+  SendStreamDataToPeer(1, "eep", 6, NO_FIN, &last_packet);  // Packet 8
+  EXPECT_EQ(QuicPacketNumber(8u), last_packet);
+  SendAckPacketToPeer();  // Packet 9
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
+  }
+  EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
+}
+
+// QuicConnection should record the packet sent-time prior to sending the
+// packet.
+TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
+  // We're using a MockClock for the tests, so we have complete control over the
+  // time.
+  // Our recorded timestamp for the last packet sent time will be passed in to
+  // the send_algorithm.  Make sure that it is set to the correct value.
+  QuicTime actual_recorded_send_time = QuicTime::Zero();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<0>(&actual_recorded_send_time));
+
+  // First send without any pause and check the result.
+  QuicTime expected_recorded_send_time = clock_.Now();
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+      << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+      << ".  Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+
+  // Now pause during the write, and check the results.
+  actual_recorded_send_time = QuicTime::Zero();
+  const QuicTime::Delta write_pause_time_delta =
+      QuicTime::Delta::FromMilliseconds(5000);
+  SetWritePauseTimeDelta(write_pause_time_delta);
+  expected_recorded_send_time = clock_.Now();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<0>(&actual_recorded_send_time));
+  connection_.SendStreamDataWithString(2, "baz", 0, NO_FIN);
+  EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+      << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+      << ".  Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+}
+
+TEST_P(QuicConnectionTest, FramePacking) {
+  // Send two stream frames in 1 packet by queueing them.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendStreamData3();
+    connection_.SendStreamData5();
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  }
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's an ack and two stream frames from
+  // two different streams.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  }
+
+  EXPECT_TRUE(writer_->ack_frames().empty());
+
+  ASSERT_EQ(2u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
+            writer_->stream_frames()[1]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
+  // Send two stream frames (one non-crypto, then one crypto) in 2 packets by
+  // queueing them.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendStreamData3();
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoStreamData();
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  }
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it contains a crypto stream frame.
+  EXPECT_LE(2u, writer_->frame_count());
+  ASSERT_LE(1u, writer_->padding_frames().size());
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    ASSERT_EQ(1u, writer_->stream_frames().size());
+    EXPECT_EQ(QuicUtils::GetCryptoStreamId(connection_.transport_version()),
+              writer_->stream_frames()[0]->stream_id);
+  } else {
+    EXPECT_LE(1u, writer_->crypto_frames().size());
+  }
+}
+
+TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
+  // Send two stream frames (one crypto, then one non-crypto) in 2 packets by
+  // queueing them.
+  {
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendCryptoStreamData();
+    connection_.SendStreamData3();
+  }
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's the stream frame from stream 3.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, FramePackingAckResponse) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  // Process a data packet to queue up a pending ack.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  QuicPacketNumber last_packet;
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    connection_.SendCryptoDataWithString("foo", 0);
+  } else {
+    SendStreamDataToPeer(
+        QuicUtils::GetCryptoStreamId(connection_.transport_version()), "foo", 0,
+        NO_FIN, &last_packet);
+  }
+  // Verify ack is bundled with outging packet.
+  EXPECT_FALSE(writer_->ack_frames().empty());
+
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData3)),
+                      IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData5))));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+
+  // Process a data packet to cause the visitor's OnCanWrite to be invoked.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ProcessDataPacket(2);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's an ack and two stream frames from
+  // two different streams.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  ASSERT_EQ(2u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
+            writer_->stream_frames()[1]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, FramePackingSendv) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.transport_version(), Perspective::IS_CLIENT);
+  connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure multiple iovector blocks have
+  // been packed into a single stream frame from one stream.
+  EXPECT_EQ(1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(0u, writer_->padding_frames().size());
+  QuicStreamFrame* frame = writer_->stream_frames()[0].get();
+  EXPECT_EQ(stream_id, frame->stream_id);
+  EXPECT_EQ("ABCDEF",
+            absl::string_view(frame->data_buffer, frame->data_length));
+}
+
+TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+
+  BlockOnNextWrite();
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.transport_version(), Perspective::IS_CLIENT);
+  connection_.SaveAndSendStreamData(stream_id, "ABCDEF", 0, NO_FIN);
+
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_TRUE(connection_.HasQueuedData());
+
+  // Unblock the writes and actually send.
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  // Parse the last packet and ensure it's one stream frame from one stream.
+  EXPECT_EQ(1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(0u, writer_->padding_frames().size());
+  QuicStreamFrame* frame = writer_->stream_frames()[0].get();
+  EXPECT_EQ(stream_id, frame->stream_id);
+  EXPECT_EQ("ABCDEF",
+            absl::string_view(frame->data_buffer, frame->data_length));
+}
+
+TEST_P(QuicConnectionTest, SendingZeroBytes) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Send a zero byte write with a fin using writev.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.transport_version(), Perspective::IS_CLIENT);
+  connection_.SaveAndSendStreamData(stream_id, {}, 0, FIN);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Padding frames are added by v99 to ensure a minimum packet size.
+  size_t extra_padding_frames = 0;
+  if (GetParam().version.HasHeaderProtection()) {
+    extra_padding_frames = 1;
+  }
+
+  // Parse the last packet and ensure it's one stream frame from one stream.
+  EXPECT_EQ(1u + extra_padding_frames, writer_->frame_count());
+  EXPECT_EQ(extra_padding_frames, writer_->padding_frames().size());
+  ASSERT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(stream_id, writer_->stream_frames()[0]->stream_id);
+  EXPECT_TRUE(writer_->stream_frames()[0]->fin);
+}
+
+TEST_P(QuicConnectionTest, LargeSendWithPendingAck) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  // Set the ack alarm by processing a ping frame.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Processs a PING frame.
+  ProcessFramePacket(QuicFrame(QuicPingFrame()));
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  // Send data and ensure the ack is bundled.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(9);
+  const std::string data(10000, '?');
+  QuicConsumedData consumed = connection_.SaveAndSendStreamData(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()), data,
+      0, FIN);
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.HasQueuedData());
+
+  // Parse the last packet and ensure it's one stream frame with a fin.
+  EXPECT_EQ(1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_TRUE(writer_->stream_frames()[0]->fin);
+  // Ensure the ack alarm was cancelled when the ack was sent.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, OnCanWrite) {
+  // Visitor's OnCanWrite will send data, but will have more pending writes.
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData3)),
+                      IgnoreResult(InvokeWithoutArgs(
+                          &connection_, &TestConnection::SendStreamData5))));
+  {
+    InSequence seq;
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(Return(false));
+  }
+
+  EXPECT_CALL(*send_algorithm_, CanSend(_))
+      .WillRepeatedly(testing::Return(true));
+
+  connection_.OnCanWrite();
+
+  // Parse the last packet and ensure it's the two stream frames from
+  // two different streams.
+  EXPECT_EQ(2u, writer_->frame_count());
+  EXPECT_EQ(2u, writer_->stream_frames().size());
+  EXPECT_EQ(GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+            writer_->stream_frames()[0]->stream_id);
+  EXPECT_EQ(GetNthClientInitiatedStreamId(2, connection_.transport_version()),
+            writer_->stream_frames()[1]->stream_id);
+}
+
+TEST_P(QuicConnectionTest, RetransmitOnNack) {
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(3, "foos", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(3, "fooos", 7, NO_FIN, &last_packet);
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Don't lose a packet on an ack, and nothing is retransmitted.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame ack_one = InitAckFrame(1);
+  ProcessAckPacket(&ack_one);
+
+  // Lose a packet and ensure it triggers retransmission.
+  QuicAckFrame nack_two = ConstructAckFrame(3, 2);
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
+  ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
+  // Block the connection to queue the packet.
+  BlockOnNextWrite();
+
+  QuicStreamId stream_id = 2;
+  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+  // Now that there is a queued packet, reset the stream.
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Unblock the connection and verify that only the RST_STREAM is sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, SendQueuedPacketForQuicRstStreamNoError) {
+  // Block the connection to queue the packet.
+  BlockOnNextWrite();
+
+  QuicStreamId stream_id = 2;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+  // Now that there is a queued packet, reset the stream.
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
+
+  // Unblock the connection and verify that the RST_STREAM is sent and the data
+  // packet is sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
+
+  // Lose a packet and ensure it does not trigger retransmission.
+  QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnNack) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "fooos", 7, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
+
+  // Lose a packet, ensure it triggers retransmission.
+  QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ProcessAckPacket(&nack_two);
+}
+
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Fire the RTO and verify that the RST_STREAM is resent, not stream data.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  connection_.GetRetransmissionAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+}
+
+// Ensure that if the only data in flight is non-retransmittable, the
+// retransmission alarm is not set.
+TEST_P(QuicConnectionTest, CancelRetransmissionAlarmAfterResetStream) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+
+  // Cancel the stream.
+  const QuicPacketNumber rst_packet = last_data_packet + 1;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, rst_packet, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Ack the RST_STREAM frame (since it's retransmittable), but not the data
+  // packet, which is no longer retransmittable since the stream was cancelled.
+  QuicAckFrame nack_stream_data =
+      ConstructAckFrame(rst_packet, last_data_packet);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&nack_stream_data);
+
+  // Ensure that the data is still in flight, but the retransmission alarm is no
+  // longer set.
+  EXPECT_GT(manager_->GetBytesInFlight(), 0u);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
+  connection_.SetMaxTailLossProbes(0);
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 3);
+
+  // Fire the RTO and verify that the RST_STREAM is resent, the stream data
+  // is sent.
+  const size_t num_retransmissions = connection_.PtoEnabled() ? 1 : 2;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(num_retransmissions));
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  connection_.GetRetransmissionAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  if (num_retransmissions == 2) {
+    ASSERT_EQ(1u, writer_->rst_stream_frames().size());
+    EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+  }
+}
+
+TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
+
+  // Lose a packet which will trigger a pending retransmission.
+  QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&ack);
+
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 12);
+
+  // Unblock the connection and verify that the RST_STREAM is sent but not the
+  // second data packet nor a retransmit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
+}
+
+TEST_P(QuicConnectionTest, SendPendingRetransmissionForQuicRstStreamNoError) {
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foos", 3, NO_FIN, &last_packet);
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(stream_id, "fooos", 7, NO_FIN);
+
+  // Lose a packet which will trigger a pending retransmission.
+  QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(last_packet - 1, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessAckPacket(&ack);
+
+  SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 12);
+
+  // Unblock the connection and verify that the RST_STREAM is sent and the
+  // second data packet or a retransmit is sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2));
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  // The RST_STREAM_FRAME is sent after queued packets and pending
+  // retransmission.
+  connection_.SendControlFrame(QuicFrame(
+      new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, RetransmitAckedPacket) {
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);    // Packet 1
+  SendStreamDataToPeer(1, "foos", 3, NO_FIN, &last_packet);   // Packet 2
+  SendStreamDataToPeer(1, "fooos", 7, NO_FIN, &last_packet);  // Packet 3
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Instigate a loss with an ack.
+  QuicAckFrame nack_two = ConstructAckFrame(3, 2);
+  // The first nack should trigger a fast retransmission, but we'll be
+  // write blocked, so the packet will be queued.
+  BlockOnNextWrite();
+
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
+      .Times(1);
+  ProcessAckPacket(&nack_two);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Now, ack the previous transmission.
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _));
+  QuicAckFrame ack_all = InitAckFrame(3);
+  ProcessAckPacket(&ack_all);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
+      .Times(0);
+
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  // We do not store retransmittable frames of this retransmission.
+  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 4));
+}
+
+TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  QuicPacketNumber original, second;
+
+  QuicByteCount packet_size =
+      SendStreamDataToPeer(3, "foo", 0, NO_FIN, &original);  // 1st packet.
+  SendStreamDataToPeer(3, "bar", 3, NO_FIN, &second);        // 2nd packet.
+
+  QuicAckFrame frame = InitAckFrame({{second, second + 1}});
+  // The first nack should retransmit the largest observed packet.
+  LostPacketVector lost_packets;
+  lost_packets.push_back(LostPacket(original, kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  // Packet 1 is short header for IETF QUIC because the encryption level
+  // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _,
+                           GetParam().version.HasIetfInvariantHeader()
+                               ? packet_size
+                               : packet_size - kQuicVersionSize,
+                           _));
+  ProcessAckPacket(&frame);
+}
+
+TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  for (int i = 0; i < 10; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "foo", i * 3, NO_FIN);
+  }
+
+  // Block the writer and ensure they're queued.
+  BlockOnNextWrite();
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_TRUE(connection_.HasQueuedData());
+
+  // Unblock the writer.
+  writer_->SetWritable();
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
+      2 * DefaultRetransmissionTime().ToMicroseconds()));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.GetRetransmissionAlarm()->Fire();
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedBufferedThenSent) {
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // The second packet should also be queued, in order to ensure packets are
+  // never sent out of order.
+  writer_->SetWritable();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(2u, connection_.NumQueuedPackets());
+
+  // Now both are sent in order when we unblock.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  // Simulate the retransmission alarm firing.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Ack the sent packet before the callback returns, which happens in
+  // rare circumstances with write blocked sockets.
+  QuicAckFrame ack = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  uint64_t retransmission = connection_.PtoEnabled() ? 3 : 2;
+  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
+                                                            retransmission));
+}
+
+TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) {
+  // Block the connection.
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+
+  // Set the send alarm. Fire the alarm and ensure it doesn't attempt to write.
+  connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
+  connection_.GetSendAlarm()->Fire();
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, NoSendAlarmAfterProcessPacketWhenWriteBlocked) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Block the connection.
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  // Process packet number 1. Can not call ProcessPacket or ProcessDataPacket
+  // here, because they will fire the alarm after QuicConnection::ProcessPacket
+  // is returned.
+  const uint64_t received_packet_num = 1;
+  const bool has_stop_waiting = false;
+  const EncryptionLevel level = ENCRYPTION_FORWARD_SECURE;
+  std::unique_ptr<QuicPacket> packet(
+      ConstructDataPacket(received_packet_num, has_stop_waiting, level));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, AddToWriteBlockedListIfWriterBlockedWhenProcessing) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+
+  // Simulate the case where a shared writer gets blocked by another connection.
+  writer_->SetWriteBlocked();
+
+  // Process an ACK, make sure the connection calls visitor_->OnWriteBlocked().
+  QuicAckFrame ack1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  ProcessAckPacket(1, &ack1);
+}
+
+TEST_P(QuicConnectionTest, DoNotAddToWriteBlockedListAfterDisconnect) {
+  writer_->SetBatchMode(true);
+  EXPECT_TRUE(connection_.connected());
+  // Have to explicitly grab the OnConnectionClosed frame and check
+  // its parameters because this is a silent connection close and the
+  // frame is not also transmitted to the peer.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                                ConnectionCloseBehavior::SILENT_CLOSE);
+
+    EXPECT_FALSE(connection_.connected());
+    writer_->SetWriteBlocked();
+  }
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, AddToWriteBlockedListIfBlockedOnFlushPackets) {
+  writer_->SetBatchMode(true);
+  writer_->BlockOnNextFlush();
+
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // flusher's destructor will call connection_.FlushPackets, which should add
+    // the connection to the write blocked list.
+  }
+}
+
+TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  int offset = 0;
+  // Send packets 1 to 15.
+  for (int i = 0; i < 15; ++i) {
+    SendStreamDataToPeer(1, "foo", offset, NO_FIN, nullptr);
+    offset += 3;
+  }
+
+  // Ack 15, nack 1-14.
+
+  QuicAckFrame nack =
+      InitAckFrame({{QuicPacketNumber(15), QuicPacketNumber(16)}});
+
+  // 14 packets have been NACK'd and lost.
+  LostPacketVector lost_packets;
+  for (int i = 1; i < 15; ++i) {
+    lost_packets.push_back(
+        LostPacket(QuicPacketNumber(i), kMaxOutgoingPacketSize));
+  }
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessAckPacket(&nack);
+}
+
+// Test sending multiple acks from the connection to the session.
+TEST_P(QuicConnectionTest, MultipleAcks) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 2
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  SendAckPacketToPeer();                                    // Packet 3
+  SendStreamDataToPeer(5, "foo", 0, NO_FIN, &last_packet);  // Packet 4
+  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
+  SendStreamDataToPeer(1, "foo", 3, NO_FIN, &last_packet);  // Packet 5
+  EXPECT_EQ(QuicPacketNumber(5u), last_packet);
+  SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 6
+  EXPECT_EQ(QuicPacketNumber(6u), last_packet);
+
+  // Client will ack packets 1, 2, [!3], 4, 5.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame1 = ConstructAckFrame(5, 3);
+  ProcessAckPacket(&frame1);
+
+  // Now the client implicitly acks 3, and explicitly acks 6.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame2 = InitAckFrame(6);
+  ProcessAckPacket(&frame2);
+}
+
+TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);  // Packet 1;
+  // From now on, we send acks, so the send algorithm won't mark them pending.
+  SendAckPacketToPeer();  // Packet 2
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame = InitAckFrame(1);
+  ProcessAckPacket(&frame);
+
+  // Verify that our internal state has least-unacked as 2, because we're still
+  // waiting for a potential ack for 2.
+
+  EXPECT_EQ(QuicPacketNumber(2u), stop_waiting()->least_unacked);
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame(2);
+  ProcessAckPacket(&frame);
+  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
+
+  // When we send an ack, we make sure our least-unacked makes sense.  In this
+  // case since we're not waiting on an ack for 2 and all packets are acked, we
+  // set it to 3.
+  SendAckPacketToPeer();  // Packet 3
+  // Least_unacked remains at 3 until another ack is received.
+  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    // Check that the outgoing ack had its packet number as least_unacked.
+    EXPECT_EQ(QuicPacketNumber(3u), least_unacked());
+  }
+
+  // Ack the ack, which updates the rtt and raises the least unacked.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame(3);
+  ProcessAckPacket(&frame);
+
+  SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);  // Packet 4
+  EXPECT_EQ(QuicPacketNumber(4u), stop_waiting()->least_unacked);
+  SendAckPacketToPeer();  // Packet 5
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_FALSE(least_unacked().IsInitialized());
+  } else {
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
+  }
+
+  // Send two data packets at the end, and ensure if the last one is acked,
+  // the least unacked is raised above the ack packets.
+  SendStreamDataToPeer(1, "bar", 6, NO_FIN, nullptr);  // Packet 6
+  SendStreamDataToPeer(1, "bar", 9, NO_FIN, nullptr);  // Packet 7
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
+                        {QuicPacketNumber(7), QuicPacketNumber(8)}});
+  ProcessAckPacket(&frame);
+
+  EXPECT_EQ(QuicPacketNumber(6u), stop_waiting()->least_unacked);
+}
+
+TEST_P(QuicConnectionTest, TLP) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(1);
+
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
+  // Simulate the retransmission alarm firing and sending a tlp,
+  // so send algorithm's OnRetransmissionTimeout is not called.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  const QuicPacketNumber retransmission(
+      connection_.SupportsMultiplePacketNumberSpaces() ? 3 : 2);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, retransmission, _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(retransmission, writer_->header().packet_number);
+  // We do not raise the high water mark yet.
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+}
+
+TEST_P(QuicConnectionTest, RTO) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  QuicTime default_retransmission_time =
+      clock_.ApproximateNow() + DefaultRetransmissionTime();
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+
+  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
+  EXPECT_EQ(default_retransmission_time,
+            connection_.GetRetransmissionAlarm()->deadline());
+  // Simulate the retransmission alarm firing.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
+  // We do not raise the high water mark yet.
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
+}
+
+// Regression test of b/133771183.
+TEST_P(QuicConnectionTest, RtoWithNoDataToRetransmit) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SetMaxTailLossProbes(0);
+
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
+  // Connection is cwnd limited.
+  CongestionBlockWrites();
+  // Stream gets reset.
+  SendRstStream(3, QUIC_ERROR_PROCESSING_STREAM, 3);
+  // Simulate the retransmission alarm firing.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  // RTO fires, but there is no packet to be RTOed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(40);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(20);
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(1);
+  // Receives packets 1 - 40.
+  for (size_t i = 1; i <= 40; ++i) {
+    ProcessDataPacket(i);
+  }
+}
+
+TEST_P(QuicConnectionTest, SendHandshakeMessages) {
+  use_tagging_decrypter();
+  // A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
+  // the end of the packet. We can test this to check which encrypter was used.
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+
+  // Attempt to send a handshake message and have the socket block.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  BlockOnNextWrite();
+  connection_.SendCryptoDataWithString("foo", 0);
+  // The packet should be serialized, but not queued.
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Switch to the new encrypter.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  // Now become writeable and flush the packets.
+  writer_->SetWritable();
+  EXPECT_CALL(visitor_, OnCanWrite());
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  // Verify that the handshake packet went out at the null encryption.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+}
+
+TEST_P(QuicConnectionTest,
+       DropRetransmitsForNullEncryptedPacketAfterForwardSecure) {
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SendCryptoStreamData();
+
+  // Simulate the retransmission alarm firing and the socket blocking.
+  BlockOnNextWrite();
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Go forward secure.
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+
+  EXPECT_EQ(QuicTime::Zero(), connection_.GetRetransmissionAlarm()->deadline());
+  // Unblock the socket and ensure that no packets are sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+}
+
+TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+
+  connection_.SendCryptoDataWithString("foo", 0);
+
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  SendStreamDataToPeer(2, "bar", 0, NO_FIN, nullptr);
+  EXPECT_FALSE(notifier_.HasLostStreamData());
+  connection_.MarkZeroRttPacketsForRetransmission(0);
+  EXPECT_TRUE(notifier_.HasLostStreamData());
+}
+
+TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  use_tagging_decrypter();
+
+  const uint8_t tag = 0x07;
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+
+  // Process an encrypted packet which can not yet be decrypted which should
+  // result in the packet being buffered.
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Transition to the new encryption state and process another encrypted packet
+  // which should result in the original packet being processed.
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Finally, process a third packet and note that we do not reprocess the
+  // buffered packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+}
+
+TEST_P(QuicConnectionTest, TestRetransmitOrder) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  QuicByteCount first_packet_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&first_packet_size));
+
+  connection_.SendStreamDataWithString(3, "first_packet", 0, NO_FIN);
+  QuicByteCount second_packet_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&second_packet_size));
+  connection_.SendStreamDataWithString(3, "second_packet", 12, NO_FIN);
+  EXPECT_NE(first_packet_size, second_packet_size);
+  // Advance the clock by huge time to make sure packets will be retransmitted.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+  {
+    InSequence s;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
+  }
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Advance again and expect the packets to be sent again in the same order.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
+  {
+    InSequence s;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
+  }
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+TEST_P(QuicConnectionTest, Buffer100NonDecryptablePacketsThenKeyChange) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(100);
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  use_tagging_decrypter();
+
+  const uint8_t tag = 0x07;
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+
+  // Process an encrypted packet which can not yet be decrypted which should
+  // result in the packet being buffered.
+  for (uint64_t i = 1; i <= 100; ++i) {
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+
+  // Transition to the new encryption state and process another encrypted packet
+  // which should result in the original packets being processed.
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(100);
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+
+  // Finally, process a third packet and note that we do not reprocess the
+  // buffered packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(102, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+}
+
+TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) {
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Test that RTO is started once we write to the socket.
+  writer_->SetWritable();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  connection_.SendStreamDataWithString(3, "bar", 0, NO_FIN);
+  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_EQ(DefaultRetransmissionTime(),
+            retransmission_alarm->deadline() - clock_.Now());
+
+  // Advance the time right before the RTO, then receive an ack for the first
+  // packet to delay the RTO.
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame ack = InitAckFrame(1);
+  ProcessAckPacket(&ack);
+  // Now we have an RTT sample of DefaultRetransmissionTime(500ms),
+  // so the RTO has increased to 2 * SRTT.
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_EQ(retransmission_alarm->deadline() - clock_.Now(),
+            2 * DefaultRetransmissionTime());
+
+  // Move forward past the original RTO and ensure the RTO is still pending.
+  clock_.AdvanceTime(2 * DefaultRetransmissionTime());
+
+  // Ensure the second packet gets retransmitted when it finally fires.
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_EQ(retransmission_alarm->deadline(), clock_.ApproximateNow());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  // Manually cancel the alarm to simulate a real test.
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // The new retransmitted packet number should set the RTO to a larger value
+  // than previously.
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+  QuicTime next_rto_time = retransmission_alarm->deadline();
+  QuicTime expected_rto_time =
+      connection_.sent_packet_manager().GetRetransmissionTime();
+  EXPECT_EQ(next_rto_time, expected_rto_time);
+}
+
+TEST_P(QuicConnectionTest, TestQueued) {
+  connection_.SetMaxTailLossProbes(0);
+
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Unblock the writes and actually send.
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, InitialTimeout) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+
+  // SetFromConfig sets the initial timeouts before negotiation.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  // Subtract a second from the idle timeout on the client side.
+  QuicTime default_timeout =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  // Simulate the timeout alarm firing.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1));
+  connection_.GetTimeoutAlarm()->Fire();
+
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, IdleTimeoutAfterFirstSentPacket) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  QuicTime initial_ddl =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_TRUE(connection_.connected());
+
+  // Advance the time and send the first packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  // This will be the updated deadline for the connection to idle time out.
+  QuicTime new_ddl = clock_.ApproximateNow() +
+                     QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+
+  // Simulate the timeout alarm firing, the connection should not be closed as
+  // a new packet has been sent.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  QuicTime::Delta delay = initial_ddl - clock_.ApproximateNow();
+  clock_.AdvanceTime(delay);
+  // Verify the timeout alarm deadline is updated.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(new_ddl, connection_.GetTimeoutAlarm()->deadline());
+
+  // Simulate the timeout alarm firing again, the connection now should be
+  // closed.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  clock_.AdvanceTime(new_ddl - clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, IdleTimeoutAfterSendTwoPackets) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  QuicTime initial_ddl =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(initial_ddl, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_TRUE(connection_.connected());
+
+  // Immediately send the first packet, this is a rare case but test code will
+  // hit this issue often as MockClock used for tests doesn't move with code
+  // execution until manually adjusted.
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+
+  // Advance the time and send the second packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+
+  // Simulate the timeout alarm firing, the connection will be closed.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  clock_.AdvanceTime(initial_ddl - clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, HandshakeTimeout) {
+  // Use a shorter handshake timeout than idle timeout for this test.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  connection_.SetNetworkTimeouts(timeout, timeout);
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicTime handshake_timeout =
+      clock_.ApproximateNow() + timeout - QuicTime::Delta::FromSeconds(1);
+  EXPECT_EQ(handshake_timeout, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_TRUE(connection_.connected());
+
+  // Send and ack new data 3 seconds later to lengthen the idle timeout.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(3));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&frame);
+
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(2));
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  // Simulate the timeout alarm firing.
+  connection_.GetTimeoutAlarm()->Fire();
+
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_HANDSHAKE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, PingAfterSend) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  // Advance to 5ms, and send a packet to the peer, which will set
+  // the ping alarm.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now recevie an ACK of the previous packet, which will move the
+  // ping alarm forward.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  // The ping timer is set slightly less than 15 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
+      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  writer_->Reset();
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+  writer_->Reset();
+
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  SendAckPacketToPeer();
+
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, ReducedPingTimeout) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  // Use a reduced ping timeout for this connection.
+  connection_.set_ping_timeout(QuicTime::Delta::FromSeconds(10));
+
+  // Advance to 5ms, and send a packet to the peer, which will set
+  // the ping alarm.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(10),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now recevie an ACK of the previous packet, which will move the
+  // ping alarm forward.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  // The ping timer is set slightly less than 10 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromSeconds(10) - QuicTime::Delta::FromMilliseconds(5),
+      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  writer_->Reset();
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+  writer_->Reset();
+
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(false));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  SendAckPacketToPeer();
+
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+}
+
+// Tests whether sending an MTU discovery packet to peer successfully causes the
+// maximum packet size to increase.
+TEST_P(QuicConnectionTest, SendMtuDiscoveryPacket) {
+  MtuDiscoveryTestInit();
+
+  // Send an MTU probe.
+  const size_t new_mtu = kDefaultMaxPacketSize + 100;
+  QuicByteCount mtu_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&mtu_probe_size));
+  connection_.SendMtuDiscoveryPacket(new_mtu);
+  EXPECT_EQ(new_mtu, mtu_probe_size);
+  EXPECT_EQ(QuicPacketNumber(1u), creator_->packet_number());
+
+  // Send more than MTU worth of data.  No acknowledgement was received so far,
+  // so the MTU should be at its old value.
+  const std::string data(kDefaultMaxPacketSize + 1, '.');
+  QuicByteCount size_before_mtu_change;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(2)
+      .WillOnce(SaveArg<3>(&size_before_mtu_change))
+      .WillOnce(Return());
+  connection_.SendStreamDataWithString(3, data, 0, FIN);
+  EXPECT_EQ(QuicPacketNumber(3u), creator_->packet_number());
+  EXPECT_EQ(kDefaultMaxPacketSize, size_before_mtu_change);
+
+  // Acknowledge all packets so far.
+  QuicAckFrame probe_ack = InitAckFrame(3);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(new_mtu, connection_.max_packet_length());
+
+  // Send the same data again.  Check that it fits into a single packet now.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(3, data, 0, FIN);
+  EXPECT_EQ(QuicPacketNumber(4u), creator_->packet_number());
+}
+
+// Verifies that when a MTU probe packet is sent and buffered in a batch writer,
+// the writer is flushed immediately.
+TEST_P(QuicConnectionTest, BatchWriterFlushedAfterMtuDiscoveryPacket) {
+  writer_->SetBatchMode(true);
+  MtuDiscoveryTestInit();
+
+  // Send an MTU probe.
+  const size_t target_mtu = kDefaultMaxPacketSize + 100;
+  QuicByteCount mtu_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&mtu_probe_size));
+  const uint32_t prior_flush_attempts = writer_->flush_attempts();
+  connection_.SendMtuDiscoveryPacket(target_mtu);
+  EXPECT_EQ(target_mtu, mtu_probe_size);
+  EXPECT_EQ(writer_->flush_attempts(), prior_flush_attempts + 1);
+}
+
+// Tests whether MTU discovery does not happen when it is not explicitly enabled
+// by the connection options.
+TEST_P(QuicConnectionTest, MtuDiscoveryDisabled) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 10;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  const QuicPacketCount number_of_packets = packets_between_probes_base * 2;
+  for (QuicPacketCount i = 0; i < number_of_packets; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    EXPECT_EQ(0u, connection_.mtu_probe_count());
+  }
+}
+
+// Tests whether MTU discovery works when all probes are acknowledged on the
+// first try.
+TEST_P(QuicConnectionTest, MtuDiscoveryEnabled) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
+                                  kMtuDiscoveryTargetPacketSizeHigh));
+
+  const QuicPacketNumber probe_packet_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_packet_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  QuicStreamOffset stream_offset = packets_between_probes_base;
+  QuicByteCount last_probe_size = 0;
+  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
+       ++num_probes) {
+    // Send just enough packets without triggering the next probe.
+    for (QuicPacketCount i = 0;
+         i < (packets_between_probes_base << num_probes) - 1; ++i) {
+      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    }
+
+    // Trigger the next probe.
+    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
+    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    QuicByteCount new_probe_size;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .WillOnce(SaveArg<3>(&new_probe_size));
+    connection_.GetMtuDiscoveryAlarm()->Fire();
+    EXPECT_THAT(new_probe_size,
+                InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
+    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
+
+    // Acknowledge all packets sent so far.
+    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
+    ProcessAckPacket(&probe_ack);
+    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
+    EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+    last_probe_size = probe_size;
+    probe_size = new_probe_size;
+  }
+
+  // The last probe size should be equal to the target.
+  EXPECT_EQ(probe_size, kMtuDiscoveryTargetPacketSizeHigh);
+
+  writer_->SetShouldWriteFail();
+
+  // Ignore PACKET_WRITE_ERROR once.
+  SendStreamDataToPeer(3, "(", stream_offset++, NO_FIN, nullptr);
+  EXPECT_EQ(last_probe_size, connection_.max_packet_length());
+  EXPECT_TRUE(connection_.connected());
+
+  // Close connection on another PACKET_WRITE_ERROR.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  SendStreamDataToPeer(3, ")", stream_offset++, NO_FIN, nullptr);
+  EXPECT_EQ(last_probe_size, connection_.max_packet_length());
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+// After a successful MTU probe, one and only one write error should be ignored
+// if it happened in QuicConnection::FlushPacket.
+TEST_P(QuicConnectionTest,
+       MtuDiscoveryIgnoreOneWriteErrorInFlushAfterSuccessfulProbes) {
+  MtuDiscoveryTestInit();
+  writer_->SetBatchMode(true);
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  const QuicByteCount original_max_packet_length =
+      connection_.max_packet_length();
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
+                                  kMtuDiscoveryTargetPacketSizeHigh));
+
+  const QuicPacketNumber probe_packet_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_packet_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  writer_->SetShouldWriteFail();
+
+  // Ignore PACKET_WRITE_ERROR once.
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // flusher's destructor will call connection_.FlushPackets, which should
+    // get a WRITE_STATUS_ERROR from the writer and ignore it.
+  }
+  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
+  EXPECT_TRUE(connection_.connected());
+
+  // Close connection on another PACKET_WRITE_ERROR.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // flusher's destructor will call connection_.FlushPackets, which should
+    // get a WRITE_STATUS_ERROR from the writer and ignore it.
+  }
+  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PACKET_WRITE_ERROR));
+}
+
+// Simulate the case where the first attempt to send a probe is write blocked,
+// and after unblock, the second attempt returns a MSG_TOO_BIG error.
+TEST_P(QuicConnectionTest, MtuDiscoveryWriteBlocked) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  QuicByteCount original_max_packet_length = connection_.max_packet_length();
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  BlockOnNextWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  ASSERT_TRUE(connection_.connected());
+
+  writer_->SetWritable();
+  SimulateNextPacketTooLarge();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_EQ(original_max_packet_length, connection_.max_packet_length());
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Tests whether MTU discovery works correctly when the probes never get
+// acknowledged.
+TEST_P(QuicConnectionTest, MtuDiscoveryFailed) {
+  MtuDiscoveryTestInit();
+
+  // Lower the number of probes between packets in order to make the test go
+  // much faster.
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
+
+  EXPECT_EQ(packets_between_probes_base,
+            QuicConnectionPeer::GetPacketsBetweenMtuProbes(&connection_));
+
+  // This tests sends more packets than strictly necessary to make sure that if
+  // the connection was to send more discovery packets than needed, those would
+  // get caught as well.
+  const QuicPacketCount number_of_packets =
+      packets_between_probes_base * (1 << (kMtuDiscoveryAttempts + 1));
+  std::vector<QuicPacketNumber> mtu_discovery_packets;
+  // Called on many acks.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  for (QuicPacketCount i = 0; i < number_of_packets; i++) {
+    SendStreamDataToPeer(3, "!", i, NO_FIN, nullptr);
+    clock_.AdvanceTime(rtt);
+
+    // Receive an ACK, which marks all data packets as received, and all MTU
+    // discovery packets as missing.
+
+    QuicAckFrame ack;
+
+    if (!mtu_discovery_packets.empty()) {
+      QuicPacketNumber min_packet = *min_element(mtu_discovery_packets.begin(),
+                                                 mtu_discovery_packets.end());
+      QuicPacketNumber max_packet = *max_element(mtu_discovery_packets.begin(),
+                                                 mtu_discovery_packets.end());
+      ack.packets.AddRange(QuicPacketNumber(1), min_packet);
+      ack.packets.AddRange(QuicPacketNumber(max_packet + 1),
+                           creator_->packet_number() + 1);
+      ack.largest_acked = creator_->packet_number();
+
+    } else {
+      ack.packets.AddRange(QuicPacketNumber(1), creator_->packet_number() + 1);
+      ack.largest_acked = creator_->packet_number();
+    }
+
+    ProcessAckPacket(&ack);
+
+    // Trigger MTU probe if it would be scheduled now.
+    if (!connection_.GetMtuDiscoveryAlarm()->IsSet()) {
+      continue;
+    }
+
+    // Fire the alarm.  The alarm should cause a packet to be sent.
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetMtuDiscoveryAlarm()->Fire();
+    // Record the packet number of the MTU discovery packet in order to
+    // mark it as NACK'd.
+    mtu_discovery_packets.push_back(creator_->packet_number());
+  }
+
+  // Ensure the number of packets between probes grows exponentially by checking
+  // it against the closed-form expression for the packet number.
+  ASSERT_EQ(kMtuDiscoveryAttempts, mtu_discovery_packets.size());
+  for (uint64_t i = 0; i < kMtuDiscoveryAttempts; i++) {
+    // 2^0 + 2^1 + 2^2 + ... + 2^n = 2^(n + 1) - 1
+    const QuicPacketCount packets_between_probes =
+        packets_between_probes_base * ((1 << (i + 1)) - 1);
+    EXPECT_EQ(QuicPacketNumber(packets_between_probes + (i + 1)),
+              mtu_discovery_packets[i]);
+  }
+
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  EXPECT_EQ(kDefaultMaxPacketSize, connection_.max_packet_length());
+  EXPECT_EQ(kMtuDiscoveryAttempts, connection_.mtu_probe_count());
+}
+
+// Probe 3 times, the first one succeeds, then fails, then succeeds again.
+TEST_P(QuicConnectionTest, MtuDiscoverySecondProbeFailed) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  QuicStreamOffset stream_offset = 0;
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(),
+                                  kMtuDiscoveryTargetPacketSizeHigh));
+
+  const QuicPacketNumber probe_packet_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_packet_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame first_ack = InitAckFrame(probe_packet_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&first_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  // Send just enough packets without triggering the second probe.
+  for (QuicPacketCount i = 0; i < (packets_between_probes_base << 1) - 1; ++i) {
+    SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the second probe.
+  SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount second_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&second_probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_THAT(second_probe_size,
+              InRange(probe_size, kMtuDiscoveryTargetPacketSizeHigh));
+  EXPECT_EQ(2u, connection_.mtu_probe_count());
+
+  // Acknowledge all packets sent so far, except the second probe.
+  QuicPacketNumber second_probe_packet_number = creator_->packet_number();
+  QuicAckFrame second_ack = InitAckFrame(second_probe_packet_number - 1);
+  ProcessAckPacket(&first_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+
+  // Send just enough packets without triggering the third probe.
+  for (QuicPacketCount i = 0; i < (packets_between_probes_base << 2) - 1; ++i) {
+    SendStreamDataToPeer(3, "@", stream_offset++, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the third probe.
+  SendStreamDataToPeer(3, "#", stream_offset++, NO_FIN, nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount third_probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&third_probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  EXPECT_THAT(third_probe_size, InRange(probe_size, second_probe_size));
+  EXPECT_EQ(3u, connection_.mtu_probe_count());
+
+  // Acknowledge all packets sent so far, except the second probe.
+  QuicAckFrame third_ack =
+      ConstructAckFrame(creator_->packet_number(), second_probe_packet_number);
+  ProcessAckPacket(&third_ack);
+  EXPECT_EQ(third_probe_size, connection_.max_packet_length());
+
+  SendStreamDataToPeer(3, "$", stream_offset++, NO_FIN, nullptr);
+  EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
+
+  if (connection_.PathDegradingDetectionInProgress() &&
+      QuicConnectionPeer::GetPathDegradingDeadline(&connection_) <
+          QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
+              &connection_)) {
+    // Fire path degrading alarm first.
+    connection_.PathDegradingTimeout();
+  }
+
+  // Verify the max packet size has not reduced.
+  EXPECT_EQ(third_probe_size, connection_.max_packet_length());
+
+  // Fire alarm to get path mtu reduction callback called.
+  EXPECT_TRUE(connection_.PathMtuReductionDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+
+  // Verify the max packet size has reduced to the previous value.
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+}
+
+// Tests whether MTU discovery works when the writer has a limit on how large a
+// packet can be.
+TEST_P(QuicConnectionTest, MtuDiscoveryWriterLimited) {
+  MtuDiscoveryTestInit();
+
+  const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
+  writer_->set_max_packet_size(mtu_limit);
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  QuicByteCount probe_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(SaveArg<3>(&probe_size));
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+
+  EXPECT_THAT(probe_size, InRange(connection_.max_packet_length(), mtu_limit));
+
+  const QuicPacketNumber probe_sequence_number =
+      FirstSendingPacketNumber() + packets_between_probes_base;
+  ASSERT_EQ(probe_sequence_number, creator_->packet_number());
+
+  // Acknowledge all packets sent so far.
+  QuicAckFrame probe_ack = InitAckFrame(probe_sequence_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(probe_size, connection_.max_packet_length());
+  EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+
+  QuicStreamOffset stream_offset = packets_between_probes_base;
+  for (size_t num_probes = 1; num_probes < kMtuDiscoveryAttempts;
+       ++num_probes) {
+    // Send just enough packets without triggering the next probe.
+    for (QuicPacketCount i = 0;
+         i < (packets_between_probes_base << num_probes) - 1; ++i) {
+      SendStreamDataToPeer(3, ".", stream_offset++, NO_FIN, nullptr);
+      ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    }
+
+    // Trigger the next probe.
+    SendStreamDataToPeer(3, "!", stream_offset++, NO_FIN, nullptr);
+    ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+    QuicByteCount new_probe_size;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .WillOnce(SaveArg<3>(&new_probe_size));
+    connection_.GetMtuDiscoveryAlarm()->Fire();
+    EXPECT_THAT(new_probe_size, InRange(probe_size, mtu_limit));
+    EXPECT_EQ(num_probes + 1, connection_.mtu_probe_count());
+
+    // Acknowledge all packets sent so far.
+    QuicAckFrame probe_ack = InitAckFrame(creator_->packet_number());
+    ProcessAckPacket(&probe_ack);
+    EXPECT_EQ(new_probe_size, connection_.max_packet_length());
+    EXPECT_EQ(0u, connection_.GetBytesInFlight());
+
+    probe_size = new_probe_size;
+  }
+
+  // The last probe size should be equal to the target.
+  EXPECT_EQ(probe_size, mtu_limit);
+}
+
+// Tests whether MTU discovery works when the writer returns an error despite
+// advertising higher packet length.
+TEST_P(QuicConnectionTest, MtuDiscoveryWriterFailed) {
+  MtuDiscoveryTestInit();
+
+  const QuicByteCount mtu_limit = kMtuDiscoveryTargetPacketSizeHigh - 1;
+  const QuicByteCount initial_mtu = connection_.max_packet_length();
+  EXPECT_LT(initial_mtu, mtu_limit);
+  writer_->set_max_packet_size(mtu_limit);
+
+  const QuicPacketCount packets_between_probes_base = 5;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Trigger the probe.
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  ASSERT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  writer_->SimulateNextPacketTooLarge();
+  connection_.GetMtuDiscoveryAlarm()->Fire();
+  ASSERT_TRUE(connection_.connected());
+
+  // Send more data.
+  QuicPacketNumber probe_number = creator_->packet_number();
+  QuicPacketCount extra_packets = packets_between_probes_base * 3;
+  for (QuicPacketCount i = 0; i < extra_packets; i++) {
+    connection_.EnsureWritableAndSendStreamData5();
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  // Acknowledge all packets sent so far, except for the lost probe.
+  QuicAckFrame probe_ack =
+      ConstructAckFrame(creator_->packet_number(), probe_number);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&probe_ack);
+  EXPECT_EQ(initial_mtu, connection_.max_packet_length());
+
+  // Send more packets, and ensure that none of them sets the alarm.
+  for (QuicPacketCount i = 0; i < 4 * packets_between_probes_base; i++) {
+    connection_.EnsureWritableAndSendStreamData5();
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  EXPECT_EQ(initial_mtu, connection_.max_packet_length());
+  EXPECT_EQ(1u, connection_.mtu_probe_count());
+}
+
+TEST_P(QuicConnectionTest, NoMtuDiscoveryAfterConnectionClosed) {
+  MtuDiscoveryTestInit();
+
+  const QuicPacketCount packets_between_probes_base = 10;
+  set_packets_between_probes_base(packets_between_probes_base);
+
+  connection_.EnablePathMtuDiscovery(send_algorithm_);
+
+  // Send enough packets so that the next one triggers path MTU discovery.
+  for (QuicPacketCount i = 0; i < packets_between_probes_base - 1; i++) {
+    SendStreamDataToPeer(3, ".", i, NO_FIN, nullptr);
+    ASSERT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+  }
+
+  SendStreamDataToPeer(3, "!", packets_between_probes_base - 1, NO_FIN,
+                       nullptr);
+  EXPECT_TRUE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendDuringHandshake) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Now send more data. This will not move the timeout because
+  // no data has been received since the previous write.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(initial_idle_timeout - five_ms - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(five_ms);
+  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterRetransmission) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime start_time = clock_.Now();
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  QuicTime default_timeout = clock_.Now() + initial_idle_timeout;
+
+  connection_.SetMaxTailLossProbes(0);
+  const QuicTime default_retransmission_time =
+      start_time + DefaultRetransmissionTime();
+
+  ASSERT_LT(default_retransmission_time, default_timeout);
+
+  // When we send a packet, the timeout will change to 5 ms +
+  // kInitialIdleTimeoutSecs (but it will not reschedule the alarm).
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  const QuicTime send_time = start_time + five_ms;
+  clock_.AdvanceTime(five_ms);
+  ASSERT_EQ(send_time, clock_.Now());
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Move forward 5 ms and receive a packet, which will move the timeout
+  // forward 5 ms more (but will not reschedule the alarm).
+  const QuicTime receive_time = send_time + five_ms;
+  clock_.AdvanceTime(receive_time - clock_.Now());
+  ASSERT_EQ(receive_time, clock_.Now());
+  ProcessPacket(1);
+
+  // Now move forward to the retransmission time and retransmit the
+  // packet, which should move the timeout forward again (but will not
+  // reschedule the alarm).
+  EXPECT_EQ(default_retransmission_time + five_ms,
+            connection_.GetRetransmissionAlarm()->deadline());
+  // Simulate the retransmission alarm firing.
+  const QuicTime rto_time = send_time + DefaultRetransmissionTime();
+  const QuicTime final_timeout = rto_time + initial_idle_timeout;
+  clock_.AdvanceTime(rto_time - clock_.Now());
+  ASSERT_EQ(rto_time, clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Advance to the original timeout and fire the alarm. The connection should
+  // timeout, and the alarm should be registered based on the time of the
+  // retransmission.
+  clock_.AdvanceTime(default_timeout - clock_.Now());
+  ASSERT_EQ(default_timeout.ToDebuggingValue(),
+            clock_.Now().ToDebuggingValue());
+  EXPECT_EQ(default_timeout, clock_.Now());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+  ASSERT_EQ(final_timeout.ToDebuggingValue(),
+            connection_.GetTimeoutAlarm()->deadline().ToDebuggingValue());
+
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(final_timeout - clock_.Now());
+  EXPECT_EQ(connection_.GetTimeoutAlarm()->deadline(), clock_.Now());
+  EXPECT_EQ(final_timeout, clock_.Now());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
+  // When the idle timeout fires, verify that by default we do not send any
+  // connection close packets.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  // Create a handshake message that also enables silent close.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta default_idle_timeout =
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Now send more data. This will not move the timeout because
+  // no data has been received since the previous write.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(default_idle_timeout - five_ms - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // This time, we should time out.
+  // This results in a SILENT_CLOSE, so the writer will not be invoked
+  // and will not save the frame. Grab the frame from OnConnectionClosed
+  // directly.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+
+  clock_.AdvanceTime(five_ms);
+  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_NETWORK_IDLE_TIMEOUT));
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseAndTLP) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  // Same test as above, but sending TLPs causes a connection close to be sent.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  // Create a handshake message that also enables silent close.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta default_idle_timeout =
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Retransmit the packet via tail loss probe.
+  clock_.AdvanceTime(connection_.GetRetransmissionAlarm()->deadline() -
+                     clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // This time, we should time out and send a connection close due to the TLP.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
+                     clock_.ApproximateNow() + five_ms);
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
+  // Same test as above, but having open streams causes a connection close
+  // to be sent.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  // Create a handshake message that also enables silent close.
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta default_idle_timeout =
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
+
+  // When we send a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  clock_.AdvanceTime(five_ms);
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Indicate streams are still open.
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail)) {
+    EXPECT_CALL(visitor_, GetStreamsInfoForLogging()).WillOnce(Return(""));
+  }
+
+  // This time, we should time out and send a connection close due to the TLP.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
+                     clock_.ApproximateNow() + five_ms);
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterReceive) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
+
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, NO_FIN);
+
+  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+  clock_.AdvanceTime(five_ms);
+
+  // When we receive a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  QuicAckFrame ack = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(initial_idle_timeout - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  clock_.AdvanceTime(five_ms);
+  EXPECT_EQ(default_timeout + five_ms, clock_.ApproximateNow());
+  connection_.GetTimeoutAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  const QuicTime::Delta initial_idle_timeout =
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  connection_.SetNetworkTimeouts(
+      QuicTime::Delta::Infinite(),
+      initial_idle_timeout + QuicTime::Delta::FromSeconds(1));
+  const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
+  QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, NO_FIN);
+
+  EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+  clock_.AdvanceTime(five_ms);
+
+  // When we receive a packet, the timeout will change to 5ms +
+  // kInitialIdleTimeoutSecs.
+  QuicAckFrame ack = InitAckFrame(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  // The original alarm will fire.  We should not time out because we had a
+  // network event at t=5ms.  The alarm will reregister.
+  clock_.AdvanceTime(initial_idle_timeout - five_ms);
+  EXPECT_EQ(default_timeout, clock_.ApproximateNow());
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(default_timeout + five_ms,
+            connection_.GetTimeoutAlarm()->deadline());
+
+  // Now, send packets while advancing the time and verify that the connection
+  // eventually times out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  for (int i = 0; i < 100 && connection_.connected(); ++i) {
+    QUIC_LOG(INFO) << "sending data packet";
+    connection_.SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()),
+        "foo", 0, NO_FIN);
+    connection_.GetTimeoutAlarm()->Fire();
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
+}
+
+TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(2);
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k5RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 6 times, twice for TLP and 4 times for RTO.
+  for (int i = 0; i < 6; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(4u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  // This time, we should time out.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, SendScheduler) {
+  // Test that if we send a packet without delay, it is not queued.
+  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> packet =
+      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
+                         HAS_RETRANSMITTABLE_DATA, false, false);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, FailToSendFirstPacket) {
+  // Test that the connection does not crash when it fails to send the first
+  // packet at which point self_address_ might be uninitialized.
+  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+  std::unique_ptr<QuicPacket> packet =
+      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
+  writer_->SetShouldWriteFail();
+  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
+                         HAS_RETRANSMITTABLE_DATA, false, false);
+}
+
+TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
+  QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> packet =
+      ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _))
+      .Times(0);
+  connection_.SendPacket(ENCRYPTION_INITIAL, 1, std::move(packet),
+                         HAS_RETRANSMITTABLE_DATA, false, false);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
+  // Queue the first packet.
+  size_t payload_length = connection_.max_packet_length();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(testing::Return(false));
+  const std::string payload(payload_length, 'a');
+  QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.version().transport_version, Perspective::IS_CLIENT));
+  EXPECT_EQ(0u, connection_
+                    .SendStreamDataWithString(first_bidi_stream_id, payload, 0,
+                                              NO_FIN)
+                    .bytes_consumed);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+TEST_P(QuicConnectionTest, SendingThreePackets) {
+  // Make the payload twice the size of the packet, so 3 packets are written.
+  size_t total_payload_length = 2 * connection_.max_packet_length();
+  const std::string payload(total_payload_length, 'a');
+  QuicStreamId first_bidi_stream_id(QuicUtils::GetFirstBidirectionalStreamId(
+      connection_.version().transport_version, Perspective::IS_CLIENT));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+  EXPECT_EQ(payload.size(), connection_
+                                .SendStreamDataWithString(first_bidi_stream_id,
+                                                          payload, 0, NO_FIN)
+                                .bytes_consumed);
+}
+
+TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!GetParam().version.HasIetfInvariantHeader()) {
+    // For IETF QUIC, encryption level will be switched to FORWARD_SECURE in
+    // SendStreamDataWithString.
+    QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  }
+  // Set up a larger payload than will fit in one packet.
+  const std::string payload(connection_.max_packet_length(), 'a');
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+
+  // Now send some packets with no truncation.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  EXPECT_EQ(payload.size(),
+            connection_.SendStreamDataWithString(3, payload, 0, NO_FIN)
+                .bytes_consumed);
+  // Track the size of the second packet here.  The overhead will be the largest
+  // we see in this test, due to the non-truncated connection id.
+  size_t non_truncated_packet_size = writer_->last_packet_size();
+
+  // Change to a 0 byte connection id.
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  EXPECT_EQ(payload.size(),
+            connection_.SendStreamDataWithString(3, payload, 1350, NO_FIN)
+                .bytes_consumed);
+  if (connection_.version().HasIetfInvariantHeader()) {
+    // Short header packets sent from server omit connection ID already, and
+    // stream offset size increases from 0 to 2.
+    EXPECT_EQ(non_truncated_packet_size, writer_->last_packet_size() - 2);
+  } else {
+    // Just like above, we save 8 bytes on payload, and 8 on truncation. -2
+    // because stream offset size is 2 instead of 0.
+    EXPECT_EQ(non_truncated_packet_size,
+              writer_->last_packet_size() + 8 * 2 - 2);
+  }
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAck) {
+  QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+  // Simulate delayed ack alarm firing.
+  clock_.AdvanceTime(DefaultDelayedAckTime());
+  connection_.GetAckAlarm()->Fire();
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() +
+                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // The 10th received packet causes an ack to be sent.
+  for (int i = 0; i < 9; ++i) {
+    EXPECT_TRUE(connection_.HasPendingAcks());
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_ZERO_RTT);
+  }
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  // No limit on the number of packets received before sending an ack.
+  connection_options.push_back(kAKDU);
+  config.SetConnectionOptionsToSend(connection_options);
+  connection_.SetFromConfig(config);
+
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() +
+                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // 18 packets will not cause an ack to be sent.  19 will because when
+  // stop waiting frames are in use, we ack every 20 packets no matter what.
+  for (int i = 0; i < 18; ++i) {
+    EXPECT_TRUE(connection_.HasPendingAcks());
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_ZERO_RTT);
+  }
+  // The delayed ack timer should still be set to the expected deadline.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
+  EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(AnyNumber());
+  QuicConnectionPeer::SetAckDecimationDelay(&connection_, 0.125);
+
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // The ack time should be based on min_rtt/8, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() +
+                      QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  const uint8_t tag = 0x07;
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(tag));
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(tag));
+  // Process a packet from the non-crypto stream.
+  frame1_.stream_id = 3;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
+  // instead of ENCRYPTION_INITIAL.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_ZERO_RTT);
+
+  // Check if delayed ack timer is running for the expected interval.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // The 10th received packet causes an ack to be sent.
+  for (int i = 0; i < 9; ++i) {
+    EXPECT_TRUE(connection_.HasPendingAcks());
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_ZERO_RTT);
+  }
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  // Check that ack is sent and that delayed ack alarm is set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // Completing the handshake as the server does nothing.
+  QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_SERVER);
+  connection_.OnHandshakeComplete();
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+  // Complete the handshake as the client decreases the delayed ack time to 0ms.
+  QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_CLIENT);
+  connection_.OnHandshakeComplete();
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
+              connection_.GetAckAlarm()->deadline());
+  } else {
+    EXPECT_EQ(clock_.ApproximateNow(), connection_.GetAckAlarm()->deadline());
+  }
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  ProcessPacket(2);
+  // Check that ack is sent and that delayed ack alarm is reset.
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessPacket(2);
+  size_t frames_per_ack = GetParam().no_stop_waiting ? 1 : 2;
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  writer_->Reset();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessPacket(4);
+  EXPECT_EQ(0u, writer_->frame_count());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(5);
+  padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + frames_per_ack, writer_->frame_count());
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  writer_->Reset();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  // Now only set the timer on the 6th packet, instead of sending another ack.
+  ProcessPacket(6);
+  padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count, writer_->frame_count());
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ProcessDataPacket(1);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  // Check that ack is bundled with outgoing data and that delayed ack
+  // alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  connection_.SendCryptoDataWithString("foo", 0);
+  // Check that ack is bundled with outgoing crypto data.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  } else {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  }
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_FALSE(connection_.HasQueuedData());
+  connection_.SendCryptoDataWithString("bar", 3);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    // CRYPTO frames are not flushed when writer is blocked.
+    EXPECT_FALSE(connection_.HasQueuedData());
+  } else {
+    EXPECT_TRUE(connection_.HasQueuedData());
+  }
+}
+
+TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(IgnoreResult(InvokeWithoutArgs(
+          &connection_, &TestConnection::SendCryptoStreamData)));
+  // Process a packet from the crypto stream, which is frame1_'s default.
+  // Receiving the CHLO as packet 2 first will cause the connection to
+  // immediately send an ack, due to the packet gap.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Check that ack is sent and that delayed ack alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+  } else {
+    EXPECT_EQ(1u, writer_->crypto_frames().size());
+  }
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+
+  // Process two packets from the crypto stream, which is frame1_'s default,
+  // simulating a 2 packet reject.
+  {
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+    } else {
+      EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+    }
+    ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+    // Send the new CHLO when the REJ is processed.
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      EXPECT_CALL(visitor_, OnCryptoFrame(_))
+          .WillOnce(IgnoreResult(InvokeWithoutArgs(
+              &connection_, &TestConnection::SendCryptoStreamData)));
+    } else {
+      EXPECT_CALL(visitor_, OnStreamFrame(_))
+          .WillOnce(IgnoreResult(InvokeWithoutArgs(
+              &connection_, &TestConnection::SendCryptoStreamData)));
+    }
+    ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  }
+  // Check that ack is sent and that delayed ack alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+  } else {
+    EXPECT_EQ(1u, writer_->crypto_frames().size());
+  }
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      3, NO_FIN);
+  // Ack the second packet, which will retransmit the first packet.
+  QuicAckFrame ack = ConstructAckFrame(2, 1);
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  writer_->Reset();
+
+  // Now ack the retransmission, which will both raise the high water mark
+  // and see if there is more data to send.
+  ack = ConstructAckFrame(3, 1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(&ack);
+
+  // Check that no packet is sent and the ack alarm isn't set.
+  EXPECT_EQ(0u, writer_->frame_count());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  writer_->Reset();
+
+  // Send the same ack, but send both data and an ack together.
+  ack = ConstructAckFrame(3, 1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(visitor_, OnCanWrite())
+      .WillOnce(IgnoreResult(InvokeWithoutArgs(
+          &connection_, &TestConnection::EnsureWritableAndSendStreamData5)));
+  ProcessAckPacket(&ack);
+
+  // Check that ack is bundled with outgoing data and the delayed ack
+  // alarm is reset.
+  if (GetParam().no_stop_waiting) {
+    // Do not ACK acks.
+    EXPECT_EQ(1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
+  if (GetParam().no_stop_waiting) {
+    EXPECT_TRUE(writer_->ack_frames().empty());
+  } else {
+    EXPECT_FALSE(writer_->ack_frames().empty());
+    EXPECT_EQ(QuicPacketNumber(3u),
+              LargestAcked(writer_->ack_frames().front()));
+  }
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, NoAckSentForClose) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  ProcessClosePacket(2);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, SendWhenDisconnected) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_EQ(DISCARD, connection_.GetSerializedPacketFate(
+                         /*is_mtu_discovery=*/false, ENCRYPTION_INITIAL));
+}
+
+TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
+
+  EXPECT_QUIC_BUG(connection_.SendConnectivityProbingPacket(
+                      writer_.get(), connection_.peer_address()),
+                  "Not sending connectivity probing packet as connection is "
+                  "disconnected.");
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+  // Block next write so that sending connectivity probe will encounter a
+  // blocked write when send a connectivity probe to the peer.
+  probing_writer.BlockOnNextWrite();
+  // Connection will not be marked as write blocked as connectivity probe only
+  // affects the probing_writer which is not the default.
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(1);
+  connection_.SendConnectivityProbingPacket(&probing_writer,
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  // Block next write so that sending connectivity probe will encounter a
+  // blocked write when send a connectivity probe to the peer.
+  writer_->BlockOnNextWrite();
+  // Connection will be marked as write blocked as server uses the default
+  // writer to send connectivity probes.
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(1);
+  if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
+    QuicPathFrameBuffer payload{
+        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendPathChallenge(
+        payload, connection_.self_address(), connection_.peer_address(),
+        connection_.effective_peer_address(), writer_.get());
+  } else {
+    connection_.SendConnectivityProbingPacket(writer_.get(),
+                                              connection_.peer_address());
+  }
+}
+
+TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+  probing_writer.SetShouldWriteFail();
+
+  // Connection should not be closed if a connectivity probe is failed to be
+  // sent.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
+  connection_.SendConnectivityProbingPacket(&probing_writer,
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterErrorWhenServerSendsConnectivityProbe) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  writer_->SetShouldWriteFail();
+  // Connection should not be closed if a connectivity probe is failed to be
+  // sent.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, PublicReset) {
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicPublicResetPacket header;
+  // Public reset packet in only built by server.
+  header.connection_id = connection_id_;
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      framer_.BuildPublicResetPacket(header));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PUBLIC_RESET));
+}
+
+TEST_P(QuicConnectionTest, IetfStatelessReset) {
+  if (!GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
+                                                 kTestStatelessResetToken);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
+                                                /*received_packet_length=*/100,
+                                                kTestStatelessResetToken));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  if (!connection_.use_path_validator()) {
+    EXPECT_CALL(visitor_, ValidateStatelessReset(_, _)).WillOnce(Return(true));
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PUBLIC_RESET));
+}
+
+TEST_P(QuicConnectionTest, GoAway) {
+  if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) {
+    // GoAway is not available in version 99.
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicGoAwayFrame* goaway = new QuicGoAwayFrame();
+  goaway->last_good_stream_id = 1;
+  goaway->error_code = QUIC_PEER_GOING_AWAY;
+  goaway->reason_phrase = "Going away.";
+  EXPECT_CALL(visitor_, OnGoAway(_));
+  ProcessGoAwayPacket(goaway);
+}
+
+TEST_P(QuicConnectionTest, WindowUpdate) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicWindowUpdateFrame window_update;
+  window_update.stream_id = 3;
+  window_update.max_data = 1234;
+  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
+  ProcessFramePacket(QuicFrame(window_update));
+}
+
+TEST_P(QuicConnectionTest, Blocked) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicBlockedFrame blocked;
+  blocked.stream_id = 3;
+  EXPECT_CALL(visitor_, OnBlockedFrame(_));
+  ProcessFramePacket(QuicFrame(blocked));
+  EXPECT_EQ(1u, connection_.GetStats().blocked_frames_received);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+}
+
+TEST_P(QuicConnectionTest, ZeroBytePacket) {
+  // Don't close the connection for zero byte packets.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  QuicReceivedPacket encrypted(nullptr, 0, QuicTime::Zero());
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, encrypted);
+}
+
+TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    return;
+  }
+  // Set the packet number of the ack packet to be least unacked (4).
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 3);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessStopWaitingPacket(InitStopWaitingFrame(4));
+  EXPECT_FALSE(connection_.ack_frame().packets.Empty());
+}
+
+TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
+  // All supported versions except the one the connection supports.
+  ParsedQuicVersionVector versions;
+  for (auto version : AllSupportedVersions()) {
+    if (version != connection_.version()) {
+      versions.push_back(version);
+    }
+  }
+
+  // Send a version negotiation packet.
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(),
+          connection_.version().HasIetfInvariantHeader(),
+          connection_.version().HasLengthPrefixedConnectionIds(), versions));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  // Verify no connection close packet gets sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_INVALID_VERSION));
+}
+
+TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiationWithConnectionClose) {
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kINVC);
+  config.SetClientConnectionOptions(connection_options);
+  connection_.SetFromConfig(config);
+
+  // All supported versions except the one the connection supports.
+  ParsedQuicVersionVector versions;
+  for (auto version : AllSupportedVersions()) {
+    if (version != connection_.version()) {
+      versions.push_back(version);
+    }
+  }
+
+  // Send a version negotiation packet.
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(),
+          connection_.version().HasIetfInvariantHeader(),
+          connection_.version().HasLengthPrefixedConnectionIds(), versions));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  // Verify connection close packet gets sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1u));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_INVALID_VERSION));
+}
+
+TEST_P(QuicConnectionTest, BadVersionNegotiation) {
+  // Send a version negotiation packet with the version the client started with.
+  // It should be rejected.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(),
+          connection_.version().HasIetfInvariantHeader(),
+          connection_.version().HasLengthPrefixedConnectionIds(),
+          AllSupportedVersions()));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
+}
+
+TEST_P(QuicConnectionTest, CheckSendStats) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(0);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(3, "first", 0, NO_FIN);
+  size_t first_packet_size = writer_->last_packet_size();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendStreamDataWithString(5, "second", 0, NO_FIN);
+  size_t second_packet_size = writer_->last_packet_size();
+
+  // 2 retransmissions due to rto, 1 due to explicit nack.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+
+  // Retransmit due to RTO.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  // Retransmit due to explicit nacks.
+  QuicAckFrame nack_three =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(4), QuicPacketNumber(5)}});
+
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(3), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessAckPacket(&nack_three);
+
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .WillOnce(Return(QuicBandwidth::Zero()));
+
+  const QuicConnectionStats& stats = connection_.GetStats();
+  // For IETF QUIC, version is not included as the encryption level switches to
+  // FORWARD_SECURE in SendStreamDataWithString.
+  size_t save_on_version =
+      GetParam().version.HasIetfInvariantHeader() ? 0 : kQuicVersionSize;
+  EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - save_on_version,
+            stats.bytes_sent);
+  EXPECT_EQ(5u, stats.packets_sent);
+  EXPECT_EQ(2 * first_packet_size + second_packet_size - save_on_version,
+            stats.bytes_retransmitted);
+  EXPECT_EQ(3u, stats.packets_retransmitted);
+  EXPECT_EQ(1u, stats.rto_count);
+  EXPECT_EQ(kDefaultMaxPacketSize, stats.egress_mtu);
+}
+
+TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
+  // Construct a packet with stream frame and connection close frame.
+  QuicPacketHeader header;
+  if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+    header.source_connection_id = connection_id_;
+    header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    if (!peer_framer_.version().HasIetfInvariantHeader()) {
+      header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    }
+  } else {
+    header.destination_connection_id = connection_id_;
+    if (peer_framer_.version().HasIetfInvariantHeader()) {
+      header.destination_connection_id_included = CONNECTION_ID_ABSENT;
+    }
+  }
+  header.packet_number = QuicPacketNumber(1);
+  header.version_flag = false;
+
+  QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY;
+  // This QuicConnectionCloseFrame will default to being for a Google QUIC
+  // close. If doing IETF QUIC then set fields appropriately for CC/T or CC/A,
+  // depending on the mapping.
+  QuicConnectionCloseFrame qccf(peer_framer_.transport_version(),
+                                kQuicErrorCode, NO_IETF_QUIC_ERROR, "",
+                                /*transport_close_frame_type=*/0);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  frames.push_back(QuicFrame(&qccf));
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+  EXPECT_TRUE(nullptr != packet);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
+      kMaxOutgoingPacketSize);
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_PEER_GOING_AWAY));
+}
+
+TEST_P(QuicConnectionTest, SelectMutualVersion) {
+  connection_.SetSupportedVersions(AllSupportedVersions());
+  // Set the connection to speak the lowest quic version.
+  connection_.set_version(QuicVersionMin());
+  EXPECT_EQ(QuicVersionMin(), connection_.version());
+
+  // Pass in available versions which includes a higher mutually supported
+  // version.  The higher mutually supported version should be selected.
+  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  EXPECT_TRUE(connection_.SelectMutualVersion(supported_versions));
+  EXPECT_EQ(QuicVersionMax(), connection_.version());
+
+  // Expect that the lowest version is selected.
+  // Ensure the lowest supported version is less than the max, unless they're
+  // the same.
+  ParsedQuicVersionVector lowest_version_vector;
+  lowest_version_vector.push_back(QuicVersionMin());
+  EXPECT_TRUE(connection_.SelectMutualVersion(lowest_version_vector));
+  EXPECT_EQ(QuicVersionMin(), connection_.version());
+
+  // Shouldn't be able to find a mutually supported version.
+  ParsedQuicVersionVector unsupported_version;
+  unsupported_version.push_back(UnsupportedQuicVersion());
+  EXPECT_FALSE(connection_.SelectMutualVersion(unsupported_version));
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseWhenWritable) {
+  EXPECT_FALSE(writer_->IsWriteBlocked());
+
+  // Send a packet.
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  TriggerConnectionClose();
+  EXPECT_LE(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseGettingWriteBlocked) {
+  BlockOnNextWrite();
+  TriggerConnectionClose();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  TriggerConnectionClose();
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, OnPacketSentDebugVisitor) {
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
+
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
+  QuicPacketHeader header;
+  header.packet_number = QuicPacketNumber(1);
+  if (GetParam().version.HasIetfInvariantHeader()) {
+    header.form = IETF_QUIC_LONG_HEADER_PACKET;
+  }
+
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketHeader(Ref(header), _, _)).Times(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(1);
+  EXPECT_CALL(debug_visitor, OnSuccessfulVersionNegotiation(_)).Times(1);
+  connection_.OnPacketHeader(header);
+}
+
+TEST_P(QuicConnectionTest, Pacing) {
+  TestConnection server(connection_id_, kPeerAddress, kSelfAddress,
+                        helper_.get(), alarm_factory_.get(), writer_.get(),
+                        Perspective::IS_SERVER, version());
+  TestConnection client(connection_id_, kSelfAddress, kPeerAddress,
+                        helper_.get(), alarm_factory_.get(), writer_.get(),
+                        Perspective::IS_CLIENT, version());
+  EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
+      static_cast<const QuicSentPacketManager*>(
+          &client.sent_packet_manager())));
+  EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
+      static_cast<const QuicSentPacketManager*>(
+          &server.sent_packet_manager())));
+}
+
+TEST_P(QuicConnectionTest, WindowUpdateInstigateAcks) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Send a WINDOW_UPDATE frame.
+  QuicWindowUpdateFrame window_update;
+  window_update.stream_id = 3;
+  window_update.max_data = 1234;
+  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
+  ProcessFramePacket(QuicFrame(window_update));
+
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  // Send a BLOCKED frame.
+  QuicBlockedFrame blocked;
+  blocked.stream_id = 3;
+  EXPECT_CALL(visitor_, OnBlockedFrame(_));
+  ProcessFramePacket(QuicFrame(blocked));
+
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
+  // Enable pacing.
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  // Send two packets.  One packet is not sufficient because if it gets acked,
+  // there will be no packets in flight after that and the pacer will always
+  // allow the next packet in that situation.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, NO_FIN);
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "bar",
+      3, NO_FIN);
+  connection_.OnCanWrite();
+
+  // Schedule the next packet for a few milliseconds in future.
+  QuicSentPacketManagerPeer::DisablePacerBursts(manager_);
+  QuicTime scheduled_pacing_time =
+      clock_.Now() + QuicTime::Delta::FromMilliseconds(5);
+  QuicSentPacketManagerPeer::SetNextPacedPacketTime(manager_,
+                                                    scheduled_pacing_time);
+
+  // Send a packet and have it be blocked by congestion control.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
+  connection_.SendStreamDataWithString(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "baz",
+      6, NO_FIN);
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+
+  // Process an ack and the send alarm will be set to the new 5ms delay.
+  QuicAckFrame ack = InitAckFrame(1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  ProcessAckPacket(&ack);
+  size_t padding_frame_count = writer_->padding_frames().size();
+  EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_TRUE(connection_.GetSendAlarm()->IsSet());
+  EXPECT_EQ(scheduled_pacing_time, connection_.GetSendAlarm()->deadline());
+  writer_->Reset();
+}
+
+TEST_P(QuicConnectionTest, SendAcksImmediately) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  CongestionBlockWrites();
+  SendAckPacketToPeer();
+}
+
+TEST_P(QuicConnectionTest, SendPingImmediately) {
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  CongestionBlockWrites();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(debug_visitor, OnPingSent()).Times(1);
+  connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
+TEST_P(QuicConnectionTest, SendBlockedImmediately) {
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+  EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent);
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
+TEST_P(QuicConnectionTest, FailedToSendBlockedFrames) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  QuicBlockedFrame blocked(1, 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  connection_.SendControlFrame(QuicFrame(blocked));
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
+TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, {}, 0, FIN),
+                  "Cannot send stream data with level: ENCRYPTION_INITIAL");
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA));
+}
+
+TEST_P(QuicConnectionTest, SetRetransmissionAlarmForCryptoPacket) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendCryptoStreamData();
+
+  // Verify retransmission timer is correctly set after crypto packet has been
+  // sent.
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime retransmission_time =
+      QuicConnectionPeer::GetSentPacketManager(&connection_)
+          ->GetRetransmissionTime();
+  EXPECT_NE(retransmission_time, clock_.ApproximateNow());
+  EXPECT_EQ(retransmission_time,
+            connection_.GetRetransmissionAlarm()->deadline());
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+// Includes regression test for b/69979024.
+TEST_P(QuicConnectionTest, PathDegradingDetectionForNonCryptoPackets) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  for (int i = 0; i < 2; ++i) {
+    // Send a packet. Now there's a retransmittable packet on the wire, so the
+    // path degrading detection should be set.
+    connection_.SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
+        offset, NO_FIN);
+    offset += data_size;
+    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+    // Check the deadline of the path degrading detection.
+    QuicTime::Delta delay =
+        QuicConnectionPeer::GetSentPacketManager(&connection_)
+            ->GetPathDegradingDelay();
+    EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                         clock_.ApproximateNow());
+
+    // Send a second packet. The path degrading detection's deadline should
+    // remain the same.
+    // Regression test for b/69979024.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    QuicTime prev_deadline =
+        connection_.GetBlackholeDetectorAlarm()->deadline();
+    connection_.SendStreamDataWithString(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
+        offset, NO_FIN);
+    offset += data_size;
+    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+    EXPECT_EQ(prev_deadline,
+              connection_.GetBlackholeDetectorAlarm()->deadline());
+
+    // Now receive an ACK of the first packet. This should advance the path
+    // degrading detection's deadline since forward progress has been made.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    if (i == 0) {
+      EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+    }
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+    // Check the deadline of the path degrading detection.
+    delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                ->GetPathDegradingDelay();
+    EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                         clock_.ApproximateNow());
+
+    if (i == 0) {
+      // Now receive an ACK of the second packet. Since there are no more
+      // retransmittable packets on the wire, this should cancel the path
+      // degrading detection.
+      clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+      EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+      frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+      ProcessAckPacket(&frame);
+      EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+    } else {
+      // Advance time to the path degrading alarm's deadline and simulate
+      // firing the alarm.
+      clock_.AdvanceTime(delay);
+      EXPECT_CALL(visitor_, OnPathDegrading());
+      connection_.PathDegradingTimeout();
+      EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+    }
+  }
+  EXPECT_TRUE(connection_.IsPathDegrading());
+}
+
+TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPingAlarm) {
+  const QuicTime::Delta retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(50);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Send a packet.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  // Now there's a retransmittable packet on the wire, so the path degrading
+  // alarm should be set.
+  // The retransmittable-on-wire alarm should not be set.
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+  ASSERT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive an ACK of the packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  // No more retransmittable packets on the wire, so the path degrading alarm
+  // should be cancelled, and the ping alarm should be set to the
+  // retransmittable_on_wire_timeout.
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Simulate firing the ping alarm and sending a PING.
+  clock_.AdvanceTime(retransmittable_on_wire_timeout);
+  connection_.GetPingAlarm()->Fire();
+
+  // Now there's a retransmittable packet (PING) on the wire, so the path
+  // degrading alarm should be set.
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+}
+
+TEST_P(QuicConnectionTest, ServerRetransmittableOnWire) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  SetQuicReloadableFlag(quic_enable_server_on_wire_ping, true);
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kSRWP);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  connection_.SetFromConfig(config);
+
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  ProcessPacket(1);
+
+  ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromMilliseconds(200);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  // Verify PING alarm gets cancelled.
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+  // Now receive an ACK of the packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(2, &frame);
+  // Verify PING alarm gets scheduled.
+  ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+// This test verifies that the connection marks path as degrading and does not
+// spin timer to detect path degrading when a new packet is sent on the
+// degraded path.
+TEST_P(QuicConnectionTest, NoPathDegradingDetectionIfPathIsDegrading) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Send the first packet. Now there's a retransmittable packet on the wire, so
+  // the path degrading alarm should be set.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading detection.
+  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Send a second packet. The path degrading detection's deadline should remain
+  // the same.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
+
+  // Now receive an ACK of the first packet. This should advance the path
+  // degrading detection's deadline since forward progress has been made.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading alarm.
+  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Advance time to the path degrading detection's deadline and simulate
+  // firing the path degrading detection. This path will be considered as
+  // degrading.
+  clock_.AdvanceTime(delay);
+  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+  connection_.PathDegradingTimeout();
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  // Send a third packet. The path degrading detection is no longer set but path
+  // should still be marked as degrading.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+}
+
+// This test verifies that the connection unmarks path as degrarding and spins
+// the timer to detect future path degrading when forward progress is made
+// after path has been marked degrading.
+TEST_P(QuicConnectionTest, UnmarkPathDegradingOnForwardProgress) {
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Send the first packet. Now there's a retransmittable packet on the wire, so
+  // the path degrading alarm should be set.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading alarm.
+  QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+                              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Send a second packet. The path degrading alarm's deadline should remain
+  // the same.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
+
+  // Now receive an ACK of the first packet. This should advance the path
+  // degrading alarm's deadline since forward progress has been made.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  // Check the deadline of the path degrading alarm.
+  delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+              ->GetPathDegradingDelay();
+  EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
+                       clock_.ApproximateNow());
+
+  // Advance time to the path degrading alarm's deadline and simulate
+  // firing the alarm.
+  clock_.AdvanceTime(delay);
+  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+  connection_.PathDegradingTimeout();
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+
+  // Send a third packet. The path degrading alarm is no longer set but path
+  // should still be marked as degrading.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_TRUE(connection_.IsPathDegrading());
+
+  // Now receive an ACK of the second packet. This should unmark the path as
+  // degrading. And will set a timer to detect new path degrading.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, NoPathDegradingOnServer) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+  // Send data.
+  const char data[] = "data";
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+  // Ack data.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
+  ProcessAckPacket(&frame);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, NoPathDegradingAfterSendingAck) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(1);
+  SendAckPacketToPeer();
+  EXPECT_FALSE(connection_.sent_packet_manager().unacked_packets().empty());
+  EXPECT_FALSE(connection_.sent_packet_manager().HasInFlightPackets());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, MultipleCallsToCloseConnection) {
+  // Verifies that multiple calls to CloseConnection do not
+  // result in multiple attempts to close the connection - it will be marked as
+  // disconnected after the first call.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+  connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+  connection_.CloseConnection(QUIC_NO_ERROR, "no reason",
+                              ConnectionCloseBehavior::SILENT_CLOSE);
+}
+
+TEST_P(QuicConnectionTest, ServerReceivesChloOnNonCryptoStream) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  CryptoHandshakeMessage message;
+  CryptoFramer framer;
+  message.set_tag(kCHLO);
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  frame1_.stream_id = 10;
+  frame1_.data_buffer = data->data();
+  frame1_.data_length = data->length();
+
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  ForceProcessFramePacket(QuicFrame(frame1_));
+  if (VersionHasIetfQuicFrames(version().transport_version)) {
+    // INITIAL packet should not contain STREAM frame.
+    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+  } else {
+    TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
+  }
+}
+
+TEST_P(QuicConnectionTest, ClientReceivesRejOnNonCryptoStream) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  CryptoHandshakeMessage message;
+  CryptoFramer framer;
+  message.set_tag(kREJ);
+  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
+  frame1_.stream_id = 10;
+  frame1_.data_buffer = data->data();
+  frame1_.data_length = data->length();
+
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  ForceProcessFramePacket(QuicFrame(frame1_));
+  if (VersionHasIetfQuicFrames(version().transport_version)) {
+    // INITIAL packet should not contain STREAM frame.
+    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+  } else {
+    TestConnectionCloseQuicErrorCode(QUIC_MAYBE_CORRUPTED_MEMORY);
+  }
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnPacketTooLarge) {
+  SimulateNextPacketTooLarge();
+  // A connection close packet is sent
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, AlwaysGetPacketTooLarge) {
+  // Test even we always get packet too large, we do not infinitely try to send
+  // close packet.
+  AlwaysGetPacketTooLarge();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnQueuedWriteError) {
+  // Regression test for crbug.com/979507.
+  //
+  // If we get a write error when writing queued packets, we should attempt to
+  // send a connection close packet, but if sending that fails, it shouldn't get
+  // queued.
+
+  // Queue a packet to write.
+  BlockOnNextWrite();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  // Configure writer to always fail.
+  AlwaysGetPacketTooLarge();
+
+  // Expect that we attempt to close the connection exactly once.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+
+  // Unblock the writes and actually send.
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+// Verify that if connection has no outstanding data, it notifies the send
+// algorithm after the write.
+TEST_P(QuicConnectionTest, SendDataAndBecomeApplicationLimited) {
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
+  {
+    InSequence seq;
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(Return(false));
+  }
+
+  connection_.SendStreamData3();
+}
+
+// Verify that the connection does not become app-limited if there is
+// outstanding data to send after the write.
+TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedIfMoreDataAvailable) {
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
+  {
+    InSequence seq;
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+  }
+
+  connection_.SendStreamData3();
+}
+
+// Verify that the connection does not become app-limited after blocked write
+// even if there is outstanding data to send after the write.
+TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedDueToWriteBlock) {
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+  BlockOnNextWrite();
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamData3();
+
+  // Now unblock the writer, become congestion control blocked,
+  // and ensure we become app-limited after writing.
+  writer_->SetWritable();
+  CongestionBlockWrites();
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
+  connection_.OnCanWrite();
+}
+
+// Test the mode in which the link is filled up with probing retransmissions if
+// the connection becomes application-limited.
+TEST_P(QuicConnectionTest, SendDataWhenApplicationLimited) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
+      .WillRepeatedly(Return(true));
+  {
+    InSequence seq;
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(Return(false));
+  }
+  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
+    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
+        PROBING_RETRANSMISSION);
+  });
+  // Fix congestion window to be 20,000 bytes.
+  EXPECT_CALL(*send_algorithm_, CanSend(Ge(20000u)))
+      .WillRepeatedly(Return(false));
+  EXPECT_CALL(*send_algorithm_, CanSend(Lt(20000u)))
+      .WillRepeatedly(Return(true));
+
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
+  ASSERT_EQ(0u, connection_.GetStats().packets_sent);
+  connection_.set_fill_up_link_during_probing(true);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.SendStreamData3();
+
+  // We expect a lot of packets from a 20 kbyte window.
+  EXPECT_GT(connection_.GetStats().packets_sent, 10u);
+  // Ensure that the packets are padded.
+  QuicByteCount average_packet_size =
+      connection_.GetStats().bytes_sent / connection_.GetStats().packets_sent;
+  EXPECT_GT(average_packet_size, 1000u);
+
+  // Acknowledge all packets sent, except for the last one.
+  QuicAckFrame ack = InitAckFrame(
+      connection_.sent_packet_manager().GetLargestSentPacket() - 1);
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+
+  // Ensure that since we no longer have retransmittable bytes in flight, this
+  // will not cause any responses to be sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
+  ProcessAckPacket(&ack);
+}
+
+TEST_P(QuicConnectionTest, DoNotForceSendingAckOnPacketTooLarge) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  // Send an ack by simulating delayed ack alarm firing.
+  ProcessPacket(1);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  connection_.GetAckAlarm()->Fire();
+  // Simulate data packet causes write error.
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  SimulateNextPacketTooLarge();
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  // Ack frame is not bundled in connection close packet.
+  EXPECT_TRUE(writer_->ack_frames().empty());
+  if (writer_->padding_frames().empty()) {
+    EXPECT_EQ(1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+  }
+
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAllLevels) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    // Each connection close packet should be sent in distinct UDP packets.
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->connection_close_packets());
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->packets_write_attempts());
+    return;
+  }
+
+  // A single UDP packet should be sent with multiple connection close packets
+  // coalesced together.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Only the first packet has been processed yet.
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+
+  // ProcessPacket resets the visitor and frees the coalesced packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOneLevel) {
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, DoNotPadServerInitialConnectionClose) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  EXPECT_TRUE(writer_->padding_frames().empty());
+  EXPECT_EQ(ENCRYPTION_INITIAL, writer_->framer()->last_decrypted_level());
+}
+
+// Regression test for b/63620844.
+TEST_P(QuicConnectionTest, FailedToWriteHandshakePacket) {
+  SimulateNextPacketTooLarge();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+
+  connection_.SendCryptoStreamData();
+  TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
+}
+
+TEST_P(QuicConnectionTest, MaxPacingRate) {
+  EXPECT_EQ(0, connection_.MaxPacingRate().ToBytesPerSecond());
+  connection_.SetMaxPacingRate(QuicBandwidth::FromBytesPerSecond(100));
+  EXPECT_EQ(100, connection_.MaxPacingRate().ToBytesPerSecond());
+}
+
+TEST_P(QuicConnectionTest, ClientAlwaysSendConnectionId) {
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+  EXPECT_EQ(CONNECTION_ID_PRESENT,
+            writer_->last_packet_header().destination_connection_id_included);
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedBytesForConnectionId(&config, 0);
+  connection_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(3, "bar", 3, NO_FIN);
+  // Verify connection id is still sent in the packet.
+  EXPECT_EQ(CONNECTION_ID_PRESENT,
+            writer_->last_packet_header().destination_connection_id_included);
+}
+
+TEST_P(QuicConnectionTest, SendProbingRetransmissions) {
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  const QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "bar", 3, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "test", 6, NO_FIN, &last_packet);
+
+  const QuicByteCount old_bytes_in_flight =
+      connection_.sent_packet_manager().GetBytesInFlight();
+
+  // Allow 9 probing retransmissions to be sent.
+  {
+    InSequence seq;
+    EXPECT_CALL(*send_algorithm_, CanSend(_))
+        .Times(9 * 2)
+        .WillRepeatedly(Return(true));
+    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  }
+  // Expect them retransmitted in cyclic order (foo, bar, test, foo, bar...).
+  QuicPacketCount sent_count = 0;
+
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
+      .WillRepeatedly(Invoke(
+          [this, &sent_count](QuicPacketNumber, QuicPacketLength, bool,
+                              TransmissionType, EncryptionLevel,
+                              const QuicFrames&, const QuicFrames&, QuicTime) {
+            ASSERT_EQ(1u, writer_->stream_frames().size());
+            if (connection_.version().CanSendCoalescedPackets()) {
+              // There is a delay of sending coalesced packet, so (6, 0, 3, 6,
+              // 0...).
+              EXPECT_EQ(3 * ((sent_count + 2) % 3),
+                        writer_->stream_frames()[0]->offset);
+            } else {
+              // Identify the frames by stream offset (0, 3, 6, 0, 3...).
+              EXPECT_EQ(3 * (sent_count % 3),
+                        writer_->stream_frames()[0]->offset);
+            }
+            sent_count++;
+          }));
+
+  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
+    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
+        PROBING_RETRANSMISSION);
+  });
+
+  connection_.SendProbingRetransmissions();
+
+  // Ensure that the in-flight has increased.
+  const QuicByteCount new_bytes_in_flight =
+      connection_.sent_packet_manager().GetBytesInFlight();
+  EXPECT_GT(new_bytes_in_flight, old_bytes_in_flight);
+}
+
+// Ensure that SendProbingRetransmissions() does not retransmit anything when
+// there are no outstanding packets.
+TEST_P(QuicConnectionTest,
+       SendProbingRetransmissionsFailsWhenNothingToRetransmit) {
+  ASSERT_TRUE(connection_.sent_packet_manager().unacked_packets().empty());
+
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
+    return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
+        PROBING_RETRANSMISSION);
+  });
+
+  connection_.SendProbingRetransmissions();
+}
+
+TEST_P(QuicConnectionTest, PingAfterLastRetransmittablePacketAcked) {
+  const QuicTime::Delta retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(50);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Advance 5ms, send a retransmittable packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Advance 5ms, send a second retransmittable packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+
+  // Now receive an ACK of the first packet. This should not set the
+  // retransmittable-on-wire alarm since packet 2 is still on the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  // The ping alarm has a 1 second granularity, and the clock has been advanced
+  // 10ms since it was originally set.
+  EXPECT_EQ(ping_delay - QuicTime::Delta::FromMilliseconds(10),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive an ACK of the second packet. This should set the
+  // retransmittable-on-wire alarm now that no retransmittable packets are on
+  // the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive a duplicate ACK of the second packet. This should not update
+  // the ping alarm.
+  QuicTime prev_deadline = connection_.GetPingAlarm()->deadline();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
+
+  // Now receive a non-ACK packet.  This should not update the ping alarm.
+  prev_deadline = connection_.GetPingAlarm()->deadline();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  ProcessPacket(4);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
+
+  // Simulate the alarm firing and check that a PING is sent.
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(padding_frame_count + 2u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
+  }
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, NoPingIfRetransmittablePacketSent) {
+  const QuicTime::Delta retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(50);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+
+  // Advance 5ms, send a retransmittable packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  QuicTime::Delta ping_delay = QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+  EXPECT_EQ(ping_delay,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now receive an ACK of the first packet. This should set the
+  // retransmittable-on-wire alarm now that no retransmittable packets are on
+  // the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Before the alarm fires, send another retransmittable packet. This should
+  // cancel the retransmittable-on-wire alarm since now there's a
+  // retransmittable packet on the wire.
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+
+  // Now receive an ACK of the second packet. This should set the
+  // retransmittable-on-wire alarm now that no retransmittable packets are on
+  // the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Simulate the alarm firing and check that a PING is sent.
+  writer_->Reset();
+  connection_.GetPingAlarm()->Fire();
+  size_t padding_frame_count = writer_->padding_frames().size();
+  if (GetParam().no_stop_waiting) {
+    // Do not ACK acks.
+    EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(padding_frame_count + 3u, writer_->frame_count());
+  }
+  ASSERT_EQ(1u, writer_->ping_frames().size());
+}
+
+// When there is no stream data received but are open streams, send the
+// first few consecutive pings with aggressive retransmittable-on-wire
+// timeout. Exponentially back off the retransmittable-on-wire ping timeout
+// afterwards until it exceeds the default ping timeout.
+TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
+  int max_aggressive_retransmittable_on_wire_ping_count = 5;
+  SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
+              max_aggressive_retransmittable_on_wire_ping_count);
+  const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(200);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      initial_retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  // Advance 5ms, send a retransmittable data packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+
+  // Verify that the first few consecutive retransmittable on wire pings are
+  // sent with aggressive timeout.
+  for (int i = 0; i <= max_aggressive_retransmittable_on_wire_ping_count; i++) {
+    // Receive an ACK of the previous packet. This should set the ping alarm
+    // with the initial retransmittable-on-wire timeout.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+  }
+
+  QuicTime::Delta retransmittable_on_wire_timeout =
+      initial_retransmittable_on_wire_timeout;
+
+  // Verify subsequent pings are sent with timeout that is exponentially backed
+  // off.
+  while (retransmittable_on_wire_timeout * 2 < connection_.ping_timeout()) {
+    // Receive an ACK for the previous PING. This should set the
+    // ping alarm with backed off retransmittable-on-wire timeout.
+    retransmittable_on_wire_timeout = retransmittable_on_wire_timeout * 2;
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+  }
+
+  // The ping alarm is set with default ping timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Receive an ACK for the previous PING. The ping alarm is set with an
+  // earlier deadline.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicPacketNumber ack_num = creator_->packet_number();
+  QuicAckFrame frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout() - QuicTime::Delta::FromMilliseconds(5),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+// This test verify that the count of consecutive aggressive pings is reset
+// when new data is received. And it also verifies the connection resets
+// the exponential back-off of the retransmittable-on-wire ping timeout
+// after receiving new stream data.
+TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
+  int max_aggressive_retransmittable_on_wire_ping_count = 3;
+  SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count, 3);
+  const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(200);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      initial_retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+
+  const char data[] = "data";
+  // Advance 5ms, send a retransmittable data packet to the peer.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Receive an ACK of the first packet. This should set the ping alarm with
+  // initial retransmittable-on-wire timeout since there is no retransmittable
+  // packet on the wire.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Simulate the alarm firing and check that a PING is sent.
+  writer_->Reset();
+  clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+  connection_.GetPingAlarm()->Fire();
+
+  // Receive an ACK for the previous PING. Ping alarm will be set with
+  // aggressive timeout.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicPacketNumber ack_num = creator_->packet_number();
+  frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Process a data packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacket(peer_creator_.packet_number() + 1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
+                                         peer_creator_.packet_number() + 1);
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Verify the count of consecutive aggressive pings is reset.
+  for (int i = 0; i < max_aggressive_retransmittable_on_wire_ping_count; i++) {
+    // Receive an ACK of the previous packet. This should set the ping alarm
+    // with the initial retransmittable-on-wire timeout.
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+    // Advance 5ms to receive next packet.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  }
+
+  // Receive another ACK for the previous PING. This should set the
+  // ping alarm with backed off retransmittable-on-wire timeout.
+  ack_num = creator_->packet_number();
+  frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout * 2,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  writer_->Reset();
+  clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout);
+  connection_.GetPingAlarm()->Fire();
+
+  // Process another data packet and a new ACK packet. The ping alarm is set
+  // with aggressive ping timeout again.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  ProcessDataPacket(peer_creator_.packet_number() + 1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_,
+                                         peer_creator_.packet_number() + 1);
+  ack_num = creator_->packet_number();
+  frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+// Make sure that we never send more retransmissible on the wire pings than
+// the limit in FLAGS_quic_max_retransmittable_on_wire_ping_count.
+TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) {
+  static constexpr int kMaxRetransmittableOnWirePingCount = 3;
+  SetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count,
+              kMaxRetransmittableOnWirePingCount);
+  static constexpr QuicTime::Delta initial_retransmittable_on_wire_timeout =
+      QuicTime::Delta::FromMilliseconds(200);
+  static constexpr QuicTime::Delta short_delay =
+      QuicTime::Delta::FromMilliseconds(5);
+  ASSERT_LT(short_delay * 10, initial_retransmittable_on_wire_timeout);
+  connection_.set_initial_retransmittable_on_wire_timeout(
+      initial_retransmittable_on_wire_timeout);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+
+  const char data[] = "data";
+  // Advance 5ms, send a retransmittable data packet to the peer.
+  clock_.AdvanceTime(short_delay);
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  connection_.SendStreamDataWithString(1, data, 0, NO_FIN);
+  EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
+  // The ping alarm is set for the ping timeout, not the shorter
+  // retransmittable_on_wire_timeout.
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+      .Times(AnyNumber());
+
+  // Verify that the first few consecutive retransmittable on wire pings are
+  // sent with aggressive timeout.
+  for (int i = 0; i <= kMaxRetransmittableOnWirePingCount; i++) {
+    // Receive an ACK of the previous packet. This should set the ping alarm
+    // with the initial retransmittable-on-wire timeout.
+    clock_.AdvanceTime(short_delay);
+    QuicPacketNumber ack_num = creator_->packet_number();
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+    ProcessAckPacket(&frame);
+    EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+    EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+              connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+    // Simulate the alarm firing and check that a PING is sent.
+    writer_->Reset();
+    clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+    connection_.GetPingAlarm()->Fire();
+  }
+
+  // Receive an ACK of the previous packet. This should set the ping alarm
+  // but this time with the default ping timeout.
+  QuicPacketNumber ack_num = creator_->packet_number();
+  QuicAckFrame frame = InitAckFrame(
+      {{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
+  ProcessAckPacket(&frame);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_EQ(connection_.ping_timeout(),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+TEST_P(QuicConnectionTest, ValidStatelessResetToken) {
+  const StatelessResetToken kTestToken{0, 1, 0, 1, 0, 1, 0, 1,
+                                       0, 1, 0, 1, 0, 1, 0, 1};
+  const StatelessResetToken kWrongTestToken{0, 1, 0, 1, 0, 1, 0, 1,
+                                            0, 1, 0, 1, 0, 1, 0, 2};
+  QuicConfig config;
+  // No token has been received.
+  EXPECT_FALSE(connection_.IsValidStatelessResetToken(kTestToken));
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(2);
+  // Token is different from received token.
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
+  connection_.SetFromConfig(config);
+  EXPECT_FALSE(connection_.IsValidStatelessResetToken(kWrongTestToken));
+
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(connection_.IsValidStatelessResetToken(kTestToken));
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedWithInvalidAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  BlockOnNextWrite();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendStreamDataWithString(5, "foo", 0, FIN);
+  // This causes connection to be closed because packet 1 has not been sent yet.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessAckPacket(1, &frame);
+  EXPECT_EQ(0, connection_close_frame_count_);
+}
+
+TEST_P(QuicConnectionTest, SendMessage) {
+  if (!VersionSupportsMessageFrames(connection_.transport_version())) {
+    return;
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfig config;
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  std::string message(connection_.GetCurrentLargestMessagePayload() * 2, 'a');
+  quiche::QuicheMemSlice slice;
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendStreamData3();
+    // Send a message which cannot fit into current open packet, and 2 packets
+    // get sent, one contains stream frame, and the other only contains the
+    // message frame.
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+    slice = MemSliceFromString(absl::string_view(
+        message.data(), connection_.GetCurrentLargestMessagePayload()));
+    EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+              connection_.SendMessage(1, absl::MakeSpan(&slice, 1), false));
+  }
+  // Fail to send a message if connection is congestion control blocked.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  slice = MemSliceFromString("message");
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            connection_.SendMessage(2, absl::MakeSpan(&slice, 1), false));
+
+  // Always fail to send a message which cannot fit into one packet.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  slice = MemSliceFromString(absl::string_view(
+      message.data(), connection_.GetCurrentLargestMessagePayload() + 1));
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            connection_.SendMessage(3, absl::MakeSpan(&slice, 1), false));
+}
+
+TEST_P(QuicConnectionTest, GetCurrentLargestMessagePayload) {
+  if (!connection_.version().SupportsMessageFrames()) {
+    return;
+  }
+  // Force use of this encrypter to simplify test expectations by making sure
+  // that the encryption overhead is constant across versions.
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x00));
+  QuicPacketLength expected_largest_payload = 1219;
+  if (connection_.version().SendsVariableLengthPacketNumberInLongHeader()) {
+    expected_largest_payload += 3;
+  }
+  if (connection_.version().HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (connection_.version().HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  if (connection_.version().UsesTls()) {
+    // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
+    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
+    QuicConfig config;
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+    // Verify the value post-handshake.
+    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
+              expected_largest_payload);
+  } else {
+    EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(),
+              expected_largest_payload);
+  }
+}
+
+TEST_P(QuicConnectionTest, GetGuaranteedLargestMessagePayload) {
+  if (!connection_.version().SupportsMessageFrames()) {
+    return;
+  }
+  // Force use of this encrypter to simplify test expectations by making sure
+  // that the encryption overhead is constant across versions.
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x00));
+  QuicPacketLength expected_largest_payload = 1219;
+  if (connection_.version().HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (connection_.version().HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  if (connection_.version().UsesTls()) {
+    // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
+    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
+    QuicConfig config;
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+    // Verify the value post-handshake.
+    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
+              expected_largest_payload);
+  } else {
+    EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
+              expected_largest_payload);
+  }
+}
+
+TEST_P(QuicConnectionTest, LimitedLargestMessagePayload) {
+  if (!connection_.version().SupportsMessageFrames() ||
+      !connection_.version().UsesTls()) {
+    return;
+  }
+  constexpr QuicPacketLength kFrameSizeLimit = 1000;
+  constexpr QuicPacketLength kPayloadSizeLimit =
+      kFrameSizeLimit - kQuicFrameTypeSize;
+  // QUIC+TLS disallows DATAGRAM/MESSAGE frames before the handshake.
+  EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), 0);
+  EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(), 0);
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMaxDatagramFrameSize(&config, kFrameSizeLimit);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  // Verify the value post-handshake.
+  EXPECT_EQ(connection_.GetCurrentLargestMessagePayload(), kPayloadSizeLimit);
+  EXPECT_EQ(connection_.GetGuaranteedLargestMessagePayload(),
+            kPayloadSizeLimit);
+}
+
+// Test to check that the path challenge/path response logic works
+// correctly. This test is only for version-99
+TEST_P(QuicConnectionTest, ServerResponseToPathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  // First check if the server can send probing packet.
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  // Create and send the probe request (PATH_CHALLENGE frame).
+  // SendConnectivityProbingPacket ends up calling
+  // TestPacketWriter::WritePacket() which in turns receives and parses the
+  // packet by calling framer_.ProcessPacket() -- which in turn calls
+  // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
+  // the packet in writer_->path_challenge_frames()
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+  // Save the random contents of the challenge for later comparison to the
+  // response.
+  ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
+  QuicPathFrameBuffer challenge_data =
+      writer_->path_challenge_frames().front().data_buffer;
+
+  // Normally, QuicConnection::OnPathChallengeFrame and OnPaddingFrame would be
+  // called and it will perform actions to ensure that the rest of the protocol
+  // is performed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_TRUE(connection_.OnPathChallengeFrame(
+      writer_->path_challenge_frames().front()));
+  EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
+  creator_->FlushCurrentPacket();
+
+  // The final check is to ensure that the random data in the response matches
+  // the random data from the challenge.
+  EXPECT_EQ(1u, writer_->path_response_frames().size());
+  EXPECT_EQ(0, memcmp(&challenge_data,
+                      &(writer_->path_response_frames().front().data_buffer),
+                      sizeof(challenge_data)));
+}
+
+TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnDefaulSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  // First check if the client can send probing packet.
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  // Create and send the probe request (PATH_CHALLENGE frame).
+  // SendConnectivityProbingPacket ends up calling
+  // TestPacketWriter::WritePacket() which in turns receives and parses the
+  // packet by calling framer_.ProcessPacket() -- which in turn calls
+  // SimpleQuicFramer::OnPathChallengeFrame(). SimpleQuicFramer saves
+  // the packet in writer_->path_challenge_frames()
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.SendConnectivityProbingPacket(writer_.get(),
+                                            connection_.peer_address());
+  // Save the random contents of the challenge for later validation against the
+  // response.
+  ASSERT_GE(writer_->path_challenge_frames().size(), 1u);
+  QuicPathFrameBuffer challenge_data =
+      writer_->path_challenge_frames().front().data_buffer;
+
+  // Normally, QuicConnection::OnPathChallengeFrame would be
+  // called and it will perform actions to ensure that the rest of the protocol
+  // is performed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_TRUE(connection_.OnPathChallengeFrame(
+      writer_->path_challenge_frames().front()));
+  EXPECT_TRUE(connection_.OnPaddingFrame(writer_->padding_frames().front()));
+  creator_->FlushCurrentPacket();
+
+  // The final check is to ensure that the random data in the response matches
+  // the random data from the challenge.
+  EXPECT_EQ(1u, writer_->path_response_frames().size());
+  EXPECT_EQ(0, memcmp(&challenge_data,
+                      &(writer_->path_response_frames().front().data_buffer),
+                      sizeof(challenge_data)));
+}
+
+TEST_P(QuicConnectionTest, ClientResponseToPathChallengeOnAlternativeSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+  QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+
+  // Receiving a PATH_CHALLENGE on the alternative path. Response to this
+  // PATH_CHALLENGE should be sent via the alternative writer.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(2u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_response_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+  QuicSocketAddress kNewerSelfAddress(QuicIpAddress::Loopback6(),
+                                      /*port=*/34567);
+  // Receiving a PATH_CHALLENGE on an unknown socket should be ignored.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+  ProcessReceivedPacket(kNewerSelfAddress, kPeerAddress, *received);
+}
+
+TEST_P(QuicConnectionTest,
+       RestartPathDegradingDetectionAfterMigrationWithProbe) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Send data and verify the path degrading detection is set.
+  const char data[] = "data";
+  size_t data_size = strlen(data);
+  QuicStreamOffset offset = 0;
+  connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+  offset += data_size;
+
+  // Verify the path degrading detection is in progress.
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  QuicTime ddl = connection_.GetBlackholeDetectorAlarm()->deadline();
+
+  // Simulate the firing of path degrading.
+  clock_.AdvanceTime(ddl - clock_.ApproximateNow());
+  EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+  connection_.PathDegradingTimeout();
+  EXPECT_TRUE(connection_.IsPathDegrading());
+  EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    // Simulate path degrading handling by sending a probe on an alternet path.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+    TestPacketWriter probing_writer(version(), &clock_, Perspective::IS_CLIENT);
+    connection_.SendConnectivityProbingPacket(&probing_writer,
+                                              connection_.peer_address());
+    // Verify that path degrading detection is not reset.
+    EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+    // Simulate successful path degrading handling by receiving probe response.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+    EXPECT_CALL(visitor_,
+                OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+        .Times(1);
+    const QuicSocketAddress kNewSelfAddress =
+        QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+    std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+    std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+        QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                            probing_packet->encrypted_length),
+        clock_.Now()));
+    uint64_t num_probing_received =
+        connection_.GetStats().num_connectivity_probing_received;
+    ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+    EXPECT_EQ(num_probing_received + 1,
+              connection_.GetStats().num_connectivity_probing_received);
+    EXPECT_EQ(kPeerAddress, connection_.peer_address());
+    EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+    EXPECT_TRUE(connection_.IsPathDegrading());
+  }
+
+  // Verify new path degrading detection is activated.
+  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
+  connection_.OnSuccessfulMigration(/*is_port_change*/ true);
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
+  if (!GetParam().version.HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  EXPECT_EQ(kSelfAddress, connection_.self_address());
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
+  EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
+  EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+  const SendAlgorithmInterface* send_algorithm = manager_->GetSendAlgorithm();
+
+  // Migrate to a new address with different IP.
+  const QuicSocketAddress kNewSelfAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, false);
+  EXPECT_EQ(default_init_rtt, manager_->GetRttStats()->initial_rtt());
+  EXPECT_EQ(0u, manager_->GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_->GetConsecutiveTlpCount());
+  EXPECT_NE(send_algorithm, manager_->GetSendAlgorithm());
+}
+
+// Regression test for b/110259444
+TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  writer_->SetWriteBlocked();
+
+  ProcessPacket(1);
+  // Verify ack alarm is set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Fire the ack alarm, verify no packet is sent because the writer is blocked.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetAckAlarm()->Fire();
+
+  writer_->SetWritable();
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(2);
+  // Verify ack alarm is not set.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, DisablePacingOffloadConnectionOptions) {
+  EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
+  writer_->set_supports_release_time(true);
+  QuicConfig config;
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_TRUE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
+
+  QuicTagVector connection_options;
+  connection_options.push_back(kNPCO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  // Verify pacing offload is disabled.
+  EXPECT_FALSE(QuicConnectionPeer::SupportsReleaseTime(&connection_));
+}
+
+// Regression test for b/110259444
+// Get a path response without having issued a path challenge...
+TEST_P(QuicConnectionTest, OrphanPathResponse) {
+  QuicPathFrameBuffer data = {{0, 1, 2, 3, 4, 5, 6, 7}};
+
+  QuicPathResponseFrame frame(99, data);
+  EXPECT_TRUE(connection_.OnPathResponseFrame(frame));
+  // If PATH_RESPONSE was accepted (payload matches the payload saved
+  // in QuicConnection::transmitted_connectivity_probe_payload_) then
+  // current_packet_content_ would be set to FIRST_FRAME_IS_PING.
+  // Since this PATH_RESPONSE does not match, current_packet_content_
+  // must not be FIRST_FRAME_IS_PING.
+  EXPECT_NE(QuicConnection::FIRST_FRAME_IS_PING,
+            QuicConnectionPeer::GetCurrentPacketContent(&connection_));
+}
+
+// Regression test for b/120791670
+TEST_P(QuicConnectionTest, StopProcessingGQuicPacketInIetfQuicConnection) {
+  // This test mimics a problematic scenario where a QUIC connection using a
+  // modern version received a Q043 packet and processed it incorrectly.
+  // We can remove this test once Q043 is deprecated.
+  if (!version().HasIetfInvariantHeader()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+
+  // Let connection process a Google QUIC packet.
+  peer_framer_.set_version_for_tests(ParsedQuicVersion::Q043());
+  std::unique_ptr<QuicPacket> packet(
+      ConstructDataPacket(2, !kHasStopWaiting, ENCRYPTION_INITIAL));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  // Make sure no stream frame is processed.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+
+  EXPECT_EQ(2u, connection_.GetStats().packets_received);
+  EXPECT_EQ(1u, connection_.GetStats().packets_processed);
+}
+
+TEST_P(QuicConnectionTest, AcceptPacketNumberZero) {
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    return;
+  }
+  // Set first_sending_packet_number to be 0 to allow successfully processing
+  // acks which ack packet number 0.
+  QuicFramerPeer::SetFirstSendingPacketNumber(writer_->framer()->framer(), 0);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  ProcessPacket(0);
+  EXPECT_EQ(QuicPacketNumber(0), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+
+  ProcessPacket(2);
+  EXPECT_EQ(QuicPacketNumber(2), LargestAcked(connection_.ack_frame()));
+  EXPECT_EQ(1u, connection_.ack_frame().packets.NumIntervals());
+}
+
+TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicSending) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+
+  connection_.SendCryptoStreamData();
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(4);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
+                                         NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
+                                         NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         8, NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         12, FIN);
+  // Received ACK for packets 2, 4, 5.
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(4), QuicPacketNumber(6)}});
+  // Make sure although the same packet number is used, but they are in
+  // different packet number spaces.
+  ProcessFramePacketAtLevel(30, QuicFrame(&frame2), ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, PeerAcksPacketsInWrongPacketNumberSpace) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+
+  connection_.SendCryptoStreamData();
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  ProcessFramePacketAtLevel(30, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
+                                         NO_FIN);
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 4,
+                                         NO_FIN);
+
+  // Received ACK for packets 2 and 3 in wrong packet number space.
+  QuicAckFrame invalid_ack =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(4)}});
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ProcessFramePacketAtLevel(300, QuicFrame(&invalid_ack), ENCRYPTION_INITIAL);
+  TestConnectionCloseQuicErrorCode(QUIC_INVALID_ACK_DATA);
+}
+
+TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in application data.
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         0, NO_FIN);
+  // Verify application data ACK gets bundled with outgoing data.
+  EXPECT_EQ(2u, writer_->frame_count());
+  // Make sure ACK alarm is still set because initial data is not ACKed.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Receive packet 1001 in application data.
+  ProcessDataPacketAtLevel(1001, false, ENCRYPTION_FORWARD_SECURE);
+  clock_.AdvanceTime(DefaultRetransmissionTime());
+  // Simulates ACK alarm fires and verify two ACKs are flushed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.GetAckAlarm()->Fire();
+  EXPECT_FALSE(connection_.HasPendingAcks());
+  // Receives more packets in application data.
+  ProcessDataPacketAtLevel(1002, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  // Verify zero rtt and forward secure packets get acked in the same packet.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(1003);
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in application data.
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  writer_->SetWriteBlocked();
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AnyNumber());
+  // Simulates ACK alarm fires and verify no ACK is flushed because of write
+  // blocked.
+  clock_.AdvanceTime(DefaultDelayedAckTime());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.GetAckAlarm()->Fire();
+  // Verify ACK alarm is not set.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+
+  writer_->SetWritable();
+  // Verify 2 ACKs are sent when connection gets unblocked.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  connection_.OnCanWrite();
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+// Make sure a packet received with the right client connection ID is processed.
+TEST_P(QuicConnectionTest, ValidClientConnectionId) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  SetClientConnectionId(TestConnectionId(0x33));
+  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
+  header.destination_connection_id = TestConnectionId(0x33);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  QuicFrames frames;
+  QuicPingFrame ping_frame;
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(ping_frame));
+  frames.push_back(QuicFrame(padding_frame));
+  std::unique_ptr<QuicPacket> packet =
+      BuildUnsizedDataPacket(&peer_framer_, header, frames);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                     false);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+}
+
+// Make sure a packet received with a different client connection ID is dropped.
+TEST_P(QuicConnectionTest, InvalidClientConnectionId) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  SetClientConnectionId(TestConnectionId(0x33));
+  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_FORWARD_SECURE);
+  header.destination_connection_id = TestConnectionId(0xbad);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  QuicFrames frames;
+  QuicPingFrame ping_frame;
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(ping_frame));
+  frames.push_back(QuicFrame(padding_frame));
+  std::unique_ptr<QuicPacket> packet =
+      BuildUnsizedDataPacket(&peer_framer_, header, frames);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(1), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                     false);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+}
+
+// Make sure the first packet received with a different client connection ID on
+// the server is processed and it changes the client connection ID.
+TEST_P(QuicConnectionTest, UpdateClientConnectionIdFromFirstPacket) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
+  header.source_connection_id = TestConnectionId(0x33);
+  header.source_connection_id_included = CONNECTION_ID_PRESENT;
+  QuicFrames frames;
+  QuicPingFrame ping_frame;
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(ping_frame));
+  frames.push_back(QuicFrame(padding_frame));
+  std::unique_ptr<QuicPacket> packet =
+      BuildUnsizedDataPacket(&peer_framer_, header, frames);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
+                                  *packet, buffer, kMaxOutgoingPacketSize);
+  QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                     false);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_EQ(TestConnectionId(0x33), connection_.client_connection_id());
+}
+void QuicConnectionTest::TestReplaceConnectionIdFromInitial() {
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+  // We start with a known connection ID.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_NE(TestConnectionId(0x33), connection_.connection_id());
+  // Receiving an initial can replace the connection ID once.
+  {
+    QuicPacketHeader header = ConstructPacketHeader(1, ENCRYPTION_INITIAL);
+    header.source_connection_id = TestConnectionId(0x33);
+    header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    QuicFrames frames;
+    QuicPingFrame ping_frame;
+    QuicPaddingFrame padding_frame;
+    frames.push_back(QuicFrame(ping_frame));
+    frames.push_back(QuicFrame(padding_frame));
+    std::unique_ptr<QuicPacket> packet =
+        BuildUnsizedDataPacket(&peer_framer_, header, frames);
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(1),
+                                    *packet, buffer, kMaxOutgoingPacketSize);
+    QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                       false);
+    ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
+  EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
+  // Trying to replace the connection ID a second time drops the packet.
+  {
+    QuicPacketHeader header = ConstructPacketHeader(2, ENCRYPTION_INITIAL);
+    header.source_connection_id = TestConnectionId(0x66);
+    header.source_connection_id_included = CONNECTION_ID_PRESENT;
+    QuicFrames frames;
+    QuicPingFrame ping_frame;
+    QuicPaddingFrame padding_frame;
+    frames.push_back(QuicFrame(ping_frame));
+    frames.push_back(QuicFrame(padding_frame));
+    std::unique_ptr<QuicPacket> packet =
+        BuildUnsizedDataPacket(&peer_framer_, header, frames);
+    char buffer[kMaxOutgoingPacketSize];
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(ENCRYPTION_INITIAL, QuicPacketNumber(2),
+                                    *packet, buffer, kMaxOutgoingPacketSize);
+    QuicReceivedPacket received_packet(buffer, encrypted_length, clock_.Now(),
+                                       false);
+    ProcessReceivedPacket(kSelfAddress, kPeerAddress, received_packet);
+  }
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
+  EXPECT_EQ(TestConnectionId(0x33), connection_.connection_id());
+}
+
+TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromInitial) {
+  TestReplaceConnectionIdFromInitial();
+}
+
+TEST_P(QuicConnectionTest, ReplaceServerConnectionIdFromRetryAndInitial) {
+  // First make the connection process a RETRY and replace the server connection
+  // ID a first time.
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+  // Reset the test framer to use the right connection ID.
+  peer_framer_.SetInitialObfuscators(connection_.connection_id());
+  // Now process an INITIAL and replace the server connection ID a second time.
+  TestReplaceConnectionIdFromInitial();
+}
+
+// Regression test for b/134416344.
+TEST_P(QuicConnectionTest, CheckConnectedBeforeFlush) {
+  // This test mimics a scenario where a connection processes 2 packets and the
+  // 2nd packet contains connection close frame. When the 2nd flusher goes out
+  // of scope, a delayed ACK is pending, and ACK alarm should not be scheduled
+  // because connection is disconnected.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  const QuicErrorCode kErrorCode = QUIC_INTERNAL_ERROR;
+  std::unique_ptr<QuicConnectionCloseFrame> connection_close_frame(
+      new QuicConnectionCloseFrame(connection_.transport_version(), kErrorCode,
+                                   NO_IETF_QUIC_ERROR, "",
+                                   /*transport_close_frame_type=*/0));
+
+  // Received 2 packets.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  }
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  ProcessFramePacketWithAddresses(QuicFrame(connection_close_frame.release()),
+                                  kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  // Verify ack alarm is not set.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+// Verify that a packet containing three coalesced packets is parsed correctly.
+TEST_P(QuicConnectionTest, CoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
+    // Coalesced packets can only be encoded using long header lengths.
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(3);
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+  }
+
+  uint64_t packet_numbers[3] = {1, 2, 3};
+  EncryptionLevel encryption_levels[3] = {
+      ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
+  char buffer[kMaxOutgoingPacketSize] = {};
+  size_t total_encrypted_length = 0;
+  for (int i = 0; i < 3; i++) {
+    QuicPacketHeader header =
+        ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
+    QuicFrames frames;
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      frames.push_back(QuicFrame(&crypto_frame_));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+    }
+    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+    peer_creator_.set_encryption_level(encryption_levels[i]);
+    size_t encrypted_length = peer_framer_.EncryptPayload(
+        encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
+        buffer + total_encrypted_length,
+        sizeof(buffer) - total_encrypted_length);
+    EXPECT_GT(encrypted_length, 0u);
+    total_encrypted_length += encrypted_length;
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Regression test for crbug.com/992831.
+TEST_P(QuicConnectionTest, CoalescedPacketThatSavesFrames) {
+  if (!QuicVersionHasLongHeaderLengths(connection_.transport_version())) {
+    // Coalesced packets can only be encoded using long header lengths.
+    return;
+  }
+  if (connection_.SupportsMultiplePacketNumberSpaces()) {
+    // TODO(b/129151114) Enable this test with multiple packet number spaces.
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_TRUE(connection_.connected());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_))
+        .Times(3)
+        .WillRepeatedly([this](const QuicCryptoFrame& /*frame*/) {
+          // QuicFrame takes ownership of the QuicBlockedFrame.
+          connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+        });
+  } else {
+    EXPECT_CALL(visitor_, OnStreamFrame(_))
+        .Times(3)
+        .WillRepeatedly([this](const QuicStreamFrame& /*frame*/) {
+          // QuicFrame takes ownership of the QuicBlockedFrame.
+          connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+        });
+  }
+
+  uint64_t packet_numbers[3] = {1, 2, 3};
+  EncryptionLevel encryption_levels[3] = {
+      ENCRYPTION_INITIAL, ENCRYPTION_INITIAL, ENCRYPTION_FORWARD_SECURE};
+  char buffer[kMaxOutgoingPacketSize] = {};
+  size_t total_encrypted_length = 0;
+  for (int i = 0; i < 3; i++) {
+    QuicPacketHeader header =
+        ConstructPacketHeader(packet_numbers[i], encryption_levels[i]);
+    QuicFrames frames;
+    if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+      frames.push_back(QuicFrame(&crypto_frame_));
+    } else {
+      frames.push_back(QuicFrame(frame1_));
+    }
+    std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
+    peer_creator_.set_encryption_level(encryption_levels[i]);
+    size_t encrypted_length = peer_framer_.EncryptPayload(
+        encryption_levels[i], QuicPacketNumber(packet_numbers[i]), *packet,
+        buffer + total_encrypted_length,
+        sizeof(buffer) - total_encrypted_length);
+    EXPECT_GT(encrypted_length, 0u);
+    total_encrypted_length += encrypted_length;
+  }
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, total_encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+
+  EXPECT_TRUE(connection_.connected());
+
+  SendAckPacketToPeer();
+}
+
+// Regresstion test for b/138962304.
+TEST_P(QuicConnectionTest, RtoAndWriteBlocked) {
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Writer gets blocked.
+  writer_->SetWriteBlocked();
+
+  // Cancel the stream.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+      .WillRepeatedly(
+          Invoke(&notifier_, &SimpleSessionNotifier::WillingToWrite));
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Retransmission timer fires in RTO mode.
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify no packets get flushed when writer is blocked.
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+// Regresstion test for b/138962304.
+TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.SetMaxTailLossProbes(1);
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+  SendStreamDataToPeer(4, "foo", 0, NO_FIN, &last_data_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Writer gets blocked.
+  writer_->SetWriteBlocked();
+
+  // Cancel stream 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  // Retransmission timer fires in TLP mode.
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify one packets is forced flushed when writer is blocked.
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+}
+
+// Regresstion test for b/139375344.
+TEST_P(QuicConnectionTest, RtoForcesSendingPing) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SetMaxTailLossProbes(2);
+  EXPECT_EQ(0u, connection_.GetStats().tlp_count);
+  EXPECT_EQ(0u, connection_.GetStats().rto_count);
+
+  SendStreamDataToPeer(2, "foo", 0, NO_FIN, nullptr);
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+  // TLP fires.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().tlp_count);
+  EXPECT_EQ(0u, connection_.GetStats().rto_count);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Packet 1 gets acked.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessAckPacket(1, &frame);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
+
+  // RTO fires, verify a PING packet gets sent because there is no data to send.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().tlp_count);
+  EXPECT_EQ(1u, connection_.GetStats().rto_count);
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, ProbeTimeout) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Reset stream.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Fire the PTO and verify only the RST_STREAM is resent, not stream data.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(0u, writer_->stream_frames().size());
+  EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAfter6ClientPTOs) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k1PTO);
+  connection_options.push_back(k6PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  }
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 5 times.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  EXPECT_EQ(5u, connection_.sent_packet_manager().GetConsecutivePtoCount());
+  // Closes connection on 6th PTO.
+  // May send multiple connecction close packets with multiple PN spaces.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAfter7ClientPTOs) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2PTO);
+  connection_options.push_back(k7PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  }
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 6 times.
+  for (int i = 0; i < 6; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  EXPECT_EQ(6u, connection_.sent_packet_manager().GetConsecutivePtoCount());
+  // Closes connection on 7th PTO.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionAfter8ClientPTOs) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2PTO);
+  connection_options.push_back(k8PTO);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  }
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+
+  // Fire the retransmission alarm 7 times.
+  for (int i = 0; i < 7; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    connection_.GetRetransmissionAlarm()->Fire();
+    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+    EXPECT_TRUE(connection_.connected());
+  }
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.PathDegradingTimeout();
+
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
+  EXPECT_EQ(7u, connection_.sent_packet_manager().GetConsecutivePtoCount());
+  // Closes connection on 8th PTO.
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  connection_.GetBlackholeDetectorAlarm()->Fire();
+  EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
+}
+
+TEST_P(QuicConnectionTest, DeprecateHandshakeMode) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+
+  // Verify retransmission alarm is still set because handshake is not
+  // confirmed although there is nothing in flight.
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(0u, connection_.GetStats().pto_count);
+  EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
+
+  // PTO fires, verify a PING packet gets sent because there is no data to send.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().pto_count);
+  EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count);
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, AntiAmplificationLimit) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor =
+      GetQuicFlag(FLAGS_quic_anti_amplification_factor);
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
+TEST_P(QuicConnectionTest, 3AntiAmplificationLimit) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k3AFF);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor = 3;
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
+TEST_P(QuicConnectionTest, 10AntiAmplificationLimit) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k10AF);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor = 10;
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
+TEST_P(QuicConnectionTest, AckPendingWithAmplificationLimited) {
+  if (!connection_.version().SupportsAntiAmplificationLimit()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Receives packet 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Send response in different encryption level and cause amplification factor
+  // throttled.
+  size_t i = 0;
+  while (connection_.CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+    connection_.SendCryptoDataWithString(std::string(1024, 'a'), i * 1024,
+                                         ENCRYPTION_HANDSHAKE);
+    ++i;
+  }
+  // Verify ACK is still pending.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  // Fire ACK alarm and verify ACK cannot be sent due to amplification factor.
+  clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetAckAlarm()->Fire();
+  // Verify ACK alarm is cancelled.
+  EXPECT_FALSE(connection_.HasPendingAcks());
+
+  // Receives packet 2 and verify ACK gets flushed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  EXPECT_FALSE(writer_->ack_frames().empty());
+}
+
+TEST_P(QuicConnectionTest, ConnectionCloseFrameType) {
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    // Test relevent only for IETF QUIC.
+    return;
+  }
+  const QuicErrorCode kQuicErrorCode = IETF_QUIC_PROTOCOL_VIOLATION;
+  // Use the (unknown) frame type of 9999 to avoid triggering any logic
+  // which might be associated with the processing of a known frame type.
+  const uint64_t kTransportCloseFrameType = 9999u;
+  QuicFramerPeer::set_current_received_frame_type(
+      QuicConnectionPeer::GetFramer(&connection_), kTransportCloseFrameType);
+  // Do a transport connection close
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
+      writer_->connection_close_frames();
+  ASSERT_EQ(1u, connection_close_frames.size());
+  EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
+            connection_close_frames[0].close_type);
+  EXPECT_EQ(kQuicErrorCode, connection_close_frames[0].quic_error_code);
+  EXPECT_EQ(kTransportCloseFrameType,
+            connection_close_frames[0].transport_close_frame_type);
+}
+
+// Regression test for b/137401387 and b/138962304.
+TEST_P(QuicConnectionTest, RtoPacketAsTwo) {
+  if (connection_.PtoEnabled()) {
+    return;
+  }
+  connection_.SetMaxTailLossProbes(1);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  std::string stream_data(3000, 's');
+  // Send packets 1 - 66 and exhaust cwnd.
+  for (size_t i = 0; i < 22; ++i) {
+    // 3 packets for each stream, the first 2 are guaranteed to be full packets.
+    SendStreamDataToPeer(i + 2, stream_data, 0, FIN, nullptr);
+  }
+  CongestionBlockWrites();
+
+  // Fires TLP. Please note, this tail loss probe has 1 byte less stream data
+  // compared to packet 1 because packet number length increases.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(67), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Fires RTO. Please note, although packets 2 and 3 *should* be RTOed, but
+  // packet 2 gets RTOed to two packets because packet number length increases.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(68), _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(69), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  // Resets all streams except 2 and ack packets 1 and 2. Now, packet 3 is the
+  // only one containing retransmittable frames.
+  for (size_t i = 1; i < 22; ++i) {
+    notifier_.OnStreamReset(i + 2, QUIC_STREAM_CANCELLED);
+  }
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(3)}});
+  ProcessAckPacket(1, &frame);
+  CongestionUnblockWrites();
+
+  // Fires TLP, verify a PING gets sent because packet 3 is marked
+  // RTO_RETRANSMITTED.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(70), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+TEST_P(QuicConnectionTest, PtoSkipsPacketNumber) {
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k1PTO);
+  connection_options.push_back(kPTOS);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(stream_id, "foooooo", 0, NO_FIN, &last_packet);
+  SendStreamDataToPeer(stream_id, "foooooo", 7, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2), last_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Fire PTO and verify the PTO retransmission skips one packet number.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(QuicPacketNumber(4), writer_->last_packet_header().packet_number);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, SendCoalescedPackets) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(3);
+  EXPECT_CALL(debug_visitor, OnCoalescedPacketSent(_, _)).Times(1);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    use_tagging_decrypter();
+    connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0);
+    // Verify this packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString("bar", 3);
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TaggingEncrypter>(0x03));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
+  }
+  // Verify all 3 packets are coalesced in the same UDP datagram.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+  // Verify the packet is padded to full.
+  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
+
+  // Verify packet process.
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  EXPECT_EQ(0u, writer_->stream_frames().size());
+  // Verify there is coalesced packet.
+  EXPECT_NE(nullptr, writer_->coalesced_packet());
+}
+
+TEST_P(QuicConnectionTest, FailToCoalescePacket) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration() ||
+      !connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+
+  EXPECT_CALL(visitor_, OnHandshakePacketSent());
+
+  if (GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  }
+
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  auto test_body = [&] {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0);
+    // Verify this packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString("bar", 3);
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TaggingEncrypter>(0x03));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
+
+    creator_->Flush();
+
+    auto& coalesced_packet =
+        QuicConnectionPeer::GetCoalescedPacket(&connection_);
+    QuicPacketLength coalesced_packet_max_length =
+        coalesced_packet.max_packet_length();
+    QuicCoalescedPacketPeer::SetMaxPacketLength(coalesced_packet,
+                                                coalesced_packet.length());
+
+    // Make the coalescer's FORWARD_SECURE packet longer.
+    *QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
+        coalesced_packet, ENCRYPTION_FORWARD_SECURE) += "!!! TEST !!!";
+
+    QUIC_LOG(INFO) << "Reduced coalesced_packet_max_length from "
+                   << coalesced_packet_max_length << " to "
+                   << coalesced_packet.max_packet_length()
+                   << ", coalesced_packet.length:" << coalesced_packet.length()
+                   << ", coalesced_packet.packet_lengths:"
+                   << absl::StrJoin(coalesced_packet.packet_lengths(), ":");
+  };
+
+  EXPECT_QUIC_BUG(test_body(), "SerializeCoalescedPacket failed.");
+
+  if (GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
+    EXPECT_FALSE(connection_.connected());
+    EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+                IsError(QUIC_FAILED_TO_SERIALIZE_PACKET));
+    EXPECT_EQ(saved_connection_close_frame_.error_details,
+              "Failed to serialize coalesced packet.");
+  } else {
+    EXPECT_TRUE(connection_.connected());
+  }
+}
+
+TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
+  connection_.EnableLegacyVersionEncapsulation("test.example.org");
+
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
+
+  // Our TestPacketWriter normally parses the sent packet using the version
+  // from the connection, so here we need to tell it to use the encapsulation
+  // version, and reset the initial decrypter for that version.
+  writer_->framer()->SetSupportedVersions(
+      SupportedVersions(LegacyVersionForEncapsulation()));
+  writer_->framer()->framer()->SetInitialObfuscators(
+      connection_.connection_id());
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendCryptoDataWithString("TEST_CRYPTO_DATA", /*offset=*/0);
+  }
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  // Verify that the packet is fully padded.
+  EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
+
+  // Check that the connection stats show Legacy Version Encapsulation was used.
+  EXPECT_GT(connection_.GetStats().sent_legacy_version_encapsulated_packets,
+            0u);
+
+  // Verify that the sent packet was in fact encapsulated, and check header.
+  const QuicPacketHeader& encapsulated_header = writer_->last_packet_header();
+  EXPECT_TRUE(encapsulated_header.version_flag);
+  EXPECT_EQ(encapsulated_header.version, LegacyVersionForEncapsulation());
+  EXPECT_EQ(encapsulated_header.destination_connection_id,
+            connection_.connection_id());
+
+  // Encapsulated packet should contain a stream frame for the crypto stream,
+  // optionally padding, and nothing else.
+  EXPECT_EQ(0u, writer_->crypto_frames().size());
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(writer_->frame_count(), writer_->framer()->padding_frames().size() +
+                                        writer_->stream_frames().size());
+}
+
+TEST_P(QuicConnectionTest, ClientReceivedHandshakeDone) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, ServerReceivedHandshakeDone) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnHandshakeDoneReceived()).Times(0);
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(1, connection_close_frame_count_);
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest, MultiplePacketNumberSpacePto) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  // Send handshake packet.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
+
+  // Send application data.
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         0, NO_FIN);
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+  QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  // Retransmit handshake data.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify 1-RTT packet gets coalesced with handshake retransmission.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+
+  // Send application data.
+  connection_.SendApplicationDataAtLevel(ENCRYPTION_FORWARD_SECURE, 5, "data",
+                                         4, NO_FIN);
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  // Retransmit handshake data again.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(9), _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(8), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify 1-RTT packet gets coalesced with handshake retransmission.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+
+  // Discard handshake key.
+  connection_.OnHandshakeComplete();
+  retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
+  EXPECT_NE(QuicTime::Zero(), retransmission_time);
+
+  // Retransmit application data.
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(11), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+}
+
+void QuicConnectionTest::TestClientRetryHandling(
+    bool invalid_retry_tag, bool missing_original_id_in_config,
+    bool wrong_original_id_in_config, bool missing_retry_id_in_config,
+    bool wrong_retry_id_in_config) {
+  if (invalid_retry_tag) {
+    ASSERT_FALSE(missing_original_id_in_config);
+    ASSERT_FALSE(wrong_original_id_in_config);
+    ASSERT_FALSE(missing_retry_id_in_config);
+    ASSERT_FALSE(wrong_retry_id_in_config);
+  } else {
+    ASSERT_FALSE(missing_original_id_in_config && wrong_original_id_in_config);
+    ASSERT_FALSE(missing_retry_id_in_config && wrong_retry_id_in_config);
+  }
+  if (!version().UsesTls()) {
+    return;
+  }
+
+  // These values come from draft-ietf-quic-v2 Appendix A.4.
+  uint8_t retry_packet_rfcv2[] = {
+      0xcf, 0x70, 0x9a, 0x50, 0xc4, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1d, 0xc7, 0x11, 0x30,
+      0xcd, 0x1e, 0xd3, 0x9d, 0x6e, 0xfc, 0xee, 0x5c, 0x85, 0x80, 0x65, 0x01};
+  // These values come from RFC9001 Appendix A.4.
+  uint8_t retry_packet_rfcv1[] = {
+      0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x04, 0xa2, 0x65, 0xba,
+      0x2e, 0xff, 0x4d, 0x82, 0x90, 0x58, 0xfb, 0x3f, 0x0f, 0x24, 0x96, 0xba};
+  uint8_t retry_packet29[] = {
+      0xff, 0xff, 0x00, 0x00, 0x1d, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xd1, 0x69, 0x26, 0xd8,
+      0x1f, 0x6f, 0x9c, 0xa2, 0x95, 0x3a, 0x8a, 0xa4, 0x57, 0x5e, 0x1e, 0x49};
+
+  uint8_t* retry_packet;
+  size_t retry_packet_length;
+  if (version() == ParsedQuicVersion::V2Draft01()) {
+    retry_packet = retry_packet_rfcv2;
+    retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv2);
+  } else if (version() == ParsedQuicVersion::RFCv1()) {
+    retry_packet = retry_packet_rfcv1;
+    retry_packet_length = ABSL_ARRAYSIZE(retry_packet_rfcv1);
+  } else if (version() == ParsedQuicVersion::Draft29()) {
+    retry_packet = retry_packet29;
+    retry_packet_length = ABSL_ARRAYSIZE(retry_packet29);
+  } else {
+    // TODO(dschinazi) generate retry packets for all versions once we have
+    // server-side support for generating these programmatically.
+    return;
+  }
+
+  uint8_t original_connection_id_bytes[] = {0x83, 0x94, 0xc8, 0xf0,
+                                            0x3e, 0x51, 0x57, 0x08};
+  uint8_t new_connection_id_bytes[] = {0xf0, 0x67, 0xa5, 0x50,
+                                       0x2a, 0x42, 0x62, 0xb5};
+  uint8_t retry_token_bytes[] = {0x74, 0x6f, 0x6b, 0x65, 0x6e};
+
+  QuicConnectionId original_connection_id(
+      reinterpret_cast<char*>(original_connection_id_bytes),
+      ABSL_ARRAYSIZE(original_connection_id_bytes));
+  QuicConnectionId new_connection_id(
+      reinterpret_cast<char*>(new_connection_id_bytes),
+      ABSL_ARRAYSIZE(new_connection_id_bytes));
+
+  std::string retry_token(reinterpret_cast<char*>(retry_token_bytes),
+                          ABSL_ARRAYSIZE(retry_token_bytes));
+
+  if (invalid_retry_tag) {
+    // Flip the last bit of the retry packet to prevent the integrity tag
+    // from validating correctly.
+    retry_packet[retry_packet_length - 1] ^= 1;
+  }
+
+  QuicConnectionId config_original_connection_id = original_connection_id;
+  if (wrong_original_id_in_config) {
+    // Flip the first bit of the connection ID.
+    ASSERT_FALSE(config_original_connection_id.IsEmpty());
+    config_original_connection_id.mutable_data()[0] ^= 0x80;
+  }
+  QuicConnectionId config_retry_source_connection_id = new_connection_id;
+  if (wrong_retry_id_in_config) {
+    // Flip the first bit of the connection ID.
+    ASSERT_FALSE(config_retry_source_connection_id.IsEmpty());
+    config_retry_source_connection_id.mutable_data()[0] ^= 0x80;
+  }
+
+  // Make sure the connection uses the connection ID from the test vectors,
+  QuicConnectionPeer::SetServerConnectionId(&connection_,
+                                            original_connection_id);
+  // Make sure our fake framer has the new post-retry INITIAL keys so that any
+  // retransmission triggered by retry can be decrypted.
+  writer_->framer()->framer()->SetInitialObfuscators(new_connection_id);
+
+  // Process the RETRY packet.
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(reinterpret_cast<char*>(retry_packet),
+                         retry_packet_length, clock_.Now()));
+
+  if (invalid_retry_tag) {
+    // Make sure we refuse to process a RETRY with invalid tag.
+    EXPECT_FALSE(connection_.GetStats().retry_packet_processed);
+    EXPECT_EQ(connection_.connection_id(), original_connection_id);
+    EXPECT_TRUE(QuicPacketCreatorPeer::GetRetryToken(
+                    QuicConnectionPeer::GetPacketCreator(&connection_))
+                    .empty());
+    return;
+  }
+
+  // Make sure we correctly parsed the RETRY.
+  EXPECT_TRUE(connection_.GetStats().retry_packet_processed);
+  EXPECT_EQ(connection_.connection_id(), new_connection_id);
+  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
+                QuicConnectionPeer::GetPacketCreator(&connection_)),
+            retry_token);
+
+  // Test validating the original_connection_id from the config.
+  QuicConfig received_config;
+  QuicConfigPeer::SetNegotiated(&received_config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &received_config, connection_.connection_id());
+    if (!missing_retry_id_in_config) {
+      QuicConfigPeer::SetReceivedRetrySourceConnectionId(
+          &received_config, config_retry_source_connection_id);
+    }
+  }
+  if (!missing_original_id_in_config) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &received_config, config_original_connection_id);
+  }
+
+  if (missing_original_id_in_config || wrong_original_id_in_config ||
+      missing_retry_id_in_config || wrong_retry_id_in_config) {
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor_,
+                OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+        .Times(0);
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  connection_.SetFromConfig(received_config);
+  if (missing_original_id_in_config || wrong_original_id_in_config ||
+      missing_retry_id_in_config || wrong_retry_id_in_config) {
+    ASSERT_FALSE(connection_.connected());
+    TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+  } else {
+    EXPECT_TRUE(connection_.connected());
+  }
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetry) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryInvalidTag) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/true,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryMissingOriginalId) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/true,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryWrongOriginalId) {
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/true,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryMissingRetryId) {
+  if (!connection_.version().UsesTls()) {
+    // Versions that do not authenticate connection IDs never send the
+    // retry_source_connection_id transport parameter.
+    return;
+  }
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/true,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryWrongRetryId) {
+  if (!connection_.version().UsesTls()) {
+    // Versions that do not authenticate connection IDs never send the
+    // retry_source_connection_id transport parameter.
+    return;
+  }
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/true);
+}
+
+TEST_P(QuicConnectionTest, ClientRetransmitsInitialPacketsOnRetry) {
+  if (!connection_.version().HasIetfQuicFrames()) {
+    // TestClientRetryHandling() currently only supports IETF draft versions.
+    return;
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+
+  connection_.SendCryptoStreamData();
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+
+  // Verify that initial data is retransmitted immediately after receiving
+  // RETRY.
+  if (GetParam().ack_response == AckResponse::kImmediate) {
+    EXPECT_EQ(2u, writer_->packets_write_attempts());
+    EXPECT_EQ(1u, writer_->framer()->crypto_frames().size());
+  }
+}
+
+TEST_P(QuicConnectionTest, NoInitialPacketsRetransmissionOnInvalidRetry) {
+  if (!connection_.version().HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+
+  connection_.SendCryptoStreamData();
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  TestClientRetryHandling(/*invalid_retry_tag=*/true,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, ClientReceivesOriginalConnectionIdWithoutRetry) {
+  if (!connection_.version().UsesTls()) {
+    // QUIC+TLS is required to transmit connection ID transport parameters.
+    return;
+  }
+  if (connection_.version().UsesTls()) {
+    // Versions that authenticate connection IDs always send the
+    // original_destination_connection_id transport parameter.
+    return;
+  }
+  // Make sure that receiving the original_destination_connection_id transport
+  // parameter fails the handshake when no RETRY packet was received before it.
+  QuicConfig received_config;
+  QuicConfigPeer::SetNegotiated(&received_config, true);
+  QuicConfigPeer::SetReceivedOriginalConnectionId(&received_config,
+                                                  TestConnectionId(0x12345));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SetFromConfig(received_config);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
+TEST_P(QuicConnectionTest, ClientReceivesRetrySourceConnectionIdWithoutRetry) {
+  if (!connection_.version().UsesTls()) {
+    // Versions that do not authenticate connection IDs never send the
+    // retry_source_connection_id transport parameter.
+    return;
+  }
+  // Make sure that receiving the retry_source_connection_id transport parameter
+  // fails the handshake when no RETRY packet was received before it.
+  QuicConfig received_config;
+  QuicConfigPeer::SetNegotiated(&received_config, true);
+  QuicConfigPeer::SetReceivedRetrySourceConnectionId(&received_config,
+                                                     TestConnectionId(0x12345));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(1);
+  connection_.SetFromConfig(received_config);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
+// Regression test for http://crbug/1047977
+TEST_P(QuicConnectionTest, MaxStreamsFrameCausesConnectionClose) {
+  if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
+    return;
+  }
+  // Received frame causes connection close.
+  EXPECT_CALL(visitor_, OnMaxStreamsFrame(_))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+        connection_.CloseConnection(
+            QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
+            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return true;
+      }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, StreamsBlockedFrameCausesConnectionClose) {
+  if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
+    return;
+  }
+  // Received frame causes connection close.
+  EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+        connection_.CloseConnection(
+            QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, "error",
+            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return true;
+      }));
+  QuicFrames frames;
+  frames.push_back(
+      QuicFrame(QuicStreamsBlockedFrame(kInvalidControlFrameId, 10, false)));
+  frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest,
+       BundleAckWithConnectionCloseMultiplePacketNumberSpace) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  // Receives packet 2000 in application data.
+  ProcessDataPacketAtLevel(2000, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+  connection_.CloseConnection(
+      kQuicErrorCode, "Some random error message",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+  TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  // Verify ack is bundled.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    // Each connection close packet should be sent in distinct UDP packets.
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->connection_close_packets());
+    EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+              writer_->packets_write_attempts());
+    return;
+  }
+
+  // A single UDP packet should be sent with multiple connection close packets
+  // coalesced together.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Only the first packet has been processed yet.
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+
+  // ProcessPacket resets the visitor and frees the coalesced packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->connection_close_packets());
+  EXPECT_EQ(1u, writer_->connection_close_frames().size());
+  // Verify ack is bundled.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+// Regression test for b/151220135.
+TEST_P(QuicConnectionTest, SendPingWhenSkipPacketNumberForPto) {
+  if (!VersionSupportsMessageFrames(connection_.transport_version())) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kPTOS);
+  connection_options.push_back(k1PTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+        &config, kMaxAcceptedDatagramFrameSize);
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  connection_.OnHandshakeComplete();
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, SendMessage("message"));
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // PTO fires, verify a PING packet gets sent because there is no data to
+  // send.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+  connection_.GetRetransmissionAlarm()->Fire();
+  EXPECT_EQ(1u, connection_.GetStats().pto_count);
+  EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count);
+  EXPECT_EQ(1u, writer_->ping_frames().size());
+}
+
+// Regression test for b/155757133
+TEST_P(QuicConnectionTest, DonotChangeQueuedAcks) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  ProcessPacket(2);
+  ProcessPacket(3);
+  ProcessPacket(4);
+  // Process a packet containing stream frame followed by ACK of packets 1.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicStreamFrame(
+      QuicUtils::GetFirstBidirectionalStreamId(
+          connection_.version().transport_version, Perspective::IS_CLIENT),
+      false, 0u, absl::string_view())));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(QuicFrame(&ack_frame));
+  // Receiving stream frame causes something to send.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
+    connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+    // Verify now the queued ACK contains packet number 2.
+    EXPECT_TRUE(QuicPacketCreatorPeer::QueuedFrames(
+                    QuicConnectionPeer::GetPacketCreator(&connection_))[0]
+                    .ack_frame->packets.Contains(QuicPacketNumber(2)));
+  }));
+  ProcessFramesPacketAtLevel(9, frames, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(writer_->ack_frames()[0].packets.Contains(QuicPacketNumber(2)));
+}
+
+TEST_P(QuicConnectionTest, DonotExtendIdleTimeOnUndecryptablePackets) {
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  // Subtract a second from the idle timeout on the client side.
+  QuicTime initial_deadline =
+      clock_.ApproximateNow() +
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
+  EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
+
+  // Received an undecryptable packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  const uint8_t tag = 0x07;
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(tag));
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  // Verify deadline does not get extended.
+  EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
+  QuicTime::Delta delay = initial_deadline - clock_.ApproximateNow();
+  clock_.AdvanceTime(delay);
+  connection_.GetTimeoutAlarm()->Fire();
+  // Verify connection gets closed.
+  EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, BundleAckWithImmediateResponse) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
+    notifier_.WriteOrBufferWindowUpate(0, 0);
+  }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ProcessDataPacket(1);
+  // Verify ACK is bundled with WINDOW_UPDATE.
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, AckAlarmFiresEarly) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in application data.
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Verify ACK deadline does not change.
+  EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
+            connection_.GetAckAlarm()->deadline());
+
+  // Ack alarm fires early.
+  // Verify the earliest ACK is flushed.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  connection_.GetAckAlarm()->Fire();
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
+            connection_.GetAckAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionClient) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kCBHD);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole detection is in progress.
+  EXPECT_TRUE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionServer) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(kCBHD);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole detection is disabled.
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, 2RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k2RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(2),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 3RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k3RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(3),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 4RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k4RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(4),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 6RtoBlackholeDetection) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k6RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify blackhole delay is expected.
+  EXPECT_EQ(clock_.Now() +
+                connection_.sent_packet_manager().GetNetworkBlackholeDelay(6),
+            QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+// Regresstion test for b/158491591.
+TEST_P(QuicConnectionTest, MadeForwardProgressOnDiscardingKeys) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  // Send handshake packet.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k5RTO);
+  config.SetConnectionOptionsToSend(connection_options);
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  // Discard handshake keys.
+  connection_.OnHandshakeComplete();
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    // Verify blackhole detection stops.
+    EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+  } else {
+    // Problematic: although there is nothing in flight, blackhole detection is
+    // still in progress.
+    EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  }
+}
+
+TEST_P(QuicConnectionTest, ProcessUndecryptablePacketsBasedOnEncryptionLevel) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  use_tagging_decrypter();
+
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  for (uint64_t i = 1; i <= 3; ++i) {
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  }
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  for (uint64_t j = 5; j <= 7; ++j) {
+    ProcessDataPacketAtLevel(j, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  }
+  EXPECT_EQ(7u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  // Verify all ENCRYPTION_HANDSHAKE packets get processed.
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(6);
+  }
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  // Verify the 1-RTT packet gets processed.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+}
+
+TEST_P(QuicConnectionTest, ServerBundlesInitialDataWithInitialAck) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+  QuicTime expected_pto_time =
+      connection_.sent_packet_manager().GetRetransmissionTime();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  // Verify PTO time does not change.
+  EXPECT_EQ(expected_pto_time,
+            connection_.sent_packet_manager().GetRetransmissionTime());
+
+  // Receives packet 1001 in initial data.
+  ProcessCryptoPacketAtLevel(1001, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Receives packet 1002 in initial data.
+  ProcessCryptoPacketAtLevel(1002, ENCRYPTION_INITIAL);
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  // Verify CRYPTO frame is bundled with INITIAL ACK.
+  EXPECT_FALSE(writer_->crypto_frames().empty());
+  // Verify PTO time changes.
+  EXPECT_NE(expected_pto_time,
+            connection_.sent_packet_manager().GetRetransmissionTime());
+}
+
+TEST_P(QuicConnectionTest, ClientBundlesHandshakeDataWithHandshakeAck) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  // Receives packet 1000 in handshake data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+  // Receives packet 1001 in handshake data.
+  ProcessCryptoPacketAtLevel(1001, ENCRYPTION_HANDSHAKE);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  // Receives packet 1002 in handshake data.
+  ProcessCryptoPacketAtLevel(1002, ENCRYPTION_HANDSHAKE);
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  // Verify CRYPTO frame is bundled with HANDSHAKE ACK.
+  EXPECT_FALSE(writer_->crypto_frames().empty());
+}
+
+// Regresstion test for b/156232673.
+TEST_P(QuicConnectionTest, CoalescePacketOfLowerEncryptionLevel) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    use_tagging_decrypter();
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    SendStreamDataToPeer(2, std::string(1286, 'a'), 0, NO_FIN, nullptr);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    // Try to coalesce a HANDSHAKE packet after 1-RTT packet.
+    // Verify soft max packet length gets resumed and handshake packet gets
+    // successfully sent.
+    connection_.SendCryptoDataWithString("a", 0, ENCRYPTION_HANDSHAKE);
+  }
+}
+
+// Regression test for b/160790422.
+TEST_P(QuicConnectionTest, ServerRetransmitsHandshakeDataEarly) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+  QuicTime expected_pto_time =
+      connection_.sent_packet_manager().GetRetransmissionTime();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  // Send HANDSHAKE 2 and 3.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+  connection_.SendCryptoDataWithString("bar", 3, ENCRYPTION_HANDSHAKE);
+  // Verify PTO time does not change.
+  EXPECT_EQ(expected_pto_time,
+            connection_.sent_packet_manager().GetRetransmissionTime());
+
+  // Receives ACK for HANDSHAKE 2.
+  QuicFrames frames;
+  auto ack_frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  frames.push_back(QuicFrame(&ack_frame));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramesPacketAtLevel(30, frames, ENCRYPTION_HANDSHAKE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Receives PING from peer.
+  frames.clear();
+  frames.push_back(QuicFrame(QuicPingFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(3)));
+  ProcessFramesPacketAtLevel(31, frames, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(clock_.Now() + kAlarmGranularity,
+            connection_.GetAckAlarm()->deadline());
+  // Fire ACK alarm.
+  clock_.AdvanceTime(kAlarmGranularity);
+  connection_.GetAckAlarm()->Fire();
+  EXPECT_FALSE(writer_->ack_frames().empty());
+  // Verify handshake data gets retransmitted early.
+  EXPECT_FALSE(writer_->crypto_frames().empty());
+}
+
+// Regression test for b/161228202
+TEST_P(QuicConnectionTest, InflatedRttSample) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // 30ms RTT.
+  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
+  set_perspective(Perspective::IS_SERVER);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  std::string initial_crypto_data(512, 'a');
+  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
+                                       ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.sent_packet_manager()
+                  .GetRetransmissionTime()
+                  .IsInitialized());
+  QuicTime::Delta pto_timeout =
+      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
+  // Send Handshake 2.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  std::string handshake_crypto_data(1024, 'a');
+  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
+                                       ENCRYPTION_HANDSHAKE);
+
+  // INITIAL 1 gets lost and PTO fires.
+  clock_.AdvanceTime(pto_timeout);
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  clock_.AdvanceTime(kTestRTT);
+  // Assume retransmitted INITIAL gets received.
+  QuicFrames frames;
+  auto ack_frame = InitAckFrame({{QuicPacketNumber(4), QuicPacketNumber(5)}});
+  frames.push_back(QuicFrame(&ack_frame));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  ProcessFramesPacketAtLevel(1001, frames, ENCRYPTION_INITIAL);
+  EXPECT_EQ(kTestRTT, rtt_stats->latest_rtt());
+  // Because retransmitted INITIAL gets received so HANDSHAKE 2 gets processed.
+  frames.clear();
+  // HANDSHAKE 5 is also processed.
+  QuicAckFrame ack_frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(5), QuicPacketNumber(6)}});
+  ack_frame2.ack_delay_time = QuicTime::Delta::Zero();
+  frames.push_back(QuicFrame(&ack_frame2));
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_HANDSHAKE);
+  // Verify RTT inflation gets mitigated.
+  EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
+}
+
+// Regression test for b/161228202
+TEST_P(QuicConnectionTest, CoalscingPacketCausesInfiniteLoop) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+
+  // Set anti amplification factor to 2, such that RetransmitDataOfSpaceIfAny
+  // makes no forward progress and causes infinite loop.
+  SetQuicFlag(FLAGS_quic_anti_amplification_factor, 2);
+
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  std::string initial_crypto_data(512, 'a');
+  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
+                                       ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.sent_packet_manager()
+                  .GetRetransmissionTime()
+                  .IsInitialized());
+  QuicTime::Delta pto_timeout =
+      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
+  // Send Handshake 2.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  // Verify HANDSHAKE packet is coalesced with INITIAL retransmission.
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  std::string handshake_crypto_data(1024, 'a');
+  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
+                                       ENCRYPTION_HANDSHAKE);
+
+  // INITIAL 1 gets lost and PTO fires.
+  clock_.AdvanceTime(pto_timeout);
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
+TEST_P(QuicConnectionTest, ClientAckDelayForAsyncPacketProcessing) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  // SetFromConfig is always called after construction from InitializeSession.
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  // Received undecryptable HANDSHAKE 2.
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  // Received INITIAL 4 (which is retransmission of INITIAL 1) after 100ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_INITIAL);
+  // Generate HANDSHAKE key.
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  // Verify HANDSHAKE packet gets processed.
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  } else {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  }
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify immediate ACK has been sent out when flush went out of scope.
+    ASSERT_FALSE(connection_.HasPendingAcks());
+  } else {
+    ASSERT_TRUE(connection_.HasPendingAcks());
+    // Send ACKs.
+    clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
+    connection_.GetAckAlarm()->Fire();
+  }
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify the ack_delay_time in the sent HANDSHAKE ACK frame is 100ms.
+    EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
+              writer_->ack_frames()[0].ack_delay_time);
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+    return;
+  }
+  // Verify the ack_delay_time in the INITIAL ACK frame is 1ms.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
+            writer_->ack_frames()[0].ack_delay_time);
+  // Process the coalesced HANDSHAKE packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  // Verify the ack_delay_time in the HANDSHAKE ACK frame includes the
+  // buffering time.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(101),
+            writer_->ack_frames()[0].ack_delay_time);
+  ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, TestingLiveness) {
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+
+  CryptoHandshakeMessage msg;
+  std::string error_details;
+  QuicConfig client_config;
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  client_config.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(30));
+  client_config.ToHandshakeMessage(&msg, connection_.transport_version());
+  const QuicErrorCode error =
+      config.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_THAT(error, IsQuicNoError());
+
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+
+  connection_.SetFromConfig(config);
+  connection_.OnHandshakeComplete();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.MaybeTestLiveness());
+
+  QuicTime deadline = connection_.GetTimeoutAlarm()->deadline();
+  QuicTime::Delta timeout = deadline - clock_.ApproximateNow();
+  // Advance time to near the idle timeout.
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_TRUE(connection_.MaybeTestLiveness());
+  // Verify idle deadline does not change.
+  EXPECT_EQ(deadline, connection_.GetTimeoutAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, SilentIdleTimeout) {
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  QuicConfig config;
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+
+  if (version().handshake_protocol == PROTOCOL_TLS1_3) {
+    EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  }
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetTimeoutAlarm()->Fire();
+  // Verify the connection close packets get serialized and added to
+  // termination packets list.
+  EXPECT_NE(nullptr,
+            QuicConnectionPeer::GetConnectionClosePacket(&connection_));
+}
+
+TEST_P(QuicConnectionTest, DonotSendPing) {
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.OnHandshakeComplete();
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(true));
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()),
+      "GET /", 0, FIN, nullptr);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(15),
+            connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  // Now recevie an ACK and response of the previous packet, which will move the
+  // ping alarm forward.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  QuicFrames frames;
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(QuicFrame(&ack_frame));
+  frames.push_back(QuicFrame(QuicStreamFrame(
+      GetNthClientInitiatedStreamId(0, connection_.transport_version()), true,
+      0u, absl::string_view())));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  // The ping timer is set slightly less than 15 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(
+      QuicTime::Delta::FromSeconds(15) - QuicTime::Delta::FromMilliseconds(5),
+      connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  // Suppose now ShouldKeepConnectionAlive returns false.
+  EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+      .WillRepeatedly(Return(false));
+  // Verify PING does not get sent.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.GetPingAlarm()->Fire();
+}
+
+// Regression test for b/159698337
+TEST_P(QuicConnectionTest, DuplicateAckCausesLostPackets) {
+  if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  // Finish handshake.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  std::string data(1200, 'a');
+  // Send data packets 1 - 5.
+  for (size_t i = 0; i < 5; ++i) {
+    SendStreamDataToPeer(
+        GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
+        i * 1200, i == 4 ? FIN : NO_FIN, nullptr);
+  }
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(3);
+
+  // ACK packet 5 and 1 and 2 are detected lost.
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(5), QuicPacketNumber(6)}});
+  LostPacketVector lost_packets;
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(2), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .Times(AnyNumber())
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  ProcessAckPacket(1, &frame);
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
+  EXPECT_TRUE(retransmission_alarm->IsSet());
+
+  // ACK packet 1 - 5 and 7.
+  QuicAckFrame frame2 =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(6)},
+                    {QuicPacketNumber(7), QuicPacketNumber(8)}});
+  ProcessAckPacket(2, &frame2);
+  EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+
+  // ACK packet 7 again and assume packet 6 is detected lost.
+  QuicAckFrame frame3 =
+      InitAckFrame({{QuicPacketNumber(7), QuicPacketNumber(8)}});
+  lost_packets.clear();
+  lost_packets.push_back(
+      LostPacket(QuicPacketNumber(6), kMaxOutgoingPacketSize));
+  EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
+      .Times(AnyNumber())
+      .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
+                      Return(LossDetectionInterface::DetectionStats())));
+  ProcessAckPacket(3, &frame3);
+  // Make sure loss detection is cancelled even there is no new acked packets.
+  EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+}
+
+TEST_P(QuicConnectionTest, ShorterIdleTimeoutOnSentPackets) {
+  EXPECT_TRUE(connection_.connected());
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.SetClientConnectionOptions(QuicTagVector{kFIDT});
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    EXPECT_CALL(visitor_, GetHandshakeState())
+        .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+  }
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  connection_.SetFromConfig(config);
+
+  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  // Send a packet close to timeout.
+  QuicTime::Delta timeout =
+      connection_.GetTimeoutAlarm()->deadline() - clock_.Now();
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromSeconds(1));
+  // Send stream data.
+  SendStreamDataToPeer(
+      GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+      0, FIN, nullptr);
+  // Verify this sent packet does not extend idle timeout since 1s is > PTO
+  // delay.
+  ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            connection_.GetTimeoutAlarm()->deadline() - clock_.Now());
+
+  // Received an ACK 100ms later.
+  clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(100));
+  QuicAckFrame ack = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  ProcessAckPacket(1, &ack);
+  // Verify idle timeout gets extended.
+  EXPECT_EQ(clock_.Now() + timeout, connection_.GetTimeoutAlarm()->deadline());
+}
+
+// Regression test for b/166255274
+TEST_P(QuicConnectionTest,
+       ReserializeInitialPacketInCoalescerAfterDiscardingInitialKey) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+    // Verify the packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+    // Flush pending ACKs.
+    connection_.GetAckAlarm()->Fire();
+  }
+  EXPECT_FALSE(connection_.packet_creator().HasPendingFrames());
+  // The ACK frame is deleted along with initial_packet_ in coalescer. Sending
+  // connection close would cause this (released) ACK frame be serialized (and
+  // crashes).
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, PathValidationOnNewSocketSuccess) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(new QuicPathResponseFrame(
+      99, new_writer.path_challenge_frames().front().data_buffer)));
+  ProcessFramesPacketWithAddresses(frames, kNewSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(success);
+}
+
+TEST_P(QuicConnectionTest, NewPathValidationCancelsPreviousOne) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = true;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  // Start another path validation request.
+  const QuicSocketAddress kNewSelfAddress2(QuicIpAddress::Any4(), 12346);
+  EXPECT_NE(kNewSelfAddress2, connection_.self_address());
+  TestPacketWriter new_writer2(version(), &clock_, Perspective::IS_CLIENT);
+  if (!connection_.connection_migration_use_new_cid()) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .Times(AtLeast(1u))
+        .WillOnce(Invoke([&]() {
+          EXPECT_EQ(1u, new_writer2.packets_write_attempts());
+          EXPECT_EQ(1u, new_writer2.path_challenge_frames().size());
+          EXPECT_EQ(1u, new_writer2.padding_frames().size());
+          EXPECT_EQ(kNewSelfAddress2.host(),
+                    new_writer2.last_write_source_address());
+        }));
+  }
+  bool success2 = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress2, connection_.peer_address(), &new_writer2),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress2, connection_.peer_address(),
+          &success2));
+  EXPECT_FALSE(success);
+  if (connection_.connection_migration_use_new_cid()) {
+    // There is no pening path validation as there is no available connection
+    // ID.
+    EXPECT_FALSE(connection_.HasPendingPathValidation());
+  } else {
+    EXPECT_TRUE(connection_.HasPendingPathValidation());
+  }
+}
+
+// Regression test for b/182571515.
+TEST_P(QuicConnectionTest, PathValidationRetry) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(2u)
+      .WillRepeatedly(Invoke([&]() {
+        EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+      }));
+  bool success = true;
+  connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
+                               connection_.self_address(),
+                               connection_.peer_address(), writer_.get()),
+                           std::make_unique<TestValidationResultDelegate>(
+                               &connection_, connection_.self_address(),
+                               connection_.peer_address(), &success));
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+
+  // Retry after time out.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  static_cast<TestAlarmFactory::TestAlarm*>(
+      QuicPathValidatorPeer::retry_timer(
+          QuicConnectionPeer::path_validator(&connection_)))
+      ->Fire();
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+}
+
+TEST_P(QuicConnectionTest, PathValidationReceivesStatelessReset) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedStatelessResetToken(&config,
+                                                 kTestStatelessResetToken);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = true;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildIetfStatelessResetPacket(connection_id_,
+                                                /*received_packet_length=*/100,
+                                                kTestStatelessResetToken));
+  std::unique_ptr<QuicReceivedPacket> received(
+      ConstructReceivedPacket(*packet, QuicTime::Zero()));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
+  connection_.ProcessUdpPacket(kNewSelfAddress, kPeerAddress, *received);
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+  EXPECT_FALSE(success);
+}
+
+// Tests that PATH_CHALLENGE is dropped if it is sent via a blocked alternative
+// writer.
+TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedNewSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  new_writer.BlockOnNextWrite();
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1))
+      .WillOnce(Invoke([&]() {
+        // Even though the socket is blocked, the PATH_CHALLENGE should still be
+        // treated as sent.
+        EXPECT_EQ(1u, new_writer.packets_write_attempts());
+        EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+        EXPECT_EQ(1u, new_writer.padding_frames().size());
+        EXPECT_EQ(kNewSelfAddress.host(),
+                  new_writer.last_write_source_address());
+      }));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+  new_writer.SetWritable();
+  // Write event on the default socket shouldn't make any difference.
+  connection_.OnCanWrite();
+  // A NEW_CONNECTION_ID frame is received in PathProbeTestInit and OnCanWrite
+  // will write a acking packet.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_EQ(1u, new_writer.packets_write_attempts());
+}
+
+//  Tests that PATH_CHALLENGE is dropped if it is sent via the default writer
+//  and the writer is blocked.
+TEST_P(QuicConnectionTest, SendPathChallengeUsingBlockedDefaultSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
+  writer_->BlockOnNextWrite();
+  // 1st time is after writer returns WRITE_STATUS_BLOCKED. 2nd time is in
+  // ShouldGeneratePacket().
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(2));
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([&]() {
+        // This packet isn't sent actually, instead it is buffered in the
+        // connection.
+        EXPECT_EQ(1u, writer_->packets_write_attempts());
+        if (connection_.validate_client_address()) {
+          EXPECT_EQ(1u, writer_->path_response_frames().size());
+          EXPECT_EQ(0,
+                    memcmp(&path_challenge_payload,
+                           &writer_->path_response_frames().front().data_buffer,
+                           sizeof(path_challenge_payload)));
+        }
+        EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillRepeatedly(Invoke([&]() {
+        // Only one PATH_CHALLENGE should be sent out.
+        EXPECT_EQ(0u, writer_->path_challenge_frames().size());
+      }));
+  bool success = false;
+  if (connection_.validate_client_address()) {
+    // Receiving a PATH_CHALLENGE from the new peer address should trigger
+    // address validation.
+    QuicFrames frames;
+    frames.push_back(
+        QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+    ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                     ENCRYPTION_FORWARD_SECURE);
+  } else {
+    // Manually start to validate the new peer address.
+    connection_.ValidatePath(
+        std::make_unique<TestQuicPathValidationContext>(
+            connection_.self_address(), kNewPeerAddress, writer_.get()),
+        std::make_unique<TestValidationResultDelegate>(
+            &connection_, connection_.self_address(), kNewPeerAddress,
+            &success));
+  }
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  // Try again with the new socket blocked from the beginning. The 2nd
+  // PATH_CHALLENGE shouldn't be serialized, but be dropped.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  static_cast<TestAlarmFactory::TestAlarm*>(
+      QuicPathValidatorPeer::retry_timer(
+          QuicConnectionPeer::path_validator(&connection_)))
+      ->Fire();
+
+  // No more write attempt should be made.
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+  writer_->SetWritable();
+  // OnCanWrite() should actually write out the 1st PATH_CHALLENGE packet
+  // buffered earlier, thus incrementing the write counter. It may also send
+  // ACKs to previously received packets.
+  connection_.OnCanWrite();
+  EXPECT_LE(2u, writer_->packets_write_attempts());
+}
+
+// Tests that write error on the alternate socket should be ignored.
+TEST_P(QuicConnectionTest, SendPathChallengeFailOnNewSocket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  new_writer.SetShouldWriteFail();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_EQ(1u, new_writer.packets_write_attempts());
+  EXPECT_EQ(1u, new_writer.path_challenge_frames().size());
+  EXPECT_EQ(1u, new_writer.padding_frames().size());
+  EXPECT_EQ(kNewSelfAddress.host(), new_writer.last_write_source_address());
+
+  EXPECT_EQ(0u, writer_->packets_write_attempts());
+  //  Regardless of the write error, the connection should still be connected.
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Tests that write error while sending PATH_CHALLANGE from the default socket
+// should close the connection.
+TEST_P(QuicConnectionTest, SendPathChallengeFailOnDefaultPath) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  writer_->SetShouldWriteFail();
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(
+          Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
+            EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
+          }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+  {
+    // Add a flusher to force flush, otherwise the frames will remain in the
+    // packet creator.
+    bool success = false;
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    connection_.ValidatePath(std::make_unique<TestQuicPathValidationContext>(
+                                 connection_.self_address(),
+                                 connection_.peer_address(), writer_.get()),
+                             std::make_unique<TestValidationResultDelegate>(
+                                 &connection_, connection_.self_address(),
+                                 connection_.peer_address(), &success));
+  }
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(connection_.peer_address(), writer_->last_write_peer_address());
+  EXPECT_FALSE(connection_.connected());
+  // Closing connection should abandon ongoing path validation.
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+}
+
+TEST_P(QuicConnectionTest, SendPathChallengeFailOnAlternativePeerAddress) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  writer_->SetShouldWriteFail();
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(
+          Invoke([](QuicConnectionCloseFrame frame, ConnectionCloseSource) {
+            EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, frame.quic_error_code);
+          }));
+  // Sending PATH_CHALLENGE to trigger a flush write which will fail and close
+  // the connection.
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          connection_.self_address(), kNewPeerAddress, writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, connection_.self_address(), kNewPeerAddress, &success));
+
+  EXPECT_EQ(1u, writer_->packets_write_attempts());
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest,
+       SendPathChallengeFailPacketTooBigOnAlternativePeerAddress) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  // Make sure there is no outstanding ACK_FRAME to write.
+  connection_.OnCanWrite();
+  uint32_t num_packets_write_attempts = writer_->packets_write_attempts();
+
+  writer_->SetShouldWriteFail();
+  writer_->SetWriteError(*writer_->MessageTooBigErrorCode());
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .Times(0u);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0u);
+  // Sending PATH_CHALLENGE to trigger a flush write which will fail with
+  // MSG_TOO_BIG.
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          connection_.self_address(), kNewPeerAddress, writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, connection_.self_address(), kNewPeerAddress, &success));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  // Connection shouldn't be closed.
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_EQ(++num_packets_write_attempts, writer_->packets_write_attempts());
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+}
+
+// Check that if there are two PATH_CHALLENGE frames in the packet, the latter
+// one is ignored.
+TEST_P(QuicConnectionTest, ReceiveMultiplePathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicPathFrameBuffer path_frame_buffer1{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicPathFrameBuffer path_frame_buffer2{8, 9, 10, 11, 12, 13, 14, 15};
+  QuicFrames frames;
+  frames.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer1)));
+  frames.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer2)));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+
+  // Expect 2 packets to be sent: the first are padded PATH_RESPONSE(s) to the
+  // alternative peer address. The 2nd is a ACK-only packet to the original
+  // peer address.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(2)
+      .WillOnce(Invoke([=]() {
+        EXPECT_EQ(1u, writer_->path_response_frames().size());
+        // The final check is to ensure that the random data in the response
+        // matches the random data from the challenge.
+        EXPECT_EQ(0,
+                  memcmp(path_frame_buffer1.data(),
+                         &(writer_->path_response_frames().front().data_buffer),
+                         sizeof(path_frame_buffer1)));
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillOnce(Invoke([=]() {
+        // The last write of ACK-only packet should still use the old peer
+        // address.
+        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+      }));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+}
+
+TEST_P(QuicConnectionTest, ReceiveStreamFrameBeforePathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
+      .Times(connection_.validate_client_address() ? 0u : 1u);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
+        // Send some data on the stream. The STREAM_FRAME should be built into
+        // one packet together with the latter PATH_RESPONSE and PATH_CHALLENGE.
+        const std::string data{"response body"};
+        connection_.producer()->SaveStreamData(frame.stream_id, data);
+        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
+                                           NO_FIN);
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(connection_.validate_client_address() ? 0u : 1u);
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+
+  // Verify that this packet contains a STREAM_FRAME and a
+  // PATH_RESPONSE_FRAME.
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+  EXPECT_EQ(1u, writer_->path_response_frames().size());
+  EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
+            writer_->path_challenge_frames().size());
+  // The final check is to ensure that the random data in the response
+  // matches the random data from the challenge.
+  EXPECT_EQ(0, memcmp(path_frame_buffer.data(),
+                      &(writer_->path_response_frames().front().data_buffer),
+                      sizeof(path_frame_buffer)));
+  EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
+            writer_->path_challenge_frames().size());
+  EXPECT_EQ(1u, writer_->padding_frames().size());
+  EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+  if (connection_.validate_client_address()) {
+    EXPECT_TRUE(connection_.HasPendingPathValidation());
+  }
+}
+
+TEST_P(QuicConnectionTest, ReceiveStreamFrameFollowingPathChallenge) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  // PATH_RESPONSE should be flushed out before the rest packet is parsed.
+  frames.push_back(QuicFrame(frame1_));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+  QuicByteCount received_packet_size;
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(AtLeast(1u))
+      .WillOnce(Invoke([=, &received_packet_size]() {
+        // Verify that this packet contains a PATH_RESPONSE_FRAME.
+        EXPECT_EQ(0u, writer_->stream_frames().size());
+        EXPECT_EQ(1u, writer_->path_response_frames().size());
+        // The final check is to ensure that the random data in the response
+        // matches the random data from the challenge.
+        EXPECT_EQ(0,
+                  memcmp(path_frame_buffer.data(),
+                         &(writer_->path_response_frames().front().data_buffer),
+                         sizeof(path_frame_buffer)));
+        EXPECT_EQ(connection_.validate_client_address() ? 1u : 0u,
+                  writer_->path_challenge_frames().size());
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+        received_packet_size =
+            QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_);
+      }));
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE));
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration())
+      .Times(connection_.validate_client_address() ? 0u : 1u);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(Invoke([=](const QuicStreamFrame& frame) {
+        // Send some data on the stream. The STREAM_FRAME should be built into a
+        // new packet but throttled by anti-amplifciation limit.
+        const std::string data{"response body"};
+        connection_.producer()->SaveStreamData(frame.stream_id, data);
+        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
+                                           NO_FIN);
+      }));
+
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_EQ(0u,
+            QuicConnectionPeer::BytesReceivedOnAlternativePath(&connection_));
+  EXPECT_EQ(
+      received_packet_size,
+      QuicConnectionPeer::BytesReceivedBeforeAddressValidation(&connection_));
+}
+
+// Tests that a PATH_CHALLENGE is received in between other frames in an out of
+// order packet.
+TEST_P(QuicConnectionTest, PathChallengeWithDataInOutOfOrderPacket) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  frames.push_back(QuicFrame(frame2_));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke([=](const QuicStreamFrame& frame) {
+        // Send some data on the stream. The STREAM_FRAME should be built into
+        // one packet together with the latter PATH_RESPONSE.
+        const std::string data{"response body"};
+        connection_.producer()->SaveStreamData(frame.stream_id, data);
+        return notifier_.WriteOrBufferData(frame.stream_id, data.length(),
+                                           NO_FIN);
+      }));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(Invoke([=]() {
+        // Verify that this packet contains a STREAM_FRAME and is sent to the
+        // original peer address.
+        EXPECT_EQ(1u, writer_->stream_frames().size());
+        // No connection migration should happen because the packet is received
+        // out of order.
+        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillOnce(Invoke([=]() {
+        EXPECT_EQ(1u, writer_->path_response_frames().size());
+        // The final check is to ensure that the random data in the response
+        // matches the random data from the challenge.
+        EXPECT_EQ(0,
+                  memcmp(path_frame_buffer.data(),
+                         &(writer_->path_response_frames().front().data_buffer),
+                         sizeof(path_frame_buffer)));
+        EXPECT_EQ(1u, writer_->padding_frames().size());
+        // PATH_RESPONSE should be sent in another packet to a different peer
+        // address.
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+      }))
+      .WillOnce(Invoke([=]() {
+        // Verify that this packet contains a STREAM_FRAME and is sent to the
+        // original peer address.
+        EXPECT_EQ(1u, writer_->stream_frames().size());
+        // No connection migration should happen because the packet is received
+        // out of order.
+        EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+      }));
+  // Lower the packet number so that receiving this packet shouldn't trigger
+  // peer migration.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+}
+
+// Tests that a PATH_CHALLENGE is cached if its PATH_RESPONSE can't be sent.
+TEST_P(QuicConnectionTest, FailToWritePathResponse) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+
+  QuicFrames frames;
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
+                                          /*port=*/23456);
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
+  // Lower the packet number so that receiving this packet shouldn't trigger
+  // peer migration.
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  writer_->SetWriteBlocked();
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+}
+
+// Regression test for b/168101557.
+TEST_P(QuicConnectionTest, HandshakeDataDoesNotGetPtoed) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  // Send HANDSHAKE packets.
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Send half RTT packet.
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  // Receives HANDSHAKE 1.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  // Verify there is pending ACK.
+  ASSERT_TRUE(connection_.HasPendingAcks());
+  // Set the send alarm.
+  connection_.GetSendAlarm()->Set(clock_.ApproximateNow());
+
+  // Fire ACK alarm.
+  connection_.GetAckAlarm()->Fire();
+  // Verify 1-RTT packet is coalesced with handshake packet.
+  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+  connection_.GetSendAlarm()->Fire();
+
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify a handshake packet gets PTOed and 1-RTT packet gets coalesced.
+  EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+}
+
+// Regression test for b/168294218.
+TEST_P(QuicConnectionTest, CoalescerHandlesInitialKeyDiscard) {
+  if (!connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_discard_initial_packet_with_key_dropped, true);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    use_tagging_decrypter();
+    ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                             std::make_unique<TaggingEncrypter>(0x01));
+    connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                             std::make_unique<TaggingEncrypter>(0x02));
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+    // Verify this packet is on hold.
+    EXPECT_EQ(0u, writer_->packets_write_attempts());
+  }
+  EXPECT_TRUE(connection_.connected());
+}
+
+// Regresstion test for b/168294218
+TEST_P(QuicConnectionTest, ZeroRttRejectionAndMissingInitialKeys) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  // Not defer send in response to packet.
+  connection_.set_defer_send_in_response_to_packets(false);
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).WillOnce(Invoke([this]() {
+    connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+    connection_.NeuterUnencryptedPackets();
+  }));
+  EXPECT_CALL(visitor_, OnCryptoFrame(_))
+      .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
+        if (frame.level == ENCRYPTION_HANDSHAKE) {
+          // 0-RTT gets rejected.
+          connection_.MarkZeroRttPacketsForRetransmission(0);
+          // Send Crypto data.
+          connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                                   std::make_unique<TaggingEncrypter>(0x03));
+          connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+          connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+          connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                                   std::make_unique<TaggingEncrypter>(0x04));
+          connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+          // Advance INITIAL ack delay to trigger initial ACK to be sent AFTER
+          // the retransmission of rejected 0-RTT packets while the HANDSHAKE
+          // packet is still in the coalescer, such that the INITIAL key gets
+          // dropped between SendAllPendingAcks and actually send the ack frame,
+          // bummer.
+          clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+        }
+      }));
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  QuicAckFrame frame1 = InitAckFrame(1);
+  // Received ACK for packet 1.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Fire retransmission alarm.
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  QuicFrames frames1;
+  frames1.push_back(QuicFrame(&crypto_frame_));
+  QuicFrames frames2;
+  QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
+                               absl::string_view(data1));
+  frames2.push_back(QuicFrame(&crypto_frame));
+  ProcessCoalescedPacket(
+      {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
+}
+
+TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SendCryptoStreamData();
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  connection_.SendStreamDataWithString(4, "bar", 0, NO_FIN);
+  // Received ACK for packet 1, HANDSHAKE packet and 1-RTT ACK.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  QuicFrames frames1;
+  QuicAckFrame ack_frame1 = InitAckFrame(1);
+  frames1.push_back(QuicFrame(&ack_frame1));
+
+  QuicFrames frames2;
+  QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
+                               absl::string_view(data1));
+  frames2.push_back(QuicFrame(&crypto_frame));
+  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+  ProcessCoalescedPacket(
+      {{1, frames1, ENCRYPTION_INITIAL}, {2, frames2, ENCRYPTION_HANDSHAKE}});
+
+  QuicFrames frames3;
+  QuicAckFrame ack_frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  frames3.push_back(QuicFrame(&ack_frame2));
+  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(1);
+  ProcessCoalescedPacket({{3, frames3, ENCRYPTION_FORWARD_SECURE}});
+
+  QuicFrames frames4;
+  QuicAckFrame ack_frame3 =
+      InitAckFrame({{QuicPacketNumber(3), QuicPacketNumber(4)}});
+  frames4.push_back(QuicFrame(&ack_frame3));
+  EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
+  ProcessCoalescedPacket({{4, frames4, ENCRYPTION_FORWARD_SECURE}});
+}
+
+TEST_P(QuicConnectionTest, InitiateKeyUpdate) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  TransportParameters params;
+  QuicConfig config;
+  std::string error_details;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+
+  MockFramerVisitor peer_framer_visitor_;
+  peer_framer_.set_visitor(&peer_framer_visitor_);
+
+  use_tagging_decrypter();
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+
+  // Key update should still not be allowed, since no packet has been acked
+  // from the current key phase.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Send packet 1.
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+
+  // Key update should still not be allowed, even though a packet was sent in
+  // the current key phase it hasn't been acked yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  // Receive ack for packet 1.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  ProcessAckPacket(&frame1);
+
+  // OnDecryptedFirstPacketInKeyPhase is called even on the first key phase,
+  // so discard_previous_keys_alarm_ should be set now.
+  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Key update should now be allowed.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x02);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  // discard_previous_keys_alarm_ should not be set until a packet from the new
+  // key phase has been received. (The alarm that was set above should be
+  // cleared if it hasn't fired before the next key update happened.)
+  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Pretend that peer accepts the key update.
+  EXPECT_CALL(peer_framer_visitor_,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
+  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
+  peer_framer_.SetKeyUpdateSupportForConnection(true);
+  peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
+
+  // Another key update should not be allowed yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+
+  // Send packet 2.
+  SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+  // Receive ack for packet 2.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame2 = InitAckFrame(2);
+  ProcessAckPacket(&frame2);
+  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Key update should be allowed again now that a packet has been acked from
+  // the current key phase.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x03);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  // Pretend that peer accepts the key update.
+  EXPECT_CALL(peer_framer_visitor_,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x03); });
+  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); });
+  peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
+
+  // Another key update should not be allowed yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+
+  // Send packet 3.
+  SendStreamDataToPeer(3, "baz", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(3u), last_packet);
+
+  // Another key update should not be allowed yet.
+  EXPECT_FALSE(connection_.IsKeyUpdateAllowed());
+  EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Receive ack for packet 3.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame3 = InitAckFrame(3);
+  ProcessAckPacket(&frame3);
+  EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+
+  // Key update should be allowed now.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x04); });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x04);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
+  EXPECT_FALSE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
+}
+
+TEST_P(QuicConnectionTest, InitiateKeyUpdateApproachingConfidentialityLimit) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 3U);
+
+  std::string error_details;
+  TransportParameters params;
+  // Key update is enabled.
+  QuicConfig config;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  MockFramerVisitor peer_framer_visitor_;
+  peer_framer_.set_visitor(&peer_framer_visitor_);
+
+  use_tagging_decrypter();
+
+  uint8_t current_tag = 0x01;
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(current_tag));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(current_tag));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+
+  peer_framer_.SetKeyUpdateSupportForConnection(true);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(current_tag));
+
+  const QuicConnectionStats& stats = connection_.GetStats();
+
+  for (int packet_num = 1; packet_num <= 8; ++packet_num) {
+    if (packet_num == 3 || packet_num == 6) {
+      current_tag++;
+      EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<StrictTaggingDecrypter>(current_tag);
+          });
+      EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<TaggingEncrypter>(current_tag);
+          });
+      EXPECT_CALL(visitor_,
+                  OnKeyUpdate(KeyUpdateReason::kLocalKeyUpdateLimitOverride));
+    }
+    // Send packet.
+    QuicPacketNumber last_packet;
+    SendStreamDataToPeer(packet_num, "foo", 0, NO_FIN, &last_packet);
+    EXPECT_EQ(QuicPacketNumber(packet_num), last_packet);
+    if (packet_num >= 6) {
+      EXPECT_EQ(2U, stats.key_update_count);
+    } else if (packet_num >= 3) {
+      EXPECT_EQ(1U, stats.key_update_count);
+    } else {
+      EXPECT_EQ(0U, stats.key_update_count);
+    }
+
+    if (packet_num == 4 || packet_num == 7) {
+      // Pretend that peer accepts the key update.
+      EXPECT_CALL(peer_framer_visitor_,
+                  AdvanceKeysAndCreateCurrentOneRttDecrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<StrictTaggingDecrypter>(current_tag);
+          });
+      EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+          .WillOnce([current_tag]() {
+            return std::make_unique<TaggingEncrypter>(current_tag);
+          });
+      peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
+    }
+    // Receive ack for packet.
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    QuicAckFrame frame1 = InitAckFrame(packet_num);
+    ProcessAckPacket(&frame1);
+  }
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionOnConfidentialityLimitKeyUpdateNotAllowed) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  // Set key update confidentiality limit to 1 packet.
+  SetQuicFlag(FLAGS_quic_key_update_confidentiality_limit, 1U);
+  // Use confidentiality limit for connection close of 3 packets.
+  constexpr size_t kConfidentialityLimit = 3U;
+
+  std::string error_details;
+  TransportParameters params;
+  // Key update is enabled.
+  QuicConfig config;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypterWithConfidentialityLimit>(
+          Perspective::IS_CLIENT, kConfidentialityLimit));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+
+  QuicPacketNumber last_packet;
+  // Send 3 packets without receiving acks for any of them. Key update will not
+  // be allowed, so the confidentiality limit should be reached, forcing the
+  // connection to be closed.
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_TRUE(connection_.connected());
+  SendStreamDataToPeer(2, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_FALSE(connection_.connected());
+  const QuicConnectionStats& stats = connection_.GetStats();
+  EXPECT_EQ(0U, stats.key_update_count);
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitDuringHandshake) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 3;
+
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+      EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAfterHandshake) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 3;
+
+  use_tagging_decrypter();
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionOnIntegrityLimitAcrossEncryptionLevels) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 4;
+
+  use_tagging_decrypter();
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= 2; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, IntegrityLimitDoesNotApplyWithoutDecryptionKey) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr uint8_t correct_tag = 0x01;
+  constexpr uint8_t wrong_tag = 0xFE;
+  constexpr QuicPacketCount kIntegrityLimit = 3;
+
+  use_tagging_decrypter();
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   correct_tag, kIntegrityLimit));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(correct_tag));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(wrong_tag));
+  for (uint64_t i = 1; i <= kIntegrityLimit * 2; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        0u, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOnIntegrityLimitAcrossKeyPhases) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  constexpr QuicPacketCount kIntegrityLimit = 4;
+
+  TransportParameters params;
+  QuicConfig config;
+  std::string error_details;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  if (connection_.version().UsesTls()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+        &config, connection_.connection_id());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  MockFramerVisitor peer_framer_visitor_;
+  peer_framer_.set_visitor(&peer_framer_visitor_);
+
+  use_tagging_decrypter();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+                   0x01, kIntegrityLimit));
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  for (uint64_t i = 1; i <= 2; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  // Send packet 1.
+  QuicPacketNumber last_packet;
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
+  // Receive ack for packet 1.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  ProcessAckPacket(&frame1);
+  // Key update should now be allowed, initiate it.
+  EXPECT_CALL(visitor_, AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce([kIntegrityLimit]() {
+        return std::make_unique<StrictTaggingDecrypterWithIntegrityLimit>(
+            0x02, kIntegrityLimit);
+      });
+  EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() {
+    return std::make_unique<TaggingEncrypter>(0x02);
+  });
+  EXPECT_CALL(visitor_, OnKeyUpdate(KeyUpdateReason::kLocalForTests));
+  EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests));
+
+  // Pretend that peer accepts the key update.
+  EXPECT_CALL(peer_framer_visitor_,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter())
+      .WillOnce(
+          []() { return std::make_unique<StrictTaggingDecrypter>(0x02); });
+  EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter())
+      .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); });
+  peer_framer_.SetKeyUpdateSupportForConnection(true);
+  peer_framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests);
+
+  // Send packet 2.
+  SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
+  // Receive ack for packet 2.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  QuicAckFrame frame2 = InitAckFrame(2);
+  ProcessAckPacket(&frame2);
+
+  EXPECT_EQ(2u,
+            connection_.GetStats().num_failed_authentication_packets_received);
+
+  // Do two more undecryptable packets. Integrity limit should be reached.
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  for (uint64_t i = 3; i <= kIntegrityLimit; ++i) {
+    EXPECT_TRUE(connection_.connected());
+    if (i == kIntegrityLimit) {
+      EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+    }
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+    EXPECT_EQ(
+        i, connection_.GetStats().num_failed_authentication_packets_received);
+  }
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(QUIC_AEAD_LIMIT_REACHED);
+}
+
+TEST_P(QuicConnectionTest, SendAckFrequencyFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  connection_.OnHandshakeComplete();
+
+  writer_->SetWritable();
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 99);
+  // Send packet 100
+  SendStreamDataToPeer(/*id=*/1, "foo", /*offset=*/0, NO_FIN, nullptr);
+
+  QuicAckFrequencyFrame captured_frame;
+  EXPECT_CALL(visitor_, SendAckFrequency(_))
+      .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
+        captured_frame = frame;
+      }));
+  // Send packet 101.
+  SendStreamDataToPeer(/*id=*/1, "bar", /*offset=*/3, NO_FIN, nullptr);
+
+  EXPECT_EQ(captured_frame.packet_tolerance, 10u);
+  EXPECT_EQ(captured_frame.max_ack_delay,
+            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+
+  // Sending packet 102 does not trigger sending another AckFrequencyFrame.
+  SendStreamDataToPeer(/*id=*/1, "baz", /*offset=*/6, NO_FIN, nullptr);
+}
+
+TEST_P(QuicConnectionTest, SendAckFrequencyFrameUponHandshakeCompletion) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  QuicTagVector quic_tag_vector;
+  // Enable sending AckFrequency upon handshake completion.
+  quic_tag_vector.push_back(kAFF2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  QuicAckFrequencyFrame captured_frame;
+  EXPECT_CALL(visitor_, SendAckFrequency(_))
+      .WillOnce(Invoke([&captured_frame](const QuicAckFrequencyFrame& frame) {
+        captured_frame = frame;
+      }));
+
+  connection_.OnHandshakeComplete();
+
+  EXPECT_EQ(captured_frame.packet_tolerance, 2u);
+  EXPECT_EQ(captured_frame.max_ack_delay,
+            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+}
+
+TEST_P(QuicConnectionTest, FastRecoveryOfLostServerHello) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.SendCryptoStreamData();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+  // Assume ServerHello gets lost.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // Shorten PTO for fast recovery from lost ServerHello.
+  EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
+            connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, ServerHelloGetsReordered) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  connection_.SetFromConfig(config);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_))
+      .WillRepeatedly(Invoke([=](const QuicCryptoFrame& frame) {
+        if (frame.level == ENCRYPTION_INITIAL) {
+          // Install handshake read keys.
+          SetDecrypter(ENCRYPTION_HANDSHAKE,
+                       std::make_unique<StrictTaggingDecrypter>(0x02));
+          connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                                   std::make_unique<TaggingEncrypter>(0x02));
+          connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+        }
+      }));
+
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.SendCryptoStreamData();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+  // Assume ServerHello gets reordered.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x02));
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_HANDSHAKE);
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  // Verify fast recovery is not enabled.
+  EXPECT_EQ(connection_.sent_packet_manager().GetRetransmissionTime(),
+            connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, MigratePath) {
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+  EXPECT_CALL(visitor_, OnPathDegrading());
+  connection_.OnPathDegradingDetected();
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+
+  // Buffer a packet.
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+  writer_->SetWriteBlocked();
+  connection_.SendMtuDiscoveryPacket(kMaxOutgoingPacketSize);
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading());
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, /*owns_writer=*/false);
+
+  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
+  EXPECT_EQ(&new_writer, QuicConnectionPeer::GetWriter(&connection_));
+  EXPECT_FALSE(connection_.IsPathDegrading());
+  // Buffered packet on the old path should be discarded.
+  if (connection_.connection_migration_use_new_cid()) {
+    EXPECT_EQ(0u, connection_.NumQueuedPackets());
+  } else {
+    EXPECT_EQ(1u, connection_.NumQueuedPackets());
+  }
+}
+
+TEST_P(QuicConnectionTest, MigrateToNewPathDuringProbing) {
+  if (!VersionHasIetfQuicFrames(connection_.version().transport_version) ||
+      !connection_.use_path_validator()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
+  EXPECT_NE(kNewSelfAddress, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  bool success = false;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), &new_writer),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePath(
+      &connection_, kNewSelfAddress, connection_.peer_address()));
+
+  connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
+                          &new_writer, /*owns_writer=*/false);
+  EXPECT_EQ(kNewSelfAddress, connection_.self_address());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  EXPECT_FALSE(QuicConnectionPeer::IsAlternativePath(
+      &connection_, kNewSelfAddress, connection_.peer_address()));
+}
+
+TEST_P(QuicConnectionTest, SingleAckInPacket) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    connection_.SendStreamData3();
+    connection_.CloseConnection(
+        QUIC_INTERNAL_ERROR, "error",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  ASSERT_FALSE(writer_->ack_frames().empty());
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+}
+
+TEST_P(QuicConnectionTest,
+       ServerReceivedZeroRttPacketAfterOneRttPacketWithRetainedKey) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_SERVER);
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Finish handshake.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+
+  // 0-RTT packet received out of order should be decoded since the decrypter
+  // is temporarily retained.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(
+      0u,
+      connection_.GetStats()
+          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
+
+  // Simulate the timeout for discarding 0-RTT keys passing.
+  connection_.GetDiscardZeroRttDecryptionKeysAlarm()->Fire();
+
+  // Another 0-RTT packet received now should not be decoded.
+  EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(
+      1u,
+      connection_.GetStats()
+          .num_tls_server_zero_rtt_packets_received_after_discarding_decrypter);
+
+  // The |discard_zero_rtt_decryption_keys_alarm_| should only be set on the
+  // first 1-RTT packet received.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(5, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, NewTokenFrameInstigateAcks) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
+  EXPECT_CALL(visitor_, OnNewTokenReceived(_));
+  ProcessFramePacket(QuicFrame(new_token));
+
+  // Ensure that this has caused the ACK alarm to be set.
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, ServerClosesConnectionOnNewTokenFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
+  EXPECT_CALL(visitor_, OnNewTokenReceived(_)).Times(0);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  ProcessFramePacket(QuicFrame(new_token));
+  EXPECT_FALSE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, OverrideRetryTokenWithRetryPacket) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  std::string address_token = "TestAddressToken";
+  connection_.SetSourceAddressTokenToSend(address_token);
+  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
+                QuicConnectionPeer::GetPacketCreator(&connection_)),
+            address_token);
+  // Passes valid retry and verify token gets overridden.
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, DonotOverrideRetryTokenWithAddressToken) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  // Passes valid retry and verify token gets overridden.
+  TestClientRetryHandling(/*invalid_retry_tag=*/false,
+                          /*missing_original_id_in_config=*/false,
+                          /*wrong_original_id_in_config=*/false,
+                          /*missing_retry_id_in_config=*/false,
+                          /*wrong_retry_id_in_config=*/false);
+  std::string retry_token = QuicPacketCreatorPeer::GetRetryToken(
+      QuicConnectionPeer::GetPacketCreator(&connection_));
+
+  std::string address_token = "TestAddressToken";
+  connection_.SetSourceAddressTokenToSend(address_token);
+  EXPECT_EQ(QuicPacketCreatorPeer::GetRetryToken(
+                QuicConnectionPeer::GetPacketCreator(&connection_)),
+            retry_token);
+}
+
+TEST_P(QuicConnectionTest,
+       ServerReceivedZeroRttWithHigherPacketNumberThanOneRtt) {
+  if (!connection_.version().UsesTls()) {
+    return;
+  }
+
+  // The code that checks for this error piggybacks on some book-keeping state
+  // kept for key update, so enable key update for the test.
+  std::string error_details;
+  TransportParameters params;
+  QuicConfig config;
+  EXPECT_THAT(config.ProcessTransportParameters(
+                  params, /* is_resumption = */ false, &error_details),
+              IsQuicNoError());
+  QuicConfigPeer::SetNegotiated(&config, true);
+  QuicConfigPeer::SetReceivedOriginalConnectionId(&config,
+                                                  connection_.connection_id());
+  QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+      &config, connection_.connection_id());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+
+  set_perspective(Perspective::IS_SERVER);
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  // Finish handshake.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  // Decrypt a 1-RTT packet.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.GetDiscardZeroRttDecryptionKeysAlarm()->IsSet());
+
+  // 0-RTT packet with higher packet number than a 1-RTT packet is invalid and
+  // should cause the connection to be closed.
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  EXPECT_FALSE(connection_.connected());
+  TestConnectionCloseQuicErrorCode(
+      QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
+}
+
+// Regression test for b/177312785
+TEST_P(QuicConnectionTest, PeerMigrateBeforeHandshakeConfirm) {
+  if (!VersionHasIetfQuicFrames(version().transport_version)) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_START));
+
+  // Clear direct_peer_address.
+  QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+  // Clear effective_peer_address, it is the same as direct_peer_address for
+  // this test.
+  QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+                                              QuicSocketAddress());
+  EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress, kPeerAddress,
+                                  ENCRYPTION_INITIAL);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+  // Process another packet with a different peer address on server side will
+  // close connection.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+  EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(0);
+  ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
+                                  kNewPeerAddress, ENCRYPTION_INITIAL);
+  EXPECT_FALSE(connection_.connected());
+}
+
+// Regresstion test for b/175685916
+TEST_P(QuicConnectionTest, TryToFlushAckWithAckQueued) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  set_perspective(Perspective::IS_SERVER);
+
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  connection_.SetFromConfig(config);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_.OnHandshakeComplete();
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 200);
+
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  // Sending ACK_FREQUENCY bundles ACK. QuicConnectionPeer::SendPing
+  // will try to bundle ACK but there is no pending ACK.
+  EXPECT_CALL(visitor_, SendAckFrequency(_))
+      .WillOnce(Invoke(&notifier_,
+                       &SimpleSessionNotifier::WriteOrBufferAckFrequency));
+  QuicConnectionPeer::SendPing(&connection_);
+}
+
+TEST_P(QuicConnectionTest, PathChallengeBeforePeerIpAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  SetClientConnectionId(TestConnectionId(1));
+  connection_.CreateConnectionIdManager();
+
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId client_cid0 = connection_.client_connection_id();
+  QuicConnectionId client_cid1 = TestConnectionId(2);
+  QuicConnectionId server_cid1;
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+  // Receives new client CID from client.
+  QuicNewConnectionIdFrame new_cid_frame;
+  new_cid_frame.connection_id = client_cid1;
+  new_cid_frame.sequence_number = 1u;
+  new_cid_frame.retire_prior_to = 0u;
+  connection_.OnNewConnectionIdFrame(new_cid_frame);
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  peer_creator_.SetServerConnectionId(server_cid1);
+  const QuicSocketAddress kNewPeerAddress =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicFrames frames1;
+  frames1.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+  QuicPathFrameBuffer payload;
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(AtLeast(1))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+        EXPECT_FALSE(writer_->path_response_frames().empty());
+        EXPECT_FALSE(writer_->path_challenge_frames().empty());
+        payload = writer_->path_challenge_frames().front().data_buffer;
+      }));
+  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid0);
+  EXPECT_EQ(default_path->server_connection_id, server_cid0);
+  EXPECT_EQ(alternative_path->client_connection_id, client_cid1);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Process another packet with a different peer address on server side will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  }));
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_TRUE(writer_->path_challenge_frames().empty());
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid1);
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  // The previous default path is kept as alternative path before reverse path
+  // validation finishes.
+  EXPECT_EQ(alternative_path->client_connection_id, client_cid0);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid0);
+  EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
+
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            connection_.active_effective_peer_migration_type());
+  EXPECT_EQ(1u, connection_.GetStats()
+                    .num_peer_migration_to_proactively_validated_address);
+
+  // The PATH_CHALLENGE and PATH_RESPONSE is expanded upto the max packet size
+  // which may exceeds the anti-amplification limit. Verify server is throttled
+  // by anti-amplification limit.
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receiving PATH_RESPONSE should lift the anti-amplification limit.
+  QuicFrames frames3;
+  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  EXPECT_CALL(visitor_, MaybeSendAddressToken());
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .Times(testing::AtLeast(1u));
+  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  // Verify that alternative_path_ is cleared and the peer CID is retired.
+  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+
+  // Verify the anti-amplification limit is lifted by sending a packet larger
+  // than the anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+}
+
+TEST_P(QuicConnectionTest,
+       PathValidationSucceedsBeforePeerIpAddressChangeAtServer) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId server_cid1;
+  // Sends new server CID to client.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(
+          Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Receive probing packet with new peer address.
+  peer_creator_.SetServerConnectionId(server_cid1);
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+  QuicPathFrameBuffer payload;
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.peer_address());
+        EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+        EXPECT_FALSE(writer_->path_response_frames().empty());
+        EXPECT_FALSE(writer_->path_challenge_frames().empty());
+        payload = writer_->path_challenge_frames().front().data_buffer;
+      }))
+      .WillRepeatedly(Invoke([&]() {
+        // Only start reverse path validation once.
+        EXPECT_TRUE(writer_->path_challenge_frames().empty());
+      }));
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicFrames frames1;
+  frames1.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_EQ(default_path->server_connection_id, server_cid0);
+  EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+  // Receive PATH_RESPONSE should mark the new peer address validated.
+  QuicFrames frames3;
+  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+
+  // Process another packet with a newer peer address with the same port will
+  // start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
+                                            /*port=*/34567);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
+  }));
+  EXPECT_CALL(visitor_, MaybeSendAddressToken());
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewerPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewerPeerAddress, connection_.peer_address());
+  EXPECT_EQ(kNewerPeerAddress, connection_.effective_peer_address());
+  // Since the newer address has the same IP as the previously validated probing
+  // address. The peer migration becomes validated immediately.
+  EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
+  EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
+  EXPECT_EQ(1u, connection_.GetStats()
+                    .num_peer_migration_to_proactively_validated_address);
+  EXPECT_FALSE(connection_.HasPendingPathValidation());
+  EXPECT_NE(connection_.sent_packet_manager().GetSendAlgorithm(),
+            send_algorithm_);
+
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid1);
+  // Verify that alternative_path_ is cleared.
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+
+  // Verify the server is not throttled by the anti-amplification limit by
+  // sending a packet larger than the anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  connection_.SendCryptoDataWithString(std::string(1200, 'a'), 0);
+  EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
+}
+
+TEST_P(QuicConnectionTest,
+       ProbedOnAnotherPathAfterPeerIpAddressChangeAtServer) {
+  PathProbeTestInit(Perspective::IS_SERVER);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+
+  const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/23456);
+
+  // Process a packet with a new peer address will start connection migration.
+  EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
+  // IETF QUIC send algorithm should be changed to a different object, so no
+  // OnPacketSent() called on the old send algorithm.
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+      .Times(0);
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([=]() {
+    EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  }));
+  QuicFrames frames2;
+  frames2.push_back(QuicFrame(frame2_));
+  ProcessFramesPacketWithAddresses(frames2, kSelfAddress, kNewPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+
+  // Switch to use the mock send algorithm.
+  send_algorithm_ = new StrictMock<MockSendAlgorithm>();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
+  connection_.SetSendAlgorithm(send_algorithm_);
+
+  // Receive probing packet with a newer peer address shouldn't override the
+  // on-going path validation.
+  const QuicSocketAddress kNewerPeerAddress(QuicIpAddress::Loopback4(),
+                                            /*port=*/34567);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(Invoke([&]() {
+        EXPECT_EQ(kNewerPeerAddress, writer_->last_write_peer_address());
+        EXPECT_FALSE(writer_->path_response_frames().empty());
+        EXPECT_TRUE(writer_->path_challenge_frames().empty());
+      }));
+  QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+  QuicFrames frames1;
+  frames1.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+  ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewerPeerAddress,
+                                   ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+  EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+  EXPECT_TRUE(QuicConnectionPeer::IsAlternativePathValidated(&connection_));
+  EXPECT_TRUE(connection_.HasPendingPathValidation());
+}
+
+TEST_P(QuicConnectionTest,
+       PathValidationFailedOnClientDueToLackOfServerConnectionId) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+    config.SetConnectionOptionsToSend({kRVCM});
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/34567);
+
+  bool success;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+
+  EXPECT_FALSE(success);
+}
+
+TEST_P(QuicConnectionTest,
+       PathValidationFailedOnClientDueToLackOfClientConnectionIdTheSecondTime) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+  SetClientConnectionId(TestConnectionId(1));
+
+  // Make sure server connection ID is available for the 1st validation.
+  QuicConnectionId server_cid0 = connection_.connection_id();
+  QuicConnectionId server_cid1 = TestConnectionId(2);
+  QuicConnectionId server_cid2 = TestConnectionId(4);
+  QuicConnectionId client_cid1;
+  QuicNewConnectionIdFrame frame1;
+  frame1.connection_id = server_cid1;
+  frame1.sequence_number = 1u;
+  frame1.retire_prior_to = 0u;
+  frame1.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
+  connection_.OnNewConnectionIdFrame(frame1);
+  const auto* packet_creator =
+      QuicConnectionPeer::GetPacketCreator(&connection_);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid0);
+
+  // Client will issue a new client connection ID to server.
+  EXPECT_CALL(visitor_, SendNewConnectionId(_))
+      .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
+        client_cid1 = frame.connection_id;
+      }));
+
+  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
+  ASSERT_NE(kSelfAddress1, connection_.self_address());
+  bool success1;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kSelfAddress1, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kSelfAddress1, connection_.peer_address(), &success1));
+
+  // Migrate upon 1st validation success.
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
+                                      &new_writer, /*owns_writer=*/false));
+  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, client_cid1);
+  EXPECT_EQ(default_path->server_connection_id, server_cid1);
+  EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), server_cid1);
+
+  // Client will retire server connection ID on old default_path.
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+
+  // Another server connection ID is available to client.
+  QuicNewConnectionIdFrame frame2;
+  frame2.connection_id = server_cid2;
+  frame2.sequence_number = 2u;
+  frame2.retire_prior_to = 1u;
+  frame2.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
+  connection_.OnNewConnectionIdFrame(frame2);
+
+  const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
+                                        /*port=*/45678);
+  bool success2;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kSelfAddress2, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kSelfAddress2, connection_.peer_address(), &success2));
+  // Since server does not retire any client connection ID yet, 2nd validation
+  // would fail due to lack of client connection ID.
+  EXPECT_FALSE(success2);
+}
+
+TEST_P(QuicConnectionTest, ServerConnectionIdRetiredUponPathValidationFailure) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT);
+
+  // Make sure server connection ID is available for validation.
+  QuicNewConnectionIdFrame frame;
+  frame.connection_id = TestConnectionId(2);
+  frame.sequence_number = 1u;
+  frame.retire_prior_to = 0u;
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  connection_.OnNewConnectionIdFrame(frame);
+
+  const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Loopback4(),
+                                          /*port=*/34567);
+  bool success;
+  connection_.ValidatePath(
+      std::make_unique<TestQuicPathValidationContext>(
+          kNewSelfAddress, connection_.peer_address(), writer_.get()),
+      std::make_unique<TestValidationResultDelegate>(
+          &connection_, kNewSelfAddress, connection_.peer_address(), &success));
+
+  auto* path_validator = QuicConnectionPeer::path_validator(&connection_);
+  path_validator->CancelPathValidation();
+  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
+  EXPECT_FALSE(success);
+  const auto* alternative_path =
+      QuicConnectionPeer::GetAlternativePath(&connection_);
+  EXPECT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  EXPECT_TRUE(alternative_path->server_connection_id.IsEmpty());
+  EXPECT_FALSE(alternative_path->stateless_reset_token.has_value());
+
+  // Client will retire server connection ID on alternative_path.
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/1u));
+  retire_peer_issued_cid_alarm->Fire();
+}
+
+TEST_P(QuicConnectionTest,
+       MigratePathDirectlyFailedDueToLackOfServerConnectionId) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
+  ASSERT_NE(kSelfAddress1, connection_.self_address());
+
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  ASSERT_FALSE(connection_.MigratePath(kSelfAddress1,
+                                       connection_.peer_address(), &new_writer,
+                                       /*owns_writer=*/false));
+}
+
+TEST_P(QuicConnectionTest,
+       MigratePathDirectlyFailedDueToLackOfClientConnectionIdTheSecondTime) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_CLIENT,
+                    /*receive_new_server_connection_id=*/false);
+  SetClientConnectionId(TestConnectionId(1));
+
+  // Make sure server connection ID is available for the 1st migration.
+  QuicNewConnectionIdFrame frame1;
+  frame1.connection_id = TestConnectionId(2);
+  frame1.sequence_number = 1u;
+  frame1.retire_prior_to = 0u;
+  frame1.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame1.connection_id);
+  connection_.OnNewConnectionIdFrame(frame1);
+
+  // Client will issue a new client connection ID to server.
+  QuicConnectionId new_client_connection_id;
+  EXPECT_CALL(visitor_, SendNewConnectionId(_))
+      .WillOnce(Invoke([&](const QuicNewConnectionIdFrame& frame) {
+        new_client_connection_id = frame.connection_id;
+      }));
+
+  // 1st migration is successful.
+  const QuicSocketAddress kSelfAddress1(QuicIpAddress::Any4(), 12345);
+  ASSERT_NE(kSelfAddress1, connection_.self_address());
+  TestPacketWriter new_writer(version(), &clock_, Perspective::IS_CLIENT);
+  ASSERT_TRUE(connection_.MigratePath(kSelfAddress1, connection_.peer_address(),
+                                      &new_writer,
+                                      /*owns_writer=*/false));
+  QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(&connection_);
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  EXPECT_EQ(default_path->client_connection_id, new_client_connection_id);
+  EXPECT_EQ(default_path->server_connection_id, frame1.connection_id);
+  EXPECT_EQ(default_path->stateless_reset_token, frame1.stateless_reset_token);
+
+  // Client will retire server connection ID on old default_path.
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+
+  // Another server connection ID is available to client.
+  QuicNewConnectionIdFrame frame2;
+  frame2.connection_id = TestConnectionId(4);
+  frame2.sequence_number = 2u;
+  frame2.retire_prior_to = 1u;
+  frame2.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame2.connection_id);
+  connection_.OnNewConnectionIdFrame(frame2);
+
+  // Since server does not retire any client connection ID yet, 2nd migration
+  // would fail due to lack of client connection ID.
+  const QuicSocketAddress kSelfAddress2(QuicIpAddress::Loopback4(),
+                                        /*port=*/45678);
+  auto new_writer2 = std::make_unique<TestPacketWriter>(version(), &clock_,
+                                                        Perspective::IS_CLIENT);
+  ASSERT_FALSE(connection_.MigratePath(
+      kSelfAddress2, connection_.peer_address(), new_writer2.release(),
+      /*owns_writer=*/true));
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionAfterReceiveNewConnectionIdFromPeerUsingEmptyCID) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  ASSERT_TRUE(connection_.client_connection_id().IsEmpty());
+
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest, NewConnectionIdFrameResultsInError) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.CreateConnectionIdManager();
+  ASSERT_FALSE(connection_.connection_id().IsEmpty());
+
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = connection_id_;  // Reuses connection ID casuing error.
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_FALSE(connection_.OnNewConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest,
+       ClientRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  connection_.CreateConnectionIdManager();
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
+
+  frame.sequence_number = 2u;
+  frame.connection_id = TestConnectionId(2);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.connection_id(), connection_id_);
+
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(connection_.connection_id(), TestConnectionId(2));
+  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
+            TestConnectionId(2));
+}
+
+TEST_P(QuicConnectionTest,
+       ServerRetirePeerIssuedConnectionIdTriggeredByNewConnectionIdFrame) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  SetClientConnectionId(TestConnectionId(0));
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
+
+  frame.sequence_number = 2u;
+  frame.connection_id = TestConnectionId(2);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
+
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
+  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
+            TestConnectionId(2));
+}
+
+TEST_P(
+    QuicConnectionTest,
+    ReplacePeerIssuedConnectionIdOnBothPathsTriggeredByNewConnectionIdFrame) {
+  if (!version().HasIetfQuicFrames() || !connection_.use_path_validator() ||
+      !connection_.count_bytes_on_alternative_path_separately()) {
+    return;
+  }
+  PathProbeTestInit(Perspective::IS_SERVER);
+  SetClientConnectionId(TestConnectionId(0));
+
+  // Populate alternative_path_ with probing packet.
+  std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+
+  std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+      QuicEncryptedPacket(probing_packet->encrypted_buffer,
+                          probing_packet->encrypted_length),
+      clock_.Now()));
+  QuicIpAddress new_host;
+  new_host.FromString("1.1.1.1");
+  ProcessReceivedPacket(kSelfAddress,
+                        QuicSocketAddress(new_host, /*port=*/23456), *received);
+
+  EXPECT_EQ(
+      TestConnectionId(0),
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(1);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  auto* retire_peer_issued_cid_alarm =
+      connection_.GetRetirePeerIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_peer_issued_cid_alarm->IsSet());
+
+  frame.sequence_number = 2u;
+  frame.connection_id = TestConnectionId(2);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 1u;  // CID associated with #1 will be retired.
+
+  EXPECT_TRUE(connection_.OnNewConnectionIdFrame(frame));
+  ASSERT_TRUE(retire_peer_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(0));
+
+  EXPECT_CALL(visitor_, SendRetireConnectionId(/*sequence_number=*/0u));
+  retire_peer_issued_cid_alarm->Fire();
+  EXPECT_EQ(connection_.client_connection_id(), TestConnectionId(2));
+  EXPECT_EQ(connection_.packet_creator().GetDestinationConnectionId(),
+            TestConnectionId(2));
+  // Clean up alternative path connection ID.
+  EXPECT_EQ(
+      TestConnectionId(2),
+      QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(&connection_));
+}
+
+TEST_P(QuicConnectionTest,
+       CloseConnectionAfterReceiveRetireConnectionIdWhenNoCIDIssued) {
+  if (!version().HasIetfQuicFrames() ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+
+  EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest, RetireConnectionIdFrameResultsInError) {
+  if (!version().HasIetfQuicFrames() ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+      .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 2u;  // The corresponding ID is never issued.
+
+  EXPECT_FALSE(connection_.OnRetireConnectionIdFrame(frame));
+
+  EXPECT_FALSE(connection_.connected());
+  EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+              IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+}
+
+TEST_P(QuicConnectionTest,
+       ServerRetireSelfIssuedConnectionIdWithoutSendingNewConnectionIdBefore) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+
+  auto* retire_self_issued_cid_alarm =
+      connection_.GetRetireSelfIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
+
+  QuicConnectionId cid0 = connection_id_;
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 0u;
+  if (connection_.connection_migration_use_new_cid()) {
+    EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_)).Times(2);
+    EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
+  }
+  EXPECT_TRUE(connection_.OnRetireConnectionIdFrame(frame));
+}
+
+TEST_P(QuicConnectionTest, ServerRetireSelfIssuedConnectionId) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+  QuicConnectionId recorded_cid;
+  auto cid_recorder = [&recorded_cid](const QuicConnectionId& cid) {
+    recorded_cid = cid;
+  };
+  QuicConnectionId cid0 = connection_id_;
+  QuicConnectionId cid1;
+  QuicConnectionId cid2;
+  EXPECT_EQ(connection_.connection_id(), cid0);
+  EXPECT_EQ(connection_.GetOneActiveServerConnectionId(), cid0);
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke(cid_recorder));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  connection_.MaybeSendConnectionIdToClient();
+  cid1 = recorded_cid;
+
+  auto* retire_self_issued_cid_alarm =
+      connection_.GetRetireSelfIssuedConnectionIdAlarm();
+  ASSERT_FALSE(retire_self_issued_cid_alarm->IsSet());
+
+  // Generate three packets with different connection IDs that will arrive out
+  // of order (2, 1, 3) later.
+  char buffers[3][kMaxOutgoingPacketSize];
+  // Destination connection ID of packet1 is cid0.
+  auto packet1 =
+      ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
+                      buffers[0], kMaxOutgoingPacketSize);
+  peer_creator_.SetServerConnectionId(cid1);
+  auto retire_cid_frame = std::make_unique<QuicRetireConnectionIdFrame>();
+  retire_cid_frame->sequence_number = 0u;
+  // Destination connection ID of packet2 is cid1.
+  auto packet2 = ConstructPacket({QuicFrame(retire_cid_frame.release())},
+                                 ENCRYPTION_FORWARD_SECURE, buffers[1],
+                                 kMaxOutgoingPacketSize);
+  // Destination connection ID of packet3 is cid1.
+  auto packet3 =
+      ConstructPacket({QuicFrame(QuicPingFrame())}, ENCRYPTION_FORWARD_SECURE,
+                      buffers[2], kMaxOutgoingPacketSize);
+
+  // Packet2 with RetireConnectionId frame trigers sending NewConnectionId
+  // immediately.
+  EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+      .WillOnce(Invoke(cid_recorder));
+  EXPECT_CALL(visitor_, SendNewConnectionId(_));
+  peer_creator_.SetServerConnectionId(cid1);
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet2);
+  cid2 = recorded_cid;
+  // cid0 is not retired immediately.
+  EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
+              ElementsAre(cid0, cid1, cid2));
+  ASSERT_TRUE(retire_self_issued_cid_alarm->IsSet());
+  EXPECT_EQ(connection_.connection_id(), cid1);
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
+              connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+
+  // Packet1 updates the connection ID on the default path but not the active
+  // connection ID.
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet1);
+  EXPECT_EQ(connection_.connection_id(), cid0);
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid0 ||
+              connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+
+  // cid0 is retired when the retire CID alarm fires.
+  EXPECT_CALL(visitor_, OnServerConnectionIdRetired(cid0));
+  retire_self_issued_cid_alarm->Fire();
+  EXPECT_THAT(connection_.GetActiveServerConnectionIds(),
+              ElementsAre(cid1, cid2));
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+
+  // Packet3 updates the connection ID on the default path.
+  connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *packet3);
+  EXPECT_EQ(connection_.connection_id(), cid1);
+  EXPECT_TRUE(connection_.GetOneActiveServerConnectionId() == cid1 ||
+              connection_.GetOneActiveServerConnectionId() == cid2);
+}
+
+TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoAlternativePath) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+  connection_.set_client_connection_id(TestConnectionId(1));
+
+  // Set up the state after path probing.
+  const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
+  QuicIpAddress new_host;
+  new_host.FromString("12.12.12.12");
+  alternative_path->self_address = default_path->self_address;
+  alternative_path->peer_address = QuicSocketAddress(new_host, 12345);
+  alternative_path->server_connection_id = TestConnectionId(3);
+  ASSERT_TRUE(alternative_path->client_connection_id.IsEmpty());
+  ASSERT_FALSE(alternative_path->stateless_reset_token.has_value());
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(5);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+  // New ID is patched onto the alternative path when the needed
+  // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
+  connection_.OnNewConnectionIdFrame(frame);
+
+  ASSERT_EQ(alternative_path->client_connection_id, frame.connection_id);
+  ASSERT_EQ(alternative_path->stateless_reset_token,
+            frame.stateless_reset_token);
+}
+
+TEST_P(QuicConnectionTest, PatchMissingClientConnectionIdOntoDefaultPath) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.CreateConnectionIdManager();
+  connection_.set_client_connection_id(TestConnectionId(1));
+
+  // Set up the state after peer migration without probing.
+  auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+  auto* alternative_path = QuicConnectionPeer::GetAlternativePath(&connection_);
+  auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+  *alternative_path = std::move(*default_path);
+  QuicIpAddress new_host;
+  new_host.FromString("12.12.12.12");
+  default_path->self_address = default_path->self_address;
+  default_path->peer_address = QuicSocketAddress(new_host, 12345);
+  default_path->server_connection_id = TestConnectionId(3);
+  packet_creator->SetDefaultPeerAddress(default_path->peer_address);
+  packet_creator->SetServerConnectionId(default_path->server_connection_id);
+  packet_creator->SetClientConnectionId(default_path->client_connection_id);
+
+  ASSERT_FALSE(default_path->validated);
+  ASSERT_TRUE(default_path->client_connection_id.IsEmpty());
+  ASSERT_FALSE(default_path->stateless_reset_token.has_value());
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 1u;
+  frame.connection_id = TestConnectionId(5);
+  frame.stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(frame.connection_id);
+  frame.retire_prior_to = 0u;
+  // New ID is patched onto the default path when the needed
+  // NEW_CONNECTION_ID frame is received after PATH_CHALLENGE frame.
+  connection_.OnNewConnectionIdFrame(frame);
+
+  ASSERT_EQ(default_path->client_connection_id, frame.connection_id);
+  ASSERT_EQ(default_path->stateless_reset_token, frame.stateless_reset_token);
+  ASSERT_EQ(packet_creator->GetDestinationConnectionId(), frame.connection_id);
+}
+
+TEST_P(QuicConnectionTest, ShouldGeneratePacketBlockedByMissingConnectionId) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  connection_.set_client_connection_id(TestConnectionId(1));
+  connection_.CreateConnectionIdManager();
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+
+  ASSERT_TRUE(
+      connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
+
+  QuicPacketCreator* packet_creator =
+      QuicConnectionPeer::GetPacketCreator(&connection_);
+  QuicIpAddress peer_host1;
+  peer_host1.FromString("12.12.12.12");
+  QuicSocketAddress peer_address1(peer_host1, 1235);
+
+  {
+    // No connection ID is available as context is created without any.
+    QuicPacketCreator::ScopedPeerAddressContext context(
+        packet_creator, peer_address1, EmptyQuicConnectionId(),
+        EmptyQuicConnectionId(),
+        /*update_connection_id=*/true);
+    ASSERT_FALSE(connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                  NOT_HANDSHAKE));
+  }
+  ASSERT_TRUE(
+      connection_.ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
+}
+
+// Regression test for b/182571515
+TEST_P(QuicConnectionTest, LostDataThenGetAcknowledged) {
+  set_perspective(Perspective::IS_SERVER);
+  if (!connection_.validate_client_address()) {
+    return;
+  }
+
+  QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+  if (version().SupportsAntiAmplificationLimit()) {
+    QuicConnectionPeer::SetAddressValidated(&connection_);
+  }
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  // Discard INITIAL key.
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
+
+  QuicPacketNumber last_packet;
+  // Send packets 1 to 4.
+  SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 1
+  SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 2
+  SendStreamDataToPeer(3, "foo", 6, NO_FIN, &last_packet);  // Packet 3
+  SendStreamDataToPeer(3, "foo", 9, NO_FIN, &last_packet);  // Packet 4
+
+  // Process a PING packet to set peer address.
+  ProcessFramePacket(QuicFrame(QuicPingFrame()));
+
+  // Process a packet containing a STREAM_FRAME and an ACK with changed peer
+  // address.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1_));
+  QuicAckFrame ack = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)}});
+  frames.push_back(QuicFrame(&ack));
+
+  EXPECT_CALL(visitor_, OnConnectionMigration(_)).Times(1);
+
+  // Invoke OnCanWrite.
+  EXPECT_CALL(visitor_, OnStreamFrame(_))
+      .WillOnce(
+          InvokeWithoutArgs(&notifier_, &SimpleSessionNotifier::OnCanWrite));
+  QuicIpAddress ip_address;
+  ASSERT_TRUE(ip_address.FromString("127.0.52.223"));
+  EXPECT_QUIC_BUG(ProcessFramesPacketWithAddresses(
+                      frames, kSelfAddress, QuicSocketAddress(ip_address, 1000),
+                      ENCRYPTION_FORWARD_SECURE),
+                  "Try to write mid packet processing");
+  EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+  // Verify stream frame will not be retransmitted.
+  EXPECT_TRUE(writer_->stream_frames().empty());
+}
+
+TEST_P(QuicConnectionTest, PtoSendStreamData) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  // Send HANDSHAKE packets.
+  EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // Send half RTT packet with congestion control blocked.
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(false));
+  connection_.SendStreamDataWithString(2, std::string(1500, 'a'), 0, NO_FIN);
+
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify INITIAL and HANDSHAKE get retransmitted.
+  EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
+}
+
+TEST_P(QuicConnectionTest, SendingZeroRttPacketsDoesNotPostponePTO) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // Install 0-RTT keys.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+
+  // CHLO gets acknowledged after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // Send 0-RTT packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // PTO deadline should be unchanged.
+  EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, QueueingUndecryptablePacketsDoesntPostponePTO) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  // CHLO gets acknowledged after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // Receive an undecryptable packets.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO deadline is sooner.
+  EXPECT_GT(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
+  pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // PTO fires.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // Verify PTO deadline does not change.
+  ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(pto_deadline, connection_.GetRetransmissionAlarm()->deadline());
+}
+
+TEST_P(QuicConnectionTest, QueueUndecryptableHandshakePackets) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  connection_.RemoveDecrypter(ENCRYPTION_HANDSHAKE);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  // Receive an undecryptable handshake packet.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0xFF));
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+  // Verify this handshake packet gets queued.
+  EXPECT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+}
+
+TEST_P(QuicConnectionTest, PingNotSentAt0RTTLevelWhenInitialAvailable) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  use_tagging_decrypter();
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send CHLO.
+  connection_.SendCryptoStreamData();
+  // Send 0-RTT packet.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+
+  // CHLO gets acknowledged after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  QuicAckFrame frame1 = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
+  // Verify PTO is still armed since address validation is not finished yet.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  QuicTime pto_deadline = connection_.GetRetransmissionAlarm()->deadline();
+
+  // PTO fires.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  clock_.AdvanceTime(pto_deadline - clock_.ApproximateNow());
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify the PING gets sent in ENCRYPTION_INITIAL.
+  EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
+}
+
+TEST_P(QuicConnectionTest, AckElicitingFrames) {
+  if (!GetQuicReloadableFlag(
+          quic_remove_connection_migration_connection_option)) {
+    QuicConfig config;
+    config.SetConnectionOptionsToSend({kRVCM});
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    connection_.SetFromConfig(config);
+  }
+  if (!version().HasIetfQuicFrames() ||
+      !connection_.connection_migration_use_new_cid()) {
+    return;
+  }
+  EXPECT_CALL(visitor_, SendNewConnectionId(_)).Times(2);
+  EXPECT_CALL(visitor_, OnRstStream(_));
+  EXPECT_CALL(visitor_, OnWindowUpdateFrame(_));
+  EXPECT_CALL(visitor_, OnBlockedFrame(_));
+  EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
+  EXPECT_CALL(visitor_, OnStreamFrame(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(visitor_, OnMaxStreamsFrame(_));
+  EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_));
+  EXPECT_CALL(visitor_, OnStopSendingFrame(_));
+  EXPECT_CALL(visitor_, OnMessageReceived(""));
+  EXPECT_CALL(visitor_, OnNewTokenReceived(""));
+
+  SetClientConnectionId(TestConnectionId(12));
+  connection_.CreateConnectionIdManager();
+  QuicConnectionPeer::GetSelfIssuedConnectionIdManager(&connection_)
+      ->MaybeSendNewConnectionIds();
+  connection_.set_can_receive_ack_frequency_frame();
+
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  QuicRstStreamFrame rst_stream_frame;
+  QuicWindowUpdateFrame window_update_frame;
+  QuicPathChallengeFrame path_challenge_frame;
+  QuicNewConnectionIdFrame new_connection_id_frame;
+  QuicRetireConnectionIdFrame retire_connection_id_frame;
+  retire_connection_id_frame.sequence_number = 1u;
+  QuicStopSendingFrame stop_sending_frame;
+  QuicPathResponseFrame path_response_frame;
+  QuicMessageFrame message_frame;
+  QuicNewTokenFrame new_token_frame;
+  QuicAckFrequencyFrame ack_frequency_frame;
+  QuicBlockedFrame blocked_frame;
+  size_t packet_number = 1;
+
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
+    QuicFrameType frame_type = static_cast<QuicFrameType>(i);
+    bool skipped = false;
+    QuicFrame frame;
+    QuicFrames frames;
+    // Add some padding to fullfill the min size requirement of header
+    // protection.
+    frames.push_back(QuicFrame(QuicPaddingFrame(10)));
+    switch (frame_type) {
+      case PADDING_FRAME:
+        frame = QuicFrame(QuicPaddingFrame(10));
+        break;
+      case MTU_DISCOVERY_FRAME:
+        frame = QuicFrame(QuicMtuDiscoveryFrame());
+        break;
+      case PING_FRAME:
+        frame = QuicFrame(QuicPingFrame());
+        break;
+      case MAX_STREAMS_FRAME:
+        frame = QuicFrame(QuicMaxStreamsFrame());
+        break;
+      case STOP_WAITING_FRAME:
+        // Not supported.
+        skipped = true;
+        break;
+      case STREAMS_BLOCKED_FRAME:
+        frame = QuicFrame(QuicStreamsBlockedFrame());
+        break;
+      case STREAM_FRAME:
+        frame = QuicFrame(QuicStreamFrame());
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        frame = QuicFrame(QuicHandshakeDoneFrame());
+        break;
+      case ACK_FRAME:
+        frame = QuicFrame(&ack_frame);
+        break;
+      case RST_STREAM_FRAME:
+        frame = QuicFrame(&rst_stream_frame);
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        // Do not test connection close.
+        skipped = true;
+        break;
+      case GOAWAY_FRAME:
+        // Does not exist in IETF QUIC.
+        skipped = true;
+        break;
+      case BLOCKED_FRAME:
+        frame = QuicFrame(blocked_frame);
+        break;
+      case WINDOW_UPDATE_FRAME:
+        frame = QuicFrame(window_update_frame);
+        break;
+      case PATH_CHALLENGE_FRAME:
+        frame = QuicFrame(&path_challenge_frame);
+        break;
+      case STOP_SENDING_FRAME:
+        frame = QuicFrame(stop_sending_frame);
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        frame = QuicFrame(&new_connection_id_frame);
+        break;
+      case RETIRE_CONNECTION_ID_FRAME:
+        frame = QuicFrame(&retire_connection_id_frame);
+        break;
+      case PATH_RESPONSE_FRAME:
+        frame = QuicFrame(&path_response_frame);
+        break;
+      case MESSAGE_FRAME:
+        frame = QuicFrame(&message_frame);
+        break;
+      case CRYPTO_FRAME:
+        // CRYPTO_FRAME is ack eliciting is covered by other tests.
+        skipped = true;
+        break;
+      case NEW_TOKEN_FRAME:
+        frame = QuicFrame(&new_token_frame);
+        break;
+      case ACK_FREQUENCY_FRAME:
+        frame = QuicFrame(&ack_frequency_frame);
+        break;
+      case NUM_FRAME_TYPES:
+        skipped = true;
+        break;
+    }
+    if (skipped) {
+      continue;
+    }
+    ASSERT_EQ(frame_type, frame.type);
+    frames.push_back(frame);
+    EXPECT_FALSE(connection_.HasPendingAcks());
+    // Process frame.
+    ProcessFramesPacketAtLevel(packet_number++, frames,
+                               ENCRYPTION_FORWARD_SECURE);
+    if (QuicUtils::IsAckElicitingFrame(frame_type)) {
+      ASSERT_TRUE(connection_.HasPendingAcks()) << frame;
+      // Flush ACK.
+      clock_.AdvanceTime(DefaultDelayedAckTime());
+      connection_.GetAckAlarm()->Fire();
+    }
+    EXPECT_FALSE(connection_.HasPendingAcks());
+    ASSERT_TRUE(connection_.connected());
+  }
+}
+
+TEST_P(QuicConnectionTest, ReceivedChloAndAck) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  QuicFrames frames;
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(MakeCryptoFrame());
+  frames.push_back(QuicFrame(&ack_frame));
+
+  EXPECT_CALL(visitor_, OnCryptoFrame(_))
+      .WillOnce(IgnoreResult(InvokeWithoutArgs(
+          &connection_, &TestConnection::SendCryptoStreamData)));
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  ProcessFramesPacketWithAddresses(frames, kSelfAddress, kPeerAddress,
+                                   ENCRYPTION_INITIAL);
+}
+
+// Regression test for b/201643321.
+TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+  // Received ENCRYPTION_ZERO_RTT 1.
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    // Send half RTT data to exhaust amplification credit.
+    connection_.SendStreamDataWithString(0, std::string(100 * 1024, 'a'), 0,
+                                         NO_FIN);
+  }
+  // Received INITIAL 2.
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.HasPendingAcks());
+  // Verify ACK delay is 1ms.
+  EXPECT_EQ(clock_.Now() + kAlarmGranularity,
+            connection_.GetAckAlarm()->deadline());
+  // ACK is not throttled by amplification limit, and SHLO is bundled. Also
+  // HANDSHAKE + 1RTT packets get coalesced.
+  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+  } else {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+  }
+  // ACK alarm fires.
+  clock_.AdvanceTime(kAlarmGranularity);
+  connection_.GetAckAlarm()->Fire();
+  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    // Verify 1-RTT packet is coalesced.
+    EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
+  } else {
+    // Verify HANDSHAKE packet is coalesced with INITIAL ACK + SHLO.
+    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+  }
+  // Only the first packet in the coalesced packet has been processed,
+  // verify SHLO is bundled with INITIAL ACK.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  // Process the coalesced HANDSHAKE packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(0u, writer_->ack_frames().size());
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    // Process the coalesced 1-RTT packet.
+    ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+    packet = writer_->coalesced_packet()->Clone();
+    writer_->framer()->ProcessPacket(*packet);
+    EXPECT_EQ(0u, writer_->crypto_frames().size());
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+  } else {
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+  }
+
+  // Received INITIAL 3.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  ProcessCryptoPacketAtLevel(3, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+}
+
+// Regression test for b/216133388.
+TEST_P(QuicConnectionTest, FailedToConsumeCryptoData) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+  // Received ENCRYPTION_ZERO_RTT 1.
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send 1-RTT 3.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(40, 'a'), 0, NO_FIN);
+  }
+  // Received HANDSHAKE Ping, hence discard INITIAL keys.
+  peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                            std::make_unique<TaggingEncrypter>(0x03));
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.NeuterUnencryptedPackets();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_HANDSHAKE);
+  clock_.AdvanceTime(kAlarmGranularity);
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Sending this 1-RTT data would leave the coalescer only have space to
+    // accommodate the HANDSHAKE ACK. The crypto data cannot be bundled with the
+    // ACK.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(1395, 'a'), 40, NO_FIN);
+  }
+  // Verify retransmission alarm is armed.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  const QuicTime retransmission_time =
+      connection_.GetRetransmissionAlarm()->deadline();
+  clock_.AdvanceTime(retransmission_time - clock_.Now());
+  connection_.GetRetransmissionAlarm()->Fire();
+
+  if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
+    // Verify the retransmission is a coalesced packet with HANDSHAKE 2 and
+    // 1-RTT 3.
+    EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
+    // Only the first packet in the coalesced packet has been processed.
+    EXPECT_EQ(1u, writer_->crypto_frames().size());
+    // Process the coalesced 1-RTT packet.
+    ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+    auto packet = writer_->coalesced_packet()->Clone();
+    writer_->framer()->ProcessPacket(*packet);
+    EXPECT_EQ(1u, writer_->stream_frames().size());
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+  } else {
+    // Although packet 2 has not been retransmitted, it has been marked PTOed
+    // and a HANDHSAKE PING gets retransmitted.
+    EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
+    EXPECT_EQ(1u, writer_->ping_frames().size());
+    EXPECT_TRUE(writer_->stream_frames().empty());
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+  }
+  // Verify retransmission alarm is still armed.
+  ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest,
+       RTTSampleDoesNotIncludeQueuingDelayWithPostponedAckProcessing) {
+  // An endpoint might postpone the processing of ACK when the corresponding
+  // decryption key is not available. This test makes sure the RTT sample does
+  // not include the queuing delay.
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+
+  // 30ms RTT.
+  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(30);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(kTestRTT, QuicTime::Delta::Zero(), QuicTime::Zero());
+  use_tagging_decrypter();
+
+  // Send 0-RTT packet.
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SendStreamDataWithString(0, std::string(10, 'a'), 0, FIN);
+
+  // Receives 1-RTT ACK for 0-RTT packet after RTT + ack_delay.
+  clock_.AdvanceTime(
+      kTestRTT + QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  // Peer reported ACK delay.
+  ack_frame.ack_delay_time =
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(&ack_frame));
+  QuicPacketHeader header =
+      ConstructPacketHeader(30, ENCRYPTION_FORWARD_SECURE);
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(30), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+  // Assume 1-RTT decrypter is available after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  // Verify RTT sample does not include queueing delay.
+  EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
+}
+
+// Regression test for b/112480134.
+TEST_P(QuicConnectionTest, NoExtraPaddingInReserializedInitial) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration() ||
+      !connection_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+
+  set_perspective(Perspective::IS_SERVER);
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+
+  uint64_t debug_visitor_sent_count = 0;
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
+      .WillRepeatedly([&]() { debug_visitor_sent_count++; });
+
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+
+  // Received ENCRYPTION_ZERO_RTT 2.
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send 1-RTT 3.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(400, 'b'), 0, NO_FIN);
+  }
+
+  // Arrange the stream data to be sent in response to ENCRYPTION_INITIAL 3.
+  const std::string data4(1000, '4');  // Data to send in stream id 4
+  const std::string data8(3000, '8');  // Data to send in stream id 8
+  EXPECT_CALL(visitor_, OnCanWrite()).WillOnce([&]() {
+    connection_.producer()->SaveStreamData(4, data4);
+    connection_.producer()->SaveStreamData(8, data8);
+
+    notifier_.WriteOrBufferData(4, data4.size(), FIN_AND_PADDING);
+
+    // This should trigger FlushCoalescedPacket.
+    notifier_.WriteOrBufferData(8, data8.size(), FIN);
+  });
+
+  QuicByteCount pending_padding_after_serialize_2nd_1rtt_packet = 0;
+  QuicPacketCount num_1rtt_packets_serialized = 0;
+  EXPECT_CALL(connection_, OnSerializedPacket(_))
+      .WillRepeatedly([&](SerializedPacket packet) {
+        if (packet.encryption_level == ENCRYPTION_FORWARD_SECURE) {
+          num_1rtt_packets_serialized++;
+          if (num_1rtt_packets_serialized == 2) {
+            pending_padding_after_serialize_2nd_1rtt_packet =
+                connection_.packet_creator().pending_padding_bytes();
+          }
+        }
+        connection_.QuicConnection::OnSerializedPacket(std::move(packet));
+      });
+
+  // Server receives INITIAL 3, this will serialzie FS 7 (stream 4, stream 8),
+  // which will trigger a flush of a coalesced packet consists of INITIAL 4,
+  // HS 5 and FS 6 (stream 4).
+  if (GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
+    // Expect no QUIC_BUG.
+    ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
+    EXPECT_EQ(
+        debug_visitor_sent_count,
+        connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
+  } else {
+    // Expect QUIC_BUG due to extra padding.
+    EXPECT_QUIC_BUG(
+        { ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL); },
+        "Reserialize initial packet in coalescer has unexpected size");
+    EXPECT_EQ(
+        debug_visitor_sent_count + 1,
+        connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
+  }
+
+  // The error only happens if after serializing the second 1RTT packet(pkt #7),
+  // the pending padding bytes is non zero.
+  EXPECT_GT(pending_padding_after_serialize_2nd_1rtt_packet, 0u);
+  EXPECT_TRUE(connection_.connected());
+}
+
+TEST_P(QuicConnectionTest, ReportedAckDelayIncludesQueuingDelay) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  QuicConfig config;
+  config.set_max_undecryptable_packets(3);
+  connection_.SetFromConfig(config);
+
+  // Receive 1-RTT ack-eliciting packet while keys are not available.
+  connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+  peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<TaggingEncrypter>(0x01));
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicPingFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  QuicPacketHeader header =
+      ConstructPacketHeader(30, ENCRYPTION_FORWARD_SECURE);
+  std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
+
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = peer_framer_.EncryptPayload(
+      ENCRYPTION_FORWARD_SECURE, QuicPacketNumber(30), *packet, buffer,
+      kMaxOutgoingPacketSize);
+  EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  const QuicTime packet_receipt_time = clock_.Now();
+  connection_.ProcessUdpPacket(
+      kSelfAddress, kPeerAddress,
+      QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
+  if (connection_.GetSendAlarm()->IsSet()) {
+    connection_.GetSendAlarm()->Fire();
+  }
+  ASSERT_EQ(1u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+  // 1-RTT keys become available after 10ms.
+  const QuicTime::Delta kQueuingDelay = QuicTime::Delta::FromMilliseconds(10);
+  clock_.AdvanceTime(kQueuingDelay);
+  EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+               std::make_unique<StrictTaggingDecrypter>(0x01));
+  ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+
+  connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+  ASSERT_TRUE(connection_.HasPendingAcks());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    EXPECT_EQ(packet_receipt_time + DefaultDelayedAckTime(),
+              connection_.GetAckAlarm()->deadline());
+    clock_.AdvanceTime(packet_receipt_time + DefaultDelayedAckTime() -
+                       clock_.Now());
+  } else {
+    EXPECT_EQ(clock_.Now() + DefaultDelayedAckTime(),
+              connection_.GetAckAlarm()->deadline());
+    clock_.AdvanceTime(DefaultDelayedAckTime());
+  }
+  // Fire ACK alarm.
+  connection_.GetAckAlarm()->Fire();
+  ASSERT_EQ(1u, writer_->ack_frames().size());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify ACK delay time does not include queuing delay.
+    EXPECT_EQ(DefaultDelayedAckTime(), writer_->ack_frames()[0].ack_delay_time);
+  } else {
+    // Verify ACK delay time = queuing delay + ack delay
+    EXPECT_EQ(DefaultDelayedAckTime() + kQueuingDelay,
+              writer_->ack_frames()[0].ack_delay_time);
+  }
+}
+
+TEST_P(QuicConnectionTest, CoalesceOneRTTPacketWithInitialAndHandshakePackets) {
+  if (!version().HasIetfQuicFrames()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                            std::make_unique<TaggingEncrypter>(0x02));
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  SetDecrypter(ENCRYPTION_ZERO_RTT,
+               std::make_unique<StrictTaggingDecrypter>(0x02));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+
+  // Received ENCRYPTION_ZERO_RTT 2.
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send 1-RTT data.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(2000, 'b'), 0, FIN);
+  }
+  // Verify coalesced packet [INITIAL 1 + HANDSHAKE 2 + part of 1-RTT data] +
+  // rest of 1-RTT data get sent.
+  EXPECT_EQ(2u, writer_->packets_write_attempts());
+
+  // Received ENCRYPTION_INITIAL 3.
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
+
+  // Verify a coalesced packet gets sent.
+  EXPECT_EQ(3u, writer_->packets_write_attempts());
+
+  // Only the first INITIAL packet has been processed yet.
+  EXPECT_EQ(1u, writer_->ack_frames().size());
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+
+  // Process HANDSHAKE packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  auto packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->crypto_frames().size());
+  if (!GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
+    ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+    return;
+  }
+  // Process 1-RTT packet.
+  ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+  packet = writer_->coalesced_packet()->Clone();
+  writer_->framer()->ProcessPacket(*packet);
+  EXPECT_EQ(1u, writer_->stream_frames().size());
+}
+
+// Regression test for b/180103273
+TEST_P(QuicConnectionTest, SendMultipleConnectionCloses) {
+  if (!version().HasIetfQuicFrames() ||
+      !GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  // Finish handshake.
+  QuicConnectionPeer::SetAddressValidated(&connection_);
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  notifier_.NeuterUnencryptedData();
+  connection_.NeuterUnencryptedPackets();
+  connection_.OnHandshakeComplete();
+  connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+  connection_.RemoveEncrypter(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(visitor_, GetHandshakeState())
+      .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+
+  SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
+  ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
+  // Verify BeforeConnectionCloseSent gets called twice while OnConnectionClosed
+  // is called once.
+  EXPECT_CALL(visitor_, BeforeConnectionCloseSent()).Times(2);
+  EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+  // Send connection close w/o closing connection.
+  QuicConnectionPeer::SendConnectionClosePacket(
+      &connection_, INTERNAL_ERROR, QUIC_INTERNAL_ERROR, "internal error");
+  // Fire blackhole detection alarm.
+  EXPECT_QUIC_BUG(connection_.GetBlackholeDetectorAlarm()->Fire(),
+                  "Already sent connection close");
+}
+
+// Regression test for b/157895910.
+TEST_P(QuicConnectionTest, EarliestSentTimeNotInitializedWhenPtoFires) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+  use_tagging_decrypter();
+
+  // Received INITIAL 1.
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x03));
+  SetDecrypter(ENCRYPTION_HANDSHAKE,
+               std::make_unique<StrictTaggingDecrypter>(0x03));
+  connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<TaggingEncrypter>(0x04));
+  {
+    QuicConnection::ScopedPacketFlusher flusher(&connection_);
+    // Send INITIAL 1.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+    connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+    // Send HANDSHAKE 2.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    connection_.SendCryptoDataWithString(std::string(200, 'a'), 0,
+                                         ENCRYPTION_HANDSHAKE);
+    // Send half RTT data.
+    connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    connection_.SendStreamDataWithString(0, std::string(2000, 'b'), 0, FIN);
+  }
+
+  // Received ACKs for both INITIAL and HANDSHAKE packets.
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  QuicFrames frames1;
+  QuicAckFrame ack_frame1 = InitAckFrame(1);
+  frames1.push_back(QuicFrame(&ack_frame1));
+
+  QuicFrames frames2;
+  QuicAckFrame ack_frame2 =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+  frames2.push_back(QuicFrame(&ack_frame2));
+  ProcessCoalescedPacket(
+      {{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
+  // Verify PTO is not armed given the only outstanding data is half RTT data.
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_constants.cc b/quiche/quic/core/quic_constants.cc
new file mode 100644
index 0000000..b9594fa
--- /dev/null
+++ b/quiche/quic/core/quic_constants.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_constants.h"
+
+namespace quic {
+
+const char* const kFinalOffsetHeaderKey = ":final-offset";
+
+const char* const kEPIDGoogleFrontEnd = "GFE";
+const char* const kEPIDGoogleFrontEnd0 = "GFE0";
+
+QuicPacketNumber MaxRandomInitialPacketNumber() {
+  static const QuicPacketNumber kMaxRandomInitialPacketNumber =
+      QuicPacketNumber(0x7fffffff);
+  return kMaxRandomInitialPacketNumber;
+}
+
+QuicPacketNumber FirstSendingPacketNumber() {
+  static const QuicPacketNumber kFirstSendingPacketNumber = QuicPacketNumber(1);
+  return kFirstSendingPacketNumber;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_constants.h b/quiche/quic/core/quic_constants.h
new file mode 100644
index 0000000..189179f
--- /dev/null
+++ b/quiche/quic/core/quic_constants.h
@@ -0,0 +1,316 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
+#define QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <limits>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+// Definitions of constant values used throughout the QUIC code.
+
+namespace quic {
+
+// Simple time constants.
+const uint64_t kNumSecondsPerMinute = 60;
+const uint64_t kNumSecondsPerHour = kNumSecondsPerMinute * 60;
+const uint64_t kNumSecondsPerWeek = kNumSecondsPerHour * 24 * 7;
+const uint64_t kNumMillisPerSecond = 1000;
+const uint64_t kNumMicrosPerMilli = 1000;
+const uint64_t kNumMicrosPerSecond = kNumMicrosPerMilli * kNumMillisPerSecond;
+
+// Default number of connections for N-connection emulation.
+const uint32_t kDefaultNumConnections = 2;
+// Default initial maximum size in bytes of a QUIC packet.
+const QuicByteCount kDefaultMaxPacketSize = 1250;
+// Default initial maximum size in bytes of a QUIC packet for servers.
+const QuicByteCount kDefaultServerMaxPacketSize = 1000;
+// Maximum transmission unit on Ethernet.
+const QuicByteCount kEthernetMTU = 1500;
+// The maximum packet size of any QUIC packet over IPv6, based on ethernet's max
+// size, minus the IP and UDP headers. IPv6 has a 40 byte header, UDP adds an
+// additional 8 bytes.  This is a total overhead of 48 bytes.  Ethernet's
+// max packet size is 1500 bytes,  1500 - 48 = 1452.
+const QuicByteCount kMaxV6PacketSize = 1452;
+// The maximum packet size of any QUIC packet over IPv4.
+// 1500(Ethernet) - 20(IPv4 header) - 8(UDP header) = 1472.
+const QuicByteCount kMaxV4PacketSize = 1472;
+// The maximum incoming packet size allowed.
+const QuicByteCount kMaxIncomingPacketSize = kMaxV4PacketSize;
+// The maximum outgoing packet size allowed.
+const QuicByteCount kMaxOutgoingPacketSize = kMaxV6PacketSize;
+// ETH_MAX_MTU - MAX(sizeof(iphdr), sizeof(ip6_hdr)) - sizeof(udphdr).
+const QuicByteCount kMaxGsoPacketSize = 65535 - 40 - 8;
+// The maximal IETF DATAGRAM frame size we'll accept. Choosing 2^16 ensures
+// that it is greater than the biggest frame we could ever fit in a QUIC packet.
+const QuicByteCount kMaxAcceptedDatagramFrameSize = 65536;
+// Default value of the max_packet_size transport parameter if it is not
+// transmitted.
+const QuicByteCount kDefaultMaxPacketSizeTransportParam = 65527;
+// Default maximum packet size used in the Linux TCP implementation.
+// Used in QUIC for congestion window computations in bytes.
+const QuicByteCount kDefaultTCPMSS = 1460;
+const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
+// The minimum size of a packet which can elicit a version negotiation packet,
+// as per section 8.1 of the QUIC spec.
+const QuicByteCount kMinPacketSizeForVersionNegotiation = 1200;
+
+// We match SPDY's use of 32 (since we'd compete with SPDY).
+const QuicPacketCount kInitialCongestionWindow = 32;
+
+// Do not allow initial congestion window to be greater than 200 packets.
+const QuicPacketCount kMaxInitialCongestionWindow = 200;
+
+// Do not allow initial congestion window to be smaller than 10 packets.
+const QuicPacketCount kMinInitialCongestionWindow = 10;
+
+// Minimum size of initial flow control window, for both stream and session.
+// This is only enforced when version.AllowsLowFlowControlLimits() is false.
+const QuicByteCount kMinimumFlowControlSendWindow = 16 * 1024;  // 16 KB
+// Default size of initial flow control window, for both stream and session.
+const QuicByteCount kDefaultFlowControlSendWindow = 16 * 1024;  // 16 KB
+
+// Maximum flow control receive window limits for connection and stream.
+const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024;   // 16 MB
+const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024;  // 24 MB
+
+// Minimum size of the CWND, in packets, when doing bandwidth resumption.
+const QuicPacketCount kMinCongestionWindowForBandwidthResumption = 10;
+
+// Default size of the socket receive buffer in bytes.
+const QuicByteCount kDefaultSocketReceiveBuffer = 1024 * 1024;
+
+// The lower bound of an untrusted initial rtt value.
+const uint32_t kMinUntrustedInitialRoundTripTimeUs = 10 * kNumMicrosPerMilli;
+
+// The lower bound of a trusted initial rtt value.
+const uint32_t kMinTrustedInitialRoundTripTimeUs = 5 * kNumMicrosPerMilli;
+
+// Don't allow a client to suggest an RTT longer than 1 second.
+const uint32_t kMaxInitialRoundTripTimeUs = kNumMicrosPerSecond;
+
+// Maximum number of open streams per connection.
+const size_t kDefaultMaxStreamsPerConnection = 100;
+
+// Number of bytes reserved for public flags in the packet header.
+const size_t kPublicFlagsSize = 1;
+// Number of bytes reserved for version number in the packet header.
+const size_t kQuicVersionSize = 4;
+
+// Minimum number of active connection IDs that an end point can maintain.
+const uint32_t kMinNumOfActiveConnectionIds = 2;
+
+// Length of the retry integrity tag in bytes.
+// https://tools.ietf.org/html/draft-ietf-quic-transport-25#section-17.2.5
+const size_t kRetryIntegrityTagLength = 16;
+
+// By default, UnackedPacketsMap allocates buffer of 64 after the first packet
+// is added.
+const int kDefaultUnackedPacketsInitialCapacity = 64;
+
+// Signifies that the QuicPacket will contain version of the protocol.
+const bool kIncludeVersion = true;
+// Signifies that the QuicPacket will include a diversification nonce.
+const bool kIncludeDiversificationNonce = true;
+
+// Header key used to identify final offset on data stream when sending HTTP/2
+// trailing headers over QUIC.
+QUIC_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
+
+// Default maximum delayed ack time, in ms.
+// Uses a 25ms delayed ack timer. Helps with better signaling
+// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
+const int64_t kDefaultDelayedAckTimeMs = 25;
+
+// Default minimum delayed ack time, in ms (used only for sender control of ack
+// frequency).
+const uint32_t kDefaultMinAckDelayTimeMs = 5;
+
+// Default shift of the ACK delay in the IETF QUIC ACK frame.
+const uint32_t kDefaultAckDelayExponent = 3;
+
+// Minimum tail loss probe time in ms.
+static const int64_t kMinTailLossProbeTimeoutMs = 10;
+
+// The timeout before the handshake succeeds.
+const int64_t kInitialIdleTimeoutSecs = 5;
+// The maximum idle timeout that can be negotiated.
+const int64_t kMaximumIdleTimeoutSecs = 60 * 10;  // 10 minutes.
+// The default timeout for a connection until the crypto handshake succeeds.
+const int64_t kMaxTimeForCryptoHandshakeSecs = 10;  // 10 secs.
+
+// Default limit on the number of undecryptable packets the connection buffers
+// before the CHLO/SHLO arrive.
+const size_t kDefaultMaxUndecryptablePackets = 10;
+
+// Default ping timeout.
+const int64_t kPingTimeoutSecs = 15;  // 15 secs.
+
+// Minimum number of RTTs between Server Config Updates (SCUP) sent to client.
+const int kMinIntervalBetweenServerConfigUpdatesRTTs = 10;
+
+// Minimum time between Server Config Updates (SCUP) sent to client.
+const int kMinIntervalBetweenServerConfigUpdatesMs = 1000;
+
+// Minimum number of packets between Server Config Updates (SCUP).
+const int kMinPacketsBetweenServerConfigUpdates = 100;
+
+// The number of open streams that a server will accept is set to be slightly
+// larger than the negotiated limit. Immediately closing the connection if the
+// client opens slightly too many streams is not ideal: the client may have sent
+// a FIN that was lost, and simultaneously opened a new stream. The number of
+// streams a server accepts is a fixed increment over the negotiated limit, or a
+// percentage increase, whichever is larger.
+const float kMaxStreamsMultiplier = 1.1f;
+const int kMaxStreamsMinimumIncrement = 10;
+
+// Available streams are ones with IDs less than the highest stream that has
+// been opened which have neither been opened or reset. The limit on the number
+// of available streams is 10 times the limit on the number of open streams.
+const int kMaxAvailableStreamsMultiplier = 10;
+
+// Track the number of promises that are not yet claimed by a
+// corresponding get.  This must be smaller than
+// kMaxAvailableStreamsMultiplier, because RST on a promised stream my
+// create available streams entries.
+const int kMaxPromisedStreamsMultiplier = kMaxAvailableStreamsMultiplier - 1;
+
+// TCP RFC calls for 1 second RTO however Linux differs from this default and
+// define the minimum RTO to 200ms, we will use the same until we have data to
+// support a higher or lower value.
+static const int64_t kMinRetransmissionTimeMs = 200;
+// The delayed ack time must not be greater than half the min RTO.
+static_assert(kDefaultDelayedAckTimeMs <= kMinRetransmissionTimeMs / 2,
+              "Delayed ack time must be less than or equal half the MinRTO");
+
+// We define an unsigned 16-bit floating point value, inspired by IEEE floats
+// (http://en.wikipedia.org/wiki/Half_precision_floating-point_format),
+// with 5-bit exponent (bias 1), 11-bit mantissa (effective 12 with hidden
+// bit) and denormals, but without signs, transfinites or fractions. Wire format
+// 16 bits (little-endian byte order) are split into exponent (high 5) and
+// mantissa (low 11) and decoded as:
+//   uint64_t value;
+//   if (exponent == 0) value = mantissa;
+//   else value = (mantissa | 1 << 11) << (exponent - 1)
+const int kUFloat16ExponentBits = 5;
+const int kUFloat16MaxExponent = (1 << kUFloat16ExponentBits) - 2;     // 30
+const int kUFloat16MantissaBits = 16 - kUFloat16ExponentBits;          // 11
+const int kUFloat16MantissaEffectiveBits = kUFloat16MantissaBits + 1;  // 12
+const uint64_t kUFloat16MaxValue =  // 0x3FFC0000000
+    ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1)
+    << kUFloat16MaxExponent;
+
+// kDiversificationNonceSize is the size, in bytes, of the nonce that a server
+// may set in the packet header to ensure that its INITIAL keys are not
+// duplicated.
+const size_t kDiversificationNonceSize = 32;
+
+// The largest gap in packets we'll accept without closing the connection.
+// This will likely have to be tuned.
+const QuicPacketCount kMaxPacketGap = 5000;
+
+// The max number of sequence number intervals that
+// QuicPeerIssuedConnetionIdManager can maintain.
+const size_t kMaxNumConnectionIdSequenceNumberIntervals = 20;
+
+// The maximum number of random padding bytes to add.
+const QuicByteCount kMaxNumRandomPaddingBytes = 256;
+
+// The size of stream send buffer data slice size in bytes. A data slice is
+// piece of stream data stored in contiguous memory, and a stream frame can
+// contain data from multiple data slices.
+const QuicByteCount kQuicStreamSendBufferSliceSize = 4 * 1024;
+
+// For When using Random Initial Packet Numbers, they can start
+// anyplace in the range 1...((2^31)-1) or 0x7fffffff
+QUIC_EXPORT_PRIVATE QuicPacketNumber MaxRandomInitialPacketNumber();
+
+// Used to represent an invalid or no control frame id.
+const QuicControlFrameId kInvalidControlFrameId = 0;
+
+// The max length a stream can have.
+const QuicByteCount kMaxStreamLength = (UINT64_C(1) << 62) - 1;
+
+// The max value that can be encoded using IETF Var Ints.
+const uint64_t kMaxIetfVarInt = UINT64_C(0x3fffffffffffffff);
+
+// The maximum stream id value that is supported - (2^32)-1
+const QuicStreamId kMaxQuicStreamId = 0xffffffff;
+
+// The maximum value that can be stored in a 32-bit QuicStreamCount.
+const QuicStreamCount kMaxQuicStreamCount = 0xffffffff;
+
+// Number of bytes reserved for packet header type.
+const size_t kPacketHeaderTypeSize = 1;
+
+// Number of bytes reserved for connection ID length.
+const size_t kConnectionIdLengthSize = 1;
+
+// Minimum length of random bytes in IETF stateless reset packet.
+const size_t kMinRandomBytesLengthInStatelessReset = 24;
+
+// Maximum length allowed for the token in a NEW_TOKEN frame.
+const size_t kMaxNewTokenTokenLength = 0xffff;
+
+// The prefix used by a source address token in a NEW_TOKEN frame.
+const uint8_t kAddressTokenPrefix = 0;
+
+// Default initial rtt used before any samples are received.
+const int kInitialRttMs = 100;
+
+// Default threshold of packet reordering before a packet is declared lost.
+static const QuicPacketCount kDefaultPacketReorderingThreshold = 3;
+
+// Default fraction (1/4) of an RTT the algorithm waits before determining a
+// packet is lost due to early retransmission by time based loss detection.
+static const int kDefaultLossDelayShift = 2;
+
+// Default fraction (1/8) of an RTT when doing IETF loss detection.
+static const int kDefaultIetfLossDelayShift = 3;
+
+// Maximum number of retransmittable packets received before sending an ack.
+const QuicPacketCount kDefaultRetransmittablePacketsBeforeAck = 2;
+// Wait for up to 10 retransmittable packets before sending an ack.
+const QuicPacketCount kMaxRetransmittablePacketsBeforeAck = 10;
+// Minimum number of packets received before ack decimation is enabled.
+// This intends to avoid the beginning of slow start, when CWNDs may be
+// rapidly increasing.
+const QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
+// One quarter RTT delay when doing ack decimation.
+const float kAckDecimationDelay = 0.25;
+
+// The default alarm granularity assumed by QUIC code.
+const QuicTime::Delta kAlarmGranularity = QuicTime::Delta::FromMilliseconds(1);
+
+// Maximum number of unretired connection IDs a connection can have.
+const size_t kMaxNumConnectonIdsInUse = 10u;
+
+// Packet number of first sending packet of a connection. Please note, this
+// cannot be used as first received packet because peer can choose its starting
+// packet number.
+QUIC_EXPORT_PRIVATE QuicPacketNumber FirstSendingPacketNumber();
+
+// Used by clients to tell if a public reset is sent from a Google frontend.
+QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd;
+QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd0;
+
+// HTTP/3 Datagrams.
+enum : QuicDatagramContextId {
+  kFirstDatagramContextIdClient = 0,
+  kFirstDatagramContextIdServer = 1,
+  kDatagramContextIdIncrement = 2,
+};
+
+enum : uint64_t {
+  kHttpDatagramStreamIdDivisor = 4,
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/quiche/quic/core/quic_control_frame_manager.cc b/quiche/quic/core/quic_control_frame_manager.cc
new file mode 100644
index 0000000..64e5eec
--- /dev/null
+++ b/quiche/quic/core/quic_control_frame_manager.cc
@@ -0,0 +1,363 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_control_frame_manager.h"
+
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+
+// The maximum number of buffered control frames which are waiting to be ACKed
+// or sent for the first time.
+const size_t kMaxNumControlFrames = 1000;
+
+}  // namespace
+
+QuicControlFrameManager::QuicControlFrameManager(QuicSession* session)
+    : last_control_frame_id_(kInvalidControlFrameId),
+      least_unacked_(1),
+      least_unsent_(1),
+      delegate_(session) {}
+
+QuicControlFrameManager::~QuicControlFrameManager() {
+  while (!control_frames_.empty()) {
+    DeleteFrame(&control_frames_.front());
+    control_frames_.pop_front();
+  }
+}
+
+void QuicControlFrameManager::WriteOrBufferQuicFrame(QuicFrame frame) {
+  const bool had_buffered_frames = HasBufferedFrames();
+  control_frames_.emplace_back(frame);
+  if (control_frames_.size() > kMaxNumControlFrames) {
+    delegate_->OnControlFrameManagerError(
+        QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES,
+        absl::StrCat("More than ", kMaxNumControlFrames,
+                     "buffered control frames, least_unacked: ", least_unacked_,
+                     ", least_unsent_: ", least_unsent_));
+    return;
+  }
+  if (had_buffered_frames) {
+    return;
+  }
+  WriteBufferedFrames();
+}
+
+void QuicControlFrameManager::WriteOrBufferRstStream(
+    QuicStreamId id, QuicResetStreamError error,
+    QuicStreamOffset bytes_written) {
+  QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
+  WriteOrBufferQuicFrame((QuicFrame(new QuicRstStreamFrame(
+      ++last_control_frame_id_, id, error, bytes_written))));
+}
+
+void QuicControlFrameManager::WriteOrBufferGoAway(
+    QuicErrorCode error, QuicStreamId last_good_stream_id,
+    const std::string& reason) {
+  QUIC_DVLOG(1) << "Writing GOAWAY_FRAME";
+  WriteOrBufferQuicFrame(QuicFrame(new QuicGoAwayFrame(
+      ++last_control_frame_id_, error, last_good_stream_id, reason)));
+}
+
+void QuicControlFrameManager::WriteOrBufferWindowUpdate(
+    QuicStreamId id, QuicStreamOffset byte_offset) {
+  QUIC_DVLOG(1) << "Writing WINDOW_UPDATE_FRAME";
+  WriteOrBufferQuicFrame(QuicFrame(
+      QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
+}
+
+void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
+  QUIC_DVLOG(1) << "Writing BLOCKED_FRAME";
+  WriteOrBufferQuicFrame(
+      QuicFrame(QuicBlockedFrame(++last_control_frame_id_, id)));
+}
+
+void QuicControlFrameManager::WriteOrBufferStreamsBlocked(QuicStreamCount count,
+                                                          bool unidirectional) {
+  QUIC_DVLOG(1) << "Writing STREAMS_BLOCKED Frame";
+  QUIC_CODE_COUNT(quic_streams_blocked_transmits);
+  WriteOrBufferQuicFrame(QuicFrame(QuicStreamsBlockedFrame(
+      ++last_control_frame_id_, count, unidirectional)));
+}
+
+void QuicControlFrameManager::WriteOrBufferMaxStreams(QuicStreamCount count,
+                                                      bool unidirectional) {
+  QUIC_DVLOG(1) << "Writing MAX_STREAMS Frame";
+  QUIC_CODE_COUNT(quic_max_streams_transmits);
+  WriteOrBufferQuicFrame(QuicFrame(
+      QuicMaxStreamsFrame(++last_control_frame_id_, count, unidirectional)));
+}
+
+void QuicControlFrameManager::WriteOrBufferStopSending(
+    QuicResetStreamError error, QuicStreamId stream_id) {
+  QUIC_DVLOG(1) << "Writing STOP_SENDING_FRAME";
+  WriteOrBufferQuicFrame(QuicFrame(
+      QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
+}
+
+void QuicControlFrameManager::WriteOrBufferHandshakeDone() {
+  QUIC_DVLOG(1) << "Writing HANDSHAKE_DONE";
+  WriteOrBufferQuicFrame(
+      QuicFrame(QuicHandshakeDoneFrame(++last_control_frame_id_)));
+}
+
+void QuicControlFrameManager::WriteOrBufferAckFrequency(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame";
+  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
+  // Using the control_frame_id for sequence_number here leaves gaps in
+  // sequence_number.
+  WriteOrBufferQuicFrame(
+      QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
+                                          /*sequence_number=*/control_frame_id,
+                                          ack_frequency_frame.packet_tolerance,
+                                          ack_frequency_frame.max_ack_delay)));
+}
+
+void QuicControlFrameManager::WriteOrBufferNewConnectionId(
+    const QuicConnectionId& connection_id, uint64_t sequence_number,
+    uint64_t retire_prior_to,
+    const StatelessResetToken& stateless_reset_token) {
+  QUIC_DVLOG(1) << "Writing NEW_CONNECTION_ID frame";
+  WriteOrBufferQuicFrame(QuicFrame(new QuicNewConnectionIdFrame(
+      ++last_control_frame_id_, connection_id, sequence_number,
+      stateless_reset_token, retire_prior_to)));
+}
+
+void QuicControlFrameManager::WriteOrBufferRetireConnectionId(
+    uint64_t sequence_number) {
+  QUIC_DVLOG(1) << "Writing RETIRE_CONNECTION_ID frame";
+  WriteOrBufferQuicFrame(QuicFrame(new QuicRetireConnectionIdFrame(
+      ++last_control_frame_id_, sequence_number)));
+}
+
+void QuicControlFrameManager::WriteOrBufferNewToken(absl::string_view token) {
+  QUIC_DVLOG(1) << "Writing NEW_TOKEN frame";
+  WriteOrBufferQuicFrame(
+      QuicFrame(new QuicNewTokenFrame(++last_control_frame_id_, token)));
+}
+
+void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    QUIC_BUG(quic_bug_12727_1)
+        << "Send or retransmit a control frame with invalid control frame id";
+    return;
+  }
+  if (frame.type == WINDOW_UPDATE_FRAME) {
+    QuicStreamId stream_id = frame.window_update_frame.stream_id;
+    if (window_update_frames_.contains(stream_id) &&
+        id > window_update_frames_[stream_id]) {
+      // Consider the older window update of the same stream as acked.
+      OnControlFrameIdAcked(window_update_frames_[stream_id]);
+    }
+    window_update_frames_[stream_id] = id;
+  }
+  if (pending_retransmissions_.contains(id)) {
+    // This is retransmitted control frame.
+    pending_retransmissions_.erase(id);
+    return;
+  }
+  if (id > least_unsent_) {
+    QUIC_BUG(quic_bug_10517_1)
+        << "Try to send control frames out of order, id: " << id
+        << " least_unsent: " << least_unsent_;
+    delegate_->OnControlFrameManagerError(
+        QUIC_INTERNAL_ERROR, "Try to send control frames out of order");
+    return;
+  }
+  ++least_unsent_;
+}
+
+bool QuicControlFrameManager::OnControlFrameAcked(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (!OnControlFrameIdAcked(id)) {
+    return false;
+  }
+  if (frame.type == WINDOW_UPDATE_FRAME) {
+    QuicStreamId stream_id = frame.window_update_frame.stream_id;
+    if (window_update_frames_.contains(stream_id) &&
+        window_update_frames_[stream_id] == id) {
+      window_update_frames_.erase(stream_id);
+    }
+  }
+  return true;
+}
+
+void QuicControlFrameManager::OnControlFrameLost(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    // Frame does not have a valid control frame ID, ignore it.
+    return;
+  }
+  if (id >= least_unsent_) {
+    QUIC_BUG(quic_bug_10517_2) << "Try to mark unsent control frame as lost";
+    delegate_->OnControlFrameManagerError(
+        QUIC_INTERNAL_ERROR, "Try to mark unsent control frame as lost");
+    return;
+  }
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    // This frame has already been acked.
+    return;
+  }
+  if (!pending_retransmissions_.contains(id)) {
+    pending_retransmissions_[id] = true;
+    QUIC_BUG_IF(quic_bug_12727_2,
+                pending_retransmissions_.size() > control_frames_.size())
+        << "least_unacked_: " << least_unacked_
+        << ", least_unsent_: " << least_unsent_;
+  }
+}
+
+bool QuicControlFrameManager::IsControlFrameOutstanding(
+    const QuicFrame& frame) const {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    // Frame without a control frame ID should not be retransmitted.
+    return false;
+  }
+  // Consider this frame is outstanding if it does not get acked.
+  return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
+         GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
+             kInvalidControlFrameId;
+}
+
+bool QuicControlFrameManager::HasPendingRetransmission() const {
+  return !pending_retransmissions_.empty();
+}
+
+bool QuicControlFrameManager::WillingToWrite() const {
+  return HasPendingRetransmission() || HasBufferedFrames();
+}
+
+QuicFrame QuicControlFrameManager::NextPendingRetransmission() const {
+  QUIC_BUG_IF(quic_bug_12727_3, pending_retransmissions_.empty())
+      << "Unexpected call to NextPendingRetransmission() with empty pending "
+      << "retransmission list.";
+  QuicControlFrameId id = pending_retransmissions_.begin()->first;
+  return control_frames_.at(id - least_unacked_);
+}
+
+void QuicControlFrameManager::OnCanWrite() {
+  if (HasPendingRetransmission()) {
+    // Exit early to allow streams to write pending retransmissions if any.
+    WritePendingRetransmission();
+    return;
+  }
+  WriteBufferedFrames();
+}
+
+bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame,
+                                                     TransmissionType type) {
+  QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
+                type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    // Frame does not have a valid control frame ID, ignore it. Returns true
+    // to allow writing following frames.
+    return true;
+  }
+  if (id >= least_unsent_) {
+    QUIC_BUG(quic_bug_10517_3) << "Try to retransmit unsent control frame";
+    delegate_->OnControlFrameManagerError(
+        QUIC_INTERNAL_ERROR, "Try to retransmit unsent control frame");
+    return false;
+  }
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    // This frame has already been acked.
+    return true;
+  }
+  QuicFrame copy = CopyRetransmittableControlFrame(frame);
+  QUIC_DVLOG(1) << "control frame manager is forced to retransmit frame: "
+                << frame;
+  if (delegate_->WriteControlFrame(copy, type)) {
+    return true;
+  }
+  DeleteFrame(&copy);
+  return false;
+}
+
+void QuicControlFrameManager::WriteBufferedFrames() {
+  while (HasBufferedFrames()) {
+    QuicFrame frame_to_send =
+        control_frames_.at(least_unsent_ - least_unacked_);
+    QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
+    if (!delegate_->WriteControlFrame(copy, NOT_RETRANSMISSION)) {
+      // Connection is write blocked.
+      DeleteFrame(&copy);
+      break;
+    }
+    OnControlFrameSent(frame_to_send);
+  }
+}
+
+void QuicControlFrameManager::WritePendingRetransmission() {
+  while (HasPendingRetransmission()) {
+    QuicFrame pending = NextPendingRetransmission();
+    QuicFrame copy = CopyRetransmittableControlFrame(pending);
+    if (!delegate_->WriteControlFrame(copy, LOSS_RETRANSMISSION)) {
+      // Connection is write blocked.
+      DeleteFrame(&copy);
+      break;
+    }
+    OnControlFrameSent(pending);
+  }
+}
+
+bool QuicControlFrameManager::OnControlFrameIdAcked(QuicControlFrameId id) {
+  if (id == kInvalidControlFrameId) {
+    // Frame does not have a valid control frame ID, ignore it.
+    return false;
+  }
+  if (id >= least_unsent_) {
+    QUIC_BUG(quic_bug_10517_4) << "Try to ack unsent control frame";
+    delegate_->OnControlFrameManagerError(QUIC_INTERNAL_ERROR,
+                                          "Try to ack unsent control frame");
+    return false;
+  }
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    // This frame has already been acked.
+    return false;
+  }
+
+  // Set control frame ID of acked frames to 0.
+  SetControlFrameId(kInvalidControlFrameId,
+                    &control_frames_.at(id - least_unacked_));
+  // Remove acked control frames from pending retransmissions.
+  pending_retransmissions_.erase(id);
+  // Clean up control frames queue and increment least_unacked_.
+  while (!control_frames_.empty() &&
+         GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
+    DeleteFrame(&control_frames_.front());
+    control_frames_.pop_front();
+    ++least_unacked_;
+  }
+  return true;
+}
+
+bool QuicControlFrameManager::HasBufferedFrames() const {
+  return least_unsent_ < least_unacked_ + control_frames_.size();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_control_frame_manager.h b/quiche/quic/core/quic_control_frame_manager.h
new file mode 100644
index 0000000..b885301
--- /dev/null
+++ b/quiche/quic/core/quic_control_frame_manager.h
@@ -0,0 +1,192 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+class QuicSession;
+
+namespace test {
+class QuicControlFrameManagerPeer;
+}  // namespace test
+
+// Control frame manager contains a list of sent control frames with valid
+// control frame IDs. Control frames without valid control frame IDs include:
+// (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
+// STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
+// APPLICATION_CLOSE frames.
+// New control frames are added to the tail of the list when they are added to
+// the generator. Control frames are removed from the head of the list when they
+// get acked. Control frame manager also keeps track of lost control frames
+// which need to be retransmitted.
+class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
+ public:
+  class QUIC_EXPORT_PRIVATE DelegateInterface {
+   public:
+    virtual ~DelegateInterface() = default;
+
+    // Notifies the delegate of errors.
+    virtual void OnControlFrameManagerError(QuicErrorCode error_code,
+                                            std::string error_details) = 0;
+
+    virtual bool WriteControlFrame(const QuicFrame& frame,
+                                   TransmissionType type) = 0;
+  };
+
+  explicit QuicControlFrameManager(QuicSession* session);
+  QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
+  QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
+  ~QuicControlFrameManager();
+
+  // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferRstStream(QuicControlFrameId id, QuicResetStreamError error,
+                              QuicStreamOffset bytes_written);
+
+  // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferGoAway(QuicErrorCode error,
+                           QuicStreamId last_good_stream_id,
+                           const std::string& reason);
+
+  // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
+
+  // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferBlocked(QuicStreamId id);
+
+  // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
+  // sent immediately.
+  void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
+
+  // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
+
+  // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
+  // can not be sent immediately.
+  void WriteOrBufferStopSending(QuicResetStreamError error,
+                                QuicStreamId stream_id);
+
+  // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
+  // be sent immediately.
+  void WriteOrBufferHandshakeDone();
+
+  // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
+  // sent immediately.
+  void WriteOrBufferAckFrequency(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Tries to send a NEW_CONNECTION_ID frame. The frame is buffered if it cannot
+  // be sent immediately.
+  void WriteOrBufferNewConnectionId(
+      const QuicConnectionId& connection_id, uint64_t sequence_number,
+      uint64_t retire_prior_to,
+      const StatelessResetToken& stateless_reset_token);
+
+  // Tries to send a RETIRE_CONNNECTION_ID frame. The frame is buffered if it
+  // cannot be sent immediately.
+  void WriteOrBufferRetireConnectionId(uint64_t sequence_number);
+
+  // Tries to send a NEW_TOKEN frame. Buffers the frame if it cannot be sent
+  // immediately.
+  void WriteOrBufferNewToken(absl::string_view token);
+
+  // Called when |frame| gets acked. Returns true if |frame| gets acked for the
+  // first time, return false otherwise.
+  bool OnControlFrameAcked(const QuicFrame& frame);
+
+  // Called when |frame| is considered as lost.
+  void OnControlFrameLost(const QuicFrame& frame);
+
+  // Called by the session when the connection becomes writable.
+  void OnCanWrite();
+
+  // Retransmit |frame| if it is still outstanding. Returns false if the frame
+  // does not get retransmitted because the connection is blocked. Otherwise,
+  // returns true.
+  bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
+
+  // Returns true if |frame| is outstanding and waiting to be acked. Returns
+  // false otherwise.
+  bool IsControlFrameOutstanding(const QuicFrame& frame) const;
+
+  // Returns true if there is any lost control frames waiting to be
+  // retransmitted.
+  bool HasPendingRetransmission() const;
+
+  // Returns true if there are any lost or new control frames waiting to be
+  // sent.
+  bool WillingToWrite() const;
+
+ private:
+  friend class test::QuicControlFrameManagerPeer;
+
+  // Tries to write buffered control frames to the peer.
+  void WriteBufferedFrames();
+
+  // Called when |frame| is sent for the first time or gets retransmitted.
+  void OnControlFrameSent(const QuicFrame& frame);
+
+  // Writes pending retransmissions if any.
+  void WritePendingRetransmission();
+
+  // Called when frame with |id| gets acked. Returns true if |id| gets acked for
+  // the first time, return false otherwise.
+  bool OnControlFrameIdAcked(QuicControlFrameId id);
+
+  // Retrieves the next pending retransmission. This must only be called when
+  // there are pending retransmissions.
+  QuicFrame NextPendingRetransmission() const;
+
+  // Returns true if there are buffered frames waiting to be sent for the first
+  // time.
+  bool HasBufferedFrames() const;
+
+  // Writes or buffers a control frame.  Frame is buffered if there already
+  // are frames waiting to be sent. If no others waiting, will try to send the
+  // frame.
+  void WriteOrBufferQuicFrame(QuicFrame frame);
+
+  quiche::QuicheCircularDeque<QuicFrame> control_frames_;
+
+  // Id of latest saved control frame. 0 if no control frame has been saved.
+  QuicControlFrameId last_control_frame_id_;
+
+  // The control frame at the 0th index of control_frames_.
+  QuicControlFrameId least_unacked_;
+
+  // ID of the least unsent control frame.
+  QuicControlFrameId least_unsent_;
+
+  // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
+  // is not used here.
+  // Lost control frames waiting to be retransmitted.
+  quiche::QuicheLinkedHashMap<QuicControlFrameId, bool>
+      pending_retransmissions_;
+
+  DelegateInterface* delegate_;
+
+  // Last sent window update frame for each stream.
+  absl::flat_hash_map<QuicStreamId, QuicControlFrameId> window_update_frames_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
diff --git a/quiche/quic/core/quic_control_frame_manager_test.cc b/quiche/quic/core/quic_control_frame_manager_test.cc
new file mode 100644
index 0000000..821bcca
--- /dev/null
+++ b/quiche/quic/core/quic_control_frame_manager_test.cc
@@ -0,0 +1,363 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_control_frame_manager.h"
+
+#include <utility>
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+class QuicControlFrameManagerPeer {
+ public:
+  static size_t QueueSize(QuicControlFrameManager* manager) {
+    return manager->control_frames_.size();
+  }
+};
+
+namespace {
+
+const QuicStreamId kTestStreamId = 5;
+const QuicRstStreamErrorCode kTestStopSendingCode =
+    QUIC_STREAM_ENCODER_STREAM_ERROR;
+
+class QuicControlFrameManagerTest : public QuicTest {
+ public:
+  bool SaveControlFrame(const QuicFrame& frame, TransmissionType /*type*/) {
+    frame_ = frame;
+    return true;
+  }
+
+ protected:
+  // Pre-fills the control frame queue with the following frames:
+  //  ID Type
+  //  1  RST_STREAM
+  //  2  GO_AWAY
+  //  3  WINDOW_UPDATE
+  //  4  BLOCKED
+  //  5  STOP_SENDING
+  // This is verified. The tests then perform manipulations on these.
+  void Initialize() {
+    connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
+                                         Perspective::IS_SERVER);
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
+    manager_ = std::make_unique<QuicControlFrameManager>(session_.get());
+    EXPECT_EQ(0u, QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+    EXPECT_FALSE(manager_->HasPendingRetransmission());
+    EXPECT_FALSE(manager_->WillingToWrite());
+
+    EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+    manager_->WriteOrBufferRstStream(
+        kTestStreamId,
+        QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
+    manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
+                                  "Going away.");
+    manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
+    manager_->WriteOrBufferBlocked(kTestStreamId);
+    manager_->WriteOrBufferStopSending(
+        QuicResetStreamError::FromInternal(kTestStopSendingCode),
+        kTestStreamId);
+    number_of_frames_ = 5u;
+    EXPECT_EQ(number_of_frames_,
+              QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
+
+    EXPECT_FALSE(manager_->HasPendingRetransmission());
+    EXPECT_TRUE(manager_->WillingToWrite());
+  }
+
+  QuicRstStreamFrame rst_stream_ = {1, kTestStreamId, QUIC_STREAM_CANCELLED, 0};
+  QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
+                             "Going away."};
+  QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
+  QuicBlockedFrame blocked_ = {4, kTestStreamId};
+  QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<StrictMock<MockQuicSession>> session_;
+  std::unique_ptr<QuicControlFrameManager> manager_;
+  QuicFrame frame_;
+  size_t number_of_frames_;
+};
+
+TEST_F(QuicControlFrameManagerTest, OnControlFrameAcked) {
+  Initialize();
+  InSequence s;
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(3)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  // Send control frames 1, 2, 3.
+  manager_->OnCanWrite();
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
+
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(window_update_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
+  EXPECT_EQ(number_of_frames_,
+            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
+  EXPECT_EQ(number_of_frames_,
+            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+  EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&rst_stream_)));
+  EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(&rst_stream_)));
+  // Only after the first frame in the queue is acked do the frames get
+  // removed ... now see that the length has been reduced by 3.
+  EXPECT_EQ(number_of_frames_ - 3u,
+            QuicControlFrameManagerPeer::QueueSize(manager_.get()));
+  // Duplicate ack.
+  EXPECT_FALSE(manager_->OnControlFrameAcked(QuicFrame(&goaway_)));
+
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Send control frames 4, 5.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->WillingToWrite());
+}
+
+TEST_F(QuicControlFrameManagerTest, OnControlFrameLost) {
+  Initialize();
+  InSequence s;
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(3)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  // Send control frames 1, 2, 3.
+  manager_->OnCanWrite();
+
+  // Lost control frames 1, 2, 3.
+  manager_->OnControlFrameLost(QuicFrame(&rst_stream_));
+  manager_->OnControlFrameLost(QuicFrame(&goaway_));
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  EXPECT_TRUE(manager_->HasPendingRetransmission());
+
+  // Ack control frame 2.
+  manager_->OnControlFrameAcked(QuicFrame(&goaway_));
+
+  // Retransmit control frames 1, 3.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Send control frames 4, 5, and 6.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(number_of_frames_ - 3u)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->WillingToWrite());
+}
+
+TEST_F(QuicControlFrameManagerTest, RetransmitControlFrame) {
+  Initialize();
+  InSequence s;
+  // Send control frames 1, 2, 3, 4.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(number_of_frames_)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Ack control frame 2.
+  manager_->OnControlFrameAcked(QuicFrame(&goaway_));
+  // Do not retransmit an acked frame
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(0);
+  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(&goaway_),
+                                               PTO_RETRANSMISSION));
+
+  // Retransmit control frame 3.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_TRUE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
+                                               PTO_RETRANSMISSION));
+
+  // Retransmit control frame 4, and connection is write blocked.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  EXPECT_FALSE(manager_->RetransmitControlFrame(QuicFrame(window_update_),
+                                                PTO_RETRANSMISSION));
+}
+
+TEST_F(QuicControlFrameManagerTest, SendAndAckAckFrequencyFrame) {
+  Initialize();
+  InSequence s;
+  // Send Non-AckFrequency frame 1-5.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(5)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  manager_->OnCanWrite();
+
+  // Send AckFrequencyFrame as frame 6.
+  QuicAckFrequencyFrame frame_to_send;
+  frame_to_send.packet_tolerance = 10;
+  frame_to_send.max_ack_delay = QuicTime::Delta::FromMilliseconds(24);
+  manager_->WriteOrBufferAckFrequency(frame_to_send);
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Ack AckFrequencyFrame.
+  QuicAckFrequencyFrame expected_ack_frequency = {
+      6, 6, 10, QuicTime::Delta::FromMilliseconds(24)};
+  EXPECT_TRUE(
+      manager_->OnControlFrameAcked(QuicFrame(&expected_ack_frequency)));
+}
+
+TEST_F(QuicControlFrameManagerTest, NewAndRetireConnectionIdFrames) {
+  Initialize();
+  InSequence s;
+
+  // Send other frames 1-5.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(5)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  // Send NewConnectionIdFrame as frame 6.
+  manager_->WriteOrBufferNewConnectionId(
+      TestConnectionId(3), /*sequence_number=*/2, /*retire_prior_to=*/1,
+      /*stateless_reset_token=*/
+      {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1});
+  // Send RetireConnectionIdFrame as frame 7.
+  manager_->WriteOrBufferRetireConnectionId(/*sequence_number=*/0);
+  manager_->OnCanWrite();
+
+  // Ack both frames.
+  QuicNewConnectionIdFrame new_connection_id_frame;
+  new_connection_id_frame.control_frame_id = 6;
+  QuicRetireConnectionIdFrame retire_connection_id_frame;
+  retire_connection_id_frame.control_frame_id = 7;
+  EXPECT_TRUE(
+      manager_->OnControlFrameAcked(QuicFrame(&new_connection_id_frame)));
+  EXPECT_TRUE(
+      manager_->OnControlFrameAcked(QuicFrame(&retire_connection_id_frame)));
+}
+
+TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) {
+  Initialize();
+  // Send two more window updates of the same stream.
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId, 200);
+  QuicWindowUpdateFrame window_update2(number_of_frames_ + 1, kTestStreamId,
+                                       200);
+
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId, 300);
+  QuicWindowUpdateFrame window_update3(number_of_frames_ + 2, kTestStreamId,
+                                       300);
+  InSequence s;
+  // Flush all buffered control frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Mark all 3 window updates as lost.
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update2));
+  manager_->OnControlFrameLost(QuicFrame(window_update3));
+  EXPECT_TRUE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Verify only the latest window update gets retransmitted.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(this, &QuicControlFrameManagerTest::SaveControlFrame));
+  manager_->OnCanWrite();
+  EXPECT_EQ(number_of_frames_ + 2u,
+            frame_.window_update_frame.control_frame_id);
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_FALSE(manager_->WillingToWrite());
+  DeleteFrame(&frame_);
+}
+
+TEST_F(QuicControlFrameManagerTest, RetransmitWindowUpdateOfDifferentStreams) {
+  Initialize();
+  // Send two more window updates of different streams.
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId + 2, 200);
+  QuicWindowUpdateFrame window_update2(5, kTestStreamId + 2, 200);
+
+  manager_->WriteOrBufferWindowUpdate(kTestStreamId + 4, 300);
+  QuicWindowUpdateFrame window_update3(6, kTestStreamId + 4, 300);
+  InSequence s;
+  // Flush all buffered control frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+
+  // Mark all 3 window updates as lost.
+  manager_->OnControlFrameLost(QuicFrame(window_update_));
+  manager_->OnControlFrameLost(QuicFrame(window_update2));
+  manager_->OnControlFrameLost(QuicFrame(window_update3));
+  EXPECT_TRUE(manager_->HasPendingRetransmission());
+  EXPECT_TRUE(manager_->WillingToWrite());
+
+  // Verify all 3 window updates get retransmitted.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(3)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  manager_->OnCanWrite();
+  EXPECT_FALSE(manager_->HasPendingRetransmission());
+  EXPECT_FALSE(manager_->WillingToWrite());
+}
+
+TEST_F(QuicControlFrameManagerTest, TooManyBufferedControlFrames) {
+  Initialize();
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(5)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  // Flush buffered frames.
+  manager_->OnCanWrite();
+  // Write 995 control frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).WillOnce(Return(false));
+  for (size_t i = 0; i < 995; ++i) {
+    manager_->WriteOrBufferRstStream(
+        kTestStreamId,
+        QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0);
+  }
+  // Verify write one more control frame causes connection close.
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES, _,
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  manager_->WriteOrBufferRstStream(
+      kTestStreamId, QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED),
+      0);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_handshaker.cc b/quiche/quic/core/quic_crypto_client_handshaker.cc
new file mode 100644
index 0000000..c4a8262
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_handshaker.cc
@@ -0,0 +1,629 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_client_handshaker.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
+    ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent)
+    : parent_(parent) {}
+
+QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
+    ~ProofVerifierCallbackImpl() {}
+
+void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Run(
+    bool ok,
+    const std::string& error_details,
+    std::unique_ptr<ProofVerifyDetails>* details) {
+  if (parent_ == nullptr) {
+    return;
+  }
+
+  parent_->verify_ok_ = ok;
+  parent_->verify_error_details_ = error_details;
+  parent_->verify_details_ = std::move(*details);
+  parent_->proof_verify_callback_ = nullptr;
+  parent_->DoHandshakeLoop(nullptr);
+
+  // The ProofVerifier owns this object and will delete it when this method
+  // returns.
+}
+
+void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
+  parent_ = nullptr;
+}
+
+QuicCryptoClientHandshaker::QuicCryptoClientHandshaker(
+    const QuicServerId& server_id,
+    QuicCryptoClientStream* stream,
+    QuicSession* session,
+    std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    QuicCryptoClientStream::ProofHandler* proof_handler)
+    : QuicCryptoHandshaker(stream, session),
+      stream_(stream),
+      session_(session),
+      delegate_(session),
+      next_state_(STATE_IDLE),
+      num_client_hellos_(0),
+      crypto_config_(crypto_config),
+      server_id_(server_id),
+      generation_counter_(0),
+      verify_context_(std::move(verify_context)),
+      proof_verify_callback_(nullptr),
+      proof_handler_(proof_handler),
+      verify_ok_(false),
+      proof_verify_start_time_(QuicTime::Zero()),
+      num_scup_messages_received_(0),
+      encryption_established_(false),
+      one_rtt_keys_available_(false),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
+
+QuicCryptoClientHandshaker::~QuicCryptoClientHandshaker() {
+  if (proof_verify_callback_) {
+    proof_verify_callback_->Cancel();
+  }
+}
+
+void QuicCryptoClientHandshaker::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QuicCryptoHandshaker::OnHandshakeMessage(message);
+  if (message.tag() == kSCUP) {
+    if (!one_rtt_keys_available()) {
+      stream_->OnUnrecoverableError(
+          QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
+          "Early SCUP disallowed");
+      return;
+    }
+
+    // |message| is an update from the server, so we treat it differently from a
+    // handshake message.
+    HandleServerConfigUpdateMessage(message);
+    num_scup_messages_received_++;
+    return;
+  }
+
+  // Do not process handshake messages after the handshake is confirmed.
+  if (one_rtt_keys_available()) {
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+                                  "Unexpected handshake message");
+    return;
+  }
+
+  DoHandshakeLoop(&message);
+}
+
+bool QuicCryptoClientHandshaker::CryptoConnect() {
+  next_state_ = STATE_INITIALIZE;
+  DoHandshakeLoop(nullptr);
+  return session()->connection()->connected();
+}
+
+int QuicCryptoClientHandshaker::num_sent_client_hellos() const {
+  return num_client_hellos_;
+}
+
+bool QuicCryptoClientHandshaker::IsResumption() const {
+  QUIC_BUG_IF(quic_bug_12522_1, !one_rtt_keys_available_);
+  // While 0-RTT handshakes could be considered to be like resumption, QUIC
+  // Crypto doesn't have the same notion of a resumption like TLS does.
+  return false;
+}
+
+bool QuicCryptoClientHandshaker::EarlyDataAccepted() const {
+  QUIC_BUG_IF(quic_bug_12522_2, !one_rtt_keys_available_);
+  return num_client_hellos_ == 1;
+}
+
+ssl_early_data_reason_t QuicCryptoClientHandshaker::EarlyDataReason() const {
+  return early_data_reason_;
+}
+
+bool QuicCryptoClientHandshaker::ReceivedInchoateReject() const {
+  QUIC_BUG_IF(quic_bug_12522_3, !one_rtt_keys_available_);
+  return num_client_hellos_ >= 3;
+}
+
+int QuicCryptoClientHandshaker::num_scup_messages_received() const {
+  return num_scup_messages_received_;
+}
+
+std::string QuicCryptoClientHandshaker::chlo_hash() const {
+  return chlo_hash_;
+}
+
+bool QuicCryptoClientHandshaker::encryption_established() const {
+  return encryption_established_;
+}
+
+bool QuicCryptoClientHandshaker::one_rtt_keys_available() const {
+  return one_rtt_keys_available_;
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoClientHandshaker::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* QuicCryptoClientHandshaker::crypto_message_parser() {
+  return QuicCryptoHandshaker::crypto_message_parser();
+}
+
+HandshakeState QuicCryptoClientHandshaker::GetHandshakeState() const {
+  return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+}
+
+void QuicCryptoClientHandshaker::OnHandshakeDoneReceived() {
+  QUICHE_DCHECK(false);
+}
+
+void QuicCryptoClientHandshaker::OnNewTokenReceived(
+    absl::string_view /*token*/) {
+  QUICHE_DCHECK(false);
+}
+
+size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicCryptoClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+std::unique_ptr<QuicEncrypter>
+QuicCryptoClientHandshaker::CreateCurrentOneRttEncrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+void QuicCryptoClientHandshaker::OnConnectionClosed(
+    QuicErrorCode /*error*/,
+    ConnectionCloseSource /*source*/) {
+  next_state_ = STATE_CONNECTION_CLOSED;
+}
+
+void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
+    const CryptoHandshakeMessage& server_config_update) {
+  QUICHE_DCHECK(server_config_update.tag() == kSCUP);
+  std::string error_details;
+  QuicCryptoClientConfig::CachedState* cached =
+      crypto_config_->LookupOrCreate(server_id_);
+  QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
+      server_config_update, session()->connection()->clock()->WallNow(),
+      session()->transport_version(), chlo_hash_, cached,
+      crypto_negotiated_params_, &error_details);
+
+  if (error != QUIC_NO_ERROR) {
+    stream_->OnUnrecoverableError(
+        error, "Server config update invalid: " + error_details);
+    return;
+  }
+
+  QUICHE_DCHECK(one_rtt_keys_available());
+  if (proof_verify_callback_) {
+    proof_verify_callback_->Cancel();
+  }
+  next_state_ = STATE_INITIALIZE_SCUP;
+  DoHandshakeLoop(nullptr);
+}
+
+void QuicCryptoClientHandshaker::DoHandshakeLoop(
+    const CryptoHandshakeMessage* in) {
+  QuicCryptoClientConfig::CachedState* cached =
+      crypto_config_->LookupOrCreate(server_id_);
+
+  QuicAsyncStatus rv = QUIC_SUCCESS;
+  do {
+    QUICHE_CHECK_NE(STATE_NONE, next_state_);
+    const State state = next_state_;
+    next_state_ = STATE_IDLE;
+    rv = QUIC_SUCCESS;
+    switch (state) {
+      case STATE_INITIALIZE:
+        DoInitialize(cached);
+        break;
+      case STATE_SEND_CHLO:
+        DoSendCHLO(cached);
+        return;  // return waiting to hear from server.
+      case STATE_RECV_REJ:
+        DoReceiveREJ(in, cached);
+        break;
+      case STATE_VERIFY_PROOF:
+        rv = DoVerifyProof(cached);
+        break;
+      case STATE_VERIFY_PROOF_COMPLETE:
+        DoVerifyProofComplete(cached);
+        break;
+      case STATE_RECV_SHLO:
+        DoReceiveSHLO(in, cached);
+        break;
+      case STATE_IDLE:
+        // This means that the peer sent us a message that we weren't expecting.
+        stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                      "Handshake in idle state");
+        return;
+      case STATE_INITIALIZE_SCUP:
+        DoInitializeServerConfigUpdate(cached);
+        break;
+      case STATE_NONE:
+        QUIC_NOTREACHED();
+        return;
+      case STATE_CONNECTION_CLOSED:
+        rv = QUIC_FAILURE;
+        return;  // We are done.
+    }
+  } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
+}
+
+void QuicCryptoClientHandshaker::DoInitialize(
+    QuicCryptoClientConfig::CachedState* cached) {
+  if (!cached->IsEmpty() && !cached->signature().empty()) {
+    // Note that we verify the proof even if the cached proof is valid.
+    // This allows us to respond to CA trust changes or certificate
+    // expiration because it may have been a while since we last verified
+    // the proof.
+    QUICHE_DCHECK(crypto_config_->proof_verifier());
+    // Track proof verification time when cached server config is used.
+    proof_verify_start_time_ = session()->connection()->clock()->Now();
+    chlo_hash_ = cached->chlo_hash();
+    // If the cached state needs to be verified, do it now.
+    next_state_ = STATE_VERIFY_PROOF;
+  } else {
+    next_state_ = STATE_SEND_CHLO;
+  }
+}
+
+void QuicCryptoClientHandshaker::DoSendCHLO(
+    QuicCryptoClientConfig::CachedState* cached) {
+  // Send the client hello in plaintext.
+  session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  encryption_established_ = false;
+  if (num_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) {
+    stream_->OnUnrecoverableError(
+        QUIC_CRYPTO_TOO_MANY_REJECTS,
+        absl::StrCat("More than ", QuicCryptoClientStream::kMaxClientHellos,
+                     " rejects"));
+    return;
+  }
+  num_client_hellos_++;
+
+  CryptoHandshakeMessage out;
+  QUICHE_DCHECK(session() != nullptr);
+  QUICHE_DCHECK(session()->config() != nullptr);
+  // Send all the options, regardless of whether we're sending an
+  // inchoate or subsequent hello.
+  session()->config()->ToHandshakeMessage(&out, session()->transport_version());
+
+  bool fill_inchoate_client_hello = false;
+  if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
+    early_data_reason_ = ssl_early_data_no_session_offered;
+    fill_inchoate_client_hello = true;
+  } else if (session()->config()->HasClientRequestedIndependentOption(
+                 kQNZ2, session()->perspective()) &&
+             num_client_hellos_ == 1) {
+    early_data_reason_ = ssl_early_data_disabled;
+    fill_inchoate_client_hello = true;
+  }
+  if (fill_inchoate_client_hello) {
+    crypto_config_->FillInchoateClientHello(
+        server_id_, session()->supported_versions().front(), cached,
+        session()->connection()->random_generator(),
+        /* demand_x509_proof= */ true, crypto_negotiated_params_, &out);
+    // Pad the inchoate client hello to fill up a packet.
+    const QuicByteCount kFramingOverhead = 50;  // A rough estimate.
+    const QuicByteCount max_packet_size =
+        session()->connection()->max_packet_length();
+    if (max_packet_size <= kFramingOverhead) {
+      QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
+                        << ") has no room for framing overhead.";
+      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                                    "max_packet_size too smalll");
+      return;
+    }
+    if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
+      QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
+      stream_->OnUnrecoverableError(QUIC_INTERNAL_ERROR, "CHLO too large");
+      return;
+    }
+    next_state_ = STATE_RECV_REJ;
+    chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
+    session()->connection()->set_fully_pad_crypto_handshake_packets(
+        crypto_config_->pad_inchoate_hello());
+    SendHandshakeMessage(out, ENCRYPTION_INITIAL);
+    return;
+  }
+
+  std::string error_details;
+  QuicErrorCode error = crypto_config_->FillClientHello(
+      server_id_, session()->connection()->connection_id(),
+      session()->supported_versions().front(),
+      session()->connection()->version(), cached,
+      session()->connection()->clock()->WallNow(),
+      session()->connection()->random_generator(), crypto_negotiated_params_,
+      &out, &error_details);
+  if (error != QUIC_NO_ERROR) {
+    // Flush the cached config so that, if it's bad, the server has a
+    // chance to send us another in the future.
+    cached->InvalidateServerConfig();
+    stream_->OnUnrecoverableError(error, error_details);
+    return;
+  }
+  chlo_hash_ = CryptoUtils::HashHandshakeMessage(out, Perspective::IS_CLIENT);
+  if (cached->proof_verify_details()) {
+    proof_handler_->OnProofVerifyDetailsAvailable(
+        *cached->proof_verify_details());
+  }
+  next_state_ = STATE_RECV_SHLO;
+  session()->connection()->set_fully_pad_crypto_handshake_packets(
+      crypto_config_->pad_full_hello());
+  SendHandshakeMessage(out, ENCRYPTION_INITIAL);
+  // Be prepared to decrypt with the new server write key.
+  delegate_->OnNewEncryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
+      /*set_alternative_decrypter=*/true,
+      /*latch_once_used=*/true);
+  encryption_established_ = true;
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  if (early_data_reason_ == ssl_early_data_unknown && num_client_hellos_ > 1) {
+    early_data_reason_ = ssl_early_data_peer_declined;
+  }
+}
+
+void QuicCryptoClientHandshaker::DoReceiveREJ(
+    const CryptoHandshakeMessage* in,
+    QuicCryptoClientConfig::CachedState* cached) {
+  // We sent a dummy CHLO because we didn't have enough information to
+  // perform a handshake, or we sent a full hello that the server
+  // rejected. Here we hope to have a REJ that contains the information
+  // that we need.
+  if (in->tag() != kREJ) {
+    next_state_ = STATE_NONE;
+    stream_->OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                  "Expected REJ");
+    return;
+  }
+
+  QuicTagVector reject_reasons;
+  static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
+  if (in->GetTaglist(kRREJ, &reject_reasons) == QUIC_NO_ERROR) {
+    uint32_t packed_error = 0;
+    for (size_t i = 0; i < reject_reasons.size(); ++i) {
+      // HANDSHAKE_OK is 0 and don't report that as error.
+      if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
+        continue;
+      }
+      HandshakeFailureReason reason =
+          static_cast<HandshakeFailureReason>(reject_reasons[i]);
+      packed_error |= 1 << (reason - 1);
+    }
+    QUIC_DVLOG(1) << "Reasons for rejection: " << packed_error;
+    if (num_client_hellos_ == QuicCryptoClientStream::kMaxClientHellos) {
+      QuicClientSparseHistogram("QuicClientHelloRejectReasons.TooMany",
+                                packed_error);
+    }
+    QuicClientSparseHistogram("QuicClientHelloRejectReasons.Secure",
+                              packed_error);
+  }
+
+  // Receipt of a REJ message means that the server received the CHLO
+  // so we can cancel and retransmissions.
+  delegate_->NeuterUnencryptedData();
+
+  std::string error_details;
+  QuicErrorCode error = crypto_config_->ProcessRejection(
+      *in, session()->connection()->clock()->WallNow(),
+      session()->transport_version(), chlo_hash_, cached,
+      crypto_negotiated_params_, &error_details);
+
+  if (error != QUIC_NO_ERROR) {
+    next_state_ = STATE_NONE;
+    stream_->OnUnrecoverableError(error, error_details);
+    return;
+  }
+  if (!cached->proof_valid()) {
+    if (!cached->signature().empty()) {
+      // Note that we only verify the proof if the cached proof is not
+      // valid. If the cached proof is valid here, someone else must have
+      // just added the server config to the cache and verified the proof,
+      // so we can assume no CA trust changes or certificate expiration
+      // has happened since then.
+      next_state_ = STATE_VERIFY_PROOF;
+      return;
+    }
+  }
+  next_state_ = STATE_SEND_CHLO;
+}
+
+QuicAsyncStatus QuicCryptoClientHandshaker::DoVerifyProof(
+    QuicCryptoClientConfig::CachedState* cached) {
+  ProofVerifier* verifier = crypto_config_->proof_verifier();
+  QUICHE_DCHECK(verifier);
+  next_state_ = STATE_VERIFY_PROOF_COMPLETE;
+  generation_counter_ = cached->generation_counter();
+
+  ProofVerifierCallbackImpl* proof_verify_callback =
+      new ProofVerifierCallbackImpl(this);
+
+  verify_ok_ = false;
+
+  QuicAsyncStatus status = verifier->VerifyProof(
+      server_id_.host(), server_id_.port(), cached->server_config(),
+      session()->transport_version(), chlo_hash_, cached->certs(),
+      cached->cert_sct(), cached->signature(), verify_context_.get(),
+      &verify_error_details_, &verify_details_,
+      std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
+
+  switch (status) {
+    case QUIC_PENDING:
+      proof_verify_callback_ = proof_verify_callback;
+      QUIC_DVLOG(1) << "Doing VerifyProof";
+      break;
+    case QUIC_FAILURE:
+      break;
+    case QUIC_SUCCESS:
+      verify_ok_ = true;
+      break;
+  }
+  return status;
+}
+
+void QuicCryptoClientHandshaker::DoVerifyProofComplete(
+    QuicCryptoClientConfig::CachedState* cached) {
+  if (proof_verify_start_time_.IsInitialized()) {
+    QUIC_CLIENT_HISTOGRAM_TIMES(
+        "QuicSession.VerifyProofTime.CachedServerConfig",
+        (session()->connection()->clock()->Now() - proof_verify_start_time_),
+        QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::FromSeconds(10),
+        50, "");
+  }
+  if (!verify_ok_) {
+    if (verify_details_) {
+      proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
+    }
+    if (num_client_hellos_ == 0) {
+      cached->Clear();
+      next_state_ = STATE_INITIALIZE;
+      return;
+    }
+    next_state_ = STATE_NONE;
+    QUIC_CLIENT_HISTOGRAM_BOOL("QuicVerifyProofFailed.HandshakeConfirmed",
+                               one_rtt_keys_available(), "");
+    stream_->OnUnrecoverableError(QUIC_PROOF_INVALID,
+                                  "Proof invalid: " + verify_error_details_);
+    return;
+  }
+
+  // Check if generation_counter has changed between STATE_VERIFY_PROOF and
+  // STATE_VERIFY_PROOF_COMPLETE state changes.
+  if (generation_counter_ != cached->generation_counter()) {
+    next_state_ = STATE_VERIFY_PROOF;
+  } else {
+    SetCachedProofValid(cached);
+    cached->SetProofVerifyDetails(verify_details_.release());
+    if (!one_rtt_keys_available()) {
+      next_state_ = STATE_SEND_CHLO;
+    } else {
+      next_state_ = STATE_NONE;
+    }
+  }
+}
+
+void QuicCryptoClientHandshaker::DoReceiveSHLO(
+    const CryptoHandshakeMessage* in,
+    QuicCryptoClientConfig::CachedState* cached) {
+  next_state_ = STATE_NONE;
+  // We sent a CHLO that we expected to be accepted and now we're
+  // hoping for a SHLO from the server to confirm that.  First check
+  // to see whether the response was a reject, and if so, move on to
+  // the reject-processing state.
+  if (in->tag() == kREJ) {
+    // A reject message must be sent in ENCRYPTION_INITIAL.
+    if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
+      // The rejection was sent encrypted!
+      stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                    "encrypted REJ message");
+      return;
+    }
+    next_state_ = STATE_RECV_REJ;
+    return;
+  }
+
+  if (in->tag() != kSHLO) {
+    stream_->OnUnrecoverableError(
+        QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+        absl::StrCat("Expected SHLO or REJ. Received: ",
+                     QuicTagToString(in->tag())));
+    return;
+  }
+
+  if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
+    // The server hello was sent without encryption.
+    stream_->OnUnrecoverableError(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                  "unencrypted SHLO message");
+    return;
+  }
+  if (num_client_hellos_ == 1) {
+    early_data_reason_ = ssl_early_data_accepted;
+  }
+
+  std::string error_details;
+  QuicErrorCode error = crypto_config_->ProcessServerHello(
+      *in, session()->connection()->connection_id(),
+      session()->connection()->version(),
+      session()->connection()->server_supported_versions(), cached,
+      crypto_negotiated_params_, &error_details);
+
+  if (error != QUIC_NO_ERROR) {
+    stream_->OnUnrecoverableError(error,
+                                  "Server hello invalid: " + error_details);
+    return;
+  }
+  error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
+  if (error != QUIC_NO_ERROR) {
+    stream_->OnUnrecoverableError(error,
+                                  "Server hello invalid: " + error_details);
+    return;
+  }
+  session()->OnConfigNegotiated();
+
+  CrypterPair* crypters = &crypto_negotiated_params_->forward_secure_crypters;
+  // TODO(agl): we don't currently latch this decrypter because the idea
+  // has been floated that the server shouldn't send packets encrypted
+  // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
+  // packet from the client.
+  delegate_->OnNewEncryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
+                                         std::move(crypters->encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(ENCRYPTION_FORWARD_SECURE,
+                                         std::move(crypters->decrypter),
+                                         /*set_alternative_decrypter=*/true,
+                                         /*latch_once_used=*/false);
+  one_rtt_keys_available_ = true;
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  delegate_->NeuterHandshakeData();
+}
+
+void QuicCryptoClientHandshaker::DoInitializeServerConfigUpdate(
+    QuicCryptoClientConfig::CachedState* cached) {
+  bool update_ignored = false;
+  if (!cached->IsEmpty() && !cached->signature().empty()) {
+    // Note that we verify the proof even if the cached proof is valid.
+    QUICHE_DCHECK(crypto_config_->proof_verifier());
+    next_state_ = STATE_VERIFY_PROOF;
+  } else {
+    update_ignored = true;
+    next_state_ = STATE_NONE;
+  }
+  QUIC_CLIENT_HISTOGRAM_COUNTS("QuicNumServerConfig.UpdateMessagesIgnored",
+                               update_ignored, 1, 1000000, 50, "");
+}
+
+void QuicCryptoClientHandshaker::SetCachedProofValid(
+    QuicCryptoClientConfig::CachedState* cached) {
+  cached->SetProofValid();
+  proof_handler_->OnProofValid(*cached);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_handshaker.h b/quiche/quic/core/quic_crypto_client_handshaker.h
new file mode 100644
index 0000000..07404d6
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_handshaker.h
@@ -0,0 +1,211 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
+
+#include <string>
+
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+
+// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
+// QUIC crypto as the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
+    : public QuicCryptoClientStream::HandshakerInterface,
+      public QuicCryptoHandshaker {
+ public:
+  QuicCryptoClientHandshaker(
+      const QuicServerId& server_id,
+      QuicCryptoClientStream* stream,
+      QuicSession* session,
+      std::unique_ptr<ProofVerifyContext> verify_context,
+      QuicCryptoClientConfig* crypto_config,
+      QuicCryptoClientStream::ProofHandler* proof_handler);
+  QuicCryptoClientHandshaker(const QuicCryptoClientHandshaker&) = delete;
+  QuicCryptoClientHandshaker& operator=(const QuicCryptoClientHandshaker&) =
+      delete;
+
+  ~QuicCryptoClientHandshaker() override;
+
+  // From QuicCryptoClientStream::HandshakerInterface
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  bool IsResumption() const override;
+  bool EarlyDataAccepted() const override;
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool ReceivedInchoateReject() const override;
+  int num_scup_messages_received() const override;
+  std::string chlo_hash() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {
+    QUICHE_NOTREACHED();
+  }
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+
+  // From QuicCryptoHandshaker
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+ protected:
+  // Returns the QuicSession that this stream belongs to.
+  QuicSession* session() const { return session_; }
+
+  // Send either InchoateClientHello or ClientHello message to the server.
+  void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached);
+
+ private:
+  // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
+  // The ProofVerifier calls this class with the result of proof verification
+  // when verification is performed asynchronously.
+  class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
+      : public ProofVerifierCallback {
+   public:
+    explicit ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent);
+    ~ProofVerifierCallbackImpl() override;
+
+    // ProofVerifierCallback interface.
+    void Run(bool ok,
+             const std::string& error_details,
+             std::unique_ptr<ProofVerifyDetails>* details) override;
+
+    // Cancel causes any future callbacks to be ignored. It must be called on
+    // the same thread as the callback will be made on.
+    void Cancel();
+
+   private:
+    QuicCryptoClientHandshaker* parent_;
+  };
+
+  enum State {
+    STATE_IDLE,
+    STATE_INITIALIZE,
+    STATE_SEND_CHLO,
+    STATE_RECV_REJ,
+    STATE_VERIFY_PROOF,
+    STATE_VERIFY_PROOF_COMPLETE,
+    STATE_RECV_SHLO,
+    STATE_INITIALIZE_SCUP,
+    STATE_NONE,
+    STATE_CONNECTION_CLOSED,
+  };
+
+  // Handles new server config and optional source-address token provided by the
+  // server during a connection.
+  void HandleServerConfigUpdateMessage(
+      const CryptoHandshakeMessage& server_config_update);
+
+  // DoHandshakeLoop performs a step of the handshake state machine. Note that
+  // |in| may be nullptr if the call did not result from a received message.
+  void DoHandshakeLoop(const CryptoHandshakeMessage* in);
+
+  // Start the handshake process.
+  void DoInitialize(QuicCryptoClientConfig::CachedState* cached);
+
+  // Process REJ message from the server.
+  void DoReceiveREJ(const CryptoHandshakeMessage* in,
+                    QuicCryptoClientConfig::CachedState* cached);
+
+  // Start the proof verification process. Returns the QuicAsyncStatus returned
+  // by the ProofVerifier's VerifyProof.
+  QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
+
+  // If proof is valid then it sets the proof as valid (which persists the
+  // server config). If not, it closes the connection.
+  void DoVerifyProofComplete(QuicCryptoClientConfig::CachedState* cached);
+
+  // Process SHLO message from the server.
+  void DoReceiveSHLO(const CryptoHandshakeMessage* in,
+                     QuicCryptoClientConfig::CachedState* cached);
+
+  // Start the proof verification if |server_id_| is https and |cached| has
+  // signature.
+  void DoInitializeServerConfigUpdate(
+      QuicCryptoClientConfig::CachedState* cached);
+
+  // Called to set the proof of |cached| valid.  Also invokes the session's
+  // OnProofValid() method.
+  void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);
+
+  QuicCryptoClientStream* stream_;
+
+  QuicSession* session_;
+  HandshakerDelegateInterface* delegate_;
+
+  State next_state_;
+  // num_client_hellos_ contains the number of client hello messages that this
+  // connection has sent.
+  int num_client_hellos_;
+
+  ssl_early_data_reason_t early_data_reason_ = ssl_early_data_unknown;
+
+  QuicCryptoClientConfig* const crypto_config_;
+
+  // SHA-256 hash of the most recently sent CHLO.
+  std::string chlo_hash_;
+
+  // Server's (hostname, port, is_https, privacy_mode) tuple.
+  const QuicServerId server_id_;
+
+  // Generation counter from QuicCryptoClientConfig's CachedState.
+  uint64_t generation_counter_;
+
+  // verify_context_ contains the context object that we pass to asynchronous
+  // proof verifications.
+  std::unique_ptr<ProofVerifyContext> verify_context_;
+
+  // proof_verify_callback_ contains the callback object that we passed to an
+  // asynchronous proof verification. The ProofVerifier owns this object.
+  ProofVerifierCallbackImpl* proof_verify_callback_;
+  // proof_handler_ contains the callback object used by a quic client
+  // for proof verification. It is not owned by this class.
+  QuicCryptoClientStream::ProofHandler* proof_handler_;
+
+  // These members are used to store the result of an asynchronous proof
+  // verification. These members must not be used after
+  // STATE_VERIFY_PROOF_COMPLETE.
+  bool verify_ok_;
+  std::string verify_error_details_;
+  std::unique_ptr<ProofVerifyDetails> verify_details_;
+
+  QuicTime proof_verify_start_time_;
+
+  int num_scup_messages_received_;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
diff --git a/quiche/quic/core/quic_crypto_client_handshaker_test.cc b/quiche/quic/core/quic_crypto_client_handshaker_test.cc
new file mode 100644
index 0000000..65d98f9
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_handshaker_test.cc
@@ -0,0 +1,239 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_client_handshaker.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace {
+
+class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
+ public:
+  ~TestProofHandler() override {}
+  void OnProofValid(
+      const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& /*verify_details*/) override {}
+};
+
+class InsecureProofVerifier : public ProofVerifier {
+ public:
+  InsecureProofVerifier() {}
+  ~InsecureProofVerifier() override {}
+
+  // ProofVerifier override.
+  QuicAsyncStatus VerifyProof(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::string& /*server_config*/,
+      QuicTransportVersion /*transport_version*/,
+      absl::string_view /*chlo_hash*/,
+      const std::vector<std::string>& /*certs*/,
+      const std::string& /*cert_sct*/,
+      const std::string& /*signature*/,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return QUIC_SUCCESS;
+  }
+
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::vector<std::string>& /*certs*/,
+      const std::string& /*ocsp_response*/,
+      const std::string& /*cert_sct*/,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*details*/,
+      uint8_t* /*out_alert*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return QUIC_SUCCESS;
+  }
+
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    return nullptr;
+  }
+};
+
+class DummyProofSource : public ProofSource {
+ public:
+  DummyProofSource() {}
+  ~DummyProofSource() override {}
+
+  // ProofSource override.
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& /*server_config*/,
+                QuicTransportVersion /*transport_version*/,
+                absl::string_view /*chlo_hash*/,
+                std::unique_ptr<Callback> callback) override {
+    bool cert_matched_sni;
+    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+        GetCertChain(server_address, client_address, hostname,
+                     &cert_matched_sni);
+    QuicCryptoProof proof;
+    proof.signature = "Dummy signature";
+    proof.leaf_cert_scts = "Dummy timestamp";
+    proof.cert_matched_sni = cert_matched_sni;
+    callback->Run(true, chain, proof, /*details=*/nullptr);
+  }
+
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& /*server_address*/,
+      const QuicSocketAddress& /*client_address*/,
+      const std::string& /*hostname*/, bool* /*cert_matched_sni*/) override {
+    std::vector<std::string> certs;
+    certs.push_back("Dummy cert");
+    return quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
+        new ProofSource::Chain(certs));
+  }
+
+  void ComputeTlsSignature(
+      const QuicSocketAddress& /*server_address*/,
+      const QuicSocketAddress& /*client_address*/,
+      const std::string& /*hostname*/,
+      uint16_t /*signature_algorit*/,
+      absl::string_view /*in*/,
+      std::unique_ptr<SignatureCallback> callback) override {
+    callback->Run(true, "Dummy signature", /*details=*/nullptr);
+  }
+
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override {
+    return {};
+  }
+
+  TicketCrypter* GetTicketCrypter() override { return nullptr; }
+};
+
+class Handshaker : public QuicCryptoClientHandshaker {
+ public:
+  Handshaker(const QuicServerId& server_id,
+             QuicCryptoClientStream* stream,
+             QuicSession* session,
+             std::unique_ptr<ProofVerifyContext> verify_context,
+             QuicCryptoClientConfig* crypto_config,
+             QuicCryptoClientStream::ProofHandler* proof_handler)
+      : QuicCryptoClientHandshaker(server_id,
+                                   stream,
+                                   session,
+                                   std::move(verify_context),
+                                   crypto_config,
+                                   proof_handler) {}
+
+  void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
+    QuicCryptoClientHandshaker::DoSendCHLO(cached);
+  }
+};
+
+class QuicCryptoClientHandshakerTest
+    : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicCryptoClientHandshakerTest()
+      : version_(GetParam()),
+        proof_handler_(),
+        helper_(),
+        alarm_factory_(),
+        server_id_("host", 123),
+        connection_(new test::MockQuicConnection(&helper_,
+                                                 &alarm_factory_,
+                                                 Perspective::IS_CLIENT,
+                                                 {version_})),
+        session_(connection_, false),
+        crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
+        client_stream_(
+            new QuicCryptoClientStream(server_id_,
+                                       &session_,
+                                       nullptr,
+                                       &crypto_client_config_,
+                                       &proof_handler_,
+                                       /*has_application_state = */ false)),
+        handshaker_(server_id_,
+                    client_stream_,
+                    &session_,
+                    nullptr,
+                    &crypto_client_config_,
+                    &proof_handler_),
+        state_() {
+    // Session takes the ownership of the client stream! (but handshaker also
+    // takes a reference to it, but doesn't take the ownership).
+    session_.SetCryptoStream(client_stream_);
+    session_.Initialize();
+  }
+
+  void InitializeServerParametersToEnableFullHello() {
+    QuicCryptoServerConfig::ConfigOptions options;
+    QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
+        helper_.GetRandomGenerator(), helper_.GetClock(), options);
+    state_.Initialize(
+        config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
+        "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
+        helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
+
+    state_.SetProofValid();
+  }
+
+  ParsedQuicVersion version_;
+  TestProofHandler proof_handler_;
+  test::MockQuicConnectionHelper helper_;
+  test::MockAlarmFactory alarm_factory_;
+  QuicServerId server_id_;
+  // Session takes the ownership of the connection.
+  test::MockQuicConnection* connection_;
+  test::MockQuicSession session_;
+  QuicCryptoClientConfig crypto_client_config_;
+  QuicCryptoClientStream* client_stream_;
+  Handshaker handshaker_;
+  QuicCryptoClientConfig::CachedState state_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicCryptoClientHandshakerTests,
+    QuicCryptoClientHandshakerTest,
+    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
+    ::testing::PrintToStringParamName());
+
+TEST_P(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
+  handshaker_.DoSendCHLOTest(&state_);
+
+  EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
+}
+
+TEST_P(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
+  crypto_client_config_.set_pad_inchoate_hello(false);
+  handshaker_.DoSendCHLOTest(&state_);
+  EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
+}
+
+TEST_P(QuicCryptoClientHandshakerTest,
+       TestPaddingInFullHelloEvenIfInchoateDisabled) {
+  // Disable inchoate, but full hello should still be padded.
+  crypto_client_config_.set_pad_inchoate_hello(false);
+
+  InitializeServerParametersToEnableFullHello();
+
+  handshaker_.DoSendCHLOTest(&state_);
+  EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
+}
+
+TEST_P(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
+  crypto_client_config_.set_pad_full_hello(false);
+
+  InitializeServerParametersToEnableFullHello();
+
+  handshaker_.DoSendCHLOTest(&state_);
+  EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_stream.cc b/quiche/quic/core/quic_crypto_client_stream.cc
new file mode 100644
index 0000000..f9339dc
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_stream.cc
@@ -0,0 +1,169 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_crypto_client_handshaker.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+const int QuicCryptoClientStream::kMaxClientHellos;
+
+QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(QuicSession* session)
+    : QuicCryptoStream(session) {}
+
+QuicCryptoClientStream::QuicCryptoClientStream(
+    const QuicServerId& server_id,
+    QuicSession* session,
+    std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    ProofHandler* proof_handler,
+    bool has_application_state)
+    : QuicCryptoClientStreamBase(session) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT,
+                   session->connection()->perspective());
+  switch (session->connection()->version().handshake_protocol) {
+    case PROTOCOL_QUIC_CRYPTO:
+      handshaker_ = std::make_unique<QuicCryptoClientHandshaker>(
+          server_id, this, session, std::move(verify_context), crypto_config,
+          proof_handler);
+      break;
+    case PROTOCOL_TLS1_3: {
+      auto handshaker = std::make_unique<TlsClientHandshaker>(
+          server_id, this, session, std::move(verify_context), crypto_config,
+          proof_handler, has_application_state);
+      tls_handshaker_ = handshaker.get();
+      handshaker_ = std::move(handshaker);
+      break;
+    }
+    case PROTOCOL_UNSUPPORTED:
+      QUIC_BUG(quic_bug_10296_1)
+          << "Attempting to create QuicCryptoClientStream for unknown "
+             "handshake protocol";
+  }
+}
+
+QuicCryptoClientStream::~QuicCryptoClientStream() {}
+
+bool QuicCryptoClientStream::CryptoConnect() {
+  return handshaker_->CryptoConnect();
+}
+
+int QuicCryptoClientStream::num_sent_client_hellos() const {
+  return handshaker_->num_sent_client_hellos();
+}
+
+bool QuicCryptoClientStream::IsResumption() const {
+  return handshaker_->IsResumption();
+}
+
+bool QuicCryptoClientStream::EarlyDataAccepted() const {
+  return handshaker_->EarlyDataAccepted();
+}
+
+ssl_early_data_reason_t QuicCryptoClientStream::EarlyDataReason() const {
+  return handshaker_->EarlyDataReason();
+}
+
+bool QuicCryptoClientStream::ReceivedInchoateReject() const {
+  return handshaker_->ReceivedInchoateReject();
+}
+
+int QuicCryptoClientStream::num_scup_messages_received() const {
+  return handshaker_->num_scup_messages_received();
+}
+
+bool QuicCryptoClientStream::encryption_established() const {
+  return handshaker_->encryption_established();
+}
+
+bool QuicCryptoClientStream::one_rtt_keys_available() const {
+  return handshaker_->one_rtt_keys_available();
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoClientStream::crypto_negotiated_params() const {
+  return handshaker_->crypto_negotiated_params();
+}
+
+CryptoMessageParser* QuicCryptoClientStream::crypto_message_parser() {
+  return handshaker_->crypto_message_parser();
+}
+
+HandshakeState QuicCryptoClientStream::GetHandshakeState() const {
+  return handshaker_->GetHandshakeState();
+}
+
+size_t QuicCryptoClientStream::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return handshaker_->BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicCryptoClientStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return handshaker_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter>
+QuicCryptoClientStream::CreateCurrentOneRttEncrypter() {
+  return handshaker_->CreateCurrentOneRttEncrypter();
+}
+
+bool QuicCryptoClientStream::ExportKeyingMaterial(absl::string_view label,
+                                                  absl::string_view context,
+                                                  size_t result_len,
+                                                  std::string* result) {
+  return handshaker_->ExportKeyingMaterial(label, context, result_len, result);
+}
+
+std::string QuicCryptoClientStream::chlo_hash() const {
+  return handshaker_->chlo_hash();
+}
+
+void QuicCryptoClientStream::OnOneRttPacketAcknowledged() {
+  handshaker_->OnOneRttPacketAcknowledged();
+}
+
+void QuicCryptoClientStream::OnHandshakePacketSent() {
+  handshaker_->OnHandshakePacketSent();
+}
+
+void QuicCryptoClientStream::OnConnectionClosed(QuicErrorCode error,
+                                                ConnectionCloseSource source) {
+  handshaker_->OnConnectionClosed(error, source);
+}
+
+void QuicCryptoClientStream::OnHandshakeDoneReceived() {
+  handshaker_->OnHandshakeDoneReceived();
+}
+
+void QuicCryptoClientStream::OnNewTokenReceived(absl::string_view token) {
+  handshaker_->OnNewTokenReceived(token);
+}
+
+void QuicCryptoClientStream::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> application_state) {
+  handshaker_->SetServerApplicationStateForResumption(
+      std::move(application_state));
+}
+
+SSL* QuicCryptoClientStream::GetSsl() const {
+  return tls_handshaker_ == nullptr ? nullptr : tls_handshaker_->ssl();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_client_stream.h b/quiche/quic/core/quic_crypto_client_stream.h
new file mode 100644
index 0000000..64b110c
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_stream.h
@@ -0,0 +1,307 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicCryptoClientStreamPeer;
+}  // namespace test
+
+class TlsClientHandshaker;
+
+class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
+ public:
+  explicit QuicCryptoClientStreamBase(QuicSession* session);
+
+  ~QuicCryptoClientStreamBase() override {}
+
+  // Performs a crypto handshake with the server. Returns true if the connection
+  // is still connected.
+  virtual bool CryptoConnect() = 0;
+
+  // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
+  // ReceivedInchoateReject instead.
+  //
+  // num_sent_client_hellos returns the number of client hello messages that
+  // have been sent. If the handshake has completed then this is one greater
+  // than the number of round-trips needed for the handshake.
+  virtual int num_sent_client_hellos() const = 0;
+
+  // Returns true if the handshake performed was a resumption instead of a full
+  // handshake. Resumption only makes sense for TLS handshakes - there is no
+  // concept of resumption for QUIC crypto even though it supports a 0-RTT
+  // handshake. This function only returns valid results once the handshake is
+  // complete.
+  virtual bool IsResumption() const = 0;
+
+  // Returns true if early data (0-RTT) was accepted in the connection.
+  virtual bool EarlyDataAccepted() const = 0;
+
+  // Returns true if the client received an inchoate REJ during the handshake,
+  // extending the handshake by one round trip. This only applies for QUIC
+  // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
+  // but that is handled at the connection layer instead of the crypto layer.
+  virtual bool ReceivedInchoateReject() const = 0;
+
+  // The number of server config update messages received by the
+  // client.  Does not count update messages that were received prior
+  // to handshake confirmation.
+  virtual int num_scup_messages_received() const = 0;
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_params*/) const override {
+    QUICHE_DCHECK(false);
+    return "";
+  }
+
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    QUICHE_DCHECK(false);
+    return nullptr;
+  }
+
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {
+    QUICHE_DCHECK(false);
+  }
+};
+
+class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
+    : public QuicCryptoClientStreamBase {
+ public:
+  // kMaxClientHellos is the maximum number of times that we'll send a client
+  // hello. The value 4 accounts for:
+  //   * One failure due to an incorrect or missing source-address token.
+  //   * One failure due the server's certificate chain being unavailible and
+  //     the server being unwilling to send it without a valid source-address
+  //     token.
+  //   * One failure due to the ServerConfig private key being located on a
+  //     remote oracle which has become unavailable, forcing the server to send
+  //     the client a fallback ServerConfig.
+  static const int kMaxClientHellos = 4;
+
+  // QuicCryptoClientStream creates a HandshakerInterface at construction time
+  // based on the QuicTransportVersion of the connection. Different
+  // HandshakerInterfaces provide implementations of different crypto handshake
+  // protocols. Currently QUIC crypto is the only protocol implemented; a future
+  // HandshakerInterface will use TLS as the handshake protocol.
+  // QuicCryptoClientStream delegates all of its public methods to its
+  // HandshakerInterface.
+  //
+  // This setup of the crypto stream delegating its implementation to the
+  // handshaker results in the handshaker reading and writing bytes on the
+  // crypto stream, instead of the handshaker passing the stream bytes to send.
+  class QUIC_EXPORT_PRIVATE HandshakerInterface {
+   public:
+    virtual ~HandshakerInterface() {}
+
+    // Performs a crypto handshake with the server. Returns true if the
+    // connection is still connected.
+    virtual bool CryptoConnect() = 0;
+
+    // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
+    // ReceivedInchoateReject instead.
+    //
+    // num_sent_client_hellos returns the number of client hello messages that
+    // have been sent. If the handshake has completed then this is one greater
+    // than the number of round-trips needed for the handshake.
+    virtual int num_sent_client_hellos() const = 0;
+
+    // Returns true if the handshake performed was a resumption instead of a
+    // full handshake. Resumption only makes sense for TLS handshakes - there is
+    // no concept of resumption for QUIC crypto even though it supports a 0-RTT
+    // handshake. This function only returns valid results once the handshake is
+    // complete.
+    virtual bool IsResumption() const = 0;
+
+    // Returns true if early data (0-RTT) was accepted in the connection.
+    virtual bool EarlyDataAccepted() const = 0;
+
+    // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
+    // rejected.
+    virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
+
+    // Returns true if the client received an inchoate REJ during the handshake,
+    // extending the handshake by one round trip. This only applies for QUIC
+    // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
+    // but that is handled at the connection layer instead of the crypto layer.
+    virtual bool ReceivedInchoateReject() const = 0;
+
+    // The number of server config update messages received by the
+    // client.  Does not count update messages that were received prior
+    // to handshake confirmation.
+    virtual int num_scup_messages_received() const = 0;
+
+    virtual std::string chlo_hash() const = 0;
+
+    // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
+    // for the connection.
+    virtual bool encryption_established() const = 0;
+
+    // Returns true once 1RTT keys are available.
+    virtual bool one_rtt_keys_available() const = 0;
+
+    // Returns the parameters negotiated in the crypto handshake.
+    virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+        const = 0;
+
+    // Used by QuicCryptoStream to parse data received on this stream.
+    virtual CryptoMessageParser* crypto_message_parser() = 0;
+
+    // Used by QuicCryptoStream to know how much unprocessed data can be
+    // buffered at each encryption level.
+    virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
+
+    // Called to generate a decrypter for the next key phase. Each call should
+    // generate the key for phase n+1.
+    virtual std::unique_ptr<QuicDecrypter>
+    AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+    // Called to generate an encrypter for the same key phase of the last
+    // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
+    virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+
+    // Returns current handshake state.
+    virtual HandshakeState GetHandshakeState() const = 0;
+
+    // Called when a 1RTT packet has been acknowledged.
+    virtual void OnOneRttPacketAcknowledged() = 0;
+
+    // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+    virtual void OnHandshakePacketSent() = 0;
+
+    // Called when connection gets closed.
+    virtual void OnConnectionClosed(QuicErrorCode error,
+                                    ConnectionCloseSource source) = 0;
+
+    // Called when handshake done has been received.
+    virtual void OnHandshakeDoneReceived() = 0;
+
+    // Called when new token has been received.
+    virtual void OnNewTokenReceived(absl::string_view token) = 0;
+
+    // Called when application state is received.
+    virtual void SetServerApplicationStateForResumption(
+        std::unique_ptr<ApplicationState> application_state) = 0;
+
+    // Called to obtain keying material export of length |result_len| with the
+    // given |label| and |context|. Returns false on failure.
+    virtual bool ExportKeyingMaterial(absl::string_view label,
+                                      absl::string_view context,
+                                      size_t result_len,
+                                      std::string* result) = 0;
+  };
+
+  // ProofHandler is an interface that handles callbacks from the crypto
+  // stream when the client has proof verification details of the server.
+  class QUIC_EXPORT_PRIVATE ProofHandler {
+   public:
+    virtual ~ProofHandler() {}
+
+    // Called when the proof in |cached| is marked valid.  If this is a secure
+    // QUIC session, then this will happen only after the proof verifier
+    // completes.
+    virtual void OnProofValid(
+        const QuicCryptoClientConfig::CachedState& cached) = 0;
+
+    // Called when proof verification details become available, either because
+    // proof verification is complete, or when cached details are used. This
+    // will only be called for secure QUIC connections.
+    virtual void OnProofVerifyDetailsAvailable(
+        const ProofVerifyDetails& verify_details) = 0;
+  };
+
+  QuicCryptoClientStream(const QuicServerId& server_id,
+                         QuicSession* session,
+                         std::unique_ptr<ProofVerifyContext> verify_context,
+                         QuicCryptoClientConfig* crypto_config,
+                         ProofHandler* proof_handler,
+                         bool has_application_state);
+  QuicCryptoClientStream(const QuicCryptoClientStream&) = delete;
+  QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete;
+
+  ~QuicCryptoClientStream() override;
+
+  // From QuicCryptoClientStreamBase
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  bool IsResumption() const override;
+  bool EarlyDataAccepted() const override;
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool ReceivedInchoateReject() const override;
+
+  int num_scup_messages_received() const override;
+
+  // From QuicCryptoStream
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override;
+  void OnHandshakePacketSent() override;
+  void OnConnectionClosed(QuicErrorCode error,
+                          ConnectionCloseSource source) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  HandshakeState GetHandshakeState() const override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> application_state) override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  SSL* GetSsl() const override;
+  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
+                            size_t result_len, std::string* result) override;
+  std::string chlo_hash() const;
+
+ protected:
+  void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) {
+    handshaker_ = std::move(handshaker);
+  }
+
+ private:
+  friend class test::QuicCryptoClientStreamPeer;
+  std::unique_ptr<HandshakerInterface> handshaker_;
+  // Points to |handshaker_| if it uses TLS1.3. Otherwise, nullptr.
+  // TODO(danzh) change the type of |handshaker_| to TlsClientHandshaker after
+  // deprecating Google QUIC.
+  TlsClientHandshaker* tls_handshaker_{nullptr};
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
diff --git a/quiche/quic/core/quic_crypto_client_stream_test.cc b/quiche/quic/core/quic_crypto_client_stream_test.cc
new file mode 100644
index 0000000..377f7a2
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_client_stream_test.cc
@@ -0,0 +1,371 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+// This test tests the client-side of the QUIC crypto handshake. It does not
+// test the TLS handshake - that is in tls_client_handshaker_test.cc.
+class QuicCryptoClientStreamTest : public QuicTest {
+ public:
+  QuicCryptoClientStreamTest()
+      : supported_versions_(AllSupportedVersionsWithQuicCrypto()),
+        server_id_(kServerHostname, kServerPort, false),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+                       std::make_unique<test::SimpleSessionCache>()),
+        server_crypto_config_(
+            crypto_test_utils::CryptoServerConfigForTesting()) {
+    CreateConnection();
+  }
+
+  void CreateSession() {
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        connection_, DefaultQuicConfig(), supported_versions_, server_id_,
+        &crypto_config_);
+    EXPECT_CALL(*session_, GetAlpnsToOffer())
+        .WillRepeatedly(testing::Return(std::vector<std::string>(
+            {AlpnForVersion(connection_->version())})));
+  }
+
+  void CreateConnection() {
+    connection_ =
+        new PacketSavingConnection(&client_helper_, &alarm_factory_,
+                                   Perspective::IS_CLIENT, supported_versions_);
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    CreateSession();
+  }
+
+  void CompleteCryptoHandshake() {
+    int proof_verify_details_calls = 1;
+    if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
+      EXPECT_CALL(*session_, OnProofValid(testing::_))
+          .Times(testing::AtLeast(1));
+      proof_verify_details_calls = 0;
+    }
+    EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
+        .Times(testing::AtLeast(proof_verify_details_calls));
+    stream()->CryptoConnect();
+    QuicConfig config;
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+        connection_, stream(), AlpnForVersion(connection_->version()));
+  }
+
+  QuicCryptoClientStream* stream() {
+    return session_->GetMutableCryptoStream();
+  }
+
+  MockQuicConnectionHelper server_helper_;
+  MockQuicConnectionHelper client_helper_;
+  MockAlarmFactory alarm_factory_;
+  PacketSavingConnection* connection_;
+  ParsedQuicVersionVector supported_versions_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicServerId server_id_;
+  CryptoHandshakeMessage message_;
+  QuicCryptoClientConfig crypto_config_;
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+};
+
+TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
+  EXPECT_FALSE(stream()->encryption_established());
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
+  CompleteCryptoHandshake();
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_no_session_offered);
+}
+
+TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
+  CompleteCryptoHandshake();
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
+  message_.set_tag(kCHLO);
+  crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
+                                                  Perspective::IS_CLIENT);
+}
+
+TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
+  stream()->CryptoConnect();
+
+  message_.set_tag(kCHLO);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                            "Expected REJ", _));
+  crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
+                                                  Perspective::IS_CLIENT);
+}
+
+TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
+  CompleteCryptoHandshake();
+
+  const QuicConfig* config = session_->config();
+  EXPECT_EQ(kMaximumIdleTimeoutSecs, config->IdleNetworkTimeout().ToSeconds());
+
+  const QuicCryptoNegotiatedParameters& crypto_params(
+      stream()->crypto_negotiated_params());
+  EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
+  EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
+}
+
+TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
+  // Seed the config with a cached server config.
+  CompleteCryptoHandshake();
+
+  // Recreate connection with the new config.
+  CreateConnection();
+
+  // Advance time 5 years to ensure that we pass the expiry time of the cached
+  // server config.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
+
+  EXPECT_CALL(*session_, OnProofValid(testing::_));
+  stream()->CryptoConnect();
+  // Check that a client hello was sent.
+  ASSERT_EQ(1u, connection_->encrypted_packets_.size());
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ClientTurnedOffZeroRtt) {
+  // Seed the config with a cached server config.
+  CompleteCryptoHandshake();
+
+  // Recreate connection with the new config.
+  CreateConnection();
+
+  // Set connection option.
+  QuicTagVector options;
+  options.push_back(kQNZ2);
+  session_->config()->SetClientConnectionOptions(options);
+
+  CompleteCryptoHandshake();
+  // Check that two client hellos were sent, one inchoate and one normal.
+  EXPECT_EQ(2, stream()->num_sent_client_hellos());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_disabled);
+}
+
+TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
+  // Test that if the client's clock is skewed with respect to the server,
+  // the handshake succeeds. In the past, the client would get the server
+  // config, notice that it had already expired and then close the connection.
+
+  // Advance time 5 years to ensure that we pass the expiry time in the server
+  // config, but the TTL is used instead.
+  connection_->AdvanceTime(
+      QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
+
+  // The handshakes completes!
+  CompleteCryptoHandshake();
+}
+
+TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
+  // Seed the config with a cached server config.
+  CompleteCryptoHandshake();
+
+  // Recreate connection with the new config.
+  CreateConnection();
+
+  QuicCryptoClientConfig::CachedState* state =
+      crypto_config_.LookupOrCreate(server_id_);
+
+  std::vector<std::string> certs = state->certs();
+  std::string cert_sct = state->cert_sct();
+  std::string signature = state->signature();
+  std::string chlo_hash = state->chlo_hash();
+  state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
+
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
+      .Times(testing::AnyNumber());
+  stream()->CryptoConnect();
+  // Check that a client hello was sent.
+  ASSERT_EQ(1u, connection_->encrypted_packets_.size());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
+  // Test that the crypto client stream can receive server config updates after
+  // the connection has been established.
+  CompleteCryptoHandshake();
+
+  QuicCryptoClientConfig::CachedState* state =
+      crypto_config_.LookupOrCreate(server_id_);
+
+  // Ensure cached STK is different to what we send in the handshake.
+  EXPECT_NE("xstk", state->source_address_token());
+
+  // Initialize using {...} syntax to avoid trailing \0 if converting from
+  // string.
+  unsigned char stk[] = {'x', 's', 't', 'k'};
+
+  // Minimum SCFG that passes config validation checks.
+  unsigned char scfg[] = {// SCFG
+                          0x53, 0x43, 0x46, 0x47,
+                          // num entries
+                          0x01, 0x00,
+                          // padding
+                          0x00, 0x00,
+                          // EXPY
+                          0x45, 0x58, 0x50, 0x59,
+                          // EXPY end offset
+                          0x08, 0x00, 0x00, 0x00,
+                          // Value
+                          '1', '2', '3', '4', '5', '6', '7', '8'};
+
+  CryptoHandshakeMessage server_config_update;
+  server_config_update.set_tag(kSCUP);
+  server_config_update.SetValue(kSourceAddressTokenTag, stk);
+  server_config_update.SetValue(kSCFG, scfg);
+  const uint64_t expiry_seconds = 60 * 60 * 24 * 2;
+  server_config_update.SetValue(kSTTL, expiry_seconds);
+
+  crypto_test_utils::SendHandshakeMessageToStream(
+      stream(), server_config_update, Perspective::IS_SERVER);
+
+  // Make sure that the STK and SCFG are cached correctly.
+  EXPECT_EQ("xstk", state->source_address_token());
+
+  const std::string& cached_scfg = state->server_config();
+  quiche::test::CompareCharArraysWithHexError(
+      "scfg", cached_scfg.data(), cached_scfg.length(),
+      reinterpret_cast<char*>(scfg), ABSL_ARRAYSIZE(scfg));
+
+  QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+}
+
+TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
+  // Test that the crypto client stream can receive and use server config
+  // updates with certificates after the connection has been established.
+  CompleteCryptoHandshake();
+
+  // Build a server config update message with certificates
+  QuicCryptoServerConfig crypto_config(
+      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+      crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
+  crypto_test_utils::SetupCryptoServerConfigForTest(
+      connection_->clock(), QuicRandom::GetInstance(), &crypto_config);
+  SourceAddressTokens tokens;
+  QuicCompressedCertsCache cache(1);
+  CachedNetworkParameters network_params;
+  CryptoHandshakeMessage server_config_update;
+
+  class Callback : public BuildServerConfigUpdateMessageResultCallback {
+   public:
+    Callback(bool* ok, CryptoHandshakeMessage* message)
+        : ok_(ok), message_(message) {}
+    void Run(bool ok, const CryptoHandshakeMessage& message) override {
+      *ok_ = ok;
+      *message_ = message;
+    }
+
+   private:
+    bool* ok_;
+    CryptoHandshakeMessage* message_;
+  };
+
+  // Note: relies on the callback being invoked synchronously
+  bool ok = false;
+  crypto_config.BuildServerConfigUpdateMessage(
+      session_->transport_version(), stream()->chlo_hash(), tokens,
+      QuicSocketAddress(QuicIpAddress::Loopback6(), 1234),
+      QuicSocketAddress(QuicIpAddress::Loopback6(), 4321), connection_->clock(),
+      QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(),
+      &network_params,
+      std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>(
+          new Callback(&ok, &server_config_update)));
+  EXPECT_TRUE(ok);
+
+  EXPECT_CALL(*session_, OnProofValid(testing::_));
+  crypto_test_utils::SendHandshakeMessageToStream(
+      stream(), server_config_update, Perspective::IS_SERVER);
+
+  // Recreate connection with the new config and verify a 0-RTT attempt.
+  CreateConnection();
+
+  EXPECT_CALL(*session_, OnProofValid(testing::_));
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
+      .Times(testing::AnyNumber());
+  stream()->CryptoConnect();
+  EXPECT_TRUE(session_->IsEncryptionEstablished());
+}
+
+TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
+  CryptoHandshakeMessage server_config_update;
+  server_config_update.set_tag(kSCUP);
+  crypto_test_utils::SendHandshakeMessageToStream(
+      stream(), server_config_update, Perspective::IS_SERVER);
+}
+
+TEST_F(QuicCryptoClientStreamTest, PreferredVersion) {
+  // This mimics the case where client receives version negotiation packet, such
+  // that, the preferred version is different from the packets' version.
+  connection_ = new PacketSavingConnection(
+      &client_helper_, &alarm_factory_, Perspective::IS_CLIENT,
+      ParsedVersionOfIndex(supported_versions_, 1));
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  CreateSession();
+  CompleteCryptoHandshake();
+  // 2 CHLOs are sent.
+  ASSERT_EQ(2u, session_->sent_crypto_handshake_messages().size());
+  // Verify preferred version is the highest version that session supports, and
+  // is different from connection's version.
+  QuicVersionLabel client_version_label;
+  EXPECT_THAT(session_->sent_crypto_handshake_messages()[0].GetVersionLabel(
+                  kVER, &client_version_label),
+              IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
+            client_version_label);
+  EXPECT_THAT(session_->sent_crypto_handshake_messages()[1].GetVersionLabel(
+                  kVER, &client_version_label),
+              IsQuicNoError());
+  EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
+            client_version_label);
+  EXPECT_NE(CreateQuicVersionLabel(connection_->version()),
+            client_version_label);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_handshaker.cc b/quiche/quic/core/quic_crypto_handshaker.cc
new file mode 100644
index 0000000..57c7035
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_handshaker.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+
+#include "quiche/quic/core/quic_session.h"
+
+namespace quic {
+
+#define ENDPOINT \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicCryptoHandshaker::QuicCryptoHandshaker(QuicCryptoStream* stream,
+                                           QuicSession* session)
+    : stream_(stream), session_(session), last_sent_handshake_message_tag_(0) {
+  crypto_framer_.set_visitor(this);
+}
+
+QuicCryptoHandshaker::~QuicCryptoHandshaker() {}
+
+void QuicCryptoHandshaker::SendHandshakeMessage(
+    const CryptoHandshakeMessage& message,
+    EncryptionLevel level) {
+  QUIC_DVLOG(1) << ENDPOINT << "Sending " << message.DebugString();
+  session()->NeuterUnencryptedData();
+  session()->OnCryptoHandshakeMessageSent(message);
+  last_sent_handshake_message_tag_ = message.tag();
+  const QuicData& data = message.GetSerialized();
+  stream_->WriteCryptoData(level, data.AsStringPiece());
+}
+
+void QuicCryptoHandshaker::OnError(CryptoFramer* framer) {
+  QUIC_DLOG(WARNING) << "Error processing crypto data: "
+                     << QuicErrorCodeToString(framer->error());
+}
+
+void QuicCryptoHandshaker::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received " << message.DebugString();
+  session()->OnCryptoHandshakeMessageReceived(message);
+}
+
+CryptoMessageParser* QuicCryptoHandshaker::crypto_message_parser() {
+  return &crypto_framer_;
+}
+
+size_t QuicCryptoHandshaker::BufferSizeLimitForLevel(EncryptionLevel) const {
+  return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_handshaker.h b/quiche/quic/core/quic_crypto_handshaker.h
new file mode 100644
index 0000000..526dbd5
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_handshaker.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
+
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicCryptoHandshaker
+    : public CryptoFramerVisitorInterface {
+ public:
+  QuicCryptoHandshaker(QuicCryptoStream* stream, QuicSession* session);
+  QuicCryptoHandshaker(const QuicCryptoHandshaker&) = delete;
+  QuicCryptoHandshaker& operator=(const QuicCryptoHandshaker&) = delete;
+
+  ~QuicCryptoHandshaker() override;
+
+  // Sends |message| to the peer.
+  // TODO(wtc): return a success/failure status.
+  void SendHandshakeMessage(const CryptoHandshakeMessage& message,
+                            EncryptionLevel level);
+
+  void OnError(CryptoFramer* framer) override;
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+  CryptoMessageParser* crypto_message_parser();
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
+
+ protected:
+  QuicTag last_sent_handshake_message_tag() const {
+    return last_sent_handshake_message_tag_;
+  }
+
+ private:
+  QuicSession* session() { return session_; }
+
+  QuicCryptoStream* stream_;
+  QuicSession* session_;
+
+  CryptoFramer crypto_framer_;
+
+  // Records last sent crypto handshake message tag.
+  QuicTag last_sent_handshake_message_tag_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_HANDSHAKER_H_
diff --git a/quiche/quic/core/quic_crypto_server_stream.cc b/quiche/quic/core/quic_crypto_server_stream.cc
new file mode 100644
index 0000000..8cefbb5
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream.cc
@@ -0,0 +1,538 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_server_stream.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+class QuicCryptoServerStream::ProcessClientHelloCallback
+    : public ProcessClientHelloResultCallback {
+ public:
+  ProcessClientHelloCallback(
+      QuicCryptoServerStream* parent,
+      const quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>& result)
+      : parent_(parent), result_(result) {}
+
+  void Run(
+      QuicErrorCode error,
+      const std::string& error_details,
+      std::unique_ptr<CryptoHandshakeMessage> message,
+      std::unique_ptr<DiversificationNonce> diversification_nonce,
+      std::unique_ptr<ProofSource::Details> proof_source_details) override {
+    if (parent_ == nullptr) {
+      return;
+    }
+
+    parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
+        *result_, error, error_details, std::move(message),
+        std::move(diversification_nonce), std::move(proof_source_details));
+  }
+
+  void Cancel() { parent_ = nullptr; }
+
+ private:
+  QuicCryptoServerStream* parent_;
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result_;
+};
+
+QuicCryptoServerStream::QuicCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSession* session,
+    QuicCryptoServerStreamBase::Helper* helper)
+    : QuicCryptoServerStreamBase(session),
+      QuicCryptoHandshaker(this, session),
+      session_(session),
+      delegate_(session),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(compressed_certs_cache),
+      signed_config_(new QuicSignedServerConfig),
+      helper_(helper),
+      num_handshake_messages_(0),
+      num_handshake_messages_with_server_nonces_(0),
+      send_server_config_update_cb_(nullptr),
+      num_server_config_update_messages_sent_(0),
+      zero_rtt_attempted_(false),
+      chlo_packet_size_(0),
+      validate_client_hello_cb_(nullptr),
+      process_client_hello_cb_(nullptr),
+      encryption_established_(false),
+      one_rtt_keys_available_(false),
+      one_rtt_packet_decrypted_(false),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
+
+QuicCryptoServerStream::~QuicCryptoServerStream() {
+  CancelOutstandingCallbacks();
+}
+
+void QuicCryptoServerStream::CancelOutstandingCallbacks() {
+  // Detach from the validation callback.  Calling this multiple times is safe.
+  if (validate_client_hello_cb_ != nullptr) {
+    validate_client_hello_cb_->Cancel();
+    validate_client_hello_cb_ = nullptr;
+  }
+  if (send_server_config_update_cb_ != nullptr) {
+    send_server_config_update_cb_->Cancel();
+    send_server_config_update_cb_ = nullptr;
+  }
+  if (process_client_hello_cb_ != nullptr) {
+    process_client_hello_cb_->Cancel();
+    process_client_hello_cb_ = nullptr;
+  }
+}
+
+void QuicCryptoServerStream::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QuicCryptoHandshaker::OnHandshakeMessage(message);
+  ++num_handshake_messages_;
+  chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
+
+  // Do not process handshake messages after the handshake is confirmed.
+  if (one_rtt_keys_available_) {
+    OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+                         "Unexpected handshake message from client");
+    return;
+  }
+
+  if (message.tag() != kCHLO) {
+    OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                         "Handshake packet not CHLO");
+    return;
+  }
+
+  if (validate_client_hello_cb_ != nullptr ||
+      process_client_hello_cb_ != nullptr) {
+    // Already processing some other handshake message.  The protocol
+    // does not allow for clients to send multiple handshake messages
+    // before the server has a chance to respond.
+    OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
+                         "Unexpected handshake message while processing CHLO");
+    return;
+  }
+
+  chlo_hash_ =
+      CryptoUtils::HashHandshakeMessage(message, Perspective::IS_SERVER);
+
+  std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
+  QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
+  QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
+  validate_client_hello_cb_ = cb.get();
+  crypto_config_->ValidateClientHello(
+      message, GetClientAddress(), session()->connection()->self_address(),
+      transport_version(), session()->connection()->clock(), signed_config_,
+      std::move(cb));
+}
+
+void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        result,
+    std::unique_ptr<ProofSource::Details> details) {
+  // Clear the callback that got us here.
+  QUICHE_DCHECK(validate_client_hello_cb_ != nullptr);
+  QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
+  validate_client_hello_cb_ = nullptr;
+
+  std::unique_ptr<ProcessClientHelloCallback> cb(
+      new ProcessClientHelloCallback(this, result));
+  process_client_hello_cb_ = cb.get();
+  ProcessClientHello(result, std::move(details), std::move(cb));
+}
+
+void QuicCryptoServerStream::
+    FinishProcessingHandshakeMessageAfterProcessClientHello(
+        const ValidateClientHelloResultCallback::Result& result,
+        QuicErrorCode error,
+        const std::string& error_details,
+        std::unique_ptr<CryptoHandshakeMessage> reply,
+        std::unique_ptr<DiversificationNonce> diversification_nonce,
+        std::unique_ptr<ProofSource::Details> proof_source_details) {
+  // Clear the callback that got us here.
+  QUICHE_DCHECK(process_client_hello_cb_ != nullptr);
+  QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
+  process_client_hello_cb_ = nullptr;
+  proof_source_details_ = std::move(proof_source_details);
+
+  AdjustTestValue("quic::QuicCryptoServerStream::after_process_client_hello",
+                  session());
+
+  if (!session()->connection()->connected()) {
+    QUIC_CODE_COUNT(quic_crypto_disconnected_after_process_client_hello);
+    QUIC_LOG_FIRST_N(INFO, 10)
+        << "After processing CHLO, QUIC connection has been closed with code "
+        << session()->error() << ", details: " << session()->error_details();
+    return;
+  }
+
+  const CryptoHandshakeMessage& message = result.client_hello;
+  if (error != QUIC_NO_ERROR) {
+    OnUnrecoverableError(error, error_details);
+    return;
+  }
+
+  if (reply->tag() != kSHLO) {
+    session()->connection()->set_fully_pad_crypto_handshake_packets(
+        crypto_config_->pad_rej());
+    // Send REJ in plaintext.
+    SendHandshakeMessage(*reply, ENCRYPTION_INITIAL);
+    return;
+  }
+
+  // If we are returning a SHLO then we accepted the handshake.  Now
+  // process the negotiated configuration options as part of the
+  // session config.
+  QuicConfig* config = session()->config();
+  OverrideQuicConfigDefaults(config);
+  std::string process_error_details;
+  const QuicErrorCode process_error =
+      config->ProcessPeerHello(message, CLIENT, &process_error_details);
+  if (process_error != QUIC_NO_ERROR) {
+    OnUnrecoverableError(process_error, process_error_details);
+    return;
+  }
+
+  session()->OnConfigNegotiated();
+
+  config->ToHandshakeMessage(reply.get(), session()->transport_version());
+
+  // Receiving a full CHLO implies the client is prepared to decrypt with
+  // the new server write key.  We can start to encrypt with the new server
+  // write key.
+  //
+  // NOTE: the SHLO will be encrypted with the new server write key.
+  delegate_->OnNewEncryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(
+      ENCRYPTION_ZERO_RTT,
+      std::move(crypto_negotiated_params_->initial_crypters.decrypter),
+      /*set_alternative_decrypter=*/false,
+      /*latch_once_used=*/false);
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  delegate_->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+  session()->connection()->SetDiversificationNonce(*diversification_nonce);
+
+  session()->connection()->set_fully_pad_crypto_handshake_packets(
+      crypto_config_->pad_shlo());
+  // Send SHLO in ENCRYPTION_ZERO_RTT.
+  SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT);
+  delegate_->OnNewEncryptionKeyAvailable(
+      ENCRYPTION_FORWARD_SECURE,
+      std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
+  delegate_->OnNewDecryptionKeyAvailable(
+      ENCRYPTION_FORWARD_SECURE,
+      std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
+      /*set_alternative_decrypter=*/true,
+      /*latch_once_used=*/false);
+  encryption_established_ = true;
+  one_rtt_keys_available_ = true;
+  delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+}
+
+void QuicCryptoServerStream::SendServerConfigUpdate(
+    const CachedNetworkParameters* cached_network_params) {
+  if (!one_rtt_keys_available_) {
+    return;
+  }
+
+  if (send_server_config_update_cb_ != nullptr) {
+    QUIC_DVLOG(1)
+        << "Skipped server config update since one is already in progress";
+    return;
+  }
+
+  std::unique_ptr<SendServerConfigUpdateCallback> cb(
+      new SendServerConfigUpdateCallback(this));
+  send_server_config_update_cb_ = cb.get();
+
+  crypto_config_->BuildServerConfigUpdateMessage(
+      session()->transport_version(), chlo_hash_,
+      previous_source_address_tokens_, session()->connection()->self_address(),
+      GetClientAddress(), session()->connection()->clock(),
+      session()->connection()->random_generator(), compressed_certs_cache_,
+      *crypto_negotiated_params_, cached_network_params, std::move(cb));
+}
+
+QuicCryptoServerStream::SendServerConfigUpdateCallback::
+    SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
+    : parent_(parent) {}
+
+void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
+  parent_ = nullptr;
+}
+
+// From BuildServerConfigUpdateMessageResultCallback
+void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
+    bool ok,
+    const CryptoHandshakeMessage& message) {
+  if (parent_ == nullptr) {
+    return;
+  }
+  parent_->FinishSendServerConfigUpdate(ok, message);
+}
+
+void QuicCryptoServerStream::FinishSendServerConfigUpdate(
+    bool ok,
+    const CryptoHandshakeMessage& message) {
+  // Clear the callback that got us here.
+  QUICHE_DCHECK(send_server_config_update_cb_ != nullptr);
+  send_server_config_update_cb_ = nullptr;
+
+  if (!ok) {
+    QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!";
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Server: Sending server config update: "
+                << message.DebugString();
+
+  // Send server config update in ENCRYPTION_FORWARD_SECURE.
+  SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE);
+
+  ++num_server_config_update_messages_sent_;
+}
+
+bool QuicCryptoServerStream::DisableResumption() {
+  QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
+  return false;
+}
+
+bool QuicCryptoServerStream::IsZeroRtt() const {
+  return num_handshake_messages_ == 1 &&
+         num_handshake_messages_with_server_nonces_ == 0;
+}
+
+bool QuicCryptoServerStream::IsResumption() const {
+  // QUIC Crypto doesn't have a non-0-RTT resumption mode.
+  return IsZeroRtt();
+}
+
+int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
+  return num_server_config_update_messages_sent_;
+}
+
+const CachedNetworkParameters*
+QuicCryptoServerStream::PreviousCachedNetworkParams() const {
+  return previous_cached_network_params_.get();
+}
+
+bool QuicCryptoServerStream::ResumptionAttempted() const {
+  return zero_rtt_attempted_;
+}
+
+bool QuicCryptoServerStream::EarlyDataAttempted() const {
+  QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
+  return zero_rtt_attempted_;
+}
+
+void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
+    CachedNetworkParameters cached_network_params) {
+  previous_cached_network_params_.reset(
+      new CachedNetworkParameters(cached_network_params));
+}
+
+void QuicCryptoServerStream::OnPacketDecrypted(EncryptionLevel level) {
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    one_rtt_packet_decrypted_ = true;
+    delegate_->NeuterHandshakeData();
+  }
+}
+
+void QuicCryptoServerStream::OnHandshakeDoneReceived() {
+  QUICHE_DCHECK(false);
+}
+
+void QuicCryptoServerStream::OnNewTokenReceived(absl::string_view /*token*/) {
+  QUICHE_DCHECK(false);
+}
+
+std::string QuicCryptoServerStream::GetAddressToken(
+    const CachedNetworkParameters* /*cached_network_parameters*/) const {
+  QUICHE_DCHECK(false);
+  return "";
+}
+
+bool QuicCryptoServerStream::ValidateAddressToken(
+    absl::string_view /*token*/) const {
+  QUICHE_DCHECK(false);
+  return false;
+}
+
+bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
+  return signed_config_->proof.send_expect_ct_header;
+}
+
+bool QuicCryptoServerStream::DidCertMatchSni() const {
+  return signed_config_->proof.cert_matched_sni;
+}
+
+const ProofSource::Details* QuicCryptoServerStream::ProofSourceDetails() const {
+  return proof_source_details_.get();
+}
+
+bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
+    std::string* output) const {
+  if (!encryption_established() ||
+      crypto_negotiated_params_->channel_id.empty()) {
+    return false;
+  }
+
+  const std::string& channel_id(crypto_negotiated_params_->channel_id);
+  uint8_t digest[SHA256_DIGEST_LENGTH];
+  SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
+         digest);
+
+  quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output);
+  return true;
+}
+
+ssl_early_data_reason_t QuicCryptoServerStream::EarlyDataReason() const {
+  if (IsZeroRtt()) {
+    return ssl_early_data_accepted;
+  }
+  if (zero_rtt_attempted_) {
+    return ssl_early_data_session_not_resumed;
+  }
+  return ssl_early_data_no_session_offered;
+}
+
+bool QuicCryptoServerStream::encryption_established() const {
+  return encryption_established_;
+}
+
+bool QuicCryptoServerStream::one_rtt_keys_available() const {
+  return one_rtt_keys_available_;
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoServerStream::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* QuicCryptoServerStream::crypto_message_parser() {
+  return QuicCryptoHandshaker::crypto_message_parser();
+}
+
+HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
+  return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+}
+
+void QuicCryptoServerStream::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> /*state*/) {
+  // QUIC Crypto doesn't need to remember any application state as part of doing
+  // 0-RTT resumption, so this function is a no-op.
+}
+
+size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+std::unique_ptr<QuicEncrypter>
+QuicCryptoServerStream::CreateCurrentOneRttEncrypter() {
+  // Key update is only defined in QUIC+TLS.
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+void QuicCryptoServerStream::ProcessClientHello(
+    quiche::QuicheReferenceCountedPointer<
+        ValidateClientHelloResultCallback::Result>
+        result,
+    std::unique_ptr<ProofSource::Details> proof_source_details,
+    std::unique_ptr<ProcessClientHelloResultCallback> done_cb) {
+  proof_source_details_ = std::move(proof_source_details);
+  const CryptoHandshakeMessage& message = result->client_hello;
+  std::string error_details;
+  if (!helper_->CanAcceptClientHello(
+          message, GetClientAddress(), session()->connection()->peer_address(),
+          session()->connection()->self_address(), &error_details)) {
+    done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr,
+                 nullptr);
+    return;
+  }
+
+  absl::string_view user_agent_id;
+  message.GetStringPiece(quic::kUAID, &user_agent_id);
+  if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) {
+    session()->SetUserAgentId(std::string(user_agent_id));
+  }
+
+  if (!result->info.server_nonce.empty()) {
+    ++num_handshake_messages_with_server_nonces_;
+  }
+
+  if (num_handshake_messages_ == 1) {
+    // Client attempts zero RTT handshake by sending a non-inchoate CHLO.
+    absl::string_view public_value;
+    zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value);
+  }
+
+  // Store the bandwidth estimate from the client.
+  if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
+    previous_cached_network_params_.reset(
+        new CachedNetworkParameters(result->cached_network_params));
+  }
+  previous_source_address_tokens_ = result->info.source_address_tokens;
+
+  QuicConnection* connection = session()->connection();
+  crypto_config_->ProcessClientHello(
+      result, /*reject_only=*/false, connection->connection_id(),
+      connection->self_address(), GetClientAddress(), connection->version(),
+      session()->supported_versions(), connection->clock(),
+      connection->random_generator(), compressed_certs_cache_,
+      crypto_negotiated_params_, signed_config_,
+      QuicCryptoStream::CryptoMessageFramingOverhead(
+          transport_version(), connection->connection_id()),
+      chlo_packet_size_, std::move(done_cb));
+}
+
+void QuicCryptoServerStream::OverrideQuicConfigDefaults(
+    QuicConfig* /*config*/) {}
+
+QuicCryptoServerStream::ValidateCallback::ValidateCallback(
+    QuicCryptoServerStream* parent)
+    : parent_(parent) {}
+
+void QuicCryptoServerStream::ValidateCallback::Cancel() {
+  parent_ = nullptr;
+}
+
+void QuicCryptoServerStream::ValidateCallback::Run(
+    quiche::QuicheReferenceCountedPointer<Result> result,
+    std::unique_ptr<ProofSource::Details> details) {
+  if (parent_ != nullptr) {
+    parent_->FinishProcessingHandshakeMessage(std::move(result),
+                                              std::move(details));
+  }
+}
+
+const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
+  return session()->connection()->peer_address();
+}
+
+SSL* QuicCryptoServerStream::GetSsl() const { return nullptr; }
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_server_stream.h b/quiche/quic/core/quic_crypto_server_stream.h
new file mode 100644
index 0000000..c66b229
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream.h
@@ -0,0 +1,267 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
+
+#include <string>
+
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/proto/source_address_token_proto.h"
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicCryptoServerStreamPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
+    : public QuicCryptoServerStreamBase,
+      public QuicCryptoHandshaker {
+ public:
+  QuicCryptoServerStream(const QuicCryptoServerStream&) = delete;
+  QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete;
+
+  ~QuicCryptoServerStream() override;
+
+  // From QuicCryptoServerStreamBase
+  void CancelOutstandingCallbacks() override;
+  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
+  void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) override;
+  bool DisableResumption() override;
+  bool IsZeroRtt() const override;
+  bool IsResumption() const override;
+  bool ResumptionAttempted() const override;
+  bool EarlyDataAttempted() const override;
+  int NumServerConfigUpdateMessagesSent() const override;
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) override;
+  void OnPacketDecrypted(EncryptionLevel level) override;
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_params*/) const override;
+  bool ValidateAddressToken(absl::string_view token) const override;
+  bool ShouldSendExpectCTHeader() const override;
+  bool DidCertMatchSni() const override;
+  const ProofSource::Details* ProofSourceDetails() const override;
+
+  // From QuicCryptoStream
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> state) override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  SSL* GetSsl() const override;
+
+  // From QuicCryptoHandshaker
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+
+ protected:
+  QUIC_EXPORT_PRIVATE friend std::unique_ptr<QuicCryptoServerStreamBase>
+  CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                           QuicCompressedCertsCache* compressed_certs_cache,
+                           QuicSession* session,
+                           QuicCryptoServerStreamBase::Helper* helper);
+
+  // |crypto_config| must outlive the stream.
+  // |session| must outlive the stream.
+  // |helper| must outlive the stream.
+  QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                         QuicCompressedCertsCache* compressed_certs_cache,
+                         QuicSession* session,
+                         QuicCryptoServerStreamBase::Helper* helper);
+
+  virtual void ProcessClientHello(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          result,
+      std::unique_ptr<ProofSource::Details> proof_source_details,
+      std::unique_ptr<ProcessClientHelloResultCallback> done_cb);
+
+  // Hook that allows the server to set QuicConfig defaults just
+  // before going through the parameter negotiation step.
+  virtual void OverrideQuicConfigDefaults(QuicConfig* config);
+
+  // Returns client address used to generate and validate source address token.
+  virtual const QuicSocketAddress GetClientAddress();
+
+  // Returns the QuicSession that this stream belongs to.
+  QuicSession* session() const { return session_; }
+
+  void set_encryption_established(bool encryption_established) {
+    encryption_established_ = encryption_established;
+  }
+
+  void set_one_rtt_keys_available(bool one_rtt_keys_available) {
+    one_rtt_keys_available_ = one_rtt_keys_available;
+  }
+
+ private:
+  friend class test::QuicCryptoServerStreamPeer;
+
+  class QUIC_EXPORT_PRIVATE ValidateCallback
+      : public ValidateClientHelloResultCallback {
+   public:
+    explicit ValidateCallback(QuicCryptoServerStream* parent);
+    ValidateCallback(const ValidateCallback&) = delete;
+    ValidateCallback& operator=(const ValidateCallback&) = delete;
+    // To allow the parent to detach itself from the callback before deletion.
+    void Cancel();
+
+    // From ValidateClientHelloResultCallback
+    void Run(quiche::QuicheReferenceCountedPointer<Result> result,
+             std::unique_ptr<ProofSource::Details> details) override;
+
+   private:
+    QuicCryptoServerStream* parent_;
+  };
+
+  class SendServerConfigUpdateCallback
+      : public BuildServerConfigUpdateMessageResultCallback {
+   public:
+    explicit SendServerConfigUpdateCallback(QuicCryptoServerStream* parent);
+    SendServerConfigUpdateCallback(const SendServerConfigUpdateCallback&) =
+        delete;
+    void operator=(const SendServerConfigUpdateCallback&) = delete;
+
+    // To allow the parent to detach itself from the callback before deletion.
+    void Cancel();
+
+    // From BuildServerConfigUpdateMessageResultCallback
+    void Run(bool ok, const CryptoHandshakeMessage& message) override;
+
+   private:
+    QuicCryptoServerStream* parent_;
+  };
+
+  // Invoked by ValidateCallback::RunImpl once initial validation of
+  // the client hello is complete.  Finishes processing of the client
+  // hello message and handles handshake success/failure.
+  void FinishProcessingHandshakeMessage(
+      quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>
+          result,
+      std::unique_ptr<ProofSource::Details> details);
+
+  class ProcessClientHelloCallback;
+  friend class ProcessClientHelloCallback;
+
+  // Portion of FinishProcessingHandshakeMessage which executes after
+  // ProcessClientHello has been called.
+  void FinishProcessingHandshakeMessageAfterProcessClientHello(
+      const ValidateClientHelloResultCallback::Result& result,
+      QuicErrorCode error,
+      const std::string& error_details,
+      std::unique_ptr<CryptoHandshakeMessage> reply,
+      std::unique_ptr<DiversificationNonce> diversification_nonce,
+      std::unique_ptr<ProofSource::Details> proof_source_details);
+
+  // Invoked by SendServerConfigUpdateCallback::RunImpl once the proof has been
+  // received.  |ok| indicates whether or not the proof was successfully
+  // acquired, and |message| holds the partially-constructed message from
+  // SendServerConfigUpdate.
+  void FinishSendServerConfigUpdate(bool ok,
+                                    const CryptoHandshakeMessage& message);
+
+  // Returns the QuicTransportVersion of the connection.
+  QuicTransportVersion transport_version() const {
+    return session_->transport_version();
+  }
+
+  QuicSession* session_;
+  HandshakerDelegateInterface* delegate_;
+
+  // crypto_config_ contains crypto parameters for the handshake.
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // compressed_certs_cache_ contains a set of most recently compressed certs.
+  // Owned by QuicDispatcher.
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  // Server's certificate chain and signature of the server config, as provided
+  // by ProofSource::GetProof.
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+
+  // Hash of the last received CHLO message which can be used for generating
+  // server config update messages.
+  std::string chlo_hash_;
+
+  // Pointer to the helper for this crypto stream. Must outlive this stream.
+  QuicCryptoServerStreamBase::Helper* helper_;
+
+  // Number of handshake messages received by this stream.
+  uint8_t num_handshake_messages_;
+
+  // Number of handshake messages received by this stream that contain
+  // server nonces (indicating that this is a non-zero-RTT handshake
+  // attempt).
+  uint8_t num_handshake_messages_with_server_nonces_;
+
+  // Pointer to the active callback that will receive the result of
+  // BuildServerConfigUpdateMessage and forward it to
+  // FinishSendServerConfigUpdate.  nullptr if no update message is currently
+  // being built.
+  SendServerConfigUpdateCallback* send_server_config_update_cb_;
+
+  // Number of server config update (SCUP) messages sent by this stream.
+  int num_server_config_update_messages_sent_;
+
+  // If the client provides CachedNetworkParameters in the STK in the CHLO, then
+  // store here, and send back in future STKs if we have no better bandwidth
+  // estimate to send.
+  std::unique_ptr<CachedNetworkParameters> previous_cached_network_params_;
+
+  // Contains any source address tokens which were present in the CHLO.
+  SourceAddressTokens previous_source_address_tokens_;
+
+  // True if client attempts 0-rtt handshake (which can succeed or fail).
+  bool zero_rtt_attempted_;
+
+  // Size of the packet containing the most recently received CHLO.
+  QuicByteCount chlo_packet_size_;
+
+  // Pointer to the active callback that will receive the result of the client
+  // hello validation request and forward it to FinishProcessingHandshakeMessage
+  // for processing.  nullptr if no handshake message is being validated.  Note
+  // that this field is mutually exclusive with process_client_hello_cb_.
+  ValidateCallback* validate_client_hello_cb_;
+
+  // Pointer to the active callback which will receive the results of
+  // ProcessClientHello and forward it to
+  // FinishProcessingHandshakeMessageAfterProcessClientHello.  Note that this
+  // field is mutually exclusive with validate_client_hello_cb_.
+  ProcessClientHelloCallback* process_client_hello_cb_;
+
+  // The ProofSource::Details from this connection.
+  std::unique_ptr<ProofSource::Details> proof_source_details_;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  bool one_rtt_packet_decrypted_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
diff --git a/quiche/quic/core/quic_crypto_server_stream_base.cc b/quiche/quic/core/quic_crypto_server_stream_base.cc
new file mode 100644
index 0000000..7cff108
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream_base.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_server_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/tls_server_handshaker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicCryptoServerStreamBase::QuicCryptoServerStreamBase(QuicSession* session)
+    : QuicCryptoStream(session) {}
+
+std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSession* session,
+    QuicCryptoServerStreamBase::Helper* helper) {
+  switch (session->connection()->version().handshake_protocol) {
+    case PROTOCOL_QUIC_CRYPTO:
+      return std::unique_ptr<QuicCryptoServerStream>(new QuicCryptoServerStream(
+          crypto_config, compressed_certs_cache, session, helper));
+    case PROTOCOL_TLS1_3:
+      return std::unique_ptr<TlsServerHandshaker>(
+          new TlsServerHandshaker(session, crypto_config));
+    case PROTOCOL_UNSUPPORTED:
+      break;
+  }
+  QUIC_BUG(quic_bug_10492_1)
+      << "Unknown handshake protocol: "
+      << static_cast<int>(session->connection()->version().handshake_protocol);
+  return nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_server_stream_base.h b/quiche/quic/core/quic_crypto_server_stream_base.h
new file mode 100644
index 0000000..84d6190
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream_base.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_crypto_handshaker.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class CachedNetworkParameters;
+class CryptoHandshakeMessage;
+class QuicCryptoServerConfig;
+class QuicCryptoServerStreamBase;
+
+// TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
+// various code and test refactoring.
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
+ public:
+  explicit QuicCryptoServerStreamBase(QuicSession* session);
+
+  class QUIC_EXPORT_PRIVATE Helper {
+   public:
+    virtual ~Helper() {}
+
+    // Returns true if |message|, which was received on |self_address| is
+    // acceptable according to the visitor's policy. Otherwise, returns false
+    // and populates |error_details|.
+    virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
+                                      const QuicSocketAddress& client_address,
+                                      const QuicSocketAddress& peer_address,
+                                      const QuicSocketAddress& self_address,
+                                      std::string* error_details) const = 0;
+  };
+
+  ~QuicCryptoServerStreamBase() override {}
+
+  // Cancel any outstanding callbacks, such as asynchronous validation of client
+  // hello.
+  virtual void CancelOutstandingCallbacks() = 0;
+
+  // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
+  // SHA-256 hash of the client's ChannelID key and returns true, if the client
+  // presented a ChannelID. Otherwise it returns false.
+  virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0;
+
+  virtual int NumServerConfigUpdateMessagesSent() const = 0;
+
+  // Sends the latest server config and source-address token to the client.
+  virtual void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) = 0;
+
+  // Disables TLS resumption, should be called as early as possible.
+  // Return true if resumption is disabled.
+  // Return false if nothing happened, typically it means it is called too late.
+  virtual bool DisableResumption() = 0;
+
+  // Returns true if the connection was a successful 0-RTT resumption.
+  virtual bool IsZeroRtt() const = 0;
+
+  // Returns true if the connection was the result of a resumption handshake,
+  // whether 0-RTT or not.
+  virtual bool IsResumption() const = 0;
+
+  // Returns true if the client attempted a resumption handshake, whether or not
+  // the resumption actually occurred.
+  virtual bool ResumptionAttempted() const = 0;
+
+  // Returns true if the client attempted to use early data, as indicated by the
+  // "early_data" TLS extension. TLS only.
+  virtual bool EarlyDataAttempted() const = 0;
+
+  // NOTE: Indicating that the Expect-CT header should be sent here presents
+  // a layering violation to some extent. The Expect-CT header only applies to
+  // HTTP connections, while this class can be used for non-HTTP applications.
+  // However, it is exposed here because that is the only place where the
+  // configuration for the certificate used in the connection is accessible.
+  virtual bool ShouldSendExpectCTHeader() const = 0;
+
+  // Return true if a cert was picked that matched the SNI hostname.
+  virtual bool DidCertMatchSni() const = 0;
+
+  // Returns the Details from the latest call to ProofSource::GetProof or
+  // ProofSource::ComputeTlsSignature. Returns nullptr if no such call has been
+  // made. The Details are owned by the QuicCryptoServerStreamBase and the
+  // pointer is only valid while the owning object is still valid.
+  virtual const ProofSource::Details* ProofSourceDetails() const = 0;
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    QUICHE_NOTREACHED();
+    return false;
+  }
+};
+
+// Creates an appropriate QuicCryptoServerStream for the provided parameters,
+// including the version used by |session|. |crypto_config|, |session|, and
+// |helper| must all outlive the stream. The caller takes ownership of the
+// returned object.
+QUIC_EXPORT_PRIVATE std::unique_ptr<QuicCryptoServerStreamBase>
+CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                         QuicCompressedCertsCache* compressed_certs_cache,
+                         QuicSession* session,
+                         QuicCryptoServerStreamBase::Helper* helper);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_BASE_H_
diff --git a/quiche/quic/core/quic_crypto_server_stream_test.cc b/quiche/quic/core/quic_crypto_server_stream_test.cc
new file mode 100644
index 0000000..649f340
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_server_stream_test.cc
@@ -0,0 +1,400 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/failing_proof_source.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+class QuicConnection;
+class QuicStream;
+}  // namespace quic
+
+using testing::_;
+using testing::NiceMock;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+// This test tests the server-side of the QUIC crypto handshake. It does not
+// test the TLS handshake - that is in tls_server_handshaker_test.cc.
+class QuicCryptoServerStreamTest : public QuicTest {
+ public:
+  QuicCryptoServerStreamTest()
+      : QuicCryptoServerStreamTest(crypto_test_utils::ProofSourceForTesting()) {
+  }
+
+  explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
+      : server_crypto_config_(QuicCryptoServerConfig::TESTING,
+                              QuicRandom::GetInstance(),
+                              std::move(proof_source),
+                              KeyExchangeSource::Default()),
+        server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        server_id_(kServerHostname, kServerPort, false),
+        client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+
+  void Initialize() { InitializeServer(); }
+
+  ~QuicCryptoServerStreamTest() override {
+    // Ensure that anything that might reference |helpers_| is destroyed before
+    // |helpers_| is destroyed.
+    server_session_.reset();
+    client_session_.reset();
+    helpers_.clear();
+    alarm_factories_.clear();
+  }
+
+  // Initializes the crypto server stream state for testing.  May be
+  // called multiple times.
+  void InitializeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        &server_crypto_config_, &server_compressed_certs_cache_,
+        &server_connection_, &server_session);
+    QUICHE_CHECK(server_session);
+    server_session_.reset(server_session);
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly(
+            [this](const std::vector<absl::string_view>& alpns) {
+              return std::find(
+                  alpns.cbegin(), alpns.cend(),
+                  AlpnForVersion(server_session_->connection()->version()));
+            });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        &server_crypto_config_);
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoClientStream* client_stream() {
+    return client_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake client, and all its associated state, for
+  // testing.  May be called multiple times.
+  void InitializeFakeClient() {
+    TestQuicSpdyClientSession* client_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateClientSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        &client_crypto_config_, &client_connection_, &client_session);
+    QUICHE_CHECK(client_session);
+    client_session_.reset(client_session);
+  }
+
+  int CompleteCryptoHandshake() {
+    QUICHE_CHECK(server_connection_);
+    QUICHE_CHECK(server_session_ != nullptr);
+
+    return crypto_test_utils::HandshakeWithFakeClient(
+        helpers_.back().get(), alarm_factories_.back().get(),
+        server_connection_, server_stream(), server_id_, client_options_,
+        /*alpn=*/"");
+  }
+
+  // Performs a single round of handshake message-exchange between the
+  // client and server.
+  void AdvanceHandshakeWithFakeClient() {
+    QUICHE_CHECK(server_connection_);
+    QUICHE_CHECK(client_session_ != nullptr);
+
+    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    client_stream()->CryptoConnect();
+    crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 0,
+                                        server_connection_, server_stream(), 0);
+  }
+
+ protected:
+  // Every connection gets its own MockQuicConnectionHelper and
+  // MockAlarmFactory, tracked separately from the server and client state so
+  // their lifetimes persist through the whole test.
+  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
+  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
+
+  // Server state.
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  QuicCryptoServerConfig server_crypto_config_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+  QuicServerId server_id_;
+
+  // Client state.
+  PacketSavingConnection* client_connection_;
+  QuicCryptoClientConfig client_crypto_config_;
+  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
+
+  CryptoHandshakeMessage message_;
+  crypto_test_utils::FakeClientOptions client_options_;
+
+  // Which QUIC versions the client and server support.
+  ParsedQuicVersionVector supported_versions_ =
+      AllSupportedVersionsWithQuicCrypto();
+};
+
+TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
+  Initialize();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
+  // CompleteCryptoHandshake returns the number of client hellos sent. This
+  // test should send:
+  //   * One to get a source-address token and certificates.
+  //   * One to complete the handshake.
+  Initialize();
+  EXPECT_EQ(2, CompleteCryptoHandshake());
+  EXPECT_TRUE(server_stream()->encryption_established());
+  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
+  Initialize();
+  InitializeFakeClient();
+
+  // Do a first handshake in order to prime the client config with the server's
+  // information.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+
+  // Now do another handshake, with the blocking SHLO connection option.
+  InitializeServer();
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_TRUE(server_stream()->encryption_established());
+  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
+            server_session_->connection()->encryption_level());
+}
+
+TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
+  Initialize();
+  InitializeFakeClient();
+
+  // Do a first handshake in order to prime the client config with the server's
+  // information.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->ResumptionAttempted());
+
+  // Now do another handshake, hopefully in 0-RTT.
+  QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
+  InitializeFakeClient();
+  InitializeServer();
+
+  EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+  EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+  client_stream()->CryptoConnect();
+
+  EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+  EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+  crypto_test_utils::CommunicateHandshakeMessages(
+      client_connection_, client_stream(), server_connection_, server_stream());
+
+  EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_F(QuicCryptoServerStreamTest, FailByPolicy) {
+  Initialize();
+  InitializeFakeClient();
+
+  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  AdvanceHandshakeWithFakeClient();
+}
+
+TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
+  Initialize();
+  CompleteCryptoHandshake();
+  EXPECT_CALL(
+      *server_connection_,
+      CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
+  message_.set_tag(kCHLO);
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
+                                                  Perspective::IS_CLIENT);
+}
+
+TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
+  Initialize();
+
+  message_.set_tag(kSHLO);
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, _, _));
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), message_,
+                                                  Perspective::IS_SERVER);
+}
+
+TEST_F(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) {
+  // An attempt to send a SCUP before completing handshake should fail.
+  Initialize();
+
+  server_stream()->SendServerConfigUpdate(nullptr);
+  EXPECT_EQ(0, server_stream()->NumServerConfigUpdateMessagesSent());
+}
+
+TEST_F(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
+  Initialize();
+
+  InitializeFakeClient();
+
+  // Do a first handshake in order to prime the client config with the server's
+  // information.
+  AdvanceHandshakeWithFakeClient();
+
+  // Now do another handshake, with the blocking SHLO connection option.
+  InitializeServer();
+  InitializeFakeClient();
+  AdvanceHandshakeWithFakeClient();
+
+  // Send a SCUP message and ensure that the client was able to verify it.
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  server_stream()->SendServerConfigUpdate(nullptr);
+  crypto_test_utils::AdvanceHandshake(client_connection_, client_stream(), 1,
+                                      server_connection_, server_stream(), 1);
+
+  EXPECT_EQ(1, server_stream()->NumServerConfigUpdateMessagesSent());
+  EXPECT_EQ(1, client_stream()->num_scup_messages_received());
+}
+
+class QuicCryptoServerStreamTestWithFailingProofSource
+    : public QuicCryptoServerStreamTest {
+ public:
+  QuicCryptoServerStreamTestWithFailingProofSource()
+      : QuicCryptoServerStreamTest(
+            std::unique_ptr<FailingProofSource>(new FailingProofSource)) {}
+};
+
+TEST_F(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
+  Initialize();
+  InitializeFakeClient();
+
+  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to get proof", _));
+  // Regression test for b/31521252, in which a crash would happen here.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+class QuicCryptoServerStreamTestWithFakeProofSource
+    : public QuicCryptoServerStreamTest {
+ public:
+  QuicCryptoServerStreamTestWithFakeProofSource()
+      : QuicCryptoServerStreamTest(
+            std::unique_ptr<FakeProofSource>(new FakeProofSource)),
+        crypto_config_peer_(&server_crypto_config_) {}
+
+  FakeProofSource* GetFakeProofSource() const {
+    return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
+  }
+
+ protected:
+  QuicCryptoServerConfigPeer crypto_config_peer_;
+};
+
+// Regression test for b/35422225, in which multiple CHLOs arriving on the same
+// connection in close succession could cause a crash.
+TEST_F(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
+  Initialize();
+  GetFakeProofSource()->Activate();
+  EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+      .WillOnce(testing::Return(true));
+
+  // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
+  // first one from the list of supported versions.
+  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      transport_version = version.transport_version;
+      break;
+    }
+  }
+  ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
+
+  // Create a minimal CHLO
+  MockClock clock;
+  CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
+      &clock, transport_version, &server_crypto_config_);
+
+  // Send in the CHLO, and check that a callback is now pending in the
+  // ProofSource.
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
+                                                  Perspective::IS_CLIENT);
+  EXPECT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+  // Send in a second CHLO while processing of the first is still pending.
+  // Verify that the server closes the connection rather than crashing.  Note
+  // that the crash is a use-after-free, so it may only show up consistently in
+  // ASAN tests.
+  EXPECT_CALL(
+      *server_connection_,
+      CloseConnection(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
+                      "Unexpected handshake message while processing CHLO", _));
+  crypto_test_utils::SendHandshakeMessageToStream(server_stream(), chlo,
+                                                  Perspective::IS_CLIENT);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_stream.cc b/quiche/quic/core/quic_crypto_stream.cc
new file mode 100644
index 0000000..1f442de
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_stream.cc
@@ -0,0 +1,482 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_stream.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define ENDPOINT                                                   \
+  (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                      : "Client:"  \
+                                                        " ")
+
+QuicCryptoStream::QuicCryptoStream(QuicSession* session)
+    : QuicStream(
+          QuicVersionUsesCryptoFrames(session->transport_version())
+              ? QuicUtils::GetInvalidStreamId(session->transport_version())
+              : QuicUtils::GetCryptoStreamId(session->transport_version()),
+          session,
+          /*is_static=*/true,
+          QuicVersionUsesCryptoFrames(session->transport_version())
+              ? CRYPTO
+              : BIDIRECTIONAL),
+      substreams_{{{this, ENCRYPTION_INITIAL},
+                   {this, ENCRYPTION_HANDSHAKE},
+                   {this, ENCRYPTION_ZERO_RTT},
+                   {this, ENCRYPTION_FORWARD_SECURE}}} {
+  // The crypto stream is exempt from connection level flow control.
+  DisableConnectionFlowControlForThisStream();
+}
+
+QuicCryptoStream::~QuicCryptoStream() {}
+
+// static
+QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead(
+    QuicTransportVersion version,
+    QuicConnectionId connection_id) {
+  QUICHE_DCHECK(
+      QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_1;
+  QuicVariableLengthIntegerLength length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  if (!QuicVersionHasLongHeaderLengths(version)) {
+    retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  return QuicPacketCreator::StreamFramePacketOverhead(
+      version, static_cast<QuicConnectionIdLength>(connection_id.length()),
+      PACKET_0BYTE_CONNECTION_ID,
+      /*include_version=*/true,
+      /*include_diversification_nonce=*/true,
+      VersionHasIetfInvariantHeader(version) ? PACKET_4BYTE_PACKET_NUMBER
+                                             : PACKET_1BYTE_PACKET_NUMBER,
+      retry_token_length_length, length_length,
+      /*offset=*/0);
+}
+
+void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12573_1,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 shouldn't receive CRYPTO frames";
+  EncryptionLevel level = session()->connection()->last_decrypted_level();
+  substreams_[level].sequencer.OnCryptoFrame(frame);
+  EncryptionLevel frame_level = level;
+  if (substreams_[level].sequencer.NumBytesBuffered() >
+      BufferSizeLimitForLevel(frame_level)) {
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Too much crypto data received");
+  }
+}
+
+void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    QUIC_PEER_BUG(quic_peer_bug_12573_2)
+        << "Crypto data received in stream frame instead of crypto frame";
+    OnUnrecoverableError(QUIC_INVALID_STREAM_DATA, "Unexpected stream frame");
+  }
+  QuicStream::OnStreamFrame(frame);
+}
+
+void QuicCryptoStream::OnDataAvailable() {
+  EncryptionLevel level = session()->connection()->last_decrypted_level();
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    // Versions less than 47 only support QUIC crypto, which ignores the
+    // EncryptionLevel passed into CryptoMessageParser::ProcessInput (and
+    // OnDataAvailableInSequencer).
+    OnDataAvailableInSequencer(sequencer(), level);
+    return;
+  }
+  OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
+}
+
+void QuicCryptoStream::OnDataAvailableInSequencer(
+    QuicStreamSequencer* sequencer,
+    EncryptionLevel level) {
+  struct iovec iov;
+  while (sequencer->GetReadableRegion(&iov)) {
+    absl::string_view data(static_cast<char*>(iov.iov_base), iov.iov_len);
+    if (!crypto_message_parser()->ProcessInput(data, level)) {
+      OnUnrecoverableError(crypto_message_parser()->error(),
+                           crypto_message_parser()->error_detail());
+      return;
+    }
+    sequencer->MarkConsumed(iov.iov_len);
+    if (one_rtt_keys_available() &&
+        crypto_message_parser()->InputBytesRemaining() == 0) {
+      // If the handshake is complete and the current message has been fully
+      // processed then no more handshake messages are likely to arrive soon
+      // so release the memory in the stream sequencer.
+      sequencer->ReleaseBufferIfEmpty();
+    }
+  }
+}
+
+void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
+                                       absl::string_view data) {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    WriteOrBufferDataAtLevel(data, /*fin=*/false, level,
+                             /*ack_listener=*/nullptr);
+    return;
+  }
+  if (data.empty()) {
+    QUIC_BUG(quic_bug_10322_1) << "Empty crypto data being written";
+    return;
+  }
+  const bool had_buffered_data = HasBufferedCryptoFrames();
+  // Append |data| to the send buffer for this encryption level.
+  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+  QuicStreamOffset offset = send_buffer->stream_offset();
+  send_buffer->SaveStreamData(data);
+  if (kMaxStreamLength - offset < data.length()) {
+    QUIC_BUG(quic_bug_10322_2) << "Writing too much crypto handshake data";
+    // TODO(nharper): Switch this to an IETF QUIC error code, possibly
+    // INTERNAL_ERROR?
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Writing too much crypto handshake data");
+  }
+  if (had_buffered_data) {
+    // Do not try to write if there is buffered data.
+    return;
+  }
+
+  size_t bytes_consumed = stream_delegate()->SendCryptoData(
+      level, data.length(), offset, NOT_RETRANSMISSION);
+  send_buffer->OnStreamDataConsumed(bytes_consumed);
+}
+
+size_t QuicCryptoStream::BufferSizeLimitForLevel(EncryptionLevel) const {
+  return GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
+}
+
+bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
+                                          QuicTime::Delta /*ack_delay_time*/) {
+  QuicByteCount newly_acked_length = 0;
+  if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
+          frame.offset, frame.data_length, &newly_acked_length)) {
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+                         "Trying to ack unsent crypto data.");
+    return false;
+  }
+  return newly_acked_length > 0;
+}
+
+void QuicCryptoStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
+                                   "Attempt to reset crypto stream");
+}
+
+void QuicCryptoStream::NeuterUnencryptedStreamData() {
+  NeuterStreamDataOfEncryptionLevel(ENCRYPTION_INITIAL);
+}
+
+void QuicCryptoStream::NeuterStreamDataOfEncryptionLevel(
+    EncryptionLevel level) {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    for (const auto& interval : bytes_consumed_[level]) {
+      QuicByteCount newly_acked_length = 0;
+      send_buffer().OnStreamDataAcked(
+          interval.min(), interval.max() - interval.min(), &newly_acked_length);
+    }
+    return;
+  }
+  QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+  // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer to
+  // replace the following code.
+  QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
+  to_ack.Complement(0, send_buffer->stream_offset());
+  for (const auto& interval : to_ack) {
+    QuicByteCount newly_acked_length = 0;
+    send_buffer->OnStreamDataAcked(
+        interval.min(), interval.max() - interval.min(), &newly_acked_length);
+  }
+}
+
+void QuicCryptoStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
+  if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    QUIC_BUG(quic_bug_10322_3)
+        << "Stream data consumed when CRYPTO frames should be in use";
+  }
+  if (bytes_consumed > 0) {
+    bytes_consumed_[session()->connection()->encryption_level()].Add(
+        stream_bytes_written(), stream_bytes_written() + bytes_consumed);
+  }
+  QuicStream::OnStreamDataConsumed(bytes_consumed);
+}
+
+namespace {
+
+constexpr std::array<EncryptionLevel, NUM_ENCRYPTION_LEVELS>
+AllEncryptionLevels() {
+  return {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+          ENCRYPTION_FORWARD_SECURE};
+}
+
+}  // namespace
+
+bool QuicCryptoStream::HasPendingCryptoRetransmission() const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    return false;
+  }
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    if (substreams_[level].send_buffer.HasPendingRetransmission()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicCryptoStream::WritePendingCryptoRetransmission() {
+  QUIC_BUG_IF(quic_bug_12573_3,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't write CRYPTO frames";
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+    while (send_buffer->HasPendingRetransmission()) {
+      auto pending = send_buffer->NextPendingRetransmission();
+      size_t bytes_consumed = stream_delegate()->SendCryptoData(
+          level, pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
+      send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
+      if (bytes_consumed < pending.length) {
+        return;
+      }
+    }
+  }
+}
+
+void QuicCryptoStream::WritePendingRetransmission() {
+  while (HasPendingRetransmission()) {
+    StreamPendingRetransmission pending =
+        send_buffer().NextPendingRetransmission();
+    QuicIntervalSet<QuicStreamOffset> retransmission(
+        pending.offset, pending.offset + pending.length);
+    EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
+    // Determine the encryption level to write the retransmission
+    // at. The retransmission should be written at the same encryption level
+    // as the original transmission.
+    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+      if (retransmission.Intersects(bytes_consumed_[i])) {
+        retransmission_encryption_level = static_cast<EncryptionLevel>(i);
+        retransmission.Intersection(bytes_consumed_[i]);
+        break;
+      }
+    }
+    pending.offset = retransmission.begin()->min();
+    pending.length =
+        retransmission.begin()->max() - retransmission.begin()->min();
+    QuicConsumedData consumed = RetransmitStreamDataAtLevel(
+        pending.offset, pending.length, retransmission_encryption_level,
+        HANDSHAKE_RETRANSMISSION);
+    if (consumed.bytes_consumed < pending.length) {
+      // The connection is write blocked.
+      break;
+    }
+  }
+}
+
+bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset,
+                                            QuicByteCount data_length,
+                                            bool /*fin*/,
+                                            TransmissionType type) {
+  QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
+  QuicIntervalSet<QuicStreamOffset> retransmission(offset,
+                                                   offset + data_length);
+  // Determine the encryption level to send data. This only needs to be once as
+  // [offset, offset + data_length) is guaranteed to be in the same packet.
+  EncryptionLevel send_encryption_level = ENCRYPTION_INITIAL;
+  for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    if (retransmission.Intersects(bytes_consumed_[i])) {
+      send_encryption_level = static_cast<EncryptionLevel>(i);
+      break;
+    }
+  }
+  retransmission.Difference(bytes_acked());
+  for (const auto& interval : retransmission) {
+    QuicStreamOffset retransmission_offset = interval.min();
+    QuicByteCount retransmission_length = interval.max() - interval.min();
+    QuicConsumedData consumed = RetransmitStreamDataAtLevel(
+        retransmission_offset, retransmission_length, send_encryption_level,
+        type);
+    if (consumed.bytes_consumed < retransmission_length) {
+      // The connection is write blocked.
+      return false;
+    }
+  }
+
+  return true;
+}
+
+QuicConsumedData QuicCryptoStream::RetransmitStreamDataAtLevel(
+    QuicStreamOffset retransmission_offset,
+    QuicByteCount retransmission_length,
+    EncryptionLevel encryption_level,
+    TransmissionType type) {
+  QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
+  const auto consumed = stream_delegate()->WritevData(
+      id(), retransmission_length, retransmission_offset, NO_FIN, type,
+      encryption_level);
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
+                << " is forced to retransmit stream data ["
+                << retransmission_offset << ", "
+                << retransmission_offset + retransmission_length
+                << "), with encryption level: " << encryption_level
+                << ", consumed: " << consumed;
+  OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
+                             consumed.fin_consumed);
+
+  return consumed;
+}
+
+uint64_t QuicCryptoStream::crypto_bytes_read() const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    return stream_bytes_read();
+  }
+  uint64_t bytes_read = 0;
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    bytes_read += substreams_[level].sequencer.NumBytesConsumed();
+  }
+  return bytes_read;
+}
+
+uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
+  return substreams_[level].sequencer.NumBytesConsumed();
+}
+
+bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) {
+  QUIC_BUG_IF(quic_bug_12573_4,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't write CRYPTO frames (2)";
+  return substreams_[level].send_buffer.WriteStreamData(offset, data_length,
+                                                        writer);
+}
+
+void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
+  QUIC_BUG_IF(quic_bug_12573_5,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't lose CRYPTO frames";
+  substreams_[crypto_frame->level].send_buffer.OnStreamDataLost(
+      crypto_frame->offset, crypto_frame->data_length);
+}
+
+bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
+                                      TransmissionType type) {
+  QUIC_BUG_IF(quic_bug_12573_6,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't retransmit CRYPTO frames";
+  QuicIntervalSet<QuicStreamOffset> retransmission(
+      crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
+  QuicStreamSendBuffer* send_buffer =
+      &substreams_[crypto_frame->level].send_buffer;
+  retransmission.Difference(send_buffer->bytes_acked());
+  if (retransmission.Empty()) {
+    return true;
+  }
+  for (const auto& interval : retransmission) {
+    size_t retransmission_offset = interval.min();
+    size_t retransmission_length = interval.max() - interval.min();
+    size_t bytes_consumed = stream_delegate()->SendCryptoData(
+        crypto_frame->level, retransmission_length, retransmission_offset,
+        type);
+    send_buffer->OnStreamDataRetransmitted(retransmission_offset,
+                                           bytes_consumed);
+    if (bytes_consumed < retransmission_length) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void QuicCryptoStream::WriteBufferedCryptoFrames() {
+  QUIC_BUG_IF(quic_bug_12573_7,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't use CRYPTO frames";
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+    const size_t data_length =
+        send_buffer->stream_offset() - send_buffer->stream_bytes_written();
+    if (data_length == 0) {
+      // No buffered data for this encryption level.
+      continue;
+    }
+    size_t bytes_consumed = stream_delegate()->SendCryptoData(
+        level, data_length, send_buffer->stream_bytes_written(),
+        NOT_RETRANSMISSION);
+    send_buffer->OnStreamDataConsumed(bytes_consumed);
+    if (bytes_consumed < data_length) {
+      // Connection is write blocked.
+      break;
+    }
+  }
+}
+
+bool QuicCryptoStream::HasBufferedCryptoFrames() const {
+  QUIC_BUG_IF(quic_bug_12573_8,
+              !QuicVersionUsesCryptoFrames(session()->transport_version()))
+      << "Versions less than 47 don't use CRYPTO frames";
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    const QuicStreamSendBuffer& send_buffer = substreams_[level].send_buffer;
+    QUICHE_DCHECK_GE(send_buffer.stream_offset(),
+                     send_buffer.stream_bytes_written());
+    if (send_buffer.stream_offset() > send_buffer.stream_bytes_written()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level,
+                                          size_t offset,
+                                          size_t length) const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    // This only happens if a client was originally configured for a version
+    // greater than 45, but received a version negotiation packet and is
+    // attempting to retransmit for a version less than 47. Outside of tests,
+    // this is a misconfiguration of the client, and this connection will be
+    // doomed. Return false here to avoid trying to retransmit CRYPTO frames on
+    // the wrong transport version.
+    return false;
+  }
+  return substreams_[level].send_buffer.IsStreamDataOutstanding(offset, length);
+}
+
+bool QuicCryptoStream::IsWaitingForAcks() const {
+  if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
+    return QuicStream::IsWaitingForAcks();
+  }
+  for (EncryptionLevel level : AllEncryptionLevels()) {
+    if (substreams_[level].send_buffer.stream_bytes_outstanding()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+QuicCryptoStream::CryptoSubstream::CryptoSubstream(
+    QuicCryptoStream* crypto_stream,
+    EncryptionLevel)
+    : sequencer(crypto_stream),
+      send_buffer(crypto_stream->session()
+                      ->connection()
+                      ->helper()
+                      ->GetStreamSendBufferAllocator()) {}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_crypto_stream.h b/quiche/quic/core/quic_crypto_stream.h
new file mode 100644
index 0000000..64031b2
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_stream.h
@@ -0,0 +1,274 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
+
+#include <array>
+#include <cstddef>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class CachedNetworkParameters;
+class QuicSession;
+
+// Crypto handshake messages in QUIC take place over a reserved stream with the
+// id 1.  Each endpoint (client and server) will allocate an instance of a
+// subclass of QuicCryptoStream to send and receive handshake messages.  (In the
+// normal 1-RTT handshake, the client will send a client hello, CHLO, message.
+// The server will receive this message and respond with a server hello message,
+// SHLO.  At this point both sides will have established a crypto context they
+// can use to send encrypted messages.
+//
+// For more details:
+// https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
+class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
+ public:
+  explicit QuicCryptoStream(QuicSession* session);
+  QuicCryptoStream(const QuicCryptoStream&) = delete;
+  QuicCryptoStream& operator=(const QuicCryptoStream&) = delete;
+
+  ~QuicCryptoStream() override;
+
+  // Returns the per-packet framing overhead associated with sending a
+  // handshake message for |version|.
+  static QuicByteCount CryptoMessageFramingOverhead(
+      QuicTransportVersion version,
+      QuicConnectionId connection_id);
+
+  // QuicStream implementation
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  void OnDataAvailable() override;
+
+  // Called when a CRYPTO frame is received.
+  void OnCryptoFrame(const QuicCryptoFrame& frame);
+
+  // Called when a CRYPTO frame is ACKed.
+  bool OnCryptoFrameAcked(const QuicCryptoFrame& frame,
+                          QuicTime::Delta ack_delay_time);
+
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+  // Performs key extraction to derive a new secret of |result_len| bytes
+  // dependent on |label|, |context|, and the stream's negotiated subkey secret.
+  // Returns false if the handshake has not been confirmed or the parameters are
+  // invalid (e.g. |label| contains null bytes); returns true on success. This
+  // method is only supported for IETF QUIC and MUST NOT be called in gQUIC as
+  // that'll trigger an assert in DEBUG build.
+  virtual bool ExportKeyingMaterial(absl::string_view label,
+                                    absl::string_view context,
+                                    size_t result_len, std::string* result) = 0;
+
+  // Writes |data| to the QuicStream at level |level|.
+  virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data);
+
+  // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
+  // rejected. Note that the value returned by this function may vary during the
+  // handshake. Once |one_rtt_keys_available| returns true, the value returned
+  // by this function will not change for the rest of the lifetime of the
+  // QuicCryptoStream.
+  virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
+
+  // Returns true once an encrypter has been set for the connection.
+  virtual bool encryption_established() const = 0;
+
+  // Returns true once the crypto handshake has completed.
+  virtual bool one_rtt_keys_available() const = 0;
+
+  // Returns the parameters negotiated in the crypto handshake.
+  virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const = 0;
+
+  // Provides the message parser to use when data is received on this stream.
+  virtual CryptoMessageParser* crypto_message_parser() = 0;
+
+  // Called when a packet of encryption |level| has been successfully decrypted.
+  virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
+
+  // Called when a 1RTT packet has been acknowledged.
+  virtual void OnOneRttPacketAcknowledged() = 0;
+
+  // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+  virtual void OnHandshakePacketSent() = 0;
+
+  // Called when a handshake done frame has been received.
+  virtual void OnHandshakeDoneReceived() = 0;
+
+  // Called when a new token frame has been received.
+  virtual void OnNewTokenReceived(absl::string_view token) = 0;
+
+  // Called to get an address token.
+  virtual std::string GetAddressToken(
+      const CachedNetworkParameters* cached_network_params) const = 0;
+
+  // Called to validate |token|.
+  virtual bool ValidateAddressToken(absl::string_view token) const = 0;
+
+  // Get the last CachedNetworkParameters received from a valid address token.
+  virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
+      const = 0;
+
+  // Set the CachedNetworkParameters that will be returned by
+  // PreviousCachedNetworkParams.
+  // TODO(wub): This function is test only, move it to a test only library.
+  virtual void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) = 0;
+
+  // Returns current handshake state.
+  virtual HandshakeState GetHandshakeState() const = 0;
+
+  // Called to provide the server-side application state that must be checked
+  // when performing a 0-RTT TLS resumption.
+  //
+  // On a client, this may be called at any time; 0-RTT tickets will not be
+  // cached until this function is called. When a 0-RTT resumption is attempted,
+  // QuicSession::SetApplicationState will be called with the state provided by
+  // a call to this function on a previous connection.
+  //
+  // On a server, this function must be called before commencing the handshake,
+  // otherwise 0-RTT tickets will not be issued. On subsequent connections,
+  // 0-RTT will be rejected if the data passed into this function does not match
+  // the data passed in on the connection where the 0-RTT ticket was issued.
+  virtual void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> state) = 0;
+
+  // Returns the maximum number of bytes that can be buffered at a particular
+  // encryption level |level|.
+  virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
+
+  // Called to generate a decrypter for the next key phase. Each call should
+  // generate the key for phase n+1.
+  virtual std::unique_ptr<QuicDecrypter>
+  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+  // Called to generate an encrypter for the same key phase of the last
+  // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
+  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+
+  // Return the SSL struct object created by BoringSSL if the stream is using
+  // TLS1.3. Otherwise, return nullptr.
+  // This method is used in Envoy.
+  virtual SSL* GetSsl() const = 0;
+
+  // Called to cancel retransmission of unencrypted crypto stream data.
+  void NeuterUnencryptedStreamData();
+
+  // Called to cancel retransmission of data of encryption |level|.
+  void NeuterStreamDataOfEncryptionLevel(EncryptionLevel level);
+
+  // Override to record the encryption level of consumed data.
+  void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
+
+  // Returns whether there are any bytes pending retransmission in CRYPTO
+  // frames.
+  virtual bool HasPendingCryptoRetransmission() const;
+
+  // Writes any pending CRYPTO frame retransmissions.
+  void WritePendingCryptoRetransmission();
+
+  // Override to retransmit lost crypto data with the appropriate encryption
+  // level.
+  void WritePendingRetransmission() override;
+
+  // Override to send unacked crypto data with the appropriate encryption level.
+  bool RetransmitStreamData(QuicStreamOffset offset,
+                            QuicByteCount data_length,
+                            bool fin,
+                            TransmissionType type) override;
+
+  // Sends stream retransmission data at |encryption_level|.
+  QuicConsumedData RetransmitStreamDataAtLevel(
+      QuicStreamOffset retransmission_offset,
+      QuicByteCount retransmission_length,
+      EncryptionLevel encryption_level,
+      TransmissionType type);
+
+  // Returns the number of bytes of handshake data that have been received from
+  // the peer in either CRYPTO or STREAM frames.
+  uint64_t crypto_bytes_read() const;
+
+  // Returns the number of bytes of handshake data that have been received from
+  // the peer in CRYPTO frames at a particular encryption level.
+  QuicByteCount BytesReadOnLevel(EncryptionLevel level) const;
+
+  // Writes |data_length| of data of a crypto frame to |writer|. The data
+  // written is from the send buffer for encryption level |level| and starts at
+  // |offset|.
+  bool WriteCryptoFrame(EncryptionLevel level,
+                        QuicStreamOffset offset,
+                        QuicByteCount data_length,
+                        QuicDataWriter* writer);
+
+  // Called when data from a CRYPTO frame is considered lost. The lost data is
+  // identified by the encryption level, offset, and length in |crypto_frame|.
+  void OnCryptoFrameLost(QuicCryptoFrame* crypto_frame);
+
+  // Called to retransmit any outstanding data in the range indicated by the
+  // encryption level, offset, and length in |crypto_frame|. Returns true if all
+  // data gets retransmitted.
+  bool RetransmitData(QuicCryptoFrame* crypto_frame, TransmissionType type);
+
+  // Called to write buffered crypto frames.
+  void WriteBufferedCryptoFrames();
+
+  // Returns true if there is buffered crypto frames.
+  bool HasBufferedCryptoFrames() const;
+
+  // Returns true if any portion of the data at encryption level |level|
+  // starting at |offset| for |length| bytes is outstanding.
+  bool IsFrameOutstanding(EncryptionLevel level,
+                          size_t offset,
+                          size_t length) const;
+
+  // Returns true if the crypto handshake is still waiting for acks of sent
+  // data, and false if all data has been acked.
+  bool IsWaitingForAcks() const;
+
+  // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
+  // with the data available in |sequencer| and |level|, and marks the data
+  // passed to ProcessInput as consumed.
+  virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
+                                          EncryptionLevel level);
+
+  QuicStreamSequencer* GetStreamSequencerForLevel(EncryptionLevel level) {
+    return &substreams_[level].sequencer;
+  }
+
+ private:
+  // Data sent and received in CRYPTO frames is sent at multiple encryption
+  // levels. Some of the state for the single logical crypto stream is split
+  // across encryption levels, and a CryptoSubstream is used to manage that
+  // state for a particular encryption level.
+  struct QUIC_EXPORT_PRIVATE CryptoSubstream {
+    CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
+
+    QuicStreamSequencer sequencer;
+    QuicStreamSendBuffer send_buffer;
+  };
+
+  // Consumed data according to encryption levels.
+  // TODO(fayang): This is not needed once switching from QUIC crypto to
+  // TLS 1.3, which never encrypts crypto data.
+  QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
+
+  // Keeps state for data sent/received in CRYPTO frames at each encryption
+  // level.
+  std::array<CryptoSubstream, NUM_ENCRYPTION_LEVELS> substreams_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
diff --git a/quiche/quic/core/quic_crypto_stream_test.cc b/quiche/quic/core/quic_crypto_stream_test.cc
new file mode 100644
index 0000000..4b298c3
--- /dev/null
+++ b/quiche/quic/core/quic_crypto_stream_test.cc
@@ -0,0 +1,722 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_crypto_stream.h"
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicCryptoStream : public QuicCryptoStream,
+                             public QuicCryptoHandshaker {
+ public:
+  explicit MockQuicCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        params_(new QuicCryptoNegotiatedParameters) {}
+  MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
+  MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    messages_.push_back(message);
+  }
+
+  std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }
+
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override { return false; }
+  bool one_rtt_keys_available() const override { return false; }
+
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  std::vector<CryptoHandshakeMessage> messages_;
+};
+
+class QuicCryptoStreamTest : public QuicTest {
+ public:
+  QuicCryptoStreamTest()
+      : connection_(new MockQuicConnection(&helper_,
+                                           &alarm_factory_,
+                                           Perspective::IS_CLIENT)),
+        session_(connection_, /*create_mock_crypto_stream=*/false) {
+    EXPECT_CALL(*static_cast<MockPacketWriter*>(connection_->writer()),
+                WritePacket(_, _, _, _, _))
+        .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
+    stream_ = new MockQuicCryptoStream(&session_);
+    session_.SetCryptoStream(stream_);
+    session_.Initialize();
+    message_.set_tag(kSHLO);
+    message_.SetStringPiece(1, "abc");
+    message_.SetStringPiece(2, "def");
+    ConstructHandshakeMessage();
+  }
+  QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
+  QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;
+
+  void ConstructHandshakeMessage() {
+    CryptoFramer framer;
+    message_data_ = framer.ConstructHandshakeMessage(message_);
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  MockQuicSpdySession session_;
+  MockQuicCryptoStream* stream_;
+  CryptoHandshakeMessage message_;
+  std::unique_ptr<QuicData> message_data_;
+};
+
+TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
+  EXPECT_FALSE(stream_->encryption_established());
+  EXPECT_FALSE(stream_->one_rtt_keys_available());
+}
+
+TEST_F(QuicCryptoStreamTest, ProcessRawData) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    stream_->OnStreamFrame(QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+        /*fin=*/false,
+        /*offset=*/0, message_data_->AsStringPiece()));
+  } else {
+    stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
+                                           message_data_->AsStringPiece()));
+  }
+  ASSERT_EQ(1u, stream_->messages()->size());
+  const CryptoHandshakeMessage& message = (*stream_->messages())[0];
+  EXPECT_EQ(kSHLO, message.tag());
+  EXPECT_EQ(2u, message.tag_value_map().size());
+  EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
+  EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
+}
+
+TEST_F(QuicCryptoStreamTest, ProcessBadData) {
+  std::string bad(message_data_->data(), message_data_->length());
+  const int kFirstTagIndex = sizeof(uint32_t) +  // message tag
+                             sizeof(uint16_t) +  // number of tag-value pairs
+                             sizeof(uint16_t);   // padding
+  EXPECT_EQ(1, bad[kFirstTagIndex]);
+  bad[kFirstTagIndex] = 0x7F;  // out of order tag
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
+                                            testing::_, testing::_));
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    stream_->OnStreamFrame(QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+        /*fin=*/false, /*offset=*/0, bad));
+  } else {
+    stream_->OnCryptoFrame(
+        QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
+  }
+}
+
+TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
+  EXPECT_FALSE(
+      QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Lost [0, 1000).
+  stream_->OnStreamFrameLost(0, 1000, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  // Lost [1200, 2000).
+  stream_->OnStreamFrameLost(1200, 800, false);
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1000, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
+  // they are in different encryption levels.
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 150, 1200, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 650, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+  connection_->SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Lost [0, 1000).
+  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Lost [1200, 2000).
+  lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
+  // they are in different encryption levels.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+}
+
+// Regression test for handling the missing ENCRYPTION_HANDSHAKE in
+// quic_crypto_stream.cc. This test is essentially the same as
+// RetransmitCryptoDataInCryptoFrames, except it uses ENCRYPTION_HANDSHAKE in
+// place of ENCRYPTION_ZERO_RTT.
+TEST_F(QuicCryptoStreamTest, RetransmitEncryptionHandshakeLevelCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  InSequence s;
+  // Send [0, 1000) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1000, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1000, 2000) in ENCRYPTION_HANDSHAKE.
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_HANDSHAKE, std::move(encrypter));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(ENCRYPTION_HANDSHAKE, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_HANDSHAKE, data);
+  connection_->SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Lost [1000, 1200).
+  QuicCryptoFrame lost_frame(ENCRYPTION_HANDSHAKE, 0, 200);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Verify [1000, 1200) is sent.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 200, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+}
+
+TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+
+  // Lost [0, 1350).
+  stream_->OnStreamFrameLost(0, 1350, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  // Neuters [0, 1350).
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  // Lost [0, 1350) again.
+  stream_->OnStreamFrameLost(0, 1350, false);
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+
+  // Lost [1350, 2000).
+  stream_->OnStreamFrameLost(1350, 650, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+}
+
+TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetEncrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+
+  // Lost [0, 1350).
+  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Neuters [0, 1350).
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+  // Lost [0, 1350) again.
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+
+  // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
+  // level.
+  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  stream_->NeuterUnencryptedStreamData();
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Ack [2000, 2500).
+  QuicByteCount newly_acked_length = 0;
+  stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
+                              QuicTime::Zero(), &newly_acked_length);
+  EXPECT_EQ(500u, newly_acked_length);
+
+  // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 650, 1350, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_.ConsumeData(
+            QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
+            1350, NO_FIN, HANDSHAKE_RETRANSMISSION, absl::nullopt);
+      }));
+
+  EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false,
+                                             HANDSHAKE_RETRANSMISSION));
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Force session to send [1350, 1500) again and all data is consumed.
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 650, 1350, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 200, 2500, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false,
+                                            HANDSHAKE_RETRANSMISSION));
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
+  // Force to send an empty frame.
+  EXPECT_TRUE(
+      stream_->RetransmitStreamData(0, 0, false, HANDSHAKE_RETRANSMISSION));
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
+  std::unique_ptr<NullEncrypter> encrypter =
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
+  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+  connection_->SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Ack [2000, 2500).
+  QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
+  EXPECT_TRUE(
+      stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
+
+  // Retransmit only [1350, 1500).
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
+  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
+
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  // Retransmit [1350, 2700) again and all data is sent.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
+  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
+  // Verify connection's encryption level has restored.
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  // Force to send an empty frame.
+  QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
+  stream_->RetransmitData(&empty_frame, HANDSHAKE_RETRANSMISSION);
+}
+
+// Regression test for b/115926584.
+TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  std::string data(1350, 'a');
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(testing::Return(QuicConsumedData(0, false)));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  // Although there is no outstanding data, verify session has pending crypto
+  // data.
+  EXPECT_TRUE(session_.HasUnackedCryptoData());
+
+  EXPECT_CALL(
+      session_,
+      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+                 1350, 0, _, _, _))
+      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_.HasUnackedCryptoData());
+}
+
+TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_.HasUnackedCryptoData());
+}
+
+// Regression test for bugfix of GetPacketHeaderSize.
+TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
+  for (const ParsedQuicVersion& version :
+       AllSupportedVersionsWithQuicCrypto()) {
+    SCOPED_TRACE(version);
+    QuicByteCount expected_overhead = 48;
+    if (version.HasIetfInvariantHeader()) {
+      expected_overhead += 4;
+    }
+    if (version.HasLongHeaderLengths()) {
+      expected_overhead += 3;
+    }
+    if (version.HasLengthPrefixedConnectionIds()) {
+      expected_overhead += 1;
+    }
+    EXPECT_EQ(expected_overhead,
+              QuicCryptoStream::CryptoMessageFramingOverhead(
+                  version.transport_version, TestConnectionId()));
+  }
+}
+
+TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  // Only consumed 1000 bytes.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Return(1000));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
+
+  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
+  // because there is buffered data.
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  connection_->SetEncrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
+      .WillOnce(Return(350));
+  // Partial write of ENCRYPTION_ZERO_RTT data.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Return(1000));
+  stream_->WriteBufferedCryptoFrames();
+  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
+  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
+
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
+      .WillOnce(Return(350));
+  stream_->WriteBufferedCryptoFrames();
+  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
+}
+
+TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
+                          'a');
+
+  // Set offset to 1 so that we guarantee the data gets buffered instead of
+  // immediately processed.
+  QuicStreamOffset offset = 1;
+  stream_->OnCryptoFrame(
+      QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
+}
+
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  InSequence s;
+  // Send [0, 1350) in ENCRYPTION_INITIAL.
+  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+  std::string data(1350, 'a');
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+
+  // Lost [0, 1000).
+  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
+  stream_->OnCryptoFrameLost(&lost_frame);
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Simulate connection is constrained by amplification restriction.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Return(0));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+  // Connection gets unblocked.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+      .WillOnce(Invoke(connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  stream_->WritePendingCryptoRetransmission();
+  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+}
+
+// Regression test for b/203199510
+TEST_F(QuicCryptoStreamTest, EmptyCryptoFrame) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  QuicCryptoFrame empty_crypto_frame(ENCRYPTION_INITIAL, 0, nullptr, 0);
+  stream_->OnCryptoFrame(empty_crypto_frame);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_data_reader.cc b/quiche/quic/core/quic_data_reader.cc
new file mode 100644
index 0000000..e82c598
--- /dev/null
+++ b/quiche/quic/core/quic_data_reader.cc
@@ -0,0 +1,176 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_data_reader.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+QuicDataReader::QuicDataReader(absl::string_view data)
+    : quiche::QuicheDataReader(data) {}
+
+QuicDataReader::QuicDataReader(const char* data, const size_t len)
+    : QuicDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
+
+QuicDataReader::QuicDataReader(const char* data,
+                               const size_t len,
+                               quiche::Endianness endianness)
+    : quiche::QuicheDataReader(data, len, endianness) {}
+
+bool QuicDataReader::ReadUFloat16(uint64_t* result) {
+  uint16_t value;
+  if (!ReadUInt16(&value)) {
+    return false;
+  }
+
+  *result = value;
+  if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
+    // Fast path: either the value is denormalized (no hidden bit), or
+    // normalized (hidden bit set, exponent offset by one) with exponent zero.
+    // Zero exponent offset by one sets the bit exactly where the hidden bit is.
+    // So in both cases the value encodes itself.
+    return true;
+  }
+
+  uint16_t exponent =
+      value >> kUFloat16MantissaBits;  // No sign extend on uint!
+  // After the fast pass, the exponent is at least one (offset by one).
+  // Un-offset the exponent.
+  --exponent;
+  QUICHE_DCHECK_GE(exponent, 1);
+  QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
+  // Here we need to clear the exponent and set the hidden bit. We have already
+  // decremented the exponent, so when we subtract it, it leaves behind the
+  // hidden bit.
+  *result -= exponent << kUFloat16MantissaBits;
+  *result <<= exponent;
+  QUICHE_DCHECK_GE(*result,
+                   static_cast<uint64_t>(1 << kUFloat16MantissaEffectiveBits));
+  QUICHE_DCHECK_LE(*result, kUFloat16MaxValue);
+  return true;
+}
+
+bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id,
+                                      uint8_t length) {
+  if (length == 0) {
+    connection_id->set_length(0);
+    return true;
+  }
+
+  if (BytesRemaining() < length) {
+    return false;
+  }
+
+  connection_id->set_length(length);
+  const bool ok =
+      ReadBytes(connection_id->mutable_data(), connection_id->length());
+  QUICHE_DCHECK(ok);
+  return ok;
+}
+
+bool QuicDataReader::ReadLengthPrefixedConnectionId(
+    QuicConnectionId* connection_id) {
+  uint8_t connection_id_length;
+  if (!ReadUInt8(&connection_id_length)) {
+    return false;
+  }
+  return ReadConnectionId(connection_id, connection_id_length);
+}
+
+QuicVariableLengthIntegerLength QuicDataReader::PeekVarInt62Length() {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+  const unsigned char* next =
+      reinterpret_cast<const unsigned char*>(data() + pos());
+  if (BytesRemaining() == 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  return static_cast<QuicVariableLengthIntegerLength>(
+      1 << ((*next & 0b11000000) >> 6));
+}
+
+// Read an IETF/QUIC formatted 62-bit Variable Length Integer.
+//
+// Performance notes
+//
+// Measurements and experiments showed that unrolling the four cases
+// like this and dereferencing next_ as we do (*(next_+n) --- and then
+// doing a single pos_+=x at the end) gains about 10% over making a
+// loop and dereferencing next_ such as *(next_++)
+//
+// Using a register for pos_ was not helpful.
+//
+// Branches are ordered to increase the likelihood of the first being
+// taken.
+//
+// Low-level optimization is useful here because this function will be
+// called frequently, leading to outsize benefits.
+bool QuicDataReader::ReadVarInt62(uint64_t* result) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining = BytesRemaining();
+  const unsigned char* next =
+      reinterpret_cast<const unsigned char*>(data() + pos());
+  if (remaining != 0) {
+    switch (*next & 0xc0) {
+      case 0xc0:
+        // Leading 0b11...... is 8 byte encoding
+        if (remaining >= 8) {
+          *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) +
+                    (static_cast<uint64_t>(*(next + 1)) << 48) +
+                    (static_cast<uint64_t>(*(next + 2)) << 40) +
+                    (static_cast<uint64_t>(*(next + 3)) << 32) +
+                    (static_cast<uint64_t>(*(next + 4)) << 24) +
+                    (static_cast<uint64_t>(*(next + 5)) << 16) +
+                    (static_cast<uint64_t>(*(next + 6)) << 8) +
+                    (static_cast<uint64_t>(*(next + 7)) << 0);
+          AdvancePos(8);
+          return true;
+        }
+        return false;
+
+      case 0x80:
+        // Leading 0b10...... is 4 byte encoding
+        if (remaining >= 4) {
+          *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) +
+                    (((*(next + 2)) << 8)) + (((*(next + 3)) << 0));
+          AdvancePos(4);
+          return true;
+        }
+        return false;
+
+      case 0x40:
+        // Leading 0b01...... is 2 byte encoding
+        if (remaining >= 2) {
+          *result = (((*(next)) & 0x3f) << 8) + (*(next + 1));
+          AdvancePos(2);
+          return true;
+        }
+        return false;
+
+      case 0x00:
+        // Leading 0b00...... is 1 byte encoding
+        *result = (*next) & 0x3f;
+        AdvancePos(1);
+        return true;
+    }
+  }
+  return false;
+}
+
+bool QuicDataReader::ReadStringPieceVarInt62(absl::string_view* result) {
+  uint64_t result_length;
+  if (!ReadVarInt62(&result_length)) {
+    return false;
+  }
+  return ReadStringPiece(result, result_length);
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_data_reader.h b/quiche/quic/core/quic_data_reader.h
new file mode 100644
index 0000000..c21f2be
--- /dev/null
+++ b/quiche/quic/core/quic_data_reader.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
+#define QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+// Used for reading QUIC data. Though there isn't really anything terribly
+// QUIC-specific here, it's a helper class that's useful when doing QUIC
+// framing.
+//
+// To use, simply construct a QuicDataReader using the underlying buffer that
+// you'd like to read fields from, then call one of the Read*() methods to
+// actually do some reading.
+//
+// This class keeps an internal iterator to keep track of what's already been
+// read and each successive Read*() call automatically increments said iterator
+// on success. On failure, internal state of the QuicDataReader should not be
+// trusted and it is up to the caller to throw away the failed instance and
+// handle the error as appropriate. None of the Read*() methods should ever be
+// called after failure, as they will also fail immediately.
+class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader {
+ public:
+  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
+  // Caller must provide an underlying buffer to work on.
+  explicit QuicDataReader(absl::string_view data);
+  // Constructs a reader using NETWORK_BYTE_ORDER endianness.
+  // Caller must provide an underlying buffer to work on.
+  QuicDataReader(const char* data, const size_t len);
+  // Constructs a reader using the specified endianness.
+  // Caller must provide an underlying buffer to work on.
+  QuicDataReader(const char* data,
+                 const size_t len,
+                 quiche::Endianness endianness);
+  QuicDataReader(const QuicDataReader&) = delete;
+  QuicDataReader& operator=(const QuicDataReader&) = delete;
+
+  // Empty destructor.
+  ~QuicDataReader() {}
+
+  // Reads a 16-bit unsigned float into the given output parameter.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadUFloat16(uint64_t* result);
+
+  // Reads connection ID into the given output parameter.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadConnectionId(QuicConnectionId* connection_id, uint8_t length);
+
+  // Reads 8-bit connection ID length followed by connection ID of that length.
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadLengthPrefixedConnectionId(QuicConnectionId* connection_id);
+
+  // Returns the length in bytes of a variable length integer based on the next
+  // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure.
+  QuicVariableLengthIntegerLength PeekVarInt62Length();
+
+  // Read an IETF-encoded Variable Length Integer and place the result
+  // in |*result|.
+  // Returns true if it works, false if not. The only error is that
+  // there is not enough in the buffer to read the number.
+  // If there is an error, |*result| is not altered.
+  // Numbers are encoded per the rules in draft-ietf-quic-transport-10.txt
+  // and that the integers in the range 0 ... (2^62)-1.
+  bool ReadVarInt62(uint64_t* result);
+
+  // Reads a string prefixed with a Variable Length integer length into the
+  // given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Forwards the internal iterator on success.
+  // Returns true on success, false otherwise.
+  bool ReadStringPieceVarInt62(absl::string_view* result);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DATA_READER_H_
diff --git a/quiche/quic/core/quic_data_writer.cc b/quiche/quic/core/quic_data_writer.cc
new file mode 100644
index 0000000..571d2b0
--- /dev/null
+++ b/quiche/quic/core/quic_data_writer.cc
@@ -0,0 +1,260 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_data_writer.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+QuicDataWriter::QuicDataWriter(size_t size, char* buffer)
+    : quiche::QuicheDataWriter(size, buffer) {}
+
+QuicDataWriter::QuicDataWriter(size_t size,
+                               char* buffer,
+                               quiche::Endianness endianness)
+    : quiche::QuicheDataWriter(size, buffer, endianness) {}
+
+QuicDataWriter::~QuicDataWriter() {}
+
+bool QuicDataWriter::WriteUFloat16(uint64_t value) {
+  uint16_t result;
+  if (value < (UINT64_C(1) << kUFloat16MantissaEffectiveBits)) {
+    // Fast path: either the value is denormalized, or has exponent zero.
+    // Both cases are represented by the value itself.
+    result = static_cast<uint16_t>(value);
+  } else if (value >= kUFloat16MaxValue) {
+    // Value is out of range; clamp it to the maximum representable.
+    result = std::numeric_limits<uint16_t>::max();
+  } else {
+    // The highest bit is between position 13 and 42 (zero-based), which
+    // corresponds to exponent 1-30. In the output, mantissa is from 0 to 10,
+    // hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11
+    // and count the shifts.
+    uint16_t exponent = 0;
+    for (uint16_t offset = 16; offset > 0; offset /= 2) {
+      // Right-shift the value until the highest bit is in position 11.
+      // For offset of 16, 8, 4, 2 and 1 (binary search over 1-30),
+      // shift if the bit is at or above 11 + offset.
+      if (value >= (UINT64_C(1) << (kUFloat16MantissaBits + offset))) {
+        exponent += offset;
+        value >>= offset;
+      }
+    }
+
+    QUICHE_DCHECK_GE(exponent, 1);
+    QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
+    QUICHE_DCHECK_GE(value, UINT64_C(1) << kUFloat16MantissaBits);
+    QUICHE_DCHECK_LT(value, UINT64_C(1) << kUFloat16MantissaEffectiveBits);
+
+    // Hidden bit (position 11) is set. We should remove it and increment the
+    // exponent. Equivalently, we just add it to the exponent.
+    // This hides the bit.
+    result = static_cast<uint16_t>(value + (exponent << kUFloat16MantissaBits));
+  }
+
+  if (endianness() == quiche::NETWORK_BYTE_ORDER) {
+    result = quiche::QuicheEndian::HostToNet16(result);
+  }
+  return WriteBytes(&result, sizeof(result));
+}
+
+bool QuicDataWriter::WriteConnectionId(QuicConnectionId connection_id) {
+  if (connection_id.IsEmpty()) {
+    return true;
+  }
+  return WriteBytes(connection_id.data(), connection_id.length());
+}
+
+bool QuicDataWriter::WriteLengthPrefixedConnectionId(
+    QuicConnectionId connection_id) {
+  return WriteUInt8(connection_id.length()) && WriteConnectionId(connection_id);
+}
+
+bool QuicDataWriter::WriteRandomBytes(QuicRandom* random, size_t length) {
+  char* dest = BeginWrite(length);
+  if (!dest) {
+    return false;
+  }
+
+  random->RandBytes(dest, length);
+  IncreaseLength(length);
+  return true;
+}
+
+bool QuicDataWriter::WriteInsecureRandomBytes(QuicRandom* random,
+                                              size_t length) {
+  char* dest = BeginWrite(length);
+  if (!dest) {
+    return false;
+  }
+
+  random->InsecureRandBytes(dest, length);
+  IncreaseLength(length);
+  return true;
+}
+
+// Converts a uint64_t into an IETF/Quic formatted Variable Length
+// Integer. IETF Variable Length Integers have 62 significant bits, so
+// the value to write must be in the range of 0..(2^62)-1.
+//
+// Performance notes
+//
+// Measurements and experiments showed that unrolling the four cases
+// like this and dereferencing next_ as we do (*(next_+n)) gains about
+// 10% over making a loop and dereferencing it as *(next_++)
+//
+// Using a register for next didn't help.
+//
+// Branches are ordered to increase the likelihood of the first being
+// taken.
+//
+// Low-level optimization is useful here because this function will be
+// called frequently, leading to outsize benefits.
+bool QuicDataWriter::WriteVarInt62(uint64_t value) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining_bytes = remaining();
+  char* next = buffer() + length();
+
+  if ((value & kVarInt62ErrorMask) == 0) {
+    // We know the high 2 bits are 0 so |value| is legal.
+    // We can do the encoding.
+    if ((value & kVarInt62Mask8Bytes) != 0) {
+      // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte
+      // encoding.
+      if (remaining_bytes >= 8) {
+        *(next + 0) = ((value >> 56) & 0x3f) + 0xc0;
+        *(next + 1) = (value >> 48) & 0xff;
+        *(next + 2) = (value >> 40) & 0xff;
+        *(next + 3) = (value >> 32) & 0xff;
+        *(next + 4) = (value >> 24) & 0xff;
+        *(next + 5) = (value >> 16) & 0xff;
+        *(next + 6) = (value >> 8) & 0xff;
+        *(next + 7) = value & 0xff;
+        IncreaseLength(8);
+        return true;
+      }
+      return false;
+    }
+    // The high-order-4 bytes are all 0, check for a 1, 2, or 4-byte
+    // encoding
+    if ((value & kVarInt62Mask4Bytes) != 0) {
+      // The encoding will not fit into 2 bytes, Do a 4-byte
+      // encoding.
+      if (remaining_bytes >= 4) {
+        *(next + 0) = ((value >> 24) & 0x3f) + 0x80;
+        *(next + 1) = (value >> 16) & 0xff;
+        *(next + 2) = (value >> 8) & 0xff;
+        *(next + 3) = value & 0xff;
+        IncreaseLength(4);
+        return true;
+      }
+      return false;
+    }
+    // The high-order bits are all 0. Check to see if the number
+    // can be encoded as one or two bytes. One byte encoding has
+    // only 6 significant bits (bits 0xffffffff ffffffc0 are all 0).
+    // Two byte encoding has more than 6, but 14 or less significant
+    // bits (bits 0xffffffff ffffc000 are 0 and 0x00000000 00003fc0
+    // are not 0)
+    if ((value & kVarInt62Mask2Bytes) != 0) {
+      // Do 2-byte encoding
+      if (remaining_bytes >= 2) {
+        *(next + 0) = ((value >> 8) & 0x3f) + 0x40;
+        *(next + 1) = (value)&0xff;
+        IncreaseLength(2);
+        return true;
+      }
+      return false;
+    }
+    if (remaining_bytes >= 1) {
+      // Do 1-byte encoding
+      *next = (value & 0x3f);
+      IncreaseLength(1);
+      return true;
+    }
+    return false;
+  }
+  // Can not encode, high 2 bits not 0
+  return false;
+}
+
+bool QuicDataWriter::WriteVarInt62(
+    uint64_t value,
+    QuicVariableLengthIntegerLength write_length) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining_bytes = remaining();
+  if (remaining_bytes < write_length) {
+    return false;
+  }
+
+  const QuicVariableLengthIntegerLength min_length = GetVarInt62Len(value);
+  if (write_length < min_length) {
+    QUIC_BUG(quic_bug_10347_1) << "Cannot write value " << value
+                               << " with write_length " << write_length;
+    return false;
+  }
+  if (write_length == min_length) {
+    return WriteVarInt62(value);
+  }
+
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_2) {
+    return WriteUInt8(0b01000000) && WriteUInt8(value);
+  }
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_4) {
+    return WriteUInt8(0b10000000) && WriteUInt8(0) && WriteUInt16(value);
+  }
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_8) {
+    return WriteUInt8(0b11000000) && WriteUInt8(0) && WriteUInt16(0) &&
+           WriteUInt32(value);
+  }
+
+  QUIC_BUG(quic_bug_10347_2)
+      << "Invalid write_length " << static_cast<int>(write_length);
+  return false;
+}
+
+// static
+QuicVariableLengthIntegerLength QuicDataWriter::GetVarInt62Len(uint64_t value) {
+  if ((value & kVarInt62ErrorMask) != 0) {
+    QUIC_BUG(quic_bug_10347_3) << "Attempted to encode a value, " << value
+                               << ", that is too big for VarInt62";
+    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  if ((value & kVarInt62Mask8Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+  }
+  if ((value & kVarInt62Mask4Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  }
+  if ((value & kVarInt62Mask2Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_1;
+}
+
+bool QuicDataWriter::WriteStringPieceVarInt62(
+    const absl::string_view& string_piece) {
+  if (!WriteVarInt62(string_piece.size())) {
+    return false;
+  }
+  if (!string_piece.empty()) {
+    if (!WriteBytes(string_piece.data(), string_piece.size())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_data_writer.h b/quiche/quic/core/quic_data_writer.h
new file mode 100644
index 0000000..b1cd198
--- /dev/null
+++ b/quiche/quic/core/quic_data_writer.h
@@ -0,0 +1,100 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
+#define QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_data_writer.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+class QuicRandom;
+
+// Maximum value that can be properly encoded using VarInt62 coding.
+const uint64_t kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff);
+
+// VarInt62 encoding masks
+// If a uint64_t anded with a mask is not 0 then the value is encoded
+// using that length (or is too big, in the case of kVarInt62ErrorMask).
+// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
+// and if none are non-0, the value is encoded in 1 byte.
+const uint64_t kVarInt62ErrorMask = UINT64_C(0xc000000000000000);
+const uint64_t kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000);
+const uint64_t kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000);
+const uint64_t kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0);
+
+// This class provides facilities for packing QUIC data.
+//
+// The QuicDataWriter supports appending primitive values (int, string, etc)
+// to a frame instance.  The internal memory buffer is exposed as the "data"
+// of the QuicDataWriter.
+class QUIC_EXPORT_PRIVATE QuicDataWriter : public quiche::QuicheDataWriter {
+ public:
+  // Creates a QuicDataWriter where |buffer| is not owned
+  // using NETWORK_BYTE_ORDER endianness.
+  QuicDataWriter(size_t size, char* buffer);
+  // Creates a QuicDataWriter where |buffer| is not owned
+  // using the specified endianness.
+  QuicDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
+  QuicDataWriter(const QuicDataWriter&) = delete;
+  QuicDataWriter& operator=(const QuicDataWriter&) = delete;
+
+  ~QuicDataWriter();
+
+  // Methods for adding to the payload.  These values are appended to the end
+  // of the QuicDataWriter payload.
+
+  // Write an unsigned-integer value per the IETF QUIC/Variable Length
+  // Integer encoding rules (see draft-ietf-quic-transport-08.txt).
+  // IETF Variable Length Integers have 62 significant bits, so the
+  // value to write must be in the range of 0...(2^62)-1. Returns
+  // false if the value is out of range or if there is no room in the
+  // buffer.
+  bool WriteVarInt62(uint64_t value);
+
+  // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
+  // This is not as optimized as WriteVarInt62(uint64_t).
+  // Returns false if the value does not fit in the specified write_length or if
+  // there is no room in the buffer.
+  bool WriteVarInt62(uint64_t value,
+                     QuicVariableLengthIntegerLength write_length);
+
+  // Writes a string piece as a consecutive length/content pair. The
+  // length is VarInt62 encoded.
+  bool WriteStringPieceVarInt62(const absl::string_view& string_piece);
+
+  // Utility function to return the number of bytes needed to encode
+  // the given value using IETF VarInt62 encoding. Returns the number
+  // of bytes required to encode the given integer or 0 if the value
+  // is too large to encode.
+  static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value);
+
+  // Write unsigned floating point corresponding to the value. Large values are
+  // clamped to the maximum representable (kUFloat16MaxValue). Values that can
+  // not be represented directly are rounded down.
+  bool WriteUFloat16(uint64_t value);
+  // Write connection ID to the payload.
+  bool WriteConnectionId(QuicConnectionId connection_id);
+
+  // Write 8-bit length followed by connection ID to the payload.
+  bool WriteLengthPrefixedConnectionId(QuicConnectionId connection_id);
+
+  // Write |length| random bytes generated by |random|.
+  bool WriteRandomBytes(QuicRandom* random, size_t length);
+
+  // Write |length| random bytes generated by |random|. This MUST NOT be used
+  // for any application that requires cryptographically-secure randomness.
+  bool WriteInsecureRandomBytes(QuicRandom* random, size_t length);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
diff --git a/quiche/quic/core/quic_data_writer_test.cc b/quiche/quic/core/quic_data_writer_test.cc
new file mode 100644
index 0000000..40ad70e
--- /dev/null
+++ b/quiche/quic/core/quic_data_writer_test.cc
@@ -0,0 +1,1281 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_data_writer.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+char* AsChars(unsigned char* data) {
+  return reinterpret_cast<char*>(data);
+}
+
+struct TestParams {
+  explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
+
+  quiche::Endianness endianness;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
+      "ByteOrder");
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (quiche::Endianness endianness :
+       {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
+    params.push_back(TestParams(endianness));
+  }
+  return params;
+}
+
+class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
+                         QuicDataWriterTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
+  // Check the arithmetic on the constants - otherwise the values below make
+  // no sense.
+  EXPECT_EQ(30, kUFloat16MaxExponent);
+  EXPECT_EQ(11, kUFloat16MantissaBits);
+  EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
+  EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
+}
+
+TEST_P(QuicDataWriterTest, WriteUFloat16) {
+  struct TestCase {
+    uint64_t decoded;
+    uint16_t encoded;
+  };
+  TestCase test_cases[] = {
+      // Small numbers represent themselves.
+      {0, 0},
+      {1, 1},
+      {2, 2},
+      {3, 3},
+      {4, 4},
+      {5, 5},
+      {6, 6},
+      {7, 7},
+      {15, 15},
+      {31, 31},
+      {42, 42},
+      {123, 123},
+      {1234, 1234},
+      // Check transition through 2^11.
+      {2046, 2046},
+      {2047, 2047},
+      {2048, 2048},
+      {2049, 2049},
+      // Running out of mantissa at 2^12.
+      {4094, 4094},
+      {4095, 4095},
+      {4096, 4096},
+      {4097, 4096},
+      {4098, 4097},
+      {4099, 4097},
+      {4100, 4098},
+      {4101, 4098},
+      // Check transition through 2^13.
+      {8190, 6143},
+      {8191, 6143},
+      {8192, 6144},
+      {8193, 6144},
+      {8194, 6144},
+      {8195, 6144},
+      {8196, 6145},
+      {8197, 6145},
+      // Half-way through the exponents.
+      {0x7FF8000, 0x87FF},
+      {0x7FFFFFF, 0x87FF},
+      {0x8000000, 0x8800},
+      {0xFFF0000, 0x8FFF},
+      {0xFFFFFFF, 0x8FFF},
+      {0x10000000, 0x9000},
+      // Transition into the largest exponent.
+      {0x1FFFFFFFFFE, 0xF7FF},
+      {0x1FFFFFFFFFF, 0xF7FF},
+      {0x20000000000, 0xF800},
+      {0x20000000001, 0xF800},
+      {0x2003FFFFFFE, 0xF800},
+      {0x2003FFFFFFF, 0xF800},
+      {0x20040000000, 0xF801},
+      {0x20040000001, 0xF801},
+      // Transition into the max value and clamping.
+      {0x3FF80000000, 0xFFFE},
+      {0x3FFBFFFFFFF, 0xFFFE},
+      {0x3FFC0000000, 0xFFFF},
+      {0x3FFC0000001, 0xFFFF},
+      {0x3FFFFFFFFFF, 0xFFFF},
+      {0x40000000000, 0xFFFF},
+      {0xFFFFFFFFFFFFFFFF, 0xFFFF},
+  };
+  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+
+  for (int i = 0; i < num_test_cases; ++i) {
+    char buffer[2];
+    QuicDataWriter writer(2, buffer, GetParam().endianness);
+    EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
+    uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      result = quiche::QuicheEndian::HostToNet16(result);
+    }
+    EXPECT_EQ(test_cases[i].encoded, result);
+  }
+}
+
+TEST_P(QuicDataWriterTest, ReadUFloat16) {
+  struct TestCase {
+    uint64_t decoded;
+    uint16_t encoded;
+  };
+  TestCase test_cases[] = {
+      // There are fewer decoding test cases because encoding truncates, and
+      // decoding returns the smallest expansion.
+      // Small numbers represent themselves.
+      {0, 0},
+      {1, 1},
+      {2, 2},
+      {3, 3},
+      {4, 4},
+      {5, 5},
+      {6, 6},
+      {7, 7},
+      {15, 15},
+      {31, 31},
+      {42, 42},
+      {123, 123},
+      {1234, 1234},
+      // Check transition through 2^11.
+      {2046, 2046},
+      {2047, 2047},
+      {2048, 2048},
+      {2049, 2049},
+      // Running out of mantissa at 2^12.
+      {4094, 4094},
+      {4095, 4095},
+      {4096, 4096},
+      {4098, 4097},
+      {4100, 4098},
+      // Check transition through 2^13.
+      {8190, 6143},
+      {8192, 6144},
+      {8196, 6145},
+      // Half-way through the exponents.
+      {0x7FF8000, 0x87FF},
+      {0x8000000, 0x8800},
+      {0xFFF0000, 0x8FFF},
+      {0x10000000, 0x9000},
+      // Transition into the largest exponent.
+      {0x1FFE0000000, 0xF7FF},
+      {0x20000000000, 0xF800},
+      {0x20040000000, 0xF801},
+      // Transition into the max value.
+      {0x3FF80000000, 0xFFFE},
+      {0x3FFC0000000, 0xFFFF},
+  };
+  int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+
+  for (int i = 0; i < num_test_cases; ++i) {
+    uint16_t encoded_ufloat = test_cases[i].encoded;
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
+    }
+    QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
+                          GetParam().endianness);
+    uint64_t value;
+    EXPECT_TRUE(reader.ReadUFloat16(&value));
+    EXPECT_EQ(test_cases[i].decoded, value);
+  }
+}
+
+TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
+  // Just test all 16-bit encoded values. 0 and max already tested above.
+  uint64_t previous_value = 0;
+  for (uint16_t i = 1; i < 0xFFFF; ++i) {
+    // Read the two bytes.
+    uint16_t read_number = i;
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      read_number = quiche::QuicheEndian::HostToNet16(read_number);
+    }
+    QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
+                          GetParam().endianness);
+    uint64_t value;
+    // All values must be decodable.
+    EXPECT_TRUE(reader.ReadUFloat16(&value));
+    // Check that small numbers represent themselves
+    if (i < 4097) {
+      EXPECT_EQ(i, value);
+    }
+    // Check there's monotonic growth.
+    EXPECT_LT(previous_value, value);
+    // Check that precision is within 0.5% away from the denormals.
+    if (i > 2000) {
+      EXPECT_GT(previous_value * 1005, value * 1000);
+    }
+    // Check we're always within the promised range.
+    EXPECT_LT(value, UINT64_C(0x3FFC0000000));
+    previous_value = value;
+    char buffer[6];
+    QuicDataWriter writer(6, buffer, GetParam().endianness);
+    EXPECT_TRUE(writer.WriteUFloat16(value - 1));
+    EXPECT_TRUE(writer.WriteUFloat16(value));
+    EXPECT_TRUE(writer.WriteUFloat16(value + 1));
+    // Check minimal decoding (previous decoding has previous encoding).
+    uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
+    uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
+    uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
+    if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
+      encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
+      encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
+      encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
+    }
+    EXPECT_EQ(i - 1, encoded1);
+    // Check roundtrip.
+    EXPECT_EQ(i, encoded2);
+    // Check next decoding.
+    EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
+  }
+}
+
+TEST_P(QuicDataWriterTest, WriteConnectionId) {
+  QuicConnectionId connection_id =
+      TestConnectionId(UINT64_C(0x0011223344556677));
+  char big_endian[] = {
+      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  };
+  EXPECT_EQ(connection_id.length(), ABSL_ARRAYSIZE(big_endian));
+  ASSERT_LE(connection_id.length(), 255);
+  char buffer[255];
+  QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteConnectionId(connection_id));
+  quiche::test::CompareCharArraysWithHexError(
+      "connection_id", buffer, connection_id.length(), big_endian,
+      connection_id.length());
+
+  QuicConnectionId read_connection_id;
+  QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
+  EXPECT_TRUE(
+      reader.ReadConnectionId(&read_connection_id, ABSL_ARRAYSIZE(big_endian)));
+  EXPECT_EQ(connection_id, read_connection_id);
+}
+
+TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
+  QuicConnectionId connection_id =
+      TestConnectionId(UINT64_C(0x0011223344556677));
+  char length_prefixed_connection_id[] = {
+      0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+  };
+  EXPECT_EQ(ABSL_ARRAYSIZE(length_prefixed_connection_id),
+            kConnectionIdLengthSize + connection_id.length());
+  char buffer[kConnectionIdLengthSize + 255] = {};
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer);
+  EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
+  quiche::test::CompareCharArraysWithHexError(
+      "WriteLengthPrefixedConnectionId", buffer, writer.length(),
+      length_prefixed_connection_id,
+      ABSL_ARRAYSIZE(length_prefixed_connection_id));
+
+  // Verify that writing length then connection ID produces the same output.
+  memset(buffer, 0, ABSL_ARRAYSIZE(buffer));
+  QuicDataWriter writer2(ABSL_ARRAYSIZE(buffer), buffer);
+  EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
+  EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
+  quiche::test::CompareCharArraysWithHexError(
+      "Write length then ConnectionId", buffer, writer2.length(),
+      length_prefixed_connection_id,
+      ABSL_ARRAYSIZE(length_prefixed_connection_id));
+
+  QuicConnectionId read_connection_id;
+  QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer));
+  EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
+  EXPECT_EQ(connection_id, read_connection_id);
+
+  // Verify that reading length then connection ID produces the same output.
+  uint8_t read_connection_id_length2 = 33;
+  QuicConnectionId read_connection_id2;
+  QuicDataReader reader2(buffer, ABSL_ARRAYSIZE(buffer));
+  ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
+  EXPECT_EQ(connection_id.length(), read_connection_id_length2);
+  EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
+                                       read_connection_id_length2));
+  EXPECT_EQ(connection_id, read_connection_id2);
+}
+
+TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
+  QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
+  char buffer[2];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_TRUE(writer.WriteUInt8(1));
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_TRUE(writer.WriteUInt8(2));
+  EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
+  EXPECT_FALSE(writer.WriteUInt8(3));
+
+  EXPECT_EQ(buffer[0], 1);
+  EXPECT_EQ(buffer[1], 2);
+
+  QuicConnectionId read_connection_id = TestConnectionId();
+  uint8_t read_byte;
+  QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer), GetParam().endianness);
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
+  EXPECT_EQ(read_byte, 1);
+  // Reset read_connection_id to something else to verify that
+  // ReadConnectionId properly sets it back to empty.
+  read_connection_id = TestConnectionId();
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_TRUE(reader.ReadUInt8(&read_byte));
+  EXPECT_EQ(read_byte, 2);
+  read_connection_id = TestConnectionId();
+  EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
+  EXPECT_EQ(read_connection_id, empty_connection_id);
+  EXPECT_FALSE(reader.ReadUInt8(&read_byte));
+}
+
+TEST_P(QuicDataWriterTest, WriteTag) {
+  char CHLO[] = {
+      'C',
+      'H',
+      'L',
+      'O',
+  };
+  const int kBufferLength = sizeof(QuicTag);
+  char buffer[kBufferLength];
+  QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
+  writer.WriteTag(kCHLO);
+  quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
+                                              CHLO, kBufferLength);
+
+  QuicTag read_chlo;
+  QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
+  reader.ReadTag(&read_chlo);
+  EXPECT_EQ(kCHLO, read_chlo);
+}
+
+TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
+  char little_endian16[] = {0x22, 0x11};
+  char big_endian16[] = {0x11, 0x22};
+  char buffer16[2];
+  {
+    uint16_t in_memory16 = 0x1122;
+    QuicDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteUInt16(in_memory16);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
+                                                            : little_endian16,
+        2);
+
+    uint16_t read_number16;
+    QuicDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadUInt16(&read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+
+  {
+    uint64_t in_memory16 = 0x0000000000001122;
+    QuicDataWriter writer(2, buffer16, GetParam().endianness);
+    writer.WriteBytesToUInt64(2, in_memory16);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint16_t", buffer16, 2,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
+                                                            : little_endian16,
+        2);
+
+    uint64_t read_number16;
+    QuicDataReader reader(buffer16, 2, GetParam().endianness);
+    reader.ReadBytesToUInt64(2, &read_number16);
+    EXPECT_EQ(in_memory16, read_number16);
+  }
+}
+
+TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
+  char little_endian24[] = {0x33, 0x22, 0x11};
+  char big_endian24[] = {0x11, 0x22, 0x33};
+  char buffer24[3];
+  uint64_t in_memory24 = 0x0000000000112233;
+  QuicDataWriter writer(3, buffer24, GetParam().endianness);
+  writer.WriteBytesToUInt64(3, in_memory24);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint24", buffer24, 3,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
+                                                          : little_endian24,
+      3);
+
+  uint64_t read_number24;
+  QuicDataReader reader(buffer24, 3, GetParam().endianness);
+  reader.ReadBytesToUInt64(3, &read_number24);
+  EXPECT_EQ(in_memory24, read_number24);
+}
+
+TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
+  char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
+  char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
+  char buffer32[4];
+  {
+    uint32_t in_memory32 = 0x11223344;
+    QuicDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteUInt32(in_memory32);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
+                                                            : little_endian32,
+        4);
+
+    uint32_t read_number32;
+    QuicDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadUInt32(&read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+
+  {
+    uint64_t in_memory32 = 0x11223344;
+    QuicDataWriter writer(4, buffer32, GetParam().endianness);
+    writer.WriteBytesToUInt64(4, in_memory32);
+    quiche::test::CompareCharArraysWithHexError(
+        "uint32_t", buffer32, 4,
+        GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
+                                                            : little_endian32,
+        4);
+
+    uint64_t read_number32;
+    QuicDataReader reader(buffer32, 4, GetParam().endianness);
+    reader.ReadBytesToUInt64(4, &read_number32);
+    EXPECT_EQ(in_memory32, read_number32);
+  }
+}
+
+TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
+  uint64_t in_memory40 = 0x0000001122334455;
+  char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
+  char buffer40[5];
+  QuicDataWriter writer(5, buffer40, GetParam().endianness);
+  writer.WriteBytesToUInt64(5, in_memory40);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint40", buffer40, 5,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
+                                                          : little_endian40,
+      5);
+
+  uint64_t read_number40;
+  QuicDataReader reader(buffer40, 5, GetParam().endianness);
+  reader.ReadBytesToUInt64(5, &read_number40);
+  EXPECT_EQ(in_memory40, read_number40);
+}
+
+TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
+  uint64_t in_memory48 = 0x0000112233445566;
+  char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+  char buffer48[6];
+  QuicDataWriter writer(6, buffer48, GetParam().endianness);
+  writer.WriteBytesToUInt64(6, in_memory48);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint48", buffer48, 6,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
+                                                          : little_endian48,
+      6);
+
+  uint64_t read_number48;
+  QuicDataReader reader(buffer48, 6, GetParam().endianness);
+  reader.ReadBytesToUInt64(6., &read_number48);
+  EXPECT_EQ(in_memory48, read_number48);
+}
+
+TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
+  uint64_t in_memory56 = 0x0011223344556677;
+  char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+  char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
+  char buffer56[7];
+  QuicDataWriter writer(7, buffer56, GetParam().endianness);
+  writer.WriteBytesToUInt64(7, in_memory56);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint56", buffer56, 7,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
+                                                          : little_endian56,
+      7);
+
+  uint64_t read_number56;
+  QuicDataReader reader(buffer56, 7, GetParam().endianness);
+  reader.ReadBytesToUInt64(7, &read_number56);
+  EXPECT_EQ(in_memory56, read_number56);
+}
+
+TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
+  uint64_t in_memory64 = 0x1122334455667788;
+  unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
+                                     0x44, 0x33, 0x22, 0x11};
+  unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
+                                  0x55, 0x66, 0x77, 0x88};
+  char buffer64[8];
+  QuicDataWriter writer(8, buffer64, GetParam().endianness);
+  writer.WriteBytesToUInt64(8, in_memory64);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
+          ? AsChars(big_endian64)
+          : AsChars(little_endian64),
+      8);
+
+  uint64_t read_number64;
+  QuicDataReader reader(buffer64, 8, GetParam().endianness);
+  reader.ReadBytesToUInt64(8, &read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+
+  QuicDataWriter writer2(8, buffer64, GetParam().endianness);
+  writer2.WriteUInt64(in_memory64);
+  quiche::test::CompareCharArraysWithHexError(
+      "uint64_t", buffer64, 8,
+      GetParam().endianness == quiche::NETWORK_BYTE_ORDER
+          ? AsChars(big_endian64)
+          : AsChars(little_endian64),
+      8);
+  read_number64 = 0u;
+  QuicDataReader reader2(buffer64, 8, GetParam().endianness);
+  reader2.ReadUInt64(&read_number64);
+  EXPECT_EQ(in_memory64, read_number64);
+}
+
+TEST_P(QuicDataWriterTest, WriteIntegers) {
+  char buf[43];
+  uint8_t i8 = 0x01;
+  uint16_t i16 = 0x0123;
+  uint32_t i32 = 0x01234567;
+  uint64_t i64 = 0x0123456789ABCDEF;
+  QuicDataWriter writer(46, buf, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 1u:
+        EXPECT_TRUE(writer.WriteUInt8(i8));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 2u:
+        EXPECT_TRUE(writer.WriteUInt16(i16));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 3u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 4u:
+        EXPECT_TRUE(writer.WriteUInt32(i32));
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      case 5u:
+      case 6u:
+      case 7u:
+      case 8u:
+        EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
+        break;
+      default:
+        EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
+    }
+  }
+
+  QuicDataReader reader(buf, 46, GetParam().endianness);
+  for (size_t i = 0; i < 10; ++i) {
+    uint8_t read8;
+    uint16_t read16;
+    uint32_t read32;
+    uint64_t read64;
+    switch (i) {
+      case 0u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0u, read64);
+        break;
+      case 1u:
+        EXPECT_TRUE(reader.ReadUInt8(&read8));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i8, read8);
+        EXPECT_EQ(0xEFu, read64);
+        break;
+      case 2u:
+        EXPECT_TRUE(reader.ReadUInt16(&read16));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i16, read16);
+        EXPECT_EQ(0xCDEFu, read64);
+        break;
+      case 3u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0xABCDEFu, read64);
+        break;
+      case 4u:
+        EXPECT_TRUE(reader.ReadUInt32(&read32));
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(i32, read32);
+        EXPECT_EQ(0x89ABCDEFu, read64);
+        break;
+      case 5u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x6789ABCDEFu, read64);
+        break;
+      case 6u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x456789ABCDEFu, read64);
+        break;
+      case 7u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x23456789ABCDEFu, read64);
+        break;
+      case 8u:
+        EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
+        EXPECT_EQ(0x0123456789ABCDEFu, read64);
+        break;
+      default:
+        EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
+    }
+  }
+}
+
+TEST_P(QuicDataWriterTest, WriteBytes) {
+  char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+  char buf[ABSL_ARRAYSIZE(bytes)];
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
+  for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
+    EXPECT_EQ(bytes[i], buf[i]);
+  }
+}
+
+const int kVarIntBufferLength = 1024;
+
+// Encodes and then decodes a specified value, checks that the
+// value that was encoded is the same as the decoded value, the length
+// is correct, and that after decoding, all data in the buffer has
+// been consumed..
+// Returns true if everything works, false if not.
+bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
+  // Init the buffer to all 0, just for cleanliness. Makes for better
+  // output if, in debugging, we need to dump out the buffer.
+  memset(buffer, 0, size_of_buffer);
+  // make a writer. Note that for IETF encoding
+  // we do not care about endianness... It's always big-endian,
+  // but the c'tor expects to be told what endianness is in force...
+  QuicDataWriter writer(size_of_buffer, buffer,
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  // Try to write the value.
+  if (writer.WriteVarInt62(value_in) != true) {
+    return false;
+  }
+  // Look at the value we encoded. Determine how much should have been
+  // used based on the value, and then check the state of the writer
+  // to see that it matches.
+  size_t expected_length = 0;
+  if (value_in <= 0x3f) {
+    expected_length = 1;
+  } else if (value_in <= 0x3fff) {
+    expected_length = 2;
+  } else if (value_in <= 0x3fffffff) {
+    expected_length = 4;
+  } else {
+    expected_length = 8;
+  }
+  if (writer.length() != expected_length) {
+    return false;
+  }
+
+  // set up a reader, just the length we've used, no more, no less.
+  QuicDataReader reader(buffer, expected_length,
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  uint64_t value_out;
+
+  if (reader.ReadVarInt62(&value_out) == false) {
+    return false;
+  }
+  if (value_in != value_out) {
+    return false;
+  }
+  // We only write one value so there had better be nothing left to read
+  return reader.IsDoneReading();
+}
+
+// Test that 8-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt8Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x31 + 0xc0));  // 0xc0 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
+}
+
+// Test that 4-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt4Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x32 + 0x80));  // 0x80 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
+}
+
+// Test that 2-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt2Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3647));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x36 + 0x40));  // 0x40 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
+}
+
+// Test that 1-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicDataWriterTest, VarInt1Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer
+  // is correct. Bytes are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3f));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
+}
+
+// Test certain, targeted, values that are expected to succeed:
+// 0, 1,
+// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
+// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
+// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
+//                          transition)
+// 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
+// 0xfe, 0xff, 0x100, 0x101,
+// 0xfffe, 0xffff, 0x10000, 0x10001,
+// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
+// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
+// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
+// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
+// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
+TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t passing_values[] = {
+      0,
+      1,
+      0x3e,
+      0x3f,
+      0x40,
+      0x41,
+      0x3ffe,
+      0x3fff,
+      0x4000,
+      0x4001,
+      0x3ffffffe,
+      0x3fffffff,
+      0x40000000,
+      0x40000001,
+      0x3ffffffffffffffe,
+      0x3fffffffffffffff,
+      0xfe,
+      0xff,
+      0x100,
+      0x101,
+      0xfffe,
+      0xffff,
+      0x10000,
+      0x10001,
+      0xfffffe,
+      0xffffff,
+      0x1000000,
+      0x1000001,
+      0xfffffffe,
+      0xffffffff,
+      0x100000000,
+      0x100000001,
+      0xfffffffffe,
+      0xffffffffff,
+      0x10000000000,
+      0x10000000001,
+      0xfffffffffffe,
+      0xffffffffffff,
+      0x1000000000000,
+      0x1000000000001,
+      0xfffffffffffffe,
+      0xffffffffffffff,
+      0x100000000000000,
+      0x100000000000001,
+  };
+  for (uint64_t test_val : passing_values) {
+    EXPECT_TRUE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " failed";
+  }
+}
+//
+// Test certain, targeted, values where failure is expected (the
+// values are invalid w.r.t. IETF VarInt encoding):
+// 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
+// 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
+TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t failing_values[] = {
+      0x4000000000000000,
+      0x4000000000000001,
+      0xfffffffffffffffe,
+      0xffffffffffffffff,
+  };
+  for (uint64_t test_val : failing_values) {
+    EXPECT_FALSE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " succeeded, but was an "
+        << "invalid value";
+  }
+}
+
+// Following tests all try to fill the buffer with multiple values,
+// go one value more than the buffer can accommodate, then read
+// the successfully encoded values, and try to read the unsuccessfully
+// encoded value. The following is the number of values to encode.
+const int kMultiVarCount = 1000;
+
+// Test writing & reading multiple 8-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt8) {
+  uint64_t test_val;
+  char buffer[8 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 4-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt4) {
+  uint64_t test_val;
+  char buffer[4 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
+  }
+  EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 2-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt2) {
+  uint64_t test_val;
+  char buffer[2 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
+  }
+  EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 1-byte-encoded varints
+TEST_P(QuicDataWriterTest, MultiVarInt1) {
+  uint64_t test_val;
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over. &0xf ensures we do not
+  // overflow the max value for single-byte encoding.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
+  }
+  EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing varints with a forced length.
+TEST_P(QuicDataWriterTest, VarIntFixedLength) {
+  char buffer[90];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  uint64_t test_val = 0;
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1u);
+  }
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 63u);
+  }
+
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 64u);
+  }
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16383u);
+  }
+
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16384u);
+  }
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1073741823u);
+  }
+
+  EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+  EXPECT_EQ(test_val, 1073741824u);
+
+  // We are at the end of the buffer so this should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test encoding/decoding stream-id values.
+void EncodeDecodeStreamId(uint64_t value_in) {
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+
+  // Encode the given Stream ID.
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(value_in));
+
+  QuicDataReader reader(buffer, sizeof(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  QuicStreamId received_stream_id;
+  uint64_t temp;
+  EXPECT_TRUE(reader.ReadVarInt62(&temp));
+  received_stream_id = static_cast<QuicStreamId>(temp);
+  EXPECT_EQ(value_in, received_stream_id);
+}
+
+// Test writing & reading stream-ids of various value.
+TEST_P(QuicDataWriterTest, StreamId1) {
+  // Check a 1-byte QuicStreamId, should work
+  EncodeDecodeStreamId(UINT64_C(0x15));
+
+  // Check a 2-byte QuicStream ID. It should work.
+  EncodeDecodeStreamId(UINT64_C(0x1567));
+
+  // Check a QuicStreamId that requires 4 bytes of encoding
+  // This should work.
+  EncodeDecodeStreamId(UINT64_C(0x34567890));
+
+  // Check a QuicStreamId that requires 8 bytes of encoding
+  // but whose value is in the acceptable range.
+  // This should work.
+  EncodeDecodeStreamId(UINT64_C(0xf4567890));
+}
+
+TEST_P(QuicDataWriterTest, WriteRandomBytes) {
+  char buffer[20];
+  char expected[20];
+  for (size_t i = 0; i < 20; ++i) {
+    expected[i] = 'r';
+  }
+  MockRandom random;
+  QuicDataWriter writer(20, buffer, GetParam().endianness);
+  EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
+
+  EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
+  quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
+                                              20);
+}
+
+TEST_P(QuicDataWriterTest, WriteInsecureRandomBytes) {
+  char buffer[20];
+  char expected[20];
+  for (size_t i = 0; i < 20; ++i) {
+    expected[i] = 'r';
+  }
+  MockRandom random;
+  QuicDataWriter writer(20, buffer, GetParam().endianness);
+  EXPECT_FALSE(writer.WriteInsecureRandomBytes(&random, 30));
+
+  EXPECT_TRUE(writer.WriteInsecureRandomBytes(&random, 20));
+  quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
+                                              20);
+}
+
+TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
+  // In range [0, 63], variable length should be 1 byte.
+  char buffer[20];
+  QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(50));
+  QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(1, reader.PeekVarInt62Length());
+  // In range (63-16383], variable length should be 2 byte2.
+  char buffer2[20];
+  QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer2.WriteVarInt62(100));
+  QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(2, reader2.PeekVarInt62Length());
+  // In range (16383, 1073741823], variable length should be 4 bytes.
+  char buffer3[20];
+  QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer3.WriteVarInt62(20000));
+  QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(4, reader3.PeekVarInt62Length());
+  // In range (1073741823, 4611686018427387903], variable length should be 8
+  // bytes.
+  char buffer4[20];
+  QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
+  QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
+  EXPECT_EQ(8, reader4.PeekVarInt62Length());
+}
+
+TEST_P(QuicDataWriterTest, ValidStreamCount) {
+  char buffer[1024];
+  memset(buffer, 0, sizeof(buffer));
+  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                        quiche::Endianness::NETWORK_BYTE_ORDER);
+  QuicDataReader reader(buffer, sizeof(buffer));
+  const QuicStreamCount write_stream_count = 0xffeeddcc;
+  EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
+  QuicStreamCount read_stream_count;
+  uint64_t temp;
+  EXPECT_TRUE(reader.ReadVarInt62(&temp));
+  read_stream_count = static_cast<QuicStreamId>(temp);
+  EXPECT_EQ(write_stream_count, read_stream_count);
+}
+
+TEST_P(QuicDataWriterTest, Seek) {
+  char buffer[3] = {};
+  QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
+  EXPECT_TRUE(writer.WriteUInt8(42));
+  EXPECT_TRUE(writer.Seek(1));
+  EXPECT_TRUE(writer.WriteUInt8(3));
+
+  char expected[] = {42, 0, 3};
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
+    EXPECT_EQ(buffer[i], expected[i]);
+  }
+}
+
+TEST_P(QuicDataWriterTest, SeekTooFarFails) {
+  char buffer[20];
+
+  // Check that one can seek to the end of the writer, but not past.
+  {
+    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+    EXPECT_TRUE(writer.Seek(20));
+    EXPECT_FALSE(writer.Seek(1));
+  }
+
+  // Seeking several bytes past the end fails.
+  {
+    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+    EXPECT_FALSE(writer.Seek(100));
+  }
+
+  // Seeking so far that arithmetic overflow could occur also fails.
+  {
+    QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
+                          GetParam().endianness);
+    EXPECT_TRUE(writer.Seek(10));
+    EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
+  }
+}
+
+TEST_P(QuicDataWriterTest, PayloadReads) {
+  char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  char expected_first_read[4] = {1, 2, 3, 4};
+  char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+  QuicDataReader reader(buffer, sizeof(buffer));
+  char first_read_buffer[4] = {};
+  EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
+  quiche::test::CompareCharArraysWithHexError(
+      "first read", first_read_buffer, sizeof(first_read_buffer),
+      expected_first_read, sizeof(expected_first_read));
+  absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "peeked_remaining_payload", peeked_remaining_payload.data(),
+      peeked_remaining_payload.length(), expected_remaining,
+      sizeof(expected_remaining));
+  absl::string_view full_payload = reader.FullPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "full_payload", full_payload.data(), full_payload.length(), buffer,
+      sizeof(buffer));
+  absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "read_remaining_payload", read_remaining_payload.data(),
+      read_remaining_payload.length(), expected_remaining,
+      sizeof(expected_remaining));
+  EXPECT_TRUE(reader.IsDoneReading());
+  absl::string_view full_payload2 = reader.FullPayload();
+  quiche::test::CompareCharArraysWithHexError(
+      "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
+      sizeof(buffer));
+}
+
+TEST_P(QuicDataWriterTest, StringPieceVarInt62) {
+  char inner_buffer[16] = {1, 2,  3,  4,  5,  6,  7,  8,
+                           9, 10, 11, 12, 13, 14, 15, 16};
+  absl::string_view inner_payload_write(inner_buffer, sizeof(inner_buffer));
+  char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {};
+  QuicDataWriter writer(sizeof(buffer), buffer);
+  EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write));
+  EXPECT_EQ(0u, writer.remaining());
+  QuicDataReader reader(buffer, sizeof(buffer));
+  absl::string_view inner_payload_read;
+  EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read));
+  quiche::test::CompareCharArraysWithHexError(
+      "inner_payload", inner_payload_write.data(), inner_payload_write.length(),
+      inner_payload_read.data(), inner_payload_read.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_datagram_queue.cc b/quiche/quic/core/quic_datagram_queue.cc
new file mode 100644
index 0000000..412eeab
--- /dev/null
+++ b/quiche/quic/core/quic_datagram_queue.cc
@@ -0,0 +1,101 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_datagram_queue.h"
+
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+
+constexpr float kExpiryInMinRtts = 1.25;
+constexpr float kMinPacingWindows = 4;
+
+QuicDatagramQueue::QuicDatagramQueue(QuicSession* session)
+    : QuicDatagramQueue(session, nullptr) {}
+
+QuicDatagramQueue::QuicDatagramQueue(QuicSession* session,
+                                     std::unique_ptr<Observer> observer)
+    : session_(session),
+      clock_(session->connection()->clock()),
+      observer_(std::move(observer)) {}
+
+MessageStatus QuicDatagramQueue::SendOrQueueDatagram(
+    quiche::QuicheMemSlice datagram) {
+  // If the queue is non-empty, always queue the daragram.  This ensures that
+  // the datagrams are sent in the same order that they were sent by the
+  // application.
+  if (queue_.empty()) {
+    MessageResult result = session_->SendMessage(absl::MakeSpan(&datagram, 1));
+    if (result.status != MESSAGE_STATUS_BLOCKED) {
+      if (observer_) {
+        observer_->OnDatagramProcessed(result.status);
+      }
+      return result.status;
+    }
+  }
+
+  queue_.emplace_back(Datagram{std::move(datagram),
+                               clock_->ApproximateNow() + GetMaxTimeInQueue()});
+  return MESSAGE_STATUS_BLOCKED;
+}
+
+absl::optional<MessageStatus> QuicDatagramQueue::TrySendingNextDatagram() {
+  RemoveExpiredDatagrams();
+  if (queue_.empty()) {
+    return absl::nullopt;
+  }
+
+  MessageResult result =
+      session_->SendMessage(absl::MakeSpan(&queue_.front().datagram, 1));
+  if (result.status != MESSAGE_STATUS_BLOCKED) {
+    queue_.pop_front();
+    if (observer_) {
+      observer_->OnDatagramProcessed(result.status);
+    }
+  }
+  return result.status;
+}
+
+size_t QuicDatagramQueue::SendDatagrams() {
+  size_t num_datagrams = 0;
+  for (;;) {
+    absl::optional<MessageStatus> status = TrySendingNextDatagram();
+    if (!status.has_value()) {
+      break;
+    }
+    if (*status == MESSAGE_STATUS_BLOCKED) {
+      break;
+    }
+    num_datagrams++;
+  }
+  return num_datagrams;
+}
+
+QuicTime::Delta QuicDatagramQueue::GetMaxTimeInQueue() const {
+  if (!max_time_in_queue_.IsZero()) {
+    return max_time_in_queue_;
+  }
+
+  const QuicTime::Delta min_rtt =
+      session_->connection()->sent_packet_manager().GetRttStats()->min_rtt();
+  return std::max(kExpiryInMinRtts * min_rtt,
+                  kMinPacingWindows * kAlarmGranularity);
+}
+
+void QuicDatagramQueue::RemoveExpiredDatagrams() {
+  QuicTime now = clock_->ApproximateNow();
+  while (!queue_.empty() && queue_.front().expiry <= now) {
+    queue_.pop_front();
+    if (observer_) {
+      observer_->OnDatagramProcessed(absl::nullopt);
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_datagram_queue.h b/quiche/quic/core/quic_datagram_queue.h
new file mode 100644
index 0000000..7120c51
--- /dev/null
+++ b/quiche/quic/core/quic_datagram_queue.h
@@ -0,0 +1,89 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
+#define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
+
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+class QuicSession;
+
+// Provides a way to buffer QUIC datagrams (messages) in case they cannot
+// be sent due to congestion control.  Datagrams are buffered for a limited
+// amount of time, and deleted after that time passes.
+class QUIC_EXPORT_PRIVATE QuicDatagramQueue {
+ public:
+  // An interface used to monitor events on the associated `QuicDatagramQueue`.
+  class QUIC_EXPORT_PRIVATE Observer {
+   public:
+    virtual ~Observer() = default;
+
+    // Called when a datagram in the associated queue is sent or discarded.
+    // Identity information for the datagram is not given, because the sending
+    // and discarding order is always first-in-first-out.
+    // This function is called synchronously in `QuicDatagramQueue` methods.
+    // `status` is nullopt when the datagram is dropped due to being in the
+    // queue for too long.
+    virtual void OnDatagramProcessed(absl::optional<MessageStatus> status) = 0;
+  };
+
+  // |session| is not owned and must outlive this object.
+  explicit QuicDatagramQueue(QuicSession* session);
+
+  // |session| is not owned and must outlive this object.
+  QuicDatagramQueue(QuicSession* session, std::unique_ptr<Observer> observer);
+
+  // Adds the datagram to the end of the queue.  May send it immediately; if
+  // not, MESSAGE_STATUS_BLOCKED is returned.
+  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram);
+
+  // Attempts to send a single datagram from the queue.  Returns the result of
+  // SendMessage(), or nullopt if there were no unexpired datagrams to send.
+  absl::optional<MessageStatus> TrySendingNextDatagram();
+
+  // Sends all of the unexpired datagrams until either the connection becomes
+  // write-blocked or the queue is empty.  Returns the number of datagrams sent.
+  size_t SendDatagrams();
+
+  // Returns the amount of time a datagram is allowed to be in the queue before
+  // it is dropped.  If not set explicitly using SetMaxTimeInQueue(), an
+  // RTT-based heuristic is used.
+  QuicTime::Delta GetMaxTimeInQueue() const;
+
+  void SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue) {
+    max_time_in_queue_ = max_time_in_queue;
+  }
+
+  size_t queue_size() { return queue_.size(); }
+
+  bool empty() { return queue_.empty(); }
+
+ private:
+  struct QUIC_EXPORT_PRIVATE Datagram {
+    quiche::QuicheMemSlice datagram;
+    QuicTime expiry;
+  };
+
+  // Removes expired datagrams from the front of the queue.
+  void RemoveExpiredDatagrams();
+
+  QuicSession* session_;  // Not owned.
+  const QuicClock* clock_;
+
+  QuicTime::Delta max_time_in_queue_ = QuicTime::Delta::Zero();
+  quiche::QuicheCircularDeque<Datagram> queue_;
+  std::unique_ptr<Observer> observer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
diff --git a/quiche/quic/core/quic_datagram_queue_test.cc b/quiche/quic/core/quic_datagram_queue_test.cc
new file mode 100644
index 0000000..9cb2c3c
--- /dev/null
+++ b/quiche/quic/core/quic_datagram_queue_test.cc
@@ -0,0 +1,299 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_datagram_queue.h"
+
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+
+using testing::_;
+using testing::ElementsAre;
+using testing::Return;
+
+class EstablishedCryptoStream : public MockQuicCryptoStream {
+ public:
+  using MockQuicCryptoStream::MockQuicCryptoStream;
+
+  bool encryption_established() const override { return true; }
+};
+
+class QuicDatagramQueueObserver final : public QuicDatagramQueue::Observer {
+ public:
+  class Context : public quiche::QuicheReferenceCounted {
+   public:
+    std::vector<absl::optional<MessageStatus>> statuses;
+  };
+
+  QuicDatagramQueueObserver() : context_(new Context()) {}
+  QuicDatagramQueueObserver(const QuicDatagramQueueObserver&) = delete;
+  QuicDatagramQueueObserver& operator=(const QuicDatagramQueueObserver&) =
+      delete;
+
+  void OnDatagramProcessed(absl::optional<MessageStatus> status) override {
+    context_->statuses.push_back(std::move(status));
+  }
+
+  const quiche::QuicheReferenceCountedPointer<Context>& context() {
+    return context_;
+  }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<Context> context_;
+};
+
+class QuicDatagramQueueTestBase : public QuicTest {
+ protected:
+  QuicDatagramQueueTestBase()
+      : connection_(new MockQuicConnection(&helper_,
+                                           &alarm_factory_,
+                                           Perspective::IS_CLIENT)),
+        session_(connection_) {
+    session_.SetCryptoStream(new EstablishedCryptoStream(&session_));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+  }
+
+  ~QuicDatagramQueueTestBase() = default;
+
+  quiche::QuicheMemSlice CreateMemSlice(absl::string_view data) {
+    return quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
+        helper_.GetStreamSendBufferAllocator(), data));
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;  // Owned by |session_|.
+  MockQuicSession session_;
+};
+
+class QuicDatagramQueueTest : public QuicDatagramQueueTestBase {
+ public:
+  QuicDatagramQueueTest() : queue_(&session_) {}
+
+ protected:
+  QuicDatagramQueue queue_;
+};
+
+TEST_F(QuicDatagramQueueTest, SendDatagramImmediately) {
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  MessageStatus status = queue_.SendOrQueueDatagram(CreateMemSlice("test"));
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, status);
+  EXPECT_EQ(0u, queue_.queue_size());
+}
+
+TEST_F(QuicDatagramQueueTest, SendDatagramAfterBuffering) {
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  MessageStatus initial_status =
+      queue_.SendOrQueueDatagram(CreateMemSlice("test"));
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED, initial_status);
+  EXPECT_EQ(1u, queue_.queue_size());
+
+  // Verify getting write blocked does not remove the datagram from the queue.
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
+  ASSERT_TRUE(status.has_value());
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED, *status);
+  EXPECT_EQ(1u, queue_.queue_size());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  status = queue_.TrySendingNextDatagram();
+  ASSERT_TRUE(status.has_value());
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS, *status);
+  EXPECT_EQ(0u, queue_.queue_size());
+}
+
+TEST_F(QuicDatagramQueueTest, EmptyBuffer) {
+  absl::optional<MessageStatus> status = queue_.TrySendingNextDatagram();
+  EXPECT_FALSE(status.has_value());
+
+  size_t num_messages = queue_.SendDatagrams();
+  EXPECT_EQ(0u, num_messages);
+}
+
+TEST_F(QuicDatagramQueueTest, MultipleDatagrams) {
+  // Note that SendMessage() is called only once here, since all the remaining
+  // messages are automatically queued due to the queue being non-empty.
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("d"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("e"));
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .Times(5)
+      .WillRepeatedly(Return(MESSAGE_STATUS_SUCCESS));
+  size_t num_messages = queue_.SendDatagrams();
+  EXPECT_EQ(5u, num_messages);
+}
+
+TEST_F(QuicDatagramQueueTest, DefaultMaxTimeInQueue) {
+  EXPECT_EQ(QuicTime::Delta::Zero(),
+            connection_->sent_packet_manager().GetRttStats()->min_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(4), queue_.GetMaxTimeInQueue());
+
+  RttStats* stats =
+      const_cast<RttStats*>(connection_->sent_packet_manager().GetRttStats());
+  stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                   QuicTime::Delta::Zero(), helper_.GetClock()->Now());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(125), queue_.GetMaxTimeInQueue());
+}
+
+TEST_F(QuicDatagramQueueTest, Expiry) {
+  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
+  queue_.SetMaxTimeInQueue(expiry);
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
+  helper_.AdvanceTime(0.6 * expiry);
+  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
+  helper_.AdvanceTime(0.6 * expiry);
+  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
+
+  std::vector<std::string> messages;
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillRepeatedly([&messages](QuicMessageId /*id*/,
+                                  absl::Span<quiche::QuicheMemSlice> message,
+                                  bool /*flush*/) {
+        messages.push_back(std::string(message[0].AsStringView()));
+        return MESSAGE_STATUS_SUCCESS;
+      });
+  EXPECT_EQ(2u, queue_.SendDatagrams());
+  EXPECT_THAT(messages, ElementsAre("b", "c"));
+}
+
+TEST_F(QuicDatagramQueueTest, ExpireAll) {
+  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
+  queue_.SetMaxTimeInQueue(expiry);
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+  queue_.SendOrQueueDatagram(CreateMemSlice("a"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("b"));
+  queue_.SendOrQueueDatagram(CreateMemSlice("c"));
+
+  helper_.AdvanceTime(100 * expiry);
+  EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
+  EXPECT_EQ(0u, queue_.SendDatagrams());
+}
+
+class QuicDatagramQueueWithObserverTest : public QuicDatagramQueueTestBase {
+ public:
+  QuicDatagramQueueWithObserverTest()
+      : observer_(std::make_unique<QuicDatagramQueueObserver>()),
+        context_(observer_->context()),
+        queue_(&session_, std::move(observer_)) {}
+
+ protected:
+  // This is moved out immediately.
+  std::unique_ptr<QuicDatagramQueueObserver> observer_;
+
+  quiche::QuicheReferenceCountedPointer<QuicDatagramQueueObserver::Context>
+      context_;
+  QuicDatagramQueue queue_;
+};
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessImmediately) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveFailureImmediately) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
+
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_TOO_LARGE));
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, BlockingShouldNotBeObserved) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillRepeatedly(Return(MESSAGE_STATUS_BLOCKED));
+
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+  EXPECT_EQ(0u, queue_.SendDatagrams());
+
+  EXPECT_TRUE(context_->statuses.empty());
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveSuccessAfterBuffering) {
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+
+  EXPECT_EQ(1u, queue_.SendDatagrams());
+  EXPECT_THAT(context_->statuses, ElementsAre(MESSAGE_STATUS_SUCCESS));
+}
+
+TEST_F(QuicDatagramQueueWithObserverTest, ObserveExpiry) {
+  constexpr QuicTime::Delta expiry = QuicTime::Delta::FromMilliseconds(100);
+  queue_.SetMaxTimeInQueue(expiry);
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _))
+      .WillOnce(Return(MESSAGE_STATUS_BLOCKED));
+
+  EXPECT_EQ(MESSAGE_STATUS_BLOCKED,
+            queue_.SendOrQueueDatagram(CreateMemSlice("a")));
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_CALL(*connection_, SendMessage(_, _, _)).Times(0);
+  helper_.AdvanceTime(100 * expiry);
+
+  EXPECT_TRUE(context_->statuses.empty());
+
+  EXPECT_EQ(0u, queue_.SendDatagrams());
+  EXPECT_THAT(context_->statuses, ElementsAre(absl::nullopt));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_default_packet_writer.cc b/quiche/quic/core/quic_default_packet_writer.cc
new file mode 100644
index 0000000..744591b
--- /dev/null
+++ b/quiche/quic/core/quic_default_packet_writer.cc
@@ -0,0 +1,75 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_default_packet_writer.h"
+
+#include "quiche/quic/core/quic_udp_socket.h"
+
+namespace quic {
+
+QuicDefaultPacketWriter::QuicDefaultPacketWriter(int fd)
+    : fd_(fd), write_blocked_(false) {}
+
+QuicDefaultPacketWriter::~QuicDefaultPacketWriter() = default;
+
+WriteResult QuicDefaultPacketWriter::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  QUICHE_DCHECK(!write_blocked_);
+  QUICHE_DCHECK(nullptr == options)
+      << "QuicDefaultPacketWriter does not accept any options.";
+  QuicUdpPacketInfo packet_info;
+  packet_info.SetPeerAddress(peer_address);
+  packet_info.SetSelfIp(self_address);
+  WriteResult result =
+      QuicUdpSocketApi().WritePacket(fd_, buffer, buf_len, packet_info);
+  if (IsWriteBlockedStatus(result.status)) {
+    write_blocked_ = true;
+  }
+  return result;
+}
+
+bool QuicDefaultPacketWriter::IsWriteBlocked() const {
+  return write_blocked_;
+}
+
+void QuicDefaultPacketWriter::SetWritable() {
+  write_blocked_ = false;
+}
+
+absl::optional<int> QuicDefaultPacketWriter::MessageTooBigErrorCode() const {
+  return EMSGSIZE;
+}
+
+QuicByteCount QuicDefaultPacketWriter::GetMaxPacketSize(
+    const QuicSocketAddress& /*peer_address*/) const {
+  return kMaxOutgoingPacketSize;
+}
+
+bool QuicDefaultPacketWriter::SupportsReleaseTime() const {
+  return false;
+}
+
+bool QuicDefaultPacketWriter::IsBatchMode() const {
+  return false;
+}
+
+QuicPacketBuffer QuicDefaultPacketWriter::GetNextWriteLocation(
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/) {
+  return {nullptr, nullptr};
+}
+
+WriteResult QuicDefaultPacketWriter::Flush() {
+  return WriteResult(WRITE_STATUS_OK, 0);
+}
+
+void QuicDefaultPacketWriter::set_write_blocked(bool is_blocked) {
+  write_blocked_ = is_blocked;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_default_packet_writer.h b/quiche/quic/core/quic_default_packet_writer.h
new file mode 100644
index 0000000..ad76cfa
--- /dev/null
+++ b/quiche/quic/core/quic_default_packet_writer.h
@@ -0,0 +1,57 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
+#define QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
+
+#include <cstddef>
+
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+struct WriteResult;
+
+// Default packet writer which wraps QuicSocketUtils WritePacket.
+class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
+ public:
+  explicit QuicDefaultPacketWriter(int fd);
+  QuicDefaultPacketWriter(const QuicDefaultPacketWriter&) = delete;
+  QuicDefaultPacketWriter& operator=(const QuicDefaultPacketWriter&) = delete;
+  ~QuicDefaultPacketWriter() override;
+
+  // QuicPacketWriter
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+  bool IsWriteBlocked() const override;
+  void SetWritable() override;
+  absl::optional<int> MessageTooBigErrorCode() const override;
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const override;
+  bool SupportsReleaseTime() const override;
+  bool IsBatchMode() const override;
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) override;
+  WriteResult Flush() override;
+
+  void set_fd(int fd) { fd_ = fd; }
+
+ protected:
+  void set_write_blocked(bool is_blocked);
+  int fd() { return fd_; }
+
+ private:
+  int fd_;
+  bool write_blocked_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DEFAULT_PACKET_WRITER_H_
diff --git a/quiche/quic/core/quic_dispatcher.cc b/quiche/quic/core/quic_dispatcher.cc
new file mode 100644
index 0000000..d5344a0
--- /dev/null
+++ b/quiche/quic/core/quic_dispatcher.cc
@@ -0,0 +1,1456 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_dispatcher.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/chlo_extractor.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_chlo_extractor.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
+using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
+using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+
+namespace {
+
+// Minimal INITIAL packet length sent by clients is 1200.
+const QuicPacketLength kMinClientInitialPacketLength = 1200;
+
+// An alarm that informs the QuicDispatcher to delete old sessions.
+class DeleteSessionsAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  DeleteSessionsAlarm(const DeleteSessionsAlarm&) = delete;
+  DeleteSessionsAlarm& operator=(const DeleteSessionsAlarm&) = delete;
+
+  void OnAlarm() override { dispatcher_->DeleteSessions(); }
+
+ private:
+  // Not owned.
+  QuicDispatcher* dispatcher_;
+};
+
+// An alarm that informs the QuicDispatcher to clear
+// recent_stateless_reset_addresses_.
+class ClearStatelessResetAddressesAlarm
+    : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit ClearStatelessResetAddressesAlarm(QuicDispatcher* dispatcher)
+      : dispatcher_(dispatcher) {}
+  ClearStatelessResetAddressesAlarm(const DeleteSessionsAlarm&) = delete;
+  ClearStatelessResetAddressesAlarm& operator=(const DeleteSessionsAlarm&) =
+      delete;
+
+  void OnAlarm() override { dispatcher_->ClearStatelessResetAddresses(); }
+
+ private:
+  // Not owned.
+  QuicDispatcher* dispatcher_;
+};
+
+// Collects packets serialized by a QuicPacketCreator in order
+// to be handed off to the time wait list manager.
+class PacketCollector : public QuicPacketCreator::DelegateInterface,
+                        public QuicStreamFrameDataProducer {
+ public:
+  explicit PacketCollector(quiche::QuicheBufferAllocator* allocator)
+      : send_buffer_(allocator) {}
+  ~PacketCollector() override = default;
+
+  // QuicPacketCreator::DelegateInterface methods:
+  void OnSerializedPacket(SerializedPacket serialized_packet) override {
+    // Make a copy of the serialized packet to send later.
+    packets_.emplace_back(
+        new QuicEncryptedPacket(CopyBuffer(serialized_packet),
+                                serialized_packet.encrypted_length, true));
+  }
+
+  QuicPacketBuffer GetPacketBuffer() override {
+    // Let QuicPacketCreator to serialize packets on stack buffer.
+    return {nullptr, nullptr};
+  }
+
+  void OnUnrecoverableError(QuicErrorCode /*error*/,
+                            const std::string& /*error_details*/) override {}
+
+  bool ShouldGeneratePacket(HasRetransmittableData /*retransmittable*/,
+                            IsHandshake /*handshake*/) override {
+    QUICHE_DCHECK(false);
+    return true;
+  }
+
+  const QuicFrames MaybeBundleAckOpportunistically() override {
+    QUICHE_DCHECK(false);
+    return {};
+  }
+
+  SerializedPacketFate GetSerializedPacketFate(
+      bool /*is_mtu_discovery*/,
+      EncryptionLevel /*encryption_level*/) override {
+    return SEND_TO_WRITER;
+  }
+
+  // QuicStreamFrameDataProducer
+  WriteStreamDataResult WriteStreamData(QuicStreamId /*id*/,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) override {
+    if (send_buffer_.WriteStreamData(offset, data_length, writer)) {
+      return WRITE_SUCCESS;
+    }
+    return WRITE_FAILED;
+  }
+  bool WriteCryptoData(EncryptionLevel /*level*/,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override {
+    return send_buffer_.WriteStreamData(offset, data_length, writer);
+  }
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
+    return &packets_;
+  }
+
+ private:
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
+  // This is only needed until the packets are encrypted. Once packets are
+  // encrypted, the stream data is no longer required.
+  QuicStreamSendBuffer send_buffer_;
+};
+
+// Helper for statelessly closing connections by generating the
+// correct termination packets and adding the connection to the time wait
+// list manager.
+class StatelessConnectionTerminator {
+ public:
+  StatelessConnectionTerminator(QuicConnectionId server_connection_id,
+                                const ParsedQuicVersion version,
+                                QuicConnectionHelperInterface* helper,
+                                QuicTimeWaitListManager* time_wait_list_manager)
+      : server_connection_id_(server_connection_id),
+        framer_(ParsedQuicVersionVector{version},
+                /*unused*/ QuicTime::Zero(),
+                Perspective::IS_SERVER,
+                /*unused*/ kQuicDefaultConnectionIdLength),
+        collector_(helper->GetStreamSendBufferAllocator()),
+        creator_(server_connection_id, &framer_, &collector_),
+        time_wait_list_manager_(time_wait_list_manager) {
+    framer_.set_data_producer(&collector_);
+    framer_.SetInitialObfuscators(server_connection_id);
+  }
+
+  ~StatelessConnectionTerminator() {
+    // Clear framer's producer.
+    framer_.set_data_producer(nullptr);
+  }
+
+  // Generates a packet containing a CONNECTION_CLOSE frame specifying
+  // |error_code| and |error_details| and add the connection to time wait.
+  void CloseConnection(QuicErrorCode error_code,
+                       const std::string& error_details,
+                       bool ietf_quic,
+                       std::vector<QuicConnectionId> active_connection_ids) {
+    SerializeConnectionClosePacket(error_code, error_details);
+
+    time_wait_list_manager_->AddConnectionIdToTimeWait(
+        QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+        TimeWaitConnectionInfo(ietf_quic, collector_.packets(),
+                               std::move(active_connection_ids),
+                               /*srtt=*/QuicTime::Delta::Zero()));
+  }
+
+ private:
+  void SerializeConnectionClosePacket(QuicErrorCode error_code,
+                                      const std::string& error_details) {
+    QuicConnectionCloseFrame* frame =
+        new QuicConnectionCloseFrame(framer_.transport_version(), error_code,
+                                     NO_IETF_QUIC_ERROR, error_details,
+                                     /*transport_close_frame_type=*/0);
+
+    if (!creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION)) {
+      QUIC_BUG(quic_bug_10287_1) << "Unable to add frame to an empty packet";
+      delete frame;
+      return;
+    }
+    creator_.FlushCurrentPacket();
+    QUICHE_DCHECK_EQ(1u, collector_.packets()->size());
+  }
+
+  QuicConnectionId server_connection_id_;
+  QuicFramer framer_;
+  // Set as the visitor of |creator_| to collect any generated packets.
+  PacketCollector collector_;
+  QuicPacketCreator creator_;
+  QuicTimeWaitListManager* time_wait_list_manager_;
+};
+
+// Class which extracts the ALPN and SNI from a QUIC_CRYPTO CHLO packet.
+class ChloAlpnSniExtractor : public ChloExtractor::Delegate {
+ public:
+  void OnChlo(QuicTransportVersion version,
+              QuicConnectionId /*server_connection_id*/,
+              const CryptoHandshakeMessage& chlo) override {
+    absl::string_view alpn_value;
+    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
+      alpn_ = std::string(alpn_value);
+    }
+    absl::string_view sni;
+    if (chlo.GetStringPiece(quic::kSNI, &sni)) {
+      sni_ = std::string(sni);
+    }
+    absl::string_view uaid_value;
+    if (chlo.GetStringPiece(quic::kUAID, &uaid_value)) {
+      uaid_ = std::string(uaid_value);
+    }
+    if (version == LegacyVersionForEncapsulation().transport_version) {
+      absl::string_view qlve_value;
+      if (chlo.GetStringPiece(kQLVE, &qlve_value)) {
+        legacy_version_encapsulation_inner_packet_ = std::string(qlve_value);
+      }
+    }
+  }
+
+  std::string&& ConsumeAlpn() { return std::move(alpn_); }
+
+  std::string&& ConsumeSni() { return std::move(sni_); }
+
+  std::string&& ConsumeUaid() { return std::move(uaid_); }
+
+  std::string&& ConsumeLegacyVersionEncapsulationInnerPacket() {
+    return std::move(legacy_version_encapsulation_inner_packet_);
+  }
+
+ private:
+  std::string alpn_;
+  std::string sni_;
+  std::string uaid_;
+  std::string legacy_version_encapsulation_inner_packet_;
+};
+
+bool MaybeHandleLegacyVersionEncapsulation(
+    QuicDispatcher* dispatcher,
+    std::string legacy_version_encapsulation_inner_packet,
+    const ReceivedPacketInfo& packet_info) {
+  if (legacy_version_encapsulation_inner_packet.empty()) {
+    // This CHLO did not contain the Legacy Version Encapsulation tag.
+    return false;
+  }
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type;
+  bool version_present;
+  bool has_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+  QuicConnectionId destination_connection_id, source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(),
+                          legacy_version_encapsulation_inner_packet.length()),
+      kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  if (error != QUIC_NO_ERROR) {
+    QUIC_DLOG(ERROR)
+        << "Failed to parse Legacy Version Encapsulation inner packet:"
+        << detailed_error;
+    return false;
+  }
+  if (destination_connection_id != packet_info.destination_connection_id) {
+    // We enforce that the inner and outer connection IDs match to make sure
+    // this never impacts routing of packets.
+    QUIC_DLOG(ERROR) << "Ignoring Legacy Version Encapsulation packet "
+                        "with mismatched connection ID "
+                     << destination_connection_id << " vs "
+                     << packet_info.destination_connection_id;
+    return false;
+  }
+  if (legacy_version_encapsulation_inner_packet.length() >=
+      packet_info.packet.length()) {
+    QUIC_BUG(quic_bug_10287_2)
+        << "Inner packet cannot be larger than outer "
+        << legacy_version_encapsulation_inner_packet.length() << " vs "
+        << packet_info.packet.length();
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "Extracted a Legacy Version Encapsulation "
+                << legacy_version_encapsulation_inner_packet.length()
+                << " byte packet of version " << parsed_version;
+
+  // Append zeroes to the end of the packet. This will ensure that
+  // we use the right number of bytes for calculating anti-amplification
+  // limits. Note that this only works for long headers of versions that carry
+  // long header lengths, since they'll ignore any trailing zeroes. We still
+  // do this for all packets to ensure version negotiation works.
+  legacy_version_encapsulation_inner_packet.append(
+      packet_info.packet.length() -
+          legacy_version_encapsulation_inner_packet.length(),
+      0x00);
+
+  // Process the inner packet as if it had been received by itself.
+  QuicReceivedPacket received_encapsulated_packet(
+      legacy_version_encapsulation_inner_packet.data(),
+      legacy_version_encapsulation_inner_packet.length(),
+      packet_info.packet.receipt_time());
+  dispatcher->ProcessPacket(packet_info.self_address, packet_info.peer_address,
+                            received_encapsulated_packet);
+  QUIC_CODE_COUNT(quic_legacy_version_encapsulation_decapsulated);
+  return true;
+}
+
+}  // namespace
+
+QuicDispatcher::QuicDispatcher(
+    const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
+    QuicVersionManager* version_manager,
+    std::unique_ptr<QuicConnectionHelperInterface> helper,
+    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+    std::unique_ptr<QuicAlarmFactory> alarm_factory,
+    uint8_t expected_server_connection_id_length)
+    : config_(config),
+      crypto_config_(crypto_config),
+      compressed_certs_cache_(
+          QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+      helper_(std::move(helper)),
+      session_helper_(std::move(session_helper)),
+      alarm_factory_(std::move(alarm_factory)),
+      delete_sessions_alarm_(
+          alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))),
+      buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()),
+      version_manager_(version_manager),
+      last_error_(QUIC_NO_ERROR),
+      new_sessions_allowed_per_event_loop_(0u),
+      accept_new_connections_(true),
+      allow_short_initial_server_connection_ids_(false),
+      expected_server_connection_id_length_(
+          expected_server_connection_id_length),
+      clear_stateless_reset_addresses_alarm_(alarm_factory_->CreateAlarm(
+          new ClearStatelessResetAddressesAlarm(this))),
+      should_update_expected_server_connection_id_length_(false) {
+  QUIC_BUG_IF(quic_bug_12724_1, GetSupportedVersions().empty())
+      << "Trying to create dispatcher without any supported versions";
+  QUIC_DLOG(INFO) << "Created QuicDispatcher with versions: "
+                  << ParsedQuicVersionVectorToString(GetSupportedVersions());
+}
+
+QuicDispatcher::~QuicDispatcher() {
+  if (delete_sessions_alarm_ != nullptr) {
+    delete_sessions_alarm_->PermanentCancel();
+  }
+  if (clear_stateless_reset_addresses_alarm_ != nullptr) {
+    clear_stateless_reset_addresses_alarm_->PermanentCancel();
+  }
+  reference_counted_session_map_.clear();
+  closed_session_list_.clear();
+  num_sessions_in_session_map_ = 0;
+}
+
+void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) {
+  QUICHE_DCHECK(writer_ == nullptr);
+  writer_.reset(writer);
+  time_wait_list_manager_.reset(CreateQuicTimeWaitListManager());
+}
+
+void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
+                                   const QuicSocketAddress& peer_address,
+                                   const QuicReceivedPacket& packet) {
+  QUIC_DVLOG(2) << "Dispatcher received encrypted " << packet.length()
+                << " bytes:" << std::endl
+                << quiche::QuicheTextUtils::HexDump(
+                       absl::string_view(packet.data(), packet.length()));
+  ReceivedPacketInfo packet_info(self_address, peer_address, packet);
+  std::string detailed_error;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      packet, expected_server_connection_id_length_, &packet_info.form,
+      &packet_info.long_packet_type, &packet_info.version_flag,
+      &packet_info.use_length_prefix, &packet_info.version_label,
+      &packet_info.version, &packet_info.destination_connection_id,
+      &packet_info.source_connection_id, &packet_info.retry_token,
+      &detailed_error);
+  if (error != QUIC_NO_ERROR) {
+    // Packet has framing error.
+    SetLastError(error);
+    QUIC_DLOG(ERROR) << detailed_error;
+    return;
+  }
+  if (packet_info.destination_connection_id.length() !=
+          expected_server_connection_id_length_ &&
+      !should_update_expected_server_connection_id_length_ &&
+      packet_info.version.IsKnown() &&
+      !packet_info.version.AllowsVariableLengthConnectionIds()) {
+    SetLastError(QUIC_INVALID_PACKET_HEADER);
+    QUIC_DLOG(ERROR) << "Invalid Connection Id Length";
+    return;
+  }
+
+  if (packet_info.version_flag && IsSupportedVersion(packet_info.version)) {
+    if (!QuicUtils::IsConnectionIdValidForVersion(
+            packet_info.destination_connection_id,
+            packet_info.version.transport_version)) {
+      SetLastError(QUIC_INVALID_PACKET_HEADER);
+      QUIC_DLOG(ERROR)
+          << "Invalid destination connection ID length for version";
+      return;
+    }
+    if (packet_info.version.SupportsClientConnectionIds() &&
+        !QuicUtils::IsConnectionIdValidForVersion(
+            packet_info.source_connection_id,
+            packet_info.version.transport_version)) {
+      SetLastError(QUIC_INVALID_PACKET_HEADER);
+      QUIC_DLOG(ERROR) << "Invalid source connection ID length for version";
+      return;
+    }
+  }
+
+  if (should_update_expected_server_connection_id_length_) {
+    expected_server_connection_id_length_ =
+        packet_info.destination_connection_id.length();
+  }
+
+  if (MaybeDispatchPacket(packet_info)) {
+    // Packet has been dropped or successfully dispatched, stop processing.
+    return;
+  }
+  ProcessHeader(&packet_info);
+}
+
+QuicConnectionId QuicDispatcher::MaybeReplaceServerConnectionId(
+    const QuicConnectionId& server_connection_id,
+    const ParsedQuicVersion& version) const {
+  const uint8_t server_connection_id_length = server_connection_id.length();
+  if (server_connection_id_length == expected_server_connection_id_length_) {
+    return server_connection_id;
+  }
+  QUICHE_DCHECK(version.AllowsVariableLengthConnectionIds());
+  QuicConnectionId new_connection_id;
+  if (server_connection_id_length < expected_server_connection_id_length_) {
+    new_connection_id = ReplaceShortServerConnectionId(
+        version, server_connection_id, expected_server_connection_id_length_);
+    // Verify that ReplaceShortServerConnectionId is deterministic.
+    QUICHE_DCHECK_EQ(
+        new_connection_id,
+        ReplaceShortServerConnectionId(version, server_connection_id,
+                                       expected_server_connection_id_length_));
+  } else {
+    new_connection_id = ReplaceLongServerConnectionId(
+        version, server_connection_id, expected_server_connection_id_length_);
+    // Verify that ReplaceLongServerConnectionId is deterministic.
+    QUICHE_DCHECK_EQ(
+        new_connection_id,
+        ReplaceLongServerConnectionId(version, server_connection_id,
+                                      expected_server_connection_id_length_));
+  }
+  QUICHE_DCHECK_EQ(expected_server_connection_id_length_,
+                   new_connection_id.length());
+
+  QUIC_DLOG(INFO) << "Replacing incoming connection ID " << server_connection_id
+                  << " with " << new_connection_id;
+  return new_connection_id;
+}
+
+QuicConnectionId QuicDispatcher::ReplaceShortServerConnectionId(
+    const ParsedQuicVersion& /*version*/,
+    const QuicConnectionId& server_connection_id,
+    uint8_t expected_server_connection_id_length) const {
+  QUICHE_DCHECK_LT(server_connection_id.length(),
+                   expected_server_connection_id_length);
+  return QuicUtils::CreateReplacementConnectionId(
+      server_connection_id, expected_server_connection_id_length);
+}
+
+QuicConnectionId QuicDispatcher::ReplaceLongServerConnectionId(
+    const ParsedQuicVersion& /*version*/,
+    const QuicConnectionId& server_connection_id,
+    uint8_t expected_server_connection_id_length) const {
+  QUICHE_DCHECK_GT(server_connection_id.length(),
+                   expected_server_connection_id_length);
+  return QuicUtils::CreateReplacementConnectionId(
+      server_connection_id, expected_server_connection_id_length);
+}
+
+namespace {
+constexpr bool IsSourceUdpPortBlocked(uint16_t port) {
+  // These UDP source ports have been observed in large scale denial of service
+  // attacks and are not expected to ever carry user traffic, they are therefore
+  // blocked as a safety measure. See draft-ietf-quic-applicability for details.
+  constexpr uint16_t blocked_ports[] = {
+      0,      // We cannot send to port 0 so drop that source port.
+      17,     // Quote of the Day, can loop with QUIC.
+      19,     // Chargen, can loop with QUIC.
+      53,     // DNS, vulnerable to reflection attacks.
+      111,    // Portmap.
+      123,    // NTP, vulnerable to reflection attacks.
+      137,    // NETBIOS Name Service,
+      128,    // NETBIOS Datagram Service
+      161,    // SNMP.
+      389,    // CLDAP.
+      500,    // IKE, can loop with QUIC.
+      1900,   // SSDP, vulnerable to reflection attacks.
+      5353,   // mDNS, vulnerable to reflection attacks.
+      11211,  // memcache, vulnerable to reflection attacks.
+              // This list MUST be sorted in increasing order.
+  };
+  constexpr size_t num_blocked_ports = ABSL_ARRAYSIZE(blocked_ports);
+  constexpr uint16_t highest_blocked_port =
+      blocked_ports[num_blocked_ports - 1];
+  if (QUICHE_PREDICT_TRUE(port > highest_blocked_port)) {
+    // Early-return to skip comparisons for the majority of traffic.
+    return false;
+  }
+  for (size_t i = 0; i < num_blocked_ports; i++) {
+    if (port == blocked_ports[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+}  // namespace
+
+bool QuicDispatcher::MaybeDispatchPacket(
+    const ReceivedPacketInfo& packet_info) {
+  if (IsSourceUdpPortBlocked(packet_info.peer_address.port())) {
+    // Silently drop the received packet.
+    QUIC_CODE_COUNT(quic_dropped_blocked_port);
+    return true;
+  }
+
+  QuicConnectionId server_connection_id = packet_info.destination_connection_id;
+
+  // The IETF spec requires the client to generate an initial server
+  // connection ID that is at least 64 bits long. After that initial
+  // connection ID, the dispatcher picks a new one of its expected length.
+  // Therefore we should never receive a connection ID that is smaller
+  // than 64 bits and smaller than what we expect. Unless the version is
+  // unknown, in which case we allow short connection IDs for version
+  // negotiation because that version could allow those.
+  if (packet_info.version_flag && packet_info.version.IsKnown() &&
+      server_connection_id.length() < kQuicMinimumInitialConnectionIdLength &&
+      server_connection_id.length() < expected_server_connection_id_length_ &&
+      !allow_short_initial_server_connection_ids_) {
+    QUICHE_DCHECK(packet_info.version_flag);
+    QUICHE_DCHECK(packet_info.version.AllowsVariableLengthConnectionIds());
+    QUIC_DLOG(INFO) << "Packet with short destination connection ID "
+                    << server_connection_id << " expected "
+                    << static_cast<int>(expected_server_connection_id_length_);
+    // Drop the packet silently.
+    QUIC_CODE_COUNT(quic_dropped_invalid_small_initial_connection_id);
+    return true;
+  }
+
+  if (packet_info.version_flag && packet_info.version.IsKnown() &&
+      !QuicUtils::IsConnectionIdLengthValidForVersion(
+          server_connection_id.length(),
+          packet_info.version.transport_version)) {
+    QUIC_DLOG(INFO) << "Packet with destination connection ID "
+                    << server_connection_id << " is invalid with version "
+                    << packet_info.version;
+    // Drop the packet silently.
+    QUIC_CODE_COUNT(quic_dropped_invalid_initial_connection_id);
+    return true;
+  }
+
+  // Packets with connection IDs for active connections are processed
+  // immediately.
+  auto it = reference_counted_session_map_.find(server_connection_id);
+  if (it != reference_counted_session_map_.end()) {
+    QUICHE_DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
+    if (packet_info.version_flag &&
+        packet_info.version != it->second->version() &&
+        packet_info.version == LegacyVersionForEncapsulation()) {
+      // This packet is using the Legacy Version Encapsulation version but the
+      // corresponding session isn't, attempt extraction of inner packet.
+      ChloAlpnSniExtractor alpn_extractor;
+      if (ChloExtractor::Extract(packet_info.packet, packet_info.version,
+                                 config_->create_session_tag_indicators(),
+                                 &alpn_extractor,
+                                 server_connection_id.length())) {
+        if (MaybeHandleLegacyVersionEncapsulation(
+                this,
+                alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket(),
+                packet_info)) {
+          return true;
+        }
+      }
+    }
+    it->second->ProcessUdpPacket(packet_info.self_address,
+                                 packet_info.peer_address, packet_info.packet);
+    return true;
+  }
+  if (packet_info.version.IsKnown()) {
+    // We did not find the connection ID, check if we've replaced it.
+    // This is only performed for supported versions because packets with
+    // unsupported versions can flow through this function in order to send
+    // a version negotiation packet, but we know that their connection ID
+    // did not get replaced since that is performed on connection creation,
+    // and that only happens for known verions.
+    QuicConnectionId replaced_connection_id = MaybeReplaceServerConnectionId(
+        server_connection_id, packet_info.version);
+    if (replaced_connection_id != server_connection_id) {
+      // Search for the replacement.
+      auto it2 = reference_counted_session_map_.find(replaced_connection_id);
+      if (it2 != reference_counted_session_map_.end()) {
+        QUICHE_DCHECK(
+            !buffered_packets_.HasBufferedPackets(replaced_connection_id));
+        it2->second->ProcessUdpPacket(packet_info.self_address,
+                                      packet_info.peer_address,
+                                      packet_info.packet);
+        return true;
+      }
+    }
+  }
+
+  if (buffered_packets_.HasChloForConnection(server_connection_id)) {
+    BufferEarlyPacket(packet_info);
+    return true;
+  }
+
+  if (OnFailedToDispatchPacket(packet_info)) {
+    return true;
+  }
+
+  if (time_wait_list_manager_->IsConnectionIdInTimeWait(server_connection_id)) {
+    // This connection ID is already in time-wait state.
+    time_wait_list_manager_->ProcessPacket(
+        packet_info.self_address, packet_info.peer_address,
+        packet_info.destination_connection_id, packet_info.form,
+        packet_info.packet.length(), GetPerPacketContext());
+    return true;
+  }
+
+  // The packet has an unknown connection ID.
+  if (!accept_new_connections_ && packet_info.version_flag) {
+    // If not accepting new connections, reject packets with version which can
+    // potentially result in new connection creation. But if the packet doesn't
+    // have version flag, leave it to ValidityChecks() to reset it.
+    // By adding the connection to time wait list, following packets on this
+    // connection will not reach ShouldAcceptNewConnections().
+    StatelesslyTerminateConnection(
+        packet_info.destination_connection_id, packet_info.form,
+        packet_info.version_flag, packet_info.use_length_prefix,
+        packet_info.version, QUIC_HANDSHAKE_FAILED,
+        "Stop accepting new connections",
+        quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
+    // Time wait list will reject the packet correspondingly..
+    time_wait_list_manager()->ProcessPacket(
+        packet_info.self_address, packet_info.peer_address,
+        packet_info.destination_connection_id, packet_info.form,
+        packet_info.packet.length(), GetPerPacketContext());
+    OnNewConnectionRejected();
+    return true;
+  }
+
+  // Unless the packet provides a version, assume that we can continue
+  // processing using our preferred version.
+  if (packet_info.version_flag) {
+    if (!IsSupportedVersion(packet_info.version)) {
+      if (ShouldCreateSessionForUnknownVersion(packet_info.version_label)) {
+        return false;
+      }
+      if (!crypto_config()->validate_chlo_size() ||
+          packet_info.packet.length() >= kMinPacketSizeForVersionNegotiation) {
+        // Since the version is not supported, send a version negotiation
+        // packet and stop processing the current packet.
+        QuicConnectionId client_connection_id =
+            packet_info.source_connection_id;
+        time_wait_list_manager()->SendVersionNegotiationPacket(
+            server_connection_id, client_connection_id,
+            packet_info.form != GOOGLE_QUIC_PACKET,
+            packet_info.use_length_prefix, GetSupportedVersions(),
+            packet_info.self_address, packet_info.peer_address,
+            GetPerPacketContext());
+      }
+      return true;
+    }
+
+    if (crypto_config()->validate_chlo_size() &&
+        packet_info.form == IETF_QUIC_LONG_HEADER_PACKET &&
+        packet_info.long_packet_type == INITIAL &&
+        packet_info.packet.length() < kMinClientInitialPacketLength) {
+      QUIC_DVLOG(1) << "Dropping initial packet which is too short, length: "
+                    << packet_info.packet.length();
+      QUIC_CODE_COUNT(quic_drop_small_initial_packets);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void QuicDispatcher::ProcessHeader(ReceivedPacketInfo* packet_info) {
+  QuicConnectionId server_connection_id =
+      packet_info->destination_connection_id;
+  // Packet's connection ID is unknown.  Apply the validity checks.
+  QuicPacketFate fate = ValidityChecks(*packet_info);
+
+  if (fate == kFateProcess) {
+    absl::optional<ParsedClientHello> parsed_chlo =
+        TryExtractChloOrBufferEarlyPacket(*packet_info);
+    if (!parsed_chlo.has_value()) {
+      // Client Hello incomplete. Packet has been buffered or (rarely) dropped.
+      return;
+    }
+
+    // Client Hello fully received.
+    fate = ValidityChecksOnFullChlo(*packet_info, *parsed_chlo);
+
+    if (fate == kFateProcess) {
+      QUICHE_DCHECK(
+          parsed_chlo->legacy_version_encapsulation_inner_packet.empty() ||
+          !packet_info->version.UsesTls());
+      if (MaybeHandleLegacyVersionEncapsulation(
+              this, parsed_chlo->legacy_version_encapsulation_inner_packet,
+              *packet_info)) {
+        return;
+      }
+
+      ProcessChlo(*std::move(parsed_chlo), packet_info);
+      return;
+    }
+  }
+
+  switch (fate) {
+    case kFateProcess:
+      // kFateProcess have been processed above.
+      QUIC_BUG(quic_dispatcher_bad_packet_fate) << fate;
+      break;
+    case kFateTimeWait:
+      // Add this connection_id to the time-wait state, to safely reject
+      // future packets.
+      QUIC_DLOG(INFO) << "Adding connection ID " << server_connection_id
+                      << " to time-wait list.";
+      QUIC_CODE_COUNT(quic_reject_fate_time_wait);
+      StatelesslyTerminateConnection(
+          server_connection_id, packet_info->form, packet_info->version_flag,
+          packet_info->use_length_prefix, packet_info->version,
+          QUIC_HANDSHAKE_FAILED, "Reject connection",
+          quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
+
+      QUICHE_DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
+          server_connection_id));
+      time_wait_list_manager_->ProcessPacket(
+          packet_info->self_address, packet_info->peer_address,
+          server_connection_id, packet_info->form, packet_info->packet.length(),
+          GetPerPacketContext());
+
+      buffered_packets_.DiscardPackets(server_connection_id);
+      break;
+    case kFateDrop:
+      break;
+  }
+}
+
+absl::optional<ParsedClientHello>
+QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
+    const ReceivedPacketInfo& packet_info) {
+  if (packet_info.version.UsesTls()) {
+    bool has_full_tls_chlo = false;
+    std::string sni;
+    std::vector<std::string> alpns;
+    bool resumption_attempted = false, early_data_attempted = false;
+    if (buffered_packets_.HasBufferedPackets(
+            packet_info.destination_connection_id)) {
+      // If we already have buffered packets for this connection ID,
+      // use the associated TlsChloExtractor to parse this packet.
+      has_full_tls_chlo = buffered_packets_.IngestPacketForTlsChloExtraction(
+          packet_info.destination_connection_id, packet_info.version,
+          packet_info.packet, &alpns, &sni, &resumption_attempted,
+          &early_data_attempted);
+    } else {
+      // If we do not have a BufferedPacketList for this connection ID,
+      // create a single-use one to check whether this packet contains a
+      // full single-packet CHLO.
+      TlsChloExtractor tls_chlo_extractor;
+      tls_chlo_extractor.IngestPacket(packet_info.version, packet_info.packet);
+      if (tls_chlo_extractor.HasParsedFullChlo()) {
+        // This packet contains a full single-packet CHLO.
+        has_full_tls_chlo = true;
+        alpns = tls_chlo_extractor.alpns();
+        sni = tls_chlo_extractor.server_name();
+        resumption_attempted = tls_chlo_extractor.resumption_attempted();
+        early_data_attempted = tls_chlo_extractor.early_data_attempted();
+      }
+    }
+    if (!has_full_tls_chlo) {
+      // This packet does not contain a full CHLO. It could be a 0-RTT
+      // packet that arrived before the CHLO (due to loss or reordering),
+      // or it could be a fragment of a multi-packet CHLO.
+      BufferEarlyPacket(packet_info);
+      return absl::nullopt;
+    }
+
+    ParsedClientHello parsed_chlo;
+    parsed_chlo.sni = std::move(sni);
+    parsed_chlo.alpns = std::move(alpns);
+    if (packet_info.retry_token.has_value()) {
+      parsed_chlo.retry_token = std::string(*packet_info.retry_token);
+    }
+    parsed_chlo.resumption_attempted = resumption_attempted;
+    parsed_chlo.early_data_attempted = early_data_attempted;
+    return parsed_chlo;
+  }
+
+  ChloAlpnSniExtractor alpn_extractor;
+  if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
+      !ChloExtractor::Extract(packet_info.packet, packet_info.version,
+                              config_->create_session_tag_indicators(),
+                              &alpn_extractor,
+                              packet_info.destination_connection_id.length())) {
+    // Buffer non-CHLO packets.
+    BufferEarlyPacket(packet_info);
+    return absl::nullopt;
+  }
+
+  // We only apply this check for versions that do not use the IETF
+  // invariant header because those versions are already checked in
+  // QuicDispatcher::MaybeDispatchPacket.
+  if (packet_info.version_flag &&
+      !packet_info.version.HasIetfInvariantHeader() &&
+      crypto_config()->validate_chlo_size() &&
+      packet_info.packet.length() < kMinClientInitialPacketLength) {
+    QUIC_DVLOG(1) << "Dropping CHLO packet which is too short, length: "
+                  << packet_info.packet.length();
+    QUIC_CODE_COUNT(quic_drop_small_chlo_packets);
+    return absl::nullopt;
+  }
+
+  ParsedClientHello parsed_chlo;
+  parsed_chlo.legacy_version_encapsulation_inner_packet =
+      alpn_extractor.ConsumeLegacyVersionEncapsulationInnerPacket();
+  parsed_chlo.sni = alpn_extractor.ConsumeSni();
+  parsed_chlo.uaid = alpn_extractor.ConsumeUaid();
+  parsed_chlo.alpns = {alpn_extractor.ConsumeAlpn()};
+  return parsed_chlo;
+}
+
+std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) {
+  if (alpns.empty()) {
+    return "";
+  }
+  if (alpns.size() > 1u) {
+    const std::vector<std::string>& supported_alpns =
+        version_manager_->GetSupportedAlpns();
+    for (const std::string& alpn : alpns) {
+      if (std::find(supported_alpns.begin(), supported_alpns.end(), alpn) !=
+          supported_alpns.end()) {
+        return alpn;
+      }
+    }
+  }
+  return alpns[0];
+}
+
+QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
+    const ReceivedPacketInfo& packet_info) {
+  if (!packet_info.version_flag) {
+    QUIC_DLOG(INFO)
+        << "Packet without version arrived for unknown connection ID "
+        << packet_info.destination_connection_id;
+    MaybeResetPacketsWithNoVersion(packet_info);
+    return kFateDrop;
+  }
+
+  // Let the connection parse and validate packet number.
+  return kFateProcess;
+}
+
+void QuicDispatcher::CleanUpSession(QuicConnectionId server_connection_id,
+                                    QuicConnection* connection,
+                                    QuicErrorCode /*error*/,
+                                    const std::string& /*error_details*/,
+                                    ConnectionCloseSource /*source*/) {
+  write_blocked_list_.erase(connection);
+  QuicTimeWaitListManager::TimeWaitAction action =
+      QuicTimeWaitListManager::SEND_STATELESS_RESET;
+  if (connection->termination_packets() != nullptr &&
+      !connection->termination_packets()->empty()) {
+    action = QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS;
+  } else {
+    if (!connection->IsHandshakeComplete()) {
+      // TODO(fayang): Do not serialize connection close packet if the
+      // connection is closed by the client.
+      if (!connection->version().HasIetfInvariantHeader()) {
+        QUIC_CODE_COUNT(gquic_add_to_time_wait_list_with_handshake_failed);
+      } else {
+        QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_handshake_failed);
+      }
+      // This serializes a connection close termination packet and adds the
+      // connection to the time wait list.
+      StatelessConnectionTerminator terminator(
+          server_connection_id, connection->version(), helper_.get(),
+          time_wait_list_manager_.get());
+      terminator.CloseConnection(
+          QUIC_HANDSHAKE_FAILED,
+          "Connection is closed by server before handshake confirmed",
+          connection->version().HasIetfInvariantHeader(),
+          connection->GetActiveServerConnectionIds());
+      return;
+    }
+    QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_stateless_reset);
+  }
+  time_wait_list_manager_->AddConnectionIdToTimeWait(
+      action,
+      TimeWaitConnectionInfo(
+          connection->version().HasIetfInvariantHeader(),
+          connection->termination_packets(),
+          connection->GetActiveServerConnectionIds(),
+          connection->sent_packet_manager().GetRttStats()->smoothed_rtt()));
+}
+
+void QuicDispatcher::StartAcceptingNewConnections() {
+  accept_new_connections_ = true;
+}
+
+void QuicDispatcher::StopAcceptingNewConnections() {
+  accept_new_connections_ = false;
+  // No more CHLO will arrive and buffered CHLOs shouldn't be able to create
+  // connections.
+  buffered_packets_.DiscardAllPackets();
+}
+
+void QuicDispatcher::PerformActionOnActiveSessions(
+    std::function<void(QuicSession*)> operation) const {
+  absl::flat_hash_set<QuicSession*> visited_session;
+  visited_session.reserve(reference_counted_session_map_.size());
+  for (auto const& kv : reference_counted_session_map_) {
+    QuicSession* session = kv.second.get();
+    if (visited_session.insert(session).second) {
+      operation(session);
+    }
+  }
+}
+
+// Get a snapshot of all sessions.
+std::vector<std::shared_ptr<QuicSession>> QuicDispatcher::GetSessionsSnapshot()
+    const {
+  std::vector<std::shared_ptr<QuicSession>> snapshot;
+  snapshot.reserve(reference_counted_session_map_.size());
+  absl::flat_hash_set<QuicSession*> visited_session;
+  visited_session.reserve(reference_counted_session_map_.size());
+  for (auto const& kv : reference_counted_session_map_) {
+    QuicSession* session = kv.second.get();
+    if (visited_session.insert(session).second) {
+      snapshot.push_back(kv.second);
+    }
+  }
+  return snapshot;
+}
+
+std::unique_ptr<QuicPerPacketContext> QuicDispatcher::GetPerPacketContext()
+    const {
+  return nullptr;
+}
+
+void QuicDispatcher::DeleteSessions() {
+  if (!write_blocked_list_.empty()) {
+    for (const auto& session : closed_session_list_) {
+      if (write_blocked_list_.erase(session->connection()) != 0) {
+        QUIC_BUG(quic_bug_12724_2)
+            << "QuicConnection was in WriteBlockedList before destruction "
+            << session->connection()->connection_id();
+      }
+    }
+  }
+  closed_session_list_.clear();
+}
+
+void QuicDispatcher::ClearStatelessResetAddresses() {
+  recent_stateless_reset_addresses_.clear();
+}
+
+void QuicDispatcher::OnCanWrite() {
+  // The socket is now writable.
+  writer_->SetWritable();
+
+  // Move every blocked writer in |write_blocked_list_| to a temporary list.
+  const size_t num_blocked_writers_before = write_blocked_list_.size();
+  WriteBlockedList temp_list;
+  temp_list.swap(write_blocked_list_);
+  QUICHE_DCHECK(write_blocked_list_.empty());
+
+  // Give each blocked writer a chance to write what they indended to write.
+  // If they are blocked again, they will call |OnWriteBlocked| to add
+  // themselves back into |write_blocked_list_|.
+  while (!temp_list.empty()) {
+    QuicBlockedWriterInterface* blocked_writer = temp_list.begin()->first;
+    temp_list.erase(temp_list.begin());
+    blocked_writer->OnBlockedWriterCanWrite();
+  }
+  const size_t num_blocked_writers_after = write_blocked_list_.size();
+  if (num_blocked_writers_after != 0) {
+    if (num_blocked_writers_before == num_blocked_writers_after) {
+      QUIC_CODE_COUNT(quic_zero_progress_on_can_write);
+    } else {
+      QUIC_CODE_COUNT(quic_blocked_again_on_can_write);
+    }
+  }
+}
+
+bool QuicDispatcher::HasPendingWrites() const {
+  return !write_blocked_list_.empty();
+}
+
+void QuicDispatcher::Shutdown() {
+  while (!reference_counted_session_map_.empty()) {
+    QuicSession* session = reference_counted_session_map_.begin()->second.get();
+    session->connection()->CloseConnection(
+        QUIC_PEER_GOING_AWAY, "Server shutdown imminent",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    // Validate that the session removes itself from the session map on close.
+    QUICHE_DCHECK(reference_counted_session_map_.empty() ||
+                  reference_counted_session_map_.begin()->second.get() !=
+                      session);
+  }
+  DeleteSessions();
+}
+
+void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
+                                        QuicErrorCode error,
+                                        const std::string& error_details,
+                                        ConnectionCloseSource source) {
+  auto it = reference_counted_session_map_.find(server_connection_id);
+  if (it == reference_counted_session_map_.end()) {
+    QUIC_BUG(quic_bug_10287_3) << "ConnectionId " << server_connection_id
+                               << " does not exist in the session map.  Error: "
+                               << QuicErrorCodeToString(error);
+    QUIC_BUG(quic_bug_10287_4) << QuicStackTrace();
+    return;
+  }
+
+  QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
+      << "Closing connection (" << server_connection_id
+      << ") due to error: " << QuicErrorCodeToString(error)
+      << ", with details: " << error_details;
+
+  QuicConnection* connection = it->second->connection();
+  if (ShouldDestroySessionAsynchronously()) {
+    // Set up alarm to fire immediately to bring destruction of this session
+    // out of current call stack.
+    if (closed_session_list_.empty()) {
+      delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(),
+                                     QuicTime::Delta::Zero());
+    }
+    closed_session_list_.push_back(std::move(it->second));
+  }
+  CleanUpSession(it->first, connection, error, error_details, source);
+  for (const QuicConnectionId& cid :
+       connection->GetActiveServerConnectionIds()) {
+    reference_counted_session_map_.erase(cid);
+  }
+  --num_sessions_in_session_map_;
+}
+
+void QuicDispatcher::OnWriteBlocked(
+    QuicBlockedWriterInterface* blocked_writer) {
+  if (!blocked_writer->IsWriterBlocked()) {
+    // It is a programming error if this ever happens. When we are sure it is
+    // not happening, replace it with a QUICHE_DCHECK.
+    QUIC_BUG(quic_bug_12724_4)
+        << "Tried to add writer into blocked list when it shouldn't be added";
+    // Return without adding the connection to the blocked list, to avoid
+    // infinite loops in OnCanWrite.
+    return;
+  }
+
+  write_blocked_list_.insert(std::make_pair(blocked_writer, true));
+}
+
+void QuicDispatcher::OnRstStreamReceived(const QuicRstStreamFrame& /*frame*/) {}
+
+void QuicDispatcher::OnStopSendingReceived(
+    const QuicStopSendingFrame& /*frame*/) {}
+
+void QuicDispatcher::OnNewConnectionIdSent(
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& new_connection_id) {
+  auto it = reference_counted_session_map_.find(server_connection_id);
+  if (it == reference_counted_session_map_.end()) {
+    QUIC_BUG(quic_bug_10287_7)
+        << "Couldn't locate the session that issues the connection ID in "
+           "reference_counted_session_map_.  server_connection_id:"
+        << server_connection_id << " new_connection_id: " << new_connection_id;
+    return;
+  }
+  // Count new connection ID added to the dispatcher map.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 6, 6);
+  auto insertion_result = reference_counted_session_map_.insert(
+      std::make_pair(new_connection_id, it->second));
+  QUICHE_DCHECK(insertion_result.second);
+}
+
+void QuicDispatcher::OnConnectionIdRetired(
+    const QuicConnectionId& server_connection_id) {
+  reference_counted_session_map_.erase(server_connection_id);
+}
+
+void QuicDispatcher::OnConnectionAddedToTimeWaitList(
+    QuicConnectionId server_connection_id) {
+  QUIC_DLOG(INFO) << "Connection " << server_connection_id
+                  << " added to time wait list.";
+}
+
+void QuicDispatcher::StatelesslyTerminateConnection(
+    QuicConnectionId server_connection_id,
+    PacketHeaderFormat format,
+    bool version_flag,
+    bool use_length_prefix,
+    ParsedQuicVersion version,
+    QuicErrorCode error_code,
+    const std::string& error_details,
+    QuicTimeWaitListManager::TimeWaitAction action) {
+  if (format != IETF_QUIC_LONG_HEADER_PACKET && !version_flag) {
+    QUIC_DVLOG(1) << "Statelessly terminating " << server_connection_id
+                  << " based on a non-ietf-long packet, action:" << action
+                  << ", error_code:" << error_code
+                  << ", error_details:" << error_details;
+    time_wait_list_manager_->AddConnectionIdToTimeWait(
+        action, TimeWaitConnectionInfo(format != GOOGLE_QUIC_PACKET, nullptr,
+                                       {server_connection_id}));
+    return;
+  }
+
+  // If the version is known and supported by framer, send a connection close.
+  if (IsSupportedVersion(version)) {
+    QUIC_DVLOG(1)
+        << "Statelessly terminating " << server_connection_id
+        << " based on an ietf-long packet, which has a supported version:"
+        << version << ", error_code:" << error_code
+        << ", error_details:" << error_details;
+
+    StatelessConnectionTerminator terminator(server_connection_id, version,
+                                             helper_.get(),
+                                             time_wait_list_manager_.get());
+    // This also adds the connection to time wait list.
+    terminator.CloseConnection(
+        error_code, error_details, format != GOOGLE_QUIC_PACKET,
+        /*active_connection_ids=*/{server_connection_id});
+    QUIC_CODE_COUNT(quic_dispatcher_generated_connection_close);
+    QuicSession::RecordConnectionCloseAtServer(
+        error_code, ConnectionCloseSource::FROM_SELF);
+    return;
+  }
+
+  QUIC_DVLOG(1)
+      << "Statelessly terminating " << server_connection_id
+      << " based on an ietf-long packet, which has an unsupported version:"
+      << version << ", error_code:" << error_code
+      << ", error_details:" << error_details;
+  // Version is unknown or unsupported by framer, send a version negotiation
+  // with an empty version list, which can be understood by the client.
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(QuicFramer::BuildVersionNegotiationPacket(
+      server_connection_id, EmptyQuicConnectionId(),
+      /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, use_length_prefix,
+      /*versions=*/{}));
+  time_wait_list_manager()->AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/format != GOOGLE_QUIC_PACKET,
+                             &termination_packets, {server_connection_id}));
+}
+
+bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
+    QuicVersionLabel /*version_label*/) {
+  return false;
+}
+
+void QuicDispatcher::OnExpiredPackets(
+    QuicConnectionId server_connection_id,
+    BufferedPacketList early_arrived_packets) {
+  QUIC_CODE_COUNT(quic_reject_buffered_packets_expired);
+  StatelesslyTerminateConnection(
+      server_connection_id,
+      early_arrived_packets.ietf_quic ? IETF_QUIC_LONG_HEADER_PACKET
+                                      : GOOGLE_QUIC_PACKET,
+      /*version_flag=*/true,
+      early_arrived_packets.version.HasLengthPrefixedConnectionIds(),
+      early_arrived_packets.version, QUIC_HANDSHAKE_FAILED,
+      "Packets buffered for too long",
+      quic::QuicTimeWaitListManager::SEND_STATELESS_RESET);
+}
+
+void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
+  // Reset the counter before starting creating connections.
+  new_sessions_allowed_per_event_loop_ = max_connections_to_create;
+  for (; new_sessions_allowed_per_event_loop_ > 0;
+       --new_sessions_allowed_per_event_loop_) {
+    QuicConnectionId server_connection_id;
+    BufferedPacketList packet_list =
+        buffered_packets_.DeliverPacketsForNextConnection(
+            &server_connection_id);
+    const std::list<BufferedPacket>& packets = packet_list.buffered_packets;
+    if (packets.empty()) {
+      return;
+    }
+    if (!packet_list.parsed_chlo.has_value()) {
+      QUIC_BUG(quic_dispatcher_no_parsed_chlo_in_buffered_packets)
+          << "Buffered connection has no CHLO. connection_id:"
+          << server_connection_id;
+      continue;
+    }
+    const ParsedClientHello& parsed_chlo = *packet_list.parsed_chlo;
+    QuicConnectionId original_connection_id = server_connection_id;
+    server_connection_id = MaybeReplaceServerConnectionId(server_connection_id,
+                                                          packet_list.version);
+    std::string alpn = SelectAlpn(parsed_chlo.alpns);
+    std::unique_ptr<QuicSession> session = CreateQuicSession(
+        server_connection_id, packets.front().self_address,
+        packets.front().peer_address, alpn, packet_list.version, parsed_chlo);
+    if (original_connection_id != server_connection_id) {
+      session->connection()->SetOriginalDestinationConnectionId(
+          original_connection_id);
+    }
+    QUIC_DLOG(INFO) << "Created new session for " << server_connection_id;
+
+    auto insertion_result = reference_counted_session_map_.insert(
+        std::make_pair(server_connection_id,
+                       std::shared_ptr<QuicSession>(std::move(session))));
+    if (!insertion_result.second) {
+      QUIC_BUG(quic_bug_12724_5)
+          << "Tried to add a session to session_map with existing connection "
+             "id: "
+          << server_connection_id;
+    } else {
+      ++num_sessions_in_session_map_;
+    }
+    DeliverPacketsToSession(packets, insertion_result.first->second.get());
+  }
+}
+
+bool QuicDispatcher::HasChlosBuffered() const {
+  return buffered_packets_.HasChlosBuffered();
+}
+
+bool QuicDispatcher::ShouldCreateOrBufferPacketForConnection(
+    const ReceivedPacketInfo& packet_info) {
+  QUIC_VLOG(1) << "Received packet from new connection "
+               << packet_info.destination_connection_id;
+  return true;
+}
+
+// Return true if there is any packet buffered in the store.
+bool QuicDispatcher::HasBufferedPackets(QuicConnectionId server_connection_id) {
+  return buffered_packets_.HasBufferedPackets(server_connection_id);
+}
+
+void QuicDispatcher::OnBufferPacketFailure(
+    EnqueuePacketResult result,
+    QuicConnectionId server_connection_id) {
+  QUIC_DLOG(INFO) << "Fail to buffer packet on connection "
+                  << server_connection_id << " because of " << result;
+}
+
+QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
+  return new QuicTimeWaitListManager(writer_.get(), this, helper_->GetClock(),
+                                     alarm_factory_.get());
+}
+
+void QuicDispatcher::BufferEarlyPacket(const ReceivedPacketInfo& packet_info) {
+  bool is_new_connection = !buffered_packets_.HasBufferedPackets(
+      packet_info.destination_connection_id);
+  if (is_new_connection &&
+      !ShouldCreateOrBufferPacketForConnection(packet_info)) {
+    return;
+  }
+
+  EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
+      packet_info.destination_connection_id,
+      packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet,
+      packet_info.self_address, packet_info.peer_address, packet_info.version,
+      /*parsed_chlo=*/absl::nullopt);
+  if (rs != EnqueuePacketResult::SUCCESS) {
+    OnBufferPacketFailure(rs, packet_info.destination_connection_id);
+  }
+}
+
+void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
+                                 ReceivedPacketInfo* packet_info) {
+  if (!buffered_packets_.HasBufferedPackets(
+          packet_info->destination_connection_id) &&
+      !ShouldCreateOrBufferPacketForConnection(*packet_info)) {
+    return;
+  }
+  if (GetQuicFlag(FLAGS_quic_allow_chlo_buffering) &&
+      new_sessions_allowed_per_event_loop_ <= 0) {
+    // Can't create new session any more. Wait till next event loop.
+    QUIC_BUG_IF(quic_bug_12724_7, buffered_packets_.HasChloForConnection(
+                                      packet_info->destination_connection_id));
+    EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
+        packet_info->destination_connection_id,
+        packet_info->form != GOOGLE_QUIC_PACKET, packet_info->packet,
+        packet_info->self_address, packet_info->peer_address,
+        packet_info->version, std::move(parsed_chlo));
+    if (rs != EnqueuePacketResult::SUCCESS) {
+      OnBufferPacketFailure(rs, packet_info->destination_connection_id);
+    }
+    return;
+  }
+
+  QuicConnectionId original_connection_id =
+      packet_info->destination_connection_id;
+  packet_info->destination_connection_id = MaybeReplaceServerConnectionId(
+      original_connection_id, packet_info->version);
+  // Creates a new session and process all buffered packets for this connection.
+  std::string alpn = SelectAlpn(parsed_chlo.alpns);
+  std::unique_ptr<QuicSession> session = CreateQuicSession(
+      packet_info->destination_connection_id, packet_info->self_address,
+      packet_info->peer_address, alpn, packet_info->version, parsed_chlo);
+  if (QUIC_PREDICT_FALSE(session == nullptr)) {
+    QUIC_BUG(quic_bug_10287_8)
+        << "CreateQuicSession returned nullptr for "
+        << packet_info->destination_connection_id << " from "
+        << packet_info->peer_address << " to " << packet_info->self_address
+        << " ALPN \"" << alpn << "\" version " << packet_info->version;
+    return;
+  }
+  if (original_connection_id != packet_info->destination_connection_id) {
+    session->connection()->SetOriginalDestinationConnectionId(
+        original_connection_id);
+  }
+  QUIC_DLOG(INFO) << "Created new session for "
+                  << packet_info->destination_connection_id;
+
+  QuicSession* session_ptr;
+  auto insertion_result = reference_counted_session_map_.insert(std::make_pair(
+      packet_info->destination_connection_id,
+      std::shared_ptr<QuicSession>(std::move(session.release()))));
+  if (!insertion_result.second) {
+    QUIC_BUG(quic_bug_10287_9)
+        << "Tried to add a session to session_map with existing "
+           "connection id: "
+        << packet_info->destination_connection_id;
+  } else {
+    ++num_sessions_in_session_map_;
+  }
+  session_ptr = insertion_result.first->second.get();
+  std::list<BufferedPacket> packets =
+      buffered_packets_.DeliverPackets(packet_info->destination_connection_id)
+          .buffered_packets;
+  // Process CHLO at first.
+  session_ptr->ProcessUdpPacket(packet_info->self_address,
+                                packet_info->peer_address, packet_info->packet);
+  // Deliver queued-up packets in the same order as they arrived.
+  // Do this even when flag is off because there might be still some packets
+  // buffered in the store before flag is turned off.
+  DeliverPacketsToSession(packets, session_ptr);
+  --new_sessions_allowed_per_event_loop_;
+}
+
+bool QuicDispatcher::ShouldDestroySessionAsynchronously() {
+  return true;
+}
+
+void QuicDispatcher::SetLastError(QuicErrorCode error) {
+  last_error_ = error;
+}
+
+bool QuicDispatcher::OnFailedToDispatchPacket(
+    const ReceivedPacketInfo& /*packet_info*/) {
+  return false;
+}
+
+const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
+  return version_manager_->GetSupportedVersions();
+}
+
+void QuicDispatcher::DeliverPacketsToSession(
+    const std::list<BufferedPacket>& packets,
+    QuicSession* session) {
+  for (const BufferedPacket& packet : packets) {
+    session->ProcessUdpPacket(packet.self_address, packet.peer_address,
+                              *(packet.packet));
+  }
+}
+
+bool QuicDispatcher::IsSupportedVersion(const ParsedQuicVersion version) {
+  for (const ParsedQuicVersion& supported_version :
+       version_manager_->GetSupportedVersions()) {
+    if (version == supported_version) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicDispatcher::MaybeResetPacketsWithNoVersion(
+    const ReceivedPacketInfo& packet_info) {
+  QUICHE_DCHECK(!packet_info.version_flag);
+  // Do not send a stateless reset if a reset has been sent to this address
+  // recently.
+  if (recent_stateless_reset_addresses_.contains(packet_info.peer_address)) {
+    QUIC_CODE_COUNT(quic_donot_send_reset_repeatedly);
+    QUICHE_DCHECK(use_recent_reset_addresses_);
+    return;
+  }
+  if (packet_info.form != GOOGLE_QUIC_PACKET) {
+    // Drop IETF packets smaller than the minimal stateless reset length.
+    if (packet_info.packet.length() <=
+        QuicFramer::GetMinStatelessResetPacketLength()) {
+      QUIC_CODE_COUNT(quic_drop_too_small_short_header_packets);
+      return;
+    }
+  } else {
+    const size_t MinValidPacketLength =
+        kPacketHeaderTypeSize + expected_server_connection_id_length_ +
+        PACKET_1BYTE_PACKET_NUMBER + /*payload size=*/1 + /*tag size=*/12;
+    if (packet_info.packet.length() < MinValidPacketLength) {
+      // The packet size is too small.
+      QUIC_CODE_COUNT(drop_too_small_packets);
+      return;
+    }
+  }
+  if (use_recent_reset_addresses_) {
+    QUIC_RESTART_FLAG_COUNT(quic_use_recent_reset_addresses);
+    // Do not send a stateless reset if there are too many stateless reset
+    // addresses.
+    if (recent_stateless_reset_addresses_.size() >=
+        GetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses)) {
+      QUIC_CODE_COUNT(quic_too_many_recent_reset_addresses);
+      return;
+    }
+    if (recent_stateless_reset_addresses_.empty()) {
+      clear_stateless_reset_addresses_alarm_->Update(
+          helper()->GetClock()->ApproximateNow() +
+              QuicTime::Delta::FromMilliseconds(GetQuicFlag(
+                  FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms)),
+          QuicTime::Delta::Zero());
+    }
+    recent_stateless_reset_addresses_.emplace(packet_info.peer_address);
+  }
+
+  time_wait_list_manager()->SendPublicReset(
+      packet_info.self_address, packet_info.peer_address,
+      packet_info.destination_connection_id,
+      packet_info.form != GOOGLE_QUIC_PACKET, packet_info.packet.length(),
+      GetPerPacketContext());
+}
+
+size_t QuicDispatcher::NumSessions() const {
+  return num_sessions_in_session_map_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_dispatcher.h b/quiche/quic/core/quic_dispatcher.h
new file mode 100644
index 0000000..e529eda
--- /dev/null
+++ b/quiche/quic/core/quic_dispatcher.h
@@ -0,0 +1,484 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A server side dispatcher which dispatches a given client's data to their
+// stream.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
+#define QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_blocked_writer_interface.h"
+#include "quiche/quic/core/quic_buffered_packet_store.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_process_packet_interface.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/core/quic_version_manager.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+namespace test {
+class QuicDispatcherPeer;
+}  // namespace test
+
+class QuicConfig;
+class QuicCryptoServerConfig;
+
+class QUIC_NO_EXPORT QuicDispatcher
+    : public QuicTimeWaitListManager::Visitor,
+      public ProcessPacketInterface,
+      public QuicBufferedPacketStore::VisitorInterface {
+ public:
+  // Ideally we'd have a linked_hash_set: the  boolean is unused.
+  using WriteBlockedList =
+      quiche::QuicheLinkedHashMap<QuicBlockedWriterInterface*, bool>;
+
+  QuicDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      uint8_t expected_server_connection_id_length);
+  QuicDispatcher(const QuicDispatcher&) = delete;
+  QuicDispatcher& operator=(const QuicDispatcher&) = delete;
+
+  ~QuicDispatcher() override;
+
+  // Takes ownership of |writer|.
+  void InitializeWithWriter(QuicPacketWriter* writer);
+
+  // Process the incoming packet by creating a new session, passing it to
+  // an existing session, or passing it to the time wait list.
+  void ProcessPacket(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address,
+                     const QuicReceivedPacket& packet) override;
+
+  // Called when the socket becomes writable to allow queued writes to happen.
+  virtual void OnCanWrite();
+
+  // Returns true if there's anything in the blocked writer list.
+  virtual bool HasPendingWrites() const;
+
+  // Sends ConnectionClose frames to all connected clients.
+  void Shutdown();
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Ensure that the closed connection is cleaned up asynchronously.
+  void OnConnectionClosed(QuicConnectionId server_connection_id,
+                          QuicErrorCode error,
+                          const std::string& error_details,
+                          ConnectionCloseSource source) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Queues the blocked writer for later resumption.
+  void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Collects reset error code received on streams.
+  void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Collects reset error code received on streams.
+  void OnStopSendingReceived(const QuicStopSendingFrame& frame) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Add the newly issued connection ID to the session map.
+  void OnNewConnectionIdSent(
+      const QuicConnectionId& server_connection_id,
+      const QuicConnectionId& new_connection_id) override;
+
+  // QuicSession::Visitor interface implementation (via inheritance of
+  // QuicTimeWaitListManager::Visitor):
+  // Remove the retired connection ID from the session map.
+  void OnConnectionIdRetired(
+      const QuicConnectionId& server_connection_id) override;
+
+  // QuicTimeWaitListManager::Visitor interface implementation
+  // Called whenever the time wait list manager adds a new connection to the
+  // time-wait list.
+  void OnConnectionAddedToTimeWaitList(
+      QuicConnectionId server_connection_id) override;
+
+  using ReferenceCountedSessionMap =
+      absl::flat_hash_map<QuicConnectionId,
+                          std::shared_ptr<QuicSession>,
+                          QuicConnectionIdHash>;
+
+  size_t NumSessions() const;
+
+  // Deletes all sessions on the closed session list and clears the list.
+  virtual void DeleteSessions();
+
+  // Clear recent_stateless_reset_addresses_.
+  void ClearStatelessResetAddresses();
+
+  using ConnectionIdMap = absl::
+      flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>;
+
+  // QuicBufferedPacketStore::VisitorInterface implementation.
+  void OnExpiredPackets(QuicConnectionId server_connection_id,
+                        QuicBufferedPacketStore::BufferedPacketList
+                            early_arrived_packets) override;
+
+  // Create connections for previously buffered CHLOs as many as allowed.
+  virtual void ProcessBufferedChlos(size_t max_connections_to_create);
+
+  // Return true if there is CHLO buffered.
+  virtual bool HasChlosBuffered() const;
+
+  // Start accepting new ConnectionIds.
+  void StartAcceptingNewConnections();
+
+  // Stop accepting new ConnectionIds, either as a part of the lame
+  // duck process or because explicitly configured.
+  void StopAcceptingNewConnections();
+
+  // Apply an operation for each session.
+  void PerformActionOnActiveSessions(
+      std::function<void(QuicSession*)> operation) const;
+
+  // Get a snapshot of all sessions.
+  std::vector<std::shared_ptr<QuicSession>> GetSessionsSnapshot() const;
+
+  bool accept_new_connections() const { return accept_new_connections_; }
+
+ protected:
+  // Creates a QUIC session based on the given information.
+  // |alpn| is the selected ALPN from |parsed_chlo.alpns|.
+  virtual std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId server_connection_id,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version,
+      const ParsedClientHello& parsed_chlo) = 0;
+
+  // Tries to validate and dispatch packet based on available information.
+  // Returns true if packet is dropped or successfully dispatched (e.g.,
+  // processed by existing session, processed by time wait list, etc.),
+  // otherwise, returns false and the packet needs further processing.
+  virtual bool MaybeDispatchPacket(const ReceivedPacketInfo& packet_info);
+
+  // Generate a connection ID with a length that is expected by the dispatcher.
+  // Called only when |server_connection_id| is shorter than
+  // |expected_connection_id_length|.
+  // Note that this MUST produce a deterministic result (calling this method
+  // with two connection IDs that are equal must produce the same result).
+  // Note that this is not used in general operation because our default
+  // |expected_server_connection_id_length| is 8, and the IETF specification
+  // requires clients to use an initial length of at least 8. However, we
+  // allow disabling that requirement via
+  // |allow_short_initial_server_connection_ids_|.
+  virtual QuicConnectionId ReplaceShortServerConnectionId(
+      const ParsedQuicVersion& version,
+      const QuicConnectionId& server_connection_id,
+      uint8_t expected_server_connection_id_length) const;
+
+  // Generate a connection ID with a length that is expected by the dispatcher.
+  // Called only when |server_connection_id| is longer than
+  // |expected_connection_id_length|.
+  // Note that this MUST produce a deterministic result (calling this method
+  // with two connection IDs that are equal must produce the same result).
+  virtual QuicConnectionId ReplaceLongServerConnectionId(
+      const ParsedQuicVersion& version,
+      const QuicConnectionId& server_connection_id,
+      uint8_t expected_server_connection_id_length) const;
+
+  // Values to be returned by ValidityChecks() to indicate what should be done
+  // with a packet. Fates with greater values are considered to be higher
+  // priority. ValidityChecks should return fate based on the priority order
+  // (i.e., returns higher priority fate first)
+  enum QuicPacketFate {
+    // Process the packet normally, which is usually to establish a connection.
+    kFateProcess,
+    // Put the connection ID into time-wait state and send a public reset.
+    kFateTimeWait,
+    // Drop the packet.
+    kFateDrop,
+  };
+
+  // This method is called by ProcessHeader on packets not associated with a
+  // known connection ID.  It applies validity checks and returns a
+  // QuicPacketFate to tell what should be done with the packet.
+  // TODO(fayang): Merge ValidityChecks into MaybeDispatchPacket.
+  virtual QuicPacketFate ValidityChecks(const ReceivedPacketInfo& packet_info);
+
+  // Extra validity checks after the full Client Hello is parsed, this allows
+  // subclasses to reject a connection based on sni or alpn.
+  // Only called if ValidityChecks returns kFateProcess.
+  virtual QuicPacketFate ValidityChecksOnFullChlo(
+      const ReceivedPacketInfo& /*packet_info*/,
+      const ParsedClientHello& /*parsed_chlo*/) const {
+    return kFateProcess;
+  }
+
+  // Create and return the time wait list manager for this dispatcher, which
+  // will be owned by the dispatcher as time_wait_list_manager_
+  virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
+
+  // Buffers packet until it can be delivered to a connection.
+  void BufferEarlyPacket(const ReceivedPacketInfo& packet_info);
+
+  // Called when |packet_info| is the last received packet of the client hello.
+  // |parsed_chlo| is the parsed version of the client hello. Creates a new
+  // connection and delivers any buffered packets for that connection id.
+  void ProcessChlo(ParsedClientHello parsed_chlo,
+                   ReceivedPacketInfo* packet_info);
+
+  // Return true if dispatcher wants to destroy session outside of
+  // OnConnectionClosed() call stack.
+  virtual bool ShouldDestroySessionAsynchronously();
+
+  QuicTimeWaitListManager* time_wait_list_manager() {
+    return time_wait_list_manager_.get();
+  }
+
+  const ParsedQuicVersionVector& GetSupportedVersions();
+
+  const QuicConfig& config() const { return *config_; }
+
+  const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
+
+  QuicCompressedCertsCache* compressed_certs_cache() {
+    return &compressed_certs_cache_;
+  }
+
+  QuicConnectionHelperInterface* helper() { return helper_.get(); }
+
+  QuicCryptoServerStreamBase::Helper* session_helper() {
+    return session_helper_.get();
+  }
+
+  const QuicCryptoServerStreamBase::Helper* session_helper() const {
+    return session_helper_.get();
+  }
+
+  QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
+
+  QuicPacketWriter* writer() { return writer_.get(); }
+
+  // Returns true if a session should be created for a connection with an
+  // unknown version identified by |version_label|.
+  virtual bool ShouldCreateSessionForUnknownVersion(
+      QuicVersionLabel version_label);
+
+  void SetLastError(QuicErrorCode error);
+
+  // Called by MaybeDispatchPacket when current packet cannot be dispatched.
+  // Used by subclasses to conduct specific logic to dispatch packet. Returns
+  // true if packet is successfully dispatched.
+  virtual bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info);
+
+  // Called when a new connection starts to be handled by this dispatcher.
+  // Either this connection is created or its packets is buffered while waiting
+  // for CHLO. Returns true if a new connection should be created or its packets
+  // should be buffered, false otherwise.
+  virtual bool ShouldCreateOrBufferPacketForConnection(
+      const ReceivedPacketInfo& packet_info);
+
+  bool HasBufferedPackets(QuicConnectionId server_connection_id);
+
+  // Called when BufferEarlyPacket() fail to buffer the packet.
+  virtual void OnBufferPacketFailure(
+      QuicBufferedPacketStore::EnqueuePacketResult result,
+      QuicConnectionId server_connection_id);
+
+  // Removes the session from the write blocked list, and adds the ConnectionId
+  // to the time-wait list.  The caller needs to manually remove the session
+  // from the map after that.
+  void CleanUpSession(QuicConnectionId server_connection_id,
+                      QuicConnection* connection,
+                      QuicErrorCode error,
+                      const std::string& error_details,
+                      ConnectionCloseSource source);
+
+  // Called to terminate a connection statelessly. Depending on |format|, either
+  // 1) send connection close with |error_code| and |error_details| and add
+  // connection to time wait list or 2) directly add connection to time wait
+  // list with |action|.
+  void StatelesslyTerminateConnection(
+      QuicConnectionId server_connection_id,
+      PacketHeaderFormat format,
+      bool version_flag,
+      bool use_length_prefix,
+      ParsedQuicVersion version,
+      QuicErrorCode error_code,
+      const std::string& error_details,
+      QuicTimeWaitListManager::TimeWaitAction action);
+
+  // Save/Restore per packet context.
+  virtual std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const;
+  virtual void RestorePerPacketContext(
+      std::unique_ptr<QuicPerPacketContext> /*context*/) {}
+
+  // If true, our framer will change its expected connection ID length
+  // to the received destination connection ID length of all IETF long headers.
+  void SetShouldUpdateExpectedServerConnectionIdLength(
+      bool should_update_expected_server_connection_id_length) {
+    should_update_expected_server_connection_id_length_ =
+        should_update_expected_server_connection_id_length;
+  }
+
+  // If true, the dispatcher will allow incoming initial packets that have
+  // destination connection IDs shorter than 64 bits.
+  void SetAllowShortInitialServerConnectionIds(
+      bool allow_short_initial_server_connection_ids) {
+    allow_short_initial_server_connection_ids_ =
+        allow_short_initial_server_connection_ids;
+  }
+
+  // Called if a packet from an unseen connection is reset or rejected.
+  virtual void OnNewConnectionRejected() {}
+
+  // Selects the preferred ALPN from a vector of ALPNs.
+  // This runs through the list of ALPNs provided by the client and picks the
+  // first one it supports. If no supported versions are found, the first
+  // element of the vector is returned.
+  std::string SelectAlpn(const std::vector<std::string>& alpns);
+
+  // If the connection ID length is different from what the dispatcher expects,
+  // replace the connection ID with one of the right length.
+  // Note that this MUST produce a deterministic result (calling this method
+  // with two connection IDs that are equal must produce the same result).
+  QuicConnectionId MaybeReplaceServerConnectionId(
+      const QuicConnectionId& server_connection_id,
+      const ParsedQuicVersion& version) const;
+
+  // Sends public/stateless reset packets with no version and unknown
+  // connection ID according to the packet's size.
+  virtual void MaybeResetPacketsWithNoVersion(
+      const quic::ReceivedPacketInfo& packet_info);
+
+ private:
+  friend class test::QuicDispatcherPeer;
+
+  // TODO(fayang): Consider to rename this function to
+  // ProcessValidatedPacketWithUnknownConnectionId.
+  void ProcessHeader(ReceivedPacketInfo* packet_info);
+
+  // Try to extract information(sni, alpns, ...) if the full Client Hello has
+  // been parsed.
+  //
+  // Return the parsed client hello if the full Client Hello has been
+  // successfully parsed.
+  //
+  // Otherwise return absl::nullopt and either buffer or (rarely) drop the
+  // packet.
+  absl::optional<ParsedClientHello> TryExtractChloOrBufferEarlyPacket(
+      const ReceivedPacketInfo& packet_info);
+
+  // Deliver |packets| to |session| for further processing.
+  void DeliverPacketsToSession(
+      const std::list<QuicBufferedPacketStore::BufferedPacket>& packets,
+      QuicSession* session);
+
+  // Returns true if |version| is a supported protocol version.
+  bool IsSupportedVersion(const ParsedQuicVersion version);
+
+  const QuicConfig* config_;
+
+  const QuicCryptoServerConfig* crypto_config_;
+
+  // The cache for most recently compressed certs.
+  QuicCompressedCertsCache compressed_certs_cache_;
+
+  // The list of connections waiting to write.
+  WriteBlockedList write_blocked_list_;
+
+  ReferenceCountedSessionMap reference_counted_session_map_;
+
+  // Entity that manages connection_ids in time wait state.
+  std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
+
+  // The list of closed but not-yet-deleted sessions.
+  std::vector<std::shared_ptr<QuicSession>> closed_session_list_;
+
+  // The helper used for all connections.
+  std::unique_ptr<QuicConnectionHelperInterface> helper_;
+
+  // The helper used for all sessions.
+  std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper_;
+
+  // Creates alarms.
+  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
+
+  // An alarm which deletes closed sessions.
+  std::unique_ptr<QuicAlarm> delete_sessions_alarm_;
+
+  // The writer to write to the socket with.
+  std::unique_ptr<QuicPacketWriter> writer_;
+
+  // Packets which are buffered until a connection can be created to handle
+  // them.
+  QuicBufferedPacketStore buffered_packets_;
+
+  // Used to get the supported versions based on flag. Does not own.
+  QuicVersionManager* version_manager_;
+
+  // The last error set by SetLastError().
+  // TODO(fayang): consider removing last_error_.
+  QuicErrorCode last_error_;
+
+  // Number of unique session in session map.
+  size_t num_sessions_in_session_map_ = 0;
+
+  // A backward counter of how many new sessions can be create within current
+  // event loop. When reaches 0, it means can't create sessions for now.
+  int16_t new_sessions_allowed_per_event_loop_;
+
+  // True if this dispatcher is accepting new ConnectionIds (new client
+  // connections), false otherwise.
+  bool accept_new_connections_;
+
+  // If false, the dispatcher follows the IETF spec and rejects packets with
+  // invalid destination connection IDs lengths below 64 bits.
+  // If true they are allowed.
+  bool allow_short_initial_server_connection_ids_;
+
+  // IETF short headers contain a destination connection ID but do not
+  // encode its length. This variable contains the length we expect to read.
+  // This is also used to signal an error when a long header packet with
+  // different destination connection ID length is received when
+  // should_update_expected_server_connection_id_length_ is false and packet's
+  // version does not allow variable length connection ID.
+  uint8_t expected_server_connection_id_length_;
+
+  // Records client addresses that have been recently reset.
+  absl::flat_hash_set<QuicSocketAddress, QuicSocketAddressHash>
+      recent_stateless_reset_addresses_;
+
+  // An alarm which clear recent_stateless_reset_addresses_.
+  std::unique_ptr<QuicAlarm> clear_stateless_reset_addresses_alarm_;
+
+  // If true, change expected_server_connection_id_length_ to be the received
+  // destination connection ID length of all IETF long headers.
+  bool should_update_expected_server_connection_id_length_;
+
+  const bool use_recent_reset_addresses_ =
+      GetQuicRestartFlag(quic_use_recent_reset_addresses);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
diff --git a/quiche/quic/core/quic_dispatcher_test.cc b/quiche/quic/core/quic_dispatcher_test.cc
new file mode 100644
index 0000000..3dad096
--- /dev/null
+++ b/quiche/quic/core/quic_dispatcher_test.cc
@@ -0,0 +1,2914 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_dispatcher.h"
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/chlo_extractor.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/mock_quic_time_wait_list_manager.h"
+#include "quiche/quic/test_tools/quic_buffered_packet_store_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_time_wait_list_manager_peer.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+using testing::ByMove;
+using testing::Eq;
+using testing::InSequence;
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Return;
+using testing::WithArg;
+using testing::WithoutArgs;
+
+static const size_t kDefaultMaxConnectionsInStore = 100;
+static const size_t kMaxConnectionsWithoutCHLO =
+    kDefaultMaxConnectionsInStore / 2;
+static const int16_t kMaxNumSessionsToCreate = 16;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestQuicSpdyServerSession : public QuicServerSessionBase {
+ public:
+  TestQuicSpdyServerSession(const QuicConfig& config,
+                            QuicConnection* connection,
+                            const QuicCryptoServerConfig* crypto_config,
+                            QuicCompressedCertsCache* compressed_certs_cache)
+      : QuicServerSessionBase(config, CurrentSupportedVersions(), connection,
+                              nullptr, nullptr, crypto_config,
+                              compressed_certs_cache) {
+    Initialize();
+  }
+  TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
+  TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
+      delete;
+
+  ~TestQuicSpdyServerSession() override { DeleteConnection(); }
+
+  MOCK_METHOD(void, OnConnectionClosed,
+              (const QuicConnectionCloseFrame& frame,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
+              (override));
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override {
+    return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
+                                    stream_helper());
+  }
+
+  QuicCryptoServerStreamBase::Helper* stream_helper() {
+    return QuicServerSessionBase::stream_helper();
+  }
+};
+
+class TestDispatcher : public QuicDispatcher {
+ public:
+  TestDispatcher(const QuicConfig* config,
+                 const QuicCryptoServerConfig* crypto_config,
+                 QuicVersionManager* version_manager, QuicRandom* random)
+      : QuicDispatcher(config, crypto_config, version_manager,
+                       std::make_unique<MockQuicConnectionHelper>(),
+                       std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+                           new QuicSimpleCryptoServerStreamHelper()),
+                       std::make_unique<TestAlarmFactory>(),
+                       kQuicDefaultConnectionIdLength),
+        random_(random) {}
+
+  MOCK_METHOD(std::unique_ptr<QuicSession>, CreateQuicSession,
+              (QuicConnectionId connection_id,
+               const QuicSocketAddress& self_address,
+               const QuicSocketAddress& peer_address, absl::string_view alpn,
+               const ParsedQuicVersion& version,
+               const ParsedClientHello& parsed_chlo),
+              (override));
+
+  MOCK_METHOD(bool, ShouldCreateOrBufferPacketForConnection,
+              (const ReceivedPacketInfo& packet_info), (override));
+
+  struct TestQuicPerPacketContext : public QuicPerPacketContext {
+    std::string custom_packet_context;
+  };
+
+  std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
+    auto test_context = std::make_unique<TestQuicPerPacketContext>();
+    test_context->custom_packet_context = custom_packet_context_;
+    return std::move(test_context);
+  }
+
+  void RestorePerPacketContext(
+      std::unique_ptr<QuicPerPacketContext> context) override {
+    TestQuicPerPacketContext* test_context =
+        static_cast<TestQuicPerPacketContext*>(context.get());
+    custom_packet_context_ = test_context->custom_packet_context;
+  }
+
+  std::string custom_packet_context_;
+
+  using QuicDispatcher::MaybeDispatchPacket;
+  using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
+  using QuicDispatcher::writer;
+
+  QuicRandom* random_;
+};
+
+// A Connection class which unregisters the session from the dispatcher when
+// sending connection close.
+// It'd be slightly more realistic to do this from the Session but it would
+// involve a lot more mocking.
+class MockServerConnection : public MockQuicConnection {
+ public:
+  MockServerConnection(QuicConnectionId connection_id,
+                       MockQuicConnectionHelper* helper,
+                       MockAlarmFactory* alarm_factory,
+                       QuicDispatcher* dispatcher)
+      : MockQuicConnection(connection_id, helper, alarm_factory,
+                           Perspective::IS_SERVER),
+        dispatcher_(dispatcher),
+        active_connection_ids_({connection_id}) {}
+
+  void AddNewConnectionId(QuicConnectionId id) {
+    dispatcher_->OnNewConnectionIdSent(active_connection_ids_.back(), id);
+    QuicConnectionPeer::SetServerConnectionId(this, id);
+    active_connection_ids_.push_back(id);
+  }
+
+  void RetireConnectionId(QuicConnectionId id) {
+    auto it = std::find(active_connection_ids_.begin(),
+                        active_connection_ids_.end(), id);
+    QUICHE_DCHECK(it != active_connection_ids_.end());
+    dispatcher_->OnConnectionIdRetired(id);
+    active_connection_ids_.erase(it);
+  }
+
+  std::vector<QuicConnectionId> GetActiveServerConnectionIds() const override {
+    return active_connection_ids_;
+  }
+
+  void UnregisterOnConnectionClosed() {
+    QUIC_LOG(ERROR) << "Unregistering " << connection_id();
+    dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
+                                    "Unregistering.",
+                                    ConnectionCloseSource::FROM_SELF);
+  }
+
+ private:
+  QuicDispatcher* dispatcher_;
+  std::vector<QuicConnectionId> active_connection_ids_;
+};
+
+class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicDispatcherTestBase()
+      : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
+
+  explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
+      : version_(GetParam()),
+        version_manager_(AllSupportedVersions()),
+        crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(), std::move(proof_source),
+                       KeyExchangeSource::Default()),
+        server_address_(QuicIpAddress::Any4(), 5),
+        dispatcher_(new NiceMock<TestDispatcher>(
+            &config_, &crypto_config_, &version_manager_,
+            mock_helper_.GetRandomGenerator())),
+        time_wait_list_manager_(nullptr),
+        session1_(nullptr),
+        session2_(nullptr),
+        store_(nullptr),
+        connection_id_(1) {}
+
+  void SetUp() override {
+    dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
+    // Set the counter to some value to start with.
+    QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
+        dispatcher_.get(), kMaxNumSessionsToCreate);
+    ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
+        .WillByDefault(Return(true));
+  }
+
+  MockQuicConnection* connection1() {
+    if (session1_ == nullptr) {
+      return nullptr;
+    }
+    return reinterpret_cast<MockQuicConnection*>(session1_->connection());
+  }
+
+  MockQuicConnection* connection2() {
+    if (session2_ == nullptr) {
+      return nullptr;
+    }
+    return reinterpret_cast<MockQuicConnection*>(session2_->connection());
+  }
+
+  // Process a packet with an 8 byte connection id,
+  // 6 byte packet number, default path id, and packet number 1,
+  // using the version under test.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, const std::string& data) {
+    ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
+                  CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
+  }
+
+  // Process a packet with a default path id, and packet number 1,
+  // using the version under test.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, const std::string& data,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicPacketNumberLength packet_number_length) {
+    ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
+                  server_connection_id_included, packet_number_length, 1);
+  }
+
+  // Process a packet using the version under test.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, const std::string& data,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicPacketNumberLength packet_number_length,
+                     uint64_t packet_number) {
+    ProcessPacket(peer_address, server_connection_id, has_version_flag,
+                  version_, data, true, server_connection_id_included,
+                  packet_number_length, packet_number);
+  }
+
+  // Processes a packet.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     bool has_version_flag, ParsedQuicVersion version,
+                     const std::string& data, bool full_padding,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicPacketNumberLength packet_number_length,
+                     uint64_t packet_number) {
+    ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
+                  has_version_flag, version, data, full_padding,
+                  server_connection_id_included, CONNECTION_ID_ABSENT,
+                  packet_number_length, packet_number);
+  }
+
+  // Processes a packet.
+  void ProcessPacket(QuicSocketAddress peer_address,
+                     QuicConnectionId server_connection_id,
+                     QuicConnectionId client_connection_id,
+                     bool has_version_flag, ParsedQuicVersion version,
+                     const std::string& data, bool full_padding,
+                     QuicConnectionIdIncluded server_connection_id_included,
+                     QuicConnectionIdIncluded client_connection_id_included,
+                     QuicPacketNumberLength packet_number_length,
+                     uint64_t packet_number) {
+    ParsedQuicVersionVector versions(SupportedVersions(version));
+    std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+        server_connection_id, client_connection_id, has_version_flag, false,
+        packet_number, data, full_padding, server_connection_id_included,
+        client_connection_id_included, packet_number_length, &versions));
+    std::unique_ptr<QuicReceivedPacket> received_packet(
+        ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
+    ProcessReceivedPacket(std::move(received_packet), peer_address, version,
+                          server_connection_id);
+  }
+
+  void ProcessReceivedPacket(
+      std::unique_ptr<QuicReceivedPacket> received_packet,
+      const QuicSocketAddress& peer_address, const ParsedQuicVersion& version,
+      const QuicConnectionId& server_connection_id) {
+    if (version.UsesQuicCrypto() &&
+        ChloExtractor::Extract(*received_packet, version, {}, nullptr,
+                               server_connection_id.length())) {
+      // Add CHLO packet to the beginning to be verified first, because it is
+      // also processed first by new session.
+      data_connection_map_[server_connection_id].push_front(
+          std::string(received_packet->data(), received_packet->length()));
+    } else {
+      // For non-CHLO, always append to last.
+      data_connection_map_[server_connection_id].push_back(
+          std::string(received_packet->data(), received_packet->length()));
+    }
+    dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
+  }
+
+  void ValidatePacket(QuicConnectionId conn_id,
+                      const QuicEncryptedPacket& packet) {
+    EXPECT_EQ(data_connection_map_[conn_id].front().length(),
+              packet.AsStringPiece().length());
+    EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
+    data_connection_map_[conn_id].pop_front();
+  }
+
+  std::unique_ptr<QuicSession> CreateSession(
+      TestDispatcher* dispatcher, const QuicConfig& config,
+      QuicConnectionId connection_id, const QuicSocketAddress& /*peer_address*/,
+      MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      TestQuicSpdyServerSession** session_ptr) {
+    MockServerConnection* connection = new MockServerConnection(
+        connection_id, helper, alarm_factory, dispatcher);
+    connection->SetQuicPacketWriter(dispatcher->writer(),
+                                    /*owns_writer=*/false);
+    auto session = std::make_unique<TestQuicSpdyServerSession>(
+        config, connection, crypto_config, compressed_certs_cache);
+    *session_ptr = session.get();
+    connection->set_visitor(session.get());
+    ON_CALL(*connection, CloseConnection(_, _, _))
+        .WillByDefault(WithoutArgs(Invoke(
+            connection, &MockServerConnection::UnregisterOnConnectionClosed)));
+    return session;
+  }
+
+  void CreateTimeWaitListManager() {
+    time_wait_list_manager_ = new MockTimeWaitListManager(
+        QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
+        mock_helper_.GetClock(), &mock_alarm_factory_);
+    // dispatcher_ takes the ownership of time_wait_list_manager_.
+    QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                               time_wait_list_manager_);
+  }
+
+  std::string SerializeCHLO() {
+    CryptoHandshakeMessage client_hello;
+    client_hello.set_tag(kCHLO);
+    client_hello.SetStringPiece(kALPN, ExpectedAlpn());
+    return std::string(client_hello.GetSerialized().AsStringPiece());
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    ProcessUndecryptableEarlyPacket(version_, peer_address,
+                                    server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
+        GetUndecryptableEarlyPacket(version, server_connection_id);
+    std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
+        *encrypted_packet, mock_helper_.GetClock()->Now()));
+    ProcessReceivedPacket(std::move(received_packet), peer_address, version,
+                          server_connection_id);
+  }
+
+  void ProcessFirstFlight(const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version_, peer_address, server_connection_id);
+  }
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version, peer_address, server_connection_id,
+                       EmptyQuicConnectionId());
+  }
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id,
+                          const QuicConnectionId& client_connection_id) {
+    ProcessFirstFlight(version, peer_address, server_connection_id,
+                       client_connection_id, TestClientCryptoConfig());
+  }
+
+  void ProcessFirstFlight(
+      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id,
+      const QuicConnectionId& client_connection_id,
+      std::unique_ptr<QuicCryptoClientConfig> client_crypto_config) {
+    std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+        GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                server_connection_id, client_connection_id,
+                                std::move(client_crypto_config));
+    for (auto&& packet : packets) {
+      ProcessReceivedPacket(std::move(packet), peer_address, version,
+                            server_connection_id);
+    }
+  }
+
+  std::unique_ptr<QuicCryptoClientConfig> TestClientCryptoConfig() {
+    auto client_crypto_config = std::make_unique<QuicCryptoClientConfig>(
+        crypto_test_utils::ProofVerifierForTesting());
+    if (address_token_.has_value()) {
+      client_crypto_config->LookupOrCreate(TestServerId())
+          ->set_source_address_token(*address_token_);
+    }
+    return client_crypto_config;
+  }
+
+  // If called, the first flight packets generated in |ProcessFirstFlight| will
+  // contain the given |address_token|.
+  void SetAddressToken(std::string address_token) {
+    address_token_ = std::move(address_token);
+  }
+
+  std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
+    return AlpnForVersion(version);
+  }
+
+  std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
+
+  ParsedClientHello ParsedClientHelloForTest() {
+    ParsedClientHello parsed_chlo;
+    parsed_chlo.alpns = {ExpectedAlpn()};
+    parsed_chlo.sni = TestHostname();
+    return parsed_chlo;
+  }
+
+  void MarkSession1Deleted() { session1_ = nullptr; }
+
+  void VerifyVersionSupported(ParsedQuicVersion version) {
+    QuicConnectionId connection_id = TestConnectionId(++connection_id_);
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+    EXPECT_CALL(*dispatcher_,
+                CreateQuicSession(connection_id, _, client_address,
+                                  Eq(ExpectedAlpnForVersion(version)), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, connection_id, client_address,
+            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(
+            Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
+              ValidatePacket(connection_id, packet);
+            })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(connection_id)));
+    ProcessFirstFlight(version, client_address, connection_id);
+  }
+
+  void VerifyVersionNotSupported(ParsedQuicVersion version) {
+    QuicConnectionId connection_id = TestConnectionId(++connection_id_);
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+    EXPECT_CALL(*dispatcher_,
+                CreateQuicSession(connection_id, _, client_address, _, _, _))
+        .Times(0);
+    ProcessFirstFlight(version, client_address, connection_id);
+  }
+
+  void TestTlsMultiPacketClientHello(bool add_reordering);
+
+  void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      const QuicConnectionId& server_connection_id,
+      const QuicConnectionId& client_connection_id);
+
+  TestAlarmFactory::TestAlarm* GetClearResetAddressesAlarm() {
+    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+        QuicDispatcherPeer::GetClearResetAddressesAlarm(dispatcher_.get()));
+  }
+
+  ParsedQuicVersion version_;
+  MockQuicConnectionHelper mock_helper_;
+  MockAlarmFactory mock_alarm_factory_;
+  QuicConfig config_;
+  QuicVersionManager version_manager_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicSocketAddress server_address_;
+  std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
+  MockTimeWaitListManager* time_wait_list_manager_;
+  TestQuicSpdyServerSession* session1_;
+  TestQuicSpdyServerSession* session2_;
+  std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
+  QuicBufferedPacketStore* store_;
+  uint64_t connection_id_;
+  absl::optional<std::string> address_token_;
+};
+
+class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
+class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
+                         QuicDispatcherTestAllVersions,
+                         ::testing::ValuesIn(CurrentSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
+                         QuicDispatcherTestOneVersion,
+                         ::testing::Values(CurrentSupportedVersions().front()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
+  if (version_.UsesQuicCrypto()) {
+    return;
+  }
+  SetAddressToken("hsdifghdsaifnasdpfjdsk");
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(TestConnectionId(1), _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+}
+
+void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
+    bool add_reordering) {
+  if (!version_.UsesTls()) {
+    return;
+  }
+  SetAddressToken("857293462398");
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId server_connection_id = TestConnectionId();
+  QuicConfig client_config = DefaultQuicConfig();
+  // Add a 2000-byte custom parameter to increase the length of the CHLO.
+  constexpr auto kCustomParameterId =
+      static_cast<TransportParameters::TransportParameterId>(0xff33);
+  std::string kCustomParameterValue(2000, '-');
+  client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
+      kCustomParameterValue;
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_, client_config, server_connection_id,
+                              EmptyQuicConnectionId(),
+                              TestClientCryptoConfig());
+  ASSERT_EQ(packets.size(), 2u);
+  if (add_reordering) {
+    std::swap(packets[0], packets[1]);
+  }
+
+  // Processing the first packet should not create a new session.
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
+  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
+                        server_connection_id);
+
+  EXPECT_EQ(dispatcher_->NumSessions(), 0u)
+      << "No session should be created before the rest of the CHLO arrives.";
+
+  // Processing the second packet should create the new session.
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(server_connection_id, _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, server_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2);
+
+  ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
+                        server_connection_id);
+  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
+  TestTlsMultiPacketClientHello(/*add_reordering=*/false);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
+  TestTlsMultiPacketClientHello(/*add_reordering=*/true);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
+  if (!version_.HasLongHeaderLengths()) {
+    // Decapsulating Legacy Version Encapsulation packets from these versions
+    // is not currently supported in QuicDispatcher.
+    return;
+  }
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId server_connection_id = TestConnectionId();
+  QuicConfig client_config = DefaultQuicConfig();
+  client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_, client_config, server_connection_id);
+  ASSERT_EQ(packets.size(), 1u);
+
+  // Validate that Legacy Version Encapsulation is actually being used by
+  // checking the version of the packet before processing it.
+  PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
+  QuicLongHeaderType long_packet_type;
+  bool version_present;
+  bool has_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+  QuicConnectionId destination_connection_id, source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
+      kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+  EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
+  EXPECT_TRUE(version_present);
+  EXPECT_FALSE(has_length_prefix);
+  EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
+  EXPECT_EQ(destination_connection_id, server_connection_id);
+  EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_TRUE(detailed_error.empty());
+
+  // Processing the packet should create a new session.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(server_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, server_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2);
+
+  ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
+                        server_connection_id);
+  EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+
+  // Processing the same packet a second time should also be routed by the
+  // dispatcher to the right connection (we expect ProcessUdpPacket to be
+  // called twice, see the EXPECT_CALL above).
+  ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
+                        server_connection_id);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(TestConnectionId(1), _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  EXPECT_CALL(
+      *dispatcher_,
+      CreateQuicSession(TestConnectionId(2), _, client_address,
+                        Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(2), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(2), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
+  ProcessFirstFlight(client_address, TestConnectionId(2));
+
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(1)
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessPacket(client_address, TestConnectionId(1), false, "data");
+}
+
+// Regression test of b/93325907.
+TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  // Verify both packets 1 and 2 are processed by connection 1.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2)
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+            ValidatePacket(TestConnectionId(1), packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+  // Packet number 256 with packet number length 1 would be considered as 0 in
+  // dispatcher.
+  ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
+                CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
+      .Times(1);
+  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
+                     TestConnectionId(1));
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       StatelessVersionNegotiationWithVeryLongConnectionId) {
+  QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
+      .Times(1);
+  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
+                     connection_id);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       StatelessVersionNegotiationWithClientConnectionId) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(
+                  TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
+      .Times(1);
+  ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
+                     TestConnectionId(1), TestConnectionId(2));
+}
+
+TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
+      .Times(0);
+  std::string chlo = SerializeCHLO() + std::string(1200, 'a');
+  // Truncate to 1100 bytes of payload which results in a packet just
+  // under 1200 bytes after framing, packet, and encryption overhead.
+  QUICHE_DCHECK_LE(1200u, chlo.length());
+  std::string truncated_chlo = chlo.substr(0, 1100);
+  QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
+  ProcessPacket(client_address, TestConnectionId(1), true,
+                QuicVersionReservedForNegotiation(), truncated_chlo, false,
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
+}
+
+// Disabling CHLO size validation allows the dispatcher to send version
+// negotiation packets in response to a CHLO that is otherwise too small.
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationWithoutChloSizeValidation) {
+  crypto_config_.set_validate_chlo_size(false);
+
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
+      .Times(1);
+  std::string chlo = SerializeCHLO() + std::string(1200, 'a');
+  // Truncate to 1100 bytes of payload which results in a packet just
+  // under 1200 bytes after framing, packet, and encryption overhead.
+  QUICHE_DCHECK_LE(1200u, chlo.length());
+  std::string truncated_chlo = chlo.substr(0, 1100);
+  QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
+  ProcessPacket(client_address, TestConnectionId(1), true,
+                QuicVersionReservedForNegotiation(), truncated_chlo, true,
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
+  CreateTimeWaitListManager();
+
+  // Create a new session.
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, _, client_address,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, connection_id);
+
+  // Now close the connection, which should add it to the time wait list.
+  session1_->connection()->CloseConnection(
+      QUIC_INVALID_VERSION,
+      "Server: Packet 2 without version flag before version negotiated.",
+      ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
+
+  // Dispatcher forwards subsequent packets for this connection_id to the time
+  // wait list manager.
+  EXPECT_CALL(*time_wait_list_manager_,
+              ProcessPacket(_, _, connection_id, _, _, _))
+      .Times(1);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, connection_id, true, "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  // Dispatcher forwards all packets for this connection_id to the time wait
+  // list manager.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              ProcessPacket(_, _, connection_id, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(1);
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+
+  uint8_t short_packet[21] = {0x70, 0xa7, 0x02, 0x6b};
+  QuicReceivedPacket packet(reinterpret_cast<char*>(short_packet), 21,
+                            QuicTime::Zero());
+  uint8_t valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
+  QuicReceivedPacket packet2(reinterpret_cast<char*>(valid_size_packet), 23,
+                             QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  // Verify small packet is silently dropped.
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(0);
+  dispatcher_->ProcessPacket(server_address_, client_address, packet);
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, packet2);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, DropPacketWithInvalidFlags) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t all_zero_packet[1200] = {};
+  QuicReceivedPacket packet(reinterpret_cast<char*>(all_zero_packet),
+                            sizeof(all_zero_packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(0);
+  dispatcher_->ProcessPacket(server_address_, client_address, packet);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, LimitResetsToSameClientAddress) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
+  QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    // Verify only one reset is sent to the address, although multiple packets
+    // are received.
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(1);
+  } else {
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(3);
+  }
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data2");
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data3");
+
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(2);
+  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       StopSendingResetOnTooManyRecentAddresses) {
+  SetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses, 2);
+  const size_t kTestLifeTimeMs = 10;
+  SetQuicFlag(FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms,
+              kTestLifeTimeMs);
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
+  QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+
+  EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+      .Times(2);
+  EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+  const QuicTime expected_deadline =
+      mock_helper_.GetClock()->Now() +
+      QuicTime::Delta::FromMilliseconds(kTestLifeTimeMs);
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
+    EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
+  } else {
+    EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
+  }
+  // Received no version packet 2 after 5ms.
+  mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
+                "data");
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
+    // Verify deadline does not change.
+    EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
+  } else {
+    EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
+  }
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    // Verify reset gets throttled since there are too many recent addresses.
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(0);
+  } else {
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(1);
+  }
+  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
+                "data");
+
+  mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
+    GetClearResetAddressesAlarm()->Fire();
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(2);
+  } else {
+    EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+        .Times(3);
+  }
+  ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
+                "data");
+  ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
+                "data");
+}
+
+// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
+TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    // When variable length connection IDs are not supported, the connection
+    // fails. See StrayPacketTruncatedConnectionId.
+    return;
+  }
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
+  QuicConnectionId fixed_connection_id =
+      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(fixed_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, fixed_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
+            ValidatePacket(bad_connection_id, packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
+  ProcessFirstFlight(client_address, bad_connection_id);
+}
+
+// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
+TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    // When variable length connection IDs are not supported, the connection
+    // fails. See StrayPacketTruncatedConnectionId.
+    return;
+  }
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId fixed_connection_id =
+      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
+
+  // Disable validation of invalid short connection IDs.
+  dispatcher_->SetAllowShortInitialServerConnectionIds(true);
+  // Note that StrayPacketTruncatedConnectionId covers the case where the
+  // validation is still enabled.
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(fixed_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, fixed_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
+            ValidatePacket(bad_connection_id, packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
+  ProcessFirstFlight(client_address, bad_connection_id);
+}
+
+// Makes sure TestConnectionId(1) creates a new connection and
+// TestConnectionIdNineBytesLong(2) gets replaced.
+TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
+  QuicConnectionId fixed_connection_id =
+      QuicUtils::CreateReplacementConnectionId(bad_connection_id);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(fixed_connection_id, _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, fixed_connection_id, client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
+            ValidatePacket(bad_connection_id, packet);
+          })));
+  EXPECT_CALL(*dispatcher_,
+              ShouldCreateOrBufferPacketForConnection(
+                  ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
+  ProcessFirstFlight(client_address, bad_connection_id);
+
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(1)
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessPacket(client_address, TestConnectionId(1), false, "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
+
+  // dispatcher_ should drop this packet.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
+                                              client_address, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithBlockedPort) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 17);
+
+  // dispatcher_ should drop this packet.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
+                                              client_address, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
+                "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithNonBlockedPort) {
+  CreateTimeWaitListManager();
+
+  // Port 443 must not be blocked because it might be useful for proxies to send
+  // proxied traffic with source port 443 as that allows building a full QUIC
+  // proxy using a single UDP socket.
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 443);
+
+  // dispatcher_ should not drop this packet.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       DropPacketWithKnownVersionAndInvalidShortInitialConnectionId) {
+  if (!version_.AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  // dispatcher_ should drop this packet.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessFirstFlight(client_address, EmptyQuicConnectionId());
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+       DropPacketWithKnownVersionAndInvalidInitialConnectionId) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress server_address;
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  // dispatcher_ should drop this packet with invalid connection ID.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  absl::string_view cid_str = "123456789abcdefg123456789abcdefg";
+  QuicConnectionId invalid_connection_id(cid_str.data(), cid_str.length());
+  QuicReceivedPacket packet("packet", 6, QuicTime::Zero());
+  ReceivedPacketInfo packet_info(server_address, client_address, packet);
+  packet_info.version_flag = true;
+  packet_info.version = version_;
+  packet_info.destination_connection_id = invalid_connection_id;
+
+  ASSERT_TRUE(dispatcher_->MaybeDispatchPacket(packet_info));
+}
+
+void QuicDispatcherTestBase::
+    TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+        const QuicConnectionId& server_connection_id,
+        const QuicConnectionId& client_connection_id) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(
+                  server_connection_id, client_connection_id,
+                  /*ietf_quic=*/true,
+                  /*use_length_prefix=*/true, _, _, client_address, _))
+      .Times(1);
+  ProcessFirstFlight(ParsedQuicVersion::ReservedForNegotiation(),
+                     client_address, server_connection_id,
+                     client_connection_id);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId) {
+  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      EmptyQuicConnectionId(), EmptyQuicConnectionId());
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2) {
+  char server_connection_id_bytes[3] = {1, 2, 3};
+  QuicConnectionId server_connection_id(server_connection_id_bytes,
+                                        sizeof(server_connection_id_bytes));
+  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      server_connection_id, EmptyQuicConnectionId());
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3) {
+  char client_connection_id_bytes[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+  QuicConnectionId client_connection_id(client_connection_id_bytes,
+                                        sizeof(client_connection_id_bytes));
+  TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
+      EmptyQuicConnectionId(), client_connection_id);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
+  VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
+  for (ParsedQuicVersion version : CurrentSupportedVersions()) {
+    VerifyVersionSupported(version);
+    QuicDisableVersion(version);
+    VerifyVersionNotSupported(version);
+    QuicEnableVersion(version);
+    VerifyVersionSupported(version);
+  }
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionDraft28WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 0xFF, 0x00, 0x00, 28, /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionDraft27WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 0xFF, 0x00, 0x00, 27, /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionDraft25WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 0xFF, 0x00, 0x00, 25, /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionT050WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'T', '0', '5', '0', /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ049WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '9', /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ048WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ047WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ045WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     ABSL_ARRAYSIZE(packet), QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionQ044WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet44[kMinPacketSizeForVersionNegotiation] = {
+      0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
+  QuicReceivedPacket received_packet44(reinterpret_cast<char*>(packet44),
+                                       kMinPacketSizeForVersionNegotiation,
+                                       QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/false, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address,
+                             received_packet44);
+}
+
+TEST_P(QuicDispatcherTestOneVersion,
+       RejectDeprecatedVersionT051WithVersionNegotiation) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
+      0xFF, 'T', '0', '5', '1', /*destination connection ID length*/ 0x08};
+  QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
+                                     kMinPacketSizeForVersionNegotiation,
+                                     QuicTime::Zero());
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(
+      *time_wait_list_manager_,
+      SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
+                                   /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
+}
+
+static_assert(quic::SupportedVersions().size() == 6u,
+              "Please add new RejectDeprecatedVersion tests above this assert "
+              "when deprecating versions");
+
+TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  CreateTimeWaitListManager();
+  char packet[1200];
+  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                            0x6c, 0x7a, 0x20, 0x21};
+  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), destination_connection_id_bytes,
+      sizeof(destination_connection_id_bytes)));
+  QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  QuicConnectionId client_connection_id = EmptyQuicConnectionId();
+  QuicConnectionId server_connection_id(
+      destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
+  EXPECT_CALL(*time_wait_list_manager_,
+              SendVersionNegotiationPacket(
+                  server_connection_id, client_connection_id,
+                  /*ietf_quic=*/true, /*use_length_prefix=*/true, _, _, _, _))
+      .Times(1);
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+}
+
+// Testing packet writer that saves all packets instead of sending them.
+// Useful for tests that need access to sent packets.
+class SavingWriter : public QuicPacketWriterWrapper {
+ public:
+  bool IsWriteBlocked() const override { return false; }
+
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& /*self_client_address*/,
+                          const QuicSocketAddress& /*peer_client_address*/,
+                          PerPacketOptions* /*options*/) override {
+    packets_.push_back(
+        QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
+    return &packets_;
+  }
+
+ private:
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
+};
+
+TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
+  SavingWriter* saving_writer = new SavingWriter();
+  // dispatcher_ takes ownership of saving_writer.
+  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
+
+  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
+      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
+      &mock_alarm_factory_);
+  // dispatcher_ takes ownership of time_wait_list_manager.
+  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                             time_wait_list_manager);
+  char packet[1200] = {};
+  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                            0x6c, 0x7a, 0x20, 0x21};
+  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), destination_connection_id_bytes,
+      sizeof(destination_connection_id_bytes)));
+  QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+  ASSERT_EQ(1u, saving_writer->packets()->size());
+
+  char source_connection_id_bytes[255] = {};
+  uint8_t source_connection_id_length = sizeof(source_connection_id_bytes);
+  std::string detailed_error = "foobar";
+  EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
+      (*(saving_writer->packets()))[0]->data(),
+      (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ("", detailed_error);
+
+  // The source connection ID of the probe response should match the
+  // destination connection ID of the probe request.
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed probe", source_connection_id_bytes, source_connection_id_length,
+      destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
+}
+
+TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
+  // WARNING: do not remove or modify this test without making sure that we
+  // still have adequate coverage for the Android conformance test.
+  SavingWriter* saving_writer = new SavingWriter();
+  // dispatcher_ takes ownership of saving_writer.
+  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
+
+  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
+      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
+      &mock_alarm_factory_);
+  // dispatcher_ takes ownership of time_wait_list_manager.
+  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                             time_wait_list_manager);
+  // clang-format off
+  static const unsigned char packet[1200] = {
+    // Android UDP network conformance test packet as it was after this change:
+    // https://android-review.googlesource.com/c/platform/cts/+/1454515
+    0xc0,  // long header
+    0xaa, 0xda, 0xca, 0xca,  // reserved-space version number
+    0x08,  // destination connection ID length
+    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  // 8-byte connection ID
+    0x00,  // source connection ID length
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+  ASSERT_EQ(1u, saving_writer->packets()->size());
+
+  // The Android UDP network conformance test directly checks that these bytes
+  // of the response match the connection ID that was sent.
+  ASSERT_GE((*(saving_writer->packets()))[0]->length(), 15u);
+  quiche::test::CompareCharArraysWithHexError(
+      "response connection ID", &(*(saving_writer->packets()))[0]->data()[7], 8,
+      reinterpret_cast<const char*>(&packet[6]), 8);
+}
+
+TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) {
+  // WARNING: this test covers an old Android Conformance Test that has now been
+  // changed, but it'll take time for the change to propagate through the
+  // Android ecosystem. The Android team has asked us to keep this test
+  // supported until at least 2021-03-31. After that date, and when we drop
+  // support for sending QUIC version negotiation packets using the legacy
+  // Google QUIC format (Q001-Q043), then we can delete this test.
+  // TODO(dschinazi) delete this test after 2021-03-31
+  SavingWriter* saving_writer = new SavingWriter();
+  // dispatcher_ takes ownership of saving_writer.
+  QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
+
+  QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
+      saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
+      &mock_alarm_factory_);
+  // dispatcher_ takes ownership of time_wait_list_manager.
+  QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
+                                             time_wait_list_manager);
+  // clang-format off
+  static const unsigned char packet[1200] = {
+    // Android UDP network conformance test packet as it was after this change:
+    // https://android-review.googlesource.com/c/platform/cts/+/1104285
+    // but before this change:
+    // https://android-review.googlesource.com/c/platform/cts/+/1454515
+    0x0d,  // public flags: version, 8-byte connection ID, 1-byte packet number
+    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  // 8-byte connection ID
+    0xaa, 0xda, 0xca, 0xaa,  // reserved-space version number
+    0x01,  // 1-byte packet number
+    0x00,  // private flags
+    0x07,  // PING frame
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet), false);
+  std::unique_ptr<QuicReceivedPacket> received_packet(
+      ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
+  ASSERT_EQ(1u, saving_writer->packets()->size());
+
+  // The Android UDP network conformance test directly checks that bytes 1-9
+  // of the response match the connection ID that was sent.
+  static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
+                                             0x75, 0x76, 0x77, 0x78};
+  ASSERT_GE((*(saving_writer->packets()))[0]->length(),
+            1u + sizeof(connection_id_bytes));
+  quiche::test::CompareCharArraysWithHexError(
+      "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
+      sizeof(connection_id_bytes), connection_id_bytes,
+      sizeof(connection_id_bytes));
+}
+
+TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+  ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
+                version_, SerializeCHLO(), /*full_padding=*/false,
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
+  CreateTimeWaitListManager();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
+
+  // clang-format off
+  uint8_t coalesced_packet[1200] = {
+    // first coalesced packet
+      // public flags (long header with packet type INITIAL and
+      // 4-byte packet number)
+      0xC3,
+      // version
+      'Q', '0', '9', '9',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x05,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // Padding
+      0x00,
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xC3,
+      // version
+      'Q', '0', '9', '9',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+  };
+  // clang-format on
+  QuicReceivedPacket packet(reinterpret_cast<char*>(coalesced_packet), 1200,
+                            QuicTime::Zero());
+  dispatcher_->ProcessPacket(server_address_, client_address, packet);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+
+  dispatcher_->StopAcceptingNewConnections();
+  EXPECT_FALSE(dispatcher_->accept_new_connections());
+
+  // No more new connections afterwards.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(2), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .Times(0u);
+  ProcessFirstFlight(client_address, TestConnectionId(2));
+
+  // Existing connections should be able to continue.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(1u)
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessPacket(client_address, TestConnectionId(1), false, "data");
+}
+
+TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
+  dispatcher_->StopAcceptingNewConnections();
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+  // No more new connections afterwards.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(2), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .Times(0u);
+  ProcessFirstFlight(client_address, TestConnectionId(2));
+
+  dispatcher_->StartAcceptingNewConnections();
+  EXPECT_TRUE(dispatcher_->accept_new_connections());
+
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(1), _, client_address,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, TestConnectionId(1), client_address,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+        ValidatePacket(TestConnectionId(1), packet);
+      })));
+  ProcessFirstFlight(client_address, TestConnectionId(1));
+}
+
+TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
+  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
+  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
+  EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
+  // Q033 is no longer supported but Q050 is.
+  QuicEnableVersion(ParsedQuicVersion::Q050());
+  EXPECT_EQ(
+      QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
+      "h3-Q050");
+}
+
+// Verify the stopgap test: Packets with truncated connection IDs should be
+// dropped.
+class QuicDispatcherTestStrayPacketConnectionId
+    : public QuicDispatcherTestBase {};
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
+                         QuicDispatcherTestStrayPacketConnectionId,
+                         ::testing::ValuesIn(CurrentSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+// Packets with truncated connection IDs should be dropped.
+TEST_P(QuicDispatcherTestStrayPacketConnectionId,
+       StrayPacketTruncatedConnectionId) {
+  CreateTimeWaitListManager();
+
+  QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+  QuicConnectionId connection_id = TestConnectionId(1);
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
+      .Times(0);
+
+  ProcessPacket(client_address, connection_id, true, "data",
+                CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
+}
+
+class BlockingWriter : public QuicPacketWriterWrapper {
+ public:
+  BlockingWriter() : write_blocked_(false) {}
+
+  bool IsWriteBlocked() const override { return write_blocked_; }
+  void SetWritable() override { write_blocked_ = false; }
+
+  WriteResult WritePacket(const char* /*buffer*/, size_t /*buf_len*/,
+                          const QuicIpAddress& /*self_client_address*/,
+                          const QuicSocketAddress& /*peer_client_address*/,
+                          PerPacketOptions* /*options*/) override {
+    // It would be quite possible to actually implement this method here with
+    // the fake blocked status, but it would be significantly more work in
+    // Chromium, and since it's not called anyway, don't bother.
+    QUIC_LOG(DFATAL) << "Not supported";
+    return WriteResult();
+  }
+
+  bool write_blocked_;
+};
+
+class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
+ public:
+  void SetUp() override {
+    QuicDispatcherTestBase::SetUp();
+    writer_ = new BlockingWriter;
+    QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
+
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(1), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(1), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+    ProcessFirstFlight(client_address, TestConnectionId(1));
+
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(2), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(2), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
+    ProcessFirstFlight(client_address, TestConnectionId(2));
+
+    blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
+  }
+
+  void TearDown() override {
+    if (connection1() != nullptr) {
+      EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+    }
+
+    if (connection2() != nullptr) {
+      EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+    }
+    dispatcher_->Shutdown();
+  }
+
+  // Set the dispatcher's writer to be blocked. By default, all connections use
+  // the same writer as the dispatcher in this test.
+  void SetBlocked() {
+    QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
+    writer_->write_blocked_ = true;
+  }
+
+  // Simulate what happens when connection1 gets blocked when writing.
+  void BlockConnection1() {
+    Connection1Writer()->write_blocked_ = true;
+    dispatcher_->OnWriteBlocked(connection1());
+  }
+
+  BlockingWriter* Connection1Writer() {
+    return static_cast<BlockingWriter*>(connection1()->writer());
+  }
+
+  // Simulate what happens when connection2 gets blocked when writing.
+  void BlockConnection2() {
+    Connection2Writer()->write_blocked_ = true;
+    dispatcher_->OnWriteBlocked(connection2());
+  }
+
+  BlockingWriter* Connection2Writer() {
+    return static_cast<BlockingWriter*>(connection2()->writer());
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  BlockingWriter* writer_;
+  QuicDispatcher::WriteBlockedList* blocked_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
+                         QuicDispatcherWriteBlockedListTest,
+                         ::testing::Values(CurrentSupportedVersions().front()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
+  // No OnCanWrite calls because no connections are blocked.
+  dispatcher_->OnCanWrite();
+
+  // Register connection 1 for events, and make sure it's notified.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // It should get only one notification.
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
+  // Make sure we handle events in order.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // Check the other ordering.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection2());
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
+  // Add and remove one connction.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  blocked_list_->erase(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+
+  // Add and remove one connction and make sure it doesn't affect others.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  blocked_list_->erase(connection1());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // Add it, remove it, and add it back and make sure things are OK.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  blocked_list_->erase(connection1());
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
+  dispatcher_->OnCanWrite();
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
+  // Make sure a double add does not necessitate a double remove.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection1());
+  blocked_list_->erase(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+
+  // Make sure a double add does not result in two OnCanWrite calls.
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection1());
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
+  dispatcher_->OnCanWrite();
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
+  // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
+  // into the write blocked list.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+
+  // connection1 should be still in the write blocked list.
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  // Now call OnCanWrite again, connection1 should get its second chance.
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
+  // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
+  // into the write blocked list.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
+  dispatcher_->OnCanWrite();
+
+  // connection2 should be still in the write blocked list.
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  // Now call OnCanWrite again, connection2 should get its second chance.
+  EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest,
+       OnCanWriteHandleBlockBothConnections) {
+  // Both connections get blocked in OnCanWrite, and added back into the write
+  // blocked list.
+  InSequence s;
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  dispatcher_->OnWriteBlocked(connection2());
+  EXPECT_CALL(*connection1(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
+  EXPECT_CALL(*connection2(), OnCanWrite())
+      .WillOnce(
+          Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
+  dispatcher_->OnCanWrite();
+
+  // Both connections should be still in the write blocked list.
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  // Now call OnCanWrite again, both connections should get its second chance.
+  EXPECT_CALL(*connection1(), OnCanWrite());
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
+  // By default, all connections share the same packet writer with the
+  // dispatcher.
+  EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
+  EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
+
+  // Test the case where connection1 shares the same packet writer as the
+  // dispatcher, whereas connection2 owns it's packet writer.
+  // Change connection2's writer.
+  connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
+  EXPECT_NE(dispatcher_->writer(), connection2()->writer());
+
+  BlockConnection2();
+  EXPECT_TRUE(dispatcher_->HasPendingWrites());
+
+  EXPECT_CALL(*connection2(), OnCanWrite());
+  dispatcher_->OnCanWrite();
+  EXPECT_FALSE(dispatcher_->HasPendingWrites());
+}
+
+TEST_P(QuicDispatcherWriteBlockedListTest,
+       RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
+  dispatcher_->OnConnectionClosed(connection1()->connection_id(),
+                                  QUIC_PACKET_WRITE_ERROR, "Closed by test.",
+                                  ConnectionCloseSource::FROM_SELF);
+
+  SetBlocked();
+
+  ASSERT_FALSE(dispatcher_->HasPendingWrites());
+  SetBlocked();
+  dispatcher_->OnWriteBlocked(connection1());
+  ASSERT_TRUE(dispatcher_->HasPendingWrites());
+
+  EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
+                  "QuicConnection was in WriteBlockedList before destruction");
+  MarkSession1Deleted();
+}
+
+class QuicDispatcherSupportMultipleConnectionIdPerConnectionTest
+    : public QuicDispatcherTestBase {
+ public:
+  QuicDispatcherSupportMultipleConnectionIdPerConnectionTest()
+      : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {
+    dispatcher_ = std::make_unique<NiceMock<TestDispatcher>>(
+        &config_, &crypto_config_, &version_manager_,
+        mock_helper_.GetRandomGenerator());
+  }
+  void AddConnection1() {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(1), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(1), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
+    ProcessFirstFlight(client_address, TestConnectionId(1));
+  }
+
+  void AddConnection2() {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 2);
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(2), client_address,
+            &helper_, &alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
+          ValidatePacket(TestConnectionId(2), packet);
+        })));
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
+    ProcessFirstFlight(client_address, TestConnectionId(2));
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    QuicDispatcherSupportMultipleConnectionIdPerConnectionTests,
+    QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+    ::testing::Values(CurrentSupportedVersions().front()),
+    ::testing::PrintToStringParamName());
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       OnNewConnectionIdSent) {
+  AddConnection1();
+  ASSERT_EQ(dispatcher_->NumSessions(), 1u);
+  ASSERT_THAT(session1_, testing::NotNull());
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+
+  {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
+    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+    auto* session =
+        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(3));
+    ASSERT_EQ(session, session1_);
+  }
+
+  {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
+    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+    auto* session =
+        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(4));
+    ASSERT_EQ(session, session1_);
+  }
+
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  // Would timed out unless all sessions have been removed from the session map.
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       RetireConnectionIdFromSingleConnection) {
+  AddConnection1();
+  ASSERT_EQ(dispatcher_->NumSessions(), 1u);
+  ASSERT_THAT(session1_, testing::NotNull());
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+
+  // Adds 1 new connection id every turn and retires 2 connection ids every
+  // other turn.
+  for (int i = 2; i < 10; ++i) {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(i));
+    ASSERT_EQ(
+        QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(i)),
+        session1_);
+    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
+                                              TestConnectionId(i - 1)),
+              session1_);
+    EXPECT_EQ(dispatcher_->NumSessions(), 1u);
+    if (i % 2 == 1) {
+      mock_server_connection1->RetireConnectionId(TestConnectionId(i - 2));
+      mock_server_connection1->RetireConnectionId(TestConnectionId(i - 1));
+    }
+  }
+
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  // Would timed out unless all sessions have been removed from the session map.
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       RetireConnectionIdFromMultipleConnections) {
+  AddConnection1();
+  AddConnection2();
+  ASSERT_EQ(dispatcher_->NumSessions(), 2u);
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+  MockServerConnection* mock_server_connection2 =
+      reinterpret_cast<MockServerConnection*>(connection2());
+
+  for (int i = 2; i < 10; ++i) {
+    mock_server_connection1->AddNewConnectionId(TestConnectionId(2 * i - 1));
+    mock_server_connection2->AddNewConnectionId(TestConnectionId(2 * i));
+    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
+                                              TestConnectionId(2 * i - 1)),
+              session1_);
+    ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
+                                              TestConnectionId(2 * i)),
+              session2_);
+    EXPECT_EQ(dispatcher_->NumSessions(), 2u);
+    mock_server_connection1->RetireConnectionId(TestConnectionId(2 * i - 3));
+    mock_server_connection2->RetireConnectionId(TestConnectionId(2 * i - 2));
+  }
+
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(19));
+  mock_server_connection2->AddNewConnectionId(TestConnectionId(20));
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  // Would timed out unless all sessions have been removed from the session map.
+  dispatcher_->Shutdown();
+}
+
+TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
+       TimeWaitListPoplulateCorrectly) {
+  QuicTimeWaitListManager* time_wait_list_manager =
+      QuicDispatcherPeer::GetTimeWaitListManager(dispatcher_.get());
+  AddConnection1();
+  MockServerConnection* mock_server_connection1 =
+      reinterpret_cast<MockServerConnection*>(connection1());
+
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(2));
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
+  mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
+  mock_server_connection1->RetireConnectionId(TestConnectionId(1));
+  mock_server_connection1->RetireConnectionId(TestConnectionId(2));
+
+  EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
+  connection1()->CloseConnection(
+      QUIC_PEER_GOING_AWAY, "Close for testing",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+  EXPECT_FALSE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(1)));
+  EXPECT_FALSE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(2)));
+  EXPECT_TRUE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(3)));
+  EXPECT_TRUE(
+      time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(4)));
+
+  dispatcher_->Shutdown();
+}
+
+class BufferedPacketStoreTest : public QuicDispatcherTestBase {
+ public:
+  BufferedPacketStoreTest()
+      : QuicDispatcherTestBase(),
+        client_addr_(QuicIpAddress::Loopback4(), 1234) {}
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
+                                               server_connection_id);
+  }
+
+  void ProcessFirstFlight(const QuicSocketAddress& peer_address,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version_, peer_address, server_connection_id);
+  }
+
+  void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(client_addr_, server_connection_id);
+  }
+
+  void ProcessFirstFlight(const ParsedQuicVersion& version,
+                          const QuicConnectionId& server_connection_id) {
+    ProcessFirstFlight(version, client_addr_, server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
+        version, peer_address, server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const QuicSocketAddress& peer_address,
+      const QuicConnectionId& server_connection_id) {
+    ProcessUndecryptableEarlyPacket(version_, peer_address,
+                                    server_connection_id);
+  }
+
+  void ProcessUndecryptableEarlyPacket(
+      const QuicConnectionId& server_connection_id) {
+    ProcessUndecryptableEarlyPacket(version_, client_addr_,
+                                    server_connection_id);
+  }
+
+ protected:
+  QuicSocketAddress client_addr_;
+};
+
+INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests, BufferedPacketStoreTest,
+                         ::testing::ValuesIn(CurrentSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
+  InSequence s;
+  QuicConnectionId conn_id = TestConnectionId(1);
+  // Non-CHLO should be buffered upon arrival, and should trigger
+  // ShouldCreateOrBufferPacketForConnection().
+  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
+                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
+  // Process non-CHLO packet.
+  ProcessUndecryptableEarlyPacket(conn_id);
+  EXPECT_EQ(0u, dispatcher_->NumSessions())
+      << "No session should be created before CHLO arrives.";
+
+  // When CHLO arrives, a new session should be created, and all packets
+  // buffered should be delivered to the session.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(conn_id, _, client_addr_, Eq(ExpectedAlpn()), _,
+                                Eq(ParsedClientHelloForTest())))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(2)  // non-CHLO + CHLO.
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(conn_id, packet);
+            }
+          })));
+  ProcessFirstFlight(conn_id);
+}
+
+TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
+  InSequence s;
+  QuicConnectionId conn_id = TestConnectionId(1);
+  // A bunch of non-CHLO should be buffered upon arrival, and the first one
+  // should trigger ShouldCreateOrBufferPacketForConnection().
+  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
+                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
+  for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
+    ProcessUndecryptableEarlyPacket(conn_id);
+  }
+  EXPECT_EQ(0u, dispatcher_->NumSessions())
+      << "No session should be created before CHLO arrives.";
+
+  // Pop out the last packet as it is also be dropped by the store.
+  data_connection_map_[conn_id].pop_back();
+  // When CHLO arrives, a new session should be created, and all packets
+  // buffered should be delivered to the session.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+
+  // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
+  // should be delivered in arrival order.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(kDefaultMaxUndecryptablePackets + 1)  // + 1 for CHLO.
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(conn_id, packet);
+            }
+          })));
+  ProcessFirstFlight(conn_id);
+}
+
+TEST_P(BufferedPacketStoreTest,
+       ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
+  InSequence s;
+  // A bunch of non-CHLO should be buffered upon arrival.
+  size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
+  for (size_t i = 1; i <= kNumConnections; ++i) {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
+    QuicConnectionId conn_id = TestConnectionId(i);
+    EXPECT_CALL(*dispatcher_,
+                ShouldCreateOrBufferPacketForConnection(
+                    ReceivedPacketInfoConnectionIdEquals(conn_id)));
+    ProcessUndecryptableEarlyPacket(client_address, conn_id);
+  }
+
+  // Pop out the packet on last connection as it shouldn't be enqueued in store
+  // as well.
+  data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
+
+  // Reset session creation counter to ensure processing CHLO can always
+  // create session.
+  QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
+                                                              kNumConnections);
+  // Process CHLOs to create session for these connections.
+  for (size_t i = 1; i <= kNumConnections; ++i) {
+    QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
+    QuicConnectionId conn_id = TestConnectionId(i);
+    if (i == kNumConnections) {
+      EXPECT_CALL(*dispatcher_,
+                  ShouldCreateOrBufferPacketForConnection(
+                      ReceivedPacketInfoConnectionIdEquals(conn_id)));
+    }
+    EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_address,
+                                                Eq(ExpectedAlpn()), _, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
+            &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    // First |kNumConnections| - 1 connections should have buffered
+    // a packet in store. The rest should have been dropped.
+    size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, client_address, _))
+        .Times(num_packet_to_process)
+        .WillRepeatedly(WithArg<2>(
+            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+              if (version_.UsesQuicCrypto()) {
+                ValidatePacket(conn_id, packet);
+              }
+            })));
+
+    ProcessFirstFlight(client_address, conn_id);
+  }
+}
+
+// Tests that store delivers empty packet list if CHLO arrives firstly.
+TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
+  QuicConnectionId conn_id = TestConnectionId(1);
+  EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
+                                ReceivedPacketInfoConnectionIdEquals(conn_id)));
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, client_addr_, _));
+  ProcessFirstFlight(conn_id);
+}
+
+// Tests that a retransmitted CHLO arrives after a connection for the
+// CHLO has been created.
+TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
+  InSequence s;
+  QuicConnectionId conn_id = TestConnectionId(1);
+  ProcessUndecryptableEarlyPacket(conn_id);
+
+  // When CHLO arrives, a new session should be created, and all packets
+  // buffered should be delivered to the session.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .Times(1)  // Only triggered by 1st CHLO.
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+          &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(3)  // Triggered by 1 data packet and 2 CHLOs.
+      .WillRepeatedly(
+          WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(conn_id, packet);
+            }
+          })));
+
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+      GetFirstFlightOfPackets(version_, conn_id);
+  ASSERT_EQ(packets.size(), 1u);
+  // Receive the CHLO once.
+  ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
+  // Receive the CHLO a second time to simulate retransmission.
+  ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
+}
+
+// Tests that expiration of a connection add connection id to time wait list.
+TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
+  InSequence s;
+  CreateTimeWaitListManager();
+  QuicBufferedPacketStore* store =
+      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+  QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
+
+  QuicConnectionId conn_id = TestConnectionId(1);
+  ProcessPacket(client_addr_, conn_id, true, absl::StrCat("data packet ", 2),
+                CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
+                /*packet_number=*/2);
+
+  mock_helper_.AdvanceTime(
+      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
+  QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
+  // Cancel alarm as if it had been fired.
+  alarm->Cancel();
+  store->OnExpirationTimeout();
+  // New arrived CHLO will be dropped because this connection is in time wait
+  // list.
+  ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
+  EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _, _));
+  ProcessFirstFlight(conn_id);
+}
+
+TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
+  // Process more than (|kMaxNumSessionsToCreate| +
+  // |kDefaultMaxConnectionsInStore|) CHLOs,
+  // the first |kMaxNumSessionsToCreate| should create connections immediately,
+  // the next |kDefaultMaxConnectionsInStore| should be buffered,
+  // the rest should be dropped.
+  QuicBufferedPacketStore* store =
+      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+  const size_t kNumCHLOs =
+      kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
+  for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
+    EXPECT_CALL(
+        *dispatcher_,
+        ShouldCreateOrBufferPacketForConnection(
+            ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _,
+                                    Eq(ParsedClientHelloForTest())))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillOnce(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+    if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
+        conn_id > kMaxNumSessionsToCreate) {
+      EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
+    } else {
+      // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
+      // connections immediately, and the last CHLO should be dropped as the
+      // store is full.
+      EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
+    }
+  }
+
+  // Graduately consume buffered CHLOs. The buffered connections should be
+  // created but the dropped one shouldn't.
+  for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
+       conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
+       ++conn_id) {
+    EXPECT_CALL(*dispatcher_,
+                CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                  Eq(ExpectedAlpn()), _,
+                                  Eq(ParsedClientHelloForTest())))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
+            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillOnce(WithArg<2>(
+            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+              if (version_.UsesQuicCrypto()) {
+                ValidatePacket(TestConnectionId(conn_id), packet);
+              }
+            })));
+  }
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(TestConnectionId(kNumCHLOs), _, client_addr_,
+                                Eq(ExpectedAlpn()), _, _))
+      .Times(0);
+
+  while (store->HasChlosBuffered()) {
+    dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+  }
+
+  EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
+                             kDefaultMaxConnectionsInStore),
+            session1_->connection_id());
+}
+
+// Duplicated CHLO shouldn't be buffered.
+TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
+  for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
+       ++conn_id) {
+    // Last CHLO will be buffered. Others will create connection right away.
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillOnce(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+  }
+  // Retransmit CHLO on last connection should be dropped.
+  QuicConnectionId last_connection =
+      TestConnectionId(kMaxNumSessionsToCreate + 1);
+  ProcessFirstFlight(last_connection);
+
+  size_t packets_buffered = 2;
+
+  // Reset counter and process buffered CHLO.
+  EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, _, client_addr_,
+                                              Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, last_connection, client_addr_,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  // Only one packet(CHLO) should be process.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(packets_buffered)
+      .WillRepeatedly(WithArg<2>(
+          Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(last_connection, packet);
+            }
+          })));
+  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
+  uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
+  QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
+  for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
+    // Last CHLO will be buffered. Others will create connection right away.
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillRepeatedly(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+  }
+
+  // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
+  // last one should be dropped.
+  for (uint64_t packet_number = 2;
+       packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
+    ProcessPacket(client_addr_, last_connection_id, true, "data packet");
+  }
+
+  // Reset counter and process buffered CHLO.
+  EXPECT_CALL(*dispatcher_,
+              CreateQuicSession(last_connection_id, _, client_addr_,
+                                Eq(ExpectedAlpn()), _, _))
+      .WillOnce(Return(ByMove(CreateSession(
+          dispatcher_.get(), config_, last_connection_id, client_addr_,
+          &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+          QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+  // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
+  // should be process.
+  EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+              ProcessUdpPacket(_, _, _))
+      .Times(kDefaultMaxUndecryptablePackets + 1)
+      .WillRepeatedly(WithArg<2>(
+          Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
+            if (version_.UsesQuicCrypto()) {
+              ValidatePacket(last_connection_id, packet);
+            }
+          })));
+  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+// Tests that when dispatcher's packet buffer is full, a CHLO on connection
+// which doesn't have buffered CHLO should be buffered.
+TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
+  QuicBufferedPacketStore* store =
+      QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+
+  uint64_t conn_id = 1;
+  ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
+  // Fill packet buffer to full with CHLOs on other connections. Need to feed
+  // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
+  // session directly.
+  for (conn_id = 2;
+       conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
+       ++conn_id) {
+    if (conn_id <= kMaxNumSessionsToCreate + 1) {
+      EXPECT_CALL(*dispatcher_,
+                  CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                                    Eq(ExpectedAlpn()), _, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillOnce(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(TestConnectionId(conn_id));
+  }
+  EXPECT_FALSE(store->HasChloForConnection(
+      /*connection_id=*/TestConnectionId(1)));
+
+  // CHLO on connection 1 should still be buffered.
+  ProcessFirstFlight(TestConnectionId(1));
+  EXPECT_TRUE(store->HasChloForConnection(
+      /*connection_id=*/TestConnectionId(1)));
+}
+
+// Regression test for b/117874922.
+TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
+  // Ensure the preferred version is not supported by the server.
+  QuicDisableVersion(AllSupportedVersions().front());
+
+  uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
+  ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
+  for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
+    // Last 5 CHLOs will be buffered. Others will create connection right away.
+    ParsedQuicVersion version =
+        supported_versions[(conn_id - 1) % supported_versions.size()];
+    if (conn_id <= kMaxNumSessionsToCreate) {
+      EXPECT_CALL(
+          *dispatcher_,
+          CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                            Eq(ExpectedAlpnForVersion(version)), version, _))
+          .WillOnce(Return(ByMove(CreateSession(
+              dispatcher_.get(), config_, TestConnectionId(conn_id),
+              client_addr_, &mock_helper_, &mock_alarm_factory_,
+              &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+              &session1_))));
+      EXPECT_CALL(
+          *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+          ProcessUdpPacket(_, _, _))
+          .WillRepeatedly(WithArg<2>(
+              Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+                if (version_.UsesQuicCrypto()) {
+                  ValidatePacket(TestConnectionId(conn_id), packet);
+                }
+              })));
+    }
+    ProcessFirstFlight(version, TestConnectionId(conn_id));
+  }
+
+  // Process buffered CHLOs. Verify the version is correct.
+  for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
+       conn_id <= last_connection_id; ++conn_id) {
+    ParsedQuicVersion version =
+        supported_versions[(conn_id - 1) % supported_versions.size()];
+    EXPECT_CALL(
+        *dispatcher_,
+        CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
+                          Eq(ExpectedAlpnForVersion(version)), version, _))
+        .WillOnce(Return(ByMove(CreateSession(
+            dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
+            &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+            QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+    EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+                ProcessUdpPacket(_, _, _))
+        .WillRepeatedly(WithArg<2>(
+            Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
+              if (version_.UsesQuicCrypto()) {
+                ValidatePacket(TestConnectionId(conn_id), packet);
+              }
+            })));
+  }
+  dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_alarm_factory.cc b/quiche/quic/core/quic_epoll_alarm_factory.cc
new file mode 100644
index 0000000..23df28b
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_alarm_factory.cc
@@ -0,0 +1,89 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+
+#include <type_traits>
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+
+namespace quic {
+namespace {
+
+class QuicEpollAlarm : public QuicAlarm {
+ public:
+  QuicEpollAlarm(QuicEpollServer* epoll_server,
+                 QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+      : QuicAlarm(std::move(delegate)),
+        epoll_server_(epoll_server),
+        epoll_alarm_impl_(this) {}
+
+ protected:
+  void SetImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    epoll_server_->RegisterAlarm(
+        (deadline() - QuicTime::Zero()).ToMicroseconds(), &epoll_alarm_impl_);
+  }
+
+  void CancelImpl() override {
+    QUICHE_DCHECK(!deadline().IsInitialized());
+    epoll_alarm_impl_.UnregisterIfRegistered();
+  }
+
+  void UpdateImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    int64_t epoll_deadline = (deadline() - QuicTime::Zero()).ToMicroseconds();
+    if (epoll_alarm_impl_.registered()) {
+      epoll_alarm_impl_.ReregisterAlarm(epoll_deadline);
+    } else {
+      epoll_server_->RegisterAlarm(epoll_deadline, &epoll_alarm_impl_);
+    }
+  }
+
+ private:
+  class EpollAlarmImpl : public QuicEpollAlarmBase {
+   public:
+    using int64_epoll = decltype(QuicEpollAlarmBase().OnAlarm());
+
+    explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
+
+    // Use the same integer type as the base class.
+    int64_epoll OnAlarm() override {
+      QuicEpollAlarmBase::OnAlarm();
+      alarm_->Fire();
+      // Fire will take care of registering the alarm, if needed.
+      return 0;
+    }
+
+   private:
+    QuicEpollAlarm* alarm_;
+  };
+
+  QuicEpollServer* epoll_server_;
+  EpollAlarmImpl epoll_alarm_impl_;
+};
+
+}  // namespace
+
+QuicEpollAlarmFactory::QuicEpollAlarmFactory(QuicEpollServer* epoll_server)
+    : epoll_server_(epoll_server) {}
+
+QuicEpollAlarmFactory::~QuicEpollAlarmFactory() = default;
+
+QuicAlarm* QuicEpollAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
+  return new QuicEpollAlarm(epoll_server_,
+                            QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+}
+
+QuicArenaScopedPtr<QuicAlarm> QuicEpollAlarmFactory::CreateAlarm(
+    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+    QuicConnectionArena* arena) {
+  if (arena != nullptr) {
+    return arena->New<QuicEpollAlarm>(epoll_server_, std::move(delegate));
+  }
+  return QuicArenaScopedPtr<QuicAlarm>(
+      new QuicEpollAlarm(epoll_server_, std::move(delegate)));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_alarm_factory.h b/quiche/quic/core/quic_epoll_alarm_factory.h
new file mode 100644
index 0000000..8ccc923
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_alarm_factory.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+
+namespace quic {
+
+// Creates alarms that use the supplied EpollServer for timing and firing.
+class QUIC_EXPORT_PRIVATE QuicEpollAlarmFactory : public QuicAlarmFactory {
+ public:
+  explicit QuicEpollAlarmFactory(QuicEpollServer* epoll_server);
+  QuicEpollAlarmFactory(const QuicEpollAlarmFactory&) = delete;
+  QuicEpollAlarmFactory& operator=(const QuicEpollAlarmFactory&) = delete;
+  ~QuicEpollAlarmFactory() override;
+
+  // QuicAlarmFactory interface.
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override;
+
+ private:
+  QuicEpollServer* epoll_server_;  // Not owned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_ALARM_FACTORY_H_
diff --git a/quiche/quic/core/quic_epoll_alarm_factory_test.cc b/quiche/quic/core/quic_epoll_alarm_factory_test.cc
new file mode 100644
index 0000000..30fd188
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_alarm_factory_test.cc
@@ -0,0 +1,141 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/platform/api/quiche_epoll_test_tools.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestDelegate : public QuicAlarm::DelegateWithoutContext {
+ public:
+  TestDelegate() : fired_(false) {}
+
+  void OnAlarm() override { fired_ = true; }
+
+  bool fired() const { return fired_; }
+
+ private:
+  bool fired_;
+};
+
+// The boolean parameter denotes whether or not to use an arena.
+class QuicEpollAlarmFactoryTest : public QuicTestWithParam<bool> {
+ protected:
+  QuicEpollAlarmFactoryTest()
+      : clock_(&epoll_server_), alarm_factory_(&epoll_server_) {}
+
+  QuicConnectionArena* GetArenaParam() {
+    return GetParam() ? &arena_ : nullptr;
+  }
+
+  const QuicEpollClock clock_;
+  QuicEpollAlarmFactory alarm_factory_;
+  quiche::QuicheFakeEpollServer epoll_server_;
+  QuicConnectionArena arena_;
+};
+
+INSTANTIATE_TEST_SUITE_P(UseArena,
+                         QuicEpollAlarmFactoryTest,
+                         ::testing::ValuesIn({true, false}),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarm) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(start + delta);
+
+  epoll_server_.AdvanceByAndWaitForEventsAndExecuteCallbacks(
+      delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+}
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndCancel) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  TestDelegate* unowned_delegate = delegate.get();
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(start + delta);
+  alarm->Cancel();
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+  EXPECT_FALSE(unowned_delegate->fired());
+}
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndReset) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  TestDelegate* unowned_delegate = delegate.get();
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(clock_.Now() + delta);
+  alarm->Cancel();
+  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
+  alarm->Set(clock_.Now() + new_delta);
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+  EXPECT_FALSE(unowned_delegate->fired());
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(
+      (new_delta - delta).ToMicroseconds());
+  EXPECT_EQ(start + new_delta, clock_.Now());
+  EXPECT_TRUE(unowned_delegate->fired());
+}
+
+TEST_P(QuicEpollAlarmFactoryTest, CreateAlarmAndUpdate) {
+  QuicArenaScopedPtr<TestDelegate> delegate =
+      QuicArenaScopedPtr<TestDelegate>(new TestDelegate());
+  TestDelegate* unowned_delegate = delegate.get();
+  QuicArenaScopedPtr<QuicAlarm> alarm(
+      alarm_factory_.CreateAlarm(std::move(delegate), GetArenaParam()));
+
+  QuicTime start = clock_.Now();
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+  alarm->Set(clock_.Now() + delta);
+  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
+  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds());
+  EXPECT_EQ(start + delta, clock_.Now());
+  EXPECT_FALSE(unowned_delegate->fired());
+
+  // Move the alarm forward 1us and ensure it doesn't move forward.
+  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(2));
+
+  epoll_server_.AdvanceByExactlyAndCallCallbacks(
+      (new_delta - delta).ToMicroseconds());
+  EXPECT_EQ(start + new_delta, clock_.Now());
+  EXPECT_TRUE(unowned_delegate->fired());
+
+  // Set the alarm via an update call.
+  new_delta = QuicTime::Delta::FromMicroseconds(5);
+  alarm->Update(clock_.Now() + new_delta, QuicTime::Delta::FromMicroseconds(1));
+  EXPECT_TRUE(alarm->IsSet());
+
+  // Update it with an uninitialized time and ensure it's cancelled.
+  alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
+  EXPECT_FALSE(alarm->IsSet());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_clock.cc b/quiche/quic/core/quic_epoll_clock.cc
new file mode 100644
index 0000000..a4087a0
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_clock.cc
@@ -0,0 +1,46 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_epoll_clock.h"
+
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+
+namespace quic {
+
+QuicEpollClock::QuicEpollClock(QuicEpollServer* epoll_server)
+    : epoll_server_(epoll_server), largest_time_(QuicTime::Zero()) {}
+
+QuicEpollClock::~QuicEpollClock() {}
+
+QuicTime QuicEpollClock::ApproximateNow() const {
+  return CreateTimeFromMicroseconds(epoll_server_->ApproximateNowInUsec());
+}
+
+QuicTime QuicEpollClock::Now() const {
+  QuicTime now = CreateTimeFromMicroseconds(epoll_server_->NowInUsec());
+
+  if (now <= largest_time_) {
+    if (now < largest_time_) {
+      QUICHE_CODE_COUNT(quic_epoll_clock_step_backward);
+    }
+    // Time not increasing, return |largest_time_|.
+    return largest_time_;
+  }
+
+  largest_time_ = now;
+  return largest_time_;
+}
+
+QuicWallTime QuicEpollClock::WallNow() const {
+  return QuicWallTime::FromUNIXMicroseconds(
+      epoll_server_->ApproximateNowInUsec());
+}
+
+QuicTime QuicEpollClock::ConvertWallTimeToQuicTime(
+    const QuicWallTime& walltime) const {
+  return QuicTime::Zero() +
+         QuicTime::Delta::FromMicroseconds(walltime.ToUNIXMicroseconds());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_clock.h b/quiche/quic/core/quic_epoll_clock.h
new file mode 100644
index 0000000..42bea33
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_clock.h
@@ -0,0 +1,48 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
+
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Clock to efficiently retrieve an approximately accurate time from an
+// EpollServer.
+class QUIC_EXPORT_PRIVATE QuicEpollClock : public QuicClock {
+ public:
+  explicit QuicEpollClock(QuicEpollServer* epoll_server);
+  QuicEpollClock(const QuicEpollClock&) = delete;
+  QuicEpollClock& operator=(const QuicEpollClock&) = delete;
+  ~QuicEpollClock() override;
+
+  // Returns the approximate current time as a QuicTime object.
+  QuicTime ApproximateNow() const override;
+
+  // Returns the current time as a QuicTime object.
+  // Note: this use significant resources please use only if needed.
+  QuicTime Now() const override;
+
+  // WallNow returns the current wall-time - a time that is consistent across
+  // different clocks.
+  QuicWallTime WallNow() const override;
+
+  // Override to do less work in this implementation.  The epoll clock is
+  // already based on system (unix epoch) time, no conversion required.
+  QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const override;
+
+ protected:
+  QuicEpollServer* epoll_server_;
+  // Largest time returned from Now() so far.
+  mutable QuicTime largest_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
diff --git a/quiche/quic/core/quic_epoll_clock_test.cc b/quiche/quic/core/quic_epoll_clock_test.cc
new file mode 100644
index 0000000..e501fc4
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_clock_test.cc
@@ -0,0 +1,139 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_epoll_clock.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/platform/api/quiche_epoll_test_tools.h"
+
+namespace quic {
+namespace test {
+
+class QuicEpollClockTest : public QuicTest {};
+
+TEST_F(QuicEpollClockTest, ApproximateNowInUsec) {
+  quiche::QuicheFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(1000000);
+  EXPECT_EQ(1000000,
+            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
+  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(1000000u, clock.WallNow().ToUNIXMicroseconds());
+
+  epoll_server.AdvanceBy(5);
+  EXPECT_EQ(1000005,
+            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
+  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(1000005u, clock.WallNow().ToUNIXMicroseconds());
+
+  epoll_server.AdvanceBy(10 * 1000000);
+  EXPECT_EQ(11u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(11000005u, clock.WallNow().ToUNIXMicroseconds());
+}
+
+TEST_F(QuicEpollClockTest, NowInUsec) {
+  quiche::QuicheFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(1000000);
+  EXPECT_EQ(1000000, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
+
+  epoll_server.AdvanceBy(5);
+  EXPECT_EQ(1000005, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
+}
+
+TEST_F(QuicEpollClockTest, CalibrateRealEpollClock) {
+  QuicEpollServer epoll_server;
+
+  QuicEpollClock uncalibrated_clock(&epoll_server);
+  QuicEpollClock calibrated_clock(&epoll_server);
+  EXPECT_TRUE(calibrated_clock.ComputeCalibrationOffset().IsZero());
+
+  for (int i = 0; i < 100; ++i) {
+    QuicWallTime wallnow = uncalibrated_clock.WallNow();
+    EXPECT_EQ(uncalibrated_clock.ConvertWallTimeToQuicTime(wallnow),
+              calibrated_clock.ConvertWallTimeToQuicTime(wallnow));
+  }
+}
+
+// ClockWithOffset is a clock whose offset(WallNow() - Now() at any instant) is
+// given at construction time.
+class ClockWithOffset : public QuicEpollClock {
+ public:
+  ClockWithOffset(QuicEpollServer* epoll_server, QuicTime::Delta offset)
+      : QuicEpollClock(epoll_server), offset_(offset) {}
+
+  QuicTime Now() const override { return QuicEpollClock::Now() - offset_; }
+
+  // QuicEpollClock disables ConvertWallTimeToQuicTime since it always have a
+  // zero offset. We need to re-enable it here in order to test the calibration
+  // and conversion code in QuicClock.
+  QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const override {
+    return QuicClock::ConvertWallTimeToQuicTime(walltime);
+  }
+
+ private:
+  QuicTime::Delta offset_;
+};
+
+TEST_F(QuicEpollClockTest, CalibrateClockWithOffset) {
+  QuicEpollServer epoll_server;
+
+  for (const QuicTime::Delta& offset : {QuicTime::Delta::FromSeconds(5000),
+                                        QuicTime::Delta::FromSeconds(-8000)}) {
+    ClockWithOffset clock(&epoll_server, offset);
+    ASSERT_EQ(offset, clock.ComputeCalibrationOffset())
+        << "offset (us): " << offset.ToMicroseconds();
+    // Test fails without this.
+    clock.SetCalibrationOffset(offset);
+
+    QuicWallTime last_walltime = clock.WallNow();
+    QuicTime last_time = clock.ConvertWallTimeToQuicTime(last_walltime);
+
+    for (int i = 0; i < 1e5; ++i) {
+      QuicWallTime wallnow = clock.WallNow();
+      QuicTime now = clock.ConvertWallTimeToQuicTime(wallnow);
+
+      if (wallnow.IsAfter(last_walltime)) {
+        ASSERT_LT(0, (now - last_time).ToMicroseconds())
+            << "offset (us): " << offset.ToMicroseconds();
+
+        last_walltime = wallnow;
+        last_time = now;
+      }
+    }
+  }
+}
+
+TEST_F(QuicEpollClockTest, MonotonicityWithRealEpollClock) {
+  QuicEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  QuicTime last_now = clock.Now();
+  for (int i = 0; i < 1e5; ++i) {
+    QuicTime now = clock.Now();
+
+    ASSERT_LE(last_now, now);
+
+    last_now = now;
+  }
+}
+
+TEST_F(QuicEpollClockTest, MonotonicityWithFakeEpollClock) {
+  quiche::QuicheFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(100);
+  QuicTime last_now = clock.Now();
+
+  epoll_server.set_now_in_usec(90);
+  QuicTime now = clock.Now();
+
+  ASSERT_EQ(last_now, now);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_connection_helper.cc b/quiche/quic/core/quic_epoll_connection_helper.cc
new file mode 100644
index 0000000..0ccd2c1
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_connection_helper.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+
+#include <errno.h>
+#include <sys/socket.h>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+
+namespace quic {
+
+QuicEpollConnectionHelper::QuicEpollConnectionHelper(
+    QuicEpollServer* epoll_server, QuicAllocator allocator_type)
+    : clock_(epoll_server),
+      random_generator_(QuicRandom::GetInstance()),
+      allocator_type_(allocator_type) {}
+
+QuicEpollConnectionHelper::~QuicEpollConnectionHelper() = default;
+
+const QuicClock* QuicEpollConnectionHelper::GetClock() const {
+  return &clock_;
+}
+
+QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() {
+  return random_generator_;
+}
+
+quiche::QuicheBufferAllocator*
+QuicEpollConnectionHelper::GetStreamSendBufferAllocator() {
+  if (allocator_type_ == QuicAllocator::BUFFER_POOL) {
+    return &stream_buffer_allocator_;
+  } else {
+    QUICHE_DCHECK(allocator_type_ == QuicAllocator::SIMPLE);
+    return &simple_buffer_allocator_;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_epoll_connection_helper.h b/quiche/quic/core/quic_epoll_connection_helper.h
new file mode 100644
index 0000000..a424770
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_connection_helper.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The epoll-specific helper for QuicConnection which uses
+// EpollAlarm for alarms, and used an int fd_ for writing data.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
+
+#include <sys/types.h>
+
+#include <set>
+
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_default_packet_writer.h"
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_stream_buffer_allocator.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+class QuicRandom;
+
+enum class QuicAllocator { SIMPLE, BUFFER_POOL };
+
+class QUIC_EXPORT_PRIVATE QuicEpollConnectionHelper
+    : public QuicConnectionHelperInterface {
+ public:
+  QuicEpollConnectionHelper(QuicEpollServer* epoll_server,
+                            QuicAllocator allocator_type);
+  QuicEpollConnectionHelper(const QuicEpollConnectionHelper&) = delete;
+  QuicEpollConnectionHelper& operator=(const QuicEpollConnectionHelper&) =
+      delete;
+  ~QuicEpollConnectionHelper() override;
+
+  // QuicConnectionHelperInterface
+  const QuicClock* GetClock() const override;
+  QuicRandom* GetRandomGenerator() override;
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
+
+ private:
+  const QuicEpollClock clock_;
+  QuicRandom* random_generator_;
+  // Set up allocators.  They take up minimal memory before use.
+  // Allocator for stream send buffers.
+  QuicStreamBufferAllocator stream_buffer_allocator_;
+  quiche::SimpleBufferAllocator simple_buffer_allocator_;
+  QuicAllocator allocator_type_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CONNECTION_HELPER_H_
diff --git a/quiche/quic/core/quic_epoll_connection_helper_test.cc b/quiche/quic/core/quic_epoll_connection_helper_test.cc
new file mode 100644
index 0000000..4ce2f17
--- /dev/null
+++ b/quiche/quic/core/quic_epoll_connection_helper_test.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/platform/api/quiche_epoll_test_tools.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicEpollConnectionHelperTest : public QuicTest {
+ protected:
+  QuicEpollConnectionHelperTest()
+      : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL) {}
+
+  quiche::QuicheFakeEpollServer epoll_server_;
+  QuicEpollConnectionHelper helper_;
+};
+
+TEST_F(QuicEpollConnectionHelperTest, GetClock) {
+  const QuicClock* clock = helper_.GetClock();
+  QuicTime start = clock->Now();
+
+  QuicTime::Delta delta = QuicTime::Delta::FromMilliseconds(5);
+  epoll_server_.AdvanceBy(delta.ToMicroseconds());
+
+  EXPECT_EQ(start + delta, clock->Now());
+}
+
+TEST_F(QuicEpollConnectionHelperTest, GetRandomGenerator) {
+  QuicRandom* random = helper_.GetRandomGenerator();
+  EXPECT_EQ(QuicRandom::GetInstance(), random);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_error_codes.cc b/quiche/quic/core/quic_error_codes.cc
new file mode 100644
index 0000000..b6cdd7b
--- /dev/null
+++ b/quiche/quic/core/quic_error_codes.cc
@@ -0,0 +1,975 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_error_codes.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/strings/str_cat.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+const char* QuicRstStreamErrorCodeToString(QuicRstStreamErrorCode error) {
+  switch (error) {
+    RETURN_STRING_LITERAL(QUIC_STREAM_NO_ERROR);
+    RETURN_STRING_LITERAL(QUIC_ERROR_PROCESSING_STREAM);
+    RETURN_STRING_LITERAL(QUIC_MULTIPLE_TERMINATION_OFFSETS);
+    RETURN_STRING_LITERAL(QUIC_BAD_APPLICATION_PAYLOAD);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CONNECTION_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_PEER_GOING_AWAY);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CANCELLED);
+    RETURN_STRING_LITERAL(QUIC_RST_ACKNOWLEDGEMENT);
+    RETURN_STRING_LITERAL(QUIC_REFUSED_STREAM);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_URL);
+    RETURN_STRING_LITERAL(QUIC_UNAUTHORIZED_PROMISE_URL);
+    RETURN_STRING_LITERAL(QUIC_DUPLICATE_PROMISE_URL);
+    RETURN_STRING_LITERAL(QUIC_PROMISE_VARY_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PROMISE_METHOD);
+    RETURN_STRING_LITERAL(QUIC_PUSH_STREAM_TIMED_OUT);
+    RETURN_STRING_LITERAL(QUIC_HEADERS_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_STREAM_TTL_EXPIRED);
+    RETURN_STRING_LITERAL(QUIC_DATA_AFTER_CLOSE_OFFSET);
+    RETURN_STRING_LITERAL(QUIC_STREAM_GENERAL_PROTOCOL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_STREAM_CREATION_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CLOSED_CRITICAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_UNEXPECTED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_FRAME_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_EXCESSIVE_LOAD);
+    RETURN_STRING_LITERAL(QUIC_STREAM_ID_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_SETTINGS_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_MISSING_SETTINGS);
+    RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_REJECTED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_REQUEST_INCOMPLETE);
+    RETURN_STRING_LITERAL(QUIC_STREAM_CONNECT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_VERSION_FALLBACK);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DECOMPRESSION_FAILED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_ENCODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DECODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE);
+    RETURN_STRING_LITERAL(QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
+    RETURN_STRING_LITERAL(
+        QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED);
+    RETURN_STRING_LITERAL(QUIC_STREAM_LAST_ERROR);
+  }
+  // Return a default value so that we return this when |error| doesn't match
+  // any of the QuicRstStreamErrorCodes. This can happen when the RstStream
+  // frame sent by the peer (attacker) has invalid error code.
+  return "INVALID_RST_STREAM_ERROR_CODE";
+}
+
+const char* QuicErrorCodeToString(QuicErrorCode error) {
+  switch (error) {
+    RETURN_STRING_LITERAL(QUIC_NO_ERROR);
+    RETURN_STRING_LITERAL(QUIC_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DATA_AFTER_TERMINATION);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PACKET_HEADER);
+    RETURN_STRING_LITERAL(QUIC_INVALID_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_MISSING_PAYLOAD);
+    RETURN_STRING_LITERAL(QUIC_INVALID_FEC_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_OVERLAPPING_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_RST_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_GOAWAY_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_WINDOW_UPDATE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_BLOCKED_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STOP_WAITING_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CLOSE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_ACK_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PUBLIC_RST_PACKET);
+    RETURN_STRING_LITERAL(QUIC_DECRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_ENCRYPTION_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_PACKET_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_PEER_GOING_AWAY);
+    RETURN_STRING_LITERAL(QUIC_HANDSHAKE_FAILED);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_TAGS_OUT_OF_ORDER);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_ENTRIES);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_TOO_MANY_REJECTS);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_INVALID_VALUE_LENGTH)
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_VERSION_NOT_SUPPORTED);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_NO_SUPPORT);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_UNSUPPORTED_PROOF_DEMAND);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_ID);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OPEN_STREAMS);
+    RETURN_STRING_LITERAL(QUIC_PUBLIC_RESET);
+    RETURN_STRING_LITERAL(QUIC_INVALID_VERSION);
+    RETURN_STRING_LITERAL(QUIC_PACKET_WRONG_VERSION);
+    RETURN_STRING_LITERAL(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
+    RETURN_STRING_LITERAL(QUIC_INVALID_HEADER_ID);
+    RETURN_STRING_LITERAL(QUIC_INVALID_NEGOTIATED_VALUE);
+    RETURN_STRING_LITERAL(QUIC_DECOMPRESSION_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_NETWORK_IDLE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_HANDSHAKE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_ADDRESS);
+    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_PORT);
+    RETURN_STRING_LITERAL(QUIC_PACKET_WRITE_ERROR);
+    RETURN_STRING_LITERAL(QUIC_PACKET_READ_ERROR);
+    RETURN_STRING_LITERAL(QUIC_EMPTY_STREAM_FRAME_NO_FIN);
+    RETURN_STRING_LITERAL(QUIC_INVALID_HEADERS_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE);
+    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
+    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
+    RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_INVALID_WINDOW);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_IP_POOLED);
+    RETURN_STRING_LITERAL(QUIC_PROOF_INVALID);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_DUPLICATE_TAG);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CHANNEL_ID_SIGNATURE);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE);
+    RETURN_STRING_LITERAL(QUIC_VERSION_NEGOTIATION_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_CANCELLED);
+    RETURN_STRING_LITERAL(QUIC_BAD_PACKET_LOSS_RATE);
+    RETURN_STRING_LITERAL(QUIC_PUBLIC_RESETS_POST_HANDSHAKE);
+    RETURN_STRING_LITERAL(QUIC_FAILED_TO_SERIALIZE_PACKET);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_AVAILABLE_STREAMS);
+    RETURN_STRING_LITERAL(QUIC_UNENCRYPTED_FEC_DATA);
+    RETURN_STRING_LITERAL(QUIC_BAD_MULTIPATH_FLAG);
+    RETURN_STRING_LITERAL(QUIC_IP_ADDRESS_CHANGED);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_RTOS);
+    RETURN_STRING_LITERAL(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA);
+    RETURN_STRING_LITERAL(QUIC_MAYBE_CORRUPTED_MEMORY);
+    RETURN_STRING_LITERAL(QUIC_CRYPTO_CHLO_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST);
+    RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_NOT_ACTIVE);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_STREAM_DATA_INTERVALS);
+    RETURN_STRING_LITERAL(QUIC_STREAM_SEQUENCER_INVALID_STATE);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_SESSIONS_ON_SERVER);
+    RETURN_STRING_LITERAL(QUIC_STREAM_LENGTH_OVERFLOW);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_INVALID_MAX_DATA_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_BLOCKED_DATA);
+    RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_DATA);
+    RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_ID_LIMIT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE);
+    RETURN_STRING_LITERAL(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_CHALLENGE_DATA);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PATH_RESPONSE_DATA);
+    RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED);
+    RETURN_STRING_LITERAL(QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED);
+    RETURN_STRING_LITERAL(QUIC_INVALID_MESSAGE_DATA);
+    RETURN_STRING_LITERAL(IETF_QUIC_PROTOCOL_VIOLATION);
+    RETURN_STRING_LITERAL(QUIC_INVALID_NEW_TOKEN);
+    RETURN_STRING_LITERAL(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_STREAMS_BLOCKED_ERROR);
+    RETURN_STRING_LITERAL(QUIC_MAX_STREAMS_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HTTP_DECODER_ERROR);
+    RETURN_STRING_LITERAL(QUIC_STALE_CONNECTION_CANCELLED);
+    RETURN_STRING_LITERAL(QUIC_IETF_GQUIC_ERROR_MISSING);
+    RETURN_STRING_LITERAL(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES);
+    RETURN_STRING_LITERAL(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECOMPRESSION_FAILED);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_ERROR);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX);
+    RETURN_STRING_LITERAL(
+        QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND);
+    RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT);
+    RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT);
+    RETURN_STRING_LITERAL(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET);
+    RETURN_STRING_LITERAL(QUIC_STREAM_MULTIPLE_OFFSET);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_TOO_LARGE);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_WRONG_DIRECTION);
+    RETURN_STRING_LITERAL(QUIC_HTTP_CLOSED_CRITICAL_STREAM);
+    RETURN_STRING_LITERAL(QUIC_HTTP_MISSING_SETTINGS_FRAME);
+    RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_MAX_PUSH_ID);
+    RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_LIMIT_TOO_LOW);
+    RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID);
+    RETURN_STRING_LITERAL(QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS);
+    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_SETTING);
+    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SPDY_FRAME);
+    RETURN_STRING_LITERAL(QUIC_HTTP_RECEIVE_SERVER_PUSH);
+    RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_SETTING_VALUE);
+    RETURN_STRING_LITERAL(QUIC_HPACK_INDEX_VARINT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_HPACK_NAME_HUFFMAN_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_VALUE_HUFFMAN_ERROR);
+    RETURN_STRING_LITERAL(QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE);
+    RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_INDEX);
+    RETURN_STRING_LITERAL(QUIC_HPACK_INVALID_NAME_INDEX);
+    RETURN_STRING_LITERAL(QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED);
+    RETURN_STRING_LITERAL(
+        QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK);
+    RETURN_STRING_LITERAL(
+        QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING);
+    RETURN_STRING_LITERAL(QUIC_HPACK_TRUNCATED_BLOCK);
+    RETURN_STRING_LITERAL(QUIC_HPACK_FRAGMENT_TOO_LONG);
+    RETURN_STRING_LITERAL(QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT);
+    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_UNRETRANSMITTABLE);
+    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED);
+    RETURN_STRING_LITERAL(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED);
+    RETURN_STRING_LITERAL(QUIC_SILENT_IDLE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_MISSING_WRITE_KEYS);
+    RETURN_STRING_LITERAL(QUIC_KEY_UPDATE_ERROR);
+    RETURN_STRING_LITERAL(QUIC_AEAD_LIMIT_REACHED);
+    RETURN_STRING_LITERAL(QUIC_MAX_AGE_TIMEOUT);
+    RETURN_STRING_LITERAL(QUIC_INVALID_PRIORITY_UPDATE);
+    RETURN_STRING_LITERAL(QUIC_TLS_BAD_CERTIFICATE);
+    RETURN_STRING_LITERAL(QUIC_TLS_UNSUPPORTED_CERTIFICATE);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REVOKED);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_EXPIRED);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_UNKNOWN);
+    RETURN_STRING_LITERAL(QUIC_TLS_INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(QUIC_TLS_UNRECOGNIZED_NAME);
+    RETURN_STRING_LITERAL(QUIC_TLS_CERTIFICATE_REQUIRED);
+    RETURN_STRING_LITERAL(QUIC_INVALID_CHARACTER_IN_FIELD_VALUE);
+    RETURN_STRING_LITERAL(QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL);
+    RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH);
+    RETURN_STRING_LITERAL(QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE);
+    RETURN_STRING_LITERAL(QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED);
+
+    RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
+    // Intentionally have no default case, so we'll break the build
+    // if we add errors and don't put them here.
+  }
+  // Return a default value so that we return this when |error| doesn't match
+  // any of the QuicErrorCodes. This can happen when the ConnectionClose
+  // frame sent by the peer (attacker) has invalid error code.
+  return "INVALID_ERROR_CODE";
+}
+
+std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) {
+  if (c >= CRYPTO_ERROR_FIRST && c <= CRYPTO_ERROR_LAST) {
+    const int tls_error = static_cast<int>(c - CRYPTO_ERROR_FIRST);
+    const char* tls_error_description = SSL_alert_desc_string_long(tls_error);
+    if (strcmp("unknown", tls_error_description) != 0) {
+      return absl::StrCat("CRYPTO_ERROR(", tls_error_description, ")");
+    }
+    return absl::StrCat("CRYPTO_ERROR(unknown(", tls_error, "))");
+  }
+
+  switch (c) {
+    RETURN_STRING_LITERAL(NO_IETF_QUIC_ERROR);
+    RETURN_STRING_LITERAL(INTERNAL_ERROR);
+    RETURN_STRING_LITERAL(SERVER_BUSY_ERROR);
+    RETURN_STRING_LITERAL(FLOW_CONTROL_ERROR);
+    RETURN_STRING_LITERAL(STREAM_LIMIT_ERROR);
+    RETURN_STRING_LITERAL(STREAM_STATE_ERROR);
+    RETURN_STRING_LITERAL(FINAL_SIZE_ERROR);
+    RETURN_STRING_LITERAL(FRAME_ENCODING_ERROR);
+    RETURN_STRING_LITERAL(TRANSPORT_PARAMETER_ERROR);
+    RETURN_STRING_LITERAL(CONNECTION_ID_LIMIT_ERROR);
+    RETURN_STRING_LITERAL(PROTOCOL_VIOLATION);
+    RETURN_STRING_LITERAL(INVALID_TOKEN);
+    RETURN_STRING_LITERAL(CRYPTO_BUFFER_EXCEEDED);
+    RETURN_STRING_LITERAL(KEY_UPDATE_ERROR);
+    RETURN_STRING_LITERAL(AEAD_LIMIT_REACHED);
+    // CRYPTO_ERROR is handled in the if before this switch, these cases do not
+    // change behavior and are only here to make the compiler happy.
+    case CRYPTO_ERROR_FIRST:
+    case CRYPTO_ERROR_LAST:
+      QUICHE_DCHECK(false) << "Unexpected error " << static_cast<uint64_t>(c);
+      break;
+  }
+
+  return absl::StrCat("Unknown(", static_cast<uint64_t>(c), ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicIetfTransportErrorCodes& c) {
+  os << QuicIetfTransportErrorCodeString(c);
+  return os;
+}
+
+QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
+    QuicErrorCode error) {
+  switch (error) {
+    case QUIC_NO_ERROR:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_STREAM_DATA_AFTER_TERMINATION:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_PACKET_HEADER:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_FRAME_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_MISSING_PAYLOAD:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_FEC_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_STREAM_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_OVERLAPPING_STREAM_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNENCRYPTED_STREAM_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_MAYBE_CORRUPTED_MEMORY:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNENCRYPTED_FEC_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_RST_STREAM_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CONNECTION_CLOSE_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_GOAWAY_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_WINDOW_UPDATE_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_BLOCKED_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_STOP_WAITING_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_PATH_CLOSE_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_ACK_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_MESSAGE_DATA:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_VERSION_NEGOTIATION_PACKET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PUBLIC_RST_PACKET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_DECRYPTION_FAILURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_ENCRYPTION_FAILURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PACKET_TOO_LARGE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PEER_GOING_AWAY:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_STREAM_ID:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PRIORITY:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_OPEN_STREAMS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TOO_MANY_AVAILABLE_STREAMS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PUBLIC_RESET:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_VERSION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PACKET_WRONG_VERSION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_HEADER_ID:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_NEGOTIATED_VALUE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_DECOMPRESSION_FAILURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_NETWORK_IDLE_TIMEOUT:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_SILENT_IDLE_TIMEOUT:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_HANDSHAKE_TIMEOUT:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_ERROR_MIGRATING_ADDRESS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_ERROR_MIGRATING_PORT:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PACKET_WRITE_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PACKET_READ_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_EMPTY_STREAM_FRAME_NO_FIN:
+      return {true, static_cast<uint64_t>(FRAME_ENCODING_ERROR)};
+    case QUIC_INVALID_HEADERS_STREAM_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA:
+      return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
+    case QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_FLOW_CONTROL_INVALID_WINDOW:
+      return {true, static_cast<uint64_t>(FLOW_CONTROL_ERROR)};
+    case QUIC_CONNECTION_IP_POOLED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_CANCELLED:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_BAD_PACKET_LOSS_RATE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PUBLIC_RESETS_POST_HANDSHAKE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_FAILED_TO_SERIALIZE_PACKET:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_RTOS:
+      return {true, static_cast<uint64_t>(NO_IETF_QUIC_ERROR)};
+    case QUIC_HANDSHAKE_FAILED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_TAGS_OUT_OF_ORDER:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_TOO_MANY_ENTRIES:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_INVALID_VALUE_LENGTH:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CRYPTO_MESSAGE_TYPE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_CHANNEL_ID_SIGNATURE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNSUPPORTED_PROOF_DEMAND:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CRYPTO_VERSION_NOT_SUPPORTED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_NO_SUPPORT:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_TOO_MANY_REJECTS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_PROOF_INVALID:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_DUPLICATE_TAG:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_SERVER_CONFIG_EXPIRED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_CRYPTO_CHLO_TOO_LARGE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_VERSION_NEGOTIATION_MISMATCH:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_BAD_MULTIPATH_FLAG:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MULTIPATH_PATH_DOES_NOT_EXIST:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_MULTIPATH_PATH_NOT_ACTIVE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_IP_ADDRESS_CHANGED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_STREAM_DATA_INTERVALS:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAM_SEQUENCER_INVALID_STATE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_TOO_MANY_SESSIONS_ON_SERVER:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_STREAM_LENGTH_OVERFLOW:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_MAX_DATA_FRAME_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MAX_STREAMS_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAMS_BLOCKED_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_STREAM_BLOCKED_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_NEW_CONNECTION_ID_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_STOP_SENDING_FRAME_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PATH_CHALLENGE_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_PATH_RESPONSE_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case IETF_QUIC_PROTOCOL_VIOLATION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_INVALID_NEW_TOKEN:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM:
+      return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
+    case QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_RETIRE_CONNECTION_ID_DATA:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAMS_BLOCKED_ERROR:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MAX_STREAMS_ERROR:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_HTTP_DECODER_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_STALE_CONNECTION_CANCELLED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_IETF_GQUIC_ERROR_MISSING:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_QPACK_DECOMPRESSION_FAILED:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECOMPRESSION_FAILED)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_ERROR:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT:
+      return {false, static_cast<uint64_t>(
+                         QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)};
+    case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_STREAM_MULTIPLE_OFFSET:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_HTTP_FRAME_TOO_LARGE:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD)};
+    case QUIC_HTTP_FRAME_ERROR:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR)};
+    case QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
+    case QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR)};
+    case QUIC_HTTP_STREAM_WRONG_DIRECTION:
+      return {true, static_cast<uint64_t>(STREAM_STATE_ERROR)};
+    case QUIC_HTTP_CLOSED_CRITICAL_STREAM:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM)};
+    case QUIC_HTTP_MISSING_SETTINGS_FRAME:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS)};
+    case QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_INVALID_MAX_PUSH_ID:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_STREAM_LIMIT_TOO_LOW:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+    case QUIC_HTTP_RECEIVE_SERVER_PUSH:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+    case QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HTTP_GOAWAY_INVALID_STREAM_ID:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR)};
+    case QUIC_HTTP_RECEIVE_SPDY_SETTING:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_INVALID_SETTING_VALUE:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+    case QUIC_HTTP_RECEIVE_SPDY_FRAME:
+      return {false,
+              static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED)};
+    case QUIC_HPACK_INDEX_VARINT_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_NAME_TOO_LONG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_VALUE_TOO_LONG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_NAME_HUFFMAN_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_VALUE_HUFFMAN_ERROR:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_INVALID_INDEX:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_INVALID_NAME_INDEX:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_TRUNCATED_BLOCK:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_FRAGMENT_TOO_LONG:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_ZERO_RTT_UNRETRANSMITTABLE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_MISSING_WRITE_KEYS:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_KEY_UPDATE_ERROR:
+      return {true, static_cast<uint64_t>(KEY_UPDATE_ERROR)};
+    case QUIC_AEAD_LIMIT_REACHED:
+      return {true, static_cast<uint64_t>(AEAD_LIMIT_REACHED)};
+    case QUIC_MAX_AGE_TIMEOUT:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR)};
+    case QUIC_INVALID_PRIORITY_UPDATE:
+      return {false, static_cast<uint64_t>(
+                         QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+    case QUIC_TLS_BAD_CERTIFICATE:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_BAD_CERTIFICATE)};
+    case QUIC_TLS_UNSUPPORTED_CERTIFICATE:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_UNSUPPORTED_CERTIFICATE)};
+    case QUIC_TLS_CERTIFICATE_REVOKED:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_REVOKED)};
+    case QUIC_TLS_CERTIFICATE_EXPIRED:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_EXPIRED)};
+    case QUIC_TLS_CERTIFICATE_UNKNOWN:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_UNKNOWN)};
+    case QUIC_TLS_INTERNAL_ERROR:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_INTERNAL_ERROR)};
+    case QUIC_TLS_UNRECOGNIZED_NAME:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_UNRECOGNIZED_NAME)};
+    case QUIC_TLS_CERTIFICATE_REQUIRED:
+      return {true, static_cast<uint64_t>(CRYPTO_ERROR_FIRST +
+                                          SSL_AD_CERTIFICATE_REQUIRED)};
+    case QUIC_CONNECTION_ID_LIMIT_ERROR:
+      return {true, static_cast<uint64_t>(CONNECTION_ID_LIMIT_ERROR)};
+    case QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE:
+      return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+    case QUIC_INVALID_CHARACTER_IN_FIELD_VALUE:
+      return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::MESSAGE_ERROR)};
+    case QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED:
+      return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
+    case QUIC_LAST_ERROR:
+      return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)};
+  }
+  // This function should not be called with unknown error code.
+  return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+}
+
+QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc) {
+  switch (desc) {
+    case SSL_AD_BAD_CERTIFICATE:
+      return QUIC_TLS_BAD_CERTIFICATE;
+    case SSL_AD_UNSUPPORTED_CERTIFICATE:
+      return QUIC_TLS_UNSUPPORTED_CERTIFICATE;
+    case SSL_AD_CERTIFICATE_REVOKED:
+      return QUIC_TLS_CERTIFICATE_REVOKED;
+    case SSL_AD_CERTIFICATE_EXPIRED:
+      return QUIC_TLS_CERTIFICATE_EXPIRED;
+    case SSL_AD_CERTIFICATE_UNKNOWN:
+      return QUIC_TLS_CERTIFICATE_UNKNOWN;
+    case SSL_AD_INTERNAL_ERROR:
+      return QUIC_TLS_INTERNAL_ERROR;
+    case SSL_AD_UNRECOGNIZED_NAME:
+      return QUIC_TLS_UNRECOGNIZED_NAME;
+    case SSL_AD_CERTIFICATE_REQUIRED:
+      return QUIC_TLS_CERTIFICATE_REQUIRED;
+    default:
+      return QUIC_HANDSHAKE_FAILED;
+  }
+}
+
+// Convert a QuicRstStreamErrorCode to an application error code to be used in
+// an IETF QUIC RESET_STREAM frame
+uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
+    QuicRstStreamErrorCode rst_stream_error_code) {
+  switch (rst_stream_error_code) {
+    case QUIC_STREAM_NO_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
+    case QUIC_ERROR_PROCESSING_STREAM:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_MULTIPLE_TERMINATION_OFFSETS:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_BAD_APPLICATION_PAYLOAD:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_CONNECTION_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+    case QUIC_STREAM_PEER_GOING_AWAY:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_CANCELLED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_RST_ACKNOWLEDGEMENT:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR);
+    case QUIC_REFUSED_STREAM:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
+    case QUIC_INVALID_PROMISE_URL:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_UNAUTHORIZED_PROMISE_URL:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_DUPLICATE_PROMISE_URL:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_PROMISE_VARY_MISMATCH:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_INVALID_PROMISE_METHOD:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_PUSH_STREAM_TIMED_OUT:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_HEADERS_TOO_LARGE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
+    case QUIC_STREAM_TTL_EXPIRED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
+    case QUIC_DATA_AFTER_CLOSE_OFFSET:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_GENERAL_PROTOCOL_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR);
+    case QUIC_STREAM_INTERNAL_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+    case QUIC_STREAM_STREAM_CREATION_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR);
+    case QUIC_STREAM_CLOSED_CRITICAL_STREAM:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM);
+    case QUIC_STREAM_FRAME_UNEXPECTED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED);
+    case QUIC_STREAM_FRAME_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR);
+    case QUIC_STREAM_EXCESSIVE_LOAD:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD);
+    case QUIC_STREAM_ID_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR);
+    case QUIC_STREAM_SETTINGS_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR);
+    case QUIC_STREAM_MISSING_SETTINGS:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS);
+    case QUIC_STREAM_REQUEST_REJECTED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED);
+    case QUIC_STREAM_REQUEST_INCOMPLETE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE);
+    case QUIC_STREAM_CONNECT_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
+    case QUIC_STREAM_VERSION_FALLBACK:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK);
+    case QUIC_STREAM_DECOMPRESSION_FAILED:
+      return static_cast<uint64_t>(
+          QuicHttpQpackErrorCode::DECOMPRESSION_FAILED);
+    case QUIC_STREAM_ENCODER_STREAM_ERROR:
+      return static_cast<uint64_t>(
+          QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
+    case QUIC_STREAM_DECODER_STREAM_ERROR:
+      return static_cast<uint64_t>(
+          QuicHttpQpackErrorCode::DECODER_STREAM_ERROR);
+    case QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+    case QUIC_STREAM_WEBTRANSPORT_SESSION_GONE:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
+    case QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR);
+    case QUIC_STREAM_LAST_ERROR:
+      return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+  }
+  return static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR);
+}
+
+// Convert the application error code of an IETF QUIC RESET_STREAM frame
+// to QuicRstStreamErrorCode.
+QuicRstStreamErrorCode IetfResetStreamErrorCodeToRstStreamErrorCode(
+    uint64_t ietf_error_code) {
+  switch (ietf_error_code) {
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR):
+      return QUIC_STREAM_NO_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR):
+      return QUIC_STREAM_GENERAL_PROTOCOL_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR):
+      return QUIC_STREAM_INTERNAL_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR):
+      return QUIC_STREAM_STREAM_CREATION_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM):
+      return QUIC_STREAM_CLOSED_CRITICAL_STREAM;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED):
+      return QUIC_STREAM_FRAME_UNEXPECTED;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR):
+      return QUIC_STREAM_FRAME_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD):
+      return QUIC_STREAM_EXCESSIVE_LOAD;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR):
+      return QUIC_STREAM_ID_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR):
+      return QUIC_STREAM_SETTINGS_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS):
+      return QUIC_STREAM_MISSING_SETTINGS;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED):
+      return QUIC_STREAM_REQUEST_REJECTED;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED):
+      return QUIC_STREAM_CANCELLED;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE):
+      return QUIC_STREAM_REQUEST_INCOMPLETE;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR):
+      return QUIC_STREAM_CONNECT_ERROR;
+    case static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK):
+      return QUIC_STREAM_VERSION_FALLBACK;
+    case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED):
+      return QUIC_STREAM_DECOMPRESSION_FAILED;
+    case static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR):
+      return QUIC_STREAM_ENCODER_STREAM_ERROR;
+    case static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR):
+      return QUIC_STREAM_DECODER_STREAM_ERROR;
+  }
+  return QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE;
+}
+
+// static
+QuicResetStreamError QuicResetStreamError::FromInternal(
+    QuicRstStreamErrorCode code) {
+  return QuicResetStreamError(
+      code, RstStreamErrorCodeToIetfResetStreamErrorCode(code));
+}
+
+// static
+QuicResetStreamError QuicResetStreamError::FromIetf(uint64_t code) {
+  return QuicResetStreamError(
+      IetfResetStreamErrorCodeToRstStreamErrorCode(code), code);
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_error_codes.h b/quiche/quic/core/quic_error_codes.h
new file mode 100644
index 0000000..9c20cd5
--- /dev/null
+++ b/quiche/quic/core/quic_error_codes.h
@@ -0,0 +1,769 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
+#define QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
+
+#include <cstdint>
+#include <limits>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicRstStreamErrorCode is encoded as a single octet on-the-wire in IETF QUIC
+// and a 32-bit integer in gQUIC.
+enum QuicRstStreamErrorCode : uint32_t {
+  // Complete response has been sent, sending a RST to ask the other endpoint
+  // to stop sending request data without discarding the response.
+  QUIC_STREAM_NO_ERROR = 0,
+
+  // There was some error which halted stream processing.
+  QUIC_ERROR_PROCESSING_STREAM = 1,
+  // We got two fin or reset offsets which did not match.
+  QUIC_MULTIPLE_TERMINATION_OFFSETS = 2,
+  // We got bad payload and can not respond to it at the protocol level.
+  QUIC_BAD_APPLICATION_PAYLOAD = 3,
+  // Stream closed due to connection error. No reset frame is sent when this
+  // happens.
+  QUIC_STREAM_CONNECTION_ERROR = 4,
+  // GoAway frame sent. No more stream can be created.
+  QUIC_STREAM_PEER_GOING_AWAY = 5,
+  // The stream has been cancelled.
+  QUIC_STREAM_CANCELLED = 6,
+  // Closing stream locally, sending a RST to allow for proper flow control
+  // accounting. Sent in response to a RST from the peer.
+  QUIC_RST_ACKNOWLEDGEMENT = 7,
+  // Receiver refused to create the stream (because its limit on open streams
+  // has been reached).  The sender should retry the request later (using
+  // another stream).
+  QUIC_REFUSED_STREAM = 8,
+  // Invalid URL in PUSH_PROMISE request header.
+  QUIC_INVALID_PROMISE_URL = 9,
+  // Server is not authoritative for this URL.
+  QUIC_UNAUTHORIZED_PROMISE_URL = 10,
+  // Can't have more than one active PUSH_PROMISE per URL.
+  QUIC_DUPLICATE_PROMISE_URL = 11,
+  // Vary check failed.
+  QUIC_PROMISE_VARY_MISMATCH = 12,
+  // Only GET and HEAD methods allowed.
+  QUIC_INVALID_PROMISE_METHOD = 13,
+  // The push stream is unclaimed and timed out.
+  QUIC_PUSH_STREAM_TIMED_OUT = 14,
+  // Received headers were too large.
+  QUIC_HEADERS_TOO_LARGE = 15,
+  // The data is not likely arrive in time.
+  QUIC_STREAM_TTL_EXPIRED = 16,
+  // The stream received data that goes beyond its close offset.
+  QUIC_DATA_AFTER_CLOSE_OFFSET = 17,
+  // Peer violated protocol requirements in a way which does not match a more
+  // specific error code, or endpoint declines to use the more specific error
+  // code.
+  QUIC_STREAM_GENERAL_PROTOCOL_ERROR = 18,
+  // An internal error has occurred.
+  QUIC_STREAM_INTERNAL_ERROR = 19,
+  // Peer created a stream that will not be accepted.
+  QUIC_STREAM_STREAM_CREATION_ERROR = 20,
+  // A stream required by the connection was closed or reset.
+  QUIC_STREAM_CLOSED_CRITICAL_STREAM = 21,
+  // A frame was received which was not permitted in the current state or on the
+  // current stream.
+  QUIC_STREAM_FRAME_UNEXPECTED = 22,
+  // A frame that fails to satisfy layout requirements or with an invalid size
+  // was received.
+  QUIC_STREAM_FRAME_ERROR = 23,
+  // Peer exhibits a behavior that might be generating excessive load.
+  QUIC_STREAM_EXCESSIVE_LOAD = 24,
+  // A Stream ID or Push ID was used incorrectly, such as exceeding a limit,
+  // reducing a limit, or being reused.
+  QUIC_STREAM_ID_ERROR = 25,
+  // Error in the payload of a SETTINGS frame.
+  QUIC_STREAM_SETTINGS_ERROR = 26,
+  // No SETTINGS frame was received at the beginning of the control stream.
+  QUIC_STREAM_MISSING_SETTINGS = 27,
+  // A server rejected a request without performing any application processing.
+  QUIC_STREAM_REQUEST_REJECTED = 28,
+  // The client's stream terminated without containing a fully-formed request.
+  QUIC_STREAM_REQUEST_INCOMPLETE = 29,
+  // The connection established in response to a CONNECT request was reset or
+  // abnormally closed.
+  QUIC_STREAM_CONNECT_ERROR = 30,
+  // The requested operation cannot be served over HTTP/3.
+  // The peer should retry over HTTP/1.1.
+  QUIC_STREAM_VERSION_FALLBACK = 31,
+  // The QPACK decoder failed to interpret a header block and is not able to
+  // continue decoding that header block.
+  QUIC_STREAM_DECOMPRESSION_FAILED = 32,
+  // The QPACK decoder failed to interpret an encoder instruction received on
+  // the encoder stream.
+  QUIC_STREAM_ENCODER_STREAM_ERROR = 33,
+  // The QPACK encoder failed to interpret a decoder instruction received on the
+  // decoder stream.
+  QUIC_STREAM_DECODER_STREAM_ERROR = 34,
+  // IETF RESET_FRAME application error code not matching any HTTP/3 or QPACK
+  // error codes.
+  QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE = 35,
+  // WebTransport session is going away, causing all underlying streams to be
+  // reset.
+  QUIC_STREAM_WEBTRANSPORT_SESSION_GONE = 36,
+  // There is no corresponding WebTransport session to associate this stream
+  // with, and the limit for buffered streams has been exceeded.
+  QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED = 37,
+  // No error. Used as bound while iterating.
+  QUIC_STREAM_LAST_ERROR = 38,
+};
+// QuicRstStreamErrorCode is encoded as a single octet on-the-wire.
+static_assert(static_cast<int>(QUIC_STREAM_LAST_ERROR) <=
+                  std::numeric_limits<uint8_t>::max(),
+              "QuicRstStreamErrorCode exceeds single octet");
+
+// These values must remain stable as they are uploaded to UMA histograms.
+// To add a new error code, use the current value of QUIC_LAST_ERROR and
+// increment QUIC_LAST_ERROR.
+enum QuicErrorCode {
+  QUIC_NO_ERROR = 0,
+
+  // Connection has reached an invalid state.
+  QUIC_INTERNAL_ERROR = 1,
+  // There were data frames after the a fin or reset.
+  QUIC_STREAM_DATA_AFTER_TERMINATION = 2,
+  // Control frame is malformed.
+  QUIC_INVALID_PACKET_HEADER = 3,
+  // Frame data is malformed.
+  QUIC_INVALID_FRAME_DATA = 4,
+  // The packet contained no payload.
+  QUIC_MISSING_PAYLOAD = 48,
+  // FEC data is malformed.
+  QUIC_INVALID_FEC_DATA = 5,
+  // STREAM frame data is malformed.
+  QUIC_INVALID_STREAM_DATA = 46,
+  // STREAM frame data overlaps with buffered data.
+  QUIC_OVERLAPPING_STREAM_DATA = 87,
+  // Received STREAM frame data is not encrypted.
+  QUIC_UNENCRYPTED_STREAM_DATA = 61,
+  // Attempt to send unencrypted STREAM frame.
+  QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA = 88,
+  // Received a frame which is likely the result of memory corruption.
+  QUIC_MAYBE_CORRUPTED_MEMORY = 89,
+  // FEC frame data is not encrypted.
+  QUIC_UNENCRYPTED_FEC_DATA = 77,
+  // RST_STREAM frame data is malformed.
+  QUIC_INVALID_RST_STREAM_DATA = 6,
+  // CONNECTION_CLOSE frame data is malformed.
+  QUIC_INVALID_CONNECTION_CLOSE_DATA = 7,
+  // GOAWAY frame data is malformed.
+  QUIC_INVALID_GOAWAY_DATA = 8,
+  // WINDOW_UPDATE frame data is malformed.
+  QUIC_INVALID_WINDOW_UPDATE_DATA = 57,
+  // BLOCKED frame data is malformed.
+  QUIC_INVALID_BLOCKED_DATA = 58,
+  // STOP_WAITING frame data is malformed.
+  QUIC_INVALID_STOP_WAITING_DATA = 60,
+  // PATH_CLOSE frame data is malformed.
+  QUIC_INVALID_PATH_CLOSE_DATA = 78,
+  // ACK frame data is malformed.
+  QUIC_INVALID_ACK_DATA = 9,
+  // Message frame data is malformed.
+  QUIC_INVALID_MESSAGE_DATA = 112,
+
+  // Version negotiation packet is malformed.
+  QUIC_INVALID_VERSION_NEGOTIATION_PACKET = 10,
+  // Public RST packet is malformed.
+  QUIC_INVALID_PUBLIC_RST_PACKET = 11,
+  // There was an error decrypting.
+  QUIC_DECRYPTION_FAILURE = 12,
+  // There was an error encrypting.
+  QUIC_ENCRYPTION_FAILURE = 13,
+  // The packet exceeded kMaxOutgoingPacketSize.
+  QUIC_PACKET_TOO_LARGE = 14,
+  // The peer is going away.  May be a client or server.
+  QUIC_PEER_GOING_AWAY = 16,
+  // A stream ID was invalid.
+  QUIC_INVALID_STREAM_ID = 17,
+  // A priority was invalid.
+  QUIC_INVALID_PRIORITY = 49,
+  // Too many streams already open.
+  QUIC_TOO_MANY_OPEN_STREAMS = 18,
+  // The peer created too many available streams.
+  QUIC_TOO_MANY_AVAILABLE_STREAMS = 76,
+  // Received public reset for this connection.
+  QUIC_PUBLIC_RESET = 19,
+  // Version selected by client is not acceptable to the server.
+  QUIC_INVALID_VERSION = 20,
+  // Received packet indicates version that does not match connection version.
+  QUIC_PACKET_WRONG_VERSION = 212,
+
+  // The Header ID for a stream was too far from the previous.
+  QUIC_INVALID_HEADER_ID = 22,
+  // Negotiable parameter received during handshake had invalid value.
+  QUIC_INVALID_NEGOTIATED_VALUE = 23,
+  // There was an error decompressing data.
+  QUIC_DECOMPRESSION_FAILURE = 24,
+  // The connection timed out due to no network activity.
+  QUIC_NETWORK_IDLE_TIMEOUT = 25,
+  // The connection timed out waiting for the handshake to complete.
+  QUIC_HANDSHAKE_TIMEOUT = 67,
+  // There was an error encountered migrating addresses.
+  QUIC_ERROR_MIGRATING_ADDRESS = 26,
+  // There was an error encountered migrating port only.
+  QUIC_ERROR_MIGRATING_PORT = 86,
+  // There was an error while writing to the socket.
+  QUIC_PACKET_WRITE_ERROR = 27,
+  // There was an error while reading from the socket.
+  QUIC_PACKET_READ_ERROR = 51,
+  // We received a STREAM_FRAME with no data and no fin flag set.
+  QUIC_EMPTY_STREAM_FRAME_NO_FIN = 50,
+  // We received invalid data on the headers stream.
+  QUIC_INVALID_HEADERS_STREAM_DATA = 56,
+  // Invalid data on the headers stream received because of decompression
+  // failure.
+  QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE = 97,
+  // The peer received too much data, violating flow control.
+  QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA = 59,
+  // The peer sent too much data, violating flow control.
+  QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA = 63,
+  // The peer received an invalid flow control window.
+  QUIC_FLOW_CONTROL_INVALID_WINDOW = 64,
+  // The connection has been IP pooled into an existing connection.
+  QUIC_CONNECTION_IP_POOLED = 62,
+  // The connection has too many outstanding sent packets.
+  QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS = 68,
+  // The connection has too many outstanding received packets.
+  QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS = 69,
+  // The quic connection has been cancelled.
+  QUIC_CONNECTION_CANCELLED = 70,
+  // Disabled QUIC because of high packet loss rate.
+  QUIC_BAD_PACKET_LOSS_RATE = 71,
+  // Disabled QUIC because of too many PUBLIC_RESETs post handshake.
+  QUIC_PUBLIC_RESETS_POST_HANDSHAKE = 73,
+  // Closed because we failed to serialize a packet.
+  QUIC_FAILED_TO_SERIALIZE_PACKET = 75,
+  // QUIC timed out after too many RTOs.
+  QUIC_TOO_MANY_RTOS = 85,
+
+  // Crypto errors.
+
+  // Handshake failed.
+  QUIC_HANDSHAKE_FAILED = 28,
+  // Handshake message contained out of order tags.
+  QUIC_CRYPTO_TAGS_OUT_OF_ORDER = 29,
+  // Handshake message contained too many entries.
+  QUIC_CRYPTO_TOO_MANY_ENTRIES = 30,
+  // Handshake message contained an invalid value length.
+  QUIC_CRYPTO_INVALID_VALUE_LENGTH = 31,
+  // A crypto message was received after the handshake was complete.
+  QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE = 32,
+  // A crypto message was received with an illegal message tag.
+  QUIC_INVALID_CRYPTO_MESSAGE_TYPE = 33,
+  // A crypto message was received with an illegal parameter.
+  QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER = 34,
+  // An invalid channel id signature was supplied.
+  QUIC_INVALID_CHANNEL_ID_SIGNATURE = 52,
+  // A crypto message was received with a mandatory parameter missing.
+  QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND = 35,
+  // A crypto message was received with a parameter that has no overlap
+  // with the local parameter.
+  QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP = 36,
+  // A crypto message was received that contained a parameter with too few
+  // values.
+  QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND = 37,
+  // A demand for an unsupport proof type was received.
+  QUIC_UNSUPPORTED_PROOF_DEMAND = 94,
+  // An internal error occurred in crypto processing.
+  QUIC_CRYPTO_INTERNAL_ERROR = 38,
+  // A crypto handshake message specified an unsupported version.
+  QUIC_CRYPTO_VERSION_NOT_SUPPORTED = 39,
+  // (Deprecated) A crypto handshake message resulted in a stateless reject.
+  // QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT = 72,
+  // There was no intersection between the crypto primitives supported by the
+  // peer and ourselves.
+  QUIC_CRYPTO_NO_SUPPORT = 40,
+  // The server rejected our client hello messages too many times.
+  QUIC_CRYPTO_TOO_MANY_REJECTS = 41,
+  // The client rejected the server's certificate chain or signature.
+  QUIC_PROOF_INVALID = 42,
+  // A crypto message was received with a duplicate tag.
+  QUIC_CRYPTO_DUPLICATE_TAG = 43,
+  // A crypto message was received with the wrong encryption level (i.e. it
+  // should have been encrypted but was not.)
+  QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT = 44,
+  // The server config for a server has expired.
+  QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45,
+  // We failed to setup the symmetric keys for a connection.
+  QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED = 53,
+  // A handshake message arrived, but we are still validating the
+  // previous handshake message.
+  QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO = 54,
+  // A server config update arrived before the handshake is complete.
+  QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE = 65,
+  // CHLO cannot fit in one packet.
+  QUIC_CRYPTO_CHLO_TOO_LARGE = 90,
+  // This connection involved a version negotiation which appears to have been
+  // tampered with.
+  QUIC_VERSION_NEGOTIATION_MISMATCH = 55,
+
+  // Multipath errors.
+  // Multipath is not enabled, but a packet with multipath flag on is received.
+  QUIC_BAD_MULTIPATH_FLAG = 79,
+  // A path is supposed to exist but does not.
+  QUIC_MULTIPATH_PATH_DOES_NOT_EXIST = 91,
+  // A path is supposed to be active but is not.
+  QUIC_MULTIPATH_PATH_NOT_ACTIVE = 92,
+
+  // IP address changed causing connection close.
+  QUIC_IP_ADDRESS_CHANGED = 80,
+
+  // Connection migration errors.
+  // Network changed, but connection had no migratable streams.
+  QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS = 81,
+  // Connection changed networks too many times.
+  QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES = 82,
+  // Connection migration was attempted, but there was no new network to
+  // migrate to.
+  QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK = 83,
+  // Network changed, but connection had one or more non-migratable streams.
+  QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
+  // Network changed, but connection migration was disabled by config.
+  QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG = 99,
+  // Network changed, but error was encountered on the alternative network.
+  QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR = 100,
+  // Network changed, but handshake is not confirmed yet.
+  QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED = 111,
+  QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED = 194,
+
+  // Stream frames arrived too discontiguously so that stream sequencer buffer
+  // maintains too many intervals.
+  QUIC_TOO_MANY_STREAM_DATA_INTERVALS = 93,
+
+  // Sequencer buffer get into weird state where continuing read/write will lead
+  // to crash.
+  QUIC_STREAM_SEQUENCER_INVALID_STATE = 95,
+
+  // Connection closed because of server hits max number of sessions allowed.
+  QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96,
+
+  // Receive a RST_STREAM with offset larger than kMaxStreamLength.
+  QUIC_STREAM_LENGTH_OVERFLOW = 98,
+  // Received a MAX DATA frame with errors.
+  QUIC_INVALID_MAX_DATA_FRAME_DATA = 102,
+  // Received a MAX STREAM DATA frame with errors.
+  QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA = 103,
+  // Received a MAX_STREAMS frame with bad data
+  QUIC_MAX_STREAMS_DATA = 104,
+  // Received a STREAMS_BLOCKED frame with bad data
+  QUIC_STREAMS_BLOCKED_DATA = 105,
+  // Error deframing a STREAM BLOCKED frame.
+  QUIC_INVALID_STREAM_BLOCKED_DATA = 106,
+  // NEW CONNECTION ID frame data is malformed.
+  QUIC_INVALID_NEW_CONNECTION_ID_DATA = 107,
+  // More connection IDs than allowed are issued.
+  QUIC_CONNECTION_ID_LIMIT_ERROR = 203,
+  // The peer retires connection IDs too quickly.
+  QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE = 204,
+  // Received a MAX STREAM DATA frame with errors.
+  QUIC_INVALID_STOP_SENDING_FRAME_DATA = 108,
+  // Error deframing PATH CHALLENGE or PATH RESPONSE frames.
+  QUIC_INVALID_PATH_CHALLENGE_DATA = 109,
+  QUIC_INVALID_PATH_RESPONSE_DATA = 110,
+  // This is used to indicate an IETF QUIC PROTOCOL VIOLATION
+  // transport error within Google (pre-v99) QUIC.
+  IETF_QUIC_PROTOCOL_VIOLATION = 113,
+  QUIC_INVALID_NEW_TOKEN = 114,
+
+  // Received stream data on a WRITE_UNIDIRECTIONAL stream.
+  QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM = 115,
+  // Try to send stream data on a READ_UNIDIRECTIONAL stream.
+  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM = 116,
+
+  // RETIRE CONNECTION ID frame data is malformed.
+  QUIC_INVALID_RETIRE_CONNECTION_ID_DATA = 117,
+
+  // Error in a received STREAMS BLOCKED frame.
+  QUIC_STREAMS_BLOCKED_ERROR = 118,
+  // Error in a received MAX STREAMS frame
+  QUIC_MAX_STREAMS_ERROR = 119,
+  // Error in Http decoder
+  QUIC_HTTP_DECODER_ERROR = 120,
+  // Connection from stale host needs to be cancelled.
+  QUIC_STALE_CONNECTION_CANCELLED = 121,
+
+  // A pseudo error, used as an extended error reason code in the error_details
+  // of IETF-QUIC CONNECTION_CLOSE frames. It is used in
+  // OnConnectionClosed upcalls to indicate that extended error information was
+  // not available in a received CONNECTION_CLOSE frame.
+  QUIC_IETF_GQUIC_ERROR_MISSING = 122,
+
+  // Received WindowUpdate on a READ_UNIDIRECTIONAL stream.
+  QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM = 123,
+
+  // There are too many buffered control frames in control frame manager.
+  QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES = 124,
+
+  // QuicTransport received invalid client indication.
+  QUIC_TRANSPORT_INVALID_CLIENT_INDICATION = 125,
+
+  // Internal error codes for QPACK errors.
+  QUIC_QPACK_DECOMPRESSION_FAILED = 126,
+
+  // Obsolete generic QPACK encoder and decoder stream error codes.
+  QUIC_QPACK_ENCODER_STREAM_ERROR = 127,
+  QUIC_QPACK_DECODER_STREAM_ERROR = 128,
+
+  // QPACK encoder stream errors.
+
+  // Variable integer exceeding 2^64-1 received.
+  QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE = 174,
+  // String literal exceeding kStringLiteralLengthLimit in length received.
+  QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG = 175,
+  // String literal with invalid Huffman encoding received.
+  QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR = 176,
+  // Invalid static table index in Insert With Name Reference instruction.
+  QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY = 177,
+  // Error inserting entry with static name reference in Insert With Name
+  // Reference instruction due to entry size exceeding dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC = 178,
+  // Invalid relative index in Insert With Name Reference instruction.
+  QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX = 179,
+  // Dynamic entry not found in Insert With Name Reference instruction.
+  QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND = 180,
+  // Error inserting entry with dynamic name reference in Insert With Name
+  // Reference instruction due to entry size exceeding dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC = 181,
+  // Error inserting entry in Insert With Literal Name instruction due to entry
+  // size exceeding dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL = 182,
+  // Invalid relative index in Duplicate instruction.
+  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX = 183,
+  // Dynamic entry not found in Duplicate instruction.
+  QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND = 184,
+  // Error in Set Dynamic Table Capacity instruction due to new capacity
+  // exceeding maximum dynamic table capacity.
+  QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY = 185,
+
+  // QPACK decoder stream errors.
+
+  // Variable integer exceeding 2^64-1 received.
+  QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE = 186,
+  // Insert Count Increment instruction received with invalid 0 increment.
+  QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT = 187,
+  // Insert Count Increment instruction causes uint64_t overflow.
+  QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW = 188,
+  // Insert Count Increment instruction increases Known Received Count beyond
+  // inserted entry cound.
+  QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT = 189,
+  // Header Acknowledgement received for stream that has no outstanding header
+  // blocks.
+  QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT = 190,
+
+  // Received stream data beyond close offset.
+  QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET = 129,
+
+  // Received multiple close offset.
+  QUIC_STREAM_MULTIPLE_OFFSET = 130,
+
+  // HTTP/3 errors.
+
+  // Frame payload larger than what HttpDecoder is willing to buffer.
+  QUIC_HTTP_FRAME_TOO_LARGE = 131,
+  // Malformed HTTP/3 frame, or PUSH_PROMISE or CANCEL_PUSH received (which is
+  // an error because MAX_PUSH_ID is never sent).
+  QUIC_HTTP_FRAME_ERROR = 132,
+  // A frame that is never allowed on a request stream is received.
+  QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM = 133,
+  // A frame that is never allowed on the control stream is received.
+  QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM = 134,
+  // An invalid sequence of frames normally allowed on a request stream is
+  // received.
+  QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM = 151,
+  // A second SETTINGS frame is received on the control stream.
+  QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM = 152,
+  // A second instance of a unidirectional stream of a certain type is created.
+  QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM = 153,
+  // Client receives a server-initiated bidirectional stream.
+  QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM = 154,
+  // Server opens stream with stream ID corresponding to client-initiated
+  // stream or vice versa.
+  QUIC_HTTP_STREAM_WRONG_DIRECTION = 155,
+  // Peer closes one of the six critical unidirectional streams (control, QPACK
+  // encoder or decoder, in either direction).
+  QUIC_HTTP_CLOSED_CRITICAL_STREAM = 156,
+  // The first frame received on the control stream is not a SETTINGS frame.
+  QUIC_HTTP_MISSING_SETTINGS_FRAME = 157,
+  // The received SETTINGS frame contains duplicate setting identifiers.
+  QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER = 158,
+  // MAX_PUSH_ID frame received with push ID value smaller than a previously
+  // received value.
+  QUIC_HTTP_INVALID_MAX_PUSH_ID = 159,
+  // Received unidirectional stream limit is lower than required by HTTP/3.
+  QUIC_HTTP_STREAM_LIMIT_TOO_LOW = 160,
+  // Received mismatched SETTINGS frame from HTTP/3 connection where early data
+  // is accepted. Server violated the HTTP/3 spec.
+  QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH = 164,
+  // Received mismatched SETTINGS frame from HTTP/3 connection where early data
+  // is rejected. Our implementation currently doesn't support it.
+  QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH = 165,
+  // Client received GOAWAY frame with stream ID that is not for a
+  // client-initiated bidirectional stream.
+  QUIC_HTTP_GOAWAY_INVALID_STREAM_ID = 166,
+  // Received GOAWAY frame with ID that is greater than previously received ID.
+  QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS = 167,
+  // HTTP/3 session received SETTINGS frame which contains HTTP/2 specific
+  // settings.
+  QUIC_HTTP_RECEIVE_SPDY_SETTING = 169,
+  // HTTP/3 session received an HTTP/2 only frame.
+  QUIC_HTTP_RECEIVE_SPDY_FRAME = 171,
+  // HTTP/3 session received SERVER_PUSH stream, which is an error because
+  // PUSH_PROMISE is not accepted.
+  QUIC_HTTP_RECEIVE_SERVER_PUSH = 205,
+  // HTTP/3 session received invalid SETTING value.
+  QUIC_HTTP_INVALID_SETTING_VALUE = 207,
+
+  // HPACK header block decoding errors.
+  // Index varint beyond implementation limit.
+  QUIC_HPACK_INDEX_VARINT_ERROR = 135,
+  // Name length varint beyond implementation limit.
+  QUIC_HPACK_NAME_LENGTH_VARINT_ERROR = 136,
+  // Value length varint beyond implementation limit.
+  QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR = 137,
+  // Name length exceeds buffer limit.
+  QUIC_HPACK_NAME_TOO_LONG = 138,
+  // Value length exceeds buffer limit.
+  QUIC_HPACK_VALUE_TOO_LONG = 139,
+  // Name Huffman encoding error.
+  QUIC_HPACK_NAME_HUFFMAN_ERROR = 140,
+  // Value Huffman encoding error.
+  QUIC_HPACK_VALUE_HUFFMAN_ERROR = 141,
+  // Next instruction should have been a dynamic table size update.
+  QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE = 142,
+  // Invalid index in indexed header field representation.
+  QUIC_HPACK_INVALID_INDEX = 143,
+  // Invalid index in literal header field with indexed name representation.
+  QUIC_HPACK_INVALID_NAME_INDEX = 144,
+  // Dynamic table size update not allowed.
+  QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED = 145,
+  // Initial dynamic table size update is above low water mark.
+  QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK = 146,
+  // Dynamic table size update is above acknowledged setting.
+  QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING = 147,
+  // HPACK block ends in the middle of an instruction.
+  QUIC_HPACK_TRUNCATED_BLOCK = 148,
+  // Incoming data fragment exceeds buffer limit.
+  QUIC_HPACK_FRAGMENT_TOO_LONG = 149,
+  // Total compressed HPACK data size exceeds limit.
+  QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT = 150,
+
+  // Stream/flow control limit from 1-RTT handshake is too low to retransmit
+  // 0-RTT data. This is our implentation error. We could in theory keep the
+  // connection alive but chose not to for simplicity.
+  QUIC_ZERO_RTT_UNRETRANSMITTABLE = 161,
+  // Stream/flow control limit from 0-RTT rejection reduces cached limit.
+  // This is our implentation error. We could in theory keep the connection
+  // alive but chose not to for simplicity.
+  QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED = 162,
+  // Stream/flow control limit from 0-RTT resumption reduces cached limit.
+  // This is the peer violating QUIC spec.
+  QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED = 163,
+
+  // The connection silently timed out due to no network activity.
+  QUIC_SILENT_IDLE_TIMEOUT = 168,
+
+  // Try to write data without the right write keys.
+  QUIC_MISSING_WRITE_KEYS = 170,
+
+  // An endpoint detected errors in performing key updates.
+  QUIC_KEY_UPDATE_ERROR = 172,
+
+  // An endpoint has reached the confidentiality or integrity limit for the
+  // AEAD algorithm used by the given connection.
+  QUIC_AEAD_LIMIT_REACHED = 173,
+
+  // Connection reached maximum age (regardless of activity), no new requests
+  // are accepted.  This error code is sent in transport layer GOAWAY frame when
+  // using gQUIC, and only used internally when using HTTP/3.  Active requests
+  // are still served, after which connection will be closed due to idle
+  // timeout.
+  QUIC_MAX_AGE_TIMEOUT = 191,
+
+  // Decrypted a 0-RTT packet with a higher packet number than a 1-RTT packet.
+  QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER = 192,
+
+  // Received PRIORITY_UPDATE frame with invalid payload.
+  QUIC_INVALID_PRIORITY_UPDATE = 193,
+
+  // Maps to specific errors from the CRYPTO_ERROR range from
+  // https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
+  // This attempts to choose a subset of the most interesting errors rather
+  // than mapping every possible CRYPTO_ERROR code.
+  QUIC_TLS_BAD_CERTIFICATE = 195,
+  QUIC_TLS_UNSUPPORTED_CERTIFICATE = 196,
+  QUIC_TLS_CERTIFICATE_REVOKED = 197,
+  QUIC_TLS_CERTIFICATE_EXPIRED = 198,
+  QUIC_TLS_CERTIFICATE_UNKNOWN = 199,
+  QUIC_TLS_INTERNAL_ERROR = 200,
+  QUIC_TLS_UNRECOGNIZED_NAME = 201,
+  QUIC_TLS_CERTIFICATE_REQUIRED = 202,
+
+  // An HTTP field value containing an invalid character has been received.
+  QUIC_INVALID_CHARACTER_IN_FIELD_VALUE = 206,
+
+  // Error code related to the usage of TLS keying material export.
+  QUIC_TLS_UNEXPECTED_KEYING_MATERIAL_EXPORT_LABEL = 208,
+  QUIC_TLS_KEYING_MATERIAL_EXPORTS_MISMATCH = 209,
+  QUIC_TLS_KEYING_MATERIAL_EXPORT_NOT_AVAILABLE = 210,
+  QUIC_UNEXPECTED_DATA_BEFORE_ENCRYPTION_ESTABLISHED = 211,
+
+  // No error. Used as bound while iterating.
+  QUIC_LAST_ERROR = 213,
+};
+// QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
+// or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
+// the smaller of the two limits.
+static_assert(static_cast<uint64_t>(QUIC_LAST_ERROR) <=
+                  static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()),
+              "QuicErrorCode exceeds four octets");
+
+// Represents a reason for resetting a stream in both gQUIC and IETF error code
+// space.  Both error codes have to be present.
+class QUIC_EXPORT_PRIVATE QuicResetStreamError {
+ public:
+  // Constructs a QuicResetStreamError from QuicRstStreamErrorCode; the IETF
+  // error code is inferred.
+  static QuicResetStreamError FromInternal(QuicRstStreamErrorCode code);
+  // Constructs a QuicResetStreamError from an IETF error code; the internal
+  // error code is inferred.
+  static QuicResetStreamError FromIetf(uint64_t code);
+  // Constructs a QuicResetStreamError with no error.
+  static QuicResetStreamError NoError() {
+    return FromInternal(QUIC_STREAM_NO_ERROR);
+  }
+
+  QuicResetStreamError(QuicRstStreamErrorCode internal_code,
+                       uint64_t ietf_application_code)
+      : internal_code_(internal_code),
+        ietf_application_code_(ietf_application_code) {}
+
+  QuicRstStreamErrorCode internal_code() const { return internal_code_; }
+  uint64_t ietf_application_code() const { return ietf_application_code_; }
+
+  bool operator==(const QuicResetStreamError& other) const {
+    return internal_code() == other.internal_code() &&
+           ietf_application_code() == other.ietf_application_code();
+  }
+
+  // Returns true if the object holds no error.
+  bool ok() const { return internal_code() == QUIC_STREAM_NO_ERROR; }
+
+ private:
+  // Error code used in gQUIC.  Even when IETF QUIC is in use, this needs to be
+  // populated as we use those internally.
+  QuicRstStreamErrorCode internal_code_;
+  // Application error code used in IETF QUIC.
+  uint64_t ietf_application_code_;
+};
+
+// Convert TLS alert code to QuicErrorCode.
+QUIC_EXPORT_PRIVATE QuicErrorCode TlsAlertToQuicErrorCode(uint8_t desc);
+
+// Returns the name of the QuicRstStreamErrorCode as a char*
+QUIC_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
+    QuicRstStreamErrorCode error);
+
+// Returns the name of the QuicErrorCode as a char*
+QUIC_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
+
+// Wire values for QUIC transport errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes
+enum QuicIetfTransportErrorCodes : uint64_t {
+  NO_IETF_QUIC_ERROR = 0x0,
+  INTERNAL_ERROR = 0x1,
+  SERVER_BUSY_ERROR = 0x2,
+  FLOW_CONTROL_ERROR = 0x3,
+  STREAM_LIMIT_ERROR = 0x4,
+  STREAM_STATE_ERROR = 0x5,
+  FINAL_SIZE_ERROR = 0x6,
+  FRAME_ENCODING_ERROR = 0x7,
+  TRANSPORT_PARAMETER_ERROR = 0x8,
+  CONNECTION_ID_LIMIT_ERROR = 0x9,
+  PROTOCOL_VIOLATION = 0xA,
+  INVALID_TOKEN = 0xB,
+  CRYPTO_BUFFER_EXCEEDED = 0xD,
+  KEY_UPDATE_ERROR = 0xE,
+  AEAD_LIMIT_REACHED = 0xF,
+  CRYPTO_ERROR_FIRST = 0x100,
+  CRYPTO_ERROR_LAST = 0x1FF,
+};
+
+QUIC_EXPORT_PRIVATE std::string QuicIetfTransportErrorCodeString(
+    QuicIetfTransportErrorCodes c);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicIetfTransportErrorCodes& c);
+
+// A transport error code (if is_transport_close is true) or application error
+// code (if is_transport_close is false) to be used in CONNECTION_CLOSE frames.
+struct QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping {
+  bool is_transport_close;
+  uint64_t error_code;
+};
+
+// Convert QuicErrorCode to transport or application IETF error code
+// to be used in CONNECTION_CLOSE frames.
+QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping
+QuicErrorCodeToTransportErrorCode(QuicErrorCode error);
+
+// Wire values for HTTP/3 errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-http.html#http-error-codes
+enum class QuicHttp3ErrorCode {
+  // NO_ERROR is defined as a C preprocessor macro on Windows.
+  HTTP3_NO_ERROR = 0x100,
+  GENERAL_PROTOCOL_ERROR = 0x101,
+  INTERNAL_ERROR = 0x102,
+  STREAM_CREATION_ERROR = 0x103,
+  CLOSED_CRITICAL_STREAM = 0x104,
+  FRAME_UNEXPECTED = 0x105,
+  FRAME_ERROR = 0x106,
+  EXCESSIVE_LOAD = 0x107,
+  ID_ERROR = 0x108,
+  SETTINGS_ERROR = 0x109,
+  MISSING_SETTINGS = 0x10A,
+  REQUEST_REJECTED = 0x10B,
+  REQUEST_CANCELLED = 0x10C,
+  REQUEST_INCOMPLETE = 0x10D,
+  MESSAGE_ERROR = 0x10E,
+  CONNECT_ERROR = 0x10F,
+  VERSION_FALLBACK = 0x110,
+};
+
+// Wire values for QPACK errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#error-code-registration
+enum class QuicHttpQpackErrorCode {
+  DECOMPRESSION_FAILED = 0x200,
+  ENCODER_STREAM_ERROR = 0x201,
+  DECODER_STREAM_ERROR = 0x202
+};
+
+// Convert a QuicRstStreamErrorCode to an application error code to be used in
+// an IETF QUIC RESET_STREAM frame
+QUIC_EXPORT_PRIVATE uint64_t RstStreamErrorCodeToIetfResetStreamErrorCode(
+    QuicRstStreamErrorCode rst_stream_error_code);
+
+// Convert the application error code of an IETF QUIC RESET_STREAM frame
+// to QuicRstStreamErrorCode.
+QUIC_EXPORT_PRIVATE QuicRstStreamErrorCode
+IetfResetStreamErrorCodeToRstStreamErrorCode(uint64_t ietf_error_code);
+
+QUIC_EXPORT_PRIVATE inline std::string HistogramEnumString(
+    QuicErrorCode enum_value) {
+  return QuicErrorCodeToString(enum_value);
+}
+
+QUIC_EXPORT_PRIVATE inline std::string HistogramEnumDescription(
+    QuicErrorCode /*dummy*/) {
+  return "cause";
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ERROR_CODES_H_
diff --git a/quiche/quic/core/quic_error_codes_test.cc b/quiche/quic/core/quic_error_codes_test.cc
new file mode 100644
index 0000000..b888bb7
--- /dev/null
+++ b/quiche/quic/core/quic_error_codes_test.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_error_codes.h"
+
+#include <cstdint>
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using QuicErrorCodesTest = QuicTest;
+
+TEST_F(QuicErrorCodesTest, QuicErrorCodeToString) {
+  EXPECT_STREQ("QUIC_NO_ERROR", QuicErrorCodeToString(QUIC_NO_ERROR));
+}
+
+TEST_F(QuicErrorCodesTest, QuicIetfTransportErrorCodeString) {
+  EXPECT_EQ("CRYPTO_ERROR(missing extension)",
+            QuicIetfTransportErrorCodeString(
+                static_cast<quic::QuicIetfTransportErrorCodes>(
+                    CRYPTO_ERROR_FIRST + SSL_AD_MISSING_EXTENSION)));
+
+  EXPECT_EQ("NO_IETF_QUIC_ERROR",
+            QuicIetfTransportErrorCodeString(NO_IETF_QUIC_ERROR));
+  EXPECT_EQ("INTERNAL_ERROR", QuicIetfTransportErrorCodeString(INTERNAL_ERROR));
+  EXPECT_EQ("SERVER_BUSY_ERROR",
+            QuicIetfTransportErrorCodeString(SERVER_BUSY_ERROR));
+  EXPECT_EQ("FLOW_CONTROL_ERROR",
+            QuicIetfTransportErrorCodeString(FLOW_CONTROL_ERROR));
+  EXPECT_EQ("STREAM_LIMIT_ERROR",
+            QuicIetfTransportErrorCodeString(STREAM_LIMIT_ERROR));
+  EXPECT_EQ("STREAM_STATE_ERROR",
+            QuicIetfTransportErrorCodeString(STREAM_STATE_ERROR));
+  EXPECT_EQ("FINAL_SIZE_ERROR",
+            QuicIetfTransportErrorCodeString(FINAL_SIZE_ERROR));
+  EXPECT_EQ("FRAME_ENCODING_ERROR",
+            QuicIetfTransportErrorCodeString(FRAME_ENCODING_ERROR));
+  EXPECT_EQ("TRANSPORT_PARAMETER_ERROR",
+            QuicIetfTransportErrorCodeString(TRANSPORT_PARAMETER_ERROR));
+  EXPECT_EQ("CONNECTION_ID_LIMIT_ERROR",
+            QuicIetfTransportErrorCodeString(CONNECTION_ID_LIMIT_ERROR));
+  EXPECT_EQ("PROTOCOL_VIOLATION",
+            QuicIetfTransportErrorCodeString(PROTOCOL_VIOLATION));
+  EXPECT_EQ("INVALID_TOKEN", QuicIetfTransportErrorCodeString(INVALID_TOKEN));
+  EXPECT_EQ("CRYPTO_BUFFER_EXCEEDED",
+            QuicIetfTransportErrorCodeString(CRYPTO_BUFFER_EXCEEDED));
+  EXPECT_EQ("KEY_UPDATE_ERROR",
+            QuicIetfTransportErrorCodeString(KEY_UPDATE_ERROR));
+  EXPECT_EQ("AEAD_LIMIT_REACHED",
+            QuicIetfTransportErrorCodeString(AEAD_LIMIT_REACHED));
+
+  EXPECT_EQ("Unknown(1024)",
+            QuicIetfTransportErrorCodeString(
+                static_cast<quic::QuicIetfTransportErrorCodes>(0x400)));
+}
+
+TEST_F(QuicErrorCodesTest, QuicErrorCodeToTransportErrorCode) {
+  for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR;
+       ++internal_error_code) {
+    std::string internal_error_code_string =
+        QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code));
+    if (internal_error_code_string == "INVALID_ERROR_CODE") {
+      // Not a valid QuicErrorCode.
+      continue;
+    }
+    QuicErrorCodeToIetfMapping ietf_error_code =
+        QuicErrorCodeToTransportErrorCode(
+            static_cast<QuicErrorCode>(internal_error_code));
+    if (ietf_error_code.is_transport_close) {
+      QuicIetfTransportErrorCodes transport_error_code =
+          static_cast<QuicIetfTransportErrorCodes>(ietf_error_code.error_code);
+      bool is_transport_crypto_error_code =
+          transport_error_code >= 0x100 && transport_error_code <= 0x1ff;
+      if (is_transport_crypto_error_code) {
+        // Ensure that every QuicErrorCode that maps to a CRYPTO_ERROR code has
+        // a corresponding reverse mapping in TlsAlertToQuicErrorCode:
+        EXPECT_EQ(
+            internal_error_code,
+            TlsAlertToQuicErrorCode(transport_error_code - CRYPTO_ERROR_FIRST));
+      }
+      bool is_valid_transport_error_code =
+          transport_error_code <= 0x0f || is_transport_crypto_error_code;
+      EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string;
+    } else {
+      // Non-transport errors are application errors, either HTTP/3 or QPACK.
+      uint64_t application_error_code = ietf_error_code.error_code;
+      bool is_valid_http3_error_code =
+          application_error_code >= 0x100 && application_error_code <= 0x110;
+      bool is_valid_qpack_error_code =
+          application_error_code >= 0x200 && application_error_code <= 0x202;
+      EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code)
+          << internal_error_code_string;
+    }
+  }
+}
+
+using QuicRstErrorCodesTest = QuicTest;
+
+TEST_F(QuicRstErrorCodesTest, QuicRstStreamErrorCodeToString) {
+  EXPECT_STREQ("QUIC_BAD_APPLICATION_PAYLOAD",
+               QuicRstStreamErrorCodeToString(QUIC_BAD_APPLICATION_PAYLOAD));
+}
+
+// When an IETF application protocol error code (sent on the wire in
+// RESET_STREAM and STOP_SENDING frames) is translated into a
+// QuicRstStreamErrorCode and back, it must yield the original value.
+TEST_F(QuicRstErrorCodesTest,
+       IetfResetStreamErrorCodeToRstStreamErrorCodeAndBack) {
+  for (uint64_t wire_code :
+       {static_cast<uint64_t>(QuicHttp3ErrorCode::HTTP3_NO_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::INTERNAL_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::CLOSED_CRITICAL_STREAM),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_UNEXPECTED),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::FRAME_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::EXCESSIVE_LOAD),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::ID_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::MISSING_SETTINGS),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_REJECTED),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_INCOMPLETE),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::CONNECT_ERROR),
+        static_cast<uint64_t>(QuicHttp3ErrorCode::VERSION_FALLBACK),
+        static_cast<uint64_t>(QuicHttpQpackErrorCode::DECOMPRESSION_FAILED),
+        static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR),
+        static_cast<uint64_t>(QuicHttpQpackErrorCode::DECODER_STREAM_ERROR)}) {
+    QuicRstStreamErrorCode rst_stream_error_code =
+        IetfResetStreamErrorCodeToRstStreamErrorCode(wire_code);
+    EXPECT_EQ(wire_code, RstStreamErrorCodeToIetfResetStreamErrorCode(
+                             rst_stream_error_code));
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
similarity index 100%
rename from quic/core/quic_flags_list.h
rename to quiche/quic/core/quic_flags_list.h
diff --git a/quiche/quic/core/quic_flow_controller.cc b/quiche/quic/core/quic_flow_controller.cc
new file mode 100644
index 0000000..6b5041d
--- /dev/null
+++ b/quiche/quic/core/quic_flow_controller.cc
@@ -0,0 +1,319 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_flow_controller.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+std::string QuicFlowController::LogLabel() {
+  if (is_connection_flow_controller_) {
+    return "connection";
+  }
+  return absl::StrCat("stream ", id_);
+}
+
+QuicFlowController::QuicFlowController(
+    QuicSession* session,
+    QuicStreamId id,
+    bool is_connection_flow_controller,
+    QuicStreamOffset send_window_offset,
+    QuicStreamOffset receive_window_offset,
+    QuicByteCount receive_window_size_limit,
+    bool should_auto_tune_receive_window,
+    QuicFlowControllerInterface* session_flow_controller)
+    : session_(session),
+      connection_(session->connection()),
+      id_(id),
+      is_connection_flow_controller_(is_connection_flow_controller),
+      perspective_(session->perspective()),
+      bytes_sent_(0),
+      send_window_offset_(send_window_offset),
+      bytes_consumed_(0),
+      highest_received_byte_offset_(0),
+      receive_window_offset_(receive_window_offset),
+      receive_window_size_(receive_window_offset),
+      receive_window_size_limit_(receive_window_size_limit),
+      auto_tune_receive_window_(should_auto_tune_receive_window),
+      session_flow_controller_(session_flow_controller),
+      last_blocked_send_window_offset_(0),
+      prev_window_update_time_(QuicTime::Zero()) {
+  QUICHE_DCHECK_LE(receive_window_size_, receive_window_size_limit_);
+  QUICHE_DCHECK_EQ(
+      is_connection_flow_controller_,
+      QuicUtils::GetInvalidStreamId(session_->transport_version()) == id_);
+
+  QUIC_DVLOG(1) << ENDPOINT << "Created flow controller for " << LogLabel()
+                << ", setting initial receive window offset to: "
+                << receive_window_offset_
+                << ", max receive window to: " << receive_window_size_
+                << ", max receive window limit to: "
+                << receive_window_size_limit_
+                << ", setting send window offset to: " << send_window_offset_;
+}
+
+void QuicFlowController::AddBytesConsumed(QuicByteCount bytes_consumed) {
+  bytes_consumed_ += bytes_consumed;
+  QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " consumed " << bytes_consumed_
+                << " bytes.";
+
+  MaybeSendWindowUpdate();
+}
+
+bool QuicFlowController::UpdateHighestReceivedOffset(
+    QuicStreamOffset new_offset) {
+  // Only update if offset has increased.
+  if (new_offset <= highest_received_byte_offset_) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << LogLabel()
+                << " highest byte offset increased from "
+                << highest_received_byte_offset_ << " to " << new_offset;
+  highest_received_byte_offset_ = new_offset;
+  return true;
+}
+
+void QuicFlowController::AddBytesSent(QuicByteCount bytes_sent) {
+  if (bytes_sent_ + bytes_sent > send_window_offset_) {
+    QUIC_BUG(quic_bug_10836_1)
+        << ENDPOINT << LogLabel() << " Trying to send an extra " << bytes_sent
+        << " bytes, when bytes_sent = " << bytes_sent_
+        << ", and send_window_offset_ = " << send_window_offset_;
+    bytes_sent_ = send_window_offset_;
+
+    // This is an error on our side, close the connection as soon as possible.
+    connection_->CloseConnection(
+        QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA,
+        absl::StrCat(send_window_offset_ - (bytes_sent_ + bytes_sent),
+                     "bytes over send window offset"),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  bytes_sent_ += bytes_sent;
+  QUIC_DVLOG(1) << ENDPOINT << LogLabel() << " sent " << bytes_sent_
+                << " bytes.";
+}
+
+bool QuicFlowController::FlowControlViolation() {
+  if (highest_received_byte_offset_ > receive_window_offset_) {
+    QUIC_DLOG(INFO) << ENDPOINT << "Flow control violation on " << LogLabel()
+                    << ", receive window offset: " << receive_window_offset_
+                    << ", highest received byte offset: "
+                    << highest_received_byte_offset_;
+    return true;
+  }
+  return false;
+}
+
+void QuicFlowController::MaybeIncreaseMaxWindowSize() {
+  // Core of receive window auto tuning.  This method should be called before a
+  // WINDOW_UPDATE frame is sent.  Ideally, window updates should occur close to
+  // once per RTT.  If a window update happens much faster than RTT, it implies
+  // that the flow control window is imposing a bottleneck.  To prevent this,
+  // this method will increase the receive window size (subject to a reasonable
+  // upper bound).  For simplicity this algorithm is deliberately asymmetric, in
+  // that it may increase window size but never decreases.
+
+  // Keep track of timing between successive window updates.
+  QuicTime now = connection_->clock()->ApproximateNow();
+  QuicTime prev = prev_window_update_time_;
+  prev_window_update_time_ = now;
+  if (!prev.IsInitialized()) {
+    QUIC_DVLOG(1) << ENDPOINT << "first window update for " << LogLabel();
+    return;
+  }
+
+  if (!auto_tune_receive_window_) {
+    return;
+  }
+
+  // Get outbound RTT.
+  QuicTime::Delta rtt =
+      connection_->sent_packet_manager().GetRttStats()->smoothed_rtt();
+  if (rtt.IsZero()) {
+    QUIC_DVLOG(1) << ENDPOINT << "rtt zero for " << LogLabel();
+    return;
+  }
+
+  // Now we can compare timing of window updates with RTT.
+  QuicTime::Delta since_last = now - prev;
+  QuicTime::Delta two_rtt = 2 * rtt;
+
+  if (since_last >= two_rtt) {
+    // If interval between window updates is sufficiently large, there
+    // is no need to increase receive_window_size_.
+    return;
+  }
+  QuicByteCount old_window = receive_window_size_;
+  IncreaseWindowSize();
+
+  if (receive_window_size_ > old_window) {
+    QUIC_DVLOG(1) << ENDPOINT << "New max window increase for " << LogLabel()
+                  << " after " << since_last.ToMicroseconds()
+                  << " us, and RTT is " << rtt.ToMicroseconds()
+                  << "us. max wndw: " << receive_window_size_;
+    if (session_flow_controller_ != nullptr) {
+      session_flow_controller_->EnsureWindowAtLeast(
+          kSessionFlowControlMultiplier * receive_window_size_);
+    }
+  } else {
+    // TODO(ckrasic) - add a varz to track this (?).
+    QUIC_LOG_FIRST_N(INFO, 1)
+        << ENDPOINT << "Max window at limit for " << LogLabel() << " after "
+        << since_last.ToMicroseconds() << " us, and RTT is "
+        << rtt.ToMicroseconds() << "us. Limit size: " << receive_window_size_;
+  }
+}
+
+void QuicFlowController::IncreaseWindowSize() {
+  receive_window_size_ *= 2;
+  receive_window_size_ =
+      std::min(receive_window_size_, receive_window_size_limit_);
+}
+
+QuicByteCount QuicFlowController::WindowUpdateThreshold() {
+  return receive_window_size_ / 2;
+}
+
+void QuicFlowController::MaybeSendWindowUpdate() {
+  if (!session_->connection()->connected()) {
+    return;
+  }
+  // Send WindowUpdate to increase receive window if
+  // (receive window offset - consumed bytes) < (max window / 2).
+  // This is behaviour copied from SPDY.
+  QUICHE_DCHECK_LE(bytes_consumed_, receive_window_offset_);
+  QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
+  QuicByteCount threshold = WindowUpdateThreshold();
+
+  if (!prev_window_update_time_.IsInitialized()) {
+    // Treat the initial window as if it is a window update, so if 1/2 the
+    // window is used in less than 2 RTTs, the window is increased.
+    prev_window_update_time_ = connection_->clock()->ApproximateNow();
+  }
+
+  if (available_window >= threshold) {
+    QUIC_DVLOG(1) << ENDPOINT << "Not sending WindowUpdate for " << LogLabel()
+                  << ", available window: " << available_window
+                  << " >= threshold: " << threshold;
+    return;
+  }
+
+  MaybeIncreaseMaxWindowSize();
+  UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
+}
+
+void QuicFlowController::UpdateReceiveWindowOffsetAndSendWindowUpdate(
+    QuicStreamOffset available_window) {
+  // Update our receive window.
+  receive_window_offset_ += (receive_window_size_ - available_window);
+
+  QUIC_DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for " << LogLabel()
+                << ", consumed bytes: " << bytes_consumed_
+                << ", available window: " << available_window
+                << ", and threshold: " << WindowUpdateThreshold()
+                << ", and receive window size: " << receive_window_size_
+                << ". New receive window offset is: " << receive_window_offset_;
+
+  SendWindowUpdate();
+}
+
+bool QuicFlowController::ShouldSendBlocked() {
+  if (SendWindowSize() != 0 ||
+      last_blocked_send_window_offset_ >= send_window_offset_) {
+    return false;
+  }
+  QUIC_DLOG(INFO) << ENDPOINT << LogLabel() << " is flow control blocked. "
+                  << "Send window: " << SendWindowSize()
+                  << ", bytes sent: " << bytes_sent_
+                  << ", send limit: " << send_window_offset_;
+  // The entire send_window has been consumed, we are now flow control
+  // blocked.
+
+  // Keep track of when we last sent a BLOCKED frame so that we only send one
+  // at a given send offset.
+  last_blocked_send_window_offset_ = send_window_offset_;
+  return true;
+}
+
+bool QuicFlowController::UpdateSendWindowOffset(
+    QuicStreamOffset new_send_window_offset) {
+  // Only update if send window has increased.
+  if (new_send_window_offset <= send_window_offset_) {
+    return false;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for " << LogLabel()
+                << " with new offset " << new_send_window_offset
+                << " current offset: " << send_window_offset_
+                << " bytes_sent: " << bytes_sent_;
+
+  // The flow is now unblocked but could have also been unblocked
+  // before.  Return true iff this update caused a change from blocked
+  // to unblocked.
+  const bool was_previously_blocked = IsBlocked();
+  send_window_offset_ = new_send_window_offset;
+  return was_previously_blocked;
+}
+
+void QuicFlowController::EnsureWindowAtLeast(QuicByteCount window_size) {
+  if (receive_window_size_limit_ >= window_size) {
+    return;
+  }
+
+  QuicStreamOffset available_window = receive_window_offset_ - bytes_consumed_;
+  IncreaseWindowSize();
+  UpdateReceiveWindowOffsetAndSendWindowUpdate(available_window);
+}
+
+bool QuicFlowController::IsBlocked() const {
+  return SendWindowSize() == 0;
+}
+
+uint64_t QuicFlowController::SendWindowSize() const {
+  if (bytes_sent_ > send_window_offset_) {
+    return 0;
+  }
+  return send_window_offset_ - bytes_sent_;
+}
+
+void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) {
+  QUICHE_DCHECK_LE(size, receive_window_size_limit_);
+  QUIC_DVLOG(1) << ENDPOINT << "UpdateReceiveWindowSize for " << LogLabel()
+                << ": " << size;
+  if (receive_window_size_ != receive_window_offset_) {
+    QUIC_BUG(quic_bug_10836_2)
+        << "receive_window_size_:" << receive_window_size_
+        << " != receive_window_offset:" << receive_window_offset_;
+    return;
+  }
+  receive_window_size_ = size;
+  receive_window_offset_ = size;
+}
+
+void QuicFlowController::SendWindowUpdate() {
+  QuicStreamId id = id_;
+  if (is_connection_flow_controller_) {
+    id = QuicUtils::GetInvalidStreamId(connection_->transport_version());
+  }
+  session_->SendWindowUpdate(id, receive_window_offset_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_flow_controller.h b/quiche/quic/core/quic_flow_controller.h
new file mode 100644
index 0000000..69a4e94
--- /dev/null
+++ b/quiche/quic/core/quic_flow_controller.h
@@ -0,0 +1,217 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
+#define QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicFlowControllerPeer;
+}  // namespace test
+
+class QuicConnection;
+class QuicSession;
+
+// How much larger the session flow control window needs to be relative to any
+// stream's flow control window.
+const float kSessionFlowControlMultiplier = 1.5;
+
+class QUIC_EXPORT_PRIVATE QuicFlowControllerInterface {
+ public:
+  virtual ~QuicFlowControllerInterface() {}
+
+  // Ensures the flow control window is at least |window_size| and send out an
+  // update frame if it is increased.
+  virtual void EnsureWindowAtLeast(QuicByteCount window_size) = 0;
+};
+
+// QuicFlowController allows a QUIC stream or connection to perform flow
+// control. The stream/connection owns a QuicFlowController which keeps track of
+// bytes sent/received, can tell the owner if it is flow control blocked, and
+// can send WINDOW_UPDATE or BLOCKED frames when needed.
+class QUIC_EXPORT_PRIVATE QuicFlowController
+    : public QuicFlowControllerInterface {
+ public:
+  QuicFlowController(QuicSession* session,
+                     QuicStreamId id,
+                     bool is_connection_flow_controller,
+                     QuicStreamOffset send_window_offset,
+                     QuicStreamOffset receive_window_offset,
+                     QuicByteCount receive_window_size_limit,
+                     bool should_auto_tune_receive_window,
+                     QuicFlowControllerInterface* session_flow_controller);
+
+  QuicFlowController(const QuicFlowController&) = delete;
+  QuicFlowController(QuicFlowController&&) = default;
+  QuicFlowController& operator=(const QuicFlowController&) = delete;
+
+  ~QuicFlowController() override {}
+
+  // Called when we see a new highest received byte offset from the peer, either
+  // via a data frame or a RST.
+  // Returns true if this call changes highest_received_byte_offset_, and false
+  // in the case where |new_offset| is <= highest_received_byte_offset_.
+  bool UpdateHighestReceivedOffset(QuicStreamOffset new_offset);
+
+  // Called when bytes received from the peer are consumed locally. This may
+  // trigger the sending of a WINDOW_UPDATE frame using |connection|.
+  void AddBytesConsumed(QuicByteCount bytes_consumed);
+
+  // Called when bytes are sent to the peer.
+  void AddBytesSent(QuicByteCount bytes_sent);
+
+  // Increases |send_window_offset_| if |new_send_window_offset| is
+  // greater than the current value.  Returns true if this increase
+  // also causes us to change from a blocked state to unblocked.  In
+  // all other cases, returns false.
+  bool UpdateSendWindowOffset(QuicStreamOffset new_send_window_offset);
+
+  // QuicFlowControllerInterface.
+  void EnsureWindowAtLeast(QuicByteCount window_size) override;
+
+  // Returns the current available send window.
+  QuicByteCount SendWindowSize() const;
+
+  QuicByteCount receive_window_size() const { return receive_window_size_; }
+
+  // Returns whether a BLOCKED frame should be sent.
+  bool ShouldSendBlocked();
+
+  // Returns true if flow control send limits have been reached.
+  bool IsBlocked() const;
+
+  // Returns true if flow control receive limits have been violated by the peer.
+  bool FlowControlViolation();
+
+  // Inform the peer of new receive window.
+  void SendWindowUpdate();
+
+  QuicByteCount bytes_consumed() const { return bytes_consumed_; }
+
+  QuicByteCount bytes_sent() const { return bytes_sent_; }
+
+  QuicStreamOffset send_window_offset() const { return send_window_offset_; }
+
+  QuicStreamOffset highest_received_byte_offset() const {
+    return highest_received_byte_offset_;
+  }
+
+  void set_receive_window_size_limit(QuicByteCount receive_window_size_limit) {
+    QUICHE_DCHECK_GE(receive_window_size_limit, receive_window_size_limit_);
+    receive_window_size_limit_ = receive_window_size_limit;
+  }
+
+  // Should only be called before any data is received.
+  void UpdateReceiveWindowSize(QuicStreamOffset size);
+
+  bool auto_tune_receive_window() { return auto_tune_receive_window_; }
+
+ private:
+  friend class test::QuicFlowControllerPeer;
+
+  // Send a WINDOW_UPDATE frame if appropriate.
+  void MaybeSendWindowUpdate();
+
+  // Auto-tune the max receive window size.
+  void MaybeIncreaseMaxWindowSize();
+
+  // Updates the current offset and sends a window update frame.
+  void UpdateReceiveWindowOffsetAndSendWindowUpdate(
+      QuicStreamOffset available_window);
+
+  // Double the window size as long as we haven't hit the max window size.
+  void IncreaseWindowSize();
+
+  // Returns "stream $ID" (where $ID is set to |id_|) or "connection" based on
+  // |is_connection_flow_controller_|.
+  std::string LogLabel();
+
+  // The parent session/connection, used to send connection close on flow
+  // control violation, and WINDOW_UPDATE and BLOCKED frames when appropriate.
+  // Not owned.
+  QuicSession* session_;
+  QuicConnection* connection_;
+
+  // ID of stream this flow controller belongs to. If
+  // |is_connection_flow_controller_| is false, this must be a valid stream ID.
+  QuicStreamId id_;
+
+  // Whether this flow controller is the connection level flow controller
+  // instead of the flow controller for a stream. If true, |id_| is ignored.
+  bool is_connection_flow_controller_;
+
+  // Tracks if this is owned by a server or a client.
+  Perspective perspective_;
+
+  // Tracks number of bytes sent to the peer.
+  QuicByteCount bytes_sent_;
+
+  // The absolute offset in the outgoing byte stream. If this offset is reached
+  // then we become flow control blocked until we receive a WINDOW_UPDATE.
+  QuicStreamOffset send_window_offset_;
+
+  // Overview of receive flow controller.
+  //
+  // 0=...===1=======2-------3 ...... FIN
+  //         |<--- <= 4  --->|
+  //
+
+  // 1) bytes_consumed_ - moves forward when data is read out of the
+  //    stream.
+  //
+  // 2) highest_received_byte_offset_ - moves when data is received
+  //    from the peer.
+  //
+  // 3) receive_window_offset_ - moves when WINDOW_UPDATE is sent.
+  //
+  // 4) receive_window_size_ - maximum allowed unread data (3 - 1).
+  //    This value may be increased by auto-tuning.
+  //
+  // 5) receive_window_size_limit_ - limit on receive_window_size_;
+  //    auto-tuning will not increase window size beyond this limit.
+
+  // Track number of bytes received from the peer, which have been consumed
+  // locally.
+  QuicByteCount bytes_consumed_;
+
+  // The highest byte offset we have seen from the peer. This could be the
+  // highest offset in a data frame, or a final value in a RST.
+  QuicStreamOffset highest_received_byte_offset_;
+
+  // The absolute offset in the incoming byte stream. The peer should never send
+  // us bytes which are beyond this offset.
+  QuicStreamOffset receive_window_offset_;
+
+  // Largest size the receive window can grow to.
+  QuicByteCount receive_window_size_;
+
+  // Upper limit on receive_window_size_;
+  QuicByteCount receive_window_size_limit_;
+
+  // Used to dynamically enable receive window auto-tuning.
+  bool auto_tune_receive_window_;
+
+  // The session's flow controller. Null if this is the session flow controller.
+  // Not owned.
+  QuicFlowControllerInterface* session_flow_controller_;
+
+  // Send window update when receive window size drops below this.
+  QuicByteCount WindowUpdateThreshold();
+
+  // Keep track of the last time we sent a BLOCKED frame. We should only send
+  // another when the number of bytes we have sent has changed.
+  QuicStreamOffset last_blocked_send_window_offset_;
+
+  // Keep time of the last time a window update was sent.  We use this
+  // as part of the receive window auto tuning.
+  QuicTime prev_window_update_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
diff --git a/quiche/quic/core/quic_flow_controller_test.cc b/quiche/quic/core/quic_flow_controller_test.cc
new file mode 100644
index 0000000..20cb599
--- /dev/null
+++ b/quiche/quic/core/quic_flow_controller_test.cc
@@ -0,0 +1,408 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_flow_controller.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+
+// Receive window auto-tuning uses RTT in its logic.
+const int64_t kRtt = 100;
+
+class MockFlowController : public QuicFlowControllerInterface {
+ public:
+  MockFlowController() {}
+  MockFlowController(const MockFlowController&) = delete;
+  MockFlowController& operator=(const MockFlowController&) = delete;
+  ~MockFlowController() override {}
+
+  MOCK_METHOD(void, EnsureWindowAtLeast, (QuicByteCount), (override));
+};
+
+class QuicFlowControllerTest : public QuicTest {
+ public:
+  void Initialize() {
+    connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
+                                         Perspective::IS_CLIENT);
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<MockQuicSession>(connection_);
+    flow_controller_ = std::make_unique<QuicFlowController>(
+        session_.get(), stream_id_, /*is_connection_flow_controller*/ false,
+        send_window_, receive_window_, kStreamReceiveWindowLimit,
+        should_auto_tune_receive_window_, &session_flow_controller_);
+  }
+
+ protected:
+  QuicStreamId stream_id_ = 1234;
+  QuicByteCount send_window_ = kInitialSessionFlowControlWindowForTest;
+  QuicByteCount receive_window_ = kInitialSessionFlowControlWindowForTest;
+  std::unique_ptr<QuicFlowController> flow_controller_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<MockQuicSession> session_;
+  MockFlowController session_flow_controller_;
+  bool should_auto_tune_receive_window_ = false;
+};
+
+TEST_F(QuicFlowControllerTest, SendingBytes) {
+  Initialize();
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Send some bytes, but not enough to block.
+  flow_controller_->AddBytesSent(send_window_ / 2);
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
+
+  // Send enough bytes to block.
+  flow_controller_->AddBytesSent(send_window_ / 2);
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+
+  // BLOCKED frame should get sent.
+  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+
+  // Update the send window, and verify this has unblocked.
+  EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Updating with a smaller offset doesn't change anything.
+  EXPECT_FALSE(flow_controller_->UpdateSendWindowOffset(send_window_ / 10));
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Try to send more bytes, violating flow control.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _, _));
+  EXPECT_QUIC_BUG(
+      flow_controller_->AddBytesSent(send_window_ * 10),
+      absl::StrCat("Trying to send an extra ", send_window_ * 10, " bytes"));
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytes) {
+  Initialize();
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(
+      flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ((receive_window_ / 2) - 1,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Consume enough bytes to send a WINDOW_UPDATE frame.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
+
+  flow_controller_->AddBytesConsumed(1 + receive_window_ / 2);
+
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+}
+
+TEST_F(QuicFlowControllerTest, Move) {
+  Initialize();
+
+  flow_controller_->AddBytesSent(send_window_ / 2);
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize());
+
+  EXPECT_TRUE(
+      flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ((receive_window_ / 2) - 1,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicFlowController flow_controller2(std::move(*flow_controller_));
+  EXPECT_EQ(send_window_ / 2, flow_controller2.SendWindowSize());
+  EXPECT_FALSE(flow_controller2.FlowControlViolation());
+  EXPECT_EQ((receive_window_ / 2) - 1,
+            QuicFlowControllerPeer::ReceiveWindowSize(&flow_controller2));
+}
+
+TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
+  Initialize();
+
+  // Test that we don't send duplicate BLOCKED frames. We should only send one
+  // BLOCKED frame at a given send window offset.
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+
+  // Send enough bytes to block.
+  flow_controller_->AddBytesSent(send_window_);
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+
+  // BLOCKED frame should get sent.
+  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+
+  // BLOCKED frame should not get sent again until our send offset changes.
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+  EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+
+  // Update the send window, then send enough bytes to block again.
+  EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
+  flow_controller_->AddBytesSent(send_window_);
+  EXPECT_TRUE(flow_controller_->IsBlocked());
+  EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+
+  // BLOCKED frame should get sent as send offset has changed.
+  EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
+  should_auto_tune_receive_window_ = true;
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
+  EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+  EXPECT_CALL(
+      session_flow_controller_,
+      EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
+
+  // Consume enough bytes to send a WINDOW_UPDATE frame.
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+  EXPECT_GT(new_threshold, threshold);
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) {
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Consume enough bytes to send a WINDOW_UPDATE frame.
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Move time forward, but by less than two RTTs.  Then receive and consume
+  // some more, forcing a second WINDOW_UPDATE with an increased max window
+  // size.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt - 1));
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+  EXPECT_EQ(new_threshold, threshold);
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) {
+  should_auto_tune_receive_window_ = true;
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _)).Times(1);
+  EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+  EXPECT_CALL(
+      session_flow_controller_,
+      EnsureWindowAtLeast(kInitialSessionFlowControlWindowForTest * 2 * 1.5));
+  flow_controller_->AddBytesConsumed(threshold + 1);
+
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(2 * kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Move time forward, but by more than two RTTs.  Then receive and consume
+  // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
+
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+  EXPECT_EQ(new_threshold, 2 * threshold);
+}
+
+TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) {
+  Initialize();
+  // This test will generate two WINDOW_UPDATE frames.
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+  EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
+
+  // Make sure clock is inititialized.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicSentPacketManager* manager =
+      QuicConnectionPeer::GetSentPacketManager(connection_);
+  RttStats* rtt_stats = const_cast<RttStats*>(manager->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRtt),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_FALSE(flow_controller_->IsBlocked());
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  QuicByteCount threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  QuicStreamOffset receive_offset = threshold + 1;
+  // Receive some bytes, updating highest received offset, but not enough to
+  // fill flow control receive window.
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest - receive_offset,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  flow_controller_->AddBytesConsumed(threshold + 1);
+
+  // Result is that once again we have a fully open receive window.
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
+            QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
+
+  // Move time forward, but by more than two RTTs.  Then receive and consume
+  // some more, forcing a second WINDOW_UPDATE with unchanged max window size.
+  connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(2 * kRtt + 1));
+
+  receive_offset += threshold + 1;
+  EXPECT_TRUE(flow_controller_->UpdateHighestReceivedOffset(receive_offset));
+
+  flow_controller_->AddBytesConsumed(threshold + 1);
+  EXPECT_FALSE(flow_controller_->FlowControlViolation());
+
+  QuicByteCount new_threshold =
+      QuicFlowControllerPeer::WindowUpdateThreshold(flow_controller_.get());
+
+  EXPECT_EQ(new_threshold, threshold);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_framer.cc b/quiche/quic/core/quic_framer.cc
new file mode 100644
index 0000000..193ceff
--- /dev/null
+++ b/quiche/quic/core/quic_framer.cc
@@ -0,0 +1,7244 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_framer.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_socket_address_coder.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+namespace {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+// Number of bits the packet number length bits are shifted from the right
+// edge of the header.
+const uint8_t kPublicHeaderSequenceNumberShift = 4;
+
+// There are two interpretations for the Frame Type byte in the QUIC protocol,
+// resulting in two Frame Types: Special Frame Types and Regular Frame Types.
+//
+// Regular Frame Types use the Frame Type byte simply. Currently defined
+// Regular Frame Types are:
+// Padding            : 0b 00000000 (0x00)
+// ResetStream        : 0b 00000001 (0x01)
+// ConnectionClose    : 0b 00000010 (0x02)
+// GoAway             : 0b 00000011 (0x03)
+// WindowUpdate       : 0b 00000100 (0x04)
+// Blocked            : 0b 00000101 (0x05)
+//
+// Special Frame Types encode both a Frame Type and corresponding flags
+// all in the Frame Type byte. Currently defined Special Frame Types
+// are:
+// Stream             : 0b 1xxxxxxx
+// Ack                : 0b 01xxxxxx
+//
+// Semantics of the flag bits above (the x bits) depends on the frame type.
+
+// Masks to determine if the frame type is a special use
+// and for specific special frame types.
+const uint8_t kQuicFrameTypeBrokenMask = 0xE0;   // 0b 11100000
+const uint8_t kQuicFrameTypeSpecialMask = 0xC0;  // 0b 11000000
+const uint8_t kQuicFrameTypeStreamMask = 0x80;
+const uint8_t kQuicFrameTypeAckMask = 0x40;
+static_assert(kQuicFrameTypeSpecialMask ==
+                  (kQuicFrameTypeStreamMask | kQuicFrameTypeAckMask),
+              "Invalid kQuicFrameTypeSpecialMask");
+
+// The stream type format is 1FDOOOSS, where
+//    F is the fin bit.
+//    D is the data length bit (0 or 2 bytes).
+//    OO/OOO are the size of the offset.
+//    SS is the size of the stream ID.
+// Note that the stream encoding can not be determined by inspection. It can
+// be determined only by knowing the QUIC Version.
+// Stream frame relative shifts and masks for interpreting the stream flags.
+// StreamID may be 1, 2, 3, or 4 bytes.
+const uint8_t kQuicStreamIdShift = 2;
+const uint8_t kQuicStreamIDLengthMask = 0x03;
+
+// Offset may be 0, 2, 4, or 8 bytes.
+const uint8_t kQuicStreamShift = 3;
+const uint8_t kQuicStreamOffsetMask = 0x07;
+
+// Data length may be 0 or 2 bytes.
+const uint8_t kQuicStreamDataLengthShift = 1;
+const uint8_t kQuicStreamDataLengthMask = 0x01;
+
+// Fin bit may be set or not.
+const uint8_t kQuicStreamFinShift = 1;
+const uint8_t kQuicStreamFinMask = 0x01;
+
+// The format is 01M0LLOO, where
+//   M if set, there are multiple ack blocks in the frame.
+//  LL is the size of the largest ack field.
+//  OO is the size of the ack blocks offset field.
+// packet number size shift used in AckFrames.
+const uint8_t kQuicSequenceNumberLengthNumBits = 2;
+const uint8_t kActBlockLengthOffset = 0;
+const uint8_t kLargestAckedOffset = 2;
+
+// Acks may have only one ack block.
+const uint8_t kQuicHasMultipleAckBlocksOffset = 5;
+
+// Timestamps are 4 bytes followed by 2 bytes.
+const uint8_t kQuicNumTimestampsLength = 1;
+const uint8_t kQuicFirstTimestampLength = 4;
+const uint8_t kQuicTimestampLength = 2;
+// Gaps between packet numbers are 1 byte.
+const uint8_t kQuicTimestampPacketNumberGapLength = 1;
+
+// Maximum length of encoded error strings.
+const int kMaxErrorStringLength = 256;
+
+const uint8_t kConnectionIdLengthAdjustment = 3;
+const uint8_t kDestinationConnectionIdLengthMask = 0xF0;
+const uint8_t kSourceConnectionIdLengthMask = 0x0F;
+
+// Returns the absolute value of the difference between |a| and |b|.
+uint64_t Delta(uint64_t a, uint64_t b) {
+  // Since these are unsigned numbers, we can't just return abs(a - b)
+  if (a < b) {
+    return b - a;
+  }
+  return a - b;
+}
+
+uint64_t ClosestTo(uint64_t target, uint64_t a, uint64_t b) {
+  return (Delta(target, a) < Delta(target, b)) ? a : b;
+}
+
+QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
+  switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
+    case PACKET_FLAGS_8BYTE_PACKET:
+      return PACKET_6BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_4BYTE_PACKET:
+      return PACKET_4BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_2BYTE_PACKET:
+      return PACKET_2BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_1BYTE_PACKET:
+      return PACKET_1BYTE_PACKET_NUMBER;
+    default:
+      QUIC_BUG(quic_bug_10850_1) << "Unreachable case statement.";
+      return PACKET_6BYTE_PACKET_NUMBER;
+  }
+}
+
+QuicPacketNumberLength ReadAckPacketNumberLength(uint8_t flags) {
+  switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
+    case PACKET_FLAGS_8BYTE_PACKET:
+      return PACKET_6BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_4BYTE_PACKET:
+      return PACKET_4BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_2BYTE_PACKET:
+      return PACKET_2BYTE_PACKET_NUMBER;
+    case PACKET_FLAGS_1BYTE_PACKET:
+      return PACKET_1BYTE_PACKET_NUMBER;
+    default:
+      QUIC_BUG(quic_bug_10850_2) << "Unreachable case statement.";
+      return PACKET_6BYTE_PACKET_NUMBER;
+  }
+}
+
+uint8_t PacketNumberLengthToOnWireValue(
+    QuicPacketNumberLength packet_number_length) {
+  return packet_number_length - 1;
+}
+
+QuicPacketNumberLength GetShortHeaderPacketNumberLength(uint8_t type) {
+  QUICHE_DCHECK(!(type & FLAGS_LONG_HEADER));
+  return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
+}
+
+uint8_t LongHeaderTypeToOnWireValue(QuicLongHeaderType type,
+                                    const ParsedQuicVersion& version) {
+  switch (type) {
+    case INITIAL:
+      return version.UsesV2PacketTypes() ? (1 << 4) : 0;
+    case ZERO_RTT_PROTECTED:
+      return version.UsesV2PacketTypes() ? (2 << 4) : (1 << 4);
+    case HANDSHAKE:
+      return version.UsesV2PacketTypes() ? (3 << 4) : (2 << 4);
+    case RETRY:
+      return version.UsesV2PacketTypes() ? 0 : (3 << 4);
+    case VERSION_NEGOTIATION:
+      return 0xF0;  // Value does not matter
+    default:
+      QUIC_BUG(quic_bug_10850_3) << "Invalid long header type: " << type;
+      return 0xFF;
+  }
+}
+
+QuicLongHeaderType GetLongHeaderType(uint8_t type,
+                                     const ParsedQuicVersion& version) {
+  QUICHE_DCHECK((type & FLAGS_LONG_HEADER));
+  switch ((type & 0x30) >> 4) {
+    case 0:
+      return version.UsesV2PacketTypes() ? RETRY : INITIAL;
+    case 1:
+      return version.UsesV2PacketTypes() ? INITIAL : ZERO_RTT_PROTECTED;
+    case 2:
+      return version.UsesV2PacketTypes() ? ZERO_RTT_PROTECTED : HANDSHAKE;
+    case 3:
+      return version.UsesV2PacketTypes() ? HANDSHAKE : RETRY;
+    default:
+      QUIC_BUG(quic_bug_10850_4) << "Unreachable statement";
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+QuicPacketNumberLength GetLongHeaderPacketNumberLength(uint8_t type) {
+  return static_cast<QuicPacketNumberLength>((type & 0x03) + 1);
+}
+
+// Used to get packet number space before packet gets decrypted.
+PacketNumberSpace GetPacketNumberSpace(const QuicPacketHeader& header) {
+  switch (header.form) {
+    case GOOGLE_QUIC_PACKET:
+      QUIC_BUG(quic_bug_10850_5)
+          << "Try to get packet number space of Google QUIC packet";
+      break;
+    case IETF_QUIC_SHORT_HEADER_PACKET:
+      return APPLICATION_DATA;
+    case IETF_QUIC_LONG_HEADER_PACKET:
+      switch (header.long_packet_type) {
+        case INITIAL:
+          return INITIAL_DATA;
+        case HANDSHAKE:
+          return HANDSHAKE_DATA;
+        case ZERO_RTT_PROTECTED:
+          return APPLICATION_DATA;
+        case VERSION_NEGOTIATION:
+        case RETRY:
+        case INVALID_PACKET_TYPE:
+          QUIC_BUG(quic_bug_10850_6)
+              << "Try to get packet number space of long header type: "
+              << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
+          break;
+      }
+  }
+
+  return NUM_PACKET_NUMBER_SPACES;
+}
+
+EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) {
+  switch (header.form) {
+    case GOOGLE_QUIC_PACKET:
+      QUIC_BUG(quic_bug_10850_7)
+          << "Cannot determine EncryptionLevel from Google QUIC header";
+      break;
+    case IETF_QUIC_SHORT_HEADER_PACKET:
+      return ENCRYPTION_FORWARD_SECURE;
+    case IETF_QUIC_LONG_HEADER_PACKET:
+      switch (header.long_packet_type) {
+        case INITIAL:
+          return ENCRYPTION_INITIAL;
+        case HANDSHAKE:
+          return ENCRYPTION_HANDSHAKE;
+        case ZERO_RTT_PROTECTED:
+          return ENCRYPTION_ZERO_RTT;
+        case VERSION_NEGOTIATION:
+        case RETRY:
+        case INVALID_PACKET_TYPE:
+          QUIC_BUG(quic_bug_10850_8)
+              << "No encryption used with type "
+              << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
+      }
+  }
+  return NUM_ENCRYPTION_LEVELS;
+}
+
+absl::string_view TruncateErrorString(absl::string_view error) {
+  if (error.length() <= kMaxErrorStringLength) {
+    return error;
+  }
+  return absl::string_view(error.data(), kMaxErrorStringLength);
+}
+
+size_t TruncatedErrorStringSize(const absl::string_view& error) {
+  if (error.length() < kMaxErrorStringLength) {
+    return error.length();
+  }
+  return kMaxErrorStringLength;
+}
+
+uint8_t GetConnectionIdLengthValue(QuicConnectionIdLength length) {
+  if (length == 0) {
+    return 0;
+  }
+  return static_cast<uint8_t>(length - kConnectionIdLengthAdjustment);
+}
+
+bool IsValidPacketNumberLength(QuicPacketNumberLength packet_number_length) {
+  size_t length = packet_number_length;
+  return length == 1 || length == 2 || length == 4 || length == 6 ||
+         length == 8;
+}
+
+bool IsValidFullPacketNumber(uint64_t full_packet_number,
+                             ParsedQuicVersion version) {
+  return full_packet_number > 0 || version.HasIetfQuicFrames();
+}
+
+bool AppendIetfConnectionIds(bool version_flag, bool use_length_prefix,
+                             QuicConnectionId destination_connection_id,
+                             QuicConnectionId source_connection_id,
+                             QuicDataWriter* writer) {
+  if (!version_flag) {
+    return writer->WriteConnectionId(destination_connection_id);
+  }
+
+  if (use_length_prefix) {
+    return writer->WriteLengthPrefixedConnectionId(destination_connection_id) &&
+           writer->WriteLengthPrefixedConnectionId(source_connection_id);
+  }
+
+  // Compute connection ID length byte.
+  uint8_t dcil = GetConnectionIdLengthValue(
+      static_cast<QuicConnectionIdLength>(destination_connection_id.length()));
+  uint8_t scil = GetConnectionIdLengthValue(
+      static_cast<QuicConnectionIdLength>(source_connection_id.length()));
+  uint8_t connection_id_length = dcil << 4 | scil;
+
+  return writer->WriteUInt8(connection_id_length) &&
+         writer->WriteConnectionId(destination_connection_id) &&
+         writer->WriteConnectionId(source_connection_id);
+}
+
+enum class DroppedPacketReason {
+  // General errors
+  INVALID_PUBLIC_HEADER,
+  VERSION_MISMATCH,
+  // Version negotiation packet errors
+  INVALID_VERSION_NEGOTIATION_PACKET,
+  // Public reset packet errors, pre-v44
+  INVALID_PUBLIC_RESET_PACKET,
+  // Data packet errors
+  INVALID_PACKET_NUMBER,
+  INVALID_DIVERSIFICATION_NONCE,
+  DECRYPTION_FAILURE,
+  NUM_REASONS,
+};
+
+void RecordDroppedPacketReason(DroppedPacketReason reason) {
+  QUIC_CLIENT_HISTOGRAM_ENUM("QuicDroppedPacketReason", reason,
+                             DroppedPacketReason::NUM_REASONS,
+                             "The reason a packet was not processed. Recorded "
+                             "each time such a packet is dropped");
+}
+
+PacketHeaderFormat GetIetfPacketHeaderFormat(uint8_t type_byte) {
+  return type_byte & FLAGS_LONG_HEADER ? IETF_QUIC_LONG_HEADER_PACKET
+                                       : IETF_QUIC_SHORT_HEADER_PACKET;
+}
+
+std::string GenerateErrorString(std::string initial_error_string,
+                                QuicErrorCode quic_error_code) {
+  if (quic_error_code == QUIC_IETF_GQUIC_ERROR_MISSING) {
+    // QUIC_IETF_GQUIC_ERROR_MISSING is special -- it means not to encode
+    // the error value in the string.
+    return initial_error_string;
+  }
+  return absl::StrCat(std::to_string(static_cast<unsigned>(quic_error_code)),
+                      ":", initial_error_string);
+}
+
+}  // namespace
+
+QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
+                       QuicTime creation_time, Perspective perspective,
+                       uint8_t expected_server_connection_id_length)
+    : visitor_(nullptr),
+      error_(QUIC_NO_ERROR),
+      last_serialized_server_connection_id_(EmptyQuicConnectionId()),
+      last_serialized_client_connection_id_(EmptyQuicConnectionId()),
+      version_(ParsedQuicVersion::Unsupported()),
+      supported_versions_(supported_versions),
+      decrypter_level_(ENCRYPTION_INITIAL),
+      alternative_decrypter_level_(NUM_ENCRYPTION_LEVELS),
+      alternative_decrypter_latch_(false),
+      perspective_(perspective),
+      validate_flags_(true),
+      process_timestamps_(false),
+      max_receive_timestamps_per_ack_(std::numeric_limits<uint32_t>::max()),
+      receive_timestamps_exponent_(0),
+      creation_time_(creation_time),
+      last_timestamp_(QuicTime::Delta::Zero()),
+      support_key_update_for_connection_(false),
+      current_key_phase_bit_(false),
+      potential_peer_key_update_attempt_count_(0),
+      first_sending_packet_number_(FirstSendingPacketNumber()),
+      data_producer_(nullptr),
+      infer_packet_header_type_from_version_(perspective ==
+                                             Perspective::IS_CLIENT),
+      expected_server_connection_id_length_(
+          expected_server_connection_id_length),
+      expected_client_connection_id_length_(0),
+      supports_multiple_packet_number_spaces_(false),
+      last_written_packet_number_length_(0),
+      peer_ack_delay_exponent_(kDefaultAckDelayExponent),
+      local_ack_delay_exponent_(kDefaultAckDelayExponent),
+      current_received_frame_type_(0),
+      previously_received_frame_type_(0) {
+  QUICHE_DCHECK(!supported_versions.empty());
+  version_ = supported_versions_[0];
+  QUICHE_DCHECK(version_.IsKnown())
+      << ParsedQuicVersionVectorToString(supported_versions_);
+}
+
+QuicFramer::~QuicFramer() {}
+
+// static
+size_t QuicFramer::GetMinStreamFrameSize(QuicTransportVersion version,
+                                         QuicStreamId stream_id,
+                                         QuicStreamOffset offset,
+                                         bool last_frame_in_packet,
+                                         size_t data_length) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(stream_id) +
+           (last_frame_in_packet
+                ? 0
+                : QuicDataWriter::GetVarInt62Len(data_length)) +
+           (offset != 0 ? QuicDataWriter::GetVarInt62Len(offset) : 0);
+  }
+  return kQuicFrameTypeSize + GetStreamIdSize(stream_id) +
+         GetStreamOffsetSize(offset) +
+         (last_frame_in_packet ? 0 : kQuicStreamPayloadLengthSize);
+}
+
+// static
+size_t QuicFramer::GetMinCryptoFrameSize(QuicStreamOffset offset,
+                                         QuicPacketLength data_length) {
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(offset) +
+         QuicDataWriter::GetVarInt62Len(data_length);
+}
+
+// static
+size_t QuicFramer::GetMessageFrameSize(QuicTransportVersion version,
+                                       bool last_frame_in_packet,
+                                       QuicByteCount length) {
+  QUIC_BUG_IF(quic_bug_12975_1, !VersionSupportsMessageFrames(version))
+      << "Try to serialize MESSAGE frame in " << version;
+  return kQuicFrameTypeSize +
+         (last_frame_in_packet ? 0 : QuicDataWriter::GetVarInt62Len(length)) +
+         length;
+}
+
+// static
+size_t QuicFramer::GetMinAckFrameSize(
+    QuicTransportVersion version, const QuicAckFrame& ack_frame,
+    uint32_t local_ack_delay_exponent,
+    bool use_ietf_ack_with_receive_timestamp) {
+  if (VersionHasIetfQuicFrames(version)) {
+    // The minimal ack frame consists of the following fields: Largest
+    // Acknowledged, ACK Delay, 0 ACK Block Count, First ACK Block and either 0
+    // Timestamp Range Count or ECN counts.
+    // Type byte + largest acked.
+    size_t min_size =
+        kQuicFrameTypeSize +
+        QuicDataWriter::GetVarInt62Len(LargestAcked(ack_frame).ToUint64());
+    // Ack delay.
+    min_size += QuicDataWriter::GetVarInt62Len(
+        ack_frame.ack_delay_time.ToMicroseconds() >> local_ack_delay_exponent);
+    // 0 ack block count.
+    min_size += QuicDataWriter::GetVarInt62Len(0);
+    // First ack block.
+    min_size += QuicDataWriter::GetVarInt62Len(
+        ack_frame.packets.Empty() ? 0
+                                  : ack_frame.packets.rbegin()->Length() - 1);
+
+    if (use_ietf_ack_with_receive_timestamp) {
+      // 0 Timestamp Range Count.
+      min_size += QuicDataWriter::GetVarInt62Len(0);
+    } else if (ack_frame.ecn_counters_populated &&
+               (ack_frame.ect_0_count || ack_frame.ect_1_count ||
+                ack_frame.ecn_ce_count)) {
+      // ECN counts.
+      min_size += (QuicDataWriter::GetVarInt62Len(ack_frame.ect_0_count) +
+                   QuicDataWriter::GetVarInt62Len(ack_frame.ect_1_count) +
+                   QuicDataWriter::GetVarInt62Len(ack_frame.ecn_ce_count));
+    }
+    return min_size;
+  }
+  return kQuicFrameTypeSize +
+         GetMinPacketNumberLength(LargestAcked(ack_frame)) +
+         kQuicDeltaTimeLargestObservedSize + kQuicNumTimestampsSize;
+}
+
+// static
+size_t QuicFramer::GetStopWaitingFrameSize(
+    QuicPacketNumberLength packet_number_length) {
+  size_t min_size = kQuicFrameTypeSize + packet_number_length;
+  return min_size;
+}
+
+// static
+size_t QuicFramer::GetRstStreamFrameSize(QuicTransportVersion version,
+                                         const QuicRstStreamFrame& frame) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return QuicDataWriter::GetVarInt62Len(frame.stream_id) +
+           QuicDataWriter::GetVarInt62Len(frame.byte_offset) +
+           kQuicFrameTypeSize +
+           QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
+  }
+  return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
+         kQuicErrorCodeSize;
+}
+
+// static
+size_t QuicFramer::GetConnectionCloseFrameSize(
+    QuicTransportVersion version, const QuicConnectionCloseFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    // Not IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
+    return kQuicFrameTypeSize + kQuicErrorCodeSize +
+           kQuicErrorDetailsLengthSize +
+           TruncatedErrorStringSize(frame.error_details);
+  }
+
+  // Prepend the extra error information to the string and get the result's
+  // length.
+  const size_t truncated_error_string_size = TruncatedErrorStringSize(
+      GenerateErrorString(frame.error_details, frame.quic_error_code));
+
+  const size_t frame_size =
+      truncated_error_string_size +
+      QuicDataWriter::GetVarInt62Len(truncated_error_string_size) +
+      kQuicFrameTypeSize +
+      QuicDataWriter::GetVarInt62Len(frame.wire_error_code);
+  if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    return frame_size;
+  }
+  // The Transport close frame has the transport_close_frame_type, so include
+  // its length.
+  return frame_size +
+         QuicDataWriter::GetVarInt62Len(frame.transport_close_frame_type);
+}
+
+// static
+size_t QuicFramer::GetMinGoAwayFrameSize() {
+  return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
+         kQuicMaxStreamIdSize;
+}
+
+// static
+size_t QuicFramer::GetWindowUpdateFrameSize(
+    QuicTransportVersion version, const QuicWindowUpdateFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
+  }
+  if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
+    // Frame would be a MAX DATA frame, which has only a Maximum Data field.
+    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data);
+  }
+  // Frame would be MAX STREAM DATA, has Maximum Stream Data and Stream ID
+  // fields.
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.max_data) +
+         QuicDataWriter::GetVarInt62Len(frame.stream_id);
+}
+
+// static
+size_t QuicFramer::GetMaxStreamsFrameSize(QuicTransportVersion version,
+                                          const QuicMaxStreamsFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    QUIC_BUG(quic_bug_10850_9)
+        << "In version " << version
+        << ", which does not support IETF Frames, and tried to serialize "
+           "MaxStreams Frame.";
+  }
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.stream_count);
+}
+
+// static
+size_t QuicFramer::GetStreamsBlockedFrameSize(
+    QuicTransportVersion version, const QuicStreamsBlockedFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    QUIC_BUG(quic_bug_10850_10)
+        << "In version " << version
+        << ", which does not support IETF frames, and tried to serialize "
+           "StreamsBlocked Frame.";
+  }
+
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.stream_count);
+}
+
+// static
+size_t QuicFramer::GetBlockedFrameSize(QuicTransportVersion version,
+                                       const QuicBlockedFrame& frame) {
+  if (!VersionHasIetfQuicFrames(version)) {
+    return kQuicFrameTypeSize + kQuicMaxStreamIdSize;
+  }
+  if (frame.stream_id == QuicUtils::GetInvalidStreamId(version)) {
+    // return size of IETF QUIC Blocked frame
+    return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset);
+  }
+  // return size of IETF QUIC Stream Blocked frame.
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.offset) +
+         QuicDataWriter::GetVarInt62Len(frame.stream_id);
+}
+
+// static
+size_t QuicFramer::GetStopSendingFrameSize(const QuicStopSendingFrame& frame) {
+  return kQuicFrameTypeSize + QuicDataWriter::GetVarInt62Len(frame.stream_id) +
+         QuicDataWriter::GetVarInt62Len(frame.ietf_error_code);
+}
+
+// static
+size_t QuicFramer::GetAckFrequencyFrameSize(
+    const QuicAckFrequencyFrame& frame) {
+  return QuicDataWriter::GetVarInt62Len(IETF_ACK_FREQUENCY) +
+         QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
+         QuicDataWriter::GetVarInt62Len(frame.packet_tolerance) +
+         QuicDataWriter::GetVarInt62Len(frame.max_ack_delay.ToMicroseconds()) +
+         // One byte for encoding boolean
+         1;
+}
+
+// static
+size_t QuicFramer::GetPathChallengeFrameSize(
+    const QuicPathChallengeFrame& frame) {
+  return kQuicFrameTypeSize + sizeof(frame.data_buffer);
+}
+
+// static
+size_t QuicFramer::GetPathResponseFrameSize(
+    const QuicPathResponseFrame& frame) {
+  return kQuicFrameTypeSize + sizeof(frame.data_buffer);
+}
+
+// static
+size_t QuicFramer::GetRetransmittableControlFrameSize(
+    QuicTransportVersion version, const QuicFrame& frame) {
+  switch (frame.type) {
+    case PING_FRAME:
+      // Ping has no payload.
+      return kQuicFrameTypeSize;
+    case RST_STREAM_FRAME:
+      return GetRstStreamFrameSize(version, *frame.rst_stream_frame);
+    case CONNECTION_CLOSE_FRAME:
+      return GetConnectionCloseFrameSize(version,
+                                         *frame.connection_close_frame);
+    case GOAWAY_FRAME:
+      return GetMinGoAwayFrameSize() +
+             TruncatedErrorStringSize(frame.goaway_frame->reason_phrase);
+    case WINDOW_UPDATE_FRAME:
+      // For IETF QUIC, this could be either a MAX DATA or MAX STREAM DATA.
+      // GetWindowUpdateFrameSize figures this out and returns the correct
+      // length.
+      return GetWindowUpdateFrameSize(version, frame.window_update_frame);
+    case BLOCKED_FRAME:
+      return GetBlockedFrameSize(version, frame.blocked_frame);
+    case NEW_CONNECTION_ID_FRAME:
+      return GetNewConnectionIdFrameSize(*frame.new_connection_id_frame);
+    case RETIRE_CONNECTION_ID_FRAME:
+      return GetRetireConnectionIdFrameSize(*frame.retire_connection_id_frame);
+    case NEW_TOKEN_FRAME:
+      return GetNewTokenFrameSize(*frame.new_token_frame);
+    case MAX_STREAMS_FRAME:
+      return GetMaxStreamsFrameSize(version, frame.max_streams_frame);
+    case STREAMS_BLOCKED_FRAME:
+      return GetStreamsBlockedFrameSize(version, frame.streams_blocked_frame);
+    case PATH_RESPONSE_FRAME:
+      return GetPathResponseFrameSize(*frame.path_response_frame);
+    case PATH_CHALLENGE_FRAME:
+      return GetPathChallengeFrameSize(*frame.path_challenge_frame);
+    case STOP_SENDING_FRAME:
+      return GetStopSendingFrameSize(frame.stop_sending_frame);
+    case HANDSHAKE_DONE_FRAME:
+      // HANDSHAKE_DONE has no payload.
+      return kQuicFrameTypeSize;
+    case ACK_FREQUENCY_FRAME:
+      return GetAckFrequencyFrameSize(*frame.ack_frequency_frame);
+    case STREAM_FRAME:
+    case ACK_FRAME:
+    case STOP_WAITING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case PADDING_FRAME:
+    case MESSAGE_FRAME:
+    case CRYPTO_FRAME:
+    case NUM_FRAME_TYPES:
+      QUICHE_DCHECK(false);
+      return 0;
+  }
+
+  // Not reachable, but some Chrome compilers can't figure that out.  *sigh*
+  QUICHE_DCHECK(false);
+  return 0;
+}
+
+// static
+size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) {
+  // Sizes are 1 through 4 bytes.
+  for (int i = 1; i <= 4; ++i) {
+    stream_id >>= 8;
+    if (stream_id == 0) {
+      return i;
+    }
+  }
+  QUIC_BUG(quic_bug_10850_11) << "Failed to determine StreamIDSize.";
+  return 4;
+}
+
+// static
+size_t QuicFramer::GetStreamOffsetSize(QuicStreamOffset offset) {
+  // 0 is a special case.
+  if (offset == 0) {
+    return 0;
+  }
+  // 2 through 8 are the remaining sizes.
+  offset >>= 8;
+  for (int i = 2; i <= 8; ++i) {
+    offset >>= 8;
+    if (offset == 0) {
+      return i;
+    }
+  }
+  QUIC_BUG(quic_bug_10850_12) << "Failed to determine StreamOffsetSize.";
+  return 8;
+}
+
+// static
+size_t QuicFramer::GetNewConnectionIdFrameSize(
+    const QuicNewConnectionIdFrame& frame) {
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
+         QuicDataWriter::GetVarInt62Len(frame.retire_prior_to) +
+         kConnectionIdLengthSize + frame.connection_id.length() +
+         sizeof(frame.stateless_reset_token);
+}
+
+// static
+size_t QuicFramer::GetRetireConnectionIdFrameSize(
+    const QuicRetireConnectionIdFrame& frame) {
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.sequence_number);
+}
+
+// static
+size_t QuicFramer::GetNewTokenFrameSize(const QuicNewTokenFrame& frame) {
+  return kQuicFrameTypeSize +
+         QuicDataWriter::GetVarInt62Len(frame.token.length()) +
+         frame.token.length();
+}
+
+// TODO(nharper): Change this method to take a ParsedQuicVersion.
+bool QuicFramer::IsSupportedTransportVersion(
+    const QuicTransportVersion version) const {
+  for (const ParsedQuicVersion& supported_version : supported_versions_) {
+    if (version == supported_version.transport_version) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicFramer::IsSupportedVersion(const ParsedQuicVersion version) const {
+  for (const ParsedQuicVersion& supported_version : supported_versions_) {
+    if (version == supported_version) {
+      return true;
+    }
+  }
+  return false;
+}
+
+size_t QuicFramer::GetSerializedFrameLength(
+    const QuicFrame& frame, size_t free_bytes, bool first_frame,
+    bool last_frame, QuicPacketNumberLength packet_number_length) {
+  // Prevent a rare crash reported in b/19458523.
+  if (frame.type == ACK_FRAME && frame.ack_frame == nullptr) {
+    QUIC_BUG(quic_bug_10850_13)
+        << "Cannot compute the length of a null ack frame. free_bytes:"
+        << free_bytes << " first_frame:" << first_frame
+        << " last_frame:" << last_frame
+        << " seq num length:" << packet_number_length;
+    set_error(QUIC_INTERNAL_ERROR);
+    visitor_->OnError(this);
+    return 0;
+  }
+  if (frame.type == PADDING_FRAME) {
+    if (frame.padding_frame.num_padding_bytes == -1) {
+      // Full padding to the end of the packet.
+      return free_bytes;
+    } else {
+      // Lite padding.
+      return free_bytes <
+                     static_cast<size_t>(frame.padding_frame.num_padding_bytes)
+                 ? free_bytes
+                 : frame.padding_frame.num_padding_bytes;
+    }
+  }
+
+  size_t frame_len =
+      ComputeFrameLength(frame, last_frame, packet_number_length);
+  if (frame_len <= free_bytes) {
+    // Frame fits within packet. Note that acks may be truncated.
+    return frame_len;
+  }
+  // Only truncate the first frame in a packet, so if subsequent ones go
+  // over, stop including more frames.
+  if (!first_frame) {
+    return 0;
+  }
+  bool can_truncate =
+      frame.type == ACK_FRAME &&
+      free_bytes >=
+          GetMinAckFrameSize(version_.transport_version, *frame.ack_frame,
+                             local_ack_delay_exponent_,
+                             UseIetfAckWithReceiveTimestamp(*frame.ack_frame));
+  if (can_truncate) {
+    // Truncate the frame so the packet will not exceed kMaxOutgoingPacketSize.
+    // Note that we may not use every byte of the writer in this case.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Truncating large frame, free bytes: " << free_bytes;
+    return free_bytes;
+  }
+  return 0;
+}
+
+QuicFramer::AckFrameInfo::AckFrameInfo()
+    : max_block_length(0), first_block_length(0), num_ack_blocks(0) {}
+
+QuicFramer::AckFrameInfo::AckFrameInfo(const AckFrameInfo& other) = default;
+
+QuicFramer::AckFrameInfo::~AckFrameInfo() {}
+
+bool QuicFramer::WriteIetfLongHeaderLength(const QuicPacketHeader& header,
+                                           QuicDataWriter* writer,
+                                           size_t length_field_offset,
+                                           EncryptionLevel level) {
+  if (!QuicVersionHasLongHeaderLengths(transport_version()) ||
+      !header.version_flag || length_field_offset == 0) {
+    return true;
+  }
+  if (writer->length() < length_field_offset ||
+      writer->length() - length_field_offset <
+          kQuicDefaultLongHeaderLengthLength) {
+    set_detailed_error("Invalid length_field_offset.");
+    QUIC_BUG(quic_bug_10850_14) << "Invalid length_field_offset.";
+    return false;
+  }
+  size_t length_to_write = writer->length() - length_field_offset -
+                           kQuicDefaultLongHeaderLengthLength;
+  // Add length of auth tag.
+  length_to_write = GetCiphertextSize(level, length_to_write);
+
+  QuicDataWriter length_writer(writer->length() - length_field_offset,
+                               writer->data() + length_field_offset);
+  if (!length_writer.WriteVarInt62(length_to_write,
+                                   kQuicDefaultLongHeaderLengthLength)) {
+    set_detailed_error("Failed to overwrite long header length.");
+    QUIC_BUG(quic_bug_10850_15) << "Failed to overwrite long header length.";
+    return false;
+  }
+  return true;
+}
+
+size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
+                                   const QuicFrames& frames, char* buffer,
+                                   size_t packet_length,
+                                   EncryptionLevel level) {
+  QUIC_BUG_IF(quic_bug_12975_2,
+              header.version_flag && version().HasIetfInvariantHeader() &&
+                  header.long_packet_type == RETRY && !frames.empty())
+      << "IETF RETRY packets cannot contain frames " << header;
+  QuicDataWriter writer(packet_length, buffer);
+  size_t length_field_offset = 0;
+  if (!AppendPacketHeader(header, &writer, &length_field_offset)) {
+    QUIC_BUG(quic_bug_10850_16) << "AppendPacketHeader failed";
+    return 0;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    if (AppendIetfFrames(frames, &writer) == 0) {
+      return 0;
+    }
+    if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset,
+                                   level)) {
+      return 0;
+    }
+    return writer.length();
+  }
+
+  size_t i = 0;
+  for (const QuicFrame& frame : frames) {
+    // Determine if we should write stream frame length in header.
+    const bool last_frame_in_packet = i == frames.size() - 1;
+    if (!AppendTypeByte(frame, last_frame_in_packet, &writer)) {
+      QUIC_BUG(quic_bug_10850_17) << "AppendTypeByte failed";
+      return 0;
+    }
+
+    switch (frame.type) {
+      case PADDING_FRAME:
+        if (!AppendPaddingFrame(frame.padding_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_18)
+              << "AppendPaddingFrame of "
+              << frame.padding_frame.num_padding_bytes << " failed";
+          return 0;
+        }
+        break;
+      case STREAM_FRAME:
+        if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
+                               &writer)) {
+          QUIC_BUG(quic_bug_10850_19) << "AppendStreamFrame failed";
+          return 0;
+        }
+        break;
+      case ACK_FRAME:
+        if (!AppendAckFrameAndTypeByte(*frame.ack_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_20)
+              << "AppendAckFrameAndTypeByte failed: " << detailed_error_;
+          return 0;
+        }
+        break;
+      case STOP_WAITING_FRAME:
+        if (!AppendStopWaitingFrame(header, frame.stop_waiting_frame,
+                                    &writer)) {
+          QUIC_BUG(quic_bug_10850_21) << "AppendStopWaitingFrame failed";
+          return 0;
+        }
+        break;
+      case MTU_DISCOVERY_FRAME:
+        // MTU discovery frames are serialized as ping frames.
+        ABSL_FALLTHROUGH_INTENDED;
+      case PING_FRAME:
+        // Ping has no payload.
+        break;
+      case RST_STREAM_FRAME:
+        if (!AppendRstStreamFrame(*frame.rst_stream_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_22) << "AppendRstStreamFrame failed";
+          return 0;
+        }
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        if (!AppendConnectionCloseFrame(*frame.connection_close_frame,
+                                        &writer)) {
+          QUIC_BUG(quic_bug_10850_23) << "AppendConnectionCloseFrame failed";
+          return 0;
+        }
+        break;
+      case GOAWAY_FRAME:
+        if (!AppendGoAwayFrame(*frame.goaway_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_24) << "AppendGoAwayFrame failed";
+          return 0;
+        }
+        break;
+      case WINDOW_UPDATE_FRAME:
+        if (!AppendWindowUpdateFrame(frame.window_update_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_25) << "AppendWindowUpdateFrame failed";
+          return 0;
+        }
+        break;
+      case BLOCKED_FRAME:
+        if (!AppendBlockedFrame(frame.blocked_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_26) << "AppendBlockedFrame failed";
+          return 0;
+        }
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        set_detailed_error(
+            "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case RETIRE_CONNECTION_ID_FRAME:
+        set_detailed_error(
+            "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF "
+            "QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case NEW_TOKEN_FRAME:
+        set_detailed_error(
+            "Attempt to append NEW_TOKEN_ID frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case MAX_STREAMS_FRAME:
+        set_detailed_error(
+            "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case STREAMS_BLOCKED_FRAME:
+        set_detailed_error(
+            "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case PATH_RESPONSE_FRAME:
+        set_detailed_error(
+            "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case PATH_CHALLENGE_FRAME:
+        set_detailed_error(
+            "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case STOP_SENDING_FRAME:
+        set_detailed_error(
+            "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      case MESSAGE_FRAME:
+        if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
+                                           last_frame_in_packet, &writer)) {
+          QUIC_BUG(quic_bug_10850_27) << "AppendMessageFrame failed";
+          return 0;
+        }
+        break;
+      case CRYPTO_FRAME:
+        if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
+          set_detailed_error(
+              "Attempt to append CRYPTO frame in version prior to 47.");
+          return RaiseError(QUIC_INTERNAL_ERROR);
+        }
+        if (!AppendCryptoFrame(*frame.crypto_frame, &writer)) {
+          QUIC_BUG(quic_bug_10850_28) << "AppendCryptoFrame failed";
+          return 0;
+        }
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        // HANDSHAKE_DONE has no payload.
+        break;
+      default:
+        RaiseError(QUIC_INVALID_FRAME_DATA);
+        QUIC_BUG(quic_bug_10850_29) << "QUIC_INVALID_FRAME_DATA";
+        return 0;
+    }
+    ++i;
+  }
+
+  if (!WriteIetfLongHeaderLength(header, &writer, length_field_offset, level)) {
+    return 0;
+  }
+
+  return writer.length();
+}
+
+size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames,
+                                    QuicDataWriter* writer) {
+  size_t i = 0;
+  for (const QuicFrame& frame : frames) {
+    // Determine if we should write stream frame length in header.
+    const bool last_frame_in_packet = i == frames.size() - 1;
+    if (!AppendIetfFrameType(frame, last_frame_in_packet, writer)) {
+      QUIC_BUG(quic_bug_10850_30)
+          << "AppendIetfFrameType failed: " << detailed_error();
+      return 0;
+    }
+
+    switch (frame.type) {
+      case PADDING_FRAME:
+        if (!AppendPaddingFrame(frame.padding_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_31) << "AppendPaddingFrame of "
+                                      << frame.padding_frame.num_padding_bytes
+                                      << " failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STREAM_FRAME:
+        if (!AppendStreamFrame(frame.stream_frame, last_frame_in_packet,
+                               writer)) {
+          QUIC_BUG(quic_bug_10850_32)
+              << "AppendStreamFrame " << frame.stream_frame
+              << " failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case ACK_FRAME:
+        if (!AppendIetfAckFrameAndTypeByte(*frame.ack_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_33)
+              << "AppendIetfAckFrameAndTypeByte failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STOP_WAITING_FRAME:
+        set_detailed_error(
+            "Attempt to append STOP WAITING frame in IETF QUIC.");
+        RaiseError(QUIC_INTERNAL_ERROR);
+        QUIC_BUG(quic_bug_10850_34) << detailed_error();
+        return 0;
+      case MTU_DISCOVERY_FRAME:
+        // MTU discovery frames are serialized as ping frames.
+        ABSL_FALLTHROUGH_INTENDED;
+      case PING_FRAME:
+        // Ping has no payload.
+        break;
+      case RST_STREAM_FRAME:
+        if (!AppendRstStreamFrame(*frame.rst_stream_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_35)
+              << "AppendRstStreamFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case CONNECTION_CLOSE_FRAME:
+        if (!AppendIetfConnectionCloseFrame(*frame.connection_close_frame,
+                                            writer)) {
+          QUIC_BUG(quic_bug_10850_36)
+              << "AppendIetfConnectionCloseFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case GOAWAY_FRAME:
+        set_detailed_error("Attempt to append GOAWAY frame in IETF QUIC.");
+        RaiseError(QUIC_INTERNAL_ERROR);
+        QUIC_BUG(quic_bug_10850_37) << detailed_error();
+        return 0;
+      case WINDOW_UPDATE_FRAME:
+        // Depending on whether there is a stream ID or not, will be either a
+        // MAX STREAM DATA frame or a MAX DATA frame.
+        if (frame.window_update_frame.stream_id ==
+            QuicUtils::GetInvalidStreamId(transport_version())) {
+          if (!AppendMaxDataFrame(frame.window_update_frame, writer)) {
+            QUIC_BUG(quic_bug_10850_38)
+                << "AppendMaxDataFrame failed: " << detailed_error();
+            return 0;
+          }
+        } else {
+          if (!AppendMaxStreamDataFrame(frame.window_update_frame, writer)) {
+            QUIC_BUG(quic_bug_10850_39)
+                << "AppendMaxStreamDataFrame failed: " << detailed_error();
+            return 0;
+          }
+        }
+        break;
+      case BLOCKED_FRAME:
+        if (!AppendBlockedFrame(frame.blocked_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_40)
+              << "AppendBlockedFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case MAX_STREAMS_FRAME:
+        if (!AppendMaxStreamsFrame(frame.max_streams_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_41)
+              << "AppendMaxStreamsFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STREAMS_BLOCKED_FRAME:
+        if (!AppendStreamsBlockedFrame(frame.streams_blocked_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_42)
+              << "AppendStreamsBlockedFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case NEW_CONNECTION_ID_FRAME:
+        if (!AppendNewConnectionIdFrame(*frame.new_connection_id_frame,
+                                        writer)) {
+          QUIC_BUG(quic_bug_10850_43)
+              << "AppendNewConnectionIdFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case RETIRE_CONNECTION_ID_FRAME:
+        if (!AppendRetireConnectionIdFrame(*frame.retire_connection_id_frame,
+                                           writer)) {
+          QUIC_BUG(quic_bug_10850_44)
+              << "AppendRetireConnectionIdFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case NEW_TOKEN_FRAME:
+        if (!AppendNewTokenFrame(*frame.new_token_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_45)
+              << "AppendNewTokenFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case STOP_SENDING_FRAME:
+        if (!AppendStopSendingFrame(frame.stop_sending_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_46)
+              << "AppendStopSendingFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case PATH_CHALLENGE_FRAME:
+        if (!AppendPathChallengeFrame(*frame.path_challenge_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_47)
+              << "AppendPathChallengeFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case PATH_RESPONSE_FRAME:
+        if (!AppendPathResponseFrame(*frame.path_response_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_48)
+              << "AppendPathResponseFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case MESSAGE_FRAME:
+        if (!AppendMessageFrameAndTypeByte(*frame.message_frame,
+                                           last_frame_in_packet, writer)) {
+          QUIC_BUG(quic_bug_10850_49)
+              << "AppendMessageFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case CRYPTO_FRAME:
+        if (!AppendCryptoFrame(*frame.crypto_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_50)
+              << "AppendCryptoFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      case HANDSHAKE_DONE_FRAME:
+        // HANDSHAKE_DONE has no payload.
+        break;
+      case ACK_FREQUENCY_FRAME:
+        if (!AppendAckFrequencyFrame(*frame.ack_frequency_frame, writer)) {
+          QUIC_BUG(quic_bug_10850_51)
+              << "AppendAckFrequencyFrame failed: " << detailed_error();
+          return 0;
+        }
+        break;
+      default:
+        set_detailed_error("Tried to append unknown frame type.");
+        RaiseError(QUIC_INVALID_FRAME_DATA);
+        QUIC_BUG(quic_bug_10850_52)
+            << "QUIC_INVALID_FRAME_DATA: " << frame.type;
+        return 0;
+    }
+    ++i;
+  }
+
+  return writer->length();
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildPublicResetPacket(
+    const QuicPublicResetPacket& packet) {
+  CryptoHandshakeMessage reset;
+  reset.set_tag(kPRST);
+  reset.SetValue(kRNON, packet.nonce_proof);
+  if (packet.client_address.host().address_family() !=
+      IpAddressFamily::IP_UNSPEC) {
+    // packet.client_address is non-empty.
+    QuicSocketAddressCoder address_coder(packet.client_address);
+    std::string serialized_address = address_coder.Encode();
+    if (serialized_address.empty()) {
+      return nullptr;
+    }
+    reset.SetStringPiece(kCADR, serialized_address);
+  }
+  if (!packet.endpoint_id.empty()) {
+    reset.SetStringPiece(kEPID, packet.endpoint_id);
+  }
+  const QuicData& reset_serialized = reset.GetSerialized();
+
+  size_t len = kPublicFlagsSize + packet.connection_id.length() +
+               reset_serialized.length();
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+
+  uint8_t flags = static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_RST |
+                                       PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID);
+  // This hack makes post-v33 public reset packet look like pre-v33 packets.
+  flags |= static_cast<uint8_t>(PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
+  if (!writer.WriteUInt8(flags)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteConnectionId(packet.connection_id)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteBytes(reset_serialized.data(), reset_serialized.length())) {
+    return nullptr;
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
+}
+
+// static
+size_t QuicFramer::GetMinStatelessResetPacketLength() {
+  // 5 bytes (40 bits) = 2 Fixed Bits (01) + 38 Unpredictable bits
+  return 5 + kStatelessResetTokenLength;
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildIetfStatelessResetPacket(
+    QuicConnectionId /*connection_id*/, size_t received_packet_length,
+    StatelessResetToken stateless_reset_token) {
+  QUIC_DVLOG(1) << "Building IETF stateless reset packet.";
+  if (received_packet_length <= GetMinStatelessResetPacketLength()) {
+    QUICHE_DLOG(ERROR)
+        << "Tried to build stateless reset packet with received packet "
+           "length "
+        << received_packet_length;
+    return nullptr;
+  }
+  // To ensure stateless reset is indistinguishable from a valid packet,
+  // include the max connection ID length.
+  size_t len = std::min(received_packet_length - 1,
+                        GetMinStatelessResetPacketLength() + 1 +
+                            kQuicMaxConnectionIdWithLengthPrefixLength);
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+  // Append random bytes. This randomness only exists to prevent middleboxes
+  // from comparing the entire packet to a known value. Therefore it has no
+  // cryptographic use, and does not need a secure cryptographic pseudo-random
+  // number generator. It's therefore safe to use WriteInsecureRandomBytes.
+  if (!writer.WriteInsecureRandomBytes(QuicRandom::GetInstance(),
+                                       len - kStatelessResetTokenLength)) {
+    QUIC_BUG(362045737_2) << "Failed to append random bytes of length: "
+                          << len - kStatelessResetTokenLength;
+    return nullptr;
+  }
+  // Change first 2 fixed bits to 01.
+  buffer[0] &= ~FLAGS_LONG_HEADER;
+  buffer[0] |= FLAGS_FIXED_BIT;
+
+  // Append stateless reset token.
+  if (!writer.WriteBytes(&stateless_reset_token,
+                         sizeof(stateless_reset_token))) {
+    QUIC_BUG(362045737_3) << "Failed to write stateless reset token";
+    return nullptr;
+  }
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len,
+                                               /*owns_buffer=*/true);
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
+    QuicConnectionId server_connection_id,
+    QuicConnectionId client_connection_id, bool ietf_quic,
+    bool use_length_prefix, const ParsedQuicVersionVector& versions) {
+  QUIC_CODE_COUNT(quic_build_version_negotiation);
+  if (use_length_prefix) {
+    QUICHE_DCHECK(ietf_quic);
+    QUIC_CODE_COUNT(quic_build_version_negotiation_ietf);
+  } else if (ietf_quic) {
+    QUIC_CODE_COUNT(quic_build_version_negotiation_old_ietf);
+  } else {
+    QUIC_CODE_COUNT(quic_build_version_negotiation_old_gquic);
+  }
+  ParsedQuicVersionVector wire_versions = versions;
+  // Add a version reserved for negotiation as suggested by the
+  // "Using Reserved Versions" section of draft-ietf-quic-transport.
+  if (wire_versions.empty()) {
+    // Ensure that version negotiation packets we send have at least two
+    // versions. This guarantees that, under all circumstances, all QUIC
+    // packets we send are at least 14 bytes long.
+    wire_versions = {QuicVersionReservedForNegotiation(),
+                     QuicVersionReservedForNegotiation()};
+  } else {
+    // This is not uniformely distributed but is acceptable since no security
+    // depends on this randomness.
+    size_t version_index = 0;
+    const bool disable_randomness =
+        GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness);
+    if (!disable_randomness) {
+      version_index =
+          QuicRandom::GetInstance()->RandUint64() % (wire_versions.size() + 1);
+    }
+    wire_versions.insert(wire_versions.begin() + version_index,
+                         QuicVersionReservedForNegotiation());
+  }
+  if (ietf_quic) {
+    return BuildIetfVersionNegotiationPacket(
+        use_length_prefix, server_connection_id, client_connection_id,
+        wire_versions);
+  }
+
+  // The GQUIC encoding does not support encoding client connection IDs.
+  QUICHE_DCHECK(client_connection_id.IsEmpty());
+  // The GQUIC encoding does not support length-prefixed connection IDs.
+  QUICHE_DCHECK(!use_length_prefix);
+
+  QUICHE_DCHECK(!wire_versions.empty());
+  size_t len = kPublicFlagsSize + server_connection_id.length() +
+               wire_versions.size() * kQuicVersionSize;
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+
+  uint8_t flags = static_cast<uint8_t>(
+      PACKET_PUBLIC_FLAGS_VERSION | PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID |
+      PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD);
+  if (!writer.WriteUInt8(flags)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteConnectionId(server_connection_id)) {
+    return nullptr;
+  }
+
+  for (const ParsedQuicVersion& version : wire_versions) {
+    if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
+      return nullptr;
+    }
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
+}
+
+// static
+std::unique_ptr<QuicEncryptedPacket>
+QuicFramer::BuildIetfVersionNegotiationPacket(
+    bool use_length_prefix, QuicConnectionId server_connection_id,
+    QuicConnectionId client_connection_id,
+    const ParsedQuicVersionVector& versions) {
+  QUIC_DVLOG(1) << "Building IETF version negotiation packet with"
+                << (use_length_prefix ? "" : "out")
+                << " length prefix, server_connection_id "
+                << server_connection_id << " client_connection_id "
+                << client_connection_id << " versions "
+                << ParsedQuicVersionVectorToString(versions);
+  QUICHE_DCHECK(!versions.empty());
+  size_t len = kPacketHeaderTypeSize + kConnectionIdLengthSize +
+               client_connection_id.length() + server_connection_id.length() +
+               (versions.size() + 1) * kQuicVersionSize;
+  if (use_length_prefix) {
+    // When using length-prefixed connection IDs, packets carry two lengths
+    // instead of one.
+    len += kConnectionIdLengthSize;
+  }
+  std::unique_ptr<char[]> buffer(new char[len]);
+  QuicDataWriter writer(len, buffer.get());
+
+  // TODO(fayang): Randomly select a value for the type.
+  uint8_t type = static_cast<uint8_t>(FLAGS_LONG_HEADER | FLAGS_FIXED_BIT);
+  if (!writer.WriteUInt8(type)) {
+    return nullptr;
+  }
+
+  if (!writer.WriteUInt32(0)) {
+    return nullptr;
+  }
+
+  if (!AppendIetfConnectionIds(true, use_length_prefix, client_connection_id,
+                               server_connection_id, &writer)) {
+    return nullptr;
+  }
+
+  for (const ParsedQuicVersion& version : versions) {
+    if (!writer.WriteUInt32(CreateQuicVersionLabel(version))) {
+      return nullptr;
+    }
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer.release(), len, true);
+}
+
+bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
+  QUICHE_DCHECK(!is_processing_packet_) << ENDPOINT << "Nested ProcessPacket";
+  is_processing_packet_ = true;
+  bool result = ProcessPacketInternal(packet);
+  is_processing_packet_ = false;
+  return result;
+}
+
+bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) {
+  QuicDataReader reader(packet.data(), packet.length());
+
+  bool packet_has_ietf_packet_header = false;
+  if (infer_packet_header_type_from_version_) {
+    packet_has_ietf_packet_header = version_.HasIetfInvariantHeader();
+  } else if (!reader.IsDoneReading()) {
+    uint8_t type = reader.PeekByte();
+    packet_has_ietf_packet_header = QuicUtils::IsIetfPacketHeader(type);
+  }
+  if (packet_has_ietf_packet_header) {
+    QUIC_DVLOG(1) << ENDPOINT << "Processing IETF QUIC packet.";
+  }
+
+  visitor_->OnPacket();
+
+  QuicPacketHeader header;
+  if (!ProcessPublicHeader(&reader, packet_has_ietf_packet_header, &header)) {
+    QUICHE_DCHECK_NE("", detailed_error_);
+    QUIC_DVLOG(1) << ENDPOINT << "Unable to process public header. Error: "
+                  << detailed_error_;
+    QUICHE_DCHECK_NE("", detailed_error_);
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_HEADER);
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+
+  if (!visitor_->OnUnauthenticatedPublicHeader(header)) {
+    // The visitor suppresses further processing of the packet.
+    return true;
+  }
+
+  if (IsVersionNegotiation(header, packet_has_ietf_packet_header)) {
+    if (perspective_ == Perspective::IS_CLIENT) {
+      QUIC_DVLOG(1) << "Client received version negotiation packet";
+      return ProcessVersionNegotiationPacket(&reader, header);
+    } else {
+      QUIC_DLOG(ERROR) << "Server received version negotiation packet";
+      set_detailed_error("Server received version negotiation packet.");
+      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    }
+  }
+
+  if (header.version_flag && header.version != version_) {
+    if (perspective_ == Perspective::IS_SERVER) {
+      if (!visitor_->OnProtocolVersionMismatch(header.version)) {
+        RecordDroppedPacketReason(DroppedPacketReason::VERSION_MISMATCH);
+        return true;
+      }
+    } else {
+      // A client received a packet of a different version but that packet is
+      // not a version negotiation packet. It is therefore invalid and dropped.
+      QUIC_DLOG(ERROR) << "Client received unexpected version "
+                       << ParsedQuicVersionToString(header.version)
+                       << " instead of " << ParsedQuicVersionToString(version_);
+      set_detailed_error("Client received unexpected version.");
+      return RaiseError(QUIC_PACKET_WRONG_VERSION);
+    }
+  }
+
+  bool rv;
+  if (header.long_packet_type == RETRY) {
+    rv = ProcessRetryPacket(&reader, header);
+  } else if (header.reset_flag) {
+    rv = ProcessPublicResetPacket(&reader, header);
+  } else if (packet.length() <= kMaxIncomingPacketSize) {
+    // The optimized decryption algorithm implementations run faster when
+    // operating on aligned memory.
+    ABSL_CACHELINE_ALIGNED char buffer[kMaxIncomingPacketSize];
+    if (packet_has_ietf_packet_header) {
+      rv = ProcessIetfDataPacket(&reader, &header, packet, buffer,
+                                 ABSL_ARRAYSIZE(buffer));
+    } else {
+      rv = ProcessDataPacket(&reader, &header, packet, buffer,
+                             ABSL_ARRAYSIZE(buffer));
+    }
+  } else {
+    std::unique_ptr<char[]> large_buffer(new char[packet.length()]);
+    if (packet_has_ietf_packet_header) {
+      rv = ProcessIetfDataPacket(&reader, &header, packet, large_buffer.get(),
+                                 packet.length());
+    } else {
+      rv = ProcessDataPacket(&reader, &header, packet, large_buffer.get(),
+                             packet.length());
+    }
+    QUIC_BUG_IF(quic_bug_10850_53, rv)
+        << "QUIC should never successfully process packets larger"
+        << "than kMaxIncomingPacketSize. packet size:" << packet.length();
+  }
+  return rv;
+}
+
+bool QuicFramer::ProcessVersionNegotiationPacket(
+    QuicDataReader* reader, const QuicPacketHeader& header) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+
+  QuicVersionNegotiationPacket packet(
+      GetServerConnectionIdAsRecipient(header, perspective_));
+  // Try reading at least once to raise error if the packet is invalid.
+  do {
+    QuicVersionLabel version_label;
+    if (!ProcessVersionLabel(reader, &version_label)) {
+      set_detailed_error("Unable to read supported version in negotiation.");
+      RecordDroppedPacketReason(
+          DroppedPacketReason::INVALID_VERSION_NEGOTIATION_PACKET);
+      return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+    }
+    ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
+    if (parsed_version != UnsupportedQuicVersion()) {
+      packet.versions.push_back(parsed_version);
+    }
+  } while (!reader->IsDoneReading());
+
+  QUIC_DLOG(INFO) << ENDPOINT << "parsed version negotiation: "
+                  << ParsedQuicVersionVectorToString(packet.versions);
+
+  visitor_->OnVersionNegotiationPacket(packet);
+  return true;
+}
+
+bool QuicFramer::ProcessRetryPacket(QuicDataReader* reader,
+                                    const QuicPacketHeader& header) {
+  QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+  if (drop_incoming_retry_packets_) {
+    QUIC_DLOG(INFO) << "Ignoring received RETRY packet";
+    return true;
+  }
+
+  if (version_.UsesTls()) {
+    QUICHE_DCHECK(version_.HasLengthPrefixedConnectionIds()) << version_;
+    const size_t bytes_remaining = reader->BytesRemaining();
+    if (bytes_remaining <= kRetryIntegrityTagLength) {
+      set_detailed_error("Retry packet too short to parse integrity tag.");
+      return false;
+    }
+    const size_t retry_token_length =
+        bytes_remaining - kRetryIntegrityTagLength;
+    QUICHE_DCHECK_GT(retry_token_length, 0u);
+    absl::string_view retry_token;
+    if (!reader->ReadStringPiece(&retry_token, retry_token_length)) {
+      set_detailed_error("Failed to read retry token.");
+      return false;
+    }
+    absl::string_view retry_without_tag = reader->PreviouslyReadPayload();
+    absl::string_view integrity_tag = reader->ReadRemainingPayload();
+    QUICHE_DCHECK_EQ(integrity_tag.length(), kRetryIntegrityTagLength);
+    visitor_->OnRetryPacket(EmptyQuicConnectionId(),
+                            header.source_connection_id, retry_token,
+                            integrity_tag, retry_without_tag);
+    return true;
+  }
+
+  QuicConnectionId original_destination_connection_id;
+  if (version_.HasLengthPrefixedConnectionIds()) {
+    // Parse Original Destination Connection ID.
+    if (!reader->ReadLengthPrefixedConnectionId(
+            &original_destination_connection_id)) {
+      set_detailed_error("Unable to read Original Destination ConnectionId.");
+      return false;
+    }
+  } else {
+    // Parse Original Destination Connection ID Length.
+    uint8_t odcil = header.type_byte & 0xf;
+    if (odcil != 0) {
+      odcil += kConnectionIdLengthAdjustment;
+    }
+
+    // Parse Original Destination Connection ID.
+    if (!reader->ReadConnectionId(&original_destination_connection_id, odcil)) {
+      set_detailed_error("Unable to read Original Destination ConnectionId.");
+      return false;
+    }
+  }
+
+  if (!QuicUtils::IsConnectionIdValidForVersion(
+          original_destination_connection_id, transport_version())) {
+    set_detailed_error(
+        "Received Original Destination ConnectionId with invalid length.");
+    return false;
+  }
+
+  absl::string_view retry_token = reader->ReadRemainingPayload();
+  visitor_->OnRetryPacket(original_destination_connection_id,
+                          header.source_connection_id, retry_token,
+                          /*retry_integrity_tag=*/absl::string_view(),
+                          /*retry_without_tag=*/absl::string_view());
+  return true;
+}
+
+// Seeks the current packet to check for a coalesced packet at the end.
+// If the IETF length field only spans part of the outer packet,
+// then there is a coalesced packet after this one.
+void QuicFramer::MaybeProcessCoalescedPacket(
+    const QuicDataReader& encrypted_reader, uint64_t remaining_bytes_length,
+    const QuicPacketHeader& header) {
+  if (header.remaining_packet_length >= remaining_bytes_length) {
+    // There is no coalesced packet.
+    return;
+  }
+
+  absl::string_view remaining_data = encrypted_reader.PeekRemainingPayload();
+  QUICHE_DCHECK_EQ(remaining_data.length(), remaining_bytes_length);
+
+  const char* coalesced_data =
+      remaining_data.data() + header.remaining_packet_length;
+  uint64_t coalesced_data_length =
+      remaining_bytes_length - header.remaining_packet_length;
+  QuicDataReader coalesced_reader(coalesced_data, coalesced_data_length);
+
+  QuicPacketHeader coalesced_header;
+  if (!ProcessIetfPacketHeader(&coalesced_reader, &coalesced_header)) {
+    // Some implementations pad their INITIAL packets by sending random invalid
+    // data after the INITIAL, and that is allowed by the specification. If we
+    // fail to parse a subsequent coalesced packet, simply ignore it.
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Failed to parse received coalesced header of length "
+                    << coalesced_data_length
+                    << " with error: " << detailed_error_ << ": "
+                    << absl::BytesToHexString(absl::string_view(
+                           coalesced_data, coalesced_data_length))
+                    << " previous header was " << header;
+    return;
+  }
+
+  if (coalesced_header.destination_connection_id !=
+      header.destination_connection_id) {
+    // Drop coalesced packets with mismatched connection IDs.
+    QUIC_DLOG(INFO) << ENDPOINT << "Received mismatched coalesced header "
+                    << coalesced_header << " previous header was " << header;
+    QUIC_CODE_COUNT(
+        quic_received_coalesced_packets_with_mismatched_connection_id);
+    return;
+  }
+
+  QuicEncryptedPacket coalesced_packet(coalesced_data, coalesced_data_length,
+                                       /*owns_buffer=*/false);
+  visitor_->OnCoalescedPacket(coalesced_packet);
+}
+
+bool QuicFramer::MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
+                                        QuicPacketHeader* header) {
+  if (!QuicVersionHasLongHeaderLengths(header->version.transport_version) ||
+      header->form != IETF_QUIC_LONG_HEADER_PACKET ||
+      (header->long_packet_type != INITIAL &&
+       header->long_packet_type != HANDSHAKE &&
+       header->long_packet_type != ZERO_RTT_PROTECTED)) {
+    return true;
+  }
+  header->length_length = encrypted_reader->PeekVarInt62Length();
+  if (!encrypted_reader->ReadVarInt62(&header->remaining_packet_length)) {
+    set_detailed_error("Unable to read long header payload length.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  uint64_t remaining_bytes_length = encrypted_reader->BytesRemaining();
+  if (header->remaining_packet_length > remaining_bytes_length) {
+    set_detailed_error("Long header payload length longer than packet.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+
+  MaybeProcessCoalescedPacket(*encrypted_reader, remaining_bytes_length,
+                              *header);
+
+  if (!encrypted_reader->TruncateRemaining(header->remaining_packet_length)) {
+    set_detailed_error("Length TruncateRemaining failed.");
+    QUIC_BUG(quic_bug_10850_54) << "Length TruncateRemaining failed.";
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
+                                       QuicPacketHeader* header,
+                                       const QuicEncryptedPacket& packet,
+                                       char* decrypted_buffer,
+                                       size_t buffer_length) {
+  QUICHE_DCHECK_NE(GOOGLE_QUIC_PACKET, header->form);
+  QUICHE_DCHECK(!header->has_possible_stateless_reset_token);
+  header->length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  header->remaining_packet_length = 0;
+  if (header->form == IETF_QUIC_SHORT_HEADER_PACKET &&
+      perspective_ == Perspective::IS_CLIENT) {
+    // Peek possible stateless reset token. Will only be used on decryption
+    // failure.
+    absl::string_view remaining = encrypted_reader->PeekRemainingPayload();
+    if (remaining.length() >= sizeof(header->possible_stateless_reset_token)) {
+      header->has_possible_stateless_reset_token = true;
+      memcpy(&header->possible_stateless_reset_token,
+             &remaining.data()[remaining.length() -
+                               sizeof(header->possible_stateless_reset_token)],
+             sizeof(header->possible_stateless_reset_token));
+    }
+  }
+
+  if (!MaybeProcessIetfLength(encrypted_reader, header)) {
+    return false;
+  }
+
+  absl::string_view associated_data;
+  std::vector<char> ad_storage;
+  QuicPacketNumber base_packet_number;
+  if (header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
+      header->long_packet_type != VERSION_NEGOTIATION) {
+    QUICHE_DCHECK(header->form == IETF_QUIC_SHORT_HEADER_PACKET ||
+                  header->long_packet_type == INITIAL ||
+                  header->long_packet_type == HANDSHAKE ||
+                  header->long_packet_type == ZERO_RTT_PROTECTED);
+    // Process packet number.
+    if (supports_multiple_packet_number_spaces_) {
+      PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
+      if (pn_space == NUM_PACKET_NUMBER_SPACES) {
+        return RaiseError(QUIC_INVALID_PACKET_HEADER);
+      }
+      base_packet_number = largest_decrypted_packet_numbers_[pn_space];
+    } else {
+      base_packet_number = largest_packet_number_;
+    }
+    uint64_t full_packet_number;
+    bool hp_removal_failed = false;
+    if (version_.HasHeaderProtection()) {
+      if (!RemoveHeaderProtection(encrypted_reader, packet, header,
+                                  &full_packet_number, &ad_storage)) {
+        hp_removal_failed = true;
+      }
+      associated_data = absl::string_view(ad_storage.data(), ad_storage.size());
+    } else if (!ProcessAndCalculatePacketNumber(
+                   encrypted_reader, header->packet_number_length,
+                   base_packet_number, &full_packet_number)) {
+      set_detailed_error("Unable to read packet number.");
+      RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+
+    if (hp_removal_failed ||
+        !IsValidFullPacketNumber(full_packet_number, version())) {
+      if (IsIetfStatelessResetPacket(*header)) {
+        // This is a stateless reset packet.
+        QuicIetfStatelessResetPacket packet(
+            *header, header->possible_stateless_reset_token);
+        visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
+        return true;
+      }
+      if (hp_removal_failed) {
+        const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
+        const bool has_decryption_key = decrypter_[decryption_level] != nullptr;
+        visitor_->OnUndecryptablePacket(
+            QuicEncryptedPacket(encrypted_reader->FullPayload()),
+            decryption_level, has_decryption_key);
+        RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
+        set_detailed_error(absl::StrCat(
+            "Unable to decrypt ", EncryptionLevelToString(decryption_level),
+            " header protection", has_decryption_key ? "" : " (missing key)",
+            "."));
+        return RaiseError(QUIC_DECRYPTION_FAILURE);
+      }
+      RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+      set_detailed_error("packet numbers cannot be 0.");
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+    header->packet_number = QuicPacketNumber(full_packet_number);
+  }
+
+  // A nonce should only present in SHLO from the server to the client when
+  // using QUIC crypto.
+  if (header->form == IETF_QUIC_LONG_HEADER_PACKET &&
+      header->long_packet_type == ZERO_RTT_PROTECTED &&
+      perspective_ == Perspective::IS_CLIENT &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    if (!encrypted_reader->ReadBytes(
+            reinterpret_cast<uint8_t*>(last_nonce_.data()),
+            last_nonce_.size())) {
+      set_detailed_error("Unable to read nonce.");
+      RecordDroppedPacketReason(
+          DroppedPacketReason::INVALID_DIVERSIFICATION_NONCE);
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+
+    header->nonce = &last_nonce_;
+  } else {
+    header->nonce = nullptr;
+  }
+
+  if (!visitor_->OnUnauthenticatedHeader(*header)) {
+    set_detailed_error(
+        "Visitor asked to stop processing of unauthenticated header.");
+    return false;
+  }
+
+  absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
+  if (!version_.HasHeaderProtection()) {
+    associated_data = GetAssociatedDataFromEncryptedPacket(
+        version_.transport_version, packet,
+        GetIncludedDestinationConnectionIdLength(*header),
+        GetIncludedSourceConnectionIdLength(*header), header->version_flag,
+        header->nonce != nullptr, header->packet_number_length,
+        header->retry_token_length_length, header->retry_token.length(),
+        header->length_length);
+  }
+
+  size_t decrypted_length = 0;
+  EncryptionLevel decrypted_level;
+  if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
+                      decrypted_buffer, buffer_length, &decrypted_length,
+                      &decrypted_level)) {
+    if (IsIetfStatelessResetPacket(*header)) {
+      // This is a stateless reset packet.
+      QuicIetfStatelessResetPacket packet(
+          *header, header->possible_stateless_reset_token);
+      visitor_->OnAuthenticatedIetfStatelessResetPacket(packet);
+      return true;
+    }
+    const EncryptionLevel decryption_level = GetEncryptionLevel(*header);
+    const bool has_decryption_key = version_.KnowsWhichDecrypterToUse() &&
+                                    decrypter_[decryption_level] != nullptr;
+    visitor_->OnUndecryptablePacket(
+        QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
+        has_decryption_key);
+    set_detailed_error(absl::StrCat(
+        "Unable to decrypt ", EncryptionLevelToString(decryption_level),
+        " payload with reconstructed packet number ",
+        header->packet_number.ToString(), " (largest decrypted was ",
+        base_packet_number.ToString(), ")",
+        has_decryption_key || !version_.KnowsWhichDecrypterToUse()
+            ? ""
+            : " (missing key)",
+        "."));
+    RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
+    return RaiseError(QUIC_DECRYPTION_FAILURE);
+  }
+  QuicDataReader reader(decrypted_buffer, decrypted_length);
+
+  // Update the largest packet number after we have decrypted the packet
+  // so we are confident is not attacker controlled.
+  if (supports_multiple_packet_number_spaces_) {
+    largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
+                                          decrypted_level)]
+        .UpdateMax(header->packet_number);
+  } else {
+    largest_packet_number_.UpdateMax(header->packet_number);
+  }
+
+  if (!visitor_->OnPacketHeader(*header)) {
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+    // The visitor suppresses further processing of the packet.
+    return true;
+  }
+
+  if (packet.length() > kMaxIncomingPacketSize) {
+    set_detailed_error("Packet too large.");
+    return RaiseError(QUIC_PACKET_TOO_LARGE);
+  }
+
+  // Handle the payload.
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    current_received_frame_type_ = 0;
+    previously_received_frame_type_ = 0;
+    if (!ProcessIetfFrameData(&reader, *header, decrypted_level)) {
+      current_received_frame_type_ = 0;
+      previously_received_frame_type_ = 0;
+      QUICHE_DCHECK_NE(QUIC_NO_ERROR,
+                       error_);  // ProcessIetfFrameData sets the error.
+      QUICHE_DCHECK_NE("", detailed_error_);
+      QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
+                         << detailed_error_;
+      return false;
+    }
+    current_received_frame_type_ = 0;
+    previously_received_frame_type_ = 0;
+  } else {
+    if (!ProcessFrameData(&reader, *header)) {
+      QUICHE_DCHECK_NE(QUIC_NO_ERROR,
+                       error_);  // ProcessFrameData sets the error.
+      QUICHE_DCHECK_NE("", detailed_error_);
+      QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
+                         << detailed_error_;
+      return false;
+    }
+  }
+
+  visitor_->OnPacketComplete();
+  return true;
+}
+
+bool QuicFramer::ProcessDataPacket(QuicDataReader* encrypted_reader,
+                                   QuicPacketHeader* header,
+                                   const QuicEncryptedPacket& packet,
+                                   char* decrypted_buffer,
+                                   size_t buffer_length) {
+  if (!ProcessUnauthenticatedHeader(encrypted_reader, header)) {
+    QUICHE_DCHECK_NE("", detailed_error_);
+    QUIC_DVLOG(1)
+        << ENDPOINT
+        << "Unable to process packet header. Stopping parsing. Error: "
+        << detailed_error_;
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PACKET_NUMBER);
+    return false;
+  }
+
+  absl::string_view encrypted = encrypted_reader->ReadRemainingPayload();
+  absl::string_view associated_data = GetAssociatedDataFromEncryptedPacket(
+      version_.transport_version, packet,
+      GetIncludedDestinationConnectionIdLength(*header),
+      GetIncludedSourceConnectionIdLength(*header), header->version_flag,
+      header->nonce != nullptr, header->packet_number_length,
+      header->retry_token_length_length, header->retry_token.length(),
+      header->length_length);
+
+  size_t decrypted_length = 0;
+  EncryptionLevel decrypted_level;
+  if (!DecryptPayload(packet.length(), encrypted, associated_data, *header,
+                      decrypted_buffer, buffer_length, &decrypted_length,
+                      &decrypted_level)) {
+    const EncryptionLevel decryption_level = decrypter_level_;
+    // This version uses trial decryption so we always report to our visitor
+    // that we are not certain we have the correct decryption key.
+    const bool has_decryption_key = false;
+    visitor_->OnUndecryptablePacket(
+        QuicEncryptedPacket(encrypted_reader->FullPayload()), decryption_level,
+        has_decryption_key);
+    RecordDroppedPacketReason(DroppedPacketReason::DECRYPTION_FAILURE);
+    set_detailed_error(absl::StrCat("Unable to decrypt ",
+                                    EncryptionLevelToString(decryption_level),
+                                    " payload."));
+    return RaiseError(QUIC_DECRYPTION_FAILURE);
+  }
+
+  QuicDataReader reader(decrypted_buffer, decrypted_length);
+
+  // Update the largest packet number after we have decrypted the packet
+  // so we are confident is not attacker controlled.
+  if (supports_multiple_packet_number_spaces_) {
+    largest_decrypted_packet_numbers_[QuicUtils::GetPacketNumberSpace(
+                                          decrypted_level)]
+        .UpdateMax(header->packet_number);
+  } else {
+    largest_packet_number_.UpdateMax(header->packet_number);
+  }
+
+  if (!visitor_->OnPacketHeader(*header)) {
+    // The visitor suppresses further processing of the packet.
+    return true;
+  }
+
+  if (packet.length() > kMaxIncomingPacketSize) {
+    set_detailed_error("Packet too large.");
+    return RaiseError(QUIC_PACKET_TOO_LARGE);
+  }
+
+  // Handle the payload.
+  if (!ProcessFrameData(&reader, *header)) {
+    QUICHE_DCHECK_NE(QUIC_NO_ERROR,
+                     error_);  // ProcessFrameData sets the error.
+    QUICHE_DCHECK_NE("", detailed_error_);
+    QUIC_DLOG(WARNING) << ENDPOINT << "Unable to process frame data. Error: "
+                       << detailed_error_;
+    return false;
+  }
+
+  visitor_->OnPacketComplete();
+  return true;
+}
+
+bool QuicFramer::ProcessPublicResetPacket(QuicDataReader* reader,
+                                          const QuicPacketHeader& header) {
+  QuicPublicResetPacket packet(
+      GetServerConnectionIdAsRecipient(header, perspective_));
+
+  std::unique_ptr<CryptoHandshakeMessage> reset(
+      CryptoFramer::ParseMessage(reader->ReadRemainingPayload()));
+  if (!reset) {
+    set_detailed_error("Unable to read reset message.");
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
+    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
+  }
+  if (reset->tag() != kPRST) {
+    set_detailed_error("Incorrect message tag.");
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
+    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
+  }
+
+  if (reset->GetUint64(kRNON, &packet.nonce_proof) != QUIC_NO_ERROR) {
+    set_detailed_error("Unable to read nonce proof.");
+    RecordDroppedPacketReason(DroppedPacketReason::INVALID_PUBLIC_RESET_PACKET);
+    return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
+  }
+  // TODO(satyamshekhar): validate nonce to protect against DoS.
+
+  absl::string_view address;
+  if (reset->GetStringPiece(kCADR, &address)) {
+    QuicSocketAddressCoder address_coder;
+    if (address_coder.Decode(address.data(), address.length())) {
+      packet.client_address =
+          QuicSocketAddress(address_coder.ip(), address_coder.port());
+    }
+  }
+
+  absl::string_view endpoint_id;
+  if (perspective_ == Perspective::IS_CLIENT &&
+      reset->GetStringPiece(kEPID, &endpoint_id)) {
+    packet.endpoint_id = std::string(endpoint_id);
+    packet.endpoint_id += '\0';
+  }
+
+  visitor_->OnPublicResetPacket(packet);
+  return true;
+}
+
+bool QuicFramer::IsIetfStatelessResetPacket(
+    const QuicPacketHeader& header) const {
+  QUIC_BUG_IF(quic_bug_12975_3, header.has_possible_stateless_reset_token &&
+                                    perspective_ != Perspective::IS_CLIENT)
+      << "has_possible_stateless_reset_token can only be true at client side.";
+  return header.form == IETF_QUIC_SHORT_HEADER_PACKET &&
+         header.has_possible_stateless_reset_token &&
+         visitor_->IsValidStatelessResetToken(
+             header.possible_stateless_reset_token);
+}
+
+bool QuicFramer::HasEncrypterOfEncryptionLevel(EncryptionLevel level) const {
+  return encrypter_[level] != nullptr;
+}
+
+bool QuicFramer::HasDecrypterOfEncryptionLevel(EncryptionLevel level) const {
+  return decrypter_[level] != nullptr;
+}
+
+bool QuicFramer::HasAnEncrypterForSpace(PacketNumberSpace space) const {
+  switch (space) {
+    case INITIAL_DATA:
+      return HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL);
+    case HANDSHAKE_DATA:
+      return HasEncrypterOfEncryptionLevel(ENCRYPTION_HANDSHAKE);
+    case APPLICATION_DATA:
+      return HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT) ||
+             HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    case NUM_PACKET_NUMBER_SPACES:
+      break;
+  }
+  QUIC_BUG(quic_bug_10850_55)
+      << ENDPOINT
+      << "Try to send data of space: " << PacketNumberSpaceToString(space);
+  return false;
+}
+
+EncryptionLevel QuicFramer::GetEncryptionLevelToSendApplicationData() const {
+  if (!HasAnEncrypterForSpace(APPLICATION_DATA)) {
+    QUIC_BUG(quic_bug_12975_4)
+        << "Tried to get encryption level to send application data with no "
+           "encrypter available.";
+    return NUM_ENCRYPTION_LEVELS;
+  }
+  if (HasEncrypterOfEncryptionLevel(ENCRYPTION_FORWARD_SECURE)) {
+    return ENCRYPTION_FORWARD_SECURE;
+  }
+  QUICHE_DCHECK(HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT));
+  return ENCRYPTION_ZERO_RTT;
+}
+
+bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
+                                    QuicDataWriter* writer,
+                                    size_t* length_field_offset) {
+  if (version().HasIetfInvariantHeader()) {
+    return AppendIetfPacketHeader(header, writer, length_field_offset);
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Appending header: " << header;
+  uint8_t public_flags = 0;
+  if (header.reset_flag) {
+    public_flags |= PACKET_PUBLIC_FLAGS_RST;
+  }
+  if (header.version_flag) {
+    public_flags |= PACKET_PUBLIC_FLAGS_VERSION;
+  }
+
+  public_flags |= GetPacketNumberFlags(header.packet_number_length)
+                  << kPublicHeaderSequenceNumberShift;
+
+  if (header.nonce != nullptr) {
+    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+    public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
+  }
+
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsSender(header, perspective_);
+  QuicConnectionIdIncluded server_connection_id_included =
+      GetServerConnectionIdIncludedAsSender(header, perspective_);
+  QUICHE_DCHECK_EQ(CONNECTION_ID_ABSENT,
+                   GetClientConnectionIdIncludedAsSender(header, perspective_))
+      << ENDPOINT << ParsedQuicVersionToString(version_)
+      << " invalid header: " << header;
+
+  switch (server_connection_id_included) {
+    case CONNECTION_ID_ABSENT:
+      if (!writer->WriteUInt8(public_flags |
+                              PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID)) {
+        return false;
+      }
+      break;
+    case CONNECTION_ID_PRESENT:
+      QUIC_BUG_IF(quic_bug_12975_5,
+                  !QuicUtils::IsConnectionIdValidForVersion(
+                      server_connection_id, transport_version()))
+          << "AppendPacketHeader: attempted to use connection ID "
+          << server_connection_id << " which is invalid with version "
+          << version();
+
+      public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
+      if (perspective_ == Perspective::IS_CLIENT) {
+        public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
+      }
+      if (!writer->WriteUInt8(public_flags) ||
+          !writer->WriteConnectionId(server_connection_id)) {
+        return false;
+      }
+      break;
+  }
+  last_serialized_server_connection_id_ = server_connection_id;
+
+  if (header.version_flag) {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+    QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
+    if (!writer->WriteUInt32(version_label)) {
+      return false;
+    }
+
+    QUIC_DVLOG(1) << ENDPOINT << "label = '"
+                  << QuicVersionLabelToString(version_label) << "'";
+  }
+
+  if (header.nonce != nullptr &&
+      !writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
+    return false;
+  }
+
+  if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
+                          writer)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
+                                          QuicDataWriter* writer) {
+  uint8_t type = 0;
+  if (header.version_flag) {
+    type = static_cast<uint8_t>(
+        FLAGS_LONG_HEADER | FLAGS_FIXED_BIT |
+        LongHeaderTypeToOnWireValue(header.long_packet_type, version_) |
+        PacketNumberLengthToOnWireValue(header.packet_number_length));
+  } else {
+    type = static_cast<uint8_t>(
+        FLAGS_FIXED_BIT | (current_key_phase_bit_ ? FLAGS_KEY_PHASE_BIT : 0) |
+        PacketNumberLengthToOnWireValue(header.packet_number_length));
+  }
+  return writer->WriteUInt8(type);
+}
+
+bool QuicFramer::AppendIetfPacketHeader(const QuicPacketHeader& header,
+                                        QuicDataWriter* writer,
+                                        size_t* length_field_offset) {
+  QUIC_DVLOG(1) << ENDPOINT << "Appending IETF header: " << header;
+  QuicConnectionId server_connection_id =
+      GetServerConnectionIdAsSender(header, perspective_);
+  QUIC_BUG_IF(quic_bug_12975_6, !QuicUtils::IsConnectionIdValidForVersion(
+                                    server_connection_id, transport_version()))
+      << "AppendIetfPacketHeader: attempted to use connection ID "
+      << server_connection_id << " which is invalid with version " << version();
+  if (!AppendIetfHeaderTypeByte(header, writer)) {
+    return false;
+  }
+
+  if (header.version_flag) {
+    QUICHE_DCHECK_NE(VERSION_NEGOTIATION, header.long_packet_type)
+        << "QuicFramer::AppendIetfPacketHeader does not support sending "
+           "version negotiation packets, use "
+           "QuicFramer::BuildVersionNegotiationPacket instead "
+        << header;
+    // Append version for long header.
+    QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
+    if (!writer->WriteUInt32(version_label)) {
+      return false;
+    }
+  }
+
+  // Append connection ID.
+  if (!AppendIetfConnectionIds(
+          header.version_flag, version_.HasLengthPrefixedConnectionIds(),
+          header.destination_connection_id_included != CONNECTION_ID_ABSENT
+              ? header.destination_connection_id
+              : EmptyQuicConnectionId(),
+          header.source_connection_id_included != CONNECTION_ID_ABSENT
+              ? header.source_connection_id
+              : EmptyQuicConnectionId(),
+          writer)) {
+    return false;
+  }
+
+  last_serialized_server_connection_id_ = server_connection_id;
+  if (version_.SupportsClientConnectionIds()) {
+    last_serialized_client_connection_id_ =
+        GetClientConnectionIdAsSender(header, perspective_);
+  }
+
+  // TODO(b/141924462) Remove this QUIC_BUG once we do support sending RETRY.
+  QUIC_BUG_IF(quic_bug_12975_7,
+              header.version_flag && header.long_packet_type == RETRY)
+      << "Sending IETF RETRY packets is not currently supported " << header;
+
+  if (QuicVersionHasLongHeaderLengths(transport_version()) &&
+      header.version_flag) {
+    if (header.long_packet_type == INITIAL) {
+      QUICHE_DCHECK_NE(VARIABLE_LENGTH_INTEGER_LENGTH_0,
+                       header.retry_token_length_length)
+          << ENDPOINT << ParsedQuicVersionToString(version_)
+          << " bad retry token length length in header: " << header;
+      // Write retry token length.
+      if (!writer->WriteVarInt62(header.retry_token.length(),
+                                 header.retry_token_length_length)) {
+        return false;
+      }
+      // Write retry token.
+      if (!header.retry_token.empty() &&
+          !writer->WriteStringPiece(header.retry_token)) {
+        return false;
+      }
+    }
+    if (length_field_offset != nullptr) {
+      *length_field_offset = writer->length();
+    }
+    // Add fake length to reserve two bytes to add length in later.
+    writer->WriteVarInt62(256);
+  } else if (length_field_offset != nullptr) {
+    *length_field_offset = 0;
+  }
+
+  // Append packet number.
+  if (!AppendPacketNumber(header.packet_number_length, header.packet_number,
+                          writer)) {
+    return false;
+  }
+  last_written_packet_number_length_ = header.packet_number_length;
+
+  if (!header.version_flag) {
+    return true;
+  }
+
+  if (header.nonce != nullptr) {
+    QUICHE_DCHECK(header.version_flag);
+    QUICHE_DCHECK_EQ(ZERO_RTT_PROTECTED, header.long_packet_type);
+    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+    if (!writer->WriteBytes(header.nonce, kDiversificationNonceSize)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+const QuicTime::Delta QuicFramer::CalculateTimestampFromWire(
+    uint32_t time_delta_us) {
+  // The new time_delta might have wrapped to the next epoch, or it
+  // might have reverse wrapped to the previous epoch, or it might
+  // remain in the same epoch. Select the time closest to the previous
+  // time.
+  //
+  // epoch_delta is the delta between epochs. A delta is 4 bytes of
+  // microseconds.
+  const uint64_t epoch_delta = UINT64_C(1) << 32;
+  uint64_t epoch = last_timestamp_.ToMicroseconds() & ~(epoch_delta - 1);
+  // Wrapping is safe here because a wrapped value will not be ClosestTo below.
+  uint64_t prev_epoch = epoch - epoch_delta;
+  uint64_t next_epoch = epoch + epoch_delta;
+
+  uint64_t time = ClosestTo(
+      last_timestamp_.ToMicroseconds(), epoch + time_delta_us,
+      ClosestTo(last_timestamp_.ToMicroseconds(), prev_epoch + time_delta_us,
+                next_epoch + time_delta_us));
+
+  return QuicTime::Delta::FromMicroseconds(time);
+}
+
+uint64_t QuicFramer::CalculatePacketNumberFromWire(
+    QuicPacketNumberLength packet_number_length,
+    QuicPacketNumber base_packet_number, uint64_t packet_number) const {
+  // The new packet number might have wrapped to the next epoch, or
+  // it might have reverse wrapped to the previous epoch, or it might
+  // remain in the same epoch.  Select the packet number closest to the
+  // next expected packet number, the previous packet number plus 1.
+
+  // epoch_delta is the delta between epochs the packet number was serialized
+  // with, so the correct value is likely the same epoch as the last sequence
+  // number or an adjacent epoch.
+  if (!base_packet_number.IsInitialized()) {
+    return packet_number;
+  }
+  const uint64_t epoch_delta = UINT64_C(1) << (8 * packet_number_length);
+  uint64_t next_packet_number = base_packet_number.ToUint64() + 1;
+  uint64_t epoch = base_packet_number.ToUint64() & ~(epoch_delta - 1);
+  uint64_t prev_epoch = epoch - epoch_delta;
+  uint64_t next_epoch = epoch + epoch_delta;
+
+  return ClosestTo(next_packet_number, epoch + packet_number,
+                   ClosestTo(next_packet_number, prev_epoch + packet_number,
+                             next_epoch + packet_number));
+}
+
+bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
+                                     bool packet_has_ietf_packet_header,
+                                     QuicPacketHeader* header) {
+  if (packet_has_ietf_packet_header) {
+    return ProcessIetfPacketHeader(reader, header);
+  }
+  uint8_t public_flags;
+  if (!reader->ReadBytes(&public_flags, 1)) {
+    set_detailed_error("Unable to read public flags.");
+    return false;
+  }
+
+  header->reset_flag = (public_flags & PACKET_PUBLIC_FLAGS_RST) != 0;
+  header->version_flag = (public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
+
+  if (validate_flags_ && !header->version_flag &&
+      public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+    set_detailed_error("Illegal public flags value.");
+    return false;
+  }
+
+  if (header->reset_flag && header->version_flag) {
+    set_detailed_error("Got version flag in reset packet");
+    return false;
+  }
+
+  QuicConnectionId* header_connection_id = &header->destination_connection_id;
+  QuicConnectionIdIncluded* header_connection_id_included =
+      &header->destination_connection_id_included;
+  if (perspective_ == Perspective::IS_CLIENT) {
+    header_connection_id = &header->source_connection_id;
+    header_connection_id_included = &header->source_connection_id_included;
+  }
+  switch (public_flags & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) {
+    case PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID:
+      if (!reader->ReadConnectionId(header_connection_id,
+                                    kQuicDefaultConnectionIdLength)) {
+        set_detailed_error("Unable to read ConnectionId.");
+        return false;
+      }
+      *header_connection_id_included = CONNECTION_ID_PRESENT;
+      break;
+    case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
+      *header_connection_id_included = CONNECTION_ID_ABSENT;
+      *header_connection_id = last_serialized_server_connection_id_;
+      break;
+  }
+
+  header->packet_number_length = ReadSequenceNumberLength(
+      public_flags >> kPublicHeaderSequenceNumberShift);
+
+  // Read the version only if the packet is from the client.
+  // version flag from the server means version negotiation packet.
+  if (header->version_flag && perspective_ == Perspective::IS_SERVER) {
+    QuicVersionLabel version_label;
+    if (!ProcessVersionLabel(reader, &version_label)) {
+      set_detailed_error("Unable to read protocol version.");
+      return false;
+    }
+    // If the version from the new packet is the same as the version of this
+    // framer, then the public flags should be set to something we understand.
+    // If not, this raises an error.
+    ParsedQuicVersion version = ParseQuicVersionLabel(version_label);
+    if (version == version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+      set_detailed_error("Illegal public flags value.");
+      return false;
+    }
+    header->version = version;
+  }
+
+  // A nonce should only be present in packets from the server to the client,
+  // which are neither version negotiation nor public reset packets.
+  if (public_flags & PACKET_PUBLIC_FLAGS_NONCE &&
+      !(public_flags & PACKET_PUBLIC_FLAGS_VERSION) &&
+      !(public_flags & PACKET_PUBLIC_FLAGS_RST) &&
+      // The nonce flag from a client is ignored and is assumed to be an older
+      // client indicating an eight-byte connection ID.
+      perspective_ == Perspective::IS_CLIENT) {
+    if (!reader->ReadBytes(reinterpret_cast<uint8_t*>(last_nonce_.data()),
+                           last_nonce_.size())) {
+      set_detailed_error("Unable to read nonce.");
+      return false;
+    }
+    header->nonce = &last_nonce_;
+  } else {
+    header->nonce = nullptr;
+  }
+
+  return true;
+}
+
+// static
+QuicPacketNumberLength QuicFramer::GetMinPacketNumberLength(
+    QuicPacketNumber packet_number) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (packet_number < QuicPacketNumber(1 << (PACKET_1BYTE_PACKET_NUMBER * 8))) {
+    return PACKET_1BYTE_PACKET_NUMBER;
+  } else if (packet_number <
+             QuicPacketNumber(1 << (PACKET_2BYTE_PACKET_NUMBER * 8))) {
+    return PACKET_2BYTE_PACKET_NUMBER;
+  } else if (packet_number <
+             QuicPacketNumber(UINT64_C(1)
+                              << (PACKET_4BYTE_PACKET_NUMBER * 8))) {
+    return PACKET_4BYTE_PACKET_NUMBER;
+  } else {
+    return PACKET_6BYTE_PACKET_NUMBER;
+  }
+}
+
+// static
+uint8_t QuicFramer::GetPacketNumberFlags(
+    QuicPacketNumberLength packet_number_length) {
+  switch (packet_number_length) {
+    case PACKET_1BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_1BYTE_PACKET;
+    case PACKET_2BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_2BYTE_PACKET;
+    case PACKET_4BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_4BYTE_PACKET;
+    case PACKET_6BYTE_PACKET_NUMBER:
+    case PACKET_8BYTE_PACKET_NUMBER:
+      return PACKET_FLAGS_8BYTE_PACKET;
+    default:
+      QUIC_BUG(quic_bug_10850_56) << "Unreachable case statement.";
+      return PACKET_FLAGS_8BYTE_PACKET;
+  }
+}
+
+// static
+QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
+    const QuicAckFrame& frame) {
+  AckFrameInfo new_ack_info;
+  if (frame.packets.Empty()) {
+    return new_ack_info;
+  }
+  // The first block is the last interval. It isn't encoded with the gap-length
+  // encoding, so skip it.
+  new_ack_info.first_block_length = frame.packets.LastIntervalLength();
+  auto itr = frame.packets.rbegin();
+  QuicPacketNumber previous_start = itr->min();
+  new_ack_info.max_block_length = itr->Length();
+  ++itr;
+
+  // Don't do any more work after getting information for 256 ACK blocks; any
+  // more can't be encoded anyway.
+  for (; itr != frame.packets.rend() &&
+         new_ack_info.num_ack_blocks < std::numeric_limits<uint8_t>::max();
+       previous_start = itr->min(), ++itr) {
+    const auto& interval = *itr;
+    const QuicPacketCount total_gap = previous_start - interval.max();
+    new_ack_info.num_ack_blocks +=
+        (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
+        std::numeric_limits<uint8_t>::max();
+    new_ack_info.max_block_length =
+        std::max(new_ack_info.max_block_length, interval.Length());
+  }
+  return new_ack_info;
+}
+
+bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
+                                              QuicPacketHeader* header) {
+  QuicPacketNumber base_packet_number;
+  if (supports_multiple_packet_number_spaces_) {
+    PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
+    if (pn_space == NUM_PACKET_NUMBER_SPACES) {
+      set_detailed_error("Unable to determine packet number space.");
+      return RaiseError(QUIC_INVALID_PACKET_HEADER);
+    }
+    base_packet_number = largest_decrypted_packet_numbers_[pn_space];
+  } else {
+    base_packet_number = largest_packet_number_;
+  }
+  uint64_t full_packet_number;
+  if (!ProcessAndCalculatePacketNumber(
+          encrypted_reader, header->packet_number_length, base_packet_number,
+          &full_packet_number)) {
+    set_detailed_error("Unable to read packet number.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+
+  if (!IsValidFullPacketNumber(full_packet_number, version())) {
+    set_detailed_error("packet numbers cannot be 0.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  header->packet_number = QuicPacketNumber(full_packet_number);
+
+  if (!visitor_->OnUnauthenticatedHeader(*header)) {
+    set_detailed_error(
+        "Visitor asked to stop processing of unauthenticated header.");
+    return false;
+  }
+  // The function we are in is called because the framer believes that it is
+  // processing a packet that uses the non-IETF (i.e. Google QUIC) packet header
+  // type. Usually, the framer makes that decision based on the framer's
+  // version, but when the framer is used with Perspective::IS_SERVER, then
+  // before version negotiation is complete (specifically, before
+  // InferPacketHeaderTypeFromVersion is called), this decision is made based on
+  // the type byte of the packet.
+  //
+  // If the framer's version KnowsWhichDecrypterToUse, then that version expects
+  // to use the IETF packet header type. If that's the case and we're in this
+  // function, then the packet received is invalid: the framer was expecting an
+  // IETF packet header and didn't get one.
+  if (version().KnowsWhichDecrypterToUse()) {
+    set_detailed_error("Invalid public header type for expected version.");
+    return RaiseError(QUIC_INVALID_PACKET_HEADER);
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfHeaderTypeByte(QuicDataReader* reader,
+                                           QuicPacketHeader* header) {
+  uint8_t type;
+  if (!reader->ReadBytes(&type, 1)) {
+    set_detailed_error("Unable to read first byte.");
+    return false;
+  }
+  header->type_byte = type;
+  // Determine whether this is a long or short header.
+  header->form = GetIetfPacketHeaderFormat(type);
+  if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
+    // Version is always present in long headers.
+    header->version_flag = true;
+    // In versions that do not support client connection IDs, we mark the
+    // corresponding connection ID as absent.
+    header->destination_connection_id_included =
+        (perspective_ == Perspective::IS_SERVER ||
+         version_.SupportsClientConnectionIds())
+            ? CONNECTION_ID_PRESENT
+            : CONNECTION_ID_ABSENT;
+    header->source_connection_id_included =
+        (perspective_ == Perspective::IS_CLIENT ||
+         version_.SupportsClientConnectionIds())
+            ? CONNECTION_ID_PRESENT
+            : CONNECTION_ID_ABSENT;
+    // Read version tag.
+    QuicVersionLabel version_label;
+    if (!ProcessVersionLabel(reader, &version_label)) {
+      set_detailed_error("Unable to read protocol version.");
+      return false;
+    }
+    if (!version_label) {
+      // Version label is 0 indicating this is a version negotiation packet.
+      header->long_packet_type = VERSION_NEGOTIATION;
+    } else {
+      header->version = ParseQuicVersionLabel(version_label);
+      if (header->version.IsKnown()) {
+        if (!(type & FLAGS_FIXED_BIT)) {
+          set_detailed_error("Fixed bit is 0 in long header.");
+          return false;
+        }
+        header->long_packet_type = GetLongHeaderType(type, header->version);
+        switch (header->long_packet_type) {
+          case INVALID_PACKET_TYPE:
+            set_detailed_error("Illegal long header type value.");
+            return false;
+          case RETRY:
+            if (!version().SupportsRetry()) {
+              set_detailed_error("RETRY not supported in this version.");
+              return false;
+            }
+            if (perspective_ == Perspective::IS_SERVER) {
+              set_detailed_error("Client-initiated RETRY is invalid.");
+              return false;
+            }
+            break;
+          default:
+            if (!header->version.HasHeaderProtection()) {
+              header->packet_number_length =
+                  GetLongHeaderPacketNumberLength(type);
+            }
+            break;
+        }
+      }
+    }
+
+    QUIC_DVLOG(1) << ENDPOINT << "Received IETF long header: "
+                  << QuicUtils::QuicLongHeaderTypetoString(
+                         header->long_packet_type);
+    return true;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Received IETF short header";
+  // Version is not present in short headers.
+  header->version_flag = false;
+  // In versions that do not support client connection IDs, the client will not
+  // receive destination connection IDs.
+  header->destination_connection_id_included =
+      (perspective_ == Perspective::IS_SERVER ||
+       version_.SupportsClientConnectionIds())
+          ? CONNECTION_ID_PRESENT
+          : CONNECTION_ID_ABSENT;
+  header->source_connection_id_included = CONNECTION_ID_ABSENT;
+  if (!(type & FLAGS_FIXED_BIT)) {
+    set_detailed_error("Fixed bit is 0 in short header.");
+    return false;
+  }
+  if (!version_.HasHeaderProtection()) {
+    header->packet_number_length = GetShortHeaderPacketNumberLength(type);
+  }
+  QUIC_DVLOG(1) << "packet_number_length = " << header->packet_number_length;
+  return true;
+}
+
+// static
+bool QuicFramer::ProcessVersionLabel(QuicDataReader* reader,
+                                     QuicVersionLabel* version_label) {
+  if (!reader->ReadUInt32(version_label)) {
+    return false;
+  }
+  return true;
+}
+
+// static
+bool QuicFramer::ProcessAndValidateIetfConnectionIdLength(
+    QuicDataReader* reader, ParsedQuicVersion version, Perspective perspective,
+    bool should_update_expected_server_connection_id_length,
+    uint8_t* expected_server_connection_id_length,
+    uint8_t* destination_connection_id_length,
+    uint8_t* source_connection_id_length, std::string* detailed_error) {
+  uint8_t connection_id_lengths_byte;
+  if (!reader->ReadBytes(&connection_id_lengths_byte, 1)) {
+    *detailed_error = "Unable to read ConnectionId length.";
+    return false;
+  }
+  uint8_t dcil =
+      (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
+  if (dcil != 0) {
+    dcil += kConnectionIdLengthAdjustment;
+  }
+  uint8_t scil = connection_id_lengths_byte & kSourceConnectionIdLengthMask;
+  if (scil != 0) {
+    scil += kConnectionIdLengthAdjustment;
+  }
+  if (should_update_expected_server_connection_id_length) {
+    uint8_t server_connection_id_length =
+        perspective == Perspective::IS_SERVER ? dcil : scil;
+    if (*expected_server_connection_id_length != server_connection_id_length) {
+      QUIC_DVLOG(1) << "Updating expected_server_connection_id_length: "
+                    << static_cast<int>(*expected_server_connection_id_length)
+                    << " -> " << static_cast<int>(server_connection_id_length);
+      *expected_server_connection_id_length = server_connection_id_length;
+    }
+  }
+  if (!should_update_expected_server_connection_id_length &&
+      (dcil != *destination_connection_id_length ||
+       scil != *source_connection_id_length) &&
+      version.IsKnown() && !version.AllowsVariableLengthConnectionIds()) {
+    QUIC_DVLOG(1) << "dcil: " << static_cast<uint32_t>(dcil)
+                  << ", scil: " << static_cast<uint32_t>(scil);
+    *detailed_error = "Invalid ConnectionId length.";
+    return false;
+  }
+  *destination_connection_id_length = dcil;
+  *source_connection_id_length = scil;
+  return true;
+}
+
+bool QuicFramer::ValidateReceivedConnectionIds(const QuicPacketHeader& header) {
+  bool skip_server_connection_id_validation =
+      perspective_ == Perspective::IS_CLIENT &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+  if (!skip_server_connection_id_validation &&
+      !QuicUtils::IsConnectionIdValidForVersion(
+          GetServerConnectionIdAsRecipient(header, perspective_),
+          transport_version())) {
+    set_detailed_error("Received server connection ID with invalid length.");
+    return false;
+  }
+
+  bool skip_client_connection_id_validation =
+      perspective_ == Perspective::IS_SERVER &&
+      header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+  if (!skip_client_connection_id_validation &&
+      version_.SupportsClientConnectionIds() &&
+      !QuicUtils::IsConnectionIdValidForVersion(
+          GetClientConnectionIdAsRecipient(header, perspective_),
+          transport_version())) {
+    set_detailed_error("Received client connection ID with invalid length.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfPacketHeader(QuicDataReader* reader,
+                                         QuicPacketHeader* header) {
+  if (version_.HasLengthPrefixedConnectionIds()) {
+    uint8_t expected_destination_connection_id_length =
+        perspective_ == Perspective::IS_CLIENT
+            ? expected_client_connection_id_length_
+            : expected_server_connection_id_length_;
+    QuicVersionLabel version_label;
+    bool has_length_prefix;
+    std::string detailed_error;
+    QuicErrorCode parse_result = QuicFramer::ParsePublicHeader(
+        reader, expected_destination_connection_id_length,
+        version_.HasIetfInvariantHeader(), &header->type_byte, &header->form,
+        &header->version_flag, &has_length_prefix, &version_label,
+        &header->version, &header->destination_connection_id,
+        &header->source_connection_id, &header->long_packet_type,
+        &header->retry_token_length_length, &header->retry_token,
+        &detailed_error);
+    if (parse_result != QUIC_NO_ERROR) {
+      set_detailed_error(detailed_error);
+      return false;
+    }
+    header->destination_connection_id_included = CONNECTION_ID_PRESENT;
+    header->source_connection_id_included =
+        header->version_flag ? CONNECTION_ID_PRESENT : CONNECTION_ID_ABSENT;
+
+    if (!ValidateReceivedConnectionIds(*header)) {
+      return false;
+    }
+
+    if (header->version_flag &&
+        header->long_packet_type != VERSION_NEGOTIATION &&
+        !(header->type_byte & FLAGS_FIXED_BIT)) {
+      set_detailed_error("Fixed bit is 0 in long header.");
+      return false;
+    }
+    if (!header->version_flag && !(header->type_byte & FLAGS_FIXED_BIT)) {
+      set_detailed_error("Fixed bit is 0 in short header.");
+      return false;
+    }
+    if (!header->version_flag) {
+      if (!version_.HasHeaderProtection()) {
+        header->packet_number_length =
+            GetShortHeaderPacketNumberLength(header->type_byte);
+      }
+      return true;
+    }
+    if (header->long_packet_type == RETRY) {
+      if (!version().SupportsRetry()) {
+        set_detailed_error("RETRY not supported in this version.");
+        return false;
+      }
+      if (perspective_ == Perspective::IS_SERVER) {
+        set_detailed_error("Client-initiated RETRY is invalid.");
+        return false;
+      }
+      return true;
+    }
+    if (header->version.IsKnown() && !header->version.HasHeaderProtection()) {
+      header->packet_number_length =
+          GetLongHeaderPacketNumberLength(header->type_byte);
+    }
+
+    return true;
+  }
+
+  if (!ProcessIetfHeaderTypeByte(reader, header)) {
+    return false;
+  }
+
+  uint8_t destination_connection_id_length =
+      header->destination_connection_id_included == CONNECTION_ID_PRESENT
+          ? (perspective_ == Perspective::IS_SERVER
+                 ? expected_server_connection_id_length_
+                 : expected_client_connection_id_length_)
+          : 0;
+  uint8_t source_connection_id_length =
+      header->source_connection_id_included == CONNECTION_ID_PRESENT
+          ? (perspective_ == Perspective::IS_CLIENT
+                 ? expected_server_connection_id_length_
+                 : expected_client_connection_id_length_)
+          : 0;
+  if (header->form == IETF_QUIC_LONG_HEADER_PACKET) {
+    if (!ProcessAndValidateIetfConnectionIdLength(
+            reader, header->version, perspective_,
+            /*should_update_expected_server_connection_id_length=*/false,
+            &expected_server_connection_id_length_,
+            &destination_connection_id_length, &source_connection_id_length,
+            &detailed_error_)) {
+      return false;
+    }
+  }
+
+  // Read connection ID.
+  if (!reader->ReadConnectionId(&header->destination_connection_id,
+                                destination_connection_id_length)) {
+    set_detailed_error("Unable to read destination connection ID.");
+    return false;
+  }
+
+  if (!reader->ReadConnectionId(&header->source_connection_id,
+                                source_connection_id_length)) {
+    set_detailed_error("Unable to read source connection ID.");
+    return false;
+  }
+
+  if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
+    if (!header->source_connection_id.IsEmpty()) {
+      QUICHE_DCHECK(!version_.SupportsClientConnectionIds());
+      set_detailed_error("Client connection ID not supported in this version.");
+      return false;
+    }
+  }
+
+  return ValidateReceivedConnectionIds(*header);
+}
+
+bool QuicFramer::ProcessAndCalculatePacketNumber(
+    QuicDataReader* reader, QuicPacketNumberLength packet_number_length,
+    QuicPacketNumber base_packet_number, uint64_t* packet_number) {
+  uint64_t wire_packet_number;
+  if (!reader->ReadBytesToUInt64(packet_number_length, &wire_packet_number)) {
+    return false;
+  }
+
+  // TODO(ianswett): Explore the usefulness of trying multiple packet numbers
+  // in case the first guess is incorrect.
+  *packet_number = CalculatePacketNumberFromWire(
+      packet_number_length, base_packet_number, wire_packet_number);
+  return true;
+}
+
+bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
+                                  const QuicPacketHeader& header) {
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
+      << "IETF QUIC Framing negotiated but attempting to process frames as "
+         "non-IETF QUIC.";
+  if (reader->IsDoneReading()) {
+    set_detailed_error("Packet has no frames.");
+    return RaiseError(QUIC_MISSING_PAYLOAD);
+  }
+  QUIC_DVLOG(2) << ENDPOINT << "Processing packet with header " << header;
+  while (!reader->IsDoneReading()) {
+    uint8_t frame_type;
+    if (!reader->ReadBytes(&frame_type, 1)) {
+      set_detailed_error("Unable to read frame type.");
+      return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+    const uint8_t special_mask = version_.HasIetfInvariantHeader()
+                                     ? kQuicFrameTypeSpecialMask
+                                     : kQuicFrameTypeBrokenMask;
+    if (frame_type & special_mask) {
+      // Stream Frame
+      if (frame_type & kQuicFrameTypeStreamMask) {
+        QuicStreamFrame frame;
+        if (!ProcessStreamFrame(reader, frame_type, &frame)) {
+          return RaiseError(QUIC_INVALID_STREAM_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing stream frame " << frame;
+        if (!visitor_->OnStreamFrame(frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      // Ack Frame
+      if (frame_type & kQuicFrameTypeAckMask) {
+        if (!ProcessAckFrame(reader, frame_type)) {
+          return RaiseError(QUIC_INVALID_ACK_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing ACK frame";
+        continue;
+      }
+
+      // This was a special frame type that did not match any
+      // of the known ones. Error.
+      set_detailed_error("Illegal frame type.");
+      QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
+                         << static_cast<int>(frame_type);
+      return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+
+    switch (frame_type) {
+      case PADDING_FRAME: {
+        QuicPaddingFrame frame;
+        ProcessPaddingFrame(reader, &frame);
+        QUIC_DVLOG(2) << ENDPOINT << "Processing padding frame " << frame;
+        if (!visitor_->OnPaddingFrame(frame)) {
+          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case RST_STREAM_FRAME: {
+        QuicRstStreamFrame frame;
+        if (!ProcessRstStreamFrame(reader, &frame)) {
+          return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing reset stream frame " << frame;
+        if (!visitor_->OnRstStreamFrame(frame)) {
+          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case CONNECTION_CLOSE_FRAME: {
+        QuicConnectionCloseFrame frame;
+        if (!ProcessConnectionCloseFrame(reader, &frame)) {
+          return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+        }
+
+        QUIC_DVLOG(2) << ENDPOINT << "Processing connection close frame "
+                      << frame;
+        if (!visitor_->OnConnectionCloseFrame(frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case GOAWAY_FRAME: {
+        QuicGoAwayFrame goaway_frame;
+        if (!ProcessGoAwayFrame(reader, &goaway_frame)) {
+          return RaiseError(QUIC_INVALID_GOAWAY_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing go away frame "
+                      << goaway_frame;
+        if (!visitor_->OnGoAwayFrame(goaway_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case WINDOW_UPDATE_FRAME: {
+        QuicWindowUpdateFrame window_update_frame;
+        if (!ProcessWindowUpdateFrame(reader, &window_update_frame)) {
+          return RaiseError(QUIC_INVALID_WINDOW_UPDATE_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing window update frame "
+                      << window_update_frame;
+        if (!visitor_->OnWindowUpdateFrame(window_update_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case BLOCKED_FRAME: {
+        QuicBlockedFrame blocked_frame;
+        if (!ProcessBlockedFrame(reader, &blocked_frame)) {
+          return RaiseError(QUIC_INVALID_BLOCKED_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing blocked frame "
+                      << blocked_frame;
+        if (!visitor_->OnBlockedFrame(blocked_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+
+      case STOP_WAITING_FRAME: {
+        QuicStopWaitingFrame stop_waiting_frame;
+        if (!ProcessStopWaitingFrame(reader, header, &stop_waiting_frame)) {
+          return RaiseError(QUIC_INVALID_STOP_WAITING_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing stop waiting frame "
+                      << stop_waiting_frame;
+        if (!visitor_->OnStopWaitingFrame(stop_waiting_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        continue;
+      }
+      case PING_FRAME: {
+        // Ping has no payload.
+        QuicPingFrame ping_frame;
+        if (!visitor_->OnPingFrame(ping_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing ping frame " << ping_frame;
+        continue;
+      }
+      case IETF_EXTENSION_MESSAGE_NO_LENGTH:
+        ABSL_FALLTHROUGH_INTENDED;
+      case IETF_EXTENSION_MESSAGE: {
+        QuicMessageFrame message_frame;
+        if (!ProcessMessageFrame(reader,
+                                 frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH,
+                                 &message_frame)) {
+          return RaiseError(QUIC_INVALID_MESSAGE_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing message frame "
+                      << message_frame;
+        if (!visitor_->OnMessageFrame(message_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        break;
+      }
+      case CRYPTO_FRAME: {
+        if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
+          set_detailed_error("Illegal frame type.");
+          return RaiseError(QUIC_INVALID_FRAME_DATA);
+        }
+        QuicCryptoFrame frame;
+        if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
+          return RaiseError(QUIC_INVALID_FRAME_DATA);
+        }
+        QUIC_DVLOG(2) << ENDPOINT << "Processing crypto frame " << frame;
+        if (!visitor_->OnCryptoFrame(frame)) {
+          QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        break;
+      }
+      case HANDSHAKE_DONE_FRAME: {
+        // HANDSHAKE_DONE has no payload.
+        QuicHandshakeDoneFrame handshake_done_frame;
+        QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
+                      << handshake_done_frame;
+        if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
+          QUIC_DVLOG(1) << ENDPOINT
+                        << "Visitor asked to stop further processing.";
+          // Returning true since there was no parsing error.
+          return true;
+        }
+        break;
+      }
+
+      default:
+        set_detailed_error("Illegal frame type.");
+        QUIC_DLOG(WARNING) << ENDPOINT << "Illegal frame type: "
+                           << static_cast<int>(frame_type);
+        return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+  }
+
+  return true;
+}
+
+// static
+bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
+    uint64_t frame_type, EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+    case ENCRYPTION_HANDSHAKE:
+      return frame_type == IETF_CRYPTO || frame_type == IETF_ACK ||
+             frame_type == IETF_ACK_ECN ||
+             frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
+             frame_type == IETF_PING || frame_type == IETF_PADDING ||
+             frame_type == IETF_CONNECTION_CLOSE;
+    case ENCRYPTION_ZERO_RTT:
+      return !(frame_type == IETF_ACK || frame_type == IETF_ACK_ECN ||
+               frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
+               frame_type == IETF_CRYPTO || frame_type == IETF_HANDSHAKE_DONE ||
+               frame_type == IETF_NEW_TOKEN ||
+               frame_type == IETF_PATH_RESPONSE ||
+               frame_type == IETF_RETIRE_CONNECTION_ID);
+    case ENCRYPTION_FORWARD_SECURE:
+      return true;
+    default:
+      QUIC_BUG(quic_bug_10850_57) << "Unknown encryption level: " << level;
+  }
+  return false;
+}
+
+bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader,
+                                      const QuicPacketHeader& header,
+                                      EncryptionLevel decrypted_level) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version))
+      << "Attempt to process frames as IETF frames but version ("
+      << version_.transport_version << ") does not support IETF Framing.";
+
+  if (reader->IsDoneReading()) {
+    set_detailed_error("Packet has no frames.");
+    return RaiseError(QUIC_MISSING_PAYLOAD);
+  }
+
+  QUIC_DVLOG(2) << ENDPOINT << "Processing IETF packet with header " << header;
+  while (!reader->IsDoneReading()) {
+    uint64_t frame_type;
+    // Will be the number of bytes into which frame_type was encoded.
+    size_t encoded_bytes = reader->BytesRemaining();
+    if (!reader->ReadVarInt62(&frame_type)) {
+      set_detailed_error("Unable to read frame type.");
+      return RaiseError(QUIC_INVALID_FRAME_DATA);
+    }
+    if (!IsIetfFrameTypeExpectedForEncryptionLevel(frame_type,
+                                                   decrypted_level)) {
+      set_detailed_error(absl::StrCat(
+          "IETF frame type ",
+          QuicIetfFrameTypeString(static_cast<QuicIetfFrameType>(frame_type)),
+          " is unexpected at encryption level ",
+          EncryptionLevelToString(decrypted_level)));
+      return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
+    }
+    previously_received_frame_type_ = current_received_frame_type_;
+    current_received_frame_type_ = frame_type;
+
+    // Is now the number of bytes into which the frame type was encoded.
+    encoded_bytes -= reader->BytesRemaining();
+
+    // Check that the frame type is minimally encoded.
+    if (encoded_bytes !=
+        static_cast<size_t>(QuicDataWriter::GetVarInt62Len(frame_type))) {
+      // The frame type was not minimally encoded.
+      set_detailed_error("Frame type not minimally encoded.");
+      return RaiseError(IETF_QUIC_PROTOCOL_VIOLATION);
+    }
+
+    if (IS_IETF_STREAM_FRAME(frame_type)) {
+      QuicStreamFrame frame;
+      if (!ProcessIetfStreamFrame(reader, frame_type, &frame)) {
+        return RaiseError(QUIC_INVALID_STREAM_DATA);
+      }
+      QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream frame " << frame;
+      if (!visitor_->OnStreamFrame(frame)) {
+        QUIC_DVLOG(1) << ENDPOINT
+                      << "Visitor asked to stop further processing.";
+        // Returning true since there was no parsing error.
+        return true;
+      }
+    } else {
+      switch (frame_type) {
+        case IETF_PADDING: {
+          QuicPaddingFrame frame;
+          ProcessPaddingFrame(reader, &frame);
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF padding frame "
+                        << frame;
+          if (!visitor_->OnPaddingFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_RST_STREAM: {
+          QuicRstStreamFrame frame;
+          if (!ProcessIetfResetStreamFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF reset stream frame "
+                        << frame;
+          if (!visitor_->OnRstStreamFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_APPLICATION_CLOSE:
+        case IETF_CONNECTION_CLOSE: {
+          QuicConnectionCloseFrame frame;
+          if (!ProcessIetfConnectionCloseFrame(
+                  reader,
+                  (frame_type == IETF_CONNECTION_CLOSE)
+                      ? IETF_QUIC_TRANSPORT_CONNECTION_CLOSE
+                      : IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+                  &frame)) {
+            return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF connection close frame "
+                        << frame;
+          if (!visitor_->OnConnectionCloseFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_MAX_DATA: {
+          QuicWindowUpdateFrame frame;
+          if (!ProcessMaxDataFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_MAX_DATA_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max data frame "
+                        << frame;
+          if (!visitor_->OnWindowUpdateFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_MAX_STREAM_DATA: {
+          QuicWindowUpdateFrame frame;
+          if (!ProcessMaxStreamDataFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max stream data frame "
+                        << frame;
+          if (!visitor_->OnWindowUpdateFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_MAX_STREAMS_BIDIRECTIONAL:
+        case IETF_MAX_STREAMS_UNIDIRECTIONAL: {
+          QuicMaxStreamsFrame frame;
+          if (!ProcessMaxStreamsFrame(reader, &frame, frame_type)) {
+            return RaiseError(QUIC_MAX_STREAMS_DATA);
+          }
+          QUIC_CODE_COUNT_N(quic_max_streams_received, 1, 2);
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF max streams frame "
+                        << frame;
+          if (!visitor_->OnMaxStreamsFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_PING: {
+          // Ping has no payload.
+          QuicPingFrame ping_frame;
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ping frame "
+                        << ping_frame;
+          if (!visitor_->OnPingFrame(ping_frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_DATA_BLOCKED: {
+          QuicBlockedFrame frame;
+          if (!ProcessDataBlockedFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_BLOCKED_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF blocked frame "
+                        << frame;
+          if (!visitor_->OnBlockedFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_STREAM_DATA_BLOCKED: {
+          QuicBlockedFrame frame;
+          if (!ProcessStreamDataBlockedFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_STREAM_BLOCKED_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stream blocked frame "
+                        << frame;
+          if (!visitor_->OnBlockedFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_STREAMS_BLOCKED_UNIDIRECTIONAL:
+        case IETF_STREAMS_BLOCKED_BIDIRECTIONAL: {
+          QuicStreamsBlockedFrame frame;
+          if (!ProcessStreamsBlockedFrame(reader, &frame, frame_type)) {
+            return RaiseError(QUIC_STREAMS_BLOCKED_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF streams blocked frame "
+                        << frame;
+          if (!visitor_->OnStreamsBlockedFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_NEW_CONNECTION_ID: {
+          QuicNewConnectionIdFrame frame;
+          if (!ProcessNewConnectionIdFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT
+                        << "Processing IETF new connection ID frame " << frame;
+          if (!visitor_->OnNewConnectionIdFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_RETIRE_CONNECTION_ID: {
+          QuicRetireConnectionIdFrame frame;
+          if (!ProcessRetireConnectionIdFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT
+                        << "Processing IETF retire connection ID frame "
+                        << frame;
+          if (!visitor_->OnRetireConnectionIdFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_NEW_TOKEN: {
+          QuicNewTokenFrame frame;
+          if (!ProcessNewTokenFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_NEW_TOKEN);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF new token frame "
+                        << frame;
+          if (!visitor_->OnNewTokenFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_STOP_SENDING: {
+          QuicStopSendingFrame frame;
+          if (!ProcessStopSendingFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_STOP_SENDING_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF stop sending frame "
+                        << frame;
+          if (!visitor_->OnStopSendingFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_ACK_RECEIVE_TIMESTAMPS:
+          if (!process_timestamps_) {
+            set_detailed_error("Unsupported frame type.");
+            QUIC_DLOG(WARNING)
+                << ENDPOINT << "IETF_ACK_RECEIVE_TIMESTAMPS not supported";
+            return RaiseError(QUIC_INVALID_FRAME_DATA);
+          }
+          ABSL_FALLTHROUGH_INTENDED;
+        case IETF_ACK_ECN:
+        case IETF_ACK: {
+          QuicAckFrame frame;
+          if (!ProcessIetfAckFrame(reader, frame_type, &frame)) {
+            return RaiseError(QUIC_INVALID_ACK_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ACK frame " << frame;
+          break;
+        }
+        case IETF_PATH_CHALLENGE: {
+          QuicPathChallengeFrame frame;
+          if (!ProcessPathChallengeFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_PATH_CHALLENGE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path challenge frame "
+                        << frame;
+          if (!visitor_->OnPathChallengeFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_PATH_RESPONSE: {
+          QuicPathResponseFrame frame;
+          if (!ProcessPathResponseFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_PATH_RESPONSE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF path response frame "
+                        << frame;
+          if (!visitor_->OnPathResponseFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_EXTENSION_MESSAGE_NO_LENGTH_V99:
+          ABSL_FALLTHROUGH_INTENDED;
+        case IETF_EXTENSION_MESSAGE_V99: {
+          QuicMessageFrame message_frame;
+          if (!ProcessMessageFrame(
+                  reader, frame_type == IETF_EXTENSION_MESSAGE_NO_LENGTH_V99,
+                  &message_frame)) {
+            return RaiseError(QUIC_INVALID_MESSAGE_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF message frame "
+                        << message_frame;
+          if (!visitor_->OnMessageFrame(message_frame)) {
+            QUIC_DVLOG(1) << ENDPOINT
+                          << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_CRYPTO: {
+          QuicCryptoFrame frame;
+          if (!ProcessCryptoFrame(reader, GetEncryptionLevel(header), &frame)) {
+            return RaiseError(QUIC_INVALID_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF crypto frame " << frame;
+          if (!visitor_->OnCryptoFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        case IETF_HANDSHAKE_DONE: {
+          // HANDSHAKE_DONE has no payload.
+          QuicHandshakeDoneFrame handshake_done_frame;
+          if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
+            QUIC_DVLOG(1) << ENDPOINT
+                          << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
+                        << handshake_done_frame;
+          break;
+        }
+        case IETF_ACK_FREQUENCY: {
+          QuicAckFrequencyFrame frame;
+          if (!ProcessAckFrequencyFrame(reader, &frame)) {
+            return RaiseError(QUIC_INVALID_FRAME_DATA);
+          }
+          QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ack frequency frame "
+                        << frame;
+          if (!visitor_->OnAckFrequencyFrame(frame)) {
+            QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+            // Returning true since there was no parsing error.
+            return true;
+          }
+          break;
+        }
+        default:
+          set_detailed_error("Illegal frame type.");
+          QUIC_DLOG(WARNING)
+              << ENDPOINT
+              << "Illegal frame type: " << static_cast<int>(frame_type);
+          return RaiseError(QUIC_INVALID_FRAME_DATA);
+      }
+    }
+  }
+  return true;
+}
+
+namespace {
+// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
+inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
+  return (1u << num_bits) - 1;
+}
+
+// Extract |num_bits| from |flags| offset by |offset|.
+uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
+  return (flags >> offset) & GetMaskFromNumBits(num_bits);
+}
+
+// Extract the bit at position |offset| from |flags| as a bool.
+bool ExtractBit(uint8_t flags, uint8_t offset) {
+  return ((flags >> offset) & GetMaskFromNumBits(1)) != 0;
+}
+
+// Set |num_bits|, offset by |offset| to |val| in |flags|.
+void SetBits(uint8_t* flags, uint8_t val, uint8_t num_bits, uint8_t offset) {
+  QUICHE_DCHECK_LE(val, GetMaskFromNumBits(num_bits));
+  *flags |= val << offset;
+}
+
+// Set the bit at position |offset| to |val| in |flags|.
+void SetBit(uint8_t* flags, bool val, uint8_t offset) {
+  SetBits(flags, val ? 1 : 0, 1, offset);
+}
+}  // namespace
+
+bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader, uint8_t frame_type,
+                                    QuicStreamFrame* frame) {
+  uint8_t stream_flags = frame_type;
+
+  uint8_t stream_id_length = 0;
+  uint8_t offset_length = 4;
+  bool has_data_length = true;
+  stream_flags &= ~kQuicFrameTypeStreamMask;
+
+  // Read from right to left: StreamID, Offset, Data Length, Fin.
+  stream_id_length = (stream_flags & kQuicStreamIDLengthMask) + 1;
+  stream_flags >>= kQuicStreamIdShift;
+
+  offset_length = (stream_flags & kQuicStreamOffsetMask);
+  // There is no encoding for 1 byte, only 0 and 2 through 8.
+  if (offset_length > 0) {
+    offset_length += 1;
+  }
+  stream_flags >>= kQuicStreamShift;
+
+  has_data_length =
+      (stream_flags & kQuicStreamDataLengthMask) == kQuicStreamDataLengthMask;
+  stream_flags >>= kQuicStreamDataLengthShift;
+
+  frame->fin = (stream_flags & kQuicStreamFinMask) == kQuicStreamFinShift;
+
+  uint64_t stream_id;
+  if (!reader->ReadBytesToUInt64(stream_id_length, &stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+  frame->stream_id = static_cast<QuicStreamId>(stream_id);
+
+  if (!reader->ReadBytesToUInt64(offset_length, &frame->offset)) {
+    set_detailed_error("Unable to read offset.");
+    return false;
+  }
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (has_data_length) {
+    if (!reader->ReadStringPiece16(&data)) {
+      set_detailed_error("Unable to read frame data.");
+      return false;
+    }
+  } else {
+    if (!reader->ReadStringPiece(&data, reader->BytesRemaining())) {
+      set_detailed_error("Unable to read frame data.");
+      return false;
+    }
+  }
+  frame->data_buffer = data.data();
+  frame->data_length = static_cast<uint16_t>(data.length());
+
+  return true;
+}
+
+bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader,
+                                        uint8_t frame_type,
+                                        QuicStreamFrame* frame) {
+  // Read stream id from the frame. It's always present.
+  if (!ReadUint32FromVarint62(reader, IETF_STREAM, &frame->stream_id)) {
+    return false;
+  }
+
+  // If we have a data offset, read it. If not, set to 0.
+  if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
+    if (!reader->ReadVarInt62(&frame->offset)) {
+      set_detailed_error("Unable to read stream data offset.");
+      return false;
+    }
+  } else {
+    // no offset in the frame, ensure it's 0 in the Frame.
+    frame->offset = 0;
+  }
+
+  // If we have a data length, read it. If not, set to 0.
+  if (frame_type & IETF_STREAM_FRAME_LEN_BIT) {
+    uint64_t length;
+    if (!reader->ReadVarInt62(&length)) {
+      set_detailed_error("Unable to read stream data length.");
+      return false;
+    }
+    if (length > std::numeric_limits<decltype(frame->data_length)>::max()) {
+      set_detailed_error("Stream data length is too large.");
+      return false;
+    }
+    frame->data_length = length;
+  } else {
+    // no length in the frame, it is the number of bytes remaining in the
+    // packet.
+    frame->data_length = reader->BytesRemaining();
+  }
+
+  if (frame_type & IETF_STREAM_FRAME_FIN_BIT) {
+    frame->fin = true;
+  } else {
+    frame->fin = false;
+  }
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (!reader->ReadStringPiece(&data, frame->data_length)) {
+    set_detailed_error("Unable to read frame data.");
+    return false;
+  }
+  frame->data_buffer = data.data();
+  QUICHE_DCHECK_EQ(frame->data_length, data.length());
+
+  return true;
+}
+
+bool QuicFramer::ProcessCryptoFrame(QuicDataReader* reader,
+                                    EncryptionLevel encryption_level,
+                                    QuicCryptoFrame* frame) {
+  frame->level = encryption_level;
+  if (!reader->ReadVarInt62(&frame->offset)) {
+    set_detailed_error("Unable to read crypto data offset.");
+    return false;
+  }
+  uint64_t len;
+  if (!reader->ReadVarInt62(&len) ||
+      len > std::numeric_limits<QuicPacketLength>::max()) {
+    set_detailed_error("Invalid data length.");
+    return false;
+  }
+  frame->data_length = len;
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (!reader->ReadStringPiece(&data, frame->data_length)) {
+    set_detailed_error("Unable to read frame data.");
+    return false;
+  }
+  frame->data_buffer = data.data();
+  return true;
+}
+
+bool QuicFramer::ProcessAckFrequencyFrame(QuicDataReader* reader,
+                                          QuicAckFrequencyFrame* frame) {
+  if (!reader->ReadVarInt62(&frame->sequence_number)) {
+    set_detailed_error("Unable to read sequence number.");
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&frame->packet_tolerance)) {
+    set_detailed_error("Unable to read packet tolerance.");
+    return false;
+  }
+  if (frame->packet_tolerance == 0) {
+    set_detailed_error("Invalid packet tolerance.");
+    return false;
+  }
+  uint64_t max_ack_delay_us;
+  if (!reader->ReadVarInt62(&max_ack_delay_us)) {
+    set_detailed_error("Unable to read max_ack_delay_us.");
+    return false;
+  }
+  constexpr uint64_t kMaxAckDelayUsBound = 1u << 24;
+  if (max_ack_delay_us > kMaxAckDelayUsBound) {
+    set_detailed_error("Invalid max_ack_delay_us.");
+    return false;
+  }
+  frame->max_ack_delay = QuicTime::Delta::FromMicroseconds(max_ack_delay_us);
+
+  uint8_t ignore_order;
+  if (!reader->ReadUInt8(&ignore_order)) {
+    set_detailed_error("Unable to read ignore_order.");
+    return false;
+  }
+  if (ignore_order > 1) {
+    set_detailed_error("Invalid ignore_order.");
+    return false;
+  }
+  frame->ignore_order = ignore_order;
+
+  return true;
+}
+
+bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
+  const bool has_ack_blocks =
+      ExtractBit(frame_type, kQuicHasMultipleAckBlocksOffset);
+  uint8_t num_ack_blocks = 0;
+  uint8_t num_received_packets = 0;
+
+  // Determine the two lengths from the frame type: largest acked length,
+  // ack block length.
+  const QuicPacketNumberLength ack_block_length =
+      ReadAckPacketNumberLength(ExtractBits(
+          frame_type, kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset));
+  const QuicPacketNumberLength largest_acked_length =
+      ReadAckPacketNumberLength(ExtractBits(
+          frame_type, kQuicSequenceNumberLengthNumBits, kLargestAckedOffset));
+
+  uint64_t largest_acked;
+  if (!reader->ReadBytesToUInt64(largest_acked_length, &largest_acked)) {
+    set_detailed_error("Unable to read largest acked.");
+    return false;
+  }
+
+  if (largest_acked < first_sending_packet_number_.ToUint64()) {
+    // Connection always sends packet starting from kFirstSendingPacketNumber >
+    // 0, peer has observed an unsent packet.
+    set_detailed_error("Largest acked is 0.");
+    return false;
+  }
+
+  uint64_t ack_delay_time_us;
+  if (!reader->ReadUFloat16(&ack_delay_time_us)) {
+    set_detailed_error("Unable to read ack delay time.");
+    return false;
+  }
+
+  if (!visitor_->OnAckFrameStart(
+          QuicPacketNumber(largest_acked),
+          ack_delay_time_us == kUFloat16MaxValue
+              ? QuicTime::Delta::Infinite()
+              : QuicTime::Delta::FromMicroseconds(ack_delay_time_us))) {
+    // The visitor suppresses further processing of the packet. Although this is
+    // not a parsing error, returns false as this is in middle of processing an
+    // ack frame,
+    set_detailed_error("Visitor suppresses further processing of ack frame.");
+    return false;
+  }
+
+  if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) {
+    set_detailed_error("Unable to read num of ack blocks.");
+    return false;
+  }
+
+  uint64_t first_block_length;
+  if (!reader->ReadBytesToUInt64(ack_block_length, &first_block_length)) {
+    set_detailed_error("Unable to read first ack block length.");
+    return false;
+  }
+
+  if (first_block_length == 0) {
+    set_detailed_error("First block length is zero.");
+    return false;
+  }
+  bool first_ack_block_underflow = first_block_length > largest_acked + 1;
+  if (first_block_length + first_sending_packet_number_.ToUint64() >
+      largest_acked + 1) {
+    first_ack_block_underflow = true;
+  }
+  if (first_ack_block_underflow) {
+    set_detailed_error(absl::StrCat("Underflow with first ack block length ",
+                                    first_block_length, " largest acked is ",
+                                    largest_acked, ".")
+                           .c_str());
+    return false;
+  }
+
+  uint64_t first_received = largest_acked + 1 - first_block_length;
+  if (!visitor_->OnAckRange(QuicPacketNumber(first_received),
+                            QuicPacketNumber(largest_acked + 1))) {
+    // The visitor suppresses further processing of the packet. Although
+    // this is not a parsing error, returns false as this is in middle
+    // of processing an ack frame,
+    set_detailed_error("Visitor suppresses further processing of ack frame.");
+    return false;
+  }
+
+  if (num_ack_blocks > 0) {
+    for (size_t i = 0; i < num_ack_blocks; ++i) {
+      uint8_t gap = 0;
+      if (!reader->ReadUInt8(&gap)) {
+        set_detailed_error("Unable to read gap to next ack block.");
+        return false;
+      }
+      uint64_t current_block_length;
+      if (!reader->ReadBytesToUInt64(ack_block_length, &current_block_length)) {
+        set_detailed_error("Unable to ack block length.");
+        return false;
+      }
+      bool ack_block_underflow = first_received < gap + current_block_length;
+      if (first_received < gap + current_block_length +
+                               first_sending_packet_number_.ToUint64()) {
+        ack_block_underflow = true;
+      }
+      if (ack_block_underflow) {
+        set_detailed_error(absl::StrCat("Underflow with ack block length ",
+                                        current_block_length,
+                                        ", end of block is ",
+                                        first_received - gap, ".")
+                               .c_str());
+        return false;
+      }
+
+      first_received -= (gap + current_block_length);
+      if (current_block_length > 0) {
+        if (!visitor_->OnAckRange(
+                QuicPacketNumber(first_received),
+                QuicPacketNumber(first_received) + current_block_length)) {
+          // The visitor suppresses further processing of the packet. Although
+          // this is not a parsing error, returns false as this is in middle
+          // of processing an ack frame,
+          set_detailed_error(
+              "Visitor suppresses further processing of ack frame.");
+          return false;
+        }
+      }
+    }
+  }
+
+  if (!reader->ReadUInt8(&num_received_packets)) {
+    set_detailed_error("Unable to read num received packets.");
+    return false;
+  }
+
+  if (!ProcessTimestampsInAckFrame(num_received_packets,
+                                   QuicPacketNumber(largest_acked), reader)) {
+    return false;
+  }
+
+  // Done processing the ACK frame.
+  if (!visitor_->OnAckFrameEnd(QuicPacketNumber(first_received))) {
+    set_detailed_error(
+        "Error occurs when visitor finishes processing the ACK frame.");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
+                                             QuicPacketNumber largest_acked,
+                                             QuicDataReader* reader) {
+  if (num_received_packets == 0) {
+    return true;
+  }
+  uint8_t delta_from_largest_observed;
+  if (!reader->ReadUInt8(&delta_from_largest_observed)) {
+    set_detailed_error("Unable to read sequence delta in received packets.");
+    return false;
+  }
+
+  if (largest_acked.ToUint64() <= delta_from_largest_observed) {
+    set_detailed_error(
+        absl::StrCat("delta_from_largest_observed too high: ",
+                     delta_from_largest_observed,
+                     ", largest_acked: ", largest_acked.ToUint64())
+            .c_str());
+    return false;
+  }
+
+  // Time delta from the framer creation.
+  uint32_t time_delta_us;
+  if (!reader->ReadUInt32(&time_delta_us)) {
+    set_detailed_error("Unable to read time delta in received packets.");
+    return false;
+  }
+
+  QuicPacketNumber seq_num = largest_acked - delta_from_largest_observed;
+  if (process_timestamps_) {
+    last_timestamp_ = CalculateTimestampFromWire(time_delta_us);
+
+    visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
+  }
+
+  for (uint8_t i = 1; i < num_received_packets; ++i) {
+    if (!reader->ReadUInt8(&delta_from_largest_observed)) {
+      set_detailed_error("Unable to read sequence delta in received packets.");
+      return false;
+    }
+    if (largest_acked.ToUint64() <= delta_from_largest_observed) {
+      set_detailed_error(
+          absl::StrCat("delta_from_largest_observed too high: ",
+                       delta_from_largest_observed,
+                       ", largest_acked: ", largest_acked.ToUint64())
+              .c_str());
+      return false;
+    }
+    seq_num = largest_acked - delta_from_largest_observed;
+
+    // Time delta from the previous timestamp.
+    uint64_t incremental_time_delta_us;
+    if (!reader->ReadUFloat16(&incremental_time_delta_us)) {
+      set_detailed_error(
+          "Unable to read incremental time delta in received packets.");
+      return false;
+    }
+
+    if (process_timestamps_) {
+      last_timestamp_ = last_timestamp_ + QuicTime::Delta::FromMicroseconds(
+                                              incremental_time_delta_us);
+      visitor_->OnAckTimestamp(seq_num, creation_time_ + last_timestamp_);
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfAckFrame(QuicDataReader* reader,
+                                     uint64_t frame_type,
+                                     QuicAckFrame* ack_frame) {
+  uint64_t largest_acked;
+  if (!reader->ReadVarInt62(&largest_acked)) {
+    set_detailed_error("Unable to read largest acked.");
+    return false;
+  }
+  if (largest_acked < first_sending_packet_number_.ToUint64()) {
+    // Connection always sends packet starting from kFirstSendingPacketNumber >
+    // 0, peer has observed an unsent packet.
+    set_detailed_error("Largest acked is 0.");
+    return false;
+  }
+  ack_frame->largest_acked = static_cast<QuicPacketNumber>(largest_acked);
+  uint64_t ack_delay_time_in_us;
+  if (!reader->ReadVarInt62(&ack_delay_time_in_us)) {
+    set_detailed_error("Unable to read ack delay time.");
+    return false;
+  }
+
+  if (ack_delay_time_in_us >= (kVarInt62MaxValue >> peer_ack_delay_exponent_)) {
+    ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
+  } else {
+    ack_delay_time_in_us = (ack_delay_time_in_us << peer_ack_delay_exponent_);
+    ack_frame->ack_delay_time =
+        QuicTime::Delta::FromMicroseconds(ack_delay_time_in_us);
+  }
+  if (!visitor_->OnAckFrameStart(QuicPacketNumber(largest_acked),
+                                 ack_frame->ack_delay_time)) {
+    // The visitor suppresses further processing of the packet. Although this is
+    // not a parsing error, returns false as this is in middle of processing an
+    // ACK frame.
+    set_detailed_error("Visitor suppresses further processing of ACK frame.");
+    return false;
+  }
+
+  // Get number of ACK blocks from the packet.
+  uint64_t ack_block_count;
+  if (!reader->ReadVarInt62(&ack_block_count)) {
+    set_detailed_error("Unable to read ack block count.");
+    return false;
+  }
+  // There always is a first ACK block, which is the (number of packets being
+  // acked)-1, up to and including the packet at largest_acked. Therefore if the
+  // value is 0, then only largest is acked. If it is 1, then largest-1,
+  // largest] are acked, etc
+  uint64_t ack_block_value;
+  if (!reader->ReadVarInt62(&ack_block_value)) {
+    set_detailed_error("Unable to read first ack block length.");
+    return false;
+  }
+  // Calculate the packets being acked in the first block.
+  //  +1 because AddRange implementation requires [low,high)
+  uint64_t block_high = largest_acked + 1;
+  uint64_t block_low = largest_acked - ack_block_value;
+
+  // ack_block_value is the number of packets preceding the
+  // largest_acked packet which are in the block being acked. Thus,
+  // its maximum value is largest_acked-1. Test this, reporting an
+  // error if the value is wrong.
+  if (ack_block_value + first_sending_packet_number_.ToUint64() >
+      largest_acked) {
+    set_detailed_error(absl::StrCat("Underflow with first ack block length ",
+                                    ack_block_value + 1, " largest acked is ",
+                                    largest_acked, ".")
+                           .c_str());
+    return false;
+  }
+
+  if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
+                            QuicPacketNumber(block_high))) {
+    // The visitor suppresses further processing of the packet. Although
+    // this is not a parsing error, returns false as this is in middle
+    // of processing an ACK frame.
+    set_detailed_error("Visitor suppresses further processing of ACK frame.");
+    return false;
+  }
+
+  while (ack_block_count != 0) {
+    uint64_t gap_block_value;
+    // Get the sizes of the gap and ack blocks,
+    if (!reader->ReadVarInt62(&gap_block_value)) {
+      set_detailed_error("Unable to read gap block value.");
+      return false;
+    }
+    // It's an error if the gap is larger than the space from packet
+    // number 0 to the start of the block that's just been acked, PLUS
+    // there must be space for at least 1 packet to be acked. For
+    // example, if block_low is 10 and gap_block_value is 9, it means
+    // the gap block is 10 packets long, leaving no room for a packet
+    // to be acked. Thus, gap_block_value+2 can not be larger than
+    // block_low.
+    // The test is written this way to detect wrap-arounds.
+    if ((gap_block_value + 2) > block_low) {
+      set_detailed_error(
+          absl::StrCat("Underflow with gap block length ", gap_block_value + 1,
+                       " previous ack block start is ", block_low, ".")
+              .c_str());
+      return false;
+    }
+
+    // Adjust block_high to be the top of the next ack block.
+    // There is a gap of |gap_block_value| packets between the bottom
+    // of ack block N and top of block N+1.  Note that gap_block_value
+    // is he size of the gap minus 1 (per the QUIC protocol), and
+    // block_high is the packet number of the first packet of the gap
+    // (per the implementation of OnAckRange/AddAckRange, below).
+    block_high = block_low - 1 - gap_block_value;
+
+    if (!reader->ReadVarInt62(&ack_block_value)) {
+      set_detailed_error("Unable to read ack block value.");
+      return false;
+    }
+    if (ack_block_value + first_sending_packet_number_.ToUint64() >
+        (block_high - 1)) {
+      set_detailed_error(
+          absl::StrCat("Underflow with ack block length ", ack_block_value + 1,
+                       " latest ack block end is ", block_high - 1, ".")
+              .c_str());
+      return false;
+    }
+    // Calculate the low end of the new nth ack block. The +1 is
+    // because the encoded value is the blocksize-1.
+    block_low = block_high - 1 - ack_block_value;
+    if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
+                              QuicPacketNumber(block_high))) {
+      // The visitor suppresses further processing of the packet. Although
+      // this is not a parsing error, returns false as this is in middle
+      // of processing an ACK frame.
+      set_detailed_error("Visitor suppresses further processing of ACK frame.");
+      return false;
+    }
+
+    // Another one done.
+    ack_block_count--;
+  }
+
+  if (frame_type == IETF_ACK_RECEIVE_TIMESTAMPS) {
+    QUICHE_DCHECK(process_timestamps_);
+    if (!ProcessIetfTimestampsInAckFrame(ack_frame->largest_acked, reader)) {
+      return false;
+    }
+  } else if (frame_type == IETF_ACK_ECN) {
+    ack_frame->ecn_counters_populated = true;
+    if (!reader->ReadVarInt62(&ack_frame->ect_0_count)) {
+      set_detailed_error("Unable to read ack ect_0_count.");
+      return false;
+    }
+    if (!reader->ReadVarInt62(&ack_frame->ect_1_count)) {
+      set_detailed_error("Unable to read ack ect_1_count.");
+      return false;
+    }
+    if (!reader->ReadVarInt62(&ack_frame->ecn_ce_count)) {
+      set_detailed_error("Unable to read ack ecn_ce_count.");
+      return false;
+    }
+  } else {
+    ack_frame->ecn_counters_populated = false;
+    ack_frame->ect_0_count = 0;
+    ack_frame->ect_1_count = 0;
+    ack_frame->ecn_ce_count = 0;
+  }
+  // TODO(fayang): Report ECN counts to visitor when they are actually used.
+  if (!visitor_->OnAckFrameEnd(QuicPacketNumber(block_low))) {
+    set_detailed_error(
+        "Error occurs when visitor finishes processing the ACK frame.");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
+                                                 QuicDataReader* reader) {
+  uint64_t timestamp_range_count;
+  if (!reader->ReadVarInt62(&timestamp_range_count)) {
+    set_detailed_error("Unable to read receive timestamp range count.");
+    return false;
+  }
+  if (timestamp_range_count == 0) {
+    return true;
+  }
+
+  QuicPacketNumber packet_number = largest_acked;
+
+  // Iterate through all timestamp ranges, each of which represents a block of
+  // contiguous packets for which receive timestamps are being reported. Each
+  // range is of the form:
+  //
+  // Timestamp Range {
+  //    Gap (i),
+  //    Timestamp Delta Count (i),
+  //    Timestamp Delta (i) ...,
+  //  }
+  for (uint64_t i = 0; i < timestamp_range_count; i++) {
+    uint64_t gap;
+    if (!reader->ReadVarInt62(&gap)) {
+      set_detailed_error("Unable to read receive timestamp gap.");
+      return false;
+    }
+    if (packet_number.ToUint64() < gap) {
+      set_detailed_error("Receive timestamp gap too high.");
+      return false;
+    }
+    packet_number = packet_number - gap;
+    uint64_t timestamp_count;
+    if (!reader->ReadVarInt62(&timestamp_count)) {
+      set_detailed_error("Unable to read receive timestamp count.");
+      return false;
+    }
+    if (packet_number.ToUint64() < timestamp_count) {
+      set_detailed_error("Receive timestamp count too high.");
+      return false;
+    }
+    for (uint64_t j = 0; j < timestamp_count; j++) {
+      uint64_t timestamp_delta;
+      if (!reader->ReadVarInt62(&timestamp_delta)) {
+        set_detailed_error("Unable to read receive timestamp delta.");
+        return false;
+      }
+      // The first timestamp delta is relative to framer creation time; whereas
+      // subsequent deltas are relative to the previous delta in decreasing
+      // packet order.
+      timestamp_delta = timestamp_delta << receive_timestamps_exponent_;
+      if (i == 0 && j == 0) {
+        last_timestamp_ = QuicTime::Delta::FromMicroseconds(timestamp_delta);
+      } else {
+        last_timestamp_ = last_timestamp_ -
+                          QuicTime::Delta::FromMicroseconds(timestamp_delta);
+        if (last_timestamp_ < QuicTime::Delta::Zero()) {
+          set_detailed_error("Receive timestamp delta too high.");
+          return false;
+        }
+      }
+      visitor_->OnAckTimestamp(packet_number, creation_time_ + last_timestamp_);
+      packet_number--;
+    }
+    packet_number--;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStopWaitingFrame(QuicDataReader* reader,
+                                         const QuicPacketHeader& header,
+                                         QuicStopWaitingFrame* stop_waiting) {
+  uint64_t least_unacked_delta;
+  if (!reader->ReadBytesToUInt64(header.packet_number_length,
+                                 &least_unacked_delta)) {
+    set_detailed_error("Unable to read least unacked delta.");
+    return false;
+  }
+  if (header.packet_number.ToUint64() <= least_unacked_delta) {
+    set_detailed_error("Invalid unacked delta.");
+    return false;
+  }
+  stop_waiting->least_unacked = header.packet_number - least_unacked_delta;
+
+  return true;
+}
+
+bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
+                                       QuicRstStreamFrame* frame) {
+  if (!reader->ReadUInt32(&frame->stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+
+  if (!reader->ReadUInt64(&frame->byte_offset)) {
+    set_detailed_error("Unable to read rst stream sent byte offset.");
+    return false;
+  }
+
+  uint32_t error_code;
+  if (!reader->ReadUInt32(&error_code)) {
+    set_detailed_error("Unable to read rst stream error code.");
+    return false;
+  }
+
+  if (error_code >= QUIC_STREAM_LAST_ERROR) {
+    // Ignore invalid stream error code if any.
+    error_code = QUIC_STREAM_LAST_ERROR;
+  }
+
+  frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
+
+  return true;
+}
+
+bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
+                                             QuicConnectionCloseFrame* frame) {
+  uint32_t error_code;
+  frame->close_type = GOOGLE_QUIC_CONNECTION_CLOSE;
+
+  if (!reader->ReadUInt32(&error_code)) {
+    set_detailed_error("Unable to read connection close error code.");
+    return false;
+  }
+
+  // For Google QUIC connection closes, |wire_error_code| and |quic_error_code|
+  // must have the same value.
+  frame->wire_error_code = error_code;
+  frame->quic_error_code = static_cast<QuicErrorCode>(error_code);
+
+  absl::string_view error_details;
+  if (!reader->ReadStringPiece16(&error_details)) {
+    set_detailed_error("Unable to read connection close error details.");
+    return false;
+  }
+  frame->error_details = std::string(error_details);
+
+  return true;
+}
+
+bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
+                                    QuicGoAwayFrame* frame) {
+  uint32_t error_code;
+  if (!reader->ReadUInt32(&error_code)) {
+    set_detailed_error("Unable to read go away error code.");
+    return false;
+  }
+
+  frame->error_code = static_cast<QuicErrorCode>(error_code);
+
+  uint32_t stream_id;
+  if (!reader->ReadUInt32(&stream_id)) {
+    set_detailed_error("Unable to read last good stream id.");
+    return false;
+  }
+  frame->last_good_stream_id = static_cast<QuicStreamId>(stream_id);
+
+  absl::string_view reason_phrase;
+  if (!reader->ReadStringPiece16(&reason_phrase)) {
+    set_detailed_error("Unable to read goaway reason.");
+    return false;
+  }
+  frame->reason_phrase = std::string(reason_phrase);
+
+  return true;
+}
+
+bool QuicFramer::ProcessWindowUpdateFrame(QuicDataReader* reader,
+                                          QuicWindowUpdateFrame* frame) {
+  if (!reader->ReadUInt32(&frame->stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+
+  if (!reader->ReadUInt64(&frame->max_data)) {
+    set_detailed_error("Unable to read window byte_offset.");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::ProcessBlockedFrame(QuicDataReader* reader,
+                                     QuicBlockedFrame* frame) {
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(version_.transport_version))
+      << "Attempt to process non-IETF QUIC frames in an IETF QUIC version.";
+
+  if (!reader->ReadUInt32(&frame->stream_id)) {
+    set_detailed_error("Unable to read stream_id.");
+    return false;
+  }
+
+  return true;
+}
+
+void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader,
+                                     QuicPaddingFrame* frame) {
+  // Type byte has been read.
+  frame->num_padding_bytes = 1;
+  uint8_t next_byte;
+  while (!reader->IsDoneReading() && reader->PeekByte() == 0x00) {
+    reader->ReadBytes(&next_byte, 1);
+    QUICHE_DCHECK_EQ(0x00, next_byte);
+    ++frame->num_padding_bytes;
+  }
+}
+
+bool QuicFramer::ProcessMessageFrame(QuicDataReader* reader,
+                                     bool no_message_length,
+                                     QuicMessageFrame* frame) {
+  if (no_message_length) {
+    absl::string_view remaining(reader->ReadRemainingPayload());
+    frame->data = remaining.data();
+    frame->message_length = remaining.length();
+    return true;
+  }
+
+  uint64_t message_length;
+  if (!reader->ReadVarInt62(&message_length)) {
+    set_detailed_error("Unable to read message length");
+    return false;
+  }
+
+  absl::string_view message_piece;
+  if (!reader->ReadStringPiece(&message_piece, message_length)) {
+    set_detailed_error("Unable to read message data");
+    return false;
+  }
+
+  frame->data = message_piece.data();
+  frame->message_length = message_length;
+
+  return true;
+}
+
+// static
+absl::string_view QuicFramer::GetAssociatedDataFromEncryptedPacket(
+    QuicTransportVersion version, const QuicEncryptedPacket& encrypted,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length, bool includes_version,
+    bool includes_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    uint64_t retry_token_length,
+    QuicVariableLengthIntegerLength length_length) {
+  // TODO(ianswett): This is identical to QuicData::AssociatedData.
+  return absl::string_view(
+      encrypted.data(),
+      GetStartOfEncryptedData(version, destination_connection_id_length,
+                              source_connection_id_length, includes_version,
+                              includes_diversification_nonce,
+                              packet_number_length, retry_token_length_length,
+                              retry_token_length, length_length));
+}
+
+void QuicFramer::SetDecrypter(EncryptionLevel level,
+                              std::unique_ptr<QuicDecrypter> decrypter) {
+  QUICHE_DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
+  QUICHE_DCHECK_GE(level, decrypter_level_);
+  QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Setting decrypter from level "
+                << decrypter_level_ << " to " << level;
+  decrypter_[decrypter_level_] = nullptr;
+  decrypter_[level] = std::move(decrypter);
+  decrypter_level_ = level;
+}
+
+void QuicFramer::SetAlternativeDecrypter(
+    EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+    bool latch_once_used) {
+  QUICHE_DCHECK_NE(level, decrypter_level_);
+  QUICHE_DCHECK(!version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Setting alternative decrypter from level "
+                << alternative_decrypter_level_ << " to " << level;
+  if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
+    decrypter_[alternative_decrypter_level_] = nullptr;
+  }
+  decrypter_[level] = std::move(decrypter);
+  alternative_decrypter_level_ = level;
+  alternative_decrypter_latch_ = latch_once_used;
+}
+
+void QuicFramer::InstallDecrypter(EncryptionLevel level,
+                                  std::unique_ptr<QuicDecrypter> decrypter) {
+  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level " << level;
+  decrypter_[level] = std::move(decrypter);
+}
+
+void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
+  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
+  QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level " << level;
+  decrypter_[level] = nullptr;
+}
+
+void QuicFramer::SetKeyUpdateSupportForConnection(bool enabled) {
+  QUIC_DVLOG(1) << ENDPOINT << "SetKeyUpdateSupportForConnection: " << enabled;
+  support_key_update_for_connection_ = enabled;
+}
+
+void QuicFramer::DiscardPreviousOneRttKeys() {
+  QUICHE_DCHECK(support_key_update_for_connection_);
+  QUIC_DVLOG(1) << ENDPOINT << "Discarding previous set of 1-RTT keys";
+  previous_decrypter_ = nullptr;
+}
+
+bool QuicFramer::DoKeyUpdate(KeyUpdateReason reason) {
+  QUICHE_DCHECK(support_key_update_for_connection_);
+  if (!next_decrypter_) {
+    // If key update is locally initiated, next decrypter might not be created
+    // yet.
+    next_decrypter_ = visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+  }
+  std::unique_ptr<QuicEncrypter> next_encrypter =
+      visitor_->CreateCurrentOneRttEncrypter();
+  if (!next_decrypter_ || !next_encrypter) {
+    QUIC_BUG(quic_bug_10850_58) << "Failed to create next crypters";
+    return false;
+  }
+  key_update_performed_ = true;
+  current_key_phase_bit_ = !current_key_phase_bit_;
+  QUIC_DLOG(INFO) << ENDPOINT << "DoKeyUpdate: new current_key_phase_bit_="
+                  << current_key_phase_bit_;
+  current_key_phase_first_received_packet_number_.Clear();
+  previous_decrypter_ = std::move(decrypter_[ENCRYPTION_FORWARD_SECURE]);
+  decrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_decrypter_);
+  encrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_encrypter);
+  switch (reason) {
+    case KeyUpdateReason::kInvalid:
+      QUIC_CODE_COUNT(quic_key_update_invalid);
+      break;
+    case KeyUpdateReason::kRemote:
+      QUIC_CODE_COUNT(quic_key_update_remote);
+      break;
+    case KeyUpdateReason::kLocalForTests:
+      QUIC_CODE_COUNT(quic_key_update_local_for_tests);
+      break;
+    case KeyUpdateReason::kLocalForInteropRunner:
+      QUIC_CODE_COUNT(quic_key_update_local_for_interop_runner);
+      break;
+    case KeyUpdateReason::kLocalAeadConfidentialityLimit:
+      QUIC_CODE_COUNT(quic_key_update_local_aead_confidentiality_limit);
+      break;
+    case KeyUpdateReason::kLocalKeyUpdateLimitOverride:
+      QUIC_CODE_COUNT(quic_key_update_local_limit_override);
+      break;
+  }
+  visitor_->OnKeyUpdate(reason);
+  return true;
+}
+
+QuicPacketCount QuicFramer::PotentialPeerKeyUpdateAttemptCount() const {
+  return potential_peer_key_update_attempt_count_;
+}
+
+const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const {
+  QUICHE_DCHECK(version_.KnowsWhichDecrypterToUse());
+  return decrypter_[level].get();
+}
+
+const QuicDecrypter* QuicFramer::decrypter() const {
+  return decrypter_[decrypter_level_].get();
+}
+
+const QuicDecrypter* QuicFramer::alternative_decrypter() const {
+  if (alternative_decrypter_level_ == NUM_ENCRYPTION_LEVELS) {
+    return nullptr;
+  }
+  return decrypter_[alternative_decrypter_level_].get();
+}
+
+void QuicFramer::SetEncrypter(EncryptionLevel level,
+                              std::unique_ptr<QuicEncrypter> encrypter) {
+  QUICHE_DCHECK_GE(level, 0);
+  QUICHE_DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
+  QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level " << level;
+  encrypter_[level] = std::move(encrypter);
+}
+
+void QuicFramer::RemoveEncrypter(EncryptionLevel level) {
+  QUIC_DVLOG(1) << ENDPOINT << "Removing encrypter of " << level;
+  encrypter_[level] = nullptr;
+}
+
+void QuicFramer::SetInitialObfuscators(QuicConnectionId connection_id) {
+  CrypterPair crypters;
+  CryptoUtils::CreateInitialObfuscators(perspective_, version_, connection_id,
+                                        &crypters);
+  encrypter_[ENCRYPTION_INITIAL] = std::move(crypters.encrypter);
+  decrypter_[ENCRYPTION_INITIAL] = std::move(crypters.decrypter);
+}
+
+size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
+                                  QuicPacketNumber packet_number, size_t ad_len,
+                                  size_t total_len, size_t buffer_len,
+                                  char* buffer) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_10850_59)
+        << ENDPOINT
+        << "Attempted to encrypt in place without encrypter at level " << level;
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  size_t output_length = 0;
+  if (!encrypter_[level]->EncryptPacket(
+          packet_number.ToUint64(),
+          absl::string_view(buffer, ad_len),  // Associated data
+          absl::string_view(buffer + ad_len,
+                            total_len - ad_len),  // Plaintext
+          buffer + ad_len,                        // Destination buffer
+          &output_length, buffer_len - ad_len)) {
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+  if (version_.HasHeaderProtection() &&
+      !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
+    QUIC_DLOG(ERROR) << "Applying header protection failed.";
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  return ad_len + output_length;
+}
+
+namespace {
+
+const size_t kHPSampleLen = 16;
+
+constexpr bool IsLongHeader(uint8_t type_byte) {
+  return (type_byte & FLAGS_LONG_HEADER) != 0;
+}
+
+}  // namespace
+
+bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level, char* buffer,
+                                       size_t buffer_len, size_t ad_len) {
+  QuicDataReader buffer_reader(buffer, buffer_len);
+  QuicDataWriter buffer_writer(buffer_len, buffer);
+  // The sample starts 4 bytes after the start of the packet number.
+  if (ad_len < last_written_packet_number_length_) {
+    return false;
+  }
+  size_t pn_offset = ad_len - last_written_packet_number_length_;
+  // Sample the ciphertext and generate the mask to use for header protection.
+  size_t sample_offset = pn_offset + 4;
+  QuicDataReader sample_reader(buffer, buffer_len);
+  absl::string_view sample;
+  if (!sample_reader.Seek(sample_offset) ||
+      !sample_reader.ReadStringPiece(&sample, kHPSampleLen)) {
+    QUIC_BUG(quic_bug_10850_60)
+        << "Not enough bytes to sample: sample_offset " << sample_offset
+        << ", sample len: " << kHPSampleLen << ", buffer len: " << buffer_len;
+    return false;
+  }
+
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_12975_8)
+        << ENDPOINT
+        << "Attempted to apply header protection without encrypter at level "
+        << level << " using " << version_;
+    return false;
+  }
+
+  std::string mask = encrypter_[level]->GenerateHeaderProtectionMask(sample);
+  if (mask.empty()) {
+    QUIC_BUG(quic_bug_10850_61) << "Unable to generate header protection mask.";
+    return false;
+  }
+  QuicDataReader mask_reader(mask.data(), mask.size());
+
+  // Apply the mask to the 4 or 5 least significant bits of the first byte.
+  uint8_t bitmask = 0x1f;
+  uint8_t type_byte;
+  if (!buffer_reader.ReadUInt8(&type_byte)) {
+    return false;
+  }
+  QuicLongHeaderType header_type;
+  if (IsLongHeader(type_byte)) {
+    bitmask = 0x0f;
+    header_type = GetLongHeaderType(type_byte, version_);
+    if (header_type == INVALID_PACKET_TYPE) {
+      return false;
+    }
+  }
+  uint8_t mask_byte;
+  if (!mask_reader.ReadUInt8(&mask_byte) ||
+      !buffer_writer.WriteUInt8(type_byte ^ (mask_byte & bitmask))) {
+    return false;
+  }
+
+  // Adjust |pn_offset| to account for the diversification nonce.
+  if (IsLongHeader(type_byte) && header_type == ZERO_RTT_PROTECTED &&
+      perspective_ == Perspective::IS_SERVER &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+    if (pn_offset <= kDiversificationNonceSize) {
+      QUIC_BUG(quic_bug_10850_62)
+          << "Expected diversification nonce, but not enough bytes";
+      return false;
+    }
+    pn_offset -= kDiversificationNonceSize;
+  }
+  // Advance the reader and writer to the packet number. Both the reader and
+  // writer have each read/written one byte.
+  if (!buffer_writer.Seek(pn_offset - 1) ||
+      !buffer_reader.Seek(pn_offset - 1)) {
+    return false;
+  }
+  // Apply the rest of the mask to the packet number.
+  for (size_t i = 0; i < last_written_packet_number_length_; ++i) {
+    uint8_t buffer_byte;
+    uint8_t mask_byte;
+    if (!mask_reader.ReadUInt8(&mask_byte) ||
+        !buffer_reader.ReadUInt8(&buffer_byte) ||
+        !buffer_writer.WriteUInt8(buffer_byte ^ mask_byte)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader,
+                                        const QuicEncryptedPacket& packet,
+                                        QuicPacketHeader* header,
+                                        uint64_t* full_packet_number,
+                                        std::vector<char>* associated_data) {
+  EncryptionLevel expected_decryption_level = GetEncryptionLevel(*header);
+  QuicDecrypter* decrypter = decrypter_[expected_decryption_level].get();
+  if (decrypter == nullptr) {
+    QUIC_DVLOG(1)
+        << ENDPOINT
+        << "No decrypter available for removing header protection at level "
+        << expected_decryption_level;
+    return false;
+  }
+
+  bool has_diversification_nonce =
+      header->form == IETF_QUIC_LONG_HEADER_PACKET &&
+      header->long_packet_type == ZERO_RTT_PROTECTED &&
+      perspective_ == Perspective::IS_CLIENT &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO;
+
+  // Read a sample from the ciphertext and compute the mask to use for header
+  // protection.
+  absl::string_view remaining_packet = reader->PeekRemainingPayload();
+  QuicDataReader sample_reader(remaining_packet);
+
+  // The sample starts 4 bytes after the start of the packet number.
+  absl::string_view pn;
+  if (!sample_reader.ReadStringPiece(&pn, 4)) {
+    QUIC_DVLOG(1) << "Not enough data to sample";
+    return false;
+  }
+  if (has_diversification_nonce) {
+    // In Google QUIC, the diversification nonce comes between the packet number
+    // and the sample.
+    if (!sample_reader.Seek(kDiversificationNonceSize)) {
+      QUIC_DVLOG(1) << "No diversification nonce to skip over";
+      return false;
+    }
+  }
+  std::string mask = decrypter->GenerateHeaderProtectionMask(&sample_reader);
+  QuicDataReader mask_reader(mask.data(), mask.size());
+  if (mask.empty()) {
+    QUIC_DVLOG(1) << "Failed to compute mask";
+    return false;
+  }
+
+  // Unmask the rest of the type byte.
+  uint8_t bitmask = 0x1f;
+  if (IsLongHeader(header->type_byte)) {
+    bitmask = 0x0f;
+  }
+  uint8_t mask_byte;
+  if (!mask_reader.ReadUInt8(&mask_byte)) {
+    QUIC_DVLOG(1) << "No first byte to read from mask";
+    return false;
+  }
+  header->type_byte ^= (mask_byte & bitmask);
+
+  // Compute the packet number length.
+  header->packet_number_length =
+      static_cast<QuicPacketNumberLength>((header->type_byte & 0x03) + 1);
+
+  char pn_buffer[IETF_MAX_PACKET_NUMBER_LENGTH] = {};
+  QuicDataWriter pn_writer(ABSL_ARRAYSIZE(pn_buffer), pn_buffer);
+
+  // Read the (protected) packet number from the reader and unmask the packet
+  // number.
+  for (size_t i = 0; i < header->packet_number_length; ++i) {
+    uint8_t protected_pn_byte, mask_byte;
+    if (!mask_reader.ReadUInt8(&mask_byte) ||
+        !reader->ReadUInt8(&protected_pn_byte) ||
+        !pn_writer.WriteUInt8(protected_pn_byte ^ mask_byte)) {
+      QUIC_DVLOG(1) << "Failed to unmask packet number";
+      return false;
+    }
+  }
+  QuicDataReader packet_number_reader(pn_writer.data(), pn_writer.length());
+  QuicPacketNumber base_packet_number;
+  if (supports_multiple_packet_number_spaces_) {
+    PacketNumberSpace pn_space = GetPacketNumberSpace(*header);
+    if (pn_space == NUM_PACKET_NUMBER_SPACES) {
+      return false;
+    }
+    base_packet_number = largest_decrypted_packet_numbers_[pn_space];
+  } else {
+    base_packet_number = largest_packet_number_;
+  }
+  if (!ProcessAndCalculatePacketNumber(
+          &packet_number_reader, header->packet_number_length,
+          base_packet_number, full_packet_number)) {
+    return false;
+  }
+
+  // Get the associated data, and apply the same unmasking operations to it.
+  absl::string_view ad = GetAssociatedDataFromEncryptedPacket(
+      version_.transport_version, packet,
+      GetIncludedDestinationConnectionIdLength(*header),
+      GetIncludedSourceConnectionIdLength(*header), header->version_flag,
+      has_diversification_nonce, header->packet_number_length,
+      header->retry_token_length_length, header->retry_token.length(),
+      header->length_length);
+  *associated_data = std::vector<char>(ad.begin(), ad.end());
+  QuicDataWriter ad_writer(associated_data->size(), associated_data->data());
+
+  // Apply the unmasked type byte and packet number to |associated_data|.
+  if (!ad_writer.WriteUInt8(header->type_byte)) {
+    return false;
+  }
+  // Put the packet number at the end of the AD, or if there's a diversification
+  // nonce, before that (which is at the end of the AD).
+  size_t seek_len = ad_writer.remaining() - header->packet_number_length;
+  if (has_diversification_nonce) {
+    seek_len -= kDiversificationNonceSize;
+  }
+  if (!ad_writer.Seek(seek_len) ||
+      !ad_writer.WriteBytes(pn_writer.data(), pn_writer.length())) {
+    QUIC_DVLOG(1) << "Failed to apply unmasking operations to AD";
+    return false;
+  }
+
+  return true;
+}
+
+size_t QuicFramer::EncryptPayload(EncryptionLevel level,
+                                  QuicPacketNumber packet_number,
+                                  const QuicPacket& packet, char* buffer,
+                                  size_t buffer_len) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_10850_63)
+        << ENDPOINT << "Attempted to encrypt without encrypter at level "
+        << level;
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  absl::string_view associated_data =
+      packet.AssociatedData(version_.transport_version);
+  // Copy in the header, because the encrypter only populates the encrypted
+  // plaintext content.
+  const size_t ad_len = associated_data.length();
+  if (packet.length() < ad_len) {
+    QUIC_BUG(quic_bug_10850_64)
+        << ENDPOINT << "packet is shorter than associated data length. version:"
+        << version() << ", packet length:" << packet.length()
+        << ", associated data length:" << ad_len;
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+  memmove(buffer, associated_data.data(), ad_len);
+  // Encrypt the plaintext into the buffer.
+  size_t output_length = 0;
+  if (!encrypter_[level]->EncryptPacket(
+          packet_number.ToUint64(), associated_data,
+          packet.Plaintext(version_.transport_version), buffer + ad_len,
+          &output_length, buffer_len - ad_len)) {
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+  if (version_.HasHeaderProtection() &&
+      !ApplyHeaderProtection(level, buffer, ad_len + output_length, ad_len)) {
+    QUIC_DLOG(ERROR) << "Applying header protection failed.";
+    RaiseError(QUIC_ENCRYPTION_FAILURE);
+    return 0;
+  }
+
+  return ad_len + output_length;
+}
+
+size_t QuicFramer::GetCiphertextSize(EncryptionLevel level,
+                                     size_t plaintext_size) const {
+  if (encrypter_[level] == nullptr) {
+    QUIC_BUG(quic_bug_10850_65)
+        << ENDPOINT
+        << "Attempted to get ciphertext size without encrypter at level "
+        << level << " using " << version_;
+    return plaintext_size;
+  }
+  return encrypter_[level]->GetCiphertextSize(plaintext_size);
+}
+
+size_t QuicFramer::GetMaxPlaintextSize(size_t ciphertext_size) {
+  // In order to keep the code simple, we don't have the current encryption
+  // level to hand. Both the NullEncrypter and AES-GCM have a tag length of 12.
+  size_t min_plaintext_size = ciphertext_size;
+
+  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
+    if (encrypter_[i] != nullptr) {
+      size_t size = encrypter_[i]->GetMaxPlaintextSize(ciphertext_size);
+      if (size < min_plaintext_size) {
+        min_plaintext_size = size;
+      }
+    }
+  }
+
+  return min_plaintext_size;
+}
+
+QuicPacketCount QuicFramer::GetOneRttEncrypterConfidentialityLimit() const {
+  if (!encrypter_[ENCRYPTION_FORWARD_SECURE]) {
+    QUIC_BUG(quic_bug_10850_66) << "1-RTT encrypter not set";
+    return 0;
+  }
+  return encrypter_[ENCRYPTION_FORWARD_SECURE]->GetConfidentialityLimit();
+}
+
+bool QuicFramer::DecryptPayload(size_t udp_packet_length,
+                                absl::string_view encrypted,
+                                absl::string_view associated_data,
+                                const QuicPacketHeader& header,
+                                char* decrypted_buffer, size_t buffer_length,
+                                size_t* decrypted_length,
+                                EncryptionLevel* decrypted_level) {
+  if (!EncryptionLevelIsValid(decrypter_level_)) {
+    QUIC_BUG(quic_bug_10850_67)
+        << "Attempted to decrypt with bad decrypter_level_";
+    return false;
+  }
+  EncryptionLevel level = decrypter_level_;
+  QuicDecrypter* decrypter = decrypter_[level].get();
+  QuicDecrypter* alternative_decrypter = nullptr;
+  bool key_phase_parsed = false;
+  bool key_phase;
+  bool attempt_key_update = false;
+  if (version().KnowsWhichDecrypterToUse()) {
+    if (header.form == GOOGLE_QUIC_PACKET) {
+      QUIC_BUG(quic_bug_10850_68)
+          << "Attempted to decrypt GOOGLE_QUIC_PACKET with a version that "
+             "knows which decrypter to use";
+      return false;
+    }
+    level = GetEncryptionLevel(header);
+    if (!EncryptionLevelIsValid(level)) {
+      QUIC_BUG(quic_bug_10850_69) << "Attempted to decrypt with bad level";
+      return false;
+    }
+    decrypter = decrypter_[level].get();
+    if (decrypter == nullptr) {
+      return false;
+    }
+    if (level == ENCRYPTION_ZERO_RTT &&
+        perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) {
+      decrypter->SetDiversificationNonce(*header.nonce);
+    }
+    if (support_key_update_for_connection_ &&
+        header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+      QUICHE_DCHECK(version().UsesTls());
+      QUICHE_DCHECK_EQ(level, ENCRYPTION_FORWARD_SECURE);
+      key_phase = (header.type_byte & FLAGS_KEY_PHASE_BIT) != 0;
+      key_phase_parsed = true;
+      QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
+                    << " received key_phase=" << key_phase
+                    << " current_key_phase_bit_=" << current_key_phase_bit_;
+      if (key_phase != current_key_phase_bit_) {
+        if ((current_key_phase_first_received_packet_number_.IsInitialized() &&
+             header.packet_number >
+                 current_key_phase_first_received_packet_number_) ||
+            (!current_key_phase_first_received_packet_number_.IsInitialized() &&
+             !key_update_performed_)) {
+          if (!next_decrypter_) {
+            next_decrypter_ =
+                visitor_->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+            if (!next_decrypter_) {
+              QUIC_BUG(quic_bug_10850_70) << "Failed to create next_decrypter";
+              return false;
+            }
+          }
+          QUIC_DVLOG(1) << ENDPOINT << "packet " << header.packet_number
+                        << " attempt_key_update=true";
+          attempt_key_update = true;
+          potential_peer_key_update_attempt_count_++;
+          decrypter = next_decrypter_.get();
+        } else {
+          if (previous_decrypter_) {
+            QUIC_DVLOG(1) << ENDPOINT
+                          << "trying previous_decrypter_ for packet "
+                          << header.packet_number;
+            decrypter = previous_decrypter_.get();
+          } else {
+            QUIC_DVLOG(1) << ENDPOINT << "dropping packet "
+                          << header.packet_number << " with old key phase";
+            return false;
+          }
+        }
+      }
+    }
+  } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
+    if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
+      QUIC_BUG(quic_bug_10850_71)
+          << "Attempted to decrypt with bad alternative_decrypter_level_";
+      return false;
+    }
+    alternative_decrypter = decrypter_[alternative_decrypter_level_].get();
+  }
+
+  if (decrypter == nullptr) {
+    QUIC_BUG(quic_bug_10850_72)
+        << "Attempting to decrypt without decrypter, encryption level:" << level
+        << " version:" << version();
+    return false;
+  }
+
+  bool success = decrypter->DecryptPacket(
+      header.packet_number.ToUint64(), associated_data, encrypted,
+      decrypted_buffer, decrypted_length, buffer_length);
+  if (success) {
+    visitor_->OnDecryptedPacket(udp_packet_length, level);
+    if (level == ENCRYPTION_ZERO_RTT &&
+        current_key_phase_first_received_packet_number_.IsInitialized() &&
+        header.packet_number >
+            current_key_phase_first_received_packet_number_) {
+      set_detailed_error(absl::StrCat(
+          "Decrypted a 0-RTT packet with a packet number ",
+          header.packet_number.ToString(),
+          " which is higher than a 1-RTT packet number ",
+          current_key_phase_first_received_packet_number_.ToString()));
+      return RaiseError(QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
+    }
+    *decrypted_level = level;
+    potential_peer_key_update_attempt_count_ = 0;
+    if (attempt_key_update) {
+      if (!DoKeyUpdate(KeyUpdateReason::kRemote)) {
+        set_detailed_error("Key update failed due to internal error");
+        return RaiseError(QUIC_INTERNAL_ERROR);
+      }
+      QUICHE_DCHECK_EQ(current_key_phase_bit_, key_phase);
+    }
+    if (key_phase_parsed &&
+        !current_key_phase_first_received_packet_number_.IsInitialized() &&
+        key_phase == current_key_phase_bit_) {
+      // Set packet number for current key phase if it hasn't been initialized
+      // yet. This is set outside of attempt_key_update since the key update
+      // may have been initiated locally, and in that case we don't know yet
+      // which packet number from the remote side to use until we receive a
+      // packet with that phase.
+      QUIC_DVLOG(1) << ENDPOINT
+                    << "current_key_phase_first_received_packet_number_ = "
+                    << header.packet_number;
+      current_key_phase_first_received_packet_number_ = header.packet_number;
+      visitor_->OnDecryptedFirstPacketInKeyPhase();
+    }
+  } else if (alternative_decrypter != nullptr) {
+    if (header.nonce != nullptr) {
+      QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+      alternative_decrypter->SetDiversificationNonce(*header.nonce);
+    }
+    bool try_alternative_decryption = true;
+    if (alternative_decrypter_level_ == ENCRYPTION_ZERO_RTT) {
+      if (perspective_ == Perspective::IS_CLIENT) {
+        if (header.nonce == nullptr) {
+          // Can not use INITIAL decryption without a diversification nonce.
+          try_alternative_decryption = false;
+        }
+      } else {
+        QUICHE_DCHECK(header.nonce == nullptr);
+      }
+    }
+
+    if (try_alternative_decryption) {
+      success = alternative_decrypter->DecryptPacket(
+          header.packet_number.ToUint64(), associated_data, encrypted,
+          decrypted_buffer, decrypted_length, buffer_length);
+    }
+    if (success) {
+      visitor_->OnDecryptedPacket(udp_packet_length,
+                                  alternative_decrypter_level_);
+      *decrypted_level = decrypter_level_;
+      if (alternative_decrypter_latch_) {
+        if (!EncryptionLevelIsValid(alternative_decrypter_level_)) {
+          QUIC_BUG(quic_bug_10850_73)
+              << "Attempted to latch alternate decrypter with bad "
+                 "alternative_decrypter_level_";
+          return false;
+        }
+        // Switch to the alternative decrypter and latch so that we cannot
+        // switch back.
+        decrypter_level_ = alternative_decrypter_level_;
+        alternative_decrypter_level_ = NUM_ENCRYPTION_LEVELS;
+      } else {
+        // Switch the alternative decrypter so that we use it first next time.
+        EncryptionLevel level = alternative_decrypter_level_;
+        alternative_decrypter_level_ = decrypter_level_;
+        decrypter_level_ = level;
+      }
+    }
+  }
+
+  if (!success) {
+    QUIC_DVLOG(1) << ENDPOINT << "DecryptPacket failed for: " << header;
+    return false;
+  }
+
+  return true;
+}
+
+size_t QuicFramer::GetIetfAckFrameSize(const QuicAckFrame& frame) {
+  // Type byte, largest_acked, and delay_time are straight-forward.
+  size_t ack_frame_size = kQuicFrameTypeSize;
+  QuicPacketNumber largest_acked = LargestAcked(frame);
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(largest_acked.ToUint64());
+  uint64_t ack_delay_time_us;
+  ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
+  ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(ack_delay_time_us);
+
+  if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
+    QUIC_BUG(quic_bug_10850_74) << "Malformed ack frame";
+    // ACK frame serialization will fail and connection will be closed.
+    return ack_frame_size;
+  }
+
+  // Ack block count.
+  ack_frame_size +=
+      QuicDataWriter::GetVarInt62Len(frame.packets.NumIntervals() - 1);
+
+  // First Ack range.
+  auto iter = frame.packets.rbegin();
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(iter->Length() - 1);
+  QuicPacketNumber previous_smallest = iter->min();
+  ++iter;
+
+  // Ack blocks.
+  for (; iter != frame.packets.rend(); ++iter) {
+    const uint64_t gap = previous_smallest - iter->max() - 1;
+    const uint64_t ack_range = iter->Length() - 1;
+    ack_frame_size += (QuicDataWriter::GetVarInt62Len(gap) +
+                       QuicDataWriter::GetVarInt62Len(ack_range));
+    previous_smallest = iter->min();
+  }
+
+  if (UseIetfAckWithReceiveTimestamp(frame)) {
+    ack_frame_size += GetIetfAckFrameTimestampSize(frame);
+  } else if (frame.ecn_counters_populated &&
+             (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+    // ECN counts.
+    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_0_count);
+    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ect_1_count);
+    ack_frame_size += QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count);
+  }
+
+  return ack_frame_size;
+}
+
+size_t QuicFramer::GetIetfAckFrameTimestampSize(const QuicAckFrame& ack) {
+  QUICHE_DCHECK(!ack.received_packet_times.empty());
+  std::string detailed_error;
+  absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
+      GetAckTimestampRanges(ack, detailed_error);
+  if (!detailed_error.empty()) {
+    return 0;
+  }
+
+  int64_t size =
+      FrameAckTimestampRanges(ack, timestamp_ranges, /*writer=*/nullptr);
+  return std::max<int64_t>(0, size);
+}
+
+size_t QuicFramer::GetAckFrameSize(
+    const QuicAckFrame& ack, QuicPacketNumberLength /*packet_number_length*/) {
+  QUICHE_DCHECK(!ack.packets.Empty());
+  size_t ack_size = 0;
+
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return GetIetfAckFrameSize(ack);
+  }
+  AckFrameInfo ack_info = GetAckFrameInfo(ack);
+  QuicPacketNumberLength ack_block_length =
+      GetMinPacketNumberLength(QuicPacketNumber(ack_info.max_block_length));
+
+  ack_size = GetMinAckFrameSize(version_.transport_version, ack,
+                                local_ack_delay_exponent_,
+                                UseIetfAckWithReceiveTimestamp(ack));
+  // First ack block length.
+  ack_size += ack_block_length;
+  if (ack_info.num_ack_blocks != 0) {
+    ack_size += kNumberOfAckBlocksSize;
+    ack_size += std::min(ack_info.num_ack_blocks, kMaxAckBlocks) *
+                (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
+  }
+
+  // Include timestamps.
+  if (process_timestamps_) {
+    ack_size += GetAckFrameTimeStampSize(ack);
+  }
+
+  return ack_size;
+}
+
+size_t QuicFramer::GetAckFrameTimeStampSize(const QuicAckFrame& ack) {
+  if (ack.received_packet_times.empty()) {
+    return 0;
+  }
+
+  return kQuicNumTimestampsLength + kQuicFirstTimestampLength +
+         (kQuicTimestampLength + kQuicTimestampPacketNumberGapLength) *
+             (ack.received_packet_times.size() - 1);
+}
+
+size_t QuicFramer::ComputeFrameLength(
+    const QuicFrame& frame, bool last_frame_in_packet,
+    QuicPacketNumberLength packet_number_length) {
+  switch (frame.type) {
+    case STREAM_FRAME:
+      return GetMinStreamFrameSize(
+                 version_.transport_version, frame.stream_frame.stream_id,
+                 frame.stream_frame.offset, last_frame_in_packet,
+                 frame.stream_frame.data_length) +
+             frame.stream_frame.data_length;
+    case CRYPTO_FRAME:
+      return GetMinCryptoFrameSize(frame.crypto_frame->offset,
+                                   frame.crypto_frame->data_length) +
+             frame.crypto_frame->data_length;
+    case ACK_FRAME: {
+      return GetAckFrameSize(*frame.ack_frame, packet_number_length);
+    }
+    case STOP_WAITING_FRAME:
+      return GetStopWaitingFrameSize(packet_number_length);
+    case MTU_DISCOVERY_FRAME:
+      // MTU discovery frames are serialized as ping frames.
+      return kQuicFrameTypeSize;
+    case MESSAGE_FRAME:
+      return GetMessageFrameSize(version_.transport_version,
+                                 last_frame_in_packet,
+                                 frame.message_frame->message_length);
+    case PADDING_FRAME:
+      QUICHE_DCHECK(false);
+      return 0;
+    default:
+      return GetRetransmittableControlFrameSize(version_.transport_version,
+                                                frame);
+  }
+}
+
+bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
+                                bool last_frame_in_packet,
+                                QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfFrameType(frame, last_frame_in_packet, writer);
+  }
+  uint8_t type_byte = 0;
+  switch (frame.type) {
+    case STREAM_FRAME:
+      type_byte =
+          GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
+      break;
+    case ACK_FRAME:
+      return true;
+    case MTU_DISCOVERY_FRAME:
+      type_byte = static_cast<uint8_t>(PING_FRAME);
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      set_detailed_error(
+          "Attempt to append NEW_CONNECTION_ID frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case RETIRE_CONNECTION_ID_FRAME:
+      set_detailed_error(
+          "Attempt to append RETIRE_CONNECTION_ID frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case NEW_TOKEN_FRAME:
+      set_detailed_error(
+          "Attempt to append NEW_TOKEN frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case MAX_STREAMS_FRAME:
+      set_detailed_error(
+          "Attempt to append MAX_STREAMS frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case STREAMS_BLOCKED_FRAME:
+      set_detailed_error(
+          "Attempt to append STREAMS_BLOCKED frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case PATH_RESPONSE_FRAME:
+      set_detailed_error(
+          "Attempt to append PATH_RESPONSE frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case PATH_CHALLENGE_FRAME:
+      set_detailed_error(
+          "Attempt to append PATH_CHALLENGE frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case STOP_SENDING_FRAME:
+      set_detailed_error(
+          "Attempt to append STOP_SENDING frame and not in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case MESSAGE_FRAME:
+      return true;
+
+    default:
+      type_byte = static_cast<uint8_t>(frame.type);
+      break;
+  }
+
+  return writer->WriteUInt8(type_byte);
+}
+
+bool QuicFramer::AppendIetfFrameType(const QuicFrame& frame,
+                                     bool last_frame_in_packet,
+                                     QuicDataWriter* writer) {
+  uint8_t type_byte = 0;
+  switch (frame.type) {
+    case PADDING_FRAME:
+      type_byte = IETF_PADDING;
+      break;
+    case RST_STREAM_FRAME:
+      type_byte = IETF_RST_STREAM;
+      break;
+    case CONNECTION_CLOSE_FRAME:
+      switch (frame.connection_close_frame->close_type) {
+        case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+          type_byte = IETF_APPLICATION_CLOSE;
+          break;
+        case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+          type_byte = IETF_CONNECTION_CLOSE;
+          break;
+        default:
+          set_detailed_error(absl::StrCat(
+              "Invalid QuicConnectionCloseFrame type: ",
+              static_cast<int>(frame.connection_close_frame->close_type)));
+          return RaiseError(QUIC_INTERNAL_ERROR);
+      }
+      break;
+    case GOAWAY_FRAME:
+      set_detailed_error(
+          "Attempt to create non-IETF QUIC GOAWAY frame in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case WINDOW_UPDATE_FRAME:
+      // Depending on whether there is a stream ID or not, will be either a
+      // MAX_STREAM_DATA frame or a MAX_DATA frame.
+      if (frame.window_update_frame.stream_id ==
+          QuicUtils::GetInvalidStreamId(transport_version())) {
+        type_byte = IETF_MAX_DATA;
+      } else {
+        type_byte = IETF_MAX_STREAM_DATA;
+      }
+      break;
+    case BLOCKED_FRAME:
+      if (frame.blocked_frame.stream_id ==
+          QuicUtils::GetInvalidStreamId(transport_version())) {
+        type_byte = IETF_DATA_BLOCKED;
+      } else {
+        type_byte = IETF_STREAM_DATA_BLOCKED;
+      }
+      break;
+    case STOP_WAITING_FRAME:
+      set_detailed_error(
+          "Attempt to append type byte of STOP WAITING frame in IETF QUIC.");
+      return RaiseError(QUIC_INTERNAL_ERROR);
+    case PING_FRAME:
+      type_byte = IETF_PING;
+      break;
+    case STREAM_FRAME:
+      type_byte =
+          GetStreamFrameTypeByte(frame.stream_frame, last_frame_in_packet);
+      break;
+    case ACK_FRAME:
+      // Do nothing here, AppendIetfAckFrameAndTypeByte() will put the type byte
+      // in the buffer.
+      return true;
+    case MTU_DISCOVERY_FRAME:
+      // The path MTU discovery frame is encoded as a PING frame on the wire.
+      type_byte = IETF_PING;
+      break;
+    case NEW_CONNECTION_ID_FRAME:
+      type_byte = IETF_NEW_CONNECTION_ID;
+      break;
+    case RETIRE_CONNECTION_ID_FRAME:
+      type_byte = IETF_RETIRE_CONNECTION_ID;
+      break;
+    case NEW_TOKEN_FRAME:
+      type_byte = IETF_NEW_TOKEN;
+      break;
+    case MAX_STREAMS_FRAME:
+      if (frame.max_streams_frame.unidirectional) {
+        type_byte = IETF_MAX_STREAMS_UNIDIRECTIONAL;
+      } else {
+        type_byte = IETF_MAX_STREAMS_BIDIRECTIONAL;
+      }
+      break;
+    case STREAMS_BLOCKED_FRAME:
+      if (frame.streams_blocked_frame.unidirectional) {
+        type_byte = IETF_STREAMS_BLOCKED_UNIDIRECTIONAL;
+      } else {
+        type_byte = IETF_STREAMS_BLOCKED_BIDIRECTIONAL;
+      }
+      break;
+    case PATH_RESPONSE_FRAME:
+      type_byte = IETF_PATH_RESPONSE;
+      break;
+    case PATH_CHALLENGE_FRAME:
+      type_byte = IETF_PATH_CHALLENGE;
+      break;
+    case STOP_SENDING_FRAME:
+      type_byte = IETF_STOP_SENDING;
+      break;
+    case MESSAGE_FRAME:
+      return true;
+    case CRYPTO_FRAME:
+      type_byte = IETF_CRYPTO;
+      break;
+    case HANDSHAKE_DONE_FRAME:
+      type_byte = IETF_HANDSHAKE_DONE;
+      break;
+    case ACK_FREQUENCY_FRAME:
+      type_byte = IETF_ACK_FREQUENCY;
+      break;
+    default:
+      QUIC_BUG(quic_bug_10850_75)
+          << "Attempt to generate a frame type for an unsupported value: "
+          << frame.type;
+      return false;
+  }
+  return writer->WriteVarInt62(type_byte);
+}
+
+// static
+bool QuicFramer::AppendPacketNumber(QuicPacketNumberLength packet_number_length,
+                                    QuicPacketNumber packet_number,
+                                    QuicDataWriter* writer) {
+  QUICHE_DCHECK(packet_number.IsInitialized());
+  if (!IsValidPacketNumberLength(packet_number_length)) {
+    QUIC_BUG(quic_bug_10850_76)
+        << "Invalid packet_number_length: " << packet_number_length;
+    return false;
+  }
+  return writer->WriteBytesToUInt64(packet_number_length,
+                                    packet_number.ToUint64());
+}
+
+// static
+bool QuicFramer::AppendStreamId(size_t stream_id_length, QuicStreamId stream_id,
+                                QuicDataWriter* writer) {
+  if (stream_id_length == 0 || stream_id_length > 4) {
+    QUIC_BUG(quic_bug_10850_77)
+        << "Invalid stream_id_length: " << stream_id_length;
+    return false;
+  }
+  return writer->WriteBytesToUInt64(stream_id_length, stream_id);
+}
+
+// static
+bool QuicFramer::AppendStreamOffset(size_t offset_length,
+                                    QuicStreamOffset offset,
+                                    QuicDataWriter* writer) {
+  if (offset_length == 1 || offset_length > 8) {
+    QUIC_BUG(quic_bug_10850_78)
+        << "Invalid stream_offset_length: " << offset_length;
+    return false;
+  }
+
+  return writer->WriteBytesToUInt64(offset_length, offset);
+}
+
+// static
+bool QuicFramer::AppendAckBlock(uint8_t gap,
+                                QuicPacketNumberLength length_length,
+                                uint64_t length, QuicDataWriter* writer) {
+  if (length == 0) {
+    if (!IsValidPacketNumberLength(length_length)) {
+      QUIC_BUG(quic_bug_10850_79)
+          << "Invalid packet_number_length: " << length_length;
+      return false;
+    }
+    return writer->WriteUInt8(gap) &&
+           writer->WriteBytesToUInt64(length_length, length);
+  }
+  return writer->WriteUInt8(gap) &&
+         AppendPacketNumber(length_length, QuicPacketNumber(length), writer);
+}
+
+bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
+                                   bool no_stream_frame_length,
+                                   QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfStreamFrame(frame, no_stream_frame_length, writer);
+  }
+  if (!AppendStreamId(GetStreamIdSize(frame.stream_id), frame.stream_id,
+                      writer)) {
+    QUIC_BUG(quic_bug_10850_80) << "Writing stream id size failed.";
+    return false;
+  }
+  if (!AppendStreamOffset(GetStreamOffsetSize(frame.offset), frame.offset,
+                          writer)) {
+    QUIC_BUG(quic_bug_10850_81) << "Writing offset size failed.";
+    return false;
+  }
+  if (!no_stream_frame_length) {
+    static_assert(
+        std::numeric_limits<decltype(frame.data_length)>::max() <=
+            std::numeric_limits<uint16_t>::max(),
+        "If frame.data_length can hold more than a uint16_t than we need to "
+        "check that frame.data_length <= std::numeric_limits<uint16_t>::max()");
+    if (!writer->WriteUInt16(static_cast<uint16_t>(frame.data_length))) {
+      QUIC_BUG(quic_bug_10850_82) << "Writing stream frame length failed";
+      return false;
+    }
+  }
+
+  if (data_producer_ != nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
+    if (frame.data_length == 0) {
+      return true;
+    }
+    if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
+                                        frame.data_length,
+                                        writer) != WRITE_SUCCESS) {
+      QUIC_BUG(quic_bug_10850_83) << "Writing frame data failed.";
+      return false;
+    }
+    return true;
+  }
+
+  if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
+    QUIC_BUG(quic_bug_10850_84) << "Writing frame data failed.";
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendNewTokenFrame(const QuicNewTokenFrame& frame,
+                                     QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.token.length()))) {
+    set_detailed_error("Writing token length failed.");
+    return false;
+  }
+  if (!writer->WriteBytes(frame.token.data(), frame.token.length())) {
+    set_detailed_error("Writing token buffer failed.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessNewTokenFrame(QuicDataReader* reader,
+                                      QuicNewTokenFrame* frame) {
+  uint64_t length;
+  if (!reader->ReadVarInt62(&length)) {
+    set_detailed_error("Unable to read new token length.");
+    return false;
+  }
+  if (length > kMaxNewTokenTokenLength) {
+    set_detailed_error("Token length larger than maximum.");
+    return false;
+  }
+
+  // TODO(ianswett): Don't use absl::string_view as an intermediary.
+  absl::string_view data;
+  if (!reader->ReadStringPiece(&data, length)) {
+    set_detailed_error("Unable to read new token data.");
+    return false;
+  }
+  frame->token = std::string(data);
+  return true;
+}
+
+// Add a new ietf-format stream frame.
+// Bits controlling whether there is a frame-length and frame-offset
+// are in the QuicStreamFrame.
+bool QuicFramer::AppendIetfStreamFrame(const QuicStreamFrame& frame,
+                                       bool last_frame_in_packet,
+                                       QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
+    set_detailed_error("Writing stream id failed.");
+    return false;
+  }
+
+  if (frame.offset != 0) {
+    if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
+      set_detailed_error("Writing data offset failed.");
+      return false;
+    }
+  }
+
+  if (!last_frame_in_packet) {
+    if (!writer->WriteVarInt62(frame.data_length)) {
+      set_detailed_error("Writing data length failed.");
+      return false;
+    }
+  }
+
+  if (frame.data_length == 0) {
+    return true;
+  }
+  if (data_producer_ == nullptr) {
+    if (!writer->WriteBytes(frame.data_buffer, frame.data_length)) {
+      set_detailed_error("Writing frame data failed.");
+      return false;
+    }
+  } else {
+    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
+
+    if (data_producer_->WriteStreamData(frame.stream_id, frame.offset,
+                                        frame.data_length,
+                                        writer) != WRITE_SUCCESS) {
+      set_detailed_error("Writing frame data from producer failed.");
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::AppendCryptoFrame(const QuicCryptoFrame& frame,
+                                   QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
+    set_detailed_error("Writing data offset failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.data_length))) {
+    set_detailed_error("Writing data length failed.");
+    return false;
+  }
+  if (data_producer_ == nullptr) {
+    if (frame.data_buffer == nullptr ||
+        !writer->WriteBytes(frame.data_buffer, frame.data_length)) {
+      set_detailed_error("Writing frame data failed.");
+      return false;
+    }
+  } else {
+    QUICHE_DCHECK_EQ(nullptr, frame.data_buffer);
+    if (!data_producer_->WriteCryptoData(frame.level, frame.offset,
+                                         frame.data_length, writer)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+                                         QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.sequence_number)) {
+    set_detailed_error("Writing sequence number failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.packet_tolerance)) {
+    set_detailed_error("Writing packet tolerance failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(
+          static_cast<uint64_t>(frame.max_ack_delay.ToMicroseconds()))) {
+    set_detailed_error("Writing max_ack_delay_us failed.");
+    return false;
+  }
+  if (!writer->WriteUInt8(static_cast<uint8_t>(frame.ignore_order))) {
+    set_detailed_error("Writing ignore_order failed.");
+    return false;
+  }
+
+  return true;
+}
+
+void QuicFramer::set_version(const ParsedQuicVersion version) {
+  QUICHE_DCHECK(IsSupportedVersion(version))
+      << ParsedQuicVersionToString(version);
+  version_ = version;
+}
+
+bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                           QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return AppendIetfAckFrameAndTypeByte(frame, writer);
+  }
+
+  const AckFrameInfo new_ack_info = GetAckFrameInfo(frame);
+  QuicPacketNumber largest_acked = LargestAcked(frame);
+  QuicPacketNumberLength largest_acked_length =
+      GetMinPacketNumberLength(largest_acked);
+  QuicPacketNumberLength ack_block_length =
+      GetMinPacketNumberLength(QuicPacketNumber(new_ack_info.max_block_length));
+  // Calculate available bytes for timestamps and ack blocks.
+  int32_t available_timestamp_and_ack_block_bytes =
+      writer->capacity() - writer->length() - ack_block_length -
+      GetMinAckFrameSize(version_.transport_version, frame,
+                         local_ack_delay_exponent_,
+                         UseIetfAckWithReceiveTimestamp(frame)) -
+      (new_ack_info.num_ack_blocks != 0 ? kNumberOfAckBlocksSize : 0);
+  QUICHE_DCHECK_LE(0, available_timestamp_and_ack_block_bytes);
+
+  uint8_t type_byte = 0;
+  SetBit(&type_byte, new_ack_info.num_ack_blocks != 0,
+         kQuicHasMultipleAckBlocksOffset);
+
+  SetBits(&type_byte, GetPacketNumberFlags(largest_acked_length),
+          kQuicSequenceNumberLengthNumBits, kLargestAckedOffset);
+
+  SetBits(&type_byte, GetPacketNumberFlags(ack_block_length),
+          kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset);
+
+  type_byte |= kQuicFrameTypeAckMask;
+
+  if (!writer->WriteUInt8(type_byte)) {
+    return false;
+  }
+
+  size_t max_num_ack_blocks = available_timestamp_and_ack_block_bytes /
+                              (ack_block_length + PACKET_1BYTE_PACKET_NUMBER);
+
+  // Number of ack blocks.
+  size_t num_ack_blocks =
+      std::min(new_ack_info.num_ack_blocks, max_num_ack_blocks);
+  if (num_ack_blocks > std::numeric_limits<uint8_t>::max()) {
+    num_ack_blocks = std::numeric_limits<uint8_t>::max();
+  }
+
+  // Largest acked.
+  if (!AppendPacketNumber(largest_acked_length, largest_acked, writer)) {
+    return false;
+  }
+
+  // Largest acked delta time.
+  uint64_t ack_delay_time_us = kUFloat16MaxValue;
+  if (!frame.ack_delay_time.IsInfinite()) {
+    QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
+    ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
+  }
+  if (!writer->WriteUFloat16(ack_delay_time_us)) {
+    return false;
+  }
+
+  if (num_ack_blocks > 0) {
+    if (!writer->WriteBytes(&num_ack_blocks, 1)) {
+      return false;
+    }
+  }
+
+  // First ack block length.
+  if (!AppendPacketNumber(ack_block_length,
+                          QuicPacketNumber(new_ack_info.first_block_length),
+                          writer)) {
+    return false;
+  }
+
+  // Ack blocks.
+  if (num_ack_blocks > 0) {
+    size_t num_ack_blocks_written = 0;
+    // Append, in descending order from the largest ACKed packet, a series of
+    // ACK blocks that represents the successfully acknoweldged packets. Each
+    // appended gap/block length represents a descending delta from the previous
+    // block. i.e.:
+    // |--- length ---|--- gap ---|--- length ---|--- gap ---|--- largest ---|
+    // For gaps larger than can be represented by a single encoded gap, a 0
+    // length gap of the maximum is used, i.e.:
+    // |--- length ---|--- gap ---|- 0 -|--- gap ---|--- largest ---|
+    auto itr = frame.packets.rbegin();
+    QuicPacketNumber previous_start = itr->min();
+    ++itr;
+
+    for (;
+         itr != frame.packets.rend() && num_ack_blocks_written < num_ack_blocks;
+         previous_start = itr->min(), ++itr) {
+      const auto& interval = *itr;
+      const uint64_t total_gap = previous_start - interval.max();
+      const size_t num_encoded_gaps =
+          (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
+          std::numeric_limits<uint8_t>::max();
+
+      // Append empty ACK blocks because the gap is longer than a single gap.
+      for (size_t i = 1;
+           i < num_encoded_gaps && num_ack_blocks_written < num_ack_blocks;
+           ++i) {
+        if (!AppendAckBlock(std::numeric_limits<uint8_t>::max(),
+                            ack_block_length, 0, writer)) {
+          return false;
+        }
+        ++num_ack_blocks_written;
+      }
+      if (num_ack_blocks_written >= num_ack_blocks) {
+        if (QUIC_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
+          QUIC_BUG(quic_bug_10850_85)
+              << "Wrote " << num_ack_blocks_written << ", expected to write "
+              << num_ack_blocks;
+        }
+        break;
+      }
+
+      const uint8_t last_gap =
+          total_gap -
+          (num_encoded_gaps - 1) * std::numeric_limits<uint8_t>::max();
+      // Append the final ACK block with a non-empty size.
+      if (!AppendAckBlock(last_gap, ack_block_length, interval.Length(),
+                          writer)) {
+        return false;
+      }
+      ++num_ack_blocks_written;
+    }
+    QUICHE_DCHECK_EQ(num_ack_blocks, num_ack_blocks_written);
+  }
+  // Timestamps.
+  // If we don't process timestamps or if we don't have enough available space
+  // to append all the timestamps, don't append any of them.
+  if (process_timestamps_ && writer->capacity() - writer->length() >=
+                                 GetAckFrameTimeStampSize(frame)) {
+    if (!AppendTimestampsToAckFrame(frame, writer)) {
+      return false;
+    }
+  } else {
+    uint8_t num_received_packets = 0;
+    if (!writer->WriteBytes(&num_received_packets, 1)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame,
+                                            QuicDataWriter* writer) {
+  QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
+                   frame.received_packet_times.size());
+  // num_received_packets is only 1 byte.
+  if (frame.received_packet_times.size() >
+      std::numeric_limits<uint8_t>::max()) {
+    return false;
+  }
+
+  uint8_t num_received_packets = frame.received_packet_times.size();
+  if (!writer->WriteBytes(&num_received_packets, 1)) {
+    return false;
+  }
+  if (num_received_packets == 0) {
+    return true;
+  }
+
+  auto it = frame.received_packet_times.begin();
+  QuicPacketNumber packet_number = it->first;
+  uint64_t delta_from_largest_observed = LargestAcked(frame) - packet_number;
+
+  QUICHE_DCHECK_GE(std::numeric_limits<uint8_t>::max(),
+                   delta_from_largest_observed);
+  if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
+    return false;
+  }
+
+  if (!writer->WriteUInt8(delta_from_largest_observed)) {
+    return false;
+  }
+
+  // Use the lowest 4 bytes of the time delta from the creation_time_.
+  const uint64_t time_epoch_delta_us = UINT64_C(1) << 32;
+  uint32_t time_delta_us =
+      static_cast<uint32_t>((it->second - creation_time_).ToMicroseconds() &
+                            (time_epoch_delta_us - 1));
+  if (!writer->WriteUInt32(time_delta_us)) {
+    return false;
+  }
+
+  QuicTime prev_time = it->second;
+
+  for (++it; it != frame.received_packet_times.end(); ++it) {
+    packet_number = it->first;
+    delta_from_largest_observed = LargestAcked(frame) - packet_number;
+
+    if (delta_from_largest_observed > std::numeric_limits<uint8_t>::max()) {
+      return false;
+    }
+
+    if (!writer->WriteUInt8(delta_from_largest_observed)) {
+      return false;
+    }
+
+    uint64_t frame_time_delta_us = (it->second - prev_time).ToMicroseconds();
+    prev_time = it->second;
+    if (!writer->WriteUFloat16(frame_time_delta_us)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+absl::InlinedVector<QuicFramer::AckTimestampRange, 2>
+QuicFramer::GetAckTimestampRanges(const QuicAckFrame& frame,
+                                  std::string& detailed_error) const {
+  detailed_error = "";
+  if (frame.received_packet_times.empty()) {
+    return {};
+  }
+
+  absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges;
+
+  for (size_t r = 0; r < std::min<size_t>(max_receive_timestamps_per_ack_,
+                                          frame.received_packet_times.size());
+       ++r) {
+    const size_t i = frame.received_packet_times.size() - 1 - r;
+    const QuicPacketNumber packet_number = frame.received_packet_times[i].first;
+    const QuicTime receive_timestamp = frame.received_packet_times[i].second;
+
+    if (timestamp_ranges.empty()) {
+      if (receive_timestamp < creation_time_ ||
+          LargestAcked(frame) < packet_number) {
+        detailed_error =
+            "The first packet is either received earlier than framer creation "
+            "time, or larger than largest acked packet.";
+        QUIC_BUG(quic_framer_ack_ts_first_packet_bad)
+            << detailed_error << " receive_timestamp:" << receive_timestamp
+            << ", framer_creation_time:" << creation_time_
+            << ", packet_number:" << packet_number
+            << ", largest_acked:" << LargestAcked(frame);
+        return {};
+      }
+      timestamp_ranges.push_back(AckTimestampRange());
+      timestamp_ranges.back().gap = LargestAcked(frame) - packet_number;
+      timestamp_ranges.back().range_begin = i;
+      timestamp_ranges.back().range_end = i;
+      continue;
+    }
+
+    const size_t prev_i = timestamp_ranges.back().range_end;
+    const QuicPacketNumber prev_packet_number =
+        frame.received_packet_times[prev_i].first;
+    const QuicTime prev_receive_timestamp =
+        frame.received_packet_times[prev_i].second;
+
+    QUIC_DVLOG(3) << "prev_packet_number:" << prev_packet_number
+                  << ", packet_number:" << packet_number;
+    if (prev_receive_timestamp < receive_timestamp ||
+        prev_packet_number <= packet_number) {
+      detailed_error = "Packet number and/or receive time not in order.";
+      QUIC_BUG(quic_framer_ack_ts_packet_out_of_order)
+          << detailed_error << " packet_number:" << packet_number
+          << ", receive_timestamp:" << receive_timestamp
+          << ", prev_packet_number:" << prev_packet_number
+          << ", prev_receive_timestamp:" << prev_receive_timestamp;
+      return {};
+    }
+
+    if (prev_packet_number == packet_number + 1) {
+      timestamp_ranges.back().range_end = i;
+    } else {
+      timestamp_ranges.push_back(AckTimestampRange());
+      timestamp_ranges.back().gap = prev_packet_number - 2 - packet_number;
+      timestamp_ranges.back().range_begin = i;
+      timestamp_ranges.back().range_end = i;
+    }
+  }
+
+  return timestamp_ranges;
+}
+
+int64_t QuicFramer::FrameAckTimestampRanges(
+    const QuicAckFrame& frame,
+    const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
+    QuicDataWriter* writer) const {
+  int64_t size = 0;
+  auto maybe_write_var_int62 = [&](uint64_t value) {
+    size += QuicDataWriter::GetVarInt62Len(value);
+    if (writer != nullptr && !writer->WriteVarInt62(value)) {
+      return false;
+    }
+    return true;
+  };
+
+  if (!maybe_write_var_int62(timestamp_ranges.size())) {
+    return -1;
+  }
+
+  // |effective_prev_time| is the exponent-encoded timestamp of the previous
+  // packet.
+  absl::optional<QuicTime> effective_prev_time;
+  for (const AckTimestampRange& range : timestamp_ranges) {
+    QUIC_DVLOG(3) << "Range: gap:" << range.gap << ", beg:" << range.range_begin
+                  << ", end:" << range.range_end;
+    if (!maybe_write_var_int62(range.gap)) {
+      return -1;
+    }
+
+    if (!maybe_write_var_int62(range.range_begin - range.range_end + 1)) {
+      return -1;
+    }
+
+    for (int64_t i = range.range_begin; i >= range.range_end; --i) {
+      const QuicTime receive_timestamp = frame.received_packet_times[i].second;
+      uint64_t time_delta;
+      if (effective_prev_time.has_value()) {
+        time_delta =
+            (*effective_prev_time - receive_timestamp).ToMicroseconds();
+        QUIC_DVLOG(3) << "time_delta:" << time_delta
+                      << ", exponent:" << receive_timestamps_exponent_
+                      << ", effective_prev_time:" << *effective_prev_time
+                      << ", recv_time:" << receive_timestamp;
+        time_delta = time_delta >> receive_timestamps_exponent_;
+        effective_prev_time = effective_prev_time.value() -
+                              QuicTime::Delta::FromMicroseconds(
+                                  time_delta << receive_timestamps_exponent_);
+      } else {
+        // The first delta is from framer creation to the current receive
+        // timestamp (forward in time), whereas in the common case subsequent
+        // deltas move backwards in time.
+        time_delta = (receive_timestamp - creation_time_).ToMicroseconds();
+        QUIC_DVLOG(3) << "First time_delta:" << time_delta
+                      << ", exponent:" << receive_timestamps_exponent_
+                      << ", recv_time:" << receive_timestamp
+                      << ", creation_time:" << creation_time_;
+        // Round up the first exponent-encoded time delta so that the next
+        // receive timestamp is guaranteed to be decreasing.
+        time_delta = ((time_delta - 1) >> receive_timestamps_exponent_) + 1;
+        effective_prev_time =
+            creation_time_ + QuicTime::Delta::FromMicroseconds(
+                                 time_delta << receive_timestamps_exponent_);
+      }
+
+      if (!maybe_write_var_int62(time_delta)) {
+        return -1;
+      }
+    }
+  }
+
+  return size;
+}
+
+bool QuicFramer::AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
+                                                QuicDataWriter* writer) {
+  QUICHE_DCHECK(!frame.received_packet_times.empty());
+  std::string detailed_error;
+  const absl::InlinedVector<AckTimestampRange, 2> timestamp_ranges =
+      GetAckTimestampRanges(frame, detailed_error);
+  if (!detailed_error.empty()) {
+    set_detailed_error(std::move(detailed_error));
+    return false;
+  }
+
+  // Compute the size first using a null writer.
+  int64_t size =
+      FrameAckTimestampRanges(frame, timestamp_ranges, /*writer=*/nullptr);
+  if (size > static_cast<int64_t>(writer->capacity() - writer->length())) {
+    QUIC_DVLOG(1) << "Insufficient room to write IETF ack receive timestamps. "
+                     "size_remain:"
+                  << (writer->capacity() - writer->length())
+                  << ", size_needed:" << size;
+    // Write a Timestamp Range Count of 0.
+    return writer->WriteVarInt62(0);
+  }
+
+  return FrameAckTimestampRanges(frame, timestamp_ranges, writer) > 0;
+}
+
+bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
+                                        const QuicStopWaitingFrame& frame,
+                                        QuicDataWriter* writer) {
+  QUICHE_DCHECK(!version_.HasIetfInvariantHeader());
+  QUICHE_DCHECK(frame.least_unacked.IsInitialized());
+  QUICHE_DCHECK_GE(header.packet_number, frame.least_unacked);
+  const uint64_t least_unacked_delta =
+      header.packet_number - frame.least_unacked;
+  const uint64_t length_shift = header.packet_number_length * 8;
+
+  if (least_unacked_delta >> length_shift > 0) {
+    QUIC_BUG(quic_bug_10850_86)
+        << "packet_number_length " << header.packet_number_length
+        << " is too small for least_unacked_delta: " << least_unacked_delta
+        << " packet_number:" << header.packet_number
+        << " least_unacked:" << frame.least_unacked
+        << " version:" << version_.transport_version;
+    return false;
+  }
+  if (least_unacked_delta == 0) {
+    return writer->WriteBytesToUInt64(header.packet_number_length,
+                                      least_unacked_delta);
+  }
+  if (!AppendPacketNumber(header.packet_number_length,
+                          QuicPacketNumber(least_unacked_delta), writer)) {
+    QUIC_BUG(quic_bug_10850_87)
+        << " seq failed: " << header.packet_number_length;
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                               QuicDataWriter* writer) {
+  uint8_t type = IETF_ACK;
+  uint64_t ecn_size = 0;
+  if (UseIetfAckWithReceiveTimestamp(frame)) {
+    type = IETF_ACK_RECEIVE_TIMESTAMPS;
+  } else if (frame.ecn_counters_populated &&
+             (frame.ect_0_count || frame.ect_1_count || frame.ecn_ce_count)) {
+    // Change frame type to ACK_ECN if any ECN count is available.
+    type = IETF_ACK_ECN;
+    ecn_size = (QuicDataWriter::GetVarInt62Len(frame.ect_0_count) +
+                QuicDataWriter::GetVarInt62Len(frame.ect_1_count) +
+                QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count));
+  }
+
+  if (!writer->WriteVarInt62(type)) {
+    set_detailed_error("No room for frame-type");
+    return false;
+  }
+
+  QuicPacketNumber largest_acked = LargestAcked(frame);
+  if (!writer->WriteVarInt62(largest_acked.ToUint64())) {
+    set_detailed_error("No room for largest-acked in ack frame");
+    return false;
+  }
+
+  uint64_t ack_delay_time_us = kVarInt62MaxValue;
+  if (!frame.ack_delay_time.IsInfinite()) {
+    QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
+    ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
+    ack_delay_time_us = ack_delay_time_us >> local_ack_delay_exponent_;
+  }
+
+  if (!writer->WriteVarInt62(ack_delay_time_us)) {
+    set_detailed_error("No room for ack-delay in ack frame");
+    return false;
+  }
+
+  if (frame.packets.Empty() || frame.packets.Max() != largest_acked) {
+    QUIC_BUG(quic_bug_10850_88) << "Malformed ack frame: " << frame;
+    set_detailed_error("Malformed ack frame");
+    return false;
+  }
+
+  // Latch ack_block_count for potential truncation.
+  const uint64_t ack_block_count = frame.packets.NumIntervals() - 1;
+  QuicDataWriter count_writer(QuicDataWriter::GetVarInt62Len(ack_block_count),
+                              writer->data() + writer->length());
+  if (!writer->WriteVarInt62(ack_block_count)) {
+    set_detailed_error("No room for ack block count in ack frame");
+    return false;
+  }
+  auto iter = frame.packets.rbegin();
+  if (!writer->WriteVarInt62(iter->Length() - 1)) {
+    set_detailed_error("No room for first ack block in ack frame");
+    return false;
+  }
+  QuicPacketNumber previous_smallest = iter->min();
+  ++iter;
+  // Append remaining ACK blocks.
+  uint64_t appended_ack_blocks = 0;
+  for (; iter != frame.packets.rend(); ++iter) {
+    const uint64_t gap = previous_smallest - iter->max() - 1;
+    const uint64_t ack_range = iter->Length() - 1;
+
+    if (type == IETF_ACK_RECEIVE_TIMESTAMPS &&
+        writer->remaining() <
+            static_cast<size_t>(QuicDataWriter::GetVarInt62Len(gap) +
+                                QuicDataWriter::GetVarInt62Len(ack_range) +
+                                QuicDataWriter::GetVarInt62Len(0))) {
+      // If we write this ACK range we won't have space for a timestamp range
+      // count of 0.
+      break;
+    } else if (writer->remaining() < ecn_size ||
+               writer->remaining() - ecn_size <
+                   static_cast<size_t>(
+                       QuicDataWriter::GetVarInt62Len(gap) +
+                       QuicDataWriter::GetVarInt62Len(ack_range))) {
+      // ACK range does not fit, truncate it.
+      break;
+    }
+    const bool success =
+        writer->WriteVarInt62(gap) && writer->WriteVarInt62(ack_range);
+    QUICHE_DCHECK(success);
+    previous_smallest = iter->min();
+    ++appended_ack_blocks;
+  }
+
+  if (appended_ack_blocks < ack_block_count) {
+    // Truncation is needed, rewrite the ack block count.
+    if (QuicDataWriter::GetVarInt62Len(appended_ack_blocks) !=
+            QuicDataWriter::GetVarInt62Len(ack_block_count) ||
+        !count_writer.WriteVarInt62(appended_ack_blocks)) {
+      // This should never happen as ack_block_count is limited by
+      // max_ack_ranges_.
+      QUIC_BUG(quic_bug_10850_89)
+          << "Ack frame truncation fails. ack_block_count: " << ack_block_count
+          << ", appended count: " << appended_ack_blocks;
+      set_detailed_error("ACK frame truncation fails");
+      return false;
+    }
+    QUIC_DLOG(INFO) << ENDPOINT << "ACK ranges get truncated from "
+                    << ack_block_count << " to " << appended_ack_blocks;
+  }
+
+  if (type == IETF_ACK_ECN) {
+    // Encode the ECN counts.
+    if (!writer->WriteVarInt62(frame.ect_0_count)) {
+      set_detailed_error("No room for ect_0_count in ack frame");
+      return false;
+    }
+    if (!writer->WriteVarInt62(frame.ect_1_count)) {
+      set_detailed_error("No room for ect_1_count in ack frame");
+      return false;
+    }
+    if (!writer->WriteVarInt62(frame.ecn_ce_count)) {
+      set_detailed_error("No room for ecn_ce_count in ack frame");
+      return false;
+    }
+  }
+
+  if (type == IETF_ACK_RECEIVE_TIMESTAMPS) {
+    if (!AppendIetfTimestampsToAckFrame(frame, writer)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
+                                      QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfResetStreamFrame(frame, writer);
+  }
+  if (!writer->WriteUInt32(frame.stream_id)) {
+    return false;
+  }
+
+  if (!writer->WriteUInt64(frame.byte_offset)) {
+    return false;
+  }
+
+  uint32_t error_code = static_cast<uint32_t>(frame.error_code);
+  if (!writer->WriteUInt32(error_code)) {
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicFramer::AppendConnectionCloseFrame(
+    const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return AppendIetfConnectionCloseFrame(frame, writer);
+  }
+  uint32_t error_code = static_cast<uint32_t>(frame.wire_error_code);
+  if (!writer->WriteUInt32(error_code)) {
+    return false;
+  }
+  if (!writer->WriteStringPiece16(TruncateErrorString(frame.error_details))) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendGoAwayFrame(const QuicGoAwayFrame& frame,
+                                   QuicDataWriter* writer) {
+  uint32_t error_code = static_cast<uint32_t>(frame.error_code);
+  if (!writer->WriteUInt32(error_code)) {
+    return false;
+  }
+  uint32_t stream_id = static_cast<uint32_t>(frame.last_good_stream_id);
+  if (!writer->WriteUInt32(stream_id)) {
+    return false;
+  }
+  if (!writer->WriteStringPiece16(TruncateErrorString(frame.reason_phrase))) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                                         QuicDataWriter* writer) {
+  uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
+  if (!writer->WriteUInt32(stream_id)) {
+    return false;
+  }
+  if (!writer->WriteUInt64(frame.max_data)) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendBlockedFrame(const QuicBlockedFrame& frame,
+                                    QuicDataWriter* writer) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    if (frame.stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+      return AppendDataBlockedFrame(frame, writer);
+    }
+    return AppendStreamDataBlockedFrame(frame, writer);
+  }
+  uint32_t stream_id = static_cast<uint32_t>(frame.stream_id);
+  if (!writer->WriteUInt32(stream_id)) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame,
+                                    QuicDataWriter* writer) {
+  if (frame.num_padding_bytes == 0) {
+    return false;
+  }
+  if (frame.num_padding_bytes < 0) {
+    QUIC_BUG_IF(quic_bug_12975_9, frame.num_padding_bytes != -1);
+    writer->WritePadding();
+    return true;
+  }
+  // Please note, num_padding_bytes includes type byte which has been written.
+  return writer->WritePaddingBytes(frame.num_padding_bytes - 1);
+}
+
+bool QuicFramer::AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
+                                               bool last_frame_in_packet,
+                                               QuicDataWriter* writer) {
+  uint8_t type_byte;
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH_V99
+                                     : IETF_EXTENSION_MESSAGE_V99;
+  } else {
+    type_byte = last_frame_in_packet ? IETF_EXTENSION_MESSAGE_NO_LENGTH
+                                     : IETF_EXTENSION_MESSAGE;
+  }
+  if (!writer->WriteUInt8(type_byte)) {
+    return false;
+  }
+  if (!last_frame_in_packet && !writer->WriteVarInt62(frame.message_length)) {
+    return false;
+  }
+  for (const auto& slice : frame.message_data) {
+    if (!writer->WriteBytes(slice.data(), slice.length())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicFramer::RaiseError(QuicErrorCode error) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Error: " << QuicErrorCodeToString(error)
+                  << " detail: " << detailed_error_;
+  set_error(error);
+  if (visitor_) {
+    visitor_->OnError(this);
+  }
+  return false;
+}
+
+bool QuicFramer::IsVersionNegotiation(
+    const QuicPacketHeader& header, bool packet_has_ietf_packet_header) const {
+  if (!packet_has_ietf_packet_header &&
+      perspective_ == Perspective::IS_CLIENT) {
+    return header.version_flag;
+  }
+  if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return false;
+  }
+  return header.long_packet_type == VERSION_NEGOTIATION;
+}
+
+bool QuicFramer::AppendIetfConnectionCloseFrame(
+    const QuicConnectionCloseFrame& frame, QuicDataWriter* writer) {
+  if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
+      frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+    QUIC_BUG(quic_bug_10850_90)
+        << "Invalid close_type for writing IETF CONNECTION CLOSE.";
+    set_detailed_error("Invalid close_type for writing IETF CONNECTION CLOSE.");
+    return false;
+  }
+
+  if (!writer->WriteVarInt62(frame.wire_error_code)) {
+    set_detailed_error("Can not write connection close frame error code");
+    return false;
+  }
+
+  if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    // Write the frame-type of the frame causing the error only
+    // if it's a CONNECTION_CLOSE/Transport.
+    if (!writer->WriteVarInt62(frame.transport_close_frame_type)) {
+      set_detailed_error("Writing frame type failed.");
+      return false;
+    }
+  }
+
+  // There may be additional error information available in the extracted error
+  // code. Encode the error information in the reason phrase and serialize the
+  // result.
+  std::string final_error_string =
+      GenerateErrorString(frame.error_details, frame.quic_error_code);
+  if (!writer->WriteStringPieceVarInt62(
+          TruncateErrorString(final_error_string))) {
+    set_detailed_error("Can not write connection close phrase");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfConnectionCloseFrame(
+    QuicDataReader* reader, QuicConnectionCloseType type,
+    QuicConnectionCloseFrame* frame) {
+  frame->close_type = type;
+
+  uint64_t error_code;
+  if (!reader->ReadVarInt62(&error_code)) {
+    set_detailed_error("Unable to read connection close error code.");
+    return false;
+  }
+
+  frame->wire_error_code = error_code;
+
+  if (type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+    // The frame-type of the frame causing the error is present only
+    // if it's a CONNECTION_CLOSE/Transport.
+    if (!reader->ReadVarInt62(&frame->transport_close_frame_type)) {
+      set_detailed_error("Unable to read connection close frame type.");
+      return false;
+    }
+  }
+
+  uint64_t phrase_length;
+  if (!reader->ReadVarInt62(&phrase_length)) {
+    set_detailed_error("Unable to read connection close error details.");
+    return false;
+  }
+
+  absl::string_view phrase;
+  if (!reader->ReadStringPiece(&phrase, static_cast<size_t>(phrase_length))) {
+    set_detailed_error("Unable to read connection close error details.");
+    return false;
+  }
+  frame->error_details = std::string(phrase);
+
+  // The frame may have an extracted error code in it. Look for it and
+  // extract it. If it's not present, MaybeExtract will return
+  // QUIC_IETF_GQUIC_ERROR_MISSING.
+  MaybeExtractQuicErrorCode(frame);
+  return true;
+}
+
+// IETF Quic Path Challenge/Response frames.
+bool QuicFramer::ProcessPathChallengeFrame(QuicDataReader* reader,
+                                           QuicPathChallengeFrame* frame) {
+  if (!reader->ReadBytes(frame->data_buffer.data(),
+                         frame->data_buffer.size())) {
+    set_detailed_error("Can not read path challenge data.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessPathResponseFrame(QuicDataReader* reader,
+                                          QuicPathResponseFrame* frame) {
+  if (!reader->ReadBytes(frame->data_buffer.data(),
+                         frame->data_buffer.size())) {
+    set_detailed_error("Can not read path response data.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
+                                          QuicDataWriter* writer) {
+  if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
+    set_detailed_error("Writing Path Challenge data failed.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendPathResponseFrame(const QuicPathResponseFrame& frame,
+                                         QuicDataWriter* writer) {
+  if (!writer->WriteBytes(frame.data_buffer.data(), frame.data_buffer.size())) {
+    set_detailed_error("Writing Path Response data failed.");
+    return false;
+  }
+  return true;
+}
+
+// Add a new ietf-format stream reset frame.
+// General format is
+//    stream id
+//    application error code
+//    final offset
+bool QuicFramer::AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
+                                            QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
+    set_detailed_error("Writing reset-stream stream id failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.ietf_error_code))) {
+    set_detailed_error("Writing reset-stream error code failed.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.byte_offset))) {
+    set_detailed_error("Writing reset-stream final-offset failed.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessIetfResetStreamFrame(QuicDataReader* reader,
+                                             QuicRstStreamFrame* frame) {
+  // Get Stream ID from frame. ReadVarIntStreamID returns false
+  // if either A) there is a read error or B) the resulting value of
+  // the Stream ID is larger than the maximum allowed value.
+  if (!ReadUint32FromVarint62(reader, IETF_RST_STREAM, &frame->stream_id)) {
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&frame->ietf_error_code)) {
+    set_detailed_error("Unable to read rst stream error code.");
+    return false;
+  }
+
+  frame->error_code =
+      IetfResetStreamErrorCodeToRstStreamErrorCode(frame->ietf_error_code);
+
+  if (!reader->ReadVarInt62(&frame->byte_offset)) {
+    set_detailed_error("Unable to read rst stream sent byte offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStopSendingFrame(
+    QuicDataReader* reader, QuicStopSendingFrame* stop_sending_frame) {
+  if (!ReadUint32FromVarint62(reader, IETF_STOP_SENDING,
+                              &stop_sending_frame->stream_id)) {
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&stop_sending_frame->ietf_error_code)) {
+    set_detailed_error("Unable to read stop sending application error code.");
+    return false;
+  }
+
+  stop_sending_frame->error_code = IetfResetStreamErrorCodeToRstStreamErrorCode(
+      stop_sending_frame->ietf_error_code);
+  return true;
+}
+
+bool QuicFramer::AppendStopSendingFrame(
+    const QuicStopSendingFrame& stop_sending_frame, QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
+    set_detailed_error("Can not write stop sending stream id");
+    return false;
+  }
+  if (!writer->WriteVarInt62(
+          static_cast<uint64_t>(stop_sending_frame.ietf_error_code))) {
+    set_detailed_error("Can not write application error code");
+    return false;
+  }
+  return true;
+}
+
+// Append/process IETF-Format MAX_DATA Frame
+bool QuicFramer::AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
+                                    QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.max_data)) {
+    set_detailed_error("Can not write MAX_DATA byte-offset");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessMaxDataFrame(QuicDataReader* reader,
+                                     QuicWindowUpdateFrame* frame) {
+  frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
+  if (!reader->ReadVarInt62(&frame->max_data)) {
+    set_detailed_error("Can not read MAX_DATA byte-offset");
+    return false;
+  }
+  return true;
+}
+
+// Append/process IETF-Format MAX_STREAM_DATA Frame
+bool QuicFramer::AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
+                                          QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_id)) {
+    set_detailed_error("Can not write MAX_STREAM_DATA stream id");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.max_data)) {
+    set_detailed_error("Can not write MAX_STREAM_DATA byte-offset");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessMaxStreamDataFrame(QuicDataReader* reader,
+                                           QuicWindowUpdateFrame* frame) {
+  if (!ReadUint32FromVarint62(reader, IETF_MAX_STREAM_DATA,
+                              &frame->stream_id)) {
+    return false;
+  }
+  if (!reader->ReadVarInt62(&frame->max_data)) {
+    set_detailed_error("Can not read MAX_STREAM_DATA byte-count");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
+                                       QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_count)) {
+    set_detailed_error("Can not write MAX_STREAMS stream count");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessMaxStreamsFrame(QuicDataReader* reader,
+                                        QuicMaxStreamsFrame* frame,
+                                        uint64_t frame_type) {
+  if (!ReadUint32FromVarint62(reader,
+                              static_cast<QuicIetfFrameType>(frame_type),
+                              &frame->stream_count)) {
+    return false;
+  }
+  frame->unidirectional = (frame_type == IETF_MAX_STREAMS_UNIDIRECTIONAL);
+  return true;
+}
+
+bool QuicFramer::AppendDataBlockedFrame(const QuicBlockedFrame& frame,
+                                        QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.offset)) {
+    set_detailed_error("Can not write blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessDataBlockedFrame(QuicDataReader* reader,
+                                         QuicBlockedFrame* frame) {
+  // Indicates that it is a BLOCKED frame (as opposed to STREAM_BLOCKED).
+  frame->stream_id = QuicUtils::GetInvalidStreamId(transport_version());
+  if (!reader->ReadVarInt62(&frame->offset)) {
+    set_detailed_error("Can not read blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
+                                              QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_id)) {
+    set_detailed_error("Can not write stream blocked stream id.");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.offset)) {
+    set_detailed_error("Can not write stream blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStreamDataBlockedFrame(QuicDataReader* reader,
+                                               QuicBlockedFrame* frame) {
+  if (!ReadUint32FromVarint62(reader, IETF_STREAM_DATA_BLOCKED,
+                              &frame->stream_id)) {
+    return false;
+  }
+  if (!reader->ReadVarInt62(&frame->offset)) {
+    set_detailed_error("Can not read stream blocked offset.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                                           QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.stream_count)) {
+    set_detailed_error("Can not write STREAMS_BLOCKED stream count");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessStreamsBlockedFrame(QuicDataReader* reader,
+                                            QuicStreamsBlockedFrame* frame,
+                                            uint64_t frame_type) {
+  if (!ReadUint32FromVarint62(reader,
+                              static_cast<QuicIetfFrameType>(frame_type),
+                              &frame->stream_count)) {
+    return false;
+  }
+  if (frame->stream_count > QuicUtils::GetMaxStreamCount()) {
+    // If stream count is such that the resulting stream ID would exceed our
+    // implementation limit, generate an error.
+    set_detailed_error(
+        "STREAMS_BLOCKED stream count exceeds implementation limit.");
+    return false;
+  }
+  frame->unidirectional = (frame_type == IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
+  return true;
+}
+
+bool QuicFramer::AppendNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& frame, QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.sequence_number)) {
+    set_detailed_error("Can not write New Connection ID sequence number");
+    return false;
+  }
+  if (!writer->WriteVarInt62(frame.retire_prior_to)) {
+    set_detailed_error("Can not write New Connection ID retire_prior_to");
+    return false;
+  }
+  if (!writer->WriteLengthPrefixedConnectionId(frame.connection_id)) {
+    set_detailed_error("Can not write New Connection ID frame connection ID");
+    return false;
+  }
+
+  if (!writer->WriteBytes(
+          static_cast<const void*>(&frame.stateless_reset_token),
+          sizeof(frame.stateless_reset_token))) {
+    set_detailed_error("Can not write New Connection ID Reset Token");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessNewConnectionIdFrame(QuicDataReader* reader,
+                                             QuicNewConnectionIdFrame* frame) {
+  if (!reader->ReadVarInt62(&frame->sequence_number)) {
+    set_detailed_error(
+        "Unable to read new connection ID frame sequence number.");
+    return false;
+  }
+
+  if (!reader->ReadVarInt62(&frame->retire_prior_to)) {
+    set_detailed_error(
+        "Unable to read new connection ID frame retire_prior_to.");
+    return false;
+  }
+  if (frame->retire_prior_to > frame->sequence_number) {
+    set_detailed_error("Retire_prior_to > sequence_number.");
+    return false;
+  }
+
+  if (!reader->ReadLengthPrefixedConnectionId(&frame->connection_id)) {
+    set_detailed_error("Unable to read new connection ID frame connection id.");
+    return false;
+  }
+
+  if (!QuicUtils::IsConnectionIdValidForVersion(frame->connection_id,
+                                                transport_version())) {
+    set_detailed_error("Invalid new connection ID length for version.");
+    return false;
+  }
+
+  if (!reader->ReadBytes(&frame->stateless_reset_token,
+                         sizeof(frame->stateless_reset_token))) {
+    set_detailed_error("Can not read new connection ID frame reset token.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::AppendRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& frame, QuicDataWriter* writer) {
+  if (!writer->WriteVarInt62(frame.sequence_number)) {
+    set_detailed_error("Can not write Retire Connection ID sequence number");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ProcessRetireConnectionIdFrame(
+    QuicDataReader* reader, QuicRetireConnectionIdFrame* frame) {
+  if (!reader->ReadVarInt62(&frame->sequence_number)) {
+    set_detailed_error(
+        "Unable to read retire connection ID frame sequence number.");
+    return false;
+  }
+  return true;
+}
+
+bool QuicFramer::ReadUint32FromVarint62(QuicDataReader* reader,
+                                        QuicIetfFrameType type,
+                                        QuicStreamId* id) {
+  uint64_t temp_uint64;
+  if (!reader->ReadVarInt62(&temp_uint64)) {
+    set_detailed_error("Unable to read " + QuicIetfFrameTypeString(type) +
+                       " frame stream id/count.");
+    return false;
+  }
+  if (temp_uint64 > kMaxQuicStreamId) {
+    set_detailed_error("Stream id/count of " + QuicIetfFrameTypeString(type) +
+                       "frame is too large.");
+    return false;
+  }
+  *id = static_cast<uint32_t>(temp_uint64);
+  return true;
+}
+
+uint8_t QuicFramer::GetStreamFrameTypeByte(const QuicStreamFrame& frame,
+                                           bool last_frame_in_packet) const {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    return GetIetfStreamFrameTypeByte(frame, last_frame_in_packet);
+  }
+  uint8_t type_byte = 0;
+  // Fin bit.
+  type_byte |= frame.fin ? kQuicStreamFinMask : 0;
+
+  // Data Length bit.
+  type_byte <<= kQuicStreamDataLengthShift;
+  type_byte |= last_frame_in_packet ? 0 : kQuicStreamDataLengthMask;
+
+  // Offset 3 bits.
+  type_byte <<= kQuicStreamShift;
+  const size_t offset_len = GetStreamOffsetSize(frame.offset);
+  if (offset_len > 0) {
+    type_byte |= offset_len - 1;
+  }
+
+  // stream id 2 bits.
+  type_byte <<= kQuicStreamIdShift;
+  type_byte |= GetStreamIdSize(frame.stream_id) - 1;
+  type_byte |= kQuicFrameTypeStreamMask;  // Set Stream Frame Type to 1.
+
+  return type_byte;
+}
+
+uint8_t QuicFramer::GetIetfStreamFrameTypeByte(
+    const QuicStreamFrame& frame, bool last_frame_in_packet) const {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
+  uint8_t type_byte = IETF_STREAM;
+  if (!last_frame_in_packet) {
+    type_byte |= IETF_STREAM_FRAME_LEN_BIT;
+  }
+  if (frame.offset != 0) {
+    type_byte |= IETF_STREAM_FRAME_OFF_BIT;
+  }
+  if (frame.fin) {
+    type_byte |= IETF_STREAM_FRAME_FIN_BIT;
+  }
+  return type_byte;
+}
+
+void QuicFramer::InferPacketHeaderTypeFromVersion() {
+  // This function should only be called when server connection negotiates the
+  // version.
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
+  QUICHE_DCHECK(!infer_packet_header_type_from_version_);
+  infer_packet_header_type_from_version_ = true;
+}
+
+void QuicFramer::EnableMultiplePacketNumberSpacesSupport() {
+  if (supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10850_91)
+        << "Multiple packet number spaces has already been enabled";
+    return;
+  }
+  if (largest_packet_number_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10850_92)
+        << "Try to enable multiple packet number spaces support after any "
+           "packet has been received.";
+    return;
+  }
+
+  supports_multiple_packet_number_spaces_ = true;
+}
+
+// static
+QuicErrorCode QuicFramer::ParsePublicHeaderDispatcher(
+    const QuicEncryptedPacket& packet,
+    uint8_t expected_destination_connection_id_length,
+    PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
+    bool* version_present, bool* has_length_prefix,
+    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
+    QuicConnectionId* destination_connection_id,
+    QuicConnectionId* source_connection_id,
+    absl::optional<absl::string_view>* retry_token,
+    std::string* detailed_error) {
+  QuicDataReader reader(packet.data(), packet.length());
+  if (reader.IsDoneReading()) {
+    *detailed_error = "Unable to read first byte.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  const uint8_t first_byte = reader.PeekByte();
+  if ((first_byte & FLAGS_LONG_HEADER) == 0 &&
+      (first_byte & FLAGS_FIXED_BIT) == 0 &&
+      (first_byte & FLAGS_DEMULTIPLEXING_BIT) == 0) {
+    // All versions of Google QUIC up to and including Q043 set
+    // FLAGS_DEMULTIPLEXING_BIT to one on all client-to-server packets. Q044
+    // and Q045 were never default-enabled in production. All subsequent
+    // versions of Google QUIC (starting with Q046) require FLAGS_FIXED_BIT to
+    // be set to one on all packets. All versions of IETF QUIC (since
+    // draft-ietf-quic-transport-17 which was earlier than the first IETF QUIC
+    // version that was deployed in production by any implementation) also
+    // require FLAGS_FIXED_BIT to be set to one on all packets. If a packet
+    // has the FLAGS_LONG_HEADER bit set to one, it could be a first flight
+    // from an unknown future version that allows the other two bits to be set
+    // to zero. Based on this, packets that have all three of those bits set
+    // to zero are known to be invalid.
+    *detailed_error = "Invalid flags.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  const bool ietf_format = QuicUtils::IsIetfPacketHeader(first_byte);
+  uint8_t unused_first_byte;
+  QuicVariableLengthIntegerLength retry_token_length_length;
+  absl::string_view maybe_retry_token;
+  QuicErrorCode error_code = ParsePublicHeader(
+      &reader, expected_destination_connection_id_length, ietf_format,
+      &unused_first_byte, format, version_present, has_length_prefix,
+      version_label, parsed_version, destination_connection_id,
+      source_connection_id, long_packet_type, &retry_token_length_length,
+      &maybe_retry_token, detailed_error);
+  if (retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+    *retry_token = maybe_retry_token;
+  } else {
+    retry_token->reset();
+  }
+  return error_code;
+}
+
+// static
+QuicErrorCode QuicFramer::ParsePublicHeaderGoogleQuic(
+    QuicDataReader* reader, uint8_t* first_byte, PacketHeaderFormat* format,
+    bool* version_present, QuicVersionLabel* version_label,
+    ParsedQuicVersion* parsed_version,
+    QuicConnectionId* destination_connection_id, std::string* detailed_error) {
+  *format = GOOGLE_QUIC_PACKET;
+  *version_present = (*first_byte & PACKET_PUBLIC_FLAGS_VERSION) != 0;
+  uint8_t destination_connection_id_length = 0;
+  if ((*first_byte & PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID) != 0) {
+    destination_connection_id_length = kQuicDefaultConnectionIdLength;
+  }
+  if (!reader->ReadConnectionId(destination_connection_id,
+                                destination_connection_id_length)) {
+    *detailed_error = "Unable to read ConnectionId.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+  if (*version_present) {
+    if (!ProcessVersionLabel(reader, version_label)) {
+      *detailed_error = "Unable to read protocol version.";
+      return QUIC_INVALID_PACKET_HEADER;
+    }
+    *parsed_version = ParseQuicVersionLabel(*version_label);
+  }
+  return QUIC_NO_ERROR;
+}
+
+namespace {
+
+const QuicVersionLabel kProxVersionLabel = 0x50524F58;  // "PROX"
+
+inline bool PacketHasLengthPrefixedConnectionIds(
+    const QuicDataReader& reader, ParsedQuicVersion parsed_version,
+    QuicVersionLabel version_label, uint8_t first_byte) {
+  if (parsed_version.IsKnown()) {
+    return parsed_version.HasLengthPrefixedConnectionIds();
+  }
+
+  // Received unsupported version, check known old unsupported versions.
+  if (QuicVersionLabelUses4BitConnectionIdLength(version_label)) {
+    return false;
+  }
+
+  // Received unknown version, check connection ID length byte.
+  if (reader.IsDoneReading()) {
+    // This check is required to safely peek the connection ID length byte.
+    return true;
+  }
+  const uint8_t connection_id_length_byte = reader.PeekByte();
+
+  // Check for packets produced by older versions of
+  // QuicFramer::WriteClientVersionNegotiationProbePacket
+  if (first_byte == 0xc0 && (connection_id_length_byte & 0x0f) == 0 &&
+      connection_id_length_byte >= 0x50 && version_label == 0xcabadaba) {
+    return false;
+  }
+
+  // Check for munged packets with version tag PROX.
+  if ((connection_id_length_byte & 0x0f) == 0 &&
+      connection_id_length_byte >= 0x20 && version_label == kProxVersionLabel) {
+    return false;
+  }
+
+  return true;
+}
+
+inline bool ParseLongHeaderConnectionIds(
+    QuicDataReader& reader, bool has_length_prefix,
+    QuicVersionLabel version_label, QuicConnectionId& destination_connection_id,
+    QuicConnectionId& source_connection_id, std::string& detailed_error) {
+  if (has_length_prefix) {
+    if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
+      detailed_error = "Unable to read destination connection ID.";
+      return false;
+    }
+    if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
+      if (version_label == kProxVersionLabel) {
+        // The "PROX" version does not follow the length-prefixed invariants,
+        // and can therefore attempt to read a payload byte and interpret it
+        // as the source connection ID length, which could fail to parse.
+        // In that scenario we keep the source connection ID empty but mark
+        // parsing as successful.
+        return true;
+      }
+      detailed_error = "Unable to read source connection ID.";
+      return false;
+    }
+  } else {
+    // Parse connection ID lengths.
+    uint8_t connection_id_lengths_byte;
+    if (!reader.ReadUInt8(&connection_id_lengths_byte)) {
+      detailed_error = "Unable to read connection ID lengths.";
+      return false;
+    }
+    uint8_t destination_connection_id_length =
+        (connection_id_lengths_byte & kDestinationConnectionIdLengthMask) >> 4;
+    if (destination_connection_id_length != 0) {
+      destination_connection_id_length += kConnectionIdLengthAdjustment;
+    }
+    uint8_t source_connection_id_length =
+        connection_id_lengths_byte & kSourceConnectionIdLengthMask;
+    if (source_connection_id_length != 0) {
+      source_connection_id_length += kConnectionIdLengthAdjustment;
+    }
+
+    // Read destination connection ID.
+    if (!reader.ReadConnectionId(&destination_connection_id,
+                                 destination_connection_id_length)) {
+      detailed_error = "Unable to read destination connection ID.";
+      return false;
+    }
+
+    // Read source connection ID.
+    if (!reader.ReadConnectionId(&source_connection_id,
+                                 source_connection_id_length)) {
+      detailed_error = "Unable to read source connection ID.";
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace
+
+// static
+QuicErrorCode QuicFramer::ParsePublicHeader(
+    QuicDataReader* reader, uint8_t expected_destination_connection_id_length,
+    bool ietf_format, uint8_t* first_byte, PacketHeaderFormat* format,
+    bool* version_present, bool* has_length_prefix,
+    QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
+    QuicConnectionId* destination_connection_id,
+    QuicConnectionId* source_connection_id,
+    QuicLongHeaderType* long_packet_type,
+    QuicVariableLengthIntegerLength* retry_token_length_length,
+    absl::string_view* retry_token, std::string* detailed_error) {
+  *version_present = false;
+  *has_length_prefix = false;
+  *version_label = 0;
+  *parsed_version = UnsupportedQuicVersion();
+  *source_connection_id = EmptyQuicConnectionId();
+  *long_packet_type = INVALID_PACKET_TYPE;
+  *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  *retry_token = absl::string_view();
+  *detailed_error = "";
+
+  if (!reader->ReadUInt8(first_byte)) {
+    *detailed_error = "Unable to read first byte.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (!ietf_format) {
+    return ParsePublicHeaderGoogleQuic(
+        reader, first_byte, format, version_present, version_label,
+        parsed_version, destination_connection_id, detailed_error);
+  }
+
+  *format = GetIetfPacketHeaderFormat(*first_byte);
+
+  if (*format == IETF_QUIC_SHORT_HEADER_PACKET) {
+    // Read destination connection ID using
+    // expected_destination_connection_id_length to determine its length.
+    if (!reader->ReadConnectionId(destination_connection_id,
+                                  expected_destination_connection_id_length)) {
+      *detailed_error = "Unable to read destination connection ID.";
+      return QUIC_INVALID_PACKET_HEADER;
+    }
+    return QUIC_NO_ERROR;
+  }
+
+  QUICHE_DCHECK_EQ(IETF_QUIC_LONG_HEADER_PACKET, *format);
+  *version_present = true;
+  if (!ProcessVersionLabel(reader, version_label)) {
+    *detailed_error = "Unable to read protocol version.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (*version_label == 0) {
+    *long_packet_type = VERSION_NEGOTIATION;
+  }
+
+  // Parse version.
+  *parsed_version = ParseQuicVersionLabel(*version_label);
+
+  // Figure out which IETF QUIC invariants this packet follows.
+  *has_length_prefix = PacketHasLengthPrefixedConnectionIds(
+      *reader, *parsed_version, *version_label, *first_byte);
+
+  // Parse connection IDs.
+  if (!ParseLongHeaderConnectionIds(*reader, *has_length_prefix, *version_label,
+                                    *destination_connection_id,
+                                    *source_connection_id, *detailed_error)) {
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (!parsed_version->IsKnown()) {
+    // Skip parsing of long packet type and retry token for unknown versions.
+    return QUIC_NO_ERROR;
+  }
+
+  // Parse long packet type.
+  *long_packet_type = GetLongHeaderType(*first_byte, *parsed_version);
+
+  switch (*long_packet_type) {
+    case INVALID_PACKET_TYPE:
+      *detailed_error = "Unable to parse long packet type.";
+      return QUIC_INVALID_PACKET_HEADER;
+    case INITIAL:
+      if (!parsed_version->SupportsRetry()) {
+        // Retry token is only present on initial packets for some versions.
+        return QUIC_NO_ERROR;
+      }
+      break;
+    default:
+      return QUIC_NO_ERROR;
+  }
+
+  *retry_token_length_length = reader->PeekVarInt62Length();
+  uint64_t retry_token_length;
+  if (!reader->ReadVarInt62(&retry_token_length)) {
+    *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    *detailed_error = "Unable to read retry token length.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  if (!reader->ReadStringPiece(retry_token, retry_token_length)) {
+    *detailed_error = "Unable to read retry token.";
+    return QUIC_INVALID_PACKET_HEADER;
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+// static
+bool QuicFramer::WriteClientVersionNegotiationProbePacket(
+    char* packet_bytes, QuicByteCount packet_length,
+    const char* destination_connection_id_bytes,
+    uint8_t destination_connection_id_length) {
+  if (packet_bytes == nullptr) {
+    QUIC_BUG(quic_bug_10850_93) << "Invalid packet_bytes";
+    return false;
+  }
+  if (packet_length < kMinPacketSizeForVersionNegotiation ||
+      packet_length > 65535) {
+    QUIC_BUG(quic_bug_10850_94) << "Invalid packet_length";
+    return false;
+  }
+  if (destination_connection_id_length > kQuicMaxConnectionId4BitLength ||
+      destination_connection_id_length < kQuicDefaultConnectionIdLength) {
+    QUIC_BUG(quic_bug_10850_95) << "Invalid connection_id_length";
+    return false;
+  }
+  // clang-format off
+  const unsigned char packet_start_bytes[] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    // This intentionally differs from QuicVersionReservedForNegotiation()
+    // to allow differentiating them over the wire.
+    0xca, 0xba, 0xda, 0xda,
+  };
+  // clang-format on
+  static_assert(sizeof(packet_start_bytes) == 5, "bad packet_start_bytes size");
+  QuicDataWriter writer(packet_length, packet_bytes);
+  if (!writer.WriteBytes(packet_start_bytes, sizeof(packet_start_bytes))) {
+    QUIC_BUG(quic_bug_10850_96) << "Failed to write packet start";
+    return false;
+  }
+
+  QuicConnectionId destination_connection_id(destination_connection_id_bytes,
+                                             destination_connection_id_length);
+  if (!AppendIetfConnectionIds(
+          /*version_flag=*/true, /*use_length_prefix=*/true,
+          destination_connection_id, EmptyQuicConnectionId(), &writer)) {
+    QUIC_BUG(quic_bug_10850_97) << "Failed to write connection IDs";
+    return false;
+  }
+  // Add 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+  // not parse with any known version. The zeroes make sure that packet numbers,
+  // retry token lengths and payload lengths are parsed as zero, and if the
+  // zeroes are treated as padding frames, 0xff is known to not parse as a
+  // valid frame type.
+  if (!writer.WriteUInt64(0) ||
+      !writer.WriteUInt64(std::numeric_limits<uint64_t>::max())) {
+    QUIC_BUG(quic_bug_10850_98) << "Failed to write 18 bytes";
+    return false;
+  }
+  // Make sure the polite greeting below is padded to a 16-byte boundary to
+  // make it easier to read in tcpdump.
+  while (writer.length() % 16 != 0) {
+    if (!writer.WriteUInt8(0)) {
+      QUIC_BUG(quic_bug_10850_99) << "Failed to write padding byte";
+      return false;
+    }
+  }
+  // Add a polite greeting in case a human sees this in tcpdump.
+  static const char polite_greeting[] =
+      "This packet only exists to trigger IETF QUIC version negotiation. "
+      "Please respond with a Version Negotiation packet indicating what "
+      "versions you support. Thank you and have a nice day.";
+  if (!writer.WriteBytes(polite_greeting, sizeof(polite_greeting))) {
+    QUIC_BUG(quic_bug_10850_100) << "Failed to write polite greeting";
+    return false;
+  }
+  // Fill the rest of the packet with zeroes.
+  writer.WritePadding();
+  QUICHE_DCHECK_EQ(0u, writer.remaining());
+  return true;
+}
+
+// static
+bool QuicFramer::ParseServerVersionNegotiationProbeResponse(
+    const char* packet_bytes, QuicByteCount packet_length,
+    char* source_connection_id_bytes, uint8_t* source_connection_id_length_out,
+    std::string* detailed_error) {
+  if (detailed_error == nullptr) {
+    QUIC_BUG(quic_bug_10850_101) << "Invalid error_details";
+    return false;
+  }
+  *detailed_error = "";
+  if (packet_bytes == nullptr) {
+    *detailed_error = "Invalid packet_bytes";
+    return false;
+  }
+  if (packet_length < 6) {
+    *detailed_error = "Invalid packet_length";
+    return false;
+  }
+  if (source_connection_id_bytes == nullptr) {
+    *detailed_error = "Invalid source_connection_id_bytes";
+    return false;
+  }
+  if (source_connection_id_length_out == nullptr) {
+    *detailed_error = "Invalid source_connection_id_length_out";
+    return false;
+  }
+  QuicDataReader reader(packet_bytes, packet_length);
+  uint8_t type_byte = 0;
+  if (!reader.ReadUInt8(&type_byte)) {
+    *detailed_error = "Failed to read type byte";
+    return false;
+  }
+  if ((type_byte & 0x80) == 0) {
+    *detailed_error = "Packet does not have long header";
+    return false;
+  }
+  uint32_t version = 0;
+  if (!reader.ReadUInt32(&version)) {
+    *detailed_error = "Failed to read version";
+    return false;
+  }
+  if (version != 0) {
+    *detailed_error = "Packet is not a version negotiation packet";
+    return false;
+  }
+
+  QuicConnectionId destination_connection_id, source_connection_id;
+  if (!reader.ReadLengthPrefixedConnectionId(&destination_connection_id)) {
+    *detailed_error = "Failed to read destination connection ID";
+    return false;
+  }
+  if (!reader.ReadLengthPrefixedConnectionId(&source_connection_id)) {
+    *detailed_error = "Failed to read source connection ID";
+    return false;
+  }
+
+  if (destination_connection_id.length() != 0) {
+    *detailed_error = "Received unexpected destination connection ID length";
+    return false;
+  }
+  if (*source_connection_id_length_out < source_connection_id.length()) {
+    *detailed_error =
+        absl::StrCat("*source_connection_id_length_out too small ",
+                     static_cast<int>(*source_connection_id_length_out), " < ",
+                     static_cast<int>(source_connection_id.length()));
+    return false;
+  }
+
+  memcpy(source_connection_id_bytes, source_connection_id.data(),
+         source_connection_id.length());
+  *source_connection_id_length_out = source_connection_id.length();
+
+  return true;
+}
+
+// Look for and parse the error code from the "<quic_error_code>:" text that
+// may be present at the start of the CONNECTION_CLOSE error details string.
+// This text, inserted by the peer if it's using Google's QUIC implementation,
+// contains additional error information that narrows down the exact error.  If
+// the string is not found, or is not properly formed, it returns
+// ErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING
+void MaybeExtractQuicErrorCode(QuicConnectionCloseFrame* frame) {
+  std::vector<absl::string_view> ed = absl::StrSplit(frame->error_details, ':');
+  uint64_t extracted_error_code;
+  if (ed.size() < 2 || !quiche::QuicheTextUtils::IsAllDigits(ed[0]) ||
+      !absl::SimpleAtoi(ed[0], &extracted_error_code)) {
+    if (frame->close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
+        frame->wire_error_code == NO_IETF_QUIC_ERROR) {
+      frame->quic_error_code = QUIC_NO_ERROR;
+    } else {
+      frame->quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
+    }
+    return;
+  }
+  // Return the error code (numeric) and the error details string without the
+  // error code prefix. Note that Split returns everything up to, but not
+  // including, the split character, so the length of ed[0] is just the number
+  // of digits in the error number. In removing the prefix, 1 is added to the
+  // length to account for the :
+  absl::string_view x = absl::string_view(frame->error_details);
+  x.remove_prefix(ed[0].length() + 1);
+  frame->error_details = std::string(x);
+  frame->quic_error_code = static_cast<QuicErrorCode>(extracted_error_code);
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_framer.h b/quiche/quic/core/quic_framer.h
new file mode 100644
index 0000000..de03169
--- /dev/null
+++ b/quiche/quic/core/quic_framer.h
@@ -0,0 +1,1265 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_FRAMER_H_
+#define QUICHE_QUIC_CORE_QUIC_FRAMER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicFramerPeer;
+}  // namespace test
+
+class QuicDataReader;
+class QuicDataWriter;
+class QuicFramer;
+class QuicStreamFrameDataProducer;
+
+// Number of bytes reserved for the frame type preceding each frame.
+const size_t kQuicFrameTypeSize = 1;
+// Number of bytes reserved for error code.
+const size_t kQuicErrorCodeSize = 4;
+// Number of bytes reserved to denote the length of error details field.
+const size_t kQuicErrorDetailsLengthSize = 2;
+
+// Maximum number of bytes reserved for stream id.
+const size_t kQuicMaxStreamIdSize = 4;
+// Maximum number of bytes reserved for byte offset in stream frame.
+const size_t kQuicMaxStreamOffsetSize = 8;
+// Number of bytes reserved to store payload length in stream frame.
+const size_t kQuicStreamPayloadLengthSize = 2;
+// Number of bytes to reserve for IQ Error codes (for the Connection Close,
+// Application Close, and Reset Stream frames).
+const size_t kQuicIetfQuicErrorCodeSize = 2;
+// Minimum size of the IETF QUIC Error Phrase's length field
+const size_t kIetfQuicMinErrorPhraseLengthSize = 1;
+
+// Size in bytes reserved for the delta time of the largest observed
+// packet number in ack frames.
+const size_t kQuicDeltaTimeLargestObservedSize = 2;
+// Size in bytes reserved for the number of received packets with timestamps.
+const size_t kQuicNumTimestampsSize = 1;
+// Size in bytes reserved for the number of missing packets in ack frames.
+const size_t kNumberOfNackRangesSize = 1;
+// Size in bytes reserved for the number of ack blocks in ack frames.
+const size_t kNumberOfAckBlocksSize = 1;
+// Maximum number of missing packet ranges that can fit within an ack frame.
+const size_t kMaxNackRanges = (1 << (kNumberOfNackRangesSize * 8)) - 1;
+// Maximum number of ack blocks that can fit within an ack frame.
+const size_t kMaxAckBlocks = (1 << (kNumberOfAckBlocksSize * 8)) - 1;
+
+// This class receives callbacks from the framer when packets
+// are processed.
+class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
+ public:
+  virtual ~QuicFramerVisitorInterface() {}
+
+  // Called if an error is detected in the QUIC protocol.
+  virtual void OnError(QuicFramer* framer) = 0;
+
+  // Called only when |perspective_| is IS_SERVER and the framer gets a
+  // packet with version flag true and the version on the packet doesn't match
+  // |quic_version_|. The visitor should return true after it updates the
+  // version of the |framer_| to |received_version| or false to stop processing
+  // this packet.
+  virtual bool OnProtocolVersionMismatch(
+      ParsedQuicVersion received_version) = 0;
+
+  // Called when a new packet has been received, before it
+  // has been validated or processed.
+  virtual void OnPacket() = 0;
+
+  // Called when a public reset packet has been parsed but has not yet
+  // been validated.
+  virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) = 0;
+
+  // Called only when |perspective_| is IS_CLIENT and a version negotiation
+  // packet has been parsed.
+  virtual void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) = 0;
+
+  // Called only when |perspective_| is IS_CLIENT and a retry packet has been
+  // parsed. |new_connection_id| contains the value of the Source Connection
+  // ID field, and |retry_token| contains the value of the Retry Token field.
+  // On versions where UsesTls() is false,
+  // |original_connection_id| contains the value of the Original Destination
+  // Connection ID field, and both |retry_integrity_tag| and
+  // |retry_without_tag| are empty.
+  // On versions where UsesTls() is true,
+  // |original_connection_id| is empty, |retry_integrity_tag| contains the
+  // value of the Retry Integrity Tag field, and |retry_without_tag| contains
+  // the entire RETRY packet except the Retry Integrity Tag field.
+  virtual void OnRetryPacket(QuicConnectionId original_connection_id,
+                             QuicConnectionId new_connection_id,
+                             absl::string_view retry_token,
+                             absl::string_view retry_integrity_tag,
+                             absl::string_view retry_without_tag) = 0;
+
+  // Called when all fields except packet number has been parsed, but has not
+  // been authenticated. If it returns false, framing for this packet will
+  // cease.
+  virtual bool OnUnauthenticatedPublicHeader(
+      const QuicPacketHeader& header) = 0;
+
+  // Called when the unauthenticated portion of the header has been parsed.
+  // If OnUnauthenticatedHeader returns false, framing for this packet will
+  // cease.
+  virtual bool OnUnauthenticatedHeader(const QuicPacketHeader& header) = 0;
+
+  // Called when a packet has been decrypted. |length| is the packet length,
+  // and |level| is the encryption level of the packet.
+  virtual void OnDecryptedPacket(size_t length, EncryptionLevel level) = 0;
+
+  // Called when the complete header of a packet had been parsed.
+  // If OnPacketHeader returns false, framing for this packet will cease.
+  virtual bool OnPacketHeader(const QuicPacketHeader& header) = 0;
+
+  // Called when the packet being processed contains multiple IETF QUIC packets,
+  // which is due to there being more data after what is covered by the length
+  // field. |packet| contains the remaining data which can be processed.
+  // Note that this is called when the framer parses the length field, before
+  // it attempts to decrypt the first payload. It is the visitor's
+  // responsibility to buffer the packet and call ProcessPacket on it
+  // after the framer is done parsing the current payload. |packet| does not
+  // own its internal buffer, the visitor should make a copy of it.
+  virtual void OnCoalescedPacket(const QuicEncryptedPacket& packet) = 0;
+
+  // Called when the packet being processed failed to decrypt.
+  // |has_decryption_key| indicates whether the framer knew which decryption
+  // key to use for this packet and already had a suitable key.
+  virtual void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                                     EncryptionLevel decryption_level,
+                                     bool has_decryption_key) = 0;
+
+  // Called when a StreamFrame has been parsed.
+  virtual bool OnStreamFrame(const QuicStreamFrame& frame) = 0;
+
+  // Called when a CRYPTO frame has been parsed.
+  virtual bool OnCryptoFrame(const QuicCryptoFrame& frame) = 0;
+
+  // Called when largest acked of an AckFrame has been parsed.
+  virtual bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                               QuicTime::Delta ack_delay_time) = 0;
+
+  // Called when ack range [start, end) of an AckFrame has been parsed.
+  virtual bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) = 0;
+
+  // Called when a timestamp in the AckFrame has been parsed.
+  virtual bool OnAckTimestamp(QuicPacketNumber packet_number,
+                              QuicTime timestamp) = 0;
+
+  // Called after the last ack range in an AckFrame has been parsed.
+  // |start| is the starting value of the last ack range.
+  virtual bool OnAckFrameEnd(QuicPacketNumber start) = 0;
+
+  // Called when a StopWaitingFrame has been parsed.
+  virtual bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) = 0;
+
+  // Called when a QuicPaddingFrame has been parsed.
+  virtual bool OnPaddingFrame(const QuicPaddingFrame& frame) = 0;
+
+  // Called when a PingFrame has been parsed.
+  virtual bool OnPingFrame(const QuicPingFrame& frame) = 0;
+
+  // Called when a RstStreamFrame has been parsed.
+  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) = 0;
+
+  // Called when a ConnectionCloseFrame, of any type, has been parsed.
+  virtual bool OnConnectionCloseFrame(
+      const QuicConnectionCloseFrame& frame) = 0;
+
+  // Called when a StopSendingFrame has been parsed.
+  virtual bool OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
+
+  // Called when a PathChallengeFrame has been parsed.
+  virtual bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) = 0;
+
+  // Called when a PathResponseFrame has been parsed.
+  virtual bool OnPathResponseFrame(const QuicPathResponseFrame& frame) = 0;
+
+  // Called when a GoAwayFrame has been parsed.
+  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) = 0;
+
+  // Called when a WindowUpdateFrame has been parsed.
+  virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) = 0;
+
+  // Called when a BlockedFrame has been parsed.
+  virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) = 0;
+
+  // Called when a NewConnectionIdFrame has been parsed.
+  virtual bool OnNewConnectionIdFrame(
+      const QuicNewConnectionIdFrame& frame) = 0;
+
+  // Called when a RetireConnectionIdFrame has been parsed.
+  virtual bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) = 0;
+
+  // Called when a NewTokenFrame has been parsed.
+  virtual bool OnNewTokenFrame(const QuicNewTokenFrame& frame) = 0;
+
+  // Called when a message frame has been parsed.
+  virtual bool OnMessageFrame(const QuicMessageFrame& frame) = 0;
+
+  // Called when a handshake done frame has been parsed.
+  virtual bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) = 0;
+
+  // Called when an AckFrequencyFrame has been parsed.
+  virtual bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) = 0;
+
+  // Called when a packet has been completely processed.
+  virtual void OnPacketComplete() = 0;
+
+  // Called to check whether |token| is a valid stateless reset token.
+  virtual bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const = 0;
+
+  // Called when an IETF stateless reset packet has been parsed and validated
+  // with the stateless reset token.
+  virtual void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) = 0;
+
+  // Called when an IETF MaxStreams frame has been parsed.
+  virtual bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) = 0;
+
+  // Called when an IETF StreamsBlocked frame has been parsed.
+  virtual bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) = 0;
+
+  // Called when a Key Phase Update has been initiated. This is called for both
+  // locally and peer initiated key updates. If the key update was locally
+  // initiated, this does not indicate the peer has received the key update yet.
+  virtual void OnKeyUpdate(KeyUpdateReason reason) = 0;
+
+  // Called on the first decrypted packet in each key phase (including the
+  // first key phase.)
+  virtual void OnDecryptedFirstPacketInKeyPhase() = 0;
+
+  // Called when the framer needs to generate a decrypter for the next key
+  // phase. Each call should generate the key for phase n+1.
+  virtual std::unique_ptr<QuicDecrypter>
+  AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
+
+  // Called when the framer needs to generate an encrypter. The key corresponds
+  // to the key phase of the last decrypter returned by
+  // AdvanceKeysAndCreateCurrentOneRttDecrypter().
+  virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
+};
+
+// Class for parsing and constructing QUIC packets.  It has a
+// QuicFramerVisitorInterface that is called when packets are parsed.
+class QUIC_EXPORT_PRIVATE QuicFramer {
+ public:
+  // Constructs a new framer that installs a kNULL QuicEncrypter and
+  // QuicDecrypter for level ENCRYPTION_INITIAL. |supported_versions| specifies
+  // the list of supported QUIC versions. |quic_version_| is set to the maximum
+  // version in |supported_versions|.
+  QuicFramer(const ParsedQuicVersionVector& supported_versions,
+             QuicTime creation_time,
+             Perspective perspective,
+             uint8_t expected_server_connection_id_length);
+  QuicFramer(const QuicFramer&) = delete;
+  QuicFramer& operator=(const QuicFramer&) = delete;
+
+  virtual ~QuicFramer();
+
+  // Returns true if |version| is a supported transport version.
+  bool IsSupportedTransportVersion(const QuicTransportVersion version) const;
+
+  // Returns true if |version| is a supported protocol version.
+  bool IsSupportedVersion(const ParsedQuicVersion version) const;
+
+  // Set callbacks to be called from the framer.  A visitor must be set, or
+  // else the framer will likely crash.  It is acceptable for the visitor
+  // to do nothing.  If this is called multiple times, only the last visitor
+  // will be used.
+  void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; }
+
+  const ParsedQuicVersionVector& supported_versions() const {
+    return supported_versions_;
+  }
+
+  QuicTransportVersion transport_version() const {
+    return version_.transport_version;
+  }
+
+  ParsedQuicVersion version() const { return version_; }
+
+  void set_version(const ParsedQuicVersion version);
+
+  // Does not QUICHE_DCHECK for supported version. Used by tests to set
+  // unsupported version to trigger version negotiation.
+  void set_version_for_tests(const ParsedQuicVersion version) {
+    version_ = version;
+  }
+
+  QuicErrorCode error() const { return error_; }
+
+  // Allows enabling or disabling of timestamp processing and serialization.
+  // TODO(ianswett): Remove the const once timestamps are negotiated via
+  // transport params.
+  void set_process_timestamps(bool process_timestamps) const {
+    process_timestamps_ = process_timestamps;
+  }
+
+  // Sets the max number of receive timestamps to send per ACK frame.
+  // TODO(wub): Remove the const once timestamps are negotiated via
+  // transport params.
+  void set_max_receive_timestamps_per_ack(uint32_t max_timestamps) const {
+    max_receive_timestamps_per_ack_ = max_timestamps;
+  }
+
+  // Sets the exponent to use when writing/reading ACK receive timestamps.
+  void set_receive_timestamps_exponent(uint32_t exponent) const {
+    receive_timestamps_exponent_ = exponent;
+  }
+
+  // Pass a UDP packet into the framer for parsing.
+  // Return true if the packet was processed successfully. |packet| must be a
+  // single, complete UDP packet (not a frame of a packet).  This packet
+  // might be null padded past the end of the payload, which will be correctly
+  // ignored.
+  bool ProcessPacket(const QuicEncryptedPacket& packet);
+
+  // Whether we are in the middle of a call to this->ProcessPacket.
+  bool is_processing_packet() const { return is_processing_packet_; }
+
+  // Largest size in bytes of all stream frame fields without the payload.
+  static size_t GetMinStreamFrameSize(QuicTransportVersion version,
+                                      QuicStreamId stream_id,
+                                      QuicStreamOffset offset,
+                                      bool last_frame_in_packet,
+                                      size_t data_length);
+  // Returns the overhead of framing a CRYPTO frame with the specific offset and
+  // data length provided, but not counting the size of the data payload.
+  static size_t GetMinCryptoFrameSize(QuicStreamOffset offset,
+                                      QuicPacketLength data_length);
+  static size_t GetMessageFrameSize(QuicTransportVersion version,
+                                    bool last_frame_in_packet,
+                                    QuicByteCount length);
+  // Size in bytes of all ack frame fields without the missing packets or ack
+  // blocks.
+  static size_t GetMinAckFrameSize(QuicTransportVersion version,
+                                   const QuicAckFrame& ack_frame,
+                                   uint32_t local_ack_delay_exponent,
+                                   bool use_ietf_ack_with_receive_timestamp);
+  // Size in bytes of a stop waiting frame.
+  static size_t GetStopWaitingFrameSize(
+      QuicPacketNumberLength packet_number_length);
+  // Size in bytes of all reset stream frame fields.
+  static size_t GetRstStreamFrameSize(QuicTransportVersion version,
+                                      const QuicRstStreamFrame& frame);
+  // Size in bytes of all ack frenquency frame fields.
+  static size_t GetAckFrequencyFrameSize(const QuicAckFrequencyFrame& frame);
+  // Size in bytes of all connection close frame fields, including the error
+  // details.
+  static size_t GetConnectionCloseFrameSize(
+      QuicTransportVersion version,
+      const QuicConnectionCloseFrame& frame);
+  // Size in bytes of all GoAway frame fields without the reason phrase.
+  static size_t GetMinGoAwayFrameSize();
+  // Size in bytes of all WindowUpdate frame fields.
+  // For version 99, determines whether a MAX DATA or MAX STREAM DATA frame will
+  // be generated and calculates the appropriate size.
+  static size_t GetWindowUpdateFrameSize(QuicTransportVersion version,
+                                         const QuicWindowUpdateFrame& frame);
+  // Size in bytes of all MaxStreams frame fields.
+  static size_t GetMaxStreamsFrameSize(QuicTransportVersion version,
+                                       const QuicMaxStreamsFrame& frame);
+  // Size in bytes of all StreamsBlocked frame fields.
+  static size_t GetStreamsBlockedFrameSize(
+      QuicTransportVersion version,
+      const QuicStreamsBlockedFrame& frame);
+  // Size in bytes of all Blocked frame fields.
+  static size_t GetBlockedFrameSize(QuicTransportVersion version,
+                                    const QuicBlockedFrame& frame);
+  // Size in bytes of PathChallenge frame.
+  static size_t GetPathChallengeFrameSize(const QuicPathChallengeFrame& frame);
+  // Size in bytes of PathResponse frame.
+  static size_t GetPathResponseFrameSize(const QuicPathResponseFrame& frame);
+  // Size in bytes required to serialize the stream id.
+  static size_t GetStreamIdSize(QuicStreamId stream_id);
+  // Size in bytes required to serialize the stream offset.
+  static size_t GetStreamOffsetSize(QuicStreamOffset offset);
+  // Size in bytes for a serialized new connection id frame
+  static size_t GetNewConnectionIdFrameSize(
+      const QuicNewConnectionIdFrame& frame);
+
+  // Size in bytes for a serialized retire connection id frame
+  static size_t GetRetireConnectionIdFrameSize(
+      const QuicRetireConnectionIdFrame& frame);
+
+  // Size in bytes for a serialized new token frame
+  static size_t GetNewTokenFrameSize(const QuicNewTokenFrame& frame);
+
+  // Size in bytes required for a serialized stop sending frame.
+  static size_t GetStopSendingFrameSize(const QuicStopSendingFrame& frame);
+
+  // Size in bytes required for a serialized retransmittable control |frame|.
+  static size_t GetRetransmittableControlFrameSize(QuicTransportVersion version,
+                                                   const QuicFrame& frame);
+
+  // Returns the number of bytes added to the packet for the specified frame,
+  // and 0 if the frame doesn't fit.  Includes the header size for the first
+  // frame.
+  size_t GetSerializedFrameLength(const QuicFrame& frame,
+                                  size_t free_bytes,
+                                  bool first_frame_in_packet,
+                                  bool last_frame_in_packet,
+                                  QuicPacketNumberLength packet_number_length);
+
+  // Returns the associated data from the encrypted packet |encrypted| as a
+  // stringpiece.
+  static absl::string_view GetAssociatedDataFromEncryptedPacket(
+      QuicTransportVersion version,
+      const QuicEncryptedPacket& encrypted,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length,
+      bool includes_version,
+      bool includes_diversification_nonce,
+      QuicPacketNumberLength packet_number_length,
+      QuicVariableLengthIntegerLength retry_token_length_length,
+      uint64_t retry_token_length,
+      QuicVariableLengthIntegerLength length_length);
+
+  // Parses the unencrypted fields in a QUIC header using |reader| as input,
+  // stores the result in the other parameters.
+  // |expected_destination_connection_id_length| is only used for short headers.
+  static QuicErrorCode ParsePublicHeader(
+      QuicDataReader* reader,
+      uint8_t expected_destination_connection_id_length,
+      bool ietf_format,
+      uint8_t* first_byte,
+      PacketHeaderFormat* format,
+      bool* version_present,
+      bool* has_length_prefix,
+      QuicVersionLabel* version_label,
+      ParsedQuicVersion* parsed_version,
+      QuicConnectionId* destination_connection_id,
+      QuicConnectionId* source_connection_id,
+      QuicLongHeaderType* long_packet_type,
+      QuicVariableLengthIntegerLength* retry_token_length_length,
+      absl::string_view* retry_token,
+      std::string* detailed_error);
+
+  // Parses the unencrypted fields in |packet| and stores them in the other
+  // parameters. This can only be called on the server.
+  // |expected_destination_connection_id_length| is only used for short headers.
+  static QuicErrorCode ParsePublicHeaderDispatcher(
+      const QuicEncryptedPacket& packet,
+      uint8_t expected_destination_connection_id_length,
+      PacketHeaderFormat* format, QuicLongHeaderType* long_packet_type,
+      bool* version_present, bool* has_length_prefix,
+      QuicVersionLabel* version_label, ParsedQuicVersion* parsed_version,
+      QuicConnectionId* destination_connection_id,
+      QuicConnectionId* source_connection_id,
+      absl::optional<absl::string_view>* retry_token,
+      std::string* detailed_error);
+
+  // Serializes a packet containing |frames| into |buffer|.
+  // Returns the length of the packet, which must not be longer than
+  // |packet_length|.  Returns 0 if it fails to serialize.
+  size_t BuildDataPacket(const QuicPacketHeader& header,
+                         const QuicFrames& frames,
+                         char* buffer,
+                         size_t packet_length,
+                         EncryptionLevel level);
+
+  // Returns a new public reset packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildPublicResetPacket(
+      const QuicPublicResetPacket& packet);
+
+  // Returns the minimal stateless reset packet length.
+  static size_t GetMinStatelessResetPacketLength();
+
+  // Returns a new IETF stateless reset packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
+      QuicConnectionId connection_id,
+      size_t received_packet_length,
+      StatelessResetToken stateless_reset_token);
+
+  // Returns a new version negotiation packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
+      QuicConnectionId server_connection_id,
+      QuicConnectionId client_connection_id,
+      bool ietf_quic,
+      bool use_length_prefix,
+      const ParsedQuicVersionVector& versions);
+
+  // Returns a new IETF version negotiation packet.
+  static std::unique_ptr<QuicEncryptedPacket> BuildIetfVersionNegotiationPacket(
+      bool use_length_prefix,
+      QuicConnectionId server_connection_id,
+      QuicConnectionId client_connection_id,
+      const ParsedQuicVersionVector& versions);
+
+  // If header.version_flag is set, the version in the
+  // packet will be set -- but it will be set from version_ not
+  // header.versions.
+  bool AppendPacketHeader(const QuicPacketHeader& header,
+                          QuicDataWriter* writer,
+                          size_t* length_field_offset);
+  bool AppendIetfHeaderTypeByte(const QuicPacketHeader& header,
+                                QuicDataWriter* writer);
+  bool AppendIetfPacketHeader(const QuicPacketHeader& header,
+                              QuicDataWriter* writer,
+                              size_t* length_field_offset);
+  bool WriteIetfLongHeaderLength(const QuicPacketHeader& header,
+                                 QuicDataWriter* writer,
+                                 size_t length_field_offset,
+                                 EncryptionLevel level);
+  bool AppendTypeByte(const QuicFrame& frame,
+                      bool last_frame_in_packet,
+                      QuicDataWriter* writer);
+  bool AppendIetfFrameType(const QuicFrame& frame,
+                           bool last_frame_in_packet,
+                           QuicDataWriter* writer);
+  size_t AppendIetfFrames(const QuicFrames& frames, QuicDataWriter* writer);
+  bool AppendStreamFrame(const QuicStreamFrame& frame,
+                         bool no_stream_frame_length, QuicDataWriter* writer);
+  bool AppendCryptoFrame(const QuicCryptoFrame& frame, QuicDataWriter* writer);
+  bool AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+                               QuicDataWriter* writer);
+
+  // SetDecrypter sets the primary decrypter, replacing any that already exists.
+  // If an alternative decrypter is in place then the function QUICHE_DCHECKs.
+  // This is intended for cases where one knows that future packets will be
+  // using the new decrypter and the previous decrypter is now obsolete. |level|
+  // indicates the encryption level of the new decrypter.
+  void SetDecrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicDecrypter> decrypter);
+
+  // SetAlternativeDecrypter sets a decrypter that may be used to decrypt
+  // future packets. |level| indicates the encryption level of the decrypter. If
+  // |latch_once_used| is true, then the first time that the decrypter is
+  // successful it will replace the primary decrypter.  Otherwise both
+  // decrypters will remain active and the primary decrypter will be the one
+  // last used.
+  void SetAlternativeDecrypter(EncryptionLevel level,
+                               std::unique_ptr<QuicDecrypter> decrypter,
+                               bool latch_once_used);
+
+  void InstallDecrypter(EncryptionLevel level,
+                        std::unique_ptr<QuicDecrypter> decrypter);
+  void RemoveDecrypter(EncryptionLevel level);
+
+  // Enables key update support.
+  void SetKeyUpdateSupportForConnection(bool enabled);
+  // Discard the decrypter for the previous key phase.
+  void DiscardPreviousOneRttKeys();
+  // Update the key phase.
+  bool DoKeyUpdate(KeyUpdateReason reason);
+  // Returns the count of packets received that appeared to attempt a key
+  // update but failed decryption which have been received since the last
+  // successfully decrypted packet.
+  QuicPacketCount PotentialPeerKeyUpdateAttemptCount() const;
+
+  const QuicDecrypter* GetDecrypter(EncryptionLevel level) const;
+  const QuicDecrypter* decrypter() const;
+  const QuicDecrypter* alternative_decrypter() const;
+
+  // Changes the encrypter used for level |level| to |encrypter|.
+  void SetEncrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicEncrypter> encrypter);
+
+  // Called to remove encrypter of encryption |level|.
+  void RemoveEncrypter(EncryptionLevel level);
+
+  // Sets the encrypter and decrypter for the ENCRYPTION_INITIAL level.
+  void SetInitialObfuscators(QuicConnectionId connection_id);
+
+  // Encrypts a payload in |buffer|.  |ad_len| is the length of the associated
+  // data. |total_len| is the length of the associated data plus plaintext.
+  // |buffer_len| is the full length of the allocated buffer.
+  size_t EncryptInPlace(EncryptionLevel level,
+                        QuicPacketNumber packet_number,
+                        size_t ad_len,
+                        size_t total_len,
+                        size_t buffer_len,
+                        char* buffer);
+
+  // Returns the length of the data encrypted into |buffer| if |buffer_len| is
+  // long enough, and otherwise 0.
+  size_t EncryptPayload(EncryptionLevel level,
+                        QuicPacketNumber packet_number,
+                        const QuicPacket& packet,
+                        char* buffer,
+                        size_t buffer_len);
+
+  // Returns the length of the ciphertext that would be generated by encrypting
+  // to plaintext of size |plaintext_size| at the given level.
+  size_t GetCiphertextSize(EncryptionLevel level, size_t plaintext_size) const;
+
+  // Returns the maximum length of plaintext that can be encrypted
+  // to ciphertext no larger than |ciphertext_size|.
+  size_t GetMaxPlaintextSize(size_t ciphertext_size);
+
+  // Returns the maximum number of packets that can be safely encrypted with
+  // the active AEAD. 1-RTT keys must be set before calling this method.
+  QuicPacketCount GetOneRttEncrypterConfidentialityLimit() const;
+
+  const std::string& detailed_error() { return detailed_error_; }
+
+  // The minimum packet number length required to represent |packet_number|.
+  static QuicPacketNumberLength GetMinPacketNumberLength(
+      QuicPacketNumber packet_number);
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    supported_versions_ = versions;
+    version_ = versions[0];
+  }
+
+  // Tell framer to infer packet header type from version_.
+  void InferPacketHeaderTypeFromVersion();
+
+  // Returns true if |header| is considered as an stateless reset packet.
+  bool IsIetfStatelessResetPacket(const QuicPacketHeader& header) const;
+
+  // Returns true if encrypter of |level| is available.
+  bool HasEncrypterOfEncryptionLevel(EncryptionLevel level) const;
+  // Returns true if decrypter of |level| is available.
+  bool HasDecrypterOfEncryptionLevel(EncryptionLevel level) const;
+
+  // Returns true if an encrypter of |space| is available.
+  bool HasAnEncrypterForSpace(PacketNumberSpace space) const;
+
+  // Returns the encryption level to send application data. This should be only
+  // called with available encrypter for application data.
+  EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
+
+  void set_validate_flags(bool value) { validate_flags_ = value; }
+
+  Perspective perspective() const { return perspective_; }
+
+  QuicStreamFrameDataProducer* data_producer() const { return data_producer_; }
+
+  void set_data_producer(QuicStreamFrameDataProducer* data_producer) {
+    data_producer_ = data_producer;
+  }
+
+  QuicTime creation_time() const { return creation_time_; }
+
+  QuicPacketNumber first_sending_packet_number() const {
+    return first_sending_packet_number_;
+  }
+
+  uint64_t current_received_frame_type() const {
+    return current_received_frame_type_;
+  }
+
+  uint64_t previously_received_frame_type() const {
+    return previously_received_frame_type_;
+  }
+
+  // The connection ID length the framer expects on incoming IETF short headers
+  // on the server.
+  uint8_t GetExpectedServerConnectionIdLength() {
+    return expected_server_connection_id_length_;
+  }
+
+  // Change the expected destination connection ID length for short headers on
+  // the client.
+  void SetExpectedClientConnectionIdLength(
+      uint8_t expected_client_connection_id_length) {
+    expected_client_connection_id_length_ =
+        expected_client_connection_id_length;
+  }
+
+  void EnableMultiplePacketNumberSpacesSupport();
+
+  // Writes an array of bytes that, if sent as a UDP datagram, will trigger
+  // IETF QUIC Version Negotiation on servers. The bytes will be written to
+  // |packet_bytes|, which must point to |packet_length| bytes of memory.
+  // |packet_length| must be in the range [1200, 65535].
+  // |destination_connection_id_bytes| will be sent as the destination
+  // connection ID, and must point to |destination_connection_id_length| bytes
+  // of memory. |destination_connection_id_length| must be in the range [8,18].
+  // When targeting Google servers, it is recommended to use a
+  // |destination_connection_id_length| of 8.
+  static bool WriteClientVersionNegotiationProbePacket(
+      char* packet_bytes,
+      QuicByteCount packet_length,
+      const char* destination_connection_id_bytes,
+      uint8_t destination_connection_id_length);
+
+  // Parses a packet which a QUIC server sent in response to a packet sent by
+  // WriteClientVersionNegotiationProbePacket. |packet_bytes| must point to
+  // |packet_length| bytes in memory which represent the response.
+  // |packet_length| must be greater or equal to 6. This method will fill in
+  // |source_connection_id_bytes| which must point to at least
+  // |*source_connection_id_length_out| bytes in memory.
+  // |*source_connection_id_length_out| must be at least 18.
+  // |*source_connection_id_length_out| will contain the length of the received
+  // source connection ID, which on success will match the contents of the
+  // destination connection ID passed in to
+  // WriteClientVersionNegotiationProbePacket. In the case of a failure,
+  // |detailed_error| will be filled in with an explanation of what failed.
+  static bool ParseServerVersionNegotiationProbeResponse(
+      const char* packet_bytes,
+      QuicByteCount packet_length,
+      char* source_connection_id_bytes,
+      uint8_t* source_connection_id_length_out,
+      std::string* detailed_error);
+
+  void set_local_ack_delay_exponent(uint32_t exponent) {
+    local_ack_delay_exponent_ = exponent;
+  }
+  uint32_t local_ack_delay_exponent() const {
+    return local_ack_delay_exponent_;
+  }
+
+  void set_peer_ack_delay_exponent(uint32_t exponent) {
+    peer_ack_delay_exponent_ = exponent;
+  }
+  uint32_t peer_ack_delay_exponent() const { return peer_ack_delay_exponent_; }
+
+  void set_drop_incoming_retry_packets(bool drop_incoming_retry_packets) {
+    drop_incoming_retry_packets_ = drop_incoming_retry_packets;
+  }
+
+ private:
+  friend class test::QuicFramerPeer;
+
+  using NackRangeMap = std::map<QuicPacketNumber, uint8_t>;
+
+  // AckTimestampRange is a data structure derived from a QuicAckFrame. It is
+  // used to serialize timestamps in a IETF_ACK_RECEIVE_TIMESTAMPS frame.
+  struct QUIC_EXPORT_PRIVATE AckTimestampRange {
+    QuicPacketCount gap;
+    // |range_begin| and |range_end| are index(es) in
+    // QuicAckFrame.received_packet_times, representing a continuous range of
+    // packet numbers in descending order. |range_begin| >= |range_end|.
+    int64_t range_begin;  // Inclusive
+    int64_t range_end;    // Inclusive
+  };
+  absl::InlinedVector<AckTimestampRange, 2> GetAckTimestampRanges(
+      const QuicAckFrame& frame, std::string& detailed_error) const;
+  int64_t FrameAckTimestampRanges(
+      const QuicAckFrame& frame,
+      const absl::InlinedVector<AckTimestampRange, 2>& timestamp_ranges,
+      QuicDataWriter* writer) const;
+
+  struct QUIC_EXPORT_PRIVATE AckFrameInfo {
+    AckFrameInfo();
+    AckFrameInfo(const AckFrameInfo& other);
+    ~AckFrameInfo();
+
+    // The maximum ack block length.
+    QuicPacketCount max_block_length;
+    // Length of first ack block.
+    QuicPacketCount first_block_length;
+    // Number of ACK blocks needed for the ACK frame.
+    size_t num_ack_blocks;
+  };
+
+  // Applies header protection to an IETF QUIC packet header in |buffer| using
+  // the encrypter for level |level|. The buffer has |buffer_len| bytes of data,
+  // with the first protected packet bytes starting at |ad_len|.
+  bool ApplyHeaderProtection(EncryptionLevel level,
+                             char* buffer,
+                             size_t buffer_len,
+                             size_t ad_len);
+
+  // Removes header protection from an IETF QUIC packet header.
+  //
+  // The packet number from the header is read from |reader|, where the packet
+  // number is the next contents in |reader|. |reader| is only advanced by the
+  // length of the packet number, but it is also used to peek the sample needed
+  // for removing header protection.
+  //
+  // Properties needed for removing header protection are read from |header|.
+  // The packet number length and type byte are written to |header|.
+  //
+  // The packet number, after removing header protection and decoding it, is
+  // written to |full_packet_number|. Finally, the header, with header
+  // protection removed, is written to |associated_data| to be used in packet
+  // decryption. |packet| is used in computing the asociated data.
+  bool RemoveHeaderProtection(QuicDataReader* reader,
+                              const QuicEncryptedPacket& packet,
+                              QuicPacketHeader* header,
+                              uint64_t* full_packet_number,
+                              std::vector<char>* associated_data);
+
+  bool ProcessDataPacket(QuicDataReader* reader,
+                         QuicPacketHeader* header,
+                         const QuicEncryptedPacket& packet,
+                         char* decrypted_buffer,
+                         size_t buffer_length);
+
+  bool ProcessIetfDataPacket(QuicDataReader* encrypted_reader,
+                             QuicPacketHeader* header,
+                             const QuicEncryptedPacket& packet,
+                             char* decrypted_buffer,
+                             size_t buffer_length);
+
+  bool ProcessPublicResetPacket(QuicDataReader* reader,
+                                const QuicPacketHeader& header);
+
+  bool ProcessVersionNegotiationPacket(QuicDataReader* reader,
+                                       const QuicPacketHeader& header);
+
+  bool ProcessRetryPacket(QuicDataReader* reader,
+                          const QuicPacketHeader& header);
+
+  void MaybeProcessCoalescedPacket(const QuicDataReader& encrypted_reader,
+                                   uint64_t remaining_bytes_length,
+                                   const QuicPacketHeader& header);
+
+  bool MaybeProcessIetfLength(QuicDataReader* encrypted_reader,
+                              QuicPacketHeader* header);
+
+  bool ProcessPublicHeader(QuicDataReader* reader,
+                           bool packet_has_ietf_packet_header,
+                           QuicPacketHeader* header);
+
+  // Processes the unauthenticated portion of the header into |header| from
+  // the current QuicDataReader.  Returns true on success, false on failure.
+  bool ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
+                                    QuicPacketHeader* header);
+
+  // Processes the version label in the packet header.
+  static bool ProcessVersionLabel(QuicDataReader* reader,
+                                  QuicVersionLabel* version_label);
+
+  // Validates and updates |destination_connection_id_length| and
+  // |source_connection_id_length|. When
+  // |should_update_expected_server_connection_id_length| is true, length
+  // validation is disabled and |expected_server_connection_id_length| is set
+  // to the appropriate length.
+  // TODO(b/133873272) refactor this method.
+  static bool ProcessAndValidateIetfConnectionIdLength(
+      QuicDataReader* reader,
+      ParsedQuicVersion version,
+      Perspective perspective,
+      bool should_update_expected_server_connection_id_length,
+      uint8_t* expected_server_connection_id_length,
+      uint8_t* destination_connection_id_length,
+      uint8_t* source_connection_id_length,
+      std::string* detailed_error);
+
+  bool ProcessIetfHeaderTypeByte(QuicDataReader* reader,
+                                 QuicPacketHeader* header);
+  bool ProcessIetfPacketHeader(QuicDataReader* reader,
+                               QuicPacketHeader* header);
+
+  // First processes possibly truncated packet number. Calculates the full
+  // packet number from the truncated one and the last seen packet number, and
+  // stores it to |packet_number|.
+  bool ProcessAndCalculatePacketNumber(
+      QuicDataReader* reader,
+      QuicPacketNumberLength packet_number_length,
+      QuicPacketNumber base_packet_number,
+      uint64_t* packet_number);
+  bool ProcessFrameData(QuicDataReader* reader, const QuicPacketHeader& header);
+
+  static bool IsIetfFrameTypeExpectedForEncryptionLevel(uint64_t frame_type,
+                                                        EncryptionLevel level);
+
+  bool ProcessIetfFrameData(QuicDataReader* reader,
+                            const QuicPacketHeader& header,
+                            EncryptionLevel decrypted_level);
+  bool ProcessStreamFrame(QuicDataReader* reader,
+                          uint8_t frame_type,
+                          QuicStreamFrame* frame);
+  bool ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type);
+  bool ProcessTimestampsInAckFrame(uint8_t num_received_packets,
+                                   QuicPacketNumber largest_acked,
+                                   QuicDataReader* reader);
+  bool ProcessIetfAckFrame(QuicDataReader* reader,
+                           uint64_t frame_type,
+                           QuicAckFrame* ack_frame);
+  bool ProcessIetfTimestampsInAckFrame(QuicPacketNumber largest_acked,
+                                       QuicDataReader* reader);
+  bool ProcessStopWaitingFrame(QuicDataReader* reader,
+                               const QuicPacketHeader& header,
+                               QuicStopWaitingFrame* stop_waiting);
+  bool ProcessRstStreamFrame(QuicDataReader* reader, QuicRstStreamFrame* frame);
+  bool ProcessConnectionCloseFrame(QuicDataReader* reader,
+                                   QuicConnectionCloseFrame* frame);
+  bool ProcessGoAwayFrame(QuicDataReader* reader, QuicGoAwayFrame* frame);
+  bool ProcessWindowUpdateFrame(QuicDataReader* reader,
+                                QuicWindowUpdateFrame* frame);
+  bool ProcessBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
+  void ProcessPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame);
+  bool ProcessMessageFrame(QuicDataReader* reader,
+                           bool no_message_length,
+                           QuicMessageFrame* frame);
+
+  bool DecryptPayload(size_t udp_packet_length,
+                      absl::string_view encrypted,
+                      absl::string_view associated_data,
+                      const QuicPacketHeader& header,
+                      char* decrypted_buffer,
+                      size_t buffer_length,
+                      size_t* decrypted_length,
+                      EncryptionLevel* decrypted_level);
+
+  // Returns the full packet number from the truncated
+  // wire format version and the last seen packet number.
+  uint64_t CalculatePacketNumberFromWire(
+      QuicPacketNumberLength packet_number_length,
+      QuicPacketNumber base_packet_number,
+      uint64_t packet_number) const;
+
+  // Returns the QuicTime::Delta corresponding to the time from when the framer
+  // was created.
+  const QuicTime::Delta CalculateTimestampFromWire(uint32_t time_delta_us);
+
+  // Computes the wire size in bytes of time stamps in |ack|.
+  size_t GetAckFrameTimeStampSize(const QuicAckFrame& ack);
+  size_t GetIetfAckFrameTimestampSize(const QuicAckFrame& ack);
+
+  // Computes the wire size in bytes of the |ack| frame.
+  size_t GetAckFrameSize(const QuicAckFrame& ack,
+                         QuicPacketNumberLength packet_number_length);
+  // Computes the wire-size, in bytes, of the |frame| ack frame, for IETF Quic.
+  size_t GetIetfAckFrameSize(const QuicAckFrame& frame);
+
+  // Computes the wire size in bytes of the |ack| frame.
+  size_t GetAckFrameSize(const QuicAckFrame& ack);
+
+  // Computes the wire size in bytes of the payload of |frame|.
+  size_t ComputeFrameLength(const QuicFrame& frame,
+                            bool last_frame_in_packet,
+                            QuicPacketNumberLength packet_number_length);
+
+  static bool AppendPacketNumber(QuicPacketNumberLength packet_number_length,
+                                 QuicPacketNumber packet_number,
+                                 QuicDataWriter* writer);
+  static bool AppendStreamId(size_t stream_id_length,
+                             QuicStreamId stream_id,
+                             QuicDataWriter* writer);
+  static bool AppendStreamOffset(size_t offset_length,
+                                 QuicStreamOffset offset,
+                                 QuicDataWriter* writer);
+
+  // Appends a single ACK block to |writer| and returns true if the block was
+  // successfully appended.
+  static bool AppendAckBlock(uint8_t gap,
+                             QuicPacketNumberLength length_length,
+                             uint64_t length,
+                             QuicDataWriter* writer);
+
+  static uint8_t GetPacketNumberFlags(
+      QuicPacketNumberLength packet_number_length);
+
+  static AckFrameInfo GetAckFrameInfo(const QuicAckFrame& frame);
+
+  static QuicErrorCode ParsePublicHeaderGoogleQuic(
+      QuicDataReader* reader,
+      uint8_t* first_byte,
+      PacketHeaderFormat* format,
+      bool* version_present,
+      QuicVersionLabel* version_label,
+      ParsedQuicVersion* parsed_version,
+      QuicConnectionId* destination_connection_id,
+      std::string* detailed_error);
+
+  bool ValidateReceivedConnectionIds(const QuicPacketHeader& header);
+
+  // The Append* methods attempt to write the provided header or frame using the
+  // |writer|, and return true if successful.
+
+  bool AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                 QuicDataWriter* writer);
+  bool AppendTimestampsToAckFrame(const QuicAckFrame& frame,
+                                  QuicDataWriter* writer);
+
+  // Append IETF format ACK frame.
+  //
+  // AppendIetfAckFrameAndTypeByte adds the IETF type byte and the body
+  // of the frame.
+  bool AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
+                                     QuicDataWriter* writer);
+  bool AppendIetfTimestampsToAckFrame(const QuicAckFrame& frame,
+                                      QuicDataWriter* writer);
+
+  bool AppendStopWaitingFrame(const QuicPacketHeader& header,
+                              const QuicStopWaitingFrame& frame,
+                              QuicDataWriter* writer);
+  bool AppendRstStreamFrame(const QuicRstStreamFrame& frame,
+                            QuicDataWriter* writer);
+  bool AppendConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+                                  QuicDataWriter* writer);
+  bool AppendGoAwayFrame(const QuicGoAwayFrame& frame, QuicDataWriter* writer);
+  bool AppendWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                               QuicDataWriter* writer);
+  bool AppendBlockedFrame(const QuicBlockedFrame& frame,
+                          QuicDataWriter* writer);
+  bool AppendPaddingFrame(const QuicPaddingFrame& frame,
+                          QuicDataWriter* writer);
+  bool AppendMessageFrameAndTypeByte(const QuicMessageFrame& frame,
+                                     bool last_frame_in_packet,
+                                     QuicDataWriter* writer);
+
+  // IETF frame processing methods.
+  bool ProcessIetfStreamFrame(QuicDataReader* reader,
+                              uint8_t frame_type,
+                              QuicStreamFrame* frame);
+  bool ProcessIetfConnectionCloseFrame(QuicDataReader* reader,
+                                       QuicConnectionCloseType type,
+                                       QuicConnectionCloseFrame* frame);
+  bool ProcessPathChallengeFrame(QuicDataReader* reader,
+                                 QuicPathChallengeFrame* frame);
+  bool ProcessPathResponseFrame(QuicDataReader* reader,
+                                QuicPathResponseFrame* frame);
+  bool ProcessIetfResetStreamFrame(QuicDataReader* reader,
+                                   QuicRstStreamFrame* frame);
+  bool ProcessStopSendingFrame(QuicDataReader* reader,
+                               QuicStopSendingFrame* stop_sending_frame);
+  bool ProcessCryptoFrame(QuicDataReader* reader,
+                          EncryptionLevel encryption_level,
+                          QuicCryptoFrame* frame);
+  bool ProcessAckFrequencyFrame(QuicDataReader* reader,
+                                QuicAckFrequencyFrame* frame);
+  // IETF frame appending methods.  All methods append the type byte as well.
+  bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
+                             bool last_frame_in_packet,
+                             QuicDataWriter* writer);
+  bool AppendIetfConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+                                      QuicDataWriter* writer);
+  bool AppendPathChallengeFrame(const QuicPathChallengeFrame& frame,
+                                QuicDataWriter* writer);
+  bool AppendPathResponseFrame(const QuicPathResponseFrame& frame,
+                               QuicDataWriter* writer);
+  bool AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
+                                  QuicDataWriter* writer);
+  bool AppendStopSendingFrame(const QuicStopSendingFrame& stop_sending_frame,
+                              QuicDataWriter* writer);
+
+  // Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
+  bool AppendMaxDataFrame(const QuicWindowUpdateFrame& frame,
+                          QuicDataWriter* writer);
+  bool AppendMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
+                                QuicDataWriter* writer);
+  bool ProcessMaxDataFrame(QuicDataReader* reader,
+                           QuicWindowUpdateFrame* frame);
+  bool ProcessMaxStreamDataFrame(QuicDataReader* reader,
+                                 QuicWindowUpdateFrame* frame);
+
+  bool AppendMaxStreamsFrame(const QuicMaxStreamsFrame& frame,
+                             QuicDataWriter* writer);
+  bool ProcessMaxStreamsFrame(QuicDataReader* reader,
+                              QuicMaxStreamsFrame* frame,
+                              uint64_t frame_type);
+
+  bool AppendDataBlockedFrame(const QuicBlockedFrame& frame,
+                              QuicDataWriter* writer);
+  bool ProcessDataBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame);
+
+  bool AppendStreamDataBlockedFrame(const QuicBlockedFrame& frame,
+                                    QuicDataWriter* writer);
+  bool ProcessStreamDataBlockedFrame(QuicDataReader* reader,
+                                     QuicBlockedFrame* frame);
+
+  bool AppendStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                                 QuicDataWriter* writer);
+  bool ProcessStreamsBlockedFrame(QuicDataReader* reader,
+                                  QuicStreamsBlockedFrame* frame,
+                                  uint64_t frame_type);
+
+  bool AppendNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame,
+                                  QuicDataWriter* writer);
+  bool ProcessNewConnectionIdFrame(QuicDataReader* reader,
+                                   QuicNewConnectionIdFrame* frame);
+  bool AppendRetireConnectionIdFrame(const QuicRetireConnectionIdFrame& frame,
+                                     QuicDataWriter* writer);
+  bool ProcessRetireConnectionIdFrame(QuicDataReader* reader,
+                                      QuicRetireConnectionIdFrame* frame);
+
+  bool AppendNewTokenFrame(const QuicNewTokenFrame& frame,
+                           QuicDataWriter* writer);
+  bool ProcessNewTokenFrame(QuicDataReader* reader, QuicNewTokenFrame* frame);
+
+  bool RaiseError(QuicErrorCode error);
+
+  // Returns true if |header| indicates a version negotiation packet.
+  bool IsVersionNegotiation(const QuicPacketHeader& header,
+                            bool packet_has_ietf_packet_header) const;
+
+  // Calculates and returns type byte of stream frame.
+  uint8_t GetStreamFrameTypeByte(const QuicStreamFrame& frame,
+                                 bool last_frame_in_packet) const;
+  uint8_t GetIetfStreamFrameTypeByte(const QuicStreamFrame& frame,
+                                     bool last_frame_in_packet) const;
+
+  void set_error(QuicErrorCode error) { error_ = error; }
+
+  void set_detailed_error(const char* error) { detailed_error_ = error; }
+  void set_detailed_error(std::string error) { detailed_error_ = error; }
+
+  // Returns false if the reading fails.
+  bool ReadUint32FromVarint62(QuicDataReader* reader,
+                              QuicIetfFrameType type,
+                              QuicStreamId* id);
+
+  bool ProcessPacketInternal(const QuicEncryptedPacket& packet);
+
+  // Determine whether the given QuicAckFrame should be serialized with a
+  // IETF_ACK_RECEIVE_TIMESTAMPS frame type.
+  bool UseIetfAckWithReceiveTimestamp(const QuicAckFrame& frame) const {
+    return VersionHasIetfQuicFrames(version_.transport_version) &&
+           process_timestamps_ &&
+           std::min<uint64_t>(max_receive_timestamps_per_ack_,
+                              frame.received_packet_times.size()) > 0;
+  }
+
+  std::string detailed_error_;
+  QuicFramerVisitorInterface* visitor_;
+  QuicErrorCode error_;
+  // Updated by ProcessPacketHeader when it succeeds decrypting a larger packet.
+  QuicPacketNumber largest_packet_number_;
+  // Largest successfully decrypted packet number per packet number space. Only
+  // used when supports_multiple_packet_number_spaces_ is true.
+  QuicPacketNumber largest_decrypted_packet_numbers_[NUM_PACKET_NUMBER_SPACES];
+  // Last server connection ID seen on the wire.
+  QuicConnectionId last_serialized_server_connection_id_;
+  // Last client connection ID seen on the wire.
+  QuicConnectionId last_serialized_client_connection_id_;
+  // Version of the protocol being used.
+  ParsedQuicVersion version_;
+  // This vector contains QUIC versions which we currently support.
+  // This should be ordered such that the highest supported version is the first
+  // element, with subsequent elements in descending order (versions can be
+  // skipped as necessary).
+  ParsedQuicVersionVector supported_versions_;
+  // Decrypters used to decrypt packets during parsing.
+  std::unique_ptr<QuicDecrypter> decrypter_[NUM_ENCRYPTION_LEVELS];
+  // The encryption level of the primary decrypter to use in |decrypter_|.
+  EncryptionLevel decrypter_level_;
+  // The encryption level of the alternative decrypter to use in |decrypter_|.
+  // When set to NUM_ENCRYPTION_LEVELS, indicates that there is no alternative
+  // decrypter.
+  EncryptionLevel alternative_decrypter_level_;
+  // |alternative_decrypter_latch_| is true if, when the decrypter at
+  // |alternative_decrypter_level_| successfully decrypts a packet, we should
+  // install it as the only decrypter.
+  bool alternative_decrypter_latch_;
+  // Encrypters used to encrypt packets via EncryptPayload().
+  std::unique_ptr<QuicEncrypter> encrypter_[NUM_ENCRYPTION_LEVELS];
+  // Tracks if the framer is being used by the entity that received the
+  // connection or the entity that initiated it.
+  Perspective perspective_;
+  // If false, skip validation that the public flags are set to legal values.
+  bool validate_flags_;
+  // The diversification nonce from the last received packet.
+  DiversificationNonce last_nonce_;
+  // If true, send and process timestamps in the ACK frame.
+  // TODO(ianswett): Remove the mutables once set_process_timestamps and
+  // set_receive_timestamp_exponent_ aren't const.
+  mutable bool process_timestamps_;
+  // The max number of receive timestamps to send per ACK frame.
+  mutable uint32_t max_receive_timestamps_per_ack_;
+  // The exponent to use when writing/reading ACK receive timestamps.
+  mutable uint32_t receive_timestamps_exponent_;
+  // The creation time of the connection, used to calculate timestamps.
+  QuicTime creation_time_;
+  // The last timestamp received if process_timestamps_ is true.
+  QuicTime::Delta last_timestamp_;
+
+  // Whether IETF QUIC Key Update is supported on this connection.
+  bool support_key_update_for_connection_;
+  // The value of the current key phase bit, which is toggled when the keys are
+  // changed.
+  bool current_key_phase_bit_;
+  // Whether we have performed a key update at least once.
+  bool key_update_performed_ = false;
+  // Tracks the first packet received in the current key phase. Will be
+  // uninitialized before the first one-RTT packet has been received or after a
+  // locally initiated key update but before the first packet from the peer in
+  // the new key phase is received.
+  QuicPacketNumber current_key_phase_first_received_packet_number_;
+  // Counts the number of packets received that might have been failed key
+  // update attempts. Reset to zero every time a packet is successfully
+  // decrypted.
+  QuicPacketCount potential_peer_key_update_attempt_count_;
+  // Decrypter for the previous key phase. Will be null if in the first key
+  // phase or previous keys have been discarded.
+  std::unique_ptr<QuicDecrypter> previous_decrypter_;
+  // Decrypter for the next key phase. May be null if next keys haven't been
+  // generated yet.
+  std::unique_ptr<QuicDecrypter> next_decrypter_;
+
+  // If this is a framer of a connection, this is the packet number of first
+  // sending packet. If this is a framer of a framer of dispatcher, this is the
+  // packet number of sent packets (for those which have packet number).
+  const QuicPacketNumber first_sending_packet_number_;
+
+  // If not null, framer asks data_producer_ to write stream frame data. Not
+  // owned. TODO(fayang): Consider add data producer to framer's constructor.
+  QuicStreamFrameDataProducer* data_producer_;
+
+  // Whether we are in the middle of a call to this->ProcessPacket.
+  bool is_processing_packet_ = false;
+
+  // If true, framer infers packet header type (IETF/GQUIC) from version_.
+  // Otherwise, framer infers packet header type from first byte of a received
+  // packet.
+  bool infer_packet_header_type_from_version_;
+
+  // IETF short headers contain a destination connection ID but do not
+  // encode its length. These variables contains the length we expect to read.
+  // This is also used to validate the long header destination connection ID
+  // lengths in older versions of QUIC.
+  uint8_t expected_server_connection_id_length_;
+  uint8_t expected_client_connection_id_length_;
+
+  // Indicates whether this framer supports multiple packet number spaces.
+  bool supports_multiple_packet_number_spaces_;
+
+  // Indicates whether received RETRY packets should be dropped.
+  bool drop_incoming_retry_packets_ = false;
+
+  // The length in bytes of the last packet number written to an IETF-framed
+  // packet.
+  size_t last_written_packet_number_length_;
+
+  // The amount to shift the ack timestamp in ACK frames. The default is 3.
+  // Local_ is the amount this node shifts timestamps in ACK frames it
+  // generates. it is sent to the peer in a transport parameter negotiation.
+  // Peer_ is the amount the peer shifts timestamps when it sends ACK frames to
+  // this node. This node "unshifts" by this amount. The value is received from
+  // the peer in the transport parameter negotiation. IETF QUIC only.
+  uint32_t peer_ack_delay_exponent_;
+  uint32_t local_ack_delay_exponent_;
+
+  // The type of received IETF frame currently being processed.  0 when not
+  // processing a frame or when processing Google QUIC frames.  Used to populate
+  // the Transport Connection Close when there is an error during frame
+  // processing.
+  uint64_t current_received_frame_type_;
+
+  // TODO(haoyuewang) Remove this debug utility.
+  // The type of the IETF frame preceding the frame currently being processed. 0
+  // when not processing a frame or only 1 frame has been processed.
+  uint64_t previously_received_frame_type_;
+};
+
+// Look for and parse the error code from the "<quic_error_code>:" text that
+// may be present at the start of the CONNECTION_CLOSE error details string.
+// This text, inserted by the peer if it's using Google's QUIC implementation,
+// contains additional error information that narrows down the exact error. The
+// extracted error code and (possibly updated) error_details string are returned
+// in |*frame|. If an error code is not found in the error details, then
+// frame->quic_error_code is set to
+// QuicErrorCode::QUIC_IETF_GQUIC_ERROR_MISSING.  If there is an error code in
+// the string then it is removed from the string.
+QUIC_EXPORT_PRIVATE void MaybeExtractQuicErrorCode(
+    QuicConnectionCloseFrame* frame);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_FRAMER_H_
diff --git a/quiche/quic/core/quic_framer_test.cc b/quiche/quic/core/quic_framer_test.cc
new file mode 100644
index 0000000..76bbe4a
--- /dev/null
+++ b/quiche/quic/core/quic_framer_test.cc
@@ -0,0 +1,16373 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_framer.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+using testing::ContainerEq;
+using testing::Return;
+
+namespace quic {
+namespace test {
+namespace {
+
+const uint64_t kEpoch = UINT64_C(1) << 32;
+const uint64_t kMask = kEpoch - 1;
+
+const StatelessResetToken kTestStatelessResetToken{
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
+
+// Use fields in which each byte is distinct to ensure that every byte is
+// framed correctly. The values are otherwise arbitrary.
+QuicConnectionId FramerTestConnectionId() {
+  return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
+}
+
+QuicConnectionId FramerTestConnectionIdPlusOne() {
+  return TestConnectionId(UINT64_C(0xFEDCBA9876543211));
+}
+
+QuicConnectionId FramerTestConnectionIdNineBytes() {
+  uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
+                                    0x54, 0x32, 0x10, 0x42};
+  return QuicConnectionId(reinterpret_cast<char*>(connection_id_bytes),
+                          sizeof(connection_id_bytes));
+}
+
+const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
+const QuicPacketNumber kSmallLargestObserved =
+    QuicPacketNumber(UINT16_C(0x1234));
+const QuicPacketNumber kSmallMissingPacket = QuicPacketNumber(UINT16_C(0x1233));
+const QuicPacketNumber kLeastUnacked = QuicPacketNumber(UINT64_C(0x012345670));
+const QuicStreamId kStreamId = UINT64_C(0x01020304);
+// Note that the high 4 bits of the stream offset must be less than 0x40
+// in order to ensure that the value can be encoded using VarInt62 encoding.
+const QuicStreamOffset kStreamOffset = UINT64_C(0x3A98FEDC32107654);
+const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789);
+
+// In testing that we can ack the full range of packets...
+// This is the largest packet number that can be represented in IETF QUIC
+// varint62 format.
+const QuicPacketNumber kLargestIetfLargestObserved =
+    QuicPacketNumber(UINT64_C(0x3fffffffffffffff));
+// Encodings for the two bits in a VarInt62 that
+// describe the length of the VarInt61. For binary packet
+// formats in this file, the convention is to code the
+// first byte as
+//   kVarInt62FourBytes + 0x<value_in_that_byte>
+const uint8_t kVarInt62OneByte = 0x00;
+const uint8_t kVarInt62TwoBytes = 0x40;
+const uint8_t kVarInt62FourBytes = 0x80;
+const uint8_t kVarInt62EightBytes = 0xc0;
+
+class TestEncrypter : public QuicEncrypter {
+ public:
+  ~TestEncrypter() override {}
+  bool SetKey(absl::string_view /*key*/) override { return true; }
+  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
+    return true;
+  }
+  bool SetIV(absl::string_view /*iv*/) override { return true; }
+  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
+    return true;
+  }
+  bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
+                     absl::string_view plaintext, char* output,
+                     size_t* output_length,
+                     size_t /*max_output_length*/) override {
+    packet_number_ = QuicPacketNumber(packet_number);
+    associated_data_ = std::string(associated_data);
+    plaintext_ = std::string(plaintext);
+    memcpy(output, plaintext.data(), plaintext.length());
+    *output_length = plaintext.length();
+    return true;
+  }
+  std::string GenerateHeaderProtectionMask(
+      absl::string_view /*sample*/) override {
+    return std::string(5, 0);
+  }
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetIVSize() const override { return 0; }
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
+    return ciphertext_size;
+  }
+  size_t GetCiphertextSize(size_t plaintext_size) const override {
+    return plaintext_size;
+  }
+  QuicPacketCount GetConfidentialityLimit() const override {
+    return std::numeric_limits<QuicPacketCount>::max();
+  }
+  absl::string_view GetKey() const override { return absl::string_view(); }
+  absl::string_view GetNoncePrefix() const override {
+    return absl::string_view();
+  }
+
+  QuicPacketNumber packet_number_;
+  std::string associated_data_;
+  std::string plaintext_;
+};
+
+class TestDecrypter : public QuicDecrypter {
+ public:
+  ~TestDecrypter() override {}
+  bool SetKey(absl::string_view /*key*/) override { return true; }
+  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
+    return true;
+  }
+  bool SetIV(absl::string_view /*iv*/) override { return true; }
+  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
+    return true;
+  }
+  bool SetPreliminaryKey(absl::string_view /*key*/) override {
+    QUIC_BUG(quic_bug_10486_1) << "should not be called";
+    return false;
+  }
+  bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
+    return true;
+  }
+  bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
+                     absl::string_view ciphertext, char* output,
+                     size_t* output_length,
+                     size_t /*max_output_length*/) override {
+    packet_number_ = QuicPacketNumber(packet_number);
+    associated_data_ = std::string(associated_data);
+    ciphertext_ = std::string(ciphertext);
+    memcpy(output, ciphertext.data(), ciphertext.length());
+    *output_length = ciphertext.length();
+    return true;
+  }
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* /*sample_reader*/) override {
+    return std::string(5, 0);
+  }
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetIVSize() const override { return 0; }
+  absl::string_view GetKey() const override { return absl::string_view(); }
+  absl::string_view GetNoncePrefix() const override {
+    return absl::string_view();
+  }
+  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
+  uint32_t cipher_id() const override { return 0xFFFFFFF2; }
+  QuicPacketCount GetIntegrityLimit() const override {
+    return std::numeric_limits<QuicPacketCount>::max();
+  }
+  QuicPacketNumber packet_number_;
+  std::string associated_data_;
+  std::string ciphertext_;
+};
+
+std::unique_ptr<QuicEncryptedPacket> EncryptPacketWithTagAndPhase(
+    const QuicPacket& packet, uint8_t tag, bool phase) {
+  std::string packet_data = std::string(packet.AsStringPiece());
+  if (phase) {
+    packet_data[0] |= FLAGS_KEY_PHASE_BIT;
+  } else {
+    packet_data[0] &= ~FLAGS_KEY_PHASE_BIT;
+  }
+
+  TaggingEncrypter crypter(tag);
+  const size_t packet_size = crypter.GetCiphertextSize(packet_data.size());
+  char* buffer = new char[packet_size];
+  size_t buf_len = 0;
+  if (!crypter.EncryptPacket(0, absl::string_view(), packet_data, buffer,
+                             &buf_len, packet_size)) {
+    delete[] buffer;
+    return nullptr;
+  }
+
+  return std::make_unique<QuicEncryptedPacket>(buffer, buf_len,
+                                               /*owns_buffer=*/true);
+}
+
+class TestQuicVisitor : public QuicFramerVisitorInterface {
+ public:
+  TestQuicVisitor()
+      : error_count_(0),
+        version_mismatch_(0),
+        packet_count_(0),
+        frame_count_(0),
+        complete_packets_(0),
+        derive_next_key_count_(0),
+        decrypted_first_packet_in_key_phase_count_(0),
+        accept_packet_(true),
+        accept_public_header_(true) {}
+
+  ~TestQuicVisitor() override {}
+
+  void OnError(QuicFramer* f) override {
+    QUIC_DLOG(INFO) << "QuicFramer Error: " << QuicErrorCodeToString(f->error())
+                    << " (" << f->error() << ")";
+    ++error_count_;
+  }
+
+  void OnPacket() override {}
+
+  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
+    public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) override {
+    version_negotiation_packet_ =
+        std::make_unique<QuicVersionNegotiationPacket>((packet));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  void OnRetryPacket(QuicConnectionId original_connection_id,
+                     QuicConnectionId new_connection_id,
+                     absl::string_view retry_token,
+                     absl::string_view retry_integrity_tag,
+                     absl::string_view retry_without_tag) override {
+    on_retry_packet_called_ = true;
+    retry_original_connection_id_ =
+        std::make_unique<QuicConnectionId>(original_connection_id);
+    retry_new_connection_id_ =
+        std::make_unique<QuicConnectionId>(new_connection_id);
+    retry_token_ = std::make_unique<std::string>(std::string(retry_token));
+    retry_token_integrity_tag_ =
+        std::make_unique<std::string>(std::string(retry_integrity_tag));
+    retry_without_tag_ =
+        std::make_unique<std::string>(std::string(retry_without_tag));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
+    QUIC_DLOG(INFO) << "QuicFramer Version Mismatch, version: "
+                    << received_version;
+    ++version_mismatch_;
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return false;
+  }
+
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
+    header_ = std::make_unique<QuicPacketHeader>((header));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return accept_public_header_;
+  }
+
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return true;
+  }
+
+  void OnDecryptedPacket(size_t /*length*/,
+                         EncryptionLevel /*level*/) override {
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  bool OnPacketHeader(const QuicPacketHeader& header) override {
+    ++packet_count_;
+    header_ = std::make_unique<QuicPacketHeader>((header));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return accept_packet_;
+  }
+
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
+    coalesced_packets_.push_back(packet.Clone());
+  }
+
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override {
+    undecryptable_packets_.push_back(packet.Clone());
+    undecryptable_decryption_levels_.push_back(decryption_level);
+    undecryptable_has_decryption_keys_.push_back(has_decryption_key);
+  }
+
+  bool OnStreamFrame(const QuicStreamFrame& frame) override {
+    ++frame_count_;
+    // Save a copy of the data so it is valid after the packet is processed.
+    std::string* string_data =
+        new std::string(frame.data_buffer, frame.data_length);
+    stream_data_.push_back(absl::WrapUnique(string_data));
+    stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
+        frame.stream_id, frame.fin, frame.offset, *string_data));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      // Low order bits of type encode flags, ignore them for this test.
+      EXPECT_TRUE(IS_IETF_STREAM_FRAME(framer_->current_received_frame_type()));
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
+    ++frame_count_;
+    // Save a copy of the data so it is valid after the packet is processed.
+    std::string* string_data =
+        new std::string(frame.data_buffer, frame.data_length);
+    crypto_data_.push_back(absl::WrapUnique(string_data));
+    crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
+        frame.level, frame.offset, *string_data));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_CRYPTO, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override {
+    ++frame_count_;
+    QuicAckFrame ack_frame;
+    ack_frame.largest_acked = largest_acked;
+    ack_frame.ack_delay_time = ack_delay_time;
+    ack_frames_.push_back(std::make_unique<QuicAckFrame>(ack_frame));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
+                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
+                  IETF_ACK_RECEIVE_TIMESTAMPS ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
+    QUICHE_DCHECK(!ack_frames_.empty());
+    ack_frames_[ack_frames_.size() - 1]->packets.AddRange(start, end);
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
+                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
+                  IETF_ACK_RECEIVE_TIMESTAMPS ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override {
+    ack_frames_[ack_frames_.size() - 1]->received_packet_times.push_back(
+        std::make_pair(packet_number, timestamp));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_ACK == framer_->current_received_frame_type() ||
+                  IETF_ACK_ECN == framer_->current_received_frame_type() ||
+                  IETF_ACK_RECEIVE_TIMESTAMPS ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
+
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
+    ++frame_count_;
+    stop_waiting_frames_.push_back(
+        std::make_unique<QuicStopWaitingFrame>(frame));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
+    padding_frames_.push_back(std::make_unique<QuicPaddingFrame>(frame));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_PADDING, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnPingFrame(const QuicPingFrame& frame) override {
+    ++frame_count_;
+    ping_frames_.push_back(std::make_unique<QuicPingFrame>(frame));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_PING, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnMessageFrame(const QuicMessageFrame& frame) override {
+    ++frame_count_;
+    message_frames_.push_back(
+        std::make_unique<QuicMessageFrame>(frame.data, frame.message_length));
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 ==
+                      framer_->current_received_frame_type() ||
+                  IETF_EXTENSION_MESSAGE_V99 ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
+    ++frame_count_;
+    handshake_done_frames_.push_back(
+        std::make_unique<QuicHandshakeDoneFrame>(frame));
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_EQ(IETF_HANDSHAKE_DONE, framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+    ++frame_count_;
+    ack_frequency_frames_.emplace_back(
+        std::make_unique<QuicAckFrequencyFrame>(frame));
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_EQ(IETF_ACK_FREQUENCY, framer_->current_received_frame_type());
+    return true;
+  }
+
+  void OnPacketComplete() override { ++complete_packets_; }
+
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
+    rst_stream_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_EQ(IETF_RST_STREAM, framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
+    connection_close_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_NE(GOOGLE_QUIC_CONNECTION_CLOSE, frame.close_type);
+      if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+        EXPECT_EQ(IETF_CONNECTION_CLOSE,
+                  framer_->current_received_frame_type());
+      } else {
+        EXPECT_EQ(IETF_APPLICATION_CLOSE,
+                  framer_->current_received_frame_type());
+      }
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
+    stop_sending_frame_ = frame;
+    EXPECT_EQ(IETF_STOP_SENDING, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
+    path_challenge_frame_ = frame;
+    EXPECT_EQ(IETF_PATH_CHALLENGE, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
+    path_response_frame_ = frame;
+    EXPECT_EQ(IETF_PATH_RESPONSE, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
+    goaway_frame_ = frame;
+    EXPECT_FALSE(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
+    max_streams_frame_ = frame;
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_TRUE(IETF_MAX_STREAMS_UNIDIRECTIONAL ==
+                    framer_->current_received_frame_type() ||
+                IETF_MAX_STREAMS_BIDIRECTIONAL ==
+                    framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
+    streams_blocked_frame_ = frame;
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    EXPECT_TRUE(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL ==
+                    framer_->current_received_frame_type() ||
+                IETF_STREAMS_BLOCKED_BIDIRECTIONAL ==
+                    framer_->current_received_frame_type());
+    return true;
+  }
+
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
+    window_update_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_MAX_DATA == framer_->current_received_frame_type() ||
+                  IETF_MAX_STREAM_DATA ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
+    blocked_frame_ = frame;
+    if (VersionHasIetfQuicFrames(transport_version_)) {
+      EXPECT_TRUE(IETF_DATA_BLOCKED == framer_->current_received_frame_type() ||
+                  IETF_STREAM_DATA_BLOCKED ==
+                      framer_->current_received_frame_type());
+    } else {
+      EXPECT_EQ(0u, framer_->current_received_frame_type());
+    }
+    return true;
+  }
+
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
+    new_connection_id_ = frame;
+    EXPECT_EQ(IETF_NEW_CONNECTION_ID, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override {
+    EXPECT_EQ(IETF_RETIRE_CONNECTION_ID,
+              framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    retire_connection_id_ = frame;
+    return true;
+  }
+
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
+    new_token_ = frame;
+    EXPECT_EQ(IETF_NEW_TOKEN, framer_->current_received_frame_type());
+    EXPECT_TRUE(VersionHasIetfQuicFrames(transport_version_));
+    return true;
+  }
+
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override {
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+    return token == kTestStatelessResetToken;
+  }
+
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override {
+    stateless_reset_packet_ =
+        std::make_unique<QuicIetfStatelessResetPacket>(packet);
+    EXPECT_EQ(0u, framer_->current_received_frame_type());
+  }
+
+  void OnKeyUpdate(KeyUpdateReason reason) override {
+    key_update_reasons_.push_back(reason);
+  }
+
+  void OnDecryptedFirstPacketInKeyPhase() override {
+    decrypted_first_packet_in_key_phase_count_++;
+  }
+
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    derive_next_key_count_++;
+    return std::make_unique<StrictTaggingDecrypter>(derive_next_key_count_);
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return std::make_unique<TaggingEncrypter>(derive_next_key_count_);
+  }
+
+  void set_framer(QuicFramer* framer) {
+    framer_ = framer;
+    transport_version_ = framer->transport_version();
+  }
+
+  size_t key_update_count() const { return key_update_reasons_.size(); }
+
+  // Counters from the visitor_ callbacks.
+  int error_count_;
+  int version_mismatch_;
+  int packet_count_;
+  int frame_count_;
+  int complete_packets_;
+  std::vector<KeyUpdateReason> key_update_reasons_;
+  int derive_next_key_count_;
+  int decrypted_first_packet_in_key_phase_count_;
+  bool accept_packet_;
+  bool accept_public_header_;
+
+  std::unique_ptr<QuicPacketHeader> header_;
+  std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
+  std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
+  std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
+  std::unique_ptr<QuicConnectionId> retry_original_connection_id_;
+  std::unique_ptr<QuicConnectionId> retry_new_connection_id_;
+  std::unique_ptr<std::string> retry_token_;
+  std::unique_ptr<std::string> retry_token_integrity_tag_;
+  std::unique_ptr<std::string> retry_without_tag_;
+  bool on_retry_packet_called_ = false;
+  std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
+  std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
+  std::vector<std::unique_ptr<QuicAckFrame>> ack_frames_;
+  std::vector<std::unique_ptr<QuicStopWaitingFrame>> stop_waiting_frames_;
+  std::vector<std::unique_ptr<QuicPaddingFrame>> padding_frames_;
+  std::vector<std::unique_ptr<QuicPingFrame>> ping_frames_;
+  std::vector<std::unique_ptr<QuicMessageFrame>> message_frames_;
+  std::vector<std::unique_ptr<QuicHandshakeDoneFrame>> handshake_done_frames_;
+  std::vector<std::unique_ptr<QuicAckFrequencyFrame>> ack_frequency_frames_;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> coalesced_packets_;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
+  std::vector<EncryptionLevel> undecryptable_decryption_levels_;
+  std::vector<bool> undecryptable_has_decryption_keys_;
+  QuicRstStreamFrame rst_stream_frame_;
+  QuicConnectionCloseFrame connection_close_frame_;
+  QuicStopSendingFrame stop_sending_frame_;
+  QuicGoAwayFrame goaway_frame_;
+  QuicPathChallengeFrame path_challenge_frame_;
+  QuicPathResponseFrame path_response_frame_;
+  QuicWindowUpdateFrame window_update_frame_;
+  QuicBlockedFrame blocked_frame_;
+  QuicStreamsBlockedFrame streams_blocked_frame_;
+  QuicMaxStreamsFrame max_streams_frame_;
+  QuicNewConnectionIdFrame new_connection_id_;
+  QuicRetireConnectionIdFrame retire_connection_id_;
+  QuicNewTokenFrame new_token_;
+  std::vector<std::unique_ptr<std::string>> stream_data_;
+  std::vector<std::unique_ptr<std::string>> crypto_data_;
+  QuicTransportVersion transport_version_;
+  QuicFramer* framer_;
+};
+
+// Simple struct for defining a packet's content, and associated
+// parse error.
+struct PacketFragment {
+  std::string error_if_missing;
+  std::vector<unsigned char> fragment;
+};
+
+using PacketFragments = std::vector<struct PacketFragment>;
+
+class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicFramerTest()
+      : encrypter_(new test::TestEncrypter()),
+        decrypter_(new test::TestDecrypter()),
+        version_(GetParam()),
+        start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
+        framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER,
+                kQuicDefaultConnectionIdLength) {
+    framer_.set_version(version_);
+    if (framer_.version().KnowsWhichDecrypterToUse()) {
+      framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+                               std::unique_ptr<QuicDecrypter>(decrypter_));
+    } else {
+      framer_.SetDecrypter(ENCRYPTION_INITIAL,
+                           std::unique_ptr<QuicDecrypter>(decrypter_));
+    }
+    framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                         std::unique_ptr<QuicEncrypter>(encrypter_));
+
+    framer_.set_visitor(&visitor_);
+    framer_.InferPacketHeaderTypeFromVersion();
+    visitor_.set_framer(&framer_);
+  }
+
+  void SetDecrypterLevel(EncryptionLevel level) {
+    if (!framer_.version().KnowsWhichDecrypterToUse()) {
+      return;
+    }
+    decrypter_ = new TestDecrypter();
+    framer_.InstallDecrypter(level, std::unique_ptr<QuicDecrypter>(decrypter_));
+  }
+
+  // Helper function to get unsigned char representation of the handshake
+  // protocol byte at position |pos| of the current QUIC version number.
+  unsigned char GetQuicVersionByte(int pos) {
+    return (CreateQuicVersionLabel(version_) >> 8 * (3 - pos)) & 0xff;
+  }
+
+  // Helper functions to take a v1 long header packet and make it v2. These are
+  // not needed for short header packets, but if sent, this function will exit
+  // cleanly. It needs to be called twice for coalesced packets (see references
+  // to length_of_first_coalesced_packet below for examples of how to do this).
+  inline void ReviseFirstByteByVersion(unsigned char packet_ietf[]) {
+    if (version_.UsesV2PacketTypes() && (packet_ietf[0] >= 0x80)) {
+      packet_ietf[0] = (packet_ietf[0] + 0x10) | 0xc0;
+    }
+  }
+  inline void ReviseFirstByteByVersion(PacketFragments& packet_ietf) {
+    ReviseFirstByteByVersion(&packet_ietf[0].fragment[0]);
+  }
+
+  bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
+    if (packet_number != encrypter_->packet_number_) {
+      QUIC_LOG(ERROR) << "Encrypted incorrect packet number.  expected "
+                      << packet_number
+                      << " actual: " << encrypter_->packet_number_;
+      return false;
+    }
+    if (packet->AssociatedData(framer_.transport_version()) !=
+        encrypter_->associated_data_) {
+      QUIC_LOG(ERROR) << "Encrypted incorrect associated data.  expected "
+                      << packet->AssociatedData(framer_.transport_version())
+                      << " actual: " << encrypter_->associated_data_;
+      return false;
+    }
+    if (packet->Plaintext(framer_.transport_version()) !=
+        encrypter_->plaintext_) {
+      QUIC_LOG(ERROR) << "Encrypted incorrect plaintext data.  expected "
+                      << packet->Plaintext(framer_.transport_version())
+                      << " actual: " << encrypter_->plaintext_;
+      return false;
+    }
+    return true;
+  }
+
+  bool CheckDecryption(const QuicEncryptedPacket& encrypted,
+                       bool includes_version,
+                       bool includes_diversification_nonce,
+                       QuicConnectionIdLength destination_connection_id_length,
+                       QuicConnectionIdLength source_connection_id_length) {
+    return CheckDecryption(
+        encrypted, includes_version, includes_diversification_nonce,
+        destination_connection_id_length, source_connection_id_length,
+        VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  }
+
+  bool CheckDecryption(
+      const QuicEncryptedPacket& encrypted, bool includes_version,
+      bool includes_diversification_nonce,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length,
+      QuicVariableLengthIntegerLength retry_token_length_length,
+      size_t retry_token_length,
+      QuicVariableLengthIntegerLength length_length) {
+    if (visitor_.header_->packet_number != decrypter_->packet_number_) {
+      QUIC_LOG(ERROR) << "Decrypted incorrect packet number.  expected "
+                      << visitor_.header_->packet_number
+                      << " actual: " << decrypter_->packet_number_;
+      return false;
+    }
+    absl::string_view associated_data =
+        QuicFramer::GetAssociatedDataFromEncryptedPacket(
+            framer_.transport_version(), encrypted,
+            destination_connection_id_length, source_connection_id_length,
+            includes_version, includes_diversification_nonce,
+            PACKET_4BYTE_PACKET_NUMBER, retry_token_length_length,
+            retry_token_length, length_length);
+    if (associated_data != decrypter_->associated_data_) {
+      QUIC_LOG(ERROR) << "Decrypted incorrect associated data.  expected "
+                      << absl::BytesToHexString(associated_data) << " actual: "
+                      << absl::BytesToHexString(decrypter_->associated_data_);
+      return false;
+    }
+    absl::string_view ciphertext(
+        encrypted.AsStringPiece().substr(GetStartOfEncryptedData(
+            framer_.transport_version(), destination_connection_id_length,
+            source_connection_id_length, includes_version,
+            includes_diversification_nonce, PACKET_4BYTE_PACKET_NUMBER,
+            retry_token_length_length, retry_token_length, length_length)));
+    if (ciphertext != decrypter_->ciphertext_) {
+      QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data.  expected "
+                      << absl::BytesToHexString(ciphertext) << " actual: "
+                      << absl::BytesToHexString(decrypter_->ciphertext_)
+                      << " associated data: "
+                      << absl::BytesToHexString(associated_data);
+      return false;
+    }
+    return true;
+  }
+
+  char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
+
+  // Creates a new QuicEncryptedPacket by concatenating the various
+  // packet fragments in |fragments|.
+  std::unique_ptr<QuicEncryptedPacket> AssemblePacketFromFragments(
+      const PacketFragments& fragments) {
+    char* buffer = new char[kMaxOutgoingPacketSize + 1];
+    size_t len = 0;
+    for (const auto& fragment : fragments) {
+      memcpy(buffer + len, fragment.fragment.data(), fragment.fragment.size());
+      len += fragment.fragment.size();
+    }
+    return std::make_unique<QuicEncryptedPacket>(buffer, len, true);
+  }
+
+  void CheckFramingBoundaries(const PacketFragments& fragments,
+                              QuicErrorCode error_code) {
+    std::unique_ptr<QuicEncryptedPacket> packet(
+        AssemblePacketFromFragments(fragments));
+    // Check all the various prefixes of |packet| for the expected
+    // parse error and error code.
+    for (size_t i = 0; i < packet->length(); ++i) {
+      std::string expected_error;
+      size_t len = 0;
+      for (const auto& fragment : fragments) {
+        len += fragment.fragment.size();
+        if (i < len) {
+          expected_error = fragment.error_if_missing;
+          break;
+        }
+      }
+
+      if (expected_error.empty()) continue;
+
+      CheckProcessingFails(*packet, i, expected_error, error_code);
+    }
+  }
+
+  void CheckProcessingFails(const QuicEncryptedPacket& packet, size_t len,
+                            std::string expected_error,
+                            QuicErrorCode error_code) {
+    QuicEncryptedPacket encrypted(packet.data(), len, false);
+    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
+    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
+    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
+  }
+
+  void CheckProcessingFails(unsigned char* packet, size_t len,
+                            std::string expected_error,
+                            QuicErrorCode error_code) {
+    QuicEncryptedPacket encrypted(AsChars(packet), len, false);
+    EXPECT_FALSE(framer_.ProcessPacket(encrypted)) << "len: " << len;
+    EXPECT_EQ(expected_error, framer_.detailed_error()) << "len: " << len;
+    EXPECT_EQ(error_code, framer_.error()) << "len: " << len;
+  }
+
+  // Checks if the supplied string matches data in the supplied StreamFrame.
+  void CheckStreamFrameData(std::string str, QuicStreamFrame* frame) {
+    EXPECT_EQ(str, std::string(frame->data_buffer, frame->data_length));
+  }
+
+  void CheckCalculatePacketNumber(uint64_t expected_packet_number,
+                                  QuicPacketNumber last_packet_number) {
+    uint64_t wire_packet_number = expected_packet_number & kMask;
+    EXPECT_EQ(expected_packet_number,
+              QuicFramerPeer::CalculatePacketNumberFromWire(
+                  &framer_, PACKET_4BYTE_PACKET_NUMBER, last_packet_number,
+                  wire_packet_number))
+        << "last_packet_number: " << last_packet_number
+        << " wire_packet_number: " << wire_packet_number;
+  }
+
+  std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
+                                              const QuicFrames& frames) {
+    return BuildUnsizedDataPacket(&framer_, header, frames);
+  }
+
+  std::unique_ptr<QuicPacket> BuildDataPacket(const QuicPacketHeader& header,
+                                              const QuicFrames& frames,
+                                              size_t packet_size) {
+    return BuildUnsizedDataPacket(&framer_, header, frames, packet_size);
+  }
+
+  // N starts at 1.
+  QuicStreamId GetNthStreamid(QuicTransportVersion transport_version,
+                              Perspective perspective, bool bidirectional,
+                              int n) {
+    if (bidirectional) {
+      return QuicUtils::GetFirstBidirectionalStreamId(transport_version,
+                                                      perspective) +
+             ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
+    }
+    // Unidirectional
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version,
+                                                     perspective) +
+           ((n - 1) * QuicUtils::StreamIdDelta(transport_version));
+  }
+
+  QuicTime CreationTimePlus(uint64_t offset_us) {
+    return framer_.creation_time() +
+           QuicTime::Delta::FromMicroseconds(offset_us);
+  }
+
+  test::TestEncrypter* encrypter_;
+  test::TestDecrypter* decrypter_;
+  ParsedQuicVersion version_;
+  QuicTime start_;
+  QuicFramer framer_;
+  test::TestQuicVisitor visitor_;
+  quiche::SimpleBufferAllocator allocator_;
+};
+
+// Multiple test cases of QuicFramerTest use byte arrays to define packets for
+// testing, and these byte arrays contain the QUIC version. This macro explodes
+// the 32-bit version into four bytes in network order. Since it uses methods of
+// QuicFramerTest, it is only valid to use this in a QuicFramerTest.
+#define QUIC_VERSION_BYTES                                             \
+  GetQuicVersionByte(0), GetQuicVersionByte(1), GetQuicVersionByte(2), \
+      GetQuicVersionByte(3)
+
+// Run all framer tests with all supported versions of QUIC.
+INSTANTIATE_TEST_SUITE_P(QuicFramerTests, QuicFramerTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
+  // A few quick manual sanity checks.
+  CheckCalculatePacketNumber(UINT64_C(1), QuicPacketNumber());
+  CheckCalculatePacketNumber(kEpoch + 1, QuicPacketNumber(kMask));
+  CheckCalculatePacketNumber(kEpoch, QuicPacketNumber(kMask));
+  for (uint64_t j = 0; j < 10; j++) {
+    CheckCalculatePacketNumber(j, QuicPacketNumber());
+    CheckCalculatePacketNumber(kEpoch - 1 - j, QuicPacketNumber());
+  }
+
+  // Cases where the last number was close to the start of the range.
+  for (QuicPacketNumber last = QuicPacketNumber(1); last < QuicPacketNumber(10);
+       last++) {
+    // Small numbers should not wrap (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(j, last);
+    }
+
+    // Large numbers should not wrap either (because we're near 0 already).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(kEpoch - 1 - j, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
+  // Cases where the last number was close to the end of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    QuicPacketNumber last = QuicPacketNumber(kEpoch - i);
+
+    // Small numbers should wrap.
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(kEpoch + j, last);
+    }
+
+    // Large numbers should not (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(kEpoch - 1 - j, last);
+    }
+  }
+}
+
+// Next check where we're in a non-zero epoch to verify we handle
+// reverse wrapping, too.
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearPrevEpoch) {
+  const uint64_t prev_epoch = 1 * kEpoch;
+  const uint64_t cur_epoch = 2 * kEpoch;
+  // Cases where the last number was close to the start of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    QuicPacketNumber last = QuicPacketNumber(cur_epoch + i);
+    // Small number should not wrap (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(cur_epoch + j, last);
+    }
+
+    // But large numbers should reverse wrap.
+    for (uint64_t j = 0; j < 10; j++) {
+      uint64_t num = kEpoch - 1 - j;
+      CheckCalculatePacketNumber(prev_epoch + num, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextEpoch) {
+  const uint64_t cur_epoch = 2 * kEpoch;
+  const uint64_t next_epoch = 3 * kEpoch;
+  // Cases where the last number was close to the end of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    QuicPacketNumber last = QuicPacketNumber(next_epoch - 1 - i);
+
+    // Small numbers should wrap.
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(next_epoch + j, last);
+    }
+
+    // but large numbers should not (even if they're out of order).
+    for (uint64_t j = 0; j < 10; j++) {
+      uint64_t num = kEpoch - 1 - j;
+      CheckCalculatePacketNumber(cur_epoch + num, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearNextMax) {
+  const uint64_t max_number = std::numeric_limits<uint64_t>::max();
+  const uint64_t max_epoch = max_number & ~kMask;
+
+  // Cases where the last number was close to the end of the range
+  for (uint64_t i = 0; i < 10; i++) {
+    // Subtract 1, because the expected next packet number is 1 more than the
+    // last packet number.
+    QuicPacketNumber last = QuicPacketNumber(max_number - i - 1);
+
+    // Small numbers should not wrap, because they have nowhere to go.
+    for (uint64_t j = 0; j < 10; j++) {
+      CheckCalculatePacketNumber(max_epoch + j, last);
+    }
+
+    // Large numbers should not wrap either.
+    for (uint64_t j = 0; j < 10; j++) {
+      uint64_t num = kEpoch - 1 - j;
+      CheckCalculatePacketNumber(max_epoch + num, last);
+    }
+  }
+}
+
+TEST_P(QuicFramerTest, EmptyPacket) {
+  char packet[] = {0x00};
+  QuicEncryptedPacket encrypted(packet, 0, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+}
+
+TEST_P(QuicFramerTest, LargePacket) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[kMaxIncomingPacketSize + 1] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78, 0x56, 0x34, 0x12,
+    // private flags
+    0x00,
+  };
+  unsigned char packet46[kMaxIncomingPacketSize + 1] = {
+    // type (short header 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78, 0x56, 0x34, 0x12,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  const size_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+
+  memset(p + header_size, 0, kMaxIncomingPacketSize - header_size);
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  ASSERT_TRUE(visitor_.header_.get());
+  // Make sure we've parsed the packet header, so we can send an error.
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  // Make sure the correct error is propagated.
+  EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_TOO_LARGE));
+  EXPECT_EQ("Packet too large.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, PacketHeader) {
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"Unable to read public flags.",
+       {0x28}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments = packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label;
+  std::string detailed_error;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_FALSE(use_length_prefix);
+  EXPECT_THAT(error_code, IsQuicNoError());
+  EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
+  EXPECT_FALSE(version_flag);
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, LongPacketHeader) {
+  // clang-format off
+  PacketFragments packet46 = {
+    // type (long header with packet type ZERO_RTT)
+    {"Unable to read first byte.",
+     {0xD3}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // connection_id length
+    {"Unable to read ConnectionId length.",
+     {0x50}},
+    // connection_id
+    {"Unable to read destination connection ID.",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"Unable to read packet number.",
+     {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  if (!framer_.version().HasIetfInvariantHeader() ||
+      QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet46));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_TRUE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
+
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label;
+  std::string detailed_error;
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      *encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(error_code, IsQuicNoError());
+  EXPECT_EQ("", detailed_error);
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_FALSE(use_length_prefix);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_flag);
+  EXPECT_EQ(kQuicDefaultConnectionIdLength, destination_connection_id.length());
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, LongPacketHeaderWithBothConnectionIds) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    0xD3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x55,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    0xD3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag = false;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label = 0;
+  std::string detailed_error = "";
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(error_code, IsQuicNoError());
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
+            use_length_prefix);
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_flag);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(), source_connection_id);
+}
+
+TEST_P(QuicFramerTest, AllZeroPacketParsingFails) {
+  unsigned char packet[1200] = {};
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_flag = false;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  QuicVersionLabel version_label = 0;
+  std::string detailed_error = "";
+  bool use_length_prefix;
+  absl::optional<absl::string_view> retry_token;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  const QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_flag, &use_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_EQ(error_code, QUIC_INVALID_PACKET_HEADER);
+  EXPECT_EQ(detailed_error, "Invalid flags.");
+}
+
+TEST_P(QuicFramerTest, ParsePublicHeader) {
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version included, 8-byte connection ID,
+    // 4-byte packet number)
+    0x29,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // version
+    QUIC_VERSION_BYTES,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet46[] = {
+      // public flags (long header with packet type HANDSHAKE and
+      // 4-byte packet number)
+      0xE3,
+      // version
+      QUIC_VERSION_BYTES,
+      // connection ID lengths
+      0x50,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // long header packet length
+      0x05,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // padding frame
+      0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+
+  uint8_t first_byte = 0x33;
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  bool version_present = false, has_length_prefix = false;
+  QuicVersionLabel version_label = 0;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
+                   source_connection_id = EmptyQuicConnectionId();
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  absl::string_view retry_token;
+  std::string detailed_error = "foobar";
+
+  QuicDataReader reader(AsChars(p), p_length);
+  const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
+      &reader, kQuicDefaultConnectionIdLength,
+      /*ietf_format=*/
+      framer_.version().HasIetfInvariantHeader(), &first_byte, &format,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &long_packet_type,
+      &retry_token_length_length, &retry_token, &detailed_error);
+  EXPECT_THAT(parse_error, IsQuicNoError());
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(p[0], first_byte);
+  EXPECT_TRUE(version_present);
+  EXPECT_EQ(framer_.version().HasLengthPrefixedConnectionIds(),
+            has_length_prefix);
+  EXPECT_EQ(CreateQuicVersionLabel(framer_.version()), version_label);
+  EXPECT_EQ(framer_.version(), parsed_version);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
+  EXPECT_EQ(absl::string_view(), retry_token);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+    EXPECT_EQ(HANDSHAKE, long_packet_type);
+  } else {
+    EXPECT_EQ(GOOGLE_QUIC_PACKET, format);
+  }
+}
+
+TEST_P(QuicFramerTest, ParsePublicHeaderProxBadSourceConnectionIdLength) {
+  if (!framer_.version().HasLengthPrefixedConnectionIds()) {
+    return;
+  }
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    'P', 'R', 'O', 'X',
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length (bogus)
+    0xEE,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+
+  uint8_t first_byte = 0x33;
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  bool version_present = false, has_length_prefix = false;
+  QuicVersionLabel version_label = 0;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
+                   source_connection_id = EmptyQuicConnectionId();
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  absl::string_view retry_token;
+  std::string detailed_error = "foobar";
+
+  QuicDataReader reader(AsChars(p), p_length);
+  const QuicErrorCode parse_error = QuicFramer::ParsePublicHeader(
+      &reader, kQuicDefaultConnectionIdLength,
+      /*ietf_format=*/true, &first_byte, &format, &version_present,
+      &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &long_packet_type,
+      &retry_token_length_length, &retry_token, &detailed_error);
+  EXPECT_THAT(parse_error, IsQuicNoError());
+  EXPECT_EQ("", detailed_error);
+  EXPECT_EQ(p[0], first_byte);
+  EXPECT_TRUE(version_present);
+  EXPECT_TRUE(has_length_prefix);
+  EXPECT_EQ(0x50524F58u, version_label);  // "PROX"
+  EXPECT_EQ(UnsupportedQuicVersion(), parsed_version);
+  EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
+  EXPECT_EQ(absl::string_view(), retry_token);
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+}
+
+TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToClient) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  framer_.SetExpectedClientConnectionIdLength(kQuicDefaultConnectionIdLength);
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x13, 0x37, 0x42, 0x33,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+}
+
+// In short header packets from client to server, the client connection ID
+// is omitted, but the framer adds it to the header struct using its
+// last serialized client connection ID. This test ensures that this
+// mechanism behaves as expected.
+TEST_P(QuicFramerTest, ClientConnectionIdFromShortHeaderToServer) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLastSerializedClientConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x13, 0x37, 0x42, 0x33,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      FramerTestConnectionId());
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (0 byte connection_id)
+      {"Unable to read public flags.",
+       {0x20}},
+      // connection_id
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+        // type (short header, 4 byte packet number)
+        {"Unable to read first byte.",
+         {0x43}},
+        // connection_id
+        // packet number
+        {"Unable to read packet number.",
+         {0x12, 0x34, 0x56, 0x78}},
+   };
+
+  PacketFragments packet_hp = {
+        // type (short header, 4 byte packet number)
+        {"Unable to read first byte.",
+         {0x43}},
+        // connection_id
+        // packet number
+        {"",
+         {0x12, 0x34, 0x56, 0x78}},
+   };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (0 byte connection_id)
+      {"Unable to read public flags.",
+       {0x29}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"Unable to read protocol version.",
+       {QUIC_VERSION_BYTES}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
+      // packet number)
+      {"Unable to read first byte.",
+       {0xD3}},
+      // version tag
+      {"Unable to read protocol version.",
+       {QUIC_VERSION_BYTES}},
+      // connection_id length
+      {"Unable to read ConnectionId length.",
+       {0x50}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet49 = {
+      // type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
+      // packet number)
+      {"Unable to read first byte.",
+       {0xD3}},
+      // version tag
+      {"Unable to read protocol version.",
+       {QUIC_VERSION_BYTES}},
+      // destination connection ID length
+      {"Unable to read destination connection ID.",
+       {0x08}},
+      // destination connection ID
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // source connection ID length
+      {"Unable to read source connection ID.",
+       {0x00}},
+      // long header packet length
+      {"Unable to read long header payload length.",
+       {0x04}},
+      // packet number
+      {"Long header payload length longer than packet.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  ReviseFirstByteByVersion(packet49);
+  PacketFragments& fragments =
+      framer_.version().HasLongHeaderLengths()
+          ? packet49
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_TRUE(visitor_.header_->version_flag);
+  EXPECT_EQ(GetParam(), visitor_.header_->version);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id and 4 byte packet number)
+      {"Unable to read public flags.",
+       {0x28}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"Unable to read first byte.",
+       {0x43}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+
+  PacketFragments packet_hp = {
+      // type (short header, 4 byte packet number)
+      {"Unable to read first byte.",
+       {0x43}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id and 2 byte packet number)
+      {"Unable to read public flags.",
+       {0x18}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x56, 0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 2 byte packet number)
+      {"Unable to read first byte.",
+       {0x41}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x56, 0x78}},
+  };
+
+  PacketFragments packet_hp = {
+      // type (short header, 2 byte packet number)
+      {"Unable to read first byte.",
+       {0x41}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78}},
+      // padding
+      {"", {0x00, 0x00}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsQuicNoError());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  }
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id and 1 byte packet number)
+      {"Unable to read public flags.",
+       {0x08}},
+      // connection_id
+      {"Unable to read ConnectionId.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x78}},
+  };
+
+  PacketFragments packet46 = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x78}},
+  };
+
+  PacketFragments packet_hp = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x78}},
+      // padding
+      {"", {0x00, 0x00, 0x00}},
+  };
+
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection()
+          ? packet_hp
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsQuicNoError());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  }
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // Test the case when a packet is received from the past and future packet
+  // numbers are still calculated relative to the largest received packet.
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber - 2;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  QuicEncryptedPacket encrypted(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber - 2, visitor_.header_->packet_number);
+
+  // Receive a 1 byte packet number.
+  header.packet_number = kPacketNumber;
+  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  QuicEncryptedPacket encrypted1(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted1));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  // Process a 2 byte packet number 256 packets ago.
+  header.packet_number = kPacketNumber - 256;
+  header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  QuicEncryptedPacket encrypted2(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted2));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber - 256, visitor_.header_->packet_number);
+
+  // Process another 1 byte packet number and ensure it works.
+  header.packet_number = kPacketNumber - 1;
+  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  QuicEncryptedPacket encrypted3(data->data(), data->length(), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted3));
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_->destination_connection_id);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber - 1, visitor_.header_->packet_number);
+}
+
+TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags: includes nonce flag
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // nonce
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[] = {
+    // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
+    // number.
+    0xD0,
+    // version tag
+    QUIC_VERSION_BYTES,
+    // connection_id length
+    0x05,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+    // nonce
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+
+    // frame type (padding)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet49[] = {
+    // type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
+    // number.
+    0xD0,
+    // version tag
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x00,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x26,
+    // packet number
+    0x78,
+    // nonce
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+
+    // frame type (padding)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
+    return;
+  }
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_TRUE(visitor_.header_->nonce != nullptr);
+  for (char i = 0; i < 32; ++i) {
+    EXPECT_EQ(i, (*visitor_.header_->nonce)[static_cast<size_t>(i)]);
+  }
+  EXPECT_EQ(1u, visitor_.padding_frames_.size());
+  EXPECT_EQ(5, visitor_.padding_frames_[0]->num_padding_bytes);
+}
+
+TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id, version flag and an unknown flag)
+    0x29,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // version tag
+    'Q', '0', '0', '0',
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+    0xD3,
+    // version tag
+    'Q', '0', '0', '0',
+    // connection_id length
+    0x50,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet49[] = {
+    // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+    0xD3,
+    // version tag
+    'Q', '0', '0', '0',
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(0, visitor_.frame_count_);
+  EXPECT_EQ(1, visitor_.version_mismatch_);
+}
+
+TEST_P(QuicFramerTest, PaddingFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
+    0x08 | 0x01 | 0x02 | 0x04,
+
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    kVarInt62OneByte + 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  EXPECT_EQ(2u, visitor_.padding_frames_.size());
+  EXPECT_EQ(2, visitor_.padding_frames_[0]->num_padding_bytes);
+  EXPECT_EQ(2, visitor_.padding_frames_[1]->num_padding_bytes);
+  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+}
+
+TEST_P(QuicFramerTest, StreamFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFF}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFF}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
+      {"",
+       { 0x08 | 0x01 | 0x02 | 0x04 }},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Unable to read frame data.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+// Test an empty (no data) stream frame.
+TEST_P(QuicFramerTest, EmptyStreamFrame) {
+  // Only the IETF QUIC spec explicitly says that empty
+  // stream frames are supported.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type - IETF_STREAM with FIN, LEN, and OFFSET bits set.
+      {"",
+       { 0x08 | 0x01 | 0x02 | 0x04 }},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  EXPECT_EQ(kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  EXPECT_EQ(visitor_.stream_frames_[0].get()->data_length, 0u);
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, MissingDiversificationNonce) {
+  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
+    // TLS does not use diversification nonces.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  decrypter_ = new test::TestDecrypter();
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::unique_ptr<QuicDecrypter>(decrypter_));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 Perspective::IS_CLIENT));
+    framer_.SetAlternativeDecrypter(
+        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+  }
+
+  // clang-format off
+  unsigned char packet[] = {
+        // public flags (8 byte connection_id)
+        0x28,
+        // connection_id
+        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+        // packet number
+        0x12, 0x34, 0x56, 0x78,
+        // padding frame
+        0x00,
+    };
+
+  unsigned char packet46[] = {
+        // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+        0xD3,
+        // version tag
+        QUIC_VERSION_BYTES,
+        // connection_id length
+        0x05,
+        // connection_id
+        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+        // packet number
+        0x12, 0x34, 0x56, 0x78,
+        // padding frame
+        0x00,
+    };
+
+  unsigned char packet49[] = {
+        // type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
+        0xD3,
+        // version tag
+        QUIC_VERSION_BYTES,
+        // destination connection ID length
+        0x00,
+        // source connection ID length
+        0x08,
+        // source connection ID
+        0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
+        // IETF long header payload length
+        0x05,
+        // packet number
+        0x12, 0x34, 0x56, 0x78,
+        // padding frame
+        0x00,
+    };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+    EXPECT_EQ("Unable to decrypt ENCRYPTION_ZERO_RTT header protection.",
+              framer_.detailed_error());
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    // Cannot read diversification nonce.
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Unable to read nonce.", framer_.detailed_error());
+  } else {
+    EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  }
+}
+
+TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
+  if (framer_.version().HasIetfInvariantHeader()) {
+    // This test is nonsensical for IETF Quic.
+    return;
+  }
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments = packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFD}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (stream frame with fin)
+       {"",
+        {0xFD}},
+       // stream id
+       {"Unable to read stream_id.",
+        {0x03, 0x04}},
+       // offset
+       {"Unable to read offset.",
+        {0x3A, 0x98, 0xFE, 0xDC,
+         0x32, 0x10, 0x76, 0x54}},
+       {"Unable to read frame data.",
+        {
+          // data length
+          0x00, 0x0c,
+          // data
+          'h',  'e',  'l',  'l',
+          'o',  ' ',  'w',  'o',
+          'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
+      {"",
+       {0x08 | 0x01 | 0x02 | 0x04}},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62TwoBytes + 0x03, 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Unable to read frame data.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 2 bytes of kStreamId.
+  EXPECT_EQ(0x0000FFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFC}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFC}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM frame with LEN, FIN, and OFFSET bits set)
+      {"",
+       {0x08 | 0x01 | 0x02 | 0x04}},
+      // stream id
+      {"Unable to read IETF_STREAM frame stream id/count.",
+       {kVarInt62OneByte + 0x04}},
+      // offset
+      {"Unable to read stream data offset.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Unable to read stream data length.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Unable to read frame data.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 1 byte of kStreamId.
+  EXPECT_EQ(0x000000FF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, StreamFrameWithVersion) {
+  // If IETF frames are in use then we must also have the IETF
+  // header invariants.
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    QUICHE_DCHECK(framer_.version().HasIetfInvariantHeader());
+  }
+
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (version, 8 byte connection_id)
+      {"",
+       {0x29}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet46 = {
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      {"",
+       {0xD3}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // connection_id length
+      {"",
+       {0x50}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Unable to read offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Unable to read frame data.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet49 = {
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      {"",
+       {0xD3}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // destination connection ID length
+      {"",
+       {0x08}},
+      // destination connection ID
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // source connection ID length
+      {"",
+       {0x00}},
+      // long header packet length
+      {"",
+       {0x1E}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stream frame with fin)
+      {"",
+       {0xFE}},
+      // stream id
+      {"Long header payload length longer than packet.",
+       {0x02, 0x03, 0x04}},
+      // offset
+      {"Long header payload length longer than packet.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      {"Long header payload length longer than packet.",
+       {
+         // data length
+         0x00, 0x0c,
+         // data
+         'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      {"",
+       {0xD3}},
+      // version tag
+      {"",
+       {QUIC_VERSION_BYTES}},
+      // destination connection ID length
+      {"",
+       {0x08}},
+      // destination connection ID
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // source connection ID length
+      {"",
+       {0x00}},
+      // long header packet length
+      {"",
+       {0x1E}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      {"",
+       {0x08 | 0x01 | 0x02 | 0x04}},
+      // stream id
+      {"Long header payload length longer than packet.",
+       {kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04}},
+      // offset
+      {"Long header payload length longer than packet.",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Long header payload length longer than packet.",
+       {kVarInt62OneByte + 0x0c}},
+      // data
+      {"Long header payload length longer than packet.",
+       { 'h',  'e',  'l',  'l',
+         'o',  ' ',  'w',  'o',
+         'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  QuicVariableLengthIntegerLength retry_token_length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  size_t retry_token_length = 0;
+  QuicVariableLengthIntegerLength length_length =
+      QuicVersionHasLongHeaderLengths(framer_.transport_version())
+          ? VARIABLE_LENGTH_INTEGER_LENGTH_1
+          : VARIABLE_LENGTH_INTEGER_LENGTH_0;
+
+  ReviseFirstByteByVersion(packet_ietf);
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasLongHeaderLengths()
+                 ? packet49
+                 : (framer_.version().HasIetfInvariantHeader() ? packet46
+                                                               : packet));
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID,
+      retry_token_length_length, retry_token_length, length_length));
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  CheckFramingBoundaries(fragments, framer_.version().HasLongHeaderLengths()
+                                        ? QUIC_INVALID_PACKET_HEADER
+                                        : QUIC_INVALID_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, RejectPacket) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  visitor_.accept_packet_ = false;
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x28,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin)
+      0xFF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (STREAM Frame with FIN, LEN, and OFFSET bits set)
+      0x10 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+  QuicEncryptedPacket encrypted(AsChars(p),
+                                framer_.version().HasIetfInvariantHeader()
+                                    ? ABSL_ARRAYSIZE(packet46)
+                                    : ABSL_ARRAYSIZE(packet),
+                                false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+}
+
+TEST_P(QuicFramerTest, RejectPublicHeader) {
+  visitor_.accept_public_header_ = false;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 1 byte packet number)
+    0x40,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x01,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(
+      framer_.version().HasIetfInvariantHeader() ? AsChars(packet46)
+                                                 : AsChars(packet),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet),
+      false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_FALSE(visitor_.header_->packet_number.IsInitialized());
+}
+
+TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short packet, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short packet, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK)
+       // (one ack block, 2 byte largest observed, 2 byte block length)
+       // IETF-Quic ignores the bit-fields in the ack type, all of
+       // that information is encoded elsewhere in the frame.
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62TwoBytes  + 0x12, 0x34}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+      // Ack block count (0 -- no blocks after the first)
+      {"Unable to read ack block count.",
+       {kVarInt62OneByte + 0x00}},
+       // first ack block length - 1.
+       // IETF Quic defines the ack block's value as the "number of
+       // packets that preceed the largest packet number in the block"
+       // which for the 1st ack block is the largest acked field,
+       // above. This means that if we are acking just packet 0x1234
+       // then the 1st ack block will be 0.
+       {"Unable to read first ack block length.",
+        {kVarInt62TwoBytes + 0x12, 0x33}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
+  ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+// This test checks that the ack frame processor correctly identifies
+// and handles the case where the first ack block is larger than the
+// largest_acked packet.
+TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x88, 0x88}},
+      // num timestamps.
+      {"Underflow with first ack block length 34952 largest acked is 4660.",
+       {0x00}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       {0x45}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x88, 0x88}},
+      // num timestamps.
+      {"Underflow with first ack block length 34952 largest acked is 4660.",
+       {0x00}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62TwoBytes  + 0x12, 0x34}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (0 -- no blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x00}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62TwoBytes + 0x28, 0x88}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+// This test checks that the ack frame processor correctly identifies
+// and handles the case where the third ack block's gap is larger than the
+// available space in the ack range.
+TEST_P(QuicFramerTest, ThirdAckBlockUnderflowGap) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 63}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (2 -- 2 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x02}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 13}},  // Ack 14 packets, range 50..63 (inclusive)
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 9}},  // Gap 10 packets, 40..49 (inclusive)
+       {"Unable to read ack block value.",
+        {kVarInt62OneByte + 9}},  // Ack 10 packets, 30..39 (inclusive)
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 29}},  // A gap of 30 packets (0..29 inclusive)
+                                   // should be too big, leaving no room
+                                   // for the ack.
+       {"Underflow with gap block length 30 previous ack block start is 30.",
+        {kVarInt62OneByte + 10}},  // Don't care
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(
+      framer_.detailed_error(),
+      "Underflow with gap block length 30 previous ack block start is 30.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// This test checks that the ack frame processor correctly identifies
+// and handles the case where the third ack block's length is larger than the
+// available space in the ack range.
+TEST_P(QuicFramerTest, ThirdAckBlockUnderflowAck) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 63}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (2 -- 2 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x02}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 13}},  // only 50 packet numbers "left"
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 10}},  // Only 40 packet numbers left
+       {"Unable to read ack block value.",
+        {kVarInt62OneByte + 10}},  // only 30 packet numbers left.
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 1}},  // Gap is OK, 29 packet numbers left
+      {"Unable to read ack block value.",
+        {kVarInt62OneByte + 30}},  // Use up all 30, should be an error
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with ack block length 31 latest ack block end is 25.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// Tests a variety of ack block wrap scenarios. For example, if the
+// N-1th block causes packet 0 to be acked, then a gap would wrap
+// around to 0x3fffffff ffffffff... Make sure we detect this
+// condition.
+TEST_P(QuicFramerTest, AckBlockUnderflowGapWrap) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 10}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (1 -- 1 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 1}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 9}},  // Ack packets 1..10 (inclusive)
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 1}},  // Gap of 2 packets (-1...0), should wrap
+       {"Underflow with gap block length 2 previous ack block start is 1.",
+        {kVarInt62OneByte + 9}},  // irrelevant
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with gap block length 2 previous ack block start is 1.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// As AckBlockUnderflowGapWrap, but in this test, it's the ack
+// component of the ack-block that causes the wrap, not the gap.
+TEST_P(QuicFramerTest, AckBlockUnderflowAckWrap) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62OneByte  + 10}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count (1 -- 1 blocks after the first)
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 1}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62OneByte + 6}},  // Ack packets 4..10 (inclusive)
+
+       {"Unable to read gap block value.",
+        {kVarInt62OneByte + 1}},  // Gap of 2 packets (2..3)
+       {"Unable to read ack block value.",
+        {kVarInt62OneByte + 9}},  // Should wrap.
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with ack block length 10 latest ack block end is 1.");
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_ACK_DATA);
+}
+
+// An ack block that acks the entire range, 1...0x3fffffffffffffff
+TEST_P(QuicFramerTest, AckBlockAcksEverything) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Test originally written for development of IETF QUIC. The test may
+    // also apply to Google QUIC. If so, the test should be extended to
+    // include Google QUIC (frame formats, etc). See b/141858819.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62EightBytes  + 0x3f, 0xff, 0xff, 0xff,
+         0xff, 0xff, 0xff, 0xff}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Ack block count No additional blocks
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62EightBytes  + 0x3f, 0xff, 0xff, 0xff,
+         0xff, 0xff, 0xff, 0xfe}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(1u, frame.packets.NumIntervals());
+  EXPECT_EQ(kLargestIetfLargestObserved, LargestAcked(frame));
+  EXPECT_EQ(kLargestIetfLargestObserved.ToUint64(),
+            frame.packets.NumPacketsSlow());
+}
+
+// This test looks for a malformed ack where
+//  - There is a largest-acked value (that is, the frame is acking
+//    something,
+//  - But the length of the first ack block is 0 saying that no frames
+//    are being acked with the largest-acked value or there are no
+//    additional ack blocks.
+//
+TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Not applicable to version 99 -- first ack block contains the
+    // number of packets that preceed the largest_acked packet.
+    // A value of 0 means no packets preceed --- that the block's
+    // length is 1. Therefore the condition that this test checks can
+    // not arise.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       { 0x2C }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x01 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x00 }},
+      // gap to next block.
+      { "First block length is zero.",
+        { 0x01 }},
+      // ack block length.
+      { "First block length is zero.",
+        { 0x0e, 0xaf }},
+      // Number of timestamps.
+      { "First block length is zero.",
+        { 0x00 }},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x01 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x00 }},
+      // gap to next block.
+      { "First block length is zero.",
+        { 0x01 }},
+      // ack block length.
+      { "First block length is zero.",
+        { 0x0e, 0xaf }},
+      // Number of timestamps.
+      { "First block length is zero.",
+        { 0x00 }},
+  };
+
+  // clang-format on
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_ACK_DATA));
+
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (ack frame)
+      // (one ack block, 4 byte largest observed, 2 byte block length)
+      {"",
+       {0x49}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34, 0x56, 0x78}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78, 0x9A, 0xBC}},
+      // frame type (ack frame)
+      // (one ack block, 4 byte largest observed, 2 byte block length)
+      {"",
+       {0x49}},
+      // largest acked
+      {"Unable to read largest acked.",
+       {0x12, 0x34, 0x56, 0x78}},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       {0x00, 0x00}},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       {0x12, 0x34}},
+      // num timestamps.
+      {"Unable to read num received packets.",
+       {0x00}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x56, 0x78, 0x9A, 0xBC}},
+       // frame type (IETF_ACK frame)
+       {"",
+        {0x02}},
+       // largest acked
+       {"Unable to read largest acked.",
+        {kVarInt62FourBytes  + 0x12, 0x34, 0x56, 0x78}},
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        {kVarInt62OneByte + 0x00}},
+       // Number of ack blocks after first
+       {"Unable to read ack block count.",
+        {kVarInt62OneByte + 0x00}},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        {kVarInt62TwoBytes  + 0x12, 0x33}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(kPacketNumber, LargestAcked(frame));
+  ASSERT_EQ(4660u, frame.packets.NumPacketsSlow());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
+// Tests ability to handle multiple ackblocks after the first ack
+// block. Non-version-99 tests include multiple timestamps as well.
+TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       { 0x2C }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x04 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x01 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x01 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x0e, 0xaf }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0xff }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x00 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x91 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x01, 0xea }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x05 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x04 }},
+      // Number of timestamps.
+      { "Unable to read num received packets.",
+        { 0x02 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x01 }},
+      // Delta time.
+      { "Unable to read time delta in received packets.",
+        { 0x76, 0x54, 0x32, 0x10 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x02 }},
+      // Delta time.
+      { "Unable to read incremental time delta in received packets.",
+        { 0x32, 0x10 }},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (ack frame)
+      // (more than one ack block, 2 byte largest observed, 2 byte block length)
+      {"",
+       { 0x65 }},
+      // largest acked
+      {"Unable to read largest acked.",
+       { 0x12, 0x34 }},
+      // Zero delta time.
+      {"Unable to read ack delay time.",
+       { 0x00, 0x00 }},
+      // num ack blocks ranges.
+      {"Unable to read num of ack blocks.",
+       { 0x04 }},
+      // first ack block length.
+      {"Unable to read first ack block length.",
+       { 0x00, 0x01 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x01 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x0e, 0xaf }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0xff }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x00 }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x91 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x01, 0xea }},
+      // gap to next block.
+      { "Unable to read gap to next ack block.",
+        { 0x05 }},
+      // ack block length.
+      { "Unable to ack block length.",
+        { 0x00, 0x04 }},
+      // Number of timestamps.
+      { "Unable to read num received packets.",
+        { 0x02 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x01 }},
+      // Delta time.
+      { "Unable to read time delta in received packets.",
+        { 0x76, 0x54, 0x32, 0x10 }},
+      // Delta from largest observed.
+      { "Unable to read sequence delta in received packets.",
+        { 0x02 }},
+      // Delta time.
+      { "Unable to read incremental time delta in received packets.",
+        { 0x32, 0x10 }},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x03 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Additional ACK Block #1
+       // gap to next block.
+       { "Unable to read gap block value.",
+         { kVarInt62OneByte + 0x00 }},   // gap of 1 packet
+       // ack block length.
+       { "Unable to read ack block value.",
+         { kVarInt62TwoBytes + 0x0e, 0xae }},   // 3759
+
+       // pre-version-99 test includes an ack block of 0 length. this
+       // can not happen in version 99. ergo the second block is not
+       // present in the v99 test and the gap length of the next block
+       // is the sum of the two gaps in the pre-version-99 tests.
+       // Additional ACK Block #2
+       // gap to next block.
+       { "Unable to read gap block value.",
+         { kVarInt62TwoBytes + 0x01, 0x8f }},  // Gap is 400 (0x190) pkts
+       // ack block length.
+       { "Unable to read ack block value.",
+         { kVarInt62TwoBytes + 0x01, 0xe9 }},  // block is 389 (x1ea) pkts
+
+       // Additional ACK Block #3
+       // gap to next block.
+       { "Unable to read gap block value.",
+         { kVarInt62OneByte + 0x04 }},   // Gap is 5 packets.
+       // ack block length.
+       { "Unable to read ack block value.",
+         { kVarInt62OneByte + 0x03 }},   // block is 3 packets.
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62FourBytes + 0x36, 0x54, 0x32, 0x10 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x32, 0x10 }},
+  };
+
+  // clang-format on
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(kSmallLargestObserved, LargestAcked(frame));
+  ASSERT_EQ(4254u, frame.packets.NumPacketsSlow());
+  EXPECT_EQ(4u, frame.packets.NumIntervals());
+  EXPECT_EQ(2u, frame.received_packet_times.size());
+}
+
+TEST_P(QuicFramerTest, AckFrameMultipleReceiveTimestampRanges) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x03 }},
+
+       // Timestamp range 1 (three packets).
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x03 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62FourBytes + 0x29, 0xff, 0xff, 0xff}},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x11, 0x11 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x01}},
+
+       // Timestamp range 2 (one packet).
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x05 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x10, 0x00 }},
+
+       // Timestamp range 3 (two packets).
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x08 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x10 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x01, 0x00 }},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  // Timestamp Range 1.
+                  {LargestAcked(frame) - 2, CreationTimePlus(0x29ffffff)},
+                  {LargestAcked(frame) - 3, CreationTimePlus(0x29ffeeee)},
+                  {LargestAcked(frame) - 4, CreationTimePlus(0x29ffeeed)},
+                  // Timestamp Range 2.
+                  {LargestAcked(frame) - 11, CreationTimePlus(0x29ffdeed)},
+                  // Timestamp Range 3.
+                  {LargestAcked(frame) - 21, CreationTimePlus(0x29ffdedd)},
+                  {LargestAcked(frame) - 22, CreationTimePlus(0x29ffdddd)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampWithExponent) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x00 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x03 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x29, 0xff}},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x11, 0x11 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x01}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_receive_timestamps_exponent(3);
+  framer_.set_process_timestamps(true);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  // Timestamp Range 1.
+                  {LargestAcked(frame), CreationTimePlus(0x29ff << 3)},
+                  {LargestAcked(frame) - 1, CreationTimePlus(0x18ee << 3)},
+                  {LargestAcked(frame) - 2, CreationTimePlus(0x18ed << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampGapTooHigh) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x79 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x29, 0xff}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp gap too high."));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampCountTooHigh) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x0a}},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62OneByte + 0x0b}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp delta too high."));
+}
+
+TEST_P(QuicFramerTest, AckFrameReceiveTimestampDeltaTooHigh) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       { 0x43 }},
+      // connection_id
+      {"",
+       { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+      // packet number
+      {"",
+       { 0x12, 0x34, 0x56, 0x78 }},
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      {"",
+       { 0x22 }},
+       // largest acked
+       {"Unable to read largest acked.",
+        { kVarInt62TwoBytes + 0x12, 0x34 }},   // = 4660
+       // Zero delta time.
+       {"Unable to read ack delay time.",
+        { kVarInt62OneByte + 0x00 }},
+       // number of additional ack blocks
+       {"Unable to read ack block count.",
+        { kVarInt62OneByte + 0x00 }},
+       // first ack block length.
+       {"Unable to read first ack block length.",
+        { kVarInt62OneByte + 0x00 }},  // 1st block length = 1
+
+       // Receive Timestamps.
+       { "Unable to read receive timestamp range count.",
+         { kVarInt62OneByte + 0x01 }},
+       { "Unable to read receive timestamp gap.",
+         { kVarInt62OneByte + 0x02 }},
+       { "Unable to read receive timestamp count.",
+         { kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77 }},
+       { "Unable to read receive timestamp delta.",
+         { kVarInt62TwoBytes + 0x29, 0xff}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+
+  framer_.set_process_timestamps(true);
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "Receive timestamp count too high."));
+}
+
+TEST_P(QuicFramerTest, AckFrameTimeStampDeltaTooHigh) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x28,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x01,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x01,
+      // num timestamps.
+      0x01,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x01,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x01,
+      // num timestamps.
+      0x01,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+  };
+  // clang-format on
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // ACK Timestamp is not a feature of IETF QUIC.
+    return;
+  }
+  QuicEncryptedPacket encrypted(
+      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
+      ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "delta_from_largest_observed too high"));
+}
+
+TEST_P(QuicFramerTest, AckFrameTimeStampSecondDeltaTooHigh) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x28,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x03,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x03,
+      // num timestamps.
+      0x02,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+      // Delta from largest observed.
+      0x03,
+      // Delta time.
+      0x10, 0x32,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 1 byte largest observed, 1 byte block length)
+      0x40,
+      // largest acked
+      0x03,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x03,
+      // num timestamps.
+      0x02,
+      // Delta from largest observed.
+      0x01,
+      // Delta time.
+      0x10, 0x32, 0x54, 0x76,
+      // Delta from largest observed.
+      0x03,
+      // Delta time.
+      0x10, 0x32,
+  };
+  // clang-format on
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // ACK Timestamp is not a feature of IETF QUIC.
+    return;
+  }
+  QuicEncryptedPacket encrypted(
+      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
+      ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_TRUE(absl::StartsWith(framer_.detailed_error(),
+                               "delta_from_largest_observed too high"));
+}
+
+TEST_P(QuicFramerTest, NewStopWaitingFrame) {
+  if (VersionHasIetfQuicFrames(version_.transport_version)) {
+    // The Stop Waiting frame is not in IETF QUIC
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x2C}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stop waiting frame)
+      {"",
+       {0x06}},
+      // least packet number awaiting an ack, delta from packet number.
+      {"Unable to read least unacked delta.",
+        {0x00, 0x00, 0x00, 0x08}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (stop waiting frame)
+      {"",
+       {0x06}},
+      // least packet number awaiting an ack, delta from packet number.
+      {"Unable to read least unacked delta.",
+        {0x00, 0x00, 0x00, 0x08}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  ASSERT_EQ(1u, visitor_.stop_waiting_frames_.size());
+  const QuicStopWaitingFrame& frame = *visitor_.stop_waiting_frames_[0];
+  EXPECT_EQ(kLeastUnacked, frame.least_unacked);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_STOP_WAITING_DATA);
+}
+
+TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
+  // The Stop Waiting frame is not in IETF QUIC
+  if (VersionHasIetfQuicFrames(version_.transport_version) &&
+      framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // frame type (stop waiting frame)
+    0x06,
+    // least packet number awaiting an ack, delta from packet number.
+    0x13, 0x34, 0x56, 0x78,
+    0x9A, 0xA8,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+    // frame type (stop waiting frame)
+    0x06,
+    // least packet number awaiting an ack, delta from packet number.
+    0x57, 0x78, 0x9A, 0xA8,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(
+      AsChars(framer_.version().HasIetfInvariantHeader() ? packet46 : packet),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet),
+      false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_STOP_WAITING_DATA));
+  EXPECT_EQ("Invalid unacked delta.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, RstStreamFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (rst stream frame)
+      {"",
+       {0x01}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // sent byte offset
+      {"Unable to read rst stream sent byte offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // error code QUIC_STREAM_CANCELLED
+      {"Unable to read rst stream error code.",
+       {0x00, 0x00, 0x00, 0x06}}
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (rst stream frame)
+      {"",
+       {0x01}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // sent byte offset
+      {"Unable to read rst stream sent byte offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // error code QUIC_STREAM_CANCELLED
+      {"Unable to read rst stream error code.",
+       {0x00, 0x00, 0x00, 0x06}}
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_RST_STREAM frame)
+      {"",
+       {0x04}},
+      // stream id
+      {"Unable to read IETF_RST_STREAM frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // application error code H3_REQUEST_CANCELLED gets translated to
+      // QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED.
+      {"Unable to read rst stream error code.",
+       {kVarInt62TwoBytes + 0x01, 0x0c}},
+      // Final Offset
+      {"Unable to read rst stream sent byte offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}}
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.rst_stream_frame_.stream_id);
+  EXPECT_EQ(QUIC_STREAM_CANCELLED, visitor_.rst_stream_frame_.error_code);
+  EXPECT_EQ(kStreamOffset, visitor_.rst_stream_frame_.byte_offset);
+  CheckFramingBoundaries(fragments, QUIC_INVALID_RST_STREAM_DATA);
+}
+
+TEST_P(QuicFramerTest, ConnectionCloseFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0x00, 0x11}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0x00, 0x11}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF Transport CONNECTION_CLOSE frame)
+      {"",
+       {0x1c}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62TwoBytes + 0x00, 0x11}},
+      {"Unable to read connection close frame type.",
+       {kVarInt62TwoBytes + 0x12, 0x34 }},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         kVarInt62OneByte + 0x11,
+         // error details with QuicErrorCode serialized
+         '1',  '1',  '5',  ':',
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0x11u, static_cast<unsigned>(
+                       visitor_.connection_close_frame_.wire_error_code));
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(0x1234u,
+              visitor_.connection_close_frame_.transport_close_frame_type);
+    EXPECT_EQ(115u, visitor_.connection_close_frame_.quic_error_code);
+  } else {
+    // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
+    // same value.
+    EXPECT_EQ(0x11u, static_cast<unsigned>(
+                         visitor_.connection_close_frame_.quic_error_code));
+  }
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+TEST_P(QuicFramerTest, ConnectionCloseFrameWithUnknownErrorCode) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (connection close frame)
+      {"",
+       {0x02}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read connection close error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF Transport CONNECTION_CLOSE frame)
+      {"",
+       {0x1c}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62FourBytes + 0x00, 0x00, 0xC0, 0xDE}},
+      {"Unable to read connection close frame type.",
+       {kVarInt62TwoBytes + 0x12, 0x34 }},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         kVarInt62OneByte + 0x11,
+         // error details with QuicErrorCode larger than QUIC_LAST_ERROR
+         '8',  '4',  '9',  ':',
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(0x1234u,
+              visitor_.connection_close_frame_.transport_close_frame_type);
+    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
+    EXPECT_EQ(849u, visitor_.connection_close_frame_.quic_error_code);
+  } else {
+    // For Google QUIC frame, |quic_error_code| and |wire_error_code| has the
+    // same value.
+    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.wire_error_code);
+    EXPECT_EQ(0xC0DEu, visitor_.connection_close_frame_.quic_error_code);
+  }
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+// As above, but checks that for Google-QUIC, if there happens
+// to be an ErrorCode string at the start of the details, it is
+// NOT extracted/parsed/folded/spindled/and/mutilated.
+TEST_P(QuicFramerTest, ConnectionCloseFrameWithExtractedInfoIgnoreGCuic) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (8 byte connection_id)
+    {"",
+     {0x28}},
+    // connection_id
+    {"",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"",
+     {0x12, 0x34, 0x56, 0x78}},
+    // frame type (connection close frame)
+    {"",
+     {0x02}},
+    // error code
+    {"Unable to read connection close error code.",
+     {0x00, 0x00, 0x00, 0x11}},
+    {"Unable to read connection close error details.",
+     {
+       // error details length
+       0x0, 0x13,
+       // error details
+      '1',  '7',  '7',  '6',
+      '7',  ':',  'b',  'e',
+      'c',  'a',  'u',  's',
+      'e',  ' ',  'I',  ' ',
+      'c',  'a',  'n'}
+    }
+  };
+
+  PacketFragments packet46 = {
+    // type (short header, 4 byte packet number)
+    {"",
+     {0x43}},
+    // connection_id
+    {"",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"",
+     {0x12, 0x34, 0x56, 0x78}},
+    // frame type (connection close frame)
+    {"",
+     {0x02}},
+    // error code
+    {"Unable to read connection close error code.",
+     {0x00, 0x00, 0x00, 0x11}},
+    {"Unable to read connection close error details.",
+     {
+       // error details length
+       0x0, 0x13,
+       // error details
+      '1',  '7',  '7',  '6',
+      '7',  ':',  'b',  'e',
+      'c',  'a',  'u',  's',
+      'e',  ' ',  'I',  ' ',
+      'c',  'a',  'n'}
+    }
+  };
+
+  PacketFragments packet_ietf = {
+    // type (short header, 4 byte packet number)
+    {"",
+     {0x43}},
+    // connection_id
+    {"",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"",
+     {0x12, 0x34, 0x56, 0x78}},
+    // frame type (IETF Transport CONNECTION_CLOSE frame)
+    {"",
+     {0x1c}},
+    // error code
+    {"Unable to read connection close error code.",
+     {kVarInt62OneByte + 0x11}},
+    {"Unable to read connection close frame type.",
+     {kVarInt62TwoBytes + 0x12, 0x34 }},
+    {"Unable to read connection close error details.",
+     {
+       // error details length
+       kVarInt62OneByte + 0x13,
+       // error details
+      '1',  '7',  '7',  '6',
+      '7',  ':',  'b',  'e',
+      'c',  'a',  'u',  's',
+      'e',  ' ',  'I',  ' ',
+      'c',  'a',  'n'}
+    }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0x11u, static_cast<unsigned>(
+                       visitor_.connection_close_frame_.wire_error_code));
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(0x1234u,
+              visitor_.connection_close_frame_.transport_close_frame_type);
+    EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
+    EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+  } else {
+    EXPECT_EQ(0x11u, visitor_.connection_close_frame_.quic_error_code);
+    // Error code is not prepended in GQUIC, so it is not removed and should
+    // remain in the reason phrase.
+    EXPECT_EQ("17767:because I can",
+              visitor_.connection_close_frame_.error_details);
+  }
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+// Test the CONNECTION_CLOSE/Application variant.
+TEST_P(QuicFramerTest, ApplicationCloseFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_CONNECTION_CLOSE/Application frame)
+      {"",
+       {0x1d}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62TwoBytes + 0x00, 0x11}},
+      {"Unable to read connection close error details.",
+       {
+         // error details length
+         kVarInt62OneByte + 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+            visitor_.connection_close_frame_.close_type);
+  EXPECT_EQ(122u, visitor_.connection_close_frame_.quic_error_code);
+  EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+// Check that we can extract an error code from an application close.
+TEST_P(QuicFramerTest, ApplicationCloseFrameExtract) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_CONNECTION_CLOSE/Application frame)
+      {"",
+       {0x1d}},
+      // error code
+      {"Unable to read connection close error code.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read connection close error details.",
+       {
+       // error details length
+       kVarInt62OneByte + 0x13,
+       // error details
+       '1',  '7',  '7',  '6',
+       '7',  ':',  'b',  'e',
+       'c',  'a',  'u',  's',
+       'e',  ' ',  'I',  ' ',
+       'c',  'a',  'n'}
+      }
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(IETF_QUIC_APPLICATION_CONNECTION_CLOSE,
+            visitor_.connection_close_frame_.close_type);
+  EXPECT_EQ(17767u, visitor_.connection_close_frame_.quic_error_code);
+  EXPECT_EQ(0x11u, visitor_.connection_close_frame_.wire_error_code);
+  EXPECT_EQ("because I can", visitor_.connection_close_frame_.error_details);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_CONNECTION_CLOSE_DATA);
+}
+
+TEST_P(QuicFramerTest, GoAwayFrame) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is not in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0x00, 0x09}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0x00, 0x09}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
+  EXPECT_EQ(0x9u, visitor_.goaway_frame_.error_code);
+  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
+}
+
+TEST_P(QuicFramerTest, GoAwayFrameWithUnknownErrorCode) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is not in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (go away frame)
+      {"",
+       {0x03}},
+      // error code larger than QUIC_LAST_ERROR
+      {"Unable to read go away error code.",
+       {0x00, 0x00, 0xC0, 0xDE}},
+      // stream id
+      {"Unable to read last good stream id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // stream id
+      {"Unable to read goaway reason.",
+       {
+         // error details length
+         0x0, 0x0d,
+         // error details
+         'b',  'e',  'c',  'a',
+         'u',  's',  'e',  ' ',
+         'I',  ' ',  'c',  'a',
+         'n'}
+      }
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.goaway_frame_.last_good_stream_id);
+  EXPECT_EQ(0xC0DE, visitor_.goaway_frame_.error_code);
+  EXPECT_EQ("because I can", visitor_.goaway_frame_.reason_phrase);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_GOAWAY_DATA);
+}
+
+TEST_P(QuicFramerTest, WindowUpdateFrame) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is not in IETF QUIC, see MaxDataFrame and MaxStreamDataFrame
+    // for IETF QUIC equivalents.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (window update frame)
+      {"",
+       {0x04}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // byte offset
+      {"Unable to read window byte_offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (window update frame)
+      {"",
+       {0x04}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+      // byte offset
+      {"Unable to read window byte_offset.",
+       {0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfInvariantHeader() ? packet46 : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_WINDOW_UPDATE_DATA);
+}
+
+TEST_P(QuicFramerTest, MaxDataFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is available only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_MAX_DATA frame)
+      {"",
+       {0x10}},
+      // byte offset
+      {"Can not read MAX_DATA byte-offset",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(QuicUtils::GetInvalidStreamId(framer_.transport_version()),
+            visitor_.window_update_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_DATA_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, MaxStreamDataFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame available only in IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_MAX_STREAM_DATA frame)
+      {"",
+       {0x11}},
+      // stream id
+      {"Unable to read IETF_MAX_STREAM_DATA frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // byte offset
+      {"Can not read MAX_STREAM_DATA byte-count",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.window_update_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.window_update_frame_.max_data);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, BlockedFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (8 byte connection_id)
+      {"",
+       {0x28}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (blocked frame)
+      {"",
+       {0x05}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+  };
+
+  PacketFragments packet46 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (blocked frame)
+      {"",
+       {0x05}},
+      // stream id
+      {"Unable to read stream_id.",
+       {0x01, 0x02, 0x03, 0x04}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_STREAM_BLOCKED frame)
+      {"",
+       {0x15}},
+      // stream id
+      {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      // Offset
+      {"Can not read stream blocked offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? packet_ietf
+          : (framer_.version().HasIetfInvariantHeader() ? packet46 : packet);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
+  } else {
+    EXPECT_EQ(0u, visitor_.blocked_frame_.offset);
+  }
+  EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    CheckFramingBoundaries(fragments, QUIC_INVALID_STREAM_BLOCKED_DATA);
+  } else {
+    CheckFramingBoundaries(fragments, QUIC_INVALID_BLOCKED_DATA);
+  }
+}
+
+TEST_P(QuicFramerTest, PingFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+     // public flags (8 byte connection_id)
+     0x28,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type (ping frame)
+     0x07,
+    };
+
+  unsigned char packet46[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type
+     0x07,
+    };
+
+  unsigned char packet_ietf[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type (IETF_PING frame)
+     0x01,
+    };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(
+      AsChars(VersionHasIetfQuicFrames(framer_.transport_version())
+                  ? packet_ietf
+                  : (framer_.version().HasIetfInvariantHeader() ? packet46
+                                                                : packet)),
+      VersionHasIetfQuicFrames(framer_.transport_version())
+          ? ABSL_ARRAYSIZE(packet_ietf)
+          : (framer_.version().HasIetfInvariantHeader()
+                 ? ABSL_ARRAYSIZE(packet46)
+                 : ABSL_ARRAYSIZE(packet)),
+      false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(1u, visitor_.ping_frames_.size());
+
+  // No need to check the PING frame boundaries because it has no payload.
+}
+
+TEST_P(QuicFramerTest, HandshakeDoneFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // frame type (Handshake done frame)
+     0x1e,
+    };
+  // clang-format on
+
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(1u, visitor_.handshake_done_frames_.size());
+}
+
+TEST_P(QuicFramerTest, ParseAckFrequencyFrame) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+     // type (short header, 4 byte packet number)
+     0x43,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x12, 0x34, 0x56, 0x78,
+
+     // ack frequency frame type (which needs two bytes as it is > 0x3F)
+     0x40, 0xAF,
+     // sequence_number
+     0x11,
+     // packet_tolerance
+     0x02,
+     // max_ack_delay_us = 2'5000 us
+     0x80, 0x00, 0x61, 0xA8,
+     // ignore_order
+     0x01
+  };
+  // clang-format on
+
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(1u, visitor_.ack_frequency_frames_.size());
+  const auto& frame = visitor_.ack_frequency_frames_.front();
+  EXPECT_EQ(17u, frame->sequence_number);
+  EXPECT_EQ(2u, frame->packet_tolerance);
+  EXPECT_EQ(2'5000u, frame->max_ack_delay.ToMicroseconds());
+  EXPECT_EQ(true, frame->ignore_order);
+}
+
+TEST_P(QuicFramerTest, MessageFrame) {
+  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet46 = {
+       // type (short header, 4 byte packet number)
+       {"",
+        {0x43}},
+       // connection_id
+       {"",
+        {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+       // packet number
+       {"",
+        {0x12, 0x34, 0x56, 0x78}},
+       // message frame type.
+       {"",
+        { 0x21 }},
+       // message length
+       {"Unable to read message length",
+        {0x07}},
+       // message data
+       {"Unable to read message data",
+        {'m', 'e', 's', 's', 'a', 'g', 'e'}},
+        // message frame no length.
+        {"",
+         { 0x20 }},
+        // message data
+        {{},
+         {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
+   };
+  PacketFragments packet_ietf = {
+       // type (short header, 4 byte packet number)
+       {"",
+        {0x43}},
+       // connection_id
+       {"",
+        {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+       // packet number
+       {"",
+        {0x12, 0x34, 0x56, 0x78}},
+       // message frame type.
+       {"",
+        { 0x31 }},
+       // message length
+       {"Unable to read message length",
+        {0x07}},
+       // message data
+       {"Unable to read message data",
+        {'m', 'e', 's', 's', 'a', 'g', 'e'}},
+        // message frame no length.
+        {"",
+         { 0x30 }},
+        // message data
+        {{},
+         {'m', 'e', 's', 's', 'a', 'g', 'e', '2'}},
+   };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    encrypted = AssemblePacketFromFragments(packet_ietf);
+  } else {
+    encrypted = AssemblePacketFromFragments(packet46);
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  ASSERT_EQ(2u, visitor_.message_frames_.size());
+  EXPECT_EQ(7u, visitor_.message_frames_[0]->message_length);
+  EXPECT_EQ(8u, visitor_.message_frames_[1]->message_length);
+
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    CheckFramingBoundaries(packet_ietf, QUIC_INVALID_MESSAGE_DATA);
+  } else {
+    CheckFramingBoundaries(packet46, QUIC_INVALID_MESSAGE_DATA);
+  }
+}
+
+TEST_P(QuicFramerTest, PublicResetPacketV33) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (public reset, 8 byte connection_id)
+      {"",
+       {0x0A}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"Unable to read reset message.",
+       {
+         // message tag (kPRST)
+         'P', 'R', 'S', 'T',
+         // num_entries (2) + padding
+         0x02, 0x00, 0x00, 0x00,
+         // tag kRNON
+         'R', 'N', 'O', 'N',
+         // end offset 8
+         0x08, 0x00, 0x00, 0x00,
+         // tag kRSEQ
+         'R', 'S', 'E', 'Q',
+         // end offset 16
+         0x10, 0x00, 0x00, 0x00,
+         // nonce proof
+         0x89, 0x67, 0x45, 0x23,
+         0x01, 0xEF, 0xCD, 0xAB,
+         // rejected packet number
+         0xBC, 0x9A, 0x78, 0x56,
+         0x34, 0x12, 0x00, 0x00,
+       }
+      }
+  };
+  // clang-format on
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.public_reset_packet_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.public_reset_packet_->connection_id);
+  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+  EXPECT_EQ(
+      IpAddressFamily::IP_UNSPEC,
+      visitor_.public_reset_packet_->client_address.host().address_family());
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
+}
+
+TEST_P(QuicFramerTest, PublicResetPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (public reset, 8 byte connection_id)
+      {"",
+       {0x0E}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"Unable to read reset message.",
+       {
+         // message tag (kPRST)
+         'P', 'R', 'S', 'T',
+         // num_entries (2) + padding
+         0x02, 0x00, 0x00, 0x00,
+         // tag kRNON
+         'R', 'N', 'O', 'N',
+         // end offset 8
+         0x08, 0x00, 0x00, 0x00,
+         // tag kRSEQ
+         'R', 'S', 'E', 'Q',
+         // end offset 16
+         0x10, 0x00, 0x00, 0x00,
+         // nonce proof
+         0x89, 0x67, 0x45, 0x23,
+         0x01, 0xEF, 0xCD, 0xAB,
+         // rejected packet number
+         0xBC, 0x9A, 0x78, 0x56,
+         0x34, 0x12, 0x00, 0x00,
+       }
+      }
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.public_reset_packet_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.public_reset_packet_->connection_id);
+  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+  EXPECT_EQ(
+      IpAddressFamily::IP_UNSPEC,
+      visitor_.public_reset_packet_->client_address.host().address_family());
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
+}
+
+TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (public reset, 8 byte connection_id)
+    0x0A,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // message tag (kPRST)
+    'P', 'R', 'S', 'T',
+    // num_entries (2) + padding
+    0x02, 0x00, 0x00, 0x00,
+    // tag kRNON
+    'R', 'N', 'O', 'N',
+    // end offset 8
+    0x08, 0x00, 0x00, 0x00,
+    // tag kRSEQ
+    'R', 'S', 'E', 'Q',
+    // end offset 16
+    0x10, 0x00, 0x00, 0x00,
+    // nonce proof
+    0x89, 0x67, 0x45, 0x23,
+    0x01, 0xEF, 0xCD, 0xAB,
+    // rejected packet number
+    0xBC, 0x9A, 0x78, 0x56,
+    0x34, 0x12, 0x00, 0x00,
+    // trailing junk
+    'j', 'u', 'n', 'k',
+  };
+  // clang-format on
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  ASSERT_THAT(framer_.error(), IsError(QUIC_INVALID_PUBLIC_RST_PACKET));
+  EXPECT_EQ("Unable to read reset message.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, PublicResetPacketWithClientAddress) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (public reset, 8 byte connection_id)
+      {"",
+       {0x0A}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"Unable to read reset message.",
+       {
+         // message tag (kPRST)
+         'P', 'R', 'S', 'T',
+         // num_entries (2) + padding
+         0x03, 0x00, 0x00, 0x00,
+         // tag kRNON
+         'R', 'N', 'O', 'N',
+         // end offset 8
+         0x08, 0x00, 0x00, 0x00,
+         // tag kRSEQ
+         'R', 'S', 'E', 'Q',
+         // end offset 16
+         0x10, 0x00, 0x00, 0x00,
+         // tag kCADR
+         'C', 'A', 'D', 'R',
+         // end offset 24
+         0x18, 0x00, 0x00, 0x00,
+         // nonce proof
+         0x89, 0x67, 0x45, 0x23,
+         0x01, 0xEF, 0xCD, 0xAB,
+         // rejected packet number
+         0xBC, 0x9A, 0x78, 0x56,
+         0x34, 0x12, 0x00, 0x00,
+         // client address: 4.31.198.44:443
+         0x02, 0x00,
+         0x04, 0x1F, 0xC6, 0x2C,
+         0xBB, 0x01,
+       }
+      }
+  };
+  // clang-format on
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.public_reset_packet_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.public_reset_packet_->connection_id);
+  EXPECT_EQ(kNonceProof, visitor_.public_reset_packet_->nonce_proof);
+  EXPECT_EQ("4.31.198.44",
+            visitor_.public_reset_packet_->client_address.host().ToString());
+  EXPECT_EQ(443, visitor_.public_reset_packet_->client_address.port());
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_PUBLIC_RST_PACKET);
+}
+
+TEST_P(QuicFramerTest, IetfStatelessResetPacket) {
+  // clang-format off
+  unsigned char packet[] = {
+      // type (short packet, 1 byte packet number)
+      0x50,
+      // Random bytes
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      // stateless reset token
+      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+  };
+  // clang-format on
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  decrypter_ = new test::TestDecrypter();
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::unique_ptr<QuicDecrypter>(decrypter_));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 Perspective::IS_CLIENT));
+    framer_.SetAlternativeDecrypter(
+        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+  }
+  // This packet cannot be decrypted because diversification nonce is missing.
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.stateless_reset_packet_.get());
+  EXPECT_EQ(kTestStatelessResetToken,
+            visitor_.stateless_reset_packet_->stateless_reset_token);
+}
+
+TEST_P(QuicFramerTest, IetfStatelessResetPacketInvalidStatelessResetToken) {
+  // clang-format off
+  unsigned char packet[] = {
+      // type (short packet, 1 byte packet number)
+      0x50,
+      // Random bytes
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      0x01, 0x11, 0x02, 0x22, 0x03, 0x33, 0x04, 0x44,
+      // stateless reset token
+      0xB6, 0x69, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetLastSerializedServerConnectionId(&framer_,
+                                                      TestConnectionId(0x33));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  decrypter_ = new test::TestDecrypter();
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::unique_ptr<QuicDecrypter>(decrypter_));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 Perspective::IS_CLIENT));
+    framer_.SetAlternativeDecrypter(
+        ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+  }
+  // This packet cannot be decrypted because diversification nonce is missing.
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  ASSERT_FALSE(visitor_.stateless_reset_packet_);
+}
+
+TEST_P(QuicFramerTest, VersionNegotiationPacketClient) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (version, 8 byte connection_id)
+      {"",
+       {0x29}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+
+  PacketFragments packet46 = {
+      // type (long header)
+      {"",
+       {0x8F}},
+      // version tag
+      {"",
+       {0x00, 0x00, 0x00, 0x00}},
+      {"",
+       {0x05}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // Supported versions
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+
+  PacketFragments packet49 = {
+      // type (long header)
+      {"",
+       {0x8F}},
+      // version tag
+      {"",
+       {0x00, 0x00, 0x00, 0x00}},
+      {"",
+       {0x08}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      {"",
+       {0x00}},
+      // Supported versions
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+  // clang-format on
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  PacketFragments& fragments =
+      framer_.version().HasLongHeaderLengths()     ? packet49
+      : framer_.version().HasIetfInvariantHeader() ? packet46
+                                                   : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
+  EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
+  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
+
+  // Remove the last version from the packet so that every truncated
+  // version of the packet is invalid, otherwise checking boundaries
+  // is annoyingly complicated.
+  for (size_t i = 0; i < 4; ++i) {
+    fragments.back().fragment.pop_back();
+  }
+  CheckFramingBoundaries(fragments, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+}
+
+TEST_P(QuicFramerTest, VersionNegotiationPacketServer) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (long header with all ignored bits set)
+      0xFF,
+      // version
+      0x00, 0x00, 0x00, 0x00,
+      // connection ID lengths
+      0x50,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // supported versions
+      QUIC_VERSION_BYTES,
+      'Q', '2', '.', '0',
+  };
+  unsigned char packet2[] = {
+      // public flags (long header with all ignored bits set)
+      0xFF,
+      // version
+      0x00, 0x00, 0x00, 0x00,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // source connection ID length
+      0x00,
+      // supported versions
+      QUIC_VERSION_BYTES,
+      'Q', '2', '.', '0',
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLengthPrefixedConnectionIds()) {
+    p = packet2;
+    p_length = ABSL_ARRAYSIZE(packet2);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(),
+              IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
+  EXPECT_EQ("Server received version negotiation packet.",
+            framer_.detailed_error());
+  EXPECT_FALSE(visitor_.version_negotiation_packet_.get());
+}
+
+TEST_P(QuicFramerTest, OldVersionNegotiationPacket) {
+  // clang-format off
+  PacketFragments packet = {
+      // public flags (version, 8 byte connection_id)
+      {"",
+       {0x2D}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // version tag
+      {"Unable to read supported version in negotiation.",
+       {QUIC_VERSION_BYTES,
+        'Q', '2', '.', '0'}},
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.version_negotiation_packet_.get());
+  EXPECT_EQ(1u, visitor_.version_negotiation_packet_->versions.size());
+  EXPECT_EQ(GetParam(), visitor_.version_negotiation_packet_->versions[0]);
+
+  // Remove the last version from the packet so that every truncated
+  // version of the packet is invalid, otherwise checking boundaries
+  // is annoyingly complicated.
+  for (size_t i = 0; i < 4; ++i) {
+    packet.back().fragment.pop_back();
+  }
+  CheckFramingBoundaries(packet, QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+}
+
+TEST_P(QuicFramerTest, ParseIetfRetryPacket) {
+  if (!framer_.version().SupportsRetry()) {
+    return;
+  }
+  // IETF RETRY is only sent from client to server.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (long header with packet type RETRY and ODCIL=8)
+      0xF5,
+      // version
+      QUIC_VERSION_BYTES,
+      // connection ID lengths
+      0x05,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // original destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // retry token
+      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
+      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
+  };
+  unsigned char packet49[] = {
+      // public flags (long header with packet type RETRY)
+      0xF0,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x00,
+      // source connection ID length
+      0x08,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // original destination connection ID length
+      0x08,
+      // original destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // retry token
+      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
+      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
+  };
+  unsigned char packet_with_tag[] = {
+      // public flags (long header with packet type RETRY)
+      0xF0,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x00,
+      // source connection ID length
+      0x08,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // retry token
+      'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
+      ' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
+      // retry token integrity tag
+      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().UsesTls()) {
+    ReviseFirstByteByVersion(packet_with_tag);
+    p = packet_with_tag;
+    p_length = ABSL_ARRAYSIZE(packet_with_tag);
+  } else if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_TRUE(visitor_.on_retry_packet_called_);
+  ASSERT_TRUE(visitor_.retry_new_connection_id_.get());
+  ASSERT_TRUE(visitor_.retry_token_.get());
+
+  if (framer_.version().UsesTls()) {
+    ASSERT_TRUE(visitor_.retry_token_integrity_tag_.get());
+    static const unsigned char expected_integrity_tag[16] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    };
+    quiche::test::CompareCharArraysWithHexError(
+        "retry integrity tag", visitor_.retry_token_integrity_tag_->data(),
+        visitor_.retry_token_integrity_tag_->length(),
+        reinterpret_cast<const char*>(expected_integrity_tag),
+        ABSL_ARRAYSIZE(expected_integrity_tag));
+    ASSERT_TRUE(visitor_.retry_without_tag_.get());
+    quiche::test::CompareCharArraysWithHexError(
+        "retry without tag", visitor_.retry_without_tag_->data(),
+        visitor_.retry_without_tag_->length(),
+        reinterpret_cast<const char*>(packet_with_tag), 35);
+  } else {
+    ASSERT_TRUE(visitor_.retry_original_connection_id_.get());
+    EXPECT_EQ(FramerTestConnectionId(),
+              *visitor_.retry_original_connection_id_.get());
+  }
+
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(),
+            *visitor_.retry_new_connection_id_.get());
+  EXPECT_EQ("Hello this is RETRY!", *visitor_.retry_token_.get());
+
+  // IETF RETRY is only sent from client to server, the rest of this test
+  // ensures that the server correctly drops them without acting on them.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Reset our visitor state to default settings.
+  visitor_.retry_original_connection_id_.reset();
+  visitor_.retry_new_connection_id_.reset();
+  visitor_.retry_token_.reset();
+  visitor_.retry_token_integrity_tag_.reset();
+  visitor_.retry_without_tag_.reset();
+  visitor_.on_retry_packet_called_ = false;
+
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  EXPECT_EQ("Client-initiated RETRY is invalid.", framer_.detailed_error());
+
+  EXPECT_FALSE(visitor_.on_retry_packet_called_);
+  EXPECT_FALSE(visitor_.retry_new_connection_id_.get());
+  EXPECT_FALSE(visitor_.retry_token_.get());
+  EXPECT_FALSE(visitor_.retry_token_integrity_tag_.get());
+  EXPECT_FALSE(visitor_.retry_without_tag_.get());
+}
+
+TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+                               absl::string_view("hello world!"));
+  QuicPaddingFrame padding_frame(2);
+  QuicFrames frames = {QuicFrame(padding_frame), QuicFrame(stream_frame),
+                       QuicFrame(padding_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // paddings
+    0x00, 0x00,
+    // frame type (IETF_STREAM with FIN, LEN, and OFFSET bits set)
+    0x08 | 0x01 | 0x02 | 0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    kVarInt62OneByte + 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+    // paddings
+    0x00, 0x00,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id and 4 byte packet number)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number_length = PACKET_2BYTE_PACKET_NUMBER;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id and 2 byte packet number)
+    0x1C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 2 byte packet number)
+    0x41,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 2 byte packet number)
+    0x41,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x56, 0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number_length = PACKET_1BYTE_PACKET_NUMBER;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // clang-format off
+  unsigned char packet[kMaxOutgoingPacketSize] = {
+    // public flags (8 byte connection_id and 1 byte packet number)
+    0x0C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[kMaxOutgoingPacketSize] = {
+    // type (short header, 1 byte packet number)
+    0x40,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet_ietf[kMaxOutgoingPacketSize] = {
+    // type (short header, 1 byte packet number)
+    0x40,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x78,
+
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  uint64_t header_size = GetPacketHeaderSize(
+      framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+                               absl::string_view("hello world!"));
+
+  QuicFrames frames = {QuicFrame(stream_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin and no length)
+    0xDF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin and no length)
+    0xDF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAM frame with FIN and OFFSET, no length)
+    0x08 | 0x01 | 0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = true;
+  if (framer_.version().HasIetfInvariantHeader()) {
+    header.long_packet_type = ZERO_RTT_PROTECTED;
+  }
+  header.packet_number = kPacketNumber;
+  if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
+                               absl::string_view("hello world!"));
+  QuicFrames frames = {QuicFrame(stream_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (version, 8 byte connection_id)
+      0x2D,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin and no length)
+      0xDF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+
+  unsigned char packet46[] = {
+      // type (long header with packet type ZERO_RTT_PROTECTED)
+      0xD3,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // connection_id length
+      0x50,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin and no length)
+      0xDF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+
+  unsigned char packet49[] = {
+      // type (long header with packet type ZERO_RTT_PROTECTED)
+      0xD3,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // length
+      0x40, 0x1D,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (stream frame with fin and no length)
+      0xDF,
+      // stream id
+      0x01, 0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (long header with packet type ZERO_RTT_PROTECTED)
+      0xD3,
+      // version tag
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // length
+      0x40, 0x1D,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_STREAM frame with fin and offset, no length)
+      0x08 | 0x01 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data
+      'h',  'e',  'l',  'l',  'o',  ' ',  'w',  'o',  'r', 'l', 'd', '!',
+  };
+  // clang-format on
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    ReviseFirstByteByVersion(packet_ietf);
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildCryptoFramePacket) {
+  if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  SimpleDataProducer data_producer;
+  framer_.set_data_producer(&data_producer);
+
+  absl::string_view crypto_frame_contents("hello world!");
+  QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, kStreamOffset,
+                               crypto_frame_contents.length());
+  data_producer.SaveCryptoData(ENCRYPTION_INITIAL, kStreamOffset,
+                               crypto_frame_contents);
+
+  QuicFrames frames = {QuicFrame(&crypto_frame)};
+
+  // clang-format off
+  unsigned char packet48[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (QuicFrameType CRYPTO_FRAME)
+    0x08,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // length
+    kVarInt62OneByte + 12,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CRYPTO frame)
+    0x06,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // length
+    kVarInt62OneByte + 12,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+  };
+  // clang-format on
+
+  unsigned char* packet = packet48;
+  size_t packet_size = ABSL_ARRAYSIZE(packet48);
+  if (framer_.version().HasIetfQuicFrames()) {
+    packet = packet_ietf;
+    packet_size = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError("constructed packet",
+                                              data->data(), data->length(),
+                                              AsChars(packet), packet_size);
+}
+
+TEST_P(QuicFramerTest, CryptoFrame) {
+  if (!QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    // CRYPTO frames aren't supported prior to v48.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet48 = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (QuicFrameType CRYPTO_FRAME)
+      {"",
+       {0x08}},
+      // offset
+      {"",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Invalid data length.",
+       {kVarInt62OneByte + 12}},
+      // data
+      {"Unable to read frame data.",
+       {'h',  'e',  'l',  'l',
+        'o',  ' ',  'w',  'o',
+        'r',  'l',  'd',  '!'}},
+  };
+
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_CRYPTO frame)
+      {"",
+       {0x06}},
+      // offset
+      {"",
+       {kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+        0x32, 0x10, 0x76, 0x54}},
+      // data length
+      {"Invalid data length.",
+       {kVarInt62OneByte + 12}},
+      // data
+      {"Unable to read frame data.",
+       {'h',  'e',  'l',  'l',
+        'o',  ' ',  'w',  'o',
+        'r',  'l',  'd',  '!'}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasIetfQuicFrames() ? packet_ietf : packet48;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+  ASSERT_EQ(1u, visitor_.crypto_frames_.size());
+  QuicCryptoFrame* frame = visitor_.crypto_frames_[0].get();
+  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, frame->level);
+  EXPECT_EQ(kStreamOffset, frame->offset);
+  EXPECT_EQ("hello world!",
+            std::string(frame->data_buffer, frame->data_length));
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
+  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (version, 8 byte connection_id)
+      0x0D,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  unsigned char packet46[] = {
+      // type (long header)
+      0xC0,
+      // version tag
+      0x00, 0x00, 0x00, 0x00,
+      // connection_id length
+      0x05,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  unsigned char packet49[] = {
+      // type (long header)
+      0xC0,
+      // version tag
+      0x00, 0x00, 0x00, 0x00,
+      // destination connection ID length
+      0x00,
+      // source connection ID length
+      0x08,
+      // source connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    p = packet49;
+    p_size = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicConnectionId connection_id = FramerTestConnectionId();
+  std::unique_ptr<QuicEncryptedPacket> data(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id, EmptyQuicConnectionId(),
+          framer_.version().HasIetfInvariantHeader(),
+          framer_.version().HasLengthPrefixedConnectionIds(),
+          SupportedVersions(GetParam())));
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildVersionNegotiationPacketWithClientConnectionId) {
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+
+  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
+
+  // clang-format off
+  unsigned char packet[] = {
+      // type (long header)
+      0xC0,
+      // version tag
+      0x00, 0x00, 0x00, 0x00,
+      // client/destination connection ID
+      0x08,
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // server/source connection ID
+      0x08,
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // supported versions
+      0xDA, 0x5A, 0x3A, 0x3A,
+      QUIC_VERSION_BYTES,
+  };
+  // clang-format on
+
+  QuicConnectionId server_connection_id = FramerTestConnectionId();
+  QuicConnectionId client_connection_id = FramerTestConnectionIdPlusOne();
+  std::unique_ptr<QuicEncryptedPacket> data(
+      QuicFramer::BuildVersionNegotiationPacket(
+          server_connection_id, client_connection_id, true, true,
+          SupportedVersions(GetParam())));
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 2 byte largest observed, 2 byte block length)
+      0x45,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 2 byte largest observed, 2 byte block length)
+      0x45,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62TwoBytes + 0x12, 0x34,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // Number of additional ack blocks.
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12, 0x33,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameMultipleRanges) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      // Timestamp Range 3.
+      {kSmallLargestObserved - 22, CreationTimePlus(0x29ffdddd)},
+      {kSmallLargestObserved - 21, CreationTimePlus(0x29ffdedd)},
+      // Timestamp Range 2.
+      {kSmallLargestObserved - 11, CreationTimePlus(0x29ffdeed)},
+      // Timestamp Range 1.
+      {kSmallLargestObserved - 4, CreationTimePlus(0x29ffeeed)},
+      {kSmallLargestObserved - 3, CreationTimePlus(0x29ffeeee)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0x29ffffff)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE,
+      0xDC,
+      0xBA,
+      0x98,
+      0x76,
+      0x54,
+      0x32,
+      0x10,
+      // packet number
+      0x12,
+      0x34,
+      0x56,
+      0x78,
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      0x22,
+      // largest acked
+      kVarInt62TwoBytes + 0x12,
+      0x34,  // = 4660
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // number of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12,
+      0x33,
+
+      // Receive Timestamps.
+
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x03,
+
+      // Timestamp range 1 (three packets).
+      // Gap
+      kVarInt62OneByte + 0x02,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x03,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x29,
+      0xff,
+      0xff,
+      0xff,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x11,
+      0x11,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x01,
+
+      // Timestamp range 2 (one packet).
+      // Gap
+      kVarInt62OneByte + 0x05,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x01,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x10,
+      0x00,
+
+      // Timestamp range 3 (two packets).
+      // Gap
+      kVarInt62OneByte + 0x08,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x10,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x01,
+      0x00,
+  };
+  // clang-format on
+
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameExceedsMaxTimestamps) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      // Timestamp Range 3 (not included because max receive timestamps = 4).
+      {kSmallLargestObserved - 20, CreationTimePlus(0x29ffdddd)},
+      // Timestamp Range 2.
+      {kSmallLargestObserved - 10, CreationTimePlus(0x29ffdedd)},
+      {kSmallLargestObserved - 9, CreationTimePlus(0x29ffdeed)},
+      // Timestamp Range 1.
+      {kSmallLargestObserved - 2, CreationTimePlus(0x29ffeeed)},
+      {kSmallLargestObserved - 1, CreationTimePlus(0x29ffeeee)},
+      {kSmallLargestObserved, CreationTimePlus(0x29ffffff)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE,
+      0xDC,
+      0xBA,
+      0x98,
+      0x76,
+      0x54,
+      0x32,
+      0x10,
+      // packet number
+      0x12,
+      0x34,
+      0x56,
+      0x78,
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      0x22,
+      // largest acked
+      kVarInt62TwoBytes + 0x12,
+      0x34,  // = 4660
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // number of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12,
+      0x33,
+
+      // Receive Timestamps.
+
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+
+      // Timestamp range 1 (three packets).
+      // Gap
+      kVarInt62OneByte + 0x00,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x03,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x29,
+      0xff,
+      0xff,
+      0xff,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x11,
+      0x11,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x01,
+
+      // Timestamp range 2 (one packet).
+      // Gap
+      kVarInt62OneByte + 0x05,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x01,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x10,
+      0x00,
+  };
+  // clang-format on
+
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(4);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAckReceiveTimestampsFrameWithExponentEncoding) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      // Timestamp Range 2.
+      {kSmallLargestObserved - 12, CreationTimePlus((0x06c00 << 3) + 0x03)},
+      {kSmallLargestObserved - 11, CreationTimePlus((0x28e00 << 3) + 0x00)},
+      // Timestamp Range 1.
+      {kSmallLargestObserved - 5, CreationTimePlus((0x29f00 << 3) + 0x00)},
+      {kSmallLargestObserved - 4, CreationTimePlus((0x29f00 << 3) + 0x01)},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x29f00 << 3) + 0x02)},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x29f00 << 3) + 0x03)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE,
+      0xDC,
+      0xBA,
+      0x98,
+      0x76,
+      0x54,
+      0x32,
+      0x10,
+      // packet number
+      0x12,
+      0x34,
+      0x56,
+      0x78,
+
+      // frame type (IETF_ACK_RECEIVE_TIMESTAMPS frame)
+      0x22,
+      // largest acked
+      kVarInt62TwoBytes + 0x12,
+      0x34,  // = 4660
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // number of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x12,
+      0x33,
+
+      // Receive Timestamps.
+
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+
+      // Timestamp range 1 (three packets).
+      // Gap
+      kVarInt62OneByte + 0x02,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x04,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x00,
+      0x02,
+      0x9f,
+      0x01,  // round up
+      // Timestamp Delta
+      kVarInt62OneByte + 0x00,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x00,
+      // Timestamp Delta
+      kVarInt62OneByte + 0x01,
+
+      // Timestamp range 2 (one packet).
+      // Gap
+      kVarInt62OneByte + 0x04,
+      // Timestamp Range Count
+      kVarInt62OneByte + 0x02,
+      // Timestamp Delta
+      kVarInt62TwoBytes + 0x11,
+      0x00,
+      // Timestamp Delta
+      kVarInt62FourBytes + 0x00,
+      0x02,
+      0x21,
+      0xff,
+  };
+  // clang-format on
+
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildAndProcessAckReceiveTimestampsWithMultipleRanges) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+      {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+      {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+      {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+      {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+      {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved, CreationTimePlus(0xabcdef123)},
+                  {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+                  {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+                  {kSmallLargestObserved - 4, CreationTimePlus(0xabcdea125)},
+                  {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+                  {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+                  {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+              }));
+}
+
+TEST_P(QuicFramerTest,
+       BuildAndProcessAckReceiveTimestampsExceedsMaxTimestamps) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(2);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 1201, CreationTimePlus(0x8bcaef234)},
+      {kSmallLargestObserved - 1200, CreationTimePlus(0x8bcdef123)},
+      {kSmallLargestObserved - 1000, CreationTimePlus(0xaacdef123)},
+      {kSmallLargestObserved - 5, CreationTimePlus(0xabcdea125)},
+      {kSmallLargestObserved - 3, CreationTimePlus(0xabcded124)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+      {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 1, CreationTimePlus(0xabcdef123)},
+                  {kSmallLargestObserved - 2, CreationTimePlus(0xabcdee124)},
+              }));
+}
+
+TEST_P(QuicFramerTest,
+       BuildAndProcessAckReceiveTimestampsWithExponentNoTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
+      {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
+      {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
+      {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 3, CreationTimePlus(0x29fe << 3)},
+                  {kSmallLargestObserved - 7, CreationTimePlus(0x29ed << 3)},
+                  {kSmallLargestObserved - 8, CreationTimePlus(0x1add << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest,
+       BuildAndProcessAckReceiveTimestampsWithExponentTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 10, CreationTimePlus((0x1001 << 3) + 1)},
+      {kSmallLargestObserved - 9, CreationTimePlus((0x2995 << 3) - 1)},
+      {kSmallLargestObserved - 8, CreationTimePlus((0x2995 << 3) + 0)},
+      {kSmallLargestObserved - 7, CreationTimePlus((0x2995 << 3) + 1)},
+      {kSmallLargestObserved - 6, CreationTimePlus((0x2995 << 3) + 2)},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x2995 << 3) + 3)},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x2995 << 3) + 4)},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 2, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 3, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 6, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 7, CreationTimePlus(0x2996 << 3)},
+                  {kSmallLargestObserved - 8, CreationTimePlus(0x2995 << 3)},
+                  {kSmallLargestObserved - 9, CreationTimePlus(0x2995 << 3)},
+                  {kSmallLargestObserved - 10, CreationTimePlus(0x1002 << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckReceiveTimestamps) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_THAT(frame.received_packet_times,
+              ContainerEq(PacketTimeVector{
+                  {kSmallLargestObserved - 2, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 3, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 4, CreationTimePlus(0x29ff << 3)},
+                  {kSmallLargestObserved - 5, CreationTimePlus(0x29ff << 3)},
+              }));
+}
+
+TEST_P(QuicFramerTest, AckReceiveTimestampsPacketOutOfOrder) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+
+  // The packet numbers below are out of order, this is impossible because we
+  // don't record out of order packets in received_packet_times. The test is
+  // intended to ensure this error is raised when it happens.
+  ack_frame.received_packet_times = PacketTimeVector{
+      {kSmallLargestObserved - 5, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 2, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 4, CreationTimePlus((0x29ff << 3))},
+      {kSmallLargestObserved - 3, CreationTimePlus((0x29ff << 3))},
+  };
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  EXPECT_QUIC_BUG(BuildDataPacket(header, frames),
+                  "Packet number and/or receive time not in order.");
+}
+
+// If there's insufficient room for IETF ack receive timestamps, don't write any
+// timestamp ranges.
+TEST_P(QuicFramerTest, IetfAckReceiveTimestampsTruncate) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8192);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame = InitAckFrame(kSmallLargestObserved);
+  for (QuicPacketNumber i(1); i <= kSmallLargestObserved; i += 2) {
+    ack_frame.received_packet_times.push_back(
+        {i, CreationTimePlus((0x29ff << 3))});
+  }
+
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+
+  const QuicAckFrame& frame = *visitor_.ack_frames_[0];
+  EXPECT_TRUE(frame.received_packet_times.empty());
+}
+
+// If there are too many ack ranges, they will be truncated to make room for a
+// timestamp range count of 0.
+TEST_P(QuicFramerTest, IetfAckReceiveTimestampsAckRangeTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  framer_.set_process_timestamps(true);
+  framer_.set_max_receive_timestamps_per_ack(8);
+  framer_.set_receive_timestamps_exponent(3);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame;
+  // Create a packet with just the ack.
+  ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
+                                   /*max_num_gaps=*/200,
+                                   /*largest_acked=*/kMaxIetfVarInt);
+  ack_frame.received_packet_times = PacketTimeVector{
+      {QuicPacketNumber(kMaxIetfVarInt) - 2, CreationTimePlus((0x29ff << 3))},
+  };
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+  // Build an ACK packet.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            LargestAcked(processed_ack_frame));
+  // Verify ACK ranges in the frame gets truncated.
+  ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(158u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            processed_ack_frame.packets.Max());
+  // But the receive timestamps are not truncated because they are small.
+  EXPECT_FALSE(processed_ack_frame.received_packet_times.empty());
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(kPacketNumber);
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 4 byte largest observed, 4 byte block length)
+      0x4A,
+      // largest acked
+      0x12, 0x34, 0x56, 0x78,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34, 0x56, 0x78,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (no ack blocks, 4 byte largest observed, 4 byte block length)
+      0x4A,
+      // largest acked
+      0x12, 0x34, 0x56, 0x78,
+      // Zero delta time.
+      0x00, 0x00,
+      // first ack block length.
+      0x12, 0x34, 0x56, 0x78,
+      // num timestamps.
+      0x00,
+  };
+
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // Nr. of additional ack blocks
+      kVarInt62OneByte + 0x00,
+      // first ack block length.
+      kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObserved to make this test finished in a short time.
+  QuicAckFrame ack_frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
+                    {QuicPacketNumber(10), QuicPacketNumber(500)},
+                    {QuicPacketNumber(900), kSmallMissingPacket},
+                    {kSmallMissingPacket + 1, kSmallLargestObserved + 1}});
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0x04,
+      // first ack block length.
+      0x00, 0x01,
+      // gap to next block.
+      0x01,
+      // ack block length.
+      0x0e, 0xaf,
+      // gap to next block.
+      0xff,
+      // ack block length.
+      0x00, 0x00,
+      // gap to next block.
+      0x91,
+      // ack block length.
+      0x01, 0xea,
+      // gap to next block.
+      0x05,
+      // ack block length.
+      0x00, 0x04,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0x04,
+      // first ack block length.
+      0x00, 0x01,
+      // gap to next block.
+      0x01,
+      // ack block length.
+      0x0e, 0xaf,
+      // gap to next block.
+      0xff,
+      // ack block length.
+      0x00, 0x00,
+      // gap to next block.
+      0x91,
+      // ack block length.
+      0x01, 0xea,
+      // gap to next block.
+      0x05,
+      // ack block length.
+      0x00, 0x04,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62TwoBytes + 0x12, 0x34,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // num additional ack blocks.
+      kVarInt62OneByte + 0x03,
+      // first ack block length.
+      kVarInt62OneByte + 0x00,
+
+      // gap to next block.
+      kVarInt62OneByte + 0x00,
+      // ack block length.
+      kVarInt62TwoBytes + 0x0e, 0xae,
+
+      // gap to next block.
+      kVarInt62TwoBytes + 0x01, 0x8f,
+      // ack block length.
+      kVarInt62TwoBytes + 0x01, 0xe9,
+
+      // gap to next block.
+      kVarInt62OneByte + 0x04,
+      // ack block length.
+      kVarInt62OneByte + 0x03,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Use kSmallLargestObservedto make this test finished in a short time.
+  QuicAckFrame ack_frame;
+  ack_frame.largest_acked = kSmallLargestObserved;
+  ack_frame.ack_delay_time = QuicTime::Delta::Zero();
+  // 300 ack blocks.
+  for (size_t i = 2; i < 2 * 300; i += 2) {
+    ack_frame.packets.Add(QuicPacketNumber(i));
+  }
+  ack_frame.packets.AddRange(QuicPacketNumber(600), kSmallLargestObserved + 1);
+
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (8 byte connection_id)
+      0x2C,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0xff,
+      // first ack block length.
+      0x0f, 0xdd,
+      // 255 = 4 * 63 + 3
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet46[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (ack frame)
+      // (has ack blocks, 2 byte largest observed, 2 byte block length)
+      0x65,
+      // largest acked
+      0x12, 0x34,
+      // Zero delta time.
+      0x00, 0x00,
+      // num ack blocks ranges.
+      0xff,
+      // first ack block length.
+      0x0f, 0xdd,
+      // 255 = 4 * 63 + 3
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+      // num timestamps.
+      0x00,
+  };
+
+  unsigned char packet_ietf[] = {
+      // type (short header, 4 byte packet number)
+      0x43,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_ACK frame)
+      0x02,
+      // largest acked
+      kVarInt62TwoBytes + 0x12, 0x34,
+      // Zero delta time.
+      kVarInt62OneByte + 0x00,
+      // num ack blocks ranges.
+      kVarInt62TwoBytes + 0x01, 0x2b,
+      // first ack block length.
+      kVarInt62TwoBytes + 0x0f, 0xdc,
+      // 255 added blocks of gap_size == 1, ack_size == 1
+#define V99AddedBLOCK kVarInt62OneByte + 0x00, kVarInt62OneByte + 0x00
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+      V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK, V99AddedBLOCK,
+
+#undef V99AddedBLOCK
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStopWaitingFrame stop_waiting_frame;
+  stop_waiting_frame.least_unacked = kLeastUnacked;
+
+  QuicFrames frames = {QuicFrame(stop_waiting_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stop waiting frame)
+    0x06,
+    // least packet number awaiting an ack, delta from packet number.
+    0x00, 0x00, 0x00, 0x08,
+  };
+
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicRstStreamFrame rst_frame;
+  rst_frame.stream_id = kStreamId;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    rst_frame.ietf_error_code = 0x01;
+  } else {
+    rst_frame.error_code = static_cast<QuicRstStreamErrorCode>(0x05060708);
+  }
+  rst_frame.byte_offset = 0x0807060504030201;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (rst stream frame)
+    0x01,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // sent byte offset
+    0x08, 0x07, 0x06, 0x05,
+    0x04, 0x03, 0x02, 0x01,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+  };
+
+  unsigned char packet46[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (rst stream frame)
+    0x01,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // sent byte offset
+    0x08, 0x07, 0x06, 0x05,
+    0x04, 0x03, 0x02, 0x01,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_RST_STREAM frame)
+    0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // error code
+    kVarInt62OneByte + 0x01,
+    // sent byte offset
+    kVarInt62EightBytes + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
+  };
+  // clang-format on
+
+  QuicFrames frames = {QuicFrame(&rst_frame)};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildCloseFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame close_frame(framer_.transport_version(),
+                                       QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
+                                       "because I can", 0x05);
+  QuicFrames frames = {QuicFrame(&close_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CONNECTION_CLOSE frame)
+    0x1c,
+    // error code
+    kVarInt62OneByte + 0x01,
+    // Frame type within the CONNECTION_CLOSE frame
+    kVarInt62OneByte + 0x05,
+    // error details length
+    kVarInt62OneByte + 0x0f,
+    // error details
+    '1',  ':',  'b',  'e',
+    'c',  'a',  'u',  's',
+    'e',  ' ',  'I',  ' ',
+    'c',  'a',  'n',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildCloseFramePacketExtendedInfo) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame close_frame(
+      framer_.transport_version(),
+      static_cast<QuicErrorCode>(
+          VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x01
+                                                                : 0x05060708),
+      NO_IETF_QUIC_ERROR, "because I can", 0x05);
+  // Set this so that it is "there" for both Google QUIC and IETF QUIC
+  // framing. It better not show up for Google QUIC!
+  close_frame.quic_error_code = static_cast<QuicErrorCode>(0x4567);
+
+  QuicFrames frames = {QuicFrame(&close_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CONNECTION_CLOSE frame)
+    0x1c,
+    // IETF error code INTERNAL_ERROR = 0x01 corresponding to
+    // QuicErrorCode::QUIC_INTERNAL_ERROR = 0x01.
+    kVarInt62OneByte + 0x01,
+    // Frame type within the CONNECTION_CLOSE frame
+    kVarInt62OneByte + 0x05,
+    // error details length
+    kVarInt62OneByte + 0x13,
+    // error details
+    '1',  '7',  '7',  '6',
+    '7',  ':',  'b',  'e',
+    'c',  'a',  'u',  's',
+    'e',  ' ',  'I',  ' ',
+    'c',  'a',  'n'
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame close_frame(framer_.transport_version(),
+                                       QUIC_INTERNAL_ERROR, NO_IETF_QUIC_ERROR,
+                                       std::string(2048, 'A'), 0x05);
+  QuicFrames frames = {QuicFrame(&close_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (connection close frame)
+    0x02,
+    // error code
+    0x00, 0x00, 0x00, 0x01,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_CONNECTION_CLOSE frame)
+    0x1c,
+    // error code
+    kVarInt62OneByte + 0x01,
+    // Frame type within the CONNECTION_CLOSE frame
+    kVarInt62OneByte + 0x05,
+    // error details length
+    kVarInt62TwoBytes + 0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    '1',  ':',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildApplicationCloseFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame app_close_frame;
+  app_close_frame.wire_error_code = 0x11;
+  app_close_frame.error_details = "because I can";
+  app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
+
+  QuicFrames frames = {QuicFrame(&app_close_frame)};
+
+  // clang-format off
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_APPLICATION_CLOSE frame)
+    0x1d,
+    // error code
+    kVarInt62OneByte + 0x11,
+    // error details length
+    kVarInt62OneByte + 0x0f,
+    // error details, note that it includes an extended error code.
+    '0',  ':',  'b',  'e',
+    'c',  'a',  'u',  's',
+    'e',  ' ',  'I',  ' ',
+    'c',  'a',  'n',
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedApplicationCloseFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicConnectionCloseFrame app_close_frame;
+  app_close_frame.wire_error_code = 0x11;
+  app_close_frame.error_details = std::string(2048, 'A');
+  app_close_frame.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE;
+  // Setting to missing ensures that if it is missing, the extended
+  // code is not added to the text message.
+  app_close_frame.quic_error_code = QUIC_IETF_GQUIC_ERROR_MISSING;
+
+  QuicFrames frames = {QuicFrame(&app_close_frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_APPLICATION_CLOSE frame)
+    0x1d,
+    // error code
+    kVarInt62OneByte + 0x11,
+    // error details length
+    kVarInt62TwoBytes + 0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildGoAwayPacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for Google QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicGoAwayFrame goaway_frame;
+  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
+  goaway_frame.last_good_stream_id = kStreamId;
+  goaway_frame.reason_phrase = "because I can";
+
+  QuicFrames frames = {QuicFrame(&goaway_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x00, 0x0d,
+    // error details
+    'b',  'e',  'c',  'a',
+    'u',  's',  'e',  ' ',
+    'I',  ' ',  'c',  'a',
+    'n',
+  };
+
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for Google QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicGoAwayFrame goaway_frame;
+  goaway_frame.error_code = static_cast<QuicErrorCode>(0x05060708);
+  goaway_frame.last_good_stream_id = kStreamId;
+  goaway_frame.reason_phrase = std::string(2048, 'A');
+
+  QuicFrames frames = {QuicFrame(&goaway_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (go away frame)
+    0x03,
+    // error code
+    0x05, 0x06, 0x07, 0x08,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // error details length
+    0x01, 0x00,
+    // error details (truncated to 256 bytes)
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+    'A',  'A',  'A',  'A',  'A',  'A',  'A',  'A',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicWindowUpdateFrame window_update_frame;
+  window_update_frame.stream_id = kStreamId;
+  window_update_frame.max_data = 0x1122334455667788;
+
+  QuicFrames frames = {QuicFrame(window_update_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (window update frame)
+    0x04,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (window update frame)
+    0x04,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAM_DATA frame)
+    0x11,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildMaxStreamDataPacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicWindowUpdateFrame window_update_frame;
+  window_update_frame.stream_id = kStreamId;
+  window_update_frame.max_data = 0x1122334455667788;
+
+  QuicFrames frames = {QuicFrame(window_update_frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAM_DATA frame)
+    0x11,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // byte offset
+    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildMaxDataPacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicWindowUpdateFrame window_update_frame;
+  window_update_frame.stream_id =
+      QuicUtils::GetInvalidStreamId(framer_.transport_version());
+  window_update_frame.max_data = 0x1122334455667788;
+
+  QuicFrames frames = {QuicFrame(window_update_frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_DATA frame)
+    0x10,
+    // byte offset
+    kVarInt62EightBytes + 0x11, 0x22, 0x33, 0x44,
+    0x55, 0x66, 0x77, 0x88,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildBlockedPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicBlockedFrame blocked_frame;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // For IETF QUIC, the stream ID must be <invalid> for the frame
+    // to be a BLOCKED frame. if it's valid, it will be a
+    // STREAM_BLOCKED frame.
+    blocked_frame.stream_id =
+        QuicUtils::GetInvalidStreamId(framer_.transport_version());
+  } else {
+    blocked_frame.stream_id = kStreamId;
+  }
+  blocked_frame.offset = kStreamOffset;
+
+  QuicFrames frames = {QuicFrame(blocked_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (blocked frame)
+    0x05,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+  };
+
+  unsigned char packet46[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (blocked frame)
+    0x05,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short packet, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_DATA_BLOCKED frame)
+    0x14,
+    // Offset
+    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p), p_size);
+}
+
+TEST_P(QuicFramerTest, BuildPingPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPingFrame())};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ping frame)
+    0x07,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type
+    0x07,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PING frame)
+    0x01,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildHandshakeDonePacket) {
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicHandshakeDoneFrame())};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (Handshake done frame)
+    0x1e,
+  };
+  // clang-format on
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildAckFrequencyPacket) {
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrequencyFrame ack_frequency_frame;
+  ack_frequency_frame.sequence_number = 3;
+  ack_frequency_frame.packet_tolerance = 5;
+  ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMicroseconds(0x3fff);
+  ack_frequency_frame.ignore_order = false;
+  QuicFrames frames = {QuicFrame(&ack_frequency_frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (Ack Frequency frame)
+    0x40, 0xaf,
+    // sequence number
+    0x03,
+    // packet tolerance
+    0x05,
+    // max_ack_delay_us
+    0x7f, 0xff,
+    // ignore_oder
+    0x00
+  };
+  // clang-format on
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildMessagePacket) {
+  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicMessageFrame frame(1, MemSliceFromString("message"));
+  QuicMessageFrame frame2(2, MemSliceFromString("message2"));
+  QuicFrames frames = {QuicFrame(&frame), QuicFrame(&frame2)};
+
+  // clang-format off
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (message frame)
+    0x21,
+    // Length
+    0x07,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e',
+    // frame type (message frame no length)
+    0x20,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e', '2'
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MESSAGE frame)
+    0x31,
+    // Length
+    0x07,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e',
+    // frame type (message frame no length)
+    0x30,
+    // Message Data
+    'm', 'e', 's', 's', 'a', 'g', 'e', '2'
+  };
+  // clang-format on
+
+  unsigned char* p = packet46;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  }
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      ABSL_ARRAYSIZE(packet46));
+}
+
+// Test that the MTU discovery packet is serialized correctly as a PING packet.
+TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicMtuDiscoveryFrame())};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ping frame)
+    0x07,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type
+    0x07,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PING frame)
+    0x01,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  unsigned char* p = packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(p),
+      framer_.version().HasIetfInvariantHeader() ? ABSL_ARRAYSIZE(packet46)
+                                                 : ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPublicResetPacket) {
+  QuicPublicResetPacket reset_packet;
+  reset_packet.connection_id = FramerTestConnectionId();
+  reset_packet.nonce_proof = kNonceProof;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (public reset, 8 byte ConnectionId)
+    0x0E,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // message tag (kPRST)
+    'P', 'R', 'S', 'T',
+    // num_entries (1) + padding
+    0x01, 0x00, 0x00, 0x00,
+    // tag kRNON
+    'R', 'N', 'O', 'N',
+    // end offset 8
+    0x08, 0x00, 0x00, 0x00,
+    // nonce proof
+    0x89, 0x67, 0x45, 0x23,
+    0x01, 0xEF, 0xCD, 0xAB,
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildPublicResetPacket(reset_packet));
+  ASSERT_TRUE(data != nullptr);
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
+  QuicPublicResetPacket reset_packet;
+  reset_packet.connection_id = FramerTestConnectionId();
+  reset_packet.nonce_proof = kNonceProof;
+  reset_packet.client_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), 0x1234);
+
+  // clang-format off
+  unsigned char packet[] = {
+      // public flags (public reset, 8 byte ConnectionId)
+      0x0E,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98,
+      0x76, 0x54, 0x32, 0x10,
+      // message tag (kPRST)
+      'P', 'R', 'S', 'T',
+      // num_entries (2) + padding
+      0x02, 0x00, 0x00, 0x00,
+      // tag kRNON
+      'R', 'N', 'O', 'N',
+      // end offset 8
+      0x08, 0x00, 0x00, 0x00,
+      // tag kCADR
+      'C', 'A', 'D', 'R',
+      // end offset 16
+      0x10, 0x00, 0x00, 0x00,
+      // nonce proof
+      0x89, 0x67, 0x45, 0x23,
+      0x01, 0xEF, 0xCD, 0xAB,
+      // client address
+      0x02, 0x00,
+      0x7F, 0x00, 0x00, 0x01,
+      0x34, 0x12,
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildPublicResetPacket(reset_packet));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, BuildPublicResetPacketWithEndpointId) {
+  QuicPublicResetPacket reset_packet;
+  reset_packet.connection_id = FramerTestConnectionId();
+  reset_packet.nonce_proof = kNonceProof;
+  reset_packet.endpoint_id = "FakeServerId";
+
+  // The tag value map in CryptoHandshakeMessage is a std::map, so the two tags
+  // in the packet, kRNON and kEPID, have unspecified ordering w.r.t each other.
+  // clang-format off
+  unsigned char packet_variant1[] = {
+      // public flags (public reset, 8 byte ConnectionId)
+      0x0E,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98,
+      0x76, 0x54, 0x32, 0x10,
+      // message tag (kPRST)
+      'P', 'R', 'S', 'T',
+      // num_entries (2) + padding
+      0x02, 0x00, 0x00, 0x00,
+      // tag kRNON
+      'R', 'N', 'O', 'N',
+      // end offset 8
+      0x08, 0x00, 0x00, 0x00,
+      // tag kEPID
+      'E', 'P', 'I', 'D',
+      // end offset 20
+      0x14, 0x00, 0x00, 0x00,
+      // nonce proof
+      0x89, 0x67, 0x45, 0x23,
+      0x01, 0xEF, 0xCD, 0xAB,
+      // Endpoint ID
+      'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
+  };
+  unsigned char packet_variant2[] = {
+      // public flags (public reset, 8 byte ConnectionId)
+      0x0E,
+      // connection_id
+      0xFE, 0xDC, 0xBA, 0x98,
+      0x76, 0x54, 0x32, 0x10,
+      // message tag (kPRST)
+      'P', 'R', 'S', 'T',
+      // num_entries (2) + padding
+      0x02, 0x00, 0x00, 0x00,
+      // tag kEPID
+      'E', 'P', 'I', 'D',
+      // end offset 12
+      0x0C, 0x00, 0x00, 0x00,
+      // tag kRNON
+      'R', 'N', 'O', 'N',
+      // end offset 20
+      0x14, 0x00, 0x00, 0x00,
+      // Endpoint ID
+      'F', 'a', 'k', 'e', 'S', 'e', 'r', 'v', 'e', 'r', 'I', 'd',
+      // nonce proof
+      0x89, 0x67, 0x45, 0x23,
+      0x01, 0xEF, 0xCD, 0xAB,
+  };
+  // clang-format on
+
+  if (framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildPublicResetPacket(reset_packet));
+  ASSERT_TRUE(data != nullptr);
+
+  // Variant 1 ends with char 'd'. Variant 1 ends with char 0xAB.
+  if ('d' == data->data()[data->length() - 1]) {
+    quiche::test::CompareCharArraysWithHexError(
+        "constructed packet", data->data(), data->length(),
+        AsChars(packet_variant1), ABSL_ARRAYSIZE(packet_variant1));
+  } else {
+    quiche::test::CompareCharArraysWithHexError(
+        "constructed packet", data->data(), data->length(),
+        AsChars(packet_variant2), ABSL_ARRAYSIZE(packet_variant2));
+  }
+}
+
+TEST_P(QuicFramerTest, BuildIetfStatelessResetPacket) {
+  // clang-format off
+    unsigned char packet[] = {
+      // 1st byte 01XX XXXX
+      0x40,
+      // At least 4 bytes of random bytes.
+      0x00, 0x00, 0x00, 0x00,
+      // stateless reset token
+      0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+      0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f
+    };
+  // clang-format on
+
+  // Build the minimal stateless reset packet.
+  std::unique_ptr<QuicEncryptedPacket> data(
+      framer_.BuildIetfStatelessResetPacket(
+          FramerTestConnectionId(),
+          QuicFramer::GetMinStatelessResetPacketLength() + 1,
+          kTestStatelessResetToken));
+  ASSERT_TRUE(data);
+  EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength(), data->length());
+  // Verify the first 2 bits are 01.
+  EXPECT_FALSE(data->data()[0] & FLAGS_LONG_HEADER);
+  EXPECT_TRUE(data->data()[0] & FLAGS_FIXED_BIT);
+  // Verify stateless reset token.
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet",
+      data->data() + data->length() - kStatelessResetTokenLength,
+      kStatelessResetTokenLength,
+      AsChars(packet) + ABSL_ARRAYSIZE(packet) - kStatelessResetTokenLength,
+      kStatelessResetTokenLength);
+
+  // Packets with length <= minimal stateless reset does not trigger stateless
+  // reset.
+  std::unique_ptr<QuicEncryptedPacket> data2(
+      framer_.BuildIetfStatelessResetPacket(
+          FramerTestConnectionId(),
+          QuicFramer::GetMinStatelessResetPacketLength(),
+          kTestStatelessResetToken));
+  ASSERT_FALSE(data2);
+
+  // Do not send stateless reset >= minimal stateless reset + 1 + max
+  // connection ID length.
+  std::unique_ptr<QuicEncryptedPacket> data3(
+      framer_.BuildIetfStatelessResetPacket(FramerTestConnectionId(), 1000,
+                                            kTestStatelessResetToken));
+  ASSERT_TRUE(data3);
+  EXPECT_EQ(QuicFramer::GetMinStatelessResetPacketLength() + 1 +
+                kQuicMaxConnectionIdWithLengthPrefixLength,
+            data3->length());
+}
+
+TEST_P(QuicFramerTest, EncryptPacket) {
+  QuicPacketNumber packet_number = kPacketNumber;
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet50[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+    'q',  'r',  's',  't',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasHeaderProtection()) {
+    p = packet50;
+    p_size = ABSL_ARRAYSIZE(packet50);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  std::unique_ptr<QuicPacket> raw(new QuicPacket(
+      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = framer_.EncryptPayload(
+      ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
+
+  ASSERT_NE(0u, encrypted_length);
+  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
+}
+
+// Regression test for b/158014497.
+TEST_P(QuicFramerTest, EncryptEmptyPacket) {
+  auto packet = std::make_unique<QuicPacket>(
+      new char[100], 0, true, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID,
+      /*includes_version=*/true,
+      /*includes_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0,
+      /*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = 1;
+  EXPECT_QUIC_BUG(encrypted_length = framer_.EncryptPayload(
+                      ENCRYPTION_INITIAL, kPacketNumber, *packet, buffer,
+                      kMaxOutgoingPacketSize),
+                  "packet is shorter than associated data length");
+  EXPECT_EQ(0u, encrypted_length);
+}
+
+TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketNumber packet_number = kPacketNumber;
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version, 8 byte connection_id)
+    0x29,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // version tag
+    'Q', '.', '1', '0',
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet46[] = {
+    // type (long header with packet type ZERO_RTT_PROTECTED)
+    0xD3,
+    // version tag
+    'Q', '.', '1', '0',
+    // connection_id length
+    0x50,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+  };
+
+  unsigned char packet50[] = {
+    // type (long header with packet type ZERO_RTT_PROTECTED)
+    0xD3,
+    // version tag
+    'Q', '.', '1', '0',
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // redundancy
+    'a',  'b',  'c',  'd',
+    'e',  'f',  'g',  'h',
+    'i',  'j',  'k',  'l',
+    'm',  'n',  'o',  'p',
+    'q',  'r',  's',  't',
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  // TODO(ianswett): see todo in previous test.
+  if (framer_.version().HasHeaderProtection()) {
+    p = packet50;
+    p_size = ABSL_ARRAYSIZE(packet50);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<QuicPacket> raw(new QuicPacket(
+      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+      PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
+      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length = framer_.EncryptPayload(
+      ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
+
+  ASSERT_NE(0u, encrypted_length);
+  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
+}
+
+TEST_P(QuicFramerTest, AckTruncationLargePacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This test is not applicable to this version; the range count is
+    // effectively unlimited
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame;
+  // Create a packet with just the ack.
+  ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // Build an ack packet with truncation due to limit in number of nack ranges.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
+  ASSERT_EQ(256u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(90u), processed_ack_frame.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
+}
+
+// Regression test for b/150386368.
+TEST_P(QuicFramerTest, IetfAckFrameTruncation) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame;
+  // Create a packet with just the ack.
+  ack_frame = MakeAckFrameWithGaps(/*gap_size=*/0xffffffff,
+                                   /*max_num_gaps=*/200,
+                                   /*largest_acked=*/kMaxIetfVarInt);
+  ack_frame.ecn_counters_populated = true;
+  ack_frame.ect_0_count = 100;
+  ack_frame.ect_1_count = 10000;
+  ack_frame.ecn_ce_count = 1000000;
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+  // Build an ACK packet.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            LargestAcked(processed_ack_frame));
+  // Verify ACK frame gets truncated.
+  ASSERT_LT(processed_ack_frame.packets.NumPacketsSlow(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(157u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_LT(processed_ack_frame.packets.NumIntervals(),
+            ack_frame.packets.NumIntervals());
+  EXPECT_EQ(QuicPacketNumber(kMaxIetfVarInt),
+            processed_ack_frame.packets.Max());
+}
+
+TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This test is not applicable to this version; the range count is
+    // effectively unlimited
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // Create a packet with just the ack.
+  QuicAckFrame ack_frame;
+  ack_frame = MakeAckFrameWithAckBlocks(300, 0u);
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+
+  // Build an ack packet with truncation due to limit in number of nack ranges.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(
+      BuildDataPacket(header, frames, 500));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
+  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
+  ASSERT_EQ(240u, processed_ack_frame.packets.NumPacketsSlow());
+  EXPECT_EQ(QuicPacketNumber(122u), processed_ack_frame.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
+}
+
+TEST_P(QuicFramerTest, CleanTruncation) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This test is not applicable to this version; the range count is
+    // effectively unlimited
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicAckFrame ack_frame = InitAckFrame(201);
+
+  // Create a packet with just the ack.
+  QuicFrames frames = {QuicFrame(&ack_frame)};
+  if (framer_.version().HasHeaderProtection()) {
+    frames.push_back(QuicFrame(QuicPaddingFrame(12)));
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> raw_ack_packet(BuildDataPacket(header, frames));
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+
+  char buffer[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number,
+                             *raw_ack_packet, buffer, kMaxOutgoingPacketSize);
+  ASSERT_NE(0u, encrypted_length);
+
+  // Now make sure we can turn our ack packet back into an ack frame.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  ASSERT_TRUE(framer_.ProcessPacket(
+      QuicEncryptedPacket(buffer, encrypted_length, false)));
+
+  // Test for clean truncation of the ack by comparing the length of the
+  // original packets to the re-serialized packets.
+  frames.clear();
+  frames.push_back(QuicFrame(visitor_.ack_frames_[0].get()));
+  if (framer_.version().HasHeaderProtection()) {
+    frames.push_back(QuicFrame(*visitor_.padding_frames_[0].get()));
+  }
+
+  size_t original_raw_length = raw_ack_packet->length();
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  raw_ack_packet = BuildDataPacket(header, frames);
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+  EXPECT_EQ(original_raw_length, raw_ack_packet->length());
+  ASSERT_TRUE(raw_ack_packet != nullptr);
+}
+
+TEST_P(QuicFramerTest, StopPacketProcessing) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+
+    // frame type (ack frame)
+    0x40,
+    // least packet number awaiting an ack
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xA0,
+    // largest observed packet number
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBF,
+    // num missing packets
+    0x01,
+    // missing packet
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBE,
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (stream frame with fin)
+    0xFF,
+    // stream id
+    0x01, 0x02, 0x03, 0x04,
+    // offset
+    0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+
+    // frame type (ack frame)
+    0x40,
+    // least packet number awaiting an ack
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xA0,
+    // largest observed packet number
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBF,
+    // num missing packets
+    0x01,
+    // missing packet
+    0x12, 0x34, 0x56, 0x78,
+    0x9A, 0xBE,
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAM frame with fin, length, and offset bits set)
+    0x08 | 0x01 | 0x02 | 0x04,
+    // stream id
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // offset
+    kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+    0x32, 0x10, 0x76, 0x54,
+    // data length
+    kVarInt62TwoBytes + 0x00, 0x0c,
+    // data
+    'h',  'e',  'l',  'l',
+    'o',  ' ',  'w',  'o',
+    'r',  'l',  'd',  '!',
+
+    // frame type (ack frame)
+    0x0d,
+    // largest observed packet number
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
+    // Delta time
+    kVarInt62OneByte + 0x00,
+    // Ack Block count
+    kVarInt62OneByte + 0x01,
+    // First block size (one packet)
+    kVarInt62OneByte + 0x00,
+
+    // Next gap size & ack. Missing all preceding packets
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
+    kVarInt62OneByte + 0x00,
+  };
+  // clang-format on
+
+  MockFramerVisitor visitor;
+  framer_.set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnPacket());
+  EXPECT_CALL(visitor, OnPacketHeader(_));
+  EXPECT_CALL(visitor, OnStreamFrame(_)).WillOnce(Return(false));
+  EXPECT_CALL(visitor, OnPacketComplete());
+  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_)).WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_)).WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnDecryptedPacket(_, _));
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+}
+
+static char kTestString[] = "At least 20 characters.";
+static QuicStreamId kTestQuicStreamId = 1;
+
+MATCHER_P(ExpectedStreamFrame, version, "") {
+  return (arg.stream_id == kTestQuicStreamId ||
+          QuicUtils::IsCryptoStreamId(version.transport_version,
+                                      arg.stream_id)) &&
+         !arg.fin && arg.offset == 0 &&
+         std::string(arg.data_buffer, arg.data_length) == kTestString;
+  // FIN is hard-coded false in ConstructEncryptedPacket.
+  // Offset 0 is hard-coded in ConstructEncryptedPacket.
+}
+
+// Verify that the packet returned by ConstructEncryptedPacket() can be properly
+// parsed by the framer.
+TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
+  // Since we are using ConstructEncryptedPacket, we have to set the framer's
+  // crypto to be Null.
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(framer_.perspective()));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 framer_.perspective()));
+  }
+  ParsedQuicVersionVector versions;
+  versions.push_back(framer_.version());
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      TestConnectionId(), EmptyQuicConnectionId(), false, false,
+      kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &versions));
+
+  MockFramerVisitor visitor;
+  framer_.set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnPacket()).Times(1);
+  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1).WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
+  EXPECT_CALL(visitor, OnError(_)).Times(0);
+  EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
+  if (!QuicVersionUsesCryptoFrames(framer_.version().transport_version)) {
+    EXPECT_CALL(visitor, OnStreamFrame(ExpectedStreamFrame(framer_.version())))
+        .Times(1);
+  } else {
+    EXPECT_CALL(visitor, OnCryptoFrame(_)).Times(1);
+  }
+  EXPECT_CALL(visitor, OnPacketComplete()).Times(1);
+
+  EXPECT_TRUE(framer_.ProcessPacket(*packet));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+}
+
+// Verify that the packet returned by ConstructMisFramedEncryptedPacket()
+// does cause the framer to return an error.
+TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
+  // Since we are using ConstructEncryptedPacket, we have to set the framer's
+  // crypto to be Null.
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(framer_.perspective()));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_INITIAL, std::make_unique<NullDecrypter>(
+                                                 framer_.perspective()));
+  }
+  framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                       std::make_unique<NullEncrypter>(framer_.perspective()));
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
+      TestConnectionId(), EmptyQuicConnectionId(), false, false,
+      kTestQuicStreamId, kTestString, CONNECTION_ID_PRESENT,
+      CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, framer_.version(),
+      Perspective::IS_CLIENT));
+
+  MockFramerVisitor visitor;
+  framer_.set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnPacket()).Times(1);
+  EXPECT_CALL(visitor, OnUnauthenticatedPublicHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnUnauthenticatedHeader(_))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(visitor, OnPacketHeader(_)).Times(1);
+  EXPECT_CALL(visitor, OnDecryptedPacket(_, _)).Times(1);
+  EXPECT_CALL(visitor, OnError(_)).Times(1);
+  EXPECT_CALL(visitor, OnStreamFrame(_)).Times(0);
+  EXPECT_CALL(visitor, OnPacketComplete()).Times(0);
+
+  EXPECT_FALSE(framer_.ProcessPacket(*packet));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+}
+
+TEST_P(QuicFramerTest, IetfBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_DATA_BLOCKED)
+      {"",
+       {0x14}},
+      // blocked offset
+      {"Can not read blocked offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicBlockedFrame frame;
+  frame.stream_id = QuicUtils::GetInvalidStreamId(framer_.transport_version());
+  frame.offset = kStreamOffset;
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_DATA_BLOCKED)
+    0x14,
+    // Offset
+    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, IetfStreamBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAM_DATA_BLOCKED)
+      {"",
+       {0x15}},
+      // blocked offset
+      {"Unable to read IETF_STREAM_DATA_BLOCKED frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      {"Can not read stream blocked offset.",
+       {kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.blocked_frame_.stream_id);
+  EXPECT_EQ(kStreamOffset, visitor_.blocked_frame_.offset);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STREAM_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfStreamBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicBlockedFrame frame;
+  frame.stream_id = kStreamId;
+  frame.offset = kStreamOffset;
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAM_DATA_BLOCKED)
+    0x15,
+    // Stream ID
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // Offset
+    kVarInt62EightBytes + 0x3a, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BiDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+      {"",
+       {0x12}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_BIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, UniDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // Test runs in client mode, no connection id
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+      {"",
+       {0x13}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+      {"",
+       {0x13}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // Test runs in client mode, no connection id
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+      {"",
+       {0x13}},
+      // max. streams
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+// The following four tests ensure that the framer can deserialize a stream
+// count that is large enough to cause the resulting stream ID to exceed the
+// current implementation limit(32 bits). The intent is that when this happens,
+// the stream limit is pegged to the maximum supported value. There are four
+// tests, for the four combinations of uni- and bi-directional, server- and
+// client- initiated.
+TEST_P(QuicFramerTest, BiDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+    0x12,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
+}
+
+TEST_P(QuicFramerTest, ClientBiDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // Test runs in client mode, no connection id
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+    0x12,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_FALSE(visitor_.max_streams_frame_.unidirectional);
+}
+
+TEST_P(QuicFramerTest, ServerUniDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL)
+    0x13,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+}
+
+TEST_P(QuicFramerTest, ClientUniDiMaxStreamsFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // Test runs in client mode, no connection id
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_UNDIRECTIONAL)
+    0x13,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0x40000000u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+}
+
+// Specifically test that count==0 is accepted.
+TEST_P(QuicFramerTest, MaxStreamsFrameZeroCount) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL)
+    0x12,
+    // max. streams == 0.
+    kVarInt62OneByte + 0x00
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+}
+
+TEST_P(QuicFramerTest, ServerBiDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
+      {"",
+       {0x13}},
+      // stream count
+      {"Unable to read IETF_MAX_STREAMS_UNIDIRECTIONAL frame stream id/count.",
+       {kVarInt62OneByte + 0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.max_streams_frame_.stream_count);
+  EXPECT_TRUE(visitor_.max_streams_frame_.unidirectional);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_MAX_STREAMS_DATA);
+}
+
+TEST_P(QuicFramerTest, BiDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
+      {"",
+       {0x16}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_BIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_FALSE(visitor_.streams_blocked_frame_.unidirectional);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, UniDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+      {"",
+       {0x17}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, ClientUniDiStreamsBlockedFrame) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // Test runs in client mode, no connection id
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+      {"",
+       {0x17}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x03}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_0BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(3u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+// Check that when we get a STREAMS_BLOCKED frame that specifies too large
+// a stream count, we reject with an appropriate error. There is no need to
+// check for different combinations of Uni/Bi directional and client/server
+// initiated; the logic does not take these into account.
+TEST_P(QuicFramerTest, StreamsBlockedFrameTooBig) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // Test runs in client mode, no connection id
+    // packet number
+    0x12, 0x34, 0x9A, 0xBC,
+    // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL)
+    0x16,
+
+    // max. streams. Max stream ID allowed is 0xffffffff
+    // This encodes a count of 0x40000000, leading to stream
+    // IDs in the range 0x1 00000000 to 0x1 00000003.
+    kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet_ietf),
+                                ABSL_ARRAYSIZE(packet_ietf), false);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_STREAMS_BLOCKED_DATA));
+  EXPECT_EQ(framer_.detailed_error(),
+            "STREAMS_BLOCKED stream count exceeds implementation limit.");
+}
+
+// Specifically test that count==0 is accepted.
+TEST_P(QuicFramerTest, StreamsBlockedFrameZeroCount) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+      {"",
+       {0x17}},
+      // stream id
+      {"Unable to read IETF_STREAMS_BLOCKED_UNIDIRECTIONAL "
+       "frame stream id/count.",
+       {kVarInt62OneByte + 0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.streams_blocked_frame_.stream_count);
+  EXPECT_TRUE(visitor_.streams_blocked_frame_.unidirectional);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_STREAMS_BLOCKED_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildBiDiStreamsBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStreamsBlockedFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = false;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAMS_BLOCKED_BIDIRECTIONAL frame)
+    0x16,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildUniStreamsBlockedPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStreamsBlockedFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = true;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STREAMS_BLOCKED_UNIDIRECTIONAL frame)
+    0x17,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildBiDiMaxStreamsPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicMaxStreamsFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = false;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAMS_BIDIRECTIONAL frame)
+    0x12,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, BuildUniDiMaxStreamsPacket) {
+  // This frame is only for IETF QUIC.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  // This test runs in client mode.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicMaxStreamsFrame frame;
+  frame.stream_count = 3;
+  frame.unidirectional = true;
+
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_MAX_STREAMS_UNIDIRECTIONAL frame)
+    0x13,
+    // Stream count
+    kVarInt62OneByte + 0x03
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, NewConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // error code
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x09}},
+      {"Unable to read new connection ID frame connection id.",
+       {0x08}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
+      {"Can not read new connection ID frame reset token.",
+       {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+        0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(FramerTestConnectionIdPlusOne(),
+            visitor_.new_connection_id_.connection_id);
+  EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
+  EXPECT_EQ(0x09u, visitor_.new_connection_id_.retire_prior_to);
+  EXPECT_EQ(kTestStatelessResetToken,
+            visitor_.new_connection_id_.stateless_reset_token);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+}
+
+TEST_P(QuicFramerTest, NewConnectionIdFrameVariableLength) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // error code
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x0a}},
+      {"Unable to read new connection ID frame connection id.",
+       {0x09}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      {"Can not read new connection ID frame reset token.",
+       {0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+        0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(FramerTestConnectionIdNineBytes(),
+            visitor_.new_connection_id_.connection_id);
+  EXPECT_EQ(0x11u, visitor_.new_connection_id_.sequence_number);
+  EXPECT_EQ(0x0au, visitor_.new_connection_id_.retire_prior_to);
+  EXPECT_EQ(kTestStatelessResetToken,
+            visitor_.new_connection_id_.stateless_reset_token);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_NEW_CONNECTION_ID_DATA);
+}
+
+// Verifies that parsing a NEW_CONNECTION_ID frame with a length above the
+// specified maximum fails.
+TEST_P(QuicFramerTest, InvalidLongNewConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // The NEW_CONNECTION_ID frame is only for IETF QUIC.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // error code
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x0b}},
+      {"Unable to read new connection ID frame connection id.",
+       {0x40}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
+        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
+        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E,
+        0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+        0xF0, 0xD2, 0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E}},
+      {"Can not read new connection ID frame reset token.",
+       {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
+  EXPECT_EQ("Invalid new connection ID length for version.",
+            framer_.detailed_error());
+}
+
+// Verifies that parsing a NEW_CONNECTION_ID frame with an invalid
+// retire-prior-to fails.
+TEST_P(QuicFramerTest, InvalidRetirePriorToNewConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_CONNECTION_ID frame)
+      {"",
+       {0x18}},
+      // sequence number
+      {"Unable to read new connection ID frame sequence number.",
+       {kVarInt62OneByte + 0x11}},
+      {"Unable to read new connection ID frame retire_prior_to.",
+       {kVarInt62OneByte + 0x1b}},
+      {"Unable to read new connection ID frame connection id length.",
+       {0x08}},  // connection ID length
+      {"Unable to read new connection ID frame connection id.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11}},
+      {"Can not read new connection ID frame reset token.",
+       {0xb5, 0x69, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_NEW_CONNECTION_ID_DATA));
+  EXPECT_EQ("Retire_prior_to > sequence_number.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, BuildNewConnectionIdFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicNewConnectionIdFrame frame;
+  frame.sequence_number = 0x11;
+  frame.retire_prior_to = 0x0c;
+  // Use this value to force a 4-byte encoded variable length connection ID
+  // in the frame.
+  frame.connection_id = FramerTestConnectionIdPlusOne();
+  frame.stateless_reset_token = kTestStatelessResetToken;
+
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_NEW_CONNECTION_ID frame)
+    0x18,
+    // sequence number
+    kVarInt62OneByte + 0x11,
+    // retire_prior_to
+    kVarInt62OneByte + 0x0c,
+    // new connection id length
+    0x08,
+    // new connection id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // stateless reset token
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, NewTokenFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_NEW_TOKEN frame)
+      {"",
+       {0x07}},
+      // Length
+      {"Unable to read new token length.",
+       {kVarInt62OneByte + 0x08}},
+      {"Unable to read new token data.",
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}}
+  };
+  // clang-format on
+  uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
+                                    0x04, 0x05, 0x06, 0x07};
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(sizeof(expected_token_value), visitor_.new_token_.token.length());
+  EXPECT_EQ(0, memcmp(expected_token_value, visitor_.new_token_.token.data(),
+                      sizeof(expected_token_value)));
+
+  CheckFramingBoundaries(packet, QUIC_INVALID_NEW_TOKEN);
+}
+
+TEST_P(QuicFramerTest, BuildNewTokenFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for IETF QUIC only.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  uint8_t expected_token_value[] = {0x00, 0x01, 0x02, 0x03,
+                                    0x04, 0x05, 0x06, 0x07};
+
+  QuicNewTokenFrame frame(0,
+                          absl::string_view((const char*)(expected_token_value),
+                                            sizeof(expected_token_value)));
+
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_NEW_TOKEN frame)
+    0x07,
+    // Length and token
+    kVarInt62OneByte + 0x08,
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet),
+      ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicFramerTest, IetfStopSendingFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Stop sending frame is IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_STOP_SENDING frame)
+      {"",
+       {0x05}},
+      // stream id
+      {"Unable to read IETF_STOP_SENDING frame stream id/count.",
+       {kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04}},
+      {"Unable to read stop sending application error code.",
+       {kVarInt62FourBytes + 0x00, 0x00, 0x76, 0x54}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(kStreamId, visitor_.stop_sending_frame_.stream_id);
+  EXPECT_EQ(QUIC_STREAM_UNKNOWN_APPLICATION_ERROR_CODE,
+            visitor_.stop_sending_frame_.error_code);
+  EXPECT_EQ(static_cast<uint64_t>(0x7654),
+            visitor_.stop_sending_frame_.ietf_error_code);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_STOP_SENDING_FRAME_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfStopSendingPacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Stop sending frame is IETF QUIC only.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicStopSendingFrame frame;
+  frame.stream_id = kStreamId;
+  frame.error_code = QUIC_STREAM_ENCODER_STREAM_ERROR;
+  frame.ietf_error_code =
+      static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
+  QuicFrames frames = {QuicFrame(frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_STOP_SENDING frame)
+    0x05,
+    // Stream ID
+    kVarInt62FourBytes + 0x01, 0x02, 0x03, 0x04,
+    // Application error code
+    kVarInt62TwoBytes + 0x02, 0x01,
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, IetfPathChallengeFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path Challenge frame is IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_PATH_CHALLENGE)
+      {"",
+       {0x1a}},
+      // data
+      {"Can not read path challenge data.",
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
+            visitor_.path_challenge_frame_.data_buffer);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_CHALLENGE_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfPathChallengePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path Challenge frame is IETF QUIC only.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicPathChallengeFrame frame;
+  frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PATH_CHALLENGE)
+    0x1a,
+    // Data
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, IetfPathResponseFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path response frame is IETF QUIC only.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (IETF_PATH_RESPONSE)
+      {"",
+       {0x1b}},
+      // data
+      {"Can not read path response data.",
+       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}}),
+            visitor_.path_response_frame_.data_buffer);
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_PATH_RESPONSE_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildIetfPathResponsePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Path response frame is IETF QUIC only
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicPathResponseFrame frame;
+  frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PATH_RESPONSE)
+    0x1b,
+    // Data
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, GetRetransmittableControlFrameSize) {
+  QuicRstStreamFrame rst_stream(1, 3, QUIC_STREAM_CANCELLED, 1024);
+  EXPECT_EQ(QuicFramer::GetRstStreamFrameSize(framer_.transport_version(),
+                                              rst_stream),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&rst_stream)));
+
+  std::string error_detail(2048, 'e');
+  QuicConnectionCloseFrame connection_close(framer_.transport_version(),
+                                            QUIC_NETWORK_IDLE_TIMEOUT,
+                                            NO_IETF_QUIC_ERROR, error_detail,
+                                            /*transport_close_frame_type=*/0);
+
+  EXPECT_EQ(QuicFramer::GetConnectionCloseFrameSize(framer_.transport_version(),
+                                                    connection_close),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&connection_close)));
+
+  QuicGoAwayFrame goaway(2, QUIC_PEER_GOING_AWAY, 3, error_detail);
+  EXPECT_EQ(QuicFramer::GetMinGoAwayFrameSize() + 256,
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&goaway)));
+
+  QuicWindowUpdateFrame window_update(3, 3, 1024);
+  EXPECT_EQ(QuicFramer::GetWindowUpdateFrameSize(framer_.transport_version(),
+                                                 window_update),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(window_update)));
+
+  QuicBlockedFrame blocked(4, 3, 1024);
+  EXPECT_EQ(
+      QuicFramer::GetBlockedFrameSize(framer_.transport_version(), blocked),
+      QuicFramer::GetRetransmittableControlFrameSize(
+          framer_.transport_version(), QuicFrame(blocked)));
+
+  // Following frames are IETF QUIC frames only.
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+
+  QuicNewConnectionIdFrame new_connection_id(5, TestConnectionId(), 1,
+                                             kTestStatelessResetToken, 1);
+  EXPECT_EQ(QuicFramer::GetNewConnectionIdFrameSize(new_connection_id),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&new_connection_id)));
+
+  QuicMaxStreamsFrame max_streams(6, 3, /*unidirectional=*/false);
+  EXPECT_EQ(QuicFramer::GetMaxStreamsFrameSize(framer_.transport_version(),
+                                               max_streams),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(max_streams)));
+
+  QuicStreamsBlockedFrame streams_blocked(7, 3, /*unidirectional=*/false);
+  EXPECT_EQ(QuicFramer::GetStreamsBlockedFrameSize(framer_.transport_version(),
+                                                   streams_blocked),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(streams_blocked)));
+
+  QuicPathFrameBuffer buffer = {
+      {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
+  QuicPathResponseFrame path_response_frame(8, buffer);
+  EXPECT_EQ(QuicFramer::GetPathResponseFrameSize(path_response_frame),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&path_response_frame)));
+
+  QuicPathChallengeFrame path_challenge_frame(9, buffer);
+  EXPECT_EQ(QuicFramer::GetPathChallengeFrameSize(path_challenge_frame),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(&path_challenge_frame)));
+
+  QuicStopSendingFrame stop_sending_frame(10, 3, QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(QuicFramer::GetStopSendingFrameSize(stop_sending_frame),
+            QuicFramer::GetRetransmittableControlFrameSize(
+                framer_.transport_version(), QuicFrame(stop_sending_frame)));
+}
+
+// A set of tests to ensure that bad frame-type encodings
+// are properly detected and handled.
+// First, four tests to see that unknown frame types generate
+// a QUIC_INVALID_FRAME_DATA error with detailed information
+// "Illegal frame type." This regardless of the encoding of the type
+// (1/2/4/8 bytes).
+// This only for version 99.
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown1Byte) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, single-byte encoding)
+      {"",
+       {0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown2Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x01, 0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown4Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, four-byte encoding)
+      {"",
+       {kVarInt62FourBytes + 0x01, 0x00, 0x00, 0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorUnknown8Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (unknown value, eight-byte encoding)
+      {"",
+       {kVarInt62EightBytes + 0x01, 0x00, 0x00, 0x01, 0x02, 0x34, 0x56, 0x38}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
+  EXPECT_EQ("Illegal frame type.", framer_.detailed_error());
+}
+
+// Three tests to check that known frame types that are not minimally
+// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
+// information "Frame type not minimally encoded."
+// Look at the frame-type encoded in 2, 4, and 8 bytes.
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (Blocked, two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x08}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown4Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (Blocked, four-byte encoding)
+      {"",
+       {kVarInt62FourBytes + 0x00, 0x00, 0x00, 0x08}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown8Bytes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (Blocked, eight-byte encoding)
+      {"",
+       {kVarInt62EightBytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+}
+
+// Tests to check that all known IETF frame types that are not minimally
+// encoded generate IETF_QUIC_PROTOCOL_VIOLATION errors with detailed
+// information "Frame type not minimally encoded."
+// Just look at 2-byte encoding.
+TEST_P(QuicFramerTest, IetfFrameTypeEncodingErrorKnown2BytesAllTypes) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Only IETF QUIC encodes frame types such that this test is relevant.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+
+  // clang-format off
+  PacketFragments packets[] = {
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x00}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x01}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x02}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x03}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x04}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x05}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x06}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x07}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x08}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x09}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0a}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0b}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0c}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0d}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0e}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x0f}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x10}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x11}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x12}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x13}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x14}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x15}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x16}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x17}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x18}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x20}}
+    },
+    {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x9A, 0xBC}},
+      // frame type (two-byte encoding)
+      {"",
+       {kVarInt62TwoBytes + 0x00, 0x21}}
+    },
+  };
+  // clang-format on
+
+  for (PacketFragments& packet : packets) {
+    std::unique_ptr<QuicEncryptedPacket> encrypted(
+        AssemblePacketFromFragments(packet));
+
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+
+    EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+    EXPECT_EQ("Frame type not minimally encoded.", framer_.detailed_error());
+  }
+}
+
+TEST_P(QuicFramerTest, RetireConnectionIdFrame) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for version 99.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  PacketFragments packet_ietf = {
+      // type (short header, 4 byte packet number)
+      {"",
+       {0x43}},
+      // connection_id
+      {"",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+      // packet number
+      {"",
+       {0x12, 0x34, 0x56, 0x78}},
+      // frame type (IETF_RETIRE_CONNECTION_ID frame)
+      {"",
+       {0x19}},
+      // Sequence number
+      {"Unable to read retire connection ID frame sequence number.",
+       {kVarInt62TwoBytes + 0x11, 0x22}}
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet_ietf));
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_TRUE(CheckDecryption(
+      *encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+      PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+  EXPECT_EQ(0u, visitor_.stream_frames_.size());
+
+  EXPECT_EQ(0x1122u, visitor_.retire_connection_id_.sequence_number);
+
+  ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+  CheckFramingBoundaries(packet_ietf, QUIC_INVALID_RETIRE_CONNECTION_ID_DATA);
+}
+
+TEST_P(QuicFramerTest, BuildRetireConnectionIdFramePacket) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // This frame is only for version 99.
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicRetireConnectionIdFrame frame;
+  frame.sequence_number = 0x1122;
+
+  QuicFrames frames = {QuicFrame(&frame)};
+
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_RETIRE_CONNECTION_ID frame)
+    0x19,
+    // sequence number
+    kVarInt62TwoBytes + 0x11, 0x22
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data->data(), data->length(), AsChars(packet_ietf),
+      ABSL_ARRAYSIZE(packet_ietf));
+}
+
+TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x00,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x00,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x00,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x00,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // Largest acked
+    kVarInt62OneByte + 0x00,
+    // Zero delta time.
+    kVarInt62OneByte + 0x00,
+    // Ack block count 0
+    kVarInt62OneByte + 0x00,
+    // First ack block length
+    kVarInt62OneByte + 0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_EQ(framer_.detailed_error(), "Largest acked is 0.");
+}
+
+TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x02,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x03,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x45,
+    // largest observed
+    0x00, 0x02,
+    // Zero delta time.
+    0x00, 0x00,
+    // first ack block length.
+    0x00, 0x03,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // Largest acked
+    kVarInt62OneByte + 0x02,
+    // Zero delta time.
+    kVarInt62OneByte + 0x00,
+    // Ack block count 0
+    kVarInt62OneByte + 0x00,
+    // First ack block length
+    kVarInt62OneByte + 0x02,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  EXPECT_EQ(framer_.detailed_error(),
+            "Underflow with first ack block length 3 largest acked is 2.");
+}
+
+TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) {
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x60,
+    // largest observed
+    0x0A,
+    // Zero delta time.
+    0x00, 0x00,
+    // Num of ack blocks
+    0x02,
+    // first ack block length.
+    0x02,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x01,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x06,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ack frame)
+    0x60,
+    // largest observed
+    0x0A,
+    // Zero delta time.
+    0x00, 0x00,
+    // Num of ack blocks
+    0x02,
+    // first ack block length.
+    0x02,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x01,
+    // gap to next block
+    0x01,
+    // ack block length
+    0x06,
+    // num timestamps.
+    0x00
+  };
+
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // Largest acked
+    kVarInt62OneByte + 0x0A,
+    // Zero delta time.
+    kVarInt62OneByte + 0x00,
+    // Ack block count 2
+    kVarInt62OneByte + 0x02,
+    // First ack block length
+    kVarInt62OneByte + 0x01,
+    // gap to next block length
+    kVarInt62OneByte + 0x00,
+    // ack block length
+    kVarInt62OneByte + 0x00,
+    // gap to next block length
+    kVarInt62OneByte + 0x00,
+    // ack block length
+    kVarInt62OneByte + 0x05,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_size = ABSL_ARRAYSIZE(packet);
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    p = packet_ietf;
+    p_size = ABSL_ARRAYSIZE(packet_ietf);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_size, false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(framer_.detailed_error(),
+              "Underflow with ack block length 6 latest ack block end is 5.");
+  } else {
+    EXPECT_EQ(framer_.detailed_error(),
+              "Underflow with ack block length 6, end of block is 6.");
+  }
+}
+
+TEST_P(QuicFramerTest, CoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t first_packet_ietf_size = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
+  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(2u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[1]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[1]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[1]->offset);
+  CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[1].get());
+}
+
+TEST_P(QuicFramerTest, CoalescedPacketWithUdpPadding) {
+  if (!framer_.version().HasLongHeaderLengths()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // padding
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+      // padding
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  EXPECT_EQ(visitor_.coalesced_packets_.size(), 0u);
+}
+
+TEST_P(QuicFramerTest, CoalescedPacketWithDifferentVersion) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // garbage version
+      'G', 'A', 'B', 'G',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // garbage version
+      'G', 'A', 'B', 'G',
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t first_packet_ietf_size = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[first_packet_ietf_size], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[first_packet_ietf_size]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
+  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  // Verify version mismatch gets reported.
+  EXPECT_EQ(1, visitor_.version_mismatch_);
+}
+
+TEST_P(QuicFramerTest, UndecryptablePacketWithoutDecrypter) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  if (!framer_.version().KnowsWhichDecrypterToUse()) {
+    // We create a bad client decrypter by using initial encryption with a
+    // bogus connection ID; it should fail to decrypt everything.
+    QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
+    CrypterPair bogus_crypters;
+    CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                          framer_.version(),
+                                          bogus_connection_id, &bogus_crypters);
+    // This removes all other decrypters.
+    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                         std::move(bogus_crypters.decrypter));
+  }
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version included, 8-byte connection ID,
+    // 4-byte packet number)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet46[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x05,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x00,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x24,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+  // First attempt decryption without the handshake crypter.
+  EXPECT_FALSE(
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
+  quiche::test::CompareCharArraysWithHexError(
+      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
+      visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    EXPECT_EQ(ENCRYPTION_HANDSHAKE,
+              visitor_.undecryptable_decryption_levels_[0]);
+  }
+  EXPECT_FALSE(visitor_.undecryptable_has_decryption_keys_[0]);
+}
+
+TEST_P(QuicFramerTest, UndecryptablePacketWithDecrypter) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // We create a bad client decrypter by using initial encryption with a
+  // bogus connection ID; it should fail to decrypt everything.
+  QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
+  CrypterPair bad_handshake_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                        framer_.version(), bogus_connection_id,
+                                        &bad_handshake_crypters);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
+                             std::move(bad_handshake_crypters.decrypter));
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_HANDSHAKE,
+                         std::move(bad_handshake_crypters.decrypter));
+  }
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (version included, 8-byte connection ID,
+    // 4-byte packet number)
+    0x28,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet46[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x05,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x00,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x24,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frames
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  } else if (framer_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    p_length = ABSL_ARRAYSIZE(packet46);
+  }
+
+  EXPECT_FALSE(
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false)));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
+  quiche::test::CompareCharArraysWithHexError(
+      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
+      visitor_.undecryptable_packets_[0]->length(), AsChars(p), p_length);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    EXPECT_EQ(ENCRYPTION_HANDSHAKE,
+              visitor_.undecryptable_decryption_levels_[0]);
+  }
+  EXPECT_EQ(framer_.version().KnowsWhichDecrypterToUse(),
+            visitor_.undecryptable_has_decryption_keys_[0]);
+}
+
+TEST_P(QuicFramerTest, UndecryptableCoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // We create a bad client decrypter by using initial encryption with a
+  // bogus connection ID; it should fail to decrypt everything.
+  QuicConnectionId bogus_connection_id = TestConnectionId(0xbad);
+  CrypterPair bad_handshake_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                        framer_.version(), bogus_connection_id,
+                                        &bad_handshake_crypters);
+  framer_.InstallDecrypter(ENCRYPTION_HANDSHAKE,
+                           std::move(bad_handshake_crypters.decrypter));
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type HANDSHAKE and
+      // 4-byte packet number)
+      0xE3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type HANDSHAKE and
+      // 4-byte packet number)
+      0xE3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t length_of_first_coalesced_packet = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_DECRYPTION_FAILURE));
+
+  ASSERT_EQ(1u, visitor_.undecryptable_packets_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_decryption_levels_.size());
+  ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
+  // Make sure we only receive the first undecryptable packet and not the
+  // full packet including the second coalesced packet.
+  quiche::test::CompareCharArraysWithHexError(
+      "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
+      visitor_.undecryptable_packets_[0]->length(), AsChars(p),
+      length_of_first_coalesced_packet);
+  EXPECT_EQ(ENCRYPTION_HANDSHAKE, visitor_.undecryptable_decryption_levels_[0]);
+  EXPECT_TRUE(visitor_.undecryptable_has_decryption_keys_[0]);
+
+  // Make sure the second coalesced packet is parsed correctly.
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 1u);
+  EXPECT_TRUE(framer_.ProcessPacket(*visitor_.coalesced_packets_[0].get()));
+
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("HELLO_WORLD?", visitor_.stream_frames_[0].get());
+}
+
+TEST_P(QuicFramerTest, MismatchedCoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x79,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'H',  'E',  'L',  'L',
+      'O',  '_',  'W',  'O',
+      'R',  'L',  'D',  '?',
+  };
+  // clang-format on
+  const size_t length_of_first_coalesced_packet = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
+}
+
+TEST_P(QuicFramerTest, InvalidCoalescedPacket) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (stream frame with fin)
+      0xFE,
+      // stream id
+      0x02, 0x03, 0x04,
+      // offset
+      0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+      // data length
+      0x00, 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version would be here but we cut off the invalid coalesced header.
+  };
+  unsigned char packet_ietf[] = {
+    // first coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version
+      QUIC_VERSION_BYTES,
+      // destination connection ID length
+      0x08,
+      // destination connection ID
+      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+      // source connection ID length
+      0x00,
+      // long header packet length
+      0x1E,
+      // packet number
+      0x12, 0x34, 0x56, 0x78,
+      // frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
+      0x08 | 0x01 | 0x02 | 0x04,
+      // stream id
+      kVarInt62FourBytes + 0x00, 0x02, 0x03, 0x04,
+      // offset
+      kVarInt62EightBytes + 0x3A, 0x98, 0xFE, 0xDC,
+      0x32, 0x10, 0x76, 0x54,
+      // data length
+      kVarInt62OneByte + 0x0c,
+      // data
+      'h',  'e',  'l',  'l',
+      'o',  ' ',  'w',  'o',
+      'r',  'l',  'd',  '!',
+    // second coalesced packet
+      // public flags (long header with packet type ZERO_RTT_PROTECTED and
+      // 4-byte packet number)
+      0xD3,
+      // version would be here but we cut off the invalid coalesced header.
+  };
+  // clang-format on
+  const size_t length_of_first_coalesced_packet = 46;
+  // If the first packet changes, the attempt to fix the first byte of the
+  // second packet will fail.
+  EXPECT_EQ(packet_ietf[length_of_first_coalesced_packet], 0xD3);
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasIetfQuicFrames()) {
+    ReviseFirstByteByVersion(packet_ietf);
+    ReviseFirstByteByVersion(&packet_ietf[length_of_first_coalesced_packet]);
+    p = packet_ietf;
+    p_length = ABSL_ARRAYSIZE(packet_ietf);
+  }
+
+  QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  ASSERT_TRUE(visitor_.header_.get());
+
+  ASSERT_EQ(1u, visitor_.stream_frames_.size());
+  EXPECT_EQ(0u, visitor_.ack_frames_.size());
+
+  // Stream ID should be the last 3 bytes of kStreamId.
+  EXPECT_EQ(0x00FFFFFF & kStreamId, visitor_.stream_frames_[0]->stream_id);
+  EXPECT_TRUE(visitor_.stream_frames_[0]->fin);
+  EXPECT_EQ(kStreamOffset, visitor_.stream_frames_[0]->offset);
+  CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
+
+  ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
+}
+
+// Some IETF implementations send an initial followed by zeroes instead of
+// padding inside the initial. We need to make sure that we still process
+// the initial correctly and ignore the zeroes.
+TEST_P(QuicFramerTest, CoalescedPacketWithZeroesRoundTrip) {
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
+      !framer_.version().UsesInitialObfuscators()) {
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  QuicConnectionId connection_id = FramerTestConnectionId();
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  CrypterPair client_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_CLIENT,
+                                        framer_.version(), connection_id,
+                                        &client_crypters);
+  framer_.SetEncrypter(ENCRYPTION_INITIAL,
+                       std::move(client_crypters.encrypter));
+
+  QuicPacketHeader header;
+  header.destination_connection_id = connection_id;
+  header.version_flag = true;
+  header.packet_number = kPacketNumber;
+  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+  header.long_packet_type = INITIAL;
+  header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+  QuicFrames frames = {QuicFrame(QuicPingFrame()),
+                       QuicFrame(QuicPaddingFrame(3))};
+
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_NE(nullptr, data);
+
+  // Add zeroes after the valid initial packet.
+  unsigned char packet[kMaxOutgoingPacketSize] = {};
+  size_t encrypted_length =
+      framer_.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *data,
+                             AsChars(packet), ABSL_ARRAYSIZE(packet));
+  ASSERT_NE(0u, encrypted_length);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  CrypterPair server_crypters;
+  CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER,
+                                        framer_.version(), connection_id,
+                                        &server_crypters);
+  framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+                           std::move(server_crypters.decrypter));
+
+  // Make sure the first long header initial packet parses correctly.
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+
+  // Make sure we discard the subsequent zeroes.
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  EXPECT_TRUE(visitor_.coalesced_packets_.empty());
+}
+
+TEST_P(QuicFramerTest, ClientReceivesWrongVersion) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+  // clang-format off
+  unsigned char packet[] = {
+       // public flags (long header with packet type INITIAL)
+       0xC3,
+       // version that is different from the framer's version
+       'Q', '0', '4', '3',
+       // connection ID lengths
+       0x05,
+       // source connection ID
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+       // packet number
+       0x01,
+       // padding frame
+       0x00,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(QUIC_PACKET_WRONG_VERSION));
+  EXPECT_EQ("Client received unexpected version.", framer_.detailed_error());
+}
+
+TEST_P(QuicFramerTest, PacketHeaderWithVariableLengthConnectionId) {
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  uint8_t connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
+                                    0x54, 0x32, 0x10, 0x42};
+  QuicConnectionId connection_id(reinterpret_cast<char*>(connection_id_bytes),
+                                 sizeof(connection_id_bytes));
+  QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
+  QuicFramerPeer::SetExpectedServerConnectionIDLength(&framer_,
+                                                      connection_id.length());
+
+  // clang-format off
+  PacketFragments packet = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      // packet number
+      {"Unable to read packet number.",
+       {0x78}},
+  };
+
+  PacketFragments packet_with_padding = {
+      // type (8 byte connection_id and 1 byte packet number)
+      {"Unable to read first byte.",
+       {0x40}},
+      // connection_id
+      {"Unable to read destination connection ID.",
+       {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x42}},
+      // packet number
+      {"",
+       {0x78}},
+      // padding
+      {"", {0x00, 0x00, 0x00}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments =
+      framer_.version().HasHeaderProtection() ? packet_with_padding : packet;
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+  if (framer_.version().HasHeaderProtection()) {
+    EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsQuicNoError());
+  } else {
+    EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+    EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
+  }
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(connection_id, visitor_.header_->destination_connection_id);
+  EXPECT_FALSE(visitor_.header_->reset_flag);
+  EXPECT_FALSE(visitor_.header_->version_flag);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, visitor_.header_->packet_number_length);
+  EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);
+
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, MultiplePacketNumberSpaces) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    return;
+  }
+  framer_.EnableMultiplePacketNumberSpacesSupport();
+
+  // clang-format off
+  unsigned char long_header_packet[] = {
+       // public flags (long header with packet type ZERO_RTT_PROTECTED and
+       // 4-byte packet number)
+       0xD3,
+       // version
+       QUIC_VERSION_BYTES,
+       // destination connection ID length
+       0x50,
+       // destination connection ID
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+       // packet number
+       0x12, 0x34, 0x56, 0x78,
+       // padding frame
+       0x00,
+   };
+  unsigned char long_header_packet_ietf[] = {
+       // public flags (long header with packet type ZERO_RTT_PROTECTED and
+       // 4-byte packet number)
+       0xD3,
+       // version
+       QUIC_VERSION_BYTES,
+       // destination connection ID length
+       0x08,
+       // destination connection ID
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+       // source connection ID length
+       0x00,
+       // long header packet length
+       0x05,
+       // packet number
+       0x12, 0x34, 0x56, 0x78,
+       // padding frame
+       0x00,
+  };
+  // clang-format on
+
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                             std::make_unique<TestDecrypter>());
+    framer_.RemoveDecrypter(ENCRYPTION_INITIAL);
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_ZERO_RTT,
+                         std::make_unique<TestDecrypter>());
+  }
+  if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
+    EXPECT_TRUE(framer_.ProcessPacket(
+        QuicEncryptedPacket(AsChars(long_header_packet),
+                            ABSL_ARRAYSIZE(long_header_packet), false)));
+  } else {
+    ReviseFirstByteByVersion(long_header_packet_ietf);
+    EXPECT_TRUE(framer_.ProcessPacket(
+        QuicEncryptedPacket(AsChars(long_header_packet_ietf),
+                            ABSL_ARRAYSIZE(long_header_packet_ietf), false)));
+  }
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
+          .IsInitialized());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
+          .IsInitialized());
+  EXPECT_EQ(kPacketNumber, QuicFramerPeer::GetLargestDecryptedPacketNumber(
+                               &framer_, APPLICATION_DATA));
+
+  // clang-format off
+  unsigned char short_header_packet[] = {
+     // type (short header, 1 byte packet number)
+     0x40,
+     // connection_id
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+     // packet number
+     0x79,
+     // padding frame
+     0x00, 0x00, 0x00,
+  };
+  // clang-format on
+
+  QuicEncryptedPacket short_header_encrypted(
+      AsChars(short_header_packet), ABSL_ARRAYSIZE(short_header_packet), false);
+  if (framer_.version().KnowsWhichDecrypterToUse()) {
+    framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                             std::make_unique<TestDecrypter>());
+    framer_.RemoveDecrypter(ENCRYPTION_ZERO_RTT);
+  } else {
+    framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                         std::make_unique<TestDecrypter>());
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(short_header_encrypted));
+
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, INITIAL_DATA)
+          .IsInitialized());
+  EXPECT_FALSE(
+      QuicFramerPeer::GetLargestDecryptedPacketNumber(&framer_, HANDSHAKE_DATA)
+          .IsInitialized());
+  EXPECT_EQ(kPacketNumber + 1, QuicFramerPeer::GetLargestDecryptedPacketNumber(
+                                   &framer_, APPLICATION_DATA));
+}
+
+TEST_P(QuicFramerTest, IetfRetryPacketRejected) {
+  if (!framer_.version().KnowsWhichDecrypterToUse() ||
+      framer_.version().SupportsRetry()) {
+    return;
+  }
+
+  // clang-format off
+  PacketFragments packet46 = {
+    // public flags (IETF Retry packet, 0-length original destination CID)
+    {"Unable to read first byte.",
+     {0xf0}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // connection_id length
+    {"RETRY not supported in this version.",
+     {0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet46));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  CheckFramingBoundaries(packet46, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, RetryPacketRejectedWithMultiplePacketNumberSpaces) {
+  if (!framer_.version().HasIetfInvariantHeader() ||
+      framer_.version().SupportsRetry()) {
+    return;
+  }
+  framer_.EnableMultiplePacketNumberSpacesSupport();
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (IETF Retry packet, 0-length original destination CID)
+    {"Unable to read first byte.",
+     {0xf0}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // connection_id length
+    {"RETRY not supported in this version.",
+     {0x00}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, ProcessPublicHeaderNoVersionInferredType) {
+  // The framer needs to have Perspective::IS_SERVER and configured to infer the
+  // packet header type from the packet (not the version). The framer's version
+  // needs to be one that uses the IETF packet format.
+  if (!framer_.version().KnowsWhichDecrypterToUse()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+
+  // Prepare a packet that uses the Google QUIC packet header but has no version
+  // field.
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (1-byte packet number, 8-byte connection_id, no version)
+    {"Unable to read public flags.",
+     {0x08}},
+    // connection_id
+    {"Unable to read ConnectionId.",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // packet number
+    {"Unable to read packet number.",
+     {0x01}},
+    // padding
+    {"Invalid public header type for expected version.",
+     {0x00}},
+  };
+  // clang-format on
+
+  PacketFragments& fragments = packet;
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(fragments));
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  EXPECT_EQ("Invalid public header type for expected version.",
+            framer_.detailed_error());
+  CheckFramingBoundaries(fragments, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, ProcessMismatchedHeaderVersion) {
+  // The framer needs to have Perspective::IS_SERVER and configured to infer the
+  // packet header type from the packet (not the version). The framer's version
+  // needs to be one that uses the IETF packet format.
+  if (!framer_.version().KnowsWhichDecrypterToUse()) {
+    return;
+  }
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+
+  // clang-format off
+  PacketFragments packet = {
+    // public flags (Google QUIC header with version present)
+    {"Unable to read public flags.",
+     {0x09}},
+    // connection_id
+    {"Unable to read ConnectionId.",
+     {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+    // version tag
+    {"Unable to read protocol version.",
+     {QUIC_VERSION_BYTES}},
+    // packet number
+    {"Unable to read packet number.",
+     {0x01}},
+  };
+  // clang-format on
+
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      AssemblePacketFromFragments(packet));
+  framer_.ProcessPacket(*encrypted);
+
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+  EXPECT_EQ("Invalid public header type for expected version.",
+            framer_.detailed_error());
+  CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER);
+}
+
+TEST_P(QuicFramerTest, WriteClientVersionNegotiationProbePacket) {
+  // clang-format off
+  static const uint8_t expected_packet[1200] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    0xca, 0xba, 0xda, 0xda,
+    // Destination connection ID length 8.
+    0x08,
+    // 8-byte destination connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // Source connection ID length 0.
+    0x00,
+    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+    // not parse with any known version.
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    // zeroes to pad to 16 byte boundary.
+    0x00,
+    // A polite greeting in case a human sees this in tcpdump.
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
+    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
+    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
+    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
+    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
+    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
+    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
+    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
+    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
+    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
+    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
+    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
+    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
+    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
+  };
+  // clang-format on
+  char packet[1200];
+  char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                            0x6c, 0x7a, 0x20, 0x21};
+  EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), destination_connection_id_bytes,
+      sizeof(destination_connection_id_bytes)));
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", packet, sizeof(packet),
+      reinterpret_cast<const char*>(expected_packet), sizeof(expected_packet));
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet), false);
+  if (!framer_.version().HasLengthPrefixedConnectionIds()) {
+    // We can only parse the connection ID with a parser expecting
+    // length-prefixed connection IDs.
+    EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+    return;
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+  ASSERT_TRUE(visitor_.header_.get());
+  QuicConnectionId probe_payload_connection_id(
+      reinterpret_cast<const char*>(destination_connection_id_bytes),
+      sizeof(destination_connection_id_bytes));
+  EXPECT_EQ(probe_payload_connection_id,
+            visitor_.header_.get()->destination_connection_id);
+}
+
+TEST_P(QuicFramerTest, DispatcherParseOldClientVersionNegotiationProbePacket) {
+  // clang-format off
+  static const uint8_t packet[1200] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    0xca, 0xba, 0xda, 0xba,
+    // Destination connection ID length 8, source connection ID length 0.
+    0x50,
+    // 8-byte destination connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+    // not parse with any known version.
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    // 2 bytes of zeroes to pad to 16 byte boundary.
+    0x00, 0x00,
+    // A polite greeting in case a human sees this in tcpdump.
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
+    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
+    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
+    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
+    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
+    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
+    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
+    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
+    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
+    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
+    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
+    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
+    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
+    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
+  };
+  // clang-format on
+  char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                                     0x6c, 0x7a, 0x20, 0x21};
+  QuicConnectionId expected_destination_connection_id(
+      reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
+      sizeof(expected_destination_connection_id_bytes));
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet));
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_present = false, has_length_prefix = true;
+  QuicVersionLabel version_label = 33;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = TestConnectionId(1);
+  QuicConnectionId source_connection_id = TestConnectionId(2);
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error = "foobar";
+  QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(header_parse_result, IsQuicNoError());
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_present);
+  EXPECT_FALSE(has_length_prefix);
+  EXPECT_EQ(0xcabadaba, version_label);
+  EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_FALSE(retry_token.has_value());
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, DispatcherParseClientVersionNegotiationProbePacket) {
+  // clang-format off
+  static const uint8_t packet[1200] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version, part of the IETF space reserved for negotiation.
+    0xca, 0xba, 0xda, 0xba,
+    // Destination connection ID length 8.
+    0x08,
+    // 8-byte destination connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // Source connection ID length 0.
+    0x00,
+    // 8 bytes of zeroes followed by 8 bytes of ones to ensure that this does
+    // not parse with any known version.
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    // 1 byte of zeroes to pad to 16 byte boundary.
+    0x00,
+    // A polite greeting in case a human sees this in tcpdump.
+    0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x63,
+    0x6b, 0x65, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79,
+    0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x20,
+    0x74, 0x6f, 0x20, 0x74, 0x72, 0x69, 0x67, 0x67,
+    0x65, 0x72, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20,
+    0x51, 0x55, 0x49, 0x43, 0x20, 0x76, 0x65, 0x72,
+    0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, 0x67,
+    0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+    0x2e, 0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65,
+    0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64,
+    0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20,
+    0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
+    0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+    0x65, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x68,
+    0x61, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+    0x6f, 0x6e, 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20,
+    0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2e,
+    0x20, 0x54, 0x68, 0x61, 0x6e, 0x6b, 0x20, 0x79,
+    0x6f, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68,
+    0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x69,
+    0x63, 0x65, 0x20, 0x64, 0x61, 0x79, 0x2e, 0x00,
+  };
+  // clang-format on
+  char expected_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                                     0x6c, 0x7a, 0x20, 0x21};
+  QuicConnectionId expected_destination_connection_id(
+      reinterpret_cast<const char*>(expected_destination_connection_id_bytes),
+      sizeof(expected_destination_connection_id_bytes));
+
+  QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
+                                sizeof(packet));
+  PacketHeaderFormat format = GOOGLE_QUIC_PACKET;
+  QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+  bool version_present = false, has_length_prefix = false;
+  QuicVersionLabel version_label = 33;
+  ParsedQuicVersion parsed_version = UnsupportedQuicVersion();
+  QuicConnectionId destination_connection_id = TestConnectionId(1);
+  QuicConnectionId source_connection_id = TestConnectionId(2);
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error = "foobar";
+  QuicErrorCode header_parse_result = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted, kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+      &version_present, &has_length_prefix, &version_label, &parsed_version,
+      &destination_connection_id, &source_connection_id, &retry_token,
+      &detailed_error);
+  EXPECT_THAT(header_parse_result, IsQuicNoError());
+  EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
+  EXPECT_TRUE(version_present);
+  EXPECT_TRUE(has_length_prefix);
+  EXPECT_EQ(0xcabadaba, version_label);
+  EXPECT_EQ(expected_destination_connection_id, destination_connection_id);
+  EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, ParseServerVersionNegotiationProbeResponse) {
+  // clang-format off
+  const uint8_t packet[] = {
+    // IETF long header with fixed bit set, type initial, all-0 encrypted bits.
+    0xc0,
+    // Version of 0, indicating version negotiation.
+    0x00, 0x00, 0x00, 0x00,
+    // Destination connection ID length 0, source connection ID length 8.
+    0x00, 0x08,
+    // 8-byte source connection ID.
+    0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21,
+    // A few supported versions.
+    0xaa, 0xaa, 0xaa, 0xaa,
+    QUIC_VERSION_BYTES,
+  };
+  // clang-format on
+  char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21};
+  char parsed_probe_payload_bytes[255] = {};
+  uint8_t parsed_probe_payload_length = sizeof(parsed_probe_payload_bytes);
+  std::string parse_detailed_error = "";
+  EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
+      reinterpret_cast<const char*>(packet), sizeof(packet),
+      reinterpret_cast<char*>(parsed_probe_payload_bytes),
+      &parsed_probe_payload_length, &parse_detailed_error));
+  EXPECT_EQ("", parse_detailed_error);
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed probe", parsed_probe_payload_bytes, parsed_probe_payload_length,
+      probe_payload_bytes, sizeof(probe_payload_bytes));
+}
+
+TEST_P(QuicFramerTest, ParseClientVersionNegotiationProbePacket) {
+  char packet[1200];
+  char input_destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                                  0x6c, 0x7a, 0x20, 0x21};
+  ASSERT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), input_destination_connection_id_bytes,
+      sizeof(input_destination_connection_id_bytes)));
+  char parsed_destination_connection_id_bytes[255] = {0};
+  uint8_t parsed_destination_connection_id_length =
+      sizeof(parsed_destination_connection_id_bytes);
+  ASSERT_TRUE(ParseClientVersionNegotiationProbePacket(
+      packet, sizeof(packet), parsed_destination_connection_id_bytes,
+      &parsed_destination_connection_id_length));
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed destination connection ID",
+      parsed_destination_connection_id_bytes,
+      parsed_destination_connection_id_length,
+      input_destination_connection_id_bytes,
+      sizeof(input_destination_connection_id_bytes));
+}
+
+TEST_P(QuicFramerTest, WriteServerVersionNegotiationProbeResponse) {
+  char packet[1200];
+  size_t packet_length = sizeof(packet);
+  char input_source_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
+                                             0x6c, 0x7a, 0x20, 0x21};
+  ASSERT_TRUE(WriteServerVersionNegotiationProbeResponse(
+      packet, &packet_length, input_source_connection_id_bytes,
+      sizeof(input_source_connection_id_bytes)));
+  char parsed_source_connection_id_bytes[255] = {0};
+  uint8_t parsed_source_connection_id_length =
+      sizeof(parsed_source_connection_id_bytes);
+  std::string detailed_error;
+  ASSERT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
+      packet, packet_length, parsed_source_connection_id_bytes,
+      &parsed_source_connection_id_length, &detailed_error))
+      << detailed_error;
+  quiche::test::CompareCharArraysWithHexError(
+      "parsed destination connection ID", parsed_source_connection_id_bytes,
+      parsed_source_connection_id_length, input_source_connection_id_bytes,
+      sizeof(input_source_connection_id_bytes));
+}
+
+TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToClient) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x50,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x00,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+  const bool parse_success =
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    EXPECT_FALSE(parse_success);
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
+    return;
+  }
+  EXPECT_TRUE(parse_success);
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_.get()->destination_connection_id);
+}
+
+TEST_P(QuicFramerTest, ClientConnectionIdFromLongHeaderToServer) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_HANDSHAKE);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x05,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  unsigned char packet49[] = {
+    // public flags (long header with packet type HANDSHAKE and
+    // 4-byte packet number)
+    0xE3,
+    // version
+    QUIC_VERSION_BYTES,
+    // connection ID lengths
+    0x00, 0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // padding frame
+    0x00,
+  };
+  // clang-format on
+  unsigned char* p = packet;
+  size_t p_length = ABSL_ARRAYSIZE(packet);
+  if (framer_.version().HasLongHeaderLengths()) {
+    ReviseFirstByteByVersion(packet49);
+    p = packet49;
+    p_length = ABSL_ARRAYSIZE(packet49);
+  }
+  const bool parse_success =
+      framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
+  if (!framer_.version().AllowsVariableLengthConnectionIds()) {
+    EXPECT_FALSE(parse_success);
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Invalid ConnectionId length.", framer_.detailed_error());
+    return;
+  }
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    EXPECT_FALSE(parse_success);
+    EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_PACKET_HEADER));
+    EXPECT_EQ("Client connection ID not supported in this version.",
+              framer_.detailed_error());
+    return;
+  }
+  EXPECT_TRUE(parse_success);
+  EXPECT_THAT(framer_.error(), IsQuicNoError());
+  EXPECT_EQ("", framer_.detailed_error());
+  ASSERT_TRUE(visitor_.header_.get());
+  EXPECT_EQ(FramerTestConnectionId(),
+            visitor_.header_.get()->source_connection_id);
+}
+
+TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthClient) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  char connection_id_lengths = 0x05;
+  QuicDataReader reader(&connection_id_lengths, 1);
+
+  bool should_update_expected_server_connection_id_length = false;
+  uint8_t expected_server_connection_id_length = 8;
+  uint8_t destination_connection_id_length = 0;
+  uint8_t source_connection_id_length = 8;
+  std::string detailed_error = "";
+
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader, framer_.version(), Perspective::IS_CLIENT,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(0, destination_connection_id_length);
+  EXPECT_EQ(8, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+
+  QuicDataReader reader2(&connection_id_lengths, 1);
+  should_update_expected_server_connection_id_length = true;
+  expected_server_connection_id_length = 33;
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader2, framer_.version(), Perspective::IS_CLIENT,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(0, destination_connection_id_length);
+  EXPECT_EQ(8, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, ProcessAndValidateIetfConnectionIdLengthServer) {
+  if (!framer_.version().HasIetfInvariantHeader()) {
+    // This test requires an IETF long header.
+    return;
+  }
+  char connection_id_lengths = 0x50;
+  QuicDataReader reader(&connection_id_lengths, 1);
+
+  bool should_update_expected_server_connection_id_length = false;
+  uint8_t expected_server_connection_id_length = 8;
+  uint8_t destination_connection_id_length = 8;
+  uint8_t source_connection_id_length = 0;
+  std::string detailed_error = "";
+
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader, framer_.version(), Perspective::IS_SERVER,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(8, destination_connection_id_length);
+  EXPECT_EQ(0, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+
+  QuicDataReader reader2(&connection_id_lengths, 1);
+  should_update_expected_server_connection_id_length = true;
+  expected_server_connection_id_length = 33;
+  EXPECT_TRUE(QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+      &reader2, framer_.version(), Perspective::IS_SERVER,
+      should_update_expected_server_connection_id_length,
+      &expected_server_connection_id_length, &destination_connection_id_length,
+      &source_connection_id_length, &detailed_error));
+  EXPECT_EQ(8, expected_server_connection_id_length);
+  EXPECT_EQ(8, destination_connection_id_length);
+  EXPECT_EQ(0, source_connection_id_length);
+  EXPECT_EQ("", detailed_error);
+}
+
+TEST_P(QuicFramerTest, TestExtendedErrorCodeParser) {
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    // Extended error codes only in IETF QUIC
+    return;
+  }
+  QuicConnectionCloseFrame frame;
+
+  frame.error_details = "this has no error code info in it";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("this has no error code info in it", frame.error_details);
+
+  frame.error_details = "1234this does not have the colon in it";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("1234this does not have the colon in it", frame.error_details);
+
+  frame.error_details = "1a234:this has a colon, but a malformed error number";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("1a234:this has a colon, but a malformed error number",
+            frame.error_details);
+
+  frame.error_details = "1234:this is good";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u, frame.quic_error_code);
+  EXPECT_EQ("this is good", frame.error_details);
+
+  frame.error_details =
+      "1234 :this is not good, space between last digit and colon";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("1234 :this is not good, space between last digit and colon",
+            frame.error_details);
+
+  frame.error_details = "123456789";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(
+      frame.quic_error_code,
+      IsError(QUIC_IETF_GQUIC_ERROR_MISSING));  // Not good, all numbers, no :
+  EXPECT_EQ("123456789", frame.error_details);
+
+  frame.error_details = "1234:";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u,
+            frame.quic_error_code);  // corner case.
+  EXPECT_EQ("", frame.error_details);
+
+  frame.error_details = "1234:5678";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u,
+            frame.quic_error_code);  // another corner case.
+  EXPECT_EQ("5678", frame.error_details);
+
+  frame.error_details = "12345 6789:";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code,
+              IsError(QUIC_IETF_GQUIC_ERROR_MISSING));  // Not good
+  EXPECT_EQ("12345 6789:", frame.error_details);
+
+  frame.error_details = ":no numbers, is not good";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ(":no numbers, is not good", frame.error_details);
+
+  frame.error_details = "qwer:also no numbers, is not good";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ("qwer:also no numbers, is not good", frame.error_details);
+
+  frame.error_details = " 1234:this is not good, space before first digit";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_THAT(frame.quic_error_code, IsError(QUIC_IETF_GQUIC_ERROR_MISSING));
+  EXPECT_EQ(" 1234:this is not good, space before first digit",
+            frame.error_details);
+
+  frame.error_details = "1234:";
+  MaybeExtractQuicErrorCode(&frame);
+  EXPECT_EQ(1234u,
+            frame.quic_error_code);  // this is good
+  EXPECT_EQ("", frame.error_details);
+}
+
+// Regression test for crbug/1029636.
+TEST_P(QuicFramerTest, OverlyLargeAckDelay) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+  // clang-format off
+  unsigned char packet_ietf[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_ACK frame)
+    0x02,
+    // largest acked
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x78,
+    // ack delay time.
+    kVarInt62EightBytes + 0x31, 0x00, 0x00, 0x00, 0xF3, 0xA0, 0x81, 0xE0,
+    // Nr. of additional ack blocks
+    kVarInt62OneByte + 0x00,
+    // first ack block length.
+    kVarInt62FourBytes + 0x12, 0x34, 0x56, 0x77,
+  };
+  // clang-format on
+
+  framer_.ProcessPacket(QuicEncryptedPacket(
+      AsChars(packet_ietf), ABSL_ARRAYSIZE(packet_ietf), false));
+  ASSERT_EQ(1u, visitor_.ack_frames_.size());
+  // Verify ack_delay_time is set correctly.
+  EXPECT_EQ(QuicTime::Delta::Infinite(),
+            visitor_.ack_frames_[0]->ack_delay_time);
+}
+
+TEST_P(QuicFramerTest, KeyUpdate) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=0, key=1: no key update.
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=1, key=2: key update should have
+  // occurred.
+  ASSERT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[0]);
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed another valid packet with phase=1, key=2: no key update.
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process another key update.
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 2, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  ASSERT_EQ(2u, visitor_.key_update_count());
+  EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[1]);
+  EXPECT_EQ(2, visitor_.derive_next_key_count_);
+  EXPECT_EQ(3, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterUpdate) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 1.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 0. (Receiving packet from previous phase
+  // after packet from new phase was received.)
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateOldPacketAfterDiscardPreviousOneRttKeys) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 1.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Discard keys for previous key phase.
+  framer_.DiscardPreviousOneRttKeys();
+
+  // Process packet N+1 with phase 0. (Receiving packet from previous phase
+  // after packet from new phase was received.)
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should not decrypt and key update count should not change.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdatePacketsOutOfOrder) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 1.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 1. (Receiving packet from new phase out of
+  // order.)
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateWrongKey) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 0, false));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=0, key=1: no key update.
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 2, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=1 but key=3, should not process and should not cause key
+  // update, but next decrypter key should have been created to attempt to
+  // decode it.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(1u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=1 but key=1, should not process and should not cause key
+  // update.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=0 but key=2, should not process and should not cause key
+  // update.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(2u, framer_.PotentialPeerKeyUpdateAttemptCount());
+
+  header.packet_number += 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet with phase=0 and key=0, should process and reset
+  // potential_peer_key_update_attempt_count_.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+  EXPECT_EQ(0u, framer_.PotentialPeerKeyUpdateAttemptCount());
+}
+
+TEST_P(QuicFramerTest, KeyUpdateReceivedWhenNotEnabled) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 1, true));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Received a packet with key phase updated even though framer hasn't had key
+  // update enabled (SetNextOneRttCrypters never called). Should fail to
+  // process.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(0u, visitor_.key_update_count());
+  EXPECT_EQ(0, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateLocallyInitiated) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
+  // Key update count should be updated, but haven't received packet from peer
+  // with new key phase.
+  ASSERT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(KeyUpdateReason::kLocalForTests, visitor_.key_update_reasons_[0]);
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 1.
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, 1, true));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change and
+  // OnDecryptedFirstPacketInKeyPhase should have been called.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N-1 with phase 0. (Receiving packet from previous phase
+  // after packet from new phase was received.)
+  header.packet_number = kPacketNumber - 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 0 and key 1. This should not decrypt even
+  // though it's using the previous key, since the packet number is higher than
+  // a packet number received using the current key.
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should not decrypt and key update count should not change.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(2, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateLocallyInitiatedReceivedOldPacket) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests));
+  // Key update count should be updated, but haven't received packet
+  // from peer with new key phase.
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  // Process packet N with phase 0. (Receiving packet from previous phase
+  // after locally initiated key update, but before any packet from new phase
+  // was received.)
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted =
+      EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change and
+  // OnDecryptedFirstPacketInKeyPhase should not have been called since the
+  // packet was from the previous key phase.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+1 with phase 1.
+  header.packet_number = kPacketNumber + 1;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 1, true);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should decrypt and key update count should not change, but
+  // OnDecryptedFirstPacketInKeyPhase should have been called.
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+
+  // Process packet N+2 with phase 0 and key 1. This should not decrypt even
+  // though it's using the previous key, since the packet number is higher than
+  // a packet number received using the current key.
+  header.packet_number = kPacketNumber + 2;
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  data = BuildDataPacket(header, frames);
+  ASSERT_TRUE(data != nullptr);
+  encrypted = EncryptPacketWithTagAndPhase(*data, 0, false);
+  ASSERT_TRUE(encrypted);
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  // Packet should not decrypt and key update count should not change.
+  EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(2, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, KeyUpdateOnFirstReceivedPacket) {
+  if (!framer_.version().UsesTls()) {
+    // Key update is only used in QUIC+TLS.
+    return;
+  }
+  ASSERT_TRUE(framer_.version().KnowsWhichDecrypterToUse());
+  // Doesn't use SetDecrypterLevel since we want to use StrictTaggingDecrypter
+  // instead of TestDecrypter.
+  framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                           std::make_unique<StrictTaggingDecrypter>(/*key=*/0));
+  framer_.SetKeyUpdateSupportForConnection(true);
+
+  QuicPacketHeader header;
+  header.destination_connection_id = FramerTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = QuicPacketNumber(123);
+
+  QuicFrames frames = {QuicFrame(QuicPaddingFrame())};
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+  std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+  ASSERT_TRUE(data != nullptr);
+  std::unique_ptr<QuicEncryptedPacket> encrypted(
+      EncryptPacketWithTagAndPhase(*data, /*tag=*/1, /*phase=*/true));
+  ASSERT_TRUE(encrypted);
+
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
+  // Processed valid packet with phase=1, key=1: do key update.
+  EXPECT_EQ(1u, visitor_.key_update_count());
+  EXPECT_EQ(1, visitor_.derive_next_key_count_);
+  EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_);
+}
+
+TEST_P(QuicFramerTest, ErrorWhenUnexpectedFrameTypeEncountered) {
+  if (!VersionHasIetfQuicFrames(framer_.transport_version()) ||
+      !QuicVersionHasLongHeaderLengths(framer_.transport_version()) ||
+      !framer_.version().HasLongHeaderLengths()) {
+    return;
+  }
+  SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (long header with packet type ZERO_RTT_PROTECTED and
+    // 4-byte packet number)
+    0xD3,
+    // version
+    QUIC_VERSION_BYTES,
+    // destination connection ID length
+    0x08,
+    // destination connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // source connection ID length
+    0x08,
+    // source connection ID
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+    // long header packet length
+    0x05,
+    // packet number
+    0x12, 0x34, 0x56, 0x00,
+    // unexpected ietf ack frame type in 0-RTT packet
+    0x02,
+  };
+  // clang-format on
+
+  ReviseFirstByteByVersion(packet);
+  QuicEncryptedPacket encrypted(AsChars(packet), ABSL_ARRAYSIZE(packet), false);
+
+  EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+  EXPECT_THAT(framer_.error(), IsError(IETF_QUIC_PROTOCOL_VIOLATION));
+  EXPECT_EQ(
+      "IETF frame type IETF_ACK is unexpected at encryption level "
+      "ENCRYPTION_ZERO_RTT",
+      framer_.detailed_error());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_idle_network_detector.cc b/quiche/quic/core/quic_idle_network_detector.cc
new file mode 100644
index 0000000..77d6dba
--- /dev/null
+++ b/quiche/quic/core/quic_idle_network_detector.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_idle_network_detector.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+
+class AlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit AlarmDelegate(QuicIdleNetworkDetector* detector,
+                         QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
+  AlarmDelegate(const AlarmDelegate&) = delete;
+  AlarmDelegate& operator=(const AlarmDelegate&) = delete;
+
+  void OnAlarm() override { detector_->OnAlarm(); }
+
+ private:
+  QuicIdleNetworkDetector* detector_;
+};
+
+}  // namespace
+
+QuicIdleNetworkDetector::QuicIdleNetworkDetector(
+    Delegate* delegate, QuicTime now, QuicConnectionArena* arena,
+    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
+    : delegate_(delegate),
+      start_time_(now),
+      handshake_timeout_(QuicTime::Delta::Infinite()),
+      time_of_last_received_packet_(now),
+      time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
+      idle_network_timeout_(QuicTime::Delta::Infinite()),
+      alarm_(alarm_factory->CreateAlarm(
+          arena->New<AlarmDelegate>(this, context), arena)) {}
+
+void QuicIdleNetworkDetector::OnAlarm() {
+  if (handshake_timeout_.IsInfinite()) {
+    delegate_->OnIdleNetworkDetected();
+    return;
+  }
+  if (idle_network_timeout_.IsInfinite()) {
+    delegate_->OnHandshakeTimeout();
+    return;
+  }
+  if (last_network_activity_time() + idle_network_timeout_ >
+      start_time_ + handshake_timeout_) {
+    delegate_->OnHandshakeTimeout();
+    return;
+  }
+  delegate_->OnIdleNetworkDetected();
+}
+
+void QuicIdleNetworkDetector::SetTimeouts(
+    QuicTime::Delta handshake_timeout,
+    QuicTime::Delta idle_network_timeout) {
+  handshake_timeout_ = handshake_timeout;
+  idle_network_timeout_ = idle_network_timeout;
+
+  SetAlarm();
+}
+
+void QuicIdleNetworkDetector::StopDetection() {
+  alarm_->PermanentCancel();
+  handshake_timeout_ = QuicTime::Delta::Infinite();
+  idle_network_timeout_ = QuicTime::Delta::Infinite();
+  stopped_ = true;
+}
+
+void QuicIdleNetworkDetector::OnPacketSent(QuicTime now,
+                                           QuicTime::Delta pto_delay) {
+  if (time_of_first_packet_sent_after_receiving_ >
+      time_of_last_received_packet_) {
+    return;
+  }
+  time_of_first_packet_sent_after_receiving_ =
+      std::max(time_of_first_packet_sent_after_receiving_, now);
+  if (shorter_idle_timeout_on_sent_packet_) {
+    MaybeSetAlarmOnSentPacket(pto_delay);
+    return;
+  }
+
+  SetAlarm();
+}
+
+void QuicIdleNetworkDetector::OnPacketReceived(QuicTime now) {
+  time_of_last_received_packet_ = std::max(time_of_last_received_packet_, now);
+
+  SetAlarm();
+}
+
+void QuicIdleNetworkDetector::SetAlarm() {
+  if (stopped_) {
+    // TODO(wub): If this QUIC_BUG fires, it indicates a problem in the
+    // QuicConnection, which somehow called this function while disconnected.
+    // That problem needs to be fixed.
+    QUIC_BUG(quic_idle_detector_set_alarm_after_stopped)
+        << "SetAlarm called after stopped";
+    return;
+  }
+  // Set alarm to the nearer deadline.
+  QuicTime new_deadline = QuicTime::Zero();
+  if (!handshake_timeout_.IsInfinite()) {
+    new_deadline = start_time_ + handshake_timeout_;
+  }
+  if (!idle_network_timeout_.IsInfinite()) {
+    const QuicTime idle_network_deadline = GetIdleNetworkDeadline();
+    if (new_deadline.IsInitialized()) {
+      new_deadline = std::min(new_deadline, idle_network_deadline);
+    } else {
+      new_deadline = idle_network_deadline;
+    }
+  }
+  alarm_->Update(new_deadline, kAlarmGranularity);
+}
+
+void QuicIdleNetworkDetector::MaybeSetAlarmOnSentPacket(
+    QuicTime::Delta pto_delay) {
+  QUICHE_DCHECK(shorter_idle_timeout_on_sent_packet_);
+  if (!handshake_timeout_.IsInfinite() || !alarm_->IsSet()) {
+    SetAlarm();
+    return;
+  }
+  // Make sure connection will be alive for another PTO.
+  const QuicTime deadline = alarm_->deadline();
+  const QuicTime min_deadline = last_network_activity_time() + pto_delay;
+  if (deadline > min_deadline) {
+    return;
+  }
+  alarm_->Update(min_deadline, kAlarmGranularity);
+}
+
+QuicTime QuicIdleNetworkDetector::GetIdleNetworkDeadline() const {
+  if (idle_network_timeout_.IsInfinite()) {
+    return QuicTime::Zero();
+  }
+  return last_network_activity_time() + idle_network_timeout_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_idle_network_detector.h b/quiche/quic/core/quic_idle_network_detector.h
new file mode 100644
index 0000000..0b5a20e
--- /dev/null
+++ b/quiche/quic/core/quic_idle_network_detector.h
@@ -0,0 +1,118 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
+#define QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicIdleNetworkDetectorTestPeer;
+}  // namespace test
+
+// QuicIdleNetworkDetector detects handshake timeout and idle network timeout.
+// Handshake timeout detection is disabled after handshake completes. Idle
+// network deadline is extended by network activity (e.g., sending or receiving
+// packets).
+class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
+ public:
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Called when handshake times out.
+    virtual void OnHandshakeTimeout() = 0;
+
+    // Called when idle network has been detected.
+    virtual void OnIdleNetworkDetected() = 0;
+  };
+
+  QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
+                          QuicConnectionArena* arena,
+                          QuicAlarmFactory* alarm_factory,
+                          QuicConnectionContext* context);
+
+  void OnAlarm();
+
+  // Called to set handshake_timeout_ and idle_network_timeout_.
+  void SetTimeouts(QuicTime::Delta handshake_timeout,
+                   QuicTime::Delta idle_network_timeout);
+
+  // Stop the detection once and for all.
+  void StopDetection();
+
+  // Called when a packet gets sent.
+  void OnPacketSent(QuicTime now, QuicTime::Delta pto_delay);
+
+  // Called when a packet gets received.
+  void OnPacketReceived(QuicTime now);
+
+  void enable_shorter_idle_timeout_on_sent_packet() {
+    shorter_idle_timeout_on_sent_packet_ = true;
+  }
+
+  QuicTime::Delta handshake_timeout() const { return handshake_timeout_; }
+
+  QuicTime time_of_last_received_packet() const {
+    return time_of_last_received_packet_;
+  }
+
+  QuicTime last_network_activity_time() const {
+    return std::max(time_of_last_received_packet_,
+                    time_of_first_packet_sent_after_receiving_);
+  }
+
+  QuicTime::Delta idle_network_timeout() const { return idle_network_timeout_; }
+
+  QuicTime GetIdleNetworkDeadline() const;
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicIdleNetworkDetectorTestPeer;
+
+  void SetAlarm();
+
+  void MaybeSetAlarmOnSentPacket(QuicTime::Delta pto_delay);
+
+  Delegate* delegate_;  // Not owned.
+
+  // Start time of the detector, handshake deadline = start_time_ +
+  // handshake_timeout_.
+  const QuicTime start_time_;
+
+  // Handshake timeout. Infinit means handshake has completed.
+  QuicTime::Delta handshake_timeout_;
+
+  // Time that last packet is received for this connection. Initialized to
+  // start_time_.
+  QuicTime time_of_last_received_packet_;
+
+  // Time that the first packet gets sent after the received packet. idle
+  // network deadline = std::max(time_of_last_received_packet_,
+  // time_of_first_packet_sent_after_receiving_) + idle_network_timeout_.
+  // Initialized to 0.
+  QuicTime time_of_first_packet_sent_after_receiving_;
+
+  // Idle network timeout. Infinit means no idle network timeout.
+  QuicTime::Delta idle_network_timeout_;
+
+  QuicArenaScopedPtr<QuicAlarm> alarm_;
+
+  bool shorter_idle_timeout_on_sent_packet_ = false;
+
+  // Whether |StopDetection| has been called.
+  bool stopped_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_IDLE_NETWORK_DETECTOR_H_
diff --git a/quiche/quic/core/quic_idle_network_detector_test.cc b/quiche/quic/core/quic_idle_network_detector_test.cc
new file mode 100644
index 0000000..31aa8b4
--- /dev/null
+++ b/quiche/quic/core/quic_idle_network_detector_test.cc
@@ -0,0 +1,200 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_idle_network_detector.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class QuicIdleNetworkDetectorTestPeer {
+ public:
+  static QuicAlarm* GetAlarm(QuicIdleNetworkDetector* detector) {
+    return detector->alarm_.get();
+  }
+};
+
+namespace {
+
+class MockDelegate : public QuicIdleNetworkDetector::Delegate {
+ public:
+  MOCK_METHOD(void, OnHandshakeTimeout, (), (override));
+  MOCK_METHOD(void, OnIdleNetworkDetected, (), (override));
+};
+
+class QuicIdleNetworkDetectorTest : public QuicTest {
+ public:
+  QuicIdleNetworkDetectorTest() {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    detector_ = std::make_unique<QuicIdleNetworkDetector>(
+        &delegate_, clock_.Now(), &arena_, &alarm_factory_,
+        /*context=*/nullptr);
+    alarm_ = static_cast<MockAlarmFactory::TestAlarm*>(
+        QuicIdleNetworkDetectorTestPeer::GetAlarm(detector_.get()));
+  }
+
+ protected:
+  testing::StrictMock<MockDelegate> delegate_;
+  QuicConnectionArena arena_;
+  MockAlarmFactory alarm_factory_;
+
+  std::unique_ptr<QuicIdleNetworkDetector> detector_;
+
+  MockAlarmFactory::TestAlarm* alarm_;
+  MockClock clock_;
+};
+
+TEST_F(QuicIdleNetworkDetectorTest,
+       IdleNetworkDetectedBeforeHandshakeCompletes) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(20),
+            alarm_->deadline());
+
+  // No network activity for 20s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
+  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest, HandshakeTimeout) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+
+  // Has network activity after 15s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  detector_->OnPacketReceived(clock_.Now());
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(15),
+            alarm_->deadline());
+  // Handshake does not complete for another 15s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  EXPECT_CALL(delegate_, OnHandshakeTimeout());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest,
+       IdleNetworkDetectedAfterHandshakeCompletes) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+
+  // Handshake completes in 200ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketReceived(clock_.Now());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // No network activity for 600s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600));
+  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest,
+       DoNotExtendIdleDeadlineOnConsecutiveSentPackets) {
+  EXPECT_FALSE(alarm_->IsSet());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+  EXPECT_TRUE(alarm_->IsSet());
+
+  // Handshake completes in 200ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketReceived(clock_.Now());
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // Sent packets after 200ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
+  const QuicTime packet_sent_time = clock_.Now();
+  EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // Sent another packet after 200ms
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
+  // Verify idle network deadline does not extend.
+  EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
+            alarm_->deadline());
+
+  // No network activity for 600s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
+                     QuicTime::Delta::FromMilliseconds(200));
+  EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+  alarm_->Fire();
+}
+
+TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
+  detector_->enable_shorter_idle_timeout_on_sent_packet();
+  detector_->SetTimeouts(
+      /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+      /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(30));
+  EXPECT_TRUE(alarm_->IsSet());
+  const QuicTime deadline = alarm_->deadline();
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30), deadline);
+
+  // Send a packet after 15s and 2s PTO delay.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify alarm does not get extended because deadline is > PTO delay.
+  EXPECT_EQ(deadline, alarm_->deadline());
+
+  // Send another packet near timeout and 2 s PTO delay.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(14));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify alarm does not get extended although it is shorter than PTO.
+  EXPECT_EQ(deadline, alarm_->deadline());
+
+  // Receive a packet after 1s.
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  detector_->OnPacketReceived(clock_.Now());
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify idle timeout gets extended by 30s.
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30),
+            alarm_->deadline());
+
+  // Send a packet near timeout..
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(29));
+  detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
+  EXPECT_TRUE(alarm_->IsSet());
+  // Verify idle timeout gets extended by 1s.
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(2), alarm_->deadline());
+}
+
+TEST_F(QuicIdleNetworkDetectorTest, NoAlarmAfterStopped) {
+  detector_->StopDetection();
+
+  EXPECT_QUIC_BUG(
+      detector_->SetTimeouts(
+          /*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
+          /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20)),
+      "SetAlarm called after stopped");
+  EXPECT_FALSE(alarm_->IsSet());
+}
+
+}  // namespace
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_interval.h b/quiche/quic/core/quic_interval.h
new file mode 100644
index 0000000..040355f
--- /dev/null
+++ b/quiche/quic/core/quic_interval.h
@@ -0,0 +1,390 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
+#define QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
+
+// An QuicInterval<T> is a data structure used to represent a contiguous,
+// mutable range over an ordered type T. Supported operations include testing a
+// value to see whether it is included in the QuicInterval, comparing two
+// QuicIntervals, and performing their union, intersection, and difference. For
+// the purposes of this library, an "ordered type" is any type that induces a
+// total order on its values via its less-than operator (operator<()). Examples
+// of such types are basic arithmetic types like int and double as well as class
+// types like string.
+//
+// An QuicInterval<T> is represented using the usual C++ STL convention, namely
+// as the half-open QuicInterval [min, max). A point p is considered to be
+// contained in the QuicInterval iff p >= min && p < max. One consequence of
+// this definition is that for any non-empty QuicInterval, min is contained in
+// the QuicInterval but max is not. There is no canonical representation for the
+// empty QuicInterval; rather, any QuicInterval where max <= min is regarded as
+// empty. As a consequence, two empty QuicIntervals will still compare as equal
+// despite possibly having different underlying min() or max() values. Also
+// beware of the terminology used here: the library uses the terms "min" and
+// "max" rather than "begin" and "end" as is conventional for the STL.
+//
+// T is required to be default- and copy-constructable, to have an assignment
+// operator, and the full complement of comparison operators (<, <=, ==, !=, >=,
+// >).  A difference operator (operator-()) is required if
+// QuicInterval<T>::Length is used.
+//
+// QuicInterval supports operator==. Two QuicIntervals are considered equal if
+// either they are both empty or if their corresponding min and max fields
+// compare equal. QuicInterval also provides an operator<. Unfortunately,
+// operator< is currently buggy because its behavior is inconsistent with
+// operator==: two empty ranges with different representations may be regarded
+// as equal by operator== but regarded as different by operator<. Bug 9240050
+// has been created to address this.
+//
+//
+// Examples:
+//   QuicInterval<int> r1(0, 100);  // The QuicInterval [0, 100).
+//   EXPECT_TRUE(r1.Contains(0));
+//   EXPECT_TRUE(r1.Contains(50));
+//   EXPECT_FALSE(r1.Contains(100));  // 100 is just outside the QuicInterval.
+//
+//   QuicInterval<int> r2(50, 150);  // The QuicInterval [50, 150).
+//   EXPECT_TRUE(r1.Intersects(r2));
+//   EXPECT_FALSE(r1.Contains(r2));
+//   EXPECT_TRUE(r1.IntersectWith(r2));  // Mutates r1.
+//   EXPECT_EQ(QuicInterval<int>(50, 100), r1);  // r1 is now [50, 100).
+//
+//   QuicInterval<int> r3(1000, 2000);  // The QuicInterval [1000, 2000).
+//   EXPECT_TRUE(r1.IntersectWith(r3));  // Mutates r1.
+//   EXPECT_TRUE(r1.Empty());  // Now r1 is empty.
+//   EXPECT_FALSE(r1.Contains(r1.min()));  // e.g. doesn't contain its own min.
+
+#include <stddef.h>
+#include <algorithm>
+#include <ostream>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_NO_EXPORT QuicInterval {
+ private:
+  // Type trait for deriving the return type for QuicInterval::Length.  If
+  // operator-() is not defined for T, then the return type is void.  This makes
+  // the signature for Length compile so that the class can be used for such T,
+  // but code that calls Length would still generate a compilation error.
+  template <typename U>
+  class QUIC_NO_EXPORT DiffTypeOrVoid {
+   private:
+    template <typename V>
+    static auto f(const V* v) -> decltype(*v - *v);
+    template <typename V>
+    static void f(...);
+
+   public:
+    using type = typename std::decay<decltype(f<U>(nullptr))>::type;
+  };
+
+ public:
+  // Construct an QuicInterval representing an empty QuicInterval.
+  QuicInterval() : min_(), max_() {}
+
+  // Construct an QuicInterval representing the QuicInterval [min, max). If min
+  // < max, the constructed object will represent the non-empty QuicInterval
+  // containing all values from min up to (but not including) max. On the other
+  // hand, if min >= max, the constructed object will represent the empty
+  // QuicInterval.
+  QuicInterval(const T& min, const T& max) : min_(min), max_(max) {}
+
+  template <typename U1,
+            typename U2,
+            typename = typename std::enable_if<
+                std::is_convertible<U1, T>::value &&
+                std::is_convertible<U2, T>::value>::type>
+  QuicInterval(U1&& min, U2&& max)
+      : min_(std::forward<U1>(min)), max_(std::forward<U2>(max)) {}
+
+  const T& min() const { return min_; }
+  const T& max() const { return max_; }
+  void SetMin(const T& t) { min_ = t; }
+  void SetMax(const T& t) { max_ = t; }
+
+  void Set(const T& min, const T& max) {
+    SetMin(min);
+    SetMax(max);
+  }
+
+  void Clear() { *this = {}; }
+
+  bool Empty() const { return min() >= max(); }
+
+  // Returns the length of this QuicInterval. The value returned is zero if
+  // Empty() is true; otherwise the value returned is max() - min().
+  typename DiffTypeOrVoid<T>::type Length() const {
+    return (Empty() ? min() : max()) - min();
+  }
+
+  // Returns true iff t >= min() && t < max().
+  bool Contains(const T& t) const { return min() <= t && max() > t; }
+
+  // Returns true iff *this and i are non-empty, and *this includes i. "*this
+  // includes i" means that for all t, if i.Contains(t) then this->Contains(t).
+  // Note the unintuitive consequence of this definition: this method always
+  // returns false when i is the empty QuicInterval.
+  bool Contains(const QuicInterval& i) const {
+    return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max();
+  }
+
+  // Returns true iff there exists some point t for which this->Contains(t) &&
+  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
+  bool Intersects(const QuicInterval& i) const {
+    return !Empty() && !i.Empty() && min() < i.max() && max() > i.min();
+  }
+
+  // Returns true iff there exists some point t for which this->Contains(t) &&
+  // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty.
+  // Furthermore, if the intersection is non-empty and the out pointer is not
+  // null, this method stores the calculated intersection in *out.
+  bool Intersects(const QuicInterval& i, QuicInterval* out) const;
+
+  // Sets *this to be the intersection of itself with i. Returns true iff
+  // *this was modified.
+  bool IntersectWith(const QuicInterval& i);
+
+  // Returns true iff this and other have disjoint closures.  For nonempty
+  // intervals, that means there is at least one point between this and other.
+  // Roughly speaking that means the intervals don't intersect, and they are not
+  // adjacent.   Empty intervals are always separated from any other interval.
+  bool Separated(const QuicInterval& other) const {
+    if (Empty() || other.Empty())
+      return true;
+    return other.max() < min() || max() < other.min();
+  }
+
+  // Calculates the smallest QuicInterval containing both *this i, and updates
+  // *this to represent that QuicInterval, and returns true iff *this was
+  // modified.
+  bool SpanningUnion(const QuicInterval& i);
+
+  // Determines the difference between two QuicIntervals by finding all points
+  // that are contained in *this but not in i, coalesces those points into the
+  // largest possible contiguous QuicIntervals, and appends those QuicIntervals
+  // to the *difference vector. Intuitively this can be thought of as "erasing"
+  // i from *this. This will either completely erase *this (leaving nothing
+  // behind), partially erase some of *this from the left or right side (leaving
+  // some residual behind), or erase a hole in the middle of *this (leaving
+  // behind an QuicInterval on either side). Therefore, 0, 1, or 2 QuicIntervals
+  // will be appended to *difference. The method returns true iff the
+  // intersection of *this and i is non-empty. The caller owns the vector and
+  // the QuicInterval* pointers inside it. The difference vector is required to
+  // be non-null.
+  bool Difference(const QuicInterval& i,
+                  std::vector<QuicInterval*>* difference) const;
+
+  // Determines the difference between two QuicIntervals as in
+  // Difference(QuicInterval&, vector*), but stores the results directly in out
+  // parameters rather than dynamically allocating an QuicInterval* and
+  // appending it to a vector. If two results are generated, the one with the
+  // smaller value of min() will be stored in *lo and the other in *hi.
+  // Otherwise (if fewer than two results are generated), unused arguments will
+  // be set to the empty QuicInterval (it is possible that *lo will be empty and
+  // *hi non-empty). The method returns true iff the intersection of *this and i
+  // is non-empty.
+  bool Difference(const QuicInterval& i,
+                  QuicInterval* lo,
+                  QuicInterval* hi) const;
+
+  friend bool operator==(const QuicInterval& a, const QuicInterval& b) {
+    bool ae = a.Empty();
+    bool be = b.Empty();
+    if (ae && be)
+      return true;  // All empties are equal.
+    if (ae != be)
+      return false;  // Empty cannot equal nonempty.
+    return a.min() == b.min() && a.max() == b.max();
+  }
+
+  friend bool operator!=(const QuicInterval& a, const QuicInterval& b) {
+    return !(a == b);
+  }
+
+  // Defines a comparator which can be used to induce an order on QuicIntervals,
+  // so that, for example, they can be stored in an ordered container such as
+  // std::set. The ordering is arbitrary, but does provide the guarantee that,
+  // for non-empty QuicIntervals X and Y, if X contains Y, then X <= Y.
+  // TODO(kosak): The current implementation of this comparator has a problem
+  // because the ordering it induces is inconsistent with that of Equals(). In
+  // particular, this comparator does not properly consider all empty
+  // QuicIntervals equivalent. Bug 9240050 has been created to track this.
+  friend bool operator<(const QuicInterval& a, const QuicInterval& b) {
+    return a.min() < b.min() || (!(b.min() < a.min()) && b.max() < a.max());
+  }
+
+ private:
+  T min_;  // Inclusive lower bound.
+  T max_;  // Exclusive upper bound.
+};
+
+// Constructs an QuicInterval by deducing the types from the function arguments.
+template <typename T>
+QuicInterval<T> MakeQuicInterval(T&& lhs, T&& rhs) {
+  return QuicInterval<T>(std::forward<T>(lhs), std::forward<T>(rhs));
+}
+
+// Note: ideally we'd use
+//   decltype(out << "[" << i.min() << ", " << i.max() << ")")
+// as return type of the function, but as of July 2017 this triggers g++
+// "sorry, unimplemented: string literal in function template signature" error.
+template <typename T>
+auto operator<<(std::ostream& out, const QuicInterval<T>& i)
+    -> decltype(out << i.min()) {
+  return out << "[" << i.min() << ", " << i.max() << ")";
+}
+
+//==============================================================================
+// Implementation details: Clients can stop reading here.
+
+template <typename T>
+bool QuicInterval<T>::Intersects(const QuicInterval& i,
+                                 QuicInterval* out) const {
+  if (!Intersects(i))
+    return false;
+  if (out != nullptr) {
+    *out = QuicInterval(std::max(min(), i.min()), std::min(max(), i.max()));
+  }
+  return true;
+}
+
+template <typename T>
+bool QuicInterval<T>::IntersectWith(const QuicInterval& i) {
+  if (Empty())
+    return false;
+  bool modified = false;
+  if (i.min() > min()) {
+    SetMin(i.min());
+    modified = true;
+  }
+  if (i.max() < max()) {
+    SetMax(i.max());
+    modified = true;
+  }
+  return modified;
+}
+
+template <typename T>
+bool QuicInterval<T>::SpanningUnion(const QuicInterval& i) {
+  if (i.Empty())
+    return false;
+  if (Empty()) {
+    *this = i;
+    return true;
+  }
+  bool modified = false;
+  if (i.min() < min()) {
+    SetMin(i.min());
+    modified = true;
+  }
+  if (i.max() > max()) {
+    SetMax(i.max());
+    modified = true;
+  }
+  return modified;
+}
+
+template <typename T>
+bool QuicInterval<T>::Difference(const QuicInterval& i,
+                                 std::vector<QuicInterval*>* difference) const {
+  if (Empty()) {
+    // <empty> - <i> = <empty>
+    return false;
+  }
+  if (i.Empty()) {
+    // <this> - <empty> = <this>
+    difference->push_back(new QuicInterval(*this));
+    return false;
+  }
+  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
+    //            [------ this ------)
+    // [------ i ------)
+    //                 [-- result ---)
+    difference->push_back(new QuicInterval(i.max(), max()));
+    return true;
+  }
+  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
+    // [------ this ------)
+    //            [------ i ------)
+    // [- result -)
+    difference->push_back(new QuicInterval(min(), i.min()));
+    return true;
+  }
+  if (min() < i.min() && max() > i.max()) {
+    // [------- this --------)
+    //      [---- i ----)
+    // [ R1 )           [ R2 )
+    // There are two results: R1 and R2.
+    difference->push_back(new QuicInterval(min(), i.min()));
+    difference->push_back(new QuicInterval(i.max(), max()));
+    return true;
+  }
+  if (min() >= i.min() && max() <= i.max()) {
+    //   [--- this ---)
+    // [------ i --------)
+    // Intersection is <this>, so difference yields the empty QuicInterval.
+    // Nothing is appended to *difference.
+    return true;
+  }
+  // No intersection. Append <this>.
+  difference->push_back(new QuicInterval(*this));
+  return false;
+}
+
+template <typename T>
+bool QuicInterval<T>::Difference(const QuicInterval& i,
+                                 QuicInterval* lo,
+                                 QuicInterval* hi) const {
+  // Initialize *lo and *hi to empty
+  *lo = {};
+  *hi = {};
+  if (Empty())
+    return false;
+  if (i.Empty()) {
+    *lo = *this;
+    return false;
+  }
+  if (min() < i.max() && min() >= i.min() && max() > i.max()) {
+    //            [------ this ------)
+    // [------ i ------)
+    //                 [-- result ---)
+    *hi = QuicInterval(i.max(), max());
+    return true;
+  }
+  if (max() > i.min() && max() <= i.max() && min() < i.min()) {
+    // [------ this ------)
+    //            [------ i ------)
+    // [- result -)
+    *lo = QuicInterval(min(), i.min());
+    return true;
+  }
+  if (min() < i.min() && max() > i.max()) {
+    // [------- this --------)
+    //      [---- i ----)
+    // [ R1 )           [ R2 )
+    // There are two results: R1 and R2.
+    *lo = QuicInterval(min(), i.min());
+    *hi = QuicInterval(i.max(), max());
+    return true;
+  }
+  if (min() >= i.min() && max() <= i.max()) {
+    //   [--- this ---)
+    // [------ i --------)
+    // Intersection is <this>, so difference yields the empty QuicInterval.
+    return true;
+  }
+  *lo = *this;  // No intersection.
+  return false;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_H_
diff --git a/quiche/quic/core/quic_interval_deque.h b/quiche/quic/core/quic_interval_deque.h
new file mode 100644
index 0000000..f4bf092
--- /dev/null
+++ b/quiche/quic/core/quic_interval_deque.h
@@ -0,0 +1,393 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
+#define QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
+
+#include <algorithm>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicIntervalDequePeer;
+}  // namespace test
+
+// QuicIntervalDeque<T, C> is a templated wrapper container, wrapping random
+// access data structures. The wrapper allows items to be added to the
+// underlying container with intervals associated with each item. The intervals
+// _should_ be added already sorted and represent searchable indices. The search
+// is optimized for sequential usage.
+//
+// As the intervals are to be searched sequentially the search for the next
+// interval can be achieved in O(1), by simply remembering the last interval
+// consumed. The structure also checks for an "off-by-one" use case wherein the
+// |cached_index_| is off by one index as the caller didn't call operator |++|
+// to increment the index. Other intervals can be found in O(log(n)) as they are
+// binary searchable. A use case for this structure is packet buffering: Packets
+// are sent sequentially but can sometimes needed for retransmission. The
+// packets and their payloads are added with associated intervals representing
+// data ranges they carry. When a user asks for a particular interval it's very
+// likely they are requesting the next sequential interval, receiving it in O(1)
+// time. Updating the sequential index is done automatically through the
+// |DataAt| method and its iterator operator |++|.
+//
+// The intervals are represented using the usual C++ STL convention, namely as
+// the half-open QuicInterval [min, max). A point p is considered to be
+// contained in the QuicInterval iff p >= min && p < max. One consequence of
+// this definition is that for any non-empty QuicInterval, min is contained in
+// the QuicInterval but max is not. There is no canonical representation for the
+// empty QuicInterval; and empty intervals are forbidden from being added to
+// this container as they would be unsearchable.
+//
+// The type T is required to be copy-constructable or move-constructable. The
+// type T is also expected to have an |interval()| method returning a
+// QuicInterval<std::size> for the particular value. The type C is required to
+// be a random access container supporting the methods |pop_front|, |push_back|,
+// |operator[]|, |size|, and iterator support for |std::lower_bound| eg. a
+// |deque| or |vector|.
+//
+// The QuicIntervalDeque<T, C>, like other C++ STL random access containers,
+// doesn't have any explicit support for any equality operators.
+//
+//
+// Examples with internal state:
+//
+//   // An example class to be stored inside the Interval Deque.
+//   struct IntervalVal {
+//     const int32_t val;
+//     const size_t interval_begin, interval_end;
+//     QuicInterval<size_t> interval();
+//   };
+//   typedef IntervalVal IV;
+//   QuicIntervialDeque<IntervalValue> deque;
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {}
+//
+//   // Add interval items
+//   deque.PushBack(IV(val: 0, interval_begin: 0, interval_end: 10));
+//   deque.PushBack(IV(val: 1, interval_begin: 20, interval_end: 25));
+//   deque.PushBack(IV(val: 2, interval_begin: 25, interval_end: 30));
+//
+//   // State:
+//   //   cached_index -> 0
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look for 0 and return [0, 10). Time: O(1)
+//   auto it = deque.DataAt(0);
+//   assert(it->val == 0);
+//   it++;  // Increment and move the |cached_index_| over [0, 10) to [20, 25).
+//   assert(it->val == 1);
+//
+//   // State:
+//   //   cached_index -> 1
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look for 20 and return [20, 25). Time: O(1)
+//   auto it = deque.DataAt(20); // |cached_index_| remains unchanged.
+//   assert(it->val == 1);
+//
+//   // State:
+//   //   cached_index -> 1
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look for 15 and return deque.DataEnd(). Time: O(log(n))
+//   auto it = deque.DataAt(15); // |cached_index_| remains unchanged.
+//   assert(it == deque.DataEnd());
+//
+//   // Look for 25 and return [25, 30). Time: O(1) with off-by-one.
+//   auto it = deque.DataAt(25); // |cached_index_| is updated to 2.
+//   assert(it->val == 2);
+//   it++; // |cached_index_| is set to |None| as all data has been iterated.
+//
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {{0, [0, 10)}, {1, [20, 25)}, {2, [25, 30)}}
+//
+//   // Look again for 0 and return [0, 10). Time: O(log(n))
+//   auto it = deque.DataAt(0);
+//
+//
+//   deque.PopFront();  // Pop -> {0, [0, 10)}
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {{1, [20, 25)}, {2, [25, 30)}}
+//
+//   deque.PopFront();  // Pop -> {1, [20, 25)}
+//
+//   // State:
+//   //   cached_index -> None
+//   //   container -> {{2, [25, 30)}}
+//
+//   deque.PushBack(IV(val: 3, interval_begin: 35, interval_end: 50));
+//
+//   // State:
+//   //   cached_index -> 1
+//   //   container -> {{2, [25, 30)}, {3, [35, 50)}}
+
+template <class T, class C = QUIC_NO_EXPORT quiche::QuicheCircularDeque<T>>
+class QUIC_NO_EXPORT QuicIntervalDeque {
+ public:
+  class QUIC_NO_EXPORT Iterator {
+   public:
+    // Used by |std::lower_bound|
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = T;
+    using difference_type = std::ptrdiff_t;
+    using pointer = T*;
+    using reference = T&;
+
+    // Every increment of the iterator will increment the |cached_index_| if
+    // |index_| is larger than the current |cached_index_|. |index_| is bounded
+    // at |deque_.size()| and any attempt to increment above that will be
+    // ignored. Once an iterator has iterated all elements the |cached_index_|
+    // will be reset.
+    Iterator(std::size_t index, QuicIntervalDeque* deque)
+        : index_(index), deque_(deque) {}
+    // Only the ++ operator attempts to update the cached index. Other operators
+    // are used by |lower_bound| to binary search and are thus private.
+    Iterator& operator++() {
+      // Don't increment when we are at the end.
+      const std::size_t container_size = deque_->container_.size();
+      if (index_ >= container_size) {
+        QUIC_BUG(quic_bug_10862_1) << "Iterator out of bounds.";
+        return *this;
+      }
+      index_++;
+      if (deque_->cached_index_.has_value()) {
+        const std::size_t cached_index = deque_->cached_index_.value();
+        // If all items are iterated then reset the |cached_index_|
+        if (index_ == container_size) {
+          deque_->cached_index_.reset();
+        } else {
+          // Otherwise the new |cached_index_| is the max of itself and |index_|
+          if (cached_index < index_) {
+            deque_->cached_index_ = index_;
+          }
+        }
+      }
+      return *this;
+    }
+    Iterator operator++(int) {
+      Iterator copy = *this;
+      ++(*this);
+      return copy;
+    }
+    reference operator*() { return deque_->container_[index_]; }
+    reference operator*() const { return deque_->container_[index_]; }
+    pointer operator->() { return &deque_->container_[index_]; }
+    bool operator==(const Iterator& rhs) const {
+      return index_ == rhs.index_ && deque_ == rhs.deque_;
+    }
+    bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
+
+   private:
+    // A set of private operators for |std::lower_bound|
+    Iterator operator+(difference_type amount) const {
+      Iterator copy = *this;
+      copy.index_ += amount;
+      QUICHE_DCHECK(copy.index_ < copy.deque_->size());
+      return copy;
+    }
+    Iterator& operator+=(difference_type amount) {
+      index_ += amount;
+      QUICHE_DCHECK(index_ < deque_->size());
+      return *this;
+    }
+    difference_type operator-(const Iterator& rhs) const {
+      return static_cast<difference_type>(index_) -
+             static_cast<difference_type>(rhs.index_);
+    }
+
+    // |index_| is the index of the item in |*deque_|.
+    std::size_t index_;
+    // |deque_| is a pointer to the container the iterator came from.
+    QuicIntervalDeque* deque_;
+
+    friend class QuicIntervalDeque;
+  };
+
+  QuicIntervalDeque();
+
+  // Adds an item to the underlying container. The |item|'s interval _should_ be
+  // strictly greater than the last interval added.
+  void PushBack(T&& item);
+  void PushBack(const T& item);
+  // Removes the front/top of the underlying container and the associated
+  // interval.
+  void PopFront();
+  // Returns an iterator to the beginning of the data. The iterator will move
+  // the |cached_index_| as the iterator moves.
+  Iterator DataBegin();
+  // Returns an iterator to the end of the data.
+  Iterator DataEnd();
+  // Returns an iterator pointing to the item in |interval_begin|. The iterator
+  // will move the |cached_index_| as the iterator moves.
+  Iterator DataAt(const std::size_t interval_begin);
+
+  // Returns the number of items contained inside the structure.
+  std::size_t Size() const;
+  // Returns whether the structure is empty.
+  bool Empty() const;
+
+ private:
+  struct QUIC_NO_EXPORT IntervalCompare {
+    bool operator()(const T& item, std::size_t interval_begin) const {
+      return item.interval().max() <= interval_begin;
+    }
+  };
+
+  template <class U>
+  void PushBackUniversal(U&& item);
+
+  Iterator Search(const std::size_t interval_begin,
+                  const std::size_t begin_index,
+                  const std::size_t end_index);
+
+  // For accessing the |cached_index_|
+  friend class test::QuicIntervalDequePeer;
+
+  C container_;
+  absl::optional<std::size_t> cached_index_;
+};
+
+template <class T, class C>
+QuicIntervalDeque<T, C>::QuicIntervalDeque() {}
+
+template <class T, class C>
+void QuicIntervalDeque<T, C>::PushBack(T&& item) {
+  PushBackUniversal(std::move(item));
+}
+
+template <class T, class C>
+void QuicIntervalDeque<T, C>::PushBack(const T& item) {
+  PushBackUniversal(item);
+}
+
+template <class T, class C>
+void QuicIntervalDeque<T, C>::PopFront() {
+  if (container_.size() == 0) {
+    QUIC_BUG(quic_bug_10862_2) << "Trying to pop from an empty container.";
+    return;
+  }
+  container_.pop_front();
+  if (container_.size() == 0) {
+    cached_index_.reset();
+  }
+  if (cached_index_.value_or(0) > 0) {
+    cached_index_ = cached_index_.value() - 1;
+  }
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator
+QuicIntervalDeque<T, C>::DataBegin() {
+  return Iterator(0, this);
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataEnd() {
+  return Iterator(container_.size(), this);
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::DataAt(
+    const std::size_t interval_begin) {
+  // No |cached_index_| value means all items can be searched.
+  if (!cached_index_.has_value()) {
+    return Search(interval_begin, 0, container_.size());
+  }
+
+  const std::size_t cached_index = cached_index_.value();
+  QUICHE_DCHECK(cached_index < container_.size());
+
+  const QuicInterval<size_t> cached_interval =
+      container_[cached_index].interval();
+  // Does our cached index point directly to what we want?
+  if (cached_interval.Contains(interval_begin)) {
+    return Iterator(cached_index, this);
+  }
+
+  // Are we off-by-one?
+  const std::size_t next_index = cached_index + 1;
+  if (next_index < container_.size()) {
+    if (container_[next_index].interval().Contains(interval_begin)) {
+      cached_index_ = next_index;
+      return Iterator(next_index, this);
+    }
+  }
+
+  // Small optimization:
+  // Determine if we should binary search above or below the cached interval.
+  const std::size_t cached_begin = cached_interval.min();
+  bool looking_below = interval_begin < cached_begin;
+  const std::size_t lower = looking_below ? 0 : cached_index + 1;
+  const std::size_t upper = looking_below ? cached_index : container_.size();
+  Iterator ret = Search(interval_begin, lower, upper);
+  if (ret == DataEnd()) {
+    return ret;
+  }
+  // Update the |cached_index_| to point to the higher index.
+  if (!looking_below) {
+    cached_index_ = ret.index_;
+  }
+  return ret;
+}
+
+template <class T, class C>
+std::size_t QuicIntervalDeque<T, C>::Size() const {
+  return container_.size();
+}
+
+template <class T, class C>
+bool QuicIntervalDeque<T, C>::Empty() const {
+  return container_.size() == 0;
+}
+
+template <class T, class C>
+template <class U>
+void QuicIntervalDeque<T, C>::PushBackUniversal(U&& item) {
+  QuicInterval<std::size_t> interval = item.interval();
+  // Adding an empty interval is a bug.
+  if (interval.Empty()) {
+    QUIC_BUG(quic_bug_10862_3)
+        << "Trying to save empty interval to quiche::QuicheCircularDeque.";
+    return;
+  }
+  container_.push_back(std::forward<U>(item));
+  if (!cached_index_.has_value()) {
+    cached_index_ = container_.size() - 1;
+  }
+}
+
+template <class T, class C>
+typename QuicIntervalDeque<T, C>::Iterator QuicIntervalDeque<T, C>::Search(
+    const std::size_t interval_begin,
+    const std::size_t begin_index,
+    const std::size_t end_index) {
+  auto begin = container_.begin() + begin_index;
+  auto end = container_.begin() + end_index;
+  auto res = std::lower_bound(begin, end, interval_begin, IntervalCompare());
+  // Just because we run |lower_bound| and it didn't return |container_.end()|
+  // doesn't mean we found our desired interval.
+  if (res != end && res->interval().Contains(interval_begin)) {
+    return Iterator(std::distance(begin, res) + begin_index, this);
+  }
+  return DataEnd();
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_DEQUE_H_
diff --git a/quiche/quic/core/quic_interval_deque_test.cc b/quiche/quic/core/quic_interval_deque_test.cc
new file mode 100644
index 0000000..8a1f028
--- /dev/null
+++ b/quiche/quic/core/quic_interval_deque_test.cc
@@ -0,0 +1,360 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_interval_deque.h"
+#include <cstdint>
+#include <ostream>
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_interval_deque_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const int32_t kSize = 100;
+const std::size_t kIntervalStep = 10;
+
+}  // namespace
+
+struct TestIntervalItem {
+  int32_t val;
+  std::size_t interval_start, interval_end;
+  QuicInterval<std::size_t> interval() const {
+    return QuicInterval<std::size_t>(interval_start, interval_end);
+  }
+  TestIntervalItem(int32_t val,
+                   std::size_t interval_start,
+                   std::size_t interval_end)
+      : val(val), interval_start(interval_start), interval_end(interval_end) {}
+};
+
+using QID = QuicIntervalDeque<TestIntervalItem>;
+
+class QuicIntervalDequeTest : public QuicTest {
+ public:
+  QuicIntervalDequeTest() {
+    // Add items with intervals of |kIntervalStep| size.
+    for (int32_t i = 0; i < kSize; ++i) {
+      const std::size_t interval_begin = kIntervalStep * i;
+      const std::size_t interval_end = interval_begin + kIntervalStep;
+      qid_.PushBack(TestIntervalItem(i, interval_begin, interval_end));
+    }
+  }
+
+  QID qid_;
+};
+
+// The goal of this test is to show insertion/push_back, iteration, and and
+// deletion/pop_front from the container.
+TEST_F(QuicIntervalDequeTest, InsertRemoveSize) {
+  QID qid;
+
+  EXPECT_EQ(qid.Size(), std::size_t(0));
+  qid.PushBack(TestIntervalItem(0, 0, 10));
+  EXPECT_EQ(qid.Size(), std::size_t(1));
+  qid.PushBack(TestIntervalItem(1, 10, 20));
+  EXPECT_EQ(qid.Size(), std::size_t(2));
+  qid.PushBack(TestIntervalItem(2, 20, 30));
+  EXPECT_EQ(qid.Size(), std::size_t(3));
+  qid.PushBack(TestIntervalItem(3, 30, 40));
+  EXPECT_EQ(qid.Size(), std::size_t(4));
+
+  // Advance the index all the way...
+  int32_t i = 0;
+  for (auto it = qid.DataAt(0); it != qid.DataEnd(); ++it, ++i) {
+    const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
+    EXPECT_EQ(index, i);
+    EXPECT_EQ(it->val, i);
+  }
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid);
+  EXPECT_EQ(index, -1);
+
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(3));
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(2));
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(1));
+  qid.PopFront();
+  EXPECT_EQ(qid.Size(), std::size_t(0));
+
+  EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show how the |DataAt| method can move the |cached_index| as the
+// iterator moves through the data.
+TEST_F(QuicIntervalDequeTest, InsertIterateWhole) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  auto it = qid_.DataBegin();
+  auto end = qid_.DataEnd();
+  for (int32_t i = 0; i < kSize; ++i, ++it) {
+    EXPECT_EQ(it->val, i);
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // Make sure the index hasn't changed just from using |DataAt|
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_before, i);
+    // This increment should move the index forward.
+    lookup++;
+    // Check that the index has changed.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
+    EXPECT_EQ(index_after, after_i);
+    EXPECT_NE(it, end);
+  }
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show how the |DataAt| method can move the |cached_index| using
+// the off-by-one logic.
+TEST_F(QuicIntervalDequeTest, OffByOne) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  auto it = qid_.DataBegin();
+  auto end = qid_.DataEnd();
+  for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
+    EXPECT_EQ(it->val, i);
+    const int32_t off_by_one_i = i + 1;
+    const std::size_t current_iteraval_begin = off_by_one_i * kIntervalStep;
+    // Make sure the index has changed just from using |DataAt|
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_before, i);
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(off_by_one_i, lookup->val);
+    // Check that the index has changed.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = off_by_one_i == kSize ? -1 : off_by_one_i;
+    EXPECT_EQ(index_after, after_i);
+    EXPECT_NE(it, end);
+  }
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show modify the structure with a live iterator.
+TEST_F(QuicIntervalDequeTest, IteratorInvalidation) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  const std::size_t iteraval_begin = (kSize - 1) * kIntervalStep;
+  auto lookup = qid_.DataAt(iteraval_begin);
+  EXPECT_EQ((*lookup).val, (kSize - 1));
+  qid_.PopFront();
+  EXPECT_QUIC_BUG(lookup++, "Iterator out of bounds.");
+  auto lookup_end = qid_.DataAt(iteraval_begin + kIntervalStep);
+  EXPECT_EQ(lookup_end, qid_.DataEnd());
+}
+
+// The goal of this test is the same as |InsertIterateWhole| but to
+// skip certain intervals and show the |cached_index| is updated properly.
+TEST_F(QuicIntervalDequeTest, InsertIterateSkip) {
+  // The write index should point to the beginning of the container.
+  const int32_t cached_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(cached_index, 0);
+
+  const std::size_t step = 4;
+  for (int32_t i = 0; i < kSize; i += 4) {
+    if (i != 0) {
+      const int32_t before_i = (i - (step - 1));
+      EXPECT_EQ(QuicIntervalDequePeer::GetCachedIndex(&qid_), before_i);
+    }
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // Make sure the index _has_ changed just from using |DataAt| since we're
+    // skipping data.
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_before, i);
+    // This increment should move the index forward.
+    lookup++;
+    // Check that the index has changed.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
+    EXPECT_EQ(index_after, after_i);
+  }
+}
+
+// The goal of this test is the same as |InsertIterateWhole| but it has
+// |PopFront| calls interleaved to show the |cached_index| updates correctly.
+TEST_F(QuicIntervalDequeTest, InsertDeleteIterate) {
+  // The write index should point to the beginning of the container.
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index, 0);
+
+  std::size_t limit = 0;
+  for (int32_t i = 0; limit < qid_.Size(); ++i, ++limit) {
+    // Always point to the beginning of the container.
+    auto it = qid_.DataBegin();
+    EXPECT_EQ(it->val, i);
+
+    // Get an iterator.
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    // The index should always point to 0.
+    EXPECT_EQ(index_before, 0);
+    // This iterator increment should effect the index.
+    lookup++;
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_after, 1);
+    // Decrement the |temp_size| and pop from the front.
+    qid_.PopFront();
+    // Show the index has been updated to point to 0 again (from 1).
+    const int32_t index_after_pop =
+        QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_after_pop, 0);
+  }
+}
+
+// The goal of this test is to move the index to the end and then add more data
+// to show it can be reset to a valid index.
+TEST_F(QuicIntervalDequeTest, InsertIterateInsert) {
+  // The write index should point to the beginning of the container.
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index, 0);
+
+  int32_t iterated_elements = 0;
+  for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
+    // Get an iterator.
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    // The index should always point to i.
+    EXPECT_EQ(index_before, i);
+    // This iterator increment should effect the index.
+    lookup++;
+    // Show the index has been updated to point to i + 1 or -1 if at the end.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1) == kSize ? -1 : (i + 1);
+    EXPECT_EQ(index_after, after_i);
+  }
+  const int32_t invalid_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(invalid_index, -1);
+
+  // Add more data to the container, making the index valid.
+  const std::size_t offset = qid_.Size();
+  for (int32_t i = 0; i < kSize; ++i) {
+    const std::size_t interval_begin = offset + (kIntervalStep * i);
+    const std::size_t interval_end = offset + interval_begin + kIntervalStep;
+    qid_.PushBack(TestIntervalItem(i + offset, interval_begin, interval_end));
+    const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    // Index should now be valid and equal to the size of the container before
+    // adding more items to it.
+    EXPECT_EQ(index_current, iterated_elements);
+  }
+  // Show the index is still valid and hasn't changed since the first iteration
+  // of the loop.
+  const int32_t index_after_add = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index_after_add, iterated_elements);
+
+  // Iterate over all the data in the container and eventually reset the index
+  // as we did before.
+  for (int32_t i = 0; i < kSize; ++i, ++iterated_elements) {
+    const std::size_t interval_begin = offset + (kIntervalStep * i);
+    const int32_t index_current = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_current, iterated_elements);
+    auto lookup = qid_.DataAt(interval_begin);
+    const int32_t expected_value = i + offset;
+    EXPECT_EQ(lookup->val, expected_value);
+    lookup++;
+    const int32_t after_inc =
+        (iterated_elements + 1) == (kSize * 2) ? -1 : (iterated_elements + 1);
+    const int32_t after_index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(after_index, after_inc);
+  }
+  // Show the index is now invalid.
+  const int32_t invalid_index_again =
+      QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(invalid_index_again, -1);
+}
+
+// The goal of this test is to push data into the container at specific
+// intervals and show how the |DataAt| can iterate over already scanned data.
+TEST_F(QuicIntervalDequeTest, RescanData) {
+  // The write index should point to the beginning of the container.
+  const int32_t index = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+  EXPECT_EQ(index, 0);
+
+  auto it = qid_.DataBegin();
+  auto end = qid_.DataEnd();
+  for (int32_t i = 0; i < kSize - 1; ++i, ++it) {
+    EXPECT_EQ(it->val, i);
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // Make sure the index has changed just from using |DataAt|
+    const int32_t cached_index_before =
+        QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(cached_index_before, i);
+    // Ensure the real index has changed just from using |DataAt| and the
+    // off-by-one logic
+    const int32_t index_before = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t before_i = i;
+    EXPECT_EQ(index_before, before_i);
+    // This increment should move the cached index forward.
+    lookup++;
+    // Check that the cached index has moved foward.
+    const int32_t cached_index_after =
+        QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    const int32_t after_i = (i + 1);
+    EXPECT_EQ(cached_index_after, after_i);
+    EXPECT_NE(it, end);
+  }
+
+  // Iterate over items which have been consumed before.
+  int32_t expected_index = static_cast<int32_t>(kSize - 1);
+  for (int32_t i = 0; i < kSize - 1; ++i) {
+    const std::size_t current_iteraval_begin = i * kIntervalStep;
+    // The |DataAt| method should find the correct interval.
+    auto lookup = qid_.DataAt(current_iteraval_begin);
+    EXPECT_EQ(i, lookup->val);
+    // This increment shouldn't move the index forward as the index is currently
+    // ahead.
+    lookup++;
+    // Check that the index hasn't moved foward.
+    const int32_t index_after = QuicIntervalDequePeer::GetCachedIndex(&qid_);
+    EXPECT_EQ(index_after, expected_index);
+    EXPECT_NE(it, end);
+  }
+}
+
+// The goal of this test is to show that popping from an empty container is a
+// bug.
+TEST_F(QuicIntervalDequeTest, PopEmpty) {
+  QID qid;
+  EXPECT_TRUE(qid.Empty());
+  EXPECT_QUIC_BUG(qid.PopFront(), "Trying to pop from an empty container.");
+}
+
+// The goal of this test is to show that adding a zero-sized interval is a bug.
+TEST_F(QuicIntervalDequeTest, ZeroSizedInterval) {
+  QID qid;
+  EXPECT_QUIC_BUG(qid.PushBack(TestIntervalItem(0, 0, 0)),
+                  "Trying to save empty interval to .");
+}
+
+// The goal of this test is to show that an iterator to an empty container
+// returns |DataEnd|.
+TEST_F(QuicIntervalDequeTest, IteratorEmpty) {
+  QID qid;
+  auto it = qid.DataAt(0);
+  EXPECT_EQ(it, qid.DataEnd());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_interval_set.h b/quiche/quic/core/quic_interval_set.h
new file mode 100644
index 0000000..e97efed
--- /dev/null
+++ b/quiche/quic/core/quic_interval_set.h
@@ -0,0 +1,896 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
+#define QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
+
+// QuicIntervalSet<T> is a data structure used to represent a sorted set of
+// non-empty, non-adjacent, and mutually disjoint intervals. Mutations to an
+// interval set preserve these properties, altering the set as needed. For
+// example, adding [2, 3) to a set containing only [1, 2) would result in the
+// set containing the single interval [1, 3).
+//
+// Supported operations include testing whether an Interval is contained in the
+// QuicIntervalSet, comparing two QuicIntervalSets, and performing
+// QuicIntervalSet union, intersection, and difference.
+//
+// QuicIntervalSet maintains the minimum number of entries needed to represent
+// the set of underlying intervals. When the QuicIntervalSet is modified (e.g.
+// due to an Add operation), other interval entries may be coalesced, removed,
+// or otherwise modified in order to maintain this invariant. The intervals are
+// maintained in sorted order, by ascending min() value.
+//
+// The reader is cautioned to beware of the terminology used here: this library
+// uses the terms "min" and "max" rather than "begin" and "end" as is
+// conventional for the STL. The terminology [min, max) refers to the half-open
+// interval which (if the interval is not empty) contains min but does not
+// contain max. An interval is considered empty if min >= max.
+//
+// T is required to be default- and copy-constructible, to have an assignment
+// operator, a difference operator (operator-()), and the full complement of
+// comparison operators (<, <=, ==, !=, >=, >). These requirements are inherited
+// from value_type.
+//
+// QuicIntervalSet has constant-time move operations.
+//
+//
+// Examples:
+//   QuicIntervalSet<int> intervals;
+//   intervals.Add(Interval<int>(10, 20));
+//   intervals.Add(Interval<int>(30, 40));
+//   // intervals contains [10,20) and [30,40).
+//   intervals.Add(Interval<int>(15, 35));
+//   // intervals has been coalesced. It now contains the single range [10,40).
+//   EXPECT_EQ(1, intervals.Size());
+//   EXPECT_TRUE(intervals.Contains(Interval<int>(10, 40)));
+//
+//   intervals.Difference(Interval<int>(10, 20));
+//   // intervals should now contain the single range [20, 40).
+//   EXPECT_EQ(1, intervals.Size());
+//   EXPECT_TRUE(intervals.Contains(Interval<int>(20, 40)));
+
+#include <stddef.h>
+#include <algorithm>
+#include <initializer_list>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include <string>
+
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+template <typename T>
+class QUIC_NO_EXPORT QuicIntervalSet {
+ public:
+  using value_type = QuicInterval<T>;
+
+ private:
+  struct QUIC_NO_EXPORT IntervalLess {
+    using is_transparent = void;
+    bool operator()(const value_type& a, const value_type& b) const;
+    // These transparent overloads are used when we do all of our searches (via
+    // Set::lower_bound() and Set::upper_bound()), which avoids the need to
+    // construct an interval when we are looking for a point and also avoids
+    // needing to worry about comparing overlapping intervals in the overload
+    // that takes two value_types (the one just above this comment).
+    bool operator()(const value_type& a, const T& point) const;
+    bool operator()(const value_type& a, T&& point) const;
+    bool operator()(const T& point, const value_type& a) const;
+    bool operator()(T&& point, const value_type& a) const;
+  };
+
+  using Set = QuicSmallOrderedSet<value_type, IntervalLess>;
+
+ public:
+  using const_iterator = typename Set::const_iterator;
+  using const_reverse_iterator = typename Set::const_reverse_iterator;
+
+  // Instantiates an empty QuicIntervalSet.
+  QuicIntervalSet() = default;
+
+  // Instantiates a QuicIntervalSet containing exactly one initial half-open
+  // interval [min, max), unless the given interval is empty, in which case the
+  // QuicIntervalSet will be empty.
+  explicit QuicIntervalSet(const value_type& interval) { Add(interval); }
+
+  // Instantiates a QuicIntervalSet containing the half-open interval [min,
+  // max).
+  QuicIntervalSet(const T& min, const T& max) { Add(min, max); }
+
+  QuicIntervalSet(std::initializer_list<value_type> il) { assign(il); }
+
+  // Clears this QuicIntervalSet.
+  void Clear() { intervals_.clear(); }
+
+  // Returns the number of disjoint intervals contained in this QuicIntervalSet.
+  size_t Size() const { return intervals_.size(); }
+
+  // Returns the smallest interval that contains all intervals in this
+  // QuicIntervalSet, or the empty interval if the set is empty.
+  value_type SpanningInterval() const;
+
+  // Adds "interval" to this QuicIntervalSet. Adding the empty interval has no
+  // effect.
+  void Add(const value_type& interval);
+
+  // Adds the interval [min, max) to this QuicIntervalSet. Adding the empty
+  // interval has no effect.
+  void Add(const T& min, const T& max) { Add(value_type(min, max)); }
+
+  // Same semantics as Add(const value_type&), but optimized for the case where
+  // rbegin()->min() <= |interval|.min() <= rbegin()->max().
+  void AddOptimizedForAppend(const value_type& interval) {
+    if (Empty()) {
+      Add(interval);
+      return;
+    }
+
+    const_reverse_iterator last_interval = intervals_.rbegin();
+
+    // If interval.min() is outside of [last_interval->min, last_interval->max],
+    // we can not simply extend last_interval->max.
+    if (interval.min() < last_interval->min() ||
+        interval.min() > last_interval->max()) {
+      Add(interval);
+      return;
+    }
+
+    if (interval.max() <= last_interval->max()) {
+      // interval is fully contained by last_interval.
+      return;
+    }
+
+    // Extend last_interval.max to interval.max, in place.
+    //
+    // Set does not allow in-place updates due to the potential of violating its
+    // ordering requirements. But we know setting the max of the last interval
+    // is safe w.r.t set ordering and other invariants of QuicIntervalSet, so we
+    // force an in-place update for performance.
+    const_cast<value_type*>(&(*last_interval))->SetMax(interval.max());
+  }
+
+  // Same semantics as Add(const T&, const T&), but optimized for the case where
+  // rbegin()->max() == |min|.
+  void AddOptimizedForAppend(const T& min, const T& max) {
+    AddOptimizedForAppend(value_type(min, max));
+  }
+
+  // TODO(wub): Similar to AddOptimizedForAppend, we can also have a
+  // AddOptimizedForPrepend if there is a use case.
+
+  // Remove the first interval.
+  // REQUIRES: !Empty()
+  void PopFront() {
+    QUICHE_DCHECK(!Empty());
+    intervals_.erase(intervals_.begin());
+  }
+
+  // Trim all values that are smaller than |value|. Which means
+  // a) If all values in an interval is smaller than |value|, the entire
+  //    interval is removed.
+  // b) If some but not all values in an interval is smaller than |value|, the
+  //    min of that interval is raised to |value|.
+  // Returns true if some intervals are trimmed.
+  bool TrimLessThan(const T& value) {
+    // Number of intervals that are fully or partially trimmed.
+    size_t num_intervals_trimmed = 0;
+
+    while (!intervals_.empty()) {
+      const_iterator first_interval = intervals_.begin();
+      if (first_interval->min() >= value) {
+        break;
+      }
+
+      ++num_intervals_trimmed;
+
+      if (first_interval->max() <= value) {
+        // a) Trim the entire interval.
+        intervals_.erase(first_interval);
+        continue;
+      }
+
+      // b) Trim a prefix of the interval.
+      //
+      // Set does not allow in-place updates due to the potential of violating
+      // its ordering requirements. But increasing the min of the first interval
+      // will not break the ordering, hence the const_cast.
+      const_cast<value_type*>(&(*first_interval))->SetMin(value);
+      break;
+    }
+
+    return num_intervals_trimmed != 0;
+  }
+
+  // Returns true if this QuicIntervalSet is empty.
+  bool Empty() const { return intervals_.empty(); }
+
+  // Returns true if any interval in this QuicIntervalSet contains the indicated
+  // value.
+  bool Contains(const T& value) const;
+
+  // Returns true if there is some interval in this QuicIntervalSet that wholly
+  // contains the given interval. An interval O "wholly contains" a non-empty
+  // interval I if O.Contains(p) is true for every p in I. This is the same
+  // definition used by value_type::Contains(). This method returns false on
+  // the empty interval, due to a (perhaps unintuitive) convention inherited
+  // from value_type.
+  // Example:
+  //   Assume an QuicIntervalSet containing the entries { [10,20), [30,40) }.
+  //   Contains(Interval(15, 16)) returns true, because [10,20) contains
+  //   [15,16). However, Contains(Interval(15, 35)) returns false.
+  bool Contains(const value_type& interval) const;
+
+  // Returns true if for each interval in "other", there is some (possibly
+  // different) interval in this QuicIntervalSet which wholly contains it. See
+  // Contains(const value_type& interval) for the meaning of "wholly contains".
+  // Perhaps unintuitively, this method returns false if "other" is the empty
+  // set. The algorithmic complexity of this method is O(other.Size() *
+  // log(this->Size())). The method could be rewritten to run in O(other.Size()
+  // + this->Size()), and this alternative could be implemented as a free
+  // function using the public API.
+  bool Contains(const QuicIntervalSet<T>& other) const;
+
+  // Returns true if there is some interval in this QuicIntervalSet that wholly
+  // contains the interval [min, max). See Contains(const value_type&).
+  bool Contains(const T& min, const T& max) const {
+    return Contains(value_type(min, max));
+  }
+
+  // Returns true if for some interval in "other", there is some interval in
+  // this QuicIntervalSet that intersects with it. See value_type::Intersects()
+  // for the definition of interval intersection.  Runs in time O(n+m) where n
+  // is the number of intervals in this and m is the number of intervals in
+  // other.
+  bool Intersects(const QuicIntervalSet& other) const;
+
+  // Returns an iterator to the value_type in the QuicIntervalSet that contains
+  // the given value. In other words, returns an iterator to the unique interval
+  // [min, max) in the QuicIntervalSet that has the property min <= value < max.
+  // If there is no such interval, this method returns end().
+  const_iterator Find(const T& value) const;
+
+  // Returns an iterator to the value_type in the QuicIntervalSet that wholly
+  // contains the given interval. In other words, returns an iterator to the
+  // unique interval outer in the QuicIntervalSet that has the property that
+  // outer.Contains(interval). If there is no such interval, or if interval is
+  // empty, returns end().
+  const_iterator Find(const value_type& interval) const;
+
+  // Returns an iterator to the value_type in the QuicIntervalSet that wholly
+  // contains [min, max). In other words, returns an iterator to the unique
+  // interval outer in the QuicIntervalSet that has the property that
+  // outer.Contains(Interval<T>(min, max)). If there is no such interval, or if
+  // interval is empty, returns end().
+  const_iterator Find(const T& min, const T& max) const {
+    return Find(value_type(min, max));
+  }
+
+  // Returns an iterator pointing to the first value_type which contains or
+  // goes after the given value.
+  //
+  // Example:
+  //   [10, 20)  [30, 40)
+  //   ^                    LowerBound(10)
+  //   ^                    LowerBound(15)
+  //             ^          LowerBound(20)
+  //             ^          LowerBound(25)
+  const_iterator LowerBound(const T& value) const;
+
+  // Returns an iterator pointing to the first value_type which goes after
+  // the given value.
+  //
+  // Example:
+  //   [10, 20)  [30, 40)
+  //             ^          UpperBound(10)
+  //             ^          UpperBound(15)
+  //             ^          UpperBound(20)
+  //             ^          UpperBound(25)
+  const_iterator UpperBound(const T& value) const;
+
+  // Returns true if every value within the passed interval is not Contained
+  // within the QuicIntervalSet.
+  // Note that empty intervals are always considered disjoint from the
+  // QuicIntervalSet (even though the QuicIntervalSet doesn't `Contain` them).
+  bool IsDisjoint(const value_type& interval) const;
+
+  // Merges all the values contained in "other" into this QuicIntervalSet.
+  //
+  // Performance: Let n == Size() and m = other.Size().  Union() runs in O(m)
+  // Set operations, so that if Set is a tree, it runs in time O(m log(n+m)) and
+  // if Set is a flat_set it runs in time O(m(n+m)).  In principle, for the
+  // flat_set, we should be able to make this run in time O(n+m).
+  //
+  // TODO(bradleybear): Make Union() run in time O(n+m) for flat_set.  This may
+  // require an additional template parameter to indicate that the Set is a
+  // linear-time data structure instead of a log-time data structure.
+  void Union(const QuicIntervalSet& other);
+
+  // Modifies this QuicIntervalSet so that it contains only those values that
+  // are currently present both in *this and in the QuicIntervalSet "other".
+  void Intersection(const QuicIntervalSet& other);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // currently in *this but not in "interval".
+  void Difference(const value_type& interval);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // currently in *this but not in the interval [min, max).
+  void Difference(const T& min, const T& max);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // currently in *this but not in the QuicIntervalSet "other".  Runs in time
+  // O(n+m) where n is this->Size(), m is other.Size(), regardless of whether
+  // the Set is a flat_set or a std::set.
+  void Difference(const QuicIntervalSet& other);
+
+  // Mutates this QuicIntervalSet so that it contains only those values that are
+  // in [min, max) but not currently in *this.
+  void Complement(const T& min, const T& max);
+
+  // QuicIntervalSet's begin() iterator. The invariants of QuicIntervalSet
+  // guarantee that for each entry e in the set, e.min() < e.max() (because the
+  // entries are non-empty) and for each entry f that appears later in the set,
+  // e.max() < f.min() (because the entries are ordered, pairwise-disjoint, and
+  // non-adjacent). Modifications to this QuicIntervalSet invalidate these
+  // iterators.
+  const_iterator begin() const { return intervals_.begin(); }
+
+  // QuicIntervalSet's end() iterator.
+  const_iterator end() const { return intervals_.end(); }
+
+  // QuicIntervalSet's rbegin() and rend() iterators. Iterator invalidation
+  // semantics are the same as those for begin() / end().
+  const_reverse_iterator rbegin() const { return intervals_.rbegin(); }
+
+  const_reverse_iterator rend() const { return intervals_.rend(); }
+
+  template <typename Iter>
+  void assign(Iter first, Iter last) {
+    Clear();
+    for (; first != last; ++first)
+      Add(*first);
+  }
+
+  void assign(std::initializer_list<value_type> il) {
+    assign(il.begin(), il.end());
+  }
+
+  // Returns a human-readable representation of this set. This will typically be
+  // (though is not guaranteed to be) of the form
+  //   "[a1, b1) [a2, b2) ... [an, bn)"
+  // where the intervals are in the same order as given by traversal from
+  // begin() to end(). This representation is intended for human consumption;
+  // computer programs should not rely on the output being in exactly this form.
+  std::string ToString() const;
+
+  QuicIntervalSet& operator=(std::initializer_list<value_type> il) {
+    assign(il.begin(), il.end());
+    return *this;
+  }
+
+  friend bool operator==(const QuicIntervalSet& a, const QuicIntervalSet& b) {
+    return a.Size() == b.Size() &&
+           std::equal(a.begin(), a.end(), b.begin(), NonemptyIntervalEq());
+  }
+
+  friend bool operator!=(const QuicIntervalSet& a, const QuicIntervalSet& b) {
+    return !(a == b);
+  }
+
+ private:
+  // Simple member-wise equality, since all intervals are non-empty.
+  struct QUIC_NO_EXPORT NonemptyIntervalEq {
+    bool operator()(const value_type& a, const value_type& b) const {
+      return a.min() == b.min() && a.max() == b.max();
+    }
+  };
+
+  // Returns true if this set is valid (i.e. all intervals in it are non-empty,
+  // non-adjacent, and mutually disjoint). Currently this is used as an
+  // integrity check by the Intersection() and Difference() methods, but is only
+  // invoked for debug builds (via QUICHE_DCHECK).
+  bool Valid() const;
+
+  // Finds the first interval that potentially intersects 'other'.
+  const_iterator FindIntersectionCandidate(const QuicIntervalSet& other) const;
+
+  // Finds the first interval that potentially intersects 'interval'.  More
+  // precisely, return an interator it pointing at the last interval J such that
+  // interval <= J.  If all the intervals are > J then return begin().
+  const_iterator FindIntersectionCandidate(const value_type& interval) const;
+
+  // Helper for Intersection() and Difference(): Finds the next pair of
+  // intervals from 'x' and 'y' that intersect. 'mine' is an iterator
+  // over x->intervals_. 'theirs' is an iterator over y.intervals_. 'mine'
+  // and 'theirs' are advanced until an intersecting pair is found.
+  // Non-intersecting intervals (aka "holes") from x->intervals_ can be
+  // optionally erased by "on_hole". "on_hole" must return an iterator to the
+  // first element in 'x' after the hole, or x->intervals_.end() if no elements
+  // exist after the hole.
+  template <typename X, typename Func>
+  static bool FindNextIntersectingPairImpl(X* x,
+                                           const QuicIntervalSet& y,
+                                           const_iterator* mine,
+                                           const_iterator* theirs,
+                                           Func on_hole);
+
+  // The variant of the above method that doesn't mutate this QuicIntervalSet.
+  bool FindNextIntersectingPair(const QuicIntervalSet& other,
+                                const_iterator* mine,
+                                const_iterator* theirs) const {
+    return FindNextIntersectingPairImpl(
+        this, other, mine, theirs,
+        [](const QuicIntervalSet*, const_iterator, const_iterator end) {
+          return end;
+        });
+  }
+
+  // The variant of the above method that mutates this QuicIntervalSet by
+  // erasing holes.
+  bool FindNextIntersectingPairAndEraseHoles(const QuicIntervalSet& other,
+                                             const_iterator* mine,
+                                             const_iterator* theirs) {
+    return FindNextIntersectingPairImpl(
+        this, other, mine, theirs,
+        [](QuicIntervalSet* x, const_iterator from, const_iterator to) {
+          return x->intervals_.erase(from, to);
+        });
+  }
+
+  // The representation for the intervals. The intervals in this set are
+  // non-empty, pairwise-disjoint, non-adjacent and ordered in ascending order
+  // by min().
+  Set intervals_;
+};
+
+template <typename T>
+auto operator<<(std::ostream& out, const QuicIntervalSet<T>& seq)
+    -> decltype(out << *seq.begin()) {
+  out << "{";
+  for (const auto& interval : seq) {
+    out << " " << interval;
+  }
+  out << " }";
+
+  return out;
+}
+
+//==============================================================================
+// Implementation details: Clients can stop reading here.
+
+template <typename T>
+typename QuicIntervalSet<T>::value_type QuicIntervalSet<T>::SpanningInterval()
+    const {
+  value_type result;
+  if (!intervals_.empty()) {
+    result.SetMin(intervals_.begin()->min());
+    result.SetMax(intervals_.rbegin()->max());
+  }
+  return result;
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Add(const value_type& interval) {
+  if (interval.Empty())
+    return;
+  const_iterator it = intervals_.lower_bound(interval.min());
+  value_type the_union = interval;
+  if (it != intervals_.begin()) {
+    --it;
+    if (it->Separated(the_union)) {
+      ++it;
+    }
+  }
+  // Don't erase the elements one at a time, since that will produce quadratic
+  // work on a flat_set, and apparently an extra log-factor of work for a
+  // tree-based set.  Instead identify the first and last intervals that need to
+  // be erased, and call erase only once.
+  const_iterator start = it;
+  while (it != intervals_.end() && !it->Separated(the_union)) {
+    the_union.SpanningUnion(*it);
+    ++it;
+  }
+  intervals_.erase(start, it);
+  intervals_.insert(the_union);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Contains(const T& value) const {
+  // Find the first interval with min() > value, then move back one step
+  const_iterator it = intervals_.upper_bound(value);
+  if (it == intervals_.begin())
+    return false;
+  --it;
+  return it->Contains(value);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Contains(const value_type& interval) const {
+  // Find the first interval with min() > value, then move back one step.
+  const_iterator it = intervals_.upper_bound(interval.min());
+  if (it == intervals_.begin())
+    return false;
+  --it;
+  return it->Contains(interval);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Contains(const QuicIntervalSet<T>& other) const {
+  if (!SpanningInterval().Contains(other.SpanningInterval())) {
+    return false;
+  }
+
+  for (const_iterator i = other.begin(); i != other.end(); ++i) {
+    // If we don't contain the interval, can return false now.
+    if (!Contains(*i)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// This method finds the interval that Contains() "value", if such an interval
+// exists in the QuicIntervalSet. The way this is done is to locate the
+// "candidate interval", the only interval that could *possibly* contain value,
+// and test it using Contains(). The candidate interval is the interval with the
+// largest min() having min() <= value.
+//
+// Another detail involves the choice of which Set method to use to try to find
+// the candidate interval. The most appropriate entry point is
+// Set::upper_bound(), which finds the least interval with a min > the
+// value. The semantics of upper_bound() are slightly different from what we
+// want (namely, to find the greatest interval which is <= the probe interval)
+// but they are close enough; the interval found by upper_bound() will always be
+// one step past the interval we are looking for (if it exists) or at begin()
+// (if it does not). Getting to the proper interval is a simple matter of
+// decrementing the iterator.
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
+    const T& value) const {
+  const_iterator it = intervals_.upper_bound(value);
+  if (it == intervals_.begin())
+    return intervals_.end();
+  --it;
+  if (it->Contains(value))
+    return it;
+  else
+    return intervals_.end();
+}
+
+// This method finds the interval that Contains() the interval "probe", if such
+// an interval exists in the QuicIntervalSet. The way this is done is to locate
+// the "candidate interval", the only interval that could *possibly* contain
+// "probe", and test it using Contains().  We use the same algorithm as for
+// Find(value), except that instead of checking that the value is contained, we
+// check that the probe is contained.
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::Find(
+    const value_type& probe) const {
+  const_iterator it = intervals_.upper_bound(probe.min());
+  if (it == intervals_.begin())
+    return intervals_.end();
+  --it;
+  if (it->Contains(probe))
+    return it;
+  else
+    return intervals_.end();
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::LowerBound(
+    const T& value) const {
+  const_iterator it = intervals_.lower_bound(value);
+  if (it == intervals_.begin()) {
+    return it;
+  }
+
+  // The previous intervals_.lower_bound() checking is essentially based on
+  // interval.min(), so we need to check whether the `value` is contained in
+  // the previous interval.
+  --it;
+  if (it->Contains(value)) {
+    return it;
+  } else {
+    return ++it;
+  }
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator QuicIntervalSet<T>::UpperBound(
+    const T& value) const {
+  return intervals_.upper_bound(value);
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::IsDisjoint(const value_type& interval) const {
+  if (interval.Empty())
+    return true;
+  // Find the first interval with min() > interval.min()
+  const_iterator it = intervals_.upper_bound(interval.min());
+  if (it != intervals_.end() && interval.max() > it->min())
+    return false;
+  if (it == intervals_.begin())
+    return true;
+  --it;
+  return it->max() <= interval.min();
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Union(const QuicIntervalSet& other) {
+  for (const value_type& interval : other.intervals_) {
+    Add(interval);
+  }
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator
+QuicIntervalSet<T>::FindIntersectionCandidate(
+    const QuicIntervalSet& other) const {
+  return FindIntersectionCandidate(*other.intervals_.begin());
+}
+
+template <typename T>
+typename QuicIntervalSet<T>::const_iterator
+QuicIntervalSet<T>::FindIntersectionCandidate(
+    const value_type& interval) const {
+  // Use upper_bound to efficiently find the first interval in intervals_
+  // where min() is greater than interval.min().  If the result
+  // isn't the beginning of intervals_ then move backwards one interval since
+  // the interval before it is the first candidate where max() may be
+  // greater than interval.min().
+  // In other words, no interval before that can possibly intersect with any
+  // of other.intervals_.
+  const_iterator mine = intervals_.upper_bound(interval.min());
+  if (mine != intervals_.begin()) {
+    --mine;
+  }
+  return mine;
+}
+
+template <typename T>
+template <typename X, typename Func>
+bool QuicIntervalSet<T>::FindNextIntersectingPairImpl(X* x,
+                                                      const QuicIntervalSet& y,
+                                                      const_iterator* mine,
+                                                      const_iterator* theirs,
+                                                      Func on_hole) {
+  QUICHE_CHECK(x != nullptr);
+  if ((*mine == x->intervals_.end()) || (*theirs == y.intervals_.end())) {
+    return false;
+  }
+  while (!(**mine).Intersects(**theirs)) {
+    const_iterator erase_first = *mine;
+    // Skip over intervals in 'mine' that don't reach 'theirs'.
+    while (*mine != x->intervals_.end() && (**mine).max() <= (**theirs).min()) {
+      ++(*mine);
+    }
+    *mine = on_hole(x, erase_first, *mine);
+    // We're done if the end of intervals_ is reached.
+    if (*mine == x->intervals_.end()) {
+      return false;
+    }
+    // Skip over intervals 'theirs' that don't reach 'mine'.
+    while (*theirs != y.intervals_.end() &&
+           (**theirs).max() <= (**mine).min()) {
+      ++(*theirs);
+    }
+    // If the end of other.intervals_ is reached, we're done.
+    if (*theirs == y.intervals_.end()) {
+      on_hole(x, *mine, x->intervals_.end());
+      return false;
+    }
+  }
+  return true;
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Intersection(const QuicIntervalSet& other) {
+  if (!SpanningInterval().Intersects(other.SpanningInterval())) {
+    intervals_.clear();
+    return;
+  }
+
+  const_iterator mine = FindIntersectionCandidate(other);
+  // Remove any intervals that cannot possibly intersect with other.intervals_.
+  mine = intervals_.erase(intervals_.begin(), mine);
+  const_iterator theirs = other.FindIntersectionCandidate(*this);
+
+  while (FindNextIntersectingPairAndEraseHoles(other, &mine, &theirs)) {
+    // OK, *mine and *theirs intersect.  Now, we find the largest
+    // span of intervals in other (starting at theirs) - say [a..b]
+    // - that intersect *mine, and we replace *mine with (*mine
+    // intersect x) for all x in [a..b] Note that subsequent
+    // intervals in this can't intersect any intervals in [a..b) --
+    // they may only intersect b or subsequent intervals in other.
+    value_type i(*mine);
+    intervals_.erase(mine);
+    mine = intervals_.end();
+    value_type intersection;
+    while (theirs != other.intervals_.end() &&
+           i.Intersects(*theirs, &intersection)) {
+      std::pair<const_iterator, bool> ins = intervals_.insert(intersection);
+      QUICHE_DCHECK(ins.second);
+      mine = ins.first;
+      ++theirs;
+    }
+    QUICHE_DCHECK(mine != intervals_.end());
+    --theirs;
+    ++mine;
+  }
+  QUICHE_DCHECK(Valid());
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Intersects(const QuicIntervalSet& other) const {
+  // Don't bother to handle nonoverlapping spanning intervals as a special case.
+  // This code runs in time O(n+m), as guaranteed, even for that case .
+  // Handling the nonoverlapping spanning intervals as a special case doesn't
+  // improve the asymptotics but does make the code more complex.
+  auto mine = intervals_.begin();
+  auto theirs = other.intervals_.begin();
+  while (mine != intervals_.end() && theirs != other.intervals_.end()) {
+    if (mine->Intersects(*theirs))
+      return true;
+    else if (*mine < *theirs)
+      ++mine;
+    else
+      ++theirs;
+  }
+  return false;
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Difference(const value_type& interval) {
+  if (!SpanningInterval().Intersects(interval)) {
+    return;
+  }
+  Difference(QuicIntervalSet<T>(interval));
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Difference(const T& min, const T& max) {
+  Difference(value_type(min, max));
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Difference(const QuicIntervalSet& other) {
+  // In order to avoid quadratic-time when using a flat set, we don't try to
+  // update intervals_ in place.  Instead we build up a new result_, always
+  // inserting at the end which is O(1) time per insertion.  Since the number of
+  // elements in the result is O(Size() + other.Size()), the cost for all the
+  // insertions is also O(Size() + other.Size()).
+  //
+  // We look at all the elements of intervals_, so that's O(Size()).
+  //
+  // We also look at all the elements of other.intervals_, for O(other.Size()).
+  if (Empty())
+    return;
+  Set result;
+  const_iterator mine = intervals_.begin();
+  value_type myinterval = *mine;
+  const_iterator theirs = other.intervals_.begin();
+  while (mine != intervals_.end()) {
+    // Loop invariants:
+    //   myinterval is nonempty.
+    //   mine points at a range that is a suffix of myinterval.
+    QUICHE_DCHECK(!myinterval.Empty());
+    QUICHE_DCHECK(myinterval.max() == mine->max());
+
+    // There are 3 cases.
+    //  myinterval is completely before theirs (treat theirs==end() as if it is
+    //  infinity).
+    //    --> consume myinterval into result.
+    //  myinterval is completely after theirs
+    //    --> theirs can no longer affect us, so ++theirs.
+    //  myinterval touches theirs with a prefix of myinterval not touching
+    //  *theirs.
+    //    --> consume the prefix of myinterval into the result.
+    //  myinterval touches theirs, with the first element of myinterval in
+    //  *theirs.
+    //    -> reduce myinterval
+    if (theirs == other.intervals_.end() || myinterval.max() <= theirs->min()) {
+      // Keep all of my_interval.
+      result.insert(result.end(), myinterval);
+      myinterval.Clear();
+    } else if (theirs->max() <= myinterval.min()) {
+      ++theirs;
+    } else if (myinterval.min() < theirs->min()) {
+      // Keep a nonempty prefix of my interval.
+      result.insert(result.end(), value_type(myinterval.min(), theirs->min()));
+      myinterval.SetMin(theirs->max());
+    } else {
+      // myinterval starts at or after *theirs, chop down myinterval.
+      myinterval.SetMin(theirs->max());
+    }
+    // if myinterval became empty, find the next interval
+    if (myinterval.Empty()) {
+      ++mine;
+      if (mine != intervals_.end()) {
+        myinterval = *mine;
+      }
+    }
+  }
+  std::swap(result, intervals_);
+  QUICHE_DCHECK(Valid());
+}
+
+template <typename T>
+void QuicIntervalSet<T>::Complement(const T& min, const T& max) {
+  QuicIntervalSet<T> span(min, max);
+  span.Difference(*this);
+  intervals_.swap(span.intervals_);
+}
+
+template <typename T>
+std::string QuicIntervalSet<T>::ToString() const {
+  std::ostringstream os;
+  os << *this;
+  return os.str();
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::Valid() const {
+  const_iterator prev = end();
+  for (const_iterator it = begin(); it != end(); ++it) {
+    // invalid or empty interval.
+    if (it->min() >= it->max())
+      return false;
+    // Not sorted, not disjoint, or adjacent.
+    if (prev != end() && prev->max() >= it->min())
+      return false;
+    prev = it;
+  }
+  return true;
+}
+
+// This comparator orders intervals first by ascending min().  The Set never
+// contains overlapping intervals, so that suffices.
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
+                                                  const value_type& b) const {
+  // This overload is probably used only by Set::insert().
+  return a.min() < b.min();
+}
+
+// It appears that the Set::lower_bound(T) method uses only two overloads of the
+// comparison operator that take a T as the second argument..  In contrast
+// Set::upper_bound(T) uses the two overloads that take T as the first argument.
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
+                                                  const T& point) const {
+  // Compare an interval to a point.
+  return a.min() < point;
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const value_type& a,
+                                                  T&& point) const {
+  // Compare an interval to a point
+  return a.min() < point;
+}
+
+// It appears that the Set::upper_bound(T) method uses only the next two
+// overloads of the comparison operator.
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(const T& point,
+                                                  const value_type& a) const {
+  // Compare an interval to a point.
+  return point < a.min();
+}
+
+template <typename T>
+bool QuicIntervalSet<T>::IntervalLess::operator()(T&& point,
+                                                  const value_type& a) const {
+  // Compare an interval to a point.
+  return point < a.min();
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_INTERVAL_SET_H_
diff --git a/quiche/quic/core/quic_interval_set_test.cc b/quiche/quic/core/quic_interval_set_test.cc
new file mode 100644
index 0000000..fca037d
--- /dev/null
+++ b/quiche/quic/core/quic_interval_set_test.cc
@@ -0,0 +1,1071 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_interval_set.h"
+
+#include <stdarg.h>
+
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAreArray;
+
+class QuicIntervalSetTest : public QuicTest {
+ protected:
+  virtual void SetUp() {
+    // Initialize two QuicIntervalSets for union, intersection, and difference
+    // tests
+    is.Add(100, 200);
+    is.Add(300, 400);
+    is.Add(500, 600);
+    is.Add(700, 800);
+    is.Add(900, 1000);
+    is.Add(1100, 1200);
+    is.Add(1300, 1400);
+    is.Add(1500, 1600);
+    is.Add(1700, 1800);
+    is.Add(1900, 2000);
+    is.Add(2100, 2200);
+
+    // Lots of different cases:
+    other.Add(50, 70);      // disjoint, at the beginning
+    other.Add(2250, 2270);  // disjoint, at the end
+    other.Add(650, 670);    // disjoint, in the middle
+    other.Add(350, 360);    // included
+    other.Add(370, 380);    // also included (two at once)
+    other.Add(470, 530);    // overlaps low end
+    other.Add(770, 830);    // overlaps high end
+    other.Add(870, 900);    // meets at low end
+    other.Add(1200, 1230);  // meets at high end
+    other.Add(1270, 1830);  // overlaps multiple ranges
+  }
+
+  virtual void TearDown() {
+    is.Clear();
+    EXPECT_TRUE(is.Empty());
+    other.Clear();
+    EXPECT_TRUE(other.Empty());
+  }
+  QuicIntervalSet<int> is;
+  QuicIntervalSet<int> other;
+};
+
+TEST_F(QuicIntervalSetTest, IsDisjoint) {
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 99)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(0, 100)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 299)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 407)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(405, 499)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(2300, 2300)));
+  EXPECT_TRUE(
+      is.IsDisjoint(QuicInterval<int>(2300, std::numeric_limits<int>::max())));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(100, 105)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(199, 300)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 450)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(299, 400)));
+  EXPECT_FALSE(is.IsDisjoint(QuicInterval<int>(250, 2000)));
+  EXPECT_FALSE(
+      is.IsDisjoint(QuicInterval<int>(2199, std::numeric_limits<int>::max())));
+  // Empty intervals.
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(90, 90)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 100)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(100, 90)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(150, 150)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(200, 200)));
+  EXPECT_TRUE(is.IsDisjoint(QuicInterval<int>(400, 300)));
+}
+
+// Base helper method for verifying the contents of an interval set.
+// Returns true iff <is> contains <count> intervals whose successive
+// endpoints match the sequence of args in <ap>:
+static bool VA_Check(const QuicIntervalSet<int>& is, int count, va_list ap) {
+  std::vector<QuicInterval<int>> intervals(is.begin(), is.end());
+  if (count != static_cast<int>(intervals.size())) {
+    QUIC_LOG(ERROR) << "Expected " << count << " intervals, got "
+                    << intervals.size() << ": " << is;
+    return false;
+  }
+  if (count != static_cast<int>(is.Size())) {
+    QUIC_LOG(ERROR) << "Expected " << count << " intervals, got Size "
+                    << is.Size() << ": " << is;
+    return false;
+  }
+  bool result = true;
+  for (int i = 0; i < count; i++) {
+    int min = va_arg(ap, int);
+    int max = va_arg(ap, int);
+    if (min != intervals[i].min() || max != intervals[i].max()) {
+      QUIC_LOG(ERROR) << "Expected: [" << min << ", " << max << ") got "
+                      << intervals[i] << " in " << is;
+      result = false;
+    }
+  }
+  return result;
+}
+
+static bool Check(const QuicIntervalSet<int>& is, int count, ...) {
+  va_list ap;
+  va_start(ap, count);
+  const bool result = VA_Check(is, count, ap);
+  va_end(ap);
+  return result;
+}
+
+// Some helper functions for testing Contains and Find, which are logically the
+// same.
+static void TestContainsAndFind(const QuicIntervalSet<int>& is, int value) {
+  EXPECT_TRUE(is.Contains(value)) << "Set does not contain " << value;
+  auto it = is.Find(value);
+  EXPECT_NE(it, is.end()) << "No iterator to interval containing " << value;
+  EXPECT_TRUE(it->Contains(value)) << "Iterator does not contain " << value;
+}
+
+static void TestContainsAndFind(const QuicIntervalSet<int>& is,
+                                int min,
+                                int max) {
+  EXPECT_TRUE(is.Contains(min, max))
+      << "Set does not contain interval with min " << min << "and max " << max;
+  auto it = is.Find(min, max);
+  EXPECT_NE(it, is.end()) << "No iterator to interval with min " << min
+                          << "and max " << max;
+  EXPECT_TRUE(it->Contains(QuicInterval<int>(min, max)))
+      << "Iterator does not contain interval with min " << min << "and max "
+      << max;
+}
+
+static void TestNotContainsAndFind(const QuicIntervalSet<int>& is, int value) {
+  EXPECT_FALSE(is.Contains(value)) << "Set contains " << value;
+  auto it = is.Find(value);
+  EXPECT_EQ(it, is.end()) << "There is iterator to interval containing "
+                          << value;
+}
+
+static void TestNotContainsAndFind(const QuicIntervalSet<int>& is,
+                                   int min,
+                                   int max) {
+  EXPECT_FALSE(is.Contains(min, max))
+      << "Set contains interval with min " << min << "and max " << max;
+  auto it = is.Find(min, max);
+  EXPECT_EQ(it, is.end()) << "There is iterator to interval with min " << min
+                          << "and max " << max;
+}
+
+TEST_F(QuicIntervalSetTest, AddInterval) {
+  QuicIntervalSet<int> s;
+  s.Add(QuicInterval<int>(0, 10));
+  EXPECT_TRUE(Check(s, 1, 0, 10));
+}
+
+TEST_F(QuicIntervalSetTest, DecrementIterator) {
+  auto it = is.end();
+  EXPECT_NE(it, is.begin());
+  --it;
+  EXPECT_EQ(*it, QuicInterval<int>(2100, 2200));
+  ++it;
+  EXPECT_EQ(it, is.end());
+}
+
+TEST_F(QuicIntervalSetTest, AddOptimizedForAppend) {
+  QuicIntervalSet<int> empty_one, empty_two;
+  empty_one.AddOptimizedForAppend(QuicInterval<int>(0, 99));
+  EXPECT_TRUE(Check(empty_one, 1, 0, 99));
+
+  empty_two.AddOptimizedForAppend(1, 50);
+  EXPECT_TRUE(Check(empty_two, 1, 1, 50));
+
+  QuicIntervalSet<int> iset;
+  iset.AddOptimizedForAppend(100, 150);
+  iset.AddOptimizedForAppend(200, 250);
+  EXPECT_TRUE(Check(iset, 2, 100, 150, 200, 250));
+
+  iset.AddOptimizedForAppend(199, 200);
+  EXPECT_TRUE(Check(iset, 2, 100, 150, 199, 250));
+
+  iset.AddOptimizedForAppend(251, 260);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
+
+  iset.AddOptimizedForAppend(252, 260);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 260));
+
+  iset.AddOptimizedForAppend(252, 300);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 300));
+
+  iset.AddOptimizedForAppend(300, 350);
+  EXPECT_TRUE(Check(iset, 3, 100, 150, 199, 250, 251, 350));
+}
+
+TEST_F(QuicIntervalSetTest, PopFront) {
+  QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
+  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
+
+  iset.PopFront();
+  EXPECT_TRUE(Check(iset, 2, 400, 500, 700, 800));
+
+  iset.PopFront();
+  EXPECT_TRUE(Check(iset, 1, 700, 800));
+
+  iset.PopFront();
+  EXPECT_TRUE(iset.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, TrimLessThan) {
+  QuicIntervalSet<int> iset{{100, 200}, {400, 500}, {700, 800}};
+  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
+
+  EXPECT_FALSE(iset.TrimLessThan(99));
+  EXPECT_FALSE(iset.TrimLessThan(100));
+  EXPECT_TRUE(Check(iset, 3, 100, 200, 400, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(101));
+  EXPECT_TRUE(Check(iset, 3, 101, 200, 400, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(199));
+  EXPECT_TRUE(Check(iset, 3, 199, 200, 400, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(450));
+  EXPECT_TRUE(Check(iset, 2, 450, 500, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(500));
+  EXPECT_TRUE(Check(iset, 1, 700, 800));
+
+  EXPECT_TRUE(iset.TrimLessThan(801));
+  EXPECT_TRUE(iset.Empty());
+
+  EXPECT_FALSE(iset.TrimLessThan(900));
+  EXPECT_TRUE(iset.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetBasic) {
+  // Test Add, Get, Contains and Find
+  QuicIntervalSet<int> iset;
+  EXPECT_TRUE(iset.Empty());
+  EXPECT_EQ(0u, iset.Size());
+  iset.Add(100, 200);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(1u, iset.Size());
+  iset.Add(100, 150);
+  iset.Add(150, 200);
+  iset.Add(130, 170);
+  iset.Add(90, 150);
+  iset.Add(170, 220);
+  iset.Add(300, 400);
+  iset.Add(250, 450);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(2u, iset.Size());
+  EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
+
+  // Test two intervals with a.max == b.min, that will just join up.
+  iset.Clear();
+  iset.Add(100, 200);
+  iset.Add(200, 300);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(1u, iset.Size());
+  EXPECT_TRUE(Check(iset, 1, 100, 300));
+
+  // Test adding two sets together.
+  iset.Clear();
+  QuicIntervalSet<int> iset_add;
+  iset.Add(100, 200);
+  iset.Add(100, 150);
+  iset.Add(150, 200);
+  iset.Add(130, 170);
+  iset_add.Add(90, 150);
+  iset_add.Add(170, 220);
+  iset_add.Add(300, 400);
+  iset_add.Add(250, 450);
+
+  iset.Union(iset_add);
+  EXPECT_FALSE(iset.Empty());
+  EXPECT_EQ(2u, iset.Size());
+  EXPECT_TRUE(Check(iset, 2, 90, 220, 250, 450));
+
+  // Test begin()/end(), and rbegin()/rend()
+  // to iterate over intervals.
+  {
+    std::vector<QuicInterval<int>> expected(iset.begin(), iset.end());
+
+    std::vector<QuicInterval<int>> actual1;
+    std::copy(iset.begin(), iset.end(), back_inserter(actual1));
+    ASSERT_EQ(expected.size(), actual1.size());
+
+    std::vector<QuicInterval<int>> actual2;
+    std::copy(iset.begin(), iset.end(), back_inserter(actual2));
+    ASSERT_EQ(expected.size(), actual2.size());
+
+    for (size_t i = 0; i < expected.size(); i++) {
+      EXPECT_EQ(expected[i].min(), actual1[i].min());
+      EXPECT_EQ(expected[i].max(), actual1[i].max());
+
+      EXPECT_EQ(expected[i].min(), actual2[i].min());
+      EXPECT_EQ(expected[i].max(), actual2[i].max());
+    }
+
+    // Ensure that the rbegin()/rend() iterators correctly yield the intervals
+    // in reverse order.
+    EXPECT_THAT(std::vector<QuicInterval<int>>(iset.rbegin(), iset.rend()),
+                ElementsAreArray(expected.rbegin(), expected.rend()));
+  }
+
+  TestNotContainsAndFind(iset, 89);
+  TestContainsAndFind(iset, 90);
+  TestContainsAndFind(iset, 120);
+  TestContainsAndFind(iset, 219);
+  TestNotContainsAndFind(iset, 220);
+  TestNotContainsAndFind(iset, 235);
+  TestNotContainsAndFind(iset, 249);
+  TestContainsAndFind(iset, 250);
+  TestContainsAndFind(iset, 300);
+  TestContainsAndFind(iset, 449);
+  TestNotContainsAndFind(iset, 450);
+  TestNotContainsAndFind(iset, 451);
+
+  TestNotContainsAndFind(iset, 50, 60);
+  TestNotContainsAndFind(iset, 50, 90);
+  TestNotContainsAndFind(iset, 50, 200);
+  TestNotContainsAndFind(iset, 90, 90);
+  TestContainsAndFind(iset, 90, 200);
+  TestContainsAndFind(iset, 100, 200);
+  TestContainsAndFind(iset, 100, 220);
+  TestNotContainsAndFind(iset, 100, 221);
+  TestNotContainsAndFind(iset, 220, 220);
+  TestNotContainsAndFind(iset, 240, 300);
+  TestContainsAndFind(iset, 250, 300);
+  TestContainsAndFind(iset, 260, 300);
+  TestContainsAndFind(iset, 300, 450);
+  TestNotContainsAndFind(iset, 300, 451);
+
+  QuicIntervalSet<int> iset_contains;
+  iset_contains.Add(50, 90);
+  EXPECT_FALSE(iset.Contains(iset_contains));
+  iset_contains.Clear();
+
+  iset_contains.Add(90, 200);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(100, 200);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(100, 220);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(250, 300);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(300, 450);
+  EXPECT_TRUE(iset.Contains(iset_contains));
+  iset_contains.Add(300, 451);
+  EXPECT_FALSE(iset.Contains(iset_contains));
+  EXPECT_FALSE(iset.Contains(QuicInterval<int>()));
+  EXPECT_FALSE(iset.Contains(QuicIntervalSet<int>()));
+
+  // Check the case where the query set isn't contained, but the spanning
+  // intervals do overlap.
+  QuicIntervalSet<int> i2({{220, 230}});
+  EXPECT_FALSE(iset.Contains(i2));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetContainsEmpty) {
+  const QuicIntervalSet<int> empty;
+  const QuicIntervalSet<int> other_empty;
+  const QuicIntervalSet<int> non_empty({{10, 20}, {40, 50}});
+  EXPECT_FALSE(empty.Contains(empty));
+  EXPECT_FALSE(empty.Contains(other_empty));
+  EXPECT_FALSE(empty.Contains(non_empty));
+  EXPECT_FALSE(non_empty.Contains(empty));
+}
+
+TEST_F(QuicIntervalSetTest, Equality) {
+  QuicIntervalSet<int> is_copy = is;
+  EXPECT_EQ(is, is);
+  EXPECT_EQ(is, is_copy);
+  EXPECT_NE(is, other);
+  EXPECT_NE(is, QuicIntervalSet<int>());
+  EXPECT_EQ(QuicIntervalSet<int>(), QuicIntervalSet<int>());
+}
+
+TEST_F(QuicIntervalSetTest, LowerAndUpperBound) {
+  QuicIntervalSet<int> intervals;
+  intervals.Add(10, 20);
+  intervals.Add(30, 40);
+
+  //   [10, 20)  [30, 40)  end
+  //   ^                        LowerBound(5)
+  //   ^                        LowerBound(10)
+  //   ^                        LowerBound(15)
+  //             ^              LowerBound(20)
+  //             ^              LowerBound(25)
+  //             ^              LowerBound(30)
+  //             ^              LowerBound(35)
+  //                       ^    LowerBound(40)
+  //                       ^    LowerBound(50)
+  EXPECT_EQ(intervals.LowerBound(5)->min(), 10);
+  EXPECT_EQ(intervals.LowerBound(10)->min(), 10);
+  EXPECT_EQ(intervals.LowerBound(15)->min(), 10);
+  EXPECT_EQ(intervals.LowerBound(20)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(25)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(30)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(35)->min(), 30);
+  EXPECT_EQ(intervals.LowerBound(40), intervals.end());
+  EXPECT_EQ(intervals.LowerBound(50), intervals.end());
+
+  //   [10, 20)  [30, 40)  end
+  //   ^                        UpperBound(5)
+  //             ^              UpperBound(10)
+  //             ^              UpperBound(15)
+  //             ^              UpperBound(20)
+  //             ^              UpperBound(25)
+  //                       ^    UpperBound(30)
+  //                       ^    UpperBound(35)
+  //                       ^    UpperBound(40)
+  //                       ^    UpperBound(50)
+  EXPECT_EQ(intervals.UpperBound(5)->min(), 10);
+  EXPECT_EQ(intervals.UpperBound(10)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(15)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(20)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(25)->min(), 30);
+  EXPECT_EQ(intervals.UpperBound(30), intervals.end());
+  EXPECT_EQ(intervals.UpperBound(35), intervals.end());
+  EXPECT_EQ(intervals.UpperBound(40), intervals.end());
+  EXPECT_EQ(intervals.UpperBound(50), intervals.end());
+}
+
+TEST_F(QuicIntervalSetTest, SpanningInterval) {
+  // Spanning interval of an empty set is empty:
+  {
+    QuicIntervalSet<int> iset;
+    const QuicInterval<int>& ival = iset.SpanningInterval();
+    EXPECT_TRUE(ival.Empty());
+  }
+
+  // Spanning interval of a set with one interval is that interval:
+  {
+    QuicIntervalSet<int> iset;
+    iset.Add(100, 200);
+    const QuicInterval<int>& ival = iset.SpanningInterval();
+    EXPECT_EQ(100, ival.min());
+    EXPECT_EQ(200, ival.max());
+  }
+
+  // Spanning interval of a set with multiple elements is determined
+  // by the endpoints of the first and last element:
+  {
+    const QuicInterval<int>& ival = is.SpanningInterval();
+    EXPECT_EQ(100, ival.min());
+    EXPECT_EQ(2200, ival.max());
+  }
+  {
+    const QuicInterval<int>& ival = other.SpanningInterval();
+    EXPECT_EQ(50, ival.min());
+    EXPECT_EQ(2270, ival.max());
+  }
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetUnion) {
+  is.Union(other);
+  EXPECT_TRUE(Check(is, 12, 50, 70, 100, 200, 300, 400, 470, 600, 650, 670, 700,
+                    830, 870, 1000, 1100, 1230, 1270, 1830, 1900, 2000, 2100,
+                    2200, 2250, 2270));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersection) {
+  EXPECT_TRUE(is.Intersects(other));
+  EXPECT_TRUE(other.Intersects(is));
+  is.Intersection(other);
+  EXPECT_TRUE(Check(is, 7, 350, 360, 370, 380, 500, 530, 770, 800, 1300, 1400,
+                    1500, 1600, 1700, 1800));
+  EXPECT_TRUE(is.Intersects(other));
+  EXPECT_TRUE(other.Intersects(is));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionBothEmpty) {
+  QuicIntervalSet<std::string> mine, theirs;
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyMine) {
+  QuicIntervalSet<std::string> mine;
+  QuicIntervalSet<std::string> theirs("a", "b");
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionEmptyTheirs) {
+  QuicIntervalSet<std::string> mine("a", "b");
+  QuicIntervalSet<std::string> theirs;
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBeforeMine) {
+  QuicIntervalSet<std::string> mine("y", "z");
+  QuicIntervalSet<std::string> theirs;
+  theirs.Add("a", "b");
+  theirs.Add("c", "d");
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBeforeTheirs) {
+  QuicIntervalSet<std::string> mine;
+  mine.Add("a", "b");
+  mine.Add("c", "d");
+  QuicIntervalSet<std::string> theirs("y", "z");
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionTheirsBeforeMineInt64Singletons) {
+  QuicIntervalSet<int64_t> mine({{10, 15}});
+  QuicIntervalSet<int64_t> theirs({{-20, -5}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionMineBeforeTheirsIntSingletons) {
+  QuicIntervalSet<int> mine({{10, 15}});
+  QuicIntervalSet<int> theirs({{90, 95}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionTheirsBetweenMine) {
+  QuicIntervalSet<int64_t> mine({{0, 5}, {40, 50}});
+  QuicIntervalSet<int64_t> theirs({{10, 15}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionMineBetweenTheirs) {
+  QuicIntervalSet<int> mine({{20, 25}});
+  QuicIntervalSet<int> theirs({{10, 15}, {30, 32}});
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionAlternatingIntervals) {
+  QuicIntervalSet<int> mine, theirs;
+  mine.Add(10, 20);
+  mine.Add(40, 50);
+  mine.Add(60, 70);
+  theirs.Add(25, 39);
+  theirs.Add(55, 59);
+  theirs.Add(75, 79);
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(mine.Empty());
+  EXPECT_FALSE(mine.Intersects(theirs));
+  EXPECT_FALSE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionAdjacentAlternatingNonIntersectingIntervals) {
+  // Make sure that intersection with adjacent interval set is empty.
+  const QuicIntervalSet<int> x1({{0, 10}});
+  const QuicIntervalSet<int> y1({{-50, 0}, {10, 95}});
+
+  QuicIntervalSet<int> result1 = x1;
+  result1.Intersection(y1);
+  EXPECT_TRUE(result1.Empty()) << result1;
+
+  const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
+  const QuicIntervalSet<int16_t> y2(
+      {{-50, -40}, {-2, 0}, {10, 20}, {32, 40}, {90, 95}});
+
+  QuicIntervalSet<int16_t> result2 = x2;
+  result2.Intersection(y2);
+  EXPECT_TRUE(result2.Empty()) << result2;
+
+  const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
+  const QuicIntervalSet<int64_t> y3({{-10, -1}, {10, 95}});
+
+  QuicIntervalSet<int64_t> result3 = x3;
+  result3.Intersection(y3);
+  EXPECT_TRUE(result3.Empty()) << result3;
+}
+
+TEST_F(QuicIntervalSetTest,
+       QuicIntervalSetIntersectionAlternatingIntersectingIntervals) {
+  const QuicIntervalSet<int> x1({{0, 10}});
+  const QuicIntervalSet<int> y1({{-50, 1}, {9, 95}});
+  const QuicIntervalSet<int> expected_result1({{0, 1}, {9, 10}});
+
+  QuicIntervalSet<int> result1 = x1;
+  result1.Intersection(y1);
+  EXPECT_EQ(result1, expected_result1);
+
+  const QuicIntervalSet<int16_t> x2({{0, 10}, {20, 30}, {40, 90}});
+  const QuicIntervalSet<int16_t> y2(
+      {{-50, -40}, {-2, 2}, {9, 21}, {32, 41}, {85, 95}});
+  const QuicIntervalSet<int16_t> expected_result2(
+      {{0, 2}, {9, 10}, {20, 21}, {40, 41}, {85, 90}});
+
+  QuicIntervalSet<int16_t> result2 = x2;
+  result2.Intersection(y2);
+  EXPECT_EQ(result2, expected_result2);
+
+  const QuicIntervalSet<int64_t> x3({{-1, 5}, {5, 10}});
+  const QuicIntervalSet<int64_t> y3({{-10, 3}, {4, 95}});
+  const QuicIntervalSet<int64_t> expected_result3({{-1, 3}, {4, 10}});
+
+  QuicIntervalSet<int64_t> result3 = x3;
+  result3.Intersection(y3);
+  EXPECT_EQ(result3, expected_result3);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionIdentical) {
+  QuicIntervalSet<int> copy(is);
+  EXPECT_TRUE(copy.Intersects(is));
+  EXPECT_TRUE(is.Intersects(copy));
+  is.Intersection(copy);
+  EXPECT_EQ(copy, is);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSuperset) {
+  QuicIntervalSet<int> mine(-1, 10000);
+  EXPECT_TRUE(mine.Intersects(is));
+  EXPECT_TRUE(is.Intersects(mine));
+  mine.Intersection(is);
+  EXPECT_EQ(is, mine);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionSubset) {
+  QuicIntervalSet<int> copy(is);
+  QuicIntervalSet<int> theirs(-1, 10000);
+  EXPECT_TRUE(copy.Intersects(theirs));
+  EXPECT_TRUE(theirs.Intersects(copy));
+  is.Intersection(theirs);
+  EXPECT_EQ(copy, is);
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetIntersectionLargeSet) {
+  QuicIntervalSet<int> mine, theirs;
+  // mine: [0, 9), [10, 19), ..., [990, 999)
+  for (int i = 0; i < 1000; i += 10) {
+    mine.Add(i, i + 9);
+  }
+
+  theirs.Add(500, 520);
+  theirs.Add(535, 545);
+  theirs.Add(801, 809);
+  EXPECT_TRUE(mine.Intersects(theirs));
+  EXPECT_TRUE(theirs.Intersects(mine));
+  mine.Intersection(theirs);
+  EXPECT_TRUE(Check(mine, 5, 500, 509, 510, 519, 535, 539, 540, 545, 801, 809));
+  EXPECT_TRUE(mine.Intersects(theirs));
+  EXPECT_TRUE(theirs.Intersects(mine));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifference) {
+  is.Difference(other);
+  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
+                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
+  QuicIntervalSet<int> copy = is;
+  is.Difference(copy);
+  EXPECT_TRUE(is.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleBounds) {
+  std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
+  for (const QuicInterval<int>& ival : ivals) {
+    is.Difference(ival.min(), ival.max());
+  }
+  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
+                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceSingleInterval) {
+  std::vector<QuicInterval<int>> ivals(other.begin(), other.end());
+  for (const QuicInterval<int>& ival : ivals) {
+    is.Difference(ival);
+  }
+  EXPECT_TRUE(Check(is, 10, 100, 200, 300, 350, 360, 370, 380, 400, 530, 600,
+                    700, 770, 900, 1000, 1100, 1200, 1900, 2000, 2100, 2200));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceAlternatingIntervals) {
+  QuicIntervalSet<int> mine, theirs;
+  mine.Add(10, 20);
+  mine.Add(40, 50);
+  mine.Add(60, 70);
+  theirs.Add(25, 39);
+  theirs.Add(55, 59);
+  theirs.Add(75, 79);
+
+  mine.Difference(theirs);
+  EXPECT_TRUE(Check(mine, 3, 10, 20, 40, 50, 60, 70));
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyMine) {
+  QuicIntervalSet<std::string> mine, theirs;
+  theirs.Add("a", "b");
+
+  mine.Difference(theirs);
+  EXPECT_TRUE(mine.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceEmptyTheirs) {
+  QuicIntervalSet<std::string> mine, theirs;
+  mine.Add("a", "b");
+
+  mine.Difference(theirs);
+  EXPECT_EQ(1u, mine.Size());
+  EXPECT_EQ("a", mine.begin()->min());
+  EXPECT_EQ("b", mine.begin()->max());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceTheirsBeforeMine) {
+  QuicIntervalSet<std::string> mine, theirs;
+  mine.Add("y", "z");
+  theirs.Add("a", "b");
+
+  mine.Difference(theirs);
+  EXPECT_EQ(1u, mine.Size());
+  EXPECT_EQ("y", mine.begin()->min());
+  EXPECT_EQ("z", mine.begin()->max());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceMineBeforeTheirs) {
+  QuicIntervalSet<std::string> mine, theirs;
+  mine.Add("a", "b");
+  theirs.Add("y", "z");
+
+  mine.Difference(theirs);
+  EXPECT_EQ(1u, mine.Size());
+  EXPECT_EQ("a", mine.begin()->min());
+  EXPECT_EQ("b", mine.begin()->max());
+}
+
+TEST_F(QuicIntervalSetTest, QuicIntervalSetDifferenceIdentical) {
+  QuicIntervalSet<std::string> mine;
+  mine.Add("a", "b");
+  mine.Add("c", "d");
+  QuicIntervalSet<std::string> theirs(mine);
+
+  mine.Difference(theirs);
+  EXPECT_TRUE(mine.Empty());
+}
+
+TEST_F(QuicIntervalSetTest, EmptyComplement) {
+  // The complement of an empty set is the input interval:
+  QuicIntervalSet<int> iset;
+  iset.Complement(100, 200);
+  EXPECT_TRUE(Check(iset, 1, 100, 200));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, OuterCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that covers all of these ranges
+  iset.Add(0, 500);
+  EXPECT_TRUE(Check(iset, 1, 0, 500));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, InnerCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that partially covers the left and right most ranges.
+  iset.Add(125, 425);
+  EXPECT_TRUE(Check(iset, 1, 100, 450));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, LeftCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that partially covers the left most range.
+  iset.Add(125, 500);
+  EXPECT_TRUE(Check(iset, 1, 100, 500));
+}
+
+TEST(QuicIntervalSetMultipleCompactionTest, RightCovering) {
+  QuicIntervalSet<int> iset;
+  // First add a bunch of disjoint ranges
+  iset.Add(100, 150);
+  iset.Add(200, 250);
+  iset.Add(300, 350);
+  iset.Add(400, 450);
+  EXPECT_TRUE(Check(iset, 4, 100, 150, 200, 250, 300, 350, 400, 450));
+  // Now add a big range that partially covers the right most range.
+  iset.Add(0, 425);
+  EXPECT_TRUE(Check(iset, 1, 0, 450));
+}
+
+// Helper method for testing and verifying the results of a one-interval
+// completement case.
+static bool CheckOneComplement(int add_min,
+                               int add_max,
+                               int comp_min,
+                               int comp_max,
+                               int count,
+                               ...) {
+  QuicIntervalSet<int> iset;
+  iset.Add(add_min, add_max);
+  iset.Complement(comp_min, comp_max);
+  bool result = true;
+  va_list ap;
+  va_start(ap, count);
+  if (!VA_Check(iset, count, ap)) {
+    result = false;
+  }
+  va_end(ap);
+  return result;
+}
+
+TEST_F(QuicIntervalSetTest, SingleIntervalComplement) {
+  // Verify the complement of a set with one interval (i):
+  //                     |-----   i  -----|
+  // |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(0, 10, 50, 150, 1, 50, 150));
+
+  //          |-----   i  -----|
+  //    |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 0, 100, 1, 0, 50));
+
+  //    |-----   i  -----|
+  //    |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 50, 150, 0));
+
+  //    |----------   i  ----------|
+  //        |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 500, 100, 300, 0));
+
+  //        |----- i -----|
+  //    |---------- args  ----------|
+  EXPECT_TRUE(CheckOneComplement(50, 500, 0, 800, 2, 0, 50, 500, 800));
+
+  //    |-----   i  -----|
+  //          |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 100, 300, 1, 150, 300));
+
+  //    |-----   i  -----|
+  //                        |----- args -----|
+  EXPECT_TRUE(CheckOneComplement(50, 150, 200, 300, 1, 200, 300));
+}
+
+// Helper method that copies <iset> and takes its complement,
+// returning false if Check succeeds.
+static bool CheckComplement(const QuicIntervalSet<int>& iset,
+                            int comp_min,
+                            int comp_max,
+                            int count,
+                            ...) {
+  QuicIntervalSet<int> iset_copy = iset;
+  iset_copy.Complement(comp_min, comp_max);
+  bool result = true;
+  va_list ap;
+  va_start(ap, count);
+  if (!VA_Check(iset_copy, count, ap)) {
+    result = false;
+  }
+  va_end(ap);
+  return result;
+}
+
+TEST_F(QuicIntervalSetTest, MultiIntervalComplement) {
+  // Initialize a small test set:
+  QuicIntervalSet<int> iset;
+  iset.Add(100, 200);
+  iset.Add(300, 400);
+  iset.Add(500, 600);
+
+  //                     |-----   i  -----|
+  // |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 0, 50, 1, 0, 50));
+
+  //          |-----   i  -----|
+  //    |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 0, 200, 1, 0, 100));
+  EXPECT_TRUE(CheckComplement(iset, 0, 220, 2, 0, 100, 200, 220));
+
+  //    |-----   i  -----|
+  //    |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 100, 600, 2, 200, 300, 400, 500));
+
+  //    |----------   i  ----------|
+  //        |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 300, 400, 0));
+  EXPECT_TRUE(CheckComplement(iset, 250, 400, 1, 250, 300));
+  EXPECT_TRUE(CheckComplement(iset, 300, 450, 1, 400, 450));
+  EXPECT_TRUE(CheckComplement(iset, 250, 450, 2, 250, 300, 400, 450));
+
+  //        |----- i -----|
+  //    |---------- comp  ----------|
+  EXPECT_TRUE(
+      CheckComplement(iset, 0, 700, 4, 0, 100, 200, 300, 400, 500, 600, 700));
+
+  //    |-----   i  -----|
+  //          |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 400, 700, 2, 400, 500, 600, 700));
+  EXPECT_TRUE(CheckComplement(iset, 350, 700, 2, 400, 500, 600, 700));
+
+  //    |-----   i  -----|
+  //                        |----- comp -----|
+  EXPECT_TRUE(CheckComplement(iset, 700, 800, 1, 700, 800));
+}
+
+// Verifies ToString, operator<< don't assert.
+TEST_F(QuicIntervalSetTest, ToString) {
+  QuicIntervalSet<int> iset;
+  iset.Add(300, 400);
+  iset.Add(100, 200);
+  iset.Add(500, 600);
+  EXPECT_TRUE(!iset.ToString().empty());
+  QUIC_VLOG(2) << iset;
+  // Order and format of ToString() output is guaranteed.
+  EXPECT_EQ("{ [100, 200) [300, 400) [500, 600) }", iset.ToString());
+  EXPECT_EQ("{ [1, 2) }", QuicIntervalSet<int>(1, 2).ToString());
+  EXPECT_EQ("{ }", QuicIntervalSet<int>().ToString());
+}
+
+TEST_F(QuicIntervalSetTest, ConstructionDiscardsEmptyInterval) {
+  EXPECT_TRUE(QuicIntervalSet<int>(QuicInterval<int>(2, 2)).Empty());
+  EXPECT_TRUE(QuicIntervalSet<int>(2, 2).Empty());
+  EXPECT_FALSE(QuicIntervalSet<int>(QuicInterval<int>(2, 3)).Empty());
+  EXPECT_FALSE(QuicIntervalSet<int>(2, 3).Empty());
+}
+
+TEST_F(QuicIntervalSetTest, Swap) {
+  QuicIntervalSet<int> a, b;
+  a.Add(300, 400);
+  b.Add(100, 200);
+  b.Add(500, 600);
+  std::swap(a, b);
+  EXPECT_TRUE(Check(a, 2, 100, 200, 500, 600));
+  EXPECT_TRUE(Check(b, 1, 300, 400));
+  std::swap(a, b);
+  EXPECT_TRUE(Check(a, 1, 300, 400));
+  EXPECT_TRUE(Check(b, 2, 100, 200, 500, 600));
+}
+
+TEST_F(QuicIntervalSetTest, OutputReturnsOstreamRef) {
+  std::stringstream ss;
+  const QuicIntervalSet<int> v(QuicInterval<int>(1, 2));
+  auto return_type_is_a_ref = [](std::ostream&) {};
+  return_type_is_a_ref(ss << v);
+}
+
+struct NotOstreamable {
+  bool operator<(const NotOstreamable&) const { return false; }
+  bool operator>(const NotOstreamable&) const { return false; }
+  bool operator!=(const NotOstreamable&) const { return false; }
+  bool operator>=(const NotOstreamable&) const { return true; }
+  bool operator<=(const NotOstreamable&) const { return true; }
+  bool operator==(const NotOstreamable&) const { return true; }
+};
+
+TEST_F(QuicIntervalSetTest, IntervalOfTypeWithNoOstreamSupport) {
+  const NotOstreamable v;
+  const QuicIntervalSet<NotOstreamable> d(QuicInterval<NotOstreamable>(v, v));
+  // EXPECT_EQ builds a string representation of d. If d::operator<<()
+  // would be defined then this test would not compile because NotOstreamable
+  // objects lack the operator<<() support.
+  EXPECT_EQ(d, d);
+}
+
+class QuicIntervalSetInitTest : public QuicTest {
+ protected:
+  const std::vector<QuicInterval<int>> intervals_{{0, 1}, {2, 4}};
+};
+
+TEST_F(QuicIntervalSetInitTest, DirectInit) {
+  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
+  QuicIntervalSet<int> s(il);
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, CopyInit) {
+  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
+  QuicIntervalSet<int> s = il;
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, AssignIterPair) {
+  QuicIntervalSet<int> s(0, 1000);  // Make sure assign clears.
+  s.assign(intervals_.begin(), intervals_.end());
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, AssignInitList) {
+  QuicIntervalSet<int> s(0, 1000);  // Make sure assign clears.
+  s.assign({{0, 1}, {2, 3}, {3, 4}});
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, AssignmentInitList) {
+  std::initializer_list<QuicInterval<int>> il = {{0, 1}, {2, 3}, {3, 4}};
+  QuicIntervalSet<int> s;
+  s = il;
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+TEST_F(QuicIntervalSetInitTest, BracedInitThenBracedAssign) {
+  QuicIntervalSet<int> s{{0, 1}, {2, 3}, {3, 4}};
+  s = {{0, 1}, {2, 4}};
+  EXPECT_THAT(s, ElementsAreArray(intervals_));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_interval_test.cc b/quiche/quic/core/quic_interval_test.cc
new file mode 100644
index 0000000..6848472
--- /dev/null
+++ b/quiche/quic/core/quic_interval_test.cc
@@ -0,0 +1,470 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_interval.h"
+
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+template <typename ForwardIterator>
+void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
+  while (begin != end) {
+    auto temp = begin;
+    ++begin;
+    delete *temp;
+  }
+}
+
+template <typename T>
+void STLDeleteElements(T* container) {
+  if (!container)
+    return;
+  STLDeleteContainerPointers(container->begin(), container->end());
+  container->clear();
+}
+
+class ConstructorListener {
+ public:
+  ConstructorListener(int* copy_construct_counter, int* move_construct_counter)
+      : copy_construct_counter_(copy_construct_counter),
+        move_construct_counter_(move_construct_counter) {
+    *copy_construct_counter_ = 0;
+    *move_construct_counter_ = 0;
+  }
+  ConstructorListener(const ConstructorListener& other) {
+    copy_construct_counter_ = other.copy_construct_counter_;
+    move_construct_counter_ = other.move_construct_counter_;
+    ++*copy_construct_counter_;
+  }
+  ConstructorListener(ConstructorListener&& other) {
+    copy_construct_counter_ = other.copy_construct_counter_;
+    move_construct_counter_ = other.move_construct_counter_;
+    ++*move_construct_counter_;
+  }
+  bool operator<(const ConstructorListener&) { return false; }
+  bool operator>(const ConstructorListener&) { return false; }
+  bool operator<=(const ConstructorListener&) { return true; }
+  bool operator>=(const ConstructorListener&) { return true; }
+  bool operator==(const ConstructorListener&) { return true; }
+
+ private:
+  int* copy_construct_counter_;
+  int* move_construct_counter_;
+};
+
+TEST(QuicIntervalConstructorTest, Move) {
+  int object1_copy_count, object1_move_count;
+  ConstructorListener object1(&object1_copy_count, &object1_move_count);
+  int object2_copy_count, object2_move_count;
+  ConstructorListener object2(&object2_copy_count, &object2_move_count);
+
+  QuicInterval<ConstructorListener> interval(object1, std::move(object2));
+  EXPECT_EQ(1, object1_copy_count);
+  EXPECT_EQ(0, object1_move_count);
+  EXPECT_EQ(0, object2_copy_count);
+  EXPECT_EQ(1, object2_move_count);
+}
+
+TEST(QuicIntervalConstructorTest, ImplicitConversion) {
+  struct WrappedInt {
+    WrappedInt(int value) : value(value) {}
+    bool operator<(const WrappedInt& other) { return value < other.value; }
+    bool operator>(const WrappedInt& other) { return value > other.value; }
+    bool operator<=(const WrappedInt& other) { return value <= other.value; }
+    bool operator>=(const WrappedInt& other) { return value >= other.value; }
+    bool operator==(const WrappedInt& other) { return value == other.value; }
+    int value;
+  };
+
+  static_assert(std::is_convertible<int, WrappedInt>::value, "");
+  static_assert(
+      std::is_constructible<QuicInterval<WrappedInt>, int, int>::value, "");
+
+  QuicInterval<WrappedInt> i(10, 20);
+  EXPECT_EQ(10, i.min().value);
+  EXPECT_EQ(20, i.max().value);
+}
+
+class QuicIntervalTest : public QuicTest {
+ protected:
+  // Test intersection between the two intervals i1 and i2.  Tries
+  // i1.IntersectWith(i2) and vice versa. The intersection should change i1 iff
+  // changes_i1 is true, and the same for changes_i2.  The resulting
+  // intersection should be result.
+  void TestIntersect(const QuicInterval<int64_t>& i1,
+                     const QuicInterval<int64_t>& i2,
+                     bool changes_i1,
+                     bool changes_i2,
+                     const QuicInterval<int64_t>& result) {
+    QuicInterval<int64_t> i;
+    i = i1;
+    EXPECT_TRUE(i.IntersectWith(i2) == changes_i1 && i == result);
+    i = i2;
+    EXPECT_TRUE(i.IntersectWith(i1) == changes_i2 && i == result);
+  }
+};
+
+TEST_F(QuicIntervalTest, ConstructorsCopyAndClear) {
+  QuicInterval<int32_t> empty;
+  EXPECT_TRUE(empty.Empty());
+
+  QuicInterval<int32_t> d2(0, 100);
+  EXPECT_EQ(0, d2.min());
+  EXPECT_EQ(100, d2.max());
+  EXPECT_EQ(QuicInterval<int32_t>(0, 100), d2);
+  EXPECT_NE(QuicInterval<int32_t>(0, 99), d2);
+
+  empty = d2;
+  EXPECT_EQ(0, d2.min());
+  EXPECT_EQ(100, d2.max());
+  EXPECT_TRUE(empty == d2);
+  EXPECT_EQ(empty, d2);
+  EXPECT_TRUE(d2 == empty);
+  EXPECT_EQ(d2, empty);
+
+  QuicInterval<int32_t> max_less_than_min(40, 20);
+  EXPECT_TRUE(max_less_than_min.Empty());
+  EXPECT_EQ(40, max_less_than_min.min());
+  EXPECT_EQ(20, max_less_than_min.max());
+
+  QuicInterval<int> d3(10, 20);
+  d3.Clear();
+  EXPECT_TRUE(d3.Empty());
+}
+
+TEST_F(QuicIntervalTest, MakeQuicInterval) {
+  static_assert(
+      std::is_same<QuicInterval<int>, decltype(MakeQuicInterval(0, 3))>::value,
+      "Type is deduced incorrectly.");
+  static_assert(std::is_same<QuicInterval<double>,
+                             decltype(MakeQuicInterval(0., 3.))>::value,
+                "Type is deduced incorrectly.");
+
+  EXPECT_EQ(MakeQuicInterval(0., 3.), QuicInterval<double>(0, 3));
+}
+
+TEST_F(QuicIntervalTest, GettersSetters) {
+  QuicInterval<int32_t> d1(100, 200);
+
+  // SetMin:
+  d1.SetMin(30);
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(200, d1.max());
+
+  // SetMax:
+  d1.SetMax(220);
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  // Set:
+  d1.Clear();
+  d1.Set(30, 220);
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  // SpanningUnion:
+  QuicInterval<int32_t> d2;
+  EXPECT_TRUE(!d1.SpanningUnion(d2));
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  EXPECT_TRUE(d2.SpanningUnion(d1));
+  EXPECT_EQ(30, d2.min());
+  EXPECT_EQ(220, d2.max());
+
+  d2.SetMin(40);
+  d2.SetMax(100);
+  EXPECT_TRUE(!d1.SpanningUnion(d2));
+  EXPECT_EQ(30, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  d2.SetMin(20);
+  d2.SetMax(100);
+  EXPECT_TRUE(d1.SpanningUnion(d2));
+  EXPECT_EQ(20, d1.min());
+  EXPECT_EQ(220, d1.max());
+
+  d2.SetMin(50);
+  d2.SetMax(300);
+  EXPECT_TRUE(d1.SpanningUnion(d2));
+  EXPECT_EQ(20, d1.min());
+  EXPECT_EQ(300, d1.max());
+
+  d2.SetMin(0);
+  d2.SetMax(500);
+  EXPECT_TRUE(d1.SpanningUnion(d2));
+  EXPECT_EQ(0, d1.min());
+  EXPECT_EQ(500, d1.max());
+
+  d2.SetMin(100);
+  d2.SetMax(0);
+  EXPECT_TRUE(!d1.SpanningUnion(d2));
+  EXPECT_EQ(0, d1.min());
+  EXPECT_EQ(500, d1.max());
+  EXPECT_TRUE(d2.SpanningUnion(d1));
+  EXPECT_EQ(0, d2.min());
+  EXPECT_EQ(500, d2.max());
+}
+
+TEST_F(QuicIntervalTest, CoveringOps) {
+  const QuicInterval<int64_t> empty;
+  const QuicInterval<int64_t> d(100, 200);
+  const QuicInterval<int64_t> d1(0, 50);
+  const QuicInterval<int64_t> d2(50, 110);
+  const QuicInterval<int64_t> d3(110, 180);
+  const QuicInterval<int64_t> d4(180, 220);
+  const QuicInterval<int64_t> d5(220, 300);
+  const QuicInterval<int64_t> d6(100, 150);
+  const QuicInterval<int64_t> d7(150, 200);
+  const QuicInterval<int64_t> d8(0, 300);
+
+  // Intersection:
+  EXPECT_TRUE(d.Intersects(d));
+  EXPECT_TRUE(!empty.Intersects(d) && !d.Intersects(empty));
+  EXPECT_TRUE(!d.Intersects(d1) && !d1.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d2) && d2.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d3) && d3.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d4) && d4.Intersects(d));
+  EXPECT_TRUE(!d.Intersects(d5) && !d5.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d6) && d6.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d7) && d7.Intersects(d));
+  EXPECT_TRUE(d.Intersects(d8) && d8.Intersects(d));
+
+  QuicInterval<int64_t> i;
+  EXPECT_TRUE(d.Intersects(d, &i) && d == i);
+  EXPECT_TRUE(!empty.Intersects(d, nullptr) && !d.Intersects(empty, nullptr));
+  EXPECT_TRUE(!d.Intersects(d1, nullptr) && !d1.Intersects(d, nullptr));
+  EXPECT_TRUE(d.Intersects(d2, &i) && i == QuicInterval<int64_t>(100, 110));
+  EXPECT_TRUE(d2.Intersects(d, &i) && i == QuicInterval<int64_t>(100, 110));
+  EXPECT_TRUE(d.Intersects(d3, &i) && i == d3);
+  EXPECT_TRUE(d3.Intersects(d, &i) && i == d3);
+  EXPECT_TRUE(d.Intersects(d4, &i) && i == QuicInterval<int64_t>(180, 200));
+  EXPECT_TRUE(d4.Intersects(d, &i) && i == QuicInterval<int64_t>(180, 200));
+  EXPECT_TRUE(!d.Intersects(d5, nullptr) && !d5.Intersects(d, nullptr));
+  EXPECT_TRUE(d.Intersects(d6, &i) && i == d6);
+  EXPECT_TRUE(d6.Intersects(d, &i) && i == d6);
+  EXPECT_TRUE(d.Intersects(d7, &i) && i == d7);
+  EXPECT_TRUE(d7.Intersects(d, &i) && i == d7);
+  EXPECT_TRUE(d.Intersects(d8, &i) && i == d);
+  EXPECT_TRUE(d8.Intersects(d, &i) && i == d);
+
+  // Test IntersectsWith().
+  // Arguments are TestIntersect(i1, i2, changes_i1, changes_i2, result).
+  TestIntersect(empty, d, false, true, empty);
+  TestIntersect(d, d1, true, true, empty);
+  TestIntersect(d1, d2, true, true, empty);
+  TestIntersect(d, d2, true, true, QuicInterval<int64_t>(100, 110));
+  TestIntersect(d8, d, true, false, d);
+  TestIntersect(d8, d1, true, false, d1);
+  TestIntersect(d8, d5, true, false, d5);
+
+  // Contains:
+  EXPECT_TRUE(!empty.Contains(d) && !d.Contains(empty));
+  EXPECT_TRUE(d.Contains(d));
+  EXPECT_TRUE(!d.Contains(d1) && !d1.Contains(d));
+  EXPECT_TRUE(!d.Contains(d2) && !d2.Contains(d));
+  EXPECT_TRUE(d.Contains(d3) && !d3.Contains(d));
+  EXPECT_TRUE(!d.Contains(d4) && !d4.Contains(d));
+  EXPECT_TRUE(!d.Contains(d5) && !d5.Contains(d));
+  EXPECT_TRUE(d.Contains(d6) && !d6.Contains(d));
+  EXPECT_TRUE(d.Contains(d7) && !d7.Contains(d));
+  EXPECT_TRUE(!d.Contains(d8) && d8.Contains(d));
+
+  EXPECT_TRUE(d.Contains(100));
+  EXPECT_TRUE(!d.Contains(200));
+  EXPECT_TRUE(d.Contains(150));
+  EXPECT_TRUE(!d.Contains(99));
+  EXPECT_TRUE(!d.Contains(201));
+
+  // Difference:
+  std::vector<QuicInterval<int64_t>*> diff;
+
+  EXPECT_TRUE(!d.Difference(empty, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+  EXPECT_TRUE(!empty.Difference(d, &diff) && diff.empty());
+
+  EXPECT_TRUE(d.Difference(d, &diff) && diff.empty());
+  EXPECT_TRUE(!d.Difference(d1, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  QuicInterval<int64_t> lo;
+  QuicInterval<int64_t> hi;
+
+  EXPECT_TRUE(d.Difference(d2, &lo, &hi));
+  EXPECT_TRUE(lo.Empty());
+  EXPECT_EQ(110, hi.min());
+  EXPECT_EQ(200, hi.max());
+  EXPECT_TRUE(d.Difference(d2, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(110, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d3, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(110, lo.max());
+  EXPECT_EQ(180, hi.min());
+  EXPECT_EQ(200, hi.max());
+  EXPECT_TRUE(d.Difference(d3, &diff));
+  EXPECT_EQ(2u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(110, diff[0]->max());
+  EXPECT_EQ(180, diff[1]->min());
+  EXPECT_EQ(200, diff[1]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d4, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(180, lo.max());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_TRUE(d.Difference(d4, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(180, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_FALSE(d.Difference(d5, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(200, lo.max());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_FALSE(d.Difference(d5, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d6, &lo, &hi));
+  EXPECT_TRUE(lo.Empty());
+  EXPECT_EQ(150, hi.min());
+  EXPECT_EQ(200, hi.max());
+  EXPECT_TRUE(d.Difference(d6, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(150, diff[0]->min());
+  EXPECT_EQ(200, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d7, &lo, &hi));
+  EXPECT_EQ(100, lo.min());
+  EXPECT_EQ(150, lo.max());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_TRUE(d.Difference(d7, &diff));
+  EXPECT_EQ(1u, diff.size());
+  EXPECT_EQ(100, diff[0]->min());
+  EXPECT_EQ(150, diff[0]->max());
+  STLDeleteElements(&diff);
+
+  EXPECT_TRUE(d.Difference(d8, &lo, &hi));
+  EXPECT_TRUE(lo.Empty());
+  EXPECT_TRUE(hi.Empty());
+  EXPECT_TRUE(d.Difference(d8, &diff) && diff.empty());
+}
+
+TEST_F(QuicIntervalTest, Separated) {
+  using QI = QuicInterval<int>;
+  EXPECT_FALSE(QI(100, 200).Separated(QI(100, 200)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(200, 300)));
+  EXPECT_TRUE(QI(100, 200).Separated(QI(201, 300)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(0, 100)));
+  EXPECT_TRUE(QI(100, 200).Separated(QI(0, 99)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(150, 170)));
+  EXPECT_FALSE(QI(150, 170).Separated(QI(100, 200)));
+  EXPECT_FALSE(QI(100, 200).Separated(QI(150, 250)));
+  EXPECT_FALSE(QI(150, 250).Separated(QI(100, 200)));
+}
+
+TEST_F(QuicIntervalTest, Length) {
+  const QuicInterval<int> empty1;
+  const QuicInterval<int> empty2(1, 1);
+  const QuicInterval<int> empty3(1, 0);
+  const QuicInterval<QuicTime> empty4(
+      QuicTime::Zero() + QuicTime::Delta::FromSeconds(1), QuicTime::Zero());
+  const QuicInterval<int> d1(1, 2);
+  const QuicInterval<int> d2(0, 50);
+  const QuicInterval<QuicTime> d3(
+      QuicTime::Zero(), QuicTime::Zero() + QuicTime::Delta::FromSeconds(1));
+  const QuicInterval<QuicTime> d4(
+      QuicTime::Zero() + QuicTime::Delta::FromSeconds(3600),
+      QuicTime::Zero() + QuicTime::Delta::FromSeconds(5400));
+
+  EXPECT_EQ(0, empty1.Length());
+  EXPECT_EQ(0, empty2.Length());
+  EXPECT_EQ(0, empty3.Length());
+  EXPECT_EQ(QuicTime::Delta::Zero(), empty4.Length());
+  EXPECT_EQ(1, d1.Length());
+  EXPECT_EQ(50, d2.Length());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1), d3.Length());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1800), d4.Length());
+}
+
+TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOperatorMinus) {
+  // QuicInterval<T> should work even if T does not support operator-().  We
+  // just can't call QuicInterval<T>::Length() for such types.
+  const QuicInterval<std::string> d1("a", "b");
+  const QuicInterval<std::pair<int, int>> d2({1, 2}, {4, 3});
+  EXPECT_EQ("a", d1.min());
+  EXPECT_EQ("b", d1.max());
+  EXPECT_EQ(std::make_pair(1, 2), d2.min());
+  EXPECT_EQ(std::make_pair(4, 3), d2.max());
+}
+
+struct NoEquals {
+  NoEquals(int v) : value(v) {}  // NOLINT
+  int value;
+  bool operator<(const NoEquals& other) const { return value < other.value; }
+};
+
+TEST_F(QuicIntervalTest, OrderedComparisonForTypeWithoutEquals) {
+  const QuicInterval<NoEquals> d1(0, 4);
+  const QuicInterval<NoEquals> d2(0, 3);
+  const QuicInterval<NoEquals> d3(1, 4);
+  const QuicInterval<NoEquals> d4(1, 5);
+  const QuicInterval<NoEquals> d6(0, 4);
+  EXPECT_TRUE(d1 < d2);
+  EXPECT_TRUE(d1 < d3);
+  EXPECT_TRUE(d1 < d4);
+  EXPECT_FALSE(d1 < d6);
+}
+
+TEST_F(QuicIntervalTest, OutputReturnsOstreamRef) {
+  std::stringstream ss;
+  const QuicInterval<int> v(1, 2);
+  // If (ss << v) were to return a value, it wouldn't match the signature of
+  // return_type_is_a_ref() function.
+  auto return_type_is_a_ref = [](std::ostream&) {};
+  return_type_is_a_ref(ss << v);
+}
+
+struct NotOstreamable {
+  bool operator<(const NotOstreamable&) const { return false; }
+  bool operator>=(const NotOstreamable&) const { return true; }
+  bool operator==(const NotOstreamable&) const { return true; }
+};
+
+TEST_F(QuicIntervalTest, IntervalOfTypeWithNoOstreamSupport) {
+  const NotOstreamable v;
+  const QuicInterval<NotOstreamable> d(v, v);
+  // EXPECT_EQ builds a string representation of d. If d::operator<<() would be
+  // defined then this test would not compile because NotOstreamable objects
+  // lack the operator<<() support.
+  EXPECT_EQ(d, d);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator.cc b/quiche/quic/core/quic_legacy_version_encapsulator.cc
new file mode 100644
index 0000000..826a101
--- /dev/null
+++ b/quiche/quic/core/quic_legacy_version_encapsulator.cc
@@ -0,0 +1,153 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_legacy_version_encapsulator.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
+    QuicPacketBuffer packet_buffer)
+    : packet_buffer_(packet_buffer) {}
+
+QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}
+
+// static
+QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
+    absl::string_view sni) {
+  // The number 52 is the sum of:
+  // - Flags (1 byte)
+  // - Server Connection ID (8 bytes)
+  // - Version (4 bytes)
+  // - Packet Number (1 byte)
+  // - Message Authentication Hash (12 bytes)
+  // - Frame Type (1 byte)
+  // - Stream ID (1 byte)
+  // - ClientHello tag (4 bytes)
+  // - ClientHello num tags (2 bytes)
+  // - Padding (2 bytes)
+  // - SNI tag (4 bytes)
+  // - SNI end offset (4 bytes)
+  // - QLVE tag (4 bytes)
+  // - QLVE end offset (4 bytes)
+  return 52 + sni.length();
+}
+
+QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
+  return packet_buffer_;
+}
+
+void QuicLegacyVersionEncapsulator::OnSerializedPacket(
+    SerializedPacket serialized_packet) {
+  if (encrypted_length_ != 0) {
+    unrecoverable_failure_encountered_ = true;
+    QUIC_BUG(quic_bug_10615_1) << "OnSerializedPacket called twice";
+    return;
+  }
+  if (serialized_packet.encrypted_length == 0) {
+    unrecoverable_failure_encountered_ = true;
+    QUIC_BUG(quic_bug_10615_2) << "OnSerializedPacket called with empty packet";
+    return;
+  }
+  encrypted_length_ = serialized_packet.encrypted_length;
+}
+
+void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
+    QuicErrorCode error,
+    const std::string& error_details) {
+  unrecoverable_failure_encountered_ = true;
+  QUIC_BUG(quic_bug_10615_3) << "QuicLegacyVersionEncapsulator received error "
+                             << error << ": " << error_details;
+}
+
+bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
+    HasRetransmittableData /*retransmittable*/,
+    IsHandshake /*handshake*/) {
+  return true;
+}
+
+const QuicFrames
+QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
+  // We do not want to ever include any ACKs here, return an empty array.
+  return QuicFrames();
+}
+
+SerializedPacketFate QuicLegacyVersionEncapsulator::GetSerializedPacketFate(
+    bool /*is_mtu_discovery*/,
+    EncryptionLevel /*encryption_level*/) {
+  return SEND_TO_WRITER;
+}
+
+// static
+QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
+    absl::string_view sni,
+    absl::string_view inner_packet,
+    const QuicConnectionId& server_connection_id,
+    QuicTime creation_time,
+    QuicByteCount outer_max_packet_length,
+    char* out) {
+  if (outer_max_packet_length > kMaxOutgoingPacketSize) {
+    outer_max_packet_length = kMaxOutgoingPacketSize;
+  }
+  CryptoHandshakeMessage outer_chlo;
+  outer_chlo.set_tag(kCHLO);
+  outer_chlo.SetStringPiece(kSNI, sni);
+  outer_chlo.SetStringPiece(kQLVE, inner_packet);
+  const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
+  QUICHE_DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
+  QUICHE_DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
+  QuicStreamFrame outer_stream_frame(
+      QuicUtils::GetCryptoStreamId(
+          LegacyVersionForEncapsulation().transport_version),
+      /*fin=*/false,
+      /*offset=*/0, serialized_outer_chlo.AsStringPiece());
+  QuicFramer outer_framer(
+      ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
+      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  outer_framer.SetInitialObfuscators(server_connection_id);
+  char outer_encrypted_packet[kMaxOutgoingPacketSize];
+  QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
+  QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
+  QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
+                                  &creator_delegate);
+  outer_creator.SetMaxPacketLength(outer_max_packet_length);
+  outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
+  outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
+  if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
+                                         NOT_RETRANSMISSION)) {
+    QUIC_BUG(quic_bug_10615_4)
+        << "Failed to add Legacy Version Encapsulation stream frame "
+           "(max packet length is "
+        << outer_creator.max_packet_length() << ") " << outer_stream_frame;
+    return 0;
+  }
+  outer_creator.FlushCurrentPacket();
+  const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
+  if (creator_delegate.unrecoverable_failure_encountered_ ||
+      encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10615_5)
+        << "Failed to perform Legacy Version Encapsulation of "
+        << inner_packet.length() << " bytes";
+    return 0;
+  }
+  if (encrypted_length > kMaxOutgoingPacketSize) {
+    QUIC_BUG(quic_bug_10615_6)
+        << "Legacy Version Encapsulation outer creator generated a "
+           "packet with unexpected length "
+        << encrypted_length;
+    return 0;
+  }
+
+  QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
+                  << inner_packet.length() << " bytes to " << encrypted_length;
+
+  // Replace our current packet with the encapsulated one.
+  memcpy(out, outer_encrypted_packet, encrypted_length);
+  return encrypted_length;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator.h b/quiche/quic/core/quic_legacy_version_encapsulator.h
new file mode 100644
index 0000000..fb2db98
--- /dev/null
+++ b/quiche/quic/core/quic_legacy_version_encapsulator.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QuicLegacyVersionEncapsulator is responsible for encapsulation of packets
+// using Legacy Version Encapsulation.
+
+class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator
+    : public QuicPacketCreator::DelegateInterface {
+ public:
+  // Encapsulates |inner_packet| into a new encapsulated packet that uses a
+  // CHLO of version LegacyVersionForEncapsulation() with server name |sni|
+  // exposed and using |server_connection_id|. The packet will be padded up to
+  // |outer_max_packet_length| bytes if necessary. On failure, returns 0. On
+  // success, returns the length of the outer encapsulated packet, and copies
+  // the contents of the encapsulated packet to |out|. |out| must point to a
+  // valid memory buffer capable of holding kMaxOutgoingPacketSize bytes.
+  static QuicPacketLength Encapsulate(
+      absl::string_view sni,
+      absl::string_view inner_packet,
+      const QuicConnectionId& server_connection_id,
+      QuicTime creation_time,
+      QuicByteCount outer_max_packet_length,
+      char* out);
+
+  // Returns the number of bytes of minimum overhead caused by Legacy Version
+  // Encapsulation, based on the length of the provided server name |sni|.
+  // The overhead may be higher due to extra padding added.
+  static QuicByteCount GetMinimumOverhead(absl::string_view sni);
+
+  // Overrides for QuicPacketCreator::DelegateInterface.
+  QuicPacketBuffer GetPacketBuffer() override;
+  void OnSerializedPacket(SerializedPacket serialized_packet) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& error_details) override;
+  bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+                            IsHandshake handshake) override;
+  const QuicFrames MaybeBundleAckOpportunistically() override;
+  SerializedPacketFate GetSerializedPacketFate(
+      bool is_mtu_discovery,
+      EncryptionLevel encryption_level) override;
+
+  ~QuicLegacyVersionEncapsulator() override;
+
+ private:
+  explicit QuicLegacyVersionEncapsulator(QuicPacketBuffer packet_buffer);
+
+  // Disallow copy, move and assignment.
+  QuicLegacyVersionEncapsulator(const QuicLegacyVersionEncapsulator&) = delete;
+  QuicLegacyVersionEncapsulator(QuicLegacyVersionEncapsulator&&) = delete;
+  QuicLegacyVersionEncapsulator& operator=(
+      const QuicLegacyVersionEncapsulator&) = delete;
+  QuicLegacyVersionEncapsulator& operator=(QuicLegacyVersionEncapsulator&&) =
+      delete;
+
+  QuicPacketBuffer packet_buffer_;
+  QuicPacketLength encrypted_length_ = 0;
+  bool unrecoverable_failure_encountered_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
diff --git a/quiche/quic/core/quic_legacy_version_encapsulator_test.cc b/quiche/quic/core/quic_legacy_version_encapsulator_test.cc
new file mode 100644
index 0000000..928386d
--- /dev/null
+++ b/quiche/quic/core/quic_legacy_version_encapsulator_test.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_legacy_version_encapsulator.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicLegacyVersionEncapsulatorTest
+    : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicLegacyVersionEncapsulatorTest()
+      : version_(GetParam()),
+        sni_("test.example.org"),
+        server_connection_id_(TestConnectionId()),
+        outer_max_packet_length_(kMaxOutgoingPacketSize),
+        encapsulated_length_(0) {}
+
+  void Encapsulate(const std::string& inner_packet) {
+    encapsulated_length_ = QuicLegacyVersionEncapsulator::Encapsulate(
+        sni_, inner_packet, server_connection_id_, QuicTime::Zero(),
+        outer_max_packet_length_, outer_buffer_);
+  }
+
+  void CheckEncapsulation() {
+    ASSERT_NE(encapsulated_length_, 0u);
+    ASSERT_EQ(encapsulated_length_, outer_max_packet_length_);
+    // Verify that the encapsulated packet parses as encapsulated.
+    PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
+    QuicLongHeaderType long_packet_type;
+    bool version_present;
+    bool has_length_prefix;
+    QuicVersionLabel version_label;
+    ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+    QuicConnectionId destination_connection_id, source_connection_id;
+    absl::optional<absl::string_view> retry_token;
+    std::string detailed_error;
+    const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+        QuicEncryptedPacket(outer_buffer_, encapsulated_length_),
+        kQuicDefaultConnectionIdLength, &format, &long_packet_type,
+        &version_present, &has_length_prefix, &version_label, &parsed_version,
+        &destination_connection_id, &source_connection_id, &retry_token,
+        &detailed_error);
+    ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+    EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
+    EXPECT_TRUE(version_present);
+    EXPECT_FALSE(has_length_prefix);
+    EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
+    EXPECT_EQ(destination_connection_id, server_connection_id_);
+    EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
+    EXPECT_FALSE(retry_token.has_value());
+    EXPECT_TRUE(detailed_error.empty());
+  }
+
+  QuicByteCount Overhead() {
+    return QuicLegacyVersionEncapsulator::GetMinimumOverhead(sni_);
+  }
+
+  ParsedQuicVersion version_;
+  std::string sni_;
+  QuicConnectionId server_connection_id_;
+  QuicByteCount outer_max_packet_length_;
+  char outer_buffer_[kMaxOutgoingPacketSize];
+  QuicPacketLength encapsulated_length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicLegacyVersionEncapsulatorTests,
+                         QuicLegacyVersionEncapsulatorTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, Simple) {
+  Encapsulate("TEST_INNER_PACKET");
+  CheckEncapsulation();
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, TooBig) {
+  std::string inner_packet(kMaxOutgoingPacketSize, '?');
+  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
+  ASSERT_EQ(encapsulated_length_, 0u);
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, BarelyFits) {
+  QuicByteCount inner_size = kMaxOutgoingPacketSize - Overhead();
+  std::string inner_packet(inner_size, '?');
+  Encapsulate(inner_packet);
+  CheckEncapsulation();
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, DoesNotQuiteFit) {
+  QuicByteCount inner_size = 1 + kMaxOutgoingPacketSize - Overhead();
+  std::string inner_packet(inner_size, '?');
+  EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
+  ASSERT_EQ(encapsulated_length_, 0u);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_linux_socket_utils.cc b/quiche/quic/core/quic_linux_socket_utils.cc
new file mode 100644
index 0000000..c28cf21
--- /dev/null
+++ b/quiche/quic/core/quic_linux_socket_utils.cc
@@ -0,0 +1,315 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+
+#include <linux/net_tstamp.h>
+#include <netinet/in.h>
+#include <cstdint>
+
+#include "quiche/quic/core/quic_syscall_wrapper.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+QuicMsgHdr::QuicMsgHdr(const char* buffer,
+                       size_t buf_len,
+                       const QuicSocketAddress& peer_address,
+                       char* cbuf,
+                       size_t cbuf_size)
+    : iov_{const_cast<char*>(buffer), buf_len},
+      cbuf_(cbuf),
+      cbuf_size_(cbuf_size),
+      cmsg_(nullptr) {
+  // Only support unconnected sockets.
+  QUICHE_DCHECK(peer_address.IsInitialized());
+
+  raw_peer_address_ = peer_address.generic_address();
+  hdr_.msg_name = &raw_peer_address_;
+  hdr_.msg_namelen = raw_peer_address_.ss_family == AF_INET
+                         ? sizeof(sockaddr_in)
+                         : sizeof(sockaddr_in6);
+
+  hdr_.msg_iov = &iov_;
+  hdr_.msg_iovlen = 1;
+  hdr_.msg_flags = 0;
+
+  hdr_.msg_control = nullptr;
+  hdr_.msg_controllen = 0;
+}
+
+void QuicMsgHdr::SetIpInNextCmsg(const QuicIpAddress& self_address) {
+  if (!self_address.IsInitialized()) {
+    return;
+  }
+
+  if (self_address.IsIPv4()) {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address, GetNextCmsgData<in_pktinfo>(IPPROTO_IP, IP_PKTINFO));
+  } else {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address, GetNextCmsgData<in6_pktinfo>(IPPROTO_IPV6, IPV6_PKTINFO));
+  }
+}
+
+void* QuicMsgHdr::GetNextCmsgDataInternal(int cmsg_level,
+                                          int cmsg_type,
+                                          size_t data_size) {
+  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+  // return nullptr.
+  hdr_.msg_controllen += CMSG_SPACE(data_size);
+  QUICHE_DCHECK_LE(hdr_.msg_controllen, cbuf_size_);
+
+  if (cmsg_ == nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, hdr_.msg_control);
+    memset(cbuf_, 0, cbuf_size_);
+    hdr_.msg_control = cbuf_;
+    cmsg_ = CMSG_FIRSTHDR(&hdr_);
+  } else {
+    QUICHE_DCHECK_NE(nullptr, hdr_.msg_control);
+    cmsg_ = CMSG_NXTHDR(&hdr_, cmsg_);
+  }
+
+  QUICHE_DCHECK_NE(nullptr, cmsg_) << "Insufficient control buffer space";
+
+  cmsg_->cmsg_len = CMSG_LEN(data_size);
+  cmsg_->cmsg_level = cmsg_level;
+  cmsg_->cmsg_type = cmsg_type;
+
+  return CMSG_DATA(cmsg_);
+}
+
+void QuicMMsgHdr::InitOneHeader(int i, const BufferedWrite& buffered_write) {
+  mmsghdr* mhdr = GetMMsgHdr(i);
+  msghdr* hdr = &mhdr->msg_hdr;
+  iovec* iov = GetIov(i);
+
+  iov->iov_base = const_cast<char*>(buffered_write.buffer);
+  iov->iov_len = buffered_write.buf_len;
+  hdr->msg_iov = iov;
+  hdr->msg_iovlen = 1;
+  hdr->msg_control = nullptr;
+  hdr->msg_controllen = 0;
+
+  // Only support unconnected sockets.
+  QUICHE_DCHECK(buffered_write.peer_address.IsInitialized());
+
+  sockaddr_storage* peer_address_storage = GetPeerAddressStorage(i);
+  *peer_address_storage = buffered_write.peer_address.generic_address();
+  hdr->msg_name = peer_address_storage;
+  hdr->msg_namelen = peer_address_storage->ss_family == AF_INET
+                         ? sizeof(sockaddr_in)
+                         : sizeof(sockaddr_in6);
+}
+
+void QuicMMsgHdr::SetIpInNextCmsg(int i, const QuicIpAddress& self_address) {
+  if (!self_address.IsInitialized()) {
+    return;
+  }
+
+  if (self_address.IsIPv4()) {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address, GetNextCmsgData<in_pktinfo>(i, IPPROTO_IP, IP_PKTINFO));
+  } else {
+    QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+        self_address,
+        GetNextCmsgData<in6_pktinfo>(i, IPPROTO_IPV6, IPV6_PKTINFO));
+  }
+}
+
+void* QuicMMsgHdr::GetNextCmsgDataInternal(int i,
+                                           int cmsg_level,
+                                           int cmsg_type,
+                                           size_t data_size) {
+  mmsghdr* mhdr = GetMMsgHdr(i);
+  msghdr* hdr = &mhdr->msg_hdr;
+  cmsghdr*& cmsg = *GetCmsgHdr(i);
+
+  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+  // return nullptr.
+  hdr->msg_controllen += CMSG_SPACE(data_size);
+  QUICHE_DCHECK_LE(hdr->msg_controllen, cbuf_size_);
+
+  if (cmsg == nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
+    hdr->msg_control = GetCbuf(i);
+    cmsg = CMSG_FIRSTHDR(hdr);
+  } else {
+    QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
+    cmsg = CMSG_NXTHDR(hdr, cmsg);
+  }
+
+  QUICHE_DCHECK_NE(nullptr, cmsg) << "Insufficient control buffer space";
+
+  cmsg->cmsg_len = CMSG_LEN(data_size);
+  cmsg->cmsg_level = cmsg_level;
+  cmsg->cmsg_type = cmsg_type;
+
+  return CMSG_DATA(cmsg);
+}
+
+int QuicMMsgHdr::num_bytes_sent(int num_packets_sent) {
+  QUICHE_DCHECK_LE(0, num_packets_sent);
+  QUICHE_DCHECK_LE(num_packets_sent, num_msgs_);
+
+  int bytes_sent = 0;
+  iovec* iov = GetIov(0);
+  for (int i = 0; i < num_packets_sent; ++i) {
+    bytes_sent += iov[i].iov_len;
+  }
+  return bytes_sent;
+}
+
+// static
+int QuicLinuxSocketUtils::GetUDPSegmentSize(int fd) {
+  int optval;
+  socklen_t optlen = sizeof(optval);
+  int rc = getsockopt(fd, SOL_UDP, UDP_SEGMENT, &optval, &optlen);
+  if (rc < 0) {
+    QUIC_LOG_EVERY_N_SEC(INFO, 10)
+        << "getsockopt(UDP_SEGMENT) failed: " << strerror(errno);
+    return -1;
+  }
+  QUIC_LOG_EVERY_N_SEC(INFO, 10)
+      << "getsockopt(UDP_SEGMENT) returned segment size: " << optval;
+  return optval;
+}
+
+// static
+bool QuicLinuxSocketUtils::EnableReleaseTime(int fd, clockid_t clockid) {
+  // TODO(wub): Change to sock_txtime once it is available in linux/net_tstamp.h
+  struct LinuxSockTxTime {
+    clockid_t clockid; /* reference clockid */
+    uint32_t flags;    /* flags defined by enum txtime_flags */
+  };
+
+  LinuxSockTxTime so_txtime_val{clockid, 0};
+
+  if (setsockopt(fd, SOL_SOCKET, SO_TXTIME, &so_txtime_val,
+                 sizeof(so_txtime_val)) != 0) {
+    QUIC_LOG_EVERY_N_SEC(INFO, 10)
+        << "setsockopt(SOL_SOCKET,SO_TXTIME) failed: " << strerror(errno);
+    return false;
+  }
+
+  return true;
+}
+
+// static
+bool QuicLinuxSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) {
+  if (hdr->msg_controllen > 0) {
+    struct cmsghdr* cmsg;
+    for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
+         cmsg = CMSG_NXTHDR(hdr, cmsg)) {
+      if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
+          (cmsg->cmsg_level == IPPROTO_IPV6 &&
+           cmsg->cmsg_type == IPV6_HOPLIMIT)) {
+        *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+// static
+void QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+    const QuicIpAddress& self_address,
+    void* cmsg_data) {
+  QUICHE_DCHECK(self_address.IsInitialized());
+  const std::string& address_str = self_address.ToPackedString();
+  if (self_address.IsIPv4()) {
+    in_pktinfo* pktinfo = static_cast<in_pktinfo*>(cmsg_data);
+    pktinfo->ipi_ifindex = 0;
+    memcpy(&pktinfo->ipi_spec_dst, address_str.c_str(), address_str.length());
+  } else if (self_address.IsIPv6()) {
+    in6_pktinfo* pktinfo = static_cast<in6_pktinfo*>(cmsg_data);
+    memcpy(&pktinfo->ipi6_addr, address_str.c_str(), address_str.length());
+  } else {
+    QUIC_BUG(quic_bug_10598_1) << "Unrecognized IPAddress";
+  }
+}
+
+// static
+size_t QuicLinuxSocketUtils::SetIpInfoInCmsg(const QuicIpAddress& self_address,
+                                             cmsghdr* cmsg) {
+  std::string address_string;
+  if (self_address.IsIPv4()) {
+    cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
+    cmsg->cmsg_level = IPPROTO_IP;
+    cmsg->cmsg_type = IP_PKTINFO;
+    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+    memset(pktinfo, 0, sizeof(in_pktinfo));
+    pktinfo->ipi_ifindex = 0;
+    address_string = self_address.ToPackedString();
+    memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
+           address_string.length());
+    return sizeof(in_pktinfo);
+  } else if (self_address.IsIPv6()) {
+    cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
+    cmsg->cmsg_level = IPPROTO_IPV6;
+    cmsg->cmsg_type = IPV6_PKTINFO;
+    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+    memset(pktinfo, 0, sizeof(in6_pktinfo));
+    address_string = self_address.ToPackedString();
+    memcpy(&pktinfo->ipi6_addr, address_string.c_str(),
+           address_string.length());
+    return sizeof(in6_pktinfo);
+  } else {
+    QUIC_BUG(quic_bug_10598_2) << "Unrecognized IPAddress";
+    return 0;
+  }
+}
+
+// static
+WriteResult QuicLinuxSocketUtils::WritePacket(int fd, const QuicMsgHdr& hdr) {
+  int rc;
+  do {
+    rc = GetGlobalSyscallWrapper()->Sendmsg(fd, hdr.hdr(), 0);
+  } while (rc < 0 && errno == EINTR);
+  if (rc >= 0) {
+    return WriteResult(WRITE_STATUS_OK, rc);
+  }
+  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+                         ? WRITE_STATUS_BLOCKED
+                         : WRITE_STATUS_ERROR,
+                     errno);
+}
+
+// static
+WriteResult QuicLinuxSocketUtils::WriteMultiplePackets(int fd,
+                                                       QuicMMsgHdr* mhdr,
+                                                       int* num_packets_sent) {
+  *num_packets_sent = 0;
+
+  if (mhdr->num_msgs() <= 0) {
+    return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+  }
+
+  int rc;
+  do {
+    rc = GetGlobalSyscallWrapper()->Sendmmsg(fd, mhdr->mhdr(), mhdr->num_msgs(),
+                                             0);
+  } while (rc < 0 && errno == EINTR);
+
+  if (rc > 0) {
+    *num_packets_sent = rc;
+
+    return WriteResult(WRITE_STATUS_OK, mhdr->num_bytes_sent(rc));
+  } else if (rc == 0) {
+    QUIC_BUG(quic_bug_10598_3)
+        << "sendmmsg returned 0, returning WRITE_STATUS_ERROR. errno: "
+        << errno;
+    errno = EIO;
+  }
+
+  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+                         ? WRITE_STATUS_BLOCKED
+                         : WRITE_STATUS_ERROR,
+                     errno);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_linux_socket_utils.h b/quiche/quic/core/quic_linux_socket_utils.h
new file mode 100644
index 0000000..7203a17
--- /dev/null
+++ b/quiche/quic/core/quic_linux_socket_utils.h
@@ -0,0 +1,297 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <deque>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+#ifndef SOL_UDP
+#define SOL_UDP 17
+#endif
+
+#ifndef UDP_SEGMENT
+#define UDP_SEGMENT 103
+#endif
+
+#ifndef UDP_MAX_SEGMENTS
+#define UDP_MAX_SEGMENTS (1 << 6UL)
+#endif
+
+#ifndef SO_TXTIME
+#define SO_TXTIME 61
+#endif
+
+namespace quic {
+
+const int kCmsgSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
+const int kCmsgSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
+// kCmsgSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
+const int kCmsgSpaceForIp = (kCmsgSpaceForIpv4 < kCmsgSpaceForIpv6)
+                                ? kCmsgSpaceForIpv6
+                                : kCmsgSpaceForIpv4;
+
+const int kCmsgSpaceForSegmentSize = CMSG_SPACE(sizeof(uint16_t));
+
+const int kCmsgSpaceForTxTime = CMSG_SPACE(sizeof(uint64_t));
+
+const int kCmsgSpaceForTTL = CMSG_SPACE(sizeof(int));
+
+// QuicMsgHdr is used to build msghdr objects that can be used send packets via
+// ::sendmsg.
+//
+// Example:
+//   // cbuf holds control messages(cmsgs). The size is determined from what
+//   // cmsgs will be set for this msghdr.
+//   char cbuf[kCmsgSpaceForIp + kCmsgSpaceForSegmentSize];
+//   QuicMsgHdr hdr(packet_buf, packet_buf_len, peer_addr, cbuf, sizeof(cbuf));
+//
+//   // Set IP in cmsgs.
+//   hdr.SetIpInNextCmsg(self_addr);
+//
+//   // Set GSO size in cmsgs.
+//   *hdr.GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = 1200;
+//
+//   QuicLinuxSocketUtils::WritePacket(fd, hdr);
+class QUIC_EXPORT_PRIVATE QuicMsgHdr {
+ public:
+  QuicMsgHdr(const char* buffer,
+             size_t buf_len,
+             const QuicSocketAddress& peer_address,
+             char* cbuf,
+             size_t cbuf_size);
+
+  // Set IP info in the next cmsg. Both IPv4 and IPv6 are supported.
+  void SetIpInNextCmsg(const QuicIpAddress& self_address);
+
+  template <typename DataType>
+  DataType* GetNextCmsgData(int cmsg_level, int cmsg_type) {
+    return reinterpret_cast<DataType*>(
+        GetNextCmsgDataInternal(cmsg_level, cmsg_type, sizeof(DataType)));
+  }
+
+  const msghdr* hdr() const { return &hdr_; }
+
+ protected:
+  void* GetNextCmsgDataInternal(int cmsg_level,
+                                int cmsg_type,
+                                size_t data_size);
+
+  msghdr hdr_;
+  iovec iov_;
+  sockaddr_storage raw_peer_address_;
+  char* cbuf_;
+  const size_t cbuf_size_;
+  // The last cmsg populated so far. nullptr means nothing has been populated.
+  cmsghdr* cmsg_;
+};
+
+// BufferedWrite holds all information needed to send a packet.
+struct QUIC_EXPORT_PRIVATE BufferedWrite {
+  BufferedWrite(const char* buffer,
+                size_t buf_len,
+                const QuicIpAddress& self_address,
+                const QuicSocketAddress& peer_address)
+      : BufferedWrite(buffer,
+                      buf_len,
+                      self_address,
+                      peer_address,
+                      std::unique_ptr<PerPacketOptions>(),
+                      /*release_time=*/0) {}
+
+  BufferedWrite(const char* buffer,
+                size_t buf_len,
+                const QuicIpAddress& self_address,
+                const QuicSocketAddress& peer_address,
+                std::unique_ptr<PerPacketOptions> options,
+                uint64_t release_time)
+      : buffer(buffer),
+        buf_len(buf_len),
+        self_address(self_address),
+        peer_address(peer_address),
+        options(std::move(options)),
+        release_time(release_time) {}
+
+  const char* buffer;  // Not owned.
+  size_t buf_len;
+  QuicIpAddress self_address;
+  QuicSocketAddress peer_address;
+  std::unique_ptr<PerPacketOptions> options;
+
+  // The release time according to the owning packet writer's clock, which is
+  // often not a QuicClock. Calculated from packet writer's Now() and the
+  // release time delay in |options|.
+  // 0 means it can be sent at the same time as the previous packet in a batch,
+  // or can be sent Now() if this is the first packet of a batch.
+  uint64_t release_time;
+};
+
+// QuicMMsgHdr is used to build mmsghdr objects that can be used to send
+// multiple packets at once via ::sendmmsg.
+//
+// Example:
+//   quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+//   ... (Populate buffered_writes) ...
+//
+//   QuicMMsgHdr mhdr(
+//       buffered_writes.begin(), buffered_writes.end(), kCmsgSpaceForIp,
+//       [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+//         mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+//       });
+//
+//   int num_packets_sent;
+//   QuicSocketUtils::WriteMultiplePackets(fd, &mhdr, &num_packets_sent);
+class QUIC_EXPORT_PRIVATE QuicMMsgHdr {
+ public:
+  using ControlBufferInitializer = std::function<
+      void(QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)>;
+  template <typename IteratorT>
+  QuicMMsgHdr(const IteratorT& first,
+              const IteratorT& last,
+              size_t cbuf_size,
+              ControlBufferInitializer cbuf_initializer)
+      : num_msgs_(std::distance(first, last)), cbuf_size_(cbuf_size) {
+    static_assert(
+        std::is_same<typename std::iterator_traits<IteratorT>::value_type,
+                     BufferedWrite>::value,
+        "Must iterate over a collection of BufferedWrite.");
+
+    QUICHE_DCHECK_LE(0, num_msgs_);
+    if (num_msgs_ == 0) {
+      return;
+    }
+
+    storage_.reset(new char[StorageSize()]);
+    memset(&storage_[0], 0, StorageSize());
+
+    int i = -1;
+    for (auto it = first; it != last; ++it) {
+      ++i;
+
+      InitOneHeader(i, *it);
+      if (cbuf_initializer) {
+        cbuf_initializer(this, i, *it);
+      }
+    }
+  }
+
+  void SetIpInNextCmsg(int i, const QuicIpAddress& self_address);
+
+  template <typename DataType>
+  DataType* GetNextCmsgData(int i, int cmsg_level, int cmsg_type) {
+    return reinterpret_cast<DataType*>(
+        GetNextCmsgDataInternal(i, cmsg_level, cmsg_type, sizeof(DataType)));
+  }
+
+  mmsghdr* mhdr() { return GetMMsgHdr(0); }
+
+  int num_msgs() const { return num_msgs_; }
+
+  // Get the total number of bytes in the first |num_packets_sent| packets.
+  int num_bytes_sent(int num_packets_sent);
+
+ protected:
+  void InitOneHeader(int i, const BufferedWrite& buffered_write);
+
+  void* GetNextCmsgDataInternal(int i,
+                                int cmsg_level,
+                                int cmsg_type,
+                                size_t data_size);
+
+  size_t StorageSize() const {
+    return num_msgs_ *
+           (sizeof(mmsghdr) + sizeof(iovec) + sizeof(sockaddr_storage) +
+            sizeof(cmsghdr*) + cbuf_size_);
+  }
+
+  mmsghdr* GetMMsgHdr(int i) {
+    auto* first = reinterpret_cast<mmsghdr*>(&storage_[0]);
+    return &first[i];
+  }
+
+  iovec* GetIov(int i) {
+    auto* first = reinterpret_cast<iovec*>(GetMMsgHdr(num_msgs_));
+    return &first[i];
+  }
+
+  sockaddr_storage* GetPeerAddressStorage(int i) {
+    auto* first = reinterpret_cast<sockaddr_storage*>(GetIov(num_msgs_));
+    return &first[i];
+  }
+
+  cmsghdr** GetCmsgHdr(int i) {
+    auto* first = reinterpret_cast<cmsghdr**>(GetPeerAddressStorage(num_msgs_));
+    return &first[i];
+  }
+
+  char* GetCbuf(int i) {
+    auto* first = reinterpret_cast<char*>(GetCmsgHdr(num_msgs_));
+    return &first[i * cbuf_size_];
+  }
+
+  const int num_msgs_;
+  // Size of cmsg buffer for each message.
+  const size_t cbuf_size_;
+  // storage_ holds the memory of
+  // |num_msgs_| mmsghdr
+  // |num_msgs_| iovec
+  // |num_msgs_| sockaddr_storage, for peer addresses
+  // |num_msgs_| cmsghdr*
+  // |num_msgs_| cbuf, each of size cbuf_size
+  std::unique_ptr<char[]> storage_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicLinuxSocketUtils {
+ public:
+  // Return the UDP segment size of |fd|, 0 means segment size has not been set
+  // on this socket. If GSO is not supported, return -1.
+  static int GetUDPSegmentSize(int fd);
+
+  // Enable release time on |fd|.
+  static bool EnableReleaseTime(int fd, clockid_t clockid);
+
+  // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
+  // value and return true. Otherwise it will return false.
+  static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);
+
+  // Set IP(self_address) in |cmsg_data|. Does not touch other fields in the
+  // containing cmsghdr.
+  static void SetIpInfoInCmsgData(const QuicIpAddress& self_address,
+                                  void* cmsg_data);
+
+  // A helper for WritePacket which fills in the cmsg with the supplied self
+  // address.
+  // Returns the length of the packet info structure used.
+  static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
+                                cmsghdr* cmsg);
+
+  // Writes the packet in |hdr| to the socket, using ::sendmsg.
+  static WriteResult WritePacket(int fd, const QuicMsgHdr& hdr);
+
+  // Writes the packets in |mhdr| to the socket, using ::sendmmsg if available.
+  static WriteResult WriteMultiplePackets(int fd,
+                                          QuicMMsgHdr* mhdr,
+                                          int* num_packets_sent);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
diff --git a/quiche/quic/core/quic_linux_socket_utils_test.cc b/quiche/quic/core/quic_linux_socket_utils_test.cc
new file mode 100644
index 0000000..5ae2fde
--- /dev/null
+++ b/quiche/quic/core/quic_linux_socket_utils_test.cc
@@ -0,0 +1,329 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_linux_socket_utils.h"
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <cstddef>
+#include <sstream>
+#include <vector>
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_mock_syscall_wrapper.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicLinuxSocketUtilsTest : public QuicTest {
+ protected:
+  WriteResult TestWriteMultiplePackets(
+      int fd,
+      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& first,
+      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& last,
+      int* num_packets_sent) {
+    QuicMMsgHdr mhdr(
+        first, last, kCmsgSpaceForIp,
+        [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+          mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+        });
+
+    WriteResult res =
+        QuicLinuxSocketUtils::WriteMultiplePackets(fd, &mhdr, num_packets_sent);
+    return res;
+  }
+
+  MockQuicSyscallWrapper mock_syscalls_;
+  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
+};
+
+void CheckIpAndTtlInCbuf(msghdr* hdr,
+                         const void* cbuf,
+                         const QuicIpAddress& self_addr,
+                         int ttl) {
+  const bool is_ipv4 = self_addr.IsIPv4();
+  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+
+  EXPECT_EQ(cbuf, hdr->msg_control);
+  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
+
+  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
+  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
+                                    : CMSG_LEN(sizeof(in6_pktinfo)));
+  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
+
+  const std::string& self_addr_str = self_addr.ToPackedString();
+  if (is_ipv4) {
+    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  } else {
+    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  }
+
+  cmsg = CMSG_NXTHDR(hdr, cmsg);
+  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
+  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_TTL : IPV6_HOPLIMIT);
+  EXPECT_EQ(ttl, *reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+
+  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
+}
+
+void CheckMsghdrWithoutCbuf(const msghdr* hdr,
+                            const void* buffer,
+                            size_t buf_len,
+                            const QuicSocketAddress& peer_addr) {
+  EXPECT_EQ(
+      peer_addr.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
+      hdr->msg_namelen);
+  sockaddr_storage peer_generic_addr = peer_addr.generic_address();
+  EXPECT_EQ(0, memcmp(hdr->msg_name, &peer_generic_addr, hdr->msg_namelen));
+  EXPECT_EQ(1u, hdr->msg_iovlen);
+  EXPECT_EQ(buffer, hdr->msg_iov->iov_base);
+  EXPECT_EQ(buf_len, hdr->msg_iov->iov_len);
+  EXPECT_EQ(0, hdr->msg_flags);
+  EXPECT_EQ(nullptr, hdr->msg_control);
+  EXPECT_EQ(0u, hdr->msg_controllen);
+}
+
+void CheckIpAndGsoSizeInCbuf(msghdr* hdr,
+                             const void* cbuf,
+                             const QuicIpAddress& self_addr,
+                             uint16_t gso_size) {
+  const bool is_ipv4 = self_addr.IsIPv4();
+  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+
+  EXPECT_EQ(cbuf, hdr->msg_control);
+  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
+
+  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
+  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
+                                    : CMSG_LEN(sizeof(in6_pktinfo)));
+  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
+
+  const std::string& self_addr_str = self_addr.ToPackedString();
+  if (is_ipv4) {
+    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  } else {
+    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
+                        self_addr_str.length()));
+  }
+
+  cmsg = CMSG_NXTHDR(hdr, cmsg);
+  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(uint16_t)));
+  EXPECT_EQ(cmsg->cmsg_level, SOL_UDP);
+  EXPECT_EQ(cmsg->cmsg_type, UDP_SEGMENT);
+  EXPECT_EQ(gso_size, *reinterpret_cast<uint16_t*>(CMSG_DATA(cmsg)));
+
+  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, QuicMsgHdr) {
+  QuicSocketAddress peer_addr(QuicIpAddress::Loopback4(), 1234);
+  char packet_buf[1024];
+
+  QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, nullptr, 0);
+  CheckMsghdrWithoutCbuf(quic_hdr.hdr(), packet_buf, sizeof(packet_buf),
+                         peer_addr);
+
+  for (bool is_ipv4 : {true, false}) {
+    QuicIpAddress self_addr =
+        is_ipv4 ? QuicIpAddress::Loopback4() : QuicIpAddress::Loopback6();
+    char cbuf[kCmsgSpaceForIp + kCmsgSpaceForTTL];
+    QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, cbuf,
+                        sizeof(cbuf));
+    msghdr* hdr = const_cast<msghdr*>(quic_hdr.hdr());
+
+    EXPECT_EQ(nullptr, hdr->msg_control);
+    EXPECT_EQ(0u, hdr->msg_controllen);
+
+    quic_hdr.SetIpInNextCmsg(self_addr);
+    EXPECT_EQ(cbuf, hdr->msg_control);
+    const size_t ip_cmsg_space =
+        is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+    EXPECT_EQ(ip_cmsg_space, hdr->msg_controllen);
+
+    if (is_ipv4) {
+      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IP, IP_TTL) = 32;
+    } else {
+      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IPV6, IPV6_HOPLIMIT) = 32;
+    }
+
+    CheckIpAndTtlInCbuf(hdr, cbuf, self_addr, 32);
+  }
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, QuicMMsgHdr) {
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  char packet_buf1[1024];
+  char packet_buf2[512];
+  buffered_writes.emplace_back(
+      packet_buf1, sizeof(packet_buf1), QuicIpAddress::Loopback4(),
+      QuicSocketAddress(QuicIpAddress::Loopback4(), 4));
+  buffered_writes.emplace_back(
+      packet_buf2, sizeof(packet_buf2), QuicIpAddress::Loopback6(),
+      QuicSocketAddress(QuicIpAddress::Loopback6(), 6));
+
+  QuicMMsgHdr quic_mhdr_without_cbuf(buffered_writes.begin(),
+                                     buffered_writes.end(), 0, nullptr);
+  for (size_t i = 0; i < buffered_writes.size(); ++i) {
+    const BufferedWrite& bw = buffered_writes[i];
+    CheckMsghdrWithoutCbuf(&quic_mhdr_without_cbuf.mhdr()[i].msg_hdr, bw.buffer,
+                           bw.buf_len, bw.peer_address);
+  }
+
+  QuicMMsgHdr quic_mhdr_with_cbuf(
+      buffered_writes.begin(), buffered_writes.end(),
+      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize,
+      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+        *mhdr->GetNextCmsgData<uint16_t>(i, SOL_UDP, UDP_SEGMENT) = 1300;
+      });
+  for (size_t i = 0; i < buffered_writes.size(); ++i) {
+    const BufferedWrite& bw = buffered_writes[i];
+    msghdr* hdr = &quic_mhdr_with_cbuf.mhdr()[i].msg_hdr;
+    CheckIpAndGsoSizeInCbuf(hdr, hdr->msg_control, bw.self_address, 1300);
+  }
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_NoPacketsToSend) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+
+  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _)).Times(0);
+
+  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL),
+            TestWriteMultiplePackets(1, buffered_writes.begin(),
+                                     buffered_writes.end(), &num_packets_sent));
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteBlocked) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
+                               QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
+                          unsigned int /*vlen*/, int /*flags*/) {
+        errno = EWOULDBLOCK;
+        return -1;
+      }));
+
+  EXPECT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
+            TestWriteMultiplePackets(1, buffered_writes.begin(),
+                                     buffered_writes.end(), &num_packets_sent));
+  EXPECT_EQ(0, num_packets_sent);
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteError) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
+                               QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
+                          unsigned int /*vlen*/, int /*flags*/) {
+        errno = EPERM;
+        return -1;
+      }));
+
+  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM),
+            TestWriteMultiplePackets(1, buffered_writes.begin(),
+                                     buffered_writes.end(), &num_packets_sent));
+  EXPECT_EQ(0, num_packets_sent);
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteSuccess) {
+  int num_packets_sent;
+  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
+  const int kNumBufferedWrites = 10;
+  static_assert(kNumBufferedWrites < 256, "Must be less than 256");
+  std::vector<std::string> buffer_holder;
+  for (int i = 0; i < kNumBufferedWrites; ++i) {
+    size_t buf_len = (i + 1) * 2;
+    std::ostringstream buffer_ostream;
+    while (buffer_ostream.str().length() < buf_len) {
+      buffer_ostream << i;
+    }
+    buffer_holder.push_back(buffer_ostream.str().substr(0, buf_len - 1) + '$');
+
+    buffered_writes.emplace_back(buffer_holder.back().data(), buf_len,
+                                 QuicIpAddress(),
+                                 QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+    // Leave the first self_address uninitialized.
+    if (i != 0) {
+      ASSERT_TRUE(buffered_writes.back().self_address.FromString("127.0.0.1"));
+    }
+
+    std::ostringstream peer_ip_ostream;
+    QuicIpAddress peer_ip_address;
+    peer_ip_ostream << "127.0.1." << i + 1;
+    ASSERT_TRUE(peer_ip_address.FromString(peer_ip_ostream.str()));
+    buffered_writes.back().peer_address =
+        QuicSocketAddress(peer_ip_address, i + 1);
+  }
+
+  InSequence s;
+
+  for (int expected_num_packets_sent : {1, 2, 3, 10}) {
+    SCOPED_TRACE(testing::Message()
+                 << "expected_num_packets_sent=" << expected_num_packets_sent);
+    EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+        .WillOnce(Invoke(
+            [&](int /*fd*/, mmsghdr* msgvec, unsigned int vlen, int /*flags*/) {
+              EXPECT_LE(static_cast<unsigned int>(expected_num_packets_sent),
+                        vlen);
+              for (unsigned int i = 0; i < vlen; ++i) {
+                const BufferedWrite& buffered_write = buffered_writes[i];
+                const msghdr& hdr = msgvec[i].msg_hdr;
+                EXPECT_EQ(1u, hdr.msg_iovlen);
+                EXPECT_EQ(buffered_write.buffer, hdr.msg_iov->iov_base);
+                EXPECT_EQ(buffered_write.buf_len, hdr.msg_iov->iov_len);
+                sockaddr_storage expected_peer_address =
+                    buffered_write.peer_address.generic_address();
+                EXPECT_EQ(0, memcmp(&expected_peer_address, hdr.msg_name,
+                                    sizeof(sockaddr_storage)));
+                EXPECT_EQ(buffered_write.self_address.IsInitialized(),
+                          hdr.msg_control != nullptr);
+              }
+              return expected_num_packets_sent;
+            }))
+        .RetiresOnSaturation();
+
+    int expected_bytes_written = 0;
+    for (auto it = buffered_writes.cbegin();
+         it != buffered_writes.cbegin() + expected_num_packets_sent; ++it) {
+      expected_bytes_written += it->buf_len;
+    }
+
+    EXPECT_EQ(
+        WriteResult(WRITE_STATUS_OK, expected_bytes_written),
+        TestWriteMultiplePackets(1, buffered_writes.cbegin(),
+                                 buffered_writes.cend(), &num_packets_sent));
+    EXPECT_EQ(expected_num_packets_sent, num_packets_sent);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_lru_cache.h b/quiche/quic/core/quic_lru_cache.h
new file mode 100644
index 0000000..d1c010e
--- /dev/null
+++ b/quiche/quic/core/quic_lru_cache.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
+#define QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
+
+#include <memory>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+// A LRU cache that maps from type Key to Value* in QUIC.
+// This cache CANNOT be shared by multiple threads (even with locks) because
+// Value* returned by Lookup() can be invalid if the entry is evicted by other
+// threads.
+template <class K, class V, class Hash = std::hash<K>,
+          class Eq = std::equal_to<K>>
+class QUIC_NO_EXPORT QuicLRUCache {
+ private:
+  using HashMapType =
+      typename quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq>;
+
+ public:
+  // The iterator, if valid, points to std::pair<K, std::unique_ptr<V>>.
+  using iterator = typename HashMapType::iterator;
+  using const_iterator = typename HashMapType::const_iterator;
+  using reverse_iterator = typename HashMapType::reverse_iterator;
+  using const_reverse_iterator = typename HashMapType::const_reverse_iterator;
+
+  explicit QuicLRUCache(size_t capacity) : capacity_(capacity) {}
+  QuicLRUCache(const QuicLRUCache&) = delete;
+  QuicLRUCache& operator=(const QuicLRUCache&) = delete;
+
+  iterator begin() { return cache_.begin(); }
+  const_iterator begin() const { return cache_.begin(); }
+
+  iterator end() { return cache_.end(); }
+  const_iterator end() const { return cache_.end(); }
+
+  reverse_iterator rbegin() { return cache_.rbegin(); }
+  const_reverse_iterator rbegin() const { return cache_.rbegin(); }
+
+  reverse_iterator rend() { return cache_.rend(); }
+  const_reverse_iterator rend() const { return cache_.rend(); }
+
+  // Inserts one unit of |key|, |value| pair to the cache. Cache takes ownership
+  // of inserted |value|.
+  void Insert(const K& key, std::unique_ptr<V> value) {
+    auto it = cache_.find(key);
+    if (it != cache_.end()) {
+      cache_.erase(it);
+    }
+    cache_.emplace(key, std::move(value));
+
+    if (cache_.size() > capacity_) {
+      cache_.pop_front();
+    }
+    QUICHE_DCHECK_LE(cache_.size(), capacity_);
+  }
+
+  iterator Lookup(const K& key) {
+    auto iter = cache_.find(key);
+    if (iter == cache_.end()) {
+      return iter;
+    }
+
+    std::unique_ptr<V> value = std::move(iter->second);
+    cache_.erase(iter);
+    auto result = cache_.emplace(key, std::move(value));
+    QUICHE_DCHECK(result.second);
+    return result.first;
+  }
+
+  iterator Erase(iterator iter) { return cache_.erase(iter); }
+
+  // Removes all entries from the cache.
+  void Clear() { cache_.clear(); }
+
+  // Returns maximum size of the cache.
+  size_t MaxSize() const { return capacity_; }
+
+  // Returns current size of the cache.
+  size_t Size() const { return cache_.size(); }
+
+ private:
+  quiche::QuicheLinkedHashMap<K, std::unique_ptr<V>, Hash, Eq> cache_;
+  const size_t capacity_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_LRU_CACHE_H_
diff --git a/quiche/quic/core/quic_lru_cache_test.cc b/quiche/quic/core/quic_lru_cache_test.cc
new file mode 100644
index 0000000..91a7913
--- /dev/null
+++ b/quiche/quic/core/quic_lru_cache_test.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_lru_cache.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct CachedItem {
+  explicit CachedItem(uint32_t new_value) : value(new_value) {}
+
+  uint32_t value;
+};
+
+TEST(QuicLRUCacheTest, InsertAndLookup) {
+  QuicLRUCache<int, CachedItem> cache(5);
+  EXPECT_EQ(cache.end(), cache.Lookup(1));
+  EXPECT_EQ(0u, cache.Size());
+  EXPECT_EQ(5u, cache.MaxSize());
+
+  // Check that item 1 was properly inserted.
+  std::unique_ptr<CachedItem> item1(new CachedItem(11));
+  cache.Insert(1, std::move(item1));
+  EXPECT_EQ(1u, cache.Size());
+  EXPECT_EQ(11u, cache.Lookup(1)->second->value);
+
+  // Check that item 2 overrides item 1.
+  std::unique_ptr<CachedItem> item2(new CachedItem(12));
+  cache.Insert(1, std::move(item2));
+  EXPECT_EQ(1u, cache.Size());
+  EXPECT_EQ(12u, cache.Lookup(1)->second->value);
+
+  std::unique_ptr<CachedItem> item3(new CachedItem(13));
+  cache.Insert(3, std::move(item3));
+  EXPECT_EQ(2u, cache.Size());
+  auto iter = cache.Lookup(3);
+  ASSERT_NE(cache.end(), iter);
+  EXPECT_EQ(13u, iter->second->value);
+  cache.Erase(iter);
+  ASSERT_EQ(cache.end(), cache.Lookup(3));
+  EXPECT_EQ(1u, cache.Size());
+
+  // No memory leakage.
+  cache.Clear();
+  EXPECT_EQ(0u, cache.Size());
+}
+
+TEST(QuicLRUCacheTest, Eviction) {
+  QuicLRUCache<int, CachedItem> cache(3);
+
+  for (size_t i = 1; i <= 4; ++i) {
+    std::unique_ptr<CachedItem> item(new CachedItem(10 + i));
+    cache.Insert(i, std::move(item));
+  }
+
+  EXPECT_EQ(3u, cache.Size());
+  EXPECT_EQ(3u, cache.MaxSize());
+
+  // Make sure item 1 is evicted.
+  EXPECT_EQ(cache.end(), cache.Lookup(1));
+  EXPECT_EQ(14u, cache.Lookup(4)->second->value);
+
+  EXPECT_EQ(12u, cache.Lookup(2)->second->value);
+  std::unique_ptr<CachedItem> item5(new CachedItem(15));
+  cache.Insert(5, std::move(item5));
+  // Make sure item 3 is evicted.
+  EXPECT_EQ(cache.end(), cache.Lookup(3));
+  EXPECT_EQ(15u, cache.Lookup(5)->second->value);
+
+  // No memory leakage.
+  cache.Clear();
+  EXPECT_EQ(0u, cache.Size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_mtu_discovery.cc b/quiche/quic/core/quic_mtu_discovery.cc
new file mode 100644
index 0000000..95080f7
--- /dev/null
+++ b/quiche/quic/core/quic_mtu_discovery.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_mtu_discovery.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+QuicConnectionMtuDiscoverer::QuicConnectionMtuDiscoverer(
+    QuicPacketCount packets_between_probes_base,
+    QuicPacketNumber next_probe_at)
+    : packets_between_probes_(packets_between_probes_base),
+      next_probe_at_(next_probe_at) {}
+
+void QuicConnectionMtuDiscoverer::Enable(
+    QuicByteCount max_packet_length,
+    QuicByteCount target_max_packet_length) {
+  QUICHE_DCHECK(!IsEnabled());
+
+  if (target_max_packet_length <= max_packet_length) {
+    QUIC_DVLOG(1) << "MtuDiscoverer not enabled. target_max_packet_length:"
+                  << target_max_packet_length
+                  << " <= max_packet_length:" << max_packet_length;
+    return;
+  }
+
+  min_probe_length_ = max_packet_length;
+  max_probe_length_ = target_max_packet_length;
+  QUICHE_DCHECK(IsEnabled());
+
+  QUIC_DVLOG(1) << "MtuDiscoverer enabled. min:" << min_probe_length_
+                << ", max:" << max_probe_length_
+                << ", next:" << next_probe_packet_length();
+}
+
+void QuicConnectionMtuDiscoverer::Disable() {
+  *this = QuicConnectionMtuDiscoverer(packets_between_probes_, next_probe_at_);
+}
+
+bool QuicConnectionMtuDiscoverer::IsEnabled() const {
+  return min_probe_length_ < max_probe_length_;
+}
+
+bool QuicConnectionMtuDiscoverer::ShouldProbeMtu(
+    QuicPacketNumber largest_sent_packet) const {
+  if (!IsEnabled()) {
+    return false;
+  }
+
+  if (remaining_probe_count_ == 0) {
+    QUIC_DVLOG(1)
+        << "ShouldProbeMtu returns false because max probe count reached";
+    return false;
+  }
+
+  if (largest_sent_packet < next_probe_at_) {
+    QUIC_DVLOG(1) << "ShouldProbeMtu returns false because not enough packets "
+                     "sent since last probe. largest_sent_packet:"
+                  << largest_sent_packet
+                  << ", next_probe_at_:" << next_probe_at_;
+    return false;
+  }
+
+  QUIC_DVLOG(1) << "ShouldProbeMtu returns true. largest_sent_packet:"
+                << largest_sent_packet;
+  return true;
+}
+
+QuicPacketLength QuicConnectionMtuDiscoverer::GetUpdatedMtuProbeSize(
+    QuicPacketNumber largest_sent_packet) {
+  QUICHE_DCHECK(ShouldProbeMtu(largest_sent_packet));
+
+  QuicPacketLength probe_packet_length = next_probe_packet_length();
+  if (probe_packet_length == last_probe_length_) {
+    // The next probe packet is as big as the previous one. Assuming the
+    // previous one exceeded MTU, we need to decrease the probe packet length.
+    max_probe_length_ = probe_packet_length;
+  } else {
+    QUICHE_DCHECK_GT(probe_packet_length, last_probe_length_);
+  }
+  last_probe_length_ = next_probe_packet_length();
+
+  packets_between_probes_ *= 2;
+  next_probe_at_ = largest_sent_packet + packets_between_probes_ + 1;
+  if (remaining_probe_count_ > 0) {
+    --remaining_probe_count_;
+  }
+
+  QUIC_DVLOG(1) << "GetUpdatedMtuProbeSize: probe_packet_length:"
+                << last_probe_length_
+                << ", New packets_between_probes_:" << packets_between_probes_
+                << ", next_probe_at_:" << next_probe_at_
+                << ", remaining_probe_count_:" << remaining_probe_count_;
+  QUICHE_DCHECK(!ShouldProbeMtu(largest_sent_packet));
+  return last_probe_length_;
+}
+
+QuicPacketLength QuicConnectionMtuDiscoverer::next_probe_packet_length() const {
+  QUICHE_DCHECK_NE(min_probe_length_, 0);
+  QUICHE_DCHECK_NE(max_probe_length_, 0);
+  QUICHE_DCHECK_GE(max_probe_length_, min_probe_length_);
+
+  const QuicPacketLength normal_next_probe_length =
+      (min_probe_length_ + max_probe_length_ + 1) / 2;
+
+  if (remaining_probe_count_ == 1 &&
+      normal_next_probe_length > last_probe_length_) {
+    // If the previous probe succeeded, and there is only one last probe to
+    // send, use |max_probe_length_| for the last probe.
+    return max_probe_length_;
+  }
+  return normal_next_probe_length;
+}
+
+void QuicConnectionMtuDiscoverer::OnMaxPacketLengthUpdated(
+    QuicByteCount old_value,
+    QuicByteCount new_value) {
+  if (!IsEnabled() || new_value <= old_value) {
+    return;
+  }
+
+  QUICHE_DCHECK_EQ(old_value, min_probe_length_);
+  min_probe_length_ = new_value;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicConnectionMtuDiscoverer& d) {
+  os << "{ min_probe_length_:" << d.min_probe_length_
+     << " max_probe_length_:" << d.max_probe_length_
+     << " last_probe_length_:" << d.last_probe_length_
+     << " remaining_probe_count_:" << d.remaining_probe_count_
+     << " packets_between_probes_:" << d.packets_between_probes_
+     << " next_probe_at_:" << d.next_probe_at_ << " }";
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_mtu_discovery.h b/quiche/quic/core/quic_mtu_discovery.h
new file mode 100644
index 0000000..6175d6d
--- /dev/null
+++ b/quiche/quic/core/quic_mtu_discovery.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
+#define QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
+
+#include <iostream>
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+// The initial number of packets between MTU probes.  After each attempt the
+// number is doubled.
+const QuicPacketCount kPacketsBetweenMtuProbesBase = 100;
+
+// The number of MTU probes that get sent before giving up.
+const size_t kMtuDiscoveryAttempts = 3;
+
+// Ensure that exponential back-off does not result in an integer overflow.
+// The number of packets can be potentially capped, but that is not useful at
+// current kMtuDiscoveryAttempts value, and hence is not implemented at present.
+static_assert(kMtuDiscoveryAttempts + 8 < 8 * sizeof(QuicPacketNumber),
+              "The number of MTU discovery attempts is too high");
+static_assert(kPacketsBetweenMtuProbesBase < (1 << 8),
+              "The initial number of packets between MTU probes is too high");
+
+// The increased packet size targeted when doing path MTU discovery.
+const QuicByteCount kMtuDiscoveryTargetPacketSizeHigh = 1400;
+const QuicByteCount kMtuDiscoveryTargetPacketSizeLow = 1380;
+
+static_assert(kMtuDiscoveryTargetPacketSizeLow <= kMaxOutgoingPacketSize,
+              "MTU discovery target is too large");
+static_assert(kMtuDiscoveryTargetPacketSizeHigh <= kMaxOutgoingPacketSize,
+              "MTU discovery target is too large");
+
+static_assert(kMtuDiscoveryTargetPacketSizeLow > kDefaultMaxPacketSize,
+              "MTU discovery target does not exceed the default packet size");
+static_assert(kMtuDiscoveryTargetPacketSizeHigh > kDefaultMaxPacketSize,
+              "MTU discovery target does not exceed the default packet size");
+
+// QuicConnectionMtuDiscoverer is a MTU discovery controller, it answers two
+// questions:
+// 1) Probe scheduling: Whether a connection should send a MTU probe packet
+//    right now.
+// 2) MTU search stradegy: When it is time to send, what should be the size of
+//    the probing packet.
+// Note the discoverer does not actually send or process probing packets.
+//
+// Unit tests are in QuicConnectionTest.MtuDiscovery*.
+class QUIC_EXPORT_PRIVATE QuicConnectionMtuDiscoverer {
+ public:
+  // Construct a discoverer in the disabled state.
+  QuicConnectionMtuDiscoverer() = default;
+
+  // Construct a discoverer in the disabled state, with the given parameters.
+  QuicConnectionMtuDiscoverer(QuicPacketCount packets_between_probes_base,
+                              QuicPacketNumber next_probe_at);
+
+  // Enable the discoverer by setting the probe target.
+  // max_packet_length: The max packet length currently used.
+  // target_max_packet_length: The target max packet length to probe.
+  void Enable(QuicByteCount max_packet_length,
+              QuicByteCount target_max_packet_length);
+
+  // Disable the discoverer by unsetting the probe target.
+  void Disable();
+
+  // Whether a MTU probe packet should be sent right now.
+  // Always return false if disabled.
+  bool ShouldProbeMtu(QuicPacketNumber largest_sent_packet) const;
+
+  // Called immediately before a probing packet is sent, to get the size of the
+  // packet.
+  // REQUIRES: ShouldProbeMtu(largest_sent_packet) == true.
+  QuicPacketLength GetUpdatedMtuProbeSize(QuicPacketNumber largest_sent_packet);
+
+  // Called after the max packet length is updated, which is triggered by a ack
+  // of a probing packet.
+  void OnMaxPacketLengthUpdated(QuicByteCount old_value,
+                                QuicByteCount new_value);
+
+  QuicPacketCount packets_between_probes() const {
+    return packets_between_probes_;
+  }
+
+  QuicPacketNumber next_probe_at() const { return next_probe_at_; }
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConnectionMtuDiscoverer& d);
+
+ private:
+  bool IsEnabled() const;
+  QuicPacketLength next_probe_packet_length() const;
+
+  QuicPacketLength min_probe_length_ = 0;
+  QuicPacketLength max_probe_length_ = 0;
+
+  QuicPacketLength last_probe_length_ = 0;
+
+  uint16_t remaining_probe_count_ = kMtuDiscoveryAttempts;
+
+  // The number of packets between MTU probes.
+  QuicPacketCount packets_between_probes_ = kPacketsBetweenMtuProbesBase;
+
+  // The packet number of the packet after which the next MTU probe will be
+  // sent.
+  QuicPacketNumber next_probe_at_ =
+      QuicPacketNumber(kPacketsBetweenMtuProbesBase);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_MTU_DISCOVERY_H_
diff --git a/quiche/quic/core/quic_network_blackhole_detector.cc b/quiche/quic/core/quic_network_blackhole_detector.cc
new file mode 100644
index 0000000..da9262a
--- /dev/null
+++ b/quiche/quic/core/quic_network_blackhole_detector.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_network_blackhole_detector.h"
+
+#include "quiche/quic/core/quic_constants.h"
+
+namespace quic {
+
+namespace {
+
+class AlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit AlarmDelegate(QuicNetworkBlackholeDetector* detector,
+                         QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
+  AlarmDelegate(const AlarmDelegate&) = delete;
+  AlarmDelegate& operator=(const AlarmDelegate&) = delete;
+
+  void OnAlarm() override { detector_->OnAlarm(); }
+
+ private:
+  QuicNetworkBlackholeDetector* detector_;
+};
+
+}  // namespace
+
+QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(
+    Delegate* delegate, QuicConnectionArena* arena,
+    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
+    : delegate_(delegate),
+      alarm_(alarm_factory->CreateAlarm(
+          arena->New<AlarmDelegate>(this, context), arena)) {}
+
+void QuicNetworkBlackholeDetector::OnAlarm() {
+  QuicTime next_deadline = GetEarliestDeadline();
+  if (!next_deadline.IsInitialized()) {
+    QUIC_BUG(quic_bug_10328_1) << "BlackholeDetector alarm fired unexpectedly";
+    return;
+  }
+
+  QUIC_DVLOG(1) << "BlackholeDetector alarm firing. next_deadline:"
+                << next_deadline
+                << ", path_degrading_deadline_:" << path_degrading_deadline_
+                << ", path_mtu_reduction_deadline_:"
+                << path_mtu_reduction_deadline_
+                << ", blackhole_deadline_:" << blackhole_deadline_;
+  if (path_degrading_deadline_ == next_deadline) {
+    path_degrading_deadline_ = QuicTime::Zero();
+    delegate_->OnPathDegradingDetected();
+  }
+
+  if (path_mtu_reduction_deadline_ == next_deadline) {
+    path_mtu_reduction_deadline_ = QuicTime::Zero();
+    delegate_->OnPathMtuReductionDetected();
+  }
+
+  if (blackhole_deadline_ == next_deadline) {
+    blackhole_deadline_ = QuicTime::Zero();
+    delegate_->OnBlackholeDetected();
+  }
+
+  UpdateAlarm();
+}
+
+void QuicNetworkBlackholeDetector::StopDetection(bool permanent) {
+  if (permanent) {
+    alarm_->PermanentCancel();
+  } else {
+    alarm_->Cancel();
+  }
+  path_degrading_deadline_ = QuicTime::Zero();
+  blackhole_deadline_ = QuicTime::Zero();
+  path_mtu_reduction_deadline_ = QuicTime::Zero();
+}
+
+void QuicNetworkBlackholeDetector::RestartDetection(
+    QuicTime path_degrading_deadline,
+    QuicTime blackhole_deadline,
+    QuicTime path_mtu_reduction_deadline) {
+  path_degrading_deadline_ = path_degrading_deadline;
+  blackhole_deadline_ = blackhole_deadline;
+  path_mtu_reduction_deadline_ = path_mtu_reduction_deadline;
+
+  QUIC_BUG_IF(quic_bug_12708_1, blackhole_deadline_.IsInitialized() &&
+                                    blackhole_deadline_ != GetLastDeadline())
+      << "Blackhole detection deadline should be the last deadline.";
+
+  UpdateAlarm();
+}
+
+QuicTime QuicNetworkBlackholeDetector::GetEarliestDeadline() const {
+  QuicTime result = QuicTime::Zero();
+  for (QuicTime t : {path_degrading_deadline_, blackhole_deadline_,
+                     path_mtu_reduction_deadline_}) {
+    if (!t.IsInitialized()) {
+      continue;
+    }
+
+    if (!result.IsInitialized() || t < result) {
+      result = t;
+    }
+  }
+
+  return result;
+}
+
+QuicTime QuicNetworkBlackholeDetector::GetLastDeadline() const {
+  return std::max({path_degrading_deadline_, blackhole_deadline_,
+                   path_mtu_reduction_deadline_});
+}
+
+void QuicNetworkBlackholeDetector::UpdateAlarm() const {
+  // If called after OnBlackholeDetected(), the alarm may have been permanently
+  // cancelled and is not safe to be armed again.
+  if (alarm_->IsPermanentlyCancelled()) {
+    return;
+  }
+
+  QuicTime next_deadline = GetEarliestDeadline();
+
+  QUIC_DVLOG(1) << "Updating alarm. next_deadline:" << next_deadline
+                << ", path_degrading_deadline_:" << path_degrading_deadline_
+                << ", path_mtu_reduction_deadline_:"
+                << path_mtu_reduction_deadline_
+                << ", blackhole_deadline_:" << blackhole_deadline_;
+
+  alarm_->Update(next_deadline, kAlarmGranularity);
+}
+
+bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
+  return alarm_->IsSet();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_network_blackhole_detector.h b/quiche/quic/core/quic_network_blackhole_detector.h
new file mode 100644
index 0000000..7defc47
--- /dev/null
+++ b/quiche/quic/core/quic_network_blackhole_detector.h
@@ -0,0 +1,91 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
+#define QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicNetworkBlackholeDetectorPeer;
+}  // namespace test
+
+// QuicNetworkBlackholeDetector can detect path degrading and/or network
+// blackhole. If both detections are in progress, detector will be in path
+// degrading detection mode. After reporting path degrading detected, detector
+// switches to blackhole detection mode. So blackhole detection deadline must
+// be later than path degrading deadline.
+class QUIC_EXPORT_PRIVATE QuicNetworkBlackholeDetector {
+ public:
+  class QUIC_EXPORT_PRIVATE Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Called when the path degrading alarm fires.
+    virtual void OnPathDegradingDetected() = 0;
+
+    // Called when the path blackhole alarm fires.
+    virtual void OnBlackholeDetected() = 0;
+
+    // Called when the path mtu reduction alarm fires.
+    virtual void OnPathMtuReductionDetected() = 0;
+  };
+
+  QuicNetworkBlackholeDetector(Delegate* delegate, QuicConnectionArena* arena,
+                               QuicAlarmFactory* alarm_factory,
+                               QuicConnectionContext* context);
+
+  // Called to stop all detections. If |permanent|, the alarm will be cancelled
+  // permanently and future calls to RestartDetection will be no-op.
+  void StopDetection(bool permanent);
+
+  // Called to restart path degrading, path mtu reduction and blackhole
+  // detections. Please note, if |blackhole_deadline| is set, it must be the
+  // furthest in the future of all deadlines.
+  void RestartDetection(QuicTime path_degrading_deadline,
+                        QuicTime blackhole_deadline,
+                        QuicTime path_mtu_reduction_deadline);
+
+  // Called when |alarm_| fires.
+  void OnAlarm();
+
+  // Returns true if |alarm_| is set.
+  bool IsDetectionInProgress() const;
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicNetworkBlackholeDetectorPeer;
+
+  QuicTime GetEarliestDeadline() const;
+  QuicTime GetLastDeadline() const;
+
+  // Update alarm to the next deadline.
+  void UpdateAlarm() const;
+
+  Delegate* delegate_;  // Not owned.
+
+  // Time that Delegate::OnPathDegrading will be called. 0 means no path
+  // degrading detection is in progress.
+  QuicTime path_degrading_deadline_ = QuicTime::Zero();
+  // Time that Delegate::OnBlackholeDetected will be called. 0 means no
+  // blackhole detection is in progress.
+  QuicTime blackhole_deadline_ = QuicTime::Zero();
+  // Time that Delegate::OnPathMtuReductionDetected will be called. 0 means no
+  // path mtu reduction detection is in progress.
+  QuicTime path_mtu_reduction_deadline_ = QuicTime::Zero();
+
+  QuicArenaScopedPtr<QuicAlarm> alarm_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
diff --git a/quiche/quic/core/quic_network_blackhole_detector_test.cc b/quiche/quic/core/quic_network_blackhole_detector_test.cc
new file mode 100644
index 0000000..ca2c87d
--- /dev/null
+++ b/quiche/quic/core/quic_network_blackhole_detector_test.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_network_blackhole_detector.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class QuicNetworkBlackholeDetectorPeer {
+ public:
+  static QuicAlarm* GetAlarm(QuicNetworkBlackholeDetector* detector) {
+    return detector->alarm_.get();
+  }
+};
+
+namespace {
+class MockDelegate : public QuicNetworkBlackholeDetector::Delegate {
+ public:
+  MOCK_METHOD(void, OnPathDegradingDetected, (), (override));
+  MOCK_METHOD(void, OnBlackholeDetected, (), (override));
+  MOCK_METHOD(void, OnPathMtuReductionDetected, (), (override));
+};
+
+const size_t kPathDegradingDelayInSeconds = 5;
+const size_t kPathMtuReductionDelayInSeconds = 7;
+const size_t kBlackholeDelayInSeconds = 10;
+
+class QuicNetworkBlackholeDetectorTest : public QuicTest {
+ public:
+  QuicNetworkBlackholeDetectorTest()
+      : detector_(&delegate_, &arena_, &alarm_factory_, /*context=*/nullptr),
+        alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
+            QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_))),
+        path_degrading_delay_(
+            QuicTime::Delta::FromSeconds(kPathDegradingDelayInSeconds)),
+        path_mtu_reduction_delay_(
+            QuicTime::Delta::FromSeconds(kPathMtuReductionDelayInSeconds)),
+        blackhole_delay_(
+            QuicTime::Delta::FromSeconds(kBlackholeDelayInSeconds)) {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+ protected:
+  void RestartDetection() {
+    detector_.RestartDetection(clock_.Now() + path_degrading_delay_,
+                               clock_.Now() + blackhole_delay_,
+                               clock_.Now() + path_mtu_reduction_delay_);
+  }
+
+  testing::StrictMock<MockDelegate> delegate_;
+  QuicConnectionArena arena_;
+  MockAlarmFactory alarm_factory_;
+
+  QuicNetworkBlackholeDetector detector_;
+
+  MockAlarmFactory::TestAlarm* alarm_;
+  MockClock clock_;
+  const QuicTime::Delta path_degrading_delay_;
+  const QuicTime::Delta path_mtu_reduction_delay_;
+  const QuicTime::Delta blackhole_delay_;
+};
+
+TEST_F(QuicNetworkBlackholeDetectorTest, StartAndFire) {
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+
+  RestartDetection();
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+
+  // Fire path degrading alarm.
+  clock_.AdvanceTime(path_degrading_delay_);
+  EXPECT_CALL(delegate_, OnPathDegradingDetected());
+  alarm_->Fire();
+
+  // Verify path mtu reduction detection is still in progress.
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
+            alarm_->deadline());
+
+  // Fire path mtu reduction detection alarm.
+  clock_.AdvanceTime(path_mtu_reduction_delay_ - path_degrading_delay_);
+  EXPECT_CALL(delegate_, OnPathMtuReductionDetected());
+  alarm_->Fire();
+
+  // Verify blackhole detection is still in progress.
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + blackhole_delay_ - path_mtu_reduction_delay_,
+            alarm_->deadline());
+
+  // Fire blackhole detection alarm.
+  clock_.AdvanceTime(blackhole_delay_ - path_mtu_reduction_delay_);
+  EXPECT_CALL(delegate_, OnBlackholeDetected());
+  alarm_->Fire();
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+}
+
+TEST_F(QuicNetworkBlackholeDetectorTest, RestartAndStop) {
+  RestartDetection();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  RestartDetection();
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+
+  detector_.StopDetection(/*permanent=*/false);
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+}
+
+TEST_F(QuicNetworkBlackholeDetectorTest, PathDegradingFiresAndRestart) {
+  EXPECT_FALSE(detector_.IsDetectionInProgress());
+  RestartDetection();
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+
+  // Fire path degrading alarm.
+  clock_.AdvanceTime(path_degrading_delay_);
+  EXPECT_CALL(delegate_, OnPathDegradingDetected());
+  alarm_->Fire();
+
+  // Verify path mtu reduction detection is still in progress.
+  EXPECT_TRUE(detector_.IsDetectionInProgress());
+  EXPECT_EQ(clock_.Now() + path_mtu_reduction_delay_ - path_degrading_delay_,
+            alarm_->deadline());
+
+  // After 100ms, restart detections on forward progress.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  RestartDetection();
+  // Verify alarm is armed based on path degrading deadline.
+  EXPECT_EQ(clock_.Now() + path_degrading_delay_, alarm_->deadline());
+}
+
+}  // namespace
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_one_block_arena.h b/quiche/quic/core/quic_one_block_arena.h
new file mode 100644
index 0000000..4bebebe
--- /dev/null
+++ b/quiche/quic/core/quic_one_block_arena.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// An arena that consists of a single inlined block of |ArenaSize|. Useful to
+// avoid repeated calls to malloc/new and to improve memory locality.
+// QUICHE_DCHECK's if an allocation out of the arena ever fails in debug builds;
+// falls back to heap allocation in release builds.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
+#define QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+template <uint32_t ArenaSize>
+class QUIC_EXPORT_PRIVATE QuicOneBlockArena {
+  static const uint32_t kMaxAlign = 8;
+
+ public:
+  QuicOneBlockArena() : offset_(0) {}
+  QuicOneBlockArena(const QuicOneBlockArena&) = delete;
+  QuicOneBlockArena& operator=(const QuicOneBlockArena&) = delete;
+
+  // Instantiates an object of type |T| with |args|. |args| are perfectly
+  // forwarded to |T|'s constructor. The returned pointer's lifetime is
+  // controlled by QuicArenaScopedPtr.
+  template <typename T, typename... Args>
+  QuicArenaScopedPtr<T> New(Args&&... args) {
+    QUICHE_DCHECK_LT(AlignedSize<T>(), ArenaSize)
+        << "Object is too large for the arena.";
+    static_assert(alignof(T) > 1,
+                  "Objects added to the arena must be at least 2B aligned.");
+    if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
+      QUIC_BUG(quic_bug_10593_1)
+          << "Ran out of space in QuicOneBlockArena at " << this
+          << ", max size was " << ArenaSize << ", failing request was "
+          << AlignedSize<T>() << ", end of arena was " << offset_;
+      return QuicArenaScopedPtr<T>(new T(std::forward<Args>(args)...));
+    }
+
+    void* buf = &storage_[offset_];
+    new (buf) T(std::forward<Args>(args)...);
+    offset_ += AlignedSize<T>();
+    return QuicArenaScopedPtr<T>(buf,
+                                 QuicArenaScopedPtr<T>::ConstructFrom::kArena);
+  }
+
+ private:
+  // Returns the size of |T| aligned up to |kMaxAlign|.
+  template <typename T>
+  static inline uint32_t AlignedSize() {
+    return ((sizeof(T) + (kMaxAlign - 1)) / kMaxAlign) * kMaxAlign;
+  }
+
+  // Actual storage.
+  // Subtle/annoying: the value '8' must be coded explicitly into the alignment
+  // declaration for MSVC.
+  alignas(8) char storage_[ArenaSize];
+  // Current offset into the storage.
+  uint32_t offset_;
+};
+
+// QuicConnections currently use around 1KB of polymorphic types which would
+// ordinarily be on the heap. Instead, store them inline in an arena.
+using QuicConnectionArena = QuicOneBlockArena<1152>;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_ONE_BLOCK_ARENA_H_
diff --git a/quiche/quic/core/quic_one_block_arena_test.cc b/quiche/quic/core/quic_one_block_arena_test.cc
new file mode 100644
index 0000000..89c774d
--- /dev/null
+++ b/quiche/quic/core/quic_one_block_arena_test.cc
@@ -0,0 +1,60 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace {
+
+static const uint32_t kMaxAlign = 8;
+
+struct TestObject {
+  uint32_t value;
+};
+
+class QuicOneBlockArenaTest : public QuicTest {};
+
+TEST_F(QuicOneBlockArenaTest, AllocateSuccess) {
+  QuicOneBlockArena<1024> arena;
+  QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
+  EXPECT_TRUE(ptr.is_from_arena());
+}
+
+TEST_F(QuicOneBlockArenaTest, Exhaust) {
+  QuicOneBlockArena<1024> arena;
+  for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
+    QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
+    EXPECT_TRUE(ptr.is_from_arena());
+  }
+  QuicArenaScopedPtr<TestObject> ptr;
+  EXPECT_QUIC_BUG(ptr = arena.New<TestObject>(),
+                  "Ran out of space in QuicOneBlockArena");
+  EXPECT_FALSE(ptr.is_from_arena());
+}
+
+TEST_F(QuicOneBlockArenaTest, NoOverlaps) {
+  QuicOneBlockArena<1024> arena;
+  std::vector<QuicArenaScopedPtr<TestObject>> objects;
+  QuicIntervalSet<uintptr_t> used;
+  for (size_t i = 0; i < 1024 / kMaxAlign; ++i) {
+    QuicArenaScopedPtr<TestObject> ptr = arena.New<TestObject>();
+    EXPECT_TRUE(ptr.is_from_arena());
+
+    uintptr_t begin = reinterpret_cast<uintptr_t>(ptr.get());
+    uintptr_t end = begin + sizeof(TestObject);
+    EXPECT_FALSE(used.Contains(begin));
+    EXPECT_FALSE(used.Contains(end - 1));
+    used.Add(begin, end);
+  }
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_creator.cc b/quiche/quic/core/quic_packet_creator.cc
new file mode 100644
index 0000000..4390747
--- /dev/null
+++ b/quiche/quic/core/quic_packet_creator.cc
@@ -0,0 +1,2306 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packet_creator.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_chaos_protector.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+namespace {
+
+QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return INITIAL;
+    case ENCRYPTION_HANDSHAKE:
+      return HANDSHAKE;
+    case ENCRYPTION_ZERO_RTT:
+      return ZERO_RTT_PROTECTED;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG(quic_bug_12398_1)
+          << "Try to derive long header type for packet with encryption level: "
+          << level;
+      return INVALID_PACKET_TYPE;
+    default:
+      QUIC_BUG(quic_bug_10752_1) << level;
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+void LogCoalesceStreamFrameStatus(bool success) {
+  QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
+                      "Success rate of coalesing stream frames attempt.");
+}
+
+// ScopedPacketContextSwitcher saves |packet|'s states and change states
+// during its construction. When the switcher goes out of scope, it restores
+// saved states.
+class ScopedPacketContextSwitcher {
+ public:
+  ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
+                              QuicPacketNumberLength packet_number_length,
+                              EncryptionLevel encryption_level,
+                              SerializedPacket* packet)
+
+      : saved_packet_number_(packet->packet_number),
+        saved_packet_number_length_(packet->packet_number_length),
+        saved_encryption_level_(packet->encryption_level),
+        packet_(packet) {
+    packet_->packet_number = packet_number,
+    packet_->packet_number_length = packet_number_length;
+    packet_->encryption_level = encryption_level;
+  }
+
+  ~ScopedPacketContextSwitcher() {
+    packet_->packet_number = saved_packet_number_;
+    packet_->packet_number_length = saved_packet_number_length_;
+    packet_->encryption_level = saved_encryption_level_;
+  }
+
+ private:
+  const QuicPacketNumber saved_packet_number_;
+  const QuicPacketNumberLength saved_packet_number_length_;
+  const EncryptionLevel saved_encryption_level_;
+  SerializedPacket* packet_;
+};
+
+}  // namespace
+
+#define ENDPOINT \
+  (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
+                                     QuicFramer* framer,
+                                     DelegateInterface* delegate)
+    : QuicPacketCreator(server_connection_id,
+                        framer,
+                        QuicRandom::GetInstance(),
+                        delegate) {}
+
+QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
+                                     QuicFramer* framer, QuicRandom* random,
+                                     DelegateInterface* delegate)
+    : delegate_(delegate),
+      debug_delegate_(nullptr),
+      framer_(framer),
+      random_(random),
+      send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
+      have_diversification_nonce_(false),
+      max_packet_length_(0),
+      server_connection_id_included_(CONNECTION_ID_PRESENT),
+      packet_size_(0),
+      server_connection_id_(server_connection_id),
+      client_connection_id_(EmptyQuicConnectionId()),
+      packet_(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false,
+              false),
+      pending_padding_bytes_(0),
+      needs_full_padding_(false),
+      next_transmission_type_(NOT_RETRANSMISSION),
+      flusher_attached_(false),
+      fully_pad_crypto_handshake_packets_(true),
+      latched_hard_max_packet_length_(0),
+      max_datagram_frame_size_(0),
+      chaos_protection_enabled_(
+          GetQuicFlag(FLAGS_quic_enable_chaos_protection) &&
+          framer->perspective() == Perspective::IS_CLIENT) {
+  SetMaxPacketLength(kDefaultMaxPacketSize);
+  if (!framer_->version().UsesTls()) {
+    // QUIC+TLS negotiates the maximum datagram frame size via the
+    // IETF QUIC max_datagram_frame_size transport parameter.
+    // QUIC_CRYPTO however does not negotiate this so we set its value here.
+    SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+}
+
+QuicPacketCreator::~QuicPacketCreator() {
+  DeleteFrames(&packet_.retransmittable_frames);
+}
+
+void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
+                                     std::unique_ptr<QuicEncrypter> encrypter) {
+  framer_->SetEncrypter(level, std::move(encrypter));
+  max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
+}
+
+bool QuicPacketCreator::CanSetMaxPacketLength() const {
+  // |max_packet_length_| should not be changed mid-packet.
+  return queued_frames_.empty();
+}
+
+void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
+  QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
+
+  // Avoid recomputing |max_plaintext_size_| if the length does not actually
+  // change.
+  if (length == max_packet_length_) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Updating packet creator max packet length from "
+                << max_packet_length_ << " to " << length;
+
+  max_packet_length_ = length;
+  max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
+  QUIC_BUG_IF(quic_bug_12398_2, max_plaintext_size_ - PacketHeaderSize() <
+                                    MinPlaintextPacketSize(framer_->version()))
+      << ENDPOINT << "Attempted to set max packet length too small";
+}
+
+void QuicPacketCreator::SetMaxDatagramFrameSize(
+    QuicByteCount max_datagram_frame_size) {
+  constexpr QuicByteCount upper_bound =
+      std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
+                              std::numeric_limits<size_t>::max());
+  if (max_datagram_frame_size > upper_bound) {
+    // A value of |max_datagram_frame_size| that is equal or greater than
+    // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
+    // We therefore clamp the value here to allow us to safely cast
+    // |max_datagram_frame_size_| to QuicPacketLength or size_t.
+    max_datagram_frame_size = upper_bound;
+  }
+  max_datagram_frame_size_ = max_datagram_frame_size;
+}
+
+void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
+  QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
+  if (length > max_packet_length_) {
+    QUIC_BUG(quic_bug_10752_2)
+        << ENDPOINT
+        << "Try to increase max_packet_length_ in "
+           "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
+    return;
+  }
+  if (framer_->GetMaxPlaintextSize(length) <
+      PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
+    // Please note: this would not guarantee to fit next packet if the size of
+    // packet header increases (e.g., encryption level changes).
+    QUIC_DLOG(INFO) << ENDPOINT << length
+                    << " is too small to fit packet header";
+    RemoveSoftMaxPacketLength();
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Setting soft max packet length to: " << length;
+  latched_hard_max_packet_length_ = max_packet_length_;
+  max_packet_length_ = length;
+  max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
+}
+
+// Stops serializing version of the protocol in packets sent after this call.
+// A packet that is already open might send kQuicVersionSize bytes less than the
+// maximum packet size if we stop sending version before it is serialized.
+void QuicPacketCreator::StopSendingVersion() {
+  QUICHE_DCHECK(send_version_in_packet_) << ENDPOINT;
+  QUICHE_DCHECK(!version().HasIetfInvariantHeader()) << ENDPOINT;
+  send_version_in_packet_ = false;
+  if (packet_size_ > 0) {
+    QUICHE_DCHECK_LT(kQuicVersionSize, packet_size_) << ENDPOINT;
+    packet_size_ -= kQuicVersionSize;
+  }
+}
+
+void QuicPacketCreator::SetDiversificationNonce(
+    const DiversificationNonce& nonce) {
+  QUICHE_DCHECK(!have_diversification_nonce_) << ENDPOINT;
+  have_diversification_nonce_ = true;
+  diversification_nonce_ = nonce;
+}
+
+void QuicPacketCreator::UpdatePacketNumberLength(
+    QuicPacketNumber least_packet_awaited_by_peer,
+    QuicPacketCount max_packets_in_flight) {
+  if (!queued_frames_.empty()) {
+    // Don't change creator state if there are frames queued.
+    QUIC_BUG(quic_bug_10752_3)
+        << ENDPOINT << "Called UpdatePacketNumberLength with "
+        << queued_frames_.size()
+        << " queued_frames.  First frame type:" << queued_frames_.front().type
+        << " last frame type:" << queued_frames_.back().type;
+    return;
+  }
+
+  const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
+  QUICHE_DCHECK_LE(least_packet_awaited_by_peer, next_packet_number)
+      << ENDPOINT;
+  const uint64_t current_delta =
+      next_packet_number - least_packet_awaited_by_peer;
+  const uint64_t delta = std::max(current_delta, max_packets_in_flight);
+  const QuicPacketNumberLength packet_number_length =
+      QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
+  if (packet_.packet_number_length == packet_number_length) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Updating packet number length from "
+                << static_cast<int>(packet_.packet_number_length) << " to "
+                << static_cast<int>(packet_number_length)
+                << ", least_packet_awaited_by_peer: "
+                << least_packet_awaited_by_peer
+                << " max_packets_in_flight: " << max_packets_in_flight
+                << " next_packet_number: " << next_packet_number;
+  packet_.packet_number_length = packet_number_length;
+}
+
+void QuicPacketCreator::SkipNPacketNumbers(
+    QuicPacketCount count,
+    QuicPacketNumber least_packet_awaited_by_peer,
+    QuicPacketCount max_packets_in_flight) {
+  if (!queued_frames_.empty()) {
+    // Don't change creator state if there are frames queued.
+    QUIC_BUG(quic_bug_10752_4)
+        << ENDPOINT << "Called SkipNPacketNumbers with "
+        << queued_frames_.size()
+        << " queued_frames.  First frame type:" << queued_frames_.front().type
+        << " last frame type:" << queued_frames_.back().type;
+    return;
+  }
+  if (packet_.packet_number > packet_.packet_number + count) {
+    // Skipping count packet numbers causes packet number wrapping around,
+    // reject it.
+    QUIC_LOG(WARNING) << ENDPOINT << "Skipping " << count
+                      << " packet numbers causes packet number wrapping "
+                         "around, least_packet_awaited_by_peer: "
+                      << least_packet_awaited_by_peer
+                      << " packet_number:" << packet_.packet_number;
+    return;
+  }
+  packet_.packet_number += count;
+  // Packet number changes, update packet number length if necessary.
+  UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
+}
+
+bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
+    EncryptionLevel level,
+    size_t write_length,
+    QuicStreamOffset offset,
+    bool needs_full_padding,
+    TransmissionType transmission_type,
+    QuicFrame* frame) {
+  QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoDataToFillCurrentPacket " << level
+                << " write_length " << write_length << " offset " << offset
+                << (needs_full_padding ? " needs_full_padding" : "") << " "
+                << transmission_type;
+  if (!CreateCryptoFrame(level, write_length, offset, frame)) {
+    return false;
+  }
+  // When crypto data was sent in stream frames, ConsumeData is called with
+  // |needs_full_padding = true|. Keep the same behavior here when sending
+  // crypto frames.
+  //
+  // TODO(nharper): Check what the IETF drafts say about padding out initial
+  // messages and change this as appropriate.
+  if (needs_full_padding) {
+    needs_full_padding_ = true;
+  }
+  return AddFrame(*frame, transmission_type);
+}
+
+bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
+    QuicStreamId id,
+    size_t data_size,
+    QuicStreamOffset offset,
+    bool fin,
+    bool needs_full_padding,
+    TransmissionType transmission_type,
+    QuicFrame* frame) {
+  if (!HasRoomForStreamFrame(id, offset, data_size)) {
+    return false;
+  }
+  CreateStreamFrame(id, data_size, offset, fin, frame);
+  // Explicitly disallow multi-packet CHLOs.
+  if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
+      StreamFrameIsClientHello(frame->stream_frame) &&
+      frame->stream_frame.data_length < data_size) {
+    const std::string error_details =
+        "Client hello won't fit in a single packet.";
+    QUIC_BUG(quic_bug_10752_5)
+        << ENDPOINT << error_details << " Constructed stream frame length: "
+        << frame->stream_frame.data_length << " CHLO length: " << data_size;
+    delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
+    return false;
+  }
+  if (!AddFrame(*frame, transmission_type)) {
+    // Fails if we try to write unencrypted stream data.
+    return false;
+  }
+  if (needs_full_padding) {
+    needs_full_padding_ = true;
+  }
+
+  return true;
+}
+
+bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
+                                              QuicStreamOffset offset,
+                                              size_t data_size) {
+  const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
+      framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
+      data_size);
+  if (BytesFree() > min_stream_frame_size) {
+    return true;
+  }
+  if (!RemoveSoftMaxPacketLength()) {
+    return false;
+  }
+  return BytesFree() > min_stream_frame_size;
+}
+
+bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
+  const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
+      framer_->transport_version(), /*last_frame_in_packet=*/true, length);
+  if (static_cast<QuicByteCount>(message_frame_size) >
+      max_datagram_frame_size_) {
+    return false;
+  }
+  if (BytesFree() >= message_frame_size) {
+    return true;
+  }
+  if (!RemoveSoftMaxPacketLength()) {
+    return false;
+  }
+  return BytesFree() >= message_frame_size;
+}
+
+// static
+size_t QuicPacketCreator::StreamFramePacketOverhead(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicVariableLengthIntegerLength length_length,
+    QuicStreamOffset offset) {
+  return GetPacketHeaderSize(version, destination_connection_id_length,
+                             source_connection_id_length, include_version,
+                             include_diversification_nonce,
+                             packet_number_length, retry_token_length_length, 0,
+                             length_length) +
+
+         // Assumes a packet with a single stream frame, which omits the length,
+         // causing the data length argument to be ignored.
+         QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
+                                           kMaxOutgoingPacketSize /* unused */);
+}
+
+void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
+                                          size_t data_size,
+                                          QuicStreamOffset offset,
+                                          bool fin,
+                                          QuicFrame* frame) {
+  // Make sure max_packet_length_ is greater than the largest possible overhead
+  // or max_packet_length_ is set to the soft limit.
+  QUICHE_DCHECK(
+      max_packet_length_ >
+          StreamFramePacketOverhead(
+              framer_->transport_version(), GetDestinationConnectionIdLength(),
+              GetSourceConnectionIdLength(), kIncludeVersion,
+              IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
+              GetRetryTokenLengthLength(), GetLengthLength(), offset) ||
+      latched_hard_max_packet_length_ > 0)
+      << ENDPOINT;
+
+  QUIC_BUG_IF(quic_bug_12398_3, !HasRoomForStreamFrame(id, offset, data_size))
+      << ENDPOINT << "No room for Stream frame, BytesFree: " << BytesFree()
+      << " MinStreamFrameSize: "
+      << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
+                                           offset, true, data_size);
+
+  QUIC_BUG_IF(quic_bug_12398_4, data_size == 0 && !fin)
+      << ENDPOINT << "Creating a stream frame for stream ID:" << id
+      << " with no data or fin.";
+  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
+      framer_->transport_version(), id, offset,
+      /* last_frame_in_packet= */ true, data_size);
+  size_t bytes_consumed =
+      std::min<size_t>(BytesFree() - min_frame_size, data_size);
+
+  bool set_fin = fin && bytes_consumed == data_size;  // Last frame.
+  *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
+}
+
+bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
+                                          size_t write_length,
+                                          QuicStreamOffset offset,
+                                          QuicFrame* frame) {
+  const size_t min_frame_size =
+      QuicFramer::GetMinCryptoFrameSize(write_length, offset);
+  if (BytesFree() <= min_frame_size &&
+      (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
+    return false;
+  }
+  size_t max_write_length = BytesFree() - min_frame_size;
+  size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
+  *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
+  return true;
+}
+
+void QuicPacketCreator::FlushCurrentPacket() {
+  if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
+    return;
+  }
+
+  ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
+  QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
+
+  if (external_buffer.buffer == nullptr) {
+    external_buffer.buffer = stack_buffer;
+    external_buffer.release_buffer = nullptr;
+  }
+
+  QUICHE_DCHECK_EQ(nullptr, packet_.encrypted_buffer) << ENDPOINT;
+  if (!SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize,
+                       /*allow_padding=*/true)) {
+    return;
+  }
+  OnSerializedPacket();
+}
+
+void QuicPacketCreator::OnSerializedPacket() {
+  QUIC_BUG_IF(quic_bug_12398_5, packet_.encrypted_buffer == nullptr)
+      << ENDPOINT;
+
+  SerializedPacket packet(std::move(packet_));
+  ClearPacket();
+  RemoveSoftMaxPacketLength();
+  delegate_->OnSerializedPacket(std::move(packet));
+}
+
+void QuicPacketCreator::ClearPacket() {
+  packet_.has_ack = false;
+  packet_.has_stop_waiting = false;
+  packet_.has_crypto_handshake = NOT_HANDSHAKE;
+  packet_.transmission_type = NOT_RETRANSMISSION;
+  packet_.encrypted_buffer = nullptr;
+  packet_.encrypted_length = 0;
+  packet_.has_ack_frequency = false;
+  packet_.has_message = false;
+  packet_.fate = SEND_TO_WRITER;
+  QUIC_BUG_IF(quic_bug_12398_6, packet_.release_encrypted_buffer != nullptr)
+      << ENDPOINT << "packet_.release_encrypted_buffer should be empty";
+  packet_.release_encrypted_buffer = nullptr;
+  QUICHE_DCHECK(packet_.retransmittable_frames.empty()) << ENDPOINT;
+  QUICHE_DCHECK(packet_.nonretransmittable_frames.empty()) << ENDPOINT;
+  packet_.largest_acked.Clear();
+  needs_full_padding_ = false;
+}
+
+size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
+    const SerializedPacket& packet,
+    size_t padding_size,
+    char* buffer,
+    size_t buffer_len) {
+  QUIC_BUG_IF(quic_bug_12398_7, packet.encryption_level != ENCRYPTION_INITIAL);
+  QUIC_BUG_IF(quic_bug_12398_8, packet.nonretransmittable_frames.empty() &&
+                                    packet.retransmittable_frames.empty())
+      << ENDPOINT
+      << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
+         "packet";
+
+  if (close_connection_if_fail_to_serialzie_coalesced_packet_ &&
+      HasPendingFrames()) {
+    QUIC_BUG(quic_packet_creator_unexpected_queued_frames)
+        << "Unexpected queued frames: " << GetPendingFramesInfo();
+    return 0;
+  }
+
+  ScopedPacketContextSwitcher switcher(
+      packet.packet_number -
+          1,  // -1 because serialize packet increase packet number.
+      packet.packet_number_length, packet.encryption_level, &packet_);
+  for (const QuicFrame& frame : packet.nonretransmittable_frames) {
+    if (!AddFrame(frame, packet.transmission_type)) {
+      QUIC_BUG(quic_bug_10752_6)
+          << ENDPOINT << "Failed to serialize frame: " << frame;
+      return 0;
+    }
+  }
+  for (const QuicFrame& frame : packet.retransmittable_frames) {
+    if (!AddFrame(frame, packet.transmission_type)) {
+      QUIC_BUG(quic_bug_10752_7)
+          << ENDPOINT << "Failed to serialize frame: " << frame;
+      return 0;
+    }
+  }
+  // Add necessary padding.
+  if (padding_size > 0) {
+    QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
+    if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
+                  packet.transmission_type)) {
+      QUIC_BUG(quic_bug_10752_8)
+          << ENDPOINT << "Failed to add padding of size " << padding_size
+          << " when serializing ENCRYPTION_INITIAL "
+             "packet in coalesced packet";
+      return 0;
+    }
+  }
+
+  if (close_connection_if_fail_to_serialzie_coalesced_packet_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(
+        quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 1, 2);
+  }
+
+  if (!SerializePacket(
+          QuicOwnedPacketBuffer(buffer, nullptr), buffer_len,
+          /*allow_padding=*/
+          !close_connection_if_fail_to_serialzie_coalesced_packet_)) {
+    return 0;
+  }
+  const size_t encrypted_length = packet_.encrypted_length;
+  // Clear frames in packet_. No need to DeleteFrames since frames are owned by
+  // initial_packet.
+  packet_.retransmittable_frames.clear();
+  packet_.nonretransmittable_frames.clear();
+  ClearPacket();
+  return encrypted_length;
+}
+
+void QuicPacketCreator::CreateAndSerializeStreamFrame(
+    QuicStreamId id,
+    size_t write_length,
+    QuicStreamOffset iov_offset,
+    QuicStreamOffset stream_offset,
+    bool fin,
+    TransmissionType transmission_type,
+    size_t* num_bytes_consumed) {
+  // TODO(b/167222597): consider using ScopedSerializationFailureHandler.
+  QUICHE_DCHECK(queued_frames_.empty()) << ENDPOINT;
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
+      << ENDPOINT;
+  // Write out the packet header
+  QuicPacketHeader header;
+  FillPacketHeader(&header);
+  packet_.fate = delegate_->GetSerializedPacketFate(
+      /*is_mtu_discovery=*/false, packet_.encryption_level);
+  QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
+                << ": " << SerializedPacketFateToString(packet_.fate) << " of "
+                << EncryptionLevelToString(packet_.encryption_level);
+
+  ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
+  QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
+
+  if (packet_buffer.buffer == nullptr) {
+    packet_buffer.buffer = stack_buffer;
+    packet_buffer.release_buffer = nullptr;
+  }
+
+  char* encrypted_buffer = packet_buffer.buffer;
+
+  QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
+  size_t length_field_offset = 0;
+  if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
+    QUIC_BUG(quic_bug_10752_9) << ENDPOINT << "AppendPacketHeader failed";
+    return;
+  }
+
+  // Create a Stream frame with the remaining space.
+  QUIC_BUG_IF(quic_bug_12398_9, iov_offset == write_length && !fin)
+      << ENDPOINT << "Creating a stream frame with no data or fin.";
+  const size_t remaining_data_size = write_length - iov_offset;
+  size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
+      framer_->transport_version(), id, stream_offset,
+      /* last_frame_in_packet= */ true, remaining_data_size);
+  size_t available_size =
+      max_plaintext_size_ - writer.length() - min_frame_size;
+  size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
+  size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
+  bool needs_padding = false;
+  if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
+    needs_padding = true;
+    // Recalculate sizes with the stream frame not being marked as the last
+    // frame in the packet.
+    min_frame_size = QuicFramer::GetMinStreamFrameSize(
+        framer_->transport_version(), id, stream_offset,
+        /* last_frame_in_packet= */ false, remaining_data_size);
+    available_size = max_plaintext_size_ - writer.length() - min_frame_size;
+    bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
+    plaintext_bytes_written = min_frame_size + bytes_consumed;
+  }
+
+  const bool set_fin = fin && (bytes_consumed == remaining_data_size);
+  QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
+
+  // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
+  // into one method that takes a QuicStreamFrame, if warranted.
+  bool omit_frame_length = !needs_padding;
+  if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
+    QUIC_BUG(quic_bug_10752_10) << ENDPOINT << "AppendTypeByte failed";
+    return;
+  }
+  if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
+    QUIC_BUG(quic_bug_10752_11) << ENDPOINT << "AppendStreamFrame failed";
+    return;
+  }
+  if (needs_padding &&
+      plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
+      !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
+                                plaintext_bytes_written)) {
+    QUIC_BUG(quic_bug_10752_12) << ENDPOINT << "Unable to add padding bytes";
+    return;
+  }
+
+  if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
+                                          packet_.encryption_level)) {
+    return;
+  }
+
+  packet_.transmission_type = transmission_type;
+
+  QUICHE_DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
+                packet_.encryption_level == ENCRYPTION_ZERO_RTT)
+      << ENDPOINT << packet_.encryption_level;
+  size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header),
+      writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
+  if (encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10752_13)
+        << ENDPOINT << "Failed to encrypt packet number "
+        << header.packet_number;
+    return;
+  }
+  // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
+  // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
+  *num_bytes_consumed = bytes_consumed;
+  packet_size_ = 0;
+  packet_.encrypted_buffer = encrypted_buffer;
+  packet_.encrypted_length = encrypted_length;
+
+  packet_buffer.buffer = nullptr;
+  packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
+
+  packet_.retransmittable_frames.push_back(QuicFrame(frame));
+  OnSerializedPacket();
+}
+
+bool QuicPacketCreator::HasPendingFrames() const {
+  return !queued_frames_.empty();
+}
+
+std::string QuicPacketCreator::GetPendingFramesInfo() const {
+  return QuicFramesToString(queued_frames_);
+}
+
+bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
+  return !packet_.retransmittable_frames.empty();
+}
+
+bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
+  for (const auto& frame : packet_.retransmittable_frames) {
+    if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+size_t QuicPacketCreator::ExpansionOnNewFrame() const {
+  // If the last frame in the packet is a message frame, then it will expand to
+  // include the varint message length when a new frame is added.
+  if (queued_frames_.empty()) {
+    return 0;
+  }
+  return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
+                                          framer_->transport_version());
+}
+
+// static
+size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
+    const QuicFrame& last_frame,
+    QuicTransportVersion version) {
+  if (last_frame.type == MESSAGE_FRAME) {
+    return QuicDataWriter::GetVarInt62Len(
+        last_frame.message_frame->message_length);
+  }
+  if (last_frame.type != STREAM_FRAME) {
+    return 0;
+  }
+  if (VersionHasIetfQuicFrames(version)) {
+    return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
+  }
+  return kQuicStreamPayloadLengthSize;
+}
+
+size_t QuicPacketCreator::BytesFree() const {
+  return max_plaintext_size_ -
+         std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
+}
+
+size_t QuicPacketCreator::PacketSize() const {
+  return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
+}
+
+bool QuicPacketCreator::AddPaddedSavedFrame(
+    const QuicFrame& frame,
+    TransmissionType transmission_type) {
+  if (AddFrame(frame, transmission_type)) {
+    needs_full_padding_ = true;
+    return true;
+  }
+  return false;
+}
+
+absl::optional<size_t>
+QuicPacketCreator::MaybeBuildDataPacketWithChaosProtection(
+    const QuicPacketHeader& header,
+    char* buffer) {
+  if (!chaos_protection_enabled_ ||
+      packet_.encryption_level != ENCRYPTION_INITIAL ||
+      !framer_->version().UsesCryptoFrames() || queued_frames_.size() != 2u ||
+      queued_frames_[0].type != CRYPTO_FRAME ||
+      queued_frames_[1].type != PADDING_FRAME ||
+      // Do not perform chaos protection if we do not have a known number of
+      // padding bytes to work with.
+      queued_frames_[1].padding_frame.num_padding_bytes <= 0 ||
+      // Chaos protection relies on the framer using a crypto data producer,
+      // which is always the case in practice.
+      framer_->data_producer() == nullptr) {
+    return absl::nullopt;
+  }
+  const QuicCryptoFrame& crypto_frame = *queued_frames_[0].crypto_frame;
+  if (packet_.encryption_level != crypto_frame.level) {
+    QUIC_BUG(chaos frame level)
+        << ENDPOINT << packet_.encryption_level << " != " << crypto_frame.level;
+    return absl::nullopt;
+  }
+  QuicChaosProtector chaos_protector(
+      crypto_frame, queued_frames_[1].padding_frame.num_padding_bytes,
+      packet_size_, framer_, random_);
+  return chaos_protector.BuildDataPacket(header, buffer);
+}
+
+bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
+                                        size_t encrypted_buffer_len,
+                                        bool allow_padding) {
+  if (packet_.encrypted_buffer != nullptr) {
+    const std::string error_details =
+        "Packet's encrypted buffer is not empty before serialization";
+    QUIC_BUG(quic_bug_10752_14) << ENDPOINT << error_details;
+    delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                                    error_details);
+    return false;
+  }
+  ScopedSerializationFailureHandler handler(this);
+
+  QUICHE_DCHECK_LT(0u, encrypted_buffer_len) << ENDPOINT;
+  QUIC_BUG_IF(quic_bug_12398_10,
+              queued_frames_.empty() && pending_padding_bytes_ == 0)
+      << ENDPOINT << "Attempt to serialize empty packet";
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+  if (delegate_ != nullptr) {
+    packet_.fate = delegate_->GetSerializedPacketFate(
+        /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
+                                                          MTU_DISCOVERY_FRAME),
+        packet_.encryption_level);
+    QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
+                  << ": " << SerializedPacketFateToString(packet_.fate)
+                  << " of "
+                  << EncryptionLevelToString(packet_.encryption_level);
+  }
+
+  if (allow_padding) {
+    MaybeAddPadding();
+  }
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
+                << QuicFramesToString(queued_frames_) << " at encryption_level "
+                << packet_.encryption_level
+                << ", allow_padding:" << allow_padding;
+
+  if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
+    // TODO(fayang): Use QUIC_MISSING_WRITE_KEYS for serialization failures due
+    // to missing keys.
+    QUIC_BUG(quic_bug_10752_15)
+        << ENDPOINT << "Attempting to serialize " << header
+        << QuicFramesToString(queued_frames_) << " at missing encryption_level "
+        << packet_.encryption_level << " using " << framer_->version();
+    return false;
+  }
+
+  QUICHE_DCHECK_GE(max_plaintext_size_, packet_size_) << ENDPOINT;
+  // Use the packet_size_ instead of the buffer size to ensure smaller
+  // packet sizes are properly used.
+
+  size_t length;
+  absl::optional<size_t> length_with_chaos_protection =
+      MaybeBuildDataPacketWithChaosProtection(header, encrypted_buffer.buffer);
+  if (length_with_chaos_protection.has_value()) {
+    length = length_with_chaos_protection.value();
+  } else {
+    length = framer_->BuildDataPacket(header, queued_frames_,
+                                      encrypted_buffer.buffer, packet_size_,
+                                      packet_.encryption_level);
+  }
+
+  if (length == 0) {
+    QUIC_BUG(quic_bug_10752_16)
+        << ENDPOINT << "Failed to serialize "
+        << QuicFramesToString(queued_frames_)
+        << " at encryption_level: " << packet_.encryption_level
+        << ", needs_full_padding_: " << needs_full_padding_
+        << ", pending_padding_bytes_: " << pending_padding_bytes_
+        << ", latched_hard_max_packet_length_: "
+        << latched_hard_max_packet_length_
+        << ", max_packet_length_: " << max_packet_length_
+        << ", header: " << header;
+    return false;
+  }
+
+  // ACK Frames will be truncated due to length only if they're the only frame
+  // in the packet, and if packet_size_ was set to max_plaintext_size_. If
+  // truncation due to length occurred, then GetSerializedFrameLength will have
+  // returned all bytes free.
+  bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
+                                      queued_frames_.size() == 1 &&
+                                      queued_frames_.back().type == ACK_FRAME;
+  // Because of possible truncation, we can't be confident that our
+  // packet size calculation worked correctly.
+  if (!possibly_truncated_by_length) {
+    QUICHE_DCHECK_EQ(packet_size_, length) << ENDPOINT;
+  }
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      encrypted_buffer_len, encrypted_buffer.buffer);
+  if (encrypted_length == 0) {
+    QUIC_BUG(quic_bug_10752_17)
+        << ENDPOINT << "Failed to encrypt packet number "
+        << packet_.packet_number;
+    return false;
+  }
+
+  packet_size_ = 0;
+  packet_.encrypted_buffer = encrypted_buffer.buffer;
+  packet_.encrypted_length = encrypted_length;
+
+  encrypted_buffer.buffer = nullptr;
+  packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
+  return true;
+}
+
+std::unique_ptr<SerializedPacket>
+QuicPacketCreator::SerializeConnectivityProbingPacket() {
+  QUIC_BUG_IF(quic_bug_12398_11,
+              VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT
+      << "Must not be version 99 to serialize padded ping connectivity probe";
+  RemoveSoftMaxPacketLength();
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
+                << header;
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  size_t length = BuildConnectivityProbingPacket(
+      header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
+  QUICHE_DCHECK(length) << ENDPOINT;
+
+  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
+      << ENDPOINT;
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      kMaxOutgoingPacketSize, buffer.get());
+  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
+
+  std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
+      header.packet_number, header.packet_number_length, buffer.release(),
+      encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
+
+  serialize_packet->release_encrypted_buffer = [](const char* p) {
+    delete[] p;
+  };
+  serialize_packet->encryption_level = packet_.encryption_level;
+  serialize_packet->transmission_type = NOT_RETRANSMISSION;
+
+  return serialize_packet;
+}
+
+std::unique_ptr<SerializedPacket>
+QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
+    const QuicPathFrameBuffer& payload) {
+  QUIC_BUG_IF(quic_bug_12398_12,
+              !VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT
+      << "Must be version 99 to serialize path challenge connectivity probe, "
+         "is version "
+      << framer_->transport_version();
+  RemoveSoftMaxPacketLength();
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  size_t length =
+      BuildPaddedPathChallengePacket(header, buffer.get(), max_plaintext_size_,
+                                     payload, packet_.encryption_level);
+  QUICHE_DCHECK(length) << ENDPOINT;
+
+  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
+      << ENDPOINT;
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      kMaxOutgoingPacketSize, buffer.get());
+  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
+
+  std::unique_ptr<SerializedPacket> serialize_packet(
+      new SerializedPacket(header.packet_number, header.packet_number_length,
+                           buffer.release(), encrypted_length,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false));
+
+  serialize_packet->release_encrypted_buffer = [](const char* p) {
+    delete[] p;
+  };
+  serialize_packet->encryption_level = packet_.encryption_level;
+  serialize_packet->transmission_type = NOT_RETRANSMISSION;
+
+  return serialize_packet;
+}
+
+std::unique_ptr<SerializedPacket>
+QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
+    const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+    const bool is_padded) {
+  QUIC_BUG_IF(quic_bug_12398_13,
+              !VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT
+      << "Must be version 99 to serialize path response connectivity probe, is "
+         "version "
+      << framer_->transport_version();
+  RemoveSoftMaxPacketLength();
+  QuicPacketHeader header;
+  // FillPacketHeader increments packet_number_.
+  FillPacketHeader(&header);
+
+  QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  size_t length =
+      BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
+                              payloads, is_padded, packet_.encryption_level);
+  QUICHE_DCHECK(length) << ENDPOINT;
+
+  QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
+      << ENDPOINT;
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.packet_number,
+      GetStartOfEncryptedData(framer_->transport_version(), header), length,
+      kMaxOutgoingPacketSize, buffer.get());
+  QUICHE_DCHECK(encrypted_length) << ENDPOINT;
+
+  std::unique_ptr<SerializedPacket> serialize_packet(
+      new SerializedPacket(header.packet_number, header.packet_number_length,
+                           buffer.release(), encrypted_length,
+                           /*has_ack=*/false, /*has_stop_waiting=*/false));
+
+  serialize_packet->release_encrypted_buffer = [](const char* p) {
+    delete[] p;
+  };
+  serialize_packet->encryption_level = packet_.encryption_level;
+  serialize_packet->transmission_type = NOT_RETRANSMISSION;
+
+  return serialize_packet;
+}
+
+size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
+    const QuicPacketHeader& header,
+    char* buffer,
+    size_t packet_length,
+    const QuicPathFrameBuffer& payload,
+    EncryptionLevel level) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT;
+  QuicFrames frames;
+
+  // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
+  QuicPathChallengeFrame path_challenge_frame(0, payload);
+  frames.push_back(QuicFrame(&path_challenge_frame));
+
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
+  }
+
+  // Add padding to the rest of the packet in order to assess Path MTU
+  // characteristics.
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(padding_frame));
+
+  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::BuildPathResponsePacket(
+    const QuicPacketHeader& header,
+    char* buffer,
+    size_t packet_length,
+    const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+    const bool is_padded,
+    EncryptionLevel level) {
+  if (payloads.empty()) {
+    QUIC_BUG(quic_bug_12398_14)
+        << ENDPOINT
+        << "Attempt to generate connectivity response with no request payloads";
+    return 0;
+  }
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
+      << ENDPOINT;
+
+  std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
+  for (const QuicPathFrameBuffer& payload : payloads) {
+    // Note that the control frame ID can be 0 since this is not retransmitted.
+    path_response_frames.push_back(
+        std::make_unique<QuicPathResponseFrame>(0, payload));
+  }
+
+  QuicFrames frames;
+  for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
+       path_response_frames) {
+    frames.push_back(QuicFrame(path_response_frame.get()));
+    if (debug_delegate_ != nullptr) {
+      debug_delegate_->OnFrameAddedToPacket(
+          QuicFrame(path_response_frame.get()));
+    }
+  }
+
+  if (is_padded) {
+    // Add padding to the rest of the packet in order to assess Path MTU
+    // characteristics.
+    QuicPaddingFrame padding_frame;
+    frames.push_back(QuicFrame(padding_frame));
+  }
+
+  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::BuildConnectivityProbingPacket(
+    const QuicPacketHeader& header,
+    char* buffer,
+    size_t packet_length,
+    EncryptionLevel level) {
+  QuicFrames frames;
+
+  // Write a PING frame, which has no data payload.
+  QuicPingFrame ping_frame;
+  frames.push_back(QuicFrame(ping_frame));
+
+  // Add padding to the rest of the packet.
+  QuicPaddingFrame padding_frame;
+  frames.push_back(QuicFrame(padding_frame));
+
+  return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::SerializeCoalescedPacket(
+    const QuicCoalescedPacket& coalesced,
+    char* buffer,
+    size_t buffer_len) {
+  if (HasPendingFrames()) {
+    QUIC_BUG(quic_bug_10752_18)
+        << ENDPOINT << "Try to serialize coalesced packet with pending frames";
+    return 0;
+  }
+  RemoveSoftMaxPacketLength();
+  QUIC_BUG_IF(quic_bug_12398_15, coalesced.length() == 0)
+      << ENDPOINT << "Attempt to serialize empty coalesced packet";
+  size_t packet_length = 0;
+  size_t initial_length = 0;
+  size_t padding_size = 0;
+  if (coalesced.initial_packet() != nullptr) {
+    // Padding coalesced packet containing initial packet to full.
+    padding_size = coalesced.max_packet_length() - coalesced.length();
+    if (framer_->perspective() == Perspective::IS_SERVER &&
+        QuicUtils::ContainsFrameType(
+            coalesced.initial_packet()->retransmittable_frames,
+            CONNECTION_CLOSE_FRAME)) {
+      // Do not pad server initial connection close packet.
+      padding_size = 0;
+    }
+    initial_length = ReserializeInitialPacketInCoalescedPacket(
+        *coalesced.initial_packet(), padding_size, buffer, buffer_len);
+    if (initial_length == 0) {
+      QUIC_BUG(quic_bug_10752_19)
+          << ENDPOINT
+          << "Failed to reserialize ENCRYPTION_INITIAL packet in "
+             "coalesced packet";
+      return 0;
+    }
+    QUIC_BUG_IF(quic_reserialize_initial_packet_unexpected_size,
+                coalesced.initial_packet()->encrypted_length + padding_size !=
+                    initial_length)
+        << "Reserialize initial packet in coalescer has unexpected size, "
+           "original_length: "
+        << coalesced.initial_packet()->encrypted_length
+        << ", coalesced.max_packet_length: " << coalesced.max_packet_length()
+        << ", coalesced.length: " << coalesced.length()
+        << ", padding_size: " << padding_size
+        << ", serialized_length: " << initial_length
+        << ", retransmittable frames: "
+        << QuicFramesToString(
+               coalesced.initial_packet()->retransmittable_frames)
+        << ", nonretransmittable frames: "
+        << QuicFramesToString(
+               coalesced.initial_packet()->nonretransmittable_frames);
+    buffer += initial_length;
+    buffer_len -= initial_length;
+    packet_length += initial_length;
+  }
+  size_t length_copied = 0;
+  if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
+    QUIC_BUG(quic_serialize_coalesced_packet_copy_failure)
+        << "SerializeCoalescedPacket failed. buffer_len:" << buffer_len
+        << ", initial_length:" << initial_length
+        << ", padding_size: " << padding_size
+        << ", length_copied:" << length_copied
+        << ", coalesced.length:" << coalesced.length()
+        << ", coalesced.max_packet_length:" << coalesced.max_packet_length()
+        << ", coalesced.packet_lengths:"
+        << absl::StrJoin(coalesced.packet_lengths(), ":");
+    return 0;
+  }
+  packet_length += length_copied;
+  QUIC_DVLOG(1) << ENDPOINT
+                << "Successfully serialized coalesced packet of length: "
+                << packet_length;
+  return packet_length;
+}
+
+// TODO(b/74062209): Make this a public method of framer?
+SerializedPacket QuicPacketCreator::NoPacket() {
+  return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
+                          nullptr, 0, false, false);
+}
+
+QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
+  if (framer_->perspective() == Perspective::IS_SERVER) {
+    return client_connection_id_;
+  }
+  return server_connection_id_;
+}
+
+QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
+  if (framer_->perspective() == Perspective::IS_CLIENT) {
+    return client_connection_id_;
+  }
+  return server_connection_id_;
+}
+
+QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
+    const {
+  // In versions that do not support client connection IDs, the destination
+  // connection ID is only sent from client to server.
+  return (framer_->perspective() == Perspective::IS_CLIENT ||
+          framer_->version().SupportsClientConnectionIds())
+             ? CONNECTION_ID_PRESENT
+             : CONNECTION_ID_ABSENT;
+}
+
+QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
+    const {
+  // Long header packets sent by server include source connection ID.
+  // Ones sent by the client only include source connection ID if the version
+  // supports client connection IDs.
+  if (HasIetfLongHeader() &&
+      (framer_->perspective() == Perspective::IS_SERVER ||
+       framer_->version().SupportsClientConnectionIds())) {
+    return CONNECTION_ID_PRESENT;
+  }
+  if (framer_->perspective() == Perspective::IS_SERVER) {
+    return server_connection_id_included_;
+  }
+  return CONNECTION_ID_ABSENT;
+}
+
+QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
+    const {
+  QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
+                                                         transport_version()))
+      << ENDPOINT;
+  return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
+             ? static_cast<QuicConnectionIdLength>(
+                   GetDestinationConnectionId().length())
+             : PACKET_0BYTE_CONNECTION_ID;
+}
+
+QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
+  QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
+                                                         transport_version()))
+      << ENDPOINT;
+  return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
+             ? static_cast<QuicConnectionIdLength>(
+                   GetSourceConnectionId().length())
+             : PACKET_0BYTE_CONNECTION_ID;
+}
+
+QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
+  if (HasIetfLongHeader() &&
+      !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
+    return PACKET_4BYTE_PACKET_NUMBER;
+  }
+  return packet_.packet_number_length;
+}
+
+size_t QuicPacketCreator::PacketHeaderSize() const {
+  return GetPacketHeaderSize(
+      framer_->transport_version(), GetDestinationConnectionIdLength(),
+      GetSourceConnectionIdLength(), IncludeVersionInHeader(),
+      IncludeNonceInPublicHeader(), GetPacketNumberLength(),
+      GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
+}
+
+QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
+    const {
+  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
+      HasIetfLongHeader() &&
+      EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
+    return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+}
+
+absl::string_view QuicPacketCreator::GetRetryToken() const {
+  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
+      HasIetfLongHeader() &&
+      EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
+    return retry_token_;
+  }
+  return absl::string_view();
+}
+
+void QuicPacketCreator::SetRetryToken(absl::string_view retry_token) {
+  retry_token_ = std::string(retry_token);
+}
+
+bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
+    const QuicFrame& frame) {
+  QUIC_BUG_IF(quic_bug_12398_16, IsControlFrame(frame.type) &&
+                                     !GetControlFrameId(frame) &&
+                                     frame.type != PING_FRAME)
+      << ENDPOINT
+      << "Adding a control frame with no control frame id: " << frame;
+  QUICHE_DCHECK(QuicUtils::IsRetransmittableFrame(frame.type))
+      << ENDPOINT << frame;
+  MaybeBundleAckOpportunistically();
+  if (HasPendingFrames()) {
+    if (AddFrame(frame, next_transmission_type_)) {
+      // There is pending frames and current frame fits.
+      return true;
+    }
+  }
+  QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
+  if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
+      !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
+                                       NOT_HANDSHAKE)) {
+    // Do not check congestion window for ping or connection close frames.
+    return false;
+  }
+  const bool success = AddFrame(frame, next_transmission_type_);
+  QUIC_BUG_IF(quic_bug_10752_20, !success)
+      << ENDPOINT << "Failed to add frame:" << frame
+      << " transmission_type:" << next_transmission_type_;
+  return success;
+}
+
+QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
+                                                size_t write_length,
+                                                QuicStreamOffset offset,
+                                                StreamSendingState state) {
+  QUIC_BUG_IF(quic_bug_10752_21, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to write stream data.";
+  bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
+  MaybeBundleAckOpportunistically();
+  bool fin = state != NO_FIN;
+  QUIC_BUG_IF(quic_bug_12398_17, has_handshake && fin)
+      << ENDPOINT << "Handshake packets should never send a fin";
+  // To make reasoning about crypto frames easier, we don't combine them with
+  // other retransmittable frames in a single packet.
+  if (has_handshake && HasPendingRetransmittableFrames()) {
+    FlushCurrentPacket();
+  }
+
+  size_t total_bytes_consumed = 0;
+  bool fin_consumed = false;
+
+  if (!HasRoomForStreamFrame(id, offset, write_length)) {
+    FlushCurrentPacket();
+  }
+
+  if (!fin && (write_length == 0)) {
+    QUIC_BUG(quic_bug_10752_22)
+        << ENDPOINT << "Attempt to consume empty data without FIN.";
+    return QuicConsumedData(0, false);
+  }
+  // We determine if we can enter the fast path before executing
+  // the slow path loop.
+  bool run_fast_path =
+      !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
+      write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
+      latched_hard_max_packet_length_ == 0;
+
+  while (!run_fast_path &&
+         (has_handshake || delegate_->ShouldGeneratePacket(
+                               HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
+    QuicFrame frame;
+    bool needs_full_padding =
+        has_handshake && fully_pad_crypto_handshake_packets_;
+
+    if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
+                                        offset + total_bytes_consumed, fin,
+                                        needs_full_padding,
+                                        next_transmission_type_, &frame)) {
+      // The creator is always flushed if there's not enough room for a new
+      // stream frame before ConsumeData, so ConsumeData should always succeed.
+      QUIC_BUG(quic_bug_10752_23)
+          << ENDPOINT << "Failed to ConsumeData, stream:" << id;
+      return QuicConsumedData(0, false);
+    }
+
+    // A stream frame is created and added.
+    size_t bytes_consumed = frame.stream_frame.data_length;
+    total_bytes_consumed += bytes_consumed;
+    fin_consumed = fin && total_bytes_consumed == write_length;
+    if (fin_consumed && state == FIN_AND_PADDING) {
+      AddRandomPadding();
+    }
+    QUICHE_DCHECK(total_bytes_consumed == write_length ||
+                  (bytes_consumed > 0 && HasPendingFrames()))
+        << ENDPOINT;
+
+    if (total_bytes_consumed == write_length) {
+      // We're done writing the data. Exit the loop.
+      // We don't make this a precondition because we could have 0 bytes of data
+      // if we're simply writing a fin.
+      break;
+    }
+    FlushCurrentPacket();
+
+    run_fast_path =
+        !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
+        write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
+        latched_hard_max_packet_length_ == 0;
+  }
+
+  if (run_fast_path) {
+    return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
+                               total_bytes_consumed);
+  }
+
+  // Don't allow the handshake to be bundled with other retransmittable frames.
+  if (has_handshake) {
+    FlushCurrentPacket();
+  }
+
+  return QuicConsumedData(total_bytes_consumed, fin_consumed);
+}
+
+QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
+    QuicStreamId id,
+    size_t write_length,
+    QuicStreamOffset offset,
+    bool fin,
+    size_t total_bytes_consumed) {
+  QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
+      << ENDPOINT;
+  if (AttemptingToSendUnencryptedStreamData()) {
+    return QuicConsumedData(total_bytes_consumed,
+                            fin && (total_bytes_consumed == write_length));
+  }
+
+  while (total_bytes_consumed < write_length &&
+         delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
+                                         NOT_HANDSHAKE)) {
+    // Serialize and encrypt the packet.
+    size_t bytes_consumed = 0;
+    CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
+                                  offset + total_bytes_consumed, fin,
+                                  next_transmission_type_, &bytes_consumed);
+    if (bytes_consumed == 0) {
+      const std::string error_details =
+          "Failed in CreateAndSerializeStreamFrame.";
+      QUIC_BUG(quic_bug_10752_24) << ENDPOINT << error_details;
+      delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                                      error_details);
+      break;
+    }
+    total_bytes_consumed += bytes_consumed;
+  }
+
+  return QuicConsumedData(total_bytes_consumed,
+                          fin && (total_bytes_consumed == write_length));
+}
+
+size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
+                                            size_t write_length,
+                                            QuicStreamOffset offset) {
+  QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoData " << level << " write_length "
+                << write_length << " offset " << offset;
+  QUIC_BUG_IF(quic_bug_10752_25, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to write crypto data.";
+  MaybeBundleAckOpportunistically();
+  // To make reasoning about crypto frames easier, we don't combine them with
+  // other retransmittable frames in a single packet.
+  // TODO(nharper): Once we have separate packet number spaces, everything
+  // should be driven by encryption level, and we should stop flushing in this
+  // spot.
+  if (HasPendingRetransmittableFrames()) {
+    FlushCurrentPacket();
+  }
+
+  size_t total_bytes_consumed = 0;
+
+  while (
+      total_bytes_consumed < write_length &&
+      delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
+    QuicFrame frame;
+    if (!ConsumeCryptoDataToFillCurrentPacket(
+            level, write_length - total_bytes_consumed,
+            offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
+            next_transmission_type_, &frame)) {
+      // The only pending data in the packet is non-retransmittable frames.
+      // I'm assuming here that they won't occupy so much of the packet that a
+      // CRYPTO frame won't fit.
+      QUIC_BUG_IF(quic_bug_10752_26, !HasSoftMaxPacketLength()) << absl::StrCat(
+          ENDPOINT, "Failed to ConsumeCryptoData at level ", level,
+          ", pending_frames: ", GetPendingFramesInfo(),
+          ", has_soft_max_packet_length: ", HasSoftMaxPacketLength(),
+          ", max_packet_length: ", max_packet_length_, ", transmission_type: ",
+          TransmissionTypeToString(next_transmission_type_),
+          ", packet_number: ", packet_number().ToString());
+      return 0;
+    }
+    total_bytes_consumed += frame.crypto_frame->data_length;
+    FlushCurrentPacket();
+  }
+
+  // Don't allow the handshake to be bundled with other retransmittable frames.
+  FlushCurrentPacket();
+
+  return total_bytes_consumed;
+}
+
+void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
+  // MTU discovery frames must be sent by themselves.
+  if (!CanSetMaxPacketLength()) {
+    QUIC_BUG(quic_bug_10752_27)
+        << ENDPOINT
+        << "MTU discovery packets should only be sent when no other "
+        << "frames needs to be sent.";
+    return;
+  }
+  const QuicByteCount current_mtu = max_packet_length();
+
+  // The MTU discovery frame is allocated on the stack, since it is going to be
+  // serialized within this function.
+  QuicMtuDiscoveryFrame mtu_discovery_frame;
+  QuicFrame frame(mtu_discovery_frame);
+
+  // Send the probe packet with the new length.
+  SetMaxPacketLength(target_mtu);
+  const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
+  FlushCurrentPacket();
+  // The only reason AddFrame can fail is that the packet is too full to fit in
+  // a ping.  This is not possible for any sane MTU.
+  QUIC_BUG_IF(quic_bug_10752_28, !success)
+      << ENDPOINT << "Failed to send path MTU target_mtu:" << target_mtu
+      << " transmission_type:" << next_transmission_type_;
+
+  // Reset the packet length back.
+  SetMaxPacketLength(current_mtu);
+}
+
+void QuicPacketCreator::MaybeBundleAckOpportunistically() {
+  if (has_ack()) {
+    // Ack already queued, nothing to do.
+    return;
+  }
+  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                       NOT_HANDSHAKE)) {
+    return;
+  }
+  const bool flushed =
+      FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
+  QUIC_BUG_IF(quic_bug_10752_29, !flushed)
+      << ENDPOINT << "Failed to flush ACK frame. encryption_level:"
+      << packet_.encryption_level;
+}
+
+bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
+  QUIC_BUG_IF(quic_bug_10752_30, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to send ACK frame.";
+  // MaybeBundleAckOpportunistically could be called nestedly when sending a
+  // control frame causing another control frame to be sent.
+  QUIC_BUG_IF(quic_bug_12398_18, !frames.empty() && has_ack())
+      << ENDPOINT << "Trying to flush " << quiche::PrintElements(frames)
+      << " when there is ACK queued";
+  for (const auto& frame : frames) {
+    QUICHE_DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME)
+        << ENDPOINT;
+    if (HasPendingFrames()) {
+      if (AddFrame(frame, next_transmission_type_)) {
+        // There is pending frames and current frame fits.
+        continue;
+      }
+    }
+    QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
+    // There is no pending frames, consult the delegate whether a packet can be
+    // generated.
+    if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                         NOT_HANDSHAKE)) {
+      return false;
+    }
+    const bool success = AddFrame(frame, next_transmission_type_);
+    QUIC_BUG_IF(quic_bug_10752_31, !success)
+        << ENDPOINT << "Failed to flush " << frame;
+  }
+  return true;
+}
+
+void QuicPacketCreator::AddRandomPadding() {
+  AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
+}
+
+void QuicPacketCreator::AttachPacketFlusher() {
+  flusher_attached_ = true;
+  if (!write_start_packet_number_.IsInitialized()) {
+    write_start_packet_number_ = NextSendingPacketNumber();
+  }
+}
+
+void QuicPacketCreator::Flush() {
+  FlushCurrentPacket();
+  SendRemainingPendingPadding();
+  flusher_attached_ = false;
+  if (GetQuicFlag(FLAGS_quic_export_write_path_stats_at_server)) {
+    if (!write_start_packet_number_.IsInitialized()) {
+      QUIC_BUG(quic_bug_10752_32)
+          << ENDPOINT << "write_start_packet_number is not initialized";
+      return;
+    }
+    QUIC_SERVER_HISTOGRAM_COUNTS(
+        "quic_server_num_written_packets_per_write",
+        NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
+        "Number of QUIC packets written per write operation");
+  }
+  write_start_packet_number_.Clear();
+}
+
+void QuicPacketCreator::SendRemainingPendingPadding() {
+  while (
+      pending_padding_bytes() > 0 && !HasPendingFrames() &&
+      delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
+    FlushCurrentPacket();
+  }
+}
+
+void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
+  if (length == 0) {
+    SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
+  } else {
+    SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
+  }
+}
+
+void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
+  next_transmission_type_ = type;
+}
+
+MessageStatus QuicPacketCreator::AddMessageFrame(
+    QuicMessageId message_id, absl::Span<quiche::QuicheMemSlice> message) {
+  QUIC_BUG_IF(quic_bug_10752_33, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to add message frame.";
+  MaybeBundleAckOpportunistically();
+  const QuicByteCount message_length = MemSliceSpanTotalSize(message);
+  if (message_length > GetCurrentLargestMessagePayload()) {
+    return MESSAGE_STATUS_TOO_LARGE;
+  }
+  if (!HasRoomForMessageFrame(message_length)) {
+    FlushCurrentPacket();
+  }
+  QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
+  const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
+  if (!success) {
+    QUIC_BUG(quic_bug_10752_34)
+        << ENDPOINT << "Failed to send message " << message_id;
+    delete frame;
+    return MESSAGE_STATUS_INTERNAL_ERROR;
+  }
+  QUICHE_DCHECK_EQ(MemSliceSpanTotalSize(message),
+                   0u);  // Ensure the old slices are empty.
+  return MESSAGE_STATUS_SUCCESS;
+}
+
+QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
+  if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
+      HasIetfLongHeader()) {
+    QuicLongHeaderType long_header_type =
+        EncryptionlevelToLongHeaderType(packet_.encryption_level);
+    if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
+        long_header_type == HANDSHAKE) {
+      return VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    }
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+}
+
+void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
+  header->destination_connection_id = GetDestinationConnectionId();
+  header->destination_connection_id_included =
+      GetDestinationConnectionIdIncluded();
+  header->source_connection_id = GetSourceConnectionId();
+  header->source_connection_id_included = GetSourceConnectionIdIncluded();
+  header->reset_flag = false;
+  header->version_flag = IncludeVersionInHeader();
+  if (IncludeNonceInPublicHeader()) {
+    QUICHE_DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective())
+        << ENDPOINT;
+    header->nonce = &diversification_nonce_;
+  } else {
+    header->nonce = nullptr;
+  }
+  packet_.packet_number = NextSendingPacketNumber();
+  header->packet_number = packet_.packet_number;
+  header->packet_number_length = GetPacketNumberLength();
+  header->retry_token_length_length = GetRetryTokenLengthLength();
+  header->retry_token = GetRetryToken();
+  header->length_length = GetLengthLength();
+  header->remaining_packet_length = 0;
+  if (!HasIetfLongHeader()) {
+    return;
+  }
+  header->long_packet_type =
+      EncryptionlevelToLongHeaderType(packet_.encryption_level);
+}
+
+size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
+  size_t serialized_frame_length = framer_->GetSerializedFrameLength(
+      frame, BytesFree(), queued_frames_.empty(),
+      /* last_frame_in_packet= */ true, GetPacketNumberLength());
+  if (!framer_->version().HasHeaderProtection() ||
+      serialized_frame_length == 0) {
+    return serialized_frame_length;
+  }
+  // Calculate frame bytes and bytes free with this frame added.
+  const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
+                             ExpansionOnNewFrame() + serialized_frame_length;
+  if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
+    // No extra bytes is needed.
+    return serialized_frame_length;
+  }
+  if (BytesFree() < serialized_frame_length) {
+    QUIC_BUG(quic_bug_10752_35) << ENDPOINT << "Frame does not fit: " << frame;
+    return 0;
+  }
+  // Please note bytes_free does not take |frame|'s expansion into account.
+  size_t bytes_free = BytesFree() - serialized_frame_length;
+  // Extra bytes needed (this is NOT padding needed) should be at least 1
+  // padding + expansion.
+  const size_t extra_bytes_needed = std::max(
+      1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
+      MinPlaintextPacketSize(framer_->version()) - frame_bytes);
+  if (bytes_free < extra_bytes_needed) {
+    // This frame does not fit.
+    return 0;
+  }
+  return serialized_frame_length;
+}
+
+bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
+                                 TransmissionType transmission_type) {
+  QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
+                << transmission_type << ": " << frame;
+  if (frame.type == STREAM_FRAME &&
+      !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+                                   frame.stream_frame.stream_id) &&
+      AttemptingToSendUnencryptedStreamData()) {
+    return false;
+  }
+
+  // Sanity check to ensure we don't send frames at the wrong encryption level.
+  QUICHE_DCHECK(
+      packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
+      packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
+      (frame.type != GOAWAY_FRAME && frame.type != WINDOW_UPDATE_FRAME &&
+       frame.type != HANDSHAKE_DONE_FRAME &&
+       frame.type != NEW_CONNECTION_ID_FRAME &&
+       frame.type != MAX_STREAMS_FRAME && frame.type != STREAMS_BLOCKED_FRAME &&
+       frame.type != PATH_RESPONSE_FRAME &&
+       frame.type != PATH_CHALLENGE_FRAME && frame.type != STOP_SENDING_FRAME &&
+       frame.type != MESSAGE_FRAME && frame.type != NEW_TOKEN_FRAME &&
+       frame.type != RETIRE_CONNECTION_ID_FRAME &&
+       frame.type != ACK_FREQUENCY_FRAME))
+      << ENDPOINT << frame.type << " not allowed at "
+      << packet_.encryption_level;
+
+  if (frame.type == STREAM_FRAME) {
+    if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
+      LogCoalesceStreamFrameStatus(true);
+      return true;
+    } else {
+      LogCoalesceStreamFrameStatus(false);
+    }
+  }
+
+  // If this is an ACK frame, validate that it is non-empty and that
+  // largest_acked matches the max packet number.
+  QUICHE_DCHECK(frame.type != ACK_FRAME || (!frame.ack_frame->packets.Empty() &&
+                                            frame.ack_frame->packets.Max() ==
+                                                frame.ack_frame->largest_acked))
+      << ENDPOINT << "Invalid ACK frame: " << frame;
+
+  size_t frame_len = GetSerializedFrameLength(frame);
+  if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
+    // Remove soft max_packet_length and retry.
+    frame_len = GetSerializedFrameLength(frame);
+  }
+  if (frame_len == 0) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Flushing because current open packet is full when adding "
+                  << frame;
+    FlushCurrentPacket();
+    return false;
+  }
+  if (queued_frames_.empty()) {
+    packet_size_ = PacketHeaderSize();
+  }
+  QUICHE_DCHECK_LT(0u, packet_size_) << ENDPOINT;
+
+  packet_size_ += ExpansionOnNewFrame() + frame_len;
+
+  if (QuicUtils::IsRetransmittableFrame(frame.type)) {
+    packet_.retransmittable_frames.push_back(frame);
+    queued_frames_.push_back(frame);
+    if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
+      packet_.has_crypto_handshake = IS_HANDSHAKE;
+    }
+  } else {
+    if (frame.type == PADDING_FRAME &&
+        frame.padding_frame.num_padding_bytes == -1) {
+      // Populate the actual length of full padding frame, such that one can
+      // know how much padding is actually added.
+      packet_.nonretransmittable_frames.push_back(
+          QuicFrame(QuicPaddingFrame(frame_len)));
+    } else {
+      packet_.nonretransmittable_frames.push_back(frame);
+    }
+    queued_frames_.push_back(frame);
+  }
+
+  if (frame.type == ACK_FRAME) {
+    packet_.has_ack = true;
+    packet_.largest_acked = LargestAcked(*frame.ack_frame);
+  } else if (frame.type == STOP_WAITING_FRAME) {
+    packet_.has_stop_waiting = true;
+  } else if (frame.type == ACK_FREQUENCY_FRAME) {
+    packet_.has_ack_frequency = true;
+  } else if (frame.type == MESSAGE_FRAME) {
+    packet_.has_message = true;
+  }
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnFrameAddedToPacket(frame);
+  }
+
+  // Packet transmission type is determined by the last added retransmittable
+  // frame.
+  if (QuicUtils::IsRetransmittableFrame(frame.type)) {
+    packet_.transmission_type = transmission_type;
+  }
+  return true;
+}
+
+void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
+  if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
+    return;
+  }
+  const size_t frame_bytes = PacketSize() - PacketHeaderSize();
+  if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
+    return;
+  }
+  const QuicByteCount min_header_protection_padding =
+      std::max(1 + ExpansionOnNewFrame(),
+               MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
+      ExpansionOnNewFrame();
+  // Update pending_padding_bytes_.
+  pending_padding_bytes_ =
+      std::max(pending_padding_bytes_, min_header_protection_padding);
+}
+
+bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
+  if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
+    return false;
+  }
+  QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
+  if (candidate->stream_id != frame.stream_id ||
+      candidate->offset + candidate->data_length != frame.offset ||
+      frame.data_length > BytesFree()) {
+    return false;
+  }
+  candidate->data_length += frame.data_length;
+  candidate->fin = frame.fin;
+
+  // The back of retransmittable frames must be the same as the original
+  // queued frames' back.
+  QUICHE_DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME)
+      << ENDPOINT;
+  QuicStreamFrame* retransmittable =
+      &packet_.retransmittable_frames.back().stream_frame;
+  QUICHE_DCHECK_EQ(retransmittable->stream_id, frame.stream_id) << ENDPOINT;
+  QUICHE_DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
+                   frame.offset)
+      << ENDPOINT;
+  retransmittable->data_length = candidate->data_length;
+  retransmittable->fin = candidate->fin;
+  packet_size_ += frame.data_length;
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnStreamFrameCoalesced(*candidate);
+  }
+  return true;
+}
+
+bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
+  if (latched_hard_max_packet_length_ == 0) {
+    return false;
+  }
+  if (!CanSetMaxPacketLength()) {
+    return false;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Restoring max packet length to: "
+                << latched_hard_max_packet_length_;
+  SetMaxPacketLength(latched_hard_max_packet_length_);
+  // Reset latched_max_packet_length_.
+  latched_hard_max_packet_length_ = 0;
+  return true;
+}
+
+void QuicPacketCreator::MaybeAddPadding() {
+  // The current packet should have no padding bytes because padding is only
+  // added when this method is called just before the packet is serialized.
+  if (BytesFree() == 0) {
+    // Don't pad full packets.
+    return;
+  }
+
+  if (packet_.transmission_type == PROBING_RETRANSMISSION) {
+    needs_full_padding_ = true;
+  }
+
+  if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
+    // Do not add full padding if the packet is going to be coalesced or
+    // encapsulated.
+    needs_full_padding_ = false;
+  }
+
+  // Header protection requires a minimum plaintext packet size.
+  MaybeAddExtraPaddingForHeaderProtection();
+
+  QUIC_DVLOG(3) << "MaybeAddPadding for " << packet_.packet_number
+                << ": transmission_type:" << packet_.transmission_type
+                << ", fate:" << packet_.fate
+                << ", needs_full_padding_:" << needs_full_padding_
+                << ", pending_padding_bytes_:" << pending_padding_bytes_
+                << ", BytesFree:" << BytesFree();
+
+  if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
+    // Do not need padding.
+    return;
+  }
+
+  int padding_bytes = -1;
+  if (!needs_full_padding_) {
+    padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
+    pending_padding_bytes_ -= padding_bytes;
+  }
+
+  bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
+                          packet_.transmission_type);
+  QUIC_BUG_IF(quic_bug_10752_36, !success)
+      << ENDPOINT << "Failed to add padding_bytes: " << padding_bytes
+      << " transmission_type: " << packet_.transmission_type;
+}
+
+bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
+  return have_diversification_nonce_ &&
+         packet_.encryption_level == ENCRYPTION_ZERO_RTT;
+}
+
+bool QuicPacketCreator::IncludeVersionInHeader() const {
+  if (version().HasIetfInvariantHeader()) {
+    return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
+  }
+  return send_version_in_packet_;
+}
+
+void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
+  pending_padding_bytes_ += size;
+  QUIC_DVLOG(3) << "After AddPendingPadding(" << size
+                << "), pending_padding_bytes_:" << pending_padding_bytes_;
+}
+
+bool QuicPacketCreator::StreamFrameIsClientHello(
+    const QuicStreamFrame& frame) const {
+  if (framer_->perspective() == Perspective::IS_SERVER ||
+      !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
+                                   frame.stream_id)) {
+    return false;
+  }
+  // The ClientHello is always sent with INITIAL encryption.
+  return packet_.encryption_level == ENCRYPTION_INITIAL;
+}
+
+void QuicPacketCreator::SetServerConnectionIdIncluded(
+    QuicConnectionIdIncluded server_connection_id_included) {
+  QUICHE_DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
+                server_connection_id_included == CONNECTION_ID_ABSENT)
+      << ENDPOINT;
+  QUICHE_DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
+                server_connection_id_included != CONNECTION_ID_ABSENT)
+      << ENDPOINT;
+  server_connection_id_included_ = server_connection_id_included;
+}
+
+void QuicPacketCreator::SetServerConnectionId(
+    QuicConnectionId server_connection_id) {
+  server_connection_id_ = server_connection_id;
+}
+
+void QuicPacketCreator::SetClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  QUICHE_DCHECK(client_connection_id.IsEmpty() ||
+                framer_->version().SupportsClientConnectionIds())
+      << ENDPOINT;
+  client_connection_id_ = client_connection_id;
+}
+
+QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
+  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
+    return 0;
+  }
+  const size_t packet_header_size = GetPacketHeaderSize(
+      framer_->transport_version(), GetDestinationConnectionIdLength(),
+      GetSourceConnectionIdLength(), IncludeVersionInHeader(),
+      IncludeNonceInPublicHeader(), GetPacketNumberLength(),
+      // No Retry token on packets containing application data.
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
+  // This is the largest possible message payload when the length field is
+  // omitted.
+  size_t max_plaintext_size =
+      latched_hard_max_packet_length_ == 0
+          ? max_plaintext_size_
+          : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
+  size_t largest_frame =
+      max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
+  if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
+    largest_frame = static_cast<size_t>(max_datagram_frame_size_);
+  }
+  return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
+}
+
+QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
+  if (!VersionSupportsMessageFrames(framer_->transport_version())) {
+    return 0;
+  }
+  // QUIC Crypto server packets may include a diversification nonce.
+  const bool may_include_nonce =
+      framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+      framer_->perspective() == Perspective::IS_SERVER;
+  // IETF QUIC long headers include a length on client 0RTT packets.
+  QuicVariableLengthIntegerLength length_length =
+      VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  if (framer_->perspective() == Perspective::IS_CLIENT) {
+    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+  if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
+    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  const size_t packet_header_size = GetPacketHeaderSize(
+      framer_->transport_version(), GetDestinationConnectionIdLength(),
+      // Assume CID lengths don't change, but version may be present.
+      GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
+      PACKET_4BYTE_PACKET_NUMBER,
+      // No Retry token on packets containing application data.
+      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
+  // This is the largest possible message payload when the length field is
+  // omitted.
+  size_t max_plaintext_size =
+      latched_hard_max_packet_length_ == 0
+          ? max_plaintext_size_
+          : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
+  size_t largest_frame =
+      max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
+  if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
+    largest_frame = static_cast<size_t>(max_datagram_frame_size_);
+  }
+  const QuicPacketLength largest_payload =
+      largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
+  // This must always be less than or equal to GetCurrentLargestMessagePayload.
+  QUICHE_DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload())
+      << ENDPOINT;
+  return largest_payload;
+}
+
+bool QuicPacketCreator::AttemptingToSendUnencryptedStreamData() {
+  if (packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
+      packet_.encryption_level == ENCRYPTION_FORWARD_SECURE) {
+    return false;
+  }
+  const std::string error_details =
+      absl::StrCat("Cannot send stream data with level: ",
+                   EncryptionLevelToString(packet_.encryption_level));
+  QUIC_BUG(quic_bug_10752_37) << ENDPOINT << error_details;
+  delegate_->OnUnrecoverableError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA,
+                                  error_details);
+  return true;
+}
+
+bool QuicPacketCreator::HasIetfLongHeader() const {
+  return version().HasIetfInvariantHeader() &&
+         packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
+}
+
+// static
+size_t QuicPacketCreator::MinPlaintextPacketSize(
+    const ParsedQuicVersion& version) {
+  if (!version.HasHeaderProtection()) {
+    return 0;
+  }
+  // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
+  // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
+  // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
+  // numbers could be as small as 1 byte, but the sample starts 4 bytes after
+  // the packet number, at least 3 bytes of plaintext are needed to make sure
+  // that there is enough ciphertext to sample.
+  //
+  // Google QUIC crypto uses different AEAD algorithms - in particular the auth
+  // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
+  // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
+  // ciphertext to sample.
+  //
+  // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
+  // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
+  // determined based on the handshake protocol used). However, even when TLS
+  // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
+  // test crypters) which also only use 12 byte tags.
+  //
+  // TODO(nharper): Set this based on the handshake protocol in use.
+  return 7;
+}
+
+QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
+  if (!packet_number().IsInitialized()) {
+    return framer_->first_sending_packet_number();
+  }
+  return packet_number() + 1;
+}
+
+bool QuicPacketCreator::PacketFlusherAttached() const {
+  return flusher_attached_;
+}
+
+bool QuicPacketCreator::HasSoftMaxPacketLength() const {
+  return latched_hard_max_packet_length_ != 0;
+}
+
+void QuicPacketCreator::SetDefaultPeerAddress(QuicSocketAddress address) {
+  if (!packet_.peer_address.IsInitialized()) {
+    packet_.peer_address = address;
+    return;
+  }
+  if (packet_.peer_address != address) {
+    FlushCurrentPacket();
+    packet_.peer_address = address;
+  }
+}
+
+#define ENDPOINT2                                                          \
+  (creator_->framer_->perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                              : "Client: ")
+
+QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
+    QuicPacketCreator* creator,
+    QuicSocketAddress address,
+    bool update_connection_id)
+    : ScopedPeerAddressContext(creator,
+                               address,
+                               EmptyQuicConnectionId(),
+                               EmptyQuicConnectionId(),
+                               update_connection_id) {}
+
+QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
+    QuicPacketCreator* creator,
+    QuicSocketAddress address,
+    const QuicConnectionId& client_connection_id,
+    const QuicConnectionId& server_connection_id,
+    bool update_connection_id)
+    : creator_(creator),
+      old_peer_address_(creator_->packet_.peer_address),
+      old_client_connection_id_(creator_->GetClientConnectionId()),
+      old_server_connection_id_(creator_->GetServerConnectionId()),
+      update_connection_id_(update_connection_id) {
+  QUIC_BUG_IF(quic_bug_12398_19, !old_peer_address_.IsInitialized())
+      << ENDPOINT2
+      << "Context is used before serialized packet's peer address is "
+         "initialized.";
+  creator_->SetDefaultPeerAddress(address);
+  if (update_connection_id_) {
+    // Flush current packet if connection ID length changes.
+    if (address == old_peer_address_ &&
+        ((client_connection_id.length() !=
+          old_client_connection_id_.length()) ||
+         (server_connection_id.length() !=
+          old_server_connection_id_.length()))) {
+      creator_->FlushCurrentPacket();
+    }
+    creator_->SetClientConnectionId(client_connection_id);
+    creator_->SetServerConnectionId(server_connection_id);
+  }
+}
+
+QuicPacketCreator::ScopedPeerAddressContext::~ScopedPeerAddressContext() {
+  creator_->SetDefaultPeerAddress(old_peer_address_);
+  if (update_connection_id_) {
+    creator_->SetClientConnectionId(old_client_connection_id_);
+    creator_->SetServerConnectionId(old_server_connection_id_);
+  }
+}
+
+QuicPacketCreator::ScopedSerializationFailureHandler::
+    ScopedSerializationFailureHandler(QuicPacketCreator* creator)
+    : creator_(creator) {}
+
+QuicPacketCreator::ScopedSerializationFailureHandler::
+    ~ScopedSerializationFailureHandler() {
+  if (creator_ == nullptr) {
+    return;
+  }
+  // Always clear queued_frames_.
+  creator_->queued_frames_.clear();
+
+  if (creator_->packet_.encrypted_buffer == nullptr) {
+    const std::string error_details = "Failed to SerializePacket.";
+    QUIC_BUG(quic_bug_10752_38) << ENDPOINT2 << error_details;
+    creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
+                                              error_details);
+  }
+}
+
+#undef ENDPOINT2
+
+void QuicPacketCreator::set_encryption_level(EncryptionLevel level) {
+  QUICHE_DCHECK(level == packet_.encryption_level || !HasPendingFrames())
+      << ENDPOINT << "Cannot update encryption level from "
+      << packet_.encryption_level << " to " << level
+      << " when we already have pending frames: "
+      << QuicFramesToString(queued_frames_);
+  packet_.encryption_level = level;
+}
+
+void QuicPacketCreator::AddPathChallengeFrame(
+    const QuicPathFrameBuffer& payload) {
+  // TODO(danzh) Unify similar checks at several entry points into one in
+  // AddFrame(). Sort out test helper functions and peer class that don't
+  // enforce this check.
+  QUIC_BUG_IF(quic_bug_10752_39, !flusher_attached_)
+      << ENDPOINT
+      << "Packet flusher is not attached when "
+         "generator tries to write stream data.";
+  // Write a PATH_CHALLENGE frame, which has a random 8-byte payload.
+  auto path_challenge_frame = new QuicPathChallengeFrame(0, payload);
+  QuicFrame frame(path_challenge_frame);
+  if (AddPaddedFrameWithRetry(frame)) {
+    return;
+  }
+  // Fail silently if the probing packet cannot be written, path validation
+  // initiator will retry sending automatically.
+  // TODO(danzh) This will consume retry budget, if it causes performance
+  // regression, consider to notify the caller about the sending failure and let
+  // the caller to decide if it worth retrying.
+  QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now";
+  delete path_challenge_frame;
+}
+
+bool QuicPacketCreator::AddPathResponseFrame(
+    const QuicPathFrameBuffer& data_buffer) {
+  auto path_response =
+      new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
+  QuicFrame frame(path_response);
+  if (AddPaddedFrameWithRetry(frame)) {
+    return true;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
+  delete path_response;
+  return false;
+}
+
+bool QuicPacketCreator::AddPaddedFrameWithRetry(const QuicFrame& frame) {
+  if (HasPendingFrames()) {
+    if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) {
+      // Frame is queued.
+      return true;
+    }
+  }
+  // Frame was not queued but queued frames were flushed.
+  QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
+  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                       NOT_HANDSHAKE)) {
+    return false;
+  }
+  bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION);
+  QUIC_BUG_IF(quic_bug_12398_20, !success) << ENDPOINT;
+  return true;
+}
+
+bool QuicPacketCreator::HasRetryToken() const {
+  return !retry_token_.empty();
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_creator.h b/quiche/quic/core/quic_packet_creator.h
new file mode 100644
index 0000000..55b7a2d
--- /dev/null
+++ b/quiche/quic/core/quic_packet_creator.h
@@ -0,0 +1,732 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Responsible for creating packets on behalf of a QuicConnection.
+// Packets are serialized just-in-time. Stream data and control frames will be
+// requested from the Connection just-in-time. Frames are accumulated into
+// "current" packet until no more frames can fit, then current packet gets
+// serialized and passed to connection via OnSerializedPacket().
+//
+// Whether a packet should be serialized is determined by whether delegate is
+// writable. If the Delegate is not writable, then no operations will cause
+// a packet to be serialized.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
+
+#include <cstddef>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_coalesced_packet.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+namespace test {
+class QuicPacketCreatorPeer;
+}
+
+class QUIC_EXPORT_PRIVATE QuicPacketCreator {
+ public:
+  // A delegate interface for further processing serialized packet.
+  class QUIC_EXPORT_PRIVATE DelegateInterface {
+   public:
+    virtual ~DelegateInterface() {}
+    // Get a buffer of kMaxOutgoingPacketSize bytes to serialize the next
+    // packet. If the return value's buffer is nullptr, QuicPacketCreator will
+    // serialize on a stack buffer.
+    virtual QuicPacketBuffer GetPacketBuffer() = 0;
+    // Called when a packet is serialized. Delegate take the ownership of
+    // |serialized_packet|.
+    virtual void OnSerializedPacket(SerializedPacket serialized_packet) = 0;
+
+    // Called when an unrecoverable error is encountered.
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& error_details) = 0;
+
+    // Consults delegate whether a packet should be generated.
+    virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+                                      IsHandshake handshake) = 0;
+    // Called when there is data to be sent. Retrieves updated ACK frame from
+    // the delegate.
+    virtual const QuicFrames MaybeBundleAckOpportunistically() = 0;
+
+    // Returns the packet fate for serialized packets which will be handed over
+    // to delegate via OnSerializedPacket(). Called when a packet is about to be
+    // serialized.
+    virtual SerializedPacketFate GetSerializedPacketFate(
+        bool is_mtu_discovery,
+        EncryptionLevel encryption_level) = 0;
+  };
+
+  // Interface which gets callbacks from the QuicPacketCreator at interesting
+  // points.  Implementations must not mutate the state of the creator
+  // as a result of these callbacks.
+  class QUIC_EXPORT_PRIVATE DebugDelegate {
+   public:
+    virtual ~DebugDelegate() {}
+
+    // Called when a frame has been added to the current packet.
+    virtual void OnFrameAddedToPacket(const QuicFrame& /*frame*/) {}
+
+    // Called when a stream frame is coalesced with an existing stream frame.
+    // |frame| is the new stream frame.
+    virtual void OnStreamFrameCoalesced(const QuicStreamFrame& /*frame*/) {}
+  };
+
+  // Set the peer address and connection IDs with which the serialized packet
+  // will be sent to during the scope of this object. Upon exiting the scope,
+  // the original peer address and connection IDs are restored.
+  class QUIC_EXPORT_PRIVATE ScopedPeerAddressContext {
+   public:
+    ScopedPeerAddressContext(QuicPacketCreator* creator,
+                             QuicSocketAddress address,
+                             bool update_connection_id);
+
+    ScopedPeerAddressContext(QuicPacketCreator* creator,
+                             QuicSocketAddress address,
+                             const QuicConnectionId& client_connection_id,
+                             const QuicConnectionId& server_connection_id,
+                             bool update_connection_id);
+    ~ScopedPeerAddressContext();
+
+   private:
+    QuicPacketCreator* creator_;
+    QuicSocketAddress old_peer_address_;
+    QuicConnectionId old_client_connection_id_;
+    QuicConnectionId old_server_connection_id_;
+    bool update_connection_id_;
+  };
+
+  QuicPacketCreator(QuicConnectionId server_connection_id,
+                    QuicFramer* framer,
+                    DelegateInterface* delegate);
+  QuicPacketCreator(QuicConnectionId server_connection_id,
+                    QuicFramer* framer,
+                    QuicRandom* random,
+                    DelegateInterface* delegate);
+  QuicPacketCreator(const QuicPacketCreator&) = delete;
+  QuicPacketCreator& operator=(const QuicPacketCreator&) = delete;
+
+  ~QuicPacketCreator();
+
+  // Makes the framer not serialize the protocol version in sent packets.
+  void StopSendingVersion();
+
+  // SetDiversificationNonce sets the nonce that will be sent in each public
+  // header of packets encrypted at the initial encryption level. Should only
+  // be called by servers.
+  void SetDiversificationNonce(const DiversificationNonce& nonce);
+
+  // Update the packet number length to use in future packets as soon as it
+  // can be safely changed.
+  // TODO(fayang): Directly set packet number length instead of compute it in
+  // creator.
+  void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
+                                QuicPacketCount max_packets_in_flight);
+
+  // Skip |count| packet numbers.
+  void SkipNPacketNumbers(QuicPacketCount count,
+                          QuicPacketNumber least_packet_awaited_by_peer,
+                          QuicPacketCount max_packets_in_flight);
+
+  // The overhead the framing will add for a packet with one frame.
+  static size_t StreamFramePacketOverhead(
+      QuicTransportVersion version,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length,
+      bool include_version,
+      bool include_diversification_nonce,
+      QuicPacketNumberLength packet_number_length,
+      QuicVariableLengthIntegerLength retry_token_length_length,
+      QuicVariableLengthIntegerLength length_length,
+      QuicStreamOffset offset);
+
+  // Returns false and flushes all pending frames if current open packet is
+  // full.
+  // If current packet is not full, creates a stream frame that fits into the
+  // open packet and adds it to the packet.
+  bool ConsumeDataToFillCurrentPacket(QuicStreamId id,
+                                      size_t data_size,
+                                      QuicStreamOffset offset,
+                                      bool fin,
+                                      bool needs_full_padding,
+                                      TransmissionType transmission_type,
+                                      QuicFrame* frame);
+
+  // Creates a CRYPTO frame that fits into the current packet (which must be
+  // empty) and adds it to the packet.
+  bool ConsumeCryptoDataToFillCurrentPacket(EncryptionLevel level,
+                                            size_t write_length,
+                                            QuicStreamOffset offset,
+                                            bool needs_full_padding,
+                                            TransmissionType transmission_type,
+                                            QuicFrame* frame);
+
+  // Returns true if current open packet can accommodate more stream frames of
+  // stream |id| at |offset| and data length |data_size|, false otherwise.
+  // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
+  bool HasRoomForStreamFrame(QuicStreamId id,
+                             QuicStreamOffset offset,
+                             size_t data_size);
+
+  // Returns true if current open packet can accommodate a message frame of
+  // |length|.
+  // TODO(fayang): mark this const by moving RemoveSoftMaxPacketLength out.
+  bool HasRoomForMessageFrame(QuicByteCount length);
+
+  // Serializes all added frames into a single packet and invokes the delegate_
+  // to further process the SerializedPacket.
+  void FlushCurrentPacket();
+
+  // Optimized method to create a QuicStreamFrame and serialize it. Adds the
+  // QuicStreamFrame to the returned SerializedPacket.  Sets
+  // |num_bytes_consumed| to the number of bytes consumed to create the
+  // QuicStreamFrame.
+  void CreateAndSerializeStreamFrame(QuicStreamId id,
+                                     size_t write_length,
+                                     QuicStreamOffset iov_offset,
+                                     QuicStreamOffset stream_offset,
+                                     bool fin,
+                                     TransmissionType transmission_type,
+                                     size_t* num_bytes_consumed);
+
+  // Returns true if there are frames pending to be serialized.
+  bool HasPendingFrames() const;
+
+  // TODO(haoyuewang) Remove this debug utility.
+  // Returns the information of pending frames as a string.
+  std::string GetPendingFramesInfo() const;
+
+  // Returns true if there are retransmittable frames pending to be serialized.
+  bool HasPendingRetransmittableFrames() const;
+
+  // Returns true if there are stream frames for |id| pending to be serialized.
+  bool HasPendingStreamFramesOfStream(QuicStreamId id) const;
+
+  // Returns the number of bytes which are available to be used by additional
+  // frames in the packet.  Since stream frames are slightly smaller when they
+  // are the last frame in a packet, this method will return a different
+  // value than max_packet_size - PacketSize(), in this case.
+  size_t BytesFree() const;
+
+  // Returns the number of bytes that the packet will expand by if a new frame
+  // is added to the packet. If the last frame was a stream frame, it will
+  // expand slightly when a new frame is added, and this method returns the
+  // amount of expected expansion.
+  size_t ExpansionOnNewFrame() const;
+
+  // Returns the number of bytes that the packet will expand by when a new frame
+  // is going to be added. |last_frame| is the last frame of the packet.
+  static size_t ExpansionOnNewFrameWithLastFrame(const QuicFrame& last_frame,
+                                                 QuicTransportVersion version);
+
+  // Returns the number of bytes in the current packet, including the header,
+  // if serialized with the current frames.  Adding a frame to the packet
+  // may change the serialized length of existing frames, as per the comment
+  // in BytesFree.
+  size_t PacketSize() const;
+
+  // Tries to add |frame| to the packet creator's list of frames to be
+  // serialized. If the frame does not fit into the current packet, flushes the
+  // packet and returns false.
+  bool AddFrame(const QuicFrame& frame, TransmissionType transmission_type);
+
+  // Identical to AddSavedFrame, but allows the frame to be padded.
+  bool AddPaddedSavedFrame(const QuicFrame& frame,
+                           TransmissionType transmission_type);
+
+  // Creates a connectivity probing packet for versions prior to version 99.
+  std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket();
+
+  // Create connectivity probing request and response packets using PATH
+  // CHALLENGE and PATH RESPONSE frames, respectively, for version 99/IETF QUIC.
+  // SerializePathChallengeConnectivityProbingPacket will pad the packet to be
+  // MTU bytes long.
+  std::unique_ptr<SerializedPacket>
+  SerializePathChallengeConnectivityProbingPacket(
+      const QuicPathFrameBuffer& payload);
+
+  // If |is_padded| is true then SerializePathResponseConnectivityProbingPacket
+  // will pad the packet to be MTU bytes long, else it will not pad the packet.
+  // |payloads| is cleared.
+  std::unique_ptr<SerializedPacket>
+  SerializePathResponseConnectivityProbingPacket(
+      const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+      const bool is_padded);
+
+  // Add PATH_RESPONSE to current packet, flush before or afterwards if needed.
+  bool AddPathResponseFrame(const QuicPathFrameBuffer& data_buffer);
+
+  // Add PATH_CHALLENGE to current packet, flush before or afterwards if needed.
+  // This is a best effort adding. It may fail becasue of delegate state, but
+  // it's okay because of path validation retry mechanism.
+  void AddPathChallengeFrame(const QuicPathFrameBuffer& payload);
+
+  // Returns a dummy packet that is valid but contains no useful information.
+  static SerializedPacket NoPacket();
+
+  // Returns the server connection ID to send over the wire.
+  const QuicConnectionId& GetServerConnectionId() const {
+    return server_connection_id_;
+  }
+
+  // Returns the client connection ID to send over the wire.
+  const QuicConnectionId& GetClientConnectionId() const {
+    return client_connection_id_;
+  }
+
+  // Returns the destination connection ID to send over the wire.
+  QuicConnectionId GetDestinationConnectionId() const;
+
+  // Returns the source connection ID to send over the wire.
+  QuicConnectionId GetSourceConnectionId() const;
+
+  // Returns length of destination connection ID to send over the wire.
+  QuicConnectionIdLength GetDestinationConnectionIdLength() const;
+
+  // Returns length of source connection ID to send over the wire.
+  QuicConnectionIdLength GetSourceConnectionIdLength() const;
+
+  // Sets whether the server connection ID should be sent over the wire.
+  void SetServerConnectionIdIncluded(
+      QuicConnectionIdIncluded server_connection_id_included);
+
+  // Update the server connection ID used in outgoing packets.
+  void SetServerConnectionId(QuicConnectionId server_connection_id);
+
+  // Update the client connection ID used in outgoing packets.
+  void SetClientConnectionId(QuicConnectionId client_connection_id);
+
+  // Sets the encryption level that will be applied to new packets.
+  void set_encryption_level(EncryptionLevel level);
+  EncryptionLevel encryption_level() { return packet_.encryption_level; }
+
+  // Sets whether initial packets are protected with chaos.
+  void set_chaos_protection_enabled(bool chaos_protection_enabled) {
+    chaos_protection_enabled_ = chaos_protection_enabled;
+  }
+
+  // packet number of the last created packet, or 0 if no packets have been
+  // created.
+  QuicPacketNumber packet_number() const { return packet_.packet_number; }
+
+  QuicByteCount max_packet_length() const { return max_packet_length_; }
+
+  bool has_ack() const { return packet_.has_ack; }
+
+  bool has_stop_waiting() const { return packet_.has_stop_waiting; }
+
+  // Sets the encrypter to use for the encryption level and updates the max
+  // plaintext size.
+  void SetEncrypter(EncryptionLevel level,
+                    std::unique_ptr<QuicEncrypter> encrypter);
+
+  // Indicates whether the packet creator is in a state where it can change
+  // current maximum packet length.
+  bool CanSetMaxPacketLength() const;
+
+  // Sets the maximum packet length.
+  void SetMaxPacketLength(QuicByteCount length);
+
+  // Sets the maximum DATAGRAM/MESSAGE frame size we can send.
+  void SetMaxDatagramFrameSize(QuicByteCount max_datagram_frame_size);
+
+  // Set a soft maximum packet length in the creator. If a packet cannot be
+  // successfully created, creator will remove the soft limit and use the actual
+  // max packet length.
+  void SetSoftMaxPacketLength(QuicByteCount length);
+
+  // Increases pending_padding_bytes by |size|. Pending padding will be sent by
+  // MaybeAddPadding().
+  void AddPendingPadding(QuicByteCount size);
+
+  // Sets the retry token to be sent over the wire in IETF Initial packets.
+  void SetRetryToken(absl::string_view retry_token);
+
+  // Consumes retransmittable control |frame|. Returns true if the frame is
+  // successfully consumed. Returns false otherwise.
+  bool ConsumeRetransmittableControlFrame(const QuicFrame& frame);
+
+  // Given some data, may consume part or all of it and pass it to the
+  // packet creator to be serialized into packets. If not in batch
+  // mode, these packets will also be sent during this call.
+  // When |state| is FIN_AND_PADDING, random padding of size [1, 256] will be
+  // added after stream frames. If current constructed packet cannot
+  // accommodate, the padding will overflow to the next packet(s).
+  QuicConsumedData ConsumeData(QuicStreamId id,
+                               size_t write_length,
+                               QuicStreamOffset offset,
+                               StreamSendingState state);
+
+  // Sends as many data only packets as allowed by the send algorithm and the
+  // available iov.
+  // This path does not support padding, or bundling pending frames.
+  // In case we access this method from ConsumeData, total_bytes_consumed
+  // keeps track of how many bytes have already been consumed.
+  QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
+                                       size_t write_length,
+                                       QuicStreamOffset offset,
+                                       bool fin,
+                                       size_t total_bytes_consumed);
+
+  // Consumes data for CRYPTO frames sent at |level| starting at |offset| for a
+  // total of |write_length| bytes, and returns the number of bytes consumed.
+  // The data is passed into the packet creator and serialized into one or more
+  // packets.
+  size_t ConsumeCryptoData(EncryptionLevel level,
+                           size_t write_length,
+                           QuicStreamOffset offset);
+
+  // Generates an MTU discovery packet of specified size.
+  void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);
+
+  // Called when there is data to be sent, Retrieves updated ACK frame from
+  // delegate_ and flushes it.
+  void MaybeBundleAckOpportunistically();
+
+  // Called to flush ACK and STOP_WAITING frames, returns false if the flush
+  // fails.
+  bool FlushAckFrame(const QuicFrames& frames);
+
+  // Adds a random amount of padding (between 1 to 256 bytes).
+  void AddRandomPadding();
+
+  // Attaches packet flusher.
+  void AttachPacketFlusher();
+
+  // Flushes everything, including current open packet and pending padding.
+  void Flush();
+
+  // Sends remaining pending padding.
+  // Pending paddings should only be sent when there is nothing else to send.
+  void SendRemainingPendingPadding();
+
+  // Set the minimum number of bytes for the server connection id length;
+  void SetServerConnectionIdLength(uint32_t length);
+
+  // Set transmission type of next constructed packets.
+  void SetTransmissionType(TransmissionType type);
+
+  // Tries to add a message frame containing |message| and returns the status.
+  MessageStatus AddMessageFrame(QuicMessageId message_id,
+                                absl::Span<quiche::QuicheMemSlice> message);
+
+  // Returns the largest payload that will fit into a single MESSAGE frame.
+  QuicPacketLength GetCurrentLargestMessagePayload() const;
+  // Returns the largest payload that will fit into a single MESSAGE frame at
+  // any point during the connection.  This assumes the version and
+  // connection ID lengths do not change.
+  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
+
+  // Packet number of next created packet.
+  QuicPacketNumber NextSendingPacketNumber() const;
+
+  void set_debug_delegate(DebugDelegate* debug_delegate) {
+    debug_delegate_ = debug_delegate;
+  }
+
+  QuicByteCount pending_padding_bytes() const { return pending_padding_bytes_; }
+
+  ParsedQuicVersion version() const { return framer_->version(); }
+
+  QuicTransportVersion transport_version() const {
+    return framer_->transport_version();
+  }
+
+  // Returns the minimum size that the plaintext of a packet must be.
+  static size_t MinPlaintextPacketSize(const ParsedQuicVersion& version);
+
+  // Indicates whether packet flusher is currently attached.
+  bool PacketFlusherAttached() const;
+
+  void set_fully_pad_crypto_handshake_packets(bool new_value) {
+    fully_pad_crypto_handshake_packets_ = new_value;
+  }
+
+  bool fully_pad_crypto_handshake_packets() const {
+    return fully_pad_crypto_handshake_packets_;
+  }
+
+  // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also
+  // fills the packet with padding.
+  size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header,
+                                        char* buffer,
+                                        size_t packet_length,
+                                        const QuicPathFrameBuffer& payload,
+                                        EncryptionLevel level);
+
+  // Serialize a probing response packet that uses IETF QUIC's PATH RESPONSE
+  // frame. Also fills the packet with padding if |is_padded| is
+  // true. |payloads| is always emptied, even if the packet can not be
+  // successfully built.
+  size_t BuildPathResponsePacket(
+      const QuicPacketHeader& header,
+      char* buffer,
+      size_t packet_length,
+      const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
+      const bool is_padded,
+      EncryptionLevel level);
+
+  // Serializes a probing packet, which is a padded PING packet. Returns the
+  // length of the packet. Returns 0 if it fails to serialize.
+  size_t BuildConnectivityProbingPacket(const QuicPacketHeader& header,
+                                        char* buffer,
+                                        size_t packet_length,
+                                        EncryptionLevel level);
+
+  // Serializes |coalesced| to provided |buffer|, returns coalesced packet
+  // length if serialization succeeds. Otherwise, returns 0.
+  size_t SerializeCoalescedPacket(const QuicCoalescedPacket& coalesced,
+                                  char* buffer,
+                                  size_t buffer_len);
+
+  // Returns true if max_packet_length_ is currently a soft value.
+  bool HasSoftMaxPacketLength() const;
+
+  // Use this address to sent to the peer from now on. If this address is
+  // different from the current one, flush all the queue frames first.
+  void SetDefaultPeerAddress(QuicSocketAddress address);
+
+  // Return true if retry_token_ is not empty.
+  bool HasRetryToken() const;
+
+  const QuicSocketAddress& peer_address() const { return packet_.peer_address; }
+
+  bool close_connection_if_fail_to_serialzie_coalesced_packet() const {
+    return close_connection_if_fail_to_serialzie_coalesced_packet_;
+  }
+
+ private:
+  friend class test::QuicPacketCreatorPeer;
+
+  // Used to 1) clear queued_frames_, 2) report unrecoverable error (if
+  // serialization fails) upon exiting the scope.
+  class QUIC_EXPORT_PRIVATE ScopedSerializationFailureHandler {
+   public:
+    explicit ScopedSerializationFailureHandler(QuicPacketCreator* creator);
+    ~ScopedSerializationFailureHandler();
+
+   private:
+    QuicPacketCreator* creator_;  // Unowned.
+  };
+
+  // Attempts to build a data packet with chaos protection. If this packet isn't
+  // supposed to be protected or if serialization fails then absl::nullopt is
+  // returned. Otherwise returns the serialized length.
+  absl::optional<size_t> MaybeBuildDataPacketWithChaosProtection(
+      const QuicPacketHeader& header,
+      char* buffer);
+
+  // Creates a stream frame which fits into the current open packet. If
+  // |data_size| is 0 and fin is true, the expected behavior is to consume
+  // the fin.
+  void CreateStreamFrame(QuicStreamId id,
+                         size_t data_size,
+                         QuicStreamOffset offset,
+                         bool fin,
+                         QuicFrame* frame);
+
+  // Creates a CRYPTO frame which fits into the current open packet. Returns
+  // false if there isn't enough room in the current open packet for a CRYPTO
+  // frame, and true if there is.
+  bool CreateCryptoFrame(EncryptionLevel level,
+                         size_t write_length,
+                         QuicStreamOffset offset,
+                         QuicFrame* frame);
+
+  void FillPacketHeader(QuicPacketHeader* header);
+
+  // Adds a padding frame to the current packet (if there is space) when (1)
+  // current packet needs full padding or (2) there are pending paddings.
+  void MaybeAddPadding();
+
+  // Serializes all frames which have been added and adds any which should be
+  // retransmitted to packet_.retransmittable_frames. All frames must fit into
+  // a single packet. Returns true on success, otherwise, returns false.
+  // Fails if |encrypted_buffer| is not large enough for the encrypted packet.
+  //
+  // Padding may be added if |allow_padding|. Currently, the only case where it
+  // is disallowed is reserializing a coalesced initial packet.
+  ABSL_MUST_USE_RESULT bool SerializePacket(
+      QuicOwnedPacketBuffer encrypted_buffer, size_t encrypted_buffer_len,
+      bool allow_padding);
+
+  // Called after a new SerialiedPacket is created to call the delegate's
+  // OnSerializedPacket and reset state.
+  void OnSerializedPacket();
+
+  // Clears all fields of packet_ that should be cleared between serializations.
+  void ClearPacket();
+
+  // Re-serialzes frames of ENCRYPTION_INITIAL packet in coalesced packet with
+  // the original packet's packet number and packet number length.
+  // |padding_size| indicates the size of necessary padding. Returns 0 if
+  // serialization fails.
+  size_t ReserializeInitialPacketInCoalescedPacket(
+      const SerializedPacket& packet,
+      size_t padding_size,
+      char* buffer,
+      size_t buffer_len);
+
+  // Tries to coalesce |frame| with the back of |queued_frames_|.
+  // Returns true on success.
+  bool MaybeCoalesceStreamFrame(const QuicStreamFrame& frame);
+
+  // Called to remove the soft max_packet_length and restores
+  // latched_hard_max_packet_length_ if the packet cannot accommodate a single
+  // frame. Returns true if the soft limit is successfully removed. Returns
+  // false if either there is no current soft limit or there are queued frames
+  // (such that the packet length cannot be changed).
+  bool RemoveSoftMaxPacketLength();
+
+  // Returns true if a diversification nonce should be included in the current
+  // packet's header.
+  bool IncludeNonceInPublicHeader() const;
+
+  // Returns true if version should be included in current packet's header.
+  bool IncludeVersionInHeader() const;
+
+  // Returns length of packet number to send over the wire.
+  // packet_.packet_number_length should never be read directly, use this
+  // function instead.
+  QuicPacketNumberLength GetPacketNumberLength() const;
+
+  // Returns the size in bytes of the packet header.
+  size_t PacketHeaderSize() const;
+
+  // Returns whether the destination connection ID is sent over the wire.
+  QuicConnectionIdIncluded GetDestinationConnectionIdIncluded() const;
+
+  // Returns whether the source connection ID is sent over the wire.
+  QuicConnectionIdIncluded GetSourceConnectionIdIncluded() const;
+
+  // Returns length of the retry token variable length integer to send over the
+  // wire. Is non-zero for v99 IETF Initial packets.
+  QuicVariableLengthIntegerLength GetRetryTokenLengthLength() const;
+
+  // Returns the retry token to send over the wire, only sent in
+  // v99 IETF Initial packets.
+  absl::string_view GetRetryToken() const;
+
+  // Returns length of the length variable length integer to send over the
+  // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets.
+  QuicVariableLengthIntegerLength GetLengthLength() const;
+
+  // Returns true if |frame| is a ClientHello.
+  bool StreamFrameIsClientHello(const QuicStreamFrame& frame) const;
+
+  // Returns true if packet under construction has IETF long header.
+  bool HasIetfLongHeader() const;
+
+  // Get serialized frame length. Returns 0 if the frame does not fit into
+  // current packet.
+  size_t GetSerializedFrameLength(const QuicFrame& frame);
+
+  // Add extra padding to pending_padding_bytes_ to meet minimum plaintext
+  // packet size required for header protection.
+  void MaybeAddExtraPaddingForHeaderProtection();
+
+  // Returns true and close connection if it attempts to send unencrypted data.
+  bool AttemptingToSendUnencryptedStreamData();
+
+  // Add the given frame to the current packet with full padding. If the current
+  // packet doesn't have enough space, flush once and try again. Return false if
+  // fail to add.
+  bool AddPaddedFrameWithRetry(const QuicFrame& frame);
+
+  // Does not own these delegates or the framer.
+  DelegateInterface* delegate_;
+  DebugDelegate* debug_delegate_;
+  QuicFramer* framer_;
+  QuicRandom* random_;
+
+  // Controls whether version should be included while serializing the packet.
+  // send_version_in_packet_ should never be read directly, use
+  // IncludeVersionInHeader() instead.
+  bool send_version_in_packet_;
+  // If true, then |diversification_nonce_| will be included in the header of
+  // all packets created at the initial encryption level.
+  bool have_diversification_nonce_;
+  DiversificationNonce diversification_nonce_;
+  // Maximum length including headers and encryption (UDP payload length.)
+  QuicByteCount max_packet_length_;
+  size_t max_plaintext_size_;
+  // Whether the server_connection_id is sent over the wire.
+  QuicConnectionIdIncluded server_connection_id_included_;
+
+  // Frames to be added to the next SerializedPacket
+  QuicFrames queued_frames_;
+
+  // Serialization size of header + frames. If there is no queued frames,
+  // packet_size_ is 0.
+  // TODO(ianswett): Move packet_size_ into SerializedPacket once
+  // QuicEncryptedPacket has been flattened into SerializedPacket.
+  size_t packet_size_;
+  QuicConnectionId server_connection_id_;
+  QuicConnectionId client_connection_id_;
+
+  // Packet used to invoke OnSerializedPacket.
+  SerializedPacket packet_;
+
+  // Retry token to send over the wire in v99 IETF Initial packets.
+  std::string retry_token_;
+
+  // Pending padding bytes to send. Pending padding bytes will be sent in next
+  // packet(s) (after all other frames) if current constructed packet does not
+  // have room to send all of them.
+  QuicByteCount pending_padding_bytes_;
+
+  // Indicates whether current constructed packet needs full padding to max
+  // packet size. Please note, full padding does not consume pending padding
+  // bytes.
+  bool needs_full_padding_;
+
+  // Transmission type of the next serialized packet.
+  TransmissionType next_transmission_type_;
+
+  // True if packet flusher is currently attached.
+  bool flusher_attached_;
+
+  // Whether crypto handshake packets should be fully padded.
+  bool fully_pad_crypto_handshake_packets_;
+
+  // Packet number of the first packet of a write operation. This gets set
+  // when the out-most flusher attaches and gets cleared when the out-most
+  // flusher detaches.
+  QuicPacketNumber write_start_packet_number_;
+
+  // If not 0, this latches the actual max_packet_length when
+  // SetSoftMaxPacketLength is called and max_packet_length_ gets
+  // set to a soft value.
+  QuicByteCount latched_hard_max_packet_length_;
+
+  // The maximum length of a MESSAGE/DATAGRAM frame that our peer is willing to
+  // accept. There is no limit for QUIC_CRYPTO connections, but QUIC+TLS
+  // negotiates this during the handshake.
+  QuicByteCount max_datagram_frame_size_;
+
+  // Whether to attempt protecting initial packets with chaos.
+  bool chaos_protection_enabled_;
+
+  const bool close_connection_if_fail_to_serialzie_coalesced_packet_ =
+      GetQuicReloadableFlag(
+          quic_close_connection_if_fail_to_serialzie_coalesced_packet2);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
diff --git a/quiche/quic/core/quic_packet_creator_test.cc b/quiche/quic/core/quic_packet_creator_test.cc
new file mode 100644
index 0000000..7bbd237
--- /dev/null
+++ b/quiche/quic/core/quic_packet_creator_test.cc
@@ -0,0 +1,3937 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packet_creator.h"
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
+// Use fields in which each byte is distinct to ensure that every byte is
+// framed correctly. The values are otherwise arbitrary.
+QuicConnectionId CreateTestConnectionId() {
+  return TestConnectionId(UINT64_C(0xFEDCBA9876543210));
+}
+
+// Run tests with combinations of {ParsedQuicVersion,
+// ToggleVersionSerialization}.
+struct TestParams {
+  TestParams(ParsedQuicVersion version, bool version_serialization)
+      : version(version), version_serialization(version_serialization) {}
+
+  ParsedQuicVersion version;
+  bool version_serialization;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(ParsedQuicVersionToString(p.version), "_",
+                      (p.version_serialization ? "Include" : "No"), "Version");
+}
+
+// Constructs various test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+  for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+    params.push_back(TestParams(all_supported_versions[i], true));
+    params.push_back(TestParams(all_supported_versions[i], false));
+  }
+  return params;
+}
+
+class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
+ public:
+  ~MockDebugDelegate() override = default;
+
+  MOCK_METHOD(void, OnFrameAddedToPacket, (const QuicFrame& frame), (override));
+
+  MOCK_METHOD(void,
+              OnStreamFrameCoalesced,
+              (const QuicStreamFrame& frame),
+              (override));
+};
+
+class TestPacketCreator : public QuicPacketCreator {
+ public:
+  TestPacketCreator(QuicConnectionId connection_id,
+                    QuicFramer* framer,
+                    DelegateInterface* delegate,
+                    SimpleDataProducer* producer)
+      : QuicPacketCreator(connection_id, framer, delegate),
+        producer_(producer),
+        version_(framer->version()) {}
+
+  bool ConsumeDataToFillCurrentPacket(QuicStreamId id, absl::string_view data,
+                                      QuicStreamOffset offset, bool fin,
+                                      bool needs_full_padding,
+                                      TransmissionType transmission_type,
+                                      QuicFrame* frame) {
+    // Save data before data is consumed.
+    if (!data.empty()) {
+      producer_->SaveStreamData(id, data);
+    }
+    return QuicPacketCreator::ConsumeDataToFillCurrentPacket(
+        id, data.length(), offset, fin, needs_full_padding, transmission_type,
+        frame);
+  }
+
+  void StopSendingVersion() {
+    if (version_.HasIetfInvariantHeader()) {
+      set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+      return;
+    }
+    QuicPacketCreator::StopSendingVersion();
+  }
+
+  SimpleDataProducer* producer_;
+  ParsedQuicVersion version_;
+};
+
+class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
+ public:
+  void ClearSerializedPacketForTests(SerializedPacket /*serialized_packet*/) {
+    // serialized packet self-clears on destruction.
+  }
+
+  void SaveSerializedPacket(SerializedPacket serialized_packet) {
+    serialized_packet_.reset(CopySerializedPacket(
+        serialized_packet, &allocator_, /*copy_buffer=*/true));
+  }
+
+  void DeleteSerializedPacket() { serialized_packet_ = nullptr; }
+
+ protected:
+  QuicPacketCreatorTest()
+      : connection_id_(TestConnectionId(2)),
+        server_framer_(SupportedVersions(GetParam().version),
+                       QuicTime::Zero(),
+                       Perspective::IS_SERVER,
+                       connection_id_.length()),
+        client_framer_(SupportedVersions(GetParam().version),
+                       QuicTime::Zero(),
+                       Perspective::IS_CLIENT,
+                       connection_id_.length()),
+        data_("foo"),
+        creator_(connection_id_, &client_framer_, &delegate_, &producer_) {
+    EXPECT_CALL(delegate_, GetPacketBuffer())
+        .WillRepeatedly(Return(QuicPacketBuffer()));
+    EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
+        .WillRepeatedly(Return(SEND_TO_WRITER));
+    creator_.SetEncrypter(ENCRYPTION_INITIAL, std::make_unique<NullEncrypter>(
+                                                  Perspective::IS_CLIENT));
+    creator_.SetEncrypter(ENCRYPTION_HANDSHAKE, std::make_unique<NullEncrypter>(
+                                                    Perspective::IS_CLIENT));
+    creator_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
+                                                   Perspective::IS_CLIENT));
+    creator_.SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+    client_framer_.set_visitor(&framer_visitor_);
+    server_framer_.set_visitor(&framer_visitor_);
+    client_framer_.set_data_producer(&producer_);
+    if (server_framer_.version().KnowsWhichDecrypterToUse()) {
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_INITIAL,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_ZERO_RTT,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_HANDSHAKE,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+      server_framer_.InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+    } else {
+      server_framer_.SetDecrypter(
+          ENCRYPTION_INITIAL,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+    }
+  }
+
+  ~QuicPacketCreatorTest() override {}
+
+  SerializedPacket SerializeAllFrames(const QuicFrames& frames) {
+    SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
+        &creator_, frames, buffer_, kMaxOutgoingPacketSize);
+    EXPECT_EQ(QuicPacketCreatorPeer::GetEncryptionLevel(&creator_),
+              packet.encryption_level);
+    return packet;
+  }
+
+  void ProcessPacket(const SerializedPacket& packet) {
+    QuicEncryptedPacket encrypted_packet(packet.encrypted_buffer,
+                                         packet.encrypted_length);
+    server_framer_.ProcessPacket(encrypted_packet);
+  }
+
+  void CheckStreamFrame(const QuicFrame& frame,
+                        QuicStreamId stream_id,
+                        const std::string& data,
+                        QuicStreamOffset offset,
+                        bool fin) {
+    EXPECT_EQ(STREAM_FRAME, frame.type);
+    EXPECT_EQ(stream_id, frame.stream_frame.stream_id);
+    char buf[kMaxOutgoingPacketSize];
+    QuicDataWriter writer(kMaxOutgoingPacketSize, buf, quiche::HOST_BYTE_ORDER);
+    if (frame.stream_frame.data_length > 0) {
+      producer_.WriteStreamData(stream_id, frame.stream_frame.offset,
+                                frame.stream_frame.data_length, &writer);
+    }
+    EXPECT_EQ(data, absl::string_view(buf, frame.stream_frame.data_length));
+    EXPECT_EQ(offset, frame.stream_frame.offset);
+    EXPECT_EQ(fin, frame.stream_frame.fin);
+  }
+
+  // Returns the number of bytes consumed by the header of packet, including
+  // the version.
+  size_t GetPacketHeaderOverhead(QuicTransportVersion version) {
+    return GetPacketHeaderSize(
+        version, creator_.GetDestinationConnectionIdLength(),
+        creator_.GetSourceConnectionIdLength(),
+        QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+        !kIncludeDiversificationNonce,
+        QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+        QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
+        QuicPacketCreatorPeer::GetLengthLength(&creator_));
+  }
+
+  // Returns the number of bytes of overhead that will be added to a packet
+  // of maximum length.
+  size_t GetEncryptionOverhead() {
+    return creator_.max_packet_length() -
+           client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
+  }
+
+  // Returns the number of bytes consumed by the non-data fields of a stream
+  // frame, assuming it is the last frame in the packet
+  size_t GetStreamFrameOverhead(QuicTransportVersion version) {
+    return QuicFramer::GetMinStreamFrameSize(
+        version, GetNthClientInitiatedStreamId(1), kOffset, true,
+        /* data_length= */ 0);
+  }
+
+  bool IsDefaultTestConfiguration() {
+    TestParams p = GetParam();
+    return p.version == AllSupportedVersions()[0] && p.version_serialization;
+  }
+
+  QuicStreamId GetNthClientInitiatedStreamId(int n) const {
+    return QuicUtils::GetFirstBidirectionalStreamId(
+               creator_.transport_version(), Perspective::IS_CLIENT) +
+           n * 2;
+  }
+
+  void TestChaosProtection(bool enabled);
+
+  static constexpr QuicStreamOffset kOffset = 0u;
+
+  char buffer_[kMaxOutgoingPacketSize];
+  QuicConnectionId connection_id_;
+  QuicFrames frames_;
+  QuicFramer server_framer_;
+  QuicFramer client_framer_;
+  StrictMock<MockFramerVisitor> framer_visitor_;
+  StrictMock<MockPacketCreatorDelegate> delegate_;
+  std::string data_;
+  TestPacketCreator creator_;
+  std::unique_ptr<SerializedPacket> serialized_packet_;
+  SimpleDataProducer producer_;
+  quiche::SimpleBufferAllocator allocator_;
+};
+
+// Run all packet creator tests with all supported versions of QUIC, and with
+// and without version in the packet header, as well as doing a run for each
+// length of truncated connection id.
+INSTANTIATE_TEST_SUITE_P(QuicPacketCreatorTests,
+                         QuicPacketCreatorTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicPacketCreatorTest, SerializeFrames) {
+  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    EncryptionLevel level = static_cast<EncryptionLevel>(i);
+    creator_.set_encryption_level(level);
+    if (level != ENCRYPTION_ZERO_RTT) {
+      frames_.push_back(QuicFrame(new QuicAckFrame(InitAckFrame(1))));
+    }
+    QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        client_framer_.transport_version(), Perspective::IS_CLIENT);
+    if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
+      frames_.push_back(QuicFrame(
+          QuicStreamFrame(stream_id, false, 0u, absl::string_view())));
+    }
+    SerializedPacket serialized = SerializeAllFrames(frames_);
+    EXPECT_EQ(level, serialized.encryption_level);
+    if (level != ENCRYPTION_ZERO_RTT) {
+      delete frames_[0].ack_frame;
+    }
+    frames_.clear();
+
+    {
+      InSequence s;
+      EXPECT_CALL(framer_visitor_, OnPacket());
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+      if (level != ENCRYPTION_ZERO_RTT) {
+        EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
+            .WillOnce(Return(true));
+        EXPECT_CALL(framer_visitor_,
+                    OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
+            .WillOnce(Return(true));
+        EXPECT_CALL(framer_visitor_, OnAckFrameEnd(QuicPacketNumber(1)))
+            .WillOnce(Return(true));
+      }
+      if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
+        EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+      }
+      if (client_framer_.version().HasHeaderProtection()) {
+        EXPECT_CALL(framer_visitor_, OnPaddingFrame(_))
+            .Times(testing::AnyNumber());
+      }
+      EXPECT_CALL(framer_visitor_, OnPacketComplete());
+    }
+    ProcessPacket(serialized);
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) {
+  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
+      creator_.transport_version(), QUIC_NO_ERROR, NO_IETF_QUIC_ERROR, "error",
+      /*transport_close_frame_type=*/0);
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame));
+  SerializedPacket serialized = SerializeAllFrames(frames);
+  EXPECT_EQ(ENCRYPTION_INITIAL, serialized.encryption_level);
+  ASSERT_EQ(QuicPacketNumber(1u), serialized.packet_number);
+  ASSERT_EQ(QuicPacketNumber(1u), creator_.packet_number());
+
+  InSequence s;
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  EXPECT_CALL(framer_visitor_, OnConnectionCloseFrame(_));
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+
+  ProcessPacket(serialized);
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeCryptoDataToFillCurrentPacket) {
+  std::string data = "crypto data";
+  QuicFrame frame;
+  ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+      ENCRYPTION_INITIAL, data.length(), 0,
+      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+  EXPECT_EQ(frame.crypto_frame->data_length, data.length());
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataToFillCurrentPacket) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(4u, consumed);
+  CheckStreamFrame(frame, stream_id, "test", 0u, false);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataFin) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, true, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(4u, consumed);
+  CheckStreamFrame(frame, stream_id, "test", 0u, true);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataFinOnly) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, {}, 0u, true, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(0u, consumed);
+  CheckStreamFrame(frame, stream_id, std::string(), 0u, true);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(absl::StartsWith(creator_.GetPendingFramesInfo(),
+                               "type { STREAM_FRAME }"));
+}
+
+TEST_P(QuicPacketCreatorTest, CreateAllFreeBytesForStreamFrames) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead();
+  for (size_t i = overhead + QuicPacketCreator::MinPlaintextPacketSize(
+                                 client_framer_.version());
+       i < overhead + 100; ++i) {
+    SCOPED_TRACE(i);
+    creator_.SetMaxPacketLength(i);
+    const bool should_have_room =
+        i >
+        overhead + GetStreamFrameOverhead(client_framer_.transport_version());
+    ASSERT_EQ(should_have_room,
+              creator_.HasRoomForStreamFrame(GetNthClientInitiatedStreamId(1),
+                                             kOffset, /* data_size=*/0xffff));
+    if (should_have_room) {
+      QuicFrame frame;
+      const std::string data("testdata");
+      EXPECT_CALL(delegate_, OnSerializedPacket(_))
+          .WillRepeatedly(Invoke(
+              this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
+      ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+          GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
+          NOT_RETRANSMISSION, &frame));
+      size_t bytes_consumed = frame.stream_frame.data_length;
+      EXPECT_LT(0u, bytes_consumed);
+      creator_.FlushCurrentPacket();
+    }
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, StreamFrameConsumption) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  // Compute the total overhead for a single frame in packet.
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead() +
+      GetStreamFrameOverhead(client_framer_.transport_version());
+  size_t capacity = kDefaultMaxPacketSize - overhead;
+  // Now, test various sizes around this size.
+  for (int delta = -5; delta <= 5; ++delta) {
+    std::string data(capacity + delta, 'A');
+    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
+    QuicFrame frame;
+    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+        GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
+        NOT_RETRANSMISSION, &frame));
+
+    // BytesFree() returns bytes available for the next frame, which will
+    // be two bytes smaller since the stream frame would need to be grown.
+    EXPECT_EQ(2u, creator_.ExpansionOnNewFrame());
+    size_t expected_bytes_free = bytes_free < 3 ? 0 : bytes_free - 2;
+    EXPECT_EQ(expected_bytes_free, creator_.BytesFree()) << "delta: " << delta;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+    creator_.FlushCurrentPacket();
+    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+    DeleteSerializedPacket();
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, CryptoStreamFramePacketPadding) {
+  // This test serializes crypto payloads slightly larger than a packet, which
+  // Causes the multi-packet ClientHello check to fail.
+  SetQuicFlag(FLAGS_quic_enforce_single_packet_chlo, false);
+  // Compute the total overhead for a single frame in packet.
+  size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead();
+  if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    overhead +=
+        QuicFramer::GetMinCryptoFrameSize(kOffset, kMaxOutgoingPacketSize);
+  } else {
+    overhead += GetStreamFrameOverhead(client_framer_.transport_version());
+  }
+  ASSERT_GT(kMaxOutgoingPacketSize, overhead);
+  size_t capacity = kDefaultMaxPacketSize - overhead;
+  // Now, test various sizes around this size.
+  for (int delta = -5; delta <= 5; ++delta) {
+    SCOPED_TRACE(delta);
+    std::string data(capacity + delta, 'A');
+    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
+
+    QuicFrame frame;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillRepeatedly(
+            Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+    if (client_framer_.version().CanSendCoalescedPackets()) {
+      EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
+          .WillRepeatedly(Return(COALESCE));
+    }
+    if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+      ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+          QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+          data, kOffset, false, true, NOT_RETRANSMISSION, &frame));
+      size_t bytes_consumed = frame.stream_frame.data_length;
+      EXPECT_LT(0u, bytes_consumed);
+    } else {
+      producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
+      ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+          ENCRYPTION_INITIAL, data.length(), kOffset,
+          /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+      size_t bytes_consumed = frame.crypto_frame->data_length;
+      EXPECT_LT(0u, bytes_consumed);
+    }
+    creator_.FlushCurrentPacket();
+    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+    // If there is not enough space in the packet to fit a padding frame
+    // (1 byte) and to expand the stream frame (another 2 bytes) the packet
+    // will not be padded.
+    // Padding is skipped when we try to send coalesced packets.
+    if ((bytes_free < 3 &&
+         !QuicVersionUsesCryptoFrames(client_framer_.transport_version())) ||
+        client_framer_.version().CanSendCoalescedPackets()) {
+      EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
+                serialized_packet_->encrypted_length);
+    } else {
+      EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
+    }
+    DeleteSerializedPacket();
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  // Compute the total overhead for a single frame in packet.
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead() +
+      GetStreamFrameOverhead(client_framer_.transport_version());
+  ASSERT_GT(kDefaultMaxPacketSize, overhead);
+  size_t capacity = kDefaultMaxPacketSize - overhead;
+  // Now, test various sizes around this size.
+  for (int delta = -5; delta <= 5; ++delta) {
+    std::string data(capacity + delta, 'A');
+    size_t bytes_free = delta > 0 ? 0 : 0 - delta;
+
+    QuicFrame frame;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+        GetNthClientInitiatedStreamId(1), data, kOffset, false, false,
+        NOT_RETRANSMISSION, &frame));
+    size_t bytes_consumed = frame.stream_frame.data_length;
+    EXPECT_LT(0u, bytes_consumed);
+    creator_.FlushCurrentPacket();
+    ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+    if (bytes_free > 0) {
+      EXPECT_EQ(kDefaultMaxPacketSize - bytes_free,
+                serialized_packet_->encrypted_length);
+    } else {
+      EXPECT_EQ(kDefaultMaxPacketSize, serialized_packet_->encrypted_length);
+    }
+    DeleteSerializedPacket();
+  }
+}
+
+// Test that the path challenge connectivity probing packet is serialized
+// correctly as a padded PATH CHALLENGE packet.
+TEST_P(QuicPacketCreatorTest, BuildPathChallengePacket) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  MockRandom randomizer;
+  QuicPathFrameBuffer payload;
+  randomizer.RandBytes(payload.data(), payload.size());
+
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // Path Challenge Frame type (IETF_PATH_CHALLENGE)
+    0x1a,
+    // 8 "random" bytes, MockRandom makes lots of r's
+    'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r',
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+
+  size_t length = creator_.BuildPaddedPathChallengePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payload,
+      ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+
+  // Payload has the random bytes that were generated. Copy them into packet,
+  // above, before checking that the generated packet is correct.
+  EXPECT_EQ(kQuicPathFrameBufferSize, payload.size());
+
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildConnectivityProbingPacket) {
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+
+  // clang-format off
+  unsigned char packet[] = {
+    // public flags (8 byte connection_id)
+    0x2C,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (ping frame)
+    0x07,
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet46[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type
+    0x07,
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+
+  unsigned char packet99[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // frame type (IETF_PING frame)
+    0x01,
+    // frame type (padding frame)
+    0x00,
+    0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  unsigned char* p = packet;
+  size_t packet_size = ABSL_ARRAYSIZE(packet);
+  if (creator_.version().HasIetfQuicFrames()) {
+    p = packet99;
+    packet_size = ABSL_ARRAYSIZE(packet99);
+  } else if (creator_.version().HasIetfInvariantHeader()) {
+    p = packet46;
+    packet_size = ABSL_ARRAYSIZE(packet46);
+  }
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+
+  size_t length = creator_.BuildConnectivityProbingPacket(
+      header, buffer.get(), packet_size, ENCRYPTION_INITIAL);
+
+  EXPECT_NE(0u, length);
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(p), packet_size);
+}
+
+// Several tests that the path response connectivity probing packet is
+// serialized correctly as either a padded and unpadded PATH RESPONSE
+// packet. Also generates packets with 1 and 3 PATH_RESPONSES in them to
+// exercised the single- and multiple- payload cases.
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponseUnpadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+
+  // Build 1 PATH RESPONSE, not padded
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // Path Response Frame type (IETF_PATH_RESPONSE)
+    0x1b,
+    // 8 "random" bytes
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+  };
+  // clang-format on
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/false, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket1ResponsePadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+
+  // Build 1 PATH RESPONSE, padded
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // Path Response Frame type (IETF_PATH_RESPONSE)
+    0x1b,
+    // 8 "random" bytes
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    // Padding type and pad
+    0x00, 0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/true, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesUnpadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+  QuicPathFrameBuffer payload1 = {
+      {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
+  QuicPathFrameBuffer payload2 = {
+      {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
+
+  // Build one packet with 3 PATH RESPONSES, no padding
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // 3 path response frames (IETF_PATH_RESPONSE type byte and payload)
+    0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+    0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+  };
+  // clang-format on
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/false, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    // This frame is only for IETF QUIC.
+    return;
+  }
+
+  QuicPacketHeader header;
+  header.destination_connection_id = CreateTestConnectionId();
+  header.reset_flag = false;
+  header.version_flag = false;
+  header.packet_number = kPacketNumber;
+  QuicPathFrameBuffer payload0 = {
+      {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}};
+  QuicPathFrameBuffer payload1 = {
+      {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}};
+  QuicPathFrameBuffer payload2 = {
+      {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28}};
+
+  // Build one packet with 3 PATH RESPONSES, with padding
+  // clang-format off
+  unsigned char packet[] = {
+    // type (short header, 4 byte packet number)
+    0x43,
+    // connection_id
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    // packet number
+    0x12, 0x34, 0x56, 0x78,
+
+    // 3 path response frames (IETF_PATH_RESPONSE byte and payload)
+    0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x1b, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+    0x1b, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+    // Padding
+    0x00, 0x00, 0x00, 0x00, 0x00
+  };
+  // clang-format on
+
+  std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+  size_t length = creator_.BuildPathResponsePacket(
+      header, buffer.get(), ABSL_ARRAYSIZE(packet), payloads,
+      /*is_padded=*/true, ENCRYPTION_INITIAL);
+  EXPECT_EQ(length, ABSL_ARRAYSIZE(packet));
+  QuicPacket data(creator_.transport_version(), buffer.release(), length, true,
+                  header);
+
+  quiche::test::CompareCharArraysWithHexError(
+      "constructed packet", data.data(), data.length(),
+      reinterpret_cast<char*>(packet), ABSL_ARRAYSIZE(packet));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  std::unique_ptr<SerializedPacket> encrypted;
+  if (VersionHasIetfQuicFrames(creator_.transport_version())) {
+    QuicPathFrameBuffer payload = {
+        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+    encrypted =
+        creator_.SerializePathChallengeConnectivityProbingPacket(payload);
+  } else {
+    encrypted = creator_.SerializeConnectivityProbingPacket();
+  }
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    if (VersionHasIetfQuicFrames(creator_.transport_version())) {
+      EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    } else {
+      EXPECT_CALL(framer_visitor_, OnPingFrame(_));
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathChallengeConnectivityProbingPacket(payload));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest,
+       SerializePathResponseProbePacket1PayloadUnPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest,
+       SerializePathResponseProbePacket2PayloadsUnPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+  QuicPathFrameBuffer payload2 = {
+      {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest,
+       SerializePathResponseProbePacket3PayloadsUnpadded) {
+  if (!VersionHasIetfQuicFrames(creator_.transport_version())) {
+    return;
+  }
+  QuicPathFrameBuffer payload0 = {
+      {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
+  QuicPathFrameBuffer payload1 = {
+      {0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
+  QuicPathFrameBuffer payload2 = {
+      {0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  quiche::QuicheCircularDeque<QuicPathFrameBuffer> payloads;
+  payloads.push_back(payload0);
+  payloads.push_back(payload1);
+  payloads.push_back(payload2);
+
+  std::unique_ptr<SerializedPacket> encrypted(
+      creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+  InSequence s;
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+
+  server_framer_.ProcessPacket(QuicEncryptedPacket(
+      encrypted->encrypted_buffer, encrypted->encrypted_length));
+}
+
+TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
+  if (creator_.version().HasIetfInvariantHeader() &&
+      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
+    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  } else {
+    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+  }
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_,
+                                         UINT64_C(64) * 256 * 256 * 256 * 256);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
+  if (creator_.version().HasIetfInvariantHeader() &&
+      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
+    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  } else {
+    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+  }
+
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 * 256 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 * 256 * 256 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.UpdatePacketNumberLength(
+      QuicPacketNumber(1),
+      UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
+  EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, SkipNPacketNumbers) {
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
+  if (creator_.version().HasIetfInvariantHeader() &&
+      !GetParam().version.SendsVariableLengthPacketNumberInLongHeader()) {
+    EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  } else {
+    EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+              QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+  }
+  creator_.SkipNPacketNumbers(63, QuicPacketNumber(2),
+                              10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(QuicPacketNumber(64), creator_.packet_number());
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.SkipNPacketNumbers(64 * 255, QuicPacketNumber(2),
+                              10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(QuicPacketNumber(64 * 256), creator_.packet_number());
+  EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+
+  creator_.SkipNPacketNumbers(64 * 256 * 255, QuicPacketNumber(2),
+                              10000 / kDefaultMaxPacketSize);
+  EXPECT_EQ(QuicPacketNumber(64 * 256 * 256), creator_.packet_number());
+  EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
+            QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeFrame) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  std::string data("test data");
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    QuicStreamFrame stream_frame(
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+        /*fin=*/false, 0u, absl::string_view());
+    frames_.push_back(QuicFrame(stream_frame));
+  } else {
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
+    frames_.push_back(
+        QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
+  }
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+
+  QuicPacketHeader header;
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
+    if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+      EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
+    } else {
+      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(serialized);
+  EXPECT_EQ(GetParam().version_serialization, header.version_flag);
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeFrameShortData) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  std::string data("Hello World!");
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    QuicStreamFrame stream_frame(
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+        /*fin=*/false, 0u, absl::string_view());
+    frames_.push_back(QuicFrame(stream_frame));
+  } else {
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
+    frames_.push_back(
+        QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
+  }
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+
+  QuicPacketHeader header;
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
+    if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+      EXPECT_CALL(framer_visitor_, OnCryptoFrame(_));
+    } else {
+      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(serialized);
+  EXPECT_EQ(GetParam().version_serialization, header.version_flag);
+}
+
+void QuicPacketCreatorTest::TestChaosProtection(bool enabled) {
+  if (!GetParam().version.UsesCryptoFrames()) {
+    return;
+  }
+  MockRandom mock_random(2);
+  QuicPacketCreatorPeer::SetRandom(&creator_, &mock_random);
+  creator_.set_chaos_protection_enabled(enabled);
+  std::string data("ChAoS_ThEoRy!");
+  producer_.SaveCryptoData(ENCRYPTION_INITIAL, 0, data);
+  frames_.push_back(
+      QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, 0, data.length())));
+  frames_.push_back(QuicFrame(QuicPaddingFrame(33)));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  if (enabled) {
+    EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(AtLeast(2));
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(AtLeast(2));
+    EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(AtLeast(1));
+  } else {
+    EXPECT_CALL(framer_visitor_, OnCryptoFrame(_)).Times(1);
+    EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(1);
+    EXPECT_CALL(framer_visitor_, OnPingFrame(_)).Times(0);
+  }
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  ProcessPacket(serialized);
+}
+
+TEST_P(QuicPacketCreatorTest, ChaosProtectionEnabled) {
+  TestChaosProtection(/*enabled=*/true);
+}
+
+TEST_P(QuicPacketCreatorTest, ChaosProtectionDisabled) {
+  TestChaosProtection(/*enabled=*/false);
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  // A string larger than fits into a frame.
+  QuicFrame frame;
+  size_t payload_length = creator_.max_packet_length();
+  const std::string too_long_payload(payload_length, 'a');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, too_long_payload, 0u, true, false, NOT_RETRANSMISSION,
+      &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  // The entire payload could not be consumed.
+  EXPECT_GT(payload_length, consumed);
+  creator_.FlushCurrentPacket();
+  DeleteSerializedPacket();
+}
+
+TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  const size_t max_plaintext_size =
+      client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    stream_id =
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version());
+  }
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
+  EXPECT_EQ(max_plaintext_size -
+                GetPacketHeaderSize(
+                    client_framer_.transport_version(),
+                    creator_.GetDestinationConnectionIdLength(),
+                    creator_.GetSourceConnectionIdLength(),
+                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+                    !kIncludeDiversificationNonce,
+                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
+                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
+            creator_.BytesFree());
+  StrictMock<MockDebugDelegate> debug;
+  creator_.set_debug_delegate(&debug);
+
+  // Add a variety of frame types and then a padding frame.
+  QuicAckFrame ack_frame(InitAckFrame(10u));
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
+
+  QuicFrame frame;
+  const std::string data("test");
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  size_t consumed = frame.stream_frame.data_length;
+  EXPECT_EQ(4u, consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id));
+
+  QuicPaddingFrame padding_frame;
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(padding_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_EQ(0u, creator_.BytesFree());
+
+  // Packet is full. Creator will flush.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  EXPECT_FALSE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+
+  // Ensure the packet is successfully created.
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
+  const QuicFrames& retransmittable =
+      serialized_packet_->retransmittable_frames;
+  ASSERT_EQ(1u, retransmittable.size());
+  EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
+  EXPECT_TRUE(serialized_packet_->has_ack);
+  EXPECT_EQ(QuicPacketNumber(10u), serialized_packet_->largest_acked);
+  DeleteSerializedPacket();
+
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id));
+  EXPECT_EQ(max_plaintext_size -
+                GetPacketHeaderSize(
+                    client_framer_.transport_version(),
+                    creator_.GetDestinationConnectionIdLength(),
+                    creator_.GetSourceConnectionIdLength(),
+                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+                    !kIncludeDiversificationNonce,
+                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
+                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
+            creator_.BytesFree());
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  EXPECT_FALSE(creator_.HasPendingFrames());
+
+  const std::string data("test");
+  producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  size_t num_bytes_consumed;
+  StrictMock<MockDebugDelegate> debug;
+  creator_.set_debug_delegate(&debug);
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  creator_.CreateAndSerializeStreamFrame(
+      GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true,
+      NOT_RETRANSMISSION, &num_bytes_consumed);
+  EXPECT_EQ(4u, num_bytes_consumed);
+
+  // Ensure the packet is successfully created.
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
+  const QuicFrames& retransmittable =
+      serialized_packet_->retransmittable_frames;
+  ASSERT_EQ(1u, retransmittable.size());
+  EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
+  DeleteSerializedPacket();
+
+  EXPECT_FALSE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeStreamFrameWithPadding) {
+  // Regression test to check that CreateAndSerializeStreamFrame uses a
+  // correctly formatted stream frame header when appending padding.
+
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  EXPECT_FALSE(creator_.HasPendingFrames());
+
+  // Send one byte of stream data.
+  const std::string data("a");
+  producer_.SaveStreamData(GetNthClientInitiatedStreamId(0), data);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  size_t num_bytes_consumed;
+  creator_.CreateAndSerializeStreamFrame(
+      GetNthClientInitiatedStreamId(0), data.length(), 0, 0, true,
+      NOT_RETRANSMISSION, &num_bytes_consumed);
+  EXPECT_EQ(1u, num_bytes_consumed);
+
+  // Check that a packet is created.
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+  ASSERT_FALSE(serialized_packet_->retransmittable_frames.empty());
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    if (client_framer_.version().HasHeaderProtection()) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(*serialized_packet_);
+}
+
+TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  creator_.set_encryption_level(ENCRYPTION_INITIAL);
+  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+  QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
+                               /*fin=*/false, 0u, absl::string_view());
+  EXPECT_QUIC_BUG(
+      creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
+      "Cannot send stream data with level: ENCRYPTION_INITIAL");
+}
+
+TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
+  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+  QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
+                               /*fin=*/false, 0u, absl::string_view());
+  EXPECT_QUIC_BUG(
+      creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
+      "Cannot send stream data with level: ENCRYPTION_HANDSHAKE");
+}
+
+TEST_P(QuicPacketCreatorTest, ChloTooLarge) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (!IsDefaultTestConfiguration()) {
+    return;
+  }
+
+  // This test only matters when the crypto handshake is sent in stream frames.
+  // TODO(b/128596274): Re-enable when this check is supported for CRYPTO
+  // frames.
+  if (QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    return;
+  }
+
+  CryptoHandshakeMessage message;
+  message.set_tag(kCHLO);
+  message.set_minimum_size(kMaxOutgoingPacketSize);
+  CryptoFramer framer;
+  std::unique_ptr<QuicData> message_data;
+  message_data = framer.ConstructHandshakeMessage(message);
+
+  QuicFrame frame;
+  EXPECT_CALL(delegate_, OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, _));
+  EXPECT_QUIC_BUG(
+      creator_.ConsumeDataToFillCurrentPacket(
+          QuicUtils::GetCryptoStreamId(client_framer_.transport_version()),
+          absl::string_view(message_data->data(), message_data->length()), 0u,
+          false, false, NOT_RETRANSMISSION, &frame),
+      "Client hello won't fit in a single packet.");
+}
+
+TEST_P(QuicPacketCreatorTest, PendingPadding) {
+  EXPECT_EQ(0u, creator_.pending_padding_bytes());
+  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes * 10);
+  EXPECT_EQ(kMaxNumRandomPaddingBytes * 10, creator_.pending_padding_bytes());
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  // Flush all paddings.
+  while (creator_.pending_padding_bytes() > 0) {
+    creator_.FlushCurrentPacket();
+    {
+      InSequence s;
+      EXPECT_CALL(framer_visitor_, OnPacket());
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+      EXPECT_CALL(framer_visitor_, OnPacketComplete());
+    }
+    // Packet only contains padding.
+    ProcessPacket(*serialized_packet_);
+  }
+  EXPECT_EQ(0u, creator_.pending_padding_bytes());
+}
+
+TEST_P(QuicPacketCreatorTest, FullPaddingDoesNotConsumePendingPadding) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false,
+      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  creator_.FlushCurrentPacket();
+  EXPECT_EQ(kMaxNumRandomPaddingBytes, creator_.pending_padding_bytes());
+}
+
+TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  const QuicByteCount kStreamFramePayloadSize = 100u;
+  // Set the packet size be enough for one stream frame with 0 stream offset +
+  // 1.
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  size_t length =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      GetEncryptionOverhead() +
+      QuicFramer::GetMinStreamFrameSize(
+          client_framer_.transport_version(), stream_id, 0,
+          /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
+      kStreamFramePayloadSize + 1;
+  creator_.SetMaxPacketLength(length);
+  creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
+  QuicByteCount pending_padding_bytes = creator_.pending_padding_bytes();
+  QuicFrame frame;
+  char buf[kStreamFramePayloadSize + 1] = {};
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  // Send stream frame of size kStreamFramePayloadSize.
+  creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, absl::string_view(buf, kStreamFramePayloadSize), 0u, false,
+      false, NOT_RETRANSMISSION, &frame);
+  creator_.FlushCurrentPacket();
+  // 1 byte padding is sent.
+  EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
+  // Send stream frame of size kStreamFramePayloadSize + 1.
+  creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, absl::string_view(buf, kStreamFramePayloadSize + 1),
+      kStreamFramePayloadSize, false, false, NOT_RETRANSMISSION, &frame);
+  // No padding is sent.
+  creator_.FlushCurrentPacket();
+  EXPECT_EQ(pending_padding_bytes - 1, creator_.pending_padding_bytes());
+  // Flush all paddings.
+  while (creator_.pending_padding_bytes() > 0) {
+    creator_.FlushCurrentPacket();
+  }
+  EXPECT_EQ(0u, creator_.pending_padding_bytes());
+}
+
+TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  char* buffer = new char[kMaxOutgoingPacketSize];
+  QuicPacketBuffer external_buffer = {buffer,
+                                      [](const char* p) { delete[] p; }};
+  EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(external_buffer));
+
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false,
+      /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([&external_buffer](SerializedPacket serialized_packet) {
+        EXPECT_EQ(external_buffer.buffer, serialized_packet.encrypted_buffer);
+      }));
+  creator_.FlushCurrentPacket();
+}
+
+// Test for error found in
+// https://bugs.chromium.org/p/chromium/issues/detail?id=859949 where a gap
+// length that crosses an IETF VarInt length boundary would cause a
+// failure. While this test is not applicable to versions other than version 99,
+// it should still work. Hence, it is not made version-specific.
+TEST_P(QuicPacketCreatorTest, IetfAckGapErrorRegression) {
+  QuicAckFrame ack_frame =
+      InitAckFrame({{QuicPacketNumber(60), QuicPacketNumber(61)},
+                    {QuicPacketNumber(125), QuicPacketNumber(126)}});
+  frames_.push_back(QuicFrame(&ack_frame));
+  SerializeAllFrames(frames_);
+}
+
+TEST_P(QuicPacketCreatorTest, AddMessageFrame) {
+  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
+    return;
+  }
+  if (client_framer_.version().UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .Times(3)
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorTest::ClearSerializedPacketForTests));
+  // Verify that there is enough room for the largest message payload.
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetCurrentLargestMessagePayload()));
+  std::string large_message(creator_.GetCurrentLargestMessagePayload(), 'a');
+  QuicMessageFrame* message_frame =
+      new QuicMessageFrame(1, MemSliceFromString(large_message));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(message_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  creator_.FlushCurrentPacket();
+
+  QuicMessageFrame* frame2 =
+      new QuicMessageFrame(2, MemSliceFromString("message"));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame2), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  // Verify if a new frame is added, 1 byte message length will be added.
+  EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
+  QuicMessageFrame* frame3 =
+      new QuicMessageFrame(3, MemSliceFromString("message2"));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame3), NOT_RETRANSMISSION));
+  EXPECT_EQ(1u, creator_.ExpansionOnNewFrame());
+  creator_.FlushCurrentPacket();
+
+  QuicFrame frame;
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  const std::string data("test");
+  EXPECT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id, data, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  QuicMessageFrame* frame4 =
+      new QuicMessageFrame(4, MemSliceFromString("message"));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame4), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  // Verify there is not enough room for largest payload.
+  EXPECT_FALSE(creator_.HasRoomForMessageFrame(
+      creator_.GetCurrentLargestMessagePayload()));
+  // Add largest message will causes the flush of the stream frame.
+  QuicMessageFrame frame5(5, MemSliceFromString(large_message));
+  EXPECT_FALSE(creator_.AddFrame(QuicFrame(&frame5), NOT_RETRANSMISSION));
+  EXPECT_FALSE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest, MessageFrameConsumption) {
+  if (!VersionSupportsMessageFrames(client_framer_.transport_version())) {
+    return;
+  }
+  if (client_framer_.version().UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  std::string message_data(kDefaultMaxPacketSize, 'a');
+  // Test all possible encryption levels of message frames.
+  for (EncryptionLevel level :
+       {ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
+    creator_.set_encryption_level(level);
+    // Test all possible sizes of message frames.
+    for (size_t message_size = 0;
+         message_size <= creator_.GetCurrentLargestMessagePayload();
+         ++message_size) {
+      QuicMessageFrame* frame =
+          new QuicMessageFrame(0, MemSliceFromString(absl::string_view(
+                                      message_data.data(), message_size)));
+      EXPECT_TRUE(creator_.AddFrame(QuicFrame(frame), NOT_RETRANSMISSION));
+      EXPECT_TRUE(creator_.HasPendingFrames());
+
+      size_t expansion_bytes = message_size >= 64 ? 2 : 1;
+      EXPECT_EQ(expansion_bytes, creator_.ExpansionOnNewFrame());
+      // Verify BytesFree returns bytes available for the next frame, which
+      // should subtract the message length.
+      size_t expected_bytes_free =
+          creator_.GetCurrentLargestMessagePayload() - message_size <
+                  expansion_bytes
+              ? 0
+              : creator_.GetCurrentLargestMessagePayload() - expansion_bytes -
+                    message_size;
+      EXPECT_EQ(expected_bytes_free, creator_.BytesFree());
+      EXPECT_LE(creator_.GetGuaranteedLargestMessagePayload(),
+                creator_.GetCurrentLargestMessagePayload());
+      EXPECT_CALL(delegate_, OnSerializedPacket(_))
+          .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+      creator_.FlushCurrentPacket();
+      ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+      DeleteSerializedPacket();
+    }
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, GetGuaranteedLargestMessagePayload) {
+  ParsedQuicVersion version = GetParam().version;
+  if (!version.SupportsMessageFrames()) {
+    return;
+  }
+  if (version.UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  QuicPacketLength expected_largest_payload = 1219;
+  if (version.HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (version.HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  // Now test whether SetMaxDatagramFrameSize works.
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload - 1,
+            creator_.GetGuaranteedLargestMessagePayload());
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(
+      creator_.GetGuaranteedLargestMessagePayload()));
+
+  constexpr QuicPacketLength kFrameSizeLimit = 1000;
+  constexpr QuicPacketLength kPayloadSizeLimit =
+      kFrameSizeLimit - kQuicFrameTypeSize;
+  creator_.SetMaxDatagramFrameSize(kFrameSizeLimit);
+  EXPECT_EQ(creator_.GetGuaranteedLargestMessagePayload(), kPayloadSizeLimit);
+  EXPECT_TRUE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit));
+  EXPECT_FALSE(creator_.HasRoomForMessageFrame(kPayloadSizeLimit + 1));
+}
+
+TEST_P(QuicPacketCreatorTest, GetCurrentLargestMessagePayload) {
+  ParsedQuicVersion version = GetParam().version;
+  if (!version.SupportsMessageFrames()) {
+    return;
+  }
+  if (version.UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  QuicPacketLength expected_largest_payload = 1219;
+  if (version.SendsVariableLengthPacketNumberInLongHeader()) {
+    expected_largest_payload += 3;
+  }
+  if (version.HasLongHeaderLengths()) {
+    expected_largest_payload -= 2;
+  }
+  if (version.HasLengthPrefixedConnectionIds()) {
+    expected_largest_payload -= 1;
+  }
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetCurrentLargestMessagePayload());
+
+  // Now test whether SetMaxDatagramFrameSize works.
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload + 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetCurrentLargestMessagePayload());
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload,
+            creator_.GetCurrentLargestMessagePayload());
+
+  creator_.SetMaxDatagramFrameSize(expected_largest_payload - 1 +
+                                   kQuicFrameTypeSize);
+  EXPECT_EQ(expected_largest_payload - 1,
+            creator_.GetCurrentLargestMessagePayload());
+}
+
+TEST_P(QuicPacketCreatorTest, PacketTransmissionType) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+
+  QuicAckFrame temp_ack_frame = InitAckFrame(1);
+  QuicFrame ack_frame(&temp_ack_frame);
+  ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(ack_frame.type));
+
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicFrame stream_frame(QuicStreamFrame(stream_id,
+                                         /*fin=*/false, 0u,
+                                         absl::string_view()));
+  ASSERT_TRUE(QuicUtils::IsRetransmittableFrame(stream_frame.type));
+
+  QuicFrame padding_frame{QuicPaddingFrame()};
+  ASSERT_FALSE(QuicUtils::IsRetransmittableFrame(padding_frame.type));
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+
+  EXPECT_TRUE(creator_.AddFrame(ack_frame, LOSS_RETRANSMISSION));
+  ASSERT_EQ(serialized_packet_, nullptr);
+
+  EXPECT_TRUE(creator_.AddFrame(stream_frame, RTO_RETRANSMISSION));
+  ASSERT_EQ(serialized_packet_, nullptr);
+
+  EXPECT_TRUE(creator_.AddFrame(padding_frame, TLP_RETRANSMISSION));
+  creator_.FlushCurrentPacket();
+  ASSERT_TRUE(serialized_packet_->encrypted_buffer);
+
+  // The last retransmittable frame on packet is a stream frame, the packet's
+  // transmission type should be the same as the stream frame's.
+  EXPECT_EQ(serialized_packet_->transmission_type, RTO_RETRANSMISSION);
+  DeleteSerializedPacket();
+}
+
+TEST_P(QuicPacketCreatorTest, RetryToken) {
+  if (!GetParam().version_serialization ||
+      !QuicVersionHasLongHeaderLengths(client_framer_.transport_version())) {
+    return;
+  }
+
+  char retry_token_bytes[] = {1, 2,  3,  4,  5,  6,  7,  8,
+                              9, 10, 11, 12, 13, 14, 15, 16};
+
+  creator_.SetRetryToken(
+      std::string(retry_token_bytes, sizeof(retry_token_bytes)));
+
+  frames_.push_back(QuicFrame(QuicPingFrame()));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+
+  QuicPacketHeader header;
+  {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_))
+        .WillOnce(DoAll(SaveArg<0>(&header), Return(true)));
+    EXPECT_CALL(framer_visitor_, OnPingFrame(_));
+    if (client_framer_.version().HasHeaderProtection()) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  }
+  ProcessPacket(serialized);
+  ASSERT_TRUE(header.version_flag);
+  ASSERT_EQ(header.long_packet_type, INITIAL);
+  ASSERT_EQ(header.retry_token.length(), sizeof(retry_token_bytes));
+  quiche::test::CompareCharArraysWithHexError(
+      "retry token", header.retry_token.data(), header.retry_token.length(),
+      retry_token_bytes, sizeof(retry_token_bytes));
+}
+
+TEST_P(QuicPacketCreatorTest, GetConnectionId) {
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
+}
+
+TEST_P(QuicPacketCreatorTest, ClientConnectionId) {
+  if (!client_framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
+  creator_.SetClientConnectionId(TestConnectionId(0x33));
+  EXPECT_EQ(TestConnectionId(2), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
+}
+
+TEST_P(QuicPacketCreatorTest, CoalesceStreamFrames) {
+  InSequence s;
+  if (!GetParam().version_serialization) {
+    creator_.StopSendingVersion();
+  }
+  const size_t max_plaintext_size =
+      client_framer_.GetMaxPlaintextSize(creator_.max_packet_length());
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicStreamId stream_id1 = QuicUtils::GetFirstBidirectionalStreamId(
+      client_framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicStreamId stream_id2 = GetNthClientInitiatedStreamId(1);
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(stream_id1));
+  EXPECT_EQ(max_plaintext_size -
+                GetPacketHeaderSize(
+                    client_framer_.transport_version(),
+                    creator_.GetDestinationConnectionIdLength(),
+                    creator_.GetSourceConnectionIdLength(),
+                    QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+                    !kIncludeDiversificationNonce,
+                    QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+                    QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_),
+                    0, QuicPacketCreatorPeer::GetLengthLength(&creator_)),
+            creator_.BytesFree());
+  StrictMock<MockDebugDelegate> debug;
+  creator_.set_debug_delegate(&debug);
+
+  QuicFrame frame;
+  const std::string data1("test");
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id1, data1, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id1));
+
+  const std::string data2("coalesce");
+  // frame will be coalesced with the first frame.
+  const auto previous_size = creator_.PacketSize();
+  QuicStreamFrame target(stream_id1, true, 0, data1.length() + data2.length());
+  EXPECT_CALL(debug, OnStreamFrameCoalesced(target));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id1, data2, 4u, true, false, NOT_RETRANSMISSION, &frame));
+  EXPECT_EQ(frame.stream_frame.data_length,
+            creator_.PacketSize() - previous_size);
+
+  // frame is for another stream, so it won't be coalesced.
+  const auto length = creator_.BytesFree() - 10u;
+  const std::string data3(length, 'x');
+  EXPECT_CALL(debug, OnFrameAddedToPacket(_));
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id2, data3, 0u, false, false, NOT_RETRANSMISSION, &frame));
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(stream_id2));
+
+  // The packet doesn't have enough free bytes for all data, but will still be
+  // able to consume and coalesce part of them.
+  EXPECT_CALL(debug, OnStreamFrameCoalesced(_));
+  const std::string data4("somerandomdata");
+  ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+      stream_id2, data4, length, false, false, NOT_RETRANSMISSION, &frame));
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  creator_.FlushCurrentPacket();
+  EXPECT_CALL(framer_visitor_, OnPacket());
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+  EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+  EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+  EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+  // The packet should only have 2 stream frames.
+  EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+  EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+  EXPECT_CALL(framer_visitor_, OnPacketComplete());
+  ProcessPacket(*serialized_packet_);
+}
+
+TEST_P(QuicPacketCreatorTest, SaveNonRetransmittableFrames) {
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  frames_.push_back(QuicFrame(&ack_frame));
+  frames_.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  ASSERT_EQ(2u, serialized.nonretransmittable_frames.size());
+  EXPECT_EQ(ACK_FRAME, serialized.nonretransmittable_frames[0].type);
+  EXPECT_EQ(PADDING_FRAME, serialized.nonretransmittable_frames[1].type);
+  // Verify full padding frame is translated to a padding frame with actual
+  // bytes of padding.
+  EXPECT_LT(
+      0,
+      serialized.nonretransmittable_frames[1].padding_frame.num_padding_bytes);
+  frames_.clear();
+
+  // Serialize another packet with the same frames.
+  SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
+      &creator_, serialized.nonretransmittable_frames, buffer_,
+      kMaxOutgoingPacketSize);
+  // Verify the packet length of both packets are equal.
+  EXPECT_EQ(serialized.encrypted_length, packet.encrypted_length);
+}
+
+TEST_P(QuicPacketCreatorTest, SerializeCoalescedPacket) {
+  QuicCoalescedPacket coalesced;
+  quiche::SimpleBufferAllocator allocator;
+  QuicSocketAddress self_address(QuicIpAddress::Loopback4(), 1);
+  QuicSocketAddress peer_address(QuicIpAddress::Loopback4(), 2);
+  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    EncryptionLevel level = static_cast<EncryptionLevel>(i);
+    creator_.set_encryption_level(level);
+    QuicAckFrame ack_frame(InitAckFrame(1));
+    if (level != ENCRYPTION_ZERO_RTT) {
+      frames_.push_back(QuicFrame(&ack_frame));
+    }
+    if (level != ENCRYPTION_INITIAL && level != ENCRYPTION_HANDSHAKE) {
+      frames_.push_back(
+          QuicFrame(QuicStreamFrame(1, false, 0u, absl::string_view())));
+    }
+    SerializedPacket serialized = SerializeAllFrames(frames_);
+    EXPECT_EQ(level, serialized.encryption_level);
+    frames_.clear();
+    ASSERT_TRUE(coalesced.MaybeCoalescePacket(serialized, self_address,
+                                              peer_address, &allocator,
+                                              creator_.max_packet_length()));
+  }
+  char buffer[kMaxOutgoingPacketSize];
+  size_t coalesced_length = creator_.SerializeCoalescedPacket(
+      coalesced, buffer, kMaxOutgoingPacketSize);
+  // Verify packet is padded to full.
+  ASSERT_EQ(coalesced.max_packet_length(), coalesced_length);
+  if (!QuicVersionHasLongHeaderLengths(server_framer_.transport_version())) {
+    return;
+  }
+  // Verify packet process.
+  std::unique_ptr<QuicEncryptedPacket> packets[NUM_ENCRYPTION_LEVELS];
+  packets[ENCRYPTION_INITIAL] =
+      std::make_unique<QuicEncryptedPacket>(buffer, coalesced_length);
+  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    InSequence s;
+    EXPECT_CALL(framer_visitor_, OnPacket());
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+    if (i < ENCRYPTION_FORWARD_SECURE) {
+      // Save coalesced packet.
+      EXPECT_CALL(framer_visitor_, OnCoalescedPacket(_))
+          .WillOnce(Invoke([i, &packets](const QuicEncryptedPacket& packet) {
+            packets[i + 1] = packet.Clone();
+          }));
+    }
+    EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+    EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+    EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+    if (i != ENCRYPTION_ZERO_RTT) {
+      EXPECT_CALL(framer_visitor_, OnAckFrameStart(_, _))
+          .WillOnce(Return(true));
+      EXPECT_CALL(framer_visitor_,
+                  OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)))
+          .WillOnce(Return(true));
+      EXPECT_CALL(framer_visitor_, OnAckFrameEnd(_)).WillOnce(Return(true));
+    }
+    if (i == ENCRYPTION_INITIAL) {
+      // Verify padding is added.
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    } else if (i != ENCRYPTION_ZERO_RTT) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_)).Times(testing::AtMost(1));
+    }
+    if (i != ENCRYPTION_INITIAL && i != ENCRYPTION_HANDSHAKE) {
+      EXPECT_CALL(framer_visitor_, OnStreamFrame(_));
+    }
+    if (i == ENCRYPTION_ZERO_RTT) {
+      EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+    }
+    EXPECT_CALL(framer_visitor_, OnPacketComplete());
+
+    server_framer_.ProcessPacket(*packets[i]);
+  }
+}
+
+TEST_P(QuicPacketCreatorTest, SoftMaxPacketLength) {
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  QuicByteCount previous_max_packet_length = creator_.max_packet_length();
+  const size_t overhead =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
+      GetEncryptionOverhead();
+  // Make sure a length which cannot accommodate header (includes header
+  // protection minimal length) gets rejected.
+  creator_.SetSoftMaxPacketLength(overhead - 1);
+  EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+
+  creator_.SetSoftMaxPacketLength(overhead);
+  EXPECT_EQ(overhead, creator_.max_packet_length());
+
+  // Verify creator has room for stream frame because max_packet_length_ gets
+  // restored.
+  ASSERT_TRUE(creator_.HasRoomForStreamFrame(
+      GetNthClientInitiatedStreamId(1), kMaxIetfVarInt,
+      std::numeric_limits<uint32_t>::max()));
+  EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+
+  // Same for message frame.
+  if (VersionSupportsMessageFrames(client_framer_.transport_version())) {
+    creator_.SetSoftMaxPacketLength(overhead);
+    if (client_framer_.version().UsesTls()) {
+      creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+    }
+    // Verify GetCurrentLargestMessagePayload is based on the actual
+    // max_packet_length.
+    EXPECT_LT(1u, creator_.GetCurrentLargestMessagePayload());
+    EXPECT_EQ(overhead, creator_.max_packet_length());
+    ASSERT_TRUE(creator_.HasRoomForMessageFrame(
+        creator_.GetCurrentLargestMessagePayload()));
+    EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+  }
+
+  // Verify creator can consume crypto data because max_packet_length_ gets
+  // restored.
+  creator_.SetSoftMaxPacketLength(overhead);
+  EXPECT_EQ(overhead, creator_.max_packet_length());
+  const std::string data = "crypto data";
+  QuicFrame frame;
+  if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+    ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+        QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), data,
+        kOffset, false, true, NOT_RETRANSMISSION, &frame));
+    size_t bytes_consumed = frame.stream_frame.data_length;
+    EXPECT_LT(0u, bytes_consumed);
+  } else {
+    producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
+    ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+        ENCRYPTION_INITIAL, data.length(), kOffset,
+        /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+    size_t bytes_consumed = frame.crypto_frame->data_length;
+    EXPECT_LT(0u, bytes_consumed);
+  }
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+  creator_.FlushCurrentPacket();
+
+  // Verify ACK frame can be consumed.
+  creator_.SetSoftMaxPacketLength(overhead);
+  EXPECT_EQ(overhead, creator_.max_packet_length());
+  QuicAckFrame ack_frame(InitAckFrame(10u));
+  EXPECT_TRUE(creator_.AddFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
+TEST_P(QuicPacketCreatorTest,
+       ChangingEncryptionLevelRemovesSoftMaxPacketLength) {
+  if (!client_framer_.version().CanSendCoalescedPackets()) {
+    return;
+  }
+  // First set encryption level to forward secure which has the shortest header.
+  creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+  const QuicByteCount previous_max_packet_length = creator_.max_packet_length();
+  const size_t min_acceptable_packet_size =
+      GetPacketHeaderOverhead(client_framer_.transport_version()) +
+      QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
+      GetEncryptionOverhead();
+  // Then set the soft max packet length to the lowest allowed value.
+  creator_.SetSoftMaxPacketLength(min_acceptable_packet_size);
+  // Make sure that the low value was accepted.
+  EXPECT_EQ(creator_.max_packet_length(), min_acceptable_packet_size);
+  // Now set the encryption level to handshake which increases the header size.
+  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
+  // Make sure that adding a frame removes the the soft max packet length.
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  frames_.push_back(QuicFrame(&ack_frame));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  EXPECT_EQ(serialized.encryption_level, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(creator_.max_packet_length(), previous_max_packet_length);
+}
+
+class MockDelegate : public QuicPacketCreator::DelegateInterface {
+ public:
+  MockDelegate() {}
+  MockDelegate(const MockDelegate&) = delete;
+  MockDelegate& operator=(const MockDelegate&) = delete;
+  ~MockDelegate() override {}
+
+  MOCK_METHOD(bool,
+              ShouldGeneratePacket,
+              (HasRetransmittableData retransmittable, IsHandshake handshake),
+              (override));
+  MOCK_METHOD(const QuicFrames,
+              MaybeBundleAckOpportunistically,
+              (),
+              (override));
+  MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
+  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
+  MOCK_METHOD(void,
+              OnUnrecoverableError,
+              (QuicErrorCode, const std::string&),
+              (override));
+  MOCK_METHOD(SerializedPacketFate,
+              GetSerializedPacketFate,
+              (bool, EncryptionLevel),
+              (override));
+
+  void SetCanWriteAnything() {
+    EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true));
+    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
+        .WillRepeatedly(Return(true));
+  }
+
+  void SetCanNotWrite() {
+    EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
+        .WillRepeatedly(Return(false));
+  }
+
+  // Use this when only ack frames should be allowed to be written.
+  void SetCanWriteOnlyNonRetransmittable() {
+    EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
+        .WillRepeatedly(Return(true));
+  }
+};
+
+// Simple struct for describing the contents of a packet.
+// Useful in conjunction with a SimpleQuicFrame for validating that a packet
+// contains the expected frames.
+struct PacketContents {
+  PacketContents()
+      : num_ack_frames(0),
+        num_connection_close_frames(0),
+        num_goaway_frames(0),
+        num_rst_stream_frames(0),
+        num_stop_waiting_frames(0),
+        num_stream_frames(0),
+        num_crypto_frames(0),
+        num_ping_frames(0),
+        num_mtu_discovery_frames(0),
+        num_padding_frames(0) {}
+
+  size_t num_ack_frames;
+  size_t num_connection_close_frames;
+  size_t num_goaway_frames;
+  size_t num_rst_stream_frames;
+  size_t num_stop_waiting_frames;
+  size_t num_stream_frames;
+  size_t num_crypto_frames;
+  size_t num_ping_frames;
+  size_t num_mtu_discovery_frames;
+  size_t num_padding_frames;
+};
+
+class MultiplePacketsTestPacketCreator : public QuicPacketCreator {
+ public:
+  MultiplePacketsTestPacketCreator(
+      QuicConnectionId connection_id,
+      QuicFramer* framer,
+      QuicRandom* random_generator,
+      QuicPacketCreator::DelegateInterface* delegate,
+      SimpleDataProducer* producer)
+      : QuicPacketCreator(connection_id, framer, random_generator, delegate),
+        ack_frame_(InitAckFrame(1)),
+        delegate_(static_cast<MockDelegate*>(delegate)),
+        producer_(producer) {}
+
+  bool ConsumeRetransmittableControlFrame(const QuicFrame& frame,
+                                          bool bundle_ack) {
+    if (!has_ack()) {
+      QuicFrames frames;
+      if (bundle_ack) {
+        frames.push_back(QuicFrame(&ack_frame_));
+      }
+      if (delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                          NOT_HANDSHAKE)) {
+        EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically())
+            .WillOnce(Return(frames));
+      }
+    }
+    return QuicPacketCreator::ConsumeRetransmittableControlFrame(frame);
+  }
+
+  QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
+                                       absl::string_view data) {
+    // Save data before data is consumed.
+    if (!data.empty()) {
+      producer_->SaveStreamData(id, data);
+    }
+    return QuicPacketCreator::ConsumeDataFastPath(id, data.length(),
+                                                  /* offset = */ 0,
+                                                  /* fin = */ true, 0);
+  }
+
+  QuicConsumedData ConsumeData(QuicStreamId id, absl::string_view data,
+                               QuicStreamOffset offset,
+                               StreamSendingState state) {
+    // Save data before data is consumed.
+    if (!data.empty()) {
+      producer_->SaveStreamData(id, data);
+    }
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::ConsumeData(id, data.length(), offset, state);
+  }
+
+  MessageStatus AddMessageFrame(QuicMessageId message_id,
+                                quiche::QuicheMemSlice message) {
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::AddMessageFrame(message_id,
+                                              absl::MakeSpan(&message, 1));
+  }
+
+  size_t ConsumeCryptoData(EncryptionLevel level,
+                           absl::string_view data,
+                           QuicStreamOffset offset) {
+    producer_->SaveCryptoData(level, offset, data);
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::ConsumeCryptoData(level, data.length(), offset);
+  }
+
+  QuicAckFrame ack_frame_;
+  MockDelegate* delegate_;
+  SimpleDataProducer* producer_;
+};
+
+class QuicPacketCreatorMultiplePacketsTest : public QuicTest {
+ public:
+  QuicPacketCreatorMultiplePacketsTest()
+      : framer_(AllSupportedVersions(),
+                QuicTime::Zero(),
+                Perspective::IS_CLIENT,
+                kQuicDefaultConnectionIdLength),
+        creator_(TestConnectionId(),
+                 &framer_,
+                 &random_creator_,
+                 &delegate_,
+                 &producer_),
+        ack_frame_(InitAckFrame(1)) {
+    EXPECT_CALL(delegate_, GetPacketBuffer())
+        .WillRepeatedly(Return(QuicPacketBuffer()));
+    EXPECT_CALL(delegate_, GetSerializedPacketFate(_, _))
+        .WillRepeatedly(Return(SEND_TO_WRITER));
+    creator_.SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+    creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+    framer_.set_data_producer(&producer_);
+    if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) {
+      simple_framer_.framer()->InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_SERVER));
+    }
+    creator_.AttachPacketFlusher();
+  }
+
+  ~QuicPacketCreatorMultiplePacketsTest() override {}
+
+  void SavePacket(SerializedPacket packet) {
+    QUICHE_DCHECK(packet.release_encrypted_buffer == nullptr);
+    packet.encrypted_buffer = CopyBuffer(packet);
+    packet.release_encrypted_buffer = [](const char* p) { delete[] p; };
+    packets_.push_back(std::move(packet));
+  }
+
+ protected:
+  QuicRstStreamFrame* CreateRstStreamFrame() {
+    return new QuicRstStreamFrame(1, 1, QUIC_STREAM_NO_ERROR, 0);
+  }
+
+  QuicGoAwayFrame* CreateGoAwayFrame() {
+    return new QuicGoAwayFrame(2, QUIC_NO_ERROR, 1, std::string());
+  }
+
+  void CheckPacketContains(const PacketContents& contents,
+                           size_t packet_index) {
+    ASSERT_GT(packets_.size(), packet_index);
+    const SerializedPacket& packet = packets_[packet_index];
+    size_t num_retransmittable_frames =
+        contents.num_connection_close_frames + contents.num_goaway_frames +
+        contents.num_rst_stream_frames + contents.num_stream_frames +
+        contents.num_crypto_frames + contents.num_ping_frames;
+    size_t num_frames =
+        contents.num_ack_frames + contents.num_stop_waiting_frames +
+        contents.num_mtu_discovery_frames + contents.num_padding_frames +
+        num_retransmittable_frames;
+
+    if (num_retransmittable_frames == 0) {
+      ASSERT_TRUE(packet.retransmittable_frames.empty());
+    } else {
+      ASSERT_FALSE(packet.retransmittable_frames.empty());
+      EXPECT_EQ(num_retransmittable_frames,
+                packet.retransmittable_frames.size());
+    }
+
+    ASSERT_TRUE(packet.encrypted_buffer != nullptr);
+    ASSERT_TRUE(simple_framer_.ProcessPacket(
+        QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
+    size_t num_padding_frames = 0;
+    if (contents.num_padding_frames == 0) {
+      num_padding_frames = simple_framer_.padding_frames().size();
+    }
+    EXPECT_EQ(num_frames + num_padding_frames, simple_framer_.num_frames());
+    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
+    EXPECT_EQ(contents.num_connection_close_frames,
+              simple_framer_.connection_close_frames().size());
+    EXPECT_EQ(contents.num_goaway_frames,
+              simple_framer_.goaway_frames().size());
+    EXPECT_EQ(contents.num_rst_stream_frames,
+              simple_framer_.rst_stream_frames().size());
+    EXPECT_EQ(contents.num_stream_frames,
+              simple_framer_.stream_frames().size());
+    EXPECT_EQ(contents.num_crypto_frames,
+              simple_framer_.crypto_frames().size());
+    EXPECT_EQ(contents.num_stop_waiting_frames,
+              simple_framer_.stop_waiting_frames().size());
+    if (contents.num_padding_frames != 0) {
+      EXPECT_EQ(contents.num_padding_frames,
+                simple_framer_.padding_frames().size());
+    }
+
+    // From the receiver's perspective, MTU discovery frames are ping frames.
+    EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames,
+              simple_framer_.ping_frames().size());
+  }
+
+  void CheckPacketHasSingleStreamFrame(size_t packet_index) {
+    ASSERT_GT(packets_.size(), packet_index);
+    const SerializedPacket& packet = packets_[packet_index];
+    ASSERT_FALSE(packet.retransmittable_frames.empty());
+    EXPECT_EQ(1u, packet.retransmittable_frames.size());
+    ASSERT_TRUE(packet.encrypted_buffer != nullptr);
+    ASSERT_TRUE(simple_framer_.ProcessPacket(
+        QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length)));
+    EXPECT_EQ(1u, simple_framer_.num_frames());
+    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
+  }
+
+  void CheckAllPacketsHaveSingleStreamFrame() {
+    for (size_t i = 0; i < packets_.size(); i++) {
+      CheckPacketHasSingleStreamFrame(i);
+    }
+  }
+
+  QuicFramer framer_;
+  MockRandom random_creator_;
+  StrictMock<MockDelegate> delegate_;
+  MultiplePacketsTestPacketCreator creator_;
+  SimpleQuicFramer simple_framer_;
+  std::vector<SerializedPacket> packets_;
+  QuicAckFrame ack_frame_;
+  struct iovec iov_;
+  quiche::SimpleBufferAllocator allocator_;
+
+ private:
+  std::unique_ptr<char[]> data_array_;
+  SimpleDataProducer producer_;
+};
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_NotWritable) {
+  delegate_.SetCanNotWrite();
+
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/false);
+  EXPECT_FALSE(consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+  delete rst_frame;
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       WrongEncryptionLevelForStreamDataFastPath) {
+  creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
+  delegate_.SetCanWriteAnything();
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
+  EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+  EXPECT_QUIC_BUG(creator_.ConsumeDataFastPath(
+                      QuicUtils::GetFirstBidirectionalStreamId(
+                          framer_.transport_version(), Perspective::IS_CLIENT),
+                      data),
+                  "");
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_OnlyAckWritable) {
+  delegate_.SetCanWriteOnlyNonRetransmittable();
+
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/false);
+  EXPECT_FALSE(consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+  delete rst_frame;
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       AddControlFrame_WritableAndShouldNotFlush) {
+  delegate_.SetCanWriteAnything();
+
+  creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
+                                              /*bundle_ack=*/false);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       AddControlFrame_NotWritableBatchThenFlush) {
+  delegate_.SetCanNotWrite();
+
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/false);
+  EXPECT_FALSE(consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+  delete rst_frame;
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       AddControlFrame_WritableAndShouldFlush) {
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
+                                              /*bundle_ack=*/false);
+  creator_.Flush();
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_rst_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeCryptoData) {
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  std::string data = "crypto data";
+  size_t consumed_bytes =
+      creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+  creator_.Flush();
+  EXPECT_EQ(data.length(), consumed_bytes);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_crypto_frames = 1;
+  contents.num_padding_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeCryptoDataCheckShouldGeneratePacket) {
+  delegate_.SetCanNotWrite();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
+  std::string data = "crypto data";
+  size_t consumed_bytes =
+      creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+  creator_.Flush();
+  EXPECT_EQ(0u, consumed_bytes);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) {
+  delegate_.SetCanNotWrite();
+
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, FIN);
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeData_WritableAndShouldNotFlush) {
+  delegate_.SetCanWriteAnything();
+
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeData_WritableAndShouldFlush) {
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, FIN);
+  creator_.Flush();
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+// Test the behavior of ConsumeData when the data consumed is for the crypto
+// handshake stream.  Ensure that the packet is always sent and padded even if
+// the creator operates in batch mode.
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_Handshake) {
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  const std::string data = "foo bar";
+  size_t consumed_bytes = 0;
+  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    consumed_bytes = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+  } else {
+    consumed_bytes =
+        creator_
+            .ConsumeData(
+                QuicUtils::GetCryptoStreamId(framer_.transport_version()), data,
+                0, NO_FIN)
+            .bytes_consumed;
+  }
+  EXPECT_EQ(7u, consumed_bytes);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    contents.num_crypto_frames = 1;
+  } else {
+    contents.num_stream_frames = 1;
+  }
+  contents.num_padding_frames = 1;
+  CheckPacketContains(contents, 0);
+
+  ASSERT_EQ(1u, packets_.size());
+  ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length());
+  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
+}
+
+// Test the behavior of ConsumeData when the data is for the crypto handshake
+// stream, but padding is disabled.
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeData_Handshake_PaddingDisabled) {
+  creator_.set_fully_pad_crypto_handshake_packets(false);
+
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  const std::string data = "foo";
+  size_t bytes_consumed = 0;
+  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    bytes_consumed = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+  } else {
+    bytes_consumed =
+        creator_
+            .ConsumeData(
+                QuicUtils::GetCryptoStreamId(framer_.transport_version()), data,
+                0, NO_FIN)
+            .bytes_consumed;
+  }
+  EXPECT_EQ(3u, bytes_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    contents.num_crypto_frames = 1;
+  } else {
+    contents.num_stream_frames = 1;
+  }
+  contents.num_padding_frames = 0;
+  CheckPacketContains(contents, 0);
+
+  ASSERT_EQ(1u, packets_.size());
+
+  // Packet is not fully padded, but we want to future packets to be larger.
+  ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length());
+  size_t expected_packet_length = 27;
+  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
+    // The framing of CRYPTO frames is slightly different than that of stream
+    // frames, so the expected packet length differs slightly.
+    expected_packet_length = 28;
+  }
+  if (framer_.version().HasHeaderProtection()) {
+    expected_packet_length = 29;
+  }
+  EXPECT_EQ(expected_packet_length, packets_[0].encrypted_length);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_EmptyData) {
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_QUIC_BUG(creator_.ConsumeData(
+                      QuicUtils::QuicUtils::GetFirstBidirectionalStreamId(
+                          framer_.transport_version(), Perspective::IS_CLIENT),
+                      {}, 0, NO_FIN),
+                  "Attempt to consume empty data without FIN.");
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
+  delegate_.SetCanWriteAnything();
+
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "foo", 0, FIN);
+  QuicConsumedData consumed = creator_.ConsumeData(3, "quux", 3, NO_FIN);
+  EXPECT_EQ(4u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_BatchOperations) {
+  delegate_.SetCanWriteAnything();
+
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "foo", 0, NO_FIN);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "quux", 3, FIN);
+  EXPECT_EQ(4u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // Now both frames will be flushed out.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  creator_.Flush();
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeData_FramesPreviouslyQueued) {
+  // Set the packet size be enough for two stream frames with 0 stream offset,
+  // but not enough for a stream frame of 0 offset and one with non-zero offset.
+  size_t length =
+      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
+      GetPacketHeaderSize(
+          framer_.transport_version(),
+          creator_.GetDestinationConnectionIdLength(),
+          creator_.GetSourceConnectionIdLength(),
+          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+          !kIncludeDiversificationNonce,
+          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
+          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
+      // Add an extra 3 bytes for the payload and 1 byte so
+      // BytesFree is larger than the GetMinStreamFrameSize.
+      QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0,
+                                        false, 3) +
+      3 +
+      QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, true,
+                                        1) +
+      1;
+  creator_.SetMaxPacketLength(length);
+  delegate_.SetCanWriteAnything();
+  {
+    InSequence dummy;
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(
+            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(
+            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  }
+  // Queue enough data to prevent a stream frame with a non-zero offset from
+  // fitting.
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // This frame will not fit with the existing frame, causing the queued frame
+  // to be serialized, and it will be added to a new open packet.
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "bar", 3, FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  creator_.FlushCurrentPacket();
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+  CheckPacketContains(contents, 1);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataFastPath) {
+  delegate_.SetCanWriteAnything();
+  creator_.SetTransmissionType(LOSS_RETRANSMISSION);
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeDataFastPath(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data);
+  EXPECT_EQ(10000u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+  EXPECT_FALSE(packets_.empty());
+  SerializedPacket& packet = packets_.back();
+  EXPECT_TRUE(!packet.retransmittable_frames.empty());
+  EXPECT_EQ(LOSS_RETRANSMISSION, packet.transmission_type);
+  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+  const QuicStreamFrame& stream_frame =
+      packet.retransmittable_frames.front().stream_frame;
+  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLarge) {
+  delegate_.SetCanWriteAnything();
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, 0, FIN);
+  EXPECT_EQ(10000u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  PacketContents contents;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+  EXPECT_FALSE(packets_.empty());
+  SerializedPacket& packet = packets_.back();
+  EXPECT_TRUE(!packet.retransmittable_frames.empty());
+  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+  const QuicStreamFrame& stream_frame =
+      packet.retransmittable_frames.front().stream_frame;
+  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckFalse) {
+  delegate_.SetCanNotWrite();
+
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool success =
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/true);
+  EXPECT_FALSE(success);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  delegate_.SetCanWriteAnything();
+
+  creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                              /*bundle_ack=*/false);
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()),
+                                              /*bundle_ack=*/true);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, 0, FIN);
+  creator_.Flush();
+
+  EXPECT_EQ(10000u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  EXPECT_FALSE(packets_.empty());
+  SerializedPacket& packet = packets_.back();
+  EXPECT_TRUE(!packet.retransmittable_frames.empty());
+  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+  const QuicStreamFrame& stream_frame =
+      packet.retransmittable_frames.front().stream_frame;
+  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckTrue) {
+  delegate_.SetCanNotWrite();
+  delegate_.SetCanWriteAnything();
+
+  const std::string data(10000, '?');
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, 0, FIN);
+  creator_.Flush();
+
+  EXPECT_EQ(10000u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  EXPECT_FALSE(packets_.empty());
+  SerializedPacket& packet = packets_.back();
+  EXPECT_TRUE(!packet.retransmittable_frames.empty());
+  EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+  const QuicStreamFrame& stream_frame =
+      packet.retransmittable_frames.front().stream_frame;
+  EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations) {
+  delegate_.SetCanNotWrite();
+
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/true);
+  EXPECT_FALSE(consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3));
+
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_TRUE(
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/false));
+  // Send some data and a control frame
+  creator_.ConsumeData(3, "quux", 0, NO_FIN);
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()),
+                                                /*bundle_ack=*/false);
+  }
+  EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(3));
+
+  // All five frames will be flushed out in a single packet.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  creator_.Flush();
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+  EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3));
+
+  PacketContents contents;
+  // ACK will be flushed by connection.
+  contents.num_ack_frames = 0;
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    contents.num_goaway_frames = 1;
+  } else {
+    contents.num_goaway_frames = 0;
+  }
+  contents.num_rst_stream_frames = 1;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations2) {
+  delegate_.SetCanNotWrite();
+
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool success =
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/true);
+  EXPECT_FALSE(success);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  delegate_.SetCanWriteAnything();
+
+  {
+    InSequence dummy;
+    // All five frames will be flushed out in a single packet
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(
+            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+    EXPECT_CALL(delegate_, OnSerializedPacket(_))
+        .WillOnce(
+            Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  }
+  EXPECT_TRUE(
+      creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/false));
+  // Send enough data to exceed one packet
+  size_t data_len = kDefaultMaxPacketSize + 100;
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(3, data, 0, FIN);
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()),
+                                                /*bundle_ack=*/false);
+  }
+
+  creator_.Flush();
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // The first packet should have the queued data and part of the stream data.
+  PacketContents contents;
+  // ACK will be sent by connection.
+  contents.num_ack_frames = 0;
+  contents.num_rst_stream_frames = 1;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+
+  // The second should have the remainder of the stream data.
+  PacketContents contents2;
+  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+    contents2.num_goaway_frames = 1;
+  } else {
+    contents2.num_goaway_frames = 0;
+  }
+  contents2.num_stream_frames = 1;
+  CheckPacketContains(contents2, 1);
+}
+
+// Regression test of b/120493795.
+TEST_F(QuicPacketCreatorMultiplePacketsTest, PacketTransmissionType) {
+  delegate_.SetCanWriteAnything();
+
+  // The first ConsumeData will fill the packet without flush.
+  creator_.SetTransmissionType(LOSS_RETRANSMISSION);
+
+  size_t data_len = 1224;
+  const std::string data(data_len, '?');
+  QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId(
+      framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicConsumedData consumed = creator_.ConsumeData(stream1_id, data, 0, NO_FIN);
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  ASSERT_EQ(0u, creator_.BytesFree())
+      << "Test setup failed: Please increase data_len to "
+      << data_len + creator_.BytesFree() << " bytes.";
+
+  // The second ConsumeData can not be added to the packet and will flush.
+  creator_.SetTransmissionType(NOT_RETRANSMISSION);
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  QuicStreamId stream2_id = stream1_id + 4;
+
+  consumed = creator_.ConsumeData(stream2_id, data, 0, NO_FIN);
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+
+  // Ensure the packet is successfully created.
+  ASSERT_EQ(1u, packets_.size());
+  ASSERT_TRUE(packets_[0].encrypted_buffer);
+  ASSERT_EQ(1u, packets_[0].retransmittable_frames.size());
+  EXPECT_EQ(stream1_id,
+            packets_[0].retransmittable_frames[0].stream_frame.stream_id);
+
+  // Since the second frame was not added, the packet's transmission type
+  // should be the first frame's type.
+  EXPECT_EQ(packets_[0].transmission_type, LOSS_RETRANSMISSION);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, TestConnectionIdLength) {
+  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
+  creator_.SetServerConnectionIdLength(0);
+  EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
+            creator_.GetDestinationConnectionIdLength());
+
+  for (size_t i = 1; i < 10; i++) {
+    creator_.SetServerConnectionIdLength(i);
+    if (framer_.version().HasIetfInvariantHeader()) {
+      EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
+                creator_.GetDestinationConnectionIdLength());
+    } else {
+      EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID,
+                creator_.GetDestinationConnectionIdLength());
+    }
+  }
+}
+
+// Test whether SetMaxPacketLength() works in the situation when the queue is
+// empty, and we send three packets worth of data.
+TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Initial) {
+  delegate_.SetCanWriteAnything();
+
+  // Send enough data for three packets.
+  size_t data_len = 3 * kDefaultMaxPacketSize + 1;
+  size_t packet_len = kDefaultMaxPacketSize + 100;
+  ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
+  creator_.SetMaxPacketLength(packet_len);
+  EXPECT_EQ(packet_len, creator_.max_packet_length());
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .Times(3)
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*offset=*/0, FIN);
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // We expect three packets, and first two of them have to be of packet_len
+  // size.  We check multiple packets (instead of just one) because we want to
+  // ensure that |max_packet_length_| does not get changed incorrectly by the
+  // creator after first packet is serialized.
+  ASSERT_EQ(3u, packets_.size());
+  EXPECT_EQ(packet_len, packets_[0].encrypted_length);
+  EXPECT_EQ(packet_len, packets_[1].encrypted_length);
+  CheckAllPacketsHaveSingleStreamFrame();
+}
+
+// Test whether SetMaxPacketLength() works in the situation when we first write
+// data, then change packet size, then write data again.
+TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Middle) {
+  delegate_.SetCanWriteAnything();
+
+  // We send enough data to overflow default packet length, but not the altered
+  // one.
+  size_t data_len = kDefaultMaxPacketSize;
+  size_t packet_len = kDefaultMaxPacketSize + 100;
+  ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
+
+  // We expect to see three packets in total.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .Times(3)
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  // Send two packets before packet size change.
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*offset=*/0, NO_FIN);
+  creator_.Flush();
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // Make sure we already have two packets.
+  ASSERT_EQ(2u, packets_.size());
+
+  // Increase packet size.
+  creator_.SetMaxPacketLength(packet_len);
+  EXPECT_EQ(packet_len, creator_.max_packet_length());
+
+  // Send a packet after packet size change.
+  creator_.AttachPacketFlusher();
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data, data_len, FIN);
+  creator_.Flush();
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // We expect first data chunk to get fragmented, but the second one to fit
+  // into a single packet.
+  ASSERT_EQ(3u, packets_.size());
+  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
+  EXPECT_LE(kDefaultMaxPacketSize, packets_[2].encrypted_length);
+  CheckAllPacketsHaveSingleStreamFrame();
+}
+
+// Test whether SetMaxPacketLength() works correctly when we force the change of
+// the packet size in the middle of the batched packet.
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       SetMaxPacketLength_MidpacketFlush) {
+  delegate_.SetCanWriteAnything();
+
+  size_t first_write_len = kDefaultMaxPacketSize / 2;
+  size_t packet_len = kDefaultMaxPacketSize + 100;
+  size_t second_write_len = packet_len + 1;
+  ASSERT_LE(packet_len, kMaxOutgoingPacketSize);
+
+  // First send half of the packet worth of data.  We are in the batch mode, so
+  // should not cause packet serialization.
+  const std::string first_write(first_write_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      first_write,
+      /*offset=*/0, NO_FIN);
+  EXPECT_EQ(first_write_len, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // Make sure we have no packets so far.
+  ASSERT_EQ(0u, packets_.size());
+
+  // Expect a packet to be flushed.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  // Increase packet size after flushing all frames.
+  // Ensure it's immediately enacted.
+  creator_.FlushCurrentPacket();
+  creator_.SetMaxPacketLength(packet_len);
+  EXPECT_EQ(packet_len, creator_.max_packet_length());
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // We expect to see exactly one packet serialized after that, because we send
+  // a value somewhat exceeding new max packet size, and the tail data does not
+  // get serialized because we are still in the batch mode.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  // Send a more than a packet worth of data to the same stream.  This should
+  // trigger serialization of one packet, and queue another one.
+  const std::string second_write(second_write_len, '?');
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      second_write,
+      /*offset=*/first_write_len, FIN);
+  EXPECT_EQ(second_write_len, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // We expect the first packet to be underfilled, and the second packet be up
+  // to the new max packet size.
+  ASSERT_EQ(2u, packets_.size());
+  EXPECT_GT(kDefaultMaxPacketSize, packets_[0].encrypted_length);
+  EXPECT_EQ(packet_len, packets_[1].encrypted_length);
+
+  CheckAllPacketsHaveSingleStreamFrame();
+}
+
+// Test sending a connectivity probing packet.
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       GenerateConnectivityProbingPacket) {
+  delegate_.SetCanWriteAnything();
+
+  std::unique_ptr<SerializedPacket> probing_packet;
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    QuicPathFrameBuffer payload = {
+        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+    probing_packet =
+        creator_.SerializePathChallengeConnectivityProbingPacket(payload);
+  } else {
+    probing_packet = creator_.SerializeConnectivityProbingPacket();
+  }
+
+  ASSERT_TRUE(simple_framer_.ProcessPacket(QuicEncryptedPacket(
+      probing_packet->encrypted_buffer, probing_packet->encrypted_length)));
+
+  EXPECT_EQ(2u, simple_framer_.num_frames());
+  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
+    EXPECT_EQ(1u, simple_framer_.path_challenge_frames().size());
+  } else {
+    EXPECT_EQ(1u, simple_framer_.ping_frames().size());
+  }
+  EXPECT_EQ(1u, simple_framer_.padding_frames().size());
+}
+
+// Test sending an MTU probe, without any surrounding data.
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       GenerateMtuDiscoveryPacket_Simple) {
+  delegate_.SetCanWriteAnything();
+
+  const size_t target_mtu = kDefaultMaxPacketSize + 100;
+  static_assert(target_mtu < kMaxOutgoingPacketSize,
+                "The MTU probe used by the test exceeds maximum packet size");
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  creator_.GenerateMtuDiscoveryPacket(target_mtu);
+
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+  ASSERT_EQ(1u, packets_.size());
+  EXPECT_EQ(target_mtu, packets_[0].encrypted_length);
+
+  PacketContents contents;
+  contents.num_mtu_discovery_frames = 1;
+  contents.num_padding_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+// Test sending an MTU probe.  Surround it with data, to ensure that it resets
+// the MTU to the value before the probe was sent.
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       GenerateMtuDiscoveryPacket_SurroundedByData) {
+  delegate_.SetCanWriteAnything();
+
+  const size_t target_mtu = kDefaultMaxPacketSize + 100;
+  static_assert(target_mtu < kMaxOutgoingPacketSize,
+                "The MTU probe used by the test exceeds maximum packet size");
+
+  // Send enough data so it would always cause two packets to be sent.
+  const size_t data_len = target_mtu + 1;
+
+  // Send a total of five packets: two packets before the probe, the probe
+  // itself, and two packets after the probe.
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .Times(5)
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  // Send data before the MTU probe.
+  const std::string data(data_len, '?');
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*offset=*/0, NO_FIN);
+  creator_.Flush();
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // Send the MTU probe.
+  creator_.GenerateMtuDiscoveryPacket(target_mtu);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  // Send data after the MTU probe.
+  creator_.AttachPacketFlusher();
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      data,
+      /*offset=*/data_len, FIN);
+  creator_.Flush();
+  EXPECT_EQ(data_len, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  ASSERT_EQ(5u, packets_.size());
+  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length);
+  EXPECT_EQ(target_mtu, packets_[2].encrypted_length);
+  EXPECT_EQ(kDefaultMaxPacketSize, packets_[3].encrypted_length);
+
+  PacketContents probe_contents;
+  probe_contents.num_mtu_discovery_frames = 1;
+  probe_contents.num_padding_frames = 1;
+
+  CheckPacketHasSingleStreamFrame(0);
+  CheckPacketHasSingleStreamFrame(1);
+  CheckPacketContains(probe_contents, 2);
+  CheckPacketHasSingleStreamFrame(3);
+  CheckPacketHasSingleStreamFrame(4);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, DontCrashOnInvalidStopWaiting) {
+  if (VersionSupportsMessageFrames(framer_.transport_version())) {
+    return;
+  }
+  // Test added to ensure the creator does not crash when an invalid frame is
+  // added.  Because this is an indication of internal programming errors,
+  // DFATALs are expected.
+  // A 1 byte packet number length can't encode a gap of 1000.
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1000);
+
+  delegate_.SetCanNotWrite();
+  delegate_.SetCanWriteAnything();
+
+  // This will not serialize any packets, because of the invalid frame.
+  EXPECT_CALL(delegate_,
+              OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, _));
+  EXPECT_QUIC_BUG(creator_.Flush(),
+                  "packet_number_length 1 is too small "
+                  "for least_unacked_delta: 1001");
+}
+
+// Regression test for b/31486443.
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConnectionCloseFrameLargerThanPacketSize) {
+  delegate_.SetCanWriteAnything();
+  char buf[2000] = {};
+  absl::string_view error_details(buf, 2000);
+  const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR;
+
+  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
+      framer_.transport_version(), kQuicErrorCode, NO_IETF_QUIC_ERROR,
+      std::string(error_details),
+      /*transport_close_frame_type=*/0);
+  creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame),
+                                              /*bundle_ack=*/false);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       RandomPaddingAfterFinSingleStreamSinglePacket) {
+  const QuicByteCount kStreamFramePayloadSize = 100u;
+  char buf[kStreamFramePayloadSize] = {};
+  const QuicStreamId kDataStreamId = 5;
+  // Set the packet size be enough for one stream frame with 0 stream offset and
+  // max size of random padding.
+  size_t length =
+      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
+      GetPacketHeaderSize(
+          framer_.transport_version(),
+          creator_.GetDestinationConnectionIdLength(),
+          creator_.GetSourceConnectionIdLength(),
+          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+          !kIncludeDiversificationNonce,
+          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
+          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
+      QuicFramer::GetMinStreamFrameSize(
+          framer_.transport_version(), kDataStreamId, 0,
+          /*last_frame_in_packet=*/false,
+          kStreamFramePayloadSize + kMaxNumRandomPaddingBytes) +
+      kStreamFramePayloadSize + kMaxNumRandomPaddingBytes;
+  creator_.SetMaxPacketLength(length);
+  delegate_.SetCanWriteAnything();
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 0,
+      FIN_AND_PADDING);
+  creator_.Flush();
+  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  EXPECT_EQ(1u, packets_.size());
+  PacketContents contents;
+  // The packet has both stream and padding frames.
+  contents.num_padding_frames = 1;
+  contents.num_stream_frames = 1;
+  CheckPacketContains(contents, 0);
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       RandomPaddingAfterFinSingleStreamMultiplePackets) {
+  const QuicByteCount kStreamFramePayloadSize = 100u;
+  char buf[kStreamFramePayloadSize] = {};
+  const QuicStreamId kDataStreamId = 5;
+  // Set the packet size be enough for one stream frame with 0 stream offset +
+  // 1. One or more packets will accommodate.
+  size_t length =
+      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
+      GetPacketHeaderSize(
+          framer_.transport_version(),
+          creator_.GetDestinationConnectionIdLength(),
+          creator_.GetSourceConnectionIdLength(),
+          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+          !kIncludeDiversificationNonce,
+          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
+          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
+      QuicFramer::GetMinStreamFrameSize(
+          framer_.transport_version(), kDataStreamId, 0,
+          /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) +
+      kStreamFramePayloadSize + 1;
+  creator_.SetMaxPacketLength(length);
+  delegate_.SetCanWriteAnything();
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId, absl::string_view(buf, kStreamFramePayloadSize), 0,
+      FIN_AND_PADDING);
+  creator_.Flush();
+  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  EXPECT_LE(1u, packets_.size());
+  PacketContents contents;
+  // The first packet has both stream and padding frames.
+  contents.num_stream_frames = 1;
+  contents.num_padding_frames = 1;
+  CheckPacketContains(contents, 0);
+
+  for (size_t i = 1; i < packets_.size(); ++i) {
+    // Following packets only have paddings.
+    contents.num_stream_frames = 0;
+    contents.num_padding_frames = 1;
+    CheckPacketContains(contents, i);
+  }
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       RandomPaddingAfterFinMultipleStreamsMultiplePackets) {
+  const QuicByteCount kStreamFramePayloadSize = 100u;
+  char buf[kStreamFramePayloadSize] = {};
+  const QuicStreamId kDataStreamId1 = 5;
+  const QuicStreamId kDataStreamId2 = 6;
+  // Set the packet size be enough for first frame with 0 stream offset + second
+  // frame + 1 byte payload. two or more packets will accommodate.
+  size_t length =
+      NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
+      GetPacketHeaderSize(
+          framer_.transport_version(),
+          creator_.GetDestinationConnectionIdLength(),
+          creator_.GetSourceConnectionIdLength(),
+          QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
+          !kIncludeDiversificationNonce,
+          QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+          QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0,
+          QuicPacketCreatorPeer::GetLengthLength(&creator_)) +
+      QuicFramer::GetMinStreamFrameSize(
+          framer_.transport_version(), kDataStreamId1, 0,
+          /*last_frame_in_packet=*/false, kStreamFramePayloadSize) +
+      kStreamFramePayloadSize +
+      QuicFramer::GetMinStreamFrameSize(framer_.transport_version(),
+                                        kDataStreamId1, 0,
+                                        /*last_frame_in_packet=*/false, 1) +
+      1;
+  creator_.SetMaxPacketLength(length);
+  delegate_.SetCanWriteAnything();
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId1, absl::string_view(buf, kStreamFramePayloadSize), 0,
+      FIN_AND_PADDING);
+  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
+  consumed = creator_.ConsumeData(
+      kDataStreamId2, absl::string_view(buf, kStreamFramePayloadSize), 0,
+      FIN_AND_PADDING);
+  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
+  creator_.Flush();
+  EXPECT_FALSE(creator_.HasPendingFrames());
+  EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+
+  EXPECT_LE(2u, packets_.size());
+  PacketContents contents;
+  // The first packet has two stream frames.
+  contents.num_stream_frames = 2;
+  CheckPacketContains(contents, 0);
+
+  // The second packet has one stream frame and padding frames.
+  contents.num_stream_frames = 1;
+  contents.num_padding_frames = 1;
+  CheckPacketContains(contents, 1);
+
+  for (size_t i = 2; i < packets_.size(); ++i) {
+    // Following packets only have paddings.
+    contents.num_stream_frames = 0;
+    contents.num_padding_frames = 1;
+    CheckPacketContains(contents, i);
+  }
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, AddMessageFrame) {
+  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
+    return;
+  }
+  if (framer_.version().UsesTls()) {
+    creator_.SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
+  }
+  delegate_.SetCanWriteAnything();
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "foo", 0, FIN);
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+            creator_.AddMessageFrame(1, MemSliceFromString("message")));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // Add a message which causes the flush of current packet.
+  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
+            creator_.AddMessageFrame(
+                2, MemSliceFromString(std::string(
+                       creator_.GetCurrentLargestMessagePayload(), 'a'))));
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // Failed to send messages which cannot fit into one packet.
+  EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
+            creator_.AddMessageFrame(
+                3, MemSliceFromString(std::string(
+                       creator_.GetCurrentLargestMessagePayload() + 10, 'a'))));
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ConnectionId) {
+  creator_.SetServerConnectionId(TestConnectionId(0x1337));
+  EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId());
+  if (!framer_.version().SupportsClientConnectionIds()) {
+    return;
+  }
+  creator_.SetClientConnectionId(TestConnectionId(0x33));
+  EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId());
+  EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId());
+}
+
+// Regresstion test for b/159812345.
+TEST_F(QuicPacketCreatorMultiplePacketsTest, ExtraPaddingNeeded) {
+  if (!framer_.version().HasHeaderProtection()) {
+    return;
+  }
+  delegate_.SetCanWriteAnything();
+
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       "a", 0, FIN);
+  creator_.Flush();
+  ASSERT_FALSE(packets_[0].nonretransmittable_frames.empty());
+  QuicFrame padding = packets_[0].nonretransmittable_frames[0];
+  // Verify stream frame expansion is excluded.
+  padding.padding_frame.num_padding_bytes = 3;
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       PeerAddressContextWithSameAddress) {
+  QuicConnectionId client_connection_id = TestConnectionId(1);
+  QuicConnectionId server_connection_id = TestConnectionId(2);
+  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
+  creator_.SetDefaultPeerAddress(peer_addr);
+  creator_.SetClientConnectionId(client_connection_id);
+  creator_.SetServerConnectionId(server_connection_id);
+  // Send some stream data.
+  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+      .WillRepeatedly(Return(true));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  {
+    // Set the same address via context which should not trigger flush.
+    QuicPacketCreator::ScopedPeerAddressContext context(
+        &creator_, peer_addr, client_connection_id, server_connection_id,
+        /*update_connection_id=*/true);
+    ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
+    ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
+    EXPECT_TRUE(creator_.HasPendingFrames());
+    // Queue another STREAM_FRAME.
+    QuicConsumedData consumed = creator_.ConsumeData(
+        QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                                 Perspective::IS_CLIENT),
+        "foo", 0, FIN);
+    EXPECT_EQ(3u, consumed.bytes_consumed);
+  }
+  // After exiting the scope, the last queued frame should be flushed.
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr, packet.peer_address);
+        ASSERT_EQ(2u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.back().type);
+      }));
+  creator_.FlushCurrentPacket();
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       PeerAddressContextWithDifferentAddress) {
+  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
+  creator_.SetDefaultPeerAddress(peer_addr);
+  // Send some stream data.
+  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+      .WillRepeatedly(Return(true));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+
+  QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+      }))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr1, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+      }));
+  EXPECT_TRUE(creator_.HasPendingFrames());
+  {
+    QuicConnectionId client_connection_id = TestConnectionId(1);
+    QuicConnectionId server_connection_id = TestConnectionId(2);
+    // Set a different address via context which should trigger flush.
+    QuicPacketCreator::ScopedPeerAddressContext context(
+        &creator_, peer_addr1, client_connection_id, server_connection_id,
+        /*update_connection_id=*/true);
+    ASSERT_EQ(client_connection_id, creator_.GetClientConnectionId());
+    ASSERT_EQ(server_connection_id, creator_.GetServerConnectionId());
+    EXPECT_FALSE(creator_.HasPendingFrames());
+    // Queue another STREAM_FRAME.
+    QuicConsumedData consumed = creator_.ConsumeData(
+        QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                                 Perspective::IS_CLIENT),
+        "foo", 0, FIN);
+    EXPECT_EQ(3u, consumed.bytes_consumed);
+    EXPECT_TRUE(creator_.HasPendingFrames());
+  }
+  // After exiting the scope, the last queued frame should be flushed.
+  EXPECT_FALSE(creator_.HasPendingFrames());
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       NestedPeerAddressContextWithDifferentAddress) {
+  QuicConnectionId client_connection_id1 = creator_.GetClientConnectionId();
+  QuicConnectionId server_connection_id1 = creator_.GetServerConnectionId();
+  QuicSocketAddress peer_addr(QuicIpAddress::Any4(), 12345);
+  creator_.SetDefaultPeerAddress(peer_addr);
+  QuicPacketCreator::ScopedPeerAddressContext context(
+      &creator_, peer_addr, client_connection_id1, server_connection_id1,
+      /*update_connection_id=*/true);
+  ASSERT_EQ(client_connection_id1, creator_.GetClientConnectionId());
+  ASSERT_EQ(server_connection_id1, creator_.GetServerConnectionId());
+
+  // Send some stream data.
+  EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+      .WillRepeatedly(Return(true));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(creator_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      "foo", 0, NO_FIN);
+  EXPECT_EQ(3u, consumed.bytes_consumed);
+  EXPECT_TRUE(creator_.HasPendingFrames());
+
+  QuicSocketAddress peer_addr1(QuicIpAddress::Any4(), 12346);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+
+        QuicConnectionId client_connection_id2 = TestConnectionId(3);
+        QuicConnectionId server_connection_id2 = TestConnectionId(4);
+        // Set up another context with a different address.
+        QuicPacketCreator::ScopedPeerAddressContext context(
+            &creator_, peer_addr1, client_connection_id2, server_connection_id2,
+            /*update_connection_id=*/true);
+        ASSERT_EQ(client_connection_id2, creator_.GetClientConnectionId());
+        ASSERT_EQ(server_connection_id2, creator_.GetServerConnectionId());
+        EXPECT_CALL(delegate_, ShouldGeneratePacket(_, _))
+            .WillRepeatedly(Return(true));
+        QuicConsumedData consumed = creator_.ConsumeData(
+            QuicUtils::GetFirstBidirectionalStreamId(
+                creator_.transport_version(), Perspective::IS_CLIENT),
+            "foo", 0, NO_FIN);
+        EXPECT_EQ(3u, consumed.bytes_consumed);
+        EXPECT_TRUE(creator_.HasPendingFrames());
+        // This should trigger another OnSerializedPacket() with the 2nd
+        // address.
+        creator_.FlushCurrentPacket();
+      }))
+      .WillOnce(Invoke([=](SerializedPacket packet) {
+        EXPECT_EQ(peer_addr1, packet.peer_address);
+        ASSERT_EQ(1u, packet.retransmittable_frames.size());
+        EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type);
+      }));
+  creator_.FlushCurrentPacket();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_number.cc b/quiche/quic/core/quic_packet_number.cc
new file mode 100644
index 0000000..ab220bf
--- /dev/null
+++ b/quiche/quic/core/quic_packet_number.cc
@@ -0,0 +1,111 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packet_number.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+void QuicPacketNumber::Clear() {
+  packet_number_ = UninitializedPacketNumber();
+}
+
+void QuicPacketNumber::UpdateMax(QuicPacketNumber new_value) {
+  if (!new_value.IsInitialized()) {
+    return;
+  }
+  if (!IsInitialized()) {
+    packet_number_ = new_value.ToUint64();
+  } else {
+    packet_number_ = std::max(packet_number_, new_value.ToUint64());
+  }
+}
+
+uint64_t QuicPacketNumber::Hash() const {
+  QUICHE_DCHECK(IsInitialized());
+  return packet_number_;
+}
+
+uint64_t QuicPacketNumber::ToUint64() const {
+  QUICHE_DCHECK(IsInitialized());
+  return packet_number_;
+}
+
+bool QuicPacketNumber::IsInitialized() const {
+  return packet_number_ != UninitializedPacketNumber();
+}
+
+QuicPacketNumber& QuicPacketNumber::operator++() {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
+#endif
+  packet_number_++;
+  return *this;
+}
+
+QuicPacketNumber QuicPacketNumber::operator++(int) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_LT(ToUint64(), std::numeric_limits<uint64_t>::max() - 1);
+#endif
+  QuicPacketNumber previous(*this);
+  packet_number_++;
+  return previous;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator--() {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GE(ToUint64(), 1UL);
+#endif
+  packet_number_--;
+  return *this;
+}
+
+QuicPacketNumber QuicPacketNumber::operator--(int) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GE(ToUint64(), 1UL);
+#endif
+  QuicPacketNumber previous(*this);
+  packet_number_--;
+  return previous;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator+=(uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - ToUint64(), delta);
+#endif
+  packet_number_ += delta;
+  return *this;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator-=(uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(IsInitialized());
+  QUICHE_DCHECK_GE(ToUint64(), delta);
+#endif
+  packet_number_ -= delta;
+  return *this;
+}
+
+std::string QuicPacketNumber::ToString() const {
+  if (!IsInitialized()) {
+    return "uninitialized";
+  }
+  return absl::StrCat(ToUint64());
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicPacketNumber& p) {
+  os << p.ToString();
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_number.h b/quiche/quic/core/quic_packet_number.h
new file mode 100644
index 0000000..0cd94c9
--- /dev/null
+++ b/quiche/quic/core/quic_packet_number.h
@@ -0,0 +1,165 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
+
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// QuicPacketNumber can either initialized or uninitialized. An initialized
+// packet number is simply an ordinal number. A sentinel value is used to
+// represent an uninitialized packet number.
+class QUIC_EXPORT_PRIVATE QuicPacketNumber {
+ public:
+  // Construct an uninitialized packet number.
+  constexpr QuicPacketNumber() : packet_number_(UninitializedPacketNumber()) {}
+
+  // Construct a packet number from uint64_t. |packet_number| cannot equal the
+  // sentinel value.
+  explicit constexpr QuicPacketNumber(uint64_t packet_number)
+      : packet_number_(packet_number) {
+    QUICHE_DCHECK_NE(UninitializedPacketNumber(), packet_number)
+        << "Use default constructor for uninitialized packet number";
+  }
+
+  // The sentinel value representing an uninitialized packet number.
+  static constexpr uint64_t UninitializedPacketNumber() {
+    return std::numeric_limits<uint64_t>::max();
+  }
+
+  // Packet number becomes uninitialized after calling this function.
+  void Clear();
+
+  // Updates this packet number to be |new_value| if it is greater than current
+  // value.
+  void UpdateMax(QuicPacketNumber new_value);
+
+  // REQUIRES: IsInitialized() == true.
+  uint64_t Hash() const;
+
+  // Converts packet number to uint64_t.
+  // REQUIRES: IsInitialized() == true.
+  uint64_t ToUint64() const;
+
+  // Returns true if packet number is considered initialized.
+  bool IsInitialized() const;
+
+  // REQUIRES: IsInitialized() == true && ToUint64() <
+  // numeric_limits<uint64_t>::max() - 1.
+  QuicPacketNumber& operator++();
+  QuicPacketNumber operator++(int);
+  // REQUIRES: IsInitialized() == true && ToUint64() >= 1.
+  QuicPacketNumber& operator--();
+  QuicPacketNumber operator--(int);
+
+  // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
+  // ToUint64() > |delta|.
+  QuicPacketNumber& operator+=(uint64_t delta);
+  // REQUIRES: IsInitialized() == true && ToUint64() >= |delta|.
+  QuicPacketNumber& operator-=(uint64_t delta);
+
+  // Human-readable representation suitable for logging.
+  std::string ToString() const;
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPacketNumber& p);
+
+ private:
+  // All following operators REQUIRE operands.Initialized() == true.
+  friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+
+  // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() > |delta|.
+  friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
+                                           uint64_t delta);
+  // REQUIRES: lhs.ToUint64() >= |delta|.
+  friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
+                                           uint64_t delta);
+  // REQUIRES: lhs >= rhs.
+  friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
+
+  uint64_t packet_number_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicPacketNumberHash {
+ public:
+  uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
+    return packet_number.Hash();
+  }
+};
+
+inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ == rhs.packet_number_;
+}
+
+inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ != rhs.packet_number_;
+}
+
+inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ < rhs.packet_number_;
+}
+
+inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ <= rhs.packet_number_;
+}
+
+inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ > rhs.packet_number_;
+}
+
+inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ >= rhs.packet_number_;
+}
+
+inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(lhs.IsInitialized());
+  QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - lhs.ToUint64(),
+                   delta);
+#endif
+  return QuicPacketNumber(lhs.packet_number_ + delta);
+}
+
+inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
+#ifndef NDEBUG
+  QUICHE_DCHECK(lhs.IsInitialized());
+  QUICHE_DCHECK_GE(lhs.ToUint64(), delta);
+#endif
+  return QuicPacketNumber(lhs.packet_number_ - delta);
+}
+
+inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ - rhs.packet_number_;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
diff --git a/quiche/quic/core/quic_packet_number_test.cc b/quiche/quic/core/quic_packet_number_test.cc
new file mode 100644
index 0000000..084a435
--- /dev/null
+++ b/quiche/quic/core/quic_packet_number_test.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packet_number.h"
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+TEST(QuicPacketNumberTest, BasicTest) {
+  QuicPacketNumber num;
+  EXPECT_FALSE(num.IsInitialized());
+
+  QuicPacketNumber num2(10);
+  EXPECT_TRUE(num2.IsInitialized());
+  EXPECT_EQ(10u, num2.ToUint64());
+  EXPECT_EQ(10u, num2.Hash());
+  num2.UpdateMax(num);
+  EXPECT_EQ(10u, num2.ToUint64());
+  num2.UpdateMax(QuicPacketNumber(9));
+  EXPECT_EQ(10u, num2.ToUint64());
+  num2.UpdateMax(QuicPacketNumber(11));
+  EXPECT_EQ(11u, num2.ToUint64());
+  num2.Clear();
+  EXPECT_FALSE(num2.IsInitialized());
+  num2.UpdateMax(QuicPacketNumber(9));
+  EXPECT_EQ(9u, num2.ToUint64());
+
+  QuicPacketNumber num4(0);
+  EXPECT_TRUE(num4.IsInitialized());
+  EXPECT_EQ(0u, num4.ToUint64());
+  EXPECT_EQ(0u, num4.Hash());
+  num4.Clear();
+  EXPECT_FALSE(num4.IsInitialized());
+}
+
+TEST(QuicPacketNumberTest, Operators) {
+  QuicPacketNumber num(100);
+  EXPECT_EQ(QuicPacketNumber(100), num++);
+  EXPECT_EQ(QuicPacketNumber(101), num);
+  EXPECT_EQ(QuicPacketNumber(101), num--);
+  EXPECT_EQ(QuicPacketNumber(100), num);
+
+  EXPECT_EQ(QuicPacketNumber(101), ++num);
+  EXPECT_EQ(QuicPacketNumber(100), --num);
+
+  QuicPacketNumber num3(0);
+  EXPECT_EQ(QuicPacketNumber(0), num3++);
+  EXPECT_EQ(QuicPacketNumber(1), num3);
+  EXPECT_EQ(QuicPacketNumber(2), ++num3);
+
+  EXPECT_EQ(QuicPacketNumber(2), num3--);
+  EXPECT_EQ(QuicPacketNumber(1), num3);
+  EXPECT_EQ(QuicPacketNumber(0), --num3);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_reader.cc b/quiche/quic/core/quic_packet_reader.cc
new file mode 100644
index 0000000..e6c1d2d
--- /dev/null
+++ b/quiche/quic/core/quic_packet_reader.cc
@@ -0,0 +1,135 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packet_reader.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_process_packet_interface.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+QuicPacketReader::QuicPacketReader()
+    : read_buffers_(kNumPacketsPerReadMmsgCall),
+      read_results_(kNumPacketsPerReadMmsgCall) {
+  QUICHE_DCHECK_EQ(read_buffers_.size(), read_results_.size());
+  for (size_t i = 0; i < read_results_.size(); ++i) {
+    read_results_[i].packet_buffer.buffer = read_buffers_[i].packet_buffer;
+    read_results_[i].packet_buffer.buffer_len =
+        sizeof(read_buffers_[i].packet_buffer);
+
+    read_results_[i].control_buffer.buffer = read_buffers_[i].control_buffer;
+    read_results_[i].control_buffer.buffer_len =
+        sizeof(read_buffers_[i].control_buffer);
+  }
+}
+
+QuicPacketReader::~QuicPacketReader() = default;
+
+bool QuicPacketReader::ReadAndDispatchPackets(
+    int fd,
+    int port,
+    const QuicClock& clock,
+    ProcessPacketInterface* processor,
+    QuicPacketCount* /*packets_dropped*/) {
+  // Reset all read_results for reuse.
+  for (size_t i = 0; i < read_results_.size(); ++i) {
+    read_results_[i].Reset(
+        /*packet_buffer_length=*/sizeof(read_buffers_[i].packet_buffer));
+  }
+
+  // Use clock.Now() as the packet receipt time, the time between packet
+  // arriving at the host and now is considered part of the network delay.
+  QuicTime now = clock.Now();
+
+  size_t packets_read = socket_api_.ReadMultiplePackets(
+      fd,
+      BitMask64(QuicUdpPacketInfoBit::DROPPED_PACKETS,
+                QuicUdpPacketInfoBit::PEER_ADDRESS,
+                QuicUdpPacketInfoBit::V4_SELF_IP,
+                QuicUdpPacketInfoBit::V6_SELF_IP,
+                QuicUdpPacketInfoBit::RECV_TIMESTAMP, QuicUdpPacketInfoBit::TTL,
+                QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER),
+      &read_results_);
+  for (size_t i = 0; i < packets_read; ++i) {
+    auto& result = read_results_[i];
+    if (!result.ok) {
+      QUIC_CODE_COUNT(quic_packet_reader_read_failure);
+      continue;
+    }
+
+    if (!result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+      QUIC_BUG(quic_bug_10329_1) << "Unable to get peer socket address.";
+      continue;
+    }
+
+    QuicSocketAddress peer_address =
+        result.packet_info.peer_address().Normalized();
+
+    QuicIpAddress self_ip = GetSelfIpFromPacketInfo(
+        result.packet_info, peer_address.host().IsIPv6());
+    if (!self_ip.IsInitialized()) {
+      QUIC_BUG(quic_bug_10329_2) << "Unable to get self IP address.";
+      continue;
+    }
+
+    bool has_ttl = result.packet_info.HasValue(QuicUdpPacketInfoBit::TTL);
+    int ttl = has_ttl ? result.packet_info.ttl() : 0;
+    if (!has_ttl) {
+      QUIC_CODE_COUNT(quic_packet_reader_no_ttl);
+    }
+
+    char* headers = nullptr;
+    size_t headers_length = 0;
+    if (result.packet_info.HasValue(
+            QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
+      headers = result.packet_info.google_packet_headers().buffer;
+      headers_length = result.packet_info.google_packet_headers().buffer_len;
+    } else {
+      QUIC_CODE_COUNT(quic_packet_reader_no_google_packet_header);
+    }
+
+    QuicReceivedPacket packet(
+        result.packet_buffer.buffer, result.packet_buffer.buffer_len, now,
+        /*owns_buffer=*/false, ttl, has_ttl, headers, headers_length,
+        /*owns_header_buffer=*/false);
+
+    QuicSocketAddress self_address(self_ip, port);
+    processor->ProcessPacket(self_address, peer_address, packet);
+  }
+
+  // We may not have read all of the packets available on the socket.
+  return packets_read == kNumPacketsPerReadMmsgCall;
+}
+
+// static
+QuicIpAddress QuicPacketReader::GetSelfIpFromPacketInfo(
+    const QuicUdpPacketInfo& packet_info,
+    bool prefer_v6_ip) {
+  if (prefer_v6_ip) {
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
+      return packet_info.self_v6_ip();
+    }
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
+      return packet_info.self_v4_ip();
+    }
+  } else {
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
+      return packet_info.self_v4_ip();
+    }
+    if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
+      return packet_info.self_v6_ip();
+    }
+  }
+  return QuicIpAddress();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_reader.h b/quiche/quic/core/quic_packet_reader.h
new file mode 100644
index 0000000..18b78d7
--- /dev/null
+++ b/quiche/quic/core/quic_packet_reader.h
@@ -0,0 +1,67 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A class to read incoming QUIC packets from the UDP socket.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
+
+#include "absl/base/optimization.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_process_packet_interface.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Read in larger batches to minimize recvmmsg overhead.
+const int kNumPacketsPerReadMmsgCall = 16;
+
+class QUIC_EXPORT_PRIVATE QuicPacketReader {
+ public:
+  QuicPacketReader();
+  QuicPacketReader(const QuicPacketReader&) = delete;
+  QuicPacketReader& operator=(const QuicPacketReader&) = delete;
+
+  virtual ~QuicPacketReader();
+
+  // Reads a number of packets from the given fd, and then passes them off to
+  // the PacketProcessInterface.  Returns true if there may be additional
+  // packets available on the socket.
+  // Populates |packets_dropped| if it is non-null and the socket is configured
+  // to track dropped packets and some packets are read.
+  // If the socket has timestamping enabled, the per packet timestamps will be
+  // passed to the processor. Otherwise, |clock| will be used.
+  virtual bool ReadAndDispatchPackets(int fd,
+                                      int port,
+                                      const QuicClock& clock,
+                                      ProcessPacketInterface* processor,
+                                      QuicPacketCount* packets_dropped);
+
+ private:
+  // Return the self ip from |packet_info|.
+  // For dual stack sockets, |packet_info| may contain both a v4 and a v6 ip, in
+  // that case, |prefer_v6_ip| is used to determine which one is used as the
+  // return value. If neither v4 nor v6 ip exists, return an uninitialized ip.
+  static QuicIpAddress GetSelfIpFromPacketInfo(
+      const QuicUdpPacketInfo& packet_info,
+      bool prefer_v6_ip);
+
+  struct QUIC_EXPORT_PRIVATE ReadBuffer {
+    ABSL_CACHELINE_ALIGNED char
+        control_buffer[kDefaultUdpPacketControlBufferSize];  // For ancillary
+                                                             // data.
+    ABSL_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize];
+  };
+
+  QuicUdpSocketApi socket_api_;
+  std::vector<ReadBuffer> read_buffers_;
+  QuicUdpSocketApi::ReadPacketResults read_results_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
diff --git a/quiche/quic/core/quic_packet_writer.h b/quiche/quic/core/quic_packet_writer.h
new file mode 100644
index 0000000..1406c19
--- /dev/null
+++ b/quiche/quic/core/quic_packet_writer.h
@@ -0,0 +1,170 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
+
+#include <cstddef>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+struct WriteResult;
+
+struct QUIC_EXPORT_PRIVATE PerPacketOptions {
+  virtual ~PerPacketOptions() {}
+
+  // Returns a heap-allocated copy of |this|.
+  //
+  // The subclass implementation of this method should look like this:
+  //   return std::make_unique<MyAwesomePerPacketOptions>(*this);
+  //
+  // This method is declared pure virtual in order to ensure the subclasses
+  // would not forget to override it.
+  virtual std::unique_ptr<PerPacketOptions> Clone() const = 0;
+
+  // Specifies ideal release time delay for this packet.
+  QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
+  // Whether it is allowed to send this packet without |release_time_delay|.
+  bool allow_burst = false;
+};
+
+// An interface between writers and the entity managing the
+// socket (in our case the QuicDispatcher).  This allows the Dispatcher to
+// control writes, and manage any writers who end up write blocked.
+// A concrete writer works in one of the two modes:
+// - PassThrough mode. This is the default mode. Caller calls WritePacket with
+//   caller-allocated packet buffer. Unless the writer is blocked, each call to
+//   WritePacket triggers a write using the underlying socket API.
+//
+// - Batch mode. In this mode, a call to WritePacket may not cause a packet to
+//   be sent using the underlying socket API. Instead, multiple packets are
+//   saved in the writer's internal buffer until they are flushed. The flush can
+//   be explicit, by calling Flush, or implicit, e.g. by calling
+//   WritePacket when the internal buffer is near full.
+//
+// Buffer management:
+// In Batch mode, a writer manages an internal buffer, which is large enough to
+// hold multiple packets' data. If the caller calls WritePacket with a
+// caller-allocated packet buffer, the writer will memcpy the buffer into the
+// internal buffer. Caller can also avoid this memcpy by:
+// 1. Call GetNextWriteLocation to get a pointer P into the internal buffer.
+// 2. Serialize the packet directly to P.
+// 3. Call WritePacket with P as the |buffer|.
+class QUIC_EXPORT_PRIVATE QuicPacketWriter {
+ public:
+  virtual ~QuicPacketWriter() {}
+
+  // PassThrough mode:
+  // Sends the packet out to the peer, with some optional per-packet options.
+  // If the write succeeded, the result's status is WRITE_STATUS_OK and
+  // bytes_written is populated. If the write failed, the result's status is
+  // WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and error_code is populated.
+  //
+  // Batch mode:
+  // If the writer is blocked, return WRITE_STATUS_BLOCKED immediately.
+  // If the packet can be batched with other buffered packets, save the packet
+  // to the internal buffer.
+  // If the packet can not be batched, or the internal buffer is near full after
+  // it is buffered, the internal buffer is flushed to free up space.
+  // Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) on success. When
+  // <bytes_flushed> is zero, it means the packet is buffered and not flushed.
+  // Return WRITE_STATUS_BLOCKED if the packet is not buffered and the socket is
+  // blocked while flushing.
+  // Otherwise return an error status.
+  //
+  // Options must be either null, or created for the particular QuicPacketWriter
+  // implementation. Options may be ignored, depending on the implementation.
+  //
+  // Some comment about memory management if |buffer| was previously acquired
+  // by a call to "GetNextWriteLocation()":
+  //
+  // a) When WRITE_STATUS_OK is returned, the caller expects the writer owns the
+  // packet buffers and they will be released when the write finishes.
+  //
+  // b) When this function returns any status >= WRITE_STATUS_ERROR, the caller
+  // expects the writer releases the buffer (if needed) before the function
+  // returns.
+  //
+  // c) When WRITE_STATUS_BLOCKED is returned, the caller makes a copy of the
+  // buffer and will retry after unblock, so if |payload| is allocated from
+  // GetNextWriteLocation(), it
+  //    1) needs to be released before return, and
+  //    2) the content of |payload| should not change after return.
+  //
+  // d) When WRITE_STATUS_BLOCKED_DATA_BUFFERED is returned, the caller expects
+  // 1) the writer owns the packet buffers, and 2) the writer will re-send the
+  // packet when it unblocks.
+  virtual WriteResult WritePacket(const char* buffer,
+                                  size_t buf_len,
+                                  const QuicIpAddress& self_address,
+                                  const QuicSocketAddress& peer_address,
+                                  PerPacketOptions* options) = 0;
+
+  // Returns true if the network socket is not writable.
+  virtual bool IsWriteBlocked() const = 0;
+
+  // Records that the socket has become writable, for example when an EPOLLOUT
+  // is received or an asynchronous write completes.
+  virtual void SetWritable() = 0;
+
+  // The error code used by the writer to indicate that the write failed due to
+  // supplied packet being too big.  This is equivalent to returning
+  // WRITE_STATUS_MSG_TOO_BIG as a status.
+  virtual absl::optional<int> MessageTooBigErrorCode() const = 0;
+
+  // Returns the maximum size of the packet which can be written using this
+  // writer for the supplied peer address.  This size may actually exceed the
+  // size of a valid QUIC packet.
+  virtual QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const = 0;
+
+  // Returns true if the socket supports release timestamp.
+  virtual bool SupportsReleaseTime() const = 0;
+
+  // True=Batch mode. False=PassThrough mode.
+  virtual bool IsBatchMode() const = 0;
+
+  // PassThrough mode: Return {nullptr, nullptr}
+  //
+  // Batch mode:
+  // Return the QuicPacketBuffer for the next packet. A minimum of
+  // kMaxOutgoingPacketSize is guaranteed to be available from the returned
+  // address. If the internal buffer does not have enough space,
+  // {nullptr, nullptr} is returned. All arguments should be identical to the
+  // follow-up call to |WritePacket|, they are here to allow advanced packet
+  // memory management in packet writers, e.g. one packet buffer pool per
+  // |peer_address|.
+  //
+  // If QuicPacketBuffer.release_buffer is !nullptr, it should be called iff
+  // the caller does not call WritePacket for the returned buffer.
+  virtual QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) = 0;
+
+  // PassThrough mode: Return WriteResult(WRITE_STATUS_OK, 0).
+  //
+  // Batch mode:
+  // Try send all buffered packets.
+  // - Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered
+  //   packets were sent successfully.
+  // - Return WRITE_STATUS_BLOCKED if the underlying socket is blocked while
+  //   sending. Some packets may have been sent, packets not sent will stay in
+  //   the internal buffer.
+  // - Return a status >= WRITE_STATUS_ERROR if an error was encuontered while
+  //   sending. As this is not a re-tryable error, any batched packets which
+  //   were on memory acquired via GetNextWriteLocation() should be released and
+  //   the batch should be dropped.
+  virtual WriteResult Flush() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
diff --git a/quiche/quic/core/quic_packet_writer_wrapper.cc b/quiche/quic/core/quic_packet_writer_wrapper.cc
new file mode 100644
index 0000000..522f6bf
--- /dev/null
+++ b/quiche/quic/core/quic_packet_writer_wrapper.cc
@@ -0,0 +1,83 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+QuicPacketWriterWrapper::QuicPacketWriterWrapper() = default;
+
+QuicPacketWriterWrapper::~QuicPacketWriterWrapper() {
+  unset_writer();
+}
+
+WriteResult QuicPacketWriterWrapper::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  return writer_->WritePacket(buffer, buf_len, self_address, peer_address,
+                              options);
+}
+
+bool QuicPacketWriterWrapper::IsWriteBlocked() const {
+  return writer_->IsWriteBlocked();
+}
+
+void QuicPacketWriterWrapper::SetWritable() {
+  writer_->SetWritable();
+}
+
+absl::optional<int> QuicPacketWriterWrapper::MessageTooBigErrorCode() const {
+  return writer_->MessageTooBigErrorCode();
+}
+
+QuicByteCount QuicPacketWriterWrapper::GetMaxPacketSize(
+    const QuicSocketAddress& peer_address) const {
+  return writer_->GetMaxPacketSize(peer_address);
+}
+
+bool QuicPacketWriterWrapper::SupportsReleaseTime() const {
+  return writer_->SupportsReleaseTime();
+}
+
+bool QuicPacketWriterWrapper::IsBatchMode() const {
+  return writer_->IsBatchMode();
+}
+
+QuicPacketBuffer QuicPacketWriterWrapper::GetNextWriteLocation(
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address) {
+  return writer_->GetNextWriteLocation(self_address, peer_address);
+}
+
+WriteResult QuicPacketWriterWrapper::Flush() {
+  return writer_->Flush();
+}
+
+void QuicPacketWriterWrapper::set_writer(QuicPacketWriter* writer) {
+  unset_writer();
+  writer_ = writer;
+  owns_writer_ = true;
+}
+
+void QuicPacketWriterWrapper::set_non_owning_writer(QuicPacketWriter* writer) {
+  unset_writer();
+  writer_ = writer;
+  owns_writer_ = false;
+}
+
+void QuicPacketWriterWrapper::unset_writer() {
+  if (owns_writer_) {
+    delete writer_;
+  }
+
+  owns_writer_ = false;
+  writer_ = nullptr;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packet_writer_wrapper.h b/quiche/quic/core/quic_packet_writer_wrapper.h
new file mode 100644
index 0000000..4f8ab61
--- /dev/null
+++ b/quiche/quic/core/quic_packet_writer_wrapper.h
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "quiche/quic/core/quic_packet_writer.h"
+
+namespace quic {
+
+// Wraps a writer object to allow dynamically extending functionality. Use
+// cases: replace writer while dispatcher and connections hold on to the
+// wrapper; mix in monitoring; mix in mocks in unit tests.
+class QUIC_NO_EXPORT QuicPacketWriterWrapper : public QuicPacketWriter {
+ public:
+  QuicPacketWriterWrapper();
+  QuicPacketWriterWrapper(const QuicPacketWriterWrapper&) = delete;
+  QuicPacketWriterWrapper& operator=(const QuicPacketWriterWrapper&) = delete;
+  ~QuicPacketWriterWrapper() override;
+
+  // Default implementation of the QuicPacketWriter interface. Passes everything
+  // to |writer_|.
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+  bool IsWriteBlocked() const override;
+  void SetWritable() override;
+  absl::optional<int> MessageTooBigErrorCode() const override;
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const override;
+  bool SupportsReleaseTime() const override;
+  bool IsBatchMode() const override;
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) override;
+  WriteResult Flush() override;
+
+  // Takes ownership of |writer|.
+  void set_writer(QuicPacketWriter* writer);
+
+  // Does not take ownership of |writer|.
+  void set_non_owning_writer(QuicPacketWriter* writer);
+
+  virtual void set_peer_address(const QuicSocketAddress& /*peer_address*/) {}
+
+  QuicPacketWriter* writer() { return writer_; }
+
+ private:
+  void unset_writer();
+
+  QuicPacketWriter* writer_ = nullptr;
+  bool owns_writer_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_WRAPPER_H_
diff --git a/quiche/quic/core/quic_packets.cc b/quiche/quic/core/quic_packets.cc
new file mode 100644
index 0000000..d3db3b7
--- /dev/null
+++ b/quiche/quic/core/quic_packets.cc
@@ -0,0 +1,596 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packets.h"
+
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicConnectionId GetServerConnectionIdAsRecipient(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionId GetClientConnectionIdAsRecipient(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
+                                               Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.destination_connection_id;
+  }
+  return header.source_connection_id;
+}
+
+QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.destination_connection_id_included;
+  }
+  return header.source_connection_id_included;
+}
+
+QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
+                                               Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.source_connection_id;
+  }
+  return header.destination_connection_id;
+}
+
+QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
+    const QuicPacketHeader& header,
+    Perspective perspective) {
+  if (perspective == Perspective::IS_CLIENT) {
+    return header.source_connection_id_included;
+  }
+  return header.destination_connection_id_included;
+}
+
+QuicConnectionIdLength GetIncludedConnectionIdLength(
+    QuicConnectionId connection_id,
+    QuicConnectionIdIncluded connection_id_included) {
+  QUICHE_DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
+                connection_id_included == CONNECTION_ID_ABSENT);
+  return connection_id_included == CONNECTION_ID_PRESENT
+             ? static_cast<QuicConnectionIdLength>(connection_id.length())
+             : PACKET_0BYTE_CONNECTION_ID;
+}
+
+QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(
+    const QuicPacketHeader& header) {
+  return GetIncludedConnectionIdLength(
+      header.destination_connection_id,
+      header.destination_connection_id_included);
+}
+
+QuicConnectionIdLength GetIncludedSourceConnectionIdLength(
+    const QuicPacketHeader& header) {
+  return GetIncludedConnectionIdLength(header.source_connection_id,
+                                       header.source_connection_id_included);
+}
+
+size_t GetPacketHeaderSize(QuicTransportVersion version,
+                           const QuicPacketHeader& header) {
+  return GetPacketHeaderSize(
+      version, GetIncludedDestinationConnectionIdLength(header),
+      GetIncludedSourceConnectionIdLength(header), header.version_flag,
+      header.nonce != nullptr, header.packet_number_length,
+      header.retry_token_length_length, header.retry_token.length(),
+      header.length_length);
+}
+
+size_t GetPacketHeaderSize(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length) {
+  if (VersionHasIetfInvariantHeader(version)) {
+    if (include_version) {
+      // Long header.
+      size_t size = kPacketHeaderTypeSize + kConnectionIdLengthSize +
+                    destination_connection_id_length +
+                    source_connection_id_length + packet_number_length +
+                    kQuicVersionSize;
+      if (include_diversification_nonce) {
+        size += kDiversificationNonceSize;
+      }
+      if (VersionHasLengthPrefixedConnectionIds(version)) {
+        size += kConnectionIdLengthSize;
+      }
+      QUICHE_DCHECK(
+          QuicVersionHasLongHeaderLengths(version) ||
+          retry_token_length_length + retry_token_length + length_length == 0);
+      if (QuicVersionHasLongHeaderLengths(version)) {
+        size += retry_token_length_length + retry_token_length + length_length;
+      }
+      return size;
+    }
+    // Short header.
+    return kPacketHeaderTypeSize + destination_connection_id_length +
+           packet_number_length;
+  }
+  // Google QUIC versions <= 43 can only carry one connection ID.
+  QUICHE_DCHECK(destination_connection_id_length == 0 ||
+                source_connection_id_length == 0);
+  return kPublicFlagsSize + destination_connection_id_length +
+         source_connection_id_length +
+         (include_version ? kQuicVersionSize : 0) + packet_number_length +
+         (include_diversification_nonce ? kDiversificationNonceSize : 0);
+}
+
+size_t GetStartOfEncryptedData(QuicTransportVersion version,
+                               const QuicPacketHeader& header) {
+  return GetPacketHeaderSize(version, header);
+}
+
+size_t GetStartOfEncryptedData(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length) {
+  // Encryption starts before private flags.
+  return GetPacketHeaderSize(
+      version, destination_connection_id_length, source_connection_id_length,
+      include_version, include_diversification_nonce, packet_number_length,
+      retry_token_length_length, retry_token_length, length_length);
+}
+
+QuicPacketHeader::QuicPacketHeader()
+    : destination_connection_id(EmptyQuicConnectionId()),
+      destination_connection_id_included(CONNECTION_ID_PRESENT),
+      source_connection_id(EmptyQuicConnectionId()),
+      source_connection_id_included(CONNECTION_ID_ABSENT),
+      reset_flag(false),
+      version_flag(false),
+      has_possible_stateless_reset_token(false),
+      packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
+      version(UnsupportedQuicVersion()),
+      nonce(nullptr),
+      form(GOOGLE_QUIC_PACKET),
+      long_packet_type(INITIAL),
+      possible_stateless_reset_token({}),
+      retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
+      retry_token(absl::string_view()),
+      length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
+      remaining_packet_length(0) {}
+
+QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
+
+QuicPacketHeader::~QuicPacketHeader() {}
+
+QuicPacketHeader& QuicPacketHeader::operator=(const QuicPacketHeader& other) =
+    default;
+
+QuicPublicResetPacket::QuicPublicResetPacket()
+    : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
+
+QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
+    : connection_id(connection_id), nonce_proof(0) {}
+
+QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
+    : connection_id(EmptyQuicConnectionId()) {}
+
+QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
+    QuicConnectionId connection_id)
+    : connection_id(connection_id) {}
+
+QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
+    const QuicVersionNegotiationPacket& other) = default;
+
+QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
+    : stateless_reset_token({}) {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
+    const QuicPacketHeader& header,
+    StatelessResetToken token)
+    : header(header), stateless_reset_token(token) {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
+    const QuicIetfStatelessResetPacket& other) = default;
+
+QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
+  os << "{ destination_connection_id: " << header.destination_connection_id
+     << " ("
+     << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
+             ? "present"
+             : "absent")
+     << "), source_connection_id: " << header.source_connection_id << " ("
+     << (header.source_connection_id_included == CONNECTION_ID_PRESENT
+             ? "present"
+             : "absent")
+     << "), packet_number_length: "
+     << static_cast<int>(header.packet_number_length)
+     << ", reset_flag: " << header.reset_flag
+     << ", version_flag: " << header.version_flag;
+  if (header.version_flag) {
+    os << ", version: " << ParsedQuicVersionToString(header.version);
+    if (header.long_packet_type != INVALID_PACKET_TYPE) {
+      os << ", long_packet_type: "
+         << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
+    }
+    if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+      os << ", retry_token_length_length: "
+         << static_cast<int>(header.retry_token_length_length);
+    }
+    if (header.retry_token.length() != 0) {
+      os << ", retry_token_length: " << header.retry_token.length();
+    }
+    if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+      os << ", length_length: " << static_cast<int>(header.length_length);
+    }
+    if (header.remaining_packet_length != 0) {
+      os << ", remaining_packet_length: " << header.remaining_packet_length;
+    }
+  }
+  if (header.nonce != nullptr) {
+    os << ", diversification_nonce: "
+       << absl::BytesToHexString(
+              absl::string_view(header.nonce->data(), header.nonce->size()));
+  }
+  os << ", packet_number: " << header.packet_number << " }\n";
+  return os;
+}
+
+QuicData::QuicData(const char* buffer, size_t length)
+    : buffer_(buffer), length_(length), owns_buffer_(false) {}
+
+QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
+    : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
+
+QuicData::QuicData(absl::string_view packet_data)
+    : buffer_(packet_data.data()),
+      length_(packet_data.length()),
+      owns_buffer_(false) {}
+
+QuicData::~QuicData() {
+  if (owns_buffer_) {
+    delete[] const_cast<char*>(buffer_);
+  }
+}
+
+QuicPacket::QuicPacket(
+    char* buffer,
+    size_t length,
+    bool owns_buffer,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool includes_version,
+    bool includes_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length)
+    : QuicData(buffer, length, owns_buffer),
+      buffer_(buffer),
+      destination_connection_id_length_(destination_connection_id_length),
+      source_connection_id_length_(source_connection_id_length),
+      includes_version_(includes_version),
+      includes_diversification_nonce_(includes_diversification_nonce),
+      packet_number_length_(packet_number_length),
+      retry_token_length_length_(retry_token_length_length),
+      retry_token_length_(retry_token_length),
+      length_length_(length_length) {}
+
+QuicPacket::QuicPacket(QuicTransportVersion /*version*/,
+                       char* buffer,
+                       size_t length,
+                       bool owns_buffer,
+                       const QuicPacketHeader& header)
+    : QuicPacket(buffer,
+                 length,
+                 owns_buffer,
+                 GetIncludedDestinationConnectionIdLength(header),
+                 GetIncludedSourceConnectionIdLength(header),
+                 header.version_flag,
+                 header.nonce != nullptr,
+                 header.packet_number_length,
+                 header.retry_token_length_length,
+                 header.retry_token.length(),
+                 header.length_length) {}
+
+QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
+    : QuicData(buffer, length) {}
+
+QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
+                                         size_t length,
+                                         bool owns_buffer)
+    : QuicData(buffer, length, owns_buffer) {}
+
+QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data)
+    : QuicData(data) {}
+
+std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
+  char* buffer = new char[this->length()];
+  memcpy(buffer, this->data(), this->length());
+  return std::make_unique<QuicEncryptedPacket>(buffer, this->length(), true);
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
+  os << s.length() << "-byte data";
+  return os;
+}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time)
+    : QuicReceivedPacket(buffer,
+                         length,
+                         receipt_time,
+                         false /* owns_buffer */) {}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time,
+                                       bool owns_buffer)
+    : QuicReceivedPacket(buffer,
+                         length,
+                         receipt_time,
+                         owns_buffer,
+                         0 /* ttl */,
+                         true /* ttl_valid */) {}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time,
+                                       bool owns_buffer,
+                                       int ttl,
+                                       bool ttl_valid)
+    : quic::QuicReceivedPacket(buffer,
+                               length,
+                               receipt_time,
+                               owns_buffer,
+                               ttl,
+                               ttl_valid,
+                               nullptr /* packet_headers */,
+                               0 /* headers_length */,
+                               false /* owns_header_buffer */) {}
+
+QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
+                                       size_t length,
+                                       QuicTime receipt_time,
+                                       bool owns_buffer,
+                                       int ttl,
+                                       bool ttl_valid,
+                                       char* packet_headers,
+                                       size_t headers_length,
+                                       bool owns_header_buffer)
+    : QuicEncryptedPacket(buffer, length, owns_buffer),
+      receipt_time_(receipt_time),
+      ttl_(ttl_valid ? ttl : -1),
+      packet_headers_(packet_headers),
+      headers_length_(headers_length),
+      owns_header_buffer_(owns_header_buffer) {}
+
+QuicReceivedPacket::~QuicReceivedPacket() {
+  if (owns_header_buffer_) {
+    delete[] static_cast<char*>(packet_headers_);
+  }
+}
+
+std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
+  char* buffer = new char[this->length()];
+  memcpy(buffer, this->data(), this->length());
+  if (this->packet_headers()) {
+    char* headers_buffer = new char[this->headers_length()];
+    memcpy(headers_buffer, this->packet_headers(), this->headers_length());
+    return std::make_unique<QuicReceivedPacket>(
+        buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
+        headers_buffer, this->headers_length(), true);
+  }
+
+  return std::make_unique<QuicReceivedPacket>(
+      buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
+  os << s.length() << "-byte data";
+  return os;
+}
+
+absl::string_view QuicPacket::AssociatedData(
+    QuicTransportVersion version) const {
+  return absl::string_view(
+      data(),
+      GetStartOfEncryptedData(version, destination_connection_id_length_,
+                              source_connection_id_length_, includes_version_,
+                              includes_diversification_nonce_,
+                              packet_number_length_, retry_token_length_length_,
+                              retry_token_length_, length_length_));
+}
+
+absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const {
+  const size_t start_of_encrypted_data = GetStartOfEncryptedData(
+      version, destination_connection_id_length_, source_connection_id_length_,
+      includes_version_, includes_diversification_nonce_, packet_number_length_,
+      retry_token_length_length_, retry_token_length_, length_length_);
+  return absl::string_view(data() + start_of_encrypted_data,
+                           length() - start_of_encrypted_data);
+}
+
+SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
+                                   QuicPacketNumberLength packet_number_length,
+                                   const char* encrypted_buffer,
+                                   QuicPacketLength encrypted_length,
+                                   bool has_ack,
+                                   bool has_stop_waiting)
+    : encrypted_buffer(encrypted_buffer),
+      encrypted_length(encrypted_length),
+      has_crypto_handshake(NOT_HANDSHAKE),
+      packet_number(packet_number),
+      packet_number_length(packet_number_length),
+      encryption_level(ENCRYPTION_INITIAL),
+      has_ack(has_ack),
+      has_stop_waiting(has_stop_waiting),
+      transmission_type(NOT_RETRANSMISSION),
+      has_ack_frame_copy(false),
+      has_ack_frequency(false),
+      has_message(false),
+      fate(SEND_TO_WRITER) {}
+
+SerializedPacket::SerializedPacket(SerializedPacket&& other)
+    : has_crypto_handshake(other.has_crypto_handshake),
+      packet_number(other.packet_number),
+      packet_number_length(other.packet_number_length),
+      encryption_level(other.encryption_level),
+      has_ack(other.has_ack),
+      has_stop_waiting(other.has_stop_waiting),
+      transmission_type(other.transmission_type),
+      largest_acked(other.largest_acked),
+      has_ack_frame_copy(other.has_ack_frame_copy),
+      has_ack_frequency(other.has_ack_frequency),
+      has_message(other.has_message),
+      fate(other.fate),
+      peer_address(other.peer_address) {
+  if (this != &other) {
+    if (release_encrypted_buffer && encrypted_buffer != nullptr) {
+      release_encrypted_buffer(encrypted_buffer);
+    }
+    encrypted_buffer = other.encrypted_buffer;
+    encrypted_length = other.encrypted_length;
+    release_encrypted_buffer = std::move(other.release_encrypted_buffer);
+    other.release_encrypted_buffer = nullptr;
+
+    retransmittable_frames.swap(other.retransmittable_frames);
+    nonretransmittable_frames.swap(other.nonretransmittable_frames);
+  }
+}
+
+SerializedPacket::~SerializedPacket() {
+  if (release_encrypted_buffer && encrypted_buffer != nullptr) {
+    release_encrypted_buffer(encrypted_buffer);
+  }
+
+  if (!retransmittable_frames.empty()) {
+    DeleteFrames(&retransmittable_frames);
+  }
+  for (auto& frame : nonretransmittable_frames) {
+    if (!has_ack_frame_copy && frame.type == ACK_FRAME) {
+      // Do not delete ack frame if the packet does not own a copy of it.
+      continue;
+    }
+    DeleteFrame(&frame);
+  }
+}
+
+SerializedPacket* CopySerializedPacket(const SerializedPacket& serialized,
+                                       quiche::QuicheBufferAllocator* allocator,
+                                       bool copy_buffer) {
+  SerializedPacket* copy = new SerializedPacket(
+      serialized.packet_number, serialized.packet_number_length,
+      serialized.encrypted_buffer, serialized.encrypted_length,
+      serialized.has_ack, serialized.has_stop_waiting);
+  copy->has_crypto_handshake = serialized.has_crypto_handshake;
+  copy->encryption_level = serialized.encryption_level;
+  copy->transmission_type = serialized.transmission_type;
+  copy->largest_acked = serialized.largest_acked;
+  copy->has_ack_frequency = serialized.has_ack_frequency;
+  copy->has_message = serialized.has_message;
+  copy->fate = serialized.fate;
+  copy->peer_address = serialized.peer_address;
+
+  if (copy_buffer) {
+    copy->encrypted_buffer = CopyBuffer(serialized);
+    copy->release_encrypted_buffer = [](const char* p) { delete[] p; };
+  }
+  // Copy underlying frames.
+  copy->retransmittable_frames =
+      CopyQuicFrames(allocator, serialized.retransmittable_frames);
+  QUICHE_DCHECK(copy->nonretransmittable_frames.empty());
+  for (const auto& frame : serialized.nonretransmittable_frames) {
+    if (frame.type == ACK_FRAME) {
+      copy->has_ack_frame_copy = true;
+    }
+    copy->nonretransmittable_frames.push_back(CopyQuicFrame(allocator, frame));
+  }
+  return copy;
+}
+
+char* CopyBuffer(const SerializedPacket& packet) {
+  return CopyBuffer(packet.encrypted_buffer, packet.encrypted_length);
+}
+
+char* CopyBuffer(const char* encrypted_buffer,
+                 QuicPacketLength encrypted_length) {
+  char* dst_buffer = new char[encrypted_length];
+  memcpy(dst_buffer, encrypted_buffer, encrypted_length);
+  return dst_buffer;
+}
+
+ReceivedPacketInfo::ReceivedPacketInfo(const QuicSocketAddress& self_address,
+                                       const QuicSocketAddress& peer_address,
+                                       const QuicReceivedPacket& packet)
+    : self_address(self_address),
+      peer_address(peer_address),
+      packet(packet),
+      form(GOOGLE_QUIC_PACKET),
+      long_packet_type(INVALID_PACKET_TYPE),
+      version_flag(false),
+      use_length_prefix(false),
+      version_label(0),
+      version(ParsedQuicVersion::Unsupported()),
+      destination_connection_id(EmptyQuicConnectionId()),
+      source_connection_id(EmptyQuicConnectionId()) {}
+
+ReceivedPacketInfo::~ReceivedPacketInfo() {}
+
+std::string ReceivedPacketInfo::ToString() const {
+  std::string output =
+      absl::StrCat("{ self_address: ", self_address.ToString(),
+                   ", peer_address: ", peer_address.ToString(),
+                   ", packet_length: ", packet.length(),
+                   ", header_format: ", form, ", version_flag: ", version_flag);
+  if (version_flag) {
+    absl::StrAppend(&output, ", version: ", ParsedQuicVersionToString(version));
+  }
+  absl::StrAppend(
+      &output,
+      ", destination_connection_id: ", destination_connection_id.ToString(),
+      ", source_connection_id: ", source_connection_id.ToString(), " }\n");
+  return output;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ReceivedPacketInfo& packet_info) {
+  os << packet_info.ToString();
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_packets.h b/quiche/quic/core/quic_packets.h
new file mode 100644
index 0000000..98ab413
--- /dev/null
+++ b/quiche/quic/core/quic_packets.h
@@ -0,0 +1,462 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKETS_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKETS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_ack_listener_interface.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+class QuicPacket;
+struct QuicPacketHeader;
+
+// Returns the destination connection ID of |header| when |perspective| is
+// server, and the source connection ID when |perspective| is client.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetServerConnectionIdAsRecipient(const QuicPacketHeader& header,
+                                 Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// client, and the source connection ID when |perspective| is server.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetClientConnectionIdAsRecipient(const QuicPacketHeader& header,
+                                 Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// client, and the source connection ID when |perspective| is server.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetServerConnectionIdAsSender(const QuicPacketHeader& header,
+                              Perspective perspective);
+
+// Returns the destination connection ID included of |header| when |perspective|
+// is client, and the source connection ID included when |perspective| is
+// server.
+QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
+GetServerConnectionIdIncludedAsSender(const QuicPacketHeader& header,
+                                      Perspective perspective);
+
+// Returns the destination connection ID of |header| when |perspective| is
+// server, and the source connection ID when |perspective| is client.
+QUIC_EXPORT_PRIVATE QuicConnectionId
+GetClientConnectionIdAsSender(const QuicPacketHeader& header,
+                              Perspective perspective);
+
+// Returns the destination connection ID included of |header| when |perspective|
+// is server, and the source connection ID included when |perspective| is
+// client.
+QUIC_EXPORT_PRIVATE QuicConnectionIdIncluded
+GetClientConnectionIdIncludedAsSender(const QuicPacketHeader& header,
+                                      Perspective perspective);
+
+// Number of connection ID bytes that are actually included over the wire.
+QUIC_EXPORT_PRIVATE QuicConnectionIdLength
+GetIncludedConnectionIdLength(QuicConnectionId connection_id,
+                              QuicConnectionIdIncluded connection_id_included);
+
+// Number of destination connection ID bytes that are actually included over the
+// wire for this particular header.
+QUIC_EXPORT_PRIVATE QuicConnectionIdLength
+GetIncludedDestinationConnectionIdLength(const QuicPacketHeader& header);
+
+// Number of source connection ID bytes that are actually included over the
+// wire for this particular header.
+QUIC_EXPORT_PRIVATE QuicConnectionIdLength
+GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header);
+
+// Size in bytes of the data packet header.
+QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version,
+                                               const QuicPacketHeader& header);
+
+QUIC_EXPORT_PRIVATE size_t
+GetPacketHeaderSize(QuicTransportVersion version,
+                    QuicConnectionIdLength destination_connection_id_length,
+                    QuicConnectionIdLength source_connection_id_length,
+                    bool include_version,
+                    bool include_diversification_nonce,
+                    QuicPacketNumberLength packet_number_length,
+                    QuicVariableLengthIntegerLength retry_token_length_length,
+                    QuicByteCount retry_token_length,
+                    QuicVariableLengthIntegerLength length_length);
+
+// Index of the first byte in a QUIC packet of encrypted data.
+QUIC_EXPORT_PRIVATE size_t
+GetStartOfEncryptedData(QuicTransportVersion version,
+                        const QuicPacketHeader& header);
+
+QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length,
+    bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    QuicVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    QuicVariableLengthIntegerLength length_length);
+
+struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
+  QuicPacketHeader();
+  QuicPacketHeader(const QuicPacketHeader& other);
+  ~QuicPacketHeader();
+
+  QuicPacketHeader& operator=(const QuicPacketHeader& other);
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPacketHeader& header);
+
+  // Universal header. All QuicPacket headers will have a connection_id and
+  // public flags.
+  QuicConnectionId destination_connection_id;
+  QuicConnectionIdIncluded destination_connection_id_included;
+  QuicConnectionId source_connection_id;
+  QuicConnectionIdIncluded source_connection_id_included;
+  // This is only used for Google QUIC.
+  bool reset_flag;
+  // For Google QUIC, version flag in packets from the server means version
+  // negotiation packet. For IETF QUIC, version flag means long header.
+  bool version_flag;
+  // Indicates whether |possible_stateless_reset_token| contains a valid value
+  // parsed from the packet buffer. IETF QUIC only, always false for GQUIC.
+  bool has_possible_stateless_reset_token;
+  QuicPacketNumberLength packet_number_length;
+  uint8_t type_byte;
+  ParsedQuicVersion version;
+  // nonce contains an optional, 32-byte nonce value. If not included in the
+  // packet, |nonce| will be empty.
+  DiversificationNonce* nonce;
+  QuicPacketNumber packet_number;
+  // Format of this header.
+  PacketHeaderFormat form;
+  // Short packet type is reflected in packet_number_length.
+  QuicLongHeaderType long_packet_type;
+  // Only valid if |has_possible_stateless_reset_token| is true.
+  // Stores last 16 bytes of a this packet, used to check whether this packet is
+  // a stateless reset packet on decryption failure.
+  StatelessResetToken possible_stateless_reset_token;
+  // Length of the retry token length variable length integer field,
+  // carried only by v99 IETF Initial packets.
+  QuicVariableLengthIntegerLength retry_token_length_length;
+  // Retry token, carried only by v99 IETF Initial packets.
+  absl::string_view retry_token;
+  // Length of the length variable length integer field,
+  // carried only by v99 IETF Initial, 0-RTT and Handshake packets.
+  QuicVariableLengthIntegerLength length_length;
+  // Length of the packet number and payload, carried only by v99 IETF Initial,
+  // 0-RTT and Handshake packets. Also includes the length of the
+  // diversification nonce in server to client 0-RTT packets.
+  QuicByteCount remaining_packet_length;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
+  QuicPublicResetPacket();
+  explicit QuicPublicResetPacket(QuicConnectionId connection_id);
+
+  QuicConnectionId connection_id;
+  QuicPublicResetNonceProof nonce_proof;
+  QuicSocketAddress client_address;
+  // An arbitrary string to identify an endpoint. Used by clients to
+  // differentiate traffic from Google servers vs Non-google servers.
+  // Will not be used if empty().
+  std::string endpoint_id;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
+  QuicVersionNegotiationPacket();
+  explicit QuicVersionNegotiationPacket(QuicConnectionId connection_id);
+  QuicVersionNegotiationPacket(const QuicVersionNegotiationPacket& other);
+  ~QuicVersionNegotiationPacket();
+
+  QuicConnectionId connection_id;
+  ParsedQuicVersionVector versions;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket {
+  QuicIetfStatelessResetPacket();
+  QuicIetfStatelessResetPacket(const QuicPacketHeader& header,
+                               StatelessResetToken token);
+  QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other);
+  ~QuicIetfStatelessResetPacket();
+
+  QuicPacketHeader header;
+  StatelessResetToken stateless_reset_token;
+};
+
+class QUIC_EXPORT_PRIVATE QuicData {
+ public:
+  // Creates a QuicData from a buffer and length. Does not own the buffer.
+  QuicData(const char* buffer, size_t length);
+  // Creates a QuicData from a buffer and length,
+  // optionally taking ownership of the buffer.
+  QuicData(const char* buffer, size_t length, bool owns_buffer);
+  // Creates a QuicData from a absl::string_view. Does not own the
+  // buffer.
+  QuicData(absl::string_view data);
+  QuicData(const QuicData&) = delete;
+  QuicData& operator=(const QuicData&) = delete;
+  virtual ~QuicData();
+
+  absl::string_view AsStringPiece() const {
+    return absl::string_view(data(), length());
+  }
+
+  const char* data() const { return buffer_; }
+  size_t length() const { return length_; }
+
+ private:
+  const char* buffer_;
+  size_t length_;
+  bool owns_buffer_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
+ public:
+  QuicPacket(char* buffer,
+             size_t length,
+             bool owns_buffer,
+             QuicConnectionIdLength destination_connection_id_length,
+             QuicConnectionIdLength source_connection_id_length,
+             bool includes_version,
+             bool includes_diversification_nonce,
+             QuicPacketNumberLength packet_number_length,
+             QuicVariableLengthIntegerLength retry_token_length_length,
+             QuicByteCount retry_token_length,
+             QuicVariableLengthIntegerLength length_length);
+  QuicPacket(QuicTransportVersion version,
+             char* buffer,
+             size_t length,
+             bool owns_buffer,
+             const QuicPacketHeader& header);
+  QuicPacket(const QuicPacket&) = delete;
+  QuicPacket& operator=(const QuicPacket&) = delete;
+
+  absl::string_view AssociatedData(QuicTransportVersion version) const;
+  absl::string_view Plaintext(QuicTransportVersion version) const;
+
+  char* mutable_data() { return buffer_; }
+
+ private:
+  char* buffer_;
+  const QuicConnectionIdLength destination_connection_id_length_;
+  const QuicConnectionIdLength source_connection_id_length_;
+  const bool includes_version_;
+  const bool includes_diversification_nonce_;
+  const QuicPacketNumberLength packet_number_length_;
+  const QuicVariableLengthIntegerLength retry_token_length_length_;
+  const QuicByteCount retry_token_length_;
+  const QuicVariableLengthIntegerLength length_length_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
+ public:
+  // Creates a QuicEncryptedPacket from a buffer and length.
+  // Does not own the buffer.
+  QuicEncryptedPacket(const char* buffer, size_t length);
+  // Creates a QuicEncryptedPacket from a buffer and length,
+  // optionally taking ownership of the buffer.
+  QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer);
+  // Creates a QuicEncryptedPacket from a absl::string_view.
+  // Does not own the buffer.
+  QuicEncryptedPacket(absl::string_view data);
+
+  QuicEncryptedPacket(const QuicEncryptedPacket&) = delete;
+  QuicEncryptedPacket& operator=(const QuicEncryptedPacket&) = delete;
+
+  // Clones the packet into a new packet which owns the buffer.
+  std::unique_ptr<QuicEncryptedPacket> Clone() const;
+
+  // By default, gtest prints the raw bytes of an object. The bool data
+  // member (in the base class QuicData) causes this object to have padding
+  // bytes, which causes the default gtest object printer to read
+  // uninitialize memory. So we need to teach gtest how to print this object.
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicEncryptedPacket& s);
+};
+
+// A received encrypted QUIC packet, with a recorded time of receipt.
+class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
+ public:
+  QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time);
+  QuicReceivedPacket(const char* buffer,
+                     size_t length,
+                     QuicTime receipt_time,
+                     bool owns_buffer);
+  QuicReceivedPacket(const char* buffer,
+                     size_t length,
+                     QuicTime receipt_time,
+                     bool owns_buffer,
+                     int ttl,
+                     bool ttl_valid);
+  QuicReceivedPacket(const char* buffer,
+                     size_t length,
+                     QuicTime receipt_time,
+                     bool owns_buffer,
+                     int ttl,
+                     bool ttl_valid,
+                     char* packet_headers,
+                     size_t headers_length,
+                     bool owns_header_buffer);
+  ~QuicReceivedPacket();
+  QuicReceivedPacket(const QuicReceivedPacket&) = delete;
+  QuicReceivedPacket& operator=(const QuicReceivedPacket&) = delete;
+
+  // Clones the packet into a new packet which owns the buffer.
+  std::unique_ptr<QuicReceivedPacket> Clone() const;
+
+  // Returns the time at which the packet was received.
+  QuicTime receipt_time() const { return receipt_time_; }
+
+  // This is the TTL of the packet, assuming ttl_vaild_ is true.
+  int ttl() const { return ttl_; }
+
+  // Start of packet headers.
+  char* packet_headers() const { return packet_headers_; }
+
+  // Length of packet headers.
+  int headers_length() const { return headers_length_; }
+
+  // By default, gtest prints the raw bytes of an object. The bool data
+  // member (in the base class QuicData) causes this object to have padding
+  // bytes, which causes the default gtest object printer to read
+  // uninitialize memory. So we need to teach gtest how to print this object.
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicReceivedPacket& s);
+
+ private:
+  const QuicTime receipt_time_;
+  int ttl_;
+  // Points to the start of packet headers.
+  char* packet_headers_;
+  // Length of packet headers.
+  int headers_length_;
+  // Whether owns the buffer for packet headers.
+  bool owns_header_buffer_;
+};
+
+// SerializedPacket contains information of a serialized(encrypted) packet.
+//
+// WARNING:
+//
+//   If you add a member field to this class, please make sure it is properly
+//   copied in |CopySerializedPacket|.
+//
+struct QUIC_EXPORT_PRIVATE SerializedPacket {
+  SerializedPacket(QuicPacketNumber packet_number,
+                   QuicPacketNumberLength packet_number_length,
+                   const char* encrypted_buffer,
+                   QuicPacketLength encrypted_length,
+                   bool has_ack,
+                   bool has_stop_waiting);
+
+  // Copy constructor & assignment are deleted. Use |CopySerializedPacket| to
+  // make a copy.
+  SerializedPacket(const SerializedPacket& other) = delete;
+  SerializedPacket& operator=(const SerializedPacket& other) = delete;
+  SerializedPacket(SerializedPacket&& other);
+  ~SerializedPacket();
+
+  // TODO(wub): replace |encrypted_buffer|+|release_encrypted_buffer| by a
+  // QuicOwnedPacketBuffer.
+  // Not owned if |release_encrypted_buffer| is nullptr. Otherwise it is
+  // released by |release_encrypted_buffer| on destruction.
+  const char* encrypted_buffer;
+  QuicPacketLength encrypted_length;
+  std::function<void(const char*)> release_encrypted_buffer;
+
+  QuicFrames retransmittable_frames;
+  QuicFrames nonretransmittable_frames;
+  IsHandshake has_crypto_handshake;
+  QuicPacketNumber packet_number;
+  QuicPacketNumberLength packet_number_length;
+  EncryptionLevel encryption_level;
+  // TODO(fayang): Remove has_ack and has_stop_waiting.
+  bool has_ack;
+  bool has_stop_waiting;
+  TransmissionType transmission_type;
+  // The largest acked of the AckFrame in this packet if has_ack is true,
+  // 0 otherwise.
+  QuicPacketNumber largest_acked;
+  // Indicates whether this packet has a copy of ack frame in
+  // nonretransmittable_frames.
+  bool has_ack_frame_copy;
+  bool has_ack_frequency;
+  bool has_message;
+  SerializedPacketFate fate;
+  QuicSocketAddress peer_address;
+};
+
+// Make a copy of |serialized| (including the underlying frames). |copy_buffer|
+// indicates whether the encrypted buffer should be copied.
+QUIC_EXPORT_PRIVATE SerializedPacket* CopySerializedPacket(
+    const SerializedPacket& serialized,
+    quiche::QuicheBufferAllocator* allocator, bool copy_buffer);
+
+// Allocates a new char[] of size |packet.encrypted_length| and copies in
+// |packet.encrypted_buffer|.
+QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
+// Allocates a new char[] of size |encrypted_length| and copies in
+// |encrypted_buffer|.
+QUIC_EXPORT_PRIVATE char* CopyBuffer(const char* encrypted_buffer,
+                                     QuicPacketLength encrypted_length);
+
+// Context for an incoming packet.
+struct QUIC_EXPORT_PRIVATE QuicPerPacketContext {
+  virtual ~QuicPerPacketContext() {}
+};
+
+// ReceivedPacketInfo comprises information obtained by parsing the unencrypted
+// bytes of a received packet.
+struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
+  ReceivedPacketInfo(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address,
+                     const QuicReceivedPacket& packet);
+  ReceivedPacketInfo(const ReceivedPacketInfo& other) = default;
+
+  ~ReceivedPacketInfo();
+
+  std::string ToString() const;
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const ReceivedPacketInfo& packet_info);
+
+  const QuicSocketAddress& self_address;
+  const QuicSocketAddress& peer_address;
+  const QuicReceivedPacket& packet;
+
+  PacketHeaderFormat form;
+  // This is only used if the form is IETF_QUIC_LONG_HEADER_PACKET.
+  QuicLongHeaderType long_packet_type;
+  bool version_flag;
+  bool use_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion version;
+  QuicConnectionId destination_connection_id;
+  QuicConnectionId source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKETS_H_
diff --git a/quiche/quic/core/quic_packets_test.cc b/quiche/quic/core/quic_packets_test.cc
new file mode 100644
index 0000000..f0a7e7f
--- /dev/null
+++ b/quiche/quic/core/quic_packets_test.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_packets.h"
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+QuicPacketHeader CreateFakePacketHeader() {
+  QuicPacketHeader header;
+  header.destination_connection_id = TestConnectionId(1);
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id = TestConnectionId(2);
+  header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  return header;
+}
+
+class QuicPacketsTest : public QuicTest {};
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdAsRecipient) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(1),
+            GetServerConnectionIdAsRecipient(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(2),
+            GetServerConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(2),
+            GetServerConnectionIdAsSender(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(1),
+            GetServerConnectionIdAsSender(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetServerConnectionIdIncludedAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(CONNECTION_ID_ABSENT, GetServerConnectionIdIncludedAsSender(
+                                      header, Perspective::IS_SERVER));
+  EXPECT_EQ(CONNECTION_ID_PRESENT, GetServerConnectionIdIncludedAsSender(
+                                       header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdIncludedAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(CONNECTION_ID_PRESENT, GetClientConnectionIdIncludedAsSender(
+                                       header, Perspective::IS_SERVER));
+  EXPECT_EQ(CONNECTION_ID_ABSENT, GetClientConnectionIdIncludedAsSender(
+                                      header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdAsRecipient) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(2),
+            GetClientConnectionIdAsRecipient(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(1),
+            GetClientConnectionIdAsRecipient(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, GetClientConnectionIdAsSender) {
+  QuicPacketHeader header = CreateFakePacketHeader();
+  EXPECT_EQ(TestConnectionId(1),
+            GetClientConnectionIdAsSender(header, Perspective::IS_SERVER));
+  EXPECT_EQ(TestConnectionId(2),
+            GetClientConnectionIdAsSender(header, Perspective::IS_CLIENT));
+}
+
+TEST_F(QuicPacketsTest, CopySerializedPacket) {
+  std::string buffer(1000, 'a');
+  quiche::SimpleBufferAllocator allocator;
+  SerializedPacket packet(QuicPacketNumber(1), PACKET_1BYTE_PACKET_NUMBER,
+                          buffer.data(), buffer.length(), /*has_ack=*/false,
+                          /*has_stop_waiting=*/false);
+  packet.retransmittable_frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
+  packet.retransmittable_frames.push_back(QuicFrame(QuicStreamFrame()));
+
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  packet.nonretransmittable_frames.push_back(QuicFrame(&ack_frame));
+  packet.nonretransmittable_frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+
+  std::unique_ptr<SerializedPacket> copy = absl::WrapUnique<SerializedPacket>(
+      CopySerializedPacket(packet, &allocator, /*copy_buffer=*/true));
+  EXPECT_EQ(quic::QuicPacketNumber(1), copy->packet_number);
+  EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER, copy->packet_number_length);
+  ASSERT_EQ(2u, copy->retransmittable_frames.size());
+  EXPECT_EQ(WINDOW_UPDATE_FRAME, copy->retransmittable_frames[0].type);
+  EXPECT_EQ(STREAM_FRAME, copy->retransmittable_frames[1].type);
+
+  ASSERT_EQ(2u, copy->nonretransmittable_frames.size());
+  EXPECT_EQ(ACK_FRAME, copy->nonretransmittable_frames[0].type);
+  EXPECT_EQ(PADDING_FRAME, copy->nonretransmittable_frames[1].type);
+  EXPECT_EQ(1000u, copy->encrypted_length);
+  quiche::test::CompareCharArraysWithHexError(
+      "encrypted_buffer", copy->encrypted_buffer, copy->encrypted_length,
+      packet.encrypted_buffer, packet.encrypted_length);
+
+  std::unique_ptr<SerializedPacket> copy2 = absl::WrapUnique<SerializedPacket>(
+      CopySerializedPacket(packet, &allocator, /*copy_buffer=*/false));
+  EXPECT_EQ(packet.encrypted_buffer, copy2->encrypted_buffer);
+  EXPECT_EQ(1000u, copy2->encrypted_length);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_path_validator.cc b/quiche/quic/core/quic_path_validator.cc
new file mode 100644
index 0000000..279ac0f
--- /dev/null
+++ b/quiche/quic/core/quic_path_validator.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_path_validator.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+class RetryAlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+  explicit RetryAlarmDelegate(QuicPathValidator* path_validator,
+                              QuicConnectionContext* context)
+      : QuicAlarm::DelegateWithContext(context),
+        path_validator_(path_validator) {}
+  RetryAlarmDelegate(const RetryAlarmDelegate&) = delete;
+  RetryAlarmDelegate& operator=(const RetryAlarmDelegate&) = delete;
+
+  void OnAlarm() override { path_validator_->OnRetryTimeout(); }
+
+ private:
+  QuicPathValidator* path_validator_;
+};
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicPathValidationContext& context) {
+  return os << " from " << context.self_address_ << " to "
+            << context.peer_address_;
+}
+
+QuicPathValidator::QuicPathValidator(QuicAlarmFactory* alarm_factory,
+                                     QuicConnectionArena* arena,
+                                     SendDelegate* send_delegate,
+                                     QuicRandom* random,
+                                     QuicConnectionContext* context)
+    : send_delegate_(send_delegate),
+      random_(random),
+      retry_timer_(alarm_factory->CreateAlarm(
+          arena->New<RetryAlarmDelegate>(this, context), arena)),
+      retry_count_(0u) {}
+
+void QuicPathValidator::OnPathResponse(const QuicPathFrameBuffer& probing_data,
+                                       QuicSocketAddress self_address) {
+  if (!HasPendingPathValidation()) {
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Match PATH_RESPONSE received on " << self_address;
+  QUIC_BUG_IF(quic_bug_12402_1, !path_context_->self_address().IsInitialized())
+      << "Self address should have been known by now";
+  if (self_address != path_context_->self_address()) {
+    QUIC_DVLOG(1) << "Expect the response to be received on "
+                  << path_context_->self_address();
+    return;
+  }
+  // This iterates at most 3 times.
+  if (std::find(probing_data_.begin(), probing_data_.end(), probing_data) !=
+      probing_data_.end()) {
+    result_delegate_->OnPathValidationSuccess(std::move(path_context_));
+    ResetPathValidation();
+  } else {
+    QUIC_DVLOG(1) << "PATH_RESPONSE with payload " << probing_data.data()
+                  << " doesn't match the probing data.";
+  }
+}
+
+void QuicPathValidator::StartPathValidation(
+    std::unique_ptr<QuicPathValidationContext> context,
+    std::unique_ptr<ResultDelegate> result_delegate) {
+  QUICHE_DCHECK(context);
+  QUIC_DLOG(INFO) << "Start validating path " << *context
+                  << " via writer: " << context->WriterToUse();
+  if (path_context_ != nullptr) {
+    QUIC_BUG(quic_bug_10876_1)
+        << "There is an on-going validation on path " << *path_context_;
+    ResetPathValidation();
+  }
+
+  path_context_ = std::move(context);
+  result_delegate_ = std::move(result_delegate);
+  SendPathChallengeAndSetAlarm();
+}
+
+void QuicPathValidator::ResetPathValidation() {
+  path_context_ = nullptr;
+  result_delegate_ = nullptr;
+  retry_timer_->Cancel();
+  retry_count_ = 0;
+}
+
+void QuicPathValidator::CancelPathValidation() {
+  if (path_context_ == nullptr) {
+    return;
+  }
+  QUIC_DVLOG(1) << "Cancel validation on path" << *path_context_;
+  result_delegate_->OnPathValidationFailure(std::move(path_context_));
+  ResetPathValidation();
+}
+
+bool QuicPathValidator::HasPendingPathValidation() const {
+  return path_context_ != nullptr;
+}
+
+QuicPathValidationContext* QuicPathValidator::GetContext() const {
+  return path_context_.get();
+}
+
+const QuicPathFrameBuffer& QuicPathValidator::GeneratePathChallengePayload() {
+  probing_data_.push_back(QuicPathFrameBuffer());
+  random_->RandBytes(probing_data_.back().data(), sizeof(QuicPathFrameBuffer));
+  return probing_data_.back();
+}
+
+void QuicPathValidator::OnRetryTimeout() {
+  ++retry_count_;
+  if (retry_count_ > kMaxRetryTimes) {
+    CancelPathValidation();
+    return;
+  }
+  QUIC_DVLOG(1) << "Send another PATH_CHALLENGE on path " << *path_context_;
+  SendPathChallengeAndSetAlarm();
+}
+
+void QuicPathValidator::SendPathChallengeAndSetAlarm() {
+  bool should_continue = send_delegate_->SendPathChallenge(
+      GeneratePathChallengePayload(), path_context_->self_address(),
+      path_context_->peer_address(), path_context_->effective_peer_address(),
+      path_context_->WriterToUse());
+
+  if (!should_continue) {
+    // The delegate doesn't want to continue the path validation.
+    CancelPathValidation();
+    return;
+  }
+  retry_timer_->Set(send_delegate_->GetRetryTimeout(
+      path_context_->peer_address(), path_context_->WriterToUse()));
+}
+
+bool QuicPathValidator::IsValidatingPeerAddress(
+    const QuicSocketAddress& effective_peer_address) {
+  return path_context_ != nullptr &&
+         path_context_->effective_peer_address() == effective_peer_address;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_path_validator.h b/quiche/quic/core/quic_path_validator.h
new file mode 100644
index 0000000..5c9c85e
--- /dev/null
+++ b/quiche/quic/core/quic_path_validator.h
@@ -0,0 +1,160 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
+
+#include <ostream>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_arena_scoped_ptr.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+namespace test {
+class QuicPathValidatorPeer;
+}
+
+class QuicConnection;
+
+// Interface to provide the information of the path to be validated.
+class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
+ public:
+  QuicPathValidationContext(const QuicSocketAddress& self_address,
+                            const QuicSocketAddress& peer_address)
+      : self_address_(self_address),
+        peer_address_(peer_address),
+        effective_peer_address_(peer_address) {}
+
+  QuicPathValidationContext(const QuicSocketAddress& self_address,
+                            const QuicSocketAddress& peer_address,
+                            const QuicSocketAddress& effective_peer_address)
+      : self_address_(self_address),
+        peer_address_(peer_address),
+        effective_peer_address_(effective_peer_address) {}
+
+  virtual ~QuicPathValidationContext() = default;
+
+  virtual QuicPacketWriter* WriterToUse() = 0;
+
+  const QuicSocketAddress& self_address() const { return self_address_; }
+  const QuicSocketAddress& peer_address() const { return peer_address_; }
+  const QuicSocketAddress& effective_peer_address() const {
+    return effective_peer_address_;
+  }
+
+ private:
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPathValidationContext& context);
+
+  QuicSocketAddress self_address_;
+  // The address to send PATH_CHALLENGE.
+  QuicSocketAddress peer_address_;
+  // The actual peer address which is different from |peer_address_| if the peer
+  // is behind a proxy.
+  QuicSocketAddress effective_peer_address_;
+};
+
+// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
+// declaring a path validation failure.
+class QUIC_EXPORT_PRIVATE QuicPathValidator {
+ public:
+  static const uint16_t kMaxRetryTimes = 2;
+
+  // Used to write PATH_CHALLENGE on the path to be validated and to get retry
+  // timeout.
+  class QUIC_EXPORT_PRIVATE SendDelegate {
+   public:
+    virtual ~SendDelegate() = default;
+
+    // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
+    // path information. Return false if the delegate doesn't want to continue
+    // the validation.
+    virtual bool SendPathChallenge(
+        const QuicPathFrameBuffer& data_buffer,
+        const QuicSocketAddress& self_address,
+        const QuicSocketAddress& peer_address,
+        const QuicSocketAddress& effective_peer_address,
+        QuicPacketWriter* writer) = 0;
+    // Return the time to retry sending PATH_CHALLENGE again based on given peer
+    // address and writer.
+    virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
+                                     QuicPacketWriter* writer) const = 0;
+  };
+
+  // Handles the validation result.
+  // TODO(danzh) consider to simplify this interface and its life time to
+  // outlive a validation.
+  class QUIC_EXPORT_PRIVATE ResultDelegate {
+   public:
+    virtual ~ResultDelegate() = default;
+
+    virtual void OnPathValidationSuccess(
+        std::unique_ptr<QuicPathValidationContext> context) = 0;
+
+    virtual void OnPathValidationFailure(
+        std::unique_ptr<QuicPathValidationContext> context) = 0;
+  };
+
+  QuicPathValidator(QuicAlarmFactory* alarm_factory, QuicConnectionArena* arena,
+                    SendDelegate* delegate, QuicRandom* random,
+                    QuicConnectionContext* context);
+
+  // Send PATH_CHALLENGE and start the retry timer.
+  void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
+                           std::unique_ptr<ResultDelegate> result_delegate);
+
+  // Called when a PATH_RESPONSE frame has been received. Matches the received
+  // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
+  // frames and the self address on which it was sent.
+  void OnPathResponse(const QuicPathFrameBuffer& probing_data,
+                      QuicSocketAddress self_address);
+
+  // Cancel the retry timer and reset the path and result delegate.
+  void CancelPathValidation();
+
+  bool HasPendingPathValidation() const;
+
+  QuicPathValidationContext* GetContext() const;
+
+  // Send another PATH_CHALLENGE on the same path. After retrying
+  // |kMaxRetryTimes| times, fail the current path validation.
+  void OnRetryTimeout();
+
+  bool IsValidatingPeerAddress(const QuicSocketAddress& effective_peer_address);
+
+ private:
+  friend class test::QuicPathValidatorPeer;
+
+  // Return the payload to be used in the next PATH_CHALLENGE frame.
+  const QuicPathFrameBuffer& GeneratePathChallengePayload();
+
+  void SendPathChallengeAndSetAlarm();
+
+  void ResetPathValidation();
+
+  // Has at most 3 entries due to validation timeout.
+  absl::InlinedVector<QuicPathFrameBuffer, 3> probing_data_;
+  SendDelegate* send_delegate_;
+  QuicRandom* random_;
+  std::unique_ptr<QuicPathValidationContext> path_context_;
+  std::unique_ptr<ResultDelegate> result_delegate_;
+  QuicArenaScopedPtr<QuicAlarm> retry_timer_;
+  size_t retry_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
diff --git a/quiche/quic/core/quic_path_validator_test.cc b/quiche/quic/core/quic_path_validator_test.cc
new file mode 100644
index 0000000..a9e0da4
--- /dev/null
+++ b/quiche/quic/core/quic_path_validator_test.cc
@@ -0,0 +1,254 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_path_validator.h"
+
+#include <memory>
+
+#include "quiche/quic/core/frames/quic_path_challenge_frame.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_path_validator_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::Return;
+
+namespace quic {
+namespace test {
+
+class MockSendDelegate : public QuicPathValidator::SendDelegate {
+ public:
+  // Send a PATH_CHALLENGE frame using given path information and populate
+  // |data_buffer| with the frame payload. Return true if the validator should
+  // move forward in validation, i.e. arm the retry timer.
+  MOCK_METHOD(bool,
+              SendPathChallenge,
+              (const QuicPathFrameBuffer&,
+               const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               QuicPacketWriter*),
+              (override));
+
+  MOCK_METHOD(QuicTime,
+              GetRetryTimeout,
+              (const QuicSocketAddress&, QuicPacketWriter*),
+              (const, override));
+};
+
+class QuicPathValidatorTest : public QuicTest {
+ public:
+  QuicPathValidatorTest()
+      : path_validator_(&alarm_factory_, &arena_, &send_delegate_, &random_,
+                        /*context=*/nullptr),
+        context_(new MockQuicPathValidationContext(
+            self_address_, peer_address_, effective_peer_address_, &writer_)),
+        result_delegate_(
+            new testing::StrictMock<MockQuicPathValidationResultDelegate>()) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+    ON_CALL(send_delegate_, GetRetryTimeout(_, _))
+        .WillByDefault(
+            Return(clock_.ApproximateNow() +
+                   3 * QuicTime::Delta::FromMilliseconds(kInitialRttMs)));
+  }
+
+ protected:
+  quic::test::MockAlarmFactory alarm_factory_;
+  MockSendDelegate send_delegate_;
+  MockRandom random_;
+  MockClock clock_;
+  QuicConnectionArena arena_;
+  QuicPathValidator path_validator_;
+  QuicSocketAddress self_address_{QuicIpAddress::Any4(), 443};
+  QuicSocketAddress peer_address_{QuicIpAddress::Loopback4(), 443};
+  QuicSocketAddress effective_peer_address_{QuicIpAddress::Loopback4(), 12345};
+  MockPacketWriter writer_;
+  MockQuicPathValidationContext* context_;
+  MockQuicPathValidationResultDelegate* result_delegate_;
+};
+
+TEST_F(QuicPathValidatorTest, PathValidationSuccessOnFirstRound) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+  EXPECT_TRUE(path_validator_.HasPendingPathValidation());
+  EXPECT_TRUE(path_validator_.IsValidatingPeerAddress(effective_peer_address_));
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
+      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
+        EXPECT_EQ(context.get(), context_);
+      }));
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+}
+
+TEST_F(QuicPathValidatorTest, RespondWithDifferentSelfAddress) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_));
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  // Reception of a PATH_RESPONSE on a different self address should be ignored.
+  const QuicSocketAddress kAlternativeSelfAddress(QuicIpAddress::Any6(), 54321);
+  EXPECT_NE(kAlternativeSelfAddress, self_address_);
+  path_validator_.OnPathResponse(challenge_data, kAlternativeSelfAddress);
+
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_))
+      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
+        EXPECT_EQ(context->self_address(), self_address_);
+      }));
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+}
+
+TEST_F(QuicPathValidatorTest, RespondAfter1stRetry) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        // Store up the 1st PATH_CHALLANGE payload.
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        EXPECT_NE(payload, challenge_data);
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(2u);
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  random_.ChangeValue();
+  alarm_factory_.FireAlarm(
+      QuicPathValidatorPeer::retry_timer(&path_validator_));
+
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
+  // Respond to the 1st PATH_CHALLENGE should complete the validation.
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+}
+
+TEST_F(QuicPathValidatorTest, RespondToRetryChallenge) {
+  QuicPathFrameBuffer challenge_data;
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer& payload,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, QuicPacketWriter*) {
+        EXPECT_NE(challenge_data, payload);
+        memcpy(challenge_data.data(), payload.data(), payload.size());
+        return true;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(2u);
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+  random_.ChangeValue();
+  alarm_factory_.FireAlarm(
+      QuicPathValidatorPeer::retry_timer(&path_validator_));
+
+  // Respond to the 2nd PATH_CHALLENGE should complete the validation.
+  EXPECT_CALL(*result_delegate_, OnPathValidationSuccess(_));
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+}
+
+TEST_F(QuicPathValidatorTest, ValidationTimeOut) {
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .Times(3u)
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(3u);
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+
+  QuicPathFrameBuffer challenge_data;
+  memset(challenge_data.data(), 'a', challenge_data.size());
+  // Reception of a PATH_RESPONSE with different payload should be ignored.
+  path_validator_.OnPathResponse(challenge_data, self_address_);
+
+  // Retry 3 times. The 3rd time should fail the validation.
+  EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_))
+      .WillOnce(Invoke([=](std::unique_ptr<QuicPathValidationContext> context) {
+        EXPECT_EQ(context_, context.get());
+      }));
+  for (size_t i = 0; i <= QuicPathValidator::kMaxRetryTimes; ++i) {
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs));
+    alarm_factory_.FireAlarm(
+        QuicPathValidatorPeer::retry_timer(&path_validator_));
+  }
+}
+
+TEST_F(QuicPathValidatorTest, SendPathChallengeError) {
+  EXPECT_CALL(send_delegate_,
+              SendPathChallenge(_, self_address_, peer_address_,
+                                effective_peer_address_, &writer_))
+      .WillOnce(Invoke([&](const QuicPathFrameBuffer&, const QuicSocketAddress&,
+                           const QuicSocketAddress&, const QuicSocketAddress&,
+                           QuicPacketWriter*) {
+        // Abandon this validation in the call stack shouldn't cause crash and
+        // should cancel the alarm.
+        path_validator_.CancelPathValidation();
+        return false;
+      }));
+  EXPECT_CALL(send_delegate_, GetRetryTimeout(peer_address_, &writer_))
+      .Times(0u);
+  EXPECT_CALL(*result_delegate_, OnPathValidationFailure(_));
+  path_validator_.StartPathValidation(
+      std::unique_ptr<QuicPathValidationContext>(context_),
+      std::unique_ptr<MockQuicPathValidationResultDelegate>(result_delegate_));
+  EXPECT_FALSE(path_validator_.HasPendingPathValidation());
+  EXPECT_FALSE(QuicPathValidatorPeer::retry_timer(&path_validator_)->IsSet());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_process_packet_interface.h b/quiche/quic/core/quic_process_packet_interface.h
new file mode 100644
index 0000000..30bd071
--- /dev/null
+++ b/quiche/quic/core/quic_process_packet_interface.h
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
+#define QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// A class to process each incoming packet.
+class QUIC_NO_EXPORT ProcessPacketInterface {
+ public:
+  virtual ~ProcessPacketInterface() {}
+  virtual void ProcessPacket(const QuicSocketAddress& self_address,
+                             const QuicSocketAddress& peer_address,
+                             const QuicReceivedPacket& packet) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PROCESS_PACKET_INTERFACE_H_
diff --git a/quic/core/quic_protocol_flags_list.h b/quiche/quic/core/quic_protocol_flags_list.h
similarity index 100%
rename from quic/core/quic_protocol_flags_list.h
rename to quiche/quic/core/quic_protocol_flags_list.h
diff --git a/quiche/quic/core/quic_received_packet_manager.cc b/quiche/quic/core/quic_received_packet_manager.cc
new file mode 100644
index 0000000..f8bcb13
--- /dev/null
+++ b/quiche/quic/core/quic_received_packet_manager.cc
@@ -0,0 +1,354 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_received_packet_manager.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace {
+
+// The maximum number of packets to ack immediately after a missing packet for
+// fast retransmission to kick in at the sender.  This limit is created to
+// reduce the number of acks sent that have no benefit for fast retransmission.
+// Set to the number of nacks needed for fast retransmit plus one for protection
+// against an ack loss
+const size_t kMaxPacketsAfterNewMissing = 4;
+
+// One eighth RTT delay when doing ack decimation.
+const float kShortAckDecimationDelay = 0.125;
+}  // namespace
+
+QuicReceivedPacketManager::QuicReceivedPacketManager()
+    : QuicReceivedPacketManager(nullptr) {}
+
+QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
+    : ack_frame_updated_(false),
+      max_ack_ranges_(0),
+      time_largest_observed_(QuicTime::Zero()),
+      save_timestamps_(false),
+      save_timestamps_for_in_order_packets_(false),
+      stats_(stats),
+      num_retransmittable_packets_received_since_last_ack_sent_(0),
+      min_received_before_ack_decimation_(kMinReceivedBeforeAckDecimation),
+      ack_frequency_(kDefaultRetransmittablePacketsBeforeAck),
+      ack_decimation_delay_(kAckDecimationDelay),
+      unlimited_ack_decimation_(false),
+      one_immediate_ack_(false),
+      ignore_order_(false),
+      local_max_ack_delay_(
+          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+      ack_timeout_(QuicTime::Zero()),
+      time_of_previous_received_packet_(QuicTime::Zero()),
+      was_last_packet_missing_(false),
+      last_ack_frequency_frame_sequence_number_(-1) {}
+
+QuicReceivedPacketManager::~QuicReceivedPacketManager() {}
+
+void QuicReceivedPacketManager::SetFromConfig(const QuicConfig& config,
+                                              Perspective perspective) {
+  if (config.HasClientSentConnectionOption(kAKD3, perspective)) {
+    ack_decimation_delay_ = kShortAckDecimationDelay;
+  }
+  if (config.HasClientSentConnectionOption(kAKDU, perspective)) {
+    unlimited_ack_decimation_ = true;
+  }
+  if (config.HasClientSentConnectionOption(k1ACK, perspective)) {
+    one_immediate_ack_ = true;
+  }
+}
+
+void QuicReceivedPacketManager::RecordPacketReceived(
+    const QuicPacketHeader& header,
+    QuicTime receipt_time) {
+  const QuicPacketNumber packet_number = header.packet_number;
+  QUICHE_DCHECK(IsAwaitingPacket(packet_number))
+      << " packet_number:" << packet_number;
+  was_last_packet_missing_ = IsMissing(packet_number);
+  if (!ack_frame_updated_) {
+    ack_frame_.received_packet_times.clear();
+  }
+  ack_frame_updated_ = true;
+
+  // Whether |packet_number| is received out of order.
+  bool packet_reordered = false;
+  if (LargestAcked(ack_frame_).IsInitialized() &&
+      LargestAcked(ack_frame_) > packet_number) {
+    // Record how out of order stats.
+    packet_reordered = true;
+    ++stats_->packets_reordered;
+    stats_->max_sequence_reordering =
+        std::max(stats_->max_sequence_reordering,
+                 LargestAcked(ack_frame_) - packet_number);
+    int64_t reordering_time_us =
+        (receipt_time - time_largest_observed_).ToMicroseconds();
+    stats_->max_time_reordering_us =
+        std::max(stats_->max_time_reordering_us, reordering_time_us);
+  }
+  if (!LargestAcked(ack_frame_).IsInitialized() ||
+      packet_number > LargestAcked(ack_frame_)) {
+    ack_frame_.largest_acked = packet_number;
+    time_largest_observed_ = receipt_time;
+  }
+  ack_frame_.packets.Add(packet_number);
+
+  if (save_timestamps_) {
+    // The timestamp format only handles packets in time order.
+    if (save_timestamps_for_in_order_packets_ && packet_reordered) {
+      QUIC_DLOG(WARNING) << "Not saving receive timestamp for packet "
+                         << packet_number;
+    } else if (!ack_frame_.received_packet_times.empty() &&
+               ack_frame_.received_packet_times.back().second > receipt_time) {
+      QUIC_LOG(WARNING)
+          << "Receive time went backwards from: "
+          << ack_frame_.received_packet_times.back().second.ToDebuggingValue()
+          << " to " << receipt_time.ToDebuggingValue();
+    } else {
+      ack_frame_.received_packet_times.push_back(
+          std::make_pair(packet_number, receipt_time));
+    }
+  }
+
+  if (least_received_packet_number_.IsInitialized()) {
+    least_received_packet_number_ =
+        std::min(least_received_packet_number_, packet_number);
+  } else {
+    least_received_packet_number_ = packet_number;
+  }
+}
+
+bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
+  return LargestAcked(ack_frame_).IsInitialized() &&
+         packet_number < LargestAcked(ack_frame_) &&
+         !ack_frame_.packets.Contains(packet_number);
+}
+
+bool QuicReceivedPacketManager::IsAwaitingPacket(
+    QuicPacketNumber packet_number) const {
+  return quic::IsAwaitingPacket(ack_frame_, packet_number,
+                                peer_least_packet_awaiting_ack_);
+}
+
+const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame(
+    QuicTime approximate_now) {
+  if (time_largest_observed_ == QuicTime::Zero()) {
+    // We have received no packets.
+    ack_frame_.ack_delay_time = QuicTime::Delta::Infinite();
+  } else {
+    // Ensure the delta is zero if approximate now is "in the past".
+    ack_frame_.ack_delay_time = approximate_now < time_largest_observed_
+                                    ? QuicTime::Delta::Zero()
+                                    : approximate_now - time_largest_observed_;
+  }
+  while (max_ack_ranges_ > 0 &&
+         ack_frame_.packets.NumIntervals() > max_ack_ranges_) {
+    ack_frame_.packets.RemoveSmallestInterval();
+  }
+  // Clear all packet times if any are too far from largest observed.
+  // It's expected this is extremely rare.
+  for (auto it = ack_frame_.received_packet_times.begin();
+       it != ack_frame_.received_packet_times.end();) {
+    if (LargestAcked(ack_frame_) - it->first >=
+        std::numeric_limits<uint8_t>::max()) {
+      it = ack_frame_.received_packet_times.erase(it);
+    } else {
+      ++it;
+    }
+  }
+
+#if QUIC_FRAME_DEBUG
+  QuicFrame frame = QuicFrame(&ack_frame_);
+  frame.delete_forbidden = true;
+  return frame;
+#else  // QUIC_FRAME_DEBUG
+  return QuicFrame(&ack_frame_);
+#endif  // QUIC_FRAME_DEBUG
+}
+
+void QuicReceivedPacketManager::DontWaitForPacketsBefore(
+    QuicPacketNumber least_unacked) {
+  if (!least_unacked.IsInitialized()) {
+    return;
+  }
+  // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks.
+  QUICHE_DCHECK(!peer_least_packet_awaiting_ack_.IsInitialized() ||
+                peer_least_packet_awaiting_ack_ <= least_unacked);
+  if (!peer_least_packet_awaiting_ack_.IsInitialized() ||
+      least_unacked > peer_least_packet_awaiting_ack_) {
+    peer_least_packet_awaiting_ack_ = least_unacked;
+    bool packets_updated = ack_frame_.packets.RemoveUpTo(least_unacked);
+    if (packets_updated) {
+      // Ack frame gets updated because packets set is updated because of stop
+      // waiting frame.
+      ack_frame_updated_ = true;
+    }
+  }
+  QUICHE_DCHECK(ack_frame_.packets.Empty() ||
+                !peer_least_packet_awaiting_ack_.IsInitialized() ||
+                ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_);
+}
+
+QuicTime::Delta QuicReceivedPacketManager::GetMaxAckDelay(
+    QuicPacketNumber last_received_packet_number,
+    const RttStats& rtt_stats) const {
+  if (AckFrequencyFrameReceived() ||
+      last_received_packet_number < PeerFirstSendingPacketNumber() +
+                                        min_received_before_ack_decimation_) {
+    return local_max_ack_delay_;
+  }
+
+  // Wait for the minimum of the ack decimation delay or the delayed ack time
+  // before sending an ack.
+  QuicTime::Delta ack_delay = std::min(
+      local_max_ack_delay_, rtt_stats.min_rtt() * ack_decimation_delay_);
+  return std::max(ack_delay, kAlarmGranularity);
+}
+
+void QuicReceivedPacketManager::MaybeUpdateAckFrequency(
+    QuicPacketNumber last_received_packet_number) {
+  if (AckFrequencyFrameReceived()) {
+    // Skip Ack Decimation below after receiving an AckFrequencyFrame from the
+    // other end point.
+    return;
+  }
+  if (last_received_packet_number <
+      PeerFirstSendingPacketNumber() + min_received_before_ack_decimation_) {
+    return;
+  }
+  ack_frequency_ = unlimited_ack_decimation_
+                       ? std::numeric_limits<size_t>::max()
+                       : kMaxRetransmittablePacketsBeforeAck;
+}
+
+void QuicReceivedPacketManager::MaybeUpdateAckTimeout(
+    bool should_last_packet_instigate_acks,
+    QuicPacketNumber last_received_packet_number,
+    QuicTime last_packet_receipt_time, QuicTime now,
+    const RttStats* rtt_stats) {
+  if (!ack_frame_updated_) {
+    // ACK frame has not been updated, nothing to do.
+    return;
+  }
+
+  if (!ignore_order_ && was_last_packet_missing_ &&
+      last_sent_largest_acked_.IsInitialized() &&
+      last_received_packet_number < last_sent_largest_acked_) {
+    // Only ack immediately if an ACK frame was sent with a larger largest acked
+    // than the newly received packet number.
+    ack_timeout_ = now;
+    return;
+  }
+
+  if (!should_last_packet_instigate_acks) {
+    return;
+  }
+
+  ++num_retransmittable_packets_received_since_last_ack_sent_;
+
+  MaybeUpdateAckFrequency(last_received_packet_number);
+  if (num_retransmittable_packets_received_since_last_ack_sent_ >=
+      ack_frequency_) {
+    ack_timeout_ = now;
+    return;
+  }
+
+  if (!ignore_order_ && HasNewMissingPackets()) {
+    ack_timeout_ = now;
+    return;
+  }
+
+  QuicTime ack_timeout_base = now;
+  const bool quic_update_ack_timeout_on_receipt_time =
+      GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time);
+  if (quic_update_ack_timeout_on_receipt_time) {
+    if (last_packet_receipt_time <= now) {
+      QUIC_CODE_COUNT(quic_update_ack_timeout_on_receipt_time);
+      ack_timeout_base = last_packet_receipt_time;
+    } else {
+      QUIC_CODE_COUNT(quic_update_ack_timeout_on_now);
+      ack_timeout_base = now;
+    }
+  }
+  QuicTime updated_ack_time =
+      ack_timeout_base +
+      GetMaxAckDelay(last_received_packet_number, *rtt_stats);
+  if (quic_update_ack_timeout_on_receipt_time) {
+    updated_ack_time = std::max(now, updated_ack_time);
+  }
+  if (!ack_timeout_.IsInitialized() || ack_timeout_ > updated_ack_time) {
+    ack_timeout_ = updated_ack_time;
+  }
+}
+
+void QuicReceivedPacketManager::ResetAckStates() {
+  ack_frame_updated_ = false;
+  ack_timeout_ = QuicTime::Zero();
+  num_retransmittable_packets_received_since_last_ack_sent_ = 0;
+  last_sent_largest_acked_ = LargestAcked(ack_frame_);
+}
+
+bool QuicReceivedPacketManager::HasMissingPackets() const {
+  if (ack_frame_.packets.Empty()) {
+    return false;
+  }
+  if (ack_frame_.packets.NumIntervals() > 1) {
+    return true;
+  }
+  return peer_least_packet_awaiting_ack_.IsInitialized() &&
+         ack_frame_.packets.Min() > peer_least_packet_awaiting_ack_;
+}
+
+bool QuicReceivedPacketManager::HasNewMissingPackets() const {
+  if (one_immediate_ack_) {
+    return HasMissingPackets() && ack_frame_.packets.LastIntervalLength() == 1;
+  }
+  return HasMissingPackets() &&
+         ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing;
+}
+
+bool QuicReceivedPacketManager::ack_frame_updated() const {
+  return ack_frame_updated_;
+}
+
+QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const {
+  return LargestAcked(ack_frame_);
+}
+
+QuicPacketNumber QuicReceivedPacketManager::PeerFirstSendingPacketNumber()
+    const {
+  if (!least_received_packet_number_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10849_1) << "No packets have been received yet";
+    return QuicPacketNumber(1);
+  }
+  return least_received_packet_number_;
+}
+
+bool QuicReceivedPacketManager::IsAckFrameEmpty() const {
+  return ack_frame_.packets.Empty();
+}
+
+void QuicReceivedPacketManager::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& frame) {
+  int64_t new_sequence_number = frame.sequence_number;
+  if (new_sequence_number <= last_ack_frequency_frame_sequence_number_) {
+    // Ignore old ACK_FREQUENCY frames.
+    return;
+  }
+  last_ack_frequency_frame_sequence_number_ = new_sequence_number;
+  ack_frequency_ = frame.packet_tolerance;
+  local_max_ack_delay_ = frame.max_ack_delay;
+  ignore_order_ = frame.ignore_order;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_received_packet_manager.h b/quiche/quic/core/quic_received_packet_manager.h
new file mode 100644
index 0000000..cf08f22
--- /dev/null
+++ b/quiche/quic/core/quic_received_packet_manager.h
@@ -0,0 +1,218 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
+
+#include <cstddef>
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class RttStats;
+
+namespace test {
+class QuicConnectionPeer;
+class QuicReceivedPacketManagerPeer;
+class UberReceivedPacketManagerPeer;
+}  // namespace test
+
+struct QuicConnectionStats;
+
+// Records all received packets by a connection.
+class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
+ public:
+  QuicReceivedPacketManager();
+  explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
+  QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete;
+  QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) =
+      delete;
+  virtual ~QuicReceivedPacketManager();
+
+  void SetFromConfig(const QuicConfig& config, Perspective perspective);
+
+  // Updates the internal state concerning which packets have been received.
+  // header: the packet header.
+  // timestamp: the arrival time of the packet.
+  virtual void RecordPacketReceived(const QuicPacketHeader& header,
+                                    QuicTime receipt_time);
+
+  // Checks whether |packet_number| is missing and less than largest observed.
+  virtual bool IsMissing(QuicPacketNumber packet_number);
+
+  // Checks if we're still waiting for the packet with |packet_number|.
+  virtual bool IsAwaitingPacket(QuicPacketNumber packet_number) const;
+
+  // Retrieves a frame containing a QuicAckFrame.  The ack frame may not be
+  // changed outside QuicReceivedPacketManager and must be serialized before
+  // another packet is received, or it will change.
+  const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now);
+
+  // Deletes all missing packets before least unacked. The connection won't
+  // process any packets with packet number before |least_unacked| that it
+  // received after this call.
+  void DontWaitForPacketsBefore(QuicPacketNumber least_unacked);
+
+  // Called to update ack_timeout_ to the time when an ACK needs to be sent. A
+  // caller can decide whether and when to send an ACK by retrieving
+  // ack_timeout_. If ack_timeout_ is not initialized, no ACK needs to be sent.
+  // Otherwise, ACK needs to be sent by the specified time.
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             QuicPacketNumber last_received_packet_number,
+                             QuicTime last_packet_receipt_time, QuicTime now,
+                             const RttStats* rtt_stats);
+
+  // Resets ACK related states, called after an ACK is successfully sent.
+  void ResetAckStates();
+
+  // Returns true if there are any missing packets.
+  bool HasMissingPackets() const;
+
+  // Returns true when there are new missing packets to be reported within 3
+  // packets of the largest observed.
+  virtual bool HasNewMissingPackets() const;
+
+  QuicPacketNumber peer_least_packet_awaiting_ack() const {
+    return peer_least_packet_awaiting_ack_;
+  }
+
+  virtual bool ack_frame_updated() const;
+
+  QuicPacketNumber GetLargestObserved() const;
+
+  // Returns peer first sending packet number to our best knowledge. Considers
+  // least_received_packet_number_ as peer first sending packet number. Please
+  // note, this function should only be called when at least one packet has been
+  // received.
+  QuicPacketNumber PeerFirstSendingPacketNumber() const;
+
+  // Returns true if ack frame is empty.
+  bool IsAckFrameEmpty() const;
+
+  void set_connection_stats(QuicConnectionStats* stats) { stats_ = stats; }
+
+  // For logging purposes.
+  const QuicAckFrame& ack_frame() const { return ack_frame_; }
+
+  void set_max_ack_ranges(size_t max_ack_ranges) {
+    max_ack_ranges_ = max_ack_ranges;
+  }
+
+  void set_save_timestamps(bool save_timestamps, bool in_order_packets_only) {
+    save_timestamps_ = save_timestamps;
+    save_timestamps_for_in_order_packets_ = in_order_packets_only;
+  }
+
+  size_t min_received_before_ack_decimation() const {
+    return min_received_before_ack_decimation_;
+  }
+  void set_min_received_before_ack_decimation(size_t new_value) {
+    min_received_before_ack_decimation_ = new_value;
+  }
+
+  void set_ack_frequency(size_t new_value) {
+    QUICHE_DCHECK_GT(new_value, 0u);
+    ack_frequency_ = new_value;
+  }
+
+  void set_local_max_ack_delay(QuicTime::Delta local_max_ack_delay) {
+    local_max_ack_delay_ = local_max_ack_delay;
+  }
+
+  QuicTime ack_timeout() const { return ack_timeout_; }
+
+  void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicReceivedPacketManagerPeer;
+  friend class test::UberReceivedPacketManagerPeer;
+
+  // Sets ack_timeout_ to |time| if ack_timeout_ is not initialized or > time.
+  void MaybeUpdateAckTimeoutTo(QuicTime time);
+
+  // Maybe update ack_frequency_ when condition meets.
+  void MaybeUpdateAckFrequency(QuicPacketNumber last_received_packet_number);
+
+  QuicTime::Delta GetMaxAckDelay(QuicPacketNumber last_received_packet_number,
+                                 const RttStats& rtt_stats) const;
+
+  bool AckFrequencyFrameReceived() const {
+    return last_ack_frequency_frame_sequence_number_ >= 0;
+  }
+
+  // Least packet number of the the packet sent by the peer for which it
+  // hasn't received an ack.
+  QuicPacketNumber peer_least_packet_awaiting_ack_;
+
+  // Received packet information used to produce acks.
+  QuicAckFrame ack_frame_;
+
+  // True if |ack_frame_| has been updated since UpdateReceivedPacketInfo was
+  // last called.
+  bool ack_frame_updated_;
+
+  // Maximum number of ack ranges allowed to be stored in the ack frame.
+  size_t max_ack_ranges_;
+
+  // The time we received the largest_observed packet number, or zero if
+  // no packet numbers have been received since UpdateReceivedPacketInfo.
+  // Needed for calculating ack_delay_time.
+  QuicTime time_largest_observed_;
+
+  // If true, save timestamps in the ack_frame_.
+  bool save_timestamps_;
+
+  // If true and |save_timestamps_|, only save timestamps for packets that are
+  // received in order.
+  bool save_timestamps_for_in_order_packets_;
+
+  // Least packet number received from peer.
+  QuicPacketNumber least_received_packet_number_;
+
+  QuicConnectionStats* stats_;
+
+  // How many retransmittable packets have arrived without sending an ack.
+  QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_;
+  // Ack decimation will start happening after this many packets are received.
+  size_t min_received_before_ack_decimation_;
+  // Ack every n-th packet.
+  size_t ack_frequency_;
+  // The max delay in fraction of min_rtt to use when sending decimated acks.
+  float ack_decimation_delay_;
+  // When true, removes ack decimation's max number of packets(10) before
+  // sending an ack.
+  bool unlimited_ack_decimation_;
+  // When true, only send 1 immediate ACK when reordering is detected.
+  bool one_immediate_ack_;
+  // When true, do not ack immediately upon observation of packet reordering.
+  bool ignore_order_;
+
+  // The local node's maximum ack delay time. This is the maximum amount of
+  // time to wait before sending an acknowledgement.
+  QuicTime::Delta local_max_ack_delay_;
+  // Time that an ACK needs to be sent. 0 means no ACK is pending. Used when
+  // decide_when_to_send_acks_ is true.
+  QuicTime ack_timeout_;
+
+  // The time the previous ack-instigating packet was received and processed.
+  QuicTime time_of_previous_received_packet_;
+  // Whether the most recent packet was missing before it was received.
+  bool was_last_packet_missing_;
+
+  // Last sent largest acked, which gets updated when ACK was successfully sent.
+  QuicPacketNumber last_sent_largest_acked_;
+
+  // The sequence number of the last received AckFrequencyFrame. Negative if
+  // none received.
+  int64_t last_ack_frequency_frame_sequence_number_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_
diff --git a/quiche/quic/core/quic_received_packet_manager_test.cc b/quiche/quic/core/quic_received_packet_manager_test.cc
new file mode 100644
index 0000000..65cfa86
--- /dev/null
+++ b/quiche/quic/core/quic_received_packet_manager_test.cc
@@ -0,0 +1,691 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_received_packet_manager.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <ostream>
+#include <vector>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class QuicReceivedPacketManagerPeer {
+ public:
+  static void SetOneImmediateAck(QuicReceivedPacketManager* manager,
+                                 bool one_immediate_ack) {
+    manager->one_immediate_ack_ = one_immediate_ack;
+  }
+
+  static void SetAckDecimationDelay(QuicReceivedPacketManager* manager,
+                                    float ack_decimation_delay) {
+    manager->ack_decimation_delay_ = ack_decimation_delay;
+  }
+};
+
+namespace {
+
+const bool kInstigateAck = true;
+const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
+const QuicTime::Delta kDelayedAckTime =
+    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+class QuicReceivedPacketManagerTest : public QuicTest {
+ protected:
+  QuicReceivedPacketManagerTest() : received_manager_(&stats_) {
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
+    received_manager_.set_save_timestamps(true, false);
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number) {
+    RecordPacketReceipt(packet_number, QuicTime::Zero());
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
+    QuicPacketHeader header;
+    header.packet_number = QuicPacketNumber(packet_number);
+    received_manager_.RecordPacketReceived(header, receipt_time);
+  }
+
+  bool HasPendingAck() {
+    return received_manager_.ack_timeout().IsInitialized();
+  }
+
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             uint64_t last_received_packet_number) {
+    received_manager_.MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks,
+        QuicPacketNumber(last_received_packet_number),
+        /*last_packet_receipt_time=*/clock_.ApproximateNow(),
+        /*now=*/clock_.ApproximateNow(), &rtt_stats_);
+  }
+
+  void CheckAckTimeout(QuicTime time) {
+    QUICHE_DCHECK(HasPendingAck());
+    QUICHE_DCHECK_EQ(received_manager_.ack_timeout(), time);
+    if (time <= clock_.ApproximateNow()) {
+      // ACK timeout expires, send an ACK.
+      received_manager_.ResetAckStates();
+      QUICHE_DCHECK(!HasPendingAck());
+    }
+  }
+
+  MockClock clock_;
+  RttStats rtt_stats_;
+  QuicConnectionStats stats_;
+  QuicReceivedPacketManager received_manager_;
+};
+
+TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
+  QuicPacketHeader header;
+  header.packet_number = QuicPacketNumber(2u);
+  received_manager_.RecordPacketReceived(header, QuicTime::Zero());
+  header.packet_number = QuicPacketNumber(7u);
+  received_manager_.RecordPacketReceived(header, QuicTime::Zero());
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
+  received_manager_.DontWaitForPacketsBefore(QuicPacketNumber(4));
+  EXPECT_FALSE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
+}
+
+TEST_F(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
+  QuicPacketHeader header;
+  header.packet_number = QuicPacketNumber(2u);
+  QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  received_manager_.RecordPacketReceived(header, two_ms);
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+
+  QuicFrame ack = received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
+  received_manager_.ResetAckStates();
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  // When UpdateReceivedPacketInfo with a time earlier than the time of the
+  // largest observed packet, make sure that the delta is 0, not negative.
+  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
+  ack = received_manager_.GetUpdatedAckFrame(four_ms);
+  received_manager_.ResetAckStates();
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  // When UpdateReceivedPacketInfo after not having received a new packet,
+  // the delta should still be accurate.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
+            ack.ack_frame->ack_delay_time);
+  // And received packet times won't have change.
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  header.packet_number = QuicPacketNumber(999u);
+  received_manager_.RecordPacketReceived(header, two_ms);
+  header.packet_number = QuicPacketNumber(4u);
+  received_manager_.RecordPacketReceived(header, two_ms);
+  header.packet_number = QuicPacketNumber(1000u);
+  received_manager_.RecordPacketReceived(header, two_ms);
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  ack = received_manager_.GetUpdatedAckFrame(two_ms);
+  received_manager_.ResetAckStates();
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  // UpdateReceivedPacketInfo should discard any times which can't be
+  // expressed on the wire.
+  EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(1);
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(6);
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+
+  EXPECT_EQ(4u, stats_.max_sequence_reordering);
+  EXPECT_EQ(1000, stats_.max_time_reordering_us);
+  EXPECT_EQ(1u, stats_.packets_reordered);
+}
+
+TEST_F(QuicReceivedPacketManagerTest, LimitAckRanges) {
+  received_manager_.set_max_ack_ranges(10);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  for (int i = 0; i < 100; ++i) {
+    RecordPacketReceipt(1 + 2 * i);
+    EXPECT_TRUE(received_manager_.ack_frame_updated());
+    received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
+    EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
+    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
+              received_manager_.ack_frame().packets.Max());
+    for (int j = 0; j < std::min(10, i + 1); ++j) {
+      ASSERT_GE(i, j);
+      EXPECT_TRUE(received_manager_.ack_frame().packets.Contains(
+          QuicPacketNumber(1 + (i - j) * 2)));
+      if (i > j) {
+        EXPECT_FALSE(received_manager_.ack_frame().packets.Contains(
+            QuicPacketNumber((i - j) * 2)));
+      }
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+  RecordPacketReceipt(3, QuicTime::Zero());
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderPackets) {
+  received_manager_.set_save_timestamps(true, true);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_TRUE(received_manager_.ack_frame_updated());
+  EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
+  RecordPacketReceipt(4,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+
+  RecordPacketReceipt(3,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(3));
+  EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, HasMissingPackets) {
+  EXPECT_QUIC_BUG(received_manager_.PeerFirstSendingPacketNumber(),
+                  "No packets have been received yet");
+  RecordPacketReceipt(4, QuicTime::Zero());
+  EXPECT_EQ(QuicPacketNumber(4),
+            received_manager_.PeerFirstSendingPacketNumber());
+  EXPECT_FALSE(received_manager_.HasMissingPackets());
+  RecordPacketReceipt(3, QuicTime::Zero());
+  EXPECT_FALSE(received_manager_.HasMissingPackets());
+  EXPECT_EQ(QuicPacketNumber(3),
+            received_manager_.PeerFirstSendingPacketNumber());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_EQ(QuicPacketNumber(1),
+            received_manager_.PeerFirstSendingPacketNumber());
+  EXPECT_TRUE(received_manager_.HasMissingPackets());
+  RecordPacketReceipt(2, QuicTime::Zero());
+  EXPECT_EQ(QuicPacketNumber(1),
+            received_manager_.PeerFirstSendingPacketNumber());
+  EXPECT_FALSE(received_manager_.HasMissingPackets());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(6, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 6);
+  // Immediate ack is scheduled, because 4 is still missing.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Should ack immediately, since this fills the last hole.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(7, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 7);
+  // Immediate ack is scheduled, because 4 is still missing.
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent1Ack) {
+  QuicReceivedPacketManagerPeer::SetOneImmediateAck(&received_manager_, true);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(6, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 6);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Should ack immediately, since this fills the last hole.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(7, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 7);
+  // Delayed ack is scheduled, even though 4 is still missing.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(QuicReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, AckReceiptCausesAckSend) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  clock_.AdvanceTime(kDelayedAckTime);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 4);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 5);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, AckSentEveryNthPacket) {
+  EXPECT_FALSE(HasPendingAck());
+  received_manager_.set_ack_frequency(3);
+
+  // Receives packets 1 - 39.
+  for (size_t i = 1; i <= 39; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 3 == 0) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest, AckDecimationReducesAcks) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Start ack decimation from 10th packet.
+  received_manager_.set_min_received_before_ack_decimation(10);
+
+  // Receives packets 1 - 29.
+  for (size_t i = 1; i <= 29; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i <= 10) {
+      // For packets 1-10, ack every 2 packets.
+      if (i % 2 == 0) {
+        CheckAckTimeout(clock_.ApproximateNow());
+      } else {
+        CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+      }
+      continue;
+    }
+    // ack at 20.
+    if (i == 20) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
+    }
+  }
+
+  // We now receive the 30th packet, and so we send an ack.
+  RecordPacketReceipt(30, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 30);
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimation) {
+  EXPECT_FALSE(HasPendingAck());
+  // The ack time should be based on min_rtt * 1/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationMin1ms) {
+  EXPECT_FALSE(HasPendingAck());
+  // Seed the min_rtt with a kAlarmGranularity signal.
+  rtt_stats_.UpdateRtt(kAlarmGranularity, QuicTime::Delta::Zero(),
+                       clock_.ApproximateNow());
+  // The ack time should be based on kAlarmGranularity, since the RTT is 1ms.
+  QuicTime ack_time = clock_.ApproximateNow() + kAlarmGranularity;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       SendDelayedAckDecimationUnlimitedAggregation) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicConfig config;
+  QuicTagVector connection_options;
+  // No limit on the number of packets received before sending an ack.
+  connection_options.push_back(kAKDU);
+  config.SetConnectionOptionsToSend(connection_options);
+  received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
+
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // 18 packets will not cause an ack to be sent.  19 will because when
+  // stop waiting frames are in use, we ack every 20 packets no matter what.
+  for (int i = 1; i <= 18; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(ack_time);
+}
+
+TEST_F(QuicReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicReceivedPacketManagerPeer::SetAckDecimationDelay(&received_manager_,
+                                                       0.125);
+
+  // The ack time should be based on min_rtt/8, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       UpdateMaxAckDelayAndAckFrequencyFromAckFrequencyFrame) {
+  EXPECT_FALSE(HasPendingAck());
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(10);
+  frame.packet_tolerance = 5;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  for (int i = 1; i <= 50; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % frame.packet_tolerance == 0) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + frame.max_ack_delay);
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       DisableOutOfOrderAckByIgnoreOrderFromAckFrequencyFrame) {
+  EXPECT_FALSE(HasPendingAck());
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = kDelayedAckTime;
+  frame.packet_tolerance = 2;
+  frame.ignore_order = true;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Don't ack as ignore_order is set by AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Don't ack as ignore_order is set by AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       DisableMissingPaketsAckByIgnoreOrderFromAckFrequencyFrame) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicConfig config;
+  config.SetConnectionOptionsToSend({kAFFE});
+  received_manager_.SetFromConfig(config, Perspective::IS_CLIENT);
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = kDelayedAckTime;
+  frame.packet_tolerance = 2;
+  frame.ignore_order = true;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  // Don't ack even if packet 3 is newly missing as ignore_order is set by
+  // AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 5);
+  // Immediate ack is sent as this is the 2nd packet of every two packets.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(7, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 7);
+  // Don't ack even if packet 6 is newly missing as ignore_order is set by
+  // AckFrequencyFrame.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       AckDecimationDisabledWhenAckFrequencyFrameIsReceived) {
+  EXPECT_FALSE(HasPendingAck());
+
+  QuicAckFrequencyFrame frame;
+  frame.max_ack_delay = kDelayedAckTime;
+  frame.packet_tolerance = 3;
+  frame.ignore_order = true;
+  received_manager_.OnAckFrequencyFrame(frame);
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  uint64_t FiftyPacketsAfterAckDecimation = kFirstDecimatedPacket + 50;
+  for (uint64_t i = 1; i < FiftyPacketsAfterAckDecimation; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 3 == 0) {
+      // Ack every 3 packets as decimation is disabled.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      // Ack at default delay as decimation is disabled.
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+}
+
+TEST_F(QuicReceivedPacketManagerTest, UpdateAckTimeoutOnPacketReceiptTime) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Received packets 3 and 4.
+  QuicTime packet_receipt_time3 = clock_.ApproximateNow();
+  // Packet 3 gets processed after 10ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  RecordPacketReceipt(3, packet_receipt_time3);
+  received_manager_.MaybeUpdateAckTimeout(
+      kInstigateAck, QuicPacketNumber(3),
+      /*last_packet_receipt_time=*/packet_receipt_time3,
+      clock_.ApproximateNow(), &rtt_stats_);
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Make sure ACK timeout is based on receipt time.
+    CheckAckTimeout(packet_receipt_time3 + kDelayedAckTime);
+  } else {
+    // Make sure ACK timeout is based on now.
+    CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  }
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  // Immediate ack is sent.
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(QuicReceivedPacketManagerTest,
+       UpdateAckTimeoutOnPacketReceiptTimeLongerQueuingTime) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Received packets 3 and 4.
+  QuicTime packet_receipt_time3 = clock_.ApproximateNow();
+  // Packet 3 gets processed after 100ms.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+  RecordPacketReceipt(3, packet_receipt_time3);
+  received_manager_.MaybeUpdateAckTimeout(
+      kInstigateAck, QuicPacketNumber(3),
+      /*last_packet_receipt_time=*/packet_receipt_time3,
+      clock_.ApproximateNow(), &rtt_stats_);
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Given 100ms > ack delay, verify immediate ACK.
+    CheckAckTimeout(clock_.ApproximateNow());
+  } else {
+    // Make sure ACK timeout is based on now.
+    CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sent_packet_manager.cc b/quiche/quic/core/quic_sent_packet_manager.cc
new file mode 100644
index 0000000..a77dddb
--- /dev/null
+++ b/quiche/quic/core/quic_sent_packet_manager.cc
@@ -0,0 +1,1872 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <string>
+
+#include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
+#include "quiche/quic/core/congestion_control/pacing_sender.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+
+namespace {
+static const int64_t kDefaultRetransmissionTimeMs = 500;
+static const int64_t kMaxRetransmissionTimeMs = 60000;
+// Maximum number of exponential backoffs used for RTO timeouts.
+static const size_t kMaxRetransmissions = 10;
+// Maximum number of packets retransmitted upon an RTO.
+static const size_t kMaxRetransmissionsOnTimeout = 2;
+// The path degrading delay is the sum of this number of consecutive RTO delays.
+const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
+
+// Ensure the handshake timer isnt't faster than 10ms.
+// This limits the tenth retransmitted packet to 10s after the initial CHLO.
+static const int64_t kMinHandshakeTimeoutMs = 10;
+
+// Sends up to two tail loss probes before firing an RTO,
+// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
+static const size_t kDefaultMaxTailLossProbes = 2;
+
+// Returns true of retransmissions of the specified type should retransmit
+// the frames directly (as opposed to resulting in a loss notification).
+inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
+  return transmission_type == HANDSHAKE_RETRANSMISSION ||
+         transmission_type == TLP_RETRANSMISSION ||
+         transmission_type == PROBING_RETRANSMISSION ||
+         transmission_type == RTO_RETRANSMISSION ||
+         transmission_type == PTO_RETRANSMISSION;
+}
+
+// If pacing rate is accurate, > 2 burst token is not likely to help first ACK
+// to arrive earlier, and overly large burst token could cause incast packet
+// losses.
+static const uint32_t kConservativeUnpacedBurst = 2;
+
+}  // namespace
+
+#define ENDPOINT                                                         \
+  (unacked_packets_.perspective() == Perspective::IS_SERVER ? "Server: " \
+                                                            : "Client: ")
+
+QuicSentPacketManager::QuicSentPacketManager(
+    Perspective perspective, const QuicClock* clock, QuicRandom* random,
+    QuicConnectionStats* stats, CongestionControlType congestion_control_type)
+    : unacked_packets_(perspective),
+      clock_(clock),
+      random_(random),
+      stats_(stats),
+      debug_delegate_(nullptr),
+      network_change_visitor_(nullptr),
+      initial_congestion_window_(kInitialCongestionWindow),
+      loss_algorithm_(&uber_loss_algorithm_),
+      consecutive_rto_count_(0),
+      consecutive_tlp_count_(0),
+      consecutive_crypto_retransmission_count_(0),
+      pending_timer_transmission_count_(0),
+      max_tail_loss_probes_(kDefaultMaxTailLossProbes),
+      max_rto_packets_(kMaxRetransmissionsOnTimeout),
+      using_pacing_(false),
+      use_new_rto_(false),
+      conservative_handshake_retransmits_(false),
+      min_tlp_timeout_(
+          QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
+      min_rto_timeout_(
+          QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
+      largest_mtu_acked_(0),
+      handshake_finished_(false),
+      peer_max_ack_delay_(
+          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+      rtt_updated_(false),
+      acked_packets_iter_(last_ack_frame_.packets.rbegin()),
+      pto_enabled_(GetQuicRestartFlag(quic_default_on_pto2)),
+      max_probe_packets_per_pto_(2),
+      consecutive_pto_count_(0),
+      handshake_mode_disabled_(false),
+      skip_packet_number_for_pto_(false),
+      always_include_max_ack_delay_for_pto_timeout_(true),
+      pto_exponential_backoff_start_point_(0),
+      pto_rttvar_multiplier_(4),
+      num_tlp_timeout_ptos_(0),
+      handshake_packet_acked_(false),
+      zero_rtt_packet_acked_(false),
+      one_rtt_packet_acked_(false),
+      first_pto_srtt_multiplier_(0),
+      use_standard_deviation_for_pto_(false),
+      pto_multiplier_without_rtt_samples_(3),
+      num_ptos_for_path_degrading_(0),
+      ignore_pings_(false),
+      ignore_ack_delay_(false) {
+  SetSendAlgorithm(congestion_control_type);
+  if (pto_enabled_) {
+    QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 1, 2);
+    // TODO(fayang): change the default values when deprecating
+    // quic_default_on_pto2.
+    // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
+    // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
+    // last in flight packet.
+    max_probe_packets_per_pto_ = 1;
+    skip_packet_number_for_pto_ = true;
+    first_pto_srtt_multiplier_ = 1.5;
+    pto_rttvar_multiplier_ = 2;
+  }
+}
+
+QuicSentPacketManager::~QuicSentPacketManager() {}
+
+void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
+  const Perspective perspective = unacked_packets_.perspective();
+  if (config.HasReceivedInitialRoundTripTimeUs() &&
+      config.ReceivedInitialRoundTripTimeUs() > 0) {
+    if (!config.HasClientSentConnectionOption(kNRTT, perspective)) {
+      SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                        config.ReceivedInitialRoundTripTimeUs()),
+                    /*trusted=*/false);
+    }
+  } else if (config.HasInitialRoundTripTimeUsToSend() &&
+             config.GetInitialRoundTripTimeUsToSend() > 0) {
+    SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                      config.GetInitialRoundTripTimeUsToSend()),
+                  /*trusted=*/false);
+  }
+  if (config.HasReceivedMaxAckDelayMs()) {
+    peer_max_ack_delay_ =
+        QuicTime::Delta::FromMilliseconds(config.ReceivedMaxAckDelayMs());
+  }
+  if (GetQuicReloadableFlag(quic_can_send_ack_frequency) &&
+      perspective == Perspective::IS_SERVER) {
+    if (config.HasReceivedMinAckDelayMs()) {
+      peer_min_ack_delay_ =
+          QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs());
+    }
+    if (config.HasClientSentConnectionOption(kAFF1, perspective)) {
+      use_smoothed_rtt_in_ack_delay_ = true;
+    }
+  }
+  if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
+    ignore_ack_delay_ = true;
+  }
+  if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
+    // Set the minimum to the alarm granularity.
+    min_tlp_timeout_ = kAlarmGranularity;
+  }
+  if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
+    // Set the minimum to the alarm granularity.
+    min_rto_timeout_ = kAlarmGranularity;
+  }
+
+  if (!GetQuicRestartFlag(quic_default_on_pto2)) {
+    if (config.HasClientSentConnectionOption(k2PTO, perspective)) {
+      pto_enabled_ = true;
+    }
+    if (config.HasClientSentConnectionOption(k1PTO, perspective)) {
+      pto_enabled_ = true;
+      max_probe_packets_per_pto_ = 1;
+    }
+
+    if (config.HasClientSentConnectionOption(kPTOS, perspective)) {
+      if (!pto_enabled_) {
+        QUIC_PEER_BUG(quic_peer_bug_12552_1)
+            << "PTO is not enabled when receiving PTOS connection option.";
+        pto_enabled_ = true;
+        max_probe_packets_per_pto_ = 1;
+      }
+      skip_packet_number_for_pto_ = true;
+    }
+    if (pto_enabled_) {
+      if (config.HasClientSentConnectionOption(kPTOA, perspective)) {
+        always_include_max_ack_delay_for_pto_timeout_ = false;
+      }
+      if (config.HasClientSentConnectionOption(kPEB1, perspective)) {
+        StartExponentialBackoffAfterNthPto(1);
+      }
+      if (config.HasClientSentConnectionOption(kPEB2, perspective)) {
+        StartExponentialBackoffAfterNthPto(2);
+      }
+      if (config.HasClientSentConnectionOption(kPVS1, perspective)) {
+        pto_rttvar_multiplier_ = 2;
+      }
+      if (config.HasClientSentConnectionOption(kPAG1, perspective)) {
+        QUIC_CODE_COUNT(one_aggressive_pto);
+        num_tlp_timeout_ptos_ = 1;
+      }
+      if (config.HasClientSentConnectionOption(kPAG2, perspective)) {
+        QUIC_CODE_COUNT(two_aggressive_ptos);
+        num_tlp_timeout_ptos_ = 2;
+      }
+      if (config.HasClientSentConnectionOption(kPLE1, perspective)) {
+        first_pto_srtt_multiplier_ = 0.5;
+      } else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
+        first_pto_srtt_multiplier_ = 1.5;
+      }
+      if (config.HasClientSentConnectionOption(kAPTO, perspective)) {
+        pto_multiplier_without_rtt_samples_ = 1.5;
+      }
+      if (config.HasClientSentConnectionOption(kPSDA, perspective)) {
+        use_standard_deviation_for_pto_ = true;
+        rtt_stats_.EnableStandardDeviationCalculation();
+      }
+    }
+  }
+
+  if (pto_enabled_) {
+    if (config.HasClientRequestedIndependentOption(kPDP1, perspective)) {
+      num_ptos_for_path_degrading_ = 1;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP2, perspective)) {
+      num_ptos_for_path_degrading_ = 2;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP3, perspective)) {
+      num_ptos_for_path_degrading_ = 3;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP4, perspective)) {
+      num_ptos_for_path_degrading_ = 4;
+    }
+    if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
+      num_ptos_for_path_degrading_ = 5;
+    }
+  }
+
+  // Configure congestion control.
+  if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
+    SetSendAlgorithm(kBBR);
+  }
+  if (GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
+      config.HasClientRequestedIndependentOption(kB2ON, perspective)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_allow_client_enabled_bbr_v2);
+    SetSendAlgorithm(kBBRv2);
+  }
+
+  if (config.HasClientRequestedIndependentOption(kRENO, perspective)) {
+    SetSendAlgorithm(kRenoBytes);
+  } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective) ||
+             (GetQuicReloadableFlag(quic_default_to_bbr) &&
+              config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
+    SetSendAlgorithm(kCubicBytes);
+  }
+
+  // Initial window.
+  if (GetQuicReloadableFlag(quic_unified_iw_options)) {
+    if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 1, 4);
+      initial_congestion_window_ = 3;
+      send_algorithm_->SetInitialCongestionWindowInPackets(3);
+    }
+    if (config.HasClientRequestedIndependentOption(kIW10, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 2, 4);
+      initial_congestion_window_ = 10;
+      send_algorithm_->SetInitialCongestionWindowInPackets(10);
+    }
+    if (config.HasClientRequestedIndependentOption(kIW20, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 3, 4);
+      initial_congestion_window_ = 20;
+      send_algorithm_->SetInitialCongestionWindowInPackets(20);
+    }
+    if (config.HasClientRequestedIndependentOption(kIW50, perspective)) {
+      QUIC_RELOADABLE_FLAG_COUNT_N(quic_unified_iw_options, 4, 4);
+      initial_congestion_window_ = 50;
+      send_algorithm_->SetInitialCongestionWindowInPackets(50);
+    }
+  }
+  if (config.HasClientRequestedIndependentOption(kBWS5, perspective)) {
+    initial_congestion_window_ = 10;
+    send_algorithm_->SetInitialCongestionWindowInPackets(10);
+  }
+
+  if (config.HasClientRequestedIndependentOption(kIGNP, perspective)) {
+    ignore_pings_ = true;
+  }
+
+  using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
+
+  if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
+    max_tail_loss_probes_ = 0;
+  }
+  if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
+    max_tail_loss_probes_ = 1;
+  }
+  if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
+    max_rto_packets_ = 1;
+  }
+  if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
+    use_new_rto_ = true;
+  }
+  // Configure loss detection.
+  if (config.HasClientRequestedIndependentOption(kILD0, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
+    uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kILD1, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
+    uber_loss_algorithm_.DisableAdaptiveReorderingThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kILD2, perspective)) {
+    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
+    uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
+  }
+  if (config.HasClientRequestedIndependentOption(kILD3, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
+    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kILD4, perspective)) {
+    uber_loss_algorithm_.SetReorderingShift(kDefaultLossDelayShift);
+    uber_loss_algorithm_.EnableAdaptiveReorderingThreshold();
+    uber_loss_algorithm_.EnableAdaptiveTimeThreshold();
+  }
+  if (config.HasClientRequestedIndependentOption(kRUNT, perspective)) {
+    uber_loss_algorithm_.DisablePacketThresholdForRuntPackets();
+  }
+  if (config.HasClientSentConnectionOption(kCONH, perspective)) {
+    conservative_handshake_retransmits_ = true;
+  }
+  send_algorithm_->SetFromConfig(config, perspective);
+  loss_algorithm_->SetFromConfig(config, perspective);
+
+  if (network_change_visitor_ != nullptr) {
+    network_change_visitor_->OnCongestionChange();
+  }
+
+  if (debug_delegate_ != nullptr) {
+    DebugDelegate::SendParameters parameters;
+    parameters.congestion_control_type =
+        send_algorithm_->GetCongestionControlType();
+    parameters.use_pacing = using_pacing_;
+    parameters.initial_congestion_window = initial_congestion_window_;
+    debug_delegate_->OnConfigProcessed(parameters);
+  }
+}
+
+void QuicSentPacketManager::ApplyConnectionOptions(
+    const QuicTagVector& connection_options) {
+  absl::optional<CongestionControlType> cc_type;
+  if (ContainsQuicTag(connection_options, kB2ON)) {
+    cc_type = kBBRv2;
+  } else if (ContainsQuicTag(connection_options, kTBBR)) {
+    cc_type = kBBR;
+  } else if (ContainsQuicTag(connection_options, kRENO)) {
+    cc_type = kRenoBytes;
+  } else if (ContainsQuicTag(connection_options, kQBIC)) {
+    cc_type = kCubicBytes;
+  }
+
+  if (cc_type.has_value()) {
+    SetSendAlgorithm(*cc_type);
+  }
+
+  send_algorithm_->ApplyConnectionOptions(connection_options);
+}
+
+void QuicSentPacketManager::ResumeConnectionState(
+    const CachedNetworkParameters& cached_network_params,
+    bool max_bandwidth_resumption) {
+  QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
+      max_bandwidth_resumption
+          ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
+          : cached_network_params.bandwidth_estimate_bytes_per_second());
+  QuicTime::Delta rtt =
+      QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
+  // This calls the old AdjustNetworkParameters interface, and fills certain
+  // fields in SendAlgorithmInterface::NetworkParams
+  // (e.g., quic_bbr_fix_pacing_rate) using GFE flags.
+  SendAlgorithmInterface::NetworkParams params(
+      bandwidth, rtt, /*allow_cwnd_to_decrease = */ false);
+  // The rtt is trusted because it's a min_rtt measured from a previous
+  // connection with the same network path between client and server.
+  params.is_rtt_trusted = true;
+  AdjustNetworkParameters(params);
+}
+
+void QuicSentPacketManager::AdjustNetworkParameters(
+    const SendAlgorithmInterface::NetworkParams& params) {
+  if (params.burst_token != 0) {
+    if (using_pacing_) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_set_burst_token);
+      int old_burst_size = pacing_sender_.initial_burst_size();
+      pacing_sender_.SetBurstTokens(params.burst_token);
+      if (debug_delegate_ != nullptr) {
+        debug_delegate_->OnAdjustBurstSize(old_burst_size,
+                                           pacing_sender_.initial_burst_size());
+      }
+    }
+    return;
+  }
+  const QuicBandwidth& bandwidth = params.bandwidth;
+  const QuicTime::Delta& rtt = params.rtt;
+
+  if (use_lower_min_irtt()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 2, 2);
+    if (!rtt.IsZero()) {
+      if (params.is_rtt_trusted) {
+        // Always set initial rtt if it's trusted.
+        SetInitialRtt(rtt, /*trusted=*/true);
+      } else if (rtt_stats_.initial_rtt() ==
+                 QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
+        // Only set initial rtt if we are using the default. This avoids
+        // overwriting a trusted initial rtt by an untrusted one.
+        SetInitialRtt(rtt, /*trusted=*/false);
+      }
+    }
+  } else {
+    if (!rtt.IsZero()) {
+      SetInitialRtt(rtt, /*trusted=*/false);
+    }
+  }
+  const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
+  if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
+      !bandwidth.IsZero()) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts);
+    pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst);
+  }
+  send_algorithm_->AdjustNetworkParameters(params);
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnAdjustNetworkParameters(
+        bandwidth, rtt.IsZero() ? rtt_stats_.MinOrInitialRtt() : rtt, old_cwnd,
+        send_algorithm_->GetCongestionWindow());
+  }
+}
+
+void QuicSentPacketManager::SetLossDetectionTuner(
+    std::unique_ptr<LossDetectionTunerInterface> tuner) {
+  uber_loss_algorithm_.SetLossDetectionTuner(std::move(tuner));
+}
+
+void QuicSentPacketManager::OnConfigNegotiated() {
+  loss_algorithm_->OnConfigNegotiated();
+}
+
+void QuicSentPacketManager::OnConnectionClosed() {
+  loss_algorithm_->OnConnectionClosed();
+}
+
+void QuicSentPacketManager::SetHandshakeConfirmed() {
+  if (!handshake_finished_) {
+    handshake_finished_ = true;
+    NeuterHandshakePackets();
+  }
+}
+
+void QuicSentPacketManager::PostProcessNewlyAckedPackets(
+    QuicPacketNumber ack_packet_number,
+    EncryptionLevel ack_decrypted_level,
+    const QuicAckFrame& ack_frame,
+    QuicTime ack_receive_time,
+    bool rtt_updated,
+    QuicByteCount prior_bytes_in_flight) {
+  unacked_packets_.NotifyAggregatedStreamFrameAcked(
+      last_ack_frame_.ack_delay_time);
+  InvokeLossDetection(ack_receive_time);
+  // Ignore losses in RTO mode.
+  if (consecutive_rto_count_ > 0 && !use_new_rto_) {
+    packets_lost_.clear();
+  }
+  MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
+                             ack_receive_time);
+  unacked_packets_.RemoveObsoletePackets();
+
+  sustained_bandwidth_recorder_.RecordEstimate(
+      send_algorithm_->InRecovery(), send_algorithm_->InSlowStart(),
+      send_algorithm_->BandwidthEstimate(), ack_receive_time, clock_->WallNow(),
+      rtt_stats_.smoothed_rtt());
+
+  // Anytime we are making forward progress and have a new RTT estimate, reset
+  // the backoff counters.
+  if (rtt_updated) {
+    if (consecutive_rto_count_ > 0) {
+      // If the ack acknowledges data sent prior to the RTO,
+      // the RTO was spurious.
+      if (LargestAcked(ack_frame) < first_rto_transmission_) {
+        // Replace SRTT with latest_rtt and increase the variance to prevent
+        // a spurious RTO from happening again.
+        rtt_stats_.ExpireSmoothedMetrics();
+      } else {
+        if (!use_new_rto_) {
+          send_algorithm_->OnRetransmissionTimeout(true);
+        }
+      }
+    }
+    // Records the max consecutive RTO or PTO before forward progress has been
+    // made.
+    if (consecutive_rto_count_ >
+        stats_->max_consecutive_rto_with_forward_progress) {
+      stats_->max_consecutive_rto_with_forward_progress =
+          consecutive_rto_count_;
+    } else if (consecutive_pto_count_ >
+               stats_->max_consecutive_rto_with_forward_progress) {
+      stats_->max_consecutive_rto_with_forward_progress =
+          consecutive_pto_count_;
+    }
+    // Reset all retransmit counters any time a new packet is acked.
+    consecutive_rto_count_ = 0;
+    consecutive_tlp_count_ = 0;
+    consecutive_pto_count_ = 0;
+    consecutive_crypto_retransmission_count_ = 0;
+  }
+
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnIncomingAck(
+        ack_packet_number, ack_decrypted_level, ack_frame, ack_receive_time,
+        LargestAcked(ack_frame), rtt_updated, GetLeastUnacked());
+  }
+  // Remove packets below least unacked from all_packets_acked_ and
+  // last_ack_frame_.
+  last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
+  last_ack_frame_.received_packet_times.clear();
+}
+
+void QuicSentPacketManager::MaybeInvokeCongestionEvent(
+    bool rtt_updated,
+    QuicByteCount prior_in_flight,
+    QuicTime event_time) {
+  if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
+    return;
+  }
+  const bool overshooting_detected =
+      stats_->overshooting_detected_with_network_parameters_adjusted;
+  if (using_pacing_) {
+    pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
+                                     packets_acked_, packets_lost_);
+  } else {
+    send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
+                                       packets_acked_, packets_lost_);
+  }
+  if (debug_delegate_ != nullptr && !overshooting_detected &&
+      stats_->overshooting_detected_with_network_parameters_adjusted) {
+    debug_delegate_->OnOvershootingDetected();
+  }
+  packets_acked_.clear();
+  packets_lost_.clear();
+  if (network_change_visitor_ != nullptr) {
+    network_change_visitor_->OnCongestionChange();
+  }
+}
+
+void QuicSentPacketManager::MarkInitialPacketsForRetransmission() {
+  if (unacked_packets_.empty()) {
+    return;
+  }
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
+  for (; packet_number <= largest_sent_packet; ++packet_number) {
+    QuicTransmissionInfo* transmission_info =
+        unacked_packets_.GetMutableTransmissionInfo(packet_number);
+    if (transmission_info->encryption_level == ENCRYPTION_INITIAL) {
+      if (transmission_info->in_flight) {
+        unacked_packets_.RemoveFromInFlight(transmission_info);
+      }
+      if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        MarkForRetransmission(packet_number, ALL_INITIAL_RETRANSMISSION);
+      }
+    }
+  }
+}
+
+void QuicSentPacketManager::MarkZeroRttPacketsForRetransmission() {
+  if (unacked_packets_.empty()) {
+    return;
+  }
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
+  for (; packet_number <= largest_sent_packet; ++packet_number) {
+    QuicTransmissionInfo* transmission_info =
+        unacked_packets_.GetMutableTransmissionInfo(packet_number);
+    if (transmission_info->encryption_level == ENCRYPTION_ZERO_RTT) {
+      if (transmission_info->in_flight) {
+        // Remove 0-RTT packets and packets of the wrong version from flight,
+        // because neither can be processed by the peer.
+        unacked_packets_.RemoveFromInFlight(transmission_info);
+      }
+      if (unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION);
+      }
+    }
+  }
+}
+
+void QuicSentPacketManager::NeuterUnencryptedPackets() {
+  for (QuicPacketNumber packet_number :
+       unacked_packets_.NeuterUnencryptedPackets()) {
+    send_algorithm_->OnPacketNeutered(packet_number);
+  }
+  if (handshake_mode_disabled_) {
+    consecutive_pto_count_ = 0;
+    uber_loss_algorithm_.ResetLossDetection(INITIAL_DATA);
+  }
+}
+
+void QuicSentPacketManager::NeuterHandshakePackets() {
+  for (QuicPacketNumber packet_number :
+       unacked_packets_.NeuterHandshakePackets()) {
+    send_algorithm_->OnPacketNeutered(packet_number);
+  }
+  if (handshake_mode_disabled_) {
+    consecutive_pto_count_ = 0;
+    uber_loss_algorithm_.ResetLossDetection(HANDSHAKE_DATA);
+  }
+}
+
+bool QuicSentPacketManager::ShouldAddMaxAckDelay(
+    PacketNumberSpace space) const {
+  QUICHE_DCHECK(pto_enabled_);
+  if (supports_multiple_packet_number_spaces() && space != APPLICATION_DATA) {
+    // When the PTO is armed for Initial or Handshake packet number spaces,
+    // the max_ack_delay is 0.
+    return false;
+  }
+  if (always_include_max_ack_delay_for_pto_timeout_) {
+    return true;
+  }
+  if (!unacked_packets_
+           .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
+           .IsInitialized() ||
+      unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+          APPLICATION_DATA) <
+          FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation - 1) {
+    // Peer is doing TCP style acking. Expect an immediate ACK if more than 1
+    // packet are outstanding.
+    if (unacked_packets_.packets_in_flight() >=
+        kDefaultRetransmittablePacketsBeforeAck) {
+      return false;
+    }
+  } else if (unacked_packets_.packets_in_flight() >=
+             kMaxRetransmittablePacketsBeforeAck) {
+    // Peer is doing ack decimation. Expect an immediate ACK if >= 10
+    // packets are outstanding.
+    return false;
+  }
+  if (skip_packet_number_for_pto_ && consecutive_pto_count_ > 0) {
+    // An immediate ACK is expected when doing PTOS. Please note, this will miss
+    // cases when PTO fires and turns out to be spurious.
+    return false;
+  }
+  return true;
+}
+
+QuicTime QuicSentPacketManager::GetEarliestPacketSentTimeForPto(
+    PacketNumberSpace* packet_number_space) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  QuicTime earliest_sent_time = QuicTime::Zero();
+  for (int8_t i = 0; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+    const QuicTime sent_time = unacked_packets_.GetLastInFlightPacketSentTime(
+        static_cast<PacketNumberSpace>(i));
+    if (!handshake_finished_ && i == APPLICATION_DATA) {
+      // Do not arm PTO for application data until handshake gets confirmed.
+      continue;
+    }
+    if (!sent_time.IsInitialized() || (earliest_sent_time.IsInitialized() &&
+                                       earliest_sent_time <= sent_time)) {
+      continue;
+    }
+    earliest_sent_time = sent_time;
+    *packet_number_space = static_cast<PacketNumberSpace>(i);
+  }
+
+  return earliest_sent_time;
+}
+
+void QuicSentPacketManager::MarkForRetransmission(
+    QuicPacketNumber packet_number,
+    TransmissionType transmission_type) {
+  QuicTransmissionInfo* transmission_info =
+      unacked_packets_.GetMutableTransmissionInfo(packet_number);
+  // A previous RTO retransmission may cause connection close; packets without
+  // retransmittable frames can be marked for loss retransmissions.
+  QUIC_BUG_IF(quic_bug_12552_2, transmission_type != LOSS_RETRANSMISSION &&
+                                    transmission_type != RTO_RETRANSMISSION &&
+                                    !unacked_packets_.HasRetransmittableFrames(
+                                        *transmission_info))
+      << "packet number " << packet_number
+      << " transmission_type: " << transmission_type << " transmission_info "
+      << transmission_info->DebugString();
+  // Handshake packets should never be sent as probing retransmissions.
+  QUICHE_DCHECK(!transmission_info->has_crypto_handshake ||
+                transmission_type != PROBING_RETRANSMISSION);
+  if (ShouldForceRetransmission(transmission_type)) {
+    const bool retransmitted = unacked_packets_.RetransmitFrames(
+        QuicFrames(transmission_info->retransmittable_frames),
+        transmission_type);
+    if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
+      QUIC_RESTART_FLAG_COUNT(quic_set_packet_state_if_all_data_retransmitted);
+      if (!retransmitted) {
+        // Do not set packet state if the data is not fully retransmitted.
+        // This should only happen if packet payload size decreases which can be
+        // caused by:
+        // 1) connection tries to opportunistically retransmit data
+        // when sending a packet of a different packet number space, or
+        // 2) path MTU decreases, or
+        // 3) packet header size increases (e.g., packet number length
+        // increases).
+        QUIC_CODE_COUNT(quic_retransmit_frames_failed);
+        return;
+      }
+      QUIC_CODE_COUNT(quic_retransmit_frames_succeeded);
+    }
+  } else {
+    unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
+
+    if (!transmission_info->retransmittable_frames.empty()) {
+      if (transmission_type == LOSS_RETRANSMISSION) {
+        // Record the first packet sent after loss, which allows to wait 1
+        // more RTT before giving up on this lost packet.
+        transmission_info->first_sent_after_loss =
+            unacked_packets_.largest_sent_packet() + 1;
+      } else {
+        // Clear the recorded first packet sent after loss when version or
+        // encryption changes.
+        transmission_info->first_sent_after_loss.Clear();
+      }
+    }
+  }
+
+  // Get the latest transmission_info here as it can be invalidated after
+  // HandleRetransmission adding new sent packets into unacked_packets_.
+  transmission_info =
+      unacked_packets_.GetMutableTransmissionInfo(packet_number);
+
+  // Update packet state according to transmission type.
+  transmission_info->state =
+      QuicUtils::RetransmissionTypeToPacketState(transmission_type);
+}
+
+void QuicSentPacketManager::RecordOneSpuriousRetransmission(
+    const QuicTransmissionInfo& info) {
+  stats_->bytes_spuriously_retransmitted += info.bytes_sent;
+  ++stats_->packets_spuriously_retransmitted;
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type,
+                                                    info.bytes_sent);
+  }
+}
+
+void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
+                                              QuicTransmissionInfo* info,
+                                              QuicTime ack_receive_time,
+                                              QuicTime::Delta ack_delay_time,
+                                              QuicTime receive_timestamp) {
+  if (info->has_ack_frequency) {
+    for (const auto& frame : info->retransmittable_frames) {
+      if (frame.type == ACK_FREQUENCY_FRAME) {
+        OnAckFrequencyFrameAcked(*frame.ack_frequency_frame);
+      }
+    }
+  }
+  // Try to aggregate acked stream frames if acked packet is not a
+  // retransmission.
+  if (info->transmission_type == NOT_RETRANSMISSION) {
+    unacked_packets_.MaybeAggregateAckedStreamFrame(*info, ack_delay_time,
+                                                    receive_timestamp);
+  } else {
+    unacked_packets_.NotifyAggregatedStreamFrameAcked(ack_delay_time);
+    const bool new_data_acked = unacked_packets_.NotifyFramesAcked(
+        *info, ack_delay_time, receive_timestamp);
+    if (!new_data_acked && info->transmission_type != NOT_RETRANSMISSION) {
+      // Record as a spurious retransmission if this packet is a
+      // retransmission and no new data gets acked.
+      QUIC_DVLOG(1) << "Detect spurious retransmitted packet " << packet_number
+                    << " transmission type: " << info->transmission_type;
+      RecordOneSpuriousRetransmission(*info);
+    }
+  }
+  if (info->state == LOST) {
+    // Record as a spurious loss as a packet previously declared lost gets
+    // acked.
+    const PacketNumberSpace packet_number_space =
+        unacked_packets_.GetPacketNumberSpace(info->encryption_level);
+    const QuicPacketNumber previous_largest_acked =
+        supports_multiple_packet_number_spaces()
+            ? unacked_packets_.GetLargestAckedOfPacketNumberSpace(
+                  packet_number_space)
+            : unacked_packets_.largest_acked();
+    QUIC_DVLOG(1) << "Packet " << packet_number
+                  << " was detected lost spuriously, "
+                     "previous_largest_acked: "
+                  << previous_largest_acked;
+    loss_algorithm_->SpuriousLossDetected(unacked_packets_, rtt_stats_,
+                                          ack_receive_time, packet_number,
+                                          previous_largest_acked);
+    ++stats_->packet_spuriously_detected_lost;
+  }
+
+  if (network_change_visitor_ != nullptr &&
+      info->bytes_sent > largest_mtu_acked_) {
+    largest_mtu_acked_ = info->bytes_sent;
+    network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_);
+  }
+  unacked_packets_.RemoveFromInFlight(info);
+  unacked_packets_.RemoveRetransmittability(info);
+  info->state = ACKED;
+}
+
+bool QuicSentPacketManager::CanSendAckFrequency() const {
+  return !peer_min_ack_delay_.IsInfinite() && handshake_finished_;
+}
+
+QuicAckFrequencyFrame QuicSentPacketManager::GetUpdatedAckFrequencyFrame()
+    const {
+  QuicAckFrequencyFrame frame;
+  if (!CanSendAckFrequency()) {
+    QUIC_BUG(quic_bug_10750_1)
+        << "New AckFrequencyFrame is created while it shouldn't.";
+    return frame;
+  }
+
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_can_send_ack_frequency, 1, 3);
+  frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck;
+  auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt()
+                                            : rtt_stats_.MinOrInitialRtt();
+  frame.max_ack_delay = rtt * kAckDecimationDelay;
+  frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
+  // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to
+  // 5 ms on the client side.
+  frame.max_ack_delay =
+      std::max(frame.max_ack_delay,
+               QuicTime::Delta::FromMilliseconds(kDefaultMinAckDelayTimeMs));
+  return frame;
+}
+
+bool QuicSentPacketManager::OnPacketSent(
+    SerializedPacket* mutable_packet,
+    QuicTime sent_time,
+    TransmissionType transmission_type,
+    HasRetransmittableData has_retransmittable_data,
+    bool measure_rtt) {
+  const SerializedPacket& packet = *mutable_packet;
+  QuicPacketNumber packet_number = packet.packet_number;
+  QUICHE_DCHECK_LE(FirstSendingPacketNumber(), packet_number);
+  QUICHE_DCHECK(!unacked_packets_.IsUnacked(packet_number));
+  QUIC_BUG_IF(quic_bug_10750_2, packet.encrypted_length == 0)
+      << "Cannot send empty packets.";
+  if (pending_timer_transmission_count_ > 0) {
+    --pending_timer_transmission_count_;
+  }
+
+  bool in_flight = has_retransmittable_data == HAS_RETRANSMITTABLE_DATA;
+  if (ignore_pings_ && mutable_packet->retransmittable_frames.size() == 1 &&
+      mutable_packet->retransmittable_frames[0].type == PING_FRAME) {
+    // Dot not use PING only packet for RTT measure or congestion control.
+    in_flight = false;
+    measure_rtt = false;
+  }
+  if (using_pacing_) {
+    pacing_sender_.OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
+                                packet_number, packet.encrypted_length,
+                                has_retransmittable_data);
+  } else {
+    send_algorithm_->OnPacketSent(sent_time, unacked_packets_.bytes_in_flight(),
+                                  packet_number, packet.encrypted_length,
+                                  has_retransmittable_data);
+  }
+
+  // Deallocate message data in QuicMessageFrame immediately after packet
+  // sent.
+  if (packet.has_message) {
+    for (auto& frame : mutable_packet->retransmittable_frames) {
+      if (frame.type == MESSAGE_FRAME) {
+        frame.message_frame->message_data.clear();
+        frame.message_frame->message_length = 0;
+      }
+    }
+  }
+
+  if (packet.has_ack_frequency) {
+    for (const auto& frame : packet.retransmittable_frames) {
+      if (frame.type == ACK_FREQUENCY_FRAME) {
+        OnAckFrequencyFrameSent(*frame.ack_frequency_frame);
+      }
+    }
+  }
+  unacked_packets_.AddSentPacket(mutable_packet, transmission_type, sent_time,
+                                 in_flight, measure_rtt);
+  // Reset the retransmission timer anytime a pending packet is sent.
+  return in_flight;
+}
+
+QuicSentPacketManager::RetransmissionTimeoutMode
+QuicSentPacketManager::OnRetransmissionTimeout() {
+  QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
+                (handshake_mode_disabled_ && !handshake_finished_));
+  QUICHE_DCHECK_EQ(0u, pending_timer_transmission_count_);
+  // Handshake retransmission, timer based loss detection, TLP, and RTO are
+  // implemented with a single alarm. The handshake alarm is set when the
+  // handshake has not completed, the loss alarm is set when the loss detection
+  // algorithm says to, and the TLP and  RTO alarms are set after that.
+  // The TLP alarm is always set to run for under an RTO.
+  switch (GetRetransmissionMode()) {
+    case HANDSHAKE_MODE:
+      QUICHE_DCHECK(!handshake_mode_disabled_);
+      ++stats_->crypto_retransmit_count;
+      RetransmitCryptoPackets();
+      return HANDSHAKE_MODE;
+    case LOSS_MODE: {
+      ++stats_->loss_timeout_count;
+      QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
+      const QuicTime now = clock_->Now();
+      InvokeLossDetection(now);
+      MaybeInvokeCongestionEvent(false, prior_in_flight, now);
+      return LOSS_MODE;
+    }
+    case TLP_MODE:
+      ++stats_->tlp_count;
+      ++consecutive_tlp_count_;
+      pending_timer_transmission_count_ = 1;
+      // TLPs prefer sending new data instead of retransmitting data, so
+      // give the connection a chance to write before completing the TLP.
+      return TLP_MODE;
+    case RTO_MODE:
+      ++stats_->rto_count;
+      RetransmitRtoPackets();
+      return RTO_MODE;
+    case PTO_MODE:
+      QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
+      ++stats_->pto_count;
+      if (handshake_mode_disabled_ && !handshake_finished_) {
+        ++stats_->crypto_retransmit_count;
+      }
+      ++consecutive_pto_count_;
+      pending_timer_transmission_count_ = max_probe_packets_per_pto_;
+      return PTO_MODE;
+  }
+  QUIC_BUG(quic_bug_10750_3)
+      << "Unknown retransmission mode " << GetRetransmissionMode();
+  return GetRetransmissionMode();
+}
+
+void QuicSentPacketManager::RetransmitCryptoPackets() {
+  QUICHE_DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
+  ++consecutive_crypto_retransmission_count_;
+  bool packet_retransmitted = false;
+  std::vector<QuicPacketNumber> crypto_retransmissions;
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      // Only retransmit frames which are in flight, and therefore have been
+      // sent.
+      if (!transmission_info->in_flight ||
+          transmission_info->state != OUTSTANDING ||
+          !transmission_info->has_crypto_handshake ||
+          !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        continue;
+      }
+      packet_retransmitted = true;
+      crypto_retransmissions.push_back(packet_number);
+      ++pending_timer_transmission_count_;
+    }
+  }
+  QUICHE_DCHECK(packet_retransmitted)
+      << "No crypto packets found to retransmit.";
+  for (QuicPacketNumber retransmission : crypto_retransmissions) {
+    MarkForRetransmission(retransmission, HANDSHAKE_RETRANSMISSION);
+  }
+}
+
+bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
+  QUICHE_DCHECK(!pto_enabled_);
+  if (pending_timer_transmission_count_ == 0) {
+    return false;
+  }
+  if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
+    return false;
+  }
+  return true;
+}
+
+bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      // Only retransmit frames which are in flight, and therefore have been
+      // sent.
+      if (!transmission_info->in_flight ||
+          transmission_info->state != OUTSTANDING ||
+          !unacked_packets_.HasRetransmittableFrames(*transmission_info)) {
+        continue;
+      }
+      MarkForRetransmission(packet_number, type);
+      return true;
+    }
+  }
+  QUIC_DVLOG(1)
+      << "No retransmittable packets, so RetransmitOldestPacket failed.";
+  return false;
+}
+
+void QuicSentPacketManager::RetransmitRtoPackets() {
+  QUICHE_DCHECK(!pto_enabled_);
+  QUIC_BUG_IF(quic_bug_12552_3, pending_timer_transmission_count_ > 0)
+      << "Retransmissions already queued:" << pending_timer_transmission_count_;
+  // Mark two packets for retransmission.
+  std::vector<QuicPacketNumber> retransmissions;
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      if (transmission_info->state == OUTSTANDING &&
+          unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
+          pending_timer_transmission_count_ < max_rto_packets_) {
+        QUICHE_DCHECK(transmission_info->in_flight);
+        retransmissions.push_back(packet_number);
+        ++pending_timer_transmission_count_;
+      }
+    }
+  }
+  if (pending_timer_transmission_count_ > 0) {
+    if (consecutive_rto_count_ == 0) {
+      first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
+    }
+    ++consecutive_rto_count_;
+  }
+  for (QuicPacketNumber retransmission : retransmissions) {
+    MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
+  }
+  if (retransmissions.empty()) {
+    QUIC_BUG_IF(quic_bug_12552_4, pending_timer_transmission_count_ != 0);
+    // No packets to be RTO retransmitted, raise up a credit to allow
+    // connection to send.
+    QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
+    pending_timer_transmission_count_ = 1;
+  }
+}
+
+void QuicSentPacketManager::MaybeSendProbePackets() {
+  if (pending_timer_transmission_count_ == 0) {
+    return;
+  }
+  PacketNumberSpace packet_number_space;
+  if (supports_multiple_packet_number_spaces()) {
+    // Find out the packet number space to send probe packets.
+    if (!GetEarliestPacketSentTimeForPto(&packet_number_space)
+             .IsInitialized()) {
+      QUIC_BUG_IF(quic_earliest_sent_time_not_initialized,
+                  unacked_packets_.perspective() == Perspective::IS_SERVER)
+          << "earliest_sent_time not initialized when trying to send PTO "
+             "retransmissions";
+      return;
+    }
+  }
+  std::vector<QuicPacketNumber> probing_packets;
+  if (!unacked_packets_.empty()) {
+    QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+    QuicPacketNumber largest_sent_packet =
+        unacked_packets_.largest_sent_packet();
+    for (; packet_number <= largest_sent_packet; ++packet_number) {
+      QuicTransmissionInfo* transmission_info =
+          unacked_packets_.GetMutableTransmissionInfo(packet_number);
+      if (transmission_info->state == OUTSTANDING &&
+          unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
+          (!supports_multiple_packet_number_spaces() ||
+           unacked_packets_.GetPacketNumberSpace(
+               transmission_info->encryption_level) == packet_number_space)) {
+        QUICHE_DCHECK(transmission_info->in_flight);
+        probing_packets.push_back(packet_number);
+        if (probing_packets.size() == pending_timer_transmission_count_) {
+          break;
+        }
+      }
+    }
+  }
+
+  for (QuicPacketNumber retransmission : probing_packets) {
+    QUIC_DVLOG(1) << ENDPOINT << "Marking " << retransmission
+                  << " for probing retransmission";
+    MarkForRetransmission(retransmission, PTO_RETRANSMISSION);
+  }
+  // It is possible that there is not enough outstanding data for probing.
+}
+
+void QuicSentPacketManager::AdjustPendingTimerTransmissions() {
+  if (pending_timer_transmission_count_ < max_probe_packets_per_pto_) {
+    // There are packets sent already, clear credit.
+    pending_timer_transmission_count_ = 0;
+    return;
+  }
+  // No packet gets sent, leave 1 credit to allow data to be write eventually.
+  pending_timer_transmission_count_ = 1;
+}
+
+void QuicSentPacketManager::EnableIetfPtoAndLossDetection() {
+  if (pto_enabled_) {
+    QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 2, 2);
+    // Disable handshake mode.
+    handshake_mode_disabled_ = true;
+    return;
+  }
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    QUIC_BUG(pto_not_enabled)
+        << "PTO is not enabled while quic_default_on_pto2 is true";
+    return;
+  }
+  pto_enabled_ = true;
+  handshake_mode_disabled_ = true;
+  // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
+  // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
+  // last in flight packet.
+  max_probe_packets_per_pto_ = 1;
+  skip_packet_number_for_pto_ = true;
+  first_pto_srtt_multiplier_ = 1.5;
+  pto_rttvar_multiplier_ = 2;
+}
+
+void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(
+    size_t exponential_backoff_start_point) {
+  pto_exponential_backoff_start_point_ = exponential_backoff_start_point;
+}
+
+void QuicSentPacketManager::RetransmitDataOfSpaceIfAny(
+    PacketNumberSpace space) {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  if (!unacked_packets_.GetLastInFlightPacketSentTime(space).IsInitialized()) {
+    // No in flight data of space.
+    return;
+  }
+  if (unacked_packets_.empty()) {
+    return;
+  }
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  QuicPacketNumber largest_sent_packet = unacked_packets_.largest_sent_packet();
+  for (; packet_number <= largest_sent_packet; ++packet_number) {
+    QuicTransmissionInfo* transmission_info =
+        unacked_packets_.GetMutableTransmissionInfo(packet_number);
+    if (transmission_info->state == OUTSTANDING &&
+        unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
+        unacked_packets_.GetPacketNumberSpace(
+            transmission_info->encryption_level) == space) {
+      QUICHE_DCHECK(transmission_info->in_flight);
+      if (pending_timer_transmission_count_ == 0) {
+        pending_timer_transmission_count_ = 1;
+      }
+      MarkForRetransmission(packet_number, PTO_RETRANSMISSION);
+      return;
+    }
+  }
+}
+
+QuicSentPacketManager::RetransmissionTimeoutMode
+QuicSentPacketManager::GetRetransmissionMode() const {
+  QUICHE_DCHECK(unacked_packets_.HasInFlightPackets() ||
+                (handshake_mode_disabled_ && !handshake_finished_));
+  if (!handshake_mode_disabled_ && !handshake_finished_ &&
+      unacked_packets_.HasPendingCryptoPackets()) {
+    return HANDSHAKE_MODE;
+  }
+  if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
+    return LOSS_MODE;
+  }
+  if (pto_enabled_) {
+    return PTO_MODE;
+  }
+  if (consecutive_tlp_count_ < max_tail_loss_probes_) {
+    if (unacked_packets_.HasUnackedRetransmittableFrames()) {
+      return TLP_MODE;
+    }
+  }
+  return RTO_MODE;
+}
+
+void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
+  if (!packets_acked_.empty()) {
+    QUICHE_DCHECK_LE(packets_acked_.front().packet_number,
+                     packets_acked_.back().packet_number);
+    largest_newly_acked_ = packets_acked_.back().packet_number;
+  }
+  LossDetectionInterface::DetectionStats detection_stats =
+      loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_,
+                                    largest_newly_acked_, packets_acked_,
+                                    &packets_lost_);
+
+  if (detection_stats.sent_packets_max_sequence_reordering >
+      stats_->sent_packets_max_sequence_reordering) {
+    stats_->sent_packets_max_sequence_reordering =
+        detection_stats.sent_packets_max_sequence_reordering;
+  }
+
+  stats_->sent_packets_num_borderline_time_reorderings +=
+      detection_stats.sent_packets_num_borderline_time_reorderings;
+
+  stats_->total_loss_detection_response_time +=
+      detection_stats.total_loss_detection_response_time;
+
+  for (const LostPacket& packet : packets_lost_) {
+    QuicTransmissionInfo* info =
+        unacked_packets_.GetMutableTransmissionInfo(packet.packet_number);
+    ++stats_->packets_lost;
+    if (debug_delegate_ != nullptr) {
+      debug_delegate_->OnPacketLoss(packet.packet_number,
+                                    info->encryption_level, LOSS_RETRANSMISSION,
+                                    time);
+    }
+    unacked_packets_.RemoveFromInFlight(info);
+
+    MarkForRetransmission(packet.packet_number, LOSS_RETRANSMISSION);
+  }
+}
+
+bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
+                                           QuicTime::Delta ack_delay_time,
+                                           QuicTime ack_receive_time) {
+  // We rely on ack_delay_time to compute an RTT estimate, so we
+  // only update rtt when the largest observed gets acked and the acked packet
+  // is not useless.
+  if (!unacked_packets_.IsUnacked(largest_acked)) {
+    return false;
+  }
+  // We calculate the RTT based on the highest ACKed packet number, the lower
+  // packet numbers will include the ACK aggregation delay.
+  const QuicTransmissionInfo& transmission_info =
+      unacked_packets_.GetTransmissionInfo(largest_acked);
+  // Ensure the packet has a valid sent time.
+  if (transmission_info.sent_time == QuicTime::Zero()) {
+    QUIC_BUG(quic_bug_10750_4)
+        << "Acked packet has zero sent time, largest_acked:" << largest_acked;
+    return false;
+  }
+  if (transmission_info.state == NOT_CONTRIBUTING_RTT) {
+    return false;
+  }
+  if (transmission_info.sent_time > ack_receive_time) {
+    QUIC_CODE_COUNT(quic_receive_acked_before_sending);
+  }
+
+  QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
+  const bool min_rtt_available = !rtt_stats_.min_rtt().IsZero();
+  rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
+
+  if (!min_rtt_available && !rtt_stats_.min_rtt().IsZero()) {
+    loss_algorithm_->OnMinRttAvailable();
+  }
+
+  return true;
+}
+
+QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now) const {
+  // The TLP logic is entirely contained within QuicSentPacketManager, so the
+  // send algorithm does not need to be consulted.
+  if (pending_timer_transmission_count_ > 0) {
+    return QuicTime::Delta::Zero();
+  }
+
+  if (using_pacing_) {
+    return pacing_sender_.TimeUntilSend(now,
+                                        unacked_packets_.bytes_in_flight());
+  }
+
+  return send_algorithm_->CanSend(unacked_packets_.bytes_in_flight())
+             ? QuicTime::Delta::Zero()
+             : QuicTime::Delta::Infinite();
+}
+
+const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
+  if (!unacked_packets_.HasInFlightPackets() &&
+      PeerCompletedAddressValidation()) {
+    return QuicTime::Zero();
+  }
+  if (pending_timer_transmission_count_ > 0) {
+    // Do not set the timer if there is any credit left.
+    return QuicTime::Zero();
+  }
+  PacketNumberSpace packet_number_space;
+  if (!simplify_set_retransmission_alarm_ &&
+      supports_multiple_packet_number_spaces() &&
+      unacked_packets_.perspective() == Perspective::IS_SERVER &&
+      !GetEarliestPacketSentTimeForPto(&packet_number_space).IsInitialized()) {
+    // Do not set the timer on the server side if the only in flight packets are
+    // half RTT data.
+    return QuicTime::Zero();
+  }
+  switch (GetRetransmissionMode()) {
+    case HANDSHAKE_MODE:
+      return unacked_packets_.GetLastCryptoPacketSentTime() +
+             GetCryptoRetransmissionDelay();
+    case LOSS_MODE:
+      return loss_algorithm_->GetLossTimeout();
+    case TLP_MODE: {
+      QUICHE_DCHECK(!pto_enabled_);
+      // TODO(ianswett): When CWND is available, it would be preferable to
+      // set the timer based on the earliest retransmittable packet.
+      // Base the updated timer on the send time of the last packet.
+      const QuicTime sent_time =
+          unacked_packets_.GetLastInFlightPacketSentTime();
+      const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
+      // Ensure the TLP timer never gets set to a time in the past.
+      return std::max(clock_->ApproximateNow(), tlp_time);
+    }
+    case RTO_MODE: {
+      QUICHE_DCHECK(!pto_enabled_);
+      // The RTO is based on the first outstanding packet.
+      const QuicTime sent_time =
+          unacked_packets_.GetLastInFlightPacketSentTime();
+      QuicTime rto_time = sent_time + GetRetransmissionDelay();
+      // Wait for TLP packets to be acked before an RTO fires.
+      QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
+      return std::max(tlp_time, rto_time);
+    }
+    case PTO_MODE: {
+      if (!supports_multiple_packet_number_spaces()) {
+        if (first_pto_srtt_multiplier_ > 0 &&
+            unacked_packets_.HasInFlightPackets() &&
+            consecutive_pto_count_ == 0) {
+          // Arm 1st PTO with earliest in flight sent time, and make sure at
+          // least first_pto_srtt_multiplier_ * RTT has been passed since last
+          // in flight packet.
+          return std::max(
+              clock_->ApproximateNow(),
+              std::max(unacked_packets_.GetFirstInFlightTransmissionInfo()
+                               ->sent_time +
+                           GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES),
+                       unacked_packets_.GetLastInFlightPacketSentTime() +
+                           first_pto_srtt_multiplier_ *
+                               rtt_stats_.SmoothedOrInitialRtt()));
+        }
+        // Ensure PTO never gets set to a time in the past.
+        return std::max(clock_->ApproximateNow(),
+                        unacked_packets_.GetLastInFlightPacketSentTime() +
+                            GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES));
+      }
+
+      PacketNumberSpace packet_number_space = NUM_PACKET_NUMBER_SPACES;
+      // earliest_right_edge is the earliest sent time of the last in flight
+      // packet of all packet number spaces.
+      QuicTime earliest_right_edge =
+          GetEarliestPacketSentTimeForPto(&packet_number_space);
+      if (!earliest_right_edge.IsInitialized()) {
+        // Arm PTO from now if there is no in flight packets.
+        earliest_right_edge = clock_->ApproximateNow();
+      }
+      if (first_pto_srtt_multiplier_ > 0 &&
+          packet_number_space == APPLICATION_DATA &&
+          consecutive_pto_count_ == 0) {
+        const QuicTransmissionInfo* first_application_info =
+            unacked_packets_.GetFirstInFlightTransmissionInfoOfSpace(
+                APPLICATION_DATA);
+        if (first_application_info != nullptr) {
+          // Arm 1st PTO with earliest in flight sent time, and make sure at
+          // least first_pto_srtt_multiplier_ * RTT has been passed since last
+          // in flight packet. Only do this for application data.
+          return std::max(
+              clock_->ApproximateNow(),
+              std::max(
+                  first_application_info->sent_time +
+                      GetProbeTimeoutDelay(packet_number_space),
+                  earliest_right_edge + first_pto_srtt_multiplier_ *
+                                            rtt_stats_.SmoothedOrInitialRtt()));
+        }
+      }
+      return std::max(
+          clock_->ApproximateNow(),
+          earliest_right_edge + GetProbeTimeoutDelay(packet_number_space));
+    }
+  }
+  QUICHE_DCHECK(false);
+  return QuicTime::Zero();
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
+  if (num_ptos_for_path_degrading_ > 0) {
+    return num_ptos_for_path_degrading_ * GetPtoDelay();
+  }
+  return GetNConsecutiveRetransmissionTimeoutDelay(
+      max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
+    int8_t num_rtos_for_blackhole_detection) const {
+  return GetNConsecutiveRetransmissionTimeoutDelay(
+      max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
+}
+
+QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
+    int8_t num_rtos_for_blackhole_detection) const {
+  return GetNetworkBlackholeDelay(num_rtos_for_blackhole_detection / 2);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
+    const {
+  // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
+  // because crypto handshake messages don't incur a delayed ack time.
+  QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+  int64_t delay_ms;
+  if (conservative_handshake_retransmits_) {
+    // Using the delayed ack time directly could cause conservative handshake
+    // retransmissions to actually be more aggressive than the default.
+    delay_ms = std::max(peer_max_ack_delay_.ToMilliseconds(),
+                        static_cast<int64_t>(2 * srtt.ToMilliseconds()));
+  } else {
+    delay_ms = std::max(kMinHandshakeTimeoutMs,
+                        static_cast<int64_t>(1.5 * srtt.ToMilliseconds()));
+  }
+  return QuicTime::Delta::FromMilliseconds(
+      delay_ms << consecutive_crypto_retransmission_count_);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
+  QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+  if (!unacked_packets_.HasMultipleInFlightPackets()) {
+    // This expression really should be using the delayed ack time, but in TCP
+    // MinRTO was traditionally set to 2x the delayed ack timer and this
+    // expression assumed QUIC did the same.
+    return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
+  }
+  return std::max(min_tlp_timeout_, 2 * srtt);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
+  QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
+  if (rtt_stats_.smoothed_rtt().IsZero()) {
+    // We are in the initial state, use default timeout values.
+    retransmission_delay =
+        QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
+  } else {
+    retransmission_delay =
+        rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
+    if (retransmission_delay < min_rto_timeout_) {
+      retransmission_delay = min_rto_timeout_;
+    }
+  }
+
+  // Calculate exponential back off.
+  retransmission_delay =
+      retransmission_delay *
+      (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
+
+  if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
+    return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
+  }
+  return retransmission_delay;
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay(
+    PacketNumberSpace space) const {
+  QUICHE_DCHECK(pto_enabled_);
+  if (rtt_stats_.smoothed_rtt().IsZero()) {
+    // Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack.
+    QUIC_BUG_IF(quic_bug_12552_6, rtt_stats_.initial_rtt().IsZero());
+    return std::max(
+               pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(),
+               QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
+           (1 << consecutive_pto_count_);
+  }
+  const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
+                                      ? rtt_stats_.GetStandardOrMeanDeviation()
+                                      : rtt_stats_.mean_deviation();
+  QuicTime::Delta pto_delay =
+      rtt_stats_.smoothed_rtt() +
+      std::max(pto_rttvar_multiplier_ * rtt_var, kAlarmGranularity) +
+      (ShouldAddMaxAckDelay(space) ? peer_max_ack_delay_
+                                   : QuicTime::Delta::Zero());
+  pto_delay =
+      pto_delay * (1 << (consecutive_pto_count_ -
+                         std::min(consecutive_pto_count_,
+                                  pto_exponential_backoff_start_point_)));
+  if (consecutive_pto_count_ < num_tlp_timeout_ptos_) {
+    // Make first n PTOs similar to TLPs.
+    if (pto_delay > 2 * rtt_stats_.smoothed_rtt()) {
+      QUIC_CODE_COUNT(quic_delayed_pto);
+      pto_delay = std::max(kAlarmGranularity, 2 * rtt_stats_.smoothed_rtt());
+    } else {
+      QUIC_CODE_COUNT(quic_faster_pto);
+    }
+  }
+  return pto_delay;
+}
+
+QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
+  if (send_algorithm_->GetCongestionControlType() == kBBR ||
+      send_algorithm_->GetCongestionControlType() == kBBRv2) {
+    return stats_->slowstart_duration.GetTotalElapsedTime(
+        clock_->ApproximateNow());
+  }
+  return QuicTime::Delta::Infinite();
+}
+
+QuicByteCount QuicSentPacketManager::GetAvailableCongestionWindowInBytes()
+    const {
+  QuicByteCount congestion_window = GetCongestionWindowInBytes();
+  QuicByteCount bytes_in_flight = GetBytesInFlight();
+  return congestion_window - std::min(congestion_window, bytes_in_flight);
+}
+
+std::string QuicSentPacketManager::GetDebugState() const {
+  return send_algorithm_->GetDebugState();
+}
+
+void QuicSentPacketManager::SetSendAlgorithm(
+    CongestionControlType congestion_control_type) {
+  if (send_algorithm_ &&
+      send_algorithm_->GetCongestionControlType() == congestion_control_type) {
+    return;
+  }
+
+  SetSendAlgorithm(SendAlgorithmInterface::Create(
+      clock_, &rtt_stats_, &unacked_packets_, congestion_control_type, random_,
+      stats_, initial_congestion_window_, send_algorithm_.get()));
+}
+
+void QuicSentPacketManager::SetSendAlgorithm(
+    SendAlgorithmInterface* send_algorithm) {
+  send_algorithm_.reset(send_algorithm);
+  pacing_sender_.set_sender(send_algorithm);
+}
+
+std::unique_ptr<SendAlgorithmInterface>
+QuicSentPacketManager::OnConnectionMigration(bool reset_send_algorithm) {
+  consecutive_rto_count_ = 0;
+  consecutive_tlp_count_ = 0;
+  consecutive_pto_count_ = 0;
+  rtt_stats_.OnConnectionMigration();
+  if (!reset_send_algorithm) {
+    send_algorithm_->OnConnectionMigration();
+    return nullptr;
+  }
+
+  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
+      std::move(send_algorithm_);
+  SetSendAlgorithm(old_send_algorithm->GetCongestionControlType());
+  // Treat all in flight packets sent to the old peer address as lost and
+  // retransmit them.
+  QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
+  for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
+       ++it, ++packet_number) {
+    if (it->in_flight) {
+      // Proactively retransmit any packet which is in flight on the old path.
+      // As a result, these packets will not contribute to congestion control.
+      unacked_packets_.RemoveFromInFlight(packet_number);
+      // Retransmitting these packets with PATH_CHANGE_RETRANSMISSION will mark
+      // them as useless, thus not contributing to RTT stats.
+      if (unacked_packets_.HasRetransmittableFrames(packet_number)) {
+        MarkForRetransmission(packet_number, PATH_RETRANSMISSION);
+        QUICHE_DCHECK_EQ(it->state, NOT_CONTRIBUTING_RTT);
+      }
+    }
+    it->state = NOT_CONTRIBUTING_RTT;
+  }
+  return old_send_algorithm;
+}
+
+void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
+                                            QuicTime::Delta ack_delay_time,
+                                            QuicTime ack_receive_time) {
+  QUICHE_DCHECK(packets_acked_.empty());
+  QUICHE_DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
+  // Ignore peer_max_ack_delay and use received ack_delay during
+  // handshake when supporting multiple packet number spaces.
+  if (!supports_multiple_packet_number_spaces() || handshake_finished_) {
+    if (ack_delay_time > peer_max_ack_delay()) {
+      ack_delay_time = peer_max_ack_delay();
+    }
+    if (ignore_ack_delay_) {
+      ack_delay_time = QuicTime::Delta::Zero();
+    }
+  }
+  rtt_updated_ =
+      MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
+  last_ack_frame_.ack_delay_time = ack_delay_time;
+  acked_packets_iter_ = last_ack_frame_.packets.rbegin();
+}
+
+void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
+                                       QuicPacketNumber end) {
+  if (!last_ack_frame_.largest_acked.IsInitialized() ||
+      end > last_ack_frame_.largest_acked + 1) {
+    // Largest acked increases.
+    unacked_packets_.IncreaseLargestAcked(end - 1);
+    last_ack_frame_.largest_acked = end - 1;
+  }
+  // Drop ack ranges which ack packets below least_unacked.
+  QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
+  if (least_unacked.IsInitialized() && end <= least_unacked) {
+    return;
+  }
+  start = std::max(start, least_unacked);
+  do {
+    QuicPacketNumber newly_acked_start = start;
+    if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
+      newly_acked_start = std::max(start, acked_packets_iter_->max());
+    }
+    for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
+         --acked) {
+      // Check if end is above the current range. If so add newly acked packets
+      // in descending order.
+      packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
+      if (acked == FirstSendingPacketNumber()) {
+        break;
+      }
+    }
+    if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
+        start > acked_packets_iter_->min()) {
+      // Finish adding all newly acked packets.
+      return;
+    }
+    end = std::min(end, acked_packets_iter_->min());
+    ++acked_packets_iter_;
+  } while (start < end);
+}
+
+void QuicSentPacketManager::OnAckTimestamp(QuicPacketNumber packet_number,
+                                           QuicTime timestamp) {
+  last_ack_frame_.received_packet_times.push_back({packet_number, timestamp});
+  for (AckedPacket& packet : packets_acked_) {
+    if (packet.packet_number == packet_number) {
+      packet.receive_timestamp = timestamp;
+      return;
+    }
+  }
+}
+
+AckResult QuicSentPacketManager::OnAckFrameEnd(
+    QuicTime ack_receive_time,
+    QuicPacketNumber ack_packet_number,
+    EncryptionLevel ack_decrypted_level) {
+  QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
+  // Reverse packets_acked_ so that it is in ascending order.
+  std::reverse(packets_acked_.begin(), packets_acked_.end());
+  for (AckedPacket& acked_packet : packets_acked_) {
+    QuicTransmissionInfo* info =
+        unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
+    if (!QuicUtils::IsAckable(info->state)) {
+      if (info->state == ACKED) {
+        QUIC_BUG(quic_bug_10750_5)
+            << "Trying to ack an already acked packet: "
+            << acked_packet.packet_number
+            << ", last_ack_frame_: " << last_ack_frame_
+            << ", least_unacked: " << unacked_packets_.GetLeastUnacked()
+            << ", packets_acked_: " << quiche::PrintElements(packets_acked_);
+      } else {
+        QUIC_PEER_BUG(quic_peer_bug_10750_6)
+            << "Received " << ack_decrypted_level
+            << " ack for unackable packet: " << acked_packet.packet_number
+            << " with state: "
+            << QuicUtils::SentPacketStateToString(info->state);
+        if (supports_multiple_packet_number_spaces()) {
+          if (info->state == NEVER_SENT) {
+            return UNSENT_PACKETS_ACKED;
+          }
+          return UNACKABLE_PACKETS_ACKED;
+        }
+      }
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Got an " << ack_decrypted_level
+                  << " ack for packet " << acked_packet.packet_number
+                  << " , state: "
+                  << QuicUtils::SentPacketStateToString(info->state);
+    const PacketNumberSpace packet_number_space =
+        unacked_packets_.GetPacketNumberSpace(info->encryption_level);
+    if (supports_multiple_packet_number_spaces() &&
+        QuicUtils::GetPacketNumberSpace(ack_decrypted_level) !=
+            packet_number_space) {
+      return PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE;
+    }
+    last_ack_frame_.packets.Add(acked_packet.packet_number);
+    if (info->encryption_level == ENCRYPTION_HANDSHAKE) {
+      handshake_packet_acked_ = true;
+    } else if (info->encryption_level == ENCRYPTION_ZERO_RTT) {
+      zero_rtt_packet_acked_ = true;
+    } else if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
+      one_rtt_packet_acked_ = true;
+    }
+    largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
+    if (supports_multiple_packet_number_spaces()) {
+      largest_packets_peer_knows_is_acked_[packet_number_space].UpdateMax(
+          info->largest_acked);
+    }
+    // If data is associated with the most recent transmission of this
+    // packet, then inform the caller.
+    if (info->in_flight) {
+      acked_packet.bytes_acked = info->bytes_sent;
+    } else {
+      // Unackable packets are skipped earlier.
+      largest_newly_acked_ = acked_packet.packet_number;
+    }
+    unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
+        packet_number_space, acked_packet.packet_number);
+    MarkPacketHandled(acked_packet.packet_number, info, ack_receive_time,
+                      last_ack_frame_.ack_delay_time,
+                      acked_packet.receive_timestamp);
+  }
+  const bool acked_new_packet = !packets_acked_.empty();
+  PostProcessNewlyAckedPackets(ack_packet_number, ack_decrypted_level,
+                               last_ack_frame_, ack_receive_time, rtt_updated_,
+                               prior_bytes_in_flight);
+
+  return acked_new_packet ? PACKETS_NEWLY_ACKED : NO_PACKETS_NEWLY_ACKED;
+}
+
+void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
+  debug_delegate_ = debug_delegate;
+}
+
+void QuicSentPacketManager::OnApplicationLimited() {
+  if (using_pacing_) {
+    pacing_sender_.OnApplicationLimited();
+  }
+  send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight());
+  if (debug_delegate_ != nullptr) {
+    debug_delegate_->OnApplicationLimited();
+  }
+}
+
+NextReleaseTimeResult QuicSentPacketManager::GetNextReleaseTime() const {
+  if (!using_pacing_) {
+    return {QuicTime::Zero(), false};
+  }
+
+  return pacing_sender_.GetNextReleaseTime();
+}
+
+void QuicSentPacketManager::SetInitialRtt(QuicTime::Delta rtt, bool trusted) {
+  const QuicTime::Delta min_rtt = QuicTime::Delta::FromMicroseconds(
+      trusted ? kMinTrustedInitialRoundTripTimeUs
+              : kMinUntrustedInitialRoundTripTimeUs);
+  QuicTime::Delta max_rtt =
+      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
+  rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt)));
+}
+
+void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() {
+  EnableIetfPtoAndLossDetection();
+  unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
+}
+
+QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket(
+    EncryptionLevel decrypted_packet_level) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  return unacked_packets_.GetLargestAckedOfPacketNumberSpace(
+      QuicUtils::GetPacketNumberSpace(decrypted_packet_level));
+}
+
+QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer(
+    EncryptionLevel encryption_level) const {
+  QuicPacketNumber largest_acked;
+  if (supports_multiple_packet_number_spaces()) {
+    largest_acked = GetLargestAckedPacket(encryption_level);
+  } else {
+    largest_acked = GetLargestObserved();
+  }
+  if (!largest_acked.IsInitialized()) {
+    // If no packets have been acked, return the first sent packet to ensure
+    // we use a large enough packet number length.
+    return FirstSendingPacketNumber();
+  }
+  QuicPacketNumber least_awaited = largest_acked + 1;
+  QuicPacketNumber least_unacked = GetLeastUnacked();
+  if (least_unacked.IsInitialized() && least_unacked < least_awaited) {
+    least_awaited = least_unacked;
+  }
+  return least_awaited;
+}
+
+QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked(
+    EncryptionLevel decrypted_packet_level) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces());
+  return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace(
+      decrypted_packet_level)];
+}
+
+QuicTime::Delta
+QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
+    int num_timeouts) const {
+  QuicTime::Delta total_delay = QuicTime::Delta::Zero();
+  const QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+  int num_tlps =
+      std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
+  num_timeouts -= num_tlps;
+  if (num_tlps > 0) {
+    const QuicTime::Delta tlp_delay =
+        std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
+                               ? min_tlp_timeout_
+                               : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
+    total_delay = total_delay + num_tlps * tlp_delay;
+  }
+  if (num_timeouts == 0) {
+    return total_delay;
+  }
+
+  const QuicTime::Delta retransmission_delay =
+      rtt_stats_.smoothed_rtt().IsZero()
+          ? QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs)
+          : std::max(srtt + 4 * rtt_stats_.mean_deviation(), min_rto_timeout_);
+  total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
+  return total_delay;
+}
+
+bool QuicSentPacketManager::PeerCompletedAddressValidation() const {
+  if (unacked_packets_.perspective() == Perspective::IS_SERVER ||
+      !handshake_mode_disabled_) {
+    return true;
+  }
+
+  // To avoid handshake deadlock due to anti-amplification limit, client needs
+  // to set PTO timer until server successfully processed any HANDSHAKE packet.
+  return handshake_finished_ || handshake_packet_acked_;
+}
+
+bool QuicSentPacketManager::IsLessThanThreePTOs(QuicTime::Delta timeout) const {
+  return timeout < 3 * GetPtoDelay();
+}
+
+QuicTime::Delta QuicSentPacketManager::GetPtoDelay() const {
+  return pto_enabled_ ? GetProbeTimeoutDelay(APPLICATION_DATA)
+                      : GetRetransmissionDelay();
+}
+
+void QuicSentPacketManager::OnAckFrequencyFrameSent(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  in_use_sent_ack_delays_.emplace_back(ack_frequency_frame.max_ack_delay,
+                                       ack_frequency_frame.sequence_number);
+  if (ack_frequency_frame.max_ack_delay > peer_max_ack_delay_) {
+    peer_max_ack_delay_ = ack_frequency_frame.max_ack_delay;
+  }
+}
+
+void QuicSentPacketManager::OnAckFrequencyFrameAcked(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  int stale_entry_count = 0;
+  for (auto it = in_use_sent_ack_delays_.cbegin();
+       it != in_use_sent_ack_delays_.cend(); ++it) {
+    if (it->second < ack_frequency_frame.sequence_number) {
+      ++stale_entry_count;
+    } else {
+      break;
+    }
+  }
+  if (stale_entry_count > 0) {
+    in_use_sent_ack_delays_.pop_front_n(stale_entry_count);
+  }
+  if (in_use_sent_ack_delays_.empty()) {
+    QUIC_BUG(quic_bug_10750_7) << "in_use_sent_ack_delays_ is empty.";
+    return;
+  }
+  peer_max_ack_delay_ = std::max_element(in_use_sent_ack_delays_.cbegin(),
+                                         in_use_sent_ack_delays_.cend())
+                            ->first;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sent_packet_manager.h b/quiche/quic/core/quic_sent_packet_manager.h
new file mode 100644
index 0000000..4be38bb
--- /dev/null
+++ b/quiche/quic/core/quic_sent_packet_manager.h
@@ -0,0 +1,784 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/core/congestion_control/pacing_sender.h"
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/congestion_control/uber_loss_algorithm.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicSentPacketManagerPeer;
+}  // namespace test
+
+class QuicClock;
+class QuicConfig;
+struct QuicConnectionStats;
+
+// Class which tracks the set of packets sent on a QUIC connection and contains
+// a send algorithm to decide when to send new packets.  It keeps track of any
+// retransmittable data associated with each packet. If a packet is
+// retransmitted, it will keep track of each version of a packet so that if a
+// previous transmission is acked, the data will not be retransmitted.
+class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
+ public:
+  // Interface which gets callbacks from the QuicSentPacketManager at
+  // interesting points.  Implementations must not mutate the state of
+  // the packet manager or connection as a result of these callbacks.
+  class QUIC_EXPORT_PRIVATE DebugDelegate {
+   public:
+    struct QUIC_EXPORT_PRIVATE SendParameters {
+      CongestionControlType congestion_control_type;
+      bool use_pacing;
+      QuicPacketCount initial_congestion_window;
+    };
+
+    virtual ~DebugDelegate() {}
+
+    // Called when a spurious retransmission is detected.
+    virtual void OnSpuriousPacketRetransmission(
+        TransmissionType /*transmission_type*/,
+        QuicByteCount /*byte_size*/) {}
+
+    virtual void OnIncomingAck(QuicPacketNumber /*ack_packet_number*/,
+                               EncryptionLevel /*ack_decrypted_level*/,
+                               const QuicAckFrame& /*ack_frame*/,
+                               QuicTime /*ack_receive_time*/,
+                               QuicPacketNumber /*largest_observed*/,
+                               bool /*rtt_updated*/,
+                               QuicPacketNumber /*least_unacked_sent_packet*/) {
+    }
+
+    virtual void OnPacketLoss(QuicPacketNumber /*lost_packet_number*/,
+                              EncryptionLevel /*encryption_level*/,
+                              TransmissionType /*transmission_type*/,
+                              QuicTime /*detection_time*/) {}
+
+    virtual void OnApplicationLimited() {}
+
+    virtual void OnAdjustNetworkParameters(QuicBandwidth /*bandwidth*/,
+                                           QuicTime::Delta /*rtt*/,
+                                           QuicByteCount /*old_cwnd*/,
+                                           QuicByteCount /*new_cwnd*/) {}
+
+    virtual void OnAdjustBurstSize(int /*old_burst_size*/,
+                                   int /*new_burst_size*/) {}
+
+    virtual void OnOvershootingDetected() {}
+
+    virtual void OnConfigProcessed(const SendParameters& /*parameters*/) {}
+  };
+
+  // Interface which gets callbacks from the QuicSentPacketManager when
+  // network-related state changes. Implementations must not mutate the
+  // state of the packet manager as a result of these callbacks.
+  class QUIC_EXPORT_PRIVATE NetworkChangeVisitor {
+   public:
+    virtual ~NetworkChangeVisitor() {}
+
+    // Called when congestion window or RTT may have changed.
+    virtual void OnCongestionChange() = 0;
+
+    // Called when the Path MTU may have increased.
+    virtual void OnPathMtuIncreased(QuicPacketLength packet_size) = 0;
+  };
+
+  // The retransmission timer is a single timer which switches modes depending
+  // upon connection state.
+  enum RetransmissionTimeoutMode {
+    // A conventional TCP style RTO.
+    RTO_MODE,
+    // A tail loss probe.  By default, QUIC sends up to two before RTOing.
+    TLP_MODE,
+    // Retransmission of handshake packets prior to handshake completion.
+    HANDSHAKE_MODE,
+    // Re-invoke the loss detection when a packet is not acked before the
+    // loss detection algorithm expects.
+    LOSS_MODE,
+    // A probe timeout. At least one probe packet must be sent when timer
+    // expires.
+    PTO_MODE,
+  };
+
+  QuicSentPacketManager(Perspective perspective,
+                        const QuicClock* clock,
+                        QuicRandom* random,
+                        QuicConnectionStats* stats,
+                        CongestionControlType congestion_control_type);
+  QuicSentPacketManager(const QuicSentPacketManager&) = delete;
+  QuicSentPacketManager& operator=(const QuicSentPacketManager&) = delete;
+  virtual ~QuicSentPacketManager();
+
+  virtual void SetFromConfig(const QuicConfig& config);
+
+  void ReserveUnackedPacketsInitialCapacity(int initial_capacity) {
+    unacked_packets_.ReserveInitialCapacity(initial_capacity);
+  }
+
+  void ApplyConnectionOptions(const QuicTagVector& connection_options);
+
+  // Pass the CachedNetworkParameters to the send algorithm.
+  void ResumeConnectionState(
+      const CachedNetworkParameters& cached_network_params,
+      bool max_bandwidth_resumption);
+
+  void SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
+    pacing_sender_.set_max_pacing_rate(max_pacing_rate);
+  }
+
+  QuicBandwidth MaxPacingRate() const {
+    return pacing_sender_.max_pacing_rate();
+  }
+
+  // Called to mark the handshake state complete, and all handshake packets are
+  // neutered.
+  // TODO(fayang): Rename this function to OnHandshakeComplete.
+  void SetHandshakeConfirmed();
+
+  // Requests retransmission of all unacked 0-RTT packets.
+  // Only 0-RTT encrypted packets will be retransmitted. This can happen,
+  // for example, when a CHLO has been rejected and the previously encrypted
+  // data needs to be encrypted with a new key.
+  void MarkZeroRttPacketsForRetransmission();
+
+  // Request retransmission of all unacked INITIAL packets.
+  void MarkInitialPacketsForRetransmission();
+
+  // Notify the sent packet manager of an external network measurement or
+  // prediction for either |bandwidth| or |rtt|; either can be empty.
+  void AdjustNetworkParameters(
+      const SendAlgorithmInterface::NetworkParams& params);
+
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner);
+  void OnConfigNegotiated();
+  void OnConnectionClosed();
+
+  // Retransmits the oldest pending packet there is still a tail loss probe
+  // pending.  Invoked after OnRetransmissionTimeout.
+  bool MaybeRetransmitTailLossProbe();
+
+  // Retransmits the oldest pending packet.
+  bool MaybeRetransmitOldestPacket(TransmissionType type);
+
+  // Removes the retransmittable frames from all unencrypted packets to ensure
+  // they don't get retransmitted.
+  void NeuterUnencryptedPackets();
+
+  // Returns true if there's outstanding crypto data.
+  bool HasUnackedCryptoPackets() const {
+    return unacked_packets_.HasPendingCryptoPackets();
+  }
+
+  // Returns true if there are packets in flight expecting to be acknowledged.
+  bool HasInFlightPackets() const {
+    return unacked_packets_.HasInFlightPackets();
+  }
+
+  // Returns the smallest packet number of a serialized packet which has not
+  // been acked by the peer.
+  QuicPacketNumber GetLeastUnacked() const {
+    return unacked_packets_.GetLeastUnacked();
+  }
+
+  // Called when we have sent bytes to the peer.  This informs the manager both
+  // the number of bytes sent and if they were retransmitted and if this packet
+  // is used for rtt measuring.  Returns true if the sender should reset the
+  // retransmission timer.
+  bool OnPacketSent(SerializedPacket* mutable_packet,
+                    QuicTime sent_time,
+                    TransmissionType transmission_type,
+                    HasRetransmittableData has_retransmittable_data,
+                    bool measure_rtt);
+
+  bool CanSendAckFrequency() const;
+
+  QuicAckFrequencyFrame GetUpdatedAckFrequencyFrame() const;
+
+  // Called when the retransmission timer expires and returns the retransmission
+  // mode.
+  RetransmissionTimeoutMode OnRetransmissionTimeout();
+
+  // Calculate the time until we can send the next packet to the wire.
+  // Note 1: When kUnknownWaitTime is returned, there is no need to poll
+  // TimeUntilSend again until we receive an OnIncomingAckFrame event.
+  // Note 2: Send algorithms may or may not use |retransmit| in their
+  // calculations.
+  QuicTime::Delta TimeUntilSend(QuicTime now) const;
+
+  // Returns the current delay for the retransmission timer, which may send
+  // either a tail loss probe or do a full RTO.  Returns QuicTime::Zero() if
+  // there are no retransmittable packets.
+  const QuicTime GetRetransmissionTime() const;
+
+  // Returns the current delay for the path degrading timer, which is used to
+  // notify the session that this connection is degrading.
+  const QuicTime::Delta GetPathDegradingDelay() const;
+
+  // Returns the current delay for detecting network blackhole.
+  const QuicTime::Delta GetNetworkBlackholeDelay(
+      int8_t num_rtos_for_blackhole_detection) const;
+
+  // Returns the delay before reducing max packet size. This delay is guranteed
+  // to be smaller than the network blackhole delay.
+  QuicTime::Delta GetMtuReductionDelay(
+      int8_t num_rtos_for_blackhole_detection) const;
+
+  const RttStats* GetRttStats() const { return &rtt_stats_; }
+
+  void SetRttStats(const RttStats& rtt_stats) {
+    rtt_stats_.CloneFrom(rtt_stats);
+  }
+
+  // Returns the estimated bandwidth calculated by the congestion algorithm.
+  QuicBandwidth BandwidthEstimate() const {
+    return send_algorithm_->BandwidthEstimate();
+  }
+
+  const QuicSustainedBandwidthRecorder* SustainedBandwidthRecorder() const {
+    return &sustained_bandwidth_recorder_;
+  }
+
+  // Returns the size of the current congestion window in number of
+  // kDefaultTCPMSS-sized segments. Note, this is not the *available* window.
+  // Some send algorithms may not use a congestion window and will return 0.
+  QuicPacketCount GetCongestionWindowInTcpMss() const {
+    return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS;
+  }
+
+  // Returns the number of packets of length |max_packet_length| which fit in
+  // the current congestion window. More packets may end up in flight if the
+  // congestion window has been recently reduced, of if non-full packets are
+  // sent.
+  QuicPacketCount EstimateMaxPacketsInFlight(
+      QuicByteCount max_packet_length) const {
+    return send_algorithm_->GetCongestionWindow() / max_packet_length;
+  }
+
+  // Returns the size of the current congestion window size in bytes.
+  QuicByteCount GetCongestionWindowInBytes() const {
+    return send_algorithm_->GetCongestionWindow();
+  }
+
+  // Returns the difference between current congestion window and bytes in
+  // flight. Returns 0 if bytes in flight is bigger than the current congestion
+  // window.
+  QuicByteCount GetAvailableCongestionWindowInBytes() const;
+
+  QuicBandwidth GetPacingRate() const {
+    return send_algorithm_->PacingRate(GetBytesInFlight());
+  }
+
+  // Returns the size of the slow start congestion window in nume of 1460 byte
+  // TCP segments, aka ssthresh.  Some send algorithms do not define a slow
+  // start threshold and will return 0.
+  QuicPacketCount GetSlowStartThresholdInTcpMss() const {
+    return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS;
+  }
+
+  // Return the total time spent in slow start so far. If the sender is
+  // currently in slow start, the return value will include the duration between
+  // the most recent entry to slow start and now.
+  //
+  // Only implemented for BBR. Return QuicTime::Delta::Infinite() for other
+  // congestion controllers.
+  QuicTime::Delta GetSlowStartDuration() const;
+
+  // Returns debugging information about the state of the congestion controller.
+  std::string GetDebugState() const;
+
+  // Returns the number of bytes that are considered in-flight, i.e. not lost or
+  // acknowledged.
+  QuicByteCount GetBytesInFlight() const {
+    return unacked_packets_.bytes_in_flight();
+  }
+
+  // Called when peer address changes. Must be called IFF the address change is
+  // not NAT rebinding. If reset_send_algorithm is true, switch to a new send
+  // algorithm object and retransmit all the in-flight packets. Return the send
+  // algorithm object used on the previous path.
+  std::unique_ptr<SendAlgorithmInterface> OnConnectionMigration(
+      bool reset_send_algorithm);
+
+  // Called when an ack frame is initially parsed.
+  void OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time,
+                       QuicTime ack_receive_time);
+
+  // Called when ack range [start, end) is received. Populates packets_acked_
+  // with newly acked packets.
+  void OnAckRange(QuicPacketNumber start, QuicPacketNumber end);
+
+  // Called when a timestamp is processed.  If it's present in packets_acked_,
+  // the timestamp field is set.  Otherwise, the timestamp is ignored.
+  void OnAckTimestamp(QuicPacketNumber packet_number, QuicTime timestamp);
+
+  // Called when an ack frame is parsed completely.
+  AckResult OnAckFrameEnd(QuicTime ack_receive_time,
+                          QuicPacketNumber ack_packet_number,
+                          EncryptionLevel ack_decrypted_level);
+
+  void EnableMultiplePacketNumberSpacesSupport();
+
+  void SetDebugDelegate(DebugDelegate* debug_delegate);
+
+  void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity) {
+    pacing_sender_.set_alarm_granularity(alarm_granularity);
+  }
+
+  QuicPacketNumber GetLargestObserved() const {
+    return unacked_packets_.largest_acked();
+  }
+
+  QuicPacketNumber GetLargestAckedPacket(
+      EncryptionLevel decrypted_packet_level) const;
+
+  QuicPacketNumber GetLargestSentPacket() const {
+    return unacked_packets_.largest_sent_packet();
+  }
+
+  // Returns the lowest of the largest acknowledged packet and the least
+  // unacked packet. This is designed to be used when computing the packet
+  // number length to send.
+  QuicPacketNumber GetLeastPacketAwaitedByPeer(
+      EncryptionLevel encryption_level) const;
+
+  QuicPacketNumber GetLargestPacketPeerKnowsIsAcked(
+      EncryptionLevel decrypted_packet_level) const;
+
+  void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor) {
+    QUICHE_DCHECK(!network_change_visitor_);
+    QUICHE_DCHECK(visitor);
+    network_change_visitor_ = visitor;
+  }
+
+  bool InSlowStart() const { return send_algorithm_->InSlowStart(); }
+
+  size_t GetConsecutiveRtoCount() const { return consecutive_rto_count_; }
+
+  size_t GetConsecutiveTlpCount() const { return consecutive_tlp_count_; }
+
+  size_t GetConsecutivePtoCount() const { return consecutive_pto_count_; }
+
+  void OnApplicationLimited();
+
+  const SendAlgorithmInterface* GetSendAlgorithm() const {
+    return send_algorithm_.get();
+  }
+
+  void SetSessionNotifier(SessionNotifierInterface* session_notifier) {
+    unacked_packets_.SetSessionNotifier(session_notifier);
+  }
+
+  NextReleaseTimeResult GetNextReleaseTime() const;
+
+  QuicPacketCount initial_congestion_window() const {
+    return initial_congestion_window_;
+  }
+
+  QuicPacketNumber largest_packet_peer_knows_is_acked() const {
+    QUICHE_DCHECK(!supports_multiple_packet_number_spaces());
+    return largest_packet_peer_knows_is_acked_;
+  }
+
+  size_t pending_timer_transmission_count() const {
+    return pending_timer_transmission_count_;
+  }
+
+  QuicTime::Delta peer_max_ack_delay() const { return peer_max_ack_delay_; }
+
+  void set_peer_max_ack_delay(QuicTime::Delta peer_max_ack_delay) {
+    // The delayed ack time should never be more than one half the min RTO time.
+    QUICHE_DCHECK_LE(peer_max_ack_delay, (min_rto_timeout_ * 0.5));
+    peer_max_ack_delay_ = peer_max_ack_delay;
+  }
+
+  const QuicUnackedPacketMap& unacked_packets() const {
+    return unacked_packets_;
+  }
+
+  const UberLossAlgorithm* uber_loss_algorithm() const {
+    return &uber_loss_algorithm_;
+  }
+
+  // Sets the send algorithm to the given congestion control type and points the
+  // pacing sender at |send_algorithm_|. Can be called any number of times.
+  void SetSendAlgorithm(CongestionControlType congestion_control_type);
+
+  // Sets the send algorithm to |send_algorithm| and points the pacing sender at
+  // |send_algorithm_|. Takes ownership of |send_algorithm|. Can be called any
+  // number of times.
+  // Setting the send algorithm once the connection is underway is dangerous.
+  void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm);
+
+  // Sends up to max_probe_packets_per_pto_ probe packets.
+  void MaybeSendProbePackets();
+
+  // Called to adjust pending_timer_transmission_count_ accordingly.
+  void AdjustPendingTimerTransmissions();
+
+  // Called to disable HANDSHAKE_MODE, and only PTO and LOSS modes are used.
+  // Also enable IETF loss detection.
+  void EnableIetfPtoAndLossDetection();
+
+  // Called to set the start point of doing exponential backoff when calculating
+  // PTO timeout.
+  void StartExponentialBackoffAfterNthPto(
+      size_t exponential_backoff_start_point);
+
+  // Called to retransmit in flight packet of |space| if any.
+  void RetransmitDataOfSpaceIfAny(PacketNumberSpace space);
+
+  // Returns true if |timeout| is less than 3 * RTO/PTO delay.
+  bool IsLessThanThreePTOs(QuicTime::Delta timeout) const;
+
+  // Returns current PTO delay.
+  QuicTime::Delta GetPtoDelay() const;
+
+  bool supports_multiple_packet_number_spaces() const {
+    return unacked_packets_.supports_multiple_packet_number_spaces();
+  }
+
+  bool pto_enabled() const { return pto_enabled_; }
+
+  bool handshake_mode_disabled() const { return handshake_mode_disabled_; }
+
+  bool skip_packet_number_for_pto() const {
+    return skip_packet_number_for_pto_;
+  }
+
+  bool zero_rtt_packet_acked() const { return zero_rtt_packet_acked_; }
+
+  bool one_rtt_packet_acked() const { return one_rtt_packet_acked_; }
+
+  void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); }
+
+  // Gets the earliest in flight packet sent time to calculate PTO. Also
+  // updates |packet_number_space| if a PTO timer should be armed.
+  QuicTime GetEarliestPacketSentTimeForPto(
+      PacketNumberSpace* packet_number_space) const;
+
+  void set_num_ptos_for_path_degrading(int num_ptos_for_path_degrading) {
+    num_ptos_for_path_degrading_ = num_ptos_for_path_degrading;
+  }
+
+  // Sets the initial RTT of the connection. The inital RTT is clamped to
+  // - A maximum of kMaxInitialRoundTripTimeUs.
+  // - A minimum of kMinTrustedInitialRoundTripTimeUs if |trusted|, or
+  // kMinUntrustedInitialRoundTripTimeUs if not |trusted|.
+  void SetInitialRtt(QuicTime::Delta rtt, bool trusted);
+
+  bool use_lower_min_irtt() const { return use_lower_min_irtt_; }
+
+  bool simplify_set_retransmission_alarm() const {
+    return simplify_set_retransmission_alarm_;
+  }
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::QuicSentPacketManagerPeer;
+
+  // Returns the current retransmission mode.
+  RetransmissionTimeoutMode GetRetransmissionMode() const;
+
+  // Retransmits all crypto stream packets.
+  void RetransmitCryptoPackets();
+
+  // Retransmits two packets for an RTO and removes any non-retransmittable
+  // packets from flight.
+  void RetransmitRtoPackets();
+
+  // Returns the timeout for retransmitting crypto handshake packets.
+  const QuicTime::Delta GetCryptoRetransmissionDelay() const;
+
+  // Calls GetTailLossProbeDelay() with values from the current state of this
+  // packet manager as its params.
+  const QuicTime::Delta GetTailLossProbeDelay() const;
+
+  // Calls GetRetransmissionDelay() with values from the current state of this
+  // packet manager as its params.
+  const QuicTime::Delta GetRetransmissionDelay() const;
+
+  // Returns the probe timeout.
+  const QuicTime::Delta GetProbeTimeoutDelay(PacketNumberSpace space) const;
+
+  // Update the RTT if the ack is for the largest acked packet number.
+  // Returns true if the rtt was updated.
+  bool MaybeUpdateRTT(QuicPacketNumber largest_acked,
+                      QuicTime::Delta ack_delay_time,
+                      QuicTime ack_receive_time);
+
+  // Invokes the loss detection algorithm and loses and retransmits packets if
+  // necessary.
+  void InvokeLossDetection(QuicTime time);
+
+  // Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
+  // or pending losses.  Clears pending acks and pending losses afterwards.
+  // |prior_in_flight| is the number of bytes in flight before the losses or
+  // acks, |event_time| is normally the timestamp of the ack packet which caused
+  // the event, although it can be the time at which loss detection was
+  // triggered.
+  void MaybeInvokeCongestionEvent(bool rtt_updated,
+                                  QuicByteCount prior_in_flight,
+                                  QuicTime event_time);
+
+  // Removes the retransmittability and in flight properties from the packet at
+  // |info| due to receipt by the peer.
+  void MarkPacketHandled(QuicPacketNumber packet_number,
+                         QuicTransmissionInfo* info,
+                         QuicTime ack_receive_time,
+                         QuicTime::Delta ack_delay_time,
+                         QuicTime receive_timestamp);
+
+  // Request that |packet_number| be retransmitted after the other pending
+  // retransmissions.  Does not add it to the retransmissions if it's already
+  // a pending retransmission. Do not reuse iterator of the underlying
+  // unacked_packets_ after calling this function as it can be invalidated.
+  void MarkForRetransmission(QuicPacketNumber packet_number,
+                             TransmissionType transmission_type);
+
+  // Called after packets have been marked handled with last received ack frame.
+  void PostProcessNewlyAckedPackets(QuicPacketNumber ack_packet_number,
+                                    EncryptionLevel ack_decrypted_level,
+                                    const QuicAckFrame& ack_frame,
+                                    QuicTime ack_receive_time,
+                                    bool rtt_updated,
+                                    QuicByteCount prior_bytes_in_flight);
+
+  // Notify observers that packet with QuicTransmissionInfo |info| is a spurious
+  // retransmission. It is caller's responsibility to guarantee the packet with
+  // QuicTransmissionInfo |info| is a spurious retransmission before calling
+  // this function.
+  void RecordOneSpuriousRetransmission(const QuicTransmissionInfo& info);
+
+  // Called when handshake is confirmed to remove the retransmittable frames
+  // from all packets of HANDSHAKE_DATA packet number space to ensure they don't
+  // get retransmitted and will eventually be removed from unacked packets map.
+  void NeuterHandshakePackets();
+
+  // Indicates whether including peer_max_ack_delay_ when calculating PTO
+  // timeout.
+  bool ShouldAddMaxAckDelay(PacketNumberSpace space) const;
+
+  // A helper function to return total delay of |num_timeouts| retransmission
+  // timeout with TLP and RTO mode.
+  QuicTime::Delta GetNConsecutiveRetransmissionTimeoutDelay(
+      int num_timeouts) const;
+
+  // Returns true if peer has finished address validation, such that
+  // retransmission timer is not armed if there is no packets in flight.
+  bool PeerCompletedAddressValidation() const;
+
+  // Called when an AckFrequencyFrame is sent.
+  void OnAckFrequencyFrameSent(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Called when an AckFrequencyFrame is acked.
+  void OnAckFrequencyFrameAcked(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Newly serialized retransmittable packets are added to this map, which
+  // contains owning pointers to any contained frames.  If a packet is
+  // retransmitted, this map will contain entries for both the old and the new
+  // packet. The old packet's retransmittable frames entry will be nullptr,
+  // while the new packet's entry will contain the frames to retransmit.
+  // If the old packet is acked before the new packet, then the old entry will
+  // be removed from the map and the new entry's retransmittable frames will be
+  // set to nullptr.
+  QuicUnackedPacketMap unacked_packets_;
+
+  const QuicClock* clock_;
+  QuicRandom* random_;
+  QuicConnectionStats* stats_;
+
+  DebugDelegate* debug_delegate_;
+  NetworkChangeVisitor* network_change_visitor_;
+  QuicPacketCount initial_congestion_window_;
+  RttStats rtt_stats_;
+  std::unique_ptr<SendAlgorithmInterface> send_algorithm_;
+  // Not owned. Always points to |uber_loss_algorithm_| outside of tests.
+  LossDetectionInterface* loss_algorithm_;
+  UberLossAlgorithm uber_loss_algorithm_;
+
+  // Tracks the first RTO packet.  If any packet before that packet gets acked,
+  // it indicates the RTO was spurious and should be reversed(F-RTO).
+  QuicPacketNumber first_rto_transmission_;
+  // Number of times the RTO timer has fired in a row without receiving an ack.
+  size_t consecutive_rto_count_;
+  // Number of times the tail loss probe has been sent.
+  size_t consecutive_tlp_count_;
+  // Number of times the crypto handshake has been retransmitted.
+  size_t consecutive_crypto_retransmission_count_;
+  // Number of pending transmissions of TLP, RTO, or crypto packets.
+  size_t pending_timer_transmission_count_;
+  // Maximum number of tail loss probes to send before firing an RTO.
+  size_t max_tail_loss_probes_;
+  // Maximum number of packets to send upon RTO.
+  QuicPacketCount max_rto_packets_;
+  // If true, send the TLP at 0.5 RTT.
+  bool using_pacing_;
+  // If true, use the new RTO with loss based CWND reduction instead of the send
+  // algorithms's OnRetransmissionTimeout to reduce the congestion window.
+  bool use_new_rto_;
+  // If true, use a more conservative handshake retransmission policy.
+  bool conservative_handshake_retransmits_;
+  // The minimum TLP timeout.
+  QuicTime::Delta min_tlp_timeout_;
+  // The minimum RTO.
+  QuicTime::Delta min_rto_timeout_;
+
+  // Vectors packets acked and lost as a result of the last congestion event.
+  AckedPacketVector packets_acked_;
+  LostPacketVector packets_lost_;
+  // Largest newly acknowledged packet.
+  QuicPacketNumber largest_newly_acked_;
+  // Largest packet in bytes ever acknowledged.
+  QuicPacketLength largest_mtu_acked_;
+
+  // Replaces certain calls to |send_algorithm_| when |using_pacing_| is true.
+  // Calls into |send_algorithm_| for the underlying congestion control.
+  PacingSender pacing_sender_;
+
+  // Indicates whether handshake is finished. This is purely used to determine
+  // retransmission mode. DONOT use this to infer handshake state.
+  bool handshake_finished_;
+
+  // Records bandwidth from server to client in normal operation, over periods
+  // of time with no loss events.
+  QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
+
+  // The largest acked value that was sent in an ack, which has then been acked.
+  QuicPacketNumber largest_packet_peer_knows_is_acked_;
+  // The largest acked value that was sent in an ack, which has then been acked
+  // for per packet number space. Only used when connection supports multiple
+  // packet number spaces.
+  QuicPacketNumber
+      largest_packets_peer_knows_is_acked_[NUM_PACKET_NUMBER_SPACES];
+
+  // The maximum ACK delay time that the peer might uses. Initialized to be the
+  // same as local_max_ack_delay_, may be changed via transport parameter
+  // negotiation or subsequently by AckFrequencyFrame.
+  QuicTime::Delta peer_max_ack_delay_;
+
+  // Peer sends min_ack_delay in TransportParameter to advertise its support for
+  // AckFrequencyFrame.
+  QuicTime::Delta peer_min_ack_delay_ = QuicTime::Delta::Infinite();
+
+  // Use smoothed RTT for computing max_ack_delay in AckFrequency frame.
+  bool use_smoothed_rtt_in_ack_delay_ = false;
+
+  // The history of outstanding max_ack_delays sent to peer. Outstanding means
+  // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or
+  // an unacked AckFrequencyFrame after that.
+  quiche::QuicheCircularDeque<
+      std::pair<QuicTime::Delta, /*sequence_number=*/uint64_t>>
+      in_use_sent_ack_delays_;
+
+  // Latest received ack frame.
+  QuicAckFrame last_ack_frame_;
+
+  // Record whether RTT gets updated by last largest acked..
+  bool rtt_updated_;
+
+  // A reverse iterator of last_ack_frame_.packets. This is reset in
+  // OnAckRangeStart, and gradually moves in OnAckRange..
+  PacketNumberQueue::const_reverse_iterator acked_packets_iter_;
+
+  // Indicates whether PTO mode has been enabled. PTO mode unifies TLP and RTO
+  // modes.
+  bool pto_enabled_;
+
+  // Maximum number of probes to send when PTO fires.
+  size_t max_probe_packets_per_pto_;
+
+  // Number of times the PTO timer has fired in a row without receiving an ack.
+  size_t consecutive_pto_count_;
+
+  // True if HANDSHAKE mode has been disabled.
+  bool handshake_mode_disabled_;
+
+  // If true, skip packet number before sending the last PTO retransmission.
+  bool skip_packet_number_for_pto_;
+
+  // If true, always include peer_max_ack_delay_ when calculating PTO timeout.
+  bool always_include_max_ack_delay_for_pto_timeout_;
+
+  // When calculating PTO timeout, the start point of doing exponential backoff.
+  // For example, 0 : always do exponential backoff. n : do exponential backoff
+  // since nth PTO.
+  size_t pto_exponential_backoff_start_point_;
+
+  // The multiplier of rttvar when calculating PTO timeout.
+  int pto_rttvar_multiplier_;
+
+  // Number of PTOs similar to TLPs.
+  size_t num_tlp_timeout_ptos_;
+
+  // True if any ENCRYPTION_HANDSHAKE packet gets acknowledged.
+  bool handshake_packet_acked_;
+
+  // True if any 0-RTT packet gets acknowledged.
+  bool zero_rtt_packet_acked_;
+
+  // True if any 1-RTT packet gets acknowledged.
+  bool one_rtt_packet_acked_;
+
+  // If > 0, arm the 1st PTO with max of earliest in flight sent time + PTO
+  // delay and multiplier * srtt from last in flight packet.
+  float first_pto_srtt_multiplier_;
+
+  // If true, use standard deviation (instead of mean deviation) when
+  // calculating PTO timeout.
+  bool use_standard_deviation_for_pto_;
+
+  // The multiplier for caculating PTO timeout before any RTT sample is
+  // available.
+  float pto_multiplier_without_rtt_samples_;
+
+  // The number of PTOs needed for path degrading alarm. If equals to 0, the
+  // traditional path degrading mechanism will be used.
+  int num_ptos_for_path_degrading_;
+
+  // If true, do not use PING only packets for RTT measurement or congestion
+  // control.
+  bool ignore_pings_;
+
+  // Whether to ignore the ack_delay in received ACKs.
+  bool ignore_ack_delay_;
+
+  // Latched value of --quic_use_lower_min_for_trusted_irtt.
+  bool use_lower_min_irtt_ =
+      GetQuicReloadableFlag(quic_use_lower_min_for_trusted_irtt);
+
+  const bool simplify_set_retransmission_alarm_ =
+      GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
new file mode 100644
index 0000000..61e7f2a
--- /dev/null
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -0,0 +1,4744 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::IsEmpty;
+using testing::Not;
+using testing::Pointwise;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace quic {
+namespace test {
+namespace {
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+// Stream ID for data sent in CreatePacket().
+const QuicStreamId kStreamId = 7;
+
+// Matcher to check that the packet number matches the second argument.
+MATCHER(PacketNumberEq, "") {
+  return std::get<0>(arg).packet_number == QuicPacketNumber(std::get<1>(arg));
+}
+
+class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
+ public:
+  MOCK_METHOD(void, OnSpuriousPacketRetransmission,
+              (TransmissionType transmission_type, QuicByteCount byte_size),
+              (override));
+  MOCK_METHOD(void, OnPacketLoss,
+              (QuicPacketNumber lost_packet_number,
+               EncryptionLevel encryption_level,
+               TransmissionType transmission_type, QuicTime detection_time),
+              (override));
+};
+
+class QuicSentPacketManagerTest : public QuicTest {
+ public:
+  bool RetransmitCryptoPacket(uint64_t packet_number) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.retransmittable_frames.push_back(
+        QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
+    packet.has_crypto_handshake = IS_HANDSHAKE;
+    manager_.OnPacketSent(&packet, clock_.Now(), HANDSHAKE_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+    return true;
+  }
+
+  bool RetransmitDataPacket(uint64_t packet_number, TransmissionType type,
+                            EncryptionLevel level) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, true));
+    packet.encryption_level = level;
+    manager_.OnPacketSent(&packet, clock_.Now(), type, HAS_RETRANSMITTABLE_DATA,
+                          true);
+    return true;
+  }
+
+  bool RetransmitDataPacket(uint64_t packet_number, TransmissionType type) {
+    return RetransmitDataPacket(packet_number, type, ENCRYPTION_INITIAL);
+  }
+
+ protected:
+  const CongestionControlType kInitialCongestionControlType = kCubicBytes;
+  QuicSentPacketManagerTest()
+      : manager_(Perspective::IS_SERVER, &clock_, QuicRandom::GetInstance(),
+                 &stats_, kInitialCongestionControlType),
+        send_algorithm_(new StrictMock<MockSendAlgorithm>),
+        network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
+    QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
+    // Disable tail loss probes for most tests.
+    QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
+    // Advance the time 1s so the send times are never QuicTime::Zero.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+    manager_.SetNetworkChangeVisitor(network_change_visitor_.get());
+    manager_.SetSessionNotifier(&notifier_);
+
+    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
+        .WillRepeatedly(Return(kInitialCongestionControlType));
+    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, OnPacketNeutered(_)).Times(AnyNumber());
+    EXPECT_CALL(*network_change_visitor_, OnPathMtuIncreased(1000))
+        .Times(AnyNumber());
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_)).Times(AnyNumber());
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillRepeatedly(Return(true));
+  }
+
+  ~QuicSentPacketManagerTest() override {}
+
+  QuicByteCount BytesInFlight() { return manager_.GetBytesInFlight(); }
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
+    if (num_packets == 0) {
+      EXPECT_TRUE(manager_.unacked_packets().empty());
+      EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
+                        &manager_));
+      return;
+    }
+
+    EXPECT_FALSE(manager_.unacked_packets().empty());
+    EXPECT_EQ(QuicPacketNumber(packets[0]), manager_.GetLeastUnacked());
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(
+          manager_.unacked_packets().IsUnacked(QuicPacketNumber(packets[i])))
+          << packets[i];
+    }
+  }
+
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
+    EXPECT_EQ(
+        num_packets,
+        QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(QuicSentPacketManagerPeer::HasRetransmittableFrames(
+          &manager_, packets[i]))
+          << " packets[" << i << "]:" << packets[i];
+    }
+  }
+
+  void ExpectAck(uint64_t largest_observed) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        // Ensure the AckedPacketVector argument contains largest_observed.
+        OnCongestionEvent(true, _, _,
+                          Pointwise(PacketNumberEq(), {largest_observed}),
+                          IsEmpty()));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  void ExpectUpdatedRtt(uint64_t /*largest_observed*/) {
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty()));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  void ExpectAckAndLoss(bool rtt_updated, uint64_t largest_observed,
+                        uint64_t lost_packet) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnCongestionEvent(rtt_updated, _, _,
+                          Pointwise(PacketNumberEq(), {largest_observed}),
+                          Pointwise(PacketNumberEq(), {lost_packet})));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  // |packets_acked| and |packets_lost| should be in packet number order.
+  void ExpectAcksAndLosses(bool rtt_updated, uint64_t* packets_acked,
+                           size_t num_packets_acked, uint64_t* packets_lost,
+                           size_t num_packets_lost) {
+    std::vector<QuicPacketNumber> ack_vector;
+    for (size_t i = 0; i < num_packets_acked; ++i) {
+      ack_vector.push_back(QuicPacketNumber(packets_acked[i]));
+    }
+    std::vector<QuicPacketNumber> lost_vector;
+    for (size_t i = 0; i < num_packets_lost; ++i) {
+      lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
+    }
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(rtt_updated, _, _,
+                                  Pointwise(PacketNumberEq(), ack_vector),
+                                  Pointwise(PacketNumberEq(), lost_vector)));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+        .Times(AnyNumber());
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number) {
+    RetransmitAndSendPacket(old_packet_number, new_packet_number,
+                            TLP_RETRANSMISSION);
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number,
+                               TransmissionType transmission_type) {
+    bool is_lost = false;
+    if (transmission_type == HANDSHAKE_RETRANSMISSION ||
+        transmission_type == TLP_RETRANSMISSION ||
+        transmission_type == RTO_RETRANSMISSION ||
+        transmission_type == PROBING_RETRANSMISSION) {
+      EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+          .WillOnce(WithArgs<1>(
+              Invoke([this, new_packet_number](TransmissionType type) {
+                return RetransmitDataPacket(new_packet_number, type);
+              })));
+    } else {
+      EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+      is_lost = true;
+    }
+    QuicSentPacketManagerPeer::MarkForRetransmission(
+        &manager_, old_packet_number, transmission_type);
+    if (!is_lost) {
+      return;
+    }
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(new_packet_number, true));
+    manager_.OnPacketSent(&packet, clock_.Now(), transmission_type,
+                          HAS_RETRANSMITTABLE_DATA, true);
+  }
+
+  SerializedPacket CreateDataPacket(uint64_t packet_number) {
+    return CreatePacket(packet_number, true);
+  }
+
+  SerializedPacket CreatePacket(uint64_t packet_number, bool retransmittable) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    if (retransmittable) {
+      packet.retransmittable_frames.push_back(
+          QuicFrame(QuicStreamFrame(kStreamId, false, 0, absl::string_view())));
+    }
+    return packet;
+  }
+
+  SerializedPacket CreatePingPacket(uint64_t packet_number) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    packet.retransmittable_frames.push_back(QuicFrame(QuicPingFrame()));
+    return packet;
+  }
+
+  void SendDataPacket(uint64_t packet_number) {
+    SendDataPacket(packet_number, ENCRYPTION_INITIAL);
+  }
+
+  void SendDataPacket(uint64_t packet_number,
+                      EncryptionLevel encryption_level) {
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(),
+                             QuicPacketNumber(packet_number), _, _));
+    SerializedPacket packet(CreateDataPacket(packet_number));
+    packet.encryption_level = encryption_level;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+  }
+
+  void SendPingPacket(uint64_t packet_number,
+                      EncryptionLevel encryption_level) {
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(),
+                             QuicPacketNumber(packet_number), _, _));
+    SerializedPacket packet(CreatePingPacket(packet_number));
+    packet.encryption_level = encryption_level;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+  }
+
+  void SendCryptoPacket(uint64_t packet_number) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.retransmittable_frames.push_back(
+        QuicFrame(QuicStreamFrame(1, false, 0, absl::string_view())));
+    packet.has_crypto_handshake = IS_HANDSHAKE;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, true);
+    EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(true));
+  }
+
+  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked) {
+    SendAckPacket(packet_number, largest_acked, ENCRYPTION_INITIAL);
+  }
+
+  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked,
+                     EncryptionLevel level) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, NO_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.largest_acked = QuicPacketNumber(largest_acked);
+    packet.encryption_level = level;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          NO_RETRANSMITTABLE_DATA, true);
+  }
+
+  void EnablePto(QuicTag tag) {
+    QuicConfig config;
+    QuicTagVector options;
+    options.push_back(tag);
+    QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+    manager_.SetFromConfig(config);
+    EXPECT_TRUE(manager_.pto_enabled());
+  }
+
+  int GetPtoRttvarMultiplier() {
+    if (GetQuicRestartFlag(quic_default_on_pto2) ||
+        manager_.handshake_mode_disabled()) {
+      return 2;
+    }
+    return 4;
+  }
+
+  quiche::SimpleBufferAllocator allocator_;
+  QuicSentPacketManager manager_;
+  MockClock clock_;
+  QuicConnectionStats stats_;
+  MockSendAlgorithm* send_algorithm_;
+  std::unique_ptr<MockNetworkChangeVisitor> network_change_visitor_;
+  StrictMock<MockSessionNotifier> notifier_;
+};
+
+TEST_F(QuicSentPacketManagerTest, IsUnacked) {
+  VerifyUnackedPackets(nullptr, 0);
+  SendDataPacket(1);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+}
+
+TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable = {1, 2};
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Ack 2 but not 1.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // Packet 1 is unacked, pending, but not retransmittable.
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
+  SendDataPacket(1);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+                                                   TLP_RETRANSMISSION);
+  // Ack 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  // We do not know packet 2 is a spurious retransmission until it gets acked.
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
+  SendDataPacket(1);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).WillRepeatedly(Return(true));
+  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+                                                   TLP_RETRANSMISSION);
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // Ack 1 but not 2.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // 2 remains unacked, but no packets have retransmittable data.
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+  // Ack 2 causes 2 be considered as spurious retransmission.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // First, ACK packet 1 which makes packet 2 non-retransmittable.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  SendDataPacket(3);
+  SendDataPacket(4);
+  SendDataPacket(5);
+  clock_.AdvanceTime(rtt);
+
+  // Next, NACK packet 2 three times.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  ExpectAckAndLoss(true, 3, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_INITIAL));
+
+  ExpectAck(5);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Verify that the retransmission alarm would not fire,
+  // since there is no retransmittable data outstanding.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       DISABLED_RetransmitTwiceThenAckPreviousBeforeSend) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Fire the RTO, which will mark 2 for retransmission (but will not send it).
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+
+  // Ack 1 but not 2, before 2 is able to be sent.
+  // Since 1 has been retransmitted, it has already been lost, and so the
+  // send algorithm is not informed that it has been ACK'd.
+  ExpectUpdatedRtt(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Verify that the retransmission alarm would not fire,
+  // since there is no retransmittable data outstanding.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
+  StrictMock<MockDebugDelegate> debug_delegate;
+  EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(TLP_RETRANSMISSION,
+                                                             kDefaultLength))
+      .Times(1);
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  RetransmitAndSendPacket(2, 3);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // Ack 1 but not 2 or 3.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  // Frames in packets 2 and 3 are acked.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_))
+      .Times(2)
+      .WillRepeatedly(Return(false));
+
+  // 2 and 3 remain unacked, but no packets have retransmittable data.
+  uint64_t unacked[] = {2, 3};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Ensure packet 2 is lost when 4 is sent and 3 and 4 are acked.
+  SendDataPacket(4);
+  // No new data gets acked in packet 3.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
+      .WillOnce(Return(false))
+      .WillRepeatedly(Return(true));
+  uint64_t acked[] = {3, 4};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t unacked2[] = {2};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+
+  SendDataPacket(5);
+  ExpectAckAndLoss(true, 5, 2);
+  EXPECT_CALL(debug_delegate,
+              OnPacketLoss(QuicPacketNumber(2), _, LOSS_RETRANSMISSION, _));
+  // Frames in all packets are acked.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // Notify session that stream frame in packet 2 gets lost although it is
+  // not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t unacked3[] = {2};
+  VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  // Spurious retransmission is detected when packet 3 gets acked. We cannot
+  // know packet 2 is a spurious until it gets acked.
+  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
+  EXPECT_EQ(1u, stats_.packets_lost);
+  EXPECT_LT(0.0, stats_.total_loss_detection_response_time);
+  EXPECT_LE(1u, stats_.sent_packets_max_sequence_reordering);
+}
+
+TEST_F(QuicSentPacketManagerTest, AckOriginalTransmission) {
+  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Ack original transmission, but that wasn't lost via fast retransmit,
+  // so no call on OnSpuriousRetransmission is expected.
+  {
+    ExpectAck(1);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                     ENCRYPTION_INITIAL));
+  }
+
+  SendDataPacket(3);
+  SendDataPacket(4);
+  // Ack 4, which causes 3 to be retransmitted.
+  {
+    ExpectAck(4);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                     ENCRYPTION_INITIAL));
+    RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+  }
+
+  // Ack 3, which causes SpuriousRetransmitDetected to be called.
+  {
+    uint64_t acked[] = {3};
+    ExpectAcksAndLosses(false, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    EXPECT_CALL(*loss_algorithm,
+                SpuriousLossDetected(_, _, _, QuicPacketNumber(3),
+                                     QuicPacketNumber(4)));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(0u, stats_.packet_spuriously_detected_lost);
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                     ENCRYPTION_INITIAL));
+    EXPECT_EQ(1u, stats_.packet_spuriously_detected_lost);
+    // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
+    // 5 will cause 5 be considered as a spurious retransmission as no new
+    // data gets acked.
+    ExpectAck(5);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).WillOnce(Return(false));
+    manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_EQ(PACKETS_NEWLY_ACKED,
+              manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                     ENCRYPTION_INITIAL));
+  }
+}
+
+TEST_F(QuicSentPacketManagerTest, GetLeastUnacked) {
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
+  SendDataPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+}
+
+TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
+  EXPECT_FALSE(manager_.largest_packet_peer_knows_is_acked().IsInitialized());
+  SendDataPacket(1);
+  SendAckPacket(2, 1);
+
+  // Now ack the ack and expect an RTT update.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2),
+                           QuicTime::Delta::FromMilliseconds(5), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(1), manager_.largest_packet_peer_knows_is_acked());
+
+  SendAckPacket(3, 3);
+
+  // Now ack the ack and expect only an RTT update.
+  uint64_t acked2[] = {3};
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(3u),
+            manager_.largest_packet_peer_knows_is_acked());
+}
+
+TEST_F(QuicSentPacketManagerTest, Rtt) {
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(20);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) {
+  // Expect that the RTT is equal to the local time elapsed, since the
+  // ack_delay_time is larger than the local time elapsed
+  // and is hence invalid.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1),
+                           QuicTime::Delta::FromMilliseconds(11), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
+  // Expect that the RTT is equal to the local time elapsed, since the
+  // ack_delay_time is infinite, and is hence invalid.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttWithDeltaExceedingLimit) {
+  // Initialize min and smoothed rtt to 10ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  QuicTime::Delta send_delta = QuicTime::Delta::FromMilliseconds(100);
+  QuicTime::Delta ack_delay =
+      QuicTime::Delta::FromMilliseconds(5) + manager_.peer_max_ack_delay();
+  ASSERT_GT(send_delta - rtt_stats->min_rtt(), ack_delay);
+  SendDataPacket(1);
+  clock_.AdvanceTime(send_delta);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), ack_delay, clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+
+  QuicTime::Delta expected_rtt_sample =
+      send_delta - manager_.peer_max_ack_delay();
+  EXPECT_EQ(expected_rtt_sample, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
+  // Expect that the RTT is the time between send and receive since the
+  // ack_delay_time is zero.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  // The first tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // The second tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Ack the third and ensure the first two are still pending.
+  ExpectAck(3);
+
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_TRUE(manager_.HasInFlightPackets());
+
+  // Acking two more packets will lose both of them due to nacks.
+  SendDataPacket(4);
+  SendDataPacket(5);
+  uint64_t acked[] = {4, 5};
+  uint64_t lost[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
+                      ABSL_ARRAYSIZE(lost));
+  // Frames in all packets are acked.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  // Notify session that stream frame in packets 1 and 2 get lost although
+  // they are not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  EXPECT_EQ(2u, stats_.tlp_count);
+  EXPECT_EQ(0u, stats_.rto_count);
+}
+
+TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  QuicTime rto_packet_time = clock_.Now();
+  // Advance the time.
+  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
+
+  // The first tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
+
+  // The second tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(102, type);
+      })));
+  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Ensure the RTO is set based on the correct packet.
+  rto_packet_time = clock_.Now();
+  EXPECT_EQ(rto_packet_time + QuicTime::Delta::FromMilliseconds(500),
+            manager_.GetRetransmissionTime());
+
+  // Advance the time enough to ensure all packets are RTO'd.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(103, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(104, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2u, stats_.tlp_count);
+  EXPECT_EQ(1u, stats_.rto_count);
+  EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
+  // There are 2 RTO retransmissions.
+  EXPECT_EQ(104 * kDefaultLength, manager_.GetBytesInFlight());
+  QuicPacketNumber largest_acked = QuicPacketNumber(103);
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(
+                  true, _, _, Pointwise(PacketNumberEq(), {largest_acked}), _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  // Although frames in packet 3 gets acked, it would be kept for another
+  // RTT.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  // Packets [1, 102] are lost, although stream frame in packet 3 is not
+  // outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(102);
+  manager_.OnAckFrameStart(QuicPacketNumber(103), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(103), QuicPacketNumber(104));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  // All packets before 103 should be lost.
+  // Packet 104 is still in flight.
+  EXPECT_EQ(1000u, manager_.GetBytesInFlight());
+  EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
+}
+
+TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
+  // Send 2 crypto packets and 3 data packets.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  const size_t kNumSentDataPackets = 3;
+  for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
+    SendDataPacket(kNumSentCryptoPackets + i);
+  }
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+  EXPECT_EQ(5 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // The first retransmits 2 packets.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(6); }))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(7); }));
+  manager_.OnRetransmissionTimeout();
+  // Expect all 4 handshake packets to be in flight and 3 data packets.
+  EXPECT_EQ(7 * kDefaultLength, manager_.GetBytesInFlight());
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // The second retransmits 2 packets.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(8); }))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(9); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(9 * kDefaultLength, manager_.GetBytesInFlight());
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Now ack the two crypto packets and the speculatively encrypted request,
+  // and ensure the first four crypto packets get abandoned, but not lost.
+  // Crypto packets remain in flight, so any that aren't acked will be lost.
+  uint64_t acked[] = {3, 4, 5, 8, 9};
+  uint64_t lost[] = {1, 2, 6};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
+                      ABSL_ARRAYSIZE(lost));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(3);
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+}
+
+TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit the crypto packet as 2.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  manager_.OnRetransmissionTimeout();
+
+  // Retransmit the crypto packet as 3.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
+  manager_.OnRetransmissionTimeout();
+
+  // Now ack the second crypto packet, and ensure the first gets removed, but
+  // the third does not.
+  uint64_t acked[] = {2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+  uint64_t unacked[] = {1, 3};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+}
+
+TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
+  // Send 2 crypto packets and 1 data packet.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  SendDataPacket(3);
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit 2 crypto packets, but not the serialized packet.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(5); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       CryptoHandshakeRetransmissionThenNeuterAndAck) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit the crypto packet as 2.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Retransmit the crypto packet as 3.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
+
+  // Now neuter all unacked unencrypted packets, which occurs when the
+  // connection goes forward secure.
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+  uint64_t unacked[] = {1, 2, 3};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+
+  // Ensure both packets get discarded when packet 2 is acked.
+  uint64_t acked[] = {3};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  StrictMock<MockDebugDelegate> debug_delegate;
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(102, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission.
+  // Ensure no packets are lost.
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(true, _, _,
+                                Pointwise(PacketNumberEq(), {largest_acked}),
+                                /*lost_packets=*/IsEmpty()));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  // RTO's use loss detection instead of immediately declaring retransmitted
+  // packets lost.
+  for (int i = 1; i <= 99; ++i) {
+    EXPECT_CALL(debug_delegate,
+                OnPacketLoss(QuicPacketNumber(i), _, LOSS_RETRANSMISSION, _));
+  }
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  // Packets [1, 99] are considered as lost, although stream frame in packet
+  // 2 is not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmissionTimeoutOnePacket) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Set the 1RTO connection option.
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1RTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  StrictMock<MockDebugDelegate> debug_delegate;
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(1)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(101 * kDefaultLength, manager_.GetBytesInFlight());
+}
+
+TEST_F(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(kNRTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(101, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(102, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission and expect no call to OnRetransmissionTimeout.
+  // This will include packets in the lost packet map.
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(true, _, _,
+                                Pointwise(PacketNumberEq(), {largest_acked}),
+                                /*lost_packets=*/Not(IsEmpty())));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  // Packets [1, 99] are considered as lost, although stream frame in packet
+  // 2 is not outstanding.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Rto a second time.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // The original packet and newest should be outstanding.
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+}
+
+TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(2, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Rto a second time.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // The first two packets should still be outstanding.
+  EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTime) {
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
+  QuicTime crypto_packet_send_time = clock_.Now();
+  SendCryptoPacket(1);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime expected_time = clock_.Now() + 1.5 * srtt;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(1.5 * srtt);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  // When session decides what to write, crypto_packet_send_time gets updated.
+  crypto_packet_send_time = clock_.Now();
+  manager_.OnRetransmissionTimeout();
+
+  // The retransmission time should now be twice as far in the future.
+  expected_time = crypto_packet_send_time + srtt * 2 * 1.5;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet for the 2nd time.
+  clock_.AdvanceTime(2 * 1.5 * srtt);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(3); }));
+  // When session decides what to write, crypto_packet_send_time gets updated.
+  crypto_packet_send_time = clock_.Now();
+  manager_.OnRetransmissionTimeout();
+
+  // Verify exponential backoff of the retransmission timeout.
+  expected_time = crypto_packet_send_time + srtt * 4 * 1.5;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       GetConservativeTransmissionTimeCryptoHandshake) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kCONH);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  // Calling SetFromConfig requires mocking out some send algorithm methods.
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  QuicTime crypto_packet_send_time = clock_.Now();
+  SendCryptoPacket(1);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(25),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime expected_time = clock_.Now() + 2 * srtt;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(2 * srtt);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(2); }));
+  crypto_packet_send_time = clock_.Now();
+  manager_.OnRetransmissionTimeout();
+
+  // The retransmission time should now be twice as far in the future.
+  expected_time = crypto_packet_send_time + srtt * 2 * 2;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime::Delta expected_tlp_delay = 2 * srtt;
+  QuicTime expected_time = clock_.Now() + expected_tlp_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(expected_tlp_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type);
+      })));
+  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  expected_time = clock_.Now() + expected_tlp_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  SendDataPacket(1);
+  SendDataPacket(2);
+  SendDataPacket(3);
+  SendDataPacket(4);
+
+  QuicTime::Delta expected_rto_delay =
+      rtt_stats->smoothed_rtt() + 4 * rtt_stats->mean_deviation();
+  QuicTime expected_time = clock_.Now() + expected_rto_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(expected_rto_delay);
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(6, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  // All previous packets are inflight, plus two rto retransmissions.
+  EXPECT_EQ(6 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // The delay should double the second time.
+  expected_time = clock_.Now() + expected_rto_delay + expected_rto_delay;
+  // Once we always base the timer on the right edge, leaving the older packets
+  // in flight doesn't change the timeout.
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Ack a packet before the first RTO and ensure the RTO timeout returns to the
+  // original value and OnRetransmissionTimeout is not called or reverted.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(4 * kDefaultLength, manager_.GetBytesInFlight());
+
+  // Wait 2RTTs from now for the RTO, since it's the max of the RTO time
+  // and the TLP time.  In production, there would always be two TLP's first.
+  // Since retransmission was spurious, smoothed_rtt_ is expired, and replaced
+  // by the latest RTT sample of 500ms.
+  expected_time = clock_.Now() + QuicTime::Delta::FromMilliseconds(1000);
+  // Once we always base the timer on the right edge, leaving the older packets
+  // in flight doesn't change the timeout.
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  SendDataPacket(1);
+  // Provide a 1ms RTT sample.
+  const_cast<RttStats*>(manager_.GetRttStats())
+      ->UpdateRtt(QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::Zero(),
+                  QuicTime::Zero());
+  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(200);
+
+  // If the delay is smaller than the min, ensure it exponentially backs off
+  // from the min.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+    delay = delay + delay;
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
+          return RetransmitDataPacket(i + 2, type);
+        })));
+    manager_.OnRetransmissionTimeout();
+  }
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  SendDataPacket(1);
+  // Provide a 60s RTT sample.
+  const_cast<RttStats*>(manager_.GetRttStats())
+      ->UpdateRtt(QuicTime::Delta::FromSeconds(60), QuicTime::Delta::Zero(),
+                  QuicTime::Zero());
+
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  SendDataPacket(1);
+  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500);
+
+  // Delay should back off exponentially.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+    delay = delay + delay;
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
+          return RetransmitDataPacket(i + 2, type);
+        })));
+    manager_.OnRetransmissionTimeout();
+  }
+}
+
+TEST_F(QuicSentPacketManagerTest, RetransmissionDelay) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  const int64_t kRttMs = 250;
+  const int64_t kDeviationMs = 5;
+
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
+                       QuicTime::Delta::Zero(), clock_.Now());
+
+  // Initial value is to set the median deviation to half of the initial rtt,
+  // the median in then multiplied by a factor of 4 and finally the smoothed rtt
+  // is added which is the initial rtt.
+  QuicTime::Delta expected_delay =
+      QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
+  EXPECT_EQ(expected_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+
+  for (int i = 0; i < 100; ++i) {
+    // Run to make sure that we converge.
+    rtt_stats->UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+    rtt_stats->UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+  }
+  expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
+
+  EXPECT_NEAR(kRttMs, rtt_stats->smoothed_rtt().ToMilliseconds(), 1);
+  EXPECT_NEAR(expected_delay.ToMilliseconds(),
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
+                  .ToMilliseconds(),
+              1);
+}
+
+TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
+  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillRepeatedly(Return(QuicTime::Zero()));
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  // Handle an ack which causes the loss algorithm to be evaluated and
+  // set the loss timeout.
+  ExpectAck(2);
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillRepeatedly(Return(timeout));
+  EXPECT_EQ(timeout, manager_.GetRetransmissionTime());
+
+  // Fire the retransmission timeout and ensure the loss detection algorithm
+  // is invoked.
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  manager_.OnRetransmissionTimeout();
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateIetfLossDetectionFromOptions) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD0);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionOneFourthRttFromOptions) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionAdaptiveReorderingThreshold) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(3, QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionAdaptiveReorderingThreshold2) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD3);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       NegotiateIetfLossDetectionAdaptiveReorderingAndTimeThreshold) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kILD4);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(kDefaultLossDelayShift,
+            QuicSentPacketManagerPeer::GetReorderingShift(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(&manager_));
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kRENO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kTBBR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                      ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kBYTE);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                             ->GetCongestionControlType());
+  options.clear();
+  options.push_back(kRENO);
+  options.push_back(kBYTE);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  // No change if the server receives client options.
+  const SendAlgorithmInterface* mock_sender =
+      QuicSentPacketManagerPeer::GetSendAlgorithm(manager_);
+  options.push_back(kRENO);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(mock_sender, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_));
+
+  // Change the congestion control on the client with client options.
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kTBBR);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                      ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kBYTE);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                             ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kRENO);
+  options.push_back(kBYTE);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(config);
+  // Set the initial RTT to 1us.
+  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
+      QuicTime::Delta::FromMicroseconds(1));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+
+  // Send two packets, and the TLP should be 1ms.
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
+  SendDataPacket(1);
+  SendDataPacket(2);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD2);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  // Set the initial RTT to 1us.
+  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
+      QuicTime::Delta::FromMicroseconds(1));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  // Send two packets, and the TLP should be 1ms.
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
+  SendDataPacket(1);
+  SendDataPacket(2);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD3);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  // Provide one RTT measurement, because otherwise we use the default of 500ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
+  EXPECT_EQ(expected_rto_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD3);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  // Provide one RTT measurement, because otherwise we use the default of 500ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
+  EXPECT_EQ(expected_rto_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
+  QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
+  EXPECT_EQ(expected_tlp_delay,
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kNTLP);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kNTLP);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(k1TLP);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(k1TLP);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtServer) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kNRTO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtClient) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kNRTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(325);
+  EXPECT_NE(initial_rtt, manager_.GetRttStats()->smoothed_rtt());
+
+  QuicConfig config;
+  config.SetInitialRoundTripTimeUsToSend(initial_rtt.ToMicroseconds());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.GetRttStats()->smoothed_rtt());
+  EXPECT_EQ(initial_rtt, manager_.GetRttStats()->initial_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, ResumeConnectionState) {
+  // The sent packet manager should use the RTT from CachedNetworkParameters if
+  // it is provided.
+  const QuicTime::Delta kRtt = QuicTime::Delta::FromMilliseconds(123);
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds());
+
+  SendAlgorithmInterface::NetworkParams params;
+  params.bandwidth = QuicBandwidth::Zero();
+  params.allow_cwnd_to_decrease = false;
+  params.rtt = kRtt;
+  params.is_rtt_trusted = true;
+
+  EXPECT_CALL(*send_algorithm_, AdjustNetworkParameters(params));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .Times(testing::AnyNumber());
+  manager_.ResumeConnectionState(cached_network_params, false);
+  EXPECT_EQ(kRtt, manager_.GetRttStats()->initial_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration());
+  EXPECT_EQ(nullptr,
+            manager_.OnConnectionMigration(/*reset_send_algorithm=*/false));
+
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+}
+
+// Tests that ResetCongestionControlUponPeerAddressChange() resets send
+// algorithm and RTT. And unACK'ed packets are handled correctly.
+TEST_F(QuicSentPacketManagerTest,
+       ConnectionMigrationUnspecifiedChangeResetSendAlgorithm) {
+  auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+
+  RttStats old_rtt_stats;
+  old_rtt_stats.CloneFrom(*manager_.GetRttStats());
+
+  // Packet1 will be mark for retransmission upon migration.
+  EXPECT_CALL(notifier_, OnFrameLost(_));
+  std::unique_ptr<SendAlgorithmInterface> old_send_algorithm =
+      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+
+  EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
+  EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
+            manager_.GetSendAlgorithm()->GetCongestionControlType());
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+  // Packets sent earlier shouldn't be regarded as in flight.
+  EXPECT_EQ(0u, BytesInFlight());
+
+  // Replace the new send algorithm with the mock object.
+  manager_.SetSendAlgorithm(old_send_algorithm.release());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Application retransmit the data as LOSS_RETRANSMISSION.
+  RetransmitDataPacket(2, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kDefaultLength, BytesInFlight());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Receiving an ACK for packet1 20s later shouldn't update the RTT, and
+  // shouldn't be treated as spurious retransmission.
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, kDefaultLength, _, _, _))
+      .WillOnce(testing::WithArg<3>(
+          Invoke([](const AckedPacketVector& acked_packets) {
+            EXPECT_EQ(1u, acked_packets.size());
+            EXPECT_EQ(QuicPacketNumber(1), acked_packets[0].packet_number);
+            // The bytes in packet1 shouldn't contribute to congestion control.
+            EXPECT_EQ(0u, acked_packets[0].bytes_acked);
+          })));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  // Receiving an ACK for packet2 should update RTT and congestion control.
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _))
+      .WillOnce(testing::WithArg<3>(
+          Invoke([](const AckedPacketVector& acked_packets) {
+            EXPECT_EQ(1u, acked_packets.size());
+            EXPECT_EQ(QuicPacketNumber(2), acked_packets[0].packet_number);
+            // The bytes in packet2 should contribute to congestion control.
+            EXPECT_EQ(kDefaultLength, acked_packets[0].bytes_acked);
+          })));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRttStats()->latest_rtt());
+
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Trigger loss timeout and mark packet3 for retransmission.
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
+        packet_lost->emplace_back(QuicPacketNumber(3u), kDefaultLength);
+        return LossDetectionInterface::DetectionStats();
+      })));
+  EXPECT_CALL(notifier_, OnFrameLost(_));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(false, kDefaultLength, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(0u, BytesInFlight());
+
+  // Migrate again with unACK'ed but not in-flight packet.
+  // Packet3 shouldn't be marked for retransmission again as it is not in
+  // flight.
+  old_send_algorithm =
+      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+
+  EXPECT_NE(old_send_algorithm.get(), manager_.GetSendAlgorithm());
+  EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
+            manager_.GetSendAlgorithm()->GetCongestionControlType());
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  manager_.SetSendAlgorithm(old_send_algorithm.release());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
+  // Receiving an ACK for packet3 shouldn't update RTT. Though packet 3 was
+  // marked lost, this spurious retransmission shouldn't be reported to the loss
+  // algorithm.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  SendDataPacket(4, ENCRYPTION_FORWARD_SECURE);
+  // Trigger loss timeout and mark packet4 for retransmission.
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillOnce(Return(clock_.Now() + QuicTime::Delta::FromMilliseconds(10)));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _))
+      .WillOnce(WithArgs<5>(Invoke([](LostPacketVector* packet_lost) {
+        packet_lost->emplace_back(QuicPacketNumber(4u), kDefaultLength);
+        return LossDetectionInterface::DetectionStats();
+      })));
+  EXPECT_CALL(notifier_, OnFrameLost(_));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(false, kDefaultLength, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(0u, BytesInFlight());
+
+  // Application retransmit the data as LOSS_RETRANSMISSION.
+  RetransmitDataPacket(5, LOSS_RETRANSMISSION, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(kDefaultLength, BytesInFlight());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(30));
+  // Receiving an ACK for packet4 should update RTT, but not bytes in flight.
+  // This spurious retransmission should be reported to the loss algorithm.
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(kDefaultLength, BytesInFlight());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(30),
+            manager_.GetRttStats()->latest_rtt());
+
+  // Migrate again with in-flight packet5 whose retransmittable frames are all
+  // ACKed. Packet5 should be marked for retransmission but nothing to
+  // retransmit.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillOnce(Return(false));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(0u);
+  old_send_algorithm =
+      manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+
+  manager_.SetSendAlgorithm(old_send_algorithm.release());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Receiving an ACK for packet5 shouldn't update RTT. Though packet 5 was
+  // marked for retransmission, this spurious retransmission shouldn't be
+  // reported to the loss algorithm.
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(0u, BytesInFlight());
+  EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
+}
+
+TEST_F(QuicSentPacketManagerTest, PathMtuIncreased) {
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, BytesInFlight(), QuicPacketNumber(1), _, _));
+  SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                          nullptr, kDefaultLength + 100, false, false);
+  manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, true);
+
+  // Ack the large packet and expect the path MTU to increase.
+  ExpectAck(1);
+  EXPECT_CALL(*network_change_visitor_,
+              OnPathMtuIncreased(kDefaultLength + 100));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, OnAckRangeSlowPath) {
+  // Send packets 1 - 20.
+  for (size_t i = 1; i <= 20; ++i) {
+    SendDataPacket(i);
+  }
+  // Ack [5, 7), [10, 12), [15, 17).
+  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
+  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+  ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
+                      ABSL_ARRAYSIZE(lost1));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
+  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
+  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
+  // Make sure empty range does not harm.
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Ack [4, 8), [9, 13), [14, 21).
+  uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21));
+  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, TolerateReneging) {
+  // Send packets 1 - 20.
+  for (size_t i = 1; i <= 20; ++i) {
+    SendDataPacket(i);
+  }
+  // Ack [5, 7), [10, 12), [15, 17).
+  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
+  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+  ExpectAcksAndLosses(true, acked1, ABSL_ARRAYSIZE(acked1), lost1,
+                      ABSL_ARRAYSIZE(lost1));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
+  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
+  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Making sure reneged ACK does not harm. Ack [4, 8), [9, 13).
+  uint64_t acked2[] = {4, 7, 9, 12};
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(12), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(16), manager_.GetLargestObserved());
+}
+
+TEST_F(QuicSentPacketManagerTest, MultiplePacketNumberSpaces) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  const QuicUnackedPacketMap* unacked_packets =
+      QuicSentPacketManagerPeer::GetUnackedPacketMap(&manager_);
+  EXPECT_FALSE(
+      unacked_packets
+          ->GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
+          .IsInitialized());
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL).IsInitialized());
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_FALSE(
+      unacked_packets
+          ->GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
+          .IsInitialized());
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicPacketNumber(1),
+            manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL));
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE).IsInitialized());
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_FALSE(
+      unacked_packets
+          ->GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
+          .IsInitialized());
+  // Ack packet 2.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(2),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
+  // Ack packet 3.
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(3),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_FALSE(
+      manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized());
+  // Send packets 4 and 5.
+  SendDataPacket(4, ENCRYPTION_ZERO_RTT);
+  SendDataPacket(5, ENCRYPTION_ZERO_RTT);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(5),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Ack packet 5.
+  ExpectAck(5);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(QuicPacketNumber(3),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(5),
+            manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(QuicPacketNumber(5),
+            manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
+
+  // Send packets 6 - 8.
+  SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
+  SendDataPacket(7, ENCRYPTION_FORWARD_SECURE);
+  SendDataPacket(8, ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(8),
+            unacked_packets->GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Ack all packets.
+  uint64_t acked[] = {4, 6, 7, 8};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(8), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(9));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(5),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(QuicPacketNumber(3),
+            manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(8),
+            manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT));
+  EXPECT_EQ(QuicPacketNumber(8),
+            manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE));
+}
+
+TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+
+  // ACK packets 2 and 3 in the wrong packet number space.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, PacketsGetAckedInWrongPacketNumberSpace2) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+
+  // ACK packet 1 in the wrong packet number space.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_HANDSHAKE));
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       ToleratePacketsGetAckedInWrongPacketNumberSpace) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+
+  // Packet 1 gets acked in the wrong packet number space. Since packet 1 has
+  // been acked in the correct packet number space, tolerate it.
+  uint64_t acked[] = {2, 3};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+}
+
+// Regression test for b/133771183.
+TEST_F(QuicSentPacketManagerTest, PacketInLimbo) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  // Send SHLO.
+  SendCryptoPacket(1);
+  // Send data packet.
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Send Ack Packet.
+  SendAckPacket(3, 1, ENCRYPTION_FORWARD_SECURE);
+  // Retransmit SHLO.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }));
+  manager_.OnRetransmissionTimeout();
+
+  // Successfully decrypt a forward secure packet.
+  manager_.SetHandshakeConfirmed();
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  // Send Ack packet.
+  SendAckPacket(5, 2, ENCRYPTION_FORWARD_SECURE);
+
+  // Retransmission alarm fires.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // Received Ack of packets 1, 3 and 4.
+  uint64_t acked[] = {1, 3, 4};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  uint64_t acked2[] = {5, 6};
+  uint64_t loss[] = {2};
+  // Verify packet 2 is detected lost.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), loss,
+                      ABSL_ARRAYSIZE(loss));
+  manager_.OnAckFrameStart(QuicPacketNumber(6), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(7));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+}
+
+TEST_F(QuicSentPacketManagerTest, RtoFiresNoPacketToRetransmit) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  // Send 10 packets.
+  for (size_t i = 1; i <= 10; ++i) {
+    SendDataPacket(i);
+  }
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(11, type);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(12, type);
+      })));
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(1u, stats_.rto_count);
+  EXPECT_EQ(0u, manager_.pending_timer_transmission_count());
+
+  // RTO fires again, but there is no packet to be RTO retransmitted.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2u, stats_.rto_count);
+  // Verify a credit is raised up.
+  EXPECT_EQ(1u, manager_.pending_timer_transmission_count());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
+  EnablePto(k2PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicTime packet1_sent_time = clock_.Now();
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on sent time of packet 2.
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    // Verify PTO is set based on left edge.
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+  EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
+
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+        })));
+  } else {
+    // Verify two probe packets get sent.
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+        })))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+        })));
+  }
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value.
+  QuicTime sent_time = clock_.Now();
+  EXPECT_EQ(sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 4.
+  EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
+  EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
+}
+
+TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
+  EnablePto(k1PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  QuicTime packet1_sent_time = clock_.Now();
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  // Verify PTO period is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    // Verify PTO is set based on left edge.
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Verify one probe packet gets sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+}
+
+TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeClient) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // Send CHLO.
+  SendCryptoPacket(1);
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(0u, manager_.GetBytesInFlight());
+  // Verify retransmission timeout is not zero because handshake is not
+  // confirmed although there is no in flight packet.
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Fire PTO.
+  EXPECT_EQ(QuicSentPacketManager::PTO_MODE,
+            manager_.OnRetransmissionTimeout());
+  // Send handshake packet.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  // Ack packet 2.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+  // Verify retransmission timeout is zero because server has successfully
+  // processed HANDSHAKE packet.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeServer) {
+  manager_.EnableIetfPtoAndLossDetection();
+  // Send SHLO.
+  SendCryptoPacket(1);
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Ack packet 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(0u, manager_.GetBytesInFlight());
+  // Verify retransmission timeout is not set on server side because there is
+  // nothing in flight.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoTimeoutIncludesMaxAckDelay) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Use PTOS and PTOA.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPTOA);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set and ack delay is included.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on sent time of packet 2 but ack delay is
+  // not included as an immediate ACK is expected.
+  expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
+                                                kDefaultDelayedAckTimeMs);
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value. Also, ack delay is
+  // not included.
+  QuicTime sent_time = clock_.Now();
+  EXPECT_EQ(sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 4. Because of
+  // PTOS turns out to be spurious, ACK delay is included.
+  EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 4.
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_FORWARD_SECURE));
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  // Send more packets, such that peer will do ack decimation.
+  std::vector<uint64_t> acked2;
+  for (size_t i = 5; i <= 100; ++i) {
+    SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
+    acked2.push_back(i);
+  }
+  // Received ACK for all sent packets.
+  ExpectAcksAndLosses(true, &acked2[0], acked2.size(), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(100), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(101));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(100),
+                                   ENCRYPTION_FORWARD_SECURE));
+
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  for (size_t i = 101; i < 110; i++) {
+    SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
+    // Verify PTO timeout includes ACK delay as there are less than 10 packets
+    // outstanding.
+    EXPECT_EQ(clock_.Now() + expected_pto_delay,
+              manager_.GetRetransmissionTime());
+  }
+  expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
+                                                kDefaultDelayedAckTimeMs);
+  SendDataPacket(110, ENCRYPTION_FORWARD_SECURE);
+  // Verify ACK delay is excluded.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, StartExponentialBackoffSince2ndPto) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k2PTO);
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPEB2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on sent time of packet 2.
+  QuicTime deadline = clock_.Now() + expected_pto_delay;
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    // Verify PTO is set based on left edge.
+    deadline = packet1_sent_time + expected_pto_delay;
+  }
+  EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(deadline - clock_.Now());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify no exponential backoff.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 2nd PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(2u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify still no exponential backoff.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 3rd PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(3u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(7, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(8, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify exponential backoff starts.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 4th PTO.
+  clock_.AdvanceTime(expected_pto_delay * 2);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(4u, stats_.pto_count);
+
+  // Verify two probe packets get sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .Times(2)
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(9, type, ENCRYPTION_FORWARD_SECURE);
+      })))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(10, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify exponential backoff continues.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoTimeoutRttVarMultiple) {
+  EnablePto(k1PTO);
+  // Use 2 * rttvar
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPVS1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set based on 2 times rtt var.
+  QuicTime::Delta expected_pto_delay =
+      srtt + 2 * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+// Regression test for b/143962153
+TEST_F(QuicSentPacketManagerTest, RtoNotInFlightPacket) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  // Send SHLO.
+  QuicStreamFrame crypto_frame(1, false, 0, absl::string_view());
+  SendCryptoPacket(1);
+  // Send data packet.
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+
+  // Successfully decrypt a forward secure packet.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+  manager_.SetHandshakeConfirmed();
+
+  // 1st TLP.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // 2nd TLP.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeRetransmitTailLossProbe();
+
+  // RTO retransmits SHLO although it is not in flight.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<0>(Invoke([&crypto_frame](const QuicFrames& frames) {
+        EXPECT_EQ(1u, frames.size());
+        EXPECT_NE(crypto_frame, frames[0].stream_frame);
+        return true;
+      })));
+  manager_.OnRetransmissionTimeout();
+}
+
+TEST_F(QuicSentPacketManagerTest, Aggressive1Pto) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Let the first PTO be aggressive.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPAG1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay = 2 * srtt;
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+
+  // Verify PTO period gets set correctly.
+  QuicTime sent_time = clock_.Now();
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, Aggressive2Ptos) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Let the first PTO be aggressive.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPAG2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay = 2 * srtt;
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+
+  // Verify PTO period gets set correctly.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke 2nd PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(2u, stats_.pto_count);
+
+  // Verify 1 probe packets get sent and packet number gets skipped.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO period gets set correctly.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, IW10ForUpAndDown) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kBWS5);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetInitialCongestionWindowInPackets(10));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(10u, manager_.initial_congestion_window());
+}
+
+TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial key and send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  // Verify PTO is correctly set based on sent time of packet 2.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+  EXPECT_EQ(1u, stats_.crypto_retransmit_count);
+
+  // Verify probe packet gets sent.
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_HANDSHAKE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in application data with 0-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_ZERO_RTT);
+  const QuicTime packet4_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 3.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 5 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(5, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet5_sent_time = clock_.Now();
+  // Verify PTO timeout is now based on packet 5 because packet 4 should be
+  // ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 6 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(6, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is now based on packet 5.
+  EXPECT_EQ(packet5_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 7 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  const QuicTime packet7_sent_time = clock_.Now();
+  SendDataPacket(7, ENCRYPTION_HANDSHAKE);
+
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation();
+  // Verify PTO timeout is now based on packet 7.
+  EXPECT_EQ(packet7_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Neuter handshake key.
+  manager_.SetHandshakeConfirmed();
+  // Forward progress has been made, verify PTO counter gets reset. PTO timeout
+  // is armed by left edge.
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet4_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  const QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial keys.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  // Send packet 3 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is based on packet 2.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  // Verify PTO timeout is based on packet 4 as application data is ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard handshake keys.
+  manager_.SetHandshakeConfirmed();
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  // Verify PTO timeout is now based on packet 3 as handshake is
+  // complete/confirmed.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
+  EnablePto(k1PTO);
+  // Use PTOS and PLE1.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  const QuicTime packet1_sent_time = clock_.Now();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the current value and based on packet3.
+  QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 4.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
+  EnablePto(k1PTO);
+  // Use PTOS and PLE2.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  const QuicTime packet1_sent_time = clock_.Now();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Sent a packet 10ms before PTO expiring.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
+      expected_pto_delay.ToMilliseconds() - 10));
+  SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO expands to packet 2 sent time + 1.5 * srtt.
+  expected_pto_delay = 1.5 * rtt_stats->smoothed_rtt();
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  EXPECT_EQ(0u, stats_.pto_count);
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_EQ(1u, stats_.pto_count);
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+      })));
+  manager_.MaybeSendProbePackets();
+  // Verify PTO period gets set to twice the expected value and based on
+  // packet3 (right edge).
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
+            manager_.GetRetransmissionTime());
+
+  // Received ACK for packets 1 and 2.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+  expected_pto_delay =
+      rtt_stats->SmoothedOrInitialRtt() +
+      std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+               QuicTime::Delta::FromMilliseconds(1)) +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  // Verify PTO is correctly re-armed based on sent time of packet 3 (left
+  // edge).
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutUsingStandardDeviation) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  EnablePto(k1PTO);
+  // Use PTOS and PSDA.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPSDA);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(75),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO is correctly set using standard deviation.
+  QuicTime::Delta expected_pto_delay =
+      srtt +
+      GetPtoRttvarMultiplier() * rtt_stats->GetStandardOrMeanDeviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       ComputingProbeTimeoutByLeftEdgeMultiplePacketNumberSpaces) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  // Use PTOS and PLE1.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE1);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  const QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial keys.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  // Send packet 3 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is based on packet 2.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  // Verify PTO timeout is based on packet 4 as application data is ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard handshake keys.
+  manager_.SetHandshakeConfirmed();
+  // Verify PTO timeout is now based on packet 3 as handshake is
+  // complete/confirmed.
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is still based on packet 3.
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       ComputingProbeTimeoutByLeftEdge2MultiplePacketNumberSpaces) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EnablePto(k1PTO);
+  // Use PTOS and PLE2.
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kPTOS);
+  options.push_back(kPLE2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(manager_.skip_packet_number_for_pto());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  const QuicTime packet1_sent_time = clock_.Now();
+  // Verify PTO is correctly set.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 2 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+  // Verify PTO timeout is still based on packet 1.
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard initial keys.
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+
+  // Send packet 3 in 1-RTT.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(3, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout is based on packet 2.
+  const QuicTime packet3_sent_time = clock_.Now();
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 4 in handshake.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  // Verify PTO timeout is based on packet 4 as application data is ignored.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Discard handshake keys.
+  manager_.SetHandshakeConfirmed();
+  // Verify PTO timeout is now based on packet 3 as handshake is
+  // complete/confirmed.
+  expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+  EXPECT_EQ(packet3_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Send packet 5 10ms before PTO expiring.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(
+      expected_pto_delay.ToMilliseconds() - 10));
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+  // Verify PTO timeout expands to packet 5 sent time + 1.5 * srtt.
+  EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->smoothed_rtt(),
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, SetHandshakeConfirmed) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
+      .WillOnce(
+          Invoke([](const QuicFrame& /*frame*/, QuicTime::Delta ack_delay_time,
+                    QuicTime receive_timestamp) {
+            EXPECT_TRUE(ack_delay_time.IsZero());
+            EXPECT_EQ(receive_timestamp, QuicTime::Zero());
+            return true;
+          }));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(2))).Times(1);
+  manager_.SetHandshakeConfirmed();
+}
+
+// Regresstion test for b/148841700.
+TEST_F(QuicSentPacketManagerTest, NeuterUnencryptedPackets) {
+  SendCryptoPacket(1);
+  SendPingPacket(2, ENCRYPTION_INITIAL);
+  // Crypto data has been discarded but ping does not.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _))
+      .Times(2)
+      .WillOnce(Return(false))
+      .WillOnce(Return(true));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+
+  EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(1))).Times(1);
+  manager_.NeuterUnencryptedPackets();
+}
+
+TEST_F(QuicSentPacketManagerTest, MarkInitialPacketsForRetransmission) {
+  SendCryptoPacket(1);
+  SendPingPacket(2, ENCRYPTION_HANDSHAKE);
+  // Only the INITIAL packet will be retransmitted.
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  manager_.MarkInitialPacketsForRetransmission();
+}
+
+TEST_F(QuicSentPacketManagerTest, NoPacketThresholdDetectionForRuntPackets) {
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kRUNT);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_FALSE(
+      QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelay) {
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  // Before RTT sample is available.
+  // 2 TLPs + 2 RTOs.
+  QuicTime::Delta expected_delay = QuicTime::Delta::Zero();
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
+  }
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
+  }
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+
+  expected_delay = QuicTime::Delta::Zero();
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 0);
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 0);
+
+  // After RTT sample is available.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // 2 TLPs + 2 RTOs.
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
+  }
+  for (size_t i = 0; i < 2; ++i) {
+    QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
+    expected_delay =
+        expected_delay +
+        QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
+  }
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing2PTO) {
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1PTO);
+  QuicTagVector client_options;
+  client_options.push_back(kPDP2);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  client_config.SetClientConnectionOptions(client_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(manager_.pto_enabled());
+  QuicTime::Delta expected_delay = 2 * manager_.GetPtoDelay();
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing1PTO) {
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1PTO);
+  QuicTagVector client_options;
+  client_options.push_back(kPDP1);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  client_config.SetClientConnectionOptions(client_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(manager_.pto_enabled());
+  QuicTime::Delta expected_delay = 1 * manager_.GetPtoDelay();
+  EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
+TEST_F(QuicSentPacketManagerTest, ClientsIgnorePings) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  QuicConfig client_config;
+  QuicTagVector options;
+  QuicTagVector client_options;
+  client_options.push_back(kIGNP);
+  client_config.SetConnectionOptionsToSend(options);
+  client_config.SetClientConnectionOptions(client_options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(client_config);
+
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  SendPingPacket(1, ENCRYPTION_INITIAL);
+  // Verify PING only packet is not considered in flight.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+  SendDataPacket(2, ENCRYPTION_INITIAL);
+  EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+
+  uint64_t acked[] = {1};
+  ExpectAcksAndLosses(/*rtt_updated=*/false, acked, ABSL_ARRAYSIZE(acked),
+                      nullptr, 0);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  // Verify no RTT samples for PING only packet.
+  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+  ExpectAck(2);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
+}
+
+// Regression test for b/154050235.
+TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kInitialRttMs),
+            rtt_stats->initial_rtt());
+  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+  SendCryptoPacket(1);
+  QuicTime::Delta expected_pto_delay =
+      QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
+  manager_.MaybeSendProbePackets();
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    manager_.AdjustPendingTimerTransmissions();
+  }
+  // Verify exponential backoff of the PTO timeout.
+  EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  // Assume client provided a tiny initial RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMicroseconds(1));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1), rtt_stats->initial_rtt());
+  EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+  SendCryptoPacket(1);
+  QuicTime::Delta expected_pto_delay = QuicTime::Delta::FromMilliseconds(10);
+  // Verify kMinHandshakeTimeoutMs is respected.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(
+          WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
+  manager_.MaybeSendProbePackets();
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    manager_.AdjustPendingTimerTransmissions();
+  }
+  // Verify exponential backoff of the PTO timeout.
+  EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, HandshakeAckCausesInitialKeyDropping) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  // Send INITIAL packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  QuicTime::Delta expected_pto_delay =
+      QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+  // Send HANDSHAKE ack.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendAckPacket(2, /*largest_acked=*/1, ENCRYPTION_HANDSHAKE);
+  // Sending HANDSHAKE packet causes dropping of INITIAL key.
+  EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  manager_.NeuterUnencryptedPackets();
+  // There is no in flight packets.
+  EXPECT_FALSE(manager_.HasInFlightPackets());
+  // Verify PTO timer gets rearmed from now because of anti-amplification.
+  EXPECT_EQ(clock_.Now() + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Invoke PTO.
+  clock_.AdvanceTime(expected_pto_delay);
+  manager_.OnRetransmissionTimeout();
+  // Verify nothing to probe (and connection will send PING for current
+  // encryption level).
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
+  manager_.MaybeSendProbePackets();
+}
+
+// Regression test for b/156487311
+TEST_F(QuicSentPacketManagerTest, ClearLastInflightPacketsSentTime) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  // Send INITIAL 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Send HANDSHAKE 2.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+  const QuicTime packet2_sent_time = clock_.Now();
+
+  // Send half RTT 5.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+
+  // Received ACK for INITIAL 1.
+  ExpectAck(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  const QuicTime::Delta pto_delay =
+      rtt_stats->smoothed_rtt() +
+      GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  // Verify PTO is armed based on handshake data.
+  EXPECT_EQ(packet2_sent_time + pto_delay, manager_.GetRetransmissionTime());
+}
+
+// Regression test for b/157895910.
+TEST_F(QuicSentPacketManagerTest, EarliestSentTimeNotInitializedWhenPtoFires) {
+  if (GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm)) {
+    return;
+  }
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  // Send INITIAL 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+
+  // Send HANDSHAKE packets.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+
+  // Send half RTT packet.
+  SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+
+  // Received ACK for INITIAL packet 1.
+  ExpectAck(1);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+
+  // Received ACK for HANDSHAKE packets.
+  uint64_t acked[] = {2, 3, 4};
+  ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(5));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_HANDSHAKE));
+  // Verify PTO will not be armed.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+  // Send packet 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  QuicTime packet1_sent_time = clock_.Now();
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Send packets 2 and 3.
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+  QuicTime packet2_sent_time = clock_.Now();
+  SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+  // Verify PTO is correctly set based on packet 1.
+  QuicTime::Delta expected_pto_delay =
+      srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+      QuicTime::Delta::Zero();
+  EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Assume connection is going to send INITIAL ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(4, type, ENCRYPTION_INITIAL);
+      })));
+  manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
+  // Verify PTO is re-armed based on packet 2.
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+
+  // Connection is going to send another INITIAL ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+      .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+        return RetransmitDataPacket(5, type, ENCRYPTION_INITIAL);
+      })));
+  manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
+  // Verify PTO does not change.
+  EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       AggressivePtoBeforeAnyRttSamplesAreAvailable) {
+  if (GetQuicRestartFlag(quic_default_on_pto2)) {
+    return;
+  }
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kAPTO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  // Send INITIAL 1.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  // Verify retransmission timeout is expected.
+  EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(),
+            manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, SendPathChallengeAndGetAck) {
+  QuicPacketNumber packet_number(1);
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, BytesInFlight(), packet_number, _, _));
+  SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER, nullptr,
+                          kDefaultLength, false, false);
+  QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
+  packet.nonretransmittable_frames.push_back(
+      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                        NO_RETRANSMITTABLE_DATA, false);
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(/*rtt_updated=*/false, _, _,
+                                Pointwise(PacketNumberEq(), {1}), IsEmpty()));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+
+  // Get ACK for the packet.
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_FORWARD_SECURE));
+}
+
+SerializedPacket MakePacketWithAckFrequencyFrame(
+    int packet_number, int ack_frequency_sequence_number,
+    QuicTime::Delta max_ack_delay) {
+  auto* ack_frequency_frame = new QuicAckFrequencyFrame();
+  ack_frequency_frame->max_ack_delay = max_ack_delay;
+  ack_frequency_frame->sequence_number = ack_frequency_sequence_number;
+  SerializedPacket packet(QuicPacketNumber(packet_number),
+                          PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                          /*has_ack=*/false,
+                          /*has_stop_waiting=*/false);
+  packet.retransmittable_frames.push_back(QuicFrame(ack_frequency_frame));
+  packet.has_ack_frequency = true;
+  packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  return packet;
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       PeerMaxAckDelayUpdatedFromAckFrequencyFrameOneAtATime) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+      .Times(AnyNumber());
+
+  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
+  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
+  auto plus_1_ms_delay = initial_peer_max_ack_delay + one_ms;
+  auto minus_1_ms_delay = initial_peer_max_ack_delay - one_ms;
+
+  // Send and Ack frame1.
+  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1,
+      plus_1_ms_delay);
+  // Higher on the fly max_ack_delay changes peer_max_ack_delay.
+  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
+
+  // Send and Ack frame2.
+  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2,
+      minus_1_ms_delay);
+  // Lower on the fly max_ack_delay does not change peer_max_ack_delay.
+  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), minus_1_ms_delay);
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       PeerMaxAckDelayUpdatedFromInOrderAckFrequencyFrames) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+      .Times(AnyNumber());
+
+  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
+  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
+  auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
+  auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
+  auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
+  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_1_ms);
+  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
+  SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
+
+  // Send frame1, farme2, frame3.
+  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
+  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+  manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+
+  // Ack frame1, farme2, frame3.
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+}
+
+TEST_F(QuicSentPacketManagerTest,
+       PeerMaxAckDelayUpdatedFromOutOfOrderAckedAckFrequencyFrames) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+      .Times(AnyNumber());
+
+  auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay();
+  auto one_ms = QuicTime::Delta::FromMilliseconds(1);
+  auto extra_1_ms = initial_peer_max_ack_delay + one_ms;
+  auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms;
+  auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms;
+  auto extra_4_ms = initial_peer_max_ack_delay + 4 * one_ms;
+  SerializedPacket packet1 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_4_ms);
+  SerializedPacket packet2 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms);
+  SerializedPacket packet3 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms);
+  SerializedPacket packet4 = MakePacketWithAckFrequencyFrame(
+      /*packet_number=*/4, /*ack_frequency_sequence_number=*/4, extra_1_ms);
+
+  // Send frame1, farme2, frame3, frame4.
+  manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION,
+                        HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  manager_.OnPacketSent(&packet4, clock_.Now(), NOT_RETRANSMISSION,
+                        NO_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_4_ms);
+
+  // Ack frame3.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+  // Acking frame1 do not affect peer_max_ack_delay after frame3 is acked.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+  // Acking frame2 do not affect peer_max_ack_delay after frame3 is acked.
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms);
+  // Acking frame4 updates peer_max_ack_delay.
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(5));
+  manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                         ENCRYPTION_FORWARD_SECURE);
+  EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms);
+}
+
+TEST_F(QuicSentPacketManagerTest, ClearDataInMessageFrameAfterPacketSent) {
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+
+  QuicMessageFrame* message_frame = nullptr;
+  {
+    quiche::QuicheMemSlice slice(quiche::QuicheBuffer(&allocator_, 1024));
+    message_frame = new QuicMessageFrame(/*message_id=*/1, std::move(slice));
+    EXPECT_FALSE(message_frame->message_data.empty());
+    EXPECT_EQ(message_frame->message_length, 1024);
+
+    SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                            /*encrypted_buffer=*/nullptr, kDefaultLength,
+                            /*has_ack=*/false,
+                            /*has_stop_waiting*/ false);
+    packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
+    packet.retransmittable_frames.push_back(QuicFrame(message_frame));
+    packet.has_message = true;
+    manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
+                          HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true);
+  }
+
+  EXPECT_TRUE(message_frame->message_data.empty());
+  EXPECT_EQ(message_frame->message_length, 0);
+}
+
+TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrame) {
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  manager_.SetFromConfig(config);
+  manager_.SetHandshakeConfirmed();
+
+  // Set up RTTs.
+  auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
+                       /*ack_delay=*/QuicTime::Delta::Zero(),
+                       /*now=*/QuicTime::Zero());
+  // Make sure srtt and min_rtt are different.
+  rtt_stats->UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(160),
+      /*ack_delay=*/QuicTime::Delta::Zero(),
+      /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
+
+  auto frame = manager_.GetUpdatedAckFrequencyFrame();
+  EXPECT_EQ(frame.max_ack_delay,
+            std::max(rtt_stats->min_rtt() * 0.25,
+                     QuicTime::Delta::FromMilliseconds(1u)));
+  EXPECT_EQ(frame.packet_tolerance, 10u);
+}
+
+TEST_F(QuicSentPacketManagerTest, SmoothedRttIgnoreAckDelay) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kMAD0);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(config);
+
+  SendDataPacket(1);
+  // Ack 1.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1),
+                           QuicTime::Delta::FromMilliseconds(100),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  // Verify that ack_delay is ignored in the first measurement.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->smoothed_rtt());
+
+  SendDataPacket(2);
+  // Ack 2.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2),
+                           QuicTime::Delta::FromMilliseconds(100),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->smoothed_rtt());
+
+  SendDataPacket(3);
+  // Ack 3.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(300));
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3),
+                           QuicTime::Delta::FromMilliseconds(50), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(300),
+            manager_.GetRttStats()->smoothed_rtt());
+
+  SendDataPacket(4);
+  // Ack 4.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4),
+                           QuicTime::Delta::FromMilliseconds(300),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+                                   ENCRYPTION_INITIAL));
+  // Verify that large erroneous ack_delay does not change Smoothed RTT.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+            manager_.GetRttStats()->latest_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(287500),
+            manager_.GetRttStats()->smoothed_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, IgnorePeerMaxAckDelayDuringHandshake) {
+  manager_.EnableMultiplePacketNumberSpacesSupport();
+  // 100ms RTT.
+  const QuicTime::Delta kTestRTT = QuicTime::Delta::FromMilliseconds(100);
+
+  // Server sends INITIAL 1 and HANDSHAKE 2.
+  SendDataPacket(1, ENCRYPTION_INITIAL);
+  SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+
+  // Receive client ACK for INITIAL 1 after one RTT.
+  clock_.AdvanceTime(kTestRTT);
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+                                   ENCRYPTION_INITIAL));
+  EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
+
+  // Assume the cert verification on client takes 50ms, such that the HANDSHAKE
+  // packet is queued for 50ms.
+  const QuicTime::Delta queuing_delay = QuicTime::Delta::FromMilliseconds(50);
+  clock_.AdvanceTime(queuing_delay);
+  // Ack 2.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), queuing_delay, clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_EQ(PACKETS_NEWLY_ACKED,
+            manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
+                                   ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(kTestRTT, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrameWithSRTT) {
+  SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  QuicConfig config;
+  QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1);
+  QuicTagVector quic_tag_vector;
+  quic_tag_vector.push_back(kAFF1);  // SRTT enabling tag.
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector);
+  manager_.SetFromConfig(config);
+  manager_.SetHandshakeConfirmed();
+
+  // Set up RTTs.
+  auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(80),
+                       /*ack_delay=*/QuicTime::Delta::Zero(),
+                       /*now=*/QuicTime::Zero());
+  // Make sure srtt and min_rtt are different.
+  rtt_stats->UpdateRtt(
+      QuicTime::Delta::FromMilliseconds(160),
+      /*ack_delay=*/QuicTime::Delta::Zero(),
+      /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24));
+
+  auto frame = manager_.GetUpdatedAckFrequencyFrame();
+  EXPECT_EQ(frame.max_ack_delay,
+            std::max(rtt_stats->SmoothedOrInitialRtt() * 0.25,
+                     QuicTime::Delta::FromMilliseconds(1u)));
+}
+
+TEST_F(QuicSentPacketManagerTest, SetInitialRtt) {
+  // Upper bounds.
+  manager_.SetInitialRtt(
+      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs + 1), false);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMaxInitialRoundTripTimeUs);
+
+  manager_.SetInitialRtt(
+      QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs + 1), true);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMaxInitialRoundTripTimeUs);
+
+  EXPECT_GT(kMinUntrustedInitialRoundTripTimeUs,
+            kMinTrustedInitialRoundTripTimeUs);
+
+  // Lower bounds for untrusted rtt.
+  manager_.SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                             kMinUntrustedInitialRoundTripTimeUs - 1),
+                         false);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMinUntrustedInitialRoundTripTimeUs);
+
+  // Lower bounds for trusted rtt.
+  manager_.SetInitialRtt(QuicTime::Delta::FromMicroseconds(
+                             kMinUntrustedInitialRoundTripTimeUs - 1),
+                         true);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMinUntrustedInitialRoundTripTimeUs - 1);
+
+  manager_.SetInitialRtt(
+      QuicTime::Delta::FromMicroseconds(kMinTrustedInitialRoundTripTimeUs - 1),
+      true);
+  EXPECT_EQ(manager_.GetRttStats()->initial_rtt().ToMicroseconds(),
+            kMinTrustedInitialRoundTripTimeUs);
+}
+
+TEST_F(QuicSentPacketManagerTest, GetAvailableCongestionWindow) {
+  SendDataPacket(1);
+  EXPECT_EQ(kDefaultLength, manager_.GetBytesInFlight());
+
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(kDefaultLength + 10));
+  EXPECT_EQ(10u, manager_.GetAvailableCongestionWindowInBytes());
+
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(kDefaultLength));
+  EXPECT_EQ(0u, manager_.GetAvailableCongestionWindowInBytes());
+
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(kDefaultLength - 10));
+  EXPECT_EQ(0u, manager_.GetAvailableCongestionWindowInBytes());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_server_id.cc b/quiche/quic/core/quic_server_id.cc
new file mode 100644
index 0000000..9f61072
--- /dev/null
+++ b/quiche/quic/core/quic_server_id.cc
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_server_id.h"
+
+#include <string>
+#include <tuple>
+
+namespace quic {
+
+QuicServerId::QuicServerId() : QuicServerId("", 0, false) {}
+
+QuicServerId::QuicServerId(const std::string& host, uint16_t port)
+    : QuicServerId(host, port, false) {}
+
+QuicServerId::QuicServerId(const std::string& host,
+                           uint16_t port,
+                           bool privacy_mode_enabled)
+    : host_(host), port_(port), privacy_mode_enabled_(privacy_mode_enabled) {}
+
+QuicServerId::~QuicServerId() {}
+
+bool QuicServerId::operator<(const QuicServerId& other) const {
+  return std::tie(port_, host_, privacy_mode_enabled_) <
+         std::tie(other.port_, other.host_, other.privacy_mode_enabled_);
+}
+
+bool QuicServerId::operator==(const QuicServerId& other) const {
+  return privacy_mode_enabled_ == other.privacy_mode_enabled_ &&
+         host_ == other.host_ && port_ == other.port_;
+}
+
+bool QuicServerId::operator!=(const QuicServerId& other) const {
+  return !(*this == other);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_server_id.h b/quiche/quic/core/quic_server_id.h
new file mode 100644
index 0000000..8f437d1
--- /dev/null
+++ b/quiche/quic/core/quic_server_id.h
@@ -0,0 +1,55 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
+#define QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
+
+#include <cstdint>
+#include <string>
+
+#include "absl/hash/hash.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The id used to identify sessions. Includes the hostname, port, scheme and
+// privacy_mode.
+class QUIC_EXPORT_PRIVATE QuicServerId {
+ public:
+  QuicServerId();
+  QuicServerId(const std::string& host, uint16_t port);
+  QuicServerId(const std::string& host,
+               uint16_t port,
+               bool privacy_mode_enabled);
+  ~QuicServerId();
+
+  // Needed to be an element of an ordered container.
+  bool operator<(const QuicServerId& other) const;
+  bool operator==(const QuicServerId& other) const;
+
+  bool operator!=(const QuicServerId& other) const;
+
+  const std::string& host() const { return host_; }
+
+  uint16_t port() const { return port_; }
+
+  bool privacy_mode_enabled() const { return privacy_mode_enabled_; }
+
+ private:
+  std::string host_;
+  uint16_t port_;
+  bool privacy_mode_enabled_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicServerIdHash {
+ public:
+  size_t operator()(const quic::QuicServerId& server_id) const noexcept {
+    return absl::HashOf(server_id.host(), server_id.port(),
+                        server_id.privacy_mode_enabled());
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SERVER_ID_H_
diff --git a/quiche/quic/core/quic_server_id_test.cc b/quiche/quic/core/quic_server_id_test.cc
new file mode 100644
index 0000000..c4e5368
--- /dev/null
+++ b/quiche/quic/core/quic_server_id_test.cc
@@ -0,0 +1,124 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_server_id.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace {
+
+class QuicServerIdTest : public QuicTest {};
+
+TEST_F(QuicServerIdTest, Constructor) {
+  QuicServerId google_server_id("google.com", 10, false);
+  EXPECT_EQ("google.com", google_server_id.host());
+  EXPECT_EQ(10, google_server_id.port());
+  EXPECT_FALSE(google_server_id.privacy_mode_enabled());
+
+  QuicServerId private_server_id("mail.google.com", 12, true);
+  EXPECT_EQ("mail.google.com", private_server_id.host());
+  EXPECT_EQ(12, private_server_id.port());
+  EXPECT_TRUE(private_server_id.privacy_mode_enabled());
+}
+
+TEST_F(QuicServerIdTest, LessThan) {
+  QuicServerId a_10_https("a.com", 10, false);
+  QuicServerId a_11_https("a.com", 11, false);
+  QuicServerId b_10_https("b.com", 10, false);
+  QuicServerId b_11_https("b.com", 11, false);
+
+  QuicServerId a_10_https_private("a.com", 10, true);
+  QuicServerId a_11_https_private("a.com", 11, true);
+  QuicServerId b_10_https_private("b.com", 10, true);
+  QuicServerId b_11_https_private("b.com", 11, true);
+
+  // Test combinations of host, port, and privacy being same on left and
+  // right side of less than.
+  EXPECT_FALSE(a_10_https < a_10_https);
+  EXPECT_TRUE(a_10_https < a_10_https_private);
+  EXPECT_FALSE(a_10_https_private < a_10_https);
+  EXPECT_FALSE(a_10_https_private < a_10_https_private);
+
+  // Test with either host, port or https being different on left and right side
+  // of less than.
+  bool left_privacy;
+  bool right_privacy;
+  for (int i = 0; i < 4; i++) {
+    left_privacy = (i / 2 == 0);
+    right_privacy = (i % 2 == 0);
+    QuicServerId a_10_https_left_private("a.com", 10, left_privacy);
+    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
+    QuicServerId a_11_https_left_private("a.com", 11, left_privacy);
+    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
+
+    QuicServerId b_10_https_left_private("b.com", 10, left_privacy);
+    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
+    QuicServerId b_11_https_left_private("b.com", 11, left_privacy);
+    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
+
+    EXPECT_TRUE(a_10_https_left_private < a_11_https_right_private);
+    EXPECT_TRUE(a_10_https_left_private < b_10_https_right_private);
+    EXPECT_TRUE(a_10_https_left_private < b_11_https_right_private);
+    EXPECT_FALSE(a_11_https_left_private < a_10_https_right_private);
+    EXPECT_FALSE(a_11_https_left_private < b_10_https_right_private);
+    EXPECT_TRUE(a_11_https_left_private < b_11_https_right_private);
+    EXPECT_FALSE(b_10_https_left_private < a_10_https_right_private);
+    EXPECT_TRUE(b_10_https_left_private < a_11_https_right_private);
+    EXPECT_TRUE(b_10_https_left_private < b_11_https_right_private);
+    EXPECT_FALSE(b_11_https_left_private < a_10_https_right_private);
+    EXPECT_FALSE(b_11_https_left_private < a_11_https_right_private);
+    EXPECT_FALSE(b_11_https_left_private < b_10_https_right_private);
+  }
+}
+
+TEST_F(QuicServerIdTest, Equals) {
+  bool left_privacy;
+  bool right_privacy;
+  for (int i = 0; i < 2; i++) {
+    left_privacy = right_privacy = (i == 0);
+    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
+    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
+    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
+    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
+
+    EXPECT_NE(a_10_https_right_private, a_11_https_right_private);
+    EXPECT_NE(a_10_https_right_private, b_10_https_right_private);
+    EXPECT_NE(a_10_https_right_private, b_11_https_right_private);
+
+    QuicServerId new_a_10_https_left_private("a.com", 10, left_privacy);
+    QuicServerId new_a_11_https_left_private("a.com", 11, left_privacy);
+    QuicServerId new_b_10_https_left_private("b.com", 10, left_privacy);
+    QuicServerId new_b_11_https_left_private("b.com", 11, left_privacy);
+
+    EXPECT_EQ(new_a_10_https_left_private, a_10_https_right_private);
+    EXPECT_EQ(new_a_11_https_left_private, a_11_https_right_private);
+    EXPECT_EQ(new_b_10_https_left_private, b_10_https_right_private);
+    EXPECT_EQ(new_b_11_https_left_private, b_11_https_right_private);
+  }
+
+  for (int i = 0; i < 2; i++) {
+    right_privacy = (i == 0);
+    QuicServerId a_10_https_right_private("a.com", 10, right_privacy);
+    QuicServerId a_11_https_right_private("a.com", 11, right_privacy);
+    QuicServerId b_10_https_right_private("b.com", 10, right_privacy);
+    QuicServerId b_11_https_right_private("b.com", 11, right_privacy);
+
+    QuicServerId new_a_10_https_left_private("a.com", 10, false);
+
+    EXPECT_NE(new_a_10_https_left_private, a_11_https_right_private);
+    EXPECT_NE(new_a_10_https_left_private, b_10_https_right_private);
+    EXPECT_NE(new_a_10_https_left_private, b_11_https_right_private);
+  }
+  QuicServerId a_10_https_private("a.com", 10, true);
+  QuicServerId new_a_10_https_no_private("a.com", 10, false);
+  EXPECT_NE(new_a_10_https_no_private, a_10_https_private);
+}
+
+}  // namespace
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_session.cc b/quiche/quic/core/quic_session.cc
new file mode 100644
index 0000000..4d89cdd
--- /dev/null
+++ b/quiche/quic/core/quic_session.cc
@@ -0,0 +1,2669 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_session.h"
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_context.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using spdy::SpdyPriority;
+
+namespace quic {
+
+namespace {
+
+class ClosedStreamsCleanUpDelegate : public QuicAlarm::Delegate {
+ public:
+  explicit ClosedStreamsCleanUpDelegate(QuicSession* session)
+      : session_(session) {}
+  ClosedStreamsCleanUpDelegate(const ClosedStreamsCleanUpDelegate&) = delete;
+  ClosedStreamsCleanUpDelegate& operator=(const ClosedStreamsCleanUpDelegate&) =
+      delete;
+
+  QuicConnectionContext* GetConnectionContext() override {
+    return (session_->connection() == nullptr)
+               ? nullptr
+               : session_->connection()->context();
+  }
+
+  void OnAlarm() override { session_->CleanUpClosedStreams(); }
+
+ private:
+  QuicSession* session_;
+};
+
+}  // namespace
+
+#define ENDPOINT \
+  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QuicSession::QuicSession(
+    QuicConnection* connection, Visitor* owner, const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicStreamCount num_expected_unidirectional_static_streams)
+    : QuicSession(connection, owner, config, supported_versions,
+                  num_expected_unidirectional_static_streams, nullptr) {}
+
+QuicSession::QuicSession(
+    QuicConnection* connection, Visitor* owner, const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicStreamCount num_expected_unidirectional_static_streams,
+    std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
+    : connection_(connection),
+      perspective_(connection->perspective()),
+      visitor_(owner),
+      write_blocked_streams_(connection->transport_version()),
+      config_(config),
+      stream_id_manager_(perspective(), connection->transport_version(),
+                         kDefaultMaxStreamsPerConnection,
+                         config_.GetMaxBidirectionalStreamsToSend()),
+      ietf_streamid_manager_(perspective(), connection->version(), this, 0,
+                             num_expected_unidirectional_static_streams,
+                             config_.GetMaxBidirectionalStreamsToSend(),
+                             config_.GetMaxUnidirectionalStreamsToSend() +
+                                 num_expected_unidirectional_static_streams),
+      num_draining_streams_(0),
+      num_outgoing_draining_streams_(0),
+      num_static_streams_(0),
+      num_zombie_streams_(0),
+      flow_controller_(
+          this, QuicUtils::GetInvalidStreamId(connection->transport_version()),
+          /*is_connection_flow_controller*/ true,
+          connection->version().AllowsLowFlowControlLimits()
+              ? 0
+              : kMinimumFlowControlSendWindow,
+          config_.GetInitialSessionFlowControlWindowToSend(),
+          kSessionReceiveWindowLimit, perspective() == Perspective::IS_SERVER,
+          nullptr),
+      currently_writing_stream_id_(0),
+      transport_goaway_sent_(false),
+      transport_goaway_received_(false),
+      control_frame_manager_(this),
+      last_message_id_(0),
+      datagram_queue_(this, std::move(datagram_observer)),
+      closed_streams_clean_up_alarm_(nullptr),
+      supported_versions_(supported_versions),
+      is_configured_(false),
+      was_zero_rtt_rejected_(false),
+      liveness_testing_in_progress_(false) {
+  closed_streams_clean_up_alarm_ =
+      absl::WrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
+          new ClosedStreamsCleanUpDelegate(this)));
+  if (perspective() == Perspective::IS_SERVER &&
+      connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
+  }
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    config_.SetMaxUnidirectionalStreamsToSend(
+        config_.GetMaxUnidirectionalStreamsToSend() +
+        num_expected_unidirectional_static_streams);
+  }
+}
+
+void QuicSession::Initialize() {
+  connection_->set_visitor(this);
+  connection_->SetSessionNotifier(this);
+  connection_->SetDataProducer(this);
+  connection_->SetUnackedMapInitialCapacity();
+  connection_->SetFromConfig(config_);
+  if (perspective_ == Perspective::IS_CLIENT) {
+    if (config_.HasClientRequestedIndependentOption(kAFFE, perspective_) &&
+        version().HasIetfQuicFrames()) {
+      connection_->set_can_receive_ack_frequency_frame();
+      config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
+    }
+    if (config_.HasClientRequestedIndependentOption(kNBPE, perspective_)) {
+      permutes_tls_extensions_ = false;
+    }
+  }
+
+  connection_->CreateConnectionIdManager();
+
+  // On the server side, version negotiation has been done by the dispatcher,
+  // and the server session is created with the right version.
+  if (perspective() == Perspective::IS_SERVER) {
+    connection_->OnSuccessfulVersionNegotiation();
+  }
+
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return;
+  }
+
+  QUICHE_DCHECK_EQ(QuicUtils::GetCryptoStreamId(transport_version()),
+                   GetMutableCryptoStream()->id());
+}
+
+QuicSession::~QuicSession() {
+  if (closed_streams_clean_up_alarm_ != nullptr) {
+    closed_streams_clean_up_alarm_->PermanentCancel();
+  }
+}
+
+PendingStream* QuicSession::PendingStreamOnStreamFrame(
+    const QuicStreamFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QuicStreamId stream_id = frame.stream_id;
+
+  PendingStream* pending = GetOrCreatePendingStream(stream_id);
+
+  if (!pending) {
+    if (frame.fin) {
+      QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
+      OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+    }
+    return nullptr;
+  }
+
+  pending->OnStreamFrame(frame);
+  if (!connection()->connected()) {
+    return nullptr;
+  }
+  return pending;
+}
+
+void QuicSession::MaybeProcessPendingStream(PendingStream* pending) {
+  QUICHE_DCHECK(pending != nullptr);
+  QuicStreamId stream_id = pending->id();
+  absl::optional<QuicResetStreamError> stop_sending_error_code =
+      pending->GetStopSendingErrorCode();
+  QuicStream* stream = ProcessPendingStream(pending);
+  if (stream != nullptr) {
+    // The pending stream should now be in the scope of normal streams.
+    QUICHE_DCHECK(IsClosedStream(stream_id) || IsOpenStream(stream_id))
+        << "Stream " << stream_id << " not created";
+    pending_stream_map_.erase(stream_id);
+    if (stop_sending_error_code) {
+      stream->OnStopSending(*stop_sending_error_code);
+      if (!connection()->connected()) {
+        return;
+      }
+    }
+    stream->OnStreamCreatedFromPendingStream();
+    return;
+  }
+  // At this point, none of the bytes has been successfully consumed by the
+  // application layer. We should close the pending stream even if it is
+  // bidirectionl as no application will be able to write in a bidirectional
+  // stream with zero byte as input.
+  if (pending->sequencer()->IsClosed()) {
+    ClosePendingStream(stream_id);
+  }
+}
+
+void QuicSession::PendingStreamOnWindowUpdateFrame(
+    const QuicWindowUpdateFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
+  if (pending) {
+    pending->OnWindowUpdateFrame(frame);
+  }
+}
+
+void QuicSession::PendingStreamOnStopSendingFrame(
+    const QuicStopSendingFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
+  if (pending) {
+    pending->OnStopSending(frame.error());
+  }
+}
+
+void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
+  QuicStreamId stream_id = frame.stream_id;
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (ShouldProcessFrameByPendingStream(STREAM_FRAME, stream_id)) {
+    PendingStream* pending = PendingStreamOnStreamFrame(frame);
+    if (pending != nullptr && ShouldProcessPendingStreamImmediately()) {
+      MaybeProcessPendingStream(pending);
+    }
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+
+  if (!stream) {
+    // The stream no longer exists, but we may still be interested in the
+    // final stream byte offset sent by the peer. A frame with a FIN can give
+    // us this offset.
+    if (frame.fin) {
+      QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
+      OnFinalByteOffsetReceived(stream_id, final_byte_offset);
+    }
+    return;
+  }
+  stream->OnStreamFrame(frame);
+}
+
+void QuicSession::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  GetMutableCryptoStream()->OnCryptoFrame(frame);
+}
+
+void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
+  // STOP_SENDING is in IETF QUIC only.
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
+
+  QuicStreamId stream_id = frame.stream_id;
+  // If Stream ID is invalid then close the connection.
+  // TODO(ianswett): This check is redundant to checks for IsClosedStream,
+  // but removing it requires removing multiple QUICHE_DCHECKs.
+  // TODO(ianswett): Multiple QUIC_DVLOGs could be QUIC_PEER_BUGs.
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received STOP_SENDING with invalid stream_id: "
+                  << stream_id << " Closing connection";
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for an invalid stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  // If stream_id is READ_UNIDIRECTIONAL, close the connection.
+  if (QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id),
+                               version()) == READ_UNIDIRECTIONAL) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received STOP_SENDING for a read-only stream_id: "
+                  << stream_id << ".";
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for a read-only stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (visitor_) {
+    visitor_->OnStopSendingReceived(frame);
+  }
+  if (ShouldProcessFrameByPendingStream(STOP_SENDING_FRAME, stream_id)) {
+    PendingStreamOnStopSendingFrame(frame);
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+  if (!stream) {
+    // Errors are handled by GetOrCreateStream.
+    return;
+  }
+
+  stream->OnStopSending(frame.error());
+}
+
+void QuicSession::OnPacketDecrypted(EncryptionLevel level) {
+  GetMutableCryptoStream()->OnPacketDecrypted(level);
+  if (liveness_testing_in_progress_) {
+    liveness_testing_in_progress_ = false;
+    OnCanCreateNewOutgoingStream(/*unidirectional=*/false);
+  }
+}
+
+void QuicSession::OnOneRttPacketAcknowledged() {
+  GetMutableCryptoStream()->OnOneRttPacketAcknowledged();
+}
+
+void QuicSession::OnHandshakePacketSent() {
+  GetMutableCryptoStream()->OnHandshakePacketSent();
+}
+
+std::unique_ptr<QuicDecrypter>
+QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return GetMutableCryptoStream()->AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() {
+  return GetMutableCryptoStream()->CreateCurrentOneRttEncrypter();
+}
+
+void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
+  QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
+  QuicStreamId stream_id = frame.stream_id;
+
+  PendingStream* pending = GetOrCreatePendingStream(stream_id);
+
+  if (!pending) {
+    HandleRstOnValidNonexistentStream(frame);
+    return;
+  }
+
+  pending->OnRstStreamFrame(frame);
+  // At this point, none of the bytes has been consumed by the application
+  // layer. It is safe to close the pending stream even if it is bidirectionl as
+  // no application will be able to write in a bidirectional stream with zero
+  // byte as input.
+  ClosePendingStream(stream_id);
+}
+
+void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
+  QuicStreamId stream_id = frame.stream_id;
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id),
+                               version()) == WRITE_UNIDIRECTIONAL) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Received RESET_STREAM for a write-only stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (visitor_) {
+    visitor_->OnRstStreamReceived(frame);
+  }
+
+  if (ShouldProcessFrameByPendingStream(RST_STREAM_FRAME, stream_id)) {
+    PendingStreamOnRstStream(frame);
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+
+  if (!stream) {
+    HandleRstOnValidNonexistentStream(frame);
+    return;  // Errors are handled by GetOrCreateStream.
+  }
+  stream->OnStreamReset(frame);
+}
+
+void QuicSession::OnGoAway(const QuicGoAwayFrame& /*frame*/) {
+  QUIC_BUG_IF(quic_bug_12435_1, version().UsesHttp3())
+      << "gQUIC GOAWAY received on version " << version();
+
+  transport_goaway_received_ = true;
+}
+
+void QuicSession::OnMessageReceived(absl::string_view message) {
+  QUIC_DVLOG(1) << ENDPOINT << "Received message of length "
+                << message.length();
+  QUIC_DVLOG(2) << ENDPOINT << "Contents of message of length "
+                << message.length() << ":" << std::endl
+                << quiche::QuicheTextUtils::HexDump(message);
+}
+
+void QuicSession::OnHandshakeDoneReceived() {
+  QUIC_DVLOG(1) << ENDPOINT << "OnHandshakeDoneReceived";
+  GetMutableCryptoStream()->OnHandshakeDoneReceived();
+}
+
+void QuicSession::OnNewTokenReceived(absl::string_view token) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+  GetMutableCryptoStream()->OnNewTokenReceived(token);
+}
+
+// static
+void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
+                                                ConnectionCloseSource source) {
+  if (error != QUIC_NO_ERROR) {
+    if (source == ConnectionCloseSource::FROM_SELF) {
+      QUIC_SERVER_HISTOGRAM_ENUM(
+          "quic_server_connection_close_errors", error, QUIC_LAST_ERROR,
+          "QuicErrorCode for server-closed connections.");
+    } else {
+      QUIC_SERVER_HISTOGRAM_ENUM(
+          "quic_client_connection_close_errors", error, QUIC_LAST_ERROR,
+          "QuicErrorCode for client-closed connections.");
+    }
+  }
+}
+
+void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                                     ConnectionCloseSource source) {
+  QUICHE_DCHECK(!connection_->connected());
+  if (perspective() == Perspective::IS_SERVER) {
+    RecordConnectionCloseAtServer(frame.quic_error_code, source);
+  }
+
+  if (on_closed_frame_.quic_error_code == QUIC_NO_ERROR) {
+    // Save all of the connection close information
+    on_closed_frame_ = frame;
+  }
+
+  GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
+
+  PerformActionOnActiveStreams([this, frame, source](QuicStream* stream) {
+    QuicStreamId id = stream->id();
+    stream->OnConnectionClosed(frame.quic_error_code, source);
+    auto it = stream_map_.find(id);
+    if (it != stream_map_.end()) {
+      QUIC_BUG_IF(quic_bug_12435_2, !it->second->IsZombie())
+          << ENDPOINT << "Non-zombie stream " << id
+          << " failed to close under OnConnectionClosed";
+    }
+    return true;
+  });
+
+  closed_streams_clean_up_alarm_->Cancel();
+
+  if (visitor_) {
+    visitor_->OnConnectionClosed(connection_->GetOneActiveServerConnectionId(),
+                                 frame.quic_error_code, frame.error_details,
+                                 source);
+  }
+}
+
+void QuicSession::OnWriteBlocked() {
+  if (!connection_->connected()) {
+    return;
+  }
+  if (visitor_) {
+    visitor_->OnWriteBlocked(connection_);
+  }
+}
+
+void QuicSession::OnSuccessfulVersionNegotiation(
+    const ParsedQuicVersion& /*version*/) {}
+
+void QuicSession::OnPacketReceived(const QuicSocketAddress& /*self_address*/,
+                                   const QuicSocketAddress& peer_address,
+                                   bool is_connectivity_probe) {
+  if (is_connectivity_probe && perspective() == Perspective::IS_SERVER) {
+    // Server only sends back a connectivity probe after received a
+    // connectivity probe from a new peer address.
+      connection_->SendConnectivityProbingPacket(nullptr, peer_address);
+  }
+}
+
+void QuicSession::OnPathDegrading() {}
+
+void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
+
+bool QuicSession::AllowSelfAddressChange() const { return false; }
+
+void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
+  // assume that it still exists.
+  QuicStreamId stream_id = frame.stream_id;
+  if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
+    // This is a window update that applies to the connection, rather than an
+    // individual stream.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received connection level flow control window "
+                     "update with max data: "
+                  << frame.max_data;
+    flow_controller_.UpdateSendWindowOffset(frame.max_data);
+    return;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id),
+                               version()) == READ_UNIDIRECTIONAL) {
+    connection()->CloseConnection(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (ShouldProcessFrameByPendingStream(WINDOW_UPDATE_FRAME, stream_id)) {
+    PendingStreamOnWindowUpdateFrame(frame);
+    return;
+  }
+
+  QuicStream* stream = GetOrCreateStream(stream_id);
+  if (stream != nullptr) {
+    stream->OnWindowUpdateFrame(frame);
+  }
+}
+
+void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
+  // TODO(rjshade): Compare our flow control receive windows for specified
+  //                streams: if we have a large window then maybe something
+  //                had gone wrong with the flow control accounting.
+  QUIC_DLOG(INFO) << ENDPOINT << "Received BLOCKED frame with stream id: "
+                  << frame.stream_id;
+}
+
+bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
+                                            uint64_t previous_bytes_written,
+                                            bool previous_fin_sent) {
+  if (  // Stream should not be closed.
+      !stream->write_side_closed() &&
+      // Not connection flow control blocked.
+      !flow_controller_.IsBlocked() &&
+      // Detect lack of forward progress.
+      previous_bytes_written == stream->stream_bytes_written() &&
+      previous_fin_sent == stream->fin_sent()) {
+    stream->set_busy_counter(stream->busy_counter() + 1);
+    QUIC_DVLOG(1) << ENDPOINT << "Suspected busy loop on stream id "
+                  << stream->id() << " stream_bytes_written "
+                  << stream->stream_bytes_written() << " fin "
+                  << stream->fin_sent() << " count " << stream->busy_counter();
+    // Wait a few iterations before firing, the exact count is
+    // arbitrary, more than a few to cover a few test-only false
+    // positives.
+    if (stream->busy_counter() > 20) {
+      QUIC_LOG(ERROR) << ENDPOINT << "Detected busy loop on stream id "
+                      << stream->id() << " stream_bytes_written "
+                      << stream->stream_bytes_written() << " fin "
+                      << stream->fin_sent();
+      return false;
+    }
+  } else {
+    stream->set_busy_counter(0);
+  }
+  return true;
+}
+
+bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const {
+  if (!stream->write_side_closed() && stream->HasBufferedData() &&
+      !stream->IsFlowControlBlocked() &&
+      !write_blocked_streams_.IsStreamBlocked(stream->id())) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "stream " << stream->id()
+                     << " has buffered " << stream->BufferedDataBytes()
+                     << " bytes, and is not flow control blocked, "
+                        "but it is not in the write block list.";
+    return false;
+  }
+  return true;
+}
+
+void QuicSession::OnCanWrite() {
+  if (connection_->framer().is_processing_packet()) {
+    // Do not write data in the middle of packet processing because rest
+    // frames in the packet may change the data to write. For example, lost
+    // data could be acknowledged. Also, connection is going to emit
+    // OnCanWrite signal post packet processing.
+    QUIC_BUG(session_write_mid_packet_processing)
+        << ENDPOINT << "Try to write mid packet processing.";
+    return;
+  }
+  if (!RetransmitLostData()) {
+    // Cannot finish retransmitting lost data, connection is write blocked.
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Cannot finish retransmitting lost data, connection is "
+                     "write blocked.";
+    return;
+  }
+  // We limit the number of writes to the number of pending streams. If more
+  // streams become pending, WillingAndAbleToWrite will be true, which will
+  // cause the connection to request resumption before yielding to other
+  // connections.
+  // If we are connection level flow control blocked, then only allow the
+  // crypto and headers streams to try writing as all other streams will be
+  // blocked.
+  size_t num_writes = flow_controller_.IsBlocked()
+                          ? write_blocked_streams_.NumBlockedSpecialStreams()
+                          : write_blocked_streams_.NumBlockedStreams();
+  if (num_writes == 0 && !control_frame_manager_.WillingToWrite() &&
+      datagram_queue_.empty() &&
+      (!QuicVersionUsesCryptoFrames(transport_version()) ||
+       !GetCryptoStream()->HasBufferedCryptoFrames())) {
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(connection_);
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+    if (crypto_stream->HasBufferedCryptoFrames()) {
+      crypto_stream->WriteBufferedCryptoFrames();
+    }
+    if (crypto_stream->HasBufferedCryptoFrames()) {
+      // Cannot finish writing buffered crypto frames, connection is write
+      // blocked.
+      return;
+    }
+  }
+  if (control_frame_manager_.WillingToWrite()) {
+    control_frame_manager_.OnCanWrite();
+  }
+  // TODO(b/147146815): this makes all datagrams go before stream data.  We
+  // should have a better priority scheme for this.
+  if (!datagram_queue_.empty()) {
+    size_t written = datagram_queue_.SendDatagrams();
+    QUIC_DVLOG(1) << ENDPOINT << "Sent " << written << " datagrams";
+    if (!datagram_queue_.empty()) {
+      return;
+    }
+  }
+  std::vector<QuicStreamId> last_writing_stream_ids;
+  for (size_t i = 0; i < num_writes; ++i) {
+    if (!(write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+          write_blocked_streams_.HasWriteBlockedDataStreams())) {
+      // Writing one stream removed another!? Something's broken.
+      QUIC_BUG(quic_bug_10866_1)
+          << "WriteBlockedStream is missing, num_writes: " << num_writes
+          << ", finished_writes: " << i
+          << ", connected: " << connection_->connected()
+          << ", connection level flow control blocked: "
+          << flow_controller_.IsBlocked();
+      for (QuicStreamId id : last_writing_stream_ids) {
+        QUIC_LOG(WARNING) << "last_writing_stream_id: " << id;
+      }
+      connection_->CloseConnection(QUIC_INTERNAL_ERROR,
+                                   "WriteBlockedStream is missing",
+                                   ConnectionCloseBehavior::SILENT_CLOSE);
+      return;
+    }
+    if (!CanWriteStreamData()) {
+      return;
+    }
+    currently_writing_stream_id_ = write_blocked_streams_.PopFront();
+    last_writing_stream_ids.push_back(currently_writing_stream_id_);
+    QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
+                  << currently_writing_stream_id_ << " from write-blocked list";
+    QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_);
+    if (stream != nullptr && !stream->IsFlowControlBlocked()) {
+      // If the stream can't write all bytes it'll re-add itself to the blocked
+      // list.
+      uint64_t previous_bytes_written = stream->stream_bytes_written();
+      bool previous_fin_sent = stream->fin_sent();
+      QUIC_DVLOG(1) << ENDPOINT << "stream " << stream->id()
+                    << " bytes_written " << previous_bytes_written << " fin "
+                    << previous_fin_sent;
+      stream->OnCanWrite();
+      QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
+      QUICHE_DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written,
+                                              previous_fin_sent));
+    }
+    currently_writing_stream_id_ = 0;
+  }
+}
+
+bool QuicSession::SendProbingData() {
+  if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
+          PROBING_RETRANSMISSION)) {
+    return true;
+  }
+  return false;
+}
+
+bool QuicSession::WillingAndAbleToWrite() const {
+  // Schedule a write when:
+  // 1) control frame manager has pending or new control frames, or
+  // 2) any stream has pending retransmissions, or
+  // 3) If the crypto or headers streams are blocked, or
+  // 4) connection is not flow control blocked and there are write blocked
+  // streams.
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    if (HasPendingHandshake()) {
+      return true;
+    }
+    if (!IsEncryptionEstablished()) {
+      return false;
+    }
+  }
+  if (control_frame_manager_.WillingToWrite() ||
+      !streams_with_pending_retransmission_.empty()) {
+    return true;
+  }
+  if (flow_controller_.IsBlocked()) {
+    if (VersionUsesHttp3(transport_version())) {
+      return false;
+    }
+    // Crypto and headers streams are not blocked by connection level flow
+    // control.
+    return write_blocked_streams_.HasWriteBlockedSpecialStream();
+  }
+  return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+         write_blocked_streams_.HasWriteBlockedDataStreams();
+}
+
+std::string QuicSession::GetStreamsInfoForLogging() const {
+  std::string info = absl::StrCat(
+      "num_active_streams: ", GetNumActiveStreams(),
+      ", num_pending_streams: ", pending_streams_size(),
+      ", num_outgoing_draining_streams: ", num_outgoing_draining_streams(),
+      " ");
+  // Log info for up to 5 streams.
+  size_t i = 5;
+  for (const auto& it : stream_map_) {
+    if (it.second->is_static()) {
+      continue;
+    }
+    // Calculate the stream creation delay.
+    const QuicTime::Delta delay =
+        connection_->clock()->ApproximateNow() - it.second->creation_time();
+    absl::StrAppend(
+        &info, "{", it.second->id(), ":", delay.ToDebuggingValue(), ";",
+        it.second->stream_bytes_written(), ",", it.second->fin_sent(), ",",
+        it.second->HasBufferedData(), ",", it.second->fin_buffered(), ";",
+        it.second->stream_bytes_read(), ",", it.second->fin_received(), "}");
+    --i;
+    if (i == 0) {
+      break;
+    }
+  }
+  return info;
+}
+
+bool QuicSession::HasPendingHandshake() const {
+  if (QuicVersionUsesCryptoFrames(transport_version())) {
+    return GetCryptoStream()->HasPendingCryptoRetransmission() ||
+           GetCryptoStream()->HasBufferedCryptoFrames();
+  }
+  return streams_with_pending_retransmission_.contains(
+             QuicUtils::GetCryptoStreamId(transport_version())) ||
+         write_blocked_streams_.IsStreamBlocked(
+             QuicUtils::GetCryptoStreamId(transport_version()));
+}
+
+void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                   const QuicSocketAddress& peer_address,
+                                   const QuicReceivedPacket& packet) {
+  QuicConnectionContextSwitcher cs(connection_->context());
+  connection_->ProcessUdpPacket(self_address, peer_address, packet);
+}
+
+QuicConsumedData QuicSession::WritevData(QuicStreamId id, size_t write_length,
+                                         QuicStreamOffset offset,
+                                         StreamSendingState state,
+                                         TransmissionType type,
+                                         EncryptionLevel level) {
+  QUICHE_DCHECK(connection_->connected())
+      << ENDPOINT << "Try to write stream data when connection is closed.";
+  if (!IsEncryptionEstablished() &&
+      !QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    // Do not let streams write without encryption. The calling stream will end
+    // up write blocked until OnCanWrite is next called.
+    if (was_zero_rtt_rejected_ && !OneRttKeysAvailable()) {
+      QUICHE_DCHECK(version().UsesTls() &&
+                    perspective() == Perspective::IS_CLIENT);
+      QUIC_DLOG(INFO) << ENDPOINT
+                      << "Suppress the write while 0-RTT gets rejected and "
+                         "1-RTT keys are not available. Version: "
+                      << ParsedQuicVersionToString(version());
+    } else if (version().UsesTls() || perspective() == Perspective::IS_SERVER) {
+      QUIC_BUG(quic_bug_10866_2)
+          << ENDPOINT << "Try to send data of stream " << id
+          << " before encryption is established. Version: "
+          << ParsedQuicVersionToString(version());
+    } else {
+      // In QUIC crypto, this could happen when the client sends full CHLO and
+      // 0-RTT request, then receives an inchoate REJ and sends an inchoate
+      // CHLO. The client then gets the ACK of the inchoate CHLO or the client
+      // gets the full REJ and needs to verify the proof (before it sends the
+      // full CHLO), such that there is no outstanding crypto data.
+      // Retransmission alarm fires in TLP mode which tries to retransmit the
+      // 0-RTT request (without encryption).
+      QUIC_DLOG(INFO) << ENDPOINT << "Try to send data of stream " << id
+                      << " before encryption is established.";
+    }
+    return QuicConsumedData(0, false);
+  }
+
+  SetTransmissionType(type);
+  QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
+
+  QuicConsumedData data =
+      connection_->SendStreamData(id, write_length, offset, state);
+  if (type == NOT_RETRANSMISSION) {
+    // This is new stream data.
+    write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
+  }
+
+  return data;
+}
+
+size_t QuicSession::SendCryptoData(EncryptionLevel level, size_t write_length,
+                                   QuicStreamOffset offset,
+                                   TransmissionType type) {
+  QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
+  if (!connection()->framer().HasEncrypterOfEncryptionLevel(level)) {
+    const std::string error_details = absl::StrCat(
+        "Try to send crypto data with missing keys of encryption level: ",
+        EncryptionLevelToString(level));
+    QUIC_BUG(quic_bug_10866_3) << ENDPOINT << error_details;
+    connection()->CloseConnection(
+        QUIC_MISSING_WRITE_KEYS, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return 0;
+  }
+  SetTransmissionType(type);
+  QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
+  const auto bytes_consumed =
+      connection_->SendCryptoData(level, write_length, offset);
+  return bytes_consumed;
+}
+
+void QuicSession::OnControlFrameManagerError(QuicErrorCode error_code,
+                                             std::string error_details) {
+  connection_->CloseConnection(
+      error_code, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+bool QuicSession::WriteControlFrame(const QuicFrame& frame,
+                                    TransmissionType type) {
+  QUICHE_DCHECK(connection()->connected())
+      << ENDPOINT << "Try to write control frames when connection is closed.";
+  if (!IsEncryptionEstablished()) {
+    // Suppress the write before encryption gets established.
+    return false;
+  }
+  SetTransmissionType(type);
+  QuicConnection::ScopedEncryptionLevelContext context(
+      connection(), GetEncryptionLevelToSendApplicationData());
+  return connection_->SendControlFrame(frame);
+}
+
+void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) {
+  QuicStream* stream = GetStream(id);
+  if (stream != nullptr && stream->is_static()) {
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Try to reset a static stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  if (stream != nullptr) {
+    stream->Reset(error);
+    return;
+  }
+
+  QuicConnection::ScopedPacketFlusher flusher(connection());
+  MaybeSendStopSendingFrame(id, QuicResetStreamError::FromInternal(error));
+  MaybeSendRstStreamFrame(id, QuicResetStreamError::FromInternal(error), 0);
+}
+
+void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
+                                          QuicResetStreamError error,
+                                          QuicStreamOffset bytes_written) {
+  if (!connection()->connected()) {
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version()) ||
+      QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
+                               version()) != READ_UNIDIRECTIONAL) {
+    control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
+  }
+
+  connection_->OnStreamReset(id, error.internal_code());
+}
+
+void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
+                                            QuicResetStreamError error) {
+  if (!connection()->connected()) {
+    return;
+  }
+  if (VersionHasIetfQuicFrames(transport_version()) &&
+      QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
+                               version()) != WRITE_UNIDIRECTIONAL) {
+    control_frame_manager_.WriteOrBufferStopSending(error, id);
+  }
+}
+
+void QuicSession::SendGoAway(QuicErrorCode error_code,
+                             const std::string& reason) {
+  // GOAWAY frame is not supported in IETF QUIC.
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
+  if (!IsEncryptionEstablished()) {
+    QUIC_CODE_COUNT(quic_goaway_before_encryption_established);
+    connection_->CloseConnection(
+        error_code, reason,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (transport_goaway_sent_) {
+    return;
+  }
+  transport_goaway_sent_ = true;
+
+  QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
+  control_frame_manager_.WriteOrBufferGoAway(
+      error_code,
+      QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
+          transport_version()),
+      reason);
+}
+
+void QuicSession::SendBlocked(QuicStreamId id) {
+  control_frame_manager_.WriteOrBufferBlocked(id);
+}
+
+void QuicSession::SendWindowUpdate(QuicStreamId id,
+                                   QuicStreamOffset byte_offset) {
+  control_frame_manager_.WriteOrBufferWindowUpdate(id, byte_offset);
+}
+
+void QuicSession::OnStreamError(QuicErrorCode error_code,
+                                std::string error_details) {
+  connection_->CloseConnection(
+      error_code, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicSession::OnStreamError(QuicErrorCode error_code,
+                                QuicIetfTransportErrorCodes ietf_error,
+                                std::string error_details) {
+  connection_->CloseConnection(
+      error_code, ietf_error, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
+                                 bool unidirectional) {
+  if (!is_configured_) {
+    QUIC_BUG(quic_bug_10866_5)
+        << "Try to send max streams before config negotiated.";
+    return;
+  }
+  control_frame_manager_.WriteOrBufferMaxStreams(stream_count, unidirectional);
+}
+
+void QuicSession::InsertLocallyClosedStreamsHighestOffset(
+    const QuicStreamId id, QuicStreamOffset offset) {
+  locally_closed_streams_highest_offset_[id] = offset;
+}
+
+void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
+  QUIC_DVLOG(1) << ENDPOINT << "Closing stream: " << stream_id;
+  StreamMap::iterator it = stream_map_.find(stream_id);
+  if (it == stream_map_.end()) {
+    QUIC_BUG(quic_bug_10866_6)
+        << ENDPOINT << "Stream is already closed: " << stream_id;
+    return;
+  }
+  QuicStream* stream = it->second.get();
+  StreamType type = stream->type();
+
+  const bool stream_waiting_for_acks = stream->IsWaitingForAcks();
+  if (stream_waiting_for_acks) {
+    // The stream needs to be kept alive because it's waiting for acks.
+    ++num_zombie_streams_;
+  } else {
+    closed_streams_.push_back(std::move(it->second));
+    stream_map_.erase(it);
+    // Do not retransmit data of a closed stream.
+    streams_with_pending_retransmission_.erase(stream_id);
+    if (!closed_streams_clean_up_alarm_->IsSet()) {
+      closed_streams_clean_up_alarm_->Set(
+          connection_->clock()->ApproximateNow());
+    }
+    QUIC_BUG_IF(
+        364846171_1,
+        connection_->packet_creator().HasPendingStreamFramesOfStream(stream_id))
+        << "Stream " << stream_id
+        << " gets closed while there are pending frames.";
+  }
+
+  if (!stream->HasReceivedFinalOffset()) {
+    // If we haven't received a FIN or RST for this stream, we need to keep
+    // track of the how many bytes the stream's flow controller believes it has
+    // received, for accurate connection level flow control accounting.
+    // If this is an outgoing stream, it is technically open from peer's
+    // perspective. Do not inform stream Id manager yet.
+    QUICHE_DCHECK(!stream->was_draining());
+    InsertLocallyClosedStreamsHighestOffset(
+        stream_id, stream->highest_received_byte_offset());
+    return;
+  }
+
+  const bool stream_was_draining = stream->was_draining();
+  QUIC_DVLOG_IF(1, stream_was_draining)
+      << ENDPOINT << "Stream " << stream_id << " was draining";
+  if (stream_was_draining) {
+    QUIC_BUG_IF(quic_bug_12435_4, num_draining_streams_ == 0);
+    --num_draining_streams_;
+    if (!IsIncomingStream(stream_id)) {
+      QUIC_BUG_IF(quic_bug_12435_5, num_outgoing_draining_streams_ == 0);
+      --num_outgoing_draining_streams_;
+    }
+    // Stream Id manager has been informed with draining streams.
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    stream_id_manager_.OnStreamClosed(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+  if (!connection_->connected()) {
+    return;
+  }
+  if (IsIncomingStream(stream_id)) {
+    // Stream Id manager is only interested in peer initiated stream IDs.
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      ietf_streamid_manager_.OnStreamClosed(stream_id);
+    }
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    OnCanCreateNewOutgoingStream(type != BIDIRECTIONAL);
+  }
+}
+
+void QuicSession::ClosePendingStream(QuicStreamId stream_id) {
+  QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  pending_stream_map_.erase(stream_id);
+  if (connection_->connected()) {
+    ietf_streamid_manager_.OnStreamClosed(stream_id);
+  }
+}
+
+bool QuicSession::ShouldProcessFrameByPendingStream(QuicFrameType type,
+                                                    QuicStreamId id) const {
+  return UsesPendingStreamForFrame(type, id) &&
+         stream_map_.find(id) == stream_map_.end();
+}
+
+void QuicSession::OnFinalByteOffsetReceived(
+    QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
+  auto it = locally_closed_streams_highest_offset_.find(stream_id);
+  if (it == locally_closed_streams_highest_offset_.end()) {
+    return;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Received final byte offset "
+                << final_byte_offset << " for stream " << stream_id;
+  QuicByteCount offset_diff = final_byte_offset - it->second;
+  if (flow_controller_.UpdateHighestReceivedOffset(
+          flow_controller_.highest_received_byte_offset() + offset_diff)) {
+    // If the final offset violates flow control, close the connection now.
+    if (flow_controller_.FlowControlViolation()) {
+      connection_->CloseConnection(
+          QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+          "Connection level flow control violation",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+  }
+
+  flow_controller_.AddBytesConsumed(offset_diff);
+  locally_closed_streams_highest_offset_.erase(it);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    stream_id_manager_.OnStreamClosed(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+  if (IsIncomingStream(stream_id)) {
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      ietf_streamid_manager_.OnStreamClosed(stream_id);
+    }
+  } else if (!VersionHasIetfQuicFrames(transport_version())) {
+    OnCanCreateNewOutgoingStream(false);
+  }
+}
+
+bool QuicSession::IsEncryptionEstablished() const {
+  if (GetCryptoStream() == nullptr) {
+    return false;
+  }
+  return GetCryptoStream()->encryption_established();
+}
+
+bool QuicSession::OneRttKeysAvailable() const {
+  if (GetCryptoStream() == nullptr) {
+    return false;
+  }
+  return GetCryptoStream()->one_rtt_keys_available();
+}
+
+void QuicSession::OnConfigNegotiated() {
+  // In versions with TLS, the configs will be set twice if 0-RTT is available.
+  // In the second config setting, 1-RTT keys are guaranteed to be available.
+  if (version().UsesTls() && is_configured_ &&
+      connection_->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+    QUIC_BUG(quic_bug_12435_6)
+        << ENDPOINT
+        << "1-RTT keys missing when config is negotiated for the second time.";
+    connection_->CloseConnection(
+        QUIC_INTERNAL_ERROR,
+        "1-RTT keys missing when config is negotiated for the second time.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "OnConfigNegotiated";
+  connection_->SetFromConfig(config_);
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    uint32_t max_streams = 0;
+    if (config_.HasReceivedMaxBidirectionalStreams()) {
+      max_streams = config_.ReceivedMaxBidirectionalStreams();
+    }
+    if (was_zero_rtt_rejected_ &&
+        max_streams <
+            ietf_streamid_manager_.outgoing_bidirectional_stream_count()) {
+      connection_->CloseConnection(
+          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new bidirectional "
+              "initial stream limit ",
+              max_streams, " is less than current open streams: ",
+              ietf_streamid_manager_.outgoing_bidirectional_stream_count()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Setting Bidirectional outgoing_max_streams_ to "
+                  << max_streams;
+    if (perspective_ == Perspective::IS_CLIENT &&
+        max_streams <
+            ietf_streamid_manager_.max_outgoing_bidirectional_streams()) {
+      connection_->CloseConnection(
+          was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                                 : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+          absl::StrCat(
+              was_zero_rtt_rejected_
+                  ? "Server rejected 0-RTT, aborting because "
+                  : "",
+              "new bidirectional limit ", max_streams,
+              " decreases the current limit: ",
+              ietf_streamid_manager_.max_outgoing_bidirectional_streams()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    if (ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+            max_streams)) {
+      OnCanCreateNewOutgoingStream(/*unidirectional = */ false);
+    }
+
+    max_streams = 0;
+    if (config_.HasReceivedMaxUnidirectionalStreams()) {
+      max_streams = config_.ReceivedMaxUnidirectionalStreams();
+    }
+
+    if (was_zero_rtt_rejected_ &&
+        max_streams <
+            ietf_streamid_manager_.outgoing_unidirectional_stream_count()) {
+      connection_->CloseConnection(
+          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new unidirectional "
+              "initial stream limit ",
+              max_streams, " is less than current open streams: ",
+              ietf_streamid_manager_.outgoing_unidirectional_stream_count()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+
+    if (max_streams <
+        ietf_streamid_manager_.max_outgoing_unidirectional_streams()) {
+      connection_->CloseConnection(
+          was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                                 : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+          absl::StrCat(
+              was_zero_rtt_rejected_
+                  ? "Server rejected 0-RTT, aborting because "
+                  : "",
+              "new unidirectional limit ", max_streams,
+              " decreases the current limit: ",
+              ietf_streamid_manager_.max_outgoing_unidirectional_streams()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Setting Unidirectional outgoing_max_streams_ to "
+                  << max_streams;
+    if (ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+            max_streams)) {
+      OnCanCreateNewOutgoingStream(/*unidirectional = */ true);
+    }
+  } else {
+    uint32_t max_streams = 0;
+    if (config_.HasReceivedMaxBidirectionalStreams()) {
+      max_streams = config_.ReceivedMaxBidirectionalStreams();
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Setting max_open_outgoing_streams_ to "
+                  << max_streams;
+    if (was_zero_rtt_rejected_ &&
+        max_streams < stream_id_manager_.num_open_outgoing_streams()) {
+      connection_->CloseConnection(
+          QUIC_INTERNAL_ERROR,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new stream limit ",
+              max_streams, " is less than current open streams: ",
+              stream_id_manager_.num_open_outgoing_streams()),
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return;
+    }
+    stream_id_manager_.set_max_open_outgoing_streams(max_streams);
+  }
+
+  if (perspective() == Perspective::IS_SERVER) {
+    if (config_.HasReceivedConnectionOptions()) {
+      // The following variations change the initial receive flow control
+      // window sizes.
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW6)) {
+        AdjustInitialFlowControlWindows(64 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW7)) {
+        AdjustInitialFlowControlWindows(128 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW8)) {
+        AdjustInitialFlowControlWindows(256 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW9)) {
+        AdjustInitialFlowControlWindows(512 * 1024);
+      }
+      if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFWA)) {
+        AdjustInitialFlowControlWindows(1024 * 1024);
+      }
+    }
+
+    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
+        config_.GetMaxBidirectionalStreamsToSend());
+    ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
+        config_.GetMaxUnidirectionalStreamsToSend());
+  } else {
+    // A small number of additional incoming streams beyond the limit should be
+    // allowed. This helps avoid early connection termination when FIN/RSTs for
+    // old streams are lost or arrive out of order.
+    // Use a minimum number of additional streams, or a percentage increase,
+    // whichever is larger.
+    uint32_t max_incoming_streams_to_send =
+        config_.GetMaxBidirectionalStreamsToSend();
+    uint32_t max_incoming_streams =
+        std::max(max_incoming_streams_to_send + kMaxStreamsMinimumIncrement,
+                 static_cast<uint32_t>(max_incoming_streams_to_send *
+                                       kMaxStreamsMultiplier));
+    stream_id_manager_.set_max_open_incoming_streams(max_incoming_streams);
+  }
+
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // When using IETF-style TLS transport parameters, inform existing streams
+    // of new flow-control limits.
+    if (config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
+      OnNewStreamOutgoingBidirectionalFlowControlWindow(
+          config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
+    }
+    if (config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
+      OnNewStreamIncomingBidirectionalFlowControlWindow(
+          config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
+    }
+    if (config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
+      OnNewStreamUnidirectionalFlowControlWindow(
+          config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
+    }
+  } else {  // The version uses Google QUIC Crypto.
+    if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
+      // Streams which were created before the SHLO was received (0-RTT
+      // requests) are now informed of the peer's initial flow control window.
+      OnNewStreamFlowControlWindow(
+          config_.ReceivedInitialStreamFlowControlWindowBytes());
+    }
+  }
+
+  if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) {
+    OnNewSessionFlowControlWindow(
+        config_.ReceivedInitialSessionFlowControlWindowBytes());
+  }
+
+  is_configured_ = true;
+  connection()->OnConfigNegotiated();
+
+  // Ask flow controllers to try again since the config could have unblocked us.
+  // Or if this session is configured on TLS enabled QUIC versions,
+  // attempt to retransmit 0-RTT data if there's any.
+  // TODO(fayang): consider removing this OnCanWrite call.
+  if (!connection_->framer().is_processing_packet() &&
+      (connection_->version().AllowsLowFlowControlLimits() ||
+       version().UsesTls())) {
+    QUIC_CODE_COUNT(quic_session_on_can_write_on_config_negotiated);
+    OnCanWrite();
+  }
+}
+
+absl::optional<std::string> QuicSession::OnAlpsData(
+    const uint8_t* /*alps_data*/, size_t /*alps_length*/) {
+  return absl::nullopt;
+}
+
+void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) {
+  const float session_window_multiplier =
+      config_.GetInitialStreamFlowControlWindowToSend()
+          ? static_cast<float>(
+                config_.GetInitialSessionFlowControlWindowToSend()) /
+                config_.GetInitialStreamFlowControlWindowToSend()
+          : 1.5;
+
+  QUIC_DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window;
+  config_.SetInitialStreamFlowControlWindowToSend(stream_window);
+
+  size_t session_window = session_window_multiplier * stream_window;
+  QUIC_DVLOG(1) << ENDPOINT << "Set session receive window to "
+                << session_window;
+  config_.SetInitialSessionFlowControlWindowToSend(session_window);
+  flow_controller_.UpdateReceiveWindowSize(session_window);
+  // Inform all existing streams about the new window.
+  for (auto const& kv : stream_map_) {
+    kv.second->UpdateReceiveWindowSize(stream_window);
+  }
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    GetMutableCryptoStream()->UpdateReceiveWindowSize(stream_window);
+  }
+}
+
+void QuicSession::HandleFrameOnNonexistentOutgoingStream(
+    QuicStreamId stream_id) {
+  QUICHE_DCHECK(!IsClosedStream(stream_id));
+  // Received a frame for a locally-created stream that is not currently
+  // active. This is an error.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    connection()->CloseConnection(
+        QUIC_HTTP_STREAM_WRONG_DIRECTION, "Data for nonexistent stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  connection()->CloseConnection(
+      QUIC_INVALID_STREAM_ID, "Data for nonexistent stream",
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicSession::HandleRstOnValidNonexistentStream(
+    const QuicRstStreamFrame& frame) {
+  // If the stream is neither originally in active streams nor created in
+  // GetOrCreateStream(), it could be a closed stream in which case its
+  // final received byte offset need to be updated.
+  if (IsClosedStream(frame.stream_id)) {
+    // The RST frame contains the final byte offset for the stream: we can now
+    // update the connection level flow controller if needed.
+    OnFinalByteOffsetReceived(frame.stream_id, frame.byte_offset);
+  }
+}
+
+void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
+  QUICHE_DCHECK(version().UsesQuicCrypto());
+  QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamFlowControlWindow " << new_window;
+  if (new_window < kMinimumFlowControlSendWindow) {
+    QUIC_LOG_FIRST_N(ERROR, 1)
+        << "Peer sent us an invalid stream flow control send window: "
+        << new_window << ", below minimum: " << kMinimumFlowControlSendWindow;
+    connection_->CloseConnection(
+        QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  // Inform all existing streams about the new window.
+  for (auto const& kv : stream_map_) {
+    QUIC_DVLOG(1) << ENDPOINT << "Informing stream " << kv.first
+                  << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(
+            new_window, /* was_zero_rtt_rejected = */ false)) {
+      return;
+    }
+  }
+  if (!QuicVersionUsesCryptoFrames(transport_version())) {
+    QUIC_DVLOG(1)
+        << ENDPOINT
+        << "Informing crypto stream of new stream flow control window "
+        << new_window;
+    GetMutableCryptoStream()->MaybeConfigSendWindowOffset(
+        new_window, /* was_zero_rtt_rejected = */ false);
+  }
+}
+
+void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
+    QuicStreamOffset new_window) {
+  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
+  QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamUnidirectionalFlowControlWindow "
+                << new_window;
+  // Inform all existing outgoing unidirectional streams about the new window.
+  for (auto const& kv : stream_map_) {
+    const QuicStreamId id = kv.first;
+    if (!version().HasIetfQuicFrames()) {
+      if (kv.second->type() == BIDIRECTIONAL) {
+        continue;
+      }
+    } else {
+      if (QuicUtils::IsBidirectionalStreamId(id, version())) {
+        continue;
+      }
+    }
+    if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
+                                       perspective())) {
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id
+                  << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
+                                                was_zero_rtt_rejected_)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
+    QuicStreamOffset new_window) {
+  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
+  QUIC_DVLOG(1) << ENDPOINT
+                << "OnNewStreamOutgoingBidirectionalFlowControlWindow "
+                << new_window;
+  // Inform all existing outgoing bidirectional streams about the new window.
+  for (auto const& kv : stream_map_) {
+    const QuicStreamId id = kv.first;
+    if (!version().HasIetfQuicFrames()) {
+      if (kv.second->type() != BIDIRECTIONAL) {
+        continue;
+      }
+    } else {
+      if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
+        continue;
+      }
+    }
+    if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
+                                       perspective())) {
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream "
+                  << id << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
+                                                was_zero_rtt_rejected_)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
+    QuicStreamOffset new_window) {
+  QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
+  QUIC_DVLOG(1) << ENDPOINT
+                << "OnNewStreamIncomingBidirectionalFlowControlWindow "
+                << new_window;
+  // Inform all existing incoming bidirectional streams about the new window.
+  for (auto const& kv : stream_map_) {
+    const QuicStreamId id = kv.first;
+    if (!version().HasIetfQuicFrames()) {
+      if (kv.second->type() != BIDIRECTIONAL) {
+        continue;
+      }
+    } else {
+      if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
+        continue;
+      }
+    }
+    if (QuicUtils::IsOutgoingStreamId(connection_->version(), id,
+                                      perspective())) {
+      continue;
+    }
+    QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream "
+                  << id << " of new stream flow control window " << new_window;
+    if (!kv.second->MaybeConfigSendWindowOffset(new_window,
+                                                was_zero_rtt_rejected_)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
+  QUIC_DVLOG(1) << ENDPOINT << "OnNewSessionFlowControlWindow " << new_window;
+
+  if (was_zero_rtt_rejected_ && new_window < flow_controller_.bytes_sent()) {
+    std::string error_details = absl::StrCat(
+        "Server rejected 0-RTT. Aborting because the client received session "
+        "flow control send window: ",
+        new_window,
+        ", which is below currently used: ", flow_controller_.bytes_sent());
+    QUIC_LOG(ERROR) << error_details;
+    connection_->CloseConnection(
+        QUIC_ZERO_RTT_UNRETRANSMITTABLE, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (!connection_->version().AllowsLowFlowControlLimits() &&
+      new_window < kMinimumFlowControlSendWindow) {
+    std::string error_details = absl::StrCat(
+        "Peer sent us an invalid session flow control send window: ",
+        new_window, ", below minimum: ", kMinimumFlowControlSendWindow);
+    QUIC_LOG_FIRST_N(ERROR, 1) << error_details;
+    connection_->CloseConnection(
+        QUIC_FLOW_CONTROL_INVALID_WINDOW, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (perspective_ == Perspective::IS_CLIENT &&
+      new_window < flow_controller_.send_window_offset()) {
+    // The client receives a lower limit than remembered, violating
+    // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
+    std::string error_details = absl::StrCat(
+        was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
+                               : "",
+        "new session max data ", new_window,
+        " decreases current limit: ", flow_controller_.send_window_offset());
+    QUIC_LOG(ERROR) << error_details;
+    connection_->CloseConnection(
+        was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                               : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+        error_details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  flow_controller_.UpdateSendWindowOffset(new_window);
+}
+
+bool QuicSession::OnNewDecryptionKeyAvailable(
+    EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
+    bool set_alternative_decrypter, bool latch_once_used) {
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
+      !connection()->framer().HasEncrypterOfEncryptionLevel(
+          QuicUtils::GetEncryptionLevel(
+              QuicUtils::GetPacketNumberSpace(level)))) {
+    // This should never happen because connection should never decrypt a packet
+    // while an ACK for it cannot be encrypted.
+    return false;
+  }
+  if (connection()->version().KnowsWhichDecrypterToUse()) {
+    connection()->InstallDecrypter(level, std::move(decrypter));
+    return true;
+  }
+  if (set_alternative_decrypter) {
+    connection()->SetAlternativeDecrypter(level, std::move(decrypter),
+                                          latch_once_used);
+    return true;
+  }
+  connection()->SetDecrypter(level, std::move(decrypter));
+  return true;
+}
+
+void QuicSession::OnNewEncryptionKeyAvailable(
+    EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
+  connection()->SetEncrypter(level, std::move(encrypter));
+  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
+    return;
+  }
+
+  bool reset_encryption_level = false;
+  if (IsEncryptionEstablished() && level == ENCRYPTION_HANDSHAKE) {
+    // ENCRYPTION_HANDSHAKE keys are only used for the handshake. If
+    // ENCRYPTION_ZERO_RTT keys exist, it is possible for a client to send
+    // stream data, which must not be sent at the ENCRYPTION_HANDSHAKE level.
+    // Therefore, we avoid setting the default encryption level to
+    // ENCRYPTION_HANDSHAKE.
+    reset_encryption_level = true;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
+  connection()->SetDefaultEncryptionLevel(level);
+  if (reset_encryption_level) {
+    connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  }
+  QUIC_BUG_IF(quic_bug_12435_7,
+              IsEncryptionEstablished() &&
+                  (connection()->encryption_level() == ENCRYPTION_INITIAL ||
+                   connection()->encryption_level() == ENCRYPTION_HANDSHAKE))
+      << "Encryption is established, but the encryption level " << level
+      << " does not support sending stream data";
+}
+
+void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
+  QUICHE_DCHECK_EQ(PROTOCOL_QUIC_CRYPTO,
+                   connection_->version().handshake_protocol);
+  QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
+  connection()->SetDefaultEncryptionLevel(level);
+
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      break;
+    case ENCRYPTION_ZERO_RTT:
+      if (perspective() == Perspective::IS_CLIENT) {
+        // Retransmit old 0-RTT data (if any) with the new 0-RTT keys, since
+        // they can't be decrypted by the server.
+        connection_->MarkZeroRttPacketsForRetransmission(0);
+        if (!connection_->framer().is_processing_packet()) {
+          // TODO(fayang): consider removing this OnCanWrite call.
+          // Given any streams blocked by encryption a chance to write.
+          QUIC_CODE_COUNT(
+              quic_session_on_can_write_set_default_encryption_level);
+          OnCanWrite();
+        }
+      }
+      break;
+    case ENCRYPTION_HANDSHAKE:
+      break;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG_IF(quic_bug_12435_8, !config_.negotiated())
+          << ENDPOINT << "Handshake confirmed without parameter negotiation.";
+      connection()->mutable_stats().handshake_completion_time =
+          connection()->clock()->ApproximateNow();
+      break;
+    default:
+      QUIC_BUG(quic_bug_10866_7) << "Unknown encryption level: " << level;
+  }
+}
+
+void QuicSession::OnTlsHandshakeComplete() {
+  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, connection_->version().handshake_protocol);
+  QUIC_BUG_IF(quic_bug_12435_9,
+              !GetCryptoStream()->crypto_negotiated_params().cipher_suite)
+      << ENDPOINT << "Handshake completes without cipher suite negotiation.";
+  QUIC_BUG_IF(quic_bug_12435_10, !config_.negotiated())
+      << ENDPOINT << "Handshake completes without parameter negotiation.";
+  connection()->mutable_stats().handshake_completion_time =
+      connection()->clock()->ApproximateNow();
+  if (connection()->version().UsesTls() &&
+      perspective_ == Perspective::IS_SERVER) {
+    // Server sends HANDSHAKE_DONE to signal confirmation of the handshake
+    // to the client.
+    control_frame_manager_.WriteOrBufferHandshakeDone();
+    if (connection()->version().HasIetfQuicFrames()) {
+      MaybeSendAddressToken();
+    }
+  }
+}
+
+bool QuicSession::MaybeSendAddressToken() {
+  QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER &&
+                connection()->version().HasIetfQuicFrames());
+  absl::optional<CachedNetworkParameters> cached_network_params =
+      GenerateCachedNetworkParameters();
+
+  std::string address_token = GetCryptoStream()->GetAddressToken(
+      cached_network_params.has_value() ? &cached_network_params.value()
+                                        : nullptr);
+  if (address_token.empty()) {
+    return false;
+  }
+  const size_t buf_len = address_token.length() + 1;
+  auto buffer = std::make_unique<char[]>(buf_len);
+  QuicDataWriter writer(buf_len, buffer.get());
+  // Add |kAddressTokenPrefix| for token sent in NEW_TOKEN frame.
+  writer.WriteUInt8(kAddressTokenPrefix);
+  writer.WriteBytes(address_token.data(), address_token.length());
+  control_frame_manager_.WriteOrBufferNewToken(
+      absl::string_view(buffer.get(), buf_len));
+  if (cached_network_params.has_value()) {
+    connection()->OnSendConnectionState(*cached_network_params);
+  }
+  return true;
+}
+
+void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
+  if (!connection()->version().KnowsWhichDecrypterToUse()) {
+    return;
+  }
+  connection()->RemoveDecrypter(level);
+}
+
+void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
+  QUIC_DLOG(INFO) << ENDPOINT << "Discarding " << level << " keys";
+  if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    connection()->RemoveEncrypter(level);
+  }
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      NeuterUnencryptedData();
+      break;
+    case ENCRYPTION_HANDSHAKE:
+      NeuterHandshakeData();
+      break;
+    case ENCRYPTION_ZERO_RTT:
+      break;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG(quic_bug_10866_8)
+          << ENDPOINT << "Discarding 1-RTT keys is not allowed";
+      break;
+    default:
+      QUIC_BUG(quic_bug_10866_9)
+          << ENDPOINT
+          << "Cannot discard keys for unknown encryption level: " << level;
+  }
+}
+
+void QuicSession::NeuterHandshakeData() {
+  GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(
+      ENCRYPTION_HANDSHAKE);
+  connection()->OnHandshakeComplete();
+}
+
+void QuicSession::OnZeroRttRejected(int reason) {
+  was_zero_rtt_rejected_ = true;
+  connection_->MarkZeroRttPacketsForRetransmission(reason);
+  if (connection_->encryption_level() == ENCRYPTION_FORWARD_SECURE) {
+    QUIC_BUG(quic_bug_10866_10)
+        << "1-RTT keys already available when 0-RTT is rejected.";
+    connection_->CloseConnection(
+        QUIC_INTERNAL_ERROR,
+        "1-RTT keys already available when 0-RTT is rejected.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+}
+
+bool QuicSession::FillTransportParameters(TransportParameters* params) {
+  if (version().UsesTls()) {
+    if (perspective() == Perspective::IS_SERVER) {
+      config_.SetOriginalConnectionIdToSend(
+          connection_->GetOriginalDestinationConnectionId());
+      config_.SetInitialSourceConnectionIdToSend(connection_->connection_id());
+    } else {
+      config_.SetInitialSourceConnectionIdToSend(
+          connection_->client_connection_id());
+    }
+  }
+  return config_.FillTransportParameters(params);
+}
+
+QuicErrorCode QuicSession::ProcessTransportParameters(
+    const TransportParameters& params, bool is_resumption,
+    std::string* error_details) {
+  return config_.ProcessTransportParameters(params, is_resumption,
+                                            error_details);
+}
+
+void QuicSession::OnHandshakeCallbackDone() {
+  if (!connection_->connected()) {
+    return;
+  }
+
+  if (!connection()->is_processing_packet()) {
+    connection()->MaybeProcessUndecryptablePackets();
+  }
+}
+
+bool QuicSession::PacketFlusherAttached() const {
+  QUICHE_DCHECK(connection_->connected());
+  return connection()->packet_creator().PacketFlusherAttached();
+}
+
+void QuicSession::OnCryptoHandshakeMessageSent(
+    const CryptoHandshakeMessage& /*message*/) {}
+
+void QuicSession::OnCryptoHandshakeMessageReceived(
+    const CryptoHandshakeMessage& /*message*/) {}
+
+void QuicSession::RegisterStreamPriority(
+    QuicStreamId id, bool is_static,
+    const spdy::SpdyStreamPrecedence& precedence) {
+  write_blocked_streams()->RegisterStream(id, is_static, precedence);
+}
+
+void QuicSession::UnregisterStreamPriority(QuicStreamId id, bool is_static) {
+  write_blocked_streams()->UnregisterStream(id, is_static);
+}
+
+void QuicSession::UpdateStreamPriority(
+    QuicStreamId id, const spdy::SpdyStreamPrecedence& new_precedence) {
+  write_blocked_streams()->UpdateStreamPriority(id, new_precedence);
+}
+
+QuicConfig* QuicSession::config() { return &config_; }
+
+void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
+  QuicStreamId stream_id = stream->id();
+  bool is_static = stream->is_static();
+  QUIC_DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size()
+                << ". activating stream " << stream_id;
+  QUICHE_DCHECK(!stream_map_.contains(stream_id));
+  stream_map_[stream_id] = std::move(stream);
+  if (is_static) {
+    ++num_static_streams_;
+    return;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Do not inform stream ID manager of static streams.
+    stream_id_manager_.ActivateStream(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+}
+
+QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetNextOutgoingBidirectionalStreamId();
+  }
+  return stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetNextOutgoingUnidirectionalStreamId();
+  }
+  return stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
+  if (liveness_testing_in_progress_) {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective());
+    return false;
+  }
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    if (!stream_id_manager_.CanOpenNextOutgoingStream()) {
+      return false;
+    }
+  } else {
+    if (!ietf_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) {
+      if (is_configured_) {
+        // Send STREAM_BLOCKED after config negotiated.
+        control_frame_manager_.WriteOrBufferStreamsBlocked(
+            ietf_streamid_manager_.max_outgoing_bidirectional_streams(),
+            /*unidirectional=*/false);
+      }
+      return false;
+    }
+  }
+  if (perspective() == Perspective::IS_CLIENT &&
+      connection_->MaybeTestLiveness()) {
+    // Now is relatively close to the idle timeout having the risk that requests
+    // could be discarded at the server.
+    liveness_testing_in_progress_ = true;
+    return false;
+  }
+  return true;
+}
+
+bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return stream_id_manager_.CanOpenNextOutgoingStream();
+  }
+  if (ietf_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) {
+    return true;
+  }
+  if (is_configured_) {
+    // Send STREAM_BLOCKED after config negotiated.
+    control_frame_manager_.WriteOrBufferStreamsBlocked(
+        ietf_streamid_manager_.max_outgoing_unidirectional_streams(),
+        /*unidirectional=*/true);
+  }
+  return false;
+}
+
+QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams()
+    const {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  return ietf_streamid_manager_.advertised_max_incoming_bidirectional_streams();
+}
+
+QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
+  QUICHE_DCHECK(!pending_stream_map_.contains(stream_id));
+  if (QuicUtils::IsCryptoStreamId(transport_version(), stream_id)) {
+    return GetMutableCryptoStream();
+  }
+
+  StreamMap::iterator it = stream_map_.find(stream_id);
+  if (it != stream_map_.end()) {
+    return it->second->IsZombie() ? nullptr : it->second.get();
+  }
+
+  if (IsClosedStream(stream_id)) {
+    return nullptr;
+  }
+
+  if (!IsIncomingStream(stream_id)) {
+    HandleFrameOnNonexistentOutgoingStream(stream_id);
+    return nullptr;
+  }
+
+  // TODO(fkastenholz): If we are creating a new stream and we have sent a
+  // goaway, we should ignore the stream creation. Need to add code to A) test
+  // if goaway was sent ("if (transport_goaway_sent_)") and B) reject stream
+  // creation ("return nullptr")
+
+  if (!MaybeIncreaseLargestPeerStreamId(stream_id)) {
+    return nullptr;
+  }
+
+  if (!VersionHasIetfQuicFrames(transport_version()) &&
+      !stream_id_manager_.CanOpenIncomingStream()) {
+    // Refuse to open the stream.
+    ResetStream(stream_id, QUIC_REFUSED_STREAM);
+    return nullptr;
+  }
+
+  return CreateIncomingStream(stream_id);
+}
+
+void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) {
+  QUICHE_DCHECK(stream_map_.contains(stream_id));
+  QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    ietf_streamid_manager_.OnStreamClosed(stream_id);
+  } else {
+    stream_id_manager_.OnStreamClosed(
+        /*is_incoming=*/IsIncomingStream(stream_id));
+  }
+  ++num_draining_streams_;
+  if (!IsIncomingStream(stream_id)) {
+    ++num_outgoing_draining_streams_;
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      OnCanCreateNewOutgoingStream(unidirectional);
+    }
+  }
+}
+
+bool QuicSession::MaybeIncreaseLargestPeerStreamId(
+    const QuicStreamId stream_id) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    std::string error_details;
+    if (ietf_streamid_manager_.MaybeIncreaseLargestPeerStreamId(
+            stream_id, &error_details)) {
+      return true;
+    }
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, error_details,
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  if (!stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id)) {
+    connection()->CloseConnection(
+        QUIC_TOO_MANY_AVAILABLE_STREAMS,
+        absl::StrCat(stream_id, " exceeds available streams ",
+                     stream_id_manager_.MaxAvailableStreams()),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return false;
+  }
+  return true;
+}
+
+bool QuicSession::ShouldYield(QuicStreamId stream_id) {
+  if (stream_id == currently_writing_stream_id_) {
+    return false;
+  }
+  return write_blocked_streams()->ShouldYield(stream_id);
+}
+
+PendingStream* QuicSession::GetOrCreatePendingStream(QuicStreamId stream_id) {
+  auto it = pending_stream_map_.find(stream_id);
+  if (it != pending_stream_map_.end()) {
+    return it->second.get();
+  }
+
+  if (IsClosedStream(stream_id) ||
+      !MaybeIncreaseLargestPeerStreamId(stream_id)) {
+    return nullptr;
+  }
+
+  auto pending = std::make_unique<PendingStream>(stream_id, this);
+  PendingStream* unowned_pending = pending.get();
+  pending_stream_map_[stream_id] = std::move(pending);
+  return unowned_pending;
+}
+
+void QuicSession::set_largest_peer_created_stream_id(
+    QuicStreamId largest_peer_created_stream_id) {
+  QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
+  stream_id_manager_.set_largest_peer_created_stream_id(
+      largest_peer_created_stream_id);
+}
+
+QuicStreamId QuicSession::GetLargestPeerCreatedStreamId(
+    bool unidirectional) const {
+  // This method is only used in IETF QUIC.
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  return ietf_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional);
+}
+
+void QuicSession::DeleteConnection() {
+  if (connection_) {
+    delete connection_;
+    connection_ = nullptr;
+  }
+}
+
+bool QuicSession::MaybeSetStreamPriority(
+    QuicStreamId stream_id, const spdy::SpdyStreamPrecedence& precedence) {
+  auto active_stream = stream_map_.find(stream_id);
+  if (active_stream != stream_map_.end()) {
+    active_stream->second->SetPriority(precedence);
+    return true;
+  }
+
+  return false;
+}
+
+bool QuicSession::IsClosedStream(QuicStreamId id) {
+  QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
+  if (IsOpenStream(id)) {
+    // Stream is active
+    return false;
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return !ietf_streamid_manager_.IsAvailableStream(id);
+  }
+
+  return !stream_id_manager_.IsAvailableStream(id);
+}
+
+bool QuicSession::IsOpenStream(QuicStreamId id) {
+  QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
+  const StreamMap::iterator it = stream_map_.find(id);
+  if (it != stream_map_.end()) {
+    return !it->second->IsZombie();
+  }
+  if (pending_stream_map_.contains(id) ||
+      QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    // Stream is active
+    return true;
+  }
+  return false;
+}
+
+bool QuicSession::IsStaticStream(QuicStreamId id) const {
+  auto it = stream_map_.find(id);
+  if (it == stream_map_.end()) {
+    return false;
+  }
+  return it->second->is_static();
+}
+
+size_t QuicSession::GetNumActiveStreams() const {
+  QUICHE_DCHECK_GE(
+      static_cast<QuicStreamCount>(stream_map_.size()),
+      num_static_streams_ + num_draining_streams_ + num_zombie_streams_);
+  return stream_map_.size() - num_draining_streams_ - num_static_streams_ -
+         num_zombie_streams_;
+}
+
+void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
+  if (GetOrCreateStream(id) == nullptr) {
+    QUIC_BUG(quic_bug_10866_11)
+        << "Marking unknown stream " << id << " blocked.";
+    QUIC_LOG_FIRST_N(ERROR, 2) << QuicStackTrace();
+  }
+
+  QUIC_DVLOG(1) << ENDPOINT << "Adding stream " << id
+                << " to write-blocked list";
+
+  write_blocked_streams_.AddStream(id);
+}
+
+bool QuicSession::HasDataToWrite() const {
+  return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+         write_blocked_streams_.HasWriteBlockedDataStreams() ||
+         connection_->HasQueuedData() ||
+         !streams_with_pending_retransmission_.empty() ||
+         control_frame_manager_.WillingToWrite();
+}
+
+void QuicSession::OnAckNeedsRetransmittableFrame() {
+  flow_controller_.SendWindowUpdate();
+}
+
+void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) {
+  control_frame_manager_.WriteOrBufferAckFrequency(frame);
+}
+
+void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) {
+  // Count NEW_CONNECTION_ID frames sent to client.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 1, 6);
+  control_frame_manager_.WriteOrBufferNewConnectionId(
+      frame.connection_id, frame.sequence_number, frame.retire_prior_to,
+      frame.stateless_reset_token);
+}
+
+void QuicSession::SendRetireConnectionId(uint64_t sequence_number) {
+  // Count RETIRE_CONNECTION_ID frames sent to client.
+  QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 2, 6);
+  control_frame_manager_.WriteOrBufferRetireConnectionId(sequence_number);
+}
+
+void QuicSession::OnServerConnectionIdIssued(
+    const QuicConnectionId& server_connection_id) {
+  if (visitor_) {
+    visitor_->OnNewConnectionIdSent(
+        connection_->GetOneActiveServerConnectionId(), server_connection_id);
+  }
+}
+
+void QuicSession::OnServerConnectionIdRetired(
+    const QuicConnectionId& server_connection_id) {
+  if (visitor_) {
+    visitor_->OnConnectionIdRetired(server_connection_id);
+  }
+}
+
+bool QuicSession::IsConnectionFlowControlBlocked() const {
+  return flow_controller_.IsBlocked();
+}
+
+bool QuicSession::IsStreamFlowControlBlocked() {
+  for (auto const& kv : stream_map_) {
+    if (kv.second->IsFlowControlBlocked()) {
+      return true;
+    }
+  }
+  if (!QuicVersionUsesCryptoFrames(transport_version()) &&
+      GetMutableCryptoStream()->IsFlowControlBlocked()) {
+    return true;
+  }
+  return false;
+}
+
+size_t QuicSession::MaxAvailableBidirectionalStreams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
+  }
+  return stream_id_manager_.MaxAvailableStreams();
+}
+
+size_t QuicSession::MaxAvailableUnidirectionalStreams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
+  }
+  return stream_id_manager_.MaxAvailableStreams();
+}
+
+bool QuicSession::IsIncomingStream(QuicStreamId id) const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return !QuicUtils::IsOutgoingStreamId(version(), id, perspective_);
+  }
+  return stream_id_manager_.IsIncomingStream(id);
+}
+
+void QuicSession::MaybeCloseZombieStream(QuicStreamId id) {
+  auto it = stream_map_.find(id);
+  if (it == stream_map_.end()) {
+    return;
+  }
+  --num_zombie_streams_;
+  closed_streams_.push_back(std::move(it->second));
+  stream_map_.erase(it);
+
+  if (!closed_streams_clean_up_alarm_->IsSet()) {
+    closed_streams_clean_up_alarm_->Set(connection_->clock()->ApproximateNow());
+  }
+  // Do not retransmit data of a closed stream.
+  streams_with_pending_retransmission_.erase(id);
+  QUIC_BUG_IF(364846171_2,
+              connection_->packet_creator().HasPendingStreamFramesOfStream(id))
+      << "Stream " << id << " gets closed while there are pending frames.";
+}
+
+QuicStream* QuicSession::GetStream(QuicStreamId id) const {
+  auto active_stream = stream_map_.find(id);
+  if (active_stream != stream_map_.end()) {
+    return active_stream->second.get();
+  }
+
+  if (QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+    return const_cast<QuicCryptoStream*>(GetCryptoStream());
+  }
+
+  return nullptr;
+}
+
+QuicStream* QuicSession::GetActiveStream(QuicStreamId id) const {
+  auto stream = stream_map_.find(id);
+  if (stream != stream_map_.end() && !stream->second->is_static()) {
+    return stream->second.get();
+  }
+  return nullptr;
+}
+
+bool QuicSession::OnFrameAcked(const QuicFrame& frame,
+                               QuicTime::Delta ack_delay_time,
+                               QuicTime receive_timestamp) {
+  if (frame.type == MESSAGE_FRAME) {
+    OnMessageAcked(frame.message_frame->message_id, receive_timestamp);
+    return true;
+  }
+  if (frame.type == CRYPTO_FRAME) {
+    return GetMutableCryptoStream()->OnCryptoFrameAcked(*frame.crypto_frame,
+                                                        ack_delay_time);
+  }
+  if (frame.type != STREAM_FRAME) {
+    return control_frame_manager_.OnControlFrameAcked(frame);
+  }
+  bool new_stream_data_acked = false;
+  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+  // Stream can already be reset when sent frame gets acked.
+  if (stream != nullptr) {
+    QuicByteCount newly_acked_length = 0;
+    new_stream_data_acked = stream->OnStreamFrameAcked(
+        frame.stream_frame.offset, frame.stream_frame.data_length,
+        frame.stream_frame.fin, ack_delay_time, receive_timestamp,
+        &newly_acked_length);
+    if (!stream->HasPendingRetransmission()) {
+      streams_with_pending_retransmission_.erase(stream->id());
+    }
+  }
+  return new_stream_data_acked;
+}
+
+void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
+  QuicStream* stream = GetStream(frame.stream_id);
+  if (stream == nullptr) {
+    QUIC_BUG(quic_bug_10866_12)
+        << "Stream: " << frame.stream_id << " is closed when " << frame
+        << " is retransmitted.";
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, "Attempt to retransmit frame of a closed stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length,
+                                     frame.fin);
+}
+
+void QuicSession::OnFrameLost(const QuicFrame& frame) {
+  if (frame.type == MESSAGE_FRAME) {
+    OnMessageLost(frame.message_frame->message_id);
+    return;
+  }
+  if (frame.type == CRYPTO_FRAME) {
+    GetMutableCryptoStream()->OnCryptoFrameLost(frame.crypto_frame);
+    return;
+  }
+  if (frame.type != STREAM_FRAME) {
+    control_frame_manager_.OnControlFrameLost(frame);
+    return;
+  }
+  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+  if (stream == nullptr) {
+    return;
+  }
+  stream->OnStreamFrameLost(frame.stream_frame.offset,
+                            frame.stream_frame.data_length,
+                            frame.stream_frame.fin);
+  if (stream->HasPendingRetransmission() &&
+      !streams_with_pending_retransmission_.contains(
+          frame.stream_frame.stream_id)) {
+    streams_with_pending_retransmission_.insert(
+        std::make_pair(frame.stream_frame.stream_id, true));
+  }
+}
+
+bool QuicSession::RetransmitFrames(const QuicFrames& frames,
+                                   TransmissionType type) {
+  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
+  for (const QuicFrame& frame : frames) {
+    if (frame.type == MESSAGE_FRAME) {
+      // Do not retransmit MESSAGE frames.
+      continue;
+    }
+    if (frame.type == CRYPTO_FRAME) {
+      const bool data_retransmitted =
+          GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type);
+      if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted) &&
+          !data_retransmitted) {
+        return false;
+      }
+      continue;
+    }
+    if (frame.type != STREAM_FRAME) {
+      if (!control_frame_manager_.RetransmitControlFrame(frame, type)) {
+        return false;
+      }
+      continue;
+    }
+    QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+    if (stream != nullptr &&
+        !stream->RetransmitStreamData(frame.stream_frame.offset,
+                                      frame.stream_frame.data_length,
+                                      frame.stream_frame.fin, type)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const {
+  if (frame.type == MESSAGE_FRAME) {
+    return false;
+  }
+  if (frame.type == CRYPTO_FRAME) {
+    return GetCryptoStream()->IsFrameOutstanding(
+        frame.crypto_frame->level, frame.crypto_frame->offset,
+        frame.crypto_frame->data_length);
+  }
+  if (frame.type != STREAM_FRAME) {
+    return control_frame_manager_.IsControlFrameOutstanding(frame);
+  }
+  QuicStream* stream = GetStream(frame.stream_frame.stream_id);
+  return stream != nullptr &&
+         stream->IsStreamFrameOutstanding(frame.stream_frame.offset,
+                                          frame.stream_frame.data_length,
+                                          frame.stream_frame.fin);
+}
+
+bool QuicSession::HasUnackedCryptoData() const {
+  const QuicCryptoStream* crypto_stream = GetCryptoStream();
+  return crypto_stream->IsWaitingForAcks() || crypto_stream->HasBufferedData();
+}
+
+bool QuicSession::HasUnackedStreamData() const {
+  for (const auto& it : stream_map_) {
+    if (it.second->IsWaitingForAcks()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+HandshakeState QuicSession::GetHandshakeState() const {
+  return GetCryptoStream()->GetHandshakeState();
+}
+
+WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
+                                                   QuicStreamOffset offset,
+                                                   QuicByteCount data_length,
+                                                   QuicDataWriter* writer) {
+  QuicStream* stream = GetStream(id);
+  if (stream == nullptr) {
+    // This causes the connection to be closed because of failed to serialize
+    // packet.
+    QUIC_BUG(quic_bug_10866_13)
+        << "Stream " << id << " does not exist when trying to write data."
+        << " version:" << transport_version();
+    return STREAM_MISSING;
+  }
+  if (stream->WriteStreamData(offset, data_length, writer)) {
+    return WRITE_SUCCESS;
+  }
+  return WRITE_FAILED;
+}
+
+bool QuicSession::WriteCryptoData(EncryptionLevel level,
+                                  QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  QuicDataWriter* writer) {
+  return GetMutableCryptoStream()->WriteCryptoFrame(level, offset, data_length,
+                                                    writer);
+}
+
+StatelessResetToken QuicSession::GetStatelessResetToken() const {
+  return QuicUtils::GenerateStatelessResetToken(connection_->connection_id());
+}
+
+bool QuicSession::CanWriteStreamData() const {
+  // Don't write stream data if there are queued data packets.
+  if (connection_->HasQueuedPackets()) {
+    return false;
+  }
+  // Immediately write handshake data.
+  if (HasPendingHandshake()) {
+    return true;
+  }
+  return connection_->CanWrite(HAS_RETRANSMITTABLE_DATA);
+}
+
+bool QuicSession::RetransmitLostData() {
+  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
+  // Retransmit crypto data first.
+  bool uses_crypto_frames = QuicVersionUsesCryptoFrames(transport_version());
+  QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+  if (uses_crypto_frames && crypto_stream->HasPendingCryptoRetransmission()) {
+    crypto_stream->WritePendingCryptoRetransmission();
+  }
+  // Retransmit crypto data in stream 1 frames (version < 47).
+  if (!uses_crypto_frames &&
+      streams_with_pending_retransmission_.contains(
+          QuicUtils::GetCryptoStreamId(transport_version()))) {
+    // Retransmit crypto data first.
+    QuicStream* crypto_stream =
+        GetStream(QuicUtils::GetCryptoStreamId(transport_version()));
+    crypto_stream->OnCanWrite();
+    QUICHE_DCHECK(CheckStreamWriteBlocked(crypto_stream));
+    if (crypto_stream->HasPendingRetransmission()) {
+      // Connection is write blocked.
+      return false;
+    } else {
+      streams_with_pending_retransmission_.erase(
+          QuicUtils::GetCryptoStreamId(transport_version()));
+    }
+  }
+  if (control_frame_manager_.HasPendingRetransmission()) {
+    control_frame_manager_.OnCanWrite();
+    if (control_frame_manager_.HasPendingRetransmission()) {
+      return false;
+    }
+  }
+  while (!streams_with_pending_retransmission_.empty()) {
+    if (!CanWriteStreamData()) {
+      break;
+    }
+    // Retransmit lost data on headers and data streams.
+    const QuicStreamId id = streams_with_pending_retransmission_.begin()->first;
+    QuicStream* stream = GetStream(id);
+    if (stream != nullptr) {
+      stream->OnCanWrite();
+      QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
+      if (stream->HasPendingRetransmission()) {
+        // Connection is write blocked.
+        break;
+      } else if (!streams_with_pending_retransmission_.empty() &&
+                 streams_with_pending_retransmission_.begin()->first == id) {
+        // Retransmit lost data may cause connection close. If this stream
+        // has not yet sent fin, a RST_STREAM will be sent and it will be
+        // removed from streams_with_pending_retransmission_.
+        streams_with_pending_retransmission_.pop_front();
+      }
+    } else {
+      QUIC_BUG(quic_bug_10866_14)
+          << "Try to retransmit data of a closed stream";
+      streams_with_pending_retransmission_.pop_front();
+    }
+  }
+
+  return streams_with_pending_retransmission_.empty();
+}
+
+void QuicSession::NeuterUnencryptedData() {
+  QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+  crypto_stream->NeuterUnencryptedStreamData();
+  if (!crypto_stream->HasPendingRetransmission() &&
+      !QuicVersionUsesCryptoFrames(transport_version())) {
+    streams_with_pending_retransmission_.erase(
+        QuicUtils::GetCryptoStreamId(transport_version()));
+  }
+  connection_->NeuterUnencryptedPackets();
+}
+
+void QuicSession::SetTransmissionType(TransmissionType type) {
+  connection_->SetTransmissionType(type);
+}
+
+MessageResult QuicSession::SendMessage(
+    absl::Span<quiche::QuicheMemSlice> message) {
+  return SendMessage(message, /*flush=*/false);
+}
+
+MessageResult QuicSession::SendMessage(quiche::QuicheMemSlice message) {
+  return SendMessage(absl::MakeSpan(&message, 1), /*flush=*/false);
+}
+
+MessageResult QuicSession::SendMessage(
+    absl::Span<quiche::QuicheMemSlice> message, bool flush) {
+  QUICHE_DCHECK(connection_->connected())
+      << ENDPOINT << "Try to write messages when connection is closed.";
+  if (!IsEncryptionEstablished()) {
+    return {MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0};
+  }
+  QuicConnection::ScopedEncryptionLevelContext context(
+      connection(), GetEncryptionLevelToSendApplicationData());
+  MessageStatus result =
+      connection_->SendMessage(last_message_id_ + 1, message, flush);
+  if (result == MESSAGE_STATUS_SUCCESS) {
+    return {result, ++last_message_id_};
+  }
+  return {result, 0};
+}
+
+void QuicSession::OnMessageAcked(QuicMessageId message_id,
+                                 QuicTime /*receive_timestamp*/) {
+  QUIC_DVLOG(1) << ENDPOINT << "message " << message_id << " gets acked.";
+}
+
+void QuicSession::OnMessageLost(QuicMessageId message_id) {
+  QUIC_DVLOG(1) << ENDPOINT << "message " << message_id
+                << " is considered lost";
+}
+
+void QuicSession::CleanUpClosedStreams() { closed_streams_.clear(); }
+
+QuicPacketLength QuicSession::GetCurrentLargestMessagePayload() const {
+  return connection_->GetCurrentLargestMessagePayload();
+}
+
+QuicPacketLength QuicSession::GetGuaranteedLargestMessagePayload() const {
+  return connection_->GetGuaranteedLargestMessagePayload();
+}
+
+QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.next_outgoing_bidirectional_stream_id();
+  }
+  return stream_id_manager_.next_outgoing_stream_id();
+}
+
+QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.next_outgoing_unidirectional_stream_id();
+  }
+  return stream_id_manager_.next_outgoing_stream_id();
+}
+
+bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
+  const bool allow_new_streams =
+      frame.unidirectional
+          ? ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+                frame.stream_count)
+          : ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+                frame.stream_count);
+  if (allow_new_streams) {
+    OnCanCreateNewOutgoingStream(frame.unidirectional);
+  }
+
+  return true;
+}
+
+bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) {
+  std::string error_details;
+  if (ietf_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) {
+    return true;
+  }
+  connection_->CloseConnection(
+      QUIC_STREAMS_BLOCKED_ERROR, error_details,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  return false;
+}
+
+size_t QuicSession::max_open_incoming_bidirectional_streams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
+  }
+  return stream_id_manager_.max_open_incoming_streams();
+}
+
+size_t QuicSession::max_open_incoming_unidirectional_streams() const {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
+  }
+  return stream_id_manager_.max_open_incoming_streams();
+}
+
+std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn(
+    const std::vector<absl::string_view>& alpns) const {
+  const std::string alpn = AlpnForVersion(connection()->version());
+  return std::find(alpns.cbegin(), alpns.cend(), alpn);
+}
+
+void QuicSession::OnAlpnSelected(absl::string_view alpn) {
+  QUIC_DLOG(INFO) << (perspective() == Perspective::IS_SERVER ? "Server: "
+                                                              : "Client: ")
+                  << "ALPN selected: " << alpn;
+}
+
+void QuicSession::NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level) {
+  GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(level);
+}
+
+void QuicSession::PerformActionOnActiveStreams(
+    std::function<bool(QuicStream*)> action) {
+  std::vector<QuicStream*> active_streams;
+  for (const auto& it : stream_map_) {
+    if (!it.second->is_static() && !it.second->IsZombie()) {
+      active_streams.push_back(it.second.get());
+    }
+  }
+
+  for (QuicStream* stream : active_streams) {
+    if (!action(stream)) {
+      return;
+    }
+  }
+}
+
+void QuicSession::PerformActionOnActiveStreams(
+    std::function<bool(QuicStream*)> action) const {
+  for (const auto& it : stream_map_) {
+    if (!it.second->is_static() && !it.second->IsZombie() &&
+        !action(it.second.get())) {
+      return;
+    }
+  }
+}
+
+EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const {
+  return connection_->framer().GetEncryptionLevelToSendApplicationData();
+}
+
+void QuicSession::ProcessAllPendingStreams() {
+  std::vector<PendingStream*> pending_streams;
+  pending_streams.reserve(pending_stream_map_.size());
+  for (auto it = pending_stream_map_.cbegin(); it != pending_stream_map_.cend();
+       ++it) {
+    pending_streams.push_back(it->second.get());
+  }
+  for (auto* pending_stream : pending_streams) {
+    MaybeProcessPendingStream(pending_stream);
+    if (!connection()->connected()) {
+      return;
+    }
+  }
+}
+
+void QuicSession::ValidatePath(
+    std::unique_ptr<QuicPathValidationContext> context,
+    std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate) {
+  connection_->ValidatePath(std::move(context), std::move(result_delegate));
+}
+
+bool QuicSession::HasPendingPathValidation() const {
+  return connection_->HasPendingPathValidation();
+}
+
+bool QuicSession::MigratePath(const QuicSocketAddress& self_address,
+                              const QuicSocketAddress& peer_address,
+                              QuicPacketWriter* writer, bool owns_writer) {
+  return connection_->MigratePath(self_address, peer_address, writer,
+                                  owns_writer);
+}
+
+bool QuicSession::ValidateToken(absl::string_view token) {
+  QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
+  if (GetQuicFlag(FLAGS_quic_reject_retry_token_in_initial_packet)) {
+    return false;
+  }
+  if (token.empty() || token[0] != kAddressTokenPrefix) {
+    // Validate the prefix for token received in NEW_TOKEN frame.
+    return false;
+  }
+  const bool valid = GetCryptoStream()->ValidateAddressToken(
+      absl::string_view(token.data() + 1, token.length() - 1));
+  if (valid) {
+    const CachedNetworkParameters* cached_network_params =
+        GetCryptoStream()->PreviousCachedNetworkParams();
+    if (cached_network_params != nullptr &&
+        cached_network_params->timestamp() > 0) {
+      connection()->OnReceiveConnectionState(*cached_network_params);
+    }
+  }
+  return valid;
+}
+
+#undef ENDPOINT  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_session.h b/quiche/quic/core/quic_session.h
new file mode 100644
index 0000000..a5aae44
--- /dev/null
+++ b/quiche/quic/core/quic_session.h
@@ -0,0 +1,1020 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A QuicSession, which demuxes a single connection to individual streams.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_SESSION_H_
+#define QUICHE_QUIC_CORE_QUIC_SESSION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/crypto/tls_connection.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/frames/quic_stop_sending_frame.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/core/handshaker_delegate_interface.h"
+#include "quiche/quic/core/legacy_quic_stream_id_manager.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_control_frame_manager.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_datagram_queue.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/core/stream_delegate_interface.h"
+#include "quiche/quic/core/uber_quic_stream_id_manager.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+class QuicCryptoStream;
+class QuicFlowController;
+class QuicStream;
+class QuicStreamIdManager;
+
+namespace test {
+class QuicSessionPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicSession
+    : public QuicConnectionVisitorInterface,
+      public SessionNotifierInterface,
+      public QuicStreamFrameDataProducer,
+      public QuicStreamIdManager::DelegateInterface,
+      public HandshakerDelegateInterface,
+      public StreamDelegateInterface,
+      public QuicControlFrameManager::DelegateInterface {
+ public:
+  // An interface from the session to the entity owning the session.
+  // This lets the session notify its owner (the Dispatcher) when the connection
+  // is closed, blocked, or added/removed from the time-wait list.
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called when the connection is closed after the streams have been closed.
+    virtual void OnConnectionClosed(QuicConnectionId server_connection_id,
+                                    QuicErrorCode error,
+                                    const std::string& error_details,
+                                    ConnectionCloseSource source) = 0;
+
+    // Called when the session has become write blocked.
+    virtual void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) = 0;
+
+    // Called when the session receives reset on a stream from the peer.
+    virtual void OnRstStreamReceived(const QuicRstStreamFrame& frame) = 0;
+
+    // Called when the session receives a STOP_SENDING for a stream from the
+    // peer.
+    virtual void OnStopSendingReceived(const QuicStopSendingFrame& frame) = 0;
+
+    // Called when a NewConnectionId frame has been sent.
+    virtual void OnNewConnectionIdSent(
+        const QuicConnectionId& server_connection_id,
+        const QuicConnectionId& new_connection_id) = 0;
+
+    // Called when a ConnectionId has been retired.
+    virtual void OnConnectionIdRetired(
+        const QuicConnectionId& server_connection_id) = 0;
+  };
+
+  // Does not take ownership of |connection| or |visitor|.
+  QuicSession(QuicConnection* connection, Visitor* owner,
+              const QuicConfig& config,
+              const ParsedQuicVersionVector& supported_versions,
+              QuicStreamCount num_expected_unidirectional_static_streams);
+  QuicSession(QuicConnection* connection, Visitor* owner,
+              const QuicConfig& config,
+              const ParsedQuicVersionVector& supported_versions,
+              QuicStreamCount num_expected_unidirectional_static_streams,
+              std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
+  QuicSession(const QuicSession&) = delete;
+  QuicSession& operator=(const QuicSession&) = delete;
+
+  ~QuicSession() override;
+
+  virtual void Initialize();
+
+  // Return the reserved crypto stream as a constant pointer.
+  virtual const QuicCryptoStream* GetCryptoStream() const = 0;
+
+  // QuicConnectionVisitorInterface methods:
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  void OnRstStream(const QuicRstStreamFrame& frame) override;
+  void OnGoAway(const QuicGoAwayFrame& frame) override;
+  void OnMessageReceived(absl::string_view message) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  void OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+  void OnWriteBlocked() override;
+  void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& version) override;
+  void OnPacketReceived(const QuicSocketAddress& self_address,
+                        const QuicSocketAddress& peer_address,
+                        bool is_connectivity_probe) override;
+  void OnCanWrite() override;
+  bool SendProbingData() override;
+  bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& /*self_address*/,
+      const quic::QuicSocketAddress& /*peer_address*/) override {
+    return true;
+  }
+  void OnCongestionWindowChange(QuicTime /*now*/) override {}
+  void OnConnectionMigration(AddressChangeType /*type*/) override {}
+  // Adds a connection level WINDOW_UPDATE frame.
+  void OnAckNeedsRetransmittableFrame() override;
+  void SendAckFrequency(const QuicAckFrequencyFrame& frame) override;
+  void SendNewConnectionId(const QuicNewConnectionIdFrame& frame) override;
+  void SendRetireConnectionId(uint64_t sequence_number) override;
+  void OnServerConnectionIdIssued(
+      const QuicConnectionId& server_connection_id) override;
+  void OnServerConnectionIdRetired(
+      const QuicConnectionId& server_connection_id) override;
+  bool WillingAndAbleToWrite() const override;
+  std::string GetStreamsInfoForLogging() const override;
+  void OnPathDegrading() override;
+  void OnForwardProgressMadeAfterPathDegrading() override;
+  bool AllowSelfAddressChange() const override;
+  HandshakeState GetHandshakeState() const override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  void OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  void OnPacketDecrypted(EncryptionLevel level) override;
+  void OnOneRttPacketAcknowledged() override;
+  void OnHandshakePacketSent() override;
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void BeforeConnectionCloseSent() override {}
+  bool ValidateToken(absl::string_view token) override;
+  bool MaybeSendAddressToken() override;
+  bool IsKnownServerAddress(
+      const QuicSocketAddress& /*address*/) const override {
+    return false;
+  }
+
+  // QuicStreamFrameDataProducer
+  WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) override;
+  bool WriteCryptoData(EncryptionLevel level, QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override;
+
+  // SessionNotifierInterface methods:
+  bool OnFrameAcked(const QuicFrame& frame, QuicTime::Delta ack_delay_time,
+                    QuicTime receive_timestamp) override;
+  void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override;
+  void OnFrameLost(const QuicFrame& frame) override;
+  bool RetransmitFrames(const QuicFrames& frames,
+                        TransmissionType type) override;
+  bool IsFrameOutstanding(const QuicFrame& frame) const override;
+  bool HasUnackedCryptoData() const override;
+  bool HasUnackedStreamData() const override;
+
+  void SendMaxStreams(QuicStreamCount stream_count,
+                      bool unidirectional) override;
+  // The default implementation does nothing. Subclasses should override if
+  // for example they queue up stream requests.
+  virtual void OnCanCreateNewOutgoingStream(bool /*unidirectional*/) {}
+
+  // Called on every incoming packet. Passes |packet| through to |connection_|.
+  virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                const QuicReceivedPacket& packet);
+
+  // Sends |message| as a QUIC DATAGRAM frame (QUIC MESSAGE frame in gQUIC).
+  // See <https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram> for
+  // more details.
+  //
+  // Returns a MessageResult struct which includes the status of the write
+  // operation and a message ID.  The message ID (not sent on the wire) can be
+  // used to track the message; OnMessageAcked and OnMessageLost are called when
+  // a specific message gets acked or lost.
+  //
+  // If the write operation is successful, all of the slices in |message| are
+  // consumed, leaving them empty.  If MESSAGE_STATUS_INTERNAL_ERROR is
+  // returned, the slices in question may or may not be consumed; it is no
+  // longer safe to access those.  For all other status codes, |message| is kept
+  // intact.
+  //
+  // Note that SendMessage will fail with status = MESSAGE_STATUS_BLOCKED
+  // if the connection is congestion control blocked or the underlying socket is
+  // write blocked. In this case the caller can retry sending message again when
+  // connection becomes available, for example after getting OnCanWrite()
+  // callback.
+  //
+  // SendMessage flushes the current packet even it is not full; if the
+  // application needs to bundle other data in the same packet, consider using
+  // QuicConnection::ScopedPacketFlusher around the relevant write operations.
+  MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message);
+
+  // Same as above SendMessage, except caller can specify if the given |message|
+  // should be flushed even if the underlying connection is deemed unwritable.
+  MessageResult SendMessage(absl::Span<quiche::QuicheMemSlice> message,
+                            bool flush);
+
+  // Single-slice version of SendMessage().  Unlike the version above, this
+  // version always takes ownership of the slice.
+  MessageResult SendMessage(quiche::QuicheMemSlice message);
+
+  // Called when message with |message_id| gets acked.
+  virtual void OnMessageAcked(QuicMessageId message_id,
+                              QuicTime receive_timestamp);
+
+  // Called when message with |message_id| is considered as lost.
+  virtual void OnMessageLost(QuicMessageId message_id);
+
+  // QuicControlFrameManager::DelegateInterface
+  // Close the connection on error.
+  void OnControlFrameManagerError(QuicErrorCode error_code,
+                                  std::string error_details) override;
+  // Called by control frame manager when it wants to write control frames to
+  // the peer. Returns true if |frame| is consumed, false otherwise. The frame
+  // will be sent in specified transmission |type|.
+  bool WriteControlFrame(const QuicFrame& frame,
+                         TransmissionType type) override;
+
+  // Called to send RST_STREAM (and STOP_SENDING) and close stream. If stream
+  // |id| does not exist, just send RST_STREAM (and STOP_SENDING).
+  virtual void ResetStream(QuicStreamId id, QuicRstStreamErrorCode error);
+
+  // Called when the session wants to go away and not accept any new streams.
+  virtual void SendGoAway(QuicErrorCode error_code, const std::string& reason);
+
+  // Sends a BLOCKED frame.
+  virtual void SendBlocked(QuicStreamId id);
+
+  // Sends a WINDOW_UPDATE frame.
+  virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
+
+  // Called by stream |stream_id| when it gets closed.
+  virtual void OnStreamClosed(QuicStreamId stream_id);
+
+  // Returns true if outgoing packets will be encrypted, even if the server
+  // hasn't confirmed the handshake yet.
+  virtual bool IsEncryptionEstablished() const;
+
+  // Returns true if 1RTT keys are available.
+  bool OneRttKeysAvailable() const;
+
+  // Called by the QuicCryptoStream when a new QuicConfig has been negotiated.
+  virtual void OnConfigNegotiated();
+
+  // Called by the TLS handshaker when ALPS data is received.
+  // Returns an error message if an error has occurred, or nullopt otherwise.
+  virtual absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
+                                                 size_t alps_length);
+
+  // From HandshakerDelegateInterface
+  bool OnNewDecryptionKeyAvailable(EncryptionLevel level,
+                                   std::unique_ptr<QuicDecrypter> decrypter,
+                                   bool set_alternative_decrypter,
+                                   bool latch_once_used) override;
+  void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;
+  void SetDefaultEncryptionLevel(EncryptionLevel level) override;
+  void OnTlsHandshakeComplete() override;
+  void DiscardOldDecryptionKey(EncryptionLevel level) override;
+  void DiscardOldEncryptionKey(EncryptionLevel level) override;
+  void NeuterUnencryptedData() override;
+  void NeuterHandshakeData() override;
+  void OnZeroRttRejected(int reason) override;
+  bool FillTransportParameters(TransportParameters* params) override;
+  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
+                                           bool is_resumption,
+                                           std::string* error_details) override;
+  void OnHandshakeCallbackDone() override;
+  bool PacketFlusherAttached() const override;
+  ParsedQuicVersion parsed_version() const override { return version(); }
+
+  // Implement StreamDelegateInterface.
+  void OnStreamError(QuicErrorCode error_code,
+                     std::string error_details) override;
+  void OnStreamError(QuicErrorCode error_code,
+                     QuicIetfTransportErrorCodes ietf_error,
+                     std::string error_details) override;
+  // Sets priority in the write blocked list.
+  void RegisterStreamPriority(
+      QuicStreamId id, bool is_static,
+      const spdy::SpdyStreamPrecedence& precedence) override;
+  // Clears priority from the write blocked list.
+  void UnregisterStreamPriority(QuicStreamId id, bool is_static) override;
+  // Updates priority on the write blocked list.
+  void UpdateStreamPriority(
+      QuicStreamId id,
+      const spdy::SpdyStreamPrecedence& new_precedence) override;
+
+  // Called by streams when they want to write data to the peer.
+  // Returns a pair with the number of bytes consumed from data, and a boolean
+  // indicating if the fin bit was consumed.  This does not indicate the data
+  // has been sent on the wire: it may have been turned into a packet and queued
+  // if the socket was unexpectedly blocked.
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override;
+
+  size_t SendCryptoData(EncryptionLevel level, size_t write_length,
+                        QuicStreamOffset offset,
+                        TransmissionType type) override;
+
+  // Called by the QuicCryptoStream when a handshake message is sent.
+  virtual void OnCryptoHandshakeMessageSent(
+      const CryptoHandshakeMessage& message);
+
+  // Called by the QuicCryptoStream when a handshake message is received.
+  virtual void OnCryptoHandshakeMessageReceived(
+      const CryptoHandshakeMessage& message);
+
+  // Returns mutable config for this session. Returned config is owned
+  // by QuicSession.
+  QuicConfig* config();
+
+  // Returns true if the stream existed previously and has been closed.
+  // Returns false if the stream is still active or if the stream has
+  // not yet been created.
+  bool IsClosedStream(QuicStreamId id);
+
+  QuicConnection* connection() { return connection_; }
+  const QuicConnection* connection() const { return connection_; }
+  const QuicSocketAddress& peer_address() const {
+    return connection_->peer_address();
+  }
+  const QuicSocketAddress& self_address() const {
+    return connection_->self_address();
+  }
+  QuicConnectionId connection_id() const {
+    return connection_->connection_id();
+  }
+
+  // Returns the number of currently open streams, excluding static streams, and
+  // never counting unfinished streams.
+  size_t GetNumActiveStreams() const;
+
+  // Add the stream to the session's write-blocked list because it is blocked by
+  // connection-level flow control but not by its own stream-level flow control.
+  // The stream will be given a chance to write when a connection-level
+  // WINDOW_UPDATE arrives.
+  virtual void MarkConnectionLevelWriteBlocked(QuicStreamId id);
+
+  // Called to close zombie stream |id|.
+  void MaybeCloseZombieStream(QuicStreamId id);
+
+  // Returns true if there is pending handshake data in the crypto stream.
+  // TODO(ianswett): Make this private or remove.
+  bool HasPendingHandshake() const;
+
+  // Returns true if the session has data to be sent, either queued in the
+  // connection, or in a write-blocked stream.
+  bool HasDataToWrite() const;
+
+  // Initiates a path validation on the path described in the given context,
+  // asynchronously calls |result_delegate| upon success or failure.
+  // The initiator should extend QuicPathValidationContext to provide the writer
+  // and ResultDelegate to react upon the validation result.
+  // Example implementations of these for path validation for connection
+  // migration could be:
+  //  class QUIC_EXPORT_PRIVATE PathMigrationContext
+  //      : public QuicPathValidationContext {
+  //   public:
+  //    PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
+  //                         const QuicSocketAddress& self_address,
+  //                         const QuicSocketAddress& peer_address)
+  //        : QuicPathValidationContext(self_address, peer_address),
+  //          alternative_writer_(std::move(writer)) {}
+  //
+  //    QuicPacketWriter* WriterToUse() override {
+  //         return alternative_writer_.get();
+  //    }
+  //
+  //    QuicPacketWriter* ReleaseWriter() {
+  //         return alternative_writer_.release();
+  //    }
+  //
+  //   private:
+  //    std::unique_ptr<QuicPacketWriter> alternative_writer_;
+  //  };
+  //
+  //  class PathMigrationValidationResultDelegate
+  //      : public QuicPathValidator::ResultDelegate {
+  //   public:
+  //    PathMigrationValidationResultDelegate(QuicConnection* connection)
+  //        : QuicPathValidator::ResultDelegate(), connection_(connection) {}
+  //
+  //    void OnPathValidationSuccess(
+  //        std::unique_ptr<QuicPathValidationContext> context) override {
+  //    // Do some work to prepare for migration.
+  //    // ...
+  //
+  //    // Actually migrate to the validated path.
+  //    auto migration_context = std::unique_ptr<PathMigrationContext>(
+  //        static_cast<PathMigrationContext*>(context.release()));
+  //    connection_->MigratePath(migration_context->self_address(),
+  //                          migration_context->peer_address(),
+  //                          migration_context->ReleaseWriter(),
+  //                          /*owns_writer=*/true);
+  //
+  //    // Post-migration actions
+  //    // ...
+  //  }
+  //
+  //    void OnPathValidationFailure(
+  //        std::unique_ptr<QuicPathValidationContext> /*context*/) override {
+  //    // Handle validation failure.
+  //  }
+  //
+  //   private:
+  //    QuicConnection* connection_;
+  //  };
+  void ValidatePath(
+      std::unique_ptr<QuicPathValidationContext> context,
+      std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate);
+
+  // Return true if there is a path being validated.
+  bool HasPendingPathValidation() const;
+
+  // Switch to the path described in |context| without validating the path.
+  bool MigratePath(const QuicSocketAddress& self_address,
+                   const QuicSocketAddress& peer_address,
+                   QuicPacketWriter* writer, bool owns_writer);
+
+  // Returns the largest payload that will fit into a single MESSAGE frame.
+  // Because overhead can vary during a connection, this method should be
+  // checked for every message.
+  QuicPacketLength GetCurrentLargestMessagePayload() const;
+
+  // Returns the largest payload that will fit into a single MESSAGE frame at
+  // any point during the connection.  This assumes the version and
+  // connection ID lengths do not change.
+  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
+
+  bool transport_goaway_sent() const { return transport_goaway_sent_; }
+
+  bool transport_goaway_received() const { return transport_goaway_received_; }
+
+  // Returns the Google QUIC error code
+  QuicErrorCode error() const { return on_closed_frame_.quic_error_code; }
+  const std::string& error_details() const {
+    return on_closed_frame_.error_details;
+  }
+  uint64_t transport_close_frame_type() const {
+    return on_closed_frame_.transport_close_frame_type;
+  }
+  QuicConnectionCloseType close_type() const {
+    return on_closed_frame_.close_type;
+  }
+
+  Perspective perspective() const { return perspective_; }
+
+  QuicFlowController* flow_controller() { return &flow_controller_; }
+
+  // Returns true if connection is flow controller blocked.
+  bool IsConnectionFlowControlBlocked() const;
+
+  // Returns true if any stream is flow controller blocked.
+  bool IsStreamFlowControlBlocked();
+
+  size_t max_open_incoming_bidirectional_streams() const;
+  size_t max_open_incoming_unidirectional_streams() const;
+
+  size_t MaxAvailableBidirectionalStreams() const;
+  size_t MaxAvailableUnidirectionalStreams() const;
+
+  // Returns existing stream with id = |stream_id|. If no
+  // such stream exists, and |stream_id| is a peer-created stream id,
+  // then a new stream is created and returned. In all other cases, nullptr is
+  // returned.
+  // Caller does not own the returned stream.
+  QuicStream* GetOrCreateStream(const QuicStreamId stream_id);
+
+  // Mark a stream as draining.
+  void StreamDraining(QuicStreamId id, bool unidirectional);
+
+  // Returns true if this stream should yield writes to another blocked stream.
+  virtual bool ShouldYield(QuicStreamId stream_id);
+
+  // Clean up closed_streams_.
+  void CleanUpClosedStreams();
+
+  const ParsedQuicVersionVector& supported_versions() const {
+    return supported_versions_;
+  }
+
+  QuicStreamId next_outgoing_bidirectional_stream_id() const;
+  QuicStreamId next_outgoing_unidirectional_stream_id() const;
+
+  // Return true if given stream is peer initiated.
+  bool IsIncomingStream(QuicStreamId id) const;
+
+  // Record errors when a connection is closed at the server side, should only
+  // be called from server's perspective.
+  // Noop if |error| is QUIC_NO_ERROR.
+  static void RecordConnectionCloseAtServer(QuicErrorCode error,
+                                            ConnectionCloseSource source);
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  ParsedQuicVersion version() const { return connection_->version(); }
+
+  bool is_configured() const { return is_configured_; }
+
+  // Called to neuter crypto data of encryption |level|.
+  void NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level);
+
+  // Returns the ALPN values to negotiate on this session.
+  virtual std::vector<std::string> GetAlpnsToOffer() const {
+    // TODO(vasilvv): this currently sets HTTP/3 by default.  Switch all
+    // non-HTTP applications to appropriate ALPNs.
+    return std::vector<std::string>({AlpnForVersion(connection()->version())});
+  }
+
+  // Provided a list of ALPNs offered by the client, selects an ALPN from the
+  // list, or alpns.end() if none of the ALPNs are acceptable.
+  virtual std::vector<absl::string_view>::const_iterator SelectAlpn(
+      const std::vector<absl::string_view>& alpns) const;
+
+  // Called when the ALPN of the connection is established for a connection that
+  // uses TLS handshake.
+  virtual void OnAlpnSelected(absl::string_view alpn);
+
+  // Called on clients by the crypto handshaker to provide application state
+  // necessary for sending application data in 0-RTT. The state provided here is
+  // the same state that was provided to the crypto handshaker in
+  // QuicCryptoStream::SetServerApplicationStateForResumption on a previous
+  // connection. Application protocols that require state to be carried over
+  // from the previous connection to support 0-RTT data must implement this
+  // method to ingest this state. For example, an HTTP/3 QuicSession would
+  // implement this function to process the remembered server SETTINGS and apply
+  // those SETTINGS to 0-RTT data. This function returns true if the application
+  // state has been successfully processed, and false if there was an error
+  // processing the cached state and the connection should be closed.
+  virtual bool ResumeApplicationState(ApplicationState* /*cached_state*/) {
+    return true;
+  }
+
+  // Does actual work of sending RESET_STREAM, if the stream type allows.
+  // Also informs the connection so that pending stream frames can be flushed.
+  virtual void MaybeSendRstStreamFrame(QuicStreamId id,
+                                       QuicResetStreamError error,
+                                       QuicStreamOffset bytes_written);
+
+  // Sends a STOP_SENDING frame if the stream type allows.
+  virtual void MaybeSendStopSendingFrame(QuicStreamId id,
+                                         QuicResetStreamError error);
+
+  // Returns the encryption level to send application data.
+  EncryptionLevel GetEncryptionLevelToSendApplicationData() const;
+
+  const absl::optional<std::string> user_agent_id() const {
+    return user_agent_id_;
+  }
+
+  // TODO(wub): remove saving user-agent to QuicSession.
+  void SetUserAgentId(std::string user_agent_id) {
+    user_agent_id_ = std::move(user_agent_id);
+    connection()->OnUserAgentIdKnown(user_agent_id_.value());
+  }
+
+  void SetSourceAddressTokenToSend(absl::string_view token) {
+    connection()->SetSourceAddressTokenToSend(token);
+  }
+
+  const QuicClock* GetClock() const {
+    return connection()->helper()->GetClock();
+  }
+
+  bool liveness_testing_in_progress() const {
+    return liveness_testing_in_progress_;
+  }
+
+  bool permutes_tls_extensions() const { return permutes_tls_extensions_; }
+
+  virtual QuicSSLConfig GetSSLConfig() const { return QuicSSLConfig(); }
+
+  // Latched value of flag --quic_tls_server_support_client_cert.
+  bool support_client_cert() const { return support_client_cert_; }
+
+  // Try converting all pending streams to normal streams.
+  void ProcessAllPendingStreams();
+
+  const ParsedQuicVersionVector& client_original_supported_versions() const {
+    QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+    return client_original_supported_versions_;
+  }
+  void set_client_original_supported_versions(
+      const ParsedQuicVersionVector& client_original_supported_versions) {
+    QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+    client_original_supported_versions_ = client_original_supported_versions;
+  }
+
+ protected:
+  using StreamMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
+
+  using PendingStreamMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<PendingStream>>;
+
+  using ClosedStreams = std::vector<std::unique_ptr<QuicStream>>;
+
+  using ZombieStreamMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStream>>;
+
+  // Creates a new stream to handle a peer-initiated stream.
+  // Caller does not own the returned stream.
+  // Returns nullptr and does error handling if the stream can not be created.
+  virtual QuicStream* CreateIncomingStream(QuicStreamId id) = 0;
+  virtual QuicStream* CreateIncomingStream(PendingStream* pending) = 0;
+
+  // Return the reserved crypto stream.
+  virtual QuicCryptoStream* GetMutableCryptoStream() = 0;
+
+  // Adds |stream| to the stream map.
+  virtual void ActivateStream(std::unique_ptr<QuicStream> stream);
+
+  // Set transmission type of next sending packets.
+  void SetTransmissionType(TransmissionType type);
+
+  // Returns the stream ID for a new outgoing bidirectional/unidirectional
+  // stream, and increments the underlying counter.
+  QuicStreamId GetNextOutgoingBidirectionalStreamId();
+  QuicStreamId GetNextOutgoingUnidirectionalStreamId();
+
+  // Indicates whether the next outgoing bidirectional/unidirectional stream ID
+  // can be allocated or not. The test for version-99/IETF QUIC is whether it
+  // will exceed the maximum-stream-id or not. For non-version-99 (Google) QUIC
+  // it checks whether the next stream would exceed the limit on the number of
+  // open streams.
+  bool CanOpenNextOutgoingBidirectionalStream();
+  bool CanOpenNextOutgoingUnidirectionalStream();
+
+  // Returns the maximum bidirectional streams parameter sent with the handshake
+  // as a transport parameter, or in the most recent MAX_STREAMS frame.
+  QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const;
+
+  // When a stream is closed locally, it may not yet know how many bytes the
+  // peer sent on that stream.
+  // When this data arrives (via stream frame w. FIN, trailing headers, or RST)
+  // this method is called, and correctly updates the connection level flow
+  // controller.
+  virtual void OnFinalByteOffsetReceived(QuicStreamId id,
+                                         QuicStreamOffset final_byte_offset);
+
+  // Returns true if a frame with the given type and id can be prcoessed by a
+  // PendingStream. However, the frame will always be processed by a QuicStream
+  // if one exists with the given stream_id.
+  virtual bool UsesPendingStreamForFrame(QuicFrameType /*type*/,
+                                         QuicStreamId /*stream_id*/) const {
+    return false;
+  }
+
+  // Returns true if a pending stream should be converted to a real stream after
+  // a corresponding STREAM_FRAME is received.
+  virtual bool ShouldProcessPendingStreamImmediately() const { return true; }
+
+  spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId stream_id) const {
+    return write_blocked_streams_.GetSpdyPriorityofStream(stream_id);
+  }
+
+  size_t pending_streams_size() const { return pending_stream_map_.size(); }
+
+  ClosedStreams* closed_streams() { return &closed_streams_; }
+
+  void set_largest_peer_created_stream_id(
+      QuicStreamId largest_peer_created_stream_id);
+
+  QuicWriteBlockedList* write_blocked_streams() {
+    return &write_blocked_streams_;
+  }
+
+  // Returns true if the stream is still active.
+  bool IsOpenStream(QuicStreamId id);
+
+  // Returns true if the stream is a static stream.
+  bool IsStaticStream(QuicStreamId id) const;
+
+  // Close connection when receive a frame for a locally-created nonexistent
+  // stream.
+  // Prerequisite: IsClosedStream(stream_id) == false
+  // Server session might need to override this method to allow server push
+  // stream to be promised before creating an active stream.
+  virtual void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id);
+
+  virtual bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id);
+
+  void InsertLocallyClosedStreamsHighestOffset(const QuicStreamId id,
+                                               QuicStreamOffset offset);
+  // If stream is a locally closed stream, this RST will update FIN offset.
+  // Otherwise stream is a preserved stream and the behavior of it depends on
+  // derived class's own implementation.
+  virtual void HandleRstOnValidNonexistentStream(
+      const QuicRstStreamFrame& frame);
+
+  // Returns a stateless reset token which will be included in the public reset
+  // packet.
+  virtual StatelessResetToken GetStatelessResetToken() const;
+
+  QuicControlFrameManager& control_frame_manager() {
+    return control_frame_manager_;
+  }
+
+  const LegacyQuicStreamIdManager& stream_id_manager() const {
+    return stream_id_manager_;
+  }
+
+  QuicDatagramQueue* datagram_queue() { return &datagram_queue_; }
+
+  size_t num_static_streams() const { return num_static_streams_; }
+
+  size_t num_zombie_streams() const { return num_zombie_streams_; }
+
+  bool was_zero_rtt_rejected() const { return was_zero_rtt_rejected_; }
+
+  size_t num_outgoing_draining_streams() const {
+    return num_outgoing_draining_streams_;
+  }
+
+  size_t num_draining_streams() const { return num_draining_streams_; }
+
+  // Processes the stream type information of |pending| depending on
+  // different kinds of sessions' own rules. If the pending stream has been
+  // converted to a normal stream, returns a pointer to the new stream;
+  // otherwise, returns nullptr.
+  virtual QuicStream* ProcessPendingStream(PendingStream* /*pending*/) {
+    return nullptr;
+  }
+
+  // Called by applications to perform |action| on active streams.
+  // Stream iteration will be stopped if action returns false.
+  void PerformActionOnActiveStreams(std::function<bool(QuicStream*)> action);
+  void PerformActionOnActiveStreams(
+      std::function<bool(QuicStream*)> action) const;
+
+  // Return the largest peer created stream id depending on directionality
+  // indicated by |unidirectional|.
+  QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
+
+  // Deletes the connection and sets it to nullptr, so calling it mulitiple
+  // times is safe.
+  void DeleteConnection();
+
+  // Call SetPriority() on stream id |id| and return true if stream is active.
+  bool MaybeSetStreamPriority(QuicStreamId stream_id,
+                              const spdy::SpdyStreamPrecedence& precedence);
+
+  void SetLossDetectionTuner(
+      std::unique_ptr<LossDetectionTunerInterface> tuner) {
+    connection()->SetLossDetectionTuner(std::move(tuner));
+  }
+
+  // Find stream with |id|, returns nullptr if the stream does not exist or
+  // closed. static streams and zombie streams are not considered active
+  // streams.
+  QuicStream* GetActiveStream(QuicStreamId id) const;
+
+  const UberQuicStreamIdManager& ietf_streamid_manager() const {
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+    return ietf_streamid_manager_;
+  }
+
+  // Only called at a server session. Generate a CachedNetworkParameters that
+  // can be sent to the client as part of the address token, based on the latest
+  // bandwidth/rtt information. If return absl::nullopt, address token will not
+  // contain the CachedNetworkParameters.
+  virtual absl::optional<CachedNetworkParameters>
+  GenerateCachedNetworkParameters() const {
+    return absl::nullopt;
+  }
+
+ private:
+  friend class test::QuicSessionPeer;
+
+  // Called in OnConfigNegotiated when we receive a new stream level flow
+  // control window in a negotiated config. Closes the connection if invalid.
+  void OnNewStreamFlowControlWindow(QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new unidirectional stream
+  // flow control window in a negotiated config.
+  void OnNewStreamUnidirectionalFlowControlWindow(QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new outgoing bidirectional
+  // stream flow control window in a negotiated config.
+  void OnNewStreamOutgoingBidirectionalFlowControlWindow(
+      QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new incoming bidirectional
+  // stream flow control window in a negotiated config.
+  void OnNewStreamIncomingBidirectionalFlowControlWindow(
+      QuicStreamOffset new_window);
+
+  // Called in OnConfigNegotiated when we receive a new connection level flow
+  // control window in a negotiated config. Closes the connection if invalid.
+  void OnNewSessionFlowControlWindow(QuicStreamOffset new_window);
+
+  // Debug helper for |OnCanWrite()|, check that OnStreamWrite() makes
+  // forward progress.  Returns false if busy loop detected.
+  bool CheckStreamNotBusyLooping(QuicStream* stream,
+                                 uint64_t previous_bytes_written,
+                                 bool previous_fin_sent);
+
+  // Debug helper for OnCanWrite. Check that after QuicStream::OnCanWrite(),
+  // if stream has buffered data and is not stream level flow control blocked,
+  // it has to be in the write blocked list.
+  bool CheckStreamWriteBlocked(QuicStream* stream) const;
+
+  // Called in OnConfigNegotiated for Finch trials to measure performance of
+  // starting with larger flow control receive windows.
+  void AdjustInitialFlowControlWindows(size_t stream_window);
+
+  // Find stream with |id|, returns nullptr if the stream does not exist or
+  // closed.
+  QuicStream* GetStream(QuicStreamId id) const;
+
+  // Can return NULL, e.g., if the stream has been closed before.
+  PendingStream* GetOrCreatePendingStream(QuicStreamId stream_id);
+
+  // Let streams and control frame managers retransmit lost data, returns true
+  // if all lost data is retransmitted. Returns false otherwise.
+  bool RetransmitLostData();
+
+  // Returns true if stream data should be written.
+  bool CanWriteStreamData() const;
+
+  // Closes the pending stream |stream_id| before it has been created.
+  void ClosePendingStream(QuicStreamId stream_id);
+
+  // Whether the frame with given type and id should be feed to a pending
+  // stream.
+  bool ShouldProcessFrameByPendingStream(QuicFrameType type,
+                                         QuicStreamId id) const;
+
+  // Process the pending stream if possible.
+  void MaybeProcessPendingStream(PendingStream* pending);
+
+  // Creates or gets pending stream, feeds it with |frame|, and returns the
+  // pending stream. Can return NULL, e.g., if the stream ID is invalid.
+  PendingStream* PendingStreamOnStreamFrame(const QuicStreamFrame& frame);
+
+  // Creates or gets pending strea, feed it with |frame|, and closes the pending
+  // stream.
+  void PendingStreamOnRstStream(const QuicRstStreamFrame& frame);
+
+  // Creates or gets pending stream, feeds it with |frame|, and records the
+  // max_data in the pending stream.
+  void PendingStreamOnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
+
+  // Creates or gets pending stream, feeds it with |frame|, and records the
+  // ietf_error_code in the pending stream.
+  void PendingStreamOnStopSendingFrame(const QuicStopSendingFrame& frame);
+
+  // Keep track of highest received byte offset of locally closed streams, while
+  // waiting for a definitive final highest offset from the peer.
+  absl::flat_hash_map<QuicStreamId, QuicStreamOffset>
+      locally_closed_streams_highest_offset_;
+
+  QuicConnection* connection_;
+
+  // Store perspective on QuicSession during the constructor as it may be needed
+  // during our destructor when connection_ may have already been destroyed.
+  Perspective perspective_;
+
+  // May be null.
+  Visitor* visitor_;
+
+  // A list of streams which need to write more data.  Stream register
+  // themselves in their constructor, and unregisterm themselves in their
+  // destructors, so the write blocked list must outlive all streams.
+  QuicWriteBlockedList write_blocked_streams_;
+
+  ClosedStreams closed_streams_;
+
+  QuicConfig config_;
+
+  // Map from StreamId to pointers to streams. Owns the streams.
+  StreamMap stream_map_;
+
+  // Map from StreamId to PendingStreams for peer-created unidirectional streams
+  // which are waiting for the first byte of payload to arrive.
+  PendingStreamMap pending_stream_map_;
+
+  // TODO(fayang): Consider moving LegacyQuicStreamIdManager into
+  // UberQuicStreamIdManager.
+  // Manages stream IDs for Google QUIC.
+  LegacyQuicStreamIdManager stream_id_manager_;
+
+  // Manages stream IDs for version99/IETF QUIC
+  UberQuicStreamIdManager ietf_streamid_manager_;
+
+  // A counter for streams which have sent and received FIN but waiting for
+  // application to consume data.
+  size_t num_draining_streams_;
+
+  // A counter for self initiated streams which have sent and received FIN but
+  // waiting for application to consume data.
+  size_t num_outgoing_draining_streams_;
+
+  // A counter for static streams which are in stream_map_.
+  size_t num_static_streams_;
+
+  // A counter for streams which have done reading and writing, but are waiting
+  // for acks.
+  size_t num_zombie_streams_;
+
+  // Received information for a connection close.
+  QuicConnectionCloseFrame on_closed_frame_;
+
+  // Used for connection-level flow control.
+  QuicFlowController flow_controller_;
+
+  // The stream id which was last popped in OnCanWrite, or 0, if not under the
+  // call stack of OnCanWrite.
+  QuicStreamId currently_writing_stream_id_;
+
+  // Whether a transport layer GOAWAY frame has been sent.
+  // Such a frame only exists in Google QUIC, therefore |transport_goaway_sent_|
+  // is always false when using IETF QUIC.
+  bool transport_goaway_sent_;
+
+  // Whether a transport layer GOAWAY frame has been received.
+  // Such a frame only exists in Google QUIC, therefore
+  // |transport_goaway_received_| is always false when using IETF QUIC.
+  bool transport_goaway_received_;
+
+  QuicControlFrameManager control_frame_manager_;
+
+  // Id of latest successfully sent message.
+  QuicMessageId last_message_id_;
+
+  // The buffer used to queue the DATAGRAM frames.
+  QuicDatagramQueue datagram_queue_;
+
+  // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
+  // is not used here.
+  // List of streams with pending retransmissions.
+  quiche::QuicheLinkedHashMap<QuicStreamId, bool>
+      streams_with_pending_retransmission_;
+
+  // Clean up closed_streams_ when this alarm fires.
+  std::unique_ptr<QuicAlarm> closed_streams_clean_up_alarm_;
+
+  // Supported version list used by the crypto handshake only. Please note, this
+  // list may be a superset of the connection framer's supported versions.
+  ParsedQuicVersionVector supported_versions_;
+
+  // Only non-empty on the client after receiving a version negotiation packet,
+  // contains the configured versions from the original session before version
+  // negotiation was received.
+  ParsedQuicVersionVector client_original_supported_versions_;
+
+  absl::optional<std::string> user_agent_id_;
+
+  // Initialized to false. Set to true when the session has been properly
+  // configured and is ready for general operation.
+  bool is_configured_;
+
+  // Whether the session has received a 0-RTT rejection (QUIC+TLS only).
+  bool was_zero_rtt_rejected_;
+
+  // This indicates a liveness testing is in progress, and push back the
+  // creation of new outgoing bidirectional streams.
+  bool liveness_testing_in_progress_;
+
+  // Whether BoringSSL randomizes the order of TLS extensions.
+  bool permutes_tls_extensions_ = true;
+
+  const bool support_client_cert_ =
+      GetQuicRestartFlag(quic_tls_server_support_client_cert);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SESSION_H_
diff --git a/quiche/quic/core/quic_session_test.cc b/quiche/quic/core/quic_session_test.cc
new file mode 100644
index 0000000..d97200e
--- /dev/null
+++ b/quiche/quic/core/quic_session_test.cc
@@ -0,0 +1,3093 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_session.h"
+
+#include <cstdint>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/frames/quic_max_streams_frame.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+
+using spdy::kV3HighestPriority;
+using spdy::SpdyPriority;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::StrictMock;
+using ::testing::WithArg;
+
+namespace quic {
+namespace test {
+namespace {
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+  explicit TestCryptoStream(QuicSession* session)
+      : QuicCryptoStream(session),
+        QuicCryptoHandshaker(this, session),
+        encryption_established_(false),
+        one_rtt_keys_available_(false),
+        params_(new QuicCryptoNegotiatedParameters) {
+    // Simulate a negotiated cipher_suite with a fake value.
+    params_->cipher_suite = 1;
+  }
+
+  void EstablishZeroRttEncryption() {
+    encryption_established_ = true;
+    session()->connection()->SetEncrypter(
+        ENCRYPTION_ZERO_RTT,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+  }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+    encryption_established_ = true;
+    one_rtt_keys_available_ = true;
+    QuicErrorCode error;
+    std::string error_details;
+    session()->config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session()->config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (session()->version().UsesTls()) {
+      if (session()->perspective() == Perspective::IS_CLIENT) {
+        session()->config()->SetOriginalConnectionIdToSend(
+            session()->connection()->connection_id());
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->connection_id());
+      } else {
+        session()->config()->SetInitialSourceConnectionIdToSend(
+            session()->connection()->client_connection_id());
+      }
+      TransportParameters transport_parameters;
+      EXPECT_TRUE(
+          session()->config()->FillTransportParameters(&transport_parameters));
+      error = session()->config()->ProcessTransportParameters(
+          transport_parameters, /* is_resumption = */ false, &error_details);
+    } else {
+      CryptoHandshakeMessage msg;
+      session()->config()->ToHandshakeMessage(&msg, transport_version());
+      error =
+          session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+    }
+    EXPECT_THAT(error, IsQuicNoError());
+    session()->OnNewEncryptionKeyAvailable(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(session()->perspective()));
+    session()->OnConfigNegotiated();
+    if (session()->connection()->version().handshake_protocol ==
+        PROTOCOL_TLS1_3) {
+      session()->OnTlsHandshakeComplete();
+    } else {
+      session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  }
+
+  // QuicCryptoStream implementation
+  ssl_early_data_reason_t EarlyDataReason() const override {
+    return ssl_early_data_unknown;
+  }
+  bool encryption_established() const override {
+    return encryption_established_;
+  }
+  bool one_rtt_keys_available() const override {
+    return one_rtt_keys_available_;
+  }
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override {
+    return *params_;
+  }
+  CryptoMessageParser* crypto_message_parser() override {
+    return QuicCryptoHandshaker::crypto_message_parser();
+  }
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+  HandshakeState GetHandshakeState() const override {
+    return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
+  }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter,
+              (),
+              (override));
+  MOCK_METHOD(std::unique_ptr<QuicEncrypter>,
+              CreateCurrentOneRttEncrypter,
+              (),
+              (override));
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  bool HasPendingCryptoRetransmission() const override { return false; }
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  using QuicCryptoStream::session;
+
+  bool encryption_established_;
+  bool one_rtt_keys_available_;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestStream : public QuicStream {
+ public:
+  TestStream(QuicStreamId id, QuicSession* session, StreamType type)
+      : TestStream(id, session, /*is_static=*/false, type) {}
+
+  TestStream(QuicStreamId id,
+             QuicSession* session,
+             bool is_static,
+             StreamType type)
+      : QuicStream(id, session, is_static, type) {}
+
+  TestStream(PendingStream* pending, QuicSession* session)
+      : QuicStream(pending, session, /*is_static=*/false) {}
+
+  using QuicStream::CloseWriteSide;
+  using QuicStream::WriteMemSlices;
+
+  void OnDataAvailable() override {}
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool,
+              RetransmitStreamData,
+              (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
+              (override));
+
+  MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
+};
+
+class TestSession : public QuicSession {
+ public:
+  explicit TestSession(QuicConnection* connection,
+                       MockQuicSessionVisitor* session_visitor)
+      : QuicSession(connection,
+                    session_visitor,
+                    DefaultQuicConfig(),
+                    CurrentSupportedVersions(),
+                    /*num_expected_unidirectional_static_streams = */ 0),
+        crypto_stream_(this),
+        writev_consumes_all_data_(false),
+        uses_pending_streams_(false),
+        num_incoming_streams_created_(0) {
+    Initialize();
+    this->connection()->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection->perspective()));
+    if (this->connection()->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(this->connection());
+    }
+  }
+
+  ~TestSession() override { DeleteConnection(); }
+
+  TestCryptoStream* GetMutableCryptoStream() override {
+    return &crypto_stream_;
+  }
+
+  const TestCryptoStream* GetCryptoStream() const override {
+    return &crypto_stream_;
+  }
+
+  TestStream* CreateOutgoingBidirectionalStream() {
+    QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
+    if (id ==
+        QuicUtils::GetInvalidStreamId(connection()->transport_version())) {
+      return nullptr;
+    }
+    TestStream* stream = new TestStream(id, this, BIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateOutgoingUnidirectionalStream() {
+    TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
+                                        this, WRITE_UNIDIRECTIONAL);
+    ActivateStream(absl::WrapUnique(stream));
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(QuicStreamId id) override {
+    // Enforce the limit on the number of open streams.
+    if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
+        stream_id_manager().num_open_incoming_streams() + 1 >
+            max_open_incoming_bidirectional_streams()) {
+      // No need to do this test for version 99; it's done by
+      // QuicSession::GetOrCreateStream.
+      connection()->CloseConnection(
+          QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
+          ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+      return nullptr;
+    }
+
+    TestStream* stream = new TestStream(
+        id, this,
+        DetermineStreamType(id, connection()->version(), perspective(),
+                            /*is_incoming=*/true, BIDIRECTIONAL));
+    ActivateStream(absl::WrapUnique(stream));
+    ++num_incoming_streams_created_;
+    return stream;
+  }
+
+  TestStream* CreateIncomingStream(PendingStream* pending) override {
+    TestStream* stream = new TestStream(pending, this);
+    ActivateStream(absl::WrapUnique(stream));
+    ++num_incoming_streams_created_;
+    return stream;
+  }
+
+  // QuicSession doesn't do anything in this method. So it's overridden here to
+  // test that the session handles pending streams correctly in terms of
+  // receiving stream frames.
+  QuicStream* ProcessPendingStream(PendingStream* pending) override {
+    if (pending->is_bidirectional()) {
+      return CreateIncomingStream(pending);
+    }
+    struct iovec iov;
+    if (pending->sequencer()->GetReadableRegion(&iov)) {
+      // Create TestStream once the first byte is received.
+      return CreateIncomingStream(pending);
+    }
+    return nullptr;
+  }
+
+  bool IsClosedStream(QuicStreamId id) {
+    return QuicSession::IsClosedStream(id);
+  }
+
+  QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
+    return QuicSession::GetOrCreateStream(stream_id);
+  }
+
+  bool ShouldKeepConnectionAlive() const override {
+    return GetNumActiveStreams() > 0;
+  }
+
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override {
+    bool fin = state != NO_FIN;
+    QuicConsumedData consumed(write_length, fin);
+    if (!writev_consumes_all_data_) {
+      consumed =
+          QuicSession::WritevData(id, write_length, offset, state, type, level);
+    }
+    QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
+        id, consumed.bytes_consumed);
+    return consumed;
+  }
+
+  MOCK_METHOD(void,
+              OnCanCreateNewOutgoingStream,
+              (bool unidirectional),
+              (override));
+
+  void set_writev_consumes_all_data(bool val) {
+    writev_consumes_all_data_ = val;
+  }
+
+  QuicConsumedData SendStreamData(QuicStream* stream) {
+    if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
+                                     stream->id()) &&
+        this->connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+      this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+    }
+    QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
+    QuicConsumedData consumed =
+        WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
+                   GetEncryptionLevelToSendApplicationData());
+    QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
+        consumed.bytes_consumed);
+    return consumed;
+  }
+
+  const QuicFrame& save_frame() { return save_frame_; }
+
+  bool SaveFrame(const QuicFrame& frame) {
+    save_frame_ = frame;
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+  QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
+    QUICHE_DCHECK(writev_consumes_all_data_);
+    return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
+                      GetEncryptionLevelToSendApplicationData());
+  }
+
+  bool UsesPendingStreamForFrame(QuicFrameType type,
+                                 QuicStreamId stream_id) const override {
+    if (!uses_pending_streams_) {
+      return false;
+    }
+    // Uses pending stream for STREAM/RST_STREAM frames with unidirectional read
+    // stream and uses pending stream for
+    // STREAM/RST_STREAM/STOP_SENDING/WINDOW_UPDATE frames with bidirectional
+    // stream.
+    bool is_incoming_stream = IsIncomingStream(stream_id);
+    StreamType stream_type = QuicUtils::GetStreamType(
+        stream_id, perspective(), is_incoming_stream, version());
+    switch (type) {
+      case STREAM_FRAME:
+        ABSL_FALLTHROUGH_INTENDED;
+      case RST_STREAM_FRAME:
+        return is_incoming_stream;
+      case STOP_SENDING_FRAME:
+        ABSL_FALLTHROUGH_INTENDED;
+      case WINDOW_UPDATE_FRAME:
+        return stream_type == BIDIRECTIONAL;
+      default:
+        return false;
+    }
+  }
+
+  bool ShouldProcessPendingStreamImmediately() const override {
+    return process_pending_stream_immediately_;
+  }
+
+  void set_uses_pending_streams(bool uses_pending_streams) {
+    uses_pending_streams_ = uses_pending_streams;
+  }
+
+  void set_process_pending_stream_immediately(
+      bool process_pending_stream_immediately) {
+    process_pending_stream_immediately_ = process_pending_stream_immediately;
+  }
+
+  int num_incoming_streams_created() const {
+    return num_incoming_streams_created_;
+  }
+
+  using QuicSession::ActivateStream;
+  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
+  using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
+  using QuicSession::closed_streams;
+  using QuicSession::GetNextOutgoingBidirectionalStreamId;
+  using QuicSession::GetNextOutgoingUnidirectionalStreamId;
+
+ private:
+  StrictMock<TestCryptoStream> crypto_stream_;
+
+  bool writev_consumes_all_data_;
+  bool uses_pending_streams_;
+  bool process_pending_stream_immediately_ = true;
+  QuicFrame save_frame_;
+  int num_incoming_streams_created_;
+};
+
+class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  QuicSessionTestBase(Perspective perspective, bool configure_session)
+      : connection_(
+            new StrictMock<MockQuicConnection>(&helper_,
+                                               &alarm_factory_,
+                                               perspective,
+                                               SupportedVersions(GetParam()))),
+        session_(connection_, &session_visitor_),
+        configure_session_(configure_session) {
+    session_.config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session_.config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+
+    if (configure_session) {
+      if (VersionHasIetfQuicFrames(transport_version())) {
+        EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+        EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(true)).Times(1);
+      }
+      QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
+          session_.config(), kDefaultMaxStreamsPerConnection);
+      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+          session_.config(), kDefaultMaxStreamsPerConnection);
+      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+          session_.config(), kMinimumFlowControlSendWindow);
+      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+          session_.config(), kMinimumFlowControlSendWindow);
+      QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+          session_.config(), kMinimumFlowControlSendWindow);
+      QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+          session_.config(), kMinimumFlowControlSendWindow);
+      connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+      session_.OnConfigNegotiated();
+    }
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .Times(testing::AnyNumber());
+    testing::Mock::VerifyAndClearExpectations(&session_);
+  }
+
+  ~QuicSessionTestBase() {
+    if (configure_session_) {
+      EXPECT_TRUE(session_.is_configured());
+    }
+  }
+
+  void CheckClosedStreams() {
+    QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        connection_->transport_version(), Perspective::IS_CLIENT);
+    if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+      first_stream_id =
+          QuicUtils::GetCryptoStreamId(connection_->transport_version());
+    }
+    for (QuicStreamId i = first_stream_id; i < 100; i++) {
+      if (closed_streams_.find(i) == closed_streams_.end()) {
+        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
+      } else {
+        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
+      }
+    }
+  }
+
+  void CloseStream(QuicStreamId id) {
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      if (QuicUtils::GetStreamType(
+              id, session_.perspective(), session_.IsIncomingStream(id),
+              connection_->version()) == READ_UNIDIRECTIONAL) {
+        // Verify STOP_SENDING but no RESET_STREAM is sent for
+        // READ_UNIDIRECTIONAL streams.
+        EXPECT_CALL(*connection_, SendControlFrame(_))
+            .Times(1)
+            .WillOnce(Invoke(&ClearControlFrame));
+        EXPECT_CALL(*connection_, OnStreamReset(id, _)).Times(1);
+      } else if (QuicUtils::GetStreamType(
+                     id, session_.perspective(), session_.IsIncomingStream(id),
+                     connection_->version()) == WRITE_UNIDIRECTIONAL) {
+        // Verify RESET_STREAM but not STOP_SENDING is sent for write-only
+        // stream.
+        EXPECT_CALL(*connection_, SendControlFrame(_))
+            .Times(1)
+            .WillOnce(Invoke(&ClearControlFrame));
+        EXPECT_CALL(*connection_, OnStreamReset(id, _));
+      } else {
+        // Verify RESET_STREAM and STOP_SENDING are sent for BIDIRECTIONAL
+        // streams.
+        EXPECT_CALL(*connection_, SendControlFrame(_))
+            .Times(2)
+            .WillRepeatedly(Invoke(&ClearControlFrame));
+        EXPECT_CALL(*connection_, OnStreamReset(id, _));
+      }
+    } else {
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+      EXPECT_CALL(*connection_, OnStreamReset(id, _));
+    }
+    session_.ResetStream(id, QUIC_STREAM_CANCELLED);
+    closed_streams_.insert(id);
+  }
+
+  void CompleteHandshake() {
+    CryptoHandshakeMessage msg;
+    if (connection_->version().UsesTls() &&
+        connection_->perspective() == Perspective::IS_SERVER) {
+      // HANDSHAKE_DONE frame.
+      EXPECT_CALL(*connection_, SendControlFrame(_))
+          .WillOnce(Invoke(&ClearControlFrame));
+    }
+    session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+  }
+
+  QuicTransportVersion transport_version() const {
+    return connection_->transport_version();
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(
+               connection_->transport_version(), Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(connection_->transport_version()) * n;
+  }
+
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective,
+                               bool bidirectional) {
+    // Calculate and build up stream ID rather than use
+    // GetFirst... because tests that rely on this method
+    // needs to do the stream count where #1 is 0/1/2/3, and not
+    // take into account that stream 0 is special.
+    QuicStreamId id =
+        ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
+    if (!bidirectional) {
+      id |= 0x2;
+    }
+    if (perspective == Perspective::IS_SERVER) {
+      id |= 0x1;
+    }
+    return id;
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  NiceMock<MockQuicSessionVisitor> session_visitor_;
+  StrictMock<MockQuicConnection>* connection_;
+  TestSession session_;
+  std::set<QuicStreamId> closed_streams_;
+  bool configure_session_;
+};
+
+class QuicSessionTestServer : public QuicSessionTestBase {
+ public:
+  // CheckMultiPathResponse validates that a written packet
+  // contains both expected path responses.
+  WriteResult CheckMultiPathResponse(const char* buffer,
+                                     size_t buf_len,
+                                     const QuicIpAddress& /*self_address*/,
+                                     const QuicSocketAddress& /*peer_address*/,
+                                     PerPacketOptions* /*options*/) {
+    QuicEncryptedPacket packet(buffer, buf_len);
+    {
+      InSequence s;
+      EXPECT_CALL(framer_visitor_, OnPacket());
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+      EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+      EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_, _));
+      EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+      EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
+          .WillOnce(
+              WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
+                EXPECT_EQ(path_frame_buffer1_, frame.data_buffer);
+                return true;
+              })));
+      EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_))
+          .WillOnce(
+              WithArg<0>(Invoke([this](const QuicPathResponseFrame& frame) {
+                EXPECT_EQ(path_frame_buffer2_, frame.data_buffer);
+                return true;
+              })));
+      EXPECT_CALL(framer_visitor_, OnPacketComplete());
+    }
+    client_framer_.ProcessPacket(packet);
+    return WriteResult(WRITE_STATUS_OK, 0);
+  }
+
+ protected:
+  QuicSessionTestServer()
+      : QuicSessionTestBase(Perspective::IS_SERVER, /*configure_session=*/true),
+        path_frame_buffer1_({0, 1, 2, 3, 4, 5, 6, 7}),
+        path_frame_buffer2_({8, 9, 10, 11, 12, 13, 14, 15}),
+        client_framer_(SupportedVersions(GetParam()),
+                       QuicTime::Zero(),
+                       Perspective::IS_CLIENT,
+                       kQuicDefaultConnectionIdLength) {
+    client_framer_.set_visitor(&framer_visitor_);
+    client_framer_.SetInitialObfuscators(TestConnectionId());
+    if (client_framer_.version().KnowsWhichDecrypterToUse()) {
+      client_framer_.InstallDecrypter(
+          ENCRYPTION_FORWARD_SECURE,
+          std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+    }
+  }
+
+  QuicPathFrameBuffer path_frame_buffer1_;
+  QuicPathFrameBuffer path_frame_buffer2_;
+  StrictMock<MockFramerVisitor> framer_visitor_;
+  // Framer used to process packets sent by server.
+  QuicFramer client_framer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSessionTestServer,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSessionTestServer, PeerAddress) {
+  EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
+            session_.peer_address());
+}
+
+TEST_P(QuicSessionTestServer, SelfAddress) {
+  EXPECT_TRUE(session_.self_address().IsInitialized());
+}
+
+TEST_P(QuicSessionTestServer, DontCallOnWriteBlockedForDisconnectedConnection) {
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  connection_->CloseConnection(QUIC_NO_ERROR, "Everything is fine.",
+                               ConnectionCloseBehavior::SILENT_CLOSE);
+  ASSERT_FALSE(connection_->connected());
+
+  EXPECT_CALL(session_visitor_, OnWriteBlocked(_)).Times(0);
+  session_.OnWriteBlocked();
+}
+
+TEST_P(QuicSessionTestServer, OneRttKeysAvailable) {
+  EXPECT_FALSE(session_.OneRttKeysAvailable());
+  CompleteHandshake();
+  EXPECT_TRUE(session_.OneRttKeysAvailable());
+}
+
+TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
+  // Ensure that no streams are initially closed.
+  QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      connection_->transport_version(), Perspective::IS_CLIENT);
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    first_stream_id =
+        QuicUtils::GetCryptoStreamId(connection_->transport_version());
+  }
+  for (QuicStreamId i = first_stream_id; i < 100; i++) {
+    EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
+  }
+}
+
+TEST_P(QuicSessionTestServer, AvailableBidirectionalStreams) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(3)) != nullptr);
+  // Smaller bidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(2)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(2)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedBidirectionalId(1)) != nullptr);
+}
+
+TEST_P(QuicSessionTestServer, AvailableUnidirectionalStreams) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedUnidirectionalId(3)) != nullptr);
+  // Smaller unidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedUnidirectionalId(1)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedUnidirectionalId(2)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedUnidirectionalId(2)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthClientInitiatedUnidirectionalId(1)) != nullptr);
+}
+
+TEST_P(QuicSessionTestServer, MaxAvailableBidirectionalStreams) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_EQ(session_.max_open_incoming_bidirectional_streams(),
+              session_.MaxAvailableBidirectionalStreams());
+  } else {
+    // The protocol specification requires that there can be at least 10 times
+    // as many available streams as the connection's maximum open streams.
+    EXPECT_EQ(session_.max_open_incoming_bidirectional_streams() *
+                  kMaxAvailableStreamsMultiplier,
+              session_.MaxAvailableBidirectionalStreams());
+  }
+}
+
+TEST_P(QuicSessionTestServer, MaxAvailableUnidirectionalStreams) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_EQ(session_.max_open_incoming_unidirectional_streams(),
+              session_.MaxAvailableUnidirectionalStreams());
+  } else {
+    // The protocol specification requires that there can be at least 10 times
+    // as many available streams as the connection's maximum open streams.
+    EXPECT_EQ(session_.max_open_incoming_unidirectional_streams() *
+                  kMaxAvailableStreamsMultiplier,
+              session_.MaxAvailableUnidirectionalStreams());
+  }
+}
+
+TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamLocallyCreated) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedBidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamLocallyCreated) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingUnidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(0), stream2->id());
+  TestStream* stream4 = session_.CreateOutgoingUnidirectionalStream();
+  EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(1), stream4->id());
+
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedUnidirectionalId(0));
+  CheckClosedStreams();
+  CloseStream(GetNthServerInitiatedUnidirectionalId(1));
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedBidirectionalStreamPeerCreated) {
+  CompleteHandshake();
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
+  session_.GetOrCreateStream(stream_id1);
+  session_.GetOrCreateStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateStream(
+      stream_id2 +
+      2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedUnidirectionalStreamPeerCreated) {
+  CompleteHandshake();
+  QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
+  QuicStreamId stream_id2 = GetNthClientInitiatedUnidirectionalId(1);
+  session_.GetOrCreateStream(stream_id1);
+  session_.GetOrCreateStream(stream_id2);
+
+  CheckClosedStreams();
+  CloseStream(stream_id1);
+  CheckClosedStreams();
+  CloseStream(stream_id2);
+  // Create a stream, and make another available.
+  QuicStream* stream3 = session_.GetOrCreateStream(
+      stream_id2 +
+      2 * QuicUtils::StreamIdDelta(connection_->transport_version()));
+  CheckClosedStreams();
+  // Close one, but make sure the other is still not closed
+  CloseStream(stream3->id());
+  CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, MaximumAvailableOpenedBidirectionalStreams) {
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  session_.GetOrCreateStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr,
+            session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(
+                session_.max_open_incoming_bidirectional_streams() - 1)));
+}
+
+TEST_P(QuicSessionTestServer, MaximumAvailableOpenedUnidirectionalStreams) {
+  QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
+  session_.GetOrCreateStream(stream_id);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr,
+            session_.GetOrCreateStream(GetNthClientInitiatedUnidirectionalId(
+                session_.max_open_incoming_unidirectional_streams() - 1)));
+}
+
+TEST_P(QuicSessionTestServer, TooManyAvailableBidirectionalStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedBidirectionalId(
+      session_.MaxAvailableBidirectionalStreams() + 2);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // IETF QUIC terminates the connection with invalid stream id
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    // other versions terminate the connection with
+    // QUIC_TOO_MANY_AVAILABLE_STREAMS.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
+}
+
+TEST_P(QuicSessionTestServer, TooManyAvailableUnidirectionalStreams) {
+  QuicStreamId stream_id1 = GetNthClientInitiatedUnidirectionalId(0);
+  QuicStreamId stream_id2;
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id1));
+  // A stream ID which is too large to create.
+  stream_id2 = GetNthClientInitiatedUnidirectionalId(
+      session_.MaxAvailableUnidirectionalStreams() + 2);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // IETF QUIC terminates the connection with invalid stream id
+    EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
+  } else {
+    // other versions terminate the connection with
+    // QUIC_TOO_MANY_AVAILABLE_STREAMS.
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+  }
+  EXPECT_EQ(nullptr, session_.GetOrCreateStream(stream_id2));
+}
+
+TEST_P(QuicSessionTestServer, ManyAvailableBidirectionalStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 200);
+    // Smaller limit on unidirectional streams to help detect crossed wires.
+    QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 50);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  }
+  // Create a stream at the start of the range.
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+
+  // Create the largest stream ID of a threatened total of 200 streams.
+  // GetNth... starts at 0, so for 200 streams, get the 199th.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                         GetNthClientInitiatedBidirectionalId(199)));
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // If IETF QUIC, check to make sure that creating bidirectional
+    // streams does not mess up the unidirectional streams.
+    stream_id = GetNthClientInitiatedUnidirectionalId(0);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    // Now try to get the last possible unidirectional stream.
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedUnidirectionalId(49)));
+    // and this should fail because it exceeds the unidirectional limit
+    // (but not the bi-)
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID,
+                        "Stream id 798 would exceed stream count limit 50",
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+        .Times(1);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedUnidirectionalId(199)));
+  }
+}
+
+TEST_P(QuicSessionTestServer, ManyAvailableUnidirectionalStreams) {
+  // When max_open_streams_ is 200, should be able to create 200 streams
+  // out-of-order, that is, creating the one with the largest stream ID first.
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(&session_, 200);
+    // Smaller limit on unidirectional streams to help detect crossed wires.
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_, 50);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+  }
+  // Create one stream.
+  QuicStreamId stream_id = GetNthClientInitiatedUnidirectionalId(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+
+  // Create the largest stream ID of a threatened total of 200 streams.
+  // GetNth... starts at 0, so for 200 streams, get the 199th.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                         GetNthClientInitiatedUnidirectionalId(199)));
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // If IETF QUIC, check to make sure that creating unidirectional
+    // streams does not mess up the bidirectional streams.
+    stream_id = GetNthClientInitiatedBidirectionalId(0);
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(stream_id));
+    // Now try to get the last possible bidirectional stream.
+    EXPECT_NE(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedBidirectionalId(49)));
+    // and this should fail because it exceeds the bnidirectional limit
+    // (but not the uni-)
+    std::string error_detail;
+    if (QuicVersionUsesCryptoFrames(transport_version())) {
+      error_detail = "Stream id 796 would exceed stream count limit 50";
+    } else {
+      error_detail = "Stream id 800 would exceed stream count limit 50";
+    }
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID, error_detail,
+                        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
+        .Times(1);
+    EXPECT_EQ(nullptr, session_.GetOrCreateStream(
+                           GetNthClientInitiatedBidirectionalId(199)));
+  }
+}
+
+TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId closed_stream_id = stream2->id();
+  // Close the stream.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
+  stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+  std::string msg =
+      absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
+  EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
+                  msg);
+}
+
+TEST_P(QuicSessionTestServer, OnCanWrite) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  InSequence s;
+
+  // Reregister, to test the loop limit.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  // 2 will get called a second time as it didn't finish its block
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  // 4 will not get called, as we exceeded the loop limit.
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, TestBatchedWrites) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.set_writev_consumes_all_data(true);
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // With two sessions blocked, we should get two write calls.  They should both
+  // go to the first stream as it will only write 6k and mark itself blocked
+  // again.
+  InSequence s;
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+
+  // We should get one more call for stream2, at which point it has used its
+  // write quota and we move over to stream 4.
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  session_.OnCanWrite();
+
+  // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
+  // priority stream 6.  4 should be preempted.  6 will write but *not* block so
+  // will cede back to 4.
+  stream6->SetPriority(spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  EXPECT_CALL(*stream4, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendLargeFakeData(stream4, 6000);
+        session_.MarkConnectionLevelWriteBlocked(stream4->id());
+        session_.MarkConnectionLevelWriteBlocked(stream6->id());
+      }));
+  EXPECT_CALL(*stream6, OnCanWrite())
+      .WillOnce(Invoke([this, stream4, stream6]() {
+        session_.SendStreamData(stream6);
+        session_.SendLargeFakeData(stream4, 6000);
+      }));
+  session_.OnCanWrite();
+
+  // Stream4 alread did 6k worth of writes, so after doing another 12k it should
+  // cede and 2 should resume.
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendLargeFakeData(stream4, 12000);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendLargeFakeData(stream2, 6000);
+    session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  }));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
+  // Encryption needs to be established before data can be sent.
+  CompleteHandshake();
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow())
+      .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
+  EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+
+  // Expect that we only send one packet, the writes from different streams
+  // should be bundled together.
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.SendStreamData(stream6);
+  }));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  // stream4->OnCanWrite is not called.
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Still congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // stream4->OnCanWrite is called once the connection stops being
+  // congestion-control blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
+  CompleteHandshake();
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Drive packet writer manually.
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, SendStreamsBlocked) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
+    ASSERT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
+    session_.GetNextOutgoingBidirectionalStreamId();
+  }
+  // Next checking causes STREAMS_BLOCKED to be sent.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke([](const QuicFrame& frame) {
+        EXPECT_FALSE(frame.streams_blocked_frame.unidirectional);
+        EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+                  frame.streams_blocked_frame.stream_count);
+        ClearControlFrame(frame);
+        return true;
+      }));
+  EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
+
+  for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; ++i) {
+    ASSERT_TRUE(session_.CanOpenNextOutgoingUnidirectionalStream());
+    session_.GetNextOutgoingUnidirectionalStreamId();
+  }
+  // Next checking causes STREAM_BLOCKED to be sent.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke([](const QuicFrame& frame) {
+        EXPECT_TRUE(frame.streams_blocked_frame.unidirectional);
+        EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+                  frame.streams_blocked_frame.stream_count);
+        ClearControlFrame(frame);
+        return true;
+      }));
+  EXPECT_FALSE(session_.CanOpenNextOutgoingUnidirectionalStream());
+}
+
+TEST_P(QuicSessionTestServer, BufferedHandshake) {
+  // This test is testing behavior of crypto stream flow control, but when
+  // CRYPTO frames are used, there is no flow control for the crypto handshake.
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  session_.set_writev_consumes_all_data(true);
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.
+
+  // Test that blocking other streams does not change our status.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  TestStream* stream3 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream3->id());
+  EXPECT_FALSE(session_.HasPendingHandshake());
+
+  // Blocking (due to buffering of) the Crypto stream is detected.
+  session_.MarkConnectionLevelWriteBlocked(
+      QuicUtils::GetCryptoStreamId(connection_->transport_version()));
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  EXPECT_TRUE(session_.HasPendingHandshake());
+
+  InSequence s;
+  // Force most streams to re-register, which is common scenario when we block
+  // the Crypto stream, and only the crypto stream can "really" write.
+
+  // Due to prioritization, we *should* be asked to write the crypto stream
+  // first.
+  // Don't re-register the crypto stream (which signals complete writing).
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
+    session_.SendStreamData(stream3);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  CloseStream(stream6->id());
+
+  InSequence s;
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+    session_.SendStreamData(stream2);
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.SendStreamData(stream4);
+  }));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+  // Drive congestion control manually in order to ensure that
+  // application-limited signaling is handled correctly.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Ensure connection level flow control blockage.
+  QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+  EXPECT_TRUE(session_.flow_controller()->IsBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+
+  // Mark the crypto and headers streams as write blocked, we expect them to be
+  // allowed to write later.
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    session_.MarkConnectionLevelWriteBlocked(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()));
+  }
+
+  // Create a data stream, and although it is write blocked we never expect it
+  // to be allowed to write as we are connection level flow control blocked.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  session_.MarkConnectionLevelWriteBlocked(stream->id());
+  EXPECT_CALL(*stream, OnCanWrite()).Times(0);
+
+  // The crypto and headers streams should be called even though we are
+  // connection flow control blocked.
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+  }
+
+  // After the crypto and header streams perform a write, the connection will be
+  // blocked by the flow control, hence it should become application-limited.
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, SendGoAway) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
+    return;
+  }
+  CompleteHandshake();
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.transport_goaway_sent());
+
+  const QuicStreamId kTestStreamId = 5u;
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  EXPECT_CALL(*connection_,
+              OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
+      .Times(0);
+  EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
+}
+
+TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
+    return;
+  }
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+  EXPECT_TRUE(session_.transport_goaway_sent());
+  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+}
+
+TEST_P(QuicSessionTestServer, InvalidGoAway) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // In IETF QUIC, GOAWAY lives up in the HTTP layer.
+    return;
+  }
+  QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
+                          session_.next_outgoing_bidirectional_stream_id(), "");
+  session_.OnGoAway(go_away);
+}
+
+// Test that server session will send a connectivity probe in response to a
+// connectivity probe on the same path.
+TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  QuicSocketAddress old_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+
+  QuicSocketAddress new_peer_address =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
+
+  MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+      QuicConnectionPeer::GetWriter(session_.connection()));
+  EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+    EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _))
+        .WillOnce(
+            Invoke(connection_,
+                   &MockQuicConnection::ReallySendConnectivityProbingPacket));
+  session_.OnPacketReceived(session_.self_address(), new_peer_address,
+                            /*is_connectivity_probe=*/true);
+  EXPECT_EQ(old_peer_address, session_.peer_address());
+}
+
+TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+  CompleteHandshake();
+  EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
+            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    // The test relies on headers stream, which no longer exists in IETF QUIC.
+    return;
+  }
+  QuicStreamId headers_stream_id =
+      QuicUtils::GetHeadersStreamId(connection_->transport_version());
+  std::unique_ptr<TestStream> fake_headers_stream =
+      std::make_unique<TestStream>(headers_stream_id, &session_,
+                                   /*is_static*/ true, BIDIRECTIONAL);
+  QuicSessionPeer::ActivateStream(&session_, std::move(fake_headers_stream));
+  // Send two bytes of payload.
+  QuicStreamFrame data1(headers_stream_id, true, 0, absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicStreamFrame data1(
+      QuicUtils::GetInvalidStreamId(connection_->transport_version()), true, 0,
+      absl::string_view("HT"));
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
+  // Send two bytes of payload.
+  QuicRstStreamFrame rst1(
+      kInvalidControlFrameId,
+      QuicUtils::GetInvalidStreamId(connection_->transport_version()),
+      QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
+                  ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+  session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+  if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    // This test requires Google QUIC crypto because it assumes streams start
+    // off unblocked.
+    return;
+  }
+  // Test that if a stream is flow control blocked, then on receipt of the SHLO
+  // containing a suitable send window offset, the stream becomes unblocked.
+
+  // Ensure that Writev consumes all the data it is given (simulate no socket
+  // blocking).
+  session_.set_writev_consumes_all_data(true);
+  session_.GetMutableCryptoStream()->EstablishZeroRttEncryption();
+
+  // Create a stream, and send enough data to make it flow control blocked.
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(kMinimumFlowControlSendWindow, '.');
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
+  stream2->WriteOrBufferData(body, false, nullptr);
+  EXPECT_TRUE(stream2->IsFlowControlBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Now complete the crypto handshake, resulting in an increased flow control
+  // send window.
+  CompleteHandshake();
+  EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
+  CompleteHandshake();
+  // Test that when we receive an out of order stream RST we correctly adjust
+  // our connection level flow control receive window.
+  // On close, the stream should mark as consumed all bytes between the highest
+  // byte consumed so far and the final byte offset from the RST frame.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      1 + kInitialSessionFlowControlWindowForTest / 2;
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // The test requires the stream to be fully closed in both directions. For
+    // IETF QUIC, the RST_STREAM only closes one side.
+    QuicStopSendingFrame frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    session_.OnStopSendingFrame(frame);
+  }
+  EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
+  CompleteHandshake();
+  // Test the situation where we receive a FIN on a stream, and before we fully
+  // consume all the data from the sequencer buffer we locally RST the stream.
+  // The bytes between highest consumed byte, and the final byte offset that we
+  // determined when the FIN arrived, should be marked as consumed at the
+  // connection level flow controller when the stream is reset.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  const QuicStreamOffset kByteOffset =
+      kInitialSessionFlowControlWindowForTest / 2 - 1;
+  QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(connection_->connected());
+
+  EXPECT_EQ(0u, session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(kByteOffset + frame.data_length,
+            stream->highest_received_byte_offset());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(kByteOffset + frame.data_length,
+            session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
+  CompleteHandshake();
+  // Test that when we RST the stream (and tear down stream state), and then
+  // receive a FIN from the peer, we correctly adjust our connection level flow
+  // control receive window.
+
+  // Connection starts with some non-zero highest received byte offset,
+  // due to other active streams.
+  const uint64_t kInitialConnectionBytesConsumed = 567;
+  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+  EXPECT_LT(kInitialConnectionBytesConsumed,
+            kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->UpdateHighestReceivedOffset(
+      kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+  // Reset our stream: this results in the stream being closed locally.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+
+  // Now receive a response from the peer with a FIN. We should handle this by
+  // adjusting the connection level flow control receive window to take into
+  // account the total number of bytes sent by the peer.
+  const QuicStreamOffset kByteOffset = 5678;
+  std::string body = "hello";
+  QuicStreamFrame frame(stream->id(), true, kByteOffset,
+                        absl::string_view(body));
+  session_.OnStreamFrame(frame);
+
+  QuicStreamOffset total_stream_bytes_sent_by_peer =
+      kByteOffset + body.length();
+  EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
+            session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(
+      kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
+      session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
+  CompleteHandshake();
+  // Test that when we RST the stream (and tear down stream state), and then
+  // receive a RST from the peer, we correctly adjust our connection level flow
+  // control receive window.
+
+  // Connection starts with some non-zero highest received byte offset,
+  // due to other active streams.
+  const uint64_t kInitialConnectionBytesConsumed = 567;
+  const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+  EXPECT_LT(kInitialConnectionBytesConsumed,
+            kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->UpdateHighestReceivedOffset(
+      kInitialConnectionHighestReceivedOffset);
+  session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+  // Reset our stream: this results in the stream being closed locally.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  // Now receive a RST from the peer. We should handle this by adjusting the
+  // connection level flow control receive window to take into account the total
+  // number of bytes sent by the peer.
+  const QuicStreamOffset kByteOffset = 5678;
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kByteOffset);
+  session_.OnRstStream(rst_frame);
+
+  EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
+            session_.flow_controller()->bytes_consumed());
+  EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
+            session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+  // Test that receipt of an invalid (< default) stream flow control window from
+  // the peer results in the connection being torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
+                                                            kInvalidWindow);
+
+  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+  } else {
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+// Test negotiation of custom server initial flow control window.
+TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
+  QuicTagVector copt;
+  copt.push_back(kIFW7);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+  EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
+                             session_.flow_controller()));
+}
+
+TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
+  CompleteHandshake();
+  // Test that if we receive a stream RST with a highest byte offset that
+  // violates flow control, that we close the connection.
+  const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
+      .Times(2);
+
+  // Check that stream frame + FIN results in connection close.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  QuicStreamFrame frame(stream->id(), true, kLargeOffset, absl::string_view());
+  session_.OnStreamFrame(frame);
+
+  // Check that RST results in connection close.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+                               QUIC_STREAM_CANCELLED, kLargeOffset);
+  session_.OnRstStream(rst_frame);
+}
+
+TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
+  CompleteHandshake();
+  // If a buggy/malicious peer creates too many streams that are not ended
+  // with a FIN or RST then we send an RST to refuse streams. For IETF QUIC the
+  // connection is closed.
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(kMaxStreams);
+  // Create kMaxStreams data streams, and close them all without receiving a
+  // FIN or a RST_STREAM from the client.
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
+       i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
+    QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    CloseStream(i);
+  }
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(
+        *connection_,
+        CloseConnection(QUIC_INVALID_STREAM_ID,
+                        "Stream id 20 would exceed stream count limit 5", _));
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+    EXPECT_CALL(*connection_,
+                OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+        .Times(1);
+  }
+  // Create one more data streams to exceed limit of open stream.
+  QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpenedOutgoing) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+  QuicStreamFrame data1(stream_id, true, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+  }
+  session_.StreamDraining(stream_id, /*unidirectional=*/false);
+}
+
+TEST_P(QuicSessionTestServer, NoPendingStreams) {
+  session_.set_uses_pending_streams(false);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+}
+
+TEST_P(QuicSessionTestServer, PendingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(true);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+}
+
+TEST_P(QuicSessionTestServer, BufferAllIncomingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  // Read unidirectional stream is still buffered when the first byte arrives.
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  // Bidirectional stream is buffered.
+  QuicStreamId bidirectional_stream_id =
+      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                               Perspective::IS_CLIENT);
+  QuicStreamFrame data3(bidirectional_stream_id, false, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data3);
+  EXPECT_TRUE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  session_.ProcessAllPendingStreams();
+  // Both bidirectional and read-unidirectional streams are unbuffered.
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_FALSE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(2, session_.num_incoming_streams_created());
+}
+
+TEST_P(QuicSessionTestServer, RstPendingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  QuicRstStreamFrame rst1(kInvalidControlFrameId, stream_id,
+                          QUIC_ERROR_PROCESSING_STREAM, 12);
+  session_.OnRstStream(rst1);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  QuicStreamFrame data2(stream_id, false, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  session_.ProcessAllPendingStreams();
+  // Bidirectional stream is buffered.
+  QuicStreamId bidirectional_stream_id =
+      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                               Perspective::IS_CLIENT);
+  QuicStreamFrame data3(bidirectional_stream_id, false, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data3);
+  EXPECT_TRUE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  // Bidirectional pending stream is removed after RST_STREAM is received.
+  QuicRstStreamFrame rst2(kInvalidControlFrameId, bidirectional_stream_id,
+                          QUIC_ERROR_PROCESSING_STREAM, 12);
+  session_.OnRstStream(rst2);
+  EXPECT_FALSE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+}
+
+TEST_P(QuicSessionTestServer, OnFinPendingStreams) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(true);
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data(stream_id, true, 0, "");
+  session_.OnStreamFrame(data);
+
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+
+  session_.set_process_pending_stream_immediately(false);
+  // Bidirectional pending stream remains after Fin is received.
+  // Bidirectional stream is buffered.
+  QuicStreamId bidirectional_stream_id =
+      QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                               Perspective::IS_CLIENT);
+  QuicStreamFrame data2(bidirectional_stream_id, true, 0,
+                        absl::string_view("HT"));
+  session_.OnStreamFrame(data2);
+  EXPECT_TRUE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  session_.ProcessAllPendingStreams();
+  EXPECT_FALSE(
+      QuicSessionPeer::GetPendingStream(&session_, bidirectional_stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+  QuicStream* bidirectional_stream =
+      QuicSessionPeer::GetStream(&session_, bidirectional_stream_id);
+  EXPECT_TRUE(bidirectional_stream->fin_received());
+}
+
+TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnWindowUpdate) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
+                                            0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+          "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
+  session_.OnWindowUpdateFrame(window_update_frame);
+}
+
+TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnWindowUpdate) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data);
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
+                                            kDefaultFlowControlSendWindow * 2);
+  session_.OnWindowUpdateFrame(window_update_frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  session_.ProcessAllPendingStreams();
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+  QuicStream* bidirectional_stream =
+      QuicSessionPeer::GetStream(&session_, stream_id);
+  QuicByteCount send_window =
+      QuicStreamPeer::SendWindowSize(bidirectional_stream);
+  EXPECT_EQ(send_window, kDefaultFlowControlSendWindow * 2);
+}
+
+TEST_P(QuicSessionTestServer, UnidirectionalPendingStreamOnStopSending) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data1(stream_id, true, 10, absl::string_view("HT"));
+  session_.OnStreamFrame(data1);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+  QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
+                                          QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received STOP_SENDING for a read-only stream", _));
+  session_.OnStopSendingFrame(stop_sending_frame);
+}
+
+TEST_P(QuicSessionTestServer, BidirectionalPendingStreamOnStopSending) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+
+  session_.set_uses_pending_streams(true);
+  session_.set_process_pending_stream_immediately(false);
+  QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      transport_version(), Perspective::IS_CLIENT);
+  QuicStreamFrame data(stream_id, true, 0, absl::string_view("HT"));
+  session_.OnStreamFrame(data);
+  QuicStopSendingFrame stop_sending_frame(kInvalidControlFrameId, stream_id,
+                                          QUIC_STREAM_CANCELLED);
+  session_.OnStopSendingFrame(stop_sending_frame);
+  EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(0, session_.num_incoming_streams_created());
+
+  EXPECT_CALL(*connection_, OnStreamReset(stream_id, _));
+  session_.ProcessAllPendingStreams();
+  EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&session_, stream_id));
+  EXPECT_EQ(1, session_.num_incoming_streams_created());
+  QuicStream* bidirectional_stream =
+      QuicSessionPeer::GetStream(&session_, stream_id);
+  EXPECT_TRUE(bidirectional_stream->write_side_closed());
+}
+
+TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+  // Verify that a draining stream (which has received a FIN but not consumed
+  // it) does not count against the open quota (because it is closed from the
+  // protocol point of view).
+  CompleteHandshake();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // On IETF QUIC, we will expect to see a MAX_STREAMS go out when there are
+    // not enough streams to create the next one.
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  } else {
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
+  const QuicStreamId kMaxStreams = 5;
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&session_,
+                                                            kMaxStreams);
+  } else {
+    QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+  }
+
+  // Create kMaxStreams + 1 data streams, and mark them draining.
+  const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
+  const QuicStreamId kFinalStreamId =
+      GetNthClientInitiatedBidirectionalId(2 * kMaxStreams + 1);
+  for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId;
+       i += QuicUtils::StreamIdDelta(connection_->transport_version())) {
+    QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
+    session_.OnStreamFrame(data1);
+    EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+    session_.StreamDraining(i, /*unidirectional=*/false);
+    EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
+  }
+}
+
+class QuicSessionTestClient : public QuicSessionTestBase {
+ protected:
+  QuicSessionTestClient()
+      : QuicSessionTestBase(Perspective::IS_CLIENT,
+                            /*configure_session=*/true) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSessionTestClient,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSessionTestClient, AvailableBidirectionalStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(2)) != nullptr);
+  // Smaller bidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedBidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedBidirectionalId(1)) != nullptr);
+  // And 5 should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedBidirectionalId(1)));
+}
+
+TEST_P(QuicSessionTestClient, InvalidSessionFlowControlWindowInHandshake) {
+  // Test that receipt of an invalid (< default for gQUIC, < current for TLS)
+  // session flow control window from the peer results in the connection being
+  // torn down.
+  const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
+                                                             kInvalidWindow);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(connection_->version().AllowsLowFlowControlLimits()
+                          ? QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED
+                          : QUIC_FLOW_CONTROL_INVALID_WINDOW,
+                      _, _));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, InvalidBidiStreamLimitInHandshake) {
+  // IETF QUIC only feature.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
+      session_.config(), kDefaultMaxStreamsPerConnection - 1);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, InvalidUniStreamLimitInHandshake) {
+  // IETF QUIC only feature.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+      session_.config(), kDefaultMaxStreamsPerConnection - 1);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, InvalidStreamFlowControlWindowInHandshake) {
+  // IETF QUIC only feature.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  session_.CreateOutgoingBidirectionalStream();
+  session_.CreateOutgoingBidirectionalStream();
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+      session_.config(), kMinimumFlowControlSendWindow - 1);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _))
+      .WillOnce(
+          Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
+  EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
+
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestClient, OnMaxStreamFrame) {
+  if (!VersionUsesHttp3(transport_version())) {
+    return;
+  }
+  QuicMaxStreamsFrame frame;
+  frame.unidirectional = false;
+  frame.stream_count = 120;
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+  session_.OnMaxStreamsFrame(frame);
+
+  QuicMaxStreamsFrame frame2;
+  frame2.unidirectional = false;
+  frame2.stream_count = 110;
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
+  session_.OnMaxStreamsFrame(frame2);
+}
+
+TEST_P(QuicSessionTestClient, AvailableUnidirectionalStreamsClient) {
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedUnidirectionalId(2)) != nullptr);
+  // Smaller unidirectional streams should be available.
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedUnidirectionalId(0)));
+  EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthServerInitiatedUnidirectionalId(1)));
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedUnidirectionalId(0)) != nullptr);
+  ASSERT_TRUE(session_.GetOrCreateStream(
+                  GetNthServerInitiatedUnidirectionalId(1)) != nullptr);
+  // And 5 should be not available.
+  EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
+      &session_, GetNthClientInitiatedUnidirectionalId(1)));
+}
+
+TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
+  CompleteHandshake();
+  // Verify that an incoming FIN is recorded in a stream object even if the read
+  // side has been closed.  This prevents an entry from being made in
+  // locally_closed_streams_highest_offset_ (which will never be deleted).
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+
+  // Close the read side manually.
+  QuicStreamPeer::CloseReadSide(stream);
+
+  // Receive a stream data frame with FIN.
+  QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
+  session_.OnStreamFrame(frame);
+  EXPECT_TRUE(stream->fin_received());
+
+  // Reset stream locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  stream->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+  EXPECT_TRUE(connection_->connected());
+  EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
+  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
+
+  // The stream is not waiting for the arrival of the peer's final offset as it
+  // was received with the FIN earlier.
+  EXPECT_EQ(
+      0u,
+      QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
+}
+
+TEST_P(QuicSessionTestClient, IncomingStreamWithClientInitiatedStreamId) {
+  const QuicErrorCode expected_error =
+      VersionHasIetfQuicFrames(transport_version())
+          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+          : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(expected_error, "Data for nonexistent stream",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(1),
+                        /* fin = */ false, /* offset = */ 0,
+                        absl::string_view("foo"));
+  session_.OnStreamFrame(frame);
+}
+
+TEST_P(QuicSessionTestClient, MinAckDelaySetOnTheClientQuicConfig) {
+  if (!session_.version().HasIetfQuicFrames()) {
+    return;
+  }
+  session_.config()->SetClientConnectionOptions({kAFFE});
+  session_.Initialize();
+  ASSERT_EQ(session_.config()->GetMinAckDelayToSendMs(),
+            kDefaultMinAckDelayTimeMs);
+  ASSERT_TRUE(session_.connection()->can_receive_ack_frequency_frame());
+}
+
+TEST_P(QuicSessionTestClient, FailedToCreateStreamIfTooCloseToIdleTimeout) {
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
+  QuicTime deadline = QuicConnectionPeer::GetIdleNetworkDeadline(connection_);
+  ASSERT_TRUE(deadline.IsInitialized());
+  QuicTime::Delta timeout = deadline - helper_.GetClock()->ApproximateNow();
+  // Advance time to very close idle timeout.
+  connection_->AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
+  // Verify creation of new stream gets pushed back and connectivity probing
+  // packet gets sent.
+  EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _)).Times(1);
+  EXPECT_FALSE(session_.CanOpenNextOutgoingBidirectionalStream());
+
+  // New packet gets received, idle deadline gets extended.
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false));
+  QuicConnectionPeer::GetIdleNetworkDetector(connection_)
+      .OnPacketReceived(helper_.GetClock()->ApproximateNow());
+  session_.OnPacketDecrypted(ENCRYPTION_FORWARD_SECURE);
+
+  EXPECT_TRUE(session_.CanOpenNextOutgoingBidirectionalStream());
+}
+
+TEST_P(QuicSessionTestServer, ZombieStreams) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+
+  CloseStream(stream2->id());
+  ASSERT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+  session_.MaybeCloseZombieStream(stream2->id());
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+}
+
+TEST_P(QuicSessionTestServer, RstStreamReceivedAfterRstStreamSent) {
+  CompleteHandshake();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamPeer::SetStreamBytesWritten(3, stream2);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
+  EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(0);
+  stream2->Reset(quic::QUIC_STREAM_CANCELLED);
+
+  QuicRstStreamFrame rst1(kInvalidControlFrameId, stream2->id(),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(session_, OnCanCreateNewOutgoingStream(false)).Times(1);
+  }
+  session_.OnRstStream(rst1);
+}
+
+// Regression test of b/71548958.
+TEST_P(QuicSessionTestServer, TestZombieStreams) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(100, '.');
+  stream2->WriteOrBufferData(body, false, nullptr);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  // Just for the RST_STREAM
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream2->id(), QUIC_STREAM_CANCELLED));
+  } else {
+    EXPECT_CALL(*connection_,
+                OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  stream2->OnStreamReset(rst_frame);
+
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // The test requires the stream to be fully closed in both directions. For
+    // IETF QUIC, the RST_STREAM only closes one side.
+    QuicStopSendingFrame frame(kInvalidControlFrameId, stream2->id(),
+                               QUIC_STREAM_CANCELLED);
+    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+    session_.OnStopSendingFrame(frame);
+  }
+  ASSERT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Once for the RST_STREAM, once for the STOP_SENDING
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .Times(2)
+        .WillRepeatedly(Invoke(&ClearControlFrame));
+  } else {
+    // Just for the RST_STREAM
+    EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  }
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
+  stream4->WriteOrBufferData(body, false, nullptr);
+  // Note well: Reset() actually closes the stream in both directions. For
+  // GOOGLE QUIC it sends a RST_STREAM (which does a 2-way close), for IETF
+  // QUIC it sends both a RST_STREAM and a STOP_SENDING (each of which
+  // closes in only one direction).
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(2u, session_.closed_streams()->size());
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
+  CompleteHandshake();
+  InSequence s;
+
+  // Drive congestion control manually.
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1;
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    frame1 = QuicStreamFrame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
+        0, 1300);
+  }
+  QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+  // Lost data on cryption stream, streams 2 and 4.
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(true));
+  }
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    session_.OnFrameLost(QuicFrame(frame1));
+  } else {
+    QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
+    session_.OnFrameLost(QuicFrame(&crypto_frame));
+  }
+  session_.OnFrameLost(QuicFrame(frame2));
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Mark streams 2 and 4 write blocked.
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+  // Lost data is retransmitted before new data, and retransmissions for crypto
+  // stream go first.
+  // Do not check congestion window when crypto stream has lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    EXPECT_CALL(*crypto_stream, OnCanWrite());
+    EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+        .WillOnce(Return(false));
+  }
+  // Check congestion window for non crypto streams.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+  // Connection is blocked.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+  session_.OnCanWrite();
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  // Unblock connection.
+  // Stream 2 retransmits lost data.
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  // Stream 2 sends new data.
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
+  CompleteHandshake();
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+  session_.OnFrameLost(QuicFrame(frame3));
+  session_.OnFrameLost(QuicFrame(frame2));
+  session_.OnFrameLost(QuicFrame(frame1));
+
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  // Reset stream 4 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
+  stream4->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 4 is removed from streams with lost data list.
+  EXPECT_CALL(*stream6, OnCanWrite());
+  EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, RetransmitFrames) {
+  CompleteHandshake();
+  MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+  QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+  InSequence s;
+
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  session_.SendWindowUpdate(stream2->id(), 9);
+
+  QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+  QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+  QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+  QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame1));
+  frames.push_back(QuicFrame(window_update));
+  frames.push_back(QuicFrame(frame2));
+  frames.push_back(QuicFrame(frame3));
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
+      .WillOnce(Return(true));
+  EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+  session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+}
+
+// Regression test of b/110082001.
+TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
+  CompleteHandshake();
+  // This test mimics the scenario when a dynamic stream retransmits lost data
+  // and causes connection close.
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamFrame frame(stream->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream, HasPendingRetransmission())
+      .Times(2)
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  session_.OnFrameLost(QuicFrame(frame));
+  // Retransmit stream data causes connection close. Stream has not sent fin
+  // yet, so an RST is sent.
+  EXPECT_CALL(*stream, OnCanWrite()).WillOnce(Invoke([this, stream]() {
+    session_.ResetStream(stream->id(), QUIC_STREAM_CANCELLED);
+  }));
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    // Once for the RST_STREAM, once for the STOP_SENDING
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .Times(2)
+        .WillRepeatedly(Invoke(&session_, &TestSession::SaveFrame));
+  } else {
+    // Just for the RST_STREAM
+    EXPECT_CALL(*connection_, SendControlFrame(_))
+        .WillOnce(Invoke(&session_, &TestSession::SaveFrame));
+  }
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, SendMessage) {
+  // Cannot send message when encryption is not established.
+  EXPECT_FALSE(session_.OneRttKeysAvailable());
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0),
+            session_.SendMessage(MemSliceFromString("")));
+
+  CompleteHandshake();
+  EXPECT_TRUE(session_.OneRttKeysAvailable());
+
+  EXPECT_CALL(*connection_, SendMessage(1, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
+            session_.SendMessage(MemSliceFromString("")));
+  // Verify message_id increases.
+  EXPECT_CALL(*connection_, SendMessage(2, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_TOO_LARGE));
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_TOO_LARGE, 0),
+            session_.SendMessage(MemSliceFromString("")));
+  // Verify unsent message does not consume a message_id.
+  EXPECT_CALL(*connection_, SendMessage(2, _, false))
+      .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
+  EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 2),
+            session_.SendMessage(MemSliceFromString("")));
+
+  QuicMessageFrame frame(1);
+  QuicMessageFrame frame2(2);
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
+
+  // Lost message 2.
+  session_.OnMessageLost(2);
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame2)));
+
+  // message 1 gets acked.
+  session_.OnMessageAcked(1, QuicTime::Zero());
+  EXPECT_FALSE(session_.IsFrameOutstanding(QuicFrame(&frame)));
+}
+
+// Regression test of b/115323618.
+TEST_P(QuicSessionTestServer, LocallyResetZombieStreams) {
+  CompleteHandshake();
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  std::string body(100, '.');
+  QuicStreamPeer::CloseReadSide(stream2);
+  stream2->WriteOrBufferData(body, true, nullptr);
+  EXPECT_TRUE(stream2->IsWaitingForAcks());
+  // Verify stream2 is a zombie streams.
+  auto& stream_map = QuicSessionPeer::stream_map(&session_);
+  ASSERT_TRUE(stream_map.contains(stream2->id()));
+  auto* stream = stream_map.find(stream2->id())->second.get();
+  EXPECT_TRUE(stream->IsZombie());
+
+  QuicStreamFrame frame(stream2->id(), true, 0, 100);
+  EXPECT_CALL(*stream2, HasPendingRetransmission())
+      .WillRepeatedly(Return(true));
+  session_.OnFrameLost(QuicFrame(frame));
+
+  // Reset stream2 locally.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(stream2->id(), _));
+  stream2->Reset(QUIC_STREAM_CANCELLED);
+
+  // Verify stream 2 gets closed.
+  EXPECT_TRUE(session_.IsClosedStream(stream2->id()));
+  EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+  session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, CleanUpClosedStreamsAlarm) {
+  CompleteHandshake();
+  EXPECT_FALSE(
+      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
+
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_FALSE(stream2->IsWaitingForAcks());
+
+  CloseStream(stream2->id());
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+  EXPECT_TRUE(
+      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_)->IsSet());
+
+  alarm_factory_.FireAlarm(
+      QuicSessionPeer::GetCleanUpClosedStreamsAlarm(&session_));
+  EXPECT_TRUE(session_.closed_streams()->empty());
+}
+
+TEST_P(QuicSessionTestServer, WriteUnidirectionalStream) {
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
+                                       &session_, WRITE_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+  std::string body(100, '.');
+  stream4->WriteOrBufferData(body, false, nullptr);
+  stream4->WriteOrBufferData(body, true, nullptr);
+  auto& stream_map = QuicSessionPeer::stream_map(&session_);
+  ASSERT_TRUE(stream_map.contains(stream4->id()));
+  auto* stream = stream_map.find(stream4->id())->second.get();
+  EXPECT_TRUE(stream->IsZombie());
+}
+
+TEST_P(QuicSessionTestServer, ReceivedDataOnWriteUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthServerInitiatedUnidirectionalId(1),
+                                       &session_, WRITE_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  QuicStreamFrame stream_frame(GetNthServerInitiatedUnidirectionalId(1), false,
+                               0, 2);
+  session_.OnStreamFrame(stream_frame);
+}
+
+TEST_P(QuicSessionTestServer, ReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+  EXPECT_FALSE(stream4->IsWaitingForAcks());
+  // Discard all incoming data.
+  stream4->StopReading();
+
+  std::string data(100, '.');
+  QuicStreamFrame stream_frame(GetNthClientInitiatedUnidirectionalId(1), false,
+                               0, data);
+  stream4->OnStreamFrame(stream_frame);
+  EXPECT_TRUE(session_.closed_streams()->empty());
+
+  QuicStreamFrame stream_frame2(GetNthClientInitiatedUnidirectionalId(1), true,
+                                100, data);
+  stream4->OnStreamFrame(stream_frame2);
+  EXPECT_EQ(1u, session_.closed_streams()->size());
+}
+
+TEST_P(QuicSessionTestServer, WriteOrBufferDataOnReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  std::string body(100, '.');
+  stream4->WriteOrBufferData(body, false, nullptr);
+}
+
+TEST_P(QuicSessionTestServer, WritevDataOnReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  std::string body(100, '.');
+  struct iovec iov = {const_cast<char*>(body.data()), body.length()};
+  quiche::QuicheMemSliceStorage storage(
+      &iov, 1, session_.connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  stream4->WriteMemSlices(storage.ToSpan(), false);
+}
+
+TEST_P(QuicSessionTestServer, WriteMemSlicesOnReadUnidirectionalStream) {
+  TestStream* stream4 = new TestStream(GetNthClientInitiatedUnidirectionalId(1),
+                                       &session_, READ_UNIDIRECTIONAL);
+  session_.ActivateStream(absl::WrapUnique(stream4));
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(
+                  QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM, _, _))
+      .Times(1);
+  std::string data(1024, 'a');
+  std::vector<quiche::QuicheMemSlice> buffers;
+  buffers.push_back(MemSliceFromString(data));
+  buffers.push_back(MemSliceFromString(data));
+  stream4->WriteMemSlices(absl::MakeSpan(buffers), false);
+}
+
+// Test code that tests that an incoming stream frame with a new (not previously
+// seen) stream id is acceptable. The ID must not be larger than has been
+// advertised. It may be equal to what has been advertised.  These tests
+// invoke QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId by calling
+// QuicSession::OnStreamFrame in order to check that all the steps are connected
+// properly and that nothing in the call path interferes with the check.
+// First test make sure that streams with ids below the limit are accepted.
+TEST_P(QuicSessionTestServer, NewStreamIdBelowLimit) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+  QuicStreamId bidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_bidirectional_streams() -
+          1,
+      Perspective::IS_CLIENT,
+      /*bidirectional=*/true);
+
+  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
+                                             "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(bidirectional_stream_frame);
+
+  QuicStreamId unidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_unidirectional_streams() -
+          1,
+      Perspective::IS_CLIENT,
+      /*bidirectional=*/false);
+  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
+                                              0, "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(unidirectional_stream_frame);
+}
+
+// Accept a stream with an ID that equals the limit.
+TEST_P(QuicSessionTestServer, NewStreamIdAtLimit) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+  QuicStreamId bidirectional_stream_id =
+      StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                          ->advertised_max_incoming_bidirectional_streams(),
+                      Perspective::IS_CLIENT, /*bidirectional=*/true);
+  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
+                                             "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(bidirectional_stream_frame);
+
+  QuicStreamId unidirectional_stream_id =
+      StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&session_)
+                          ->advertised_max_incoming_unidirectional_streams(),
+                      Perspective::IS_CLIENT, /*bidirectional=*/false);
+  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
+                                              0, "Random String");
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStreamFrame(unidirectional_stream_frame);
+}
+
+// Close the connection if the id exceeds the limit.
+TEST_P(QuicSessionTestServer, NewStreamIdAboveLimit) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+
+  QuicStreamId bidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_bidirectional_streams() +
+          1,
+      Perspective::IS_CLIENT, /*bidirectional=*/true);
+  QuicStreamFrame bidirectional_stream_frame(bidirectional_stream_id, false, 0,
+                                             "Random String");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Stream id 400 would exceed stream count limit 100", _));
+  session_.OnStreamFrame(bidirectional_stream_frame);
+
+  QuicStreamId unidirectional_stream_id = StreamCountToId(
+      QuicSessionPeer::ietf_streamid_manager(&session_)
+              ->advertised_max_incoming_unidirectional_streams() +
+          1,
+      Perspective::IS_CLIENT, /*bidirectional=*/false);
+  QuicStreamFrame unidirectional_stream_frame(unidirectional_stream_id, false,
+                                              0, "Random String");
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Stream id 402 would exceed stream count limit 100", _));
+  session_.OnStreamFrame(unidirectional_stream_frame);
+}
+
+// Checks that invalid stream ids are handled.
+TEST_P(QuicSessionTestServer, OnStopSendingInvalidStreamId) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  // Check that "invalid" stream ids are rejected.
+  QuicStopSendingFrame frame(1, -1, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received STOP_SENDING for an invalid stream", _));
+  session_.OnStopSendingFrame(frame);
+}
+
+TEST_P(QuicSessionTestServer, OnStopSendingReadUnidirectional) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  // It's illegal to send STOP_SENDING with a stream ID that is read-only.
+  QuicStopSendingFrame frame(1, GetNthClientInitiatedUnidirectionalId(1),
+                             QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(QUIC_INVALID_STREAM_ID,
+                      "Received STOP_SENDING for a read-only stream", _));
+  session_.OnStopSendingFrame(frame);
+}
+
+// Static streams ignore STOP_SENDING.
+TEST_P(QuicSessionTestServer, OnStopSendingStaticStreams) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicStreamId stream_id = 0;
+  std::unique_ptr<TestStream> fake_static_stream = std::make_unique<TestStream>(
+      stream_id, &session_, /*is_static*/ true, BIDIRECTIONAL);
+  QuicSessionPeer::ActivateStream(&session_, std::move(fake_static_stream));
+  // Check that a stream id in the static stream map is ignored.
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_STREAM_ID,
+                              "Received STOP_SENDING for a static stream", _));
+  session_.OnStopSendingFrame(frame);
+}
+
+// If stream is write closed, do not send a RESET_STREAM frame.
+TEST_P(QuicSessionTestServer, OnStopSendingForWriteClosedStream) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+  QuicStreamPeer::SetFinSent(stream);
+  stream->CloseWriteSide();
+  EXPECT_TRUE(stream->write_side_closed());
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStopSendingFrame(frame);
+}
+
+// If stream is closed, return true and do not close the connection.
+TEST_P(QuicSessionTestServer, OnStopSendingClosedStream) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  CompleteHandshake();
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamId stream_id = stream->id();
+  CloseStream(stream_id);
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStopSendingFrame(frame);
+}
+
+// If stream id is a nonexistent local stream, return false and close the
+// connection.
+TEST_P(QuicSessionTestServer, OnStopSendingInputNonExistentLocalStream) {
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+
+  QuicStopSendingFrame frame(1, GetNthServerInitiatedBidirectionalId(123456),
+                             QUIC_STREAM_CANCELLED);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_STREAM_WRONG_DIRECTION,
+                                            "Data for nonexistent stream", _))
+      .Times(1);
+  session_.OnStopSendingFrame(frame);
+}
+
+// If a STOP_SENDING is received for a peer initiated stream, the new stream
+// will be created.
+TEST_P(QuicSessionTestServer, OnStopSendingNewStream) {
+  CompleteHandshake();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+  QuicStopSendingFrame frame(1, GetNthClientInitiatedBidirectionalId(1),
+                             QUIC_STREAM_CANCELLED);
+
+  // A Rst will be sent as a response for STOP_SENDING.
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
+  session_.OnStopSendingFrame(frame);
+
+  QuicStream* stream =
+      session_.GetOrCreateStream(GetNthClientInitiatedBidirectionalId(1));
+  EXPECT_TRUE(stream);
+  EXPECT_TRUE(stream->write_side_closed());
+}
+
+// For a valid stream, ensure that all works
+TEST_P(QuicSessionTestServer, OnStopSendingInputValidStream) {
+  CompleteHandshake();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // Applicable only to IETF QUIC
+    return;
+  }
+
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+
+  // Ensure that the stream starts out open in both directions.
+  EXPECT_FALSE(stream->write_side_closed());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
+
+  QuicStreamId stream_id = stream->id();
+  QuicStopSendingFrame frame(1, stream_id, QUIC_STREAM_CANCELLED);
+  // Expect a reset to come back out.
+  EXPECT_CALL(*connection_, SendControlFrame(_));
+  EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_STREAM_CANCELLED));
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  session_.OnStopSendingFrame(frame);
+
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream));
+  EXPECT_TRUE(stream->write_side_closed());
+}
+
+TEST_P(QuicSessionTestServer, WriteBufferedCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    return;
+  }
+  std::string data(1350, 'a');
+  TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+  // Only consumed 1000 bytes.
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+      .WillOnce(Return(1000));
+  crypto_stream->WriteCryptoData(ENCRYPTION_INITIAL, data);
+  EXPECT_TRUE(session_.HasPendingHandshake());
+  EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+  connection_->SetEncrypter(
+      ENCRYPTION_ZERO_RTT,
+      std::make_unique<NullEncrypter>(connection_->perspective()));
+  crypto_stream->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
+      .WillOnce(Return(350));
+  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+      .WillOnce(Return(1350));
+  session_.OnCanWrite();
+  EXPECT_FALSE(session_.HasPendingHandshake());
+  EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+// Regression test for
+// https://bugs.chromium.org/p/chromium/issues/detail?id=1002119
+TEST_P(QuicSessionTestServer, StreamFrameReceivedAfterFin) {
+  TestStream* stream = session_.CreateOutgoingBidirectionalStream();
+  QuicStreamFrame frame(stream->id(), true, 0, ",");
+  session_.OnStreamFrame(frame);
+
+  QuicStreamFrame frame1(stream->id(), false, 1, ",");
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET, _, _));
+  session_.OnStreamFrame(frame1);
+}
+
+TEST_P(QuicSessionTestServer, ResetForIETFStreamTypes) {
+  CompleteHandshake();
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    return;
+  }
+
+  QuicStreamId read_only = GetNthClientInitiatedUnidirectionalId(0);
+
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(1)
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
+  session_.ResetStream(read_only, QUIC_STREAM_CANCELLED);
+
+  QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0);
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(1)
+      .WillOnce(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(write_only, _));
+  session_.ResetStream(write_only, QUIC_STREAM_CANCELLED);
+
+  QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0);
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(2)
+      .WillRepeatedly(Invoke(&ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _));
+  session_.ResetStream(bidirectional, QUIC_STREAM_CANCELLED);
+}
+
+TEST_P(QuicSessionTestServer, DecryptionKeyAvailableBeforeEncryptionKey) {
+  if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
+    return;
+  }
+  ASSERT_FALSE(connection_->framer().HasEncrypterOfEncryptionLevel(
+      ENCRYPTION_HANDSHAKE));
+  EXPECT_FALSE(session_.OnNewDecryptionKeyAvailable(
+      ENCRYPTION_HANDSHAKE, /*decrypter=*/nullptr,
+      /*set_alternative_decrypter=*/false, /*latch_once_used=*/false));
+}
+
+TEST_P(QuicSessionTestServer, IncomingStreamWithServerInitiatedStreamId) {
+  const QuicErrorCode expected_error =
+      VersionHasIetfQuicFrames(transport_version())
+          ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+          : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(expected_error, "Data for nonexistent stream",
+                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+
+  QuicStreamFrame frame(GetNthServerInitiatedBidirectionalId(1),
+                        /* fin = */ false, /* offset = */ 0,
+                        absl::string_view("foo"));
+  session_.OnStreamFrame(frame);
+}
+
+// A client test class that can be used when the automatic configuration is not
+// desired.
+class QuicSessionTestClientUnconfigured : public QuicSessionTestBase {
+ protected:
+  QuicSessionTestClientUnconfigured()
+      : QuicSessionTestBase(Perspective::IS_CLIENT,
+                            /*configure_session=*/false) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSessionTestClientUnconfigured,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSessionTestClientUnconfigured, StreamInitiallyBlockedThenUnblocked) {
+  if (!connection_->version().AllowsLowFlowControlLimits()) {
+    return;
+  }
+  // Create a stream before negotiating the config and verify it starts off
+  // blocked.
+  QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(&session_, 10);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  EXPECT_TRUE(stream2->IsFlowControlBlocked());
+  EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+  // Negotiate the config with higher received limits.
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+      session_.config(), kMinimumFlowControlSendWindow);
+  QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+      session_.config(), kMinimumFlowControlSendWindow);
+  session_.OnConfigNegotiated();
+
+  // Stream is now unblocked.
+  EXPECT_FALSE(stream2->IsFlowControlBlocked());
+  EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+  EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_socket_address_coder.cc b/quiche/quic/core/quic_socket_address_coder.cc
new file mode 100644
index 0000000..9bf85b2
--- /dev/null
+++ b/quiche/quic/core/quic_socket_address_coder.cc
@@ -0,0 +1,92 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_socket_address_coder.h"
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quic {
+
+namespace {
+
+// For convenience, the values of these constants match the values of AF_INET
+// and AF_INET6 on Linux.
+const uint16_t kIPv4 = 2;
+const uint16_t kIPv6 = 10;
+
+}  // namespace
+
+QuicSocketAddressCoder::QuicSocketAddressCoder() {}
+
+QuicSocketAddressCoder::QuicSocketAddressCoder(const QuicSocketAddress& address)
+    : address_(address) {}
+
+QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
+
+std::string QuicSocketAddressCoder::Encode() const {
+  std::string serialized;
+  uint16_t address_family;
+  switch (address_.host().address_family()) {
+    case IpAddressFamily::IP_V4:
+      address_family = kIPv4;
+      break;
+    case IpAddressFamily::IP_V6:
+      address_family = kIPv6;
+      break;
+    default:
+      return serialized;
+  }
+  serialized.append(reinterpret_cast<const char*>(&address_family),
+                    sizeof(address_family));
+  serialized.append(address_.host().ToPackedString());
+  uint16_t port = address_.port();
+  serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
+  return serialized;
+}
+
+bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
+  uint16_t address_family;
+  if (length < sizeof(address_family)) {
+    return false;
+  }
+  memcpy(&address_family, data, sizeof(address_family));
+  data += sizeof(address_family);
+  length -= sizeof(address_family);
+
+  size_t ip_length;
+  switch (address_family) {
+    case kIPv4:
+      ip_length = QuicIpAddress::kIPv4AddressSize;
+      break;
+    case kIPv6:
+      ip_length = QuicIpAddress::kIPv6AddressSize;
+      break;
+    default:
+      return false;
+  }
+  if (length < ip_length) {
+    return false;
+  }
+  std::vector<uint8_t> ip(ip_length);
+  memcpy(&ip[0], data, ip_length);
+  data += ip_length;
+  length -= ip_length;
+
+  uint16_t port;
+  if (length != sizeof(port)) {
+    return false;
+  }
+  memcpy(&port, data, length);
+
+  QuicIpAddress ip_address;
+  ip_address.FromPackedString(reinterpret_cast<const char*>(&ip[0]), ip_length);
+  address_ = QuicSocketAddress(ip_address, port);
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_socket_address_coder.h b/quiche/quic/core/quic_socket_address_coder.h
new file mode 100644
index 0000000..b56ee6a
--- /dev/null
+++ b/quiche/quic/core/quic_socket_address_coder.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
+#define QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
+
+#include <cstdint>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Serializes and parses a socket address (IP address and port), to be used in
+// the kCADR tag in the ServerHello handshake message and the Public Reset
+// packet.
+class QUIC_EXPORT_PRIVATE QuicSocketAddressCoder {
+ public:
+  QuicSocketAddressCoder();
+  explicit QuicSocketAddressCoder(const QuicSocketAddress& address);
+  QuicSocketAddressCoder(const QuicSocketAddressCoder&) = delete;
+  QuicSocketAddressCoder& operator=(const QuicSocketAddressCoder&) = delete;
+  ~QuicSocketAddressCoder();
+
+  std::string Encode() const;
+
+  bool Decode(const char* data, size_t length);
+
+  QuicIpAddress ip() const { return address_.host(); }
+
+  uint16_t port() const { return address_.port(); }
+
+ private:
+  QuicSocketAddress address_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SOCKET_ADDRESS_CODER_H_
diff --git a/quiche/quic/core/quic_socket_address_coder_test.cc b/quiche/quic/core/quic_socket_address_coder_test.cc
new file mode 100644
index 0000000..32f3570
--- /dev/null
+++ b/quiche/quic/core/quic_socket_address_coder_test.cc
@@ -0,0 +1,130 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_socket_address_coder.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicSocketAddressCoderTest : public QuicTest {};
+
+TEST_F(QuicSocketAddressCoderTest, EncodeIPv4) {
+  QuicIpAddress ip;
+  ip.FromString("4.31.198.44");
+  QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x1234));
+  std::string serialized = coder.Encode();
+  std::string expected("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
+  EXPECT_EQ(expected, serialized);
+}
+
+TEST_F(QuicSocketAddressCoderTest, EncodeIPv6) {
+  QuicIpAddress ip;
+  ip.FromString("2001:700:300:1800::f");
+  QuicSocketAddressCoder coder(QuicSocketAddress(ip, 0x5678));
+  std::string serialized = coder.Encode();
+  std::string expected(
+      "\x0a\x00"
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f"
+      "\x78\x56",
+      20);
+  EXPECT_EQ(expected, serialized);
+}
+
+TEST_F(QuicSocketAddressCoderTest, DecodeIPv4) {
+  std::string serialized("\x02\x00\x04\x1f\xc6\x2c\x34\x12", 8);
+  QuicSocketAddressCoder coder;
+  ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+  EXPECT_EQ(IpAddressFamily::IP_V4, coder.ip().address_family());
+  std::string expected_addr("\x04\x1f\xc6\x2c");
+  EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
+  EXPECT_EQ(0x1234, coder.port());
+}
+
+TEST_F(QuicSocketAddressCoderTest, DecodeIPv6) {
+  std::string serialized(
+      "\x0a\x00"
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f"
+      "\x78\x56",
+      20);
+  QuicSocketAddressCoder coder;
+  ASSERT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+  EXPECT_EQ(IpAddressFamily::IP_V6, coder.ip().address_family());
+  std::string expected_addr(
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f",
+      16);
+  EXPECT_EQ(expected_addr, coder.ip().ToPackedString());
+  EXPECT_EQ(0x5678, coder.port());
+}
+
+TEST_F(QuicSocketAddressCoderTest, DecodeBad) {
+  std::string serialized(
+      "\x0a\x00"
+      "\x20\x01\x07\x00\x03\x00\x18\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x0f"
+      "\x78\x56",
+      20);
+  QuicSocketAddressCoder coder;
+  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+  // Append junk.
+  serialized.push_back('\0');
+  EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
+  // Undo.
+  serialized.resize(20);
+  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+
+  // Set an unknown address family.
+  serialized[0] = '\x03';
+  EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
+  // Undo.
+  serialized[0] = '\x0a';
+  EXPECT_TRUE(coder.Decode(serialized.data(), serialized.length()));
+
+  // Truncate.
+  size_t len = serialized.length();
+  for (size_t i = 0; i < len; i++) {
+    ASSERT_FALSE(serialized.empty());
+    serialized.erase(serialized.length() - 1);
+    EXPECT_FALSE(coder.Decode(serialized.data(), serialized.length()));
+  }
+  EXPECT_TRUE(serialized.empty());
+}
+
+TEST_F(QuicSocketAddressCoderTest, EncodeAndDecode) {
+  struct {
+    const char* ip_literal;
+    uint16_t port;
+  } test_case[] = {
+      {"93.184.216.119", 0x1234},
+      {"199.204.44.194", 80},
+      {"149.20.4.69", 443},
+      {"127.0.0.1", 8080},
+      {"2001:700:300:1800::", 0x5678},
+      {"::1", 65534},
+  };
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(test_case); i++) {
+    QuicIpAddress ip;
+    ASSERT_TRUE(ip.FromString(test_case[i].ip_literal));
+    QuicSocketAddressCoder encoder(QuicSocketAddress(ip, test_case[i].port));
+    std::string serialized = encoder.Encode();
+
+    QuicSocketAddressCoder decoder;
+    ASSERT_TRUE(decoder.Decode(serialized.data(), serialized.length()));
+    EXPECT_EQ(encoder.ip(), decoder.ip());
+    EXPECT_EQ(encoder.port(), decoder.port());
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream.cc b/quiche/quic/core/quic_stream.cc
new file mode 100644
index 0000000..7d1a9dd
--- /dev/null
+++ b/quiche/quic/core/quic_stream.cc
@@ -0,0 +1,1459 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream.h"
+
+#include <limits>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+using spdy::SpdyPriority;
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+namespace {
+
+QuicByteCount DefaultFlowControlWindow(ParsedQuicVersion version) {
+  if (!version.AllowsLowFlowControlLimits()) {
+    return kDefaultFlowControlSendWindow;
+  }
+  return 0;
+}
+
+QuicByteCount GetInitialStreamFlowControlWindowToSend(QuicSession* session,
+                                                      QuicStreamId stream_id) {
+  ParsedQuicVersion version = session->connection()->version();
+  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+    return session->config()->GetInitialStreamFlowControlWindowToSend();
+  }
+
+  // Unidirectional streams (v99 only).
+  if (VersionHasIetfQuicFrames(version.transport_version) &&
+      !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
+    return session->config()
+        ->GetInitialMaxStreamDataBytesUnidirectionalToSend();
+  }
+
+  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
+                                    session->perspective())) {
+    return session->config()
+        ->GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend();
+  }
+
+  return session->config()
+      ->GetInitialMaxStreamDataBytesIncomingBidirectionalToSend();
+}
+
+QuicByteCount GetReceivedFlowControlWindow(QuicSession* session,
+                                           QuicStreamId stream_id) {
+  ParsedQuicVersion version = session->connection()->version();
+  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+    if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) {
+      return session->config()->ReceivedInitialStreamFlowControlWindowBytes();
+    }
+
+    return DefaultFlowControlWindow(version);
+  }
+
+  // Unidirectional streams (v99 only).
+  if (VersionHasIetfQuicFrames(version.transport_version) &&
+      !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
+    if (session->config()
+            ->HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
+      return session->config()
+          ->ReceivedInitialMaxStreamDataBytesUnidirectional();
+    }
+
+    return DefaultFlowControlWindow(version);
+  }
+
+  if (QuicUtils::IsOutgoingStreamId(version, stream_id,
+                                    session->perspective())) {
+    if (session->config()
+            ->HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
+      return session->config()
+          ->ReceivedInitialMaxStreamDataBytesOutgoingBidirectional();
+    }
+
+    return DefaultFlowControlWindow(version);
+  }
+
+  if (session->config()
+          ->HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
+    return session->config()
+        ->ReceivedInitialMaxStreamDataBytesIncomingBidirectional();
+  }
+
+  return DefaultFlowControlWindow(version);
+}
+
+}  // namespace
+
+// static
+const SpdyPriority QuicStream::kDefaultPriority;
+
+// static
+const int QuicStream::kDefaultUrgency;
+
+PendingStream::PendingStream(QuicStreamId id, QuicSession* session)
+    : id_(id),
+      version_(session->version()),
+      stream_delegate_(session),
+      stream_bytes_read_(0),
+      fin_received_(false),
+      is_bidirectional_(QuicUtils::GetStreamType(id, session->perspective(),
+                                                 /*peer_initiated = */ true,
+                                                 session->version()) ==
+                        BIDIRECTIONAL),
+      connection_flow_controller_(session->flow_controller()),
+      flow_controller_(session, id,
+                       /*is_connection_flow_controller*/ false,
+                       GetReceivedFlowControlWindow(session, id),
+                       GetInitialStreamFlowControlWindowToSend(session, id),
+                       kStreamReceiveWindowLimit,
+                       session->flow_controller()->auto_tune_receive_window(),
+                       session->flow_controller()),
+      sequencer_(this) {}
+
+void PendingStream::OnDataAvailable() {
+  // Data should be kept in the sequencer so that
+  // QuicSession::ProcessPendingStream() can read it.
+}
+
+void PendingStream::OnFinRead() { QUICHE_DCHECK(sequencer_.IsClosed()); }
+
+void PendingStream::AddBytesConsumed(QuicByteCount bytes) {
+  // It will be called when the metadata of the stream is consumed.
+  flow_controller_.AddBytesConsumed(bytes);
+  connection_flow_controller_->AddBytesConsumed(bytes);
+}
+
+void PendingStream::ResetWithError(QuicResetStreamError /*error*/) {
+  // Currently PendingStream is only read-unidirectional. It shouldn't send
+  // Reset.
+  QUIC_NOTREACHED();
+}
+
+void PendingStream::OnUnrecoverableError(QuicErrorCode error,
+                                         const std::string& details) {
+  stream_delegate_->OnStreamError(error, details);
+}
+
+void PendingStream::OnUnrecoverableError(QuicErrorCode error,
+                                         QuicIetfTransportErrorCodes ietf_error,
+                                         const std::string& details) {
+  stream_delegate_->OnStreamError(error, ietf_error, details);
+}
+
+QuicStreamId PendingStream::id() const { return id_; }
+
+ParsedQuicVersion PendingStream::version() const { return version_; }
+
+void PendingStream::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUICHE_DCHECK_EQ(frame.stream_id, id_);
+
+  bool is_stream_too_long =
+      (frame.offset > kMaxStreamLength) ||
+      (kMaxStreamLength - frame.offset < frame.data_length);
+  if (is_stream_too_long) {
+    // Close connection if stream becomes too long.
+    QUIC_PEER_BUG(quic_peer_bug_12570_1)
+        << "Receive stream frame reaches max stream length. frame offset "
+        << frame.offset << " length " << frame.data_length;
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Peer sends more data than allowed on this stream.");
+    return;
+  }
+
+  if (frame.offset + frame.data_length > sequencer_.close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
+        absl::StrCat(
+            "Stream ", id_,
+            " received data with offset: ", frame.offset + frame.data_length,
+            ", which is beyond close offset: ", sequencer()->close_offset()));
+    return;
+  }
+
+  if (frame.fin) {
+    fin_received_ = true;
+  }
+
+  // This count includes duplicate data received.
+  QuicByteCount frame_payload_size = frame.data_length;
+  stream_bytes_read_ += frame_payload_size;
+
+  // Flow control is interested in tracking highest received offset.
+  // Only interested in received frames that carry data.
+  if (frame_payload_size > 0 &&
+      MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
+    // As the highest received offset has changed, check to see if this is a
+    // violation of flow control.
+    if (flow_controller_.FlowControlViolation() ||
+        connection_flow_controller_->FlowControlViolation()) {
+      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                           "Flow control violation after increasing offset");
+      return;
+    }
+  }
+
+  sequencer_.OnStreamFrame(frame);
+}
+
+void PendingStream::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
+  QUICHE_DCHECK_EQ(frame.stream_id, id_);
+
+  if (frame.byte_offset > kMaxStreamLength) {
+    // Peer are not suppose to write bytes more than maxium allowed.
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Reset frame stream offset overflow.");
+    return;
+  }
+
+  const QuicStreamOffset kMaxOffset =
+      std::numeric_limits<QuicStreamOffset>::max();
+  if (sequencer()->close_offset() != kMaxOffset &&
+      frame.byte_offset != sequencer()->close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_MULTIPLE_OFFSET,
+        absl::StrCat("Stream ", id_,
+                     " received new final offset: ", frame.byte_offset,
+                     ", which is different from close offset: ",
+                     sequencer()->close_offset()));
+    return;
+  }
+
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  if (flow_controller_.FlowControlViolation() ||
+      connection_flow_controller_->FlowControlViolation()) {
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Flow control violation after increasing offset");
+    return;
+  }
+}
+
+void PendingStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  QUICHE_DCHECK(is_bidirectional_);
+  flow_controller_.UpdateSendWindowOffset(frame.max_data);
+}
+
+bool PendingStream::MaybeIncreaseHighestReceivedOffset(
+    QuicStreamOffset new_offset) {
+  uint64_t increment =
+      new_offset - flow_controller_.highest_received_byte_offset();
+  if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
+    return false;
+  }
+
+  // If |new_offset| increased the stream flow controller's highest received
+  // offset, increase the connection flow controller's value by the incremental
+  // difference.
+  connection_flow_controller_->UpdateHighestReceivedOffset(
+      connection_flow_controller_->highest_received_byte_offset() + increment);
+  return true;
+}
+
+void PendingStream::OnStopSending(
+    QuicResetStreamError stop_sending_error_code) {
+  if (!stop_sending_error_code_) {
+    stop_sending_error_code_ = stop_sending_error_code;
+  }
+}
+
+void PendingStream::MarkConsumed(QuicByteCount num_bytes) {
+  sequencer_.MarkConsumed(num_bytes);
+}
+
+void PendingStream::StopReading() {
+  QUIC_DVLOG(1) << "Stop reading from pending stream " << id();
+  sequencer_.StopReading();
+}
+
+QuicStream::QuicStream(PendingStream* pending, QuicSession* session,
+                       bool is_static)
+    : QuicStream(pending->id_, session, std::move(pending->sequencer_),
+                 is_static,
+                 QuicUtils::GetStreamType(pending->id_, session->perspective(),
+                                          /*peer_initiated = */ true,
+                                          session->version()),
+                 pending->stream_bytes_read_, pending->fin_received_,
+                 std::move(pending->flow_controller_),
+                 pending->connection_flow_controller_) {
+  QUICHE_DCHECK(session->version().HasIetfQuicFrames());
+  sequencer_.set_stream(this);
+}
+
+namespace {
+
+absl::optional<QuicFlowController> FlowController(QuicStreamId id,
+                                                  QuicSession* session,
+                                                  StreamType type) {
+  if (type == CRYPTO) {
+    // The only QuicStream with a StreamType of CRYPTO is QuicCryptoStream, when
+    // it is using crypto frames instead of stream frames. The QuicCryptoStream
+    // doesn't have any flow control in that case, so we don't create a
+    // QuicFlowController for it.
+    return absl::nullopt;
+  }
+  return QuicFlowController(
+      session, id,
+      /*is_connection_flow_controller*/ false,
+      GetReceivedFlowControlWindow(session, id),
+      GetInitialStreamFlowControlWindowToSend(session, id),
+      kStreamReceiveWindowLimit,
+      session->flow_controller()->auto_tune_receive_window(),
+      session->flow_controller());
+}
+
+}  // namespace
+
+QuicStream::QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
+                       StreamType type)
+    : QuicStream(id, session, QuicStreamSequencer(this), is_static, type, 0,
+                 false, FlowController(id, session, type),
+                 session->flow_controller()) {}
+
+QuicStream::QuicStream(QuicStreamId id, QuicSession* session,
+                       QuicStreamSequencer sequencer, bool is_static,
+                       StreamType type, uint64_t stream_bytes_read,
+                       bool fin_received,
+                       absl::optional<QuicFlowController> flow_controller,
+                       QuicFlowController* connection_flow_controller)
+    : sequencer_(std::move(sequencer)),
+      id_(id),
+      session_(session),
+      stream_delegate_(session),
+      precedence_(CalculateDefaultPriority(session)),
+      stream_bytes_read_(stream_bytes_read),
+      stream_error_(QuicResetStreamError::NoError()),
+      connection_error_(QUIC_NO_ERROR),
+      read_side_closed_(false),
+      write_side_closed_(false),
+      write_side_data_recvd_state_notified_(false),
+      fin_buffered_(false),
+      fin_sent_(false),
+      fin_outstanding_(false),
+      fin_lost_(false),
+      fin_received_(fin_received),
+      rst_sent_(false),
+      rst_received_(false),
+      stop_sending_sent_(false),
+      flow_controller_(std::move(flow_controller)),
+      connection_flow_controller_(connection_flow_controller),
+      stream_contributes_to_connection_flow_control_(true),
+      busy_counter_(0),
+      add_random_padding_after_fin_(false),
+      send_buffer_(
+          session->connection()->helper()->GetStreamSendBufferAllocator()),
+      buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
+      is_static_(is_static),
+      deadline_(QuicTime::Zero()),
+      was_draining_(false),
+      type_(VersionHasIetfQuicFrames(session->transport_version()) &&
+                    type != CRYPTO
+                ? QuicUtils::GetStreamType(id_, session->perspective(),
+                                           session->IsIncomingStream(id_),
+                                           session->version())
+                : type),
+      creation_time_(session->connection()->clock()->ApproximateNow()),
+      perspective_(session->perspective()) {
+  if (type_ == WRITE_UNIDIRECTIONAL) {
+    fin_received_ = true;
+    CloseReadSide();
+  } else if (type_ == READ_UNIDIRECTIONAL) {
+    fin_sent_ = true;
+    CloseWriteSide();
+  }
+  if (type_ != CRYPTO) {
+    stream_delegate_->RegisterStreamPriority(id, is_static_, precedence_);
+  }
+}
+
+QuicStream::~QuicStream() {
+  if (session_ != nullptr && IsWaitingForAcks()) {
+    QUIC_DVLOG(1)
+        << ENDPOINT << "Stream " << id_
+        << " gets destroyed while waiting for acks. stream_bytes_outstanding = "
+        << send_buffer_.stream_bytes_outstanding()
+        << ", fin_outstanding: " << fin_outstanding_;
+  }
+  if (stream_delegate_ != nullptr && type_ != CRYPTO) {
+    stream_delegate_->UnregisterStreamPriority(id(), is_static_);
+  }
+}
+
+void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUICHE_DCHECK_EQ(frame.stream_id, id_);
+
+  QUICHE_DCHECK(!(read_side_closed_ && write_side_closed_));
+
+  if (frame.fin && is_static_) {
+    OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
+                         "Attempt to close a static stream");
+    return;
+  }
+
+  if (type_ == WRITE_UNIDIRECTIONAL) {
+    OnUnrecoverableError(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
+                         "Data received on write unidirectional stream");
+    return;
+  }
+
+  bool is_stream_too_long =
+      (frame.offset > kMaxStreamLength) ||
+      (kMaxStreamLength - frame.offset < frame.data_length);
+  if (is_stream_too_long) {
+    // Close connection if stream becomes too long.
+    QUIC_PEER_BUG(quic_peer_bug_10586_1)
+        << "Receive stream frame on stream " << id_
+        << " reaches max stream length. frame offset " << frame.offset
+        << " length " << frame.data_length << ". " << sequencer_.DebugString();
+    OnUnrecoverableError(
+        QUIC_STREAM_LENGTH_OVERFLOW,
+        absl::StrCat("Peer sends more data than allowed on stream ", id_,
+                     ". frame: offset = ", frame.offset, ", length = ",
+                     frame.data_length, ". ", sequencer_.DebugString()));
+    return;
+  }
+
+  if (frame.offset + frame.data_length > sequencer_.close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET,
+        absl::StrCat(
+            "Stream ", id_,
+            " received data with offset: ", frame.offset + frame.data_length,
+            ", which is beyond close offset: ", sequencer_.close_offset()));
+    return;
+  }
+
+  if (frame.fin && !fin_received_) {
+    fin_received_ = true;
+    if (fin_sent_) {
+      QUICHE_DCHECK(!was_draining_);
+      session_->StreamDraining(id_,
+                               /*unidirectional=*/type_ != BIDIRECTIONAL);
+      was_draining_ = true;
+    }
+  }
+
+  if (read_side_closed_) {
+    QUIC_DLOG(INFO)
+        << ENDPOINT << "Stream " << frame.stream_id
+        << " is closed for reading. Ignoring newly received stream data.";
+    // The subclass does not want to read data:  blackhole the data.
+    return;
+  }
+
+  // This count includes duplicate data received.
+  QuicByteCount frame_payload_size = frame.data_length;
+  stream_bytes_read_ += frame_payload_size;
+
+  // Flow control is interested in tracking highest received offset.
+  // Only interested in received frames that carry data.
+  if (frame_payload_size > 0 &&
+      MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
+    // As the highest received offset has changed, check to see if this is a
+    // violation of flow control.
+    QUIC_BUG_IF(quic_bug_12570_2, !flow_controller_.has_value())
+        << ENDPOINT << "OnStreamFrame called on stream without flow control";
+    if ((flow_controller_.has_value() &&
+         flow_controller_->FlowControlViolation()) ||
+        connection_flow_controller_->FlowControlViolation()) {
+      OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                           "Flow control violation after increasing offset");
+      return;
+    }
+  }
+
+  sequencer_.OnStreamFrame(frame);
+}
+
+bool QuicStream::OnStopSending(QuicResetStreamError error) {
+  // Do not reset the stream if all data has been sent and acknowledged.
+  if (write_side_closed() && !IsWaitingForAcks()) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Ignoring STOP_SENDING for a write closed stream, id: "
+                  << id_;
+    return false;
+  }
+
+  if (is_static_) {
+    QUIC_DVLOG(1) << ENDPOINT
+                  << "Received STOP_SENDING for a static stream, id: " << id_
+                  << " Closing connection";
+    OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
+                         "Received STOP_SENDING for a static stream");
+    return false;
+  }
+
+  stream_error_ = error;
+  MaybeSendRstStream(error);
+  return true;
+}
+
+int QuicStream::num_frames_received() const {
+  return sequencer_.num_frames_received();
+}
+
+int QuicStream::num_duplicate_frames_received() const {
+  return sequencer_.num_duplicate_frames_received();
+}
+
+void QuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
+  rst_received_ = true;
+  if (frame.byte_offset > kMaxStreamLength) {
+    // Peer are not suppose to write bytes more than maxium allowed.
+    OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+                         "Reset frame stream offset overflow.");
+    return;
+  }
+
+  const QuicStreamOffset kMaxOffset =
+      std::numeric_limits<QuicStreamOffset>::max();
+  if (sequencer()->close_offset() != kMaxOffset &&
+      frame.byte_offset != sequencer()->close_offset()) {
+    OnUnrecoverableError(
+        QUIC_STREAM_MULTIPLE_OFFSET,
+        absl::StrCat("Stream ", id_,
+                     " received new final offset: ", frame.byte_offset,
+                     ", which is different from close offset: ",
+                     sequencer_.close_offset()));
+    return;
+  }
+
+  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
+  QUIC_BUG_IF(quic_bug_12570_3, !flow_controller_.has_value())
+      << ENDPOINT << "OnStreamReset called on stream without flow control";
+  if ((flow_controller_.has_value() &&
+       flow_controller_->FlowControlViolation()) ||
+      connection_flow_controller_->FlowControlViolation()) {
+    OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
+                         "Flow control violation after increasing offset");
+    return;
+  }
+
+  stream_error_ = frame.error();
+  // Google QUIC closes both sides of the stream in response to a
+  // RESET_STREAM, IETF QUIC closes only the read side.
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    CloseWriteSide();
+  }
+  CloseReadSide();
+}
+
+void QuicStream::OnConnectionClosed(QuicErrorCode error,
+                                    ConnectionCloseSource /*source*/) {
+  if (read_side_closed_ && write_side_closed_) {
+    return;
+  }
+  if (error != QUIC_NO_ERROR) {
+    stream_error_ =
+        QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECTION_ERROR);
+    connection_error_ = error;
+  }
+
+  CloseWriteSide();
+  CloseReadSide();
+}
+
+void QuicStream::OnFinRead() {
+  QUICHE_DCHECK(sequencer_.IsClosed());
+  // OnFinRead can be called due to a FIN flag in a headers block, so there may
+  // have been no OnStreamFrame call with a FIN in the frame.
+  fin_received_ = true;
+  // If fin_sent_ is true, then CloseWriteSide has already been called, and the
+  // stream will be destroyed by CloseReadSide, so don't need to call
+  // StreamDraining.
+  CloseReadSide();
+}
+
+void QuicStream::SetFinSent() {
+  QUICHE_DCHECK(!VersionUsesHttp3(transport_version()));
+  fin_sent_ = true;
+}
+
+void QuicStream::Reset(QuicRstStreamErrorCode error) {
+  ResetWithError(QuicResetStreamError::FromInternal(error));
+}
+
+void QuicStream::ResetWithError(QuicResetStreamError error) {
+  stream_error_ = error;
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+  MaybeSendStopSending(error);
+  MaybeSendRstStream(error);
+
+  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+    session()->MaybeCloseZombieStream(id_);
+  }
+}
+
+void QuicStream::ResetWriteSide(QuicResetStreamError error) {
+  stream_error_ = error;
+  MaybeSendRstStream(error);
+
+  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+    session()->MaybeCloseZombieStream(id_);
+  }
+}
+
+void QuicStream::SendStopSending(QuicResetStreamError error) {
+  stream_error_ = error;
+  MaybeSendStopSending(error);
+
+  if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+    session()->MaybeCloseZombieStream(id_);
+  }
+}
+
+void QuicStream::OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& details) {
+  stream_delegate_->OnStreamError(error, details);
+}
+
+void QuicStream::OnUnrecoverableError(QuicErrorCode error,
+                                      QuicIetfTransportErrorCodes ietf_error,
+                                      const std::string& details) {
+  stream_delegate_->OnStreamError(error, ietf_error, details);
+}
+
+const spdy::SpdyStreamPrecedence& QuicStream::precedence() const {
+  return precedence_;
+}
+
+void QuicStream::SetPriority(const spdy::SpdyStreamPrecedence& precedence) {
+  precedence_ = precedence;
+
+  MaybeSendPriorityUpdateFrame();
+
+  stream_delegate_->UpdateStreamPriority(id(), precedence);
+}
+
+void QuicStream::WriteOrBufferData(
+    absl::string_view data, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  QUIC_BUG_IF(quic_bug_12570_4,
+              QuicUtils::IsCryptoStreamId(transport_version(), id_))
+      << ENDPOINT
+      << "WriteOrBufferData is used to send application data, use "
+         "WriteOrBufferDataAtLevel to send crypto data.";
+  return WriteOrBufferDataAtLevel(
+      data, fin, session()->GetEncryptionLevelToSendApplicationData(),
+      ack_listener);
+}
+
+void QuicStream::WriteOrBufferDataAtLevel(
+    absl::string_view data, bool fin, EncryptionLevel level,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (data.empty() && !fin) {
+    QUIC_BUG(quic_bug_10586_2) << "data.empty() && !fin";
+    return;
+  }
+
+  if (fin_buffered_) {
+    QUIC_BUG(quic_bug_10586_3) << "Fin already buffered";
+    return;
+  }
+  if (write_side_closed_) {
+    QUIC_DLOG(ERROR) << ENDPOINT
+                     << "Attempt to write when the write side is closed";
+    if (type_ == READ_UNIDIRECTIONAL) {
+      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
+                           "Try to send data on read unidirectional stream");
+    }
+    return;
+  }
+
+  fin_buffered_ = fin;
+
+  bool had_buffered_data = HasBufferedData();
+  // Do not respect buffered data upper limit as WriteOrBufferData guarantees
+  // all data to be consumed.
+  if (data.length() > 0) {
+    QuicStreamOffset offset = send_buffer_.stream_offset();
+    if (kMaxStreamLength - offset < data.length()) {
+      QUIC_BUG(quic_bug_10586_4) << "Write too many data via stream " << id_;
+      OnUnrecoverableError(
+          QUIC_STREAM_LENGTH_OVERFLOW,
+          absl::StrCat("Write too many data via stream ", id_));
+      return;
+    }
+    send_buffer_.SaveStreamData(data);
+    OnDataBuffered(offset, data.length(), ack_listener);
+  }
+  if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
+    // Write data if there is no buffered data before.
+    WriteBufferedData(level);
+  }
+}
+
+void QuicStream::OnCanWrite() {
+  if (HasDeadlinePassed()) {
+    OnDeadlinePassed();
+    return;
+  }
+  if (HasPendingRetransmission()) {
+    WritePendingRetransmission();
+    // Exit early to allow other streams to write pending retransmissions if
+    // any.
+    return;
+  }
+
+  if (write_side_closed_) {
+    QUIC_DLOG(ERROR)
+        << ENDPOINT << "Stream " << id()
+        << " attempting to write new data when the write side is closed";
+    return;
+  }
+  if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) {
+    WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
+  }
+  if (!fin_buffered_ && !fin_sent_ && CanWriteNewData()) {
+    // Notify upper layer to write new data when buffered data size is below
+    // low water mark.
+    OnCanWriteNewData();
+  }
+}
+
+void QuicStream::MaybeSendBlocked() {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_5)
+        << ENDPOINT << "MaybeSendBlocked called on stream without flow control";
+    return;
+  }
+  if (flow_controller_->ShouldSendBlocked()) {
+    session_->SendBlocked(id_);
+  }
+  if (!stream_contributes_to_connection_flow_control_) {
+    return;
+  }
+  if (connection_flow_controller_->ShouldSendBlocked()) {
+    session_->SendBlocked(QuicUtils::GetInvalidStreamId(transport_version()));
+  }
+  // If the stream is blocked by connection-level flow control but not by
+  // stream-level flow control, add the stream to the write blocked list so that
+  // the stream will be given a chance to write when a connection-level
+  // WINDOW_UPDATE arrives.
+  if (connection_flow_controller_->IsBlocked() &&
+      !flow_controller_->IsBlocked()) {
+    session_->MarkConnectionLevelWriteBlocked(id());
+  }
+}
+
+QuicConsumedData QuicStream::WriteMemSlice(quiche::QuicheMemSlice span,
+                                           bool fin) {
+  return WriteMemSlices(absl::MakeSpan(&span, 1), fin);
+}
+
+QuicConsumedData QuicStream::WriteMemSlices(
+    absl::Span<quiche::QuicheMemSlice> span, bool fin) {
+  QuicConsumedData consumed_data(0, false);
+  if (span.empty() && !fin) {
+    QUIC_BUG(quic_bug_10586_6) << "span.empty() && !fin";
+    return consumed_data;
+  }
+
+  if (fin_buffered_) {
+    QUIC_BUG(quic_bug_10586_7) << "Fin already buffered";
+    return consumed_data;
+  }
+
+  if (write_side_closed_) {
+    QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id()
+                     << " attempting to write when the write side is closed";
+    if (type_ == READ_UNIDIRECTIONAL) {
+      OnUnrecoverableError(QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM,
+                           "Try to send data on read unidirectional stream");
+    }
+    return consumed_data;
+  }
+
+  bool had_buffered_data = HasBufferedData();
+  if (CanWriteNewData() || span.empty()) {
+    consumed_data.fin_consumed = fin;
+    if (!span.empty()) {
+      // Buffer all data if buffered data size is below limit.
+      QuicStreamOffset offset = send_buffer_.stream_offset();
+      consumed_data.bytes_consumed = send_buffer_.SaveMemSliceSpan(span);
+      if (offset > send_buffer_.stream_offset() ||
+          kMaxStreamLength < send_buffer_.stream_offset()) {
+        QUIC_BUG(quic_bug_10586_8) << "Write too many data via stream " << id_;
+        OnUnrecoverableError(
+            QUIC_STREAM_LENGTH_OVERFLOW,
+            absl::StrCat("Write too many data via stream ", id_));
+        return consumed_data;
+      }
+      OnDataBuffered(offset, consumed_data.bytes_consumed, nullptr);
+    }
+  }
+  fin_buffered_ = consumed_data.fin_consumed;
+
+  if (!had_buffered_data && (HasBufferedData() || fin_buffered_)) {
+    // Write data if there is no buffered data before.
+    WriteBufferedData(session()->GetEncryptionLevelToSendApplicationData());
+  }
+
+  return consumed_data;
+}
+
+bool QuicStream::HasPendingRetransmission() const {
+  return send_buffer_.HasPendingRetransmission() || fin_lost_;
+}
+
+bool QuicStream::IsStreamFrameOutstanding(QuicStreamOffset offset,
+                                          QuicByteCount data_length,
+                                          bool fin) const {
+  return send_buffer_.IsStreamDataOutstanding(offset, data_length) ||
+         (fin && fin_outstanding_);
+}
+
+void QuicStream::CloseReadSide() {
+  if (read_side_closed_) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Done reading from stream " << id();
+
+  read_side_closed_ = true;
+  sequencer_.ReleaseBuffer();
+
+  if (write_side_closed_) {
+    QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
+    session_->OnStreamClosed(id());
+    OnClose();
+  }
+}
+
+void QuicStream::CloseWriteSide() {
+  if (write_side_closed_) {
+    return;
+  }
+  QUIC_DVLOG(1) << ENDPOINT << "Done writing to stream " << id();
+
+  write_side_closed_ = true;
+  if (read_side_closed_) {
+    QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
+    session_->OnStreamClosed(id());
+    OnClose();
+  }
+}
+
+void QuicStream::MaybeSendStopSending(QuicResetStreamError error) {
+  if (stop_sending_sent_) {
+    return;
+  }
+
+  if (!session()->version().UsesHttp3() && !error.ok()) {
+    // In gQUIC, RST with error closes both read and write side.
+    return;
+  }
+
+  if (session()->version().UsesHttp3()) {
+    session()->MaybeSendStopSendingFrame(id(), error);
+  } else {
+    QUICHE_DCHECK_EQ(QUIC_STREAM_NO_ERROR, error.internal_code());
+    session()->MaybeSendRstStreamFrame(id(), QuicResetStreamError::NoError(),
+                                       stream_bytes_written());
+  }
+  stop_sending_sent_ = true;
+  CloseReadSide();
+}
+
+void QuicStream::MaybeSendRstStream(QuicResetStreamError error) {
+  if (rst_sent_) {
+    return;
+  }
+
+  if (!session()->version().UsesHttp3()) {
+    QUIC_BUG_IF(quic_bug_12570_5, error.ok());
+    stop_sending_sent_ = true;
+    CloseReadSide();
+  }
+  session()->MaybeSendRstStreamFrame(id(), error, stream_bytes_written());
+  rst_sent_ = true;
+  CloseWriteSide();
+}
+
+bool QuicStream::HasBufferedData() const {
+  QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
+  return send_buffer_.stream_offset() > stream_bytes_written();
+}
+
+ParsedQuicVersion QuicStream::version() const { return session_->version(); }
+
+QuicTransportVersion QuicStream::transport_version() const {
+  return session_->transport_version();
+}
+
+HandshakeProtocol QuicStream::handshake_protocol() const {
+  return session_->connection()->version().handshake_protocol;
+}
+
+void QuicStream::StopReading() {
+  QUIC_DVLOG(1) << ENDPOINT << "Stop reading from stream " << id();
+  sequencer_.StopReading();
+}
+
+void QuicStream::OnClose() {
+  QUICHE_DCHECK(read_side_closed_ && write_side_closed_);
+
+  if (!fin_sent_ && !rst_sent_) {
+    QUIC_BUG_IF(quic_bug_12570_6, session()->connection()->connected() &&
+                                      session()->version().UsesHttp3())
+        << "The stream should've already sent RST in response to "
+           "STOP_SENDING";
+    // For flow control accounting, tell the peer how many bytes have been
+    // written on this stream before termination. Done here if needed, using a
+    // RST_STREAM frame.
+    MaybeSendRstStream(QUIC_RST_ACKNOWLEDGEMENT);
+    session_->MaybeCloseZombieStream(id_);
+  }
+
+  if (!flow_controller_.has_value() ||
+      flow_controller_->FlowControlViolation() ||
+      connection_flow_controller_->FlowControlViolation()) {
+    return;
+  }
+  // The stream is being closed and will not process any further incoming bytes.
+  // As there may be more bytes in flight, to ensure that both endpoints have
+  // the same connection level flow control state, mark all unreceived or
+  // buffered bytes as consumed.
+  QuicByteCount bytes_to_consume =
+      flow_controller_->highest_received_byte_offset() -
+      flow_controller_->bytes_consumed();
+  AddBytesConsumed(bytes_to_consume);
+}
+
+void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
+  if (type_ == READ_UNIDIRECTIONAL) {
+    OnUnrecoverableError(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.");
+    return;
+  }
+
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_9)
+        << ENDPOINT
+        << "OnWindowUpdateFrame called on stream without flow control";
+    return;
+  }
+
+  if (flow_controller_->UpdateSendWindowOffset(frame.max_data)) {
+    // Let session unblock this stream.
+    session_->MarkConnectionLevelWriteBlocked(id_);
+  }
+}
+
+bool QuicStream::MaybeIncreaseHighestReceivedOffset(
+    QuicStreamOffset new_offset) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_10)
+        << ENDPOINT
+        << "MaybeIncreaseHighestReceivedOffset called on stream without "
+           "flow control";
+    return false;
+  }
+  uint64_t increment =
+      new_offset - flow_controller_->highest_received_byte_offset();
+  if (!flow_controller_->UpdateHighestReceivedOffset(new_offset)) {
+    return false;
+  }
+
+  // If |new_offset| increased the stream flow controller's highest received
+  // offset, increase the connection flow controller's value by the incremental
+  // difference.
+  if (stream_contributes_to_connection_flow_control_) {
+    connection_flow_controller_->UpdateHighestReceivedOffset(
+        connection_flow_controller_->highest_received_byte_offset() +
+        increment);
+  }
+  return true;
+}
+
+void QuicStream::AddBytesSent(QuicByteCount bytes) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_11)
+        << ENDPOINT << "AddBytesSent called on stream without flow control";
+    return;
+  }
+  flow_controller_->AddBytesSent(bytes);
+  if (stream_contributes_to_connection_flow_control_) {
+    connection_flow_controller_->AddBytesSent(bytes);
+  }
+}
+
+void QuicStream::AddBytesConsumed(QuicByteCount bytes) {
+  if (type_ == CRYPTO) {
+    // A stream with type CRYPTO has no flow control, so there's nothing this
+    // function needs to do. This function still gets called by the
+    // QuicStreamSequencers used by QuicCryptoStream.
+    return;
+  }
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_12570_7)
+        << ENDPOINT
+        << "AddBytesConsumed called on non-crypto stream without flow control";
+    return;
+  }
+  // Only adjust stream level flow controller if still reading.
+  if (!read_side_closed_) {
+    flow_controller_->AddBytesConsumed(bytes);
+  }
+
+  if (stream_contributes_to_connection_flow_control_) {
+    connection_flow_controller_->AddBytesConsumed(bytes);
+  }
+}
+
+bool QuicStream::MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
+                                             bool was_zero_rtt_rejected) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_12)
+        << ENDPOINT
+        << "ConfigSendWindowOffset called on stream without flow control";
+    return false;
+  }
+
+  // The validation code below is for QUIC with TLS only.
+  if (new_offset < flow_controller_->send_window_offset()) {
+    QUICHE_DCHECK(session()->version().UsesTls());
+    if (was_zero_rtt_rejected && new_offset < flow_controller_->bytes_sent()) {
+      // The client is given flow control window lower than what's written in
+      // 0-RTT. This QUIC implementation is unable to retransmit them.
+      QUIC_BUG_IF(quic_bug_12570_8, perspective_ == Perspective::IS_SERVER)
+          << "Server streams' flow control should never be configured twice.";
+      OnUnrecoverableError(
+          QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+          absl::StrCat(
+              "Server rejected 0-RTT, aborting because new stream max data ",
+              new_offset, " for stream ", id_, " is less than currently used: ",
+              flow_controller_->bytes_sent()));
+      return false;
+    } else if (session()->version().AllowsLowFlowControlLimits()) {
+      // In IETF QUIC, if the client receives flow control limit lower than what
+      // was resumed from 0-RTT, depending on 0-RTT status, it's either the
+      // peer's fault or our implementation's fault.
+      QUIC_BUG_IF(quic_bug_12570_9, perspective_ == Perspective::IS_SERVER)
+          << "Server streams' flow control should never be configured twice.";
+      OnUnrecoverableError(
+          was_zero_rtt_rejected ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+                                : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+          absl::StrCat(
+              was_zero_rtt_rejected ? "Server rejected 0-RTT, aborting because "
+                                    : "",
+              "new stream max data ", new_offset, " decreases current limit: ",
+              flow_controller_->send_window_offset()));
+      return false;
+    }
+  }
+
+  if (flow_controller_->UpdateSendWindowOffset(new_offset)) {
+    // Let session unblock this stream.
+    session_->MarkConnectionLevelWriteBlocked(id_);
+  }
+  return true;
+}
+
+void QuicStream::AddRandomPaddingAfterFin() {
+  add_random_padding_after_fin_ = true;
+}
+
+bool QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
+                                    QuicByteCount data_length, bool fin_acked,
+                                    QuicTime::Delta /*ack_delay_time*/,
+                                    QuicTime /*receive_timestamp*/,
+                                    QuicByteCount* newly_acked_length) {
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Acking "
+                << "[" << offset << ", " << offset + data_length << "]"
+                << " fin = " << fin_acked;
+  *newly_acked_length = 0;
+  if (!send_buffer_.OnStreamDataAcked(offset, data_length,
+                                      newly_acked_length)) {
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent data.");
+    return false;
+  }
+  if (!fin_sent_ && fin_acked) {
+    OnUnrecoverableError(QUIC_INTERNAL_ERROR, "Trying to ack unsent fin.");
+    return false;
+  }
+  // Indicates whether ack listener's OnPacketAcked should be called.
+  const bool new_data_acked =
+      *newly_acked_length > 0 || (fin_acked && fin_outstanding_);
+  if (fin_acked) {
+    fin_outstanding_ = false;
+    fin_lost_ = false;
+  }
+  if (!IsWaitingForAcks() && write_side_closed_ &&
+      !write_side_data_recvd_state_notified_) {
+    OnWriteSideInDataRecvdState();
+    write_side_data_recvd_state_notified_ = true;
+  }
+  if (!IsWaitingForAcks() && read_side_closed_ && write_side_closed_) {
+    session_->MaybeCloseZombieStream(id_);
+  }
+  return new_data_acked;
+}
+
+void QuicStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                            QuicByteCount data_length,
+                                            bool fin_retransmitted) {
+  send_buffer_.OnStreamDataRetransmitted(offset, data_length);
+  if (fin_retransmitted) {
+    fin_lost_ = false;
+  }
+}
+
+void QuicStream::OnStreamFrameLost(QuicStreamOffset offset,
+                                   QuicByteCount data_length, bool fin_lost) {
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " Losting "
+                << "[" << offset << ", " << offset + data_length << "]"
+                << " fin = " << fin_lost;
+  if (data_length > 0) {
+    send_buffer_.OnStreamDataLost(offset, data_length);
+  }
+  if (fin_lost && fin_outstanding_) {
+    fin_lost_ = true;
+  }
+}
+
+bool QuicStream::RetransmitStreamData(QuicStreamOffset offset,
+                                      QuicByteCount data_length, bool fin,
+                                      TransmissionType type) {
+  QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
+                type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
+  if (HasDeadlinePassed()) {
+    OnDeadlinePassed();
+    return true;
+  }
+  QuicIntervalSet<QuicStreamOffset> retransmission(offset,
+                                                   offset + data_length);
+  retransmission.Difference(bytes_acked());
+  bool retransmit_fin = fin && fin_outstanding_;
+  if (retransmission.Empty() && !retransmit_fin) {
+    return true;
+  }
+  QuicConsumedData consumed(0, false);
+  for (const auto& interval : retransmission) {
+    QuicStreamOffset retransmission_offset = interval.min();
+    QuicByteCount retransmission_length = interval.max() - interval.min();
+    const bool can_bundle_fin =
+        retransmit_fin && (retransmission_offset + retransmission_length ==
+                           stream_bytes_written());
+    consumed = stream_delegate_->WritevData(
+        id_, retransmission_length, retransmission_offset,
+        can_bundle_fin ? FIN : NO_FIN, type,
+        session()->GetEncryptionLevelToSendApplicationData());
+    QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                  << " is forced to retransmit stream data ["
+                  << retransmission_offset << ", "
+                  << retransmission_offset + retransmission_length
+                  << ") and fin: " << can_bundle_fin
+                  << ", consumed: " << consumed;
+    OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
+                               consumed.fin_consumed);
+    if (can_bundle_fin) {
+      retransmit_fin = !consumed.fin_consumed;
+    }
+    if (consumed.bytes_consumed < retransmission_length ||
+        (can_bundle_fin && !consumed.fin_consumed)) {
+      // Connection is write blocked.
+      return false;
+    }
+  }
+  if (retransmit_fin) {
+    QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                  << " retransmits fin only frame.";
+    consumed = stream_delegate_->WritevData(
+        id_, 0, stream_bytes_written(), FIN, type,
+        session()->GetEncryptionLevelToSendApplicationData());
+    if (!consumed.fin_consumed) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicStream::IsWaitingForAcks() const {
+  return (!rst_sent_ || stream_error_.ok()) &&
+         (send_buffer_.stream_bytes_outstanding() || fin_outstanding_);
+}
+
+QuicByteCount QuicStream::ReadableBytes() const {
+  return sequencer_.ReadableBytes();
+}
+
+bool QuicStream::WriteStreamData(QuicStreamOffset offset,
+                                 QuicByteCount data_length,
+                                 QuicDataWriter* writer) {
+  QUICHE_DCHECK_LT(0u, data_length);
+  QUIC_DVLOG(2) << ENDPOINT << "Write stream " << id_ << " data from offset "
+                << offset << " length " << data_length;
+  return send_buffer_.WriteStreamData(offset, data_length, writer);
+}
+
+void QuicStream::WriteBufferedData(EncryptionLevel level) {
+  QUICHE_DCHECK(!write_side_closed_ && (HasBufferedData() || fin_buffered_));
+
+  if (session_->ShouldYield(id())) {
+    session_->MarkConnectionLevelWriteBlocked(id());
+    return;
+  }
+
+  // Size of buffered data.
+  QuicByteCount write_length = BufferedDataBytes();
+
+  // A FIN with zero data payload should not be flow control blocked.
+  bool fin_with_zero_data = (fin_buffered_ && write_length == 0);
+
+  bool fin = fin_buffered_;
+
+  // How much data flow control permits to be written.
+  QuicByteCount send_window;
+  if (flow_controller_.has_value()) {
+    send_window = flow_controller_->SendWindowSize();
+  } else {
+    send_window = std::numeric_limits<QuicByteCount>::max();
+    QUIC_BUG(quic_bug_10586_13)
+        << ENDPOINT
+        << "WriteBufferedData called on stream without flow control";
+  }
+  if (stream_contributes_to_connection_flow_control_) {
+    send_window =
+        std::min(send_window, connection_flow_controller_->SendWindowSize());
+  }
+
+  if (send_window == 0 && !fin_with_zero_data) {
+    // Quick return if nothing can be sent.
+    MaybeSendBlocked();
+    return;
+  }
+
+  if (write_length > send_window) {
+    // Don't send the FIN unless all the data will be sent.
+    fin = false;
+
+    // Writing more data would be a violation of flow control.
+    write_length = send_window;
+    QUIC_DVLOG(1) << "stream " << id() << " shortens write length to "
+                  << write_length << " due to flow control";
+  }
+
+  StreamSendingState state = fin ? FIN : NO_FIN;
+  if (fin && add_random_padding_after_fin_) {
+    state = FIN_AND_PADDING;
+  }
+  QuicConsumedData consumed_data =
+      stream_delegate_->WritevData(id(), write_length, stream_bytes_written(),
+                                   state, NOT_RETRANSMISSION, level);
+
+  OnStreamDataConsumed(consumed_data.bytes_consumed);
+
+  AddBytesSent(consumed_data.bytes_consumed);
+  QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " sends "
+                << stream_bytes_written() << " bytes "
+                << " and has buffered data " << BufferedDataBytes() << " bytes."
+                << " fin is sent: " << consumed_data.fin_consumed
+                << " fin is buffered: " << fin_buffered_;
+
+  // The write may have generated a write error causing this stream to be
+  // closed. If so, simply return without marking the stream write blocked.
+  if (write_side_closed_) {
+    return;
+  }
+
+  if (consumed_data.bytes_consumed == write_length) {
+    if (!fin_with_zero_data) {
+      MaybeSendBlocked();
+    }
+    if (fin && consumed_data.fin_consumed) {
+      QUICHE_DCHECK(!fin_sent_);
+      fin_sent_ = true;
+      fin_outstanding_ = true;
+      if (fin_received_) {
+        QUICHE_DCHECK(!was_draining_);
+        session_->StreamDraining(id_,
+                                 /*unidirectional=*/type_ != BIDIRECTIONAL);
+        was_draining_ = true;
+      }
+      CloseWriteSide();
+    } else if (fin && !consumed_data.fin_consumed) {
+      session_->MarkConnectionLevelWriteBlocked(id());
+    }
+  } else {
+    session_->MarkConnectionLevelWriteBlocked(id());
+  }
+  if (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed) {
+    busy_counter_ = 0;
+  }
+}
+
+uint64_t QuicStream::BufferedDataBytes() const {
+  QUICHE_DCHECK_GE(send_buffer_.stream_offset(), stream_bytes_written());
+  return send_buffer_.stream_offset() - stream_bytes_written();
+}
+
+bool QuicStream::CanWriteNewData() const {
+  return BufferedDataBytes() < buffered_data_threshold_;
+}
+
+bool QuicStream::CanWriteNewDataAfterData(QuicByteCount length) const {
+  return (BufferedDataBytes() + length) < buffered_data_threshold_;
+}
+
+uint64_t QuicStream::stream_bytes_written() const {
+  return send_buffer_.stream_bytes_written();
+}
+
+const QuicIntervalSet<QuicStreamOffset>& QuicStream::bytes_acked() const {
+  return send_buffer_.bytes_acked();
+}
+
+void QuicStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
+  send_buffer_.OnStreamDataConsumed(bytes_consumed);
+}
+
+void QuicStream::WritePendingRetransmission() {
+  while (HasPendingRetransmission()) {
+    QuicConsumedData consumed(0, false);
+    if (!send_buffer_.HasPendingRetransmission()) {
+      QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                    << " retransmits fin only frame.";
+      consumed = stream_delegate_->WritevData(
+          id_, 0, stream_bytes_written(), FIN, LOSS_RETRANSMISSION,
+          session()->GetEncryptionLevelToSendApplicationData());
+      fin_lost_ = !consumed.fin_consumed;
+      if (fin_lost_) {
+        // Connection is write blocked.
+        return;
+      }
+    } else {
+      StreamPendingRetransmission pending =
+          send_buffer_.NextPendingRetransmission();
+      // Determine whether the lost fin can be bundled with the data.
+      const bool can_bundle_fin =
+          fin_lost_ &&
+          (pending.offset + pending.length == stream_bytes_written());
+      consumed = stream_delegate_->WritevData(
+          id_, pending.length, pending.offset, can_bundle_fin ? FIN : NO_FIN,
+          LOSS_RETRANSMISSION,
+          session()->GetEncryptionLevelToSendApplicationData());
+      QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+                    << " tries to retransmit stream data [" << pending.offset
+                    << ", " << pending.offset + pending.length
+                    << ") and fin: " << can_bundle_fin
+                    << ", consumed: " << consumed;
+      OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
+                                 consumed.fin_consumed);
+      if (consumed.bytes_consumed < pending.length ||
+          (can_bundle_fin && !consumed.fin_consumed)) {
+        // Connection is write blocked.
+        return;
+      }
+    }
+  }
+}
+
+bool QuicStream::MaybeSetTtl(QuicTime::Delta ttl) {
+  if (is_static_) {
+    QUIC_BUG(quic_bug_10586_14) << "Cannot set TTL of a static stream.";
+    return false;
+  }
+  if (deadline_.IsInitialized()) {
+    QUIC_DLOG(WARNING) << "Deadline has already been set.";
+    return false;
+  }
+  QuicTime now = session()->connection()->clock()->ApproximateNow();
+  deadline_ = now + ttl;
+  return true;
+}
+
+bool QuicStream::HasDeadlinePassed() const {
+  if (!deadline_.IsInitialized()) {
+    // No deadline has been set.
+    return false;
+  }
+  QuicTime now = session()->connection()->clock()->ApproximateNow();
+  if (now < deadline_) {
+    return false;
+  }
+  // TTL expired.
+  QUIC_DVLOG(1) << "stream " << id() << " deadline has passed";
+  return true;
+}
+
+void QuicStream::OnDeadlinePassed() { Reset(QUIC_STREAM_TTL_EXPIRED); }
+
+bool QuicStream::IsFlowControlBlocked() const {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_15)
+        << "Trying to access non-existent flow controller.";
+    return false;
+  }
+  return flow_controller_->IsBlocked();
+}
+
+QuicStreamOffset QuicStream::highest_received_byte_offset() const {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_16)
+        << "Trying to access non-existent flow controller.";
+    return 0;
+  }
+  return flow_controller_->highest_received_byte_offset();
+}
+
+void QuicStream::UpdateReceiveWindowSize(QuicStreamOffset size) {
+  if (!flow_controller_.has_value()) {
+    QUIC_BUG(quic_bug_10586_17)
+        << "Trying to access non-existent flow controller.";
+    return;
+  }
+  flow_controller_->UpdateReceiveWindowSize(size);
+}
+
+// static
+spdy::SpdyStreamPrecedence QuicStream::CalculateDefaultPriority(
+    const QuicSession* session) {
+  return spdy::SpdyStreamPrecedence(
+      VersionUsesHttp3(session->transport_version())
+          ? kDefaultUrgency
+          : QuicStream::kDefaultPriority);
+}
+
+absl::optional<QuicByteCount> QuicStream::GetSendWindow() const {
+  return flow_controller_.has_value()
+             ? absl::optional<QuicByteCount>(flow_controller_->SendWindowSize())
+             : absl::nullopt;
+}
+
+absl::optional<QuicByteCount> QuicStream::GetReceiveWindow() const {
+  return flow_controller_.has_value()
+             ? absl::optional<QuicByteCount>(
+                   flow_controller_->receive_window_size())
+             : absl::nullopt;
+}
+
+void QuicStream::OnStreamCreatedFromPendingStream() {
+  sequencer()->SetUnblocked();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream.h b/quiche/quic/core/quic_stream.h
new file mode 100644
index 0000000..b2a6502
--- /dev/null
+++ b/quiche/quic/core/quic_stream.h
@@ -0,0 +1,626 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The base class for client/server QUIC streams.
+
+// It does not contain the entire interface needed by an application to interact
+// with a QUIC stream.  Some parts of the interface must be obtained by
+// accessing the owning session object.  A subclass of QuicStream
+// connects the object and the application that generates and consumes the data
+// of the stream.
+
+// The QuicStream object has a dependent QuicStreamSequencer object,
+// which is given the stream frames as they arrive, and provides stream data in
+// order by invoking ProcessRawData().
+
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/core/stream_delegate_interface.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/platform/api/quiche_reference_counted.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicSession;
+class QuicStream;
+
+// Buffers frames for a stream until the first byte of that frame arrives.
+class QUIC_EXPORT_PRIVATE PendingStream
+    : public QuicStreamSequencer::StreamInterface {
+ public:
+  PendingStream(QuicStreamId id, QuicSession* session);
+  PendingStream(const PendingStream&) = delete;
+  PendingStream(PendingStream&&) = default;
+  ~PendingStream() override = default;
+
+  // QuicStreamSequencer::StreamInterface
+  void OnDataAvailable() override;
+  void OnFinRead() override;
+  void AddBytesConsumed(QuicByteCount bytes) override;
+  void ResetWithError(QuicResetStreamError error) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            QuicIetfTransportErrorCodes ietf_error,
+                            const std::string& details) override;
+  QuicStreamId id() const override;
+  ParsedQuicVersion version() const override;
+
+  // Buffers the contents of |frame|. Frame must have a non-zero offset.
+  // If the data violates flow control, the connection will be closed.
+  void OnStreamFrame(const QuicStreamFrame& frame);
+
+  bool is_bidirectional() const { return is_bidirectional_; }
+
+  // Stores the final byte offset from |frame|.
+  // If the final offset violates flow control, the connection will be closed.
+  void OnRstStreamFrame(const QuicRstStreamFrame& frame);
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
+
+  void OnStopSending(QuicResetStreamError stop_sending_error_code);
+
+  // The error code received from QuicStopSendingFrame (if any).
+  const absl::optional<QuicResetStreamError>& GetStopSendingErrorCode() const {
+    return stop_sending_error_code_;
+  }
+
+  // Returns the number of bytes read on this stream.
+  uint64_t stream_bytes_read() { return stream_bytes_read_; }
+
+  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
+
+  void MarkConsumed(QuicByteCount num_bytes);
+
+  // Tells the sequencer to ignore all incoming data itself and not call
+  // OnDataAvailable().
+  void StopReading();
+
+ private:
+  friend class QuicStream;
+
+  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
+
+  // ID of this stream.
+  QuicStreamId id_;
+
+  // QUIC version being used by this stream.
+  ParsedQuicVersion version_;
+
+  // |stream_delegate_| must outlive this stream.
+  StreamDelegateInterface* stream_delegate_;
+
+  // Bytes read refers to payload bytes only: they do not include framing,
+  // encryption overhead etc.
+  uint64_t stream_bytes_read_;
+
+  // True if a frame containing a fin has been received.
+  bool fin_received_;
+
+  // True if this pending stream is backing a bidirectional stream.
+  bool is_bidirectional_;
+
+  // Connection-level flow controller. Owned by the session.
+  QuicFlowController* connection_flow_controller_;
+  // Stream-level flow controller.
+  QuicFlowController flow_controller_;
+  // Stores the buffered frames.
+  QuicStreamSequencer sequencer_;
+  // The error code received from QuicStopSendingFrame (if any).
+  absl::optional<QuicResetStreamError> stop_sending_error_code_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicStream
+    : public QuicStreamSequencer::StreamInterface {
+ public:
+  // Default priority for Google QUIC.
+  // This is somewhat arbitrary.  It's possible, but unlikely, we will either
+  // fail to set a priority client-side, or cancel a stream before stripping the
+  // priority from the wire server-side.  In either case, start out with a
+  // priority in the middle in case of Google QUIC.
+  static const spdy::SpdyPriority kDefaultPriority = 3;
+  static_assert(kDefaultPriority ==
+                    (spdy::kV3LowestPriority + spdy::kV3HighestPriority) / 2,
+                "Unexpected value of kDefaultPriority");
+
+  // Creates a new stream with stream_id |id| associated with |session|. If
+  // |is_static| is true, then the stream will be given precedence
+  // over other streams when determing what streams should write next.
+  // |type| indicates whether the stream is bidirectional, read unidirectional
+  // or write unidirectional.
+  // TODO(fayang): Remove |type| when IETF stream ID numbering fully kicks in.
+  QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
+             StreamType type);
+  QuicStream(PendingStream* pending, QuicSession* session, bool is_static);
+  QuicStream(const QuicStream&) = delete;
+  QuicStream& operator=(const QuicStream&) = delete;
+
+  virtual ~QuicStream();
+
+  // Default priority for IETF QUIC, defined by the priority extension at
+  // https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html#urgency.
+  static const int kDefaultUrgency = 3;
+
+  // QuicStreamSequencer::StreamInterface implementation.
+  QuicStreamId id() const override { return id_; }
+  ParsedQuicVersion version() const override;
+  // Called by the stream subclass after it has consumed the final incoming
+  // data.
+  void OnFinRead() override;
+
+  // Called by the subclass or the sequencer to reset the stream from this
+  // end.
+  void ResetWithError(QuicResetStreamError error) override;
+  // Convenience wrapper for the method above.
+  // TODO(b/200606367): switch all calls to using QuicResetStreamError
+  // interface.
+  void Reset(QuicRstStreamErrorCode error);
+
+  // Reset() sends both RESET_STREAM and STOP_SENDING; the two methods below
+  // allow to send only one of those.
+  void ResetWriteSide(QuicResetStreamError error);
+  void SendStopSending(QuicResetStreamError error);
+
+  // Called by the subclass or the sequencer to close the entire connection from
+  // this end.
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            QuicIetfTransportErrorCodes ietf_error,
+                            const std::string& details) override;
+
+  // Called by the session when a (potentially duplicate) stream frame has been
+  // received for this stream.
+  virtual void OnStreamFrame(const QuicStreamFrame& frame);
+
+  // Called by the session when the connection becomes writeable to allow the
+  // stream to write any pending data.
+  virtual void OnCanWrite();
+
+  // Called by the session when the endpoint receives a RST_STREAM from the
+  // peer.
+  virtual void OnStreamReset(const QuicRstStreamFrame& frame);
+
+  // Called by the session when the endpoint receives or sends a connection
+  // close, and should immediately close the stream.
+  virtual void OnConnectionClosed(QuicErrorCode error,
+                                  ConnectionCloseSource source);
+
+  const spdy::SpdyStreamPrecedence& precedence() const;
+
+  // Send PRIORITY_UPDATE frame if application protocol supports it.
+  virtual void MaybeSendPriorityUpdateFrame() {}
+
+  // Sets |priority_| to priority.  This should only be called before bytes are
+  // written to the server.  For a server stream, this is called when a
+  // PRIORITY_UPDATE frame is received.  This calls
+  // MaybeSendPriorityUpdateFrame(), which for a client stream might send a
+  // PRIORITY_UPDATE frame.
+  void SetPriority(const spdy::SpdyStreamPrecedence& precedence);
+
+  // Returns true if this stream is still waiting for acks of sent data.
+  // This will return false if all data has been acked, or if the stream
+  // is no longer interested in data being acked (which happens when
+  // a stream is reset because of an error).
+  bool IsWaitingForAcks() const;
+
+  // Number of bytes available to read.
+  QuicByteCount ReadableBytes() const;
+
+  QuicRstStreamErrorCode stream_error() const {
+    return stream_error_.internal_code();
+  }
+  QuicErrorCode connection_error() const { return connection_error_; }
+
+  bool reading_stopped() const {
+    return sequencer_.ignore_read_data() || read_side_closed_;
+  }
+  bool write_side_closed() const { return write_side_closed_; }
+  bool read_side_closed() const { return read_side_closed_; }
+
+  bool IsZombie() const {
+    return read_side_closed_ && write_side_closed_ && IsWaitingForAcks();
+  }
+
+  bool rst_received() const { return rst_received_; }
+  bool rst_sent() const { return rst_sent_; }
+  bool fin_received() const { return fin_received_; }
+  bool fin_sent() const { return fin_sent_; }
+  bool fin_outstanding() const { return fin_outstanding_; }
+  bool fin_lost() const { return fin_lost_; }
+
+  uint64_t BufferedDataBytes() const;
+
+  uint64_t stream_bytes_read() const { return stream_bytes_read_; }
+  uint64_t stream_bytes_written() const;
+
+  size_t busy_counter() const { return busy_counter_; }
+  void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }
+
+  // Adjust the flow control window according to new offset in |frame|.
+  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
+
+  int num_frames_received() const;
+  int num_duplicate_frames_received() const;
+
+  // Flow controller related methods.
+  bool IsFlowControlBlocked() const;
+  QuicStreamOffset highest_received_byte_offset() const;
+  void UpdateReceiveWindowSize(QuicStreamOffset size);
+
+  // Called when endpoint receives a frame which could increase the highest
+  // offset.
+  // Returns true if the highest offset did increase.
+  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
+
+  // Set the flow controller's send window offset from session config.
+  // |was_zero_rtt_rejected| is true if this config is from a rejected IETF QUIC
+  // 0-RTT attempt. Closes the connection and returns false if |new_offset| is
+  // not valid.
+  bool MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
+                                   bool was_zero_rtt_rejected);
+
+  // Returns true if the stream has received either a RST_STREAM or a FIN -
+  // either of which gives a definitive number of bytes which the peer has
+  // sent. If this is not true on deletion of the stream object, the session
+  // must keep track of the stream's byte offset until a definitive final value
+  // arrives.
+  bool HasReceivedFinalOffset() const { return fin_received_ || rst_received_; }
+
+  // Returns true if the stream has queued data waiting to write.
+  bool HasBufferedData() const;
+
+  // Returns the version of QUIC being used for this stream.
+  QuicTransportVersion transport_version() const;
+
+  // Returns the crypto handshake protocol that was used on this stream's
+  // connection.
+  HandshakeProtocol handshake_protocol() const;
+
+  // Sets the sequencer to consume all incoming data itself and not call
+  // OnDataAvailable().
+  // When the FIN is received, the stream will be notified automatically (via
+  // OnFinRead()) (which may happen during the call of StopReading()).
+  // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
+  // stop sending stream-level flow-control updates when this end sends FIN.
+  virtual void StopReading();
+
+  // Sends as much of |data| to the connection on the application encryption
+  // level as the connection will consume, and then buffers any remaining data
+  // in the send buffer. If fin is true: if it is immediately passed on to the
+  // session, write_side_closed() becomes true, otherwise fin_buffered_ becomes
+  // true.
+  void WriteOrBufferData(
+      absl::string_view data, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Sends |data| to connection with specified |level|.
+  void WriteOrBufferDataAtLevel(
+      absl::string_view data, bool fin, EncryptionLevel level,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Adds random padding after the fin is consumed for this stream.
+  void AddRandomPaddingAfterFin();
+
+  // Write |data_length| of data starts at |offset| from send buffer.
+  bool WriteStreamData(QuicStreamOffset offset, QuicByteCount data_length,
+                       QuicDataWriter* writer);
+
+  // Called when data [offset, offset + data_length) is acked. |fin_acked|
+  // indicates whether the fin is acked. Returns true and updates
+  // |newly_acked_length| if any new stream data (including fin) gets acked.
+  virtual bool OnStreamFrameAcked(QuicStreamOffset offset,
+                                  QuicByteCount data_length, bool fin_acked,
+                                  QuicTime::Delta ack_delay_time,
+                                  QuicTime receive_timestamp,
+                                  QuicByteCount* newly_acked_length);
+
+  // Called when data [offset, offset + data_length) was retransmitted.
+  // |fin_retransmitted| indicates whether fin was retransmitted.
+  virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                          QuicByteCount data_length,
+                                          bool fin_retransmitted);
+
+  // Called when data [offset, offset + data_length) is considered as lost.
+  // |fin_lost| indicates whether the fin is considered as lost.
+  virtual void OnStreamFrameLost(QuicStreamOffset offset,
+                                 QuicByteCount data_length, bool fin_lost);
+
+  // Called to retransmit outstanding portion in data [offset, offset +
+  // data_length) and |fin| with Transmission |type|.
+  // Returns true if all data gets retransmitted.
+  virtual bool RetransmitStreamData(QuicStreamOffset offset,
+                                    QuicByteCount data_length, bool fin,
+                                    TransmissionType type);
+
+  // Sets deadline of this stream to be now + |ttl|, returns true if the setting
+  // succeeds.
+  bool MaybeSetTtl(QuicTime::Delta ttl);
+
+  // Commits data into the stream write buffer, and potentially sends it over
+  // the wire.  This method has all-or-nothing semantics: if the write buffer is
+  // not full, all of the memslices in |span| are moved into it; otherwise,
+  // nothing happens.
+  QuicConsumedData WriteMemSlices(absl::Span<quiche::QuicheMemSlice> span,
+                                  bool fin);
+  QuicConsumedData WriteMemSlice(quiche::QuicheMemSlice span, bool fin);
+
+  // Returns true if any stream data is lost (including fin) and needs to be
+  // retransmitted.
+  virtual bool HasPendingRetransmission() const;
+
+  // Returns true if any portion of data [offset, offset + data_length) is
+  // outstanding or fin is outstanding (if |fin| is true). Returns false
+  // otherwise.
+  bool IsStreamFrameOutstanding(QuicStreamOffset offset,
+                                QuicByteCount data_length, bool fin) const;
+
+  StreamType type() const { return type_; }
+
+  // Handle received StopSending frame. Returns true if the processing finishes
+  // gracefully.
+  virtual bool OnStopSending(QuicResetStreamError error);
+
+  // Returns true if the stream is static.
+  bool is_static() const { return is_static_; }
+
+  bool was_draining() const { return was_draining_; }
+
+  static spdy::SpdyStreamPrecedence CalculateDefaultPriority(
+      const QuicSession* session);
+
+  QuicTime creation_time() const { return creation_time_; }
+
+  bool fin_buffered() const { return fin_buffered_; }
+
+  // True if buffered data in send buffer is below buffered_data_threshold_.
+  bool CanWriteNewData() const;
+
+  // Called immediately after the stream is created from a pending stream,
+  // indicating it can start processing data.
+  void OnStreamCreatedFromPendingStream();
+
+ protected:
+  // Called when data of [offset, offset + data_length] is buffered in send
+  // buffer.
+  virtual void OnDataBuffered(
+      QuicStreamOffset /*offset*/, QuicByteCount /*data_length*/,
+      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
+      /*ack_listener*/) {}
+
+  // Called just before the object is destroyed.
+  // The object should not be accessed after OnClose is called.
+  // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
+  // a RST_STREAM has been sent.
+  virtual void OnClose();
+
+  // True if buffered data in send buffer is still below
+  // buffered_data_threshold_ even after writing |length| bytes.
+  bool CanWriteNewDataAfterData(QuicByteCount length) const;
+
+  // Called when upper layer can write new data.
+  virtual void OnCanWriteNewData() {}
+
+  // Called when |bytes_consumed| bytes has been consumed.
+  virtual void OnStreamDataConsumed(QuicByteCount bytes_consumed);
+
+  // Called by the stream sequencer as bytes are consumed from the buffer.
+  // If the receive window has dropped below the threshold, then send a
+  // WINDOW_UPDATE frame.
+  void AddBytesConsumed(QuicByteCount bytes) override;
+
+  // Writes pending retransmissions if any.
+  virtual void WritePendingRetransmission();
+
+  // This is called when stream tries to retransmit data after deadline_. Make
+  // this virtual so that subclasses can implement their own logics.
+  virtual void OnDeadlinePassed();
+
+  // Called to set fin_sent_. This is only used by Google QUIC while body is
+  // empty.
+  void SetFinSent();
+
+  // Send STOP_SENDING if it hasn't been sent yet.
+  void MaybeSendStopSending(QuicResetStreamError error);
+
+  // Send RESET_STREAM if it hasn't been sent yet.
+  void MaybeSendRstStream(QuicResetStreamError error);
+
+  // Convenience warppers for two methods above.
+  void MaybeSendRstStream(QuicRstStreamErrorCode error) {
+    MaybeSendRstStream(QuicResetStreamError::FromInternal(error));
+  }
+  void MaybeSendStopSending(QuicRstStreamErrorCode error) {
+    MaybeSendStopSending(QuicResetStreamError::FromInternal(error));
+  }
+
+  // Close the write side of the socket.  Further writes will fail.
+  // Can be called by the subclass or internally.
+  // Does not send a FIN.  May cause the stream to be closed.
+  virtual void CloseWriteSide();
+
+  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
+  void set_stream_error(QuicResetStreamError error) { stream_error_ = error; }
+
+  StreamDelegateInterface* stream_delegate() { return stream_delegate_; }
+
+  const QuicSession* session() const { return session_; }
+  QuicSession* session() { return session_; }
+
+  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
+  QuicStreamSequencer* sequencer() { return &sequencer_; }
+
+  void DisableConnectionFlowControlForThisStream() {
+    stream_contributes_to_connection_flow_control_ = false;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;
+
+  const QuicStreamSendBuffer& send_buffer() const { return send_buffer_; }
+
+  QuicStreamSendBuffer& send_buffer() { return send_buffer_; }
+
+  // Called when the write side of the stream is closed, and all of the outgoing
+  // data has been acknowledged.  This corresponds to the "Data Recvd" state of
+  // RFC 9000.
+  virtual void OnWriteSideInDataRecvdState() {}
+
+  // Return the current flow control send window in bytes.
+  absl::optional<QuicByteCount> GetSendWindow() const;
+  absl::optional<QuicByteCount> GetReceiveWindow() const;
+
+ private:
+  friend class test::QuicStreamPeer;
+  friend class QuicStreamUtils;
+
+  QuicStream(QuicStreamId id, QuicSession* session,
+             QuicStreamSequencer sequencer, bool is_static, StreamType type,
+             uint64_t stream_bytes_read, bool fin_received,
+             absl::optional<QuicFlowController> flow_controller,
+             QuicFlowController* connection_flow_controller);
+
+  // Calls MaybeSendBlocked on the stream's flow controller and the connection
+  // level flow controller.  If the stream is flow control blocked by the
+  // connection-level flow controller but not by the stream-level flow
+  // controller, marks this stream as connection-level write blocked.
+  void MaybeSendBlocked();
+
+  // Write buffered data (in send buffer) at |level|.
+  void WriteBufferedData(EncryptionLevel level);
+
+  // Close the read side of the stream.  May cause the stream to be closed.
+  void CloseReadSide();
+
+  // Called when bytes are sent to the peer.
+  void AddBytesSent(QuicByteCount bytes);
+
+  // Returns true if deadline_ has passed.
+  bool HasDeadlinePassed() const;
+
+  QuicStreamSequencer sequencer_;
+  QuicStreamId id_;
+  // Pointer to the owning QuicSession object.
+  // TODO(b/136274541): Remove session pointer from streams.
+  QuicSession* session_;
+  StreamDelegateInterface* stream_delegate_;
+  // The precedence of the stream, once parsed.
+  spdy::SpdyStreamPrecedence precedence_;
+  // Bytes read refers to payload bytes only: they do not include framing,
+  // encryption overhead etc.
+  uint64_t stream_bytes_read_;
+
+  // Stream error code received from a RstStreamFrame or error code sent by the
+  // visitor or sequencer in the RstStreamFrame.
+  QuicResetStreamError stream_error_;
+  // Connection error code due to which the stream was closed. |stream_error_|
+  // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
+  // should check |connection_error_|.
+  QuicErrorCode connection_error_;
+
+  // True if the read side is closed and further frames should be rejected.
+  bool read_side_closed_;
+  // True if the write side is closed, and further writes should fail.
+  bool write_side_closed_;
+
+  // True if OnWriteSideInDataRecvdState() has already been called.
+  bool write_side_data_recvd_state_notified_;
+
+  // True if the subclass has written a FIN with WriteOrBufferData, but it was
+  // buffered in queued_data_ rather than being sent to the session.
+  bool fin_buffered_;
+  // True if a FIN has been sent to the session.
+  bool fin_sent_;
+  // True if a FIN is waiting to be acked.
+  bool fin_outstanding_;
+  // True if a FIN is lost.
+  bool fin_lost_;
+
+  // True if this stream has received (and the sequencer has accepted) a
+  // StreamFrame with the FIN set.
+  bool fin_received_;
+
+  // True if an RST_STREAM has been sent to the session.
+  // In combination with fin_sent_, used to ensure that a FIN and/or a
+  // RST_STREAM is always sent to terminate the stream.
+  bool rst_sent_;
+
+  // True if this stream has received a RST_STREAM frame.
+  bool rst_received_;
+
+  // True if the stream has sent STOP_SENDING to the session.
+  bool stop_sending_sent_;
+
+  absl::optional<QuicFlowController> flow_controller_;
+
+  // The connection level flow controller. Not owned.
+  QuicFlowController* connection_flow_controller_;
+
+  // Special streams, such as the crypto and headers streams, do not respect
+  // connection level flow control limits (but are stream level flow control
+  // limited).
+  bool stream_contributes_to_connection_flow_control_;
+
+  // A counter incremented when OnCanWrite() is called and no progress is made.
+  // For debugging only.
+  size_t busy_counter_;
+
+  // Indicates whether paddings will be added after the fin is consumed for this
+  // stream.
+  bool add_random_padding_after_fin_;
+
+  // Send buffer of this stream. Send buffer is cleaned up when data gets acked
+  // or discarded.
+  QuicStreamSendBuffer send_buffer_;
+
+  // Latched value of quic_buffered_data_threshold.
+  const QuicByteCount buffered_data_threshold_;
+
+  // If true, then this stream has precedence over other streams for write
+  // scheduling.
+  const bool is_static_;
+
+  // If initialized, reset this stream at this deadline.
+  QuicTime deadline_;
+
+  // True if this stream has entered draining state.
+  bool was_draining_;
+
+  // Indicates whether this stream is bidirectional, read unidirectional or
+  // write unidirectional.
+  const StreamType type_;
+
+  // Creation time of this stream, as reported by the QuicClock.
+  const QuicTime creation_time_;
+
+  Perspective perspective_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_H_
diff --git a/quiche/quic/core/quic_stream_frame_data_producer.h b/quiche/quic/core/quic_stream_frame_data_producer.h
new file mode 100644
index 0000000..886c875
--- /dev/null
+++ b/quiche/quic/core/quic_stream_frame_data_producer.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QuicDataWriter;
+
+// Pure virtual class to retrieve stream data.
+class QUIC_EXPORT_PRIVATE QuicStreamFrameDataProducer {
+ public:
+  virtual ~QuicStreamFrameDataProducer() {}
+
+  // Let |writer| write |data_length| data with |offset| of stream |id|. The
+  // write fails when either stream is closed or corresponding data is failed to
+  // be retrieved. This method allows writing a single stream frame from data
+  // that spans multiple buffers.
+  virtual WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                                QuicStreamOffset offset,
+                                                QuicByteCount data_length,
+                                                QuicDataWriter* writer) = 0;
+
+  // Writes the data for a CRYPTO frame to |writer| for a frame at encryption
+  // level |level| starting at offset |offset| for |data_length| bytes. Returns
+  // whether writing the data was successful.
+  virtual bool WriteCryptoData(EncryptionLevel level,
+                               QuicStreamOffset offset,
+                               QuicByteCount data_length,
+                               QuicDataWriter* writer) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_FRAME_DATA_PRODUCER_H_
diff --git a/quiche/quic/core/quic_stream_id_manager.cc b/quiche/quic/core/quic_stream_id_manager.cc
new file mode 100644
index 0000000..04d93bb
--- /dev/null
+++ b/quiche/quic/core/quic_stream_id_manager.cc
@@ -0,0 +1,243 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "quiche/quic/core/quic_stream_id_manager.h"
+
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective_ == Perspective::IS_SERVER ? " Server: " : " Client: ")
+
+QuicStreamIdManager::QuicStreamIdManager(
+    DelegateInterface* delegate,
+    bool unidirectional,
+    Perspective perspective,
+    ParsedQuicVersion version,
+    QuicStreamCount max_allowed_outgoing_streams,
+    QuicStreamCount max_allowed_incoming_streams)
+    : delegate_(delegate),
+      unidirectional_(unidirectional),
+      perspective_(perspective),
+      version_(version),
+      outgoing_max_streams_(max_allowed_outgoing_streams),
+      next_outgoing_stream_id_(GetFirstOutgoingStreamId()),
+      outgoing_stream_count_(0),
+      incoming_actual_max_streams_(max_allowed_incoming_streams),
+      incoming_advertised_max_streams_(max_allowed_incoming_streams),
+      incoming_initial_max_open_streams_(max_allowed_incoming_streams),
+      incoming_stream_count_(0),
+      largest_peer_created_stream_id_(
+          QuicUtils::GetInvalidStreamId(version.transport_version)) {}
+
+QuicStreamIdManager::~QuicStreamIdManager() {}
+
+bool QuicStreamIdManager::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame,
+    std::string* error_details) {
+  QUICHE_DCHECK_EQ(frame.unidirectional, unidirectional_);
+  if (frame.stream_count > incoming_advertised_max_streams_) {
+    // Peer thinks it can send more streams that we've told it.
+    *error_details = absl::StrCat(
+        "StreamsBlockedFrame's stream count ", frame.stream_count,
+        " exceeds incoming max stream ", incoming_advertised_max_streams_);
+    return false;
+  }
+  QUICHE_DCHECK_LE(incoming_advertised_max_streams_,
+                   incoming_actual_max_streams_);
+  if (incoming_advertised_max_streams_ == incoming_actual_max_streams_) {
+    // We have told peer about current max.
+    return true;
+  }
+  if (frame.stream_count < incoming_actual_max_streams_) {
+    // Peer thinks it's blocked on a stream count that is less than our current
+    // max. Inform the peer of the correct stream count.
+    SendMaxStreamsFrame();
+  }
+  return true;
+}
+
+bool QuicStreamIdManager::MaybeAllowNewOutgoingStreams(
+    QuicStreamCount max_open_streams) {
+  if (max_open_streams <= outgoing_max_streams_) {
+    // Only update the stream count if it would increase the limit.
+    return false;
+  }
+
+  // This implementation only supports 32 bit Stream IDs, so limit max streams
+  // if it would exceed the max 32 bits can express.
+  outgoing_max_streams_ =
+      std::min(max_open_streams, QuicUtils::GetMaxStreamCount());
+
+  return true;
+}
+
+void QuicStreamIdManager::SetMaxOpenIncomingStreams(
+    QuicStreamCount max_open_streams) {
+  QUIC_BUG_IF(quic_bug_12413_1, incoming_stream_count_ > 0)
+      << "non-zero incoming stream count " << incoming_stream_count_
+      << " when setting max incoming stream to " << max_open_streams;
+  QUIC_DLOG_IF(WARNING, incoming_initial_max_open_streams_ != max_open_streams)
+      << absl::StrCat(unidirectional_ ? "unidirectional " : "bidirectional: ",
+                      "incoming stream limit changed from ",
+                      incoming_initial_max_open_streams_, " to ",
+                      max_open_streams);
+  incoming_actual_max_streams_ = max_open_streams;
+  incoming_advertised_max_streams_ = max_open_streams;
+  incoming_initial_max_open_streams_ = max_open_streams;
+}
+
+void QuicStreamIdManager::MaybeSendMaxStreamsFrame() {
+  int divisor = GetQuicFlag(FLAGS_quic_max_streams_window_divisor);
+
+  if (divisor > 0) {
+    if ((incoming_advertised_max_streams_ - incoming_stream_count_) >
+        (incoming_initial_max_open_streams_ / divisor)) {
+      // window too large, no advertisement
+      return;
+    }
+  }
+  SendMaxStreamsFrame();
+}
+
+void QuicStreamIdManager::SendMaxStreamsFrame() {
+  QUIC_BUG_IF(quic_bug_12413_2,
+              incoming_advertised_max_streams_ >= incoming_actual_max_streams_);
+  incoming_advertised_max_streams_ = incoming_actual_max_streams_;
+  delegate_->SendMaxStreams(incoming_advertised_max_streams_, unidirectional_);
+}
+
+void QuicStreamIdManager::OnStreamClosed(QuicStreamId stream_id) {
+  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
+                   unidirectional_);
+  if (QuicUtils::IsOutgoingStreamId(version_, stream_id, perspective_)) {
+    // Nothing to do for outgoing streams.
+    return;
+  }
+  // If the stream is inbound, we can increase the actual stream limit and maybe
+  // advertise the new limit to the peer.
+  if (incoming_actual_max_streams_ == QuicUtils::GetMaxStreamCount()) {
+    // Reached the maximum stream id value that the implementation
+    // supports. Nothing can be done here.
+    return;
+  }
+  // One stream closed, and another one can be opened.
+  incoming_actual_max_streams_++;
+  MaybeSendMaxStreamsFrame();
+}
+
+QuicStreamId QuicStreamIdManager::GetNextOutgoingStreamId() {
+  QUIC_BUG_IF(quic_bug_12413_3, outgoing_stream_count_ >= outgoing_max_streams_)
+      << "Attempt to allocate a new outgoing stream that would exceed the "
+         "limit ("
+      << outgoing_max_streams_ << ")";
+  QuicStreamId id = next_outgoing_stream_id_;
+  next_outgoing_stream_id_ +=
+      QuicUtils::StreamIdDelta(version_.transport_version);
+  outgoing_stream_count_++;
+  return id;
+}
+
+bool QuicStreamIdManager::CanOpenNextOutgoingStream() const {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(version_.transport_version));
+  return outgoing_stream_count_ < outgoing_max_streams_;
+}
+
+bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
+    const QuicStreamId stream_id,
+    std::string* error_details) {
+  // |stream_id| must be an incoming stream of the right directionality.
+  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
+                   unidirectional_);
+  QUICHE_DCHECK_NE(QuicUtils::IsServerInitiatedStreamId(
+                       version_.transport_version, stream_id),
+                   perspective_ == Perspective::IS_SERVER);
+  if (available_streams_.erase(stream_id) == 1) {
+    // stream_id is available.
+    return true;
+  }
+
+  if (largest_peer_created_stream_id_ !=
+      QuicUtils::GetInvalidStreamId(version_.transport_version)) {
+    QUICHE_DCHECK_GT(stream_id, largest_peer_created_stream_id_);
+  }
+
+  // Calculate increment of incoming_stream_count_ by creating stream_id.
+  const QuicStreamCount delta =
+      QuicUtils::StreamIdDelta(version_.transport_version);
+  const QuicStreamId least_new_stream_id =
+      largest_peer_created_stream_id_ ==
+              QuicUtils::GetInvalidStreamId(version_.transport_version)
+          ? GetFirstIncomingStreamId()
+          : largest_peer_created_stream_id_ + delta;
+  const QuicStreamCount stream_count_increment =
+      (stream_id - least_new_stream_id) / delta + 1;
+
+  if (incoming_stream_count_ + stream_count_increment >
+      incoming_advertised_max_streams_) {
+    QUIC_DLOG(INFO) << ENDPOINT
+                    << "Failed to create a new incoming stream with id:"
+                    << stream_id << ", reaching MAX_STREAMS limit: "
+                    << incoming_advertised_max_streams_ << ".";
+    *error_details = absl::StrCat("Stream id ", stream_id,
+                                  " would exceed stream count limit ",
+                                  incoming_advertised_max_streams_);
+    return false;
+  }
+
+  for (QuicStreamId id = least_new_stream_id; id < stream_id; id += delta) {
+    available_streams_.insert(id);
+  }
+  incoming_stream_count_ += stream_count_increment;
+  largest_peer_created_stream_id_ = stream_id;
+  return true;
+}
+
+bool QuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
+  QUICHE_DCHECK_NE(QuicUtils::IsBidirectionalStreamId(id, version_),
+                   unidirectional_);
+  if (QuicUtils::IsOutgoingStreamId(version_, id, perspective_)) {
+    // Stream IDs under next_ougoing_stream_id_ are either open or previously
+    // open but now closed.
+    return id >= next_outgoing_stream_id_;
+  }
+  // For peer created streams, we also need to consider available streams.
+  return largest_peer_created_stream_id_ ==
+             QuicUtils::GetInvalidStreamId(version_.transport_version) ||
+         id > largest_peer_created_stream_id_ ||
+         available_streams_.contains(id);
+}
+
+QuicStreamId QuicStreamIdManager::GetFirstOutgoingStreamId() const {
+  return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
+                                 version_.transport_version, perspective_)
+                           : QuicUtils::GetFirstBidirectionalStreamId(
+                                 version_.transport_version, perspective_);
+}
+
+QuicStreamId QuicStreamIdManager::GetFirstIncomingStreamId() const {
+  return (unidirectional_) ? QuicUtils::GetFirstUnidirectionalStreamId(
+                                 version_.transport_version,
+                                 QuicUtils::InvertPerspective(perspective_))
+                           : QuicUtils::GetFirstBidirectionalStreamId(
+                                 version_.transport_version,
+                                 QuicUtils::InvertPerspective(perspective_));
+}
+
+QuicStreamCount QuicStreamIdManager::available_incoming_streams() const {
+  return incoming_advertised_max_streams_ - incoming_stream_count_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_id_manager.h b/quiche/quic/core/quic_stream_id_manager.h
new file mode 100644
index 0000000..33d7566
--- /dev/null
+++ b/quiche/quic/core/quic_stream_id_manager.h
@@ -0,0 +1,186 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
+
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace test {
+class QuicSessionPeer;
+class QuicStreamIdManagerPeer;
+}  // namespace test
+
+// This class manages the stream ids for IETF QUIC.
+class QUIC_EXPORT_PRIVATE QuicStreamIdManager {
+ public:
+  class QUIC_EXPORT_PRIVATE DelegateInterface {
+   public:
+    virtual ~DelegateInterface() = default;
+
+    // Send a MAX_STREAMS frame.
+    virtual void SendMaxStreams(QuicStreamCount stream_count,
+                                bool unidirectional) = 0;
+  };
+
+  QuicStreamIdManager(DelegateInterface* delegate,
+                      bool unidirectional,
+                      Perspective perspective,
+                      ParsedQuicVersion version,
+                      QuicStreamCount max_allowed_outgoing_streams,
+                      QuicStreamCount max_allowed_incoming_streams);
+
+  ~QuicStreamIdManager();
+
+  // Generate a string suitable for sending to the log/etc to show current state
+  // of the stream ID manager.
+  std::string DebugString() const {
+    return absl::StrCat(
+        " { unidirectional_: ", unidirectional_,
+        ", perspective: ", perspective_,
+        ", outgoing_max_streams_: ", outgoing_max_streams_,
+        ", next_outgoing_stream_id_: ", next_outgoing_stream_id_,
+        ", outgoing_stream_count_: ", outgoing_stream_count_,
+        ", incoming_actual_max_streams_: ", incoming_actual_max_streams_,
+        ", incoming_advertised_max_streams_: ",
+        incoming_advertised_max_streams_,
+        ", incoming_stream_count_: ", incoming_stream_count_,
+        ", available_streams_.size(): ", available_streams_.size(),
+        ", largest_peer_created_stream_id_: ", largest_peer_created_stream_id_,
+        " }");
+  }
+
+  // Processes the STREAMS_BLOCKED frame. If error is encountered, populates
+  // |error_details| and returns false.
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                             std::string* error_details);
+
+  // Returns whether the next outgoing stream ID can be allocated or not.
+  bool CanOpenNextOutgoingStream() const;
+
+  // Generate and send a MAX_STREAMS frame.
+  void SendMaxStreamsFrame();
+
+  // Invoked to deal with releasing a stream. Does nothing if the stream is
+  // outgoing. If the stream is incoming, the number of streams that the peer
+  // can open will be updated and a MAX_STREAMS frame, informing the peer of
+  // the additional streams, may be sent.
+  void OnStreamClosed(QuicStreamId stream_id);
+
+  // Returns the next outgoing stream id. Applications must call
+  // CanOpenNextOutgoingStream() first.
+  QuicStreamId GetNextOutgoingStreamId();
+
+  void SetMaxOpenIncomingStreams(QuicStreamCount max_open_streams);
+
+  // Called on |max_open_streams| outgoing streams can be created because of 1)
+  // config negotiated or 2) MAX_STREAMS received. Returns true if new
+  // streams can be created.
+  bool MaybeAllowNewOutgoingStreams(QuicStreamCount max_open_streams);
+
+  // Checks if the incoming stream ID exceeds the MAX_STREAMS limit.  If the
+  // limit is exceeded, populates |error_detials| and returns false.
+  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id,
+                                        std::string* error_details);
+
+  // Returns true if |id| is still available.
+  bool IsAvailableStream(QuicStreamId id) const;
+
+  QuicStreamCount incoming_initial_max_open_streams() const {
+    return incoming_initial_max_open_streams_;
+  }
+
+  QuicStreamId next_outgoing_stream_id() const {
+    return next_outgoing_stream_id_;
+  }
+
+  // Number of streams that the peer believes that it can still create.
+  QuicStreamCount available_incoming_streams() const;
+
+  QuicStreamId largest_peer_created_stream_id() const {
+    return largest_peer_created_stream_id_;
+  }
+
+  QuicStreamCount outgoing_max_streams() const { return outgoing_max_streams_; }
+  QuicStreamCount incoming_actual_max_streams() const {
+    return incoming_actual_max_streams_;
+  }
+  QuicStreamCount incoming_advertised_max_streams() const {
+    return incoming_advertised_max_streams_;
+  }
+  QuicStreamCount outgoing_stream_count() const {
+    return outgoing_stream_count_;
+  }
+
+ private:
+  friend class test::QuicSessionPeer;
+  friend class test::QuicStreamIdManagerPeer;
+
+  // Check whether the MAX_STREAMS window has opened up enough and, if so,
+  // generate and send a MAX_STREAMS frame.
+  void MaybeSendMaxStreamsFrame();
+
+  // Get what should be the first incoming/outgoing stream ID that
+  // this stream id manager will manage, taking into account directionality and
+  // client/server perspective.
+  QuicStreamId GetFirstOutgoingStreamId() const;
+  QuicStreamId GetFirstIncomingStreamId() const;
+
+  // Back reference to the session containing this Stream ID Manager.
+  DelegateInterface* delegate_;
+
+  // Whether this stream id manager is for unidrectional (true) or bidirectional
+  // (false) streams.
+  const bool unidirectional_;
+
+  // Is this manager a client or a server.
+  const Perspective perspective_;
+
+  // QUIC version used for this manager.
+  const ParsedQuicVersion version_;
+
+  // The number of streams that this node can initiate.
+  // This limit is first set when config is negotiated, but may be updated upon
+  // receiving MAX_STREAMS frame.
+  QuicStreamCount outgoing_max_streams_;
+
+  // The ID to use for the next outgoing stream.
+  QuicStreamId next_outgoing_stream_id_;
+
+  // The number of outgoing streams that have ever been opened, including those
+  // that have been closed. This number must never be larger than
+  // outgoing_max_streams_.
+  QuicStreamCount outgoing_stream_count_;
+
+  // FOR INCOMING STREAMS
+
+  // The actual maximum number of streams that can be opened by the peer.
+  QuicStreamCount incoming_actual_max_streams_;
+  // Max incoming stream number that has been advertised to the peer and is <=
+  // incoming_actual_max_streams_. It is set to incoming_actual_max_streams_
+  // when a MAX_STREAMS is sent.
+  QuicStreamCount incoming_advertised_max_streams_;
+
+  // Initial maximum on the number of open streams allowed.
+  QuicStreamCount incoming_initial_max_open_streams_;
+
+  // The number of streams that have been created, including open ones and
+  // closed ones.
+  QuicStreamCount incoming_stream_count_;
+
+  // Set of stream ids that are less than the largest stream id that has been
+  // received, but are nonetheless available to be created.
+  absl::flat_hash_set<QuicStreamId> available_streams_;
+
+  QuicStreamId largest_peer_created_stream_id_;
+};
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quiche/quic/core/quic_stream_id_manager_test.cc b/quiche/quic/core/quic_stream_id_manager_test.cc
new file mode 100644
index 0000000..a9b3e6f
--- /dev/null
+++ b/quiche/quic/core/quic_stream_id_manager_test.cc
@@ -0,0 +1,479 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "quiche/quic/core/quic_stream_id_manager.h"
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockDelegate : public QuicStreamIdManager::DelegateInterface {
+ public:
+  MOCK_METHOD(void,
+              SendMaxStreams,
+              (QuicStreamCount stream_count, bool unidirectional),
+              (override));
+};
+
+struct TestParams {
+  TestParams(ParsedQuicVersion version,
+             Perspective perspective,
+             bool is_unidirectional)
+      : version(version),
+        perspective(perspective),
+        is_unidirectional(is_unidirectional) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+  bool is_unidirectional;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"),
+      (p.is_unidirectional ? "Unidirectional" : "Bidirectional"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (!version.HasIetfQuicFrames()) {
+      continue;
+    }
+    for (Perspective perspective :
+         {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
+      for (bool is_unidirectional : {true, false}) {
+        params.push_back(TestParams(version, perspective, is_unidirectional));
+      }
+    }
+  }
+  return params;
+}
+
+class QuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
+ protected:
+  QuicStreamIdManagerTest()
+      : stream_id_manager_(&delegate_,
+                           IsUnidirectional(),
+                           perspective(),
+                           GetParam().version,
+                           0,
+                           kDefaultMaxStreamsPerConnection) {
+    QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
+  }
+
+  QuicTransportVersion transport_version() const {
+    return GetParam().version.transport_version;
+  }
+
+  // Returns the stream ID for the Nth incoming stream (created by the peer)
+  // of the corresponding directionality of this manager.
+  QuicStreamId GetNthIncomingStreamId(int n) {
+    return QuicUtils::StreamIdDelta(transport_version()) * n +
+           (IsUnidirectional()
+                ? QuicUtils::GetFirstUnidirectionalStreamId(
+                      transport_version(),
+                      QuicUtils::InvertPerspective(perspective()))
+                : QuicUtils::GetFirstBidirectionalStreamId(
+                      transport_version(),
+                      QuicUtils::InvertPerspective(perspective())));
+  }
+
+  bool IsUnidirectional() { return GetParam().is_unidirectional; }
+  Perspective perspective() { return GetParam().perspective; }
+
+  StrictMock<MockDelegate> delegate_;
+  QuicStreamIdManager stream_id_manager_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicStreamIdManagerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicStreamIdManagerTest, Initialization) {
+  EXPECT_EQ(0u, stream_id_manager_.outgoing_max_streams());
+
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_.incoming_actual_max_streams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_.incoming_advertised_max_streams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_.incoming_initial_max_open_streams());
+}
+
+// This test checks that the stream advertisement window is set to 1
+// if the number of stream ids is 1. This is a special case in the code.
+TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsWindowForSingleStream) {
+  stream_id_manager_.SetMaxOpenIncomingStreams(1);
+  EXPECT_EQ(1u, stream_id_manager_.incoming_initial_max_open_streams());
+  EXPECT_EQ(1u, stream_id_manager_.incoming_actual_max_streams());
+}
+
+TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
+  QuicStreamCount implementation_max = QuicUtils::GetMaxStreamCount();
+  // Ensure that the limit is less than the implementation maximum.
+  EXPECT_LT(stream_id_manager_.outgoing_max_streams(), implementation_max);
+
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeAllowNewOutgoingStreams(implementation_max + 1));
+  // Should be pegged at the max.
+  EXPECT_EQ(implementation_max, stream_id_manager_.outgoing_max_streams());
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
+// the count most recently advertised in a MAX_STREAMS frame.
+TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedOk) {
+  QuicStreamCount stream_count =
+      stream_id_manager_.incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidirectional());
+  // We have notified peer about current max.
+  EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()))
+      .Times(0);
+  std::string error_details;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is equal to the
+// count most recently advertised in a MAX_STREAMS frame. No MAX_STREAMS
+// should be generated.
+TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedNoOp) {
+  QuicStreamCount stream_count =
+      stream_id_manager_.incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is greater than
+// the count most recently advertised in a MAX_STREAMS frame. Expect a
+// connection close with an error.
+TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedTooBig) {
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+  QuicStreamCount stream_count =
+      stream_id_manager_.incoming_initial_max_open_streams() + 1;
+  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+  EXPECT_EQ(
+      error_details,
+      "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
+}
+
+// Same basic tests as above, but calls
+// QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId directly, avoiding the
+// call chain. The intent is that if there is a problem, the following tests
+// will point to either the stream ID manager or the call chain. They also
+// provide specific, small scale, tests of a public QuicStreamIdManager method.
+// First test make sure that streams with ids below the limit are accepted.
+TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidBelowLimit) {
+  QuicStreamId stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() - 2);
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
+}
+
+// Accept a stream with an ID that equals the limit.
+TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidAtLimit) {
+  QuicStreamId stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() - 1);
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
+}
+
+// Close the connection if the id exceeds the limit.
+TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdInValidAboveLimit) {
+  QuicStreamId stream_id =
+      GetNthIncomingStreamId(stream_id_manager_.incoming_actual_max_streams());
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      stream_id, &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat("Stream id ", stream_id,
+                         " would exceed stream count limit 100"));
+}
+
+TEST_P(QuicStreamIdManagerTest, OnStreamsBlockedFrame) {
+  // Get the current maximum allowed incoming stream count.
+  QuicStreamCount advertised_stream_count =
+      stream_id_manager_.incoming_advertised_max_streams();
+
+  QuicStreamsBlockedFrame frame;
+
+  frame.unidirectional = IsUnidirectional();
+
+  // If the peer is saying it's blocked on the stream count that
+  // we've advertised, it's a noop since the peer has the correct information.
+  frame.stream_count = advertised_stream_count;
+  std::string error_details;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+
+  // If the peer is saying it's blocked on a stream count that is larger
+  // than what we've advertised, the connection should get closed.
+  frame.stream_count = advertised_stream_count + 1;
+  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+  EXPECT_EQ(
+      error_details,
+      "StreamsBlockedFrame's stream count 101 exceeds incoming max stream 100");
+
+  // If the peer is saying it's blocked on a count that is less than
+  // our actual count, we send a MAX_STREAMS frame and update
+  // the advertised value.
+  // First, need to bump up the actual max so there is room for the MAX
+  // STREAMS frame to send a larger ID.
+  QuicStreamCount actual_stream_count =
+      stream_id_manager_.incoming_actual_max_streams();
+
+  // Closing a stream will result in the ability to initiate one more
+  // stream
+  stream_id_manager_.OnStreamClosed(
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_));
+  EXPECT_EQ(actual_stream_count + 1u,
+            stream_id_manager_.incoming_actual_max_streams());
+  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
+            stream_id_manager_.incoming_advertised_max_streams() + 1u);
+
+  // Now simulate receiving a STREAMS_BLOCKED frame...
+  // Changing the actual maximum, above, forces a MAX_STREAMS frame to be
+  // sent, so the logic for that (SendMaxStreamsFrame(), etc) is tested.
+
+  // The STREAMS_BLOCKED frame contains the previous advertised count,
+  // not the one that the peer would have received as a result of the
+  // MAX_STREAMS sent earler.
+  frame.stream_count = advertised_stream_count;
+
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
+                             IsUnidirectional()));
+
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+  // Check that the saved frame is correct.
+  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
+            stream_id_manager_.incoming_advertised_max_streams());
+}
+
+TEST_P(QuicStreamIdManagerTest, GetNextOutgoingStream) {
+  // Number of streams we can open and the first one we should get when
+  // opening...
+  size_t number_of_streams = kDefaultMaxStreamsPerConnection;
+
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeAllowNewOutgoingStreams(number_of_streams));
+
+  QuicStreamId stream_id = IsUnidirectional()
+                               ? QuicUtils::GetFirstUnidirectionalStreamId(
+                                     transport_version(), perspective())
+                               : QuicUtils::GetFirstBidirectionalStreamId(
+                                     transport_version(), perspective());
+
+  EXPECT_EQ(number_of_streams, stream_id_manager_.outgoing_max_streams());
+  while (number_of_streams) {
+    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
+    EXPECT_EQ(stream_id, stream_id_manager_.GetNextOutgoingStreamId());
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+    number_of_streams--;
+  }
+
+  // If we try to check that the next outgoing stream id is available it should
+  // fail.
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
+
+  // If we try to get the next id (above the limit), it should cause a quic-bug.
+  EXPECT_QUIC_BUG(
+      stream_id_manager_.GetNextOutgoingStreamId(),
+      "Attempt to allocate a new outgoing stream that would exceed the limit");
+}
+
+TEST_P(QuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
+  QuicStreamId max_stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() - 1);
+  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(max_stream_id,
+                                                                  nullptr));
+
+  QuicStreamId first_stream_id = GetNthIncomingStreamId(0);
+  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      first_stream_id, nullptr));
+  // A bad stream ID results in a closed connection.
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
+      &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat(
+                "Stream id ",
+                max_stream_id + QuicUtils::StreamIdDelta(transport_version()),
+                " would exceed stream count limit 100"));
+}
+
+TEST_P(QuicStreamIdManagerTest, MaxStreamsWindow) {
+  // Open and then close a number of streams to get close to the threshold of
+  // sending a MAX_STREAM_FRAME.
+  int stream_count = stream_id_manager_.incoming_initial_max_open_streams() /
+                         GetQuicFlag(FLAGS_quic_max_streams_window_divisor) -
+                     1;
+
+  // Should not get a control-frame transmission since the peer should have
+  // "plenty" of stream IDs to use.
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+
+  // Get the first incoming stream ID to try and allocate.
+  QuicStreamId stream_id = GetNthIncomingStreamId(0);
+  size_t old_available_incoming_streams =
+      stream_id_manager_.available_incoming_streams();
+  auto i = stream_count;
+  while (i) {
+    EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id,
+                                                                    nullptr));
+
+    // This node should think that the peer believes it has one fewer
+    // stream it can create.
+    old_available_incoming_streams--;
+    EXPECT_EQ(old_available_incoming_streams,
+              stream_id_manager_.available_incoming_streams());
+
+    i--;
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+  }
+
+  // Now close them, still should get no MAX_STREAMS
+  stream_id = GetNthIncomingStreamId(0);
+  QuicStreamCount expected_actual_max =
+      stream_id_manager_.incoming_actual_max_streams();
+  QuicStreamCount expected_advertised_max_streams =
+      stream_id_manager_.incoming_advertised_max_streams();
+  while (stream_count) {
+    stream_id_manager_.OnStreamClosed(stream_id);
+    stream_count--;
+    stream_id += QuicUtils::StreamIdDelta(transport_version());
+    expected_actual_max++;
+    EXPECT_EQ(expected_actual_max,
+              stream_id_manager_.incoming_actual_max_streams());
+    // Advertised maximum should remain the same.
+    EXPECT_EQ(expected_advertised_max_streams,
+              stream_id_manager_.incoming_advertised_max_streams());
+  }
+
+  // This should not change.
+  EXPECT_EQ(old_available_incoming_streams,
+            stream_id_manager_.available_incoming_streams());
+
+  // Now whenever we close a stream we should get a MAX_STREAMS frame.
+  // Above code closed all the open streams, so we have to open/close
+  //  EXPECT_CALL(delegate_,
+  //  SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
+  //  IsUnidirectional()));
+  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidirectional()));
+  EXPECT_TRUE(
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id, nullptr));
+  stream_id_manager_.OnStreamClosed(stream_id);
+}
+
+TEST_P(QuicStreamIdManagerTest, StreamsBlockedEdgeConditions) {
+  QuicStreamsBlockedFrame frame;
+  frame.unidirectional = IsUnidirectional();
+
+  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
+  // when max_allowed_incoming_streams is 0.
+  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
+  stream_id_manager_.SetMaxOpenIncomingStreams(0);
+  frame.stream_count = 0;
+  std::string error_details;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+
+  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
+  // MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
+  EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidirectional()));
+  QuicStreamIdManagerPeer::set_incoming_actual_max_streams(&stream_id_manager_,
+                                                           123);
+  frame.stream_count = 0;
+  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
+}
+
+// Test that a MAX_STREAMS frame is generated when half the stream ids become
+// available. This has a useful side effect of testing that when streams are
+// closed, the number of available stream ids increases.
+TEST_P(QuicStreamIdManagerTest, MaxStreamsSlidingWindow) {
+  QuicStreamCount first_advert =
+      stream_id_manager_.incoming_advertised_max_streams();
+
+  // Open/close enough streams to shrink the window without causing a MAX
+  // STREAMS to be generated. The loop
+  // will make that many stream IDs available, so the last CloseStream should
+  // cause a MAX STREAMS frame to be generated.
+  int i =
+      static_cast<int>(stream_id_manager_.incoming_initial_max_open_streams() /
+                       GetQuicFlag(FLAGS_quic_max_streams_window_divisor));
+  QuicStreamId id =
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_);
+  EXPECT_CALL(delegate_, SendMaxStreams(first_advert + i, IsUnidirectional()));
+  while (i) {
+    EXPECT_TRUE(
+        stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id, nullptr));
+    stream_id_manager_.OnStreamClosed(id);
+    i--;
+    id += QuicUtils::StreamIdDelta(transport_version());
+  }
+}
+
+TEST_P(QuicStreamIdManagerTest, NewStreamDoesNotExceedLimit) {
+  EXPECT_TRUE(stream_id_manager_.MaybeAllowNewOutgoingStreams(100));
+
+  size_t stream_count = stream_id_manager_.outgoing_max_streams();
+  EXPECT_NE(0u, stream_count);
+
+  while (stream_count) {
+    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
+    stream_id_manager_.GetNextOutgoingStreamId();
+    stream_count--;
+  }
+
+  EXPECT_EQ(stream_id_manager_.outgoing_stream_count(),
+            stream_id_manager_.outgoing_max_streams());
+  // Create another, it should fail.
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
+}
+
+TEST_P(QuicStreamIdManagerTest, AvailableStreams) {
+  stream_id_manager_.MaybeIncreaseLargestPeerStreamId(GetNthIncomingStreamId(3),
+                                                      nullptr);
+
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(1)));
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(2)));
+  EXPECT_FALSE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(3)));
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(4)));
+}
+
+// Tests that if MaybeIncreaseLargestPeerStreamId is given an extremely
+// large stream ID (larger than the limit) it is rejected.
+// This is a regression for Chromium bugs 909987 and 910040
+TEST_P(QuicStreamIdManagerTest, ExtremeMaybeIncreaseLargestPeerStreamId) {
+  QuicStreamId too_big_stream_id = GetNthIncomingStreamId(
+      stream_id_manager_.incoming_actual_max_streams() + 20);
+
+  std::string error_details;
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      too_big_stream_id, &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat("Stream id ", too_big_stream_id,
+                         " would exceed stream count limit 100"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_send_buffer.cc b/quiche/quic/core/quic_stream_send_buffer.cc
new file mode 100644
index 0000000..21decfd
--- /dev/null
+++ b/quiche/quic/core/quic_stream_send_buffer.cc
@@ -0,0 +1,298 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+
+#include <algorithm>
+
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+namespace {
+
+struct CompareOffset {
+  bool operator()(const BufferedSlice& slice, QuicStreamOffset offset) const {
+    return slice.offset + slice.slice.length() < offset;
+  }
+};
+
+}  // namespace
+
+BufferedSlice::BufferedSlice(quiche::QuicheMemSlice mem_slice,
+                             QuicStreamOffset offset)
+    : slice(std::move(mem_slice)), offset(offset) {}
+
+BufferedSlice::BufferedSlice(BufferedSlice&& other) = default;
+
+BufferedSlice& BufferedSlice::operator=(BufferedSlice&& other) = default;
+
+BufferedSlice::~BufferedSlice() {}
+
+QuicInterval<std::size_t> BufferedSlice::interval() const {
+  const std::size_t length = slice.length();
+  return QuicInterval<std::size_t>(offset, offset + length);
+}
+
+bool StreamPendingRetransmission::operator==(
+    const StreamPendingRetransmission& other) const {
+  return offset == other.offset && length == other.length;
+}
+
+QuicStreamSendBuffer::QuicStreamSendBuffer(
+    quiche::QuicheBufferAllocator* allocator)
+    : current_end_offset_(0),
+      stream_offset_(0),
+      allocator_(allocator),
+      stream_bytes_written_(0),
+      stream_bytes_outstanding_(0),
+      write_index_(-1) {}
+
+QuicStreamSendBuffer::~QuicStreamSendBuffer() {}
+
+void QuicStreamSendBuffer::SaveStreamData(absl::string_view data) {
+  QUICHE_DCHECK(!data.empty());
+
+  // Latch the maximum data slice size.
+  const QuicByteCount max_data_slice_size =
+      GetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size);
+  while (!data.empty()) {
+    auto slice_len = std::min<absl::string_view::size_type>(
+        data.length(), max_data_slice_size);
+    auto buffer =
+        quiche::QuicheBuffer::Copy(allocator_, data.substr(0, slice_len));
+    SaveMemSlice(quiche::QuicheMemSlice(std::move(buffer)));
+
+    data = data.substr(slice_len);
+  }
+}
+
+void QuicStreamSendBuffer::SaveMemSlice(quiche::QuicheMemSlice slice) {
+  QUIC_DVLOG(2) << "Save slice offset " << stream_offset_ << " length "
+                << slice.length();
+  if (slice.empty()) {
+    QUIC_BUG(quic_bug_10853_1) << "Try to save empty MemSlice to send buffer.";
+    return;
+  }
+  size_t length = slice.length();
+  // Need to start the offsets at the right interval.
+  if (interval_deque_.Empty()) {
+    const QuicStreamOffset end = stream_offset_ + length;
+    current_end_offset_ = std::max(current_end_offset_, end);
+  }
+  BufferedSlice bs = BufferedSlice(std::move(slice), stream_offset_);
+  interval_deque_.PushBack(std::move(bs));
+  stream_offset_ += length;
+}
+
+QuicByteCount QuicStreamSendBuffer::SaveMemSliceSpan(
+    absl::Span<quiche::QuicheMemSlice> span) {
+  QuicByteCount total = 0;
+  for (quiche::QuicheMemSlice& slice : span) {
+    if (slice.length() == 0) {
+      // Skip empty slices.
+      continue;
+    }
+    total += slice.length();
+    SaveMemSlice(std::move(slice));
+  }
+  return total;
+}
+
+void QuicStreamSendBuffer::OnStreamDataConsumed(size_t bytes_consumed) {
+  stream_bytes_written_ += bytes_consumed;
+  stream_bytes_outstanding_ += bytes_consumed;
+}
+
+bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
+                                           QuicByteCount data_length,
+                                           QuicDataWriter* writer) {
+  QUIC_BUG_IF(quic_bug_12823_1, current_end_offset_ < offset)
+      << "Tried to write data out of sequence. last_offset_end:"
+      << current_end_offset_ << ", offset:" << offset;
+  // The iterator returned from |interval_deque_| will automatically advance
+  // the internal write index for the QuicIntervalDeque. The incrementing is
+  // done in operator++.
+  for (auto slice_it = interval_deque_.DataAt(offset);
+       slice_it != interval_deque_.DataEnd(); ++slice_it) {
+    if (data_length == 0 || offset < slice_it->offset) {
+      break;
+    }
+
+    QuicByteCount slice_offset = offset - slice_it->offset;
+    QuicByteCount available_bytes_in_slice =
+        slice_it->slice.length() - slice_offset;
+    QuicByteCount copy_length = std::min(data_length, available_bytes_in_slice);
+    if (!writer->WriteBytes(slice_it->slice.data() + slice_offset,
+                            copy_length)) {
+      QUIC_BUG(quic_bug_10853_2) << "Writer fails to write.";
+      return false;
+    }
+    offset += copy_length;
+    data_length -= copy_length;
+    const QuicStreamOffset new_end =
+        slice_it->offset + slice_it->slice.length();
+    current_end_offset_ = std::max(current_end_offset_, new_end);
+  }
+  return data_length == 0;
+}
+
+bool QuicStreamSendBuffer::OnStreamDataAcked(
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    QuicByteCount* newly_acked_length) {
+  *newly_acked_length = 0;
+  if (data_length == 0) {
+    return true;
+  }
+  if (bytes_acked_.Empty() || offset >= bytes_acked_.rbegin()->max() ||
+      bytes_acked_.IsDisjoint(
+          QuicInterval<QuicStreamOffset>(offset, offset + data_length))) {
+    // Optimization for the typical case, when all data is newly acked.
+    if (stream_bytes_outstanding_ < data_length) {
+      return false;
+    }
+    bytes_acked_.AddOptimizedForAppend(offset, offset + data_length);
+    *newly_acked_length = data_length;
+    stream_bytes_outstanding_ -= data_length;
+    pending_retransmissions_.Difference(offset, offset + data_length);
+    if (!FreeMemSlices(offset, offset + data_length)) {
+      return false;
+    }
+    CleanUpBufferedSlices();
+    return true;
+  }
+  // Exit if no new data gets acked.
+  if (bytes_acked_.Contains(offset, offset + data_length)) {
+    return true;
+  }
+  // Execute the slow path if newly acked data fill in existing holes.
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Difference(bytes_acked_);
+  for (const auto& interval : newly_acked) {
+    *newly_acked_length += (interval.max() - interval.min());
+  }
+  if (stream_bytes_outstanding_ < *newly_acked_length) {
+    return false;
+  }
+  stream_bytes_outstanding_ -= *newly_acked_length;
+  bytes_acked_.Add(offset, offset + data_length);
+  pending_retransmissions_.Difference(offset, offset + data_length);
+  if (newly_acked.Empty()) {
+    return true;
+  }
+  if (!FreeMemSlices(newly_acked.begin()->min(), newly_acked.rbegin()->max())) {
+    return false;
+  }
+  CleanUpBufferedSlices();
+  return true;
+}
+
+void QuicStreamSendBuffer::OnStreamDataLost(QuicStreamOffset offset,
+                                            QuicByteCount data_length) {
+  if (data_length == 0) {
+    return;
+  }
+  QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
+  bytes_lost.Difference(bytes_acked_);
+  if (bytes_lost.Empty()) {
+    return;
+  }
+  for (const auto& lost : bytes_lost) {
+    pending_retransmissions_.Add(lost.min(), lost.max());
+  }
+}
+
+void QuicStreamSendBuffer::OnStreamDataRetransmitted(
+    QuicStreamOffset offset,
+    QuicByteCount data_length) {
+  if (data_length == 0) {
+    return;
+  }
+  pending_retransmissions_.Difference(offset, offset + data_length);
+}
+
+bool QuicStreamSendBuffer::HasPendingRetransmission() const {
+  return !pending_retransmissions_.Empty();
+}
+
+StreamPendingRetransmission QuicStreamSendBuffer::NextPendingRetransmission()
+    const {
+  if (HasPendingRetransmission()) {
+    const auto pending = pending_retransmissions_.begin();
+    return {pending->min(), pending->max() - pending->min()};
+  }
+  QUIC_BUG(quic_bug_10853_3)
+      << "NextPendingRetransmission is called unexpected with no "
+         "pending retransmissions.";
+  return {0, 0};
+}
+
+bool QuicStreamSendBuffer::FreeMemSlices(QuicStreamOffset start,
+                                         QuicStreamOffset end) {
+  auto it = interval_deque_.DataBegin();
+  if (it == interval_deque_.DataEnd() || it->slice.empty()) {
+    QUIC_BUG(quic_bug_10853_4)
+        << "Trying to ack stream data [" << start << ", " << end << "), "
+        << (it == interval_deque_.DataEnd()
+                ? "and there is no outstanding data."
+                : "and the first slice is empty.");
+    return false;
+  }
+  if (!it->interval().Contains(start)) {
+    // Slow path that not the earliest outstanding data gets acked.
+    it = std::lower_bound(interval_deque_.DataBegin(),
+                          interval_deque_.DataEnd(), start, CompareOffset());
+  }
+  if (it == interval_deque_.DataEnd() || it->slice.empty()) {
+    QUIC_BUG(quic_bug_10853_5)
+        << "Offset " << start << " with iterator offset: " << it->offset
+        << (it == interval_deque_.DataEnd() ? " does not exist."
+                                            : " has already been acked.");
+    return false;
+  }
+  for (; it != interval_deque_.DataEnd(); ++it) {
+    if (it->offset >= end) {
+      break;
+    }
+    if (!it->slice.empty() &&
+        bytes_acked_.Contains(it->offset, it->offset + it->slice.length())) {
+      it->slice.Reset();
+    }
+  }
+  return true;
+}
+
+void QuicStreamSendBuffer::CleanUpBufferedSlices() {
+  while (!interval_deque_.Empty() &&
+         interval_deque_.DataBegin()->slice.empty()) {
+    QUIC_BUG_IF(quic_bug_12823_2,
+                interval_deque_.DataBegin()->offset > current_end_offset_)
+        << "Fail to pop front from interval_deque_. Front element contained "
+           "a slice whose data has not all be written. Front offset "
+        << interval_deque_.DataBegin()->offset << " length "
+        << interval_deque_.DataBegin()->slice.length();
+    interval_deque_.PopFront();
+  }
+}
+
+bool QuicStreamSendBuffer::IsStreamDataOutstanding(
+    QuicStreamOffset offset,
+    QuicByteCount data_length) const {
+  return data_length > 0 &&
+         !bytes_acked_.Contains(offset, offset + data_length);
+}
+
+size_t QuicStreamSendBuffer::size() const {
+  return interval_deque_.Size();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_send_buffer.h b/quiche/quic/core/quic_stream_send_buffer.h
new file mode 100644
index 0000000..c763c19
--- /dev/null
+++ b/quiche/quic/core/quic_stream_send_buffer.h
@@ -0,0 +1,173 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
+
+#include "absl/types/span.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_interval_deque.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSendBufferPeer;
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicDataWriter;
+
+// BufferedSlice comprises information of a piece of stream data stored in
+// contiguous memory space. Please note, BufferedSlice is constructed when
+// stream data is saved in send buffer and is removed when stream data is fully
+// acked. It is move-only.
+struct QUIC_EXPORT_PRIVATE BufferedSlice {
+  BufferedSlice(quiche::QuicheMemSlice mem_slice, QuicStreamOffset offset);
+  BufferedSlice(BufferedSlice&& other);
+  BufferedSlice& operator=(BufferedSlice&& other);
+
+  BufferedSlice(const BufferedSlice& other) = delete;
+  BufferedSlice& operator=(const BufferedSlice& other) = delete;
+  ~BufferedSlice();
+
+  // Return an interval representing the offset and length.
+  QuicInterval<std::size_t> interval() const;
+
+  // Stream data of this data slice.
+  quiche::QuicheMemSlice slice;
+  // Location of this data slice in the stream.
+  QuicStreamOffset offset;
+};
+
+struct QUIC_EXPORT_PRIVATE StreamPendingRetransmission {
+  constexpr StreamPendingRetransmission(QuicStreamOffset offset,
+                                        QuicByteCount length)
+      : offset(offset), length(length) {}
+
+  // Starting offset of this pending retransmission.
+  QuicStreamOffset offset;
+  // Length of this pending retransmission.
+  QuicByteCount length;
+
+  bool operator==(const StreamPendingRetransmission& other) const;
+};
+
+// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
+// are added to the tail of the list. Data slices are removed from the head of
+// the list when they get fully acked. Stream data can be retrieved and acked
+// across slice boundaries.
+class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
+ public:
+  explicit QuicStreamSendBuffer(quiche::QuicheBufferAllocator* allocator);
+  QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
+  QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
+  ~QuicStreamSendBuffer();
+
+  // Save |data| to send buffer.
+  void SaveStreamData(absl::string_view data);
+
+  // Save |slice| to send buffer.
+  void SaveMemSlice(quiche::QuicheMemSlice slice);
+
+  // Save all slices in |span| to send buffer. Return total bytes saved.
+  QuicByteCount SaveMemSliceSpan(absl::Span<quiche::QuicheMemSlice> span);
+
+  // Called when |bytes_consumed| bytes has been consumed by the stream.
+  void OnStreamDataConsumed(size_t bytes_consumed);
+
+  // Write |data_length| of data starts at |offset|.
+  bool WriteStreamData(QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer);
+
+  // Called when data [offset, offset + data_length) is acked or removed as
+  // stream is canceled. Removes fully acked data slice from send buffer. Set
+  // |newly_acked_length|. Returns false if trying to ack unsent data.
+  bool OnStreamDataAcked(QuicStreamOffset offset,
+                         QuicByteCount data_length,
+                         QuicByteCount* newly_acked_length);
+
+  // Called when data [offset, offset + data_length) is considered as lost.
+  void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
+
+  // Called when data [offset, offset + length) was retransmitted.
+  void OnStreamDataRetransmitted(QuicStreamOffset offset,
+                                 QuicByteCount data_length);
+
+  // Returns true if there is pending retransmissions.
+  bool HasPendingRetransmission() const;
+
+  // Returns next pending retransmissions.
+  StreamPendingRetransmission NextPendingRetransmission() const;
+
+  // Returns true if data [offset, offset + data_length) is outstanding and
+  // waiting to be acked. Returns false otherwise.
+  bool IsStreamDataOutstanding(QuicStreamOffset offset,
+                               QuicByteCount data_length) const;
+
+  // Number of data slices in send buffer.
+  size_t size() const;
+
+  QuicStreamOffset stream_offset() const { return stream_offset_; }
+
+  uint64_t stream_bytes_written() const { return stream_bytes_written_; }
+
+  uint64_t stream_bytes_outstanding() const {
+    return stream_bytes_outstanding_;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const {
+    return bytes_acked_;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const {
+    return pending_retransmissions_;
+  }
+
+ private:
+  friend class test::QuicStreamSendBufferPeer;
+  friend class test::QuicStreamPeer;
+
+  // Called when data within offset [start, end) gets acked. Frees fully
+  // acked buffered slices if any. Returns false if the corresponding data does
+  // not exist or has been acked.
+  bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
+
+  // Cleanup empty slices in order from buffered_slices_.
+  void CleanUpBufferedSlices();
+
+  // |current_end_offset_| stores the end offset of the current slice to ensure
+  // data isn't being written out of order when using the |interval_deque_|.
+  QuicStreamOffset current_end_offset_;
+  QuicIntervalDeque<BufferedSlice> interval_deque_;
+
+  // Offset of next inserted byte.
+  QuicStreamOffset stream_offset_;
+
+  quiche::QuicheBufferAllocator* allocator_;
+
+  // Bytes that have been consumed by the stream.
+  uint64_t stream_bytes_written_;
+
+  // Bytes that have been consumed and are waiting to be acked.
+  uint64_t stream_bytes_outstanding_;
+
+  // Offsets of data that has been acked.
+  QuicIntervalSet<QuicStreamOffset> bytes_acked_;
+
+  // Data considered as lost and needs to be retransmitted.
+  QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
+
+  // Index of slice which contains data waiting to be written for the first
+  // time. -1 if send buffer is empty or all data has been written.
+  int32_t write_index_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
diff --git a/quiche/quic/core/quic_stream_send_buffer_test.cc b/quiche/quic/core/quic_stream_send_buffer_test.cc
new file mode 100644
index 0000000..7abd791
--- /dev/null
+++ b/quiche/quic/core/quic_stream_send_buffer_test.cc
@@ -0,0 +1,345 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicStreamSendBufferTest : public QuicTest {
+ public:
+  QuicStreamSendBufferTest() : send_buffer_(&allocator_) {
+    EXPECT_EQ(0u, send_buffer_.size());
+    EXPECT_EQ(0u, send_buffer_.stream_bytes_written());
+    EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding());
+    // The stream offset should be 0 since nothing is written.
+    EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+
+    std::string data1 = absl::StrCat(
+        std::string(1536, 'a'), std::string(256, 'b'), std::string(256, 'c'));
+
+    quiche::QuicheBuffer buffer1(&allocator_, 1024);
+    memset(buffer1.data(), 'c', buffer1.size());
+    quiche::QuicheMemSlice slice1(std::move(buffer1));
+
+    quiche::QuicheBuffer buffer2(&allocator_, 768);
+    memset(buffer2.data(), 'd', buffer2.size());
+    quiche::QuicheMemSlice slice2(std::move(buffer2));
+
+    // `data` will be split into two BufferedSlices.
+    SetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size, 1024);
+    send_buffer_.SaveStreamData(data1);
+
+    send_buffer_.SaveMemSlice(std::move(slice1));
+    EXPECT_TRUE(slice1.empty());
+    send_buffer_.SaveMemSlice(std::move(slice2));
+    EXPECT_TRUE(slice2.empty());
+
+    EXPECT_EQ(4u, send_buffer_.size());
+    // At this point, `send_buffer_.interval_deque_` looks like this:
+    // BufferedSlice1: 'a' * 1024
+    // BufferedSlice2: 'a' * 512 + 'b' * 256 + 'c' * 256
+    // BufferedSlice3: 'c' * 1024
+    // BufferedSlice4: 'd' * 768
+  }
+
+  void WriteAllData() {
+    // Write all data.
+    char buf[4000];
+    QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
+    send_buffer_.WriteStreamData(0, 3840u, &writer);
+
+    send_buffer_.OnStreamDataConsumed(3840u);
+    EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
+    EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
+  }
+
+  quiche::SimpleBufferAllocator allocator_;
+  QuicStreamSendBuffer send_buffer_;
+};
+
+TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
+  char buf[4000];
+  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
+  std::string copy1(1024, 'a');
+  std::string copy2 =
+      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
+  std::string copy3(1024, 'c');
+  std::string copy4(768, 'd');
+
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 1024, &writer));
+  EXPECT_EQ(copy2, absl::string_view(buf + 1024, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer));
+  EXPECT_EQ(copy3, absl::string_view(buf + 2048, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer));
+  EXPECT_EQ(copy4, absl::string_view(buf + 3072, 768));
+
+  // Test data piece across boundries.
+  QuicDataWriter writer2(4000, buf, quiche::HOST_BYTE_ORDER);
+  std::string copy5 =
+      std::string(536, 'a') + std::string(256, 'b') + std::string(232, 'c');
+  ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2));
+  EXPECT_EQ(copy5, absl::string_view(buf, 1024));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2));
+  std::string copy6 = std::string(572, 'c') + std::string(452, 'd');
+  EXPECT_EQ(copy6, absl::string_view(buf + 1024, 1024));
+
+  // Invalid data copy.
+  QuicDataWriter writer3(4000, buf, quiche::HOST_BYTE_ORDER);
+  EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
+  EXPECT_QUIC_BUG(send_buffer_.WriteStreamData(0, 4000, &writer3),
+                  "Writer fails to write.");
+
+  send_buffer_.OnStreamDataConsumed(3840);
+  EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
+  EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
+}
+
+// Regression test for b/143491027.
+TEST_F(QuicStreamSendBufferTest,
+       WriteStreamDataContainsBothRetransmissionAndNewData) {
+  std::string copy1(1024, 'a');
+  std::string copy2 =
+      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
+  std::string copy3 = std::string(1024, 'c') + std::string(100, 'd');
+  char buf[6000];
+  QuicDataWriter writer(6000, buf, quiche::HOST_BYTE_ORDER);
+  // Write more than one slice.
+  EXPECT_EQ(0, QuicStreamSendBufferPeer::write_index(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
+  EXPECT_EQ(1, QuicStreamSendBufferPeer::write_index(&send_buffer_));
+
+  // Retransmit the first frame and also send new data.
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 2048, &writer));
+  EXPECT_EQ(copy1 + copy2, absl::string_view(buf + 1024, 2048));
+
+  // Write new data.
+  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 50, &writer));
+  EXPECT_EQ(std::string(50, 'c'), absl::string_view(buf + 1024 + 2048, 50));
+  EXPECT_EQ(3072u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1124, &writer));
+  EXPECT_EQ(copy3, absl::string_view(buf + 1024 + 2048 + 50, 1124));
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+}
+
+TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
+  WriteAllData();
+
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1024, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2048, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+
+  // Send buffer is cleaned up in order.
+  EXPECT_EQ(1u, send_buffer_.size());
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3072, 768, &newly_acked_length));
+  EXPECT_EQ(768u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+}
+
+TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
+  WriteAllData();
+
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2024, 576, &newly_acked_length));
+  EXPECT_EQ(576u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
+  EXPECT_EQ(1000u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1000, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  // Send buffer is cleaned up in order.
+  EXPECT_EQ(2u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2600, 1024, &newly_acked_length));
+  EXPECT_EQ(1024u, newly_acked_length);
+  EXPECT_EQ(1u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3624, 216, &newly_acked_length));
+  EXPECT_EQ(216u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+}
+
+TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
+  WriteAllData();
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(100, 1500, &newly_acked_length));
+  EXPECT_EQ(1500u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 500, &newly_acked_length));
+  EXPECT_EQ(500u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 2600, &newly_acked_length));
+  EXPECT_EQ(600u, newly_acked_length);
+  // Send buffer is cleaned up in order.
+  EXPECT_EQ(2u, send_buffer_.size());
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2200, 1640, &newly_acked_length));
+  EXPECT_EQ(1240u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+
+  EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
+}
+
+TEST_F(QuicStreamSendBufferTest, AckStreamDataOutOfOrder) {
+  WriteAllData();
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 1000, &newly_acked_length));
+  EXPECT_EQ(1000u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1200, 1000, &newly_acked_length));
+  EXPECT_EQ(700u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+  // Slice 2 gets fully acked.
+  EXPECT_EQ(2816u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 1840, &newly_acked_length));
+  EXPECT_EQ(1640u, newly_acked_length);
+  EXPECT_EQ(4u, send_buffer_.size());
+  // Slices 3 and 4 get fully acked.
+  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
+  EXPECT_EQ(500u, newly_acked_length);
+  EXPECT_EQ(0u, send_buffer_.size());
+  EXPECT_EQ(0u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+}
+
+TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
+  WriteAllData();
+  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
+  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
+  // Lost data [0, 1200).
+  send_buffer_.OnStreamDataLost(0, 1200);
+  // Lost data [1500, 2000).
+  send_buffer_.OnStreamDataLost(1500, 500);
+  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+
+  EXPECT_EQ(StreamPendingRetransmission(0, 1200),
+            send_buffer_.NextPendingRetransmission());
+  // Retransmit data [0, 500).
+  send_buffer_.OnStreamDataRetransmitted(0, 500);
+  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 500));
+  EXPECT_EQ(StreamPendingRetransmission(500, 700),
+            send_buffer_.NextPendingRetransmission());
+  // Ack data [500, 1200).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 700, &newly_acked_length));
+  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(500, 700));
+  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+  EXPECT_EQ(StreamPendingRetransmission(1500, 500),
+            send_buffer_.NextPendingRetransmission());
+  // Retransmit data [1500, 2000).
+  send_buffer_.OnStreamDataRetransmitted(1500, 500);
+  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
+
+  // Lost [200, 800).
+  send_buffer_.OnStreamDataLost(200, 600);
+  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+  // Verify [200, 500) is considered as lost, as [500, 800) has been acked.
+  EXPECT_EQ(StreamPendingRetransmission(200, 300),
+            send_buffer_.NextPendingRetransmission());
+
+  // Verify 0 length data is not outstanding.
+  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(100, 0));
+  // Verify partially acked data is outstanding.
+  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(400, 800));
+}
+
+TEST_F(QuicStreamSendBufferTest, EndOffset) {
+  char buf[4000];
+  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
+
+  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+  // Last offset we've seen is 1024
+  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+
+  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 512, &writer));
+  // Last offset is now 2048 as that's the end of the next slice.
+  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  send_buffer_.OnStreamDataConsumed(1024);
+
+  // If data in 1st slice gets ACK'ed, it shouldn't change the indexed slice
+  QuicByteCount newly_acked_length;
+  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
+  // Last offset is still 2048.
+  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+
+  ASSERT_TRUE(
+      send_buffer_.WriteStreamData(1024 + 512, 3840 - 1024 - 512, &writer));
+
+  // Last offset is end offset of last slice.
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+  quiche::QuicheBuffer buffer(&allocator_, 60);
+  memset(buffer.data(), 'e', buffer.size());
+  quiche::QuicheMemSlice slice(std::move(buffer));
+  send_buffer_.SaveMemSlice(std::move(slice));
+
+  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
+}
+
+TEST_F(QuicStreamSendBufferTest, SaveMemSliceSpan) {
+  quiche::SimpleBufferAllocator allocator;
+  QuicStreamSendBuffer send_buffer(&allocator);
+
+  std::string data(1024, 'a');
+  std::vector<quiche::QuicheMemSlice> buffers;
+  for (size_t i = 0; i < 10; ++i) {
+    buffers.push_back(MemSliceFromString(data));
+  }
+
+  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
+  EXPECT_EQ(10u, send_buffer.size());
+}
+
+TEST_F(QuicStreamSendBufferTest, SaveEmptyMemSliceSpan) {
+  quiche::SimpleBufferAllocator allocator;
+  QuicStreamSendBuffer send_buffer(&allocator);
+
+  std::string data(1024, 'a');
+  std::vector<quiche::QuicheMemSlice> buffers;
+  for (size_t i = 0; i < 10; ++i) {
+    buffers.push_back(MemSliceFromString(data));
+  }
+
+  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(absl::MakeSpan(buffers)));
+  // Verify the empty slice does not get saved.
+  EXPECT_EQ(10u, send_buffer.size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer.cc b/quiche/quic/core/quic_stream_sequencer.cc
new file mode 100644
index 0000000..61eec53
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer.cc
@@ -0,0 +1,309 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream_sequencer.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+QuicStreamSequencer::QuicStreamSequencer(StreamInterface* quic_stream)
+    : stream_(quic_stream),
+      buffered_frames_(kStreamReceiveWindowLimit),
+      highest_offset_(0),
+      close_offset_(std::numeric_limits<QuicStreamOffset>::max()),
+      blocked_(false),
+      num_frames_received_(0),
+      num_duplicate_frames_received_(0),
+      ignore_read_data_(false),
+      level_triggered_(false) {}
+
+QuicStreamSequencer::~QuicStreamSequencer() {
+  if (stream_ == nullptr) {
+    QUIC_BUG(quic_bug_10858_1) << "Double free'ing QuicStreamSequencer at "
+                               << this << ". " << QuicStackTrace();
+  }
+  stream_ = nullptr;
+}
+
+void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
+  QUICHE_DCHECK_LE(frame.offset + frame.data_length, close_offset_);
+  ++num_frames_received_;
+  const QuicStreamOffset byte_offset = frame.offset;
+  const size_t data_len = frame.data_length;
+
+  if (frame.fin &&
+      (!CloseStreamAtOffset(frame.offset + data_len) || data_len == 0)) {
+    return;
+  }
+  if (stream_->version().HasIetfQuicFrames() && data_len == 0) {
+    QUICHE_DCHECK(!frame.fin);
+    // Ignore empty frame with no fin.
+    return;
+  }
+  OnFrameData(byte_offset, data_len, frame.data_buffer);
+}
+
+void QuicStreamSequencer::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  ++num_frames_received_;
+  if (frame.data_length == 0) {
+    // Ignore empty crypto frame.
+    return;
+  }
+  OnFrameData(frame.offset, frame.data_length, frame.data_buffer);
+}
+
+void QuicStreamSequencer::OnFrameData(QuicStreamOffset byte_offset,
+                                      size_t data_len,
+                                      const char* data_buffer) {
+  highest_offset_ = std::max(highest_offset_, byte_offset + data_len);
+  const size_t previous_readable_bytes = buffered_frames_.ReadableBytes();
+  size_t bytes_written;
+  std::string error_details;
+  QuicErrorCode result = buffered_frames_.OnStreamData(
+      byte_offset, absl::string_view(data_buffer, data_len), &bytes_written,
+      &error_details);
+  if (result != QUIC_NO_ERROR) {
+    std::string details =
+        absl::StrCat("Stream ", stream_->id(), ": ",
+                     QuicErrorCodeToString(result), ": ", error_details);
+    QUIC_LOG_FIRST_N(WARNING, 50) << QuicErrorCodeToString(result);
+    QUIC_LOG_FIRST_N(WARNING, 50) << details;
+    stream_->OnUnrecoverableError(result, details);
+    return;
+  }
+
+  if (bytes_written == 0) {
+    ++num_duplicate_frames_received_;
+    // Silently ignore duplicates.
+    return;
+  }
+
+  if (blocked_) {
+    return;
+  }
+
+  if (level_triggered_) {
+    if (buffered_frames_.ReadableBytes() > previous_readable_bytes) {
+      // Readable bytes has changed, let stream decide if to inform application
+      // or not.
+      if (ignore_read_data_) {
+        FlushBufferedFrames();
+      } else {
+        stream_->OnDataAvailable();
+      }
+    }
+    return;
+  }
+  const bool stream_unblocked =
+      previous_readable_bytes == 0 && buffered_frames_.ReadableBytes() > 0;
+  if (stream_unblocked) {
+    if (ignore_read_data_) {
+      FlushBufferedFrames();
+    } else {
+      stream_->OnDataAvailable();
+    }
+  }
+}
+
+bool QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
+  const QuicStreamOffset kMaxOffset =
+      std::numeric_limits<QuicStreamOffset>::max();
+
+  // If there is a scheduled close, the new offset should match it.
+  if (close_offset_ != kMaxOffset && offset != close_offset_) {
+    stream_->OnUnrecoverableError(
+        QUIC_STREAM_SEQUENCER_INVALID_STATE,
+        absl::StrCat(
+            "Stream ", stream_->id(), " received new final offset: ", offset,
+            ", which is different from close offset: ", close_offset_));
+    return false;
+  }
+
+  // The final offset should be no less than the highest offset that is
+  // received.
+  if (offset < highest_offset_) {
+    stream_->OnUnrecoverableError(
+        QUIC_STREAM_SEQUENCER_INVALID_STATE,
+        absl::StrCat(
+            "Stream ", stream_->id(), " received fin with offset: ", offset,
+            ", which reduces current highest offset: ", highest_offset_));
+    return false;
+  }
+
+  close_offset_ = offset;
+
+  MaybeCloseStream();
+  return true;
+}
+
+void QuicStreamSequencer::MaybeCloseStream() {
+  if (blocked_ || !IsClosed()) {
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Passing up termination, as we've processed "
+                << buffered_frames_.BytesConsumed() << " of " << close_offset_
+                << " bytes.";
+  // This will cause the stream to consume the FIN.
+  // Technically it's an error if |num_bytes_consumed| isn't exactly
+  // equal to |close_offset|, but error handling seems silly at this point.
+  if (ignore_read_data_) {
+    // The sequencer is discarding stream data and must notify the stream on
+    // receipt of a FIN because the consumer won't.
+    stream_->OnFinRead();
+  } else {
+    stream_->OnDataAvailable();
+  }
+  buffered_frames_.Clear();
+}
+
+int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
+  QUICHE_DCHECK(!blocked_);
+  return buffered_frames_.GetReadableRegions(iov, iov_len);
+}
+
+bool QuicStreamSequencer::GetReadableRegion(iovec* iov) const {
+  QUICHE_DCHECK(!blocked_);
+  return buffered_frames_.GetReadableRegion(iov);
+}
+
+bool QuicStreamSequencer::PeekRegion(QuicStreamOffset offset,
+                                     iovec* iov) const {
+  QUICHE_DCHECK(!blocked_);
+  return buffered_frames_.PeekRegion(offset, iov);
+}
+
+void QuicStreamSequencer::Read(std::string* buffer) {
+  QUICHE_DCHECK(!blocked_);
+  buffer->resize(buffer->size() + ReadableBytes());
+  iovec iov;
+  iov.iov_len = ReadableBytes();
+  iov.iov_base = &(*buffer)[buffer->size() - iov.iov_len];
+  Readv(&iov, 1);
+}
+
+size_t QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
+  QUICHE_DCHECK(!blocked_);
+  std::string error_details;
+  size_t bytes_read;
+  QuicErrorCode read_error =
+      buffered_frames_.Readv(iov, iov_len, &bytes_read, &error_details);
+  if (read_error != QUIC_NO_ERROR) {
+    std::string details =
+        absl::StrCat("Stream ", stream_->id(), ": ", error_details);
+    stream_->OnUnrecoverableError(read_error, details);
+    return bytes_read;
+  }
+
+  stream_->AddBytesConsumed(bytes_read);
+  return bytes_read;
+}
+
+bool QuicStreamSequencer::HasBytesToRead() const {
+  return buffered_frames_.HasBytesToRead();
+}
+
+size_t QuicStreamSequencer::ReadableBytes() const {
+  return buffered_frames_.ReadableBytes();
+}
+
+bool QuicStreamSequencer::IsClosed() const {
+  return buffered_frames_.BytesConsumed() >= close_offset_;
+}
+
+void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
+  QUICHE_DCHECK(!blocked_);
+  bool result = buffered_frames_.MarkConsumed(num_bytes_consumed);
+  if (!result) {
+    QUIC_BUG(quic_bug_10858_2)
+        << "Invalid argument to MarkConsumed."
+        << " expect to consume: " << num_bytes_consumed
+        << ", but not enough bytes available. " << DebugString();
+    stream_->ResetWithError(
+        QuicResetStreamError::FromInternal(QUIC_ERROR_PROCESSING_STREAM));
+    return;
+  }
+  stream_->AddBytesConsumed(num_bytes_consumed);
+}
+
+void QuicStreamSequencer::SetBlockedUntilFlush() {
+  blocked_ = true;
+}
+
+void QuicStreamSequencer::SetUnblocked() {
+  blocked_ = false;
+  if (IsClosed() || HasBytesToRead()) {
+    stream_->OnDataAvailable();
+  }
+}
+
+void QuicStreamSequencer::StopReading() {
+  if (ignore_read_data_) {
+    return;
+  }
+  ignore_read_data_ = true;
+  FlushBufferedFrames();
+}
+
+void QuicStreamSequencer::ReleaseBuffer() {
+  buffered_frames_.ReleaseWholeBuffer();
+}
+
+void QuicStreamSequencer::ReleaseBufferIfEmpty() {
+  if (buffered_frames_.Empty()) {
+    buffered_frames_.ReleaseWholeBuffer();
+  }
+}
+
+void QuicStreamSequencer::FlushBufferedFrames() {
+  QUICHE_DCHECK(ignore_read_data_);
+  size_t bytes_flushed = buffered_frames_.FlushBufferedFrames();
+  QUIC_DVLOG(1) << "Flushing buffered data at offset "
+                << buffered_frames_.BytesConsumed() << " length "
+                << bytes_flushed << " for stream " << stream_->id();
+  stream_->AddBytesConsumed(bytes_flushed);
+  MaybeCloseStream();
+}
+
+size_t QuicStreamSequencer::NumBytesBuffered() const {
+  return buffered_frames_.BytesBuffered();
+}
+
+QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
+  return buffered_frames_.BytesConsumed();
+}
+
+const std::string QuicStreamSequencer::DebugString() const {
+  // clang-format off
+  return absl::StrCat("QuicStreamSequencer:",
+                "\n  bytes buffered: ", NumBytesBuffered(),
+                "\n  bytes consumed: ", NumBytesConsumed(),
+                "\n  has bytes to read: ", HasBytesToRead() ? "true" : "false",
+                "\n  frames received: ", num_frames_received(),
+                "\n  close offset bytes: ", close_offset_,
+                "\n  is closed: ", IsClosed() ? "true" : "false");
+  // clang-format on
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer.h b/quiche/quic/core/quic_stream_sequencer.h
new file mode 100644
index 0000000..0e8d2d2
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer.h
@@ -0,0 +1,217 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
+
+#include <cstddef>
+#include <map>
+#include <string>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSequencerPeer;
+}  // namespace test
+
+// Buffers frames until we have something which can be passed
+// up to the next layer.
+class QUIC_EXPORT_PRIVATE QuicStreamSequencer {
+ public:
+  // Interface that thie Sequencer uses to communicate with the Stream.
+  class QUIC_EXPORT_PRIVATE StreamInterface {
+   public:
+    virtual ~StreamInterface() = default;
+
+    // Called when new data is available to be read from the sequencer.
+    virtual void OnDataAvailable() = 0;
+    // Called when the end of the stream has been read.
+    virtual void OnFinRead() = 0;
+    // Called when bytes have been consumed from the sequencer.
+    virtual void AddBytesConsumed(QuicByteCount bytes) = 0;
+    // Called when an error has occurred which should result in the stream
+    // being reset.
+    virtual void ResetWithError(QuicResetStreamError error) = 0;
+    // Called when an error has occurred which should result in the connection
+    // being closed.
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      const std::string& details) = 0;
+    // Called when an error has occurred which should result in the connection
+    // being closed, specifying the wire error code |ietf_error| explicitly.
+    virtual void OnUnrecoverableError(QuicErrorCode error,
+                                      QuicIetfTransportErrorCodes ietf_error,
+                                      const std::string& details) = 0;
+    // Returns the stream id of this stream.
+    virtual QuicStreamId id() const = 0;
+
+    // Returns the QUIC version being used by this stream.
+    virtual ParsedQuicVersion version() const = 0;
+  };
+
+  explicit QuicStreamSequencer(StreamInterface* quic_stream);
+  QuicStreamSequencer(const QuicStreamSequencer&) = delete;
+  QuicStreamSequencer(QuicStreamSequencer&&) = default;
+  QuicStreamSequencer& operator=(const QuicStreamSequencer&) = delete;
+  QuicStreamSequencer& operator=(QuicStreamSequencer&&) = default;
+  virtual ~QuicStreamSequencer();
+
+  // If the frame is the next one we need in order to process in-order data,
+  // ProcessData will be immediately called on the stream until all buffered
+  // data is processed or the stream fails to consume data.  Any unconsumed
+  // data will be buffered. If the frame is not the next in line, it will be
+  // buffered.
+  void OnStreamFrame(const QuicStreamFrame& frame);
+
+  // If the frame is the next one we need in order to process in-order data,
+  // ProcessData will be immediately called on the crypto stream until all
+  // buffered data is processed or the crypto stream fails to consume data. Any
+  // unconsumed data will be buffered. If the frame is not the next in line, it
+  // will be buffered.
+  void OnCryptoFrame(const QuicCryptoFrame& frame);
+
+  // Once data is buffered, it's up to the stream to read it when the stream
+  // can handle more data.  The following three functions make that possible.
+
+  // Fills in up to iov_len iovecs with the next readable regions.  Returns the
+  // number of iovs used.  Non-destructive of the underlying data.
+  int GetReadableRegions(iovec* iov, size_t iov_len) const;
+
+  // Fills in one iovec with the next readable region.  Returns false if there
+  // is no readable region available.
+  bool GetReadableRegion(iovec* iov) const;
+
+  // Fills in one iovec with the region starting at |offset| and returns true.
+  // Returns false if no readable region is available, either because data has
+  // not been received yet or has already been consumed.
+  bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
+
+  // Copies the data into the iov_len buffers provided.  Returns the number of
+  // bytes read.  Any buffered data no longer in use will be released.
+  // TODO(rch): remove this method and instead implement it as a helper method
+  // based on GetReadableRegions and MarkConsumed.
+  size_t Readv(const struct iovec* iov, size_t iov_len);
+
+  // Consumes |num_bytes| data.  Used in conjunction with |GetReadableRegions|
+  // to do zero-copy reads.
+  void MarkConsumed(size_t num_bytes);
+
+  // Appends all of the readable data to |buffer| and marks all of the appended
+  // data as consumed.
+  void Read(std::string* buffer);
+
+  // Returns true if the sequncer has bytes available for reading.
+  bool HasBytesToRead() const;
+
+  // Number of bytes available to read.
+  size_t ReadableBytes() const;
+
+  // Returns true if the sequencer has delivered the fin.
+  bool IsClosed() const;
+
+  // Calls |OnDataAvailable| on |stream_| if there is buffered data that can
+  // be processed, and causes |OnDataAvailable| to be called as new data
+  // arrives.
+  void SetUnblocked();
+
+  // Blocks processing of frames until |SetUnblocked| is called.
+  void SetBlockedUntilFlush();
+
+  // Sets the sequencer to discard all incoming data itself and not call
+  // |stream_->OnDataAvailable()|.  |stream_->OnFinRead()| will be called
+  // automatically when the FIN is consumed (which may be immediately).
+  void StopReading();
+
+  // Free the memory of underlying buffer.
+  void ReleaseBuffer();
+
+  // Free the memory of underlying buffer when no bytes remain in it.
+  void ReleaseBufferIfEmpty();
+
+  // Number of bytes in the buffer right now.
+  size_t NumBytesBuffered() const;
+
+  // Number of bytes has been consumed.
+  QuicStreamOffset NumBytesConsumed() const;
+
+  QuicStreamOffset close_offset() const { return close_offset_; }
+
+  int num_frames_received() const { return num_frames_received_; }
+
+  int num_duplicate_frames_received() const {
+    return num_duplicate_frames_received_;
+  }
+
+  bool ignore_read_data() const { return ignore_read_data_; }
+
+  void set_level_triggered(bool level_triggered) {
+    level_triggered_ = level_triggered;
+  }
+
+  bool level_triggered() const { return level_triggered_; }
+
+  void set_stream(StreamInterface* stream) { stream_ = stream; }
+
+  // Returns string describing internal state.
+  const std::string DebugString() const;
+
+ private:
+  friend class test::QuicStreamSequencerPeer;
+
+  // Deletes and records as consumed any buffered data that is now in-sequence.
+  // (To be called only after StopReading has been called.)
+  void FlushBufferedFrames();
+
+  // Wait until we've seen 'offset' bytes, and then terminate the stream.
+  // Returns true if |stream_| is still available to receive data, and false if
+  // |stream_| is reset.
+  bool CloseStreamAtOffset(QuicStreamOffset offset);
+
+  // If we've received a FIN and have processed all remaining data, then inform
+  // the stream of FIN, and clear buffers.
+  void MaybeCloseStream();
+
+  // Shared implementation between OnStreamFrame and OnCryptoFrame.
+  void OnFrameData(QuicStreamOffset byte_offset,
+                   size_t data_len,
+                   const char* data_buffer);
+
+  // The stream which owns this sequencer.
+  StreamInterface* stream_;
+
+  // Stores received data in offset order.
+  QuicStreamSequencerBuffer buffered_frames_;
+
+  // The highest offset that is received so far.
+  QuicStreamOffset highest_offset_;
+
+  // The offset, if any, we got a stream termination for.  When this many bytes
+  // have been processed, the sequencer will be closed.
+  QuicStreamOffset close_offset_;
+
+  // If true, the sequencer is blocked from passing data to the stream and will
+  // buffer all new incoming data until FlushBufferedFrames is called.
+  bool blocked_;
+
+  // Count of the number of frames received.
+  int num_frames_received_;
+
+  // Count of the number of duplicate frames received.
+  int num_duplicate_frames_received_;
+
+  // If true, all incoming data will be discarded.
+  bool ignore_read_data_;
+
+  // If false, only call OnDataAvailable() when it becomes newly unblocked.
+  // Otherwise, call OnDataAvailable() when number of readable bytes changes.
+  bool level_triggered_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_H_
diff --git a/quiche/quic/core/quic_stream_sequencer_buffer.cc b/quiche/quic/core/quic_stream_sequencer_buffer.cc
new file mode 100644
index 0000000..9f7e0c9
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_buffer.cc
@@ -0,0 +1,546 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace {
+
+size_t CalculateBlockCount(size_t max_capacity_bytes) {
+  return (max_capacity_bytes + QuicStreamSequencerBuffer::kBlockSizeBytes - 1) /
+         QuicStreamSequencerBuffer::kBlockSizeBytes;
+}
+
+// Upper limit of how many gaps allowed in buffer, which ensures a reasonable
+// number of iterations needed to find the right gap to fill when a frame
+// arrives.
+const size_t kMaxNumDataIntervalsAllowed = 2 * kMaxPacketGap;
+
+// Number of blocks allocated initially.
+constexpr size_t kInitialBlockCount = 8u;
+
+// How fast block pointers container grow in size.
+// Choose 4 to reduce the amount of reallocation.
+constexpr int kBlocksGrowthFactor = 4;
+
+}  // namespace
+
+QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes)
+    : max_buffer_capacity_bytes_(max_capacity_bytes),
+      max_blocks_count_(CalculateBlockCount(max_capacity_bytes)),
+      current_blocks_count_(0u),
+      total_bytes_read_(0),
+      blocks_(nullptr) {
+  QUICHE_DCHECK_GE(max_blocks_count_, kInitialBlockCount);
+  Clear();
+}
+
+QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() {
+  Clear();
+}
+
+void QuicStreamSequencerBuffer::Clear() {
+  if (blocks_ != nullptr) {
+    for (size_t i = 0; i < current_blocks_count_; ++i) {
+      if (blocks_[i] != nullptr) {
+        RetireBlock(i);
+      }
+    }
+  }
+  num_bytes_buffered_ = 0;
+  bytes_received_.Clear();
+  bytes_received_.Add(0, total_bytes_read_);
+}
+
+bool QuicStreamSequencerBuffer::RetireBlock(size_t index) {
+  if (blocks_[index] == nullptr) {
+    QUIC_BUG(quic_bug_10610_1) << "Try to retire block twice";
+    return false;
+  }
+  delete blocks_[index];
+  blocks_[index] = nullptr;
+  QUIC_DVLOG(1) << "Retired block with index: " << index;
+  return true;
+}
+
+void QuicStreamSequencerBuffer::MaybeAddMoreBlocks(
+    QuicStreamOffset next_expected_byte) {
+  if (current_blocks_count_ == max_blocks_count_) {
+    return;
+  }
+  QuicStreamOffset last_byte = next_expected_byte - 1;
+  size_t num_of_blocks_needed;
+  // As long as last_byte does not wrap around, its index plus one blocks are
+  // needed. Otherwise, block_count_ blocks are needed.
+  if (last_byte < max_buffer_capacity_bytes_) {
+    num_of_blocks_needed =
+        std::max(GetBlockIndex(last_byte) + 1, kInitialBlockCount);
+  } else {
+    num_of_blocks_needed = max_blocks_count_;
+  }
+  if (current_blocks_count_ >= num_of_blocks_needed) {
+    return;
+  }
+  size_t new_block_count = kBlocksGrowthFactor * current_blocks_count_;
+  new_block_count = std::min(std::max(new_block_count, num_of_blocks_needed),
+                             max_blocks_count_);
+  auto new_blocks = std::make_unique<BufferBlock*[]>(new_block_count);
+  if (blocks_ != nullptr) {
+    memcpy(new_blocks.get(), blocks_.get(),
+           current_blocks_count_ * sizeof(BufferBlock*));
+  }
+  blocks_ = std::move(new_blocks);
+  current_blocks_count_ = new_block_count;
+}
+
+QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
+    QuicStreamOffset starting_offset,
+    absl::string_view data,
+    size_t* const bytes_buffered,
+    std::string* error_details) {
+  *bytes_buffered = 0;
+  size_t size = data.size();
+  if (size == 0) {
+    *error_details = "Received empty stream frame without FIN.";
+    return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
+  }
+  // Write beyond the current range this buffer is covering.
+  if (starting_offset + size > total_bytes_read_ + max_buffer_capacity_bytes_ ||
+      starting_offset + size < starting_offset) {
+    *error_details = "Received data beyond available range.";
+    return QUIC_INTERNAL_ERROR;
+  }
+
+  if (bytes_received_.Empty() ||
+      starting_offset >= bytes_received_.rbegin()->max() ||
+      bytes_received_.IsDisjoint(QuicInterval<QuicStreamOffset>(
+          starting_offset, starting_offset + size))) {
+    // Optimization for the typical case, when all data is newly received.
+    bytes_received_.AddOptimizedForAppend(starting_offset,
+                                          starting_offset + size);
+    if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
+      // This frame is going to create more intervals than allowed. Stop
+      // processing.
+      *error_details = "Too many data intervals received for this stream.";
+      return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
+    }
+    MaybeAddMoreBlocks(starting_offset + size);
+
+    size_t bytes_copy = 0;
+    if (!CopyStreamData(starting_offset, data, &bytes_copy, error_details)) {
+      return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+    }
+    *bytes_buffered += bytes_copy;
+    num_bytes_buffered_ += *bytes_buffered;
+    return QUIC_NO_ERROR;
+  }
+  // Slow path, received data overlaps with received data.
+  QuicIntervalSet<QuicStreamOffset> newly_received(starting_offset,
+                                                   starting_offset + size);
+  newly_received.Difference(bytes_received_);
+  if (newly_received.Empty()) {
+    return QUIC_NO_ERROR;
+  }
+  bytes_received_.Add(starting_offset, starting_offset + size);
+  if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
+    // This frame is going to create more intervals than allowed. Stop
+    // processing.
+    *error_details = "Too many data intervals received for this stream.";
+    return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
+  }
+  MaybeAddMoreBlocks(starting_offset + size);
+  for (const auto& interval : newly_received) {
+    const QuicStreamOffset copy_offset = interval.min();
+    const QuicByteCount copy_length = interval.max() - interval.min();
+    size_t bytes_copy = 0;
+    if (!CopyStreamData(copy_offset,
+                        data.substr(copy_offset - starting_offset, copy_length),
+                        &bytes_copy, error_details)) {
+      return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+    }
+    *bytes_buffered += bytes_copy;
+  }
+  num_bytes_buffered_ += *bytes_buffered;
+  return QUIC_NO_ERROR;
+}
+
+bool QuicStreamSequencerBuffer::CopyStreamData(QuicStreamOffset offset,
+                                               absl::string_view data,
+                                               size_t* bytes_copy,
+                                               std::string* error_details) {
+  *bytes_copy = 0;
+  size_t source_remaining = data.size();
+  if (source_remaining == 0) {
+    return true;
+  }
+  const char* source = data.data();
+  // Write data block by block. If corresponding block has not created yet,
+  // create it first.
+  // Stop when all data are written or reaches the logical end of the buffer.
+  while (source_remaining > 0) {
+    const size_t write_block_num = GetBlockIndex(offset);
+    const size_t write_block_offset = GetInBlockOffset(offset);
+    size_t current_blocks_count = current_blocks_count_;
+    QUICHE_DCHECK_GT(current_blocks_count, write_block_num);
+
+    size_t block_capacity = GetBlockCapacity(write_block_num);
+    size_t bytes_avail = block_capacity - write_block_offset;
+
+    // If this write meets the upper boundary of the buffer,
+    // reduce the available free bytes.
+    if (offset + bytes_avail > total_bytes_read_ + max_buffer_capacity_bytes_) {
+      bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset;
+    }
+
+    if (write_block_num >= current_blocks_count) {
+      *error_details = absl::StrCat(
+          "QuicStreamSequencerBuffer error: OnStreamData() exceed array bounds."
+          "write offset = ",
+          offset, " write_block_num = ", write_block_num,
+          " current_blocks_count_ = ", current_blocks_count);
+      return false;
+    }
+    if (blocks_ == nullptr) {
+      *error_details =
+          "QuicStreamSequencerBuffer error: OnStreamData() blocks_ is null";
+      return false;
+    }
+    if (blocks_[write_block_num] == nullptr) {
+      // TODO(danzh): Investigate if using a freelist would improve performance.
+      // Same as RetireBlock().
+      blocks_[write_block_num] = new BufferBlock();
+    }
+
+    const size_t bytes_to_copy =
+        std::min<size_t>(bytes_avail, source_remaining);
+    char* dest = blocks_[write_block_num]->buffer + write_block_offset;
+    QUIC_DVLOG(1) << "Write at offset: " << offset
+                  << " length: " << bytes_to_copy;
+
+    if (dest == nullptr || source == nullptr) {
+      *error_details = absl::StrCat(
+          "QuicStreamSequencerBuffer error: OnStreamData()"
+          " dest == nullptr: ",
+          (dest == nullptr), " source == nullptr: ", (source == nullptr),
+          " Writing at offset ", offset,
+          " Received frames: ", ReceivedFramesDebugString(),
+          " total_bytes_read_ = ", total_bytes_read_);
+      return false;
+    }
+    memcpy(dest, source, bytes_to_copy);
+    source += bytes_to_copy;
+    source_remaining -= bytes_to_copy;
+    offset += bytes_to_copy;
+    *bytes_copy += bytes_to_copy;
+  }
+  return true;
+}
+
+QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov,
+                                               size_t dest_count,
+                                               size_t* bytes_read,
+                                               std::string* error_details) {
+  *bytes_read = 0;
+  for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
+    char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
+    QUICHE_DCHECK(dest != nullptr);
+    size_t dest_remaining = dest_iov[i].iov_len;
+    while (dest_remaining > 0 && ReadableBytes() > 0) {
+      size_t block_idx = NextBlockToRead();
+      size_t start_offset_in_block = ReadOffset();
+      size_t block_capacity = GetBlockCapacity(block_idx);
+      size_t bytes_available_in_block = std::min<size_t>(
+          ReadableBytes(), block_capacity - start_offset_in_block);
+      size_t bytes_to_copy =
+          std::min<size_t>(bytes_available_in_block, dest_remaining);
+      QUICHE_DCHECK_GT(bytes_to_copy, 0u);
+      if (blocks_[block_idx] == nullptr || dest == nullptr) {
+        *error_details = absl::StrCat(
+            "QuicStreamSequencerBuffer error:"
+            " Readv() dest == nullptr: ",
+            (dest == nullptr), " blocks_[", block_idx,
+            "] == nullptr: ", (blocks_[block_idx] == nullptr),
+            " Received frames: ", ReceivedFramesDebugString(),
+            " total_bytes_read_ = ", total_bytes_read_);
+        return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+      }
+      memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
+             bytes_to_copy);
+      dest += bytes_to_copy;
+      dest_remaining -= bytes_to_copy;
+      num_bytes_buffered_ -= bytes_to_copy;
+      total_bytes_read_ += bytes_to_copy;
+      *bytes_read += bytes_to_copy;
+
+      // Retire the block if all the data is read out and no other data is
+      // stored in this block.
+      // In case of failing to retire a block which is ready to retire, return
+      // immediately.
+      if (bytes_to_copy == bytes_available_in_block) {
+        bool retire_successfully = RetireBlockIfEmpty(block_idx);
+        if (!retire_successfully) {
+          *error_details = absl::StrCat(
+              "QuicStreamSequencerBuffer error: fail to retire block ",
+              block_idx,
+              " as the block is already released, total_bytes_read_ = ",
+              total_bytes_read_,
+              " Received frames: ", ReceivedFramesDebugString());
+          return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+        }
+      }
+    }
+  }
+
+  return QUIC_NO_ERROR;
+}
+
+int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
+                                                  int iov_len) const {
+  QUICHE_DCHECK(iov != nullptr);
+  QUICHE_DCHECK_GT(iov_len, 0);
+
+  if (ReadableBytes() == 0) {
+    iov[0].iov_base = nullptr;
+    iov[0].iov_len = 0;
+    return 0;
+  }
+
+  size_t start_block_idx = NextBlockToRead();
+  QuicStreamOffset readable_offset_end = FirstMissingByte() - 1;
+  QUICHE_DCHECK_GE(readable_offset_end + 1, total_bytes_read_);
+  size_t end_block_offset = GetInBlockOffset(readable_offset_end);
+  size_t end_block_idx = GetBlockIndex(readable_offset_end);
+
+  // If readable region is within one block, deal with it seperately.
+  if (start_block_idx == end_block_idx && ReadOffset() <= end_block_offset) {
+    iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+    iov[0].iov_len = ReadableBytes();
+    QUIC_DVLOG(1) << "Got only a single block with index: " << start_block_idx;
+    return 1;
+  }
+
+  // Get first block
+  iov[0].iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
+  iov[0].iov_len = GetBlockCapacity(start_block_idx) - ReadOffset();
+  QUIC_DVLOG(1) << "Got first block " << start_block_idx << " with len "
+                << iov[0].iov_len;
+  QUICHE_DCHECK_GT(readable_offset_end + 1, total_bytes_read_ + iov[0].iov_len)
+      << "there should be more available data";
+
+  // Get readable regions of the rest blocks till either 2nd to last block
+  // before gap is met or |iov| is filled. For these blocks, one whole block is
+  // a region.
+  int iov_used = 1;
+  size_t block_idx = (start_block_idx + iov_used) % max_blocks_count_;
+  while (block_idx != end_block_idx && iov_used < iov_len) {
+    QUICHE_DCHECK(nullptr != blocks_[block_idx]);
+    iov[iov_used].iov_base = blocks_[block_idx]->buffer;
+    iov[iov_used].iov_len = GetBlockCapacity(block_idx);
+    QUIC_DVLOG(1) << "Got block with index: " << block_idx;
+    ++iov_used;
+    block_idx = (start_block_idx + iov_used) % max_blocks_count_;
+  }
+
+  // Deal with last block if |iov| can hold more.
+  if (iov_used < iov_len) {
+    QUICHE_DCHECK(nullptr != blocks_[block_idx]);
+    iov[iov_used].iov_base = blocks_[end_block_idx]->buffer;
+    iov[iov_used].iov_len = end_block_offset + 1;
+    QUIC_DVLOG(1) << "Got last block with index: " << end_block_idx;
+    ++iov_used;
+  }
+  return iov_used;
+}
+
+bool QuicStreamSequencerBuffer::GetReadableRegion(iovec* iov) const {
+  return GetReadableRegions(iov, 1) == 1;
+}
+
+bool QuicStreamSequencerBuffer::PeekRegion(QuicStreamOffset offset,
+                                           iovec* iov) const {
+  QUICHE_DCHECK(iov);
+
+  if (offset < total_bytes_read_) {
+    // Data at |offset| has already been consumed.
+    return false;
+  }
+
+  if (offset >= FirstMissingByte()) {
+    // Data at |offset| has not been received yet.
+    return false;
+  }
+
+  // Beginning of region.
+  size_t block_idx = GetBlockIndex(offset);
+  size_t block_offset = GetInBlockOffset(offset);
+  iov->iov_base = blocks_[block_idx]->buffer + block_offset;
+
+  // Determine if entire block has been received.
+  size_t end_block_idx = GetBlockIndex(FirstMissingByte());
+  if (block_idx == end_block_idx) {
+    // Only read part of block before FirstMissingByte().
+    iov->iov_len = GetInBlockOffset(FirstMissingByte()) - block_offset;
+  } else {
+    // Read entire block.
+    iov->iov_len = GetBlockCapacity(block_idx) - block_offset;
+  }
+
+  return true;
+}
+
+bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_consumed) {
+  if (bytes_consumed > ReadableBytes()) {
+    return false;
+  }
+  size_t bytes_to_consume = bytes_consumed;
+  while (bytes_to_consume > 0) {
+    size_t block_idx = NextBlockToRead();
+    size_t offset_in_block = ReadOffset();
+    size_t bytes_available = std::min<size_t>(
+        ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block);
+    size_t bytes_read = std::min<size_t>(bytes_to_consume, bytes_available);
+    total_bytes_read_ += bytes_read;
+    num_bytes_buffered_ -= bytes_read;
+    bytes_to_consume -= bytes_read;
+    // If advanced to the end of current block and end of buffer hasn't wrapped
+    // to this block yet.
+    if (bytes_available == bytes_read) {
+      RetireBlockIfEmpty(block_idx);
+    }
+  }
+
+  return true;
+}
+
+size_t QuicStreamSequencerBuffer::FlushBufferedFrames() {
+  size_t prev_total_bytes_read = total_bytes_read_;
+  total_bytes_read_ = NextExpectedByte();
+  Clear();
+  return total_bytes_read_ - prev_total_bytes_read;
+}
+
+void QuicStreamSequencerBuffer::ReleaseWholeBuffer() {
+  Clear();
+  current_blocks_count_ = 0;
+  blocks_.reset(nullptr);
+}
+
+size_t QuicStreamSequencerBuffer::ReadableBytes() const {
+  return FirstMissingByte() - total_bytes_read_;
+}
+
+bool QuicStreamSequencerBuffer::HasBytesToRead() const {
+  return ReadableBytes() > 0;
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::BytesConsumed() const {
+  return total_bytes_read_;
+}
+
+size_t QuicStreamSequencerBuffer::BytesBuffered() const {
+  return num_bytes_buffered_;
+}
+
+size_t QuicStreamSequencerBuffer::GetBlockIndex(QuicStreamOffset offset) const {
+  return (offset % max_buffer_capacity_bytes_) / kBlockSizeBytes;
+}
+
+size_t QuicStreamSequencerBuffer::GetInBlockOffset(
+    QuicStreamOffset offset) const {
+  return (offset % max_buffer_capacity_bytes_) % kBlockSizeBytes;
+}
+
+size_t QuicStreamSequencerBuffer::ReadOffset() const {
+  return GetInBlockOffset(total_bytes_read_);
+}
+
+size_t QuicStreamSequencerBuffer::NextBlockToRead() const {
+  return GetBlockIndex(total_bytes_read_);
+}
+
+bool QuicStreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) {
+  QUICHE_DCHECK(ReadableBytes() == 0 ||
+                GetInBlockOffset(total_bytes_read_) == 0)
+      << "RetireBlockIfEmpty() should only be called when advancing to next "
+      << "block or a gap has been reached.";
+  // If the whole buffer becomes empty, the last piece of data has been read.
+  if (Empty()) {
+    return RetireBlock(block_index);
+  }
+
+  // Check where the logical end of this buffer is.
+  // Not empty if the end of circular buffer has been wrapped to this block.
+  if (GetBlockIndex(NextExpectedByte() - 1) == block_index) {
+    return true;
+  }
+
+  // Read index remains in this block, which means a gap has been reached.
+  if (NextBlockToRead() == block_index) {
+    if (bytes_received_.Size() > 1) {
+      auto it = bytes_received_.begin();
+      ++it;
+      if (GetBlockIndex(it->min()) == block_index) {
+        // Do not retire the block if next data interval is in this block.
+        return true;
+      }
+    } else {
+      QUIC_BUG(quic_bug_10610_2) << "Read stopped at where it shouldn't.";
+      return false;
+    }
+  }
+  return RetireBlock(block_index);
+}
+
+bool QuicStreamSequencerBuffer::Empty() const {
+  return bytes_received_.Empty() ||
+         (bytes_received_.Size() == 1 && total_bytes_read_ > 0 &&
+          bytes_received_.begin()->max() == total_bytes_read_);
+}
+
+size_t QuicStreamSequencerBuffer::GetBlockCapacity(size_t block_index) const {
+  if ((block_index + 1) == max_blocks_count_) {
+    size_t result = max_buffer_capacity_bytes_ % kBlockSizeBytes;
+    if (result == 0) {  // whole block
+      result = kBlockSizeBytes;
+    }
+    return result;
+  } else {
+    return kBlockSizeBytes;
+  }
+}
+
+std::string QuicStreamSequencerBuffer::ReceivedFramesDebugString() const {
+  return bytes_received_.ToString();
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::FirstMissingByte() const {
+  if (bytes_received_.Empty() || bytes_received_.begin()->min() > 0) {
+    // Offset 0 is not received yet.
+    return 0;
+  }
+  return bytes_received_.begin()->max();
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::NextExpectedByte() const {
+  if (bytes_received_.Empty()) {
+    return 0;
+  }
+  return bytes_received_.rbegin()->max();
+}
+
+}  //  namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer_buffer.h b/quiche/quic/core/quic_stream_sequencer_buffer.h
new file mode 100644
index 0000000..c4aaa0a
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_buffer.h
@@ -0,0 +1,246 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
+
+// QuicStreamSequencerBuffer is a circular stream buffer with random write and
+// in-sequence read. It consists of a vector of pointers pointing
+// to memory blocks created as needed and an interval set recording received
+// data.
+// - Data are written in with offset indicating where it should be in the
+// stream, and the buffer grown as needed (up to the maximum buffer capacity),
+// without expensive copying (extra blocks are allocated).
+// - Data can be read from the buffer if there is no gap before it,
+// and the buffer shrinks as the data are consumed.
+// - An upper limit on the number of blocks in the buffer provides an upper
+//   bound on memory use.
+//
+// This class is thread-unsafe.
+//
+// QuicStreamSequencerBuffer maintains a concept of the readable region, which
+// contains all written data that has not been read.
+// It promises stability of the underlying memory addresses in the readable
+// region, so pointers into it can be maintained, and the offset of a pointer
+// from the start of the read region can be calculated.
+//
+// Expected Use:
+//  QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024);
+//  std::string source(1024, 'a');
+//  absl::string_view string_piece(source.data(), source.size());
+//  size_t written = 0;
+//  buffer.OnStreamData(800, string_piece, GetEpollClockNow(), &written);
+//  source = std::string{800, 'b'};
+//  absl::string_view string_piece1(source.data(), 800);
+//  // Try to write to [1, 801), but should fail due to overlapping,
+//  // res should be QUIC_INVALID_STREAM_DATA
+//  auto res = buffer.OnStreamData(1, string_piece1, &written));
+//  // write to [0, 800), res should be QUIC_NO_ERROR
+//  auto res = buffer.OnStreamData(0, string_piece1, GetEpollClockNow(),
+//                                  &written);
+//
+//  // Read into a iovec array with total capacity of 120 bytes.
+//  char dest[120];
+//  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40},
+//                  iovec{dest + 80, 40}};
+//  size_t read = buffer.Readv(iovecs, 3);
+//
+//  // Get single readable region.
+//  iovec iov;
+//  buffer.GetReadableRegion(iov);
+//
+//  // Get readable regions from [256, 1024) and consume some of it.
+//  iovec iovs[2];
+//  int iov_count = buffer.GetReadableRegions(iovs, 2);
+//  // Consume some bytes in iovs, returning number of bytes having been
+//  consumed.
+//  size_t consumed = consume_iovs(iovs, iov_count);
+//  buffer.MarkConsumed(consumed);
+
+#include <cstddef>
+#include <functional>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_iovec.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSequencerBufferPeer;
+}  // namespace test
+
+class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
+ public:
+  // Size of blocks used by this buffer.
+  // Choose 8K to make block large enough to hold multiple frames, each of
+  // which could be up to 1.5 KB.
+  static const size_t kBlockSizeBytes = 8 * 1024;  // 8KB
+
+  // The basic storage block used by this buffer.
+  struct QUIC_EXPORT_PRIVATE BufferBlock {
+    char buffer[kBlockSizeBytes];
+  };
+
+  explicit QuicStreamSequencerBuffer(size_t max_capacity_bytes);
+  QuicStreamSequencerBuffer(const QuicStreamSequencerBuffer&) = delete;
+  QuicStreamSequencerBuffer(QuicStreamSequencerBuffer&&) = default;
+  QuicStreamSequencerBuffer& operator=(const QuicStreamSequencerBuffer&) =
+      delete;
+  QuicStreamSequencerBuffer& operator=(QuicStreamSequencerBuffer&&) = default;
+  ~QuicStreamSequencerBuffer();
+
+  // Free the space used to buffer data.
+  void Clear();
+
+  // Returns true if there is nothing to read in this buffer.
+  bool Empty() const;
+
+  // Called to buffer new data received for this stream.  If the data was
+  // successfully buffered, returns QUIC_NO_ERROR and stores the number of
+  // bytes buffered in |bytes_buffered|. Returns an error otherwise.
+  QuicErrorCode OnStreamData(QuicStreamOffset offset,
+                             absl::string_view data,
+                             size_t* bytes_buffered,
+                             std::string* error_details);
+
+  // Reads from this buffer into given iovec array, up to number of iov_len
+  // iovec objects and returns the number of bytes read.
+  QuicErrorCode Readv(const struct iovec* dest_iov,
+                      size_t dest_count,
+                      size_t* bytes_read,
+                      std::string* error_details);
+
+  // Returns the readable region of valid data in iovec format. The readable
+  // region is the buffer region where there is valid data not yet read by
+  // client.
+  // Returns the number of iovec entries in |iov| which were populated.
+  // If the region is empty, one iovec entry with 0 length
+  // is returned, and the function returns 0. If there are more readable
+  // regions than |iov_size|, the function only processes the first
+  // |iov_size| of them.
+  int GetReadableRegions(struct iovec* iov, int iov_len) const;
+
+  // Fills in one iovec with data from the next readable region.
+  // Returns false if there is no readable region available.
+  bool GetReadableRegion(iovec* iov) const;
+
+  // Returns true and sets |*iov| to point to a region starting at |offset|.
+  // Returns false if no data can be read at |offset|, which can be because data
+  // has not been received yet or it is already consumed.
+  // Does not consume data.
+  bool PeekRegion(QuicStreamOffset offset, iovec* iov) const;
+
+  // Called after GetReadableRegions() to free up |bytes_consumed| space if
+  // these bytes are processed.
+  // Pre-requisite: bytes_consumed <= available bytes to read.
+  bool MarkConsumed(size_t bytes_consumed);
+
+  // Deletes and records as consumed any buffered data and clear the buffer.
+  // (To be called only after sequencer's StopReading has been called.)
+  size_t FlushBufferedFrames();
+
+  // Free the memory of buffered data.
+  void ReleaseWholeBuffer();
+
+  // Whether there are bytes can be read out.
+  bool HasBytesToRead() const;
+
+  // Count how many bytes have been consumed (read out of buffer).
+  QuicStreamOffset BytesConsumed() const;
+
+  // Count how many bytes are in buffer at this moment.
+  size_t BytesBuffered() const;
+
+  // Returns number of bytes available to be read out.
+  size_t ReadableBytes() const;
+
+ private:
+  friend class test::QuicStreamSequencerBufferPeer;
+
+  // Copies |data| to blocks_, sets |bytes_copy|. Returns true if the copy is
+  // successful. Otherwise, sets |error_details| and returns false.
+  bool CopyStreamData(QuicStreamOffset offset,
+                      absl::string_view data,
+                      size_t* bytes_copy,
+                      std::string* error_details);
+
+  // Dispose the given buffer block.
+  // After calling this method, blocks_[index] is set to nullptr
+  // in order to indicate that no memory set is allocated for that block.
+  // Returns true on success, false otherwise.
+  bool RetireBlock(size_t index);
+
+  // Should only be called after the indexed block is read till the end of the
+  // block or missing data has been reached.
+  // If the block at |block_index| contains no buffered data, the block
+  // should be retired.
+  // Returns true on success, or false otherwise.
+  bool RetireBlockIfEmpty(size_t block_index);
+
+  // Calculate the capacity of block at specified index.
+  // Return value should be either kBlockSizeBytes for non-trailing blocks and
+  // max_buffer_capacity % kBlockSizeBytes for trailing block.
+  size_t GetBlockCapacity(size_t index) const;
+
+  // Does not check if offset is within reasonable range.
+  size_t GetBlockIndex(QuicStreamOffset offset) const;
+
+  // Given an offset in the stream, return the offset from the beginning of the
+  // block which contains this data.
+  size_t GetInBlockOffset(QuicStreamOffset offset) const;
+
+  // Get offset relative to index 0 in logical 1st block to start next read.
+  size_t ReadOffset() const;
+
+  // Get the index of the logical 1st block to start next read.
+  size_t NextBlockToRead() const;
+
+  // Returns offset of first missing byte.
+  QuicStreamOffset FirstMissingByte() const;
+
+  // Returns offset of highest received byte + 1.
+  QuicStreamOffset NextExpectedByte() const;
+
+  // Return all received frames as a string.
+  std::string ReceivedFramesDebugString() const;
+
+  // Resize blocks_ if more blocks are needed to accomodate bytes before
+  // next_expected_byte.
+  void MaybeAddMoreBlocks(QuicStreamOffset next_expected_byte);
+
+  // The maximum total capacity of this buffer in byte, as constructed.
+  size_t max_buffer_capacity_bytes_;
+
+  // Number of blocks this buffer would have when it reaches full capacity,
+  // i.e., maximal number of blocks in blocks_.
+  size_t max_blocks_count_;
+
+  // Number of blocks this buffer currently has.
+  size_t current_blocks_count_;
+
+  // Number of bytes read out of buffer.
+  QuicStreamOffset total_bytes_read_;
+
+  // An ordered, variable-length list of blocks, with the length limited
+  // such that the number of blocks never exceeds max_blocks_count_.
+  // Each list entry can hold up to kBlockSizeBytes bytes.
+  std::unique_ptr<BufferBlock*[]> blocks_;
+
+  // Number of bytes in buffer.
+  size_t num_bytes_buffered_;
+
+  // Currently received data.
+  QuicIntervalSet<QuicStreamOffset> bytes_received_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEQUENCER_BUFFER_H_
diff --git a/quiche/quic/core/quic_stream_sequencer_buffer_test.cc b/quiche/quic/core/quic_stream_sequencer_buffer_test.cc
new file mode 100644
index 0000000..d1cdf34
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_buffer_test.cc
@@ -0,0 +1,1139 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+absl::string_view IovecToStringPiece(iovec iov) {
+  return absl::string_view(reinterpret_cast<const char*>(iov.iov_base),
+                           iov.iov_len);
+}
+
+char GetCharFromIOVecs(size_t offset, iovec iov[], size_t count) {
+  size_t start_offset = 0;
+  for (size_t i = 0; i < count; i++) {
+    if (iov[i].iov_len == 0) {
+      continue;
+    }
+    size_t end_offset = start_offset + iov[i].iov_len - 1;
+    if (offset >= start_offset && offset <= end_offset) {
+      const char* buf = reinterpret_cast<const char*>(iov[i].iov_base);
+      return buf[offset - start_offset];
+    }
+    start_offset += iov[i].iov_len;
+  }
+  QUIC_LOG(ERROR) << "Could not locate char at offset " << offset << " in "
+                  << count << " iovecs";
+  for (size_t i = 0; i < count; ++i) {
+    QUIC_LOG(ERROR) << "  iov[" << i << "].iov_len = " << iov[i].iov_len;
+  }
+  return '\0';
+}
+
+const size_t kMaxNumGapsAllowed = 2 * kMaxPacketGap;
+
+static const size_t kBlockSizeBytes =
+    QuicStreamSequencerBuffer::kBlockSizeBytes;
+using BufferBlock = QuicStreamSequencerBuffer::BufferBlock;
+
+namespace {
+
+class QuicStreamSequencerBufferTest : public QuicTest {
+ public:
+  void SetUp() override { Initialize(); }
+
+  void ResetMaxCapacityBytes(size_t max_capacity_bytes) {
+    max_capacity_bytes_ = max_capacity_bytes;
+    Initialize();
+  }
+
+ protected:
+  void Initialize() {
+    buffer_ =
+        std::make_unique<QuicStreamSequencerBuffer>((max_capacity_bytes_));
+    helper_ = std::make_unique<QuicStreamSequencerBufferPeer>((buffer_.get()));
+  }
+
+  // Use 8.5 here to make sure that the buffer has more than
+  // QuicStreamSequencerBuffer::kInitialBlockCount block and its end doesn't
+  // align with the end of a block in order to test all the offset calculation.
+  size_t max_capacity_bytes_ = 8.5 * kBlockSizeBytes;
+
+  std::unique_ptr<QuicStreamSequencerBuffer> buffer_;
+  std::unique_ptr<QuicStreamSequencerBufferPeer> helper_;
+  size_t written_ = 0;
+  std::string error_details_;
+};
+
+TEST_F(QuicStreamSequencerBufferTest, InitializeWithMaxRecvWindowSize) {
+  ResetMaxCapacityBytes(16 * 1024 * 1024);  // 16MB
+  EXPECT_EQ(2 * 1024u,                      // 16MB / 8KB = 2K
+            helper_->max_blocks_count());
+  EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
+  EXPECT_TRUE(helper_->CheckInitialState());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, InitializationWithDifferentSizes) {
+  const size_t kCapacity = 16 * QuicStreamSequencerBuffer::kBlockSizeBytes;
+  ResetMaxCapacityBytes(kCapacity);
+  EXPECT_EQ(max_capacity_bytes_, helper_->max_buffer_capacity());
+  EXPECT_TRUE(helper_->CheckInitialState());
+
+  const size_t kCapacity1 = 32 * QuicStreamSequencerBuffer::kBlockSizeBytes;
+  ResetMaxCapacityBytes(kCapacity1);
+  EXPECT_EQ(kCapacity1, helper_->max_buffer_capacity());
+  EXPECT_TRUE(helper_->CheckInitialState());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ClearOnEmpty) {
+  buffer_->Clear();
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamData0length) {
+  QuicErrorCode error =
+      buffer_->OnStreamData(800, "", &written_, &error_details_);
+  EXPECT_THAT(error, IsError(QUIC_EMPTY_STREAM_FRAME_NO_FIN));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithinBlock) {
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+  std::string source(1024, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  BufferBlock* block_ptr = helper_->GetBlock(0);
+  for (size_t i = 0; i < source.size(); ++i) {
+    ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
+  }
+  EXPECT_EQ(2, helper_->IntervalSize());
+  EXPECT_EQ(0u, helper_->ReadableBytes());
+  EXPECT_EQ(1u, helper_->bytes_received().Size());
+  EXPECT_EQ(800u, helper_->bytes_received().begin()->min());
+  EXPECT_EQ(1824u, helper_->bytes_received().begin()->max());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  EXPECT_TRUE(helper_->IsBufferAllocated());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, Move) {
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+  std::string source(1024, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  BufferBlock* block_ptr = helper_->GetBlock(0);
+  for (size_t i = 0; i < source.size(); ++i) {
+    ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
+  }
+
+  QuicStreamSequencerBuffer buffer2(std::move(*buffer_));
+  QuicStreamSequencerBufferPeer helper2(&buffer2);
+
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+
+  EXPECT_EQ(2, helper2.IntervalSize());
+  EXPECT_EQ(0u, helper2.ReadableBytes());
+  EXPECT_EQ(1u, helper2.bytes_received().Size());
+  EXPECT_EQ(800u, helper2.bytes_received().begin()->min());
+  EXPECT_EQ(1824u, helper2.bytes_received().begin()->max());
+  EXPECT_TRUE(helper2.CheckBufferInvariants());
+  EXPECT_TRUE(helper2.IsBufferAllocated());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, DISABLED_OnStreamDataInvalidSource) {
+  // Pass in an invalid source, expects to return error.
+  absl::string_view source;
+  source = absl::string_view(nullptr, 1024);
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsError(QUIC_STREAM_SEQUENCER_INVALID_STATE));
+  EXPECT_EQ(0u, error_details_.find(absl::StrCat(
+                    "QuicStreamSequencerBuffer error: OnStreamData() "
+                    "dest == nullptr: ",
+                    false, " source == nullptr: ", true)));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithOverlap) {
+  std::string source(1024, 'a');
+  // Write something into [800, 1824)
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  // Try to write to [0, 1024) and [1024, 2048).
+  EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_THAT(buffer_->OnStreamData(1024, source, &written_, &error_details_),
+              IsQuicNoError());
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       OnStreamDataOverlapAndDuplicateCornerCases) {
+  std::string source(1024, 'a');
+  // Write something into [800, 1824)
+  buffer_->OnStreamData(800, source, &written_, &error_details_);
+  source = std::string(800, 'b');
+  std::string one_byte = "c";
+  // Write [1, 801).
+  EXPECT_THAT(buffer_->OnStreamData(1, source, &written_, &error_details_),
+              IsQuicNoError());
+  // Write [0, 800).
+  EXPECT_THAT(buffer_->OnStreamData(0, source, &written_, &error_details_),
+              IsQuicNoError());
+  // Write [1823, 1824).
+  EXPECT_THAT(buffer_->OnStreamData(1823, one_byte, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(0u, written_);
+  // write one byte to [1824, 1825)
+  EXPECT_THAT(buffer_->OnStreamData(1824, one_byte, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithoutOverlap) {
+  std::string source(1024, 'a');
+  // Write something into [800, 1824).
+  EXPECT_THAT(buffer_->OnStreamData(800, source, &written_, &error_details_),
+              IsQuicNoError());
+  source = std::string(100, 'b');
+  // Write something into [kBlockSizeBytes * 2 - 20, kBlockSizeBytes * 2 + 80).
+  EXPECT_THAT(buffer_->OnStreamData(kBlockSizeBytes * 2 - 20, source, &written_,
+                                    &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(3, helper_->IntervalSize());
+  EXPECT_EQ(1024u + 100u, buffer_->BytesBuffered());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInLongStreamWithOverlap) {
+  // Assume a stream has already buffered almost 4GB.
+  uint64_t total_bytes_read = pow(2, 32) - 1;
+  helper_->set_total_bytes_read(total_bytes_read);
+  helper_->AddBytesReceived(0, total_bytes_read);
+
+  // Three new out of order frames arrive.
+  const size_t kBytesToWrite = 100;
+  std::string source(kBytesToWrite, 'a');
+  // Frame [2^32 + 500, 2^32 + 600).
+  QuicStreamOffset offset = pow(2, 32) + 500;
+  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(2, helper_->IntervalSize());
+
+  // Frame [2^32 + 700, 2^32 + 800).
+  offset = pow(2, 32) + 700;
+  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(3, helper_->IntervalSize());
+
+  // Another frame [2^32 + 300, 2^32 + 400).
+  offset = pow(2, 32) + 300;
+  EXPECT_THAT(buffer_->OnStreamData(offset, source, &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(4, helper_->IntervalSize());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEnd) {
+  // Write 50 bytes to the end.
+  const size_t kBytesToWrite = 50;
+  std::string source(kBytesToWrite, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
+                                    &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(50u, buffer_->BytesBuffered());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataTillEndCorner) {
+  // Write 1 byte to the end.
+  const size_t kBytesToWrite = 1;
+  std::string source(kBytesToWrite, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - kBytesToWrite, source,
+                                    &written_, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(1u, buffer_->BytesBuffered());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, OnStreamDataBeyondCapacity) {
+  std::string source(60, 'a');
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ - 50, source, &written_,
+                                    &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  source = "b";
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
+                                    &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  EXPECT_THAT(buffer_->OnStreamData(max_capacity_bytes_ * 1000, source,
+                                    &written_, &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  // Disallow current_gap != gaps_.end()
+  EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-1), source,
+                                    &written_, &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  // Disallow offset + size overflow
+  source = "bbb";
+  EXPECT_THAT(buffer_->OnStreamData(static_cast<QuicStreamOffset>(-2), source,
+                                    &written_, &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  EXPECT_EQ(0u, buffer_->BytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, Readv100Bytes) {
+  std::string source(1024, 'a');
+  // Write something into [kBlockSizeBytes, kBlockSizeBytes + 1024).
+  buffer_->OnStreamData(kBlockSizeBytes, source, &written_, &error_details_);
+  EXPECT_FALSE(buffer_->HasBytesToRead());
+  source = std::string(100, 'b');
+  // Write something into [0, 100).
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  EXPECT_TRUE(buffer_->HasBytesToRead());
+  // Read into a iovec array with total capacity of 120 bytes.
+  char dest[120];
+  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
+              IsQuicNoError());
+  QUIC_LOG(ERROR) << error_details_;
+  EXPECT_EQ(100u, read);
+  EXPECT_EQ(100u, buffer_->BytesConsumed());
+  EXPECT_EQ(source, absl::string_view(dest, read));
+  // The first block should be released as its data has been read out.
+  EXPECT_EQ(nullptr, helper_->GetBlock(0));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossBlocks) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full and extand 50 bytes to next block.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  EXPECT_EQ(source.size(), helper_->ReadableBytes());
+  // Iteratively read 512 bytes from buffer_-> Overwrite dest[] each time.
+  char dest[512];
+  while (helper_->ReadableBytes()) {
+    std::fill(dest, dest + 512, 0);
+    iovec iovecs[2]{iovec{dest, 256}, iovec{dest + 256, 256}};
+    size_t read;
+    EXPECT_THAT(buffer_->Readv(iovecs, 2, &read, &error_details_),
+                IsQuicNoError());
+  }
+  // The last read only reads the rest 50 bytes in 2nd block.
+  EXPECT_EQ(std::string(50, 'a'), std::string(dest, 50));
+  EXPECT_EQ(0, dest[50]) << "Dest[50] shouln't be filled.";
+  EXPECT_EQ(source.size(), buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ClearAfterRead) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full with 'a'.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  // Read first 512 bytes from buffer to make space at the beginning.
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  // Clear() should make buffer empty while preserving BytesConsumed()
+  buffer_->Clear();
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       OnStreamDataAcrossLastBlockAndFillCapacity) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full with 'a'.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  // Read first 512 bytes from buffer to make space at the beginning.
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  EXPECT_EQ(source.size(), written_);
+
+  // Write more than half block size of bytes in the last block with 'b', which
+  // will wrap to the beginning and reaches the full capacity.
+  source = std::string(0.5 * kBlockSizeBytes + 512, 'b');
+  EXPECT_THAT(buffer_->OnStreamData(2 * kBlockSizeBytes, source, &written_,
+                                    &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(source.size(), written_);
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       OnStreamDataAcrossLastBlockAndExceedCapacity) {
+  std::string source(kBlockSizeBytes + 50, 'a');
+  // Write 1st block to full.
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  // Read first 512 bytes from buffer to make space at the beginning.
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+
+  // Try to write from [max_capacity_bytes_ - 0.5 * kBlockSizeBytes,
+  // max_capacity_bytes_ +  512 + 1). But last bytes exceeds current capacity.
+  source = std::string(0.5 * kBlockSizeBytes + 512 + 1, 'b');
+  EXPECT_THAT(buffer_->OnStreamData(8 * kBlockSizeBytes, source, &written_,
+                                    &error_details_),
+              IsError(QUIC_INTERNAL_ERROR));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReadvAcrossLastBlock) {
+  // Write to full capacity and read out 512 bytes at beginning and continue
+  // appending 256 bytes.
+  std::string source(max_capacity_bytes_, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[512]{0};
+  const iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  source = std::string(256, 'b');
+  buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
+                        &error_details_);
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+
+  // Read all data out.
+  std::unique_ptr<char[]> dest1{new char[max_capacity_bytes_]};
+  dest1[0] = 0;
+  const iovec iov1{dest1.get(), max_capacity_bytes_};
+  EXPECT_THAT(buffer_->Readv(&iov1, 1, &read, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(max_capacity_bytes_ - 512 + 256, read);
+  EXPECT_EQ(max_capacity_bytes_ + 256, buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReadvEmpty) {
+  char dest[512]{0};
+  iovec iov{dest, 512};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(&iov, 1, &read, &error_details_), IsQuicNoError());
+  EXPECT_EQ(0u, read);
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsEmpty) {
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(0, iov_count);
+  EXPECT_EQ(nullptr, iovs[iov_count].iov_base);
+  EXPECT_EQ(0u, iovs[iov_count].iov_len);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, ReleaseWholeBuffer) {
+  // Tests that buffer is not deallocated unless ReleaseWholeBuffer() is called.
+  std::string source(100, 'b');
+  // Write something into [0, 100).
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  EXPECT_TRUE(buffer_->HasBytesToRead());
+  char dest[120];
+  iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40}, iovec{dest + 80, 40}};
+  size_t read;
+  EXPECT_THAT(buffer_->Readv(iovecs, 3, &read, &error_details_),
+              IsQuicNoError());
+  EXPECT_EQ(100u, read);
+  EXPECT_EQ(100u, buffer_->BytesConsumed());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  EXPECT_TRUE(helper_->IsBufferAllocated());
+  buffer_->ReleaseWholeBuffer();
+  EXPECT_FALSE(helper_->IsBufferAllocated());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsBlockedByGap) {
+  // Write into [1, 1024).
+  std::string source(1023, 'a');
+  buffer_->OnStreamData(1, source, &written_, &error_details_);
+  // Try to get readable regions, but none is there.
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(0, iov_count);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsTillEndOfBlock) {
+  // Write first block to full with [0, 256) 'a' and the rest 'b' then read out
+  // [0, 256)
+  std::string source(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1024)
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(1, iov_count);
+  EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'),
+            IovecToStringPiece(iovs[0]));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionsWithinOneBlock) {
+  // Write into [0, 1024) and then read out [0, 256)
+  std::string source(1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1024)
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(1, iov_count);
+  EXPECT_EQ(std::string(1024 - 256, 'a'), IovecToStringPiece(iovs[0]));
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       GetReadableRegionsAcrossBlockWithLongIOV) {
+  // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+  std::string source(2 * kBlockSizeBytes + 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+
+  iovec iovs[4];
+  int iov_count = buffer_->GetReadableRegions(iovs, 4);
+  EXPECT_EQ(3, iov_count);
+  EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
+  EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
+  EXPECT_EQ(1024u, iovs[2].iov_len);
+}
+
+TEST_F(QuicStreamSequencerBufferTest,
+       GetReadableRegionsWithMultipleIOVsAcrossEnd) {
+  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
+  // and then append 1024 + 512 bytes.
+  std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+  // Write across the end.
+  source = std::string(1024 + 512, 'b');
+  buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
+                        &error_details_);
+  // Use short iovec's.
+  iovec iovs[2];
+  int iov_count = buffer_->GetReadableRegions(iovs, 2);
+  EXPECT_EQ(2, iov_count);
+  EXPECT_EQ(kBlockSizeBytes - 1024, iovs[0].iov_len);
+  EXPECT_EQ(kBlockSizeBytes, iovs[1].iov_len);
+  // Use long iovec's and wrap the end of buffer.
+  iovec iovs1[11];
+  EXPECT_EQ(10, buffer_->GetReadableRegions(iovs1, 11));
+  EXPECT_EQ(0.5 * kBlockSizeBytes, iovs1[8].iov_len);
+  EXPECT_EQ(512u, iovs1[9].iov_len);
+  EXPECT_EQ(std::string(512, 'b'), IovecToStringPiece(iovs1[9]));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionEmpty) {
+  iovec iov;
+  EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
+  EXPECT_EQ(nullptr, iov.iov_base);
+  EXPECT_EQ(0u, iov.iov_len);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionBeforeGap) {
+  // Write into [1, 1024).
+  std::string source(1023, 'a');
+  buffer_->OnStreamData(1, source, &written_, &error_details_);
+  // GetReadableRegion should return false because range  [0,1) hasn't been
+  // filled yet.
+  iovec iov;
+  EXPECT_FALSE(buffer_->GetReadableRegion(&iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillEndOfBlock) {
+  // Write into [0, kBlockSizeBytes + 1) and then read out [0, 256)
+  std::string source(kBlockSizeBytes + 1, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1024)
+  iovec iov;
+  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
+  EXPECT_EQ(std::string(kBlockSizeBytes - 256, 'a'), IovecToStringPiece(iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GetReadableRegionTillGap) {
+  // Write into [0, kBlockSizeBytes - 1) and then read out [0, 256)
+  std::string source(kBlockSizeBytes - 1, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+  // Get readable region from [256, 1023)
+  iovec iov;
+  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
+  EXPECT_EQ(std::string(kBlockSizeBytes - 1 - 256, 'a'),
+            IovecToStringPiece(iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekEmptyBuffer) {
+  iovec iov;
+  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(1, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(100, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekSingleBlock) {
+  std::string source(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source, IovecToStringPiece(iov));
+
+  // Peeking again gives the same result.
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source, IovecToStringPiece(iov));
+
+  // Peek at a different offset.
+  EXPECT_TRUE(buffer_->PeekRegion(100, &iov));
+  EXPECT_EQ(absl::string_view(source).substr(100), IovecToStringPiece(iov));
+
+  // Peeking at or after FirstMissingByte() returns false.
+  EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(kBlockSizeBytes + 1, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekTwoWritesInSingleBlock) {
+  const size_t length1 = 1024;
+  std::string source1(length1, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  // The second frame goes into the same block.
+  const size_t length2 = 800;
+  std::string source2(length2, 'b');
+  buffer_->OnStreamData(length1, source2, &written_, &error_details_);
+
+  EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
+  EXPECT_EQ(source2, IovecToStringPiece(iov));
+
+  // Peek with an offset inside the first write.
+  const QuicStreamOffset offset1 = 500;
+  EXPECT_TRUE(buffer_->PeekRegion(offset1, &iov));
+  EXPECT_EQ(absl::string_view(source1).substr(offset1),
+            IovecToStringPiece(iov).substr(0, length1 - offset1));
+  EXPECT_EQ(absl::string_view(source2),
+            IovecToStringPiece(iov).substr(length1 - offset1));
+
+  // Peek with an offset inside the second write.
+  const QuicStreamOffset offset2 = 1500;
+  EXPECT_TRUE(buffer_->PeekRegion(offset2, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(offset2 - length1),
+            IovecToStringPiece(iov));
+
+  // Peeking at or after FirstMissingByte() returns false.
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekBufferWithMultipleBlocks) {
+  const size_t length1 = 1024;
+  std::string source1(length1, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  const size_t length2 = kBlockSizeBytes + 2;
+  std::string source2(length2, 'b');
+  buffer_->OnStreamData(length1, source2, &written_, &error_details_);
+
+  // Peek with offset 0 returns the entire block.
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(kBlockSizeBytes, iov.iov_len);
+  EXPECT_EQ(source1, IovecToStringPiece(iov).substr(0, length1));
+  EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
+            IovecToStringPiece(iov).substr(length1));
+
+  EXPECT_TRUE(buffer_->PeekRegion(length1, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(0, kBlockSizeBytes - length1),
+            IovecToStringPiece(iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(kBlockSizeBytes - length1),
+            IovecToStringPiece(iov));
+
+  // Peeking at or after FirstMissingByte() returns false.
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(length1 + length2 + 1, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekAfterConsumed) {
+  std::string source1(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  // Consume some data.
+  EXPECT_TRUE(buffer_->MarkConsumed(1024));
+
+  // Peeking into consumed data fails.
+  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(1024, &iov));
+  EXPECT_EQ(absl::string_view(source1).substr(1024), IovecToStringPiece(iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(1500, &iov));
+  EXPECT_EQ(absl::string_view(source1).substr(1500), IovecToStringPiece(iov));
+
+  // Consume rest of block.
+  EXPECT_TRUE(buffer_->MarkConsumed(kBlockSizeBytes - 1024));
+
+  // Read new data.
+  std::string source2(300, 'b');
+  buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
+
+  // Peek into new data.
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_EQ(source2, IovecToStringPiece(iov));
+
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes + 128, &iov));
+  EXPECT_EQ(absl::string_view(source2).substr(128), IovecToStringPiece(iov));
+
+  // Peeking into consumed data still fails.
+  EXPECT_FALSE(buffer_->PeekRegion(0, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(512, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(1024, &iov));
+  EXPECT_FALSE(buffer_->PeekRegion(1500, &iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, PeekContinously) {
+  std::string source1(kBlockSizeBytes, 'a');
+  buffer_->OnStreamData(0, source1, &written_, &error_details_);
+
+  iovec iov;
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+
+  std::string source2(kBlockSizeBytes, 'b');
+  buffer_->OnStreamData(kBlockSizeBytes, source2, &written_, &error_details_);
+
+  EXPECT_TRUE(buffer_->PeekRegion(kBlockSizeBytes, &iov));
+  EXPECT_EQ(source2, IovecToStringPiece(iov));
+
+  // First block is still there.
+  EXPECT_TRUE(buffer_->PeekRegion(0, &iov));
+  EXPECT_EQ(source1, IovecToStringPiece(iov));
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedInOneBlock) {
+  // Write into [0, 1024) and then read out [0, 256)
+  std::string source(1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+
+  EXPECT_TRUE(buffer_->MarkConsumed(512));
+  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+  EXPECT_EQ(256u, helper_->ReadableBytes());
+  buffer_->MarkConsumed(256);
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedNotEnoughBytes) {
+  // Write into [0, 1024) and then read out [0, 256)
+  std::string source(1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[256];
+  helper_->Read(dest, 256);
+
+  // Consume 1st 512 bytes
+  EXPECT_TRUE(buffer_->MarkConsumed(512));
+  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+  EXPECT_EQ(256u, helper_->ReadableBytes());
+  // Try to consume one bytes more than available. Should return false.
+  EXPECT_FALSE(buffer_->MarkConsumed(257));
+  EXPECT_EQ(256u + 512u, buffer_->BytesConsumed());
+  iovec iov;
+  EXPECT_TRUE(buffer_->GetReadableRegion(&iov));
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossBlock) {
+  // Write into [0, 2 * kBlockSizeBytes + 1024) and then read out [0, 1024)
+  std::string source(2 * kBlockSizeBytes + 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+
+  buffer_->MarkConsumed(2 * kBlockSizeBytes);
+  EXPECT_EQ(source.size(), buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, MarkConsumedAcrossEnd) {
+  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024)
+  // and then append 1024 + 512 bytes.
+  std::string source(8.5 * kBlockSizeBytes - 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+  source = std::string(1024 + 512, 'b');
+  buffer_->OnStreamData(8.5 * kBlockSizeBytes - 1024, source, &written_,
+                        &error_details_);
+  EXPECT_EQ(1024u, buffer_->BytesConsumed());
+
+  // Consume to the end of 8th block.
+  buffer_->MarkConsumed(8 * kBlockSizeBytes - 1024);
+  EXPECT_EQ(8 * kBlockSizeBytes, buffer_->BytesConsumed());
+  // Consume across the physical end of buffer
+  buffer_->MarkConsumed(0.5 * kBlockSizeBytes + 500);
+  EXPECT_EQ(max_capacity_bytes_ + 500, buffer_->BytesConsumed());
+  EXPECT_EQ(12u, helper_->ReadableBytes());
+  // Consume to the logical end of buffer
+  buffer_->MarkConsumed(12);
+  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, FlushBufferedFrames) {
+  // Write into [0, 8.5 * kBlockSizeBytes - 1024) and then read out [0, 1024).
+  std::string source(max_capacity_bytes_ - 1024, 'a');
+  buffer_->OnStreamData(0, source, &written_, &error_details_);
+  char dest[1024];
+  helper_->Read(dest, 1024);
+  EXPECT_EQ(1024u, buffer_->BytesConsumed());
+  // Write [1024, 512) to the physical beginning.
+  source = std::string(512, 'b');
+  buffer_->OnStreamData(max_capacity_bytes_, source, &written_,
+                        &error_details_);
+  EXPECT_EQ(512u, written_);
+  EXPECT_EQ(max_capacity_bytes_ - 1024 + 512, buffer_->FlushBufferedFrames());
+  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+  EXPECT_TRUE(buffer_->Empty());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+  // Clear buffer at this point should still preserve BytesConsumed().
+  buffer_->Clear();
+  EXPECT_EQ(max_capacity_bytes_ + 512, buffer_->BytesConsumed());
+  EXPECT_TRUE(helper_->CheckBufferInvariants());
+}
+
+TEST_F(QuicStreamSequencerBufferTest, TooManyGaps) {
+  // Make sure max capacity is large enough that it is possible to have more
+  // than |kMaxNumGapsAllowed| number of gaps.
+  max_capacity_bytes_ = 3 * kBlockSizeBytes;
+  // Feed buffer with 1-byte discontiguous frames. e.g. [1,2), [3,4), [5,6)...
+  for (QuicStreamOffset begin = 1; begin <= max_capacity_bytes_; begin += 2) {
+    QuicErrorCode rs =
+        buffer_->OnStreamData(begin, "a", &written_, &error_details_);
+
+    QuicStreamOffset last_straw = 2 * kMaxNumGapsAllowed - 1;
+    if (begin == last_straw) {
+      EXPECT_THAT(rs, IsError(QUIC_TOO_MANY_STREAM_DATA_INTERVALS));
+      EXPECT_EQ("Too many data intervals received for this stream.",
+                error_details_);
+      break;
+    }
+  }
+}
+
+class QuicStreamSequencerBufferRandomIOTest
+    : public QuicStreamSequencerBufferTest {
+ public:
+  using OffsetSizePair = std::pair<QuicStreamOffset, size_t>;
+
+  void SetUp() override {
+    // Test against a larger capacity then above tests. Also make sure the last
+    // block is partially available to use.
+    max_capacity_bytes_ = 8.25 * kBlockSizeBytes;
+    // Stream to be buffered should be larger than the capacity to test wrap
+    // around.
+    bytes_to_buffer_ = 2 * max_capacity_bytes_;
+    Initialize();
+
+    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
+    rng_.set_seed(seed);
+  }
+
+  // Create an out-of-order source stream with given size to populate
+  // shuffled_buf_.
+  void CreateSourceAndShuffle(size_t max_chunk_size_bytes) {
+    max_chunk_size_bytes_ = max_chunk_size_bytes;
+    std::unique_ptr<OffsetSizePair[]> chopped_stream(
+        new OffsetSizePair[bytes_to_buffer_]);
+
+    // Split stream into small chunks with random length. chopped_stream will be
+    // populated with segmented stream chunks.
+    size_t start_chopping_offset = 0;
+    size_t iterations = 0;
+    while (start_chopping_offset < bytes_to_buffer_) {
+      size_t max_chunk = std::min<size_t>(
+          max_chunk_size_bytes_, bytes_to_buffer_ - start_chopping_offset);
+      size_t chunk_size = rng_.RandUint64() % max_chunk + 1;
+      chopped_stream[iterations] =
+          OffsetSizePair(start_chopping_offset, chunk_size);
+      start_chopping_offset += chunk_size;
+      ++iterations;
+    }
+    QUICHE_DCHECK(start_chopping_offset == bytes_to_buffer_);
+    size_t chunk_num = iterations;
+
+    // Randomly change the sequence of in-ordered OffsetSizePairs to make a
+    // out-of-order array of OffsetSizePairs.
+    for (int i = chunk_num - 1; i >= 0; --i) {
+      size_t random_idx = rng_.RandUint64() % (i + 1);
+      QUIC_DVLOG(1) << "chunk offset " << chopped_stream[random_idx].first
+                    << " size " << chopped_stream[random_idx].second;
+      shuffled_buf_.push_front(chopped_stream[random_idx]);
+      chopped_stream[random_idx] = chopped_stream[i];
+    }
+  }
+
+  // Write the currently first chunk of data in the out-of-order stream into
+  // QuicStreamSequencerBuffer. If current chuck cannot be written into buffer
+  // because it goes beyond current capacity, move it to the end of
+  // shuffled_buf_ and write it later.
+  void WriteNextChunkToBuffer() {
+    OffsetSizePair& chunk = shuffled_buf_.front();
+    QuicStreamOffset offset = chunk.first;
+    const size_t num_to_write = chunk.second;
+    std::unique_ptr<char[]> write_buf{new char[max_chunk_size_bytes_]};
+    for (size_t i = 0; i < num_to_write; ++i) {
+      write_buf[i] = (offset + i) % 256;
+    }
+    absl::string_view string_piece_w(write_buf.get(), num_to_write);
+    auto result = buffer_->OnStreamData(offset, string_piece_w, &written_,
+                                        &error_details_);
+    if (result == QUIC_NO_ERROR) {
+      shuffled_buf_.pop_front();
+      total_bytes_written_ += num_to_write;
+    } else {
+      // This chunk offset exceeds window size.
+      shuffled_buf_.push_back(chunk);
+      shuffled_buf_.pop_front();
+    }
+    QUIC_DVLOG(1) << " write at offset: " << offset
+                  << " len to write: " << num_to_write
+                  << " write result: " << result
+                  << " left over: " << shuffled_buf_.size();
+  }
+
+ protected:
+  std::list<OffsetSizePair> shuffled_buf_;
+  size_t max_chunk_size_bytes_;
+  QuicStreamOffset bytes_to_buffer_;
+  size_t total_bytes_written_ = 0;
+  size_t total_bytes_read_ = 0;
+  SimpleRandom rng_;
+};
+
+TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndReadv) {
+  // Set kMaxReadSize larger than kBlockSizeBytes to test both small and large
+  // read.
+  const size_t kMaxReadSize = kBlockSizeBytes * 2;
+  // kNumReads is larger than 1 to test how multiple read destinations work.
+  const size_t kNumReads = 2;
+  // Since write and read operation have equal possibility to be called. Bytes
+  // to be written into and read out of should roughly the same.
+  const size_t kMaxWriteSize = kNumReads * kMaxReadSize;
+  size_t iterations = 0;
+
+  CreateSourceAndShuffle(kMaxWriteSize);
+
+  while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
+         iterations <= 2 * bytes_to_buffer_) {
+    uint8_t next_action =
+        shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
+    QUIC_DVLOG(1) << "iteration: " << iterations;
+    switch (next_action) {
+      case 0: {  // write
+        WriteNextChunkToBuffer();
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+      case 1: {  // readv
+        std::unique_ptr<char[][kMaxReadSize]> read_buf{
+            new char[kNumReads][kMaxReadSize]};
+        iovec dest_iov[kNumReads];
+        size_t num_to_read = 0;
+        for (size_t i = 0; i < kNumReads; ++i) {
+          dest_iov[i].iov_base =
+              reinterpret_cast<void*>(const_cast<char*>(read_buf[i]));
+          dest_iov[i].iov_len = rng_.RandUint64() % kMaxReadSize;
+          num_to_read += dest_iov[i].iov_len;
+        }
+        size_t actually_read;
+        EXPECT_THAT(buffer_->Readv(dest_iov, kNumReads, &actually_read,
+                                   &error_details_),
+                    IsQuicNoError());
+        ASSERT_LE(actually_read, num_to_read);
+        QUIC_DVLOG(1) << " read from offset: " << total_bytes_read_
+                      << " size: " << num_to_read
+                      << " actual read: " << actually_read;
+        for (size_t i = 0; i < actually_read; ++i) {
+          char ch = (i + total_bytes_read_) % 256;
+          ASSERT_EQ(ch, GetCharFromIOVecs(i, dest_iov, kNumReads))
+              << " at iteration " << iterations;
+        }
+        total_bytes_read_ += actually_read;
+        ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+    }
+    ++iterations;
+    ASSERT_LE(total_bytes_read_, total_bytes_written_);
+  }
+  EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
+  EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
+      << "iterations: " << iterations;
+  EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
+}
+
+TEST_F(QuicStreamSequencerBufferRandomIOTest, RandomWriteAndConsumeInPlace) {
+  // The value 4 is chosen such that the max write size is no larger than the
+  // maximum buffer capacity.
+  const size_t kMaxNumReads = 4;
+  // Adjust write amount be roughly equal to that GetReadableRegions() can get.
+  const size_t kMaxWriteSize = kMaxNumReads * kBlockSizeBytes;
+  ASSERT_LE(kMaxWriteSize, max_capacity_bytes_);
+  size_t iterations = 0;
+
+  CreateSourceAndShuffle(kMaxWriteSize);
+
+  while ((!shuffled_buf_.empty() || total_bytes_read_ < bytes_to_buffer_) &&
+         iterations <= 2 * bytes_to_buffer_) {
+    uint8_t next_action =
+        shuffled_buf_.empty() ? uint8_t{1} : rng_.RandUint64() % 2;
+    QUIC_DVLOG(1) << "iteration: " << iterations;
+    switch (next_action) {
+      case 0: {  // write
+        WriteNextChunkToBuffer();
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+      case 1: {  // GetReadableRegions and then MarkConsumed
+        size_t num_read = rng_.RandUint64() % kMaxNumReads + 1;
+        iovec dest_iov[kMaxNumReads];
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        size_t actually_num_read =
+            buffer_->GetReadableRegions(dest_iov, num_read);
+        ASSERT_LE(actually_num_read, num_read);
+        size_t avail_bytes = 0;
+        for (size_t i = 0; i < actually_num_read; ++i) {
+          avail_bytes += dest_iov[i].iov_len;
+        }
+        // process random number of bytes (check the value of each byte).
+        size_t bytes_to_process = rng_.RandUint64() % (avail_bytes + 1);
+        size_t bytes_processed = 0;
+        for (size_t i = 0; i < actually_num_read; ++i) {
+          size_t bytes_in_block = std::min<size_t>(
+              bytes_to_process - bytes_processed, dest_iov[i].iov_len);
+          if (bytes_in_block == 0) {
+            break;
+          }
+          for (size_t j = 0; j < bytes_in_block; ++j) {
+            ASSERT_LE(bytes_processed, bytes_to_process);
+            char char_expected =
+                (buffer_->BytesConsumed() + bytes_processed) % 256;
+            ASSERT_EQ(char_expected,
+                      reinterpret_cast<const char*>(dest_iov[i].iov_base)[j])
+                << " at iteration " << iterations;
+            ++bytes_processed;
+          }
+        }
+
+        buffer_->MarkConsumed(bytes_processed);
+
+        QUIC_DVLOG(1) << "iteration " << iterations << ": try to get "
+                      << num_read << " readable regions, actually get "
+                      << actually_num_read
+                      << " from offset: " << total_bytes_read_
+                      << "\nprocesse bytes: " << bytes_processed;
+        total_bytes_read_ += bytes_processed;
+        ASSERT_EQ(total_bytes_read_, buffer_->BytesConsumed());
+        ASSERT_TRUE(helper_->CheckBufferInvariants());
+        break;
+      }
+    }
+    ++iterations;
+    ASSERT_LE(total_bytes_read_, total_bytes_written_);
+  }
+  EXPECT_LT(iterations, bytes_to_buffer_) << "runaway test";
+  EXPECT_LE(bytes_to_buffer_, total_bytes_read_)
+      << "iterations: " << iterations;
+  EXPECT_LE(bytes_to_buffer_, total_bytes_written_);
+}
+
+TEST_F(QuicStreamSequencerBufferTest, GrowBlockSizeOnDemand) {
+  max_capacity_bytes_ = 1024 * kBlockSizeBytes;
+  std::string source_of_one_block(kBlockSizeBytes, 'a');
+  Initialize();
+
+  ASSERT_EQ(helper_->current_blocks_count(), 0u);
+
+  // A minimum of 8 blocks are allocated
+  buffer_->OnStreamData(0, source_of_one_block, &written_, &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 8u);
+
+  // Number of blocks doesn't grow if the data is within the capacity.
+  buffer_->OnStreamData(kBlockSizeBytes * 7, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 8u);
+
+  // Number of blocks grows by a factor of 4 normally.
+  buffer_->OnStreamData(kBlockSizeBytes * 8, "a", &written_, &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 32u);
+
+  // Number of blocks grow to the demanded size of 140 instead of 128 since
+  // that's not enough.
+  buffer_->OnStreamData(kBlockSizeBytes * 139, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 140u);
+
+  // Number of blocks grows by a factor of 4 normally.
+  buffer_->OnStreamData(kBlockSizeBytes * 140, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 560u);
+
+  // max_capacity_bytes is reached and number of blocks is capped.
+  buffer_->OnStreamData(kBlockSizeBytes * 560, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 1024u);
+
+  // max_capacity_bytes is reached and number of blocks is capped.
+  buffer_->OnStreamData(kBlockSizeBytes * 1025, source_of_one_block, &written_,
+                        &error_details_);
+  ASSERT_EQ(helper_->current_blocks_count(), 1024u);
+}
+
+}  // anonymous namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_sequencer_test.cc b/quiche/quic/core/quic_stream_sequencer_test.cc
new file mode 100644
index 0000000..8a1b2de
--- /dev/null
+++ b/quiche/quic/core/quic_stream_sequencer_test.cc
@@ -0,0 +1,781 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream_sequencer.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::InSequence;
+
+namespace quic {
+namespace test {
+
+class MockStream : public QuicStreamSequencer::StreamInterface {
+ public:
+  MOCK_METHOD(void, OnFinRead, (), (override));
+  MOCK_METHOD(void, OnDataAvailable, (), (override));
+  MOCK_METHOD(void,
+              OnUnrecoverableError,
+              (QuicErrorCode error, const std::string& details),
+              (override));
+  MOCK_METHOD(void,
+              OnUnrecoverableError,
+              (QuicErrorCode error,
+               QuicIetfTransportErrorCodes ietf_error,
+               const std::string& details),
+              (override));
+  MOCK_METHOD(void, ResetWithError, (QuicResetStreamError error), (override));
+  MOCK_METHOD(void, AddBytesConsumed, (QuicByteCount bytes), (override));
+
+  QuicStreamId id() const override { return 1; }
+  ParsedQuicVersion version() const override {
+    return CurrentSupportedVersions()[0];
+  }
+};
+
+namespace {
+
+static const char kPayload[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+class QuicStreamSequencerTest : public QuicTest {
+ public:
+  void ConsumeData(size_t num_bytes) {
+    char buffer[1024];
+    ASSERT_GT(ABSL_ARRAYSIZE(buffer), num_bytes);
+    struct iovec iov;
+    iov.iov_base = buffer;
+    iov.iov_len = num_bytes;
+    ASSERT_EQ(num_bytes, sequencer_->Readv(&iov, 1));
+  }
+
+ protected:
+  QuicStreamSequencerTest()
+      : stream_(), sequencer_(new QuicStreamSequencer(&stream_)) {}
+
+  // Verify that the data in first region match with the expected[0].
+  bool VerifyReadableRegion(const std::vector<std::string>& expected) {
+    return VerifyReadableRegion(*sequencer_, expected);
+  }
+
+  // Verify that the data in each of currently readable regions match with each
+  // item given in |expected|.
+  bool VerifyReadableRegions(const std::vector<std::string>& expected) {
+    return VerifyReadableRegions(*sequencer_, expected);
+  }
+
+  bool VerifyIovecs(iovec* iovecs,
+                    size_t num_iovecs,
+                    const std::vector<std::string>& expected) {
+    return VerifyIovecs(*sequencer_, iovecs, num_iovecs, expected);
+  }
+
+  bool VerifyReadableRegion(const QuicStreamSequencer& sequencer,
+                            const std::vector<std::string>& expected) {
+    iovec iovecs[1];
+    if (sequencer.GetReadableRegions(iovecs, 1)) {
+      return (VerifyIovecs(sequencer, iovecs, 1,
+                           std::vector<std::string>{expected[0]}));
+    }
+    return false;
+  }
+
+  // Verify that the data in each of currently readable regions match with each
+  // item given in |expected|.
+  bool VerifyReadableRegions(const QuicStreamSequencer& sequencer,
+                             const std::vector<std::string>& expected) {
+    iovec iovecs[5];
+    size_t num_iovecs =
+        sequencer.GetReadableRegions(iovecs, ABSL_ARRAYSIZE(iovecs));
+    return VerifyReadableRegion(sequencer, expected) &&
+           VerifyIovecs(sequencer, iovecs, num_iovecs, expected);
+  }
+
+  bool VerifyIovecs(const QuicStreamSequencer& /*sequencer*/,
+                    iovec* iovecs,
+                    size_t num_iovecs,
+                    const std::vector<std::string>& expected) {
+    int start_position = 0;
+    for (size_t i = 0; i < num_iovecs; ++i) {
+      if (!VerifyIovec(iovecs[i],
+                       expected[0].substr(start_position, iovecs[i].iov_len))) {
+        return false;
+      }
+      start_position += iovecs[i].iov_len;
+    }
+    return true;
+  }
+
+  bool VerifyIovec(const iovec& iovec, absl::string_view expected) {
+    if (iovec.iov_len != expected.length()) {
+      QUIC_LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs "
+                      << expected.length();
+      return false;
+    }
+    if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
+      QUIC_LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base)
+                      << " vs " << expected;
+      return false;
+    }
+    return true;
+  }
+
+  void OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
+    QuicStreamFrame frame;
+    frame.stream_id = 1;
+    frame.offset = byte_offset;
+    frame.data_buffer = data;
+    frame.data_length = strlen(data);
+    frame.fin = true;
+    sequencer_->OnStreamFrame(frame);
+  }
+
+  void OnFrame(QuicStreamOffset byte_offset, const char* data) {
+    QuicStreamFrame frame;
+    frame.stream_id = 1;
+    frame.offset = byte_offset;
+    frame.data_buffer = data;
+    frame.data_length = strlen(data);
+    frame.fin = false;
+    sequencer_->OnStreamFrame(frame);
+  }
+
+  size_t NumBufferedBytes() {
+    return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get());
+  }
+
+  testing::StrictMock<MockStream> stream_;
+  std::unique_ptr<QuicStreamSequencer> sequencer_;
+};
+
+// TODO(rch): reorder these tests so they build on each other.
+
+TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+
+  OnFrame(0, "abc");
+
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+  // Ignore this - it matches a past packet number and we should not see it
+  // again.
+  OnFrame(0, "def");
+  EXPECT_EQ(0u, NumBufferedBytes());
+}
+
+TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+
+  // Ignore this - it matches a buffered frame.
+  // Right now there's no checking that the payload is consistent.
+  OnFrame(0, "def");
+  EXPECT_EQ(3u, NumBufferedBytes());
+}
+
+TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
+  sequencer_->SetBlockedUntilFlush();
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  sequencer_->SetUnblocked();
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  OnFinFrame(3, "def");
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
+  sequencer_->SetBlockedUntilFlush();
+
+  OnFinFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  sequencer_->SetUnblocked();
+  EXPECT_TRUE(sequencer_->IsClosed());
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(3u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, EmptyFrame) {
+  if (!stream_.version().HasIetfQuicFrames()) {
+    EXPECT_CALL(stream_,
+                OnUnrecoverableError(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _));
+  }
+  OnFrame(0, "");
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFinFrame(0, "");
+  EXPECT_EQ(0u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
+  EXPECT_CALL(stream_, AddBytesConsumed(2));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(2);
+  }));
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(1u, NumBufferedBytes());
+  EXPECT_EQ(2u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
+  OnFrame(3, "abc");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+}
+
+TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
+  // Buffer the first
+  OnFrame(6, "ghi");
+  EXPECT_EQ(3u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+  // Buffer the second
+  OnFrame(3, "def");
+  EXPECT_EQ(6u, NumBufferedBytes());
+  EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(9));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(9);
+  }));
+
+  // Now process all of them at once.
+  OnFrame(0, "abc");
+  EXPECT_EQ(9u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+  EXPECT_EQ(0u, NumBufferedBytes());
+}
+
+TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
+  InSequence s;
+
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFinFrame(0, "abc");
+
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+}
+
+TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
+  OnFinFrame(6, "");
+  EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  OnFrame(3, "def");
+  EXPECT_CALL(stream_, AddBytesConsumed(6));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(6);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  OnFrame(0, "abc");
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
+  OnFinFrame(3, "");
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  EXPECT_CALL(stream_, OnDataAvailable()).WillOnce(testing::Invoke([this]() {
+    ConsumeData(3);
+  }));
+  EXPECT_FALSE(sequencer_->IsClosed());
+  OnFrame(0, "abc");
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
+  char buffer[3];
+
+  OnFinFrame(3, "");
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  EXPECT_FALSE(sequencer_->IsClosed());
+
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0, "abc");
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  iovec iov = {&buffer[0], 3};
+  int bytes_read = sequencer_->Readv(&iov, 1);
+  EXPECT_EQ(3, bytes_read);
+  EXPECT_TRUE(sequencer_->IsClosed());
+}
+
+TEST_F(QuicStreamSequencerTest, MultipleOffsets) {
+  OnFinFrame(3, "");
+  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
+
+  EXPECT_CALL(stream_, OnUnrecoverableError(
+                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
+                           "Stream 1 received new final offset: 1, which is "
+                           "different from close offset: 3"));
+  OnFinFrame(1, "");
+}
+
+class QuicSequencerRandomTest : public QuicStreamSequencerTest {
+ public:
+  using Frame = std::pair<int, std::string>;
+  using FrameList = std::vector<Frame>;
+
+  void CreateFrames() {
+    int payload_size = ABSL_ARRAYSIZE(kPayload) - 1;
+    int remaining_payload = payload_size;
+    while (remaining_payload != 0) {
+      int size = std::min(OneToN(6), remaining_payload);
+      int index = payload_size - remaining_payload;
+      list_.push_back(
+          std::make_pair(index, std::string(kPayload + index, size)));
+      remaining_payload -= size;
+    }
+  }
+
+  QuicSequencerRandomTest() {
+    uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
+    random_.set_seed(seed);
+
+    CreateFrames();
+  }
+
+  int OneToN(int n) { return random_.RandUint64() % n + 1; }
+
+  void ReadAvailableData() {
+    // Read all available data
+    char output[ABSL_ARRAYSIZE(kPayload) + 1];
+    iovec iov;
+    iov.iov_base = output;
+    iov.iov_len = ABSL_ARRAYSIZE(output);
+    int bytes_read = sequencer_->Readv(&iov, 1);
+    EXPECT_NE(0, bytes_read);
+    output_.append(output, bytes_read);
+  }
+
+  std::string output_;
+  // Data which peek at using GetReadableRegion if we back up.
+  std::string peeked_;
+  SimpleRandom random_;
+  FrameList list_;
+};
+
+// All frames are processed as soon as we have sequential data.
+// Infinite buffering, so all frames are acked right away.
+TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
+  EXPECT_CALL(stream_, OnDataAvailable())
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          Invoke(this, &QuicSequencerRandomTest::ReadAvailableData));
+  QuicByteCount total_bytes_consumed = 0;
+  EXPECT_CALL(stream_, AddBytesConsumed(_))
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
+            total_bytes_consumed += bytes;
+          }));
+
+  while (!list_.empty()) {
+    int index = OneToN(list_.size()) - 1;
+    QUIC_LOG(ERROR) << "Sending index " << index << " " << list_[index].second;
+    OnFrame(list_[index].first, list_[index].second.data());
+
+    list_.erase(list_.begin() + index);
+  }
+
+  ASSERT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, output_.size());
+  EXPECT_EQ(kPayload, output_);
+  EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
+}
+
+TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
+  char buffer[10];
+  iovec iov[2];
+  iov[0].iov_base = &buffer[0];
+  iov[0].iov_len = 5;
+  iov[1].iov_base = &buffer[5];
+  iov[1].iov_len = 5;
+
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber());
+  QuicByteCount total_bytes_consumed = 0;
+  EXPECT_CALL(stream_, AddBytesConsumed(_))
+      .Times(AnyNumber())
+      .WillRepeatedly(
+          testing::Invoke([&total_bytes_consumed](QuicByteCount bytes) {
+            total_bytes_consumed += bytes;
+          }));
+
+  while (output_.size() != ABSL_ARRAYSIZE(kPayload) - 1) {
+    if (!list_.empty() && OneToN(2) == 1) {  // Send data
+      int index = OneToN(list_.size()) - 1;
+      OnFrame(list_[index].first, list_[index].second.data());
+      list_.erase(list_.begin() + index);
+    } else {  // Read data
+      bool has_bytes = sequencer_->HasBytesToRead();
+      iovec peek_iov[20];
+      int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20);
+      if (has_bytes) {
+        ASSERT_LT(0, iovs_peeked);
+        ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov));
+      } else {
+        ASSERT_EQ(0, iovs_peeked);
+        ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov));
+      }
+      int total_bytes_to_peek = ABSL_ARRAYSIZE(buffer);
+      for (int i = 0; i < iovs_peeked; ++i) {
+        int bytes_to_peek =
+            std::min<int>(peek_iov[i].iov_len, total_bytes_to_peek);
+        peeked_.append(static_cast<char*>(peek_iov[i].iov_base), bytes_to_peek);
+        total_bytes_to_peek -= bytes_to_peek;
+        if (total_bytes_to_peek == 0) {
+          break;
+        }
+      }
+      int bytes_read = sequencer_->Readv(iov, 2);
+      output_.append(buffer, bytes_read);
+      ASSERT_EQ(output_.size(), peeked_.size());
+    }
+  }
+  EXPECT_EQ(std::string(kPayload), output_);
+  EXPECT_EQ(std::string(kPayload), peeked_);
+  EXPECT_EQ(ABSL_ARRAYSIZE(kPayload) - 1, total_bytes_consumed);
+}
+
+// Same as above, just using a different method for reading.
+TEST_F(QuicStreamSequencerTest, MarkConsumed) {
+  InSequence s;
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(3, "def");
+  OnFrame(6, "ghi");
+
+  // abcdefghi buffered.
+  EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
+
+  // Peek into the data.
+  std::vector<std::string> expected = {"abcdefghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  // Consume 1 byte.
+  EXPECT_CALL(stream_, AddBytesConsumed(1));
+  sequencer_->MarkConsumed(1);
+  // Verify data.
+  std::vector<std::string> expected2 = {"bcdefghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected2));
+  EXPECT_EQ(8u, sequencer_->NumBytesBuffered());
+
+  // Consume 2 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(2));
+  sequencer_->MarkConsumed(2);
+  // Verify data.
+  std::vector<std::string> expected3 = {"defghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected3));
+  EXPECT_EQ(6u, sequencer_->NumBytesBuffered());
+
+  // Consume 5 bytes.
+  EXPECT_CALL(stream_, AddBytesConsumed(5));
+  sequencer_->MarkConsumed(5);
+  // Verify data.
+  std::vector<std::string> expected4{"i"};
+  ASSERT_TRUE(VerifyReadableRegions(expected4));
+  EXPECT_EQ(1u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(9, "jklmnopqrstuvwxyz");
+
+  // Peek into the data.  Only the first chunk should be readable because of the
+  // missing data.
+  std::vector<std::string> expected{"abc"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  // Now, attempt to mark consumed more data than was readable and expect the
+  // stream to be closed.
+  EXPECT_CALL(stream_, ResetWithError(QuicResetStreamError::FromInternal(
+                           QUIC_ERROR_PROCESSING_STREAM)));
+  EXPECT_QUIC_BUG(sequencer_->MarkConsumed(4),
+                  "Invalid argument to MarkConsumed."
+                  " expect to consume: 4, but not enough bytes available.");
+}
+
+TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
+  InSequence s;
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(3, "def");
+  // Missing packet: 6, ghi.
+  OnFrame(9, "jkl");
+
+  std::vector<std::string> expected = {"abcdef"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  EXPECT_CALL(stream_, AddBytesConsumed(6));
+  sequencer_->MarkConsumed(6);
+}
+
+TEST_F(QuicStreamSequencerTest, Move) {
+  InSequence s;
+  EXPECT_CALL(stream_, OnDataAvailable());
+
+  OnFrame(0, "abc");
+  OnFrame(3, "def");
+  OnFrame(6, "ghi");
+
+  // abcdefghi buffered.
+  EXPECT_EQ(9u, sequencer_->NumBytesBuffered());
+
+  // Peek into the data.
+  std::vector<std::string> expected = {"abcdefghi"};
+  ASSERT_TRUE(VerifyReadableRegions(expected));
+
+  QuicStreamSequencer sequencer2(std::move(*sequencer_));
+  ASSERT_TRUE(VerifyReadableRegions(sequencer2, expected));
+}
+
+TEST_F(QuicStreamSequencerTest, OverlappingFramesReceived) {
+  // The peer should never send us non-identical stream frames which contain
+  // overlapping byte ranges - if they do, we close the connection.
+  QuicStreamId id = 1;
+
+  QuicStreamFrame frame1(id, false, 1, absl::string_view("hello"));
+  sequencer_->OnStreamFrame(frame1);
+
+  QuicStreamFrame frame2(id, false, 2, absl::string_view("hello"));
+  EXPECT_CALL(stream_, OnUnrecoverableError(QUIC_OVERLAPPING_STREAM_DATA, _))
+      .Times(0);
+  sequencer_->OnStreamFrame(frame2);
+}
+
+TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) {
+  QuicStreamId id = 1;
+  const std::string data(1000, '.');
+
+  // Received [0, 1000).
+  QuicStreamFrame frame1(id, false, 0, data);
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame1);
+  // Consume [0, 500).
+  EXPECT_CALL(stream_, AddBytesConsumed(500));
+  QuicStreamSequencerTest::ConsumeData(500);
+  EXPECT_EQ(500u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(500u, sequencer_->NumBytesBuffered());
+
+  // Received [500, 1500).
+  QuicStreamFrame frame2(id, false, 500, data);
+  // Do not call OnDataAvailable as there are readable bytes left in the buffer.
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  sequencer_->OnStreamFrame(frame2);
+  // Consume [1000, 1500).
+  EXPECT_CALL(stream_, AddBytesConsumed(1000));
+  QuicStreamSequencerTest::ConsumeData(1000);
+  EXPECT_EQ(1500u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+  // Received [1498, 1503).
+  QuicStreamFrame frame3(id, false, 1498, absl::string_view("hello"));
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame3);
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  QuicStreamSequencerTest::ConsumeData(3);
+  EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+  // Received [1000, 1005).
+  QuicStreamFrame frame4(id, false, 1000, absl::string_view("hello"));
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  sequencer_->OnStreamFrame(frame4);
+  EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, OnDataAvailableWhenReadableBytesIncrease) {
+  sequencer_->set_level_triggered(true);
+  QuicStreamId id = 1;
+
+  // Received [0, 5).
+  QuicStreamFrame frame1(id, false, 0, "hello");
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame1);
+  EXPECT_EQ(5u, sequencer_->NumBytesBuffered());
+
+  // Without consuming the buffer bytes, continue receiving [5, 11).
+  QuicStreamFrame frame2(id, false, 5, " world");
+  // OnDataAvailable should still be called because there are more data to read.
+  EXPECT_CALL(stream_, OnDataAvailable());
+  sequencer_->OnStreamFrame(frame2);
+  EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
+
+  // Without consuming the buffer bytes, continue receiving [12, 13).
+  QuicStreamFrame frame3(id, false, 5, "a");
+  // OnDataAvailable shouldn't be called becasue there are still only 11 bytes
+  // available.
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  sequencer_->OnStreamFrame(frame3);
+  EXPECT_EQ(11u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, ReadSingleFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0u, "abc");
+  std::string actual;
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  sequencer_->Read(&actual);
+  EXPECT_EQ("abc", actual);
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, ReadMultipleFramesWithMissingFrame) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0u, "abc");
+  OnFrame(3u, "def");
+  OnFrame(6u, "ghi");
+  OnFrame(10u, "xyz");  // Byte 9 is missing.
+  std::string actual;
+  EXPECT_CALL(stream_, AddBytesConsumed(9));
+  sequencer_->Read(&actual);
+  EXPECT_EQ("abcdefghi", actual);
+  EXPECT_EQ(3u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, ReadAndAppendToString) {
+  EXPECT_CALL(stream_, OnDataAvailable());
+  OnFrame(0u, "def");
+  OnFrame(3u, "ghi");
+  std::string actual = "abc";
+  EXPECT_CALL(stream_, AddBytesConsumed(6));
+  sequencer_->Read(&actual);
+  EXPECT_EQ("abcdefghi", actual);
+  EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+}
+
+TEST_F(QuicStreamSequencerTest, StopReading) {
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  EXPECT_CALL(stream_, OnFinRead());
+
+  EXPECT_CALL(stream_, AddBytesConsumed(0));
+  sequencer_->StopReading();
+
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFrame(0u, "abc");
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFrame(3u, "def");
+  EXPECT_CALL(stream_, AddBytesConsumed(3));
+  OnFinFrame(6u, "ghi");
+}
+
+TEST_F(QuicStreamSequencerTest, StopReadingWithLevelTriggered) {
+  EXPECT_CALL(stream_, AddBytesConsumed(0));
+  EXPECT_CALL(stream_, AddBytesConsumed(3)).Times(3);
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+  EXPECT_CALL(stream_, OnFinRead());
+
+  sequencer_->set_level_triggered(true);
+  sequencer_->StopReading();
+
+  OnFrame(0u, "abc");
+  OnFrame(3u, "def");
+  OnFinFrame(6u, "ghi");
+}
+
+// Regression test for https://crbug.com/992486.
+TEST_F(QuicStreamSequencerTest, CorruptFinFrames) {
+  EXPECT_CALL(stream_, OnUnrecoverableError(
+                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
+                           "Stream 1 received new final offset: 1, which is "
+                           "different from close offset: 2"));
+
+  OnFinFrame(2u, "");
+  OnFinFrame(0u, "a");
+  EXPECT_FALSE(sequencer_->HasBytesToRead());
+}
+
+// Regression test for crbug.com/1015693
+TEST_F(QuicStreamSequencerTest, ReceiveFinLessThanHighestOffset) {
+  EXPECT_CALL(stream_, OnDataAvailable()).Times(1);
+  EXPECT_CALL(stream_, OnUnrecoverableError(
+                           QUIC_STREAM_SEQUENCER_INVALID_STATE,
+                           "Stream 1 received fin with offset: 0, which "
+                           "reduces current highest offset: 3"));
+  OnFrame(0u, "abc");
+  OnFinFrame(0u, "");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_stream_test.cc b/quiche/quic/core/quic_stream_test.cc
new file mode 100644
index 0000000..8a112ee
--- /dev/null
+++ b/quiche/quic/core/quic_stream_test.cc
@@ -0,0 +1,1738 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_stream.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+const char kData1[] = "FooAndBar";
+const char kData2[] = "EepAndBaz";
+const QuicByteCount kDataLen = 9;
+
+class TestStream : public QuicStream {
+ public:
+  TestStream(QuicStreamId id, QuicSession* session, StreamType type)
+      : QuicStream(id, session, /*is_static=*/false, type) {
+    sequencer()->set_level_triggered(true);
+  }
+
+  TestStream(PendingStream* pending, QuicSession* session, bool is_static)
+      : QuicStream(pending, session, is_static) {}
+
+  MOCK_METHOD(void, OnDataAvailable, (), (override));
+
+  MOCK_METHOD(void, OnCanWriteNewData, (), (override));
+
+  MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
+
+  using QuicStream::CanWriteNewData;
+  using QuicStream::CanWriteNewDataAfterData;
+  using QuicStream::CloseWriteSide;
+  using QuicStream::fin_buffered;
+  using QuicStream::MaybeSendStopSending;
+  using QuicStream::OnClose;
+  using QuicStream::WriteMemSlices;
+  using QuicStream::WriteOrBufferData;
+
+ private:
+  std::string data_;
+};
+
+class QuicStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicStreamTest()
+      : zero_(QuicTime::Delta::Zero()),
+        supported_versions_(AllSupportedVersions()) {}
+
+  void Initialize(Perspective perspective = Perspective::IS_SERVER) {
+    ParsedQuicVersionVector version_vector;
+    version_vector.push_back(GetParam());
+    connection_ = new StrictMock<MockQuicConnection>(
+        &helper_, &alarm_factory_, perspective, version_vector);
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
+    session_->Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_->config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
+    session_->OnConfigNegotiated();
+
+    stream_ = new StrictMock<TestStream>(kTestStreamId, session_.get(),
+                                         BIDIRECTIONAL);
+    EXPECT_NE(nullptr, stream_);
+    // session_ now owns stream_.
+    session_->ActivateStream(absl::WrapUnique(stream_));
+    // Ignore resetting when session_ is terminated.
+    EXPECT_CALL(*session_, MaybeSendStopSendingFrame(kTestStreamId, _))
+        .Times(AnyNumber());
+    EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _))
+        .Times(AnyNumber());
+    write_blocked_list_ =
+        QuicSessionPeer::GetWriteBlockedStreams(session_.get());
+  }
+
+  bool fin_sent() { return stream_->fin_sent(); }
+  bool rst_sent() { return stream_->rst_sent(); }
+
+  bool HasWriteBlockedStreams() {
+    return write_blocked_list_->HasWriteBlockedSpecialStream() ||
+           write_blocked_list_->HasWriteBlockedDataStreams();
+  }
+
+  QuicConsumedData CloseStreamOnWriteError(
+      QuicStreamId id, QuicByteCount /*write_length*/,
+      QuicStreamOffset /*offset*/, StreamSendingState /*state*/,
+      TransmissionType /*type*/, absl::optional<EncryptionLevel> /*level*/) {
+    session_->ResetStream(id, QUIC_STREAM_CANCELLED);
+    return QuicConsumedData(1, false);
+  }
+
+  bool ClearResetStreamFrame(const QuicFrame& frame) {
+    EXPECT_EQ(RST_STREAM_FRAME, frame.type);
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+  bool ClearStopSendingFrame(const QuicFrame& frame) {
+    EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+ protected:
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnection* connection_;
+  std::unique_ptr<MockQuicSession> session_;
+  StrictMock<TestStream>* stream_;
+  QuicWriteBlockedList* write_blocked_list_;
+  QuicTime::Delta zero_;
+  ParsedQuicVersionVector supported_versions_;
+  QuicStreamId kTestStreamId =
+      GetNthClientInitiatedBidirectionalStreamId(GetParam().transport_version,
+                                                 1);
+  const QuicStreamId kTestPendingStreamId =
+      GetNthClientInitiatedUnidirectionalStreamId(GetParam().transport_version,
+                                                  1);
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicStreamTests, QuicStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+using PendingStreamTest = QuicStreamTest;
+
+INSTANTIATE_TEST_SUITE_P(PendingStreamTests, PendingStreamTest,
+                         ::testing::ValuesIn(CurrentSupportedHttp3Versions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(PendingStreamTest, PendingStreamStaticness) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_FALSE(stream.is_static());
+
+  PendingStream pending2(kTestPendingStreamId + 4, session_.get());
+  TestStream stream2(&pending2, session_.get(), true);
+  EXPECT_TRUE(stream2.is_static());
+}
+
+TEST_P(PendingStreamTest, PendingStreamType) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTypeOnClient) {
+  Initialize(Perspective::IS_CLIENT);
+
+  QuicStreamId server_initiated_pending_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(session_->transport_version(),
+                                                  1);
+  PendingStream pending(server_initiated_pending_stream_id, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTooMuchData) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  // Receive a stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicStreamFrame frame(kTestPendingStreamId, false,
+                        kInitialSessionFlowControlWindowForTest + 1, ".");
+
+  // Stream should not accept the frame, and the connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  pending.OnStreamFrame(frame);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTooMuchDataInRstStream) {
+  Initialize();
+
+  PendingStream pending1(kTestPendingStreamId, session_.get());
+  // Receive a rst stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicRstStreamFrame frame1(kInvalidControlFrameId, kTestPendingStreamId,
+                            QUIC_STREAM_CANCELLED,
+                            kInitialSessionFlowControlWindowForTest + 1);
+
+  // Pending stream should not accept the frame, and the connection should be
+  // closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  pending1.OnRstStreamFrame(frame1);
+
+  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      session_->transport_version(), Perspective::IS_CLIENT);
+  PendingStream pending2(bidirection_stream_id, session_.get());
+  // Receive a rst stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicRstStreamFrame frame2(kInvalidControlFrameId, bidirection_stream_id,
+                            QUIC_STREAM_CANCELLED,
+                            kInitialSessionFlowControlWindowForTest + 1);
+  // Bidirectional Pending stream should not accept the frame, and the
+  // connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  pending2.OnRstStreamFrame(frame2);
+}
+
+TEST_P(PendingStreamTest, PendingStreamRstStream) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  QuicStreamOffset final_byte_offset = 7;
+  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestPendingStreamId,
+                           QUIC_STREAM_CANCELLED, final_byte_offset);
+
+  // Pending stream should accept the frame and not close the connection.
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  pending.OnRstStreamFrame(frame);
+}
+
+TEST_P(PendingStreamTest, PendingStreamWindowUpdate) {
+  Initialize();
+
+  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      session_->transport_version(), Perspective::IS_CLIENT);
+  PendingStream pending(bidirection_stream_id, session_.get());
+  QuicWindowUpdateFrame frame(kInvalidControlFrameId, bidirection_stream_id,
+                              kDefaultFlowControlSendWindow * 2);
+  pending.OnWindowUpdateFrame(frame);
+  TestStream stream(&pending, session_.get(), false);
+
+  EXPECT_EQ(QuicStreamPeer::SendWindowSize(&stream),
+            kDefaultFlowControlSendWindow * 2);
+}
+
+TEST_P(PendingStreamTest, PendingStreamStopSending) {
+  Initialize();
+
+  QuicStreamId bidirection_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+      session_->transport_version(), Perspective::IS_CLIENT);
+  PendingStream pending(bidirection_stream_id, session_.get());
+  QuicResetStreamError error =
+      QuicResetStreamError::FromInternal(QUIC_STREAM_INTERNAL_ERROR);
+  pending.OnStopSending(error);
+  EXPECT_TRUE(pending.GetStopSendingErrorCode());
+  auto actual_error = *pending.GetStopSendingErrorCode();
+  EXPECT_EQ(actual_error, error);
+}
+
+TEST_P(PendingStreamTest, FromPendingStream) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+
+  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
+  pending.OnStreamFrame(frame);
+  pending.OnStreamFrame(frame);
+  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
+  pending.OnStreamFrame(frame2);
+
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(3, stream.num_frames_received());
+  EXPECT_EQ(3u, stream.stream_bytes_read());
+  EXPECT_EQ(1, stream.num_duplicate_frames_received());
+  EXPECT_EQ(true, stream.fin_received());
+  EXPECT_EQ(frame2.offset + 1, stream.highest_received_byte_offset());
+  EXPECT_EQ(frame2.offset + 1,
+            session_->flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(PendingStreamTest, FromPendingStreamThenData) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
+
+  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
+  pending.OnStreamFrame(frame);
+
+  auto stream = new TestStream(&pending, session_.get(), false);
+  session_->ActivateStream(absl::WrapUnique(stream));
+
+  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
+  stream->OnStreamFrame(frame2);
+
+  EXPECT_EQ(2, stream->num_frames_received());
+  EXPECT_EQ(2u, stream->stream_bytes_read());
+  EXPECT_EQ(true, stream->fin_received());
+  EXPECT_EQ(frame2.offset + 1, stream->highest_received_byte_offset());
+  EXPECT_EQ(frame2.offset + 1,
+            session_->flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicStreamTest, WriteAllData) {
+  Initialize();
+
+  QuicByteCount length =
+      1 + QuicPacketCreator::StreamFramePacketOverhead(
+              connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
+              PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+              !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
+  connection_->SetMaxPacketLength(length);
+
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_FALSE(HasWriteBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, NoBlockingIfNoDataOrFin) {
+  Initialize();
+
+  // Write no data and no fin.  If we consume nothing we should not be write
+  // blocked.
+  EXPECT_QUIC_BUG(
+      stream_->WriteOrBufferData(absl::string_view(), false, nullptr), "");
+  EXPECT_FALSE(HasWriteBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, BlockIfOnlySomeDataConsumed) {
+  Initialize();
+
+  // Write some data and no fin.  If we consume some but not all of the data,
+  // we should be write blocked a not all the data was consumed.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+}
+
+TEST_P(QuicStreamTest, BlockIfFinNotConsumedWithData) {
+  Initialize();
+
+  // Write some data and no fin.  If we consume all the data but not the fin,
+  // we should be write blocked because the fin was not consumed.
+  // (This should never actually happen as the fin should be sent out with the
+  // last data)
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, BlockIfSoloFinNotConsumed) {
+  Initialize();
+
+  // Write no data and a fin.  If we consume nothing we should be write blocked,
+  // as the fin was not consumed.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, false)));
+  stream_->WriteOrBufferData(absl::string_view(), true, nullptr);
+  ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, CloseOnPartialWrite) {
+  Initialize();
+
+  // Write some data and no fin. However, while writing the data
+  // close the stream and verify that MarkConnectionLevelWriteBlocked does not
+  // crash with an unknown stream.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(Invoke(this, &QuicStreamTest::CloseStreamOnWriteError));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), false, nullptr);
+  ASSERT_EQ(0u, write_blocked_list_->NumBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, WriteOrBufferData) {
+  Initialize();
+
+  EXPECT_FALSE(HasWriteBlockedStreams());
+  QuicByteCount length =
+      1 + QuicPacketCreator::StreamFramePacketOverhead(
+              connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
+              PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+              !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0,
+              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
+  connection_->SetMaxPacketLength(length);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, stream_->BufferedDataBytes());
+  EXPECT_TRUE(HasWriteBlockedStreams());
+
+  // Queue a bytes_consumed write.
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  EXPECT_EQ(10u, stream_->BufferedDataBytes());
+  // Make sure we get the tail of the first write followed by the bytes_consumed
+  InSequence s;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1,
+                                     NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*stream_, OnCanWriteNewData());
+  stream_->OnCanWrite();
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // And finally the end of the bytes_consumed.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2,
+                                     NO_FIN, NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*stream_, OnCanWriteNewData());
+  stream_->OnCanWrite();
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, WriteOrBufferDataReachStreamLimit) {
+  Initialize();
+  std::string data("aaaaa");
+  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
+                                        stream_);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  EXPECT_QUIC_BUG(stream_->WriteOrBufferData("a", false, nullptr),
+                  "Write too many data via stream");
+}
+
+TEST_P(QuicStreamTest, ConnectionCloseAfterStreamClose) {
+  Initialize();
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(session_->transport_version())) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_->OnStopSendingFrame(stop_sending);
+  }
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
+  EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
+  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
+                              ConnectionCloseSource::FROM_SELF);
+  EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
+  EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
+}
+
+TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
+  // For flow control accounting, a stream must send either a FIN or a RST frame
+  // before termination.
+  // Test that if no FIN has been sent, we send a RST.
+
+  Initialize();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Write some data, with no FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 1), false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Now close the stream, and expect that we send a RST.
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _));
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(session_->transport_version())) {
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_->OnStopSendingFrame(stop_sending);
+  }
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_FALSE(fin_sent());
+  EXPECT_TRUE(rst_sent());
+}
+
+TEST_P(QuicStreamTest, RstNotSentIfFinSent) {
+  // For flow control accounting, a stream must send either a FIN or a RST frame
+  // before termination.
+  // Test that if a FIN has been sent, we don't also send a RST.
+
+  Initialize();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Write some data, with FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 1u, 0u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 1), true, nullptr);
+  EXPECT_TRUE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Now close the stream, and expect that we do not send a RST.
+  QuicStreamPeer::CloseReadSide(stream_);
+  stream_->CloseWriteSide();
+  EXPECT_TRUE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+}
+
+TEST_P(QuicStreamTest, OnlySendOneRst) {
+  // For flow control accounting, a stream must send either a FIN or a RST frame
+  // before termination.
+  // Test that if a stream sends a RST, it doesn't send an additional RST during
+  // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
+
+  Initialize();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_FALSE(rst_sent());
+
+  // Reset the stream.
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, _, _)).Times(1);
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_FALSE(fin_sent());
+  EXPECT_TRUE(rst_sent());
+
+  // Now close the stream (any further resets being sent would break the
+  // expectation above).
+  QuicStreamPeer::CloseReadSide(stream_);
+  stream_->CloseWriteSide();
+  EXPECT_FALSE(fin_sent());
+  EXPECT_TRUE(rst_sent());
+}
+
+TEST_P(QuicStreamTest, StreamFlowControlMultipleWindowUpdates) {
+  Initialize();
+
+  // If we receive multiple WINDOW_UPDATES (potentially out of order), then we
+  // want to make sure we latch the largest offset we see.
+
+  // Initially should be default.
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            QuicStreamPeer::SendWindowOffset(stream_));
+
+  // Check a single WINDOW_UPDATE results in correct offset.
+  QuicWindowUpdateFrame window_update_1(kInvalidControlFrameId, stream_->id(),
+                                        kMinimumFlowControlSendWindow + 5);
+  stream_->OnWindowUpdateFrame(window_update_1);
+  EXPECT_EQ(window_update_1.max_data,
+            QuicStreamPeer::SendWindowOffset(stream_));
+
+  // Now send a few more WINDOW_UPDATES and make sure that only the largest is
+  // remembered.
+  QuicWindowUpdateFrame window_update_2(kInvalidControlFrameId, stream_->id(),
+                                        1);
+  QuicWindowUpdateFrame window_update_3(kInvalidControlFrameId, stream_->id(),
+                                        kMinimumFlowControlSendWindow + 10);
+  QuicWindowUpdateFrame window_update_4(kInvalidControlFrameId, stream_->id(),
+                                        5678);
+  stream_->OnWindowUpdateFrame(window_update_2);
+  stream_->OnWindowUpdateFrame(window_update_3);
+  stream_->OnWindowUpdateFrame(window_update_4);
+  EXPECT_EQ(window_update_3.max_data,
+            QuicStreamPeer::SendWindowOffset(stream_));
+}
+
+TEST_P(QuicStreamTest, FrameStats) {
+  Initialize();
+
+  EXPECT_EQ(0, stream_->num_frames_received());
+  EXPECT_EQ(0, stream_->num_duplicate_frames_received());
+  QuicStreamFrame frame(stream_->id(), false, 0, ".");
+  EXPECT_CALL(*stream_, OnDataAvailable()).Times(2);
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(1, stream_->num_frames_received());
+  EXPECT_EQ(0, stream_->num_duplicate_frames_received());
+  stream_->OnStreamFrame(frame);
+  EXPECT_EQ(2, stream_->num_frames_received());
+  EXPECT_EQ(1, stream_->num_duplicate_frames_received());
+  QuicStreamFrame frame2(stream_->id(), false, 1, "abc");
+  stream_->OnStreamFrame(frame2);
+}
+
+// Verify that when we receive a packet which violates flow control (i.e. sends
+// too much data on the stream) that the stream sequencer never sees this frame,
+// as we check for violation and close the connection early.
+TEST_P(QuicStreamTest, StreamSequencerNeverSeesPacketsViolatingFlowControl) {
+  Initialize();
+
+  // Receive a stream frame that violates flow control: the byte offset is
+  // higher than the receive window offset.
+  QuicStreamFrame frame(stream_->id(), false,
+                        kInitialSessionFlowControlWindowForTest + 1, ".");
+  EXPECT_GT(frame.offset, QuicStreamPeer::ReceiveWindowOffset(stream_));
+
+  // Stream should not accept the frame, and the connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamFrame(frame);
+}
+
+// Verify that after the consumer calls StopReading(), the stream still sends
+// flow control updates.
+TEST_P(QuicStreamTest, StopReadingSendsFlowControl) {
+  Initialize();
+
+  stream_->StopReading();
+
+  // Connection should not get terminated due to flow control errors.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
+      .Times(0);
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+
+  std::string data(1000, 'x');
+  for (QuicStreamOffset offset = 0;
+       offset < 2 * kInitialStreamFlowControlWindowForTest;
+       offset += data.length()) {
+    QuicStreamFrame frame(stream_->id(), false, offset, data);
+    stream_->OnStreamFrame(frame);
+  }
+  EXPECT_LT(kInitialStreamFlowControlWindowForTest,
+            QuicStreamPeer::ReceiveWindowOffset(stream_));
+}
+
+TEST_P(QuicStreamTest, FinalByteOffsetFromFin) {
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+
+  QuicStreamFrame stream_frame_no_fin(stream_->id(), false, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_no_fin);
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+
+  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_with_fin);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, FinalByteOffsetFromRst) {
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, InvalidFinalByteOffsetFromRst) {
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 0xFFFFFFFFFFFF);
+  // Stream should not accept the frame, and the connection should be closed.
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
+  stream_->OnStreamReset(rst_frame);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) {
+  // When receiving Trailers, an empty stream frame is created with the FIN set,
+  // and is passed to OnStreamFrame. The Trailers may be sent in advance of
+  // queued body bytes being sent, and thus the final byte offset may exceed
+  // current flow control limits. Flow control should only be concerned with
+  // data that has actually been sent/received, so verify that flow control
+  // ignores such a stream frame.
+  Initialize();
+
+  EXPECT_FALSE(stream_->HasReceivedFinalOffset());
+  const QuicStreamOffset kByteOffsetExceedingFlowControlWindow =
+      kInitialSessionFlowControlWindowForTest + 1;
+  const QuicStreamOffset current_stream_flow_control_offset =
+      QuicStreamPeer::ReceiveWindowOffset(stream_);
+  const QuicStreamOffset current_connection_flow_control_offset =
+      QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller());
+  ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
+            current_stream_flow_control_offset);
+  ASSERT_GT(kByteOffsetExceedingFlowControlWindow,
+            current_connection_flow_control_offset);
+  QuicStreamFrame zero_length_stream_frame_with_fin(
+      stream_->id(), /*fin=*/true, kByteOffsetExceedingFlowControlWindow,
+      absl::string_view());
+  EXPECT_EQ(0, zero_length_stream_frame_with_fin.data_length);
+
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  stream_->OnStreamFrame(zero_length_stream_frame_with_fin);
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+
+  // The flow control receive offset values should not have changed.
+  EXPECT_EQ(current_stream_flow_control_offset,
+            QuicStreamPeer::ReceiveWindowOffset(stream_));
+  EXPECT_EQ(
+      current_connection_flow_control_offset,
+      QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller()));
+}
+
+TEST_P(QuicStreamTest, OnStreamResetOffsetOverflow) {
+  Initialize();
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, kMaxStreamLength + 1);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  stream_->OnStreamReset(rst_frame);
+}
+
+TEST_P(QuicStreamTest, OnStreamFrameUpperLimit) {
+  Initialize();
+
+  // Modify receive window offset and sequencer buffer total_bytes_read_ to
+  // avoid flow control violation.
+  QuicStreamPeer::SetReceiveWindowOffset(stream_, kMaxStreamLength + 5u);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+                                                 kMaxStreamLength + 5u);
+  QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
+      QuicStreamPeer::sequencer(stream_), kMaxStreamLength - 10u);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+      .Times(0);
+  QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength - 1, ".");
+  stream_->OnStreamFrame(stream_frame);
+  QuicStreamFrame stream_frame2(stream_->id(), true, kMaxStreamLength, "");
+  stream_->OnStreamFrame(stream_frame2);
+}
+
+TEST_P(QuicStreamTest, StreamTooLong) {
+  Initialize();
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+      .Times(1);
+  QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength, ".");
+  EXPECT_QUIC_PEER_BUG(
+      stream_->OnStreamFrame(stream_frame),
+      absl::StrCat("Receive stream frame on stream ", stream_->id(),
+                   " reaches max stream length"));
+}
+
+TEST_P(QuicStreamTest, SetDrainingIncomingOutgoing) {
+  // Don't have incoming data consumed.
+  Initialize();
+
+  // Incoming data with FIN.
+  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_with_fin);
+  // The FIN has been received but not consumed.
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Outgoing data with FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) {
+  // Don't have incoming data consumed.
+  Initialize();
+
+  // Outgoing data with FIN.
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(absl::string_view(kData1, 2), true, nullptr);
+  EXPECT_TRUE(stream_->write_side_closed());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Incoming data with FIN.
+  QuicStreamFrame stream_frame_with_fin(stream_->id(), true, 1234, ".");
+  stream_->OnStreamFrame(stream_frame_with_fin);
+  // The FIN has been received but not consumed.
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicStreamTest, EarlyResponseFinHandling) {
+  // Verify that if the server completes the response before reading the end of
+  // the request, the received FIN is recorded.
+
+  Initialize();
+  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+
+  // Receive data for the request.
+  EXPECT_CALL(*stream_, OnDataAvailable()).Times(1);
+  QuicStreamFrame frame1(stream_->id(), false, 0, "Start");
+  stream_->OnStreamFrame(frame1);
+  // When QuicSimpleServerStream sends the response, it calls
+  // QuicStream::CloseReadSide() first.
+  QuicStreamPeer::CloseReadSide(stream_);
+  // Send data and FIN for the response.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+  // Receive remaining data and FIN for the request.
+  QuicStreamFrame frame2(stream_->id(), true, 0, "End");
+  stream_->OnStreamFrame(frame2);
+  EXPECT_TRUE(stream_->fin_received());
+  EXPECT_TRUE(stream_->HasReceivedFinalOffset());
+}
+
+TEST_P(QuicStreamTest, StreamWaitsForAcks) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  // Stream is not waiting for acks initially.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+
+  // Send kData1.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  // Stream is not waiting for acks as all sent data is acked.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // Send kData2.
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Send FIN.
+  stream_->WriteOrBufferData("", true, nullptr);
+  // Fin only frame is not stored in send buffer.
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // kData2 is retransmitted.
+  stream_->OnStreamFrameRetransmitted(9, 9, false);
+
+  // kData2 is acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  // Stream is waiting for acks as FIN is not acked.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // FIN is acked.
+  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  // Send data.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData("", true, nullptr);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  // FIN is not acked yet.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState());
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, CancelStream) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Cancel stream.
+  stream_->MaybeSendStopSending(QUIC_STREAM_NO_ERROR);
+  // stream still waits for acks as the error code is QUIC_STREAM_NO_ERROR, and
+  // data is going to be retransmitted.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(*connection_,
+              OnStreamReset(stream_->id(), QUIC_STREAM_CANCELLED));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .Times(AtLeast(1))
+      .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        session_->ReallyMaybeSendRstStreamFrame(
+            stream_->id(), QUIC_STREAM_CANCELLED,
+            stream_->stream_bytes_written());
+      }));
+
+  stream_->Reset(QUIC_STREAM_CANCELLED);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Stream stops waiting for acks as data is not going to be retransmitted.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    // In IETF QUIC, receiving a RESET_STREAM will only close the read side. The
+    // stream itself is not closed and will not send reset.
+    return;
+  }
+
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  // RST_STREAM received.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 9);
+
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
+  stream_->OnStreamReset(rst_frame);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Stream stops waiting for acks as it does not finish sending and rst is
+  // sent.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, true, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // RST_STREAM received.
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  // Stream still waits for acks as it finishes sending and has unacked data.
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+}
+
+TEST_P(QuicStreamTest, ConnectionClosed) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          stream_->id(),
+          QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 9));
+  QuicConnectionPeer::SetConnectionClose(connection_);
+  stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
+                              ConnectionCloseSource::FROM_SELF);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Stream stops waiting for acks as connection is going to close.
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, CanWriteNewDataAfterData) {
+  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
+  Initialize();
+  EXPECT_TRUE(stream_->CanWriteNewDataAfterData(99));
+  EXPECT_FALSE(stream_->CanWriteNewDataAfterData(100));
+}
+
+TEST_P(QuicStreamTest, WriteBufferedData) {
+  // Set buffered data low water mark to be 100.
+  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
+
+  Initialize();
+  std::string data(1024, 'a');
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  // Testing WriteOrBufferData.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->WriteOrBufferData(data, false, nullptr);
+  stream_->WriteOrBufferData(data, false, nullptr);
+  stream_->WriteOrBufferData(data, false, nullptr);
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+
+  // Verify all data is saved.
+  EXPECT_EQ(3 * data.length() - 100, stream_->BufferedDataBytes());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // Buffered data size > threshold, do not ask upper layer for more data.
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
+  stream_->OnCanWrite();
+  EXPECT_EQ(3 * data.length() - 200, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->CanWriteNewData());
+
+  // Send buffered data to make buffered data size < threshold.
+  QuicByteCount data_to_write =
+      3 * data.length() - 200 -
+      GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
+        return session_->ConsumeData(stream_->id(), data_to_write, 200u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // Buffered data size < threshold, ask upper layer for more data.
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(static_cast<uint64_t>(
+                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
+            stream_->BufferedDataBytes());
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  // Flush all buffered data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(0u, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->HasBufferedData());
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  // Testing Writev.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, false)));
+  struct iovec iov = {const_cast<char*>(data.data()), data.length()};
+  quiche::QuicheMemSliceStorage storage(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
+
+  // There is no buffered data before, all data should be consumed without
+  // respecting buffered data upper limit.
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->CanWriteNewData());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  quiche::QuicheMemSliceStorage storage2(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  consumed = stream_->WriteMemSlices(storage2.ToSpan(), false);
+  // No Data can be consumed as buffered data is beyond upper limit.
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
+
+  data_to_write =
+      data.length() - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
+        return session_->ConsumeData(stream_->id(), data_to_write, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(static_cast<uint64_t>(
+                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
+            stream_->BufferedDataBytes());
+  EXPECT_TRUE(stream_->CanWriteNewData());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  // All data can be consumed as buffered data is below upper limit.
+  quiche::QuicheMemSliceStorage storage3(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  consumed = stream_->WriteMemSlices(storage3.ToSpan(), false);
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(data.length() + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
+            stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->CanWriteNewData());
+}
+
+TEST_P(QuicStreamTest, WritevDataReachStreamLimit) {
+  Initialize();
+  std::string data("aaaaa");
+  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
+                                        stream_);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  struct iovec iov = {const_cast<char*>(data.data()), 5u};
+  quiche::QuicheMemSliceStorage storage(
+      &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      1024);
+  QuicConsumedData consumed = stream_->WriteMemSlices(storage.ToSpan(), false);
+  EXPECT_EQ(data.length(), consumed.bytes_consumed);
+  struct iovec iov2 = {const_cast<char*>(data.data()), 1u};
+  quiche::QuicheMemSliceStorage storage2(
+      &iov2, 1,
+      session_->connection()->helper()->GetStreamSendBufferAllocator(), 1024);
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  EXPECT_QUIC_BUG(stream_->WriteMemSlices(storage2.ToSpan(), false),
+                  "Write too many data via stream");
+}
+
+TEST_P(QuicStreamTest, WriteMemSlices) {
+  // Set buffered data low water mark to be 100.
+  SetQuicFlag(FLAGS_quic_buffered_data_threshold, 100);
+
+  Initialize();
+  constexpr QuicByteCount kDataSize = 1024;
+  quiche::QuicheBufferAllocator* allocator =
+      connection_->helper()->GetStreamSendBufferAllocator();
+  std::vector<quiche::QuicheMemSlice> vector1;
+  vector1.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  vector1.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  std::vector<quiche::QuicheMemSlice> vector2;
+  vector2.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  vector2.push_back(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer(allocator, kDataSize)));
+  absl::Span<quiche::QuicheMemSlice> span1(vector1);
+  absl::Span<quiche::QuicheMemSlice> span2(vector2);
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // There is no buffered data before, all data should be consumed.
+  QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
+  EXPECT_EQ(2048u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->fin_buffered());
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  // No Data can be consumed as buffered data is beyond upper limit.
+  consumed = stream_->WriteMemSlices(span2, true);
+  EXPECT_EQ(0u, consumed.bytes_consumed);
+  EXPECT_FALSE(consumed.fin_consumed);
+  EXPECT_EQ(2 * kDataSize - 100, stream_->BufferedDataBytes());
+  EXPECT_FALSE(stream_->fin_buffered());
+
+  QuicByteCount data_to_write =
+      2 * kDataSize - 100 - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
+        return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_EQ(static_cast<uint64_t>(
+                GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
+            stream_->BufferedDataBytes());
+  // Try to write slices2 again.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
+  consumed = stream_->WriteMemSlices(span2, true);
+  EXPECT_EQ(2048u, consumed.bytes_consumed);
+  EXPECT_TRUE(consumed.fin_consumed);
+  EXPECT_EQ(2 * kDataSize + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
+            stream_->BufferedDataBytes());
+  EXPECT_TRUE(stream_->fin_buffered());
+
+  // Flush all buffered data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
+  EXPECT_FALSE(stream_->HasBufferedData());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
+  Initialize();
+  QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_);
+  std::vector<std::pair<char*, size_t>> buffers;
+  quiche::QuicheMemSlice slice1 = MemSliceFromString("12345");
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  // There is no buffered data before, all data should be consumed.
+  QuicConsumedData consumed = stream_->WriteMemSlice(std::move(slice1), false);
+  EXPECT_EQ(5u, consumed.bytes_consumed);
+
+  quiche::QuicheMemSlice slice2 = MemSliceFromString("6");
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+  EXPECT_QUIC_BUG(stream_->WriteMemSlice(std::move(slice2), false),
+                  "Write too many data via stream");
+}
+
+TEST_P(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
+  Initialize();
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+
+  // Send [0, 27) and fin.
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, true, nullptr);
+  EXPECT_EQ(3u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+  // Ack [0, 9), [5, 22) and [18, 26)
+  // Verify [0, 9) 9 bytes are acked.
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [9, 22) 13 bytes are acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(13u, newly_acked_length);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  // Verify [22, 26) 4 bytes are acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(4u, newly_acked_length);
+  EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // Ack [0, 27). Verify [26, 27) 1 byte is acked.
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(1u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_TRUE(stream_->IsWaitingForAcks());
+  EXPECT_TRUE(session_->HasUnackedStreamData());
+
+  // Ack Fin.
+  EXPECT_CALL(*stream_, OnWriteSideInDataRecvdState()).Times(1);
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+
+  // Ack [10, 27) and fin. No new data is acked.
+  EXPECT_FALSE(
+      stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
+                                  QuicTime::Zero(), &newly_acked_length));
+  EXPECT_EQ(0u, newly_acked_length);
+  EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
+  EXPECT_FALSE(stream_->IsWaitingForAcks());
+  EXPECT_FALSE(session_->HasUnackedStreamData());
+}
+
+TEST_P(QuicStreamTest, OnStreamFrameLost) {
+  Initialize();
+
+  // Send [0, 9).
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  EXPECT_FALSE(stream_->HasBufferedData());
+  EXPECT_TRUE(stream_->IsStreamFrameOutstanding(0, 9, false));
+
+  // Try to send [9, 27), but connection is blocked.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, false)));
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  stream_->WriteOrBufferData(kData2, false, nullptr);
+  EXPECT_TRUE(stream_->HasBufferedData());
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+
+  // Lost [0, 9). When stream gets a chance to write, only lost data is
+  // transmitted.
+  stream_->OnStreamFrameLost(0, 9, false);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  EXPECT_TRUE(stream_->HasBufferedData());
+
+  // This OnCanWrite causes [9, 27) to be sent.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasBufferedData());
+
+  // Send a fin only frame.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData("", true, nullptr);
+
+  // Lost [9, 27) and fin.
+  stream_->OnStreamFrameLost(9, 18, false);
+  stream_->OnStreamFrameLost(27, 0, true);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+
+  // Ack [9, 18).
+  QuicByteCount newly_acked_length = 0;
+  EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
+                                          QuicTime::Zero(),
+                                          &newly_acked_length));
+  EXPECT_EQ(9u, newly_acked_length);
+  EXPECT_FALSE(stream_->IsStreamFrameOutstanding(9, 3, false));
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+  // This OnCanWrite causes [18, 27) and fin to be retransmitted. Verify fin can
+  // be bundled with data.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 9u, 18u, FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  stream_->OnCanWrite();
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  // Lost [9, 18) again, but it is not considered as lost because kData2
+  // has been acked.
+  stream_->OnStreamFrameLost(9, 9, false);
+  EXPECT_FALSE(stream_->HasPendingRetransmission());
+  EXPECT_TRUE(stream_->IsStreamFrameOutstanding(27, 0, true));
+}
+
+TEST_P(QuicStreamTest, CannotBundleLostFin) {
+  Initialize();
+
+  // Send [0, 18) and fin.
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData2, true, nullptr);
+
+  // Lost [0, 9) and fin.
+  stream_->OnStreamFrameLost(0, 9, false);
+  stream_->OnStreamFrameLost(18, 0, true);
+
+  // Retransmit lost data. Verify [0, 9) and fin are retransmitted in two
+  // frames.
+  InSequence s;
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, true)));
+  stream_->OnCanWrite();
+}
+
+TEST_P(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
+  Initialize();
+
+  // Set the config to a small value so that a newly created stream has small
+  // send flow control window.
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
+                                                            100);
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+      session_->config(), 100);
+  auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
+                                   GetParam().transport_version, 2),
+                               session_.get(), BIDIRECTIONAL);
+  session_->ActivateStream(absl::WrapUnique(stream));
+
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  std::string data(1024, '.');
+  stream->WriteOrBufferData(data, false, nullptr);
+  EXPECT_FALSE(HasWriteBlockedStreams());
+
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
+                                      1234);
+
+  stream->OnWindowUpdateFrame(window_update);
+  // Verify stream is marked connection level write blocked.
+  EXPECT_TRUE(HasWriteBlockedStreams());
+  EXPECT_TRUE(stream->HasBufferedData());
+}
+
+// Regression test for b/73282665.
+TEST_P(QuicStreamTest,
+       MarkConnectionLevelWriteBlockedOnWindowUpdateFrameWithNoBufferedData) {
+  Initialize();
+
+  // Set the config to a small value so that a newly created stream has small
+  // send flow control window.
+  QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
+                                                            100);
+  QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+      session_->config(), 100);
+  auto stream = new TestStream(GetNthClientInitiatedBidirectionalStreamId(
+                                   GetParam().transport_version, 2),
+                               session_.get(), BIDIRECTIONAL);
+  session_->ActivateStream(absl::WrapUnique(stream));
+
+  std::string data(100, '.');
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WriteControlFrame(_, _))
+      .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+  stream->WriteOrBufferData(data, false, nullptr);
+  EXPECT_FALSE(HasWriteBlockedStreams());
+
+  QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream_->id(),
+                                      120);
+  stream->OnWindowUpdateFrame(window_update);
+  EXPECT_FALSE(stream->HasBufferedData());
+  // Verify stream is marked as blocked although there is no buffered data.
+  EXPECT_TRUE(HasWriteBlockedStreams());
+}
+
+TEST_P(QuicStreamTest, RetransmitStreamData) {
+  Initialize();
+  InSequence s;
+
+  // Send [0, 18) with fin.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+      .Times(2)
+      .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  stream_->WriteOrBufferData(kData1, false, nullptr);
+  stream_->WriteOrBufferData(kData1, true, nullptr);
+  // Ack [10, 13).
+  QuicByteCount newly_acked_length = 0;
+  stream_->OnStreamFrameAcked(10, 3, false, QuicTime::Delta::Zero(),
+                              QuicTime::Zero(), &newly_acked_length);
+  EXPECT_EQ(3u, newly_acked_length);
+  // Retransmit [0, 18) with fin, and only [0, 8) is consumed.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
+      .WillOnce(InvokeWithoutArgs([this]() {
+        return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN,
+                                     NOT_RETRANSMISSION, absl::nullopt);
+      }));
+  EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
+
+  // Retransmit [0, 18) with fin, and all is consumed.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 5, 13, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
+
+  // Retransmit [0, 8) with fin, and all is consumed.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 8, 0, NO_FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 0, 18, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(0, 8, true, PTO_RETRANSMISSION));
+}
+
+TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresRetransmitLostData) {
+  Initialize();
+
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  std::string body(200, 'a');
+  stream_->WriteOrBufferData(body, true, nullptr);
+
+  // Set TTL to be 1 s.
+  QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
+  ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
+  // Verify data gets retransmitted because TTL does not expire.
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 100, 0, NO_FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  EXPECT_TRUE(stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION));
+  stream_->OnStreamFrameLost(100, 100, true);
+  EXPECT_TRUE(stream_->HasPendingRetransmission());
+
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  // Verify stream gets reset because TTL expires.
+  if (session_->version().UsesHttp3()) {
+    EXPECT_CALL(*session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_TTL_EXPIRED)))
+        .Times(1);
+  }
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
+      .Times(1);
+  stream_->OnCanWrite();
+}
+
+TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresEarlyRetransmitData) {
+  Initialize();
+
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
+      .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
+  std::string body(200, 'a');
+  stream_->WriteOrBufferData(body, true, nullptr);
+
+  // Set TTL to be 1 s.
+  QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
+  ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
+
+  connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  // Verify stream gets reset because TTL expires.
+  if (session_->version().UsesHttp3()) {
+    EXPECT_CALL(*session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_TTL_EXPIRED)))
+        .Times(1);
+  }
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          _, QuicResetStreamError::FromInternal(QUIC_STREAM_TTL_EXPIRED), _))
+      .Times(1);
+  stream_->RetransmitStreamData(0, 100, false, PTO_RETRANSMISSION);
+}
+
+// Test that OnStreamReset does one-way (read) closes if version 99, two way
+// (read and write) if not version 99.
+TEST_P(QuicStreamTest, OnStreamResetReadOrReadWrite) {
+  Initialize();
+  EXPECT_FALSE(stream_->write_side_closed());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    // Version 99/IETF QUIC should close just the read side.
+    EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+    EXPECT_FALSE(stream_->write_side_closed());
+  } else {
+    // Google QUIC should close both sides of the stream.
+    EXPECT_TRUE(stream_->write_side_closed());
+    EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+  }
+}
+
+TEST_P(QuicStreamTest, WindowUpdateForReadOnlyStream) {
+  Initialize();
+
+  QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
+      connection_->transport_version(), Perspective::IS_CLIENT);
+  TestStream stream(stream_id, session_.get(), READ_UNIDIRECTIONAL);
+  QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId, stream_id,
+                                            0);
+  EXPECT_CALL(
+      *connection_,
+      CloseConnection(
+          QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+          "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.", _));
+  stream.OnWindowUpdateFrame(window_update_frame);
+}
+
+TEST_P(QuicStreamTest, RstStreamFrameChangesCloseOffset) {
+  Initialize();
+
+  QuicStreamFrame stream_frame(stream_->id(), true, 0, "abc");
+  EXPECT_CALL(*stream_, OnDataAvailable());
+  stream_->OnStreamFrame(stream_frame);
+  QuicRstStreamFrame rst(kInvalidControlFrameId, stream_->id(),
+                         QUIC_STREAM_CANCELLED, 0u);
+
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_MULTIPLE_OFFSET, _, _));
+  stream_->OnStreamReset(rst);
+}
+
+// Regression test for b/176073284.
+TEST_P(QuicStreamTest, EmptyStreamFrameWithNoFin) {
+  Initialize();
+  QuicStreamFrame empty_stream_frame(stream_->id(), false, 0, "");
+  if (stream_->version().HasIetfQuicFrames()) {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _))
+        .Times(0);
+  } else {
+    EXPECT_CALL(*connection_,
+                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _));
+  }
+  EXPECT_CALL(*stream_, OnDataAvailable()).Times(0);
+  stream_->OnStreamFrame(empty_stream_frame);
+}
+
+TEST_P(QuicStreamTest, SendRstWithCustomIetfCode) {
+  Initialize();
+  QuicResetStreamError error(QUIC_STREAM_CANCELLED, 0x1234abcd);
+  EXPECT_CALL(*session_, MaybeSendRstStreamFrame(kTestStreamId, error, _))
+      .Times(1);
+  stream_->ResetWithError(error);
+  EXPECT_TRUE(rst_sent());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sustained_bandwidth_recorder.cc b/quiche/quic/core/quic_sustained_bandwidth_recorder.cc
new file mode 100644
index 0000000..c67e24f
--- /dev/null
+++ b/quiche/quic/core/quic_sustained_bandwidth_recorder.cc
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+QuicSustainedBandwidthRecorder::QuicSustainedBandwidthRecorder()
+    : has_estimate_(false),
+      is_recording_(false),
+      bandwidth_estimate_recorded_during_slow_start_(false),
+      bandwidth_estimate_(QuicBandwidth::Zero()),
+      max_bandwidth_estimate_(QuicBandwidth::Zero()),
+      max_bandwidth_timestamp_(0),
+      start_time_(QuicTime::Zero()) {}
+
+void QuicSustainedBandwidthRecorder::RecordEstimate(bool in_recovery,
+                                                    bool in_slow_start,
+                                                    QuicBandwidth bandwidth,
+                                                    QuicTime estimate_time,
+                                                    QuicWallTime wall_time,
+                                                    QuicTime::Delta srtt) {
+  if (in_recovery) {
+    is_recording_ = false;
+    QUIC_DVLOG(1) << "Stopped recording at: "
+                  << estimate_time.ToDebuggingValue();
+    return;
+  }
+
+  if (!is_recording_) {
+    // This is the first estimate of a new recording period.
+    start_time_ = estimate_time;
+    is_recording_ = true;
+    QUIC_DVLOG(1) << "Started recording at: " << start_time_.ToDebuggingValue();
+    return;
+  }
+
+  // If we have been recording for at least 3 * srtt, then record the latest
+  // bandwidth estimate as a valid sustained bandwidth estimate.
+  if (estimate_time - start_time_ >= 3 * srtt) {
+    has_estimate_ = true;
+    bandwidth_estimate_recorded_during_slow_start_ = in_slow_start;
+    bandwidth_estimate_ = bandwidth;
+    QUIC_DVLOG(1) << "New sustained bandwidth estimate (KBytes/s): "
+                  << bandwidth_estimate_.ToKBytesPerSecond();
+  }
+
+  // Check for an increase in max bandwidth.
+  if (bandwidth > max_bandwidth_estimate_) {
+    max_bandwidth_estimate_ = bandwidth;
+    max_bandwidth_timestamp_ = wall_time.ToUNIXSeconds();
+    QUIC_DVLOG(1) << "New max bandwidth estimate (KBytes/s): "
+                  << max_bandwidth_estimate_.ToKBytesPerSecond();
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_sustained_bandwidth_recorder.h b/quiche/quic/core/quic_sustained_bandwidth_recorder.h
new file mode 100644
index 0000000..1a82d22
--- /dev/null
+++ b/quiche/quic/core/quic_sustained_bandwidth_recorder.h
@@ -0,0 +1,95 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
+#define QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+namespace test {
+class QuicSustainedBandwidthRecorderPeer;
+}  // namespace test
+
+// This class keeps track of a sustained bandwidth estimate to ultimately send
+// to the client in a server config update message. A sustained bandwidth
+// estimate is only marked as valid if the QuicSustainedBandwidthRecorder has
+// been given uninterrupted reliable estimates over a certain period of time.
+class QUIC_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
+ public:
+  QuicSustainedBandwidthRecorder();
+  QuicSustainedBandwidthRecorder(const QuicSustainedBandwidthRecorder&) =
+      delete;
+  QuicSustainedBandwidthRecorder& operator=(
+      const QuicSustainedBandwidthRecorder&) = delete;
+
+  // As long as |in_recovery| is consistently false, multiple calls to this
+  // method over a 3 * srtt period results in storage of a valid sustained
+  // bandwidth estimate.
+  // |time_now| is used as a max bandwidth timestamp if needed.
+  void RecordEstimate(bool in_recovery,
+                      bool in_slow_start,
+                      QuicBandwidth bandwidth,
+                      QuicTime estimate_time,
+                      QuicWallTime wall_time,
+                      QuicTime::Delta srtt);
+
+  bool HasEstimate() const { return has_estimate_; }
+
+  QuicBandwidth BandwidthEstimate() const {
+    QUICHE_DCHECK(has_estimate_);
+    return bandwidth_estimate_;
+  }
+
+  QuicBandwidth MaxBandwidthEstimate() const {
+    QUICHE_DCHECK(has_estimate_);
+    return max_bandwidth_estimate_;
+  }
+
+  int64_t MaxBandwidthTimestamp() const {
+    QUICHE_DCHECK(has_estimate_);
+    return max_bandwidth_timestamp_;
+  }
+
+  bool EstimateRecordedDuringSlowStart() const {
+    QUICHE_DCHECK(has_estimate_);
+    return bandwidth_estimate_recorded_during_slow_start_;
+  }
+
+ private:
+  friend class test::QuicSustainedBandwidthRecorderPeer;
+
+  // True if we have been able to calculate sustained bandwidth, over at least
+  // one recording period (3 * rtt).
+  bool has_estimate_;
+
+  // True if the last call to RecordEstimate had a reliable estimate.
+  bool is_recording_;
+
+  // True if the current sustained bandwidth estimate was generated while in
+  // slow start.
+  bool bandwidth_estimate_recorded_during_slow_start_;
+
+  // The latest sustained bandwidth estimate.
+  QuicBandwidth bandwidth_estimate_;
+
+  // The maximum sustained bandwidth seen over the lifetime of the connection.
+  QuicBandwidth max_bandwidth_estimate_;
+
+  // Timestamp indicating when the max_bandwidth_estimate_ was seen.
+  int64_t max_bandwidth_timestamp_;
+
+  // Timestamp marking the beginning of the latest recording period.
+  QuicTime start_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_SUSTAINED_BANDWIDTH_RECORDER_H_
diff --git a/quiche/quic/core/quic_sustained_bandwidth_recorder_test.cc b/quiche/quic/core/quic_sustained_bandwidth_recorder_test.cc
new file mode 100644
index 0000000..6f53350
--- /dev/null
+++ b/quiche/quic/core/quic_sustained_bandwidth_recorder_test.cc
@@ -0,0 +1,133 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicSustainedBandwidthRecorderTest : public QuicTest {};
+
+TEST_F(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) {
+  QuicSustainedBandwidthRecorder recorder;
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  QuicTime estimate_time = QuicTime::Zero();
+  QuicWallTime wall_time = QuicWallTime::Zero();
+  QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
+  const int kBandwidthBitsPerSecond = 12345678;
+  QuicBandwidth bandwidth =
+      QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
+
+  bool in_recovery = false;
+  bool in_slow_start = false;
+
+  // This triggers recording, but should not yield a valid estimate yet.
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  // Send a second reading, again this should not result in a valid estimate,
+  // as not enough time has passed.
+  estimate_time = estimate_time + srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
+  estimate_time = estimate_time + srtt;
+  estimate_time = estimate_time + srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_TRUE(recorder.HasEstimate());
+  EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
+  EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
+
+  // Resetting, and sending a different estimate will only change output after
+  // a further 3 * kSRTT has passed.
+  QuicBandwidth second_bandwidth =
+      QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond);
+  // Reset the recorder by passing in a measurement while in recovery.
+  in_recovery = true;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  in_recovery = false;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
+
+  estimate_time = estimate_time + 3 * srtt;
+  const int64_t kSeconds = 556677;
+  QuicWallTime second_bandwidth_wall_time =
+      QuicWallTime::FromUNIXSeconds(kSeconds);
+  recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth,
+                          estimate_time, second_bandwidth_wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth);
+  EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
+  EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
+
+  // Reset again, this time recording a lower bandwidth than before.
+  QuicBandwidth third_bandwidth =
+      QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond);
+  // Reset the recorder by passing in an unreliable measurement.
+  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
+                          estimate_time, wall_time, srtt);
+  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
+                          estimate_time, wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
+
+  estimate_time = estimate_time + 3 * srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
+                          estimate_time, wall_time, srtt);
+  EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
+
+  // Max bandwidth should not have changed.
+  EXPECT_LT(third_bandwidth, second_bandwidth);
+  EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth);
+  EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
+}
+
+TEST_F(QuicSustainedBandwidthRecorderTest, SlowStart) {
+  // Verify that slow start status is correctly recorded.
+  QuicSustainedBandwidthRecorder recorder;
+  EXPECT_FALSE(recorder.HasEstimate());
+
+  QuicTime estimate_time = QuicTime::Zero();
+  QuicWallTime wall_time = QuicWallTime::Zero();
+  QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
+  const int kBandwidthBitsPerSecond = 12345678;
+  QuicBandwidth bandwidth =
+      QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
+
+  bool in_recovery = false;
+  bool in_slow_start = true;
+
+  // This triggers recording, but should not yield a valid estimate yet.
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+
+  // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
+  estimate_time = estimate_time + 3 * srtt;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_TRUE(recorder.HasEstimate());
+  EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart());
+
+  // Now send another estimate, this time not in slow start.
+  estimate_time = estimate_time + 3 * srtt;
+  in_slow_start = false;
+  recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
+                          wall_time, srtt);
+  EXPECT_TRUE(recorder.HasEstimate());
+  EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_syscall_wrapper.cc b/quiche/quic/core/quic_syscall_wrapper.cc
new file mode 100644
index 0000000..2214da1
--- /dev/null
+++ b/quiche/quic/core/quic_syscall_wrapper.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_syscall_wrapper.h"
+
+#include <atomic>
+#include <cerrno>
+
+namespace quic {
+namespace {
+std::atomic<QuicSyscallWrapper*> global_syscall_wrapper(new QuicSyscallWrapper);
+}  // namespace
+
+ssize_t QuicSyscallWrapper::Sendmsg(int sockfd, const msghdr* msg, int flags) {
+  return ::sendmsg(sockfd, msg, flags);
+}
+
+int QuicSyscallWrapper::Sendmmsg(int sockfd,
+                                 mmsghdr* msgvec,
+                                 unsigned int vlen,
+                                 int flags) {
+#if defined(__linux__) && !defined(__ANDROID__)
+  return ::sendmmsg(sockfd, msgvec, vlen, flags);
+#else
+  errno = ENOSYS;
+  return -1;
+#endif
+}
+
+QuicSyscallWrapper* GetGlobalSyscallWrapper() {
+  return global_syscall_wrapper.load();
+}
+
+void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper) {
+  global_syscall_wrapper.store(wrapper);
+}
+
+ScopedGlobalSyscallWrapperOverride::ScopedGlobalSyscallWrapperOverride(
+    QuicSyscallWrapper* wrapper_in_scope)
+    : original_wrapper_(GetGlobalSyscallWrapper()) {
+  SetGlobalSyscallWrapper(wrapper_in_scope);
+}
+
+ScopedGlobalSyscallWrapperOverride::~ScopedGlobalSyscallWrapperOverride() {
+  SetGlobalSyscallWrapper(original_wrapper_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_syscall_wrapper.h b/quiche/quic/core/quic_syscall_wrapper.h
new file mode 100644
index 0000000..f7a6271
--- /dev/null
+++ b/quiche/quic/core/quic_syscall_wrapper.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+struct mmsghdr;
+namespace quic {
+
+// QuicSyscallWrapper is a pass-through proxy to the real syscalls.
+class QUIC_EXPORT_PRIVATE QuicSyscallWrapper {
+ public:
+  virtual ~QuicSyscallWrapper() = default;
+
+  virtual ssize_t Sendmsg(int sockfd, const msghdr* msg, int flags);
+
+  virtual int Sendmmsg(int sockfd,
+                       mmsghdr* msgvec,
+                       unsigned int vlen,
+                       int flags);
+};
+
+// A global instance of QuicSyscallWrapper, used by some socket util functions.
+QuicSyscallWrapper* GetGlobalSyscallWrapper();
+
+// Change the global QuicSyscallWrapper to |wrapper|, for testing.
+void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper);
+
+// ScopedGlobalSyscallWrapperOverride changes the global QuicSyscallWrapper
+// during its lifetime, for testing.
+class QUIC_EXPORT_PRIVATE ScopedGlobalSyscallWrapperOverride {
+ public:
+  explicit ScopedGlobalSyscallWrapperOverride(
+      QuicSyscallWrapper* wrapper_in_scope);
+  ~ScopedGlobalSyscallWrapperOverride();
+
+ private:
+  QuicSyscallWrapper* original_wrapper_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
diff --git a/quiche/quic/core/quic_tag.cc b/quiche/quic/core/quic_tag.cc
new file mode 100644
index 0000000..48ae70a
--- /dev/null
+++ b/quiche/quic/core/quic_tag.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_tag.h"
+
+#include <algorithm>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_split.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+bool FindMutualQuicTag(const QuicTagVector& our_tags,
+                       const QuicTagVector& their_tags,
+                       QuicTag* out_result,
+                       size_t* out_index) {
+  const size_t num_our_tags = our_tags.size();
+  const size_t num_their_tags = their_tags.size();
+  for (size_t i = 0; i < num_our_tags; i++) {
+    for (size_t j = 0; j < num_their_tags; j++) {
+      if (our_tags[i] == their_tags[j]) {
+        *out_result = our_tags[i];
+        if (out_index != nullptr) {
+          *out_index = j;
+        }
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+std::string QuicTagToString(QuicTag tag) {
+  if (tag == 0) {
+    return "0";
+  }
+  char chars[sizeof tag];
+  bool ascii = true;
+  const QuicTag orig_tag = tag;
+
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) {
+    chars[i] = static_cast<char>(tag);
+    if ((chars[i] == 0 || chars[i] == '\xff') &&
+        i == ABSL_ARRAYSIZE(chars) - 1) {
+      chars[i] = ' ';
+    }
+    if (!isprint(static_cast<unsigned char>(chars[i]))) {
+      ascii = false;
+      break;
+    }
+    tag >>= 8;
+  }
+
+  if (ascii) {
+    return std::string(chars, sizeof(chars));
+  }
+
+  return absl::BytesToHexString(absl::string_view(
+      reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
+}
+
+uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+  return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
+         static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
+}
+
+bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
+  return std::find(tag_vector.begin(), tag_vector.end(), tag) !=
+         tag_vector.end();
+}
+
+QuicTag ParseQuicTag(absl::string_view tag_string) {
+  quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
+  std::string tag_bytes;
+  if (tag_string.length() == 8) {
+    tag_bytes = absl::HexStringToBytes(tag_string);
+    tag_string = tag_bytes;
+  }
+  QuicTag tag = 0;
+  // Iterate over every character from right to left.
+  for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) {
+    // The cast here is required on platforms where char is signed.
+    unsigned char token_char = static_cast<unsigned char>(*it);
+    tag <<= 8;
+    tag |= token_char;
+  }
+  return tag;
+}
+
+QuicTagVector ParseQuicTagVector(absl::string_view tags_string) {
+  QuicTagVector tag_vector;
+  quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tags_string);
+  if (!tags_string.empty()) {
+    std::vector<absl::string_view> tag_strings =
+        absl::StrSplit(tags_string, ',');
+    for (absl::string_view tag_string : tag_strings) {
+      tag_vector.push_back(ParseQuicTag(tag_string));
+    }
+  }
+  return tag_vector;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_tag.h b/quiche/quic/core/quic_tag.h
new file mode 100644
index 0000000..17c5968
--- /dev/null
+++ b/quiche/quic/core/quic_tag.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TAG_H_
+#define QUICHE_QUIC_CORE_QUIC_TAG_H_
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A QuicTag is a 32-bit used as identifiers in the QUIC handshake.  The use of
+// a uint32_t seeks to provide a balance between the tyranny of magic number
+// registries and the verbosity of strings. As far as the wire protocol is
+// concerned, these are opaque, 32-bit values.
+//
+// Tags will often be referred to by their ASCII equivalent, e.g. EXMP. This is
+// just a mnemonic for the value 0x504d5845 (little-endian version of the ASCII
+// string E X M P).
+using QuicTag = uint32_t;
+using QuicTagValueMap = std::map<QuicTag, std::string>;
+using QuicTagVector = std::vector<QuicTag>;
+
+// MakeQuicTag returns a value given the four bytes. For example:
+//   MakeQuicTag('C', 'H', 'L', 'O');
+QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(uint8_t a, uint8_t b, uint8_t c,
+                                        uint8_t d);
+
+// Returns true if |tag_vector| contains |tag|.
+QUIC_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
+                                         QuicTag tag);
+
+// Sets |out_result| to the first tag in |our_tags| that is also in |their_tags|
+// and returns true. If there is no intersection it returns false.
+//
+// If |out_index| is non-nullptr and a match is found then the index of that
+// match in |their_tags| is written to |out_index|.
+QUIC_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
+                                           const QuicTagVector& their_tags,
+                                           QuicTag* out_result,
+                                           size_t* out_index);
+
+// A utility function that converts a tag to a string. It will try to maintain
+// the human friendly name if possible (i.e. kABCD -> "ABCD"), or will just
+// treat it as a number if not.
+QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
+
+// Utility function that converts a string of the form "ABCD" to its
+// corresponding QuicTag. Note that tags that are less than four characters
+// long are right-padded with zeroes. Tags that contain non-ASCII characters
+// are represented as 8-character-long hexadecimal strings.
+QUIC_EXPORT_PRIVATE QuicTag ParseQuicTag(absl::string_view tag_string);
+
+// Utility function that converts a string of the form "ABCD,EFGH" to a vector
+// of the form {kABCD,kEFGH}. Note the caveats on ParseQuicTag.
+QUIC_EXPORT_PRIVATE QuicTagVector
+ParseQuicTagVector(absl::string_view tags_string);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TAG_H_
diff --git a/quiche/quic/core/quic_tag_test.cc b/quiche/quic/core/quic_tag_test.cc
new file mode 100644
index 0000000..b3e6510
--- /dev/null
+++ b/quiche/quic/core/quic_tag_test.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_tag.h"
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicTagTest : public QuicTest {};
+
+TEST_F(QuicTagTest, TagToString) {
+  EXPECT_EQ("SCFG", QuicTagToString(kSCFG));
+  EXPECT_EQ("SNO ", QuicTagToString(kServerNonceTag));
+  EXPECT_EQ("CRT ", QuicTagToString(kCertificateTag));
+  EXPECT_EQ("CHLO", QuicTagToString(MakeQuicTag('C', 'H', 'L', 'O')));
+  // A tag that contains a non-printing character will be printed as hex.
+  EXPECT_EQ("43484c1f", QuicTagToString(MakeQuicTag('C', 'H', 'L', '\x1f')));
+}
+
+TEST_F(QuicTagTest, MakeQuicTag) {
+  QuicTag tag = MakeQuicTag('A', 'B', 'C', 'D');
+  char bytes[4];
+  memcpy(bytes, &tag, 4);
+  EXPECT_EQ('A', bytes[0]);
+  EXPECT_EQ('B', bytes[1]);
+  EXPECT_EQ('C', bytes[2]);
+  EXPECT_EQ('D', bytes[3]);
+}
+
+TEST_F(QuicTagTest, ParseQuicTag) {
+  QuicTag tag_abcd = MakeQuicTag('A', 'B', 'C', 'D');
+  EXPECT_EQ(ParseQuicTag("ABCD"), tag_abcd);
+  EXPECT_EQ(ParseQuicTag("ABCDE"), tag_abcd);
+  QuicTag tag_efgh = MakeQuicTag('E', 'F', 'G', 'H');
+  EXPECT_EQ(ParseQuicTag("EFGH"), tag_efgh);
+  QuicTag tag_ijk = MakeQuicTag('I', 'J', 'K', 0);
+  EXPECT_EQ(ParseQuicTag("IJK"), tag_ijk);
+  QuicTag tag_l = MakeQuicTag('L', 0, 0, 0);
+  EXPECT_EQ(ParseQuicTag("L"), tag_l);
+  QuicTag tag_hex = MakeQuicTag('M', 'N', 'O', static_cast<char>(255));
+  EXPECT_EQ(ParseQuicTag("4d4e4fff"), tag_hex);
+  EXPECT_EQ(ParseQuicTag("4D4E4FFF"), tag_hex);
+  QuicTag tag_with_numbers = MakeQuicTag('P', 'Q', '1', '2');
+  EXPECT_EQ(ParseQuicTag("PQ12"), tag_with_numbers);
+  QuicTag tag_with_custom_chars = MakeQuicTag('r', '$', '_', '7');
+  EXPECT_EQ(ParseQuicTag("r$_7"), tag_with_custom_chars);
+  QuicTag tag_zero = 0;
+  EXPECT_EQ(ParseQuicTag(""), tag_zero);
+  QuicTagVector tag_vector;
+  EXPECT_EQ(ParseQuicTagVector(""), tag_vector);
+  EXPECT_EQ(ParseQuicTagVector(" "), tag_vector);
+  tag_vector.push_back(tag_abcd);
+  EXPECT_EQ(ParseQuicTagVector("ABCD"), tag_vector);
+  tag_vector.push_back(tag_efgh);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH"), tag_vector);
+  tag_vector.push_back(tag_ijk);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK"), tag_vector);
+  tag_vector.push_back(tag_l);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L"), tag_vector);
+  tag_vector.push_back(tag_hex);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff"), tag_vector);
+  tag_vector.push_back(tag_with_numbers);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12"), tag_vector);
+  tag_vector.push_back(tag_with_custom_chars);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7"),
+            tag_vector);
+  tag_vector.push_back(tag_zero);
+  EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7,"),
+            tag_vector);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time.cc b/quiche/quic/core/quic_time.cc
new file mode 100644
index 0000000..8da46fe
--- /dev/null
+++ b/quiche/quic/core/quic_time.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_time.h"
+
+#include <cinttypes>
+#include <cstdlib>
+#include <limits>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+std::string QuicTime::Delta::ToDebuggingValue() const {
+  constexpr int64_t kMillisecondInMicroseconds = 1000;
+  constexpr int64_t kSecondInMicroseconds = 1000 * kMillisecondInMicroseconds;
+
+  int64_t absolute_value = std::abs(time_offset_);
+
+  // For debugging purposes, always display the value with the highest precision
+  // available.
+  if (absolute_value >= kSecondInMicroseconds &&
+      absolute_value % kSecondInMicroseconds == 0) {
+    return absl::StrCat(time_offset_ / kSecondInMicroseconds, "s");
+  }
+  if (absolute_value >= kMillisecondInMicroseconds &&
+      absolute_value % kMillisecondInMicroseconds == 0) {
+    return absl::StrCat(time_offset_ / kMillisecondInMicroseconds, "ms");
+  }
+  return absl::StrCat(time_offset_, "us");
+}
+
+uint64_t QuicWallTime::ToUNIXSeconds() const {
+  return microseconds_ / 1000000;
+}
+
+uint64_t QuicWallTime::ToUNIXMicroseconds() const {
+  return microseconds_;
+}
+
+bool QuicWallTime::IsAfter(QuicWallTime other) const {
+  return microseconds_ > other.microseconds_;
+}
+
+bool QuicWallTime::IsBefore(QuicWallTime other) const {
+  return microseconds_ < other.microseconds_;
+}
+
+bool QuicWallTime::IsZero() const {
+  return microseconds_ == 0;
+}
+
+QuicTime::Delta QuicWallTime::AbsoluteDifference(QuicWallTime other) const {
+  uint64_t d;
+
+  if (microseconds_ > other.microseconds_) {
+    d = microseconds_ - other.microseconds_;
+  } else {
+    d = other.microseconds_ - microseconds_;
+  }
+
+  if (d > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
+    d = std::numeric_limits<int64_t>::max();
+  }
+  return QuicTime::Delta::FromMicroseconds(d);
+}
+
+QuicWallTime QuicWallTime::Add(QuicTime::Delta delta) const {
+  uint64_t microseconds = microseconds_ + delta.ToMicroseconds();
+  if (microseconds < microseconds_) {
+    microseconds = std::numeric_limits<uint64_t>::max();
+  }
+  return QuicWallTime(microseconds);
+}
+
+// TODO(ianswett) Test this.
+QuicWallTime QuicWallTime::Subtract(QuicTime::Delta delta) const {
+  uint64_t microseconds = microseconds_ - delta.ToMicroseconds();
+  if (microseconds > microseconds_) {
+    microseconds = 0;
+  }
+  return QuicWallTime(microseconds);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time.h b/quiche/quic/core/quic_time.h
new file mode 100644
index 0000000..74cfaf2
--- /dev/null
+++ b/quiche/quic/core/quic_time.h
@@ -0,0 +1,292 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// QuicTime represents one point in time, stored in microsecond resolution.
+// QuicTime is monotonically increasing, even across system clock adjustments.
+// The epoch (time 0) of QuicTime is unspecified.
+//
+// This implementation wraps a int64_t of usec since the epoch.  While
+// the epoch is the Unix epoch, do not depend on this fact because other
+// implementations, like Chrome's, do NOT have the same epoch.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TIME_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_H_
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+// TODO(vasilvv): replace with ABSL_MUST_USE_RESULT once we're using absl.
+#if defined(__clang__)
+#define QUIC_TIME_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define QUIC_TIME_WARN_UNUSED_RESULT
+#endif /* defined(__clang__) */
+
+namespace quic {
+
+class QuicClock;
+
+// A QuicTime is a purely relative time. QuicTime values from different clocks
+// cannot be compared to each other. If you need an absolute time, see
+// QuicWallTime, below.
+class QUIC_EXPORT_PRIVATE QuicTime {
+ public:
+  // A QuicTime::Delta represents the signed difference between two points in
+  // time, stored in microsecond resolution.
+  class QUIC_EXPORT_PRIVATE Delta {
+   public:
+    // Create a object with an offset of 0.
+    static constexpr Delta Zero() { return Delta(0); }
+
+    // Create a object with infinite offset time.
+    static constexpr Delta Infinite() { return Delta(kQuicInfiniteTimeUs); }
+
+    // Converts a number of seconds to a time offset.
+    static constexpr Delta FromSeconds(int64_t secs) {
+      return Delta(secs * 1000 * 1000);
+    }
+
+    // Converts a number of milliseconds to a time offset.
+    static constexpr Delta FromMilliseconds(int64_t ms) {
+      return Delta(ms * 1000);
+    }
+
+    // Converts a number of microseconds to a time offset.
+    static constexpr Delta FromMicroseconds(int64_t us) { return Delta(us); }
+
+    // Converts the time offset to a rounded number of seconds.
+    int64_t ToSeconds() const { return time_offset_ / 1000 / 1000; }
+
+    // Converts the time offset to a rounded number of milliseconds.
+    int64_t ToMilliseconds() const { return time_offset_ / 1000; }
+
+    // Converts the time offset to a rounded number of microseconds.
+    int64_t ToMicroseconds() const { return time_offset_; }
+
+    bool IsZero() const { return time_offset_ == 0; }
+
+    bool IsInfinite() const { return time_offset_ == kQuicInfiniteTimeUs; }
+
+    std::string ToDebuggingValue() const;
+
+   private:
+    friend inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs);
+    friend inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs);
+    friend inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs);
+
+    friend inline QuicTime::Delta operator+(QuicTime::Delta lhs,
+                                            QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator-(QuicTime::Delta lhs,
+                                            QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs);
+    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs);
+
+    friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
+    friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
+
+    static const int64_t kQuicInfiniteTimeUs =
+        std::numeric_limits<int64_t>::max();
+
+    explicit constexpr Delta(int64_t time_offset) : time_offset_(time_offset) {}
+
+    int64_t time_offset_;
+    friend class QuicTime;
+  };
+
+  // Creates a new QuicTime with an internal value of 0.  IsInitialized()
+  // will return false for these times.
+  static constexpr QuicTime Zero() { return QuicTime(0); }
+
+  // Creates a new QuicTime with an infinite time.
+  static constexpr QuicTime Infinite() {
+    return QuicTime(Delta::kQuicInfiniteTimeUs);
+  }
+
+  QuicTime(const QuicTime& other) = default;
+
+  QuicTime& operator=(const QuicTime& other) {
+    time_ = other.time_;
+    return *this;
+  }
+
+  // Produce the internal value to be used when logging.  This value
+  // represents the number of microseconds since some epoch.  It may
+  // be the UNIX epoch on some platforms.  On others, it may
+  // be a CPU ticks based value.
+  int64_t ToDebuggingValue() const { return time_; }
+
+  bool IsInitialized() const { return 0 != time_; }
+
+ private:
+  friend class QuicClock;
+
+  friend inline bool operator==(QuicTime lhs, QuicTime rhs);
+  friend inline bool operator<(QuicTime lhs, QuicTime rhs);
+  friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
+  friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
+  friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
+
+  explicit constexpr QuicTime(int64_t time) : time_(time) {}
+
+  int64_t time_;
+};
+
+// A QuicWallTime represents an absolute time that is globally consistent. In
+// practice, clock-skew means that comparing values from different machines
+// requires some flexibility.
+class QUIC_EXPORT_PRIVATE QuicWallTime {
+ public:
+  // FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
+  // since the UNIX epoch.
+  static constexpr QuicWallTime FromUNIXSeconds(uint64_t seconds) {
+    return QuicWallTime(seconds * 1000000);
+  }
+
+  static constexpr QuicWallTime FromUNIXMicroseconds(uint64_t microseconds) {
+    return QuicWallTime(microseconds);
+  }
+
+  // Zero returns a QuicWallTime set to zero. IsZero will return true for this
+  // value.
+  static constexpr QuicWallTime Zero() { return QuicWallTime(0); }
+
+  // Returns the number of seconds since the UNIX epoch.
+  uint64_t ToUNIXSeconds() const;
+  // Returns the number of microseconds since the UNIX epoch.
+  uint64_t ToUNIXMicroseconds() const;
+
+  bool IsAfter(QuicWallTime other) const;
+  bool IsBefore(QuicWallTime other) const;
+
+  // IsZero returns true if this object is the result of calling |Zero|.
+  bool IsZero() const;
+
+  // AbsoluteDifference returns the absolute value of the time difference
+  // between |this| and |other|.
+  QuicTime::Delta AbsoluteDifference(QuicWallTime other) const;
+
+  // Add returns a new QuicWallTime that represents the time of |this| plus
+  // |delta|.
+  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime Add(QuicTime::Delta delta) const;
+
+  // Subtract returns a new QuicWallTime that represents the time of |this|
+  // minus |delta|.
+  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime
+  Subtract(QuicTime::Delta delta) const;
+
+  bool operator==(const QuicWallTime& other) const {
+    return microseconds_ == other.microseconds_;
+  }
+
+  QuicTime::Delta operator-(const QuicWallTime& rhs) const {
+    return QuicTime::Delta::FromMicroseconds(microseconds_ - rhs.microseconds_);
+  }
+
+ private:
+  explicit constexpr QuicWallTime(uint64_t microseconds)
+      : microseconds_(microseconds) {}
+
+  uint64_t microseconds_;
+};
+
+// Non-member relational operators for QuicTime::Delta.
+inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.time_offset_ == rhs.time_offset_;
+}
+inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.time_offset_ < rhs.time_offset_;
+}
+inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs < rhs);
+}
+inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs) {
+  return QuicTime::Delta(lhs.time_offset_ << rhs);
+}
+inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs) {
+  return QuicTime::Delta(lhs.time_offset_ >> rhs);
+}
+
+// Non-member relational operators for QuicTime.
+inline bool operator==(QuicTime lhs, QuicTime rhs) {
+  return lhs.time_ == rhs.time_;
+}
+inline bool operator!=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime lhs, QuicTime rhs) {
+  return lhs.time_ < rhs.time_;
+}
+inline bool operator>(QuicTime lhs, QuicTime rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime lhs, QuicTime rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs < rhs);
+}
+
+// Override stream output operator for gtest or QUICHE_CHECK macros.
+inline std::ostream& operator<<(std::ostream& output, const QuicTime t) {
+  output << t.ToDebuggingValue();
+  return output;
+}
+
+// Non-member arithmetic operators for QuicTime::Delta.
+inline QuicTime::Delta operator+(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return QuicTime::Delta(lhs.time_offset_ + rhs.time_offset_);
+}
+inline QuicTime::Delta operator-(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return QuicTime::Delta(lhs.time_offset_ - rhs.time_offset_);
+}
+inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs) {
+  return QuicTime::Delta(lhs.time_offset_ * rhs);
+}
+inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs) {
+  return QuicTime::Delta(static_cast<int64_t>(
+      std::llround(static_cast<double>(lhs.time_offset_) * rhs)));
+}
+inline QuicTime::Delta operator*(int lhs, QuicTime::Delta rhs) {
+  return rhs * lhs;
+}
+inline QuicTime::Delta operator*(double lhs, QuicTime::Delta rhs) {
+  return rhs * lhs;
+}
+
+// Non-member arithmetic operators for QuicTime and QuicTime::Delta.
+inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs) {
+  return QuicTime(lhs.time_ + rhs.time_offset_);
+}
+inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs) {
+  return QuicTime(lhs.time_ - rhs.time_offset_);
+}
+inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs) {
+  return QuicTime::Delta(lhs.time_ - rhs.time_);
+}
+
+// Override stream output operator for gtest.
+inline std::ostream& operator<<(std::ostream& output,
+                                const QuicTime::Delta delta) {
+  output << delta.ToDebuggingValue();
+  return output;
+}
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_H_
diff --git a/quiche/quic/core/quic_time_accumulator.h b/quiche/quic/core/quic_time_accumulator.h
new file mode 100644
index 0000000..480e797
--- /dev/null
+++ b/quiche/quic/core/quic_time_accumulator.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// QuicTimeAccumulator accumulates elapsed times between Start(s) and Stop(s).
+class QUIC_EXPORT_PRIVATE QuicTimeAccumulator {
+  // TODO(wub): Switch to a data member called kNotRunningSentinel after c++17.
+  static constexpr QuicTime NotRunningSentinel() {
+    return QuicTime::Infinite();
+  }
+
+ public:
+  // True if Started and not Stopped.
+  bool IsRunning() const { return last_start_time_ != NotRunningSentinel(); }
+
+  void Start(QuicTime now) {
+    QUICHE_DCHECK(!IsRunning());
+    last_start_time_ = now;
+    QUICHE_DCHECK(IsRunning());
+  }
+
+  void Stop(QuicTime now) {
+    QUICHE_DCHECK(IsRunning());
+    if (now > last_start_time_) {
+      total_elapsed_ = total_elapsed_ + (now - last_start_time_);
+    }
+    last_start_time_ = NotRunningSentinel();
+    QUICHE_DCHECK(!IsRunning());
+  }
+
+  // Get total elapsed time between COMPLETED Start/Stop pairs.
+  QuicTime::Delta GetTotalElapsedTime() const { return total_elapsed_; }
+
+  // Get total elapsed time between COMPLETED Start/Stop pairs, plus, if it is
+  // running, the elapsed time between |last_start_time_| and |now|.
+  QuicTime::Delta GetTotalElapsedTime(QuicTime now) const {
+    if (!IsRunning()) {
+      return total_elapsed_;
+    }
+    if (now <= last_start_time_) {
+      return total_elapsed_;
+    }
+    return total_elapsed_ + (now - last_start_time_);
+  }
+
+ private:
+  //
+  //                                       |last_start_time_|
+  //                                         |
+  //                                         V
+  // Start => Stop  =>  Start => Stop  =>  Start
+  // |           |      |           |
+  // |___________|  +   |___________|  =   |total_elapsed_|
+  QuicTime::Delta total_elapsed_ = QuicTime::Delta::Zero();
+  QuicTime last_start_time_ = NotRunningSentinel();
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_ACCUMULATOR_H_
diff --git a/quiche/quic/core/quic_time_accumulator_test.cc b/quiche/quic/core/quic_time_accumulator_test.cc
new file mode 100644
index 0000000..e431378
--- /dev/null
+++ b/quiche/quic/core/quic_time_accumulator_test.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+TEST(QuicTimeAccumulator, DefaultConstruct) {
+  MockClock clock;
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTimeAccumulator acc;
+  EXPECT_FALSE(acc.IsRunning());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
+}
+
+TEST(QuicTimeAccumulator, StartStop) {
+  MockClock clock;
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTimeAccumulator acc;
+  acc.Start(clock.Now());
+  EXPECT_TRUE(acc.IsRunning());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  acc.Stop(clock.Now());
+  EXPECT_FALSE(acc.IsRunning());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
+            acc.GetTotalElapsedTime(clock.Now()));
+
+  acc.Start(clock.Now());
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(15),
+            acc.GetTotalElapsedTime(clock.Now()));
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+            acc.GetTotalElapsedTime(clock.Now()));
+
+  acc.Stop(clock.Now());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(20),
+            acc.GetTotalElapsedTime(clock.Now()));
+}
+
+TEST(QuicTimeAccumulator, ClockStepBackwards) {
+  MockClock clock;
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTimeAccumulator acc;
+  acc.Start(clock.Now());
+
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-10));
+  acc.Stop(clock.Now());
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::Zero(), acc.GetTotalElapsedTime(clock.Now()));
+
+  acc.Start(clock.Now());
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(50));
+  acc.Stop(clock.Now());
+
+  acc.Start(clock.Now());
+  clock.AdvanceTime(QuicTime::Delta::FromMilliseconds(-80));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50), acc.GetTotalElapsedTime());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(50),
+            acc.GetTotalElapsedTime(clock.Now()));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time_test.cc b/quiche/quic/core/quic_time_test.cc
new file mode 100644
index 0000000..d2a8d91
--- /dev/null
+++ b/quiche/quic/core/quic_time_test.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class QuicTimeDeltaTest : public QuicTest {};
+
+TEST_F(QuicTimeDeltaTest, Zero) {
+  EXPECT_TRUE(QuicTime::Delta::Zero().IsZero());
+  EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsZero());
+}
+
+TEST_F(QuicTimeDeltaTest, Infinite) {
+  EXPECT_TRUE(QuicTime::Delta::Infinite().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::Zero().IsInfinite());
+  EXPECT_FALSE(QuicTime::Delta::FromMilliseconds(1).IsInfinite());
+}
+
+TEST_F(QuicTimeDeltaTest, FromTo) {
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
+            QuicTime::Delta::FromMicroseconds(1000));
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            QuicTime::Delta::FromMilliseconds(1000));
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(1),
+            QuicTime::Delta::FromMicroseconds(1000000));
+
+  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
+  EXPECT_EQ(2, QuicTime::Delta::FromMilliseconds(2000).ToSeconds());
+  EXPECT_EQ(1000, QuicTime::Delta::FromMilliseconds(1).ToMicroseconds());
+  EXPECT_EQ(1, QuicTime::Delta::FromMicroseconds(1000).ToMilliseconds());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2000).ToMicroseconds(),
+            QuicTime::Delta::FromSeconds(2).ToMicroseconds());
+}
+
+TEST_F(QuicTimeDeltaTest, Add) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
+            QuicTime::Delta::Zero() + QuicTime::Delta::FromMilliseconds(2));
+}
+
+TEST_F(QuicTimeDeltaTest, Subtract) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1000),
+            QuicTime::Delta::FromMilliseconds(2) -
+                QuicTime::Delta::FromMilliseconds(1));
+}
+
+TEST_F(QuicTimeDeltaTest, Multiply) {
+  int i = 2;
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            QuicTime::Delta::FromMilliseconds(2) * i);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            i * QuicTime::Delta::FromMilliseconds(2));
+  double d = 2;
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            QuicTime::Delta::FromMilliseconds(2) * d);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(4000),
+            d * QuicTime::Delta::FromMilliseconds(2));
+
+  // Ensure we are rounding correctly within a single-bit level of precision.
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(5),
+            QuicTime::Delta::FromMicroseconds(9) * 0.5);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicTime::Delta::FromMicroseconds(12) * 0.2);
+}
+
+TEST_F(QuicTimeDeltaTest, Max) {
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2000),
+            std::max(QuicTime::Delta::FromMicroseconds(1000),
+                     QuicTime::Delta::FromMicroseconds(2000)));
+}
+
+TEST_F(QuicTimeDeltaTest, NotEqual) {
+  EXPECT_TRUE(QuicTime::Delta::FromSeconds(0) !=
+              QuicTime::Delta::FromSeconds(1));
+  EXPECT_FALSE(QuicTime::Delta::FromSeconds(0) !=
+               QuicTime::Delta::FromSeconds(0));
+}
+
+TEST_F(QuicTimeDeltaTest, DebuggingValue) {
+  const QuicTime::Delta one_us = QuicTime::Delta::FromMicroseconds(1);
+  const QuicTime::Delta one_ms = QuicTime::Delta::FromMilliseconds(1);
+  const QuicTime::Delta one_s = QuicTime::Delta::FromSeconds(1);
+
+  EXPECT_EQ("1s", one_s.ToDebuggingValue());
+  EXPECT_EQ("3s", (3 * one_s).ToDebuggingValue());
+  EXPECT_EQ("1ms", one_ms.ToDebuggingValue());
+  EXPECT_EQ("3ms", (3 * one_ms).ToDebuggingValue());
+  EXPECT_EQ("1us", one_us.ToDebuggingValue());
+  EXPECT_EQ("3us", (3 * one_us).ToDebuggingValue());
+
+  EXPECT_EQ("3001us", (3 * one_ms + one_us).ToDebuggingValue());
+  EXPECT_EQ("3001ms", (3 * one_s + one_ms).ToDebuggingValue());
+  EXPECT_EQ("3000001us", (3 * one_s + one_us).ToDebuggingValue());
+}
+
+class QuicTimeTest : public QuicTest {
+ protected:
+  MockClock clock_;
+};
+
+TEST_F(QuicTimeTest, Initialized) {
+  EXPECT_FALSE(QuicTime::Zero().IsInitialized());
+  EXPECT_TRUE((QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1))
+                  .IsInitialized());
+}
+
+TEST_F(QuicTimeTest, CopyConstruct) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
+  EXPECT_NE(time_1, QuicTime(QuicTime::Zero()));
+  EXPECT_EQ(time_1, QuicTime(time_1));
+}
+
+TEST_F(QuicTimeTest, CopyAssignment) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1234);
+  QuicTime time_2 = QuicTime::Zero();
+  EXPECT_NE(time_1, time_2);
+  time_2 = time_1;
+  EXPECT_EQ(time_1, time_2);
+}
+
+TEST_F(QuicTimeTest, Add) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+
+  QuicTime::Delta diff = time_2 - time_1;
+
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), diff);
+  EXPECT_EQ(1000, diff.ToMicroseconds());
+  EXPECT_EQ(1, diff.ToMilliseconds());
+}
+
+TEST_F(QuicTimeTest, Subtract) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1), time_2 - time_1);
+}
+
+TEST_F(QuicTimeTest, SubtractDelta) {
+  QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+  EXPECT_EQ(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1),
+            time - QuicTime::Delta::FromMilliseconds(1));
+}
+
+TEST_F(QuicTimeTest, Max) {
+  QuicTime time_1 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1);
+  QuicTime time_2 = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+
+  EXPECT_EQ(time_2, std::max(time_1, time_2));
+}
+
+TEST_F(QuicTimeTest, MockClock) {
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+
+  QuicTime now = clock_.ApproximateNow();
+  QuicTime time = QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1000);
+
+  EXPECT_EQ(now, time);
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  now = clock_.ApproximateNow();
+
+  EXPECT_NE(now, time);
+
+  time = time + QuicTime::Delta::FromMilliseconds(1);
+  EXPECT_EQ(now, time);
+}
+
+TEST_F(QuicTimeTest, LE) {
+  const QuicTime zero = QuicTime::Zero();
+  const QuicTime one = zero + QuicTime::Delta::FromSeconds(1);
+  EXPECT_TRUE(zero <= zero);
+  EXPECT_TRUE(zero <= one);
+  EXPECT_TRUE(one <= one);
+  EXPECT_FALSE(one <= zero);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time_wait_list_manager.cc b/quiche/quic/core/quic_time_wait_list_manager.cc
new file mode 100644
index 0000000..5aeff59
--- /dev/null
+++ b/quiche/quic/core/quic_time_wait_list_manager.cc
@@ -0,0 +1,503 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+
+#include <errno.h>
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+// A very simple alarm that just informs the QuicTimeWaitListManager to clean
+// up old connection_ids. This alarm should be cancelled and deleted before
+// the QuicTimeWaitListManager is deleted.
+class ConnectionIdCleanUpAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit ConnectionIdCleanUpAlarm(
+      QuicTimeWaitListManager* time_wait_list_manager)
+      : time_wait_list_manager_(time_wait_list_manager) {}
+  ConnectionIdCleanUpAlarm(const ConnectionIdCleanUpAlarm&) = delete;
+  ConnectionIdCleanUpAlarm& operator=(const ConnectionIdCleanUpAlarm&) = delete;
+
+  void OnAlarm() override {
+    time_wait_list_manager_->CleanUpOldConnectionIds();
+  }
+
+ private:
+  // Not owned.
+  QuicTimeWaitListManager* time_wait_list_manager_;
+};
+
+TimeWaitConnectionInfo::TimeWaitConnectionInfo(
+    bool ietf_quic,
+    std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+    std::vector<QuicConnectionId> active_connection_ids)
+    : TimeWaitConnectionInfo(ietf_quic,
+                             termination_packets,
+                             std::move(active_connection_ids),
+                             QuicTime::Delta::Zero()) {}
+
+TimeWaitConnectionInfo::TimeWaitConnectionInfo(
+    bool ietf_quic,
+    std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+    std::vector<QuicConnectionId> active_connection_ids,
+    QuicTime::Delta srtt)
+    : ietf_quic(ietf_quic),
+      active_connection_ids(std::move(active_connection_ids)),
+      srtt(srtt) {
+  if (termination_packets != nullptr) {
+    this->termination_packets.swap(*termination_packets);
+  }
+}
+
+QuicTimeWaitListManager::QuicTimeWaitListManager(
+    QuicPacketWriter* writer,
+    Visitor* visitor,
+    const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory)
+    : time_wait_period_(QuicTime::Delta::FromSeconds(
+          GetQuicFlag(FLAGS_quic_time_wait_list_seconds))),
+      connection_id_clean_up_alarm_(
+          alarm_factory->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
+      clock_(clock),
+      writer_(writer),
+      visitor_(visitor) {
+  SetConnectionIdCleanUpAlarm();
+}
+
+QuicTimeWaitListManager::~QuicTimeWaitListManager() {
+  connection_id_clean_up_alarm_->Cancel();
+}
+
+QuicTimeWaitListManager::ConnectionIdMap::iterator
+QuicTimeWaitListManager::FindConnectionIdDataInMap(
+    const QuicConnectionId& connection_id) {
+  auto it = indirect_connection_id_map_.find(connection_id);
+  if (it == indirect_connection_id_map_.end()) {
+    return connection_id_map_.end();
+  }
+  return connection_id_map_.find(it->second);
+}
+
+void QuicTimeWaitListManager::AddConnectionIdDataToMap(
+    const QuicConnectionId& canonical_connection_id,
+    int num_packets,
+    TimeWaitAction action,
+    TimeWaitConnectionInfo info) {
+  for (const auto& cid : info.active_connection_ids) {
+    indirect_connection_id_map_[cid] = canonical_connection_id;
+  }
+  ConnectionIdData data(num_packets, clock_->ApproximateNow(), action,
+                        std::move(info));
+  connection_id_map_.emplace(
+      std::make_pair(canonical_connection_id, std::move(data)));
+}
+
+void QuicTimeWaitListManager::RemoveConnectionDataFromMap(
+    ConnectionIdMap::iterator it) {
+  for (const auto& cid : it->second.info.active_connection_ids) {
+    indirect_connection_id_map_.erase(cid);
+  }
+  connection_id_map_.erase(it);
+}
+
+void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
+    TimeWaitAction action,
+    TimeWaitConnectionInfo info) {
+  QUICHE_DCHECK(!info.active_connection_ids.empty());
+  const QuicConnectionId& canonical_connection_id =
+      info.active_connection_ids.front();
+  QUICHE_DCHECK(action != SEND_TERMINATION_PACKETS ||
+                !info.termination_packets.empty());
+  QUICHE_DCHECK(action != DO_NOTHING || info.ietf_quic);
+  int num_packets = 0;
+  auto it = FindConnectionIdDataInMap(canonical_connection_id);
+  const bool new_connection_id = it == connection_id_map_.end();
+  if (!new_connection_id) {  // Replace record if it is reinserted.
+    num_packets = it->second.num_packets;
+    RemoveConnectionDataFromMap(it);
+  }
+  TrimTimeWaitListIfNeeded();
+  int64_t max_connections =
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
+  QUICHE_DCHECK(connection_id_map_.empty() ||
+                num_connections() < static_cast<size_t>(max_connections));
+  if (new_connection_id) {
+    for (const auto& cid : info.active_connection_ids) {
+      visitor_->OnConnectionAddedToTimeWaitList(cid);
+    }
+  }
+  AddConnectionIdDataToMap(canonical_connection_id, num_packets, action,
+                           std::move(info));
+}
+
+bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
+    QuicConnectionId connection_id) const {
+  return indirect_connection_id_map_.contains(connection_id);
+}
+
+void QuicTimeWaitListManager::OnBlockedWriterCanWrite() {
+  writer_->SetWritable();
+  while (!pending_packets_queue_.empty()) {
+    QueuedPacket* queued_packet = pending_packets_queue_.front().get();
+    if (!WriteToWire(queued_packet)) {
+      return;
+    }
+    pending_packets_queue_.pop_front();
+  }
+}
+
+void QuicTimeWaitListManager::ProcessPacket(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId connection_id,
+    PacketHeaderFormat header_format,
+    size_t received_packet_length,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  QUICHE_DCHECK(IsConnectionIdInTimeWait(connection_id));
+  // TODO(satyamshekhar): Think about handling packets from different peer
+  // addresses.
+  auto it = FindConnectionIdDataInMap(connection_id);
+  QUICHE_DCHECK(it != connection_id_map_.end());
+  // Increment the received packet count.
+  ConnectionIdData* connection_data = &it->second;
+  ++(connection_data->num_packets);
+  const QuicTime now = clock_->ApproximateNow();
+  QuicTime::Delta delta = QuicTime::Delta::Zero();
+  if (now > connection_data->time_added) {
+    delta = now - connection_data->time_added;
+  }
+  OnPacketReceivedForKnownConnection(connection_data->num_packets, delta,
+                                     connection_data->info.srtt);
+
+  if (!ShouldSendResponse(connection_data->num_packets)) {
+    QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
+                    << "throttled";
+    return;
+  }
+
+  QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: "
+                  << "header format=" << header_format
+                  << " ietf=" << connection_data->info.ietf_quic
+                  << ", action=" << connection_data->action
+                  << ", number termination packets="
+                  << connection_data->info.termination_packets.size();
+  switch (connection_data->action) {
+    case SEND_TERMINATION_PACKETS:
+      if (connection_data->info.termination_packets.empty()) {
+        QUIC_BUG(quic_bug_10608_1) << "There are no termination packets.";
+        return;
+      }
+      switch (header_format) {
+        case IETF_QUIC_LONG_HEADER_PACKET:
+          if (!connection_data->info.ietf_quic) {
+            QUIC_CODE_COUNT(quic_received_long_header_packet_for_gquic);
+          }
+          break;
+        case IETF_QUIC_SHORT_HEADER_PACKET:
+          if (!connection_data->info.ietf_quic) {
+            QUIC_CODE_COUNT(quic_received_short_header_packet_for_gquic);
+          }
+          // Send stateless reset in response to short header packets.
+          SendPublicReset(self_address, peer_address, connection_id,
+                          connection_data->info.ietf_quic,
+                          received_packet_length, std::move(packet_context));
+          return;
+        case GOOGLE_QUIC_PACKET:
+          if (connection_data->info.ietf_quic) {
+            QUIC_CODE_COUNT(quic_received_gquic_packet_for_ietf_quic);
+          }
+          break;
+      }
+
+      for (const auto& packet : connection_data->info.termination_packets) {
+        SendOrQueuePacket(std::make_unique<QueuedPacket>(
+                              self_address, peer_address, packet->Clone()),
+                          packet_context.get());
+      }
+      return;
+
+    case SEND_CONNECTION_CLOSE_PACKETS:
+      if (connection_data->info.termination_packets.empty()) {
+        QUIC_BUG(quic_bug_10608_2) << "There are no termination packets.";
+        return;
+      }
+      for (const auto& packet : connection_data->info.termination_packets) {
+        SendOrQueuePacket(std::make_unique<QueuedPacket>(
+                              self_address, peer_address, packet->Clone()),
+                          packet_context.get());
+      }
+      return;
+
+    case SEND_STATELESS_RESET:
+      if (header_format == IETF_QUIC_LONG_HEADER_PACKET) {
+        QUIC_CODE_COUNT(quic_stateless_reset_long_header_packet);
+      }
+      SendPublicReset(self_address, peer_address, connection_id,
+                      connection_data->info.ietf_quic, received_packet_length,
+                      std::move(packet_context));
+      return;
+    case DO_NOTHING:
+      QUIC_CODE_COUNT(quic_time_wait_list_do_nothing);
+      QUICHE_DCHECK(connection_data->info.ietf_quic);
+  }
+}
+
+void QuicTimeWaitListManager::SendVersionNegotiationPacket(
+    QuicConnectionId server_connection_id,
+    QuicConnectionId client_connection_id,
+    bool ietf_quic,
+    bool use_length_prefix,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  std::unique_ptr<QuicEncryptedPacket> version_packet =
+      QuicFramer::BuildVersionNegotiationPacket(
+          server_connection_id, client_connection_id, ietf_quic,
+          use_length_prefix, supported_versions);
+  QUIC_DVLOG(2) << "Dispatcher sending version negotiation packet {"
+                << ParsedQuicVersionVectorToString(supported_versions) << "}, "
+                << (ietf_quic ? "" : "!") << "ietf_quic, "
+                << (use_length_prefix ? "" : "!")
+                << "use_length_prefix:" << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       version_packet->data(), version_packet->length()));
+  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
+                                                   std::move(version_packet)),
+                    packet_context.get());
+}
+
+// Returns true if the number of packets received for this connection_id is a
+// power of 2 to throttle the number of public reset packets we send to a peer.
+bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) {
+  return (received_packet_count & (received_packet_count - 1)) == 0;
+}
+
+void QuicTimeWaitListManager::SendPublicReset(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId connection_id,
+    bool ietf_quic,
+    size_t received_packet_length,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  if (ietf_quic) {
+    std::unique_ptr<QuicEncryptedPacket> ietf_reset_packet =
+        BuildIetfStatelessResetPacket(connection_id, received_packet_length);
+    if (ietf_reset_packet == nullptr) {
+      // This could happen when trying to reject a short header packet of
+      // a connection which is in the time wait list (and with no termination
+      // packet).
+      return;
+    }
+    QUIC_DVLOG(2) << "Dispatcher sending IETF reset packet for "
+                  << connection_id << std::endl
+                  << quiche::QuicheTextUtils::HexDump(
+                         absl::string_view(ietf_reset_packet->data(),
+                                           ietf_reset_packet->length()));
+    SendOrQueuePacket(
+        std::make_unique<QueuedPacket>(self_address, peer_address,
+                                       std::move(ietf_reset_packet)),
+        packet_context.get());
+    return;
+  }
+  // Google QUIC public resets donot elicit resets in response.
+  QuicPublicResetPacket packet;
+  packet.connection_id = connection_id;
+  // TODO(satyamshekhar): generate a valid nonce for this connection_id.
+  packet.nonce_proof = 1010101;
+  // TODO(wub): This is wrong for proxied sessions. Fix it.
+  packet.client_address = peer_address;
+  GetEndpointId(&packet.endpoint_id);
+  // Takes ownership of the packet.
+  std::unique_ptr<QuicEncryptedPacket> reset_packet = BuildPublicReset(packet);
+  QUIC_DVLOG(2) << "Dispatcher sending reset packet for " << connection_id
+                << std::endl
+                << quiche::QuicheTextUtils::HexDump(absl::string_view(
+                       reset_packet->data(), reset_packet->length()));
+  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
+                                                   std::move(reset_packet)),
+                    packet_context.get());
+}
+
+void QuicTimeWaitListManager::SendPacket(const QuicSocketAddress& self_address,
+                                         const QuicSocketAddress& peer_address,
+                                         const QuicEncryptedPacket& packet) {
+  SendOrQueuePacket(std::make_unique<QueuedPacket>(self_address, peer_address,
+                                                   packet.Clone()),
+                    nullptr);
+}
+
+std::unique_ptr<QuicEncryptedPacket> QuicTimeWaitListManager::BuildPublicReset(
+    const QuicPublicResetPacket& packet) {
+  return QuicFramer::BuildPublicResetPacket(packet);
+}
+
+std::unique_ptr<QuicEncryptedPacket>
+QuicTimeWaitListManager::BuildIetfStatelessResetPacket(
+    QuicConnectionId connection_id,
+    size_t received_packet_length) {
+  return QuicFramer::BuildIetfStatelessResetPacket(
+      connection_id, received_packet_length,
+      GetStatelessResetToken(connection_id));
+}
+
+// Either sends the packet and deletes it or makes pending queue the
+// owner of the packet.
+bool QuicTimeWaitListManager::SendOrQueuePacket(
+    std::unique_ptr<QueuedPacket> packet,
+    const QuicPerPacketContext* /*packet_context*/) {
+  if (packet == nullptr) {
+    QUIC_LOG(ERROR) << "Tried to send or queue a null packet";
+    return true;
+  }
+  if (pending_packets_queue_.size() >=
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets)) {
+    // There are too many pending packets.
+    QUIC_CODE_COUNT(quic_too_many_pending_packets_in_time_wait);
+    return true;
+  }
+  if (WriteToWire(packet.get())) {
+    // Allow the packet to be deleted upon leaving this function.
+    return true;
+  }
+  pending_packets_queue_.push_back(std::move(packet));
+  return false;
+}
+
+bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
+  if (writer_->IsWriteBlocked()) {
+    visitor_->OnWriteBlocked(this);
+    return false;
+  }
+  WriteResult result = writer_->WritePacket(
+      queued_packet->packet()->data(), queued_packet->packet()->length(),
+      queued_packet->self_address().host(), queued_packet->peer_address(),
+      nullptr);
+
+  // If using a batch writer and the packet is buffered, flush it.
+  if (writer_->IsBatchMode() && result.status == WRITE_STATUS_OK &&
+      result.bytes_written == 0) {
+    result = writer_->Flush();
+  }
+
+  if (IsWriteBlockedStatus(result.status)) {
+    // If blocked and unbuffered, return false to retry sending.
+    QUICHE_DCHECK(writer_->IsWriteBlocked());
+    visitor_->OnWriteBlocked(this);
+    return result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
+  } else if (IsWriteError(result.status)) {
+    QUIC_LOG_FIRST_N(WARNING, 1)
+        << "Received unknown error while sending termination packet to "
+        << queued_packet->peer_address().ToString() << ": "
+        << strerror(result.error_code);
+  }
+  return true;
+}
+
+void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() {
+  QuicTime::Delta next_alarm_interval = QuicTime::Delta::Zero();
+  if (!connection_id_map_.empty()) {
+    QuicTime oldest_connection_id =
+        connection_id_map_.begin()->second.time_added;
+    QuicTime now = clock_->ApproximateNow();
+    if (now - oldest_connection_id < time_wait_period_) {
+      next_alarm_interval = oldest_connection_id + time_wait_period_ - now;
+    } else {
+      QUIC_LOG(ERROR)
+          << "ConnectionId lingered for longer than time_wait_period_";
+    }
+  } else {
+    // No connection_ids added so none will expire before time_wait_period_.
+    next_alarm_interval = time_wait_period_;
+  }
+
+  connection_id_clean_up_alarm_->Update(
+      clock_->ApproximateNow() + next_alarm_interval, QuicTime::Delta::Zero());
+}
+
+bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
+    QuicTime expiration_time) {
+  if (connection_id_map_.empty()) {
+    return false;
+  }
+  auto it = connection_id_map_.begin();
+  QuicTime oldest_connection_id_time = it->second.time_added;
+  if (oldest_connection_id_time > expiration_time) {
+    // Too recent, don't retire.
+    return false;
+  }
+  // This connection_id has lived its age, retire it now.
+  QUIC_DLOG(INFO) << "Connection " << it->first
+                  << " expired from time wait list";
+  RemoveConnectionDataFromMap(it);
+  if (expiration_time == QuicTime::Infinite()) {
+    QUIC_CODE_COUNT(quic_time_wait_list_trim_full);
+  } else {
+    QUIC_CODE_COUNT(quic_time_wait_list_expire_connections);
+  }
+  return true;
+}
+
+void QuicTimeWaitListManager::CleanUpOldConnectionIds() {
+  QuicTime now = clock_->ApproximateNow();
+  QuicTime expiration = now - time_wait_period_;
+
+  while (MaybeExpireOldestConnection(expiration)) {
+  }
+
+  SetConnectionIdCleanUpAlarm();
+}
+
+void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
+  const int64_t kMaxConnections =
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
+  if (kMaxConnections < 0) {
+    return;
+  }
+  while (!connection_id_map_.empty() &&
+         num_connections() >= static_cast<size_t>(kMaxConnections)) {
+    MaybeExpireOldestConnection(QuicTime::Infinite());
+  }
+}
+
+QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
+    int num_packets,
+    QuicTime time_added,
+    TimeWaitAction action,
+    TimeWaitConnectionInfo info)
+    : num_packets(num_packets),
+      time_added(time_added),
+      action(action),
+      info(std::move(info)) {}
+
+QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
+    ConnectionIdData&& other) = default;
+
+QuicTimeWaitListManager::ConnectionIdData::~ConnectionIdData() = default;
+
+StatelessResetToken QuicTimeWaitListManager::GetStatelessResetToken(
+    QuicConnectionId connection_id) const {
+  return QuicUtils::GenerateStatelessResetToken(connection_id);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_time_wait_list_manager.h b/quiche/quic/core/quic_time_wait_list_manager.h
new file mode 100644
index 0000000..a40fa2f
--- /dev/null
+++ b/quiche/quic/core/quic_time_wait_list_manager.h
@@ -0,0 +1,343 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Handles packets for connection_ids in time wait state by discarding the
+// packet and sending the peers termination packets with exponential backoff.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_blocked_writer_interface.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+namespace test {
+class QuicDispatcherPeer;
+class QuicTimeWaitListManagerPeer;
+}  // namespace test
+
+// TimeWaitConnectionInfo comprises information of a connection which is in the
+// time wait list.
+struct QUIC_NO_EXPORT TimeWaitConnectionInfo {
+  TimeWaitConnectionInfo(
+      bool ietf_quic,
+      std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+      std::vector<QuicConnectionId> active_connection_ids);
+  TimeWaitConnectionInfo(
+      bool ietf_quic,
+      std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets,
+      std::vector<QuicConnectionId> active_connection_ids,
+      QuicTime::Delta srtt);
+
+  TimeWaitConnectionInfo(const TimeWaitConnectionInfo& other) = delete;
+  TimeWaitConnectionInfo(TimeWaitConnectionInfo&& other) = default;
+
+  ~TimeWaitConnectionInfo() = default;
+
+  bool ietf_quic;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  std::vector<QuicConnectionId> active_connection_ids;
+  QuicTime::Delta srtt;
+};
+
+// Maintains a list of all connection_ids that have been recently closed. A
+// connection_id lives in this state for time_wait_period_. All packets received
+// for connection_ids in this state are handed over to the
+// QuicTimeWaitListManager by the QuicDispatcher.  Decides whether to send a
+// public reset packet, a copy of the previously sent connection close packet,
+// or nothing to the peer which sent a packet with the connection_id in time
+// wait state.  After the connection_id expires its time wait period, a new
+// connection/session will be created if a packet is received for this
+// connection_id.
+class QUIC_NO_EXPORT QuicTimeWaitListManager
+    : public QuicBlockedWriterInterface {
+ public:
+  // Specifies what the time wait list manager should do when processing packets
+  // of a time wait connection.
+  enum TimeWaitAction : uint8_t {
+    // Send specified termination packets, error if termination packet is
+    // unavailable.
+    SEND_TERMINATION_PACKETS,
+    // The same as SEND_TERMINATION_PACKETS except that the corresponding
+    // termination packets are provided by the connection.
+    SEND_CONNECTION_CLOSE_PACKETS,
+    // Send stateless reset (public reset for GQUIC).
+    SEND_STATELESS_RESET,
+
+    DO_NOTHING,
+  };
+
+  class QUIC_NO_EXPORT Visitor : public QuicSession::Visitor {
+   public:
+    // Called after the given connection is added to the time-wait list.
+    virtual void OnConnectionAddedToTimeWaitList(
+        QuicConnectionId connection_id) = 0;
+  };
+
+  // writer - the entity that writes to the socket. (Owned by the caller)
+  // visitor - the entity that manages blocked writers. (Owned by the caller)
+  // clock - provide a clock (Owned by the caller)
+  // alarm_factory - used to run clean up alarms. (Owned by the caller)
+  QuicTimeWaitListManager(QuicPacketWriter* writer,
+                          Visitor* visitor,
+                          const QuicClock* clock,
+                          QuicAlarmFactory* alarm_factory);
+  QuicTimeWaitListManager(const QuicTimeWaitListManager&) = delete;
+  QuicTimeWaitListManager& operator=(const QuicTimeWaitListManager&) = delete;
+  ~QuicTimeWaitListManager() override;
+
+  // Adds the connection IDs in info to time wait state for time_wait_period_.
+  // If |info|.termination_packets are provided, copies of these packets will be
+  // sent when a packet with one of these connection IDs is processed. Any
+  // termination packets will be move from |info|.termination_packets and will
+  // become owned by the manager. |action| specifies what the time wait list
+  // manager should do when processing packets of the connection.
+  virtual void AddConnectionIdToTimeWait(TimeWaitAction action,
+                                         TimeWaitConnectionInfo info);
+
+  // Returns true if the connection_id is in time wait state, false otherwise.
+  // Packets received for this connection_id should not lead to creation of new
+  // QuicSessions.
+  bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) const;
+
+  // Called when a packet is received for a connection_id that is in time wait
+  // state. Sends a public reset packet to the peer which sent this
+  // connection_id. Sending of the public reset packet is throttled by using
+  // exponential back off. QUICHE_DCHECKs for the connection_id to be in time
+  // wait state. virtual to override in tests.
+  // TODO(fayang): change ProcessPacket and SendPublicReset to take
+  // ReceivedPacketInfo.
+  virtual void ProcessPacket(
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      QuicConnectionId connection_id,
+      PacketHeaderFormat header_format,
+      size_t received_packet_length,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  // Called by the dispatcher when the underlying socket becomes writable again,
+  // since we might need to send pending public reset packets which we didn't
+  // send because the underlying socket was write blocked.
+  void OnBlockedWriterCanWrite() override;
+
+  bool IsWriterBlocked() const override {
+    return writer_ != nullptr && writer_->IsWriteBlocked();
+  }
+
+  // Used to delete connection_id entries that have outlived their time wait
+  // period.
+  void CleanUpOldConnectionIds();
+
+  // If necessary, trims the oldest connections from the time-wait list until
+  // the size is under the configured maximum.
+  void TrimTimeWaitListIfNeeded();
+
+  // The number of connections on the time-wait list.
+  size_t num_connections() const { return connection_id_map_.size(); }
+
+  // Sends a version negotiation packet for |server_connection_id| and
+  // |client_connection_id| announcing support for |supported_versions| to
+  // |peer_address| from |self_address|.
+  virtual void SendVersionNegotiationPacket(
+      QuicConnectionId server_connection_id,
+      QuicConnectionId client_connection_id,
+      bool ietf_quic,
+      bool use_length_prefix,
+      const ParsedQuicVersionVector& supported_versions,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  // Creates a public reset packet and sends it or queues it to be sent later.
+  virtual void SendPublicReset(
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      QuicConnectionId connection_id,
+      bool ietf_quic,
+      size_t received_packet_length,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  // Called to send |packet|.
+  virtual void SendPacket(const QuicSocketAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          const QuicEncryptedPacket& packet);
+
+  // Return a non-owning pointer to the packet writer.
+  QuicPacketWriter* writer() { return writer_; }
+
+ protected:
+  virtual std::unique_ptr<QuicEncryptedPacket> BuildPublicReset(
+      const QuicPublicResetPacket& packet);
+
+  virtual void GetEndpointId(std::string* /*endpoint_id*/) {}
+
+  // Returns a stateless reset token which will be included in the public reset
+  // packet.
+  virtual StatelessResetToken GetStatelessResetToken(
+      QuicConnectionId connection_id) const;
+
+  // Internal structure to store pending termination packets.
+  class QUIC_NO_EXPORT QueuedPacket {
+   public:
+    QueuedPacket(const QuicSocketAddress& self_address,
+                 const QuicSocketAddress& peer_address,
+                 std::unique_ptr<QuicEncryptedPacket> packet)
+        : self_address_(self_address),
+          peer_address_(peer_address),
+          packet_(std::move(packet)) {}
+    QueuedPacket(const QueuedPacket&) = delete;
+    QueuedPacket& operator=(const QueuedPacket&) = delete;
+
+    const QuicSocketAddress& self_address() const { return self_address_; }
+    const QuicSocketAddress& peer_address() const { return peer_address_; }
+    QuicEncryptedPacket* packet() { return packet_.get(); }
+
+   private:
+    // Server address on which a packet was received for a connection_id in
+    // time wait state.
+    const QuicSocketAddress self_address_;
+    // Address of the peer to send this packet to.
+    const QuicSocketAddress peer_address_;
+    // The pending termination packet that is to be sent to the peer.
+    std::unique_ptr<QuicEncryptedPacket> packet_;
+  };
+
+  // Called right after |packet| is serialized. Either sends the packet and
+  // deletes it or makes pending_packets_queue_ the owner of the packet.
+  // Subclasses overriding this method should call this class's base
+  // implementation at the end of the override.
+  // Return true if |packet| is sent, false if it is queued.
+  virtual bool SendOrQueuePacket(std::unique_ptr<QueuedPacket> packet,
+                                 const QuicPerPacketContext* packet_context);
+
+  const quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>&
+  pending_packets_queue() const {
+    return pending_packets_queue_;
+  }
+
+ private:
+  friend class test::QuicDispatcherPeer;
+  friend class test::QuicTimeWaitListManagerPeer;
+
+  // Decides if a packet should be sent for this connection_id based on the
+  // number of received packets.
+  bool ShouldSendResponse(int received_packet_count);
+
+  // Sends the packet out. Returns true if the packet was successfully consumed.
+  // If the writer got blocked and did not buffer the packet, we'll need to keep
+  // the packet and retry sending. In case of all other errors we drop the
+  // packet.
+  bool WriteToWire(QueuedPacket* packet);
+
+  // Register the alarm server to wake up at appropriate time.
+  void SetConnectionIdCleanUpAlarm();
+
+  // Removes the oldest connection from the time-wait list if it was added prior
+  // to "expiration_time".  To unconditionally remove the oldest connection, use
+  // a QuicTime::Delta:Infinity().  This function modifies the
+  // connection_id_map_.  If you plan to call this function in a loop, any
+  // iterators that you hold before the call to this function may be invalid
+  // afterward.  Returns true if the oldest connection was expired.  Returns
+  // false if the map is empty or the oldest connection has not expired.
+  bool MaybeExpireOldestConnection(QuicTime expiration_time);
+
+  // Called when a packet is received for a connection in this time wait list.
+  virtual void OnPacketReceivedForKnownConnection(
+      int /*num_packets*/,
+      QuicTime::Delta /*delta*/,
+      QuicTime::Delta /*srtt*/) const {}
+
+  std::unique_ptr<QuicEncryptedPacket> BuildIetfStatelessResetPacket(
+      QuicConnectionId connection_id,
+      size_t received_packet_length);
+
+  // A map from a recently closed connection_id to the number of packets
+  // received after the termination of the connection bound to the
+  // connection_id.
+  struct QUIC_NO_EXPORT ConnectionIdData {
+    ConnectionIdData(int num_packets,
+                     QuicTime time_added,
+                     TimeWaitAction action,
+                     TimeWaitConnectionInfo info);
+
+    ConnectionIdData(const ConnectionIdData& other) = delete;
+    ConnectionIdData(ConnectionIdData&& other);
+
+    ~ConnectionIdData();
+
+    int num_packets;
+    QuicTime time_added;
+    TimeWaitAction action;
+    TimeWaitConnectionInfo info;
+  };
+
+  // QuicheLinkedHashMap allows lookup by ConnectionId
+  // and traversal in add order.
+  using ConnectionIdMap = quiche::QuicheLinkedHashMap<QuicConnectionId,
+                                                      ConnectionIdData,
+                                                      QuicConnectionIdHash>;
+  // Do not use find/emplace/erase on this map directly. Use
+  // FindConnectionIdDataInMap, AddConnectionIdDateToMap,
+  // RemoveConnectionDataFromMap instead.
+  ConnectionIdMap connection_id_map_;
+
+  // TODO(haoyuewang) Consider making connection_id_map_ a map of shared pointer
+  // and remove the indirect map.
+  // A connection can have multiple unretired ConnectionIds when it is closed.
+  // These Ids have the same ConnectionIdData entry in connection_id_map_. To
+  // find the entry, look up the cannoical ConnectionId in
+  // indirect_connection_id_map_ first, and look up connection_id_map_ with the
+  // cannoical ConnectionId.
+  absl::flat_hash_map<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>
+      indirect_connection_id_map_;
+
+  // Find an iterator for the given connection_id. Returns
+  // connection_id_map_.end() if none found.
+  ConnectionIdMap::iterator FindConnectionIdDataInMap(
+      const QuicConnectionId& connection_id);
+  // Inserts a ConnectionIdData entry to connection_id_map_.
+  void AddConnectionIdDataToMap(const QuicConnectionId& canonical_connection_id,
+                                int num_packets,
+                                TimeWaitAction action,
+                                TimeWaitConnectionInfo info);
+  // Removes a ConnectionIdData entry in connection_id_map_.
+  void RemoveConnectionDataFromMap(ConnectionIdMap::iterator it);
+
+  // Pending termination packets that need to be sent out to the peer when we
+  // are given a chance to write by the dispatcher.
+  quiche::QuicheCircularDeque<std::unique_ptr<QueuedPacket>>
+      pending_packets_queue_;
+
+  // Time period for which connection_ids should remain in time wait state.
+  const QuicTime::Delta time_wait_period_;
+
+  // Alarm to clean up connection_ids that have out lived their duration in
+  // time wait state.
+  std::unique_ptr<QuicAlarm> connection_id_clean_up_alarm_;
+
+  // Clock to efficiently measure approximate time.
+  const QuicClock* clock_;
+
+  // Interface that writes given buffer to the socket.
+  QuicPacketWriter* writer_;
+
+  // Interface that manages blocked writers.
+  Visitor* visitor_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/quiche/quic/core/quic_time_wait_list_manager_test.cc b/quiche/quic/core/quic_time_wait_list_manager_test.cc
new file mode 100644
index 0000000..ee59fac
--- /dev/null
+++ b/quiche/quic/core/quic_time_wait_list_manager_test.cc
@@ -0,0 +1,788 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+
+#include <cerrno>
+#include <memory>
+#include <ostream>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_time_wait_list_manager_peer.h"
+
+using testing::_;
+using testing::Args;
+using testing::Assign;
+using testing::DoAll;
+using testing::Matcher;
+using testing::NiceMock;
+using testing::Return;
+using testing::ReturnPointee;
+using testing::StrictMock;
+using testing::Truly;
+
+namespace quic {
+namespace test {
+namespace {
+
+const size_t kTestPacketSize = 100;
+
+class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
+ public:
+  FramerVisitorCapturingPublicReset(QuicConnectionId connection_id)
+      : connection_id_(connection_id) {}
+  ~FramerVisitorCapturingPublicReset() override = default;
+
+  void OnPublicResetPacket(const QuicPublicResetPacket& public_reset) override {
+    public_reset_packet_ = public_reset;
+  }
+
+  const QuicPublicResetPacket public_reset_packet() {
+    return public_reset_packet_;
+  }
+
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override {
+    return token == QuicUtils::GenerateStatelessResetToken(connection_id_);
+  }
+
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override {
+    stateless_reset_packet_ = packet;
+  }
+
+  const QuicIetfStatelessResetPacket stateless_reset_packet() {
+    return stateless_reset_packet_;
+  }
+
+ private:
+  QuicPublicResetPacket public_reset_packet_;
+  QuicIetfStatelessResetPacket stateless_reset_packet_;
+  QuicConnectionId connection_id_;
+};
+
+class MockAlarmFactory;
+class MockAlarm : public QuicAlarm {
+ public:
+  explicit MockAlarm(QuicArenaScopedPtr<Delegate> delegate,
+                     int alarm_index,
+                     MockAlarmFactory* factory)
+      : QuicAlarm(std::move(delegate)),
+        alarm_index_(alarm_index),
+        factory_(factory) {}
+  virtual ~MockAlarm() {}
+
+  void SetImpl() override;
+  void CancelImpl() override;
+
+ private:
+  int alarm_index_;
+  MockAlarmFactory* factory_;
+};
+
+class MockAlarmFactory : public QuicAlarmFactory {
+ public:
+  ~MockAlarmFactory() override {}
+
+  // Creates a new platform-specific alarm which will be configured to notify
+  // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
+  // Caller takes ownership of the new alarm, which will not yet be "set" to
+  // fire.
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
+    return new MockAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate),
+                         alarm_index_++, this);
+  }
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override {
+    if (arena != nullptr) {
+      return arena->New<MockAlarm>(std::move(delegate), alarm_index_++, this);
+    }
+    return QuicArenaScopedPtr<MockAlarm>(
+        new MockAlarm(std::move(delegate), alarm_index_++, this));
+  }
+  MOCK_METHOD(void, OnAlarmSet, (int, QuicTime), ());
+  MOCK_METHOD(void, OnAlarmCancelled, (int), ());
+
+ private:
+  int alarm_index_ = 0;
+};
+
+void MockAlarm::SetImpl() {
+  factory_->OnAlarmSet(alarm_index_, deadline());
+}
+
+void MockAlarm::CancelImpl() {
+  factory_->OnAlarmCancelled(alarm_index_);
+}
+
+class QuicTimeWaitListManagerTest : public QuicTest {
+ protected:
+  QuicTimeWaitListManagerTest()
+      : time_wait_list_manager_(&writer_, &visitor_, &clock_, &alarm_factory_),
+        connection_id_(TestConnectionId(45)),
+        peer_address_(TestPeerIPAddress(), kTestPort),
+        writer_is_blocked_(false) {}
+
+  ~QuicTimeWaitListManagerTest() override = default;
+
+  void SetUp() override {
+    EXPECT_CALL(writer_, IsWriteBlocked())
+        .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
+  }
+
+  void AddConnectionId(QuicConnectionId connection_id,
+                       QuicTimeWaitListManager::TimeWaitAction action) {
+    AddConnectionId(connection_id, QuicVersionMax(), action, nullptr);
+  }
+
+  void AddStatelessConnectionId(QuicConnectionId connection_id) {
+    std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+    termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
+        new QuicEncryptedPacket(nullptr, 0, false)));
+    time_wait_list_manager_.AddConnectionIdToTimeWait(
+        QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+        TimeWaitConnectionInfo(false, &termination_packets, {connection_id}));
+  }
+
+  void AddConnectionId(
+      QuicConnectionId connection_id,
+      ParsedQuicVersion version,
+      QuicTimeWaitListManager::TimeWaitAction action,
+      std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
+    time_wait_list_manager_.AddConnectionIdToTimeWait(
+        action, TimeWaitConnectionInfo(version.HasIetfInvariantHeader(),
+                                       packets, {connection_id}));
+  }
+
+  bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
+    return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
+  }
+
+  void ProcessPacket(QuicConnectionId connection_id) {
+    time_wait_list_manager_.ProcessPacket(
+        self_address_, peer_address_, connection_id, GOOGLE_QUIC_PACKET,
+        kTestPacketSize, std::make_unique<QuicPerPacketContext>());
+  }
+
+  QuicEncryptedPacket* ConstructEncryptedPacket(
+      QuicConnectionId destination_connection_id,
+      QuicConnectionId source_connection_id,
+      uint64_t packet_number) {
+    return quic::test::ConstructEncryptedPacket(destination_connection_id,
+                                                source_connection_id, false,
+                                                false, packet_number, "data");
+  }
+
+  MockClock clock_;
+  MockAlarmFactory alarm_factory_;
+  NiceMock<MockPacketWriter> writer_;
+  StrictMock<MockQuicSessionVisitor> visitor_;
+  QuicTimeWaitListManager time_wait_list_manager_;
+  QuicConnectionId connection_id_;
+  QuicSocketAddress self_address_;
+  QuicSocketAddress peer_address_;
+  bool writer_is_blocked_;
+};
+
+bool ValidPublicResetPacketPredicate(
+    QuicConnectionId expected_connection_id,
+    const std::tuple<const char*, int>& packet_buffer) {
+  FramerVisitorCapturingPublicReset visitor(expected_connection_id);
+  QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
+                    Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+  framer.set_visitor(&visitor);
+  QuicEncryptedPacket encrypted(std::get<0>(packet_buffer),
+                                std::get<1>(packet_buffer));
+  framer.ProcessPacket(encrypted);
+  QuicPublicResetPacket packet = visitor.public_reset_packet();
+  bool public_reset_is_valid =
+      expected_connection_id == packet.connection_id &&
+      TestPeerIPAddress() == packet.client_address.host() &&
+      kTestPort == packet.client_address.port();
+
+  QuicIetfStatelessResetPacket stateless_reset =
+      visitor.stateless_reset_packet();
+
+  StatelessResetToken expected_stateless_reset_token =
+      QuicUtils::GenerateStatelessResetToken(expected_connection_id);
+
+  bool stateless_reset_is_valid =
+      stateless_reset.stateless_reset_token == expected_stateless_reset_token;
+
+  return public_reset_is_valid || stateless_reset_is_valid;
+}
+
+Matcher<const std::tuple<const char*, int>> PublicResetPacketEq(
+    QuicConnectionId connection_id) {
+  return Truly(
+      [connection_id](const std::tuple<const char*, int> packet_buffer) {
+        return ValidPublicResetPacketPredicate(connection_id, packet_buffer);
+      });
+}
+
+TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+}
+
+TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddStatelessConnectionId(connection_id_);
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
+          /*use_length_prefix=*/false, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
+      /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendIetfVersionNegotiationPacketWithoutLengthPrefix) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+          /*use_length_prefix=*/false, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+      /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendIetfVersionNegotiationPacket) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+          /*use_length_prefix=*/true, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
+      /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendIetfVersionNegotiationPacketWithClientConnectionId) {
+  std::unique_ptr<QuicEncryptedPacket> packet(
+      QuicFramer::BuildVersionNegotiationPacket(
+          connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
+          /*use_length_prefix=*/true, AllSupportedVersions()));
+  EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
+                                   peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  time_wait_list_manager_.SendVersionNegotiationPacket(
+      connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
+      /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
+      peer_address_, std::make_unique<QuicPerPacketContext>());
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  AddConnectionId(connection_id_, QuicVersionMax(),
+                  QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+                  &termination_packets);
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  AddConnectionId(connection_id_, QuicVersionMax(),
+                  QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+                  &termination_packets);
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .Times(2)
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_,
+                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_,
+                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+  for (int packet_number = 1; packet_number < 101; ++packet_number) {
+    if ((packet_number & (packet_number - 1)) == 0) {
+      EXPECT_CALL(writer_, WritePacket(_, _, _, _, _))
+          .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+    }
+    ProcessPacket(connection_id_);
+    // Send public reset with exponential back off.
+    if ((packet_number & (packet_number - 1)) == 0) {
+      EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
+          &time_wait_list_manager_, packet_number));
+    } else {
+      EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
+          &time_wait_list_manager_, packet_number));
+    }
+  }
+}
+
+TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddStatelessConnectionId(connection_id_);
+
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
+  const size_t kConnectionIdCount = 100;
+  const size_t kOldConnectionIdCount = 31;
+
+  // Add connection_ids such that their expiry time is time_wait_period_.
+  for (uint64_t conn_id = 1; conn_id <= kOldConnectionIdCount; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
+    AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
+  }
+  EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
+
+  // Add remaining connection_ids such that their add time is
+  // 2 * time_wait_period_.
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+  clock_.AdvanceTime(time_wait_period);
+  for (uint64_t conn_id = kOldConnectionIdCount + 1;
+       conn_id <= kConnectionIdCount; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
+    AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
+  }
+  EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
+
+  QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
+  // Now set the current time as time_wait_period + offset usecs.
+  clock_.AdvanceTime(offset);
+  // After all the old connection_ids are cleaned up, check the next alarm
+  // interval.
+  QuicTime next_alarm_time = clock_.Now() + time_wait_period - offset;
+  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
+
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+  for (uint64_t conn_id = 1; conn_id <= kConnectionIdCount; ++conn_id) {
+    QuicConnectionId connection_id = TestConnectionId(conn_id);
+    EXPECT_EQ(conn_id > kOldConnectionIdCount,
+              IsConnectionIdInTimeWait(connection_id))
+        << "kOldConnectionIdCount: " << kOldConnectionIdCount
+        << " connection_id: " << connection_id;
+  }
+  EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
+            time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       CleanUpOldConnectionIdsForMultipleConnectionIdsPerConnection) {
+  connection_id_ = TestConnectionId(7);
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+
+  // Add a CONNECTION_CLOSE termination packet.
+  std::vector<QuicConnectionId> active_connection_ids{connection_id_,
+                                                      TestConnectionId(8)};
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             active_connection_ids, QuicTime::Delta::Zero()));
+
+  EXPECT_TRUE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
+  EXPECT_TRUE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
+
+  // Remove these IDs.
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+  clock_.AdvanceTime(time_wait_period);
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+
+  EXPECT_FALSE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
+  EXPECT_FALSE(
+      time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
+  QuicConnectionId connection_id = TestConnectionId(1);
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
+  AddConnectionId(connection_id, QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
+      connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
+  // Let first write through.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
+  ProcessPacket(connection_id);
+
+  // write block for the next packet.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
+      .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
+                      Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
+  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
+  ProcessPacket(connection_id);
+  // 3rd packet. No public reset should be sent;
+  ProcessPacket(connection_id);
+
+  // write packet should not be called since we are write blocked but the
+  // should be queued.
+  QuicConnectionId other_connection_id = TestConnectionId(2);
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
+  AddConnectionId(other_connection_id,
+                  QuicTimeWaitListManager::SEND_STATELESS_RESET);
+  std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
+      other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
+  EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
+  ProcessPacket(other_connection_id);
+  EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
+
+  // Now expect all the write blocked public reset packets to be sent again.
+  writer_is_blocked_ = false;
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
+  time_wait_list_manager_.OnBlockedWriterCanWrite();
+}
+
+TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
+  // Add connection_ids such that their expiry time is time_wait_period_.
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+  const size_t kConnectionCloseLength = 100;
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  AddConnectionId(connection_id_, QuicVersionMax(),
+                  QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+                  &termination_packets);
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  ProcessPacket(connection_id_);
+
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+
+  QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
+  clock_.AdvanceTime(offset + time_wait_period);
+  // Now set the current time as time_wait_period + offset usecs.
+  QuicTime next_alarm_time = clock_.Now() + time_wait_period;
+  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
+
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
+  EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
+  // Simple randomization: the values of connection_ids are randomly swapped.
+  // If the container is broken, the test will be 50% flaky.
+  const uint64_t conn_id1 = QuicRandom::GetInstance()->RandUint64() % 2;
+  const QuicConnectionId connection_id1 = TestConnectionId(conn_id1);
+  const QuicConnectionId connection_id2 = TestConnectionId(1 - conn_id1);
+
+  // 1 will hash lower than 2, but we add it later. They should come out in the
+  // add order, not hash order.
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
+  AddConnectionId(connection_id1, QuicTimeWaitListManager::DO_NOTHING);
+  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(10));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
+  AddConnectionId(connection_id2, QuicTimeWaitListManager::DO_NOTHING);
+  EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
+
+  const QuicTime::Delta time_wait_period =
+      QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
+  clock_.AdvanceTime(time_wait_period - QuicTime::Delta::FromMicroseconds(9));
+
+  EXPECT_CALL(alarm_factory_, OnAlarmSet(_, _));
+
+  time_wait_list_manager_.CleanUpOldConnectionIds();
+  EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
+  EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
+  EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+}
+
+TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
+  // Basically, shut off time-based eviction.
+  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
+  SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 5);
+
+  uint64_t current_conn_id = 0;
+  const int64_t kMaxConnections =
+      GetQuicFlag(FLAGS_quic_time_wait_list_max_connections);
+  // Add exactly the maximum number of connections
+  for (int64_t i = 0; i < kMaxConnections; ++i) {
+    ++current_conn_id;
+    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
+    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
+    EXPECT_CALL(visitor_,
+                OnConnectionAddedToTimeWaitList(current_connection_id));
+    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
+    EXPECT_EQ(current_conn_id, time_wait_list_manager_.num_connections());
+    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
+  }
+
+  // Now keep adding.  Since we're already at the max, every new connection-id
+  // will evict the oldest one.
+  for (int64_t i = 0; i < kMaxConnections; ++i) {
+    ++current_conn_id;
+    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
+    const QuicConnectionId id_to_evict =
+        TestConnectionId(current_conn_id - kMaxConnections);
+    EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
+    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
+    EXPECT_CALL(visitor_,
+                OnConnectionAddedToTimeWaitList(current_connection_id));
+    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
+    EXPECT_EQ(static_cast<size_t>(kMaxConnections),
+              time_wait_list_manager_.num_connections());
+    EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
+    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
+  }
+}
+
+TEST_F(QuicTimeWaitListManagerTest, ZeroMaxConnections) {
+  // Basically, shut off time-based eviction.
+  SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000);
+  // Keep time wait list empty.
+  SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 0);
+
+  uint64_t current_conn_id = 0;
+  // Add exactly the maximum number of connections
+  for (int64_t i = 0; i < 10; ++i) {
+    ++current_conn_id;
+    QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
+    EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
+    EXPECT_CALL(visitor_,
+                OnConnectionAddedToTimeWaitList(current_connection_id));
+    AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
+    // Verify time wait list always has 1 connection.
+    EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
+    EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
+  }
+}
+
+// Regression test for b/116200989.
+TEST_F(QuicTimeWaitListManagerTest,
+       SendStatelessResetInResponseToShortHeaders) {
+  // This test mimics a scenario where an ENCRYPTION_INITIAL connection close is
+  // added as termination packet for an IETF connection ID. However, a short
+  // header packet is received later.
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             {connection_id_}));
+
+  // Termination packet is not encrypted, instead, send stateless reset.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+  // Processes IETF short header packet.
+  time_wait_list_manager_.ProcessPacket(
+      self_address_, peer_address_, connection_id_,
+      IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
+      std::make_unique<QuicPerPacketContext>());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendConnectionClosePacketsInResponseToShortHeaders) {
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+  // Add a CONNECTION_CLOSE termination packet.
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             {connection_id_}));
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+  // Processes IETF short header packet.
+  time_wait_list_manager_.ProcessPacket(
+      self_address_, peer_address_, connection_id_,
+      IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
+      std::make_unique<QuicPerPacketContext>());
+}
+
+TEST_F(QuicTimeWaitListManagerTest,
+       SendConnectionClosePacketsForMultipleConnectionIds) {
+  connection_id_ = TestConnectionId(7);
+  const size_t kConnectionCloseLength = 100;
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+  EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+  termination_packets.push_back(
+      std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+          new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+
+  // Add a CONNECTION_CLOSE termination packet.
+  std::vector<QuicConnectionId> active_connection_ids{connection_id_,
+                                                      TestConnectionId(8)};
+  time_wait_list_manager_.AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+      TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
+                             active_connection_ids, QuicTime::Delta::Zero()));
+
+  EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+                                   self_address_.host(), peer_address_, _))
+      .Times(2)
+      .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
+  // Processes IETF short header packet.
+  for (auto const& cid : active_connection_ids) {
+    time_wait_list_manager_.ProcessPacket(
+        self_address_, peer_address_, cid, IETF_QUIC_SHORT_HEADER_PACKET,
+        kTestPacketSize, std::make_unique<QuicPerPacketContext>());
+  }
+}
+
+// Regression test for b/184053898.
+TEST_F(QuicTimeWaitListManagerTest, DonotCrashOnNullStatelessReset) {
+  // Received a packet with length <
+  // QuicFramer::GetMinStatelessResetPacketLength(), and this will result in a
+  // null stateless reset.
+  time_wait_list_manager_.SendPublicReset(
+      self_address_, peer_address_, TestConnectionId(1),
+      /*ietf_quic=*/true,
+      /*received_packet_length=*/
+      QuicFramer::GetMinStatelessResetPacketLength() - 1,
+      /*packet_context=*/nullptr);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, SendOrQueueNullPacket) {
+  QuicTimeWaitListManagerPeer::SendOrQueuePacket(&time_wait_list_manager_,
+                                                 nullptr, nullptr);
+}
+
+TEST_F(QuicTimeWaitListManagerTest, TooManyPendingPackets) {
+  SetQuicFlag(FLAGS_quic_time_wait_list_max_pending_packets, 5);
+  const size_t kNumOfUnProcessablePackets = 2048;
+  EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_))
+      .Times(testing::AnyNumber());
+  // Write block for the next packets.
+  EXPECT_CALL(writer_,
+              WritePacket(_, _, self_address_.host(), peer_address_, _))
+      .With(Args<0, 1>(PublicResetPacketEq(TestConnectionId(1))))
+      .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
+                      Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
+  for (size_t i = 0; i < kNumOfUnProcessablePackets; ++i) {
+    time_wait_list_manager_.SendPublicReset(
+        self_address_, peer_address_, TestConnectionId(1),
+        /*ietf_quic=*/true,
+        /*received_packet_length=*/
+        QuicFramer::GetMinStatelessResetPacketLength() + 1,
+        /*packet_context=*/nullptr);
+  }
+  // Verify pending packet queue size is limited.
+  EXPECT_EQ(5u, QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
+                    &time_wait_list_manager_));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_trace_visitor.cc b/quiche/quic/core/quic_trace_visitor.cc
new file mode 100644
index 0000000..d7dd18b
--- /dev/null
+++ b/quiche/quic/core/quic_trace_visitor.cc
@@ -0,0 +1,348 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_trace_visitor.h"
+
+#include <string>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+quic_trace::EncryptionLevel EncryptionLevelToProto(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_INITIAL:
+      return quic_trace::ENCRYPTION_INITIAL;
+    case ENCRYPTION_HANDSHAKE:
+      return quic_trace::ENCRYPTION_HANDSHAKE;
+    case ENCRYPTION_ZERO_RTT:
+      return quic_trace::ENCRYPTION_0RTT;
+    case ENCRYPTION_FORWARD_SECURE:
+      return quic_trace::ENCRYPTION_1RTT;
+    case NUM_ENCRYPTION_LEVELS:
+      QUIC_BUG(quic_bug_10284_1) << "Invalid encryption level specified";
+      return quic_trace::ENCRYPTION_UNKNOWN;
+  }
+}
+
+QuicTraceVisitor::QuicTraceVisitor(const QuicConnection* connection)
+    : connection_(connection),
+      start_time_(connection_->clock()->ApproximateNow()) {
+  std::string binary_connection_id(connection->connection_id().data(),
+                                   connection->connection_id().length());
+  // We assume that the connection ID in gQUIC is equivalent to the
+  // server-chosen client-selected ID.
+  switch (connection->perspective()) {
+    case Perspective::IS_CLIENT:
+      trace_.set_destination_connection_id(binary_connection_id);
+      break;
+    case Perspective::IS_SERVER:
+      trace_.set_source_connection_id(binary_connection_id);
+      break;
+  }
+}
+
+void QuicTraceVisitor::OnPacketSent(
+    QuicPacketNumber packet_number,
+    QuicPacketLength packet_length,
+    bool /*has_crypto_handshake*/,
+    TransmissionType /*transmission_type*/,
+    EncryptionLevel encryption_level,
+    const QuicFrames& retransmittable_frames,
+    const QuicFrames& /*nonretransmittable_frames*/,
+    QuicTime sent_time) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_event_type(quic_trace::PACKET_SENT);
+  event->set_time_us(ConvertTimestampToRecordedFormat(sent_time));
+  event->set_packet_number(packet_number.ToUint64());
+  event->set_packet_size(packet_length);
+  event->set_encryption_level(EncryptionLevelToProto(encryption_level));
+
+  for (const QuicFrame& frame : retransmittable_frames) {
+    switch (frame.type) {
+      case STREAM_FRAME:
+      case RST_STREAM_FRAME:
+      case CONNECTION_CLOSE_FRAME:
+      case WINDOW_UPDATE_FRAME:
+      case BLOCKED_FRAME:
+      case PING_FRAME:
+      case HANDSHAKE_DONE_FRAME:
+      case ACK_FREQUENCY_FRAME:
+        PopulateFrameInfo(frame, event->add_frames());
+        break;
+
+      case PADDING_FRAME:
+      case MTU_DISCOVERY_FRAME:
+      case STOP_WAITING_FRAME:
+      case ACK_FRAME:
+        QUIC_BUG(quic_bug_12732_1)
+            << "Frames of type are not retransmittable and are not supposed "
+               "to be in retransmittable_frames";
+        break;
+
+      // New IETF frames, not used in current gQUIC version.
+      case NEW_CONNECTION_ID_FRAME:
+      case RETIRE_CONNECTION_ID_FRAME:
+      case MAX_STREAMS_FRAME:
+      case STREAMS_BLOCKED_FRAME:
+      case PATH_RESPONSE_FRAME:
+      case PATH_CHALLENGE_FRAME:
+      case STOP_SENDING_FRAME:
+      case MESSAGE_FRAME:
+      case CRYPTO_FRAME:
+      case NEW_TOKEN_FRAME:
+        break;
+
+      // Ignore gQUIC-specific frames.
+      case GOAWAY_FRAME:
+        break;
+
+      case NUM_FRAME_TYPES:
+        QUIC_BUG(quic_bug_10284_2) << "Unknown frame type encountered";
+        break;
+    }
+  }
+
+  // Output PCC DebugState on packet sent for analysis.
+  if (connection_->sent_packet_manager()
+          .GetSendAlgorithm()
+          ->GetCongestionControlType() == kPCC) {
+    PopulateTransportState(event->mutable_transport_state());
+  }
+}
+
+void QuicTraceVisitor::PopulateFrameInfo(const QuicFrame& frame,
+                                         quic_trace::Frame* frame_record) {
+  switch (frame.type) {
+    case STREAM_FRAME: {
+      frame_record->set_frame_type(quic_trace::STREAM);
+
+      quic_trace::StreamFrameInfo* info =
+          frame_record->mutable_stream_frame_info();
+      info->set_stream_id(frame.stream_frame.stream_id);
+      info->set_fin(frame.stream_frame.fin);
+      info->set_offset(frame.stream_frame.offset);
+      info->set_length(frame.stream_frame.data_length);
+      break;
+    }
+
+    case ACK_FRAME: {
+      frame_record->set_frame_type(quic_trace::ACK);
+
+      quic_trace::AckInfo* info = frame_record->mutable_ack_info();
+      info->set_ack_delay_us(frame.ack_frame->ack_delay_time.ToMicroseconds());
+      for (const auto& interval : frame.ack_frame->packets) {
+        quic_trace::AckBlock* block = info->add_acked_packets();
+        // We record intervals as [a, b], whereas the in-memory representation
+        // we currently use is [a, b).
+        block->set_first_packet(interval.min().ToUint64());
+        block->set_last_packet(interval.max().ToUint64() - 1);
+      }
+      break;
+    }
+
+    case RST_STREAM_FRAME: {
+      frame_record->set_frame_type(quic_trace::RESET_STREAM);
+
+      quic_trace::ResetStreamInfo* info =
+          frame_record->mutable_reset_stream_info();
+      info->set_stream_id(frame.rst_stream_frame->stream_id);
+      info->set_final_offset(frame.rst_stream_frame->byte_offset);
+      info->set_application_error_code(frame.rst_stream_frame->error_code);
+      break;
+    }
+
+    case CONNECTION_CLOSE_FRAME: {
+      frame_record->set_frame_type(quic_trace::CONNECTION_CLOSE);
+
+      quic_trace::CloseInfo* info = frame_record->mutable_close_info();
+      info->set_error_code(frame.connection_close_frame->quic_error_code);
+      info->set_reason_phrase(frame.connection_close_frame->error_details);
+      info->set_close_type(static_cast<quic_trace::CloseType>(
+          frame.connection_close_frame->close_type));
+      info->set_transport_close_frame_type(
+          frame.connection_close_frame->transport_close_frame_type);
+      break;
+    }
+
+    case GOAWAY_FRAME:
+      // Do not bother logging this since the frame in question is
+      // gQUIC-specific.
+      break;
+
+    case WINDOW_UPDATE_FRAME: {
+      bool is_connection = frame.window_update_frame.stream_id == 0;
+      frame_record->set_frame_type(is_connection ? quic_trace::MAX_DATA
+                                                 : quic_trace::MAX_STREAM_DATA);
+
+      quic_trace::FlowControlInfo* info =
+          frame_record->mutable_flow_control_info();
+      info->set_max_data(frame.window_update_frame.max_data);
+      if (!is_connection) {
+        info->set_stream_id(frame.window_update_frame.stream_id);
+      }
+      break;
+    }
+
+    case BLOCKED_FRAME: {
+      bool is_connection = frame.blocked_frame.stream_id == 0;
+      frame_record->set_frame_type(is_connection ? quic_trace::BLOCKED
+                                                 : quic_trace::STREAM_BLOCKED);
+
+      quic_trace::FlowControlInfo* info =
+          frame_record->mutable_flow_control_info();
+      if (!is_connection) {
+        info->set_stream_id(frame.window_update_frame.stream_id);
+      }
+      break;
+    }
+
+    case PING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case HANDSHAKE_DONE_FRAME:
+      frame_record->set_frame_type(quic_trace::PING);
+      break;
+
+    case PADDING_FRAME:
+      frame_record->set_frame_type(quic_trace::PADDING);
+      break;
+
+    case STOP_WAITING_FRAME:
+      // We're going to pretend those do not exist.
+      break;
+
+    // New IETF frames, not used in current gQUIC version.
+    case NEW_CONNECTION_ID_FRAME:
+    case RETIRE_CONNECTION_ID_FRAME:
+    case MAX_STREAMS_FRAME:
+    case STREAMS_BLOCKED_FRAME:
+    case PATH_RESPONSE_FRAME:
+    case PATH_CHALLENGE_FRAME:
+    case STOP_SENDING_FRAME:
+    case MESSAGE_FRAME:
+    case CRYPTO_FRAME:
+    case NEW_TOKEN_FRAME:
+    case ACK_FREQUENCY_FRAME:
+      break;
+
+    case NUM_FRAME_TYPES:
+      QUIC_BUG(quic_bug_10284_3) << "Unknown frame type encountered";
+      break;
+  }
+}
+
+void QuicTraceVisitor::OnIncomingAck(
+    QuicPacketNumber /*ack_packet_number*/,
+    EncryptionLevel ack_decrypted_level,
+    const QuicAckFrame& ack_frame,
+    QuicTime ack_receive_time,
+    QuicPacketNumber /*largest_observed*/,
+    bool /*rtt_updated*/,
+    QuicPacketNumber /*least_unacked_sent_packet*/) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(ConvertTimestampToRecordedFormat(ack_receive_time));
+  event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
+  event->set_event_type(quic_trace::PACKET_RECEIVED);
+  event->set_encryption_level(EncryptionLevelToProto(ack_decrypted_level));
+
+  // TODO(vasilvv): consider removing this copy.
+  QuicAckFrame copy_of_ack = ack_frame;
+  PopulateFrameInfo(QuicFrame(&copy_of_ack), event->add_frames());
+  PopulateTransportState(event->mutable_transport_state());
+}
+
+void QuicTraceVisitor::OnPacketLoss(QuicPacketNumber lost_packet_number,
+                                    EncryptionLevel encryption_level,
+                                    TransmissionType /*transmission_type*/,
+                                    QuicTime detection_time) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(ConvertTimestampToRecordedFormat(detection_time));
+  event->set_event_type(quic_trace::PACKET_LOST);
+  event->set_packet_number(lost_packet_number.ToUint64());
+  PopulateTransportState(event->mutable_transport_state());
+  event->set_encryption_level(EncryptionLevelToProto(encryption_level));
+}
+
+void QuicTraceVisitor::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                                           const QuicTime& receive_time) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(ConvertTimestampToRecordedFormat(receive_time));
+  event->set_event_type(quic_trace::PACKET_RECEIVED);
+  event->set_packet_number(connection_->GetLargestReceivedPacket().ToUint64());
+
+  PopulateFrameInfo(QuicFrame(frame), event->add_frames());
+}
+
+void QuicTraceVisitor::OnSuccessfulVersionNegotiation(
+    const ParsedQuicVersion& version) {
+  uint32_t tag =
+      quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version));
+  std::string binary_tag(reinterpret_cast<const char*>(&tag), sizeof(tag));
+  trace_.set_protocol_version(binary_tag);
+}
+
+void QuicTraceVisitor::OnApplicationLimited() {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(
+      ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
+  event->set_event_type(quic_trace::APPLICATION_LIMITED);
+}
+
+void QuicTraceVisitor::OnAdjustNetworkParameters(QuicBandwidth bandwidth,
+                                                 QuicTime::Delta rtt,
+                                                 QuicByteCount /*old_cwnd*/,
+                                                 QuicByteCount /*new_cwnd*/) {
+  quic_trace::Event* event = trace_.add_events();
+  event->set_time_us(
+      ConvertTimestampToRecordedFormat(connection_->clock()->ApproximateNow()));
+  event->set_event_type(quic_trace::EXTERNAL_PARAMETERS);
+
+  quic_trace::ExternalNetworkParameters* parameters =
+      event->mutable_external_network_parameters();
+  if (!bandwidth.IsZero()) {
+    parameters->set_bandwidth_bps(bandwidth.ToBitsPerSecond());
+  }
+  if (!rtt.IsZero()) {
+    parameters->set_rtt_us(rtt.ToMicroseconds());
+  }
+}
+
+uint64_t QuicTraceVisitor::ConvertTimestampToRecordedFormat(
+    QuicTime timestamp) {
+  if (timestamp < start_time_) {
+    QUIC_BUG(quic_bug_10284_4)
+        << "Timestamp went back in time while recording a trace";
+    return 0;
+  }
+
+  return (timestamp - start_time_).ToMicroseconds();
+}
+
+void QuicTraceVisitor::PopulateTransportState(
+    quic_trace::TransportState* state) {
+  const RttStats* rtt_stats = connection_->sent_packet_manager().GetRttStats();
+  state->set_min_rtt_us(rtt_stats->min_rtt().ToMicroseconds());
+  state->set_smoothed_rtt_us(rtt_stats->smoothed_rtt().ToMicroseconds());
+  state->set_last_rtt_us(rtt_stats->latest_rtt().ToMicroseconds());
+
+  state->set_cwnd_bytes(
+      connection_->sent_packet_manager().GetCongestionWindowInBytes());
+  QuicByteCount in_flight =
+      connection_->sent_packet_manager().GetBytesInFlight();
+  state->set_in_flight_bytes(in_flight);
+  state->set_pacing_rate_bps(connection_->sent_packet_manager()
+                                 .GetSendAlgorithm()
+                                 ->PacingRate(in_flight)
+                                 .ToBitsPerSecond());
+
+  if (connection_->sent_packet_manager()
+          .GetSendAlgorithm()
+          ->GetCongestionControlType() == kPCC) {
+    state->set_congestion_control_state(
+        connection_->sent_packet_manager().GetSendAlgorithm()->GetDebugState());
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_trace_visitor.h b/quiche/quic/core/quic_trace_visitor.h
new file mode 100644
index 0000000..ee76fff
--- /dev/null
+++ b/quiche/quic/core/quic_trace_visitor.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
+#define QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
+
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_types.h"
+#include "third_party/quic_trace/lib/quic_trace.pb.h"
+
+namespace quic {
+
+// Records a QUIC trace protocol buffer for a QuicConnection.  It's the
+// responsibility of the user of this visitor to process or store the resulting
+// trace, which can be accessed via trace().
+class QUIC_NO_EXPORT QuicTraceVisitor : public QuicConnectionDebugVisitor {
+ public:
+  explicit QuicTraceVisitor(const QuicConnection* connection);
+
+  void OnPacketSent(QuicPacketNumber packet_number,
+                    QuicPacketLength packet_length,
+                    bool has_crypto_handshake,
+                    TransmissionType transmission_type,
+                    EncryptionLevel encryption_level,
+                    const QuicFrames& retransmittable_frames,
+                    const QuicFrames& nonretransmittable_frames,
+                    QuicTime sent_time) override;
+
+  void OnIncomingAck(QuicPacketNumber ack_packet_number,
+                     EncryptionLevel ack_decrypted_level,
+                     const QuicAckFrame& ack_frame,
+                     QuicTime ack_receive_time,
+                     QuicPacketNumber largest_observed,
+                     bool rtt_updated,
+                     QuicPacketNumber least_unacked_sent_packet) override;
+
+  void OnPacketLoss(QuicPacketNumber lost_packet_number,
+                    EncryptionLevel encryption_level,
+                    TransmissionType transmission_type,
+                    QuicTime detection_time) override;
+
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
+                           const QuicTime& receive_time) override;
+
+  void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& version) override;
+
+  void OnApplicationLimited() override;
+
+  void OnAdjustNetworkParameters(QuicBandwidth bandwidth,
+                                 QuicTime::Delta rtt,
+                                 QuicByteCount old_cwnd,
+                                 QuicByteCount new_cwnd) override;
+
+  // Returns a mutable pointer to the trace.  The trace is owned by the
+  // visitor, but can be moved using Swap() method after the connection is
+  // finished.
+  quic_trace::Trace* trace() { return &trace_; }
+
+ private:
+  // Converts QuicTime into a microsecond delta w.r.t. the beginning of the
+  // connection.
+  uint64_t ConvertTimestampToRecordedFormat(QuicTime timestamp);
+  // Populates a quic_trace::Frame message from |frame|.
+  void PopulateFrameInfo(const QuicFrame& frame,
+                         quic_trace::Frame* frame_record);
+  // Populates a quic_trace::TransportState message from the associated
+  // connection.
+  void PopulateTransportState(quic_trace::TransportState* state);
+
+  quic_trace::Trace trace_;
+  const QuicConnection* connection_;
+  const QuicTime start_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TRACE_VISITOR_H_
diff --git a/quiche/quic/core/quic_trace_visitor_test.cc b/quiche/quic/core/quic_trace_visitor_test.cc
new file mode 100644
index 0000000..9e255b9
--- /dev/null
+++ b/quiche/quic/core/quic_trace_visitor_test.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_trace_visitor.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace {
+
+const QuicByteCount kTransferSize = 1000 * kMaxOutgoingPacketSize;
+const QuicByteCount kTestStreamNumber = 3;
+const QuicTime::Delta kDelay = QuicTime::Delta::FromMilliseconds(20);
+
+// The trace for this test is generated using a simulator transfer.
+class QuicTraceVisitorTest : public QuicTest {
+ public:
+  QuicTraceVisitorTest() {
+    QuicConnectionId connection_id = test::TestConnectionId();
+    simulator::Simulator simulator;
+    simulator::QuicEndpoint client(&simulator, "Client", "Server",
+                                   Perspective::IS_CLIENT, connection_id);
+    simulator::QuicEndpoint server(&simulator, "Server", "Client",
+                                   Perspective::IS_SERVER, connection_id);
+
+    const QuicBandwidth kBandwidth = QuicBandwidth::FromKBitsPerSecond(1000);
+    const QuicByteCount kBdp = kBandwidth * (2 * kDelay);
+
+    // Create parameters such that some loss is observed.
+    simulator::Switch network_switch(&simulator, "Switch", 8, 0.5 * kBdp);
+    simulator::SymmetricLink client_link(&client, network_switch.port(1),
+                                         2 * kBandwidth, kDelay);
+    simulator::SymmetricLink server_link(&server, network_switch.port(2),
+                                         kBandwidth, kDelay);
+
+    QuicTraceVisitor visitor(client.connection());
+    client.connection()->set_debug_visitor(&visitor);
+
+    // Transfer about a megabyte worth of data from client to server.
+    const QuicTime::Delta kDeadline =
+        3 * kBandwidth.TransferTime(kTransferSize);
+    client.AddBytesToTransfer(kTransferSize);
+    bool simulator_result = simulator.RunUntilOrTimeout(
+        [&]() { return server.bytes_received() >= kTransferSize; }, kDeadline);
+    QUICHE_CHECK(simulator_result);
+
+    // Save the trace and ensure some loss was observed.
+    trace_.Swap(visitor.trace());
+    QUICHE_CHECK_NE(0u, client.connection()->GetStats().packets_retransmitted);
+    packets_sent_ = client.connection()->GetStats().packets_sent;
+  }
+
+  std::vector<quic_trace::Event> AllEventsWithType(
+      quic_trace::EventType event_type) {
+    std::vector<quic_trace::Event> result;
+    for (const auto& event : trace_.events()) {
+      if (event.event_type() == event_type) {
+        result.push_back(event);
+      }
+    }
+    return result;
+  }
+
+ protected:
+  quic_trace::Trace trace_;
+  QuicPacketCount packets_sent_;
+};
+
+TEST_F(QuicTraceVisitorTest, ConnectionId) {
+  char expected_cid[] = {0, 0, 0, 0, 0, 0, 0, 42};
+  EXPECT_EQ(std::string(expected_cid, sizeof(expected_cid)),
+            trace_.destination_connection_id());
+}
+
+TEST_F(QuicTraceVisitorTest, Version) {
+  std::string version = trace_.protocol_version();
+  ASSERT_EQ(4u, version.size());
+  // Ensure version isn't all-zeroes.
+  EXPECT_TRUE(version[0] != 0 || version[1] != 0 || version[2] != 0 ||
+              version[3] != 0);
+}
+
+// Check that basic metadata about sent packets is recorded.
+TEST_F(QuicTraceVisitorTest, SentPacket) {
+  auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
+  EXPECT_EQ(packets_sent_, sent_packets.size());
+  ASSERT_GT(sent_packets.size(), 0u);
+
+  EXPECT_EQ(sent_packets[0].packet_size(), kDefaultMaxPacketSize);
+  EXPECT_EQ(sent_packets[0].packet_number(), 1u);
+}
+
+// Ensure that every stream frame that was sent is recorded.
+TEST_F(QuicTraceVisitorTest, SentStream) {
+  auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
+
+  QuicIntervalSet<QuicStreamOffset> offsets;
+  for (const quic_trace::Event& packet : sent_packets) {
+    for (const quic_trace::Frame& frame : packet.frames()) {
+      if (frame.frame_type() != quic_trace::STREAM) {
+        continue;
+      }
+
+      const quic_trace::StreamFrameInfo& info = frame.stream_frame_info();
+      if (info.stream_id() != kTestStreamNumber) {
+        continue;
+      }
+
+      ASSERT_GT(info.length(), 0u);
+      offsets.Add(info.offset(), info.offset() + info.length());
+    }
+  }
+
+  ASSERT_EQ(1u, offsets.Size());
+  EXPECT_EQ(0u, offsets.begin()->min());
+  EXPECT_EQ(kTransferSize, offsets.rbegin()->max());
+}
+
+// Ensure that all packets are either acknowledged or lost.
+TEST_F(QuicTraceVisitorTest, AckPackets) {
+  QuicIntervalSet<QuicPacketNumber> packets;
+  for (const quic_trace::Event& packet : trace_.events()) {
+    if (packet.event_type() == quic_trace::PACKET_RECEIVED) {
+      for (const quic_trace::Frame& frame : packet.frames()) {
+        if (frame.frame_type() != quic_trace::ACK) {
+          continue;
+        }
+
+        const quic_trace::AckInfo& info = frame.ack_info();
+        for (const auto& block : info.acked_packets()) {
+          packets.Add(QuicPacketNumber(block.first_packet()),
+                      QuicPacketNumber(block.last_packet()) + 1);
+        }
+      }
+    }
+    if (packet.event_type() == quic_trace::PACKET_LOST) {
+      packets.Add(QuicPacketNumber(packet.packet_number()),
+                  QuicPacketNumber(packet.packet_number()) + 1);
+    }
+  }
+
+  ASSERT_EQ(1u, packets.Size());
+  EXPECT_EQ(QuicPacketNumber(1u), packets.begin()->min());
+  // We leave some room (20 packets) for the packets which did not receive
+  // conclusive status at the end of simulation.
+  EXPECT_GT(packets.rbegin()->max(), QuicPacketNumber(packets_sent_ - 20));
+}
+
+TEST_F(QuicTraceVisitorTest, TransportState) {
+  auto acks = AllEventsWithType(quic_trace::PACKET_RECEIVED);
+  ASSERT_EQ(1, acks[0].frames_size());
+  ASSERT_EQ(quic_trace::ACK, acks[0].frames(0).frame_type());
+
+  // Check that min-RTT at the end is a reasonable approximation.
+  EXPECT_LE((4 * kDelay).ToMicroseconds() * 1.,
+            acks.rbegin()->transport_state().min_rtt_us());
+  EXPECT_GE((4 * kDelay).ToMicroseconds() * 1.25,
+            acks.rbegin()->transport_state().min_rtt_us());
+}
+
+TEST_F(QuicTraceVisitorTest, EncryptionLevels) {
+  for (const auto& event : trace_.events()) {
+    switch (event.event_type()) {
+      case quic_trace::PACKET_SENT:
+      case quic_trace::PACKET_RECEIVED:
+      case quic_trace::PACKET_LOST:
+        ASSERT_TRUE(event.has_encryption_level());
+        ASSERT_NE(event.encryption_level(), quic_trace::ENCRYPTION_UNKNOWN);
+        break;
+
+      default:
+        break;
+    }
+  }
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/core/quic_transmission_info.cc b/quiche/quic/core/quic_transmission_info.cc
new file mode 100644
index 0000000..1f61dd5
--- /dev/null
+++ b/quiche/quic/core/quic_transmission_info.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "absl/strings/str_cat.h"
+
+namespace quic {
+
+QuicTransmissionInfo::QuicTransmissionInfo()
+    : sent_time(QuicTime::Zero()),
+      bytes_sent(0),
+      encryption_level(ENCRYPTION_INITIAL),
+      transmission_type(NOT_RETRANSMISSION),
+      in_flight(false),
+      state(OUTSTANDING),
+      has_crypto_handshake(false),
+      has_ack_frequency(false) {}
+
+QuicTransmissionInfo::QuicTransmissionInfo(EncryptionLevel level,
+                                           TransmissionType transmission_type,
+                                           QuicTime sent_time,
+                                           QuicPacketLength bytes_sent,
+                                           bool has_crypto_handshake,
+                                           bool has_ack_frequency)
+    : sent_time(sent_time),
+      bytes_sent(bytes_sent),
+      encryption_level(level),
+      transmission_type(transmission_type),
+      in_flight(false),
+      state(OUTSTANDING),
+      has_crypto_handshake(has_crypto_handshake),
+      has_ack_frequency(has_ack_frequency) {}
+
+QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) =
+    default;
+
+QuicTransmissionInfo::~QuicTransmissionInfo() {}
+
+std::string QuicTransmissionInfo::DebugString() const {
+  return absl::StrCat(
+      "{sent_time: ", sent_time.ToDebuggingValue(),
+      ", bytes_sent: ", bytes_sent,
+      ", encryption_level: ", EncryptionLevelToString(encryption_level),
+      ", transmission_type: ", TransmissionTypeToString(transmission_type),
+      ", in_flight: ", in_flight, ", state: ", state,
+      ", has_crypto_handshake: ", has_crypto_handshake,
+      ", has_ack_frequency: ", has_ack_frequency,
+      ", first_sent_after_loss: ", first_sent_after_loss.ToString(),
+      ", largest_acked: ", largest_acked.ToString(),
+      ", retransmittable_frames: ", QuicFramesToString(retransmittable_frames),
+      "}");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_transmission_info.h b/quiche/quic/core/quic_transmission_info.h
new file mode 100644
index 0000000..5a10c07
--- /dev/null
+++ b/quiche/quic/core/quic_transmission_info.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
+#define QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
+
+#include <list>
+
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_ack_listener_interface.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Stores details of a single sent packet.
+struct QUIC_EXPORT_PRIVATE QuicTransmissionInfo {
+  // Used by STL when assigning into a map.
+  QuicTransmissionInfo();
+
+  // Constructs a Transmission with a new all_transmissions set
+  // containing |packet_number|.
+  QuicTransmissionInfo(EncryptionLevel level,
+                       TransmissionType transmission_type,
+                       QuicTime sent_time,
+                       QuicPacketLength bytes_sent,
+                       bool has_crypto_handshake,
+                       bool has_ack_frequency);
+
+  QuicTransmissionInfo(const QuicTransmissionInfo& other);
+
+  ~QuicTransmissionInfo();
+
+  std::string DebugString() const;
+
+  QuicFrames retransmittable_frames;
+  QuicTime sent_time;
+  QuicPacketLength bytes_sent;
+  EncryptionLevel encryption_level;
+  // Reason why this packet was transmitted.
+  TransmissionType transmission_type;
+  // In flight packets have not been abandoned or lost.
+  bool in_flight;
+  // State of this packet.
+  SentPacketState state;
+  // True if the packet contains stream data from the crypto stream.
+  bool has_crypto_handshake;
+  // True if the packet contains ack frequency frame.
+  bool has_ack_frequency;
+  // Records the first sent packet after this packet was detected lost. Zero if
+  // this packet has not been detected lost. This is used to keep lost packet
+  // for another RTT (for potential spurious loss detection)
+  QuicPacketNumber first_sent_after_loss;
+  // The largest_acked in the ack frame, if the packet contains an ack.
+  QuicPacketNumber largest_acked;
+};
+// TODO(ianswett): Add static_assert when size of this struct is reduced below
+// 64 bytes.
+// NOTE(vlovich): Existing static_assert removed because padding differences on
+// 64-bit iOS resulted in an 88-byte struct that is greater than the 84-byte
+// limit on other platforms.  Removing per ianswett's request.
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TRANSMISSION_INFO_H_
diff --git a/quiche/quic/core/quic_types.cc b/quiche/quic/core/quic_types.cc
new file mode 100644
index 0000000..389477b
--- /dev/null
+++ b/quiche/quic/core/quic_types.cc
@@ -0,0 +1,426 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_types.h"
+
+#include <cstdint>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/common/print_elements.h"
+
+namespace quic {
+
+static_assert(sizeof(StatelessResetToken) == kStatelessResetTokenLength,
+              "bad size");
+
+std::ostream& operator<<(std::ostream& os, const QuicConsumedData& s) {
+  os << "bytes_consumed: " << s.bytes_consumed
+     << " fin_consumed: " << s.fin_consumed;
+  return os;
+}
+
+std::string PerspectiveToString(Perspective perspective) {
+  if (perspective == Perspective::IS_SERVER) {
+    return "IS_SERVER";
+  }
+  if (perspective == Perspective::IS_CLIENT) {
+    return "IS_CLIENT";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(perspective), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const Perspective& perspective) {
+  os << PerspectiveToString(perspective);
+  return os;
+}
+
+std::string ConnectionCloseSourceToString(
+    ConnectionCloseSource connection_close_source) {
+  if (connection_close_source == ConnectionCloseSource::FROM_PEER) {
+    return "FROM_PEER";
+  }
+  if (connection_close_source == ConnectionCloseSource::FROM_SELF) {
+    return "FROM_SELF";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(connection_close_source),
+                      ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ConnectionCloseSource& connection_close_source) {
+  os << ConnectionCloseSourceToString(connection_close_source);
+  return os;
+}
+
+std::string ConnectionCloseBehaviorToString(
+    ConnectionCloseBehavior connection_close_behavior) {
+  if (connection_close_behavior == ConnectionCloseBehavior::SILENT_CLOSE) {
+    return "SILENT_CLOSE";
+  }
+  if (connection_close_behavior ==
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET) {
+    return "SEND_CONNECTION_CLOSE_PACKET";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(connection_close_behavior),
+                      ")");
+}
+
+std::ostream& operator<<(
+    std::ostream& os,
+    const ConnectionCloseBehavior& connection_close_behavior) {
+  os << ConnectionCloseBehaviorToString(connection_close_behavior);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const AckedPacket& acked_packet) {
+  os << "{ packet_number: " << acked_packet.packet_number
+     << ", bytes_acked: " << acked_packet.bytes_acked << ", receive_timestamp: "
+     << acked_packet.receive_timestamp.ToDebuggingValue() << "} ";
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const LostPacket& lost_packet) {
+  os << "{ packet_number: " << lost_packet.packet_number
+     << ", bytes_lost: " << lost_packet.bytes_lost << "} ";
+  return os;
+}
+
+std::string HistogramEnumString(WriteStatus enum_value) {
+  switch (enum_value) {
+    case WRITE_STATUS_OK:
+      return "OK";
+    case WRITE_STATUS_BLOCKED:
+      return "BLOCKED";
+    case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
+      return "BLOCKED_DATA_BUFFERED";
+    case WRITE_STATUS_ERROR:
+      return "ERROR";
+    case WRITE_STATUS_MSG_TOO_BIG:
+      return "MSG_TOO_BIG";
+    case WRITE_STATUS_FAILED_TO_COALESCE_PACKET:
+      return "WRITE_STATUS_FAILED_TO_COALESCE_PACKET";
+    case WRITE_STATUS_NUM_VALUES:
+      return "NUM_VALUES";
+  }
+  QUIC_DLOG(ERROR) << "Invalid WriteStatus value: "
+                   << static_cast<int16_t>(enum_value);
+  return "<invalid>";
+}
+
+std::ostream& operator<<(std::ostream& os, const WriteStatus& status) {
+  os << HistogramEnumString(status);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const WriteResult& s) {
+  os << "{ status: " << s.status;
+  if (s.status == WRITE_STATUS_OK) {
+    os << ", bytes_written: " << s.bytes_written;
+  } else {
+    os << ", error_code: " << s.error_code;
+  }
+  os << " }";
+  return os;
+}
+
+MessageResult::MessageResult(MessageStatus status, QuicMessageId message_id)
+    : status(status), message_id(message_id) {}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+std::string QuicFrameTypeToString(QuicFrameType t) {
+  switch (t) {
+    RETURN_STRING_LITERAL(PADDING_FRAME)
+    RETURN_STRING_LITERAL(RST_STREAM_FRAME)
+    RETURN_STRING_LITERAL(CONNECTION_CLOSE_FRAME)
+    RETURN_STRING_LITERAL(GOAWAY_FRAME)
+    RETURN_STRING_LITERAL(WINDOW_UPDATE_FRAME)
+    RETURN_STRING_LITERAL(BLOCKED_FRAME)
+    RETURN_STRING_LITERAL(STOP_WAITING_FRAME)
+    RETURN_STRING_LITERAL(PING_FRAME)
+    RETURN_STRING_LITERAL(CRYPTO_FRAME)
+    RETURN_STRING_LITERAL(HANDSHAKE_DONE_FRAME)
+    RETURN_STRING_LITERAL(STREAM_FRAME)
+    RETURN_STRING_LITERAL(ACK_FRAME)
+    RETURN_STRING_LITERAL(MTU_DISCOVERY_FRAME)
+    RETURN_STRING_LITERAL(NEW_CONNECTION_ID_FRAME)
+    RETURN_STRING_LITERAL(MAX_STREAMS_FRAME)
+    RETURN_STRING_LITERAL(STREAMS_BLOCKED_FRAME)
+    RETURN_STRING_LITERAL(PATH_RESPONSE_FRAME)
+    RETURN_STRING_LITERAL(PATH_CHALLENGE_FRAME)
+    RETURN_STRING_LITERAL(STOP_SENDING_FRAME)
+    RETURN_STRING_LITERAL(MESSAGE_FRAME)
+    RETURN_STRING_LITERAL(NEW_TOKEN_FRAME)
+    RETURN_STRING_LITERAL(RETIRE_CONNECTION_ID_FRAME)
+    RETURN_STRING_LITERAL(ACK_FREQUENCY_FRAME)
+    RETURN_STRING_LITERAL(NUM_FRAME_TYPES)
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(t), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicFrameType& t) {
+  os << QuicFrameTypeToString(t);
+  return os;
+}
+
+std::string QuicIetfFrameTypeString(QuicIetfFrameType t) {
+  if (IS_IETF_STREAM_FRAME(t)) {
+    return "IETF_STREAM";
+  }
+
+  switch (t) {
+    RETURN_STRING_LITERAL(IETF_PADDING);
+    RETURN_STRING_LITERAL(IETF_PING);
+    RETURN_STRING_LITERAL(IETF_ACK);
+    RETURN_STRING_LITERAL(IETF_ACK_ECN);
+    RETURN_STRING_LITERAL(IETF_RST_STREAM);
+    RETURN_STRING_LITERAL(IETF_STOP_SENDING);
+    RETURN_STRING_LITERAL(IETF_CRYPTO);
+    RETURN_STRING_LITERAL(IETF_NEW_TOKEN);
+    RETURN_STRING_LITERAL(IETF_MAX_DATA);
+    RETURN_STRING_LITERAL(IETF_MAX_STREAM_DATA);
+    RETURN_STRING_LITERAL(IETF_MAX_STREAMS_BIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_MAX_STREAMS_UNIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_DATA_BLOCKED);
+    RETURN_STRING_LITERAL(IETF_STREAM_DATA_BLOCKED);
+    RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_BIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_STREAMS_BLOCKED_UNIDIRECTIONAL);
+    RETURN_STRING_LITERAL(IETF_NEW_CONNECTION_ID);
+    RETURN_STRING_LITERAL(IETF_RETIRE_CONNECTION_ID);
+    RETURN_STRING_LITERAL(IETF_PATH_CHALLENGE);
+    RETURN_STRING_LITERAL(IETF_PATH_RESPONSE);
+    RETURN_STRING_LITERAL(IETF_CONNECTION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_APPLICATION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_NO_LENGTH_V99);
+    RETURN_STRING_LITERAL(IETF_EXTENSION_MESSAGE_V99);
+    default:
+      return absl::StrCat("Private value (", t, ")");
+  }
+}
+std::ostream& operator<<(std::ostream& os, const QuicIetfFrameType& c) {
+  os << QuicIetfFrameTypeString(c);
+  return os;
+}
+
+std::string TransmissionTypeToString(TransmissionType transmission_type) {
+  switch (transmission_type) {
+    RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
+    RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
+    RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
+    RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
+    RETURN_STRING_LITERAL(RTO_RETRANSMISSION);
+    RETURN_STRING_LITERAL(TLP_RETRANSMISSION);
+    RETURN_STRING_LITERAL(PTO_RETRANSMISSION);
+    RETURN_STRING_LITERAL(PROBING_RETRANSMISSION);
+    RETURN_STRING_LITERAL(PATH_RETRANSMISSION);
+    RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
+    default:
+      // Some varz rely on this behavior for statistic collection.
+      if (transmission_type == LAST_TRANSMISSION_TYPE + 1) {
+        return "INVALID_TRANSMISSION_TYPE";
+      }
+      return absl::StrCat("Unknown(", static_cast<int>(transmission_type), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
+  os << TransmissionTypeToString(transmission_type);
+  return os;
+}
+
+std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
+  switch (format) {
+    RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
+    RETURN_STRING_LITERAL(IETF_QUIC_SHORT_HEADER_PACKET);
+    RETURN_STRING_LITERAL(GOOGLE_QUIC_PACKET);
+    default:
+      return absl::StrCat("Unknown (", static_cast<int>(format), ")");
+  }
+}
+
+std::string QuicLongHeaderTypeToString(QuicLongHeaderType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
+    RETURN_STRING_LITERAL(INITIAL);
+    RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
+    RETURN_STRING_LITERAL(HANDSHAKE);
+    RETURN_STRING_LITERAL(RETRY);
+    RETURN_STRING_LITERAL(INVALID_PACKET_TYPE);
+    default:
+      return absl::StrCat("Unknown (", static_cast<int>(type), ")");
+  }
+}
+
+std::string MessageStatusToString(MessageStatus message_status) {
+  switch (message_status) {
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_SUCCESS);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_UNSUPPORTED);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_BLOCKED);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_TOO_LARGE);
+    RETURN_STRING_LITERAL(MESSAGE_STATUS_INTERNAL_ERROR);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(message_status), ")");
+  }
+}
+
+std::string MessageResultToString(MessageResult message_result) {
+  if (message_result.status != MESSAGE_STATUS_SUCCESS) {
+    return absl::StrCat("{", MessageStatusToString(message_result.status), "}");
+  }
+  return absl::StrCat("{MESSAGE_STATUS_SUCCESS,id=", message_result.message_id,
+                      "}");
+}
+
+std::ostream& operator<<(std::ostream& os, const MessageResult& mr) {
+  os << MessageResultToString(mr);
+  return os;
+}
+
+std::string PacketNumberSpaceToString(PacketNumberSpace packet_number_space) {
+  switch (packet_number_space) {
+    RETURN_STRING_LITERAL(INITIAL_DATA);
+    RETURN_STRING_LITERAL(HANDSHAKE_DATA);
+    RETURN_STRING_LITERAL(APPLICATION_DATA);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(packet_number_space),
+                          ")");
+  }
+}
+
+std::string SerializedPacketFateToString(SerializedPacketFate fate) {
+  switch (fate) {
+    RETURN_STRING_LITERAL(DISCARD);
+    RETURN_STRING_LITERAL(COALESCE);
+    RETURN_STRING_LITERAL(BUFFER);
+    RETURN_STRING_LITERAL(SEND_TO_WRITER);
+    RETURN_STRING_LITERAL(LEGACY_VERSION_ENCAPSULATE);
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(fate), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
+  os << SerializedPacketFateToString(fate);
+  return os;
+}
+
+std::string EncryptionLevelToString(EncryptionLevel level) {
+  switch (level) {
+    RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
+    RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
+    RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
+    RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(level), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
+  os << EncryptionLevelToString(level);
+  return os;
+}
+
+absl::string_view ClientCertModeToString(ClientCertMode mode) {
+#define RETURN_REASON_LITERAL(x) \
+  case ClientCertMode::x:        \
+    return #x
+  switch (mode) {
+    RETURN_REASON_LITERAL(kNone);
+    RETURN_REASON_LITERAL(kRequest);
+    RETURN_REASON_LITERAL(kRequire);
+    default:
+      return "<invalid>";
+  }
+#undef RETURN_REASON_LITERAL
+}
+
+std::ostream& operator<<(std::ostream& os, ClientCertMode mode) {
+  os << ClientCertModeToString(mode);
+  return os;
+}
+
+std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE);
+    RETURN_STRING_LITERAL(IETF_QUIC_APPLICATION_CONNECTION_CLOSE);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(type), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicConnectionCloseType type) {
+  os << QuicConnectionCloseTypeString(type);
+  return os;
+}
+
+std::string AddressChangeTypeToString(AddressChangeType type) {
+  using IntType = typename std::underlying_type<AddressChangeType>::type;
+  switch (type) {
+    RETURN_STRING_LITERAL(NO_CHANGE);
+    RETURN_STRING_LITERAL(PORT_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
+    default:
+      return absl::StrCat("Unknown(", static_cast<IntType>(type), ")");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, AddressChangeType type) {
+  os << AddressChangeTypeToString(type);
+  return os;
+}
+
+std::string KeyUpdateReasonString(KeyUpdateReason reason) {
+#define RETURN_REASON_LITERAL(x) \
+  case KeyUpdateReason::x:       \
+    return #x
+  switch (reason) {
+    RETURN_REASON_LITERAL(kInvalid);
+    RETURN_REASON_LITERAL(kRemote);
+    RETURN_REASON_LITERAL(kLocalForTests);
+    RETURN_REASON_LITERAL(kLocalForInteropRunner);
+    RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit);
+    RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride);
+    default:
+      return absl::StrCat("Unknown(", static_cast<int>(reason), ")");
+  }
+#undef RETURN_REASON_LITERAL
+}
+
+std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) {
+  os << KeyUpdateReasonString(reason);
+  return os;
+}
+
+bool operator==(const ParsedClientHello& a, const ParsedClientHello& b) {
+  return a.sni == b.sni && a.uaid == b.uaid && a.alpns == b.alpns &&
+         a.legacy_version_encapsulation_inner_packet ==
+             b.legacy_version_encapsulation_inner_packet &&
+         a.retry_token == b.retry_token &&
+         a.resumption_attempted == b.resumption_attempted &&
+         a.early_data_attempted == b.early_data_attempted;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ParsedClientHello& parsed_chlo) {
+  os << "{ sni:" << parsed_chlo.sni << ", uaid:" << parsed_chlo.uaid
+     << ", alpns:" << quiche::PrintElements(parsed_chlo.alpns)
+     << ", len(retry_token):" << parsed_chlo.retry_token.size()
+     << ", len(inner_packet):"
+     << parsed_chlo.legacy_version_encapsulation_inner_packet.size() << " }";
+  return os;
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_types.h b/quiche/quic/core/quic_types.h
new file mode 100644
index 0000000..b136708
--- /dev/null
+++ b/quiche/quic/core/quic_types.h
@@ -0,0 +1,891 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TYPES_H_
+#define QUICHE_QUIC_CORE_QUIC_TYPES_H_
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <ostream>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+using QuicPacketLength = uint16_t;
+using QuicControlFrameId = uint32_t;
+using QuicMessageId = uint32_t;
+
+// TODO(b/181256914) replace QuicDatagramStreamId with QuicStreamId once we
+// remove support for draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+using QuicDatagramStreamId = uint64_t;
+using QuicDatagramContextId = uint64_t;
+// Note that for draft-ietf-masque-h3-datagram-00, we represent the flow ID as a
+// QuicDatagramStreamId.
+
+// IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned
+// 62-bit numbers. However, we have decided to only support up to 2^32-1 streams
+// in order to reduce the size of data structures such as QuicStreamFrame
+// and QuicTransmissionInfo, as that allows them to fit in cache lines and has
+// visible perfomance impact.
+using QuicStreamId = uint32_t;
+
+// Count of stream IDs. Used in MAX_STREAMS and STREAMS_BLOCKED frames.
+using QuicStreamCount = QuicStreamId;
+
+using QuicByteCount = uint64_t;
+using QuicPacketCount = uint64_t;
+using QuicPublicResetNonceProof = uint64_t;
+using QuicStreamOffset = uint64_t;
+using DiversificationNonce = std::array<char, 32>;
+using PacketTimeVector = std::vector<std::pair<QuicPacketNumber, QuicTime>>;
+
+enum : size_t { kStatelessResetTokenLength = 16 };
+using StatelessResetToken = std::array<char, kStatelessResetTokenLength>;
+
+// WebTransport session IDs are stream IDs.
+using WebTransportSessionId = uint64_t;
+// WebTransport stream reset codes are 8-bit.
+using WebTransportStreamError = uint8_t;
+// WebTransport session error codes are 32-bit.
+using WebTransportSessionError = uint32_t;
+
+enum : size_t { kQuicPathFrameBufferSize = 8 };
+using QuicPathFrameBuffer = std::array<uint8_t, kQuicPathFrameBufferSize>;
+
+// The connection id sequence number specifies the order that connection
+// ids must be used in. This is also the sequence number carried in
+// the IETF QUIC NEW_CONNECTION_ID and RETIRE_CONNECTION_ID frames.
+using QuicConnectionIdSequenceNumber = uint64_t;
+
+// A custom data that represents application-specific settings.
+// In HTTP/3 for example, it includes the encoded SETTINGS.
+using ApplicationState = std::vector<uint8_t>;
+
+// A struct for functions which consume data payloads and fins.
+struct QUIC_EXPORT_PRIVATE QuicConsumedData {
+  constexpr QuicConsumedData(size_t bytes_consumed, bool fin_consumed)
+      : bytes_consumed(bytes_consumed), fin_consumed(fin_consumed) {}
+
+  // By default, gtest prints the raw bytes of an object. The bool data
+  // member causes this object to have padding bytes, which causes the
+  // default gtest object printer to read uninitialize memory. So we need
+  // to teach gtest how to print this object.
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os, const QuicConsumedData& s);
+
+  // How many bytes were consumed.
+  size_t bytes_consumed;
+
+  // True if an incoming fin was consumed.
+  bool fin_consumed;
+};
+
+// QuicAsyncStatus enumerates the possible results of an asynchronous
+// operation.
+enum QuicAsyncStatus {
+  QUIC_SUCCESS = 0,
+  QUIC_FAILURE = 1,
+  // QUIC_PENDING results from an operation that will occur asynchronously. When
+  // the operation is complete, a callback's |Run| method will be called.
+  QUIC_PENDING = 2,
+};
+
+// TODO(wtc): see if WriteStatus can be replaced by QuicAsyncStatus.
+enum WriteStatus : int16_t {
+  WRITE_STATUS_OK,
+  // Write is blocked, caller needs to retry.
+  WRITE_STATUS_BLOCKED,
+  // Write is blocked but the packet data is buffered, caller should not retry.
+  WRITE_STATUS_BLOCKED_DATA_BUFFERED,
+  // To make the IsWriteError(WriteStatus) function work properly:
+  // - Non-errors MUST be added before WRITE_STATUS_ERROR.
+  // - Errors MUST be added after WRITE_STATUS_ERROR.
+  WRITE_STATUS_ERROR,
+  WRITE_STATUS_MSG_TOO_BIG,
+  WRITE_STATUS_FAILED_TO_COALESCE_PACKET,
+  WRITE_STATUS_NUM_VALUES,
+};
+
+std::string HistogramEnumString(WriteStatus enum_value);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const WriteStatus& status);
+
+inline std::string HistogramEnumDescription(WriteStatus /*dummy*/) {
+  return "status";
+}
+
+inline bool IsWriteBlockedStatus(WriteStatus status) {
+  return status == WRITE_STATUS_BLOCKED ||
+         status == WRITE_STATUS_BLOCKED_DATA_BUFFERED;
+}
+
+inline bool IsWriteError(WriteStatus status) {
+  return status >= WRITE_STATUS_ERROR;
+}
+
+// A struct used to return the result of write calls including either the number
+// of bytes written or the error code, depending upon the status.
+struct QUIC_EXPORT_PRIVATE WriteResult {
+  constexpr WriteResult(WriteStatus status, int bytes_written_or_error_code)
+      : status(status), bytes_written(bytes_written_or_error_code) {}
+
+  constexpr WriteResult() : WriteResult(WRITE_STATUS_ERROR, 0) {}
+
+  bool operator==(const WriteResult& other) const {
+    if (status != other.status) {
+      return false;
+    }
+    switch (status) {
+      case WRITE_STATUS_OK:
+        return bytes_written == other.bytes_written;
+      case WRITE_STATUS_BLOCKED:
+      case WRITE_STATUS_BLOCKED_DATA_BUFFERED:
+        return true;
+      default:
+        return error_code == other.error_code;
+    }
+  }
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const WriteResult& s);
+
+  WriteStatus status;
+  // Number of packets dropped as a result of this write.
+  // Only used by batch writers. Otherwise always 0.
+  uint16_t dropped_packets = 0;
+  // The delta between a packet's ideal and actual send time:
+  //     actual_send_time = ideal_send_time + send_time_offset
+  //                      = (now + release_time_delay) + send_time_offset
+  // Only valid if |status| is WRITE_STATUS_OK.
+  QuicTime::Delta send_time_offset = QuicTime::Delta::Zero();
+  // TODO(wub): In some cases, WRITE_STATUS_ERROR may set an error_code and
+  // WRITE_STATUS_BLOCKED_DATA_BUFFERED may set bytes_written. This may need
+  // some cleaning up so that perhaps both values can be set and valid.
+  union {
+    int bytes_written;  // only valid when status is WRITE_STATUS_OK
+    int error_code;     // only valid when status is WRITE_STATUS_ERROR
+  };
+};
+
+enum TransmissionType : int8_t {
+  NOT_RETRANSMISSION,
+  FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
+  HANDSHAKE_RETRANSMISSION,     // Retransmits due to handshake timeouts.
+  ALL_ZERO_RTT_RETRANSMISSION,  // Retransmits all packets encrypted with 0-RTT
+                                // key.
+  LOSS_RETRANSMISSION,          // Retransmits due to loss detection.
+  RTO_RETRANSMISSION,           // Retransmits due to retransmit time out.
+  TLP_RETRANSMISSION,           // Tail loss probes.
+  PTO_RETRANSMISSION,           // Retransmission due to probe timeout.
+  PROBING_RETRANSMISSION,       // Retransmission in order to probe bandwidth.
+  PATH_RETRANSMISSION,          // Retransmission proactively due to underlying
+                                // network change.
+  ALL_INITIAL_RETRANSMISSION,   // Retransmit all packets encrypted with INITIAL
+                                // key.
+  LAST_TRANSMISSION_TYPE = ALL_INITIAL_RETRANSMISSION,
+};
+
+QUIC_EXPORT_PRIVATE std::string TransmissionTypeToString(
+    TransmissionType transmission_type);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, TransmissionType transmission_type);
+
+enum HasRetransmittableData : uint8_t {
+  NO_RETRANSMITTABLE_DATA,
+  HAS_RETRANSMITTABLE_DATA,
+};
+
+enum IsHandshake : uint8_t { NOT_HANDSHAKE, IS_HANDSHAKE };
+
+enum class Perspective : uint8_t { IS_SERVER, IS_CLIENT };
+
+QUIC_EXPORT_PRIVATE std::string PerspectiveToString(Perspective perspective);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const Perspective& perspective);
+
+// Describes whether a ConnectionClose was originated by the peer.
+enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
+
+QUIC_EXPORT_PRIVATE std::string ConnectionCloseSourceToString(
+    ConnectionCloseSource connection_close_source);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ConnectionCloseSource& connection_close_source);
+
+// Should a connection be closed silently or not.
+enum class ConnectionCloseBehavior {
+  SILENT_CLOSE,
+  SILENT_CLOSE_WITH_CONNECTION_CLOSE_PACKET_SERIALIZED,
+  SEND_CONNECTION_CLOSE_PACKET
+};
+
+QUIC_EXPORT_PRIVATE std::string ConnectionCloseBehaviorToString(
+    ConnectionCloseBehavior connection_close_behavior);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ConnectionCloseBehavior& connection_close_behavior);
+
+enum QuicFrameType : uint8_t {
+  // Regular frame types. The values set here cannot change without the
+  // introduction of a new QUIC version.
+  PADDING_FRAME = 0,
+  RST_STREAM_FRAME = 1,
+  CONNECTION_CLOSE_FRAME = 2,
+  GOAWAY_FRAME = 3,
+  WINDOW_UPDATE_FRAME = 4,
+  BLOCKED_FRAME = 5,
+  STOP_WAITING_FRAME = 6,
+  PING_FRAME = 7,
+  CRYPTO_FRAME = 8,
+  // TODO(b/157935330): stop hard coding this when deprecate T050.
+  HANDSHAKE_DONE_FRAME = 9,
+
+  // STREAM and ACK frames are special frames. They are encoded differently on
+  // the wire and their values do not need to be stable.
+  STREAM_FRAME,
+  ACK_FRAME,
+  // The path MTU discovery frame is encoded as a PING frame on the wire.
+  MTU_DISCOVERY_FRAME,
+
+  // These are for IETF-specific frames for which there is no mapping
+  // from Google QUIC frames. These are valid/allowed if and only if IETF-
+  // QUIC has been negotiated. Values are not important, they are not
+  // the values that are in the packets (see QuicIetfFrameType, below).
+  NEW_CONNECTION_ID_FRAME,
+  MAX_STREAMS_FRAME,
+  STREAMS_BLOCKED_FRAME,
+  PATH_RESPONSE_FRAME,
+  PATH_CHALLENGE_FRAME,
+  STOP_SENDING_FRAME,
+  MESSAGE_FRAME,
+  NEW_TOKEN_FRAME,
+  RETIRE_CONNECTION_ID_FRAME,
+  ACK_FREQUENCY_FRAME,
+
+  NUM_FRAME_TYPES
+};
+
+// Human-readable string suitable for logging.
+QUIC_EXPORT_PRIVATE std::string QuicFrameTypeToString(QuicFrameType t);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const QuicFrameType& t);
+
+// Ietf frame types. These are defined in the IETF QUIC Specification.
+// Explicit values are given in the enum so that we can be sure that
+// the symbol will map to the correct stream type.
+// All types are defined here, even if we have not yet implmented the
+// quic/core/stream/.... stuff needed.
+// Note: The protocol specifies that frame types are varint-62 encoded,
+// further stating that the shortest encoding must be used.  The current set of
+// frame types all have values less than 0x40 (64) so can be encoded in a single
+// byte, with the two most significant bits being 0. Thus, the following
+// enumerations are valid as both the numeric values of frame types AND their
+// encodings.
+enum QuicIetfFrameType : uint64_t {
+  IETF_PADDING = 0x00,
+  IETF_PING = 0x01,
+  IETF_ACK = 0x02,
+  IETF_ACK_ECN = 0x03,
+  IETF_RST_STREAM = 0x04,
+  IETF_STOP_SENDING = 0x05,
+  IETF_CRYPTO = 0x06,
+  IETF_NEW_TOKEN = 0x07,
+  // the low-3 bits of the stream frame type value are actually flags
+  // declaring what parts of the frame are/are-not present, as well as
+  // some other control information. The code would then do something
+  // along the lines of "if ((frame_type & 0xf8) == 0x08)" to determine
+  // whether the frame is a stream frame or not, and then examine each
+  // bit specifically when/as needed.
+  IETF_STREAM = 0x08,
+  // 0x09 through 0x0f are various flag settings of the IETF_STREAM frame.
+  IETF_MAX_DATA = 0x10,
+  IETF_MAX_STREAM_DATA = 0x11,
+  IETF_MAX_STREAMS_BIDIRECTIONAL = 0x12,
+  IETF_MAX_STREAMS_UNIDIRECTIONAL = 0x13,
+  IETF_DATA_BLOCKED = 0x14,
+  IETF_STREAM_DATA_BLOCKED = 0x15,
+  IETF_STREAMS_BLOCKED_BIDIRECTIONAL = 0x16,
+  IETF_STREAMS_BLOCKED_UNIDIRECTIONAL = 0x17,
+  IETF_NEW_CONNECTION_ID = 0x18,
+  IETF_RETIRE_CONNECTION_ID = 0x19,
+  IETF_PATH_CHALLENGE = 0x1a,
+  IETF_PATH_RESPONSE = 0x1b,
+  // Both of the following are "Connection Close" frames,
+  // the first signals transport-layer errors, the second application-layer
+  // errors.
+  IETF_CONNECTION_CLOSE = 0x1c,
+  IETF_APPLICATION_CLOSE = 0x1d,
+
+  IETF_HANDSHAKE_DONE = 0x1e,
+
+  // The MESSAGE frame type has not yet been fully standardized.
+  // QUIC versions starting with 46 and before 99 use 0x20-0x21.
+  // IETF QUIC (v99) uses 0x30-0x31, see draft-pauly-quic-datagram.
+  IETF_EXTENSION_MESSAGE_NO_LENGTH = 0x20,
+  IETF_EXTENSION_MESSAGE = 0x21,
+  IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30,
+  IETF_EXTENSION_MESSAGE_V99 = 0x31,
+
+  // An QUIC extension frame for sender control of acknowledgement delays
+  IETF_ACK_FREQUENCY = 0xaf,
+
+  // A QUIC extension frame which augments the IETF_ACK frame definition with
+  // packet receive timestamps.
+  // TODO(ianswett): Determine a proper value to replace this temporary value.
+  IETF_ACK_RECEIVE_TIMESTAMPS = 0x22,
+};
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const QuicIetfFrameType& c);
+QUIC_EXPORT_PRIVATE std::string QuicIetfFrameTypeString(QuicIetfFrameType t);
+
+// Masks for the bits that indicate the frame is a Stream frame vs the
+// bits used as flags.
+#define IETF_STREAM_FRAME_TYPE_MASK 0xfffffffffffffff8
+#define IETF_STREAM_FRAME_FLAG_MASK 0x07
+#define IS_IETF_STREAM_FRAME(_stype_) \
+  (((_stype_)&IETF_STREAM_FRAME_TYPE_MASK) == IETF_STREAM)
+
+// These are the values encoded in the low-order 3 bits of the
+// IETF_STREAMx frame type.
+#define IETF_STREAM_FRAME_FIN_BIT 0x01
+#define IETF_STREAM_FRAME_LEN_BIT 0x02
+#define IETF_STREAM_FRAME_OFF_BIT 0x04
+
+enum QuicVariableLengthIntegerLength : uint8_t {
+  // Length zero means the variable length integer is not present.
+  VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0,
+  VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1,
+  VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2,
+  VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4,
+  VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8,
+
+  // By default we write the IETF long header length using the 2-byte encoding
+  // of variable length integers, even when the length is below 64, which allows
+  // us to fill in the length before knowing what the length actually is.
+  kQuicDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2,
+};
+
+enum QuicPacketNumberLength : uint8_t {
+  PACKET_1BYTE_PACKET_NUMBER = 1,
+  PACKET_2BYTE_PACKET_NUMBER = 2,
+  PACKET_3BYTE_PACKET_NUMBER = 3,  // Used in versions 45+.
+  PACKET_4BYTE_PACKET_NUMBER = 4,
+  IETF_MAX_PACKET_NUMBER_LENGTH = 4,
+  // TODO(b/145819870): Remove 6 and 8 when we remove Q043 since these values
+  // are not representable with later versions.
+  PACKET_6BYTE_PACKET_NUMBER = 6,
+  PACKET_8BYTE_PACKET_NUMBER = 8
+};
+
+// Used to indicate a QuicSequenceNumberLength using two flag bits.
+enum QuicPacketNumberLengthFlags {
+  PACKET_FLAGS_1BYTE_PACKET = 0,           // 00
+  PACKET_FLAGS_2BYTE_PACKET = 1,           // 01
+  PACKET_FLAGS_4BYTE_PACKET = 1 << 1,      // 10
+  PACKET_FLAGS_8BYTE_PACKET = 1 << 1 | 1,  // 11
+};
+
+// The public flags are specified in one byte.
+enum QuicPacketPublicFlags {
+  PACKET_PUBLIC_FLAGS_NONE = 0,
+
+  // Bit 0: Does the packet header contains version info?
+  PACKET_PUBLIC_FLAGS_VERSION = 1 << 0,
+
+  // Bit 1: Is this packet a public reset packet?
+  PACKET_PUBLIC_FLAGS_RST = 1 << 1,
+
+  // Bit 2: indicates the header includes a nonce.
+  PACKET_PUBLIC_FLAGS_NONCE = 1 << 2,
+
+  // Bit 3: indicates whether a ConnectionID is included.
+  PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID = 0,
+  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID = 1 << 3,
+
+  // Deprecated version 32 and earlier used two bits to indicate an 8-byte
+  // connection ID. We send this from the client because of some broken
+  // middleboxes that are still checking this bit.
+  PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD = 1 << 3 | 1 << 2,
+
+  // Bits 4 and 5 describe the packet number length as follows:
+  // --00----: 1 byte
+  // --01----: 2 bytes
+  // --10----: 4 bytes
+  // --11----: 6 bytes
+  PACKET_PUBLIC_FLAGS_1BYTE_PACKET = PACKET_FLAGS_1BYTE_PACKET << 4,
+  PACKET_PUBLIC_FLAGS_2BYTE_PACKET = PACKET_FLAGS_2BYTE_PACKET << 4,
+  PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4,
+  PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_8BYTE_PACKET << 4,
+
+  // Reserved, unimplemented flags:
+
+  // Bit 7: indicates the presence of a second flags byte.
+  PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7,
+
+  // All bits set (bits 6 and 7 are not currently used): 00111111
+  PACKET_PUBLIC_FLAGS_MAX = (1 << 6) - 1,
+};
+
+// The private flags are specified in one byte.
+enum QuicPacketPrivateFlags {
+  PACKET_PRIVATE_FLAGS_NONE = 0,
+
+  // Bit 0: Does this packet contain an entropy bit?
+  PACKET_PRIVATE_FLAGS_ENTROPY = 1 << 0,
+
+  // (bits 1-7 are not used): 00000001
+  PACKET_PRIVATE_FLAGS_MAX = (1 << 1) - 1
+};
+
+// Defines for all types of congestion control algorithms that can be used in
+// QUIC. Note that this is separate from the congestion feedback type -
+// some congestion control algorithms may use the same feedback type
+// (Reno and Cubic are the classic example for that).
+enum CongestionControlType {
+  kCubicBytes,
+  kRenoBytes,
+  kBBR,
+  kPCC,
+  kGoogCC,
+  kBBRv2,
+};
+
+// EncryptionLevel enumerates the stages of encryption that a QUIC connection
+// progresses through. When retransmitting a packet, the encryption level needs
+// to be specified so that it is retransmitted at a level which the peer can
+// understand.
+enum EncryptionLevel : int8_t {
+  ENCRYPTION_INITIAL = 0,
+  ENCRYPTION_HANDSHAKE = 1,
+  ENCRYPTION_ZERO_RTT = 2,
+  ENCRYPTION_FORWARD_SECURE = 3,
+
+  NUM_ENCRYPTION_LEVELS,
+};
+
+inline bool EncryptionLevelIsValid(EncryptionLevel level) {
+  return ENCRYPTION_INITIAL <= level && level < NUM_ENCRYPTION_LEVELS;
+}
+
+QUIC_EXPORT_PRIVATE std::string EncryptionLevelToString(EncryptionLevel level);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             EncryptionLevel level);
+
+// Enumeration of whether a server endpoint will request a client certificate,
+// and whether that endpoint requires a valid client certificate to establish a
+// connection.
+enum class ClientCertMode : uint8_t {
+  kNone,     // Do not request a client certificate.  Default server behavior.
+  kRequest,  // Request a certificate, but allow unauthenticated connections.
+  kRequire,  // Require clients to provide a valid certificate.
+};
+
+QUIC_EXPORT_PRIVATE absl::string_view ClientCertModeToString(
+    ClientCertMode mode);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             ClientCertMode mode);
+
+enum AddressChangeType : uint8_t {
+  // IP address and port remain unchanged.
+  NO_CHANGE,
+  // Port changed, but IP address remains unchanged.
+  PORT_CHANGE,
+  // IPv4 address changed, but within the /24 subnet (port may have changed.)
+  IPV4_SUBNET_CHANGE,
+  // IPv4 address changed, excluding /24 subnet change (port may have changed.)
+  IPV4_TO_IPV4_CHANGE,
+  // IP address change from an IPv4 to an IPv6 address (port may have changed.)
+  IPV4_TO_IPV6_CHANGE,
+  // IP address change from an IPv6 to an IPv4 address (port may have changed.)
+  IPV6_TO_IPV4_CHANGE,
+  // IP address change from an IPv6 to an IPv6 address (port may have changed.)
+  IPV6_TO_IPV6_CHANGE,
+};
+
+QUIC_EXPORT_PRIVATE std::string AddressChangeTypeToString(
+    AddressChangeType type);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             AddressChangeType type);
+
+enum StreamSendingState {
+  // Sender has more data to send on this stream.
+  NO_FIN,
+  // Sender is done sending on this stream.
+  FIN,
+  // Sender is done sending on this stream and random padding needs to be
+  // appended after all stream frames.
+  FIN_AND_PADDING,
+};
+
+enum SentPacketState : uint8_t {
+  // The packet is in flight and waiting to be acked.
+  OUTSTANDING,
+  FIRST_PACKET_STATE = OUTSTANDING,
+  // The packet was never sent.
+  NEVER_SENT,
+  // The packet has been acked.
+  ACKED,
+  // This packet is not expected to be acked.
+  UNACKABLE,
+  // This packet has been delivered or unneeded.
+  NEUTERED,
+
+  // States below are corresponding to retransmission types in TransmissionType.
+
+  // This packet has been retransmitted when retransmission timer fires in
+  // HANDSHAKE mode.
+  HANDSHAKE_RETRANSMITTED,
+  // This packet is considered as lost, this is used for LOST_RETRANSMISSION.
+  LOST,
+  // This packet has been retransmitted when TLP fires.
+  TLP_RETRANSMITTED,
+  // This packet has been retransmitted when RTO fires.
+  RTO_RETRANSMITTED,
+  // This packet has been retransmitted when PTO fires.
+  PTO_RETRANSMITTED,
+  // This packet has been retransmitted for probing purpose.
+  PROBE_RETRANSMITTED,
+  // This packet is sent on a different path or is a PING only packet.
+  // Do not update RTT stats and congestion control if the packet is the
+  // largest_acked of an incoming ACK.
+  NOT_CONTRIBUTING_RTT,
+  LAST_PACKET_STATE = NOT_CONTRIBUTING_RTT,
+};
+
+enum PacketHeaderFormat : uint8_t {
+  IETF_QUIC_LONG_HEADER_PACKET,
+  IETF_QUIC_SHORT_HEADER_PACKET,
+  GOOGLE_QUIC_PACKET,
+};
+
+QUIC_EXPORT_PRIVATE std::string PacketHeaderFormatToString(
+    PacketHeaderFormat format);
+
+// Information about a newly acknowledged packet.
+struct QUIC_EXPORT_PRIVATE AckedPacket {
+  constexpr AckedPacket(QuicPacketNumber packet_number,
+                        QuicPacketLength bytes_acked,
+                        QuicTime receive_timestamp)
+      : packet_number(packet_number),
+        bytes_acked(bytes_acked),
+        receive_timestamp(receive_timestamp) {}
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const AckedPacket& acked_packet);
+
+  QuicPacketNumber packet_number;
+  // Number of bytes sent in the packet that was acknowledged.
+  QuicPacketLength bytes_acked;
+  // The time |packet_number| was received by the peer, according to the
+  // optional timestamp the peer included in the ACK frame which acknowledged
+  // |packet_number|. Zero if no timestamp was available for this packet.
+  QuicTime receive_timestamp;
+};
+
+// A vector of acked packets.
+using AckedPacketVector = absl::InlinedVector<AckedPacket, 2>;
+
+// Information about a newly lost packet.
+struct QUIC_EXPORT_PRIVATE LostPacket {
+  LostPacket(QuicPacketNumber packet_number, QuicPacketLength bytes_lost)
+      : packet_number(packet_number), bytes_lost(bytes_lost) {}
+
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os, const LostPacket& lost_packet);
+
+  QuicPacketNumber packet_number;
+  // Number of bytes sent in the packet that was lost.
+  QuicPacketLength bytes_lost;
+};
+
+// A vector of lost packets.
+using LostPacketVector = absl::InlinedVector<LostPacket, 2>;
+
+// Please note, this value cannot used directly for packet serialization.
+enum QuicLongHeaderType : uint8_t {
+  VERSION_NEGOTIATION,
+  INITIAL,
+  ZERO_RTT_PROTECTED,
+  HANDSHAKE,
+  RETRY,
+
+  INVALID_PACKET_TYPE,
+};
+
+QUIC_EXPORT_PRIVATE std::string QuicLongHeaderTypeToString(
+    QuicLongHeaderType type);
+
+enum QuicPacketHeaderTypeFlags : uint8_t {
+  // Bit 2: Key phase bit for IETF QUIC short header packets.
+  FLAGS_KEY_PHASE_BIT = 1 << 2,
+  // Bit 3: Google QUIC Demultiplexing bit, the short header always sets this
+  // bit to 0, allowing to distinguish Google QUIC packets from short header
+  // packets.
+  FLAGS_DEMULTIPLEXING_BIT = 1 << 3,
+  // Bits 4 and 5: Reserved bits for short header.
+  FLAGS_SHORT_HEADER_RESERVED_1 = 1 << 4,
+  FLAGS_SHORT_HEADER_RESERVED_2 = 1 << 5,
+  // Bit 6: the 'QUIC' bit.
+  FLAGS_FIXED_BIT = 1 << 6,
+  // Bit 7: Indicates the header is long or short header.
+  FLAGS_LONG_HEADER = 1 << 7,
+};
+
+enum MessageStatus {
+  MESSAGE_STATUS_SUCCESS,
+  MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED,  // Failed to send message because
+                                              // encryption is not established
+                                              // yet.
+  MESSAGE_STATUS_UNSUPPORTED,  // Failed to send message because MESSAGE frame
+                               // is not supported by the connection.
+  MESSAGE_STATUS_BLOCKED,      // Failed to send message because connection is
+                           // congestion control blocked or underlying socket is
+                           // write blocked.
+  MESSAGE_STATUS_TOO_LARGE,  // Failed to send message because the message is
+                             // too large to fit into a single packet.
+  MESSAGE_STATUS_INTERNAL_ERROR,  // Failed to send message because connection
+                                  // reaches an invalid state.
+};
+
+QUIC_EXPORT_PRIVATE std::string MessageStatusToString(
+    MessageStatus message_status);
+
+// Used to return the result of SendMessage calls
+struct QUIC_EXPORT_PRIVATE MessageResult {
+  MessageResult(MessageStatus status, QuicMessageId message_id);
+
+  bool operator==(const MessageResult& other) const {
+    return status == other.status && message_id == other.message_id;
+  }
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const MessageResult& mr);
+
+  MessageStatus status;
+  // Only valid when status is MESSAGE_STATUS_SUCCESS.
+  QuicMessageId message_id;
+};
+
+QUIC_EXPORT_PRIVATE std::string MessageResultToString(
+    MessageResult message_result);
+
+enum WriteStreamDataResult {
+  WRITE_SUCCESS,
+  STREAM_MISSING,  // Trying to write data of a nonexistent stream (e.g.
+                   // closed).
+  WRITE_FAILED,    // Trying to write nonexistent data of a stream
+};
+
+enum StreamType : uint8_t {
+  // Bidirectional streams allow for data to be sent in both directions.
+  BIDIRECTIONAL,
+
+  // Unidirectional streams carry data in one direction only.
+  WRITE_UNIDIRECTIONAL,
+  READ_UNIDIRECTIONAL,
+  // Not actually a stream type. Used only by QuicCryptoStream when it uses
+  // CRYPTO frames and isn't actually a QuicStream.
+  CRYPTO,
+};
+
+// A packet number space is the context in which a packet can be processed and
+// acknowledged.
+enum PacketNumberSpace : uint8_t {
+  INITIAL_DATA = 0,  // Only used in IETF QUIC.
+  HANDSHAKE_DATA = 1,
+  APPLICATION_DATA = 2,
+
+  NUM_PACKET_NUMBER_SPACES,
+};
+
+QUIC_EXPORT_PRIVATE std::string PacketNumberSpaceToString(
+    PacketNumberSpace packet_number_space);
+
+// Used to return the result of processing a received ACK frame.
+enum AckResult {
+  PACKETS_NEWLY_ACKED,
+  NO_PACKETS_NEWLY_ACKED,
+  UNSENT_PACKETS_ACKED,     // Peer acks unsent packets.
+  UNACKABLE_PACKETS_ACKED,  // Peer acks packets that are not expected to be
+                            // acked. For example, encryption is reestablished,
+                            // and all sent encrypted packets cannot be
+                            // decrypted by the peer. Version gets negotiated,
+                            // and all sent packets in the different version
+                            // cannot be processed by the peer.
+  PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE,
+};
+
+// Indicates the fate of a serialized packet in WritePacket().
+enum SerializedPacketFate : uint8_t {
+  DISCARD,                     // Discard the packet.
+  COALESCE,                    // Try to coalesce packet.
+  BUFFER,                      // Buffer packet in buffered_packets_.
+  SEND_TO_WRITER,              // Send packet to writer.
+  LEGACY_VERSION_ENCAPSULATE,  // Perform Legacy Version Encapsulation on this
+                               // packet.
+};
+
+QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString(
+    SerializedPacketFate fate);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const SerializedPacketFate fate);
+
+// There are three different forms of CONNECTION_CLOSE.
+enum QuicConnectionCloseType {
+  GOOGLE_QUIC_CONNECTION_CLOSE = 0,
+  IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1,
+  IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicConnectionCloseType type);
+
+QUIC_EXPORT_PRIVATE std::string QuicConnectionCloseTypeString(
+    QuicConnectionCloseType type);
+
+// Indicate handshake state of a connection.
+enum HandshakeState {
+  // Initial state.
+  HANDSHAKE_START,
+  // Only used in IETF QUIC with TLS handshake. State proceeds to
+  // HANDSHAKE_PROCESSED after a packet of HANDSHAKE packet number space
+  // gets successfully processed, and the initial key can be dropped.
+  HANDSHAKE_PROCESSED,
+  // In QUIC crypto, state proceeds to HANDSHAKE_COMPLETE if client receives
+  // SHLO or server successfully processes an ENCRYPTION_FORWARD_SECURE
+  // packet, such that the handshake packets can be neutered. In IETF QUIC
+  // with TLS handshake, state proceeds to HANDSHAKE_COMPLETE once the client
+  // has both 1-RTT send and receive keys.
+  HANDSHAKE_COMPLETE,
+  // Only used in IETF QUIC with TLS handshake. State proceeds to
+  // HANDSHAKE_CONFIRMED if 1) a client receives HANDSHAKE_DONE frame or
+  // acknowledgment for 1-RTT packet or 2) server has
+  // 1-RTT send and receive keys.
+  HANDSHAKE_CONFIRMED,
+};
+
+struct QUIC_NO_EXPORT NextReleaseTimeResult {
+  // The ideal release time of the packet being sent.
+  QuicTime release_time;
+  // Whether it is allowed to send the packet before release_time.
+  bool allow_burst;
+};
+
+// QuicPacketBuffer bundles a buffer and a function that releases it. Note
+// it does not assume ownership of buffer, i.e. it doesn't release the buffer on
+// destruction.
+struct QUIC_NO_EXPORT QuicPacketBuffer {
+  QuicPacketBuffer() = default;
+
+  QuicPacketBuffer(char* buffer,
+                   std::function<void(const char*)> release_buffer)
+      : buffer(buffer), release_buffer(std::move(release_buffer)) {}
+
+  char* buffer = nullptr;
+  std::function<void(const char*)> release_buffer;
+};
+
+// QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership.
+struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer {
+  QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete;
+  QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete;
+
+  QuicOwnedPacketBuffer(char* buffer,
+                        std::function<void(const char*)> release_buffer)
+      : QuicPacketBuffer(buffer, std::move(release_buffer)) {}
+
+  QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer)
+      : QuicPacketBuffer(std::move(owned_buffer)) {
+    // |owned_buffer| does not own a buffer any more.
+    owned_buffer.buffer = nullptr;
+  }
+
+  explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer)
+      : QuicPacketBuffer(std::move(packet_buffer)) {}
+
+  ~QuicOwnedPacketBuffer() {
+    if (release_buffer != nullptr && buffer != nullptr) {
+      release_buffer(buffer);
+    }
+  }
+};
+
+// These values must remain stable as they are uploaded to UMA histograms.
+enum class KeyUpdateReason {
+  kInvalid = 0,
+  kRemote = 1,
+  kLocalForTests = 2,
+  kLocalForInteropRunner = 3,
+  kLocalAeadConfidentialityLimit = 4,
+  kLocalKeyUpdateLimitOverride = 5,
+  kMaxValue = kLocalKeyUpdateLimitOverride,
+};
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const KeyUpdateReason reason);
+
+QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason);
+
+// QuicSSLConfig contains configurations to be applied on a SSL object, which
+// overrides the configurations in SSL_CTX.
+struct QUIC_NO_EXPORT QuicSSLConfig {
+  // Whether TLS early data should be enabled. If not set, default to enabled.
+  absl::optional<bool> early_data_enabled;
+  // Whether TLS session tickets are supported. If not set, default to
+  // supported.
+  absl::optional<bool> disable_ticket_support;
+  // If set, used to configure the SSL object with
+  // SSL_set_signing_algorithm_prefs.
+  absl::optional<absl::InlinedVector<uint16_t, 8>> signing_algorithm_prefs;
+  // Client certificate mode for mTLS support. Only used at server side.
+  ClientCertMode client_cert_mode = ClientCertMode::kNone;
+};
+
+// QuicDelayedSSLConfig contains a subset of SSL config that can be applied
+// after BoringSSL's early select certificate callback. This overwrites all SSL
+// configs applied before cert selection.
+struct QUIC_NO_EXPORT QuicDelayedSSLConfig {
+  // Client certificate mode for mTLS support. Only used at server side.
+  // absl::nullopt means do not change client certificate mode.
+  absl::optional<ClientCertMode> client_cert_mode;
+};
+
+// ParsedClientHello contains client hello information extracted from a fully
+// received client hello.
+struct QUIC_NO_EXPORT ParsedClientHello {
+  std::string sni;                 // QUIC crypto and TLS.
+  std::string uaid;                // QUIC crypto only.
+  std::vector<std::string> alpns;  // QUIC crypto and TLS.
+  std::string legacy_version_encapsulation_inner_packet;  // QUIC crypto only.
+  // The unvalidated retry token from the last received packet of a potentially
+  // multi-packet client hello. TLS only.
+  std::string retry_token;
+  bool resumption_attempted = false;  // TLS only.
+  bool early_data_attempted = false;  // TLS only.
+};
+
+QUIC_EXPORT_PRIVATE bool operator==(const ParsedClientHello& a,
+                                    const ParsedClientHello& b);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ParsedClientHello& parsed_chlo);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TYPES_H_
diff --git a/quiche/quic/core/quic_udp_socket.h b/quiche/quic/core/quic_udp_socket.h
new file mode 100644
index 0000000..fcfdcac
--- /dev/null
+++ b/quiche/quic/core/quic_udp_socket.h
@@ -0,0 +1,253 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
+#define QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include <type_traits>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+#if defined(_WIN32)
+using QuicUdpSocketFd = SOCKET;
+const QuicUdpSocketFd kQuicInvalidSocketFd = INVALID_SOCKET;
+#else
+using QuicUdpSocketFd = int;
+const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
+#endif
+
+const size_t kDefaultUdpPacketControlBufferSize = 512;
+
+enum class QuicUdpPacketInfoBit : uint8_t {
+  DROPPED_PACKETS = 0,   // Read
+  V4_SELF_IP,            // Read
+  V6_SELF_IP,            // Read
+  PEER_ADDRESS,          // Read & Write
+  RECV_TIMESTAMP,        // Read
+  TTL,                   // Read & Write
+  GOOGLE_PACKET_HEADER,  // Read
+  NUM_BITS,
+};
+static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
+                  BitMask64::NumBits(),
+              "BitMask64 not wide enough to hold all bits.");
+
+// BufferSpan points to an unowned buffer, copying this structure only copies
+// the pointer and length, not the buffer itself.
+struct QUIC_EXPORT_PRIVATE BufferSpan {
+  BufferSpan(char* buffer, size_t buffer_len)
+      : buffer(buffer), buffer_len(buffer_len) {}
+
+  BufferSpan() = default;
+  BufferSpan(const BufferSpan& other) = default;
+  BufferSpan& operator=(const BufferSpan& other) = default;
+
+  char* buffer = nullptr;
+  size_t buffer_len = 0;
+};
+
+// QuicUdpPacketInfo contains per-packet information used for sending and
+// receiving.
+class QUIC_EXPORT_PRIVATE QuicUdpPacketInfo {
+ public:
+  BitMask64 bitmask() const { return bitmask_; }
+
+  void Reset() { bitmask_.ClearAll(); }
+
+  bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
+
+  QuicPacketCount dropped_packets() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
+    return dropped_packets_;
+  }
+
+  void SetDroppedPackets(QuicPacketCount dropped_packets) {
+    dropped_packets_ = dropped_packets;
+    bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
+  }
+
+  const QuicIpAddress& self_v4_ip() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
+    return self_v4_ip_;
+  }
+
+  void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
+    self_v4_ip_ = self_v4_ip;
+    bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
+  }
+
+  const QuicIpAddress& self_v6_ip() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
+    return self_v6_ip_;
+  }
+
+  void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
+    self_v6_ip_ = self_v6_ip;
+    bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
+  }
+
+  void SetSelfIp(QuicIpAddress self_ip) {
+    if (self_ip.IsIPv4()) {
+      SetSelfV4Ip(self_ip);
+    } else {
+      SetSelfV6Ip(self_ip);
+    }
+  }
+
+  const QuicSocketAddress& peer_address() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
+    return peer_address_;
+  }
+
+  void SetPeerAddress(QuicSocketAddress peer_address) {
+    peer_address_ = peer_address;
+    bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
+  }
+
+  QuicWallTime receive_timestamp() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
+    return receive_timestamp_;
+  }
+
+  void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
+    receive_timestamp_ = receive_timestamp;
+    bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
+  }
+
+  int ttl() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
+    return ttl_;
+  }
+
+  void SetTtl(int ttl) {
+    ttl_ = ttl;
+    bitmask_.Set(QuicUdpPacketInfoBit::TTL);
+  }
+
+  BufferSpan google_packet_headers() const {
+    QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER));
+    return google_packet_headers_;
+  }
+
+  void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
+    google_packet_headers_ = google_packet_headers;
+    bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
+  }
+
+ private:
+  BitMask64 bitmask_;
+  QuicPacketCount dropped_packets_;
+  QuicIpAddress self_v4_ip_;
+  QuicIpAddress self_v6_ip_;
+  QuicSocketAddress peer_address_;
+  QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
+  int ttl_;
+  BufferSpan google_packet_headers_;
+};
+
+// QuicUdpSocketApi provides a minimal set of apis for sending and receiving
+// udp packets. The low level udp socket apis differ between kernels and kernel
+// versions, the goal of QuicUdpSocketApi is to hide such differences.
+// We use non-static functions because it is easier to be mocked in tests when
+// needed.
+class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
+ public:
+  // Creates a non-blocking udp socket, sets the receive/send buffer and enable
+  // receiving of self ip addresses on read.
+  // If address_family == AF_INET6 and ipv6_only is true, receiving of IPv4 self
+  // addresses is disabled. This is only necessary for IPv6 sockets on iOS - all
+  // other platforms can ignore this parameter. Return kQuicInvalidSocketFd if
+  // failed.
+  QuicUdpSocketFd Create(int address_family,
+                         int receive_buffer_size,
+                         int send_buffer_size,
+                         bool ipv6_only = false);
+
+  // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
+  void Destroy(QuicUdpSocketFd fd);
+
+  // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
+  // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
+  // to get the bound random port.
+  bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
+
+  // Enable receiving of various per-packet information. Return true if the
+  // corresponding information can be received on read.
+  bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
+  bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
+  bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
+  bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
+
+  // Wait for |fd| to become readable, up to |timeout|.
+  // Return true if |fd| is readable upon return.
+  bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
+
+  struct QUIC_EXPORT_PRIVATE ReadPacketResult {
+    bool ok = false;
+    QuicUdpPacketInfo packet_info;
+    BufferSpan packet_buffer;
+    BufferSpan control_buffer;
+
+    void Reset(size_t packet_buffer_length) {
+      ok = false;
+      packet_info.Reset();
+      packet_buffer.buffer_len = packet_buffer_length;
+    }
+  };
+  // Read a packet from |fd|:
+  // packet_info_interested: Bitmask indicating what information caller wants to
+  //                         receive into |result->packet_info|.
+  // result->packet_info:    Received per packet information.
+  // result->packet_buffer:  The packet buffer, to be filled with packet data.
+  //                         |result->packet_buffer.buffer_len| is set to the
+  //                         packet length on a successful return.
+  // result->control_buffer: The control buffer, used by ReadPacket internally.
+  //                         It is recommended to be
+  //                         |kDefaultUdpPacketControlBufferSize| bytes.
+  // result->ok:             True iff a packet is successfully received.
+  //
+  // If |*result| is reused for subsequent ReadPacket() calls, caller needs to
+  // call result->Reset() before each ReadPacket().
+  void ReadPacket(QuicUdpSocketFd fd,
+                  BitMask64 packet_info_interested,
+                  ReadPacketResult* result);
+
+  using ReadPacketResults = std::vector<ReadPacketResult>;
+  // Read up to |results->size()| packets from |fd|. The meaning of each element
+  // in |*results| has been documented on top of |ReadPacket|.
+  // Return the number of elements populated into |*results|, note it is
+  // possible for some of the populated elements to have ok=false.
+  size_t ReadMultiplePackets(QuicUdpSocketFd fd,
+                             BitMask64 packet_info_interested,
+                             ReadPacketResults* results);
+
+  // Write a packet to |fd|.
+  // packet_buffer, packet_buffer_len:  The packet buffer to write.
+  // packet_info:                       The per packet information to set.
+  WriteResult WritePacket(QuicUdpSocketFd fd,
+                          const char* packet_buffer,
+                          size_t packet_buffer_len,
+                          const QuicUdpPacketInfo& packet_info);
+
+ protected:
+  bool SetupSocket(QuicUdpSocketFd fd,
+                   int address_family,
+                   int receive_buffer_size,
+                   int send_buffer_size,
+                   bool ipv6_only);
+  bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
+  bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
diff --git a/quiche/quic/core/quic_udp_socket_posix.cc b/quiche/quic/core/quic_udp_socket_posix.cc
new file mode 100644
index 0000000..5851bea
--- /dev/null
+++ b/quiche/quic/core/quic_udp_socket_posix.cc
@@ -0,0 +1,639 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_udp_socket_platform_api.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#if defined(__APPLE__) && !defined(__APPLE_USE_RFC_3542)
+#error "__APPLE_USE_RFC_3542 needs to be defined."
+#endif
+
+#if defined(__linux__)
+#include <alloca.h>
+// For SO_TIMESTAMPING.
+#include <linux/net_tstamp.h>
+#endif
+
+#if defined(__linux__) && !defined(__ANDROID__)
+#define QUIC_UDP_SOCKET_SUPPORT_TTL 1
+#endif
+
+namespace quic {
+namespace {
+
+#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
+#define QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING 1
+// This is the structure that SO_TIMESTAMPING fills into the cmsg header.
+// It is well-defined, but does not have a definition in a public header.
+// See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
+// for more information.
+struct LinuxSoTimestamping {
+  // The converted system time of the timestamp.
+  struct timespec systime;
+  // Deprecated; serves only as padding.
+  struct timespec hwtimetrans;
+  // The raw hardware timestamp.
+  struct timespec hwtimeraw;
+};
+const size_t kCmsgSpaceForRecvTimestamp =
+    CMSG_SPACE(sizeof(LinuxSoTimestamping));
+#else
+const size_t kCmsgSpaceForRecvTimestamp = 0;
+#endif
+
+const size_t kMinCmsgSpaceForRead =
+    CMSG_SPACE(sizeof(uint32_t))       // Dropped packet count
+    + CMSG_SPACE(sizeof(in_pktinfo))   // V4 Self IP
+    + CMSG_SPACE(sizeof(in6_pktinfo))  // V6 Self IP
+    + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int))  // TTL
+    + kCmsgSpaceForGooglePacketHeader;
+
+QuicUdpSocketFd CreateNonblockingSocket(int address_family) {
+#if defined(__linux__) && defined(SOCK_NONBLOCK)
+
+  // Create a nonblocking socket directly.
+  int fd = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
+  if (fd < 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "socket() failed with address_family=" << address_family << ": "
+        << strerror(errno);
+    return kQuicInvalidSocketFd;
+  }
+#else
+  // Create a socket and use fcntl to set it to nonblocking.
+  // This implementation is used when building for iOS, OSX and old versions of
+  // Linux (< 2.6.27) and old versions of Android (< API 21).
+  int fd = socket(address_family, SOCK_DGRAM, IPPROTO_UDP);
+  if (fd < 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "socket() failed with address_family=" << address_family << ": "
+        << strerror(errno);
+    return kQuicInvalidSocketFd;
+  }
+  int current_flags = fcntl(fd, F_GETFL, 0);
+  if (current_flags == -1) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "failed to get current socket flags: " << strerror(errno);
+    close(fd);
+    return kQuicInvalidSocketFd;
+  }
+
+  int rc = fcntl(fd, F_SETFL, current_flags | O_NONBLOCK);
+  if (rc == -1) {
+    QUIC_LOG_FIRST_N(ERROR, 100)
+        << "failed to set socket to non-blocking: " << strerror(errno);
+    close(fd);
+    return kQuicInvalidSocketFd;
+  }
+#endif
+
+  SetGoogleSocketOptions(fd);
+  return fd;
+}  // End CreateNonblockingSocket
+
+void SetV4SelfIpInControlMessage(const QuicIpAddress& self_address,
+                                 cmsghdr* cmsg) {
+  QUICHE_DCHECK(self_address.IsIPv4());
+  in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+  memset(pktinfo, 0, sizeof(in_pktinfo));
+  pktinfo->ipi_ifindex = 0;
+  std::string address_string = self_address.ToPackedString();
+  memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
+         address_string.length());
+}
+
+void SetV6SelfIpInControlMessage(const QuicIpAddress& self_address,
+                                 cmsghdr* cmsg) {
+  QUICHE_DCHECK(self_address.IsIPv6());
+  in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+  memset(pktinfo, 0, sizeof(in6_pktinfo));
+  std::string address_string = self_address.ToPackedString();
+  memcpy(&pktinfo->ipi6_addr, address_string.c_str(), address_string.length());
+}
+
+void PopulatePacketInfoFromControlMessage(struct cmsghdr* cmsg,
+                                          QuicUdpPacketInfo* packet_info,
+                                          BitMask64 packet_info_interested) {
+#if defined(__linux__) && defined(SO_RXQ_OVFL)
+  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::DROPPED_PACKETS)) {
+      packet_info->SetDroppedPackets(
+          *(reinterpret_cast<uint32_t*> CMSG_DATA(cmsg)));
+    }
+    return;
+  }
+#endif
+
+#if defined(QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING)
+  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP)) {
+      LinuxSoTimestamping* linux_ts =
+          reinterpret_cast<LinuxSoTimestamping*>(CMSG_DATA(cmsg));
+      timespec* ts = &linux_ts->systime;
+      int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
+                     (static_cast<int64_t>(ts->tv_nsec) / 1000);
+      packet_info->SetReceiveTimestamp(
+          QuicWallTime::FromUNIXMicroseconds(usec));
+    }
+    return;
+  }
+#endif
+
+  if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V6_SELF_IP)) {
+      const in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+      const char* addr_data = reinterpret_cast<const char*>(&info->ipi6_addr);
+      int addr_len = sizeof(in6_addr);
+      QuicIpAddress self_v6_ip;
+      if (self_v6_ip.FromPackedString(addr_data, addr_len)) {
+        packet_info->SetSelfV6Ip(self_v6_ip);
+      } else {
+        QUIC_BUG(quic_bug_10751_1) << "QuicIpAddress::FromPackedString failed";
+      }
+    }
+    return;
+  }
+
+  if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V4_SELF_IP)) {
+      const in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+      const char* addr_data = reinterpret_cast<const char*>(&info->ipi_addr);
+      int addr_len = sizeof(in_addr);
+      QuicIpAddress self_v4_ip;
+      if (self_v4_ip.FromPackedString(addr_data, addr_len)) {
+        packet_info->SetSelfV4Ip(self_v4_ip);
+      } else {
+        QUIC_BUG(quic_bug_10751_2) << "QuicIpAddress::FromPackedString failed";
+      }
+    }
+    return;
+  }
+
+  if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
+      (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT)) {
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::TTL)) {
+      packet_info->SetTtl(*(reinterpret_cast<int*>(CMSG_DATA(cmsg))));
+    }
+    return;
+  }
+
+  if (packet_info_interested.IsSet(
+          QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
+    BufferSpan google_packet_headers;
+    if (GetGooglePacketHeadersFromControlMessage(
+            cmsg, &google_packet_headers.buffer,
+            &google_packet_headers.buffer_len)) {
+      packet_info->SetGooglePacketHeaders(google_packet_headers);
+    }
+  }
+}
+
+bool NextCmsg(msghdr* hdr,
+              char* control_buffer,
+              size_t control_buffer_len,
+              int cmsg_level,
+              int cmsg_type,
+              size_t data_size,
+              cmsghdr** cmsg /*in, out*/) {
+  // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+  // return nullptr.
+  hdr->msg_controllen += CMSG_SPACE(data_size);
+  if (hdr->msg_controllen > control_buffer_len) {
+    return false;
+  }
+
+  if ((*cmsg) == nullptr) {
+    QUICHE_DCHECK_EQ(nullptr, hdr->msg_control);
+    memset(control_buffer, 0, control_buffer_len);
+    hdr->msg_control = control_buffer;
+    (*cmsg) = CMSG_FIRSTHDR(hdr);
+  } else {
+    QUICHE_DCHECK_NE(nullptr, hdr->msg_control);
+    (*cmsg) = CMSG_NXTHDR(hdr, (*cmsg));
+  }
+
+  if (nullptr == (*cmsg)) {
+    return false;
+  }
+
+  (*cmsg)->cmsg_len = CMSG_LEN(data_size);
+  (*cmsg)->cmsg_level = cmsg_level;
+  (*cmsg)->cmsg_type = cmsg_type;
+
+  return true;
+}
+}  // namespace
+
+QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
+                                         int receive_buffer_size,
+                                         int send_buffer_size,
+                                         bool ipv6_only) {
+  // QUICHE_DCHECK here so the program exits early(before reading packets) in
+  // debug mode. This should have been a static_assert, however it can't be done
+  // on ios/osx because CMSG_SPACE isn't a constant expression there.
+  QUICHE_DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
+  QuicUdpSocketFd fd = CreateNonblockingSocket(address_family);
+
+  if (fd == kQuicInvalidSocketFd) {
+    return kQuicInvalidSocketFd;
+  }
+
+  if (!SetupSocket(fd, address_family, receive_buffer_size, send_buffer_size,
+                   ipv6_only)) {
+    Destroy(fd);
+    return kQuicInvalidSocketFd;
+  }
+
+  return fd;
+}
+
+bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd,
+                                   int address_family,
+                                   int receive_buffer_size,
+                                   int send_buffer_size,
+                                   bool ipv6_only) {
+  // Receive buffer size.
+  if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_buffer_size,
+                 sizeof(receive_buffer_size)) != 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket recv size";
+    return false;
+  }
+
+  // Send buffer size.
+  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_buffer_size,
+                 sizeof(send_buffer_size)) != 0) {
+    QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket send size";
+    return false;
+  }
+
+  if (!(address_family == AF_INET6 && ipv6_only)) {
+    if (!EnableReceiveSelfIpAddressForV4(fd)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Failed to enable receiving of self v4 ip";
+      return false;
+    }
+  }
+
+  if (address_family == AF_INET6) {
+    if (!EnableReceiveSelfIpAddressForV6(fd)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Failed to enable receiving of self v6 ip";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void QuicUdpSocketApi::Destroy(QuicUdpSocketFd fd) {
+  if (fd != kQuicInvalidSocketFd) {
+    close(fd);
+  }
+}
+
+bool QuicUdpSocketApi::Bind(QuicUdpSocketFd fd, QuicSocketAddress address) {
+  sockaddr_storage addr = address.generic_address();
+  int addr_len =
+      address.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
+  return 0 == bind(fd, reinterpret_cast<sockaddr*>(&addr), addr_len);
+}
+
+bool QuicUdpSocketApi::EnableDroppedPacketCount(QuicUdpSocketFd fd) {
+#if defined(__linux__) && defined(SO_RXQ_OVFL)
+  int get_overflow = 1;
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
+                         sizeof(get_overflow));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd) {
+  int get_self_ip = 1;
+  return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_self_ip,
+                         sizeof(get_self_ip));
+}
+
+bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd) {
+  int get_self_ip = 1;
+  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_self_ip,
+                         sizeof(get_self_ip));
+}
+
+bool QuicUdpSocketApi::EnableReceiveTimestamp(QuicUdpSocketFd fd) {
+#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
+  int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
+                         sizeof(timestamping));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::EnableReceiveTtlForV4(QuicUdpSocketFd fd) {
+#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
+  int get_ttl = 1;
+  return 0 == setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &get_ttl, sizeof(get_ttl));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::EnableReceiveTtlForV6(QuicUdpSocketFd fd) {
+#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
+  int get_ttl = 1;
+  return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &get_ttl,
+                         sizeof(get_ttl));
+#else
+  (void)fd;
+  return false;
+#endif
+}
+
+bool QuicUdpSocketApi::WaitUntilReadable(QuicUdpSocketFd fd,
+                                         QuicTime::Delta timeout) {
+  fd_set read_fds;
+  FD_ZERO(&read_fds);
+  FD_SET(fd, &read_fds);
+
+  timeval select_timeout;
+  select_timeout.tv_sec = timeout.ToSeconds();
+  select_timeout.tv_usec = timeout.ToMicroseconds() % 1000000;
+
+  return 1 == select(1 + fd, &read_fds, nullptr, nullptr, &select_timeout);
+}
+
+void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
+                                  BitMask64 packet_info_interested,
+                                  ReadPacketResult* result) {
+  result->ok = false;
+  BufferSpan& packet_buffer = result->packet_buffer;
+  BufferSpan& control_buffer = result->control_buffer;
+  QuicUdpPacketInfo* packet_info = &result->packet_info;
+
+  QUICHE_DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
+
+  struct iovec iov = {packet_buffer.buffer, packet_buffer.buffer_len};
+  struct sockaddr_storage raw_peer_address;
+
+  if (control_buffer.buffer_len > 0) {
+    reinterpret_cast<struct cmsghdr*>(control_buffer.buffer)->cmsg_len =
+        control_buffer.buffer_len;
+  }
+
+  msghdr hdr;
+  hdr.msg_name = &raw_peer_address;
+  hdr.msg_namelen = sizeof(raw_peer_address);
+  hdr.msg_iov = &iov;
+  hdr.msg_iovlen = 1;
+  hdr.msg_flags = 0;
+  hdr.msg_control = control_buffer.buffer;
+  hdr.msg_controllen = control_buffer.buffer_len;
+
+#if defined(__linux__)
+  // If MSG_TRUNC is set on Linux, recvmsg will return the real packet size even
+  // if |packet_buffer| is too small to receive it.
+  int flags = MSG_TRUNC;
+#else
+  int flags = 0;
+#endif
+
+  int bytes_read = recvmsg(fd, &hdr, flags);
+  if (bytes_read < 0) {
+    const int error_num = errno;
+    if (error_num != EAGAIN) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Error reading packet: " << strerror(error_num);
+    }
+    return;
+  }
+
+  if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
+    QUIC_BUG(quic_bug_10751_3)
+        << "Control buffer too small. size:" << control_buffer.buffer_len;
+    return;
+  }
+
+  if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC) ||
+      // Normally "bytes_read > packet_buffer.buffer_len" implies the MSG_TRUNC
+      // bit is set, but it is not the case if tested with config=android_arm64.
+      static_cast<size_t>(bytes_read) > packet_buffer.buffer_len) {
+    QUIC_LOG_FIRST_N(WARNING, 100)
+        << "Received truncated QUIC packet: buffer size:"
+        << packet_buffer.buffer_len << " packet size:" << bytes_read;
+    return;
+  }
+
+  packet_buffer.buffer_len = bytes_read;
+  if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+    packet_info->SetPeerAddress(QuicSocketAddress(raw_peer_address));
+  }
+
+  if (hdr.msg_controllen > 0) {
+    for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
+         cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
+      BitMask64 prior_bitmask = packet_info->bitmask();
+      PopulatePacketInfoFromControlMessage(cmsg, packet_info,
+                                           packet_info_interested);
+      if (packet_info->bitmask() == prior_bitmask) {
+        QUIC_DLOG(INFO) << "Ignored cmsg_level:" << cmsg->cmsg_level
+                        << ", cmsg_type:" << cmsg->cmsg_type;
+      }
+    }
+  }
+
+  result->ok = true;
+}
+
+size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
+                                             BitMask64 packet_info_interested,
+                                             ReadPacketResults* results) {
+#if defined(__linux__) && !defined(__ANDROID__)
+  // Use recvmmsg.
+  size_t hdrs_size = sizeof(mmsghdr) * results->size();
+  mmsghdr* hdrs = static_cast<mmsghdr*>(alloca(hdrs_size));
+  memset(hdrs, 0, hdrs_size);
+
+  struct TempPerPacketData {
+    iovec iov;
+    sockaddr_storage raw_peer_address;
+  };
+  TempPerPacketData* packet_data_array = static_cast<TempPerPacketData*>(
+      alloca(sizeof(TempPerPacketData) * results->size()));
+
+  for (size_t i = 0; i < results->size(); ++i) {
+    (*results)[i].ok = false;
+
+    msghdr* hdr = &hdrs[i].msg_hdr;
+    TempPerPacketData* packet_data = &packet_data_array[i];
+    packet_data->iov.iov_base = (*results)[i].packet_buffer.buffer;
+    packet_data->iov.iov_len = (*results)[i].packet_buffer.buffer_len;
+
+    hdr->msg_name = &packet_data->raw_peer_address;
+    hdr->msg_namelen = sizeof(sockaddr_storage);
+    hdr->msg_iov = &packet_data->iov;
+    hdr->msg_iovlen = 1;
+    hdr->msg_flags = 0;
+    hdr->msg_control = (*results)[i].control_buffer.buffer;
+    hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
+
+    QUICHE_DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
+  }
+  // If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
+  // |hdrs[i].msg_len| even if packet buffer is too small to receive it.
+  int packets_read = recvmmsg(fd, hdrs, results->size(), MSG_TRUNC, nullptr);
+  if (packets_read <= 0) {
+    const int error_num = errno;
+    if (error_num != EAGAIN) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Error reading packets: " << strerror(error_num);
+    }
+    return 0;
+  }
+
+  for (int i = 0; i < packets_read; ++i) {
+    if (hdrs[i].msg_len == 0) {
+      continue;
+    }
+
+    msghdr& hdr = hdrs[i].msg_hdr;
+    if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
+      QUIC_BUG(quic_bug_10751_4) << "Control buffer too small. size:"
+                                 << (*results)[i].control_buffer.buffer_len
+                                 << ", need:" << hdr.msg_controllen;
+      continue;
+    }
+
+    if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC)) {
+      QUIC_LOG_FIRST_N(WARNING, 100)
+          << "Received truncated QUIC packet: buffer size:"
+          << (*results)[i].packet_buffer.buffer_len
+          << " packet size:" << hdrs[i].msg_len;
+      continue;
+    }
+
+    (*results)[i].ok = true;
+    (*results)[i].packet_buffer.buffer_len = hdrs[i].msg_len;
+
+    QuicUdpPacketInfo* packet_info = &(*results)[i].packet_info;
+    if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+      packet_info->SetPeerAddress(
+          QuicSocketAddress(packet_data_array[i].raw_peer_address));
+    }
+
+    if (hdr.msg_controllen > 0) {
+      for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
+           cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
+        PopulatePacketInfoFromControlMessage(cmsg, packet_info,
+                                             packet_info_interested);
+      }
+    }
+  }
+  return packets_read;
+#else
+  size_t num_packets = 0;
+  for (ReadPacketResult& result : *results) {
+    result.ok = false;
+  }
+  for (ReadPacketResult& result : *results) {
+    errno = 0;
+    ReadPacket(fd, packet_info_interested, &result);
+    if (!result.ok && errno == EAGAIN) {
+      break;
+    }
+    ++num_packets;
+  }
+  return num_packets;
+#endif
+}
+
+WriteResult QuicUdpSocketApi::WritePacket(
+    QuicUdpSocketFd fd,
+    const char* packet_buffer,
+    size_t packet_buffer_len,
+    const QuicUdpPacketInfo& packet_info) {
+  if (!packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+    return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+  }
+
+  char control_buffer[512];
+  sockaddr_storage raw_peer_address =
+      packet_info.peer_address().generic_address();
+  iovec iov = {const_cast<char*>(packet_buffer), packet_buffer_len};
+
+  msghdr hdr;
+  hdr.msg_name = &raw_peer_address;
+  hdr.msg_namelen = packet_info.peer_address().host().IsIPv4()
+                        ? sizeof(sockaddr_in)
+                        : sizeof(sockaddr_in6);
+  hdr.msg_iov = &iov;
+  hdr.msg_iovlen = 1;
+  hdr.msg_flags = 0;
+  hdr.msg_control = nullptr;
+  hdr.msg_controllen = 0;
+
+  cmsghdr* cmsg = nullptr;
+
+  // Set self IP.
+  if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP) &&
+      packet_info.self_v4_ip().IsInitialized()) {
+    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IP,
+                  IP_PKTINFO, sizeof(in_pktinfo), &cmsg)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Not enough buffer to set self v4 ip address.";
+      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+    }
+    SetV4SelfIpInControlMessage(packet_info.self_v4_ip(), cmsg);
+  } else if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP) &&
+             packet_info.self_v6_ip().IsInitialized()) {
+    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IPV6,
+                  IPV6_PKTINFO, sizeof(in6_pktinfo), &cmsg)) {
+      QUIC_LOG_FIRST_N(ERROR, 100)
+          << "Not enough buffer to set self v6 ip address.";
+      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+    }
+    SetV6SelfIpInControlMessage(packet_info.self_v6_ip(), cmsg);
+  }
+
+#if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
+  // Set ttl.
+  if (packet_info.HasValue(QuicUdpPacketInfoBit::TTL)) {
+    int cmsg_level =
+        packet_info.peer_address().host().IsIPv4() ? IPPROTO_IP : IPPROTO_IPV6;
+    int cmsg_type =
+        packet_info.peer_address().host().IsIPv4() ? IP_TTL : IPV6_HOPLIMIT;
+    if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), cmsg_level,
+                  cmsg_type, sizeof(int), &cmsg)) {
+      QUIC_LOG_FIRST_N(ERROR, 100) << "Not enough buffer to set ttl.";
+      return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+    }
+    *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = packet_info.ttl();
+  }
+#endif
+
+  int rc;
+  do {
+    rc = sendmsg(fd, &hdr, 0);
+  } while (rc < 0 && errno == EINTR);
+  if (rc >= 0) {
+    return WriteResult(WRITE_STATUS_OK, rc);
+  }
+  return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+                         ? WRITE_STATUS_BLOCKED
+                         : WRITE_STATUS_ERROR,
+                     errno);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_unacked_packet_map.cc b/quiche/quic/core/quic_unacked_packet_map.cc
new file mode 100644
index 0000000..63c345e
--- /dev/null
+++ b/quiche/quic/core/quic_unacked_packet_map.cc
@@ -0,0 +1,658 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+
+#include <cstddef>
+#include <limits>
+#include <type_traits>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+
+namespace quic {
+
+namespace {
+bool WillStreamFrameLengthSumWrapAround(QuicPacketLength lhs,
+                                        QuicPacketLength rhs) {
+  static_assert(
+      std::is_unsigned<QuicPacketLength>::value,
+      "This function assumes QuicPacketLength is an unsigned integer type.");
+  return std::numeric_limits<QuicPacketLength>::max() - lhs < rhs;
+}
+
+enum QuicFrameTypeBitfield : uint32_t {
+  kInvalidFrameBitfield = 0,
+  kPaddingFrameBitfield = 1,
+  kRstStreamFrameBitfield = 1 << 1,
+  kConnectionCloseFrameBitfield = 1 << 2,
+  kGoawayFrameBitfield = 1 << 3,
+  kWindowUpdateFrameBitfield = 1 << 4,
+  kBlockedFrameBitfield = 1 << 5,
+  kStopWaitingFrameBitfield = 1 << 6,
+  kPingFrameBitfield = 1 << 7,
+  kCryptoFrameBitfield = 1 << 8,
+  kHandshakeDoneFrameBitfield = 1 << 9,
+  kStreamFrameBitfield = 1 << 10,
+  kAckFrameBitfield = 1 << 11,
+  kMtuDiscoveryFrameBitfield = 1 << 12,
+  kNewConnectionIdFrameBitfield = 1 << 13,
+  kMaxStreamsFrameBitfield = 1 << 14,
+  kStreamsBlockedFrameBitfield = 1 << 15,
+  kPathResponseFrameBitfield = 1 << 16,
+  kPathChallengeFrameBitfield = 1 << 17,
+  kStopSendingFrameBitfield = 1 << 18,
+  kMessageFrameBitfield = 1 << 19,
+  kNewTokenFrameBitfield = 1 << 20,
+  kRetireConnectionIdFrameBitfield = 1 << 21,
+  kAckFrequencyFrameBitfield = 1 << 22,
+};
+
+QuicFrameTypeBitfield GetFrameTypeBitfield(QuicFrameType type) {
+  switch (type) {
+    case PADDING_FRAME:
+      return kPaddingFrameBitfield;
+    case RST_STREAM_FRAME:
+      return kRstStreamFrameBitfield;
+    case CONNECTION_CLOSE_FRAME:
+      return kConnectionCloseFrameBitfield;
+    case GOAWAY_FRAME:
+      return kGoawayFrameBitfield;
+    case WINDOW_UPDATE_FRAME:
+      return kWindowUpdateFrameBitfield;
+    case BLOCKED_FRAME:
+      return kBlockedFrameBitfield;
+    case STOP_WAITING_FRAME:
+      return kStopWaitingFrameBitfield;
+    case PING_FRAME:
+      return kPingFrameBitfield;
+    case CRYPTO_FRAME:
+      return kCryptoFrameBitfield;
+    case HANDSHAKE_DONE_FRAME:
+      return kHandshakeDoneFrameBitfield;
+    case STREAM_FRAME:
+      return kStreamFrameBitfield;
+    case ACK_FRAME:
+      return kAckFrameBitfield;
+    case MTU_DISCOVERY_FRAME:
+      return kMtuDiscoveryFrameBitfield;
+    case NEW_CONNECTION_ID_FRAME:
+      return kNewConnectionIdFrameBitfield;
+    case MAX_STREAMS_FRAME:
+      return kMaxStreamsFrameBitfield;
+    case STREAMS_BLOCKED_FRAME:
+      return kStreamsBlockedFrameBitfield;
+    case PATH_RESPONSE_FRAME:
+      return kPathResponseFrameBitfield;
+    case PATH_CHALLENGE_FRAME:
+      return kPathChallengeFrameBitfield;
+    case STOP_SENDING_FRAME:
+      return kStopSendingFrameBitfield;
+    case MESSAGE_FRAME:
+      return kMessageFrameBitfield;
+    case NEW_TOKEN_FRAME:
+      return kNewTokenFrameBitfield;
+    case RETIRE_CONNECTION_ID_FRAME:
+      return kRetireConnectionIdFrameBitfield;
+    case ACK_FREQUENCY_FRAME:
+      return kAckFrequencyFrameBitfield;
+    case NUM_FRAME_TYPES:
+      QUIC_BUG(quic_bug_10518_1) << "Unexpected frame type";
+      return kInvalidFrameBitfield;
+  }
+  QUIC_BUG(quic_bug_10518_2) << "Unexpected frame type";
+  return kInvalidFrameBitfield;
+}
+
+}  // namespace
+
+QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective)
+    : perspective_(perspective),
+      least_unacked_(FirstSendingPacketNumber()),
+      bytes_in_flight_(0),
+      bytes_in_flight_per_packet_number_space_{0, 0, 0},
+      packets_in_flight_(0),
+      last_inflight_packet_sent_time_(QuicTime::Zero()),
+      last_inflight_packets_sent_time_{{QuicTime::Zero()},
+                                       {QuicTime::Zero()},
+                                       {QuicTime::Zero()}},
+      last_crypto_packet_sent_time_(QuicTime::Zero()),
+      session_notifier_(nullptr),
+      supports_multiple_packet_number_spaces_(false) {
+}
+
+QuicUnackedPacketMap::~QuicUnackedPacketMap() {
+  for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
+    DeleteFrames(&(transmission_info.retransmittable_frames));
+  }
+}
+
+void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet,
+                                         TransmissionType transmission_type,
+                                         QuicTime sent_time,
+                                         bool set_in_flight,
+                                         bool measure_rtt) {
+  const SerializedPacket& packet = *mutable_packet;
+  QuicPacketNumber packet_number = packet.packet_number;
+  QuicPacketLength bytes_sent = packet.encrypted_length;
+  QUIC_BUG_IF(quic_bug_12645_1, largest_sent_packet_.IsInitialized() &&
+                                    largest_sent_packet_ >= packet_number)
+      << "largest_sent_packet_: " << largest_sent_packet_
+      << ", packet_number: " << packet_number;
+  QUICHE_DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
+  while (least_unacked_ + unacked_packets_.size() < packet_number) {
+    unacked_packets_.push_back(QuicTransmissionInfo());
+    unacked_packets_.back().state = NEVER_SENT;
+  }
+
+  const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE;
+  QuicTransmissionInfo info(packet.encryption_level, transmission_type,
+                            sent_time, bytes_sent, has_crypto_handshake,
+                            packet.has_ack_frequency);
+  info.largest_acked = packet.largest_acked;
+  largest_sent_largest_acked_.UpdateMax(packet.largest_acked);
+
+  if (!measure_rtt) {
+    QUIC_BUG_IF(quic_bug_12645_2, set_in_flight)
+        << "Packet " << mutable_packet->packet_number << ", transmission type "
+        << TransmissionTypeToString(mutable_packet->transmission_type)
+        << ", retransmittable frames: "
+        << QuicFramesToString(mutable_packet->retransmittable_frames)
+        << ", nonretransmittable_frames: "
+        << QuicFramesToString(mutable_packet->nonretransmittable_frames);
+    info.state = NOT_CONTRIBUTING_RTT;
+  }
+
+  largest_sent_packet_ = packet_number;
+  if (set_in_flight) {
+    const PacketNumberSpace packet_number_space =
+        GetPacketNumberSpace(info.encryption_level);
+    bytes_in_flight_ += bytes_sent;
+    bytes_in_flight_per_packet_number_space_[packet_number_space] += bytes_sent;
+    ++packets_in_flight_;
+    info.in_flight = true;
+    largest_sent_retransmittable_packets_[packet_number_space] = packet_number;
+    last_inflight_packet_sent_time_ = sent_time;
+    last_inflight_packets_sent_time_[packet_number_space] = sent_time;
+  }
+  unacked_packets_.push_back(std::move(info));
+  // Swap the retransmittable frames to avoid allocations.
+  // TODO(ianswett): Could use emplace_back when Chromium can.
+  if (has_crypto_handshake) {
+    last_crypto_packet_sent_time_ = sent_time;
+  }
+
+  mutable_packet->retransmittable_frames.swap(
+      unacked_packets_.back().retransmittable_frames);
+}
+
+void QuicUnackedPacketMap::RemoveObsoletePackets() {
+  while (!unacked_packets_.empty()) {
+    if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) {
+      break;
+    }
+    DeleteFrames(&unacked_packets_.front().retransmittable_frames);
+    unacked_packets_.pop_front();
+    ++least_unacked_;
+  }
+}
+
+bool QuicUnackedPacketMap::HasRetransmittableFrames(
+    QuicPacketNumber packet_number) const {
+  QUICHE_DCHECK_GE(packet_number, least_unacked_);
+  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+  return HasRetransmittableFrames(
+      unacked_packets_[packet_number - least_unacked_]);
+}
+
+bool QuicUnackedPacketMap::HasRetransmittableFrames(
+    const QuicTransmissionInfo& info) const {
+  if (!QuicUtils::IsAckable(info.state)) {
+    return false;
+  }
+
+  for (const auto& frame : info.retransmittable_frames) {
+    if (session_notifier_->IsFrameOutstanding(frame)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicUnackedPacketMap::RemoveRetransmittability(
+    QuicTransmissionInfo* info) {
+  DeleteFrames(&info->retransmittable_frames);
+  info->first_sent_after_loss.Clear();
+}
+
+void QuicUnackedPacketMap::RemoveRetransmittability(
+    QuicPacketNumber packet_number) {
+  QUICHE_DCHECK_GE(packet_number, least_unacked_);
+  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+  QuicTransmissionInfo* info =
+      &unacked_packets_[packet_number - least_unacked_];
+  RemoveRetransmittability(info);
+}
+
+void QuicUnackedPacketMap::IncreaseLargestAcked(
+    QuicPacketNumber largest_acked) {
+  QUICHE_DCHECK(!largest_acked_.IsInitialized() ||
+                largest_acked_ <= largest_acked);
+  largest_acked_ = largest_acked;
+}
+
+void QuicUnackedPacketMap::MaybeUpdateLargestAckedOfPacketNumberSpace(
+    PacketNumberSpace packet_number_space,
+    QuicPacketNumber packet_number) {
+  largest_acked_packets_[packet_number_space].UpdateMax(packet_number);
+}
+
+bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
+    QuicPacketNumber packet_number,
+    const QuicTransmissionInfo& info) const {
+  // Packet can be used for RTT measurement if it may yet be acked as the
+  // largest observed packet by the receiver.
+  return QuicUtils::IsAckable(info.state) &&
+         (!largest_acked_.IsInitialized() || packet_number > largest_acked_) &&
+         info.state != NOT_CONTRIBUTING_RTT;
+}
+
+bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
+    const QuicTransmissionInfo& info) const {
+  // Packet contributes to congestion control if it is considered inflight.
+  return info.in_flight;
+}
+
+bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
+    const QuicTransmissionInfo& info) const {
+  // Wait for 1 RTT before giving up on the lost packet.
+  return info.first_sent_after_loss.IsInitialized() &&
+         (!largest_acked_.IsInitialized() ||
+          info.first_sent_after_loss > largest_acked_);
+}
+
+bool QuicUnackedPacketMap::IsPacketUseless(
+    QuicPacketNumber packet_number,
+    const QuicTransmissionInfo& info) const {
+  return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
+         !IsPacketUsefulForCongestionControl(info) &&
+         !IsPacketUsefulForRetransmittableData(info);
+}
+
+bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
+  if (packet_number < least_unacked_ ||
+      packet_number >= least_unacked_ + unacked_packets_.size()) {
+    return false;
+  }
+  return !IsPacketUseless(packet_number,
+                          unacked_packets_[packet_number - least_unacked_]);
+}
+
+void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
+  if (info->in_flight) {
+    QUIC_BUG_IF(quic_bug_12645_3, bytes_in_flight_ < info->bytes_sent);
+    QUIC_BUG_IF(quic_bug_12645_4, packets_in_flight_ == 0);
+    bytes_in_flight_ -= info->bytes_sent;
+    --packets_in_flight_;
+
+    const PacketNumberSpace packet_number_space =
+        GetPacketNumberSpace(info->encryption_level);
+    if (bytes_in_flight_per_packet_number_space_[packet_number_space] <
+        info->bytes_sent) {
+      QUIC_BUG(quic_bug_10518_3)
+          << "bytes_in_flight: "
+          << bytes_in_flight_per_packet_number_space_[packet_number_space]
+          << " is smaller than bytes_sent: " << info->bytes_sent
+          << " for packet number space: "
+          << PacketNumberSpaceToString(packet_number_space);
+      bytes_in_flight_per_packet_number_space_[packet_number_space] = 0;
+    } else {
+      bytes_in_flight_per_packet_number_space_[packet_number_space] -=
+          info->bytes_sent;
+    }
+    if (bytes_in_flight_per_packet_number_space_[packet_number_space] == 0) {
+      last_inflight_packets_sent_time_[packet_number_space] = QuicTime::Zero();
+    }
+
+    info->in_flight = false;
+  }
+}
+
+void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
+  QUICHE_DCHECK_GE(packet_number, least_unacked_);
+  QUICHE_DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
+  QuicTransmissionInfo* info =
+      &unacked_packets_[packet_number - least_unacked_];
+  RemoveFromInFlight(info);
+}
+
+absl::InlinedVector<QuicPacketNumber, 2>
+QuicUnackedPacketMap::NeuterUnencryptedPackets() {
+  absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
+  QuicPacketNumber packet_number = GetLeastUnacked();
+  for (QuicUnackedPacketMap::iterator it = begin(); it != end();
+       ++it, ++packet_number) {
+    if (!it->retransmittable_frames.empty() &&
+        it->encryption_level == ENCRYPTION_INITIAL) {
+      QUIC_DVLOG(2) << "Neutering unencrypted packet " << packet_number;
+      // Once the connection swithes to forward secure, no unencrypted packets
+      // will be sent. The data has been abandoned in the cryto stream. Remove
+      // it from in flight.
+      RemoveFromInFlight(packet_number);
+      it->state = NEUTERED;
+      neutered_packets.push_back(packet_number);
+      // Notify session that the data has been delivered (but do not notify
+      // send algorithm).
+      // TODO(b/148868195): use NotifyFramesNeutered.
+      NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
+      QUICHE_DCHECK(!HasRetransmittableFrames(*it));
+    }
+  }
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_ ||
+                last_inflight_packets_sent_time_[INITIAL_DATA] ==
+                    QuicTime::Zero());
+  return neutered_packets;
+}
+
+absl::InlinedVector<QuicPacketNumber, 2>
+QuicUnackedPacketMap::NeuterHandshakePackets() {
+  absl::InlinedVector<QuicPacketNumber, 2> neutered_packets;
+  QuicPacketNumber packet_number = GetLeastUnacked();
+  for (QuicUnackedPacketMap::iterator it = begin(); it != end();
+       ++it, ++packet_number) {
+    if (!it->retransmittable_frames.empty() &&
+        GetPacketNumberSpace(it->encryption_level) == HANDSHAKE_DATA) {
+      QUIC_DVLOG(2) << "Neutering handshake packet " << packet_number;
+      RemoveFromInFlight(packet_number);
+      // Notify session that the data has been delivered (but do not notify
+      // send algorithm).
+      it->state = NEUTERED;
+      neutered_packets.push_back(packet_number);
+      // TODO(b/148868195): use NotifyFramesNeutered.
+      NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
+    }
+  }
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces() ||
+                last_inflight_packets_sent_time_[HANDSHAKE_DATA] ==
+                    QuicTime::Zero());
+  return neutered_packets;
+}
+
+bool QuicUnackedPacketMap::HasInFlightPackets() const {
+  return bytes_in_flight_ > 0;
+}
+
+const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
+    QuicPacketNumber packet_number) const {
+  return unacked_packets_[packet_number - least_unacked_];
+}
+
+QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo(
+    QuicPacketNumber packet_number) {
+  return &unacked_packets_[packet_number - least_unacked_];
+}
+
+QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const {
+  return last_inflight_packet_sent_time_;
+}
+
+QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const {
+  return last_crypto_packet_sent_time_;
+}
+
+size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
+  size_t unacked_packet_count = 0;
+  QuicPacketNumber packet_number = least_unacked_;
+  for (auto it = begin(); it != end(); ++it, ++packet_number) {
+    if (!IsPacketUseless(packet_number, *it)) {
+      ++unacked_packet_count;
+    }
+  }
+  return unacked_packet_count;
+}
+
+bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
+  if (bytes_in_flight_ > kDefaultTCPMSS) {
+    return true;
+  }
+  size_t num_in_flight = 0;
+  for (auto it = rbegin(); it != rend(); ++it) {
+    if (it->in_flight) {
+      ++num_in_flight;
+    }
+    if (num_in_flight > 1) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
+  return session_notifier_->HasUnackedCryptoData();
+}
+
+bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
+  for (auto it = rbegin(); it != rend(); ++it) {
+    if (it->in_flight && HasRetransmittableFrames(*it)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
+  return least_unacked_;
+}
+
+void QuicUnackedPacketMap::SetSessionNotifier(
+    SessionNotifierInterface* session_notifier) {
+  session_notifier_ = session_notifier;
+}
+
+bool QuicUnackedPacketMap::NotifyFramesAcked(const QuicTransmissionInfo& info,
+                                             QuicTime::Delta ack_delay,
+                                             QuicTime receive_timestamp) {
+  if (session_notifier_ == nullptr) {
+    return false;
+  }
+  bool new_data_acked = false;
+  for (const QuicFrame& frame : info.retransmittable_frames) {
+    if (session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp)) {
+      new_data_acked = true;
+    }
+  }
+  return new_data_acked;
+}
+
+void QuicUnackedPacketMap::NotifyFramesLost(const QuicTransmissionInfo& info,
+                                            TransmissionType /*type*/) {
+  for (const QuicFrame& frame : info.retransmittable_frames) {
+    session_notifier_->OnFrameLost(frame);
+  }
+}
+
+bool QuicUnackedPacketMap::RetransmitFrames(const QuicFrames& frames,
+                                            TransmissionType type) {
+  return session_notifier_->RetransmitFrames(frames, type);
+}
+
+void QuicUnackedPacketMap::MaybeAggregateAckedStreamFrame(
+    const QuicTransmissionInfo& info,
+    QuicTime::Delta ack_delay,
+    QuicTime receive_timestamp) {
+  if (session_notifier_ == nullptr) {
+    return;
+  }
+  for (const auto& frame : info.retransmittable_frames) {
+    // Determine whether acked stream frame can be aggregated.
+    const bool can_aggregate =
+        frame.type == STREAM_FRAME &&
+        frame.stream_frame.stream_id == aggregated_stream_frame_.stream_id &&
+        frame.stream_frame.offset == aggregated_stream_frame_.offset +
+                                         aggregated_stream_frame_.data_length &&
+        // We would like to increment aggregated_stream_frame_.data_length by
+        // frame.stream_frame.data_length, so we need to make sure their sum is
+        // representable by QuicPacketLength, which is the type of the former.
+        !WillStreamFrameLengthSumWrapAround(
+            aggregated_stream_frame_.data_length,
+            frame.stream_frame.data_length);
+
+    if (can_aggregate) {
+      // Aggregate stream frame.
+      aggregated_stream_frame_.data_length += frame.stream_frame.data_length;
+      aggregated_stream_frame_.fin = frame.stream_frame.fin;
+      if (aggregated_stream_frame_.fin) {
+        // Notify session notifier aggregated stream frame gets acked if fin is
+        // acked.
+        NotifyAggregatedStreamFrameAcked(ack_delay);
+      }
+      continue;
+    }
+
+    NotifyAggregatedStreamFrameAcked(ack_delay);
+    if (frame.type != STREAM_FRAME || frame.stream_frame.fin) {
+      session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp);
+      continue;
+    }
+
+    // Delay notifying session notifier stream frame gets acked in case it can
+    // be aggregated with following acked ones.
+    aggregated_stream_frame_.stream_id = frame.stream_frame.stream_id;
+    aggregated_stream_frame_.offset = frame.stream_frame.offset;
+    aggregated_stream_frame_.data_length = frame.stream_frame.data_length;
+    aggregated_stream_frame_.fin = frame.stream_frame.fin;
+  }
+}
+
+void QuicUnackedPacketMap::NotifyAggregatedStreamFrameAcked(
+    QuicTime::Delta ack_delay) {
+  if (aggregated_stream_frame_.stream_id == static_cast<QuicStreamId>(-1) ||
+      session_notifier_ == nullptr) {
+    // Aggregated stream frame is empty.
+    return;
+  }
+  // Note: there is no receive_timestamp for an aggregated stream frame.  The
+  // frames that are aggregated may not have been received at the same time.
+  session_notifier_->OnFrameAcked(QuicFrame(aggregated_stream_frame_),
+                                  ack_delay,
+                                  /*receive_timestamp=*/QuicTime::Zero());
+  // Clear aggregated stream frame.
+  aggregated_stream_frame_.stream_id = -1;
+}
+
+PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
+    QuicPacketNumber packet_number) const {
+  return GetPacketNumberSpace(
+      GetTransmissionInfo(packet_number).encryption_level);
+}
+
+PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
+    EncryptionLevel encryption_level) const {
+  if (supports_multiple_packet_number_spaces_) {
+    return QuicUtils::GetPacketNumberSpace(encryption_level);
+  }
+  if (perspective_ == Perspective::IS_CLIENT) {
+    return encryption_level == ENCRYPTION_INITIAL ? HANDSHAKE_DATA
+                                                  : APPLICATION_DATA;
+  }
+  return encryption_level == ENCRYPTION_FORWARD_SECURE ? APPLICATION_DATA
+                                                       : HANDSHAKE_DATA;
+}
+
+QuicPacketNumber QuicUnackedPacketMap::GetLargestAckedOfPacketNumberSpace(
+    PacketNumberSpace packet_number_space) const {
+  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10518_4)
+        << "Invalid packet number space: " << packet_number_space;
+    return QuicPacketNumber();
+  }
+  return largest_acked_packets_[packet_number_space];
+}
+
+QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime(
+    PacketNumberSpace packet_number_space) const {
+  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10518_5)
+        << "Invalid packet number space: " << packet_number_space;
+    return QuicTime::Zero();
+  }
+  return last_inflight_packets_sent_time_[packet_number_space];
+}
+
+QuicPacketNumber
+QuicUnackedPacketMap::GetLargestSentRetransmittableOfPacketNumberSpace(
+    PacketNumberSpace packet_number_space) const {
+  if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
+    QUIC_BUG(quic_bug_10518_6)
+        << "Invalid packet number space: " << packet_number_space;
+    return QuicPacketNumber();
+  }
+  return largest_sent_retransmittable_packets_[packet_number_space];
+}
+
+const QuicTransmissionInfo*
+QuicUnackedPacketMap::GetFirstInFlightTransmissionInfo() const {
+  QUICHE_DCHECK(HasInFlightPackets());
+  for (auto it = begin(); it != end(); ++it) {
+    if (it->in_flight) {
+      return &(*it);
+    }
+  }
+  QUICHE_DCHECK(false);
+  return nullptr;
+}
+
+const QuicTransmissionInfo*
+QuicUnackedPacketMap::GetFirstInFlightTransmissionInfoOfSpace(
+    PacketNumberSpace packet_number_space) const {
+  // TODO(fayang): Optimize this part if arm 1st PTO with first in flight sent
+  // time works.
+  for (auto it = begin(); it != end(); ++it) {
+    if (it->in_flight &&
+        GetPacketNumberSpace(it->encryption_level) == packet_number_space) {
+      return &(*it);
+    }
+  }
+  return nullptr;
+}
+
+void QuicUnackedPacketMap::EnableMultiplePacketNumberSpacesSupport() {
+  if (supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10518_7)
+        << "Multiple packet number spaces has already been enabled";
+    return;
+  }
+  if (largest_sent_packet_.IsInitialized()) {
+    QUIC_BUG(quic_bug_10518_8)
+        << "Try to enable multiple packet number spaces support after any "
+           "packet has been sent.";
+    return;
+  }
+
+  supports_multiple_packet_number_spaces_ = true;
+}
+
+int32_t QuicUnackedPacketMap::GetLastPacketContent() const {
+  if (empty()) {
+    // Use -1 to distinguish with packets with no retransmittable frames nor
+    // acks.
+    return -1;
+  }
+  int32_t content = 0;
+  const QuicTransmissionInfo& last_packet = unacked_packets_.back();
+  for (const auto& frame : last_packet.retransmittable_frames) {
+    content |= GetFrameTypeBitfield(frame.type);
+  }
+  if (last_packet.largest_acked.IsInitialized()) {
+    content |= GetFrameTypeBitfield(ACK_FRAME);
+  }
+  return content;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_unacked_packet_map.h b/quiche/quic/core/quic_unacked_packet_map.h
new file mode 100644
index 0000000..ebbabe8
--- /dev/null
+++ b/quiche/quic/core/quic_unacked_packet_map.h
@@ -0,0 +1,339 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
+#define QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+
+namespace test {
+class QuicUnackedPacketMapPeer;
+}  // namespace test
+
+// Class which tracks unacked packets for three purposes:
+// 1) Track retransmittable data, including multiple transmissions of frames.
+// 2) Track packets and bytes in flight for congestion control.
+// 3) Track sent time of packets to provide RTT measurements from acks.
+class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
+ public:
+  QuicUnackedPacketMap(Perspective perspective);
+  QuicUnackedPacketMap(const QuicUnackedPacketMap&) = delete;
+  QuicUnackedPacketMap& operator=(const QuicUnackedPacketMap&) = delete;
+  ~QuicUnackedPacketMap();
+
+  // Adds |mutable_packet| to the map and marks it as sent at |sent_time|.
+  // Marks the packet as in flight if |set_in_flight| is true.
+  // Packets marked as in flight are expected to be marked as missing when they
+  // don't arrive, indicating the need for retransmission.
+  // Any retransmittible_frames in |mutable_packet| are swapped from
+  // |mutable_packet| into the QuicTransmissionInfo.
+  void AddSentPacket(SerializedPacket* mutable_packet,
+                     TransmissionType transmission_type,
+                     QuicTime sent_time,
+                     bool set_in_flight,
+                     bool measure_rtt);
+
+  // Returns true if the packet |packet_number| is unacked.
+  bool IsUnacked(QuicPacketNumber packet_number) const;
+
+  // Notifies session_notifier that frames have been acked. Returns true if any
+  // new data gets acked, returns false otherwise.
+  bool NotifyFramesAcked(const QuicTransmissionInfo& info,
+                         QuicTime::Delta ack_delay,
+                         QuicTime receive_timestamp);
+
+  // Notifies session_notifier that frames in |info| are considered as lost.
+  void NotifyFramesLost(const QuicTransmissionInfo& info,
+                        TransmissionType type);
+
+  // Notifies session_notifier to retransmit frames with |transmission_type|.
+  // Returns true if all data gets retransmitted.
+  bool RetransmitFrames(const QuicFrames& frames, TransmissionType type);
+
+  // Marks |info| as no longer in flight.
+  void RemoveFromInFlight(QuicTransmissionInfo* info);
+
+  // Marks |packet_number| as no longer in flight.
+  void RemoveFromInFlight(QuicPacketNumber packet_number);
+
+  // Called to neuter all unencrypted packets to ensure they do not get
+  // retransmitted. Returns a vector of neutered packet numbers.
+  absl::InlinedVector<QuicPacketNumber, 2> NeuterUnencryptedPackets();
+
+  // Called to neuter packets in handshake packet number space to ensure they do
+  // not get retransmitted. Returns a vector of neutered packet numbers.
+  // TODO(fayang): Consider to combine this with NeuterUnencryptedPackets.
+  absl::InlinedVector<QuicPacketNumber, 2> NeuterHandshakePackets();
+
+  // Returns true if |packet_number| has retransmittable frames. This will
+  // return false if all frames of this packet are either non-retransmittable or
+  // have been acked.
+  bool HasRetransmittableFrames(QuicPacketNumber packet_number) const;
+
+  // Returns true if |info| has retransmittable frames. This will return false
+  // if all frames of this packet are either non-retransmittable or have been
+  // acked.
+  bool HasRetransmittableFrames(const QuicTransmissionInfo& info) const;
+
+  // Returns true if there are any unacked packets which have retransmittable
+  // frames.
+  bool HasUnackedRetransmittableFrames() const;
+
+  // Returns true if there are no packets present in the unacked packet map.
+  bool empty() const { return unacked_packets_.empty(); }
+
+  // Returns the largest packet number that has been sent.
+  QuicPacketNumber largest_sent_packet() const { return largest_sent_packet_; }
+
+  QuicPacketNumber largest_sent_largest_acked() const {
+    return largest_sent_largest_acked_;
+  }
+
+  // Returns the largest packet number that has been acked.
+  QuicPacketNumber largest_acked() const { return largest_acked_; }
+
+  // Returns the sum of bytes from all packets in flight.
+  QuicByteCount bytes_in_flight() const { return bytes_in_flight_; }
+  QuicPacketCount packets_in_flight() const { return packets_in_flight_; }
+
+  // Returns the smallest packet number of a serialized packet which has not
+  // been acked by the peer.  If there are no unacked packets, returns 0.
+  QuicPacketNumber GetLeastUnacked() const;
+
+  using const_iterator =
+      quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_iterator;
+  using const_reverse_iterator =
+      quiche::QuicheCircularDeque<QuicTransmissionInfo>::const_reverse_iterator;
+  using iterator = quiche::QuicheCircularDeque<QuicTransmissionInfo>::iterator;
+
+  const_iterator begin() const { return unacked_packets_.begin(); }
+  const_iterator end() const { return unacked_packets_.end(); }
+  const_reverse_iterator rbegin() const { return unacked_packets_.rbegin(); }
+  const_reverse_iterator rend() const { return unacked_packets_.rend(); }
+  iterator begin() { return unacked_packets_.begin(); }
+  iterator end() { return unacked_packets_.end(); }
+
+  // Returns true if there are unacked packets that are in flight.
+  bool HasInFlightPackets() const;
+
+  // Returns the QuicTransmissionInfo associated with |packet_number|, which
+  // must be unacked.
+  const QuicTransmissionInfo& GetTransmissionInfo(
+      QuicPacketNumber packet_number) const;
+
+  // Returns mutable QuicTransmissionInfo associated with |packet_number|, which
+  // must be unacked.
+  QuicTransmissionInfo* GetMutableTransmissionInfo(
+      QuicPacketNumber packet_number);
+
+  // Returns the time that the last unacked packet was sent.
+  QuicTime GetLastInFlightPacketSentTime() const;
+
+  // Returns the time that the last unacked crypto packet was sent.
+  QuicTime GetLastCryptoPacketSentTime() const;
+
+  // Returns the number of unacked packets.
+  size_t GetNumUnackedPacketsDebugOnly() const;
+
+  // Returns true if there are multiple packets in flight.
+  // TODO(fayang): Remove this method and use packets_in_flight_ instead.
+  bool HasMultipleInFlightPackets() const;
+
+  // Returns true if there are any pending crypto packets.
+  bool HasPendingCryptoPackets() const;
+
+  // Returns true if there is any unacked non-crypto stream data.
+  bool HasUnackedStreamData() const {
+    return session_notifier_->HasUnackedStreamData();
+  }
+
+  // Removes any retransmittable frames from this transmission or an associated
+  // transmission.  It removes now useless transmissions, and disconnects any
+  // other packets from other transmissions.
+  void RemoveRetransmittability(QuicTransmissionInfo* info);
+
+  // Looks up the QuicTransmissionInfo by |packet_number| and calls
+  // RemoveRetransmittability.
+  void RemoveRetransmittability(QuicPacketNumber packet_number);
+
+  // Increases the largest acked.  Any packets less or equal to
+  // |largest_acked| are discarded if they are only for the RTT purposes.
+  void IncreaseLargestAcked(QuicPacketNumber largest_acked);
+
+  // Called when |packet_number| gets acked. Maybe increase the largest acked of
+  // |packet_number_space|.
+  void MaybeUpdateLargestAckedOfPacketNumberSpace(
+      PacketNumberSpace packet_number_space,
+      QuicPacketNumber packet_number);
+
+  // Remove any packets no longer needed for retransmission, congestion, or
+  // RTT measurement purposes.
+  void RemoveObsoletePackets();
+
+  // Try to aggregate acked contiguous stream frames. For noncontiguous stream
+  // frames or control frames, notify the session notifier they get acked
+  // immediately.
+  void MaybeAggregateAckedStreamFrame(const QuicTransmissionInfo& info,
+                                      QuicTime::Delta ack_delay,
+                                      QuicTime receive_timestamp);
+
+  // Notify the session notifier of any stream data aggregated in
+  // aggregated_stream_frame_.  No effect if the stream frame has an invalid
+  // stream id.
+  void NotifyAggregatedStreamFrameAcked(QuicTime::Delta ack_delay);
+
+  // Returns packet number space that |packet_number| belongs to. Please use
+  // GetPacketNumberSpace(EncryptionLevel) whenever encryption level is
+  // available.
+  PacketNumberSpace GetPacketNumberSpace(QuicPacketNumber packet_number) const;
+
+  // Returns packet number space of |encryption_level|.
+  PacketNumberSpace GetPacketNumberSpace(
+      EncryptionLevel encryption_level) const;
+
+  // Returns largest acked packet number of |packet_number_space|.
+  QuicPacketNumber GetLargestAckedOfPacketNumberSpace(
+      PacketNumberSpace packet_number_space) const;
+
+  // Returns largest sent retransmittable packet number of
+  // |packet_number_space|.
+  QuicPacketNumber GetLargestSentRetransmittableOfPacketNumberSpace(
+      PacketNumberSpace packet_number_space) const;
+
+  // Returns largest sent packet number of |encryption_level|.
+  QuicPacketNumber GetLargestSentPacketOfPacketNumberSpace(
+      EncryptionLevel encryption_level) const;
+
+  // Returns last in flight packet sent time of |packet_number_space|.
+  QuicTime GetLastInFlightPacketSentTime(
+      PacketNumberSpace packet_number_space) const;
+
+  // Returns TransmissionInfo of the first in flight packet.
+  const QuicTransmissionInfo* GetFirstInFlightTransmissionInfo() const;
+
+  // Returns TransmissionInfo of first in flight packet in
+  // |packet_number_space|.
+  const QuicTransmissionInfo* GetFirstInFlightTransmissionInfoOfSpace(
+      PacketNumberSpace packet_number_space) const;
+
+  void SetSessionNotifier(SessionNotifierInterface* session_notifier);
+
+  void EnableMultiplePacketNumberSpacesSupport();
+
+  // Returns a bitfield of retransmittable frames of last packet in
+  // unacked_packets_. For example, if the packet contains STREAM_FRAME, content
+  // & (1 << STREAM_FRAME) would be set. Returns max uint32_t if
+  // unacked_packets_ is empty.
+  int32_t GetLastPacketContent() const;
+
+  Perspective perspective() const { return perspective_; }
+
+  bool supports_multiple_packet_number_spaces() const {
+    return supports_multiple_packet_number_spaces_;
+  }
+
+  void ReserveInitialCapacity(size_t initial_capacity) {
+    unacked_packets_.reserve(initial_capacity);
+  }
+
+  std::string DebugString() const {
+    return absl::StrCat(
+        "{size: ", unacked_packets_.size(),
+        ", least_unacked: ", least_unacked_.ToString(),
+        ", largest_sent_packet: ", largest_sent_packet_.ToString(),
+        ", largest_acked: ", largest_acked_.ToString(),
+        ", bytes_in_flight: ", bytes_in_flight_,
+        ", packets_in_flight: ", packets_in_flight_, "}");
+  }
+
+ private:
+  friend class test::QuicUnackedPacketMapPeer;
+
+  // Returns true if packet may be useful for an RTT measurement.
+  bool IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number,
+                                     const QuicTransmissionInfo& info) const;
+
+  // Returns true if packet may be useful for congestion control purposes.
+  bool IsPacketUsefulForCongestionControl(
+      const QuicTransmissionInfo& info) const;
+
+  // Returns true if packet may be associated with retransmittable data
+  // directly or through retransmissions.
+  bool IsPacketUsefulForRetransmittableData(
+      const QuicTransmissionInfo& info) const;
+
+  // Returns true if the packet no longer has a purpose in the map.
+  bool IsPacketUseless(QuicPacketNumber packet_number,
+                       const QuicTransmissionInfo& info) const;
+
+  const Perspective perspective_;
+
+  QuicPacketNumber largest_sent_packet_;
+  // The largest sent packet we expect to receive an ack for per packet number
+  // space.
+  QuicPacketNumber
+      largest_sent_retransmittable_packets_[NUM_PACKET_NUMBER_SPACES];
+  // The largest sent largest_acked in an ACK frame.
+  QuicPacketNumber largest_sent_largest_acked_;
+  // The largest received largest_acked from an ACK frame.
+  QuicPacketNumber largest_acked_;
+  // The largest received largest_acked from ACK frame per packet number space.
+  QuicPacketNumber largest_acked_packets_[NUM_PACKET_NUMBER_SPACES];
+
+  // Newly serialized retransmittable packets are added to this map, which
+  // contains owning pointers to any contained frames.  If a packet is
+  // retransmitted, this map will contain entries for both the old and the new
+  // packet. The old packet's retransmittable frames entry will be nullptr,
+  // while the new packet's entry will contain the frames to retransmit.
+  // If the old packet is acked before the new packet, then the old entry will
+  // be removed from the map and the new entry's retransmittable frames will be
+  // set to nullptr.
+  quiche::QuicheCircularDeque<QuicTransmissionInfo> unacked_packets_;
+
+  // The packet at the 0th index of unacked_packets_.
+  QuicPacketNumber least_unacked_;
+
+  QuicByteCount bytes_in_flight_;
+  // Bytes in flight per packet number space.
+  QuicByteCount
+      bytes_in_flight_per_packet_number_space_[NUM_PACKET_NUMBER_SPACES];
+  QuicPacketCount packets_in_flight_;
+
+  // Time that the last inflight packet was sent.
+  QuicTime last_inflight_packet_sent_time_;
+  // Time that the last in flight packet was sent per packet number space.
+  QuicTime last_inflight_packets_sent_time_[NUM_PACKET_NUMBER_SPACES];
+
+  // Time that the last unacked crypto packet was sent.
+  QuicTime last_crypto_packet_sent_time_;
+
+  // Aggregates acked stream data across multiple acked sent packets to save CPU
+  // by reducing the number of calls to the session notifier.
+  QuicStreamFrame aggregated_stream_frame_;
+
+  // Receives notifications of frames being retransmitted or acknowledged.
+  SessionNotifierInterface* session_notifier_;
+
+  // If true, supports multiple packet number spaces.
+  bool supports_multiple_packet_number_spaces_;
+
+  // Latched value of the quic_simple_inflight_time flag.
+  bool simple_inflight_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
diff --git a/quiche/quic/core/quic_unacked_packet_map_test.cc b/quiche/quic/core/quic_unacked_packet_map_test.cc
new file mode 100644
index 0000000..02102fd
--- /dev/null
+++ b/quiche/quic/core/quic_unacked_packet_map_test.cc
@@ -0,0 +1,699 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+#include <cstddef>
+#include <limits>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_transmission_info.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_unacked_packet_map_peer.h"
+
+using testing::_;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+class QuicUnackedPacketMapTest : public QuicTestWithParam<Perspective> {
+ protected:
+  QuicUnackedPacketMapTest()
+      : unacked_packets_(GetParam()),
+        now_(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1000)) {
+    unacked_packets_.SetSessionNotifier(&notifier_);
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_))
+        .Times(testing::AnyNumber());
+  }
+
+  ~QuicUnackedPacketMapTest() override {}
+
+  SerializedPacket CreateRetransmittablePacket(uint64_t packet_number) {
+    return CreateRetransmittablePacketForStream(
+        packet_number, QuicUtils::GetFirstBidirectionalStreamId(
+                           CurrentSupportedVersions()[0].transport_version,
+                           Perspective::IS_CLIENT));
+  }
+
+  SerializedPacket CreateRetransmittablePacketForStream(
+      uint64_t packet_number,
+      QuicStreamId stream_id) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    QuicStreamFrame frame;
+    frame.stream_id = stream_id;
+    packet.retransmittable_frames.push_back(QuicFrame(frame));
+    return packet;
+  }
+
+  SerializedPacket CreateNonRetransmittablePacket(uint64_t packet_number) {
+    return SerializedPacket(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+  }
+
+  void VerifyInFlightPackets(uint64_t* packets, size_t num_packets) {
+    unacked_packets_.RemoveObsoletePackets();
+    if (num_packets == 0) {
+      EXPECT_FALSE(unacked_packets_.HasInFlightPackets());
+      EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
+      return;
+    }
+    if (num_packets == 1) {
+      EXPECT_TRUE(unacked_packets_.HasInFlightPackets());
+      EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
+      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[0])));
+      EXPECT_TRUE(
+          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[0]))
+              .in_flight);
+    }
+    for (size_t i = 0; i < num_packets; ++i) {
+      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])));
+      EXPECT_TRUE(
+          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[i]))
+              .in_flight);
+    }
+    size_t in_flight_count = 0;
+    for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
+         ++it) {
+      if (it->in_flight) {
+        ++in_flight_count;
+      }
+    }
+    EXPECT_EQ(num_packets, in_flight_count);
+  }
+
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
+    unacked_packets_.RemoveObsoletePackets();
+    if (num_packets == 0) {
+      EXPECT_TRUE(unacked_packets_.empty());
+      EXPECT_FALSE(unacked_packets_.HasUnackedRetransmittableFrames());
+      return;
+    }
+    EXPECT_FALSE(unacked_packets_.empty());
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])))
+          << packets[i];
+    }
+    EXPECT_EQ(num_packets, unacked_packets_.GetNumUnackedPacketsDebugOnly());
+  }
+
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
+    unacked_packets_.RemoveObsoletePackets();
+    size_t num_retransmittable_packets = 0;
+    for (auto it = unacked_packets_.begin(); it != unacked_packets_.end();
+         ++it) {
+      if (unacked_packets_.HasRetransmittableFrames(*it)) {
+        ++num_retransmittable_packets;
+      }
+    }
+    EXPECT_EQ(num_packets, num_retransmittable_packets);
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(unacked_packets_.HasRetransmittableFrames(
+          QuicPacketNumber(packets[i])))
+          << " packets[" << i << "]:" << packets[i];
+    }
+  }
+
+  void UpdatePacketState(uint64_t packet_number, SentPacketState state) {
+    unacked_packets_
+        .GetMutableTransmissionInfo(QuicPacketNumber(packet_number))
+        ->state = state;
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number,
+                               TransmissionType transmission_type) {
+    QUICHE_DCHECK(unacked_packets_.HasRetransmittableFrames(
+        QuicPacketNumber(old_packet_number)));
+    QuicTransmissionInfo* info = unacked_packets_.GetMutableTransmissionInfo(
+        QuicPacketNumber(old_packet_number));
+    QuicStreamId stream_id = QuicUtils::GetFirstBidirectionalStreamId(
+        CurrentSupportedVersions()[0].transport_version,
+        Perspective::IS_CLIENT);
+    for (const auto& frame : info->retransmittable_frames) {
+      if (frame.type == STREAM_FRAME) {
+        stream_id = frame.stream_frame.stream_id;
+        break;
+      }
+    }
+    UpdatePacketState(
+        old_packet_number,
+        QuicUtils::RetransmissionTypeToPacketState(transmission_type));
+    info->first_sent_after_loss = QuicPacketNumber(new_packet_number);
+    SerializedPacket packet(
+        CreateRetransmittablePacketForStream(new_packet_number, stream_id));
+    unacked_packets_.AddSentPacket(&packet, transmission_type, now_, true,
+                                   true);
+  }
+  QuicUnackedPacketMap unacked_packets_;
+  QuicTime now_;
+  StrictMock<MockSessionNotifier> notifier_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicUnackedPacketMapTest,
+                         ::testing::ValuesIn({Perspective::IS_CLIENT,
+                                              Perspective::IS_SERVER}),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicUnackedPacketMapTest, RttOnly) {
+  // Acks are only tracked for RTT measurement purposes.
+  SerializedPacket packet(CreateNonRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, false,
+                                 true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
+  // Simulate a retransmittable packet being sent and acked.
+  SerializedPacket packet(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(unacked, ABSL_ARRAYSIZE(unacked));
+
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, StopRetransmission) {
+  const QuicStreamId stream_id = 2;
+  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
+  const QuicStreamId stream_id = 2;
+  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, now_, true, true);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+}
+
+TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
+  const QuicStreamId stream_id = 2;
+  SerializedPacket packet1(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable = {1, 2};
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmittedPacket) {
+  // Simulate a retransmittable packet being sent, retransmitted, and the first
+  // transmission being acked.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable = {1, 2};
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+
+  EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  uint64_t unacked2[] = {1};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  VerifyInFlightPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyInFlightPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
+  // Simulate a retransmittable packet being sent and retransmitted twice.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1, 2};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  // Early retransmit 1 as 3 and send new data as 4.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
+  SerializedPacket packet4(CreateRetransmittablePacket(4));
+  unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked2[] = {1, 3, 4};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  uint64_t pending2[] = {3, 4};
+  VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
+  std::vector<uint64_t> retransmittable2 = {1, 3, 4};
+  VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
+
+  // Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(4));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(4));
+  RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+  SerializedPacket packet6(CreateRetransmittablePacket(6));
+  unacked_packets_.AddSentPacket(&packet6, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  std::vector<uint64_t> unacked3 = {3, 5, 6};
+  std::vector<uint64_t> retransmittable3 = {3, 5, 6};
+  VerifyUnackedPackets(&unacked3[0], unacked3.size());
+  VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
+  uint64_t pending3[] = {3, 5, 6};
+  VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
+
+  // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(6));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(6));
+  RetransmitAndSendPacket(5, 7, LOSS_RETRANSMISSION);
+
+  std::vector<uint64_t> unacked4 = {3, 5, 7};
+  std::vector<uint64_t> retransmittable4 = {3, 5, 7};
+  VerifyUnackedPackets(&unacked4[0], unacked4.size());
+  VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
+  uint64_t pending4[] = {3, 5, 7};
+  VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
+
+  // Remove the older two transmissions from in flight.
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  uint64_t pending5[] = {7};
+  VerifyInFlightPackets(pending5, ABSL_ARRAYSIZE(pending5));
+}
+
+TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) {
+  // Simulate a retransmittable packet being sent and retransmitted twice.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  VerifyInFlightPackets(unacked, ABSL_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1, 2};
+  VerifyRetransmittablePackets(retransmittable,
+                               ABSL_ARRAYSIZE(retransmittable));
+
+  // Early retransmit 1 as 3.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
+
+  uint64_t unacked2[] = {1, 3};
+  VerifyUnackedPackets(unacked2, ABSL_ARRAYSIZE(unacked2));
+  uint64_t pending2[] = {3};
+  VerifyInFlightPackets(pending2, ABSL_ARRAYSIZE(pending2));
+  std::vector<uint64_t> retransmittable2 = {1, 3};
+  VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
+
+  // TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
+  RetransmitAndSendPacket(3, 4, TLP_RETRANSMISSION);
+  SerializedPacket packet5(CreateRetransmittablePacket(5));
+  unacked_packets_.AddSentPacket(&packet5, NOT_RETRANSMISSION, now_, true,
+                                 true);
+
+  uint64_t unacked3[] = {1, 3, 4, 5};
+  VerifyUnackedPackets(unacked3, ABSL_ARRAYSIZE(unacked3));
+  uint64_t pending3[] = {3, 4, 5};
+  VerifyInFlightPackets(pending3, ABSL_ARRAYSIZE(pending3));
+  std::vector<uint64_t> retransmittable3 = {1, 3, 4, 5};
+  VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
+
+  // Early retransmit 4 as 6 and ensure in flight packet 3 is removed.
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(5));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(5));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  RetransmitAndSendPacket(4, 6, LOSS_RETRANSMISSION);
+
+  std::vector<uint64_t> unacked4 = {4, 6};
+  VerifyUnackedPackets(&unacked4[0], unacked4.size());
+  uint64_t pending4[] = {6};
+  VerifyInFlightPackets(pending4, ABSL_ARRAYSIZE(pending4));
+  std::vector<uint64_t> retransmittable4 = {4, 6};
+  VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
+}
+
+TEST_P(QuicUnackedPacketMapTest, SendWithGap) {
+  // Simulate a retransmittable packet being sent, retransmitted, and the first
+  // transmission being acked.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  SerializedPacket packet3(CreateRetransmittablePacket(3));
+  unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+
+  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.GetLeastUnacked());
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(1)));
+  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(2)));
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(3)));
+  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(4)));
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(5)));
+  EXPECT_EQ(QuicPacketNumber(5u), unacked_packets_.largest_sent_packet());
+}
+
+TEST_P(QuicUnackedPacketMapTest, AggregateContiguousAckedStreamFrames) {
+  testing::InSequence s;
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
+
+  QuicTransmissionInfo info1;
+  QuicStreamFrame stream_frame1(3, false, 0, 100);
+  info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
+
+  QuicTransmissionInfo info2;
+  QuicStreamFrame stream_frame2(3, false, 100, 100);
+  info2.retransmittable_frames.push_back(QuicFrame(stream_frame2));
+
+  QuicTransmissionInfo info3;
+  QuicStreamFrame stream_frame3(3, false, 200, 100);
+  info3.retransmittable_frames.push_back(QuicFrame(stream_frame3));
+
+  QuicTransmissionInfo info4;
+  QuicStreamFrame stream_frame4(3, true, 300, 0);
+  info4.retransmittable_frames.push_back(QuicFrame(stream_frame4));
+
+  // Verify stream frames are aggregated.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info1, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info2, QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info3, QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  // Verify aggregated stream frame gets acked since fin is acked.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info4, QuicTime::Delta::Zero(), QuicTime::Zero());
+}
+
+// Regression test for b/112930090.
+TEST_P(QuicUnackedPacketMapTest, CannotAggregateIfDataLengthOverflow) {
+  QuicByteCount kMaxAggregatedDataLength =
+      std::numeric_limits<decltype(QuicStreamFrame().data_length)>::max();
+  QuicStreamId stream_id = 2;
+
+  // acked_stream_length=512 covers the case where a frame will cause the
+  // aggregated frame length to be exactly 64K.
+  // acked_stream_length=1300 covers the case where a frame will cause the
+  // aggregated frame length to exceed 64K.
+  for (const QuicPacketLength acked_stream_length : {512, 1300}) {
+    ++stream_id;
+    QuicStreamOffset offset = 0;
+    // Expected length of the aggregated stream frame.
+    QuicByteCount aggregated_data_length = 0;
+
+    while (offset < 1e6) {
+      QuicTransmissionInfo info;
+      QuicStreamFrame stream_frame(stream_id, false, offset,
+                                   acked_stream_length);
+      info.retransmittable_frames.push_back(QuicFrame(stream_frame));
+
+      const QuicStreamFrame& aggregated_stream_frame =
+          QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(unacked_packets_);
+      if (aggregated_stream_frame.data_length + acked_stream_length <=
+          kMaxAggregatedDataLength) {
+        // Verify the acked stream frame can be aggregated.
+        EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+        unacked_packets_.MaybeAggregateAckedStreamFrame(
+            info, QuicTime::Delta::Zero(), QuicTime::Zero());
+        aggregated_data_length += acked_stream_length;
+        testing::Mock::VerifyAndClearExpectations(&notifier_);
+      } else {
+        // Verify the acked stream frame cannot be aggregated because
+        // data_length is overflow.
+        EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+        unacked_packets_.MaybeAggregateAckedStreamFrame(
+            info, QuicTime::Delta::Zero(), QuicTime::Zero());
+        aggregated_data_length = acked_stream_length;
+        testing::Mock::VerifyAndClearExpectations(&notifier_);
+      }
+
+      EXPECT_EQ(aggregated_data_length, aggregated_stream_frame.data_length);
+      offset += acked_stream_length;
+    }
+
+    // Ack the last frame of the stream.
+    QuicTransmissionInfo info;
+    QuicStreamFrame stream_frame(stream_id, true, offset, acked_stream_length);
+    info.retransmittable_frames.push_back(QuicFrame(stream_frame));
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+    unacked_packets_.MaybeAggregateAckedStreamFrame(
+        info, QuicTime::Delta::Zero(), QuicTime::Zero());
+    testing::Mock::VerifyAndClearExpectations(&notifier_);
+  }
+}
+
+TEST_P(QuicUnackedPacketMapTest, CannotAggregateAckedControlFrames) {
+  testing::InSequence s;
+  QuicWindowUpdateFrame window_update(1, 5, 100);
+  QuicStreamFrame stream_frame1(3, false, 0, 100);
+  QuicStreamFrame stream_frame2(3, false, 100, 100);
+  QuicBlockedFrame blocked(2, 5);
+  QuicGoAwayFrame go_away(3, QUIC_PEER_GOING_AWAY, 5, "Going away.");
+
+  QuicTransmissionInfo info1;
+  info1.retransmittable_frames.push_back(QuicFrame(window_update));
+  info1.retransmittable_frames.push_back(QuicFrame(stream_frame1));
+  info1.retransmittable_frames.push_back(QuicFrame(stream_frame2));
+
+  QuicTransmissionInfo info2;
+  info2.retransmittable_frames.push_back(QuicFrame(blocked));
+  info2.retransmittable_frames.push_back(QuicFrame(&go_away));
+
+  // Verify 2 contiguous stream frames are aggregated.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info1, QuicTime::Delta::Zero(), QuicTime::Zero());
+  // Verify aggregated stream frame gets acked.
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(3);
+  unacked_packets_.MaybeAggregateAckedStreamFrame(
+      info2, QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(0);
+  unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero());
+}
+
+TEST_P(QuicUnackedPacketMapTest, LargestSentPacketMultiplePacketNumberSpaces) {
+  unacked_packets_.EnableMultiplePacketNumberSpacesSupport();
+  EXPECT_FALSE(
+      unacked_packets_
+          .GetLargestSentRetransmittableOfPacketNumberSpace(INITIAL_DATA)
+          .IsInitialized());
+  // Send packet 1.
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  packet1.encryption_level = ENCRYPTION_INITIAL;
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_FALSE(
+      unacked_packets_
+          .GetLargestSentRetransmittableOfPacketNumberSpace(HANDSHAKE_DATA)
+          .IsInitialized());
+  // Send packet 2.
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  packet2.encryption_level = ENCRYPTION_HANDSHAKE;
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(2u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(2),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_FALSE(
+      unacked_packets_
+          .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
+          .IsInitialized());
+  // Send packet 3.
+  SerializedPacket packet3(CreateRetransmittablePacket(3));
+  packet3.encryption_level = ENCRYPTION_ZERO_RTT;
+  unacked_packets_.AddSentPacket(&packet3, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(3u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(2),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Verify forward secure belongs to the same packet number space as encryption
+  // zero rtt.
+  EXPECT_EQ(QuicPacketNumber(3),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+
+  // Send packet 4.
+  SerializedPacket packet4(CreateRetransmittablePacket(4));
+  packet4.encryption_level = ENCRYPTION_FORWARD_SECURE;
+  unacked_packets_.AddSentPacket(&packet4, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(QuicPacketNumber(4u), unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                INITIAL_DATA));
+  EXPECT_EQ(QuicPacketNumber(2),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                HANDSHAKE_DATA));
+  EXPECT_EQ(QuicPacketNumber(4),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  // Verify forward secure belongs to the same packet number space as encryption
+  // zero rtt.
+  EXPECT_EQ(QuicPacketNumber(4),
+            unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
+                APPLICATION_DATA));
+  EXPECT_TRUE(unacked_packets_.GetLastPacketContent() & (1 << STREAM_FRAME));
+  EXPECT_FALSE(unacked_packets_.GetLastPacketContent() & (1 << ACK_FRAME));
+}
+
+TEST_P(QuicUnackedPacketMapTest, ReserveInitialCapacityTest) {
+  QuicUnackedPacketMap unacked_packets(GetParam());
+  ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 0u);
+  unacked_packets.ReserveInitialCapacity(16);
+  QuicStreamId stream_id(1);
+  SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
+  unacked_packets.AddSentPacket(&packet, TransmissionType::NOT_RETRANSMISSION,
+                                now_, true, true);
+  ASSERT_EQ(QuicUnackedPacketMapPeer::GetCapacity(unacked_packets), 16u);
+}
+
+TEST_P(QuicUnackedPacketMapTest, DebugString) {
+  EXPECT_EQ(unacked_packets_.DebugString(),
+            "{size: 0, least_unacked: 1, largest_sent_packet: uninitialized, "
+            "largest_acked: uninitialized, bytes_in_flight: 0, "
+            "packets_in_flight: 0}");
+
+  SerializedPacket packet1(CreateRetransmittablePacket(1));
+  unacked_packets_.AddSentPacket(&packet1, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  EXPECT_EQ(
+      unacked_packets_.DebugString(),
+      "{size: 1, least_unacked: 1, largest_sent_packet: 1, largest_acked: "
+      "uninitialized, bytes_in_flight: 1000, packets_in_flight: 1}");
+
+  SerializedPacket packet2(CreateRetransmittablePacket(2));
+  unacked_packets_.AddSentPacket(&packet2, NOT_RETRANSMISSION, now_, true,
+                                 true);
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
+  unacked_packets_.RemoveObsoletePackets();
+  EXPECT_EQ(
+      unacked_packets_.DebugString(),
+      "{size: 1, least_unacked: 2, largest_sent_packet: 2, largest_acked: 1, "
+      "bytes_in_flight: 1000, packets_in_flight: 1}");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_utils.cc b/quiche/quic/core/quic_utils.cc
new file mode 100644
index 0000000..fb37efc
--- /dev/null
+++ b/quiche/quic/core/quic_utils.cc
@@ -0,0 +1,690 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_utils.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <limits>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace {
+
+// We know that >= GCC 4.8 and Clang have a __uint128_t intrinsic. Other
+// compilers don't necessarily, notably MSVC.
+#if defined(__x86_64__) &&                                         \
+    ((defined(__GNUC__) &&                                         \
+      (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
+     defined(__clang__))
+#define QUIC_UTIL_HAS_UINT128 1
+#endif
+
+#ifdef QUIC_UTIL_HAS_UINT128
+absl::uint128 IncrementalHashFast(absl::uint128 uhash, absl::string_view data) {
+  // This code ends up faster than the naive implementation for 2 reasons:
+  // 1. absl::uint128 is sufficiently complicated that the compiler
+  //    cannot transform the multiplication by kPrime into a shift-multiply-add;
+  //    it has go through all of the instructions for a 128-bit multiply.
+  // 2. Because there are so fewer instructions (around 13), the hot loop fits
+  //    nicely in the instruction queue of many Intel CPUs.
+  // kPrime = 309485009821345068724781371
+  static const absl::uint128 kPrime =
+      (static_cast<absl::uint128>(16777216) << 64) + 315;
+  auto hi = absl::Uint128High64(uhash);
+  auto lo = absl::Uint128Low64(uhash);
+  absl::uint128 xhash = (static_cast<absl::uint128>(hi) << 64) + lo;
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
+  for (size_t i = 0; i < data.length(); ++i) {
+    xhash = (xhash ^ static_cast<uint32_t>(octets[i])) * kPrime;
+  }
+  return absl::MakeUint128(absl::Uint128High64(xhash),
+                           absl::Uint128Low64(xhash));
+}
+#endif
+
+#ifndef QUIC_UTIL_HAS_UINT128
+// Slow implementation of IncrementalHash. In practice, only used by Chromium.
+absl::uint128 IncrementalHashSlow(absl::uint128 hash, absl::string_view data) {
+  // kPrime = 309485009821345068724781371
+  static const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
+  for (size_t i = 0; i < data.length(); ++i) {
+    hash = hash ^ absl::MakeUint128(0, octets[i]);
+    hash = hash * kPrime;
+  }
+  return hash;
+}
+#endif
+
+absl::uint128 IncrementalHash(absl::uint128 hash, absl::string_view data) {
+#ifdef QUIC_UTIL_HAS_UINT128
+  return IncrementalHashFast(hash, data);
+#else
+  return IncrementalHashSlow(hash, data);
+#endif
+}
+
+}  // namespace
+
+// static
+uint64_t QuicUtils::FNV1a_64_Hash(absl::string_view data) {
+  static const uint64_t kOffset = UINT64_C(14695981039346656037);
+  static const uint64_t kPrime = UINT64_C(1099511628211);
+
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
+
+  uint64_t hash = kOffset;
+
+  for (size_t i = 0; i < data.length(); ++i) {
+    hash = hash ^ octets[i];
+    hash = hash * kPrime;
+  }
+
+  return hash;
+}
+
+// static
+absl::uint128 QuicUtils::FNV1a_128_Hash(absl::string_view data) {
+  return FNV1a_128_Hash_Three(data, absl::string_view(), absl::string_view());
+}
+
+// static
+absl::uint128 QuicUtils::FNV1a_128_Hash_Two(absl::string_view data1,
+                                            absl::string_view data2) {
+  return FNV1a_128_Hash_Three(data1, data2, absl::string_view());
+}
+
+// static
+absl::uint128 QuicUtils::FNV1a_128_Hash_Three(absl::string_view data1,
+                                              absl::string_view data2,
+                                              absl::string_view data3) {
+  // The two constants are defined as part of the hash algorithm.
+  // see http://www.isthe.com/chongo/tech/comp/fnv/
+  // kOffset = 144066263297769815596495629667062367629
+  const absl::uint128 kOffset = absl::MakeUint128(
+      UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
+
+  absl::uint128 hash = IncrementalHash(kOffset, data1);
+  if (data2.empty()) {
+    return hash;
+  }
+
+  hash = IncrementalHash(hash, data2);
+  if (data3.empty()) {
+    return hash;
+  }
+  return IncrementalHash(hash, data3);
+}
+
+// static
+void QuicUtils::SerializeUint128Short(absl::uint128 v, uint8_t* out) {
+  const uint64_t lo = absl::Uint128Low64(v);
+  const uint64_t hi = absl::Uint128High64(v);
+  // This assumes that the system is little-endian.
+  memcpy(out, &lo, sizeof(lo));
+  memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
+}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x;
+
+std::string QuicUtils::AddressChangeTypeToString(AddressChangeType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(NO_CHANGE);
+    RETURN_STRING_LITERAL(PORT_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_SUBNET_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV6_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV4_CHANGE);
+    RETURN_STRING_LITERAL(IPV6_TO_IPV6_CHANGE);
+    RETURN_STRING_LITERAL(IPV4_TO_IPV4_CHANGE);
+  }
+  return "INVALID_ADDRESS_CHANGE_TYPE";
+}
+
+const char* QuicUtils::SentPacketStateToString(SentPacketState state) {
+  switch (state) {
+    RETURN_STRING_LITERAL(OUTSTANDING);
+    RETURN_STRING_LITERAL(NEVER_SENT);
+    RETURN_STRING_LITERAL(ACKED);
+    RETURN_STRING_LITERAL(UNACKABLE);
+    RETURN_STRING_LITERAL(NEUTERED);
+    RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMITTED);
+    RETURN_STRING_LITERAL(LOST);
+    RETURN_STRING_LITERAL(TLP_RETRANSMITTED);
+    RETURN_STRING_LITERAL(RTO_RETRANSMITTED);
+    RETURN_STRING_LITERAL(PTO_RETRANSMITTED);
+    RETURN_STRING_LITERAL(PROBE_RETRANSMITTED);
+    RETURN_STRING_LITERAL(NOT_CONTRIBUTING_RTT);
+  }
+  return "INVALID_SENT_PACKET_STATE";
+}
+
+// static
+const char* QuicUtils::QuicLongHeaderTypetoString(QuicLongHeaderType type) {
+  switch (type) {
+    RETURN_STRING_LITERAL(VERSION_NEGOTIATION);
+    RETURN_STRING_LITERAL(INITIAL);
+    RETURN_STRING_LITERAL(RETRY);
+    RETURN_STRING_LITERAL(HANDSHAKE);
+    RETURN_STRING_LITERAL(ZERO_RTT_PROTECTED);
+    default:
+      return "INVALID_PACKET_TYPE";
+  }
+}
+
+// static
+const char* QuicUtils::AckResultToString(AckResult result) {
+  switch (result) {
+    RETURN_STRING_LITERAL(PACKETS_NEWLY_ACKED);
+    RETURN_STRING_LITERAL(NO_PACKETS_NEWLY_ACKED);
+    RETURN_STRING_LITERAL(UNSENT_PACKETS_ACKED);
+    RETURN_STRING_LITERAL(UNACKABLE_PACKETS_ACKED);
+    RETURN_STRING_LITERAL(PACKETS_ACKED_IN_WRONG_PACKET_NUMBER_SPACE);
+  }
+  return "INVALID_ACK_RESULT";
+}
+
+// static
+AddressChangeType QuicUtils::DetermineAddressChangeType(
+    const QuicSocketAddress& old_address,
+    const QuicSocketAddress& new_address) {
+  if (!old_address.IsInitialized() || !new_address.IsInitialized() ||
+      old_address == new_address) {
+    return NO_CHANGE;
+  }
+
+  if (old_address.host() == new_address.host()) {
+    return PORT_CHANGE;
+  }
+
+  bool old_ip_is_ipv4 = old_address.host().IsIPv4() ? true : false;
+  bool migrating_ip_is_ipv4 = new_address.host().IsIPv4() ? true : false;
+  if (old_ip_is_ipv4 && !migrating_ip_is_ipv4) {
+    return IPV4_TO_IPV6_CHANGE;
+  }
+
+  if (!old_ip_is_ipv4) {
+    return migrating_ip_is_ipv4 ? IPV6_TO_IPV4_CHANGE : IPV6_TO_IPV6_CHANGE;
+  }
+
+  const int kSubnetMaskLength = 24;
+  if (old_address.host().InSameSubnet(new_address.host(), kSubnetMaskLength)) {
+    // Subnet part does not change (here, we use /24), which is considered to be
+    // caused by NATs.
+    return IPV4_SUBNET_CHANGE;
+  }
+
+  return IPV4_TO_IPV4_CHANGE;
+}
+
+// static
+bool QuicUtils::IsAckable(SentPacketState state) {
+  return state != NEVER_SENT && state != ACKED && state != UNACKABLE;
+}
+
+// static
+bool QuicUtils::IsRetransmittableFrame(QuicFrameType type) {
+  switch (type) {
+    case ACK_FRAME:
+    case PADDING_FRAME:
+    case STOP_WAITING_FRAME:
+    case MTU_DISCOVERY_FRAME:
+    case PATH_CHALLENGE_FRAME:
+    case PATH_RESPONSE_FRAME:
+      return false;
+    default:
+      return true;
+  }
+}
+
+// static
+bool QuicUtils::IsHandshakeFrame(const QuicFrame& frame,
+                                 QuicTransportVersion transport_version) {
+  if (!QuicVersionUsesCryptoFrames(transport_version)) {
+    return frame.type == STREAM_FRAME &&
+           frame.stream_frame.stream_id == GetCryptoStreamId(transport_version);
+  } else {
+    return frame.type == CRYPTO_FRAME;
+  }
+}
+
+// static
+bool QuicUtils::ContainsFrameType(const QuicFrames& frames,
+                                  QuicFrameType type) {
+  for (const QuicFrame& frame : frames) {
+    if (frame.type == type) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// static
+SentPacketState QuicUtils::RetransmissionTypeToPacketState(
+    TransmissionType retransmission_type) {
+  switch (retransmission_type) {
+    case ALL_ZERO_RTT_RETRANSMISSION:
+      return UNACKABLE;
+    case HANDSHAKE_RETRANSMISSION:
+      return HANDSHAKE_RETRANSMITTED;
+    case LOSS_RETRANSMISSION:
+      return LOST;
+    case TLP_RETRANSMISSION:
+      return TLP_RETRANSMITTED;
+    case RTO_RETRANSMISSION:
+      return RTO_RETRANSMITTED;
+    case PTO_RETRANSMISSION:
+      return PTO_RETRANSMITTED;
+    case PROBING_RETRANSMISSION:
+      return PROBE_RETRANSMITTED;
+    case PATH_RETRANSMISSION:
+      return NOT_CONTRIBUTING_RTT;
+    case ALL_INITIAL_RETRANSMISSION:
+      return UNACKABLE;
+    default:
+      QUIC_BUG(quic_bug_10839_2)
+          << retransmission_type << " is not a retransmission_type";
+      return UNACKABLE;
+  }
+}
+
+// static
+bool QuicUtils::IsIetfPacketHeader(uint8_t first_byte) {
+  return (first_byte & FLAGS_LONG_HEADER) || (first_byte & FLAGS_FIXED_BIT) ||
+         !(first_byte & FLAGS_DEMULTIPLEXING_BIT);
+}
+
+// static
+bool QuicUtils::IsIetfPacketShortHeader(uint8_t first_byte) {
+  return IsIetfPacketHeader(first_byte) && !(first_byte & FLAGS_LONG_HEADER);
+}
+
+// static
+QuicStreamId QuicUtils::GetInvalidStreamId(QuicTransportVersion version) {
+  return VersionHasIetfQuicFrames(version)
+             ? std::numeric_limits<QuicStreamId>::max()
+             : 0;
+}
+
+// static
+QuicStreamId QuicUtils::GetCryptoStreamId(QuicTransportVersion version) {
+  QUIC_BUG_IF(quic_bug_12982_1, QuicVersionUsesCryptoFrames(version))
+      << "CRYPTO data aren't in stream frames; they have no stream ID.";
+  return QuicVersionUsesCryptoFrames(version) ? GetInvalidStreamId(version) : 1;
+}
+
+// static
+bool QuicUtils::IsCryptoStreamId(QuicTransportVersion version,
+                                 QuicStreamId stream_id) {
+  if (QuicVersionUsesCryptoFrames(version)) {
+    return false;
+  }
+  return stream_id == GetCryptoStreamId(version);
+}
+
+// static
+QuicStreamId QuicUtils::GetHeadersStreamId(QuicTransportVersion version) {
+  QUICHE_DCHECK(!VersionUsesHttp3(version));
+  return GetFirstBidirectionalStreamId(version, Perspective::IS_CLIENT);
+}
+
+// static
+bool QuicUtils::IsClientInitiatedStreamId(QuicTransportVersion version,
+                                          QuicStreamId id) {
+  if (id == GetInvalidStreamId(version)) {
+    return false;
+  }
+  return VersionHasIetfQuicFrames(version) ? id % 2 == 0 : id % 2 != 0;
+}
+
+// static
+bool QuicUtils::IsServerInitiatedStreamId(QuicTransportVersion version,
+                                          QuicStreamId id) {
+  if (id == GetInvalidStreamId(version)) {
+    return false;
+  }
+  return VersionHasIetfQuicFrames(version) ? id % 2 != 0 : id % 2 == 0;
+}
+
+// static
+bool QuicUtils::IsOutgoingStreamId(ParsedQuicVersion version,
+                                   QuicStreamId id,
+                                   Perspective perspective) {
+  // Streams are outgoing streams, iff:
+  // - we are the server and the stream is server-initiated
+  // - we are the client and the stream is client-initiated.
+  const bool perspective_is_server = perspective == Perspective::IS_SERVER;
+  const bool stream_is_server =
+      QuicUtils::IsServerInitiatedStreamId(version.transport_version, id);
+  return perspective_is_server == stream_is_server;
+}
+
+// static
+bool QuicUtils::IsBidirectionalStreamId(QuicStreamId id,
+                                        ParsedQuicVersion version) {
+  QUICHE_DCHECK(version.HasIetfQuicFrames());
+  return id % 4 < 2;
+}
+
+// static
+StreamType QuicUtils::GetStreamType(QuicStreamId id,
+                                    Perspective perspective,
+                                    bool peer_initiated,
+                                    ParsedQuicVersion version) {
+  QUICHE_DCHECK(version.HasIetfQuicFrames());
+  if (IsBidirectionalStreamId(id, version)) {
+    return BIDIRECTIONAL;
+  }
+
+  if (peer_initiated) {
+    if (perspective == Perspective::IS_SERVER) {
+      QUICHE_DCHECK_EQ(2u, id % 4);
+    } else {
+      QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
+      QUICHE_DCHECK_EQ(3u, id % 4);
+    }
+    return READ_UNIDIRECTIONAL;
+  }
+
+  if (perspective == Perspective::IS_SERVER) {
+    QUICHE_DCHECK_EQ(3u, id % 4);
+  } else {
+    QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective);
+    QUICHE_DCHECK_EQ(2u, id % 4);
+  }
+  return WRITE_UNIDIRECTIONAL;
+}
+
+// static
+QuicStreamId QuicUtils::StreamIdDelta(QuicTransportVersion version) {
+  return VersionHasIetfQuicFrames(version) ? 4 : 2;
+}
+
+// static
+QuicStreamId QuicUtils::GetFirstBidirectionalStreamId(
+    QuicTransportVersion version,
+    Perspective perspective) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 0 : 1;
+  } else if (QuicVersionUsesCryptoFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 1 : 2;
+  }
+  return perspective == Perspective::IS_CLIENT ? 3 : 2;
+}
+
+// static
+QuicStreamId QuicUtils::GetFirstUnidirectionalStreamId(
+    QuicTransportVersion version,
+    Perspective perspective) {
+  if (VersionHasIetfQuicFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 2 : 3;
+  } else if (QuicVersionUsesCryptoFrames(version)) {
+    return perspective == Perspective::IS_CLIENT ? 1 : 2;
+  }
+  return perspective == Perspective::IS_CLIENT ? 3 : 2;
+}
+
+// static
+QuicStreamId QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
+    QuicTransportVersion version) {
+  if (VersionHasIetfQuicFrames(version)) {
+    // Client initiated bidirectional streams have stream IDs divisible by 4.
+    return std::numeric_limits<QuicStreamId>::max() - 3;
+  }
+
+  // Client initiated bidirectional streams have odd stream IDs.
+  return std::numeric_limits<QuicStreamId>::max();
+}
+
+// static
+QuicConnectionId QuicUtils::CreateReplacementConnectionId(
+    const QuicConnectionId& connection_id) {
+  return CreateReplacementConnectionId(connection_id,
+                                       kQuicDefaultConnectionIdLength);
+}
+
+// static
+QuicConnectionId QuicUtils::CreateReplacementConnectionId(
+    const QuicConnectionId& connection_id,
+    uint8_t expected_connection_id_length) {
+  if (expected_connection_id_length == 0) {
+    return EmptyQuicConnectionId();
+  }
+  const uint64_t connection_id_hash64 = FNV1a_64_Hash(
+      absl::string_view(connection_id.data(), connection_id.length()));
+  if (expected_connection_id_length <= sizeof(uint64_t)) {
+    return QuicConnectionId(
+        reinterpret_cast<const char*>(&connection_id_hash64),
+        expected_connection_id_length);
+  }
+  char new_connection_id_data[255] = {};
+  const absl::uint128 connection_id_hash128 = FNV1a_128_Hash(
+      absl::string_view(connection_id.data(), connection_id.length()));
+  static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <=
+                    sizeof(new_connection_id_data),
+                "bad size");
+  memcpy(new_connection_id_data, &connection_id_hash64,
+         sizeof(connection_id_hash64));
+  memcpy(new_connection_id_data + sizeof(connection_id_hash64),
+         &connection_id_hash128, sizeof(connection_id_hash128));
+  return QuicConnectionId(new_connection_id_data,
+                          expected_connection_id_length);
+}
+
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId() {
+  return CreateRandomConnectionId(kQuicDefaultConnectionIdLength,
+                                  QuicRandom::GetInstance());
+}
+
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId(QuicRandom* random) {
+  return CreateRandomConnectionId(kQuicDefaultConnectionIdLength, random);
+}
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId(
+    uint8_t connection_id_length) {
+  return CreateRandomConnectionId(connection_id_length,
+                                  QuicRandom::GetInstance());
+}
+
+// static
+QuicConnectionId QuicUtils::CreateRandomConnectionId(
+    uint8_t connection_id_length,
+    QuicRandom* random) {
+  QuicConnectionId connection_id;
+  connection_id.set_length(connection_id_length);
+  if (connection_id.length() > 0) {
+    random->RandBytes(connection_id.mutable_data(), connection_id.length());
+  }
+  return connection_id;
+}
+
+// static
+QuicConnectionId QuicUtils::CreateZeroConnectionId(
+    QuicTransportVersion version) {
+  if (!VersionAllowsVariableLengthConnectionIds(version)) {
+    char connection_id_bytes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    return QuicConnectionId(static_cast<char*>(connection_id_bytes),
+                            ABSL_ARRAYSIZE(connection_id_bytes));
+  }
+  return EmptyQuicConnectionId();
+}
+
+// static
+bool QuicUtils::IsConnectionIdLengthValidForVersion(
+    size_t connection_id_length,
+    QuicTransportVersion transport_version) {
+  // No version of QUIC can support lengths that do not fit in an uint8_t.
+  if (connection_id_length >
+      static_cast<size_t>(std::numeric_limits<uint8_t>::max())) {
+    return false;
+  }
+
+  if (transport_version == QUIC_VERSION_UNSUPPORTED ||
+      transport_version == QUIC_VERSION_RESERVED_FOR_NEGOTIATION) {
+    // Unknown versions could allow connection ID lengths up to 255.
+    return true;
+  }
+
+  const uint8_t connection_id_length8 =
+      static_cast<uint8_t>(connection_id_length);
+  // Versions that do not support variable lengths only support length 8.
+  if (!VersionAllowsVariableLengthConnectionIds(transport_version)) {
+    return connection_id_length8 == kQuicDefaultConnectionIdLength;
+  }
+  // Versions that do support variable length but do not have length-prefixed
+  // connection IDs use the 4-bit connection ID length encoding which can
+  // only encode values 0 and 4-18.
+  if (!VersionHasLengthPrefixedConnectionIds(transport_version)) {
+    return connection_id_length8 == 0 ||
+           (connection_id_length8 >= 4 &&
+            connection_id_length8 <= kQuicMaxConnectionId4BitLength);
+  }
+  return connection_id_length8 <= kQuicMaxConnectionIdWithLengthPrefixLength;
+}
+
+// static
+bool QuicUtils::IsConnectionIdValidForVersion(
+    QuicConnectionId connection_id,
+    QuicTransportVersion transport_version) {
+  return IsConnectionIdLengthValidForVersion(connection_id.length(),
+                                             transport_version);
+}
+
+StatelessResetToken QuicUtils::GenerateStatelessResetToken(
+    QuicConnectionId connection_id) {
+  static_assert(sizeof(absl::uint128) == sizeof(StatelessResetToken),
+                "bad size");
+  static_assert(alignof(absl::uint128) >= alignof(StatelessResetToken),
+                "bad alignment");
+  absl::uint128 hash = FNV1a_128_Hash(
+      absl::string_view(connection_id.data(), connection_id.length()));
+  return *reinterpret_cast<StatelessResetToken*>(&hash);
+}
+
+// static
+QuicStreamCount QuicUtils::GetMaxStreamCount() {
+  return (kMaxQuicStreamCount >> 2) + 1;
+}
+
+// static
+PacketNumberSpace QuicUtils::GetPacketNumberSpace(
+    EncryptionLevel encryption_level) {
+  switch (encryption_level) {
+    case ENCRYPTION_INITIAL:
+      return INITIAL_DATA;
+    case ENCRYPTION_HANDSHAKE:
+      return HANDSHAKE_DATA;
+    case ENCRYPTION_ZERO_RTT:
+    case ENCRYPTION_FORWARD_SECURE:
+      return APPLICATION_DATA;
+    default:
+      QUIC_BUG(quic_bug_10839_3)
+          << "Try to get packet number space of encryption level: "
+          << encryption_level;
+      return NUM_PACKET_NUMBER_SPACES;
+  }
+}
+
+// static
+EncryptionLevel QuicUtils::GetEncryptionLevel(
+    PacketNumberSpace packet_number_space) {
+  switch (packet_number_space) {
+    case INITIAL_DATA:
+      return ENCRYPTION_INITIAL;
+    case HANDSHAKE_DATA:
+      return ENCRYPTION_HANDSHAKE;
+    case APPLICATION_DATA:
+      return ENCRYPTION_FORWARD_SECURE;
+    default:
+      QUICHE_DCHECK(false);
+      return NUM_ENCRYPTION_LEVELS;
+  }
+}
+
+// static
+bool QuicUtils::IsProbingFrame(QuicFrameType type) {
+  switch (type) {
+    case PATH_CHALLENGE_FRAME:
+    case PATH_RESPONSE_FRAME:
+    case NEW_CONNECTION_ID_FRAME:
+    case PADDING_FRAME:
+      return true;
+    default:
+      return false;
+  }
+}
+
+// static
+bool QuicUtils::IsAckElicitingFrame(QuicFrameType type) {
+  switch (type) {
+    case PADDING_FRAME:
+    case STOP_WAITING_FRAME:
+    case ACK_FRAME:
+    case CONNECTION_CLOSE_FRAME:
+      return false;
+    default:
+      return true;
+  }
+}
+
+// static
+bool QuicUtils::AreStatelessResetTokensEqual(
+    const StatelessResetToken& token1,
+    const StatelessResetToken& token2) {
+  char byte = 0;
+  for (size_t i = 0; i < kStatelessResetTokenLength; i++) {
+    // This avoids compiler optimizations that could make us stop comparing
+    // after we find a byte that doesn't match.
+    byte |= (token1[i] ^ token2[i]);
+  }
+  return byte == 0;
+}
+
+bool IsValidWebTransportSessionId(WebTransportSessionId id,
+                                  ParsedQuicVersion version) {
+  QUICHE_DCHECK(version.UsesHttp3());
+  return (id <= std::numeric_limits<QuicStreamId>::max()) &&
+         QuicUtils::IsBidirectionalStreamId(id, version) &&
+         QuicUtils::IsClientInitiatedStreamId(version.transport_version, id);
+}
+
+QuicByteCount MemSliceSpanTotalSize(absl::Span<quiche::QuicheMemSlice> span) {
+  QuicByteCount total = 0;
+  for (const quiche::QuicheMemSlice& slice : span) {
+    total += slice.length();
+  }
+  return total;
+}
+
+std::string RawSha256(absl::string_view input) {
+  std::string raw_hash;
+  raw_hash.resize(SHA256_DIGEST_LENGTH);
+  SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(),
+         reinterpret_cast<uint8_t*>(&raw_hash[0]));
+  return raw_hash;
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_utils.h b/quiche/quic/core/quic_utils.h
new file mode 100644
index 0000000..6c2197b
--- /dev/null
+++ b/quiche/quic/core/quic_utils.h
@@ -0,0 +1,310 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_UTILS_H_
+#define QUICHE_QUIC_CORE_QUIC_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <sstream>
+#include <string>
+#include <type_traits>
+
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicUtils {
+ public:
+  QuicUtils() = delete;
+
+  // Returns the 64 bit FNV1a hash of the data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static uint64_t FNV1a_64_Hash(absl::string_view data);
+
+  // Returns the 128 bit FNV1a hash of the data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static absl::uint128 FNV1a_128_Hash(absl::string_view data);
+
+  // Returns the 128 bit FNV1a hash of the two sequences of data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static absl::uint128 FNV1a_128_Hash_Two(absl::string_view data1,
+                                          absl::string_view data2);
+
+  // Returns the 128 bit FNV1a hash of the three sequences of data.  See
+  // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
+  static absl::uint128 FNV1a_128_Hash_Three(absl::string_view data1,
+                                            absl::string_view data2,
+                                            absl::string_view data3);
+
+  // SerializeUint128 writes the first 96 bits of |v| in little-endian form
+  // to |out|.
+  static void SerializeUint128Short(absl::uint128 v, uint8_t* out);
+
+  // Returns AddressChangeType as a string.
+  static std::string AddressChangeTypeToString(AddressChangeType type);
+
+  // Returns SentPacketState as a char*.
+  static const char* SentPacketStateToString(SentPacketState state);
+
+  // Returns QuicLongHeaderType as a char*.
+  static const char* QuicLongHeaderTypetoString(QuicLongHeaderType type);
+
+  // Returns AckResult as a char*.
+  static const char* AckResultToString(AckResult result);
+
+  // Determines and returns change type of address change from |old_address| to
+  // |new_address|.
+  static AddressChangeType DetermineAddressChangeType(
+      const QuicSocketAddress& old_address,
+      const QuicSocketAddress& new_address);
+
+  // Returns the opposite Perspective of the |perspective| passed in.
+  static constexpr Perspective InvertPerspective(Perspective perspective) {
+    return perspective == Perspective::IS_CLIENT ? Perspective::IS_SERVER
+                                                 : Perspective::IS_CLIENT;
+  }
+
+  // Returns true if a packet is ackable. A packet is unackable if it can never
+  // be acked. Occurs when a packet is never sent, after it is acknowledged
+  // once, or if it's a crypto packet we never expect to receive an ack for.
+  static bool IsAckable(SentPacketState state);
+
+  // Returns true if frame with |type| is retransmittable. A retransmittable
+  // frame should be retransmitted if it is detected as lost.
+  static bool IsRetransmittableFrame(QuicFrameType type);
+
+  // Returns true if |frame| is a handshake frame in version |version|.
+  static bool IsHandshakeFrame(const QuicFrame& frame,
+                               QuicTransportVersion transport_version);
+
+  // Return true if any frame in |frames| is of |type|.
+  static bool ContainsFrameType(const QuicFrames& frames, QuicFrameType type);
+
+  // Returns packet state corresponding to |retransmission_type|.
+  static SentPacketState RetransmissionTypeToPacketState(
+      TransmissionType retransmission_type);
+
+  // Returns true if header with |first_byte| is considered as an IETF QUIC
+  // packet header. This only works on the server.
+  static bool IsIetfPacketHeader(uint8_t first_byte);
+
+  // Returns true if header with |first_byte| is considered as an IETF QUIC
+  // short packet header.
+  static bool IsIetfPacketShortHeader(uint8_t first_byte);
+
+  // Returns ID to denote an invalid stream of |version|.
+  static QuicStreamId GetInvalidStreamId(QuicTransportVersion version);
+
+  // Returns crypto stream ID of |version|.
+  static QuicStreamId GetCryptoStreamId(QuicTransportVersion version);
+
+  // Returns whether |id| is the stream ID for the crypto stream. If |version|
+  // is a version where crypto data doesn't go over stream frames, this function
+  // will always return false.
+  static bool IsCryptoStreamId(QuicTransportVersion version, QuicStreamId id);
+
+  // Returns headers stream ID of |version|.
+  static QuicStreamId GetHeadersStreamId(QuicTransportVersion version);
+
+  // Returns true if |id| is considered as client initiated stream ID.
+  static bool IsClientInitiatedStreamId(QuicTransportVersion version,
+                                        QuicStreamId id);
+
+  // Returns true if |id| is considered as server initiated stream ID.
+  static bool IsServerInitiatedStreamId(QuicTransportVersion version,
+                                        QuicStreamId id);
+
+  // Returns true if the stream ID represents a stream initiated by the
+  // provided perspective.
+  static bool IsOutgoingStreamId(ParsedQuicVersion version,
+                                 QuicStreamId id,
+                                 Perspective perspective);
+
+  // Returns true if |id| is considered as bidirectional stream ID. Only used in
+  // v99.
+  static bool IsBidirectionalStreamId(QuicStreamId id,
+                                      ParsedQuicVersion version);
+
+  // Returns stream type.  Either |perspective| or |peer_initiated| would be
+  // enough together with |id|.  This method enforces that the three parameters
+  // are consistent.  Only used in v99.
+  static StreamType GetStreamType(QuicStreamId id,
+                                  Perspective perspective,
+                                  bool peer_initiated,
+                                  ParsedQuicVersion version);
+
+  // Returns the delta between consecutive stream IDs of the same type.
+  static QuicStreamId StreamIdDelta(QuicTransportVersion version);
+
+  // Returns the first initiated bidirectional stream ID of |perspective|.
+  static QuicStreamId GetFirstBidirectionalStreamId(
+      QuicTransportVersion version,
+      Perspective perspective);
+
+  // Returns the first initiated unidirectional stream ID of |perspective|.
+  static QuicStreamId GetFirstUnidirectionalStreamId(
+      QuicTransportVersion version,
+      Perspective perspective);
+
+  // Returns the largest possible client initiated bidirectional stream ID.
+  static QuicStreamId GetMaxClientInitiatedBidirectionalStreamId(
+      QuicTransportVersion version);
+
+  // Generates a connection ID of length |expected_connection_id_length|
+  // derived from |connection_id|.
+  // This is guaranteed to be deterministic (calling this method with two
+  // connection IDs that are equal is guaranteed to produce the same result).
+  static QuicConnectionId CreateReplacementConnectionId(
+      const QuicConnectionId& connection_id,
+      uint8_t expected_connection_id_length);
+
+  // Generates a 64bit connection ID derived from |connection_id|.
+  // This is guaranteed to be deterministic (calling this method with two
+  // connection IDs that are equal is guaranteed to produce the same result).
+  static QuicConnectionId CreateReplacementConnectionId(
+      const QuicConnectionId& connection_id);
+
+  // Generates a random 64bit connection ID.
+  static QuicConnectionId CreateRandomConnectionId();
+
+  // Generates a random 64bit connection ID using the provided QuicRandom.
+  static QuicConnectionId CreateRandomConnectionId(QuicRandom* random);
+
+  // Generates a random connection ID of the given length.
+  static QuicConnectionId CreateRandomConnectionId(
+      uint8_t connection_id_length);
+
+  // Generates a random connection ID of the given length using the provided
+  // QuicRandom.
+  static QuicConnectionId CreateRandomConnectionId(uint8_t connection_id_length,
+                                                   QuicRandom* random);
+
+  // Returns true if the connection ID length is valid for this QUIC version.
+  static bool IsConnectionIdLengthValidForVersion(
+      size_t connection_id_length,
+      QuicTransportVersion transport_version);
+
+  // Returns true if the connection ID is valid for this QUIC version.
+  static bool IsConnectionIdValidForVersion(
+      QuicConnectionId connection_id,
+      QuicTransportVersion transport_version);
+
+  // Returns a connection ID suitable for QUIC use-cases that do not need the
+  // connection ID for multiplexing. If the version allows variable lengths,
+  // a connection of length zero is returned, otherwise 64bits set to zero.
+  static QuicConnectionId CreateZeroConnectionId(QuicTransportVersion version);
+
+  // Generates a 128bit stateless reset token based on a connection ID.
+  static StatelessResetToken GenerateStatelessResetToken(
+      QuicConnectionId connection_id);
+
+  // Determines packet number space from |encryption_level|.
+  static PacketNumberSpace GetPacketNumberSpace(
+      EncryptionLevel encryption_level);
+
+  // Determines encryption level to send packets in |packet_number_space|.
+  static EncryptionLevel GetEncryptionLevel(
+      PacketNumberSpace packet_number_space);
+
+  // Get the maximum value for a V99/IETF QUIC stream count. If a count
+  // exceeds this value, it will result in a stream ID that exceeds the
+  // implementation limit on stream ID size.
+  static QuicStreamCount GetMaxStreamCount();
+
+  // Return true if this frame is an IETF probing frame.
+  static bool IsProbingFrame(QuicFrameType type);
+
+  // Return true if the two stateless reset tokens are equal. Performs the
+  // comparison in constant time.
+  static bool AreStatelessResetTokensEqual(const StatelessResetToken& token1,
+                                           const StatelessResetToken& token2);
+
+  // Return ture if this frame is an ack-eliciting frame.
+  static bool IsAckElicitingFrame(QuicFrameType type);
+};
+
+// Returns true if the specific ID is a valid WebTransport session ID that our
+// implementation can process.
+bool IsValidWebTransportSessionId(WebTransportSessionId id,
+                                  ParsedQuicVersion transport_version);
+
+QuicByteCount MemSliceSpanTotalSize(absl::Span<quiche::QuicheMemSlice> span);
+
+// Computes a SHA-256 hash and returns the raw bytes of the hash.
+QUIC_EXPORT_PRIVATE std::string RawSha256(absl::string_view input);
+
+template <typename Mask>
+class QUIC_EXPORT_PRIVATE BitMask {
+ public:
+  // explicit to prevent (incorrect) usage like "BitMask bitmask = 0;".
+  template <typename... Bits>
+  explicit BitMask(Bits... bits) {
+    mask_ = MakeMask(bits...);
+  }
+
+  BitMask() = default;
+  BitMask(const BitMask& other) = default;
+  BitMask& operator=(const BitMask& other) = default;
+
+  template <typename... Bits>
+  void Set(Bits... bits) {
+    mask_ |= MakeMask(bits...);
+  }
+
+  template <typename Bit>
+  bool IsSet(Bit bit) const {
+    return (MakeMask(bit) & mask_) != 0;
+  }
+
+  void ClearAll() { mask_ = 0; }
+
+  static constexpr size_t NumBits() { return 8 * sizeof(Mask); }
+
+  friend bool operator==(const BitMask& lhs, const BitMask& rhs) {
+    return lhs.mask_ == rhs.mask_;
+  }
+
+  std::string DebugString() const {
+    std::ostringstream oss;
+    oss << "0x" << std::hex << mask_;
+    return oss.str();
+  }
+
+ private:
+  template <typename Bit>
+  static std::enable_if_t<std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
+    using IntType = typename std::underlying_type<Bit>::type;
+    return Mask(1) << static_cast<IntType>(bit);
+  }
+
+  template <typename Bit>
+  static std::enable_if_t<!std::is_enum<Bit>::value, Mask> MakeMask(Bit bit) {
+    return Mask(1) << bit;
+  }
+
+  template <typename Bit, typename... Bits>
+  static Mask MakeMask(Bit first_bit, Bits... other_bits) {
+    return MakeMask(first_bit) | MakeMask(other_bits...);
+  }
+
+  Mask mask_ = 0;
+};
+
+using BitMask64 = BitMask<uint64_t>;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UTILS_H_
diff --git a/quiche/quic/core/quic_utils_test.cc b/quiche/quic/core/quic_utils_test.cc
new file mode 100644
index 0000000..19ce446
--- /dev/null
+++ b/quiche/quic/core/quic_utils_test.cc
@@ -0,0 +1,404 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_utils.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/numeric/int128.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicUtilsTest : public QuicTest {};
+
+TEST_F(QuicUtilsTest, DetermineAddressChangeType) {
+  const std::string kIPv4String1 = "1.2.3.4";
+  const std::string kIPv4String2 = "1.2.3.5";
+  const std::string kIPv4String3 = "1.1.3.5";
+  const std::string kIPv6String1 = "2001:700:300:1800::f";
+  const std::string kIPv6String2 = "2001:700:300:1800:1:1:1:f";
+  QuicSocketAddress old_address;
+  QuicSocketAddress new_address;
+  QuicIpAddress address;
+
+  EXPECT_EQ(NO_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  old_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(NO_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(NO_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  new_address = QuicSocketAddress(address, 5678);
+  EXPECT_EQ(PORT_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  ASSERT_TRUE(address.FromString(kIPv6String1));
+  old_address = QuicSocketAddress(address, 1234);
+  new_address = QuicSocketAddress(address, 5678);
+  EXPECT_EQ(PORT_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  old_address = QuicSocketAddress(address, 1234);
+  ASSERT_TRUE(address.FromString(kIPv6String1));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV4_TO_IPV6_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  old_address = QuicSocketAddress(address, 1234);
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV6_TO_IPV4_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  ASSERT_TRUE(address.FromString(kIPv6String2));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV6_TO_IPV6_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+
+  ASSERT_TRUE(address.FromString(kIPv4String1));
+  old_address = QuicSocketAddress(address, 1234);
+  ASSERT_TRUE(address.FromString(kIPv4String2));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV4_SUBNET_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+  ASSERT_TRUE(address.FromString(kIPv4String3));
+  new_address = QuicSocketAddress(address, 1234);
+  EXPECT_EQ(IPV4_TO_IPV4_CHANGE,
+            QuicUtils::DetermineAddressChangeType(old_address, new_address));
+}
+
+absl::uint128 IncrementalHashReference(const void* data, size_t len) {
+  // The two constants are defined as part of the hash algorithm.
+  // see http://www.isthe.com/chongo/tech/comp/fnv/
+  // hash = 144066263297769815596495629667062367629
+  absl::uint128 hash = absl::MakeUint128(UINT64_C(7809847782465536322),
+                                         UINT64_C(7113472399480571277));
+  // kPrime = 309485009821345068724781371
+  const absl::uint128 kPrime = absl::MakeUint128(16777216, 315);
+  const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
+  for (size_t i = 0; i < len; ++i) {
+    hash = hash ^ absl::MakeUint128(0, octets[i]);
+    hash = hash * kPrime;
+  }
+  return hash;
+}
+
+TEST_F(QuicUtilsTest, ReferenceTest) {
+  std::vector<uint8_t> data(32);
+  for (size_t i = 0; i < data.size(); ++i) {
+    data[i] = i % 255;
+  }
+  EXPECT_EQ(IncrementalHashReference(data.data(), data.size()),
+            QuicUtils::FNV1a_128_Hash(absl::string_view(
+                reinterpret_cast<const char*>(data.data()), data.size())));
+}
+
+TEST_F(QuicUtilsTest, IsUnackable) {
+  for (size_t i = FIRST_PACKET_STATE; i <= LAST_PACKET_STATE; ++i) {
+    if (i == NEVER_SENT || i == ACKED || i == UNACKABLE) {
+      EXPECT_FALSE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
+    } else {
+      EXPECT_TRUE(QuicUtils::IsAckable(static_cast<SentPacketState>(i)));
+    }
+  }
+}
+
+TEST_F(QuicUtilsTest, RetransmissionTypeToPacketState) {
+  for (size_t i = FIRST_TRANSMISSION_TYPE; i <= LAST_TRANSMISSION_TYPE; ++i) {
+    if (i == NOT_RETRANSMISSION) {
+      continue;
+    }
+    SentPacketState state = QuicUtils::RetransmissionTypeToPacketState(
+        static_cast<TransmissionType>(i));
+    if (i == HANDSHAKE_RETRANSMISSION) {
+      EXPECT_EQ(HANDSHAKE_RETRANSMITTED, state);
+    } else if (i == LOSS_RETRANSMISSION) {
+      EXPECT_EQ(LOST, state);
+    } else if (i == ALL_ZERO_RTT_RETRANSMISSION) {
+      EXPECT_EQ(UNACKABLE, state);
+    } else if (i == TLP_RETRANSMISSION) {
+      EXPECT_EQ(TLP_RETRANSMITTED, state);
+    } else if (i == RTO_RETRANSMISSION) {
+      EXPECT_EQ(RTO_RETRANSMITTED, state);
+    } else if (i == PTO_RETRANSMISSION) {
+      EXPECT_EQ(PTO_RETRANSMITTED, state);
+    } else if (i == PROBING_RETRANSMISSION) {
+      EXPECT_EQ(PROBE_RETRANSMITTED, state);
+    } else if (i == PATH_RETRANSMISSION) {
+      EXPECT_EQ(NOT_CONTRIBUTING_RTT, state);
+    } else if (i == ALL_INITIAL_RETRANSMISSION) {
+      EXPECT_EQ(UNACKABLE, state);
+    } else {
+      QUICHE_DCHECK(false)
+          << "No corresponding packet state according to transmission type: "
+          << i;
+    }
+  }
+}
+
+TEST_F(QuicUtilsTest, IsIetfPacketHeader) {
+  // IETF QUIC short header
+  uint8_t first_byte = 0;
+  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_TRUE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+
+  // IETF QUIC long header
+  first_byte |= (FLAGS_LONG_HEADER | FLAGS_DEMULTIPLEXING_BIT);
+  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+
+  // IETF QUIC long header, version negotiation.
+  first_byte = 0;
+  first_byte |= FLAGS_LONG_HEADER;
+  EXPECT_TRUE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+
+  // GQUIC
+  first_byte = 0;
+  first_byte |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
+  EXPECT_FALSE(QuicUtils::IsIetfPacketHeader(first_byte));
+  EXPECT_FALSE(QuicUtils::IsIetfPacketShortHeader(first_byte));
+}
+
+TEST_F(QuicUtilsTest, ReplacementConnectionIdIsDeterministic) {
+  // Verify that two equal connection IDs get the same replacement.
+  QuicConnectionId connection_id64a = TestConnectionId(33);
+  QuicConnectionId connection_id64b = TestConnectionId(33);
+  EXPECT_EQ(connection_id64a, connection_id64b);
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b));
+  QuicConnectionId connection_id72a = TestConnectionIdNineBytesLong(42);
+  QuicConnectionId connection_id72b = TestConnectionIdNineBytesLong(42);
+  EXPECT_EQ(connection_id72a, connection_id72b);
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b));
+  // Test variant with custom length.
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 7),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b, 7));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 9),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b, 9));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 16),
+            QuicUtils::CreateReplacementConnectionId(connection_id64b, 16));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 7),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 7));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 9),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 9));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 16),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 16));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 32),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 32));
+  EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 255),
+            QuicUtils::CreateReplacementConnectionId(connection_id72b, 255));
+}
+
+TEST_F(QuicUtilsTest, ReplacementConnectionIdLengthIsCorrect) {
+  // Verify that all lengths get replaced by kQuicDefaultConnectionIdLength.
+  const char connection_id_bytes[255] = {};
+  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
+    QuicConnectionId connection_id(connection_id_bytes, i);
+    QuicConnectionId replacement_connection_id =
+        QuicUtils::CreateReplacementConnectionId(connection_id);
+    EXPECT_EQ(kQuicDefaultConnectionIdLength,
+              replacement_connection_id.length());
+    // Test variant with custom length.
+    QuicConnectionId replacement_connection_id7 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 7);
+    EXPECT_EQ(7, replacement_connection_id7.length());
+    QuicConnectionId replacement_connection_id9 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 9);
+    EXPECT_EQ(9, replacement_connection_id9.length());
+    QuicConnectionId replacement_connection_id16 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 16);
+    EXPECT_EQ(16, replacement_connection_id16.length());
+    QuicConnectionId replacement_connection_id32 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 32);
+    EXPECT_EQ(32, replacement_connection_id32.length());
+    QuicConnectionId replacement_connection_id255 =
+        QuicUtils::CreateReplacementConnectionId(connection_id, 255);
+    EXPECT_EQ(255, replacement_connection_id255.length());
+  }
+}
+
+TEST_F(QuicUtilsTest, ReplacementConnectionIdHasEntropy) {
+  // Make sure all these test connection IDs have different replacements.
+  for (uint64_t i = 0; i < 256; ++i) {
+    QuicConnectionId connection_id_i = TestConnectionId(i);
+    EXPECT_NE(connection_id_i,
+              QuicUtils::CreateReplacementConnectionId(connection_id_i));
+    for (uint64_t j = i + 1; j <= 256; ++j) {
+      QuicConnectionId connection_id_j = TestConnectionId(j);
+      EXPECT_NE(connection_id_i, connection_id_j);
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j));
+      // Test variant with custom length.
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 7),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 7));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 9),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 9));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 16),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 16));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 32),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 32));
+      EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 255),
+                QuicUtils::CreateReplacementConnectionId(connection_id_j, 255));
+    }
+  }
+}
+
+TEST_F(QuicUtilsTest, RandomConnectionId) {
+  MockRandom random(33);
+  QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(&random);
+  EXPECT_EQ(connection_id.length(), sizeof(uint64_t));
+  char connection_id_bytes[sizeof(uint64_t)];
+  random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
+  EXPECT_EQ(connection_id,
+            QuicConnectionId(static_cast<char*>(connection_id_bytes),
+                             ABSL_ARRAYSIZE(connection_id_bytes)));
+  EXPECT_NE(connection_id, EmptyQuicConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId(1));
+  EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
+  EXPECT_EQ(QuicUtils::CreateRandomConnectionId().length(),
+            kQuicDefaultConnectionIdLength);
+}
+
+TEST_F(QuicUtilsTest, RandomConnectionIdVariableLength) {
+  MockRandom random(1337);
+  const uint8_t connection_id_length = 9;
+  QuicConnectionId connection_id =
+      QuicUtils::CreateRandomConnectionId(connection_id_length, &random);
+  EXPECT_EQ(connection_id.length(), connection_id_length);
+  char connection_id_bytes[connection_id_length];
+  random.RandBytes(connection_id_bytes, ABSL_ARRAYSIZE(connection_id_bytes));
+  EXPECT_EQ(connection_id,
+            QuicConnectionId(static_cast<char*>(connection_id_bytes),
+                             ABSL_ARRAYSIZE(connection_id_bytes)));
+  EXPECT_NE(connection_id, EmptyQuicConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId());
+  EXPECT_NE(connection_id, TestConnectionId(1));
+  EXPECT_NE(connection_id, TestConnectionIdNineBytesLong(1));
+  EXPECT_EQ(QuicUtils::CreateRandomConnectionId(connection_id_length).length(),
+            connection_id_length);
+}
+
+TEST_F(QuicUtilsTest, VariableLengthConnectionId) {
+  EXPECT_FALSE(VersionAllowsVariableLengthConnectionIds(QUIC_VERSION_43));
+  EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
+      QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43), QUIC_VERSION_43));
+  EXPECT_TRUE(QuicUtils::IsConnectionIdValidForVersion(
+      QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50), QUIC_VERSION_50));
+  EXPECT_NE(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_43),
+            EmptyQuicConnectionId());
+  EXPECT_EQ(QuicUtils::CreateZeroConnectionId(QUIC_VERSION_50),
+            EmptyQuicConnectionId());
+  EXPECT_FALSE(QuicUtils::IsConnectionIdValidForVersion(EmptyQuicConnectionId(),
+                                                        QUIC_VERSION_43));
+}
+
+TEST_F(QuicUtilsTest, StatelessResetToken) {
+  QuicConnectionId connection_id1a = test::TestConnectionId(1);
+  QuicConnectionId connection_id1b = test::TestConnectionId(1);
+  QuicConnectionId connection_id2 = test::TestConnectionId(2);
+  StatelessResetToken token1a =
+      QuicUtils::GenerateStatelessResetToken(connection_id1a);
+  StatelessResetToken token1b =
+      QuicUtils::GenerateStatelessResetToken(connection_id1b);
+  StatelessResetToken token2 =
+      QuicUtils::GenerateStatelessResetToken(connection_id2);
+  EXPECT_EQ(token1a, token1b);
+  EXPECT_NE(token1a, token2);
+  EXPECT_TRUE(QuicUtils::AreStatelessResetTokensEqual(token1a, token1b));
+  EXPECT_FALSE(QuicUtils::AreStatelessResetTokensEqual(token1a, token2));
+}
+
+enum class TestEnumClassBit : uint8_t {
+  BIT_ZERO = 0,
+  BIT_ONE,
+  BIT_TWO,
+};
+
+enum TestEnumBit {
+  TEST_BIT_0 = 0,
+  TEST_BIT_1,
+  TEST_BIT_2,
+};
+
+TEST(QuicBitMaskTest, EnumClass) {
+  BitMask64 mask(TestEnumClassBit::BIT_ZERO, TestEnumClassBit::BIT_TWO);
+  EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
+  EXPECT_TRUE(mask.IsSet(TestEnumClassBit::BIT_TWO));
+
+  mask.ClearAll();
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ZERO));
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_ONE));
+  EXPECT_FALSE(mask.IsSet(TestEnumClassBit::BIT_TWO));
+}
+
+TEST(QuicBitMaskTest, Enum) {
+  BitMask64 mask(TEST_BIT_1, TEST_BIT_2);
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
+  EXPECT_TRUE(mask.IsSet(TEST_BIT_1));
+  EXPECT_TRUE(mask.IsSet(TEST_BIT_2));
+
+  mask.ClearAll();
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_0));
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_1));
+  EXPECT_FALSE(mask.IsSet(TEST_BIT_2));
+}
+
+TEST(QuicBitMaskTest, Integer) {
+  BitMask64 mask(1, 3);
+  mask.Set(3);
+  mask.Set(5, 7, 9);
+  EXPECT_FALSE(mask.IsSet(0));
+  EXPECT_TRUE(mask.IsSet(1));
+  EXPECT_FALSE(mask.IsSet(2));
+  EXPECT_TRUE(mask.IsSet(3));
+  EXPECT_FALSE(mask.IsSet(4));
+  EXPECT_TRUE(mask.IsSet(5));
+  EXPECT_FALSE(mask.IsSet(6));
+  EXPECT_TRUE(mask.IsSet(7));
+  EXPECT_FALSE(mask.IsSet(8));
+  EXPECT_TRUE(mask.IsSet(9));
+}
+
+TEST(QuicBitMaskTest, NumBits) {
+  EXPECT_EQ(64u, BitMask64::NumBits());
+  EXPECT_EQ(32u, BitMask<uint32_t>::NumBits());
+}
+
+TEST(QuicBitMaskTest, Constructor) {
+  BitMask64 empty_mask;
+  for (size_t bit = 0; bit < empty_mask.NumBits(); ++bit) {
+    EXPECT_FALSE(empty_mask.IsSet(bit));
+  }
+
+  BitMask64 mask(1, 3);
+  BitMask64 mask2 = mask;
+  BitMask64 mask3(mask2);
+
+  for (size_t bit = 0; bit < mask.NumBits(); ++bit) {
+    EXPECT_EQ(mask.IsSet(bit), mask2.IsSet(bit));
+    EXPECT_EQ(mask.IsSet(bit), mask3.IsSet(bit));
+  }
+
+  EXPECT_TRUE(std::is_trivially_copyable<BitMask64>::value);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_version_manager.cc b/quiche/quic/core/quic_version_manager.cc
new file mode 100644
index 0000000..2c88477
--- /dev/null
+++ b/quiche/quic/core/quic_version_manager.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_version_manager.h"
+
+#include <algorithm>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicVersionManager::QuicVersionManager(
+    ParsedQuicVersionVector supported_versions)
+    : allowed_supported_versions_(std::move(supported_versions)) {}
+
+QuicVersionManager::~QuicVersionManager() {}
+
+const ParsedQuicVersionVector& QuicVersionManager::GetSupportedVersions() {
+  MaybeRefilterSupportedVersions();
+  return filtered_supported_versions_;
+}
+
+const ParsedQuicVersionVector&
+QuicVersionManager::GetSupportedVersionsWithOnlyHttp3() {
+  MaybeRefilterSupportedVersions();
+  return filtered_supported_versions_with_http3_;
+}
+
+const std::vector<std::string>& QuicVersionManager::GetSupportedAlpns() {
+  MaybeRefilterSupportedVersions();
+  return filtered_supported_alpns_;
+}
+
+void QuicVersionManager::MaybeRefilterSupportedVersions() {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  if (enable_version_2_draft_01_ !=
+          GetQuicReloadableFlag(quic_enable_version_2_draft_01) ||
+      disable_version_rfcv1_ !=
+          GetQuicReloadableFlag(quic_disable_version_rfcv1) ||
+      disable_version_draft_29_ !=
+          GetQuicReloadableFlag(quic_disable_version_draft_29) ||
+      disable_version_q050_ !=
+          GetQuicReloadableFlag(quic_disable_version_q050) ||
+      disable_version_q046_ !=
+          GetQuicReloadableFlag(quic_disable_version_q046) ||
+      disable_version_q043_ !=
+          GetQuicReloadableFlag(quic_disable_version_q043)) {
+    enable_version_2_draft_01_ =
+        GetQuicReloadableFlag(quic_enable_version_2_draft_01);
+    disable_version_rfcv1_ = GetQuicReloadableFlag(quic_disable_version_rfcv1);
+    disable_version_draft_29_ =
+        GetQuicReloadableFlag(quic_disable_version_draft_29);
+    disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
+    disable_version_q046_ = GetQuicReloadableFlag(quic_disable_version_q046);
+    disable_version_q043_ = GetQuicReloadableFlag(quic_disable_version_q043);
+
+    RefilterSupportedVersions();
+  }
+}
+
+void QuicVersionManager::RefilterSupportedVersions() {
+  filtered_supported_versions_ =
+      FilterSupportedVersions(allowed_supported_versions_);
+  filtered_supported_versions_with_http3_.clear();
+  filtered_transport_versions_.clear();
+  filtered_supported_alpns_.clear();
+  for (const ParsedQuicVersion& version : filtered_supported_versions_) {
+    auto transport_version = version.transport_version;
+    if (std::find(filtered_transport_versions_.begin(),
+                  filtered_transport_versions_.end(),
+                  transport_version) == filtered_transport_versions_.end()) {
+      filtered_transport_versions_.push_back(transport_version);
+    }
+    if (version.UsesHttp3()) {
+      filtered_supported_versions_with_http3_.push_back(version);
+    }
+    if (std::find(filtered_supported_alpns_.begin(),
+                  filtered_supported_alpns_.end(),
+                  AlpnForVersion(version)) == filtered_supported_alpns_.end()) {
+      filtered_supported_alpns_.emplace_back(AlpnForVersion(version));
+    }
+  }
+}
+
+void QuicVersionManager::AddCustomAlpn(const std::string& alpn) {
+  filtered_supported_alpns_.push_back(alpn);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_version_manager.h b/quiche/quic/core/quic_version_manager.h
new file mode 100644
index 0000000..ddabd1c
--- /dev/null
+++ b/quiche/quic/core/quic_version_manager.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
+
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Used to generate filtered supported versions based on flags.
+class QUIC_EXPORT_PRIVATE QuicVersionManager {
+ public:
+  // |supported_versions| should be sorted in the order of preference (typically
+  // highest supported version to the lowest supported version).
+  explicit QuicVersionManager(ParsedQuicVersionVector supported_versions);
+  virtual ~QuicVersionManager();
+
+  // Returns currently supported QUIC versions. This vector has the same order
+  // as the versions passed to the constructor.
+  const ParsedQuicVersionVector& GetSupportedVersions();
+
+  // Returns currently supported versions using HTTP/3.
+  const ParsedQuicVersionVector& GetSupportedVersionsWithOnlyHttp3();
+
+  // Returns the list of supported ALPNs, based on the current supported
+  // versions and any custom additions by subclasses.
+  const std::vector<std::string>& GetSupportedAlpns();
+
+ protected:
+  // If the value of any reloadable flag is different from the cached value,
+  // re-filter |filtered_supported_versions_| and update the cached flag values.
+  // Otherwise, does nothing.
+  // TODO(dschinazi): Make private when deprecating
+  // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
+  void MaybeRefilterSupportedVersions();
+
+  // Refilters filtered_supported_versions_.
+  virtual void RefilterSupportedVersions();
+
+  // RefilterSupportedVersions() must be called before calling this method.
+  // TODO(dschinazi): Remove when deprecating
+  // FLAGS_gfe2_restart_flag_quic_disable_old_alt_svc_format.
+  const QuicTransportVersionVector& filtered_transport_versions() const {
+    return filtered_transport_versions_;
+  }
+
+  // Subclasses may add custom ALPNs to the supported list by overriding
+  // RefilterSupportedVersions() to first call
+  // QuicVersionManager::RefilterSupportedVersions() then AddCustomAlpn().
+  // Must not be called elsewhere.
+  void AddCustomAlpn(const std::string& alpn);
+
+ private:
+  // Cached value of reloadable flags.
+  // quic_enable_version_2_draft_01 flag
+  bool enable_version_2_draft_01_ = false;
+  // quic_disable_version_rfcv1 flag
+  bool disable_version_rfcv1_ = true;
+  // quic_disable_version_draft_29 flag
+  bool disable_version_draft_29_ = true;
+  // quic_disable_version_q050 flag
+  bool disable_version_q050_ = true;
+  // quic_disable_version_q046 flag
+  bool disable_version_q046_ = true;
+  // quic_disable_version_q043 flag
+  bool disable_version_q043_ = true;
+
+  // The list of versions that may be supported.
+  const ParsedQuicVersionVector allowed_supported_versions_;
+
+  // The following vectors are calculated from reloadable flags by
+  // RefilterSupportedVersions().  It is performed lazily when first needed, and
+  // after that, since the calculation is relatively expensive, only if the flag
+  // values change.
+
+  // This vector contains QUIC versions which are currently supported based on
+  // flags.
+  ParsedQuicVersionVector filtered_supported_versions_;
+  // Currently supported versions using HTTP/3.
+  ParsedQuicVersionVector filtered_supported_versions_with_http3_;
+  // This vector contains the transport versions from
+  // |filtered_supported_versions_|. No guarantees are made that the same
+  // transport version isn't repeated.
+  QuicTransportVersionVector filtered_transport_versions_;
+  // Contains the list of ALPNs corresponding to filtered_supported_versions_
+  // with custom ALPNs added.
+  std::vector<std::string> filtered_supported_alpns_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_VERSION_MANAGER_H_
diff --git a/quiche/quic/core/quic_version_manager_test.cc b/quiche/quic/core/quic_version_manager_test.cc
new file mode 100644
index 0000000..8ef018a
--- /dev/null
+++ b/quiche/quic/core/quic_version_manager_test.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_version_manager.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+using ::testing::ElementsAre;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicVersionManagerTest : public QuicTest {};
+
+TEST_F(QuicVersionManagerTest, QuicVersionManager) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicEnableVersion(version);
+  }
+  QuicDisableVersion(ParsedQuicVersion::V2Draft01());
+  QuicDisableVersion(ParsedQuicVersion::RFCv1());
+  QuicDisableVersion(ParsedQuicVersion::Draft29());
+  QuicVersionManager manager(AllSupportedVersions());
+
+  ParsedQuicVersionVector expected_parsed_versions;
+  expected_parsed_versions.push_back(ParsedQuicVersion::Q050());
+  expected_parsed_versions.push_back(ParsedQuicVersion::Q046());
+  expected_parsed_versions.push_back(ParsedQuicVersion::Q043());
+
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_TRUE(manager.GetSupportedVersionsWithOnlyHttp3().empty());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3-Q050", "h3-Q046", "h3-Q043"));
+
+  QuicEnableVersion(ParsedQuicVersion::Draft29());
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::Draft29());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(1u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+  EXPECT_EQ(CurrentSupportedHttp3Versions(),
+            manager.GetSupportedVersionsWithOnlyHttp3());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+
+  QuicEnableVersion(ParsedQuicVersion::RFCv1());
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::RFCv1());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(2u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+  EXPECT_EQ(CurrentSupportedHttp3Versions(),
+            manager.GetSupportedVersionsWithOnlyHttp3());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+
+  QuicEnableVersion(ParsedQuicVersion::V2Draft01());
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::V2Draft01());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(3u, manager.GetSupportedVersionsWithOnlyHttp3().size());
+  EXPECT_EQ(CurrentSupportedHttp3Versions(),
+            manager.GetSupportedVersionsWithOnlyHttp3());
+  EXPECT_THAT(
+      manager.GetSupportedAlpns(),
+      ElementsAre("h3", "h3-29", "h3-Q050", "h3-Q046", "h3-Q043"));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_versions.cc b/quiche/quic/core/quic_versions.cc
new file mode 100644
index 0000000..df43ce7
--- /dev/null
+++ b/quiche/quic/core/quic_versions.cc
@@ -0,0 +1,667 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_versions.h"
+
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
+  QuicVersionLabel result;
+  if (!GetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness)) {
+    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
+  } else {
+    result = MakeVersionLabel(0xd1, 0x57, 0x38, 0x3f);
+  }
+  result &= 0xf0f0f0f0;
+  result |= 0x0a0a0a0a;
+  return result;
+}
+
+void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  const bool enable = should_enable;
+  const bool disable = !should_enable;
+  if (version == ParsedQuicVersion::V2Draft01()) {
+    SetQuicReloadableFlag(quic_enable_version_2_draft_01, enable);
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    SetQuicReloadableFlag(quic_disable_version_rfcv1, disable);
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    SetQuicReloadableFlag(quic_disable_version_draft_29, disable);
+  } else if (version == ParsedQuicVersion::Q050()) {
+    SetQuicReloadableFlag(quic_disable_version_q050, disable);
+  } else if (version == ParsedQuicVersion::Q046()) {
+    SetQuicReloadableFlag(quic_disable_version_q046, disable);
+  } else if (version == ParsedQuicVersion::Q043()) {
+    SetQuicReloadableFlag(quic_disable_version_q043, disable);
+  } else {
+    QUIC_BUG(quic_bug_10589_1)
+        << "Cannot " << (enable ? "en" : "dis") << "able version " << version;
+  }
+}
+
+}  // namespace
+
+bool ParsedQuicVersion::IsKnown() const {
+  QUICHE_DCHECK(ParsedQuicVersionIsValid(handshake_protocol, transport_version))
+      << QuicVersionToString(transport_version) << " "
+      << HandshakeProtocolToString(handshake_protocol);
+  return transport_version != QUIC_VERSION_UNSUPPORTED;
+}
+
+bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::UsesInitialObfuscators() const {
+  QUICHE_DCHECK(IsKnown());
+  // Initial obfuscators were added in version 50.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
+  QUICHE_DCHECK(IsKnown());
+  // Low flow-control limits are used for all IETF versions.
+  return UsesHttp3();
+}
+
+bool ParsedQuicVersion::HasHeaderProtection() const {
+  QUICHE_DCHECK(IsKnown());
+  // Header protection was added in version 50.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::SupportsRetry() const {
+  QUICHE_DCHECK(IsKnown());
+  // Retry was added in version 47.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::SendsVariableLengthPacketNumberInLongHeader() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::AllowsVariableLengthConnectionIds() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionAllowsVariableLengthConnectionIds(transport_version);
+}
+
+bool ParsedQuicVersion::SupportsClientConnectionIds() const {
+  QUICHE_DCHECK(IsKnown());
+  // Client connection IDs were added in version 49.
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionHasLengthPrefixedConnectionIds(transport_version);
+}
+
+bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
+  QUICHE_DCHECK(IsKnown());
+  // The anti-amplification limit is used for all IETF versions.
+  return UsesHttp3();
+}
+
+bool ParsedQuicVersion::CanSendCoalescedPackets() const {
+  QUICHE_DCHECK(IsKnown());
+  return HasLongHeaderLengths() && UsesTls();
+}
+
+bool ParsedQuicVersion::SupportsGoogleAltSvcFormat() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionSupportsGoogleAltSvcFormat(transport_version);
+}
+
+bool ParsedQuicVersion::HasIetfInvariantHeader() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionHasIetfInvariantHeader(transport_version);
+}
+
+bool ParsedQuicVersion::SupportsMessageFrames() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionSupportsMessageFrames(transport_version);
+}
+
+bool ParsedQuicVersion::UsesHttp3() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionUsesHttp3(transport_version);
+}
+
+bool ParsedQuicVersion::HasLongHeaderLengths() const {
+  QUICHE_DCHECK(IsKnown());
+  return QuicVersionHasLongHeaderLengths(transport_version);
+}
+
+bool ParsedQuicVersion::UsesCryptoFrames() const {
+  QUICHE_DCHECK(IsKnown());
+  return QuicVersionUsesCryptoFrames(transport_version);
+}
+
+bool ParsedQuicVersion::HasIetfQuicFrames() const {
+  QUICHE_DCHECK(IsKnown());
+  return VersionHasIetfQuicFrames(transport_version);
+}
+
+bool ParsedQuicVersion::UsesLegacyTlsExtension() const {
+  QUICHE_DCHECK(IsKnown());
+  return UsesTls() && transport_version <= QUIC_VERSION_IETF_DRAFT_29;
+}
+
+bool ParsedQuicVersion::UsesTls() const {
+  QUICHE_DCHECK(IsKnown());
+  return handshake_protocol == PROTOCOL_TLS1_3;
+}
+
+bool ParsedQuicVersion::UsesQuicCrypto() const {
+  QUICHE_DCHECK(IsKnown());
+  return handshake_protocol == PROTOCOL_QUIC_CRYPTO;
+}
+
+bool ParsedQuicVersion::UsesV2PacketTypes() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
+bool ParsedQuicVersion::AlpnDeferToRFCv1() const {
+  QUICHE_DCHECK(IsKnown());
+  return transport_version == QUIC_VERSION_IETF_2_DRAFT_01;
+}
+
+bool VersionHasLengthPrefixedConnectionIds(
+    QuicTransportVersion transport_version) {
+  QUICHE_DCHECK(transport_version != QUIC_VERSION_UNSUPPORTED);
+  // Length-prefixed connection IDs were added in version 49.
+  return transport_version > QUIC_VERSION_46;
+}
+
+std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
+  os << ParsedQuicVersionToString(version);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const ParsedQuicVersionVector& versions) {
+  os << ParsedQuicVersionVectorToString(versions);
+  return os;
+}
+
+QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+  return MakeQuicTag(d, c, b, a);
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicVersionLabelVector& version_labels) {
+  os << QuicVersionLabelVectorToString(version_labels);
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const QuicTransportVersionVector& transport_versions) {
+  os << QuicTransportVersionVectorToString(transport_versions);
+  return os;
+}
+
+QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+    return MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4);
+  } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
+    return MakeVersionLabel(0x00, 0x00, 0x00, 0x01);
+  } else if (parsed_version == ParsedQuicVersion::Draft29()) {
+    return MakeVersionLabel(0xff, 0x00, 0x00, 29);
+  } else if (parsed_version == ParsedQuicVersion::Q050()) {
+    return MakeVersionLabel('Q', '0', '5', '0');
+  } else if (parsed_version == ParsedQuicVersion::Q046()) {
+    return MakeVersionLabel('Q', '0', '4', '6');
+  } else if (parsed_version == ParsedQuicVersion::Q043()) {
+    return MakeVersionLabel('Q', '0', '4', '3');
+  } else if (parsed_version == ParsedQuicVersion::ReservedForNegotiation()) {
+    return CreateRandomVersionLabelForNegotiation();
+  }
+  QUIC_BUG(quic_bug_10589_2)
+      << "Unsupported version "
+      << QuicVersionToString(parsed_version.transport_version) << " "
+      << HandshakeProtocolToString(parsed_version.handshake_protocol);
+  return 0;
+}
+
+QuicVersionLabelVector CreateQuicVersionLabelVector(
+    const ParsedQuicVersionVector& versions) {
+  QuicVersionLabelVector out;
+  out.reserve(versions.size());
+  for (const auto& version : versions) {
+    out.push_back(CreateQuicVersionLabel(version));
+  }
+  return out;
+}
+
+ParsedQuicVersionVector AllSupportedVersionsWithQuicCrypto() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_3, versions.empty())
+      << "No version with QUIC crypto found.";
+  return versions;
+}
+
+ParsedQuicVersionVector CurrentSupportedVersionsWithQuicCrypto() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_4, versions.empty())
+      << "No version with QUIC crypto found.";
+  return versions;
+}
+
+ParsedQuicVersionVector AllSupportedVersionsWithTls() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.UsesTls()) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_5, versions.empty())
+      << "No version with TLS handshake found.";
+  return versions;
+}
+
+ParsedQuicVersionVector CurrentSupportedVersionsWithTls() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+    if (version.UsesTls()) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(quic_bug_10589_6, versions.empty())
+      << "No version with TLS handshake found.";
+  return versions;
+}
+
+ParsedQuicVersionVector CurrentSupportedHttp3Versions() {
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+    if (version.UsesHttp3()) {
+      versions.push_back(version);
+    }
+  }
+  QUIC_BUG_IF(no_version_uses_http3, versions.empty())
+      << "No version speaking Http3 found.";
+  return versions;
+}
+
+ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version_label == CreateQuicVersionLabel(version)) {
+      return version;
+    }
+  }
+  // Reading from the client so this should not be considered an ERROR.
+  QUIC_DLOG(INFO) << "Unsupported QuicVersionLabel version: "
+                  << QuicVersionLabelToString(version_label);
+  return UnsupportedQuicVersion();
+}
+
+ParsedQuicVersionVector ParseQuicVersionLabelVector(
+    const QuicVersionLabelVector& version_labels) {
+  ParsedQuicVersionVector parsed_versions;
+  for (const QuicVersionLabel& version_label : version_labels) {
+    ParsedQuicVersion parsed_version = ParseQuicVersionLabel(version_label);
+    if (parsed_version.IsKnown()) {
+      parsed_versions.push_back(parsed_version);
+    }
+  }
+  return parsed_versions;
+}
+
+ParsedQuicVersion ParseQuicVersionString(absl::string_view version_string) {
+  if (version_string.empty()) {
+    return UnsupportedQuicVersion();
+  }
+  const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version_string == ParsedQuicVersionToString(version) ||
+        (version_string == AlpnForVersion(version) &&
+         !version.AlpnDeferToRFCv1()) ||
+        (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
+         version_string == QuicVersionToString(version.transport_version))) {
+      return version;
+    }
+  }
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version.UsesHttp3() &&
+        version_string ==
+            QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
+      return version;
+    }
+  }
+  int quic_version_number = 0;
+  if (absl::SimpleAtoi(version_string, &quic_version_number) &&
+      quic_version_number > 0) {
+    QuicTransportVersion transport_version =
+        static_cast<QuicTransportVersion>(quic_version_number);
+    if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
+      return UnsupportedQuicVersion();
+    }
+    ParsedQuicVersion version(PROTOCOL_QUIC_CRYPTO, transport_version);
+    if (std::find(supported_versions.begin(), supported_versions.end(),
+                  version) != supported_versions.end()) {
+      return version;
+    }
+    return UnsupportedQuicVersion();
+  }
+  // Reading from the client so this should not be considered an ERROR.
+  QUIC_DLOG(INFO) << "Unsupported QUIC version string: \"" << version_string
+                  << "\".";
+  return UnsupportedQuicVersion();
+}
+
+ParsedQuicVersionVector ParseQuicVersionVectorString(
+    absl::string_view versions_string) {
+  ParsedQuicVersionVector versions;
+  std::vector<absl::string_view> version_strings =
+      absl::StrSplit(versions_string, ',');
+  for (absl::string_view version_string : version_strings) {
+    quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
+        &version_string);
+    ParsedQuicVersion version = ParseQuicVersionString(version_string);
+    if (!version.IsKnown() || std::find(versions.begin(), versions.end(),
+                                        version) != versions.end()) {
+      continue;
+    }
+    versions.push_back(version);
+  }
+  return versions;
+}
+
+QuicTransportVersionVector AllSupportedTransportVersions() {
+  QuicTransportVersionVector transport_versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (std::find(transport_versions.begin(), transport_versions.end(),
+                  version.transport_version) == transport_versions.end()) {
+      transport_versions.push_back(version.transport_version);
+    }
+  }
+  return transport_versions;
+}
+
+ParsedQuicVersionVector AllSupportedVersions() {
+  constexpr auto supported_versions = SupportedVersions();
+  return ParsedQuicVersionVector(supported_versions.begin(),
+                                 supported_versions.end());
+}
+
+ParsedQuicVersionVector CurrentSupportedVersions() {
+  return FilterSupportedVersions(AllSupportedVersions());
+}
+
+ParsedQuicVersionVector FilterSupportedVersions(
+    ParsedQuicVersionVector versions) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  ParsedQuicVersionVector filtered_versions;
+  filtered_versions.reserve(versions.size());
+  for (const ParsedQuicVersion& version : versions) {
+    if (version == ParsedQuicVersion::V2Draft01()) {
+      if (GetQuicReloadableFlag(quic_enable_version_2_draft_01)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::RFCv1()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_rfcv1)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Draft29()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_draft_29)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Q050()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_q050)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Q046()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version == ParsedQuicVersion::Q043()) {
+      if (!GetQuicReloadableFlag(quic_disable_version_q043)) {
+        filtered_versions.push_back(version);
+      }
+    } else {
+      QUIC_BUG(quic_bug_10589_7)
+          << "QUIC version " << version << " has no flag protection";
+      filtered_versions.push_back(version);
+    }
+  }
+  return filtered_versions;
+}
+
+ParsedQuicVersionVector ParsedVersionOfIndex(
+    const ParsedQuicVersionVector& versions, int index) {
+  ParsedQuicVersionVector version;
+  int version_count = versions.size();
+  if (index >= 0 && index < version_count) {
+    version.push_back(versions[index]);
+  } else {
+    version.push_back(UnsupportedQuicVersion());
+  }
+  return version;
+}
+
+std::string QuicVersionLabelToString(QuicVersionLabel version_label) {
+  return QuicTagToString(quiche::QuicheEndian::HostToNet32(version_label));
+}
+
+ParsedQuicVersion ParseQuicVersionLabelString(
+    absl::string_view version_label_string) {
+  const ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+  for (const ParsedQuicVersion& version : supported_versions) {
+    if (version_label_string ==
+        QuicVersionLabelToString(CreateQuicVersionLabel(version))) {
+      return version;
+    }
+  }
+  return UnsupportedQuicVersion();
+}
+
+std::string QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels, const std::string& separator,
+    size_t skip_after_nth_version) {
+  std::string result;
+  for (size_t i = 0; i < version_labels.size(); ++i) {
+    if (i != 0) {
+      result.append(separator);
+    }
+
+    if (i > skip_after_nth_version) {
+      result.append("...");
+      break;
+    }
+    result.append(QuicVersionLabelToString(version_labels[i]));
+  }
+  return result;
+}
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x
+
+std::string QuicVersionToString(QuicTransportVersion transport_version) {
+  switch (transport_version) {
+    RETURN_STRING_LITERAL(QUIC_VERSION_43);
+    RETURN_STRING_LITERAL(QUIC_VERSION_46);
+    RETURN_STRING_LITERAL(QUIC_VERSION_50);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_RFC_V1);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_2_DRAFT_01);
+    RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
+    RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
+  }
+  return absl::StrCat("QUIC_VERSION_UNKNOWN(",
+                      static_cast<int>(transport_version), ")");
+}
+
+std::string HandshakeProtocolToString(HandshakeProtocol handshake_protocol) {
+  switch (handshake_protocol) {
+    RETURN_STRING_LITERAL(PROTOCOL_UNSUPPORTED);
+    RETURN_STRING_LITERAL(PROTOCOL_QUIC_CRYPTO);
+    RETURN_STRING_LITERAL(PROTOCOL_TLS1_3);
+  }
+  return absl::StrCat("PROTOCOL_UNKNOWN(", static_cast<int>(handshake_protocol),
+                      ")");
+}
+
+std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  if (version == UnsupportedQuicVersion()) {
+    return "0";
+  } else if (version == ParsedQuicVersion::V2Draft01()) {
+    QUICHE_DCHECK(version.UsesHttp3());
+    return "v2draft01";
+  } else if (version == ParsedQuicVersion::RFCv1()) {
+    QUICHE_DCHECK(version.UsesHttp3());
+    return "RFCv1";
+  } else if (version == ParsedQuicVersion::Draft29()) {
+    QUICHE_DCHECK(version.UsesHttp3());
+    return "draft29";
+  }
+
+  return QuicVersionLabelToString(CreateQuicVersionLabel(version));
+}
+
+std::string QuicTransportVersionVectorToString(
+    const QuicTransportVersionVector& versions) {
+  std::string result = "";
+  for (size_t i = 0; i < versions.size(); ++i) {
+    if (i != 0) {
+      result.append(",");
+    }
+    result.append(QuicVersionToString(versions[i]));
+  }
+  return result;
+}
+
+std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions, const std::string& separator,
+    size_t skip_after_nth_version) {
+  std::string result;
+  for (size_t i = 0; i < versions.size(); ++i) {
+    if (i != 0) {
+      result.append(separator);
+    }
+    if (i > skip_after_nth_version) {
+      result.append("...");
+      break;
+    }
+    result.append(ParsedQuicVersionToString(versions[i]));
+  }
+  return result;
+}
+
+bool VersionSupportsGoogleAltSvcFormat(QuicTransportVersion transport_version) {
+  return transport_version <= QUIC_VERSION_46;
+}
+
+bool VersionAllowsVariableLengthConnectionIds(
+    QuicTransportVersion transport_version) {
+  QUICHE_DCHECK_NE(transport_version, QUIC_VERSION_UNSUPPORTED);
+  return transport_version > QUIC_VERSION_46;
+}
+
+bool QuicVersionLabelUses4BitConnectionIdLength(
+    QuicVersionLabel version_label) {
+  // As we deprecate old versions, we still need the ability to send valid
+  // version negotiation packets for those versions. This function keeps track
+  // of the versions that ever supported the 4bit connection ID length encoding
+  // that we know about. Google QUIC 43 and earlier used a different encoding,
+  // and Google QUIC 49 and later use the new length prefixed encoding.
+  // Similarly, only IETF drafts 11 to 21 used this encoding.
+
+  // Check Q044, Q045, Q046, Q047 and Q048.
+  for (uint8_t c = '4'; c <= '8'; ++c) {
+    if (version_label == MakeVersionLabel('Q', '0', '4', c)) {
+      return true;
+    }
+  }
+  // Check T048.
+  if (version_label == MakeVersionLabel('T', '0', '4', '8')) {
+    return true;
+  }
+  // Check IETF draft versions in [11,21].
+  for (uint8_t draft_number = 11; draft_number <= 21; ++draft_number) {
+    if (version_label == MakeVersionLabel(0xff, 0x00, 0x00, draft_number)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+ParsedQuicVersion UnsupportedQuicVersion() {
+  return ParsedQuicVersion::Unsupported();
+}
+
+ParsedQuicVersion QuicVersionReservedForNegotiation() {
+  return ParsedQuicVersion::ReservedForNegotiation();
+}
+
+ParsedQuicVersion LegacyVersionForEncapsulation() {
+  return ParsedQuicVersion::Q043();
+}
+
+std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
+  if (parsed_version == ParsedQuicVersion::V2Draft01()) {
+    return "h3";
+  } else if (parsed_version == ParsedQuicVersion::RFCv1()) {
+    return "h3";
+  } else if (parsed_version == ParsedQuicVersion::Draft29()) {
+    return "h3-29";
+  }
+  return "h3-" + ParsedQuicVersionToString(parsed_version);
+}
+
+void QuicVersionInitializeSupportForIetfDraft() {
+  // Enable necessary flags.
+}
+
+void QuicEnableVersion(const ParsedQuicVersion& version) {
+  SetVersionFlag(version, /*should_enable=*/true);
+}
+
+void QuicDisableVersion(const ParsedQuicVersion& version) {
+  SetVersionFlag(version, /*should_enable=*/false);
+}
+
+bool QuicVersionIsEnabled(const ParsedQuicVersion& version) {
+  ParsedQuicVersionVector current = CurrentSupportedVersions();
+  return std::find(current.begin(), current.end(), version) != current.end();
+}
+
+#undef RETURN_STRING_LITERAL  // undef for jumbo builds
+}  // namespace quic
diff --git a/quiche/quic/core/quic_versions.h b/quiche/quic/core/quic_versions.h
new file mode 100644
index 0000000..39f8642
--- /dev/null
+++ b/quiche/quic/core/quic_versions.h
@@ -0,0 +1,652 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Definitions and utility functions related to handling of QUIC versions.
+//
+// QUIC versions are encoded over the wire as an opaque 32bit field. The wire
+// encoding is represented in memory as a QuicVersionLabel type (which is an
+// alias to uint32_t). Conceptual versions are represented in memory as
+// ParsedQuicVersion.
+//
+// We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
+//
+// All GoogleQUIC versions use a wire encoding that matches the following regex
+// when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
+// type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
+// handshake), and the two digits at the end contain the numeric value of
+// the transport version used.
+//
+// All IETF QUIC versions use the wire encoding described in:
+// https://tools.ietf.org/html/draft-ietf-quic-transport
+
+#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The list of existing QUIC transport versions. Note that QUIC versions are
+// sent over the wire as an encoding of ParsedQuicVersion, which requires a
+// QUIC transport version and handshake protocol. For transport versions of the
+// form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
+// guaranteed to match the name. Older deprecated transport versions are
+// documented in comments below.
+enum QuicTransportVersion {
+  // Special case to indicate unknown/unsupported QUIC version.
+  QUIC_VERSION_UNSUPPORTED = 0,
+
+  // Version 1 was the first version of QUIC that supported versioning.
+  // Version 2 decoupled versioning of non-cryptographic parameters from the
+  //           SCFG.
+  // Version 3 moved public flags into the beginning of the packet.
+  // Version 4 added support for variable-length connection IDs.
+  // Version 5 made specifying FEC groups optional.
+  // Version 6 introduced variable-length packet numbers.
+  // Version 7 introduced a lower-overhead encoding for stream frames.
+  // Version 8 made salt length equal to digest length for the RSA-PSS
+  //           signatures.
+  // Version 9 added stream priority.
+  // Version 10 redid the frame type numbering.
+  // Version 11 reduced the length of null encryption authentication tag
+  //            from 16 to 12 bytes.
+  // Version 12 made the sequence numbers in the ACK frames variable-sized.
+  // Version 13 added the dedicated header stream.
+  // Version 14 added byte_offset to RST_STREAM frame.
+  // Version 15 added a list of packets recovered using FEC to the ACK frame.
+  // Version 16 added STOP_WAITING frame.
+  // Version 17 added per-stream flow control.
+  // Version 18 added PING frame.
+  // Version 19 added connection-level flow control
+  // Version 20 allowed to set stream- and connection-level flow control windows
+  //            to different values.
+  // Version 21 made header and crypto streams flow-controlled.
+  // Version 22 added support for SCUP (server config update) messages.
+  // Version 23 added timestamps into the ACK frame.
+  // Version 24 added SPDY/4 header compression.
+  // Version 25 added support for SPDY/4 header keys and removed error_details
+  //            from RST_STREAM frame.
+  // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
+  // Version 27 added a nonce into SHLO.
+  // Version 28 allowed receiver to refuse creating a requested stream.
+  // Version 29 added support for QUIC_STREAM_NO_ERROR.
+  // Version 30 added server-side support for certificate transparency.
+  // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
+  //            the server.
+  // Version 32 removed FEC-related fields from wire format.
+  // Version 33 added diversification nonces.
+  // Version 34 removed entropy bits from packets and ACK frames, removed
+  //            private flag from packet header and changed the ACK format to
+  //            specify ranges of packets acknowledged rather than missing
+  //            ranges.
+  // Version 35 allows endpoints to independently set stream limit.
+  // Version 36 added support for forced head-of-line blocking experiments.
+  // Version 37 added perspective into null encryption.
+  // Version 38 switched to IETF padding frame format and support for NSTP (no
+  //            stop waiting frame) connection option.
+
+  // Version 39 writes integers and floating numbers in big endian, stops acking
+  // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do
+  // not contain retransmittable frames.
+
+  // Version 40 was an attempt to convert QUIC to IETF frame format; it was
+  //            never shipped due to a bug.
+  // Version 41 was a bugfix for version 40.  The working group changed the wire
+  //            format before it shipped, which caused it to be never shipped
+  //            and all the changes from it to be reverted.  No changes from v40
+  //            or v41 are present in subsequent versions.
+  // Version 42 allowed receiving overlapping stream data.
+
+  QUIC_VERSION_43 = 43,  // PRIORITY frames are sent by client and accepted by
+                         // server.
+  // Version 44 used IETF header format from draft-ietf-quic-invariants-05.
+
+  // Version 45 added MESSAGE frame.
+
+  QUIC_VERSION_46 = 46,  // Use IETF draft-17 header format with demultiplexing
+                         // bit.
+  // Version 47 added variable-length QUIC server connection IDs.
+  // Version 48 added CRYPTO frames for the handshake.
+  // Version 49 added client connection IDs, long header lengths, and the IETF
+  // header format from draft-ietf-quic-invariants-06
+  QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
+  // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
+  // Number 70 used to represent draft-ietf-quic-transport-25.
+  // Number 71 used to represent draft-ietf-quic-transport-27.
+  // Number 72 used to represent draft-ietf-quic-transport-28.
+  QUIC_VERSION_IETF_DRAFT_29 = 73,    // draft-ietf-quic-transport-29.
+  QUIC_VERSION_IETF_RFC_V1 = 80,      // RFC 9000.
+  QUIC_VERSION_IETF_2_DRAFT_01 = 81,  // draft-ietf-quic-v2-01.
+  // Version 99 was a dumping ground for IETF QUIC changes which were not yet
+  // ready for production between 2018-02 and 2020-02.
+
+  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
+  // which is part of a range reserved by the IETF for version negotiation
+  // testing (see the "Versions" section of draft-ietf-quic-transport).
+  // This version is intentionally meant to never be supported to trigger
+  // version negotiation when proposed by clients and to prevent client
+  // ossification when sent by servers.
+  QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
+};
+
+// Helper function which translates from a QuicTransportVersion to a string.
+// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
+QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
+    QuicTransportVersion transport_version);
+
+// The crypto handshake protocols that can be used with QUIC.
+// We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
+// PROTOCOL_TLS1_3.
+enum HandshakeProtocol {
+  PROTOCOL_UNSUPPORTED,
+  PROTOCOL_QUIC_CRYPTO,
+  PROTOCOL_TLS1_3,
+};
+
+// Helper function which translates from a HandshakeProtocol to a string.
+QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString(
+    HandshakeProtocol handshake_protocol);
+
+// Returns whether |transport_version| uses CRYPTO frames for the handshake
+// instead of stream 1.
+QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames(
+    QuicTransportVersion transport_version) {
+  // CRYPTO frames were added in version 48.
+  return transport_version > QUIC_VERSION_46;
+}
+
+// Returns whether this combination of handshake protocol and transport
+// version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT
+// allowed as TLS requires crypto frames which v43 does not support. Note that
+// UnsupportedQuicVersion is a valid version.
+QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
+    HandshakeProtocol handshake_protocol,
+    QuicTransportVersion transport_version) {
+  bool transport_version_is_valid = false;
+  constexpr QuicTransportVersion valid_transport_versions[] = {
+      QUIC_VERSION_IETF_2_DRAFT_01,
+      QUIC_VERSION_IETF_RFC_V1,
+      QUIC_VERSION_IETF_DRAFT_29,
+      QUIC_VERSION_50,
+      QUIC_VERSION_46,
+      QUIC_VERSION_43,
+      QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
+      QUIC_VERSION_UNSUPPORTED,
+  };
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
+    if (transport_version == valid_transport_versions[i]) {
+      transport_version_is_valid = true;
+      break;
+    }
+  }
+  if (!transport_version_is_valid) {
+    return false;
+  }
+  switch (handshake_protocol) {
+    case PROTOCOL_UNSUPPORTED:
+      return transport_version == QUIC_VERSION_UNSUPPORTED;
+    case PROTOCOL_QUIC_CRYPTO:
+      return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
+             transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
+             transport_version != QUIC_VERSION_IETF_RFC_V1 &&
+             transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
+    case PROTOCOL_TLS1_3:
+      return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             transport_version != QUIC_VERSION_50 &&
+             QuicVersionUsesCryptoFrames(transport_version);
+  }
+  return false;
+}
+
+// A parsed QUIC version label which determines that handshake protocol
+// and the transport version.
+struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
+  HandshakeProtocol handshake_protocol;
+  QuicTransportVersion transport_version;
+
+  constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
+                              QuicTransportVersion transport_version)
+      : handshake_protocol(handshake_protocol),
+        transport_version(transport_version) {
+    QUICHE_DCHECK(
+        ParsedQuicVersionIsValid(handshake_protocol, transport_version))
+        << QuicVersionToString(transport_version) << " "
+        << HandshakeProtocolToString(handshake_protocol);
+  }
+
+  constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
+      : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}
+
+  ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
+    QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
+                                           other.transport_version))
+        << QuicVersionToString(other.transport_version) << " "
+        << HandshakeProtocolToString(other.handshake_protocol);
+    if (this != &other) {
+      handshake_protocol = other.handshake_protocol;
+      transport_version = other.transport_version;
+    }
+    return *this;
+  }
+
+  bool operator==(const ParsedQuicVersion& other) const {
+    return handshake_protocol == other.handshake_protocol &&
+           transport_version == other.transport_version;
+  }
+
+  bool operator!=(const ParsedQuicVersion& other) const {
+    return handshake_protocol != other.handshake_protocol ||
+           transport_version != other.transport_version;
+  }
+
+  static constexpr ParsedQuicVersion V2Draft01() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
+  }
+
+  static constexpr ParsedQuicVersion RFCv1() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
+  }
+
+  static constexpr ParsedQuicVersion Draft29() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
+  }
+
+  static constexpr ParsedQuicVersion Q050() {
+    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
+  }
+
+  static constexpr ParsedQuicVersion Q046() {
+    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
+  }
+
+  static constexpr ParsedQuicVersion Q043() {
+    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
+  }
+
+  static constexpr ParsedQuicVersion Unsupported() {
+    return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
+  }
+
+  static constexpr ParsedQuicVersion ReservedForNegotiation() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3,
+                             QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
+  }
+
+  // Returns whether our codebase understands this version. This should only be
+  // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
+  // version is valid, IsKnown returns whether the version is not
+  // UnsupportedQuicVersion.
+  bool IsKnown() const;
+
+  bool KnowsWhichDecrypterToUse() const;
+
+  // Returns whether this version uses keys derived from the Connection ID for
+  // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
+  bool UsesInitialObfuscators() const;
+
+  // Indicates that this QUIC version does not have an enforced minimum value
+  // for flow control values negotiated during the handshake.
+  bool AllowsLowFlowControlLimits() const;
+
+  // Returns whether header protection is used in this version of QUIC.
+  bool HasHeaderProtection() const;
+
+  // Returns whether this version supports IETF RETRY packets.
+  bool SupportsRetry() const;
+
+  // Returns true if this version sends variable length packet number in long
+  // header.
+  bool SendsVariableLengthPacketNumberInLongHeader() const;
+
+  // Returns whether this version allows server connection ID lengths
+  // that are not 64 bits.
+  bool AllowsVariableLengthConnectionIds() const;
+
+  // Returns whether this version supports client connection ID.
+  bool SupportsClientConnectionIds() const;
+
+  // Returns whether this version supports long header 8-bit encoded
+  // connection ID lengths as described in draft-ietf-quic-invariants-06 and
+  // draft-ietf-quic-transport-22.
+  bool HasLengthPrefixedConnectionIds() const;
+
+  // Returns whether this version supports IETF style anti-amplification limit,
+  // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
+  // times received bytes until address can be validated.
+  bool SupportsAntiAmplificationLimit() const;
+
+  // Returns true if this version can send coalesced packets.
+  bool CanSendCoalescedPackets() const;
+
+  // Returns true if this version supports the old Google-style Alt-Svc
+  // advertisement format.
+  bool SupportsGoogleAltSvcFormat() const;
+
+  // Returns true if |transport_version| uses IETF invariant headers.
+  bool HasIetfInvariantHeader() const;
+
+  // Returns true if |transport_version| supports MESSAGE frames.
+  bool SupportsMessageFrames() const;
+
+  // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
+  // Notable changes are:
+  // * Headers stream no longer exists.
+  // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
+  // * PUSH_PROMISE is moved to request stream.
+  // * Unidirectional streams will have their first byte as a stream type.
+  // * HEADERS frames are compressed using QPACK.
+  // * DATA frame has frame headers.
+  // * GOAWAY is moved to HTTP layer.
+  bool UsesHttp3() const;
+
+  // Returns whether the transport_version supports the variable length integer
+  // length field as defined by IETF QUIC draft-13 and later.
+  bool HasLongHeaderLengths() const;
+
+  // Returns whether |transport_version| uses CRYPTO frames for the handshake
+  // instead of stream 1.
+  bool UsesCryptoFrames() const;
+
+  // Returns whether |transport_version| makes use of IETF QUIC
+  // frames or not.
+  bool HasIetfQuicFrames() const;
+
+  // Returns whether this version uses the legacy TLS extension codepoint.
+  bool UsesLegacyTlsExtension() const;
+
+  // Returns whether this version uses PROTOCOL_TLS1_3.
+  bool UsesTls() const;
+
+  // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
+  bool UsesQuicCrypto() const;
+
+  // Returns whether this version uses the QUICv2 Long Header Packet Types.
+  bool UsesV2PacketTypes() const;
+
+  // Returns true if this shares ALPN codes with RFCv1, and endpoints should
+  // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
+  // RFCv1.
+  bool AlpnDeferToRFCv1() const;
+};
+
+QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
+
+QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
+
+// Outer version used when encapsulating other packets using the Legacy Version
+// Encapsulation feature.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const ParsedQuicVersion& version);
+
+using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const ParsedQuicVersionVector& versions);
+
+// Representation of the on-the-wire QUIC version number. Will be written/read
+// to the wire in network-byte-order.
+using QuicVersionLabel = uint32_t;
+using QuicVersionLabelVector = std::vector<QuicVersionLabel>;
+
+// Constructs a version label from the 4 bytes such that the on-the-wire
+// order will be: d, c, b, a.
+QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
+                                                      uint8_t c, uint8_t d);
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicVersionLabelVector& version_labels);
+
+// This vector contains all crypto handshake protocols that are supported.
+constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
+  return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
+}
+
+constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
+  return {
+      ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
+      ParsedQuicVersion::Draft29(),   ParsedQuicVersion::Q050(),
+      ParsedQuicVersion::Q046(),      ParsedQuicVersion::Q043(),
+  };
+}
+
+using QuicTransportVersionVector = std::vector<QuicTransportVersion>;
+
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os, const QuicTransportVersionVector& transport_versions);
+
+// Returns a vector of supported QUIC versions.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
+
+// Returns a vector of supported QUIC versions, with any versions disabled by
+// flags excluded.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
+
+// Returns a vector of QUIC versions from |versions| which exclude any versions
+// which are disabled by flags.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+FilterSupportedVersions(ParsedQuicVersionVector versions);
+
+// Returns a subset of AllSupportedVersions() with
+// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
+// Deprecated; only to be used in components that do not yet support
+// PROTOCOL_TLS1_3.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+AllSupportedVersionsWithQuicCrypto();
+
+// Returns a subset of CurrentSupportedVersions() with
+// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+CurrentSupportedVersionsWithQuicCrypto();
+
+// Returns a subset of AllSupportedVersions() with
+// handshake_protocol == PROTOCOL_TLS1_3, in the same order.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls();
+
+// Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
+// PROTOCOL_TLS1_3.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls();
+
+// Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
+// layer.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions();
+
+// Returns QUIC version of |index| in result of |versions|. Returns
+// UnsupportedQuicVersion() if |index| is out of bounds.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
+
+// QuicVersionLabel is written to and read from the wire, but we prefer to use
+// the more readable ParsedQuicVersion at other levels.
+// Helper function which translates from a QuicVersionLabel to a
+// ParsedQuicVersion.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionLabel(QuicVersionLabel version_label);
+
+// Helper function that translates from a QuicVersionLabelVector to a
+// ParsedQuicVersionVector.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);
+
+// Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
+// ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
+// supports parsing numbers such as "46".
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionString(absl::string_view version_string);
+
+// Parses a comma-separated list of QUIC version strings. Supports parsing by
+// label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
+// For example: "h3-29,Q050,46".
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParseQuicVersionVectorString(absl::string_view versions_string);
+
+// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
+// QuicVersionLabel is written to and read from the wire, but we prefer to use
+// the more readable ParsedQuicVersion at other levels.
+// Helper function which translates from a ParsedQuicVersion to a
+// QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
+QUIC_EXPORT_PRIVATE QuicVersionLabel
+CreateQuicVersionLabel(ParsedQuicVersion parsed_version);
+
+// Constructs a QuicVersionLabelVector from the provided
+// ParsedQuicVersionVector.
+QUIC_EXPORT_PRIVATE QuicVersionLabelVector
+CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);
+
+// Helper function which translates from a QuicVersionLabel to a string.
+QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
+    QuicVersionLabel version_label);
+
+// Helper function which translates from a QuicVersionLabel string to a
+// ParsedQuicVersion. The version label string must be of the form returned
+// by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
+// "51303433" (the hex encoding of the Q064 version label). Returns
+// the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
+// otherwise.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion
+ParseQuicVersionLabelString(absl::string_view version_label_string);
+
+// Returns |separator|-separated list of string representations of
+// QuicVersionLabel values in the supplied |version_labels| vector. The values
+// after the (0-based) |skip_after_nth_version|'th are skipped.
+QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels, const std::string& separator,
+    size_t skip_after_nth_version);
+
+// Returns comma separated list of string representations of QuicVersionLabel
+// values in the supplied |version_labels| vector.
+QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
+    const QuicVersionLabelVector& version_labels) {
+  return QuicVersionLabelVectorToString(version_labels, ",",
+                                        std::numeric_limits<size_t>::max());
+}
+
+// Helper function which translates from a ParsedQuicVersion to a string.
+// Returns strings corresponding to the on-the-wire tag.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
+    ParsedQuicVersion version);
+
+// Returns a vector of supported QUIC transport versions. DEPRECATED, use
+// AllSupportedVersions instead.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
+
+// Returns comma separated list of string representations of
+// QuicTransportVersion enum values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
+    const QuicTransportVersionVector& versions);
+
+// Returns comma separated list of string representations of ParsedQuicVersion
+// values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions);
+
+// Returns |separator|-separated list of string representations of
+// ParsedQuicVersion values in the supplied |versions| vector. The values after
+// the (0-based) |skip_after_nth_version|'th are skipped.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions, const std::string& separator,
+    size_t skip_after_nth_version);
+
+// Returns comma separated list of string representations of ParsedQuicVersion
+// values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
+    const ParsedQuicVersionVector& versions) {
+  return ParsedQuicVersionVectorToString(versions, ",",
+                                         std::numeric_limits<size_t>::max());
+}
+
+// Returns true if |transport_version| uses IETF invariant headers.
+QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader(
+    QuicTransportVersion transport_version) {
+  return transport_version > QUIC_VERSION_43;
+}
+
+// Returns true if |transport_version| supports MESSAGE frames.
+QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames(
+    QuicTransportVersion transport_version) {
+  // MESSAGE frames were added in version 45.
+  return transport_version > QUIC_VERSION_43;
+}
+
+// If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
+// Notable changes are:
+// * Headers stream no longer exists.
+// * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
+// * PUSH_PROMISE is moved to request stream.
+// * Unidirectional streams will have their first byte as a stream type.
+// * HEADERS frames are compressed using QPACK.
+// * DATA frame has frame headers.
+// * GOAWAY is moved to HTTP layer.
+QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
+    QuicTransportVersion transport_version) {
+  return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
+}
+
+// Returns whether the transport_version supports the variable length integer
+// length field as defined by IETF QUIC draft-13 and later.
+QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths(
+    QuicTransportVersion transport_version) {
+  // Long header lengths were added in version 49.
+  return transport_version > QUIC_VERSION_46;
+}
+
+// Returns whether |transport_version| makes use of IETF QUIC
+// frames or not.
+QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
+    QuicTransportVersion transport_version) {
+  return VersionUsesHttp3(transport_version);
+}
+
+// Returns whether this version supports long header 8-bit encoded
+// connection ID lengths as described in draft-ietf-quic-invariants-06 and
+// draft-ietf-quic-transport-22.
+QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds(
+    QuicTransportVersion transport_version);
+
+// Returns true if this version supports the old Google-style Alt-Svc
+// advertisement format.
+QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat(
+    QuicTransportVersion transport_version);
+
+// Returns whether this version allows server connection ID lengths that are
+// not 64 bits.
+QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds(
+    QuicTransportVersion transport_version);
+
+// Returns whether this version label supports long header 4-bit encoded
+// connection ID lengths as described in draft-ietf-quic-invariants-05 and
+// draft-ietf-quic-transport-21.
+QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength(
+    QuicVersionLabel version_label);
+
+// Returns the ALPN string to use in TLS for this version of QUIC.
+QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
+    ParsedQuicVersion parsed_version);
+
+// Initializes support for the provided IETF draft version by setting the
+// correct flags.
+QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();
+
+// Configures the flags required to enable support for this version of QUIC.
+QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);
+
+// Configures the flags required to disable support for this version of QUIC.
+QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);
+
+// Returns whether support for this version of QUIC is currently enabled.
+QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
diff --git a/quiche/quic/core/quic_versions_test.cc b/quiche/quic/core/quic_versions_test.cc
new file mode 100644
index 0000000..5dbfdd0
--- /dev/null
+++ b/quiche/quic/core/quic_versions_test.cc
@@ -0,0 +1,524 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_versions.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_mock_log.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
+TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
+  EXPECT_QUIC_BUG(
+      CreateQuicVersionLabel(UnsupportedQuicVersion()),
+      "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
+}
+
+TEST(QuicVersionsTest, KnownAndValid) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_TRUE(version.IsKnown());
+    EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
+                                         version.transport_version));
+  }
+  ParsedQuicVersion unsupported = UnsupportedQuicVersion();
+  EXPECT_FALSE(unsupported.IsKnown());
+  EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
+                                       unsupported.transport_version));
+  ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
+  EXPECT_TRUE(reserved.IsKnown());
+  EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
+                                       reserved.transport_version));
+  // Check that invalid combinations are not valid.
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_43));
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
+                                        QUIC_VERSION_IETF_DRAFT_29));
+  // Check that deprecated versions are not valid.
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
+                                        static_cast<QuicTransportVersion>(33)));
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
+                                        static_cast<QuicTransportVersion>(99)));
+  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
+                                        static_cast<QuicTransportVersion>(99)));
+}
+
+TEST(QuicVersionsTest, Features) {
+  ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
+  ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
+
+  EXPECT_TRUE(parsed_version_q043.IsKnown());
+  EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
+  EXPECT_FALSE(parsed_version_q043.UsesInitialObfuscators());
+  EXPECT_FALSE(parsed_version_q043.AllowsLowFlowControlLimits());
+  EXPECT_FALSE(parsed_version_q043.HasHeaderProtection());
+  EXPECT_FALSE(parsed_version_q043.SupportsRetry());
+  EXPECT_FALSE(
+      parsed_version_q043.SendsVariableLengthPacketNumberInLongHeader());
+  EXPECT_FALSE(parsed_version_q043.AllowsVariableLengthConnectionIds());
+  EXPECT_FALSE(parsed_version_q043.SupportsClientConnectionIds());
+  EXPECT_FALSE(parsed_version_q043.HasLengthPrefixedConnectionIds());
+  EXPECT_FALSE(parsed_version_q043.SupportsAntiAmplificationLimit());
+  EXPECT_FALSE(parsed_version_q043.CanSendCoalescedPackets());
+  EXPECT_TRUE(parsed_version_q043.SupportsGoogleAltSvcFormat());
+  EXPECT_FALSE(parsed_version_q043.HasIetfInvariantHeader());
+  EXPECT_FALSE(parsed_version_q043.SupportsMessageFrames());
+  EXPECT_FALSE(parsed_version_q043.UsesHttp3());
+  EXPECT_FALSE(parsed_version_q043.HasLongHeaderLengths());
+  EXPECT_FALSE(parsed_version_q043.UsesCryptoFrames());
+  EXPECT_FALSE(parsed_version_q043.HasIetfQuicFrames());
+  EXPECT_FALSE(parsed_version_q043.UsesTls());
+  EXPECT_TRUE(parsed_version_q043.UsesQuicCrypto());
+
+  EXPECT_TRUE(parsed_version_draft_29.IsKnown());
+  EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
+  EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
+  EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
+  EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
+  EXPECT_TRUE(
+      parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
+  EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
+  EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
+  EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
+  EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
+  EXPECT_TRUE(parsed_version_draft_29.HasIetfInvariantHeader());
+  EXPECT_TRUE(parsed_version_draft_29.SupportsMessageFrames());
+  EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
+  EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
+  EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
+  EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
+  EXPECT_TRUE(parsed_version_draft_29.UsesTls());
+  EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionLabel) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(ParsedQuicVersion::Q043(),
+            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
+  EXPECT_EQ(ParsedQuicVersion::Q046(),
+            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
+  EXPECT_EQ(ParsedQuicVersion::Q050(),
+            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(),
+            ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
+            ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
+  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+            ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
+  EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
+                                     ParsedQuicVersion::RFCv1(),
+                                     ParsedQuicVersion::Draft29()}),
+            ParseQuicVersionLabelVector(QuicVersionLabelVector{
+                MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
+                MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
+                MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
+                MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
+
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
+  }
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionString) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(),
+            ParseQuicVersionString("QUIC_VERSION_46"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
+
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
+
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
+
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
+
+  // QUICv2 will never be the result for "h3".
+
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_EQ(version,
+              ParseQuicVersionString(ParsedQuicVersionToString(version)));
+    EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
+                           CreateQuicVersionLabel(version))));
+    if (!version.AlpnDeferToRFCv1()) {
+      EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
+    }
+  }
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
+  ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
+  ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
+  ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
+
+  EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
+
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
+              ElementsAre(version_q050, version_draft_29));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
+              ElementsAre(version_q050, version_draft_29));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
+              ElementsAre(version_q050, version_draft_29));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
+              ElementsAre(version_draft_29, version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
+              ElementsAre(version_q050, version_q046));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
+              ElementsAre(version_q046, version_q050));
+
+  // Regression test for https://crbug.com/1044952.
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString(
+                  "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
+              ElementsAre(version_q050));
+  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
+              ElementsAre(version_q050, version_draft_29));
+
+  EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
+  EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
+              ElementsAre(version_draft_29));
+}
+
+// Do not use MakeVersionLabel() to generate expectations, because
+// CreateQuicVersionLabel() uses MakeVersionLabel() internally,
+// in case it has a bug.
+TEST(QuicVersionsTest, CreateQuicVersionLabel) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(0x51303433u, CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
+  EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
+  EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
+  EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
+  EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
+  EXPECT_EQ(0x709a50c4u,
+            CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));
+
+  // Make sure the negotiation reserved version is in the IETF reserved space.
+  EXPECT_EQ(
+      0xda5a3a3au & 0x0f0f0f0f,
+      CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
+          0x0f0f0f0f);
+
+  // Make sure that disabling randomness works.
+  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
+  EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
+                             ParsedQuicVersion::ReservedForNegotiation()));
+}
+
+TEST(QuicVersionsTest, QuicVersionLabelToString) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ("Q043", QuicVersionLabelToString(
+                        CreateQuicVersionLabel(ParsedQuicVersion::Q043())));
+  EXPECT_EQ("Q046", QuicVersionLabelToString(
+                        CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
+  EXPECT_EQ("Q050", QuicVersionLabelToString(
+                        CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
+  EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
+                            ParsedQuicVersion::Draft29())));
+  EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
+                            ParsedQuicVersion::RFCv1())));
+  EXPECT_EQ("709a50c4", QuicVersionLabelToString(CreateQuicVersionLabel(
+                            ParsedQuicVersion::V2Draft01())));
+
+  QuicVersionLabelVector version_labels = {
+      MakeVersionLabel('Q', '0', '3', '5'),
+      MakeVersionLabel('T', '0', '3', '8'),
+      MakeVersionLabel(0xff, 0, 0, 7),
+  };
+
+  EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
+  EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
+  EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
+
+  EXPECT_EQ("Q035,T038,ff000007",
+            QuicVersionLabelVectorToString(version_labels));
+  EXPECT_EQ("Q035:T038:ff000007",
+            QuicVersionLabelVectorToString(version_labels, ":", 2));
+  EXPECT_EQ("Q035|T038|...",
+            QuicVersionLabelVectorToString(version_labels, "|", 1));
+
+  std::ostringstream os;
+  os << version_labels;
+  EXPECT_EQ("Q035,T038,ff000007", os.str());
+}
+
+TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  // Explicitly test known QUIC version label strings.
+  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionLabelString("Q043"));
+  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
+  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(),
+            ParseQuicVersionLabelString("ff00001d"));
+  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
+            ParseQuicVersionLabelString("00000001"));
+  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
+            ParseQuicVersionLabelString("709a50c4"));
+
+  // Sanity check that a variety of other serialization formats are ignored.
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
+  EXPECT_EQ(UnsupportedQuicVersion(),
+            ParseQuicVersionLabelString("QUIC_VERSION_46"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
+  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
+
+  // Test round-trips between QuicVersionLabelToString and
+  // ParseQuicVersionLabelString.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
+                           CreateQuicVersionLabel(version))));
+  }
+}
+
+TEST(QuicVersionsTest, QuicVersionToString) {
+  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
+            QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
+
+  QuicTransportVersion single_version[] = {QUIC_VERSION_43};
+  QuicTransportVersionVector versions_vector;
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
+    versions_vector.push_back(single_version[i]);
+  }
+  EXPECT_EQ("QUIC_VERSION_43",
+            QuicTransportVersionVectorToString(versions_vector));
+
+  QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
+                                              QUIC_VERSION_43};
+  versions_vector.clear();
+  for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
+    versions_vector.push_back(multiple_versions[i]);
+  }
+  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43",
+            QuicTransportVersionVectorToString(versions_vector));
+
+  // Make sure that all supported versions are present in QuicVersionToString.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
+              QuicVersionToString(version.transport_version));
+  }
+
+  std::ostringstream os;
+  os << versions_vector;
+  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
+}
+
+TEST(QuicVersionsTest, ParsedQuicVersionToString) {
+  EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
+  EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
+  EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
+  EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
+  EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
+  EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
+  EXPECT_EQ("v2draft01",
+            ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));
+
+  ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
+  EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
+
+  versions_vector = {ParsedQuicVersion::Unsupported(),
+                     ParsedQuicVersion::Q043()};
+  EXPECT_EQ("0,Q043", ParsedQuicVersionVectorToString(versions_vector));
+  EXPECT_EQ("0:Q043", ParsedQuicVersionVectorToString(versions_vector, ":",
+                                                      versions_vector.size()));
+  EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
+
+  // Make sure that all supported versions are present in
+  // ParsedQuicVersionToString.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_NE("0", ParsedQuicVersionToString(version));
+  }
+
+  std::ostringstream os;
+  os << versions_vector;
+  EXPECT_EQ("0,Q043", os.str());
+}
+
+TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicEnableVersion(version);
+  }
+  ParsedQuicVersionVector expected_parsed_versions;
+  for (const ParsedQuicVersion& version : SupportedVersions()) {
+    expected_parsed_versions.push_back(version);
+  }
+  EXPECT_EQ(expected_parsed_versions,
+            FilterSupportedVersions(AllSupportedVersions()));
+  EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
+}
+
+TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicEnableVersion(version);
+  }
+  QuicDisableVersion(AllSupportedVersions().front());
+  ParsedQuicVersionVector expected_parsed_versions;
+  for (const ParsedQuicVersion& version : SupportedVersions()) {
+    expected_parsed_versions.push_back(version);
+  }
+  expected_parsed_versions.erase(expected_parsed_versions.begin());
+  EXPECT_EQ(expected_parsed_versions,
+            FilterSupportedVersions(AllSupportedVersions()));
+}
+
+TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
+  ParsedQuicVersionVector all_versions = AllSupportedVersions();
+  int version_count = all_versions.size();
+  for (int i = -5; i <= version_count + 1; ++i) {
+    ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
+    if (i >= 0 && i < version_count) {
+      EXPECT_EQ(all_versions[i], index[0]);
+    } else {
+      EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
+    }
+  }
+}
+
+// This test may appear to be so simplistic as to be unnecessary,
+// yet a typo was made in doing the #defines and it was caught
+// only in some test far removed from here... Better safe than sorry.
+TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ(QUIC_VERSION_43, 43);
+  EXPECT_EQ(QUIC_VERSION_46, 46);
+  EXPECT_EQ(QUIC_VERSION_50, 50);
+  EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
+  EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
+  EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
+}
+
+TEST(QuicVersionsTest, AlpnForVersion) {
+  static_assert(SupportedVersions().size() == 6u,
+                "Supported versions out of sync");
+  EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
+  EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
+  EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
+  EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
+  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
+  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
+}
+
+TEST(QuicVersionsTest, QuicVersionEnabling) {
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    QuicFlagSaver flag_saver;
+    QuicDisableVersion(version);
+    EXPECT_FALSE(QuicVersionIsEnabled(version));
+    QuicEnableVersion(version);
+    EXPECT_TRUE(QuicVersionIsEnabled(version));
+  }
+}
+
+TEST(QuicVersionsTest, ReservedForNegotiation) {
+  EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
+            QuicVersionReservedForNegotiation().transport_version);
+  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
+  }
+}
+
+TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
+  size_t index = 0;
+  for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
+    for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
+      QuicTransportVersion transport_version =
+          static_cast<QuicTransportVersion>(trans_vers);
+      SCOPED_TRACE(index);
+      if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
+        ParsedQuicVersion version = SupportedVersions()[index];
+        EXPECT_EQ(version,
+                  ParsedQuicVersion(handshake_protocol, transport_version));
+        index++;
+      }
+    }
+  }
+  EXPECT_EQ(SupportedVersions().size(), index);
+}
+
+TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
+  for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
+    ParsedQuicVersion version1 = SupportedVersions()[index1];
+    for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
+         ++index2) {
+      ParsedQuicVersion version2 = SupportedVersions()[index2];
+      EXPECT_NE(version1, version2) << version1 << " " << version2;
+      EXPECT_NE(CreateQuicVersionLabel(version1),
+                CreateQuicVersionLabel(version2))
+          << version1 << " " << version2;
+      // The one pair where ALPNs are the same.
+      if ((version1 != ParsedQuicVersion::V2Draft01()) &&
+          (version2 != ParsedQuicVersion::RFCv1())) {
+        EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
+            << version1 << " " << version2;
+      }
+    }
+  }
+}
+
+TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
+  ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
+  ParsedQuicVersionVector all_current_supported_versions =
+      CurrentSupportedVersions();
+  for (auto& version : all_current_supported_versions) {
+    bool version_is_h3 = false;
+    for (auto& h3_version : h3_versions) {
+      if (version == h3_version) {
+        EXPECT_TRUE(version.UsesHttp3());
+        version_is_h3 = true;
+        break;
+      }
+    }
+    if (!version_is_h3) {
+      EXPECT_FALSE(version.UsesHttp3());
+    }
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/quic_write_blocked_list.cc b/quiche/quic/core/quic_write_blocked_list.cc
new file mode 100644
index 0000000..231259b
--- /dev/null
+++ b/quiche/quic/core/quic_write_blocked_list.cc
@@ -0,0 +1,182 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_write_blocked_list.h"
+
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+QuicWriteBlockedList::QuicWriteBlockedList(QuicTransportVersion version)
+    : priority_write_scheduler_(QuicVersionUsesCryptoFrames(version)
+                                    ? std::numeric_limits<QuicStreamId>::max()
+                                    : 0),
+      last_priority_popped_(0) {
+  memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_));
+  memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_));
+}
+
+QuicWriteBlockedList::~QuicWriteBlockedList() {}
+
+bool QuicWriteBlockedList::ShouldYield(QuicStreamId id) const {
+  for (const auto& stream : static_stream_collection_) {
+    if (stream.id == id) {
+      // Static streams should never yield to data streams, or to lower
+      // priority static stream.
+      return false;
+    }
+    if (stream.is_blocked) {
+      return true;  // All data streams yield to static streams.
+    }
+  }
+
+  return priority_write_scheduler_.ShouldYield(id);
+}
+
+QuicStreamId QuicWriteBlockedList::PopFront() {
+  QuicStreamId static_stream_id;
+  if (static_stream_collection_.UnblockFirstBlocked(&static_stream_id)) {
+    return static_stream_id;
+  }
+
+  const auto id_and_precedence =
+      priority_write_scheduler_.PopNextReadyStreamAndPrecedence();
+  const QuicStreamId id = std::get<0>(id_and_precedence);
+  const spdy::SpdyPriority priority =
+      std::get<1>(id_and_precedence).spdy3_priority();
+
+  if (!priority_write_scheduler_.HasReadyStreams()) {
+    // If no streams are blocked, don't bother latching.  This stream will be
+    // the first popped for its priority anyway.
+    batch_write_stream_id_[priority] = 0;
+    last_priority_popped_ = priority;
+  } else if (batch_write_stream_id_[priority] != id) {
+    // If newly latching this batch write stream, let it write 16k.
+    batch_write_stream_id_[priority] = id;
+    bytes_left_for_batch_write_[priority] = 16000;
+    last_priority_popped_ = priority;
+  }
+
+  return id;
+}
+
+void QuicWriteBlockedList::RegisterStream(
+    QuicStreamId stream_id,
+    bool is_static_stream,
+    const spdy::SpdyStreamPrecedence& precedence) {
+  QUICHE_DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id))
+      << "stream " << stream_id << " already registered";
+  QUICHE_DCHECK(precedence.is_spdy3_priority());
+  if (is_static_stream) {
+    static_stream_collection_.Register(stream_id);
+    return;
+  }
+
+  priority_write_scheduler_.RegisterStream(stream_id, precedence);
+}
+
+void QuicWriteBlockedList::UnregisterStream(QuicStreamId stream_id,
+                                            bool is_static) {
+  if (is_static) {
+    static_stream_collection_.Unregister(stream_id);
+    return;
+  }
+  priority_write_scheduler_.UnregisterStream(stream_id);
+}
+
+void QuicWriteBlockedList::UpdateStreamPriority(
+    QuicStreamId stream_id,
+    const spdy::SpdyStreamPrecedence& new_precedence) {
+  QUICHE_DCHECK(!static_stream_collection_.IsRegistered(stream_id));
+  QUICHE_DCHECK(new_precedence.is_spdy3_priority());
+  priority_write_scheduler_.UpdateStreamPrecedence(stream_id, new_precedence);
+}
+
+void QuicWriteBlockedList::UpdateBytesForStream(QuicStreamId stream_id,
+                                                size_t bytes) {
+  if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
+    // If this was the last data stream popped by PopFront, update the
+    // bytes remaining in its batch write.
+    bytes_left_for_batch_write_[last_priority_popped_] -=
+        std::min(bytes_left_for_batch_write_[last_priority_popped_], bytes);
+  }
+}
+
+void QuicWriteBlockedList::AddStream(QuicStreamId stream_id) {
+  if (static_stream_collection_.SetBlocked(stream_id)) {
+    return;
+  }
+
+  bool push_front =
+      stream_id == batch_write_stream_id_[last_priority_popped_] &&
+      bytes_left_for_batch_write_[last_priority_popped_] > 0;
+  priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
+}
+
+bool QuicWriteBlockedList::IsStreamBlocked(QuicStreamId stream_id) const {
+  for (const auto& stream : static_stream_collection_) {
+    if (stream.id == stream_id) {
+      return stream.is_blocked;
+    }
+  }
+
+  return priority_write_scheduler_.IsStreamReady(stream_id);
+}
+
+void QuicWriteBlockedList::StaticStreamCollection::Register(QuicStreamId id) {
+  QUICHE_DCHECK(!IsRegistered(id));
+  streams_.push_back({id, false});
+}
+
+bool QuicWriteBlockedList::StaticStreamCollection::IsRegistered(
+    QuicStreamId id) const {
+  for (const auto& stream : streams_) {
+    if (stream.id == id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void QuicWriteBlockedList::StaticStreamCollection::Unregister(QuicStreamId id) {
+  for (auto it = streams_.begin(); it != streams_.end(); ++it) {
+    if (it->id == id) {
+      if (it->is_blocked) {
+        --num_blocked_;
+      }
+      streams_.erase(it);
+      return;
+    }
+  }
+  QUICHE_DCHECK(false) << "Erasing a non-exist stream with id " << id;
+}
+
+bool QuicWriteBlockedList::StaticStreamCollection::SetBlocked(QuicStreamId id) {
+  for (auto& stream : streams_) {
+    if (stream.id == id) {
+      if (!stream.is_blocked) {
+        stream.is_blocked = true;
+        ++num_blocked_;
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicWriteBlockedList::StaticStreamCollection::UnblockFirstBlocked(
+    QuicStreamId* id) {
+  for (auto& stream : streams_) {
+    if (stream.is_blocked) {
+      --num_blocked_;
+      stream.is_blocked = false;
+      *id = stream.id;
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/quic_write_blocked_list.h b/quiche/quic/core/quic_write_blocked_list.h
new file mode 100644
index 0000000..f8bf603
--- /dev/null
+++ b/quiche/quic/core/quic_write_blocked_list.h
@@ -0,0 +1,143 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
+#define QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+
+#include "absl/container/inlined_vector.h"
+#include "quiche/http2/core/priority_write_scheduler.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+// Keeps tracks of the QUIC streams that have data to write, sorted by
+// priority.  QUIC stream priority order is:
+// Crypto stream > Headers stream > Data streams by requested priority.
+class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
+ public:
+  explicit QuicWriteBlockedList(QuicTransportVersion version);
+  QuicWriteBlockedList(const QuicWriteBlockedList&) = delete;
+  QuicWriteBlockedList& operator=(const QuicWriteBlockedList&) = delete;
+  ~QuicWriteBlockedList();
+
+  bool HasWriteBlockedDataStreams() const {
+    return priority_write_scheduler_.HasReadyStreams();
+  }
+
+  bool HasWriteBlockedSpecialStream() const {
+    return static_stream_collection_.num_blocked() > 0;
+  }
+
+  size_t NumBlockedSpecialStreams() const {
+    return static_stream_collection_.num_blocked();
+  }
+
+  size_t NumBlockedStreams() const {
+    return NumBlockedSpecialStreams() +
+           priority_write_scheduler_.NumReadyStreams();
+  }
+
+  bool ShouldYield(QuicStreamId id) const;
+
+  spdy::SpdyPriority GetSpdyPriorityofStream(QuicStreamId id) const {
+    return priority_write_scheduler_.GetStreamPrecedence(id).spdy3_priority();
+  }
+
+  // Pops the highest priority stream, special casing crypto and headers
+  // streams. Latches the most recently popped data stream for batch writing
+  // purposes.
+  QuicStreamId PopFront();
+
+  void RegisterStream(QuicStreamId stream_id,
+                      bool is_static_stream,
+                      const spdy::SpdyStreamPrecedence& precedence);
+
+  void UnregisterStream(QuicStreamId stream_id, bool is_static);
+
+  void UpdateStreamPriority(QuicStreamId stream_id,
+                            const spdy::SpdyStreamPrecedence& new_precedence);
+
+  void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes);
+
+  // Pushes a stream to the back of the list for its priority level *unless* it
+  // is latched for doing batched writes in which case it goes to the front of
+  // the list for its priority level.
+  // Headers and crypto streams are special cased to always resume first.
+  void AddStream(QuicStreamId stream_id);
+
+  // Returns true if stream with |stream_id| is write blocked.
+  bool IsStreamBlocked(QuicStreamId stream_id) const;
+
+ private:
+  http2::PriorityWriteScheduler<QuicStreamId> priority_write_scheduler_;
+
+  // If performing batch writes, this will be the stream ID of the stream doing
+  // batch writes for this priority level.  We will allow this stream to write
+  // until it has written kBatchWriteSize bytes, it has no more data to write,
+  // or a higher priority stream preempts.
+  QuicStreamId batch_write_stream_id_[spdy::kV3LowestPriority + 1];
+  // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
+  // priority.  This is decremented with each write the stream does until it is
+  // done with its batch write.
+  size_t bytes_left_for_batch_write_[spdy::kV3LowestPriority + 1];
+  // Tracks the last priority popped for UpdateBytesForStream.
+  spdy::SpdyPriority last_priority_popped_;
+
+  // A StaticStreamCollection is a vector of <QuicStreamId, bool> pairs plus a
+  // eagerly-computed number of blocked static streams.
+  class QUIC_EXPORT_PRIVATE StaticStreamCollection {
+   public:
+    struct QUIC_EXPORT_PRIVATE StreamIdBlockedPair {
+      QuicStreamId id;
+      bool is_blocked;
+    };
+
+    // Optimized for the typical case of 2 static streams per session.
+    using StreamsVector = absl::InlinedVector<StreamIdBlockedPair, 2>;
+
+    StreamsVector::const_iterator begin() const { return streams_.cbegin(); }
+
+    StreamsVector::const_iterator end() const { return streams_.cend(); }
+
+    size_t num_blocked() const { return num_blocked_; }
+
+    // Add |id| to the collection in unblocked state.
+    void Register(QuicStreamId id);
+
+    // True if |id| is in the collection, regardless of its state.
+    bool IsRegistered(QuicStreamId id) const;
+
+    // Remove |id| from the collection, if it is in the blocked state, reduce
+    // |num_blocked_| by 1.
+    void Unregister(QuicStreamId id);
+
+    // Set |id| to be blocked. If |id| is not already blocked, increase
+    // |num_blocked_| by 1.
+    // Return true if |id| is in the collection.
+    bool SetBlocked(QuicStreamId id);
+
+    // Unblock the first blocked stream in the collection.
+    // If no stream is blocked, return false. Otherwise return true, set *id to
+    // the unblocked stream id and reduce |num_blocked_| by 1.
+    bool UnblockFirstBlocked(QuicStreamId* id);
+
+   private:
+    size_t num_blocked_ = 0;
+    StreamsVector streams_;
+  };
+
+  StaticStreamCollection static_stream_collection_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_WRITE_BLOCKED_LIST_H_
diff --git a/quiche/quic/core/quic_write_blocked_list_test.cc b/quiche/quic/core/quic_write_blocked_list_test.cc
new file mode 100644
index 0000000..4d294f0
--- /dev/null
+++ b/quiche/quic/core/quic_write_blocked_list_test.cc
@@ -0,0 +1,269 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_write_blocked_list.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using spdy::kHttp2DefaultStreamWeight;
+using spdy::kV3HighestPriority;
+using spdy::kV3LowestPriority;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicWriteBlockedListTest : public QuicTestWithParam<bool> {
+ public:
+  QuicWriteBlockedListTest()
+      : write_blocked_list_(AllSupportedVersions()[0].transport_version) {}
+
+ protected:
+  QuicWriteBlockedList write_blocked_list_;
+};
+
+TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
+  /*
+       0
+       |
+       23
+       |
+       17
+       |
+       40
+  */
+  // Mark streams blocked in roughly reverse priority order, and
+  // verify that streams are sorted.
+  write_blocked_list_.RegisterStream(
+      40, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  write_blocked_list_.RegisterStream(
+      23, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      17, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  write_blocked_list_.AddStream(40);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(40));
+  write_blocked_list_.AddStream(23);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(23));
+  write_blocked_list_.AddStream(17);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(17));
+  write_blocked_list_.AddStream(3);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(3));
+  write_blocked_list_.AddStream(1);
+  EXPECT_TRUE(write_blocked_list_.IsStreamBlocked(1));
+
+  EXPECT_EQ(5u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedSpecialStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
+  // The Crypto stream is highest priority.
+  EXPECT_EQ(1u, write_blocked_list_.PopFront());
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedSpecialStreams());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(1));
+  // Followed by the Headers stream.
+  EXPECT_EQ(3u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedSpecialStreams());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(3));
+  // Streams with same priority are popped in the order they were inserted.
+  EXPECT_EQ(23u, write_blocked_list_.PopFront());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(23));
+  EXPECT_EQ(17u, write_blocked_list_.PopFront());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(17));
+  // Low priority stream appears last.
+  EXPECT_EQ(40u, write_blocked_list_.PopFront());
+  EXPECT_FALSE(write_blocked_list_.IsStreamBlocked(40));
+
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
+}
+
+TEST_F(QuicWriteBlockedListTest, CryptoStream) {
+  write_blocked_list_.RegisterStream(
+      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(1);
+
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_EQ(1u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+}
+
+TEST_F(QuicWriteBlockedListTest, HeadersStream) {
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(3);
+
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_EQ(3u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+}
+
+TEST_F(QuicWriteBlockedListTest, VerifyHeadersStream) {
+  write_blocked_list_.RegisterStream(
+      5, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(5);
+  write_blocked_list_.AddStream(3);
+
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
+  // In newer QUIC versions, there is a headers stream which is
+  // higher priority than data streams.
+  EXPECT_EQ(3u, write_blocked_list_.PopFront());
+  EXPECT_EQ(5u, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedSpecialStream());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
+}
+
+TEST_F(QuicWriteBlockedListTest, NoDuplicateEntries) {
+  // Test that QuicWriteBlockedList doesn't allow duplicate entries.
+  // Try to add a stream to the write blocked list multiple times at the same
+  // priority.
+  const QuicStreamId kBlockedId = 3 + 2;
+    write_blocked_list_.RegisterStream(
+        kBlockedId, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.AddStream(kBlockedId);
+  write_blocked_list_.AddStream(kBlockedId);
+  write_blocked_list_.AddStream(kBlockedId);
+
+  // This should only result in one blocked stream being added.
+  EXPECT_EQ(1u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list_.HasWriteBlockedDataStreams());
+
+  // There should only be one stream to pop off the front.
+  EXPECT_EQ(kBlockedId, write_blocked_list_.PopFront());
+  EXPECT_EQ(0u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list_.HasWriteBlockedDataStreams());
+}
+
+TEST_F(QuicWriteBlockedListTest, BatchingWrites) {
+  const QuicStreamId id1 = 3 + 2;
+  const QuicStreamId id2 = id1 + 2;
+  const QuicStreamId id3 = id2 + 2;
+  write_blocked_list_.RegisterStream(
+      id1, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  write_blocked_list_.RegisterStream(
+      id2, false, spdy::SpdyStreamPrecedence(kV3LowestPriority));
+  write_blocked_list_.RegisterStream(
+      id3, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  write_blocked_list_.AddStream(id1);
+  write_blocked_list_.AddStream(id2);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+
+  // The first stream we push back should stay at the front until 16k is
+  // written.
+  EXPECT_EQ(id1, write_blocked_list_.PopFront());
+  write_blocked_list_.UpdateBytesForStream(id1, 15999);
+  write_blocked_list_.AddStream(id1);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_EQ(id1, write_blocked_list_.PopFront());
+
+  // Once 16k is written the first stream will yield to the next.
+  write_blocked_list_.UpdateBytesForStream(id1, 1);
+  write_blocked_list_.AddStream(id1);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_EQ(id2, write_blocked_list_.PopFront());
+
+  // Set the new stream to have written all but one byte.
+  write_blocked_list_.UpdateBytesForStream(id2, 15999);
+  write_blocked_list_.AddStream(id2);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+
+  // Ensure higher priority streams are popped first.
+  write_blocked_list_.AddStream(id3);
+  EXPECT_EQ(id3, write_blocked_list_.PopFront());
+
+  // Higher priority streams will always be popped first, even if using their
+  // byte quota
+  write_blocked_list_.UpdateBytesForStream(id3, 20000);
+  write_blocked_list_.AddStream(id3);
+  EXPECT_EQ(id3, write_blocked_list_.PopFront());
+
+  // Once the higher priority stream is out of the way, id2 will resume its 16k
+  // write, with only 1 byte remaining of its guaranteed write allocation.
+  EXPECT_EQ(id2, write_blocked_list_.PopFront());
+  write_blocked_list_.UpdateBytesForStream(id2, 1);
+  write_blocked_list_.AddStream(id2);
+  EXPECT_EQ(2u, write_blocked_list_.NumBlockedStreams());
+  EXPECT_EQ(id1, write_blocked_list_.PopFront());
+}
+
+TEST_F(QuicWriteBlockedListTest, Ceding) {
+  /*
+       0
+       |
+       15
+       |
+       16
+       |
+       5
+       |
+       4
+       |
+       7
+  */
+  write_blocked_list_.RegisterStream(
+      15, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      16, false, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(5, false, spdy::SpdyStreamPrecedence(5));
+  write_blocked_list_.RegisterStream(4, false, spdy::SpdyStreamPrecedence(5));
+  write_blocked_list_.RegisterStream(7, false, spdy::SpdyStreamPrecedence(7));
+  write_blocked_list_.RegisterStream(
+      1, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+  write_blocked_list_.RegisterStream(
+      3, true, spdy::SpdyStreamPrecedence(kV3HighestPriority));
+
+  // When nothing is on the list, nothing yields.
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
+
+  write_blocked_list_.AddStream(5);
+  // 5 should not yield to itself.
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(5));
+  // 4 and 7 are equal or lower priority and should yield to 5.
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(4));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(7));
+  // 15, headers and crypto should preempt 5.
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(15));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+
+  // Block a high priority stream.
+  write_blocked_list_.AddStream(15);
+  // 16 should yield (same priority) but headers and crypto will still not.
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+
+  // Block the headers stream.  All streams but crypto and headers should yield.
+  write_blocked_list_.AddStream(3);
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+
+  // Block the crypto stream.  All streams but crypto should yield.
+  write_blocked_list_.AddStream(1);
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(16));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(15));
+  EXPECT_TRUE(write_blocked_list_.ShouldYield(3));
+  EXPECT_FALSE(write_blocked_list_.ShouldYield(1));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/session_notifier_interface.h b/quiche/quic/core/session_notifier_interface.h
new file mode 100644
index 0000000..ee4453a
--- /dev/null
+++ b/quiche/quic/core/session_notifier_interface.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
+#define QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
+
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+
+// Pure virtual class to be notified when a packet containing a frame is acked
+// or lost.
+class QUIC_EXPORT_PRIVATE SessionNotifierInterface {
+ public:
+  virtual ~SessionNotifierInterface() {}
+
+  // Called when |frame| is acked. Returns true if any new data gets acked,
+  // returns false otherwise.
+  virtual bool OnFrameAcked(const QuicFrame& frame,
+                            QuicTime::Delta ack_delay_time,
+                            QuicTime receive_timestamp) = 0;
+
+  // Called when |frame| is retransmitted.
+  virtual void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) = 0;
+
+  // Called when |frame| is considered as lost.
+  virtual void OnFrameLost(const QuicFrame& frame) = 0;
+
+  // Called to retransmit |frames| with transmission |type|. Returns true if all
+  // data gets retransmitted.
+  virtual bool RetransmitFrames(const QuicFrames& frames,
+                                TransmissionType type) = 0;
+
+  // Returns true if |frame| is outstanding and waiting to be acked.
+  virtual bool IsFrameOutstanding(const QuicFrame& frame) const = 0;
+
+  // Returns true if crypto stream is waiting for acks.
+  virtual bool HasUnackedCryptoData() const = 0;
+
+  // Returns true if any stream is waiting for acks.
+  virtual bool HasUnackedStreamData() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
diff --git a/quiche/quic/core/stream_delegate_interface.h b/quiche/quic/core/stream_delegate_interface.h
new file mode 100644
index 0000000..f93812c
--- /dev/null
+++ b/quiche/quic/core/stream_delegate_interface.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
+#define QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
+
+#include <cstddef>
+#include "absl/types/optional.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+class QuicStream;
+
+// Pure virtual class to get notified when particular QuicStream events
+// occurred.
+class QUIC_EXPORT_PRIVATE StreamDelegateInterface {
+ public:
+  virtual ~StreamDelegateInterface() {}
+
+  // Called when the stream has encountered errors that it can't handle.
+  virtual void OnStreamError(QuicErrorCode error_code,
+                             std::string error_details) = 0;
+  // Called when the stream has encountered errors that it can't handle,
+  // specifying the wire error code |ietf_error| explicitly.
+  virtual void OnStreamError(QuicErrorCode error_code,
+                             QuicIetfTransportErrorCodes ietf_error,
+                             std::string error_details) = 0;
+  // Called when the stream needs to write data at specified |level| and
+  // transmission |type|.
+  virtual QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                                      QuicStreamOffset offset,
+                                      StreamSendingState state,
+                                      TransmissionType type,
+                                      EncryptionLevel level) = 0;
+  // Called to write crypto data.
+  virtual size_t SendCryptoData(EncryptionLevel level,
+                                size_t write_length,
+                                QuicStreamOffset offset,
+                                TransmissionType type) = 0;
+  // Called on stream creation.
+  virtual void RegisterStreamPriority(
+      QuicStreamId id,
+      bool is_static,
+      const spdy::SpdyStreamPrecedence& precedence) = 0;
+  // Called on stream destruction to clear priority.
+  virtual void UnregisterStreamPriority(QuicStreamId id, bool is_static) = 0;
+  // Called by the stream on SetPriority to update priority.
+  virtual void UpdateStreamPriority(
+      QuicStreamId id,
+      const spdy::SpdyStreamPrecedence& new_precedence) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_STREAM_DELEGATE_INTERFACE_H_
diff --git a/quiche/quic/core/tls_chlo_extractor.cc b/quiche/quic/core/tls_chlo_extractor.cc
new file mode 100644
index 0000000..03810e9
--- /dev/null
+++ b/quiche/quic/core/tls_chlo_extractor.cc
@@ -0,0 +1,425 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/tls_chlo_extractor.h"
+#include <cstring>
+#include <memory>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+bool HasExtension(const SSL_CLIENT_HELLO* client_hello, uint16_t extension) {
+  const uint8_t* unused_extension_bytes;
+  size_t unused_extension_len;
+  return 1 == SSL_early_callback_ctx_extension_get(client_hello, extension,
+                                                   &unused_extension_bytes,
+                                                   &unused_extension_len);
+}
+}  // namespace
+
+TlsChloExtractor::TlsChloExtractor()
+    : crypto_stream_sequencer_(this),
+      state_(State::kInitial),
+      parsed_crypto_frame_in_this_packet_(false) {}
+
+TlsChloExtractor::TlsChloExtractor(TlsChloExtractor&& other)
+    : TlsChloExtractor() {
+  *this = std::move(other);
+}
+
+TlsChloExtractor& TlsChloExtractor::operator=(TlsChloExtractor&& other) {
+  framer_ = std::move(other.framer_);
+  if (framer_) {
+    framer_->set_visitor(this);
+  }
+  crypto_stream_sequencer_ = std::move(other.crypto_stream_sequencer_);
+  crypto_stream_sequencer_.set_stream(this);
+  ssl_ = std::move(other.ssl_);
+  if (ssl_) {
+    std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
+    int ex_data_index = shared_handles.second;
+    const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
+    QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
+  }
+  state_ = other.state_;
+  error_details_ = std::move(other.error_details_);
+  parsed_crypto_frame_in_this_packet_ =
+      other.parsed_crypto_frame_in_this_packet_;
+  alpns_ = std::move(other.alpns_);
+  server_name_ = std::move(other.server_name_);
+  return *this;
+}
+
+void TlsChloExtractor::IngestPacket(const ParsedQuicVersion& version,
+                                    const QuicReceivedPacket& packet) {
+  if (state_ == State::kUnrecoverableFailure) {
+    QUIC_DLOG(ERROR) << "Not ingesting packet after unrecoverable error";
+    return;
+  }
+  if (version == UnsupportedQuicVersion()) {
+    QUIC_DLOG(ERROR) << "Not ingesting packet with unsupported version";
+    return;
+  }
+  if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+    QUIC_DLOG(ERROR) << "Not ingesting packet with non-TLS version " << version;
+    return;
+  }
+  if (framer_) {
+    // This is not the first packet we have ingested, check if version matches.
+    if (!framer_->IsSupportedVersion(version)) {
+      QUIC_DLOG(ERROR)
+          << "Not ingesting packet with version mismatch, expected "
+          << framer_->version() << ", got " << version;
+      return;
+    }
+  } else {
+    // This is the first packet we have ingested, setup parser.
+    framer_ = std::make_unique<QuicFramer>(
+        ParsedQuicVersionVector{version}, QuicTime::Zero(),
+        Perspective::IS_SERVER, /*expected_server_connection_id_length=*/0);
+    // Note that expected_server_connection_id_length only matters for short
+    // headers and we explicitly drop those so we can pass any value here.
+    framer_->set_visitor(this);
+  }
+
+  // When the framer parses |packet|, if it sees a CRYPTO frame it will call
+  // OnCryptoFrame below and that will set parsed_crypto_frame_in_this_packet_
+  // to true.
+  parsed_crypto_frame_in_this_packet_ = false;
+  const bool parse_success = framer_->ProcessPacket(packet);
+  if (state_ == State::kInitial && parsed_crypto_frame_in_this_packet_) {
+    // If we parsed a CRYPTO frame but didn't advance the state from initial,
+    // then it means that we will need more packets to reassemble the full CHLO,
+    // so we advance the state here. This can happen when the first packet
+    // received is not the first one in the crypto stream. This allows us to
+    // differentiate our state between single-packet CHLO and multi-packet CHLO.
+    state_ = State::kParsedPartialChloFragment;
+  }
+
+  if (!parse_success) {
+    // This could be due to the packet being non-initial for example.
+    QUIC_DLOG(ERROR) << "Failed to process packet";
+    return;
+  }
+}
+
+// This is called when the framer parsed the unencrypted parts of the header.
+bool TlsChloExtractor::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& header) {
+  if (header.form != IETF_QUIC_LONG_HEADER_PACKET) {
+    QUIC_DLOG(ERROR) << "Not parsing non-long-header packet " << header;
+    return false;
+  }
+  if (header.long_packet_type != INITIAL) {
+    QUIC_DLOG(ERROR) << "Not parsing non-initial packet " << header;
+    return false;
+  }
+  // QuicFramer is constructed without knowledge of the server's connection ID
+  // so it needs to be set up here in order to decrypt the packet.
+  framer_->SetInitialObfuscators(header.destination_connection_id);
+  return true;
+}
+
+// This is called by the framer if it detects a change in version during
+// parsing.
+bool TlsChloExtractor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
+  // This should never be called because we already check versions in
+  // IngestPacket.
+  QUIC_BUG(quic_bug_10855_1) << "Unexpected version mismatch, expected "
+                             << framer_->version() << ", got " << version;
+  return false;
+}
+
+// This is called by the QuicStreamSequencer if it encounters an unrecoverable
+// error that will prevent it from reassembling the crypto stream data.
+void TlsChloExtractor::OnUnrecoverableError(QuicErrorCode error,
+                                            const std::string& details) {
+  HandleUnrecoverableError(absl::StrCat(
+      "Crypto stream error ", QuicErrorCodeToString(error), ": ", details));
+}
+
+void TlsChloExtractor::OnUnrecoverableError(
+    QuicErrorCode error,
+    QuicIetfTransportErrorCodes ietf_error,
+    const std::string& details) {
+  HandleUnrecoverableError(absl::StrCat(
+      "Crypto stream error ", QuicErrorCodeToString(error), "(",
+      QuicIetfTransportErrorCodeString(ietf_error), "): ", details));
+}
+
+// This is called by the framer if it sees a CRYPTO frame during parsing.
+bool TlsChloExtractor::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  if (frame.level != ENCRYPTION_INITIAL) {
+    // Since we drop non-INITIAL packets in OnUnauthenticatedPublicHeader,
+    // we should never receive any CRYPTO frames at other encryption levels.
+    QUIC_BUG(quic_bug_10855_2) << "Parsed bad-level CRYPTO frame " << frame;
+    return false;
+  }
+  // parsed_crypto_frame_in_this_packet_ is checked in IngestPacket to allow
+  // advancing our state to track the difference between single-packet CHLO
+  // and multi-packet CHLO.
+  parsed_crypto_frame_in_this_packet_ = true;
+  crypto_stream_sequencer_.OnCryptoFrame(frame);
+  return true;
+}
+
+// Called by the QuicStreamSequencer when it receives a CRYPTO frame that
+// advances the amount of contiguous data we now have starting from offset 0.
+void TlsChloExtractor::OnDataAvailable() {
+  // Lazily set up BoringSSL handle.
+  SetupSslHandle();
+
+  // Get data from the stream sequencer and pass it to BoringSSL.
+  struct iovec iov;
+  while (crypto_stream_sequencer_.GetReadableRegion(&iov)) {
+    const int rv = SSL_provide_quic_data(
+        ssl_.get(), ssl_encryption_initial,
+        reinterpret_cast<const uint8_t*>(iov.iov_base), iov.iov_len);
+    if (rv != 1) {
+      HandleUnrecoverableError("SSL_provide_quic_data failed");
+      return;
+    }
+    crypto_stream_sequencer_.MarkConsumed(iov.iov_len);
+  }
+
+  // Instruct BoringSSL to attempt parsing a full CHLO from the provided data.
+  // We ignore the return value since we know the handshake is going to fail
+  // because we explicitly cancel processing once we've parsed the CHLO.
+  (void)SSL_do_handshake(ssl_.get());
+}
+
+// static
+TlsChloExtractor* TlsChloExtractor::GetInstanceFromSSL(SSL* ssl) {
+  std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
+  int ex_data_index = shared_handles.second;
+  return reinterpret_cast<TlsChloExtractor*>(
+      SSL_get_ex_data(ssl, ex_data_index));
+}
+
+// static
+int TlsChloExtractor::SetReadSecretCallback(
+    SSL* ssl,
+    enum ssl_encryption_level_t /*level*/,
+    const SSL_CIPHER* /*cipher*/,
+    const uint8_t* /*secret*/,
+    size_t /*secret_length*/) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetReadSecretCallback");
+  return 0;
+}
+
+// static
+int TlsChloExtractor::SetWriteSecretCallback(
+    SSL* ssl,
+    enum ssl_encryption_level_t /*level*/,
+    const SSL_CIPHER* /*cipher*/,
+    const uint8_t* /*secret*/,
+    size_t /*secret_length*/) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("SetWriteSecretCallback");
+  return 0;
+}
+
+// static
+int TlsChloExtractor::WriteMessageCallback(
+    SSL* ssl,
+    enum ssl_encryption_level_t /*level*/,
+    const uint8_t* /*data*/,
+    size_t /*len*/) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("WriteMessageCallback");
+  return 0;
+}
+
+// static
+int TlsChloExtractor::FlushFlightCallback(SSL* ssl) {
+  GetInstanceFromSSL(ssl)->HandleUnexpectedCallback("FlushFlightCallback");
+  return 0;
+}
+
+void TlsChloExtractor::HandleUnexpectedCallback(
+    const std::string& callback_name) {
+  std::string error_details =
+      absl::StrCat("Unexpected callback ", callback_name);
+  QUIC_BUG(quic_bug_10855_3) << error_details;
+  HandleUnrecoverableError(error_details);
+}
+
+// static
+int TlsChloExtractor::SendAlertCallback(SSL* ssl,
+                                        enum ssl_encryption_level_t /*level*/,
+                                        uint8_t desc) {
+  GetInstanceFromSSL(ssl)->SendAlert(desc);
+  return 0;
+}
+
+void TlsChloExtractor::SendAlert(uint8_t tls_alert_value) {
+  if (tls_alert_value == SSL3_AD_HANDSHAKE_FAILURE && HasParsedFullChlo()) {
+    // This is the most common scenario. Since we return an error from
+    // SelectCertCallback in order to cancel further processing, BoringSSL will
+    // try to send this alert to tell the client that the handshake failed.
+    return;
+  }
+  HandleUnrecoverableError(absl::StrCat(
+      "BoringSSL attempted to send alert ", static_cast<int>(tls_alert_value),
+      " ", SSL_alert_desc_string_long(tls_alert_value)));
+}
+
+// static
+enum ssl_select_cert_result_t TlsChloExtractor::SelectCertCallback(
+    const SSL_CLIENT_HELLO* client_hello) {
+  GetInstanceFromSSL(client_hello->ssl)->HandleParsedChlo(client_hello);
+  // Always return an error to cancel any further processing in BoringSSL.
+  return ssl_select_cert_error;
+}
+
+// Extracts the server name and ALPN from the parsed ClientHello.
+void TlsChloExtractor::HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello) {
+  const char* server_name =
+      SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name);
+  if (server_name) {
+    server_name_ = std::string(server_name);
+  }
+
+  resumption_attempted_ =
+      HasExtension(client_hello, TLSEXT_TYPE_pre_shared_key);
+  early_data_attempted_ = HasExtension(client_hello, TLSEXT_TYPE_early_data);
+
+  const uint8_t* alpn_data;
+  size_t alpn_len;
+  int rv = SSL_early_callback_ctx_extension_get(
+      client_hello, TLSEXT_TYPE_application_layer_protocol_negotiation,
+      &alpn_data, &alpn_len);
+  if (rv == 1) {
+    QuicDataReader alpns_reader(reinterpret_cast<const char*>(alpn_data),
+                                alpn_len);
+    absl::string_view alpns_payload;
+    if (!alpns_reader.ReadStringPiece16(&alpns_payload)) {
+      HandleUnrecoverableError("Failed to read alpns_payload");
+      return;
+    }
+    QuicDataReader alpns_payload_reader(alpns_payload);
+    while (!alpns_payload_reader.IsDoneReading()) {
+      absl::string_view alpn_payload;
+      if (!alpns_payload_reader.ReadStringPiece8(&alpn_payload)) {
+        HandleUnrecoverableError("Failed to read alpn_payload");
+        return;
+      }
+      alpns_.emplace_back(std::string(alpn_payload));
+    }
+  }
+
+  // Update our state now that we've parsed a full CHLO.
+  if (state_ == State::kInitial) {
+    state_ = State::kParsedFullSinglePacketChlo;
+  } else if (state_ == State::kParsedPartialChloFragment) {
+    state_ = State::kParsedFullMultiPacketChlo;
+  } else {
+    QUIC_BUG(quic_bug_10855_4)
+        << "Unexpected state on successful parse " << StateToString(state_);
+  }
+}
+
+// static
+std::pair<SSL_CTX*, int> TlsChloExtractor::GetSharedSslHandles() {
+  // Use a lambda to benefit from C++11 guarantee that static variables are
+  // initialized lazily in a thread-safe manner. |shared_handles| is therefore
+  // guaranteed to be initialized exactly once and never destructed.
+  static std::pair<SSL_CTX*, int>* shared_handles = []() {
+    CRYPTO_library_init();
+    SSL_CTX* ssl_ctx = SSL_CTX_new(TLS_with_buffers_method());
+    SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
+    SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
+    static const SSL_QUIC_METHOD kQuicCallbacks{
+        TlsChloExtractor::SetReadSecretCallback,
+        TlsChloExtractor::SetWriteSecretCallback,
+        TlsChloExtractor::WriteMessageCallback,
+        TlsChloExtractor::FlushFlightCallback,
+        TlsChloExtractor::SendAlertCallback};
+    SSL_CTX_set_quic_method(ssl_ctx, &kQuicCallbacks);
+    SSL_CTX_set_select_certificate_cb(ssl_ctx,
+                                      TlsChloExtractor::SelectCertCallback);
+    int ex_data_index =
+        SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
+    return new std::pair<SSL_CTX*, int>(ssl_ctx, ex_data_index);
+  }();
+  return *shared_handles;
+}
+
+// Sets up the per-instance SSL handle needed by BoringSSL.
+void TlsChloExtractor::SetupSslHandle() {
+  if (ssl_) {
+    // Handles have already been set up.
+    return;
+  }
+
+  std::pair<SSL_CTX*, int> shared_handles = GetSharedSslHandles();
+  SSL_CTX* ssl_ctx = shared_handles.first;
+  int ex_data_index = shared_handles.second;
+
+  ssl_ = bssl::UniquePtr<SSL>(SSL_new(ssl_ctx));
+  const int rv = SSL_set_ex_data(ssl_.get(), ex_data_index, this);
+  QUICHE_CHECK_EQ(rv, 1) << "Internal allocation failure in SSL_set_ex_data";
+  SSL_set_accept_state(ssl_.get());
+
+  // Make sure we use the right TLS extension codepoint.
+  int use_legacy_extension = 0;
+  if (framer_->version().UsesLegacyTlsExtension()) {
+    use_legacy_extension = 1;
+  }
+  SSL_set_quic_use_legacy_codepoint(ssl_.get(), use_legacy_extension);
+}
+
+// Called by other methods to record any unrecoverable failures they experience.
+void TlsChloExtractor::HandleUnrecoverableError(
+    const std::string& error_details) {
+  if (HasParsedFullChlo()) {
+    // Ignore errors if we've parsed everything successfully.
+    QUIC_DLOG(ERROR) << "Ignoring error: " << error_details;
+    return;
+  }
+  QUIC_DLOG(ERROR) << "Handling error: " << error_details;
+
+  state_ = State::kUnrecoverableFailure;
+
+  if (error_details_.empty()) {
+    error_details_ = error_details;
+  } else {
+    error_details_ = absl::StrCat(error_details_, "; ", error_details);
+  }
+}
+
+// static
+std::string TlsChloExtractor::StateToString(State state) {
+  switch (state) {
+    case State::kInitial:
+      return "Initial";
+    case State::kParsedFullSinglePacketChlo:
+      return "ParsedFullSinglePacketChlo";
+    case State::kParsedFullMultiPacketChlo:
+      return "ParsedFullMultiPacketChlo";
+    case State::kParsedPartialChloFragment:
+      return "ParsedPartialChloFragment";
+    case State::kUnrecoverableFailure:
+      return "UnrecoverableFailure";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(state), ")");
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const TlsChloExtractor::State& state) {
+  os << TlsChloExtractor::StateToString(state);
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_chlo_extractor.h b/quiche/quic/core/tls_chlo_extractor.h
new file mode 100644
index 0000000..876dbd9
--- /dev/null
+++ b/quiche/quic/core/tls_chlo_extractor.h
@@ -0,0 +1,265 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
+#define QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Utility class that allows extracting information from a QUIC-TLS Client
+// Hello. This class creates a QuicFramer to parse the packet, and implements
+// QuicFramerVisitorInterface to access the frames parsed by the QuicFramer. It
+// then uses a QuicStreamSequencer to reassemble the contents of the crypto
+// stream, and implements QuicStreamSequencer::StreamInterface to access the
+// reassembled data.
+class QUIC_NO_EXPORT TlsChloExtractor
+    : public QuicFramerVisitorInterface,
+      public QuicStreamSequencer::StreamInterface {
+ public:
+  TlsChloExtractor();
+  TlsChloExtractor(const TlsChloExtractor&) = delete;
+  TlsChloExtractor(TlsChloExtractor&&);
+  TlsChloExtractor& operator=(const TlsChloExtractor&) = delete;
+  TlsChloExtractor& operator=(TlsChloExtractor&&);
+
+  enum class State : uint8_t {
+    kInitial = 0,
+    kParsedFullSinglePacketChlo = 1,
+    kParsedFullMultiPacketChlo = 2,
+    kParsedPartialChloFragment = 3,
+    kUnrecoverableFailure = 4,
+  };
+
+  State state() const { return state_; }
+  std::vector<std::string> alpns() const { return alpns_; }
+  std::string server_name() const { return server_name_; }
+  bool resumption_attempted() const { return resumption_attempted_; }
+  bool early_data_attempted() const { return early_data_attempted_; }
+
+  // Converts |state| to a human-readable string suitable for logging.
+  static std::string StateToString(State state);
+
+  // Ingests |packet| and attempts to parse out the CHLO.
+  void IngestPacket(const ParsedQuicVersion& version,
+                    const QuicReceivedPacket& packet);
+
+  // Returns whether the ingested packets have allowed parsing a complete CHLO.
+  bool HasParsedFullChlo() const {
+    return state_ == State::kParsedFullSinglePacketChlo ||
+           state_ == State::kParsedFullMultiPacketChlo;
+  }
+
+  // Methods from QuicFramerVisitorInterface.
+  void OnError(QuicFramer* /*framer*/) override {}
+  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
+  void OnPacket() override {}
+  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {}
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {}
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
+    return true;
+  }
+  void OnDecryptedPacket(size_t /*packet_length*/,
+                         EncryptionLevel /*level*/) override {}
+  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
+    return true;
+  }
+  void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {}
+  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
+                             EncryptionLevel /*decryption_level*/,
+                             bool /*has_decryption_key*/) override {}
+  bool OnStreamFrame(const QuicStreamFrame& /*frame*/) override { return true; }
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
+                       QuicTime::Delta /*ack_delay_time*/) override {
+    return true;
+  }
+  bool OnAckRange(QuicPacketNumber /*start*/,
+                  QuicPacketNumber /*end*/) override {
+    return true;
+  }
+  bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
+                      QuicTime /*timestamp*/) override {
+    return true;
+  }
+  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPingFrame(const QuicPingFrame& /*frame*/) override { return true; }
+  bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnConnectionCloseFrame(
+      const QuicConnectionCloseFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnNewConnectionIdFrame(
+      const QuicNewConnectionIdFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) override { return true; }
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnStreamsBlockedFrame(
+      const QuicStreamsBlockedFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnPaddingFrame(const QuicPaddingFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnMessageFrame(const QuicMessageFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) override {
+    return true;
+  }
+  void OnPacketComplete() override {}
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& /*token*/) const override {
+    return true;
+  }
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& /*packet*/) override {}
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  void OnDecryptedFirstPacketInKeyPhase() override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+
+  // Methods from QuicStreamSequencer::StreamInterface.
+  void OnDataAvailable() override;
+  void OnFinRead() override {}
+  void AddBytesConsumed(QuicByteCount /*bytes*/) override {}
+  void ResetWithError(QuicResetStreamError /*error*/) override {}
+  void OnUnrecoverableError(QuicErrorCode error,
+                            const std::string& details) override;
+  void OnUnrecoverableError(QuicErrorCode error,
+                            QuicIetfTransportErrorCodes ietf_error,
+                            const std::string& details) override;
+  QuicStreamId id() const override { return 0; }
+  ParsedQuicVersion version() const override { return framer_->version(); }
+
+ private:
+  // Parses the length of the CHLO message by looking at the first four bytes.
+  // Returns whether we have received enough data to parse the full CHLO now.
+  bool MaybeAttemptToParseChloLength();
+  // Parses the full CHLO message if enough data has been received.
+  void AttemptToParseFullChlo();
+  // Moves to the failed state and records the error details.
+  void HandleUnrecoverableError(const std::string& error_details);
+  // Lazily sets up shared SSL handles if needed.
+  static std::pair<SSL_CTX*, int> GetSharedSslHandles();
+  // Lazily sets up the per-instance SSL handle if needed.
+  void SetupSslHandle();
+  // Extract the TlsChloExtractor instance from |ssl|.
+  static TlsChloExtractor* GetInstanceFromSSL(SSL* ssl);
+
+  // BoringSSL static TLS callbacks.
+  static enum ssl_select_cert_result_t SelectCertCallback(
+      const SSL_CLIENT_HELLO* client_hello);
+  static int SetReadSecretCallback(SSL* ssl,
+                                   enum ssl_encryption_level_t level,
+                                   const SSL_CIPHER* cipher,
+                                   const uint8_t* secret,
+                                   size_t secret_length);
+  static int SetWriteSecretCallback(SSL* ssl,
+                                    enum ssl_encryption_level_t level,
+                                    const SSL_CIPHER* cipher,
+                                    const uint8_t* secret,
+                                    size_t secret_length);
+  static int WriteMessageCallback(SSL* ssl,
+                                  enum ssl_encryption_level_t level,
+                                  const uint8_t* data,
+                                  size_t len);
+  static int FlushFlightCallback(SSL* ssl);
+  static int SendAlertCallback(SSL* ssl,
+                               enum ssl_encryption_level_t level,
+                               uint8_t desc);
+
+  // Called by SelectCertCallback.
+  void HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello);
+  // Called by callbacks that should never be called.
+  void HandleUnexpectedCallback(const std::string& callback_name);
+  // Called by SendAlertCallback.
+  void SendAlert(uint8_t tls_alert_value);
+
+  // Used to parse received packets to extract single frames.
+  std::unique_ptr<QuicFramer> framer_;
+  // Used to reassemble the crypto stream from received CRYPTO frames.
+  QuicStreamSequencer crypto_stream_sequencer_;
+  // BoringSSL handle required to parse the CHLO.
+  bssl::UniquePtr<SSL> ssl_;
+  // State of this TlsChloExtractor.
+  State state_;
+  // Detail string that can be logged in the presence of unrecoverable errors.
+  std::string error_details_;
+  // Whether a CRYPTO frame was parsed in this packet.
+  bool parsed_crypto_frame_in_this_packet_;
+  // Array of ALPNs parsed from the CHLO.
+  std::vector<std::string> alpns_;
+  // SNI parsed from the CHLO.
+  std::string server_name_;
+  // Whether resumption is attempted from the CHLO, indicated by the
+  // 'pre_shared_key' TLS extension.
+  bool resumption_attempted_ = false;
+  // Whether early data is attempted from the CHLO, indicated by the
+  // 'early_data' TLS extension.
+  bool early_data_attempted_ = false;
+};
+
+// Convenience method to facilitate logging TlsChloExtractor::State.
+QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
+                                        const TlsChloExtractor::State& state);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_
diff --git a/quiche/quic/core/tls_chlo_extractor_test.cc b/quiche/quic/core/tls_chlo_extractor_test.cc
new file mode 100644
index 0000000..51e6a9a
--- /dev/null
+++ b/quiche/quic/core/tls_chlo_extractor_test.cc
@@ -0,0 +1,253 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/tls_chlo_extractor.h"
+
+#include <memory>
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/first_flight.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::AnyNumber;
+
+class TlsChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+  TlsChloExtractorTest() : version_(GetParam()), server_id_(TestServerId()) {}
+
+  void Initialize() { packets_ = GetFirstFlightOfPackets(version_, config_); }
+  void Initialize(std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
+    packets_ = GetFirstFlightOfPackets(version_, config_, TestConnectionId(),
+                                       EmptyQuicConnectionId(),
+                                       std::move(crypto_config));
+  }
+
+  // Perform a full handshake in order to insert a SSL_SESSION into
+  // crypto_config->session_cache(), which can be used by a TLS resumption.
+  void PerformFullHandshake(QuicCryptoClientConfig* crypto_config) const {
+    ASSERT_NE(crypto_config->session_cache(), nullptr);
+    MockQuicConnectionHelper client_helper, server_helper;
+    MockAlarmFactory alarm_factory;
+    ParsedQuicVersionVector supported_versions = {version_};
+    PacketSavingConnection* client_connection =
+        new PacketSavingConnection(&client_helper, &alarm_factory,
+                                   Perspective::IS_CLIENT, supported_versions);
+    // Advance the time, because timers do not like uninitialized times.
+    client_connection->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    QuicClientPushPromiseIndex push_promise_index;
+    QuicSpdyClientSession client_session(config_, supported_versions,
+                                         client_connection, server_id_,
+                                         crypto_config, &push_promise_index);
+    client_session.Initialize();
+
+    std::unique_ptr<QuicCryptoServerConfig> server_crypto_config =
+        crypto_test_utils::CryptoServerConfigForTesting();
+    QuicConfig server_config;
+
+    EXPECT_CALL(*client_connection, SendCryptoData(_, _, _)).Times(AnyNumber());
+    client_session.GetMutableCryptoStream()->CryptoConnect();
+
+    crypto_test_utils::HandshakeWithFakeServer(
+        &server_config, server_crypto_config.get(), &server_helper,
+        &alarm_factory, client_connection,
+        client_session.GetMutableCryptoStream(),
+        AlpnForVersion(client_connection->version()));
+
+    // For some reason, the test client can not receive the server settings and
+    // the SSL_SESSION will not be inserted to client's session_cache. We create
+    // a dummy settings and call SetServerApplicationStateForResumption manually
+    // to ensure the SSL_SESSION is cached.
+    // TODO(wub): Fix crypto_test_utils::HandshakeWithFakeServer to make sure a
+    // SSL_SESSION is cached at the client, and remove the rest of the function.
+    SettingsFrame server_settings;
+    server_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
+        kDefaultQpackMaxDynamicTableCapacity;
+    std::unique_ptr<char[]> buffer;
+    uint64_t length =
+        HttpEncoder::SerializeSettingsFrame(server_settings, &buffer);
+    client_session.GetMutableCryptoStream()
+        ->SetServerApplicationStateForResumption(
+            std::make_unique<ApplicationState>(buffer.get(),
+                                               buffer.get() + length));
+  }
+
+  void IngestPackets() {
+    for (const std::unique_ptr<QuicReceivedPacket>& packet : packets_) {
+      ReceivedPacketInfo packet_info(
+          QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+          QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packet);
+      std::string detailed_error;
+      absl::optional<absl::string_view> retry_token;
+      const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+          *packet, /*expected_destination_connection_id_length=*/0,
+          &packet_info.form, &packet_info.long_packet_type,
+          &packet_info.version_flag, &packet_info.use_length_prefix,
+          &packet_info.version_label, &packet_info.version,
+          &packet_info.destination_connection_id,
+          &packet_info.source_connection_id, &retry_token, &detailed_error);
+      ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+      tls_chlo_extractor_.IngestPacket(packet_info.version, packet_info.packet);
+    }
+    packets_.clear();
+  }
+
+  void ValidateChloDetails() {
+    EXPECT_TRUE(tls_chlo_extractor_.HasParsedFullChlo());
+    std::vector<std::string> alpns = tls_chlo_extractor_.alpns();
+    ASSERT_EQ(alpns.size(), 1u);
+    EXPECT_EQ(alpns[0], AlpnForVersion(version_));
+    EXPECT_EQ(tls_chlo_extractor_.server_name(), TestHostname());
+  }
+
+  void IncreaseSizeOfChlo() {
+    // Add a 2000-byte custom parameter to increase the length of the CHLO.
+    constexpr auto kCustomParameterId =
+        static_cast<TransportParameters::TransportParameterId>(0xff33);
+    std::string kCustomParameterValue(2000, '-');
+    config_.custom_transport_parameters_to_send()[kCustomParameterId] =
+        kCustomParameterValue;
+  }
+
+  ParsedQuicVersion version_;
+  QuicServerId server_id_;
+  TlsChloExtractor tls_chlo_extractor_;
+  QuicConfig config_;
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TlsChloExtractorTests,
+                         TlsChloExtractorTest,
+                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TlsChloExtractorTest, Simple) {
+  Initialize();
+  EXPECT_EQ(packets_.size(), 1u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
+  EXPECT_FALSE(tls_chlo_extractor_.resumption_attempted());
+  EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
+}
+
+TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ResumptionOnly) {
+  auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
+      crypto_test_utils::ProofVerifierForTesting(),
+      std::make_unique<SimpleSessionCache>());
+  PerformFullHandshake(crypto_client_config.get());
+
+  SSL_CTX_set_early_data_enabled(crypto_client_config->ssl_ctx(), 0);
+  Initialize(std::move(crypto_client_config));
+  EXPECT_GE(packets_.size(), 1u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
+  EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
+  EXPECT_FALSE(tls_chlo_extractor_.early_data_attempted());
+}
+
+TEST_P(TlsChloExtractorTest, TlsExtentionInfo_ZeroRtt) {
+  auto crypto_client_config = std::make_unique<QuicCryptoClientConfig>(
+      crypto_test_utils::ProofVerifierForTesting(),
+      std::make_unique<SimpleSessionCache>());
+  PerformFullHandshake(crypto_client_config.get());
+
+  IncreaseSizeOfChlo();
+  Initialize(std::move(crypto_client_config));
+  EXPECT_GE(packets_.size(), 1u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+  EXPECT_TRUE(tls_chlo_extractor_.resumption_attempted());
+  EXPECT_TRUE(tls_chlo_extractor_.early_data_attempted());
+}
+
+TEST_P(TlsChloExtractorTest, MultiPacket) {
+  IncreaseSizeOfChlo();
+  Initialize();
+  EXPECT_EQ(packets_.size(), 2u);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+}
+
+TEST_P(TlsChloExtractorTest, MultiPacketReordered) {
+  IncreaseSizeOfChlo();
+  Initialize();
+  ASSERT_EQ(packets_.size(), 2u);
+  // Artifically reorder both packets.
+  std::swap(packets_[0], packets_[1]);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+}
+
+TEST_P(TlsChloExtractorTest, MoveAssignment) {
+  Initialize();
+  EXPECT_EQ(packets_.size(), 1u);
+  TlsChloExtractor other_extractor;
+  tls_chlo_extractor_ = std::move(other_extractor);
+  IngestPackets();
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullSinglePacketChlo);
+}
+
+TEST_P(TlsChloExtractorTest, MoveAssignmentBetweenPackets) {
+  IncreaseSizeOfChlo();
+  Initialize();
+  ASSERT_EQ(packets_.size(), 2u);
+  TlsChloExtractor other_extractor;
+
+  // Have |other_extractor| parse the first packet.
+  ReceivedPacketInfo packet_info(
+      QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+      QuicSocketAddress(TestPeerIPAddress(), kTestPort), *packets_[0]);
+  std::string detailed_error;
+  absl::optional<absl::string_view> retry_token;
+  const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      *packets_[0], /*expected_destination_connection_id_length=*/0,
+      &packet_info.form, &packet_info.long_packet_type,
+      &packet_info.version_flag, &packet_info.use_length_prefix,
+      &packet_info.version_label, &packet_info.version,
+      &packet_info.destination_connection_id, &packet_info.source_connection_id,
+      &retry_token, &detailed_error);
+  ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+  other_extractor.IngestPacket(packet_info.version, packet_info.packet);
+  // Remove the first packet from the list.
+  packets_.erase(packets_.begin());
+  EXPECT_EQ(packets_.size(), 1u);
+
+  // Move the extractor.
+  tls_chlo_extractor_ = std::move(other_extractor);
+
+  // Have |tls_chlo_extractor_| parse the second packet.
+  IngestPackets();
+
+  ValidateChloDetails();
+  EXPECT_EQ(tls_chlo_extractor_.state(),
+            TlsChloExtractor::State::kParsedFullMultiPacketChlo);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/tls_client_handshaker.cc b/quiche/quic/core/tls_client_handshaker.cc
new file mode 100644
index 0000000..641dcc5
--- /dev/null
+++ b/quiche/quic/core/tls_client_handshaker.cc
@@ -0,0 +1,649 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/tls_client_handshaker.h"
+
+#include <cstring>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+TlsClientHandshaker::TlsClientHandshaker(
+    const QuicServerId& server_id,
+    QuicCryptoStream* stream,
+    QuicSession* session,
+    std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    QuicCryptoClientStream::ProofHandler* proof_handler,
+    bool has_application_state)
+    : TlsHandshaker(stream, session),
+      session_(session),
+      server_id_(server_id),
+      proof_verifier_(crypto_config->proof_verifier()),
+      verify_context_(std::move(verify_context)),
+      proof_handler_(proof_handler),
+      session_cache_(crypto_config->session_cache()),
+      user_agent_id_(crypto_config->user_agent_id()),
+      pre_shared_key_(crypto_config->pre_shared_key()),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
+      has_application_state_(has_application_state),
+      tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()) {
+  if (crypto_config->tls_signature_algorithms().has_value()) {
+    SSL_set1_sigalgs_list(ssl(),
+                          crypto_config->tls_signature_algorithms()->c_str());
+  }
+  if (crypto_config->proof_source() != nullptr) {
+    const ClientProofSource::CertAndKey* cert_and_key =
+        crypto_config->proof_source()->GetCertAndKey(server_id.host());
+    if (cert_and_key != nullptr) {
+      QUIC_DVLOG(1) << "Setting client cert and key for " << server_id.host();
+      tls_connection_.SetCertChain(cert_and_key->chain->ToCryptoBuffers().value,
+                                   cert_and_key->private_key.private_key());
+    }
+  }
+}
+
+TlsClientHandshaker::~TlsClientHandshaker() {}
+
+bool TlsClientHandshaker::CryptoConnect() {
+  if (!pre_shared_key_.empty()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    std::string error_details =
+        "QUIC client pre-shared keys not yet supported with TLS";
+    QUIC_BUG(quic_bug_10576_1) << error_details;
+    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
+    return false;
+  }
+
+  // Make sure we use the right TLS extension codepoint.
+  int use_legacy_extension = 0;
+  if (session()->version().UsesLegacyTlsExtension()) {
+    use_legacy_extension = 1;
+  }
+  SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
+
+  // TODO(b/193650832) Add SetFromConfig to QUIC handshakers and remove reliance
+  // on session pointer.
+  const bool permutes_tls_extensions = session()->permutes_tls_extensions();
+  if (!permutes_tls_extensions) {
+    QUIC_DLOG(INFO) << "Disabling TLS extension permutation";
+  }
+#if BORINGSSL_API_VERSION >= 16
+  // Ask BoringSSL to randomize the order of TLS extensions.
+  SSL_set_permute_extensions(ssl(), permutes_tls_extensions);
+#endif  // BORINGSSL_API_VERSION
+
+  // Set the SNI to send, if any.
+  SSL_set_connect_state(ssl());
+  if (QUIC_DLOG_INFO_IS_ON() &&
+      !QuicHostnameUtils::IsValidSNI(server_id_.host())) {
+    QUIC_DLOG(INFO) << "Client configured with invalid hostname \""
+                    << server_id_.host() << "\", not sending as SNI";
+  }
+  if (!server_id_.host().empty() &&
+      (QuicHostnameUtils::IsValidSNI(server_id_.host()) ||
+       allow_invalid_sni_for_tests_) &&
+      SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
+    return false;
+  }
+
+  if (!SetAlpn()) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
+    return false;
+  }
+
+  // Set the Transport Parameters to send in the ClientHello
+  if (!SetTransportParameters()) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Client failed to set Transport Parameters");
+    return false;
+  }
+
+  // Set a session to resume, if there is one.
+  if (session_cache_) {
+    cached_state_ = session_cache_->Lookup(
+        server_id_, session()->GetClock()->WallNow(), SSL_get_SSL_CTX(ssl()));
+  }
+  if (cached_state_) {
+    SSL_set_session(ssl(), cached_state_->tls_session.get());
+    if (!cached_state_->token.empty()) {
+      session()->SetSourceAddressTokenToSend(cached_state_->token);
+    }
+  }
+
+  // Start the handshake.
+  AdvanceHandshake();
+  return session()->connection()->connected();
+}
+
+bool TlsClientHandshaker::PrepareZeroRttConfig(
+    QuicResumptionState* cached_state) {
+  std::string error_details;
+  if (!cached_state->transport_params ||
+      handshaker_delegate()->ProcessTransportParameters(
+          *(cached_state->transport_params),
+          /*is_resumption = */ true, &error_details) != QUIC_NO_ERROR) {
+    QUIC_BUG(quic_bug_10576_2)
+        << "Unable to parse cached transport parameters.";
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Client failed to parse cached Transport Parameters.");
+    return false;
+  }
+
+  session()->connection()->OnTransportParametersResumed(
+      *(cached_state->transport_params));
+  session()->OnConfigNegotiated();
+
+  if (has_application_state_) {
+    if (!cached_state->application_state ||
+        !session()->ResumeApplicationState(
+            cached_state->application_state.get())) {
+      QUIC_BUG(quic_bug_10576_3) << "Unable to parse cached application state.";
+      CloseConnection(QUIC_HANDSHAKE_FAILED,
+                      "Client failed to parse cached application state.");
+      return false;
+    }
+  }
+  return true;
+}
+
+static bool IsValidAlpn(const std::string& alpn_string) {
+  return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
+}
+
+bool TlsClientHandshaker::SetAlpn() {
+  std::vector<std::string> alpns = session()->GetAlpnsToOffer();
+  if (alpns.empty()) {
+    if (allow_empty_alpn_for_tests_) {
+      return true;
+    }
+
+    QUIC_BUG(quic_bug_10576_4) << "ALPN missing";
+    return false;
+  }
+  if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
+    QUIC_BUG(quic_bug_10576_5) << "ALPN too long";
+    return false;
+  }
+
+  // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
+  // strings.
+  uint8_t alpn[1024];
+  QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
+  bool success = true;
+  for (const std::string& alpn_string : alpns) {
+    success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
+              alpn_writer.WriteStringPiece(alpn_string);
+  }
+  success =
+      success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
+  if (!success) {
+    QUIC_BUG(quic_bug_10576_6)
+        << "Failed to set ALPN: "
+        << quiche::QuicheTextUtils::HexDump(
+               absl::string_view(alpn_writer.data(), alpn_writer.length()));
+    return false;
+  }
+
+  // Enable ALPS only for versions that use HTTP/3 frames.
+  for (const std::string& alpn_string : alpns) {
+    for (const ParsedQuicVersion& version : session()->supported_versions()) {
+      if (!version.UsesHttp3() || AlpnForVersion(version) != alpn_string) {
+        continue;
+      }
+      if (SSL_add_application_settings(
+              ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
+              alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
+        QUIC_BUG(quic_bug_10576_7) << "Failed to enable ALPS.";
+        return false;
+      }
+      break;
+    }
+  }
+
+  QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
+  return true;
+}
+
+bool TlsClientHandshaker::SetTransportParameters() {
+  TransportParameters params;
+  params.perspective = Perspective::IS_CLIENT;
+  params.legacy_version_information =
+      TransportParameters::LegacyVersionInformation();
+  params.legacy_version_information.value().version =
+      CreateQuicVersionLabel(session()->supported_versions().front());
+  params.version_information = TransportParameters::VersionInformation();
+  const QuicVersionLabel version = CreateQuicVersionLabel(session()->version());
+  params.version_information.value().chosen_version = version;
+  params.version_information.value().other_versions.push_back(version);
+
+  if (!handshaker_delegate()->FillTransportParameters(&params)) {
+    return false;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersSent(params);
+
+  std::vector<uint8_t> param_bytes;
+  return SerializeTransportParameters(session()->connection()->version(),
+                                      params, &param_bytes) &&
+         SSL_set_quic_transport_params(ssl(), param_bytes.data(),
+                                       param_bytes.size()) == 1;
+}
+
+bool TlsClientHandshaker::ProcessTransportParameters(
+    std::string* error_details) {
+  received_transport_params_ = std::make_unique<TransportParameters>();
+  const uint8_t* param_bytes;
+  size_t param_bytes_len;
+  SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
+  if (param_bytes_len == 0) {
+    *error_details = "Server's transport parameters are missing";
+    return false;
+  }
+  std::string parse_error_details;
+  if (!ParseTransportParameters(
+          session()->connection()->version(), Perspective::IS_SERVER,
+          param_bytes, param_bytes_len, received_transport_params_.get(),
+          &parse_error_details)) {
+    QUICHE_DCHECK(!parse_error_details.empty());
+    *error_details =
+        "Unable to parse server's transport parameters: " + parse_error_details;
+    return false;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersReceived(
+      *received_transport_params_);
+
+  if (received_transport_params_->legacy_version_information.has_value()) {
+    if (received_transport_params_->legacy_version_information.value()
+            .version !=
+        CreateQuicVersionLabel(session()->connection()->version())) {
+      *error_details = "Version mismatch detected";
+      return false;
+    }
+    if (CryptoUtils::ValidateServerHelloVersions(
+            received_transport_params_->legacy_version_information.value()
+                .supported_versions,
+            session()->connection()->server_supported_versions(),
+            error_details) != QUIC_NO_ERROR) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+  }
+  if (received_transport_params_->version_information.has_value()) {
+    if (!CryptoUtils::ValidateChosenVersion(
+            received_transport_params_->version_information.value()
+                .chosen_version,
+            session()->version(), error_details)) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+    if (!CryptoUtils::CryptoUtils::ValidateServerVersions(
+            received_transport_params_->version_information.value()
+                .other_versions,
+            session()->version(),
+            session()->client_original_supported_versions(), error_details)) {
+      QUICHE_DCHECK(!error_details->empty());
+      return false;
+    }
+  }
+
+  if (handshaker_delegate()->ProcessTransportParameters(
+          *received_transport_params_, /* is_resumption = */ false,
+          error_details) != QUIC_NO_ERROR) {
+    QUICHE_DCHECK(!error_details->empty());
+    return false;
+  }
+
+  session()->OnConfigNegotiated();
+  if (is_connection_closed()) {
+    *error_details =
+        "Session closed the connection when parsing negotiated config.";
+    return false;
+  }
+  return true;
+}
+
+int TlsClientHandshaker::num_sent_client_hellos() const {
+  return 0;
+}
+
+bool TlsClientHandshaker::IsResumption() const {
+  QUIC_BUG_IF(quic_bug_12736_1, !one_rtt_keys_available());
+  return SSL_session_reused(ssl()) == 1;
+}
+
+bool TlsClientHandshaker::EarlyDataAccepted() const {
+  QUIC_BUG_IF(quic_bug_12736_2, !one_rtt_keys_available());
+  return SSL_early_data_accepted(ssl()) == 1;
+}
+
+ssl_early_data_reason_t TlsClientHandshaker::EarlyDataReason() const {
+  return TlsHandshaker::EarlyDataReason();
+}
+
+bool TlsClientHandshaker::ReceivedInchoateReject() const {
+  QUIC_BUG_IF(quic_bug_12736_3, !one_rtt_keys_available());
+  // REJ messages are a QUIC crypto feature, so TLS always returns false.
+  return false;
+}
+
+int TlsClientHandshaker::num_scup_messages_received() const {
+  // SCUP messages aren't sent or received when using the TLS handshake.
+  return 0;
+}
+
+std::string TlsClientHandshaker::chlo_hash() const {
+  return "";
+}
+
+bool TlsClientHandshaker::ExportKeyingMaterial(absl::string_view label,
+                                               absl::string_view context,
+                                               size_t result_len,
+                                               std::string* result) {
+  return ExportKeyingMaterialForLabel(label, context, result_len, result);
+}
+
+bool TlsClientHandshaker::encryption_established() const {
+  return encryption_established_;
+}
+
+bool TlsClientHandshaker::one_rtt_keys_available() const {
+  return state_ >= HANDSHAKE_COMPLETE;
+}
+
+const QuicCryptoNegotiatedParameters&
+TlsClientHandshaker::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
+  return TlsHandshaker::crypto_message_parser();
+}
+
+HandshakeState TlsClientHandshaker::GetHandshakeState() const {
+  return state_;
+}
+
+size_t TlsClientHandshaker::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return TlsHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+TlsClientHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter>
+TlsClientHandshaker::CreateCurrentOneRttEncrypter() {
+  return TlsHandshaker::CreateCurrentOneRttEncrypter();
+}
+
+void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
+  OnHandshakeConfirmed();
+}
+
+void TlsClientHandshaker::OnHandshakePacketSent() {
+  if (initial_keys_dropped_) {
+    return;
+  }
+  initial_keys_dropped_ = true;
+  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+}
+
+void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode error,
+                                             ConnectionCloseSource source) {
+  TlsHandshaker::OnConnectionClosed(error, source);
+}
+
+void TlsClientHandshaker::OnHandshakeDoneReceived() {
+  if (!one_rtt_keys_available()) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Unexpected handshake done received");
+    return;
+  }
+  OnHandshakeConfirmed();
+}
+
+void TlsClientHandshaker::OnNewTokenReceived(absl::string_view token) {
+  if (token.empty()) {
+    return;
+  }
+  if (session_cache_ != nullptr) {
+    session_cache_->OnNewTokenReceived(server_id_, token);
+  }
+}
+
+void TlsClientHandshaker::SetWriteSecret(
+    EncryptionLevel level,
+    const SSL_CIPHER* cipher,
+    const std::vector<uint8_t>& write_secret) {
+  if (is_connection_closed()) {
+    return;
+  }
+  if (level == ENCRYPTION_FORWARD_SECURE || level == ENCRYPTION_ZERO_RTT) {
+    encryption_established_ = true;
+  }
+  TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT);
+  }
+}
+
+void TlsClientHandshaker::OnHandshakeConfirmed() {
+  QUICHE_DCHECK(one_rtt_keys_available());
+  if (state_ >= HANDSHAKE_CONFIRMED) {
+    return;
+  }
+  state_ = HANDSHAKE_CONFIRMED;
+  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
+  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
+}
+
+QuicAsyncStatus TlsClientHandshaker::VerifyCertChain(
+    const std::vector<std::string>& certs,
+    std::string* error_details,
+    std::unique_ptr<ProofVerifyDetails>* details,
+    uint8_t* out_alert,
+    std::unique_ptr<ProofVerifierCallback> callback) {
+  const uint8_t* ocsp_response_raw;
+  size_t ocsp_response_len;
+  SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
+  std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
+                            ocsp_response_len);
+  const uint8_t* sct_list_raw;
+  size_t sct_list_len;
+  SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
+  std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
+                       sct_list_len);
+
+  return proof_verifier_->VerifyCertChain(
+      server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list,
+      verify_context_.get(), error_details, details, out_alert,
+      std::move(callback));
+}
+
+void TlsClientHandshaker::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& verify_details) {
+  proof_handler_->OnProofVerifyDetailsAvailable(verify_details);
+}
+
+void TlsClientHandshaker::FinishHandshake() {
+  FillNegotiatedParams();
+
+  QUICHE_CHECK(!SSL_in_early_data(ssl()));
+
+  QUIC_LOG(INFO) << "Client: handshake finished";
+
+  std::string error_details;
+  if (!ProcessTransportParameters(&error_details)) {
+    QUICHE_DCHECK(!error_details.empty());
+    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
+    return;
+  }
+
+  const uint8_t* alpn_data = nullptr;
+  unsigned alpn_length = 0;
+  SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
+
+  if (alpn_length == 0) {
+    QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
+    // TODO(b/130164908) this should send no_application_protocol
+    // instead of QUIC_HANDSHAKE_FAILED.
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
+    return;
+  }
+
+  std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
+                                   alpn_length);
+  std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
+  if (std::find(offered_alpns.begin(), offered_alpns.end(),
+                received_alpn_string) == offered_alpns.end()) {
+    QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
+                    << received_alpn_string;
+    // TODO(b/130164908) this should send no_application_protocol
+    // instead of QUIC_HANDSHAKE_FAILED.
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
+    return;
+  }
+  session()->OnAlpnSelected(received_alpn_string);
+  QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
+                  << "'";
+
+  // Parse ALPS extension.
+  const uint8_t* alps_data;
+  size_t alps_length;
+  SSL_get0_peer_application_settings(ssl(), &alps_data, &alps_length);
+  if (alps_length > 0) {
+    auto error = session()->OnAlpsData(alps_data, alps_length);
+    if (error) {
+      // Calling CloseConnection() is safe even in case OnAlpsData() has
+      // already closed the connection.
+      CloseConnection(
+          QUIC_HANDSHAKE_FAILED,
+          absl::StrCat("Error processing ALPS data: ", error.value()));
+      return;
+    }
+  }
+
+  state_ = HANDSHAKE_COMPLETE;
+  handshaker_delegate()->OnTlsHandshakeComplete();
+}
+
+void TlsClientHandshaker::OnEnterEarlyData() {
+  QUICHE_DCHECK(SSL_in_early_data(ssl()));
+
+  // TODO(wub): It might be unnecessary to FillNegotiatedParams() at this time,
+  // because we fill it again when handshake completes.
+  FillNegotiatedParams();
+
+  // If we're attempting a 0-RTT handshake, then we need to let the transport
+  // and application know what state to apply to early data.
+  PrepareZeroRttConfig(cached_state_.get());
+}
+
+void TlsClientHandshaker::FillNegotiatedParams() {
+  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+  if (cipher) {
+    crypto_negotiated_params_->cipher_suite =
+        SSL_CIPHER_get_protocol_id(cipher);
+  }
+  crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
+  crypto_negotiated_params_->peer_signature_algorithm =
+      SSL_get_peer_signature_algorithm(ssl());
+}
+
+void TlsClientHandshaker::ProcessPostHandshakeMessage() {
+  int rv = SSL_process_quic_post_handshake(ssl());
+  if (rv != 1) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
+  }
+}
+
+bool TlsClientHandshaker::ShouldCloseConnectionOnUnexpectedError(
+    int ssl_error) {
+  if (ssl_error != SSL_ERROR_EARLY_DATA_REJECTED) {
+    return true;
+  }
+  HandleZeroRttReject();
+  return false;
+}
+
+void TlsClientHandshaker::HandleZeroRttReject() {
+  QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server";
+  QUICHE_DCHECK(session_cache_);
+  // Disable encrytion to block outgoing data until 1-RTT keys are available.
+  encryption_established_ = false;
+  handshaker_delegate()->OnZeroRttRejected(EarlyDataReason());
+  SSL_reset_early_data_reject(ssl());
+  session_cache_->ClearEarlyData(server_id_);
+  AdvanceHandshake();
+}
+
+void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
+  if (!received_transport_params_) {
+    QUIC_BUG(quic_bug_10576_8) << "Transport parameters isn't received";
+    return;
+  }
+  if (session_cache_ == nullptr) {
+    QUIC_DVLOG(1) << "No session cache, not inserting a session";
+    return;
+  }
+  if (has_application_state_ && !received_application_state_) {
+    // Application state is not received yet. cache the sessions.
+    if (cached_tls_sessions_[0] != nullptr) {
+      cached_tls_sessions_[1] = std::move(cached_tls_sessions_[0]);
+    }
+    cached_tls_sessions_[0] = std::move(session);
+    return;
+  }
+  session_cache_->Insert(server_id_, std::move(session),
+                         *received_transport_params_,
+                         received_application_state_.get());
+}
+
+void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
+                                       absl::string_view data) {
+  if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
+    state_ = HANDSHAKE_PROCESSED;
+  }
+  TlsHandshaker::WriteMessage(level, data);
+}
+
+void TlsClientHandshaker::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> application_state) {
+  QUICHE_DCHECK(one_rtt_keys_available());
+  received_application_state_ = std::move(application_state);
+  // At least one tls session is cached before application state is received. So
+  // insert now.
+  if (session_cache_ != nullptr && cached_tls_sessions_[0] != nullptr) {
+    if (cached_tls_sessions_[1] != nullptr) {
+      // Insert the older session first.
+      session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[1]),
+                             *received_transport_params_,
+                             received_application_state_.get());
+    }
+    session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[0]),
+                           *received_transport_params_,
+                           received_application_state_.get());
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_client_handshaker.h b/quiche/quic/core/tls_client_handshaker.h
new file mode 100644
index 0000000..2aa787c
--- /dev/null
+++ b/quiche/quic/core/tls_client_handshaker.h
@@ -0,0 +1,175 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/crypto/tls_client_connection.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/tls_handshaker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
+// TLS 1.3 for the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE TlsClientHandshaker
+    : public TlsHandshaker,
+      public QuicCryptoClientStream::HandshakerInterface,
+      public TlsClientConnection::Delegate {
+ public:
+  // |crypto_config| must outlive TlsClientHandshaker.
+  TlsClientHandshaker(const QuicServerId& server_id,
+                      QuicCryptoStream* stream,
+                      QuicSession* session,
+                      std::unique_ptr<ProofVerifyContext> verify_context,
+                      QuicCryptoClientConfig* crypto_config,
+                      QuicCryptoClientStream::ProofHandler* proof_handler,
+                      bool has_application_state);
+  TlsClientHandshaker(const TlsClientHandshaker&) = delete;
+  TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete;
+
+  ~TlsClientHandshaker() override;
+
+  // From QuicCryptoClientStream::HandshakerInterface
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  bool IsResumption() const override;
+  bool EarlyDataAccepted() const override;
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool ReceivedInchoateReject() const override;
+  int num_scup_messages_received() const override;
+  std::string chlo_hash() const override;
+  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
+                            size_t result_len, std::string* result) override;
+
+  // From QuicCryptoClientStream::HandshakerInterface and TlsHandshaker
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void OnOneRttPacketAcknowledged() override;
+  void OnHandshakePacketSent() override;
+  void OnConnectionClosed(QuicErrorCode error,
+                          ConnectionCloseSource source) override;
+  void OnHandshakeDoneReceived() override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  void SetWriteSecret(EncryptionLevel level,
+                      const SSL_CIPHER* cipher,
+                      const std::vector<uint8_t>& write_secret) override;
+
+  // Override to drop initial keys if trying to write ENCRYPTION_HANDSHAKE data.
+  void WriteMessage(EncryptionLevel level, absl::string_view data) override;
+
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> application_state) override;
+
+  void AllowEmptyAlpnForTests() { allow_empty_alpn_for_tests_ = true; }
+  void AllowInvalidSNIForTests() { allow_invalid_sni_for_tests_ = true; }
+
+  // Make the SSL object from BoringSSL publicly accessible.
+  using TlsHandshaker::ssl;
+
+ protected:
+  const TlsConnection* tls_connection() const override {
+    return &tls_connection_;
+  }
+
+  void FinishHandshake() override;
+  void OnEnterEarlyData() override;
+  void FillNegotiatedParams();
+  void ProcessPostHandshakeMessage() override;
+  bool ShouldCloseConnectionOnUnexpectedError(int ssl_error) override;
+  QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // TlsClientConnection::Delegate implementation:
+  TlsConnection::Delegate* ConnectionDelegate() override { return this; }
+
+ private:
+  bool SetAlpn();
+  bool SetTransportParameters();
+  bool ProcessTransportParameters(std::string* error_details);
+  void HandleZeroRttReject();
+
+  // Called when server completes handshake (i.e., either handshake done is
+  // received or 1-RTT packet gets acknowledged).
+  void OnHandshakeConfirmed();
+
+  void InsertSession(bssl::UniquePtr<SSL_SESSION> session) override;
+
+  bool PrepareZeroRttConfig(QuicResumptionState* cached_state);
+
+  QuicSession* session() { return session_; }
+  QuicSession* session_;
+
+  QuicServerId server_id_;
+
+  // Objects used for verifying the server's certificate chain.
+  // |proof_verifier_| is owned by the caller of TlsHandshaker's constructor.
+  ProofVerifier* proof_verifier_;
+  std::unique_ptr<ProofVerifyContext> verify_context_;
+
+  // Unowned pointer to the proof handler which has the
+  // OnProofVerifyDetailsAvailable callback to use for notifying the result of
+  // certificate verification.
+  QuicCryptoClientStream::ProofHandler* proof_handler_;
+
+  // Used for session resumption. |session_cache_| is owned by the
+  // QuicCryptoClientConfig passed into TlsClientHandshaker's constructor.
+  SessionCache* session_cache_;
+
+  std::string user_agent_id_;
+
+  // Pre-shared key used during the handshake.
+  std::string pre_shared_key_;
+
+  HandshakeState state_ = HANDSHAKE_START;
+  bool encryption_established_ = false;
+  bool initial_keys_dropped_ = false;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+
+  bool allow_empty_alpn_for_tests_ = false;
+  bool allow_invalid_sni_for_tests_ = false;
+
+  const bool has_application_state_;
+  // Contains the state for performing a resumption, if one is attempted. This
+  // will always be non-null if a 0-RTT resumption is attempted.
+  std::unique_ptr<QuicResumptionState> cached_state_;
+
+  TlsClientConnection tls_connection_;
+
+  // If |has_application_state_|, stores the tls session tickets before
+  // application state is received. The latest one is put in the front.
+  bssl::UniquePtr<SSL_SESSION> cached_tls_sessions_[2] = {};
+
+  std::unique_ptr<TransportParameters> received_transport_params_ = nullptr;
+  std::unique_ptr<ApplicationState> received_application_state_ = nullptr;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_CLIENT_HANDSHAKER_H_
diff --git a/quiche/quic/core/tls_client_handshaker_test.cc b/quiche/quic/core/tls_client_handshaker_test.cc
new file mode 100644
index 0000000..e77b7af
--- /dev/null
+++ b/quiche/quic/core/tls_client_handshaker_test.cc
@@ -0,0 +1,712 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include "quiche/quic/tools/fake_proof_verifier.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+using testing::_;
+
+namespace quic {
+namespace test {
+namespace {
+
+constexpr char kServerHostname[] = "test.example.com";
+constexpr uint16_t kServerPort = 443;
+
+// TestProofVerifier wraps ProofVerifierForTesting, except for VerifyCertChain
+// which, if TestProofVerifier is active, always returns QUIC_PENDING. (If this
+// test proof verifier is not active, it delegates VerifyCertChain to the
+// ProofVerifierForTesting.) The pending VerifyCertChain operation can be
+// completed by calling InvokePendingCallback. This allows for testing
+// asynchronous VerifyCertChain operations.
+class TestProofVerifier : public ProofVerifier {
+ public:
+  TestProofVerifier()
+      : verifier_(crypto_test_utils::ProofVerifierForTesting()) {}
+
+  QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion quic_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    return verifier_->VerifyProof(
+        hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
+        signature, context, error_details, details, std::move(callback));
+  }
+
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    if (!active_) {
+      return verifier_->VerifyCertChain(
+          hostname, port, certs, ocsp_response, cert_sct, context,
+          error_details, details, out_alert, std::move(callback));
+    }
+    pending_ops_.push_back(std::make_unique<VerifyChainPendingOp>(
+        hostname, port, certs, ocsp_response, cert_sct, context, error_details,
+        details, out_alert, std::move(callback), verifier_.get()));
+    return QUIC_PENDING;
+  }
+
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    return nullptr;
+  }
+
+  void Activate() { active_ = true; }
+
+  size_t NumPendingCallbacks() const { return pending_ops_.size(); }
+
+  void InvokePendingCallback(size_t n) {
+    ASSERT_GT(NumPendingCallbacks(), n);
+    pending_ops_[n]->Run();
+    auto it = pending_ops_.begin() + n;
+    pending_ops_.erase(it);
+  }
+
+ private:
+  // Implementation of ProofVerifierCallback that fails if the callback is ever
+  // run.
+  class FailingProofVerifierCallback : public ProofVerifierCallback {
+   public:
+    void Run(bool /*ok*/,
+             const std::string& /*error_details*/,
+             std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
+      FAIL();
+    }
+  };
+
+  class VerifyChainPendingOp {
+   public:
+    VerifyChainPendingOp(const std::string& hostname,
+                         const uint16_t port,
+                         const std::vector<std::string>& certs,
+                         const std::string& ocsp_response,
+                         const std::string& cert_sct,
+                         const ProofVerifyContext* context,
+                         std::string* error_details,
+                         std::unique_ptr<ProofVerifyDetails>* details,
+                         uint8_t* out_alert,
+                         std::unique_ptr<ProofVerifierCallback> callback,
+                         ProofVerifier* delegate)
+        : hostname_(hostname),
+          port_(port),
+          certs_(certs),
+          ocsp_response_(ocsp_response),
+          cert_sct_(cert_sct),
+          context_(context),
+          error_details_(error_details),
+          details_(details),
+          out_alert_(out_alert),
+          callback_(std::move(callback)),
+          delegate_(delegate) {}
+
+    void Run() {
+      // TestProofVerifier depends on crypto_test_utils::ProofVerifierForTesting
+      // running synchronously. It passes a FailingProofVerifierCallback and
+      // runs the original callback after asserting that the verification ran
+      // synchronously.
+      QuicAsyncStatus status = delegate_->VerifyCertChain(
+          hostname_, port_, certs_, ocsp_response_, cert_sct_, context_,
+          error_details_, details_, out_alert_,
+          std::make_unique<FailingProofVerifierCallback>());
+      ASSERT_NE(status, QUIC_PENDING);
+      callback_->Run(status == QUIC_SUCCESS, *error_details_, details_);
+    }
+
+   private:
+    std::string hostname_;
+    const uint16_t port_;
+    std::vector<std::string> certs_;
+    std::string ocsp_response_;
+    std::string cert_sct_;
+    const ProofVerifyContext* context_;
+    std::string* error_details_;
+    std::unique_ptr<ProofVerifyDetails>* details_;
+    uint8_t* out_alert_;
+    std::unique_ptr<ProofVerifierCallback> callback_;
+    ProofVerifier* delegate_;
+  };
+
+  std::unique_ptr<ProofVerifier> verifier_;
+  bool active_ = false;
+  std::vector<std::unique_ptr<VerifyChainPendingOp>> pending_ops_;
+};
+
+class TlsClientHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  TlsClientHandshakerTest()
+      : supported_versions_({GetParam()}),
+        server_id_(kServerHostname, kServerPort, false),
+        server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+        std::make_unique<TestProofVerifier>(),
+        std::make_unique<test::SimpleSessionCache>());
+    server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
+    CreateConnection();
+  }
+
+  void CreateSession() {
+    session_ = std::make_unique<TestQuicSpdyClientSession>(
+        connection_, DefaultQuicConfig(), supported_versions_, server_id_,
+        crypto_config_.get());
+    EXPECT_CALL(*session_, GetAlpnsToOffer())
+        .WillRepeatedly(testing::Return(std::vector<std::string>(
+            {AlpnForVersion(connection_->version())})));
+  }
+
+  void CreateConnection() {
+    connection_ =
+        new PacketSavingConnection(&client_helper_, &alarm_factory_,
+                                   Perspective::IS_CLIENT, supported_versions_);
+    // Advance the time, because timers do not like uninitialized times.
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    CreateSession();
+  }
+
+  void CompleteCryptoHandshake() {
+    CompleteCryptoHandshakeWithServerALPN(
+        AlpnForVersion(connection_->version()));
+  }
+
+  void CompleteCryptoHandshakeWithServerALPN(const std::string& alpn) {
+    EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
+        .Times(testing::AnyNumber());
+    stream()->CryptoConnect();
+    QuicConfig config;
+    crypto_test_utils::HandshakeWithFakeServer(
+        &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+        connection_, stream(), alpn);
+  }
+
+  QuicCryptoClientStream* stream() {
+    return session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake server, and all its associated state, for testing.
+  void InitializeFakeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        &server_helper_, &alarm_factory_, server_crypto_config_.get(),
+        &server_compressed_certs_cache_, &server_connection_, &server_session);
+    server_session_.reset(server_session);
+    std::string alpn = AlpnForVersion(connection_->version());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
+          return std::find(alpns.cbegin(), alpns.cend(), alpn);
+        });
+  }
+
+  MockQuicConnectionHelper server_helper_;
+  MockQuicConnectionHelper client_helper_;
+  MockAlarmFactory alarm_factory_;
+  PacketSavingConnection* connection_;
+  ParsedQuicVersionVector supported_versions_;
+  std::unique_ptr<TestQuicSpdyClientSession> session_;
+  QuicServerId server_id_;
+  CryptoHandshakeMessage message_;
+  std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
+
+  // Server state.
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TlsHandshakerTests,
+                         TlsClientHandshakerTest,
+                         ::testing::ValuesIn(AllSupportedVersionsWithTls()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TlsClientHandshakerTest, NotInitiallyConnected) {
+  EXPECT_FALSE(stream()->encryption_established());
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, ConnectedAfterHandshake) {
+  CompleteCryptoHandshake();
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+}
+
+TEST_P(TlsClientHandshakerTest, ConnectionClosedOnTlsError) {
+  // Have client send ClientHello.
+  stream()->CryptoConnect();
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
+
+  // Send a zero-length ServerHello from server to client.
+  char bogus_handshake_message[] = {
+      // Handshake struct (RFC 8446 appendix B.3)
+      2,        // HandshakeType server_hello
+      0, 0, 0,  // uint24 length
+  };
+  stream()->crypto_message_parser()->ProcessInput(
+      absl::string_view(bogus_handshake_message,
+                        ABSL_ARRAYSIZE(bogus_handshake_message)),
+      ENCRYPTION_INITIAL);
+
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, ProofVerifyDetailsAvailableAfterHandshake) {
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
+  stream()->CryptoConnect();
+  QuicConfig config;
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+      connection_, stream(), AlpnForVersion(connection_->version()));
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, HandshakeWithAsyncProofVerifier) {
+  InitializeFakeServer();
+
+  // Enable TestProofVerifier to capture call to VerifyCertChain and run it
+  // asynchronously.
+  TestProofVerifier* proof_verifier =
+      static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
+  proof_verifier->Activate();
+
+  stream()->CryptoConnect();
+  // Exchange handshake messages.
+  std::pair<size_t, size_t> moved_message_counts =
+      crypto_test_utils::AdvanceHandshake(
+          connection_, stream(), 0, server_connection_, server_stream(), 0);
+
+  ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
+  proof_verifier->InvokePendingCallback(0);
+
+  // Exchange more handshake messages.
+  crypto_test_utils::AdvanceHandshake(
+      connection_, stream(), moved_message_counts.first, server_connection_,
+      server_stream(), moved_message_counts.second);
+
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsClientHandshakerTest, Resumption) {
+  // Disable 0-RTT on the server so that we're only testing 1-RTT resumption:
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection
+  CreateConnection();
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_TRUE(stream()->IsResumption());
+}
+
+TEST_P(TlsClientHandshakerTest, ResumptionRejection) {
+  // Disable 0-RTT on the server before the first connection so the client
+  // doesn't attempt a 0-RTT resumption, only a 1-RTT resumption.
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection, but disable resumption on the server.
+  SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
+  CreateConnection();
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(),
+            ssl_early_data_unsupported_for_session);
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRttResumption) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection
+  CreateConnection();
+  // OnConfigNegotiated should be called twice - once when processing saved
+  // 0-RTT transport parameters, and then again when receiving transport
+  // parameters from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
+      .Times(testing::AnyNumber());
+  // Start the second handshake and confirm we have keys before receiving any
+  // messages from the server.
+  stream()->CryptoConnect();
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_NE(stream()->crypto_negotiated_params().cipher_suite, 0);
+  EXPECT_NE(stream()->crypto_negotiated_params().key_exchange_group, 0);
+  EXPECT_NE(stream()->crypto_negotiated_params().peer_signature_algorithm, 0);
+  // Finish the handshake with the server.
+  QuicConfig config;
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+      connection_, stream(), AlpnForVersion(connection_->version()));
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_TRUE(stream()->IsResumption());
+  EXPECT_TRUE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_accepted);
+}
+
+// Regression test for b/186438140.
+TEST_P(TlsClientHandshakerTest, ZeroRttResumptionWithAyncProofVerifier) {
+  // Finish establishing the first connection, so the second connection can
+  // resume.
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection.
+  CreateConnection();
+  InitializeFakeServer();
+  EXPECT_CALL(*session_, OnConfigNegotiated());
+  EXPECT_CALL(*connection_, SendCryptoData(_, _, _))
+      .Times(testing::AnyNumber());
+  // Enable TestProofVerifier to capture the call to VerifyCertChain and run it
+  // asynchronously.
+  TestProofVerifier* proof_verifier =
+      static_cast<TestProofVerifier*>(crypto_config_->proof_verifier());
+  proof_verifier->Activate();
+  // Start the second handshake.
+  stream()->CryptoConnect();
+
+  ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
+
+  // Advance the handshake with the server. Since cert verification has not
+  // finished yet, client cannot derive HANDSHAKE and 1-RTT keys.
+  crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
+                                      server_connection_, server_stream(), 0);
+
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+
+  // Finish cert verification after receiving packets from server.
+  proof_verifier->InvokePendingCallback(0);
+
+  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+  // Verify client has derived HANDSHAKE key.
+  EXPECT_NE(nullptr,
+            QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_HANDSHAKE));
+
+  // Ideally, we should also verify that the process_undecryptable_packets_alarm
+  // is set and processing the undecryptable packets can advance the handshake
+  // to completion. Unfortunately, the test facilities used in this test does
+  // not support queuing and processing undecryptable packets.
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRttRejection) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection, but disable 0-RTT on the server.
+  SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+  CreateConnection();
+
+  // OnConfigNegotiated should be called twice - once when processing saved
+  // 0-RTT transport parameters, and then again when receiving transport
+  // parameters from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
+
+  // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
+  // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
+  // packet retransmission.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
+  }
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    // TODO(b/158027651): change transmission type to
+    // ALL_ZERO_RTT_RETRANSMISSION.
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+  }
+
+  CompleteCryptoHandshake();
+
+  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+  EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_TRUE(stream()->IsResumption());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_peer_declined);
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRttAndResumptionRejection) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection, but disable resumption on the server.
+  SSL_CTX_set_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
+  CreateConnection();
+
+  // OnConfigNegotiated should be called twice - once when processing saved
+  // 0-RTT transport parameters, and then again when receiving transport
+  // parameters from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(2);
+
+  // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
+  // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
+  // packet retransmission.
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
+  }
+  EXPECT_CALL(*connection_,
+              OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+  if (VersionUsesHttp3(session_->transport_version())) {
+    // TODO(b/158027651): change transmission type to
+    // ALL_ZERO_RTT_RETRANSMISSION.
+    EXPECT_CALL(*connection_,
+                OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+  }
+
+  CompleteCryptoHandshake();
+
+  QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+  EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_session_not_resumed);
+}
+
+TEST_P(TlsClientHandshakerTest, ClientSendsNoSNI) {
+  // Reconfigure client to sent an empty server hostname. The crypto config also
+  // needs to be recreated to use a FakeProofVerifier since the server's cert
+  // won't match the empty hostname.
+  server_id_ = QuicServerId("", 443);
+  crypto_config_.reset(new QuicCryptoClientConfig(
+      std::make_unique<FakeProofVerifier>(), nullptr));
+  CreateConnection();
+  InitializeFakeServer();
+
+  stream()->CryptoConnect();
+  crypto_test_utils::CommunicateHandshakeMessages(
+      connection_, stream(), server_connection_, server_stream());
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
+}
+
+TEST_P(TlsClientHandshakerTest, ClientSendingTooManyALPNs) {
+  std::string long_alpn(250, 'A');
+  EXPECT_CALL(*session_, GetAlpnsToOffer())
+      .WillOnce(testing::Return(std::vector<std::string>({
+          long_alpn + "1",
+          long_alpn + "2",
+          long_alpn + "3",
+          long_alpn + "4",
+          long_alpn + "5",
+          long_alpn + "6",
+          long_alpn + "7",
+          long_alpn + "8",
+      })));
+  EXPECT_QUIC_BUG(stream()->CryptoConnect(), "Failed to set ALPN");
+}
+
+TEST_P(TlsClientHandshakerTest, ServerRequiresCustomALPN) {
+  InitializeFakeServer();
+  const std::string kTestAlpn = "An ALPN That Client Did Not Offer";
+  EXPECT_CALL(*server_session_, SelectAlpn(_))
+      .WillOnce([kTestAlpn](const std::vector<absl::string_view>& alpns) {
+        return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
+      });
+
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED,
+                              static_cast<QuicIetfTransportErrorCodes>(
+                                  CRYPTO_ERROR_FIRST + 120),
+                              "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
+                              "no application protocol",
+                              _));
+
+  stream()->CryptoConnect();
+  crypto_test_utils::AdvanceHandshake(connection_, stream(), 0,
+                                      server_connection_, server_stream(), 0);
+
+  EXPECT_FALSE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->encryption_established());
+}
+
+TEST_P(TlsClientHandshakerTest, ZeroRTTNotAttemptedOnALPNChange) {
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->IsResumption());
+
+  // Create a second connection
+  CreateConnection();
+  // Override the ALPN to send on the second connection.
+  const std::string kTestAlpn = "Test ALPN";
+  EXPECT_CALL(*session_, GetAlpnsToOffer())
+      .WillRepeatedly(testing::Return(std::vector<std::string>({kTestAlpn})));
+  // OnConfigNegotiated should only be called once: when transport parameters
+  // are received from the server.
+  EXPECT_CALL(*session_, OnConfigNegotiated()).Times(1);
+
+  CompleteCryptoHandshakeWithServerALPN(kTestAlpn);
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+  EXPECT_FALSE(stream()->EarlyDataAccepted());
+  EXPECT_EQ(stream()->EarlyDataReason(), ssl_early_data_alpn_mismatch);
+}
+
+TEST_P(TlsClientHandshakerTest, InvalidSNI) {
+  // Test that a client will skip sending SNI if configured to send an invalid
+  // hostname. In this case, the inclusion of '!' is invalid.
+  server_id_ = QuicServerId("invalid!.example.com", 443);
+  crypto_config_.reset(new QuicCryptoClientConfig(
+      std::make_unique<FakeProofVerifier>(), nullptr));
+  CreateConnection();
+  InitializeFakeServer();
+
+  stream()->CryptoConnect();
+  crypto_test_utils::CommunicateHandshakeMessages(
+      connection_, stream(), server_connection_, server_stream());
+
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->one_rtt_keys_available());
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, "");
+}
+
+TEST_P(TlsClientHandshakerTest, BadTransportParams) {
+  if (!connection_->version().UsesHttp3()) {
+    return;
+  }
+  // Finish establishing the first connection:
+  CompleteCryptoHandshake();
+
+  // Create a second connection
+  CreateConnection();
+
+  stream()->CryptoConnect();
+  auto* id_manager = QuicSessionPeer::ietf_streamid_manager(session_.get());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            id_manager->max_outgoing_bidirectional_streams());
+  QuicConfig config;
+  config.SetMaxBidirectionalStreamsToSend(
+      config.GetMaxBidirectionalStreamsToSend() - 1);
+
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED, _, _))
+      .WillOnce(testing::Invoke(connection_,
+                                &MockQuicConnection::ReallyCloseConnection));
+  // Close connection will be called again in the handshaker, but this will be
+  // no-op as the connection is already closed.
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
+      connection_, stream(), AlpnForVersion(connection_->version()));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/tls_handshaker.cc b/quiche/quic/core/tls_handshaker.cc
new file mode 100644
index 0000000..1a94775
--- /dev/null
+++ b/quiche/quic/core/tls_handshaker.cc
@@ -0,0 +1,372 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/tls_handshaker.h"
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+
+namespace quic {
+
+#define ENDPOINT (SSL_is_server(ssl()) ? "TlsServer: " : "TlsClient: ")
+
+TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
+    TlsHandshaker* parent)
+    : parent_(parent) {}
+
+TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
+
+void TlsHandshaker::ProofVerifierCallbackImpl::Run(
+    bool ok, const std::string& /*error_details*/,
+    std::unique_ptr<ProofVerifyDetails>* details) {
+  if (parent_ == nullptr) {
+    return;
+  }
+
+  parent_->verify_details_ = std::move(*details);
+  parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
+  parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  parent_->proof_verify_callback_ = nullptr;
+  if (parent_->verify_details_) {
+    parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_);
+  }
+  parent_->AdvanceHandshake();
+}
+
+void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { parent_ = nullptr; }
+
+TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session)
+    : stream_(stream), handshaker_delegate_(session) {}
+
+TlsHandshaker::~TlsHandshaker() {
+  if (proof_verify_callback_) {
+    proof_verify_callback_->Cancel();
+  }
+}
+
+bool TlsHandshaker::ProcessInput(absl::string_view input,
+                                 EncryptionLevel level) {
+  if (parser_error_ != QUIC_NO_ERROR) {
+    return false;
+  }
+  // TODO(nharper): Call SSL_quic_read_level(ssl()) and check whether the
+  // encryption level BoringSSL expects matches the encryption level that we
+  // just received input at. If they mismatch, should ProcessInput return true
+  // or false? If data is for a future encryption level, it should be queued for
+  // later?
+  if (SSL_provide_quic_data(ssl(), TlsConnection::BoringEncryptionLevel(level),
+                            reinterpret_cast<const uint8_t*>(input.data()),
+                            input.size()) != 1) {
+    // SSL_provide_quic_data can fail for 3 reasons:
+    // - API misuse (calling it before SSL_set_custom_quic_method, which we
+    //   call in the TlsHandshaker c'tor)
+    // - Memory exhaustion when appending data to its buffer
+    // - Data provided at the wrong encryption level
+    //
+    // Of these, the only sensible error to handle is data provided at the wrong
+    // encryption level.
+    //
+    // Note: the error provided below has a good-sounding enum value, although
+    // it doesn't match the description as it's a QUIC Crypto specific error.
+    parser_error_ = QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
+    parser_error_detail_ = "TLS stack failed to receive data";
+    return false;
+  }
+  AdvanceHandshake();
+  return true;
+}
+
+void TlsHandshaker::AdvanceHandshake() {
+  if (is_connection_closed_) {
+    return;
+  }
+  if (GetHandshakeState() >= HANDSHAKE_COMPLETE) {
+    ProcessPostHandshakeMessage();
+    return;
+  }
+
+  QUICHE_BUG_IF(
+      quic_tls_server_async_done_no_flusher,
+      SSL_is_server(ssl()) && !handshaker_delegate_->PacketFlusherAttached())
+      << "is_server:" << SSL_is_server(ssl());
+
+  QUIC_VLOG(1) << ENDPOINT << "Continuing handshake";
+  int rv = SSL_do_handshake(ssl());
+
+  // If SSL_do_handshake return success(1) and we are in early data, it is
+  // possible that we have provided ServerHello to BoringSSL but it hasn't been
+  // processed. Retry SSL_do_handshake once will advance the handshake more in
+  // that case. If there are no unprocessed ServerHello, the retry will return a
+  // non-positive number.
+  if (rv == 1 && SSL_in_early_data(ssl())) {
+    OnEnterEarlyData();
+    rv = SSL_do_handshake(ssl());
+    QUIC_VLOG(1) << ENDPOINT
+                 << "SSL_do_handshake returned when entering early data. After "
+                 << "retry, rv=" << rv
+                 << ", SSL_in_early_data=" << SSL_in_early_data(ssl());
+    // The retry should either
+    // - Return <= 0 if the handshake is still pending, likely still in early
+    //   data.
+    // - Return 1 if the handshake has _actually_ finished. i.e.
+    //   SSL_in_early_data should be false.
+    //
+    // In either case, it should not both return 1 and stay in early data.
+    if (rv == 1 && SSL_in_early_data(ssl()) && !is_connection_closed_) {
+      QUIC_BUG(quic_handshaker_stay_in_early_data)
+          << "The original and the retry of SSL_do_handshake both returned "
+             "success and in early data";
+      CloseConnection(QUIC_HANDSHAKE_FAILED,
+                      "TLS handshake failed: Still in early data after retry");
+      return;
+    }
+  }
+
+  if (rv == 1) {
+    FinishHandshake();
+    return;
+  }
+  int ssl_error = SSL_get_error(ssl(), rv);
+  if (ssl_error == expected_ssl_error_) {
+    return;
+  }
+  if (ShouldCloseConnectionOnUnexpectedError(ssl_error) &&
+      !is_connection_closed_) {
+    QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
+                 << ssl_error;
+    ERR_print_errors_fp(stderr);
+    CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failed");
+  }
+}
+
+void TlsHandshaker::CloseConnection(QuicErrorCode error,
+                                    const std::string& reason_phrase) {
+  QUICHE_DCHECK(!reason_phrase.empty());
+  stream()->OnUnrecoverableError(error, reason_phrase);
+  is_connection_closed_ = true;
+}
+
+void TlsHandshaker::CloseConnection(QuicErrorCode error,
+                                    QuicIetfTransportErrorCodes ietf_error,
+                                    const std::string& reason_phrase) {
+  QUICHE_DCHECK(!reason_phrase.empty());
+  stream()->OnUnrecoverableError(error, ietf_error, reason_phrase);
+  is_connection_closed_ = true;
+}
+
+void TlsHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
+                                       ConnectionCloseSource /*source*/) {
+  is_connection_closed_ = true;
+}
+
+bool TlsHandshaker::ShouldCloseConnectionOnUnexpectedError(int /*ssl_error*/) {
+  return true;
+}
+
+size_t TlsHandshaker::BufferSizeLimitForLevel(EncryptionLevel level) const {
+  return SSL_quic_max_handshake_flight_len(
+      ssl(), TlsConnection::BoringEncryptionLevel(level));
+}
+
+ssl_early_data_reason_t TlsHandshaker::EarlyDataReason() const {
+  return SSL_get_early_data_reason(ssl());
+}
+
+const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
+  return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
+}
+
+enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
+  if (verify_result_ != ssl_verify_retry ||
+      expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
+    enum ssl_verify_result_t result = verify_result_;
+    verify_result_ = ssl_verify_retry;
+    *out_alert = cert_verify_tls_alert_;
+    return result;
+  }
+  const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
+  if (cert_chain == nullptr) {
+    *out_alert = SSL_AD_INTERNAL_ERROR;
+    return ssl_verify_invalid;
+  }
+  // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
+  std::vector<std::string> certs;
+  for (CRYPTO_BUFFER* cert : cert_chain) {
+    certs.push_back(
+        std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
+                    CRYPTO_BUFFER_len(cert)));
+  }
+  QUIC_DVLOG(1) << "VerifyCert: peer cert_chain length: " << certs.size();
+
+  ProofVerifierCallbackImpl* proof_verify_callback =
+      new ProofVerifierCallbackImpl(this);
+
+  cert_verify_tls_alert_ = *out_alert;
+  QuicAsyncStatus verify_result = VerifyCertChain(
+      certs, &cert_verify_error_details_, &verify_details_,
+      &cert_verify_tls_alert_,
+      std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
+  switch (verify_result) {
+    case QUIC_SUCCESS:
+      if (verify_details_) {
+        OnProofVerifyDetailsAvailable(*verify_details_);
+      }
+      return ssl_verify_ok;
+    case QUIC_PENDING:
+      proof_verify_callback_ = proof_verify_callback;
+      set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY);
+      return ssl_verify_retry;
+    case QUIC_FAILURE:
+    default:
+      *out_alert = cert_verify_tls_alert_;
+      QUIC_LOG(INFO) << "Cert chain verification failed: "
+                     << cert_verify_error_details_;
+      return ssl_verify_invalid;
+  }
+}
+
+void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
+                                   const SSL_CIPHER* cipher,
+                                   const std::vector<uint8_t>& write_secret) {
+  QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
+  std::unique_ptr<QuicEncrypter> encrypter =
+      QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  const EVP_MD* prf = Prf(cipher);
+  CryptoUtils::SetKeyAndIV(prf, write_secret,
+                           handshaker_delegate_->parsed_version(),
+                           encrypter.get());
+  std::vector<uint8_t> header_protection_key =
+      CryptoUtils::GenerateHeaderProtectionKey(
+          prf, write_secret, handshaker_delegate_->parsed_version(),
+          encrypter->GetKeySize());
+  encrypter->SetHeaderProtectionKey(
+      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
+                        header_protection_key.size()));
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    QUICHE_DCHECK(latest_write_secret_.empty());
+    latest_write_secret_ = write_secret;
+    one_rtt_write_header_protection_key_ = header_protection_key;
+  }
+  handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
+                                                    std::move(encrypter));
+}
+
+bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
+                                  const SSL_CIPHER* cipher,
+                                  const std::vector<uint8_t>& read_secret) {
+  QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level;
+  std::unique_ptr<QuicDecrypter> decrypter =
+      QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  const EVP_MD* prf = Prf(cipher);
+  CryptoUtils::SetKeyAndIV(prf, read_secret,
+                           handshaker_delegate_->parsed_version(),
+                           decrypter.get());
+  std::vector<uint8_t> header_protection_key =
+      CryptoUtils::GenerateHeaderProtectionKey(
+          prf, read_secret, handshaker_delegate_->parsed_version(),
+          decrypter->GetKeySize());
+  decrypter->SetHeaderProtectionKey(
+      absl::string_view(reinterpret_cast<char*>(header_protection_key.data()),
+                        header_protection_key.size()));
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    QUICHE_DCHECK(latest_read_secret_.empty());
+    latest_read_secret_ = read_secret;
+    one_rtt_read_header_protection_key_ = header_protection_key;
+  }
+  return handshaker_delegate_->OnNewDecryptionKeyAvailable(
+      level, std::move(decrypter),
+      /*set_alternative_decrypter=*/false,
+      /*latch_once_used=*/false);
+}
+
+std::unique_ptr<QuicDecrypter>
+TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  if (latest_read_secret_.empty() || latest_write_secret_.empty() ||
+      one_rtt_read_header_protection_key_.empty() ||
+      one_rtt_write_header_protection_key_.empty()) {
+    std::string error_details = "1-RTT secret(s) not set yet.";
+    QUIC_BUG(quic_bug_10312_1) << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details);
+    return nullptr;
+  }
+  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+  const EVP_MD* prf = Prf(cipher);
+  latest_read_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+      prf, handshaker_delegate_->parsed_version(), latest_read_secret_);
+  latest_write_secret_ = CryptoUtils::GenerateNextKeyPhaseSecret(
+      prf, handshaker_delegate_->parsed_version(), latest_write_secret_);
+
+  std::unique_ptr<QuicDecrypter> decrypter =
+      QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  CryptoUtils::SetKeyAndIV(prf, latest_read_secret_,
+                           handshaker_delegate_->parsed_version(),
+                           decrypter.get());
+  decrypter->SetHeaderProtectionKey(absl::string_view(
+      reinterpret_cast<char*>(one_rtt_read_header_protection_key_.data()),
+      one_rtt_read_header_protection_key_.size()));
+
+  return decrypter;
+}
+
+std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateCurrentOneRttEncrypter() {
+  if (latest_write_secret_.empty() ||
+      one_rtt_write_header_protection_key_.empty()) {
+    std::string error_details = "1-RTT write secret not set yet.";
+    QUIC_BUG(quic_bug_10312_2) << error_details;
+    CloseConnection(QUIC_INTERNAL_ERROR, error_details);
+    return nullptr;
+  }
+  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+  std::unique_ptr<QuicEncrypter> encrypter =
+      QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
+  CryptoUtils::SetKeyAndIV(Prf(cipher), latest_write_secret_,
+                           handshaker_delegate_->parsed_version(),
+                           encrypter.get());
+  encrypter->SetHeaderProtectionKey(absl::string_view(
+      reinterpret_cast<char*>(one_rtt_write_header_protection_key_.data()),
+      one_rtt_write_header_protection_key_.size()));
+  return encrypter;
+}
+
+bool TlsHandshaker::ExportKeyingMaterialForLabel(absl::string_view label,
+                                                 absl::string_view context,
+                                                 size_t result_len,
+                                                 std::string* result) {
+  if (result == nullptr) {
+    return false;
+  }
+  result->resize(result_len);
+  return SSL_export_keying_material(
+             ssl(), reinterpret_cast<uint8_t*>(&*result->begin()), result_len,
+             label.data(), label.size(),
+             reinterpret_cast<const uint8_t*>(context.data()), context.size(),
+             !context.empty()) == 1;
+}
+
+void TlsHandshaker::WriteMessage(EncryptionLevel level,
+                                 absl::string_view data) {
+  stream_->WriteCryptoData(level, data);
+}
+
+void TlsHandshaker::FlushFlight() {}
+
+void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
+  std::string error_details = absl::StrCat(
+      "TLS handshake failure (", EncryptionLevelToString(level), ") ",
+      static_cast<int>(desc), ": ", SSL_alert_desc_string_long(desc));
+  QUIC_DLOG(ERROR) << error_details;
+  CloseConnection(
+      TlsAlertToQuicErrorCode(desc),
+      static_cast<QuicIetfTransportErrorCodes>(CRYPTO_ERROR_FIRST + desc),
+      error_details);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_handshaker.h b/quiche/quic/core/tls_handshaker.h
new file mode 100644
index 0000000..bef4020
--- /dev/null
+++ b/quiche/quic/core/tls_handshaker.h
@@ -0,0 +1,225 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_message_parser.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/tls_connection.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+class QuicCryptoStream;
+
+// Base class for TlsClientHandshaker and TlsServerHandshaker. TlsHandshaker
+// provides functionality common to both the client and server, such as moving
+// messages between the TLS stack and the QUIC crypto stream, and handling
+// derivation of secrets.
+class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate,
+                                          public CryptoMessageParser {
+ public:
+  // TlsHandshaker does not take ownership of any of its arguments; they must
+  // outlive the TlsHandshaker.
+  TlsHandshaker(QuicCryptoStream* stream, QuicSession* session);
+  TlsHandshaker(const TlsHandshaker&) = delete;
+  TlsHandshaker& operator=(const TlsHandshaker&) = delete;
+
+  ~TlsHandshaker() override;
+
+  // From CryptoMessageParser
+  bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
+  size_t InputBytesRemaining() const override { return 0; }
+  QuicErrorCode error() const override { return parser_error_; }
+  const std::string& error_detail() const override {
+    return parser_error_detail_;
+  }
+
+  // The following methods provide implementations to subclasses of
+  // TlsHandshaker which use them to implement methods of QuicCryptoStream.
+  CryptoMessageParser* crypto_message_parser() { return this; }
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
+  ssl_early_data_reason_t EarlyDataReason() const;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter();
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter();
+  virtual HandshakeState GetHandshakeState() const = 0;
+  bool ExportKeyingMaterialForLabel(absl::string_view label,
+                                    absl::string_view context,
+                                    size_t result_len, std::string* result);
+
+ protected:
+  // Called when a new message is received on the crypto stream and is available
+  // for the TLS stack to read.
+  virtual void AdvanceHandshake();
+
+  void CloseConnection(QuicErrorCode error, const std::string& reason_phrase);
+  // Closes the connection, specifying the wire error code |ietf_error|
+  // explicitly.
+  void CloseConnection(QuicErrorCode error,
+                       QuicIetfTransportErrorCodes ietf_error,
+                       const std::string& reason_phrase);
+
+  void OnConnectionClosed(QuicErrorCode error, ConnectionCloseSource source);
+
+  bool is_connection_closed() const { return is_connection_closed_; }
+
+  // Called when |SSL_do_handshake| returns 1, indicating that the handshake has
+  // finished. Note that a handshake only finishes once, entering early data
+  // does not count.
+  virtual void FinishHandshake() = 0;
+
+  // Called when |SSL_do_handshake| returns 1 and the connection is in early
+  // data. In that case, |AdvanceHandshake| will call |OnEnterEarlyData| and
+  // retry |SSL_do_handshake| once.
+  virtual void OnEnterEarlyData() {
+    // By default, do nothing but check the preconditions.
+    QUICHE_DCHECK(SSL_in_early_data(ssl()));
+  }
+
+  // Called when a handshake message is received after the handshake is
+  // complete.
+  virtual void ProcessPostHandshakeMessage() = 0;
+
+  // Called when an unexpected error code is received from |SSL_get_error|. If a
+  // subclass can expect more than just a single error (as provided by
+  // |set_expected_ssl_error|), it can override this method to handle that case.
+  virtual bool ShouldCloseConnectionOnUnexpectedError(int ssl_error);
+
+  void set_expected_ssl_error(int ssl_error) {
+    expected_ssl_error_ = ssl_error;
+  }
+  int expected_ssl_error() const { return expected_ssl_error_; }
+
+  // Called to verify a cert chain. This can be implemented as a simple wrapper
+  // around ProofVerifier, which optionally gathers additional arguments to pass
+  // into their VerifyCertChain method. This class retains a non-owning pointer
+  // to |callback|; the callback must live until this function returns
+  // QUIC_SUCCESS or QUIC_FAILURE, or until the callback is run.
+  //
+  // If certificate verification fails, |*out_alert| may be set to a TLS alert
+  // that will be sent when closing the connection; it defaults to
+  // certificate_unknown. Implementations of VerifyCertChain may retain the
+  // |out_alert| pointer while performing an async operation.
+  virtual QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) = 0;
+  // Called when certificate verification is completed.
+  virtual void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) = 0;
+
+  // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
+  const EVP_MD* Prf(const SSL_CIPHER* cipher);
+
+  virtual const TlsConnection* tls_connection() const = 0;
+
+  SSL* ssl() const { return tls_connection()->ssl(); }
+
+  QuicCryptoStream* stream() { return stream_; }
+  HandshakerDelegateInterface* handshaker_delegate() {
+    return handshaker_delegate_;
+  }
+
+  enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override;
+
+  // SetWriteSecret provides the encryption secret used to encrypt messages at
+  // encryption level |level|. The secret provided here is the one from the TLS
+  // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
+  // traffic secrets and application traffic secrets. The provided write secret
+  // must be used with the provided cipher suite |cipher|.
+  void SetWriteSecret(EncryptionLevel level,
+                      const SSL_CIPHER* cipher,
+                      const std::vector<uint8_t>& write_secret) override;
+
+  // SetReadSecret is similar to SetWriteSecret, except that it is used for
+  // decrypting messages. SetReadSecret at a particular level is always called
+  // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT, where
+  // the EncryptionLevel for SetWriteSecret is ENCRYPTION_FORWARD_SECURE.
+  bool SetReadSecret(EncryptionLevel level,
+                     const SSL_CIPHER* cipher,
+                     const std::vector<uint8_t>& read_secret) override;
+
+  // WriteMessage is called when there is |data| from the TLS stack ready for
+  // the QUIC stack to write in a crypto frame. The data must be transmitted at
+  // encryption level |level|.
+  void WriteMessage(EncryptionLevel level, absl::string_view data) override;
+
+  // FlushFlight is called to signal that the current flight of
+  // messages have all been written (via calls to WriteMessage) and can be
+  // flushed to the underlying transport.
+  void FlushFlight() override;
+
+  // SendAlert causes this TlsHandshaker to close the QUIC connection with an
+  // error code corresponding to the TLS alert description |desc|.
+  void SendAlert(EncryptionLevel level, uint8_t desc) override;
+
+  // Informational callback from BoringSSL. Subclasses can override it to do
+  // logging, tracing, etc.
+  // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
+  void InfoCallback(int /*type*/, int /*value*/) override {}
+
+ private:
+  // ProofVerifierCallbackImpl handles the result of an asynchronous certificate
+  // verification operation.
+  class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl
+      : public ProofVerifierCallback {
+   public:
+    explicit ProofVerifierCallbackImpl(TlsHandshaker* parent);
+    ~ProofVerifierCallbackImpl() override;
+
+    // ProofVerifierCallback interface.
+    void Run(bool ok,
+             const std::string& error_details,
+             std::unique_ptr<ProofVerifyDetails>* details) override;
+
+    // If called, Cancel causes the pending callback to be a no-op.
+    void Cancel();
+
+   private:
+    // Non-owning pointer to the TlsHandshaker responsible for this callback.
+    // |parent_| must be valid for the life of this callback or until |Cancel|
+    // is called.
+    TlsHandshaker* parent_;
+  };
+
+  // ProofVerifierCallback used for async certificate verification. Ownership of
+  // this object is transferred to |VerifyCertChain|;
+  ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr;
+  std::unique_ptr<ProofVerifyDetails> verify_details_;
+  enum ssl_verify_result_t verify_result_ = ssl_verify_retry;
+  uint8_t cert_verify_tls_alert_ = SSL_AD_CERTIFICATE_UNKNOWN;
+  std::string cert_verify_error_details_;
+
+  int expected_ssl_error_ = SSL_ERROR_WANT_READ;
+  bool is_connection_closed_ = false;
+
+  QuicCryptoStream* stream_;
+  HandshakerDelegateInterface* handshaker_delegate_;
+
+  QuicErrorCode parser_error_ = QUIC_NO_ERROR;
+  std::string parser_error_detail_;
+
+  // The most recently derived 1-RTT read and write secrets, which are updated
+  // on each key update.
+  std::vector<uint8_t> latest_read_secret_;
+  std::vector<uint8_t> latest_write_secret_;
+  // 1-RTT header protection keys, which are not changed during key update.
+  std::vector<uint8_t> one_rtt_read_header_protection_key_;
+  std::vector<uint8_t> one_rtt_write_header_protection_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
diff --git a/quiche/quic/core/tls_server_handshaker.cc b/quiche/quic/core/tls_server_handshaker.cc
new file mode 100644
index 0000000..7d14507
--- /dev/null
+++ b/quiche/quic/core/tls_server_handshaker.cc
@@ -0,0 +1,1173 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/tls_server_handshaker.h"
+
+#include <memory>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/http_frames.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+#define RECORD_LATENCY_IN_US(stat_name, latency, comment)                   \
+  do {                                                                      \
+    const int64_t latency_in_us = (latency).ToMicroseconds();               \
+    QUIC_DVLOG(1) << "Recording " stat_name ": " << latency_in_us;          \
+    QUIC_SERVER_HISTOGRAM_COUNTS(stat_name, latency_in_us, 1, 10000000, 50, \
+                                 comment);                                  \
+  } while (0)
+
+namespace quic {
+
+namespace {
+
+// Default port for HTTP/3.
+uint16_t kDefaultPort = 443;
+
+}  // namespace
+
+TlsServerHandshaker::DefaultProofSourceHandle::DefaultProofSourceHandle(
+    TlsServerHandshaker* handshaker,
+    ProofSource* proof_source)
+    : handshaker_(handshaker), proof_source_(proof_source) {}
+
+TlsServerHandshaker::DefaultProofSourceHandle::~DefaultProofSourceHandle() {
+  CloseHandle();
+}
+
+void TlsServerHandshaker::DefaultProofSourceHandle::CloseHandle() {
+  QUIC_DVLOG(1) << "CloseHandle. is_signature_pending="
+                << (signature_callback_ != nullptr);
+  if (signature_callback_) {
+    signature_callback_->Cancel();
+    signature_callback_ = nullptr;
+  }
+}
+
+QuicAsyncStatus
+TlsServerHandshaker::DefaultProofSourceHandle::SelectCertificate(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    absl::string_view /*ssl_capabilities*/,
+    const std::string& hostname,
+    absl::string_view /*client_hello*/,
+    const std::string& /*alpn*/,
+    absl::optional<std::string> /*alps*/,
+    const std::vector<uint8_t>& /*quic_transport_params*/,
+    const absl::optional<std::vector<uint8_t>>& /*early_data_context*/,
+    const QuicSSLConfig& /*ssl_config*/) {
+  if (!handshaker_ || !proof_source_) {
+    QUIC_BUG(quic_bug_10341_1)
+        << "SelectCertificate called on a detached handle";
+    return QUIC_FAILURE;
+  }
+
+  bool cert_matched_sni;
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+      proof_source_->GetCertChain(server_address, client_address, hostname,
+                                  &cert_matched_sni);
+
+  handshaker_->OnSelectCertificateDone(
+      /*ok=*/true, /*is_sync=*/true, chain.get(),
+      /*handshake_hints=*/absl::string_view(),
+      /*ticket_encryption_key=*/absl::string_view(), cert_matched_sni,
+      QuicDelayedSSLConfig());
+  if (!handshaker_->select_cert_status().has_value()) {
+    QUIC_BUG(quic_bug_12423_1)
+        << "select_cert_status() has no value after a synchronous select cert";
+    // Return success to continue the handshake.
+    return QUIC_SUCCESS;
+  }
+  return handshaker_->select_cert_status().value();
+}
+
+QuicAsyncStatus TlsServerHandshaker::DefaultProofSourceHandle::ComputeSignature(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in,
+    size_t max_signature_size) {
+  if (!handshaker_ || !proof_source_) {
+    QUIC_BUG(quic_bug_10341_2)
+        << "ComputeSignature called on a detached handle";
+    return QUIC_FAILURE;
+  }
+
+  if (signature_callback_) {
+    QUIC_BUG(quic_bug_10341_3) << "ComputeSignature called while pending";
+    return QUIC_FAILURE;
+  }
+
+  signature_callback_ = new DefaultSignatureCallback(this);
+  proof_source_->ComputeTlsSignature(
+      server_address, client_address, hostname, signature_algorithm, in,
+      std::unique_ptr<DefaultSignatureCallback>(signature_callback_));
+
+  if (signature_callback_) {
+    QUIC_DVLOG(1) << "ComputeTlsSignature is pending";
+    signature_callback_->set_is_sync(false);
+    return QUIC_PENDING;
+  }
+
+  bool success = handshaker_->HasValidSignature(max_signature_size);
+  QUIC_DVLOG(1) << "ComputeTlsSignature completed synchronously. success:"
+                << success;
+  // OnComputeSignatureDone should have been called by signature_callback_->Run.
+  return success ? QUIC_SUCCESS : QUIC_FAILURE;
+}
+
+TlsServerHandshaker::DecryptCallback::DecryptCallback(
+    TlsServerHandshaker* handshaker)
+    : handshaker_(handshaker) {}
+
+void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) {
+  if (handshaker_ == nullptr) {
+    // The callback was cancelled before we could run.
+    return;
+  }
+
+  TlsServerHandshaker* handshaker = handshaker_;
+  handshaker_ = nullptr;
+
+  handshaker->decrypted_session_ticket_ = std::move(plaintext);
+  const bool is_async =
+      (handshaker->expected_ssl_error() == SSL_ERROR_PENDING_TICKET);
+
+  absl::optional<QuicConnectionContextSwitcher> context_switcher;
+
+  if (is_async) {
+    context_switcher.emplace(handshaker->connection_context());
+  }
+  QUIC_TRACESTRING(
+      absl::StrCat("TLS ticket decryption done. len(decrypted_ticket):",
+                   handshaker->decrypted_session_ticket_.size()));
+
+  // DecryptCallback::Run could be called synchronously. When that happens, we
+  // are currently in the middle of a call to AdvanceHandshake.
+  // (AdvanceHandshake called SSL_do_handshake, which through some layers
+  // called SessionTicketOpen, which called TicketCrypter::Decrypt, which
+  // synchronously called this function.) In that case, the handshake will
+  // continue to be processed when this function returns.
+  //
+  // When this callback is called asynchronously (i.e. the ticket decryption
+  // is pending), TlsServerHandshaker is not actively processing handshake
+  // messages. We need to have it resume processing handshake messages by
+  // calling AdvanceHandshake.
+  if (is_async) {
+    handshaker->AdvanceHandshakeFromCallback();
+  }
+
+  handshaker->ticket_decryption_callback_ = nullptr;
+}
+
+void TlsServerHandshaker::DecryptCallback::Cancel() {
+  QUICHE_DCHECK(handshaker_);
+  handshaker_ = nullptr;
+}
+
+TlsServerHandshaker::TlsServerHandshaker(
+    QuicSession* session, const QuicCryptoServerConfig* crypto_config)
+    : TlsHandshaker(this, session),
+      QuicCryptoServerStreamBase(session),
+      proof_source_(crypto_config->proof_source()),
+      pre_shared_key_(crypto_config->pre_shared_key()),
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
+      tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()),
+      crypto_config_(crypto_config) {
+  QUIC_DVLOG(1) << "TlsServerHandshaker: support_client_cert:"
+                << session->support_client_cert()
+                << ", client_cert_mode initial value: " << client_cert_mode();
+
+  QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3,
+                   session->connection()->version().handshake_protocol);
+
+  // Configure the SSL to be a server.
+  SSL_set_accept_state(ssl());
+
+  // Make sure we use the right TLS extension codepoint.
+  int use_legacy_extension = 0;
+  if (session->version().UsesLegacyTlsExtension()) {
+    use_legacy_extension = 1;
+  }
+  SSL_set_quic_use_legacy_codepoint(ssl(), use_legacy_extension);
+
+  if (session->connection()->context()->tracer) {
+    tls_connection_.EnableInfoCallback();
+  }
+
+  if (no_select_cert_if_disconnected_) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 1, 2);
+  }
+}
+
+TlsServerHandshaker::~TlsServerHandshaker() { CancelOutstandingCallbacks(); }
+
+void TlsServerHandshaker::CancelOutstandingCallbacks() {
+  if (proof_source_handle_) {
+    proof_source_handle_->CloseHandle();
+  }
+  if (ticket_decryption_callback_) {
+    ticket_decryption_callback_->Cancel();
+    ticket_decryption_callback_ = nullptr;
+  }
+}
+
+void TlsServerHandshaker::InfoCallback(int type, int value) {
+  QuicConnectionTracer* tracer =
+      session()->connection()->context()->tracer.get();
+
+  if (tracer == nullptr) {
+    return;
+  }
+
+  if (type & SSL_CB_LOOP) {
+    tracer->PrintString(
+        absl::StrCat("SSL:ACCEPT_LOOP:", SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_ALERT) {
+    const char* prefix =
+        (type & SSL_CB_READ) ? "SSL:READ_ALERT:" : "SSL:WRITE_ALERT:";
+    tracer->PrintString(absl::StrCat(prefix, SSL_alert_type_string_long(value),
+                                     ":", SSL_alert_desc_string_long(value)));
+  } else if (type & SSL_CB_EXIT) {
+    const char* prefix =
+        (value == 1) ? "SSL:ACCEPT_EXIT_OK:" : "SSL:ACCEPT_EXIT_FAIL:";
+    tracer->PrintString(absl::StrCat(prefix, SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_HANDSHAKE_START) {
+    tracer->PrintString(
+        absl::StrCat("SSL:HANDSHAKE_START:", SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_HANDSHAKE_DONE) {
+    tracer->PrintString(
+        absl::StrCat("SSL:HANDSHAKE_DONE:", SSL_state_string_long(ssl())));
+  } else {
+    QUIC_DLOG(INFO) << "Unknown event type " << type << ": "
+                    << SSL_state_string_long(ssl());
+    tracer->PrintString(
+        absl::StrCat("SSL:unknown:", value, ":", SSL_state_string_long(ssl())));
+  }
+}
+
+std::unique_ptr<ProofSourceHandle>
+TlsServerHandshaker::MaybeCreateProofSourceHandle() {
+  return std::make_unique<DefaultProofSourceHandle>(this, proof_source_);
+}
+
+bool TlsServerHandshaker::GetBase64SHA256ClientChannelID(
+    std::string* /*output*/) const {
+  // Channel ID is not supported when TLS is used in QUIC.
+  return false;
+}
+
+void TlsServerHandshaker::SendServerConfigUpdate(
+    const CachedNetworkParameters* /*cached_network_params*/) {
+  // SCUP messages aren't supported when using the TLS handshake.
+}
+
+bool TlsServerHandshaker::DisableResumption() {
+  if (!can_disable_resumption_ || !session()->connection()->connected()) {
+    return false;
+  }
+  tls_connection_.DisableTicketSupport();
+  return true;
+}
+
+bool TlsServerHandshaker::IsZeroRtt() const {
+  return SSL_early_data_accepted(ssl());
+}
+
+bool TlsServerHandshaker::IsResumption() const {
+  return SSL_session_reused(ssl());
+}
+
+bool TlsServerHandshaker::ResumptionAttempted() const {
+  return ticket_received_;
+}
+
+bool TlsServerHandshaker::EarlyDataAttempted() const {
+  QUIC_BUG_IF(quic_tls_early_data_attempted_too_early,
+              !select_cert_status_.has_value())
+      << "EarlyDataAttempted must be called after EarlySelectCertCallback is "
+         "started";
+  return early_data_attempted_;
+}
+
+int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
+  // SCUP messages aren't supported when using the TLS handshake.
+  return 0;
+}
+
+const CachedNetworkParameters*
+TlsServerHandshaker::PreviousCachedNetworkParams() const {
+  return last_received_cached_network_params_.get();
+}
+
+void TlsServerHandshaker::SetPreviousCachedNetworkParams(
+    CachedNetworkParameters cached_network_params) {
+  last_received_cached_network_params_ =
+      std::make_unique<CachedNetworkParameters>(cached_network_params);
+}
+
+void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) {
+  if (level == ENCRYPTION_HANDSHAKE && state_ < HANDSHAKE_PROCESSED) {
+    state_ = HANDSHAKE_PROCESSED;
+    handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+    handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+  }
+}
+
+void TlsServerHandshaker::OnHandshakeDoneReceived() {
+  QUICHE_DCHECK(false);
+}
+
+void TlsServerHandshaker::OnNewTokenReceived(absl::string_view /*token*/) {
+  QUICHE_DCHECK(false);
+}
+
+std::string TlsServerHandshaker::GetAddressToken(
+    const CachedNetworkParameters* cached_network_params) const {
+  SourceAddressTokens empty_previous_tokens;
+  const QuicConnection* connection = session()->connection();
+  return crypto_config_->NewSourceAddressToken(
+      crypto_config_->source_address_token_boxer(), empty_previous_tokens,
+      connection->effective_peer_address().host(),
+      connection->random_generator(), connection->clock()->WallNow(),
+      cached_network_params);
+}
+
+bool TlsServerHandshaker::ValidateAddressToken(absl::string_view token) const {
+  SourceAddressTokens tokens;
+  HandshakeFailureReason reason = crypto_config_->ParseSourceAddressToken(
+      crypto_config_->source_address_token_boxer(), token, tokens);
+  if (reason != HANDSHAKE_OK) {
+    QUIC_DLOG(WARNING) << "Failed to parse source address token: "
+                       << CryptoUtils::HandshakeFailureReasonToString(reason);
+    return false;
+  }
+  auto cached_network_params = std::make_unique<CachedNetworkParameters>();
+  reason = crypto_config_->ValidateSourceAddressTokens(
+      tokens, session()->connection()->effective_peer_address().host(),
+      session()->connection()->clock()->WallNow(), cached_network_params.get());
+  if (reason != HANDSHAKE_OK) {
+    QUIC_DLOG(WARNING) << "Failed to validate source address token: "
+                       << CryptoUtils::HandshakeFailureReasonToString(reason);
+    return false;
+  }
+
+  last_received_cached_network_params_ = std::move(cached_network_params);
+  return true;
+}
+
+bool TlsServerHandshaker::ShouldSendExpectCTHeader() const {
+  return false;
+}
+
+bool TlsServerHandshaker::DidCertMatchSni() const { return cert_matched_sni_; }
+
+const ProofSource::Details* TlsServerHandshaker::ProofSourceDetails() const {
+  return proof_source_details_.get();
+}
+
+bool TlsServerHandshaker::ExportKeyingMaterial(absl::string_view label,
+                                               absl::string_view context,
+                                               size_t result_len,
+                                               std::string* result) {
+  return ExportKeyingMaterialForLabel(label, context, result_len, result);
+}
+
+void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode error,
+                                             ConnectionCloseSource source) {
+  TlsHandshaker::OnConnectionClosed(error, source);
+}
+
+ssl_early_data_reason_t TlsServerHandshaker::EarlyDataReason() const {
+  return TlsHandshaker::EarlyDataReason();
+}
+
+bool TlsServerHandshaker::encryption_established() const {
+  return encryption_established_;
+}
+
+bool TlsServerHandshaker::one_rtt_keys_available() const {
+  return state_ == HANDSHAKE_CONFIRMED;
+}
+
+const QuicCryptoNegotiatedParameters&
+TlsServerHandshaker::crypto_negotiated_params() const {
+  return *crypto_negotiated_params_;
+}
+
+CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
+  return TlsHandshaker::crypto_message_parser();
+}
+
+HandshakeState TlsServerHandshaker::GetHandshakeState() const {
+  return state_;
+}
+
+void TlsServerHandshaker::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> state) {
+  application_state_ = std::move(state);
+}
+
+size_t TlsServerHandshaker::BufferSizeLimitForLevel(
+    EncryptionLevel level) const {
+  return TlsHandshaker::BufferSizeLimitForLevel(level);
+}
+
+std::unique_ptr<QuicDecrypter>
+TlsServerHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
+  return TlsHandshaker::AdvanceKeysAndCreateCurrentOneRttDecrypter();
+}
+
+std::unique_ptr<QuicEncrypter>
+TlsServerHandshaker::CreateCurrentOneRttEncrypter() {
+  return TlsHandshaker::CreateCurrentOneRttEncrypter();
+}
+
+void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
+
+void TlsServerHandshaker::AdvanceHandshakeFromCallback() {
+  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
+
+  AdvanceHandshake();
+  if (!is_connection_closed()) {
+    handshaker_delegate()->OnHandshakeCallbackDone();
+  }
+}
+
+bool TlsServerHandshaker::ProcessTransportParameters(
+    const SSL_CLIENT_HELLO* client_hello,
+    std::string* error_details) {
+  TransportParameters client_params;
+  const uint8_t* client_params_bytes;
+  size_t params_bytes_len;
+
+  // Make sure we use the right TLS extension codepoint.
+  uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters_standard;
+  if (session()->version().UsesLegacyTlsExtension()) {
+    extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
+  }
+  // When using early select cert callback, SSL_get_peer_quic_transport_params
+  // can not be used to retrieve the client's transport parameters, but we can
+  // use SSL_early_callback_ctx_extension_get to do that.
+  if (!SSL_early_callback_ctx_extension_get(client_hello, extension_type,
+                                            &client_params_bytes,
+                                            &params_bytes_len)) {
+    params_bytes_len = 0;
+  }
+
+  if (params_bytes_len == 0) {
+    *error_details = "Client's transport parameters are missing";
+    return false;
+  }
+  std::string parse_error_details;
+  if (!ParseTransportParameters(session()->connection()->version(),
+                                Perspective::IS_CLIENT, client_params_bytes,
+                                params_bytes_len, &client_params,
+                                &parse_error_details)) {
+    QUICHE_DCHECK(!parse_error_details.empty());
+    *error_details =
+        "Unable to parse client's transport parameters: " + parse_error_details;
+    return false;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersReceived(client_params);
+
+  if (client_params.legacy_version_information.has_value() &&
+      CryptoUtils::ValidateClientHelloVersion(
+          client_params.legacy_version_information.value().version,
+          session()->connection()->version(), session()->supported_versions(),
+          error_details) != QUIC_NO_ERROR) {
+    return false;
+  }
+
+  if (client_params.version_information.has_value() &&
+      !CryptoUtils::ValidateChosenVersion(
+          client_params.version_information.value().chosen_version,
+          session()->version(), error_details)) {
+    QUICHE_DCHECK(!error_details->empty());
+    return false;
+  }
+
+  if (handshaker_delegate()->ProcessTransportParameters(
+          client_params, /* is_resumption = */ false, error_details) !=
+      QUIC_NO_ERROR) {
+    return false;
+  }
+
+  ProcessAdditionalTransportParameters(client_params);
+
+  return true;
+}
+
+TlsServerHandshaker::SetTransportParametersResult
+TlsServerHandshaker::SetTransportParameters() {
+  SetTransportParametersResult result;
+  QUICHE_DCHECK(!result.success);
+
+  TransportParameters server_params;
+  server_params.perspective = Perspective::IS_SERVER;
+  server_params.legacy_version_information =
+      TransportParameters::LegacyVersionInformation();
+  server_params.legacy_version_information.value().supported_versions =
+      CreateQuicVersionLabelVector(session()->supported_versions());
+  server_params.legacy_version_information.value().version =
+      CreateQuicVersionLabel(session()->connection()->version());
+  server_params.version_information = TransportParameters::VersionInformation();
+  server_params.version_information.value().chosen_version =
+      CreateQuicVersionLabel(session()->version());
+  server_params.version_information.value().other_versions =
+      CreateQuicVersionLabelVector(session()->supported_versions());
+
+  if (!handshaker_delegate()->FillTransportParameters(&server_params)) {
+    return result;
+  }
+
+  // Notify QuicConnectionDebugVisitor.
+  session()->connection()->OnTransportParametersSent(server_params);
+
+  {  // Ensure |server_params_bytes| is not accessed out of the scope.
+    std::vector<uint8_t> server_params_bytes;
+    if (!SerializeTransportParameters(session()->connection()->version(),
+                                      server_params, &server_params_bytes) ||
+        SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
+                                      server_params_bytes.size()) != 1) {
+      return result;
+    }
+    result.quic_transport_params = std::move(server_params_bytes);
+  }
+
+  if (application_state_) {
+    std::vector<uint8_t> early_data_context;
+    if (!SerializeTransportParametersForTicket(
+            server_params, *application_state_, &early_data_context)) {
+      QUIC_BUG(quic_bug_10341_4)
+          << "Failed to serialize Transport Parameters for ticket.";
+      result.early_data_context = std::vector<uint8_t>();
+      return result;
+    }
+    SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
+                                    early_data_context.size());
+    result.early_data_context = std::move(early_data_context);
+    application_state_.reset(nullptr);
+  }
+  result.success = true;
+  return result;
+}
+
+void TlsServerHandshaker::SetWriteSecret(
+    EncryptionLevel level,
+    const SSL_CIPHER* cipher,
+    const std::vector<uint8_t>& write_secret) {
+  if (is_connection_closed()) {
+    return;
+  }
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    encryption_established_ = true;
+    // Fill crypto_negotiated_params_:
+    const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
+    if (cipher) {
+      crypto_negotiated_params_->cipher_suite =
+          SSL_CIPHER_get_protocol_id(cipher);
+    }
+    crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
+  }
+  TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
+}
+
+std::string TlsServerHandshaker::GetAcceptChValueForHostname(
+    const std::string& /*hostname*/) const {
+  return {};
+}
+
+void TlsServerHandshaker::FinishHandshake() {
+  QUICHE_DCHECK(!SSL_in_early_data(ssl()));
+
+  if (!valid_alpn_received_) {
+    QUIC_DLOG(ERROR)
+        << "Server: handshake finished without receiving a known ALPN";
+    // TODO(b/130164908) this should send no_application_protocol
+    // instead of QUIC_HANDSHAKE_FAILED.
+    CloseConnection(QUIC_HANDSHAKE_FAILED,
+                    "Server did not receive a known ALPN");
+    return;
+  }
+
+  ssl_early_data_reason_t reason_code = EarlyDataReason();
+  QUIC_DLOG(INFO) << "Server: handshake finished. Early data reason "
+                  << reason_code << " ("
+                  << CryptoUtils::EarlyDataReasonToString(reason_code) << ")";
+  state_ = HANDSHAKE_CONFIRMED;
+
+  handshaker_delegate()->OnTlsHandshakeComplete();
+  handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
+  handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
+  // ENCRYPTION_ZERO_RTT decryption key is not discarded here as "Servers MAY
+  // temporarily retain 0-RTT keys to allow decrypting reordered packets
+  // without requiring their contents to be retransmitted with 1-RTT keys."
+  // It is expected that QuicConnection will discard the key at an
+  // appropriate time.
+}
+
+QuicAsyncStatus TlsServerHandshaker::VerifyCertChain(
+    const std::vector<std::string>& /*certs*/,
+    std::string* /*error_details*/,
+    std::unique_ptr<ProofVerifyDetails>* /*details*/,
+    uint8_t* /*out_alert*/,
+    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+  if (!session()->support_client_cert()) {
+    QUIC_BUG(quic_bug_10341_5)
+        << "Client certificates are not yet supported on the server";
+    return QUIC_FAILURE;
+  }
+
+  QUIC_RESTART_FLAG_COUNT_N(quic_tls_server_support_client_cert, 2, 2);
+  QUIC_DVLOG(1) << "VerifyCertChain returning success";
+
+  // No real verification here. A subclass can override this function to verify
+  // the client cert if needed.
+  return QUIC_SUCCESS;
+}
+
+void TlsServerHandshaker::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& /*verify_details*/) {}
+
+ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out,
+    uint16_t sig_alg,
+    absl::string_view in) {
+  QUICHE_DCHECK_EQ(expected_ssl_error(), SSL_ERROR_WANT_READ);
+
+  QuicAsyncStatus status = proof_source_handle_->ComputeSignature(
+      session()->connection()->self_address(),
+      session()->connection()->peer_address(), crypto_negotiated_params_->sni,
+      sig_alg, in, max_out);
+  if (status == QUIC_PENDING) {
+    set_expected_ssl_error(SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
+    if (async_op_timer_.has_value()) {
+      QUIC_CODE_COUNT(
+          quic_tls_server_computing_signature_while_another_op_pending);
+    }
+    async_op_timer_ = QuicTimeAccumulator();
+    async_op_timer_->Start(now());
+  }
+  return PrivateKeyComplete(out, out_len, max_out);
+}
+
+ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out) {
+  if (expected_ssl_error() == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
+    return ssl_private_key_retry;
+  }
+
+  const bool success = HasValidSignature(max_out);
+  QuicConnectionStats::TlsServerOperationStats compute_signature_stats;
+  compute_signature_stats.success = success;
+  if (async_op_timer_.has_value()) {
+    async_op_timer_->Stop(now());
+    compute_signature_stats.async_latency =
+        async_op_timer_->GetTotalElapsedTime();
+    async_op_timer_.reset();
+    RECORD_LATENCY_IN_US("tls_server_async_compute_signature_latency_us",
+                         compute_signature_stats.async_latency,
+                         "Async compute signature latency in microseconds");
+  }
+  connection_stats().tls_server_compute_signature_stats =
+      std::move(compute_signature_stats);
+
+  if (!success) {
+    return ssl_private_key_failure;
+  }
+  *out_len = cert_verify_sig_.size();
+  memcpy(out, cert_verify_sig_.data(), *out_len);
+  cert_verify_sig_.clear();
+  cert_verify_sig_.shrink_to_fit();
+  return ssl_private_key_success;
+}
+
+void TlsServerHandshaker::OnComputeSignatureDone(
+    bool ok,
+    bool is_sync,
+    std::string signature,
+    std::unique_ptr<ProofSource::Details> details) {
+  QUIC_DVLOG(1) << "OnComputeSignatureDone. ok:" << ok
+                << ", is_sync:" << is_sync
+                << ", len(signature):" << signature.size();
+  absl::optional<QuicConnectionContextSwitcher> context_switcher;
+
+  if (!is_sync) {
+    context_switcher.emplace(connection_context());
+  }
+
+  QUIC_TRACESTRING(absl::StrCat("TLS compute signature done. ok:", ok,
+                                ", len(signature):", signature.size()));
+
+  if (ok) {
+    cert_verify_sig_ = std::move(signature);
+    proof_source_details_ = std::move(details);
+  }
+  const int last_expected_ssl_error = expected_ssl_error();
+  set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  if (!is_sync) {
+    QUICHE_DCHECK_EQ(last_expected_ssl_error,
+                     SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
+    AdvanceHandshakeFromCallback();
+  }
+}
+
+bool TlsServerHandshaker::HasValidSignature(size_t max_signature_size) const {
+  return !cert_verify_sig_.empty() &&
+         cert_verify_sig_.size() <= max_signature_size;
+}
+
+size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
+  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
+  return proof_source_->GetTicketCrypter()->MaxOverhead();
+}
+
+int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
+                                           size_t* out_len,
+                                           size_t max_out_len,
+                                           absl::string_view in) {
+  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
+  std::vector<uint8_t> ticket =
+      proof_source_->GetTicketCrypter()->Encrypt(in, ticket_encryption_key_);
+  if (max_out_len < ticket.size()) {
+    QUIC_BUG(quic_bug_12423_2)
+        << "TicketCrypter returned " << ticket.size()
+        << " bytes of ciphertext, which is larger than its max overhead of "
+        << max_out_len;
+    return 0;  // failure
+  }
+  *out_len = ticket.size();
+  memcpy(out, ticket.data(), ticket.size());
+  QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_sealed);
+  return 1;  // success
+}
+
+ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out_len,
+    absl::string_view in) {
+  QUICHE_DCHECK(proof_source_->GetTicketCrypter());
+
+  if (ignore_ticket_open_) {
+    // SetIgnoreTicketOpen has been called. Typically this means the caller is
+    // using handshake hints and expect the hints to contain ticket decryption
+    // results.
+    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_1);
+    return ssl_ticket_aead_ignore_ticket;
+  }
+
+  if (!ticket_decryption_callback_) {
+    ticket_decryption_callback_ = new DecryptCallback(this);
+    proof_source_->GetTicketCrypter()->Decrypt(
+        in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
+
+    // Decrypt can run the callback synchronously. In that case, the callback
+    // will clear the ticket_decryption_callback_ pointer, and instead of
+    // returning ssl_ticket_aead_retry, we should continue processing to
+    // return the decrypted ticket.
+    //
+    // If the callback is not run synchronously, return ssl_ticket_aead_retry
+    // and when the callback is complete this function will be run again to
+    // return the result.
+    if (ticket_decryption_callback_) {
+      QUICHE_DCHECK(!ticket_decryption_callback_->IsDone());
+      set_expected_ssl_error(SSL_ERROR_PENDING_TICKET);
+      if (async_op_timer_.has_value()) {
+        QUIC_CODE_COUNT(
+            quic_tls_server_decrypting_ticket_while_another_op_pending);
+      }
+      async_op_timer_ = QuicTimeAccumulator();
+      async_op_timer_->Start(now());
+    }
+  }
+
+  // If the async ticket decryption is pending, either started by this
+  // SessionTicketOpen call or one that happened earlier, return
+  // ssl_ticket_aead_retry.
+  if (ticket_decryption_callback_ && !ticket_decryption_callback_->IsDone()) {
+    return ssl_ticket_aead_retry;
+  }
+
+  ssl_ticket_aead_result_t result =
+      FinalizeSessionTicketOpen(out, out_len, max_out_len);
+
+  QuicConnectionStats::TlsServerOperationStats decrypt_ticket_stats;
+  decrypt_ticket_stats.success = (result == ssl_ticket_aead_success);
+  if (async_op_timer_.has_value()) {
+    async_op_timer_->Stop(now());
+    decrypt_ticket_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
+    async_op_timer_.reset();
+    RECORD_LATENCY_IN_US("tls_server_async_decrypt_ticket_latency_us",
+                         decrypt_ticket_stats.async_latency,
+                         "Async decrypt ticket latency in microseconds");
+  }
+  connection_stats().tls_server_decrypt_ticket_stats =
+      std::move(decrypt_ticket_stats);
+
+  return result;
+}
+
+ssl_ticket_aead_result_t TlsServerHandshaker::FinalizeSessionTicketOpen(
+    uint8_t* out,
+    size_t* out_len,
+    size_t max_out_len) {
+  ticket_decryption_callback_ = nullptr;
+  set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  if (decrypted_session_ticket_.empty()) {
+    QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
+    // Ticket decryption failed. Ignore the ticket.
+    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_2);
+    return ssl_ticket_aead_ignore_ticket;
+  }
+  if (max_out_len < decrypted_session_ticket_.size()) {
+    return ssl_ticket_aead_error;
+  }
+  memcpy(out, decrypted_session_ticket_.data(),
+         decrypted_session_ticket_.size());
+  *out_len = decrypted_session_ticket_.size();
+
+  QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_opened);
+  return ssl_ticket_aead_success;
+}
+
+ssl_select_cert_result_t TlsServerHandshaker::EarlySelectCertCallback(
+    const SSL_CLIENT_HELLO* client_hello) {
+  // EarlySelectCertCallback can be called twice from BoringSSL: If the first
+  // call returns ssl_select_cert_retry, when cert selection completes,
+  // SSL_do_handshake will call it again.
+
+  if (select_cert_status_.has_value()) {
+    // This is the second call, return the result directly.
+    QUIC_DVLOG(1) << "EarlySelectCertCallback called to continue handshake, "
+                     "returning directly. success:"
+                  << (select_cert_status_.value() == QUIC_SUCCESS);
+    return (select_cert_status_.value() == QUIC_SUCCESS)
+               ? ssl_select_cert_success
+               : ssl_select_cert_error;
+  }
+
+  // This is the first call.
+  select_cert_status_ = QUIC_PENDING;
+  proof_source_handle_ = MaybeCreateProofSourceHandle();
+
+  if (!pre_shared_key_.empty()) {
+    // TODO(b/154162689) add PSK support to QUIC+TLS.
+    QUIC_BUG(quic_bug_10341_6)
+        << "QUIC server pre-shared keys not yet supported with TLS";
+    return ssl_select_cert_error;
+  }
+
+  {
+    const uint8_t* unused_extension_bytes;
+    size_t unused_extension_len;
+    ticket_received_ = SSL_early_callback_ctx_extension_get(
+        client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes,
+        &unused_extension_len);
+
+    early_data_attempted_ = SSL_early_callback_ctx_extension_get(
+        client_hello, TLSEXT_TYPE_early_data, &unused_extension_bytes,
+        &unused_extension_len);
+  }
+
+  // This callback is called very early by Boring SSL, most of the SSL_get_foo
+  // function do not work at this point, but SSL_get_servername does.
+  const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
+  if (hostname) {
+    crypto_negotiated_params_->sni =
+        QuicHostnameUtils::NormalizeHostname(hostname);
+    if (!ValidateHostname(hostname)) {
+      return ssl_select_cert_error;
+    }
+    if (hostname != crypto_negotiated_params_->sni) {
+      QUIC_CODE_COUNT(quic_tls_server_hostname_diff);
+      QUIC_LOG_EVERY_N_SEC(WARNING, 300)
+          << "Raw and normalized hostnames differ, but both are valid SNIs. "
+             "raw hostname:"
+          << hostname << ", normalized:" << crypto_negotiated_params_->sni;
+    } else {
+      QUIC_CODE_COUNT(quic_tls_server_hostname_same);
+    }
+  } else {
+    QUIC_LOG(INFO) << "No hostname indicated in SNI";
+  }
+
+  std::string error_details;
+  if (!ProcessTransportParameters(client_hello, &error_details)) {
+    CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
+    return ssl_select_cert_error;
+  }
+  OverrideQuicConfigDefaults(session()->config());
+  session()->OnConfigNegotiated();
+
+  auto set_transport_params_result = SetTransportParameters();
+  if (!set_transport_params_result.success) {
+    QUIC_LOG(ERROR) << "Failed to set transport parameters";
+    return ssl_select_cert_error;
+  }
+
+  bssl::UniquePtr<uint8_t> ssl_capabilities;
+  size_t ssl_capabilities_len = 0;
+  absl::string_view ssl_capabilities_view;
+
+  absl::optional<std::string> alps;
+
+  if (CryptoUtils::GetSSLCapabilities(ssl(), &ssl_capabilities,
+                                      &ssl_capabilities_len)) {
+    ssl_capabilities_view =
+        absl::string_view(reinterpret_cast<const char*>(ssl_capabilities.get()),
+                          ssl_capabilities_len);
+  }
+
+  // Enable ALPS for the session's ALPN.
+  SetApplicationSettingsResult alps_result =
+      SetApplicationSettings(AlpnForVersion(session()->version()));
+  if (!alps_result.success) {
+    return ssl_select_cert_error;
+  }
+  alps =
+      alps_result.alps_length > 0
+          ? std::string(alps_result.alps_buffer.get(), alps_result.alps_length)
+          : std::string();
+
+  if (no_select_cert_if_disconnected_ &&
+      !session()->connection()->connected()) {
+    QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_no_select_cert_if_disconnected, 2, 2);
+    select_cert_status_ = QUIC_FAILURE;
+    return ssl_select_cert_error;
+  }
+
+  can_disable_resumption_ = false;
+  const QuicAsyncStatus status = proof_source_handle_->SelectCertificate(
+      session()->connection()->self_address().Normalized(),
+      session()->connection()->peer_address().Normalized(),
+      ssl_capabilities_view, crypto_negotiated_params_->sni,
+      absl::string_view(
+          reinterpret_cast<const char*>(client_hello->client_hello),
+          client_hello->client_hello_len),
+      AlpnForVersion(session()->version()), std::move(alps),
+      set_transport_params_result.quic_transport_params,
+      set_transport_params_result.early_data_context,
+      tls_connection_.ssl_config());
+
+  QUICHE_DCHECK_EQ(status, select_cert_status().value());
+
+  if (status == QUIC_PENDING) {
+    set_expected_ssl_error(SSL_ERROR_PENDING_CERTIFICATE);
+    if (async_op_timer_.has_value()) {
+      QUIC_CODE_COUNT(quic_tls_server_selecting_cert_while_another_op_pending);
+    }
+    async_op_timer_ = QuicTimeAccumulator();
+    async_op_timer_->Start(now());
+    return ssl_select_cert_retry;
+  }
+
+  if (status == QUIC_FAILURE) {
+    return ssl_select_cert_error;
+  }
+
+  return ssl_select_cert_success;
+}
+
+void TlsServerHandshaker::OnSelectCertificateDone(
+    bool ok, bool is_sync, const ProofSource::Chain* chain,
+    absl::string_view handshake_hints, absl::string_view ticket_encryption_key,
+    bool cert_matched_sni, QuicDelayedSSLConfig delayed_ssl_config) {
+  QUIC_DVLOG(1) << "OnSelectCertificateDone. ok:" << ok
+                << ", is_sync:" << is_sync
+                << ", len(handshake_hints):" << handshake_hints.size()
+                << ", len(ticket_encryption_key):"
+                << ticket_encryption_key.size();
+  absl::optional<QuicConnectionContextSwitcher> context_switcher;
+  if (!is_sync) {
+    context_switcher.emplace(connection_context());
+  }
+
+  QUIC_TRACESTRING(absl::StrCat(
+      "TLS select certificate done: ok:", ok,
+      ", certs_found:", (chain != nullptr && !chain->certs.empty()),
+      ", len(handshake_hints):", handshake_hints.size(),
+      ", len(ticket_encryption_key):", ticket_encryption_key.size()));
+
+  ticket_encryption_key_ = std::string(ticket_encryption_key);
+  select_cert_status_ = QUIC_FAILURE;
+  cert_matched_sni_ = cert_matched_sni;
+  if (session()->support_client_cert()) {
+    if (delayed_ssl_config.client_cert_mode.has_value()) {
+      tls_connection_.SetClientCertMode(*delayed_ssl_config.client_cert_mode);
+      QUIC_DVLOG(1) << "client_cert_mode after cert selection: "
+                    << client_cert_mode();
+    }
+  }
+  if (ok) {
+    if (chain && !chain->certs.empty()) {
+      tls_connection_.SetCertChain(chain->ToCryptoBuffers().value);
+      if (!handshake_hints.empty() &&
+          !SSL_set_handshake_hints(
+              ssl(), reinterpret_cast<const uint8_t*>(handshake_hints.data()),
+              handshake_hints.size())) {
+        // If |SSL_set_handshake_hints| fails, the ssl() object will remain
+        // intact, it is as if we didn't call it. The handshaker will
+        // continue to compute signature/decrypt ticket as normal.
+        QUIC_CODE_COUNT(quic_tls_server_set_handshake_hints_failed);
+        QUIC_DVLOG(1) << "SSL_set_handshake_hints failed";
+      }
+      select_cert_status_ = QUIC_SUCCESS;
+    } else {
+      QUIC_DLOG(ERROR) << "No certs provided for host '"
+                       << crypto_negotiated_params_->sni << "', server_address:"
+                       << session()->connection()->self_address()
+                       << ", client_address:"
+                       << session()->connection()->peer_address();
+    }
+  }
+
+  QuicConnectionStats::TlsServerOperationStats select_cert_stats;
+  select_cert_stats.success = (select_cert_status_ == QUIC_SUCCESS);
+  QUICHE_DCHECK_NE(is_sync, async_op_timer_.has_value());
+  if (async_op_timer_.has_value()) {
+    async_op_timer_->Stop(now());
+    select_cert_stats.async_latency = async_op_timer_->GetTotalElapsedTime();
+    async_op_timer_.reset();
+    RECORD_LATENCY_IN_US("tls_server_async_select_cert_latency_us",
+                         select_cert_stats.async_latency,
+                         "Async select cert latency in microseconds");
+  }
+  connection_stats().tls_server_select_cert_stats =
+      std::move(select_cert_stats);
+
+  const int last_expected_ssl_error = expected_ssl_error();
+  set_expected_ssl_error(SSL_ERROR_WANT_READ);
+  if (!is_sync) {
+    QUICHE_DCHECK_EQ(last_expected_ssl_error, SSL_ERROR_PENDING_CERTIFICATE);
+    AdvanceHandshakeFromCallback();
+  }
+}
+
+bool TlsServerHandshaker::WillNotCallComputeSignature() const {
+  return SSL_can_release_private_key(ssl());
+}
+
+bool TlsServerHandshaker::ValidateHostname(const std::string& hostname) const {
+  if (!QuicHostnameUtils::IsValidSNI(hostname)) {
+    // TODO(b/151676147): Include this error string in the CONNECTION_CLOSE
+    // frame.
+    QUIC_DLOG(ERROR) << "Invalid SNI provided: \"" << hostname << "\"";
+    return false;
+  }
+  return true;
+}
+
+int TlsServerHandshaker::TlsExtServernameCallback(int* /*out_alert*/) {
+  // SSL_TLSEXT_ERR_OK causes the server_name extension to be acked in
+  // ServerHello.
+  return SSL_TLSEXT_ERR_OK;
+}
+
+int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
+                                    uint8_t* out_len,
+                                    const uint8_t* in,
+                                    unsigned in_len) {
+  // |in| contains a sequence of 1-byte-length-prefixed values.
+  *out_len = 0;
+  *out = nullptr;
+  if (in_len == 0) {
+    QUIC_DLOG(ERROR) << "No ALPN provided by client";
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  CBS all_alpns;
+  CBS_init(&all_alpns, in, in_len);
+
+  std::vector<absl::string_view> alpns;
+  while (CBS_len(&all_alpns) > 0) {
+    CBS alpn;
+    if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
+      QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
+      return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    const size_t alpn_length = CBS_len(&alpn);
+    if (alpn_length == 0) {
+      QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
+      return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
+                       alpn_length);
+  }
+
+  // TODO(wub): Remove QuicSession::SelectAlpn. QuicSessions should know the
+  // ALPN on construction.
+  auto selected_alpn = session()->SelectAlpn(alpns);
+  if (selected_alpn == alpns.end()) {
+    QUIC_DLOG(ERROR) << "No known ALPN provided by client";
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  session()->OnAlpnSelected(*selected_alpn);
+  valid_alpn_received_ = true;
+  *out_len = selected_alpn->size();
+  *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
+  return SSL_TLSEXT_ERR_OK;
+}
+
+TlsServerHandshaker::SetApplicationSettingsResult
+TlsServerHandshaker::SetApplicationSettings(absl::string_view alpn) {
+  TlsServerHandshaker::SetApplicationSettingsResult result;
+  const uint8_t* alps_data = nullptr;
+
+  const std::string& hostname = crypto_negotiated_params_->sni;
+  std::string accept_ch_value = GetAcceptChValueForHostname(hostname);
+  std::string origin = absl::StrCat("https://", hostname);
+  uint16_t port = session()->self_address().port();
+  if (port != kDefaultPort) {
+    // This should be rare in production, but useful for test servers.
+    QUIC_CODE_COUNT(quic_server_alps_non_default_port);
+    absl::StrAppend(&origin, ":", port);
+  }
+
+  if (!accept_ch_value.empty()) {
+    AcceptChFrame frame{{{std::move(origin), std::move(accept_ch_value)}}};
+    result.alps_length =
+        HttpEncoder::SerializeAcceptChFrame(frame, &result.alps_buffer);
+    alps_data = reinterpret_cast<const uint8_t*>(result.alps_buffer.get());
+  }
+
+  if (SSL_add_application_settings(
+          ssl(), reinterpret_cast<const uint8_t*>(alpn.data()), alpn.size(),
+          alps_data, result.alps_length) != 1) {
+    QUIC_DLOG(ERROR) << "Failed to enable ALPS";
+    result.success = false;
+  } else {
+    result.success = true;
+  }
+  return result;
+}
+
+SSL* TlsServerHandshaker::GetSsl() const { return ssl(); }
+
+}  // namespace quic
diff --git a/quiche/quic/core/tls_server_handshaker.h b/quiche/quic/core/tls_server_handshaker.h
new file mode 100644
index 0000000..b7df310
--- /dev/null
+++ b/quiche/quic/core/tls_server_handshaker.h
@@ -0,0 +1,392 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
+#define QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/tls_server_connection.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_time_accumulator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/tls_handshaker.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+// An implementation of QuicCryptoServerStreamBase which uses
+// TLS 1.3 for the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE TlsServerHandshaker
+    : public TlsHandshaker,
+      public TlsServerConnection::Delegate,
+      public ProofSourceHandleCallback,
+      public QuicCryptoServerStreamBase {
+ public:
+  // |crypto_config| must outlive TlsServerHandshaker.
+  TlsServerHandshaker(QuicSession* session,
+                      const QuicCryptoServerConfig* crypto_config);
+  TlsServerHandshaker(const TlsServerHandshaker&) = delete;
+  TlsServerHandshaker& operator=(const TlsServerHandshaker&) = delete;
+
+  ~TlsServerHandshaker() override;
+
+  // From QuicCryptoServerStreamBase
+  void CancelOutstandingCallbacks() override;
+  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
+  void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) override;
+  bool DisableResumption() override;
+  bool IsZeroRtt() const override;
+  bool IsResumption() const override;
+  bool ResumptionAttempted() const override;
+  // Must be called after EarlySelectCertCallback is started.
+  bool EarlyDataAttempted() const override;
+  int NumServerConfigUpdateMessagesSent() const override;
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) override;
+  void OnPacketDecrypted(EncryptionLevel level) override;
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnConnectionClosed(QuicErrorCode error,
+                          ConnectionCloseSource source) override;
+  void OnHandshakeDoneReceived() override;
+  std::string GetAddressToken(
+      const CachedNetworkParameters* cached_network_params) const override;
+  bool ValidateAddressToken(absl::string_view token) const override;
+  void OnNewTokenReceived(absl::string_view token) override;
+  bool ShouldSendExpectCTHeader() const override;
+  bool DidCertMatchSni() const override;
+  const ProofSource::Details* ProofSourceDetails() const override;
+  bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
+                            size_t result_len, std::string* result) override;
+  SSL* GetSsl() const override;
+
+  // From QuicCryptoServerStreamBase and TlsHandshaker
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  HandshakeState GetHandshakeState() const override;
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> state) override;
+  size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override;
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
+  void SetWriteSecret(EncryptionLevel level,
+                      const SSL_CIPHER* cipher,
+                      const std::vector<uint8_t>& write_secret) override;
+
+  // Called with normalized SNI hostname as |hostname|.  Return value will be
+  // sent in an ACCEPT_CH frame in the TLS ALPS extension, unless empty.
+  virtual std::string GetAcceptChValueForHostname(
+      const std::string& hostname) const;
+
+  // Get the ClientCertMode that is currently in effect on this handshaker.
+  ClientCertMode client_cert_mode() const {
+    return tls_connection_.ssl_config().client_cert_mode;
+  }
+
+ protected:
+  // Override for tracing.
+  void InfoCallback(int type, int value) override;
+
+  // Creates a proof source handle for selecting cert and computing signature.
+  virtual std::unique_ptr<ProofSourceHandle> MaybeCreateProofSourceHandle();
+
+  // Hook to allow the server to override parts of the QuicConfig based on SNI
+  // before we generate transport parameters.
+  virtual void OverrideQuicConfigDefaults(QuicConfig* config);
+
+  virtual bool ValidateHostname(const std::string& hostname) const;
+
+  const TlsConnection* tls_connection() const override {
+    return &tls_connection_;
+  }
+
+  virtual void ProcessAdditionalTransportParameters(
+      const TransportParameters& /*params*/) {}
+
+  // Called when a potentially async operation is done and the done callback
+  // needs to advance the handshake.
+  void AdvanceHandshakeFromCallback();
+
+  // TlsHandshaker implementation:
+  void FinishHandshake() override;
+  void ProcessPostHandshakeMessage() override {}
+  QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  // TlsServerConnection::Delegate implementation:
+  // Used to select certificates and process transport parameters.
+  ssl_select_cert_result_t EarlySelectCertCallback(
+      const SSL_CLIENT_HELLO* client_hello) override;
+  int TlsExtServernameCallback(int* out_alert) override;
+  int SelectAlpn(const uint8_t** out,
+                 uint8_t* out_len,
+                 const uint8_t* in,
+                 unsigned in_len) override;
+  ssl_private_key_result_t PrivateKeySign(uint8_t* out,
+                                          size_t* out_len,
+                                          size_t max_out,
+                                          uint16_t sig_alg,
+                                          absl::string_view in) override;
+  ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
+                                              size_t* out_len,
+                                              size_t max_out) override;
+  size_t SessionTicketMaxOverhead() override;
+  int SessionTicketSeal(uint8_t* out,
+                        size_t* out_len,
+                        size_t max_out_len,
+                        absl::string_view in) override;
+  ssl_ticket_aead_result_t SessionTicketOpen(uint8_t* out,
+                                             size_t* out_len,
+                                             size_t max_out_len,
+                                             absl::string_view in) override;
+  // Called when ticket_decryption_callback_ is done to determine a final
+  // decryption result.
+  ssl_ticket_aead_result_t FinalizeSessionTicketOpen(uint8_t* out,
+                                                     size_t* out_len,
+                                                     size_t max_out_len);
+  TlsConnection::Delegate* ConnectionDelegate() override { return this; }
+
+  // The status of cert selection. nullopt means it hasn't started.
+  const absl::optional<QuicAsyncStatus>& select_cert_status() const {
+    return select_cert_status_;
+  }
+  // Whether |cert_verify_sig_| contains a valid signature.
+  // NOTE: BoringSSL queries the result of a async signature operation using
+  // PrivateKeyComplete(), a successful PrivateKeyComplete() will clear the
+  // content of |cert_verify_sig_|, this function should not be called after
+  // that.
+  bool HasValidSignature(size_t max_signature_size) const;
+
+  // ProofSourceHandleCallback implementation:
+  void OnSelectCertificateDone(
+      bool ok, bool is_sync, const ProofSource::Chain* chain,
+      absl::string_view handshake_hints,
+      absl::string_view ticket_encryption_key, bool cert_matched_sni,
+      QuicDelayedSSLConfig delayed_ssl_config) override;
+
+  void OnComputeSignatureDone(
+      bool ok,
+      bool is_sync,
+      std::string signature,
+      std::unique_ptr<ProofSource::Details> details) override;
+
+  void set_encryption_established(bool encryption_established) {
+    encryption_established_ = encryption_established;
+  }
+
+  bool WillNotCallComputeSignature() const override;
+
+  void SetIgnoreTicketOpen(bool value) { ignore_ticket_open_ = value; }
+
+ private:
+  class QUIC_EXPORT_PRIVATE DecryptCallback
+      : public ProofSource::DecryptCallback {
+   public:
+    explicit DecryptCallback(TlsServerHandshaker* handshaker);
+    void Run(std::vector<uint8_t> plaintext) override;
+
+    // If called, Cancel causes the pending callback to be a no-op.
+    void Cancel();
+
+    // Return true if either
+    // - Cancel() has been called.
+    // - Run() has been called, or is in the middle of it.
+    bool IsDone() const { return handshaker_ == nullptr; }
+
+   private:
+    TlsServerHandshaker* handshaker_;
+  };
+
+  // DefaultProofSourceHandle delegates all operations to the shared proof
+  // source.
+  class QUIC_EXPORT_PRIVATE DefaultProofSourceHandle
+      : public ProofSourceHandle {
+   public:
+    DefaultProofSourceHandle(TlsServerHandshaker* handshaker,
+                             ProofSource* proof_source);
+
+    ~DefaultProofSourceHandle() override;
+
+    // Close the handle. Cancel the pending signature operation, if any.
+    void CloseHandle() override;
+
+    // Delegates to proof_source_->GetCertChain.
+    // Returns QUIC_SUCCESS or QUIC_FAILURE. Never returns QUIC_PENDING.
+    QuicAsyncStatus SelectCertificate(
+        const QuicSocketAddress& server_address,
+        const QuicSocketAddress& client_address,
+        absl::string_view ssl_capabilities,
+        const std::string& hostname,
+        absl::string_view client_hello,
+        const std::string& alpn,
+        absl::optional<std::string> alps,
+        const std::vector<uint8_t>& quic_transport_params,
+        const absl::optional<std::vector<uint8_t>>& early_data_context,
+        const QuicSSLConfig& ssl_config) override;
+
+    // Delegates to proof_source_->ComputeTlsSignature.
+    // Returns QUIC_SUCCESS, QUIC_FAILURE or QUIC_PENDING.
+    QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
+                                     const QuicSocketAddress& client_address,
+                                     const std::string& hostname,
+                                     uint16_t signature_algorithm,
+                                     absl::string_view in,
+                                     size_t max_signature_size) override;
+
+   protected:
+    ProofSourceHandleCallback* callback() override { return handshaker_; }
+
+   private:
+    class QUIC_EXPORT_PRIVATE DefaultSignatureCallback
+        : public ProofSource::SignatureCallback {
+     public:
+      explicit DefaultSignatureCallback(DefaultProofSourceHandle* handle)
+          : handle_(handle) {}
+
+      void Run(bool ok,
+               std::string signature,
+               std::unique_ptr<ProofSource::Details> details) override {
+        if (handle_ == nullptr) {
+          // Operation has been canceled, or Run has been called.
+          return;
+        }
+
+        DefaultProofSourceHandle* handle = handle_;
+        handle_ = nullptr;
+
+        handle->signature_callback_ = nullptr;
+        if (handle->handshaker_ != nullptr) {
+          handle->handshaker_->OnComputeSignatureDone(
+              ok, is_sync_, std::move(signature), std::move(details));
+        }
+      }
+
+      // If called, Cancel causes the pending callback to be a no-op.
+      void Cancel() { handle_ = nullptr; }
+
+      void set_is_sync(bool is_sync) { is_sync_ = is_sync; }
+
+     private:
+      DefaultProofSourceHandle* handle_;
+      // Set to false if handle_->ComputeSignature returns QUIC_PENDING.
+      bool is_sync_ = true;
+    };
+
+    // Not nullptr on construction. Set to nullptr when cancelled.
+    TlsServerHandshaker* handshaker_;  // Not owned.
+    ProofSource* proof_source_;        // Not owned.
+    DefaultSignatureCallback* signature_callback_ = nullptr;
+  };
+
+  struct QUIC_NO_EXPORT SetTransportParametersResult {
+    bool success = false;
+    // Empty vector if QUIC transport params are not set successfully.
+    std::vector<uint8_t> quic_transport_params;
+    // absl::nullopt if there is no application state to begin with.
+    // Empty vector if application state is not set successfully.
+    absl::optional<std::vector<uint8_t>> early_data_context;
+  };
+
+  SetTransportParametersResult SetTransportParameters();
+  bool ProcessTransportParameters(const SSL_CLIENT_HELLO* client_hello,
+                                  std::string* error_details);
+
+  struct QUIC_NO_EXPORT SetApplicationSettingsResult {
+    bool success = false;
+    std::unique_ptr<char[]> alps_buffer;
+    size_t alps_length = 0;
+  };
+  SetApplicationSettingsResult SetApplicationSettings(absl::string_view alpn);
+
+  QuicConnectionStats& connection_stats() {
+    return session()->connection()->mutable_stats();
+  }
+  QuicTime now() const { return session()->GetClock()->Now(); }
+
+  QuicConnectionContext* connection_context() {
+    return session()->connection()->context();
+  }
+
+  std::unique_ptr<ProofSourceHandle> proof_source_handle_;
+  ProofSource* proof_source_;
+
+  // State to handle potentially asynchronous session ticket decryption.
+  // |ticket_decryption_callback_| points to the non-owned callback that was
+  // passed to ProofSource::TicketCrypter::Decrypt but hasn't finished running
+  // yet.
+  DecryptCallback* ticket_decryption_callback_ = nullptr;
+  // |decrypted_session_ticket_| contains the decrypted session ticket after the
+  // callback has run but before it is passed to BoringSSL.
+  std::vector<uint8_t> decrypted_session_ticket_;
+  // |ticket_received_| tracks whether we received a resumption ticket from the
+  // client. It does not matter whether we were able to decrypt said ticket or
+  // if we actually resumed a session with it - the presence of this ticket
+  // indicates that the client attempted a resumption.
+  bool ticket_received_ = false;
+
+  // True if the "early_data" extension is in the client hello.
+  bool early_data_attempted_ = false;
+
+  // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
+  bool ignore_ticket_open_ = false;
+
+  // nullopt means select cert hasn't started.
+  absl::optional<QuicAsyncStatus> select_cert_status_;
+
+  std::string cert_verify_sig_;
+  std::unique_ptr<ProofSource::Details> proof_source_details_;
+
+  // Count the duration of the current async operation, if any.
+  absl::optional<QuicTimeAccumulator> async_op_timer_;
+
+  std::unique_ptr<ApplicationState> application_state_;
+
+  // Pre-shared key used during the handshake.
+  std::string pre_shared_key_;
+
+  // (optional) Key to use for encrypting TLS resumption tickets.
+  std::string ticket_encryption_key_;
+
+  HandshakeState state_ = HANDSHAKE_START;
+  bool encryption_established_ = false;
+  bool valid_alpn_received_ = false;
+  bool can_disable_resumption_ = true;
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
+      crypto_negotiated_params_;
+  TlsServerConnection tls_connection_;
+  const QuicCryptoServerConfig* crypto_config_;  // Unowned.
+  // The last received CachedNetworkParameters from a validated address token.
+  mutable std::unique_ptr<CachedNetworkParameters>
+      last_received_cached_network_params_;
+
+  bool cert_matched_sni_ = false;
+  const bool no_select_cert_if_disconnected_ =
+      GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
diff --git a/quiche/quic/core/tls_server_handshaker_test.cc b/quiche/quic/core/tls_server_handshaker_test.cc
new file mode 100644
index 0000000..b49d959
--- /dev/null
+++ b/quiche/quic/core/tls_server_handshaker_test.cc
@@ -0,0 +1,1080 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/tls_server_handshaker.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/certificate_util.h"
+#include "quiche/quic/core/crypto/client_proof_source.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_client_handshaker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/failing_proof_source.h"
+#include "quiche/quic/test_tools/fake_proof_source.h"
+#include "quiche/quic/test_tools/fake_proof_source_handle.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+#include "quiche/quic/test_tools/test_ticket_crypter.h"
+
+namespace quic {
+class QuicConnection;
+class QuicStream;
+}  // namespace quic
+
+using testing::_;
+using testing::NiceMock;
+using testing::Return;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+struct TestParams {
+  ParsedQuicVersion version;
+  bool disable_resumption;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.disable_resumption ? "ResumptionDisabled" : "ResumptionEnabled"));
+}
+
+// Constructs test permutations.
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const auto& version : AllSupportedVersionsWithTls()) {
+    for (bool disable_resumption : {false, true}) {
+      params.push_back(TestParams{version, disable_resumption});
+    }
+  }
+  return params;
+}
+
+class TestTlsServerHandshaker : public TlsServerHandshaker {
+ public:
+  TestTlsServerHandshaker(QuicSession* session,
+                          const QuicCryptoServerConfig* crypto_config)
+      : TlsServerHandshaker(session, crypto_config),
+        proof_source_(crypto_config->proof_source()) {
+    ON_CALL(*this, MaybeCreateProofSourceHandle())
+        .WillByDefault(testing::Invoke(
+            this, &TestTlsServerHandshaker::RealMaybeCreateProofSourceHandle));
+
+    ON_CALL(*this, OverrideQuicConfigDefaults(_))
+        .WillByDefault(testing::Invoke(
+            this, &TestTlsServerHandshaker::RealOverrideQuicConfigDefaults));
+  }
+
+  MOCK_METHOD(std::unique_ptr<ProofSourceHandle>,
+              MaybeCreateProofSourceHandle,
+              (),
+              (override));
+
+  MOCK_METHOD(void, OverrideQuicConfigDefaults, (QuicConfig * config),
+              (override));
+
+  void SetupProofSourceHandle(
+      FakeProofSourceHandle::Action select_cert_action,
+      FakeProofSourceHandle::Action compute_signature_action,
+      QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig()) {
+    EXPECT_CALL(*this, MaybeCreateProofSourceHandle())
+        .WillOnce(
+            testing::Invoke([this, select_cert_action, compute_signature_action,
+                             dealyed_ssl_config]() {
+              auto handle = std::make_unique<FakeProofSourceHandle>(
+                  proof_source_, this, select_cert_action,
+                  compute_signature_action, dealyed_ssl_config);
+              fake_proof_source_handle_ = handle.get();
+              return handle;
+            }));
+  }
+
+  FakeProofSourceHandle* fake_proof_source_handle() {
+    return fake_proof_source_handle_;
+  }
+
+  bool received_client_cert() const { return received_client_cert_; }
+
+  using TlsServerHandshaker::AdvanceHandshake;
+  using TlsServerHandshaker::expected_ssl_error;
+
+ protected:
+  QuicAsyncStatus VerifyCertChain(
+      const std::vector<std::string>& certs, std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details, uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    received_client_cert_ = true;
+    return TlsServerHandshaker::VerifyCertChain(certs, error_details, details,
+                                                out_alert, std::move(callback));
+  }
+
+ private:
+  std::unique_ptr<ProofSourceHandle> RealMaybeCreateProofSourceHandle() {
+    return TlsServerHandshaker::MaybeCreateProofSourceHandle();
+  }
+
+  void RealOverrideQuicConfigDefaults(QuicConfig* config) {
+    return TlsServerHandshaker::OverrideQuicConfigDefaults(config);
+  }
+
+  // Owned by TlsServerHandshaker.
+  FakeProofSourceHandle* fake_proof_source_handle_ = nullptr;
+  ProofSource* proof_source_ = nullptr;
+  bool received_client_cert_ = false;
+};
+
+class TlsServerHandshakerTestSession : public TestQuicSpdyServerSession {
+ public:
+  using TestQuicSpdyServerSession::TestQuicSpdyServerSession;
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* /*compressed_certs_cache*/) override {
+    if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
+      return std::make_unique<NiceMock<TestTlsServerHandshaker>>(this,
+                                                                 crypto_config);
+    }
+
+    QUICHE_CHECK(false) << "Unsupported handshake protocol: "
+                        << connection()->version().handshake_protocol;
+    return nullptr;
+  }
+};
+
+class TlsServerHandshakerTest : public QuicTestWithParam<TestParams> {
+ public:
+  TlsServerHandshakerTest()
+      : server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        server_id_(kServerHostname, kServerPort, false),
+        supported_versions_({GetParam().version}) {
+    SetQuicFlag(FLAGS_quic_disable_server_tls_resumption,
+                GetParam().disable_resumption);
+    client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+        crypto_test_utils::ProofVerifierForTesting(),
+        std::make_unique<test::SimpleSessionCache>());
+    InitializeServerConfig();
+    InitializeServer();
+    InitializeFakeClient();
+  }
+
+  ~TlsServerHandshakerTest() override {
+    // Ensure that anything that might reference |helpers_| is destroyed before
+    // |helpers_| is destroyed.
+    server_session_.reset();
+    client_session_.reset();
+    helpers_.clear();
+    alarm_factories_.clear();
+  }
+
+  void InitializeServerConfig() {
+    auto ticket_crypter = std::make_unique<TestTicketCrypter>();
+    ticket_crypter_ = ticket_crypter.get();
+    auto proof_source = std::make_unique<FakeProofSource>();
+    proof_source_ = proof_source.get();
+    proof_source_->SetTicketCrypter(std::move(ticket_crypter));
+    server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
+        QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+        std::move(proof_source), KeyExchangeSource::Default());
+  }
+
+  void InitializeServerConfigWithFailingProofSource() {
+    server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
+        QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+        std::make_unique<FailingProofSource>(), KeyExchangeSource::Default());
+  }
+
+  void CreateTlsServerHandshakerTestSession(MockQuicConnectionHelper* helper,
+                                            MockAlarmFactory* alarm_factory) {
+    server_connection_ = new PacketSavingConnection(
+        helper, alarm_factory, Perspective::IS_SERVER,
+        ParsedVersionOfIndex(supported_versions_, 0));
+
+    TlsServerHandshakerTestSession* server_session =
+        new TlsServerHandshakerTestSession(
+            server_connection_, DefaultQuicConfig(), supported_versions_,
+            server_crypto_config_.get(), &server_compressed_certs_cache_);
+    server_session->set_client_cert_mode(initial_client_cert_mode_);
+    server_session->Initialize();
+
+    // We advance the clock initially because the default time is zero and the
+    // strike register worries that we've just overflowed a uint32_t time.
+    server_connection_->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
+
+    QUICHE_CHECK(server_session);
+    server_session_.reset(server_session);
+  }
+
+  void InitializeServerWithFakeProofSourceHandle() {
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateTlsServerHandshakerTestSession(helpers_.back().get(),
+                                         alarm_factories_.back().get());
+    server_handshaker_ = static_cast<NiceMock<TestTlsServerHandshaker>*>(
+        server_session_->GetMutableCryptoStream());
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
+          return std::find(
+              alpns.cbegin(), alpns.cend(),
+              AlpnForVersion(server_session_->connection()->version()));
+        });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        server_crypto_config_.get());
+  }
+
+  // Initializes the crypto server stream state for testing.  May be
+  // called multiple times.
+  void InitializeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        server_crypto_config_.get(), &server_compressed_certs_cache_,
+        &server_connection_, &server_session);
+    QUICHE_CHECK(server_session);
+    server_session_.reset(server_session);
+    server_handshaker_ = nullptr;
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly([this](const std::vector<absl::string_view>& alpns) {
+          return std::find(
+              alpns.cbegin(), alpns.cend(),
+              AlpnForVersion(server_session_->connection()->version()));
+        });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        server_crypto_config_.get());
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoClientStream* client_stream() {
+    return client_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake client, and all its associated state, for
+  // testing.  May be called multiple times.
+  void InitializeFakeClient() {
+    TestQuicSpdyClientSession* client_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateClientSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        client_crypto_config_.get(), &client_connection_, &client_session);
+    const std::string default_alpn =
+        AlpnForVersion(client_connection_->version());
+    ON_CALL(*client_session, GetAlpnsToOffer())
+        .WillByDefault(Return(std::vector<std::string>({default_alpn})));
+    QUICHE_CHECK(client_session);
+    client_session_.reset(client_session);
+    moved_messages_counts_ = {0, 0};
+  }
+
+  void CompleteCryptoHandshake() {
+    while (!client_stream()->one_rtt_keys_available() ||
+           !server_stream()->one_rtt_keys_available()) {
+      auto previous_moved_messages_counts = moved_messages_counts_;
+      AdvanceHandshakeWithFakeClient();
+      // Check that the handshake has made forward progress
+      ASSERT_NE(previous_moved_messages_counts, moved_messages_counts_);
+    }
+  }
+
+  // Performs a single round of handshake message-exchange between the
+  // client and server.
+  void AdvanceHandshakeWithFakeClient() {
+    QUICHE_CHECK(server_connection_);
+    QUICHE_CHECK(client_session_ != nullptr);
+
+    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    // Call CryptoConnect if we haven't moved any client messages yet.
+    if (moved_messages_counts_.first == 0) {
+      client_stream()->CryptoConnect();
+    }
+    moved_messages_counts_ = crypto_test_utils::AdvanceHandshake(
+        client_connection_, client_stream(), moved_messages_counts_.first,
+        server_connection_, server_stream(), moved_messages_counts_.second);
+  }
+
+  void ExpectHandshakeSuccessful() {
+    EXPECT_TRUE(client_stream()->one_rtt_keys_available());
+    EXPECT_TRUE(client_stream()->encryption_established());
+    EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+    EXPECT_TRUE(server_stream()->encryption_established());
+    EXPECT_EQ(HANDSHAKE_COMPLETE, client_stream()->GetHandshakeState());
+    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_stream()->GetHandshakeState());
+
+    const auto& client_crypto_params =
+        client_stream()->crypto_negotiated_params();
+    const auto& server_crypto_params =
+        server_stream()->crypto_negotiated_params();
+    // The TLS params should be filled in on the client.
+    EXPECT_NE(0, client_crypto_params.cipher_suite);
+    EXPECT_NE(0, client_crypto_params.key_exchange_group);
+    EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
+
+    // The cipher suite and key exchange group should match on the client and
+    // server.
+    EXPECT_EQ(client_crypto_params.cipher_suite,
+              server_crypto_params.cipher_suite);
+    EXPECT_EQ(client_crypto_params.key_exchange_group,
+              server_crypto_params.key_exchange_group);
+    // We don't support client certs on the server (yet), so the server
+    // shouldn't have a peer signature algorithm to report.
+    EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
+  }
+
+  // Should only be called when using FakeProofSourceHandle.
+  FakeProofSourceHandle::SelectCertArgs last_select_cert_args() const {
+    QUICHE_CHECK(server_handshaker_ &&
+                 server_handshaker_->fake_proof_source_handle());
+    QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
+                      ->all_select_cert_args()
+                      .empty());
+    return server_handshaker_->fake_proof_source_handle()
+        ->all_select_cert_args()
+        .back();
+  }
+
+  // Should only be called when using FakeProofSourceHandle.
+  FakeProofSourceHandle::ComputeSignatureArgs last_compute_signature_args()
+      const {
+    QUICHE_CHECK(server_handshaker_ &&
+                 server_handshaker_->fake_proof_source_handle());
+    QUICHE_CHECK(!server_handshaker_->fake_proof_source_handle()
+                      ->all_compute_signature_args()
+                      .empty());
+    return server_handshaker_->fake_proof_source_handle()
+        ->all_compute_signature_args()
+        .back();
+  }
+
+ protected:
+  // Setup the client to send a (self-signed) client cert to the server, if
+  // requested. InitializeFakeClient() must be called after this to take effect.
+  bool SetupClientCert() {
+    auto client_proof_source = std::make_unique<DefaultClientProofSource>();
+
+    CertificatePrivateKey client_cert_key(
+        MakeKeyPairForSelfSignedCertificate());
+
+    CertificateOptions options;
+    options.subject = "CN=subject";
+    options.serial_number = 0x12345678;
+    options.validity_start = {2020, 1, 1, 0, 0, 0};
+    options.validity_end = {2049, 12, 31, 0, 0, 0};
+    std::string der_cert =
+        CreateSelfSignedCertificate(*client_cert_key.private_key(), options);
+
+    quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+        client_cert_chain(new ClientProofSource::Chain({der_cert}));
+
+    if (!client_proof_source->AddCertAndKey({"*"}, client_cert_chain,
+                                            std::move(client_cert_key))) {
+      return false;
+    }
+
+    client_crypto_config_->set_proof_source(std::move(client_proof_source));
+    return true;
+  }
+
+  // Every connection gets its own MockQuicConnectionHelper and
+  // MockAlarmFactory, tracked separately from the server and client state so
+  // their lifetimes persist through the whole test.
+  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
+  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
+
+  // Server state.
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  // Only set when initialized with InitializeServerWithFakeProofSourceHandle.
+  NiceMock<TestTlsServerHandshaker>* server_handshaker_ = nullptr;
+  TestTicketCrypter* ticket_crypter_;  // owned by proof_source_
+  FakeProofSource* proof_source_;      // owned by server_crypto_config_
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+  QuicServerId server_id_;
+  ClientCertMode initial_client_cert_mode_ = ClientCertMode::kNone;
+
+  // Client state.
+  PacketSavingConnection* client_connection_;
+  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
+  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
+
+  crypto_test_utils::FakeClientOptions client_options_;
+  // How many handshake messages have been moved from client to server and
+  // server to client.
+  std::pair<size_t, size_t> moved_messages_counts_ = {0, 0};
+
+  // Which QUIC versions the client and server support.
+  ParsedQuicVersionVector supported_versions_;
+};
+
+INSTANTIATE_TEST_SUITE_P(TlsServerHandshakerTests,
+                         TlsServerHandshakerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(TlsServerHandshakerTest, NotInitiallyConected) {
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsServerHandshakerTest, ConnectedAfterTlsHandshake) {
+  CompleteCryptoHandshake();
+  EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertSuccess) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertFailure) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::FAIL_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  // Check that the server didn't send any handshake messages, because it failed
+  // to handshake.
+  EXPECT_EQ(moved_messages_counts_.second, 0u);
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSelectCertAndSignature) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_ASYNC);
+
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  // A select cert operation is now pending.
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  EXPECT_EQ(server_handshaker_->expected_ssl_error(),
+            SSL_ERROR_PENDING_CERTIFICATE);
+
+  // Complete the pending select cert. It should advance the handshake to
+  // compute a signature, which will also be saved as a pending operation.
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  // A compute signature operation is now pending.
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  EXPECT_EQ(server_handshaker_->expected_ssl_error(),
+            SSL_ERROR_WANT_PRIVATE_KEY_OPERATION);
+
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeWithAsyncSignature) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
+  // asynchronously.
+  proof_source_->Activate();
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
+  proof_source_->InvokePendingCallback(0);
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, CancelPendingSelectCert) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->CancelOutstandingCallbacks();
+  ASSERT_FALSE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  // CompletePendingOperation should be noop.
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+}
+
+TEST_P(TlsServerHandshakerTest, CancelPendingSignature) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
+  // asynchronously.
+  proof_source_->Activate();
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
+  server_session_ = nullptr;
+
+  proof_source_->InvokePendingCallback(0);
+}
+
+TEST_P(TlsServerHandshakerTest, ExtractSNI) {
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
+            "test.example.com");
+}
+
+TEST_P(TlsServerHandshakerTest, HostnameForCertSelectionAndComputeSignature) {
+  // Client uses upper case letters in hostname. It is considered valid by
+  // QuicHostnameUtils::IsValidSNI, but it should be normalized for cert
+  // selection.
+  server_id_ = QuicServerId("tEsT.EXAMPLE.CoM", kServerPort, false);
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
+            "test.example.com");
+
+  EXPECT_EQ(last_select_cert_args().hostname, "test.example.com");
+  EXPECT_EQ(last_compute_signature_args().hostname, "test.example.com");
+}
+
+TEST_P(TlsServerHandshakerTest, SSLConfigForCertSelection) {
+  InitializeServerWithFakeProofSourceHandle();
+
+  // Disable early data.
+  server_session_->set_early_data_enabled(false);
+
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_FALSE(last_select_cert_args().ssl_config.early_data_enabled);
+}
+
+TEST_P(TlsServerHandshakerTest, ConnectionClosedOnTlsError) {
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _, _));
+
+  // Send a zero-length ClientHello from client to server.
+  char bogus_handshake_message[] = {
+      // Handshake struct (RFC 8446 appendix B.3)
+      1,        // HandshakeType client_hello
+      0, 0, 0,  // uint24 length
+  };
+
+  // Install a packet flusher such that the packets generated by
+  // |server_connection_| in response to this handshake message are more likely
+  // to be coalesced and/or batched in the writer.
+  //
+  // This is required by TlsServerHandshaker because without the flusher, it
+  // tends to generate many small, uncoalesced packets, one per
+  // TlsHandshaker::WriteMessage.
+  QuicConnection::ScopedPacketFlusher flusher(server_connection_);
+  server_stream()->crypto_message_parser()->ProcessInput(
+      absl::string_view(bogus_handshake_message,
+                        ABSL_ARRAYSIZE(bogus_handshake_message)),
+      ENCRYPTION_INITIAL);
+
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsServerHandshakerTest, ClientSendingBadALPN) {
+  const std::string kTestBadClientAlpn = "bad-client-alpn";
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
+
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED,
+                              static_cast<QuicIetfTransportErrorCodes>(
+                                  CRYPTO_ERROR_FIRST + 120),
+                              "TLS handshake failure (ENCRYPTION_INITIAL) 120: "
+                              "no application protocol",
+                              _));
+
+  AdvanceHandshakeWithFakeClient();
+
+  EXPECT_FALSE(client_stream()->one_rtt_keys_available());
+  EXPECT_FALSE(client_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+  EXPECT_FALSE(server_stream()->encryption_established());
+}
+
+TEST_P(TlsServerHandshakerTest, CustomALPNNegotiation) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  const std::string kTestAlpn = "A Custom ALPN Value";
+  const std::vector<std::string> kTestAlpns(
+      {"foo", "bar", kTestAlpn, "something else"});
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillRepeatedly(Return(kTestAlpns));
+  EXPECT_CALL(*server_session_, SelectAlpn(_))
+      .WillOnce(
+          [kTestAlpn, kTestAlpns](const std::vector<absl::string_view>& alpns) {
+            EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns));
+            return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
+          });
+  EXPECT_CALL(*client_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
+  EXPECT_CALL(*server_session_, OnAlpnSelected(absl::string_view(kTestAlpn)));
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+}
+
+TEST_P(TlsServerHandshakerTest, RejectInvalidSNI) {
+  server_id_ = QuicServerId("invalid!.example.com", kServerPort, false);
+  InitializeFakeClient();
+  static_cast<TlsClientHandshaker*>(
+      QuicCryptoClientStreamPeer::GetHandshaker(client_stream()))
+      ->AllowInvalidSNIForTests();
+
+  // Run the handshake and expect it to fail.
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_P(TlsServerHandshakerTest, Resumption) {
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->ResumptionAttempted());
+
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_NE(server_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_NE(server_stream()->ResumptionAttempted(),
+            GetParam().disable_resumption);
+}
+
+TEST_P(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) {
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->SetRunCallbacksAsync(true);
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+  if (GetParam().disable_resumption) {
+    ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 0u);
+    return;
+  }
+  // Test that the DecryptCallback will be run asynchronously, and then run it.
+  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
+  ticket_crypter_->RunPendingCallback(0);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_TRUE(client_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_P(TlsServerHandshakerTest, AdvanceHandshakeDuringAsyncDecryptCallback) {
+  if (GetParam().disable_resumption) {
+    return;
+  }
+
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->SetRunCallbacksAsync(true);
+  // Now do another handshake
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+
+  // Ensure an async DecryptCallback is now pending.
+  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
+
+  {
+    QuicConnection::ScopedPacketFlusher flusher(server_connection_);
+    server_handshaker_->AdvanceHandshake();
+  }
+
+  // This will delete |server_handshaker_|.
+  server_session_ = nullptr;
+
+  ticket_crypter_->RunPendingCallback(0);  // Should not crash.
+}
+
+TEST_P(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) {
+  if (GetParam().disable_resumption) {
+    return;
+  }
+
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->set_fail_decrypt(true);
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_P(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) {
+  if (GetParam().disable_resumption) {
+    return;
+  }
+
+  // Do the first handshake
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  ticket_crypter_->set_fail_decrypt(true);
+  ticket_crypter_->SetRunCallbacksAsync(true);
+  // Now do another handshake
+  InitializeServer();
+  InitializeFakeClient();
+
+  AdvanceHandshakeWithFakeClient();
+  // Test that the DecryptCallback will be run asynchronously, and then run it.
+  ASSERT_EQ(ticket_crypter_->NumPendingCallbacks(), 1u);
+  ticket_crypter_->RunPendingCallback(0);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsResumption());
+  EXPECT_TRUE(server_stream()->ResumptionAttempted());
+}
+
+TEST_P(TlsServerHandshakerTest, HandshakeFailsWithFailingProofSource) {
+  InitializeServerConfigWithFailingProofSource();
+  InitializeServer();
+  InitializeFakeClient();
+
+  // Attempt handshake.
+  AdvanceHandshakeWithFakeClient();
+  // Check that the server didn't send any handshake messages, because it failed
+  // to handshake.
+  EXPECT_EQ(moved_messages_counts_.second, 0u);
+}
+
+TEST_P(TlsServerHandshakerTest, ZeroRttResumption) {
+  std::vector<uint8_t> application_state = {0, 1, 2, 3};
+
+  // Do the first handshake
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsZeroRtt());
+
+  // Now do another handshake
+  InitializeServer();
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_NE(server_stream()->IsZeroRtt(), GetParam().disable_resumption);
+}
+
+TEST_P(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) {
+  std::vector<uint8_t> original_application_state = {1, 2};
+  std::vector<uint8_t> new_application_state = {3, 4};
+
+  // Do the first handshake
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(original_application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(client_stream()->IsResumption());
+  EXPECT_FALSE(server_stream()->IsZeroRtt());
+
+  // Do another handshake, but change the application state
+  InitializeServer();
+  server_stream()->SetServerApplicationStateForResumption(
+      std::make_unique<ApplicationState>(new_application_state));
+  InitializeFakeClient();
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_NE(client_stream()->IsResumption(), GetParam().disable_resumption);
+  EXPECT_FALSE(server_stream()->IsZeroRtt());
+}
+
+TEST_P(TlsServerHandshakerTest, RequestClientCert) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  initial_client_cert_mode_ = ClientCertMode::kRequest;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  QuicDelayedSSLConfig delayed_ssl_config;
+  delayed_ssl_config.client_cert_mode = ClientCertMode::kRequest;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      delayed_ssl_config);
+
+  AdvanceHandshakeWithFakeClient();
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestClientCert_NoCert) {
+  initial_client_cert_mode_ = ClientCertMode::kRequest;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  EXPECT_FALSE(server_handshaker_->received_client_cert());
+}
+
+TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  initial_client_cert_mode_ = ClientCertMode::kRequire;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
+  ASSERT_TRUE(SetupClientCert());
+  InitializeFakeClient();
+
+  QuicDelayedSSLConfig delayed_ssl_config;
+  delayed_ssl_config.client_cert_mode = ClientCertMode::kRequire;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_ASYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      delayed_ssl_config);
+
+  AdvanceHandshakeWithFakeClient();
+  ASSERT_TRUE(
+      server_handshaker_->fake_proof_source_handle()->HasPendingOperation());
+  server_handshaker_->fake_proof_source_handle()->CompletePendingOperation();
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_TRUE(server_handshaker_->received_client_cert());
+  } else {
+    EXPECT_FALSE(server_handshaker_->received_client_cert());
+  }
+}
+
+TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert_NoCert) {
+  initial_client_cert_mode_ = ClientCertMode::kRequire;
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::DELEGATE_SYNC,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          DELEGATE_SYNC);
+
+  if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
+    EXPECT_CALL(*server_connection_,
+                CloseConnection(QUIC_TLS_CERTIFICATE_REQUIRED, _, _, _));
+  }
+  AdvanceHandshakeWithFakeClient();
+  AdvanceHandshakeWithFakeClient();
+  EXPECT_FALSE(server_handshaker_->received_client_cert());
+}
+
+TEST_P(TlsServerHandshakerTest, CloseConnectionBeforeSelectCert) {
+  InitializeServerWithFakeProofSourceHandle();
+  server_handshaker_->SetupProofSourceHandle(
+      /*select_cert_action=*/FakeProofSourceHandle::Action::
+          FAIL_SYNC_DO_NOT_CHECK_CLOSED,
+      /*compute_signature_action=*/FakeProofSourceHandle::Action::
+          FAIL_SYNC_DO_NOT_CHECK_CLOSED);
+
+  EXPECT_CALL(*server_handshaker_, OverrideQuicConfigDefaults(_))
+      .WillOnce(testing::Invoke([](QuicConfig* config) {
+        QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(config,
+                                                            /*max_streams=*/0);
+      }));
+
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _))
+      .WillOnce(testing::Invoke(
+          [this](QuicErrorCode error, const std::string& details,
+                 ConnectionCloseBehavior connection_close_behavior) {
+            server_connection_->ReallyCloseConnection(
+                error, details, connection_close_behavior);
+            ASSERT_FALSE(server_connection_->connected());
+          }));
+
+  AdvanceHandshakeWithFakeClient();
+  if (!GetQuicReloadableFlag(quic_tls_no_select_cert_if_disconnected)) {
+    // SelectCertificate is called when flag is false.
+    EXPECT_FALSE(server_handshaker_->fake_proof_source_handle()
+                     ->all_select_cert_args()
+                     .empty());
+    return;
+  }
+
+  EXPECT_TRUE(server_handshaker_->fake_proof_source_handle()
+                  ->all_select_cert_args()
+                  .empty());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/uber_quic_stream_id_manager.cc b/quiche/quic/core/uber_quic_stream_id_manager.cc
new file mode 100644
index 0000000..f659291
--- /dev/null
+++ b/quiche/quic/core/uber_quic_stream_id_manager.cc
@@ -0,0 +1,176 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/uber_quic_stream_id_manager.h"
+
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+UberQuicStreamIdManager::UberQuicStreamIdManager(
+    Perspective perspective,
+    ParsedQuicVersion version,
+    QuicStreamIdManager::DelegateInterface* delegate,
+    QuicStreamCount max_open_outgoing_bidirectional_streams,
+    QuicStreamCount max_open_outgoing_unidirectional_streams,
+    QuicStreamCount max_open_incoming_bidirectional_streams,
+    QuicStreamCount max_open_incoming_unidirectional_streams)
+    : version_(version),
+      bidirectional_stream_id_manager_(delegate,
+                                       /*unidirectional=*/false,
+                                       perspective,
+                                       version,
+                                       max_open_outgoing_bidirectional_streams,
+                                       max_open_incoming_bidirectional_streams),
+      unidirectional_stream_id_manager_(
+          delegate,
+          /*unidirectional=*/true,
+          perspective,
+          version,
+          max_open_outgoing_unidirectional_streams,
+          max_open_incoming_unidirectional_streams) {}
+
+bool UberQuicStreamIdManager::MaybeAllowNewOutgoingBidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  return bidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
+      max_open_streams);
+}
+bool UberQuicStreamIdManager::MaybeAllowNewOutgoingUnidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  return unidirectional_stream_id_manager_.MaybeAllowNewOutgoingStreams(
+      max_open_streams);
+}
+void UberQuicStreamIdManager::SetMaxOpenIncomingBidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  bidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
+}
+void UberQuicStreamIdManager::SetMaxOpenIncomingUnidirectionalStreams(
+    QuicStreamCount max_open_streams) {
+  unidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
+}
+
+bool UberQuicStreamIdManager::CanOpenNextOutgoingBidirectionalStream() const {
+  return bidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
+}
+
+bool UberQuicStreamIdManager::CanOpenNextOutgoingUnidirectionalStream() const {
+  return unidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
+}
+
+QuicStreamId UberQuicStreamIdManager::GetNextOutgoingBidirectionalStreamId() {
+  return bidirectional_stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+QuicStreamId UberQuicStreamIdManager::GetNextOutgoingUnidirectionalStreamId() {
+  return unidirectional_stream_id_manager_.GetNextOutgoingStreamId();
+}
+
+bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
+    QuicStreamId id,
+    std::string* error_details) {
+  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
+    return bidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+        id, error_details);
+  }
+  return unidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
+      id, error_details);
+}
+
+void UberQuicStreamIdManager::OnStreamClosed(QuicStreamId id) {
+  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
+    bidirectional_stream_id_manager_.OnStreamClosed(id);
+    return;
+  }
+  unidirectional_stream_id_manager_.OnStreamClosed(id);
+}
+
+bool UberQuicStreamIdManager::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& frame,
+    std::string* error_details) {
+  if (frame.unidirectional) {
+    return unidirectional_stream_id_manager_.OnStreamsBlockedFrame(
+        frame, error_details);
+  }
+  return bidirectional_stream_id_manager_.OnStreamsBlockedFrame(frame,
+                                                                error_details);
+}
+
+bool UberQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
+  if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
+    return bidirectional_stream_id_manager_.IsAvailableStream(id);
+  }
+  return unidirectional_stream_id_manager_.IsAvailableStream(id);
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::GetMaxAllowdIncomingBidirectionalStreams() const {
+  return bidirectional_stream_id_manager_.incoming_initial_max_open_streams();
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::GetMaxAllowdIncomingUnidirectionalStreams() const {
+  return unidirectional_stream_id_manager_.incoming_initial_max_open_streams();
+}
+
+QuicStreamId UberQuicStreamIdManager::GetLargestPeerCreatedStreamId(
+    bool unidirectional) const {
+  if (unidirectional) {
+    return unidirectional_stream_id_manager_.largest_peer_created_stream_id();
+  }
+  return bidirectional_stream_id_manager_.largest_peer_created_stream_id();
+}
+
+QuicStreamId UberQuicStreamIdManager::next_outgoing_bidirectional_stream_id()
+    const {
+  return bidirectional_stream_id_manager_.next_outgoing_stream_id();
+}
+
+QuicStreamId UberQuicStreamIdManager::next_outgoing_unidirectional_stream_id()
+    const {
+  return unidirectional_stream_id_manager_.next_outgoing_stream_id();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_outgoing_bidirectional_streams()
+    const {
+  return bidirectional_stream_id_manager_.outgoing_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_outgoing_unidirectional_streams()
+    const {
+  return unidirectional_stream_id_manager_.outgoing_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_incoming_bidirectional_streams()
+    const {
+  return bidirectional_stream_id_manager_.incoming_actual_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::max_incoming_unidirectional_streams()
+    const {
+  return unidirectional_stream_id_manager_.incoming_actual_max_streams();
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::advertised_max_incoming_bidirectional_streams() const {
+  return bidirectional_stream_id_manager_.incoming_advertised_max_streams();
+}
+
+QuicStreamCount
+UberQuicStreamIdManager::advertised_max_incoming_unidirectional_streams()
+    const {
+  return unidirectional_stream_id_manager_.incoming_advertised_max_streams();
+}
+
+QuicStreamCount UberQuicStreamIdManager::outgoing_bidirectional_stream_count()
+    const {
+  return bidirectional_stream_id_manager_.outgoing_stream_count();
+}
+
+QuicStreamCount UberQuicStreamIdManager::outgoing_unidirectional_stream_count()
+    const {
+  return unidirectional_stream_id_manager_.outgoing_stream_count();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/uber_quic_stream_id_manager.h b/quiche/quic/core/uber_quic_stream_id_manager.h
new file mode 100644
index 0000000..7af942a
--- /dev/null
+++ b/quiche/quic/core/uber_quic_stream_id_manager.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
+#define QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
+
+#include "quiche/quic/core/quic_stream_id_manager.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+namespace test {
+class QuicSessionPeer;
+class UberQuicStreamIdManagerPeer;
+}  // namespace test
+
+class QuicSession;
+
+// This class comprises two QuicStreamIdManagers, which manage bidirectional and
+// unidirectional stream IDs, respectively.
+class QUIC_EXPORT_PRIVATE UberQuicStreamIdManager {
+ public:
+  UberQuicStreamIdManager(
+      Perspective perspective,
+      ParsedQuicVersion version,
+      QuicStreamIdManager::DelegateInterface* delegate,
+      QuicStreamCount max_open_outgoing_bidirectional_streams,
+      QuicStreamCount max_open_outgoing_unidirectional_streams,
+      QuicStreamCount max_open_incoming_bidirectional_streams,
+      QuicStreamCount max_open_incoming_unidirectional_streams);
+
+  // Called on |max_open_streams| outgoing streams can be created because of 1)
+  // config negotiated or 2) MAX_STREAMS received. Returns true if new
+  // streams can be created.
+  bool MaybeAllowNewOutgoingBidirectionalStreams(
+      QuicStreamCount max_open_streams);
+  bool MaybeAllowNewOutgoingUnidirectionalStreams(
+      QuicStreamCount max_open_streams);
+
+  // Sets the limits to max_open_streams.
+  void SetMaxOpenIncomingBidirectionalStreams(QuicStreamCount max_open_streams);
+  void SetMaxOpenIncomingUnidirectionalStreams(
+      QuicStreamCount max_open_streams);
+
+  // Returns true if next outgoing bidirectional stream ID can be allocated.
+  bool CanOpenNextOutgoingBidirectionalStream() const;
+
+  // Returns true if next outgoing unidirectional stream ID can be allocated.
+  bool CanOpenNextOutgoingUnidirectionalStream() const;
+
+  // Returns the next outgoing bidirectional stream id.
+  QuicStreamId GetNextOutgoingBidirectionalStreamId();
+
+  // Returns the next outgoing unidirectional stream id.
+  QuicStreamId GetNextOutgoingUnidirectionalStreamId();
+
+  // Returns true if the incoming |id| is within the limit.
+  bool MaybeIncreaseLargestPeerStreamId(QuicStreamId id,
+                                        std::string* error_details);
+
+  // Called when |id| is released.
+  void OnStreamClosed(QuicStreamId id);
+
+  // Called when a STREAMS_BLOCKED frame is received.
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
+                             std::string* error_details);
+
+  // Returns true if |id| is still available.
+  bool IsAvailableStream(QuicStreamId id) const;
+
+  QuicStreamCount GetMaxAllowdIncomingBidirectionalStreams() const;
+
+  QuicStreamCount GetMaxAllowdIncomingUnidirectionalStreams() const;
+
+  QuicStreamId GetLargestPeerCreatedStreamId(bool unidirectional) const;
+
+  QuicStreamId next_outgoing_bidirectional_stream_id() const;
+  QuicStreamId next_outgoing_unidirectional_stream_id() const;
+
+  QuicStreamCount max_outgoing_bidirectional_streams() const;
+  QuicStreamCount max_outgoing_unidirectional_streams() const;
+
+  QuicStreamCount max_incoming_bidirectional_streams() const;
+  QuicStreamCount max_incoming_unidirectional_streams() const;
+
+  QuicStreamCount advertised_max_incoming_bidirectional_streams() const;
+  QuicStreamCount advertised_max_incoming_unidirectional_streams() const;
+
+  QuicStreamCount outgoing_bidirectional_stream_count() const;
+  QuicStreamCount outgoing_unidirectional_stream_count() const;
+
+ private:
+  friend class test::QuicSessionPeer;
+  friend class test::UberQuicStreamIdManagerPeer;
+
+  ParsedQuicVersion version_;
+  // Manages stream IDs of bidirectional streams.
+  QuicStreamIdManager bidirectional_stream_id_manager_;
+
+  // Manages stream IDs of unidirectional streams.
+  QuicStreamIdManager unidirectional_stream_id_manager_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_UBER_QUIC_STREAM_ID_MANAGER_H_
diff --git a/quiche/quic/core/uber_quic_stream_id_manager_test.cc b/quiche/quic/core/uber_quic_stream_id_manager_test.cc
new file mode 100644
index 0000000..4f7562b
--- /dev/null
+++ b/quiche/quic/core/uber_quic_stream_id_manager_test.cc
@@ -0,0 +1,340 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/uber_quic_stream_id_manager.h"
+
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+struct TestParams {
+  explicit TestParams(ParsedQuicVersion version, Perspective perspective)
+      : version(version), perspective(perspective) {}
+
+  ParsedQuicVersion version;
+  Perspective perspective;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+  return absl::StrCat(
+      ParsedQuicVersionToString(p.version), "_",
+      (p.perspective == Perspective::IS_CLIENT ? "client" : "server"));
+}
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (!version.HasIetfQuicFrames()) {
+      continue;
+    }
+    params.push_back(TestParams(version, Perspective::IS_CLIENT));
+    params.push_back(TestParams(version, Perspective::IS_SERVER));
+  }
+  return params;
+}
+
+class MockDelegate : public QuicStreamIdManager::DelegateInterface {
+ public:
+  MOCK_METHOD(void,
+              SendMaxStreams,
+              (QuicStreamCount stream_count, bool unidirectional),
+              (override));
+};
+
+class UberQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
+ protected:
+  UberQuicStreamIdManagerTest()
+      : manager_(perspective(),
+                 version(),
+                 &delegate_,
+                 0,
+                 0,
+                 kDefaultMaxStreamsPerConnection,
+                 kDefaultMaxStreamsPerConnection) {}
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                                    Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                     Perspective::IS_CLIENT) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
+    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                                    Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                     Perspective::IS_SERVER) +
+           QuicUtils::StreamIdDelta(transport_version()) * n;
+  }
+
+  QuicStreamId GetNthPeerInitiatedBidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_SERVER)
+                ? GetNthClientInitiatedBidirectionalId(n)
+                : GetNthServerInitiatedBidirectionalId(n));
+  }
+  QuicStreamId GetNthPeerInitiatedUnidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_SERVER)
+                ? GetNthClientInitiatedUnidirectionalId(n)
+                : GetNthServerInitiatedUnidirectionalId(n));
+  }
+  QuicStreamId GetNthSelfInitiatedBidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_CLIENT)
+                ? GetNthClientInitiatedBidirectionalId(n)
+                : GetNthServerInitiatedBidirectionalId(n));
+  }
+  QuicStreamId GetNthSelfInitiatedUnidirectionalStreamId(int n) {
+    return ((perspective() == Perspective::IS_CLIENT)
+                ? GetNthClientInitiatedUnidirectionalId(n)
+                : GetNthServerInitiatedUnidirectionalId(n));
+  }
+
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective,
+                               bool bidirectional) {
+    return ((bidirectional) ? QuicUtils::GetFirstBidirectionalStreamId(
+                                  transport_version(), perspective)
+                            : QuicUtils::GetFirstUnidirectionalStreamId(
+                                  transport_version(), perspective)) +
+           ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
+  }
+
+  ParsedQuicVersion version() { return GetParam().version; }
+  QuicTransportVersion transport_version() {
+    return version().transport_version;
+  }
+
+  Perspective perspective() { return GetParam().perspective; }
+
+  testing::StrictMock<MockDelegate> delegate_;
+  UberQuicStreamIdManager manager_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         UberQuicStreamIdManagerTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(UberQuicStreamIdManagerTest, Initialization) {
+  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
+            manager_.next_outgoing_bidirectional_stream_id());
+  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
+            manager_.next_outgoing_unidirectional_stream_id());
+}
+
+TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreams) {
+  const size_t kNumMaxOutgoingStream = 123;
+  // Set the uni- and bi- directional limits to different values to ensure
+  // that they are managed separately.
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+      kNumMaxOutgoingStream));
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+      kNumMaxOutgoingStream + 1));
+  EXPECT_EQ(kNumMaxOutgoingStream,
+            manager_.max_outgoing_bidirectional_streams());
+  EXPECT_EQ(kNumMaxOutgoingStream + 1,
+            manager_.max_outgoing_unidirectional_streams());
+  // Check that, for each directionality, we can open the correct number of
+  // streams.
+  int i = kNumMaxOutgoingStream;
+  while (i) {
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
+    manager_.GetNextOutgoingBidirectionalStreamId();
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+    manager_.GetNextOutgoingUnidirectionalStreamId();
+    i--;
+  }
+  // One more unidirectional
+  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  manager_.GetNextOutgoingUnidirectionalStreamId();
+
+  // Both should be exhausted...
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
+}
+
+TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenIncomingStreams) {
+  const size_t kNumMaxIncomingStreams = 456;
+  manager_.SetMaxOpenIncomingUnidirectionalStreams(kNumMaxIncomingStreams);
+  // Do +1 for bidirectional to ensure that uni- and bi- get properly set.
+  manager_.SetMaxOpenIncomingBidirectionalStreams(kNumMaxIncomingStreams + 1);
+  EXPECT_EQ(kNumMaxIncomingStreams + 1,
+            manager_.GetMaxAllowdIncomingBidirectionalStreams());
+  EXPECT_EQ(kNumMaxIncomingStreams,
+            manager_.GetMaxAllowdIncomingUnidirectionalStreams());
+  EXPECT_EQ(manager_.max_incoming_bidirectional_streams(),
+            manager_.advertised_max_incoming_bidirectional_streams());
+  EXPECT_EQ(manager_.max_incoming_unidirectional_streams(),
+            manager_.advertised_max_incoming_unidirectional_streams());
+  // Make sure that we can create kNumMaxIncomingStreams incoming unidirectional
+  // streams and kNumMaxIncomingStreams+1 incoming bidirectional streams.
+  size_t i;
+  for (i = 0; i < kNumMaxIncomingStreams; i++) {
+    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+        GetNthPeerInitiatedUnidirectionalStreamId(i), nullptr));
+    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+        GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
+  }
+  // Should be able to open the next bidirectional stream
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
+
+  // We should have exhausted the counts, the next streams should fail
+  std::string error_details;
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedUnidirectionalStreamId(i), &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat(
+                "Stream id ", GetNthPeerInitiatedUnidirectionalStreamId(i),
+                " would exceed stream count limit ", kNumMaxIncomingStreams));
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedBidirectionalStreamId(i + 1), &error_details));
+  EXPECT_EQ(error_details,
+            absl::StrCat("Stream id ",
+                         GetNthPeerInitiatedBidirectionalStreamId(i + 1),
+                         " would exceed stream count limit ",
+                         kNumMaxIncomingStreams + 1));
+}
+
+TEST_P(UberQuicStreamIdManagerTest, GetNextOutgoingStreamId) {
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(10));
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(10));
+  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
+            manager_.GetNextOutgoingBidirectionalStreamId());
+  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(1),
+            manager_.GetNextOutgoingBidirectionalStreamId());
+  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
+            manager_.GetNextOutgoingUnidirectionalStreamId());
+  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(1),
+            manager_.GetNextOutgoingUnidirectionalStreamId());
+}
+
+TEST_P(UberQuicStreamIdManagerTest, AvailableStreams) {
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedBidirectionalStreamId(3), nullptr));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(1)));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(2)));
+
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      GetNthPeerInitiatedUnidirectionalStreamId(3), nullptr));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(1)));
+  EXPECT_TRUE(
+      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(2)));
+}
+
+TEST_P(UberQuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/true),
+      nullptr));
+  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/false),
+      nullptr));
+
+  std::string expected_error_details =
+      perspective() == Perspective::IS_SERVER
+          ? "Stream id 400 would exceed stream count limit 100"
+          : "Stream id 401 would exceed stream count limit 100";
+  std::string error_details;
+
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/true),
+      &error_details));
+  EXPECT_EQ(expected_error_details, error_details);
+  expected_error_details =
+      perspective() == Perspective::IS_SERVER
+          ? "Stream id 402 would exceed stream count limit 100"
+          : "Stream id 403 would exceed stream count limit 100";
+
+  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
+      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
+                      QuicUtils::InvertPerspective(perspective()),
+                      /* bidirectional=*/false),
+      &error_details));
+  EXPECT_EQ(expected_error_details, error_details);
+}
+
+TEST_P(UberQuicStreamIdManagerTest, OnStreamsBlockedFrame) {
+  QuicStreamCount stream_count =
+      manager_.advertised_max_incoming_bidirectional_streams() - 1;
+
+  QuicStreamsBlockedFrame frame(kInvalidControlFrameId, stream_count,
+                                /*unidirectional=*/false);
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
+                             frame.unidirectional))
+      .Times(0);
+  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
+
+  stream_count = manager_.advertised_max_incoming_unidirectional_streams() - 1;
+  frame.stream_count = stream_count;
+  frame.unidirectional = true;
+
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
+                             frame.unidirectional))
+      .Times(0);
+  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
+}
+
+TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreamsPlusFrame) {
+  const size_t kNumMaxOutgoingStream = 123;
+  // Set the uni- and bi- directional limits to different values to ensure
+  // that they are managed separately.
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+      kNumMaxOutgoingStream));
+  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+      kNumMaxOutgoingStream + 1));
+  EXPECT_EQ(kNumMaxOutgoingStream,
+            manager_.max_outgoing_bidirectional_streams());
+  EXPECT_EQ(kNumMaxOutgoingStream + 1,
+            manager_.max_outgoing_unidirectional_streams());
+  // Check that, for each directionality, we can open the correct number of
+  // streams.
+  int i = kNumMaxOutgoingStream;
+  while (i) {
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
+    manager_.GetNextOutgoingBidirectionalStreamId();
+    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+    manager_.GetNextOutgoingUnidirectionalStreamId();
+    i--;
+  }
+  // One more unidirectional
+  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  manager_.GetNextOutgoingUnidirectionalStreamId();
+
+  // Both should be exhausted...
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
+  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/uber_received_packet_manager.cc b/quiche/quic/core/uber_received_packet_manager.cc
new file mode 100644
index 0000000..b6a7eb2
--- /dev/null
+++ b/quiche/quic/core/uber_received_packet_manager.cc
@@ -0,0 +1,248 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/uber_received_packet_manager.h"
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
+    : supports_multiple_packet_number_spaces_(false) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_connection_stats(stats);
+  }
+}
+
+UberReceivedPacketManager::~UberReceivedPacketManager() {}
+
+void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
+                                              Perspective perspective) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.SetFromConfig(config, perspective);
+  }
+}
+
+bool UberReceivedPacketManager::IsAwaitingPacket(
+    EncryptionLevel decrypted_packet_level,
+    QuicPacketNumber packet_number) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].IsAwaitingPacket(packet_number);
+  }
+  return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                       decrypted_packet_level)]
+      .IsAwaitingPacket(packet_number);
+}
+
+const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
+    PacketNumberSpace packet_number_space,
+    QuicTime approximate_now) {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
+  }
+  return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
+      approximate_now);
+}
+
+void UberReceivedPacketManager::RecordPacketReceived(
+    EncryptionLevel decrypted_packet_level,
+    const QuicPacketHeader& header,
+    QuicTime receipt_time) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].RecordPacketReceived(header, receipt_time);
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                decrypted_packet_level)]
+      .RecordPacketReceived(header, receipt_time);
+}
+
+void UberReceivedPacketManager::DontWaitForPacketsBefore(
+    EncryptionLevel decrypted_packet_level,
+    QuicPacketNumber least_unacked) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                decrypted_packet_level)]
+      .DontWaitForPacketsBefore(least_unacked);
+}
+
+void UberReceivedPacketManager::MaybeUpdateAckTimeout(
+    bool should_last_packet_instigate_acks,
+    EncryptionLevel decrypted_packet_level,
+    QuicPacketNumber last_received_packet_number,
+    QuicTime last_packet_receipt_time, QuicTime now,
+    const RttStats* rtt_stats) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks, last_received_packet_number,
+        last_packet_receipt_time, now, rtt_stats);
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                decrypted_packet_level)]
+      .MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
+                             last_received_packet_number,
+                             last_packet_receipt_time, now, rtt_stats);
+}
+
+void UberReceivedPacketManager::ResetAckStates(
+    EncryptionLevel encryption_level) {
+  if (!supports_multiple_packet_number_spaces_) {
+    received_packet_managers_[0].ResetAckStates();
+    return;
+  }
+  received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
+      .ResetAckStates();
+  if (encryption_level == ENCRYPTION_INITIAL) {
+    // After one Initial ACK is sent, the others should be sent 'immediately'.
+    received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
+        kAlarmGranularity);
+  }
+}
+
+void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport(
+    Perspective perspective) {
+  if (supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10495_1)
+        << "Multiple packet number spaces has already been enabled";
+    return;
+  }
+  if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
+    QUIC_BUG(quic_bug_10495_2)
+        << "Try to enable multiple packet number spaces support after any "
+           "packet has been received.";
+    return;
+  }
+  // In IETF QUIC, the peer is expected to acknowledge packets in Initial and
+  // Handshake packets with minimal delay.
+  if (perspective == Perspective::IS_CLIENT) {
+    // Delay the first server ACK, because server ACKs are padded to
+    // full size and count towards the amplification limit.
+    received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
+        kAlarmGranularity);
+  }
+  received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay(
+      kAlarmGranularity);
+
+  supports_multiple_packet_number_spaces_ = true;
+}
+
+bool UberReceivedPacketManager::IsAckFrameUpdated() const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].ack_frame_updated();
+  }
+  for (const auto& received_packet_manager : received_packet_managers_) {
+    if (received_packet_manager.ack_frame_updated()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
+    EncryptionLevel decrypted_packet_level) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].GetLargestObserved();
+  }
+  return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+                                       decrypted_packet_level)]
+      .GetLargestObserved();
+}
+
+QuicTime UberReceivedPacketManager::GetAckTimeout(
+    PacketNumberSpace packet_number_space) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].ack_timeout();
+  }
+  return received_packet_managers_[packet_number_space].ack_timeout();
+}
+
+QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
+  QuicTime ack_timeout = QuicTime::Zero();
+  // Returns the earliest non-zero ack timeout.
+  for (const auto& received_packet_manager : received_packet_managers_) {
+    const QuicTime timeout = received_packet_manager.ack_timeout();
+    if (!ack_timeout.IsInitialized()) {
+      ack_timeout = timeout;
+      continue;
+    }
+    if (timeout.IsInitialized()) {
+      ack_timeout = std::min(ack_timeout, timeout);
+    }
+  }
+  return ack_timeout;
+}
+
+bool UberReceivedPacketManager::IsAckFrameEmpty(
+    PacketNumberSpace packet_number_space) const {
+  if (!supports_multiple_packet_number_spaces_) {
+    return received_packet_managers_[0].IsAckFrameEmpty();
+  }
+  return received_packet_managers_[packet_number_space].IsAckFrameEmpty();
+}
+
+QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
+    const {
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
+  return received_packet_managers_[0].peer_least_packet_awaiting_ack();
+}
+
+size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
+  return received_packet_managers_[0].min_received_before_ack_decimation();
+}
+
+void UberReceivedPacketManager::set_min_received_before_ack_decimation(
+    size_t new_value) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_min_received_before_ack_decimation(new_value);
+  }
+}
+
+void UberReceivedPacketManager::set_ack_frequency(size_t new_value) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_ack_frequency(new_value);
+  }
+}
+
+const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
+  QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
+  return received_packet_managers_[0].ack_frame();
+}
+
+const QuicAckFrame& UberReceivedPacketManager::GetAckFrame(
+    PacketNumberSpace packet_number_space) const {
+  QUICHE_DCHECK(supports_multiple_packet_number_spaces_);
+  return received_packet_managers_[packet_number_space].ack_frame();
+}
+
+void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_max_ack_ranges(max_ack_ranges);
+  }
+}
+
+void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
+  for (auto& received_packet_manager : received_packet_managers_) {
+    received_packet_manager.set_save_timestamps(
+        save_timestamps, supports_multiple_packet_number_spaces_);
+  }
+}
+
+void UberReceivedPacketManager::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& frame) {
+  if (!supports_multiple_packet_number_spaces_) {
+    QUIC_BUG(quic_bug_10495_3)
+        << "Received AckFrequencyFrame when multiple packet number spaces "
+           "is not supported";
+    return;
+  }
+  received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/core/uber_received_packet_manager.h b/quiche/quic/core/uber_received_packet_manager.h
new file mode 100644
index 0000000..1eb15d9
--- /dev/null
+++ b/quiche/quic/core/uber_received_packet_manager.h
@@ -0,0 +1,111 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
+#define QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
+
+#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
+#include "quiche/quic/core/quic_received_packet_manager.h"
+
+namespace quic {
+
+// This class comprises multiple received packet managers, one per packet number
+// space. Please note, if multiple packet number spaces is not supported, only
+// one received packet manager will be used.
+class QUIC_EXPORT_PRIVATE UberReceivedPacketManager {
+ public:
+  explicit UberReceivedPacketManager(QuicConnectionStats* stats);
+  UberReceivedPacketManager(const UberReceivedPacketManager&) = delete;
+  UberReceivedPacketManager& operator=(const UberReceivedPacketManager&) =
+      delete;
+  virtual ~UberReceivedPacketManager();
+
+  void SetFromConfig(const QuicConfig& config, Perspective perspective);
+
+  // Checks if we are still waiting for the packet with |packet_number|.
+  bool IsAwaitingPacket(EncryptionLevel decrypted_packet_level,
+                        QuicPacketNumber packet_number) const;
+
+  // Called after a packet has been successfully decrypted and its header has
+  // been parsed.
+  void RecordPacketReceived(EncryptionLevel decrypted_packet_level,
+                            const QuicPacketHeader& header,
+                            QuicTime receipt_time);
+
+  // Retrieves a frame containing a QuicAckFrame. The ack frame must be
+  // serialized before another packet is received, or it will change.
+  const QuicFrame GetUpdatedAckFrame(PacketNumberSpace packet_number_space,
+                                     QuicTime approximate_now);
+
+  // Stop ACKing packets before |least_unacked|.
+  void DontWaitForPacketsBefore(EncryptionLevel decrypted_packet_level,
+                                QuicPacketNumber least_unacked);
+
+  // Called after header of last received packet has been successfully processed
+  // to update ACK timeout.
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             EncryptionLevel decrypted_packet_level,
+                             QuicPacketNumber last_received_packet_number,
+                             QuicTime last_packet_receipt_time, QuicTime now,
+                             const RttStats* rtt_stats);
+
+  // Resets ACK related states, called after an ACK is successfully sent.
+  void ResetAckStates(EncryptionLevel encryption_level);
+
+  // Called to enable multiple packet number support.
+  void EnableMultiplePacketNumberSpacesSupport(Perspective perspective);
+
+  // Returns true if ACK frame has been updated since GetUpdatedAckFrame was
+  // last called.
+  bool IsAckFrameUpdated() const;
+
+  // Returns the largest received packet number.
+  QuicPacketNumber GetLargestObserved(
+      EncryptionLevel decrypted_packet_level) const;
+
+  // Returns ACK timeout of |packet_number_space|.
+  QuicTime GetAckTimeout(PacketNumberSpace packet_number_space) const;
+
+  // Get the earliest ack_timeout of all packet number spaces.
+  QuicTime GetEarliestAckTimeout() const;
+
+  // Return true if ack frame of |packet_number_space| is empty.
+  bool IsAckFrameEmpty(PacketNumberSpace packet_number_space) const;
+
+  QuicPacketNumber peer_least_packet_awaiting_ack() const;
+
+  size_t min_received_before_ack_decimation() const;
+  void set_min_received_before_ack_decimation(size_t new_value);
+
+  void set_ack_frequency(size_t new_value);
+
+  bool supports_multiple_packet_number_spaces() const {
+    return supports_multiple_packet_number_spaces_;
+  }
+
+  // For logging purposes.
+  const QuicAckFrame& ack_frame() const;
+  const QuicAckFrame& GetAckFrame(PacketNumberSpace packet_number_space) const;
+
+  void set_max_ack_ranges(size_t max_ack_ranges);
+
+  void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame);
+
+  void set_save_timestamps(bool save_timestamps);
+
+ private:
+  friend class test::QuicConnectionPeer;
+  friend class test::UberReceivedPacketManagerPeer;
+
+  // One received packet manager per packet number space. If
+  // supports_multiple_packet_number_spaces_ is false, only the first (0 index)
+  // received_packet_manager is used.
+  QuicReceivedPacketManager received_packet_managers_[NUM_PACKET_NUMBER_SPACES];
+
+  bool supports_multiple_packet_number_spaces_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_UBER_RECEIVED_PACKET_MANAGER_H_
diff --git a/quiche/quic/core/uber_received_packet_manager_test.cc b/quiche/quic/core/uber_received_packet_manager_test.cc
new file mode 100644
index 0000000..96b951f
--- /dev/null
+++ b/quiche/quic/core/uber_received_packet_manager_test.cc
@@ -0,0 +1,561 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/uber_received_packet_manager.h"
+
+#include <utility>
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class UberReceivedPacketManagerPeer {
+ public:
+  static void SetAckDecimationDelay(UberReceivedPacketManager* manager,
+                                    float ack_decimation_delay) {
+    for (auto& received_packet_manager : manager->received_packet_managers_) {
+      received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
+    }
+  }
+};
+
+namespace {
+
+const bool kInstigateAck = true;
+const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
+const QuicTime::Delta kDelayedAckTime =
+    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+class UberReceivedPacketManagerTest : public QuicTest {
+ protected:
+  UberReceivedPacketManagerTest() {
+    manager_ = std::make_unique<UberReceivedPacketManager>(&stats_);
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    rtt_stats_.UpdateRtt(kMinRttMs, QuicTime::Delta::Zero(), QuicTime::Zero());
+    manager_->set_save_timestamps(true);
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number) {
+    RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number);
+  }
+
+  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
+    RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number, receipt_time);
+  }
+
+  void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
+                           uint64_t packet_number) {
+    RecordPacketReceipt(decrypted_packet_level, packet_number,
+                        QuicTime::Zero());
+  }
+
+  void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
+                           uint64_t packet_number,
+                           QuicTime receipt_time) {
+    QuicPacketHeader header;
+    header.packet_number = QuicPacketNumber(packet_number);
+    manager_->RecordPacketReceived(decrypted_packet_level, header,
+                                   receipt_time);
+  }
+
+  bool HasPendingAck() {
+    if (!manager_->supports_multiple_packet_number_spaces()) {
+      return manager_->GetAckTimeout(APPLICATION_DATA).IsInitialized();
+    }
+    return manager_->GetEarliestAckTimeout().IsInitialized();
+  }
+
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             uint64_t last_received_packet_number) {
+    MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
+                          ENCRYPTION_FORWARD_SECURE,
+                          last_received_packet_number);
+  }
+
+  void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+                             EncryptionLevel decrypted_packet_level,
+                             uint64_t last_received_packet_number) {
+    manager_->MaybeUpdateAckTimeout(
+        should_last_packet_instigate_acks, decrypted_packet_level,
+        QuicPacketNumber(last_received_packet_number), clock_.ApproximateNow(),
+        clock_.ApproximateNow(), &rtt_stats_);
+  }
+
+  void CheckAckTimeout(QuicTime time) {
+    QUICHE_DCHECK(HasPendingAck());
+    if (!manager_->supports_multiple_packet_number_spaces()) {
+      QUICHE_DCHECK(manager_->GetAckTimeout(APPLICATION_DATA) == time);
+      if (time <= clock_.ApproximateNow()) {
+        // ACK timeout expires, send an ACK.
+        manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+        QUICHE_DCHECK(!HasPendingAck());
+      }
+      return;
+    }
+    QUICHE_DCHECK(manager_->GetEarliestAckTimeout() == time);
+    // Send all expired ACKs.
+    for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+      const QuicTime ack_timeout =
+          manager_->GetAckTimeout(static_cast<PacketNumberSpace>(i));
+      if (!ack_timeout.IsInitialized() ||
+          ack_timeout > clock_.ApproximateNow()) {
+        continue;
+      }
+      manager_->ResetAckStates(
+          QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+    }
+  }
+
+  MockClock clock_;
+  RttStats rtt_stats_;
+  QuicConnectionStats stats_;
+  std::unique_ptr<UberReceivedPacketManager> manager_;
+};
+
+TEST_F(UberReceivedPacketManagerTest, DontWaitForPacketsBefore) {
+  EXPECT_TRUE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
+  RecordPacketReceipt(2);
+  EXPECT_FALSE(manager_->IsAckFrameEmpty(APPLICATION_DATA));
+  RecordPacketReceipt(7);
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(3u)));
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(6u)));
+  manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
+                                     QuicPacketNumber(4));
+  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                          QuicPacketNumber(3u)));
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(6u)));
+}
+
+TEST_F(UberReceivedPacketManagerTest, GetUpdatedAckFrame) {
+  QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(2, two_ms);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+
+  QuicFrame ack =
+      manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
+  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  // When UpdateReceivedPacketInfo with a time earlier than the time of the
+  // largest observed packet, make sure that the delta is 0, not negative.
+  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
+  ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, four_ms);
+  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  // When UpdateReceivedPacketInfo after not having received a new packet,
+  // the delta should still be accurate.
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
+            ack.ack_frame->ack_delay_time);
+  // And received packet times won't have change.
+  EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
+
+  RecordPacketReceipt(999, two_ms);
+  RecordPacketReceipt(4, two_ms);
+  RecordPacketReceipt(1000, two_ms);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, two_ms);
+  manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  // UpdateReceivedPacketInfo should discard any times which can't be
+  // expressed on the wire.
+  EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
+}
+
+TEST_F(UberReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(1);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(6);
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+
+  EXPECT_EQ(4u, stats_.max_sequence_reordering);
+  EXPECT_EQ(1000, stats_.max_time_reordering_us);
+  EXPECT_EQ(1u, stats_.packets_reordered);
+}
+
+TEST_F(UberReceivedPacketManagerTest, LimitAckRanges) {
+  manager_->set_max_ack_ranges(10);
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  for (int i = 0; i < 100; ++i) {
+    RecordPacketReceipt(1 + 2 * i);
+    EXPECT_TRUE(manager_->IsAckFrameUpdated());
+    manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
+    EXPECT_GE(10u, manager_->ack_frame().packets.NumIntervals());
+    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
+              manager_->ack_frame().packets.Max());
+    for (int j = 0; j < std::min(10, i + 1); ++j) {
+      ASSERT_GE(i, j);
+      EXPECT_TRUE(manager_->ack_frame().packets.Contains(
+          QuicPacketNumber(1 + (i - j) * 2)));
+      if (i > j) {
+        EXPECT_FALSE(manager_->ack_frame().packets.Contains(
+            QuicPacketNumber((i - j) * 2)));
+      }
+    }
+  }
+}
+
+TEST_F(UberReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+  RecordPacketReceipt(1, QuicTime::Zero());
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  EXPECT_EQ(1u, manager_->ack_frame().received_packet_times.size());
+  RecordPacketReceipt(2,
+                      QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
+  RecordPacketReceipt(3, QuicTime::Zero());
+  EXPECT_EQ(2u, manager_->ack_frame().received_packet_times.size());
+}
+
+TEST_F(UberReceivedPacketManagerTest, OutOfOrderReceiptCausesAckSent) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 2);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 1);
+  // Should ack immediately, since this fills the last hole.
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 4);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+}
+
+TEST_F(UberReceivedPacketManagerTest, OutOfOrderAckReceiptCausesNoAck) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckReceiptCausesAckSend) {
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(1, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 1);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(2, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 2);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(3, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 3);
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+  clock_.AdvanceTime(kDelayedAckTime);
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  RecordPacketReceipt(4, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 4);
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(5, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(!kInstigateAck, 5);
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckSentEveryNthPacket) {
+  EXPECT_FALSE(HasPendingAck());
+  manager_->set_ack_frequency(3);
+
+  // Receives packets 1 - 39.
+  for (size_t i = 1; i <= 39; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 3 == 0) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckDecimationReducesAcks) {
+  EXPECT_FALSE(HasPendingAck());
+
+  // Start ack decimation from 10th packet.
+  manager_->set_min_received_before_ack_decimation(10);
+
+  // Receives packets 1 - 29.
+  for (size_t i = 1; i <= 29; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i <= 10) {
+      // For packets 1-10, ack every 2 packets.
+      if (i % 2 == 0) {
+        CheckAckTimeout(clock_.ApproximateNow());
+      } else {
+        CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+      }
+      continue;
+    }
+    // ack at 20.
+    if (i == 20) {
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kMinRttMs * 0.25);
+    }
+  }
+
+  // We now receive the 30th packet, and so we send an ack.
+  RecordPacketReceipt(30, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, 30);
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimation) {
+  EXPECT_FALSE(HasPendingAck());
+  // The ack time should be based on min_rtt * 1/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(UberReceivedPacketManagerTest,
+       SendDelayedAckDecimationUnlimitedAggregation) {
+  EXPECT_FALSE(HasPendingAck());
+  QuicConfig config;
+  QuicTagVector connection_options;
+  // No limit on the number of packets received before sending an ack.
+  connection_options.push_back(kAKDU);
+  config.SetConnectionOptionsToSend(connection_options);
+  manager_->SetFromConfig(config, Perspective::IS_CLIENT);
+
+  // The ack time should be based on min_rtt/4, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.25;
+
+  // Process all the initial packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // 18 packets will not cause an ack to be sent.  19 will because when
+  // stop waiting frames are in use, we ack every 20 packets no matter what.
+  for (int i = 1; i <= 18; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(ack_time);
+}
+
+TEST_F(UberReceivedPacketManagerTest, SendDelayedAckDecimationEighthRtt) {
+  EXPECT_FALSE(HasPendingAck());
+  UberReceivedPacketManagerPeer::SetAckDecimationDelay(manager_.get(), 0.125);
+
+  // The ack time should be based on min_rtt/8, since it's less than the
+  // default delayed ack time.
+  QuicTime ack_time = clock_.ApproximateNow() + kMinRttMs * 0.125;
+
+  // Process all the packets in order so there aren't missing packets.
+  uint64_t kFirstDecimatedPacket = 101;
+  for (uint64_t i = 1; i < kFirstDecimatedPacket; ++i) {
+    RecordPacketReceipt(i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, i);
+    if (i % 2 == 0) {
+      // Ack every 2 packets by default.
+      CheckAckTimeout(clock_.ApproximateNow());
+    } else {
+      CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+    }
+  }
+
+  RecordPacketReceipt(kFirstDecimatedPacket, clock_.ApproximateNow());
+  MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket);
+  CheckAckTimeout(ack_time);
+
+  // The 10th received packet causes an ack to be sent.
+  for (uint64_t i = 1; i < 10; ++i) {
+    RecordPacketReceipt(kFirstDecimatedPacket + i, clock_.ApproximateNow());
+    MaybeUpdateAckTimeout(kInstigateAck, kFirstDecimatedPacket + i);
+  }
+  CheckAckTimeout(clock_.ApproximateNow());
+}
+
+TEST_F(UberReceivedPacketManagerTest,
+       DontWaitForPacketsBeforeMultiplePacketNumberSpaces) {
+  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_CLIENT);
+  EXPECT_FALSE(
+      manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE).IsInitialized());
+  EXPECT_FALSE(
+      manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE).IsInitialized());
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 2);
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 4);
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 7);
+  EXPECT_EQ(QuicPacketNumber(4),
+            manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE));
+  EXPECT_EQ(QuicPacketNumber(7),
+            manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE));
+
+  EXPECT_TRUE(
+      manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
+  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                          QuicPacketNumber(3)));
+  EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                         QuicPacketNumber(4)));
+
+  manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
+                                     QuicPacketNumber(5));
+  EXPECT_TRUE(
+      manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
+  EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+                                          QuicPacketNumber(4)));
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckSendingDifferentPacketNumberSpaces) {
+  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
+  EXPECT_FALSE(HasPendingAck());
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+
+  RecordPacketReceipt(ENCRYPTION_INITIAL, 3);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 3);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() +
+                  QuicTime::Delta::FromMilliseconds(25));
+  // Send delayed handshake data ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(25));
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+
+  // Second delayed ack should have a shorter delay.
+  RecordPacketReceipt(ENCRYPTION_INITIAL, 4);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_INITIAL, 4);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() +
+                  QuicTime::Delta::FromMilliseconds(1));
+  // Send delayed handshake data ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 3);
+  EXPECT_TRUE(manager_->IsAckFrameUpdated());
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 3);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() +
+                  QuicTime::Delta::FromMilliseconds(1));
+  // Send delayed handshake data ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 3);
+  EXPECT_TRUE(HasPendingAck());
+  // Delayed ack is scheduled.
+  CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 2);
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 2);
+  // Application data ACK should be sent immediately.
+  CheckAckTimeout(clock_.ApproximateNow());
+  EXPECT_FALSE(HasPendingAck());
+}
+
+TEST_F(UberReceivedPacketManagerTest,
+       AckTimeoutForPreviouslyUndecryptablePackets) {
+  manager_->EnableMultiplePacketNumberSpacesSupport(Perspective::IS_SERVER);
+  EXPECT_FALSE(HasPendingAck());
+  EXPECT_FALSE(manager_->IsAckFrameUpdated());
+
+  // Received undecryptable 1-RTT packet 4.
+  const QuicTime packet_receipt_time4 = clock_.ApproximateNow();
+  // 1-RTT keys become available after 10ms because HANDSHAKE 5 gets received.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 5);
+  MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 5);
+  EXPECT_TRUE(HasPendingAck());
+  RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 4);
+  manager_->MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE,
+                                  QuicPacketNumber(4), packet_receipt_time4,
+                                  clock_.ApproximateNow(), &rtt_stats_);
+
+  // Send delayed handshake ACK.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  CheckAckTimeout(clock_.ApproximateNow());
+
+  EXPECT_TRUE(HasPendingAck());
+  if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
+    // Verify ACK delay is based on packet receipt time.
+    CheckAckTimeout(clock_.ApproximateNow() -
+                    QuicTime::Delta::FromMilliseconds(11) + kDelayedAckTime);
+  } else {
+    // Delayed ack is scheduled.
+    CheckAckTimeout(clock_.ApproximateNow() -
+                    QuicTime::Delta::FromMilliseconds(1) + kDelayedAckTime);
+  }
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/core/web_transport_interface.h b/quiche/quic/core/web_transport_interface.h
new file mode 100644
index 0000000..ea8747d
--- /dev/null
+++ b/quiche/quic/core/web_transport_interface.h
@@ -0,0 +1,153 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This header contains interfaces that abstract away different backing
+// protocols for WebTransport.
+
+#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+#define QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_datagram_queue.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+// Visitor that gets notified about events related to a WebTransport stream.
+class QUIC_EXPORT_PRIVATE WebTransportStreamVisitor {
+ public:
+  virtual ~WebTransportStreamVisitor() {}
+
+  // Called whenever the stream has readable data available.
+  virtual void OnCanRead() = 0;
+  // Called whenever the stream is not write-blocked and can accept new data.
+  virtual void OnCanWrite() = 0;
+
+  // Called when RESET_STREAM is received for the stream.
+  virtual void OnResetStreamReceived(WebTransportStreamError error) = 0;
+  // Called when STOP_SENDING is received for the stream.
+  virtual void OnStopSendingReceived(WebTransportStreamError error) = 0;
+  // Called when the write side of the stream is closed and all of the data sent
+  // has been acknowledged ("Data Recvd" state of RFC 9000).
+  virtual void OnWriteSideInDataRecvdState() = 0;
+};
+
+// A stream (either bidirectional or unidirectional) that is contained within a
+// WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportStream {
+ public:
+  struct QUIC_EXPORT_PRIVATE ReadResult {
+    // Number of bytes actually read.
+    size_t bytes_read;
+    // Whether the FIN has been received; if true, no further data will arrive
+    // on the stream, and the stream object can be soon potentially garbage
+    // collected.
+    bool fin;
+  };
+
+  virtual ~WebTransportStream() {}
+
+  // Reads at most |buffer_size| bytes into |buffer|.
+  ABSL_MUST_USE_RESULT virtual ReadResult Read(char* buffer,
+                                               size_t buffer_size) = 0;
+  // Reads all available data and appends it to the end of |output|.
+  ABSL_MUST_USE_RESULT virtual ReadResult Read(std::string* output) = 0;
+  // Writes |data| into the stream.  Returns true on success.
+  ABSL_MUST_USE_RESULT virtual bool Write(absl::string_view data) = 0;
+  // Sends the FIN on the stream.  Returns true on success.
+  ABSL_MUST_USE_RESULT virtual bool SendFin() = 0;
+
+  // Indicates whether it is possible to write into stream right now.
+  virtual bool CanWrite() const = 0;
+  // Indicates the number of bytes that can be read from the stream.
+  virtual size_t ReadableBytes() const = 0;
+
+  // An ID that is unique within the session.  Those are not exposed to the user
+  // via the web API, but can be used internally for bookkeeping and
+  // diagnostics.
+  virtual QuicStreamId GetStreamId() const = 0;
+
+  // Resets the stream with the specified error code.
+  virtual void ResetWithUserCode(WebTransportStreamError error) = 0;
+  virtual void ResetDueToInternalError() = 0;
+  virtual void SendStopSending(WebTransportStreamError error) = 0;
+  // Called when the owning object has been garbage-collected.
+  virtual void MaybeResetDueToStreamObjectGone() = 0;
+
+  virtual WebTransportStreamVisitor* visitor() = 0;
+  virtual void SetVisitor(
+      std::unique_ptr<WebTransportStreamVisitor> visitor) = 0;
+};
+
+// Visitor that gets notified about events related to a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportVisitor {
+ public:
+  virtual ~WebTransportVisitor() {}
+
+  // Notifies the visitor when the session is ready to exchange application
+  // data.
+  virtual void OnSessionReady(const spdy::SpdyHeaderBlock& headers) = 0;
+
+  // Notifies the visitor when the session has been closed.
+  virtual void OnSessionClosed(WebTransportSessionError error_code,
+                               const std::string& error_message) = 0;
+
+  // Notifies the visitor when a new stream has been received.  The stream in
+  // question can be retrieved using AcceptIncomingBidirectionalStream() or
+  // AcceptIncomingUnidirectionalStream().
+  virtual void OnIncomingBidirectionalStreamAvailable() = 0;
+  virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
+
+  // Notifies the visitor when a new datagram has been received.
+  virtual void OnDatagramReceived(absl::string_view datagram) = 0;
+
+  // Notifies the visitor that a new outgoing stream can now be created.
+  virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
+  virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
+};
+
+// An abstract interface for a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportSession {
+ public:
+  virtual ~WebTransportSession() {}
+
+  // Closes the WebTransport session in question with the specified |error_code|
+  // and |error_message|.
+  virtual void CloseSession(WebTransportSessionError error_code,
+                            absl::string_view error_message) = 0;
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.
+  virtual WebTransportStream* AcceptIncomingBidirectionalStream() = 0;
+  virtual WebTransportStream* AcceptIncomingUnidirectionalStream() = 0;
+
+  // Returns true if flow control allows opening a new stream.
+  virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
+  virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
+  // Opens a new WebTransport stream, or returns nullptr if that is not possible
+  // due to flow control.
+  virtual WebTransportStream* OpenOutgoingBidirectionalStream() = 0;
+  virtual WebTransportStream* OpenOutgoingUnidirectionalStream() = 0;
+
+  virtual MessageStatus SendOrQueueDatagram(
+      quiche::QuicheMemSlice datagram) = 0;
+  // Returns a conservative estimate of the largest datagram size that the
+  // session would be able to send.
+  virtual QuicByteCount GetMaxDatagramSize() const = 0;
+  // Sets the largest duration that a datagram can spend in the queue before
+  // being silently dropped.
+  virtual void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
diff --git a/quiche/quic/load_balancer/load_balancer_config.cc b/quiche/quic/load_balancer/load_balancer_config.cc
new file mode 100644
index 0000000..2061abb
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_config.cc
@@ -0,0 +1,195 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_config.h"
+
+#include <memory>
+#include <string_view>
+
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+
+// Validates all non-key parts of the input.
+bool CommonValidation(const uint8_t config_id, const uint8_t server_id_len,
+                      const uint8_t nonce_len) {
+  if (config_id > 2 || server_id_len == 0 ||
+      nonce_len < kLoadBalancerMinNonceLen ||
+      nonce_len > kLoadBalancerMaxNonceLen ||
+      server_id_len >
+          (kQuicMaxConnectionIdWithLengthPrefixLength - nonce_len - 1)) {
+    QUIC_BUG(quic_bug_433862549_01)
+        << "Invalid LoadBalancerConfig "
+        << "Config ID " << static_cast<int>(config_id) << " Server ID Length "
+        << static_cast<int>(server_id_len) << " Nonce Length "
+        << static_cast<int>(nonce_len);
+    return false;
+  }
+  return true;
+}
+
+// Initialize the key in the constructor
+absl::optional<AES_KEY> BuildKey(absl::string_view key, bool encrypt) {
+  if (key.empty()) {
+    return absl::optional<AES_KEY>();
+  }
+  AES_KEY raw_key;
+  if (encrypt) {
+    if (AES_set_encrypt_key(reinterpret_cast<const uint8_t *>(key.data()),
+                            key.size() * 8, &raw_key) < 0) {
+      return absl::optional<AES_KEY>();
+    }
+  } else if (AES_set_decrypt_key(reinterpret_cast<const uint8_t *>(key.data()),
+                                 key.size() * 8, &raw_key) < 0) {
+    return absl::optional<AES_KEY>();
+  }
+  return raw_key;
+}
+
+// Functions to handle 4-pass encryption/decryption.
+// TakePlaintextFrom{Left,Right}() reads the left or right half of 'from' and
+// expands it into a full encryption block ('to') in accordance with the
+// internet-draft.
+void TakePlaintextFromLeft(uint8_t *to, uint8_t *from, uint8_t total_len,
+                           uint8_t index) {
+  uint8_t half = total_len / 2;
+  memset(to, 0, kLoadBalancerBlockSize - 1);
+  memcpy(to, from, half);
+  if (total_len % 2) {
+    to[half] = from[half] & 0xf0;
+  }
+  to[kLoadBalancerBlockSize - 1] = index;
+}
+
+void TakePlaintextFromRight(uint8_t *to, uint8_t *from, uint8_t total_len,
+                            uint8_t index) {
+  const uint8_t half = total_len / 2;
+  const uint8_t write_point = kLoadBalancerBlockSize - half;
+  const uint8_t read_point = total_len - half;
+  memset((to + 1), 0, kLoadBalancerBlockSize - 1);
+  memcpy(to + write_point, from + read_point, half);
+  if (total_len % 2) {
+    to[write_point - 1] = from[read_point - 1] & 0x0f;
+  }
+  to[0] = index;
+}
+
+// CiphertextXorWith{Left,Right}() takes the relevant end of the ciphertext in
+// 'from' and XORs it with half of the ConnectionId stored at 'to', in
+// accordance with the internet-draft.
+void CiphertextXorWithLeft(uint8_t *to, uint8_t *from, uint8_t total_len) {
+  uint8_t half = total_len / 2;
+  for (int i = 0; i < half; i++) {
+    *(to + i) ^= *(from + i);
+  }
+  if (total_len % 2) {
+    *(to + half) ^= (*(from + half) & 0xf0);
+  }
+}
+
+void CiphertextXorWithRight(uint8_t *to, uint8_t *from, uint8_t total_len) {
+  const uint8_t half = total_len / 2;
+  const uint8_t write_point = total_len - half;
+  const uint8_t read_point = kLoadBalancerBlockSize - half;
+  if (total_len % 2) {
+    *(to + write_point - 1) ^= (*(from + read_point - 1) & 0x0f);
+  }
+  for (int i = 0; i < half; i++) {
+    *(to + write_point + i) ^= *(from + read_point + i);
+  }
+}
+
+}  // namespace
+
+absl::optional<LoadBalancerConfig> LoadBalancerConfig::Create(
+    const uint8_t config_id, const uint8_t server_id_len,
+    const uint8_t nonce_len, const absl::string_view key) {
+  //  Check for valid parameters.
+  if (key.size() != kLoadBalancerKeyLen) {
+    QUIC_BUG(quic_bug_433862549_02)
+        << "Invalid LoadBalancerConfig Key Length: " << key.size();
+    return absl::optional<LoadBalancerConfig>();
+  }
+  if (!CommonValidation(config_id, server_id_len, nonce_len)) {
+    return absl::optional<LoadBalancerConfig>();
+  }
+  auto new_config =
+      LoadBalancerConfig(config_id, server_id_len, nonce_len, key);
+  if (!new_config.IsEncrypted()) {
+    // Something went wrong in assigning the key!
+    QUIC_BUG(quic_bug_433862549_03) << "Something went wrong in initializing "
+                                       "the load balancing key.";
+    return absl::optional<LoadBalancerConfig>();
+  }
+  return new_config;
+}
+
+// Creates an unencrypted config.
+absl::optional<LoadBalancerConfig> LoadBalancerConfig::CreateUnencrypted(
+    const uint8_t config_id, const uint8_t server_id_len,
+    const uint8_t nonce_len) {
+  return CommonValidation(config_id, server_id_len, nonce_len)
+             ? LoadBalancerConfig(config_id, server_id_len, nonce_len, "")
+             : absl::optional<LoadBalancerConfig>();
+}
+
+bool LoadBalancerConfig::EncryptionPass(uint8_t *target,
+                                        const uint8_t index) const {
+  uint8_t plaintext[kLoadBalancerBlockSize], ciphertext[kLoadBalancerBlockSize];
+  if (!key_.has_value() || target == nullptr) {
+    return false;
+  }
+  if (index % 2) {  // Odd indices go from left to right
+    TakePlaintextFromLeft(plaintext, target, total_len(), index);
+  } else {
+    TakePlaintextFromRight(plaintext, target, total_len(), index);
+  }
+  if (!BlockEncrypt(plaintext, ciphertext)) {
+    return false;
+  }
+  // XOR bits over the correct half.
+  if (index % 2) {
+    CiphertextXorWithRight(target, ciphertext, total_len());
+  } else {
+    CiphertextXorWithLeft(target, ciphertext, total_len());
+  }
+  return true;
+}
+
+bool LoadBalancerConfig::BlockEncrypt(
+    const uint8_t plaintext[kLoadBalancerBlockSize],
+    uint8_t ciphertext[kLoadBalancerBlockSize]) const {
+  if (!key_.has_value()) {
+    return false;
+  }
+  AES_encrypt(plaintext, ciphertext, &key_.value());
+  return true;
+}
+
+bool LoadBalancerConfig::BlockDecrypt(
+    const uint8_t ciphertext[kLoadBalancerBlockSize],
+    uint8_t plaintext[kLoadBalancerBlockSize]) const {
+  if (!block_decrypt_key_.has_value()) {
+    return false;
+  }
+  AES_decrypt(ciphertext, plaintext, &block_decrypt_key_.value());
+  return true;
+}
+
+LoadBalancerConfig::LoadBalancerConfig(const uint8_t config_id,
+                                       const uint8_t server_id_len,
+                                       const uint8_t nonce_len,
+                                       const absl::string_view key)
+    : config_id_(config_id),
+      server_id_len_(server_id_len),
+      nonce_len_(nonce_len),
+      key_(BuildKey(key, /* encrypt = */ true)),
+      block_decrypt_key_((server_id_len + nonce_len == kLoadBalancerBlockSize)
+                             ? BuildKey(key, /* encrypt = */ false)
+                             : absl::optional<AES_KEY>()) {}
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_config.h b/quiche/quic/load_balancer/load_balancer_config.h
new file mode 100644
index 0000000..8b21a1f
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_config.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_LOAD_BALANCER_CONFIG_H_
+#define QUICHE_QUIC_LOAD_BALANCER_CONFIG_H_
+
+#include "third_party/boringssl/src/include/openssl/aes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+inline constexpr uint8_t kLoadBalancerKeyLen = 16;
+// Regardless of key length, the AES block size is always 16 Bytes.
+inline constexpr uint8_t kLoadBalancerBlockSize = 16;
+// The spec says nonces can be 18 bytes, but 16 lets it be a uint128.
+inline constexpr uint8_t kLoadBalancerMaxNonceLen = 16;
+inline constexpr uint8_t kLoadBalancerMinNonceLen = 4;
+
+// This the base class for QUIC-LB configuration. It contains configuration
+// elements usable by both encoders (servers) and decoders (load balancers).
+// Confusingly, it is called "LoadBalancerConfig" because it pertains to objects
+// that both servers and load balancers use to interact with each other.
+class QUIC_EXPORT_PRIVATE LoadBalancerConfig {
+ public:
+  // This factory function initializes an encrypted LoadBalancerConfig and
+  // returns it in absl::optional, which is empty if the config is invalid.
+  // config_id: The first two bits of the Connection Id. Must be no larger than
+  // 2.
+  // server_id_len: Expected length of the server ids associated with this
+  // config. Must be greater than 0 and less than 16.
+  // nonce_len: Length of the nonce. Must be at least 4 and no larger than 16.
+  // Further the server_id_len + nonce_len must be no larger than 19.
+  // key: The encryption key must be 16B long.
+  static absl::optional<LoadBalancerConfig> Create(const uint8_t config_id,
+                                                   const uint8_t server_id_len,
+                                                   const uint8_t nonce_len,
+                                                   const absl::string_view key);
+
+  // Creates an unencrypted config.
+  static absl::optional<LoadBalancerConfig> CreateUnencrypted(
+      const uint8_t config_id, const uint8_t server_id_len,
+      const uint8_t nonce_len);
+
+  // Handles one pass of 4-pass encryption. Encoder and decoder use of this
+  // function varies substantially, so they are not implemented here.
+  // Returns false if the config is not encrypted.
+  ABSL_MUST_USE_RESULT bool EncryptionPass(uint8_t *target,
+                                           const uint8_t index) const;
+  // Use the key to do a block encryption, which is used both in all cases of
+  // encrypted configs. Returns false if there's no key.
+  ABSL_MUST_USE_RESULT bool BlockEncrypt(
+      const uint8_t plaintext[kLoadBalancerBlockSize],
+      uint8_t ciphertext[kLoadBalancerBlockSize]) const;
+  // Returns false if the config does not require block decryption.
+  ABSL_MUST_USE_RESULT bool BlockDecrypt(
+      const uint8_t ciphertext[kLoadBalancerBlockSize],
+      uint8_t plaintext[kLoadBalancerBlockSize]) const;
+
+  uint8_t config_id() const { return config_id_; }
+  uint8_t server_id_len() const { return server_id_len_; }
+  uint8_t nonce_len() const { return nonce_len_; }
+  uint8_t total_len() const { return server_id_len_ + nonce_len_; }
+  bool IsEncrypted() const { return key_.has_value(); }
+
+ private:
+  // Constructor is private because it doesn't validate input.
+  LoadBalancerConfig(uint8_t config_id, uint8_t server_id_len,
+                     uint8_t nonce_len, absl::string_view key);
+
+  uint8_t config_id_;
+  uint8_t server_id_len_;
+  uint8_t nonce_len_;
+  // All Connection ID encryption and decryption uses the AES_encrypt function
+  // at root, so there is a single key for all of it. This is empty if the
+  // config is not encrypted.
+  absl::optional<AES_KEY> key_;
+  // The one exception is that when total_len == 16, connection ID decryption
+  // uses AES_decrypt. The bytes that comprise the key are the same, but
+  // AES_decrypt requires an AES_KEY that is initialized differently. In all
+  // other cases, block_decrypt_key_ is empty.
+  absl::optional<AES_KEY> block_decrypt_key_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_LOAD_BALANCER_CONFIG_H
diff --git a/quiche/quic/load_balancer/load_balancer_config_test.cc b/quiche/quic/load_balancer/load_balancer_config_test.cc
new file mode 100644
index 0000000..1dad91c
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_config_test.cc
@@ -0,0 +1,152 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_config.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+constexpr char raw_key[] = {
+    0xfd, 0xf7, 0x26, 0xa9, 0x89, 0x3e, 0xc0, 0x5c,
+    0x06, 0x32, 0xd3, 0x95, 0x66, 0x80, 0xba, 0xf0,
+};
+
+class LoadBalancerConfigTest : public QuicTest {};
+
+TEST_F(LoadBalancerConfigTest, InvalidParams) {
+  // Bogus config_id.
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(3, 4, 10).has_value()),
+      "Invalid LoadBalancerConfig Config ID 3 Server ID Length 4 "
+      "Nonce Length 10");
+  // Bad Server ID lengths.
+  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
+                                   2, 0, 10, absl::string_view(raw_key, 16))
+                                   .has_value()),
+                  "Invalid LoadBalancerConfig Config ID 2 Server ID Length 0 "
+                  "Nonce Length 10");
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 16, 4).has_value()),
+      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 16 "
+      "Nonce Length 4");
+  // Bad Nonce lengths.
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 4, 2).has_value()),
+      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 4 "
+      "Nonce Length 2");
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(LoadBalancerConfig::CreateUnencrypted(2, 1, 17).has_value()),
+      "Invalid LoadBalancerConfig Config ID 2 Server ID Length 1 "
+      "Nonce Length 17");
+  // Bad key lengths.
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(LoadBalancerConfig::Create(2, 3, 4, "").has_value()),
+      "Invalid LoadBalancerConfig Key Length: 0");
+  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
+                                   2, 3, 4, absl::string_view(raw_key, 10))
+                                   .has_value()),
+                  "Invalid LoadBalancerConfig Key Length: 10");
+  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerConfig::Create(
+                                   0, 3, 4, absl::string_view(raw_key, 17))
+                                   .has_value()),
+                  "Invalid LoadBalancerConfig Key Length: 17");
+}
+
+TEST_F(LoadBalancerConfigTest, ValidParams) {
+  // Test valid configurations and accessors
+  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  EXPECT_EQ(config->config_id(), 0);
+  EXPECT_EQ(config->server_id_len(), 3);
+  EXPECT_EQ(config->nonce_len(), 4);
+  EXPECT_EQ(config->total_len(), 7);
+  EXPECT_FALSE(config->IsEncrypted());
+  auto config2 =
+      LoadBalancerConfig::Create(2, 6, 7, absl::string_view(raw_key, 16));
+  EXPECT_TRUE(config.has_value());
+  EXPECT_EQ(config2->config_id(), 2);
+  EXPECT_EQ(config2->server_id_len(), 6);
+  EXPECT_EQ(config2->nonce_len(), 7);
+  EXPECT_EQ(config2->total_len(), 13);
+  EXPECT_TRUE(config2->IsEncrypted());
+}
+
+// Compare EncryptionPass() results to the example in
+// draft-ietf-quic-load-balancers-12, Section 5.3.2.
+TEST_F(LoadBalancerConfigTest, TestEncryptionPassExample) {
+  auto config =
+      LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
+  EXPECT_TRUE(config.has_value());
+  EXPECT_TRUE(config->IsEncrypted());
+  std::array<uint8_t, 7> bytes = {
+      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
+  };
+  EXPECT_FALSE(config->EncryptionPass(nullptr, 0));
+  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 1));
+  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
+                            {0x31, 0x44, 0x1a, 0x9d, 0xbc, 0x04, 0x26})));
+  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 2));
+  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
+                            {0x4f, 0xdd, 0x0c, 0x9d, 0xbc, 0x04, 0x26})));
+  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 3));
+  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
+                            {0x4f, 0xdd, 0x0c, 0x9b, 0xba, 0x1e, 0xe0})));
+  EXPECT_TRUE(config->EncryptionPass(bytes.data(), 4));
+  EXPECT_TRUE((bytes == std::array<uint8_t, 7>(
+                            {0xe2, 0x3c, 0xb4, 0x2b, 0xba, 0x1e, 0xe0})));
+}
+
+TEST_F(LoadBalancerConfigTest, EncryptionPassPlaintext) {
+  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
+  std::array<uint8_t, 7> bytes = {
+      0x31, 0x44, 0x1a, 0x9c, 0x69, 0xc2, 0x75,
+  };
+  EXPECT_FALSE(config->EncryptionPass(bytes.data(), 1));
+}
+
+TEST_F(LoadBalancerConfigTest, InvalidBlockEncryption) {
+  uint8_t pt[kLoadBalancerBlockSize], ct[kLoadBalancerBlockSize];
+  auto pt_config = LoadBalancerConfig::CreateUnencrypted(0, 8, 8);
+  EXPECT_FALSE(pt_config->BlockEncrypt(pt, ct));
+  EXPECT_FALSE(pt_config->BlockDecrypt(ct, pt));
+  EXPECT_FALSE(pt_config->EncryptionPass(pt, 0));
+  auto small_cid_config =
+      LoadBalancerConfig::Create(0, 3, 4, absl::string_view(raw_key, 16));
+  EXPECT_TRUE(small_cid_config->BlockEncrypt(pt, ct));
+  EXPECT_FALSE(small_cid_config->BlockDecrypt(ct, pt));
+  auto block_config =
+      LoadBalancerConfig::Create(0, 8, 8, absl::string_view(raw_key, 16));
+  EXPECT_TRUE(block_config->BlockEncrypt(pt, ct));
+  EXPECT_TRUE(block_config->BlockDecrypt(ct, pt));
+}
+
+// Block decrypt test from the Test Vector in
+// draft-ietf-quic-load-balancers-12, Appendix B.
+TEST_F(LoadBalancerConfigTest, BlockEncryptionExample) {
+  const uint8_t ptext[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
+                           0xee, 0x08, 0x0d, 0xbf, 0x48, 0xc0, 0xd1, 0xe5};
+  const uint8_t ctext[] = {0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2,
+                           0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3};
+  const char key[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
+                      0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
+  uint8_t result[sizeof(ptext)];
+  auto config = LoadBalancerConfig::Create(0, 8, 8, absl::string_view(key, 16));
+  EXPECT_TRUE(config->BlockEncrypt(ptext, result));
+  EXPECT_EQ(memcmp(result, ctext, sizeof(ctext)), 0);
+  EXPECT_TRUE(config->BlockDecrypt(ctext, result));
+  EXPECT_EQ(memcmp(result, ptext, sizeof(ptext)), 0);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_decoder.cc b/quiche/quic/load_balancer/load_balancer_decoder.cc
new file mode 100644
index 0000000..ead70d8
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_decoder.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_decoder.h"
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+bool LoadBalancerDecoder::AddConfig(const LoadBalancerConfig& config) {
+  if (config_[config.config_id()].has_value()) {
+    return false;
+  }
+  config_[config.config_id()] = config;
+  return true;
+}
+
+void LoadBalancerDecoder::DeleteConfig(uint8_t config_id) {
+  if (config_id > 2) {
+    QUIC_BUG(quic_bug_438896865_01)
+        << "Decoder deleting config with invalid config_id "
+        << static_cast<int>(config_id);
+    return;
+  }
+  config_[config_id].reset();
+}
+
+// This is the core logic to extract a server ID given a valid config and
+// connection ID of sufficient length.
+absl::optional<LoadBalancerServerId> LoadBalancerDecoder::GetServerId(
+    const QuicConnectionId& connection_id) const {
+  absl::optional<uint8_t> config_id = GetConfigId(connection_id);
+  if (!config_id.has_value()) {
+    return absl::optional<LoadBalancerServerId>();
+  }
+  absl::optional<LoadBalancerConfig> config = config_[*config_id];
+  if (!config.has_value()) {
+    return absl::optional<LoadBalancerServerId>();
+  }
+  if (connection_id.length() < (1 + config->total_len())) {
+    // Connection ID wasn't long enough
+    return absl::optional<LoadBalancerServerId>();
+  }
+  // The first byte is complete. Finish the rest.
+  const uint8_t* data =
+      reinterpret_cast<const uint8_t*>(connection_id.data()) + 1;
+  if (!config->IsEncrypted()) {  // It's a Plaintext CID.
+    return LoadBalancerServerId::Create(
+        absl::Span<const uint8_t>(data, config->server_id_len()));
+  }
+  uint8_t result[kQuicMaxConnectionIdWithLengthPrefixLength];
+  if (config->total_len() == kLoadBalancerKeyLen) {  // single pass
+    if (!config->BlockDecrypt(data, result)) {
+      return absl::optional<LoadBalancerServerId>();
+    }
+  } else {
+    // Do 3 or 4 passes. Only 3 are necessary if the server_id is short enough
+    // to fit in the first half of the connection ID (the decoder doesn't need
+    // to extract the nonce).
+    memcpy(result, data, config->total_len());
+    uint8_t end = (config->server_id_len() > config->nonce_len()) ? 1 : 2;
+    for (uint8_t i = 4; i >= end; i--) {
+      if (!config->EncryptionPass(result, i)) {
+        return absl::optional<LoadBalancerServerId>();
+      }
+    }
+  }
+  return LoadBalancerServerId::Create(
+      absl::Span<const uint8_t>(result, config->server_id_len()));
+}
+
+absl::optional<uint8_t> LoadBalancerDecoder::GetConfigId(
+    const QuicConnectionId& connection_id) {
+  if (connection_id.IsEmpty()) {
+    return absl::optional<uint8_t>();
+  }
+  const uint8_t first_byte = connection_id.data()[0];
+  uint8_t codepoint = (first_byte >> 6);
+  if (codepoint <= 2) {
+    return codepoint;
+  }
+  return absl::optional<uint8_t>();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_decoder.h b/quiche/quic/load_balancer/load_balancer_decoder.h
new file mode 100644
index 0000000..34c298c
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_decoder.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
+#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
+
+#include "quiche/quic/load_balancer/load_balancer_config.h"
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+
+namespace quic {
+
+// Manages QUIC-LB configurations to extract a server ID from a properly
+// encoded connection ID, usually on behalf of a load balancer.
+class QUIC_EXPORT_PRIVATE LoadBalancerDecoder {
+ public:
+  // Returns false if the config_id codepoint is already occupied.
+  bool AddConfig(const LoadBalancerConfig& config);
+
+  // Remove support for a config
+  void DeleteConfig(const uint8_t config_id);
+
+  // For these "Get" functions, the calling code might not know the length of
+  // the connection ID. That's OK; if not, just send at least
+  // kQuicMaxConnectionIdWithLengthPrefixLength bytes in a QuicConnectionId.
+
+  // Extract a server ID from a connection ID. If there is no config for the
+  // codepoint, the connection ID is too short, or there's a decrypt error,
+  // returns empty.
+  absl::optional<LoadBalancerServerId> GetServerId(
+      const QuicConnectionId& connection_id) const;
+
+  // Returns the config ID stored in the first two bits of |connection_id|, or
+  // empty if |connection_id| is empty.
+  static absl::optional<uint8_t> GetConfigId(
+      const QuicConnectionId& connection_id);
+
+ private:
+  // Decoders can support up to 3 configs at once.
+  absl::optional<LoadBalancerConfig> config_[3];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_DECODER_H_
diff --git a/quiche/quic/load_balancer/load_balancer_decoder_test.cc b/quiche/quic/load_balancer/load_balancer_decoder_test.cc
new file mode 100644
index 0000000..379bacd
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_decoder_test.cc
@@ -0,0 +1,228 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_decoder.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class LoadBalancerDecoderTest : public QuicTest {};
+
+// Convenience function to shorten the code. Does not check if |array| is long
+// enough or |length| is valid for a server ID.
+inline LoadBalancerServerId MakeServerId(const uint8_t array[],
+                                         const uint8_t length) {
+  return *LoadBalancerServerId::Create(
+      absl::Span<const uint8_t>(array, length));
+}
+
+constexpr char kRawKey[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
+                            0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
+constexpr absl::string_view kKey(kRawKey, kLoadBalancerKeyLen);
+constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
+                                 0xab, 0x65, 0xba, 0x04, 0xc3, 0x33, 0x0a};
+
+struct LoadBalancerDecoderTestCase {
+  LoadBalancerConfig config;
+  QuicConnectionId connection_id;
+  LoadBalancerServerId server_id;
+};
+
+TEST_F(LoadBalancerDecoderTest, UnencryptedConnectionIdTestVectors) {
+  const struct LoadBalancerDecoderTestCase test_vectors[2] = {
+      {
+          *LoadBalancerConfig::CreateUnencrypted(0, 3, 4),
+          QuicConnectionId({0x07, 0xed, 0x79, 0x3a, 0x80, 0x49, 0x71, 0x8a}),
+          MakeServerId(kServerId, 3),
+      },
+      {
+          *LoadBalancerConfig::CreateUnencrypted(1, 8, 5),
+          QuicConnectionId({0x4d, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f,
+                            0x5f, 0xee, 0x15, 0xda, 0x27, 0xc4}),
+          MakeServerId(kServerId, 8),
+      }};
+  for (uint8_t i = 0; i < ABSL_ARRAYSIZE(test_vectors); i++) {
+    LoadBalancerDecoder decoder;
+    EXPECT_TRUE(decoder.AddConfig(test_vectors[i].config));
+    EXPECT_EQ(decoder.GetServerId(test_vectors[i].connection_id),
+              test_vectors[i].server_id);
+  }
+}
+
+// Compare test vectors from Appendix B of draft-ietf-quic-load-balancers-12.
+TEST_F(LoadBalancerDecoderTest, DecoderTestVectors) {
+  // Try (1) the "standard" CID length of 8
+  // (2) server_id_len > nonce_len, so there is a fourth decryption pass
+  // (3) the single-pass encryption case
+  // (4) An even total length.
+  const struct LoadBalancerDecoderTestCase test_vectors[4] = {
+      {
+          *LoadBalancerConfig::Create(0, 3, 4, kKey),
+          QuicConnectionId({0x07, 0xfb, 0xfe, 0x05, 0xf7, 0x31, 0xb4, 0x25}),
+          MakeServerId(kServerId, 3),
+      },
+      {
+          *LoadBalancerConfig::Create(1, 10, 5, kKey),
+          QuicConnectionId({0x4f, 0x01, 0x09, 0x56, 0xfb, 0x5c, 0x1d, 0x4d,
+                            0x86, 0xe0, 0x10, 0x18, 0x3e, 0x0b, 0x7d, 0x1e}),
+          MakeServerId(kServerId, 10),
+      },
+      {
+          *LoadBalancerConfig::Create(2, 8, 8, kKey),
+          QuicConnectionId({0x90, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9,
+                            0xb2, 0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c,
+                            0xc3}),
+          MakeServerId(kServerId, 8),
+      },
+      {
+          *LoadBalancerConfig::Create(0, 9, 9, kKey),
+          QuicConnectionId({0x12, 0x7a, 0x28, 0x5a, 0x09, 0xf8, 0x52, 0x80,
+                            0xf4, 0xfd, 0x6a, 0xbb, 0x43, 0x4a, 0x71, 0x59,
+                            0xe4, 0xd3, 0xeb}),
+          MakeServerId(kServerId, 9),
+      },
+  };
+
+  for (uint8_t i = 0; i < ABSL_ARRAYSIZE(test_vectors); i++) {
+    LoadBalancerDecoder decoder;
+    EXPECT_TRUE(decoder.AddConfig(test_vectors[i].config));
+    EXPECT_EQ(decoder.GetServerId(test_vectors[i].connection_id),
+              test_vectors[i].server_id);
+  }
+}
+
+TEST_F(LoadBalancerDecoderTest, NoServerIdEntry) {
+  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  EXPECT_TRUE(server_id.has_value());
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
+  QuicConnectionId no_server_id_entry(
+      {0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08});
+  EXPECT_TRUE(decoder.GetServerId(no_server_id_entry).has_value());
+}
+
+TEST_F(LoadBalancerDecoderTest, InvalidConfigId) {
+  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  EXPECT_TRUE(server_id.has_value());
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
+  QuicConnectionId wrong_config_id(
+      {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07});
+  EXPECT_FALSE(decoder
+                   .GetServerId(QuicConnectionId(
+                       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
+                   .has_value());
+}
+
+TEST_F(LoadBalancerDecoderTest, UnroutableCodepoint) {
+  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  EXPECT_TRUE(server_id.has_value());
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
+  EXPECT_FALSE(decoder
+                   .GetServerId(QuicConnectionId(
+                       {0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
+                   .has_value());
+}
+
+TEST_F(LoadBalancerDecoderTest, UnroutableCodepointAnyLength) {
+  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  EXPECT_TRUE(server_id.has_value());
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
+  EXPECT_FALSE(decoder.GetServerId(QuicConnectionId({0xff})).has_value());
+}
+
+TEST_F(LoadBalancerDecoderTest, ConnectionIdTooShort) {
+  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  EXPECT_TRUE(server_id.has_value());
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
+  EXPECT_FALSE(decoder
+                   .GetServerId(QuicConnectionId(
+                       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}))
+                   .has_value());
+}
+
+TEST_F(LoadBalancerDecoderTest, ConnectionIdTooLongIsOK) {
+  auto server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
+  auto server_id_result = decoder.GetServerId(
+      QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}));
+  EXPECT_TRUE(server_id_result.has_value());
+  EXPECT_EQ(server_id_result, server_id);
+}
+
+TEST_F(LoadBalancerDecoderTest, DeleteConfigBadId) {
+  LoadBalancerDecoder decoder;
+  decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
+  decoder.DeleteConfig(0);
+  EXPECT_QUIC_BUG(decoder.DeleteConfig(3),
+                  "Decoder deleting config with invalid config_id 3");
+  EXPECT_TRUE(decoder
+                  .GetServerId(QuicConnectionId(
+                      {0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
+                  .has_value());
+}
+
+TEST_F(LoadBalancerDecoderTest, DeleteConfigGoodId) {
+  LoadBalancerDecoder decoder;
+  decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
+  decoder.DeleteConfig(2);
+  EXPECT_FALSE(decoder
+                   .GetServerId(QuicConnectionId(
+                       {0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}))
+                   .has_value());
+}
+
+// Create two server IDs and make sure the decoder decodes the correct one.
+TEST_F(LoadBalancerDecoderTest, TwoServerIds) {
+  auto server_id1 = LoadBalancerServerId::Create({0x01, 0x02, 0x03});
+  EXPECT_TRUE(server_id1.has_value());
+  auto server_id2 = LoadBalancerServerId::Create({0x04, 0x05, 0x06});
+  LoadBalancerDecoder decoder;
+  EXPECT_TRUE(
+      decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
+  EXPECT_EQ(decoder.GetServerId(QuicConnectionId(
+                {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07})),
+            server_id1);
+  EXPECT_EQ(decoder.GetServerId(QuicConnectionId(
+                {0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a})),
+            server_id2);
+}
+
+TEST_F(LoadBalancerDecoderTest, GetConfigId) {
+  EXPECT_FALSE(
+      LoadBalancerDecoder::GetConfigId(QuicConnectionId()).has_value());
+  for (uint8_t i = 0; i < 3; i++) {
+    auto config_id = LoadBalancerDecoder::GetConfigId(
+        QuicConnectionId({static_cast<unsigned char>(i << 6)}));
+    EXPECT_TRUE(config_id.has_value());
+    EXPECT_EQ(*config_id, i);
+  }
+  EXPECT_FALSE(
+      LoadBalancerDecoder::GetConfigId(QuicConnectionId({0xc0})).has_value());
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_encoder.cc b/quiche/quic/load_balancer/load_balancer_encoder.cc
new file mode 100644
index 0000000..852e904
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_encoder.cc
@@ -0,0 +1,178 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_encoder.h"
+
+#include "absl/numeric/int128.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_packet_number.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/load_balancer/load_balancer_config.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+
+// Returns the number of nonces given a certain |nonce_len|.
+absl::uint128 NumberOfNonces(uint8_t nonce_len) {
+  return (static_cast<absl::uint128>(1) << (nonce_len * 8));
+}
+
+// Writes the |size| least significant bytes from |in| to |out| in host byte
+// order. Returns false if |out| does not have enough space.
+bool WriteUint128(const absl::uint128 in, uint8_t size, QuicDataWriter &out) {
+  if (out.remaining() < size) {
+    QUIC_BUG(quic_bug_435375038_05)
+        << "Call to WriteUint128() does not have enough space in |out|";
+    return false;
+  }
+  uint64_t num64 = absl::Uint128Low64(in);
+  if (size <= sizeof(num64)) {
+    out.WriteBytes(&num64, size);
+  } else {
+    out.WriteBytes(&num64, sizeof(num64));
+    num64 = absl::Uint128High64(in);
+    out.WriteBytes(&num64, size - sizeof(num64));
+  }
+  return true;
+}
+
+}  // namespace
+
+constexpr uint8_t kLoadBalancerLengthMask = 0x3f;
+constexpr uint8_t kLoadBalancerUnroutableConfigId = 0xc0;
+
+absl::optional<LoadBalancerEncoder> LoadBalancerEncoder::Create(
+    QuicRandom &random, LoadBalancerEncoderVisitorInterface *const visitor,
+    const bool len_self_encoded, const uint8_t unroutable_connection_id_len) {
+  if (unroutable_connection_id_len == 0 ||
+      unroutable_connection_id_len >
+          kQuicMaxConnectionIdWithLengthPrefixLength) {
+    QUIC_BUG(quic_bug_435375038_01)
+        << "Invalid unroutable_connection_id_len = "
+        << static_cast<int>(unroutable_connection_id_len);
+    return absl::optional<LoadBalancerEncoder>();
+  }
+  return LoadBalancerEncoder(random, visitor, len_self_encoded,
+                             unroutable_connection_id_len);
+}
+
+bool LoadBalancerEncoder::UpdateConfig(const LoadBalancerConfig &config,
+                                       const LoadBalancerServerId server_id) {
+  if (config_.has_value() && config_->config_id() == config.config_id()) {
+    QUIC_BUG(quic_bug_435375038_02)
+        << "Attempting to change config with same ID";
+    return false;
+  }
+  if (server_id.length() != config.server_id_len()) {
+    QUIC_BUG(quic_bug_435375038_03)
+        << "Server ID length " << static_cast<int>(server_id.length())
+        << " does not match configured value of "
+        << static_cast<int>(config.server_id_len());
+    return false;
+  }
+  if (visitor_ != nullptr) {
+    if (config_.has_value()) {
+      visitor_->OnConfigChanged(config_->config_id(), config.config_id());
+    } else {
+      visitor_->OnConfigAdded(config.config_id());
+    }
+  }
+  config_ = config;
+  server_id_ = server_id;
+
+  seed_ = absl::MakeUint128(random_.RandUint64(), random_.RandUint64()) %
+          NumberOfNonces(config.nonce_len());
+  num_nonces_left_ = NumberOfNonces(config.nonce_len());
+  return true;
+}
+
+void LoadBalancerEncoder::DeleteConfig() {
+  if (visitor_ != nullptr && config_.has_value()) {
+    visitor_->OnConfigDeleted(config_->config_id());
+  }
+  config_.reset();
+  server_id_.reset();
+  num_nonces_left_ = 0;
+}
+
+QuicConnectionId LoadBalancerEncoder::GenerateConnectionId() {
+  uint8_t length = (config_.has_value()) ? (config_->total_len() + 1)
+                                         : unroutable_connection_id_len_;
+  uint8_t config_id = config_.has_value() ? (config_->config_id() << 6)
+                                          : kLoadBalancerUnroutableConfigId;
+  if (config_.has_value() != server_id_.has_value()) {
+    QUIC_BUG(quic_bug_435375038_04)
+        << "Existence of config and server_id are out of sync";
+    return QuicConnectionId();
+  }
+  uint8_t first_byte;
+  // first byte
+  if (len_self_encoded_) {
+    first_byte = config_id | (length - 1);
+  } else {
+    random_.RandBytes(static_cast<void *>(&first_byte), 1);
+    first_byte = config_id | (first_byte & kLoadBalancerLengthMask);
+  }
+  if (config_id == kLoadBalancerUnroutableConfigId) {
+    return MakeUnroutableConnectionId(first_byte);
+  }
+  QuicConnectionId id;
+  id.set_length(length);
+  QuicDataWriter writer(length, id.mutable_data(), quiche::HOST_BYTE_ORDER);
+  writer.WriteUInt8(first_byte);
+  absl::uint128 next_nonce =
+      (seed_ + num_nonces_left_--) % NumberOfNonces(config_->nonce_len());
+  writer.WriteBytes(server_id_->data().data(), server_id_->length());
+  if (!WriteUint128(next_nonce, config_->nonce_len(), writer)) {
+    return QuicConnectionId();
+  }
+  uint8_t *block_start = reinterpret_cast<uint8_t *>(writer.data() + 1);
+  if (!config_->IsEncrypted()) {
+    // Fill the nonce field with a hash of the Connection ID to avoid the nonce
+    // visibly increasing by one. This would allow observers to correlate
+    // connection IDs as being sequential and likely from the same connection,
+    // not just the same server.
+    absl::uint128 nonce_hash =
+        QuicUtils::FNV1a_128_Hash(absl::string_view(writer.data(), length));
+    QuicDataWriter rewriter(config_->nonce_len(),
+                            id.mutable_data() + config_->server_id_len() + 1,
+                            quiche::HOST_BYTE_ORDER);
+    if (!WriteUint128(nonce_hash, config_->nonce_len(), rewriter)) {
+      return QuicConnectionId();
+    }
+  } else if (config_->total_len() == kLoadBalancerBlockSize) {
+    // Use one encryption pass.
+    if (!config_->BlockEncrypt(block_start, block_start)) {
+      QUIC_LOG(ERROR) << "Block encryption failed";
+      return QuicConnectionId();
+    }
+  } else {
+    for (uint8_t i = 1; i <= 4; i++) {
+      if (!config_->EncryptionPass(block_start, i)) {
+        QUIC_LOG(ERROR) << "Block encryption failed";
+        return QuicConnectionId();
+      }
+    }
+  }
+  if (num_nonces_left_ == 0) {
+    DeleteConfig();
+  }
+  return id;
+}
+
+QuicConnectionId LoadBalancerEncoder::MakeUnroutableConnectionId(
+    uint8_t first_byte) {
+  QuicConnectionId id;
+  id.set_length(unroutable_connection_id_len_);
+  id.mutable_data()[0] = first_byte;
+  random_.RandBytes(&id.mutable_data()[1], unroutable_connection_id_len_ - 1);
+  return id;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_encoder.h b/quiche/quic/load_balancer/load_balancer_encoder.h
new file mode 100644
index 0000000..98e1cdb
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_encoder.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_LOAD_BALANCER_ENCODER_H_
+#define QUICHE_QUIC_LOAD_BALANCER_ENCODER_H_
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/load_balancer/load_balancer_config.h"
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+
+namespace quic {
+
+namespace test {
+class LoadBalancerEncoderPeer;
+}
+
+// Default length of a 4-tuple connection ID.
+inline constexpr uint8_t kLoadBalancerUnroutableLen = 8;
+
+// Interface which receives notifications when the current config is updated.
+class QUIC_EXPORT_PRIVATE LoadBalancerEncoderVisitorInterface {
+ public:
+  virtual ~LoadBalancerEncoderVisitorInterface() {}
+
+  // Called when a config is added where none existed.
+  //
+  // Connections that support address migration should retire unroutable
+  // connection IDs and replace them with routable ones using the new config,
+  // while avoiding sending a sudden storm of packets containing
+  // RETIRE_CONNECTION_ID and NEW_CONNECTION_ID frames.
+  virtual void OnConfigAdded(const uint8_t config_id) = 0;
+  // Called when the config is changed.
+  //
+  // Existing routable connection IDs should be retired before the decoder stops
+  // supporting that config. The timing of this event is deployment-dependent
+  // and might be tied to the arrival of a new config at the encoder.
+  virtual void OnConfigChanged(const uint8_t old_config_id,
+                               const uint8_t new_config_id) = 0;
+  // Called when a config is deleted. The encoder will generate unroutable
+  // connection IDs from now on.
+  //
+  // New connections will not be able to support address migration until a new
+  // config arrives. Existing connections can retain connection IDs that use the
+  // deleted config, which will only become unroutable once the decoder also
+  // deletes it. The time of that deletion is deployment-dependent and might be
+  // tied to the arrival of a new config at the encoder.
+  virtual void OnConfigDeleted(const uint8_t config_id) = 0;
+};
+
+// Manages QUIC-LB configurations to properly encode a given server ID in a
+// QUIC Connection ID.
+class QUIC_EXPORT_PRIVATE LoadBalancerEncoder {
+ public:
+  // Returns a newly created encoder with no active config, if
+  // |unroutable_connection_id_length| is valid. |visitor| specifies an optional
+  // interface to receive callbacks when connection IDs need to be retired.
+  // If |encode_length| is true, then the first byte of any generated
+  // connection ids will encode the length. Otherwise, those bits will be
+  // random. |unroutable_connection_id_length| specifies the length of
+  // connection IDs to be generated when there is no active config. It must not
+  // be 0 and must not be larger than the RFC9000 maximum of 20.
+  static absl::optional<LoadBalancerEncoder> Create(
+      QuicRandom& random, LoadBalancerEncoderVisitorInterface* const visitor,
+      const bool len_self_encoded,
+      const uint8_t unroutable_connection_id_len = kLoadBalancerUnroutableLen);
+
+  // Attempts to replace the current config and server_id with |config| and
+  // |server_id|. If the length |server_id| does not match the server_id_length
+  // of |config| or the ID of |config| matches the ID of the current config,
+  // returns false and leaves the current config unchanged. Otherwise, returns
+  // true. When the encoder runs out of nonces, it will delete the config and
+  // begin generating unroutable connection IDs.
+  bool UpdateConfig(const LoadBalancerConfig& config,
+                    const LoadBalancerServerId server_id);
+
+  // Delete the current config and generate unroutable connection IDs from now
+  // on.
+  void DeleteConfig();
+
+  // Returns the number of additional connections IDs that can be generated with
+  // the current config, or 0 if there is no current config.
+  absl::uint128 num_nonces_left() const { return num_nonces_left_; }
+
+  // Returns true if there is an active configuration.
+  bool IsEncoding() const { return config_.has_value(); }
+  // Returns true if there is an active configuration that uses encryption.
+  bool IsEncrypted() const {
+    return config_.has_value() && config_->IsEncrypted();
+  }
+
+  // If there's an active config, generates a connection ID using it. If not,
+  // generates an unroutable connection_id. If there's an error, returns a zero-
+  // length Connection ID.
+  QuicConnectionId GenerateConnectionId();
+
+ private:
+  friend class test::LoadBalancerEncoderPeer;
+
+  LoadBalancerEncoder(QuicRandom& random,
+                      LoadBalancerEncoderVisitorInterface* const visitor,
+                      const bool len_self_encoded,
+                      const uint8_t unroutable_connection_id_len)
+      : random_(random),
+        len_self_encoded_(len_self_encoded),
+        visitor_(visitor),
+        unroutable_connection_id_len_(unroutable_connection_id_len) {}
+
+  QuicConnectionId MakeUnroutableConnectionId(uint8_t first_byte);
+
+  QuicRandom& random_;
+  const bool len_self_encoded_;
+  LoadBalancerEncoderVisitorInterface* const visitor_;
+  const uint8_t unroutable_connection_id_len_;
+
+  absl::optional<LoadBalancerConfig> config_;
+  absl::uint128 seed_, num_nonces_left_ = 0;
+  absl::optional<LoadBalancerServerId> server_id_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_LOAD_BALANCER_ENCODER_H_
diff --git a/quiche/quic/load_balancer/load_balancer_encoder_test.cc b/quiche/quic/load_balancer/load_balancer_encoder_test.cc
new file mode 100644
index 0000000..ed6db41
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_encoder_test.cc
@@ -0,0 +1,355 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_encoder.h"
+
+#include <cstdint>
+
+#include "absl/numeric/int128.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+class LoadBalancerEncoderPeer {
+ public:
+  static void SetNumNoncesLeft(LoadBalancerEncoder &encoder,
+                               uint64_t nonces_remaining) {
+    encoder.num_nonces_left_ = absl::uint128(nonces_remaining);
+  }
+};
+
+namespace {
+
+class TestLoadBalancerEncoderVisitor
+    : public LoadBalancerEncoderVisitorInterface {
+ public:
+  ~TestLoadBalancerEncoderVisitor() override {}
+
+  void OnConfigAdded(const uint8_t config_id) override {
+    num_adds_++;
+    current_config_id_ = config_id;
+  }
+
+  void OnConfigChanged(const uint8_t old_config_id,
+                       const uint8_t new_config_id) override {
+    num_adds_++;
+    num_deletes_++;
+    EXPECT_EQ(old_config_id, current_config_id_);
+    current_config_id_ = new_config_id;
+  }
+
+  void OnConfigDeleted(const uint8_t config_id) override {
+    EXPECT_EQ(config_id, current_config_id_);
+    current_config_id_.reset();
+    num_deletes_++;
+  }
+
+  uint32_t num_adds() const { return num_adds_; }
+  uint32_t num_deletes() const { return num_deletes_; }
+
+ private:
+  uint32_t num_adds_ = 0, num_deletes_ = 0;
+  absl::optional<uint8_t> current_config_id_ = absl::optional<uint8_t>();
+};
+
+// Allows the caller to specify the exact results in 64-bit chunks.
+class TestRandom : public QuicRandom {
+ public:
+  uint64_t RandUint64() override {
+    if (next_values_.empty()) {
+      return base_;
+    }
+    uint64_t value = next_values_.front();
+    next_values_.pop();
+    return value;
+  }
+
+  void RandBytes(void *data, size_t len) override {
+    size_t written = 0;
+    uint8_t *ptr = static_cast<uint8_t *>(data);
+    while (written < len) {
+      uint64_t result = RandUint64();
+      size_t to_write = (len - written > sizeof(uint64_t)) ? sizeof(uint64_t)
+                                                           : (len - written);
+      memcpy(ptr + written, &result, to_write);
+      written += to_write;
+    }
+  }
+
+  void InsecureRandBytes(void *data, size_t len) override {
+    RandBytes(data, len);
+  }
+
+  uint64_t InsecureRandUint64() override { return RandUint64(); }
+
+  void AddNextValues(uint64_t hi, uint64_t lo) {
+    next_values_.push(hi);
+    next_values_.push(lo);
+  }
+
+ private:
+  std::queue<uint64_t> next_values_;
+  uint64_t base_ = 0xDEADBEEFDEADBEEF;
+};
+
+class LoadBalancerEncoderTest : public QuicTest {
+ public:
+  TestRandom random_;
+};
+
+// Convenience function to shorten the code. Does not check if |array| is long
+// enough or |length| is valid for a server ID.
+LoadBalancerServerId MakeServerId(const uint8_t array[], const uint8_t length) {
+  return *LoadBalancerServerId::Create(
+      absl::Span<const uint8_t>(array, length));
+}
+
+constexpr char kRawKey[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
+                            0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
+constexpr absl::string_view kKey(kRawKey, kLoadBalancerKeyLen);
+constexpr uint64_t kNonceLow = 0xe5d1c048bf0d08ee;
+constexpr uint64_t kNonceHigh = 0x9321e7e34dde525d;
+constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
+                                 0xab, 0x65, 0xba, 0x04, 0xc3, 0x33, 0x0a};
+
+TEST_F(LoadBalancerEncoderTest, BadUnroutableLength) {
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(
+          LoadBalancerEncoder::Create(random_, nullptr, false, 0).has_value()),
+      "Invalid unroutable_connection_id_len = 0");
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(
+          LoadBalancerEncoder::Create(random_, nullptr, false, 21).has_value()),
+      "Invalid unroutable_connection_id_len = 21");
+}
+
+TEST_F(LoadBalancerEncoderTest, BadServerIdLength) {
+  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true);
+  EXPECT_TRUE(encoder.has_value());
+  // Expects a 3 byte server ID and got 4.
+  auto config = LoadBalancerConfig::CreateUnencrypted(1, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 4))),
+      "Server ID length 4 does not match configured value of 3");
+  EXPECT_FALSE(encoder->IsEncoding());
+}
+
+TEST_F(LoadBalancerEncoderTest, FailToUpdateConfigWithSameId) {
+  TestLoadBalancerEncoderVisitor visitor;
+  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
+  EXPECT_TRUE(encoder.has_value());
+  EXPECT_TRUE(encoder.has_value());
+  auto config = LoadBalancerConfig::CreateUnencrypted(1, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
+  EXPECT_EQ(visitor.num_adds(), 1u);
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3))),
+      "Attempting to change config with same ID");
+  EXPECT_EQ(visitor.num_adds(), 1u);
+}
+
+TEST_F(LoadBalancerEncoderTest, UnencryptedConnectionIdTestVectors) {
+  const uint8_t server_id_lens[] = {3, 8};
+  const uint8_t nonce_lens[] = {4, 5};
+  static_assert(sizeof(server_id_lens) == sizeof(nonce_lens));
+  const std::vector<QuicConnectionId> expected_connection_ids{
+      QuicConnectionId({0x07, 0xed, 0x79, 0x3a, 0x80, 0x49, 0x71, 0x8a}),
+      QuicConnectionId({0x4d, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
+                        0xee, 0x15, 0xda, 0x27, 0xc4}),
+  };
+  EXPECT_EQ(sizeof(server_id_lens), expected_connection_ids.size());
+  for (uint8_t i = 0; i < sizeof(server_id_lens); i++) {
+    uint8_t config_id = i % 3;
+    random_.AddNextValues(kNonceHigh, kNonceLow);
+    auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 8);
+    EXPECT_TRUE(encoder.has_value());
+    auto config = LoadBalancerConfig::CreateUnencrypted(
+        config_id, server_id_lens[i], nonce_lens[i]);
+    EXPECT_TRUE(config.has_value());
+    EXPECT_TRUE(encoder->UpdateConfig(
+        *config, MakeServerId(kServerId, server_id_lens[i])));
+    absl::uint128 nonces_left = encoder->num_nonces_left();
+    EXPECT_EQ(encoder->GenerateConnectionId(), expected_connection_ids[i]);
+    EXPECT_EQ(encoder->num_nonces_left(), nonces_left - 1);
+  }
+}
+
+// Follow example in draft-ietf-quic-load-balancers-12.
+TEST_F(LoadBalancerEncoderTest, FollowSpecExample) {
+  const uint8_t config_id = 0, server_id_len = 3, nonce_len = 4;
+  const uint8_t raw_server_id[] = {
+      0x31,
+      0x44,
+      0x1a,
+  };
+  const char raw_key[] = {
+      0xfd, 0xf7, 0x26, 0xa9, 0x89, 0x3e, 0xc0, 0x5c,
+      0x06, 0x32, 0xd3, 0x95, 0x66, 0x80, 0xba, 0xf0,
+  };
+  random_.AddNextValues(0, 0x75c2699c);
+  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 8);
+  EXPECT_TRUE(encoder.has_value());
+  auto config = LoadBalancerConfig::Create(config_id, server_id_len, nonce_len,
+                                           absl::string_view(raw_key));
+  EXPECT_TRUE(config.has_value());
+  EXPECT_TRUE(encoder->UpdateConfig(
+      *config, *LoadBalancerServerId::Create(raw_server_id)));
+  EXPECT_TRUE(encoder->IsEncoding());
+  const char raw_connection_id[] = {0x07, 0xe2, 0x3c, 0xb4,
+                                    0x2b, 0xba, 0x1e, 0xe0};
+  auto expected =
+      QuicConnectionId(raw_connection_id, 1 + server_id_len + nonce_len);
+  EXPECT_EQ(encoder->GenerateConnectionId(), expected);
+}
+
+// Compare test vectors from Appendix B of draft-ietf-quic-load-balancers-12.
+TEST_F(LoadBalancerEncoderTest, EncoderTestVectors) {
+  // Try (1) the "standard" ConnectionId length of 8
+  // (2) server_id_len > nonce_len, so there is a fourth decryption pass
+  // (3) the single-pass encryption case
+  // (4) An even total length.
+  uint8_t server_id_lens[] = {3, 10, 8, 9};
+  uint8_t nonce_lens[] = {4, 5, 8, 9};
+  static_assert(sizeof(server_id_lens) == sizeof(nonce_lens));
+  const std::vector<QuicConnectionId> expected_connection_ids{
+      QuicConnectionId({0x07, 0xfb, 0xfe, 0x05, 0xf7, 0x31, 0xb4, 0x25}),
+      QuicConnectionId({0x4f, 0x01, 0x09, 0x56, 0xfb, 0x5c, 0x1d, 0x4d, 0x86,
+                        0xe0, 0x10, 0x18, 0x3e, 0x0b, 0x7d, 0x1e}),
+      QuicConnectionId({0x90, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2,
+                        0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3}),
+      QuicConnectionId({0x12, 0x7a, 0x28, 0x5a, 0x09, 0xf8, 0x52, 0x80, 0xf4,
+                        0xfd, 0x6a, 0xbb, 0x43, 0x4a, 0x71, 0x59, 0xe4, 0xd3,
+                        0xeb}),
+  };
+  EXPECT_EQ(sizeof(server_id_lens), expected_connection_ids.size());
+  for (uint8_t i = 0; i < sizeof(server_id_lens); i++) {
+    uint8_t config_id = i % 3;
+    auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 8);
+    EXPECT_TRUE(encoder.has_value());
+    auto config = LoadBalancerConfig::Create(config_id, server_id_lens[i],
+                                             nonce_lens[i], kKey);
+    EXPECT_TRUE(config.has_value());
+    random_.AddNextValues(kNonceHigh, kNonceLow);
+    EXPECT_TRUE(encoder->UpdateConfig(
+        *config, MakeServerId(kServerId, server_id_lens[i])));
+    EXPECT_EQ(encoder->GenerateConnectionId(), expected_connection_ids[i]);
+  }
+}
+
+TEST_F(LoadBalancerEncoderTest, RunOutOfNonces) {
+  const uint8_t config_id = 0, server_id_len = 3, nonce_len = 4;
+  TestLoadBalancerEncoderVisitor visitor;
+  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true, 8);
+  EXPECT_TRUE(encoder.has_value());
+  auto config =
+      LoadBalancerConfig::Create(config_id, server_id_len, nonce_len, kKey);
+  EXPECT_TRUE(config.has_value());
+  EXPECT_TRUE(
+      encoder->UpdateConfig(*config, MakeServerId(kServerId, server_id_len)));
+  EXPECT_EQ(visitor.num_adds(), 1u);
+  LoadBalancerEncoderPeer::SetNumNoncesLeft(*encoder, 2);
+  EXPECT_EQ(encoder->num_nonces_left(), 2);
+  EXPECT_EQ(encoder->GenerateConnectionId(),
+            QuicConnectionId({0x07, 0xba, 0x7f, 0x38, 0x2f, 0x5c, 0x22, 0x1d}));
+  EXPECT_EQ(encoder->num_nonces_left(), 1);
+  encoder->GenerateConnectionId();
+  EXPECT_EQ(encoder->IsEncoding(), false);
+  // No retire_calls except for the initial UpdateConfig.
+  EXPECT_EQ(visitor.num_deletes(), 1u);
+}
+
+TEST_F(LoadBalancerEncoderTest, UnroutableConnectionId) {
+  random_.AddNextValues(0x83, kNonceHigh);
+  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, false);
+  EXPECT_TRUE(encoder.has_value());
+  EXPECT_EQ(encoder->num_nonces_left(), 0);
+  auto connection_id = encoder->GenerateConnectionId();
+  // The first byte is the config_id (0xc0) xored with (0x83 & 0x3f).
+  // The remaining bytes are random, and therefore match kNonceHigh.
+  QuicConnectionId expected({0xc3, 0x5d, 0x52, 0xde, 0x4d, 0xe3, 0xe7, 0x21});
+  EXPECT_EQ(expected, connection_id);
+}
+
+TEST_F(LoadBalancerEncoderTest, NonDefaultUnroutableConnectionIdLength) {
+  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true, 9);
+  EXPECT_TRUE(encoder.has_value());
+  QuicConnectionId connection_id = encoder->GenerateConnectionId();
+  EXPECT_EQ(connection_id.length(), 9);
+}
+
+TEST_F(LoadBalancerEncoderTest, DeleteConfigWhenNoConfigExists) {
+  TestLoadBalancerEncoderVisitor visitor;
+  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
+  EXPECT_TRUE(encoder.has_value());
+  encoder->DeleteConfig();
+  EXPECT_EQ(visitor.num_deletes(), 0u);
+}
+
+TEST_F(LoadBalancerEncoderTest, AddConfig) {
+  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  TestLoadBalancerEncoderVisitor visitor;
+  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
+  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
+  EXPECT_EQ(visitor.num_adds(), 1u);
+  absl::uint128 left = encoder->num_nonces_left();
+  EXPECT_EQ(left, (0x1ull << 32));
+  EXPECT_TRUE(encoder->IsEncoding());
+  EXPECT_FALSE(encoder->IsEncrypted());
+  encoder->GenerateConnectionId();
+  EXPECT_EQ(encoder->num_nonces_left(), left - 1);
+  EXPECT_EQ(visitor.num_deletes(), 0u);
+}
+
+TEST_F(LoadBalancerEncoderTest, UpdateConfig) {
+  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  TestLoadBalancerEncoderVisitor visitor;
+  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
+  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
+  config = LoadBalancerConfig::Create(1, 4, 4, kKey);
+  EXPECT_TRUE(config.has_value());
+  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 4)));
+  EXPECT_EQ(visitor.num_adds(), 2u);
+  EXPECT_EQ(visitor.num_deletes(), 1u);
+  EXPECT_TRUE(encoder->IsEncoding());
+  EXPECT_TRUE(encoder->IsEncrypted());
+}
+
+TEST_F(LoadBalancerEncoderTest, DeleteConfig) {
+  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  TestLoadBalancerEncoderVisitor visitor;
+  auto encoder = LoadBalancerEncoder::Create(random_, &visitor, true);
+  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
+  encoder->DeleteConfig();
+  EXPECT_EQ(visitor.num_adds(), 1u);
+  EXPECT_EQ(visitor.num_deletes(), 1u);
+  EXPECT_FALSE(encoder->IsEncoding());
+  EXPECT_FALSE(encoder->IsEncrypted());
+  EXPECT_EQ(encoder->num_nonces_left(), 0);
+}
+
+TEST_F(LoadBalancerEncoderTest, DeleteConfigNoVisitor) {
+  auto config = LoadBalancerConfig::CreateUnencrypted(0, 3, 4);
+  EXPECT_TRUE(config.has_value());
+  auto encoder = LoadBalancerEncoder::Create(random_, nullptr, true);
+  EXPECT_TRUE(encoder->UpdateConfig(*config, MakeServerId(kServerId, 3)));
+  encoder->DeleteConfig();
+  EXPECT_FALSE(encoder->IsEncoding());
+  EXPECT_FALSE(encoder->IsEncrypted());
+  EXPECT_EQ(encoder->num_nonces_left(), 0);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_server_id.cc b/quiche/quic/load_balancer/load_balancer_server_id.cc
new file mode 100644
index 0000000..5805b7f
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_server_id.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+
+#include "absl/strings/escaping.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+namespace {
+
+// Helper to allow setting the const array during initialization.
+std::array<uint8_t, kLoadBalancerMaxServerIdLen> MakeArray(
+    const absl::Span<const uint8_t> data, const uint8_t length) {
+  std::array<uint8_t, kLoadBalancerMaxServerIdLen> array;
+  memcpy(array.data(), data.data(), length);
+  return array;
+}
+
+}  // namespace
+
+absl::optional<LoadBalancerServerId> LoadBalancerServerId::Create(
+    const absl::Span<const uint8_t> data) {
+  if (data.length() == 0 || data.length() > kLoadBalancerMaxServerIdLen) {
+    QUIC_BUG(quic_bug_433312504_01)
+        << "Attempted to create LoadBalancerServerId with length "
+        << data.length();
+    return absl::optional<LoadBalancerServerId>();
+  }
+  return LoadBalancerServerId(data);
+}
+
+std::string LoadBalancerServerId::ToString() const {
+  return absl::BytesToHexString(
+      absl::string_view(reinterpret_cast<const char*>(data_.data()), length_));
+}
+
+LoadBalancerServerId::LoadBalancerServerId(const absl::Span<const uint8_t> data)
+    : data_(MakeArray(data, data.length())), length_(data.length()) {}
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_server_id.h b/quiche/quic/load_balancer/load_balancer_server_id.h
new file mode 100644
index 0000000..039d615
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_server_id.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_LOAD_BALANCER_SERVER_ID_H_
+#define QUICHE_QUIC_LOAD_BALANCER_SERVER_ID_H_
+
+#include <array>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// The maximum number of bytes in a LoadBalancerServerId.
+inline constexpr uint8_t kLoadBalancerMaxServerIdLen = 15;
+
+// LoadBalancerServerId is the globally understood identifier for a given pool
+// member. It is unique to any given QUIC-LB configuration. See
+// draft-ietf-quic-load-balancers-12.
+// Note: this has nothing to do with QuicServerID. It's an unfortunate collision
+// between an internal term for the destination identifiers for a particular
+// deployment (QuicServerID) and the object of a load balancing decision
+// (LoadBalancerServerId).
+class QUIC_EXPORT_PRIVATE LoadBalancerServerId {
+ public:
+  // Copies all the bytes from |data| into a new LoadBalancerServerId.
+  static absl::optional<LoadBalancerServerId> Create(
+      const absl::Span<const uint8_t> data);
+
+  // Server IDs are opaque bytes, but defining these operators allows us to sort
+  // them into a tree and define ranges.
+  bool operator<(const LoadBalancerServerId& other) const {
+    return data() < other.data();
+  }
+  bool operator==(const LoadBalancerServerId& other) const {
+    return data() == other.data();
+  }
+
+  // Hash function to allow use as a key in unordered maps.
+  template <typename H>
+  friend H AbslHashValue(H h, const LoadBalancerServerId& server_id) {
+    return H::combine_contiguous(std::move(h), server_id.data().data(),
+                                 server_id.length());
+  }
+
+  absl::Span<const uint8_t> data() const {
+    return absl::MakeConstSpan(data_.data(), length_);
+  }
+  uint8_t length() const { return length_; }
+
+  // Returns the server ID in hex format.
+  std::string ToString() const;
+
+ private:
+  // The constructor is private because it can't validate the input.
+  LoadBalancerServerId(const absl::Span<const uint8_t> data);
+
+  std::array<uint8_t, kLoadBalancerMaxServerIdLen> data_;
+  uint8_t length_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_LOAD_BALANCER_SERVER_ID_H_
diff --git a/quiche/quic/load_balancer/load_balancer_server_id_map.h b/quiche/quic/load_balancer/load_balancer_server_id_map.h
new file mode 100644
index 0000000..02671bb
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_server_id_map.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
+#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+// This class wraps an absl::flat_hash_map which associates server IDs to an
+// arbitrary type T. It validates that all server ids are of the same fixed
+// length.
+template <typename T>
+class QUIC_EXPORT_PRIVATE LoadBalancerServerIdMap {
+ public:
+  // Returns a newly created pool for server IDs of length |server_id_len|, or
+  // nullptr if |server_id_len| is invalid.
+  static std::shared_ptr<LoadBalancerServerIdMap> Create(
+      const uint8_t server_id_len);
+
+  // Returns the entry associated with |server_id|, if present. For small |T|,
+  // use Lookup. For large |T|, use LookupNoCopy.
+  absl::optional<const T> Lookup(const LoadBalancerServerId server_id) const;
+  const T* LookupNoCopy(const LoadBalancerServerId server_id) const;
+
+  // Updates the table so that |value| is associated with |server_id|. Sets
+  // QUIC_BUG if the length is incorrect for this map.
+  void AddOrReplace(const LoadBalancerServerId server_id, T value);
+
+  // Removes the entry associated with |server_id|.
+  void Erase(const LoadBalancerServerId server_id) {
+    server_id_table_.erase(server_id);
+  }
+
+  uint8_t server_id_len() const { return server_id_len_; }
+
+ private:
+  LoadBalancerServerIdMap(uint8_t server_id_len)
+      : server_id_len_(server_id_len) {}
+
+  const uint8_t server_id_len_;  // All server IDs must be of this length.
+  absl::flat_hash_map<LoadBalancerServerId, T> server_id_table_;
+};
+
+template <typename T>
+std::shared_ptr<LoadBalancerServerIdMap<T>> LoadBalancerServerIdMap<T>::Create(
+    const uint8_t server_id_len) {
+  if (server_id_len == 0 || server_id_len > kLoadBalancerMaxServerIdLen) {
+    QUIC_BUG(quic_bug_434893339_01)
+        << "Tried to configure map with server ID length "
+        << static_cast<int>(server_id_len);
+    return nullptr;
+  }
+  return std::make_shared<LoadBalancerServerIdMap<T>>(
+      LoadBalancerServerIdMap(server_id_len));
+}
+
+template <typename T>
+absl::optional<const T> LoadBalancerServerIdMap<T>::Lookup(
+    const LoadBalancerServerId server_id) const {
+  if (server_id.length() != server_id_len_) {
+    QUIC_BUG(quic_bug_434893339_02)
+        << "Lookup with a " << static_cast<int>(server_id.length())
+        << " byte server ID, map requires " << static_cast<int>(server_id_len_);
+    return absl::optional<T>();
+  }
+  auto it = server_id_table_.find(server_id);
+  return (it != server_id_table_.end()) ? it->second
+                                        : absl::optional<const T>();
+}
+
+template <typename T>
+const T* LoadBalancerServerIdMap<T>::LookupNoCopy(
+    const LoadBalancerServerId server_id) const {
+  if (server_id.length() != server_id_len_) {
+    QUIC_BUG(quic_bug_434893339_02)
+        << "Lookup with a " << static_cast<int>(server_id.length())
+        << " byte server ID, map requires " << static_cast<int>(server_id_len_);
+    return nullptr;
+  }
+  auto it = server_id_table_.find(server_id);
+  return (it != server_id_table_.end()) ? &it->second : nullptr;
+}
+
+template <typename T>
+void LoadBalancerServerIdMap<T>::AddOrReplace(
+    const LoadBalancerServerId server_id, T value) {
+  if (server_id.length() == server_id_len_) {
+    server_id_table_[server_id] = value;
+  } else {
+    QUIC_BUG(quic_bug_434893339_03)
+        << "Server ID of " << static_cast<int>(server_id.length())
+        << " bytes; this map requires " << static_cast<int>(server_id_len_);
+  }
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_SERVER_ID_MAP_H_
diff --git a/quiche/quic/load_balancer/load_balancer_server_id_map_test.cc b/quiche/quic/load_balancer/load_balancer_server_id_map_test.cc
new file mode 100644
index 0000000..d8fcdac
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_server_id_map_test.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_server_id_map.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51};
+
+class LoadBalancerServerIdMapTest : public QuicTest {
+ public:
+  const LoadBalancerServerId valid_server_id_ =
+      *LoadBalancerServerId::Create(kServerId);
+  const LoadBalancerServerId invalid_server_id_ =
+      *LoadBalancerServerId::Create(absl::Span<const uint8_t>(kServerId, 3));
+};
+
+TEST_F(LoadBalancerServerIdMapTest, CreateWithBadServerIdLength) {
+  EXPECT_QUIC_BUG(EXPECT_EQ(LoadBalancerServerIdMap<int>::Create(0), nullptr),
+                  "Tried to configure map with server ID length 0");
+  EXPECT_QUIC_BUG(EXPECT_EQ(LoadBalancerServerIdMap<int>::Create(16), nullptr),
+                  "Tried to configure map with server ID length 16");
+}
+
+TEST_F(LoadBalancerServerIdMapTest, AddOrReplaceWithBadServerIdLength) {
+  int record = 1;
+  auto pool = LoadBalancerServerIdMap<int>::Create(4);
+  EXPECT_NE(pool, nullptr);
+  EXPECT_QUIC_BUG(pool->AddOrReplace(invalid_server_id_, record),
+                  "Server ID of 3 bytes; this map requires 4");
+}
+
+TEST_F(LoadBalancerServerIdMapTest, LookupWithBadServerIdLength) {
+  int record = 1;
+  auto pool = LoadBalancerServerIdMap<int>::Create(4);
+  EXPECT_NE(pool, nullptr);
+  pool->AddOrReplace(valid_server_id_, record);
+  EXPECT_QUIC_BUG(EXPECT_FALSE(pool->Lookup(invalid_server_id_).has_value()),
+                  "Lookup with a 3 byte server ID, map requires 4");
+  EXPECT_QUIC_BUG(EXPECT_EQ(pool->LookupNoCopy(invalid_server_id_), nullptr),
+                  "Lookup with a 3 byte server ID, map requires 4");
+}
+
+TEST_F(LoadBalancerServerIdMapTest, LookupWhenEmpty) {
+  auto pool = LoadBalancerServerIdMap<int>::Create(4);
+  EXPECT_NE(pool, nullptr);
+  EXPECT_EQ(pool->LookupNoCopy(valid_server_id_), nullptr);
+  absl::optional<int> result = pool->Lookup(valid_server_id_);
+  EXPECT_FALSE(result.has_value());
+}
+
+TEST_F(LoadBalancerServerIdMapTest, AddLookup) {
+  int record1 = 1, record2 = 2;
+  auto pool = LoadBalancerServerIdMap<int>::Create(4);
+  EXPECT_NE(pool, nullptr);
+  auto other_server_id = LoadBalancerServerId::Create({0x01, 0x02, 0x03, 0x04});
+  EXPECT_TRUE(other_server_id.has_value());
+  pool->AddOrReplace(valid_server_id_, record1);
+  pool->AddOrReplace(*other_server_id, record2);
+  absl::optional<int> result = pool->Lookup(valid_server_id_);
+  EXPECT_TRUE(result.has_value());
+  EXPECT_EQ(*result, record1);
+  auto result_ptr = pool->LookupNoCopy(valid_server_id_);
+  EXPECT_NE(result_ptr, nullptr);
+  EXPECT_EQ(*result_ptr, record1);
+  result = pool->Lookup(*other_server_id);
+  EXPECT_TRUE(result.has_value());
+  EXPECT_EQ(*result, record2);
+}
+
+TEST_F(LoadBalancerServerIdMapTest, AddErase) {
+  int record = 1;
+  auto pool = LoadBalancerServerIdMap<int>::Create(4);
+  EXPECT_NE(pool, nullptr);
+  pool->AddOrReplace(valid_server_id_, record);
+  EXPECT_EQ(*pool->LookupNoCopy(valid_server_id_), record);
+  pool->Erase(valid_server_id_);
+  EXPECT_EQ(pool->LookupNoCopy(valid_server_id_), nullptr);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/load_balancer/load_balancer_server_id_test.cc b/quiche/quic/load_balancer/load_balancer_server_id_test.cc
new file mode 100644
index 0000000..ab15094
--- /dev/null
+++ b/quiche/quic/load_balancer/load_balancer_server_id_test.cc
@@ -0,0 +1,111 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+
+#include "absl/hash/hash_testing.h"
+
+#pragma clang diagnostic pop
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+class LoadBalancerServerIdTest : public QuicTest {};
+
+constexpr uint8_t kRawServerId[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+                                    0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+                                    0x0c, 0x0d, 0x0e, 0x0f};
+
+TEST_F(LoadBalancerServerIdTest, CreateReturnsNullIfTooLong) {
+  EXPECT_QUIC_BUG(EXPECT_FALSE(LoadBalancerServerId::Create(
+                                   absl::Span<const uint8_t>(kRawServerId, 16))
+                                   .has_value()),
+                  "Attempted to create LoadBalancerServerId with length 16");
+  EXPECT_QUIC_BUG(
+      EXPECT_FALSE(LoadBalancerServerId::Create(absl::Span<const uint8_t>())
+                       .has_value()),
+      "Attempted to create LoadBalancerServerId with length 0");
+}
+
+TEST_F(LoadBalancerServerIdTest, CompareIdenticalExceptLength) {
+  auto server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
+  ASSERT_TRUE(server_id.has_value());
+  EXPECT_EQ(server_id->length(), 15);
+  auto shorter_server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
+  ASSERT_TRUE(shorter_server_id.has_value());
+  EXPECT_EQ(shorter_server_id->length(), 5);
+  // Shorter comes before longer if all bits match
+  EXPECT_TRUE(shorter_server_id < server_id);
+  EXPECT_FALSE(server_id < shorter_server_id);
+  // Different lengths are never equal.
+  EXPECT_FALSE(shorter_server_id == server_id);
+}
+
+TEST_F(LoadBalancerServerIdTest, AccessorFunctions) {
+  auto server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
+  EXPECT_TRUE(server_id.has_value());
+  EXPECT_EQ(server_id->length(), 5);
+  EXPECT_EQ(memcmp(server_id->data().data(), kRawServerId, 5), 0);
+  EXPECT_EQ(server_id->ToString(), "0001020304");
+}
+
+TEST_F(LoadBalancerServerIdTest, CompareDifferentServerIds) {
+  auto server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
+  ASSERT_TRUE(server_id.has_value());
+  auto reverse = LoadBalancerServerId::Create({0x0f, 0x0e, 0x0d, 0x0c, 0x0b});
+  ASSERT_TRUE(reverse.has_value());
+  EXPECT_TRUE(server_id < reverse);
+  auto long_server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
+  EXPECT_TRUE(long_server_id < reverse);
+}
+
+TEST_F(LoadBalancerServerIdTest, EqualityOperators) {
+  auto server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
+  ASSERT_TRUE(server_id.has_value());
+  auto shorter_server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
+  ASSERT_TRUE(shorter_server_id.has_value());
+  EXPECT_FALSE(server_id == shorter_server_id);
+  auto server_id2 = server_id;
+  EXPECT_TRUE(server_id == server_id2);
+}
+
+TEST_F(LoadBalancerServerIdTest, SupportsHash) {
+  auto server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 15));
+  ASSERT_TRUE(server_id.has_value());
+  auto shorter_server_id =
+      LoadBalancerServerId::Create(absl::Span<const uint8_t>(kRawServerId, 5));
+  ASSERT_TRUE(shorter_server_id.has_value());
+  auto different_server_id =
+      LoadBalancerServerId::Create({0x0f, 0x0e, 0x0d, 0x0c, 0x0b});
+  ASSERT_TRUE(different_server_id.has_value());
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
+      *server_id,
+      *shorter_server_id,
+      *different_server_id,
+  }));
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quic/masque/README.md b/quiche/quic/masque/README.md
similarity index 100%
rename from quic/masque/README.md
rename to quiche/quic/masque/README.md
diff --git a/quiche/quic/masque/masque_client_bin.cc b/quiche/quic/masque/masque_client_bin.cc
new file mode 100644
index 0000000..a2d0c62
--- /dev/null
+++ b/quiche/quic/masque/masque_client_bin.cc
@@ -0,0 +1,118 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is reponsible for the masque_client binary. It allows testing
+// our MASQUE client code by connecting to a MASQUE proxy and then sending
+// HTTP/3 requests to web servers tunnelled over that MASQUE connection.
+// e.g.: masque_client $PROXY_HOST:$PROXY_PORT $URL1 $URL2
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "url/third_party/mozilla/url_parse.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/masque/masque_client_tools.h"
+#include "quiche/quic/masque/masque_encapsulated_epoll_client.h"
+#include "quiche/quic/masque/masque_epoll_client.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_default_proof_providers.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/fake_proof_verifier.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_system_event_loop.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, disable_certificate_verification, false,
+    "If true, don't verify the server certificate.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
+                                "Allows setting MASQUE mode, valid values are "
+                                "open and legacy. Defaults to open.");
+
+namespace quic {
+
+namespace {
+
+int RunMasqueClient(int argc, char* argv[]) {
+  quiche::QuicheSystemEventLoop event_loop("masque_client");
+  const char* usage = "Usage: masque_client [options] <url>";
+
+  // The first non-flag argument is the URI template of the MASQUE server.
+  // All subsequent ones are interpreted as URLs to fetch via the MASQUE server.
+  // Note that the URI template expansion currently only supports string
+  // replacement of {target_host} and {target_port}, not
+  // {?target_host,target_port}.
+  std::vector<std::string> urls =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (urls.empty()) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    return 1;
+  }
+
+  const bool disable_certificate_verification =
+      GetQuicFlag(FLAGS_disable_certificate_verification);
+  QuicEpollServer epoll_server;
+
+  std::string uri_template = urls[0];
+  if (!absl::StrContains(uri_template, '/')) {
+    // Allow passing in authority instead of URI template.
+    uri_template =
+        absl::StrCat("https://", uri_template, "/{target_host}/{target_port}/");
+  }
+  url::Parsed parsed_uri_template;
+  url::ParseStandardURL(uri_template.c_str(), uri_template.length(),
+                        &parsed_uri_template);
+  if (!parsed_uri_template.scheme.is_nonempty() ||
+      !parsed_uri_template.host.is_nonempty() ||
+      !parsed_uri_template.path.is_nonempty()) {
+    std::cerr << "Failed to parse MASQUE URI template \"" << urls[0] << "\""
+              << std::endl;
+    return 1;
+  }
+  std::string host = uri_template.substr(parsed_uri_template.host.begin,
+                                         parsed_uri_template.host.len);
+  std::unique_ptr<ProofVerifier> proof_verifier;
+  if (disable_certificate_verification) {
+    proof_verifier = std::make_unique<FakeProofVerifier>();
+  } else {
+    proof_verifier = CreateDefaultProofVerifier(host);
+  }
+  MasqueMode masque_mode = MasqueMode::kOpen;
+  std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
+  if (mode_string == "legacy") {
+    masque_mode = MasqueMode::kLegacy;
+  } else if (!mode_string.empty() && mode_string != "open") {
+    std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
+    return 1;
+  }
+  std::unique_ptr<MasqueEpollClient> masque_client = MasqueEpollClient::Create(
+      uri_template, masque_mode, &epoll_server, std::move(proof_verifier));
+  if (masque_client == nullptr) {
+    return 1;
+  }
+
+  std::cerr << "MASQUE is connected " << masque_client->connection_id()
+            << " in " << masque_mode << " mode" << std::endl;
+
+  for (size_t i = 1; i < urls.size(); ++i) {
+    if (!tools::SendEncapsulatedMasqueRequest(
+            masque_client.get(), &epoll_server, urls[i],
+            disable_certificate_verification)) {
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+}  // namespace
+
+}  // namespace quic
+
+int main(int argc, char* argv[]) {
+  return quic::RunMasqueClient(argc, argv);
+}
diff --git a/quiche/quic/masque/masque_client_session.cc b/quiche/quic/masque/masque_client_session.cc
new file mode 100644
index 0000000..fc6da5a
--- /dev/null
+++ b/quiche/quic/masque/masque_client_session.cc
@@ -0,0 +1,435 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_client_session.h"
+
+#include <string>
+
+#include "absl/algorithm/container.h"
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/str_cat.h"
+#include "url/url_canon.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/common/platform/api/quiche_url_utils.h"
+
+namespace quic {
+
+MasqueClientSession::MasqueClientSession(
+    MasqueMode masque_mode, const std::string& uri_template,
+    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection, const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index, Owner* owner)
+    : QuicSpdyClientSession(config, supported_versions, connection, server_id,
+                            crypto_config, push_promise_index),
+      masque_mode_(masque_mode),
+      uri_template_(uri_template),
+      owner_(owner),
+      compression_engine_(this) {}
+
+void MasqueClientSession::OnMessageReceived(absl::string_view message) {
+  if (masque_mode_ == MasqueMode::kLegacy) {
+    QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
+    QuicConnectionId client_connection_id, server_connection_id;
+    QuicSocketAddress target_server_address;
+    std::vector<char> packet;
+    bool version_present;
+    if (!compression_engine_.DecompressDatagram(
+            message, &client_connection_id, &server_connection_id,
+            &target_server_address, &packet, &version_present)) {
+      return;
+    }
+
+    auto connection_id_registration =
+        client_connection_id_registrations_.find(client_connection_id);
+    if (connection_id_registration ==
+        client_connection_id_registrations_.end()) {
+      QUIC_DLOG(ERROR) << "MasqueClientSession failed to dispatch "
+                       << client_connection_id;
+      return;
+    }
+    EncapsulatedClientSession* encapsulated_client_session =
+        connection_id_registration->second;
+    encapsulated_client_session->ProcessPacket(
+        absl::string_view(packet.data(), packet.size()), target_server_address);
+
+    QUIC_DVLOG(1) << "Sent " << packet.size() << " bytes to connection for "
+                  << client_connection_id;
+    return;
+  }
+  QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
+  QuicSpdySession::OnMessageReceived(message);
+}
+
+void MasqueClientSession::OnMessageAcked(QuicMessageId message_id,
+                                         QuicTime /*receive_timestamp*/) {
+  QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
+}
+
+void MasqueClientSession::OnMessageLost(QuicMessageId message_id) {
+  QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost";
+}
+
+const MasqueClientSession::ConnectUdpClientState*
+MasqueClientSession::GetOrCreateConnectUdpClientState(
+    const QuicSocketAddress& target_server_address,
+    EncapsulatedClientSession* encapsulated_client_session) {
+  for (const ConnectUdpClientState& client_state : connect_udp_client_states_) {
+    if (client_state.target_server_address() == target_server_address &&
+        client_state.encapsulated_client_session() ==
+            encapsulated_client_session) {
+      // Found existing CONNECT-UDP request.
+      return &client_state;
+    }
+  }
+  // No CONNECT-UDP request found, create a new one.
+
+  url::Parsed parsed_uri_template;
+  url::ParseStandardURL(uri_template_.c_str(), uri_template_.length(),
+                        &parsed_uri_template);
+  if (!parsed_uri_template.path.is_nonempty()) {
+    QUIC_BUG(bad URI template path)
+        << "Cannot parse path from URI template " << uri_template_;
+    return nullptr;
+  }
+  std::string path = uri_template_.substr(parsed_uri_template.path.begin,
+                                          parsed_uri_template.path.len);
+  if (parsed_uri_template.query.is_valid()) {
+    absl::StrAppend(&path, "?",
+                    uri_template_.substr(parsed_uri_template.query.begin,
+                                         parsed_uri_template.query.len));
+  }
+  absl::flat_hash_map<std::string, std::string> parameters;
+  parameters["target_host"] = target_server_address.host().ToString();
+  parameters["target_port"] = absl::StrCat(target_server_address.port());
+  std::string expanded_path;
+  absl::flat_hash_set<std::string> vars_found;
+  bool expanded =
+      quiche::ExpandURITemplate(path, parameters, &expanded_path, &vars_found);
+  if (!expanded || vars_found.find("target_host") == vars_found.end() ||
+      vars_found.find("target_port") == vars_found.end()) {
+    QUIC_DLOG(ERROR) << "Failed to expand URI template \"" << uri_template_
+                     << "\" for " << target_server_address;
+    return nullptr;
+  }
+
+  url::Component expanded_path_component(0, expanded_path.length());
+  url::RawCanonOutput<1024> canonicalized_path_output;
+  url::Component canonicalized_path_component;
+  bool canonicalized = url::CanonicalizePath(
+      expanded_path.c_str(), expanded_path_component,
+      &canonicalized_path_output, &canonicalized_path_component);
+  if (!canonicalized || !canonicalized_path_component.is_nonempty()) {
+    QUIC_DLOG(ERROR) << "Failed to canonicalize URI template \""
+                     << uri_template_ << "\" for " << target_server_address;
+    return nullptr;
+  }
+  std::string canonicalized_path(
+      canonicalized_path_output.data() + canonicalized_path_component.begin,
+      canonicalized_path_component.len);
+
+  QuicSpdyClientStream* stream = CreateOutgoingBidirectionalStream();
+  if (stream == nullptr) {
+    // Stream flow control limits prevented us from opening a new stream.
+    QUIC_DLOG(ERROR) << "Failed to open CONNECT-UDP stream";
+    return nullptr;
+  }
+
+  QuicUrl url(uri_template_);
+  std::string scheme = url.scheme();
+  std::string authority = url.HostPort();
+
+  QUIC_DLOG(INFO) << "Sending CONNECT-UDP request for " << target_server_address
+                  << " on stream " << stream->id() << " scheme=\"" << scheme
+                  << "\" authority=\"" << authority << "\" path=\""
+                  << canonicalized_path << "\"";
+
+  // Send the request.
+  spdy::Http2HeaderBlock headers;
+  headers[":method"] = "CONNECT";
+  headers[":protocol"] = "connect-udp";
+  headers[":scheme"] = scheme;
+  headers[":authority"] = authority;
+  headers[":path"] = canonicalized_path;
+  headers["connect-udp-version"] = "6";
+  if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
+    SpdyUtils::AddDatagramFlowIdHeader(&headers, stream->id());
+  }
+  size_t bytes_sent =
+      stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false);
+  if (bytes_sent == 0) {
+    QUIC_DLOG(ERROR) << "Failed to send CONNECT-UDP request";
+    return nullptr;
+  }
+
+  absl::optional<QuicDatagramContextId> context_id;
+  connect_udp_client_states_.push_back(
+      ConnectUdpClientState(stream, encapsulated_client_session, this,
+                            context_id, target_server_address));
+  return &connect_udp_client_states_.back();
+}
+
+void MasqueClientSession::SendPacket(
+    QuicConnectionId client_connection_id,
+    QuicConnectionId server_connection_id, absl::string_view packet,
+    const QuicSocketAddress& target_server_address,
+    EncapsulatedClientSession* encapsulated_client_session) {
+  if (masque_mode_ == MasqueMode::kLegacy) {
+    compression_engine_.CompressAndSendPacket(packet, client_connection_id,
+                                              server_connection_id,
+                                              target_server_address);
+    return;
+  }
+  const ConnectUdpClientState* connect_udp = GetOrCreateConnectUdpClientState(
+      target_server_address, encapsulated_client_session);
+  if (connect_udp == nullptr) {
+    QUIC_DLOG(ERROR) << "Failed to create CONNECT-UDP request";
+    return;
+  }
+
+  MessageStatus message_status = SendHttp3Datagram(
+      connect_udp->stream()->id(), connect_udp->context_id(), packet);
+
+  QUIC_DVLOG(1) << "Sent packet to " << target_server_address
+                << " compressed with stream ID " << connect_udp->stream()->id()
+                << " context ID "
+                << (connect_udp->context_id().has_value()
+                        ? absl::StrCat(connect_udp->context_id().value())
+                        : "none")
+                << " and got message status "
+                << MessageStatusToString(message_status);
+}
+
+void MasqueClientSession::RegisterConnectionId(
+    QuicConnectionId client_connection_id,
+    EncapsulatedClientSession* encapsulated_client_session) {
+  QUIC_DLOG(INFO) << "Registering " << client_connection_id
+                  << " to encapsulated client";
+  QUICHE_DCHECK(
+      client_connection_id_registrations_.find(client_connection_id) ==
+          client_connection_id_registrations_.end() ||
+      client_connection_id_registrations_[client_connection_id] ==
+          encapsulated_client_session);
+  client_connection_id_registrations_[client_connection_id] =
+      encapsulated_client_session;
+}
+
+void MasqueClientSession::UnregisterConnectionId(
+    QuicConnectionId client_connection_id,
+    EncapsulatedClientSession* encapsulated_client_session) {
+  QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
+  if (masque_mode_ == MasqueMode::kLegacy) {
+    if (client_connection_id_registrations_.find(client_connection_id) !=
+        client_connection_id_registrations_.end()) {
+      client_connection_id_registrations_.erase(client_connection_id);
+      owner_->UnregisterClientConnectionId(client_connection_id);
+      compression_engine_.UnregisterClientConnectionId(client_connection_id);
+    }
+    return;
+  }
+
+  for (auto it = connect_udp_client_states_.begin();
+       it != connect_udp_client_states_.end();) {
+    if (it->encapsulated_client_session() == encapsulated_client_session) {
+      QUIC_DLOG(INFO) << "Removing state for stream ID " << it->stream()->id()
+                      << " context ID "
+                      << (it->context_id().has_value()
+                              ? absl::StrCat(it->context_id().value())
+                              : "none");
+      auto* stream = it->stream();
+      it = connect_udp_client_states_.erase(it);
+      if (!stream->write_side_closed()) {
+        stream->Reset(QUIC_STREAM_CANCELLED);
+      }
+    } else {
+      ++it;
+    }
+  }
+}
+
+void MasqueClientSession::OnConnectionClosed(
+    const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
+  QuicSpdyClientSession::OnConnectionClosed(frame, source);
+  // Close all encapsulated sessions.
+  for (const auto& client_state : connect_udp_client_states_) {
+    client_state.encapsulated_client_session()->CloseConnection(
+        QUIC_CONNECTION_CANCELLED, "Underlying MASQUE connection was closed",
+        ConnectionCloseBehavior::SILENT_CLOSE);
+  }
+}
+
+void MasqueClientSession::OnStreamClosed(QuicStreamId stream_id) {
+  if (QuicUtils::IsBidirectionalStreamId(stream_id, version()) &&
+      QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
+    QuicSpdyClientStream* stream =
+        reinterpret_cast<QuicSpdyClientStream*>(GetActiveStream(stream_id));
+    if (stream != nullptr) {
+      QUIC_DLOG(INFO) << "Stream " << stream_id
+                      << " closed, got response headers:"
+                      << stream->response_headers().DebugString();
+    }
+  }
+  for (auto it = connect_udp_client_states_.begin();
+       it != connect_udp_client_states_.end();) {
+    if (it->stream()->id() == stream_id) {
+      QUIC_DLOG(INFO) << "Stream " << stream_id
+                      << " was closed, removing state for context ID "
+                      << (it->context_id().has_value()
+                              ? absl::StrCat(it->context_id().value())
+                              : "none");
+      auto* encapsulated_client_session = it->encapsulated_client_session();
+      it = connect_udp_client_states_.erase(it);
+      encapsulated_client_session->CloseConnection(
+          QUIC_CONNECTION_CANCELLED,
+          "Underlying MASQUE CONNECT-UDP stream was closed",
+          ConnectionCloseBehavior::SILENT_CLOSE);
+    } else {
+      ++it;
+    }
+  }
+
+  QuicSpdyClientSession::OnStreamClosed(stream_id);
+}
+
+bool MasqueClientSession::OnSettingsFrame(const SettingsFrame& frame) {
+  QUIC_DLOG(INFO) << "Received SETTINGS: " << frame;
+  if (!QuicSpdyClientSession::OnSettingsFrame(frame)) {
+    QUIC_DLOG(ERROR) << "Failed to parse received settings";
+    return false;
+  }
+  if (!SupportsH3Datagram()) {
+    QUIC_DLOG(ERROR) << "Refusing to use MASQUE without HTTP/3 Datagrams";
+    return false;
+  }
+  QUIC_DLOG(INFO) << "Using HTTP Datagram: " << http_datagram_support();
+  owner_->OnSettingsReceived();
+  return true;
+}
+
+MasqueClientSession::ConnectUdpClientState::ConnectUdpClientState(
+    QuicSpdyClientStream* stream,
+    EncapsulatedClientSession* encapsulated_client_session,
+    MasqueClientSession* masque_session,
+    absl::optional<QuicDatagramContextId> context_id,
+    const QuicSocketAddress& target_server_address)
+    : stream_(stream),
+      encapsulated_client_session_(encapsulated_client_session),
+      masque_session_(masque_session),
+      context_id_(context_id),
+      target_server_address_(target_server_address) {
+  QUICHE_DCHECK_NE(masque_session_, nullptr);
+  this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
+  this->stream()->RegisterHttp3DatagramContextId(
+      this->context_id(), DatagramFormatType::UDP_PAYLOAD,
+      /*format_additional_data=*/absl::string_view(), this);
+}
+
+MasqueClientSession::ConnectUdpClientState::~ConnectUdpClientState() {
+  if (stream() != nullptr) {
+    stream()->UnregisterHttp3DatagramContextId(context_id());
+    stream()->UnregisterHttp3DatagramRegistrationVisitor();
+  }
+}
+
+MasqueClientSession::ConnectUdpClientState::ConnectUdpClientState(
+    MasqueClientSession::ConnectUdpClientState&& other) {
+  *this = std::move(other);
+}
+
+MasqueClientSession::ConnectUdpClientState&
+MasqueClientSession::ConnectUdpClientState::operator=(
+    MasqueClientSession::ConnectUdpClientState&& other) {
+  stream_ = other.stream_;
+  encapsulated_client_session_ = other.encapsulated_client_session_;
+  masque_session_ = other.masque_session_;
+  context_id_ = other.context_id_;
+  target_server_address_ = other.target_server_address_;
+  other.stream_ = nullptr;
+  if (stream() != nullptr) {
+    stream()->MoveHttp3DatagramRegistration(this);
+    stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
+  }
+  return *this;
+}
+
+void MasqueClientSession::ConnectUdpClientState::OnHttp3Datagram(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  QUICHE_DCHECK_EQ(stream_id, stream()->id());
+  QUICHE_DCHECK(context_id == context_id_);
+  encapsulated_client_session_->ProcessPacket(payload, target_server_address_);
+  QUIC_DVLOG(1) << "Sent " << payload.size()
+                << " bytes to connection for stream ID " << stream_id
+                << " context ID "
+                << (context_id.has_value() ? absl::StrCat(context_id.value())
+                                           : "none");
+}
+
+void MasqueClientSession::ConnectUdpClientState::OnContextReceived(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    DatagramFormatType format_type, absl::string_view format_additional_data) {
+  if (stream_id != stream_->id()) {
+    QUIC_BUG(MASQUE client bad datagram context registration)
+        << "Registered stream ID " << stream_id << ", expected "
+        << stream_->id();
+    return;
+  }
+  if (format_type != DatagramFormatType::UDP_PAYLOAD) {
+    QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
+                    << DatagramFormatTypeToString(format_type);
+    return;
+  }
+  if (!format_additional_data.empty()) {
+    QUIC_DLOG(ERROR)
+        << "Received non-empty format additional data for context ID "
+        << (context_id_.has_value() ? context_id_.value() : 0)
+        << " on stream ID " << stream()->id();
+    masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
+    return;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO)
+        << "Ignoring unexpected context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " instead of "
+        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
+                                    : "none")
+        << " on stream ID " << stream_->id();
+    return;
+  }
+  // Do nothing since the client registers first and we currently ignore
+  // extensions.
+}
+
+void MasqueClientSession::ConnectUdpClientState::OnContextClosed(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    ContextCloseCode close_code, absl::string_view close_details) {
+  if (stream_id != stream_->id()) {
+    QUIC_BUG(MASQUE client bad datagram context registration)
+        << "Closed context on stream ID " << stream_id << ", expected "
+        << stream_->id();
+    return;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO)
+        << "Ignoring unexpected close of context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " instead of "
+        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
+                                    : "none")
+        << " on stream ID " << stream_->id();
+    return;
+  }
+  QUIC_DLOG(INFO) << "Received datagram context close with close code "
+                  << close_code << " close details \"" << close_details
+                  << "\" on stream ID " << stream_->id() << ", closing stream";
+  masque_session_->ResetStream(stream_->id(), QUIC_STREAM_CANCELLED);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_client_session.h b/quiche/quic/masque/masque_client_session.h
new file mode 100644
index 0000000..d89f4b4
--- /dev/null
+++ b/quiche/quic/masque/masque_client_session.h
@@ -0,0 +1,186 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
+
+#include <string>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/masque/masque_compression_engine.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// QUIC client session for connection to MASQUE proxy. This session establishes
+// a connection to a MASQUE proxy and handles sending and receiving DATAGRAM
+// frames for operation of the MASQUE protocol. Multiple end-to-end encapsulated
+// sessions can then coexist inside this session. Once these are created, they
+// need to be registered with this session.
+class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
+ public:
+  // Interface meant to be implemented by the owner of the
+  // MasqueClientSession instance.
+  class QUIC_NO_EXPORT Owner {
+   public:
+    virtual ~Owner() {}
+
+    // Notifies the owner that the client connection ID is no longer in use.
+    virtual void UnregisterClientConnectionId(
+        QuicConnectionId client_connection_id) = 0;
+
+    // Notifies the owner that a settings frame has been received.
+    virtual void OnSettingsReceived() = 0;
+  };
+  // Interface meant to be implemented by encapsulated client sessions, i.e.
+  // the end-to-end QUIC client sessions that run inside MASQUE encapsulation.
+  class QUIC_NO_EXPORT EncapsulatedClientSession {
+   public:
+    virtual ~EncapsulatedClientSession() {}
+
+    // Process packet that was just decapsulated.
+    virtual void ProcessPacket(absl::string_view packet,
+                               QuicSocketAddress target_server_address) = 0;
+
+    // Close the encapsulated connection.
+    virtual void CloseConnection(
+        QuicErrorCode error,
+        const std::string& details,
+        ConnectionCloseBehavior connection_close_behavior) = 0;
+  };
+
+  // Takes ownership of |connection|, but not of |crypto_config| or
+  // |push_promise_index| or |owner|. All pointers must be non-null. Caller
+  // must ensure that |push_promise_index| and |owner| stay valid for the
+  // lifetime of the newly created MasqueClientSession.
+  MasqueClientSession(MasqueMode masque_mode, const std::string& uri_template,
+                      const QuicConfig& config,
+                      const ParsedQuicVersionVector& supported_versions,
+                      QuicConnection* connection, const QuicServerId& server_id,
+                      QuicCryptoClientConfig* crypto_config,
+                      QuicClientPushPromiseIndex* push_promise_index,
+                      Owner* owner);
+
+  // Disallow copy and assign.
+  MasqueClientSession(const MasqueClientSession&) = delete;
+  MasqueClientSession& operator=(const MasqueClientSession&) = delete;
+
+  // From QuicSession.
+  void OnMessageReceived(absl::string_view message) override;
+  void OnMessageAcked(QuicMessageId message_id,
+                      QuicTime receive_timestamp) override;
+  void OnMessageLost(QuicMessageId message_id) override;
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+  void OnStreamClosed(QuicStreamId stream_id) override;
+
+  // From QuicSpdySession.
+  bool OnSettingsFrame(const SettingsFrame& frame) override;
+
+  // Send encapsulated packet.
+  void SendPacket(QuicConnectionId client_connection_id,
+                  QuicConnectionId server_connection_id,
+                  absl::string_view packet,
+                  const QuicSocketAddress& target_server_address,
+                  EncapsulatedClientSession* encapsulated_client_session);
+
+  // Register encapsulated client. This allows clients that are encapsulated
+  // within this MASQUE session to indicate they own a given client connection
+  // ID so incoming packets with that connection ID are routed back to them.
+  // Callers must not register a second different |encapsulated_client_session|
+  // with the same |client_connection_id|. Every call must be matched with a
+  // call to UnregisterConnectionId.
+  void RegisterConnectionId(
+      QuicConnectionId client_connection_id,
+      EncapsulatedClientSession* encapsulated_client_session);
+
+  // Unregister encapsulated client. |client_connection_id| must match a
+  // value previously passed to RegisterConnectionId.
+  void UnregisterConnectionId(
+      QuicConnectionId client_connection_id,
+      EncapsulatedClientSession* encapsulated_client_session);
+
+ private:
+  // State that the MasqueClientSession keeps for each CONNECT-UDP request.
+  class QUIC_NO_EXPORT ConnectUdpClientState
+      : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
+        public QuicSpdyStream::Http3DatagramVisitor {
+   public:
+    // |stream| and |encapsulated_client_session| must be valid for the lifetime
+    // of the ConnectUdpClientState.
+    explicit ConnectUdpClientState(
+        QuicSpdyClientStream* stream,
+        EncapsulatedClientSession* encapsulated_client_session,
+        MasqueClientSession* masque_session,
+        absl::optional<QuicDatagramContextId> context_id,
+        const QuicSocketAddress& target_server_address);
+
+    ~ConnectUdpClientState();
+
+    // Disallow copy but allow move.
+    ConnectUdpClientState(const ConnectUdpClientState&) = delete;
+    ConnectUdpClientState(ConnectUdpClientState&&);
+    ConnectUdpClientState& operator=(const ConnectUdpClientState&) = delete;
+    ConnectUdpClientState& operator=(ConnectUdpClientState&&);
+
+    QuicSpdyClientStream* stream() const { return stream_; }
+    EncapsulatedClientSession* encapsulated_client_session() const {
+      return encapsulated_client_session_;
+    }
+    absl::optional<QuicDatagramContextId> context_id() const {
+      return context_id_;
+    }
+    const QuicSocketAddress& target_server_address() const {
+      return target_server_address_;
+    }
+
+    // From QuicSpdyStream::Http3DatagramVisitor.
+    void OnHttp3Datagram(QuicStreamId stream_id,
+                         absl::optional<QuicDatagramContextId> context_id,
+                         absl::string_view payload) override;
+
+    // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
+    void OnContextReceived(QuicStreamId stream_id,
+                           absl::optional<QuicDatagramContextId> context_id,
+                           DatagramFormatType format_type,
+                           absl::string_view format_additional_data) override;
+    void OnContextClosed(QuicStreamId stream_id,
+                         absl::optional<QuicDatagramContextId> context_id,
+                         ContextCloseCode close_code,
+                         absl::string_view close_details) override;
+
+   private:
+    QuicSpdyClientStream* stream_;                            // Unowned.
+    EncapsulatedClientSession* encapsulated_client_session_;  // Unowned.
+    MasqueClientSession* masque_session_;                     // Unowned.
+    absl::optional<QuicDatagramContextId> context_id_;
+    QuicSocketAddress target_server_address_;
+  };
+
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    return HttpDatagramSupport::kDraft00And04;
+  }
+
+  const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
+      const QuicSocketAddress& target_server_address,
+      EncapsulatedClientSession* encapsulated_client_session);
+
+  MasqueMode masque_mode_;
+  std::string uri_template_;
+  std::list<ConnectUdpClientState> connect_udp_client_states_;
+  absl::flat_hash_map<QuicConnectionId,
+                      EncapsulatedClientSession*,
+                      QuicConnectionIdHash>
+      client_connection_id_registrations_;
+  Owner* owner_;  // Unowned;
+  MasqueCompressionEngine compression_engine_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_SESSION_H_
diff --git a/quiche/quic/masque/masque_client_tools.cc b/quiche/quic/masque/masque_client_tools.cc
new file mode 100644
index 0000000..993716a
--- /dev/null
+++ b/quiche/quic/masque/masque_client_tools.cc
@@ -0,0 +1,107 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_client_tools.h"
+#include "quiche/quic/masque/masque_encapsulated_epoll_client.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_default_proof_providers.h"
+#include "quiche/quic/tools/fake_proof_verifier.h"
+#include "quiche/quic/tools/quic_url.h"
+
+namespace quic {
+namespace tools {
+
+bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client,
+                                   QuicEpollServer* epoll_server,
+                                   std::string url_string,
+                                   bool disable_certificate_verification) {
+  const QuicUrl url(url_string, "https");
+  std::unique_ptr<ProofVerifier> proof_verifier;
+  if (disable_certificate_verification) {
+    proof_verifier = std::make_unique<FakeProofVerifier>();
+  } else {
+    proof_verifier = CreateDefaultProofVerifier(url.host());
+  }
+
+  // Build the client, and try to connect.
+  const QuicSocketAddress addr =
+      LookupAddress(url.host(), absl::StrCat(url.port()));
+  if (!addr.IsInitialized()) {
+    QUIC_LOG(ERROR) << "Unable to resolve address: " << url.host();
+    return false;
+  }
+  const QuicServerId server_id(url.host(), url.port());
+  auto client = std::make_unique<MasqueEncapsulatedEpollClient>(
+      addr, server_id, epoll_server, std::move(proof_verifier), masque_client);
+
+  if (client == nullptr) {
+    QUIC_LOG(ERROR) << "Failed to create MasqueEncapsulatedEpollClient for "
+                    << url_string;
+    return false;
+  }
+
+  client->set_initial_max_packet_length(kMasqueMaxEncapsulatedPacketSize);
+  client->set_drop_response_body(false);
+  if (!client->Initialize()) {
+    QUIC_LOG(ERROR) << "Failed to initialize MasqueEncapsulatedEpollClient for "
+                    << url_string;
+    return false;
+  }
+
+  if (!client->Connect()) {
+    QuicErrorCode error = client->session()->error();
+    QUIC_LOG(ERROR) << "Failed to connect with client "
+                    << client->session()->connection()->client_connection_id()
+                    << " server " << client->session()->connection_id()
+                    << " to " << url.HostPort()
+                    << ". Error: " << QuicErrorCodeToString(error);
+    return false;
+  }
+
+  QUIC_LOG(INFO) << "Connected client "
+                 << client->session()->connection()->client_connection_id()
+                 << " server " << client->session()->connection_id() << " for "
+                 << url_string;
+
+  // Construct the string body from flags, if provided.
+  // TODO(dschinazi) Add support for HTTP POST and non-empty bodies.
+  const std::string body = "";
+
+  // Construct a GET or POST request for supplied URL.
+  spdy::Http2HeaderBlock header_block;
+  header_block[":method"] = "GET";
+  header_block[":scheme"] = url.scheme();
+  header_block[":authority"] = url.HostPort();
+  header_block[":path"] = url.PathParamsQuery();
+
+  // Make sure to store the response, for later output.
+  client->set_store_response(true);
+
+  // Send the MASQUE init request.
+  client->SendRequestAndWaitForResponse(header_block, body,
+                                        /*fin=*/true);
+
+  if (!client->connected()) {
+    QUIC_LOG(ERROR) << "Request for " << url_string
+                    << " caused connection failure. Error: "
+                    << QuicErrorCodeToString(client->session()->error());
+    return false;
+  }
+
+  const int response_code = client->latest_response_code();
+  if (response_code < 200 || response_code >= 300) {
+    QUIC_LOG(ERROR) << "Request for " << url_string
+                    << " failed with HTTP response code " << response_code;
+    return false;
+  }
+
+  const std::string response_body = client->latest_response_body();
+  QUIC_LOG(INFO) << "Request succeeded for " << url_string << std::endl
+                 << response_body;
+
+  return true;
+}
+
+}  // namespace tools
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_client_tools.h b/quiche/quic/masque/masque_client_tools.h
new file mode 100644
index 0000000..0a8a439
--- /dev/null
+++ b/quiche/quic/masque/masque_client_tools.h
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
+
+#include "quiche/quic/masque/masque_epoll_client.h"
+
+namespace quic {
+namespace tools {
+
+// Sends an HTTP GET request for |url_string|, proxied over the MASQUE
+// connection represented by |masque_client|. A valid and owned |epoll_server|
+// is required. |disable_certificate_verification| allows disabling verification
+// of the HTTP server's TLS certificate.
+bool SendEncapsulatedMasqueRequest(MasqueEpollClient* masque_client,
+                                   QuicEpollServer* epoll_server,
+                                   std::string url_string,
+                                   bool disable_certificate_verification);
+
+}  // namespace tools
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_CLIENT_TOOLS_H_
diff --git a/quiche/quic/masque/masque_compression_engine.cc b/quiche/quic/masque/masque_compression_engine.cc
new file mode 100644
index 0000000..3d05740
--- /dev/null
+++ b/quiche/quic/masque/masque_compression_engine.cc
@@ -0,0 +1,526 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_compression_engine.h"
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+
+namespace {
+// |kFlowId0| is used to indicate creation of a new compression context.
+const QuicDatagramStreamId kFlowId0 = 0;
+
+enum MasqueAddressFamily : uint8_t {
+  MasqueAddressFamilyIPv4 = 4,
+  MasqueAddressFamilyIPv6 = 6,
+};
+
+}  // namespace
+
+MasqueCompressionEngine::MasqueCompressionEngine(
+    QuicSpdySession* masque_session)
+    : masque_session_(masque_session),
+      next_available_flow_id_(
+          masque_session_->perspective() == Perspective::IS_CLIENT ? 0 : 1) {}
+
+QuicDatagramStreamId MasqueCompressionEngine::FindOrCreateCompressionContext(
+    QuicConnectionId client_connection_id,
+    QuicConnectionId server_connection_id,
+    const QuicSocketAddress& server_address, bool client_connection_id_present,
+    bool server_connection_id_present, bool* validated) {
+  QuicDatagramStreamId flow_id = kFlowId0;
+  *validated = false;
+  for (const auto& kv : contexts_) {
+    const MasqueCompressionContext& context = kv.second;
+    if (context.server_address != server_address) {
+      continue;
+    }
+    if (client_connection_id_present &&
+        context.client_connection_id != client_connection_id) {
+      continue;
+    }
+    if (server_connection_id_present &&
+        context.server_connection_id != server_connection_id) {
+      continue;
+    }
+
+    flow_id = kv.first;
+    QUICHE_DCHECK_NE(flow_id, kFlowId0);
+    *validated = context.validated;
+    QUIC_DVLOG(1) << "Compressing using " << (*validated ? "" : "un")
+                  << "validated flow_id " << flow_id << " to "
+                  << context.server_address << " client "
+                  << context.client_connection_id << " server "
+                  << context.server_connection_id;
+    break;
+  }
+
+  if (flow_id != kFlowId0) {
+    // Found a compression context, use it.
+    return flow_id;
+  }
+
+  // Create new compression context.
+  next_available_flow_id_ += 2;
+  flow_id = next_available_flow_id_;
+  QUIC_DVLOG(1) << "Compression assigning new flow_id " << flow_id << " to "
+                << server_address << " client " << client_connection_id
+                << " server " << server_connection_id;
+  MasqueCompressionContext context;
+  context.client_connection_id = client_connection_id;
+  context.server_connection_id = server_connection_id;
+  context.server_address = server_address;
+  contexts_[flow_id] = context;
+
+  return flow_id;
+}
+
+bool MasqueCompressionEngine::WriteCompressedPacketToSlice(
+    QuicConnectionId client_connection_id,
+    QuicConnectionId server_connection_id,
+    const QuicSocketAddress& server_address,
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, QuicDatagramStreamId flow_id,
+    bool validated, uint8_t first_byte, bool long_header,
+    QuicDataReader* reader, QuicDataWriter* writer) {
+  if (validated) {
+    QUIC_DVLOG(1) << "Compressing using validated flow_id " << flow_id;
+    if (!writer->WriteVarInt62(flow_id)) {
+      QUIC_BUG(quic_bug_10981_1) << "Failed to write flow_id";
+      return false;
+    }
+  } else {
+    QUIC_DVLOG(1) << "Compressing using unvalidated flow_id " << flow_id;
+    if (!writer->WriteVarInt62(kFlowId0)) {
+      QUIC_BUG(quic_bug_10981_2) << "Failed to write kFlowId0";
+      return false;
+    }
+    if (!writer->WriteVarInt62(flow_id)) {
+      QUIC_BUG(quic_bug_10981_3) << "Failed to write flow_id";
+      return false;
+    }
+    if (!writer->WriteLengthPrefixedConnectionId(client_connection_id)) {
+      QUIC_BUG(quic_bug_10981_4) << "Failed to write client_connection_id";
+      return false;
+    }
+    if (!writer->WriteLengthPrefixedConnectionId(server_connection_id)) {
+      QUIC_BUG(quic_bug_10981_5) << "Failed to write server_connection_id";
+      return false;
+    }
+    if (!writer->WriteUInt16(server_address.port())) {
+      QUIC_BUG(quic_bug_10981_6) << "Failed to write port";
+      return false;
+    }
+    QuicIpAddress peer_ip = server_address.host();
+    QUICHE_DCHECK(peer_ip.IsInitialized());
+    std::string peer_ip_bytes = peer_ip.ToPackedString();
+    QUICHE_DCHECK(!peer_ip_bytes.empty());
+    uint8_t address_id;
+    if (peer_ip.address_family() == IpAddressFamily::IP_V6) {
+      address_id = MasqueAddressFamilyIPv6;
+      if (peer_ip_bytes.length() != QuicIpAddress::kIPv6AddressSize) {
+        QUIC_BUG(quic_bug_10981_7) << "Bad IPv6 length " << server_address;
+        return false;
+      }
+    } else if (peer_ip.address_family() == IpAddressFamily::IP_V4) {
+      address_id = MasqueAddressFamilyIPv4;
+      if (peer_ip_bytes.length() != QuicIpAddress::kIPv4AddressSize) {
+        QUIC_BUG(quic_bug_10981_8) << "Bad IPv4 length " << server_address;
+        return false;
+      }
+    } else {
+      QUIC_BUG(quic_bug_10981_9)
+          << "Unexpected server_address " << server_address;
+      return false;
+    }
+    if (!writer->WriteUInt8(address_id)) {
+      QUIC_BUG(quic_bug_10981_10) << "Failed to write address_id";
+      return false;
+    }
+    if (!writer->WriteStringPiece(peer_ip_bytes)) {
+      QUIC_BUG(quic_bug_10981_11) << "Failed to write IP address";
+      return false;
+    }
+  }
+  if (!writer->WriteUInt8(first_byte)) {
+    QUIC_BUG(quic_bug_10981_12) << "Failed to write first_byte";
+    return false;
+  }
+  if (long_header) {
+    QuicVersionLabel version_label;
+    if (!reader->ReadUInt32(&version_label)) {
+      QUIC_DLOG(ERROR) << "Failed to read version";
+      return false;
+    }
+    if (!writer->WriteUInt32(version_label)) {
+      QUIC_BUG(quic_bug_10981_13) << "Failed to write version";
+      return false;
+    }
+    QuicConnectionId packet_destination_connection_id,
+        packet_source_connection_id;
+    if (!reader->ReadLengthPrefixedConnectionId(
+            &packet_destination_connection_id) ||
+        !reader->ReadLengthPrefixedConnectionId(&packet_source_connection_id)) {
+      QUIC_DLOG(ERROR) << "Failed to parse long header connection IDs";
+      return false;
+    }
+    if (packet_destination_connection_id != destination_connection_id) {
+      QUIC_DLOG(ERROR) << "Long header packet's destination_connection_id "
+                       << packet_destination_connection_id
+                       << " does not match expected "
+                       << destination_connection_id;
+      return false;
+    }
+    if (packet_source_connection_id != source_connection_id) {
+      QUIC_DLOG(ERROR) << "Long header packet's source_connection_id "
+                       << packet_source_connection_id
+                       << " does not match expected " << source_connection_id;
+      return false;
+    }
+  } else {
+    QuicConnectionId packet_destination_connection_id;
+    if (!reader->ReadConnectionId(&packet_destination_connection_id,
+                                  destination_connection_id.length())) {
+      QUIC_DLOG(ERROR)
+          << "Failed to read short header packet's destination_connection_id";
+      return false;
+    }
+    if (packet_destination_connection_id != destination_connection_id) {
+      QUIC_DLOG(ERROR) << "Short header packet's destination_connection_id "
+                       << packet_destination_connection_id
+                       << " does not match expected "
+                       << destination_connection_id;
+      return false;
+    }
+  }
+  absl::string_view packet_payload = reader->ReadRemainingPayload();
+  if (!writer->WriteStringPiece(packet_payload)) {
+    QUIC_BUG(quic_bug_10981_14) << "Failed to write packet_payload";
+    return false;
+  }
+  return true;
+}
+
+void MasqueCompressionEngine::CompressAndSendPacket(
+    absl::string_view packet, QuicConnectionId client_connection_id,
+    QuicConnectionId server_connection_id,
+    const QuicSocketAddress& server_address) {
+  QUIC_DVLOG(2) << "Compressing client " << client_connection_id << " server "
+                << server_connection_id << "\n"
+                << quiche::QuicheTextUtils::HexDump(packet);
+  QUICHE_DCHECK(server_address.IsInitialized());
+  if (packet.empty()) {
+    QUIC_BUG(quic_bug_10981_15) << "Tried to send empty packet";
+    return;
+  }
+  QuicDataReader reader(packet.data(), packet.length());
+  uint8_t first_byte;
+  if (!reader.ReadUInt8(&first_byte)) {
+    QUIC_BUG(quic_bug_10981_16) << "Failed to read first_byte";
+    return;
+  }
+  const bool long_header = (first_byte & FLAGS_LONG_HEADER) != 0;
+  bool client_connection_id_present = true, server_connection_id_present = true;
+  QuicConnectionId destination_connection_id, source_connection_id;
+  if (masque_session_->perspective() == Perspective::IS_SERVER) {
+    destination_connection_id = client_connection_id;
+    source_connection_id = server_connection_id;
+    if (!long_header) {
+      server_connection_id_present = false;
+    }
+  } else {
+    destination_connection_id = server_connection_id;
+    source_connection_id = client_connection_id;
+    if (!long_header) {
+      client_connection_id_present = false;
+    }
+  }
+
+  bool validated = false;
+  QuicDatagramStreamId flow_id = FindOrCreateCompressionContext(
+      client_connection_id, server_connection_id, server_address,
+      client_connection_id_present, server_connection_id_present, &validated);
+
+  size_t slice_length = packet.length() - destination_connection_id.length();
+  if (long_header) {
+    slice_length -= sizeof(uint8_t) * 2 + source_connection_id.length();
+  }
+  if (validated) {
+    slice_length += QuicDataWriter::GetVarInt62Len(flow_id);
+  } else {
+    slice_length += QuicDataWriter::GetVarInt62Len(kFlowId0) +
+                    QuicDataWriter::GetVarInt62Len(flow_id) + sizeof(uint8_t) +
+                    client_connection_id.length() + sizeof(uint8_t) +
+                    server_connection_id.length() +
+                    sizeof(server_address.port()) + sizeof(uint8_t) +
+                    server_address.host().ToPackedString().length();
+  }
+  quiche::QuicheBuffer buffer(
+      masque_session_->connection()->helper()->GetStreamSendBufferAllocator(),
+      slice_length);
+  QuicDataWriter writer(buffer.size(), buffer.data());
+
+  if (!WriteCompressedPacketToSlice(
+          client_connection_id, server_connection_id, server_address,
+          destination_connection_id, source_connection_id, flow_id, validated,
+          first_byte, long_header, &reader, &writer)) {
+    return;
+  }
+
+  MessageResult message_result =
+      masque_session_->SendMessage(quiche::QuicheMemSlice(std::move(buffer)));
+
+  QUIC_DVLOG(1) << "Sent packet compressed with flow ID " << flow_id
+                << " and got message result " << message_result;
+}
+
+bool MasqueCompressionEngine::ParseCompressionContext(
+    QuicDataReader* reader, MasqueCompressionContext* context) {
+  QuicDatagramStreamId new_flow_id;
+  if (!reader->ReadVarInt62(&new_flow_id)) {
+    QUIC_DLOG(ERROR) << "Could not read new_flow_id";
+    return false;
+  }
+  QuicConnectionId new_client_connection_id;
+  if (!reader->ReadLengthPrefixedConnectionId(&new_client_connection_id)) {
+    QUIC_DLOG(ERROR) << "Could not read new_client_connection_id";
+    return false;
+  }
+  QuicConnectionId new_server_connection_id;
+  if (!reader->ReadLengthPrefixedConnectionId(&new_server_connection_id)) {
+    QUIC_DLOG(ERROR) << "Could not read new_server_connection_id";
+    return false;
+  }
+  uint16_t port;
+  if (!reader->ReadUInt16(&port)) {
+    QUIC_DLOG(ERROR) << "Could not read port";
+    return false;
+  }
+  uint8_t address_id;
+  if (!reader->ReadUInt8(&address_id)) {
+    QUIC_DLOG(ERROR) << "Could not read address_id";
+    return false;
+  }
+  size_t ip_bytes_length;
+  if (address_id == MasqueAddressFamilyIPv6) {
+    ip_bytes_length = QuicIpAddress::kIPv6AddressSize;
+  } else if (address_id == MasqueAddressFamilyIPv4) {
+    ip_bytes_length = QuicIpAddress::kIPv4AddressSize;
+  } else {
+    QUIC_DLOG(ERROR) << "Unknown address_id " << static_cast<int>(address_id);
+    return false;
+  }
+  char ip_bytes[QuicIpAddress::kMaxAddressSize];
+  if (!reader->ReadBytes(ip_bytes, ip_bytes_length)) {
+    QUIC_DLOG(ERROR) << "Could not read IP address";
+    return false;
+  }
+  QuicIpAddress ip_address;
+  ip_address.FromPackedString(ip_bytes, ip_bytes_length);
+  if (!ip_address.IsInitialized()) {
+    QUIC_BUG(quic_bug_10981_17) << "Failed to parse IP address";
+    return false;
+  }
+  QuicSocketAddress new_server_address = QuicSocketAddress(ip_address, port);
+  auto context_pair = contexts_.find(new_flow_id);
+  if (context_pair == contexts_.end()) {
+    context->client_connection_id = new_client_connection_id;
+    context->server_connection_id = new_server_connection_id;
+    context->server_address = new_server_address;
+    context->validated = true;
+    contexts_[new_flow_id] = *context;
+    QUIC_DVLOG(1) << "Registered new flow_id " << new_flow_id << " to "
+                  << new_server_address << " client "
+                  << new_client_connection_id << " server "
+                  << new_server_connection_id;
+  } else {
+    *context = context_pair->second;
+    if (context->client_connection_id != new_client_connection_id) {
+      QUIC_LOG(ERROR)
+          << "Received incorrect context registration for existing flow_id "
+          << new_flow_id << " mismatched client "
+          << context->client_connection_id << " " << new_client_connection_id;
+      return false;
+    }
+    if (context->server_connection_id != new_server_connection_id) {
+      QUIC_LOG(ERROR)
+          << "Received incorrect context registration for existing flow_id "
+          << new_flow_id << " mismatched server "
+          << context->server_connection_id << " " << new_server_connection_id;
+      return false;
+    }
+    if (context->server_address != new_server_address) {
+      QUIC_LOG(ERROR)
+          << "Received incorrect context registration for existing flow_id "
+          << new_flow_id << " mismatched server " << context->server_address
+          << " " << new_server_address;
+      return false;
+    }
+    if (!context->validated) {
+      context->validated = true;
+      contexts_[new_flow_id] = *context;
+      QUIC_DLOG(INFO) << "Successfully validated remotely-unvalidated flow_id "
+                      << new_flow_id << " to " << new_server_address
+                      << " client " << new_client_connection_id << " server "
+                      << new_server_connection_id;
+    } else {
+      QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
+                       "remotely-unvalidated flow_id "
+                    << new_flow_id << " to " << new_server_address << " client "
+                    << new_client_connection_id << " server "
+                    << new_server_connection_id;
+    }
+  }
+  return true;
+}
+
+bool MasqueCompressionEngine::WriteDecompressedPacket(
+    QuicDataReader* reader, const MasqueCompressionContext& context,
+    std::vector<char>* packet, bool* version_present) {
+  QuicConnectionId destination_connection_id, source_connection_id;
+  if (masque_session_->perspective() == Perspective::IS_SERVER) {
+    destination_connection_id = context.server_connection_id;
+    source_connection_id = context.client_connection_id;
+  } else {
+    destination_connection_id = context.client_connection_id;
+    source_connection_id = context.server_connection_id;
+  }
+
+  size_t packet_length =
+      reader->BytesRemaining() + destination_connection_id.length();
+  uint8_t first_byte;
+  if (!reader->ReadUInt8(&first_byte)) {
+    QUIC_DLOG(ERROR) << "Failed to read first_byte";
+    return false;
+  }
+  *version_present = (first_byte & FLAGS_LONG_HEADER) != 0;
+  if (*version_present) {
+    packet_length += sizeof(uint8_t) * 2 + source_connection_id.length();
+  }
+  *packet = std::vector<char>(packet_length);
+  QuicDataWriter writer(packet->size(), packet->data());
+  if (!writer.WriteUInt8(first_byte)) {
+    QUIC_BUG(quic_bug_10981_18) << "Failed to write first_byte";
+    return false;
+  }
+  if (*version_present) {
+    QuicVersionLabel version_label;
+    if (!reader->ReadUInt32(&version_label)) {
+      QUIC_DLOG(ERROR) << "Failed to read version";
+      return false;
+    }
+    if (!writer.WriteUInt32(version_label)) {
+      QUIC_BUG(quic_bug_10981_19) << "Failed to write version";
+      return false;
+    }
+    if (!writer.WriteLengthPrefixedConnectionId(destination_connection_id)) {
+      QUIC_BUG(quic_bug_10981_20)
+          << "Failed to write long header destination_connection_id";
+      return false;
+    }
+    if (!writer.WriteLengthPrefixedConnectionId(source_connection_id)) {
+      QUIC_BUG(quic_bug_10981_21)
+          << "Failed to write long header source_connection_id";
+      return false;
+    }
+  } else {
+    if (!writer.WriteConnectionId(destination_connection_id)) {
+      QUIC_BUG(quic_bug_10981_22)
+          << "Failed to write short header destination_connection_id";
+      return false;
+    }
+  }
+  absl::string_view payload = reader->ReadRemainingPayload();
+  if (!writer.WriteStringPiece(payload)) {
+    QUIC_BUG(quic_bug_10981_23) << "Failed to write payload";
+    return false;
+  }
+  return true;
+}
+
+bool MasqueCompressionEngine::DecompressDatagram(
+    absl::string_view datagram, QuicConnectionId* client_connection_id,
+    QuicConnectionId* server_connection_id, QuicSocketAddress* server_address,
+    std::vector<char>* packet, bool* version_present) {
+  QUIC_DVLOG(1) << "Decompressing DATAGRAM frame of length "
+                << datagram.length();
+  QuicDataReader reader(datagram);
+  QuicDatagramStreamId flow_id;
+  if (!reader.ReadVarInt62(&flow_id)) {
+    QUIC_DLOG(ERROR) << "Could not read flow_id";
+    return false;
+  }
+  MasqueCompressionContext context;
+  if (flow_id == kFlowId0) {
+    if (!ParseCompressionContext(&reader, &context)) {
+      return false;
+    }
+  } else {
+    auto context_pair = contexts_.find(flow_id);
+    if (context_pair == contexts_.end()) {
+      QUIC_DLOG(ERROR) << "Received unknown flow_id " << flow_id;
+      return false;
+    }
+    context = context_pair->second;
+
+    if (!context.validated) {
+      context.validated = true;
+      contexts_[flow_id] = context;
+      QUIC_DLOG(INFO) << "Successfully validated remotely-validated flow_id "
+                      << flow_id << " to " << context.server_address
+                      << " client " << context.client_connection_id
+                      << " server " << context.server_connection_id;
+    } else {
+      QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
+                       "remotely-validated flow_id "
+                    << flow_id << " to " << context.server_address << " client "
+                    << context.client_connection_id << " server "
+                    << context.server_connection_id;
+    }
+  }
+
+  if (!WriteDecompressedPacket(&reader, context, packet, version_present)) {
+    return false;
+  }
+
+  *server_address = context.server_address;
+  *client_connection_id = context.client_connection_id;
+  *server_connection_id = context.server_connection_id;
+
+  QUIC_DVLOG(2) << "Decompressed client " << context.client_connection_id
+                << " server " << context.server_connection_id << "\n"
+                << quiche::QuicheTextUtils::HexDump(
+                       absl::string_view(packet->data(), packet->size()));
+
+  return true;
+}
+
+void MasqueCompressionEngine::UnregisterClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  std::vector<QuicDatagramStreamId> flow_ids_to_remove;
+  for (const auto& kv : contexts_) {
+    const MasqueCompressionContext& context = kv.second;
+    if (context.client_connection_id == client_connection_id) {
+      flow_ids_to_remove.push_back(kv.first);
+    }
+  }
+  for (QuicDatagramStreamId flow_id : flow_ids_to_remove) {
+    contexts_.erase(flow_id);
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_compression_engine.h b/quiche/quic/masque/masque_compression_engine.h
new file mode 100644
index 0000000..1ab1f2e
--- /dev/null
+++ b/quiche/quic/masque/masque_compression_engine.h
@@ -0,0 +1,120 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// MASQUE compression engine used by client and servers.
+// This class allows converting QUIC packets into a compressed form suitable
+// for sending over QUIC DATAGRAM frames. It leverages a flow identifier at the
+// start of each datagram to indicate which compression context was used to
+// compress this packet, or to create new compression contexts.
+// Compression contexts contain client and server connection IDs and the
+// server's IP and port. This allows compressing that information in most
+// packets without requiring access to the cryptographic keys of the end-to-end
+// encapsulated session. When the flow identifier is 0, the DATAGRAM contains
+// all the contents of the compression context. When the flow identifier is
+// non-zero, those fields are removed so the encapsulated QUIC packet is
+// transmitted without connection IDs and reassembled by the peer on
+// decompression. This only needs to contain the HTTP server's IP address since
+// the client's IP address is not visible to the HTTP server.
+
+class QUIC_NO_EXPORT MasqueCompressionEngine {
+ public:
+  // Caller must ensure that |masque_session| has a lifetime longer than the
+  // newly constructed MasqueCompressionEngine.
+  explicit MasqueCompressionEngine(QuicSpdySession* masque_session);
+
+  // Disallow copy and assign.
+  MasqueCompressionEngine(const MasqueCompressionEngine&) = delete;
+  MasqueCompressionEngine& operator=(const MasqueCompressionEngine&) = delete;
+
+  // Compresses packet and sends it in a DATAGRAM frame over a MASQUE session.
+  // When used from MASQUE client to MASQUE server, the MASQUE server will then
+  // send the packet to the provided |server_address|.
+  // When used from MASQUE server to MASQUE client, the MASQUE client will then
+  // hand off the uncompressed packet to an encapsulated session that will treat
+  // it as having come from the provided |server_address|.
+  // The connection IDs are the one used by the encapsulated |packet|.
+  void CompressAndSendPacket(absl::string_view packet,
+                             QuicConnectionId client_connection_id,
+                             QuicConnectionId server_connection_id,
+                             const QuicSocketAddress& server_address);
+
+  // Decompresses received DATAGRAM frame contents from |datagram| and places
+  // them in |packet|. Reverses the transformation from CompressAndSendPacket.
+  // The connection IDs are the one used by the encapsulated |packet|.
+  // |server_address| will be filled with the |server_address| passed to
+  // CompressAndSendPacket. |version_present| will contain whether the
+  // encapsulated |packet| contains a Version field.
+  bool DecompressDatagram(absl::string_view datagram,
+                          QuicConnectionId* client_connection_id,
+                          QuicConnectionId* server_connection_id,
+                          QuicSocketAddress* server_address,
+                          std::vector<char>* packet, bool* version_present);
+
+  // Clears all entries referencing |client_connection_id| from the
+  // compression table.
+  void UnregisterClientConnectionId(QuicConnectionId client_connection_id);
+
+ private:
+  struct QUIC_NO_EXPORT MasqueCompressionContext {
+    QuicConnectionId client_connection_id;
+    QuicConnectionId server_connection_id;
+    QuicSocketAddress server_address;
+    bool validated = false;
+  };
+
+  // Finds or creates a new compression context to use during compression.
+  // |client_connection_id_present| and |server_connection_id_present| indicate
+  // whether the corresponding connection ID is present in the current packet.
+  // |validated| will contain whether the compression context that matches
+  // these arguments is currently validated or not.
+  QuicDatagramStreamId FindOrCreateCompressionContext(
+      QuicConnectionId client_connection_id,
+      QuicConnectionId server_connection_id,
+      const QuicSocketAddress& server_address,
+      bool client_connection_id_present, bool server_connection_id_present,
+      bool* validated);
+
+  // Writes compressed packet to |slice| during compression.
+  bool WriteCompressedPacketToSlice(QuicConnectionId client_connection_id,
+                                    QuicConnectionId server_connection_id,
+                                    const QuicSocketAddress& server_address,
+                                    QuicConnectionId destination_connection_id,
+                                    QuicConnectionId source_connection_id,
+                                    QuicDatagramStreamId flow_id,
+                                    bool validated, uint8_t first_byte,
+                                    bool long_header, QuicDataReader* reader,
+                                    QuicDataWriter* writer);
+
+  // Parses compression context from flow ID 0 during decompression.
+  bool ParseCompressionContext(QuicDataReader* reader,
+                               MasqueCompressionContext* context);
+
+  // Writes decompressed packet to |packet| during decompression.
+  bool WriteDecompressedPacket(QuicDataReader* reader,
+                               const MasqueCompressionContext& context,
+                               std::vector<char>* packet,
+                               bool* version_present);
+
+  QuicSpdySession* masque_session_;  // Unowned.
+  absl::flat_hash_map<QuicDatagramStreamId, MasqueCompressionContext> contexts_;
+  QuicDatagramStreamId next_available_flow_id_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
diff --git a/quiche/quic/masque/masque_dispatcher.cc b/quiche/quic/masque/masque_dispatcher.cc
new file mode 100644
index 0000000..d55e799
--- /dev/null
+++ b/quiche/quic/masque/masque_dispatcher.cc
@@ -0,0 +1,92 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_dispatcher.h"
+#include "quiche/quic/masque/masque_server_session.h"
+
+namespace quic {
+
+MasqueDispatcher::MasqueDispatcher(
+    MasqueMode masque_mode,
+    const QuicConfig* config,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicVersionManager* version_manager,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<QuicConnectionHelperInterface> helper,
+    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+    std::unique_ptr<QuicAlarmFactory> alarm_factory,
+    MasqueServerBackend* masque_server_backend,
+    uint8_t expected_server_connection_id_length)
+    : QuicSimpleDispatcher(config,
+                           crypto_config,
+                           version_manager,
+                           std::move(helper),
+                           std::move(session_helper),
+                           std::move(alarm_factory),
+                           masque_server_backend,
+                           expected_server_connection_id_length),
+      masque_mode_(masque_mode),
+      epoll_server_(epoll_server),
+      masque_server_backend_(masque_server_backend) {}
+
+std::unique_ptr<QuicSession> MasqueDispatcher::CreateQuicSession(
+    QuicConnectionId connection_id, const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
+    const ParsedQuicVersion& version,
+    const ParsedClientHello& /*parsed_chlo*/) {
+  // The MasqueServerSession takes ownership of |connection| below.
+  QuicConnection* connection =
+      new QuicConnection(connection_id, self_address, peer_address, helper(),
+                         alarm_factory(), writer(),
+                         /*owns_writer=*/false, Perspective::IS_SERVER,
+                         ParsedQuicVersionVector{version});
+
+  auto session = std::make_unique<MasqueServerSession>(
+      masque_mode_, config(), GetSupportedVersions(), connection, this, this,
+      epoll_server_, session_helper(), crypto_config(),
+      compressed_certs_cache(), masque_server_backend_);
+  session->Initialize();
+  return session;
+}
+
+bool MasqueDispatcher::OnFailedToDispatchPacket(
+    const ReceivedPacketInfo& packet_info) {
+  auto connection_id_registration = client_connection_id_registrations_.find(
+      packet_info.destination_connection_id);
+  if (connection_id_registration == client_connection_id_registrations_.end()) {
+    QUIC_DLOG(INFO) << "MasqueDispatcher failed to dispatch " << packet_info;
+    return false;
+  }
+  MasqueServerSession* masque_server_session =
+      connection_id_registration->second;
+  masque_server_session->HandlePacketFromServer(packet_info);
+  return true;
+}
+
+void MasqueDispatcher::RegisterClientConnectionId(
+    QuicConnectionId client_connection_id,
+    MasqueServerSession* masque_server_session) {
+  QUIC_DLOG(INFO) << "Registering encapsulated " << client_connection_id
+                  << " to MASQUE session "
+                  << masque_server_session->connection_id();
+
+  // Make sure we don't try to overwrite an existing registration with a
+  // different session.
+  QUIC_BUG_IF(quic_bug_12013_1,
+              client_connection_id_registrations_.find(client_connection_id) !=
+                      client_connection_id_registrations_.end() &&
+                  client_connection_id_registrations_[client_connection_id] !=
+                      masque_server_session)
+      << "Overwriting existing registration for " << client_connection_id;
+  client_connection_id_registrations_[client_connection_id] =
+      masque_server_session;
+}
+
+void MasqueDispatcher::UnregisterClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
+  client_connection_id_registrations_.erase(client_connection_id);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_dispatcher.h b/quiche/quic/masque/masque_dispatcher.h
new file mode 100644
index 0000000..34130c9
--- /dev/null
+++ b/quiche/quic/masque/masque_dispatcher.h
@@ -0,0 +1,70 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/masque/masque_server_backend.h"
+#include "quiche/quic/masque/masque_server_session.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/tools/quic_simple_dispatcher.h"
+
+namespace quic {
+
+// QUIC dispatcher that handles new MASQUE connections and can proxy traffic
+// between MASQUE clients and QUIC servers.
+class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher,
+                                        public MasqueServerSession::Visitor {
+ public:
+  explicit MasqueDispatcher(
+      MasqueMode masque_mode,
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      QuicEpollServer* epoll_server,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      MasqueServerBackend* masque_server_backend,
+      uint8_t expected_server_connection_id_length);
+
+  // Disallow copy and assign.
+  MasqueDispatcher(const MasqueDispatcher&) = delete;
+  MasqueDispatcher& operator=(const MasqueDispatcher&) = delete;
+
+  // From QuicSimpleDispatcher.
+  std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId connection_id, const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version,
+      const quic::ParsedClientHello& parsed_chlo) override;
+
+  bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info) override;
+
+  // From MasqueServerSession::Visitor.
+  void RegisterClientConnectionId(
+      QuicConnectionId client_connection_id,
+      MasqueServerSession* masque_server_session) override;
+
+  void UnregisterClientConnectionId(
+      QuicConnectionId client_connection_id) override;
+
+ private:
+  MasqueMode masque_mode_;
+  QuicEpollServer* epoll_server_;               // Unowned.
+  MasqueServerBackend* masque_server_backend_;  // Unowned.
+  // Mapping from client connection IDs to server sessions, allows routing
+  // incoming packets to the right MASQUE connection.
+  absl::flat_hash_map<QuicConnectionId,
+                      MasqueServerSession*,
+                      QuicConnectionIdHash>
+      client_connection_id_registrations_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_DISPATCHER_H_
diff --git a/quiche/quic/masque/masque_encapsulated_client_session.cc b/quiche/quic/masque/masque_encapsulated_client_session.cc
new file mode 100644
index 0000000..66f6062
--- /dev/null
+++ b/quiche/quic/masque/masque_encapsulated_client_session.cc
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_encapsulated_client_session.h"
+
+namespace quic {
+
+MasqueEncapsulatedClientSession::MasqueEncapsulatedClientSession(
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index,
+    MasqueClientSession* masque_client_session)
+    : QuicSpdyClientSession(config,
+                            supported_versions,
+                            connection,
+                            server_id,
+                            crypto_config,
+                            push_promise_index),
+      masque_client_session_(masque_client_session) {}
+
+void MasqueEncapsulatedClientSession::ProcessPacket(
+    absl::string_view packet,
+    QuicSocketAddress server_address) {
+  QuicTime now = connection()->clock()->ApproximateNow();
+  QuicReceivedPacket received_packet(packet.data(), packet.length(), now);
+  connection()->ProcessUdpPacket(connection()->self_address(), server_address,
+                                 received_packet);
+}
+
+void MasqueEncapsulatedClientSession::CloseConnection(
+    QuicErrorCode error,
+    const std::string& details,
+    ConnectionCloseBehavior connection_close_behavior) {
+  connection()->CloseConnection(error, details, connection_close_behavior);
+}
+
+void MasqueEncapsulatedClientSession::OnConnectionClosed(
+    const QuicConnectionCloseFrame& frame,
+    ConnectionCloseSource source) {
+  QuicSpdyClientSession::OnConnectionClosed(frame, source);
+  masque_client_session_->UnregisterConnectionId(
+      connection()->client_connection_id(), this);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_encapsulated_client_session.h b/quiche/quic/masque/masque_encapsulated_client_session.h
new file mode 100644
index 0000000..7e1433d
--- /dev/null
+++ b/quiche/quic/masque/masque_encapsulated_client_session.h
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
+
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/masque/masque_client_session.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// QUIC client session for QUIC encapsulated in MASQUE. This client session is
+// maintained end-to-end between the client and the web-server (the MASQUE
+// session does not have access to the cryptographic keys for the end-to-end
+// session), but its packets are sent encapsulated inside DATAGRAM frames in a
+// MASQUE session, as opposed to regular QUIC packets. Multiple encapsulated
+// sessions can coexist inside a MASQUE session.
+class QUIC_NO_EXPORT MasqueEncapsulatedClientSession
+    : public QuicSpdyClientSession,
+      public MasqueClientSession::EncapsulatedClientSession {
+ public:
+  // Takes ownership of |connection|, but not of |crypto_config| or
+  // |push_promise_index| or |masque_client_session|. All pointers must be
+  // non-null. Caller must ensure that |push_promise_index| and
+  // |masque_client_session| stay valid for the lifetime of the newly created
+  // MasqueEncapsulatedClientSession.
+  MasqueEncapsulatedClientSession(
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      const QuicServerId& server_id,
+      QuicCryptoClientConfig* crypto_config,
+      QuicClientPushPromiseIndex* push_promise_index,
+      MasqueClientSession* masque_client_session);
+
+  // Disallow copy and assign.
+  MasqueEncapsulatedClientSession(const MasqueEncapsulatedClientSession&) =
+      delete;
+  MasqueEncapsulatedClientSession& operator=(
+      const MasqueEncapsulatedClientSession&) = delete;
+
+  // From MasqueClientSession::EncapsulatedClientSession.
+  void ProcessPacket(absl::string_view packet,
+                     QuicSocketAddress server_address) override;
+  void CloseConnection(
+      QuicErrorCode error,
+      const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior) override;
+
+  // From QuicSession.
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+
+ private:
+  MasqueClientSession* masque_client_session_;  // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_CLIENT_SESSION_H_
diff --git a/quiche/quic/masque/masque_encapsulated_epoll_client.cc b/quiche/quic/masque/masque_encapsulated_epoll_client.cc
new file mode 100644
index 0000000..2845541
--- /dev/null
+++ b/quiche/quic/masque/masque_encapsulated_epoll_client.cc
@@ -0,0 +1,129 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_encapsulated_epoll_client.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/masque/masque_client_session.h"
+#include "quiche/quic/masque/masque_encapsulated_client_session.h"
+#include "quiche/quic/masque/masque_epoll_client.h"
+#include "quiche/quic/masque/masque_utils.h"
+
+namespace quic {
+
+namespace {
+
+// Custom packet writer that allows getting all of a connection's outgoing
+// packets.
+class MasquePacketWriter : public QuicPacketWriter {
+ public:
+  explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client)
+      : client_(client) {}
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& /*self_address*/,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* /*options*/) override {
+    QUICHE_DCHECK(peer_address.IsInitialized());
+    QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
+                  << " bytes to " << peer_address;
+    absl::string_view packet(buffer, buf_len);
+    client_->masque_client()->masque_client_session()->SendPacket(
+        client_->session()->connection()->client_connection_id(),
+        client_->session()->connection()->connection_id(), packet, peer_address,
+        client_->masque_encapsulated_client_session());
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  bool IsWriteBlocked() const override { return false; }
+
+  void SetWritable() override {}
+
+  absl::optional<int> MessageTooBigErrorCode() const override {
+    return EMSGSIZE;
+  }
+
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& /*peer_address*/) const override {
+    return kMasqueMaxEncapsulatedPacketSize;
+  }
+
+  bool SupportsReleaseTime() const override { return false; }
+
+  bool IsBatchMode() const override { return false; }
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& /*self_address*/,
+      const QuicSocketAddress& /*peer_address*/) override {
+    return {nullptr, nullptr};
+  }
+
+  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
+
+ private:
+  MasqueEncapsulatedEpollClient* client_;  // Unowned.
+};
+
+// Custom network helper that allows injecting a custom packet writer in order
+// to get all of a connection's outgoing packets.
+class MasqueClientEpollNetworkHelper : public QuicClientEpollNetworkHelper {
+ public:
+  MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server,
+                                 MasqueEncapsulatedEpollClient* client)
+      : QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {}
+  QuicPacketWriter* CreateQuicPacketWriter() override {
+    return new MasquePacketWriter(client_);
+  }
+
+ private:
+  MasqueEncapsulatedEpollClient* client_;  // Unowned.
+};
+
+}  // namespace
+
+MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    MasqueEpollClient* masque_client)
+    : QuicClient(
+          server_address,
+          server_id,
+          MasqueSupportedVersions(),
+          MasqueEncapsulatedConfig(),
+          epoll_server,
+          std::make_unique<MasqueClientEpollNetworkHelper>(epoll_server, this),
+          std::move(proof_verifier)),
+      masque_client_(masque_client) {}
+
+MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
+  masque_client_->masque_client_session()->UnregisterConnectionId(
+      client_connection_id_, masque_encapsulated_client_session());
+}
+
+std::unique_ptr<QuicSession>
+MasqueEncapsulatedEpollClient::CreateQuicClientSession(
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection) {
+  QUIC_DLOG(INFO) << "Creating MASQUE encapsulated session for "
+                  << connection->connection_id();
+  return std::make_unique<MasqueEncapsulatedClientSession>(
+      *config(), supported_versions, connection, server_id(), crypto_config(),
+      push_promise_index(), masque_client_->masque_client_session());
+}
+
+MasqueEncapsulatedClientSession*
+MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
+  return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
+}
+
+QuicConnectionId MasqueEncapsulatedEpollClient::GetClientConnectionId() {
+  if (client_connection_id_.IsEmpty()) {
+    client_connection_id_ = QuicUtils::CreateRandomConnectionId();
+    masque_client_->masque_client_session()->RegisterConnectionId(
+        client_connection_id_, masque_encapsulated_client_session());
+  }
+  return client_connection_id_;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_encapsulated_epoll_client.h b/quiche/quic/masque/masque_encapsulated_epoll_client.h
new file mode 100644
index 0000000..cbe1bcd
--- /dev/null
+++ b/quiche/quic/masque/masque_encapsulated_epoll_client.h
@@ -0,0 +1,50 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
+
+#include "quiche/quic/masque/masque_encapsulated_client_session.h"
+#include "quiche/quic/masque/masque_epoll_client.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/tools/quic_client.h"
+
+namespace quic {
+
+// QUIC client for QUIC encapsulated in MASQUE.
+class QUIC_NO_EXPORT MasqueEncapsulatedEpollClient : public QuicClient {
+ public:
+  MasqueEncapsulatedEpollClient(QuicSocketAddress server_address,
+                                const QuicServerId& server_id,
+                                QuicEpollServer* epoll_server,
+                                std::unique_ptr<ProofVerifier> proof_verifier,
+                                MasqueEpollClient* masque_client);
+  ~MasqueEncapsulatedEpollClient() override;
+
+  // Disallow copy and assign.
+  MasqueEncapsulatedEpollClient(const MasqueEncapsulatedEpollClient&) = delete;
+  MasqueEncapsulatedEpollClient& operator=(
+      const MasqueEncapsulatedEpollClient&) = delete;
+
+  // From QuicClient.
+  std::unique_ptr<QuicSession> CreateQuicClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection) override;
+
+  QuicConnectionId GetClientConnectionId() override;
+
+  // MASQUE client that this client is encapsulated in.
+  MasqueEpollClient* masque_client() { return masque_client_; }
+
+  // Client session for this client.
+  MasqueEncapsulatedClientSession* masque_encapsulated_client_session();
+
+ private:
+  MasqueEpollClient* masque_client_;  // Unowned.
+  QuicConnectionId client_connection_id_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_ENCAPSULATED_EPOLL_CLIENT_H_
diff --git a/quiche/quic/masque/masque_epoll_client.cc b/quiche/quic/masque/masque_epoll_client.cc
new file mode 100644
index 0000000..d20ffe4
--- /dev/null
+++ b/quiche/quic/masque/masque_epoll_client.cc
@@ -0,0 +1,156 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_epoll_client.h"
+
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/masque/masque_client_session.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/tools/quic_url.h"
+
+namespace quic {
+
+MasqueEpollClient::MasqueEpollClient(
+    QuicSocketAddress server_address, const QuicServerId& server_id,
+    MasqueMode masque_mode, QuicEpollServer* epoll_server,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    const std::string& uri_template)
+    : QuicClient(server_address, server_id, MasqueSupportedVersions(),
+                 epoll_server, std::move(proof_verifier)),
+      masque_mode_(masque_mode),
+      uri_template_(uri_template) {}
+
+std::unique_ptr<QuicSession> MasqueEpollClient::CreateQuicClientSession(
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection) {
+  QUIC_DLOG(INFO) << "Creating MASQUE session for "
+                  << connection->connection_id();
+  return std::make_unique<MasqueClientSession>(
+      masque_mode_, uri_template_, *config(), supported_versions, connection,
+      server_id(), crypto_config(), push_promise_index(), this);
+}
+
+MasqueClientSession* MasqueEpollClient::masque_client_session() {
+  return static_cast<MasqueClientSession*>(QuicClient::session());
+}
+
+QuicConnectionId MasqueEpollClient::connection_id() {
+  return masque_client_session()->connection_id();
+}
+
+std::string MasqueEpollClient::authority() const {
+  QuicUrl url(uri_template_);
+  return absl::StrCat(url.host(), ":", url.port());
+}
+
+// static
+std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
+    const std::string& uri_template, MasqueMode masque_mode,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<ProofVerifier> proof_verifier) {
+  QuicUrl url(uri_template);
+  std::string host = url.host();
+  uint16_t port = url.port();
+  // Build the masque_client, and try to connect.
+  QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
+  if (!addr.IsInitialized()) {
+    QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
+    return nullptr;
+  }
+  QuicServerId server_id(host, port);
+  // Use absl::WrapUnique(new MasqueEpollClient(...)) instead of
+  // std::make_unique<MasqueEpollClient>(...) because the constructor for
+  // MasqueEpollClient is private and therefore not accessible from make_unique.
+  auto masque_client = absl::WrapUnique(
+      new MasqueEpollClient(addr, server_id, masque_mode, epoll_server,
+                            std::move(proof_verifier), uri_template));
+
+  if (masque_client == nullptr) {
+    QUIC_LOG(ERROR) << "Failed to create masque_client";
+    return nullptr;
+  }
+
+  masque_client->set_initial_max_packet_length(kMasqueMaxOuterPacketSize);
+  masque_client->set_drop_response_body(false);
+  if (!masque_client->Initialize()) {
+    QUIC_LOG(ERROR) << "Failed to initialize masque_client";
+    return nullptr;
+  }
+  if (!masque_client->Connect()) {
+    QuicErrorCode error = masque_client->session()->error();
+    QUIC_LOG(ERROR) << "Failed to connect to " << host << ":" << port
+                    << ". Error: " << QuicErrorCodeToString(error);
+    return nullptr;
+  }
+
+  if (!masque_client->WaitUntilSettingsReceived()) {
+    QUIC_LOG(ERROR) << "Failed to receive settings";
+    return nullptr;
+  }
+
+  if (masque_client->masque_mode() == MasqueMode::kLegacy) {
+    // Construct the legacy mode init request.
+    spdy::Http2HeaderBlock header_block;
+    header_block[":method"] = "POST";
+    header_block[":scheme"] = "https";
+    header_block[":authority"] = masque_client->authority();
+    header_block[":path"] = "/.well-known/masque/init";
+    std::string body = "foo";
+
+    // Make sure to store the response, for later output.
+    masque_client->set_store_response(true);
+
+    // Send the MASQUE init command.
+    masque_client->SendRequestAndWaitForResponse(header_block, body,
+                                                 /*fin=*/true);
+
+    if (!masque_client->connected()) {
+      QUIC_LOG(ERROR)
+          << "MASQUE init request caused connection failure. Error: "
+          << QuicErrorCodeToString(masque_client->session()->error());
+      return nullptr;
+    }
+
+    const int response_code = masque_client->latest_response_code();
+    if (response_code != 200) {
+      QUIC_LOG(ERROR) << "MASQUE init request failed with HTTP response code "
+                      << response_code;
+      return nullptr;
+    }
+  }
+  return masque_client;
+}
+
+void MasqueEpollClient::OnSettingsReceived() {
+  settings_received_ = true;
+}
+
+bool MasqueEpollClient::WaitUntilSettingsReceived() {
+  while (connected() && !settings_received_) {
+    network_helper()->RunEventLoop();
+  }
+  return connected() && settings_received_;
+}
+
+void MasqueEpollClient::UnregisterClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  std::string body(client_connection_id.data(), client_connection_id.length());
+
+  // Construct a GET or POST request for supplied URL.
+  spdy::Http2HeaderBlock header_block;
+  header_block[":method"] = "POST";
+  header_block[":scheme"] = "https";
+  header_block[":authority"] = authority();
+  header_block[":path"] = "/.well-known/masque/unregister";
+
+  // Make sure to store the response, for later output.
+  set_store_response(true);
+
+  // Send the MASQUE unregister command.
+  SendRequest(header_block, body, /*fin=*/true);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_epoll_client.h b/quiche/quic/masque/masque_epoll_client.h
new file mode 100644
index 0000000..7b36bf6
--- /dev/null
+++ b/quiche/quic/masque/masque_epoll_client.h
@@ -0,0 +1,72 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
+
+#include <string>
+
+#include "quiche/quic/masque/masque_client_session.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/tools/quic_client.h"
+#include "quiche/quic/tools/quic_url.h"
+
+namespace quic {
+
+// QUIC client that implements MASQUE.
+class QUIC_NO_EXPORT MasqueEpollClient : public QuicClient,
+                                         public MasqueClientSession::Owner {
+ public:
+  // Constructs a MasqueEpollClient, performs a synchronous DNS lookup.
+  static std::unique_ptr<MasqueEpollClient> Create(
+      const std::string& uri_template, MasqueMode masque_mode,
+      QuicEpollServer* epoll_server,
+      std::unique_ptr<ProofVerifier> proof_verifier);
+
+  // From QuicClient.
+  std::unique_ptr<QuicSession> CreateQuicClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection) override;
+
+  // Client session for this client.
+  MasqueClientSession* masque_client_session();
+
+  // Convenience accessor for the underlying connection ID.
+  QuicConnectionId connection_id();
+
+  // From MasqueClientSession::Owner.
+  void OnSettingsReceived() override;
+  // Send a MASQUE client connection ID unregister command to the server.
+  void UnregisterClientConnectionId(
+      QuicConnectionId client_connection_id) override;
+
+  MasqueMode masque_mode() const { return masque_mode_; }
+
+ private:
+  // Constructor is private, use Create() instead.
+  MasqueEpollClient(QuicSocketAddress server_address,
+                    const QuicServerId& server_id, MasqueMode masque_mode,
+                    QuicEpollServer* epoll_server,
+                    std::unique_ptr<ProofVerifier> proof_verifier,
+                    const std::string& uri_template);
+
+  // Wait synchronously until we receive the peer's settings. Returns whether
+  // they were received.
+  bool WaitUntilSettingsReceived();
+
+  std::string authority() const;
+
+  // Disallow copy and assign.
+  MasqueEpollClient(const MasqueEpollClient&) = delete;
+  MasqueEpollClient& operator=(const MasqueEpollClient&) = delete;
+
+  MasqueMode masque_mode_;
+  std::string uri_template_;
+  bool settings_received_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_EPOLL_CLIENT_H_
diff --git a/quiche/quic/masque/masque_epoll_server.cc b/quiche/quic/masque/masque_epoll_server.cc
new file mode 100644
index 0000000..8399c71
--- /dev/null
+++ b/quiche/quic/masque/masque_epoll_server.cc
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_epoll_server.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/masque/masque_dispatcher.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_default_proof_providers.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+
+namespace quic {
+
+MasqueEpollServer::MasqueEpollServer(MasqueMode masque_mode,
+                                     MasqueServerBackend* masque_server_backend)
+    : QuicServer(CreateDefaultProofSource(),
+                 masque_server_backend,
+                 MasqueSupportedVersions()),
+      masque_mode_(masque_mode),
+      masque_server_backend_(masque_server_backend) {}
+
+QuicDispatcher* MasqueEpollServer::CreateQuicDispatcher() {
+  return new MasqueDispatcher(
+      masque_mode_, &config(), &crypto_config(), version_manager(),
+      epoll_server(),
+      std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
+                                                  QuicAllocator::BUFFER_POOL),
+      std::make_unique<QuicSimpleCryptoServerStreamHelper>(),
+      std::make_unique<QuicEpollAlarmFactory>(epoll_server()),
+      masque_server_backend_, expected_server_connection_id_length());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_epoll_server.h b/quiche/quic/masque/masque_epoll_server.h
new file mode 100644
index 0000000..588d0e7
--- /dev/null
+++ b/quiche/quic/masque/masque_epoll_server.h
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
+
+#include "quiche/quic/masque/masque_server_backend.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/tools/quic_server.h"
+
+namespace quic {
+
+// QUIC server that implements MASQUE.
+class QUIC_NO_EXPORT MasqueEpollServer : public QuicServer {
+ public:
+  explicit MasqueEpollServer(MasqueMode masque_mode,
+                             MasqueServerBackend* masque_server_backend);
+
+  // Disallow copy and assign.
+  MasqueEpollServer(const MasqueEpollServer&) = delete;
+  MasqueEpollServer& operator=(const MasqueEpollServer&) = delete;
+
+  // From QuicServer.
+  QuicDispatcher* CreateQuicDispatcher() override;
+
+ private:
+  MasqueMode masque_mode_;
+  MasqueServerBackend* masque_server_backend_;  // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_EPOLL_SERVER_H_
diff --git a/quiche/quic/masque/masque_server_backend.cc b/quiche/quic/masque/masque_server_backend.cc
new file mode 100644
index 0000000..193ba18
--- /dev/null
+++ b/quiche/quic/masque/masque_server_backend.cc
@@ -0,0 +1,137 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_server_backend.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+
+namespace quic {
+
+MasqueServerBackend::MasqueServerBackend(MasqueMode masque_mode,
+                                         const std::string& server_authority,
+                                         const std::string& cache_directory)
+    : masque_mode_(masque_mode), server_authority_(server_authority) {
+  if (!cache_directory.empty()) {
+    QuicMemoryCacheBackend::InitializeBackend(cache_directory);
+  }
+}
+
+bool MasqueServerBackend::MaybeHandleMasqueRequest(
+    const spdy::Http2HeaderBlock& request_headers,
+    const std::string& request_body,
+    QuicSimpleServerBackend::RequestHandler* request_handler) {
+  auto method_pair = request_headers.find(":method");
+  if (method_pair == request_headers.end()) {
+    // Request is missing a method.
+    return false;
+  }
+  absl::string_view method = method_pair->second;
+  std::string masque_path = "";
+  if (masque_mode_ == MasqueMode::kLegacy) {
+    auto path_pair = request_headers.find(":path");
+    auto scheme_pair = request_headers.find(":scheme");
+    if (path_pair == request_headers.end() ||
+        scheme_pair == request_headers.end()) {
+      // This request is missing required headers.
+      return false;
+    }
+    absl::string_view path = path_pair->second;
+    absl::string_view scheme = scheme_pair->second;
+    if (scheme != "https" || method != "POST" || request_body.empty()) {
+      // MASQUE requests MUST be a non-empty https POST.
+      return false;
+    }
+
+    if (path.rfind("/.well-known/masque/", 0) != 0) {
+      // This request is not a MASQUE path.
+      return false;
+    }
+    masque_path = std::string(path.substr(sizeof("/.well-known/masque/") - 1));
+  } else {
+    QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
+    auto protocol_pair = request_headers.find(":protocol");
+    if (method != "CONNECT" || protocol_pair == request_headers.end() ||
+        protocol_pair->second != "connect-udp") {
+      // This is not a MASQUE request.
+      return false;
+    }
+  }
+
+  if (!server_authority_.empty()) {
+    auto authority_pair = request_headers.find(":authority");
+    if (authority_pair == request_headers.end()) {
+      // Cannot enforce missing authority.
+      return false;
+    }
+    absl::string_view authority = authority_pair->second;
+    if (server_authority_ != authority) {
+      // This request does not match server_authority.
+      return false;
+    }
+  }
+
+  auto it = backend_client_states_.find(request_handler->connection_id());
+  if (it == backend_client_states_.end()) {
+    QUIC_LOG(ERROR) << "Could not find backend client for "
+                    << masque_path << request_headers.DebugString();
+    return false;
+  }
+
+  BackendClient* backend_client = it->second.backend_client;
+
+  std::unique_ptr<QuicBackendResponse> response =
+      backend_client->HandleMasqueRequest(masque_path, request_headers,
+                                          request_body, request_handler);
+  if (response == nullptr) {
+    QUIC_LOG(ERROR) << "Backend client did not process request for "
+                    << masque_path << request_headers.DebugString();
+    return false;
+  }
+
+  QUIC_DLOG(INFO) << "Sending MASQUE response for "
+                  << request_headers.DebugString();
+
+  request_handler->OnResponseBackendComplete(response.get());
+  it->second.responses.emplace_back(std::move(response));
+
+  return true;
+}
+
+void MasqueServerBackend::FetchResponseFromBackend(
+    const spdy::Http2HeaderBlock& request_headers,
+    const std::string& request_body,
+    QuicSimpleServerBackend::RequestHandler* request_handler) {
+  if (MaybeHandleMasqueRequest(request_headers, request_body,
+                               request_handler)) {
+    // Request was handled as a MASQUE request.
+    return;
+  }
+  QUIC_DLOG(INFO) << "Fetching non-MASQUE response for "
+                  << request_headers.DebugString();
+  QuicMemoryCacheBackend::FetchResponseFromBackend(
+      request_headers, request_body, request_handler);
+}
+
+void MasqueServerBackend::CloseBackendResponseStream(
+    QuicSimpleServerBackend::RequestHandler* request_handler) {
+  QUIC_DLOG(INFO) << "Closing response stream";
+  QuicMemoryCacheBackend::CloseBackendResponseStream(request_handler);
+}
+
+void MasqueServerBackend::RegisterBackendClient(QuicConnectionId connection_id,
+                                                BackendClient* backend_client) {
+  QUIC_DLOG(INFO) << "Registering backend client for " << connection_id;
+  QUIC_BUG_IF(quic_bug_12005_1, backend_client_states_.find(connection_id) !=
+                                    backend_client_states_.end())
+      << connection_id << " already in backend clients map";
+  backend_client_states_[connection_id] =
+      BackendClientState{backend_client, {}};
+}
+
+void MasqueServerBackend::RemoveBackendClient(QuicConnectionId connection_id) {
+  QUIC_DLOG(INFO) << "Removing backend client for " << connection_id;
+  backend_client_states_.erase(connection_id);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_server_backend.h b/quiche/quic/masque/masque_server_backend.h
new file mode 100644
index 0000000..482fa51
--- /dev/null
+++ b/quiche/quic/masque/masque_server_backend.h
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+
+namespace quic {
+
+// QUIC server backend that understands MASQUE requests, but otherwise answers
+// HTTP queries using an in-memory cache.
+class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend {
+ public:
+  // Interface meant to be implemented by the owner of the MasqueServerBackend
+  // instance.
+  class QUIC_NO_EXPORT BackendClient {
+   public:
+    virtual std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
+        const std::string& masque_path,
+        const spdy::Http2HeaderBlock& request_headers,
+        const std::string& request_body,
+        QuicSimpleServerBackend::RequestHandler* request_handler) = 0;
+    virtual ~BackendClient() = default;
+  };
+
+  explicit MasqueServerBackend(MasqueMode masque_mode,
+                               const std::string& server_authority,
+                               const std::string& cache_directory);
+
+  // Disallow copy and assign.
+  MasqueServerBackend(const MasqueServerBackend&) = delete;
+  MasqueServerBackend& operator=(const MasqueServerBackend&) = delete;
+
+  // From QuicMemoryCacheBackend.
+  void FetchResponseFromBackend(
+      const spdy::Http2HeaderBlock& request_headers,
+      const std::string& request_body,
+      QuicSimpleServerBackend::RequestHandler* request_handler) override;
+
+  void CloseBackendResponseStream(
+      QuicSimpleServerBackend::RequestHandler* request_handler) override;
+
+  // Register backend client that can handle MASQUE requests.
+  void RegisterBackendClient(QuicConnectionId connection_id,
+                             BackendClient* backend_client);
+
+  // Unregister backend client.
+  void RemoveBackendClient(QuicConnectionId connection_id);
+
+ private:
+  // Handle MASQUE request.
+  bool MaybeHandleMasqueRequest(
+      const spdy::Http2HeaderBlock& request_headers,
+      const std::string& request_body,
+      QuicSimpleServerBackend::RequestHandler* request_handler);
+
+  MasqueMode masque_mode_;
+  std::string server_authority_;
+
+  struct QUIC_NO_EXPORT BackendClientState {
+    BackendClient* backend_client;
+    std::vector<std::unique_ptr<QuicBackendResponse>> responses;
+  };
+  absl::
+      flat_hash_map<QuicConnectionId, BackendClientState, QuicConnectionIdHash>
+          backend_client_states_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_SERVER_BACKEND_H_
diff --git a/quiche/quic/masque/masque_server_bin.cc b/quiche/quic/masque/masque_server_bin.cc
new file mode 100644
index 0000000..ac1c189
--- /dev/null
+++ b/quiche/quic/masque/masque_server_bin.cc
@@ -0,0 +1,72 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is reponsible for the masque_server binary. It allows testing
+// our MASQUE server code by creating a MASQUE proxy that relays HTTP/3
+// requests to web servers tunnelled over MASQUE connections.
+// e.g.: masque_server
+
+#include <memory>
+
+#include "quiche/quic/masque/masque_epoll_server.h"
+#include "quiche/quic/masque/masque_server_backend.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_system_event_loop.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 9661,
+                                "The port the MASQUE server will listen on.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, cache_dir, "",
+    "Specifies the directory used during QuicHttpResponseCache "
+    "construction to seed the cache. Cache directory can be "
+    "generated using `wget -p --save-headers <url>`");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, server_authority, "",
+    "Specifies the authority over which the server will accept MASQUE "
+    "requests. Defaults to empty which allows all authorities.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
+                                "Allows setting MASQUE mode, valid values are "
+                                "open and legacy. Defaults to open.");
+
+int main(int argc, char* argv[]) {
+  quiche::QuicheSystemEventLoop event_loop("masque_server");
+  const char* usage = "Usage: masque_server [options]";
+  std::vector<std::string> non_option_args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (!non_option_args.empty()) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    return 0;
+  }
+
+  quic::MasqueMode masque_mode = quic::MasqueMode::kOpen;
+  std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
+  if (mode_string == "legacy") {
+    masque_mode = quic::MasqueMode::kLegacy;
+  } else if (!mode_string.empty() && mode_string != "open") {
+    std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
+    return 1;
+  }
+
+  auto backend = std::make_unique<quic::MasqueServerBackend>(
+      masque_mode, GetQuicFlag(FLAGS_server_authority),
+      GetQuicFlag(FLAGS_cache_dir));
+
+  auto server =
+      std::make_unique<quic::MasqueEpollServer>(masque_mode, backend.get());
+
+  if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
+          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
+    return 1;
+  }
+
+  std::cerr << "Started " << masque_mode << " MASQUE server" << std::endl;
+  server->HandleEventsForever();
+  return 0;
+}
diff --git a/quiche/quic/masque/masque_server_session.cc b/quiche/quic/masque/masque_server_session.cc
new file mode 100644
index 0000000..f221094
--- /dev/null
+++ b/quiche/quic/masque/masque_server_session.cc
@@ -0,0 +1,628 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_server_session.h"
+
+#include <netdb.h>
+
+#include <cstddef>
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/common/platform/api/quiche_url_utils.h"
+
+namespace quic {
+
+namespace {
+// RAII wrapper for QuicUdpSocketFd.
+class FdWrapper {
+ public:
+  // Takes ownership of |fd| and closes the file descriptor on destruction.
+  explicit FdWrapper(int address_family) {
+    QuicUdpSocketApi socket_api;
+    fd_ =
+        socket_api.Create(address_family,
+                          /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
+                          /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
+  }
+
+  ~FdWrapper() {
+    if (fd_ == kQuicInvalidSocketFd) {
+      return;
+    }
+    QuicUdpSocketApi socket_api;
+    socket_api.Destroy(fd_);
+  }
+
+  // Hands ownership of the file descriptor to the caller.
+  QuicUdpSocketFd extract_fd() {
+    QuicUdpSocketFd fd = fd_;
+    fd_ = kQuicInvalidSocketFd;
+    return fd;
+  }
+
+  // Keeps ownership of the file descriptor.
+  QuicUdpSocketFd fd() { return fd_; }
+
+  // Disallow copy and move.
+  FdWrapper(const FdWrapper&) = delete;
+  FdWrapper(FdWrapper&&) = delete;
+  FdWrapper& operator=(const FdWrapper&) = delete;
+  FdWrapper& operator=(FdWrapper&&) = delete;
+
+ private:
+  QuicUdpSocketFd fd_;
+};
+
+std::unique_ptr<QuicBackendResponse> CreateBackendErrorResponse(
+    absl::string_view status, absl::string_view error_details) {
+  spdy::Http2HeaderBlock response_headers;
+  response_headers[":status"] = status;
+  response_headers["masque-debug-info"] = error_details;
+  auto response = std::make_unique<QuicBackendResponse>();
+  response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
+  response->set_headers(std::move(response_headers));
+  return response;
+}
+
+}  // namespace
+
+MasqueServerSession::MasqueServerSession(
+    MasqueMode masque_mode, const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
+    QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    MasqueServerBackend* masque_server_backend)
+    : QuicSimpleServerSession(config, supported_versions, connection, visitor,
+                              helper, crypto_config, compressed_certs_cache,
+                              masque_server_backend),
+      masque_server_backend_(masque_server_backend),
+      owner_(owner),
+      epoll_server_(epoll_server),
+      compression_engine_(this),
+      masque_mode_(masque_mode) {
+  // Artificially increase the max packet length to 1350 to ensure we can fit
+  // QUIC packets inside DATAGRAM frames.
+  // TODO(b/181606597) Remove this workaround once we use PMTUD.
+  connection->SetMaxPacketLength(kDefaultMaxPacketSize);
+
+  masque_server_backend_->RegisterBackendClient(connection_id(), this);
+  QUICHE_DCHECK_NE(epoll_server_, nullptr);
+}
+
+void MasqueServerSession::OnMessageReceived(absl::string_view message) {
+  if (masque_mode_ == MasqueMode::kLegacy) {
+    QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
+    QuicConnectionId client_connection_id, server_connection_id;
+    QuicSocketAddress target_server_address;
+    std::vector<char> packet;
+    bool version_present;
+    if (!compression_engine_.DecompressDatagram(
+            message, &client_connection_id, &server_connection_id,
+            &target_server_address, &packet, &version_present)) {
+      return;
+    }
+
+    QUIC_DVLOG(1) << "Received packet of length " << packet.size() << " for "
+                  << target_server_address << " client "
+                  << client_connection_id;
+
+    if (version_present) {
+      if (client_connection_id.length() != kQuicDefaultConnectionIdLength) {
+        QUIC_DLOG(ERROR)
+            << "Dropping long header with invalid client_connection_id "
+            << client_connection_id;
+        return;
+      }
+      owner_->RegisterClientConnectionId(client_connection_id, this);
+    }
+
+    WriteResult write_result = connection()->writer()->WritePacket(
+        packet.data(), packet.size(), connection()->self_address().host(),
+        target_server_address, nullptr);
+    QUIC_DVLOG(1) << "Got " << write_result << " for " << packet.size()
+                  << " bytes to " << target_server_address;
+    return;
+  }
+  QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
+  QuicSpdySession::OnMessageReceived(message);
+}
+
+void MasqueServerSession::OnMessageAcked(QuicMessageId message_id,
+                                         QuicTime /*receive_timestamp*/) {
+  QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
+}
+
+void MasqueServerSession::OnMessageLost(QuicMessageId message_id) {
+  QUIC_DVLOG(1) << "We believe DATAGRAM frame " << message_id << " was lost";
+}
+
+void MasqueServerSession::OnConnectionClosed(
+    const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
+  QuicSimpleServerSession::OnConnectionClosed(frame, source);
+  QUIC_DLOG(INFO) << "Closing connection for " << connection_id();
+  masque_server_backend_->RemoveBackendClient(connection_id());
+  // Clearing this state will close all sockets.
+  connect_udp_server_states_.clear();
+}
+
+void MasqueServerSession::OnStreamClosed(QuicStreamId stream_id) {
+  connect_udp_server_states_.remove_if(
+      [stream_id](const ConnectUdpServerState& connect_udp) {
+        return connect_udp.stream()->id() == stream_id;
+      });
+
+  QuicSimpleServerSession::OnStreamClosed(stream_id);
+}
+
+std::unique_ptr<QuicBackendResponse> MasqueServerSession::HandleMasqueRequest(
+    const std::string& masque_path,
+    const spdy::Http2HeaderBlock& request_headers,
+    const std::string& request_body,
+    QuicSimpleServerBackend::RequestHandler* request_handler) {
+  if (masque_mode_ != MasqueMode::kLegacy) {
+    auto path_pair = request_headers.find(":path");
+    auto scheme_pair = request_headers.find(":scheme");
+    auto method_pair = request_headers.find(":method");
+    auto protocol_pair = request_headers.find(":protocol");
+    auto authority_pair = request_headers.find(":authority");
+    if (path_pair == request_headers.end()) {
+      QUIC_DLOG(ERROR) << "MASQUE request is missing :path";
+      return CreateBackendErrorResponse("400", "Missing :path");
+    }
+    if (scheme_pair == request_headers.end()) {
+      QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme";
+      return CreateBackendErrorResponse("400", "Missing :scheme");
+    }
+    if (method_pair == request_headers.end()) {
+      QUIC_DLOG(ERROR) << "MASQUE request is missing :method";
+      return CreateBackendErrorResponse("400", "Missing :method");
+    }
+    if (protocol_pair == request_headers.end()) {
+      QUIC_DLOG(ERROR) << "MASQUE request is missing :protocol";
+      return CreateBackendErrorResponse("400", "Missing :protocol");
+    }
+    if (authority_pair == request_headers.end()) {
+      QUIC_DLOG(ERROR) << "MASQUE request is missing :authority";
+      return CreateBackendErrorResponse("400", "Missing :authority");
+    }
+    absl::string_view path = path_pair->second;
+    absl::string_view scheme = scheme_pair->second;
+    absl::string_view method = method_pair->second;
+    absl::string_view protocol = protocol_pair->second;
+    absl::string_view authority = authority_pair->second;
+    if (path.empty()) {
+      QUIC_DLOG(ERROR) << "MASQUE request with empty path";
+      return CreateBackendErrorResponse("400", "Empty path");
+    }
+    if (scheme.empty()) {
+      return CreateBackendErrorResponse("400", "Empty scheme");
+    }
+    if (method != "CONNECT") {
+      QUIC_DLOG(ERROR) << "MASQUE request with bad method \"" << method << "\"";
+      return CreateBackendErrorResponse("400", "Bad method");
+    }
+    if (protocol != "connect-udp") {
+      QUIC_DLOG(ERROR) << "MASQUE request with bad protocol \"" << protocol
+                       << "\"";
+      return CreateBackendErrorResponse("400", "Bad protocol");
+    }
+    absl::optional<QuicDatagramStreamId> flow_id;
+    if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
+      flow_id = SpdyUtils::ParseDatagramFlowIdHeader(request_headers);
+      if (!flow_id.has_value()) {
+        QUIC_DLOG(ERROR)
+            << "MASQUE request with bad or missing DatagramFlowId header";
+        return CreateBackendErrorResponse(
+            "400", "Bad or missing DatagramFlowId header");
+      }
+    }
+    // Extract target host and port from path using default template.
+    std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
+    if (path_split.size() != 4 || !path_split[0].empty() ||
+        path_split[1].empty() || path_split[2].empty() ||
+        !path_split[3].empty()) {
+      QUIC_DLOG(ERROR) << "MASQUE request with bad path \"" << path << "\"";
+      return CreateBackendErrorResponse("400", "Bad path");
+    }
+    absl::optional<std::string> host = quiche::AsciiUrlDecode(path_split[1]);
+    if (!host.has_value()) {
+      QUIC_DLOG(ERROR) << "Failed to decode host \"" << path_split[1] << "\"";
+      return CreateBackendErrorResponse("500", "Failed to decode host");
+    }
+    absl::optional<std::string> port = quiche::AsciiUrlDecode(path_split[2]);
+    if (!port.has_value()) {
+      QUIC_DLOG(ERROR) << "Failed to decode port \"" << path_split[2] << "\"";
+      return CreateBackendErrorResponse("500", "Failed to decode port");
+    }
+
+    // Perform DNS resolution.
+    addrinfo hint = {};
+    hint.ai_protocol = IPPROTO_UDP;
+
+    addrinfo* info_list = nullptr;
+    int result = getaddrinfo(host.value().c_str(), port.value().c_str(), &hint,
+                             &info_list);
+    if (result != 0) {
+      QUIC_DLOG(ERROR) << "Failed to resolve " << authority << ": "
+                       << gai_strerror(result);
+      return CreateBackendErrorResponse("500", "DNS resolution failed");
+    }
+
+    QUICHE_CHECK_NE(info_list, nullptr);
+    std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(
+        info_list, freeaddrinfo);
+    QuicSocketAddress target_server_address(info_list->ai_addr,
+                                            info_list->ai_addrlen);
+    QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
+                    << request_handler->stream_id() << " flow_id="
+                    << (flow_id.has_value() ? absl::StrCat(*flow_id) : "none")
+                    << " target_server_address=\"" << target_server_address
+                    << "\"";
+
+    FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
+    if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
+      QUIC_DLOG(ERROR) << "Socket creation failed";
+      return CreateBackendErrorResponse("500", "Socket creation failed");
+    }
+    QuicSocketAddress empty_address(QuicIpAddress::Any6(), 0);
+    if (target_server_address.host().IsIPv4()) {
+      empty_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
+    }
+    QuicUdpSocketApi socket_api;
+    if (!socket_api.Bind(fd_wrapper.fd(), empty_address)) {
+      QUIC_DLOG(ERROR) << "Socket bind failed";
+      return CreateBackendErrorResponse("500", "Socket bind failed");
+    }
+    epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
+
+    absl::optional<QuicDatagramContextId> context_id;
+    QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
+        GetActiveStream(request_handler->stream_id()));
+    if (stream == nullptr) {
+      QUIC_BUG(bad masque server stream type)
+          << "Unexpected stream type for stream ID "
+          << request_handler->stream_id();
+      return CreateBackendErrorResponse("500", "Bad stream type");
+    }
+    if (flow_id.has_value()) {
+      stream->RegisterHttp3DatagramFlowId(*flow_id);
+    }
+    connect_udp_server_states_.push_back(
+        ConnectUdpServerState(stream, context_id, target_server_address,
+                              fd_wrapper.extract_fd(), this));
+
+    if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
+      // TODO(b/181256914) remove this when we drop support for
+      // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
+      stream->RegisterHttp3DatagramContextId(
+          context_id, DatagramFormatType::UDP_PAYLOAD,
+          /*format_additional_data=*/absl::string_view(),
+          &connect_udp_server_states_.back());
+    }
+
+    spdy::Http2HeaderBlock response_headers;
+    response_headers[":status"] = "200";
+    if (flow_id.has_value()) {
+      SpdyUtils::AddDatagramFlowIdHeader(&response_headers, *flow_id);
+    }
+    auto response = std::make_unique<QuicBackendResponse>();
+    response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
+    response->set_headers(std::move(response_headers));
+    response->set_body("");
+
+    return response;
+  }
+
+  QUIC_DLOG(INFO) << "MasqueServerSession handling MASQUE request";
+
+  if (masque_path == "init") {
+    if (masque_initialized_) {
+      QUIC_DLOG(ERROR) << "Got second MASQUE init request";
+      return nullptr;
+    }
+    masque_initialized_ = true;
+  } else if (masque_path == "unregister") {
+    QuicConnectionId connection_id(request_body.data(), request_body.length());
+    QUIC_DLOG(INFO) << "Received MASQUE request to unregister "
+                    << connection_id;
+    owner_->UnregisterClientConnectionId(connection_id);
+    compression_engine_.UnregisterClientConnectionId(connection_id);
+  } else {
+    if (!masque_initialized_) {
+      QUIC_DLOG(ERROR) << "Got MASQUE request before init";
+      return nullptr;
+    }
+  }
+
+  // TODO(dschinazi) implement binary protocol sent in response body.
+  const std::string response_body = "";
+  spdy::Http2HeaderBlock response_headers;
+  response_headers[":status"] = "200";
+  auto response = std::make_unique<QuicBackendResponse>();
+  response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
+  response->set_headers(std::move(response_headers));
+  response->set_body(response_body);
+
+  return response;
+}
+
+void MasqueServerSession::HandlePacketFromServer(
+    const ReceivedPacketInfo& packet_info) {
+  QUIC_DVLOG(1) << "MasqueServerSession received " << packet_info;
+  if (masque_mode_ == MasqueMode::kLegacy) {
+    compression_engine_.CompressAndSendPacket(
+        packet_info.packet.AsStringPiece(),
+        packet_info.destination_connection_id, packet_info.source_connection_id,
+        packet_info.peer_address);
+    return;
+  }
+  QUIC_LOG(ERROR) << "Ignoring packet from server in " << masque_mode_
+                  << " mode";
+}
+
+void MasqueServerSession::OnRegistration(QuicEpollServer* /*eps*/,
+                                         QuicUdpSocketFd fd, int event_mask) {
+  QUIC_DVLOG(1) << "OnRegistration " << fd << " event_mask " << event_mask;
+}
+
+void MasqueServerSession::OnModification(QuicUdpSocketFd fd, int event_mask) {
+  QUIC_DVLOG(1) << "OnModification " << fd << " event_mask " << event_mask;
+}
+
+void MasqueServerSession::OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) {
+  if ((event->in_events & EPOLLIN) == 0) {
+    QUIC_DVLOG(1) << "Ignoring OnEvent fd " << fd << " event mask "
+                  << event->in_events;
+    return;
+  }
+  auto it = absl::c_find_if(connect_udp_server_states_,
+                            [fd](const ConnectUdpServerState& connect_udp) {
+                              return connect_udp.fd() == fd;
+                            });
+  if (it == connect_udp_server_states_.end()) {
+    QUIC_BUG(quic_bug_10974_1) << "Got unexpected event mask "
+                               << event->in_events << " on unknown fd " << fd;
+    return;
+  }
+  QuicSocketAddress expected_target_server_address =
+      it->target_server_address();
+  QUICHE_DCHECK(expected_target_server_address.IsInitialized());
+  QUIC_DVLOG(1) << "Received readable event on fd " << fd << " (mask "
+                << event->in_events << ") stream ID " << it->stream()->id()
+                << " server " << expected_target_server_address;
+  QuicUdpSocketApi socket_api;
+  BitMask64 packet_info_interested(QuicUdpPacketInfoBit::PEER_ADDRESS);
+  char packet_buffer[kMaxIncomingPacketSize];
+  char control_buffer[kDefaultUdpPacketControlBufferSize];
+  while (true) {
+    QuicUdpSocketApi::ReadPacketResult read_result;
+    read_result.packet_buffer = {packet_buffer, sizeof(packet_buffer)};
+    read_result.control_buffer = {control_buffer, sizeof(control_buffer)};
+    socket_api.ReadPacket(fd, packet_info_interested, &read_result);
+    if (!read_result.ok) {
+      // Most likely there is nothing left to read, break out of read loop.
+      break;
+    }
+    if (!read_result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
+      QUIC_BUG(quic_bug_10974_2)
+          << "Missing peer address when reading from fd " << fd;
+      continue;
+    }
+    if (read_result.packet_info.peer_address() !=
+        expected_target_server_address) {
+      QUIC_DLOG(ERROR) << "Ignoring UDP packet on fd " << fd
+                       << " from unexpected server address "
+                       << read_result.packet_info.peer_address()
+                       << " (expected " << expected_target_server_address
+                       << ")";
+      continue;
+    }
+    if (!connection()->connected()) {
+      QUIC_BUG(quic_bug_10974_3)
+          << "Unexpected incoming UDP packet on fd " << fd << " from "
+          << expected_target_server_address
+          << " because MASQUE connection is closed";
+      return;
+    }
+    // The packet is valid, send it to the client in a DATAGRAM frame.
+    MessageStatus message_status = it->stream()->SendHttp3Datagram(
+        it->context_id(),
+        absl::string_view(read_result.packet_buffer.buffer,
+                          read_result.packet_buffer.buffer_len));
+    QUIC_DVLOG(1) << "Sent UDP packet from " << expected_target_server_address
+                  << " of length " << read_result.packet_buffer.buffer_len
+                  << " with stream ID " << it->stream()->id()
+                  << " and got message status "
+                  << MessageStatusToString(message_status);
+  }
+}
+
+void MasqueServerSession::OnUnregistration(QuicUdpSocketFd fd, bool replaced) {
+  QUIC_DVLOG(1) << "OnUnregistration " << fd << " " << (replaced ? "" : "!")
+                << " replaced";
+}
+
+void MasqueServerSession::OnShutdown(QuicEpollServer* /*eps*/,
+                                     QuicUdpSocketFd fd) {
+  QUIC_DVLOG(1) << "OnShutdown " << fd;
+}
+
+std::string MasqueServerSession::Name() const {
+  return std::string("MasqueServerSession-") + connection_id().ToString();
+}
+
+bool MasqueServerSession::OnSettingsFrame(const SettingsFrame& frame) {
+  QUIC_DLOG(INFO) << "Received SETTINGS: " << frame;
+  if (!QuicSimpleServerSession::OnSettingsFrame(frame)) {
+    return false;
+  }
+  if (!SupportsH3Datagram()) {
+    QUIC_DLOG(ERROR) << "Refusing to use MASQUE without HTTP Datagrams";
+    return false;
+  }
+  QUIC_DLOG(INFO) << "Using HTTP Datagram: " << http_datagram_support();
+  return true;
+}
+
+MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
+    QuicSpdyStream* stream, absl::optional<QuicDatagramContextId> context_id,
+    const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
+    MasqueServerSession* masque_session)
+    : stream_(stream),
+      context_id_(context_id),
+      target_server_address_(target_server_address),
+      fd_(fd),
+      masque_session_(masque_session) {
+  QUICHE_DCHECK_NE(fd_, kQuicInvalidSocketFd);
+  QUICHE_DCHECK_NE(masque_session_, nullptr);
+  this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
+}
+
+MasqueServerSession::ConnectUdpServerState::~ConnectUdpServerState() {
+  if (stream() != nullptr) {
+    if (context_registered_) {
+      stream()->UnregisterHttp3DatagramContextId(context_id());
+    }
+    stream()->UnregisterHttp3DatagramRegistrationVisitor();
+  }
+  if (fd_ == kQuicInvalidSocketFd) {
+    return;
+  }
+  QuicUdpSocketApi socket_api;
+  QUIC_DLOG(INFO) << "Closing fd " << fd_;
+  masque_session_->epoll_server()->UnregisterFD(fd_);
+  socket_api.Destroy(fd_);
+}
+
+MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
+    MasqueServerSession::ConnectUdpServerState&& other) {
+  fd_ = kQuicInvalidSocketFd;
+  *this = std::move(other);
+}
+
+MasqueServerSession::ConnectUdpServerState&
+MasqueServerSession::ConnectUdpServerState::operator=(
+    MasqueServerSession::ConnectUdpServerState&& other) {
+  if (fd_ != kQuicInvalidSocketFd) {
+    QuicUdpSocketApi socket_api;
+    QUIC_DLOG(INFO) << "Closing fd " << fd_;
+    masque_session_->epoll_server()->UnregisterFD(fd_);
+    socket_api.Destroy(fd_);
+  }
+  stream_ = other.stream_;
+  other.stream_ = nullptr;
+  context_id_ = other.context_id_;
+  target_server_address_ = other.target_server_address_;
+  fd_ = other.fd_;
+  masque_session_ = other.masque_session_;
+  other.fd_ = kQuicInvalidSocketFd;
+  context_registered_ = other.context_registered_;
+  other.context_registered_ = false;
+  if (stream() != nullptr) {
+    stream()->MoveHttp3DatagramRegistration(this);
+    if (context_registered_) {
+      stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
+    }
+  }
+  return *this;
+}
+
+void MasqueServerSession::ConnectUdpServerState::OnHttp3Datagram(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    absl::string_view payload) {
+  QUICHE_DCHECK_EQ(stream_id, stream()->id());
+  QUICHE_DCHECK(context_id == context_id_);
+  QuicUdpSocketApi socket_api;
+  QuicUdpPacketInfo packet_info;
+  packet_info.SetPeerAddress(target_server_address_);
+  WriteResult write_result = socket_api.WritePacket(
+      fd_, payload.data(), payload.length(), packet_info);
+  QUIC_DVLOG(1) << "Wrote packet of length " << payload.length() << " to "
+                << target_server_address_ << " with result " << write_result;
+}
+
+void MasqueServerSession::ConnectUdpServerState::OnContextReceived(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    DatagramFormatType format_type, absl::string_view format_additional_data) {
+  if (stream_id != stream()->id()) {
+    QUIC_BUG(MASQUE server bad datagram context registration)
+        << "Registered stream ID " << stream_id << ", expected "
+        << stream()->id();
+    return;
+  }
+  if (format_type != DatagramFormatType::UDP_PAYLOAD) {
+    QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
+                    << DatagramFormatTypeToString(format_type);
+    return;
+  }
+  if (!format_additional_data.empty()) {
+    QUIC_DLOG(ERROR)
+        << "Received non-empty format additional data for context ID "
+        << (context_id_.has_value() ? context_id_.value() : 0)
+        << " on stream ID " << stream()->id();
+    masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
+    return;
+  }
+  if (!context_received_) {
+    context_received_ = true;
+    context_id_ = context_id;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO)
+        << "Ignoring unexpected context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " instead of "
+        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
+                                    : "none")
+        << " on stream ID " << stream()->id();
+    return;
+  }
+  if (context_registered_) {
+    QUIC_BUG(MASQUE server double datagram context registration)
+        << "Try to re-register stream ID " << stream_id << " context ID "
+        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
+                                    : "none");
+    return;
+  }
+  context_registered_ = true;
+  stream()->RegisterHttp3DatagramContextId(context_id_, format_type,
+                                           format_additional_data, this);
+}
+
+void MasqueServerSession::ConnectUdpServerState::OnContextClosed(
+    QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
+    ContextCloseCode close_code, absl::string_view close_details) {
+  if (stream_id != stream()->id()) {
+    QUIC_BUG(MASQUE server bad datagram context registration)
+        << "Closed context on stream ID " << stream_id << ", expected "
+        << stream()->id();
+    return;
+  }
+  if (context_id != context_id_) {
+    QUIC_DLOG(INFO)
+        << "Ignoring unexpected close of context ID "
+        << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
+        << " instead of "
+        << (context_id_.has_value() ? absl::StrCat(context_id_.value())
+                                    : "none")
+        << " on stream ID " << stream()->id();
+    return;
+  }
+  QUIC_DLOG(INFO) << "Received datagram context close with close code "
+                  << close_code << " close details \"" << close_details
+                  << "\" on stream ID " << stream()->id() << ", closing stream";
+  masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_server_session.h b/quiche/quic/masque/masque_server_session.h
new file mode 100644
index 0000000..746779e
--- /dev/null
+++ b/quiche/quic/masque/masque_server_session.h
@@ -0,0 +1,156 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/masque/masque_compression_engine.h"
+#include "quiche/quic/masque/masque_server_backend.h"
+#include "quiche/quic/masque/masque_utils.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/tools/quic_simple_server_session.h"
+
+namespace quic {
+
+// QUIC server session for connection to MASQUE proxy.
+class QUIC_NO_EXPORT MasqueServerSession
+    : public QuicSimpleServerSession,
+      public MasqueServerBackend::BackendClient,
+      public QuicEpollCallbackInterface {
+ public:
+  // Interface meant to be implemented by owner of this MasqueServerSession
+  // instance.
+  class QUIC_NO_EXPORT Visitor {
+   public:
+    virtual ~Visitor() {}
+    // Register a client connection ID as being handled by this session.
+    virtual void RegisterClientConnectionId(
+        QuicConnectionId client_connection_id,
+        MasqueServerSession* masque_server_session) = 0;
+
+    // Unregister a client connection ID.
+    virtual void UnregisterClientConnectionId(
+        QuicConnectionId client_connection_id) = 0;
+  };
+
+  explicit MasqueServerSession(
+      MasqueMode masque_mode, const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
+      QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      MasqueServerBackend* masque_server_backend);
+
+  // Disallow copy and assign.
+  MasqueServerSession(const MasqueServerSession&) = delete;
+  MasqueServerSession& operator=(const MasqueServerSession&) = delete;
+
+  // From QuicSession.
+  void OnMessageReceived(absl::string_view message) override;
+  void OnMessageAcked(QuicMessageId message_id,
+                      QuicTime receive_timestamp) override;
+  void OnMessageLost(QuicMessageId message_id) override;
+  void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                          ConnectionCloseSource source) override;
+  void OnStreamClosed(QuicStreamId stream_id) override;
+
+  // From MasqueServerBackend::BackendClient.
+  std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
+      const std::string& masque_path,
+      const spdy::Http2HeaderBlock& request_headers,
+      const std::string& request_body,
+      QuicSimpleServerBackend::RequestHandler* request_handler) override;
+
+  // From QuicEpollCallbackInterface.
+  void OnRegistration(QuicEpollServer* eps, QuicUdpSocketFd fd,
+                      int event_mask) override;
+  void OnModification(QuicUdpSocketFd fd, int event_mask) override;
+  void OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) override;
+  void OnUnregistration(QuicUdpSocketFd fd, bool replaced) override;
+  void OnShutdown(QuicEpollServer* eps, QuicUdpSocketFd fd) override;
+  std::string Name() const override;
+
+  // Handle packet for client, meant to be called by MasqueDispatcher.
+  void HandlePacketFromServer(const ReceivedPacketInfo& packet_info);
+
+  QuicEpollServer* epoll_server() const { return epoll_server_; }
+
+ private:
+  // State that the MasqueServerSession keeps for each CONNECT-UDP request.
+  class QUIC_NO_EXPORT ConnectUdpServerState
+      : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
+        public QuicSpdyStream::Http3DatagramVisitor {
+   public:
+    // ConnectUdpServerState takes ownership of |fd|. It will unregister it
+    // from |epoll_server| and close the file descriptor when destructed.
+    explicit ConnectUdpServerState(
+        QuicSpdyStream* stream,
+        absl::optional<QuicDatagramContextId> context_id,
+        const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
+        MasqueServerSession* masque_session);
+
+    ~ConnectUdpServerState();
+
+    // Disallow copy but allow move.
+    ConnectUdpServerState(const ConnectUdpServerState&) = delete;
+    ConnectUdpServerState(ConnectUdpServerState&&);
+    ConnectUdpServerState& operator=(const ConnectUdpServerState&) = delete;
+    ConnectUdpServerState& operator=(ConnectUdpServerState&&);
+
+    QuicSpdyStream* stream() const { return stream_; }
+    absl::optional<QuicDatagramContextId> context_id() const {
+      return context_id_;
+    }
+    const QuicSocketAddress& target_server_address() const {
+      return target_server_address_;
+    }
+    QuicUdpSocketFd fd() const { return fd_; }
+
+    // From QuicSpdyStream::Http3DatagramVisitor.
+    void OnHttp3Datagram(QuicStreamId stream_id,
+                         absl::optional<QuicDatagramContextId> context_id,
+                         absl::string_view payload) override;
+
+    // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
+    void OnContextReceived(QuicStreamId stream_id,
+                           absl::optional<QuicDatagramContextId> context_id,
+                           DatagramFormatType format_type,
+                           absl::string_view format_additional_data) override;
+    void OnContextClosed(QuicStreamId stream_id,
+                         absl::optional<QuicDatagramContextId> context_id,
+                         ContextCloseCode close_code,
+                         absl::string_view close_details) override;
+
+   private:
+    QuicSpdyStream* stream_;
+    absl::optional<QuicDatagramContextId> context_id_;
+    QuicSocketAddress target_server_address_;
+    QuicUdpSocketFd fd_;                   // Owned.
+    MasqueServerSession* masque_session_;  // Unowned.
+    bool context_received_ = false;
+    bool context_registered_ = false;
+  };
+
+  // From QuicSpdySession.
+  bool OnSettingsFrame(const SettingsFrame& frame) override;
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    return HttpDatagramSupport::kDraft00And04;
+  }
+
+  MasqueServerBackend* masque_server_backend_;  // Unowned.
+  Visitor* owner_;                              // Unowned.
+  QuicEpollServer* epoll_server_;               // Unowned.
+  MasqueCompressionEngine compression_engine_;
+  MasqueMode masque_mode_;
+  std::list<ConnectUdpServerState> connect_udp_server_states_;
+  bool masque_initialized_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_SERVER_SESSION_H_
diff --git a/quiche/quic/masque/masque_utils.cc b/quiche/quic/masque/masque_utils.cc
new file mode 100644
index 0000000..b440bd1
--- /dev/null
+++ b/quiche/quic/masque/masque_utils.cc
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/masque/masque_utils.h"
+
+namespace quic {
+
+ParsedQuicVersionVector MasqueSupportedVersions() {
+  QuicVersionInitializeSupportForIetfDraft();
+  ParsedQuicVersionVector versions;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    // Use all versions that support IETF QUIC.
+    if (version.UsesHttp3()) {
+      QuicEnableVersion(version);
+      versions.push_back(version);
+    }
+  }
+  QUICHE_CHECK(!versions.empty());
+  return versions;
+}
+
+QuicConfig MasqueEncapsulatedConfig() {
+  QuicConfig config;
+  config.SetMaxPacketSizeToSend(kMasqueMaxEncapsulatedPacketSize);
+  return config;
+}
+
+std::string MasqueModeToString(MasqueMode masque_mode) {
+  switch (masque_mode) {
+    case MasqueMode::kInvalid:
+      return "Invalid";
+    case MasqueMode::kLegacy:
+      return "Legacy";
+    case MasqueMode::kOpen:
+      return "Open";
+  }
+  return absl::StrCat("Unknown(", static_cast<int>(masque_mode), ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const MasqueMode& masque_mode) {
+  os << MasqueModeToString(masque_mode);
+  return os;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/masque/masque_utils.h b/quiche/quic/masque/masque_utils.h
new file mode 100644
index 0000000..652bf35
--- /dev/null
+++ b/quiche/quic/masque/masque_utils.h
@@ -0,0 +1,45 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
+#define QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
+
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+
+namespace quic {
+
+// List of QUIC versions that support MASQUE. Currently restricted to IETF QUIC.
+QUIC_NO_EXPORT ParsedQuicVersionVector MasqueSupportedVersions();
+
+// Default QuicConfig for use with MASQUE. Sets a custom max_packet_size.
+QUIC_NO_EXPORT QuicConfig MasqueEncapsulatedConfig();
+
+// Maximum packet size for encapsulated connections.
+enum : QuicByteCount {
+  kMasqueMaxEncapsulatedPacketSize = 1300,
+  kMasqueMaxOuterPacketSize = 1350,
+};
+
+// Mode that MASQUE is operating in.
+enum class MasqueMode : uint8_t {
+  kInvalid = 0,  // Should never be used.
+  kLegacy = 1,   // Legacy mode uses the legacy MASQUE protocol as documented in
+  // <https://tools.ietf.org/html/draft-schinazi-masque-protocol>. That version
+  // of MASQUE uses a custom application-protocol over HTTP/3, and also allows
+  // unauthenticated clients.
+  kOpen = 2,  // Open mode uses the MASQUE HTTP CONNECT-UDP method as documented
+  // in <https://tools.ietf.org/html/draft-ietf-masque-connect-udp>. This mode
+  // allows unauthenticated clients (a more restricted mode will be added to
+  // this enum at a later date).
+};
+
+QUIC_NO_EXPORT std::string MasqueModeToString(MasqueMode masque_mode);
+QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
+                                        const MasqueMode& masque_mode);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_MASQUE_MASQUE_UTILS_H_
diff --git a/quic/platform/README.md b/quiche/quic/platform/README.md
similarity index 100%
rename from quic/platform/README.md
rename to quiche/quic/platform/README.md
diff --git a/quic/platform/api/README.md b/quiche/quic/platform/api/README.md
similarity index 100%
rename from quic/platform/api/README.md
rename to quiche/quic/platform/api/README.md
diff --git a/quiche/quic/platform/api/quic_bug_tracker.h b/quiche/quic/platform/api/quic_bug_tracker.h
new file mode 100644
index 0000000..f84d220
--- /dev/null
+++ b/quiche/quic/platform/api/quic_bug_tracker.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
+
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+
+#define QUIC_BUG QUICHE_BUG
+#define QUIC_BUG_IF QUICHE_BUG_IF
+#define QUIC_PEER_BUG QUICHE_PEER_BUG
+#define QUIC_PEER_BUG_IF QUICHE_PEER_BUG_IF
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_
diff --git a/quiche/quic/platform/api/quic_client_stats.h b/quiche/quic/platform/api/quic_client_stats.h
new file mode 100644
index 0000000..d18d614
--- /dev/null
+++ b/quiche/quic/platform/api/quic_client_stats.h
@@ -0,0 +1,87 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
+
+#include <string>
+
+#include "quiche/common/platform/api/quiche_client_stats.h"
+
+namespace quic {
+
+//------------------------------------------------------------------------------
+// Enumeration histograms.
+//
+// Sample usage:
+//   // In Chrome, these values are persisted to logs. Entries should not be
+//   // renumbered and numeric values should never be reused.
+//   enum class MyEnum {
+//     FIRST_VALUE = 0,
+//     SECOND_VALUE = 1,
+//     ...
+//     FINAL_VALUE = N,
+//     COUNT
+//   };
+//   QUIC_CLIENT_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE,
+//   MyEnum::COUNT, "Number of time $foo equals to some enum value");
+//
+// Note: The value in |sample| must be strictly less than |enum_size|.
+
+#define QUIC_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
+  QUICHE_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring)
+
+//------------------------------------------------------------------------------
+// Histogram for boolean values.
+
+// Sample usage:
+//   QUIC_CLIENT_HISTOGRAM_BOOL("My.Boolean", bool,
+//   "Number of times $foo is true or false");
+#define QUIC_CLIENT_HISTOGRAM_BOOL(name, sample, docstring) \
+  QUICHE_CLIENT_HISTOGRAM_BOOL(name, sample, docstring)
+
+//------------------------------------------------------------------------------
+// Timing histograms. These are used for collecting timing data (generally
+// latencies).
+
+// These macros create exponentially sized histograms (lengths of the bucket
+// ranges exponentially increase as the sample range increases). The units for
+// sample and max are unspecified, but they must be the same for one histogram.
+
+// Sample usage:
+//   QUIC_CLIENT_HISTOGRAM_TIMES("Very.Long.Timing.Histogram", time_delta,
+//       QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
+//       24), 100, "Time spent in doing operation.");
+#define QUIC_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
+                                    docstring)                            \
+  QUICHE_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring)
+
+//------------------------------------------------------------------------------
+// Count histograms. These are used for collecting numeric data.
+
+// These macros default to exponential histograms - i.e. the lengths of the
+// bucket ranges exponentially increase as the sample range increases.
+
+// All of these macros must be called with |name| as a runtime constant.
+
+// Any data outside the range here will be put in underflow and overflow
+// buckets. Min values should be >=1 as emitted 0s will still go into the
+// underflow bucket.
+
+// Sample usage:
+//   UMA_CLIENT_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100,
+//      "Counters of hitting certian code.");
+
+#define QUIC_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
+                                     docstring)                            \
+  QUICHE_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,     \
+                                 docstring)
+
+inline void QuicClientSparseHistogram(const std::string& name, int sample) {
+  quiche::QuicheClientSparseHistogram(name, sample);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_CLIENT_STATS_H_
diff --git a/quiche/quic/platform/api/quic_containers.h b/quiche/quic/platform/api/quic_containers.h
new file mode 100644
index 0000000..9420393
--- /dev/null
+++ b/quiche/quic/platform/api/quic_containers.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
+
+#include "quiche/common/platform/api/quiche_containers.h"
+
+namespace quic {
+
+// An ordered container optimized for small sets.
+// An implementation with O(n) mutations might be chosen
+// in case it has better memory usage and/or faster access.
+//
+// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
+template <typename Key, typename Compare = std::less<Key>>
+using QuicSmallOrderedSet = ::quiche::QuicheSmallOrderedSet<Key, Compare>;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
diff --git a/quiche/quic/platform/api/quic_default_proof_providers.h b/quiche/quic/platform/api/quic_default_proof_providers.h
new file mode 100644
index 0000000..59d9052
--- /dev/null
+++ b/quiche/quic/platform/api/quic_default_proof_providers.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
+
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/common/platform/api/quiche_default_proof_providers.h"
+
+namespace quic {
+
+// Provides a default proof verifier that can verify a cert chain for |host|.
+// The verifier has to do a good faith attempt at verifying the certificate
+// against a reasonable root store, and not just always return success.
+inline std::unique_ptr<ProofVerifier> CreateDefaultProofVerifier(
+    const std::string& host) {
+  return quiche::CreateDefaultProofVerifier(host);
+}
+
+// Provides a default proof source for CLI-based tools.  The actual certificates
+// used in the proof source should be confifgurable via command-line flags.
+inline std::unique_ptr<ProofSource> CreateDefaultProofSource() {
+  return quiche::CreateDefaultProofSource();
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/quiche/quic/platform/api/quic_epoll.h b/quiche/quic/platform/api/quic_epoll.h
new file mode 100644
index 0000000..58aa780
--- /dev/null
+++ b/quiche/quic/platform/api/quic_epoll.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
+
+#include "quiche/common/platform/api/quiche_epoll.h"
+
+namespace quic {
+
+using QuicEpollServer = quiche::QuicheEpollServer;
+using QuicEpollEvent = quiche::QuicheEpollEvent;
+using QuicEpollAlarmBase = quiche::QuicheEpollAlarmBase;
+using QuicEpollCallbackInterface = quiche::QuicheEpollCallbackInterface;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_EPOLL_H_
diff --git a/quiche/quic/platform/api/quic_expect_bug.h b/quiche/quic/platform/api/quic_expect_bug.h
new file mode 100644
index 0000000..02ba38a
--- /dev/null
+++ b/quiche/quic/platform/api/quic_expect_bug.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
+
+#include "quiche/common/platform/api/quiche_expect_bug.h"
+
+#define EXPECT_QUIC_BUG EXPECT_QUICHE_BUG
+#define EXPECT_QUIC_PEER_BUG(statement, regex) \
+  EXPECT_QUICHE_PEER_BUG(statement, regex)
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_EXPECT_BUG_H_
diff --git a/quic/platform/api/quic_export.h b/quiche/quic/platform/api/quic_export.h
similarity index 100%
rename from quic/platform/api/quic_export.h
rename to quiche/quic/platform/api/quic_export.h
diff --git a/quiche/quic/platform/api/quic_exported_stats.h b/quiche/quic/platform/api/quic_exported_stats.h
new file mode 100644
index 0000000..3e7f4a7
--- /dev/null
+++ b/quiche/quic/platform/api/quic_exported_stats.h
@@ -0,0 +1,96 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
+
+#include "quiche/quic/platform/api/quic_client_stats.h"
+#include "quiche/quic/platform/api/quic_server_stats.h"
+
+namespace quic {
+
+// TODO(wub): Add support for counters. Only histograms are supported for now.
+
+//------------------------------------------------------------------------------
+// Enumeration histograms.
+//
+// Sample usage:
+//   // In Chrome, these values are persisted to logs. Entries should not be
+//   // renumbered and numeric values should never be reused.
+//   enum class MyEnum {
+//     FIRST_VALUE = 0,
+//     SECOND_VALUE = 1,
+//     ...
+//     FINAL_VALUE = N,
+//     COUNT
+//   };
+//   QUIC_HISTOGRAM_ENUM("My.Enumeration", MyEnum::SOME_VALUE, MyEnum::COUNT,
+//                       "Number of time $foo equals to some enum value");
+//
+// Note: The value in |sample| must be strictly less than |enum_size|.
+
+#define QUIC_HISTOGRAM_ENUM(name, sample, enum_size, docstring)     \
+  do {                                                              \
+    QUIC_CLIENT_HISTOGRAM_ENUM(name, sample, enum_size, docstring); \
+    QUIC_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring); \
+  } while (0)
+
+//------------------------------------------------------------------------------
+// Histogram for boolean values.
+
+// Sample usage:
+//   QUIC_HISTOGRAM_BOOL("My.Boolean", bool,
+//                       "Number of times $foo is true or false");
+#define QUIC_HISTOGRAM_BOOL(name, sample, docstring)     \
+  do {                                                   \
+    QUIC_CLIENT_HISTOGRAM_BOOL(name, sample, docstring); \
+    QUIC_SERVER_HISTOGRAM_BOOL(name, sample, docstring); \
+  } while (0)
+
+//------------------------------------------------------------------------------
+// Timing histograms. These are used for collecting timing data (generally
+// latencies).
+
+// These macros create exponentially sized histograms (lengths of the bucket
+// ranges exponentially increase as the sample range increases). The units for
+// sample and max are unspecified, but they must be the same for one histogram.
+
+// Sample usage:
+//   QUIC_HISTOGRAM_TIMES("My.Timing.Histogram.InMs", time_delta,
+//       QuicTime::Delta::FromSeconds(1), QuicTime::Delta::FromSecond(3600 *
+//       24), 100, "Time spent in doing operation.");
+
+#define QUIC_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring) \
+  do {                                                                        \
+    QUIC_CLIENT_HISTOGRAM_TIMES(name, sample, min, max, bucket_count,         \
+                                docstring);                                   \
+    QUIC_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count,         \
+                                docstring);                                   \
+  } while (0)
+
+//------------------------------------------------------------------------------
+// Count histograms. These are used for collecting numeric data.
+
+// These macros default to exponential histograms - i.e. the lengths of the
+// bucket ranges exponentially increase as the sample range increases.
+
+// All of these macros must be called with |name| as a runtime constant.
+
+// Sample usage:
+//   QUIC_HISTOGRAM_COUNTS("My.Histogram",
+//                         sample,    // Number of something in this event.
+//                         1000,      // Record up to 1K of something.
+//                         "Number of something.");
+
+#define QUIC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, docstring) \
+  do {                                                                         \
+    QUIC_CLIENT_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,         \
+                                 docstring);                                   \
+    QUIC_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,         \
+                                 docstring);                                   \
+  } while (0)
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_EXPORTED_STATS_H_
diff --git a/quiche/quic/platform/api/quic_flag_utils.h b/quiche/quic/platform/api/quic_flag_utils.h
new file mode 100644
index 0000000..c8e179d
--- /dev/null
+++ b/quiche/quic/platform/api/quic_flag_utils.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
+
+#include "quiche/common/platform/api/quiche_flag_utils.h"
+
+#define QUIC_RELOADABLE_FLAG_COUNT QUICHE_RELOADABLE_FLAG_COUNT
+#define QUIC_RELOADABLE_FLAG_COUNT_N QUICHE_RELOADABLE_FLAG_COUNT_N
+
+#define QUIC_RESTART_FLAG_COUNT QUICHE_RESTART_FLAG_COUNT
+#define QUIC_RESTART_FLAG_COUNT_N QUICHE_RESTART_FLAG_COUNT_N
+
+#define QUIC_CODE_COUNT QUICHE_CODE_COUNT
+#define QUIC_CODE_COUNT_N QUICHE_CODE_COUNT_N
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_FLAG_UTILS_H_
diff --git a/quiche/quic/platform/api/quic_flags.h b/quiche/quic/platform/api/quic_flags.h
new file mode 100644
index 0000000..c25f160
--- /dev/null
+++ b/quiche/quic/platform/api/quic_flags.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
+
+#include <string>
+#include <vector>
+
+#include "quiche_platform_impl/quic_flags_impl.h"
+#include "quiche/common/platform/api/quiche_flags.h"
+
+#define GetQuicReloadableFlag(flag) GetQuicheReloadableFlag(quic, flag)
+#define SetQuicReloadableFlag(flag, value) \
+  SetQuicheReloadableFlag(quic, flag, value)
+#define GetQuicRestartFlag(flag) GetQuicheRestartFlag(quic, flag)
+#define SetQuicRestartFlag(flag, value) SetQuicheRestartFlag(quic, flag, value)
+#define GetQuicFlag(flag) GetQuicheFlag(flag)
+#define SetQuicFlag(flag, value) SetQuicheFlag(flag, value)
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_FLAGS_H_
diff --git a/quiche/quic/platform/api/quic_hostname_utils.h b/quiche/quic/platform/api/quic_hostname_utils.h
new file mode 100644
index 0000000..69072d5
--- /dev/null
+++ b/quiche/quic/platform/api/quic_hostname_utils.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
+
+#include "quiche/common/platform/api/quiche_hostname_utils.h"
+
+namespace quic {
+
+using QuicHostnameUtils = quiche::QuicheHostnameUtils;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_HOSTNAME_UTILS_H_
diff --git a/quiche/quic/platform/api/quic_ip_address.cc b/quiche/quic/platform/api/quic_ip_address.cc
new file mode 100644
index 0000000..2dc2071
--- /dev/null
+++ b/quiche/quic/platform/api/quic_ip_address.cc
@@ -0,0 +1,241 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+static int ToPlatformAddressFamily(IpAddressFamily family) {
+  switch (family) {
+    case IpAddressFamily::IP_V4:
+      return AF_INET;
+    case IpAddressFamily::IP_V6:
+      return AF_INET6;
+    case IpAddressFamily::IP_UNSPEC:
+      return AF_UNSPEC;
+  }
+  QUIC_BUG(quic_bug_10126_1)
+      << "Invalid IpAddressFamily " << static_cast<int32_t>(family);
+  return AF_UNSPEC;
+}
+
+QuicIpAddress QuicIpAddress::Loopback4() {
+  QuicIpAddress result;
+  result.family_ = IpAddressFamily::IP_V4;
+  result.address_.bytes[0] = 127;
+  result.address_.bytes[1] = 0;
+  result.address_.bytes[2] = 0;
+  result.address_.bytes[3] = 1;
+  return result;
+}
+
+QuicIpAddress QuicIpAddress::Loopback6() {
+  QuicIpAddress result;
+  result.family_ = IpAddressFamily::IP_V6;
+  uint8_t* bytes = result.address_.bytes;
+  memset(bytes, 0, 15);
+  bytes[15] = 1;
+  return result;
+}
+
+QuicIpAddress QuicIpAddress::Any4() {
+  in_addr address;
+  memset(&address, 0, sizeof(address));
+  return QuicIpAddress(address);
+}
+
+QuicIpAddress QuicIpAddress::Any6() {
+  in6_addr address;
+  memset(&address, 0, sizeof(address));
+  return QuicIpAddress(address);
+}
+
+QuicIpAddress::QuicIpAddress() : family_(IpAddressFamily::IP_UNSPEC) {}
+
+QuicIpAddress::QuicIpAddress(const in_addr& ipv4_address)
+    : family_(IpAddressFamily::IP_V4) {
+  address_.v4 = ipv4_address;
+}
+QuicIpAddress::QuicIpAddress(const in6_addr& ipv6_address)
+    : family_(IpAddressFamily::IP_V6) {
+  address_.v6 = ipv6_address;
+}
+
+bool operator==(QuicIpAddress lhs, QuicIpAddress rhs) {
+  if (lhs.family_ != rhs.family_) {
+    return false;
+  }
+  switch (lhs.family_) {
+    case IpAddressFamily::IP_V4:
+      return std::equal(lhs.address_.bytes,
+                        lhs.address_.bytes + QuicIpAddress::kIPv4AddressSize,
+                        rhs.address_.bytes);
+    case IpAddressFamily::IP_V6:
+      return std::equal(lhs.address_.bytes,
+                        lhs.address_.bytes + QuicIpAddress::kIPv6AddressSize,
+                        rhs.address_.bytes);
+    case IpAddressFamily::IP_UNSPEC:
+      return true;
+  }
+  QUIC_BUG(quic_bug_10126_2)
+      << "Invalid IpAddressFamily " << static_cast<int32_t>(lhs.family_);
+  return false;
+}
+
+bool operator!=(QuicIpAddress lhs, QuicIpAddress rhs) {
+  return !(lhs == rhs);
+}
+
+bool QuicIpAddress::IsInitialized() const {
+  return family_ != IpAddressFamily::IP_UNSPEC;
+}
+
+IpAddressFamily QuicIpAddress::address_family() const {
+  return family_;
+}
+
+int QuicIpAddress::AddressFamilyToInt() const {
+  return ToPlatformAddressFamily(family_);
+}
+
+std::string QuicIpAddress::ToPackedString() const {
+  switch (family_) {
+    case IpAddressFamily::IP_V4:
+      return std::string(address_.chars, sizeof(address_.v4));
+    case IpAddressFamily::IP_V6:
+      return std::string(address_.chars, sizeof(address_.v6));
+    case IpAddressFamily::IP_UNSPEC:
+      return "";
+  }
+  QUIC_BUG(quic_bug_10126_3)
+      << "Invalid IpAddressFamily " << static_cast<int32_t>(family_);
+  return "";
+}
+
+std::string QuicIpAddress::ToString() const {
+  if (!IsInitialized()) {
+    return "";
+  }
+
+  char buffer[INET6_ADDRSTRLEN] = {0};
+  const char* result =
+      inet_ntop(AddressFamilyToInt(), address_.bytes, buffer, sizeof(buffer));
+  QUIC_BUG_IF(quic_bug_10126_4, result == nullptr)
+      << "Failed to convert an IP address to string";
+  return buffer;
+}
+
+static const uint8_t kMappedAddressPrefix[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+};
+
+QuicIpAddress QuicIpAddress::Normalized() const {
+  if (!IsIPv6()) {
+    return *this;
+  }
+  if (!std::equal(std::begin(kMappedAddressPrefix),
+                  std::end(kMappedAddressPrefix), address_.bytes)) {
+    return *this;
+  }
+
+  in_addr result;
+  memcpy(&result, &address_.bytes[12], sizeof(result));
+  return QuicIpAddress(result);
+}
+
+QuicIpAddress QuicIpAddress::DualStacked() const {
+  if (!IsIPv4()) {
+    return *this;
+  }
+
+  QuicIpAddress result;
+  result.family_ = IpAddressFamily::IP_V6;
+  memcpy(result.address_.bytes, kMappedAddressPrefix,
+         sizeof(kMappedAddressPrefix));
+  memcpy(result.address_.bytes + 12, address_.bytes, kIPv4AddressSize);
+  return result;
+}
+
+bool QuicIpAddress::FromPackedString(const char* data, size_t length) {
+  switch (length) {
+    case kIPv4AddressSize:
+      family_ = IpAddressFamily::IP_V4;
+      break;
+    case kIPv6AddressSize:
+      family_ = IpAddressFamily::IP_V6;
+      break;
+    default:
+      return false;
+  }
+  memcpy(address_.chars, data, length);
+  return true;
+}
+
+bool QuicIpAddress::FromString(std::string str) {
+  for (IpAddressFamily family :
+       {IpAddressFamily::IP_V6, IpAddressFamily::IP_V4}) {
+    int result =
+        inet_pton(ToPlatformAddressFamily(family), str.c_str(), address_.bytes);
+    if (result > 0) {
+      family_ = family;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicIpAddress::IsIPv4() const {
+  return family_ == IpAddressFamily::IP_V4;
+}
+
+bool QuicIpAddress::IsIPv6() const {
+  return family_ == IpAddressFamily::IP_V6;
+}
+
+bool QuicIpAddress::InSameSubnet(const QuicIpAddress& other,
+                                 int subnet_length) {
+  if (!IsInitialized()) {
+    QUIC_BUG(quic_bug_10126_5)
+        << "Attempting to do subnet matching on undefined address";
+    return false;
+  }
+  if ((IsIPv4() && subnet_length > 32) || (IsIPv6() && subnet_length > 128)) {
+    QUIC_BUG(quic_bug_10126_6) << "Subnet mask is out of bounds";
+    return false;
+  }
+
+  int bytes_to_check = subnet_length / 8;
+  int bits_to_check = subnet_length % 8;
+  const uint8_t* const lhs = address_.bytes;
+  const uint8_t* const rhs = other.address_.bytes;
+  if (!std::equal(lhs, lhs + bytes_to_check, rhs)) {
+    return false;
+  }
+  if (bits_to_check == 0) {
+    return true;
+  }
+  QUICHE_DCHECK_LT(static_cast<size_t>(bytes_to_check), sizeof(address_.bytes));
+  int mask = (~0u) << (8u - bits_to_check);
+  return (lhs[bytes_to_check] & mask) == (rhs[bytes_to_check] & mask);
+}
+
+in_addr QuicIpAddress::GetIPv4() const {
+  QUICHE_DCHECK(IsIPv4());
+  return address_.v4;
+}
+
+in6_addr QuicIpAddress::GetIPv6() const {
+  QUICHE_DCHECK(IsIPv6());
+  return address_.v6;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/platform/api/quic_ip_address.h b/quiche/quic/platform/api/quic_ip_address.h
new file mode 100644
index 0000000..685cde8
--- /dev/null
+++ b/quiche/quic/platform/api/quic_ip_address.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
+
+#if defined(_WIN32)
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#endif
+
+#include <ostream>
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quic {
+
+// Represents an IP address.
+class QUIC_EXPORT_PRIVATE QuicIpAddress {
+ public:
+  // Sizes of IP addresses of different types, in bytes.
+  enum : size_t {
+    kIPv4AddressSize = 32 / 8,
+    kIPv6AddressSize = 128 / 8,
+    kMaxAddressSize = kIPv6AddressSize,
+  };
+
+  // TODO(fayang): Remove Loopback*() and use TestLoopback*() in tests.
+  static QuicIpAddress Loopback4();
+  static QuicIpAddress Loopback6();
+  static QuicIpAddress Any4();
+  static QuicIpAddress Any6();
+
+  QuicIpAddress();
+  QuicIpAddress(const QuicIpAddress& other) = default;
+  explicit QuicIpAddress(const in_addr& ipv4_address);
+  explicit QuicIpAddress(const in6_addr& ipv6_address);
+  QuicIpAddress& operator=(const QuicIpAddress& other) = default;
+  QuicIpAddress& operator=(QuicIpAddress&& other) = default;
+  QUIC_EXPORT_PRIVATE friend bool operator==(QuicIpAddress lhs,
+                                             QuicIpAddress rhs);
+  QUIC_EXPORT_PRIVATE friend bool operator!=(QuicIpAddress lhs,
+                                             QuicIpAddress rhs);
+
+  bool IsInitialized() const;
+  IpAddressFamily address_family() const;
+  int AddressFamilyToInt() const;
+  // Returns the address as a sequence of bytes in network-byte-order. IPv4 will
+  // be 4 bytes. IPv6 will be 16 bytes.
+  std::string ToPackedString() const;
+  // Returns string representation of the address.
+  std::string ToString() const;
+  // Normalizes the address representation with respect to IPv4 addresses, i.e,
+  // mapped IPv4 addresses ("::ffff:X.Y.Z.Q") are converted to pure IPv4
+  // addresses.  All other IPv4, IPv6, and empty values are left unchanged.
+  QuicIpAddress Normalized() const;
+  // Returns an address suitable for use in IPv6-aware contexts.  This is the
+  // opposite of NormalizeIPAddress() above.  IPv4 addresses are converted into
+  // their IPv4-mapped address equivalents (e.g. 192.0.2.1 becomes
+  // ::ffff:192.0.2.1).  IPv6 addresses are a noop (they are returned
+  // unchanged).
+  QuicIpAddress DualStacked() const;
+  bool FromPackedString(const char* data, size_t length);
+  bool FromString(std::string str);
+  bool IsIPv4() const;
+  bool IsIPv6() const;
+  bool InSameSubnet(const QuicIpAddress& other, int subnet_length);
+
+  in_addr GetIPv4() const;
+  in6_addr GetIPv6() const;
+
+ private:
+  union {
+    in_addr v4;
+    in6_addr v6;
+    uint8_t bytes[kMaxAddressSize];
+    char chars[kMaxAddressSize];
+  } address_;
+  IpAddressFamily family_;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const QuicIpAddress address) {
+  os << address.ToString();
+  return os;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_IP_ADDRESS_H_
diff --git a/quic/platform/api/quic_ip_address_family.h b/quiche/quic/platform/api/quic_ip_address_family.h
similarity index 100%
rename from quic/platform/api/quic_ip_address_family.h
rename to quiche/quic/platform/api/quic_ip_address_family.h
diff --git a/quiche/quic/platform/api/quic_ip_address_test.cc b/quiche/quic/platform/api/quic_ip_address_test.cc
new file mode 100644
index 0000000..cc06917
--- /dev/null
+++ b/quiche/quic/platform/api/quic_ip_address_test.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(QuicIpAddressTest, IPv4) {
+  QuicIpAddress ip_address;
+  EXPECT_FALSE(ip_address.IsInitialized());
+
+  EXPECT_TRUE(ip_address.FromString("127.0.52.223"));
+  EXPECT_TRUE(ip_address.IsInitialized());
+
+  EXPECT_EQ(IpAddressFamily::IP_V4, ip_address.address_family());
+  EXPECT_TRUE(ip_address.IsIPv4());
+  EXPECT_FALSE(ip_address.IsIPv6());
+
+  EXPECT_EQ("127.0.52.223", ip_address.ToString());
+  const in_addr v4_address = ip_address.GetIPv4();
+  const uint8_t* const v4_address_ptr =
+      reinterpret_cast<const uint8_t*>(&v4_address);
+  EXPECT_EQ(127u, *(v4_address_ptr + 0));
+  EXPECT_EQ(0u, *(v4_address_ptr + 1));
+  EXPECT_EQ(52u, *(v4_address_ptr + 2));
+  EXPECT_EQ(223u, *(v4_address_ptr + 3));
+}
+
+TEST(QuicIpAddressTest, IPv6) {
+  QuicIpAddress ip_address;
+  EXPECT_FALSE(ip_address.IsInitialized());
+
+  EXPECT_TRUE(ip_address.FromString("fe80::1ff:fe23:4567"));
+  EXPECT_TRUE(ip_address.IsInitialized());
+
+  EXPECT_EQ(IpAddressFamily::IP_V6, ip_address.address_family());
+  EXPECT_FALSE(ip_address.IsIPv4());
+  EXPECT_TRUE(ip_address.IsIPv6());
+
+  EXPECT_EQ("fe80::1ff:fe23:4567", ip_address.ToString());
+  const in6_addr v6_address = ip_address.GetIPv6();
+  const uint16_t* const v6_address_ptr =
+      reinterpret_cast<const uint16_t*>(&v6_address);
+  EXPECT_EQ(0x80feu, *(v6_address_ptr + 0));
+  EXPECT_EQ(0x0000u, *(v6_address_ptr + 1));
+  EXPECT_EQ(0x0000u, *(v6_address_ptr + 2));
+  EXPECT_EQ(0x0000u, *(v6_address_ptr + 3));
+  EXPECT_EQ(0x0000u, *(v6_address_ptr + 4));
+  EXPECT_EQ(0xff01u, *(v6_address_ptr + 5));
+  EXPECT_EQ(0x23feu, *(v6_address_ptr + 6));
+  EXPECT_EQ(0x6745u, *(v6_address_ptr + 7));
+
+  EXPECT_EQ(ip_address, ip_address.Normalized());
+  EXPECT_EQ(ip_address, ip_address.DualStacked());
+}
+
+TEST(QuicIpAddressTest, FromPackedString) {
+  QuicIpAddress loopback4, loopback6;
+  const char loopback4_packed[] = "\x7f\0\0\x01";
+  const char loopback6_packed[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01";
+  EXPECT_TRUE(loopback4.FromPackedString(loopback4_packed, 4));
+  EXPECT_TRUE(loopback6.FromPackedString(loopback6_packed, 16));
+  EXPECT_EQ(loopback4, QuicIpAddress::Loopback4());
+  EXPECT_EQ(loopback6, QuicIpAddress::Loopback6());
+}
+
+TEST(QuicIpAddressTest, MappedAddress) {
+  QuicIpAddress ipv4_address;
+  QuicIpAddress mapped_address;
+
+  EXPECT_TRUE(ipv4_address.FromString("127.0.0.1"));
+  EXPECT_TRUE(mapped_address.FromString("::ffff:7f00:1"));
+
+  EXPECT_EQ(mapped_address, ipv4_address.DualStacked());
+  EXPECT_EQ(ipv4_address, mapped_address.Normalized());
+}
+
+TEST(QuicIpAddressTest, Subnets) {
+  struct {
+    const char* address1;
+    const char* address2;
+    int subnet_size;
+    bool same_subnet;
+  } test_cases[] = {
+      {"127.0.0.1", "127.0.0.2", 24, true},
+      {"8.8.8.8", "127.0.0.1", 24, false},
+      {"8.8.8.8", "127.0.0.1", 16, false},
+      {"8.8.8.8", "127.0.0.1", 8, false},
+      {"8.8.8.8", "127.0.0.1", 2, false},
+      {"8.8.8.8", "127.0.0.1", 1, true},
+
+      {"127.0.0.1", "127.0.0.128", 24, true},
+      {"127.0.0.1", "127.0.0.128", 25, false},
+      {"127.0.0.1", "127.0.0.127", 25, true},
+
+      {"127.0.0.1", "127.0.0.0", 30, true},
+      {"127.0.0.1", "127.0.0.1", 30, true},
+      {"127.0.0.1", "127.0.0.2", 30, true},
+      {"127.0.0.1", "127.0.0.3", 30, true},
+      {"127.0.0.1", "127.0.0.4", 30, false},
+
+      {"127.0.0.1", "127.0.0.2", 31, false},
+      {"127.0.0.1", "127.0.0.0", 31, true},
+
+      {"::1", "fe80::1", 8, false},
+      {"::1", "fe80::1", 1, false},
+      {"::1", "fe80::1", 0, true},
+      {"fe80::1", "fe80::2", 126, true},
+      {"fe80::1", "fe80::2", 127, false},
+  };
+
+  for (const auto& test_case : test_cases) {
+    QuicIpAddress address1, address2;
+    ASSERT_TRUE(address1.FromString(test_case.address1));
+    ASSERT_TRUE(address2.FromString(test_case.address2));
+    EXPECT_EQ(test_case.same_subnet,
+              address1.InSameSubnet(address2, test_case.subnet_size))
+        << "Addresses: " << test_case.address1 << ", " << test_case.address2
+        << "; subnet: /" << test_case.subnet_size;
+  }
+}
+
+TEST(QuicIpAddress, LoopbackAddresses) {
+  QuicIpAddress loopback4;
+  QuicIpAddress loopback6;
+  ASSERT_TRUE(loopback4.FromString("127.0.0.1"));
+  ASSERT_TRUE(loopback6.FromString("::1"));
+  EXPECT_EQ(loopback4, QuicIpAddress::Loopback4());
+  EXPECT_EQ(loopback6, QuicIpAddress::Loopback6());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/platform/api/quic_logging.h b/quiche/quic/platform/api/quic_logging.h
new file mode 100644
index 0000000..442e39c
--- /dev/null
+++ b/quiche/quic/platform/api/quic_logging.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+// Please note following QUIC_LOG are platform dependent:
+// INFO severity can be degraded (to VLOG(1) or DVLOG(1)).
+// Some platforms may not support QUIC_LOG_FIRST_N or QUIC_LOG_EVERY_N_SEC, and
+// they would simply be translated to LOG.
+
+#define QUIC_DVLOG QUICHE_DVLOG
+#define QUIC_DVLOG_IF QUICHE_DVLOG_IF
+#define QUIC_DLOG QUICHE_DLOG
+#define QUIC_DLOG_IF QUICHE_DLOG_IF
+#define QUIC_VLOG QUICHE_VLOG
+#define QUIC_LOG QUICHE_LOG
+#define QUIC_LOG_FIRST_N QUICHE_LOG_FIRST_N
+#define QUIC_LOG_EVERY_N_SEC QUICHE_LOG_EVERY_N_SEC
+#define QUIC_LOG_IF QUICHE_LOG_IF
+
+#define QUIC_PREDICT_FALSE QUICHE_PREDICT_FALSE
+#define QUIC_PREDICT_TRUE QUICHE_PREDICT_TRUE
+
+// This is a noop in release build.
+#define QUIC_NOTREACHED QUICHE_NOTREACHED
+
+#define QUIC_PLOG QUICHE_PLOG
+
+#define QUIC_DLOG_INFO_IS_ON QUICHE_DLOG_INFO_IS_ON
+#define QUIC_LOG_INFO_IS_ON QUICHE_LOG_INFO_IS_ON
+#define QUIC_LOG_WARNING_IS_ON QUICHE_LOG_WARNING_IS_ON
+#define QUIC_LOG_ERROR_IS_ON QUICHE_LOG_ERROR_IS_ON
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_LOGGING_H_
diff --git a/quiche/quic/platform/api/quic_mock_log.h b/quiche/quic/platform/api/quic_mock_log.h
new file mode 100644
index 0000000..0402f10
--- /dev/null
+++ b/quiche/quic/platform/api/quic_mock_log.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
+
+#include "quiche/common/platform/api/quiche_mock_log.h"
+
+using QuicMockLog = QuicheMockLogImpl;
+
+#define CREATE_QUIC_MOCK_LOG(log) CREATE_QUICHE_MOCK_LOG(log)
+
+#define EXPECT_QUIC_LOG_CALL(log) EXPECT_QUICHE_LOG_CALL(log)
+
+#define EXPECT_QUIC_LOG_CALL_CONTAINS(log, level, content) \
+  EXPECT_QUICHE_LOG_CALL_CONTAINS(log, level, content)
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
diff --git a/quiche/quic/platform/api/quic_mutex.h b/quiche/quic/platform/api/quic_mutex.h
new file mode 100644
index 0000000..1e6f36a
--- /dev/null
+++ b/quiche/quic/platform/api/quic_mutex.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO(b/178613777): Remove this file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
+
+#include "quiche/common/platform/api/quiche_mutex.h"
+
+#define QUIC_EXCLUSIVE_LOCKS_REQUIRED QUICHE_EXCLUSIVE_LOCKS_REQUIRED
+#define QUIC_GUARDED_BY QUICHE_GUARDED_BY
+#define QUIC_LOCKABLE QUICHE_LOCKABLE
+#define QUIC_LOCKS_EXCLUDED QUICHE_LOCKS_EXCLUDED
+#define QUIC_SHARED_LOCKS_REQUIRED QUICHE_SHARED_LOCKS_REQUIRED
+#define QUIC_EXCLUSIVE_LOCK_FUNCTION QUICHE_EXCLUSIVE_LOCK_FUNCTION
+#define QUIC_UNLOCK_FUNCTION QUICHE_UNLOCK_FUNCTION
+#define QUIC_SHARED_LOCK_FUNCTION QUICHE_SHARED_LOCK_FUNCTION
+#define QUIC_SCOPED_LOCKABLE QUICHE_SCOPED_LOCKABLE
+#define QUIC_ASSERT_SHARED_LOCK QUICHE_ASSERT_SHARED_LOCK
+
+namespace quic {
+
+using QuicMutex = quiche::QuicheMutex;
+using QuicReaderMutexLock = quiche::QuicheReaderMutexLock;
+using QuicWriterMutexLock = quiche::QuicheWriterMutexLock;
+using QuicNotification = quiche::QuicheNotification;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_MUTEX_H_
diff --git a/quiche/quic/platform/api/quic_server_stats.h b/quiche/quic/platform/api/quic_server_stats.h
new file mode 100644
index 0000000..8e37346
--- /dev/null
+++ b/quiche/quic/platform/api/quic_server_stats.h
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
+
+#include "quiche/common/platform/api/quiche_server_stats.h"
+
+#define QUIC_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring) \
+  QUICHE_SERVER_HISTOGRAM_ENUM(name, sample, enum_size, docstring)
+
+#define QUIC_SERVER_HISTOGRAM_BOOL(name, sample, docstring) \
+  QUICHE_SERVER_HISTOGRAM_BOOL(name, sample, docstring)
+
+#define QUIC_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, \
+                                    docstring)                            \
+  QUICHE_SERVER_HISTOGRAM_TIMES(name, sample, min, max, bucket_count, docstring)
+
+#define QUIC_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count, \
+                                     docstring)                            \
+  QUICHE_SERVER_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count,     \
+                                 docstring)
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_SERVER_STATS_H_
diff --git a/quiche/quic/platform/api/quic_socket_address.cc b/quiche/quic/platform/api/quic_socket_address.cc
new file mode 100644
index 0000000..0a35e86
--- /dev/null
+++ b/quiche/quic/platform/api/quic_socket_address.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+#include <cstring>
+#include <limits>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quic {
+
+namespace {
+
+uint32_t HashIP(const QuicIpAddress& ip) {
+  if (ip.IsIPv4()) {
+    return ip.GetIPv4().s_addr;
+  }
+  if (ip.IsIPv6()) {
+    auto v6addr = ip.GetIPv6();
+    const uint32_t* v6_as_ints =
+        reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
+    return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3];
+  }
+  return 0;
+}
+
+}  // namespace
+
+QuicSocketAddress::QuicSocketAddress(QuicIpAddress address, uint16_t port)
+    : host_(address), port_(port) {}
+
+QuicSocketAddress::QuicSocketAddress(const struct sockaddr_storage& saddr) {
+  switch (saddr.ss_family) {
+    case AF_INET: {
+      const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&saddr);
+      host_ = QuicIpAddress(v4->sin_addr);
+      port_ = ntohs(v4->sin_port);
+      break;
+    }
+    case AF_INET6: {
+      const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&saddr);
+      host_ = QuicIpAddress(v6->sin6_addr);
+      port_ = ntohs(v6->sin6_port);
+      break;
+    }
+    default:
+      QUIC_BUG(quic_bug_10075_1)
+          << "Unknown address family passed: " << saddr.ss_family;
+      break;
+  }
+}
+
+QuicSocketAddress::QuicSocketAddress(const sockaddr* saddr, socklen_t len) {
+  sockaddr_storage storage;
+  static_assert(std::numeric_limits<socklen_t>::max() >= sizeof(storage),
+                "Cannot cast sizeof(storage) to socklen_t as it does not fit");
+  if (len < static_cast<socklen_t>(sizeof(sockaddr)) ||
+      (saddr->sa_family == AF_INET &&
+       len < static_cast<socklen_t>(sizeof(sockaddr_in))) ||
+      (saddr->sa_family == AF_INET6 &&
+       len < static_cast<socklen_t>(sizeof(sockaddr_in6))) ||
+      len > static_cast<socklen_t>(sizeof(storage))) {
+    QUIC_BUG(quic_bug_10075_2) << "Socket address of invalid length provided";
+    return;
+  }
+  memcpy(&storage, saddr, len);
+  *this = QuicSocketAddress(storage);
+}
+
+bool operator==(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
+  return lhs.host_ == rhs.host_ && lhs.port_ == rhs.port_;
+}
+
+bool operator!=(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
+  return !(lhs == rhs);
+}
+
+bool QuicSocketAddress::IsInitialized() const {
+  return host_.IsInitialized();
+}
+
+std::string QuicSocketAddress::ToString() const {
+  switch (host_.address_family()) {
+    case IpAddressFamily::IP_V4:
+      return absl::StrCat(host_.ToString(), ":", port_);
+    case IpAddressFamily::IP_V6:
+      return absl::StrCat("[", host_.ToString(), "]:", port_);
+    default:
+      return "";
+  }
+}
+
+int QuicSocketAddress::FromSocket(int fd) {
+  sockaddr_storage addr;
+  socklen_t addr_len = sizeof(addr);
+  int result = getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len);
+
+  bool success = result == 0 && addr_len > 0 &&
+                 static_cast<size_t>(addr_len) <= sizeof(addr);
+  if (success) {
+    *this = QuicSocketAddress(addr);
+    return 0;
+  }
+  return -1;
+}
+
+QuicSocketAddress QuicSocketAddress::Normalized() const {
+  return QuicSocketAddress(host_.Normalized(), port_);
+}
+
+QuicIpAddress QuicSocketAddress::host() const {
+  return host_;
+}
+
+uint16_t QuicSocketAddress::port() const {
+  return port_;
+}
+
+sockaddr_storage QuicSocketAddress::generic_address() const {
+  union {
+    sockaddr_storage storage;
+    sockaddr_in v4;
+    sockaddr_in6 v6;
+  } result;
+  memset(&result.storage, 0, sizeof(result.storage));
+
+  switch (host_.address_family()) {
+    case IpAddressFamily::IP_V4:
+      result.v4.sin_family = AF_INET;
+      result.v4.sin_addr = host_.GetIPv4();
+      result.v4.sin_port = htons(port_);
+      break;
+    case IpAddressFamily::IP_V6:
+      result.v6.sin6_family = AF_INET6;
+      result.v6.sin6_addr = host_.GetIPv6();
+      result.v6.sin6_port = htons(port_);
+      break;
+    default:
+      result.storage.ss_family = AF_UNSPEC;
+      break;
+  }
+  return result.storage;
+}
+
+uint32_t QuicSocketAddress::Hash() const {
+  uint32_t value = 0;
+  value ^= HashIP(host_);
+  value ^= port_ | (port_ << 16);
+  return value;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/platform/api/quic_socket_address.h b/quiche/quic/platform/api/quic_socket_address.h
new file mode 100644
index 0000000..9ec9717
--- /dev/null
+++ b/quiche/quic/platform/api/quic_socket_address.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+// A class representing a socket endpoint address (i.e., IP address plus a
+// port) in QUIC.
+class QUIC_EXPORT_PRIVATE QuicSocketAddress {
+ public:
+  QuicSocketAddress() {}
+  QuicSocketAddress(QuicIpAddress address, uint16_t port);
+  explicit QuicSocketAddress(const struct sockaddr_storage& saddr);
+  explicit QuicSocketAddress(const sockaddr* saddr, socklen_t len);
+  QuicSocketAddress(const QuicSocketAddress& other) = default;
+  QuicSocketAddress& operator=(const QuicSocketAddress& other) = default;
+  QuicSocketAddress& operator=(QuicSocketAddress&& other) = default;
+  QUIC_EXPORT_PRIVATE friend bool operator==(const QuicSocketAddress& lhs,
+                                             const QuicSocketAddress& rhs);
+  QUIC_EXPORT_PRIVATE friend bool operator!=(const QuicSocketAddress& lhs,
+                                             const QuicSocketAddress& rhs);
+
+  bool IsInitialized() const;
+  std::string ToString() const;
+  int FromSocket(int fd);
+  QuicSocketAddress Normalized() const;
+
+  QuicIpAddress host() const;
+  uint16_t port() const;
+  sockaddr_storage generic_address() const;
+
+  // Hashes this address to an uint32_t.
+  uint32_t Hash() const;
+
+ private:
+  QuicIpAddress host_;
+  uint16_t port_ = 0;
+};
+
+inline std::ostream& operator<<(std::ostream& os,
+                                const QuicSocketAddress address) {
+  os << address.ToString();
+  return os;
+}
+
+class QUIC_EXPORT_PRIVATE QuicSocketAddressHash {
+ public:
+  size_t operator()(QuicSocketAddress const& address) const noexcept {
+    return address.Hash();
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
diff --git a/quiche/quic/platform/api/quic_socket_address_test.cc b/quiche/quic/platform/api/quic_socket_address_test.cc
new file mode 100644
index 0000000..9512c9f
--- /dev/null
+++ b/quiche/quic/platform/api/quic_socket_address_test.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+#include <memory>
+#include <sstream>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+TEST(QuicSocketAddress, Uninitialized) {
+  QuicSocketAddress uninitialized;
+  EXPECT_FALSE(uninitialized.IsInitialized());
+}
+
+TEST(QuicSocketAddress, ExplicitConstruction) {
+  QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
+  QuicSocketAddress ipv6_address(QuicIpAddress::Loopback6(), 443);
+  EXPECT_TRUE(ipv4_address.IsInitialized());
+  EXPECT_EQ("127.0.0.1:443", ipv4_address.ToString());
+  EXPECT_EQ("[::1]:443", ipv6_address.ToString());
+  EXPECT_EQ(QuicIpAddress::Loopback4(), ipv4_address.host());
+  EXPECT_EQ(QuicIpAddress::Loopback6(), ipv6_address.host());
+  EXPECT_EQ(443, ipv4_address.port());
+}
+
+TEST(QuicSocketAddress, OutputToStream) {
+  QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
+  std::stringstream stream;
+  stream << ipv4_address;
+  EXPECT_EQ("127.0.0.1:443", stream.str());
+}
+
+TEST(QuicSocketAddress, FromSockaddrIPv4) {
+  union {
+    sockaddr_storage storage;
+    sockaddr addr;
+    sockaddr_in v4;
+  } address;
+
+  memset(&address, 0, sizeof(address));
+  address.v4.sin_family = AF_INET;
+  address.v4.sin_addr = QuicIpAddress::Loopback4().GetIPv4();
+  address.v4.sin_port = htons(443);
+  EXPECT_EQ("127.0.0.1:443",
+            QuicSocketAddress(&address.addr, sizeof(address.v4)).ToString());
+  EXPECT_EQ("127.0.0.1:443", QuicSocketAddress(address.storage).ToString());
+}
+
+TEST(QuicSocketAddress, FromSockaddrIPv6) {
+  union {
+    sockaddr_storage storage;
+    sockaddr addr;
+    sockaddr_in6 v6;
+  } address;
+
+  memset(&address, 0, sizeof(address));
+  address.v6.sin6_family = AF_INET6;
+  address.v6.sin6_addr = QuicIpAddress::Loopback6().GetIPv6();
+  address.v6.sin6_port = htons(443);
+  EXPECT_EQ("[::1]:443",
+            QuicSocketAddress(&address.addr, sizeof(address.v6)).ToString());
+  EXPECT_EQ("[::1]:443", QuicSocketAddress(address.storage).ToString());
+}
+
+TEST(QuicSocketAddres, ToSockaddrIPv4) {
+  union {
+    sockaddr_storage storage;
+    sockaddr_in v4;
+  } address;
+
+  address.storage =
+      QuicSocketAddress(QuicIpAddress::Loopback4(), 443).generic_address();
+  ASSERT_EQ(AF_INET, address.v4.sin_family);
+  EXPECT_EQ(QuicIpAddress::Loopback4(), QuicIpAddress(address.v4.sin_addr));
+  EXPECT_EQ(htons(443), address.v4.sin_port);
+}
+
+TEST(QuicSocketAddress, Normalize) {
+  QuicIpAddress dual_stacked;
+  ASSERT_TRUE(dual_stacked.FromString("::ffff:127.0.0.1"));
+  ASSERT_TRUE(dual_stacked.IsIPv6());
+  QuicSocketAddress not_normalized(dual_stacked, 443);
+  QuicSocketAddress normalized = not_normalized.Normalized();
+  EXPECT_EQ("[::ffff:127.0.0.1]:443", not_normalized.ToString());
+  EXPECT_EQ("127.0.0.1:443", normalized.ToString());
+}
+
+// TODO(vasilvv): either ensure this works on all platforms, or deprecate and
+// remove this API.
+#if defined(__linux__) && !defined(ANDROID)
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+TEST(QuicSocketAddress, FromSocket) {
+  int fd;
+  QuicSocketAddress address;
+  bool bound = false;
+  for (int port = 50000; port < 50400; port++) {
+    fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+    ASSERT_GT(fd, 0);
+
+    address = QuicSocketAddress(QuicIpAddress::Loopback6(), port);
+    sockaddr_storage raw_address = address.generic_address();
+    int bind_result = bind(fd, reinterpret_cast<const sockaddr*>(&raw_address),
+                           sizeof(sockaddr_in6));
+
+    if (bind_result < 0 && errno == EADDRINUSE) {
+      close(fd);
+      continue;
+    }
+
+    ASSERT_EQ(0, bind_result);
+    bound = true;
+    break;
+  }
+  ASSERT_TRUE(bound);
+
+  QuicSocketAddress real_address;
+  ASSERT_EQ(0, real_address.FromSocket(fd));
+  ASSERT_TRUE(real_address.IsInitialized());
+  EXPECT_EQ(real_address, address);
+  close(fd);
+}
+#endif
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/platform/api/quic_stack_trace.h b/quiche/quic/platform/api/quic_stack_trace.h
new file mode 100644
index 0000000..eb8beab
--- /dev/null
+++ b/quiche/quic/platform/api/quic_stack_trace.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
+
+#include <string>
+
+#include "quiche/common/platform/api/quiche_stack_trace.h"
+
+namespace quic {
+
+inline std::string QuicStackTrace() { return quiche::QuicheStackTrace(); }
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_STACK_TRACE_H_
diff --git a/quiche/quic/platform/api/quic_stream_buffer_allocator.h b/quiche/quic/platform/api/quic_stream_buffer_allocator.h
new file mode 100644
index 0000000..174e878
--- /dev/null
+++ b/quiche/quic/platform/api/quic_stream_buffer_allocator.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
+
+#include "quiche/common/platform/api/quiche_stream_buffer_allocator.h"
+
+namespace quic {
+
+using QuicStreamBufferAllocator = quiche::QuicheStreamBufferAllocator;
+}
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
diff --git a/quiche/quic/platform/api/quic_test.h b/quiche/quic/platform/api/quic_test.h
new file mode 100644
index 0000000..9e63acc
--- /dev/null
+++ b/quiche/quic/platform/api/quic_test.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
+
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+using QuicFlagSaver = QuicheFlagSaver;
+
+// Defines the base classes to be used in QUIC tests.
+using QuicTest = QuicheTest;
+template <class T>
+using QuicTestWithParam = QuicheTestWithParam<T>;
+
+// Class which needs to be instantiated in tests which use threads.
+using ScopedEnvironmentForThreads = ScopedEnvironmentForThreadsImpl;
+
+#define QUIC_TEST_DISABLED_IN_CHROME(name) QUICHE_TEST_DISABLED_IN_CHROME(name)
+
+inline std::string QuicGetTestMemoryCachePath() {
+  return QuicheGetTestMemoryCachePath();
+}
+
+#define QUIC_SLOW_TEST(test) QUICHE_SLOW_TEST(test)
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
diff --git a/quiche/quic/platform/api/quic_test_loopback.h b/quiche/quic/platform/api/quic_test_loopback.h
new file mode 100644
index 0000000..2e9e42f
--- /dev/null
+++ b/quiche/quic/platform/api/quic_test_loopback.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/common/platform/api/quiche_test_loopback.h"
+
+namespace quic {
+
+// Returns the address family (IPv4 or IPv6) used to run test under.
+inline IpAddressFamily AddressFamilyUnderTest() {
+  return quiche::AddressFamilyUnderTest();
+}
+
+// Returns an IPv4 loopback address.
+inline QuicIpAddress TestLoopback4() { return quiche::TestLoopback4(); }
+
+// Returns the only IPv6 loopback address.
+inline QuicIpAddress TestLoopback6() { return quiche::TestLoopback6(); }
+
+// Returns an appropriate IPv4/Ipv6 loopback address based upon whether the
+// test's environment.
+inline QuicIpAddress TestLoopback() { return quiche::TestLoopback(); }
+
+// If address family under test is IPv4, returns an indexed IPv4 loopback
+// address. If address family under test is IPv6, the address returned is
+// platform-dependent.
+inline QuicIpAddress TestLoopback(int index) {
+  return quiche::TestLoopback(index);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_LOOPBACK_H_
diff --git a/quiche/quic/platform/api/quic_test_output.h b/quiche/quic/platform/api/quic_test_output.h
new file mode 100644
index 0000000..8d4b54a
--- /dev/null
+++ b/quiche/quic/platform/api/quic_test_output.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test_output.h"
+
+namespace quic {
+
+inline void QuicSaveTestOutput(absl::string_view filename,
+                               absl::string_view data) {
+  quiche::QuicheSaveTestOutput(filename, data);
+}
+
+inline bool QuicLoadTestOutput(absl::string_view filename, std::string* data) {
+  return quiche::QuicheLoadTestOutput(filename, data);
+}
+
+inline void QuicRecordTrace(absl::string_view identifier,
+                            absl::string_view data) {
+  quiche::QuicheRecordTrace(identifier, data);
+}
+
+}  // namespace quic
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_OUTPUT_H_
diff --git a/quiche/quic/platform/api/quic_testvalue.h b/quiche/quic/platform/api/quic_testvalue.h
new file mode 100644
index 0000000..aa6074c
--- /dev/null
+++ b/quiche/quic/platform/api/quic_testvalue.h
@@ -0,0 +1,22 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO(b/178613777): Remove this file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_testvalue.h"
+
+namespace quic {
+
+template <class T>
+void AdjustTestValue(absl::string_view label, T* var) {
+  quiche::AdjustTestValue(label, var);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_TESTVALUE_H_
diff --git a/quiche/quic/platform/api/quic_thread.h b/quiche/quic/platform/api/quic_thread.h
new file mode 100644
index 0000000..4633306
--- /dev/null
+++ b/quiche/quic/platform/api/quic_thread.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
+
+#include "quiche/common/platform/api/quiche_thread.h"
+
+namespace quic {
+
+using QuicThread = quiche::QuicheThread;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_THREAD_H_
diff --git a/quiche/quic/platform/api/quic_udp_socket_platform_api.h b/quiche/quic/platform/api/quic_udp_socket_platform_api.h
new file mode 100644
index 0000000..d6009d9
--- /dev/null
+++ b/quiche/quic/platform/api/quic_udp_socket_platform_api.h
@@ -0,0 +1,29 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
+#define QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
+
+#include "quiche/common/platform/api/quiche_udp_socket_platform_api.h"
+
+namespace quic {
+
+const size_t kCmsgSpaceForGooglePacketHeader =
+    quiche::kCmsgSpaceForGooglePacketHeader;
+
+inline bool GetGooglePacketHeadersFromControlMessage(
+    struct ::cmsghdr* cmsg,
+    char** packet_headers,
+    size_t* packet_headers_len) {
+  return quiche::GetGooglePacketHeadersFromControlMessage(cmsg, packet_headers,
+                                                          packet_headers_len);
+}
+
+inline void SetGoogleSocketOptions(int fd) {
+  quiche::SetGoogleSocketOptions(fd);
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_UDP_SOCKET_PLATFORM_API_H_
diff --git a/quiche/quic/qbone/bonnet/icmp_reachable.cc b/quiche/quic/qbone/bonnet/icmp_reachable.cc
new file mode 100644
index 0000000..ee67cf2
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/icmp_reachable.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/icmp_reachable.h"
+
+#include <netinet/ip6.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+constexpr int kEpollFlags = EPOLLIN | EPOLLET;
+constexpr size_t kMtu = 1280;
+
+constexpr size_t kIPv6AddrSize = sizeof(in6_addr);
+
+}  // namespace
+
+const char kUnknownSource[] = "UNKNOWN";
+const char kNoSource[] = "N/A";
+
+IcmpReachable::IcmpReachable(QuicIpAddress source,
+                             QuicIpAddress destination,
+                             absl::Duration timeout,
+                             KernelInterface* kernel,
+                             QuicEpollServer* epoll_server,
+                             StatsInterface* stats)
+    : timeout_(timeout),
+      cb_(this),
+      kernel_(kernel),
+      epoll_server_(epoll_server),
+      stats_(stats),
+      send_fd_(0),
+      recv_fd_(0) {
+  src_.sin6_family = AF_INET6;
+  dst_.sin6_family = AF_INET6;
+
+  memcpy(&src_.sin6_addr, source.ToPackedString().data(), kIPv6AddrSize);
+  memcpy(&dst_.sin6_addr, destination.ToPackedString().data(), kIPv6AddrSize);
+}
+
+IcmpReachable::~IcmpReachable() {
+  if (send_fd_ > 0) {
+    kernel_->close(send_fd_);
+  }
+  if (recv_fd_ > 0) {
+    if (!epoll_server_->ShutdownCalled()) {
+      epoll_server_->UnregisterFD(recv_fd_);
+    }
+
+    kernel_->close(recv_fd_);
+  }
+}
+
+bool IcmpReachable::Init() {
+  send_fd_ = kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW);
+  if (send_fd_ < 0) {
+    QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
+    return false;
+  }
+
+  if (kernel_->bind(send_fd_, reinterpret_cast<struct sockaddr*>(&src_),
+                    sizeof(sockaddr_in6)) < 0) {
+    QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
+    return false;
+  }
+
+  recv_fd_ =
+      kernel_->socket(PF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_ICMPV6);
+  if (recv_fd_ < 0) {
+    QUIC_LOG(ERROR) << "Unable to open socket: " << errno;
+    return false;
+  }
+
+  if (kernel_->bind(recv_fd_, reinterpret_cast<struct sockaddr*>(&src_),
+                    sizeof(sockaddr_in6)) < 0) {
+    QUIC_LOG(ERROR) << "Unable to bind socket: " << errno;
+    return false;
+  }
+
+  icmp6_filter filter;
+  ICMP6_FILTER_SETBLOCKALL(&filter);
+  ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
+  if (kernel_->setsockopt(recv_fd_, SOL_ICMPV6, ICMP6_FILTER, &filter,
+                          sizeof(filter)) < 0) {
+    QUIC_LOG(ERROR) << "Unable to set ICMP6 filter.";
+    return false;
+  }
+
+  epoll_server_->RegisterFD(recv_fd_, &cb_, kEpollFlags);
+  epoll_server_->RegisterAlarm(0, this);
+
+  QuicWriterMutexLock mu(&header_lock_);
+  icmp_header_.icmp6_type = ICMP6_ECHO_REQUEST;
+  icmp_header_.icmp6_code = 0;
+
+  QuicRandom::GetInstance()->RandBytes(&icmp_header_.icmp6_id,
+                                       sizeof(uint16_t));
+
+  return true;
+}
+
+bool IcmpReachable::OnEvent(int fd) {
+  char buffer[kMtu];
+
+  sockaddr_in6 source_addr{};
+  socklen_t source_addr_len = sizeof(source_addr);
+
+  ssize_t size = kernel_->recvfrom(fd, &buffer, kMtu, 0,
+                                   reinterpret_cast<sockaddr*>(&source_addr),
+                                   &source_addr_len);
+
+  if (size < 0) {
+    if (errno != EAGAIN && errno != EWOULDBLOCK) {
+      stats_->OnReadError(errno);
+    }
+    return false;
+  }
+
+  QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(
+      absl::string_view(buffer, size));
+
+  auto* header = reinterpret_cast<const icmp6_hdr*>(&buffer);
+  QuicWriterMutexLock mu(&header_lock_);
+  if (header->icmp6_data32[0] != icmp_header_.icmp6_data32[0]) {
+    QUIC_VLOG(2) << "Unexpected response. id: " << header->icmp6_id
+                 << " seq: " << header->icmp6_seq
+                 << " Expected id: " << icmp_header_.icmp6_id
+                 << " seq: " << icmp_header_.icmp6_seq;
+    return true;
+  }
+  end_ = absl::Now();
+  QUIC_VLOG(1) << "Received ping response in "
+               << absl::ToInt64Microseconds(end_ - start_) << "us.";
+
+  std::string source;
+  QuicIpAddress source_ip;
+  if (!source_ip.FromPackedString(
+          reinterpret_cast<char*>(&source_addr.sin6_addr), sizeof(in6_addr))) {
+    QUIC_LOG(WARNING) << "Unable to parse source address.";
+    source = kUnknownSource;
+  } else {
+    source = source_ip.ToString();
+  }
+  stats_->OnEvent({Status::REACHABLE, end_ - start_, source});
+  return true;
+}
+
+int64 /* allow-non-std-int */ IcmpReachable::OnAlarm() {
+  EpollAlarm::OnAlarm();
+
+  QuicWriterMutexLock mu(&header_lock_);
+
+  if (end_ < start_) {
+    QUIC_VLOG(1) << "Timed out on sequence: " << icmp_header_.icmp6_seq;
+    stats_->OnEvent({Status::UNREACHABLE, absl::ZeroDuration(), kNoSource});
+  }
+
+  icmp_header_.icmp6_seq++;
+  CreateIcmpPacket(src_.sin6_addr, dst_.sin6_addr, icmp_header_, "",
+                   [this](absl::string_view packet) {
+                     QUIC_VLOG(2) << quiche::QuicheTextUtils::HexDump(packet);
+
+                     ssize_t size = kernel_->sendto(
+                         send_fd_, packet.data(), packet.size(), 0,
+                         reinterpret_cast<struct sockaddr*>(&dst_),
+                         sizeof(sockaddr_in6));
+
+                     if (size < packet.size()) {
+                       stats_->OnWriteError(errno);
+                     }
+                     start_ = absl::Now();
+                   });
+
+  return absl::ToUnixMicros(absl::Now() + timeout_);
+}
+
+absl::string_view IcmpReachable::StatusName(IcmpReachable::Status status) {
+  switch (status) {
+    case REACHABLE:
+      return "REACHABLE";
+    case UNREACHABLE:
+      return "UNREACHABLE";
+    default:
+      return "UNKNOWN";
+  }
+}
+
+void IcmpReachable::EpollCallback::OnEvent(int fd, QuicEpollEvent* event) {
+  bool can_read_more = reachable_->OnEvent(fd);
+  if (can_read_more) {
+    event->out_ready_mask |= EPOLLIN;
+  }
+}
+
+void IcmpReachable::EpollCallback::OnShutdown(QuicEpollServer* eps, int fd) {
+  eps->UnregisterFD(fd);
+}
+
+std::string IcmpReachable::EpollCallback::Name() const {
+  return "ICMP Reachable";
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/icmp_reachable.h b/quiche/quic/qbone/bonnet/icmp_reachable.h
new file mode 100644
index 0000000..74189b1
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/icmp_reachable.h
@@ -0,0 +1,140 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
+#define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
+
+#include <netinet/icmp6.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/qbone/bonnet/icmp_reachable_interface.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+
+namespace quic {
+
+extern const char kUnknownSource[];
+extern const char kNoSource[];
+
+// IcmpReachable schedules itself with an EpollServer, periodically sending
+// ICMPv6 Echo Requests to the given |destination| on the interface that the
+// given |source| is bound to. Echo Requests are sent once every |timeout|.
+// On Echo Replies, timeouts, and I/O errors, the given |stats| object will
+// be called back with details of the event.
+class IcmpReachable : public IcmpReachableInterface {
+ public:
+  enum Status { REACHABLE, UNREACHABLE };
+
+  struct ReachableEvent {
+    Status status;
+    absl::Duration response_time;
+    std::string source;
+  };
+
+  class StatsInterface {
+   public:
+    StatsInterface() = default;
+
+    StatsInterface(const StatsInterface&) = delete;
+    StatsInterface& operator=(const StatsInterface&) = delete;
+
+    StatsInterface(StatsInterface&&) = delete;
+    StatsInterface& operator=(StatsInterface&&) = delete;
+
+    virtual ~StatsInterface() = default;
+
+    virtual void OnEvent(ReachableEvent event) = 0;
+
+    virtual void OnReadError(int error) = 0;
+
+    virtual void OnWriteError(int error) = 0;
+  };
+
+  // |source| is the IPv6 address bound to the interface that IcmpReachable will
+  //          send Echo Requests on.
+  // |destination| is the IPv6 address of the destination of the Echo Requests.
+  // |timeout| is the duration IcmpReachable will wait between Echo Requests.
+  //           If no Echo Response is received by the next Echo Request, it will
+  //           be considered a timeout.
+  // |kernel| is not owned, but should outlive this instance.
+  // |epoll_server| is not owned, but should outlive this instance.
+  //                IcmpReachable's Init() must be called from within the Epoll
+  //                Server's thread.
+  // |stats| is not owned, but should outlive this instance. It will be called
+  //         back on Echo Replies, timeouts, and I/O errors.
+  IcmpReachable(QuicIpAddress source,
+                QuicIpAddress destination,
+                absl::Duration timeout,
+                KernelInterface* kernel,
+                QuicEpollServer* epoll_server,
+                StatsInterface* stats);
+
+  ~IcmpReachable() override;
+
+  // Initializes this reachability probe. Must be called from within the
+  // |epoll_server|'s thread.
+  bool Init() QUIC_LOCKS_EXCLUDED(header_lock_) override;
+
+  int64 /* allow-non-std-int */ OnAlarm()
+      QUIC_LOCKS_EXCLUDED(header_lock_) override;
+
+  static absl::string_view StatusName(Status status);
+
+ private:
+  class EpollCallback : public QuicEpollCallbackInterface {
+   public:
+    explicit EpollCallback(IcmpReachable* reachable) : reachable_(reachable) {}
+
+    EpollCallback(const EpollCallback&) = delete;
+    EpollCallback& operator=(const EpollCallback&) = delete;
+
+    EpollCallback(EpollCallback&&) = delete;
+    EpollCallback& operator=(EpollCallback&&) = delete;
+
+    void OnRegistration(QuicEpollServer* eps,
+                        int fd,
+                        int event_mask) override{};
+
+    void OnModification(int fd, int event_mask) override{};
+
+    void OnEvent(int fd, QuicEpollEvent* event) override;
+
+    void OnUnregistration(int fd, bool replaced) override{};
+
+    void OnShutdown(QuicEpollServer* eps, int fd) override;
+
+    std::string Name() const override;
+
+   private:
+    IcmpReachable* reachable_;
+  };
+
+  bool OnEvent(int fd) QUIC_LOCKS_EXCLUDED(header_lock_);
+
+  const absl::Duration timeout_;
+
+  EpollCallback cb_;
+
+  sockaddr_in6 src_{};
+  sockaddr_in6 dst_{};
+
+  KernelInterface* kernel_;
+  QuicEpollServer* epoll_server_;
+
+  StatsInterface* stats_;
+
+  int send_fd_;
+  int recv_fd_;
+
+  QuicMutex header_lock_;
+  icmp6_hdr icmp_header_ QUIC_GUARDED_BY(header_lock_){};
+
+  absl::Time start_ = absl::InfinitePast();
+  absl::Time end_ = absl::InfinitePast();
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_
diff --git a/quiche/quic/qbone/bonnet/icmp_reachable_interface.h b/quiche/quic/qbone/bonnet/icmp_reachable_interface.h
new file mode 100644
index 0000000..20bf489
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/icmp_reachable_interface.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
+#define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
+
+#include "quiche/quic/platform/api/quic_epoll.h"
+
+namespace quic {
+
+class IcmpReachableInterface : public QuicEpollAlarmBase {
+ public:
+  IcmpReachableInterface() = default;
+
+  IcmpReachableInterface(const IcmpReachableInterface&) = delete;
+  IcmpReachableInterface& operator=(const IcmpReachableInterface&) = delete;
+
+  IcmpReachableInterface(IcmpReachableInterface&&) = delete;
+  IcmpReachableInterface& operator=(IcmpReachableInterface&&) = delete;
+
+  // Initializes this reachability probe.
+  virtual bool Init() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_INTERFACE_H_
diff --git a/quiche/quic/qbone/bonnet/icmp_reachable_test.cc b/quiche/quic/qbone/bonnet/icmp_reachable_test.cc
new file mode 100644
index 0000000..ffb1092
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/icmp_reachable_test.cc
@@ -0,0 +1,267 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/icmp_reachable.h"
+
+#include <netinet/ip6.h>
+
+#include "absl/container/node_hash_map.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/platform/mock_kernel.h"
+
+namespace quic {
+namespace {
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+constexpr char kSourceAddress[] = "fe80:1:2:3:4::1";
+constexpr char kDestinationAddress[] = "fe80:4:3:2:1::1";
+
+constexpr int kFakeWriteFd = 0;
+
+icmp6_hdr GetHeaderFromPacket(const void* buf, size_t len) {
+  QUICHE_CHECK_GE(len, sizeof(ip6_hdr) + sizeof(icmp6_hdr));
+
+  auto* buffer = reinterpret_cast<const char*>(buf);
+  return *reinterpret_cast<const icmp6_hdr*>(&buffer[sizeof(ip6_hdr)]);
+}
+
+class StatsInterface : public IcmpReachable::StatsInterface {
+ public:
+  void OnEvent(IcmpReachable::ReachableEvent event) override {
+    switch (event.status) {
+      case IcmpReachable::REACHABLE: {
+        reachable_count_++;
+        break;
+      }
+      case IcmpReachable::UNREACHABLE: {
+        unreachable_count_++;
+        break;
+      }
+    }
+    current_source_ = event.source;
+  }
+
+  void OnReadError(int error) override { read_errors_[error]++; }
+
+  void OnWriteError(int error) override { write_errors_[error]++; }
+
+  bool HasWriteErrors() { return !write_errors_.empty(); }
+
+  int WriteErrorCount(int error) { return write_errors_[error]; }
+
+  bool HasReadErrors() { return !read_errors_.empty(); }
+
+  int ReadErrorCount(int error) { return read_errors_[error]; }
+
+  int reachable_count() { return reachable_count_; }
+
+  int unreachable_count() { return unreachable_count_; }
+
+  std::string current_source() { return current_source_; }
+
+ private:
+  int reachable_count_ = 0;
+  int unreachable_count_ = 0;
+
+  std::string current_source_{};
+
+  absl::node_hash_map<int, int> read_errors_;
+  absl::node_hash_map<int, int> write_errors_;
+};
+
+class IcmpReachableTest : public QuicTest {
+ public:
+  IcmpReachableTest() {
+    QUICHE_CHECK(source_.FromString(kSourceAddress));
+    QUICHE_CHECK(destination_.FromString(kDestinationAddress));
+
+    int pipe_fds[2];
+    QUICHE_CHECK(pipe(pipe_fds) >= 0) << "pipe() failed";
+
+    read_fd_ = pipe_fds[0];
+    read_src_fd_ = pipe_fds[1];
+  }
+
+  void SetFdExpectations() {
+    InSequence seq;
+    EXPECT_CALL(kernel_, socket(_, _, _)).WillOnce(Return(kFakeWriteFd));
+    EXPECT_CALL(kernel_, bind(kFakeWriteFd, _, _)).WillOnce(Return(0));
+
+    EXPECT_CALL(kernel_, socket(_, _, _)).WillOnce(Return(read_fd_));
+    EXPECT_CALL(kernel_, bind(read_fd_, _, _)).WillOnce(Return(0));
+
+    EXPECT_CALL(kernel_, setsockopt(read_fd_, SOL_ICMPV6, ICMP6_FILTER, _, _));
+
+    EXPECT_CALL(kernel_, close(read_fd_)).WillOnce(Invoke([](int fd) {
+      return close(fd);
+    }));
+  }
+
+ protected:
+  QuicIpAddress source_;
+  QuicIpAddress destination_;
+
+  int read_fd_;
+  int read_src_fd_;
+
+  StrictMock<MockKernel> kernel_;
+  QuicEpollServer epoll_server_;
+  StatsInterface stats_;
+};
+
+TEST_F(IcmpReachableTest, SendsPings) {
+  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
+                          &epoll_server_, &stats_);
+
+  SetFdExpectations();
+  ASSERT_TRUE(reachable.Init());
+
+  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
+      .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
+                          const struct sockaddr* dest_addr, socklen_t addrlen) {
+        auto icmp_header = GetHeaderFromPacket(buf, len);
+        EXPECT_EQ(icmp_header.icmp6_type, ICMP6_ECHO_REQUEST);
+        EXPECT_EQ(icmp_header.icmp6_seq, 1);
+        return len;
+      }));
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(stats_.HasWriteErrors());
+
+  epoll_server_.Shutdown();
+}
+
+TEST_F(IcmpReachableTest, HandlesUnreachableEvents) {
+  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
+                          &epoll_server_, &stats_);
+
+  SetFdExpectations();
+  ASSERT_TRUE(reachable.Init());
+
+  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
+      .Times(2)
+      .WillRepeatedly(Invoke([](int sockfd, const void* buf, size_t len,
+                                int flags, const struct sockaddr* dest_addr,
+                                socklen_t addrlen) { return len; }));
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(stats_.unreachable_count(), 0);
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(stats_.HasWriteErrors());
+  EXPECT_EQ(stats_.unreachable_count(), 1);
+  EXPECT_EQ(stats_.current_source(), kNoSource);
+
+  epoll_server_.Shutdown();
+}
+
+TEST_F(IcmpReachableTest, HandlesReachableEvents) {
+  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
+                          &epoll_server_, &stats_);
+
+  SetFdExpectations();
+  ASSERT_TRUE(reachable.Init());
+
+  icmp6_hdr last_request_hdr{};
+  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
+      .Times(2)
+      .WillRepeatedly(
+          Invoke([&last_request_hdr](
+                     int sockfd, const void* buf, size_t len, int flags,
+                     const struct sockaddr* dest_addr, socklen_t addrlen) {
+            last_request_hdr = GetHeaderFromPacket(buf, len);
+            return len;
+          }));
+
+  sockaddr_in6 source_addr{};
+  std::string packed_source = source_.ToPackedString();
+  memcpy(&source_addr.sin6_addr, packed_source.data(), packed_source.size());
+
+  EXPECT_CALL(kernel_, recvfrom(read_fd_, _, _, _, _, _))
+      .WillOnce(
+          Invoke([&source_addr](int sockfd, void* buf, size_t len, int flags,
+                                struct sockaddr* src_addr, socklen_t* addrlen) {
+            *reinterpret_cast<sockaddr_in6*>(src_addr) = source_addr;
+            return read(sockfd, buf, len);
+          }));
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(stats_.reachable_count(), 0);
+
+  icmp6_hdr response = last_request_hdr;
+  response.icmp6_type = ICMP6_ECHO_REPLY;
+
+  write(read_src_fd_, reinterpret_cast<const void*>(&response),
+        sizeof(icmp6_hdr));
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_FALSE(stats_.HasReadErrors());
+  EXPECT_FALSE(stats_.HasWriteErrors());
+  EXPECT_EQ(stats_.reachable_count(), 1);
+  EXPECT_EQ(stats_.current_source(), source_.ToString());
+
+  epoll_server_.Shutdown();
+}
+
+TEST_F(IcmpReachableTest, HandlesWriteErrors) {
+  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
+                          &epoll_server_, &stats_);
+
+  SetFdExpectations();
+  ASSERT_TRUE(reachable.Init());
+
+  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
+      .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
+                          const struct sockaddr* dest_addr, socklen_t addrlen) {
+        errno = EAGAIN;
+        return 0;
+      }));
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(stats_.WriteErrorCount(EAGAIN), 1);
+
+  epoll_server_.Shutdown();
+}
+
+TEST_F(IcmpReachableTest, HandlesReadErrors) {
+  IcmpReachable reachable(source_, destination_, absl::ZeroDuration(), &kernel_,
+                          &epoll_server_, &stats_);
+
+  SetFdExpectations();
+  ASSERT_TRUE(reachable.Init());
+
+  EXPECT_CALL(kernel_, sendto(kFakeWriteFd, _, _, _, _, _))
+      .WillOnce(Invoke([](int sockfd, const void* buf, size_t len, int flags,
+                          const struct sockaddr* dest_addr,
+                          socklen_t addrlen) { return len; }));
+
+  EXPECT_CALL(kernel_, recvfrom(read_fd_, _, _, _, _, _))
+      .WillOnce(Invoke([](int sockfd, void* buf, size_t len, int flags,
+                          struct sockaddr* src_addr, socklen_t* addrlen) {
+        errno = EIO;
+        return -1;
+      }));
+
+  icmp6_hdr response{};
+
+  write(read_src_fd_, reinterpret_cast<const void*>(&response),
+        sizeof(icmp6_hdr));
+
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(stats_.reachable_count(), 0);
+  EXPECT_EQ(stats_.ReadErrorCount(EIO), 1);
+
+  epoll_server_.Shutdown();
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/mock_icmp_reachable.h b/quiche/quic/qbone/bonnet/mock_icmp_reachable.h
new file mode 100644
index 0000000..13c294f
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/mock_icmp_reachable.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
+#define QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/icmp_reachable_interface.h"
+
+namespace quic {
+
+class MockIcmpReachable : public IcmpReachableInterface {
+ public:
+  MOCK_METHOD(bool, Init, (), (override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_ICMP_REACHABLE_H_
diff --git a/quiche/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h b/quiche/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
new file mode 100644
index 0000000..0048790
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
+#define QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h"
+
+namespace quic {
+
+class MockPacketExchangerStatsInterface
+    : public TunDevicePacketExchanger::StatsInterface {
+ public:
+  MOCK_METHOD(void, OnPacketRead, (size_t), (override));
+  MOCK_METHOD(void, OnPacketWritten, (size_t), (override));
+  MOCK_METHOD(void, OnReadError, (std::string*), (override));
+  MOCK_METHOD(void, OnWriteError, (std::string*), (override));
+
+  MOCK_METHOD(int64_t, PacketsRead, (), (const, override));
+  MOCK_METHOD(int64_t, PacketsWritten, (), (const, override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
diff --git a/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h b/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h
new file mode 100644
index 0000000..207ae29
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
+#define QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/qbone_tunnel_interface.h"
+
+namespace quic {
+
+class MockQboneTunnel : public QboneTunnelInterface {
+ public:
+  MockQboneTunnel() = default;
+
+  MOCK_METHOD(bool, WaitForEvents, (), (override));
+
+  MOCK_METHOD(void, Wake, (), (override));
+
+  MOCK_METHOD(void, ResetTunnel, (), (override));
+
+  MOCK_METHOD(State, Disconnect, (), (override));
+
+  MOCK_METHOD(void, OnControlRequest, (const quic::QboneClientRequest&),
+              (override));
+
+  MOCK_METHOD(void, OnControlError, (), (override));
+
+  MOCK_METHOD(bool, AwaitConnection, ());
+
+  MOCK_METHOD(std::string, StateToString, (State), (override));
+
+  MOCK_METHOD(quic::QboneClient*, client, (), (override));
+
+  MOCK_METHOD(State, state, ());
+
+  MOCK_METHOD(std::string, HealthString, ());
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_QBONE_TUNNEL_H_
diff --git a/quiche/quic/qbone/bonnet/mock_tun_device.h b/quiche/quic/qbone/bonnet/mock_tun_device.h
new file mode 100644
index 0000000..b712db5
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/mock_tun_device.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
+#define QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/tun_device_interface.h"
+
+namespace quic {
+
+class MockTunDevice : public TunDeviceInterface {
+ public:
+  MOCK_METHOD(bool, Init, (), (override));
+
+  MOCK_METHOD(bool, Up, (), (override));
+
+  MOCK_METHOD(bool, Down, (), (override));
+
+  MOCK_METHOD(void, CloseDevice, (), (override));
+
+  MOCK_METHOD(int, GetFileDescriptor, (), (const, override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_H_
diff --git a/quiche/quic/qbone/bonnet/mock_tun_device_controller.h b/quiche/quic/qbone/bonnet/mock_tun_device_controller.h
new file mode 100644
index 0000000..60ea0b6
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/mock_tun_device_controller.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
+#define QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/tun_device_controller.h"
+
+namespace quic {
+
+class MockTunDeviceController : public TunDeviceController {
+ public:
+  MockTunDeviceController() : TunDeviceController("", true, nullptr) {}
+
+  MOCK_METHOD(bool, UpdateAddress, (const IpRange&), (override));
+
+  MOCK_METHOD(bool, UpdateRoutes, (const IpRange&, const std::vector<IpRange>&),
+              (override));
+
+  MOCK_METHOD(QuicIpAddress, current_address, (), (override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_TUN_DEVICE_CONTROLLER_H_
diff --git a/quiche/quic/qbone/bonnet/qbone_tunnel_info.cc b/quiche/quic/qbone/bonnet/qbone_tunnel_info.cc
new file mode 100644
index 0000000..0958956
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/qbone_tunnel_info.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/qbone_tunnel_info.h"
+
+namespace quic {
+
+QuicIpAddress QboneTunnelInfo::GetAddress() {
+  QuicIpAddress no_address;
+
+  NetlinkInterface::LinkInfo link_info{};
+  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
+    return no_address;
+  }
+
+  std::vector<NetlinkInterface::AddressInfo> addresses;
+  if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
+    return no_address;
+  }
+
+  quic::QuicIpAddress link_local_subnet;
+  if (!link_local_subnet.FromString("FE80::")) {
+    return no_address;
+  }
+
+  for (const auto& address : addresses) {
+    if (address.interface_address.IsInitialized() &&
+        !link_local_subnet.InSameSubnet(address.interface_address, 10)) {
+      return address.interface_address;
+    }
+  }
+
+  return no_address;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/qbone_tunnel_info.h b/quiche/quic/qbone/bonnet/qbone_tunnel_info.h
new file mode 100644
index 0000000..d928ba7
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/qbone_tunnel_info.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
+#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+
+namespace quic {
+
+class QboneTunnelInfo {
+ public:
+  QboneTunnelInfo(std::string ifname, NetlinkInterface* netlink)
+      : ifname_(std::move(ifname)), netlink_(netlink) {}
+
+  // Returns the current QBONE tunnel address. Callers must use IsInitialized()
+  // to ensure the returned address is valid.
+  QuicIpAddress GetAddress();
+
+ private:
+  const std::string ifname_;
+  NetlinkInterface* netlink_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INFO_H_
diff --git a/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h b/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h
new file mode 100644
index 0000000..deb3b37
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
+#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
+
+#include "quiche/quic/qbone/qbone_client.h"
+
+namespace quic {
+
+// Interface for establishing bidirectional communication between a network
+// device and a QboneClient.
+class QboneTunnelInterface : public quic::QboneClientControlStream::Handler {
+ public:
+  QboneTunnelInterface() = default;
+
+  QboneTunnelInterface(const QboneTunnelInterface&) = delete;
+  QboneTunnelInterface& operator=(const QboneTunnelInterface&) = delete;
+
+  QboneTunnelInterface(QboneTunnelInterface&&) = delete;
+  QboneTunnelInterface& operator=(QboneTunnelInterface&&) = delete;
+
+  enum State {
+    UNINITIALIZED,
+    IP_RANGE_REQUESTED,
+    START_REQUESTED,
+    STARTED,
+    LAME_DUCK_REQUESTED,
+    END_REQUESTED,
+    ENDED,
+    FAILED,
+  };
+
+  // Wait and handle any events which occur.
+  // Returns true if there are any outstanding requests.
+  virtual bool WaitForEvents() = 0;
+
+  // Wakes the tunnel if it is currently in WaitForEvents.
+  virtual void Wake() = 0;
+
+  // Disconnect the tunnel, resetting it to an uninitialized state. This will
+  // force ConnectIfNeeded to reconnect on the next epoll cycle.
+  virtual void ResetTunnel() = 0;
+
+  // Disconnect from the QBONE server.
+  virtual State Disconnect() = 0;
+
+  // Callback handling responses from the QBONE server.
+  void OnControlRequest(const QboneClientRequest& request) override = 0;
+
+  // Callback handling bad responses from the QBONE server. Currently, this is
+  // only called when the response is unparsable.
+  void OnControlError() override = 0;
+
+  // Returns a string value of the given state.
+  virtual std::string StateToString(State state) = 0;
+
+  virtual QboneClient* client() = 0;
+
+  virtual State state() = 0;
+
+  virtual std::string HealthString() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_INTERFACE_H_
diff --git a/quiche/quic/qbone/bonnet/qbone_tunnel_silo.cc b/quiche/quic/qbone/bonnet/qbone_tunnel_silo.cc
new file mode 100644
index 0000000..1448d10
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/qbone_tunnel_silo.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/qbone_tunnel_silo.h"
+
+namespace quic {
+
+void QboneTunnelSilo::Run() {
+  while (ShouldRun()) {
+    tunnel_->WaitForEvents();
+  }
+
+  QUIC_LOG(INFO) << "Tunnel has disconnected in state: "
+                 << tunnel_->StateToString(tunnel_->Disconnect());
+}
+
+void QboneTunnelSilo::Quit() {
+  QUIC_LOG(INFO) << "Quit called on QboneTunnelSilo";
+  quitting_.Notify();
+  tunnel_->Wake();
+}
+
+bool QboneTunnelSilo::ShouldRun() {
+  bool post_init_shutdown_ready =
+      only_setup_tun_ &&
+      tunnel_->state() == quic::QboneTunnelInterface::STARTED;
+  return !quitting_.HasBeenNotified() && !post_init_shutdown_ready;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/qbone_tunnel_silo.h b/quiche/quic/qbone/bonnet/qbone_tunnel_silo.h
new file mode 100644
index 0000000..5e34783
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/qbone_tunnel_silo.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
+#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
+
+#include "absl/synchronization/notification.h"
+#include "quiche/quic/platform/api/quic_thread.h"
+#include "quiche/quic/qbone/bonnet/qbone_tunnel_interface.h"
+
+namespace quic {
+
+// QboneTunnelSilo is a thread that initializes and evaluates a QboneTunnel's
+// event loop.
+class QboneTunnelSilo : public QuicThread {
+ public:
+  // Does not take ownership of |tunnel|
+  explicit QboneTunnelSilo(QboneTunnelInterface* tunnel, bool only_setup_tun)
+      : QuicThread("QboneTunnelSilo"),
+        tunnel_(tunnel),
+        only_setup_tun_(only_setup_tun) {}
+
+  QboneTunnelSilo(const QboneTunnelSilo&) = delete;
+  QboneTunnelSilo& operator=(const QboneTunnelSilo&) = delete;
+
+  QboneTunnelSilo(QboneTunnelSilo&&) = delete;
+  QboneTunnelSilo& operator=(QboneTunnelSilo&&) = delete;
+
+  // Terminates the tunnel's event loop. This silo must still be joined.
+  void Quit();
+
+ protected:
+  void Run() override;
+
+ private:
+  bool ShouldRun();
+
+  QboneTunnelInterface* tunnel_;
+
+  absl::Notification quitting_;
+
+  const bool only_setup_tun_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
diff --git a/quiche/quic/qbone/bonnet/qbone_tunnel_silo_test.cc b/quiche/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
new file mode 100644
index 0000000..4fe967a
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
@@ -0,0 +1,78 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/qbone_tunnel_silo.h"
+
+#include "absl/synchronization/notification.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/mock_qbone_tunnel.h"
+
+namespace quic {
+namespace {
+
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::Return;
+
+TEST(QboneTunnelSiloTest, SiloRunsEventLoop) {
+  MockQboneTunnel mock_tunnel;
+
+  absl::Notification event_loop_run;
+  EXPECT_CALL(mock_tunnel, WaitForEvents)
+      .WillRepeatedly(Invoke([&event_loop_run]() {
+        if (!event_loop_run.HasBeenNotified()) {
+          event_loop_run.Notify();
+        }
+        return false;
+      }));
+
+  QboneTunnelSilo silo(&mock_tunnel, false);
+  silo.Start();
+
+  event_loop_run.WaitForNotification();
+
+  absl::Notification client_disconnected;
+  EXPECT_CALL(mock_tunnel, Disconnect)
+      .WillOnce(Invoke([&client_disconnected]() {
+        client_disconnected.Notify();
+        return QboneTunnelInterface::ENDED;
+      }));
+
+  silo.Quit();
+  client_disconnected.WaitForNotification();
+
+  silo.Join();
+}
+
+TEST(QboneTunnelSiloTest, SiloCanShutDownAfterInit) {
+  MockQboneTunnel mock_tunnel;
+
+  int iteration_count = 0;
+  EXPECT_CALL(mock_tunnel, WaitForEvents)
+      .WillRepeatedly(Invoke([&iteration_count]() {
+        iteration_count++;
+        return false;
+      }));
+
+  EXPECT_CALL(mock_tunnel, state)
+      .WillOnce(Return(QboneTunnelInterface::START_REQUESTED))
+      .WillOnce(Return(QboneTunnelInterface::STARTED));
+
+  absl::Notification client_disconnected;
+  EXPECT_CALL(mock_tunnel, Disconnect)
+      .WillOnce(Invoke([&client_disconnected]() {
+        client_disconnected.Notify();
+        return QboneTunnelInterface::ENDED;
+      }));
+
+  QboneTunnelSilo silo(&mock_tunnel, true);
+  silo.Start();
+
+  client_disconnected.WaitForNotification();
+  silo.Join();
+  EXPECT_THAT(iteration_count, Eq(1));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/tun_device.cc b/quiche/quic/qbone/bonnet/tun_device.cc
new file mode 100644
index 0000000..85a25fa
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device.cc
@@ -0,0 +1,219 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/tun_device.h"
+
+#include <fcntl.h>
+#include <linux/if_tun.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include "absl/cleanup/cleanup.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+
+ABSL_FLAG(std::string,
+          qbone_client_tun_device_path,
+          "/dev/net/tun",
+          "The path to the QBONE client's TUN device.");
+
+namespace quic {
+
+const int kInvalidFd = -1;
+
+TunTapDevice::TunTapDevice(const std::string& interface_name, int mtu,
+                           bool persist, bool setup_tun, bool is_tap,
+                           KernelInterface* kernel)
+    : interface_name_(interface_name),
+      mtu_(mtu),
+      persist_(persist),
+      setup_tun_(setup_tun),
+      is_tap_(is_tap),
+      file_descriptor_(kInvalidFd),
+      kernel_(*kernel) {}
+
+TunTapDevice::~TunTapDevice() {
+  if (!persist_) {
+    Down();
+  }
+  CloseDevice();
+}
+
+bool TunTapDevice::Init() {
+  if (interface_name_.empty() || interface_name_.size() >= IFNAMSIZ) {
+    QUIC_BUG(quic_bug_10995_1)
+        << "interface_name must be nonempty and shorter than " << IFNAMSIZ;
+    return false;
+  }
+
+  if (!OpenDevice()) {
+    return false;
+  }
+
+  if (!ConfigureInterface()) {
+    return false;
+  }
+
+  return true;
+}
+
+// TODO(pengg): might be better to use netlink socket, once we have a library to
+// use
+bool TunTapDevice::Up() {
+  if (!setup_tun_) {
+    return true;
+  }
+  struct ifreq if_request;
+  memset(&if_request, 0, sizeof(if_request));
+  // copy does not zero-terminate the result string, but we've memset the
+  // entire struct.
+  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
+  if_request.ifr_flags = IFF_UP;
+
+  return NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
+}
+
+// TODO(pengg): might be better to use netlink socket, once we have a library to
+// use
+bool TunTapDevice::Down() {
+  if (!setup_tun_) {
+    return true;
+  }
+  struct ifreq if_request;
+  memset(&if_request, 0, sizeof(if_request));
+  // copy does not zero-terminate the result string, but we've memset the
+  // entire struct.
+  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
+  if_request.ifr_flags = 0;
+
+  return NetdeviceIoctl(SIOCSIFFLAGS, reinterpret_cast<void*>(&if_request));
+}
+
+int TunTapDevice::GetFileDescriptor() const { return file_descriptor_; }
+
+bool TunTapDevice::OpenDevice() {
+  if (file_descriptor_ != kInvalidFd) {
+    CloseDevice();
+  }
+
+  struct ifreq if_request;
+  memset(&if_request, 0, sizeof(if_request));
+  // copy does not zero-terminate the result string, but we've memset the entire
+  // struct.
+  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
+
+  // Always set IFF_MULTI_QUEUE since a persistent device does not allow this
+  // flag to be flipped when re-opening it. The only way to flip this flag is to
+  // destroy the device and create a new one, but that deletes any existing
+  // routing associated with the interface, which makes the meaning of the
+  // 'persist' bit ambiguous.
+  if_request.ifr_flags = IFF_MULTI_QUEUE | IFF_NO_PI;
+  if (is_tap_) {
+    if_request.ifr_flags |= IFF_TAP;
+  } else {
+    if_request.ifr_flags |= IFF_TUN;
+  }
+
+  // When the device is running with IFF_MULTI_QUEUE set, each call to open will
+  // create a queue which can be used to read/write packets from/to the device.
+  bool successfully_opened = false;
+  auto cleanup = absl::MakeCleanup([this, &successfully_opened]() {
+    if (!successfully_opened) {
+      CloseDevice();
+    }
+  });
+
+  const std::string tun_device_path =
+      absl::GetFlag(FLAGS_qbone_client_tun_device_path);
+  int fd = kernel_.open(tun_device_path.c_str(), O_RDWR);
+  if (fd < 0) {
+    QUIC_PLOG(WARNING) << "Failed to open " << tun_device_path;
+    return successfully_opened;
+  }
+  file_descriptor_ = fd;
+  if (!CheckFeatures(fd)) {
+    return successfully_opened;
+  }
+
+  if (kernel_.ioctl(fd, TUNSETIFF, reinterpret_cast<void*>(&if_request)) != 0) {
+    QUIC_PLOG(WARNING) << "Failed to TUNSETIFF on fd(" << fd << ")";
+    return successfully_opened;
+  }
+
+  if (kernel_.ioctl(
+          fd, TUNSETPERSIST,
+          persist_ ? reinterpret_cast<void*>(&if_request) : nullptr) != 0) {
+    QUIC_PLOG(WARNING) << "Failed to TUNSETPERSIST on fd(" << fd << ")";
+    return successfully_opened;
+  }
+
+  successfully_opened = true;
+  return successfully_opened;
+}
+
+// TODO(pengg): might be better to use netlink socket, once we have a library to
+// use
+bool TunTapDevice::ConfigureInterface() {
+  if (!setup_tun_) {
+    return true;
+  }
+
+  struct ifreq if_request;
+  memset(&if_request, 0, sizeof(if_request));
+  // copy does not zero-terminate the result string, but we've memset the entire
+  // struct.
+  interface_name_.copy(if_request.ifr_name, IFNAMSIZ);
+  if_request.ifr_mtu = mtu_;
+
+  if (!NetdeviceIoctl(SIOCSIFMTU, reinterpret_cast<void*>(&if_request))) {
+    CloseDevice();
+    return false;
+  }
+
+  return true;
+}
+
+bool TunTapDevice::CheckFeatures(int tun_device_fd) {
+  unsigned int actual_features;
+  if (kernel_.ioctl(tun_device_fd, TUNGETFEATURES, &actual_features) != 0) {
+    QUIC_PLOG(WARNING) << "Failed to TUNGETFEATURES";
+    return false;
+  }
+  unsigned int required_features = IFF_TUN | IFF_NO_PI;
+  if ((required_features & actual_features) != required_features) {
+    QUIC_LOG(WARNING)
+        << "Required feature does not exist. required_features: 0x" << std::hex
+        << required_features << " vs actual_features: 0x" << std::hex
+        << actual_features;
+    return false;
+  }
+  return true;
+}
+
+bool TunTapDevice::NetdeviceIoctl(int request, void* argp) {
+  int fd = kernel_.socket(AF_INET6, SOCK_DGRAM, 0);
+  if (fd < 0) {
+    QUIC_PLOG(WARNING) << "Failed to create AF_INET6 socket.";
+    return false;
+  }
+
+  if (kernel_.ioctl(fd, request, argp) != 0) {
+    QUIC_PLOG(WARNING) << "Failed ioctl request: " << request;
+    kernel_.close(fd);
+    return false;
+  }
+  kernel_.close(fd);
+  return true;
+}
+
+void TunTapDevice::CloseDevice() {
+  if (file_descriptor_ != kInvalidFd) {
+    kernel_.close(file_descriptor_);
+    file_descriptor_ = kInvalidFd;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/tun_device.h b/quiche/quic/qbone/bonnet/tun_device.h
new file mode 100644
index 0000000..ccc22cb
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
+#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
+
+#include <string>
+#include <vector>
+
+#include "quiche/quic/qbone/bonnet/tun_device_interface.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+
+namespace quic {
+
+class TunTapDevice : public TunDeviceInterface {
+ public:
+  // This represents a tun device created in the OS kernel, which is a virtual
+  // network interface that any packets sent to it can be read by a user space
+  // program that owns it. The routing rule that routes packets to this
+  // interface should be defined somewhere else.
+  //
+  // Standard read/write system calls can be used to receive/send packets
+  // from/to this interface. The file descriptor is owned by this class.
+  //
+  // If persist is set to true, the device won't be deleted even after
+  // destructing. The device will be picked up when initializing this class with
+  // the same interface_name on the next time.
+  //
+  // Persisting the device is useful if one wants to keep the routing rules
+  // since once a tun device is destroyed by the kernel, all the associated
+  // routing rules go away.
+  //
+  // The caller should own kernel and make sure it outlives this.
+  TunTapDevice(const std::string& interface_name, int mtu, bool persist,
+               bool setup_tun, bool is_tap, KernelInterface* kernel);
+
+  ~TunTapDevice() override;
+
+  // Actually creates/reopens and configures the device.
+  bool Init() override;
+
+  // Marks the interface up to start receiving packets.
+  bool Up() override;
+
+  // Marks the interface down to stop receiving packets.
+  bool Down() override;
+
+  // Closes the open file descriptor for the TUN device (if one exists).
+  // It is safe to reinitialize and reuse this TunTapDevice after calling
+  // CloseDevice.
+  void CloseDevice() override;
+
+  // Gets the file descriptor that can be used to send/receive packets.
+  // This returns -1 when the TUN device is in an invalid state.
+  int GetFileDescriptor() const override;
+
+ private:
+  // Creates or reopens the tun device.
+  bool OpenDevice();
+
+  // Configure the interface.
+  bool ConfigureInterface();
+
+  // Checks if the required kernel features exists.
+  bool CheckFeatures(int tun_device_fd);
+
+  // Opens a socket and makes netdevice ioctl call
+  bool NetdeviceIoctl(int request, void* argp);
+
+  const std::string interface_name_;
+  const int mtu_;
+  const bool persist_;
+  const bool setup_tun_;
+  const bool is_tap_;
+  int file_descriptor_;
+  KernelInterface& kernel_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_H_
diff --git a/quiche/quic/qbone/bonnet/tun_device_controller.cc b/quiche/quic/qbone/bonnet/tun_device_controller.cc
new file mode 100644
index 0000000..6ec912f
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_controller.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/tun_device_controller.h"
+
+#include <linux/rtnetlink.h>
+
+#include "absl/time/clock.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+
+ABSL_FLAG(bool, qbone_tun_device_replace_default_routing_rules, true,
+          "If true, will define a rule that points packets sourced from the "
+          "qbone interface to the qbone table. This is unnecessary in "
+          "environments with no other ipv6 route.");
+
+namespace quic {
+
+bool TunDeviceController::UpdateAddress(const IpRange& desired_range) {
+  if (!setup_tun_) {
+    return true;
+  }
+
+  NetlinkInterface::LinkInfo link_info{};
+  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
+    return false;
+  }
+
+  std::vector<NetlinkInterface::AddressInfo> addresses;
+  if (!netlink_->GetAddresses(link_info.index, 0, &addresses, nullptr)) {
+    return false;
+  }
+
+  QuicIpAddress desired_address = desired_range.FirstAddressInRange();
+
+  for (const auto& address : addresses) {
+    if (!netlink_->ChangeLocalAddress(
+            link_info.index, NetlinkInterface::Verb::kRemove,
+            address.interface_address, address.prefix_length, 0, 0, {})) {
+      return false;
+    }
+  }
+
+  bool address_updated = netlink_->ChangeLocalAddress(
+      link_info.index, NetlinkInterface::Verb::kAdd, desired_address,
+      desired_range.prefix_length(), IFA_F_PERMANENT | IFA_F_NODAD,
+      RT_SCOPE_LINK, {});
+
+  if (address_updated) {
+    current_address_ = desired_address;
+
+    for (const auto& cb : address_update_cbs_) {
+      cb(current_address_);
+    }
+  }
+
+  return address_updated;
+}
+
+bool TunDeviceController::UpdateRoutes(
+    const IpRange& desired_range,
+    const std::vector<IpRange>& desired_routes) {
+  if (!setup_tun_) {
+    return true;
+  }
+
+  NetlinkInterface::LinkInfo link_info{};
+  if (!netlink_->GetLinkInfo(ifname_, &link_info)) {
+    QUIC_LOG(ERROR) << "Could not get link info for interface <" << ifname_
+                    << ">";
+    return false;
+  }
+
+  std::vector<NetlinkInterface::RoutingRule> routing_rules;
+  if (!netlink_->GetRouteInfo(&routing_rules)) {
+    QUIC_LOG(ERROR) << "Unable to get route info";
+    return false;
+  }
+
+  for (const auto& rule : routing_rules) {
+    if (rule.out_interface == link_info.index &&
+        rule.table == QboneConstants::kQboneRouteTableId) {
+      if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kRemove,
+                                 rule.table, rule.destination_subnet,
+                                 rule.scope, rule.preferred_source,
+                                 rule.out_interface)) {
+        QUIC_LOG(ERROR) << "Unable to remove old route to <"
+                        << rule.destination_subnet.ToString() << ">";
+        return false;
+      }
+    }
+  }
+
+  if (!UpdateRules(desired_range)) {
+    return false;
+  }
+
+  QuicIpAddress desired_address = desired_range.FirstAddressInRange();
+
+  std::vector<IpRange> routes(desired_routes.begin(), desired_routes.end());
+  routes.emplace_back(*QboneConstants::TerminatorLocalAddressRange());
+
+  for (const auto& route : routes) {
+    if (!netlink_->ChangeRoute(NetlinkInterface::Verb::kReplace,
+                               QboneConstants::kQboneRouteTableId, route,
+                               RT_SCOPE_LINK, desired_address,
+                               link_info.index)) {
+      QUIC_LOG(ERROR) << "Unable to add route <" << route.ToString() << ">";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool TunDeviceController::UpdateRoutesWithRetries(
+    const IpRange& desired_range,
+    const std::vector<IpRange>& desired_routes,
+    int retries) {
+  while (retries-- > 0) {
+    if (UpdateRoutes(desired_range, desired_routes)) {
+      return true;
+    }
+    absl::SleepFor(absl::Milliseconds(100));
+  }
+  return false;
+}
+
+bool TunDeviceController::UpdateRules(IpRange desired_range) {
+  if (!absl::GetFlag(FLAGS_qbone_tun_device_replace_default_routing_rules)) {
+    return true;
+  }
+
+  std::vector<NetlinkInterface::IpRule> ip_rules;
+  if (!netlink_->GetRuleInfo(&ip_rules)) {
+    QUIC_LOG(ERROR) << "Unable to get rule info";
+    return false;
+  }
+
+  for (const auto& rule : ip_rules) {
+    if (rule.table == QboneConstants::kQboneRouteTableId) {
+      if (!netlink_->ChangeRule(NetlinkInterface::Verb::kRemove,
+                                rule.table, rule.source_range)) {
+        QUIC_LOG(ERROR) << "Unable to remove old rule for table <" << rule.table
+                        << "> from source <" << rule.source_range.ToString()
+                        << ">";
+        return false;
+      }
+    }
+  }
+
+  if (!netlink_->ChangeRule(NetlinkInterface::Verb::kAdd,
+                            QboneConstants::kQboneRouteTableId,
+                            desired_range)) {
+    QUIC_LOG(ERROR) << "Unable to add rule for <" << desired_range.ToString()
+                    << ">";
+    return false;
+  }
+
+  return true;
+}
+
+QuicIpAddress TunDeviceController::current_address() {
+  return current_address_;
+}
+
+void TunDeviceController::RegisterAddressUpdateCallback(
+    const std::function<void(QuicIpAddress)>& cb) {
+  address_update_cbs_.push_back(cb);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/tun_device_controller.h b/quiche/quic/qbone/bonnet/tun_device_controller.h
new file mode 100644
index 0000000..633ec60
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_controller.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
+#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
+
+#include "quiche/quic/qbone/bonnet/tun_device.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+#include "quiche/quic/qbone/qbone_control.pb.h"
+#include "quiche/quic/qbone/qbone_control_stream.h"
+
+namespace quic {
+
+// TunDeviceController consumes control stream messages from a Qbone server
+// and applies the given updates to the TUN device.
+class TunDeviceController {
+ public:
+  // |ifname| is the interface name of the TUN device to be managed. This does
+  // not take ownership of |netlink|.
+  TunDeviceController(std::string ifname, bool setup_tun,
+                      NetlinkInterface* netlink)
+      : ifname_(std::move(ifname)), setup_tun_(setup_tun), netlink_(netlink) {}
+
+  TunDeviceController(const TunDeviceController&) = delete;
+  TunDeviceController& operator=(const TunDeviceController&) = delete;
+
+  TunDeviceController(TunDeviceController&&) = delete;
+  TunDeviceController& operator=(TunDeviceController&&) = delete;
+
+  virtual ~TunDeviceController() = default;
+
+  // Updates the local address of the TUN device to be the first address in the
+  // given |response.ip_range()|.
+  virtual bool UpdateAddress(const IpRange& desired_range);
+
+  // Updates the set of routes that the TUN device will provide. All current
+  // routes for the tunnel that do not exist in the |response| will be removed.
+  virtual bool UpdateRoutes(const IpRange& desired_range,
+                            const std::vector<IpRange>& desired_routes);
+
+  // Same as UpdateRoutes, but will wait and retry up to the number of times
+  // given by |retries| before giving up. This is an unpleasant workaround to
+  // deal with older kernels that aren't always able to set a route with a
+  // source address immediately after adding the address to the interface.
+  //
+  // TODO(b/179430548): Remove this once we've root-caused the underlying issue.
+  virtual bool UpdateRoutesWithRetries(
+      const IpRange& desired_range,
+      const std::vector<IpRange>& desired_routes,
+      int retries);
+
+  virtual void RegisterAddressUpdateCallback(
+      const std::function<void(QuicIpAddress)>& cb);
+
+  virtual QuicIpAddress current_address();
+
+ private:
+  // Update the IP Rules, this should only be used by UpdateRoutes.
+  bool UpdateRules(IpRange desired_range);
+
+  const std::string ifname_;
+  const bool setup_tun_;
+
+  NetlinkInterface* netlink_;
+
+  QuicIpAddress current_address_;
+
+  std::vector<std::function<void(QuicIpAddress)>> address_update_cbs_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_
diff --git a/quiche/quic/qbone/bonnet/tun_device_controller_test.cc b/quiche/quic/qbone/bonnet/tun_device_controller_test.cc
new file mode 100644
index 0000000..7b5bb51
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_controller_test.cc
@@ -0,0 +1,262 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/tun_device_controller.h"
+
+#include <linux/if_addr.h>
+#include <linux/rtnetlink.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/platform/mock_netlink.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+
+ABSL_DECLARE_FLAG(bool, qbone_tun_device_replace_default_routing_rules);
+
+namespace quic {
+namespace {
+using ::testing::Eq;
+
+constexpr int kIfindex = 42;
+constexpr char kIfname[] = "qbone0";
+
+const IpRange kIpRange = []() {
+  IpRange range;
+  QCHECK(range.FromString("2604:31c0:2::/64"));
+  return range;
+}();
+
+constexpr char kOldAddress[] = "1.2.3.4";
+constexpr int kOldPrefixLen = 24;
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+MATCHER_P(IpRangeEq, range,
+          absl::StrCat("expected IpRange to equal ", range.ToString())) {
+  return arg == range;
+}
+
+class TunDeviceControllerTest : public QuicTest {
+ public:
+  TunDeviceControllerTest()
+      : controller_(kIfname, true, &netlink_),
+        link_local_range_(*QboneConstants::TerminatorLocalAddressRange()) {
+    controller_.RegisterAddressUpdateCallback(
+        [this](QuicIpAddress address) { notified_address_ = address; });
+  }
+
+ protected:
+  void ExpectLinkInfo(const std::string& interface_name, int ifindex) {
+    EXPECT_CALL(netlink_, GetLinkInfo(interface_name, _))
+        .WillOnce(
+            Invoke([ifindex](absl::string_view ifname,
+                             NetlinkInterface::LinkInfo* link_info) {
+              link_info->index = ifindex;
+              return true;
+            }));
+  }
+
+  MockNetlink netlink_;
+  TunDeviceController controller_;
+  QuicIpAddress notified_address_;
+
+  IpRange link_local_range_;
+};
+
+TEST_F(TunDeviceControllerTest, AddressAppliedWhenNoneExisted) {
+  ExpectLinkInfo(kIfname, kIfindex);
+
+  EXPECT_CALL(netlink_, GetAddresses(kIfindex, _, _, _)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_,
+              ChangeLocalAddress(
+                  kIfindex, NetlinkInterface::Verb::kAdd,
+                  kIpRange.FirstAddressInRange(), kIpRange.prefix_length(),
+                  IFA_F_PERMANENT | IFA_F_NODAD, RT_SCOPE_LINK, _))
+      .WillOnce(Return(true));
+
+  EXPECT_TRUE(controller_.UpdateAddress(kIpRange));
+  EXPECT_THAT(notified_address_, Eq(kIpRange.FirstAddressInRange()));
+}
+
+TEST_F(TunDeviceControllerTest, OldAddressesAreRemoved) {
+  ExpectLinkInfo(kIfname, kIfindex);
+
+  EXPECT_CALL(netlink_, GetAddresses(kIfindex, _, _, _))
+      .WillOnce(
+          Invoke([](int interface_index, uint8_t unwanted_flags,
+                    std::vector<NetlinkInterface::AddressInfo>* addresses,
+                    int* num_ipv6_nodad_dadfailed_addresses) {
+            NetlinkInterface::AddressInfo info{};
+            info.interface_address.FromString(kOldAddress);
+            info.prefix_length = kOldPrefixLen;
+            addresses->emplace_back(info);
+            return true;
+          }));
+
+  QuicIpAddress old_address;
+  old_address.FromString(kOldAddress);
+
+  EXPECT_CALL(netlink_, ChangeLocalAddress(
+                            kIfindex, NetlinkInterface::Verb::kRemove,
+                            old_address, kOldPrefixLen, _, _, _))
+      .WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_,
+              ChangeLocalAddress(
+                  kIfindex, NetlinkInterface::Verb::kAdd,
+                  kIpRange.FirstAddressInRange(), kIpRange.prefix_length(),
+                  IFA_F_PERMANENT | IFA_F_NODAD, RT_SCOPE_LINK, _))
+      .WillOnce(Return(true));
+
+  EXPECT_TRUE(controller_.UpdateAddress(kIpRange));
+  EXPECT_THAT(notified_address_, Eq(kIpRange.FirstAddressInRange()));
+}
+
+TEST_F(TunDeviceControllerTest, UpdateRoutesRemovedOldRoutes) {
+  ExpectLinkInfo(kIfname, kIfindex);
+
+  const int num_matching_routes = 3;
+  EXPECT_CALL(netlink_, GetRouteInfo(_))
+      .WillOnce(Invoke(
+          [](std::vector<NetlinkInterface::RoutingRule>* routing_rules) {
+            NetlinkInterface::RoutingRule non_matching_route;
+            non_matching_route.table = QboneConstants::kQboneRouteTableId;
+            non_matching_route.out_interface = kIfindex + 1;
+            routing_rules->push_back(non_matching_route);
+
+            NetlinkInterface::RoutingRule matching_route;
+            matching_route.table = QboneConstants::kQboneRouteTableId;
+            matching_route.out_interface = kIfindex;
+            for (int i = 0; i < num_matching_routes; i++) {
+              routing_rules->push_back(matching_route);
+            }
+
+            NetlinkInterface::RoutingRule non_matching_table;
+            non_matching_table.table =
+                QboneConstants::kQboneRouteTableId + 1;
+            non_matching_table.out_interface = kIfindex;
+            routing_rules->push_back(non_matching_table);
+            return true;
+          }));
+
+  EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kRemove,
+                                    QboneConstants::kQboneRouteTableId, _,
+                                    _, _, kIfindex))
+      .Times(num_matching_routes)
+      .WillRepeatedly(Return(true));
+
+  EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
+                                   QboneConstants::kQboneRouteTableId,
+                                   IpRangeEq(kIpRange)))
+      .WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_,
+              ChangeRoute(NetlinkInterface::Verb::kReplace,
+                          QboneConstants::kQboneRouteTableId,
+                          IpRangeEq(link_local_range_), _, _, kIfindex))
+      .WillOnce(Return(true));
+
+  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {}));
+}
+
+TEST_F(TunDeviceControllerTest, UpdateRoutesAddsNewRoutes) {
+  ExpectLinkInfo(kIfname, kIfindex);
+
+  EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kReplace,
+                                    QboneConstants::kQboneRouteTableId,
+                                    IpRangeEq(kIpRange), _, _, kIfindex))
+      .Times(2)
+      .WillRepeatedly(Return(true))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
+                                   QboneConstants::kQboneRouteTableId,
+                                   IpRangeEq(kIpRange)))
+      .WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_,
+              ChangeRoute(NetlinkInterface::Verb::kReplace,
+                          QboneConstants::kQboneRouteTableId,
+                          IpRangeEq(link_local_range_), _, _, kIfindex))
+      .WillOnce(Return(true));
+
+  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {kIpRange, kIpRange}));
+}
+
+TEST_F(TunDeviceControllerTest, EmptyUpdateRouteKeepsLinkLocalRoute) {
+  ExpectLinkInfo(kIfname, kIfindex);
+
+  EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_, GetRuleInfo(_)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_, ChangeRule(NetlinkInterface::Verb::kAdd,
+                                   QboneConstants::kQboneRouteTableId,
+                                   IpRangeEq(kIpRange)))
+      .WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_,
+              ChangeRoute(NetlinkInterface::Verb::kReplace,
+                          QboneConstants::kQboneRouteTableId,
+                          IpRangeEq(link_local_range_), _, _, kIfindex))
+      .WillOnce(Return(true));
+
+  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {}));
+}
+
+TEST_F(TunDeviceControllerTest, DisablingRoutingRulesSkipsRuleCreation) {
+  absl::SetFlag(&FLAGS_qbone_tun_device_replace_default_routing_rules, false);
+  ExpectLinkInfo(kIfname, kIfindex);
+
+  EXPECT_CALL(netlink_, GetRouteInfo(_)).WillOnce(Return(true));
+
+  EXPECT_CALL(netlink_, ChangeRoute(NetlinkInterface::Verb::kReplace,
+                                    QboneConstants::kQboneRouteTableId,
+                                    IpRangeEq(kIpRange), _, _, kIfindex))
+      .Times(2)
+      .WillRepeatedly(Return(true))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(netlink_,
+              ChangeRoute(NetlinkInterface::Verb::kReplace,
+                          QboneConstants::kQboneRouteTableId,
+                          IpRangeEq(link_local_range_), _, _, kIfindex))
+      .WillOnce(Return(true));
+
+  EXPECT_TRUE(controller_.UpdateRoutes(kIpRange, {kIpRange, kIpRange}));
+}
+
+class DisabledTunDeviceControllerTest : public QuicTest {
+ public:
+  DisabledTunDeviceControllerTest()
+      : controller_(kIfname, false, &netlink_),
+        link_local_range_(
+            *QboneConstants::TerminatorLocalAddressRange()) {}
+
+  StrictMock<MockNetlink> netlink_;
+  TunDeviceController controller_;
+
+  IpRange link_local_range_;
+};
+
+TEST_F(DisabledTunDeviceControllerTest, UpdateRoutesIsNop) {
+  EXPECT_THAT(controller_.UpdateRoutes(kIpRange, {}), Eq(true));
+}
+
+TEST_F(DisabledTunDeviceControllerTest, UpdateAddressIsNop) {
+  EXPECT_THAT(controller_.UpdateAddress(kIpRange), Eq(true));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device_interface.h b/quiche/quic/qbone/bonnet/tun_device_interface.h
similarity index 100%
rename from quic/qbone/bonnet/tun_device_interface.h
rename to quiche/quic/qbone/bonnet/tun_device_interface.h
diff --git a/quiche/quic/qbone/bonnet/tun_device_packet_exchanger.cc b/quiche/quic/qbone/bonnet/tun_device_packet_exchanger.cc
new file mode 100644
index 0000000..6c9cb06
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_packet_exchanger.cc
@@ -0,0 +1,230 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h"
+
+#include <netinet/icmp6.h>
+#include <netinet/ip6.h>
+
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+
+namespace quic {
+
+TunDevicePacketExchanger::TunDevicePacketExchanger(
+    size_t mtu, KernelInterface* kernel, NetlinkInterface* netlink,
+    QbonePacketExchanger::Visitor* visitor, size_t max_pending_packets,
+    bool is_tap, StatsInterface* stats, absl::string_view ifname)
+    : QbonePacketExchanger(visitor, max_pending_packets),
+      mtu_(mtu),
+      kernel_(kernel),
+      netlink_(netlink),
+      ifname_(ifname),
+      is_tap_(is_tap),
+      stats_(stats) {
+  if (is_tap_) {
+    mtu_ += ETH_HLEN;
+  }
+}
+
+bool TunDevicePacketExchanger::WritePacket(const char* packet, size_t size,
+                                           bool* blocked, std::string* error) {
+  *blocked = false;
+  if (fd_ < 0) {
+    *error = absl::StrCat("Invalid file descriptor of the TUN device: ", fd_);
+    stats_->OnWriteError(error);
+    return false;
+  }
+
+  auto buffer = std::make_unique<QuicData>(packet, size);
+  if (is_tap_) {
+    buffer = ApplyL2Headers(*buffer);
+  }
+  int result = kernel_->write(fd_, buffer->data(), buffer->length());
+  if (result == -1) {
+    if (errno == EWOULDBLOCK || errno == EAGAIN) {
+      // The tunnel is blocked. Note that this does not mean the receive buffer
+      // of a TCP connection is filled. This simply means the TUN device itself
+      // is blocked on handing packets to the rest part of the kernel.
+      *error = absl::StrCat("Write to the TUN device was blocked: ", errno);
+      *blocked = true;
+      stats_->OnWriteError(error);
+    }
+    return false;
+  }
+  stats_->OnPacketWritten(result);
+
+  return true;
+}
+
+std::unique_ptr<QuicData> TunDevicePacketExchanger::ReadPacket(
+    bool* blocked, std::string* error) {
+  *blocked = false;
+  if (fd_ < 0) {
+    *error = absl::StrCat("Invalid file descriptor of the TUN device: ", fd_);
+    stats_->OnReadError(error);
+    return nullptr;
+  }
+  // Reading on a TUN device returns a packet at a time. If the packet is longer
+  // than the buffer, it's truncated.
+  auto read_buffer = std::make_unique<char[]>(mtu_);
+  int result = kernel_->read(fd_, read_buffer.get(), mtu_);
+  // Note that 0 means end of file, but we're talking about a TUN device - there
+  // is no end of file. Therefore 0 also indicates error.
+  if (result <= 0) {
+    if (errno == EAGAIN || errno == EWOULDBLOCK) {
+      *error = absl::StrCat("Read from the TUN device was blocked: ", errno);
+      *blocked = true;
+      stats_->OnReadError(error);
+    }
+    return nullptr;
+  }
+
+  auto buffer = std::make_unique<QuicData>(read_buffer.release(), result, true);
+  if (is_tap_) {
+    buffer = ConsumeL2Headers(*buffer);
+  }
+  if (buffer) {
+    stats_->OnPacketRead(buffer->length());
+  }
+  return buffer;
+}
+
+void TunDevicePacketExchanger::set_file_descriptor(int fd) { fd_ = fd; }
+
+const TunDevicePacketExchanger::StatsInterface*
+TunDevicePacketExchanger::stats_interface() const {
+  return stats_;
+}
+
+std::unique_ptr<QuicData> TunDevicePacketExchanger::ApplyL2Headers(
+    const QuicData& l3_packet) {
+  if (is_tap_ && !mac_initialized_) {
+    NetlinkInterface::LinkInfo link_info{};
+    if (netlink_->GetLinkInfo(ifname_, &link_info)) {
+      memcpy(tap_mac_, link_info.hardware_address, ETH_ALEN);
+      mac_initialized_ = true;
+    } else {
+      QUIC_LOG_EVERY_N_SEC(ERROR, 30)
+          << "Unable to get link info for: " << ifname_;
+    }
+  }
+
+  const auto l2_packet_size = l3_packet.length() + ETH_HLEN;
+  auto l2_buffer = std::make_unique<char[]>(l2_packet_size);
+
+  // Populate the Ethernet header
+  auto* hdr = reinterpret_cast<ethhdr*>(l2_buffer.get());
+  // Set src & dst to my own address
+  memcpy(hdr->h_dest, tap_mac_, ETH_ALEN);
+  memcpy(hdr->h_source, tap_mac_, ETH_ALEN);
+  // Assume ipv6 for now
+  // TODO(b/195113643): Support additional protocols.
+  hdr->h_proto = absl::ghtons(ETH_P_IPV6);
+
+  // Copy the l3 packet into buffer, just after the ethernet header.
+  memcpy(l2_buffer.get() + ETH_HLEN, l3_packet.data(), l3_packet.length());
+
+  return std::make_unique<QuicData>(l2_buffer.release(), l2_packet_size, true);
+}
+
+std::unique_ptr<QuicData> TunDevicePacketExchanger::ConsumeL2Headers(
+    const QuicData& l2_packet) {
+  if (l2_packet.length() < ETH_HLEN) {
+    // Packet is too short for ethernet headers. Drop it.
+    return nullptr;
+  }
+  auto* hdr = reinterpret_cast<const ethhdr*>(l2_packet.data());
+  if (hdr->h_proto != absl::ghtons(ETH_P_IPV6)) {
+    return nullptr;
+  }
+  constexpr auto kIp6PrefixLen = ETH_HLEN + sizeof(ip6_hdr);
+  constexpr auto kIcmp6PrefixLen = kIp6PrefixLen + sizeof(icmp6_hdr);
+  if (l2_packet.length() < kIp6PrefixLen) {
+    // Packet is too short to be ipv6. Drop it.
+    return nullptr;
+  }
+  auto* ip_hdr = reinterpret_cast<const ip6_hdr*>(l2_packet.data() + ETH_HLEN);
+  const bool is_icmp = ip_hdr->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV6;
+
+  bool is_neighbor_solicit = false;
+  if (is_icmp) {
+    if (l2_packet.length() < kIcmp6PrefixLen) {
+      // Packet is too short to be icmp6. Drop it.
+      return nullptr;
+    }
+    is_neighbor_solicit =
+        reinterpret_cast<const icmp6_hdr*>(l2_packet.data() + kIp6PrefixLen)
+            ->icmp6_type == ND_NEIGHBOR_SOLICIT;
+  }
+
+  if (is_neighbor_solicit) {
+    // If we've received a neighbor solicitation, craft an advertisement to
+    // respond with and write it back to the local interface.
+    auto* icmp6_payload = l2_packet.data() + kIcmp6PrefixLen;
+
+    QuicIpAddress target_address(
+        *reinterpret_cast<const in6_addr*>(icmp6_payload));
+    if (target_address != *QboneConstants::GatewayAddress()) {
+      // Only respond to solicitations for our gateway address
+      return nullptr;
+    }
+
+    // Neighbor Advertisement crafted per:
+    // https://datatracker.ietf.org/doc/html/rfc4861#section-4.4
+    //
+    // Using the Target link-layer address option defined at:
+    // https://datatracker.ietf.org/doc/html/rfc4861#section-4.6.1
+    constexpr size_t kIcmpv6OptionSize = 8;
+    const int payload_size = sizeof(in6_addr) + kIcmpv6OptionSize;
+    auto payload = std::make_unique<char[]>(payload_size);
+    // Place the solicited IPv6 address at the beginning of the response payload
+    memcpy(payload.get(), icmp6_payload, sizeof(in6_addr));
+    // Setup the Target link-layer address option:
+    //      0                   1                   2                   3
+    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    // |     Type      |    Length     |    Link-Layer Address ...
+    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    int pos = sizeof(in6_addr);
+    payload[pos++] = ND_OPT_TARGET_LINKADDR;    // Type
+    payload[pos++] = 1;                         // Length in units of 8 octets
+    memcpy(&payload[pos], tap_mac_, ETH_ALEN);  // This interfaces' MAC address
+
+    // Populate the ICMPv6 header
+    icmp6_hdr response_hdr{};
+    response_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
+    // Set the solicited bit to true
+    response_hdr.icmp6_dataun.icmp6_un_data8[0] = 64;
+    // Craft the full ICMPv6 packet and then ship it off to WritePacket
+    // to have it frame it with L2 headers and send it back to the requesting
+    // neighbor.
+    CreateIcmpPacket(ip_hdr->ip6_src, ip_hdr->ip6_src, response_hdr,
+                     absl::string_view(payload.get(), payload_size),
+                     [this](absl::string_view packet) {
+                       bool blocked;
+                       std::string error;
+                       WritePacket(packet.data(), packet.size(), &blocked,
+                                   &error);
+                     });
+    // Do not forward the neighbor solicitation through the tunnel since it's
+    // link-local.
+    return nullptr;
+  }
+
+  // If this isn't a Neighbor Solicitation, remove the L2 headers and forward
+  // it as though it were an L3 packet.
+  const auto l3_packet_size = l2_packet.length() - ETH_HLEN;
+  auto shift_buffer = std::make_unique<char[]>(l3_packet_size);
+  memcpy(shift_buffer.get(), l2_packet.data() + ETH_HLEN, l3_packet_size);
+
+  return std::make_unique<QuicData>(shift_buffer.release(), l3_packet_size,
+                                    true);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h b/quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h
new file mode 100644
index 0000000..4751fb8
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
+#define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
+
+#include <linux/if_ether.h>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+#include "quiche/quic/qbone/qbone_client_interface.h"
+#include "quiche/quic/qbone/qbone_packet_exchanger.h"
+
+namespace quic {
+
+class TunDevicePacketExchanger : public QbonePacketExchanger {
+ public:
+  class StatsInterface {
+   public:
+    StatsInterface() = default;
+
+    StatsInterface(const StatsInterface&) = delete;
+    StatsInterface& operator=(const StatsInterface&) = delete;
+
+    StatsInterface(StatsInterface&&) = delete;
+    StatsInterface& operator=(StatsInterface&&) = delete;
+
+    virtual ~StatsInterface() = default;
+
+    virtual void OnPacketRead(size_t count) = 0;
+    virtual void OnPacketWritten(size_t count) = 0;
+    virtual void OnReadError(std::string* error) = 0;
+    virtual void OnWriteError(std::string* error) = 0;
+
+    ABSL_MUST_USE_RESULT virtual int64_t PacketsRead() const = 0;
+    ABSL_MUST_USE_RESULT virtual int64_t PacketsWritten() const = 0;
+  };
+
+  // |mtu| is the mtu of the TUN device.
+  // |kernel| is not owned but should out live objects of this class.
+  // |visitor| is not owned but should out live objects of this class.
+  // |max_pending_packets| controls the number of packets to be queued should
+  // the TUN device become blocked.
+  // |stats| is notified about packet read/write statistics. It is not owned,
+  // but should outlive objects of this class.
+  TunDevicePacketExchanger(size_t mtu, KernelInterface* kernel,
+                           NetlinkInterface* netlink,
+                           QbonePacketExchanger::Visitor* visitor,
+                           size_t max_pending_packets, bool is_tap,
+                           StatsInterface* stats, absl::string_view ifname);
+
+  void set_file_descriptor(int fd);
+
+  ABSL_MUST_USE_RESULT const StatsInterface* stats_interface() const;
+
+ private:
+  // From QbonePacketExchanger.
+  std::unique_ptr<QuicData> ReadPacket(bool* blocked,
+                                       std::string* error) override;
+
+  // From QbonePacketExchanger.
+  bool WritePacket(const char* packet,
+                   size_t size,
+                   bool* blocked,
+                   std::string* error) override;
+
+  std::unique_ptr<QuicData> ApplyL2Headers(const QuicData& l3_packet);
+
+  std::unique_ptr<QuicData> ConsumeL2Headers(const QuicData& l2_packet);
+
+  int fd_ = -1;
+  size_t mtu_;
+  KernelInterface* kernel_;
+  NetlinkInterface* netlink_;
+  const std::string ifname_;
+
+  const bool is_tap_;
+  uint8_t tap_mac_[ETH_ALEN]{};
+  bool mac_initialized_ = false;
+
+  StatsInterface* stats_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_PACKET_EXCHANGER_H_
diff --git a/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc b/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
new file mode 100644
index 0000000..f7bf062
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/tun_device_packet_exchanger.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h"
+#include "quiche/quic/qbone/mock_qbone_client.h"
+#include "quiche/quic/qbone/platform/mock_kernel.h"
+
+namespace quic {
+namespace {
+
+const size_t kMtu = 1000;
+const size_t kMaxPendingPackets = 5;
+const int kFd = 15;
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+class MockVisitor : public QbonePacketExchanger::Visitor {
+ public:
+  MOCK_METHOD(void, OnReadError, (const std::string&), (override));
+  MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
+};
+
+class TunDevicePacketExchangerTest : public QuicTest {
+ protected:
+  TunDevicePacketExchangerTest()
+      : exchanger_(kMtu, &mock_kernel_, nullptr, &mock_visitor_,
+                   kMaxPendingPackets, false, &mock_stats_,
+                   absl::string_view()) {
+    exchanger_.set_file_descriptor(kFd);
+  }
+
+  ~TunDevicePacketExchangerTest() override = default;
+
+  MockKernel mock_kernel_;
+  StrictMock<MockVisitor> mock_visitor_;
+  StrictMock<MockQboneClient> mock_client_;
+  StrictMock<MockPacketExchangerStatsInterface> mock_stats_;
+  TunDevicePacketExchanger exchanger_;
+};
+
+TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsFalseOnError) {
+  std::string packet = "fake packet";
+  EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
+      .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
+        errno = ECOMM;
+        return -1;
+      }));
+
+  EXPECT_CALL(mock_visitor_, OnWriteError(_));
+  exchanger_.WritePacketToNetwork(packet.data(), packet.size());
+}
+
+TEST_F(TunDevicePacketExchangerTest,
+       WritePacketReturnFalseAndBlockedOnBlockedTunnel) {
+  std::string packet = "fake packet";
+  EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
+      .WillOnce(Invoke([](int fd, const void* buf, size_t count) {
+        errno = EAGAIN;
+        return -1;
+      }));
+
+  EXPECT_CALL(mock_stats_, OnWriteError(_)).Times(1);
+  exchanger_.WritePacketToNetwork(packet.data(), packet.size());
+}
+
+TEST_F(TunDevicePacketExchangerTest, WritePacketReturnsTrueOnSuccessfulWrite) {
+  std::string packet = "fake packet";
+  EXPECT_CALL(mock_kernel_, write(kFd, _, packet.size()))
+      .WillOnce(Invoke([packet](int fd, const void* buf, size_t count) {
+        EXPECT_THAT(reinterpret_cast<const char*>(buf), StrEq(packet));
+        return count;
+      }));
+
+  EXPECT_CALL(mock_stats_, OnPacketWritten(_)).Times(1);
+  exchanger_.WritePacketToNetwork(packet.data(), packet.size());
+}
+
+TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnError) {
+  EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
+      .WillOnce(Invoke([](int fd, void* buf, size_t count) {
+        errno = ECOMM;
+        return -1;
+      }));
+  EXPECT_CALL(mock_visitor_, OnReadError(_));
+  exchanger_.ReadAndDeliverPacket(&mock_client_);
+}
+
+TEST_F(TunDevicePacketExchangerTest, ReadPacketReturnsNullOnBlockedRead) {
+  EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
+      .WillOnce(Invoke([](int fd, void* buf, size_t count) {
+        errno = EAGAIN;
+        return -1;
+      }));
+  EXPECT_CALL(mock_stats_, OnReadError(_)).Times(1);
+  EXPECT_FALSE(exchanger_.ReadAndDeliverPacket(&mock_client_));
+}
+
+TEST_F(TunDevicePacketExchangerTest,
+       ReadPacketReturnsThePacketOnSuccessfulRead) {
+  std::string packet = "fake_packet";
+  EXPECT_CALL(mock_kernel_, read(kFd, _, kMtu))
+      .WillOnce(Invoke([packet](int fd, void* buf, size_t count) {
+        memcpy(buf, packet.data(), packet.size());
+        return packet.size();
+      }));
+  EXPECT_CALL(mock_client_, ProcessPacketFromNetwork(StrEq(packet)));
+  EXPECT_CALL(mock_stats_, OnPacketRead(_)).Times(1);
+  EXPECT_TRUE(exchanger_.ReadAndDeliverPacket(&mock_client_));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/bonnet/tun_device_test.cc b/quiche/quic/qbone/bonnet/tun_device_test.cc
new file mode 100644
index 0000000..4af7b20
--- /dev/null
+++ b/quiche/quic/qbone/bonnet/tun_device_test.cc
@@ -0,0 +1,211 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/bonnet/tun_device.h"
+
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <sys/ioctl.h>
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/platform/mock_kernel.h"
+
+namespace quic {
+namespace {
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrEq;
+using ::testing::Unused;
+
+const char kDeviceName[] = "tun0";
+const int kSupportedFeatures =
+    IFF_TUN | IFF_TAP | IFF_MULTI_QUEUE | IFF_ONE_QUEUE | IFF_NO_PI;
+
+// Quite a bit of EXPECT_CALL().Times(AnyNumber()).WillRepeatedly() are used to
+// make sure we can correctly set common expectations and override the
+// expectation with later call to EXPECT_CALL(). ON_CALL cannot be used here
+// since when EPXECT_CALL overrides ON_CALL, it ignores the parameter matcher
+// which results in unexpected call even if ON_CALL exists.
+class TunDeviceTest : public QuicTest {
+ protected:
+  void SetUp() override {
+    EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([this](Unused, Unused, Unused) {
+          EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
+          return next_fd_++;
+        }));
+  }
+
+  // Set the expectations for calling Init().
+  void SetInitExpectations(int mtu, bool persist) {
+    EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([this](Unused, Unused) {
+          EXPECT_CALL(mock_kernel_, close(next_fd_)).WillOnce(Return(0));
+          return next_fd_++;
+        }));
+    EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
+          auto* actual_flags = reinterpret_cast<int*>(argp);
+          *actual_flags = kSupportedFeatures;
+          return 0;
+        }));
+    EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([](Unused, Unused, void* argp) {
+          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
+          EXPECT_EQ(IFF_TUN | IFF_MULTI_QUEUE | IFF_NO_PI, ifr->ifr_flags);
+          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
+          return 0;
+        }));
+    EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([persist](Unused, Unused, void* argp) {
+          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
+          if (persist) {
+            EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
+          } else {
+            EXPECT_EQ(nullptr, ifr);
+          }
+          return 0;
+        }));
+    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _))
+        .Times(AnyNumber())
+        .WillRepeatedly(Invoke([mtu](Unused, Unused, void* argp) {
+          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
+          EXPECT_EQ(mtu, ifr->ifr_mtu);
+          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
+          return 0;
+        }));
+  }
+
+  // Expect that Up() will be called. Force the call to fail when fail == true.
+  void ExpectUp(bool fail) {
+    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
+        .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
+          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
+          EXPECT_TRUE(ifr->ifr_flags & IFF_UP);
+          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
+          if (fail) {
+            return -1;
+          } else {
+            return 0;
+          }
+        }));
+  }
+
+  // Expect that Down() will be called *after* the interface is up. Force the
+  // call to fail when fail == true.
+  void ExpectDown(bool fail) {
+    EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFFLAGS, _))
+        .WillOnce(Invoke([fail](Unused, Unused, void* argp) {
+          auto* ifr = reinterpret_cast<struct ifreq*>(argp);
+          EXPECT_FALSE(ifr->ifr_flags & IFF_UP);
+          EXPECT_THAT(ifr->ifr_name, StrEq(kDeviceName));
+          if (fail) {
+            return -1;
+          } else {
+            return 0;
+          }
+        }));
+  }
+
+  MockKernel mock_kernel_;
+  int next_fd_ = 100;
+};
+
+// A TunTapDevice can be initialized and up
+TEST_F(TunDeviceTest, BasicWorkFlow) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
+  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
+  EXPECT_TRUE(tun_device.Init());
+  EXPECT_GT(tun_device.GetFileDescriptor(), -1);
+
+  ExpectUp(/* fail = */ false);
+  EXPECT_TRUE(tun_device.Up());
+  ExpectDown(/* fail = */ false);
+}
+
+TEST_F(TunDeviceTest, FailToOpenTunDevice) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
+  EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
+      .WillOnce(Return(-1));
+  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+  ExpectDown(false);
+}
+
+TEST_F(TunDeviceTest, FailToCheckFeature) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
+  EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _)).WillOnce(Return(-1));
+  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+  ExpectDown(false);
+}
+
+TEST_F(TunDeviceTest, TooFewFeature) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
+  EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _))
+      .WillOnce(Invoke([](Unused, Unused, void* argp) {
+        int* actual_features = reinterpret_cast<int*>(argp);
+        *actual_features = IFF_TUN | IFF_ONE_QUEUE;
+        return 0;
+      }));
+  TunTapDevice tun_device(kDeviceName, 1500, false, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+  ExpectDown(false);
+}
+
+TEST_F(TunDeviceTest, FailToSetFlag) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
+  EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _)).WillOnce(Return(-1));
+  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+}
+
+TEST_F(TunDeviceTest, FailToPersistDevice) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
+  EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _)).WillOnce(Return(-1));
+  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+}
+
+TEST_F(TunDeviceTest, FailToOpenSocket) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
+  EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _)).WillOnce(Return(-1));
+  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+}
+
+TEST_F(TunDeviceTest, FailToSetMtu) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
+  EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _)).WillOnce(Return(-1));
+  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
+  EXPECT_FALSE(tun_device.Init());
+  EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
+}
+
+TEST_F(TunDeviceTest, FailToUp) {
+  SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
+  TunTapDevice tun_device(kDeviceName, 1500, true, true, false, &mock_kernel_);
+  EXPECT_TRUE(tun_device.Init());
+  EXPECT_GT(tun_device.GetFileDescriptor(), -1);
+
+  ExpectUp(/* fail = */ true);
+  EXPECT_FALSE(tun_device.Up());
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/mock_qbone_client.h b/quiche/quic/qbone/mock_qbone_client.h
new file mode 100644
index 0000000..1283431
--- /dev/null
+++ b/quiche/quic/qbone/mock_qbone_client.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
+#define QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/qbone_client_interface.h"
+
+namespace quic {
+
+class MockQboneClient : public QboneClientInterface {
+ public:
+  MOCK_METHOD(void,
+              ProcessPacketFromNetwork,
+              (absl::string_view packet),
+              (override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_MOCK_QBONE_CLIENT_H_
diff --git a/quiche/quic/qbone/mock_qbone_server_session.h b/quiche/quic/qbone/mock_qbone_server_session.h
new file mode 100644
index 0000000..e889f97
--- /dev/null
+++ b/quiche/quic/qbone/mock_qbone_server_session.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
+#define QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/qbone_server_session.h"
+
+namespace quic {
+
+class MockQboneServerSession : public QboneServerSession {
+ public:
+  explicit MockQboneServerSession(QuicConnection* connection)
+      : QboneServerSession(CurrentSupportedVersions(),
+                           connection,
+                           /*owner=*/nullptr,
+                           /*config=*/{},
+                           /*quic_crypto_server_config=*/nullptr,
+                           /*compressed_certs_cache=*/nullptr,
+                           /*writer=*/nullptr,
+                           /*self_ip=*/QuicIpAddress::Loopback6(),
+                           /*client_ip=*/QuicIpAddress::Loopback6(),
+                           /*client_ip_subnet_length=*/0,
+                           /*handler=*/nullptr) {}
+
+  MOCK_METHOD(bool, SendClientRequest, (const QboneClientRequest&), (override));
+
+  MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override));
+  MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_MOCK_QBONE_SERVER_SESSION_H_
diff --git a/quiche/quic/qbone/platform/icmp_packet.cc b/quiche/quic/qbone/platform/icmp_packet.cc
new file mode 100644
index 0000000..6aab255
--- /dev/null
+++ b/quiche/quic/qbone/platform/icmp_packet.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+
+#include <netinet/ip6.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/qbone/platform/internet_checksum.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace {
+
+constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
+constexpr size_t kIPv6HeaderSize = sizeof(ip6_hdr);
+constexpr size_t kICMPv6HeaderSize = sizeof(icmp6_hdr);
+constexpr size_t kIPv6MinPacketSize = 1280;
+
+// Hop limit set to 255 to satisfy:
+// https://datatracker.ietf.org/doc/html/rfc4861#section-11.2
+constexpr size_t kIcmpTtl = 255;
+constexpr size_t kICMPv6BodyMaxSize =
+    kIPv6MinPacketSize - kIPv6HeaderSize - kICMPv6HeaderSize;
+
+struct ICMPv6Packet {
+  ip6_hdr ip_header;
+  icmp6_hdr icmp_header;
+  uint8_t body[kICMPv6BodyMaxSize];
+};
+
+// pseudo header as described in RFC 2460 Section 8.1 (excluding addresses)
+struct IPv6PseudoHeader {
+  uint32_t payload_size{};
+  uint8_t zeros[3] = {0, 0, 0};
+  uint8_t next_header = IPPROTO_ICMPV6;
+};
+
+}  // namespace
+
+void CreateIcmpPacket(in6_addr src,
+                      in6_addr dst,
+                      const icmp6_hdr& icmp_header,
+                      absl::string_view body,
+                      const std::function<void(absl::string_view)>& cb) {
+  const size_t body_size = std::min(body.size(), kICMPv6BodyMaxSize);
+  const size_t payload_size = kICMPv6HeaderSize + body_size;
+
+  ICMPv6Packet icmp_packet{};
+  // Set version to 6.
+  icmp_packet.ip_header.ip6_vfc = 0x6 << 4;
+  // Set the payload size, protocol and TTL.
+  icmp_packet.ip_header.ip6_plen =
+      quiche::QuicheEndian::HostToNet16(payload_size);
+  icmp_packet.ip_header.ip6_nxt = IPPROTO_ICMPV6;
+  icmp_packet.ip_header.ip6_hops = kIcmpTtl;
+  // Set the source address to the specified self IP.
+  icmp_packet.ip_header.ip6_src = src;
+  icmp_packet.ip_header.ip6_dst = dst;
+
+  icmp_packet.icmp_header = icmp_header;
+  // Per RFC 4443 Section 2.3, set checksum field to 0 prior to computing it
+  icmp_packet.icmp_header.icmp6_cksum = 0;
+
+  IPv6PseudoHeader pseudo_header{};
+  pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);
+
+  InternetChecksum checksum;
+  // Pseudoheader.
+  checksum.Update(icmp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
+  checksum.Update(icmp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
+  checksum.Update(reinterpret_cast<char*>(&pseudo_header),
+                  sizeof(pseudo_header));
+  // ICMP header.
+  checksum.Update(reinterpret_cast<const char*>(&icmp_packet.icmp_header),
+                  sizeof(icmp_packet.icmp_header));
+  // Body.
+  checksum.Update(body.data(), body_size);
+  icmp_packet.icmp_header.icmp6_cksum = checksum.Value();
+
+  memcpy(icmp_packet.body, body.data(), body_size);
+
+  const char* packet = reinterpret_cast<char*>(&icmp_packet);
+  const size_t packet_size = offsetof(ICMPv6Packet, body) + body_size;
+
+  cb(absl::string_view(packet, packet_size));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/icmp_packet.h b/quiche/quic/qbone/platform/icmp_packet.h
new file mode 100644
index 0000000..4ed365e
--- /dev/null
+++ b/quiche/quic/qbone/platform/icmp_packet.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
+
+#include <netinet/icmp6.h>
+#include <netinet/in.h>
+
+#include <functional>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+// Creates an ICMPv6 packet, returning a packed string representation of the
+// packet to |cb|. The resulting packet is given to a callback because it's
+// stack allocated inside CreateIcmpPacket.
+void CreateIcmpPacket(in6_addr src,
+                      in6_addr dst,
+                      const icmp6_hdr& icmp_header,
+                      absl::string_view body,
+                      const std::function<void(absl::string_view)>& cb);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_ICMP_PACKET_H_
diff --git a/quiche/quic/qbone/platform/icmp_packet_test.cc b/quiche/quic/qbone/platform/icmp_packet_test.cc
new file mode 100644
index 0000000..d944751
--- /dev/null
+++ b/quiche/quic/qbone/platform/icmp_packet_test.cc
@@ -0,0 +1,128 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+
+#include <netinet/ip6.h>
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+constexpr char kReferenceSourceAddress[] = "fe80:1:2:3:4::1";
+constexpr char kReferenceDestinationAddress[] = "fe80:4:3:2:1::1";
+
+// clang-format off
+constexpr  uint8_t kReferenceICMPMessageBody[] {
+    0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
+    0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
+};
+
+constexpr uint8_t kReferenceICMPPacket[] = {
+    // START IPv6 Header
+    // IPv6 with zero TOS and flow label.
+    0x60, 0x00, 0x00, 0x00,
+    // Payload is 64 bytes
+    0x00, 0x40,
+    // Next header is 58
+    0x3a,
+    // Hop limit is 255
+    0xFF,
+    // Source address of fe80:1:2:3:4::1
+    0xfe, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // Destination address of fe80:4:3:2:1::1
+    0xfe, 0x80, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // END IPv6 Header
+    // START ICMPv6 Header
+    // Echo Request, zero code
+    0x80, 0x00,
+    // Checksum
+    0xec, 0x00,
+    // Identifier
+    0xcb, 0x82,
+    // Sequence Number
+    0x00, 0x01,
+    // END ICMPv6 Header
+    // Message body
+    0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
+    0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
+};
+// clang-format on
+
+}  // namespace
+
+TEST(IcmpPacketTest, CreatedPacketMatchesReference) {
+  QuicIpAddress src;
+  ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
+  in6_addr src_addr;
+  memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));
+
+  QuicIpAddress dst;
+  ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
+  in6_addr dst_addr;
+  memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));
+
+  icmp6_hdr icmp_header{};
+  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
+  icmp_header.icmp6_id = 0x82cb;
+  icmp_header.icmp6_seq = 0x0100;
+
+  absl::string_view message_body = absl::string_view(
+      reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
+  absl::string_view expected_packet = absl::string_view(
+      reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
+  CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
+                   [&expected_packet](absl::string_view packet) {
+                     QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
+                     ASSERT_EQ(packet, expected_packet);
+                   });
+}
+
+TEST(IcmpPacketTest, NonZeroChecksumIsIgnored) {
+  QuicIpAddress src;
+  ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
+  in6_addr src_addr;
+  memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));
+
+  QuicIpAddress dst;
+  ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
+  in6_addr dst_addr;
+  memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));
+
+  icmp6_hdr icmp_header{};
+  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
+  icmp_header.icmp6_id = 0x82cb;
+  icmp_header.icmp6_seq = 0x0100;
+  // Set the checksum to a bogus value
+  icmp_header.icmp6_cksum = 0x1234;
+
+  absl::string_view message_body = absl::string_view(
+      reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
+  absl::string_view expected_packet = absl::string_view(
+      reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
+  CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
+                   [&expected_packet](absl::string_view packet) {
+                     QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
+                     ASSERT_EQ(packet, expected_packet);
+                   });
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/internet_checksum.cc b/quiche/quic/qbone/platform/internet_checksum.cc
new file mode 100644
index 0000000..e819f37
--- /dev/null
+++ b/quiche/quic/qbone/platform/internet_checksum.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/internet_checksum.h"
+
+namespace quic {
+
+void InternetChecksum::Update(const char* data, size_t size) {
+  const char* current;
+  for (current = data; current + 1 < data + size; current += 2) {
+    accumulator_ += *reinterpret_cast<const uint16_t*>(current);
+  }
+  if (current < data + size) {
+    accumulator_ += *reinterpret_cast<const uint8_t*>(current);
+  }
+}
+
+void InternetChecksum::Update(const uint8_t* data, size_t size) {
+  Update(reinterpret_cast<const char*>(data), size);
+}
+
+uint16_t InternetChecksum::Value() const {
+  uint32_t total = accumulator_;
+  while (total & 0xffff0000u) {
+    total = (total >> 16u) + (total & 0xffffu);
+  }
+  return ~static_cast<uint16_t>(total);
+}
+
+}  // namespace quic
diff --git a/quic/qbone/platform/internet_checksum.h b/quiche/quic/qbone/platform/internet_checksum.h
similarity index 100%
rename from quic/qbone/platform/internet_checksum.h
rename to quiche/quic/qbone/platform/internet_checksum.h
diff --git a/quiche/quic/qbone/platform/internet_checksum_test.cc b/quiche/quic/qbone/platform/internet_checksum_test.cc
new file mode 100644
index 0000000..8033c2e
--- /dev/null
+++ b/quiche/quic/qbone/platform/internet_checksum_test.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/internet_checksum.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+// From the Numerical Example described in RFC 1071
+// https://tools.ietf.org/html/rfc1071#section-3
+TEST(InternetChecksumTest, MatchesRFC1071Example) {
+  uint8_t data[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7};
+
+  InternetChecksum checksum;
+  checksum.Update(data, 8);
+  uint16_t result = checksum.Value();
+  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
+  ASSERT_EQ(0x22, result_bytes[0]);
+  ASSERT_EQ(0x0d, result_bytes[1]);
+}
+
+// Same as above, except 7 bytes. Should behave as if there was an 8th byte
+// that equals 0.
+TEST(InternetChecksumTest, MatchesRFC1071ExampleWithOddByteCount) {
+  uint8_t data[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6};
+
+  InternetChecksum checksum;
+  checksum.Update(data, 7);
+  uint16_t result = checksum.Value();
+  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
+  ASSERT_EQ(0x23, result_bytes[0]);
+  ASSERT_EQ(0x04, result_bytes[1]);
+}
+
+// From the example described at:
+// http://www.cs.berkeley.edu/~kfall/EE122/lec06/tsld023.htm
+TEST(InternetChecksumTest, MatchesBerkleyExample) {
+  uint8_t data[] = {0xe3, 0x4f, 0x23, 0x96, 0x44, 0x27, 0x99, 0xf3};
+
+  InternetChecksum checksum;
+  checksum.Update(data, 8);
+  uint16_t result = checksum.Value();
+  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
+  ASSERT_EQ(0x1a, result_bytes[0]);
+  ASSERT_EQ(0xff, result_bytes[1]);
+}
+
+TEST(InternetChecksumTest, ChecksumRequiringMultipleCarriesInLittleEndian) {
+  uint8_t data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00};
+
+  // Data will accumulate to 0x0002FFFF
+  // Summing lower and upper halves gives 0x00010001
+  // Second sum of lower and upper halves gives 0x0002
+  // One's complement gives 0xfffd, or [0xfd, 0xff] in network byte order
+  InternetChecksum checksum;
+  checksum.Update(data, 8);
+  uint16_t result = checksum.Value();
+  auto* result_bytes = reinterpret_cast<uint8_t*>(&result);
+  EXPECT_EQ(0xfd, result_bytes[0]);
+  EXPECT_EQ(0xff, result_bytes[1]);
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/ip_range.cc b/quiche/quic/qbone/platform/ip_range.cc
new file mode 100644
index 0000000..1a42acd
--- /dev/null
+++ b/quiche/quic/qbone/platform/ip_range.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/ip_range.h"
+
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+namespace {
+
+constexpr size_t kIPv4Size = 32;
+constexpr size_t kIPv6Size = 128;
+
+QuicIpAddress TruncateToLength(const QuicIpAddress& input,
+                               size_t* prefix_length) {
+  QuicIpAddress output;
+  if (input.IsIPv4()) {
+    if (*prefix_length > kIPv4Size) {
+      *prefix_length = kIPv4Size;
+      return input;
+    }
+    uint32_t raw_address =
+        *reinterpret_cast<const uint32_t*>(input.ToPackedString().data());
+    raw_address = quiche::QuicheEndian::NetToHost32(raw_address);
+    raw_address &= ~0U << (kIPv4Size - *prefix_length);
+    raw_address = quiche::QuicheEndian::HostToNet32(raw_address);
+    output.FromPackedString(reinterpret_cast<const char*>(&raw_address),
+                            sizeof(raw_address));
+    return output;
+  }
+  if (input.IsIPv6()) {
+    if (*prefix_length > kIPv6Size) {
+      *prefix_length = kIPv6Size;
+      return input;
+    }
+    uint64_t raw_address[2];
+    memcpy(raw_address, input.ToPackedString().data(), sizeof(raw_address));
+    // raw_address[0] holds higher 8 bytes in big endian and raw_address[1]
+    // holds lower 8 bytes. Converting each to little endian for us to mask bits
+    // out.
+    // The endianess between raw_address[0] and raw_address[1] is handled
+    // explicitly by handling lower and higher bytes separately.
+    raw_address[0] = quiche::QuicheEndian::NetToHost64(raw_address[0]);
+    raw_address[1] = quiche::QuicheEndian::NetToHost64(raw_address[1]);
+    if (*prefix_length <= kIPv6Size / 2) {
+      raw_address[0] &= ~uint64_t{0} << (kIPv6Size / 2 - *prefix_length);
+      raw_address[1] = 0;
+    } else {
+      raw_address[1] &= ~uint64_t{0} << (kIPv6Size - *prefix_length);
+    }
+    raw_address[0] = quiche::QuicheEndian::HostToNet64(raw_address[0]);
+    raw_address[1] = quiche::QuicheEndian::HostToNet64(raw_address[1]);
+    output.FromPackedString(reinterpret_cast<const char*>(raw_address),
+                            sizeof(raw_address));
+    return output;
+  }
+  return output;
+}
+
+}  // namespace
+
+IpRange::IpRange(const QuicIpAddress& prefix, size_t prefix_length)
+    : prefix_(prefix), prefix_length_(prefix_length) {
+  prefix_ = TruncateToLength(prefix_, &prefix_length_);
+}
+
+bool IpRange::operator==(IpRange other) const {
+  return prefix_ == other.prefix_ && prefix_length_ == other.prefix_length_;
+}
+
+bool IpRange::operator!=(IpRange other) const {
+  return !(*this == other);
+}
+
+bool IpRange::FromString(const std::string& range) {
+  size_t slash_pos = range.find('/');
+  if (slash_pos == std::string::npos) {
+    return false;
+  }
+  QuicIpAddress prefix;
+  bool success = prefix.FromString(range.substr(0, slash_pos));
+  if (!success) {
+    return false;
+  }
+  uint64_t num_processed = 0;
+  size_t prefix_length = std::stoi(range.substr(slash_pos + 1), &num_processed);
+  if (num_processed + 1 + slash_pos != range.length()) {
+    return false;
+  }
+  prefix_ = TruncateToLength(prefix, &prefix_length);
+  prefix_length_ = prefix_length;
+  return true;
+}
+
+QuicIpAddress IpRange::FirstAddressInRange() const {
+  return prefix();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/ip_range.h b/quiche/quic/qbone/platform/ip_range.h
new file mode 100644
index 0000000..fcffea6
--- /dev/null
+++ b/quiche/quic/qbone/platform/ip_range.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+
+namespace quic {
+
+class IpRange {
+ public:
+  // Default constructor to have an uninitialized IpRange.
+  IpRange() : prefix_length_(0) {}
+
+  // prefix will be automatically truncated to prefix_length, so that any bit
+  // after prefix_length are zero.
+  IpRange(const QuicIpAddress& prefix, size_t prefix_length);
+
+  bool operator==(IpRange other) const;
+  bool operator!=(IpRange other) const;
+
+  // Parses range that looks like "10.0.0.1/8". Tailing bits will be set to zero
+  // after prefix_length. Return false if the parsing failed.
+  bool FromString(const std::string& range);
+
+  // Returns the string representation of this object.
+  std::string ToString() const {
+    if (IsInitialized()) {
+      return absl::StrCat(prefix_.ToString(), "/", prefix_length_);
+    }
+    return "(uninitialized)";
+  }
+
+  // Whether this object is initialized.
+  bool IsInitialized() const { return prefix_.IsInitialized(); }
+
+  // Returns the first available IP address in this IpRange. The resulting
+  // address will be uninitialized if there is no available address.
+  QuicIpAddress FirstAddressInRange() const;
+
+  // The address family of this IpRange.
+  IpAddressFamily address_family() const { return prefix_.address_family(); }
+
+  // The subnet's prefix address.
+  QuicIpAddress prefix() const { return prefix_; }
+
+  // The subnet's prefix length.
+  size_t prefix_length() const { return prefix_length_; }
+
+ private:
+  QuicIpAddress prefix_;
+  size_t prefix_length_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_IP_RANGE_H_
diff --git a/quiche/quic/qbone/platform/ip_range_test.cc b/quiche/quic/qbone/platform/ip_range_test.cc
new file mode 100644
index 0000000..a0444ea
--- /dev/null
+++ b/quiche/quic/qbone/platform/ip_range_test.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/ip_range.h"
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+TEST(IpRangeTest, TruncateWorksIPv4) {
+  QuicIpAddress before_truncate;
+  before_truncate.FromString("255.255.255.255");
+  EXPECT_EQ("128.0.0.0/1", IpRange(before_truncate, 1).ToString());
+  EXPECT_EQ("192.0.0.0/2", IpRange(before_truncate, 2).ToString());
+  EXPECT_EQ("255.224.0.0/11", IpRange(before_truncate, 11).ToString());
+  EXPECT_EQ("255.255.255.224/27", IpRange(before_truncate, 27).ToString());
+  EXPECT_EQ("255.255.255.254/31", IpRange(before_truncate, 31).ToString());
+  EXPECT_EQ("255.255.255.255/32", IpRange(before_truncate, 32).ToString());
+  EXPECT_EQ("255.255.255.255/32", IpRange(before_truncate, 33).ToString());
+}
+
+TEST(IpRangeTest, TruncateWorksIPv6) {
+  QuicIpAddress before_truncate;
+  before_truncate.FromString("ffff:ffff:ffff:ffff:f903::5");
+  EXPECT_EQ("fe00::/7", IpRange(before_truncate, 7).ToString());
+  EXPECT_EQ("ffff:ffff:ffff::/48", IpRange(before_truncate, 48).ToString());
+  EXPECT_EQ("ffff:ffff:ffff:ffff::/64",
+            IpRange(before_truncate, 64).ToString());
+  EXPECT_EQ("ffff:ffff:ffff:ffff:8000::/65",
+            IpRange(before_truncate, 65).ToString());
+  EXPECT_EQ("ffff:ffff:ffff:ffff:f903::4/127",
+            IpRange(before_truncate, 127).ToString());
+}
+
+TEST(IpRangeTest, FromStringWorksIPv4) {
+  IpRange range;
+  ASSERT_TRUE(range.FromString("127.0.3.249/26"));
+  EXPECT_EQ("127.0.3.192/26", range.ToString());
+}
+
+TEST(IpRangeTest, FromStringWorksIPv6) {
+  IpRange range;
+  ASSERT_TRUE(range.FromString("ff01:8f21:77f9::/33"));
+  EXPECT_EQ("ff01:8f21::/33", range.ToString());
+}
+
+TEST(IpRangeTest, FirstAddressWorksIPv6) {
+  IpRange range;
+  ASSERT_TRUE(range.FromString("ffff:ffff::/64"));
+  QuicIpAddress first_address = range.FirstAddressInRange();
+  EXPECT_EQ("ffff:ffff::", first_address.ToString());
+}
+
+TEST(IpRangeTest, FirstAddressWorksIPv4) {
+  IpRange range;
+  ASSERT_TRUE(range.FromString("10.0.0.0/24"));
+  QuicIpAddress first_address = range.FirstAddressInRange();
+  EXPECT_EQ("10.0.0.0", first_address.ToString());
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quic/qbone/platform/kernel_interface.h b/quiche/quic/qbone/platform/kernel_interface.h
similarity index 100%
rename from quic/qbone/platform/kernel_interface.h
rename to quiche/quic/qbone/platform/kernel_interface.h
diff --git a/quiche/quic/qbone/platform/mock_kernel.h b/quiche/quic/qbone/platform/mock_kernel.h
new file mode 100644
index 0000000..cfa6572
--- /dev/null
+++ b/quiche/quic/qbone/platform/mock_kernel.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+
+namespace quic {
+
+class MockKernel : public KernelInterface {
+ public:
+  MockKernel() {}
+
+  MOCK_METHOD(int,
+              bind,
+              (int fd, const struct sockaddr*, socklen_t addr_len),
+              (override));
+  MOCK_METHOD(int, close, (int fd), (override));
+  MOCK_METHOD(int, ioctl, (int fd, int request, void*), (override));
+  MOCK_METHOD(int, open, (const char*, int flags), (override));
+  MOCK_METHOD(ssize_t, read, (int fd, void*, size_t count), (override));
+  MOCK_METHOD(
+      ssize_t,
+      recvfrom,
+      (int sockfd, void*, size_t len, int flags, struct sockaddr*, socklen_t*),
+      (override));
+  MOCK_METHOD(ssize_t,
+              sendmsg,
+              (int sockfd, const struct msghdr*, int flags),
+              (override));
+  MOCK_METHOD(ssize_t,
+              sendto,
+              (int sockfd,
+               const void*,
+               size_t len,
+               int flags,
+               const struct sockaddr*,
+               socklen_t addrlen),
+              (override));
+  MOCK_METHOD(int, socket, (int domain, int type, int protocol), (override));
+  MOCK_METHOD(int,
+              setsockopt,
+              (int, int, int, const void*, socklen_t),
+              (override));
+  MOCK_METHOD(ssize_t, write, (int fd, const void*, size_t count), (override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_MOCK_KERNEL_H_
diff --git a/quiche/quic/qbone/platform/mock_netlink.h b/quiche/quic/qbone/platform/mock_netlink.h
new file mode 100644
index 0000000..23e0885
--- /dev/null
+++ b/quiche/quic/qbone/platform/mock_netlink.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+
+namespace quic {
+
+class MockNetlink : public NetlinkInterface {
+ public:
+  MOCK_METHOD(bool, GetLinkInfo, (const std::string&, LinkInfo*), (override));
+
+  MOCK_METHOD(bool,
+              GetAddresses,
+              (int, uint8_t, std::vector<AddressInfo>*, int*),
+              (override));
+
+  MOCK_METHOD(bool,
+              ChangeLocalAddress,
+              (uint32_t,
+               Verb,
+               const QuicIpAddress&,
+               uint8_t,
+               uint8_t,
+               uint8_t,
+               const std::vector<struct rtattr*>&),
+              (override));
+
+  MOCK_METHOD(bool, GetRouteInfo, (std::vector<RoutingRule>*), (override));
+
+  MOCK_METHOD(bool,
+              ChangeRoute,
+              (Verb, uint32_t, const IpRange&, uint8_t, QuicIpAddress, int32_t),
+              (override));
+
+  MOCK_METHOD(bool, GetRuleInfo, (std::vector<IpRule>*), (override));
+
+  MOCK_METHOD(bool, ChangeRule, (Verb, uint32_t, IpRange), (override));
+
+  MOCK_METHOD(bool, Send, (struct iovec*, size_t), (override));
+
+  MOCK_METHOD(bool, Recv, (uint32_t, NetlinkParserInterface*), (override));
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_MOCK_NETLINK_H_
diff --git a/quiche/quic/qbone/platform/netlink.cc b/quiche/quic/qbone/platform/netlink.cc
new file mode 100644
index 0000000..ab5743c
--- /dev/null
+++ b/quiche/quic/qbone/platform/netlink.cc
@@ -0,0 +1,837 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/netlink.h"
+
+#include <linux/fib_rules.h>
+
+#include <utility>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/qbone/platform/rtnetlink_message.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+
+namespace quic {
+
+Netlink::Netlink(KernelInterface* kernel) : kernel_(kernel) {
+  seq_ = QuicRandom::GetInstance()->RandUint64();
+}
+
+Netlink::~Netlink() {
+  CloseSocket();
+}
+
+void Netlink::ResetRecvBuf(size_t size) {
+  if (size != 0) {
+    recvbuf_ = std::make_unique<char[]>(size);
+  } else {
+    recvbuf_ = nullptr;
+  }
+  recvbuf_length_ = size;
+}
+
+bool Netlink::OpenSocket() {
+  if (socket_fd_ >= 0) {
+    return true;
+  }
+
+  socket_fd_ = kernel_->socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+
+  if (socket_fd_ < 0) {
+    QUIC_PLOG(ERROR) << "can't open netlink socket";
+    return false;
+  }
+
+  QUIC_LOG(INFO) << "Opened a new netlink socket fd = " << socket_fd_;
+
+  // bind a local address to the socket
+  sockaddr_nl myaddr;
+  memset(&myaddr, 0, sizeof(myaddr));
+  myaddr.nl_family = AF_NETLINK;
+  if (kernel_->bind(socket_fd_, reinterpret_cast<struct sockaddr*>(&myaddr),
+                    sizeof(myaddr)) < 0) {
+    QUIC_LOG(INFO) << "can't bind address to socket";
+    CloseSocket();
+    return false;
+  }
+
+  return true;
+}
+
+void Netlink::CloseSocket() {
+  if (socket_fd_ >= 0) {
+    QUIC_LOG(INFO) << "Closing netlink socket fd = " << socket_fd_;
+    kernel_->close(socket_fd_);
+  }
+  ResetRecvBuf(0);
+  socket_fd_ = -1;
+}
+
+namespace {
+
+class LinkInfoParser : public NetlinkParserInterface {
+ public:
+  LinkInfoParser(std::string interface_name, Netlink::LinkInfo* link_info)
+      : interface_name_(std::move(interface_name)), link_info_(link_info) {}
+
+  void Run(struct nlmsghdr* netlink_message) override {
+    if (netlink_message->nlmsg_type != RTM_NEWLINK) {
+      QUIC_LOG(INFO) << absl::StrCat(
+          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
+          " expected: ", RTM_NEWLINK);
+      return;
+    }
+
+    struct ifinfomsg* interface_info =
+        reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
+
+    // make sure interface_info is what we asked for.
+    if (interface_info->ifi_family != AF_UNSPEC) {
+      QUIC_LOG(INFO) << absl::StrCat(
+          "Unexpected ifi_family: ", interface_info->ifi_family,
+          " expected: ", AF_UNSPEC);
+      return;
+    }
+
+    char hardware_address[kHwAddrSize];
+    size_t hardware_address_length = 0;
+    char broadcast_address[kHwAddrSize];
+    size_t broadcast_address_length = 0;
+    std::string name;
+
+    // loop through the attributes
+    struct rtattr* rta;
+    int payload_length = IFLA_PAYLOAD(netlink_message);
+    for (rta = IFLA_RTA(interface_info); RTA_OK(rta, payload_length);
+         rta = RTA_NEXT(rta, payload_length)) {
+      int attribute_length;
+      switch (rta->rta_type) {
+        case IFLA_ADDRESS: {
+          attribute_length = RTA_PAYLOAD(rta);
+          if (attribute_length > kHwAddrSize) {
+            QUIC_VLOG(2) << "IFLA_ADDRESS too long: " << attribute_length;
+            break;
+          }
+          memmove(hardware_address, RTA_DATA(rta), attribute_length);
+          hardware_address_length = attribute_length;
+          break;
+        }
+        case IFLA_BROADCAST: {
+          attribute_length = RTA_PAYLOAD(rta);
+          if (attribute_length > kHwAddrSize) {
+            QUIC_VLOG(2) << "IFLA_BROADCAST too long: " << attribute_length;
+            break;
+          }
+          memmove(broadcast_address, RTA_DATA(rta), attribute_length);
+          broadcast_address_length = attribute_length;
+          break;
+        }
+        case IFLA_IFNAME: {
+          name = std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
+                             RTA_PAYLOAD(rta));
+          // The name maybe a 0 terminated c string.
+          name = name.substr(0, name.find('\0'));
+          break;
+        }
+      }
+    }
+
+    QUIC_VLOG(2) << "interface name: " << name
+                 << ", index: " << interface_info->ifi_index;
+
+    if (name == interface_name_) {
+      link_info_->index = interface_info->ifi_index;
+      link_info_->type = interface_info->ifi_type;
+      link_info_->hardware_address_length = hardware_address_length;
+      if (hardware_address_length > 0) {
+        memmove(&link_info_->hardware_address, hardware_address,
+                hardware_address_length);
+      }
+      link_info_->broadcast_address_length = broadcast_address_length;
+      if (broadcast_address_length > 0) {
+        memmove(&link_info_->broadcast_address, broadcast_address,
+                broadcast_address_length);
+      }
+      found_link_ = true;
+    }
+  }
+
+  bool found_link() { return found_link_; }
+
+ private:
+  const std::string interface_name_;
+  Netlink::LinkInfo* const link_info_;
+  bool found_link_ = false;
+};
+
+}  // namespace
+
+bool Netlink::GetLinkInfo(const std::string& interface_name,
+                          LinkInfo* link_info) {
+  auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET,
+                                  NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+                                  seq_, getpid(), nullptr);
+
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed.";
+    return false;
+  }
+
+  // Pass the parser to the receive routine. It may be called multiple times
+  // since there may be multiple reply packets each with multiple reply
+  // messages.
+  LinkInfoParser parser(interface_name, link_info);
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "recv failed.";
+    return false;
+  }
+
+  return parser.found_link();
+}
+
+namespace {
+
+class LocalAddressParser : public NetlinkParserInterface {
+ public:
+  LocalAddressParser(int interface_index,
+                     uint8_t unwanted_flags,
+                     std::vector<Netlink::AddressInfo>* local_addresses,
+                     int* num_ipv6_nodad_dadfailed_addresses)
+      : interface_index_(interface_index),
+        unwanted_flags_(unwanted_flags),
+        local_addresses_(local_addresses),
+        num_ipv6_nodad_dadfailed_addresses_(
+            num_ipv6_nodad_dadfailed_addresses) {}
+
+  void Run(struct nlmsghdr* netlink_message) override {
+    // each nlmsg contains a header and multiple address attributes.
+    if (netlink_message->nlmsg_type != RTM_NEWADDR) {
+      QUIC_LOG(INFO) << "Unexpected nlmsg_type: " << netlink_message->nlmsg_type
+                     << " expected: " << RTM_NEWADDR;
+      return;
+    }
+
+    struct ifaddrmsg* interface_address =
+        reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));
+
+    // Make sure this is for an address family we're interested in.
+    if (interface_address->ifa_family != AF_INET &&
+        interface_address->ifa_family != AF_INET6) {
+      QUIC_VLOG(2) << absl::StrCat("uninteresting ifa family: ",
+                                   interface_address->ifa_family);
+      return;
+    }
+
+    // Keep track of addresses with both 'nodad' and 'dadfailed', this really
+    // should't be possible and is likely a kernel bug.
+    if (num_ipv6_nodad_dadfailed_addresses_ != nullptr &&
+        (interface_address->ifa_flags & IFA_F_NODAD) &&
+        (interface_address->ifa_flags & IFA_F_DADFAILED)) {
+      ++(*num_ipv6_nodad_dadfailed_addresses_);
+    }
+
+    uint8_t unwanted_flags = interface_address->ifa_flags & unwanted_flags_;
+    if (unwanted_flags != 0) {
+      QUIC_VLOG(2) << absl::StrCat("unwanted ifa flags: ", unwanted_flags);
+      return;
+    }
+
+    // loop through the attributes
+    struct rtattr* rta;
+    int payload_length = IFA_PAYLOAD(netlink_message);
+    Netlink::AddressInfo address_info;
+    for (rta = IFA_RTA(interface_address); RTA_OK(rta, payload_length);
+         rta = RTA_NEXT(rta, payload_length)) {
+      // There's quite a lot of confusion in Linux over the use of IFA_LOCAL and
+      // IFA_ADDRESS (source and destination address). For broadcast links, such
+      // as Ethernet, they are identical (see <linux/if_addr.h>), but the kernel
+      // sometimes uses only one or the other. We'll return both so that the
+      // caller can decide which to use.
+      if (rta->rta_type != IFA_LOCAL && rta->rta_type != IFA_ADDRESS) {
+        QUIC_VLOG(2) << "Ignoring uninteresting rta_type: " << rta->rta_type;
+        continue;
+      }
+
+      switch (interface_address->ifa_family) {
+        case AF_INET:
+          ABSL_FALLTHROUGH_INTENDED;
+        case AF_INET6:
+          // QuicIpAddress knows how to parse ip from raw bytes as long as they
+          // are in network byte order.
+          if (RTA_PAYLOAD(rta) == sizeof(struct in_addr) ||
+              RTA_PAYLOAD(rta) == sizeof(struct in6_addr)) {
+            auto* raw_ip = reinterpret_cast<char*>(RTA_DATA(rta));
+            if (rta->rta_type == IFA_LOCAL) {
+              address_info.local_address.FromPackedString(raw_ip,
+                                                          RTA_PAYLOAD(rta));
+            } else {
+              address_info.interface_address.FromPackedString(raw_ip,
+                                                              RTA_PAYLOAD(rta));
+            }
+          }
+          break;
+        default:
+          QUIC_LOG(ERROR) << absl::StrCat("Unknown address family: ",
+                                          interface_address->ifa_family);
+      }
+    }
+
+    QUIC_VLOG(2) << "local_address: " << address_info.local_address.ToString()
+                 << " interface_address: "
+                 << address_info.interface_address.ToString()
+                 << " index: " << interface_address->ifa_index;
+    if (interface_address->ifa_index != interface_index_) {
+      return;
+    }
+
+    address_info.prefix_length = interface_address->ifa_prefixlen;
+    address_info.scope = interface_address->ifa_scope;
+    if (address_info.local_address.IsInitialized() ||
+        address_info.interface_address.IsInitialized()) {
+      local_addresses_->push_back(address_info);
+    }
+  }
+
+ private:
+  const int interface_index_;
+  const uint8_t unwanted_flags_;
+  std::vector<Netlink::AddressInfo>* const local_addresses_;
+  int* const num_ipv6_nodad_dadfailed_addresses_;
+};
+
+}  // namespace
+
+bool Netlink::GetAddresses(int interface_index,
+                           uint8_t unwanted_flags,
+                           std::vector<AddressInfo>* addresses,
+                           int* num_ipv6_nodad_dadfailed_addresses) {
+  // the message doesn't contain the index, we'll have to do the filtering while
+  // parsing the reply. This is because NLM_F_MATCH, which only returns entries
+  // that matches the request criteria, is not yet implemented (see man 3
+  // netlink).
+  auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET,
+                                     NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+                                     seq_, getpid(), nullptr);
+
+  // the send routine returns the socket to listen on.
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed.";
+    return false;
+  }
+
+  addresses->clear();
+  if (num_ipv6_nodad_dadfailed_addresses != nullptr) {
+    *num_ipv6_nodad_dadfailed_addresses = 0;
+  }
+
+  LocalAddressParser parser(interface_index, unwanted_flags, addresses,
+                            num_ipv6_nodad_dadfailed_addresses);
+  // Pass the parser to the receive routine. It may be called multiple times
+  // since there may be multiple reply packets each with multiple reply
+  // messages.
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "recv failed";
+    return false;
+  }
+  return true;
+}
+
+namespace {
+
+class UnknownParser : public NetlinkParserInterface {
+ public:
+  void Run(struct nlmsghdr* netlink_message) override {
+    QUIC_LOG(INFO) << "nlmsg reply type: " << netlink_message->nlmsg_type;
+  }
+};
+
+}  // namespace
+
+bool Netlink::ChangeLocalAddress(
+    uint32_t interface_index,
+    Verb verb,
+    const QuicIpAddress& address,
+    uint8_t prefix_length,
+    uint8_t ifa_flags,
+    uint8_t ifa_scope,
+    const std::vector<struct rtattr*>& additional_attributes) {
+  if (verb == Verb::kReplace) {
+    return false;
+  }
+  auto operation = verb == Verb::kAdd ? RtnetlinkMessage::Operation::NEW
+                                      : RtnetlinkMessage::Operation::DEL;
+  uint8_t address_family;
+  if (address.address_family() == IpAddressFamily::IP_V4) {
+    address_family = AF_INET;
+  } else if (address.address_family() == IpAddressFamily::IP_V6) {
+    address_family = AF_INET6;
+  } else {
+    return false;
+  }
+
+  struct ifaddrmsg address_header = {address_family, prefix_length, ifa_flags,
+                                     ifa_scope, interface_index};
+
+  auto message = AddressMessage::New(operation, NLM_F_REQUEST | NLM_F_ACK, seq_,
+                                     getpid(), &address_header);
+
+  for (const auto& attribute : additional_attributes) {
+    if (attribute->rta_type == IFA_LOCAL) {
+      continue;
+    }
+    message.AppendAttribute(attribute->rta_type, RTA_DATA(attribute),
+                            RTA_PAYLOAD(attribute));
+  }
+
+  message.AppendAttribute(IFA_LOCAL, address.ToPackedString().c_str(),
+                          address.ToPackedString().size());
+
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed";
+    return false;
+  }
+
+  UnknownParser parser;
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "receive failed.";
+    return false;
+  }
+  return true;
+}
+
+namespace {
+
+class RoutingRuleParser : public NetlinkParserInterface {
+ public:
+  explicit RoutingRuleParser(std::vector<Netlink::RoutingRule>* routing_rules)
+      : routing_rules_(routing_rules) {}
+
+  void Run(struct nlmsghdr* netlink_message) override {
+    if (netlink_message->nlmsg_type != RTM_NEWROUTE) {
+      QUIC_LOG(WARNING) << absl::StrCat(
+          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
+          " expected: ", RTM_NEWROUTE);
+      return;
+    }
+
+    auto* route = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
+    int payload_length = RTM_PAYLOAD(netlink_message);
+
+    if (route->rtm_family != AF_INET && route->rtm_family != AF_INET6) {
+      QUIC_VLOG(2) << absl::StrCat("Uninteresting family: ", route->rtm_family);
+      return;
+    }
+
+    Netlink::RoutingRule rule;
+    rule.scope = route->rtm_scope;
+    rule.table = route->rtm_table;
+
+    struct rtattr* rta;
+    for (rta = RTM_RTA(route); RTA_OK(rta, payload_length);
+         rta = RTA_NEXT(rta, payload_length)) {
+      switch (rta->rta_type) {
+        case RTA_TABLE: {
+          rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
+          break;
+        }
+        case RTA_DST: {
+          QuicIpAddress destination;
+          destination.FromPackedString(reinterpret_cast<char*> RTA_DATA(rta),
+                                       RTA_PAYLOAD(rta));
+          rule.destination_subnet = IpRange(destination, route->rtm_dst_len);
+          break;
+        }
+        case RTA_PREFSRC: {
+          QuicIpAddress preferred_source;
+          rule.preferred_source.FromPackedString(
+              reinterpret_cast<char*> RTA_DATA(rta), RTA_PAYLOAD(rta));
+          break;
+        }
+        case RTA_OIF: {
+          rule.out_interface = *reinterpret_cast<int*>(RTA_DATA(rta));
+          break;
+        }
+        default: {
+          QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
+                                       rta->rta_type);
+        }
+      }
+    }
+    routing_rules_->push_back(rule);
+  }
+
+ private:
+  std::vector<Netlink::RoutingRule>* routing_rules_;
+};
+
+}  // namespace
+
+bool Netlink::GetRouteInfo(std::vector<Netlink::RoutingRule>* routing_rules) {
+  rtmsg route_message{};
+  // Only manipulate main routing table.
+  route_message.rtm_table = RT_TABLE_MAIN;
+
+  auto message = RouteMessage::New(RtnetlinkMessage::Operation::GET,
+                                   NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH,
+                                   seq_, getpid(), &route_message);
+
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed";
+    return false;
+  }
+
+  RoutingRuleParser parser(routing_rules);
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "recv failed";
+    return false;
+  }
+
+  return true;
+}
+
+bool Netlink::ChangeRoute(Netlink::Verb verb,
+                          uint32_t table,
+                          const IpRange& destination_subnet,
+                          uint8_t scope,
+                          QuicIpAddress preferred_source,
+                          int32_t interface_index) {
+  if (!destination_subnet.prefix().IsInitialized()) {
+    return false;
+  }
+  if (destination_subnet.address_family() != IpAddressFamily::IP_V4 &&
+      destination_subnet.address_family() != IpAddressFamily::IP_V6) {
+    return false;
+  }
+  if (preferred_source.IsInitialized() &&
+      preferred_source.address_family() !=
+          destination_subnet.address_family()) {
+    return false;
+  }
+
+  RtnetlinkMessage::Operation operation;
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
+  switch (verb) {
+    case Verb::kAdd:
+      operation = RtnetlinkMessage::Operation::NEW;
+      // Setting NLM_F_EXCL so that an existing entry for this subnet will fail
+      // the request. NLM_F_CREATE is necessary to indicate this is trying to
+      // create a new entry - simply having RTM_NEWROUTE is not enough even the
+      // name suggests so.
+      flags |= NLM_F_EXCL | NLM_F_CREATE;
+      break;
+    case Verb::kRemove:
+      operation = RtnetlinkMessage::Operation::DEL;
+      break;
+    case Verb::kReplace:
+      operation = RtnetlinkMessage::Operation::NEW;
+      // Setting NLM_F_REPLACE to tell the kernel that existing entry for this
+      // subnet should be replaced.
+      flags |= NLM_F_REPLACE | NLM_F_CREATE;
+      break;
+  }
+
+  struct rtmsg route_message;
+  memset(&route_message, 0, sizeof(route_message));
+  route_message.rtm_family =
+      destination_subnet.address_family() == IpAddressFamily::IP_V4 ? AF_INET
+                                                                    : AF_INET6;
+  // rtm_dst_len and rtm_src_len are actually the subnet prefix lengths. Poor
+  // naming.
+  route_message.rtm_dst_len = destination_subnet.prefix_length();
+  // 0 means no source subnet for this rule.
+  route_message.rtm_src_len = 0;
+  // Only program the main table. Other tables are intended for the kernel to
+  // manage.
+  route_message.rtm_table = RT_TABLE_MAIN;
+  // Use RTPROT_UNSPEC to match all the different protocol. Rules added by
+  // kernel have RTPROT_KERNEL. Rules added by the root user have RTPROT_STATIC
+  // instead.
+  route_message.rtm_protocol =
+      verb == Verb::kRemove ? RTPROT_UNSPEC : RTPROT_STATIC;
+  route_message.rtm_scope = scope;
+  // Only add unicast routing rule.
+  route_message.rtm_type = RTN_UNICAST;
+  auto message =
+      RouteMessage::New(operation, flags, seq_, getpid(), &route_message);
+
+  message.AppendAttribute(RTA_TABLE, &table, sizeof(table));
+
+  // RTA_OIF is the target interface for this rule.
+  message.AppendAttribute(RTA_OIF, &interface_index, sizeof(interface_index));
+  // The actual destination subnet must be truncated of all the tailing zeros.
+  message.AppendAttribute(
+      RTA_DST,
+      reinterpret_cast<const void*>(
+          destination_subnet.prefix().ToPackedString().c_str()),
+      destination_subnet.prefix().ToPackedString().size());
+  // This is the source address to use in the IP packet should this routing rule
+  // is used.
+  if (preferred_source.IsInitialized()) {
+    auto src_str = preferred_source.ToPackedString();
+    message.AppendAttribute(RTA_PREFSRC,
+                            reinterpret_cast<const void*>(src_str.c_str()),
+                            src_str.size());
+  }
+
+  if (verb != Verb::kRemove) {
+    auto gateway_str = QboneConstants::GatewayAddress()->ToPackedString();
+    message.AppendAttribute(RTA_GATEWAY,
+                            reinterpret_cast<const void*>(gateway_str.c_str()),
+                            gateway_str.size());
+  }
+
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed";
+    return false;
+  }
+
+  UnknownParser parser;
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "receive failed.";
+    return false;
+  }
+  return true;
+}
+
+namespace {
+
+class IpRuleParser : public NetlinkParserInterface {
+ public:
+  explicit IpRuleParser(std::vector<Netlink::IpRule>* ip_rules)
+      : ip_rules_(ip_rules) {}
+
+  void Run(struct nlmsghdr* netlink_message) override {
+    if (netlink_message->nlmsg_type != RTM_NEWRULE) {
+      QUIC_LOG(WARNING) << absl::StrCat(
+          "Unexpected nlmsg_type: ", netlink_message->nlmsg_type,
+          " expected: ", RTM_NEWRULE);
+      return;
+    }
+
+    auto* rule = reinterpret_cast<rtmsg*>(NLMSG_DATA(netlink_message));
+    int payload_length = RTM_PAYLOAD(netlink_message);
+
+    if (rule->rtm_family != AF_INET6) {
+      QUIC_LOG(ERROR) << absl::StrCat("Unexpected family: ", rule->rtm_family);
+      return;
+    }
+
+    Netlink::IpRule ip_rule;
+    ip_rule.table = rule->rtm_table;
+
+    struct rtattr* rta;
+    for (rta = RTM_RTA(rule); RTA_OK(rta, payload_length);
+         rta = RTA_NEXT(rta, payload_length)) {
+      switch (rta->rta_type) {
+        case RTA_TABLE: {
+          ip_rule.table = *reinterpret_cast<uint32_t*>(RTA_DATA(rta));
+          break;
+        }
+        case RTA_SRC: {
+          QuicIpAddress src_addr;
+          src_addr.FromPackedString(reinterpret_cast<char*>(RTA_DATA(rta)),
+                                    RTA_PAYLOAD(rta));
+          IpRange src_range(src_addr, rule->rtm_src_len);
+          ip_rule.source_range = src_range;
+          break;
+        }
+        default: {
+          QUIC_VLOG(2) << absl::StrCat("Uninteresting attribute: ",
+                                       rta->rta_type);
+        }
+      }
+    }
+    ip_rules_->emplace_back(ip_rule);
+  }
+
+ private:
+  std::vector<Netlink::IpRule>* ip_rules_;
+};
+
+}  // namespace
+
+bool Netlink::GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) {
+  rtmsg rule_message{};
+  rule_message.rtm_family = AF_INET6;
+
+  auto message = RuleMessage::New(RtnetlinkMessage::Operation::GET,
+                                  NLM_F_REQUEST | NLM_F_DUMP, seq_, getpid(),
+                                  &rule_message);
+
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed";
+    return false;
+  }
+
+  IpRuleParser parser(ip_rules);
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "receive failed.";
+    return false;
+  }
+  return true;
+}
+
+bool Netlink::ChangeRule(Verb verb, uint32_t table, IpRange source_range) {
+  RtnetlinkMessage::Operation operation;
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
+
+  rtmsg rule_message{};
+  rule_message.rtm_family = AF_INET6;
+  rule_message.rtm_protocol = RTPROT_STATIC;
+  rule_message.rtm_scope = RT_SCOPE_UNIVERSE;
+  rule_message.rtm_table = RT_TABLE_UNSPEC;
+
+  rule_message.rtm_flags |= FIB_RULE_FIND_SADDR;
+
+  switch (verb) {
+    case Verb::kAdd:
+      if (!source_range.IsInitialized()) {
+        QUIC_LOG(ERROR) << "Source range must be initialized.";
+        return false;
+      }
+      operation = RtnetlinkMessage::Operation::NEW;
+      flags |= NLM_F_EXCL | NLM_F_CREATE;
+      rule_message.rtm_type = FRA_DST;
+      rule_message.rtm_src_len = source_range.prefix_length();
+      break;
+    case Verb::kRemove:
+      operation = RtnetlinkMessage::Operation::DEL;
+      break;
+    case Verb::kReplace:
+      QUIC_LOG(ERROR) << "Unsupported verb: kReplace";
+      return false;
+  }
+  auto message =
+      RuleMessage::New(operation, flags, seq_, getpid(), &rule_message);
+
+  message.AppendAttribute(RTA_TABLE, &table, sizeof(table));
+
+  if (source_range.IsInitialized()) {
+    std::string packed_src = source_range.prefix().ToPackedString();
+    message.AppendAttribute(RTA_SRC,
+                            reinterpret_cast<const void*>(packed_src.c_str()),
+                            packed_src.size());
+  }
+
+  if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
+    QUIC_LOG(ERROR) << "send failed";
+    return false;
+  }
+
+  UnknownParser parser;
+  if (!Recv(seq_++, &parser)) {
+    QUIC_LOG(ERROR) << "receive failed.";
+    return false;
+  }
+  return true;
+}
+
+bool Netlink::Send(struct iovec* iov, size_t iovlen) {
+  if (!OpenSocket()) {
+    QUIC_LOG(ERROR) << "can't open socket";
+    return false;
+  }
+
+  // an address for communicating with the kernel netlink code
+  sockaddr_nl netlink_address;
+  memset(&netlink_address, 0, sizeof(netlink_address));
+  netlink_address.nl_family = AF_NETLINK;
+  netlink_address.nl_pid = 0;     // destination is kernel
+  netlink_address.nl_groups = 0;  // no multicast
+
+  struct msghdr msg = {
+      &netlink_address, sizeof(netlink_address), iov, iovlen, nullptr, 0, 0};
+
+  if (kernel_->sendmsg(socket_fd_, &msg, 0) < 0) {
+    QUIC_LOG(ERROR) << "sendmsg failed";
+    CloseSocket();
+    return false;
+  }
+
+  return true;
+}
+
+bool Netlink::Recv(uint32_t seq, NetlinkParserInterface* parser) {
+  sockaddr_nl netlink_address;
+
+  // replies can span multiple packets
+  for (;;) {
+    socklen_t address_length = sizeof(netlink_address);
+
+    // First, call recvfrom with buffer size of 0 and MSG_PEEK | MSG_TRUNC set
+    // so that we know the size of the incoming packet before actually receiving
+    // it.
+    int next_packet_size = kernel_->recvfrom(
+        socket_fd_, recvbuf_.get(), /* len = */ 0, MSG_PEEK | MSG_TRUNC,
+        reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
+    if (next_packet_size < 0) {
+      QUIC_LOG(ERROR)
+          << "error recvfrom with MSG_PEEK | MSG_TRUNC to get packet length.";
+      CloseSocket();
+      return false;
+    }
+    QUIC_VLOG(3) << "netlink packet size: " << next_packet_size;
+    if (next_packet_size > recvbuf_length_) {
+      QUIC_VLOG(2) << "resizing recvbuf to " << next_packet_size;
+      ResetRecvBuf(next_packet_size);
+    }
+
+    // Get the packet for real.
+    memset(recvbuf_.get(), 0, recvbuf_length_);
+    int len = kernel_->recvfrom(
+        socket_fd_, recvbuf_.get(), recvbuf_length_, /* flags = */ 0,
+        reinterpret_cast<struct sockaddr*>(&netlink_address), &address_length);
+    QUIC_VLOG(3) << "recvfrom returned: " << len;
+    if (len < 0) {
+      QUIC_LOG(INFO) << "can't receive netlink packet";
+      CloseSocket();
+      return false;
+    }
+
+    // there may be multiple nlmsg's in each reply packet
+    struct nlmsghdr* netlink_message;
+    for (netlink_message = reinterpret_cast<struct nlmsghdr*>(recvbuf_.get());
+         NLMSG_OK(netlink_message, len);
+         netlink_message = NLMSG_NEXT(netlink_message, len)) {
+      QUIC_VLOG(3) << "netlink_message->nlmsg_type = "
+                   << netlink_message->nlmsg_type;
+      // make sure this is to us
+      if (netlink_message->nlmsg_seq != seq) {
+        QUIC_LOG(INFO) << "netlink_message not meant for us."
+                       << " seq: " << seq
+                       << " nlmsg_seq: " << netlink_message->nlmsg_seq;
+        continue;
+      }
+
+      // done with this whole reply (not just this particular packet)
+      if (netlink_message->nlmsg_type == NLMSG_DONE) {
+        return true;
+      }
+      if (netlink_message->nlmsg_type == NLMSG_ERROR) {
+        struct nlmsgerr* err =
+            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
+        if (netlink_message->nlmsg_len <
+            NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
+          QUIC_LOG(INFO) << "netlink_message ERROR truncated";
+        } else {
+          // an ACK
+          if (err->error == 0) {
+            QUIC_VLOG(3) << "Netlink sent an ACK";
+            return true;
+          }
+          QUIC_LOG(INFO) << "netlink_message ERROR: " << err->error;
+        }
+        return false;
+      }
+
+      parser->Run(netlink_message);
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/netlink.h b/quiche/quic/qbone/platform/netlink.h
new file mode 100644
index 0000000..dbe32e9
--- /dev/null
+++ b/quiche/quic/qbone/platform/netlink.h
@@ -0,0 +1,143 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/qbone/platform/ip_range.h"
+#include "quiche/quic/qbone/platform/kernel_interface.h"
+#include "quiche/quic/qbone/platform/netlink_interface.h"
+
+namespace quic {
+
+// A wrapper class to provide convenient methods of manipulating IP address and
+// routing table using netlink (man 7 netlink) socket. More specifically,
+// rtnetlink is used (man 7 rtnetlink).
+//
+// This class is not thread safe, but thread compatible, as long as callers can
+// make sure Send and Recv pairs are executed in sequence for a particular
+// query.
+class Netlink : public NetlinkInterface {
+ public:
+  explicit Netlink(KernelInterface* kernel);
+  ~Netlink() override;
+
+  // Gets the link information for the interface referred by the given
+  // interface_name.
+  //
+  // This is a synchronous communication. That should not be a problem since the
+  // kernel should answer immediately.
+  bool GetLinkInfo(const std::string& interface_name,
+                   LinkInfo* link_info) override;
+
+  // Gets the addresses for the given interface referred by the given
+  // interface_index.
+  //
+  // This is a synchronous communication. This should not be a problem since the
+  // kernel should answer immediately.
+  bool GetAddresses(int interface_index,
+                    uint8_t unwanted_flags,
+                    std::vector<AddressInfo>* addresses,
+                    int* num_ipv6_nodad_dadfailed_addresses) override;
+
+  // Performs the given verb that modifies local addresses on the given
+  // interface_index.
+  //
+  // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
+  // with the netlink message. Note that rta_len in each RTA is used to decide
+  // the length of the payload. The caller is responsible for making sure
+  // payload bytes are accessible after the RTA header.
+  bool ChangeLocalAddress(
+      uint32_t interface_index,
+      Verb verb,
+      const QuicIpAddress& address,
+      uint8_t prefix_length,
+      uint8_t ifa_flags,
+      uint8_t ifa_scope,
+      const std::vector<struct rtattr*>& additional_attributes) override;
+
+  // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
+  // which is programmable.
+  //
+  // This is a synchronous communication. This should not be a problem since the
+  // kernel should answer immediately.
+  bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) override;
+
+  // Performs the given Verb on the matching rule in the main routing table
+  // (RT_TABLE_MAIN).
+  //
+  // preferred_source can be !IsInitialized(), in which case it will be omitted.
+  //
+  // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
+  // preferred_source, interface_index). Return true if a matching rule is
+  // found. interface_index can be 0 for wilecard.
+  //
+  // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
+  // the given destination_subnet already exists, nothing will happen and false
+  // is returned.
+  //
+  // For Verb::kReplace, rule matching is done by destination_subnet. If no
+  // matching rule is found, a new entry will be created.
+  bool ChangeRoute(Netlink::Verb verb,
+                   uint32_t table,
+                   const IpRange& destination_subnet,
+                   uint8_t scope,
+                   QuicIpAddress preferred_source,
+                   int32_t interface_index) override;
+
+  // Returns the set of all rules in the routing policy database.
+  bool GetRuleInfo(std::vector<Netlink::IpRule>* ip_rules) override;
+
+  // Performs the give verb on the matching rule in the routing policy database.
+  // When deleting a rule, the |source_range| may be unspecified, in which case
+  // the lowest priority rule from |table| will be removed. When adding a rule,
+  // the |source_address| must be specified.
+  bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) override;
+
+  // Sends a netlink message to the kernel. iov and iovlen represents an array
+  // of struct iovec to be fed into sendmsg. The caller needs to make sure the
+  // message conform to what's expected by NLMSG_* macros.
+  //
+  // This can be useful if more flexibility is needed than the provided
+  // convenient methods can provide.
+  bool Send(struct iovec* iov, size_t iovlen) override;
+
+  // Receives a netlink message from the kernel.
+  // parser will be called on the caller's stack.
+  //
+  // This can be useful if more flexibility is needed than the provided
+  // convenient methods can provide.
+  // TODO(b/69412655): vectorize this.
+  bool Recv(uint32_t seq, NetlinkParserInterface* parser) override;
+
+ private:
+  // Reset the size of recvbuf_ to size. If size is 0, recvbuf_ will be nullptr.
+  void ResetRecvBuf(size_t size);
+
+  // Opens a netlink socket if not already opened.
+  bool OpenSocket();
+
+  // Closes the opened netlink socket. Noop if no netlink socket is opened.
+  void CloseSocket();
+
+  KernelInterface* kernel_;
+  int socket_fd_ = -1;
+  std::unique_ptr<char[]> recvbuf_ = nullptr;
+  size_t recvbuf_length_ = 0;
+  uint32_t seq_;  // next msg sequence number
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_H_
diff --git a/quiche/quic/qbone/platform/netlink_interface.h b/quiche/quic/qbone/platform/netlink_interface.h
new file mode 100644
index 0000000..1435c0f
--- /dev/null
+++ b/quiche/quic/qbone/platform/netlink_interface.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
+
+#include <linux/rtnetlink.h>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/qbone/platform/ip_range.h"
+
+namespace quic {
+
+constexpr int kHwAddrSize = 6;
+
+class NetlinkParserInterface {
+ public:
+  virtual ~NetlinkParserInterface() {}
+  virtual void Run(struct nlmsghdr* netlink_message) = 0;
+};
+
+// An interface providing convenience methods for manipulating IP address and
+// routing table using netlink (man 7 netlink) socket.
+class NetlinkInterface {
+ public:
+  virtual ~NetlinkInterface() = default;
+
+  // Link information returned from GetLinkInfo.
+  struct LinkInfo {
+    int index;
+    uint8_t type;
+    uint8_t hardware_address[kHwAddrSize];
+    uint8_t broadcast_address[kHwAddrSize];
+    size_t hardware_address_length;   // 0 if no hardware address found
+    size_t broadcast_address_length;  // 0 if no broadcast address found
+  };
+
+  // Gets the link information for the interface referred by the given
+  // interface_name.
+  virtual bool GetLinkInfo(const std::string& interface_name,
+                           LinkInfo* link_info) = 0;
+
+  // Address information reported back from GetAddresses.
+  struct AddressInfo {
+    QuicIpAddress local_address;
+    QuicIpAddress interface_address;
+    uint8_t prefix_length = 0;
+    uint8_t scope = 0;
+  };
+
+  // Gets the addresses for the given interface referred by the given
+  // interface_index.
+  virtual bool GetAddresses(int interface_index,
+                            uint8_t unwanted_flags,
+                            std::vector<AddressInfo>* addresses,
+                            int* num_ipv6_nodad_dadfailed_addresses) = 0;
+
+  enum class Verb {
+    kAdd,
+    kRemove,
+    kReplace,
+  };
+
+  // Performs the given verb that modifies local addresses on the given
+  // interface_index.
+  //
+  // additional_attributes are RTAs (man 7 rtnelink) that will be sent together
+  // with the netlink message. Note that rta_len in each RTA is used to decide
+  // the length of the payload. The caller is responsible for making sure
+  // payload bytes are accessible after the RTA header.
+  virtual bool ChangeLocalAddress(
+      uint32_t interface_index,
+      Verb verb,
+      const QuicIpAddress& address,
+      uint8_t prefix_length,
+      uint8_t ifa_flags,
+      uint8_t ifa_scope,
+      const std::vector<struct rtattr*>& additional_attributes) = 0;
+
+  // Routing rule reported back from GetRouteInfo.
+  struct RoutingRule {
+    uint32_t table;
+    IpRange destination_subnet;
+    QuicIpAddress preferred_source;
+    uint8_t scope;
+    int out_interface;
+  };
+
+  struct IpRule {
+    uint32_t table;
+    IpRange source_range;
+  };
+
+  // Gets the list of routing rules from the main routing table (RT_TABLE_MAIN),
+  // which is programmable.
+  virtual bool GetRouteInfo(std::vector<RoutingRule>* routing_rules) = 0;
+
+  // Performs the given Verb on the matching rule in the main routing table
+  // (RT_TABLE_MAIN).
+  //
+  // preferred_source can be !IsInitialized(), in which case it will be omitted.
+  //
+  // For Verb::kRemove, rule matching is done by (destination_subnet, scope,
+  // preferred_source, interface_index). Return true if a matching rule is
+  // found. interface_index can be 0 for wilecard.
+  //
+  // For Verb::kAdd, rule matching is done by destination_subnet. If a rule for
+  // the given destination_subnet already exists, nothing will happen and false
+  // is returned.
+  //
+  // For Verb::kReplace, rule matching is done by destination_subnet. If no
+  // matching rule is found, a new entry will be created.
+  virtual bool ChangeRoute(Verb verb,
+                           uint32_t table,
+                           const IpRange& destination_subnet,
+                           uint8_t scope,
+                           QuicIpAddress preferred_source,
+                           int32_t interface_index) = 0;
+
+  // Returns the set of all rules in the routing policy database.
+  virtual bool GetRuleInfo(std::vector<IpRule>* ip_rules) = 0;
+
+  // Performs the give verb on the matching rule in the routing policy database.
+  // When deleting a rule, the |source_range| may be unspecified, in which case
+  // the lowest priority rule from |table| will be removed. When adding a rule,
+  // the |source_address| must be specified.
+  virtual bool ChangeRule(Verb verb, uint32_t table, IpRange source_range) = 0;
+
+  // Sends a netlink message to the kernel. iov and iovlen represents an array
+  // of struct iovec to be fed into sendmsg. The caller needs to make sure the
+  // message conform to what's expected by NLMSG_* macros.
+  //
+  // This can be useful if more flexibility is needed than the provided
+  // convenient methods can provide.
+  virtual bool Send(struct iovec* iov, size_t iovlen) = 0;
+
+  // Receives a netlink message from the kernel.
+  // parser will be called on the caller's stack.
+  //
+  // This can be useful if more flexibility is needed than the provided
+  // convenient methods can provide.
+  virtual bool Recv(uint32_t seq, NetlinkParserInterface* parser) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_NETLINK_INTERFACE_H_
diff --git a/quiche/quic/qbone/platform/netlink_test.cc b/quiche/quic/qbone/platform/netlink_test.cc
new file mode 100644
index 0000000..ac506a9
--- /dev/null
+++ b/quiche/quic/qbone/platform/netlink_test.cc
@@ -0,0 +1,784 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/netlink.h"
+
+#include <utility>
+
+#include "absl/container/node_hash_set.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/platform/mock_kernel.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+
+namespace quic {
+namespace {
+
+using ::testing::_;
+using ::testing::Contains;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::Unused;
+
+const int kSocketFd = 101;
+
+class NetlinkTest : public QuicTest {
+ protected:
+  NetlinkTest() {
+    ON_CALL(mock_kernel_, socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE))
+        .WillByDefault(Invoke([this](Unused, Unused, Unused) {
+          EXPECT_CALL(mock_kernel_, close(kSocketFd)).WillOnce(Return(0));
+          return kSocketFd;
+        }));
+  }
+
+  void ExpectNetlinkPacket(
+      uint16_t type,
+      uint16_t flags,
+      const std::function<ssize_t(void* buf, size_t len, int seq)>&
+          recv_callback,
+      const std::function<void(const void* buf, size_t len)>& send_callback =
+          nullptr) {
+    static int seq = -1;
+    InSequence s;
+
+    EXPECT_CALL(mock_kernel_, sendmsg(kSocketFd, _, _))
+        .WillOnce(Invoke([type, flags, send_callback](
+                             Unused, const struct msghdr* msg, int) {
+          EXPECT_EQ(sizeof(struct sockaddr_nl), msg->msg_namelen);
+          auto* nl_addr =
+              reinterpret_cast<const struct sockaddr_nl*>(msg->msg_name);
+          EXPECT_EQ(AF_NETLINK, nl_addr->nl_family);
+          EXPECT_EQ(0, nl_addr->nl_pid);
+          EXPECT_EQ(0, nl_addr->nl_groups);
+
+          EXPECT_GE(msg->msg_iovlen, 1);
+          EXPECT_GE(msg->msg_iov[0].iov_len, sizeof(struct nlmsghdr));
+
+          std::string buf;
+          for (int i = 0; i < msg->msg_iovlen; i++) {
+            buf.append(
+                std::string(reinterpret_cast<char*>(msg->msg_iov[i].iov_base),
+                            msg->msg_iov[i].iov_len));
+          }
+
+          auto* netlink_message =
+              reinterpret_cast<const struct nlmsghdr*>(buf.c_str());
+          EXPECT_EQ(type, netlink_message->nlmsg_type);
+          EXPECT_EQ(flags, netlink_message->nlmsg_flags);
+          EXPECT_GE(buf.size(), netlink_message->nlmsg_len);
+
+          if (send_callback != nullptr) {
+            send_callback(buf.c_str(), buf.size());
+          }
+
+          QUICHE_CHECK_EQ(seq, -1);
+          seq = netlink_message->nlmsg_seq;
+          return buf.size();
+        }));
+
+    EXPECT_CALL(mock_kernel_,
+                recvfrom(kSocketFd, _, 0, MSG_PEEK | MSG_TRUNC, _, _))
+        .WillOnce(Invoke([this, recv_callback](Unused, Unused, Unused, Unused,
+                                               struct sockaddr* src_addr,
+                                               socklen_t* addrlen) {
+          auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
+          nl_addr->nl_family = AF_NETLINK;
+          nl_addr->nl_pid = 0;     // from kernel
+          nl_addr->nl_groups = 0;  // no multicast
+
+          int ret = recv_callback(reply_packet_, sizeof(reply_packet_), seq);
+          QUICHE_CHECK_LE(ret, sizeof(reply_packet_));
+          return ret;
+        }));
+
+    EXPECT_CALL(mock_kernel_, recvfrom(kSocketFd, _, _, _, _, _))
+        .WillOnce(Invoke([recv_callback](Unused, void* buf, size_t len, Unused,
+                                         struct sockaddr* src_addr,
+                                         socklen_t* addrlen) {
+          auto* nl_addr = reinterpret_cast<struct sockaddr_nl*>(src_addr);
+          nl_addr->nl_family = AF_NETLINK;
+          nl_addr->nl_pid = 0;     // from kernel
+          nl_addr->nl_groups = 0;  // no multicast
+
+          int ret = recv_callback(buf, len, seq);
+          EXPECT_GE(len, ret);
+          seq = -1;
+          return ret;
+        }));
+  }
+
+  char reply_packet_[4096];
+  MockKernel mock_kernel_;
+};
+
+void AddRTA(struct nlmsghdr* netlink_message,
+            uint16_t type,
+            const void* data,
+            size_t len) {
+  auto* next_header_ptr = reinterpret_cast<char*>(netlink_message) +
+                          NLMSG_ALIGN(netlink_message->nlmsg_len);
+
+  auto* rta = reinterpret_cast<struct rtattr*>(next_header_ptr);
+  rta->rta_type = type;
+  rta->rta_len = RTA_LENGTH(len);
+  memcpy(RTA_DATA(rta), data, len);
+
+  netlink_message->nlmsg_len =
+      NLMSG_ALIGN(netlink_message->nlmsg_len) + RTA_LENGTH(len);
+}
+
+void CreateIfinfomsg(struct nlmsghdr* netlink_message,
+                     const std::string& interface_name,
+                     uint16_t type,
+                     int index,
+                     unsigned int flags,
+                     unsigned int change,
+                     uint8_t address[],
+                     int address_len,
+                     uint8_t broadcast[],
+                     int broadcast_len) {
+  auto* interface_info =
+      reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
+  interface_info->ifi_family = AF_UNSPEC;
+  interface_info->ifi_type = type;
+  interface_info->ifi_index = index;
+  interface_info->ifi_flags = flags;
+  interface_info->ifi_change = change;
+  netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+
+  // Add address
+  AddRTA(netlink_message, IFLA_ADDRESS, address, address_len);
+
+  // Add broadcast address
+  AddRTA(netlink_message, IFLA_BROADCAST, broadcast, broadcast_len);
+
+  // Add name
+  AddRTA(netlink_message, IFLA_IFNAME, interface_name.c_str(),
+         interface_name.size());
+}
+
+struct nlmsghdr* CreateNetlinkMessage(void* buf,  // NOLINT
+                                      struct nlmsghdr* previous_netlink_message,
+                                      uint16_t type,
+                                      int seq) {
+  auto* next_header_ptr = reinterpret_cast<char*>(buf);
+  if (previous_netlink_message != nullptr) {
+    next_header_ptr = reinterpret_cast<char*>(previous_netlink_message) +
+                      NLMSG_ALIGN(previous_netlink_message->nlmsg_len);
+  }
+  auto* netlink_message = reinterpret_cast<nlmsghdr*>(next_header_ptr);
+  netlink_message->nlmsg_len = NLMSG_LENGTH(0);
+  netlink_message->nlmsg_type = type;
+  netlink_message->nlmsg_flags = NLM_F_MULTI;
+  netlink_message->nlmsg_pid = 0;  // from the kernel
+  netlink_message->nlmsg_seq = seq;
+
+  return netlink_message;
+}
+
+void CreateIfaddrmsg(struct nlmsghdr* nlm,
+                     int interface_index,
+                     unsigned char prefixlen,
+                     unsigned char flags,
+                     unsigned char scope,
+                     QuicIpAddress ip) {
+  QUICHE_CHECK(ip.IsInitialized());
+  unsigned char family;
+  switch (ip.address_family()) {
+    case IpAddressFamily::IP_V4:
+      family = AF_INET;
+      break;
+    case IpAddressFamily::IP_V6:
+      family = AF_INET6;
+      break;
+    default:
+      QUIC_BUG(quic_bug_11034_1)
+          << absl::StrCat("unexpected address family: ", ip.address_family());
+      family = AF_UNSPEC;
+  }
+  auto* msg = reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(nlm));
+  msg->ifa_family = family;
+  msg->ifa_prefixlen = prefixlen;
+  msg->ifa_flags = flags;
+  msg->ifa_scope = scope;
+  msg->ifa_index = interface_index;
+  nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+
+  // Add local address
+  AddRTA(nlm, IFA_LOCAL, ip.ToPackedString().c_str(),
+         ip.ToPackedString().size());
+}
+
+void CreateRtmsg(struct nlmsghdr* nlm,
+                 unsigned char family,
+                 unsigned char destination_length,
+                 unsigned char source_length,
+                 unsigned char tos,
+                 unsigned char table,
+                 unsigned char protocol,
+                 unsigned char scope,
+                 unsigned char type,
+                 unsigned int flags,
+                 QuicIpAddress destination,
+                 int interface_index) {
+  auto* msg = reinterpret_cast<struct rtmsg*>(NLMSG_DATA(nlm));
+  msg->rtm_family = family;
+  msg->rtm_dst_len = destination_length;
+  msg->rtm_src_len = source_length;
+  msg->rtm_tos = tos;
+  msg->rtm_table = table;
+  msg->rtm_protocol = protocol;
+  msg->rtm_scope = scope;
+  msg->rtm_type = type;
+  msg->rtm_flags = flags;
+  nlm->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+
+  // Add destination
+  AddRTA(nlm, RTA_DST, destination.ToPackedString().c_str(),
+         destination.ToPackedString().size());
+
+  // Add egress interface
+  AddRTA(nlm, RTA_OIF, &interface_index, sizeof(interface_index));
+}
+
+TEST_F(NetlinkTest, GetLinkInfoWorks) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  uint8_t hwaddr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
+  uint8_t bcaddr[] = {'c', 'b', 'a', 'f', 'e', 'd'};
+
+  ExpectNetlinkPacket(
+      RTM_GETLINK, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+      [&hwaddr, &bcaddr](void* buf, size_t len, int seq) {
+        int ret = 0;
+
+        struct nlmsghdr* netlink_message =
+            CreateNetlinkMessage(buf, nullptr, RTM_NEWLINK, seq);
+        CreateIfinfomsg(netlink_message, "tun0", /* type = */ 1,
+                        /* index = */ 7,
+                        /* flags = */ 0,
+                        /* change = */ 0xFFFFFFFF, hwaddr, 6, bcaddr, 6);
+        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
+
+        netlink_message =
+            CreateNetlinkMessage(buf, netlink_message, NLMSG_DONE, seq);
+        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
+
+        return ret;
+      });
+
+  Netlink::LinkInfo link_info;
+  EXPECT_TRUE(netlink->GetLinkInfo("tun0", &link_info));
+
+  EXPECT_EQ(7, link_info.index);
+  EXPECT_EQ(1, link_info.type);
+
+  for (int i = 0; i < link_info.hardware_address_length; ++i) {
+    EXPECT_EQ(hwaddr[i], link_info.hardware_address[i]);
+  }
+  for (int i = 0; i < link_info.broadcast_address_length; ++i) {
+    EXPECT_EQ(bcaddr[i], link_info.broadcast_address[i]);
+  }
+}
+
+TEST_F(NetlinkTest, GetAddressesWorks) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  absl::node_hash_set<std::string> addresses = {
+      QuicIpAddress::Any4().ToString(), QuicIpAddress::Any6().ToString()};
+
+  ExpectNetlinkPacket(
+      RTM_GETADDR, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+      [&addresses](void* buf, size_t len, int seq) {
+        int ret = 0;
+
+        struct nlmsghdr* nlm = nullptr;
+
+        for (const auto& address : addresses) {
+          QuicIpAddress ip;
+          ip.FromString(address);
+          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
+          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 24,
+                          /* flags = */ 0, /* scope = */ RT_SCOPE_UNIVERSE, ip);
+
+          ret += NLMSG_ALIGN(nlm->nlmsg_len);
+        }
+
+        // Create IPs with unwanted flags.
+        {
+          QuicIpAddress ip;
+          ip.FromString("10.0.0.1");
+          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
+          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
+                          /* flags = */ IFA_F_OPTIMISTIC, /* scope = */
+                          RT_SCOPE_UNIVERSE, ip);
+
+          ret += NLMSG_ALIGN(nlm->nlmsg_len);
+
+          ip.FromString("10.0.0.2");
+          nlm = CreateNetlinkMessage(buf, nlm, RTM_NEWADDR, seq);
+          CreateIfaddrmsg(nlm, /* interface_index = */ 7, /* prefixlen = */ 16,
+                          /* flags = */ IFA_F_TENTATIVE, /* scope = */
+                          RT_SCOPE_UNIVERSE, ip);
+
+          ret += NLMSG_ALIGN(nlm->nlmsg_len);
+        }
+
+        nlm = CreateNetlinkMessage(buf, nlm, NLMSG_DONE, seq);
+        ret += NLMSG_ALIGN(nlm->nlmsg_len);
+
+        return ret;
+      });
+
+  std::vector<Netlink::AddressInfo> reported_addresses;
+  int num_ipv6_nodad_dadfailed_addresses = 0;
+  EXPECT_TRUE(netlink->GetAddresses(7, IFA_F_TENTATIVE | IFA_F_OPTIMISTIC,
+                                    &reported_addresses,
+                                    &num_ipv6_nodad_dadfailed_addresses));
+
+  for (const auto& reported_address : reported_addresses) {
+    EXPECT_TRUE(reported_address.local_address.IsInitialized());
+    EXPECT_FALSE(reported_address.interface_address.IsInitialized());
+    EXPECT_THAT(addresses, Contains(reported_address.local_address.ToString()));
+    addresses.erase(reported_address.local_address.ToString());
+
+    EXPECT_EQ(24, reported_address.prefix_length);
+  }
+
+  EXPECT_TRUE(addresses.empty());
+}
+
+TEST_F(NetlinkTest, ChangeLocalAddressAdd) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  QuicIpAddress ip = QuicIpAddress::Any6();
+  ExpectNetlinkPacket(
+      RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST,
+      [](void* buf, size_t len, int seq) {
+        struct nlmsghdr* netlink_message =
+            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
+        auto* err =
+            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
+        // Ack the request
+        err->error = 0;
+        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
+        return netlink_message->nlmsg_len;
+      },
+      [ip](const void* buf, size_t len) {
+        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
+        auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
+            NLMSG_DATA(netlink_message));
+        EXPECT_EQ(19, ifa->ifa_prefixlen);
+        EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
+        EXPECT_EQ(IFA_F_PERMANENT, ifa->ifa_flags);
+        EXPECT_EQ(7, ifa->ifa_index);
+        EXPECT_EQ(AF_INET6, ifa->ifa_family);
+
+        const struct rtattr* rta;
+        int payload_length = IFA_PAYLOAD(netlink_message);
+        int num_rta = 0;
+        for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
+             rta = RTA_NEXT(rta, payload_length)) {
+          switch (rta->rta_type) {
+            case IFA_LOCAL: {
+              EXPECT_EQ(ip.ToPackedString().size(), RTA_PAYLOAD(rta));
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(ip, address);
+              break;
+            }
+            case IFA_CACHEINFO: {
+              EXPECT_EQ(sizeof(struct ifa_cacheinfo), RTA_PAYLOAD(rta));
+              const auto* cache_info =
+                  reinterpret_cast<const struct ifa_cacheinfo*>(RTA_DATA(rta));
+              EXPECT_EQ(8, cache_info->ifa_prefered);  // common_typos_disable
+              EXPECT_EQ(6, cache_info->ifa_valid);
+              EXPECT_EQ(4, cache_info->cstamp);
+              EXPECT_EQ(2, cache_info->tstamp);
+              break;
+            }
+            default:
+              EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
+          }
+          ++num_rta;
+        }
+        EXPECT_EQ(2, num_rta);
+      });
+
+  struct {
+    struct rtattr rta;
+    struct ifa_cacheinfo cache_info;
+  } additional_rta;
+
+  additional_rta.rta.rta_type = IFA_CACHEINFO;
+  additional_rta.rta.rta_len = RTA_LENGTH(sizeof(struct ifa_cacheinfo));
+  additional_rta.cache_info.ifa_prefered = 8;
+  additional_rta.cache_info.ifa_valid = 6;
+  additional_rta.cache_info.cstamp = 4;
+  additional_rta.cache_info.tstamp = 2;
+
+  EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kAdd, ip, 19,
+                                          IFA_F_PERMANENT, RT_SCOPE_UNIVERSE,
+                                          {&additional_rta.rta}));
+}
+
+TEST_F(NetlinkTest, ChangeLocalAddressRemove) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  QuicIpAddress ip = QuicIpAddress::Any4();
+  ExpectNetlinkPacket(
+      RTM_DELADDR, NLM_F_ACK | NLM_F_REQUEST,
+      [](void* buf, size_t len, int seq) {
+        struct nlmsghdr* netlink_message =
+            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
+        auto* err =
+            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
+        // Ack the request
+        err->error = 0;
+        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
+        return netlink_message->nlmsg_len;
+      },
+      [ip](const void* buf, size_t len) {
+        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
+        auto* ifa = reinterpret_cast<const struct ifaddrmsg*>(
+            NLMSG_DATA(netlink_message));
+        EXPECT_EQ(32, ifa->ifa_prefixlen);
+        EXPECT_EQ(RT_SCOPE_UNIVERSE, ifa->ifa_scope);
+        EXPECT_EQ(0, ifa->ifa_flags);
+        EXPECT_EQ(7, ifa->ifa_index);
+        EXPECT_EQ(AF_INET, ifa->ifa_family);
+
+        const struct rtattr* rta;
+        int payload_length = IFA_PAYLOAD(netlink_message);
+        int num_rta = 0;
+        for (rta = IFA_RTA(ifa); RTA_OK(rta, payload_length);
+             rta = RTA_NEXT(rta, payload_length)) {
+          switch (rta->rta_type) {
+            case IFA_LOCAL: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(in_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(ip, address);
+              break;
+            }
+            default:
+              EXPECT_TRUE(false) << "Seeing rtattr that should not exist";
+          }
+          ++num_rta;
+        }
+        EXPECT_EQ(1, num_rta);
+      });
+
+  EXPECT_TRUE(netlink->ChangeLocalAddress(7, Netlink::Verb::kRemove, ip, 32, 0,
+                                          RT_SCOPE_UNIVERSE, {}));
+}
+
+TEST_F(NetlinkTest, GetRouteInfoWorks) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  QuicIpAddress destination;
+  ASSERT_TRUE(destination.FromString("f800::2"));
+  ExpectNetlinkPacket(RTM_GETROUTE, NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+                      [destination](void* buf, size_t len, int seq) {
+                        int ret = 0;
+                        struct nlmsghdr* netlink_message = CreateNetlinkMessage(
+                            buf, nullptr, RTM_NEWROUTE, seq);
+                        CreateRtmsg(netlink_message, AF_INET6, 48, 0, 0,
+                                    RT_TABLE_MAIN, RTPROT_STATIC, RT_SCOPE_LINK,
+                                    RTN_UNICAST, 0, destination, 7);
+                        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
+
+                        netlink_message = CreateNetlinkMessage(
+                            buf, netlink_message, NLMSG_DONE, seq);
+                        ret += NLMSG_ALIGN(netlink_message->nlmsg_len);
+
+                        QUIC_LOG(INFO) << "ret: " << ret;
+                        return ret;
+                      });
+
+  std::vector<Netlink::RoutingRule> routing_rules;
+  EXPECT_TRUE(netlink->GetRouteInfo(&routing_rules));
+
+  ASSERT_EQ(1, routing_rules.size());
+  EXPECT_EQ(RT_SCOPE_LINK, routing_rules[0].scope);
+  EXPECT_EQ(IpRange(destination, 48).ToString(),
+            routing_rules[0].destination_subnet.ToString());
+  EXPECT_FALSE(routing_rules[0].preferred_source.IsInitialized());
+  EXPECT_EQ(7, routing_rules[0].out_interface);
+}
+
+TEST_F(NetlinkTest, ChangeRouteAdd) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  QuicIpAddress preferred_ip;
+  preferred_ip.FromString("ff80:dead:beef::1");
+  IpRange subnet;
+  subnet.FromString("ff80:dead:beef::/48");
+  int egress_interface_index = 7;
+  ExpectNetlinkPacket(
+      RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
+      [](void* buf, size_t len, int seq) {
+        struct nlmsghdr* netlink_message =
+            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
+        auto* err =
+            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
+        // Ack the request
+        err->error = 0;
+        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
+        return netlink_message->nlmsg_len;
+      },
+      [preferred_ip, subnet, egress_interface_index](const void* buf,
+                                                     size_t len) {
+        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
+        auto* rtm =
+            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
+        EXPECT_EQ(AF_INET6, rtm->rtm_family);
+        EXPECT_EQ(48, rtm->rtm_dst_len);
+        EXPECT_EQ(0, rtm->rtm_src_len);
+        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
+        EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
+        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
+        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
+
+        const struct rtattr* rta;
+        int payload_length = RTM_PAYLOAD(netlink_message);
+        int num_rta = 0;
+        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
+             rta = RTA_NEXT(rta, payload_length)) {
+          switch (rta->rta_type) {
+            case RTA_PREFSRC: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(preferred_ip, address);
+              break;
+            }
+            case RTA_GATEWAY: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
+              break;
+            }
+            case RTA_OIF: {
+              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
+              const auto* interface_index =
+                  reinterpret_cast<const int*>(RTA_DATA(rta));
+              EXPECT_EQ(egress_interface_index, *interface_index);
+              break;
+            }
+            case RTA_DST: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(subnet.ToString(),
+                        IpRange(address, rtm->rtm_dst_len).ToString());
+              break;
+            }
+            case RTA_TABLE: {
+              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
+                        QboneConstants::kQboneRouteTableId);
+              break;
+            }
+            default:
+              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
+          }
+          ++num_rta;
+        }
+        EXPECT_EQ(5, num_rta);
+      });
+  EXPECT_TRUE(netlink->ChangeRoute(
+      Netlink::Verb::kAdd, QboneConstants::kQboneRouteTableId, subnet,
+      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
+}
+
+TEST_F(NetlinkTest, ChangeRouteRemove) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  QuicIpAddress preferred_ip;
+  preferred_ip.FromString("ff80:dead:beef::1");
+  IpRange subnet;
+  subnet.FromString("ff80:dead:beef::/48");
+  int egress_interface_index = 7;
+  ExpectNetlinkPacket(
+      RTM_DELROUTE, NLM_F_ACK | NLM_F_REQUEST,
+      [](void* buf, size_t len, int seq) {
+        struct nlmsghdr* netlink_message =
+            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
+        auto* err =
+            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
+        // Ack the request
+        err->error = 0;
+        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
+        return netlink_message->nlmsg_len;
+      },
+      [preferred_ip, subnet, egress_interface_index](const void* buf,
+                                                     size_t len) {
+        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
+        auto* rtm =
+            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
+        EXPECT_EQ(AF_INET6, rtm->rtm_family);
+        EXPECT_EQ(48, rtm->rtm_dst_len);
+        EXPECT_EQ(0, rtm->rtm_src_len);
+        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
+        EXPECT_EQ(RTPROT_UNSPEC, rtm->rtm_protocol);
+        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
+        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
+
+        const struct rtattr* rta;
+        int payload_length = RTM_PAYLOAD(netlink_message);
+        int num_rta = 0;
+        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
+             rta = RTA_NEXT(rta, payload_length)) {
+          switch (rta->rta_type) {
+            case RTA_PREFSRC: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(preferred_ip, address);
+              break;
+            }
+            case RTA_OIF: {
+              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
+              const auto* interface_index =
+                  reinterpret_cast<const int*>(RTA_DATA(rta));
+              EXPECT_EQ(egress_interface_index, *interface_index);
+              break;
+            }
+            case RTA_DST: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(subnet.ToString(),
+                        IpRange(address, rtm->rtm_dst_len).ToString());
+              break;
+            }
+            case RTA_TABLE: {
+              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
+                        QboneConstants::kQboneRouteTableId);
+              break;
+            }
+            default:
+              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
+          }
+          ++num_rta;
+        }
+        EXPECT_EQ(4, num_rta);
+      });
+  EXPECT_TRUE(netlink->ChangeRoute(
+      Netlink::Verb::kRemove, QboneConstants::kQboneRouteTableId, subnet,
+      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
+}
+
+TEST_F(NetlinkTest, ChangeRouteReplace) {
+  auto netlink = std::make_unique<Netlink>(&mock_kernel_);
+
+  QuicIpAddress preferred_ip;
+  preferred_ip.FromString("ff80:dead:beef::1");
+  IpRange subnet;
+  subnet.FromString("ff80:dead:beef::/48");
+  int egress_interface_index = 7;
+  ExpectNetlinkPacket(
+      RTM_NEWROUTE, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE,
+      [](void* buf, size_t len, int seq) {
+        struct nlmsghdr* netlink_message =
+            CreateNetlinkMessage(buf, nullptr, NLMSG_ERROR, seq);
+        auto* err =
+            reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(netlink_message));
+        // Ack the request
+        err->error = 0;
+        netlink_message->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
+        return netlink_message->nlmsg_len;
+      },
+      [preferred_ip, subnet, egress_interface_index](const void* buf,
+                                                     size_t len) {
+        auto* netlink_message = reinterpret_cast<const struct nlmsghdr*>(buf);
+        auto* rtm =
+            reinterpret_cast<const struct rtmsg*>(NLMSG_DATA(netlink_message));
+        EXPECT_EQ(AF_INET6, rtm->rtm_family);
+        EXPECT_EQ(48, rtm->rtm_dst_len);
+        EXPECT_EQ(0, rtm->rtm_src_len);
+        EXPECT_EQ(RT_TABLE_MAIN, rtm->rtm_table);
+        EXPECT_EQ(RTPROT_STATIC, rtm->rtm_protocol);
+        EXPECT_EQ(RT_SCOPE_LINK, rtm->rtm_scope);
+        EXPECT_EQ(RTN_UNICAST, rtm->rtm_type);
+
+        const struct rtattr* rta;
+        int payload_length = RTM_PAYLOAD(netlink_message);
+        int num_rta = 0;
+        for (rta = RTM_RTA(rtm); RTA_OK(rta, payload_length);
+             rta = RTA_NEXT(rta, payload_length)) {
+          switch (rta->rta_type) {
+            case RTA_PREFSRC: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(preferred_ip, address);
+              break;
+            }
+            case RTA_GATEWAY: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(*QboneConstants::GatewayAddress(), address);
+              break;
+            }
+            case RTA_OIF: {
+              ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta));
+              const auto* interface_index =
+                  reinterpret_cast<const int*>(RTA_DATA(rta));
+              EXPECT_EQ(egress_interface_index, *interface_index);
+              break;
+            }
+            case RTA_DST: {
+              const auto* raw_address =
+                  reinterpret_cast<const char*>(RTA_DATA(rta));
+              ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta));
+              QuicIpAddress address;
+              address.FromPackedString(raw_address, RTA_PAYLOAD(rta));
+              EXPECT_EQ(subnet.ToString(),
+                        IpRange(address, rtm->rtm_dst_len).ToString());
+              break;
+            }
+            case RTA_TABLE: {
+              ASSERT_EQ(*reinterpret_cast<uint32_t*>(RTA_DATA(rta)),
+                        QboneConstants::kQboneRouteTableId);
+              break;
+            }
+            default:
+              EXPECT_TRUE(false) << "Seeing rtattr that should not be sent";
+          }
+          ++num_rta;
+        }
+        EXPECT_EQ(5, num_rta);
+      });
+  EXPECT_TRUE(netlink->ChangeRoute(
+      Netlink::Verb::kReplace, QboneConstants::kQboneRouteTableId, subnet,
+      RT_SCOPE_LINK, preferred_ip, egress_interface_index));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/rtnetlink_message.cc b/quiche/quic/qbone/platform/rtnetlink_message.cc
new file mode 100644
index 0000000..17e412d
--- /dev/null
+++ b/quiche/quic/qbone/platform/rtnetlink_message.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/rtnetlink_message.h"
+
+#include <utility>
+
+namespace quic {
+
+RtnetlinkMessage::RtnetlinkMessage(uint16_t type,
+                                   uint16_t flags,
+                                   uint32_t seq,
+                                   uint32_t pid,
+                                   const void* payload_header,
+                                   size_t payload_header_length) {
+  auto* buf = new uint8_t[NLMSG_SPACE(payload_header_length)];
+  memset(buf, 0, NLMSG_SPACE(payload_header_length));
+
+  auto* message_header = reinterpret_cast<struct nlmsghdr*>(buf);
+  message_header->nlmsg_len = NLMSG_LENGTH(payload_header_length);
+  message_header->nlmsg_type = type;
+  message_header->nlmsg_flags = flags;
+  message_header->nlmsg_seq = seq;
+  message_header->nlmsg_pid = pid;
+
+  if (payload_header != nullptr) {
+    memcpy(NLMSG_DATA(message_header), payload_header, payload_header_length);
+  }
+  message_.push_back({buf, NLMSG_SPACE(payload_header_length)});
+}
+
+RtnetlinkMessage::~RtnetlinkMessage() {
+  for (const auto& iov : message_) {
+    delete[] reinterpret_cast<uint8_t*>(iov.iov_base);
+  }
+}
+
+void RtnetlinkMessage::AppendAttribute(uint16_t type,
+                                       const void* data,
+                                       uint16_t data_length) {
+  auto* buf = new uint8_t[RTA_SPACE(data_length)];
+  memset(buf, 0, RTA_SPACE(data_length));
+
+  auto* rta = reinterpret_cast<struct rtattr*>(buf);
+  static_assert(sizeof(uint16_t) == sizeof(rta->rta_len),
+                "struct rtattr uses unsigned short, it's no longer 16bits");
+  static_assert(sizeof(uint16_t) == sizeof(rta->rta_type),
+                "struct rtattr uses unsigned short, it's no longer 16bits");
+
+  rta->rta_len = RTA_LENGTH(data_length);
+  rta->rta_type = type;
+  memcpy(RTA_DATA(rta), data, data_length);
+
+  message_.push_back({buf, RTA_SPACE(data_length)});
+  AdjustMessageLength(rta->rta_len);
+}
+
+std::unique_ptr<struct iovec[]> RtnetlinkMessage::BuildIoVec() const {
+  auto message = std::make_unique<struct iovec[]>(message_.size());
+  int idx = 0;
+  for (const auto& vec : message_) {
+    message[idx++] = vec;
+  }
+  return message;
+}
+
+size_t RtnetlinkMessage::IoVecSize() const {
+  return message_.size();
+}
+
+void RtnetlinkMessage::AdjustMessageLength(size_t additional_data_length) {
+  MessageHeader()->nlmsg_len =
+      NLMSG_ALIGN(MessageHeader()->nlmsg_len) + additional_data_length;
+}
+
+struct nlmsghdr* RtnetlinkMessage::MessageHeader() {
+  return reinterpret_cast<struct nlmsghdr*>(message_[0].iov_base);
+}
+
+LinkMessage LinkMessage::New(RtnetlinkMessage::Operation request_operation,
+                             uint16_t flags,
+                             uint32_t seq,
+                             uint32_t pid,
+                             const struct ifinfomsg* interface_info_header) {
+  uint16_t request_type;
+  switch (request_operation) {
+    case RtnetlinkMessage::Operation::NEW:
+      request_type = RTM_NEWLINK;
+      break;
+    case RtnetlinkMessage::Operation::DEL:
+      request_type = RTM_DELLINK;
+      break;
+    case RtnetlinkMessage::Operation::GET:
+      request_type = RTM_GETLINK;
+      break;
+  }
+  bool is_get = request_type == RTM_GETLINK;
+
+  if (is_get) {
+    struct rtgenmsg g = {AF_UNSPEC};
+    return LinkMessage(request_type, flags, seq, pid, &g, sizeof(g));
+  }
+  return LinkMessage(request_type, flags, seq, pid, interface_info_header,
+                     sizeof(struct ifinfomsg));
+}
+
+AddressMessage AddressMessage::New(
+    RtnetlinkMessage::Operation request_operation,
+    uint16_t flags,
+    uint32_t seq,
+    uint32_t pid,
+    const struct ifaddrmsg* interface_address_header) {
+  uint16_t request_type;
+  switch (request_operation) {
+    case RtnetlinkMessage::Operation::NEW:
+      request_type = RTM_NEWADDR;
+      break;
+    case RtnetlinkMessage::Operation::DEL:
+      request_type = RTM_DELADDR;
+      break;
+    case RtnetlinkMessage::Operation::GET:
+      request_type = RTM_GETADDR;
+      break;
+  }
+  bool is_get = request_type == RTM_GETADDR;
+
+  if (is_get) {
+    struct rtgenmsg g = {AF_UNSPEC};
+    return AddressMessage(request_type, flags, seq, pid, &g, sizeof(g));
+  }
+  return AddressMessage(request_type, flags, seq, pid, interface_address_header,
+                        sizeof(struct ifaddrmsg));
+}
+
+RouteMessage RouteMessage::New(RtnetlinkMessage::Operation request_operation,
+                               uint16_t flags,
+                               uint32_t seq,
+                               uint32_t pid,
+                               const struct rtmsg* route_message_header) {
+  uint16_t request_type;
+  switch (request_operation) {
+    case RtnetlinkMessage::Operation::NEW:
+      request_type = RTM_NEWROUTE;
+      break;
+    case RtnetlinkMessage::Operation::DEL:
+      request_type = RTM_DELROUTE;
+      break;
+    case RtnetlinkMessage::Operation::GET:
+      request_type = RTM_GETROUTE;
+      break;
+  }
+  return RouteMessage(request_type, flags, seq, pid, route_message_header,
+                      sizeof(struct rtmsg));
+}
+
+RuleMessage RuleMessage::New(RtnetlinkMessage::Operation request_operation,
+                             uint16_t flags,
+                             uint32_t seq,
+                             uint32_t pid,
+                             const struct rtmsg* rule_message_header) {
+  uint16_t request_type;
+  switch (request_operation) {
+    case RtnetlinkMessage::Operation::NEW:
+      request_type = RTM_NEWRULE;
+      break;
+    case RtnetlinkMessage::Operation::DEL:
+      request_type = RTM_DELRULE;
+      break;
+    case RtnetlinkMessage::Operation::GET:
+      request_type = RTM_GETRULE;
+      break;
+  }
+  return RuleMessage(request_type, flags, seq, pid, rule_message_header,
+                     sizeof(rtmsg));
+}
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/rtnetlink_message.h b/quiche/quic/qbone/platform/rtnetlink_message.h
new file mode 100644
index 0000000..f6761d4
--- /dev/null
+++ b/quiche/quic/qbone/platform/rtnetlink_message.h
@@ -0,0 +1,125 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <memory>
+#include <vector>
+
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// This base class is used to construct an array struct iovec that represents a
+// rtnetlink message as defined in man 7 rtnet. Padding for message header
+// alignment to conform NLMSG_* and RTA_* macros is added at the end of each
+// iovec::iov_base.
+class RtnetlinkMessage {
+ public:
+  virtual ~RtnetlinkMessage();
+
+  enum class Operation {
+    NEW,
+    DEL,
+    GET,
+  };
+
+  // Appends a struct rtattr to the message. nlmsg_len and rta_len is handled
+  // properly.
+  // Override this to perform check on type.
+  virtual void AppendAttribute(uint16_t type,
+                               const void* data,
+                               uint16_t data_length);
+
+  // Builds the array of iovec that can be fed into sendmsg directly.
+  std::unique_ptr<struct iovec[]> BuildIoVec() const;
+
+  // The size of the array of iovec if BuildIovec is called.
+  size_t IoVecSize() const;
+
+ protected:
+  // Subclass should add their own message header immediately after the
+  // nlmsghdr. Make this private to force the creation of such header.
+  RtnetlinkMessage(uint16_t type,
+                   uint16_t flags,
+                   uint32_t seq,
+                   uint32_t pid,
+                   const void* payload_header,
+                   size_t payload_header_length);
+
+  // Adjusts nlmsg_len in the header assuming additional_data_length is appended
+  // at the end.
+  void AdjustMessageLength(size_t additional_data_length);
+
+ private:
+  // Convenient function for accessing the nlmsghdr.
+  struct nlmsghdr* MessageHeader();
+
+  std::vector<struct iovec> message_;
+};
+
+// Message for manipulating link level configuration as defined in man 7
+// rtnetlink. RTM_NEWLINK, RTM_DELLINK and RTM_GETLINK are supported.
+class LinkMessage : public RtnetlinkMessage {
+ public:
+  static LinkMessage New(RtnetlinkMessage::Operation request_operation,
+                         uint16_t flags,
+                         uint32_t seq,
+                         uint32_t pid,
+                         const struct ifinfomsg* interface_info_header);
+
+ private:
+  using RtnetlinkMessage::RtnetlinkMessage;
+};
+
+// Message for manipulating address level configuration as defined in man 7
+// rtnetlink. RTM_NEWADDR, RTM_NEWADDR and RTM_GETADDR are supported.
+class AddressMessage : public RtnetlinkMessage {
+ public:
+  static AddressMessage New(RtnetlinkMessage::Operation request_operation,
+                            uint16_t flags,
+                            uint32_t seq,
+                            uint32_t pid,
+                            const struct ifaddrmsg* interface_address_header);
+
+ private:
+  using RtnetlinkMessage::RtnetlinkMessage;
+};
+
+// Message for manipulating routing table as defined in man 7 rtnetlink.
+// RTM_NEWROUTE, RTM_DELROUTE and RTM_GETROUTE are supported.
+class RouteMessage : public RtnetlinkMessage {
+ public:
+  static RouteMessage New(RtnetlinkMessage::Operation request_operation,
+                          uint16_t flags,
+                          uint32_t seq,
+                          uint32_t pid,
+                          const struct rtmsg* route_message_header);
+
+ private:
+  using RtnetlinkMessage::RtnetlinkMessage;
+};
+
+class RuleMessage : public RtnetlinkMessage {
+ public:
+  static RuleMessage New(RtnetlinkMessage::Operation request_operation,
+                         uint16_t flags,
+                         uint32_t seq,
+                         uint32_t pid,
+                         const struct rtmsg* rule_message_header);
+
+ private:
+  using RtnetlinkMessage::RtnetlinkMessage;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_RTNETLINK_MESSAGE_H_
diff --git a/quiche/quic/qbone/platform/rtnetlink_message_test.cc b/quiche/quic/qbone/platform/rtnetlink_message_test.cc
new file mode 100644
index 0000000..5757e88
--- /dev/null
+++ b/quiche/quic/qbone/platform/rtnetlink_message_test.cc
@@ -0,0 +1,229 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/rtnetlink_message.h"
+
+#include <net/if_arp.h>
+
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace {
+
+using ::testing::StrEq;
+
+TEST(RtnetlinkMessageTest, LinkMessageCanBeCreatedForGetOperation) {
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
+  uint32_t seq = 42;
+  uint32_t pid = 7;
+  auto message = LinkMessage::New(RtnetlinkMessage::Operation::GET, flags, seq,
+                                  pid, nullptr);
+
+  // No rtattr appended.
+  EXPECT_EQ(1, message.IoVecSize());
+
+  // nlmsghdr is built properly.
+  auto iov = message.BuildIoVec();
+  EXPECT_EQ(NLMSG_SPACE(sizeof(struct rtgenmsg)), iov[0].iov_len);
+  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
+  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
+  EXPECT_EQ(RTM_GETLINK, netlink_message->nlmsg_type);
+  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
+  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
+  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
+
+  // We actually included rtgenmsg instead of the passed in ifinfomsg since this
+  // is a GET operation.
+  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
+}
+
+TEST(RtnetlinkMessageTest, LinkMessageCanBeCreatedForNewOperation) {
+  struct ifinfomsg interface_info_header = {AF_INET, /* pad */ 0, ARPHRD_TUNNEL,
+                                            3,       0,           0xffffffff};
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
+  uint32_t seq = 42;
+  uint32_t pid = 7;
+  auto message = LinkMessage::New(RtnetlinkMessage::Operation::NEW, flags, seq,
+                                  pid, &interface_info_header);
+
+  std::string device_name = "device0";
+  message.AppendAttribute(IFLA_IFNAME, device_name.c_str(), device_name.size());
+
+  // One rtattr appended.
+  EXPECT_EQ(2, message.IoVecSize());
+
+  // nlmsghdr is built properly.
+  auto iov = message.BuildIoVec();
+  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifinfomsg))),
+            iov[0].iov_len);
+  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
+  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifinfomsg))) +
+                RTA_LENGTH(device_name.size()),
+            netlink_message->nlmsg_len);
+  EXPECT_EQ(RTM_NEWLINK, netlink_message->nlmsg_type);
+  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
+  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
+  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
+
+  // ifinfomsg is included properly.
+  auto* parsed_header =
+      reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_message));
+  EXPECT_EQ(interface_info_header.ifi_family, parsed_header->ifi_family);
+  EXPECT_EQ(interface_info_header.ifi_type, parsed_header->ifi_type);
+  EXPECT_EQ(interface_info_header.ifi_index, parsed_header->ifi_index);
+  EXPECT_EQ(interface_info_header.ifi_flags, parsed_header->ifi_flags);
+  EXPECT_EQ(interface_info_header.ifi_change, parsed_header->ifi_change);
+
+  // rtattr is handled properly.
+  EXPECT_EQ(RTA_SPACE(device_name.size()), iov[1].iov_len);
+  auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
+  EXPECT_EQ(IFLA_IFNAME, rta->rta_type);
+  EXPECT_EQ(RTA_LENGTH(device_name.size()), rta->rta_len);
+  EXPECT_THAT(device_name,
+              StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
+                                RTA_PAYLOAD(rta))));
+}
+
+TEST(RtnetlinkMessageTest, AddressMessageCanBeCreatedForGetOperation) {
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
+  uint32_t seq = 42;
+  uint32_t pid = 7;
+  auto message = AddressMessage::New(RtnetlinkMessage::Operation::GET, flags,
+                                     seq, pid, nullptr);
+
+  // No rtattr appended.
+  EXPECT_EQ(1, message.IoVecSize());
+
+  // nlmsghdr is built properly.
+  auto iov = message.BuildIoVec();
+  EXPECT_EQ(NLMSG_SPACE(sizeof(struct rtgenmsg)), iov[0].iov_len);
+  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
+  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
+  EXPECT_EQ(RTM_GETADDR, netlink_message->nlmsg_type);
+  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
+  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
+  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
+
+  // We actually included rtgenmsg instead of the passed in ifinfomsg since this
+  // is a GET operation.
+  EXPECT_EQ(NLMSG_LENGTH(sizeof(struct rtgenmsg)), netlink_message->nlmsg_len);
+}
+
+TEST(RtnetlinkMessageTest, AddressMessageCanBeCreatedForNewOperation) {
+  struct ifaddrmsg interface_address_header = {AF_INET,
+                                               /* prefixlen */ 24,
+                                               /* flags */ 0,
+                                               /* scope */ RT_SCOPE_LINK,
+                                               /* index */ 4};
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
+  uint32_t seq = 42;
+  uint32_t pid = 7;
+  auto message = AddressMessage::New(RtnetlinkMessage::Operation::NEW, flags,
+                                     seq, pid, &interface_address_header);
+
+  QuicIpAddress ip;
+  QUICHE_CHECK(ip.FromString("10.0.100.3"));
+  message.AppendAttribute(IFA_ADDRESS, ip.ToPackedString().c_str(),
+                          ip.ToPackedString().size());
+
+  // One rtattr is appended.
+  EXPECT_EQ(2, message.IoVecSize());
+
+  // nlmsghdr is built properly.
+  auto iov = message.BuildIoVec();
+  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifaddrmsg))),
+            iov[0].iov_len);
+  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
+  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct ifaddrmsg))) +
+                RTA_LENGTH(ip.ToPackedString().size()),
+            netlink_message->nlmsg_len);
+  EXPECT_EQ(RTM_NEWADDR, netlink_message->nlmsg_type);
+  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
+  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
+  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
+
+  // ifaddrmsg is included properly.
+  auto* parsed_header =
+      reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_message));
+  EXPECT_EQ(interface_address_header.ifa_family, parsed_header->ifa_family);
+  EXPECT_EQ(interface_address_header.ifa_prefixlen,
+            parsed_header->ifa_prefixlen);
+  EXPECT_EQ(interface_address_header.ifa_flags, parsed_header->ifa_flags);
+  EXPECT_EQ(interface_address_header.ifa_scope, parsed_header->ifa_scope);
+  EXPECT_EQ(interface_address_header.ifa_index, parsed_header->ifa_index);
+
+  // rtattr is handled properly.
+  EXPECT_EQ(RTA_SPACE(ip.ToPackedString().size()), iov[1].iov_len);
+  auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
+  EXPECT_EQ(IFA_ADDRESS, rta->rta_type);
+  EXPECT_EQ(RTA_LENGTH(ip.ToPackedString().size()), rta->rta_len);
+  EXPECT_THAT(ip.ToPackedString(),
+              StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
+                                RTA_PAYLOAD(rta))));
+}
+
+TEST(RtnetlinkMessageTest, RouteMessageCanBeCreatedFromNewOperation) {
+  struct rtmsg route_message_header = {AF_INET6,
+                                       /* rtm_dst_len */ 48,
+                                       /* rtm_src_len */ 0,
+                                       /* rtm_tos */ 0,
+                                       /* rtm_table */ RT_TABLE_MAIN,
+                                       /* rtm_protocol */ RTPROT_STATIC,
+                                       /* rtm_scope */ RT_SCOPE_LINK,
+                                       /* rtm_type */ RTN_LOCAL,
+                                       /* rtm_flags */ 0};
+  uint16_t flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
+  uint32_t seq = 42;
+  uint32_t pid = 7;
+  auto message = RouteMessage::New(RtnetlinkMessage::Operation::NEW, flags, seq,
+                                   pid, &route_message_header);
+
+  QuicIpAddress preferred_source;
+  QUICHE_CHECK(preferred_source.FromString("ff80::1"));
+  message.AppendAttribute(RTA_PREFSRC,
+                          preferred_source.ToPackedString().c_str(),
+                          preferred_source.ToPackedString().size());
+
+  // One rtattr is appended.
+  EXPECT_EQ(2, message.IoVecSize());
+
+  // nlmsghdr is built properly
+  auto iov = message.BuildIoVec();
+  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct rtmsg))), iov[0].iov_len);
+  auto* netlink_message = reinterpret_cast<struct nlmsghdr*>(iov[0].iov_base);
+  EXPECT_EQ(NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct rtmsg))) +
+                RTA_LENGTH(preferred_source.ToPackedString().size()),
+            netlink_message->nlmsg_len);
+  EXPECT_EQ(RTM_NEWROUTE, netlink_message->nlmsg_type);
+  EXPECT_EQ(flags, netlink_message->nlmsg_flags);
+  EXPECT_EQ(seq, netlink_message->nlmsg_seq);
+  EXPECT_EQ(pid, netlink_message->nlmsg_pid);
+
+  // rtmsg is included properly.
+  auto* parsed_header =
+      reinterpret_cast<struct rtmsg*>(NLMSG_DATA(netlink_message));
+  EXPECT_EQ(route_message_header.rtm_family, parsed_header->rtm_family);
+  EXPECT_EQ(route_message_header.rtm_dst_len, parsed_header->rtm_dst_len);
+  EXPECT_EQ(route_message_header.rtm_src_len, parsed_header->rtm_src_len);
+  EXPECT_EQ(route_message_header.rtm_tos, parsed_header->rtm_tos);
+  EXPECT_EQ(route_message_header.rtm_table, parsed_header->rtm_table);
+  EXPECT_EQ(route_message_header.rtm_protocol, parsed_header->rtm_protocol);
+  EXPECT_EQ(route_message_header.rtm_scope, parsed_header->rtm_scope);
+  EXPECT_EQ(route_message_header.rtm_type, parsed_header->rtm_type);
+  EXPECT_EQ(route_message_header.rtm_flags, parsed_header->rtm_flags);
+
+  // rtattr is handled properly.
+  EXPECT_EQ(RTA_SPACE(preferred_source.ToPackedString().size()),
+            iov[1].iov_len);
+  auto* rta = reinterpret_cast<struct rtattr*>(iov[1].iov_base);
+  EXPECT_EQ(RTA_PREFSRC, rta->rta_type);
+  EXPECT_EQ(RTA_LENGTH(preferred_source.ToPackedString().size()), rta->rta_len);
+  EXPECT_THAT(preferred_source.ToPackedString(),
+              StrEq(std::string(reinterpret_cast<char*>(RTA_DATA(rta)),
+                                RTA_PAYLOAD(rta))));
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/tcp_packet.cc b/quiche/quic/qbone/platform/tcp_packet.cc
new file mode 100644
index 0000000..8bc8cb7
--- /dev/null
+++ b/quiche/quic/qbone/platform/tcp_packet.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/tcp_packet.h"
+
+#include <netinet/ip6.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/qbone/platform/internet_checksum.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+namespace {
+
+constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
+constexpr size_t kTcpTtl = 64;
+
+struct TCPv6Packet {
+  ip6_hdr ip_header;
+  tcphdr tcp_header;
+};
+
+struct TCPv6PseudoHeader {
+  uint32_t payload_size{};
+  uint8_t zeros[3] = {0, 0, 0};
+  uint8_t next_header = IPPROTO_TCP;
+};
+
+}  // namespace
+
+void CreateTcpResetPacket(absl::string_view original_packet,
+                          const std::function<void(absl::string_view)>& cb) {
+  // By the time this method is called, original_packet should be fairly
+  // strongly validated. However, it's better to be more paranoid than not, so
+  // here are a bunch of very obvious checks.
+  if (QUIC_PREDICT_FALSE(original_packet.size() < sizeof(ip6_hdr))) {
+    return;
+  }
+  auto* ip6_header = reinterpret_cast<const ip6_hdr*>(original_packet.data());
+  if (QUIC_PREDICT_FALSE(ip6_header->ip6_vfc >> 4 != 6)) {
+    return;
+  }
+  if (QUIC_PREDICT_FALSE(ip6_header->ip6_nxt != IPPROTO_TCP)) {
+    return;
+  }
+  if (QUIC_PREDICT_FALSE(quiche::QuicheEndian::NetToHost16(
+                             ip6_header->ip6_plen) < sizeof(tcphdr))) {
+    return;
+  }
+  auto* tcp_header = reinterpret_cast<const tcphdr*>(ip6_header + 1);
+
+  // Now that the original packet has been confirmed to be well-formed, it's
+  // time to make the TCP RST packet.
+  TCPv6Packet tcp_packet{};
+
+  const size_t payload_size = sizeof(tcphdr);
+
+  // Set version to 6.
+  tcp_packet.ip_header.ip6_vfc = 0x6 << 4;
+  // Set the payload size, protocol and TTL.
+  tcp_packet.ip_header.ip6_plen =
+      quiche::QuicheEndian::HostToNet16(payload_size);
+  tcp_packet.ip_header.ip6_nxt = IPPROTO_TCP;
+  tcp_packet.ip_header.ip6_hops = kTcpTtl;
+  // Since the TCP RST is impersonating the endpoint, flip the source and
+  // destination addresses from the original packet.
+  tcp_packet.ip_header.ip6_src = ip6_header->ip6_dst;
+  tcp_packet.ip_header.ip6_dst = ip6_header->ip6_src;
+
+  // The same is true about the TCP ports
+  tcp_packet.tcp_header.dest = tcp_header->source;
+  tcp_packet.tcp_header.source = tcp_header->dest;
+
+  // There are no extensions in this header, so size is trivial
+  tcp_packet.tcp_header.doff = sizeof(tcphdr) >> 2;
+  // Checksum is 0 before it is computed
+  tcp_packet.tcp_header.check = 0;
+
+  // Per RFC 793, TCP RST comes in one of 3 flavors:
+  //
+  // * connection CLOSED
+  // * connection in non-synchronized state (LISTEN, SYN-SENT, SYN-RECEIVED)
+  // * connection in synchronized state (ESTABLISHED, FIN-WAIT-1, etc.)
+  //
+  // QBONE is acting like a firewall, so the RFC text of interest is the CLOSED
+  // state. Note, however, that it is possible for a connection to actually be
+  // in the FIN-WAIT-1 state on the remote end, but the processing logic does
+  // not change.
+  tcp_packet.tcp_header.rst = 1;
+
+  // If the incoming segment has an ACK field, the reset takes its sequence
+  // number from the ACK field of the segment,
+  if (tcp_header->ack) {
+    tcp_packet.tcp_header.seq = tcp_header->ack_seq;
+  } else {
+    // Otherwise the reset has sequence number zero and the ACK field is set to
+    // the sum of the sequence number and segment length of the incoming segment
+    tcp_packet.tcp_header.ack = 1;
+    tcp_packet.tcp_header.seq = 0;
+    tcp_packet.tcp_header.ack_seq = quiche::QuicheEndian::HostToNet32(
+        quiche::QuicheEndian::NetToHost32(tcp_header->seq) + 1);
+  }
+
+  TCPv6PseudoHeader pseudo_header{};
+  pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);
+
+  InternetChecksum checksum;
+  // Pseudoheader.
+  checksum.Update(tcp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
+  checksum.Update(tcp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
+  checksum.Update(reinterpret_cast<char*>(&pseudo_header),
+                  sizeof(pseudo_header));
+  // TCP header.
+  checksum.Update(reinterpret_cast<const char*>(&tcp_packet.tcp_header),
+                  sizeof(tcp_packet.tcp_header));
+  // There is no body.
+  tcp_packet.tcp_header.check = checksum.Value();
+
+  const char* packet = reinterpret_cast<char*>(&tcp_packet);
+
+  cb(absl::string_view(packet, sizeof(tcp_packet)));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/platform/tcp_packet.h b/quiche/quic/qbone/platform/tcp_packet.h
new file mode 100644
index 0000000..7e9550f
--- /dev/null
+++ b/quiche/quic/qbone/platform/tcp_packet.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
+#define QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <functional>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+// Creates an TCPv6 RST packet, returning a packed string representation of the
+// packet to |cb|.
+void CreateTcpResetPacket(absl::string_view original_packet,
+                          const std::function<void(absl::string_view)>& cb);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_PLATFORM_TCP_PACKET_H_
diff --git a/quiche/quic/qbone/platform/tcp_packet_test.cc b/quiche/quic/qbone/platform/tcp_packet_test.cc
new file mode 100644
index 0000000..c9ada0c
--- /dev/null
+++ b/quiche/quic/qbone/platform/tcp_packet_test.cc
@@ -0,0 +1,117 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/platform/tcp_packet.h"
+
+#include <netinet/ip6.h>
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace {
+
+// clang-format off
+constexpr uint8_t kReferenceTCPSYNPacket[] = {
+  // START IPv6 Header
+  // IPv6 with zero ToS and flow label
+  0x60, 0x00, 0x00, 0x00,
+  // Payload is 40 bytes
+  0x00, 0x28,
+  // Next header is TCP (6)
+  0x06,
+  // Hop limit is 64
+  0x40,
+  // Source address of ::1
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  // Destination address of ::1
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  // END IPv6 Header
+  // START TCPv6 Header
+  // Source port
+  0xac, 0x1e,
+  // Destination port
+  0x27, 0x0f,
+  // Sequence number
+  0x4b, 0x01, 0xe8, 0x99,
+  // Acknowledgement Sequence number,
+  0x00, 0x00, 0x00, 0x00,
+  // Offset
+  0xa0,
+  // Flags
+  0x02,
+  // Window
+  0xaa, 0xaa,
+  // Checksum
+  0x2e, 0x21,
+  // Urgent
+  0x00, 0x00,
+  // END TCPv6 Header
+  // Options
+  0x02, 0x04, 0xff, 0xc4, 0x04, 0x02, 0x08, 0x0a,
+  0x1b, 0xb8, 0x52, 0xa1, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x03, 0x03, 0x07,
+};
+
+constexpr uint8_t kReferenceTCPRSTPacket[] = {
+  // START IPv6 Header
+  // IPv6 with zero ToS and flow label
+  0x60, 0x00, 0x00, 0x00,
+  // Payload is 20 bytes
+  0x00, 0x14,
+  // Next header is TCP (6)
+  0x06,
+  // Hop limit is 64
+  0x40,
+  // Source address of ::1
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  // Destination address of ::1
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  // END IPv6 Header
+  // START TCPv6 Header
+  // Source port
+  0x27, 0x0f,
+  // Destination port
+  0xac, 0x1e,
+  // Sequence number
+  0x00, 0x00, 0x00, 0x00,
+  // Acknowledgement Sequence number,
+  0x4b, 0x01, 0xe8, 0x9a,
+  // Offset
+  0x50,
+  // Flags
+  0x14,
+  // Window
+  0x00, 0x00,
+  // Checksum
+  0xa9, 0x05,
+  // Urgent
+  0x00, 0x00,
+  // END TCPv6 Header
+};
+// clang-format on
+
+}  // namespace
+
+TEST(TcpPacketTest, CreatedPacketMatchesReference) {
+  absl::string_view syn =
+      absl::string_view(reinterpret_cast<const char*>(kReferenceTCPSYNPacket),
+                        sizeof(kReferenceTCPSYNPacket));
+  absl::string_view expected_packet =
+      absl::string_view(reinterpret_cast<const char*>(kReferenceTCPRSTPacket),
+                        sizeof(kReferenceTCPRSTPacket));
+  CreateTcpResetPacket(syn, [&expected_packet](absl::string_view packet) {
+    QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
+    ASSERT_EQ(packet, expected_packet);
+  });
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_client.cc b/quiche/quic/qbone/qbone_client.cc
new file mode 100644
index 0000000..9f2fb09
--- /dev/null
+++ b/quiche/quic/qbone/qbone_client.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_client.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/quic/qbone/qbone_stream.h"
+
+namespace quic {
+namespace {
+std::unique_ptr<QuicClientBase::NetworkHelper> CreateNetworkHelper(
+    QuicEpollServer* epoll_server,
+    QboneClient* client) {
+  std::unique_ptr<QuicClientBase::NetworkHelper> helper =
+      std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, client);
+  quic::AdjustTestValue("QboneClient/network_helper", &helper);
+  return helper;
+}
+}  // namespace
+
+QboneClient::QboneClient(QuicSocketAddress server_address,
+                         const QuicServerId& server_id,
+                         const ParsedQuicVersionVector& supported_versions,
+                         QuicSession::Visitor* session_owner,
+                         const QuicConfig& config,
+                         QuicEpollServer* epoll_server,
+                         std::unique_ptr<ProofVerifier> proof_verifier,
+                         QbonePacketWriter* qbone_writer,
+                         QboneClientControlStream::Handler* qbone_handler)
+    : QuicClientBase(
+          server_id,
+          supported_versions,
+          config,
+          new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
+          new QuicEpollAlarmFactory(epoll_server),
+          CreateNetworkHelper(epoll_server, this),
+          std::move(proof_verifier),
+          nullptr),
+      qbone_writer_(qbone_writer),
+      qbone_handler_(qbone_handler),
+      session_owner_(session_owner) {
+  set_server_address(server_address);
+  crypto_config()->set_alpn("qbone");
+}
+
+QboneClient::~QboneClient() {
+  ResetSession();
+}
+
+QboneClientSession* QboneClient::qbone_session() {
+  return static_cast<QboneClientSession*>(QuicClientBase::session());
+}
+
+void QboneClient::ProcessPacketFromNetwork(absl::string_view packet) {
+  qbone_session()->ProcessPacketFromNetwork(packet);
+}
+
+bool QboneClient::EarlyDataAccepted() {
+  return qbone_session()->EarlyDataAccepted();
+}
+
+bool QboneClient::ReceivedInchoateReject() {
+  return qbone_session()->ReceivedInchoateReject();
+}
+
+int QboneClient::GetNumSentClientHellosFromSession() {
+  return qbone_session()->GetNumSentClientHellos();
+}
+
+int QboneClient::GetNumReceivedServerConfigUpdatesFromSession() {
+  return qbone_session()->GetNumReceivedServerConfigUpdates();
+}
+
+void QboneClient::ResendSavedData() {
+  // no op.
+}
+
+void QboneClient::ClearDataToResend() {
+  // no op.
+}
+
+bool QboneClient::HasActiveRequests() {
+  return qbone_session()->HasActiveRequests();
+}
+
+class QboneClientSessionWithConnection : public QboneClientSession {
+ public:
+  using QboneClientSession::QboneClientSession;
+
+  ~QboneClientSessionWithConnection() override { DeleteConnection(); }
+};
+
+// Takes ownership of |connection|.
+std::unique_ptr<QuicSession> QboneClient::CreateQuicClientSession(
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection) {
+  return std::make_unique<QboneClientSessionWithConnection>(
+      connection, crypto_config(), session_owner(), *config(),
+      supported_versions, server_id(), qbone_writer_, qbone_handler_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_client.h b/quiche/quic/qbone/qbone_client.h
new file mode 100644
index 0000000..ca4a32a
--- /dev/null
+++ b/quiche/quic/qbone/qbone_client.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
+#define QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/qbone/qbone_client_interface.h"
+#include "quiche/quic/qbone/qbone_client_session.h"
+#include "quiche/quic/qbone/qbone_packet_writer.h"
+#include "quiche/quic/tools/quic_client_base.h"
+#include "quiche/quic/tools/quic_client_epoll_network_helper.h"
+
+namespace quic {
+// A QboneClient encapsulates connecting to a server via an epoll server
+// and setting up a QBONE tunnel. See the QboneTestClient in qbone_client_test
+// for usage.
+class QboneClient : public QuicClientBase, public QboneClientInterface {
+ public:
+  // Note that the epoll server, QBONE writer, and handler are owned
+  // by the caller.
+  QboneClient(QuicSocketAddress server_address,
+              const QuicServerId& server_id,
+              const ParsedQuicVersionVector& supported_versions,
+              QuicSession::Visitor* session_owner,
+              const QuicConfig& config,
+              QuicEpollServer* epoll_server,
+              std::unique_ptr<ProofVerifier> proof_verifier,
+              QbonePacketWriter* qbone_writer,
+              QboneClientControlStream::Handler* qbone_handler);
+  ~QboneClient() override;
+  QboneClientSession* qbone_session();
+
+  // From QboneClientInterface. Accepts a given packet from the network and
+  // sends the packet down to the QBONE connection.
+  void ProcessPacketFromNetwork(absl::string_view packet) override;
+
+  bool EarlyDataAccepted() override;
+  bool ReceivedInchoateReject() override;
+
+ protected:
+  int GetNumSentClientHellosFromSession() override;
+  int GetNumReceivedServerConfigUpdatesFromSession() override;
+
+  // This client does not resend saved data. This will be a no-op.
+  void ResendSavedData() override;
+
+  // This client does not resend saved data. This will be a no-op.
+  void ClearDataToResend() override;
+
+  // Takes ownership of |connection|.
+  std::unique_ptr<QuicSession> CreateQuicClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection) override;
+
+  QbonePacketWriter* qbone_writer() { return qbone_writer_; }
+
+  QboneClientControlStream::Handler* qbone_control_handler() {
+    return qbone_handler_;
+  }
+
+  QuicSession::Visitor* session_owner() {
+    return session_owner_;
+  }
+
+  bool HasActiveRequests() override;
+
+ private:
+  QbonePacketWriter* qbone_writer_;
+  QboneClientControlStream::Handler* qbone_handler_;
+
+  QuicSession::Visitor* session_owner_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_CLIENT_H_
diff --git a/quic/qbone/qbone_client_interface.h b/quiche/quic/qbone/qbone_client_interface.h
similarity index 100%
rename from quic/qbone/qbone_client_interface.h
rename to quiche/quic/qbone/qbone_client_interface.h
diff --git a/quiche/quic/qbone/qbone_client_session.cc b/quiche/quic/qbone/qbone_client_session.cc
new file mode 100644
index 0000000..ab21a34
--- /dev/null
+++ b/quiche/quic/qbone/qbone_client_session.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_client_session.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, qbone_client_defer_control_stream_creation, true,
+    "If true, control stream in QBONE client session is created after "
+    "encryption established.");
+
+namespace quic {
+
+QboneClientSession::QboneClientSession(
+    QuicConnection* connection,
+    QuicCryptoClientConfig* quic_crypto_client_config,
+    QuicSession::Visitor* owner,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicServerId& server_id,
+    QbonePacketWriter* writer,
+    QboneClientControlStream::Handler* handler)
+    : QboneSessionBase(connection, owner, config, supported_versions, writer),
+      server_id_(server_id),
+      quic_crypto_client_config_(quic_crypto_client_config),
+      handler_(handler) {}
+
+QboneClientSession::~QboneClientSession() {}
+
+std::unique_ptr<QuicCryptoStream> QboneClientSession::CreateCryptoStream() {
+  return std::make_unique<QuicCryptoClientStream>(
+      server_id_, this, nullptr, quic_crypto_client_config_, this,
+      /*has_application_state = */ true);
+}
+
+void QboneClientSession::CreateControlStream() {
+  if (control_stream_ != nullptr) {
+    return;
+  }
+  // Register the reserved control stream.
+  QuicStreamId next_id = GetNextOutgoingBidirectionalStreamId();
+  QUICHE_DCHECK_EQ(next_id,
+                   QboneConstants::GetControlStreamId(transport_version()));
+  auto control_stream =
+      std::make_unique<QboneClientControlStream>(this, handler_);
+  control_stream_ = control_stream.get();
+  ActivateStream(std::move(control_stream));
+}
+
+void QboneClientSession::Initialize() {
+  // Initialize must be called first, as that's what generates the crypto
+  // stream.
+  QboneSessionBase::Initialize();
+  static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream())
+      ->CryptoConnect();
+  if (!GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation)) {
+    CreateControlStream();
+  }
+}
+
+void QboneClientSession::SetDefaultEncryptionLevel(
+    quic::EncryptionLevel level) {
+  QboneSessionBase::SetDefaultEncryptionLevel(level);
+  if (GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation) &&
+      level == quic::ENCRYPTION_FORWARD_SECURE) {
+    CreateControlStream();
+  }
+}
+
+int QboneClientSession::GetNumSentClientHellos() const {
+  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
+      ->num_sent_client_hellos();
+}
+
+bool QboneClientSession::EarlyDataAccepted() const {
+  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
+      ->EarlyDataAccepted();
+}
+
+bool QboneClientSession::ReceivedInchoateReject() const {
+  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
+      ->ReceivedInchoateReject();
+}
+
+int QboneClientSession::GetNumReceivedServerConfigUpdates() const {
+  return static_cast<const QuicCryptoClientStreamBase*>(GetCryptoStream())
+      ->num_scup_messages_received();
+}
+
+bool QboneClientSession::SendServerRequest(const QboneServerRequest& request) {
+  if (!control_stream_) {
+    QUIC_BUG(quic_bug_11056_1)
+        << "Cannot send server request before control stream is created.";
+    return false;
+  }
+  return control_stream_->SendRequest(request);
+}
+
+void QboneClientSession::ProcessPacketFromNetwork(absl::string_view packet) {
+  SendPacketToPeer(packet);
+}
+
+void QboneClientSession::ProcessPacketFromPeer(absl::string_view packet) {
+  writer_->WritePacketToNetwork(packet.data(), packet.size());
+}
+
+void QboneClientSession::OnProofValid(
+    const QuicCryptoClientConfig::CachedState& cached) {}
+
+void QboneClientSession::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& verify_details) {}
+
+bool QboneClientSession::HasActiveRequests() const {
+  return GetNumActiveStreams() + num_draining_streams() > 0;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_client_session.h b/quiche/quic/qbone/qbone_client_session.h
new file mode 100644
index 0000000..37a1c28
--- /dev/null
+++ b/quiche/quic/qbone/qbone_client_session.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
+#define QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/qbone/qbone_control.pb.h"
+#include "quiche/quic/qbone/qbone_control_stream.h"
+#include "quiche/quic/qbone/qbone_packet_writer.h"
+#include "quiche/quic/qbone/qbone_session_base.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QboneClientSession
+    : public QboneSessionBase,
+      public QuicCryptoClientStream::ProofHandler {
+ public:
+  QboneClientSession(QuicConnection* connection,
+                     QuicCryptoClientConfig* quic_crypto_client_config,
+                     QuicSession::Visitor* owner,
+                     const QuicConfig& config,
+                     const ParsedQuicVersionVector& supported_versions,
+                     const QuicServerId& server_id,
+                     QbonePacketWriter* writer,
+                     QboneClientControlStream::Handler* handler);
+  QboneClientSession(const QboneClientSession&) = delete;
+  QboneClientSession& operator=(const QboneClientSession&) = delete;
+  ~QboneClientSession() override;
+
+  // QuicSession overrides. This will initiate the crypto stream.
+  void Initialize() override;
+  // Override to create control stream at FORWARD_SECURE encryption level.
+  void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
+
+  // Returns the number of client hello messages that have been sent on the
+  // crypto stream. If the handshake has completed then this is one greater
+  // than the number of round-trips needed for the handshake.
+  int GetNumSentClientHellos() const;
+
+  // Returns true if early data (0-RTT data) was sent and the server accepted
+  // it.
+  bool EarlyDataAccepted() const;
+
+  // Returns true if the handshake was delayed one round trip by the server
+  // because the server wanted proof the client controls its source address
+  // before progressing further. In Google QUIC, this would be due to an
+  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
+  // to a Retry packet.
+  // TODO(nharper): Consider a better name for this method.
+  bool ReceivedInchoateReject() const;
+
+  int GetNumReceivedServerConfigUpdates() const;
+
+  bool SendServerRequest(const QboneServerRequest& request);
+
+  void ProcessPacketFromNetwork(absl::string_view packet) override;
+  void ProcessPacketFromPeer(absl::string_view packet) override;
+
+  // Returns true if there are active requests on this session.
+  bool HasActiveRequests() const;
+
+ protected:
+  // QboneSessionBase interface implementation.
+  std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
+
+  // Instantiate QboneClientControlStream.
+  void CreateControlStream();
+
+  // ProofHandler interface implementation.
+  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  QuicServerId server_id() { return server_id_; }
+  QuicCryptoClientConfig* crypto_client_config() {
+    return quic_crypto_client_config_;
+  }
+
+ private:
+  QuicServerId server_id_;
+  // Config for QUIC crypto client stream, used by the client.
+  QuicCryptoClientConfig* quic_crypto_client_config_;
+  // Passed to the control stream.
+  QboneClientControlStream::Handler* handler_;
+  // The unowned control stream.
+  QboneClientControlStream* control_stream_ = nullptr;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_CLIENT_SESSION_H_
diff --git a/quiche/quic/qbone/qbone_client_test.cc b/quiche/quic/qbone/qbone_client_test.cc
new file mode 100644
index 0000000..dd6aa43
--- /dev/null
+++ b/quiche/quic/qbone/qbone_client_test.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Sets up a dispatcher and sends requests via the QboneClient.
+
+#include "quiche/quic/qbone/qbone_client.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_default_packet_writer.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_packet_reader.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
+#include "quiche/quic/qbone/qbone_server_session.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+#include "quiche/quic/test_tools/quic_server_peer.h"
+#include "quiche/quic/test_tools/server_thread.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_server.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+ParsedQuicVersionVector GetTestParams() {
+  ParsedQuicVersionVector test_versions;
+
+  // TODO(b/113130636): Make QBONE work with TLS.
+  for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
+    // QBONE requires MESSAGE frames
+    if (!version.SupportsMessageFrames()) {
+      continue;
+    }
+    test_versions.push_back(version);
+  }
+
+  return test_versions;
+}
+
+std::string TestPacketIn(const std::string& body) {
+  return PrependIPv6HeaderForTest(body, 5);
+}
+
+std::string TestPacketOut(const std::string& body) {
+  return PrependIPv6HeaderForTest(body, 4);
+}
+
+class DataSavingQbonePacketWriter : public QbonePacketWriter {
+ public:
+  void WritePacketToNetwork(const char* packet, size_t size) override {
+    QuicWriterMutexLock lock(&mu_);
+    data_.push_back(std::string(packet, size));
+  }
+
+  std::vector<std::string> data() {
+    QuicWriterMutexLock lock(&mu_);
+    return data_;
+  }
+
+ private:
+  QuicMutex mu_;
+  std::vector<std::string> data_;
+};
+
+// A subclass of a QBONE session that will own the connection passed in.
+class ConnectionOwningQboneServerSession : public QboneServerSession {
+ public:
+  ConnectionOwningQboneServerSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      Visitor* owner,
+      const QuicConfig& config,
+      const QuicCryptoServerConfig* quic_crypto_server_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QbonePacketWriter* writer)
+      : QboneServerSession(supported_versions,
+                           connection,
+                           owner,
+                           config,
+                           quic_crypto_server_config,
+                           compressed_certs_cache,
+                           writer,
+                           TestLoopback6(),
+                           TestLoopback6(),
+                           64,
+                           nullptr),
+        connection_(connection) {}
+
+ private:
+  // Note that we don't expect the QboneServerSession or any of its parent
+  // classes to do anything with the connection_ in their destructors.
+  std::unique_ptr<QuicConnection> connection_;
+};
+
+class QuicQboneDispatcher : public QuicDispatcher {
+ public:
+  QuicQboneDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      QbonePacketWriter* writer)
+      : QuicDispatcher(config,
+                       crypto_config,
+                       version_manager,
+                       std::move(helper),
+                       std::move(session_helper),
+                       std::move(alarm_factory),
+                       kQuicDefaultConnectionIdLength),
+        writer_(writer) {}
+
+  std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId id, const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version,
+      const ParsedClientHello& /*parsed_chlo*/) override {
+    QUICHE_CHECK_EQ(alpn, "qbone");
+    QuicConnection* connection = new QuicConnection(
+        id, self_address, peer_address, helper(), alarm_factory(), writer(),
+        /* owns_writer= */ false, Perspective::IS_SERVER,
+        ParsedQuicVersionVector{version});
+    // The connection owning wrapper owns the connection created.
+    auto session = std::make_unique<ConnectionOwningQboneServerSession>(
+        GetSupportedVersions(), connection, this, config(), crypto_config(),
+        compressed_certs_cache(), writer_);
+    session->Initialize();
+    return session;
+  }
+
+ private:
+  QbonePacketWriter* writer_;
+};
+
+class QboneTestServer : public QuicServer {
+ public:
+  explicit QboneTestServer(std::unique_ptr<ProofSource> proof_source)
+      : QuicServer(std::move(proof_source), &response_cache_) {}
+  QuicDispatcher* CreateQuicDispatcher() override {
+    QuicEpollAlarmFactory alarm_factory(epoll_server());
+    return new QuicQboneDispatcher(
+        &config(), &crypto_config(), version_manager(),
+        std::unique_ptr<QuicEpollConnectionHelper>(
+            new QuicEpollConnectionHelper(epoll_server(),
+                                          QuicAllocator::BUFFER_POOL)),
+        std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+            new QboneCryptoServerStreamHelper()),
+        std::unique_ptr<QuicEpollAlarmFactory>(
+            new QuicEpollAlarmFactory(epoll_server())),
+        &writer_);
+  }
+
+  std::vector<std::string> data() { return writer_.data(); }
+
+ private:
+  quic::QuicMemoryCacheBackend response_cache_;
+  DataSavingQbonePacketWriter writer_;
+};
+
+class QboneTestClient : public QboneClient {
+ public:
+  QboneTestClient(QuicSocketAddress server_address,
+                  const QuicServerId& server_id,
+                  const ParsedQuicVersionVector& supported_versions,
+                  QuicEpollServer* epoll_server,
+                  std::unique_ptr<ProofVerifier> proof_verifier)
+      : QboneClient(server_address,
+                    server_id,
+                    supported_versions,
+                    /*session_owner=*/nullptr,
+                    QuicConfig(),
+                    epoll_server,
+                    std::move(proof_verifier),
+                    &qbone_writer_,
+                    nullptr) {}
+
+  ~QboneTestClient() override {}
+
+  void SendData(const std::string& data) {
+    qbone_session()->ProcessPacketFromNetwork(data);
+  }
+
+  void WaitForWriteToFlush() {
+    while (connected() && session()->HasDataToWrite()) {
+      WaitForEvents();
+    }
+  }
+
+  // Returns true when the data size is reached or false on timeouts.
+  bool WaitForDataSize(int n, QuicTime::Delta timeout) {
+    const QuicClock* clock =
+        quic::test::QuicConnectionPeer::GetHelper(session()->connection())
+            ->GetClock();
+    const QuicTime deadline = clock->Now() + timeout;
+    while (data().size() < n) {
+      if (clock->Now() > deadline) {
+        return false;
+      }
+      WaitForEvents();
+    }
+    return true;
+  }
+
+  std::vector<std::string> data() { return qbone_writer_.data(); }
+
+ private:
+  DataSavingQbonePacketWriter qbone_writer_;
+};
+
+class QboneClientTest : public QuicTestWithParam<ParsedQuicVersion> {};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QboneClientTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QboneClientTest, SendDataFromClient) {
+  auto server = new QboneTestServer(crypto_test_utils::ProofSourceForTesting());
+  QuicSocketAddress server_address(TestLoopback(), 0);
+  ServerThread server_thread(server, server_address);
+  server_thread.Initialize();
+  server_address =
+      QuicSocketAddress(server_address.host(), server_thread.GetPort());
+  server_thread.Start();
+
+  QuicEpollServer epoll_server;
+  QboneTestClient client(
+      server_address,
+      QuicServerId("test.example.com", server_address.port(), false),
+      ParsedQuicVersionVector{GetParam()}, &epoll_server,
+      crypto_test_utils::ProofVerifierForTesting());
+  ASSERT_TRUE(client.Initialize());
+  ASSERT_TRUE(client.Connect());
+  ASSERT_TRUE(client.WaitForOneRttKeysAvailable());
+  client.SendData(TestPacketIn("hello"));
+  client.SendData(TestPacketIn("world"));
+  client.WaitForWriteToFlush();
+
+  // Wait until the server has received at least two packets, timeout after 5s.
+  ASSERT_TRUE(
+      server_thread.WaitUntil([&] { return server->data().size() >= 2; },
+                              QuicTime::Delta::FromSeconds(5)));
+
+  std::string long_data(
+      QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
+
+  // Pretend the server gets data.
+  server_thread.Schedule([&server, &long_data]() {
+    EXPECT_THAT(server->data()[0], testing::Eq(TestPacketOut("hello")));
+    EXPECT_THAT(server->data()[1], testing::Eq(TestPacketOut("world")));
+    auto server_session = static_cast<QboneServerSession*>(
+        QuicDispatcherPeer::GetFirstSessionIfAny(
+            QuicServerPeer::GetDispatcher(server)));
+    server_session->ProcessPacketFromNetwork(
+        TestPacketIn("Somethingsomething"));
+    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
+    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
+  });
+  ASSERT_TRUE(client.WaitForDataSize(3, QuicTime::Delta::FromSeconds(5)));
+  EXPECT_THAT(client.data()[0],
+              testing::Eq(TestPacketOut("Somethingsomething")));
+  EXPECT_THAT(client.data()[1], testing::Eq(TestPacketOut(long_data)));
+  EXPECT_THAT(client.data()[2], testing::Eq(TestPacketOut(long_data)));
+
+  client.Disconnect();
+  server_thread.Quit();
+  server_thread.Join();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_constants.cc b/quiche/quic/qbone/qbone_constants.cc
new file mode 100644
index 0000000..79a6b11
--- /dev/null
+++ b/quiche/quic/qbone/qbone_constants.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_constants.h"
+
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+constexpr char QboneConstants::kQboneAlpn[];
+const QuicByteCount QboneConstants::kMaxQbonePacketBytes;
+const uint32_t QboneConstants::kQboneRouteTableId;
+
+QuicStreamId QboneConstants::GetControlStreamId(QuicTransportVersion version) {
+  return QuicUtils::GetFirstBidirectionalStreamId(version,
+                                                  Perspective::IS_CLIENT);
+}
+
+const QuicIpAddress* QboneConstants::TerminatorLocalAddress() {
+  static auto* terminator_address = []() {
+    auto* address = new QuicIpAddress;
+    // 0x71 0x62 0x6f 0x6e 0x65 is 'qbone' in ascii.
+    address->FromString("fe80::71:626f:6e65");
+    return address;
+  }();
+  return terminator_address;
+}
+
+const IpRange* QboneConstants::TerminatorLocalAddressRange() {
+  static auto* range =
+      new quic::IpRange(*quic::QboneConstants::TerminatorLocalAddress(), 128);
+  return range;
+}
+
+const QuicIpAddress* QboneConstants::GatewayAddress() {
+  static auto* gateway_address = []() {
+    auto* address = new QuicIpAddress;
+    address->FromString("fe80::1");
+    return address;
+  }();
+  return gateway_address;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_constants.h b/quiche/quic/qbone/qbone_constants.h
new file mode 100644
index 0000000..3ac75d4
--- /dev/null
+++ b/quiche/quic/qbone/qbone_constants.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
+#define QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/qbone/platform/ip_range.h"
+
+namespace quic {
+
+struct QboneConstants {
+  // QBONE's ALPN
+  static constexpr char kQboneAlpn[] = "qbone";
+  // The maximum number of bytes allowed in a QBONE packet.
+  static const QuicByteCount kMaxQbonePacketBytes = 2000;
+  // The table id for QBONE's routing table. 'bone' in ascii.
+  static const uint32_t kQboneRouteTableId = 0x626F6E65;
+  // The stream ID of the control channel.
+  static QuicStreamId GetControlStreamId(QuicTransportVersion version);
+  // The link-local address of the Terminator
+  static const QuicIpAddress* TerminatorLocalAddress();
+  // The IPRange containing the TerminatorLocalAddress
+  static const IpRange* TerminatorLocalAddressRange();
+  // The gateway address to provide when configuring routes to the QBONE
+  // interface
+  static const QuicIpAddress* GatewayAddress();
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_CONSTANTS_H_
diff --git a/quic/qbone/qbone_control.proto b/quiche/quic/qbone/qbone_control.proto
similarity index 100%
rename from quic/qbone/qbone_control.proto
rename to quiche/quic/qbone/qbone_control.proto
diff --git a/quiche/quic/qbone/qbone_control_placeholder.proto b/quiche/quic/qbone/qbone_control_placeholder.proto
new file mode 100644
index 0000000..af99340
--- /dev/null
+++ b/quiche/quic/qbone/qbone_control_placeholder.proto
@@ -0,0 +1,20 @@
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package quic;
+
+import "quiche/quic/qbone/qbone_control.proto";
+
+// These provide fields for QboneServerRequest and QboneClientRequest that are
+// used to test the control channel.  Once the control channel actually has real
+// data to pass they can be removed.
+// TODO(b/62139999): Remove this file in favor of testing actual configuration.
+
+extend QboneServerRequest {
+  optional string server_placeholder = 179838467;
+}
+
+extend QboneClientRequest {
+  optional string client_placeholder = 179838467;
+}
diff --git a/quiche/quic/qbone/qbone_control_stream.cc b/quiche/quic/qbone/qbone_control_stream.cc
new file mode 100644
index 0000000..08efbc2
--- /dev/null
+++ b/quiche/quic/qbone/qbone_control_stream.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_control_stream.h"
+
+#include <cstdint>
+#include <limits>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+
+namespace quic {
+
+namespace {
+static constexpr size_t kRequestSizeBytes = sizeof(uint16_t);
+}  // namespace
+
+QboneControlStreamBase::QboneControlStreamBase(QuicSession* session)
+    : QuicStream(
+          QboneConstants::GetControlStreamId(session->transport_version()),
+          session,
+          /*is_static=*/true,
+          BIDIRECTIONAL),
+      pending_message_size_(0) {}
+
+QboneControlStreamBase::QboneControlStreamBase(quic::PendingStream* pending,
+                                               QuicSession* session)
+    : QuicStream(pending, session, /*is_static=*/true),
+      pending_message_size_(0) {
+  QUICHE_DCHECK_EQ(pending->id(), QboneConstants::GetControlStreamId(
+                                      session->transport_version()));
+}
+
+void QboneControlStreamBase::OnDataAvailable() {
+  sequencer()->Read(&buffer_);
+  while (true) {
+    if (pending_message_size_ == 0) {
+      // Start of a message.
+      if (buffer_.size() < kRequestSizeBytes) {
+        return;
+      }
+      memcpy(&pending_message_size_, buffer_.data(), kRequestSizeBytes);
+      buffer_.erase(0, kRequestSizeBytes);
+    }
+    // Continuation of a message.
+    if (buffer_.size() < pending_message_size_) {
+      return;
+    }
+    std::string tmp = buffer_.substr(0, pending_message_size_);
+    buffer_.erase(0, pending_message_size_);
+    pending_message_size_ = 0;
+    OnMessage(tmp);
+  }
+}
+
+bool QboneControlStreamBase::SendMessage(const proto2::Message& proto) {
+  std::string tmp;
+  if (!proto.SerializeToString(&tmp)) {
+    QUIC_BUG(quic_bug_11023_1) << "Failed to serialize QboneControlRequest";
+    return false;
+  }
+  if (tmp.size() > std::numeric_limits<uint16_t>::max()) {
+    QUIC_BUG(quic_bug_11023_2)
+        << "QboneControlRequest too large: " << tmp.size() << " > "
+        << std::numeric_limits<uint16_t>::max();
+    return false;
+  }
+  uint16_t size = tmp.size();
+  char size_str[kRequestSizeBytes];
+  memcpy(size_str, &size, kRequestSizeBytes);
+  WriteOrBufferData(absl::string_view(size_str, kRequestSizeBytes), false,
+                    nullptr);
+  WriteOrBufferData(tmp, false, nullptr);
+  return true;
+}
+
+void QboneControlStreamBase::OnStreamReset(
+    const QuicRstStreamFrame& /*frame*/) {
+  stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
+                                   "Attempt to reset control stream");
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_control_stream.h b/quiche/quic/qbone/qbone_control_stream.h
new file mode 100644
index 0000000..5935aa5
--- /dev/null
+++ b/quiche/quic/qbone/qbone_control_stream.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
+#define QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
+
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/qbone/qbone_control.pb.h"
+
+namespace quic {
+
+class QboneSessionBase;
+
+class QUIC_EXPORT_PRIVATE QboneControlStreamBase : public QuicStream {
+ public:
+  explicit QboneControlStreamBase(QuicSession* session);
+  QboneControlStreamBase(quic::PendingStream* pending, QuicSession* session);
+
+  void OnDataAvailable() override;
+
+  void OnStreamReset(const QuicRstStreamFrame& frame) override;
+
+ protected:
+  virtual void OnMessage(const std::string& data) = 0;
+  bool SendMessage(const proto2::Message& proto);
+
+ private:
+  uint16_t pending_message_size_;
+  std::string buffer_;
+};
+
+template <class T>
+class QUIC_EXPORT_PRIVATE QboneControlHandler {
+ public:
+  virtual ~QboneControlHandler() { }
+
+  virtual void OnControlRequest(const T& request) = 0;
+  virtual void OnControlError() = 0;
+};
+
+template <class Incoming, class Outgoing>
+class QUIC_EXPORT_PRIVATE QboneControlStream : public QboneControlStreamBase {
+ public:
+  using Handler = QboneControlHandler<Incoming>;
+
+  QboneControlStream(QuicSession* session, Handler* handler)
+      : QboneControlStreamBase(session), handler_(handler) {}
+  QboneControlStream(quic::PendingStream* pending, QuicSession* session,
+                     Handler* handler)
+      : QboneControlStreamBase(pending, session), handler_(handler) {}
+
+  bool SendRequest(const Outgoing& request) { return SendMessage(request); }
+
+ protected:
+  void OnMessage(const std::string& data) override {
+    Incoming request;
+    if (!request.ParseFromString(data)) {
+      QUIC_LOG(ERROR) << "Failed to parse incoming request";
+      if (handler_ != nullptr) {
+        handler_->OnControlError();
+      }
+      return;
+    }
+    if (handler_ != nullptr) {
+      handler_->OnControlRequest(request);
+    }
+  }
+
+ private:
+  Handler* handler_;
+};
+
+using QboneServerControlStream =
+    QboneControlStream<QboneServerRequest, QboneClientRequest>;
+using QboneClientControlStream =
+    QboneControlStream<QboneClientRequest, QboneServerRequest>;
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_CONTROL_STREAM_H_
diff --git a/quiche/quic/qbone/qbone_packet_exchanger.cc b/quiche/quic/qbone/qbone_packet_exchanger.cc
new file mode 100644
index 0000000..f582d6e
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_exchanger.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_packet_exchanger.h"
+
+#include <utility>
+
+namespace quic {
+
+bool QbonePacketExchanger::ReadAndDeliverPacket(
+    QboneClientInterface* qbone_client) {
+  bool blocked = false;
+  std::string error;
+  std::unique_ptr<QuicData> packet = ReadPacket(&blocked, &error);
+  if (packet == nullptr) {
+    if (!blocked && visitor_) {
+      visitor_->OnReadError(error);
+    }
+    return false;
+  }
+  qbone_client->ProcessPacketFromNetwork(packet->AsStringPiece());
+  return true;
+}
+
+void QbonePacketExchanger::WritePacketToNetwork(const char* packet,
+                                                size_t size) {
+  bool blocked = false;
+  std::string error;
+  if (packet_queue_.empty() && !write_blocked_) {
+    if (WritePacket(packet, size, &blocked, &error)) {
+      return;
+    }
+    if (blocked) {
+      write_blocked_ = true;
+    } else {
+      QUIC_LOG_EVERY_N_SEC(ERROR, 60) << "Packet write failed: " << error;
+      if (visitor_) {
+        visitor_->OnWriteError(error);
+      }
+    }
+  }
+
+  // Drop the packet on the floor if the queue if full.
+  if (packet_queue_.size() >= max_pending_packets_) {
+    return;
+  }
+
+  auto data_copy = new char[size];
+  memcpy(data_copy, packet, size);
+  packet_queue_.push_back(
+      std::make_unique<QuicData>(data_copy, size, /* owns_buffer = */ true));
+}
+
+void QbonePacketExchanger::SetWritable() {
+  write_blocked_ = false;
+  while (!packet_queue_.empty()) {
+    bool blocked = false;
+    std::string error;
+    if (WritePacket(packet_queue_.front()->data(),
+                    packet_queue_.front()->length(), &blocked, &error)) {
+      packet_queue_.pop_front();
+    } else {
+      if (!blocked && visitor_) {
+        visitor_->OnWriteError(error);
+      }
+      write_blocked_ = blocked;
+      return;
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_packet_exchanger.h b/quiche/quic/qbone/qbone_packet_exchanger.h
new file mode 100644
index 0000000..12f44b1
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_exchanger.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
+#define QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/qbone/qbone_client_interface.h"
+#include "quiche/quic/qbone/qbone_packet_writer.h"
+
+namespace quic {
+
+// Handles reading and writing on the local network and exchange packets between
+// the local network with a QBONE connection.
+class QbonePacketExchanger : public QbonePacketWriter {
+ public:
+  // The owner might want to receive notifications when read or write fails.
+  class Visitor {
+   public:
+    virtual ~Visitor() {}
+    virtual void OnReadError(const std::string& error) {}
+    virtual void OnWriteError(const std::string& error) {}
+  };
+  // Does not take ownership of visitor.
+  QbonePacketExchanger(Visitor* visitor, size_t max_pending_packets)
+      : visitor_(visitor), max_pending_packets_(max_pending_packets) {}
+
+  QbonePacketExchanger(const QbonePacketExchanger&) = delete;
+  QbonePacketExchanger& operator=(const QbonePacketExchanger&) = delete;
+
+  QbonePacketExchanger(QbonePacketExchanger&&) = delete;
+  QbonePacketExchanger& operator=(QbonePacketExchanger&&) = delete;
+
+  ~QbonePacketExchanger() = default;
+
+  // Returns true if there may be more packets to read.
+  // Implementations handles the actual raw read and delivers the packet to
+  // qbone_client.
+  bool ReadAndDeliverPacket(QboneClientInterface* qbone_client);
+
+  // From QbonePacketWriter.
+  // Writes a packet to the local network. If the write would be blocked, the
+  // packet will be queued if the queue is smaller than max_pending_packets_.
+  void WritePacketToNetwork(const char* packet, size_t size) override;
+
+  // The caller signifies that the local network is no longer blocked.
+  void SetWritable();
+
+ private:
+  // The actual implementation that reads a packet from the local network.
+  // Returns the packet if one is successfully read. This might nullptr when a)
+  // there is no packet to read, b) the read failed. In the former case, blocked
+  // is set to true. error contains the error message.
+  virtual std::unique_ptr<QuicData> ReadPacket(bool* blocked,
+                                               std::string* error) = 0;
+
+  // The actual implementation that writes a packet to the local network.
+  // Returns true if the write succeeds. blocked will be set to true if the
+  // write failure is caused by the local network being blocked. error contains
+  // the error message.
+  virtual bool WritePacket(const char* packet,
+                           size_t size,
+                           bool* blocked,
+                           std::string* error) = 0;
+
+  std::list<std::unique_ptr<QuicData>> packet_queue_;
+
+  Visitor* visitor_;
+
+  // The maximum number of packets that could be queued up when writing to local
+  // network is blocked.
+  size_t max_pending_packets_;
+
+  bool write_blocked_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_EXCHANGER_H_
diff --git a/quiche/quic/qbone/qbone_packet_exchanger_test.cc b/quiche/quic/qbone/qbone_packet_exchanger_test.cc
new file mode 100644
index 0000000..bbd6456
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_exchanger_test.cc
@@ -0,0 +1,271 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_packet_exchanger.h"
+
+#include <utility>
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/mock_qbone_client.h"
+
+namespace quic {
+namespace {
+
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+const size_t kMaxPendingPackets = 2;
+
+class MockVisitor : public QbonePacketExchanger::Visitor {
+ public:
+  MOCK_METHOD(void, OnReadError, (const std::string&), (override));
+  MOCK_METHOD(void, OnWriteError, (const std::string&), (override));
+};
+
+class FakeQbonePacketExchanger : public QbonePacketExchanger {
+ public:
+  using QbonePacketExchanger::QbonePacketExchanger;
+
+  // Adds a packet to the end of list of packets to be returned by ReadPacket.
+  // When the list is empty, ReadPacket returns nullptr to signify error as
+  // defined by QbonePacketExchanger. If SetReadError is not called or called
+  // with empty error string, ReadPacket sets blocked to true.
+  void AddPacketToBeRead(std::unique_ptr<QuicData> packet) {
+    packets_to_be_read_.push_back(std::move(packet));
+  }
+
+  // Sets the error to be returned by ReadPacket when the list of packets is
+  // empty. If error is empty string, blocked is set by ReadPacket.
+  void SetReadError(const std::string& error) { read_error_ = error; }
+
+  // Force WritePacket to fail with the given status. WritePacket returns true
+  // when blocked == true and error is empty.
+  void ForceWriteFailure(bool blocked, const std::string& error) {
+    write_blocked_ = blocked;
+    write_error_ = error;
+  }
+
+  // Packets that have been successfully written by WritePacket.
+  const std::vector<std::string>& packets_written() const {
+    return packets_written_;
+  }
+
+ private:
+  // Implements QbonePacketExchanger::ReadPacket.
+  std::unique_ptr<QuicData> ReadPacket(bool* blocked,
+                                       std::string* error) override {
+    *blocked = false;
+
+    if (packets_to_be_read_.empty()) {
+      *blocked = read_error_.empty();
+      *error = read_error_;
+      return nullptr;
+    }
+
+    std::unique_ptr<QuicData> packet = std::move(packets_to_be_read_.front());
+    packets_to_be_read_.pop_front();
+    return packet;
+  }
+
+  // Implements QbonePacketExchanger::WritePacket.
+  bool WritePacket(const char* packet,
+                   size_t size,
+                   bool* blocked,
+                   std::string* error) override {
+    *blocked = false;
+
+    if (write_blocked_ || !write_error_.empty()) {
+      *blocked = write_blocked_;
+      *error = write_error_;
+      return false;
+    }
+
+    packets_written_.push_back(std::string(packet, size));
+    return true;
+  }
+
+  std::string read_error_;
+  std::list<std::unique_ptr<QuicData>> packets_to_be_read_;
+
+  std::string write_error_;
+  bool write_blocked_ = false;
+  std::vector<std::string> packets_written_;
+};
+
+TEST(QbonePacketExchangerTest,
+     ReadAndDeliverPacketDeliversPacketToQboneClient) {
+  StrictMock<MockVisitor> visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  StrictMock<MockQboneClient> client;
+
+  std::string packet = "data";
+  exchanger.AddPacketToBeRead(
+      std::make_unique<QuicData>(packet.data(), packet.length()));
+  EXPECT_CALL(client, ProcessPacketFromNetwork(StrEq("data")));
+
+  EXPECT_TRUE(exchanger.ReadAndDeliverPacket(&client));
+}
+
+TEST(QbonePacketExchangerTest,
+     ReadAndDeliverPacketNotifiesVisitorOnReadFailure) {
+  MockVisitor visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  MockQboneClient client;
+
+  // Force read error.
+  std::string io_error = "I/O error";
+  exchanger.SetReadError(io_error);
+  EXPECT_CALL(visitor, OnReadError(StrEq(io_error))).Times(1);
+
+  EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
+}
+
+TEST(QbonePacketExchangerTest,
+     ReadAndDeliverPacketDoesNotNotifyVisitorOnBlockedIO) {
+  MockVisitor visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  MockQboneClient client;
+
+  // No more packets to read.
+  EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
+}
+
+TEST(QbonePacketExchangerTest,
+     WritePacketToNetworkWritesDirectlyToNetworkWhenNotBlocked) {
+  MockVisitor visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  MockQboneClient client;
+
+  std::string packet = "data";
+  exchanger.WritePacketToNetwork(packet.data(), packet.length());
+
+  ASSERT_EQ(exchanger.packets_written().size(), 1);
+  EXPECT_THAT(exchanger.packets_written()[0], StrEq(packet));
+}
+
+TEST(QbonePacketExchangerTest,
+     WritePacketToNetworkQueuesPacketsAndProcessThemLater) {
+  MockVisitor visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  MockQboneClient client;
+
+  // Force write to be blocked so that packets are queued.
+  exchanger.ForceWriteFailure(true, "");
+  std::vector<std::string> packets = {"packet0", "packet1"};
+  for (int i = 0; i < packets.size(); i++) {
+    exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
+  }
+
+  // Nothing should have been written because of blockage.
+  ASSERT_TRUE(exchanger.packets_written().empty());
+
+  // Remove blockage and start proccessing queued packets.
+  exchanger.ForceWriteFailure(false, "");
+  exchanger.SetWritable();
+
+  // Queued packets are processed.
+  ASSERT_EQ(exchanger.packets_written().size(), 2);
+  for (int i = 0; i < packets.size(); i++) {
+    EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
+  }
+}
+
+TEST(QbonePacketExchangerTest,
+     SetWritableContinuesProcessingPacketIfPreviousCallBlocked) {
+  MockVisitor visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  MockQboneClient client;
+
+  // Force write to be blocked so that packets are queued.
+  exchanger.ForceWriteFailure(true, "");
+  std::vector<std::string> packets = {"packet0", "packet1"};
+  for (int i = 0; i < packets.size(); i++) {
+    exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
+  }
+
+  // Nothing should have been written because of blockage.
+  ASSERT_TRUE(exchanger.packets_written().empty());
+
+  // Start processing packets, but since writes are still blocked, nothing
+  // should have been written.
+  exchanger.SetWritable();
+  ASSERT_TRUE(exchanger.packets_written().empty());
+
+  // Remove blockage and start processing packets again.
+  exchanger.ForceWriteFailure(false, "");
+  exchanger.SetWritable();
+
+  ASSERT_EQ(exchanger.packets_written().size(), 2);
+  for (int i = 0; i < packets.size(); i++) {
+    EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
+  }
+}
+
+TEST(QbonePacketExchangerTest, WritePacketToNetworkDropsPacketIfQueueIfFull) {
+  std::vector<std::string> packets = {"packet0", "packet1", "packet2"};
+  size_t queue_size = packets.size() - 1;
+  MockVisitor visitor;
+  // exchanger has smaller queue than number of packets.
+  FakeQbonePacketExchanger exchanger(&visitor, queue_size);
+  MockQboneClient client;
+
+  exchanger.ForceWriteFailure(true, "");
+  for (int i = 0; i < packets.size(); i++) {
+    exchanger.WritePacketToNetwork(packets[i].data(), packets[i].length());
+  }
+
+  // Blocked writes cause packets to be queued or dropped.
+  ASSERT_TRUE(exchanger.packets_written().empty());
+
+  exchanger.ForceWriteFailure(false, "");
+  exchanger.SetWritable();
+
+  ASSERT_EQ(exchanger.packets_written().size(), queue_size);
+  for (int i = 0; i < queue_size; i++) {
+    EXPECT_THAT(exchanger.packets_written()[i], StrEq(packets[i]));
+  }
+}
+
+TEST(QbonePacketExchangerTest, WriteErrorsGetNotified) {
+  MockVisitor visitor;
+  FakeQbonePacketExchanger exchanger(&visitor, kMaxPendingPackets);
+  MockQboneClient client;
+  std::string packet = "data";
+
+  // Write error is delivered to visitor during WritePacketToNetwork.
+  std::string io_error = "I/O error";
+  exchanger.ForceWriteFailure(false, io_error);
+  EXPECT_CALL(visitor, OnWriteError(StrEq(io_error))).Times(1);
+  exchanger.WritePacketToNetwork(packet.data(), packet.length());
+  ASSERT_TRUE(exchanger.packets_written().empty());
+
+  // Write error is delivered to visitor during SetWritable.
+  exchanger.ForceWriteFailure(true, "");
+  exchanger.WritePacketToNetwork(packet.data(), packet.length());
+
+  std::string sys_error = "sys error";
+  exchanger.ForceWriteFailure(false, sys_error);
+  EXPECT_CALL(visitor, OnWriteError(StrEq(sys_error))).Times(1);
+  exchanger.SetWritable();
+  ASSERT_TRUE(exchanger.packets_written().empty());
+}
+
+TEST(QbonePacketExchangerTest, NullVisitorDoesntCrash) {
+  FakeQbonePacketExchanger exchanger(nullptr, kMaxPendingPackets);
+  MockQboneClient client;
+  std::string packet = "data";
+
+  // Force read error.
+  std::string io_error = "I/O error";
+  exchanger.SetReadError(io_error);
+  EXPECT_FALSE(exchanger.ReadAndDeliverPacket(&client));
+
+  // Force write error
+  exchanger.ForceWriteFailure(false, io_error);
+  exchanger.WritePacketToNetwork(packet.data(), packet.length());
+  EXPECT_TRUE(exchanger.packets_written().empty());
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_packet_processor.cc b/quiche/quic/qbone/qbone_packet_processor.cc
new file mode 100644
index 0000000..0dd0460
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_processor.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_packet_processor.h"
+
+#include <cstring>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+#include "quiche/quic/qbone/platform/internet_checksum.h"
+#include "quiche/quic/qbone/platform/tcp_packet.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace {
+
+constexpr size_t kIPv6AddressSize = 16;
+constexpr size_t kIPv6MinPacketSize = 1280;
+constexpr size_t kIcmpTtl = 64;
+constexpr size_t kICMPv6DestinationUnreachableDueToSourcePolicy = 5;
+
+}  // namespace
+
+namespace quic {
+
+const QuicIpAddress QbonePacketProcessor::kInvalidIpAddress =
+    QuicIpAddress::Any6();
+
+QbonePacketProcessor::QbonePacketProcessor(QuicIpAddress self_ip,
+                                           QuicIpAddress client_ip,
+                                           size_t client_ip_subnet_length,
+                                           OutputInterface* output,
+                                           StatsInterface* stats)
+    : client_ip_(client_ip),
+      output_(output),
+      stats_(stats),
+      filter_(new Filter) {
+  memcpy(self_ip_.s6_addr, self_ip.ToPackedString().data(), kIPv6AddressSize);
+  QUICHE_DCHECK_LE(client_ip_subnet_length, kIPv6AddressSize * 8);
+  client_ip_subnet_length_ = client_ip_subnet_length;
+
+  QUICHE_DCHECK(IpAddressFamily::IP_V6 == self_ip.address_family());
+  QUICHE_DCHECK(IpAddressFamily::IP_V6 == client_ip.address_family());
+  QUICHE_DCHECK(self_ip != kInvalidIpAddress);
+}
+
+QbonePacketProcessor::OutputInterface::~OutputInterface() {}
+QbonePacketProcessor::StatsInterface::~StatsInterface() {}
+QbonePacketProcessor::Filter::~Filter() {}
+
+QbonePacketProcessor::ProcessingResult
+QbonePacketProcessor::Filter::FilterPacket(Direction direction,
+                                           absl::string_view full_packet,
+                                           absl::string_view payload,
+                                           icmp6_hdr* icmp_header,
+                                           OutputInterface* output) {
+  return ProcessingResult::OK;
+}
+
+void QbonePacketProcessor::ProcessPacket(std::string* packet,
+                                         Direction direction) {
+  if (QUIC_PREDICT_FALSE(!IsValid())) {
+    QUIC_BUG(quic_bug_11024_1)
+        << "QuicPacketProcessor is invoked in an invalid state.";
+    stats_->OnPacketDroppedSilently(direction);
+    return;
+  }
+
+  uint8_t transport_protocol;
+  char* transport_data;
+  icmp6_hdr icmp_header;
+  memset(&icmp_header, 0, sizeof(icmp_header));
+  ProcessingResult result = ProcessIPv6HeaderAndFilter(
+      packet, direction, &transport_protocol, &transport_data, &icmp_header);
+
+  switch (result) {
+    case ProcessingResult::OK:
+      switch (direction) {
+        case Direction::FROM_OFF_NETWORK:
+          output_->SendPacketToNetwork(*packet);
+          break;
+        case Direction::FROM_NETWORK:
+          output_->SendPacketToClient(*packet);
+          break;
+      }
+      stats_->OnPacketForwarded(direction);
+      break;
+    case ProcessingResult::SILENT_DROP:
+      stats_->OnPacketDroppedSilently(direction);
+      break;
+    case ProcessingResult::DEFER:
+      stats_->OnPacketDeferred(direction);
+      break;
+    case ProcessingResult::ICMP:
+      SendIcmpResponse(&icmp_header, *packet, direction);
+      stats_->OnPacketDroppedWithIcmp(direction);
+      break;
+    case ProcessingResult::ICMP_AND_TCP_RESET:
+      SendIcmpResponse(&icmp_header, *packet, direction);
+      stats_->OnPacketDroppedWithIcmp(direction);
+      SendTcpReset(*packet, direction);
+      stats_->OnPacketDroppedWithTcpReset(direction);
+      break;
+    case ProcessingResult::TCP_RESET:
+      SendTcpReset(*packet, direction);
+      stats_->OnPacketDroppedWithTcpReset(direction);
+      break;
+  }
+}
+
+QbonePacketProcessor::ProcessingResult
+QbonePacketProcessor::ProcessIPv6HeaderAndFilter(std::string* packet,
+                                                 Direction direction,
+                                                 uint8_t* transport_protocol,
+                                                 char** transport_data,
+                                                 icmp6_hdr* icmp_header) {
+  ProcessingResult result = ProcessIPv6Header(
+      packet, direction, transport_protocol, transport_data, icmp_header);
+
+  if (result == ProcessingResult::OK) {
+    char* packet_data = &*packet->begin();
+    size_t header_size = *transport_data - packet_data;
+    // Sanity-check the bounds.
+    if (packet_data >= *transport_data || header_size > packet->size() ||
+        header_size < kIPv6HeaderSize) {
+      QUIC_BUG(quic_bug_11024_2)
+          << "Invalid pointers encountered in "
+             "QbonePacketProcessor::ProcessPacket.  Dropping the packet";
+      return ProcessingResult::SILENT_DROP;
+    }
+
+    result = filter_->FilterPacket(
+        direction, *packet,
+        absl::string_view(*transport_data, packet->size() - header_size),
+        icmp_header, output_);
+  }
+
+  // Do not send ICMP error messages in response to ICMP errors.
+  if (result == ProcessingResult::ICMP) {
+    const uint8_t* header = reinterpret_cast<const uint8_t*>(packet->data());
+
+    constexpr size_t kIPv6NextHeaderOffset = 6;
+    constexpr size_t kIcmpMessageTypeOffset = kIPv6HeaderSize + 0;
+    constexpr size_t kIcmpMessageTypeMaxError = 127;
+    if (
+        // Check size.
+        packet->size() >= (kIPv6HeaderSize + kICMPv6HeaderSize) &&
+        // Check that the packet is in fact ICMP.
+        header[kIPv6NextHeaderOffset] == IPPROTO_ICMPV6 &&
+        // Check that ICMP message type is an error.
+        header[kIcmpMessageTypeOffset] < kIcmpMessageTypeMaxError) {
+      result = ProcessingResult::SILENT_DROP;
+    }
+  }
+
+  return result;
+}
+
+QbonePacketProcessor::ProcessingResult QbonePacketProcessor::ProcessIPv6Header(
+    std::string* packet,
+    Direction direction,
+    uint8_t* transport_protocol,
+    char** transport_data,
+    icmp6_hdr* icmp_header) {
+  // Check if the packet is big enough to have IPv6 header.
+  if (packet->size() < kIPv6HeaderSize) {
+    QUIC_DVLOG(1) << "Dropped malformed packet: IPv6 header too short";
+    return ProcessingResult::SILENT_DROP;
+  }
+
+  // Check version field.
+  ip6_hdr* header = reinterpret_cast<ip6_hdr*>(&*packet->begin());
+  if (header->ip6_vfc >> 4 != 6) {
+    QUIC_DVLOG(1) << "Dropped malformed packet: IP version is not IPv6";
+    return ProcessingResult::SILENT_DROP;
+  }
+
+  // Check payload size.
+  const size_t declared_payload_size =
+      quiche::QuicheEndian::NetToHost16(header->ip6_plen);
+  const size_t actual_payload_size = packet->size() - kIPv6HeaderSize;
+  if (declared_payload_size != actual_payload_size) {
+    QUIC_DVLOG(1)
+        << "Dropped malformed packet: incorrect packet length specified";
+    return ProcessingResult::SILENT_DROP;
+  }
+
+  // Check that the address of the client is in the packet.
+  QuicIpAddress address_to_check;
+  uint8_t address_reject_code;
+  bool ip_parse_result;
+  switch (direction) {
+    case Direction::FROM_OFF_NETWORK:
+      // Expect the source IP to match the client.
+      ip_parse_result = address_to_check.FromPackedString(
+          reinterpret_cast<const char*>(&header->ip6_src),
+          sizeof(header->ip6_src));
+      address_reject_code = kICMPv6DestinationUnreachableDueToSourcePolicy;
+      break;
+    case Direction::FROM_NETWORK:
+      // Expect the destination IP to match the client.
+      ip_parse_result = address_to_check.FromPackedString(
+          reinterpret_cast<const char*>(&header->ip6_dst),
+          sizeof(header->ip6_src));
+      address_reject_code = ICMP6_DST_UNREACH_NOROUTE;
+      break;
+  }
+  QUICHE_DCHECK(ip_parse_result);
+  if (!client_ip_.InSameSubnet(address_to_check, client_ip_subnet_length_)) {
+    QUIC_DVLOG(1)
+        << "Dropped packet: source/destination address is not client's";
+    icmp_header->icmp6_type = ICMP6_DST_UNREACH;
+    icmp_header->icmp6_code = address_reject_code;
+    return ProcessingResult::ICMP;
+  }
+
+  // Check and decrement TTL.
+  if (header->ip6_hops <= 1) {
+    icmp_header->icmp6_type = ICMP6_TIME_EXCEEDED;
+    icmp_header->icmp6_code = ICMP6_TIME_EXCEED_TRANSIT;
+    return ProcessingResult::ICMP;
+  }
+  header->ip6_hops--;
+
+  // Check and extract IP headers.
+  switch (header->ip6_nxt) {
+    case IPPROTO_TCP:
+    case IPPROTO_UDP:
+    case IPPROTO_ICMPV6:
+      *transport_protocol = header->ip6_nxt;
+      *transport_data = (&*packet->begin()) + kIPv6HeaderSize;
+      break;
+    default:
+      icmp_header->icmp6_type = ICMP6_PARAM_PROB;
+      icmp_header->icmp6_code = ICMP6_PARAMPROB_NEXTHEADER;
+      return ProcessingResult::ICMP;
+  }
+
+  return ProcessingResult::OK;
+}
+
+void QbonePacketProcessor::SendIcmpResponse(icmp6_hdr* icmp_header,
+                                            absl::string_view original_packet,
+                                            Direction original_direction) {
+  in6_addr dst;
+  // TODO(b/70339814): ensure this is actually a unicast address.
+  memcpy(dst.s6_addr, &original_packet[8], kIPv6AddressSize);
+
+  CreateIcmpPacket(self_ip_, dst, *icmp_header, original_packet,
+                   [this, original_direction](absl::string_view packet) {
+                     SendResponse(original_direction, packet);
+                   });
+}
+
+void QbonePacketProcessor::SendTcpReset(absl::string_view original_packet,
+                                        Direction original_direction) {
+  CreateTcpResetPacket(original_packet,
+                       [this, original_direction](absl::string_view packet) {
+                         SendResponse(original_direction, packet);
+                       });
+}
+
+void QbonePacketProcessor::SendResponse(Direction original_direction,
+                                        absl::string_view packet) {
+  switch (original_direction) {
+    case Direction::FROM_OFF_NETWORK:
+      output_->SendPacketToClient(packet);
+      break;
+    case Direction::FROM_NETWORK:
+      output_->SendPacketToNetwork(packet);
+      break;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_packet_processor.h b/quiche/quic/qbone/qbone_packet_processor.h
new file mode 100644
index 0000000..2a0f999
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_processor.h
@@ -0,0 +1,200 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
+#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
+
+#include <netinet/icmp6.h>
+#include <netinet/ip6.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+
+namespace quic {
+
+enum : size_t {
+  kIPv6HeaderSize = 40,
+  kICMPv6HeaderSize = sizeof(icmp6_hdr),
+  kTotalICMPv6HeaderSize = kIPv6HeaderSize + kICMPv6HeaderSize,
+};
+
+// QBONE packet processor accepts packets destined in either direction
+// (client-to-network or network-to-client).  It inspects them and makes
+// decisions on whether they should be forwarded or dropped, replying with ICMP
+// messages as appropriate.
+class QbonePacketProcessor {
+ public:
+  enum class Direction {
+    // Packet is going from the QBONE client into the network behind the QBONE.
+    FROM_OFF_NETWORK = 0,
+    // Packet is going from the network begin QBONE to the client.
+    FROM_NETWORK = 1
+  };
+
+  enum class ProcessingResult {
+    OK = 0,
+    SILENT_DROP = 1,
+    ICMP = 2,
+    // Equivalent to |SILENT_DROP| at the moment, but indicates that the
+    // downstream filter has buffered the packet and deferred its processing.
+    // The packet may be emitted at a later time.
+    DEFER = 3,
+    // In addition to sending an ICMP message, also send a TCP RST. This option
+    // requires the incoming packet to have been a valid TCP packet, as a TCP
+    // RST requires information from the current connection state to be
+    // well-formed.
+    ICMP_AND_TCP_RESET = 4,
+    // Send a TCP RST.
+    TCP_RESET = 5,
+  };
+
+  class OutputInterface {
+   public:
+    virtual ~OutputInterface();
+
+    virtual void SendPacketToClient(absl::string_view packet) = 0;
+    virtual void SendPacketToNetwork(absl::string_view packet) = 0;
+  };
+
+  class StatsInterface {
+   public:
+    virtual ~StatsInterface();
+
+    virtual void OnPacketForwarded(Direction direction) = 0;
+    virtual void OnPacketDroppedSilently(Direction direction) = 0;
+    virtual void OnPacketDroppedWithIcmp(Direction direction) = 0;
+    virtual void OnPacketDroppedWithTcpReset(Direction direction) = 0;
+    virtual void OnPacketDeferred(Direction direction) = 0;
+  };
+
+  // Allows to implement a custom packet filter on top of the filtering done by
+  // the packet processor itself.
+  class Filter {
+   public:
+    virtual ~Filter();
+    // The main interface function.  The following arguments are supplied:
+    // - |direction|, to indicate direction of the packet.
+    // - |full_packet|, which includes the IPv6 header and possibly the IPv6
+    //   options that were understood by the processor.
+    // - |payload|, the contents of the IPv6 packet, i.e. a TCP, a UDP or an
+    //   ICMP packet.
+    // - |icmp_header|, an output argument which allows the filter to specify
+    //   the ICMP message with which the packet is to be rejected.
+    // The method is called only on packets which were already verified as valid
+    // IPv6 packets.
+    //
+    // The implementer of this method has four options to return:
+    // - OK will cause the filter to pass the packet through
+    // - SILENT_DROP will cause the filter to drop the packet silently
+    // - ICMP will cause the filter to drop the packet and send an ICMP
+    //   response.
+    // - DEFER will cause the packet to be not forwarded; the filter is
+    //   responsible for sending (or not sending) it later using |output|.
+    //
+    // Note that |output| should not be used except in the DEFER case, as the
+    // processor will perform the necessary writes itself.
+    virtual ProcessingResult FilterPacket(Direction direction,
+                                          absl::string_view full_packet,
+                                          absl::string_view payload,
+                                          icmp6_hdr* icmp_header,
+                                          OutputInterface* output);
+
+   protected:
+    // Helper methods that allow to easily extract information that is required
+    // for filtering from the |ipv6_header| argument.  All of those assume that
+    // the header is of valid size, which is true for everything passed into
+    // FilterPacket().
+    uint8_t TransportProtocolFromHeader(absl::string_view ipv6_header) {
+      return ipv6_header[6];
+    }
+    QuicIpAddress SourceIpFromHeader(absl::string_view ipv6_header) {
+      QuicIpAddress address;
+      address.FromPackedString(&ipv6_header[8],
+                               QuicIpAddress::kIPv6AddressSize);
+      return address;
+    }
+    QuicIpAddress DestinationIpFromHeader(absl::string_view ipv6_header) {
+      QuicIpAddress address;
+      address.FromPackedString(&ipv6_header[24],
+                               QuicIpAddress::kIPv6AddressSize);
+      return address;
+    }
+  };
+
+  // |self_ip| is the IP address from which the processor will originate ICMP
+  // messages.  |client_ip| is the expected IP address of the client, used for
+  // packet validation.
+  //
+  // |output| and |stats| are the visitor interfaces used by the processor.
+  // |output| gets notified whenever the processor decides to send a packet, and
+  // |stats| gets notified about any decisions that processor makes, without a
+  // reference to which packet that decision was made about.
+  QbonePacketProcessor(QuicIpAddress self_ip,
+                       QuicIpAddress client_ip,
+                       size_t client_ip_subnet_length,
+                       OutputInterface* output,
+                       StatsInterface* stats);
+  QbonePacketProcessor(const QbonePacketProcessor&) = delete;
+  QbonePacketProcessor& operator=(const QbonePacketProcessor&) = delete;
+
+  // Accepts an IPv6 packet and handles it accordingly by either forwarding it,
+  // replying with an ICMP packet or silently dropping it.  |packet| will be
+  // modified in the process, by having the TTL field decreased.
+  void ProcessPacket(std::string* packet, Direction direction);
+
+  void set_filter(std::unique_ptr<Filter> filter) {
+    filter_ = std::move(filter);
+  }
+
+  void set_client_ip(QuicIpAddress client_ip) { client_ip_ = client_ip; }
+  void set_client_ip_subnet_length(size_t client_ip_subnet_length) {
+    client_ip_subnet_length_ = client_ip_subnet_length;
+  }
+
+  static const QuicIpAddress kInvalidIpAddress;
+
+ protected:
+  // Processes the header and returns what should be done with the packet.
+  // After that, calls an external packet filter if registered.  TTL of the
+  // packet may be decreased in the process.
+  ProcessingResult ProcessIPv6HeaderAndFilter(std::string* packet,
+                                              Direction direction,
+                                              uint8_t* transport_protocol,
+                                              char** transport_data,
+                                              icmp6_hdr* icmp_header);
+
+  void SendIcmpResponse(icmp6_hdr* icmp_header,
+                        absl::string_view original_packet,
+                        Direction original_direction);
+
+  void SendTcpReset(absl::string_view original_packet,
+                    Direction original_direction);
+
+  bool IsValid() const { return client_ip_ != kInvalidIpAddress; }
+
+  // IP address of the server.  Used to send ICMP messages.
+  in6_addr self_ip_;
+  // IP address range of the VPN client.
+  QuicIpAddress client_ip_;
+  size_t client_ip_subnet_length_;
+
+  OutputInterface* output_;
+  StatsInterface* stats_;
+  std::unique_ptr<Filter> filter_;
+
+ private:
+  // Performs basic sanity and permission checks on the packet, and decreases
+  // the TTL.
+  ProcessingResult ProcessIPv6Header(std::string* packet,
+                                     Direction direction,
+                                     uint8_t* transport_protocol,
+                                     char** transport_data,
+                                     icmp6_hdr* icmp_header);
+
+  void SendResponse(Direction original_direction, absl::string_view packet);
+};
+
+}  // namespace quic
+#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_H_
diff --git a/quiche/quic/qbone/qbone_packet_processor_test.cc b/quiche/quic/qbone/qbone_packet_processor_test.cc
new file mode 100644
index 0000000..f831973
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_processor_test.cc
@@ -0,0 +1,287 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_packet_processor.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
+
+namespace quic {
+namespace {
+
+using Direction = QbonePacketProcessor::Direction;
+using ProcessingResult = QbonePacketProcessor::ProcessingResult;
+using OutputInterface = QbonePacketProcessor::OutputInterface;
+using ::testing::_;
+using ::testing::Return;
+
+// clang-format off
+static const char kReferenceClientPacketData[] = {
+    // IPv6 with zero TOS and flow label.
+    0x60, 0x00, 0x00, 0x00,
+    // Payload size is 8 bytes.
+    0x00, 0x08,
+    // Next header is UDP
+    17,
+    // TTL is 50.
+    50,
+    // IP address of the sender is fd00:0:0:1::1
+    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // IP address of the receiver is fd00:0:0:5::1
+    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // Source port 12345
+    0x30, 0x39,
+    // Destination port 443
+    0x01, 0xbb,
+    // UDP content length is zero
+    0x00, 0x00,
+    // Checksum is not actually checked in any of the tests, so we leave it as
+    // zero
+    0x00, 0x00,
+};
+
+static const char kReferenceNetworkPacketData[] = {
+    // IPv6 with zero TOS and flow label.
+    0x60, 0x00, 0x00, 0x00,
+    // Payload size is 8 bytes.
+    0x00, 0x08,
+    // Next header is UDP
+    17,
+    // TTL is 50.
+    50,
+    // IP address of the sender is fd00:0:0:5::1
+    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // IP address of the receiver is fd00:0:0:1::1
+    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // Source port 443
+    0x01, 0xbb,
+    // Destination port 12345
+    0x30, 0x39,
+    // UDP content length is zero
+    0x00, 0x00,
+    // Checksum is not actually checked in any of the tests, so we leave it as
+    // zero
+    0x00, 0x00,
+};
+
+static const char kReferenceClientSubnetPacketData[] = {
+    // IPv6 with zero TOS and flow label.
+    0x60, 0x00, 0x00, 0x00,
+    // Payload size is 8 bytes.
+    0x00, 0x08,
+    // Next header is UDP
+    17,
+    // TTL is 50.
+    50,
+    // IP address of the sender is fd00:0:0:2::1, which is within the /62 of the
+    // client.
+    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // IP address of the receiver is fd00:0:0:5::1
+    0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    // Source port 12345
+    0x30, 0x39,
+    // Destination port 443
+    0x01, 0xbb,
+    // UDP content length is zero
+    0x00, 0x00,
+    // Checksum is not actually checked in any of the tests, so we leave it as
+    // zero
+    0x00, 0x00,
+};
+
+// clang-format on
+
+static const absl::string_view kReferenceClientPacket(
+    kReferenceClientPacketData,
+    arraysize(kReferenceClientPacketData));
+
+static const absl::string_view kReferenceNetworkPacket(
+    kReferenceNetworkPacketData,
+    arraysize(kReferenceNetworkPacketData));
+
+static const absl::string_view kReferenceClientSubnetPacket(
+    kReferenceClientSubnetPacketData,
+    arraysize(kReferenceClientSubnetPacketData));
+
+MATCHER_P(IsIcmpMessage,
+          icmp_type,
+          "Checks whether the argument is an ICMP message of supplied type") {
+  if (arg.size() < kTotalICMPv6HeaderSize) {
+    return false;
+  }
+
+  return arg[40] == icmp_type;
+}
+
+class MockPacketFilter : public QbonePacketProcessor::Filter {
+ public:
+  MOCK_METHOD(ProcessingResult,
+              FilterPacket,
+              (Direction,
+               absl::string_view,
+               absl::string_view,
+               icmp6_hdr*,
+               OutputInterface*),
+              (override));
+};
+
+class QbonePacketProcessorTest : public QuicTest {
+ protected:
+  QbonePacketProcessorTest() {
+    QUICHE_CHECK(client_ip_.FromString("fd00:0:0:1::1"));
+    QUICHE_CHECK(self_ip_.FromString("fd00:0:0:4::1"));
+    QUICHE_CHECK(network_ip_.FromString("fd00:0:0:5::1"));
+
+    processor_ = std::make_unique<QbonePacketProcessor>(
+        self_ip_, client_ip_, /*client_ip_subnet_length=*/62, &output_,
+        &stats_);
+  }
+
+  void SendPacketFromClient(absl::string_view packet) {
+    std::string packet_buffer(packet.data(), packet.size());
+    processor_->ProcessPacket(&packet_buffer, Direction::FROM_OFF_NETWORK);
+  }
+
+  void SendPacketFromNetwork(absl::string_view packet) {
+    std::string packet_buffer(packet.data(), packet.size());
+    processor_->ProcessPacket(&packet_buffer, Direction::FROM_NETWORK);
+  }
+
+  QuicIpAddress client_ip_;
+  QuicIpAddress self_ip_;
+  QuicIpAddress network_ip_;
+
+  std::unique_ptr<QbonePacketProcessor> processor_;
+  testing::StrictMock<MockPacketProcessorOutput> output_;
+  testing::StrictMock<MockPacketProcessorStats> stats_;
+};
+
+TEST_F(QbonePacketProcessorTest, EmptyPacket) {
+  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+  SendPacketFromClient("");
+
+  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
+  SendPacketFromNetwork("");
+}
+
+TEST_F(QbonePacketProcessorTest, RandomGarbage) {
+  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+  SendPacketFromClient(std::string(1280, 'a'));
+
+  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
+  SendPacketFromNetwork(std::string(1280, 'a'));
+}
+
+TEST_F(QbonePacketProcessorTest, RandomGarbageWithCorrectLengthFields) {
+  std::string packet(40, 'a');
+  packet[4] = 0;
+  packet[5] = 0;
+
+  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
+  EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
+  SendPacketFromClient(packet);
+}
+
+TEST_F(QbonePacketProcessorTest, GoodPacketFromClient) {
+  EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
+  EXPECT_CALL(output_, SendPacketToNetwork(_));
+  SendPacketFromClient(kReferenceClientPacket);
+}
+
+TEST_F(QbonePacketProcessorTest, GoodPacketFromClientSubnet) {
+  EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
+  EXPECT_CALL(output_, SendPacketToNetwork(_));
+  SendPacketFromClient(kReferenceClientSubnetPacket);
+}
+
+TEST_F(QbonePacketProcessorTest, GoodPacketFromNetwork) {
+  EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_NETWORK));
+  EXPECT_CALL(output_, SendPacketToClient(_));
+  SendPacketFromNetwork(kReferenceNetworkPacket);
+}
+
+TEST_F(QbonePacketProcessorTest, GoodPacketFromNetworkWrongDirection) {
+  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
+  EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
+  SendPacketFromClient(kReferenceNetworkPacket);
+}
+
+TEST_F(QbonePacketProcessorTest, TtlExpired) {
+  std::string packet(kReferenceNetworkPacket);
+  packet[7] = 1;
+
+  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
+  EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_TIME_EXCEEDED)));
+  SendPacketFromNetwork(packet);
+}
+
+TEST_F(QbonePacketProcessorTest, UnknownProtocol) {
+  std::string packet(kReferenceNetworkPacket);
+  packet[6] = IPPROTO_SCTP;
+
+  EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
+  EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_PARAM_PROB)));
+  SendPacketFromNetwork(packet);
+}
+
+TEST_F(QbonePacketProcessorTest, FilterFromClient) {
+  auto filter = std::make_unique<MockPacketFilter>();
+  EXPECT_CALL(*filter, FilterPacket(_, _, _, _, _))
+      .WillRepeatedly(Return(ProcessingResult::SILENT_DROP));
+  processor_->set_filter(std::move(filter));
+
+  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+  SendPacketFromClient(kReferenceClientPacket);
+}
+
+class TestFilter : public QbonePacketProcessor::Filter {
+ public:
+  TestFilter(QuicIpAddress client_ip, QuicIpAddress network_ip)
+      : client_ip_(client_ip), network_ip_(network_ip) {}
+  ProcessingResult FilterPacket(Direction direction,
+                                absl::string_view full_packet,
+                                absl::string_view payload,
+                                icmp6_hdr* icmp_header,
+                                OutputInterface* output) override {
+    EXPECT_EQ(kIPv6HeaderSize, full_packet.size() - payload.size());
+    EXPECT_EQ(IPPROTO_UDP, TransportProtocolFromHeader(full_packet));
+    EXPECT_EQ(client_ip_, SourceIpFromHeader(full_packet));
+    EXPECT_EQ(network_ip_, DestinationIpFromHeader(full_packet));
+
+    called_++;
+    return ProcessingResult::SILENT_DROP;
+  }
+
+  int called() const { return called_; }
+
+ private:
+  int called_ = 0;
+
+  QuicIpAddress client_ip_;
+  QuicIpAddress network_ip_;
+};
+
+// Verify that the parameters are passed correctly into the filter, and that the
+// helper functions of the filter class work.
+TEST_F(QbonePacketProcessorTest, FilterHelperFunctions) {
+  auto filter_owned = std::make_unique<TestFilter>(client_ip_, network_ip_);
+  TestFilter* filter = filter_owned.get();
+  processor_->set_filter(std::move(filter_owned));
+
+  EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+  SendPacketFromClient(kReferenceClientPacket);
+  ASSERT_EQ(1, filter->called());
+}
+
+}  // namespace
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_packet_processor_test_tools.cc b/quiche/quic/qbone/qbone_packet_processor_test_tools.cc
new file mode 100644
index 0000000..ae9dd56
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_processor_test_tools.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
+
+#include <netinet/ip6.h>
+
+namespace quic {
+
+std::string PrependIPv6HeaderForTest(const std::string& body, int hops) {
+  ip6_hdr header;
+  memset(&header, 0, sizeof(header));
+
+  header.ip6_vfc = 6 << 4;
+  header.ip6_plen = htons(body.size());
+  header.ip6_nxt = IPPROTO_UDP;
+  header.ip6_hops = hops;
+  header.ip6_src = in6addr_loopback;
+  header.ip6_dst = in6addr_loopback;
+
+  std::string packet(sizeof(header) + body.size(), '\0');
+  memcpy(&packet[0], &header, sizeof(header));
+  memcpy(&packet[sizeof(header)], body.data(), body.size());
+  return packet;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_packet_processor_test_tools.h b/quiche/quic/qbone/qbone_packet_processor_test_tools.h
new file mode 100644
index 0000000..587f685
--- /dev/null
+++ b/quiche/quic/qbone/qbone_packet_processor_test_tools.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
+#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/qbone/qbone_packet_processor.h"
+
+namespace quic {
+
+class MockPacketProcessorOutput : public QbonePacketProcessor::OutputInterface {
+ public:
+  MockPacketProcessorOutput() {}
+
+  MOCK_METHOD(void, SendPacketToClient, (absl::string_view), (override));
+  MOCK_METHOD(void, SendPacketToNetwork, (absl::string_view), (override));
+};
+
+class MockPacketProcessorStats : public QbonePacketProcessor::StatsInterface {
+ public:
+  MockPacketProcessorStats() {}
+
+  MOCK_METHOD(void,
+              OnPacketForwarded,
+              (QbonePacketProcessor::Direction),
+              (override));
+  MOCK_METHOD(void,
+              OnPacketDroppedSilently,
+              (QbonePacketProcessor::Direction),
+              (override));
+  MOCK_METHOD(void,
+              OnPacketDroppedWithIcmp,
+              (QbonePacketProcessor::Direction),
+              (override));
+  MOCK_METHOD(void,
+              OnPacketDroppedWithTcpReset,
+              (QbonePacketProcessor::Direction),
+              (override));
+  MOCK_METHOD(void,
+              OnPacketDeferred,
+              (QbonePacketProcessor::Direction),
+              (override));
+};
+
+std::string PrependIPv6HeaderForTest(const std::string& body, int hops);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
diff --git a/quic/qbone/qbone_packet_writer.h b/quiche/quic/qbone/qbone_packet_writer.h
similarity index 100%
rename from quic/qbone/qbone_packet_writer.h
rename to quiche/quic/qbone/qbone_packet_writer.h
diff --git a/quiche/quic/qbone/qbone_server_session.cc b/quiche/quic/qbone/qbone_server_session.cc
new file mode 100644
index 0000000..ada978e
--- /dev/null
+++ b/quiche/quic/qbone/qbone_server_session.cc
@@ -0,0 +1,133 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_server_session.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, qbone_server_defer_control_stream_creation, true,
+    "If true, control stream in QBONE server session is created after "
+    "encryption established.");
+
+namespace quic {
+
+bool QboneCryptoServerStreamHelper::CanAcceptClientHello(
+    const CryptoHandshakeMessage& chlo,
+    const QuicSocketAddress& client_address,
+    const QuicSocketAddress& peer_address,
+    const QuicSocketAddress& self_address,
+    std::string* error_details) const {
+  absl::string_view alpn;
+  chlo.GetStringPiece(quic::kALPN, &alpn);
+  if (alpn != QboneConstants::kQboneAlpn) {
+    *error_details = "ALPN-indicated protocol is not qbone";
+    return false;
+  }
+  return true;
+}
+
+QboneServerSession::QboneServerSession(
+    const quic::ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection,
+    Visitor* owner,
+    const QuicConfig& config,
+    const QuicCryptoServerConfig* quic_crypto_server_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QbonePacketWriter* writer,
+    QuicIpAddress self_ip,
+    QuicIpAddress client_ip,
+    size_t client_ip_subnet_length,
+    QboneServerControlStream::Handler* handler)
+    : QboneSessionBase(connection, owner, config, supported_versions, writer),
+      processor_(self_ip, client_ip, client_ip_subnet_length, this, this),
+      quic_crypto_server_config_(quic_crypto_server_config),
+      compressed_certs_cache_(compressed_certs_cache),
+      handler_(handler) {}
+
+QboneServerSession::~QboneServerSession() {}
+
+std::unique_ptr<QuicCryptoStream> QboneServerSession::CreateCryptoStream() {
+  return CreateCryptoServerStream(quic_crypto_server_config_,
+                                  compressed_certs_cache_, this,
+                                  &stream_helper_);
+}
+
+void QboneServerSession::CreateControlStream() {
+  if (control_stream_ != nullptr) {
+    return;
+  }
+  // Register the reserved control stream.
+  auto control_stream =
+      std::make_unique<QboneServerControlStream>(this, handler_);
+  control_stream_ = control_stream.get();
+  ActivateStream(std::move(control_stream));
+}
+
+QuicStream* QboneServerSession::CreateControlStreamFromPendingStream(
+    PendingStream* pending) {
+  QUICHE_DCHECK(control_stream_ == nullptr);
+  // Register the reserved control stream.
+  auto control_stream =
+      std::make_unique<QboneServerControlStream>(pending, this, handler_);
+  control_stream_ = control_stream.get();
+  ActivateStream(std::move(control_stream));
+  return control_stream_;
+}
+
+void QboneServerSession::Initialize() {
+  QboneSessionBase::Initialize();
+  if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) {
+    CreateControlStream();
+  }
+}
+
+void QboneServerSession::SetDefaultEncryptionLevel(
+    quic::EncryptionLevel level) {
+  QboneSessionBase::SetDefaultEncryptionLevel(level);
+  if (GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation) &&
+      level == quic::ENCRYPTION_FORWARD_SECURE) {
+    CreateControlStream();
+  }
+}
+
+bool QboneServerSession::SendClientRequest(const QboneClientRequest& request) {
+  if (!control_stream_) {
+    QUIC_BUG(quic_bug_11026_1)
+        << "Cannot send client request before control stream is created.";
+    return false;
+  }
+  return control_stream_->SendRequest(request);
+}
+
+void QboneServerSession::ProcessPacketFromNetwork(absl::string_view packet) {
+  std::string buffer = std::string(packet);
+  processor_.ProcessPacket(&buffer,
+                           QbonePacketProcessor::Direction::FROM_NETWORK);
+}
+
+void QboneServerSession::ProcessPacketFromPeer(absl::string_view packet) {
+  std::string buffer = std::string(packet);
+  processor_.ProcessPacket(&buffer,
+                           QbonePacketProcessor::Direction::FROM_OFF_NETWORK);
+}
+
+void QboneServerSession::SendPacketToClient(absl::string_view packet) {
+  SendPacketToPeer(packet);
+}
+
+void QboneServerSession::SendPacketToNetwork(absl::string_view packet) {
+  QUICHE_DCHECK(writer_ != nullptr);
+  writer_->WritePacketToNetwork(packet.data(), packet.size());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_server_session.h b/quiche/quic/qbone/qbone_server_session.h
new file mode 100644
index 0000000..341b524
--- /dev/null
+++ b/quiche/quic/qbone/qbone_server_session.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
+#define QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/qbone/qbone_control.pb.h"
+#include "quiche/quic/qbone/qbone_control_stream.h"
+#include "quiche/quic/qbone/qbone_packet_processor.h"
+#include "quiche/quic/qbone/qbone_packet_writer.h"
+#include "quiche/quic/qbone/qbone_session_base.h"
+
+namespace quic {
+
+// A helper class is used by the QuicCryptoServerStream.
+class QboneCryptoServerStreamHelper
+    : public QuicCryptoServerStreamBase::Helper {
+ public:
+  // This will look for the QBONE alpn.
+  bool CanAcceptClientHello(const CryptoHandshakeMessage& chlo,
+                            const QuicSocketAddress& client_address,
+                            const QuicSocketAddress& peer_address,
+                            const QuicSocketAddress& self_address,
+                            std::string* error_details) const override;
+};
+
+class QUIC_EXPORT_PRIVATE QboneServerSession
+    : public QboneSessionBase,
+      public QbonePacketProcessor::OutputInterface,
+      public QbonePacketProcessor::StatsInterface {
+ public:
+  QboneServerSession(const quic::ParsedQuicVersionVector& supported_versions,
+                     QuicConnection* connection,
+                     Visitor* owner,
+                     const QuicConfig& config,
+                     const QuicCryptoServerConfig* quic_crypto_server_config,
+                     QuicCompressedCertsCache* compressed_certs_cache,
+                     QbonePacketWriter* writer,
+                     QuicIpAddress self_ip,
+                     QuicIpAddress client_ip,
+                     size_t client_ip_subnet_length,
+                     QboneServerControlStream::Handler* handler);
+  QboneServerSession(const QboneServerSession&) = delete;
+  QboneServerSession& operator=(const QboneServerSession&) = delete;
+  ~QboneServerSession() override;
+
+  void Initialize() override;
+  // Override to create control stream at FORWARD_SECURE encryption level.
+  void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
+
+  virtual bool SendClientRequest(const QboneClientRequest& request);
+
+  void ProcessPacketFromNetwork(absl::string_view packet) override;
+  void ProcessPacketFromPeer(absl::string_view packet) override;
+
+  // QbonePacketProcessor::OutputInterface implementation.
+  void SendPacketToClient(absl::string_view packet) override;
+  void SendPacketToNetwork(absl::string_view packet) override;
+
+  // QbonePacketProcessor::StatsInterface implementation.
+  void OnPacketForwarded(QbonePacketProcessor::Direction direction) override {}
+  void OnPacketDroppedSilently(
+      QbonePacketProcessor::Direction direction) override {}
+  void OnPacketDroppedWithIcmp(
+      QbonePacketProcessor::Direction direction) override {}
+  void OnPacketDroppedWithTcpReset(
+      QbonePacketProcessor::Direction direction) override {}
+  void OnPacketDeferred(QbonePacketProcessor::Direction direction) override {}
+
+ protected:
+  // QboneSessionBase interface implementation.
+  std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
+
+  // Instantiates QboneServerControlStream.
+  void CreateControlStream();
+
+  // Instantiates QboneServerControlStream from the pending stream and returns a
+  // pointer to it.
+  QuicStream* CreateControlStreamFromPendingStream(PendingStream* pending);
+
+  // The packet processor.
+  QbonePacketProcessor processor_;
+
+  // Config for QUIC crypto server stream, used by the server.
+  const QuicCryptoServerConfig* quic_crypto_server_config_;
+
+ private:
+  // Used by QUIC crypto server stream to track most recently compressed certs.
+  QuicCompressedCertsCache* compressed_certs_cache_;
+  // This helper is needed when create QuicCryptoServerStream.
+  QboneCryptoServerStreamHelper stream_helper_;
+  // Passed to the control stream.
+  QboneServerControlStream::Handler* handler_;
+  // The unowned control stream.
+  QboneServerControlStream* control_stream_ = nullptr;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
diff --git a/quiche/quic/qbone/qbone_session_base.cc b/quiche/quic/qbone/qbone_session_base.cc
new file mode 100644
index 0000000..1994c84
--- /dev/null
+++ b/quiche/quic/qbone/qbone_session_base.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_session_base.h"
+
+#include <netinet/icmp6.h>
+#include <netinet/ip6.h>
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_exported_stats.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, qbone_close_ephemeral_frames, true,
+    "If true, we'll call CloseStream even when we receive ephemeral frames.");
+
+namespace quic {
+
+#define ENDPOINT \
+  (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
+
+QboneSessionBase::QboneSessionBase(
+    QuicConnection* connection,
+    Visitor* owner,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QbonePacketWriter* writer)
+    : QuicSession(connection,
+                  owner,
+                  config,
+                  supported_versions,
+                  /*num_expected_unidirectional_static_streams = */ 0) {
+  set_writer(writer);
+  const uint32_t max_streams =
+      (std::numeric_limits<uint32_t>::max() / kMaxAvailableStreamsMultiplier) -
+      1;
+  this->config()->SetMaxBidirectionalStreamsToSend(max_streams);
+  if (VersionHasIetfQuicFrames(transport_version())) {
+    this->config()->SetMaxUnidirectionalStreamsToSend(max_streams);
+  }
+}
+
+QboneSessionBase::~QboneSessionBase() {}
+
+void QboneSessionBase::Initialize() {
+  crypto_stream_ = CreateCryptoStream();
+  QuicSession::Initialize();
+}
+
+const QuicCryptoStream* QboneSessionBase::GetCryptoStream() const {
+  return crypto_stream_.get();
+}
+
+QuicCryptoStream* QboneSessionBase::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+QuicStream* QboneSessionBase::CreateOutgoingStream() {
+  return ActivateDataStream(
+      CreateDataStream(GetNextOutgoingUnidirectionalStreamId()));
+}
+
+void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (frame.offset == 0 && frame.fin && frame.data_length > 0) {
+    ++num_ephemeral_packets_;
+    ProcessPacketFromPeer(
+        absl::string_view(frame.data_buffer, frame.data_length));
+    flow_controller()->AddBytesConsumed(frame.data_length);
+    // TODO(b/147817422): Add a counter for how many streams were actually
+    // closed here.
+    if (GetQuicFlag(FLAGS_qbone_close_ephemeral_frames)) {
+      ResetStream(frame.stream_id, QUIC_STREAM_CANCELLED);
+    }
+    return;
+  }
+  QuicSession::OnStreamFrame(frame);
+}
+
+void QboneSessionBase::OnMessageReceived(absl::string_view message) {
+  ++num_message_packets_;
+  ProcessPacketFromPeer(message);
+}
+
+QuicStream* QboneSessionBase::CreateIncomingStream(QuicStreamId id) {
+  return ActivateDataStream(CreateDataStream(id));
+}
+
+QuicStream* QboneSessionBase::CreateIncomingStream(PendingStream* /*pending*/) {
+  QUIC_NOTREACHED();
+  return nullptr;
+}
+
+bool QboneSessionBase::ShouldKeepConnectionAlive() const {
+  // QBONE connections stay alive until they're explicitly closed.
+  return true;
+}
+
+std::unique_ptr<QuicStream> QboneSessionBase::CreateDataStream(
+    QuicStreamId id) {
+  if (!IsEncryptionEstablished()) {
+    // Encryption not active so no stream created
+    return nullptr;
+  }
+
+  if (IsIncomingStream(id)) {
+    ++num_streamed_packets_;
+    return std::make_unique<QboneReadOnlyStream>(id, this);
+  }
+
+  return std::make_unique<QboneWriteOnlyStream>(id, this);
+}
+
+QuicStream* QboneSessionBase::ActivateDataStream(
+    std::unique_ptr<QuicStream> stream) {
+  // Transfer ownership of the data stream to the session via ActivateStream().
+  QuicStream* raw = stream.get();
+  if (stream) {
+    // Make QuicSession take ownership of the stream.
+    ActivateStream(std::move(stream));
+  }
+  return raw;
+}
+
+void QboneSessionBase::SendPacketToPeer(absl::string_view packet) {
+  if (crypto_stream_ == nullptr) {
+    QUIC_BUG(quic_bug_10987_1)
+        << "Attempting to send packet before encryption established";
+    return;
+  }
+
+  if (send_packets_as_messages_) {
+    quiche::QuicheMemSlice slice(quiche::QuicheBuffer::Copy(
+        connection()->helper()->GetStreamSendBufferAllocator(), packet));
+    switch (SendMessage(absl::MakeSpan(&slice, 1), /*flush=*/true).status) {
+      case MESSAGE_STATUS_SUCCESS:
+        break;
+      case MESSAGE_STATUS_TOO_LARGE: {
+        if (packet.size() < sizeof(ip6_hdr)) {
+          QUIC_BUG(quic_bug_10987_2)
+              << "Dropped malformed packet: IPv6 header too short";
+          break;
+        }
+        auto* header = reinterpret_cast<const ip6_hdr*>(packet.begin());
+        icmp6_hdr icmp_header{};
+        icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
+        icmp_header.icmp6_mtu =
+            connection()->GetGuaranteedLargestMessagePayload();
+
+        CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
+                         [this](absl::string_view icmp_packet) {
+                           writer_->WritePacketToNetwork(icmp_packet.data(),
+                                                         icmp_packet.size());
+                         });
+        break;
+      }
+      case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED:
+        QUIC_BUG(quic_bug_10987_3)
+            << "MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED";
+        break;
+      case MESSAGE_STATUS_UNSUPPORTED:
+        QUIC_BUG(quic_bug_10987_4) << "MESSAGE_STATUS_UNSUPPORTED";
+        break;
+      case MESSAGE_STATUS_BLOCKED:
+        QUIC_BUG(quic_bug_10987_5) << "MESSAGE_STATUS_BLOCKED";
+        break;
+      case MESSAGE_STATUS_INTERNAL_ERROR:
+        QUIC_BUG(quic_bug_10987_6) << "MESSAGE_STATUS_INTERNAL_ERROR";
+        break;
+    }
+    return;
+  }
+
+  // QBONE streams are ephemeral.
+  QuicStream* stream = CreateOutgoingStream();
+  if (!stream) {
+    QUIC_BUG(quic_bug_10987_7) << "Failed to create an outgoing QBONE stream.";
+    return;
+  }
+
+  QboneWriteOnlyStream* qbone_stream =
+      static_cast<QboneWriteOnlyStream*>(stream);
+  qbone_stream->WritePacketToQuicStream(packet);
+}
+
+uint64_t QboneSessionBase::GetNumEphemeralPackets() const {
+  return num_ephemeral_packets_;
+}
+
+uint64_t QboneSessionBase::GetNumStreamedPackets() const {
+  return num_streamed_packets_;
+}
+
+uint64_t QboneSessionBase::GetNumMessagePackets() const {
+  return num_message_packets_;
+}
+
+uint64_t QboneSessionBase::GetNumFallbackToStream() const {
+  return num_fallback_to_stream_;
+}
+
+void QboneSessionBase::set_writer(QbonePacketWriter* writer) {
+  writer_ = writer;
+  quic::AdjustTestValue("quic_QbonePacketWriter", &writer_);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_session_base.h b/quiche/quic/qbone/qbone_session_base.h
new file mode 100644
index 0000000..1304858
--- /dev/null
+++ b/quiche/quic/qbone/qbone_session_base.h
@@ -0,0 +1,114 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
+#define QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/qbone/qbone_packet_writer.h"
+#include "quiche/quic/qbone/qbone_stream.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QboneSessionBase : public QuicSession {
+ public:
+  QboneSessionBase(QuicConnection* connection,
+                   Visitor* owner,
+                   const QuicConfig& config,
+                   const ParsedQuicVersionVector& supported_versions,
+                   QbonePacketWriter* writer);
+  QboneSessionBase(const QboneSessionBase&) = delete;
+  QboneSessionBase& operator=(const QboneSessionBase&) = delete;
+  ~QboneSessionBase() override;
+
+  // Overrides from QuicSession.
+  // This will ensure that the crypto session is created.
+  void Initialize() override;
+  // This will check if the packet is wholly contained.
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  // Called whenever a MESSAGE frame is received.
+  void OnMessageReceived(absl::string_view message) override;
+
+  virtual void ProcessPacketFromNetwork(absl::string_view packet) = 0;
+  virtual void ProcessPacketFromPeer(absl::string_view packet) = 0;
+
+  // Returns the number of QBONE network packets that were received
+  // that fit into a single QuicStreamFrame and elided the creation of
+  // a QboneReadOnlyStream.
+  uint64_t GetNumEphemeralPackets() const;
+
+  // Returns the number of QBONE network packets that were via
+  // multiple packets, requiring the creation of a QboneReadOnlyStream.
+  uint64_t GetNumStreamedPackets() const;
+
+  // Returns the number of QBONE network packets that were received using QUIC
+  // MESSAGE frame.
+  uint64_t GetNumMessagePackets() const;
+
+  // Returns the number of times sending a MESSAGE frame failed, and the session
+  // used an ephemeral stream instead.
+  uint64_t GetNumFallbackToStream() const;
+
+  void set_writer(QbonePacketWriter* writer);
+  void set_send_packets_as_messages(bool send_packets_as_messages) {
+    send_packets_as_messages_ = send_packets_as_messages;
+  }
+
+ protected:
+  virtual std::unique_ptr<QuicCryptoStream> CreateCryptoStream() = 0;
+
+  // QuicSession interface implementation.
+  QuicCryptoStream* GetMutableCryptoStream() override;
+  const QuicCryptoStream* GetCryptoStream() const override;
+  QuicStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicStream* CreateIncomingStream(PendingStream* pending) override;
+  bool ShouldKeepConnectionAlive() const override;
+
+  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id) override {
+    return true;
+  }
+
+  QuicStream* CreateOutgoingStream();
+  std::unique_ptr<QuicStream> CreateDataStream(QuicStreamId id);
+  // Activates a QuicStream.  The session takes ownership of the stream, but
+  // returns an unowned pointer to the stream for convenience.
+  QuicStream* ActivateDataStream(std::unique_ptr<QuicStream> stream);
+
+  // Accepts a given packet from the network and writes it out
+  // to the QUIC stream. This will create an ephemeral stream per
+  // packet. This function will return true if a stream was created
+  // and the packet sent. It will return false if the stream could not
+  // be created.
+  void SendPacketToPeer(absl::string_view packet);
+
+  QbonePacketWriter* writer_;
+
+  // If true, MESSAGE frames are used for short datagrams.  If false, ephemeral
+  // streams are used instead.  Note that receiving MESSAGE frames is always
+  // supported.
+  bool send_packets_as_messages_ = false;
+
+ private:
+  // Used for the crypto handshake.
+  std::unique_ptr<QuicCryptoStream> crypto_stream_;
+
+  // Statistics for the packets received by the session.
+  uint64_t num_ephemeral_packets_ = 0;
+  uint64_t num_message_packets_ = 0;
+  uint64_t num_streamed_packets_ = 0;
+
+  // Number of times the connection has failed to send packets as MESSAGE frame
+  // and used streams as a fallback.
+  uint64_t num_fallback_to_stream_ = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_SESSION_BASE_H_
diff --git a/quiche/quic/qbone/qbone_session_test.cc b/quiche/quic/qbone/qbone_session_test.cc
new file mode 100644
index 0000000..e774202
--- /dev/null
+++ b/quiche/quic/qbone/qbone_session_test.cc
@@ -0,0 +1,642 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/qbone/platform/icmp_packet.h"
+#include "quiche/quic/qbone/qbone_client_session.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/quic/qbone/qbone_control_placeholder.pb.h"
+#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
+#include "quiche/quic/qbone/qbone_server_session.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using ::testing::_;
+using ::testing::Contains;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::NiceMock;
+using ::testing::Not;
+
+std::string TestPacketIn(const std::string& body) {
+  return PrependIPv6HeaderForTest(body, 5);
+}
+
+std::string TestPacketOut(const std::string& body) {
+  return PrependIPv6HeaderForTest(body, 4);
+}
+
+ParsedQuicVersionVector GetTestParams() {
+  ParsedQuicVersionVector test_versions;
+
+  // TODO(b/113130636): Make QBONE work with TLS.
+  for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
+    // QBONE requires MESSAGE frames
+    if (!version.SupportsMessageFrames()) {
+      continue;
+    }
+    test_versions.push_back(version);
+  }
+
+  return test_versions;
+}
+
+// Used by QuicCryptoServerConfig to provide server credentials, passes
+// everything through to ProofSourceForTesting if success is true,
+// and fails otherwise.
+class IndirectionProofSource : public ProofSource {
+ public:
+  explicit IndirectionProofSource(bool success) {
+    if (success) {
+      proof_source_ = crypto_test_utils::ProofSourceForTesting();
+    }
+  }
+
+  // ProofSource override.
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& server_config,
+                QuicTransportVersion transport_version,
+                absl::string_view chlo_hash,
+                std::unique_ptr<Callback> callback) override {
+    if (!proof_source_) {
+      QuicCryptoProof proof;
+      quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+          GetCertChain(server_address, client_address, hostname,
+                       &proof.cert_matched_sni);
+      callback->Run(/*ok=*/false, chain, proof, /*details=*/nullptr);
+      return;
+    }
+    proof_source_->GetProof(server_address, client_address, hostname,
+                            server_config, transport_version, chlo_hash,
+                            std::move(callback));
+  }
+
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) override {
+    if (!proof_source_) {
+      return quiche::QuicheReferenceCountedPointer<Chain>();
+    }
+    return proof_source_->GetCertChain(server_address, client_address, hostname,
+                                       cert_matched_sni);
+  }
+
+  void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      std::unique_ptr<SignatureCallback> callback) override {
+    if (!proof_source_) {
+      callback->Run(/*ok=*/true, "Signature", /*details=*/nullptr);
+      return;
+    }
+    proof_source_->ComputeTlsSignature(server_address, client_address, hostname,
+                                       signature_algorithm, in,
+                                       std::move(callback));
+  }
+
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override {
+    if (!proof_source_) {
+      return {};
+    }
+    return proof_source_->SupportedTlsSignatureAlgorithms();
+  }
+
+  TicketCrypter* GetTicketCrypter() override { return nullptr; }
+
+ private:
+  std::unique_ptr<ProofSource> proof_source_;
+};
+
+// Used by QuicCryptoClientConfig to verify server credentials, passes
+// everything through to ProofVerifierForTesting is success is true,
+// otherwise returns a canned response of QUIC_FAILURE.
+class IndirectionProofVerifier : public ProofVerifier {
+ public:
+  explicit IndirectionProofVerifier(bool success) {
+    if (success) {
+      proof_verifier_ = crypto_test_utils::ProofVerifierForTesting();
+    }
+  }
+
+  // ProofVerifier override
+  QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion transport_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* verify_details,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    if (!proof_verifier_) {
+      return QUIC_FAILURE;
+    }
+    return proof_verifier_->VerifyProof(
+        hostname, port, server_config, transport_version, chlo_hash, certs,
+        cert_sct, signature, context, error_details, verify_details,
+        std::move(callback));
+  }
+
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::vector<std::string>& certs,
+      const std::string& ocsp_response,
+      const std::string& cert_sct,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      uint8_t* out_alert,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    if (!proof_verifier_) {
+      return QUIC_FAILURE;
+    }
+    return proof_verifier_->VerifyCertChain(
+        hostname, port, certs, ocsp_response, cert_sct, context, error_details,
+        details, out_alert, std::move(callback));
+  }
+
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    if (!proof_verifier_) {
+      return nullptr;
+    }
+    return proof_verifier_->CreateDefaultContext();
+  }
+
+ private:
+  std::unique_ptr<ProofVerifier> proof_verifier_;
+};
+
+class DataSavingQbonePacketWriter : public QbonePacketWriter {
+ public:
+  void WritePacketToNetwork(const char* packet, size_t size) override {
+    data_.push_back(std::string(packet, size));
+  }
+
+  const std::vector<std::string>& data() { return data_; }
+
+ private:
+  std::vector<std::string> data_;
+};
+
+template <class T>
+class DataSavingQboneControlHandler : public QboneControlHandler<T> {
+ public:
+  void OnControlRequest(const T& request) override { data_.push_back(request); }
+
+  void OnControlError() override { error_ = true; }
+
+  const std::vector<T>& data() { return data_; }
+  bool error() { return error_; }
+
+ private:
+  std::vector<T> data_;
+  bool error_ = false;
+};
+
+// Single-threaded scheduled task runner based on a MockClock.
+//
+// Simulates asynchronous execution on a single thread by holding scheduled
+// tasks until Run() is called. Performs no synchronization, assumes that
+// Schedule() and Run() are called on the same thread.
+class FakeTaskRunner {
+ public:
+  explicit FakeTaskRunner(MockQuicConnectionHelper* helper)
+      : tasks_([](const TaskType& l, const TaskType& r) {
+          // Items at a later time should run after items at an earlier time.
+          // Priority queue comparisons should return true if l appears after r.
+          return l->time() > r->time();
+        }),
+        helper_(helper) {}
+
+  // Runs all tasks in time order.  Executes tasks scheduled at
+  // the same in an arbitrary order.
+  void Run() {
+    while (!tasks_.empty()) {
+      tasks_.top()->Run();
+      tasks_.pop();
+    }
+  }
+
+ private:
+  class InnerTask {
+   public:
+    InnerTask(std::function<void()> task, QuicTime time)
+        : task_(std::move(task)), time_(time) {}
+
+    void Cancel() { cancelled_ = true; }
+
+    void Run() {
+      if (!cancelled_) {
+        task_();
+      }
+    }
+
+    QuicTime time() const { return time_; }
+
+   private:
+    bool cancelled_ = false;
+    std::function<void()> task_;
+    QuicTime time_;
+  };
+
+ public:
+  // Schedules a function to run immediately and advances the time.
+  void Schedule(std::function<void()> task) {
+    tasks_.push(std::shared_ptr<InnerTask>(
+        new InnerTask(std::move(task), helper_->GetClock()->Now())));
+    helper_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+  }
+
+ private:
+  using TaskType = std::shared_ptr<InnerTask>;
+  std::priority_queue<TaskType,
+                      std::vector<TaskType>,
+                      std::function<bool(const TaskType&, const TaskType&)>>
+      tasks_;
+  MockQuicConnectionHelper* helper_;
+};
+
+class QboneSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QboneSessionTest()
+      : supported_versions_({GetParam()}),
+        runner_(&helper_),
+        compressed_certs_cache_(100) {}
+
+  ~QboneSessionTest() override {
+    delete client_connection_;
+    delete server_connection_;
+  }
+
+  const MockClock* GetClock() const {
+    return static_cast<const MockClock*>(helper_.GetClock());
+  }
+
+  // The parameters are used to control whether the handshake will success or
+  // not.
+  void CreateClientAndServerSessions(bool client_handshake_success = true,
+                                     bool server_handshake_success = true,
+                                     bool send_qbone_alpn = true) {
+    // Quic crashes if packets are sent at time 0, and the clock defaults to 0.
+    helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+    alarm_factory_ = std::make_unique<QuicEpollAlarmFactory>(&epoll_server_);
+    client_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
+    server_writer_ = std::make_unique<DataSavingQbonePacketWriter>();
+    client_handler_ =
+        std::make_unique<DataSavingQboneControlHandler<QboneClientRequest>>();
+    server_handler_ =
+        std::make_unique<DataSavingQboneControlHandler<QboneServerRequest>>();
+    QuicSocketAddress server_address(TestLoopback(), 0);
+    QuicSocketAddress client_address;
+    if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
+      client_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
+    } else {
+      client_address = QuicSocketAddress(QuicIpAddress::Any6(), 0);
+    }
+
+    {
+      client_connection_ = new QuicConnection(
+          TestConnectionId(), client_address, server_address, &helper_,
+          alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
+          Perspective::IS_CLIENT, supported_versions_);
+      client_connection_->SetSelfAddress(client_address);
+      QuicConfig config;
+      client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+          std::make_unique<IndirectionProofVerifier>(client_handshake_success));
+      if (send_qbone_alpn) {
+        client_crypto_config_->set_alpn("qbone");
+      }
+      client_peer_ = std::make_unique<QboneClientSession>(
+          client_connection_, client_crypto_config_.get(),
+          /*owner=*/nullptr, config, supported_versions_,
+          QuicServerId("test.example.com", 1234, false), client_writer_.get(),
+          client_handler_.get());
+    }
+
+    {
+      server_connection_ = new QuicConnection(
+          TestConnectionId(), server_address, client_address, &helper_,
+          alarm_factory_.get(), new NiceMock<MockPacketWriter>(), true,
+          Perspective::IS_SERVER, supported_versions_);
+      server_connection_->SetSelfAddress(server_address);
+      QuicConfig config;
+      server_crypto_config_ = std::make_unique<QuicCryptoServerConfig>(
+          QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+          std::make_unique<IndirectionProofSource>(server_handshake_success),
+          KeyExchangeSource::Default());
+      QuicCryptoServerConfig::ConfigOptions options;
+      QuicServerConfigProtobuf primary_config =
+          server_crypto_config_->GenerateConfig(QuicRandom::GetInstance(),
+                                                GetClock(), options);
+      std::unique_ptr<CryptoHandshakeMessage> message(
+          server_crypto_config_->AddConfig(primary_config,
+                                           GetClock()->WallNow()));
+
+      server_peer_ = std::make_unique<QboneServerSession>(
+          supported_versions_, server_connection_, nullptr, config,
+          server_crypto_config_.get(), &compressed_certs_cache_,
+          server_writer_.get(), TestLoopback6(), TestLoopback6(), 64,
+          server_handler_.get());
+    }
+
+    // Hook everything up!
+    MockPacketWriter* client_writer = static_cast<MockPacketWriter*>(
+        QuicConnectionPeer::GetWriter(client_peer_->connection()));
+    ON_CALL(*client_writer, WritePacket(_, _, _, _, _))
+        .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
+                                     const QuicIpAddress& self_address,
+                                     const QuicSocketAddress& peer_address,
+                                     PerPacketOptions* options) {
+          char* copy = new char[1024 * 1024];
+          memcpy(copy, buffer, buf_len);
+          runner_.Schedule([this, copy, buf_len] {
+            QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
+            server_peer_->ProcessUdpPacket(server_connection_->self_address(),
+                                           client_connection_->self_address(),
+                                           packet);
+            delete[] copy;
+          });
+          return WriteResult(WRITE_STATUS_OK, buf_len);
+        }));
+    MockPacketWriter* server_writer = static_cast<MockPacketWriter*>(
+        QuicConnectionPeer::GetWriter(server_peer_->connection()));
+    ON_CALL(*server_writer, WritePacket(_, _, _, _, _))
+        .WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
+                                     const QuicIpAddress& self_address,
+                                     const QuicSocketAddress& peer_address,
+                                     PerPacketOptions* options) {
+          char* copy = new char[1024 * 1024];
+          memcpy(copy, buffer, buf_len);
+          runner_.Schedule([this, copy, buf_len] {
+            QuicReceivedPacket packet(copy, buf_len, GetClock()->Now());
+            client_peer_->ProcessUdpPacket(client_connection_->self_address(),
+                                           server_connection_->self_address(),
+                                           packet);
+            delete[] copy;
+          });
+          return WriteResult(WRITE_STATUS_OK, buf_len);
+        }));
+  }
+
+  void StartHandshake() {
+    server_peer_->Initialize();
+    client_peer_->Initialize();
+    runner_.Run();
+  }
+
+  void ExpectICMPTooBigResponse(const std::vector<std::string>& written_packets,
+                                const int mtu,
+                                const std::string& packet) {
+    auto* header = reinterpret_cast<const ip6_hdr*>(packet.data());
+    icmp6_hdr icmp_header{};
+    icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
+    icmp_header.icmp6_mtu = mtu;
+
+    std::string expected;
+    CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
+                     [&expected](absl::string_view icmp_packet) {
+                       expected = std::string(icmp_packet);
+                     });
+
+    EXPECT_THAT(written_packets, Contains(expected));
+  }
+
+  // Test handshake establishment and sending/receiving of data for two
+  // directions.
+  void TestStreamConnection(bool use_messages) {
+    ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
+    ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
+    ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
+    ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
+
+    // Create an outgoing stream from the client and say hello.
+    QUIC_LOG(INFO) << "Sending client -> server";
+    client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello"));
+    client_peer_->ProcessPacketFromNetwork(TestPacketIn("world"));
+    runner_.Run();
+    // The server should see the data, the client hasn't received
+    // anything yet.
+    EXPECT_THAT(server_writer_->data(),
+                ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
+    EXPECT_TRUE(client_writer_->data().empty());
+    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
+    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
+
+    // Let's pretend some service responds.
+    QUIC_LOG(INFO) << "Sending server -> client";
+    server_peer_->ProcessPacketFromNetwork(TestPacketIn("Hello Again"));
+    server_peer_->ProcessPacketFromNetwork(TestPacketIn("Again"));
+    runner_.Run();
+    EXPECT_THAT(server_writer_->data(),
+                ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
+    EXPECT_THAT(
+        client_writer_->data(),
+        ElementsAre(TestPacketOut("Hello Again"), TestPacketOut("Again")));
+    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
+    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
+
+    // Try to send long payloads that are larger than the QUIC MTU but
+    // smaller than the QBONE max size.
+    // This should trigger the non-ephemeral stream code path.
+    std::string long_data(
+        QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
+    QUIC_LOG(INFO) << "Sending server -> client long data";
+    server_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
+    runner_.Run();
+    if (use_messages) {
+      ExpectICMPTooBigResponse(
+          server_writer_->data(),
+          server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
+          TestPacketOut(long_data));
+    } else {
+      EXPECT_THAT(client_writer_->data(), Contains(TestPacketOut(long_data)));
+    }
+    EXPECT_THAT(server_writer_->data(),
+                Not(Contains(TestPacketOut(long_data))));
+    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
+    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
+
+    QUIC_LOG(INFO) << "Sending client -> server long data";
+    client_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
+    runner_.Run();
+    if (use_messages) {
+      ExpectICMPTooBigResponse(
+          client_writer_->data(),
+          client_peer_->connection()->GetGuaranteedLargestMessagePayload(),
+          TestPacketIn(long_data));
+    } else {
+      EXPECT_THAT(server_writer_->data(), Contains(TestPacketOut(long_data)));
+    }
+    EXPECT_FALSE(client_peer_->EarlyDataAccepted());
+    EXPECT_FALSE(client_peer_->ReceivedInchoateReject());
+    EXPECT_THAT(client_peer_->GetNumReceivedServerConfigUpdates(), Eq(0));
+
+    if (!use_messages) {
+      EXPECT_THAT(client_peer_->GetNumStreamedPackets(), Eq(1));
+      EXPECT_THAT(server_peer_->GetNumStreamedPackets(), Eq(1));
+    }
+
+    if (use_messages) {
+      EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(0));
+      EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(0));
+      EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(2));
+      EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(2));
+    } else {
+      EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(2));
+      EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(2));
+      EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(0));
+      EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(0));
+    }
+
+    // All streams are ephemeral and should be gone.
+    EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
+    EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
+  }
+
+  // Test that client and server are not connected after handshake failure.
+  void TestDisconnectAfterFailedHandshake() {
+    EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
+    EXPECT_FALSE(client_peer_->OneRttKeysAvailable());
+
+    EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
+    EXPECT_FALSE(server_peer_->OneRttKeysAvailable());
+  }
+
+ protected:
+  const ParsedQuicVersionVector supported_versions_;
+  QuicEpollServer epoll_server_;
+  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
+  FakeTaskRunner runner_;
+  MockQuicConnectionHelper helper_;
+  QuicConnection* client_connection_;
+  QuicConnection* server_connection_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+
+  std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
+  std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+  std::unique_ptr<DataSavingQbonePacketWriter> client_writer_;
+  std::unique_ptr<DataSavingQbonePacketWriter> server_writer_;
+  std::unique_ptr<DataSavingQboneControlHandler<QboneClientRequest>>
+      client_handler_;
+  std::unique_ptr<DataSavingQboneControlHandler<QboneServerRequest>>
+      server_handler_;
+
+  std::unique_ptr<QboneServerSession> server_peer_;
+  std::unique_ptr<QboneClientSession> client_peer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QboneSessionTest,
+                         ::testing::ValuesIn(GetTestParams()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QboneSessionTest, StreamConnection) {
+  CreateClientAndServerSessions();
+  client_peer_->set_send_packets_as_messages(false);
+  server_peer_->set_send_packets_as_messages(false);
+  StartHandshake();
+  TestStreamConnection(false);
+}
+
+TEST_P(QboneSessionTest, Messages) {
+  CreateClientAndServerSessions();
+  client_peer_->set_send_packets_as_messages(true);
+  server_peer_->set_send_packets_as_messages(true);
+  StartHandshake();
+  TestStreamConnection(true);
+}
+
+TEST_P(QboneSessionTest, ClientRejection) {
+  CreateClientAndServerSessions(false /*client_handshake_success*/,
+                                true /*server_handshake_success*/,
+                                true /*send_qbone_alpn*/);
+  StartHandshake();
+  TestDisconnectAfterFailedHandshake();
+}
+
+TEST_P(QboneSessionTest, BadAlpn) {
+  CreateClientAndServerSessions(true /*client_handshake_success*/,
+                                true /*server_handshake_success*/,
+                                false /*send_qbone_alpn*/);
+  StartHandshake();
+  TestDisconnectAfterFailedHandshake();
+}
+
+TEST_P(QboneSessionTest, ServerRejection) {
+  CreateClientAndServerSessions(true /*client_handshake_success*/,
+                                false /*server_handshake_success*/,
+                                true /*send_qbone_alpn*/);
+  StartHandshake();
+  TestDisconnectAfterFailedHandshake();
+}
+
+// Test that data streams are not created before handshake.
+TEST_P(QboneSessionTest, CannotCreateDataStreamBeforeHandshake) {
+  CreateClientAndServerSessions();
+  EXPECT_QUIC_BUG(client_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
+                  "Attempting to send packet before encryption established");
+  EXPECT_QUIC_BUG(server_peer_->ProcessPacketFromNetwork(TestPacketIn("hello")),
+                  "Attempting to send packet before encryption established");
+  EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
+  EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
+}
+
+TEST_P(QboneSessionTest, ControlRequests) {
+  CreateClientAndServerSessions();
+  StartHandshake();
+  EXPECT_TRUE(client_handler_->data().empty());
+  EXPECT_FALSE(client_handler_->error());
+  EXPECT_TRUE(server_handler_->data().empty());
+  EXPECT_FALSE(server_handler_->error());
+
+  QboneClientRequest client_request;
+  client_request.SetExtension(client_placeholder, "hello from the server");
+  EXPECT_TRUE(server_peer_->SendClientRequest(client_request));
+  runner_.Run();
+  ASSERT_FALSE(client_handler_->data().empty());
+  EXPECT_THAT(client_handler_->data()[0].GetExtension(client_placeholder),
+              Eq("hello from the server"));
+  EXPECT_FALSE(client_handler_->error());
+
+  QboneServerRequest server_request;
+  server_request.SetExtension(server_placeholder, "hello from the client");
+  EXPECT_TRUE(client_peer_->SendServerRequest(server_request));
+  runner_.Run();
+  ASSERT_FALSE(server_handler_->data().empty());
+  EXPECT_THAT(server_handler_->data()[0].GetExtension(server_placeholder),
+              Eq("hello from the client"));
+  EXPECT_FALSE(server_handler_->error());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_stream.cc b/quiche/quic/qbone/qbone_stream.cc
new file mode 100644
index 0000000..dad501b
--- /dev/null
+++ b/quiche/quic/qbone/qbone_stream.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_stream.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/quic/qbone/qbone_session_base.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int, qbone_stream_ttl_secs, 3,
+                                "The QBONE Stream TTL in seconds.");
+
+namespace quic {
+
+QboneWriteOnlyStream::QboneWriteOnlyStream(QuicStreamId id,
+                                           QuicSession* session)
+    : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL) {
+  // QBONE uses a LIFO queue to try to always make progress. An individual
+  // packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
+  MaybeSetTtl(
+      QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
+}
+
+void QboneWriteOnlyStream::WritePacketToQuicStream(absl::string_view packet) {
+  // Streams are one way and ephemeral. This function should only be
+  // called once.
+  WriteOrBufferData(packet, /* fin= */ true, nullptr);
+}
+
+QboneReadOnlyStream::QboneReadOnlyStream(QuicStreamId id,
+                                         QboneSessionBase* session)
+    : QuicStream(id,
+                 session,
+                 /*is_static=*/false,
+                 READ_UNIDIRECTIONAL),
+      session_(session) {
+  // QBONE uses a LIFO queue to try to always make progress. An individual
+  // packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
+  MaybeSetTtl(
+      QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
+}
+
+void QboneReadOnlyStream::OnDataAvailable() {
+  // Read in data and buffer it, attempt to frame to see if there's a packet.
+  sequencer()->Read(&buffer_);
+  if (sequencer()->IsClosed()) {
+    session_->ProcessPacketFromPeer(buffer_);
+    OnFinRead();
+    return;
+  }
+  if (buffer_.size() > QboneConstants::kMaxQbonePacketBytes) {
+    if (!rst_sent()) {
+      Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+    }
+    StopReading();
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/qbone/qbone_stream.h b/quiche/quic/qbone/qbone_stream.h
new file mode 100644
index 0000000..bc5551a
--- /dev/null
+++ b/quiche/quic/qbone/qbone_stream.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_QBONE_STREAM_H_
+#define QUICHE_QUIC_QBONE_QBONE_STREAM_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+class QboneSessionBase;
+
+// QboneWriteOnlyStream is responsible for sending data for a single
+// packet to the other side.
+// Note that the stream will be created HalfClosed (reads will be closed).
+class QUIC_EXPORT_PRIVATE QboneWriteOnlyStream : public QuicStream {
+ public:
+  QboneWriteOnlyStream(QuicStreamId id, QuicSession* session);
+
+  // QuicStream implementation. QBONE writers are ephemeral and don't
+  // read any data.
+  void OnDataAvailable() override {}
+
+  // Write a network packet over the quic stream.
+  void WritePacketToQuicStream(absl::string_view packet);
+};
+
+// QboneReadOnlyStream will be used if we find an incoming stream that
+// isn't fully contained. It will buffer the data when available and
+// attempt to parse it as a packet to send to the network when a FIN
+// is found.
+// Note that the stream will be created HalfClosed (writes will be closed).
+class QUIC_EXPORT_PRIVATE QboneReadOnlyStream : public QuicStream {
+ public:
+  QboneReadOnlyStream(QuicStreamId id, QboneSessionBase* session);
+
+  ~QboneReadOnlyStream() override = default;
+
+  // QuicStream overrides.
+  // OnDataAvailable is called when there is data in the quic stream buffer.
+  // This will copy the buffer locally and attempt to parse it to write out
+  // packets to the network.
+  void OnDataAvailable() override;
+
+ private:
+  std::string buffer_;
+  QboneSessionBase* session_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_QBONE_STREAM_H_
diff --git a/quiche/quic/qbone/qbone_stream_test.cc b/quiche/quic/qbone/qbone_stream_test.cc
new file mode 100644
index 0000000..8392496
--- /dev/null
+++ b/quiche/quic/qbone/qbone_stream_test.cc
@@ -0,0 +1,259 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/qbone_stream.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/qbone/qbone_constants.h"
+#include "quiche/quic/qbone/qbone_session_base.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+namespace {
+
+using ::testing::_;
+using ::testing::StrictMock;
+
+// MockQuicSession that does not create streams and writes data from
+// QuicStream to a string.
+class MockQuicSession : public QboneSessionBase {
+ public:
+  MockQuicSession(QuicConnection* connection, const QuicConfig& config)
+      : QboneSessionBase(connection, nullptr /*visitor*/, config,
+                         CurrentSupportedVersions(), nullptr /*writer*/) {}
+
+  ~MockQuicSession() override {}
+
+  // Writes outgoing data from QuicStream to a string.
+  QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
+                              QuicStreamOffset offset, StreamSendingState state,
+                              TransmissionType type,
+                              EncryptionLevel level) override {
+    if (!writable_) {
+      return QuicConsumedData(0, false);
+    }
+
+    return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN);
+  }
+
+  QboneReadOnlyStream* CreateIncomingStream(QuicStreamId id) override {
+    return nullptr;
+  }
+
+  // Called by QuicStream when they want to close stream.
+  MOCK_METHOD(void, MaybeSendRstStreamFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error,
+               QuicStreamOffset bytes_written),
+              (override));
+  MOCK_METHOD(void, MaybeSendStopSendingFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error), (override));
+
+  // Sets whether data is written to buffer, or else if this is write blocked.
+  void set_writable(bool writable) { writable_ = writable; }
+
+  // Tracks whether the stream is write blocked and its priority.
+  void RegisterReliableStream(QuicStreamId stream_id) {
+    // The priority effectively does not matter. Put all streams on the same
+    // priority.
+    write_blocked_streams()->RegisterStream(
+        stream_id,
+        /*is_static_stream=*/false,
+        /* precedence= */ spdy::SpdyStreamPrecedence(3));
+  }
+
+  // The session take ownership of the stream.
+  void ActivateReliableStream(std::unique_ptr<QuicStream> stream) {
+    ActivateStream(std::move(stream));
+  }
+
+  std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override {
+    return std::make_unique<test::MockQuicCryptoStream>(this);
+  }
+
+  MOCK_METHOD(void, ProcessPacketFromPeer, (absl::string_view), (override));
+  MOCK_METHOD(void, ProcessPacketFromNetwork, (absl::string_view), (override));
+
+ private:
+  // Whether data is written to write_buffer_.
+  bool writable_ = true;
+};
+
+// Packet writer that does nothing. This is required for QuicConnection but
+// isn't used for writing data.
+class DummyPacketWriter : public QuicPacketWriter {
+ public:
+  DummyPacketWriter() {}
+
+  // QuicPacketWriter overrides.
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override {
+    return WriteResult(WRITE_STATUS_ERROR, 0);
+  }
+
+  bool IsWriteBlocked() const override { return false; };
+
+  void SetWritable() override {}
+
+  absl::optional<int> MessageTooBigErrorCode() const override {
+    return absl::nullopt;
+  }
+
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& peer_address) const override {
+    return 0;
+  }
+
+  bool SupportsReleaseTime() const override { return false; }
+
+  bool IsBatchMode() const override { return false; }
+
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& self_address,
+      const QuicSocketAddress& peer_address) override {
+    return {nullptr, nullptr};
+  }
+
+  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
+};
+
+class QboneReadOnlyStreamTest : public ::testing::Test,
+                                public QuicConnectionHelperInterface {
+ public:
+  void CreateReliableQuicStream() {
+    // Arbitrary values for QuicConnection.
+    Perspective perspective = Perspective::IS_SERVER;
+    bool owns_writer = true;
+
+    alarm_factory_ = std::make_unique<test::MockAlarmFactory>();
+
+    connection_.reset(new QuicConnection(
+        test::TestConnectionId(0), QuicSocketAddress(TestLoopback(), 0),
+        QuicSocketAddress(TestLoopback(), 0),
+        this /*QuicConnectionHelperInterface*/, alarm_factory_.get(),
+        new DummyPacketWriter(), owns_writer, perspective,
+        ParsedVersionOfIndex(CurrentSupportedVersions(), 0)));
+    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_.get(),
+                                                             QuicConfig());
+    session_->Initialize();
+    stream_ = new QboneReadOnlyStream(kStreamId, session_.get());
+    session_->ActivateReliableStream(
+        std::unique_ptr<QboneReadOnlyStream>(stream_));
+  }
+
+  ~QboneReadOnlyStreamTest() override {}
+
+  const QuicClock* GetClock() const override { return &clock_; }
+
+  QuicRandom* GetRandomGenerator() override {
+    return QuicRandom::GetInstance();
+  }
+
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override {
+    return &buffer_allocator_;
+  }
+
+ protected:
+  // The QuicSession will take the ownership.
+  QboneReadOnlyStream* stream_;
+  std::unique_ptr<StrictMock<MockQuicSession>> session_;
+  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
+  std::unique_ptr<QuicConnection> connection_;
+  // Used to implement the QuicConnectionHelperInterface.
+  quiche::SimpleBufferAllocator buffer_allocator_;
+  MockClock clock_;
+  const QuicStreamId kStreamId = QuicUtils::GetFirstUnidirectionalStreamId(
+      CurrentSupportedVersions()[0].transport_version, Perspective::IS_CLIENT);
+};
+
+// Read an entire string.
+TEST_F(QboneReadOnlyStreamTest, ReadDataWhole) {
+  std::string packet = "Stuff";
+  CreateReliableQuicStream();
+  QuicStreamFrame frame(kStreamId, true, 0, packet);
+  EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
+  stream_->OnStreamFrame(frame);
+}
+
+// Test buffering.
+TEST_F(QboneReadOnlyStreamTest, ReadBuffered) {
+  CreateReliableQuicStream();
+  std::string packet = "Stuf";
+  {
+    QuicStreamFrame frame(kStreamId, false, 0, packet);
+    stream_->OnStreamFrame(frame);
+  }
+  // We didn't write 5 bytes yet...
+
+  packet = "f";
+  EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
+  {
+    QuicStreamFrame frame(kStreamId, true, 4, packet);
+    stream_->OnStreamFrame(frame);
+  }
+}
+
+TEST_F(QboneReadOnlyStreamTest, ReadOutOfOrder) {
+  CreateReliableQuicStream();
+  std::string packet = "f";
+  {
+    QuicStreamFrame frame(kStreamId, true, 4, packet);
+    stream_->OnStreamFrame(frame);
+  }
+
+  packet = "S";
+  {
+    QuicStreamFrame frame(kStreamId, false, 0, packet);
+    stream_->OnStreamFrame(frame);
+  }
+
+  packet = "tuf";
+  EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
+  {
+    QuicStreamFrame frame(kStreamId, false, 1, packet);
+    stream_->OnStreamFrame(frame);
+  }
+}
+
+// Test buffering too many bytes.
+TEST_F(QboneReadOnlyStreamTest, ReadBufferedTooLarge) {
+  CreateReliableQuicStream();
+  std::string packet = "0123456789";
+  int iterations = (QboneConstants::kMaxQbonePacketBytes / packet.size()) + 2;
+  EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
+                             kStreamId, QuicResetStreamError::FromInternal(
+                                            QUIC_BAD_APPLICATION_PAYLOAD)));
+  EXPECT_CALL(
+      *session_,
+      MaybeSendRstStreamFrame(
+          kStreamId,
+          QuicResetStreamError::FromInternal(QUIC_BAD_APPLICATION_PAYLOAD), _));
+  for (int i = 0; i < iterations; ++i) {
+    QuicStreamFrame frame(kStreamId, i == (iterations - 1), i * packet.size(),
+                          packet);
+    if (!stream_->reading_stopped()) {
+      stream_->OnStreamFrame(frame);
+    }
+  }
+  // We should have nothing written to the network and the stream
+  // should have stopped reading.
+  EXPECT_TRUE(stream_->reading_stopped());
+}
+
+}  // namespace
+
+}  // namespace quic
diff --git a/quic/quic_transport/README.md b/quiche/quic/quic_transport/README.md
similarity index 100%
rename from quic/quic_transport/README.md
rename to quiche/quic/quic_transport/README.md
diff --git a/quiche/quic/quic_transport/quic_transport_client_session.cc b/quiche/quic/quic_transport/quic_transport_client_session.cc
new file mode 100644
index 0000000..e9d0da8
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_client_session.cc
@@ -0,0 +1,267 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/quic_transport/quic_transport_client_session.h"
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/quic_transport/quic_transport_protocol.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+
+namespace quic {
+
+QuicTransportClientSession::QuicTransportClientSession(
+    QuicConnection* connection,
+    Visitor* owner,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    const GURL& url,
+    QuicCryptoClientConfig* crypto_config,
+    url::Origin origin,
+    WebTransportVisitor* visitor,
+    std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
+    : QuicSession(connection,
+                  owner,
+                  config,
+                  supported_versions,
+                  /*num_expected_unidirectional_static_streams*/ 0,
+                  std::move(datagram_observer)),
+      url_(url),
+      origin_(origin),
+      visitor_(visitor) {
+  for (const ParsedQuicVersion& version : supported_versions) {
+    QUIC_BUG_IF(quic_bug_12035_1, version.handshake_protocol != PROTOCOL_TLS1_3)
+        << "QuicTransport requires TLS 1.3 handshake";
+  }
+  crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
+      QuicServerId(url.host(), url.EffectiveIntPort()), this,
+      crypto_config->proof_verifier()->CreateDefaultContext(), crypto_config,
+      /*proof_handler=*/this, /*has_application_state = */ true);
+}
+
+void QuicTransportClientSession::OnAlpnSelected(absl::string_view alpn) {
+  // Defense in-depth: ensure the ALPN selected is the desired one.
+  if (alpn != QuicTransportAlpn()) {
+    QUIC_BUG(quic_bug_10881_1)
+        << "QuicTransport negotiated non-QuicTransport ALPN: " << alpn;
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, "QuicTransport negotiated non-QuicTransport ALPN",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  alpn_received_ = true;
+}
+
+QuicStream* QuicTransportClientSession::CreateIncomingStream(QuicStreamId id) {
+  QUIC_DVLOG(1) << "Creating incoming QuicTransport stream " << id;
+  QuicTransportStream* stream = CreateStream(id);
+  if (stream->type() == BIDIRECTIONAL) {
+    incoming_bidirectional_streams_.push_back(stream);
+    visitor_->OnIncomingBidirectionalStreamAvailable();
+  } else {
+    incoming_unidirectional_streams_.push_back(stream);
+    visitor_->OnIncomingUnidirectionalStreamAvailable();
+  }
+  return stream;
+}
+
+void QuicTransportClientSession::SetDefaultEncryptionLevel(
+    EncryptionLevel level) {
+  QuicSession::SetDefaultEncryptionLevel(level);
+  if (level == ENCRYPTION_FORWARD_SECURE) {
+    SendClientIndication();
+  }
+}
+
+void QuicTransportClientSession::OnTlsHandshakeComplete() {
+  QuicSession::OnTlsHandshakeComplete();
+  SendClientIndication();
+}
+
+QuicTransportStream*
+QuicTransportClientSession::AcceptIncomingBidirectionalStream() {
+  if (incoming_bidirectional_streams_.empty()) {
+    return nullptr;
+  }
+  QuicTransportStream* stream = incoming_bidirectional_streams_.front();
+  incoming_bidirectional_streams_.pop_front();
+  return stream;
+}
+
+QuicTransportStream*
+QuicTransportClientSession::AcceptIncomingUnidirectionalStream() {
+  if (incoming_unidirectional_streams_.empty()) {
+    return nullptr;
+  }
+  QuicTransportStream* stream = incoming_unidirectional_streams_.front();
+  incoming_unidirectional_streams_.pop_front();
+  return stream;
+}
+
+QuicTransportStream*
+QuicTransportClientSession::OpenOutgoingBidirectionalStream() {
+  if (!CanOpenNextOutgoingBidirectionalStream()) {
+    QUIC_BUG(quic_bug_10881_2)
+        << "Attempted to open a stream in violation of flow control";
+    return nullptr;
+  }
+  return CreateStream(GetNextOutgoingBidirectionalStreamId());
+}
+
+QuicTransportStream*
+QuicTransportClientSession::OpenOutgoingUnidirectionalStream() {
+  if (!CanOpenNextOutgoingUnidirectionalStream()) {
+    QUIC_BUG(quic_bug_10881_3)
+        << "Attempted to open a stream in violation of flow control";
+    return nullptr;
+  }
+  return CreateStream(GetNextOutgoingUnidirectionalStreamId());
+}
+
+QuicTransportStream* QuicTransportClientSession::CreateStream(QuicStreamId id) {
+  auto stream = std::make_unique<QuicTransportStream>(id, this, this);
+  QuicTransportStream* stream_ptr = stream.get();
+  ActivateStream(std::move(stream));
+  return stream_ptr;
+}
+
+std::string QuicTransportClientSession::SerializeClientIndication() {
+  std::string serialized_origin = origin_.Serialize();
+  if (serialized_origin.size() > std::numeric_limits<uint16_t>::max()) {
+    QUIC_BUG(quic_bug_10881_4) << "Client origin too long";
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, "Client origin too long",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return "";
+  }
+  QUIC_DLOG(INFO) << "Sending client indication with origin "
+                  << serialized_origin;
+
+  std::string path = url_.PathForRequest();
+  if (path.size() > std::numeric_limits<uint16_t>::max()) {
+    connection()->CloseConnection(
+        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, "Requested URL path too long",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return "";
+  }
+
+  constexpr size_t kPrefixSize =
+      sizeof(QuicTransportClientIndicationKeys) + sizeof(uint16_t);
+  const size_t buffer_size =
+      2 * kPrefixSize + serialized_origin.size() + path.size();
+  if (buffer_size > std::numeric_limits<uint16_t>::max()) {
+    connection()->CloseConnection(
+        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
+        "Client indication size limit exceeded",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return "";
+  }
+
+  std::string buffer;
+  buffer.resize(buffer_size);
+  QuicDataWriter writer(buffer.size(), &buffer[0]);
+  bool success =
+      writer.WriteUInt16(
+          static_cast<uint16_t>(QuicTransportClientIndicationKeys::kOrigin)) &&
+      writer.WriteUInt16(serialized_origin.size()) &&
+      writer.WriteStringPiece(serialized_origin) &&
+      writer.WriteUInt16(
+          static_cast<uint16_t>(QuicTransportClientIndicationKeys::kPath)) &&
+      writer.WriteUInt16(path.size()) && writer.WriteStringPiece(path);
+  QUIC_BUG_IF(quic_bug_10881_5, !success)
+      << "Failed to serialize client indication";
+  QUIC_BUG_IF(quic_bug_12035_2, writer.length() != buffer.length())
+      << "Serialized client indication has length different from expected";
+  return buffer;
+}
+
+void QuicTransportClientSession::SendClientIndication() {
+  if (!crypto_stream_->encryption_established()) {
+    QUIC_BUG(quic_bug_10881_6)
+        << "Client indication may only be sent once the encryption is "
+           "established.";
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, "Attempted to send client indication unencrypted",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (ready_) {
+    QUIC_BUG(quic_bug_10881_7) << "Client indication may only be sent once.";
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR, "Attempted to send client indication twice",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  auto client_indication_owned = std::make_unique<ClientIndication>(
+      /*stream_id=*/GetNextOutgoingUnidirectionalStreamId(), this,
+      /*is_static=*/false, WRITE_UNIDIRECTIONAL);
+  QUIC_BUG_IF(quic_bug_12035_3,
+              client_indication_owned->id() != ClientIndicationStream())
+      << "Client indication stream is " << client_indication_owned->id()
+      << " instead of expected " << ClientIndicationStream();
+  ClientIndication* client_indication = client_indication_owned.get();
+  ActivateStream(std::move(client_indication_owned));
+
+  client_indication->WriteOrBufferData(SerializeClientIndication(),
+                                       /*fin=*/true, nullptr);
+  client_indication_sent_ = true;
+
+  // Defense in depth: never set the ready bit unless ALPN has been confirmed.
+  if (!alpn_received_) {
+    QUIC_BUG(quic_bug_10881_8)
+        << "ALPN confirmation missing after handshake complete";
+    connection()->CloseConnection(
+        QUIC_INTERNAL_ERROR,
+        "ALPN confirmation missing after handshake complete",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
+  // Don't set the ready bit if we closed the connection due to any error
+  // beforehand.
+  if (!connection()->connected()) {
+    return;
+  }
+
+  ready_ = true;
+  visitor_->OnSessionReady(spdy::SpdyHeaderBlock());
+}
+
+void QuicTransportClientSession::OnMessageReceived(absl::string_view message) {
+  visitor_->OnDatagramReceived(message);
+}
+
+void QuicTransportClientSession::OnCanCreateNewOutgoingStream(
+    bool unidirectional) {
+  if (unidirectional) {
+    visitor_->OnCanCreateNewOutgoingUnidirectionalStream();
+  } else {
+    visitor_->OnCanCreateNewOutgoingBidirectionalStream();
+  }
+}
+
+void QuicTransportClientSession::OnProofValid(
+    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
+
+void QuicTransportClientSession::OnProofVerifyDetailsAvailable(
+    const ProofVerifyDetails& /*verify_details*/) {}
+
+}  // namespace quic
diff --git a/quiche/quic/quic_transport/quic_transport_client_session.h b/quiche/quic/quic_transport/quic_transport_client_session.h
new file mode 100644
index 0000000..9cfe3c3
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_client_session.h
@@ -0,0 +1,176 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
+
+#include <cstdint>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_datagram_queue.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/quic_transport/quic_transport_protocol.h"
+#include "quiche/quic/quic_transport/quic_transport_session_interface.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quic {
+
+// A client session for the QuicTransport protocol.
+class QUIC_EXPORT_PRIVATE QuicTransportClientSession
+    : public QuicSession,
+      public WebTransportSession,
+      public QuicTransportSessionInterface,
+      public QuicCryptoClientStream::ProofHandler {
+ public:
+  QuicTransportClientSession(
+      QuicConnection* connection,
+      Visitor* owner,
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      const GURL& url,
+      QuicCryptoClientConfig* crypto_config,
+      url::Origin origin,
+      WebTransportVisitor* visitor,
+      std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
+
+  std::vector<std::string> GetAlpnsToOffer() const override {
+    return std::vector<std::string>({QuicTransportAlpn()});
+  }
+  void OnAlpnSelected(absl::string_view alpn) override;
+  bool alpn_received() const { return alpn_received_; }
+
+  void CryptoConnect() { crypto_stream_->CryptoConnect(); }
+
+  bool ShouldKeepConnectionAlive() const override { return true; }
+
+  QuicCryptoStream* GetMutableCryptoStream() override {
+    return crypto_stream_.get();
+  }
+  const QuicCryptoStream* GetCryptoStream() const override {
+    return crypto_stream_.get();
+  }
+
+  // Returns true once the encryption has been established and the client
+  // indication has been sent.  No application data will be read or written
+  // before the connection is ready.  Once the connection becomes ready, this
+  // method will never return false.
+  bool IsSessionReady() const override { return ready_; }
+
+  QuicStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
+    QUIC_BUG(quic_bug_10890_1)
+        << "QuicTransportClientSession::CreateIncomingStream("
+           "PendingStream) not implemented";
+    return nullptr;
+  }
+
+  void SetDefaultEncryptionLevel(EncryptionLevel level) override;
+  void OnTlsHandshakeComplete() override;
+  void OnMessageReceived(absl::string_view message) override;
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.
+  QuicTransportStream* AcceptIncomingBidirectionalStream() override;
+  QuicTransportStream* AcceptIncomingUnidirectionalStream() override;
+
+  bool CanOpenNextOutgoingBidirectionalStream() override {
+    return QuicSession::CanOpenNextOutgoingBidirectionalStream();
+  }
+  bool CanOpenNextOutgoingUnidirectionalStream() override {
+    return QuicSession::CanOpenNextOutgoingUnidirectionalStream();
+  }
+  QuicTransportStream* OpenOutgoingBidirectionalStream() override;
+  QuicTransportStream* OpenOutgoingUnidirectionalStream() override;
+
+  MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram) override {
+    return datagram_queue()->SendOrQueueDatagram(std::move(datagram));
+  }
+  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override {
+    datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
+  }
+
+  // For unit tests.
+  using QuicSession::datagram_queue;
+
+  // QuicCryptoClientStream::ProofHandler implementation.
+  void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
+  void OnProofVerifyDetailsAvailable(
+      const ProofVerifyDetails& verify_details) override;
+
+  void CloseSession(WebTransportSessionError /*error_code*/,
+                    absl::string_view error_message) override {
+    connection()->CloseConnection(
+        QUIC_NO_ERROR, std::string(error_message),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+
+  QuicByteCount GetMaxDatagramSize() const override {
+    return GetGuaranteedLargestMessagePayload();
+  }
+
+ protected:
+  class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
+   public:
+    using QuicStream::QuicStream;
+
+    // This method should never be called, since the stream is client-initiated
+    // unidirectional.
+    void OnDataAvailable() override {
+      QUIC_BUG(quic_bug_10890_2) << "Received data on a write-only stream";
+    }
+  };
+
+  // Creates and activates a QuicTransportStream for the given ID.
+  QuicTransportStream* CreateStream(QuicStreamId id);
+
+  // Serializes the client indication as described in
+  // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
+  std::string SerializeClientIndication();
+  // Creates the client indication stream and sends the client indication on it.
+  void SendClientIndication();
+
+  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
+
+  std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
+  GURL url_;
+  url::Origin origin_;
+  WebTransportVisitor* visitor_;  // not owned
+  bool client_indication_sent_ = false;
+  bool alpn_received_ = false;
+  bool ready_ = false;
+
+  // Contains all of the streams that has been received by the session but have
+  // not been processed by the application.
+  // TODO(vasilvv): currently, we always send MAX_STREAMS as long as the overall
+  // maximum number of streams for the connection has not been exceeded. We
+  // should also limit the maximum number of streams that the consuming code
+  // has not accepted to a smaller number, by checking the size of
+  // |incoming_bidirectional_streams_| and |incoming_unidirectional_streams_|
+  // before sending MAX_STREAMS.
+  quiche::QuicheCircularDeque<QuicTransportStream*>
+      incoming_bidirectional_streams_;
+  quiche::QuicheCircularDeque<QuicTransportStream*>
+      incoming_unidirectional_streams_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_H_
diff --git a/quiche/quic/quic_transport/quic_transport_client_session_test.cc b/quiche/quic/quic_transport/quic_transport_client_session_test.cc
new file mode 100644
index 0000000..a26ebee
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_client_session_test.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/quic_transport/quic_transport_client_session.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "url/gurl.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::ElementsAre;
+using testing::Eq;
+
+const char* kTestOrigin = "https://test-origin.test";
+url::Origin GetTestOrigin() {
+  GURL origin_url(kTestOrigin);
+  return url::Origin::Create(origin_url);
+}
+
+ParsedQuicVersionVector GetVersions() {
+  return {DefaultVersionForQuicTransport()};
+}
+
+std::string DataInStream(QuicStream* stream) {
+  QuicStreamSendBuffer& send_buffer = QuicStreamPeer::SendBuffer(stream);
+  std::string result;
+  result.resize(send_buffer.stream_offset());
+  QuicDataWriter writer(result.size(), &result[0]);
+  EXPECT_TRUE(
+      send_buffer.WriteStreamData(0, send_buffer.stream_offset(), &writer));
+  return result;
+}
+
+class QuicTransportClientSessionTest : public QuicTest {
+ protected:
+  QuicTransportClientSessionTest()
+      : connection_(&helper_,
+                    &alarm_factory_,
+                    Perspective::IS_CLIENT,
+                    GetVersions()),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
+    QuicEnableVersion(DefaultVersionForQuicTransport());
+    CreateSession(GetTestOrigin(), "");
+  }
+
+  void CreateSession(url::Origin origin, std::string url_suffix) {
+    session_ = std::make_unique<QuicTransportClientSession>(
+        &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
+        GURL("quic-transport://test.example.com:50000" + url_suffix),
+        &crypto_config_, origin, &visitor_, /*datagram_observer=*/nullptr);
+    session_->Initialize();
+    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+        session_->GetMutableCryptoStream());
+  }
+
+  void Connect() {
+    session_->CryptoConnect();
+    QuicConfig server_config = DefaultQuicConfig();
+    std::unique_ptr<QuicCryptoServerConfig> crypto_config(
+        crypto_test_utils::CryptoServerConfigForTesting());
+    crypto_test_utils::HandshakeWithFakeServer(
+        &server_config, crypto_config.get(), &helper_, &alarm_factory_,
+        &connection_, crypto_stream_, QuicTransportAlpn());
+  }
+
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnectionHelper helper_;
+
+  PacketSavingConnection connection_;
+  QuicCryptoClientConfig crypto_config_;
+  MockClientVisitor visitor_;
+  std::unique_ptr<QuicTransportClientSession> session_;
+  QuicCryptoClientStream* crypto_stream_;
+};
+
+TEST_F(QuicTransportClientSessionTest, HasValidAlpn) {
+  EXPECT_THAT(session_->GetAlpnsToOffer(), ElementsAre(QuicTransportAlpn()));
+}
+
+TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) {
+  constexpr char kTestOriginClientIndication[] =
+      "\0\0"                      // key (0x0000, origin)
+      "\0\x18"                    // length
+      "https://test-origin.test"  // value
+      "\0\x01"                    // key (0x0001, path)
+      "\0\x01"                    // length
+      "/";                        // value
+
+  EXPECT_CALL(visitor_, OnSessionReady(_));
+  Connect();
+  EXPECT_TRUE(session_->IsSessionReady());
+
+  QuicStream* client_indication_stream;
+  client_indication_stream =
+      QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
+          .get();
+  ASSERT_TRUE(client_indication_stream != nullptr);
+  const std::string client_indication = DataInStream(client_indication_stream);
+  const std::string expected_client_indication{
+      kTestOriginClientIndication,
+      ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
+  EXPECT_EQ(client_indication, expected_client_indication);
+}
+
+TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
+  constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
+  constexpr char kTestOriginClientIndication[] =
+      "\0\0"                      // key (0x0000, origin)
+      "\0\x18"                    // length
+      "https://test-origin.test"  // value
+      "\0\x01"                    // key (0x0001, path)
+      "\0\x14"                    // length
+      "/foo/bar?hello=world";     // value
+
+  CreateSession(GetTestOrigin(), kSuffix);
+  Connect();
+  EXPECT_TRUE(session_->IsSessionReady());
+
+  QuicStream* client_indication_stream;
+  client_indication_stream =
+      QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
+          .get();
+  ASSERT_TRUE(client_indication_stream != nullptr);
+  const std::string client_indication = DataInStream(client_indication_stream);
+  const std::string expected_client_indication{
+      kTestOriginClientIndication,
+      ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
+  EXPECT_EQ(client_indication, expected_client_indication);
+}
+
+TEST_F(QuicTransportClientSessionTest, OriginTooLong) {
+  std::string long_string(68000, 'a');
+  GURL bad_origin_url{"https://" + long_string + ".example/"};
+  EXPECT_TRUE(bad_origin_url.is_valid());
+  CreateSession(url::Origin::Create(bad_origin_url), "");
+
+  EXPECT_QUIC_BUG(Connect(), "Client origin too long");
+}
+
+TEST_F(QuicTransportClientSessionTest, ReceiveNewStreams) {
+  Connect();
+  ASSERT_TRUE(session_->IsSessionReady());
+  ASSERT_TRUE(session_->AcceptIncomingUnidirectionalStream() == nullptr);
+
+  const QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(
+      session_->transport_version(), 0);
+  QuicStreamFrame frame(id, /*fin=*/false, /*offset=*/0, "test");
+  EXPECT_CALL(visitor_, OnIncomingUnidirectionalStreamAvailable()).Times(1);
+  session_->OnStreamFrame(frame);
+
+  QuicTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(stream != nullptr);
+  EXPECT_EQ(stream->ReadableBytes(), 4u);
+  EXPECT_EQ(stream->id(), id);
+}
+
+TEST_F(QuicTransportClientSessionTest, ReceiveDatagram) {
+  EXPECT_CALL(visitor_, OnDatagramReceived(Eq("test")));
+  session_->OnMessageReceived("test");
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/quic_transport/quic_transport_integration_test.cc b/quiche/quic/quic_transport/quic_transport_integration_test.cc
new file mode 100644
index 0000000..2b27942
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_integration_test.cc
@@ -0,0 +1,417 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// An integration test that covers interactions between QuicTransport client and
+// server sessions.
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/quic_transport/quic_transport_client_session.h"
+#include "quiche/quic/quic_transport/quic_transport_server_session.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint_base.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+#include "quiche/quic/tools/quic_transport_simple_server_session.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using simulator::QuicEndpointBase;
+using simulator::Simulator;
+using testing::_;
+using testing::Assign;
+using testing::Eq;
+
+url::Origin GetTestOrigin() {
+  constexpr char kTestOrigin[] = "https://test-origin.test";
+  GURL origin_url(kTestOrigin);
+  return url::Origin::Create(origin_url);
+}
+
+ParsedQuicVersionVector GetVersions() {
+  return {DefaultVersionForQuicTransport()};
+}
+
+class QuicTransportEndpointBase : public QuicEndpointBase {
+ public:
+  QuicTransportEndpointBase(Simulator* simulator,
+                            const std::string& name,
+                            const std::string& peer_name,
+                            Perspective perspective)
+      : QuicEndpointBase(simulator, name, peer_name) {
+    QuicEnableVersion(DefaultVersionForQuicTransport());
+    connection_ = std::make_unique<QuicConnection>(
+        TestConnectionId(0x10), simulator::GetAddressFromName(name),
+        simulator::GetAddressFromName(peer_name), simulator,
+        simulator->GetAlarmFactory(), &writer_,
+        /*owns_writer=*/false, perspective, GetVersions());
+    connection_->SetSelfAddress(simulator::GetAddressFromName(name));
+  }
+};
+
+class QuicTransportClientEndpoint : public QuicTransportEndpointBase {
+ public:
+  QuicTransportClientEndpoint(Simulator* simulator,
+                              const std::string& name,
+                              const std::string& peer_name,
+                              const QuicConfig& config,
+                              url::Origin origin,
+                              const std::string& path)
+      : QuicTransportEndpointBase(simulator,
+                                  name,
+                                  peer_name,
+                                  Perspective::IS_CLIENT),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+        session_(connection_.get(),
+                 nullptr,
+                 config,
+                 GetVersions(),
+                 GURL("quic-transport://test.example.com:50000" + path),
+                 &crypto_config_,
+                 origin,
+                 &visitor_,
+                 /*datagram_observer=*/nullptr) {
+    session_.Initialize();
+  }
+
+  QuicTransportClientSession* session() { return &session_; }
+  MockClientVisitor* visitor() { return &visitor_; }
+
+ private:
+  QuicCryptoClientConfig crypto_config_;
+  MockClientVisitor visitor_;
+  QuicTransportClientSession session_;
+};
+
+class QuicTransportServerEndpoint : public QuicTransportEndpointBase {
+ public:
+  QuicTransportServerEndpoint(Simulator* simulator,
+                              const std::string& name,
+                              const std::string& peer_name,
+                              const QuicConfig& config,
+                              std::vector<url::Origin> accepted_origins)
+      : QuicTransportEndpointBase(simulator,
+                                  name,
+                                  peer_name,
+                                  Perspective::IS_SERVER),
+        crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(),
+                       crypto_test_utils::ProofSourceForTesting(),
+                       KeyExchangeSource::Default()),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        session_(connection_.get(),
+                 /*owns_connection=*/false,
+                 nullptr,
+                 config,
+                 GetVersions(),
+                 &crypto_config_,
+                 &compressed_certs_cache_,
+                 accepted_origins) {
+    session_.Initialize();
+  }
+
+  QuicTransportServerSession* session() { return &session_; }
+
+ private:
+  QuicCryptoServerConfig crypto_config_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicTransportSimpleServerSession session_;
+};
+
+constexpr QuicBandwidth kClientBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10000);
+constexpr QuicTime::Delta kClientPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(2);
+constexpr QuicBandwidth kServerBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(4000);
+constexpr QuicTime::Delta kServerPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(50);
+const QuicTime::Delta kTransferTime =
+    kClientBandwidth.TransferTime(kMaxOutgoingPacketSize) +
+    kServerBandwidth.TransferTime(kMaxOutgoingPacketSize);
+const QuicTime::Delta kRtt =
+    (kClientPropagationDelay + kServerPropagationDelay + kTransferTime) * 2;
+const QuicByteCount kBdp = kRtt * kServerBandwidth;
+
+constexpr QuicTime::Delta kDefaultTimeout = QuicTime::Delta::FromSeconds(3);
+
+class QuicTransportIntegrationTest : public QuicTest {
+ public:
+  QuicTransportIntegrationTest()
+      : switch_(&simulator_, "Switch", 8, 2 * kBdp) {}
+
+  void CreateDefaultEndpoints(const std::string& path) {
+    client_ = std::make_unique<QuicTransportClientEndpoint>(
+        &simulator_, "Client", "Server", client_config_, GetTestOrigin(), path);
+    server_ = std::make_unique<QuicTransportServerEndpoint>(
+        &simulator_, "Server", "Client", server_config_, accepted_origins_);
+  }
+
+  void WireUpEndpoints() {
+    client_link_ = std::make_unique<simulator::SymmetricLink>(
+        client_.get(), switch_.port(1), kClientBandwidth,
+        kClientPropagationDelay);
+    server_link_ = std::make_unique<simulator::SymmetricLink>(
+        server_.get(), switch_.port(2), kServerBandwidth,
+        kServerPropagationDelay);
+  }
+
+  void RunHandshake() {
+    client_->session()->CryptoConnect();
+    bool result = simulator_.RunUntilOrTimeout(
+        [this]() {
+          return IsHandshakeDone(client_->session()) &&
+                 IsHandshakeDone(server_->session());
+        },
+        kDefaultTimeout);
+    EXPECT_TRUE(result);
+  }
+
+ protected:
+  template <class Session>
+  static bool IsHandshakeDone(const Session* session) {
+    return session->IsSessionReady() || session->error() != QUIC_NO_ERROR;
+  }
+
+  QuicConfig client_config_ = DefaultQuicConfig();
+  QuicConfig server_config_ = DefaultQuicConfig();
+
+  Simulator simulator_;
+  simulator::Switch switch_;
+  std::unique_ptr<simulator::SymmetricLink> client_link_;
+  std::unique_ptr<simulator::SymmetricLink> server_link_;
+
+  std::unique_ptr<QuicTransportClientEndpoint> client_;
+  std::unique_ptr<QuicTransportServerEndpoint> server_;
+
+  std::vector<url::Origin> accepted_origins_ = {GetTestOrigin()};
+};
+
+TEST_F(QuicTransportIntegrationTest, SuccessfulHandshake) {
+  CreateDefaultEndpoints("/discard");
+  WireUpEndpoints();
+  EXPECT_CALL(*client_->visitor(), OnSessionReady(_));
+  RunHandshake();
+  EXPECT_TRUE(client_->session()->IsSessionReady());
+  EXPECT_TRUE(server_->session()->IsSessionReady());
+}
+
+TEST_F(QuicTransportIntegrationTest, OriginMismatch) {
+  accepted_origins_ = {url::Origin::Create(GURL{"https://wrong-origin.test"})};
+  CreateDefaultEndpoints("/discard");
+  WireUpEndpoints();
+  RunHandshake();
+  // Wait until the client receives CONNECTION_CLOSE.
+  simulator_.RunUntilOrTimeout(
+      [this]() { return !client_->session()->connection()->connected(); },
+      kDefaultTimeout);
+  EXPECT_TRUE(client_->session()->IsSessionReady());
+  EXPECT_FALSE(server_->session()->IsSessionReady());
+  EXPECT_FALSE(client_->session()->connection()->connected());
+  EXPECT_FALSE(server_->session()->connection()->connected());
+  EXPECT_THAT(client_->session()->error(),
+              IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
+  EXPECT_THAT(server_->session()->error(),
+              IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
+}
+
+TEST_F(QuicTransportIntegrationTest, SendOutgoingStreams) {
+  CreateDefaultEndpoints("/discard");
+  WireUpEndpoints();
+  RunHandshake();
+
+  std::vector<QuicTransportStream*> streams;
+  for (int i = 0; i < 10; i++) {
+    QuicTransportStream* stream =
+        client_->session()->OpenOutgoingUnidirectionalStream();
+    ASSERT_TRUE(stream->Write("test"));
+    streams.push_back(stream);
+  }
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() {
+        return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
+               10;
+      },
+      kDefaultTimeout));
+
+  for (QuicTransportStream* stream : streams) {
+    ASSERT_TRUE(stream->SendFin());
+  }
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() {
+        return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
+               0;
+      },
+      kDefaultTimeout));
+}
+
+TEST_F(QuicTransportIntegrationTest, EchoBidirectionalStreams) {
+  CreateDefaultEndpoints("/echo");
+  WireUpEndpoints();
+  RunHandshake();
+
+  QuicTransportStream* stream =
+      client_->session()->OpenOutgoingBidirectionalStream();
+  EXPECT_TRUE(stream->Write("Hello!"));
+
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [stream]() { return stream->ReadableBytes() == strlen("Hello!"); },
+      kDefaultTimeout));
+  std::string received;
+  WebTransportStream::ReadResult result = stream->Read(&received);
+  EXPECT_EQ(result.bytes_read, strlen("Hello!"));
+  EXPECT_FALSE(result.fin);
+  EXPECT_EQ(received, "Hello!");
+
+  EXPECT_TRUE(stream->SendFin());
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() {
+        return QuicSessionPeer::GetNumOpenDynamicStreams(server_->session()) ==
+               0;
+      },
+      kDefaultTimeout));
+}
+
+TEST_F(QuicTransportIntegrationTest, EchoUnidirectionalStreams) {
+  CreateDefaultEndpoints("/echo");
+  WireUpEndpoints();
+  RunHandshake();
+
+  // Send two streams, but only send FIN on the second one.
+  QuicTransportStream* stream1 =
+      client_->session()->OpenOutgoingUnidirectionalStream();
+  EXPECT_TRUE(stream1->Write("Stream One"));
+  QuicTransportStream* stream2 =
+      client_->session()->OpenOutgoingUnidirectionalStream();
+  EXPECT_TRUE(stream2->Write("Stream Two"));
+  EXPECT_TRUE(stream2->SendFin());
+
+  // Wait until a stream is received.
+  bool stream_received = false;
+  EXPECT_CALL(*client_->visitor(), OnIncomingUnidirectionalStreamAvailable())
+      .Times(2)
+      .WillRepeatedly(Assign(&stream_received, true));
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [&stream_received]() { return stream_received; }, kDefaultTimeout));
+
+  // Receive a reply stream and expect it to be the second one.
+  QuicTransportStream* reply =
+      client_->session()->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(reply != nullptr);
+  std::string buffer;
+  WebTransportStream::ReadResult result = reply->Read(&buffer);
+  EXPECT_GT(result.bytes_read, 0u);
+  EXPECT_TRUE(result.fin);
+  EXPECT_EQ(buffer, "Stream Two");
+
+  // Reset reply-related variables.
+  stream_received = false;
+  buffer = "";
+
+  // Send FIN on the first stream, and expect to receive it back.
+  EXPECT_TRUE(stream1->SendFin());
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [&stream_received]() { return stream_received; }, kDefaultTimeout));
+  reply = client_->session()->AcceptIncomingUnidirectionalStream();
+  ASSERT_TRUE(reply != nullptr);
+  result = reply->Read(&buffer);
+  EXPECT_GT(result.bytes_read, 0u);
+  EXPECT_TRUE(result.fin);
+  EXPECT_EQ(buffer, "Stream One");
+}
+
+TEST_F(QuicTransportIntegrationTest, EchoDatagram) {
+  CreateDefaultEndpoints("/echo");
+  WireUpEndpoints();
+  RunHandshake();
+
+  client_->session()->SendOrQueueDatagram(MemSliceFromString("test"));
+
+  bool datagram_received = false;
+  EXPECT_CALL(*client_->visitor(), OnDatagramReceived(Eq("test")))
+      .WillOnce(Assign(&datagram_received, true));
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [&datagram_received]() { return datagram_received; }, kDefaultTimeout));
+}
+
+// This test sets the datagram queue to an nearly-infinte queueing time, and
+// then sends 1000 datagrams.  We expect to receive most of them back, since the
+// datagrams would be paced out by the congestion controller.
+TEST_F(QuicTransportIntegrationTest, EchoALotOfDatagrams) {
+  CreateDefaultEndpoints("/echo");
+  WireUpEndpoints();
+  RunHandshake();
+
+  // Set the datagrams to effectively never expire.
+  client_->session()->SetDatagramMaxTimeInQueue(10000 * kRtt);
+  for (int i = 0; i < 1000; i++) {
+    client_->session()->SendOrQueueDatagram(MemSliceFromString(std::string(
+        client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
+  }
+
+  size_t received = 0;
+  EXPECT_CALL(*client_->visitor(), OnDatagramReceived(_))
+      .WillRepeatedly(
+          [&received](absl::string_view /*datagram*/) { received++; });
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [this]() { return client_->session()->datagram_queue()->empty(); },
+      3 * kServerBandwidth.TransferTime(1000 * kMaxOutgoingPacketSize)));
+  // Allow extra round-trips for the final flight of datagrams to arrive back.
+  simulator_.RunFor(2 * kRtt);
+
+  EXPECT_GT(received, 500u);
+  EXPECT_LT(received, 1000u);
+}
+
+TEST_F(QuicTransportIntegrationTest, OutgoingStreamFlowControlBlocked) {
+  server_config_.SetMaxUnidirectionalStreamsToSend(4);
+  CreateDefaultEndpoints("/discard");
+  WireUpEndpoints();
+  RunHandshake();
+
+  QuicTransportStream* stream;
+  // Note that since we've already used one stream for client indication, we can
+  // only send three streams at once.
+  for (int i = 0; i < 3; i++) {
+    ASSERT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
+    stream = client_->session()->OpenOutgoingUnidirectionalStream();
+    ASSERT_TRUE(stream != nullptr);
+    ASSERT_TRUE(stream->SendFin());
+  }
+  EXPECT_FALSE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
+
+  // Receiving FINs for the streams we've just opened will cause the server to
+  // let us open more streams.
+  bool can_create_new_stream = false;
+  EXPECT_CALL(*client_->visitor(), OnCanCreateNewOutgoingUnidirectionalStream())
+      .WillOnce(Assign(&can_create_new_stream, true));
+  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
+      [&can_create_new_stream]() { return can_create_new_stream; },
+      kDefaultTimeout));
+  EXPECT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/quic_transport/quic_transport_protocol.h b/quiche/quic/quic_transport/quic_transport_protocol.h
new file mode 100644
index 0000000..e173cce
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_protocol.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// The ALPN used by QuicTransport.
+QUIC_EXPORT_PRIVATE inline const char* QuicTransportAlpn() {
+  return "wq-vvv-01";
+}
+
+// The stream ID on which the client indication is sent.
+QUIC_EXPORT_PRIVATE constexpr QuicStreamId ClientIndicationStream() {
+  return 2;
+}
+
+// The maximum allowed size of the client indication.
+QUIC_EXPORT_PRIVATE constexpr QuicByteCount ClientIndicationMaxSize() {
+  return 65536;
+}
+
+// The keys of the fields in the client indication.
+enum class QuicTransportClientIndicationKeys : uint16_t {
+  kOrigin = 0x0000,
+  kPath = 0x0001,
+};
+
+// Returns if the specified QUIC version can be used by QuicTransport.
+QUIC_EXPORT_PRIVATE constexpr bool IsVersionValidForQuicTransport(
+    const ParsedQuicVersion& version) {
+  return VersionSupportsMessageFrames(version.transport_version) &&
+         VersionHasIetfQuicFrames(version.transport_version) &&
+         version.handshake_protocol == PROTOCOL_TLS1_3;
+}
+
+// Returns default QUIC version used for QuicTransport.
+QUIC_EXPORT_PRIVATE inline ParsedQuicVersion DefaultVersionForQuicTransport() {
+  constexpr ParsedQuicVersion version = ParsedQuicVersion::Draft29();
+  static_assert(IsVersionValidForQuicTransport(version),
+                "Default QUIC version used by QuicTransport is invalid");
+  return version;
+}
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_PROTOCOL_H_
diff --git a/quiche/quic/quic_transport/quic_transport_server_session.cc b/quiche/quic/quic_transport/quic_transport_server_session.cc
new file mode 100644
index 0000000..0f99541
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_server_session.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/quic_transport/quic_transport_server_session.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "url/url_constants.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/quic_transport/quic_transport_protocol.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+
+namespace quic {
+
+namespace {
+class QuicTransportServerCryptoHelper
+    : public QuicCryptoServerStreamBase::Helper {
+ public:
+  bool CanAcceptClientHello(const CryptoHandshakeMessage& /*message*/,
+                            const QuicSocketAddress& /*client_address*/,
+                            const QuicSocketAddress& /*peer_address*/,
+                            const QuicSocketAddress& /*self_address*/,
+                            std::string* /*error_details*/) const override {
+    return true;
+  }
+};
+
+}  // namespace
+
+QuicTransportServerSession::QuicTransportServerSession(
+    QuicConnection* connection,
+    Visitor* owner,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    ServerVisitor* visitor)
+    : QuicSession(connection,
+                  owner,
+                  config,
+                  supported_versions,
+                  /*num_expected_unidirectional_static_streams*/ 0),
+      visitor_(visitor) {
+  for (const ParsedQuicVersion& version : supported_versions) {
+    QUIC_BUG_IF(quic_bug_12025_1, version.handshake_protocol != PROTOCOL_TLS1_3)
+        << "QuicTransport requires TLS 1.3 handshake";
+  }
+
+  static QuicTransportServerCryptoHelper* helper =
+      new QuicTransportServerCryptoHelper();
+  crypto_stream_ = CreateCryptoServerStream(
+      crypto_config, compressed_certs_cache, this, helper);
+}
+
+QuicStream* QuicTransportServerSession::CreateIncomingStream(QuicStreamId id) {
+  if (id == ClientIndicationStream()) {
+    auto indication = std::make_unique<ClientIndication>(this);
+    ClientIndication* indication_ptr = indication.get();
+    ActivateStream(std::move(indication));
+    return indication_ptr;
+  }
+
+  auto stream = std::make_unique<QuicTransportStream>(id, this, this);
+  QuicTransportStream* stream_ptr = stream.get();
+  ActivateStream(std::move(stream));
+  OnIncomingDataStream(stream_ptr);
+  return stream_ptr;
+}
+
+QuicTransportServerSession::ClientIndication::ClientIndication(
+    QuicTransportServerSession* session)
+    : QuicStream(ClientIndicationStream(),
+                 session,
+                 /* is_static= */ false,
+                 StreamType::READ_UNIDIRECTIONAL),
+      session_(session) {}
+
+void QuicTransportServerSession::ClientIndication::OnDataAvailable() {
+  sequencer()->Read(&buffer_);
+  if (buffer_.size() > ClientIndicationMaxSize()) {
+    session_->connection()->CloseConnection(
+        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
+        absl::StrCat("Client indication size exceeds ",
+                     ClientIndicationMaxSize(), " bytes"),
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  if (sequencer()->IsClosed()) {
+    session_->ProcessClientIndication(buffer_);
+    OnFinRead();
+  }
+}
+
+bool QuicTransportServerSession::ClientIndicationParser::Parse() {
+  bool origin_received = false;
+  bool path_received = false;
+  while (!reader_.IsDoneReading()) {
+    uint16_t key;
+    if (!reader_.ReadUInt16(&key)) {
+      ParseError("Expected 16-bit key");
+      return false;
+    }
+
+    absl::string_view value;
+    if (!reader_.ReadStringPiece16(&value)) {
+      ParseError(absl::StrCat("Failed to read value for key ", key));
+      return false;
+    }
+
+    switch (static_cast<QuicTransportClientIndicationKeys>(key)) {
+      case QuicTransportClientIndicationKeys::kOrigin: {
+        GURL origin_url{std::string(value)};
+        if (!origin_url.is_valid()) {
+          Error("Unable to parse the specified origin");
+          return false;
+        }
+
+        url::Origin origin = url::Origin::Create(origin_url);
+        QUIC_DLOG(INFO) << "QuicTransport server received origin " << origin;
+        if (!session_->visitor_->CheckOrigin(origin)) {
+          Error("Origin check failed");
+          return false;
+        }
+        origin_received = true;
+        break;
+      }
+
+      case QuicTransportClientIndicationKeys::kPath: {
+        if (!ProcessPath(value)) {
+          return false;
+        }
+        path_received = true;
+        break;
+      }
+
+      default:
+        QUIC_DLOG(INFO) << "Unknown client indication key: " << key;
+        break;
+    }
+  }
+
+  if (!origin_received) {
+    Error("No origin received");
+    return false;
+  }
+  if (!path_received) {
+    Error("No path received");
+    return false;
+  }
+
+  return true;
+}
+
+bool QuicTransportServerSession::ClientIndicationParser::ProcessPath(
+    absl::string_view path) {
+  if (path.empty() || path[0] != '/') {
+    // https://tools.ietf.org/html/draft-vvv-webtransport-quic-01#section-3.2.2
+    Error("Path must begin with a '/'");
+    return false;
+  }
+
+  // TODO(b/145674008): use the SNI value from the handshake instead of the IP
+  // address.
+  std::string url_text =
+      absl::StrCat(url::kQuicTransportScheme, url::kStandardSchemeSeparator,
+                   session_->self_address().ToString(), path);
+  GURL url{url_text};
+  if (!url.is_valid()) {
+    Error("Invalid path specified");
+    return false;
+  }
+
+  if (!session_->visitor_->ProcessPath(url)) {
+    Error("Specified path rejected");
+    return false;
+  }
+  return true;
+}
+
+void QuicTransportServerSession::ClientIndicationParser::Error(
+    const std::string& error_message) {
+  session_->connection()->CloseConnection(
+      QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, error_message,
+      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void QuicTransportServerSession::ClientIndicationParser::ParseError(
+    absl::string_view error_message) {
+  Error(absl::StrCat("Failed to parse the client indication stream: ",
+                     error_message, reader_.DebugString()));
+}
+
+void QuicTransportServerSession::ProcessClientIndication(
+    absl::string_view indication) {
+  ClientIndicationParser parser(this, indication);
+  if (!parser.Parse()) {
+    return;
+  }
+  // Don't set the ready bit if we closed the connection due to any error
+  // beforehand.
+  if (!connection()->connected()) {
+    return;
+  }
+  ready_ = true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/quic_transport/quic_transport_server_session.h b/quiche/quic/quic_transport/quic_transport_server_session.h
new file mode 100644
index 0000000..9580bcc
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_server_session.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/quic_transport/quic_transport_protocol.h"
+#include "quiche/quic/quic_transport/quic_transport_session_interface.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+
+namespace quic {
+
+// A server session for the QuicTransport protocol.
+class QUIC_EXPORT_PRIVATE QuicTransportServerSession
+    : public QuicSession,
+      public QuicTransportSessionInterface {
+ public:
+  class QUIC_EXPORT_PRIVATE ServerVisitor {
+   public:
+    virtual ~ServerVisitor() {}
+
+    // Allows the server to decide whether the specified origin is allowed to
+    // connect to it.
+    virtual bool CheckOrigin(url::Origin origin) = 0;
+
+    // Indicates that the server received a path parameter from the client.  The
+    // path parameter is parsed, and can be retrived from url.path() and
+    // url.query().  If this method returns false, the connection is closed.
+    virtual bool ProcessPath(const GURL& url) = 0;
+  };
+
+  QuicTransportServerSession(QuicConnection* connection,
+                             Visitor* owner,
+                             const QuicConfig& config,
+                             const ParsedQuicVersionVector& supported_versions,
+                             const QuicCryptoServerConfig* crypto_config,
+                             QuicCompressedCertsCache* compressed_certs_cache,
+                             ServerVisitor* visitor);
+
+  std::vector<absl::string_view>::const_iterator SelectAlpn(
+      const std::vector<absl::string_view>& alpns) const override {
+    return std::find(alpns.cbegin(), alpns.cend(), QuicTransportAlpn());
+  }
+
+  bool ShouldKeepConnectionAlive() const override { return true; }
+
+  QuicCryptoServerStreamBase* GetMutableCryptoStream() override {
+    return crypto_stream_.get();
+  }
+  const QuicCryptoServerStreamBase* GetCryptoStream() const override {
+    return crypto_stream_.get();
+  }
+
+  // Returns true once the encryption has been established, the client
+  // indication has been received and the origin has been verified.  No
+  // application data will be read or written before the connection is ready.
+  // Once the connection becomes ready, this method will never return false.
+  bool IsSessionReady() const override { return ready_; }
+
+  QuicStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicStream* CreateIncomingStream(PendingStream* /*pending*/) override {
+    QUIC_BUG(quic_bug_10884_1)
+        << "QuicTransportServerSession::CreateIncomingStream("
+           "PendingStream) not implemented";
+    return nullptr;
+  }
+
+ protected:
+  class QUIC_EXPORT_PRIVATE ClientIndication : public QuicStream {
+   public:
+    explicit ClientIndication(QuicTransportServerSession* session);
+    void OnDataAvailable() override;
+
+   private:
+    QuicTransportServerSession* session_;
+    std::string buffer_;
+  };
+
+  // Utility class for parsing the client indication.
+  class QUIC_EXPORT_PRIVATE ClientIndicationParser {
+   public:
+    ClientIndicationParser(QuicTransportServerSession* session,
+                           absl::string_view indication)
+        : session_(session), reader_(indication) {}
+
+    // Parses the specified indication.  Automatically closes the connection
+    // with detailed error if parsing fails.  Returns true on success, false on
+    // failure.
+    bool Parse();
+
+   private:
+    void Error(const std::string& error_message);
+    void ParseError(absl::string_view error_message);
+
+    // Processes the path portion of the client indication.
+    bool ProcessPath(absl::string_view path);
+
+    QuicTransportServerSession* session_;
+    QuicDataReader reader_;
+  };
+
+  // Parses and processes the client indication as described in
+  // https://vasilvv.github.io/webtransport/draft-vvv-webtransport-quic.html#rfc.section.3.2
+  void ProcessClientIndication(absl::string_view indication);
+
+  virtual void OnIncomingDataStream(QuicTransportStream* /*stream*/) {}
+
+  std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
+  bool ready_ = false;
+  ServerVisitor* visitor_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SERVER_SESSION_H_
diff --git a/quiche/quic/quic_transport/quic_transport_server_session_test.cc b/quiche/quic/quic_transport/quic_transport_server_session_test.cc
new file mode 100644
index 0000000..c2690a0
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_server_session_test.cc
@@ -0,0 +1,291 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/quic_transport/quic_transport_server_session.h"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/quic_transport/quic_transport_protocol.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::AnyNumber;
+using testing::DoAll;
+using testing::HasSubstr;
+using testing::Return;
+using testing::SaveArg;
+
+constexpr char kTestOrigin[] = "https://test-origin.test";
+constexpr char kTestOriginClientIndication[] =
+    "\0\0"                      // key (0x0000, origin)
+    "\0\x18"                    // length
+    "https://test-origin.test"  // value
+    "\0\x01"                    // key (0x0001, path)
+    "\0\x05"                    // length
+    "/test";                    // value
+const url::Origin GetTestOrigin() {
+  return url::Origin::Create(GURL(kTestOrigin));
+}
+const std::string GetTestOriginClientIndication() {
+  return std::string(kTestOriginClientIndication,
+                     sizeof(kTestOriginClientIndication) - 1);
+}
+
+ParsedQuicVersionVector GetVersions() {
+  return {DefaultVersionForQuicTransport()};
+}
+
+class QuicTransportServerSessionTest : public QuicTest {
+ public:
+  QuicTransportServerSessionTest()
+      : connection_(&helper_,
+                    &alarm_factory_,
+                    Perspective::IS_SERVER,
+                    GetVersions()),
+        crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(),
+                       crypto_test_utils::ProofSourceForTesting(),
+                       KeyExchangeSource::Default()),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    QuicEnableVersion(DefaultVersionForQuicTransport());
+    connection_.AdvanceTime(QuicTime::Delta::FromSeconds(100000));
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        helper_.GetClock(), helper_.GetRandomGenerator(), &crypto_config_);
+    session_ = std::make_unique<QuicTransportServerSession>(
+        &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
+        &crypto_config_, &compressed_certs_cache_, &visitor_);
+    session_->Initialize();
+    crypto_stream_ = session_->GetMutableCryptoStream();
+    ON_CALL(visitor_, ProcessPath(_))
+        .WillByDefault(DoAll(SaveArg<0>(&path_), Return(true)));
+  }
+
+  void Connect() {
+    crypto_test_utils::FakeClientOptions options;
+    options.only_tls_versions = true;
+    crypto_test_utils::HandshakeWithFakeClient(
+        &helper_, &alarm_factory_, &connection_, crypto_stream_,
+        QuicServerId("test.example.com", 443), options, QuicTransportAlpn());
+  }
+
+  void ReceiveIndication(absl::string_view indication) {
+    QUIC_LOG(INFO) << "Receiving indication: "
+                   << quiche::QuicheTextUtils::HexDump(indication);
+    constexpr size_t kChunkSize = 1024;
+    // Shard the indication, since some of the tests cause it to not fit into a
+    // single frame.
+    for (size_t i = 0; i < indication.size(); i += kChunkSize) {
+      QuicStreamFrame frame(ClientIndicationStream(), /*fin=*/false, i,
+                            indication.substr(i, i + kChunkSize));
+      session_->OnStreamFrame(frame);
+    }
+    session_->OnStreamFrame(QuicStreamFrame(ClientIndicationStream(),
+                                            /*fin=*/true, indication.size(),
+                                            absl::string_view()));
+  }
+
+  void ReceiveIndicationWithPath(absl::string_view path) {
+    constexpr char kTestOriginClientIndicationPrefix[] =
+        "\0\0"                      // key (0x0000, origin)
+        "\0\x18"                    // length
+        "https://test-origin.test"  // value
+        "\0\x01";                   // key (0x0001, path)
+    std::string indication{kTestOriginClientIndicationPrefix,
+                           sizeof(kTestOriginClientIndicationPrefix) - 1};
+    indication.push_back(static_cast<char>(path.size() >> 8));
+    indication.push_back(static_cast<char>(path.size() & 0xff));
+    indication += std::string{path};
+    ReceiveIndication(indication);
+  }
+
+ protected:
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnectionHelper helper_;
+
+  PacketSavingConnection connection_;
+  QuicCryptoServerConfig crypto_config_;
+  std::unique_ptr<QuicTransportServerSession> session_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  testing::NiceMock<MockServerVisitor> visitor_;
+  QuicCryptoServerStreamBase* crypto_stream_;
+  GURL path_;
+};
+
+TEST_F(QuicTransportServerSessionTest, SuccessfulHandshake) {
+  Connect();
+
+  url::Origin origin;
+  EXPECT_CALL(visitor_, CheckOrigin(_))
+      .WillOnce(DoAll(SaveArg<0>(&origin), Return(true)));
+  ReceiveIndication(GetTestOriginClientIndication());
+  EXPECT_TRUE(session_->IsSessionReady());
+  EXPECT_EQ(origin, GetTestOrigin());
+  EXPECT_EQ(path_.path(), "/test");
+}
+
+TEST_F(QuicTransportServerSessionTest, PiecewiseClientIndication) {
+  Connect();
+  size_t i = 0;
+  for (; i < sizeof(kTestOriginClientIndication) - 2; i++) {
+    QuicStreamFrame frame(
+        ClientIndicationStream(), false, i,
+        absl::string_view(&kTestOriginClientIndication[i], 1));
+    session_->OnStreamFrame(frame);
+  }
+
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  QuicStreamFrame last_frame(
+      ClientIndicationStream(), true, i,
+      absl::string_view(&kTestOriginClientIndication[i], 1));
+  session_->OnStreamFrame(last_frame);
+  EXPECT_TRUE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, OriginRejected) {
+  Connect();
+  EXPECT_CALL(connection_,
+              CloseConnection(_, HasSubstr("Origin check failed"), _));
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(false));
+  ReceiveIndication(GetTestOriginClientIndication());
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+std::string MakeUnknownField(absl::string_view payload) {
+  std::string buffer;
+  buffer.resize(payload.size() + 4);
+  QuicDataWriter writer(buffer.size(), &buffer[0]);
+  EXPECT_TRUE(writer.WriteUInt16(0xffff));
+  EXPECT_TRUE(writer.WriteUInt16(payload.size()));
+  EXPECT_TRUE(writer.WriteStringPiece(payload));
+  EXPECT_EQ(writer.remaining(), 0u);
+  return buffer;
+}
+
+TEST_F(QuicTransportServerSessionTest, SkipUnusedFields) {
+  Connect();
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  ReceiveIndication(GetTestOriginClientIndication() +
+                    MakeUnknownField("foobar"));
+  EXPECT_TRUE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, SkipLongUnusedFields) {
+  const size_t bytes =
+      ClientIndicationMaxSize() - GetTestOriginClientIndication().size() - 4;
+  Connect();
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  ReceiveIndication(GetTestOriginClientIndication() +
+                    MakeUnknownField(std::string(bytes, 'a')));
+  EXPECT_TRUE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, ClientIndicationTooLong) {
+  Connect();
+  EXPECT_CALL(
+      connection_,
+      CloseConnection(_, HasSubstr("Client indication size exceeds"), _))
+      .Times(AnyNumber());
+  ReceiveIndication(GetTestOriginClientIndication() +
+                    MakeUnknownField(std::string(65534, 'a')));
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, NoOrigin) {
+  Connect();
+  EXPECT_CALL(connection_, CloseConnection(_, HasSubstr("No origin"), _));
+  ReceiveIndication(MakeUnknownField("foobar"));
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, EmptyClientIndication) {
+  Connect();
+  EXPECT_CALL(connection_, CloseConnection(_, HasSubstr("No origin"), _));
+  ReceiveIndication("");
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, MalformedIndicationHeader) {
+  Connect();
+  EXPECT_CALL(connection_,
+              CloseConnection(_, HasSubstr("Expected 16-bit key"), _));
+  ReceiveIndication("\xff");
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, FieldTooShort) {
+  Connect();
+  EXPECT_CALL(
+      connection_,
+      CloseConnection(_, HasSubstr("Failed to read value for key 257"), _));
+  ReceiveIndication("\x01\x01\x01\x01");
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, InvalidOrigin) {
+  const std::string kEmptyOriginIndication(4, '\0');
+  Connect();
+  EXPECT_CALL(
+      connection_,
+      CloseConnection(_, HasSubstr("Unable to parse the specified origin"), _));
+  ReceiveIndication(kEmptyOriginIndication);
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, PathWithQuery) {
+  Connect();
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  ReceiveIndicationWithPath("/test?foo=bar");
+  EXPECT_TRUE(session_->IsSessionReady());
+  EXPECT_EQ(path_.path(), "/test");
+  EXPECT_EQ(path_.query(), "foo=bar");
+}
+
+TEST_F(QuicTransportServerSessionTest, PathNormalization) {
+  Connect();
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  ReceiveIndicationWithPath("/foo/../bar");
+  EXPECT_TRUE(session_->IsSessionReady());
+  EXPECT_EQ(path_.path(), "/bar");
+}
+
+TEST_F(QuicTransportServerSessionTest, EmptyPath) {
+  Connect();
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  EXPECT_CALL(connection_,
+              CloseConnection(_, HasSubstr("Path must begin with a '/'"), _));
+  ReceiveIndicationWithPath("");
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+TEST_F(QuicTransportServerSessionTest, UnprefixedPath) {
+  Connect();
+  EXPECT_CALL(visitor_, CheckOrigin(_)).WillOnce(Return(true));
+  EXPECT_CALL(connection_,
+              CloseConnection(_, HasSubstr("Path must begin with a '/'"), _));
+  ReceiveIndicationWithPath("test");
+  EXPECT_FALSE(session_->IsSessionReady());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/quic_transport/quic_transport_session_interface.h b/quiche/quic/quic_transport/quic_transport_session_interface.h
new file mode 100644
index 0000000..aad71f0
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_session_interface.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
+
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Shared interface between QuicTransportClientSession and
+// QuicTransportServerSession.
+class QUIC_EXPORT_PRIVATE QuicTransportSessionInterface {
+ public:
+  virtual ~QuicTransportSessionInterface() {}
+
+  // Indicates whether the client indication has been sent/received and the
+  // connection is thus ready to send/receive application data.  Note that the
+  // expectation for this API is that once it becomes true, it will never
+  // transition to false.
+  virtual bool IsSessionReady() const = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_SESSION_INTERFACE_H_
diff --git a/quiche/quic/quic_transport/quic_transport_stream.cc b/quiche/quic/quic_transport/quic_transport_stream.cc
new file mode 100644
index 0000000..8855b20
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_stream.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+
+#include <sys/types.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+QuicTransportStream::QuicTransportStream(
+    QuicStreamId id,
+    QuicSession* session,
+    QuicTransportSessionInterface* session_interface)
+    : QuicStream(id,
+                 session,
+                 /*is_static=*/false,
+                 QuicUtils::GetStreamType(id,
+                                          session->connection()->perspective(),
+                                          session->IsIncomingStream(id),
+                                          session->version())),
+      adapter_(session, this, sequencer()),
+      session_interface_(session_interface) {}
+
+WebTransportStream::ReadResult QuicTransportStream::Read(char* buffer,
+                                                         size_t buffer_size) {
+  if (!session_interface_->IsSessionReady()) {
+    return ReadResult{0, false};
+  }
+
+  return adapter_.Read(buffer, buffer_size);
+}
+
+WebTransportStream::ReadResult QuicTransportStream::Read(std::string* output) {
+  if (!session_interface_->IsSessionReady()) {
+    return ReadResult{0, false};
+  }
+
+  return adapter_.Read(output);
+}
+
+bool QuicTransportStream::Write(absl::string_view data) {
+  if (!CanWrite()) {
+    return false;
+  }
+
+  return adapter_.Write(data);
+}
+
+bool QuicTransportStream::SendFin() {
+  if (!CanWrite()) {
+    return false;
+  }
+
+  return adapter_.SendFin();
+}
+
+bool QuicTransportStream::CanWrite() const {
+  return session_interface_->IsSessionReady() && adapter_.CanWrite();
+}
+
+size_t QuicTransportStream::ReadableBytes() const {
+  if (!session_interface_->IsSessionReady()) {
+    return 0;
+  }
+
+  return adapter_.ReadableBytes();
+}
+
+void QuicTransportStream::OnDataAvailable() {
+  adapter_.OnDataAvailable();
+}
+
+void QuicTransportStream::OnCanWriteNewData() {
+  // Ensure the origin check has been completed, as the stream can be notified
+  // about being writable before that.
+  if (!CanWrite()) {
+    return;
+  }
+  adapter_.OnCanWriteNewData();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/quic_transport/quic_transport_stream.h b/quiche/quic/quic_transport/quic_transport_stream.h
new file mode 100644
index 0000000..aacc330
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_stream.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
+
+#include <cstddef>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/web_transport_stream_adapter.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/quic_transport/quic_transport_session_interface.h"
+
+namespace quic {
+
+// QuicTransportStream is an extension of QuicStream that provides I/O interface
+// that is safe to use in the QuicTransport context.  The interface ensures no
+// application data is processed before the client indication is processed.
+class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream,
+                                                public WebTransportStream {
+ public:
+  QuicTransportStream(QuicStreamId id,
+                      QuicSession* session,
+                      QuicTransportSessionInterface* session_interface);
+
+  // Reads at most |buffer_size| bytes into |buffer| and returns the number of
+  // bytes actually read.
+  ReadResult Read(char* buffer, size_t buffer_size) override;
+  // Reads all available data and appends it to the end of |output|.
+  ReadResult Read(std::string* output) override;
+  // Writes |data| into the stream.  Returns true on success.
+  ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
+  // Sends the FIN on the stream.  Returns true on success.
+  ABSL_MUST_USE_RESULT bool SendFin() override;
+
+  // Indicates whether it is possible to write into stream right now.
+  bool CanWrite() const override;
+  // Indicates the number of bytes that can be read from the stream.
+  size_t ReadableBytes() const override;
+
+  // QuicSession method implementations.
+  void OnDataAvailable() override;
+  void OnCanWriteNewData() override;
+
+  QuicStreamId GetStreamId() const override { return id(); }
+
+  void ResetWithUserCode(WebTransportStreamError /*error*/) override {
+    adapter_.ResetWithUserCode(0);
+  }
+  void ResetDueToInternalError() override {
+    adapter_.ResetDueToInternalError();
+  }
+  void SendStopSending(WebTransportStreamError /*error*/) override {
+    adapter_.SendStopSending(0);
+  }
+  void MaybeResetDueToStreamObjectGone() override {
+    adapter_.MaybeResetDueToStreamObjectGone();
+  }
+
+  WebTransportStreamVisitor* visitor() override { return adapter_.visitor(); }
+  void SetVisitor(std::unique_ptr<WebTransportStreamVisitor> visitor) override {
+    adapter_.SetVisitor(std::move(visitor));
+  }
+
+ protected:
+  // Hide the methods that allow writing data without checking IsSessionReady().
+  using QuicStream::WriteMemSlices;
+  using QuicStream::WriteOrBufferData;
+
+  void MaybeNotifyFinRead();
+
+  WebTransportStreamAdapter adapter_;
+  QuicTransportSessionInterface* session_interface_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QUIC_TRANSPORT_QUIC_TRANSPORT_STREAM_H_
diff --git a/quiche/quic/quic_transport/quic_transport_stream_test.cc b/quiche/quic/quic_transport/quic_transport_stream_test.cc
new file mode 100644
index 0000000..7e456ae
--- /dev/null
+++ b/quiche/quic/quic_transport/quic_transport_stream_test.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+
+#include <memory>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/frames/quic_window_update_frame.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/quic_transport/quic_transport_session_interface.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/quic_transport_test_tools.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::_;
+using testing::Return;
+
+ParsedQuicVersionVector GetVersions() {
+  return {DefaultVersionForQuicTransport()};
+}
+
+class MockQuicTransportSessionInterface : public QuicTransportSessionInterface {
+ public:
+  MOCK_METHOD(bool, IsSessionReady, (), (const, override));
+};
+
+class QuicTransportStreamTest : public QuicTest {
+ public:
+  QuicTransportStreamTest()
+      : connection_(new MockQuicConnection(&helper_,
+                                           &alarm_factory_,
+                                           Perspective::IS_CLIENT,
+                                           GetVersions())),
+        session_(connection_) {
+    QuicEnableVersion(DefaultVersionForQuicTransport());
+    session_.Initialize();
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    stream_ = new QuicTransportStream(0, &session_, &interface_);
+    session_.ActivateStream(absl::WrapUnique(stream_));
+
+    auto visitor = std::make_unique<MockStreamVisitor>();
+    visitor_ = visitor.get();
+    stream_->SetVisitor(std::move(visitor));
+  }
+
+  void ReceiveStreamData(absl::string_view data, QuicStreamOffset offset) {
+    QuicStreamFrame frame(0, false, offset, data);
+    stream_->OnStreamFrame(frame);
+  }
+
+ protected:
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnectionHelper helper_;
+
+  MockQuicConnection* connection_;  // Owned by |session_|.
+  MockQuicSession session_;
+  MockQuicTransportSessionInterface interface_;
+  QuicTransportStream* stream_;  // Owned by |session_|.
+  MockStreamVisitor* visitor_;   // Owned by |stream_|.
+};
+
+TEST_F(QuicTransportStreamTest, NotReady) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
+  ReceiveStreamData("test", 0);
+  EXPECT_EQ(stream_->ReadableBytes(), 0u);
+  EXPECT_FALSE(stream_->CanWrite());
+}
+
+TEST_F(QuicTransportStreamTest, ReadWhenNotReady) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
+  ReceiveStreamData("test", 0);
+  char buffer[4];
+  WebTransportStream::ReadResult result = stream_->Read(buffer, sizeof(buffer));
+  EXPECT_EQ(result.bytes_read, 0u);
+  EXPECT_FALSE(result.fin);
+}
+
+TEST_F(QuicTransportStreamTest, WriteWhenNotReady) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
+  EXPECT_FALSE(stream_->Write("test"));
+}
+
+TEST_F(QuicTransportStreamTest, Ready) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  ReceiveStreamData("test", 0);
+  EXPECT_EQ(stream_->ReadableBytes(), 4u);
+  EXPECT_TRUE(stream_->CanWrite());
+  EXPECT_TRUE(stream_->Write("test"));
+}
+
+TEST_F(QuicTransportStreamTest, ReceiveData) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*visitor_, OnCanRead());
+  ReceiveStreamData("test", 0);
+
+  std::string buffer;
+  WebTransportStream::ReadResult result = stream_->Read(&buffer);
+  EXPECT_EQ(result.bytes_read, 4u);
+  EXPECT_FALSE(result.fin);
+  EXPECT_EQ(buffer, "test");
+}
+
+TEST_F(QuicTransportStreamTest, FinReadWithNoDataPending) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*visitor_, OnCanRead());
+
+  QuicStreamFrame frame(0, true, 0, "");
+  stream_->OnStreamFrame(frame);
+
+  std::string buffer;
+  WebTransportStream::ReadResult result = stream_->Read(&buffer);
+  EXPECT_EQ(result.bytes_read, 0u);
+  EXPECT_TRUE(result.fin);
+  EXPECT_EQ(buffer, "");
+}
+
+TEST_F(QuicTransportStreamTest, FinReadWithDataPending) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+
+  EXPECT_CALL(*visitor_, OnCanRead());
+  QuicStreamFrame frame(0, true, 0, "test");
+  stream_->OnStreamFrame(frame);
+
+  char buffer[2];
+  WebTransportStream::ReadResult result = stream_->Read(buffer, sizeof(buffer));
+  EXPECT_EQ(result.bytes_read, 2u);
+  EXPECT_FALSE(result.fin);
+  EXPECT_EQ(buffer[0], 't');
+  EXPECT_EQ(buffer[1], 'e');
+
+  result = stream_->Read(buffer, sizeof(buffer));
+  EXPECT_EQ(result.bytes_read, 2u);
+  EXPECT_TRUE(result.fin);
+  EXPECT_EQ(buffer[0], 's');
+  EXPECT_EQ(buffer[1], 't');
+}
+
+TEST_F(QuicTransportStreamTest, WritingTooMuchData) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  ASSERT_TRUE(stream_->CanWrite());
+
+  std::string a_little_bit_of_data(128, 'A');
+  std::string a_lot_of_data(GetQuicFlag(FLAGS_quic_buffered_data_threshold) * 2,
+                            'a');
+
+  EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
+  EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
+  EXPECT_TRUE(stream_->Write(a_little_bit_of_data));
+
+  EXPECT_TRUE(stream_->Write(a_lot_of_data));
+  EXPECT_FALSE(stream_->Write(a_lot_of_data));
+}
+
+TEST_F(QuicTransportStreamTest, CannotSendFinTwice) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  ASSERT_TRUE(stream_->CanWrite());
+
+  EXPECT_CALL(session_, WritevData(stream_->id(), _, _, _, _, _))
+      .WillOnce(Return(QuicConsumedData(0, /*fin_consumed=*/true)));
+  EXPECT_TRUE(stream_->SendFin());
+  EXPECT_FALSE(stream_->CanWrite());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/bad_packet_writer.cc b/quiche/quic/test_tools/bad_packet_writer.cc
new file mode 100644
index 0000000..114e136
--- /dev/null
+++ b/quiche/quic/test_tools/bad_packet_writer.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/bad_packet_writer.h"
+
+namespace quic {
+namespace test {
+
+BadPacketWriter::BadPacketWriter(size_t packet_causing_write_error,
+                                 int error_code)
+    : packet_causing_write_error_(packet_causing_write_error),
+      error_code_(error_code) {}
+
+BadPacketWriter::~BadPacketWriter() {}
+
+WriteResult BadPacketWriter::WritePacket(const char* buffer,
+                                         size_t buf_len,
+                                         const QuicIpAddress& self_address,
+                                         const QuicSocketAddress& peer_address,
+                                         PerPacketOptions* options) {
+  if (error_code_ == 0 || packet_causing_write_error_ > 0) {
+    if (packet_causing_write_error_ > 0) {
+      --packet_causing_write_error_;
+    }
+    return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                                peer_address, options);
+  }
+  // It's time to cause write error.
+  int error_code = error_code_;
+  error_code_ = 0;
+  return WriteResult(WRITE_STATUS_ERROR, error_code);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/bad_packet_writer.h b/quiche/quic/test_tools/bad_packet_writer.h
new file mode 100644
index 0000000..7ba8383
--- /dev/null
+++ b/quiche/quic/test_tools/bad_packet_writer.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
+#define QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
+
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+
+namespace quic {
+
+namespace test {
+// This packet writer allows causing packet write error with specified error
+// code when writing a particular packet.
+class BadPacketWriter : public QuicPacketWriterWrapper {
+ public:
+  BadPacketWriter(size_t packet_causing_write_error, int error_code);
+
+  ~BadPacketWriter() override;
+
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+ private:
+  size_t packet_causing_write_error_;
+  int error_code_;
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
diff --git a/quiche/quic/test_tools/crypto_test_utils.cc b/quiche/quic/test_tools/crypto_test_utils.cc
new file mode 100644
index 0000000..9ee83ed
--- /dev/null
+++ b/quiche/quic/test_tools/crypto_test_utils.cc
@@ -0,0 +1,862 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/nid.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/channel_id.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_crypto_client_stream.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace crypto_test_utils {
+
+namespace {
+
+using testing::_;
+
+// CryptoFramerVisitor is a framer visitor that records handshake messages.
+class CryptoFramerVisitor : public CryptoFramerVisitorInterface {
+ public:
+  CryptoFramerVisitor() : error_(false) {}
+
+  void OnError(CryptoFramer* /*framer*/) override { error_ = true; }
+
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
+    messages_.push_back(message);
+  }
+
+  bool error() const { return error_; }
+
+  const std::vector<CryptoHandshakeMessage>& messages() const {
+    return messages_;
+  }
+
+ private:
+  bool error_;
+  std::vector<CryptoHandshakeMessage> messages_;
+};
+
+// HexChar parses |c| as a hex character. If valid, it sets |*value| to the
+// value of the hex character and returns true. Otherwise it returns false.
+bool HexChar(char c, uint8_t* value) {
+  if (c >= '0' && c <= '9') {
+    *value = c - '0';
+    return true;
+  }
+  if (c >= 'a' && c <= 'f') {
+    *value = c - 'a' + 10;
+    return true;
+  }
+  if (c >= 'A' && c <= 'F') {
+    *value = c - 'A' + 10;
+    return true;
+  }
+  return false;
+}
+
+}  // anonymous namespace
+
+FakeClientOptions::FakeClientOptions() {}
+
+FakeClientOptions::~FakeClientOptions() {}
+
+namespace {
+// This class is used by GenerateFullCHLO() to extract SCID and STK from
+// REJ and to construct a full CHLO with these fields and given inchoate
+// CHLO.
+class FullChloGenerator {
+ public:
+  FullChloGenerator(
+      QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
+      QuicSocketAddress client_addr, const QuicClock* clock,
+      ParsedQuicVersion version,
+      quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+          signed_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      CryptoHandshakeMessage* out)
+      : crypto_config_(crypto_config),
+        server_addr_(server_addr),
+        client_addr_(client_addr),
+        clock_(clock),
+        version_(version),
+        signed_config_(signed_config),
+        compressed_certs_cache_(compressed_certs_cache),
+        out_(out),
+        params_(new QuicCryptoNegotiatedParameters) {}
+
+  class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
+   public:
+    explicit ValidateClientHelloCallback(FullChloGenerator* generator)
+        : generator_(generator) {}
+    void Run(quiche::QuicheReferenceCountedPointer<
+                 ValidateClientHelloResultCallback::Result>
+                 result,
+             std::unique_ptr<ProofSource::Details> /* details */) override {
+      generator_->ValidateClientHelloDone(std::move(result));
+    }
+
+   private:
+    FullChloGenerator* generator_;
+  };
+
+  std::unique_ptr<ValidateClientHelloCallback>
+  GetValidateClientHelloCallback() {
+    return std::make_unique<ValidateClientHelloCallback>(this);
+  }
+
+ private:
+  void ValidateClientHelloDone(quiche::QuicheReferenceCountedPointer<
+                               ValidateClientHelloResultCallback::Result>
+                                   result) {
+    result_ = result;
+    crypto_config_->ProcessClientHello(
+        result_, /*reject_only=*/false, TestConnectionId(1), server_addr_,
+        client_addr_, version_, {version_}, clock_, QuicRandom::GetInstance(),
+        compressed_certs_cache_, params_, signed_config_,
+        /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
+        GetProcessClientHelloCallback());
+  }
+
+  class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
+   public:
+    explicit ProcessClientHelloCallback(FullChloGenerator* generator)
+        : generator_(generator) {}
+    void Run(QuicErrorCode error,
+             const std::string& error_details,
+             std::unique_ptr<CryptoHandshakeMessage> message,
+             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
+             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
+        override {
+      ASSERT_TRUE(message) << QuicErrorCodeToString(error) << " "
+                           << error_details;
+      generator_->ProcessClientHelloDone(std::move(message));
+    }
+
+   private:
+    FullChloGenerator* generator_;
+  };
+
+  std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
+    return std::make_unique<ProcessClientHelloCallback>(this);
+  }
+
+  void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> rej) {
+    // Verify output is a REJ.
+    EXPECT_THAT(rej->tag(), testing::Eq(kREJ));
+
+    QUIC_VLOG(1) << "Extract valid STK and SCID from\n" << rej->DebugString();
+    absl::string_view srct;
+    ASSERT_TRUE(rej->GetStringPiece(kSourceAddressTokenTag, &srct));
+
+    absl::string_view scfg;
+    ASSERT_TRUE(rej->GetStringPiece(kSCFG, &scfg));
+    std::unique_ptr<CryptoHandshakeMessage> server_config(
+        CryptoFramer::ParseMessage(scfg));
+
+    absl::string_view scid;
+    ASSERT_TRUE(server_config->GetStringPiece(kSCID, &scid));
+
+    *out_ = result_->client_hello;
+    out_->SetStringPiece(kSCID, scid);
+    out_->SetStringPiece(kSourceAddressTokenTag, srct);
+    uint64_t xlct = LeafCertHashForTesting();
+    out_->SetValue(kXLCT, xlct);
+  }
+
+ protected:
+  QuicCryptoServerConfig* crypto_config_;
+  QuicSocketAddress server_addr_;
+  QuicSocketAddress client_addr_;
+  const QuicClock* clock_;
+  ParsedQuicVersion version_;
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+  QuicCompressedCertsCache* compressed_certs_cache_;
+  CryptoHandshakeMessage* out_;
+
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result_;
+};
+
+}  // namespace
+
+std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting() {
+  return std::make_unique<QuicCryptoServerConfig>(
+      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+      ProofSourceForTesting(), KeyExchangeSource::Default());
+}
+
+int HandshakeWithFakeServer(QuicConfig* server_quic_config,
+                            QuicCryptoServerConfig* crypto_config,
+                            MockQuicConnectionHelper* helper,
+                            MockAlarmFactory* alarm_factory,
+                            PacketSavingConnection* client_conn,
+                            QuicCryptoClientStreamBase* client,
+                            std::string alpn) {
+  auto* server_conn = new testing::NiceMock<PacketSavingConnection>(
+      helper, alarm_factory, Perspective::IS_SERVER,
+      ParsedVersionOfIndex(client_conn->supported_versions(), 0));
+
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+  SetupCryptoServerConfigForTest(
+      server_conn->clock(), server_conn->random_generator(), crypto_config);
+
+  TestQuicSpdyServerSession server_session(
+      server_conn, *server_quic_config, client_conn->supported_versions(),
+      crypto_config, &compressed_certs_cache);
+  // Call SetServerApplicationStateForResumption so that the fake server
+  // supports 0-RTT in TLS.
+  server_session.Initialize();
+  server_session.GetMutableCryptoStream()
+      ->SetServerApplicationStateForResumption(
+          std::make_unique<ApplicationState>());
+  EXPECT_CALL(*server_session.helper(),
+              CanAcceptClientHello(testing::_, testing::_, testing::_,
+                                   testing::_, testing::_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(*server_conn, OnCanWrite()).Times(testing::AnyNumber());
+  EXPECT_CALL(*client_conn, OnCanWrite()).Times(testing::AnyNumber());
+  EXPECT_CALL(*server_conn, SendCryptoData(_, _, _))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(server_session, SelectAlpn(_))
+      .WillRepeatedly([alpn](const std::vector<absl::string_view>& alpns) {
+        return std::find(alpns.cbegin(), alpns.cend(), alpn);
+      });
+
+  // The client's handshake must have been started already.
+  QUICHE_CHECK_NE(0u, client_conn->encrypted_packets_.size());
+
+  CommunicateHandshakeMessages(client_conn, client, server_conn,
+                               server_session.GetMutableCryptoStream());
+  if (client_conn->connected() && server_conn->connected()) {
+    CompareClientAndServerKeys(client, server_session.GetMutableCryptoStream());
+  }
+
+  return client->num_sent_client_hellos();
+}
+
+int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
+                            MockAlarmFactory* alarm_factory,
+                            PacketSavingConnection* server_conn,
+                            QuicCryptoServerStreamBase* server,
+                            const QuicServerId& server_id,
+                            const FakeClientOptions& options,
+                            std::string alpn) {
+  // This function does not do version negotiation; read the supported versions
+  // directly from the server connection instead.
+  ParsedQuicVersionVector supported_versions =
+      server_conn->supported_versions();
+  if (options.only_tls_versions) {
+    supported_versions.erase(
+        std::remove_if(supported_versions.begin(), supported_versions.end(),
+                       [](const ParsedQuicVersion& version) {
+                         return version.handshake_protocol != PROTOCOL_TLS1_3;
+                       }),
+        supported_versions.end());
+    QUICHE_CHECK(!options.only_quic_crypto_versions);
+  } else if (options.only_quic_crypto_versions) {
+    supported_versions.erase(
+        std::remove_if(supported_versions.begin(), supported_versions.end(),
+                       [](const ParsedQuicVersion& version) {
+                         return version.handshake_protocol !=
+                                PROTOCOL_QUIC_CRYPTO;
+                       }),
+        supported_versions.end());
+  }
+  PacketSavingConnection* client_conn = new PacketSavingConnection(
+      helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
+  // Advance the time, because timers do not like uninitialized times.
+  client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+
+  QuicCryptoClientConfig crypto_config(ProofVerifierForTesting());
+  TestQuicSpdyClientSession client_session(client_conn, DefaultQuicConfig(),
+                                           supported_versions, server_id,
+                                           &crypto_config);
+
+  EXPECT_CALL(client_session, OnProofValid(testing::_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(client_session, OnProofVerifyDetailsAvailable(testing::_))
+      .Times(testing::AnyNumber());
+  EXPECT_CALL(*client_conn, OnCanWrite()).Times(testing::AnyNumber());
+  if (!alpn.empty()) {
+    EXPECT_CALL(client_session, GetAlpnsToOffer())
+        .WillRepeatedly(testing::Return(std::vector<std::string>({alpn})));
+  } else {
+    EXPECT_CALL(client_session, GetAlpnsToOffer())
+        .WillRepeatedly(testing::Return(std::vector<std::string>(
+            {AlpnForVersion(client_conn->version())})));
+  }
+  client_session.GetMutableCryptoStream()->CryptoConnect();
+  QUICHE_CHECK_EQ(1u, client_conn->encrypted_packets_.size());
+
+  CommunicateHandshakeMessages(client_conn,
+                               client_session.GetMutableCryptoStream(),
+                               server_conn, server);
+
+  if (server->one_rtt_keys_available() && server->encryption_established()) {
+    CompareClientAndServerKeys(client_session.GetMutableCryptoStream(), server);
+  }
+
+  return client_session.GetCryptoStream()->num_sent_client_hellos();
+}
+
+void SetupCryptoServerConfigForTest(const QuicClock* clock,
+                                    QuicRandom* rand,
+                                    QuicCryptoServerConfig* crypto_config) {
+  QuicCryptoServerConfig::ConfigOptions options;
+  options.channel_id_enabled = true;
+  std::unique_ptr<CryptoHandshakeMessage> scfg =
+      crypto_config->AddDefaultConfig(rand, clock, options);
+}
+
+void SendHandshakeMessageToStream(QuicCryptoStream* stream,
+                                  const CryptoHandshakeMessage& message,
+                                  Perspective /*perspective*/) {
+  const QuicData& data = message.GetSerialized();
+  QuicSession* session = QuicStreamPeer::session(stream);
+  if (!QuicVersionUsesCryptoFrames(session->transport_version())) {
+    QuicStreamFrame frame(
+        QuicUtils::GetCryptoStreamId(session->transport_version()), false,
+        stream->crypto_bytes_read(), data.AsStringPiece());
+    stream->OnStreamFrame(frame);
+  } else {
+    EncryptionLevel level = session->connection()->last_decrypted_level();
+    QuicCryptoFrame frame(level, stream->BytesReadOnLevel(level),
+                          data.AsStringPiece());
+    stream->OnCryptoFrame(frame);
+  }
+}
+
+void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
+                                  QuicCryptoStream* client,
+                                  PacketSavingConnection* server_conn,
+                                  QuicCryptoStream* server) {
+  size_t client_i = 0, server_i = 0;
+  while (client_conn->connected() && server_conn->connected() &&
+         (!client->one_rtt_keys_available() ||
+          !server->one_rtt_keys_available())) {
+    ASSERT_GT(client_conn->encrypted_packets_.size(), client_i);
+    QUIC_LOG(INFO) << "Processing "
+                   << client_conn->encrypted_packets_.size() - client_i
+                   << " packets client->server";
+    MovePackets(client_conn, &client_i, server, server_conn,
+                Perspective::IS_SERVER);
+
+    if (client->one_rtt_keys_available() && server->one_rtt_keys_available() &&
+        server_conn->encrypted_packets_.size() == server_i) {
+      break;
+    }
+    ASSERT_GT(server_conn->encrypted_packets_.size(), server_i);
+    QUIC_LOG(INFO) << "Processing "
+                   << server_conn->encrypted_packets_.size() - server_i
+                   << " packets server->client";
+    MovePackets(server_conn, &server_i, client, client_conn,
+                Perspective::IS_CLIENT);
+  }
+}
+
+bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
+                                       QuicCryptoStream* client,
+                                       std::function<bool()> client_condition,
+                                       PacketSavingConnection* server_conn,
+                                       QuicCryptoStream* server,
+                                       std::function<bool()> server_condition) {
+  size_t client_next_packet_to_deliver =
+      client_conn->number_of_packets_delivered_;
+  size_t server_next_packet_to_deliver =
+      server_conn->number_of_packets_delivered_;
+  while (
+      client_conn->connected() && server_conn->connected() &&
+      (!client_condition() || !server_condition()) &&
+      (client_conn->encrypted_packets_.size() > client_next_packet_to_deliver ||
+       server_conn->encrypted_packets_.size() >
+           server_next_packet_to_deliver)) {
+    if (!server_condition()) {
+      QUIC_LOG(INFO) << "Processing "
+                     << client_conn->encrypted_packets_.size() -
+                            client_next_packet_to_deliver
+                     << " packets client->server";
+      MovePackets(client_conn, &client_next_packet_to_deliver, server,
+                  server_conn, Perspective::IS_SERVER);
+    }
+    if (!client_condition()) {
+      QUIC_LOG(INFO) << "Processing "
+                     << server_conn->encrypted_packets_.size() -
+                            server_next_packet_to_deliver
+                     << " packets server->client";
+      MovePackets(server_conn, &server_next_packet_to_deliver, client,
+                  client_conn, Perspective::IS_CLIENT);
+    }
+  }
+  client_conn->number_of_packets_delivered_ = client_next_packet_to_deliver;
+  server_conn->number_of_packets_delivered_ = server_next_packet_to_deliver;
+  bool result = client_condition() && server_condition();
+  if (!result) {
+    QUIC_LOG(INFO) << "CommunicateHandshakeMessagesUnti failed with state: "
+                      "client connected? "
+                   << client_conn->connected() << " server connected? "
+                   << server_conn->connected() << " client condition met? "
+                   << client_condition() << " server condition met? "
+                   << server_condition();
+  }
+  return result;
+}
+
+std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
+                                           QuicCryptoStream* client,
+                                           size_t client_i,
+                                           PacketSavingConnection* server_conn,
+                                           QuicCryptoStream* server,
+                                           size_t server_i) {
+  if (client_conn->encrypted_packets_.size() != client_i) {
+    QUIC_LOG(INFO) << "Processing "
+                   << client_conn->encrypted_packets_.size() - client_i
+                   << " packets client->server";
+    MovePackets(client_conn, &client_i, server, server_conn,
+                Perspective::IS_SERVER);
+  }
+
+  if (server_conn->encrypted_packets_.size() != server_i) {
+    QUIC_LOG(INFO) << "Processing "
+                   << server_conn->encrypted_packets_.size() - server_i
+                   << " packets server->client";
+    MovePackets(server_conn, &server_i, client, client_conn,
+                Perspective::IS_CLIENT);
+  }
+
+  return std::make_pair(client_i, server_i);
+}
+
+std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag) {
+  auto it = message.tag_value_map().find(tag);
+  if (it == message.tag_value_map().end()) {
+    return std::string();
+  }
+  return it->second;
+}
+
+uint64_t LeafCertHashForTesting() {
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain;
+  QuicSocketAddress server_address(QuicIpAddress::Any4(), 42);
+  QuicSocketAddress client_address(QuicIpAddress::Any4(), 43);
+  QuicCryptoProof proof;
+  std::unique_ptr<ProofSource> proof_source(ProofSourceForTesting());
+
+  class Callback : public ProofSource::Callback {
+   public:
+    Callback(bool* ok,
+             quiche::QuicheReferenceCountedPointer<ProofSource::Chain>* chain)
+        : ok_(ok), chain_(chain) {}
+
+    void Run(
+        bool ok,
+        const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+        const QuicCryptoProof& /* proof */,
+        std::unique_ptr<ProofSource::Details> /* details */) override {
+      *ok_ = ok;
+      *chain_ = chain;
+    }
+
+   private:
+    bool* ok_;
+    quiche::QuicheReferenceCountedPointer<ProofSource::Chain>* chain_;
+  };
+
+  // Note: relies on the callback being invoked synchronously
+  bool ok = false;
+  proof_source->GetProof(
+      server_address, client_address, "", "",
+      AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
+      std::unique_ptr<ProofSource::Callback>(new Callback(&ok, &chain)));
+  if (!ok || chain->certs.empty()) {
+    QUICHE_DCHECK(false) << "Proof generation failed";
+    return 0;
+  }
+
+  return QuicUtils::FNV1a_64_Hash(chain->certs.at(0));
+}
+
+void FillInDummyReject(CryptoHandshakeMessage* rej) {
+  rej->set_tag(kREJ);
+
+  // Minimum SCFG that passes config validation checks.
+  // clang-format off
+  unsigned char scfg[] = {
+    // SCFG
+    0x53, 0x43, 0x46, 0x47,
+    // num entries
+    0x01, 0x00,
+    // padding
+    0x00, 0x00,
+    // EXPY
+    0x45, 0x58, 0x50, 0x59,
+    // EXPY end offset
+    0x08, 0x00, 0x00, 0x00,
+    // Value
+    '1',  '2',  '3',  '4',
+    '5',  '6',  '7',  '8'
+  };
+  // clang-format on
+  rej->SetValue(kSCFG, scfg);
+  rej->SetStringPiece(kServerNonceTag, "SERVER_NONCE");
+  int64_t ttl = 2 * 24 * 60 * 60;
+  rej->SetValue(kSTTL, ttl);
+  std::vector<QuicTag> reject_reasons;
+  reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
+  rej->SetVector(kRREJ, reject_reasons);
+}
+
+namespace {
+
+#define RETURN_STRING_LITERAL(x) \
+  case x:                        \
+    return #x
+
+std::string EncryptionLevelString(EncryptionLevel level) {
+  switch (level) {
+    RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
+    RETURN_STRING_LITERAL(ENCRYPTION_HANDSHAKE);
+    RETURN_STRING_LITERAL(ENCRYPTION_ZERO_RTT);
+    RETURN_STRING_LITERAL(ENCRYPTION_FORWARD_SECURE);
+    default:
+      return "";
+  }
+}
+
+void CompareCrypters(const QuicEncrypter* encrypter,
+                     const QuicDecrypter* decrypter,
+                     std::string label) {
+  if (encrypter == nullptr || decrypter == nullptr) {
+    ADD_FAILURE() << "Expected non-null crypters; have " << encrypter << " and "
+                  << decrypter << " for " << label;
+    return;
+  }
+  absl::string_view encrypter_key = encrypter->GetKey();
+  absl::string_view encrypter_iv = encrypter->GetNoncePrefix();
+  absl::string_view decrypter_key = decrypter->GetKey();
+  absl::string_view decrypter_iv = decrypter->GetNoncePrefix();
+  quiche::test::CompareCharArraysWithHexError(
+      label + " key", encrypter_key.data(), encrypter_key.length(),
+      decrypter_key.data(), decrypter_key.length());
+  quiche::test::CompareCharArraysWithHexError(
+      label + " iv", encrypter_iv.data(), encrypter_iv.length(),
+      decrypter_iv.data(), decrypter_iv.length());
+}
+
+}  // namespace
+
+void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
+                                QuicCryptoServerStreamBase* server) {
+  QuicFramer* client_framer = QuicConnectionPeer::GetFramer(
+      QuicStreamPeer::session(client)->connection());
+  QuicFramer* server_framer = QuicConnectionPeer::GetFramer(
+      QuicStreamPeer::session(server)->connection());
+  for (EncryptionLevel level :
+       {ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
+    SCOPED_TRACE(EncryptionLevelString(level));
+    const QuicEncrypter* client_encrypter(
+        QuicFramerPeer::GetEncrypter(client_framer, level));
+    const QuicDecrypter* server_decrypter(
+        QuicFramerPeer::GetDecrypter(server_framer, level));
+    if (level == ENCRYPTION_FORWARD_SECURE ||
+        !((level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
+           client_encrypter == nullptr) &&
+          (level == ENCRYPTION_ZERO_RTT || server_decrypter == nullptr))) {
+      CompareCrypters(client_encrypter, server_decrypter,
+                      "client " + EncryptionLevelString(level) + " write");
+    }
+    const QuicEncrypter* server_encrypter(
+        QuicFramerPeer::GetEncrypter(server_framer, level));
+    const QuicDecrypter* client_decrypter(
+        QuicFramerPeer::GetDecrypter(client_framer, level));
+    if (level == ENCRYPTION_FORWARD_SECURE ||
+        !(server_encrypter == nullptr &&
+          (level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
+           client_decrypter == nullptr))) {
+      CompareCrypters(server_encrypter, client_decrypter,
+                      "server " + EncryptionLevelString(level) + " write");
+    }
+  }
+
+  absl::string_view client_subkey_secret =
+      client->crypto_negotiated_params().subkey_secret;
+  absl::string_view server_subkey_secret =
+      server->crypto_negotiated_params().subkey_secret;
+  quiche::test::CompareCharArraysWithHexError(
+      "subkey secret", client_subkey_secret.data(),
+      client_subkey_secret.length(), server_subkey_secret.data(),
+      server_subkey_secret.length());
+}
+
+QuicTag ParseTag(const char* tagstr) {
+  const size_t len = strlen(tagstr);
+  QUICHE_CHECK_NE(0u, len);
+
+  QuicTag tag = 0;
+
+  if (tagstr[0] == '#') {
+    QUICHE_CHECK_EQ(static_cast<size_t>(1 + 2 * 4), len);
+    tagstr++;
+
+    for (size_t i = 0; i < 8; i++) {
+      tag <<= 4;
+
+      uint8_t v = 0;
+      QUICHE_CHECK(HexChar(tagstr[i], &v));
+      tag |= v;
+    }
+
+    return tag;
+  }
+
+  QUICHE_CHECK_LE(len, 4u);
+  for (size_t i = 0; i < 4; i++) {
+    tag >>= 8;
+    if (i < len) {
+      tag |= static_cast<uint32_t>(tagstr[i]) << 24;
+    }
+  }
+
+  return tag;
+}
+
+CryptoHandshakeMessage CreateCHLO(
+    std::vector<std::pair<std::string, std::string>> tags_and_values) {
+  return CreateCHLO(tags_and_values, -1);
+}
+
+CryptoHandshakeMessage CreateCHLO(
+    std::vector<std::pair<std::string, std::string>> tags_and_values,
+    int minimum_size_bytes) {
+  CryptoHandshakeMessage msg;
+  msg.set_tag(MakeQuicTag('C', 'H', 'L', 'O'));
+
+  if (minimum_size_bytes > 0) {
+    msg.set_minimum_size(minimum_size_bytes);
+  }
+
+  for (const auto& tag_and_value : tags_and_values) {
+    const std::string& tag = tag_and_value.first;
+    const std::string& value = tag_and_value.second;
+
+    const QuicTag quic_tag = ParseTag(tag.c_str());
+
+    size_t value_len = value.length();
+    if (value_len > 0 && value[0] == '#') {
+      // This is ascii encoded hex.
+      std::string hex_value =
+          absl::HexStringToBytes(absl::string_view(&value[1]));
+      msg.SetStringPiece(quic_tag, hex_value);
+      continue;
+    }
+    msg.SetStringPiece(quic_tag, value);
+  }
+
+  // The CryptoHandshakeMessage needs to be serialized and parsed to ensure
+  // that any padding is included.
+  std::unique_ptr<QuicData> bytes =
+      CryptoFramer::ConstructHandshakeMessage(msg);
+  std::unique_ptr<CryptoHandshakeMessage> parsed(
+      CryptoFramer::ParseMessage(bytes->AsStringPiece()));
+  QUICHE_CHECK(parsed);
+
+  return *parsed;
+}
+
+void MovePackets(PacketSavingConnection* source_conn,
+                 size_t* inout_packet_index,
+                 QuicCryptoStream* dest_stream,
+                 PacketSavingConnection* dest_conn,
+                 Perspective dest_perspective) {
+  SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(framer.framer(),
+                                                      TestConnectionId());
+
+  SimpleQuicFramer null_encryption_framer(source_conn->supported_versions(),
+                                          dest_perspective);
+  QuicFramerPeer::SetLastSerializedServerConnectionId(
+      null_encryption_framer.framer(), TestConnectionId());
+
+  size_t index = *inout_packet_index;
+  for (; index < source_conn->encrypted_packets_.size(); index++) {
+    if (!dest_conn->connected()) {
+      QUIC_LOG(INFO)
+          << "Destination connection disconnected. Skipping packet at index "
+          << index;
+      continue;
+    }
+    // In order to properly test the code we need to perform encryption and
+    // decryption so that the crypters latch when expected. The crypters are in
+    // |dest_conn|, but we don't want to try and use them there. Instead we swap
+    // them into |framer|, perform the decryption with them, and then swap ther
+    // back.
+    QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+    QuicConnectionPeer::AddBytesReceived(
+        dest_conn, source_conn->encrypted_packets_[index]->length());
+    if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
+      // The framer will be unable to decrypt zero-rtt packets sent during
+      // handshake or forward-secure packets sent after the handshake is
+      // complete. Don't treat them as handshake packets.
+      QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+      continue;
+    }
+    QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+
+    // Install a packet flusher such that the packets generated by |dest_conn|
+    // in response to this packet are more likely to be coalesced and/or batched
+    // in the writer.
+    QuicConnection::ScopedPacketFlusher flusher(dest_conn);
+
+    dest_conn->OnDecryptedPacket(
+        source_conn->encrypted_packets_[index]->length(),
+        framer.last_decrypted_level());
+
+    if (dest_stream->handshake_protocol() == PROTOCOL_TLS1_3) {
+      // Try to process the packet with a framer that only has the NullDecrypter
+      // for decryption. If ProcessPacket succeeds, that means the packet was
+      // encrypted with the NullEncrypter. With the TLS handshaker in use, no
+      // packets should ever be encrypted with the NullEncrypter, instead
+      // they're encrypted with an obfuscation cipher based on QUIC version and
+      // connection ID.
+      QUIC_LOG(INFO) << "Attempting to decrypt with NullDecrypter: "
+                        "expect a decryption failure on the next log line.";
+      ASSERT_FALSE(null_encryption_framer.ProcessPacket(
+          *source_conn->encrypted_packets_[index]))
+          << "No TLS packets should be encrypted with the NullEncrypter";
+    }
+
+    // Since we're using QuicFramers separate from the connections to move
+    // packets, the QuicConnection never gets notified about what level the last
+    // packet was decrypted at. This is needed by TLS to know what encryption
+    // level was used for the data it's receiving, so we plumb this information
+    // from the SimpleQuicFramer back into the connection.
+    dest_conn->OnDecryptedPacket(
+        source_conn->encrypted_packets_[index]->length(),
+        framer.last_decrypted_level());
+
+    QuicConnectionPeer::SetCurrentPacket(
+        dest_conn, source_conn->encrypted_packets_[index]->AsStringPiece());
+    for (const auto& stream_frame : framer.stream_frames()) {
+      // Ignore stream frames that are sent on other streams in the crypto
+      // event.
+      if (stream_frame->stream_id == dest_stream->id()) {
+        dest_stream->OnStreamFrame(*stream_frame);
+      }
+    }
+    for (const auto& crypto_frame : framer.crypto_frames()) {
+      dest_stream->OnCryptoFrame(*crypto_frame);
+    }
+    if (!framer.connection_close_frames().empty() && dest_conn->connected()) {
+      dest_conn->OnConnectionCloseFrame(framer.connection_close_frames()[0]);
+    }
+  }
+  *inout_packet_index = index;
+
+  QuicConnectionPeer::SetCurrentPacket(dest_conn,
+                                       absl::string_view(nullptr, 0));
+}
+
+CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
+    const QuicClock* clock,
+    QuicTransportVersion version,
+    QuicCryptoServerConfig* crypto_config) {
+  // clang-format off
+  return CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"PUBS", GenerateClientPublicValuesHex().c_str()},
+       {"NONC", GenerateClientNonceHex(clock, crypto_config).c_str()},
+       {"VER\0", QuicVersionLabelToString(
+           CreateQuicVersionLabel(
+            ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version))).c_str()}},
+      kClientHelloMinimumSize);
+  // clang-format on
+}
+
+std::string GenerateClientNonceHex(const QuicClock* clock,
+                                   QuicCryptoServerConfig* crypto_config) {
+  QuicCryptoServerConfig::ConfigOptions old_config_options;
+  QuicCryptoServerConfig::ConfigOptions new_config_options;
+  old_config_options.id = "old-config-id";
+  crypto_config->AddDefaultConfig(QuicRandom::GetInstance(), clock,
+                                  old_config_options);
+  QuicServerConfigProtobuf primary_config = crypto_config->GenerateConfig(
+      QuicRandom::GetInstance(), clock, new_config_options);
+  primary_config.set_primary_time(clock->WallNow().ToUNIXSeconds());
+  std::unique_ptr<CryptoHandshakeMessage> msg =
+      crypto_config->AddConfig(primary_config, clock->WallNow());
+  absl::string_view orbit;
+  QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
+  std::string nonce;
+  CryptoUtils::GenerateNonce(clock->WallNow(), QuicRandom::GetInstance(), orbit,
+                             &nonce);
+  return ("#" + absl::BytesToHexString(nonce));
+}
+
+std::string GenerateClientPublicValuesHex() {
+  char public_value[32];
+  memset(public_value, 42, sizeof(public_value));
+  return ("#" + absl::BytesToHexString(
+                    absl::string_view(public_value, sizeof(public_value))));
+}
+
+void GenerateFullCHLO(
+    const CryptoHandshakeMessage& inchoate_chlo,
+    QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
+    QuicSocketAddress client_addr, QuicTransportVersion transport_version,
+    const QuicClock* clock,
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    CryptoHandshakeMessage* out) {
+  // Pass a inchoate CHLO.
+  FullChloGenerator generator(
+      crypto_config, server_addr, client_addr, clock,
+      ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version), signed_config,
+      compressed_certs_cache, out);
+  crypto_config->ValidateClientHello(
+      inchoate_chlo, client_addr, server_addr, transport_version, clock,
+      signed_config, generator.GetValidateClientHelloCallback());
+}
+
+}  // namespace crypto_test_utils
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/crypto_test_utils.h b/quiche/quic/test_tools/crypto_test_utils.h
new file mode 100644
index 0000000..b54d447
--- /dev/null
+++ b/quiche/quic/test_tools/crypto_test_utils.h
@@ -0,0 +1,218 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
+#define QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
+
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+class ProofSource;
+class ProofVerifier;
+class ProofVerifyContext;
+class QuicClock;
+class QuicConfig;
+class QuicCryptoClientStream;
+class QuicCryptoServerConfig;
+class QuicCryptoServerStreamBase;
+class QuicCryptoStream;
+class QuicRandom;
+class QuicServerId;
+
+namespace test {
+
+class PacketSavingConnection;
+
+namespace crypto_test_utils {
+
+// An interface for a source of callbacks. This is used for invoking
+// callbacks asynchronously.
+//
+// Call the RunPendingCallbacks method regularly to run the callbacks from
+// this source.
+class CallbackSource {
+ public:
+  virtual ~CallbackSource() {}
+
+  // Runs pending callbacks from this source. If there is no pending
+  // callback, does nothing.
+  virtual void RunPendingCallbacks() = 0;
+};
+
+// FakeClientOptions bundles together a number of options for configuring
+// HandshakeWithFakeClient.
+struct FakeClientOptions {
+  FakeClientOptions();
+  ~FakeClientOptions();
+
+  // If only_tls_versions is set, then the client will only use TLS for the
+  // crypto handshake.
+  bool only_tls_versions = false;
+
+  // If only_quic_crypto_versions is set, then the client will only use
+  // PROTOCOL_QUIC_CRYPTO for the crypto handshake.
+  bool only_quic_crypto_versions = false;
+};
+
+// Returns a QuicCryptoServerConfig that is in a reasonable configuration to
+// pass into HandshakeWithFakeServer.
+std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting();
+
+// returns: the number of client hellos that the client sent.
+int HandshakeWithFakeServer(QuicConfig* server_quic_config,
+                            QuicCryptoServerConfig* crypto_config,
+                            MockQuicConnectionHelper* helper,
+                            MockAlarmFactory* alarm_factory,
+                            PacketSavingConnection* client_conn,
+                            QuicCryptoClientStreamBase* client,
+                            std::string alpn);
+
+// returns: the number of client hellos that the client sent.
+int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
+                            MockAlarmFactory* alarm_factory,
+                            PacketSavingConnection* server_conn,
+                            QuicCryptoServerStreamBase* server,
+                            const QuicServerId& server_id,
+                            const FakeClientOptions& options,
+                            std::string alpn);
+
+// SetupCryptoServerConfigForTest configures |crypto_config|
+// with sensible defaults for testing.
+void SetupCryptoServerConfigForTest(const QuicClock* clock,
+                                    QuicRandom* rand,
+                                    QuicCryptoServerConfig* crypto_config);
+
+// Sends the handshake message |message| to stream |stream| with the perspective
+// that the message is coming from |perspective|.
+void SendHandshakeMessageToStream(QuicCryptoStream* stream,
+                                  const CryptoHandshakeMessage& message,
+                                  Perspective perspective);
+
+// CommunicateHandshakeMessages moves messages from |client| to |server| and
+// back until |clients|'s handshake has completed.
+void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
+                                  QuicCryptoStream* client,
+                                  PacketSavingConnection* server_conn,
+                                  QuicCryptoStream* server);
+
+// CommunicateHandshakeMessagesUntil:
+// 1) Moves messages from |client| to |server| until |server_condition| is met.
+// 2) Moves messages from |server| to |client| until |client_condition| is met.
+// 3) Returns true if both conditions are met.
+// 4) Returns false if either connection is closed or there is no more packet to
+// deliver before both conditions are met.
+bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
+                                       QuicCryptoStream* client,
+                                       std::function<bool()> client_condition,
+                                       PacketSavingConnection* server_conn,
+                                       QuicCryptoStream* server,
+                                       std::function<bool()> server_condition);
+
+// AdvanceHandshake attempts to moves messages from |client| to |server| and
+// |server| to |client|. Returns the number of messages moved.
+std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
+                                           QuicCryptoStream* client,
+                                           size_t client_i,
+                                           PacketSavingConnection* server_conn,
+                                           QuicCryptoStream* server,
+                                           size_t server_i);
+
+// Returns the value for the tag |tag| in the tag value map of |message|.
+std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag);
+
+// Returns a new |ProofSource| that serves up test certificates.
+std::unique_ptr<ProofSource> ProofSourceForTesting();
+
+// Returns a new |ProofVerifier| that uses the QUIC testing root CA.
+std::unique_ptr<ProofVerifier> ProofVerifierForTesting();
+
+// Returns a hash of the leaf test certificate.
+uint64_t LeafCertHashForTesting();
+
+// Returns a |ProofVerifyContext| that must be used with the verifier
+// returned by |ProofVerifierForTesting|.
+std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting();
+
+// Creates a minimal dummy reject message that will pass the client-config
+// validation tests. This will include a server config, but no certs, proof
+// source address token, or server nonce.
+void FillInDummyReject(CryptoHandshakeMessage* rej);
+
+// ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be
+// in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex
+// format). It QUICHE_CHECK fails if there's a parse error.
+QuicTag ParseTag(const char* tagstr);
+
+// Message constructs a CHLO message from a provided vector of tag/value pairs.
+// The first of each pair is the tag of a tag/value and is given as an argument
+// to |ParseTag|. The second is the value of the tag/value pair and is either a
+// hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is
+// provided then the message will be padded to this minimum size.
+//
+//   CreateCHLO(
+//       {{"NOCE", "#11223344"},
+//        {"SNI", "www.example.com"}},
+//       optional_minimum_size_bytes);
+CryptoHandshakeMessage CreateCHLO(
+    std::vector<std::pair<std::string, std::string>> tags_and_values);
+CryptoHandshakeMessage CreateCHLO(
+    std::vector<std::pair<std::string, std::string>> tags_and_values,
+    int minimum_size_bytes);
+
+// MovePackets parses crypto handshake messages from packet number
+// |*inout_packet_index| through to the last packet (or until a packet fails
+// to decrypt) and has |dest_stream| process them. |*inout_packet_index| is
+// updated with an index one greater than the last packet processed.
+void MovePackets(PacketSavingConnection* source_conn,
+                 size_t* inout_packet_index,
+                 QuicCryptoStream* dest_stream,
+                 PacketSavingConnection* dest_conn,
+                 Perspective dest_perspective);
+
+// Return an inchoate CHLO with some basic tag value pairs.
+CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
+    const QuicClock* clock,
+    QuicTransportVersion version,
+    QuicCryptoServerConfig* crypto_config);
+
+// Takes a inchoate CHLO, returns a full CHLO in |out| which can pass
+// |crypto_config|'s validation.
+void GenerateFullCHLO(
+    const CryptoHandshakeMessage& inchoate_chlo,
+    QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
+    QuicSocketAddress client_addr, QuicTransportVersion transport_version,
+    const QuicClock* clock,
+    quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    CryptoHandshakeMessage* out);
+
+void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
+                                QuicCryptoServerStreamBase* server);
+
+// Return a CHLO nonce in hexadecimal.
+std::string GenerateClientNonceHex(const QuicClock* clock,
+                                   QuicCryptoServerConfig* crypto_config);
+
+// Return a CHLO PUBS in hexadecimal.
+std::string GenerateClientPublicValuesHex();
+
+}  // namespace crypto_test_utils
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
diff --git a/quiche/quic/test_tools/crypto_test_utils_test.cc b/quiche/quic/test_tools/crypto_test_utils_test.cc
new file mode 100644
index 0000000..200f5be
--- /dev/null
+++ b/quiche/quic/test_tools/crypto_test_utils_test.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+#include <utility>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/proto/crypto_server_config_proto.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class ShloVerifier {
+ public:
+  ShloVerifier(QuicCryptoServerConfig* crypto_config,
+               QuicSocketAddress server_addr, QuicSocketAddress client_addr,
+               const QuicClock* clock,
+               quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
+                   signed_config,
+               QuicCompressedCertsCache* compressed_certs_cache,
+               ParsedQuicVersion version)
+      : crypto_config_(crypto_config),
+        server_addr_(server_addr),
+        client_addr_(client_addr),
+        clock_(clock),
+        signed_config_(signed_config),
+        compressed_certs_cache_(compressed_certs_cache),
+        params_(new QuicCryptoNegotiatedParameters),
+        version_(version) {}
+
+  class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
+   public:
+    explicit ValidateClientHelloCallback(ShloVerifier* shlo_verifier)
+        : shlo_verifier_(shlo_verifier) {}
+    void Run(quiche::QuicheReferenceCountedPointer<
+                 ValidateClientHelloResultCallback::Result>
+                 result,
+             std::unique_ptr<ProofSource::Details> /* details */) override {
+      shlo_verifier_->ValidateClientHelloDone(result);
+    }
+
+   private:
+    ShloVerifier* shlo_verifier_;
+  };
+
+  std::unique_ptr<ValidateClientHelloCallback>
+  GetValidateClientHelloCallback() {
+    return std::make_unique<ValidateClientHelloCallback>(this);
+  }
+
+ private:
+  void ValidateClientHelloDone(
+      const quiche::QuicheReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>& result) {
+    result_ = result;
+    crypto_config_->ProcessClientHello(
+        result_, /*reject_only=*/false,
+        /*connection_id=*/TestConnectionId(1), server_addr_, client_addr_,
+        version_, AllSupportedVersions(), clock_, QuicRandom::GetInstance(),
+        compressed_certs_cache_, params_, signed_config_,
+        /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
+        GetProcessClientHelloCallback());
+  }
+
+  class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
+   public:
+    explicit ProcessClientHelloCallback(ShloVerifier* shlo_verifier)
+        : shlo_verifier_(shlo_verifier) {}
+    void Run(QuicErrorCode /*error*/,
+             const std::string& /*error_details*/,
+             std::unique_ptr<CryptoHandshakeMessage> message,
+             std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
+             std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
+        override {
+      shlo_verifier_->ProcessClientHelloDone(std::move(message));
+    }
+
+   private:
+    ShloVerifier* shlo_verifier_;
+  };
+
+  std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
+    return std::make_unique<ProcessClientHelloCallback>(this);
+  }
+
+  void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> message) {
+    // Verify output is a SHLO.
+    EXPECT_EQ(message->tag(), kSHLO)
+        << "Fail to pass validation. Get " << message->DebugString();
+  }
+
+  QuicCryptoServerConfig* crypto_config_;
+  QuicSocketAddress server_addr_;
+  QuicSocketAddress client_addr_;
+  const QuicClock* clock_;
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  quiche::QuicheReferenceCountedPointer<
+      ValidateClientHelloResultCallback::Result>
+      result_;
+
+  const ParsedQuicVersion version_;
+};
+
+class CryptoTestUtilsTest : public QuicTest {};
+
+TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) {
+  MockClock clock;
+  QuicCryptoServerConfig crypto_config(
+      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+      crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
+  QuicSocketAddress server_addr(QuicIpAddress::Any4(), 5);
+  QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1);
+  quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config(
+      new QuicSignedServerConfig);
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+  CryptoHandshakeMessage full_chlo;
+
+  QuicCryptoServerConfig::ConfigOptions old_config_options;
+  old_config_options.id = "old-config-id";
+  crypto_config.AddDefaultConfig(QuicRandom::GetInstance(), &clock,
+                                 old_config_options);
+  QuicCryptoServerConfig::ConfigOptions new_config_options;
+  QuicServerConfigProtobuf primary_config = crypto_config.GenerateConfig(
+      QuicRandom::GetInstance(), &clock, new_config_options);
+  primary_config.set_primary_time(clock.WallNow().ToUNIXSeconds());
+  std::unique_ptr<CryptoHandshakeMessage> msg =
+      crypto_config.AddConfig(primary_config, clock.WallNow());
+  absl::string_view orbit;
+  ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit));
+  std::string nonce;
+  CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit,
+                             &nonce);
+  std::string nonce_hex = "#" + absl::BytesToHexString(nonce);
+
+  char public_value[32];
+  memset(public_value, 42, sizeof(public_value));
+  std::string pub_hex = "#" + absl::BytesToHexString(absl::string_view(
+                                  public_value, sizeof(public_value)));
+
+  // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
+  // first one from the list of supported versions.
+  QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
+      transport_version = version.transport_version;
+      break;
+    }
+  }
+  ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
+
+  CryptoHandshakeMessage inchoate_chlo = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"COPT", "SREJ"},
+       {"PUBS", pub_hex},
+       {"NONC", nonce_hex},
+       {"VER\0",
+        QuicVersionLabelToString(CreateQuicVersionLabel(
+            ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version)))}},
+      kClientHelloMinimumSize);
+
+  crypto_test_utils::GenerateFullCHLO(inchoate_chlo, &crypto_config,
+                                      server_addr, client_addr,
+                                      transport_version, &clock, signed_config,
+                                      &compressed_certs_cache, &full_chlo);
+  // Verify that full_chlo can pass crypto_config's verification.
+  ShloVerifier shlo_verifier(
+      &crypto_config, server_addr, client_addr, &clock, signed_config,
+      &compressed_certs_cache,
+      ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, transport_version));
+  crypto_config.ValidateClientHello(
+      full_chlo, client_addr, server_addr, transport_version, &clock,
+      signed_config, shlo_verifier.GetValidateClientHelloCallback());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/failing_proof_source.cc b/quiche/quic/test_tools/failing_proof_source.cc
new file mode 100644
index 0000000..b16ef50
--- /dev/null
+++ b/quiche/quic/test_tools/failing_proof_source.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/failing_proof_source.h"
+
+#include "absl/strings/string_view.h"
+
+namespace quic {
+namespace test {
+
+void FailingProofSource::GetProof(const QuicSocketAddress& /*server_address*/,
+                                  const QuicSocketAddress& /*client_address*/,
+                                  const std::string& /*hostname*/,
+                                  const std::string& /*server_config*/,
+                                  QuicTransportVersion /*transport_version*/,
+                                  absl::string_view /*chlo_hash*/,
+                                  std::unique_ptr<Callback> callback) {
+  callback->Run(false, nullptr, QuicCryptoProof(), nullptr);
+}
+
+quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
+FailingProofSource::GetCertChain(const QuicSocketAddress& /*server_address*/,
+                                 const QuicSocketAddress& /*client_address*/,
+                                 const std::string& /*hostname*/,
+                                 bool* cert_matched_sni) {
+  *cert_matched_sni = false;
+  return quiche::QuicheReferenceCountedPointer<Chain>();
+}
+
+void FailingProofSource::ComputeTlsSignature(
+    const QuicSocketAddress& /*server_address*/,
+    const QuicSocketAddress& /*client_address*/,
+    const std::string& /*hostname*/,
+    uint16_t /*signature_algorithm*/,
+    absl::string_view /*in*/,
+    std::unique_ptr<SignatureCallback> callback) {
+  callback->Run(false, "", nullptr);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/failing_proof_source.h b/quiche/quic/test_tools/failing_proof_source.h
new file mode 100644
index 0000000..6ab29ac
--- /dev/null
+++ b/quiche/quic/test_tools/failing_proof_source.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
+#define QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+
+namespace quic {
+namespace test {
+
+class FailingProofSource : public ProofSource {
+ public:
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& server_config,
+                QuicTransportVersion transport_version,
+                absl::string_view chlo_hash,
+                std::unique_ptr<Callback> callback) override;
+
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) override;
+
+  void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      std::unique_ptr<SignatureCallback> callback) override;
+
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override {
+    return {};
+  }
+
+  TicketCrypter* GetTicketCrypter() override { return nullptr; }
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_FAILING_PROOF_SOURCE_H_
diff --git a/quiche/quic/test_tools/fake_proof_source.cc b/quiche/quic/test_tools/fake_proof_source.cc
new file mode 100644
index 0000000..8ae9592
--- /dev/null
+++ b/quiche/quic/test_tools/fake_proof_source.cc
@@ -0,0 +1,159 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/fake_proof_source.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+
+namespace quic {
+namespace test {
+
+FakeProofSource::FakeProofSource()
+    : delegate_(crypto_test_utils::ProofSourceForTesting()) {}
+
+FakeProofSource::~FakeProofSource() {}
+
+FakeProofSource::PendingOp::~PendingOp() = default;
+
+FakeProofSource::GetProofOp::GetProofOp(
+    const QuicSocketAddress& server_addr,
+    const QuicSocketAddress& client_address,
+    std::string hostname,
+    std::string server_config,
+    QuicTransportVersion transport_version,
+    std::string chlo_hash,
+    std::unique_ptr<ProofSource::Callback> callback,
+    ProofSource* delegate)
+    : server_address_(server_addr),
+      client_address_(client_address),
+      hostname_(std::move(hostname)),
+      server_config_(std::move(server_config)),
+      transport_version_(transport_version),
+      chlo_hash_(std::move(chlo_hash)),
+      callback_(std::move(callback)),
+      delegate_(delegate) {}
+
+FakeProofSource::GetProofOp::~GetProofOp() = default;
+
+void FakeProofSource::GetProofOp::Run() {
+  // Note: relies on the callback being invoked synchronously
+  delegate_->GetProof(server_address_, client_address_, hostname_,
+                      server_config_, transport_version_, chlo_hash_,
+                      std::move(callback_));
+}
+
+FakeProofSource::ComputeSignatureOp::ComputeSignatureOp(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    std::string hostname,
+    uint16_t sig_alg,
+    absl::string_view in,
+    std::unique_ptr<ProofSource::SignatureCallback> callback,
+    ProofSource* delegate)
+    : server_address_(server_address),
+      client_address_(client_address),
+      hostname_(std::move(hostname)),
+      sig_alg_(sig_alg),
+      in_(in),
+      callback_(std::move(callback)),
+      delegate_(delegate) {}
+
+FakeProofSource::ComputeSignatureOp::~ComputeSignatureOp() = default;
+
+void FakeProofSource::ComputeSignatureOp::Run() {
+  delegate_->ComputeTlsSignature(server_address_, client_address_, hostname_,
+                                 sig_alg_, in_, std::move(callback_));
+}
+
+void FakeProofSource::Activate() {
+  active_ = true;
+}
+
+void FakeProofSource::GetProof(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const std::string& hostname,
+    const std::string& server_config,
+    QuicTransportVersion transport_version,
+    absl::string_view chlo_hash,
+    std::unique_ptr<ProofSource::Callback> callback) {
+  if (!active_) {
+    delegate_->GetProof(server_address, client_address, hostname, server_config,
+                        transport_version, chlo_hash, std::move(callback));
+    return;
+  }
+
+  pending_ops_.push_back(std::make_unique<GetProofOp>(
+      server_address, client_address, hostname, server_config,
+      transport_version, std::string(chlo_hash), std::move(callback),
+      delegate_.get()));
+}
+
+quiche::QuicheReferenceCountedPointer<ProofSource::Chain>
+FakeProofSource::GetCertChain(const QuicSocketAddress& server_address,
+                              const QuicSocketAddress& client_address,
+                              const std::string& hostname,
+                              bool* cert_matched_sni) {
+  return delegate_->GetCertChain(server_address, client_address, hostname,
+                                 cert_matched_sni);
+}
+
+void FakeProofSource::ComputeTlsSignature(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in,
+    std::unique_ptr<ProofSource::SignatureCallback> callback) {
+  QUIC_LOG(INFO) << "FakeProofSource::ComputeTlsSignature";
+  if (!active_) {
+    QUIC_LOG(INFO) << "Not active - directly calling delegate";
+    delegate_->ComputeTlsSignature(server_address, client_address, hostname,
+                                   signature_algorithm, in,
+                                   std::move(callback));
+    return;
+  }
+
+  QUIC_LOG(INFO) << "Adding pending op";
+  pending_ops_.push_back(std::make_unique<ComputeSignatureOp>(
+      server_address, client_address, hostname, signature_algorithm, in,
+      std::move(callback), delegate_.get()));
+}
+
+absl::InlinedVector<uint16_t, 8>
+FakeProofSource::SupportedTlsSignatureAlgorithms() const {
+  return delegate_->SupportedTlsSignatureAlgorithms();
+}
+
+ProofSource::TicketCrypter* FakeProofSource::GetTicketCrypter() {
+  if (ticket_crypter_) {
+    return ticket_crypter_.get();
+  }
+  return delegate_->GetTicketCrypter();
+}
+
+void FakeProofSource::SetTicketCrypter(
+    std::unique_ptr<TicketCrypter> ticket_crypter) {
+  ticket_crypter_ = std::move(ticket_crypter);
+}
+
+int FakeProofSource::NumPendingCallbacks() const {
+  return pending_ops_.size();
+}
+
+void FakeProofSource::InvokePendingCallback(int n) {
+  QUICHE_CHECK(NumPendingCallbacks() > n);
+
+  pending_ops_[n]->Run();
+
+  auto it = pending_ops_.begin() + n;
+  pending_ops_.erase(it);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/fake_proof_source.h b/quiche/quic/test_tools/fake_proof_source.h
new file mode 100644
index 0000000..f2f5cc6
--- /dev/null
+++ b/quiche/quic/test_tools/fake_proof_source.h
@@ -0,0 +1,135 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
+#define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+
+namespace quic {
+namespace test {
+
+// Implementation of ProofSource which delegates to a ProofSourceForTesting, but
+// allows for overriding certain functionality. FakeProofSource allows
+// intercepting calls to GetProof and ComputeTlsSignature to force them to run
+// asynchronously, and allow the caller to see that the call is pending and
+// resume the operation at the caller's choosing. FakeProofSource also allows
+// the caller to replace the TicketCrypter provided by
+// FakeProofSource::GetTicketCrypter.
+class FakeProofSource : public ProofSource {
+ public:
+  FakeProofSource();
+  ~FakeProofSource() override;
+
+  // Before this object is "active", all calls to GetProof will be delegated
+  // immediately.  Once "active", the async ones will be intercepted.  This
+  // distinction is necessary to ensure that GetProof can be called without
+  // interference during test case setup.
+  void Activate();
+
+  // ProofSource interface
+  void GetProof(const QuicSocketAddress& server_address,
+                const QuicSocketAddress& client_address,
+                const std::string& hostname,
+                const std::string& server_config,
+                QuicTransportVersion transport_version,
+                absl::string_view chlo_hash,
+                std::unique_ptr<ProofSource::Callback> callback) override;
+  quiche::QuicheReferenceCountedPointer<Chain> GetCertChain(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address, const std::string& hostname,
+      bool* cert_matched_sni) override;
+  void ComputeTlsSignature(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      const std::string& hostname,
+      uint16_t signature_algorithm,
+      absl::string_view in,
+      std::unique_ptr<ProofSource::SignatureCallback> callback) override;
+  absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+      const override;
+  TicketCrypter* GetTicketCrypter() override;
+
+  // Sets the TicketCrypter to use. If nullptr, the TicketCrypter from
+  // ProofSourceForTesting will be returned instead.
+  void SetTicketCrypter(std::unique_ptr<TicketCrypter> ticket_crypter);
+
+  // Get the number of callbacks which are pending
+  int NumPendingCallbacks() const;
+
+  // Invoke a pending callback.  The index refers to the position in
+  // pending_ops_ of the callback to be completed.
+  void InvokePendingCallback(int n);
+
+ private:
+  std::unique_ptr<ProofSource> delegate_;
+  std::unique_ptr<TicketCrypter> ticket_crypter_;
+  bool active_ = false;
+
+  class PendingOp {
+   public:
+    virtual ~PendingOp();
+    virtual void Run() = 0;
+  };
+
+  class GetProofOp : public PendingOp {
+   public:
+    GetProofOp(const QuicSocketAddress& server_addr,
+               const QuicSocketAddress& client_address,
+               std::string hostname,
+               std::string server_config,
+               QuicTransportVersion transport_version,
+               std::string chlo_hash,
+               std::unique_ptr<ProofSource::Callback> callback,
+               ProofSource* delegate);
+    ~GetProofOp() override;
+
+    void Run() override;
+
+   private:
+    QuicSocketAddress server_address_;
+    QuicSocketAddress client_address_;
+    std::string hostname_;
+    std::string server_config_;
+    QuicTransportVersion transport_version_;
+    std::string chlo_hash_;
+    std::unique_ptr<ProofSource::Callback> callback_;
+    ProofSource* delegate_;
+  };
+
+  class ComputeSignatureOp : public PendingOp {
+   public:
+    ComputeSignatureOp(const QuicSocketAddress& server_address,
+                       const QuicSocketAddress& client_address,
+                       std::string hostname,
+                       uint16_t sig_alg,
+                       absl::string_view in,
+                       std::unique_ptr<ProofSource::SignatureCallback> callback,
+                       ProofSource* delegate);
+    ~ComputeSignatureOp() override;
+
+    void Run() override;
+
+   private:
+    QuicSocketAddress server_address_;
+    QuicSocketAddress client_address_;
+    std::string hostname_;
+    uint16_t sig_alg_;
+    std::string in_;
+    std::unique_ptr<ProofSource::SignatureCallback> callback_;
+    ProofSource* delegate_;
+  };
+
+  std::vector<std::unique_ptr<PendingOp>> pending_ops_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_H_
diff --git a/quiche/quic/test_tools/fake_proof_source_handle.cc b/quiche/quic/test_tools/fake_proof_source_handle.cc
new file mode 100644
index 0000000..0736b99
--- /dev/null
+++ b/quiche/quic/test_tools/fake_proof_source_handle.cc
@@ -0,0 +1,241 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/fake_proof_source_handle.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+struct QUIC_EXPORT_PRIVATE ComputeSignatureResult {
+  bool ok;
+  std::string signature;
+  std::unique_ptr<ProofSource::Details> details;
+};
+
+class QUIC_EXPORT_PRIVATE ResultSavingSignatureCallback
+    : public ProofSource::SignatureCallback {
+ public:
+  explicit ResultSavingSignatureCallback(
+      absl::optional<ComputeSignatureResult>* result)
+      : result_(result) {
+    QUICHE_DCHECK(!result_->has_value());
+  }
+  void Run(bool ok,
+           std::string signature,
+           std::unique_ptr<ProofSource::Details> details) override {
+    result_->emplace(
+        ComputeSignatureResult{ok, std::move(signature), std::move(details)});
+  }
+
+ private:
+  absl::optional<ComputeSignatureResult>* result_;
+};
+
+ComputeSignatureResult ComputeSignatureNow(
+    ProofSource* delegate,
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in) {
+  absl::optional<ComputeSignatureResult> result;
+  delegate->ComputeTlsSignature(
+      server_address, client_address, hostname, signature_algorithm, in,
+      std::make_unique<ResultSavingSignatureCallback>(&result));
+  QUICHE_CHECK(result.has_value())
+      << "delegate->ComputeTlsSignature must computes a "
+         "signature immediately";
+  return std::move(result.value());
+}
+}  // namespace
+
+FakeProofSourceHandle::FakeProofSourceHandle(
+    ProofSource* delegate, ProofSourceHandleCallback* callback,
+    Action select_cert_action, Action compute_signature_action,
+    QuicDelayedSSLConfig dealyed_ssl_config)
+    : delegate_(delegate),
+      callback_(callback),
+      select_cert_action_(select_cert_action),
+      compute_signature_action_(compute_signature_action),
+      dealyed_ssl_config_(dealyed_ssl_config) {}
+
+void FakeProofSourceHandle::CloseHandle() {
+  select_cert_op_.reset();
+  compute_signature_op_.reset();
+  closed_ = true;
+}
+
+QuicAsyncStatus FakeProofSourceHandle::SelectCertificate(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    absl::string_view ssl_capabilities,
+    const std::string& hostname,
+    absl::string_view client_hello,
+    const std::string& alpn,
+    absl::optional<std::string> alps,
+    const std::vector<uint8_t>& quic_transport_params,
+    const absl::optional<std::vector<uint8_t>>& early_data_context,
+    const QuicSSLConfig& ssl_config) {
+  if (select_cert_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
+    QUICHE_CHECK(!closed_);
+  }
+  all_select_cert_args_.push_back(SelectCertArgs(
+      server_address, client_address, ssl_capabilities, hostname, client_hello,
+      alpn, alps, quic_transport_params, early_data_context, ssl_config));
+
+  if (select_cert_action_ == Action::DELEGATE_ASYNC ||
+      select_cert_action_ == Action::FAIL_ASYNC) {
+    select_cert_op_.emplace(delegate_, callback_, select_cert_action_,
+                            all_select_cert_args_.back(), dealyed_ssl_config_);
+    return QUIC_PENDING;
+  } else if (select_cert_action_ == Action::FAIL_SYNC ||
+             select_cert_action_ == Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
+    callback()->OnSelectCertificateDone(
+        /*ok=*/false,
+        /*is_sync=*/true, nullptr, /*handshake_hints=*/absl::string_view(),
+        /*ticket_encryption_key=*/absl::string_view(),
+        /*cert_matched_sni=*/false, dealyed_ssl_config_);
+    return QUIC_FAILURE;
+  }
+
+  QUICHE_DCHECK(select_cert_action_ == Action::DELEGATE_SYNC);
+  bool cert_matched_sni;
+  quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+      delegate_->GetCertChain(server_address, client_address, hostname,
+                              &cert_matched_sni);
+
+  bool ok = chain && !chain->certs.empty();
+  callback_->OnSelectCertificateDone(
+      ok, /*is_sync=*/true, chain.get(),
+      /*handshake_hints=*/absl::string_view(),
+      /*ticket_encryption_key=*/absl::string_view(),
+      /*cert_matched_sni=*/cert_matched_sni, dealyed_ssl_config_);
+  return ok ? QUIC_SUCCESS : QUIC_FAILURE;
+}
+
+QuicAsyncStatus FakeProofSourceHandle::ComputeSignature(
+    const QuicSocketAddress& server_address,
+    const QuicSocketAddress& client_address,
+    const std::string& hostname,
+    uint16_t signature_algorithm,
+    absl::string_view in,
+    size_t max_signature_size) {
+  if (compute_signature_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
+    QUICHE_CHECK(!closed_);
+  }
+  all_compute_signature_args_.push_back(
+      ComputeSignatureArgs(server_address, client_address, hostname,
+                           signature_algorithm, in, max_signature_size));
+
+  if (compute_signature_action_ == Action::DELEGATE_ASYNC ||
+      compute_signature_action_ == Action::FAIL_ASYNC) {
+    compute_signature_op_.emplace(delegate_, callback_,
+                                  compute_signature_action_,
+                                  all_compute_signature_args_.back());
+    return QUIC_PENDING;
+  } else if (compute_signature_action_ == Action::FAIL_SYNC ||
+             compute_signature_action_ ==
+                 Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
+    callback()->OnComputeSignatureDone(/*ok=*/false, /*is_sync=*/true,
+                                       /*signature=*/"", /*details=*/nullptr);
+    return QUIC_FAILURE;
+  }
+
+  QUICHE_DCHECK(compute_signature_action_ == Action::DELEGATE_SYNC);
+  ComputeSignatureResult result =
+      ComputeSignatureNow(delegate_, server_address, client_address, hostname,
+                          signature_algorithm, in);
+  callback_->OnComputeSignatureDone(
+      result.ok, /*is_sync=*/true, result.signature, std::move(result.details));
+  return result.ok ? QUIC_SUCCESS : QUIC_FAILURE;
+}
+
+ProofSourceHandleCallback* FakeProofSourceHandle::callback() {
+  return callback_;
+}
+
+bool FakeProofSourceHandle::HasPendingOperation() const {
+  int num_pending_operations = NumPendingOperations();
+  return num_pending_operations > 0;
+}
+
+void FakeProofSourceHandle::CompletePendingOperation() {
+  QUICHE_DCHECK_LE(NumPendingOperations(), 1);
+
+  if (select_cert_op_.has_value()) {
+    select_cert_op_->Run();
+    select_cert_op_.reset();
+  } else if (compute_signature_op_.has_value()) {
+    compute_signature_op_->Run();
+    compute_signature_op_.reset();
+  }
+}
+
+int FakeProofSourceHandle::NumPendingOperations() const {
+  return static_cast<int>(select_cert_op_.has_value()) +
+         static_cast<int>(compute_signature_op_.has_value());
+}
+
+FakeProofSourceHandle::SelectCertOperation::SelectCertOperation(
+    ProofSource* delegate, ProofSourceHandleCallback* callback, Action action,
+    SelectCertArgs args, QuicDelayedSSLConfig dealyed_ssl_config)
+    : PendingOperation(delegate, callback, action),
+      args_(std::move(args)),
+      dealyed_ssl_config_(dealyed_ssl_config) {}
+
+void FakeProofSourceHandle::SelectCertOperation::Run() {
+  if (action_ == Action::FAIL_ASYNC) {
+    callback_->OnSelectCertificateDone(
+        /*ok=*/false,
+        /*is_sync=*/false, nullptr,
+        /*handshake_hints=*/absl::string_view(),
+        /*ticket_encryption_key=*/absl::string_view(),
+        /*cert_matched_sni=*/false, dealyed_ssl_config_);
+  } else if (action_ == Action::DELEGATE_ASYNC) {
+    bool cert_matched_sni;
+    quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
+        delegate_->GetCertChain(args_.server_address, args_.client_address,
+                                args_.hostname, &cert_matched_sni);
+    bool ok = chain && !chain->certs.empty();
+    callback_->OnSelectCertificateDone(
+        ok, /*is_sync=*/false, chain.get(),
+        /*handshake_hints=*/absl::string_view(),
+        /*ticket_encryption_key=*/absl::string_view(),
+        /*cert_matched_sni=*/cert_matched_sni, dealyed_ssl_config_);
+  } else {
+    QUIC_BUG(quic_bug_10139_1)
+        << "Unexpected action: " << static_cast<int>(action_);
+  }
+}
+
+FakeProofSourceHandle::ComputeSignatureOperation::ComputeSignatureOperation(
+    ProofSource* delegate,
+    ProofSourceHandleCallback* callback,
+    Action action,
+    ComputeSignatureArgs args)
+    : PendingOperation(delegate, callback, action), args_(std::move(args)) {}
+
+void FakeProofSourceHandle::ComputeSignatureOperation::Run() {
+  if (action_ == Action::FAIL_ASYNC) {
+    callback_->OnComputeSignatureDone(
+        /*ok=*/false, /*is_sync=*/false,
+        /*signature=*/"", /*details=*/nullptr);
+  } else if (action_ == Action::DELEGATE_ASYNC) {
+    ComputeSignatureResult result = ComputeSignatureNow(
+        delegate_, args_.server_address, args_.client_address, args_.hostname,
+        args_.signature_algorithm, args_.in);
+    callback_->OnComputeSignatureDone(result.ok, /*is_sync=*/false,
+                                      result.signature,
+                                      std::move(result.details));
+  } else {
+    QUIC_BUG(quic_bug_10139_2)
+        << "Unexpected action: " << static_cast<int>(action_);
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/fake_proof_source_handle.h b/quiche/quic/test_tools/fake_proof_source_handle.h
new file mode 100644
index 0000000..ac0d184
--- /dev/null
+++ b/quiche/quic/test_tools/fake_proof_source_handle.h
@@ -0,0 +1,201 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
+#define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
+
+#include "quiche/quic/core/crypto/proof_source.h"
+
+namespace quic {
+namespace test {
+
+// FakeProofSourceHandle allows its behavior to be scripted for testing.
+class FakeProofSourceHandle : public ProofSourceHandle {
+ public:
+  // What would an operation return when it is called.
+  enum class Action {
+    // Delegate the operation to |delegate_| immediately.
+    DELEGATE_SYNC = 0,
+    // Handle the operation asynchronously. Delegate the operation to
+    // |delegate_| when the caller calls CompletePendingOperation().
+    DELEGATE_ASYNC,
+    // Fail the operation immediately.
+    FAIL_SYNC,
+    // Handle the operation asynchronously. Fail the operation when the caller
+    // calls CompletePendingOperation().
+    FAIL_ASYNC,
+    // Similar to FAIL_SYNC, but do not QUICHE_CHECK(!closed_) when invoked.
+    FAIL_SYNC_DO_NOT_CHECK_CLOSED,
+  };
+
+  // |delegate| must do cert selection and signature synchronously.
+  // |dealyed_ssl_config| is the config passed to OnSelectCertificateDone.
+  FakeProofSourceHandle(
+      ProofSource* delegate, ProofSourceHandleCallback* callback,
+      Action select_cert_action, Action compute_signature_action,
+      QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig());
+
+  ~FakeProofSourceHandle() override = default;
+
+  void CloseHandle() override;
+
+  QuicAsyncStatus SelectCertificate(
+      const QuicSocketAddress& server_address,
+      const QuicSocketAddress& client_address,
+      absl::string_view ssl_capabilities,
+      const std::string& hostname,
+      absl::string_view client_hello,
+      const std::string& alpn,
+      absl::optional<std::string> alps,
+      const std::vector<uint8_t>& quic_transport_params,
+      const absl::optional<std::vector<uint8_t>>& early_data_context,
+      const QuicSSLConfig& ssl_config) override;
+
+  QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
+                                   const QuicSocketAddress& client_address,
+                                   const std::string& hostname,
+                                   uint16_t signature_algorithm,
+                                   absl::string_view in,
+                                   size_t max_signature_size) override;
+
+  ProofSourceHandleCallback* callback() override;
+
+  // Whether there's a pending operation in |this|.
+  bool HasPendingOperation() const;
+  void CompletePendingOperation();
+
+  struct SelectCertArgs {
+    SelectCertArgs(QuicSocketAddress server_address,
+                   QuicSocketAddress client_address,
+                   absl::string_view ssl_capabilities,
+                   std::string hostname,
+                   absl::string_view client_hello,
+                   std::string alpn,
+                   absl::optional<std::string> alps,
+                   std::vector<uint8_t> quic_transport_params,
+                   absl::optional<std::vector<uint8_t>> early_data_context,
+                   QuicSSLConfig ssl_config)
+        : server_address(server_address),
+          client_address(client_address),
+          ssl_capabilities(ssl_capabilities),
+          hostname(hostname),
+          client_hello(client_hello),
+          alpn(alpn),
+          alps(alps),
+          quic_transport_params(quic_transport_params),
+          early_data_context(early_data_context),
+          ssl_config(ssl_config) {}
+
+    QuicSocketAddress server_address;
+    QuicSocketAddress client_address;
+    std::string ssl_capabilities;
+    std::string hostname;
+    std::string client_hello;
+    std::string alpn;
+    absl::optional<std::string> alps;
+    std::vector<uint8_t> quic_transport_params;
+    absl::optional<std::vector<uint8_t>> early_data_context;
+    QuicSSLConfig ssl_config;
+  };
+
+  struct ComputeSignatureArgs {
+    ComputeSignatureArgs(QuicSocketAddress server_address,
+                         QuicSocketAddress client_address,
+                         std::string hostname,
+                         uint16_t signature_algorithm,
+                         absl::string_view in,
+                         size_t max_signature_size)
+        : server_address(server_address),
+          client_address(client_address),
+          hostname(hostname),
+          signature_algorithm(signature_algorithm),
+          in(in),
+          max_signature_size(max_signature_size) {}
+
+    QuicSocketAddress server_address;
+    QuicSocketAddress client_address;
+    std::string hostname;
+    uint16_t signature_algorithm;
+    std::string in;
+    size_t max_signature_size;
+  };
+
+  std::vector<SelectCertArgs> all_select_cert_args() const {
+    return all_select_cert_args_;
+  }
+
+  std::vector<ComputeSignatureArgs> all_compute_signature_args() const {
+    return all_compute_signature_args_;
+  }
+
+ private:
+  class PendingOperation {
+   public:
+    PendingOperation(ProofSource* delegate,
+                     ProofSourceHandleCallback* callback,
+                     Action action)
+        : delegate_(delegate), callback_(callback), action_(action) {}
+    virtual ~PendingOperation() = default;
+    virtual void Run() = 0;
+
+   protected:
+    ProofSource* delegate_;
+    ProofSourceHandleCallback* callback_;
+    Action action_;
+  };
+
+  class SelectCertOperation : public PendingOperation {
+   public:
+    SelectCertOperation(ProofSource* delegate,
+                        ProofSourceHandleCallback* callback, Action action,
+                        SelectCertArgs args,
+                        QuicDelayedSSLConfig dealyed_ssl_config);
+
+    ~SelectCertOperation() override = default;
+
+    void Run() override;
+
+   private:
+    const SelectCertArgs args_;
+    const QuicDelayedSSLConfig dealyed_ssl_config_;
+  };
+
+  class ComputeSignatureOperation : public PendingOperation {
+   public:
+    ComputeSignatureOperation(ProofSource* delegate,
+                              ProofSourceHandleCallback* callback,
+                              Action action,
+                              ComputeSignatureArgs args);
+
+    ~ComputeSignatureOperation() override = default;
+
+    void Run() override;
+
+   private:
+    const ComputeSignatureArgs args_;
+  };
+
+ private:
+  int NumPendingOperations() const;
+
+  bool closed_ = false;
+  ProofSource* delegate_;
+  ProofSourceHandleCallback* callback_;
+  // Action for the next select cert operation.
+  Action select_cert_action_ = Action::DELEGATE_SYNC;
+  // Action for the next compute signature operation.
+  Action compute_signature_action_ = Action::DELEGATE_SYNC;
+  const QuicDelayedSSLConfig dealyed_ssl_config_;
+  absl::optional<SelectCertOperation> select_cert_op_;
+  absl::optional<ComputeSignatureOperation> compute_signature_op_;
+
+  // Save all the select cert and compute signature args for tests to inspect.
+  std::vector<SelectCertArgs> all_select_cert_args_;
+  std::vector<ComputeSignatureArgs> all_compute_signature_args_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_
diff --git a/quiche/quic/test_tools/first_flight.cc b/quiche/quic/test_tools/first_flight.cc
new file mode 100644
index 0000000..2f70943
--- /dev/null
+++ b/quiche/quic/test_tools/first_flight.cc
@@ -0,0 +1,163 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/first_flight.h"
+
+#include <memory>
+#include <vector>
+
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// Utility class that creates a custom HTTP/3 session and QUIC connection in
+// order to extract the first flight of packets it sends. This is meant to only
+// be used by GetFirstFlightOfPackets() below.
+class FirstFlightExtractor : public DelegatedPacketWriter::Delegate {
+ public:
+  FirstFlightExtractor(const ParsedQuicVersion& version,
+                       const QuicConfig& config,
+                       const QuicConnectionId& server_connection_id,
+                       const QuicConnectionId& client_connection_id,
+                       std::unique_ptr<QuicCryptoClientConfig> crypto_config)
+      : version_(version),
+        server_connection_id_(server_connection_id),
+        client_connection_id_(client_connection_id),
+        writer_(this),
+        config_(config),
+        crypto_config_(std::move(crypto_config)) {
+    EXPECT_NE(version_, UnsupportedQuicVersion());
+  }
+
+  FirstFlightExtractor(const ParsedQuicVersion& version,
+                       const QuicConfig& config,
+                       const QuicConnectionId& server_connection_id,
+                       const QuicConnectionId& client_connection_id)
+      : FirstFlightExtractor(
+            version, config, server_connection_id, client_connection_id,
+            std::make_unique<QuicCryptoClientConfig>(
+                crypto_test_utils::ProofVerifierForTesting())) {}
+
+  void GenerateFirstFlight() {
+    crypto_config_->set_alpn(AlpnForVersion(version_));
+    connection_ =
+        new QuicConnection(server_connection_id_,
+                           /*initial_self_address=*/QuicSocketAddress(),
+                           QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+                           &connection_helper_, &alarm_factory_, &writer_,
+                           /*owns_writer=*/false, Perspective::IS_CLIENT,
+                           ParsedQuicVersionVector{version_});
+    connection_->set_client_connection_id(client_connection_id_);
+    session_ = std::make_unique<QuicSpdyClientSession>(
+        config_, ParsedQuicVersionVector{version_},
+        connection_,  // session_ takes ownership of connection_ here.
+        TestServerId(), crypto_config_.get(), &push_promise_index_);
+    session_->Initialize();
+    session_->CryptoConnect();
+  }
+
+  void OnDelegatedPacket(const char* buffer,
+                         size_t buf_len,
+                         const QuicIpAddress& /*self_client_address*/,
+                         const QuicSocketAddress& /*peer_client_address*/,
+                         PerPacketOptions* /*options*/) override {
+    packets_.emplace_back(
+        QuicReceivedPacket(buffer, buf_len,
+                           connection_helper_.GetClock()->ApproximateNow(),
+                           /*owns_buffer=*/false)
+            .Clone());
+  }
+
+  std::vector<std::unique_ptr<QuicReceivedPacket>>&& ConsumePackets() {
+    return std::move(packets_);
+  }
+
+ private:
+  ParsedQuicVersion version_;
+  QuicConnectionId server_connection_id_;
+  QuicConnectionId client_connection_id_;
+  MockQuicConnectionHelper connection_helper_;
+  MockAlarmFactory alarm_factory_;
+  DelegatedPacketWriter writer_;
+  QuicConfig config_;
+  std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
+  QuicClientPushPromiseIndex push_promise_index_;
+  QuicConnection* connection_;  // Owned by session_.
+  std::unique_ptr<QuicSpdyClientSession> session_;
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
+};
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version, const QuicConfig& config,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id,
+    std::unique_ptr<QuicCryptoClientConfig> crypto_config) {
+  FirstFlightExtractor first_flight_extractor(
+      version, config, server_connection_id, client_connection_id,
+      std::move(crypto_config));
+  first_flight_extractor.GenerateFirstFlight();
+  return first_flight_extractor.ConsumePackets();
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id) {
+  FirstFlightExtractor first_flight_extractor(
+      version, config, server_connection_id, client_connection_id);
+  first_flight_extractor.GenerateFirstFlight();
+  return first_flight_extractor.ConsumePackets();
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config,
+    const QuicConnectionId& server_connection_id) {
+  return GetFirstFlightOfPackets(version, config, server_connection_id,
+                                 EmptyQuicConnectionId());
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config) {
+  return GetFirstFlightOfPackets(version, config, TestConnectionId());
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id) {
+  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                 server_connection_id, client_connection_id);
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id) {
+  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                 server_connection_id, EmptyQuicConnectionId());
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version) {
+  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                 TestConnectionId());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/first_flight.h b/quiche/quic/test_tools/first_flight.h
new file mode 100644
index 0000000..b6118ba
--- /dev/null
+++ b/quiche/quic/test_tools/first_flight.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
+#define QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
+
+#include <memory>
+#include <vector>
+
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+namespace test {
+
+// Implementation of QuicPacketWriter that sends all packets to a delegate.
+class QUIC_NO_EXPORT DelegatedPacketWriter : public QuicPacketWriter {
+ public:
+  class QUIC_NO_EXPORT Delegate {
+   public:
+    virtual ~Delegate() {}
+    // Note that |buffer| may be released after this call completes so overrides
+    // that want to use the data after the call is complete MUST copy it.
+    virtual void OnDelegatedPacket(const char* buffer,
+                                   size_t buf_len,
+                                   const QuicIpAddress& self_client_address,
+                                   const QuicSocketAddress& peer_client_address,
+                                   PerPacketOptions* options) = 0;
+  };
+
+  // |delegate| MUST be valid for the duration of the DelegatedPacketWriter's
+  // lifetime.
+  explicit DelegatedPacketWriter(Delegate* delegate) : delegate_(delegate) {
+    QUICHE_CHECK_NE(delegate_, nullptr);
+  }
+
+  // Overrides for QuicPacketWriter.
+  bool IsWriteBlocked() const override { return false; }
+  void SetWritable() override {}
+  absl::optional<int> MessageTooBigErrorCode() const override {
+    return absl::nullopt;
+  }
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& /*peer_address*/) const override {
+    return kMaxOutgoingPacketSize;
+  }
+  bool SupportsReleaseTime() const override { return false; }
+  bool IsBatchMode() const override { return false; }
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& /*self_address*/,
+      const QuicSocketAddress& /*peer_address*/) override {
+    return {nullptr, nullptr};
+  }
+  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
+
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_client_address,
+                          const QuicSocketAddress& peer_client_address,
+                          PerPacketOptions* options) override {
+    delegate_->OnDelegatedPacket(buffer, buf_len, self_client_address,
+                                 peer_client_address, options);
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+ private:
+  Delegate* delegate_;  // Unowned.
+};
+
+// Returns an array of packets that represent the first flight of a real
+// HTTP/3 connection. In most cases, this array will only contain one packet
+// that carries the CHLO.
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version, const QuicConfig& config,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id,
+    std::unique_ptr<QuicCryptoClientConfig> crypto_config);
+
+// Below are various convenience overloads that use default values for the
+// omitted parameters:
+// |config| = DefaultQuicConfig(),
+// |server_connection_id| = TestConnectionId(),
+// |client_connection_id| = EmptyQuicConnectionId().
+// |crypto_config| =
+//     QuicCryptoClientConfig(crypto_test_utils::ProofVerifierForTesting())
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version, const QuicConfig& config,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id);
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config,
+    const QuicConnectionId& server_connection_id);
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id);
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id);
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config);
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version);
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_FIRST_FLIGHT_H_
diff --git a/quic/test_tools/fuzzing/README.md b/quiche/quic/test_tools/fuzzing/README.md
similarity index 100%
rename from quic/test_tools/fuzzing/README.md
rename to quiche/quic/test_tools/fuzzing/README.md
diff --git a/quiche/quic/test_tools/fuzzing/quic_framer_fuzzer.cc b/quiche/quic/test_tools/fuzzing/quic_framer_fuzzer.cc
new file mode 100644
index 0000000..7b1e09f
--- /dev/null
+++ b/quiche/quic/test_tools/fuzzing/quic_framer_fuzzer.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  quic::QuicFramer framer(quic::AllSupportedVersions(), quic::QuicTime::Zero(),
+                          quic::Perspective::IS_SERVER,
+                          quic::kQuicDefaultConnectionIdLength);
+  const char* const packet_bytes = reinterpret_cast<const char*>(data);
+
+  // Test the CryptoFramer.
+  absl::string_view crypto_input(packet_bytes, size);
+  std::unique_ptr<quic::CryptoHandshakeMessage> handshake_message(
+      quic::CryptoFramer::ParseMessage(crypto_input));
+
+  // Test the regular QuicFramer with the same input.
+  quic::test::NoOpFramerVisitor visitor;
+  framer.set_visitor(&visitor);
+  quic::QuicEncryptedPacket packet(packet_bytes, size);
+  framer.ProcessPacket(packet);
+
+  return 0;
+}
diff --git a/quiche/quic/test_tools/fuzzing/quic_framer_process_data_packet_fuzzer.cc b/quiche/quic/test_tools/fuzzing/quic_framer_process_data_packet_fuzzer.cc
new file mode 100644
index 0000000..c97b6e8
--- /dev/null
+++ b/quiche/quic/test_tools/fuzzing/quic_framer_process_data_packet_fuzzer.cc
@@ -0,0 +1,285 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <algorithm>
+#include <cstdint>
+#include <string>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using quic::DiversificationNonce;
+using quic::EncryptionLevel;
+using quic::FirstSendingPacketNumber;
+using quic::GetPacketHeaderSize;
+using quic::kEthernetMTU;
+using quic::kQuicDefaultConnectionIdLength;
+using quic::NullDecrypter;
+using quic::NullEncrypter;
+using quic::PacketHeaderFormat;
+using quic::ParsedQuicVersion;
+using quic::ParsedQuicVersionVector;
+using quic::Perspective;
+using quic::QuicConnectionId;
+using quic::QuicDataReader;
+using quic::QuicDataWriter;
+using quic::QuicEncryptedPacket;
+using quic::QuicFramer;
+using quic::QuicFramerVisitorInterface;
+using quic::QuicLongHeaderType;
+using quic::QuicPacketHeader;
+using quic::QuicPacketNumber;
+using quic::QuicTime;
+using quic::QuicTransportVersion;
+using quic::test::NoOpFramerVisitor;
+using quic::test::QuicFramerPeer;
+
+PacketHeaderFormat ConsumePacketHeaderFormat(FuzzedDataProvider* provider,
+                                             ParsedQuicVersion version) {
+  if (!version.HasIetfInvariantHeader()) {
+    return quic::GOOGLE_QUIC_PACKET;
+  }
+  return provider->ConsumeBool() ? quic::IETF_QUIC_LONG_HEADER_PACKET
+                                 : quic::IETF_QUIC_SHORT_HEADER_PACKET;
+}
+
+ParsedQuicVersion ConsumeParsedQuicVersion(FuzzedDataProvider* provider) {
+  // TODO(wub): Add support for v49+.
+  const QuicTransportVersion transport_versions[] = {
+      quic::QUIC_VERSION_43,
+      quic::QUIC_VERSION_46,
+  };
+
+  return ParsedQuicVersion(
+      quic::PROTOCOL_QUIC_CRYPTO,
+      transport_versions[provider->ConsumeIntegralInRange<uint8_t>(
+          0, ABSL_ARRAYSIZE(transport_versions) - 1)]);
+}
+
+// QuicSelfContainedPacketHeader is a QuicPacketHeader with built-in stroage for
+// diversification nonce.
+struct QuicSelfContainedPacketHeader : public QuicPacketHeader {
+  DiversificationNonce nonce_storage;
+};
+
+// Construct a random data packet header that 1) can be successfully serialized
+// at sender, and 2) the serialzied buffer can pass the receiver framer's
+// ProcessPublicHeader and DecryptPayload functions.
+QuicSelfContainedPacketHeader ConsumeQuicPacketHeader(
+    FuzzedDataProvider* provider,
+    Perspective receiver_perspective) {
+  QuicSelfContainedPacketHeader header;
+
+  header.version = ConsumeParsedQuicVersion(provider);
+
+  header.form = ConsumePacketHeaderFormat(provider, header.version);
+
+  const std::string cid_bytes =
+      provider->ConsumeBytesAsString(kQuicDefaultConnectionIdLength);
+  if (receiver_perspective == Perspective::IS_SERVER) {
+    header.destination_connection_id =
+        QuicConnectionId(cid_bytes.c_str(), cid_bytes.size());
+    header.destination_connection_id_included = quic::CONNECTION_ID_PRESENT;
+    header.source_connection_id_included = quic::CONNECTION_ID_ABSENT;
+  } else {
+    header.source_connection_id =
+        QuicConnectionId(cid_bytes.c_str(), cid_bytes.size());
+    header.source_connection_id_included = quic::CONNECTION_ID_PRESENT;
+    header.destination_connection_id_included = quic::CONNECTION_ID_ABSENT;
+  }
+
+  header.version_flag = receiver_perspective == Perspective::IS_SERVER;
+  header.reset_flag = false;
+
+  header.packet_number =
+      QuicPacketNumber(provider->ConsumeIntegral<uint32_t>());
+  if (header.packet_number < FirstSendingPacketNumber()) {
+    header.packet_number = FirstSendingPacketNumber();
+  }
+  header.packet_number_length = quic::PACKET_4BYTE_PACKET_NUMBER;
+
+  header.remaining_packet_length = 0;
+
+  if (header.form != quic::GOOGLE_QUIC_PACKET && header.version_flag) {
+    header.long_packet_type = static_cast<QuicLongHeaderType>(
+        provider->ConsumeIntegralInRange<uint8_t>(
+            // INITIAL, ZERO_RTT_PROTECTED, or HANDSHAKE.
+            static_cast<uint8_t>(quic::INITIAL),
+            static_cast<uint8_t>(quic::HANDSHAKE)));
+  } else {
+    header.long_packet_type = quic::INVALID_PACKET_TYPE;
+  }
+
+  if (header.form == quic::IETF_QUIC_LONG_HEADER_PACKET &&
+      header.long_packet_type == quic::ZERO_RTT_PROTECTED &&
+      receiver_perspective == Perspective::IS_CLIENT &&
+      header.version.handshake_protocol == quic::PROTOCOL_QUIC_CRYPTO) {
+    for (size_t i = 0; i < header.nonce_storage.size(); ++i) {
+      header.nonce_storage[i] = provider->ConsumeIntegral<char>();
+    }
+    header.nonce = &header.nonce_storage;
+  } else {
+    header.nonce = nullptr;
+  }
+
+  return header;
+}
+
+void SetupFramer(QuicFramer* framer, QuicFramerVisitorInterface* visitor) {
+  framer->set_visitor(visitor);
+  for (EncryptionLevel level :
+       {quic::ENCRYPTION_INITIAL, quic::ENCRYPTION_HANDSHAKE,
+        quic::ENCRYPTION_ZERO_RTT, quic::ENCRYPTION_FORWARD_SECURE}) {
+    framer->SetEncrypter(
+        level, std::make_unique<NullEncrypter>(framer->perspective()));
+    if (framer->version().KnowsWhichDecrypterToUse()) {
+      framer->InstallDecrypter(
+          level, std::make_unique<NullDecrypter>(framer->perspective()));
+    }
+  }
+
+  if (!framer->version().KnowsWhichDecrypterToUse()) {
+    framer->SetDecrypter(
+        quic::ENCRYPTION_INITIAL,
+        std::make_unique<NullDecrypter>(framer->perspective()));
+  }
+}
+
+class FuzzingFramerVisitor : public NoOpFramerVisitor {
+ public:
+  // Called after a successful ProcessPublicHeader.
+  bool OnUnauthenticatedPublicHeader(
+      const QuicPacketHeader& /*header*/) override {
+    ++process_public_header_success_count_;
+    return true;
+  }
+
+  // Called after a successful DecryptPayload.
+  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
+    ++decrypted_packet_count_;
+    return true;
+  }
+
+  uint64_t process_public_header_success_count_ = 0;
+  uint64_t decrypted_packet_count_ = 0;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider data_provider(data, size);
+
+  const QuicTime creation_time =
+      QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(
+                             data_provider.ConsumeIntegral<int32_t>());
+  Perspective receiver_perspective = data_provider.ConsumeBool()
+                                         ? Perspective::IS_CLIENT
+                                         : Perspective::IS_SERVER;
+  Perspective sender_perspective =
+      (receiver_perspective == Perspective::IS_CLIENT) ? Perspective::IS_SERVER
+                                                       : Perspective::IS_CLIENT;
+
+  QuicSelfContainedPacketHeader header =
+      ConsumeQuicPacketHeader(&data_provider, receiver_perspective);
+
+  NoOpFramerVisitor sender_framer_visitor;
+  ParsedQuicVersionVector framer_versions = {header.version};
+  QuicFramer sender_framer(framer_versions, creation_time, sender_perspective,
+                           kQuicDefaultConnectionIdLength);
+  SetupFramer(&sender_framer, &sender_framer_visitor);
+
+  FuzzingFramerVisitor receiver_framer_visitor;
+  QuicFramer receiver_framer(framer_versions, creation_time,
+                             receiver_perspective,
+                             kQuicDefaultConnectionIdLength);
+  SetupFramer(&receiver_framer, &receiver_framer_visitor);
+  if (receiver_perspective == Perspective::IS_CLIENT) {
+    QuicFramerPeer::SetLastSerializedServerConnectionId(
+        &receiver_framer, header.source_connection_id);
+  } else {
+    QuicFramerPeer::SetLastSerializedClientConnectionId(
+        &receiver_framer, header.source_connection_id);
+  }
+
+  std::array<char, kEthernetMTU> packet_buffer;
+  while (data_provider.remaining_bytes() > 16) {
+    const size_t last_remaining_bytes = data_provider.remaining_bytes();
+
+    // Get a randomized packet size.
+    uint16_t max_payload_size = static_cast<uint16_t>(
+        std::min<size_t>(data_provider.remaining_bytes(), 1350u));
+    uint16_t min_payload_size = std::min<uint16_t>(16u, max_payload_size);
+    uint16_t payload_size = data_provider.ConsumeIntegralInRange<uint16_t>(
+        min_payload_size, max_payload_size);
+
+    QUICHE_CHECK_NE(last_remaining_bytes, data_provider.remaining_bytes())
+        << "Check fail to avoid an infinite loop. ConsumeIntegralInRange("
+        << min_payload_size << ", " << max_payload_size
+        << ") did not consume any bytes. remaining_bytes:"
+        << last_remaining_bytes;
+
+    std::vector<char> payload_buffer =
+        data_provider.ConsumeBytes<char>(payload_size);
+    QUICHE_CHECK_GE(
+        packet_buffer.size(),
+        GetPacketHeaderSize(sender_framer.transport_version(), header) +
+            payload_buffer.size());
+
+    // Serialize the null-encrypted packet into |packet_buffer|.
+    QuicDataWriter writer(packet_buffer.size(), packet_buffer.data());
+    size_t length_field_offset = 0;
+    QUICHE_CHECK(sender_framer.AppendPacketHeader(header, &writer,
+                                                  &length_field_offset));
+
+    QUICHE_CHECK(
+        writer.WriteBytes(payload_buffer.data(), payload_buffer.size()));
+
+    EncryptionLevel encryption_level =
+        quic::test::HeaderToEncryptionLevel(header);
+    QUICHE_CHECK(sender_framer.WriteIetfLongHeaderLength(
+        header, &writer, length_field_offset, encryption_level));
+
+    size_t encrypted_length = sender_framer.EncryptInPlace(
+        encryption_level, header.packet_number,
+        GetStartOfEncryptedData(sender_framer.transport_version(), header),
+        writer.length(), packet_buffer.size(), packet_buffer.data());
+    QUICHE_CHECK_NE(encrypted_length, 0u);
+
+    // Use receiver's framer to process the packet. Ensure both
+    // ProcessPublicHeader and DecryptPayload were called and succeeded.
+    QuicEncryptedPacket packet(packet_buffer.data(), encrypted_length);
+    QuicDataReader reader(packet.data(), packet.length());
+
+    const uint64_t process_public_header_success_count =
+        receiver_framer_visitor.process_public_header_success_count_;
+    const uint64_t decrypted_packet_count =
+        receiver_framer_visitor.decrypted_packet_count_;
+
+    receiver_framer.ProcessPacket(packet);
+
+    QUICHE_DCHECK_EQ(
+        process_public_header_success_count + 1,
+        receiver_framer_visitor.process_public_header_success_count_)
+        << "ProcessPublicHeader failed. error:"
+        << QuicErrorCodeToString(receiver_framer.error())
+        << ", error_detail:" << receiver_framer.detailed_error()
+        << ". header:" << header;
+    QUICHE_DCHECK_EQ(decrypted_packet_count + 1,
+                     receiver_framer_visitor.decrypted_packet_count_)
+        << "Packet was not decrypted. error:"
+        << QuicErrorCodeToString(receiver_framer.error())
+        << ", error_detail:" << receiver_framer.detailed_error()
+        << ". header:" << header;
+  }
+  return 0;
+}
diff --git a/quiche/quic/test_tools/limited_mtu_test_writer.cc b/quiche/quic/test_tools/limited_mtu_test_writer.cc
new file mode 100644
index 0000000..ff009ee
--- /dev/null
+++ b/quiche/quic/test_tools/limited_mtu_test_writer.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/limited_mtu_test_writer.h"
+
+namespace quic {
+namespace test {
+
+LimitedMtuTestWriter::LimitedMtuTestWriter(QuicByteCount mtu) : mtu_(mtu) {}
+
+LimitedMtuTestWriter::~LimitedMtuTestWriter() = default;
+
+WriteResult LimitedMtuTestWriter::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  if (buf_len > mtu_) {
+    // Drop the packet.
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                              peer_address, options);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/limited_mtu_test_writer.h b/quiche/quic/test_tools/limited_mtu_test_writer.h
new file mode 100644
index 0000000..f3fdc05
--- /dev/null
+++ b/quiche/quic/test_tools/limited_mtu_test_writer.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
+#define QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
+
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+namespace test {
+
+// Simulates a connection over a link with fixed MTU.  Drops packets which
+// exceed the MTU and passes the rest of them as-is.
+class LimitedMtuTestWriter : public QuicPacketWriterWrapper {
+ public:
+  explicit LimitedMtuTestWriter(QuicByteCount mtu);
+  LimitedMtuTestWriter(const LimitedMtuTestWriter&) = delete;
+  LimitedMtuTestWriter& operator=(const LimitedMtuTestWriter&) = delete;
+  ~LimitedMtuTestWriter() override;
+
+  // Inherited from QuicPacketWriterWrapper.
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+ private:
+  QuicByteCount mtu_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_LIMITED_MTU_TEST_WRITER_H_
diff --git a/quiche/quic/test_tools/mock_clock.cc b/quiche/quic/test_tools/mock_clock.cc
new file mode 100644
index 0000000..6aced9e
--- /dev/null
+++ b/quiche/quic/test_tools/mock_clock.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+
+MockClock::MockClock() : now_(QuicTime::Zero()) {}
+
+MockClock::~MockClock() {}
+
+void MockClock::AdvanceTime(QuicTime::Delta delta) {
+  now_ = now_ + delta;
+}
+
+void MockClock::Reset() {
+  now_ = QuicTime::Zero();
+}
+
+QuicTime MockClock::Now() const {
+  return now_;
+}
+
+QuicTime MockClock::ApproximateNow() const {
+  return now_;
+}
+
+QuicWallTime MockClock::WallNow() const {
+  return QuicWallTime::FromUNIXSeconds((now_ - QuicTime::Zero()).ToSeconds());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_clock.h b/quiche/quic/test_tools/mock_clock.h
new file mode 100644
index 0000000..cbb08c0
--- /dev/null
+++ b/quiche/quic/test_tools/mock_clock.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
+
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+
+class MockClock : public QuicClock {
+ public:
+  MockClock();
+  MockClock(const MockClock&) = delete;
+  MockClock& operator=(const MockClock&) = delete;
+  ~MockClock() override;
+
+  // QuicClock implementation:
+  QuicTime Now() const override;
+  QuicTime ApproximateNow() const override;
+  QuicWallTime WallNow() const override;
+
+  // Advances the current time by |delta|, which may be negative.
+  void AdvanceTime(QuicTime::Delta delta);
+  // Resets time back to zero.
+  void Reset();
+
+ private:
+  QuicTime now_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_CLOCK_H_
diff --git a/quiche/quic/test_tools/mock_quic_client_promised_info.cc b/quiche/quic/test_tools/mock_quic_client_promised_info.cc
new file mode 100644
index 0000000..9d3a29b
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_client_promised_info.cc
@@ -0,0 +1,19 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_quic_client_promised_info.h"
+
+namespace quic {
+namespace test {
+
+MockQuicClientPromisedInfo::MockQuicClientPromisedInfo(
+    QuicSpdyClientSessionBase* session,
+    QuicStreamId id,
+    std::string url)
+    : QuicClientPromisedInfo(session, id, url) {}
+
+MockQuicClientPromisedInfo::~MockQuicClientPromisedInfo() {}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_quic_client_promised_info.h b/quiche/quic/test_tools/mock_quic_client_promised_info.h
new file mode 100644
index 0000000..42c2100
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_client_promised_info.h
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
+
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class MockQuicClientPromisedInfo : public QuicClientPromisedInfo {
+ public:
+  MockQuicClientPromisedInfo(QuicSpdyClientSessionBase* session,
+                             QuicStreamId id,
+                             std::string url);
+  ~MockQuicClientPromisedInfo() override;
+
+  MOCK_METHOD(QuicAsyncStatus,
+              HandleClientRequest,
+              (const spdy::SpdyHeaderBlock& headers,
+               QuicClientPushPromiseIndex::Delegate*),
+              (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_CLIENT_PROMISED_INFO_H_
diff --git a/quiche/quic/test_tools/mock_quic_dispatcher.cc b/quiche/quic/test_tools/mock_quic_dispatcher.cc
new file mode 100644
index 0000000..501516c
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_dispatcher.cc
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_quic_dispatcher.h"
+
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+MockQuicDispatcher::MockQuicDispatcher(
+    const QuicConfig* config,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicVersionManager* version_manager,
+    std::unique_ptr<QuicConnectionHelperInterface> helper,
+    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+    std::unique_ptr<QuicAlarmFactory> alarm_factory,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicSimpleDispatcher(config,
+                           crypto_config,
+                           version_manager,
+                           std::move(helper),
+                           std::move(session_helper),
+                           std::move(alarm_factory),
+                           quic_simple_server_backend,
+                           kQuicDefaultConnectionIdLength) {}
+
+MockQuicDispatcher::~MockQuicDispatcher() {}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_quic_dispatcher.h b/quiche/quic/test_tools/mock_quic_dispatcher.h
new file mode 100644
index 0000000..2080d32
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_dispatcher.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
+
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/tools/quic_simple_dispatcher.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+
+namespace quic {
+namespace test {
+
+class MockQuicDispatcher : public QuicSimpleDispatcher {
+ public:
+  MockQuicDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      QuicSimpleServerBackend* quic_simple_server_backend);
+  MockQuicDispatcher(const MockQuicDispatcher&) = delete;
+  MockQuicDispatcher& operator=(const MockQuicDispatcher&) = delete;
+
+  ~MockQuicDispatcher() override;
+
+  MOCK_METHOD(void,
+              ProcessPacket,
+              (const QuicSocketAddress& server_address,
+               const QuicSocketAddress& client_address,
+               const QuicReceivedPacket& packet),
+              (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
diff --git a/quiche/quic/test_tools/mock_quic_session_visitor.cc b/quiche/quic/test_tools/mock_quic_session_visitor.cc
new file mode 100644
index 0000000..5f1f75a
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_session_visitor.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+
+namespace quic {
+namespace test {
+
+MockQuicSessionVisitor::MockQuicSessionVisitor() = default;
+
+MockQuicSessionVisitor::~MockQuicSessionVisitor() = default;
+
+MockQuicCryptoServerStreamHelper::MockQuicCryptoServerStreamHelper() = default;
+
+MockQuicCryptoServerStreamHelper::~MockQuicCryptoServerStreamHelper() = default;
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_quic_session_visitor.h b/quiche/quic/test_tools/mock_quic_session_visitor.h
new file mode 100644
index 0000000..6713851
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_session_visitor.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
+
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class MockQuicSessionVisitor : public QuicTimeWaitListManager::Visitor {
+ public:
+  MockQuicSessionVisitor();
+  MockQuicSessionVisitor(const MockQuicSessionVisitor&) = delete;
+  MockQuicSessionVisitor& operator=(const MockQuicSessionVisitor&) = delete;
+  ~MockQuicSessionVisitor() override;
+  MOCK_METHOD(void,
+              OnConnectionClosed,
+              (QuicConnectionId connection_id,
+               QuicErrorCode error,
+               const std::string& error_details,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(void, OnWriteBlocked, (QuicBlockedWriterInterface*), (override));
+  MOCK_METHOD(void,
+              OnRstStreamReceived,
+              (const QuicRstStreamFrame& frame),
+              (override));
+  MOCK_METHOD(void,
+              OnStopSendingReceived,
+              (const QuicStopSendingFrame& frame),
+              (override));
+  MOCK_METHOD(void,
+              OnNewConnectionIdSent,
+              (const QuicConnectionId& server_connection_id,
+               const QuicConnectionId& new_connection_id),
+              (override));
+  MOCK_METHOD(void,
+              OnConnectionIdRetired,
+              (const quic::QuicConnectionId& server_connection_id),
+              (override));
+  MOCK_METHOD(void,
+              OnConnectionAddedToTimeWaitList,
+              (QuicConnectionId connection_id),
+              (override));
+};
+
+class MockQuicCryptoServerStreamHelper
+    : public QuicCryptoServerStreamBase::Helper {
+ public:
+  MockQuicCryptoServerStreamHelper();
+  MockQuicCryptoServerStreamHelper(const MockQuicCryptoServerStreamHelper&) =
+      delete;
+  MockQuicCryptoServerStreamHelper& operator=(
+      const MockQuicCryptoServerStreamHelper&) = delete;
+  ~MockQuicCryptoServerStreamHelper() override;
+  MOCK_METHOD(bool,
+              CanAcceptClientHello,
+              (const CryptoHandshakeMessage& message,
+               const QuicSocketAddress& client_address,
+               const QuicSocketAddress& peer_address,
+               const QuicSocketAddress& self_address,
+               std::string*),
+              (const, override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SESSION_VISITOR_H_
diff --git a/quiche/quic/test_tools/mock_quic_spdy_client_stream.cc b/quiche/quic/test_tools/mock_quic_spdy_client_stream.cc
new file mode 100644
index 0000000..d82d8f5
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_spdy_client_stream.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_quic_spdy_client_stream.h"
+
+namespace quic {
+namespace test {
+
+MockQuicSpdyClientStream::MockQuicSpdyClientStream(
+    QuicStreamId id,
+    QuicSpdyClientSession* session,
+    StreamType type)
+    : QuicSpdyClientStream(id, session, type) {}
+
+MockQuicSpdyClientStream::~MockQuicSpdyClientStream() {}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_quic_spdy_client_stream.h b/quiche/quic/test_tools/mock_quic_spdy_client_stream.h
new file mode 100644
index 0000000..cc4d87e
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_spdy_client_stream.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
+
+#include "quiche/quic/core/http/quic_header_list.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class MockQuicSpdyClientStream : public QuicSpdyClientStream {
+ public:
+  MockQuicSpdyClientStream(QuicStreamId id,
+                           QuicSpdyClientSession* session,
+                           StreamType type);
+  ~MockQuicSpdyClientStream() override;
+
+  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
+  MOCK_METHOD(void,
+              OnPromiseHeaderList,
+              (QuicStreamId promised_stream_id,
+               size_t frame_len,
+               const QuicHeaderList& list),
+              (override));
+  MOCK_METHOD(void, OnDataAvailable, (), (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_SPDY_CLIENT_STREAM_H_
diff --git a/quiche/quic/test_tools/mock_quic_time_wait_list_manager.cc b/quiche/quic/test_tools/mock_quic_time_wait_list_manager.cc
new file mode 100644
index 0000000..81486d1
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_time_wait_list_manager.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_quic_time_wait_list_manager.h"
+
+using testing::_;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+
+MockTimeWaitListManager::MockTimeWaitListManager(
+    QuicPacketWriter* writer,
+    Visitor* visitor,
+    const QuicClock* clock,
+    QuicAlarmFactory* alarm_factory)
+    : QuicTimeWaitListManager(writer, visitor, clock, alarm_factory) {
+  // Though AddConnectionIdToTimeWait is mocked, we want to retain its
+  // functionality.
+  EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _))
+      .Times(testing::AnyNumber());
+  ON_CALL(*this, AddConnectionIdToTimeWait(_, _))
+      .WillByDefault(
+          Invoke(this, &MockTimeWaitListManager::
+                           QuicTimeWaitListManager_AddConnectionIdToTimeWait));
+}
+
+MockTimeWaitListManager::~MockTimeWaitListManager() = default;
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_quic_time_wait_list_manager.h b/quiche/quic/test_tools/mock_quic_time_wait_list_manager.h
new file mode 100644
index 0000000..571c8fa
--- /dev/null
+++ b/quiche/quic/test_tools/mock_quic_time_wait_list_manager.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
+
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class MockTimeWaitListManager : public QuicTimeWaitListManager {
+ public:
+  MockTimeWaitListManager(QuicPacketWriter* writer,
+                          Visitor* visitor,
+                          const QuicClock* clock,
+                          QuicAlarmFactory* alarm_factory);
+  ~MockTimeWaitListManager() override;
+
+  MOCK_METHOD(void, AddConnectionIdToTimeWait,
+              (QuicTimeWaitListManager::TimeWaitAction action,
+               quic::TimeWaitConnectionInfo info),
+              (override));
+
+  void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
+      QuicTimeWaitListManager::TimeWaitAction action,
+      quic::TimeWaitConnectionInfo info) {
+    QuicTimeWaitListManager::AddConnectionIdToTimeWait(action, std::move(info));
+  }
+
+  MOCK_METHOD(void,
+              ProcessPacket,
+              (const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               QuicConnectionId,
+               PacketHeaderFormat,
+               size_t,
+               std::unique_ptr<QuicPerPacketContext>),
+              (override));
+
+  MOCK_METHOD(void,
+              SendVersionNegotiationPacket,
+              (QuicConnectionId server_connection_id,
+               QuicConnectionId client_connection_id,
+               bool ietf_quic,
+               bool has_length_prefix,
+               const ParsedQuicVersionVector& supported_versions,
+               const QuicSocketAddress& server_address,
+               const QuicSocketAddress& client_address,
+               std::unique_ptr<QuicPerPacketContext> packet_context),
+              (override));
+
+  MOCK_METHOD(void,
+              SendPublicReset,
+              (const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               QuicConnectionId,
+               bool,
+               size_t,
+               std::unique_ptr<QuicPerPacketContext>),
+              (override));
+
+  MOCK_METHOD(void,
+              SendPacket,
+              (const QuicSocketAddress&,
+               const QuicSocketAddress&,
+               const QuicEncryptedPacket&),
+              (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_QUIC_TIME_WAIT_LIST_MANAGER_H_
diff --git a/quiche/quic/test_tools/mock_random.cc b/quiche/quic/test_tools/mock_random.cc
new file mode 100644
index 0000000..0a61a1c
--- /dev/null
+++ b/quiche/quic/test_tools/mock_random.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/mock_random.h"
+
+#include <string.h>
+
+namespace quic {
+namespace test {
+
+MockRandom::MockRandom() : base_(0xDEADBEEF), increment_(0) {}
+
+MockRandom::MockRandom(uint32_t base) : base_(base), increment_(0) {}
+
+void MockRandom::RandBytes(void* data, size_t len) {
+  memset(data, increment_ + static_cast<uint8_t>('r'), len);
+}
+
+uint64_t MockRandom::RandUint64() {
+  return base_ + increment_;
+}
+
+void MockRandom::InsecureRandBytes(void* data, size_t len) {
+  RandBytes(data, len);
+}
+
+uint64_t MockRandom::InsecureRandUint64() {
+  return RandUint64();
+}
+
+void MockRandom::ChangeValue() {
+  increment_++;
+}
+
+void MockRandom::ResetBase(uint32_t base) {
+  base_ = base;
+  increment_ = 0;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/mock_random.h b/quiche/quic/test_tools/mock_random.h
new file mode 100644
index 0000000..03c1f00
--- /dev/null
+++ b/quiche/quic/test_tools/mock_random.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
+#define QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
+
+#include "quiche/quic/core/crypto/quic_random.h"
+
+namespace quic {
+namespace test {
+
+class MockRandom : public QuicRandom {
+ public:
+  // Initializes base_ to 0xDEADBEEF.
+  MockRandom();
+  explicit MockRandom(uint32_t base);
+  MockRandom(const MockRandom&) = delete;
+  MockRandom& operator=(const MockRandom&) = delete;
+
+  // QuicRandom:
+  // Fills the |data| buffer with a repeating byte, initially 'r'.
+  void RandBytes(void* data, size_t len) override;
+  // Returns base + the current increment.
+  uint64_t RandUint64() override;
+
+  // InsecureRandBytes behaves equivalently to RandBytes.
+  void InsecureRandBytes(void* data, size_t len) override;
+  // InsecureRandUint64 behaves equivalently to RandUint64.
+  uint64_t InsecureRandUint64() override;
+
+  // ChangeValue increments |increment_|. This causes the value returned by
+  // |RandUint64| and the byte that |RandBytes| fills with, to change.
+  void ChangeValue();
+
+  // Sets the base to |base| and resets increment to zero.
+  void ResetBase(uint32_t base);
+
+ private:
+  uint32_t base_;
+  uint8_t increment_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_MOCK_RANDOM_H_
diff --git a/quiche/quic/test_tools/packet_dropping_test_writer.cc b/quiche/quic/test_tools/packet_dropping_test_writer.cc
new file mode 100644
index 0000000..f90128c
--- /dev/null
+++ b/quiche/quic/test_tools/packet_dropping_test_writer.cc
@@ -0,0 +1,262 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/packet_dropping_test_writer.h"
+
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace test {
+
+// Every dropped packet must be followed by this number of succesfully written
+// packets. This is to avoid flaky test failures and timeouts, for example, in
+// case both the client and the server drop every other packet (which is
+// statistically possible even if drop percentage is less than 50%).
+const int32_t kMinSuccesfulWritesAfterPacketLoss = 2;
+
+// An alarm that is scheduled if a blocked socket is simulated to indicate
+// it's writable again.
+class WriteUnblockedAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit WriteUnblockedAlarm(PacketDroppingTestWriter* writer)
+      : writer_(writer) {}
+
+  void OnAlarm() override {
+    QUIC_DLOG(INFO) << "Unblocking socket.";
+    writer_->OnCanWrite();
+  }
+
+ private:
+  PacketDroppingTestWriter* writer_;
+};
+
+// An alarm that is scheduled every time a new packet is to be written at a
+// later point.
+class DelayAlarm : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit DelayAlarm(PacketDroppingTestWriter* writer) : writer_(writer) {}
+
+  void OnAlarm() override {
+    QuicTime new_deadline = writer_->ReleaseOldPackets();
+    if (new_deadline.IsInitialized()) {
+      writer_->SetDelayAlarm(new_deadline);
+    }
+  }
+
+ private:
+  PacketDroppingTestWriter* writer_;
+};
+
+PacketDroppingTestWriter::PacketDroppingTestWriter()
+    : clock_(nullptr),
+      cur_buffer_size_(0),
+      num_calls_to_write_(0),
+      // Do not require any number of successful writes before the first dropped
+      // packet.
+      num_consecutive_succesful_writes_(kMinSuccesfulWritesAfterPacketLoss),
+      fake_packet_loss_percentage_(0),
+      fake_drop_first_n_packets_(0),
+      fake_blocked_socket_percentage_(0),
+      fake_packet_reorder_percentage_(0),
+      fake_packet_delay_(QuicTime::Delta::Zero()),
+      fake_bandwidth_(QuicBandwidth::Zero()),
+      buffer_size_(0) {
+  uint64_t seed = QuicRandom::GetInstance()->RandUint64();
+  QUIC_LOG(INFO) << "Seeding packet loss with " << seed;
+  simple_random_.set_seed(seed);
+}
+
+PacketDroppingTestWriter::~PacketDroppingTestWriter() {
+  if (write_unblocked_alarm_ != nullptr) {
+    write_unblocked_alarm_->PermanentCancel();
+  }
+  if (delay_alarm_ != nullptr) {
+    delay_alarm_->PermanentCancel();
+  }
+}
+
+void PacketDroppingTestWriter::Initialize(
+    QuicConnectionHelperInterface* helper,
+    QuicAlarmFactory* alarm_factory,
+    std::unique_ptr<Delegate> on_can_write) {
+  clock_ = helper->GetClock();
+  write_unblocked_alarm_.reset(
+      alarm_factory->CreateAlarm(new WriteUnblockedAlarm(this)));
+  delay_alarm_.reset(alarm_factory->CreateAlarm(new DelayAlarm(this)));
+  on_can_write_ = std::move(on_can_write);
+}
+
+WriteResult PacketDroppingTestWriter::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  ++num_calls_to_write_;
+  ReleaseOldPackets();
+
+  QuicWriterMutexLock lock(&config_mutex_);
+  if (fake_drop_first_n_packets_ > 0 &&
+      num_calls_to_write_ <=
+          static_cast<uint64_t>(fake_drop_first_n_packets_)) {
+    QUIC_DVLOG(1) << "Dropping first " << fake_drop_first_n_packets_
+                  << " packets (packet number " << num_calls_to_write_ << ")";
+    num_consecutive_succesful_writes_ = 0;
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  // Drop every packet at 100%, otherwise always succeed for at least
+  // kMinSuccesfulWritesAfterPacketLoss packets between two dropped ones.
+  if (fake_packet_loss_percentage_ == 100 ||
+      (fake_packet_loss_percentage_ > 0 &&
+       num_consecutive_succesful_writes_ >=
+           kMinSuccesfulWritesAfterPacketLoss &&
+       (simple_random_.RandUint64() % 100 <
+        static_cast<uint64_t>(fake_packet_loss_percentage_)))) {
+    QUIC_DVLOG(1) << "Dropping packet " << num_calls_to_write_;
+    num_consecutive_succesful_writes_ = 0;
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  } else {
+    ++num_consecutive_succesful_writes_;
+  }
+
+  if (fake_blocked_socket_percentage_ > 0 &&
+      simple_random_.RandUint64() % 100 <
+          static_cast<uint64_t>(fake_blocked_socket_percentage_)) {
+    QUICHE_CHECK(on_can_write_ != nullptr);
+    QUIC_DVLOG(1) << "Blocking socket for packet " << num_calls_to_write_;
+    if (!write_unblocked_alarm_->IsSet()) {
+      // Set the alarm to fire immediately.
+      write_unblocked_alarm_->Set(clock_->ApproximateNow());
+    }
+
+    // Dropping this packet on retry could result in PTO timeout,
+    // make sure to avoid this.
+    num_consecutive_succesful_writes_ = 0;
+
+    return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN);
+  }
+
+  if (!fake_packet_delay_.IsZero() || !fake_bandwidth_.IsZero()) {
+    if (buffer_size_ > 0 && buf_len + cur_buffer_size_ > buffer_size_) {
+      // Drop packets which do not fit into the buffer.
+      QUIC_DVLOG(1) << "Dropping packet because the buffer is full.";
+      return WriteResult(WRITE_STATUS_OK, buf_len);
+    }
+
+    // Queue it to be sent.
+    QuicTime send_time = clock_->ApproximateNow() + fake_packet_delay_;
+    if (!fake_bandwidth_.IsZero()) {
+      // Calculate a time the bandwidth limit would impose.
+      QuicTime::Delta bandwidth_delay = QuicTime::Delta::FromMicroseconds(
+          (buf_len * kNumMicrosPerSecond) / fake_bandwidth_.ToBytesPerSecond());
+      send_time = delayed_packets_.empty()
+                      ? send_time + bandwidth_delay
+                      : delayed_packets_.back().send_time + bandwidth_delay;
+    }
+    std::unique_ptr<PerPacketOptions> delayed_options;
+    if (options != nullptr) {
+      delayed_options = options->Clone();
+    }
+    delayed_packets_.push_back(
+        DelayedWrite(buffer, buf_len, self_address, peer_address,
+                     std::move(delayed_options), send_time));
+    cur_buffer_size_ += buf_len;
+
+    // Set the alarm if it's not yet set.
+    if (!delay_alarm_->IsSet()) {
+      delay_alarm_->Set(send_time);
+    }
+
+    return WriteResult(WRITE_STATUS_OK, buf_len);
+  }
+
+  return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+                                              peer_address, options);
+}
+
+bool PacketDroppingTestWriter::IsWriteBlocked() const {
+  if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
+    return true;
+  }
+  return QuicPacketWriterWrapper::IsWriteBlocked();
+}
+
+void PacketDroppingTestWriter::SetWritable() {
+  if (write_unblocked_alarm_ != nullptr && write_unblocked_alarm_->IsSet()) {
+    write_unblocked_alarm_->Cancel();
+  }
+  QuicPacketWriterWrapper::SetWritable();
+}
+
+QuicTime PacketDroppingTestWriter::ReleaseNextPacket() {
+  if (delayed_packets_.empty()) {
+    return QuicTime::Zero();
+  }
+  QuicReaderMutexLock lock(&config_mutex_);
+  auto iter = delayed_packets_.begin();
+  // Determine if we should re-order.
+  if (delayed_packets_.size() > 1 && fake_packet_reorder_percentage_ > 0 &&
+      simple_random_.RandUint64() % 100 <
+          static_cast<uint64_t>(fake_packet_reorder_percentage_)) {
+    QUIC_DLOG(INFO) << "Reordering packets.";
+    ++iter;
+    // Swap the send times when re-ordering packets.
+    delayed_packets_.begin()->send_time = iter->send_time;
+  }
+
+  QUIC_DVLOG(1) << "Releasing packet.  " << (delayed_packets_.size() - 1)
+                << " remaining.";
+  // Grab the next one off the queue and send it.
+  QuicPacketWriterWrapper::WritePacket(
+      iter->buffer.data(), iter->buffer.length(), iter->self_address,
+      iter->peer_address, iter->options.get());
+  QUICHE_DCHECK_GE(cur_buffer_size_, iter->buffer.length());
+  cur_buffer_size_ -= iter->buffer.length();
+  delayed_packets_.erase(iter);
+
+  // If there are others, find the time for the next to be sent.
+  if (delayed_packets_.empty()) {
+    return QuicTime::Zero();
+  }
+  return delayed_packets_.begin()->send_time;
+}
+
+QuicTime PacketDroppingTestWriter::ReleaseOldPackets() {
+  while (!delayed_packets_.empty()) {
+    QuicTime next_send_time = delayed_packets_.front().send_time;
+    if (next_send_time > clock_->Now()) {
+      return next_send_time;
+    }
+    ReleaseNextPacket();
+  }
+  return QuicTime::Zero();
+}
+
+void PacketDroppingTestWriter::SetDelayAlarm(QuicTime new_deadline) {
+  delay_alarm_->Set(new_deadline);
+}
+
+void PacketDroppingTestWriter::OnCanWrite() {
+  on_can_write_->OnCanWrite();
+}
+
+PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    std::unique_ptr<PerPacketOptions> options,
+    QuicTime send_time)
+    : buffer(buffer, buf_len),
+      self_address(self_address),
+      peer_address(peer_address),
+      options(std::move(options)),
+      send_time(send_time) {}
+
+PacketDroppingTestWriter::DelayedWrite::~DelayedWrite() = default;
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/packet_dropping_test_writer.h b/quiche/quic/test_tools/packet_dropping_test_writer.h
new file mode 100644
index 0000000..40204d9
--- /dev/null
+++ b/quiche/quic/test_tools/packet_dropping_test_writer.h
@@ -0,0 +1,186 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
+#define QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
+
+#include <cstdint>
+#include <list>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/test_tools/quic_test_client.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// Simulates a connection that drops packets a configured percentage of the time
+// and has a blocked socket a configured percentage of the time.  Also provides
+// the options to delay packets and reorder packets if delay is enabled.
+class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
+ public:
+  class Delegate {
+   public:
+    virtual ~Delegate() {}
+    virtual void OnCanWrite() = 0;
+  };
+
+  PacketDroppingTestWriter();
+  PacketDroppingTestWriter(const PacketDroppingTestWriter&) = delete;
+  PacketDroppingTestWriter& operator=(const PacketDroppingTestWriter&) = delete;
+
+  ~PacketDroppingTestWriter() override;
+
+  // Must be called before blocking, reordering or delaying (loss is OK). May be
+  // called after connecting if the helper is not available before.
+  // |on_can_write| will be triggered when fake-unblocking.
+  void Initialize(QuicConnectionHelperInterface* helper,
+                  QuicAlarmFactory* alarm_factory,
+                  std::unique_ptr<Delegate> on_can_write);
+
+  // QuicPacketWriter methods:
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+  bool IsWriteBlocked() const override;
+
+  void SetWritable() override;
+
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& /*self_address*/,
+      const QuicSocketAddress& /*peer_address*/) override {
+    // If the wrapped writer supports zero-copy, disable it, because it is not
+    // compatible with delayed writes in this class.
+    return {nullptr, nullptr};
+  }
+
+  // Writes out any packet which should have been sent by now
+  // to the contained writer and returns the time
+  // for the next delayed packet to be written.
+  QuicTime ReleaseOldPackets();
+
+  // Sets |delay_alarm_| to fire at |new_deadline|.
+  void SetDelayAlarm(QuicTime new_deadline);
+
+  void OnCanWrite();
+
+  // The percent of time a packet is simulated as being lost.
+  // If |fake_packet_loss_percentage| is 100, then all packages are lost.
+  // Otherwise actual percentage will be lower than
+  // |fake_packet_loss_percentage|, because every dropped package is followed by
+  // a minimum number of successfully written packets.
+  void set_fake_packet_loss_percentage(int32_t fake_packet_loss_percentage) {
+    QuicWriterMutexLock lock(&config_mutex_);
+    fake_packet_loss_percentage_ = fake_packet_loss_percentage;
+  }
+
+  // Simulate dropping the first n packets unconditionally.
+  // Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
+  void set_fake_drop_first_n_packets(int32_t fake_drop_first_n_packets) {
+    QuicWriterMutexLock lock(&config_mutex_);
+    fake_drop_first_n_packets_ = fake_drop_first_n_packets;
+  }
+
+  // The percent of time WritePacket will block and set WriteResult's status
+  // to WRITE_STATUS_BLOCKED.
+  void set_fake_blocked_socket_percentage(
+      int32_t fake_blocked_socket_percentage) {
+    QUICHE_DCHECK(clock_);
+    QuicWriterMutexLock lock(&config_mutex_);
+    fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
+  }
+
+  // The percent of time a packet is simulated as being reordered.
+  void set_fake_reorder_percentage(int32_t fake_packet_reorder_percentage) {
+    QUICHE_DCHECK(clock_);
+    QuicWriterMutexLock lock(&config_mutex_);
+    QUICHE_DCHECK(!fake_packet_delay_.IsZero());
+    fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
+  }
+
+  // The delay before writing this packet.
+  void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
+    QUICHE_DCHECK(clock_);
+    QuicWriterMutexLock lock(&config_mutex_);
+    fake_packet_delay_ = fake_packet_delay;
+  }
+
+  // The maximum bandwidth and buffer size of the connection.  When these are
+  // set, packets will be delayed until a connection with that bandwidth would
+  // transmit it.  Once the |buffer_size| is reached, all new packets are
+  // dropped.
+  void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
+                                         QuicByteCount buffer_size) {
+    QUICHE_DCHECK(clock_);
+    QuicWriterMutexLock lock(&config_mutex_);
+    fake_bandwidth_ = fake_bandwidth;
+    buffer_size_ = buffer_size;
+  }
+
+  // Useful for reproducing very flaky issues.
+  ABSL_ATTRIBUTE_UNUSED void set_seed(uint64_t seed) {
+    simple_random_.set_seed(seed);
+  }
+
+ private:
+  // Writes out the next packet to the contained writer and returns the time
+  // for the next delayed packet to be written.
+  QuicTime ReleaseNextPacket();
+
+  // A single packet which will be sent at the supplied send_time.
+  struct DelayedWrite {
+   public:
+    DelayedWrite(const char* buffer,
+                 size_t buf_len,
+                 const QuicIpAddress& self_address,
+                 const QuicSocketAddress& peer_address,
+                 std::unique_ptr<PerPacketOptions> options,
+                 QuicTime send_time);
+    DelayedWrite(const DelayedWrite&) = delete;
+    DelayedWrite(DelayedWrite&&) = default;
+    DelayedWrite& operator=(const DelayedWrite&) = delete;
+    DelayedWrite& operator=(DelayedWrite&&) = default;
+    ~DelayedWrite();
+
+    std::string buffer;
+    QuicIpAddress self_address;
+    QuicSocketAddress peer_address;
+    std::unique_ptr<PerPacketOptions> options;
+    QuicTime send_time;
+  };
+
+  using DelayedPacketList = std::list<DelayedWrite>;
+
+  const QuicClock* clock_;
+  std::unique_ptr<QuicAlarm> write_unblocked_alarm_;
+  std::unique_ptr<QuicAlarm> delay_alarm_;
+  std::unique_ptr<Delegate> on_can_write_;
+  SimpleRandom simple_random_;
+  // Stored packets delayed by fake packet delay or bandwidth restrictions.
+  DelayedPacketList delayed_packets_;
+  QuicByteCount cur_buffer_size_;
+  uint64_t num_calls_to_write_;
+  int32_t num_consecutive_succesful_writes_;
+
+  QuicMutex config_mutex_;
+  int32_t fake_packet_loss_percentage_ QUIC_GUARDED_BY(config_mutex_);
+  int32_t fake_drop_first_n_packets_ QUIC_GUARDED_BY(config_mutex_);
+  int32_t fake_blocked_socket_percentage_ QUIC_GUARDED_BY(config_mutex_);
+  int32_t fake_packet_reorder_percentage_ QUIC_GUARDED_BY(config_mutex_);
+  QuicTime::Delta fake_packet_delay_ QUIC_GUARDED_BY(config_mutex_);
+  QuicBandwidth fake_bandwidth_ QUIC_GUARDED_BY(config_mutex_);
+  QuicByteCount buffer_size_ QUIC_GUARDED_BY(config_mutex_);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
diff --git a/quiche/quic/test_tools/packet_reordering_writer.cc b/quiche/quic/test_tools/packet_reordering_writer.cc
new file mode 100644
index 0000000..66073ea
--- /dev/null
+++ b/quiche/quic/test_tools/packet_reordering_writer.cc
@@ -0,0 +1,54 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/packet_reordering_writer.h"
+
+namespace quic {
+namespace test {
+
+PacketReorderingWriter::PacketReorderingWriter() = default;
+
+PacketReorderingWriter::~PacketReorderingWriter() = default;
+
+WriteResult PacketReorderingWriter::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    PerPacketOptions* options) {
+  if (!delay_next_) {
+    QUIC_VLOG(2) << "Writing a non-delayed packet";
+    WriteResult wr = QuicPacketWriterWrapper::WritePacket(
+        buffer, buf_len, self_address, peer_address, options);
+    --num_packets_to_wait_;
+    if (num_packets_to_wait_ == 0) {
+      QUIC_VLOG(2) << "Writing a delayed packet";
+      // It's time to write the delayed packet.
+      QuicPacketWriterWrapper::WritePacket(
+          delayed_data_.data(), delayed_data_.length(), delayed_self_address_,
+          delayed_peer_address_, delayed_options_.get());
+    }
+    return wr;
+  }
+  // Still have packet to wait.
+  QUICHE_DCHECK_LT(0u, num_packets_to_wait_)
+      << "Only allow one packet to be delayed";
+  delayed_data_ = std::string(buffer, buf_len);
+  delayed_self_address_ = self_address;
+  delayed_peer_address_ = peer_address;
+  if (options != nullptr) {
+    delayed_options_ = options->Clone();
+  }
+  delay_next_ = false;
+  return WriteResult(WRITE_STATUS_OK, buf_len);
+}
+
+void PacketReorderingWriter::SetDelay(size_t num_packets_to_wait) {
+  QUICHE_DCHECK_GT(num_packets_to_wait, 0u);
+  num_packets_to_wait_ = num_packets_to_wait;
+  delay_next_ = true;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/packet_reordering_writer.h b/quiche/quic/test_tools/packet_reordering_writer.h
new file mode 100644
index 0000000..9906cd0
--- /dev/null
+++ b/quiche/quic/test_tools/packet_reordering_writer.h
@@ -0,0 +1,45 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
+#define QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
+
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+
+namespace quic {
+
+namespace test {
+
+// This packet writer allows delaying writing the next packet after
+// SetDelay(num_packets_to_wait)
+// is called and buffer this packet and write it after it writes next
+// |num_packets_to_wait| packets. It doesn't support delaying a packet while
+// there is already a packet delayed.
+class PacketReorderingWriter : public QuicPacketWriterWrapper {
+ public:
+  PacketReorderingWriter();
+
+  ~PacketReorderingWriter() override;
+
+  WriteResult WritePacket(const char* buffer,
+                          size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+  void SetDelay(size_t num_packets_to_wait);
+
+ private:
+  bool delay_next_ = false;
+  size_t num_packets_to_wait_ = 0;
+  std::string delayed_data_;
+  QuicIpAddress delayed_self_address_;
+  QuicSocketAddress delayed_peer_address_;
+  std::unique_ptr<PerPacketOptions> delayed_options_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
diff --git a/quiche/quic/test_tools/qpack/qpack_decoder_test_utils.cc b/quiche/quic/test_tools/qpack/qpack_decoder_test_utils.cc
new file mode 100644
index 0000000..1b234a1
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_decoder_test_utils.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+void NoopEncoderStreamErrorDelegate::OnEncoderStreamError(
+    QuicErrorCode /* error_code */,
+    absl::string_view /*error_message*/) {}
+
+TestHeadersHandler::TestHeadersHandler()
+    : decoding_completed_(false), decoding_error_detected_(false) {}
+
+void TestHeadersHandler::OnHeaderDecoded(absl::string_view name,
+                                         absl::string_view value) {
+  ASSERT_FALSE(decoding_completed_);
+  ASSERT_FALSE(decoding_error_detected_);
+
+  header_list_.AppendValueOrAddHeader(name, value);
+}
+
+void TestHeadersHandler::OnDecodingCompleted() {
+  ASSERT_FALSE(decoding_completed_);
+  ASSERT_FALSE(decoding_error_detected_);
+
+  decoding_completed_ = true;
+}
+
+void TestHeadersHandler::OnDecodingErrorDetected(
+    QuicErrorCode /*error_code*/, absl::string_view error_message) {
+  ASSERT_FALSE(decoding_completed_);
+  ASSERT_FALSE(decoding_error_detected_);
+
+  decoding_error_detected_ = true;
+  error_message_.assign(error_message.data(), error_message.size());
+}
+
+spdy::Http2HeaderBlock TestHeadersHandler::ReleaseHeaderList() {
+  QUICHE_DCHECK(decoding_completed_);
+  QUICHE_DCHECK(!decoding_error_detected_);
+
+  return std::move(header_list_);
+}
+
+bool TestHeadersHandler::decoding_completed() const {
+  return decoding_completed_;
+}
+
+bool TestHeadersHandler::decoding_error_detected() const {
+  return decoding_error_detected_;
+}
+
+const std::string& TestHeadersHandler::error_message() const {
+  QUICHE_DCHECK(decoding_error_detected_);
+  return error_message_;
+}
+
+void QpackDecode(
+    uint64_t maximum_dynamic_table_capacity,
+    uint64_t maximum_blocked_streams,
+    QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate,
+    QpackStreamSenderDelegate* decoder_stream_sender_delegate,
+    QpackProgressiveDecoder::HeadersHandlerInterface* handler,
+    const FragmentSizeGenerator& fragment_size_generator,
+    absl::string_view data) {
+  QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
+                       encoder_stream_error_delegate);
+  decoder.set_qpack_stream_sender_delegate(decoder_stream_sender_delegate);
+  auto progressive_decoder =
+      decoder.CreateProgressiveDecoder(/* stream_id = */ 1, handler);
+  while (!data.empty()) {
+    size_t fragment_size = std::min(fragment_size_generator(), data.size());
+    progressive_decoder->Decode(data.substr(0, fragment_size));
+    data = data.substr(fragment_size);
+  }
+  progressive_decoder->EndHeaderBlock();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h b/quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h
new file mode 100644
index 0000000..5c1b4f1
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
+#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/qpack/qpack_progressive_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+namespace test {
+
+// QpackDecoder::EncoderStreamErrorDelegate implementation that does nothing.
+class NoopEncoderStreamErrorDelegate
+    : public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  ~NoopEncoderStreamErrorDelegate() override = default;
+
+  void OnEncoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+};
+
+// Mock QpackDecoder::EncoderStreamErrorDelegate implementation.
+class MockEncoderStreamErrorDelegate
+    : public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  ~MockEncoderStreamErrorDelegate() override = default;
+
+  MOCK_METHOD(void,
+              OnEncoderStreamError,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+// HeadersHandlerInterface implementation that collects decoded headers
+// into a Http2HeaderBlock.
+class TestHeadersHandler
+    : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  TestHeadersHandler();
+  ~TestHeadersHandler() override = default;
+
+  // HeadersHandlerInterface implementation:
+  void OnHeaderDecoded(absl::string_view name,
+                       absl::string_view value) override;
+  void OnDecodingCompleted() override;
+  void OnDecodingErrorDetected(QuicErrorCode error_code,
+                               absl::string_view error_message) override;
+
+  // Release decoded header list.  Must only be called if decoding is complete
+  // and no errors have been detected.
+  spdy::Http2HeaderBlock ReleaseHeaderList();
+
+  bool decoding_completed() const;
+  bool decoding_error_detected() const;
+  const std::string& error_message() const;
+
+ private:
+  spdy::Http2HeaderBlock header_list_;
+  bool decoding_completed_;
+  bool decoding_error_detected_;
+  std::string error_message_;
+};
+
+class MockHeadersHandler
+    : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  MockHeadersHandler() = default;
+  MockHeadersHandler(const MockHeadersHandler&) = delete;
+  MockHeadersHandler& operator=(const MockHeadersHandler&) = delete;
+  ~MockHeadersHandler() override = default;
+
+  MOCK_METHOD(void,
+              OnHeaderDecoded,
+              (absl::string_view name, absl::string_view value),
+              (override));
+  MOCK_METHOD(void, OnDecodingCompleted, (), (override));
+  MOCK_METHOD(void, OnDecodingErrorDetected,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+class NoOpHeadersHandler
+    : public QpackProgressiveDecoder::HeadersHandlerInterface {
+ public:
+  ~NoOpHeadersHandler() override = default;
+
+  void OnHeaderDecoded(absl::string_view /*name*/,
+                       absl::string_view /*value*/) override {}
+  void OnDecodingCompleted() override {}
+  void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
+                               absl::string_view /*error_message*/) override {}
+};
+
+void QpackDecode(
+    uint64_t maximum_dynamic_table_capacity,
+    uint64_t maximum_blocked_streams,
+    QpackDecoder::EncoderStreamErrorDelegate* encoder_stream_error_delegate,
+    QpackStreamSenderDelegate* decoder_stream_sender_delegate,
+    QpackProgressiveDecoder::HeadersHandlerInterface* handler,
+    const FragmentSizeGenerator& fragment_size_generator,
+    absl::string_view data);
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_DECODER_TEST_UTILS_H_
diff --git a/quiche/quic/test_tools/qpack/qpack_encoder_peer.cc b/quiche/quic/test_tools/qpack/qpack_encoder_peer.cc
new file mode 100644
index 0000000..7389437
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_encoder_peer.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
+
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+
+namespace quic {
+namespace test {
+
+// static
+QpackEncoderHeaderTable* QpackEncoderPeer::header_table(QpackEncoder* encoder) {
+  return &encoder->header_table_;
+}
+
+// static
+uint64_t QpackEncoderPeer::maximum_blocked_streams(
+    const QpackEncoder* encoder) {
+  return encoder->maximum_blocked_streams_;
+}
+
+// static
+uint64_t QpackEncoderPeer::smallest_blocking_index(
+    const QpackEncoder* encoder) {
+  return encoder->blocking_manager_.smallest_blocking_index();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quic/test_tools/qpack/qpack_encoder_peer.h b/quiche/quic/test_tools/qpack/qpack_encoder_peer.h
similarity index 100%
rename from quic/test_tools/qpack/qpack_encoder_peer.h
rename to quiche/quic/test_tools/qpack/qpack_encoder_peer.h
diff --git a/quiche/quic/test_tools/qpack/qpack_encoder_test_utils.cc b/quiche/quic/test_tools/qpack/qpack_encoder_test_utils.cc
new file mode 100644
index 0000000..ad357a1
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_encoder_test_utils.cc
@@ -0,0 +1,18 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+
+namespace quic {
+namespace test {
+
+void NoopDecoderStreamErrorDelegate::OnDecoderStreamError(
+    QuicErrorCode /*error_code*/,
+    absl::string_view /*error_message*/) {}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h b/quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h
new file mode 100644
index 0000000..93d242c
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_encoder_test_utils.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
+#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_encoder.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+namespace test {
+
+// QpackEncoder::DecoderStreamErrorDelegate implementation that does nothing.
+class NoopDecoderStreamErrorDelegate
+    : public QpackEncoder::DecoderStreamErrorDelegate {
+ public:
+  ~NoopDecoderStreamErrorDelegate() override = default;
+
+  void OnDecoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+};
+
+// Mock QpackEncoder::DecoderStreamErrorDelegate implementation.
+class MockDecoderStreamErrorDelegate
+    : public QpackEncoder::DecoderStreamErrorDelegate {
+ public:
+  ~MockDecoderStreamErrorDelegate() override = default;
+
+  MOCK_METHOD(void,
+              OnDecoderStreamError,
+              (QuicErrorCode error_code, absl::string_view error_message),
+              (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_ENCODER_TEST_UTILS_H_
diff --git a/quiche/quic/test_tools/qpack/qpack_offline_decoder.cc b/quiche/quic/test_tools/qpack/qpack_offline_decoder.cc
new file mode 100644
index 0000000..9901a70
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_offline_decoder.cc
@@ -0,0 +1,336 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Decoder to test QPACK Offline Interop corpus
+//
+// See https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop for
+// description of test data format.
+//
+// Example usage
+//
+//  cd $TEST_DATA
+//  git clone https://github.com/qpackers/qifs.git
+//  TEST_ENCODED_DATA=$TEST_DATA/qifs/encoded/qpack-06
+//  TEST_QIF_DATA=$TEST_DATA/qifs/qifs
+//  $BIN/qpack_offline_decoder \
+//      $TEST_ENCODED_DATA/f5/fb-req.qifencoded.4096.100.0 \
+//      $TEST_QIF_DATA/fb-req.qif
+//      $TEST_ENCODED_DATA/h2o/fb-req-hq.out.512.0.1 \
+//      $TEST_QIF_DATA/fb-req-hq.qif
+//      $TEST_ENCODED_DATA/ls-qpack/fb-resp-hq.out.0.0.0 \
+//      $TEST_QIF_DATA/fb-resp-hq.qif
+//      $TEST_ENCODED_DATA/proxygen/netbsd.qif.proxygen.out.4096.0.0 \
+//      $TEST_QIF_DATA/netbsd.qif
+//
+
+#include "quiche/quic/test_tools/qpack/qpack_offline_decoder.h"
+
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/match.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/common/platform/api/quiche_file_utils.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quic {
+
+QpackOfflineDecoder::QpackOfflineDecoder()
+    : encoder_stream_error_detected_(false) {}
+
+bool QpackOfflineDecoder::DecodeAndVerifyOfflineData(
+    absl::string_view input_filename,
+    absl::string_view expected_headers_filename) {
+  if (!ParseInputFilename(input_filename)) {
+    QUIC_LOG(ERROR) << "Error parsing input filename " << input_filename;
+    return false;
+  }
+
+  if (!DecodeHeaderBlocksFromFile(input_filename)) {
+    QUIC_LOG(ERROR) << "Error decoding header blocks in " << input_filename;
+    return false;
+  }
+
+  if (!VerifyDecodedHeaderLists(expected_headers_filename)) {
+    QUIC_LOG(ERROR) << "Header lists decoded from " << input_filename
+                    << " to not match expected headers parsed from "
+                    << expected_headers_filename;
+    return false;
+  }
+
+  return true;
+}
+
+void QpackOfflineDecoder::OnEncoderStreamError(
+    QuicErrorCode error_code, absl::string_view error_message) {
+  QUIC_LOG(ERROR) << "Encoder stream error: "
+                  << QuicErrorCodeToString(error_code) << " " << error_message;
+  encoder_stream_error_detected_ = true;
+}
+
+bool QpackOfflineDecoder::ParseInputFilename(absl::string_view input_filename) {
+  std::vector<absl::string_view> pieces = absl::StrSplit(input_filename, '.');
+
+  if (pieces.size() < 3) {
+    QUIC_LOG(ERROR) << "Not enough fields in input filename " << input_filename;
+    return false;
+  }
+
+  auto piece_it = pieces.rbegin();
+
+  // Acknowledgement mode: 1 for immediate, 0 for none.
+  if (*piece_it != "0" && *piece_it != "1") {
+    QUIC_LOG(ERROR)
+        << "Header acknowledgement field must be 0 or 1 in input filename "
+        << input_filename;
+    return false;
+  }
+
+  ++piece_it;
+
+  // Maximum allowed number of blocked streams.
+  uint64_t max_blocked_streams = 0;
+  if (!absl::SimpleAtoi(*piece_it, &max_blocked_streams)) {
+    QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it
+                    << "\" as an integer.";
+    return false;
+  }
+
+  ++piece_it;
+
+  // Maximum Dynamic Table Capacity in bytes
+  uint64_t maximum_dynamic_table_capacity = 0;
+  if (!absl::SimpleAtoi(*piece_it, &maximum_dynamic_table_capacity)) {
+    QUIC_LOG(ERROR) << "Error parsing part of input filename \"" << *piece_it
+                    << "\" as an integer.";
+    return false;
+  }
+  qpack_decoder_ = std::make_unique<QpackDecoder>(
+      maximum_dynamic_table_capacity, max_blocked_streams, this);
+  qpack_decoder_->set_qpack_stream_sender_delegate(
+      &decoder_stream_sender_delegate_);
+
+  // The initial dynamic table capacity is zero according to
+  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#eviction.
+  // However, for historical reasons, offline interop encoders use
+  // |maximum_dynamic_table_capacity| as initial capacity.
+  qpack_decoder_->OnSetDynamicTableCapacity(maximum_dynamic_table_capacity);
+
+  return true;
+}
+
+bool QpackOfflineDecoder::DecodeHeaderBlocksFromFile(
+    absl::string_view input_filename) {
+  // Store data in |input_data_storage|; use a absl::string_view to
+  // efficiently keep track of remaining portion yet to be decoded.
+  absl::optional<std::string> input_data_storage =
+      quiche::ReadFileContents(input_filename);
+  QUICHE_DCHECK(input_data_storage.has_value());
+  absl::string_view input_data(*input_data_storage);
+
+  while (!input_data.empty()) {
+    // Parse stream_id and length.
+    if (input_data.size() < sizeof(uint64_t) + sizeof(uint32_t)) {
+      QUIC_LOG(ERROR) << "Unexpected end of input file.";
+      return false;
+    }
+
+    uint64_t stream_id = quiche::QuicheEndian::NetToHost64(
+        *reinterpret_cast<const uint64_t*>(input_data.data()));
+    input_data = input_data.substr(sizeof(uint64_t));
+
+    uint32_t length = quiche::QuicheEndian::NetToHost32(
+        *reinterpret_cast<const uint32_t*>(input_data.data()));
+    input_data = input_data.substr(sizeof(uint32_t));
+
+    if (input_data.size() < length) {
+      QUIC_LOG(ERROR) << "Unexpected end of input file.";
+      return false;
+    }
+
+    // Parse data.
+    absl::string_view data = input_data.substr(0, length);
+    input_data = input_data.substr(length);
+
+    // Process data.
+    if (stream_id == 0) {
+      qpack_decoder_->encoder_stream_receiver()->Decode(data);
+
+      if (encoder_stream_error_detected_) {
+        QUIC_LOG(ERROR) << "Error detected on encoder stream.";
+        return false;
+      }
+    } else {
+      auto headers_handler = std::make_unique<test::TestHeadersHandler>();
+      auto progressive_decoder = qpack_decoder_->CreateProgressiveDecoder(
+          stream_id, headers_handler.get());
+
+      progressive_decoder->Decode(data);
+      progressive_decoder->EndHeaderBlock();
+
+      if (headers_handler->decoding_error_detected()) {
+        QUIC_LOG(ERROR) << "Sync decoding error on stream " << stream_id << ": "
+                        << headers_handler->error_message();
+        return false;
+      }
+
+      decoders_.push_back({std::move(headers_handler),
+                           std::move(progressive_decoder), stream_id});
+    }
+
+    // Move decoded header lists from TestHeadersHandlers and append them to
+    // |decoded_header_lists_| while preserving the order in |decoders_|.
+    while (!decoders_.empty() &&
+           decoders_.front().headers_handler->decoding_completed()) {
+      Decoder* decoder = &decoders_.front();
+
+      if (decoder->headers_handler->decoding_error_detected()) {
+        QUIC_LOG(ERROR) << "Async decoding error on stream "
+                        << decoder->stream_id << ": "
+                        << decoder->headers_handler->error_message();
+        return false;
+      }
+
+      if (!decoder->headers_handler->decoding_completed()) {
+        QUIC_LOG(ERROR) << "Decoding incomplete after reading entire"
+                           " file, on stream "
+                        << decoder->stream_id;
+        return false;
+      }
+
+      decoded_header_lists_.push_back(
+          decoder->headers_handler->ReleaseHeaderList());
+      decoders_.pop_front();
+    }
+  }
+
+  if (!decoders_.empty()) {
+    QUICHE_DCHECK(!decoders_.front().headers_handler->decoding_completed());
+
+    QUIC_LOG(ERROR) << "Blocked decoding uncomplete after reading entire"
+                       " file, on stream "
+                    << decoders_.front().stream_id;
+    return false;
+  }
+
+  return true;
+}
+
+bool QpackOfflineDecoder::VerifyDecodedHeaderLists(
+    absl::string_view expected_headers_filename) {
+  // Store data in |expected_headers_data_storage|; use a
+  // absl::string_view to efficiently keep track of remaining portion
+  // yet to be decoded.
+  absl::optional<std::string> expected_headers_data_storage =
+      quiche::ReadFileContents(expected_headers_filename);
+  QUICHE_DCHECK(expected_headers_data_storage.has_value());
+  absl::string_view expected_headers_data(*expected_headers_data_storage);
+
+  while (!decoded_header_lists_.empty()) {
+    spdy::Http2HeaderBlock decoded_header_list =
+        std::move(decoded_header_lists_.front());
+    decoded_header_lists_.pop_front();
+
+    spdy::Http2HeaderBlock expected_header_list;
+    if (!ReadNextExpectedHeaderList(&expected_headers_data,
+                                    &expected_header_list)) {
+      QUIC_LOG(ERROR)
+          << "Error parsing expected header list to match next decoded "
+             "header list.";
+      return false;
+    }
+
+    if (!CompareHeaderBlocks(std::move(decoded_header_list),
+                             std::move(expected_header_list))) {
+      QUIC_LOG(ERROR) << "Decoded header does not match expected header.";
+      return false;
+    }
+  }
+
+  if (!expected_headers_data.empty()) {
+    QUIC_LOG(ERROR)
+        << "Not enough encoded header lists to match expected ones.";
+    return false;
+  }
+
+  return true;
+}
+
+bool QpackOfflineDecoder::ReadNextExpectedHeaderList(
+    absl::string_view* expected_headers_data,
+    spdy::Http2HeaderBlock* expected_header_list) {
+  while (true) {
+    absl::string_view::size_type endline = expected_headers_data->find('\n');
+
+    // Even last header list must be followed by an empty line.
+    if (endline == absl::string_view::npos) {
+      QUIC_LOG(ERROR) << "Unexpected end of expected header list file.";
+      return false;
+    }
+
+    if (endline == 0) {
+      // Empty line indicates end of header list.
+      *expected_headers_data = expected_headers_data->substr(1);
+      return true;
+    }
+
+    absl::string_view header_field = expected_headers_data->substr(0, endline);
+    std::vector<absl::string_view> pieces = absl::StrSplit(header_field, '\t');
+
+    if (pieces.size() != 2) {
+      QUIC_LOG(ERROR) << "Header key and value must be separated by TAB.";
+      return false;
+    }
+
+    expected_header_list->AppendValueOrAddHeader(pieces[0], pieces[1]);
+
+    *expected_headers_data = expected_headers_data->substr(endline + 1);
+  }
+}
+
+bool QpackOfflineDecoder::CompareHeaderBlocks(
+    spdy::Http2HeaderBlock decoded_header_list,
+    spdy::Http2HeaderBlock expected_header_list) {
+  if (decoded_header_list == expected_header_list) {
+    return true;
+  }
+
+  // The h2o decoder reshuffles the "content-length" header and pseudo-headers,
+  // see
+  // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md.
+  // Remove such headers one by one if they match.
+  const char* kContentLength = "content-length";
+  const char* kPseudoHeaderPrefix = ":";
+  for (spdy::Http2HeaderBlock::iterator decoded_it =
+           decoded_header_list.begin();
+       decoded_it != decoded_header_list.end();) {
+    const absl::string_view key = decoded_it->first;
+    if (key != kContentLength && !absl::StartsWith(key, kPseudoHeaderPrefix)) {
+      ++decoded_it;
+      continue;
+    }
+    spdy::Http2HeaderBlock::iterator expected_it =
+        expected_header_list.find(key);
+    if (expected_it == expected_header_list.end() ||
+        decoded_it->second != expected_it->second) {
+      ++decoded_it;
+      continue;
+    }
+    // SpdyHeaderBlock does not support erasing by iterator, only by key.
+    ++decoded_it;
+    expected_header_list.erase(key);
+    // This will invalidate |key|.
+    decoded_header_list.erase(key);
+  }
+
+  return decoded_header_list == expected_header_list;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/test_tools/qpack/qpack_offline_decoder.h b/quiche/quic/test_tools/qpack/qpack_offline_decoder.h
new file mode 100644
index 0000000..71cb92a
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_offline_decoder.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
+
+#include <list>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_decoder.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/test_tools/qpack/qpack_decoder_test_utils.h"
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+// A decoder to read encoded data from a file, decode it, and compare to
+// a list of expected header lists read from another file.  File format is
+// described at
+// https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop.
+class QpackOfflineDecoder : public QpackDecoder::EncoderStreamErrorDelegate {
+ public:
+  QpackOfflineDecoder();
+  ~QpackOfflineDecoder() override = default;
+
+  // Read encoded header blocks and encoder stream data from |input_filename|
+  // and decode them, read expected header lists from
+  // |expected_headers_filename|, and compare decoded header lists to expected
+  // ones.  Returns true if there is an equal number of them and the
+  // corresponding ones match, false otherwise.
+  bool DecodeAndVerifyOfflineData(absl::string_view input_filename,
+                                  absl::string_view expected_headers_filename);
+
+  // QpackDecoder::EncoderStreamErrorDelegate implementation:
+  void OnEncoderStreamError(QuicErrorCode error_code,
+                            absl::string_view error_message) override;
+
+ private:
+  // Data structure to hold TestHeadersHandler and QpackProgressiveDecoder until
+  // decoding of a header header block (and all preceding header blocks) is
+  // complete.
+  struct Decoder {
+    std::unique_ptr<test::TestHeadersHandler> headers_handler;
+    std::unique_ptr<QpackProgressiveDecoder> progressive_decoder;
+    uint64_t stream_id;
+  };
+
+  // Parse decoder parameters from |input_filename| and set up |qpack_decoder_|
+  // accordingly.
+  bool ParseInputFilename(absl::string_view input_filename);
+
+  // Read encoded header blocks and encoder stream data from |input_filename|,
+  // pass them to |qpack_decoder_| for decoding, and add decoded header lists to
+  // |decoded_header_lists_|.
+  bool DecodeHeaderBlocksFromFile(absl::string_view input_filename);
+
+  // Read expected header lists from |expected_headers_filename| and verify
+  // decoded header lists in |decoded_header_lists_| against them.
+  bool VerifyDecodedHeaderLists(absl::string_view expected_headers_filename);
+
+  // Parse next header list from |*expected_headers_data| into
+  // |*expected_header_list|, removing consumed data from the beginning of
+  // |*expected_headers_data|.  Returns true on success, false if parsing fails.
+  bool ReadNextExpectedHeaderList(absl::string_view* expected_headers_data,
+                                  spdy::Http2HeaderBlock* expected_header_list);
+
+  // Compare two header lists.  Allow for different orders of certain headers as
+  // described at
+  // https://github.com/qpackers/qifs/blob/master/encoded/qpack-03/h2o/README.md.
+  bool CompareHeaderBlocks(spdy::Http2HeaderBlock decoded_header_list,
+                           spdy::Http2HeaderBlock expected_header_list);
+
+  bool encoder_stream_error_detected_;
+  test::NoopQpackStreamSenderDelegate decoder_stream_sender_delegate_;
+  std::unique_ptr<QpackDecoder> qpack_decoder_;
+
+  // Objects necessary for decoding, one list element for each header block.
+  std::list<Decoder> decoders_;
+
+  // Decoded header lists.
+  std::list<spdy::Http2HeaderBlock> decoded_header_lists_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_OFFLINE_DECODER_H_
diff --git a/quiche/quic/test_tools/qpack/qpack_test_utils.cc b/quiche/quic/test_tools/qpack/qpack_test_utils.cc
new file mode 100644
index 0000000..b6f5317
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_test_utils.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
+
+#include <limits>
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+namespace test {
+
+FragmentSizeGenerator FragmentModeToFragmentSizeGenerator(
+    FragmentMode fragment_mode) {
+  switch (fragment_mode) {
+    case FragmentMode::kSingleChunk:
+      return []() { return std::numeric_limits<size_t>::max(); };
+    case FragmentMode::kOctetByOctet:
+      return []() { return 1; };
+  }
+  QUIC_BUG(quic_bug_10259_1)
+      << "Unknown FragmentMode " << static_cast<int>(fragment_mode);
+  return []() { return 0; };
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/qpack/qpack_test_utils.h b/quiche/quic/test_tools/qpack/qpack_test_utils.h
new file mode 100644
index 0000000..c6f1c65
--- /dev/null
+++ b/quiche/quic/test_tools/qpack/qpack_test_utils.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
+#define QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
+
+#include <cstddef>
+#include <functional>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+// Called repeatedly to determine the size of each fragment when encoding or
+// decoding.  Must return a positive value.
+using FragmentSizeGenerator = std::function<size_t()>;
+
+enum class FragmentMode {
+  kSingleChunk,
+  kOctetByOctet,
+};
+
+FragmentSizeGenerator FragmentModeToFragmentSizeGenerator(
+    FragmentMode fragment_mode);
+
+// Mock QpackUnidirectionalStreamSenderDelegate implementation.
+class MockQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
+ public:
+  ~MockQpackStreamSenderDelegate() override = default;
+
+  MOCK_METHOD(void, WriteStreamData, (absl::string_view data), (override));
+  MOCK_METHOD(uint64_t, NumBytesBuffered, (), (const, override));
+};
+
+class NoopQpackStreamSenderDelegate : public QpackStreamSenderDelegate {
+ public:
+  ~NoopQpackStreamSenderDelegate() override = default;
+
+  void WriteStreamData(absl::string_view /*data*/) override {}
+
+  uint64_t NumBytesBuffered() const override { return 0; }
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QPACK_QPACK_TEST_UTILS_H_
diff --git a/quiche/quic/test_tools/quic_buffered_packet_store_peer.cc b/quiche/quic/test_tools/quic_buffered_packet_store_peer.cc
new file mode 100644
index 0000000..4d11806
--- /dev/null
+++ b/quiche/quic/test_tools/quic_buffered_packet_store_peer.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_buffered_packet_store_peer.h"
+
+#include "quiche/quic/core/quic_buffered_packet_store.h"
+
+namespace quic {
+namespace test {
+
+// static
+QuicAlarm* QuicBufferedPacketStorePeer::expiration_alarm(
+    QuicBufferedPacketStore* store) {
+  return store->expiration_alarm_.get();
+}
+
+// static
+void QuicBufferedPacketStorePeer::set_clock(QuicBufferedPacketStore* store,
+                                            const QuicClock* clock) {
+  store->clock_ = clock;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_buffered_packet_store_peer.h b/quiche/quic/test_tools/quic_buffered_packet_store_peer.h
new file mode 100644
index 0000000..0610274
--- /dev/null
+++ b/quiche/quic/test_tools/quic_buffered_packet_store_peer.h
@@ -0,0 +1,32 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
+
+#include <memory>
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_clock.h"
+
+namespace quic {
+
+class QuicBufferedPacketStore;
+
+namespace test {
+
+class QuicBufferedPacketStorePeer {
+ public:
+  QuicBufferedPacketStorePeer() = delete;
+
+  static QuicAlarm* expiration_alarm(QuicBufferedPacketStore* store);
+
+  static void set_clock(QuicBufferedPacketStore* store, const QuicClock* clock);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
diff --git a/quiche/quic/test_tools/quic_client_peer.cc b/quiche/quic/test_tools/quic_client_peer.cc
new file mode 100644
index 0000000..0b58e22
--- /dev/null
+++ b/quiche/quic/test_tools/quic_client_peer.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_client_peer.h"
+
+#include "quiche/quic/tools/quic_client.h"
+
+namespace quic {
+namespace test {
+
+// static
+bool QuicClientPeer::CreateUDPSocketAndBind(QuicClient* client) {
+  return client->network_helper()->CreateUDPSocketAndBind(
+      client->server_address(), client->bind_to_address(),
+      client->local_port());
+}
+
+// static
+void QuicClientPeer::CleanUpUDPSocket(QuicClient* client, int fd) {
+  client->epoll_network_helper()->CleanUpUDPSocket(fd);
+}
+
+// static
+void QuicClientPeer::SetClientPort(QuicClient* client, int port) {
+  client->epoll_network_helper()->SetClientPort(port);
+}
+
+// static
+void QuicClientPeer::SetWriter(QuicClient* client, QuicPacketWriter* writer) {
+  client->set_writer(writer);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quic/test_tools/quic_client_peer.h b/quiche/quic/test_tools/quic_client_peer.h
similarity index 100%
rename from quic/test_tools/quic_client_peer.h
rename to quiche/quic/test_tools/quic_client_peer.h
diff --git a/quiche/quic/test_tools/quic_client_promised_info_peer.cc b/quiche/quic/test_tools/quic_client_promised_info_peer.cc
new file mode 100644
index 0000000..5ea080c
--- /dev/null
+++ b/quiche/quic/test_tools/quic_client_promised_info_peer.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_client_promised_info_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+QuicAlarm* QuicClientPromisedInfoPeer::GetAlarm(
+    QuicClientPromisedInfo* promised_stream) {
+  return promised_stream->cleanup_alarm_.get();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_client_promised_info_peer.h b/quiche/quic/test_tools/quic_client_promised_info_peer.h
new file mode 100644
index 0000000..596200b
--- /dev/null
+++ b/quiche/quic/test_tools/quic_client_promised_info_peer.h
@@ -0,0 +1,22 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
+
+#include "quiche/quic/core/http/quic_client_promised_info.h"
+
+namespace quic {
+namespace test {
+
+class QuicClientPromisedInfoPeer {
+ public:
+  QuicClientPromisedInfoPeer() = delete;
+
+  static QuicAlarm* GetAlarm(QuicClientPromisedInfo* promised_stream);
+};
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_PROMISED_INFO_PEER_H_
diff --git a/quiche/quic/test_tools/quic_client_session_cache_peer.h b/quiche/quic/test_tools/quic_client_session_cache_peer.h
new file mode 100644
index 0000000..b070ef6
--- /dev/null
+++ b/quiche/quic/test_tools/quic_client_session_cache_peer.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
+
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+
+namespace quic {
+namespace test {
+
+class QuicClientSessionCachePeer {
+ public:
+  static std::string GetToken(QuicClientSessionCache* cache,
+                              const QuicServerId& server_id) {
+    auto iter = cache->cache_.Lookup(server_id);
+    if (iter == cache->cache_.end()) {
+      return {};
+    }
+    return iter->second->token;
+  }
+
+  static bool HasEntry(QuicClientSessionCache* cache,
+                       const QuicServerId& server_id) {
+    return cache->cache_.Lookup(server_id) != cache->cache_.end();
+  }
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CLIENT_SESSION_CACHE_PEER_H_
diff --git a/quiche/quic/test_tools/quic_coalesced_packet_peer.cc b/quiche/quic/test_tools/quic_coalesced_packet_peer.cc
new file mode 100644
index 0000000..eeb1621
--- /dev/null
+++ b/quiche/quic/test_tools/quic_coalesced_packet_peer.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_coalesced_packet_peer.h"
+
+namespace quic {
+namespace test {
+
+//  static
+void QuicCoalescedPacketPeer::SetMaxPacketLength(
+    QuicCoalescedPacket& coalesced_packet, QuicPacketLength length) {
+  coalesced_packet.max_packet_length_ = length;
+}
+
+//  static
+std::string* QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
+    QuicCoalescedPacket& coalesced_packet, EncryptionLevel encryption_level) {
+  return &coalesced_packet.encrypted_buffers_[encryption_level];
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_coalesced_packet_peer.h b/quiche/quic/test_tools/quic_coalesced_packet_peer.h
new file mode 100644
index 0000000..c84c37c
--- /dev/null
+++ b/quiche/quic/test_tools/quic_coalesced_packet_peer.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_COALESCED_PACKET_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_COALESCED_PACKET_PEER_H_
+
+#include "quiche/quic/core/quic_coalesced_packet.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+namespace test {
+
+class QuicCoalescedPacketPeer {
+ public:
+  static void SetMaxPacketLength(QuicCoalescedPacket& coalesced_packet,
+                                 QuicPacketLength length);
+
+  static std::string* GetMutableEncryptedBuffer(
+      QuicCoalescedPacket& coalesced_packet, EncryptionLevel encryption_level);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_COALESCED_PACKET_PEER_H_
diff --git a/quiche/quic/test_tools/quic_config_peer.cc b/quiche/quic/test_tools/quic_config_peer.cc
new file mode 100644
index 0000000..9d1b1be
--- /dev/null
+++ b/quiche/quic/test_tools/quic_config_peer.cc
@@ -0,0 +1,143 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_config_peer.h"
+
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_id.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
+    QuicConfig* config,
+    uint32_t window_bytes) {
+  config->initial_stream_flow_control_window_bytes_.SetReceivedValue(
+      window_bytes);
+}
+
+// static
+void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+    QuicConfig* config,
+    uint32_t window_bytes) {
+  config->initial_max_stream_data_bytes_incoming_bidirectional_
+      .SetReceivedValue(window_bytes);
+}
+
+// static
+void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+    QuicConfig* config,
+    uint32_t window_bytes) {
+  config->initial_max_stream_data_bytes_outgoing_bidirectional_
+      .SetReceivedValue(window_bytes);
+}
+
+// static
+void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+    QuicConfig* config,
+    uint32_t window_bytes) {
+  config->initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
+      window_bytes);
+}
+
+// static
+void QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+    QuicConfig* config,
+    uint32_t window_bytes) {
+  config->initial_session_flow_control_window_bytes_.SetReceivedValue(
+      window_bytes);
+}
+
+// static
+void QuicConfigPeer::SetReceivedConnectionOptions(
+    QuicConfig* config,
+    const QuicTagVector& options) {
+  config->connection_options_.SetReceivedValues(options);
+}
+
+// static
+void QuicConfigPeer::SetReceivedBytesForConnectionId(QuicConfig* config,
+                                                     uint32_t bytes) {
+  QUICHE_DCHECK(bytes == 0 || bytes == 8);
+  config->bytes_for_connection_id_.SetReceivedValue(bytes);
+}
+
+// static
+void QuicConfigPeer::SetReceivedDisableConnectionMigration(QuicConfig* config) {
+  config->connection_migration_disabled_.SetReceivedValue(1);
+}
+
+// static
+void QuicConfigPeer::SetReceivedMaxBidirectionalStreams(QuicConfig* config,
+                                                        uint32_t max_streams) {
+  config->max_bidirectional_streams_.SetReceivedValue(max_streams);
+}
+// static
+void QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(QuicConfig* config,
+                                                         uint32_t max_streams) {
+  config->max_unidirectional_streams_.SetReceivedValue(max_streams);
+}
+
+// static
+void QuicConfigPeer::SetConnectionOptionsToSend(QuicConfig* config,
+                                                const QuicTagVector& options) {
+  config->SetConnectionOptionsToSend(options);
+}
+
+// static
+void QuicConfigPeer::SetReceivedStatelessResetToken(
+    QuicConfig* config,
+    const StatelessResetToken& token) {
+  config->stateless_reset_token_.SetReceivedValue(token);
+}
+
+// static
+void QuicConfigPeer::SetReceivedMaxPacketSize(QuicConfig* config,
+                                              uint32_t max_udp_payload_size) {
+  config->max_udp_payload_size_.SetReceivedValue(max_udp_payload_size);
+}
+
+// static
+void QuicConfigPeer::SetReceivedMinAckDelayMs(QuicConfig* config,
+                                              uint32_t min_ack_delay_ms) {
+  config->min_ack_delay_ms_.SetReceivedValue(min_ack_delay_ms);
+}
+
+// static
+void QuicConfigPeer::SetNegotiated(QuicConfig* config, bool negotiated) {
+  config->negotiated_ = negotiated;
+}
+
+// static
+void QuicConfigPeer::SetReceivedOriginalConnectionId(
+    QuicConfig* config,
+    const QuicConnectionId& original_destination_connection_id) {
+  config->received_original_destination_connection_id_ =
+      original_destination_connection_id;
+}
+
+// static
+void QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+    QuicConfig* config,
+    const QuicConnectionId& initial_source_connection_id) {
+  config->received_initial_source_connection_id_ = initial_source_connection_id;
+}
+
+// static
+void QuicConfigPeer::SetReceivedRetrySourceConnectionId(
+    QuicConfig* config,
+    const QuicConnectionId& retry_source_connection_id) {
+  config->received_retry_source_connection_id_ = retry_source_connection_id;
+}
+
+// static
+void QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
+    QuicConfig* config,
+    uint64_t max_datagram_frame_size) {
+  config->max_datagram_frame_size_.SetReceivedValue(max_datagram_frame_size);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_config_peer.h b/quiche/quic/test_tools/quic_config_peer.h
new file mode 100644
index 0000000..ef106b0
--- /dev/null
+++ b/quiche/quic/test_tools/quic_config_peer.h
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
+
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QuicConfig;
+
+namespace test {
+
+class QuicConfigPeer {
+ public:
+  QuicConfigPeer() = delete;
+
+  static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config,
+                                                        uint32_t window_bytes);
+
+  static void SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+      QuicConfig* config,
+      uint32_t window_bytes);
+
+  static void SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+      QuicConfig* config,
+      uint32_t window_bytes);
+
+  static void SetReceivedInitialMaxStreamDataBytesUnidirectional(
+      QuicConfig* config,
+      uint32_t window_bytes);
+
+  static void SetReceivedInitialSessionFlowControlWindow(QuicConfig* config,
+                                                         uint32_t window_bytes);
+
+  static void SetReceivedConnectionOptions(QuicConfig* config,
+                                           const QuicTagVector& options);
+
+  static void SetReceivedBytesForConnectionId(QuicConfig* config,
+                                              uint32_t bytes);
+
+  static void SetReceivedDisableConnectionMigration(QuicConfig* config);
+
+  static void SetReceivedMaxBidirectionalStreams(QuicConfig* config,
+                                                 uint32_t max_streams);
+  static void SetReceivedMaxUnidirectionalStreams(QuicConfig* config,
+                                                  uint32_t max_streams);
+
+  static void SetConnectionOptionsToSend(QuicConfig* config,
+                                         const QuicTagVector& options);
+
+  static void SetReceivedStatelessResetToken(QuicConfig* config,
+                                             const StatelessResetToken& token);
+
+  static void SetReceivedMaxPacketSize(QuicConfig* config,
+                                       uint32_t max_udp_payload_size);
+
+  static void SetReceivedMinAckDelayMs(QuicConfig* config,
+                                       uint32_t min_ack_delay_ms);
+
+  static void SetNegotiated(QuicConfig* config, bool negotiated);
+
+  static void SetReceivedOriginalConnectionId(
+      QuicConfig* config,
+      const QuicConnectionId& original_destination_connection_id);
+
+  static void SetReceivedInitialSourceConnectionId(
+      QuicConfig* config,
+      const QuicConnectionId& initial_source_connection_id);
+
+  static void SetReceivedRetrySourceConnectionId(
+      QuicConfig* config,
+      const QuicConnectionId& retry_source_connection_id);
+
+  static void SetReceivedMaxDatagramFrameSize(QuicConfig* config,
+                                              uint64_t max_datagram_frame_size);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CONFIG_PEER_H_
diff --git a/quiche/quic/test_tools/quic_connection_id_manager_peer.h b/quiche/quic/test_tools/quic_connection_id_manager_peer.h
new file mode 100644
index 0000000..e7ac330
--- /dev/null
+++ b/quiche/quic/test_tools/quic_connection_id_manager_peer.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
+
+#include "quiche/quic/core/quic_connection_id_manager.h"
+
+namespace quic {
+namespace test {
+
+class QuicConnectionIdManagerPeer {
+ public:
+  static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
+      QuicPeerIssuedConnectionIdManager* manager) {
+    return manager->retire_connection_id_alarm_.get();
+  }
+
+  static QuicAlarm* GetRetireSelfIssuedConnectionIdAlarm(
+      QuicSelfIssuedConnectionIdManager* manager) {
+    return manager->retire_connection_id_alarm_.get();
+  }
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_ID_MANAGER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_connection_peer.cc b/quiche/quic/test_tools/quic_connection_peer.cc
new file mode 100644
index 0000000..73ec27c
--- /dev/null
+++ b/quiche/quic/test_tools/quic_connection_peer.cc
@@ -0,0 +1,550 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_received_packet_manager.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/test_tools/quic_connection_id_manager_peer.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicConnectionPeer::SetSendAlgorithm(
+    QuicConnection* connection,
+    SendAlgorithmInterface* send_algorithm) {
+  GetSentPacketManager(connection)->SetSendAlgorithm(send_algorithm);
+}
+
+// static
+void QuicConnectionPeer::SetLossAlgorithm(
+    QuicConnection* connection,
+    LossDetectionInterface* loss_algorithm) {
+  GetSentPacketManager(connection)->loss_algorithm_ = loss_algorithm;
+}
+
+// static
+void QuicConnectionPeer::PopulateStopWaitingFrame(
+    QuicConnection* connection,
+    QuicStopWaitingFrame* stop_waiting) {
+  connection->PopulateStopWaitingFrame(stop_waiting);
+}
+
+// static
+QuicPacketCreator* QuicConnectionPeer::GetPacketCreator(
+    QuicConnection* connection) {
+  return &connection->packet_creator_;
+}
+
+// static
+QuicSentPacketManager* QuicConnectionPeer::GetSentPacketManager(
+    QuicConnection* connection) {
+  return &connection->sent_packet_manager_;
+}
+
+// static
+QuicTime::Delta QuicConnectionPeer::GetNetworkTimeout(
+    QuicConnection* connection) {
+  return connection->idle_network_detector_.idle_network_timeout_;
+}
+
+// static
+QuicTime::Delta QuicConnectionPeer::GetHandshakeTimeout(
+    QuicConnection* connection) {
+  return connection->idle_network_detector_.handshake_timeout_;
+}
+
+// static
+void QuicConnectionPeer::SetPerspective(QuicConnection* connection,
+                                        Perspective perspective) {
+  connection->perspective_ = perspective;
+  QuicFramerPeer::SetPerspective(&connection->framer_, perspective);
+}
+
+// static
+void QuicConnectionPeer::SetSelfAddress(QuicConnection* connection,
+                                        const QuicSocketAddress& self_address) {
+  connection->default_path_.self_address = self_address;
+}
+
+// static
+void QuicConnectionPeer::SetPeerAddress(QuicConnection* connection,
+                                        const QuicSocketAddress& peer_address) {
+  connection->UpdatePeerAddress(peer_address);
+}
+
+// static
+void QuicConnectionPeer::SetDirectPeerAddress(
+    QuicConnection* connection,
+    const QuicSocketAddress& direct_peer_address) {
+  connection->direct_peer_address_ = direct_peer_address;
+}
+
+// static
+void QuicConnectionPeer::SetEffectivePeerAddress(
+    QuicConnection* connection,
+    const QuicSocketAddress& effective_peer_address) {
+  connection->default_path_.peer_address = effective_peer_address;
+}
+
+// static
+void QuicConnectionPeer::SwapCrypters(QuicConnection* connection,
+                                      QuicFramer* framer) {
+  QuicFramerPeer::SwapCrypters(framer, &connection->framer_);
+}
+
+// static
+void QuicConnectionPeer::SetCurrentPacket(QuicConnection* connection,
+                                          absl::string_view current_packet) {
+  connection->current_packet_data_ = current_packet.data();
+  connection->last_size_ = current_packet.size();
+}
+
+// static
+QuicConnectionHelperInterface* QuicConnectionPeer::GetHelper(
+    QuicConnection* connection) {
+  return connection->helper_;
+}
+
+// static
+QuicAlarmFactory* QuicConnectionPeer::GetAlarmFactory(
+    QuicConnection* connection) {
+  return connection->alarm_factory_;
+}
+
+// static
+QuicFramer* QuicConnectionPeer::GetFramer(QuicConnection* connection) {
+  return &connection->framer_;
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
+  return connection->ack_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
+  return connection->ping_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetRetransmissionAlarm(
+    QuicConnection* connection) {
+  return connection->retransmission_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetSendAlarm(QuicConnection* connection) {
+  return connection->send_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetMtuDiscoveryAlarm(
+    QuicConnection* connection) {
+  return connection->mtu_discovery_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(
+    QuicConnection* connection) {
+  return connection->process_undecryptable_packets_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(
+    QuicConnection* connection) {
+  return connection->discard_previous_one_rtt_keys_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(
+    QuicConnection* connection) {
+  return connection->discard_zero_rtt_decryption_keys_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetRetirePeerIssuedConnectionIdAlarm(
+    QuicConnection* connection) {
+  if (connection->peer_issued_cid_manager_ == nullptr) {
+    return nullptr;
+  }
+  return QuicConnectionIdManagerPeer::GetRetirePeerIssuedConnectionIdAlarm(
+      connection->peer_issued_cid_manager_.get());
+}
+// static
+QuicAlarm* QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(
+    QuicConnection* connection) {
+  if (connection->self_issued_cid_manager_ == nullptr) {
+    return nullptr;
+  }
+  return QuicConnectionIdManagerPeer::GetRetireSelfIssuedConnectionIdAlarm(
+      connection->self_issued_cid_manager_.get());
+}
+
+// static
+QuicPacketWriter* QuicConnectionPeer::GetWriter(QuicConnection* connection) {
+  return connection->writer_;
+}
+
+// static
+void QuicConnectionPeer::SetWriter(QuicConnection* connection,
+                                   QuicPacketWriter* writer,
+                                   bool owns_writer) {
+  if (connection->owns_writer_) {
+    delete connection->writer_;
+  }
+  connection->writer_ = writer;
+  connection->owns_writer_ = owns_writer;
+}
+
+// static
+void QuicConnectionPeer::TearDownLocalConnectionState(
+    QuicConnection* connection) {
+  connection->connected_ = false;
+}
+
+// static
+QuicEncryptedPacket* QuicConnectionPeer::GetConnectionClosePacket(
+    QuicConnection* connection) {
+  if (connection->termination_packets_ == nullptr ||
+      connection->termination_packets_->empty()) {
+    return nullptr;
+  }
+  return (*connection->termination_packets_)[0].get();
+}
+
+// static
+QuicPacketHeader* QuicConnectionPeer::GetLastHeader(
+    QuicConnection* connection) {
+  return &connection->last_header_;
+}
+
+// static
+QuicConnectionStats* QuicConnectionPeer::GetStats(QuicConnection* connection) {
+  return &connection->stats_;
+}
+
+// static
+QuicPacketCount QuicConnectionPeer::GetPacketsBetweenMtuProbes(
+    QuicConnection* connection) {
+  return connection->mtu_discoverer_.packets_between_probes();
+}
+
+// static
+void QuicConnectionPeer::ReInitializeMtuDiscoverer(
+    QuicConnection* connection,
+    QuicPacketCount packets_between_probes_base,
+    QuicPacketNumber next_probe_at) {
+  connection->mtu_discoverer_ =
+      QuicConnectionMtuDiscoverer(packets_between_probes_base, next_probe_at);
+}
+
+// static
+void QuicConnectionPeer::SetAckDecimationDelay(QuicConnection* connection,
+                                               float ack_decimation_delay) {
+  for (auto& received_packet_manager :
+       connection->uber_received_packet_manager_.received_packet_managers_) {
+    received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
+  }
+}
+
+// static
+bool QuicConnectionPeer::HasRetransmittableFrames(QuicConnection* connection,
+                                                  uint64_t packet_number) {
+  return QuicSentPacketManagerPeer::HasRetransmittableFrames(
+      GetSentPacketManager(connection), packet_number);
+}
+
+// static
+bool QuicConnectionPeer::GetNoStopWaitingFrames(QuicConnection* connection) {
+  return connection->no_stop_waiting_frames_;
+}
+
+// static
+void QuicConnectionPeer::SetNoStopWaitingFrames(QuicConnection* connection,
+                                                bool no_stop_waiting_frames) {
+  connection->no_stop_waiting_frames_ = no_stop_waiting_frames;
+}
+
+// static
+void QuicConnectionPeer::SetMaxTrackedPackets(
+    QuicConnection* connection,
+    QuicPacketCount max_tracked_packets) {
+  connection->max_tracked_packets_ = max_tracked_packets;
+}
+
+// static
+void QuicConnectionPeer::SetNegotiatedVersion(QuicConnection* connection) {
+  connection->version_negotiated_ = true;
+  if (connection->perspective() == Perspective::IS_SERVER &&
+      !QuicFramerPeer::infer_packet_header_type_from_version(
+          &connection->framer_)) {
+    connection->framer_.InferPacketHeaderTypeFromVersion();
+  }
+}
+
+// static
+void QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
+    QuicConnection* connection,
+    size_t new_value) {
+  connection->max_consecutive_num_packets_with_no_retransmittable_frames_ =
+      new_value;
+}
+
+// static
+bool QuicConnectionPeer::SupportsReleaseTime(QuicConnection* connection) {
+  return connection->supports_release_time_;
+}
+
+// static
+QuicConnection::PacketContent QuicConnectionPeer::GetCurrentPacketContent(
+    QuicConnection* connection) {
+  return connection->current_packet_content_;
+}
+
+// static
+void QuicConnectionPeer::SetLastHeaderFormat(QuicConnection* connection,
+                                             PacketHeaderFormat format) {
+  connection->last_header_.form = format;
+}
+
+// static
+void QuicConnectionPeer::AddBytesReceived(QuicConnection* connection,
+                                          size_t length) {
+  if (connection->EnforceAntiAmplificationLimit()) {
+    connection->default_path_.bytes_received_before_address_validation +=
+        length;
+  }
+}
+
+// static
+void QuicConnectionPeer::SetAddressValidated(QuicConnection* connection) {
+  connection->default_path_.validated = true;
+}
+
+// static
+void QuicConnectionPeer::SendConnectionClosePacket(
+    QuicConnection* connection,
+    QuicIetfTransportErrorCodes ietf_error,
+    QuicErrorCode error,
+    const std::string& details) {
+  connection->SendConnectionClosePacket(error, ietf_error, details);
+}
+
+// static
+size_t QuicConnectionPeer::GetNumEncryptionLevels(QuicConnection* connection) {
+  size_t count = 0;
+  for (EncryptionLevel level :
+       {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+        ENCRYPTION_FORWARD_SECURE}) {
+    if (connection->framer_.HasEncrypterOfEncryptionLevel(level)) {
+      ++count;
+    }
+  }
+  return count;
+}
+
+// static
+QuicNetworkBlackholeDetector& QuicConnectionPeer::GetBlackholeDetector(
+    QuicConnection* connection) {
+  return connection->blackhole_detector_;
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetBlackholeDetectorAlarm(
+    QuicConnection* connection) {
+  return connection->blackhole_detector_.alarm_.get();
+}
+
+// static
+QuicTime QuicConnectionPeer::GetPathDegradingDeadline(
+    QuicConnection* connection) {
+  return connection->blackhole_detector_.path_degrading_deadline_;
+}
+
+// static
+QuicTime QuicConnectionPeer::GetBlackholeDetectionDeadline(
+    QuicConnection* connection) {
+  return connection->blackhole_detector_.blackhole_deadline_;
+}
+
+// static
+QuicTime QuicConnectionPeer::GetPathMtuReductionDetectionDeadline(
+    QuicConnection* connection) {
+  return connection->blackhole_detector_.path_mtu_reduction_deadline_;
+}
+
+// static
+QuicTime QuicConnectionPeer::GetIdleNetworkDeadline(
+    QuicConnection* connection) {
+  return connection->idle_network_detector_.GetIdleNetworkDeadline();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetIdleNetworkDetectorAlarm(
+    QuicConnection* connection) {
+  return connection->idle_network_detector_.alarm_.get();
+}
+
+// static
+QuicIdleNetworkDetector& QuicConnectionPeer::GetIdleNetworkDetector(
+    QuicConnection* connection) {
+  return connection->idle_network_detector_;
+}
+
+// static
+void QuicConnectionPeer::SetServerConnectionId(
+    QuicConnection* connection,
+    const QuicConnectionId& server_connection_id) {
+  connection->default_path_.server_connection_id = server_connection_id;
+  connection->InstallInitialCrypters(server_connection_id);
+}
+
+// static
+size_t QuicConnectionPeer::NumUndecryptablePackets(QuicConnection* connection) {
+  return connection->undecryptable_packets_.size();
+}
+
+void QuicConnectionPeer::SetConnectionClose(QuicConnection* connection) {
+  connection->connected_ = false;
+}
+
+// static
+void QuicConnectionPeer::SendPing(QuicConnection* connection) {
+  connection->SendPingAtLevel(connection->encryption_level());
+}
+
+// static
+void QuicConnectionPeer::SetLastPacketDestinationAddress(
+    QuicConnection* connection,
+    const QuicSocketAddress& address) {
+  connection->last_received_packet_info_.destination_address = address;
+}
+
+// static
+QuicPathValidator* QuicConnectionPeer::path_validator(
+    QuicConnection* connection) {
+  return &connection->path_validator_;
+}
+
+//  static
+QuicByteCount QuicConnectionPeer::BytesSentOnAlternativePath(
+    QuicConnection* connection) {
+  return connection->alternative_path_.bytes_sent_before_address_validation;
+}
+
+//  static
+QuicByteCount QuicConnectionPeer::BytesReceivedOnAlternativePath(
+    QuicConnection* connection) {
+  return connection->alternative_path_.bytes_received_before_address_validation;
+}
+
+// static
+QuicConnectionId QuicConnectionPeer::GetClientConnectionIdOnAlternativePath(
+    const QuicConnection* connection) {
+  return connection->alternative_path_.client_connection_id;
+}
+
+// static
+QuicConnectionId QuicConnectionPeer::GetServerConnectionIdOnAlternativePath(
+    const QuicConnection* connection) {
+  return connection->alternative_path_.server_connection_id;
+}
+
+// static
+bool QuicConnectionPeer::IsAlternativePathValidated(
+    QuicConnection* connection) {
+  return connection->alternative_path_.validated;
+}
+
+// static
+bool QuicConnectionPeer::IsAlternativePath(
+    QuicConnection* connection,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address) {
+  return connection->IsAlternativePath(self_address, peer_address);
+}
+
+// static
+QuicByteCount QuicConnectionPeer::BytesReceivedBeforeAddressValidation(
+    QuicConnection* connection) {
+  return connection->default_path_.bytes_received_before_address_validation;
+}
+
+// static
+void QuicConnectionPeer::ResetPeerIssuedConnectionIdManager(
+    QuicConnection* connection) {
+  connection->peer_issued_cid_manager_ = nullptr;
+}
+
+// static
+QuicConnection::PathState* QuicConnectionPeer::GetDefaultPath(
+    QuicConnection* connection) {
+  return &connection->default_path_;
+}
+
+// static
+QuicConnection::PathState* QuicConnectionPeer::GetAlternativePath(
+    QuicConnection* connection) {
+  return &connection->alternative_path_;
+}
+
+// static
+void QuicConnectionPeer::RetirePeerIssuedConnectionIdsNoLongerOnPath(
+    QuicConnection* connection) {
+  connection->RetirePeerIssuedConnectionIdsNoLongerOnPath();
+}
+
+// static
+bool QuicConnectionPeer::HasUnusedPeerIssuedConnectionId(
+    const QuicConnection* connection) {
+  return connection->peer_issued_cid_manager_->HasUnusedConnectionId();
+}
+
+// static
+bool QuicConnectionPeer::HasSelfIssuedConnectionIdToConsume(
+    const QuicConnection* connection) {
+  return connection->self_issued_cid_manager_->HasConnectionIdToConsume();
+}
+
+// static
+QuicSelfIssuedConnectionIdManager*
+QuicConnectionPeer::GetSelfIssuedConnectionIdManager(
+    QuicConnection* connection) {
+  return connection->self_issued_cid_manager_.get();
+}
+
+// static
+std::unique_ptr<QuicSelfIssuedConnectionIdManager>
+QuicConnectionPeer::MakeSelfIssuedConnectionIdManager(
+    QuicConnection* connection) {
+  return connection->MakeSelfIssuedConnectionIdManager();
+}
+
+// static
+void QuicConnectionPeer::SetLastDecryptedLevel(QuicConnection* connection,
+                                               EncryptionLevel level) {
+  connection->last_decrypted_packet_level_ = level;
+}
+
+// static
+QuicCoalescedPacket& QuicConnectionPeer::GetCoalescedPacket(
+    QuicConnection* connection) {
+  return connection->coalesced_packet_;
+}
+
+// static
+void QuicConnectionPeer::FlushCoalescedPacket(QuicConnection* connection) {
+  connection->FlushCoalescedPacket();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_connection_peer.h b/quiche/quic/test_tools/quic_connection_peer.h
new file mode 100644
index 0000000..b9ca8a3
--- /dev/null
+++ b/quiche/quic/test_tools/quic_connection_peer.h
@@ -0,0 +1,233 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
+
+#include <cstddef>
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_connection_stats.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+struct QuicPacketHeader;
+class QuicAlarm;
+class QuicConnectionHelperInterface;
+class QuicConnectionVisitorInterface;
+class QuicEncryptedPacket;
+class QuicFramer;
+class QuicPacketCreator;
+class QuicPacketWriter;
+class QuicSentPacketManager;
+class SendAlgorithmInterface;
+
+namespace test {
+
+// Peer to make public a number of otherwise private QuicConnection methods.
+class QuicConnectionPeer {
+ public:
+  QuicConnectionPeer() = delete;
+
+  static void SetSendAlgorithm(QuicConnection* connection,
+                               SendAlgorithmInterface* send_algorithm);
+
+  static void SetLossAlgorithm(QuicConnection* connection,
+                               LossDetectionInterface* loss_algorithm);
+
+  static void PopulateStopWaitingFrame(QuicConnection* connection,
+                                       QuicStopWaitingFrame* stop_waiting);
+
+  static QuicPacketCreator* GetPacketCreator(QuicConnection* connection);
+
+  static QuicSentPacketManager* GetSentPacketManager(
+      QuicConnection* connection);
+
+  static QuicTime::Delta GetNetworkTimeout(QuicConnection* connection);
+
+  static QuicTime::Delta GetHandshakeTimeout(QuicConnection* connection);
+
+  static void SetPerspective(QuicConnection* connection,
+                             Perspective perspective);
+
+  static void SetSelfAddress(QuicConnection* connection,
+                             const QuicSocketAddress& self_address);
+
+  static void SetPeerAddress(QuicConnection* connection,
+                             const QuicSocketAddress& peer_address);
+
+  static void SetDirectPeerAddress(
+      QuicConnection* connection,
+      const QuicSocketAddress& direct_peer_address);
+
+  static void SetEffectivePeerAddress(
+      QuicConnection* connection,
+      const QuicSocketAddress& effective_peer_address);
+
+  static void SwapCrypters(QuicConnection* connection, QuicFramer* framer);
+
+  static void SetCurrentPacket(QuicConnection* connection,
+                               absl::string_view current_packet);
+
+  static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection);
+
+  static QuicAlarmFactory* GetAlarmFactory(QuicConnection* connection);
+
+  static QuicFramer* GetFramer(QuicConnection* connection);
+
+  static QuicAlarm* GetAckAlarm(QuicConnection* connection);
+  static QuicAlarm* GetPingAlarm(QuicConnection* connection);
+  static QuicAlarm* GetRetransmissionAlarm(QuicConnection* connection);
+  static QuicAlarm* GetSendAlarm(QuicConnection* connection);
+  static QuicAlarm* GetMtuDiscoveryAlarm(QuicConnection* connection);
+  static QuicAlarm* GetProcessUndecryptablePacketsAlarm(
+      QuicConnection* connection);
+  static QuicAlarm* GetDiscardPreviousOneRttKeysAlarm(
+      QuicConnection* connection);
+  static QuicAlarm* GetDiscardZeroRttDecryptionKeysAlarm(
+      QuicConnection* connection);
+  static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
+      QuicConnection* connection);
+  static QuicAlarm* GetRetireSelfIssuedConnectionIdAlarm(
+      QuicConnection* connection);
+
+  static QuicPacketWriter* GetWriter(QuicConnection* connection);
+  // If |owns_writer| is true, takes ownership of |writer|.
+  static void SetWriter(QuicConnection* connection,
+                        QuicPacketWriter* writer,
+                        bool owns_writer);
+  static void TearDownLocalConnectionState(QuicConnection* connection);
+  static QuicEncryptedPacket* GetConnectionClosePacket(
+      QuicConnection* connection);
+
+  static QuicPacketHeader* GetLastHeader(QuicConnection* connection);
+
+  static QuicConnectionStats* GetStats(QuicConnection* connection);
+
+  static QuicPacketCount GetPacketsBetweenMtuProbes(QuicConnection* connection);
+
+  static void ReInitializeMtuDiscoverer(
+      QuicConnection* connection,
+      QuicPacketCount packets_between_probes_base,
+      QuicPacketNumber next_probe_at);
+  static void SetAckDecimationDelay(QuicConnection* connection,
+                                    float ack_decimation_delay);
+  static bool HasRetransmittableFrames(QuicConnection* connection,
+                                       uint64_t packet_number);
+  static bool GetNoStopWaitingFrames(QuicConnection* connection);
+  static void SetNoStopWaitingFrames(QuicConnection* connection,
+                                     bool no_stop_waiting_frames);
+  static void SetMaxTrackedPackets(QuicConnection* connection,
+                                   QuicPacketCount max_tracked_packets);
+  static void SetNegotiatedVersion(QuicConnection* connection);
+  static void SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
+      QuicConnection* connection,
+      size_t new_value);
+  static bool SupportsReleaseTime(QuicConnection* connection);
+  static QuicConnection::PacketContent GetCurrentPacketContent(
+      QuicConnection* connection);
+  static void SetLastHeaderFormat(QuicConnection* connection,
+                                  PacketHeaderFormat format);
+  static void AddBytesReceived(QuicConnection* connection, size_t length);
+  static void SetAddressValidated(QuicConnection* connection);
+
+  static void SendConnectionClosePacket(QuicConnection* connection,
+                                        QuicIetfTransportErrorCodes ietf_error,
+                                        QuicErrorCode error,
+                                        const std::string& details);
+
+  static size_t GetNumEncryptionLevels(QuicConnection* connection);
+
+  static QuicNetworkBlackholeDetector& GetBlackholeDetector(
+      QuicConnection* connection);
+
+  static QuicAlarm* GetBlackholeDetectorAlarm(QuicConnection* connection);
+
+  static QuicTime GetPathDegradingDeadline(QuicConnection* connection);
+
+  static QuicTime GetBlackholeDetectionDeadline(QuicConnection* connection);
+
+  static QuicTime GetPathMtuReductionDetectionDeadline(
+      QuicConnection* connection);
+
+  static QuicAlarm* GetIdleNetworkDetectorAlarm(QuicConnection* connection);
+
+  static QuicTime GetIdleNetworkDeadline(QuicConnection* connection);
+
+  static QuicIdleNetworkDetector& GetIdleNetworkDetector(
+      QuicConnection* connection);
+
+  static void SetServerConnectionId(
+      QuicConnection* connection,
+      const QuicConnectionId& server_connection_id);
+
+  static size_t NumUndecryptablePackets(QuicConnection* connection);
+
+  static void SetConnectionClose(QuicConnection* connection);
+
+  static void SendPing(QuicConnection* connection);
+
+  static void SetLastPacketDestinationAddress(QuicConnection* connection,
+                                              const QuicSocketAddress& address);
+
+  static QuicPathValidator* path_validator(QuicConnection* connection);
+
+  static QuicByteCount BytesSentOnAlternativePath(QuicConnection* connection);
+
+  static QuicByteCount BytesReceivedOnAlternativePath(
+      QuicConnection* connection);
+
+  static QuicConnectionId GetClientConnectionIdOnAlternativePath(
+      const QuicConnection* connection);
+
+  static QuicConnectionId GetServerConnectionIdOnAlternativePath(
+      const QuicConnection* connection);
+
+  static bool IsAlternativePath(QuicConnection* connection,
+                                const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address);
+
+  static bool IsAlternativePathValidated(QuicConnection* connection);
+
+  static QuicByteCount BytesReceivedBeforeAddressValidation(
+      QuicConnection* connection);
+
+  static void ResetPeerIssuedConnectionIdManager(QuicConnection* connection);
+
+  static QuicConnection::PathState* GetDefaultPath(QuicConnection* connection);
+
+  static QuicConnection::PathState* GetAlternativePath(
+      QuicConnection* connection);
+
+  static void RetirePeerIssuedConnectionIdsNoLongerOnPath(
+      QuicConnection* connection);
+
+  static bool HasUnusedPeerIssuedConnectionId(const QuicConnection* connection);
+
+  static bool HasSelfIssuedConnectionIdToConsume(
+      const QuicConnection* connection);
+
+  static QuicSelfIssuedConnectionIdManager* GetSelfIssuedConnectionIdManager(
+      QuicConnection* connection);
+
+  static std::unique_ptr<QuicSelfIssuedConnectionIdManager>
+  MakeSelfIssuedConnectionIdManager(QuicConnection* connection);
+
+  static void SetLastDecryptedLevel(QuicConnection* connection,
+                                    EncryptionLevel level);
+
+  static QuicCoalescedPacket& GetCoalescedPacket(QuicConnection* connection);
+
+  static void FlushCoalescedPacket(QuicConnection* connection);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CONNECTION_PEER_H_
diff --git a/quiche/quic/test_tools/quic_crypto_server_config_peer.cc b/quiche/quic/test_tools/quic_crypto_server_config_peer.cc
new file mode 100644
index 0000000..f09c0cf
--- /dev/null
+++ b/quiche/quic/test_tools/quic_crypto_server_config_peer.cc
@@ -0,0 +1,160 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+QuicCryptoServerConfigPeer::GetPrimaryConfig() {
+  QuicReaderMutexLock locked(&server_config_->configs_lock_);
+  return quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>(
+      server_config_->primary_config_);
+}
+
+quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+QuicCryptoServerConfigPeer::GetConfig(std::string config_id) {
+  QuicReaderMutexLock locked(&server_config_->configs_lock_);
+  if (config_id == "<primary>") {
+    return quiche::QuicheReferenceCountedPointer<
+        QuicCryptoServerConfig::Config>(server_config_->primary_config_);
+  } else {
+    return server_config_->GetConfigWithScid(config_id);
+  }
+}
+
+ProofSource* QuicCryptoServerConfigPeer::GetProofSource() const {
+  return server_config_->proof_source_.get();
+}
+
+void QuicCryptoServerConfigPeer::ResetProofSource(
+    std::unique_ptr<ProofSource> proof_source) {
+  server_config_->proof_source_ = std::move(proof_source);
+}
+
+std::string QuicCryptoServerConfigPeer::NewSourceAddressToken(
+    std::string config_id,
+    SourceAddressTokens previous_tokens,
+    const QuicIpAddress& ip,
+    QuicRandom* rand,
+    QuicWallTime now,
+    CachedNetworkParameters* cached_network_params) {
+  return server_config_->NewSourceAddressToken(
+      *GetConfig(config_id)->source_address_token_boxer, previous_tokens, ip,
+      rand, now, cached_network_params);
+}
+
+HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSourceAddressTokens(
+    std::string config_id,
+    absl::string_view srct,
+    const QuicIpAddress& ip,
+    QuicWallTime now,
+    CachedNetworkParameters* cached_network_params) {
+  SourceAddressTokens tokens;
+  HandshakeFailureReason reason = server_config_->ParseSourceAddressToken(
+      *GetConfig(config_id)->source_address_token_boxer, srct, tokens);
+  if (reason != HANDSHAKE_OK) {
+    return reason;
+  }
+
+  return server_config_->ValidateSourceAddressTokens(tokens, ip, now,
+                                                     cached_network_params);
+}
+
+HandshakeFailureReason
+QuicCryptoServerConfigPeer::ValidateSingleSourceAddressToken(
+    absl::string_view token,
+    const QuicIpAddress& ip,
+    QuicWallTime now) {
+  SourceAddressTokens tokens;
+  HandshakeFailureReason parse_status = server_config_->ParseSourceAddressToken(
+      *GetPrimaryConfig()->source_address_token_boxer, token, tokens);
+  if (HANDSHAKE_OK != parse_status) {
+    return parse_status;
+  }
+  EXPECT_EQ(1, tokens.tokens_size());
+  return server_config_->ValidateSingleSourceAddressToken(tokens.tokens(0), ip,
+                                                          now);
+}
+
+void QuicCryptoServerConfigPeer::CheckConfigs(
+    std::vector<std::pair<std::string, bool>> expected_ids_and_status) {
+  QuicReaderMutexLock locked(&server_config_->configs_lock_);
+
+  ASSERT_EQ(expected_ids_and_status.size(), server_config_->configs_.size())
+      << ConfigsDebug();
+
+  for (const std::pair<const ServerConfigID,
+                       quiche::QuicheReferenceCountedPointer<
+                           QuicCryptoServerConfig::Config>>& i :
+       server_config_->configs_) {
+    bool found = false;
+    for (std::pair<ServerConfigID, bool>& j : expected_ids_and_status) {
+      if (i.first == j.first && i.second->is_primary == j.second) {
+        found = true;
+        j.first.clear();
+        break;
+      }
+    }
+
+    ASSERT_TRUE(found) << "Failed to find match for " << i.first
+                       << " in configs:\n"
+                       << ConfigsDebug();
+  }
+}
+
+// ConfigsDebug returns a std::string that contains debugging information about
+// the set of Configs loaded in |server_config_| and their status.
+std::string QuicCryptoServerConfigPeer::ConfigsDebug() {
+  if (server_config_->configs_.empty()) {
+    return "No Configs in QuicCryptoServerConfig";
+  }
+
+  std::string s;
+
+  for (const auto& i : server_config_->configs_) {
+    const quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+        config = i.second;
+    if (config->is_primary) {
+      s += "(primary) ";
+    } else {
+      s += "          ";
+    }
+    s += config->id;
+    s += "\n";
+  }
+
+  return s;
+}
+
+void QuicCryptoServerConfigPeer::SelectNewPrimaryConfig(int seconds) {
+  QuicWriterMutexLock locked(&server_config_->configs_lock_);
+  server_config_->SelectNewPrimaryConfig(
+      QuicWallTime::FromUNIXSeconds(seconds));
+}
+
+std::string QuicCryptoServerConfigPeer::CompressChain(
+    QuicCompressedCertsCache* compressed_certs_cache,
+    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+    const std::string& client_cached_cert_hashes) {
+  return QuicCryptoServerConfig::CompressChain(compressed_certs_cache, chain,
+                                               client_cached_cert_hashes);
+}
+
+uint32_t QuicCryptoServerConfigPeer::source_address_token_future_secs() {
+  return server_config_->source_address_token_future_secs_;
+}
+
+uint32_t QuicCryptoServerConfigPeer::source_address_token_lifetime_secs() {
+  return server_config_->source_address_token_lifetime_secs_;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_crypto_server_config_peer.h b/quiche/quic/test_tools/quic_crypto_server_config_peer.h
new file mode 100644
index 0000000..463a403
--- /dev/null
+++ b/quiche/quic/test_tools/quic_crypto_server_config_peer.h
@@ -0,0 +1,93 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+
+namespace quic {
+namespace test {
+
+// Peer for accessing otherwise private members of a QuicCryptoServerConfig.
+class QuicCryptoServerConfigPeer {
+ public:
+  explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
+      : server_config_(server_config) {}
+
+  // Returns the primary config.
+  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+  GetPrimaryConfig();
+
+  // Returns the config associated with |config_id|.
+  quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
+  GetConfig(std::string config_id);
+
+  // Returns a pointer to the ProofSource object.
+  ProofSource* GetProofSource() const;
+
+  // Reset the proof_source_ member.
+  void ResetProofSource(std::unique_ptr<ProofSource> proof_source);
+
+  // Generates a new valid source address token.
+  std::string NewSourceAddressToken(
+      std::string config_id,
+      SourceAddressTokens previous_tokens,
+      const QuicIpAddress& ip,
+      QuicRandom* rand,
+      QuicWallTime now,
+      CachedNetworkParameters* cached_network_params);
+
+  // Attempts to validate the tokens in |srct|.
+  HandshakeFailureReason ValidateSourceAddressTokens(
+      std::string config_id, absl::string_view srct, const QuicIpAddress& ip,
+      QuicWallTime now, CachedNetworkParameters* cached_network_params);
+
+  // Attempts to validate the single source address token in |token|.
+  HandshakeFailureReason ValidateSingleSourceAddressToken(
+      absl::string_view token,
+      const QuicIpAddress& ip,
+      QuicWallTime now);
+
+  // CheckConfigs compares the state of the Configs in |server_config_| to the
+  // description given as arguments.
+  // The first of each pair is the server config ID of a Config. The second is a
+  // boolean describing whether the config is the primary. For example:
+  //   CheckConfigs(std::vector<std::pair<ServerConfigID, bool>>());  // checks
+  //   that no Configs are loaded.
+  //
+  //   // Checks that exactly three Configs are loaded with the given IDs and
+  //   // status.
+  //   CheckConfigs(
+  //     {{"id1", false},
+  //      {"id2", true},
+  //      {"id3", false}});
+  void CheckConfigs(
+      std::vector<std::pair<ServerConfigID, bool>> expected_ids_and_status);
+
+  // ConfigsDebug returns a std::string that contains debugging information
+  // about the set of Configs loaded in |server_config_| and their status.
+  std::string ConfigsDebug()
+      QUIC_SHARED_LOCKS_REQUIRED(server_config_->configs_lock_);
+
+  void SelectNewPrimaryConfig(int seconds);
+
+  static std::string CompressChain(
+      QuicCompressedCertsCache* compressed_certs_cache,
+      const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
+      const std::string& client_cached_cert_hashes);
+
+  uint32_t source_address_token_future_secs();
+
+  uint32_t source_address_token_lifetime_secs();
+
+ private:
+  QuicCryptoServerConfig* server_config_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_CRYPTO_SERVER_CONFIG_PEER_H_
diff --git a/quiche/quic/test_tools/quic_dispatcher_peer.cc b/quiche/quic/test_tools/quic_dispatcher_peer.cc
new file mode 100644
index 0000000..e281952
--- /dev/null
+++ b/quiche/quic/test_tools/quic_dispatcher_peer.cc
@@ -0,0 +1,143 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+
+namespace quic {
+namespace test {
+
+// static
+QuicTimeWaitListManager* QuicDispatcherPeer::GetTimeWaitListManager(
+    QuicDispatcher* dispatcher) {
+  return dispatcher->time_wait_list_manager_.get();
+}
+
+// static
+void QuicDispatcherPeer::SetTimeWaitListManager(
+    QuicDispatcher* dispatcher,
+    QuicTimeWaitListManager* time_wait_list_manager) {
+  dispatcher->time_wait_list_manager_.reset(time_wait_list_manager);
+}
+
+// static
+void QuicDispatcherPeer::UseWriter(QuicDispatcher* dispatcher,
+                                   QuicPacketWriterWrapper* writer) {
+  writer->set_writer(dispatcher->writer_.release());
+  dispatcher->writer_.reset(writer);
+}
+
+// static
+QuicPacketWriter* QuicDispatcherPeer::GetWriter(QuicDispatcher* dispatcher) {
+  return dispatcher->writer_.get();
+}
+
+// static
+QuicCompressedCertsCache* QuicDispatcherPeer::GetCache(
+    QuicDispatcher* dispatcher) {
+  return dispatcher->compressed_certs_cache();
+}
+
+// static
+QuicConnectionHelperInterface* QuicDispatcherPeer::GetHelper(
+    QuicDispatcher* dispatcher) {
+  return dispatcher->helper_.get();
+}
+
+// static
+QuicAlarmFactory* QuicDispatcherPeer::GetAlarmFactory(
+    QuicDispatcher* dispatcher) {
+  return dispatcher->alarm_factory_.get();
+}
+
+// static
+QuicDispatcher::WriteBlockedList* QuicDispatcherPeer::GetWriteBlockedList(
+    QuicDispatcher* dispatcher) {
+  return &dispatcher->write_blocked_list_;
+}
+
+// static
+QuicErrorCode QuicDispatcherPeer::GetAndClearLastError(
+    QuicDispatcher* dispatcher) {
+  QuicErrorCode ret = dispatcher->last_error_;
+  dispatcher->last_error_ = QUIC_NO_ERROR;
+  return ret;
+}
+
+// static
+QuicBufferedPacketStore* QuicDispatcherPeer::GetBufferedPackets(
+    QuicDispatcher* dispatcher) {
+  return &(dispatcher->buffered_packets_);
+}
+
+// static
+void QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
+    QuicDispatcher* dispatcher,
+    size_t num_session_allowed) {
+  dispatcher->new_sessions_allowed_per_event_loop_ = num_session_allowed;
+}
+
+// static
+void QuicDispatcherPeer::SendPublicReset(
+    QuicDispatcher* dispatcher,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    QuicConnectionId connection_id,
+    bool ietf_quic,
+    size_t received_packet_length,
+    std::unique_ptr<QuicPerPacketContext> packet_context) {
+  dispatcher->time_wait_list_manager()->SendPublicReset(
+      self_address, peer_address, connection_id, ietf_quic,
+      received_packet_length, std::move(packet_context));
+}
+
+// static
+std::unique_ptr<QuicPerPacketContext> QuicDispatcherPeer::GetPerPacketContext(
+    QuicDispatcher* dispatcher) {
+  return dispatcher->GetPerPacketContext();
+}
+
+// static
+void QuicDispatcherPeer::RestorePerPacketContext(
+    QuicDispatcher* dispatcher,
+    std::unique_ptr<QuicPerPacketContext> context) {
+  dispatcher->RestorePerPacketContext(std::move(context));
+}
+
+// static
+std::string QuicDispatcherPeer::SelectAlpn(
+    QuicDispatcher* dispatcher,
+    const std::vector<std::string>& alpns) {
+  return dispatcher->SelectAlpn(alpns);
+}
+
+// static
+QuicSession* QuicDispatcherPeer::GetFirstSessionIfAny(
+    QuicDispatcher* dispatcher) {
+  if (dispatcher->reference_counted_session_map_.empty()) {
+    return nullptr;
+  }
+  return dispatcher->reference_counted_session_map_.begin()->second.get();
+}
+
+// static
+const QuicSession* QuicDispatcherPeer::FindSession(
+    const QuicDispatcher* dispatcher,
+    QuicConnectionId id) {
+  auto it = dispatcher->reference_counted_session_map_.find(id);
+  return (it == dispatcher->reference_counted_session_map_.end())
+             ? nullptr
+             : it->second.get();
+}
+
+// static
+QuicAlarm* QuicDispatcherPeer::GetClearResetAddressesAlarm(
+    QuicDispatcher* dispatcher) {
+  return dispatcher->clear_stateless_reset_addresses_alarm_.get();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_dispatcher_peer.h b/quiche/quic/test_tools/quic_dispatcher_peer.h
new file mode 100644
index 0000000..57c3c83
--- /dev/null
+++ b/quiche/quic/test_tools/quic_dispatcher_peer.h
@@ -0,0 +1,86 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
+
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+
+namespace quic {
+
+class QuicPacketWriterWrapper;
+
+namespace test {
+
+class QuicDispatcherPeer {
+ public:
+  QuicDispatcherPeer() = delete;
+
+  static QuicTimeWaitListManager* GetTimeWaitListManager(
+      QuicDispatcher* dispatcher);
+
+  static void SetTimeWaitListManager(
+      QuicDispatcher* dispatcher,
+      QuicTimeWaitListManager* time_wait_list_manager);
+
+  // Injects |writer| into |dispatcher| as the shared writer.
+  static void UseWriter(QuicDispatcher* dispatcher,
+                        QuicPacketWriterWrapper* writer);
+
+  static QuicPacketWriter* GetWriter(QuicDispatcher* dispatcher);
+
+  static QuicCompressedCertsCache* GetCache(QuicDispatcher* dispatcher);
+
+  static QuicConnectionHelperInterface* GetHelper(QuicDispatcher* dispatcher);
+
+  static QuicAlarmFactory* GetAlarmFactory(QuicDispatcher* dispatcher);
+
+  static QuicDispatcher::WriteBlockedList* GetWriteBlockedList(
+      QuicDispatcher* dispatcher);
+
+  // Get the dispatcher's record of the last error reported to its framer
+  // visitor's OnError() method.  Then set that record to QUIC_NO_ERROR.
+  static QuicErrorCode GetAndClearLastError(QuicDispatcher* dispatcher);
+
+  static QuicBufferedPacketStore* GetBufferedPackets(
+      QuicDispatcher* dispatcher);
+
+  static void set_new_sessions_allowed_per_event_loop(
+      QuicDispatcher* dispatcher,
+      size_t num_session_allowed);
+
+  static void SendPublicReset(
+      QuicDispatcher* dispatcher,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address,
+      QuicConnectionId connection_id,
+      bool ietf_quic,
+      size_t received_packet_length,
+      std::unique_ptr<QuicPerPacketContext> packet_context);
+
+  static std::unique_ptr<QuicPerPacketContext> GetPerPacketContext(
+      QuicDispatcher* dispatcher);
+
+  static void RestorePerPacketContext(QuicDispatcher* dispatcher,
+                                      std::unique_ptr<QuicPerPacketContext>);
+
+  static std::string SelectAlpn(QuicDispatcher* dispatcher,
+                                const std::vector<std::string>& alpns);
+
+  // Get the first session in the session map. Returns nullptr if the map is
+  // empty.
+  static QuicSession* GetFirstSessionIfAny(QuicDispatcher* dispatcher);
+
+  // Find the corresponding session if exsits.
+  static const QuicSession* FindSession(const QuicDispatcher* dispatcher,
+                                        QuicConnectionId id);
+
+  static QuicAlarm* GetClearResetAddressesAlarm(QuicDispatcher* dispatcher);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_DISPATCHER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_flow_controller_peer.cc b/quiche/quic/test_tools/quic_flow_controller_peer.cc
new file mode 100644
index 0000000..1356082
--- /dev/null
+++ b/quiche/quic/test_tools/quic_flow_controller_peer.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+
+#include <list>
+
+#include "quiche/quic/core/quic_flow_controller.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicFlowControllerPeer::SetSendWindowOffset(
+    QuicFlowController* flow_controller,
+    QuicStreamOffset offset) {
+  flow_controller->send_window_offset_ = offset;
+}
+
+// static
+void QuicFlowControllerPeer::SetReceiveWindowOffset(
+    QuicFlowController* flow_controller,
+    QuicStreamOffset offset) {
+  flow_controller->receive_window_offset_ = offset;
+}
+
+// static
+void QuicFlowControllerPeer::SetMaxReceiveWindow(
+    QuicFlowController* flow_controller,
+    QuicByteCount window_size) {
+  flow_controller->receive_window_size_ = window_size;
+}
+
+// static
+QuicStreamOffset QuicFlowControllerPeer::SendWindowOffset(
+    QuicFlowController* flow_controller) {
+  return flow_controller->send_window_offset_;
+}
+
+// static
+QuicByteCount QuicFlowControllerPeer::SendWindowSize(
+    QuicFlowController* flow_controller) {
+  return flow_controller->SendWindowSize();
+}
+
+// static
+QuicStreamOffset QuicFlowControllerPeer::ReceiveWindowOffset(
+    QuicFlowController* flow_controller) {
+  return flow_controller->receive_window_offset_;
+}
+
+// static
+QuicByteCount QuicFlowControllerPeer::ReceiveWindowSize(
+    QuicFlowController* flow_controller) {
+  return flow_controller->receive_window_offset_ -
+         flow_controller->highest_received_byte_offset_;
+}
+
+// static
+QuicByteCount QuicFlowControllerPeer::WindowUpdateThreshold(
+    QuicFlowController* flow_controller) {
+  return flow_controller->WindowUpdateThreshold();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_flow_controller_peer.h b/quiche/quic/test_tools/quic_flow_controller_peer.h
new file mode 100644
index 0000000..7c5e426
--- /dev/null
+++ b/quiche/quic/test_tools/quic_flow_controller_peer.h
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+class QuicFlowController;
+
+namespace test {
+
+class QuicFlowControllerPeer {
+ public:
+  QuicFlowControllerPeer() = delete;
+
+  static void SetSendWindowOffset(QuicFlowController* flow_controller,
+                                  QuicStreamOffset offset);
+
+  static void SetReceiveWindowOffset(QuicFlowController* flow_controller,
+                                     QuicStreamOffset offset);
+
+  static void SetMaxReceiveWindow(QuicFlowController* flow_controller,
+                                  QuicByteCount window_size);
+
+  static QuicStreamOffset SendWindowOffset(QuicFlowController* flow_controller);
+
+  static QuicByteCount SendWindowSize(QuicFlowController* flow_controller);
+
+  static QuicStreamOffset ReceiveWindowOffset(
+      QuicFlowController* flow_controller);
+
+  static QuicByteCount ReceiveWindowSize(QuicFlowController* flow_controller);
+
+  static QuicByteCount WindowUpdateThreshold(
+      QuicFlowController* flow_controller);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_FLOW_CONTROLLER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_framer_peer.cc b/quiche/quic/test_tools/quic_framer_peer.cc
new file mode 100644
index 0000000..60ccff8
--- /dev/null
+++ b/quiche/quic/test_tools/quic_framer_peer.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+namespace test {
+
+// static
+uint64_t QuicFramerPeer::CalculatePacketNumberFromWire(
+    QuicFramer* framer,
+    QuicPacketNumberLength packet_number_length,
+    QuicPacketNumber last_packet_number,
+    uint64_t packet_number) {
+  return framer->CalculatePacketNumberFromWire(
+      packet_number_length, last_packet_number, packet_number);
+}
+
+// static
+void QuicFramerPeer::SetLastSerializedServerConnectionId(
+    QuicFramer* framer,
+    QuicConnectionId server_connection_id) {
+  framer->last_serialized_server_connection_id_ = server_connection_id;
+}
+
+// static
+void QuicFramerPeer::SetLastSerializedClientConnectionId(
+    QuicFramer* framer,
+    QuicConnectionId client_connection_id) {
+  framer->last_serialized_client_connection_id_ = client_connection_id;
+}
+
+// static
+void QuicFramerPeer::SetLastWrittenPacketNumberLength(
+    QuicFramer* framer,
+    size_t packet_number_length) {
+  framer->last_written_packet_number_length_ = packet_number_length;
+}
+
+// static
+void QuicFramerPeer::SetLargestPacketNumber(QuicFramer* framer,
+                                            QuicPacketNumber packet_number) {
+  framer->largest_packet_number_ = packet_number;
+}
+
+// static
+void QuicFramerPeer::SetPerspective(QuicFramer* framer,
+                                    Perspective perspective) {
+  framer->perspective_ = perspective;
+  framer->infer_packet_header_type_from_version_ =
+      perspective == Perspective::IS_CLIENT;
+}
+
+// static
+void QuicFramerPeer::SwapCrypters(QuicFramer* framer1, QuicFramer* framer2) {
+  for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; i++) {
+    framer1->encrypter_[i].swap(framer2->encrypter_[i]);
+    framer1->decrypter_[i].swap(framer2->decrypter_[i]);
+  }
+
+  EncryptionLevel framer2_level = framer2->decrypter_level_;
+  framer2->decrypter_level_ = framer1->decrypter_level_;
+  framer1->decrypter_level_ = framer2_level;
+  framer2_level = framer2->alternative_decrypter_level_;
+  framer2->alternative_decrypter_level_ = framer1->alternative_decrypter_level_;
+  framer1->alternative_decrypter_level_ = framer2_level;
+
+  const bool framer2_latch = framer2->alternative_decrypter_latch_;
+  framer2->alternative_decrypter_latch_ = framer1->alternative_decrypter_latch_;
+  framer1->alternative_decrypter_latch_ = framer2_latch;
+}
+
+// static
+QuicEncrypter* QuicFramerPeer::GetEncrypter(QuicFramer* framer,
+                                            EncryptionLevel level) {
+  return framer->encrypter_[level].get();
+}
+
+// static
+QuicDecrypter* QuicFramerPeer::GetDecrypter(QuicFramer* framer,
+                                            EncryptionLevel level) {
+  return framer->decrypter_[level].get();
+}
+
+// static
+void QuicFramerPeer::SetFirstSendingPacketNumber(QuicFramer* framer,
+                                                 uint64_t packet_number) {
+  *const_cast<QuicPacketNumber*>(&framer->first_sending_packet_number_) =
+      QuicPacketNumber(packet_number);
+}
+
+// static
+void QuicFramerPeer::SetExpectedServerConnectionIDLength(
+    QuicFramer* framer,
+    uint8_t expected_server_connection_id_length) {
+  *const_cast<uint8_t*>(&framer->expected_server_connection_id_length_) =
+      expected_server_connection_id_length;
+}
+
+// static
+QuicPacketNumber QuicFramerPeer::GetLargestDecryptedPacketNumber(
+    QuicFramer* framer,
+    PacketNumberSpace packet_number_space) {
+  return framer->largest_decrypted_packet_numbers_[packet_number_space];
+}
+
+// static
+bool QuicFramerPeer::ProcessAndValidateIetfConnectionIdLength(
+    QuicDataReader* reader,
+    ParsedQuicVersion version,
+    Perspective perspective,
+    bool should_update_expected_server_connection_id_length,
+    uint8_t* expected_server_connection_id_length,
+    uint8_t* destination_connection_id_length,
+    uint8_t* source_connection_id_length,
+    std::string* detailed_error) {
+  return QuicFramer::ProcessAndValidateIetfConnectionIdLength(
+      reader, version, perspective,
+      should_update_expected_server_connection_id_length,
+      expected_server_connection_id_length, destination_connection_id_length,
+      source_connection_id_length, detailed_error);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_framer_peer.h b/quiche/quic/test_tools/quic_framer_peer.h
new file mode 100644
index 0000000..3b898d1
--- /dev/null
+++ b/quiche/quic/test_tools/quic_framer_peer.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
+
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+namespace test {
+
+class QuicFramerPeer {
+ public:
+  QuicFramerPeer() = delete;
+
+  static uint64_t CalculatePacketNumberFromWire(
+      QuicFramer* framer,
+      QuicPacketNumberLength packet_number_length,
+      QuicPacketNumber last_packet_number,
+      uint64_t packet_number);
+  static void SetLastSerializedServerConnectionId(
+      QuicFramer* framer,
+      QuicConnectionId server_connection_id);
+  static void SetLastSerializedClientConnectionId(
+      QuicFramer* framer,
+      QuicConnectionId client_connection_id);
+  static void SetLastWrittenPacketNumberLength(QuicFramer* framer,
+                                               size_t packet_number_length);
+  static void SetLargestPacketNumber(QuicFramer* framer,
+                                     QuicPacketNumber packet_number);
+  static void SetPerspective(QuicFramer* framer, Perspective perspective);
+
+  // SwapCrypters exchanges the state of the crypters of |framer1| with
+  // |framer2|.
+  static void SwapCrypters(QuicFramer* framer1, QuicFramer* framer2);
+
+  static QuicEncrypter* GetEncrypter(QuicFramer* framer, EncryptionLevel level);
+  static QuicDecrypter* GetDecrypter(QuicFramer* framer, EncryptionLevel level);
+
+  static void SetFirstSendingPacketNumber(QuicFramer* framer,
+                                          uint64_t packet_number);
+  static void SetExpectedServerConnectionIDLength(
+      QuicFramer* framer,
+      uint8_t expected_server_connection_id_length);
+  static QuicPacketNumber GetLargestDecryptedPacketNumber(
+      QuicFramer* framer,
+      PacketNumberSpace packet_number_space);
+
+  static bool ProcessAndValidateIetfConnectionIdLength(
+      QuicDataReader* reader,
+      ParsedQuicVersion version,
+      Perspective perspective,
+      bool should_update_expected_server_connection_id_length,
+      uint8_t* expected_server_connection_id_length,
+      uint8_t* destination_connection_id_length,
+      uint8_t* source_connection_id_length,
+      std::string* detailed_error);
+
+  static void set_current_received_frame_type(
+      QuicFramer* framer,
+      uint64_t current_received_frame_type) {
+    framer->current_received_frame_type_ = current_received_frame_type;
+  }
+
+  static bool infer_packet_header_type_from_version(QuicFramer* framer) {
+    return framer->infer_packet_header_type_from_version_;
+  }
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_FRAMER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_interval_deque_peer.h b/quiche/quic/test_tools/quic_interval_deque_peer.h
new file mode 100644
index 0000000..c522457
--- /dev/null
+++ b/quiche/quic/test_tools/quic_interval_deque_peer.h
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
+
+#include "quiche/quic/core/quic_interval_deque.h"
+
+namespace quic {
+
+namespace test {
+
+class QuicIntervalDequePeer {
+ public:
+  template <class T, class C>
+  static int32_t GetCachedIndex(QuicIntervalDeque<T, C>* interval_deque) {
+    if (!interval_deque->cached_index_.has_value()) {
+      return -1;
+    }
+    return interval_deque->cached_index_.value();
+  }
+
+  template <class T, class C>
+  static T* GetItem(QuicIntervalDeque<T, C>* interval_deque,
+                    const std::size_t index) {
+    return &interval_deque->container_[index];
+  }
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_INTERVAL_DEQUE_PEER_H_
diff --git a/quiche/quic/test_tools/quic_mock_syscall_wrapper.cc b/quiche/quic/test_tools/quic_mock_syscall_wrapper.cc
new file mode 100644
index 0000000..f934198
--- /dev/null
+++ b/quiche/quic/test_tools/quic_mock_syscall_wrapper.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_mock_syscall_wrapper.h"
+
+using testing::_;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+
+MockQuicSyscallWrapper::MockQuicSyscallWrapper(QuicSyscallWrapper* delegate) {
+  ON_CALL(*this, Sendmsg(_, _, _))
+      .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmsg));
+
+  ON_CALL(*this, Sendmmsg(_, _, _, _))
+      .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmmsg));
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_mock_syscall_wrapper.h b/quiche/quic/test_tools/quic_mock_syscall_wrapper.h
new file mode 100644
index 0000000..72a33a8
--- /dev/null
+++ b/quiche/quic/test_tools/quic_mock_syscall_wrapper.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
+
+#include "quiche/quic/core/quic_syscall_wrapper.h"
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class MockQuicSyscallWrapper : public QuicSyscallWrapper {
+ public:
+  // Create a standard mock object.
+  MockQuicSyscallWrapper() = default;
+
+  // Create a 'mockable' object that delegates everything to |delegate| by
+  // default.
+  explicit MockQuicSyscallWrapper(QuicSyscallWrapper* delegate);
+
+  MOCK_METHOD(ssize_t,
+              Sendmsg,
+              (int sockfd, const msghdr*, int flags),
+              (override));
+
+  MOCK_METHOD(int,
+              Sendmmsg,
+              (int sockfd, mmsghdr*, unsigned int vlen, int flags),
+              (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
diff --git a/quiche/quic/test_tools/quic_packet_creator_peer.cc b/quiche/quic/test_tools/quic_packet_creator_peer.cc
new file mode 100644
index 0000000..fa62e14
--- /dev/null
+++ b/quiche/quic/test_tools/quic_packet_creator_peer.cc
@@ -0,0 +1,167 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_packet_creator_peer.h"
+
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+namespace test {
+
+// static
+bool QuicPacketCreatorPeer::SendVersionInPacket(QuicPacketCreator* creator) {
+  return creator->IncludeVersionInHeader();
+}
+
+// static
+void QuicPacketCreatorPeer::SetSendVersionInPacket(
+    QuicPacketCreator* creator,
+    bool send_version_in_packet) {
+  ParsedQuicVersion version = creator->framer_->version();
+  if (!VersionHasIetfQuicFrames(version.transport_version) &&
+      version.handshake_protocol != PROTOCOL_TLS1_3) {
+    creator->send_version_in_packet_ = send_version_in_packet;
+    return;
+  }
+  if (!send_version_in_packet) {
+    creator->packet_.encryption_level = ENCRYPTION_FORWARD_SECURE;
+    return;
+  }
+  QUICHE_DCHECK(creator->packet_.encryption_level < ENCRYPTION_FORWARD_SECURE);
+}
+
+// static
+void QuicPacketCreatorPeer::SetPacketNumberLength(
+    QuicPacketCreator* creator,
+    QuicPacketNumberLength packet_number_length) {
+  creator->packet_.packet_number_length = packet_number_length;
+}
+
+// static
+QuicPacketNumberLength QuicPacketCreatorPeer::GetPacketNumberLength(
+    QuicPacketCreator* creator) {
+  return creator->GetPacketNumberLength();
+}
+
+// static
+QuicVariableLengthIntegerLength
+QuicPacketCreatorPeer::GetRetryTokenLengthLength(QuicPacketCreator* creator) {
+  return creator->GetRetryTokenLengthLength();
+}
+
+// static
+QuicVariableLengthIntegerLength QuicPacketCreatorPeer::GetLengthLength(
+    QuicPacketCreator* creator) {
+  return creator->GetLengthLength();
+}
+
+void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
+                                            uint64_t s) {
+  QUICHE_DCHECK_NE(0u, s);
+  creator->packet_.packet_number = QuicPacketNumber(s);
+}
+
+void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
+                                            QuicPacketNumber num) {
+  creator->packet_.packet_number = num;
+}
+
+// static
+void QuicPacketCreatorPeer::ClearPacketNumber(QuicPacketCreator* creator) {
+  creator->packet_.packet_number.Clear();
+}
+
+// static
+void QuicPacketCreatorPeer::FillPacketHeader(QuicPacketCreator* creator,
+                                             QuicPacketHeader* header) {
+  creator->FillPacketHeader(header);
+}
+
+// static
+void QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
+                                              QuicStreamId id,
+                                              size_t data_length,
+                                              QuicStreamOffset offset,
+                                              bool fin,
+                                              QuicFrame* frame) {
+  creator->CreateStreamFrame(id, data_length, offset, fin, frame);
+}
+
+// static
+bool QuicPacketCreatorPeer::CreateCryptoFrame(QuicPacketCreator* creator,
+                                              EncryptionLevel level,
+                                              size_t write_length,
+                                              QuicStreamOffset offset,
+                                              QuicFrame* frame) {
+  return creator->CreateCryptoFrame(level, write_length, offset, frame);
+}
+
+// static
+SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames(
+    QuicPacketCreator* creator,
+    const QuicFrames& frames,
+    char* buffer,
+    size_t buffer_len) {
+  QUICHE_DCHECK(creator->queued_frames_.empty());
+  QUICHE_DCHECK(!frames.empty());
+  for (const QuicFrame& frame : frames) {
+    bool success = creator->AddFrame(frame, NOT_RETRANSMISSION);
+    QUICHE_DCHECK(success);
+  }
+  const bool success =
+      creator->SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr),
+                               buffer_len, /*allow_padding=*/true);
+  QUICHE_DCHECK(success);
+  SerializedPacket packet = std::move(creator->packet_);
+  // The caller takes ownership of the QuicEncryptedPacket.
+  creator->packet_.encrypted_buffer = nullptr;
+  return packet;
+}
+
+// static
+std::unique_ptr<SerializedPacket>
+QuicPacketCreatorPeer::SerializeConnectivityProbingPacket(
+    QuicPacketCreator* creator) {
+  return creator->SerializeConnectivityProbingPacket();
+}
+
+// static
+std::unique_ptr<SerializedPacket>
+QuicPacketCreatorPeer::SerializePathChallengeConnectivityProbingPacket(
+    QuicPacketCreator* creator,
+    const QuicPathFrameBuffer& payload) {
+  return creator->SerializePathChallengeConnectivityProbingPacket(payload);
+}
+
+// static
+EncryptionLevel QuicPacketCreatorPeer::GetEncryptionLevel(
+    QuicPacketCreator* creator) {
+  return creator->packet_.encryption_level;
+}
+
+// static
+QuicFramer* QuicPacketCreatorPeer::framer(QuicPacketCreator* creator) {
+  return creator->framer_;
+}
+
+// static
+std::string QuicPacketCreatorPeer::GetRetryToken(QuicPacketCreator* creator) {
+  return creator->retry_token_;
+}
+
+// static
+QuicFrames& QuicPacketCreatorPeer::QueuedFrames(QuicPacketCreator* creator) {
+  return creator->queued_frames_;
+}
+
+// static
+void QuicPacketCreatorPeer::SetRandom(QuicPacketCreator* creator,
+                                      QuicRandom* random) {
+  creator->random_ = random;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_packet_creator_peer.h b/quiche/quic/test_tools/quic_packet_creator_peer.h
new file mode 100644
index 0000000..8af1a30
--- /dev/null
+++ b/quiche/quic/test_tools/quic_packet_creator_peer.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+class QuicFramer;
+class QuicPacketCreator;
+class QuicRandom;
+
+namespace test {
+
+class QuicPacketCreatorPeer {
+ public:
+  QuicPacketCreatorPeer() = delete;
+
+  static bool SendVersionInPacket(QuicPacketCreator* creator);
+
+  static void SetSendVersionInPacket(QuicPacketCreator* creator,
+                                     bool send_version_in_packet);
+  static void SetPacketNumberLength(
+      QuicPacketCreator* creator,
+      QuicPacketNumberLength packet_number_length);
+  static QuicPacketNumberLength GetPacketNumberLength(
+      QuicPacketCreator* creator);
+  static QuicVariableLengthIntegerLength GetRetryTokenLengthLength(
+      QuicPacketCreator* creator);
+  static QuicVariableLengthIntegerLength GetLengthLength(
+      QuicPacketCreator* creator);
+  static void SetPacketNumber(QuicPacketCreator* creator, uint64_t s);
+  static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber num);
+  static void ClearPacketNumber(QuicPacketCreator* creator);
+  static void FillPacketHeader(QuicPacketCreator* creator,
+                               QuicPacketHeader* header);
+  static void CreateStreamFrame(QuicPacketCreator* creator,
+                                QuicStreamId id,
+                                size_t data_length,
+                                QuicStreamOffset offset,
+                                bool fin,
+                                QuicFrame* frame);
+  static bool CreateCryptoFrame(QuicPacketCreator* creator,
+                                EncryptionLevel level,
+                                size_t write_length,
+                                QuicStreamOffset offset,
+                                QuicFrame* frame);
+  static SerializedPacket SerializeAllFrames(QuicPacketCreator* creator,
+                                             const QuicFrames& frames,
+                                             char* buffer,
+                                             size_t buffer_len);
+  static std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket(
+      QuicPacketCreator* creator);
+  static std::unique_ptr<SerializedPacket>
+  SerializePathChallengeConnectivityProbingPacket(
+      QuicPacketCreator* creator,
+      const QuicPathFrameBuffer& payload);
+
+  static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
+  static QuicFramer* framer(QuicPacketCreator* creator);
+  static std::string GetRetryToken(QuicPacketCreator* creator);
+  static QuicFrames& QueuedFrames(QuicPacketCreator* creator);
+  static void SetRandom(QuicPacketCreator* creator, QuicRandom* random);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_CREATOR_PEER_H_
diff --git a/quiche/quic/test_tools/quic_path_validator_peer.cc b/quiche/quic/test_tools/quic_path_validator_peer.cc
new file mode 100644
index 0000000..42c92cf
--- /dev/null
+++ b/quiche/quic/test_tools/quic_path_validator_peer.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_path_validator_peer.h"
+
+namespace quic {
+namespace test {
+//  static
+QuicAlarm* QuicPathValidatorPeer::retry_timer(QuicPathValidator* validator) {
+  return validator->retry_timer_.get();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_path_validator_peer.h b/quiche/quic/test_tools/quic_path_validator_peer.h
new file mode 100644
index 0000000..0013983
--- /dev/null
+++ b/quiche/quic/test_tools/quic_path_validator_peer.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
+
+#include "quiche/quic/core/quic_path_validator.h"
+
+namespace quic {
+namespace test {
+
+class QuicPathValidatorPeer {
+ public:
+  static QuicAlarm* retry_timer(QuicPathValidator* validator);
+};
+
+}  // namespace test
+}  // namespace quic
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_PATH_VALIDATOR_PEER_H_
diff --git a/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc b/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc
new file mode 100644
index 0000000..06588a4
--- /dev/null
+++ b/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -0,0 +1,224 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+
+#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+#include "quiche/quic/test_tools/quic_unacked_packet_map_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+size_t QuicSentPacketManagerPeer::GetMaxTailLossProbes(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->max_tail_loss_probes_;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetMaxTailLossProbes(
+    QuicSentPacketManager* sent_packet_manager,
+    size_t max_tail_loss_probes) {
+  sent_packet_manager->max_tail_loss_probes_ = max_tail_loss_probes;
+}
+
+// static
+bool QuicSentPacketManagerPeer::GetUseNewRto(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->use_new_rto_;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetPerspective(
+    QuicSentPacketManager* sent_packet_manager,
+    Perspective perspective) {
+  QuicUnackedPacketMapPeer::SetPerspective(
+      &sent_packet_manager->unacked_packets_, perspective);
+}
+
+// static
+SendAlgorithmInterface* QuicSentPacketManagerPeer::GetSendAlgorithm(
+    const QuicSentPacketManager& sent_packet_manager) {
+  return sent_packet_manager.send_algorithm_.get();
+}
+
+// static
+void QuicSentPacketManagerPeer::SetSendAlgorithm(
+    QuicSentPacketManager* sent_packet_manager,
+    SendAlgorithmInterface* send_algorithm) {
+  sent_packet_manager->SetSendAlgorithm(send_algorithm);
+}
+
+// static
+const LossDetectionInterface* QuicSentPacketManagerPeer::GetLossAlgorithm(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->loss_algorithm_;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetLossAlgorithm(
+    QuicSentPacketManager* sent_packet_manager,
+    LossDetectionInterface* loss_detector) {
+  sent_packet_manager->loss_algorithm_ = loss_detector;
+}
+
+// static
+RttStats* QuicSentPacketManagerPeer::GetRttStats(
+    QuicSentPacketManager* sent_packet_manager) {
+  return &sent_packet_manager->rtt_stats_;
+}
+
+// static
+bool QuicSentPacketManagerPeer::IsRetransmission(
+    QuicSentPacketManager* sent_packet_manager,
+    uint64_t packet_number) {
+  QUICHE_DCHECK(HasRetransmittableFrames(sent_packet_manager, packet_number));
+  if (!HasRetransmittableFrames(sent_packet_manager, packet_number)) {
+    return false;
+  }
+  return sent_packet_manager->unacked_packets_
+             .GetTransmissionInfo(QuicPacketNumber(packet_number))
+             .transmission_type != NOT_RETRANSMISSION;
+}
+
+// static
+void QuicSentPacketManagerPeer::MarkForRetransmission(
+    QuicSentPacketManager* sent_packet_manager,
+    uint64_t packet_number,
+    TransmissionType transmission_type) {
+  sent_packet_manager->MarkForRetransmission(QuicPacketNumber(packet_number),
+                                             transmission_type);
+}
+
+// static
+QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
+    const QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->GetRetransmissionDelay();
+}
+
+// static
+QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
+    const QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->GetTailLossProbeDelay();
+}
+
+// static
+size_t QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
+    const QuicSentPacketManager* sent_packet_manager) {
+  size_t num_unacked_packets = 0;
+  for (auto it = sent_packet_manager->unacked_packets_.begin();
+       it != sent_packet_manager->unacked_packets_.end(); ++it) {
+    if (sent_packet_manager->unacked_packets_.HasRetransmittableFrames(*it)) {
+      ++num_unacked_packets;
+    }
+  }
+  return num_unacked_packets;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetConsecutiveRtoCount(
+    QuicSentPacketManager* sent_packet_manager,
+    size_t count) {
+  sent_packet_manager->consecutive_rto_count_ = count;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetConsecutiveTlpCount(
+    QuicSentPacketManager* sent_packet_manager,
+    size_t count) {
+  sent_packet_manager->consecutive_tlp_count_ = count;
+}
+
+// static
+QuicSustainedBandwidthRecorder& QuicSentPacketManagerPeer::GetBandwidthRecorder(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->sustained_bandwidth_recorder_;
+}
+
+// static
+bool QuicSentPacketManagerPeer::UsingPacing(
+    const QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->using_pacing_;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetUsingPacing(
+    QuicSentPacketManager* sent_packet_manager,
+    bool using_pacing) {
+  sent_packet_manager->using_pacing_ = using_pacing;
+}
+
+// static
+bool QuicSentPacketManagerPeer::HasRetransmittableFrames(
+    QuicSentPacketManager* sent_packet_manager,
+    uint64_t packet_number) {
+  return sent_packet_manager->unacked_packets_.HasRetransmittableFrames(
+      QuicPacketNumber(packet_number));
+}
+
+// static
+QuicUnackedPacketMap* QuicSentPacketManagerPeer::GetUnackedPacketMap(
+    QuicSentPacketManager* sent_packet_manager) {
+  return &sent_packet_manager->unacked_packets_;
+}
+
+// static
+void QuicSentPacketManagerPeer::DisablePacerBursts(
+    QuicSentPacketManager* sent_packet_manager) {
+  sent_packet_manager->pacing_sender_.burst_tokens_ = 0;
+  sent_packet_manager->pacing_sender_.initial_burst_size_ = 0;
+}
+
+// static
+int QuicSentPacketManagerPeer::GetPacerInitialBurstSize(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->pacing_sender_.initial_burst_size_;
+}
+
+// static
+void QuicSentPacketManagerPeer::SetNextPacedPacketTime(
+    QuicSentPacketManager* sent_packet_manager,
+    QuicTime time) {
+  sent_packet_manager->pacing_sender_.ideal_next_packet_send_time_ = time;
+}
+
+// static
+int QuicSentPacketManagerPeer::GetReorderingShift(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
+      .reordering_shift();
+}
+
+// static
+bool QuicSentPacketManagerPeer::AdaptiveReorderingThresholdEnabled(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
+      .use_adaptive_reordering_threshold();
+}
+
+// static
+bool QuicSentPacketManagerPeer::AdaptiveTimeThresholdEnabled(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
+      .use_adaptive_time_threshold();
+}
+
+// static
+bool QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->uber_loss_algorithm_.general_loss_algorithms_[0]
+      .use_packet_threshold_for_runt_packets();
+}
+
+// static
+int QuicSentPacketManagerPeer::GetNumPtosForPathDegrading(
+    QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->num_ptos_for_path_degrading_;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_sent_packet_manager_peer.h b/quiche/quic/test_tools/quic_sent_packet_manager_peer.h
new file mode 100644
index 0000000..6e32b6b
--- /dev/null
+++ b/quiche/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -0,0 +1,110 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+
+namespace quic {
+
+class SendAlgorithmInterface;
+
+namespace test {
+
+class QuicSentPacketManagerPeer {
+ public:
+  QuicSentPacketManagerPeer() = delete;
+
+  static size_t GetMaxTailLossProbes(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static void SetMaxTailLossProbes(QuicSentPacketManager* sent_packet_manager,
+                                   size_t max_tail_loss_probes);
+
+  static bool GetUseNewRto(QuicSentPacketManager* sent_packet_manager);
+
+  static void SetPerspective(QuicSentPacketManager* sent_packet_manager,
+                             Perspective perspective);
+
+  static SendAlgorithmInterface* GetSendAlgorithm(
+      const QuicSentPacketManager& sent_packet_manager);
+
+  static void SetSendAlgorithm(QuicSentPacketManager* sent_packet_manager,
+                               SendAlgorithmInterface* send_algorithm);
+
+  static const LossDetectionInterface* GetLossAlgorithm(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static void SetLossAlgorithm(QuicSentPacketManager* sent_packet_manager,
+                               LossDetectionInterface* loss_detector);
+
+  static RttStats* GetRttStats(QuicSentPacketManager* sent_packet_manager);
+
+  // Returns true if |packet_number| is a retransmission of a packet.
+  static bool IsRetransmission(QuicSentPacketManager* sent_packet_manager,
+                               uint64_t packet_number);
+
+  static void MarkForRetransmission(QuicSentPacketManager* sent_packet_manager,
+                                    uint64_t packet_number,
+                                    TransmissionType transmission_type);
+
+  static QuicTime::Delta GetRetransmissionDelay(
+      const QuicSentPacketManager* sent_packet_manager);
+  static QuicTime::Delta GetTailLossProbeDelay(
+      const QuicSentPacketManager* sent_packet_manager);
+
+  static size_t GetNumRetransmittablePackets(
+      const QuicSentPacketManager* sent_packet_manager);
+
+  static void SetConsecutiveRtoCount(QuicSentPacketManager* sent_packet_manager,
+                                     size_t count);
+
+  static void SetConsecutiveTlpCount(QuicSentPacketManager* sent_packet_manager,
+                                     size_t count);
+
+  static QuicSustainedBandwidthRecorder& GetBandwidthRecorder(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static void SetUsingPacing(QuicSentPacketManager* sent_packet_manager,
+                             bool using_pacing);
+
+  static bool UsingPacing(const QuicSentPacketManager* sent_packet_manager);
+
+  static bool HasRetransmittableFrames(
+      QuicSentPacketManager* sent_packet_manager,
+      uint64_t packet_number);
+
+  static QuicUnackedPacketMap* GetUnackedPacketMap(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static void DisablePacerBursts(QuicSentPacketManager* sent_packet_manager);
+
+  static int GetPacerInitialBurstSize(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static void SetNextPacedPacketTime(QuicSentPacketManager* sent_packet_manager,
+                                     QuicTime time);
+
+  static int GetReorderingShift(QuicSentPacketManager* sent_packet_manager);
+
+  static bool AdaptiveReorderingThresholdEnabled(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static bool AdaptiveTimeThresholdEnabled(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static bool UsePacketThresholdForRuntPackets(
+      QuicSentPacketManager* sent_packet_manager);
+
+  static int GetNumPtosForPathDegrading(
+      QuicSentPacketManager* sent_packet_manager);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SENT_PACKET_MANAGER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_server_peer.cc b/quiche/quic/test_tools/quic_server_peer.cc
new file mode 100644
index 0000000..6f6c8f9
--- /dev/null
+++ b/quiche/quic/test_tools/quic_server_peer.cc
@@ -0,0 +1,32 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_server_peer.h"
+
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_packet_reader.h"
+#include "quiche/quic/tools/quic_server.h"
+
+namespace quic {
+namespace test {
+
+// static
+bool QuicServerPeer::SetSmallSocket(QuicServer* server) {
+  int size = 1024 * 10;
+  return setsockopt(server->fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) !=
+         -1;
+}
+
+// static
+QuicDispatcher* QuicServerPeer::GetDispatcher(QuicServer* server) {
+  return server->dispatcher_.get();
+}
+
+// static
+void QuicServerPeer::SetReader(QuicServer* server, QuicPacketReader* reader) {
+  server->packet_reader_.reset(reader);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quic/test_tools/quic_server_peer.h b/quiche/quic/test_tools/quic_server_peer.h
similarity index 100%
rename from quic/test_tools/quic_server_peer.h
rename to quiche/quic/test_tools/quic_server_peer.h
diff --git a/quiche/quic/test_tools/quic_server_session_base_peer.h b/quiche/quic/test_tools/quic_server_session_base_peer.h
new file mode 100644
index 0000000..5a2bd2d
--- /dev/null
+++ b/quiche/quic/test_tools/quic_server_session_base_peer.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
+
+#include "quiche/quic/core/http/quic_server_session_base.h"
+
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+namespace test {
+
+class QuicServerSessionBasePeer {
+ public:
+  static QuicStream* GetOrCreateStream(QuicServerSessionBase* s,
+                                       QuicStreamId id) {
+    return s->GetOrCreateStream(id);
+  }
+  static void SetCryptoStream(QuicServerSessionBase* s,
+                              QuicCryptoServerStreamBase* crypto_stream) {
+    s->crypto_stream_.reset(crypto_stream);
+  }
+  static bool IsBandwidthResumptionEnabled(QuicServerSessionBase* s) {
+    return s->bandwidth_resumption_enabled_;
+  }
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SERVER_SESSION_BASE_PEER_H_
diff --git a/quiche/quic/test_tools/quic_session_peer.cc b/quiche/quic/test_tools/quic_session_peer.cc
new file mode 100644
index 0000000..bb03bd2
--- /dev/null
+++ b/quiche/quic/test_tools/quic_session_peer.cc
@@ -0,0 +1,250 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_session_peer.h"
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+namespace test {
+
+// static
+QuicStreamId QuicSessionPeer::GetNextOutgoingBidirectionalStreamId(
+    QuicSession* session) {
+  return session->GetNextOutgoingBidirectionalStreamId();
+}
+
+// static
+QuicStreamId QuicSessionPeer::GetNextOutgoingUnidirectionalStreamId(
+    QuicSession* session) {
+  return session->GetNextOutgoingUnidirectionalStreamId();
+}
+
+// static
+void QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(QuicSession* session,
+                                                           QuicStreamId id) {
+  if (VersionHasIetfQuicFrames(session->transport_version())) {
+    session->ietf_streamid_manager_.bidirectional_stream_id_manager_
+        .next_outgoing_stream_id_ = id;
+    return;
+  }
+  session->stream_id_manager_.next_outgoing_stream_id_ = id;
+}
+
+// static
+void QuicSessionPeer::SetMaxOpenIncomingStreams(QuicSession* session,
+                                                uint32_t max_streams) {
+  if (VersionHasIetfQuicFrames(session->transport_version())) {
+    QUIC_BUG(quic_bug_10193_1)
+        << "SetmaxOpenIncomingStreams deprecated for IETF QUIC";
+    session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
+        max_streams);
+    session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
+        max_streams);
+    return;
+  }
+  session->stream_id_manager_.set_max_open_incoming_streams(max_streams);
+}
+
+// static
+void QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
+    QuicSession* session,
+    uint32_t max_streams) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
+      << "SetmaxOpenIncomingBidirectionalStreams not supported for Google "
+         "QUIC";
+  session->ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
+      max_streams);
+}
+// static
+void QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
+    QuicSession* session,
+    uint32_t max_streams) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
+      << "SetmaxOpenIncomingUnidirectionalStreams not supported for Google "
+         "QUIC";
+  session->ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
+      max_streams);
+}
+
+// static
+void QuicSessionPeer::SetMaxOpenOutgoingStreams(QuicSession* session,
+                                                uint32_t max_streams) {
+  if (VersionHasIetfQuicFrames(session->transport_version())) {
+    QUIC_BUG(quic_bug_10193_2)
+        << "SetmaxOpenOutgoingStreams deprecated for IETF QUIC";
+    return;
+  }
+  session->stream_id_manager_.set_max_open_outgoing_streams(max_streams);
+}
+
+// static
+void QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(
+    QuicSession* session,
+    uint32_t max_streams) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
+      << "SetmaxOpenOutgoingBidirectionalStreams not supported for Google "
+         "QUIC";
+  session->ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
+      max_streams);
+}
+// static
+void QuicSessionPeer::SetMaxOpenOutgoingUnidirectionalStreams(
+    QuicSession* session,
+    uint32_t max_streams) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(session->transport_version()))
+      << "SetmaxOpenOutgoingUnidirectionalStreams not supported for Google "
+         "QUIC";
+  session->ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
+      max_streams);
+}
+
+// static
+QuicCryptoStream* QuicSessionPeer::GetMutableCryptoStream(
+    QuicSession* session) {
+  return session->GetMutableCryptoStream();
+}
+
+// static
+QuicWriteBlockedList* QuicSessionPeer::GetWriteBlockedStreams(
+    QuicSession* session) {
+  return &session->write_blocked_streams_;
+}
+
+// static
+QuicStream* QuicSessionPeer::GetOrCreateStream(QuicSession* session,
+                                               QuicStreamId stream_id) {
+  return session->GetOrCreateStream(stream_id);
+}
+
+// static
+absl::flat_hash_map<QuicStreamId, QuicStreamOffset>&
+QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(QuicSession* session) {
+  return session->locally_closed_streams_highest_offset_;
+}
+
+// static
+QuicSession::StreamMap& QuicSessionPeer::stream_map(QuicSession* session) {
+  return session->stream_map_;
+}
+
+// static
+const QuicSession::ClosedStreams& QuicSessionPeer::closed_streams(
+    QuicSession* session) {
+  return *session->closed_streams();
+}
+
+// static
+void QuicSessionPeer::ActivateStream(QuicSession* session,
+                                     std::unique_ptr<QuicStream> stream) {
+  return session->ActivateStream(std::move(stream));
+}
+
+// static
+bool QuicSessionPeer::IsStreamClosed(QuicSession* session, QuicStreamId id) {
+  return session->IsClosedStream(id);
+}
+
+// static
+bool QuicSessionPeer::IsStreamCreated(QuicSession* session, QuicStreamId id) {
+  return session->stream_map_.contains(id);
+}
+
+// static
+bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) {
+  if (VersionHasIetfQuicFrames(session->transport_version())) {
+    if (id % QuicUtils::StreamIdDelta(session->transport_version()) < 2) {
+      return session->ietf_streamid_manager_.bidirectional_stream_id_manager_
+          .available_streams_.contains(id);
+    }
+    return session->ietf_streamid_manager_.unidirectional_stream_id_manager_
+        .available_streams_.contains(id);
+  }
+  return session->stream_id_manager_.available_streams_.contains(id);
+}
+
+// static
+QuicStream* QuicSessionPeer::GetStream(QuicSession* session, QuicStreamId id) {
+  return session->GetStream(id);
+}
+
+// static
+bool QuicSessionPeer::IsStreamWriteBlocked(QuicSession* session,
+                                           QuicStreamId id) {
+  return session->write_blocked_streams_.IsStreamBlocked(id);
+}
+
+// static
+QuicAlarm* QuicSessionPeer::GetCleanUpClosedStreamsAlarm(QuicSession* session) {
+  return session->closed_streams_clean_up_alarm_.get();
+}
+
+// static
+LegacyQuicStreamIdManager* QuicSessionPeer::GetStreamIdManager(
+    QuicSession* session) {
+  return &session->stream_id_manager_;
+}
+
+// static
+UberQuicStreamIdManager* QuicSessionPeer::ietf_streamid_manager(
+    QuicSession* session) {
+  return &session->ietf_streamid_manager_;
+}
+
+// static
+QuicStreamIdManager* QuicSessionPeer::ietf_bidirectional_stream_id_manager(
+    QuicSession* session) {
+  return &session->ietf_streamid_manager_.bidirectional_stream_id_manager_;
+}
+
+// static
+QuicStreamIdManager* QuicSessionPeer::ietf_unidirectional_stream_id_manager(
+    QuicSession* session) {
+  return &session->ietf_streamid_manager_.unidirectional_stream_id_manager_;
+}
+
+// static
+PendingStream* QuicSessionPeer::GetPendingStream(QuicSession* session,
+                                                 QuicStreamId stream_id) {
+  auto it = session->pending_stream_map_.find(stream_id);
+  return it == session->pending_stream_map_.end() ? nullptr : it->second.get();
+}
+
+// static
+void QuicSessionPeer::set_is_configured(QuicSession* session, bool value) {
+  session->is_configured_ = value;
+}
+
+// static
+void QuicSessionPeer::SetPerspective(QuicSession* session,
+                                     Perspective perspective) {
+  session->perspective_ = perspective;
+}
+
+// static
+size_t QuicSessionPeer::GetNumOpenDynamicStreams(QuicSession* session) {
+  size_t result = 0;
+  for (const auto& it : session->stream_map_) {
+    if (!it.second->is_static()) {
+      ++result;
+    }
+  }
+  // Exclude draining streams.
+  result -= session->num_draining_streams_;
+  // Add locally closed streams.
+  result += session->locally_closed_streams_highest_offset_.size();
+
+  return result;
+}
+
+// static
+size_t QuicSessionPeer::GetNumDrainingStreams(QuicSession* session) {
+  return session->num_draining_streams_;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_session_peer.h b/quiche/quic/test_tools/quic_session_peer.h
new file mode 100644
index 0000000..b01c925
--- /dev/null
+++ b/quiche/quic/test_tools/quic_session_peer.h
@@ -0,0 +1,96 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
+
+#include <cstdint>
+#include <map>
+#include <memory>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+
+namespace quic {
+
+class QuicCryptoStream;
+class QuicSession;
+class QuicStream;
+
+namespace test {
+
+class QuicSessionPeer {
+ public:
+  QuicSessionPeer() = delete;
+
+  static QuicStreamId GetNextOutgoingBidirectionalStreamId(
+      QuicSession* session);
+  static QuicStreamId GetNextOutgoingUnidirectionalStreamId(
+      QuicSession* session);
+  static void SetNextOutgoingBidirectionalStreamId(QuicSession* session,
+                                                   QuicStreamId id);
+  // Following is only for Google-QUIC, will QUIC_BUG if called for IETF
+  // QUIC.
+  static void SetMaxOpenIncomingStreams(QuicSession* session,
+                                        uint32_t max_streams);
+  // Following two are only for IETF-QUIC, will QUIC_BUG if called for Google
+  // QUIC.
+  static void SetMaxOpenIncomingBidirectionalStreams(QuicSession* session,
+                                                     uint32_t max_streams);
+  static void SetMaxOpenIncomingUnidirectionalStreams(QuicSession* session,
+                                                      uint32_t max_streams);
+
+  static void SetMaxOpenOutgoingStreams(QuicSession* session,
+                                        uint32_t max_streams);
+  static void SetMaxOpenOutgoingBidirectionalStreams(QuicSession* session,
+                                                     uint32_t max_streams);
+  static void SetMaxOpenOutgoingUnidirectionalStreams(QuicSession* session,
+                                                      uint32_t max_streams);
+
+  static QuicCryptoStream* GetMutableCryptoStream(QuicSession* session);
+  static QuicWriteBlockedList* GetWriteBlockedStreams(QuicSession* session);
+  static QuicStream* GetOrCreateStream(QuicSession* session,
+                                       QuicStreamId stream_id);
+  static absl::flat_hash_map<QuicStreamId, QuicStreamOffset>&
+  GetLocallyClosedStreamsHighestOffset(QuicSession* session);
+  static QuicSession::StreamMap& stream_map(QuicSession* session);
+  static const QuicSession::ClosedStreams& closed_streams(QuicSession* session);
+  static void ActivateStream(QuicSession* session,
+                             std::unique_ptr<QuicStream> stream);
+
+  // Discern the state of a stream.  Exactly one of these should be true at a
+  // time for any stream id > 0 (other than the special streams 1 and 3).
+  static bool IsStreamClosed(QuicSession* session, QuicStreamId id);
+  static bool IsStreamCreated(QuicSession* session, QuicStreamId id);
+  static bool IsStreamAvailable(QuicSession* session, QuicStreamId id);
+
+  static QuicStream* GetStream(QuicSession* session, QuicStreamId id);
+  static bool IsStreamWriteBlocked(QuicSession* session, QuicStreamId id);
+  static QuicAlarm* GetCleanUpClosedStreamsAlarm(QuicSession* session);
+  static LegacyQuicStreamIdManager* GetStreamIdManager(QuicSession* session);
+  static UberQuicStreamIdManager* ietf_streamid_manager(QuicSession* session);
+  static QuicStreamIdManager* ietf_bidirectional_stream_id_manager(
+      QuicSession* session);
+  static QuicStreamIdManager* ietf_unidirectional_stream_id_manager(
+      QuicSession* session);
+  static PendingStream* GetPendingStream(QuicSession* session,
+                                         QuicStreamId stream_id);
+  static void set_is_configured(QuicSession* session, bool value);
+  static void SetPerspective(QuicSession* session, Perspective perspective);
+  static size_t GetNumOpenDynamicStreams(QuicSession* session);
+  static size_t GetNumDrainingStreams(QuicSession* session);
+  static QuicStreamId GetLargestPeerCreatedStreamId(QuicSession* session,
+                                                    bool unidirectional) {
+    return session->GetLargestPeerCreatedStreamId(unidirectional);
+  }
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
diff --git a/quiche/quic/test_tools/quic_spdy_session_peer.cc b/quiche/quic/test_tools/quic_spdy_session_peer.cc
new file mode 100644
index 0000000..62348cb
--- /dev/null
+++ b/quiche/quic/test_tools/quic_spdy_session_peer.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/qpack/qpack_receive_stream.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+namespace test {
+
+// static
+QuicHeadersStream* QuicSpdySessionPeer::GetHeadersStream(
+    QuicSpdySession* session) {
+  QUICHE_DCHECK(!VersionUsesHttp3(session->transport_version()));
+  return session->headers_stream();
+}
+
+void QuicSpdySessionPeer::SetHeadersStream(QuicSpdySession* session,
+                                           QuicHeadersStream* headers_stream) {
+  QUICHE_DCHECK(!VersionUsesHttp3(session->transport_version()));
+  for (auto& it : QuicSessionPeer::stream_map(session)) {
+    if (it.first ==
+        QuicUtils::GetHeadersStreamId(session->transport_version())) {
+      it.second.reset(headers_stream);
+      session->headers_stream_ = static_cast<QuicHeadersStream*>(it.second.get());
+      break;
+    }
+  }
+}
+
+// static
+spdy::SpdyFramer* QuicSpdySessionPeer::GetSpdyFramer(QuicSpdySession* session) {
+  return &session->spdy_framer_;
+}
+
+void QuicSpdySessionPeer::SetMaxInboundHeaderListSize(
+    QuicSpdySession* session, size_t max_inbound_header_size) {
+  session->set_max_inbound_header_list_size(max_inbound_header_size);
+}
+
+// static
+size_t QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
+    QuicSpdySession* session, QuicStreamId id, spdy::SpdyHeaderBlock headers,
+    bool fin, const spdy::SpdyStreamPrecedence& precedence,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  return session->WriteHeadersOnHeadersStream(
+      id, std::move(headers), fin, precedence, std::move(ack_listener));
+}
+
+// static
+QuicStreamId QuicSpdySessionPeer::GetNextOutgoingUnidirectionalStreamId(
+    QuicSpdySession* session) {
+  return session->GetNextOutgoingUnidirectionalStreamId();
+}
+
+// static
+QuicReceiveControlStream* QuicSpdySessionPeer::GetReceiveControlStream(
+    QuicSpdySession* session) {
+  return session->receive_control_stream_;
+}
+
+// static
+QuicSendControlStream* QuicSpdySessionPeer::GetSendControlStream(
+    QuicSpdySession* session) {
+  return session->send_control_stream_;
+}
+
+// static
+QpackSendStream* QuicSpdySessionPeer::GetQpackDecoderSendStream(
+    QuicSpdySession* session) {
+  return session->qpack_decoder_send_stream_;
+}
+
+// static
+QpackSendStream* QuicSpdySessionPeer::GetQpackEncoderSendStream(
+    QuicSpdySession* session) {
+  return session->qpack_encoder_send_stream_;
+}
+
+// static
+QpackReceiveStream* QuicSpdySessionPeer::GetQpackDecoderReceiveStream(
+    QuicSpdySession* session) {
+  return session->qpack_decoder_receive_stream_;
+}
+
+// static
+QpackReceiveStream* QuicSpdySessionPeer::GetQpackEncoderReceiveStream(
+    QuicSpdySession* session) {
+  return session->qpack_encoder_receive_stream_;
+}
+
+// static
+void QuicSpdySessionPeer::SetHttpDatagramSupport(
+    QuicSpdySession* session, HttpDatagramSupport http_datagram_support) {
+  session->http_datagram_support_ = http_datagram_support;
+}
+
+// static
+HttpDatagramSupport QuicSpdySessionPeer::LocalHttpDatagramSupport(
+    QuicSpdySession* session) {
+  return session->LocalHttpDatagramSupport();
+}
+
+// static
+void QuicSpdySessionPeer::EnableWebTransport(QuicSpdySession* session) {
+  QUICHE_DCHECK(session->WillNegotiateWebTransport());
+  SetHttpDatagramSupport(session, HttpDatagramSupport::kDraft04);
+  session->peer_supports_webtransport_ = true;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_spdy_session_peer.h b/quiche/quic/test_tools/quic_spdy_session_peer.h
new file mode 100644
index 0000000..d87104f
--- /dev/null
+++ b/quiche/quic/test_tools/quic_spdy_session_peer.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
+
+#include "quiche/quic/core/http/quic_receive_control_stream.h"
+#include "quiche/quic/core/http/quic_send_control_stream.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/qpack/qpack_receive_stream.h"
+#include "quiche/quic/core/qpack/qpack_send_stream.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_write_blocked_list.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+class QuicHeadersStream;
+
+namespace test {
+
+class QuicSpdySessionPeer {
+ public:
+  QuicSpdySessionPeer() = delete;
+
+  static QuicHeadersStream* GetHeadersStream(QuicSpdySession* session);
+  static void SetHeadersStream(QuicSpdySession* session,
+                               QuicHeadersStream* headers_stream);
+  static spdy::SpdyFramer* GetSpdyFramer(QuicSpdySession* session);
+  // Must be called before Initialize().
+  static void SetMaxInboundHeaderListSize(QuicSpdySession* session,
+                                          size_t max_inbound_header_size);
+  static size_t WriteHeadersOnHeadersStream(
+      QuicSpdySession* session, QuicStreamId id, spdy::SpdyHeaderBlock headers,
+      bool fin, const spdy::SpdyStreamPrecedence& precedence,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+  // |session| can't be nullptr.
+  static QuicStreamId GetNextOutgoingUnidirectionalStreamId(
+      QuicSpdySession* session);
+  static QuicReceiveControlStream* GetReceiveControlStream(
+      QuicSpdySession* session);
+  static QuicSendControlStream* GetSendControlStream(QuicSpdySession* session);
+  static QpackSendStream* GetQpackDecoderSendStream(QuicSpdySession* session);
+  static QpackSendStream* GetQpackEncoderSendStream(QuicSpdySession* session);
+  static QpackReceiveStream* GetQpackDecoderReceiveStream(
+      QuicSpdySession* session);
+  static QpackReceiveStream* GetQpackEncoderReceiveStream(
+      QuicSpdySession* session);
+  static void SetHttpDatagramSupport(QuicSpdySession* session,
+                                     HttpDatagramSupport http_datagram_support);
+  static HttpDatagramSupport LocalHttpDatagramSupport(QuicSpdySession* session);
+  static void EnableWebTransport(QuicSpdySession* session);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_SESSION_PEER_H_
diff --git a/quiche/quic/test_tools/quic_spdy_stream_peer.cc b/quiche/quic/test_tools/quic_spdy_stream_peer.cc
new file mode 100644
index 0000000..d2ec5fd
--- /dev/null
+++ b/quiche/quic/test_tools/quic_spdy_stream_peer.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
+
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicSpdyStreamPeer::set_ack_listener(
+    QuicSpdyStream* stream,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  stream->set_ack_listener(std::move(ack_listener));
+}
+
+// static
+const QuicIntervalSet<QuicStreamOffset>&
+QuicSpdyStreamPeer::unacked_frame_headers_offsets(QuicSpdyStream* stream) {
+  return stream->unacked_frame_headers_offsets_;
+}
+
+// static
+bool QuicSpdyStreamPeer::use_datagram_contexts(QuicSpdyStream* stream) {
+  return stream->use_datagram_contexts_;
+}
+
+// static
+bool QuicSpdyStreamPeer::OnHeadersFrameEnd(QuicSpdyStream* stream) {
+  return stream->OnHeadersFrameEnd();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_spdy_stream_peer.h b/quiche/quic/test_tools/quic_spdy_stream_peer.h
new file mode 100644
index 0000000..e92f89e
--- /dev/null
+++ b/quiche/quic/test_tools/quic_spdy_stream_peer.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
+
+#include "quiche/quic/core/quic_ack_listener_interface.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+
+namespace quic {
+
+class QpackDecodedHeadersAccumulator;
+class QuicSpdyStream;
+
+namespace test {
+
+class QuicSpdyStreamPeer {
+ public:
+  static void set_ack_listener(
+      QuicSpdyStream* stream,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+  static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets(
+      QuicSpdyStream* stream);
+  static bool use_datagram_contexts(QuicSpdyStream* stream);
+  static bool OnHeadersFrameEnd(QuicSpdyStream* stream);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SPDY_STREAM_PEER_H_
diff --git a/quiche/quic/test_tools/quic_stream_id_manager_peer.cc b/quiche/quic/test_tools/quic_stream_id_manager_peer.cc
new file mode 100644
index 0000000..0bec142
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_id_manager_peer.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
+
+#include "quiche/quic/core/quic_stream_id_manager.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/uber_quic_stream_id_manager.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicStreamIdManagerPeer::set_incoming_actual_max_streams(
+    QuicStreamIdManager* stream_id_manager,
+    QuicStreamCount count) {
+  stream_id_manager->incoming_actual_max_streams_ = count;
+}
+
+// static
+void QuicStreamIdManagerPeer::set_outgoing_max_streams(
+    QuicStreamIdManager* stream_id_manager,
+    QuicStreamCount count) {
+  stream_id_manager->outgoing_max_streams_ = count;
+}
+
+// static
+QuicStreamId QuicStreamIdManagerPeer::GetFirstIncomingStreamId(
+    QuicStreamIdManager* stream_id_manager) {
+  return stream_id_manager->GetFirstIncomingStreamId();
+}
+
+// static
+bool QuicStreamIdManagerPeer::get_unidirectional(
+    QuicStreamIdManager* stream_id_manager) {
+  return stream_id_manager->unidirectional_;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_stream_id_manager_peer.h b/quiche/quic/test_tools/quic_stream_id_manager_peer.h
new file mode 100644
index 0000000..68799e2
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_id_manager_peer.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_ID_MANAGER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_ID_MANAGER_PEER_H_
+
+#include <stddef.h>
+
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QuicStreamIdManager;
+class UberQuicStreamIdManager;
+
+namespace test {
+
+class QuicStreamIdManagerPeer {
+ public:
+  QuicStreamIdManagerPeer() = delete;
+
+  static void set_incoming_actual_max_streams(
+      QuicStreamIdManager* stream_id_manager,
+      QuicStreamCount count);
+  static void set_outgoing_max_streams(QuicStreamIdManager* stream_id_manager,
+                                       QuicStreamCount count);
+
+  static QuicStreamId GetFirstIncomingStreamId(
+      QuicStreamIdManager* stream_id_manager);
+
+  static bool get_unidirectional(QuicStreamIdManager* stream_id_manager);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SESSION_PEER_H_
diff --git a/quiche/quic/test_tools/quic_stream_peer.cc b/quiche/quic/test_tools/quic_stream_peer.cc
new file mode 100644
index 0000000..594cb89
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_peer.cc
@@ -0,0 +1,120 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+
+#include <list>
+
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/test_tools/quic_flow_controller_peer.h"
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicStreamPeer::SetWriteSideClosed(bool value, QuicStream* stream) {
+  stream->write_side_closed_ = value;
+}
+
+// static
+void QuicStreamPeer::SetStreamBytesWritten(
+    QuicStreamOffset stream_bytes_written,
+    QuicStream* stream) {
+  stream->send_buffer_.stream_bytes_written_ = stream_bytes_written;
+  stream->send_buffer_.stream_bytes_outstanding_ = stream_bytes_written;
+  QuicStreamSendBufferPeer::SetStreamOffset(&stream->send_buffer_,
+                                            stream_bytes_written);
+}
+
+// static
+void QuicStreamPeer::SetSendWindowOffset(QuicStream* stream,
+                                         QuicStreamOffset offset) {
+  QuicFlowControllerPeer::SetSendWindowOffset(&*stream->flow_controller_,
+                                              offset);
+}
+
+// static
+QuicByteCount QuicStreamPeer::bytes_consumed(QuicStream* stream) {
+  return stream->flow_controller_->bytes_consumed();
+}
+
+// static
+void QuicStreamPeer::SetReceiveWindowOffset(QuicStream* stream,
+                                            QuicStreamOffset offset) {
+  QuicFlowControllerPeer::SetReceiveWindowOffset(&*stream->flow_controller_,
+                                                 offset);
+}
+
+// static
+void QuicStreamPeer::SetMaxReceiveWindow(QuicStream* stream,
+                                         QuicStreamOffset size) {
+  QuicFlowControllerPeer::SetMaxReceiveWindow(&*stream->flow_controller_, size);
+}
+
+// static
+QuicByteCount QuicStreamPeer::SendWindowSize(QuicStream* stream) {
+  return stream->flow_controller_->SendWindowSize();
+}
+
+// static
+QuicStreamOffset QuicStreamPeer::ReceiveWindowOffset(QuicStream* stream) {
+  return QuicFlowControllerPeer::ReceiveWindowOffset(
+      &*stream->flow_controller_);
+}
+
+// static
+QuicByteCount QuicStreamPeer::ReceiveWindowSize(QuicStream* stream) {
+  return QuicFlowControllerPeer::ReceiveWindowSize(&*stream->flow_controller_);
+}
+
+// static
+QuicStreamOffset QuicStreamPeer::SendWindowOffset(QuicStream* stream) {
+  return stream->flow_controller_->send_window_offset();
+}
+
+// static
+bool QuicStreamPeer::read_side_closed(QuicStream* stream) {
+  return stream->read_side_closed_;
+}
+
+// static
+void QuicStreamPeer::CloseReadSide(QuicStream* stream) {
+  stream->CloseReadSide();
+}
+
+// static
+bool QuicStreamPeer::StreamContributesToConnectionFlowControl(
+    QuicStream* stream) {
+  return stream->stream_contributes_to_connection_flow_control_;
+}
+
+// static
+QuicStreamSequencer* QuicStreamPeer::sequencer(QuicStream* stream) {
+  return &(stream->sequencer_);
+}
+
+// static
+QuicSession* QuicStreamPeer::session(QuicStream* stream) {
+  return stream->session();
+}
+
+// static
+QuicStreamSendBuffer& QuicStreamPeer::SendBuffer(QuicStream* stream) {
+  return stream->send_buffer_;
+}
+
+// static
+void QuicStreamPeer::SetFinReceived(QuicStream* stream) {
+  stream->fin_received_ = true;
+}
+
+// static
+void QuicStreamPeer::SetFinSent(QuicStream* stream) {
+  stream->fin_sent_ = true;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_stream_peer.h b/quiche/quic/test_tools/quic_stream_peer.h
new file mode 100644
index 0000000..3525deb
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_peer.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+
+class QuicStream;
+class QuicSession;
+
+namespace test {
+
+class QuicStreamPeer {
+ public:
+  QuicStreamPeer() = delete;
+
+  static void SetWriteSideClosed(bool value, QuicStream* stream);
+  static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written,
+                                    QuicStream* stream);
+  static void SetSendWindowOffset(QuicStream* stream, QuicStreamOffset offset);
+  static void SetReceiveWindowOffset(QuicStream* stream,
+                                     QuicStreamOffset offset);
+  static void SetMaxReceiveWindow(QuicStream* stream, QuicStreamOffset size);
+  static bool read_side_closed(QuicStream* stream);
+  static void CloseReadSide(QuicStream* stream);
+  static QuicByteCount bytes_consumed(QuicStream* stream);
+  static QuicByteCount ReceiveWindowSize(QuicStream* stream);
+  static QuicByteCount SendWindowSize(QuicStream* stream);
+  static QuicStreamOffset SendWindowOffset(QuicStream* stream);
+  static QuicStreamOffset ReceiveWindowOffset(QuicStream* stream);
+
+  static bool StreamContributesToConnectionFlowControl(QuicStream* stream);
+
+  static QuicStreamSequencer* sequencer(QuicStream* stream);
+  static QuicSession* session(QuicStream* stream);
+  static void SetFinReceived(QuicStream* stream);
+  static void SetFinSent(QuicStream* stream);
+
+  static QuicStreamSendBuffer& SendBuffer(QuicStream* stream);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_PEER_H_
diff --git a/quiche/quic/test_tools/quic_stream_send_buffer_peer.cc b/quiche/quic/test_tools/quic_stream_send_buffer_peer.cc
new file mode 100644
index 0000000..e4554fa
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_send_buffer_peer.cc
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "quiche/quic/test_tools/quic_interval_deque_peer.h"
+
+namespace quic {
+
+namespace test {
+
+// static
+void QuicStreamSendBufferPeer::SetStreamOffset(
+    QuicStreamSendBuffer* send_buffer,
+    QuicStreamOffset stream_offset) {
+  send_buffer->stream_offset_ = stream_offset;
+}
+
+// static
+const BufferedSlice* QuicStreamSendBufferPeer::CurrentWriteSlice(
+    QuicStreamSendBuffer* send_buffer) {
+  auto wi = write_index(send_buffer);
+
+  if (wi == -1) {
+    return nullptr;
+  }
+  return QuicIntervalDequePeer::GetItem(&send_buffer->interval_deque_, wi);
+}
+
+QuicStreamOffset QuicStreamSendBufferPeer::EndOffset(
+    QuicStreamSendBuffer* send_buffer) {
+  return send_buffer->current_end_offset_;
+}
+
+// static
+QuicByteCount QuicStreamSendBufferPeer::TotalLength(
+    QuicStreamSendBuffer* send_buffer) {
+  QuicByteCount length = 0;
+  for (auto slice = send_buffer->interval_deque_.DataBegin();
+       slice != send_buffer->interval_deque_.DataEnd(); ++slice) {
+    length += slice->slice.length();
+  }
+  return length;
+}
+
+// static
+int32_t QuicStreamSendBufferPeer::write_index(
+    QuicStreamSendBuffer* send_buffer) {
+  return QuicIntervalDequePeer::GetCachedIndex(&send_buffer->interval_deque_);
+}
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_stream_send_buffer_peer.h b/quiche/quic/test_tools/quic_stream_send_buffer_peer.h
new file mode 100644
index 0000000..9792290
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_send_buffer_peer.h
@@ -0,0 +1,33 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
+
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+
+namespace quic {
+
+namespace test {
+
+class QuicStreamSendBufferPeer {
+ public:
+  static void SetStreamOffset(QuicStreamSendBuffer* send_buffer,
+                              QuicStreamOffset stream_offset);
+
+  static const BufferedSlice* CurrentWriteSlice(
+      QuicStreamSendBuffer* send_buffer);
+
+  static QuicStreamOffset EndOffset(QuicStreamSendBuffer* send_buffer);
+
+  static QuicByteCount TotalLength(QuicStreamSendBuffer* send_buffer);
+
+  static int32_t write_index(QuicStreamSendBuffer* send_buffer);
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEND_BUFFER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
new file mode 100644
index 0000000..63d8a4b
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
@@ -0,0 +1,162 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h"
+#include <cstddef>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+using BufferBlock = quic::QuicStreamSequencerBuffer::BufferBlock;
+
+static const size_t kBlockSizeBytes =
+    quic::QuicStreamSequencerBuffer::kBlockSizeBytes;
+
+namespace quic {
+namespace test {
+
+QuicStreamSequencerBufferPeer::QuicStreamSequencerBufferPeer(
+    QuicStreamSequencerBuffer* buffer)
+    : buffer_(buffer) {}
+
+// Read from this buffer_ into the given destination buffer_ up to the
+// size of the destination. Returns the number of bytes read. Reading from
+// an empty buffer_->returns 0.
+size_t QuicStreamSequencerBufferPeer::Read(char* dest_buffer, size_t size) {
+  iovec dest;
+  dest.iov_base = dest_buffer, dest.iov_len = size;
+  size_t bytes_read;
+  std::string error_details;
+  EXPECT_THAT(buffer_->Readv(&dest, 1, &bytes_read, &error_details),
+              IsQuicNoError());
+  return bytes_read;
+}
+
+// If buffer is empty, the blocks_ array must be empty, which means all
+// blocks are deallocated.
+bool QuicStreamSequencerBufferPeer::CheckEmptyInvariants() {
+  return !buffer_->Empty() || IsBlockArrayEmpty();
+}
+
+bool QuicStreamSequencerBufferPeer::IsBlockArrayEmpty() {
+  if (buffer_->blocks_ == nullptr) {
+    return true;
+  }
+
+  size_t count = current_blocks_count();
+  for (size_t i = 0; i < count; i++) {
+    if (buffer_->blocks_[i] != nullptr) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool QuicStreamSequencerBufferPeer::CheckInitialState() {
+  EXPECT_TRUE(buffer_->Empty() && buffer_->total_bytes_read_ == 0 &&
+              buffer_->num_bytes_buffered_ == 0);
+  return CheckBufferInvariants();
+}
+
+bool QuicStreamSequencerBufferPeer::CheckBufferInvariants() {
+  QuicStreamOffset data_span =
+      buffer_->NextExpectedByte() - buffer_->total_bytes_read_;
+  bool capacity_sane = data_span <= buffer_->max_buffer_capacity_bytes_ &&
+                       data_span >= buffer_->num_bytes_buffered_;
+  if (!capacity_sane) {
+    QUIC_LOG(ERROR) << "data span is larger than capacity.";
+    QUIC_LOG(ERROR) << "total read: " << buffer_->total_bytes_read_
+                    << " last byte: " << buffer_->NextExpectedByte();
+  }
+  bool total_read_sane =
+      buffer_->FirstMissingByte() >= buffer_->total_bytes_read_;
+  if (!total_read_sane) {
+    QUIC_LOG(ERROR) << "read across 1st gap.";
+  }
+  bool read_offset_sane = buffer_->ReadOffset() < kBlockSizeBytes;
+  if (!capacity_sane) {
+    QUIC_LOG(ERROR) << "read offset go beyond 1st block";
+  }
+  bool block_match_capacity =
+      (buffer_->max_buffer_capacity_bytes_ <=
+       buffer_->max_blocks_count_ * kBlockSizeBytes) &&
+      (buffer_->max_buffer_capacity_bytes_ >
+       (buffer_->max_blocks_count_ - 1) * kBlockSizeBytes);
+  if (!capacity_sane) {
+    QUIC_LOG(ERROR) << "block number not match capcaity.";
+  }
+  bool block_retired_when_empty = CheckEmptyInvariants();
+  if (!block_retired_when_empty) {
+    QUIC_LOG(ERROR) << "block is not retired after use.";
+  }
+  return capacity_sane && total_read_sane && read_offset_sane &&
+         block_match_capacity && block_retired_when_empty;
+}
+
+size_t QuicStreamSequencerBufferPeer::GetInBlockOffset(
+    QuicStreamOffset offset) {
+  return buffer_->GetInBlockOffset(offset);
+}
+
+BufferBlock* QuicStreamSequencerBufferPeer::GetBlock(size_t index) {
+  return buffer_->blocks_[index];
+}
+
+int QuicStreamSequencerBufferPeer::IntervalSize() {
+  if (buffer_->bytes_received_.Empty()) {
+    return 1;
+  }
+  int gap_size = buffer_->bytes_received_.Size() + 1;
+  if (buffer_->bytes_received_.Empty()) {
+    return gap_size;
+  }
+  if (buffer_->bytes_received_.begin()->min() == 0) {
+    --gap_size;
+  }
+  if (buffer_->bytes_received_.rbegin()->max() ==
+      std::numeric_limits<uint64_t>::max()) {
+    --gap_size;
+  }
+  return gap_size;
+}
+
+size_t QuicStreamSequencerBufferPeer::max_buffer_capacity() {
+  return buffer_->max_buffer_capacity_bytes_;
+}
+
+size_t QuicStreamSequencerBufferPeer::ReadableBytes() {
+  return buffer_->ReadableBytes();
+}
+
+void QuicStreamSequencerBufferPeer::set_total_bytes_read(
+    QuicStreamOffset total_bytes_read) {
+  buffer_->total_bytes_read_ = total_bytes_read;
+}
+
+void QuicStreamSequencerBufferPeer::AddBytesReceived(QuicStreamOffset offset,
+                                                     QuicByteCount length) {
+  buffer_->bytes_received_.Add(offset, offset + length);
+}
+
+bool QuicStreamSequencerBufferPeer::IsBufferAllocated() {
+  return buffer_->blocks_ != nullptr;
+}
+
+size_t QuicStreamSequencerBufferPeer::max_blocks_count() {
+  return buffer_->max_blocks_count_;
+}
+
+size_t QuicStreamSequencerBufferPeer::current_blocks_count() {
+  return buffer_->current_blocks_count_;
+}
+
+const QuicIntervalSet<QuicStreamOffset>&
+QuicStreamSequencerBufferPeer::bytes_received() {
+  return buffer_->bytes_received_;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h
new file mode 100644
index 0000000..eac892a
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h
@@ -0,0 +1,65 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
+
+#include "quiche/quic/core/quic_stream_sequencer_buffer.h"
+
+namespace quic {
+
+namespace test {
+
+class QuicStreamSequencerBufferPeer {
+ public:
+  explicit QuicStreamSequencerBufferPeer(QuicStreamSequencerBuffer* buffer);
+  QuicStreamSequencerBufferPeer(const QuicStreamSequencerBufferPeer&) = delete;
+  QuicStreamSequencerBufferPeer& operator=(
+      const QuicStreamSequencerBufferPeer&) = delete;
+
+  // Read from this buffer_ into the given destination buffer_ up to the
+  // size of the destination. Returns the number of bytes read. Reading from
+  // an empty buffer_->returns 0.
+  size_t Read(char* dest_buffer, size_t size);
+
+  // If buffer is empty, the blocks_ array must be empty, which means all
+  // blocks are deallocated.
+  bool CheckEmptyInvariants();
+
+  bool IsBlockArrayEmpty();
+
+  bool CheckInitialState();
+
+  bool CheckBufferInvariants();
+
+  size_t GetInBlockOffset(QuicStreamOffset offset);
+
+  QuicStreamSequencerBuffer::BufferBlock* GetBlock(size_t index);
+
+  int IntervalSize();
+
+  size_t max_buffer_capacity();
+
+  size_t ReadableBytes();
+
+  void set_total_bytes_read(QuicStreamOffset total_bytes_read);
+
+  void AddBytesReceived(QuicStreamOffset offset, QuicByteCount length);
+
+  bool IsBufferAllocated();
+
+  size_t max_blocks_count();
+
+  size_t current_blocks_count();
+
+  const QuicIntervalSet<QuicStreamOffset>& bytes_received();
+
+ private:
+  QuicStreamSequencerBuffer* buffer_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_BUFFER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_stream_sequencer_peer.cc b/quiche/quic/test_tools/quic_stream_sequencer_peer.cc
new file mode 100644
index 0000000..100f38e
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_sequencer_peer.cc
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_stream_sequencer_peer.h"
+
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/test_tools/quic_stream_sequencer_buffer_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+size_t QuicStreamSequencerPeer::GetNumBufferedBytes(
+    QuicStreamSequencer* sequencer) {
+  return sequencer->buffered_frames_.BytesBuffered();
+}
+
+// static
+QuicStreamOffset QuicStreamSequencerPeer::GetCloseOffset(
+    QuicStreamSequencer* sequencer) {
+  return sequencer->close_offset_;
+}
+
+// static
+bool QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(
+    QuicStreamSequencer* sequencer) {
+  QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
+  return buffer_peer.IsBufferAllocated();
+}
+
+// static
+void QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
+    QuicStreamSequencer* sequencer,
+    QuicStreamOffset total_bytes_read) {
+  QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
+  buffer_peer.set_total_bytes_read(total_bytes_read);
+}
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_stream_sequencer_peer.h b/quiche/quic/test_tools/quic_stream_sequencer_peer.h
new file mode 100644
index 0000000..4be113f
--- /dev/null
+++ b/quiche/quic/test_tools/quic_stream_sequencer_peer.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+class QuicStreamSequencer;
+
+namespace test {
+
+class QuicStreamSequencerPeer {
+ public:
+  QuicStreamSequencerPeer() = delete;
+
+  static size_t GetNumBufferedBytes(QuicStreamSequencer* sequencer);
+
+  static QuicStreamOffset GetCloseOffset(QuicStreamSequencer* sequencer);
+
+  static bool IsUnderlyingBufferAllocated(QuicStreamSequencer* sequencer);
+
+  static void SetFrameBufferTotalBytesRead(QuicStreamSequencer* sequencer,
+                                           QuicStreamOffset total_bytes_read);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_STREAM_SEQUENCER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc b/quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
new file mode 100644
index 0000000..46fa83c
--- /dev/null
+++ b/quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.cc
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
+
+namespace quic {
+namespace test {
+
+// static
+void QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
+    QuicSustainedBandwidthRecorder* bandwidth_recorder,
+    int32_t bandwidth_estimate_kbytes_per_second) {
+  bandwidth_recorder->has_estimate_ = true;
+  bandwidth_recorder->bandwidth_estimate_ =
+      QuicBandwidth::FromKBytesPerSecond(bandwidth_estimate_kbytes_per_second);
+}
+
+// static
+void QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
+    QuicSustainedBandwidthRecorder* bandwidth_recorder,
+    int32_t max_bandwidth_estimate_kbytes_per_second,
+    int32_t max_bandwidth_timestamp) {
+  bandwidth_recorder->max_bandwidth_estimate_ =
+      QuicBandwidth::FromKBytesPerSecond(
+          max_bandwidth_estimate_kbytes_per_second);
+  bandwidth_recorder->max_bandwidth_timestamp_ = max_bandwidth_timestamp;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h b/quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
new file mode 100644
index 0000000..b60412c
--- /dev/null
+++ b/quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h
@@ -0,0 +1,35 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
+
+#include <cstdint>
+
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+class QuicSustainedBandwidthRecorder;
+
+namespace test {
+
+class QuicSustainedBandwidthRecorderPeer {
+ public:
+  QuicSustainedBandwidthRecorderPeer() = delete;
+
+  static void SetBandwidthEstimate(
+      QuicSustainedBandwidthRecorder* bandwidth_recorder,
+      int32_t bandwidth_estimate_kbytes_per_second);
+
+  static void SetMaxBandwidthEstimate(
+      QuicSustainedBandwidthRecorder* bandwidth_recorder,
+      int32_t max_bandwidth_estimate_kbytes_per_second,
+      int32_t max_bandwidth_timestamp);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_SUSTAINED_BANDWIDTH_RECORDER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_test_backend.cc b/quiche/quic/test_tools/quic_test_backend.cc
new file mode 100644
index 0000000..756c560
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_backend.cc
@@ -0,0 +1,120 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_test_backend.h"
+
+#include <cstring>
+#include <memory>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/test_tools/web_transport_resets_backend.h"
+#include "quiche/quic/tools/web_transport_test_visitors.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+// SessionCloseVisitor implements the "/session-close" endpoint.  If the client
+// sends a unidirectional stream of format "code message" to this endpoint, it
+// will close the session with the corresponding error code and error message.
+// For instance, sending "42 test error" will cause it to be closed with code 42
+// and message "test error".
+class SessionCloseVisitor : public WebTransportVisitor {
+ public:
+  SessionCloseVisitor(WebTransportSession* session) : session_(session) {}
+
+  void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
+  void OnSessionClosed(WebTransportSessionError /*error_code*/,
+                       const std::string& /*error_message*/) override {}
+
+  void OnIncomingBidirectionalStreamAvailable() override {}
+  void OnIncomingUnidirectionalStreamAvailable() override {
+    WebTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
+    if (stream == nullptr) {
+      return;
+    }
+    stream->SetVisitor(
+        std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
+            stream, [this](const std::string& data) {
+              std::pair<absl::string_view, absl::string_view> parsed =
+                  absl::StrSplit(data, absl::MaxSplits(' ', 1));
+              WebTransportSessionError error_code = 0;
+              bool success = absl::SimpleAtoi(parsed.first, &error_code);
+              QUICHE_DCHECK(success) << data;
+              session_->CloseSession(error_code, parsed.second);
+            }));
+    stream->visitor()->OnCanRead();
+  }
+
+  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
+
+  void OnCanCreateNewOutgoingBidirectionalStream() override {}
+  void OnCanCreateNewOutgoingUnidirectionalStream() override {}
+
+ private:
+  WebTransportSession* session_;  // Not owned.
+};
+
+}  // namespace
+
+QuicSimpleServerBackend::WebTransportResponse
+QuicTestBackend::ProcessWebTransportRequest(
+    const spdy::Http2HeaderBlock& request_headers,
+    WebTransportSession* session) {
+  if (!SupportsWebTransport()) {
+    return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
+                                                               session);
+  }
+
+  auto path_it = request_headers.find(":path");
+  if (path_it == request_headers.end()) {
+    WebTransportResponse response;
+    response.response_headers[":status"] = "400";
+    return response;
+  }
+  absl::string_view path = path_it->second;
+  // Match any "/echo.*" pass, e.g. "/echo_foobar"
+  if (absl::StartsWith(path, "/echo")) {
+    WebTransportResponse response;
+    response.response_headers[":status"] = "200";
+    // Add response headers if the paramer has "set-header=XXX:YYY" query.
+    GURL url = GURL(absl::StrCat("https://localhost", path));
+    const std::vector<std::string>& params = absl::StrSplit(url.query(), '&');
+    for (const auto& param : params) {
+      absl::string_view param_view = param;
+      if (absl::ConsumePrefix(&param_view, "set-header=")) {
+        const std::vector<absl::string_view> header_value =
+            absl::StrSplit(param_view, ':');
+        if (header_value.size() == 2 &&
+            !absl::StartsWith(header_value[0], ":")) {
+          response.response_headers[header_value[0]] = header_value[1];
+        }
+      }
+    }
+
+    response.visitor =
+        std::make_unique<EchoWebTransportSessionVisitor>(session);
+    return response;
+  }
+  if (path == "/resets") {
+    return WebTransportResetsBackend(request_headers, session);
+  }
+  if (path == "/session-close") {
+    WebTransportResponse response;
+    response.response_headers[":status"] = "200";
+    response.visitor = std::make_unique<SessionCloseVisitor>(session);
+    return response;
+  }
+
+  WebTransportResponse response;
+  response.response_headers[":status"] = "404";
+  return response;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_test_backend.h b/quiche/quic/test_tools/quic_test_backend.h
new file mode 100644
index 0000000..8fef41a
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_backend.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
+
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace quic {
+namespace test {
+
+// QuicTestBackend is a QuicSimpleServer backend usable in tests.  It has extra
+// WebTransport endpoints on top of what QuicMemoryCacheBackend already
+// provides.
+class QuicTestBackend : public QuicMemoryCacheBackend {
+ public:
+  WebTransportResponse ProcessWebTransportRequest(
+      const spdy::Http2HeaderBlock& request_headers,
+      WebTransportSession* session) override;
+  bool SupportsWebTransport() override { return enable_webtransport_; }
+
+  void set_enable_webtransport(bool enable_webtransport) {
+    QUICHE_DCHECK(!enable_webtransport || enable_extended_connect_);
+    enable_webtransport_ = enable_webtransport;
+  }
+
+  bool UsesDatagramContexts() override { return use_datagram_contexts_; }
+
+  void set_use_datagram_contexts(bool use_datagram_contexts) {
+    use_datagram_contexts_ = use_datagram_contexts;
+  }
+
+  bool SupportsExtendedConnect() override { return enable_extended_connect_; }
+
+  void set_enable_extended_connect(bool enable_extended_connect) {
+    enable_extended_connect_ = enable_extended_connect;
+  }
+
+ private:
+  bool enable_webtransport_ = false;
+  bool use_datagram_contexts_ = false;
+  bool enable_extended_connect_ = true;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_BACKEND_H_
diff --git a/quiche/quic/test_tools/quic_test_client.cc b/quiche/quic/test_tools/quic_test_client.cc
new file mode 100644
index 0000000..4dd2779
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_client.cc
@@ -0,0 +1,1010 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_test_client.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/x509.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_packet_writer_wrapper.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_stack_trace.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_client_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// RecordingProofVerifier accepts any certificate chain and records the common
+// name of the leaf and then delegates the actual verification to an actual
+// verifier. If no optional verifier is provided, then VerifyProof will return
+// success.
+class RecordingProofVerifier : public ProofVerifier {
+ public:
+  explicit RecordingProofVerifier(std::unique_ptr<ProofVerifier> verifier)
+      : verifier_(std::move(verifier)) {}
+
+  // ProofVerifier interface.
+  QuicAsyncStatus VerifyProof(
+      const std::string& hostname,
+      const uint16_t port,
+      const std::string& server_config,
+      QuicTransportVersion transport_version,
+      absl::string_view chlo_hash,
+      const std::vector<std::string>& certs,
+      const std::string& cert_sct,
+      const std::string& signature,
+      const ProofVerifyContext* context,
+      std::string* error_details,
+      std::unique_ptr<ProofVerifyDetails>* details,
+      std::unique_ptr<ProofVerifierCallback> callback) override {
+    QuicAsyncStatus process_certs_result = ProcessCerts(certs, cert_sct);
+    if (process_certs_result != QUIC_SUCCESS) {
+      return process_certs_result;
+    }
+
+    if (!verifier_) {
+      return QUIC_SUCCESS;
+    }
+
+    return verifier_->VerifyProof(hostname, port, server_config,
+                                  transport_version, chlo_hash, certs, cert_sct,
+                                  signature, context, error_details, details,
+                                  std::move(callback));
+  }
+
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::vector<std::string>& certs,
+      const std::string& /*ocsp_response*/,
+      const std::string& cert_sct,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*details*/,
+      uint8_t* /*out_alert*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return ProcessCerts(certs, cert_sct);
+  }
+
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    return verifier_ != nullptr ? verifier_->CreateDefaultContext() : nullptr;
+  }
+
+  const std::string& common_name() const { return common_name_; }
+
+  const std::string& cert_sct() const { return cert_sct_; }
+
+ private:
+  QuicAsyncStatus ProcessCerts(const std::vector<std::string>& certs,
+                               const std::string& cert_sct) {
+    common_name_.clear();
+    if (certs.empty()) {
+      return QUIC_FAILURE;
+    }
+
+    // Parse the cert into an X509 structure.
+    const uint8_t* data;
+    data = reinterpret_cast<const uint8_t*>(certs[0].data());
+    bssl::UniquePtr<X509> cert(d2i_X509(nullptr, &data, certs[0].size()));
+    if (!cert.get()) {
+      return QUIC_FAILURE;
+    }
+
+    // Extract the CN field
+    X509_NAME* subject = X509_get_subject_name(cert.get());
+    const int index = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
+    if (index < 0) {
+      return QUIC_FAILURE;
+    }
+    ASN1_STRING* name_data =
+        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, index));
+    if (name_data == nullptr) {
+      return QUIC_FAILURE;
+    }
+
+    // Convert the CN to UTF8, in case the cert represents it in a different
+    // format.
+    unsigned char* buf = nullptr;
+    const int len = ASN1_STRING_to_UTF8(&buf, name_data);
+    if (len <= 0) {
+      return QUIC_FAILURE;
+    }
+    bssl::UniquePtr<unsigned char> deleter(buf);
+
+    common_name_.assign(reinterpret_cast<const char*>(buf), len);
+    cert_sct_ = cert_sct;
+    return QUIC_SUCCESS;
+  }
+
+  std::unique_ptr<ProofVerifier> verifier_;
+  std::string common_name_;
+  std::string cert_sct_;
+};
+}  // namespace
+
+class MockableQuicClientEpollNetworkHelper
+    : public QuicClientEpollNetworkHelper {
+ public:
+  using QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper;
+  ~MockableQuicClientEpollNetworkHelper() override = default;
+
+  void ProcessPacket(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address,
+                     const QuicReceivedPacket& packet) override {
+    QuicClientEpollNetworkHelper::ProcessPacket(self_address, peer_address,
+                                                packet);
+    if (track_last_incoming_packet_) {
+      last_incoming_packet_ = packet.Clone();
+    }
+  }
+
+  QuicPacketWriter* CreateQuicPacketWriter() override {
+    QuicPacketWriter* writer =
+        QuicClientEpollNetworkHelper::CreateQuicPacketWriter();
+    if (!test_writer_) {
+      return writer;
+    }
+    test_writer_->set_writer(writer);
+    return test_writer_;
+  }
+
+  const QuicReceivedPacket* last_incoming_packet() {
+    return last_incoming_packet_.get();
+  }
+
+  void set_track_last_incoming_packet(bool track) {
+    track_last_incoming_packet_ = track;
+  }
+
+  void UseWriter(QuicPacketWriterWrapper* writer) {
+    QUICHE_CHECK(test_writer_ == nullptr);
+    test_writer_ = writer;
+  }
+
+  void set_peer_address(const QuicSocketAddress& address) {
+    QUICHE_CHECK(test_writer_ != nullptr);
+    test_writer_->set_peer_address(address);
+  }
+
+ private:
+  QuicPacketWriterWrapper* test_writer_ = nullptr;
+  // The last incoming packet, iff |track_last_incoming_packet_| is true.
+  std::unique_ptr<QuicReceivedPacket> last_incoming_packet_;
+  // If true, copy each packet from ProcessPacket into |last_incoming_packet_|
+  bool track_last_incoming_packet_ = false;
+};
+
+MockableQuicClient::MockableQuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicEpollServer* epoll_server)
+    : MockableQuicClient(server_address,
+                         server_id,
+                         QuicConfig(),
+                         supported_versions,
+                         epoll_server) {}
+
+MockableQuicClient::MockableQuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicEpollServer* epoll_server)
+    : MockableQuicClient(server_address,
+                         server_id,
+                         config,
+                         supported_versions,
+                         epoll_server,
+                         nullptr) {}
+
+MockableQuicClient::MockableQuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<ProofVerifier> proof_verifier)
+    : MockableQuicClient(server_address,
+                         server_id,
+                         config,
+                         supported_versions,
+                         epoll_server,
+                         std::move(proof_verifier),
+                         nullptr) {}
+
+MockableQuicClient::MockableQuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : QuicClient(
+          server_address,
+          server_id,
+          supported_versions,
+          config,
+          epoll_server,
+          std::make_unique<MockableQuicClientEpollNetworkHelper>(epoll_server,
+                                                                 this),
+          std::make_unique<RecordingProofVerifier>(std::move(proof_verifier)),
+          std::move(session_cache)),
+      override_server_connection_id_(EmptyQuicConnectionId()),
+      server_connection_id_overridden_(false),
+      override_client_connection_id_(EmptyQuicConnectionId()),
+      client_connection_id_overridden_(false) {}
+
+MockableQuicClient::~MockableQuicClient() {
+  if (connected()) {
+    Disconnect();
+  }
+}
+
+MockableQuicClientEpollNetworkHelper*
+MockableQuicClient::mockable_network_helper() {
+  return static_cast<MockableQuicClientEpollNetworkHelper*>(
+      epoll_network_helper());
+}
+
+const MockableQuicClientEpollNetworkHelper*
+MockableQuicClient::mockable_network_helper() const {
+  return static_cast<const MockableQuicClientEpollNetworkHelper*>(
+      epoll_network_helper());
+}
+
+QuicConnectionId MockableQuicClient::GenerateNewConnectionId() {
+  if (server_connection_id_overridden_) {
+    return override_server_connection_id_;
+  }
+  if (override_server_connection_id_length_ >= 0) {
+    return QuicUtils::CreateRandomConnectionId(
+        override_server_connection_id_length_);
+  }
+  return QuicClient::GenerateNewConnectionId();
+}
+
+void MockableQuicClient::UseConnectionId(
+    QuicConnectionId server_connection_id) {
+  server_connection_id_overridden_ = true;
+  override_server_connection_id_ = server_connection_id;
+}
+
+void MockableQuicClient::UseConnectionIdLength(
+    int server_connection_id_length) {
+  override_server_connection_id_length_ = server_connection_id_length;
+}
+
+QuicConnectionId MockableQuicClient::GetClientConnectionId() {
+  if (client_connection_id_overridden_) {
+    return override_client_connection_id_;
+  }
+  if (override_client_connection_id_length_ >= 0) {
+    return QuicUtils::CreateRandomConnectionId(
+        override_client_connection_id_length_);
+  }
+  return QuicClient::GetClientConnectionId();
+}
+
+void MockableQuicClient::UseClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  client_connection_id_overridden_ = true;
+  override_client_connection_id_ = client_connection_id;
+}
+
+void MockableQuicClient::UseClientConnectionIdLength(
+    int client_connection_id_length) {
+  override_client_connection_id_length_ = client_connection_id_length;
+}
+
+void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
+  mockable_network_helper()->UseWriter(writer);
+}
+
+void MockableQuicClient::set_peer_address(const QuicSocketAddress& address) {
+  mockable_network_helper()->set_peer_address(address);
+  if (client_session() != nullptr) {
+    client_session()->AddKnownServerAddress(address);
+  }
+}
+
+const QuicReceivedPacket* MockableQuicClient::last_incoming_packet() {
+  return mockable_network_helper()->last_incoming_packet();
+}
+
+void MockableQuicClient::set_track_last_incoming_packet(bool track) {
+  mockable_network_helper()->set_track_last_incoming_packet(track);
+}
+
+QuicTestClient::QuicTestClient(
+    QuicSocketAddress server_address,
+    const std::string& server_hostname,
+    const ParsedQuicVersionVector& supported_versions)
+    : QuicTestClient(server_address,
+                     server_hostname,
+                     QuicConfig(),
+                     supported_versions) {}
+
+QuicTestClient::QuicTestClient(
+    QuicSocketAddress server_address,
+    const std::string& server_hostname,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions)
+    : client_(new MockableQuicClient(
+          server_address,
+          QuicServerId(server_hostname, server_address.port(), false),
+          config,
+          supported_versions,
+          &epoll_server_)) {
+  Initialize();
+}
+
+QuicTestClient::QuicTestClient(
+    QuicSocketAddress server_address,
+    const std::string& server_hostname,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    std::unique_ptr<ProofVerifier> proof_verifier)
+    : client_(new MockableQuicClient(
+          server_address,
+          QuicServerId(server_hostname, server_address.port(), false),
+          config,
+          supported_versions,
+          &epoll_server_,
+          std::move(proof_verifier))) {
+  Initialize();
+}
+
+QuicTestClient::QuicTestClient(
+    QuicSocketAddress server_address,
+    const std::string& server_hostname,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : client_(new MockableQuicClient(
+          server_address,
+          QuicServerId(server_hostname, server_address.port(), false),
+          config,
+          supported_versions,
+          &epoll_server_,
+          std::move(proof_verifier),
+          std::move(session_cache))) {
+  Initialize();
+}
+
+QuicTestClient::QuicTestClient() = default;
+
+QuicTestClient::~QuicTestClient() {
+  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
+    stream.second->set_visitor(nullptr);
+  }
+}
+
+void QuicTestClient::Initialize() {
+  priority_ = 3;
+  connect_attempted_ = false;
+  auto_reconnect_ = false;
+  buffer_body_ = true;
+  num_requests_ = 0;
+  num_responses_ = 0;
+  ClearPerConnectionState();
+  // As chrome will generally do this, we want it to be the default when it's
+  // not overridden.
+  if (!client_->config()->HasSetBytesForConnectionIdToSend()) {
+    client_->config()->SetBytesForConnectionIdToSend(0);
+  }
+}
+
+void QuicTestClient::SetUserAgentID(const std::string& user_agent_id) {
+  client_->SetUserAgentID(user_agent_id);
+}
+
+ssize_t QuicTestClient::SendRequest(const std::string& uri) {
+  spdy::SpdyHeaderBlock headers;
+  if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
+    return 0;
+  }
+  return SendMessage(headers, "");
+}
+
+ssize_t QuicTestClient::SendRequestAndRstTogether(const std::string& uri) {
+  spdy::SpdyHeaderBlock headers;
+  if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
+    return 0;
+  }
+
+  QuicSpdyClientSession* session = client()->client_session();
+  QuicConnection::ScopedPacketFlusher flusher(session->connection());
+  ssize_t ret = SendMessage(headers, "", /*fin=*/true, /*flush=*/false);
+
+  QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(
+      session->transport_version(), 0);
+  session->ResetStream(stream_id, QUIC_STREAM_CANCELLED);
+  return ret;
+}
+
+void QuicTestClient::SendRequestsAndWaitForResponses(
+    const std::vector<std::string>& url_list) {
+  for (const std::string& url : url_list) {
+    SendRequest(url);
+  }
+  while (client()->WaitForEvents()) {
+  }
+}
+
+ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
+    const spdy::SpdyHeaderBlock* headers, absl::string_view body, bool fin,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  if (headers) {
+    QuicClientPushPromiseIndex::TryHandle* handle;
+    QuicAsyncStatus rv =
+        client()->push_promise_index()->Try(*headers, this, &handle);
+    if (rv == QUIC_SUCCESS)
+      return 1;
+    if (rv == QUIC_PENDING) {
+      // May need to retry request if asynchronous rendezvous fails.
+      std::unique_ptr<spdy::SpdyHeaderBlock> new_headers(
+          new spdy::SpdyHeaderBlock(headers->Clone()));
+      push_promise_data_to_resend_ = std::make_unique<TestClientDataToResend>(
+          std::move(new_headers), body, fin, this, std::move(ack_listener));
+      return 1;
+    }
+  }
+
+  // Maybe it's better just to overload this.  it's just that we need
+  // for the GetOrCreateStream function to call something else...which
+  // is icky and complicated, but maybe not worse than this.
+  QuicSpdyClientStream* stream = GetOrCreateStream();
+  if (stream == nullptr) {
+    return 0;
+  }
+  QuicSpdyStreamPeer::set_ack_listener(stream, ack_listener);
+
+  ssize_t ret = 0;
+  if (headers != nullptr) {
+    spdy::SpdyHeaderBlock spdy_headers(headers->Clone());
+    if (spdy_headers[":authority"].as_string().empty()) {
+      spdy_headers[":authority"] = client_->server_id().host();
+    }
+    ret = stream->SendRequest(std::move(spdy_headers), body, fin);
+    ++num_requests_;
+  } else {
+    stream->WriteOrBufferBody(std::string(body), fin);
+    ret = body.length();
+  }
+  return ret;
+}
+
+ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
+                                    absl::string_view body) {
+  return SendMessage(headers, body, /*fin=*/true);
+}
+
+ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
+                                    absl::string_view body,
+                                    bool fin) {
+  return SendMessage(headers, body, fin, /*flush=*/true);
+}
+
+ssize_t QuicTestClient::SendMessage(const spdy::SpdyHeaderBlock& headers,
+                                    absl::string_view body,
+                                    bool fin,
+                                    bool flush) {
+  // Always force creation of a stream for SendMessage.
+  latest_created_stream_ = nullptr;
+
+  ssize_t ret = GetOrCreateStreamAndSendRequest(&headers, body, fin, nullptr);
+
+  if (flush) {
+    WaitForWriteToFlush();
+  }
+  return ret;
+}
+
+ssize_t QuicTestClient::SendData(const std::string& data, bool last_data) {
+  return SendData(data, last_data, nullptr);
+}
+
+ssize_t QuicTestClient::SendData(
+    const std::string& data, bool last_data,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener) {
+  return GetOrCreateStreamAndSendRequest(nullptr, absl::string_view(data),
+                                         last_data, std::move(ack_listener));
+}
+
+bool QuicTestClient::response_complete() const {
+  return response_complete_;
+}
+
+int64_t QuicTestClient::response_body_size() const {
+  return response_body_size_;
+}
+
+bool QuicTestClient::buffer_body() const {
+  return buffer_body_;
+}
+
+void QuicTestClient::set_buffer_body(bool buffer_body) {
+  buffer_body_ = buffer_body;
+}
+
+const std::string& QuicTestClient::response_body() const {
+  return response_;
+}
+
+std::string QuicTestClient::SendCustomSynchronousRequest(
+    const spdy::SpdyHeaderBlock& headers,
+    const std::string& body) {
+  // Clear connection state here and only track this synchronous request.
+  ClearPerConnectionState();
+  if (SendMessage(headers, body) == 0) {
+    QUIC_DLOG(ERROR) << "Failed the request for: " << headers.DebugString();
+    // Set the response_ explicitly.  Otherwise response_ will contain the
+    // response from the previously successful request.
+    response_ = "";
+  } else {
+    WaitForResponse();
+  }
+  return response_;
+}
+
+std::string QuicTestClient::SendSynchronousRequest(const std::string& uri) {
+  spdy::SpdyHeaderBlock headers;
+  if (!PopulateHeaderBlockFromUrl(uri, &headers)) {
+    return "";
+  }
+  return SendCustomSynchronousRequest(headers, "");
+}
+
+void QuicTestClient::SendConnectivityProbing() {
+  QuicConnection* connection = client()->client_session()->connection();
+  connection->SendConnectivityProbingPacket(connection->writer(),
+                                            connection->peer_address());
+}
+
+void QuicTestClient::SetLatestCreatedStream(QuicSpdyClientStream* stream) {
+  latest_created_stream_ = stream;
+  if (latest_created_stream_ != nullptr) {
+    open_streams_[stream->id()] = stream;
+    stream->set_visitor(this);
+  }
+}
+
+QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
+  if (!connect_attempted_ || auto_reconnect_) {
+    if (!connected()) {
+      Connect();
+    }
+    if (!connected()) {
+      return nullptr;
+    }
+  }
+  if (open_streams_.empty()) {
+    ClearPerConnectionState();
+  }
+  if (!latest_created_stream_) {
+    SetLatestCreatedStream(client_->CreateClientStream());
+    if (latest_created_stream_) {
+      latest_created_stream_->SetPriority(
+          spdy::SpdyStreamPrecedence(priority_));
+    }
+  }
+
+  return latest_created_stream_;
+}
+
+QuicErrorCode QuicTestClient::connection_error() const {
+  return client()->connection_error();
+}
+
+const std::string& QuicTestClient::cert_common_name() const {
+  return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
+      ->common_name();
+}
+
+const std::string& QuicTestClient::cert_sct() const {
+  return reinterpret_cast<RecordingProofVerifier*>(client_->proof_verifier())
+      ->cert_sct();
+}
+
+const QuicTagValueMap& QuicTestClient::GetServerConfig() const {
+  QuicCryptoClientConfig* config = client_->crypto_config();
+  const QuicCryptoClientConfig::CachedState* state =
+      config->LookupOrCreate(client_->server_id());
+  const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig();
+  return handshake_msg->tag_value_map();
+}
+
+bool QuicTestClient::connected() const {
+  return client_->connected();
+}
+
+void QuicTestClient::Connect() {
+  if (connected()) {
+    QUIC_BUG(quic_bug_10133_1) << "Cannot connect already-connected client";
+    return;
+  }
+  if (!connect_attempted_) {
+    client_->Initialize();
+  }
+
+  // If we've been asked to override SNI, set it now
+  if (override_sni_set_) {
+    client_->set_server_id(
+        QuicServerId(override_sni_, address().port(), false));
+  }
+
+  client_->Connect();
+  connect_attempted_ = true;
+}
+
+void QuicTestClient::ResetConnection() {
+  Disconnect();
+  Connect();
+}
+
+void QuicTestClient::Disconnect() {
+  ClearPerConnectionState();
+  if (client_->initialized()) {
+    client_->Disconnect();
+  }
+  connect_attempted_ = false;
+}
+
+QuicSocketAddress QuicTestClient::local_address() const {
+  return client_->network_helper()->GetLatestClientAddress();
+}
+
+void QuicTestClient::ClearPerRequestState() {
+  stream_error_ = QUIC_STREAM_NO_ERROR;
+  response_ = "";
+  response_complete_ = false;
+  response_headers_complete_ = false;
+  preliminary_headers_.clear();
+  response_headers_.clear();
+  response_trailers_.clear();
+  bytes_read_ = 0;
+  bytes_written_ = 0;
+  response_body_size_ = 0;
+}
+
+bool QuicTestClient::HaveActiveStream() {
+  return push_promise_data_to_resend_.get() || !open_streams_.empty();
+}
+
+bool QuicTestClient::WaitUntil(int timeout_ms, std::function<bool()> trigger) {
+  int64_t timeout_us = timeout_ms * kNumMicrosPerMilli;
+  int64_t old_timeout_us = epoll_server()->timeout_in_us_for_test();
+  if (timeout_us > 0) {
+    epoll_server()->set_timeout_in_us(timeout_us);
+  }
+  const QuicClock* clock =
+      QuicConnectionPeer::GetHelper(client()->session()->connection())
+          ->GetClock();
+  QuicTime end_waiting_time =
+      clock->Now() + QuicTime::Delta::FromMicroseconds(timeout_us);
+  while (HaveActiveStream() && !(trigger && trigger()) &&
+         (timeout_us < 0 || clock->Now() < end_waiting_time)) {
+    client_->WaitForEvents();
+  }
+  ReadNextResponse();
+  if (timeout_us > 0) {
+    epoll_server()->set_timeout_in_us(old_timeout_us);
+  }
+  if (trigger && !trigger()) {
+    QUIC_VLOG(1) << "Client WaitUntil returning with trigger returning false.";
+    return false;
+  }
+  return true;
+}
+
+ssize_t QuicTestClient::Send(absl::string_view data) {
+  return SendData(std::string(data), false);
+}
+
+bool QuicTestClient::response_headers_complete() const {
+  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
+    if (stream.second->headers_decompressed()) {
+      return true;
+    }
+  }
+  return response_headers_complete_;
+}
+
+const spdy::SpdyHeaderBlock* QuicTestClient::response_headers() const {
+  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
+    if (stream.second->headers_decompressed()) {
+      response_headers_ = stream.second->response_headers().Clone();
+      break;
+    }
+  }
+  return &response_headers_;
+}
+
+const spdy::SpdyHeaderBlock* QuicTestClient::preliminary_headers() const {
+  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
+    size_t bytes_read =
+        stream.second->stream_bytes_read() + stream.second->header_bytes_read();
+    if (bytes_read > 0) {
+      preliminary_headers_ = stream.second->preliminary_headers().Clone();
+      break;
+    }
+  }
+  return &preliminary_headers_;
+}
+
+const spdy::SpdyHeaderBlock& QuicTestClient::response_trailers() const {
+  return response_trailers_;
+}
+
+int64_t QuicTestClient::response_size() const {
+  return bytes_read();
+}
+
+size_t QuicTestClient::bytes_read() const {
+  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
+    size_t bytes_read = stream.second->total_body_bytes_read() +
+                        stream.second->header_bytes_read();
+    if (bytes_read > 0) {
+      return bytes_read;
+    }
+  }
+  return bytes_read_;
+}
+
+size_t QuicTestClient::bytes_written() const {
+  for (std::pair<QuicStreamId, QuicSpdyClientStream*> stream : open_streams_) {
+    size_t bytes_written = stream.second->stream_bytes_written() +
+                           stream.second->header_bytes_written();
+    if (bytes_written > 0) {
+      return bytes_written;
+    }
+  }
+  return bytes_written_;
+}
+
+void QuicTestClient::OnClose(QuicSpdyStream* stream) {
+  if (stream == nullptr) {
+    return;
+  }
+  // Always close the stream, regardless of whether it was the last stream
+  // written.
+  client()->OnClose(stream);
+  ++num_responses_;
+  if (open_streams_.find(stream->id()) == open_streams_.end()) {
+    return;
+  }
+  if (latest_created_stream_ == stream) {
+    latest_created_stream_ = nullptr;
+  }
+  QuicSpdyClientStream* client_stream =
+      static_cast<QuicSpdyClientStream*>(stream);
+  QuicStreamId id = client_stream->id();
+  closed_stream_states_.insert(std::make_pair(
+      id,
+      PerStreamState(
+          // Set response_complete to true iff stream is closed while connected.
+          client_stream->stream_error(), connected(),
+          client_stream->headers_decompressed(),
+          client_stream->response_headers(),
+          client_stream->preliminary_headers(),
+          (buffer_body() ? client_stream->data() : ""),
+          client_stream->received_trailers(),
+          // Use NumBytesConsumed to avoid counting retransmitted stream frames.
+          client_stream->total_body_bytes_read() +
+              client_stream->header_bytes_read(),
+          client_stream->stream_bytes_written() +
+              client_stream->header_bytes_written(),
+          client_stream->data().size())));
+  open_streams_.erase(id);
+}
+
+bool QuicTestClient::CheckVary(
+    const spdy::SpdyHeaderBlock& /*client_request*/,
+    const spdy::SpdyHeaderBlock& /*promise_request*/,
+    const spdy::SpdyHeaderBlock& /*promise_response*/) {
+  return true;
+}
+
+void QuicTestClient::OnRendezvousResult(QuicSpdyStream* stream) {
+  std::unique_ptr<TestClientDataToResend> data_to_resend =
+      std::move(push_promise_data_to_resend_);
+  SetLatestCreatedStream(static_cast<QuicSpdyClientStream*>(stream));
+  if (stream) {
+    stream->OnBodyAvailable();
+  } else if (data_to_resend) {
+    data_to_resend->Resend();
+  }
+}
+
+void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) {
+  client_->UseWriter(writer);
+}
+
+void QuicTestClient::UseConnectionId(QuicConnectionId server_connection_id) {
+  QUICHE_DCHECK(!connected());
+  client_->UseConnectionId(server_connection_id);
+}
+
+void QuicTestClient::UseConnectionIdLength(int server_connection_id_length) {
+  QUICHE_DCHECK(!connected());
+  client_->UseConnectionIdLength(server_connection_id_length);
+}
+
+void QuicTestClient::UseClientConnectionId(
+    QuicConnectionId client_connection_id) {
+  QUICHE_DCHECK(!connected());
+  client_->UseClientConnectionId(client_connection_id);
+}
+
+void QuicTestClient::UseClientConnectionIdLength(
+    int client_connection_id_length) {
+  QUICHE_DCHECK(!connected());
+  client_->UseClientConnectionIdLength(client_connection_id_length);
+}
+
+bool QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
+  return client_->MigrateSocket(new_host);
+}
+
+bool QuicTestClient::MigrateSocketWithSpecifiedPort(
+    const QuicIpAddress& new_host,
+    int port) {
+  client_->set_local_port(port);
+  return client_->MigrateSocket(new_host);
+}
+
+QuicIpAddress QuicTestClient::bind_to_address() const {
+  return client_->bind_to_address();
+}
+
+void QuicTestClient::set_bind_to_address(QuicIpAddress address) {
+  client_->set_bind_to_address(address);
+}
+
+const QuicSocketAddress& QuicTestClient::address() const {
+  return client_->server_address();
+}
+
+void QuicTestClient::WaitForWriteToFlush() {
+  while (connected() && client()->session()->HasDataToWrite()) {
+    client_->WaitForEvents();
+  }
+}
+
+QuicTestClient::TestClientDataToResend::TestClientDataToResend(
+    std::unique_ptr<spdy::SpdyHeaderBlock> headers, absl::string_view body,
+    bool fin, QuicTestClient* test_client,
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener)
+    : QuicClient::QuicDataToResend(std::move(headers), body, fin),
+      test_client_(test_client),
+      ack_listener_(std::move(ack_listener)) {}
+
+QuicTestClient::TestClientDataToResend::~TestClientDataToResend() = default;
+
+void QuicTestClient::TestClientDataToResend::Resend() {
+  test_client_->GetOrCreateStreamAndSendRequest(headers_.get(), body_, fin_,
+                                                ack_listener_);
+  headers_.reset();
+}
+
+QuicTestClient::PerStreamState::PerStreamState(const PerStreamState& other)
+    : stream_error(other.stream_error),
+      response_complete(other.response_complete),
+      response_headers_complete(other.response_headers_complete),
+      response_headers(other.response_headers.Clone()),
+      preliminary_headers(other.preliminary_headers.Clone()),
+      response(other.response),
+      response_trailers(other.response_trailers.Clone()),
+      bytes_read(other.bytes_read),
+      bytes_written(other.bytes_written),
+      response_body_size(other.response_body_size) {}
+
+QuicTestClient::PerStreamState::PerStreamState(
+    QuicRstStreamErrorCode stream_error,
+    bool response_complete,
+    bool response_headers_complete,
+    const spdy::SpdyHeaderBlock& response_headers,
+    const spdy::SpdyHeaderBlock& preliminary_headers,
+    const std::string& response,
+    const spdy::SpdyHeaderBlock& response_trailers,
+    uint64_t bytes_read,
+    uint64_t bytes_written,
+    int64_t response_body_size)
+    : stream_error(stream_error),
+      response_complete(response_complete),
+      response_headers_complete(response_headers_complete),
+      response_headers(response_headers.Clone()),
+      preliminary_headers(preliminary_headers.Clone()),
+      response(response),
+      response_trailers(response_trailers.Clone()),
+      bytes_read(bytes_read),
+      bytes_written(bytes_written),
+      response_body_size(response_body_size) {}
+
+QuicTestClient::PerStreamState::~PerStreamState() = default;
+
+bool QuicTestClient::PopulateHeaderBlockFromUrl(
+    const std::string& uri,
+    spdy::SpdyHeaderBlock* headers) {
+  std::string url;
+  if (absl::StartsWith(uri, "https://") || absl::StartsWith(uri, "http://")) {
+    url = uri;
+  } else if (uri[0] == '/') {
+    url = "https://" + client_->server_id().host() + uri;
+  } else {
+    url = "https://" + uri;
+  }
+  return SpdyUtils::PopulateHeaderBlockFromUrl(url, headers);
+}
+
+void QuicTestClient::ReadNextResponse() {
+  if (closed_stream_states_.empty()) {
+    return;
+  }
+
+  PerStreamState state(closed_stream_states_.front().second);
+
+  stream_error_ = state.stream_error;
+  response_ = state.response;
+  response_complete_ = state.response_complete;
+  response_headers_complete_ = state.response_headers_complete;
+  preliminary_headers_ = state.preliminary_headers.Clone();
+  response_headers_ = state.response_headers.Clone();
+  response_trailers_ = state.response_trailers.Clone();
+  bytes_read_ = state.bytes_read;
+  bytes_written_ = state.bytes_written;
+  response_body_size_ = state.response_body_size;
+
+  closed_stream_states_.pop_front();
+}
+
+void QuicTestClient::ClearPerConnectionState() {
+  ClearPerRequestState();
+  open_streams_.clear();
+  closed_stream_states_.clear();
+  latest_created_stream_ = nullptr;
+}
+
+void QuicTestClient::WaitForDelayedAcks() {
+  // kWaitDuration is a period of time that is long enough for all delayed
+  // acks to be sent and received on the other end.
+  const QuicTime::Delta kWaitDuration =
+      4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+  const QuicClock* clock = client()->client_session()->connection()->clock();
+
+  QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
+  while (connected() && clock->ApproximateNow() < wait_until) {
+    // This waits for up to 50 ms.
+    client()->WaitForEvents();
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_test_client.h b/quiche/quic/test_tools/quic_test_client.h
new file mode 100644
index 0000000..2878f9b
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_client.h
@@ -0,0 +1,448 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/tools/quic_client.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+class ProofVerifier;
+class QuicPacketWriterWrapper;
+
+namespace test {
+
+class MockableQuicClientEpollNetworkHelper;
+
+// A quic client which allows mocking out reads and writes.
+class MockableQuicClient : public QuicClient {
+ public:
+  MockableQuicClient(QuicSocketAddress server_address,
+                     const QuicServerId& server_id,
+                     const ParsedQuicVersionVector& supported_versions,
+                     QuicEpollServer* epoll_server);
+
+  MockableQuicClient(QuicSocketAddress server_address,
+                     const QuicServerId& server_id,
+                     const QuicConfig& config,
+                     const ParsedQuicVersionVector& supported_versions,
+                     QuicEpollServer* epoll_server);
+
+  MockableQuicClient(QuicSocketAddress server_address,
+                     const QuicServerId& server_id,
+                     const QuicConfig& config,
+                     const ParsedQuicVersionVector& supported_versions,
+                     QuicEpollServer* epoll_server,
+                     std::unique_ptr<ProofVerifier> proof_verifier);
+
+  MockableQuicClient(QuicSocketAddress server_address,
+                     const QuicServerId& server_id,
+                     const QuicConfig& config,
+                     const ParsedQuicVersionVector& supported_versions,
+                     QuicEpollServer* epoll_server,
+                     std::unique_ptr<ProofVerifier> proof_verifier,
+                     std::unique_ptr<SessionCache> session_cache);
+  MockableQuicClient(const MockableQuicClient&) = delete;
+  MockableQuicClient& operator=(const MockableQuicClient&) = delete;
+
+  ~MockableQuicClient() override;
+
+  QuicConnectionId GenerateNewConnectionId() override;
+  void UseConnectionId(QuicConnectionId server_connection_id);
+  void UseConnectionIdLength(int server_connection_id_length);
+  QuicConnectionId GetClientConnectionId() override;
+  void UseClientConnectionId(QuicConnectionId client_connection_id);
+  void UseClientConnectionIdLength(int client_connection_id_length);
+
+  void UseWriter(QuicPacketWriterWrapper* writer);
+  void set_peer_address(const QuicSocketAddress& address);
+  // The last incoming packet, iff |track_last_incoming_packet| is true.
+  const QuicReceivedPacket* last_incoming_packet();
+  // If true, copy each packet from ProcessPacket into |last_incoming_packet|
+  void set_track_last_incoming_packet(bool track);
+
+  // Casts the network helper to a MockableQuicClientEpollNetworkHelper.
+  MockableQuicClientEpollNetworkHelper* mockable_network_helper();
+  const MockableQuicClientEpollNetworkHelper* mockable_network_helper() const;
+
+ private:
+  // Server connection ID to use, if server_connection_id_overridden_
+  QuicConnectionId override_server_connection_id_;
+  bool server_connection_id_overridden_;
+  int override_server_connection_id_length_ = -1;
+  // Client connection ID to use, if client_connection_id_overridden_
+  QuicConnectionId override_client_connection_id_;
+  bool client_connection_id_overridden_;
+  int override_client_connection_id_length_ = -1;
+  CachedNetworkParameters cached_network_paramaters_;
+};
+
+// A toy QUIC client used for testing.
+class QuicTestClient : public QuicSpdyStream::Visitor,
+                       public QuicClientPushPromiseIndex::Delegate {
+ public:
+  QuicTestClient(QuicSocketAddress server_address,
+                 const std::string& server_hostname,
+                 const ParsedQuicVersionVector& supported_versions);
+  QuicTestClient(QuicSocketAddress server_address,
+                 const std::string& server_hostname,
+                 const QuicConfig& config,
+                 const ParsedQuicVersionVector& supported_versions);
+  QuicTestClient(QuicSocketAddress server_address,
+                 const std::string& server_hostname,
+                 const QuicConfig& config,
+                 const ParsedQuicVersionVector& supported_versions,
+                 std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicTestClient(QuicSocketAddress server_address,
+                 const std::string& server_hostname,
+                 const QuicConfig& config,
+                 const ParsedQuicVersionVector& supported_versions,
+                 std::unique_ptr<ProofVerifier> proof_verifier,
+                 std::unique_ptr<SessionCache> session_cache);
+
+  ~QuicTestClient() override;
+
+  // Sets the |user_agent_id| of the |client_|.
+  void SetUserAgentID(const std::string& user_agent_id);
+
+  // Wraps data in a quic packet and sends it.
+  ssize_t SendData(const std::string& data, bool last_data);
+  // As above, but |delegate| will be notified when |data| is ACKed.
+  ssize_t SendData(
+      const std::string& data, bool last_data,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  // Clears any outstanding state and sends a simple GET of 'uri' to the
+  // server.  Returns 0 if the request failed and no bytes were written.
+  ssize_t SendRequest(const std::string& uri);
+  // Send a request R and a RST_FRAME which resets R, in the same packet.
+  ssize_t SendRequestAndRstTogether(const std::string& uri);
+  // Sends requests for all the urls and waits for the responses.  To process
+  // the individual responses as they are returned, the caller should use the
+  // set the response_listener on the client().
+  void SendRequestsAndWaitForResponses(
+      const std::vector<std::string>& url_list);
+  // Sends a request containing |headers| and |body| and returns the number of
+  // bytes sent (the size of the serialized request headers and body).
+  ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
+                      absl::string_view body);
+  // Sends a request containing |headers| and |body| with the fin bit set to
+  // |fin| and returns the number of bytes sent (the size of the serialized
+  // request headers and body).
+  ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
+                      absl::string_view body,
+                      bool fin);
+  // Sends a request containing |headers| and |body| with the fin bit set to
+  // |fin| and returns the number of bytes sent (the size of the serialized
+  // request headers and body). If |flush| is true, will wait for the message to
+  // be flushed before returning.
+  ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers,
+                      absl::string_view body,
+                      bool fin,
+                      bool flush);
+  // Sends a request containing |headers| and |body|, waits for the response,
+  // and returns the response body.
+  std::string SendCustomSynchronousRequest(const spdy::SpdyHeaderBlock& headers,
+                                           const std::string& body);
+  // Sends a GET request for |uri|, waits for the response, and returns the
+  // response body.
+  std::string SendSynchronousRequest(const std::string& uri);
+  void SendConnectivityProbing();
+  void Connect();
+  void ResetConnection();
+  void Disconnect();
+  QuicSocketAddress local_address() const;
+  void ClearPerRequestState();
+  bool WaitUntil(int timeout_ms, std::function<bool()> trigger);
+  ssize_t Send(absl::string_view data);
+  bool connected() const;
+  bool buffer_body() const;
+  void set_buffer_body(bool buffer_body);
+
+  // Getters for stream state. Please note, these getters are divided into two
+  // groups. 1) returns state which only get updated once a complete response
+  // is received. 2) returns state of the oldest active stream which have
+  // received partial response (if any).
+  // Group 1.
+  const spdy::SpdyHeaderBlock& response_trailers() const;
+  bool response_complete() const;
+  int64_t response_body_size() const;
+  const std::string& response_body() const;
+  // Group 2.
+  bool response_headers_complete() const;
+  const spdy::SpdyHeaderBlock* response_headers() const;
+  const spdy::SpdyHeaderBlock* preliminary_headers() const;
+  int64_t response_size() const;
+  size_t bytes_read() const;
+  size_t bytes_written() const;
+
+  // Returns once at least one complete response or a connection close has been
+  // received from the server. If responses are received for multiple (say 2)
+  // streams, next WaitForResponse will return immediately.
+  void WaitForResponse() { WaitForResponseForMs(-1); }
+
+  // Returns once some data is received on any open streams or at least one
+  // complete response is received from the server.
+  void WaitForInitialResponse() { WaitForInitialResponseForMs(-1); }
+
+  // Returns once at least one complete response or a connection close has been
+  // received from the server, or once the timeout expires.
+  // Passing in a timeout value of -1 disables the timeout. If multiple
+  // responses are received while the client is waiting, subsequent calls to
+  // this function will return immediately.
+  void WaitForResponseForMs(int timeout_ms) {
+    WaitUntil(timeout_ms, [this]() { return !closed_stream_states_.empty(); });
+    if (response_complete()) {
+      QUIC_VLOG(1) << "Client received response:"
+                   << response_headers()->DebugString() << response_body();
+    }
+  }
+
+  // Returns once some data is received on any open streams or at least one
+  // complete response is received from the server, or once the timeout
+  // expires. -1 means no timeout.
+  void WaitForInitialResponseForMs(int timeout_ms) {
+    WaitUntil(timeout_ms, [this]() { return response_size() != 0; });
+  }
+
+  // Migrate local address to <|new_host|, a random port>.
+  // Return whether the migration succeeded.
+  bool MigrateSocket(const QuicIpAddress& new_host);
+  // Migrate local address to <|new_host|, |port|>.
+  // Return whether the migration succeeded.
+  bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
+  QuicIpAddress bind_to_address() const;
+  void set_bind_to_address(QuicIpAddress address);
+  const QuicSocketAddress& address() const;
+
+  // From QuicSpdyStream::Visitor
+  void OnClose(QuicSpdyStream* stream) override;
+
+  // From QuicClientPushPromiseIndex::Delegate
+  bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
+                 const spdy::SpdyHeaderBlock& promise_request,
+                 const spdy::SpdyHeaderBlock& promise_response) override;
+  void OnRendezvousResult(QuicSpdyStream*) override;
+
+  // Configures client_ to take ownership of and use the writer.
+  // Must be called before initial connect.
+  void UseWriter(QuicPacketWriterWrapper* writer);
+  // Configures client_ to use a specific server connection ID instead of a
+  // random one.
+  void UseConnectionId(QuicConnectionId server_connection_id);
+  // Configures client_ to use a specific server connection ID length instead
+  // of the default of kQuicDefaultConnectionIdLength.
+  void UseConnectionIdLength(int server_connection_id_length);
+  // Configures client_ to use a specific client connection ID instead of an
+  // empty one.
+  void UseClientConnectionId(QuicConnectionId client_connection_id);
+  // Configures client_ to use a specific client connection ID length instead
+  // of the default of zero.
+  void UseClientConnectionIdLength(int client_connection_id_length);
+
+  // Returns nullptr if the maximum number of streams have already been created.
+  QuicSpdyClientStream* GetOrCreateStream();
+
+  // Calls GetOrCreateStream(), sends the request on the stream, and
+  // stores the request in case it needs to be resent.  If |headers| is
+  // null, only the body will be sent on the stream.
+  ssize_t GetOrCreateStreamAndSendRequest(
+      const spdy::SpdyHeaderBlock* headers, absl::string_view body, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+          ack_listener);
+
+  QuicRstStreamErrorCode stream_error() { return stream_error_; }
+  QuicErrorCode connection_error() const;
+
+  MockableQuicClient* client() { return client_.get(); }
+  const MockableQuicClient* client() const { return client_.get(); }
+
+  // cert_common_name returns the common name value of the server's certificate,
+  // or the empty std::string if no certificate was presented.
+  const std::string& cert_common_name() const;
+
+  // cert_sct returns the signed timestamp of the server's certificate,
+  // or the empty std::string if no signed timestamp was presented.
+  const std::string& cert_sct() const;
+
+  // Get the server config map.  Server config must exist.
+  const QuicTagValueMap& GetServerConfig() const;
+
+  void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; }
+
+  void set_priority(spdy::SpdyPriority priority) { priority_ = priority; }
+
+  void WaitForWriteToFlush();
+
+  QuicEpollServer* epoll_server() { return &epoll_server_; }
+
+  size_t num_requests() const { return num_requests_; }
+
+  size_t num_responses() const { return num_responses_; }
+
+  void set_server_address(const QuicSocketAddress& server_address) {
+    client_->set_server_address(server_address);
+  }
+
+  void set_peer_address(const QuicSocketAddress& address) {
+    client_->set_peer_address(address);
+  }
+
+  // Explicitly set the SNI value for this client, overriding the default
+  // behavior which extracts the SNI value from the request URL.
+  void OverrideSni(const std::string& sni) {
+    override_sni_set_ = true;
+    override_sni_ = sni;
+  }
+
+  void Initialize();
+
+  void set_client(MockableQuicClient* client) { client_.reset(client); }
+
+  // Given |uri|, populates the fields in |headers| for a simple GET
+  // request. If |uri| is a relative URL, the QuicServerId will be
+  // use to specify the authority.
+  bool PopulateHeaderBlockFromUrl(const std::string& uri,
+                                  spdy::SpdyHeaderBlock* headers);
+
+  // Waits for a period of time that is long enough to receive all delayed acks
+  // sent by peer.
+  void WaitForDelayedAcks();
+
+  QuicSpdyClientStream* latest_created_stream() {
+    return latest_created_stream_;
+  }
+
+ protected:
+  QuicTestClient();
+  QuicTestClient(const QuicTestClient&) = delete;
+  QuicTestClient(const QuicTestClient&&) = delete;
+  QuicTestClient& operator=(const QuicTestClient&) = delete;
+  QuicTestClient& operator=(const QuicTestClient&&) = delete;
+
+ private:
+  class TestClientDataToResend : public QuicClient::QuicDataToResend {
+   public:
+    TestClientDataToResend(
+        std::unique_ptr<spdy::SpdyHeaderBlock> headers, absl::string_view body,
+        bool fin, QuicTestClient* test_client,
+        quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+            ack_listener);
+
+    ~TestClientDataToResend() override;
+
+    void Resend() override;
+
+   protected:
+    QuicTestClient* test_client_;
+    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+        ack_listener_;
+  };
+
+  // PerStreamState of a stream is updated when it is closed.
+  struct PerStreamState {
+    PerStreamState(const PerStreamState& other);
+    PerStreamState(QuicRstStreamErrorCode stream_error,
+                   bool response_complete,
+                   bool response_headers_complete,
+                   const spdy::SpdyHeaderBlock& response_headers,
+                   const spdy::SpdyHeaderBlock& preliminary_headers,
+                   const std::string& response,
+                   const spdy::SpdyHeaderBlock& response_trailers,
+                   uint64_t bytes_read,
+                   uint64_t bytes_written,
+                   int64_t response_body_size);
+    ~PerStreamState();
+
+    QuicRstStreamErrorCode stream_error;
+    bool response_complete;
+    bool response_headers_complete;
+    spdy::SpdyHeaderBlock response_headers;
+    spdy::SpdyHeaderBlock preliminary_headers;
+    std::string response;
+    spdy::SpdyHeaderBlock response_trailers;
+    uint64_t bytes_read;
+    uint64_t bytes_written;
+    int64_t response_body_size;
+  };
+
+  bool HaveActiveStream();
+
+  // Read oldest received response and remove it from closed_stream_states_.
+  void ReadNextResponse();
+
+  // Clear open_streams_, closed_stream_states_ and reset
+  // latest_created_stream_.
+  void ClearPerConnectionState();
+
+  // Update latest_created_stream_, add |stream| to open_streams_ and starts
+  // tracking its state.
+  void SetLatestCreatedStream(QuicSpdyClientStream* stream);
+
+  QuicEpollServer epoll_server_;
+  std::unique_ptr<MockableQuicClient> client_;  // The actual client
+  QuicSpdyClientStream* latest_created_stream_;
+  std::map<QuicStreamId, QuicSpdyClientStream*> open_streams_;
+  // Received responses of closed streams.
+  quiche::QuicheLinkedHashMap<QuicStreamId, PerStreamState>
+      closed_stream_states_;
+
+  QuicRstStreamErrorCode stream_error_;
+
+  bool response_complete_;
+  bool response_headers_complete_;
+  mutable spdy::SpdyHeaderBlock preliminary_headers_;
+  mutable spdy::SpdyHeaderBlock response_headers_;
+
+  // Parsed response trailers (if present), copied from the stream in OnClose.
+  spdy::SpdyHeaderBlock response_trailers_;
+
+  spdy::SpdyPriority priority_;
+  std::string response_;
+  // bytes_read_ and bytes_written_ are updated only when stream_ is released;
+  // prefer bytes_read() and bytes_written() member functions.
+  uint64_t bytes_read_;
+  uint64_t bytes_written_;
+  // The number of HTTP body bytes received.
+  int64_t response_body_size_;
+  // True if we tried to connect already since the last call to Disconnect().
+  bool connect_attempted_;
+  // The client will auto-connect exactly once before sending data.  If
+  // something causes a connection reset, it will not automatically reconnect
+  // unless auto_reconnect_ is true.
+  bool auto_reconnect_;
+  // Should we buffer the response body? Defaults to true.
+  bool buffer_body_;
+  // For async push promise rendezvous, validation may fail in which
+  // case the request should be retried.
+  std::unique_ptr<TestClientDataToResend> push_promise_data_to_resend_;
+  // Number of requests/responses this client has sent/received.
+  size_t num_requests_;
+  size_t num_responses_;
+
+  // If set, this value is used for the connection SNI, overriding the usual
+  // logic which extracts the SNI from the request URL.
+  bool override_sni_set_ = false;
+  std::string override_sni_;
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_
diff --git a/quiche/quic/test_tools/quic_test_server.cc b/quiche/quic/test_tools/quic_test_server.cc
new file mode 100644
index 0000000..b19afc6
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_server.cc
@@ -0,0 +1,272 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_test_server.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+#include "quiche/quic/tools/quic_simple_dispatcher.h"
+#include "quiche/quic/tools/quic_simple_server_session.h"
+
+namespace quic {
+
+namespace test {
+
+class CustomStreamSession : public QuicSimpleServerSession {
+ public:
+  CustomStreamSession(
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection,
+      QuicSession::Visitor* visitor,
+      QuicCryptoServerStreamBase::Helper* helper,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicTestServer::StreamFactory* stream_factory,
+      QuicTestServer::CryptoStreamFactory* crypto_stream_factory,
+      QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerSession(config,
+                                supported_versions,
+                                connection,
+                                visitor,
+                                helper,
+                                crypto_config,
+                                compressed_certs_cache,
+                                quic_simple_server_backend),
+        stream_factory_(stream_factory),
+        crypto_stream_factory_(crypto_stream_factory) {}
+
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
+    if (!ShouldCreateIncomingStream(id)) {
+      return nullptr;
+    }
+    if (stream_factory_) {
+      QuicSpdyStream* stream =
+          stream_factory_->CreateStream(id, this, server_backend());
+      ActivateStream(absl::WrapUnique(stream));
+      return stream;
+    }
+    return QuicSimpleServerSession::CreateIncomingStream(id);
+  }
+
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override {
+    if (crypto_stream_factory_) {
+      return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
+    }
+    return QuicSimpleServerSession::CreateQuicCryptoServerStream(
+        crypto_config, compressed_certs_cache);
+  }
+
+ private:
+  QuicTestServer::StreamFactory* stream_factory_;               // Not owned.
+  QuicTestServer::CryptoStreamFactory* crypto_stream_factory_;  // Not owned.
+};
+
+class QuicTestDispatcher : public QuicSimpleDispatcher {
+ public:
+  QuicTestDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      QuicSimpleServerBackend* quic_simple_server_backend,
+      uint8_t expected_server_connection_id_length)
+      : QuicSimpleDispatcher(config,
+                             crypto_config,
+                             version_manager,
+                             std::move(helper),
+                             std::move(session_helper),
+                             std::move(alarm_factory),
+                             quic_simple_server_backend,
+                             expected_server_connection_id_length),
+        session_factory_(nullptr),
+        stream_factory_(nullptr),
+        crypto_stream_factory_(nullptr) {}
+
+  std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId id, const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
+      const ParsedQuicVersion& version,
+      const ParsedClientHello& /*parsed_chlo*/) override {
+    QuicReaderMutexLock lock(&factory_lock_);
+    // The QuicServerSessionBase takes ownership of |connection| below.
+    QuicConnection* connection = new QuicConnection(
+        id, self_address, peer_address, helper(), alarm_factory(), writer(),
+        /* owns_writer= */ false, Perspective::IS_SERVER,
+        ParsedQuicVersionVector{version});
+
+    std::unique_ptr<QuicServerSessionBase> session;
+    if (session_factory_ == nullptr && stream_factory_ == nullptr &&
+        crypto_stream_factory_ == nullptr) {
+      session = std::make_unique<QuicSimpleServerSession>(
+          config(), GetSupportedVersions(), connection, this, session_helper(),
+          crypto_config(), compressed_certs_cache(), server_backend());
+    } else if (stream_factory_ != nullptr ||
+               crypto_stream_factory_ != nullptr) {
+      session = std::make_unique<CustomStreamSession>(
+          config(), GetSupportedVersions(), connection, this, session_helper(),
+          crypto_config(), compressed_certs_cache(), stream_factory_,
+          crypto_stream_factory_, server_backend());
+    } else {
+      session = session_factory_->CreateSession(
+          config(), connection, this, session_helper(), crypto_config(),
+          compressed_certs_cache(), server_backend());
+    }
+    if (VersionUsesHttp3(version.transport_version) &&
+        GetQuicReloadableFlag(quic_verify_request_headers_2)) {
+      QUICHE_DCHECK(session->allow_extended_connect());
+      // Do not allow extended CONNECT request if the backend doesn't support
+      // it.
+      session->set_allow_extended_connect(
+          server_backend()->SupportsExtendedConnect());
+    }
+    session->Initialize();
+    return session;
+  }
+
+  void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
+    QuicWriterMutexLock lock(&factory_lock_);
+    QUICHE_DCHECK(session_factory_ == nullptr);
+    QUICHE_DCHECK(stream_factory_ == nullptr);
+    QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
+    session_factory_ = factory;
+  }
+
+  void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
+    QuicWriterMutexLock lock(&factory_lock_);
+    QUICHE_DCHECK(session_factory_ == nullptr);
+    QUICHE_DCHECK(stream_factory_ == nullptr);
+    stream_factory_ = factory;
+  }
+
+  void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
+    QuicWriterMutexLock lock(&factory_lock_);
+    QUICHE_DCHECK(session_factory_ == nullptr);
+    QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
+    crypto_stream_factory_ = factory;
+  }
+
+ private:
+  QuicMutex factory_lock_;
+  QuicTestServer::SessionFactory* session_factory_;             // Not owned.
+  QuicTestServer::StreamFactory* stream_factory_;               // Not owned.
+  QuicTestServer::CryptoStreamFactory* crypto_stream_factory_;  // Not owned.
+};
+
+QuicTestServer::QuicTestServer(
+    std::unique_ptr<ProofSource> proof_source,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicServer(std::move(proof_source), quic_simple_server_backend) {}
+
+QuicTestServer::QuicTestServer(
+    std::unique_ptr<ProofSource> proof_source,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicTestServer(std::move(proof_source),
+                     config,
+                     supported_versions,
+                     quic_simple_server_backend,
+                     kQuicDefaultConnectionIdLength) {}
+
+QuicTestServer::QuicTestServer(
+    std::unique_ptr<ProofSource> proof_source,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicSimpleServerBackend* quic_simple_server_backend,
+    uint8_t expected_server_connection_id_length)
+    : QuicServer(std::move(proof_source),
+                 config,
+                 QuicCryptoServerConfig::ConfigOptions(),
+                 supported_versions,
+                 quic_simple_server_backend,
+                 expected_server_connection_id_length) {}
+
+QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
+  return new QuicTestDispatcher(
+      &config(), &crypto_config(), version_manager(),
+      std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
+                                                  QuicAllocator::BUFFER_POOL),
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+          new QuicSimpleCryptoServerStreamHelper()),
+      std::make_unique<QuicEpollAlarmFactory>(epoll_server()), server_backend(),
+      expected_server_connection_id_length());
+}
+
+void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
+  QUICHE_DCHECK(dispatcher());
+  static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
+}
+
+void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
+  static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
+}
+
+void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
+  static_cast<QuicTestDispatcher*>(dispatcher())
+      ->SetCryptoStreamFactory(factory);
+}
+
+///////////////////////////   TEST SESSIONS ///////////////////////////////
+
+ImmediateGoAwaySession::ImmediateGoAwaySession(
+    const QuicConfig& config,
+    QuicConnection* connection,
+    QuicSession::Visitor* visitor,
+    QuicCryptoServerStreamBase::Helper* helper,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicSimpleServerSession(config,
+                              CurrentSupportedVersions(),
+                              connection,
+                              visitor,
+                              helper,
+                              crypto_config,
+                              compressed_certs_cache,
+                              quic_simple_server_backend) {}
+
+void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (VersionUsesHttp3(transport_version())) {
+    SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
+  } else {
+    SendGoAway(QUIC_PEER_GOING_AWAY, "");
+  }
+  QuicSimpleServerSession::OnStreamFrame(frame);
+}
+
+void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) {
+  // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. It's sent in a QUIC stream
+  // and requires encryption. Thus the sending is done in
+  // OnNewEncryptionKeyAvailable().
+  if (!VersionUsesHttp3(transport_version())) {
+    SendGoAway(QUIC_PEER_GOING_AWAY, "");
+  }
+  QuicSimpleServerSession::OnCryptoFrame(frame);
+}
+
+void ImmediateGoAwaySession::OnNewEncryptionKeyAvailable(
+    EncryptionLevel level,
+    std::unique_ptr<QuicEncrypter> encrypter) {
+  QuicSimpleServerSession::OnNewEncryptionKeyAvailable(level,
+                                                       std::move(encrypter));
+  if (VersionUsesHttp3(transport_version())) {
+    if (IsEncryptionEstablished() && !goaway_sent()) {
+      SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
+    }
+  }
+}
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_test_server.h b/quiche/quic/test_tools/quic_test_server.h
new file mode 100644
index 0000000..277dade
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_server.h
@@ -0,0 +1,121 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
+
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/tools/quic_server.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+#include "quiche/quic/tools/quic_simple_server_session.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+namespace quic {
+
+namespace test {
+
+// A test server which enables easy creation of custom QuicServerSessions
+//
+// Eventually this may be extended to allow custom QuicConnections etc.
+class QuicTestServer : public QuicServer {
+ public:
+  // Factory for creating QuicServerSessions.
+  class SessionFactory {
+   public:
+    virtual ~SessionFactory() {}
+
+    // Returns a new session owned by the caller.
+    virtual std::unique_ptr<QuicServerSessionBase> CreateSession(
+        const QuicConfig& config,
+        QuicConnection* connection,
+        QuicSession::Visitor* visitor,
+        QuicCryptoServerStreamBase::Helper* helper,
+        const QuicCryptoServerConfig* crypto_config,
+        QuicCompressedCertsCache* compressed_certs_cache,
+        QuicSimpleServerBackend* quic_simple_server_backend) = 0;
+  };
+
+  // Factory for creating QuicSimpleServerStreams.
+  class StreamFactory {
+   public:
+    virtual ~StreamFactory() {}
+
+    // Returns a new stream owned by the caller.
+    virtual QuicSimpleServerStream* CreateStream(
+        QuicStreamId id,
+        QuicSpdySession* session,
+        QuicSimpleServerBackend* quic_simple_server_backend) = 0;
+
+    virtual QuicSimpleServerStream* CreateStream(
+        PendingStream* pending, QuicSpdySession* session,
+        QuicSimpleServerBackend* quic_simple_server_backend) = 0;
+  };
+
+  class CryptoStreamFactory {
+   public:
+    virtual ~CryptoStreamFactory() {}
+
+    // Returns a new QuicCryptoServerStreamBase owned by the caller
+    virtual std::unique_ptr<QuicCryptoServerStreamBase> CreateCryptoStream(
+        const QuicCryptoServerConfig* crypto_config,
+        QuicServerSessionBase* session) = 0;
+  };
+
+  QuicTestServer(std::unique_ptr<ProofSource> proof_source,
+                 QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicTestServer(std::unique_ptr<ProofSource> proof_source,
+                 const QuicConfig& config,
+                 const ParsedQuicVersionVector& supported_versions,
+                 QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicTestServer(std::unique_ptr<ProofSource> proof_source,
+                 const QuicConfig& config,
+                 const ParsedQuicVersionVector& supported_versions,
+                 QuicSimpleServerBackend* quic_simple_server_backend,
+                 uint8_t expected_server_connection_id_length);
+
+  // Create a custom dispatcher which creates custom sessions.
+  QuicDispatcher* CreateQuicDispatcher() override;
+
+  // Sets a custom session factory, owned by the caller, for easy custom
+  // session logic. This is incompatible with setting a stream factory or a
+  // crypto stream factory.
+  void SetSessionFactory(SessionFactory* factory);
+
+  // Sets a custom stream factory, owned by the caller, for easy custom
+  // stream logic. This is incompatible with setting a session factory.
+  void SetSpdyStreamFactory(StreamFactory* factory);
+
+  // Sets a custom crypto stream factory, owned by the caller, for easy custom
+  // crypto logic.  This is incompatible with setting a session factory.
+  void SetCryptoStreamFactory(CryptoStreamFactory* factory);
+};
+
+// Useful test sessions for the QuicTestServer.
+
+// Test session which sends a GOAWAY immedaitely on creation, before crypto
+// credentials have even been established.
+class ImmediateGoAwaySession : public QuicSimpleServerSession {
+ public:
+  ImmediateGoAwaySession(const QuicConfig& config,
+                         QuicConnection* connection,
+                         QuicSession::Visitor* visitor,
+                         QuicCryptoServerStreamBase::Helper* helper,
+                         const QuicCryptoServerConfig* crypto_config,
+                         QuicCompressedCertsCache* compressed_certs_cache,
+                         QuicSimpleServerBackend* quic_simple_server_backend);
+
+  // Override to send GoAway.
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  void OnNewEncryptionKeyAvailable(
+      EncryptionLevel level,
+      std::unique_ptr<QuicEncrypter> encrypter) override;
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_SERVER_H_
diff --git a/quiche/quic/test_tools/quic_test_utils.cc b/quiche/quic/test_tools/quic_test_utils.cc
new file mode 100644
index 0000000..336437b
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_utils.cc
@@ -0,0 +1,1618 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/chacha.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "quiche/quic/core/crypto/crypto_framer.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/spdy/core/spdy_frame_builder.h"
+
+using testing::_;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+
+QuicConnectionId TestConnectionId() {
+  // Chosen by fair dice roll.
+  // Guaranteed to be random.
+  return TestConnectionId(42);
+}
+
+QuicConnectionId TestConnectionId(uint64_t connection_number) {
+  const uint64_t connection_id64_net =
+      quiche::QuicheEndian::HostToNet64(connection_number);
+  return QuicConnectionId(reinterpret_cast<const char*>(&connection_id64_net),
+                          sizeof(connection_id64_net));
+}
+
+QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number) {
+  const uint64_t connection_number_net =
+      quiche::QuicheEndian::HostToNet64(connection_number);
+  char connection_id_bytes[9] = {};
+  static_assert(
+      sizeof(connection_id_bytes) == 1 + sizeof(connection_number_net),
+      "bad lengths");
+  memcpy(connection_id_bytes + 1, &connection_number_net,
+         sizeof(connection_number_net));
+  return QuicConnectionId(connection_id_bytes, sizeof(connection_id_bytes));
+}
+
+uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id) {
+  QUICHE_DCHECK_EQ(connection_id.length(), kQuicDefaultConnectionIdLength);
+  uint64_t connection_id64_net = 0;
+  memcpy(&connection_id64_net, connection_id.data(),
+         std::min<size_t>(static_cast<size_t>(connection_id.length()),
+                          sizeof(connection_id64_net)));
+  return quiche::QuicheEndian::NetToHost64(connection_id64_net);
+}
+
+std::vector<uint8_t> CreateStatelessResetTokenForTest() {
+  static constexpr uint8_t kStatelessResetTokenDataForTest[16] = {
+      0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+      0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
+  return std::vector<uint8_t>(kStatelessResetTokenDataForTest,
+                              kStatelessResetTokenDataForTest +
+                                  sizeof(kStatelessResetTokenDataForTest));
+}
+
+std::string TestHostname() { return "test.example.com"; }
+
+QuicServerId TestServerId() {
+  return QuicServerId(TestHostname(), kTestPort);
+}
+
+QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks) {
+  QUICHE_DCHECK_GT(ack_blocks.size(), 0u);
+
+  QuicAckFrame ack;
+  QuicPacketNumber end_of_previous_block(1);
+  for (const QuicAckBlock& block : ack_blocks) {
+    QUICHE_DCHECK_GE(block.start, end_of_previous_block);
+    QUICHE_DCHECK_GT(block.limit, block.start);
+    ack.packets.AddRange(block.start, block.limit);
+    end_of_previous_block = block.limit;
+  }
+
+  ack.largest_acked = ack.packets.Max();
+
+  return ack;
+}
+
+QuicAckFrame InitAckFrame(uint64_t largest_acked) {
+  return InitAckFrame(QuicPacketNumber(largest_acked));
+}
+
+QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked) {
+  return InitAckFrame({{QuicPacketNumber(1), largest_acked + 1}});
+}
+
+QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
+                                       uint64_t least_unacked) {
+  QuicAckFrame ack;
+  ack.largest_acked = QuicPacketNumber(2 * num_ack_blocks + least_unacked);
+  // Add enough received packets to get num_ack_blocks ack blocks.
+  for (QuicPacketNumber i = QuicPacketNumber(2);
+       i < QuicPacketNumber(2 * num_ack_blocks + 1); i += 2) {
+    ack.packets.Add(i + least_unacked);
+  }
+  return ack;
+}
+
+QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size,
+                                  size_t max_num_gaps,
+                                  uint64_t largest_acked) {
+  QuicAckFrame ack;
+  ack.largest_acked = QuicPacketNumber(largest_acked);
+  ack.packets.Add(QuicPacketNumber(largest_acked));
+  for (size_t i = 0; i < max_num_gaps; ++i) {
+    if (largest_acked <= gap_size) {
+      break;
+    }
+    largest_acked -= gap_size;
+    ack.packets.Add(QuicPacketNumber(largest_acked));
+  }
+  return ack;
+}
+
+EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header) {
+  if (header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+    return ENCRYPTION_FORWARD_SECURE;
+  } else if (header.form == IETF_QUIC_LONG_HEADER_PACKET) {
+    if (header.long_packet_type == HANDSHAKE) {
+      return ENCRYPTION_HANDSHAKE;
+    } else if (header.long_packet_type == ZERO_RTT_PROTECTED) {
+      return ENCRYPTION_ZERO_RTT;
+    }
+  }
+  return ENCRYPTION_INITIAL;
+}
+
+std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
+    QuicFramer* framer,
+    const QuicPacketHeader& header,
+    const QuicFrames& frames) {
+  const size_t max_plaintext_size =
+      framer->GetMaxPlaintextSize(kMaxOutgoingPacketSize);
+  size_t packet_size = GetPacketHeaderSize(framer->transport_version(), header);
+  for (size_t i = 0; i < frames.size(); ++i) {
+    QUICHE_DCHECK_LE(packet_size, max_plaintext_size);
+    bool first_frame = i == 0;
+    bool last_frame = i == frames.size() - 1;
+    const size_t frame_size = framer->GetSerializedFrameLength(
+        frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
+        header.packet_number_length);
+    QUICHE_DCHECK(frame_size);
+    packet_size += frame_size;
+  }
+  return BuildUnsizedDataPacket(framer, header, frames, packet_size);
+}
+
+std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
+    QuicFramer* framer,
+    const QuicPacketHeader& header,
+    const QuicFrames& frames,
+    size_t packet_size) {
+  char* buffer = new char[packet_size];
+  EncryptionLevel level = HeaderToEncryptionLevel(header);
+  size_t length =
+      framer->BuildDataPacket(header, frames, buffer, packet_size, level);
+
+  if (length == 0) {
+    delete[] buffer;
+    return nullptr;
+  }
+  // Re-construct the data packet with data ownership.
+  return std::make_unique<QuicPacket>(
+      buffer, length, /* owns_buffer */ true,
+      GetIncludedDestinationConnectionIdLength(header),
+      GetIncludedSourceConnectionIdLength(header), header.version_flag,
+      header.nonce != nullptr, header.packet_number_length,
+      header.retry_token_length_length, header.retry_token.length(),
+      header.length_length);
+}
+
+std::string Sha1Hash(absl::string_view data) {
+  char buffer[SHA_DIGEST_LENGTH];
+  SHA1(reinterpret_cast<const uint8_t*>(data.data()), data.size(),
+       reinterpret_cast<uint8_t*>(buffer));
+  return std::string(buffer, ABSL_ARRAYSIZE(buffer));
+}
+
+bool ClearControlFrame(const QuicFrame& frame) {
+  DeleteFrame(&const_cast<QuicFrame&>(frame));
+  return true;
+}
+
+bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
+                                           TransmissionType /*type*/) {
+  return ClearControlFrame(frame);
+}
+
+uint64_t SimpleRandom::RandUint64() {
+  uint64_t result;
+  RandBytes(&result, sizeof(result));
+  return result;
+}
+
+void SimpleRandom::RandBytes(void* data, size_t len) {
+  uint8_t* data_bytes = reinterpret_cast<uint8_t*>(data);
+  while (len > 0) {
+    const size_t buffer_left = sizeof(buffer_) - buffer_offset_;
+    const size_t to_copy = std::min(buffer_left, len);
+    memcpy(data_bytes, buffer_ + buffer_offset_, to_copy);
+    data_bytes += to_copy;
+    buffer_offset_ += to_copy;
+    len -= to_copy;
+
+    if (buffer_offset_ == sizeof(buffer_)) {
+      FillBuffer();
+    }
+  }
+}
+
+void SimpleRandom::InsecureRandBytes(void* data, size_t len) {
+  RandBytes(data, len);
+}
+
+uint64_t SimpleRandom::InsecureRandUint64() {
+  return RandUint64();
+}
+
+void SimpleRandom::FillBuffer() {
+  uint8_t nonce[12];
+  memcpy(nonce, buffer_, sizeof(nonce));
+  CRYPTO_chacha_20(buffer_, buffer_, sizeof(buffer_), key_, nonce, 0);
+  buffer_offset_ = 0;
+}
+
+void SimpleRandom::set_seed(uint64_t seed) {
+  static_assert(sizeof(key_) == SHA256_DIGEST_LENGTH, "Key has to be 256 bits");
+  SHA256(reinterpret_cast<const uint8_t*>(&seed), sizeof(seed), key_);
+
+  memset(buffer_, 0, sizeof(buffer_));
+  FillBuffer();
+}
+
+MockFramerVisitor::MockFramerVisitor() {
+  // By default, we want to accept packets.
+  ON_CALL(*this, OnProtocolVersionMismatch(_))
+      .WillByDefault(testing::Return(false));
+
+  // By default, we want to accept packets.
+  ON_CALL(*this, OnUnauthenticatedHeader(_))
+      .WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnUnauthenticatedPublicHeader(_))
+      .WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnPacketHeader(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnStreamFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnCryptoFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnStopWaitingFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnPaddingFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnPingFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnRstStreamFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnConnectionCloseFrame(_))
+      .WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnStopSendingFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnPathChallengeFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnPathResponseFrame(_)).WillByDefault(testing::Return(true));
+
+  ON_CALL(*this, OnGoAwayFrame(_)).WillByDefault(testing::Return(true));
+  ON_CALL(*this, OnMaxStreamsFrame(_)).WillByDefault(testing::Return(true));
+  ON_CALL(*this, OnStreamsBlockedFrame(_)).WillByDefault(testing::Return(true));
+}
+
+MockFramerVisitor::~MockFramerVisitor() {}
+
+bool NoOpFramerVisitor::OnProtocolVersionMismatch(
+    ParsedQuicVersion /*version*/) {
+  return false;
+}
+
+bool NoOpFramerVisitor::OnUnauthenticatedPublicHeader(
+    const QuicPacketHeader& /*header*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnUnauthenticatedHeader(
+    const QuicPacketHeader& /*header*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& /*header*/) {
+  return true;
+}
+
+void NoOpFramerVisitor::OnCoalescedPacket(
+    const QuicEncryptedPacket& /*packet*/) {}
+
+void NoOpFramerVisitor::OnUndecryptablePacket(
+    const QuicEncryptedPacket& /*packet*/,
+    EncryptionLevel /*decryption_level*/,
+    bool /*has_decryption_key*/) {}
+
+bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
+                                        QuicTime::Delta /*ack_delay_time*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnAckRange(QuicPacketNumber /*start*/,
+                                   QuicPacketNumber /*end*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnAckTimestamp(QuicPacketNumber /*packet_number*/,
+                                       QuicTime /*timestamp*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnAckFrameEnd(QuicPacketNumber /*start*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnStopWaitingFrame(
+    const QuicStopWaitingFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnPingFrame(const QuicPingFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnConnectionCloseFrame(
+    const QuicConnectionCloseFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnNewConnectionIdFrame(
+    const QuicNewConnectionIdFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnRetireConnectionIdFrame(
+    const QuicRetireConnectionIdFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnStopSendingFrame(
+    const QuicStopSendingFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnPathChallengeFrame(
+    const QuicPathChallengeFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnPathResponseFrame(
+    const QuicPathResponseFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnMaxStreamsFrame(
+    const QuicMaxStreamsFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnStreamsBlockedFrame(
+    const QuicStreamsBlockedFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnWindowUpdateFrame(
+    const QuicWindowUpdateFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnMessageFrame(const QuicMessageFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnHandshakeDoneFrame(
+    const QuicHandshakeDoneFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::OnAckFrequencyFrame(
+    const QuicAckFrequencyFrame& /*frame*/) {
+  return true;
+}
+
+bool NoOpFramerVisitor::IsValidStatelessResetToken(
+    const StatelessResetToken& /*token*/) const {
+  return false;
+}
+
+MockQuicConnectionVisitor::MockQuicConnectionVisitor() {}
+
+MockQuicConnectionVisitor::~MockQuicConnectionVisitor() {}
+
+MockQuicConnectionHelper::MockQuicConnectionHelper() {}
+
+MockQuicConnectionHelper::~MockQuicConnectionHelper() {}
+
+const QuicClock* MockQuicConnectionHelper::GetClock() const {
+  return &clock_;
+}
+
+QuicRandom* MockQuicConnectionHelper::GetRandomGenerator() {
+  return &random_generator_;
+}
+
+QuicAlarm* MockAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
+  return new MockAlarmFactory::TestAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+}
+
+QuicArenaScopedPtr<QuicAlarm> MockAlarmFactory::CreateAlarm(
+    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+    QuicConnectionArena* arena) {
+  if (arena != nullptr) {
+    return arena->New<TestAlarm>(std::move(delegate));
+  } else {
+    return QuicArenaScopedPtr<TestAlarm>(new TestAlarm(std::move(delegate)));
+  }
+}
+
+quiche::QuicheBufferAllocator*
+MockQuicConnectionHelper::GetStreamSendBufferAllocator() {
+  return &buffer_allocator_;
+}
+
+void MockQuicConnectionHelper::AdvanceTime(QuicTime::Delta delta) {
+  clock_.AdvanceTime(delta);
+}
+
+MockQuicConnection::MockQuicConnection(MockQuicConnectionHelper* helper,
+                                       MockAlarmFactory* alarm_factory,
+                                       Perspective perspective)
+    : MockQuicConnection(TestConnectionId(),
+                         QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+                         helper,
+                         alarm_factory,
+                         perspective,
+                         ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
+
+MockQuicConnection::MockQuicConnection(QuicSocketAddress address,
+                                       MockQuicConnectionHelper* helper,
+                                       MockAlarmFactory* alarm_factory,
+                                       Perspective perspective)
+    : MockQuicConnection(TestConnectionId(),
+                         address,
+                         helper,
+                         alarm_factory,
+                         perspective,
+                         ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
+
+MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id,
+                                       MockQuicConnectionHelper* helper,
+                                       MockAlarmFactory* alarm_factory,
+                                       Perspective perspective)
+    : MockQuicConnection(connection_id,
+                         QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+                         helper,
+                         alarm_factory,
+                         perspective,
+                         ParsedVersionOfIndex(CurrentSupportedVersions(), 0)) {}
+
+MockQuicConnection::MockQuicConnection(
+    MockQuicConnectionHelper* helper,
+    MockAlarmFactory* alarm_factory,
+    Perspective perspective,
+    const ParsedQuicVersionVector& supported_versions)
+    : MockQuicConnection(TestConnectionId(),
+                         QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+                         helper,
+                         alarm_factory,
+                         perspective,
+                         supported_versions) {}
+
+MockQuicConnection::MockQuicConnection(
+    QuicConnectionId connection_id,
+    QuicSocketAddress initial_peer_address,
+    MockQuicConnectionHelper* helper,
+    MockAlarmFactory* alarm_factory,
+    Perspective perspective,
+    const ParsedQuicVersionVector& supported_versions)
+    : QuicConnection(
+          connection_id,
+          /*initial_self_address=*/QuicSocketAddress(QuicIpAddress::Any4(), 5),
+          initial_peer_address,
+          helper,
+          alarm_factory,
+          new testing::NiceMock<MockPacketWriter>(),
+          /* owns_writer= */ true,
+          perspective,
+          supported_versions) {
+  ON_CALL(*this, OnError(_))
+      .WillByDefault(
+          Invoke(this, &PacketSavingConnection::QuicConnection_OnError));
+  ON_CALL(*this, SendCryptoData(_, _, _))
+      .WillByDefault(
+          Invoke(this, &MockQuicConnection::QuicConnection_SendCryptoData));
+
+  SetSelfAddress(QuicSocketAddress(QuicIpAddress::Any4(), 5));
+}
+
+MockQuicConnection::~MockQuicConnection() {}
+
+void MockQuicConnection::AdvanceTime(QuicTime::Delta delta) {
+  static_cast<MockQuicConnectionHelper*>(helper())->AdvanceTime(delta);
+}
+
+bool MockQuicConnection::OnProtocolVersionMismatch(
+    ParsedQuicVersion /*version*/) {
+  return false;
+}
+
+PacketSavingConnection::PacketSavingConnection(MockQuicConnectionHelper* helper,
+                                               MockAlarmFactory* alarm_factory,
+                                               Perspective perspective)
+    : MockQuicConnection(helper, alarm_factory, perspective) {}
+
+PacketSavingConnection::PacketSavingConnection(
+    MockQuicConnectionHelper* helper,
+    MockAlarmFactory* alarm_factory,
+    Perspective perspective,
+    const ParsedQuicVersionVector& supported_versions)
+    : MockQuicConnection(helper,
+                         alarm_factory,
+                         perspective,
+                         supported_versions) {}
+
+PacketSavingConnection::~PacketSavingConnection() {}
+
+void PacketSavingConnection::SendOrQueuePacket(SerializedPacket packet) {
+  encrypted_packets_.push_back(std::make_unique<QuicEncryptedPacket>(
+      CopyBuffer(packet), packet.encrypted_length, true));
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  // Transfer ownership of the packet to the SentPacketManager and the
+  // ack notifier to the AckNotifierManager.
+  OnPacketSent(packet.encryption_level, packet.transmission_type);
+  QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent(
+      &packet, clock_.ApproximateNow(), NOT_RETRANSMISSION,
+      HAS_RETRANSMITTABLE_DATA, true);
+}
+
+MockQuicSession::MockQuicSession(QuicConnection* connection)
+    : MockQuicSession(connection, true) {}
+
+MockQuicSession::MockQuicSession(QuicConnection* connection,
+                                 bool create_mock_crypto_stream)
+    : QuicSession(connection,
+                  nullptr,
+                  DefaultQuicConfig(),
+                  connection->supported_versions(),
+                  /*num_expected_unidirectional_static_streams = */ 0) {
+  if (create_mock_crypto_stream) {
+    crypto_stream_ = std::make_unique<MockQuicCryptoStream>(this);
+  }
+  ON_CALL(*this, WritevData(_, _, _, _, _, _))
+      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
+}
+
+MockQuicSession::~MockQuicSession() {
+  DeleteConnection();
+}
+
+QuicCryptoStream* MockQuicSession::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoStream* MockQuicSession::GetCryptoStream() const {
+  return crypto_stream_.get();
+}
+
+void MockQuicSession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
+  crypto_stream_.reset(crypto_stream);
+}
+
+QuicConsumedData MockQuicSession::ConsumeData(
+    QuicStreamId id,
+    size_t write_length,
+    QuicStreamOffset offset,
+    StreamSendingState state,
+    TransmissionType /*type*/,
+    absl::optional<EncryptionLevel> /*level*/) {
+  if (write_length > 0) {
+    auto buf = std::make_unique<char[]>(write_length);
+    QuicStream* stream = GetOrCreateStream(id);
+    QUICHE_DCHECK(stream);
+    QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
+    stream->WriteStreamData(offset, write_length, &writer);
+  } else {
+    QUICHE_DCHECK(state != NO_FIN);
+  }
+  return QuicConsumedData(write_length, state != NO_FIN);
+}
+
+MockQuicCryptoStream::MockQuicCryptoStream(QuicSession* session)
+    : QuicCryptoStream(session), params_(new QuicCryptoNegotiatedParameters) {}
+
+MockQuicCryptoStream::~MockQuicCryptoStream() {}
+
+ssl_early_data_reason_t MockQuicCryptoStream::EarlyDataReason() const {
+  return ssl_early_data_unknown;
+}
+
+bool MockQuicCryptoStream::encryption_established() const {
+  return false;
+}
+
+bool MockQuicCryptoStream::one_rtt_keys_available() const {
+  return false;
+}
+
+const QuicCryptoNegotiatedParameters&
+MockQuicCryptoStream::crypto_negotiated_params() const {
+  return *params_;
+}
+
+CryptoMessageParser* MockQuicCryptoStream::crypto_message_parser() {
+  return &crypto_framer_;
+}
+
+MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
+    : MockQuicSpdySession(connection, true) {}
+
+MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection,
+                                         bool create_mock_crypto_stream)
+    : QuicSpdySession(connection,
+                      nullptr,
+                      DefaultQuicConfig(),
+                      connection->supported_versions()) {
+  if (create_mock_crypto_stream) {
+    crypto_stream_ = std::make_unique<MockQuicCryptoStream>(this);
+  }
+
+  ON_CALL(*this, WritevData(_, _, _, _, _, _))
+      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
+
+  ON_CALL(*this, SendWindowUpdate(_, _))
+      .WillByDefault([this](QuicStreamId id, QuicStreamOffset byte_offset) {
+        return QuicSpdySession::SendWindowUpdate(id, byte_offset);
+      });
+
+  ON_CALL(*this, SendBlocked(_)).WillByDefault([this](QuicStreamId id) {
+    return QuicSpdySession::SendBlocked(id);
+  });
+
+  ON_CALL(*this, OnCongestionWindowChange(_)).WillByDefault(testing::Return());
+}
+
+MockQuicSpdySession::~MockQuicSpdySession() {
+  DeleteConnection();
+}
+
+QuicCryptoStream* MockQuicSpdySession::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoStream* MockQuicSpdySession::GetCryptoStream() const {
+  return crypto_stream_.get();
+}
+
+void MockQuicSpdySession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
+  crypto_stream_.reset(crypto_stream);
+}
+
+QuicConsumedData MockQuicSpdySession::ConsumeData(
+    QuicStreamId id,
+    size_t write_length,
+    QuicStreamOffset offset,
+    StreamSendingState state,
+    TransmissionType /*type*/,
+    absl::optional<EncryptionLevel> /*level*/) {
+  if (write_length > 0) {
+    auto buf = std::make_unique<char[]>(write_length);
+    QuicStream* stream = GetOrCreateStream(id);
+    QUICHE_DCHECK(stream);
+    QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
+    stream->WriteStreamData(offset, write_length, &writer);
+  } else {
+    QUICHE_DCHECK(state != NO_FIN);
+  }
+  return QuicConsumedData(write_length, state != NO_FIN);
+}
+
+TestQuicSpdyServerSession::TestQuicSpdyServerSession(
+    QuicConnection* connection,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache)
+    : QuicServerSessionBase(config,
+                            supported_versions,
+                            connection,
+                            &visitor_,
+                            &helper_,
+                            crypto_config,
+                            compressed_certs_cache) {
+  ON_CALL(helper_, CanAcceptClientHello(_, _, _, _, _))
+      .WillByDefault(testing::Return(true));
+}
+
+TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {
+  DeleteConnection();
+}
+
+std::unique_ptr<QuicCryptoServerStreamBase>
+TestQuicSpdyServerSession::CreateQuicCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache) {
+  return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
+                                  &helper_);
+}
+
+QuicCryptoServerStreamBase*
+TestQuicSpdyServerSession::GetMutableCryptoStream() {
+  return QuicServerSessionBase::GetMutableCryptoStream();
+}
+
+const QuicCryptoServerStreamBase* TestQuicSpdyServerSession::GetCryptoStream()
+    const {
+  return QuicServerSessionBase::GetCryptoStream();
+}
+
+TestQuicSpdyClientSession::TestQuicSpdyClientSession(
+    QuicConnection* connection,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config)
+    : QuicSpdyClientSessionBase(connection,
+                                &push_promise_index_,
+                                config,
+                                supported_versions) {
+  // TODO(b/153726130): Consider adding SetServerApplicationStateForResumption
+  // calls in tests and set |has_application_state| to true.
+  crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
+      server_id, this, crypto_test_utils::ProofVerifyContextForTesting(),
+      crypto_config, this, /*has_application_state = */ false);
+  Initialize();
+  ON_CALL(*this, OnConfigNegotiated())
+      .WillByDefault(
+          Invoke(this, &TestQuicSpdyClientSession::RealOnConfigNegotiated));
+}
+
+TestQuicSpdyClientSession::~TestQuicSpdyClientSession() {}
+
+bool TestQuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
+  return true;
+}
+
+QuicCryptoClientStream* TestQuicSpdyClientSession::GetMutableCryptoStream() {
+  return crypto_stream_.get();
+}
+
+const QuicCryptoClientStream* TestQuicSpdyClientSession::GetCryptoStream()
+    const {
+  return crypto_stream_.get();
+}
+
+void TestQuicSpdyClientSession::RealOnConfigNegotiated() {
+  QuicSpdyClientSessionBase::OnConfigNegotiated();
+}
+
+TestPushPromiseDelegate::TestPushPromiseDelegate(bool match)
+    : match_(match), rendezvous_fired_(false), rendezvous_stream_(nullptr) {}
+
+bool TestPushPromiseDelegate::CheckVary(
+    const spdy::SpdyHeaderBlock& /*client_request*/,
+    const spdy::SpdyHeaderBlock& /*promise_request*/,
+    const spdy::SpdyHeaderBlock& /*promise_response*/) {
+  QUIC_DVLOG(1) << "match " << match_;
+  return match_;
+}
+
+void TestPushPromiseDelegate::OnRendezvousResult(QuicSpdyStream* stream) {
+  rendezvous_fired_ = true;
+  rendezvous_stream_ = stream;
+}
+
+MockPacketWriter::MockPacketWriter() {
+  ON_CALL(*this, GetMaxPacketSize(_))
+      .WillByDefault(testing::Return(kMaxOutgoingPacketSize));
+  ON_CALL(*this, IsBatchMode()).WillByDefault(testing::Return(false));
+  ON_CALL(*this, GetNextWriteLocation(_, _))
+      .WillByDefault(testing::Return(QuicPacketBuffer()));
+  ON_CALL(*this, Flush())
+      .WillByDefault(testing::Return(WriteResult(WRITE_STATUS_OK, 0)));
+  ON_CALL(*this, SupportsReleaseTime()).WillByDefault(testing::Return(false));
+}
+
+MockPacketWriter::~MockPacketWriter() {}
+
+MockSendAlgorithm::MockSendAlgorithm() {
+  ON_CALL(*this, PacingRate(_))
+      .WillByDefault(testing::Return(QuicBandwidth::Zero()));
+  ON_CALL(*this, BandwidthEstimate())
+      .WillByDefault(testing::Return(QuicBandwidth::Zero()));
+}
+
+MockSendAlgorithm::~MockSendAlgorithm() {}
+
+MockLossAlgorithm::MockLossAlgorithm() {}
+
+MockLossAlgorithm::~MockLossAlgorithm() {}
+
+MockAckListener::MockAckListener() {}
+
+MockAckListener::~MockAckListener() {}
+
+MockNetworkChangeVisitor::MockNetworkChangeVisitor() {}
+
+MockNetworkChangeVisitor::~MockNetworkChangeVisitor() {}
+
+QuicIpAddress TestPeerIPAddress() {
+  return QuicIpAddress::Loopback4();
+}
+
+ParsedQuicVersion QuicVersionMax() {
+  return AllSupportedVersions().front();
+}
+
+ParsedQuicVersion QuicVersionMin() {
+  return AllSupportedVersions().back();
+}
+
+void DisableQuicVersionsWithTls() {
+  for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
+    QuicDisableVersion(version);
+  }
+}
+
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id,
+    bool version_flag,
+    bool reset_flag,
+    uint64_t packet_number,
+    const std::string& data) {
+  return ConstructEncryptedPacket(
+      destination_connection_id, source_connection_id, version_flag, reset_flag,
+      packet_number, data, CONNECTION_ID_PRESENT, CONNECTION_ID_ABSENT,
+      PACKET_4BYTE_PACKET_NUMBER);
+}
+
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id,
+    bool version_flag,
+    bool reset_flag,
+    uint64_t packet_number,
+    const std::string& data,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length) {
+  return ConstructEncryptedPacket(
+      destination_connection_id, source_connection_id, version_flag, reset_flag,
+      packet_number, data, destination_connection_id_included,
+      source_connection_id_included, packet_number_length, nullptr);
+}
+
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id,
+    bool version_flag,
+    bool reset_flag,
+    uint64_t packet_number,
+    const std::string& data,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersionVector* versions) {
+  return ConstructEncryptedPacket(
+      destination_connection_id, source_connection_id, version_flag, reset_flag,
+      packet_number, data, false, destination_connection_id_included,
+      source_connection_id_included, packet_number_length, versions,
+      Perspective::IS_CLIENT);
+}
+
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id,
+    bool version_flag,
+    bool reset_flag,
+    uint64_t packet_number,
+    const std::string& data,
+    bool full_padding,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersionVector* versions) {
+  return ConstructEncryptedPacket(
+      destination_connection_id, source_connection_id, version_flag, reset_flag,
+      packet_number, data, full_padding, destination_connection_id_included,
+      source_connection_id_included, packet_number_length, versions,
+      Perspective::IS_CLIENT);
+}
+
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id,
+    bool version_flag,
+    bool reset_flag,
+    uint64_t packet_number,
+    const std::string& data,
+    bool full_padding,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersionVector* versions,
+    Perspective perspective) {
+  QuicPacketHeader header;
+  header.destination_connection_id = destination_connection_id;
+  header.destination_connection_id_included =
+      destination_connection_id_included;
+  header.source_connection_id = source_connection_id;
+  header.source_connection_id_included = source_connection_id_included;
+  header.version_flag = version_flag;
+  header.reset_flag = reset_flag;
+  header.packet_number_length = packet_number_length;
+  header.packet_number = QuicPacketNumber(packet_number);
+  ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
+  if (!versions) {
+    versions = &supported_versions;
+  }
+  EXPECT_FALSE(versions->empty());
+  ParsedQuicVersion version = (*versions)[0];
+  if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
+      version_flag) {
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicFrames frames;
+  QuicFramer framer(*versions, QuicTime::Zero(), perspective,
+                    kQuicDefaultConnectionIdLength);
+  framer.SetInitialObfuscators(destination_connection_id);
+  EncryptionLevel level =
+      header.version_flag ? ENCRYPTION_INITIAL : ENCRYPTION_FORWARD_SECURE;
+  if (level != ENCRYPTION_INITIAL) {
+    framer.SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
+  }
+  if (!QuicVersionUsesCryptoFrames(version.transport_version)) {
+    QuicFrame frame(
+        QuicStreamFrame(QuicUtils::GetCryptoStreamId(version.transport_version),
+                        false, 0, absl::string_view(data)));
+    frames.push_back(frame);
+  } else {
+    QuicFrame frame(new QuicCryptoFrame(level, 0, data));
+    frames.push_back(frame);
+  }
+  if (full_padding) {
+    frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  } else {
+    // We need a minimum number of bytes of encrypted payload. This will
+    // guarantee that we have at least that much. (It ignores the overhead of
+    // the stream/crypto framing, so it overpads slightly.)
+    size_t min_plaintext_size =
+        QuicPacketCreator::MinPlaintextPacketSize(version);
+    if (data.length() < min_plaintext_size) {
+      size_t padding_length = min_plaintext_size - data.length();
+      frames.push_back(QuicFrame(QuicPaddingFrame(padding_length)));
+    }
+  }
+
+  std::unique_ptr<QuicPacket> packet(
+      BuildUnsizedDataPacket(&framer, header, frames));
+  EXPECT_TRUE(packet != nullptr);
+  char* buffer = new char[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer.EncryptPayload(level, QuicPacketNumber(packet_number), *packet,
+                            buffer, kMaxOutgoingPacketSize);
+  EXPECT_NE(0u, encrypted_length);
+  DeleteFrames(&frames);
+  return new QuicEncryptedPacket(buffer, encrypted_length, true);
+}
+
+std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id) {
+  QuicPacketHeader header;
+  header.destination_connection_id = server_connection_id;
+  header.destination_connection_id_included = CONNECTION_ID_PRESENT;
+  header.source_connection_id = EmptyQuicConnectionId();
+  header.source_connection_id_included = CONNECTION_ID_PRESENT;
+  if (!version.SupportsClientConnectionIds()) {
+    header.source_connection_id_included = CONNECTION_ID_ABSENT;
+  }
+  header.version_flag = true;
+  header.reset_flag = false;
+  header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
+  header.packet_number = QuicPacketNumber(33);
+  header.long_packet_type = ZERO_RTT_PROTECTED;
+  if (version.HasLongHeaderLengths()) {
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicPingFrame()));
+  frames.push_back(QuicFrame(QuicPaddingFrame(100)));
+  QuicFramer framer({version}, QuicTime::Zero(), Perspective::IS_CLIENT,
+                    kQuicDefaultConnectionIdLength);
+  framer.SetInitialObfuscators(server_connection_id);
+
+  framer.SetEncrypter(ENCRYPTION_ZERO_RTT,
+                      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  std::unique_ptr<QuicPacket> packet(
+      BuildUnsizedDataPacket(&framer, header, frames));
+  EXPECT_TRUE(packet != nullptr);
+  char* buffer = new char[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer.EncryptPayload(ENCRYPTION_ZERO_RTT, header.packet_number, *packet,
+                            buffer, kMaxOutgoingPacketSize);
+  EXPECT_NE(0u, encrypted_length);
+  DeleteFrames(&frames);
+  return std::make_unique<QuicEncryptedPacket>(buffer, encrypted_length,
+                                               /*owns_buffer=*/true);
+}
+
+QuicReceivedPacket* ConstructReceivedPacket(
+    const QuicEncryptedPacket& encrypted_packet,
+    QuicTime receipt_time) {
+  char* buffer = new char[encrypted_packet.length()];
+  memcpy(buffer, encrypted_packet.data(), encrypted_packet.length());
+  return new QuicReceivedPacket(buffer, encrypted_packet.length(), receipt_time,
+                                true);
+}
+
+QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id,
+    bool version_flag,
+    bool reset_flag,
+    uint64_t packet_number,
+    const std::string& data,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersion version,
+    Perspective perspective) {
+  QuicPacketHeader header;
+  header.destination_connection_id = destination_connection_id;
+  header.destination_connection_id_included =
+      destination_connection_id_included;
+  header.source_connection_id = source_connection_id;
+  header.source_connection_id_included = source_connection_id_included;
+  header.version_flag = version_flag;
+  header.reset_flag = reset_flag;
+  header.packet_number_length = packet_number_length;
+  header.packet_number = QuicPacketNumber(packet_number);
+  if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
+      version_flag) {
+    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+  QuicFrame frame(QuicStreamFrame(1, false, 0, absl::string_view(data)));
+  QuicFrames frames;
+  frames.push_back(frame);
+  QuicFramer framer({version}, QuicTime::Zero(), perspective,
+                    kQuicDefaultConnectionIdLength);
+  framer.SetInitialObfuscators(destination_connection_id);
+  EncryptionLevel level =
+      version_flag ? ENCRYPTION_INITIAL : ENCRYPTION_FORWARD_SECURE;
+  if (level != ENCRYPTION_INITIAL) {
+    framer.SetEncrypter(level, std::make_unique<NullEncrypter>(perspective));
+  }
+  // We need a minimum of 7 bytes of encrypted payload. This will guarantee that
+  // we have at least that much. (It ignores the overhead of the stream/crypto
+  // framing, so it overpads slightly.)
+  if (data.length() < 7) {
+    size_t padding_length = 7 - data.length();
+    frames.push_back(QuicFrame(QuicPaddingFrame(padding_length)));
+  }
+
+  std::unique_ptr<QuicPacket> packet(
+      BuildUnsizedDataPacket(&framer, header, frames));
+  EXPECT_TRUE(packet != nullptr);
+
+  // Now set the frame type to 0x1F, which is an invalid frame type.
+  reinterpret_cast<unsigned char*>(
+      packet->mutable_data())[GetStartOfEncryptedData(
+      framer.transport_version(),
+      GetIncludedDestinationConnectionIdLength(header),
+      GetIncludedSourceConnectionIdLength(header), version_flag,
+      false /* no diversification nonce */, packet_number_length,
+      header.retry_token_length_length, 0, header.length_length)] = 0x1F;
+
+  char* buffer = new char[kMaxOutgoingPacketSize];
+  size_t encrypted_length =
+      framer.EncryptPayload(level, QuicPacketNumber(packet_number), *packet,
+                            buffer, kMaxOutgoingPacketSize);
+  EXPECT_NE(0u, encrypted_length);
+  return new QuicEncryptedPacket(buffer, encrypted_length, true);
+}
+
+QuicConfig DefaultQuicConfig() {
+  QuicConfig config;
+  config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
+      &config, kDefaultMaxStreamsPerConnection);
+  // Default enable NSTP.
+  // This is unnecessary for versions > 44
+  if (!config.HasClientSentConnectionOption(quic::kNSTP,
+                                            quic::Perspective::IS_CLIENT)) {
+    quic::QuicTagVector connection_options;
+    connection_options.push_back(quic::kNSTP);
+    config.SetConnectionOptionsToSend(connection_options);
+  }
+  return config;
+}
+
+ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version) {
+  ParsedQuicVersionVector versions;
+  versions.push_back(version);
+  return versions;
+}
+
+MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {}
+
+MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {}
+
+MockReceivedPacketManager::MockReceivedPacketManager(QuicConnectionStats* stats)
+    : QuicReceivedPacketManager(stats) {}
+
+MockReceivedPacketManager::~MockReceivedPacketManager() {}
+
+MockPacketCreatorDelegate::MockPacketCreatorDelegate() {}
+MockPacketCreatorDelegate::~MockPacketCreatorDelegate() {}
+
+MockSessionNotifier::MockSessionNotifier() {}
+MockSessionNotifier::~MockSessionNotifier() {}
+
+// static
+QuicCryptoClientStream::HandshakerInterface*
+QuicCryptoClientStreamPeer::GetHandshaker(QuicCryptoClientStream* stream) {
+  return stream->handshaker_.get();
+}
+
+void CreateClientSessionForTest(
+    QuicServerId server_id,
+    QuicTime::Delta connection_start_time,
+    const ParsedQuicVersionVector& supported_versions,
+    MockQuicConnectionHelper* helper,
+    MockAlarmFactory* alarm_factory,
+    QuicCryptoClientConfig* crypto_client_config,
+    PacketSavingConnection** client_connection,
+    TestQuicSpdyClientSession** client_session) {
+  QUICHE_CHECK(crypto_client_config);
+  QUICHE_CHECK(client_connection);
+  QUICHE_CHECK(client_session);
+  QUICHE_CHECK(!connection_start_time.IsZero())
+      << "Connections must start at non-zero times, otherwise the "
+      << "strike-register will be unhappy.";
+
+  QuicConfig config = DefaultQuicConfig();
+  *client_connection = new PacketSavingConnection(
+      helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
+  *client_session = new TestQuicSpdyClientSession(*client_connection, config,
+                                                  supported_versions, server_id,
+                                                  crypto_client_config);
+  (*client_connection)->AdvanceTime(connection_start_time);
+}
+
+void CreateServerSessionForTest(
+    QuicServerId /*server_id*/,
+    QuicTime::Delta connection_start_time,
+    ParsedQuicVersionVector supported_versions,
+    MockQuicConnectionHelper* helper,
+    MockAlarmFactory* alarm_factory,
+    QuicCryptoServerConfig* server_crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    PacketSavingConnection** server_connection,
+    TestQuicSpdyServerSession** server_session) {
+  QUICHE_CHECK(server_crypto_config);
+  QUICHE_CHECK(server_connection);
+  QUICHE_CHECK(server_session);
+  QUICHE_CHECK(!connection_start_time.IsZero())
+      << "Connections must start at non-zero times, otherwise the "
+      << "strike-register will be unhappy.";
+
+  *server_connection =
+      new PacketSavingConnection(helper, alarm_factory, Perspective::IS_SERVER,
+                                 ParsedVersionOfIndex(supported_versions, 0));
+  *server_session = new TestQuicSpdyServerSession(
+      *server_connection, DefaultQuicConfig(), supported_versions,
+      server_crypto_config, compressed_certs_cache);
+  (*server_session)->Initialize();
+
+  // We advance the clock initially because the default time is zero and the
+  // strike register worries that we've just overflowed a uint32_t time.
+  (*server_connection)->AdvanceTime(connection_start_time);
+}
+
+QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
+    QuicTransportVersion version,
+    int n) {
+  int num = n;
+  if (!VersionUsesHttp3(version)) {
+    num++;
+  }
+  return QuicUtils::GetFirstBidirectionalStreamId(version,
+                                                  Perspective::IS_CLIENT) +
+         QuicUtils::StreamIdDelta(version) * num;
+}
+
+QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
+    QuicTransportVersion version,
+    int n) {
+  return QuicUtils::GetFirstBidirectionalStreamId(version,
+                                                  Perspective::IS_SERVER) +
+         QuicUtils::StreamIdDelta(version) * n;
+}
+
+QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
+    QuicTransportVersion version,
+    int n) {
+  return QuicUtils::GetFirstUnidirectionalStreamId(version,
+                                                   Perspective::IS_SERVER) +
+         QuicUtils::StreamIdDelta(version) * n;
+}
+
+QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
+    QuicTransportVersion version,
+    int n) {
+  return QuicUtils::GetFirstUnidirectionalStreamId(version,
+                                                   Perspective::IS_CLIENT) +
+         QuicUtils::StreamIdDelta(version) * n;
+}
+
+StreamType DetermineStreamType(QuicStreamId id,
+                               ParsedQuicVersion version,
+                               Perspective perspective,
+                               bool is_incoming,
+                               StreamType default_type) {
+  return version.HasIetfQuicFrames()
+             ? QuicUtils::GetStreamType(id, perspective, is_incoming, version)
+             : default_type;
+}
+
+quiche::QuicheMemSlice MemSliceFromString(absl::string_view data) {
+  if (data.empty()) {
+    return quiche::QuicheMemSlice();
+  }
+
+  static quiche::SimpleBufferAllocator* allocator =
+      new quiche::SimpleBufferAllocator();
+  return quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(allocator, data));
+}
+
+bool TaggingEncrypter::EncryptPacket(uint64_t /*packet_number*/,
+                                     absl::string_view /*associated_data*/,
+                                     absl::string_view plaintext,
+                                     char* output,
+                                     size_t* output_length,
+                                     size_t max_output_length) {
+  const size_t len = plaintext.size() + kTagSize;
+  if (max_output_length < len) {
+    return false;
+  }
+  // Memmove is safe for inplace encryption.
+  memmove(output, plaintext.data(), plaintext.size());
+  output += plaintext.size();
+  memset(output, tag_, kTagSize);
+  *output_length = len;
+  return true;
+}
+
+bool TaggingDecrypter::DecryptPacket(uint64_t /*packet_number*/,
+                                     absl::string_view /*associated_data*/,
+                                     absl::string_view ciphertext,
+                                     char* output,
+                                     size_t* output_length,
+                                     size_t /*max_output_length*/) {
+  if (ciphertext.size() < kTagSize) {
+    return false;
+  }
+  if (!CheckTag(ciphertext, GetTag(ciphertext))) {
+    return false;
+  }
+  *output_length = ciphertext.size() - kTagSize;
+  memcpy(output, ciphertext.data(), *output_length);
+  return true;
+}
+
+bool TaggingDecrypter::CheckTag(absl::string_view ciphertext, uint8_t tag) {
+  for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) {
+    if (ciphertext.data()[i] != tag) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+TestPacketWriter::TestPacketWriter(ParsedQuicVersion version,
+                                   MockClock* clock,
+                                   Perspective perspective)
+    : version_(version),
+      framer_(SupportedVersions(version_),
+              QuicUtils::InvertPerspective(perspective)),
+      clock_(clock) {
+  QuicFramerPeer::SetLastSerializedServerConnectionId(framer_.framer(),
+                                                      TestConnectionId());
+  framer_.framer()->SetInitialObfuscators(TestConnectionId());
+
+  for (int i = 0; i < 128; ++i) {
+    PacketBuffer* p = new PacketBuffer();
+    packet_buffer_pool_.push_back(p);
+    packet_buffer_pool_index_[p->buffer] = p;
+    packet_buffer_free_list_.push_back(p);
+  }
+}
+
+TestPacketWriter::~TestPacketWriter() {
+  EXPECT_EQ(packet_buffer_pool_.size(), packet_buffer_free_list_.size())
+      << packet_buffer_pool_.size() - packet_buffer_free_list_.size()
+      << " out of " << packet_buffer_pool_.size()
+      << " packet buffers have been leaked.";
+  for (auto p : packet_buffer_pool_) {
+    delete p;
+  }
+}
+
+WriteResult TestPacketWriter::WritePacket(const char* buffer,
+                                          size_t buf_len,
+                                          const QuicIpAddress& self_address,
+                                          const QuicSocketAddress& peer_address,
+                                          PerPacketOptions* /*options*/) {
+  last_write_source_address_ = self_address;
+  last_write_peer_address_ = peer_address;
+  // If the buffer is allocated from the pool, return it back to the pool.
+  // Note the buffer content doesn't change.
+  if (packet_buffer_pool_index_.find(const_cast<char*>(buffer)) !=
+      packet_buffer_pool_index_.end()) {
+    FreePacketBuffer(buffer);
+  }
+
+  QuicEncryptedPacket packet(buffer, buf_len);
+  ++packets_write_attempts_;
+
+  if (packet.length() >= sizeof(final_bytes_of_last_packet_)) {
+    final_bytes_of_previous_packet_ = final_bytes_of_last_packet_;
+    memcpy(&final_bytes_of_last_packet_, packet.data() + packet.length() - 4,
+           sizeof(final_bytes_of_last_packet_));
+  }
+
+  if (use_tagging_decrypter_) {
+    if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
+      framer_.framer()->InstallDecrypter(ENCRYPTION_INITIAL,
+                                         std::make_unique<TaggingDecrypter>());
+      framer_.framer()->InstallDecrypter(ENCRYPTION_HANDSHAKE,
+                                         std::make_unique<TaggingDecrypter>());
+      framer_.framer()->InstallDecrypter(ENCRYPTION_ZERO_RTT,
+                                         std::make_unique<TaggingDecrypter>());
+      framer_.framer()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                                         std::make_unique<TaggingDecrypter>());
+    } else {
+      framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
+                                     std::make_unique<TaggingDecrypter>());
+    }
+  } else if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
+    framer_.framer()->InstallDecrypter(
+        ENCRYPTION_HANDSHAKE,
+        std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
+    framer_.framer()->InstallDecrypter(
+        ENCRYPTION_ZERO_RTT,
+        std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
+    framer_.framer()->InstallDecrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
+  }
+  EXPECT_TRUE(framer_.ProcessPacket(packet))
+      << framer_.framer()->detailed_error() << " perspective "
+      << framer_.framer()->perspective();
+  if (block_on_next_write_) {
+    write_blocked_ = true;
+    block_on_next_write_ = false;
+  }
+  if (next_packet_too_large_) {
+    next_packet_too_large_ = false;
+    return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
+  }
+  if (always_get_packet_too_large_) {
+    return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
+  }
+  if (IsWriteBlocked()) {
+    return WriteResult(is_write_blocked_data_buffered_
+                           ? WRITE_STATUS_BLOCKED_DATA_BUFFERED
+                           : WRITE_STATUS_BLOCKED,
+                       0);
+  }
+
+  if (ShouldWriteFail()) {
+    return WriteResult(WRITE_STATUS_ERROR, write_error_code_);
+  }
+
+  last_packet_size_ = packet.length();
+  last_packet_header_ = framer_.header();
+  if (!framer_.connection_close_frames().empty()) {
+    ++connection_close_packets_;
+  }
+  if (!write_pause_time_delta_.IsZero()) {
+    clock_->AdvanceTime(write_pause_time_delta_);
+  }
+  if (is_batch_mode_) {
+    bytes_buffered_ += last_packet_size_;
+    return WriteResult(WRITE_STATUS_OK, 0);
+  }
+  return WriteResult(WRITE_STATUS_OK, last_packet_size_);
+}
+
+QuicPacketBuffer TestPacketWriter::GetNextWriteLocation(
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/) {
+  return {AllocPacketBuffer(), [this](const char* p) { FreePacketBuffer(p); }};
+}
+
+WriteResult TestPacketWriter::Flush() {
+  flush_attempts_++;
+  if (block_on_next_flush_) {
+    block_on_next_flush_ = false;
+    SetWriteBlocked();
+    return WriteResult(WRITE_STATUS_BLOCKED, /*errno*/ -1);
+  }
+  if (write_should_fail_) {
+    return WriteResult(WRITE_STATUS_ERROR, /*errno*/ -1);
+  }
+  int bytes_flushed = bytes_buffered_;
+  bytes_buffered_ = 0;
+  return WriteResult(WRITE_STATUS_OK, bytes_flushed);
+}
+
+char* TestPacketWriter::AllocPacketBuffer() {
+  PacketBuffer* p = packet_buffer_free_list_.front();
+  EXPECT_FALSE(p->in_use);
+  p->in_use = true;
+  packet_buffer_free_list_.pop_front();
+  return p->buffer;
+}
+
+void TestPacketWriter::FreePacketBuffer(const char* buffer) {
+  auto iter = packet_buffer_pool_index_.find(const_cast<char*>(buffer));
+  ASSERT_TRUE(iter != packet_buffer_pool_index_.end());
+  PacketBuffer* p = iter->second;
+  ASSERT_TRUE(p->in_use);
+  p->in_use = false;
+  packet_buffer_free_list_.push_back(p);
+}
+
+bool WriteServerVersionNegotiationProbeResponse(
+    char* packet_bytes,
+    size_t* packet_length_out,
+    const char* source_connection_id_bytes,
+    uint8_t source_connection_id_length) {
+  if (packet_bytes == nullptr) {
+    QUIC_BUG(quic_bug_10256_1) << "Invalid packet_bytes";
+    return false;
+  }
+  if (packet_length_out == nullptr) {
+    QUIC_BUG(quic_bug_10256_2) << "Invalid packet_length_out";
+    return false;
+  }
+  QuicConnectionId source_connection_id(source_connection_id_bytes,
+                                        source_connection_id_length);
+  std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
+      QuicFramer::BuildVersionNegotiationPacket(
+          source_connection_id, EmptyQuicConnectionId(),
+          /*ietf_quic=*/true, /*use_length_prefix=*/true,
+          ParsedQuicVersionVector{});
+  if (!encrypted_packet) {
+    QUIC_BUG(quic_bug_10256_3) << "Failed to create version negotiation packet";
+    return false;
+  }
+  if (*packet_length_out < encrypted_packet->length()) {
+    QUIC_BUG(quic_bug_10256_4)
+        << "Invalid *packet_length_out " << *packet_length_out << " < "
+        << encrypted_packet->length();
+    return false;
+  }
+  *packet_length_out = encrypted_packet->length();
+  memcpy(packet_bytes, encrypted_packet->data(), *packet_length_out);
+  return true;
+}
+
+bool ParseClientVersionNegotiationProbePacket(
+    const char* packet_bytes,
+    size_t packet_length,
+    char* destination_connection_id_bytes,
+    uint8_t* destination_connection_id_length_out) {
+  if (packet_bytes == nullptr) {
+    QUIC_BUG(quic_bug_10256_5) << "Invalid packet_bytes";
+    return false;
+  }
+  if (packet_length < kMinPacketSizeForVersionNegotiation ||
+      packet_length > 65535) {
+    QUIC_BUG(quic_bug_10256_6) << "Invalid packet_length";
+    return false;
+  }
+  if (destination_connection_id_bytes == nullptr) {
+    QUIC_BUG(quic_bug_10256_7) << "Invalid destination_connection_id_bytes";
+    return false;
+  }
+  if (destination_connection_id_length_out == nullptr) {
+    QUIC_BUG(quic_bug_10256_8)
+        << "Invalid destination_connection_id_length_out";
+    return false;
+  }
+
+  QuicEncryptedPacket encrypted_packet(packet_bytes, packet_length);
+  PacketHeaderFormat format;
+  QuicLongHeaderType long_packet_type;
+  bool version_present, has_length_prefix;
+  QuicVersionLabel version_label;
+  ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+  QuicConnectionId destination_connection_id, source_connection_id;
+  absl::optional<absl::string_view> retry_token;
+  std::string detailed_error;
+  QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+      encrypted_packet,
+      /*expected_destination_connection_id_length=*/0, &format,
+      &long_packet_type, &version_present, &has_length_prefix, &version_label,
+      &parsed_version, &destination_connection_id, &source_connection_id,
+      &retry_token, &detailed_error);
+  if (error != QUIC_NO_ERROR) {
+    QUIC_BUG(quic_bug_10256_9) << "Failed to parse packet: " << detailed_error;
+    return false;
+  }
+  if (!version_present) {
+    QUIC_BUG(quic_bug_10256_10) << "Packet is not a long header";
+    return false;
+  }
+  if (*destination_connection_id_length_out <
+      destination_connection_id.length()) {
+    QUIC_BUG(quic_bug_10256_11)
+        << "destination_connection_id_length_out too small";
+    return false;
+  }
+  *destination_connection_id_length_out = destination_connection_id.length();
+  memcpy(destination_connection_id_bytes, destination_connection_id.data(),
+         *destination_connection_id_length_out);
+  return true;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h
new file mode 100644
index 0000000..80a88d1
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -0,0 +1,2036 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Common utilities for Quic tests
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
+#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_server_session_base.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_sent_packet_manager.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/mock_random.h"
+#include "quiche/quic/test_tools/quic_framer_peer.h"
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/common/quiche_mem_slice_storage.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+namespace test {
+
+// A generic predictable connection ID suited for testing.
+QuicConnectionId TestConnectionId();
+
+// A generic predictable connection ID suited for testing, generated from a
+// given number, such as an index.
+QuicConnectionId TestConnectionId(uint64_t connection_number);
+
+// A generic predictable connection ID suited for testing, generated from a
+// given number, such as an index. Guaranteed to be 9 bytes long.
+QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number);
+
+// Extracts the connection number passed to TestConnectionId().
+uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id);
+
+enum : uint16_t { kTestPort = 12345 };
+enum : uint32_t {
+  kMaxDatagramFrameSizeForTest = 1333,
+  kMaxPacketSizeForTest = 9001,
+  kInitialStreamFlowControlWindowForTest = 1024 * 1024,   // 1 MB
+  kInitialSessionFlowControlWindowForTest = 1536 * 1024,  // 1.5 MB
+};
+
+enum : uint64_t {
+  kAckDelayExponentForTest = 10,
+  kMaxAckDelayForTest = 51,  // ms
+  kActiveConnectionIdLimitForTest = 52,
+  kMinAckDelayUsForTest = 1000
+};
+
+// Create an arbitrary stateless reset token, same across multiple calls.
+std::vector<uint8_t> CreateStatelessResetTokenForTest();
+
+// A hostname useful for testing, returns "test.example.org".
+std::string TestHostname();
+
+// A server ID useful for testing, returns test.example.org:12345.
+QuicServerId TestServerId();
+
+// Returns the test peer IP address.
+QuicIpAddress TestPeerIPAddress();
+
+// Upper limit on versions we support.
+ParsedQuicVersion QuicVersionMax();
+
+// Lower limit on versions we support.
+ParsedQuicVersion QuicVersionMin();
+
+// Disables all flags that enable QUIC versions that use TLS.
+// This is only meant as a temporary measure to prevent some broken tests
+// from running with TLS.
+void DisableQuicVersionsWithTls();
+
+// Create an encrypted packet for testing.
+// If versions == nullptr, uses &AllSupportedVersions().
+// Note that the packet is encrypted with NullEncrypter, so to decrypt the
+// constructed packet, the framer must be set to use NullDecrypter.
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
+    uint64_t packet_number, const std::string& data, bool full_padding,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersionVector* versions, Perspective perspective);
+
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
+    uint64_t packet_number, const std::string& data, bool full_padding,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersionVector* versions);
+
+// Create an encrypted packet for testing.
+// If versions == nullptr, uses &AllSupportedVersions().
+// Note that the packet is encrypted with NullEncrypter, so to decrypt the
+// constructed packet, the framer must be set to use NullDecrypter.
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
+    uint64_t packet_number, const std::string& data,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length,
+    ParsedQuicVersionVector* versions);
+
+// This form assumes |versions| == nullptr.
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
+    uint64_t packet_number, const std::string& data,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length);
+
+// This form assumes |connection_id_length| == PACKET_8BYTE_CONNECTION_ID,
+// |packet_number_length| == PACKET_4BYTE_PACKET_NUMBER and
+// |versions| == nullptr.
+QuicEncryptedPacket* ConstructEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
+    uint64_t packet_number, const std::string& data);
+
+// Creates a client-to-server ZERO-RTT packet that will fail to decrypt.
+std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id);
+
+// Constructs a received packet for testing. The caller must take ownership
+// of the returned pointer.
+QuicReceivedPacket* ConstructReceivedPacket(
+    const QuicEncryptedPacket& encrypted_packet, QuicTime receipt_time);
+
+// Create an encrypted packet for testing whose data portion erroneous.
+// The specific way the data portion is erroneous is not specified, but
+// it is an error that QuicFramer detects.
+// Note that the packet is encrypted with NullEncrypter, so to decrypt the
+// constructed packet, the framer must be set to use NullDecrypter.
+QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
+    QuicConnectionId destination_connection_id,
+    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
+    uint64_t packet_number, const std::string& data,
+    QuicConnectionIdIncluded destination_connection_id_included,
+    QuicConnectionIdIncluded source_connection_id_included,
+    QuicPacketNumberLength packet_number_length, ParsedQuicVersion version,
+    Perspective perspective);
+
+// Returns QuicConfig set to default values.
+QuicConfig DefaultQuicConfig();
+
+ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version);
+
+struct QuicAckBlock {
+  QuicPacketNumber start;  // Included
+  QuicPacketNumber limit;  // Excluded
+};
+
+// Testing convenience method to construct a QuicAckFrame with arbitrary ack
+// blocks. Each block is given by a (closed-open) range of packet numbers. e.g.:
+// InitAckFrame({{1, 10}})
+//   => 1 ack block acking packet numbers 1 to 9.
+//
+// InitAckFrame({{1, 2}, {3, 4}})
+//   => 2 ack blocks acking packet 1 and 3. Packet 2 is missing.
+QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks);
+
+// Testing convenience method to construct a QuicAckFrame with 1 ack block which
+// covers packet number range [1, |largest_acked| + 1).
+// Equivalent to InitAckFrame({{1, largest_acked + 1}})
+QuicAckFrame InitAckFrame(uint64_t largest_acked);
+QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked);
+
+// Testing convenience method to construct a QuicAckFrame with |num_ack_blocks|
+// ack blocks of width 1 packet, starting from |least_unacked| + 2.
+QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
+                                       uint64_t least_unacked);
+
+// Testing convenice method to construct a QuicAckFrame with |largest_acked|,
+// ack blocks of width 1 packet and |gap_size|.
+QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size, size_t max_num_gaps,
+                                  uint64_t largest_acked);
+
+// Returns the encryption level that corresponds to the header type in
+// |header|. If the header is for GOOGLE_QUIC_PACKET instead of an
+// IETF-invariants packet, this function returns ENCRYPTION_INITIAL.
+EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header);
+
+// Returns a QuicPacket that is owned by the caller, and
+// is populated with the fields in |header| and |frames|, or is nullptr if the
+// packet could not be created.
+std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
+    QuicFramer* framer, const QuicPacketHeader& header,
+    const QuicFrames& frames);
+// Returns a QuicPacket that is owned by the caller, and of size |packet_size|.
+std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
+    QuicFramer* framer, const QuicPacketHeader& header,
+    const QuicFrames& frames, size_t packet_size);
+
+// Compute SHA-1 hash of the supplied std::string.
+std::string Sha1Hash(absl::string_view data);
+
+// Delete |frame| and return true.
+bool ClearControlFrame(const QuicFrame& frame);
+bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
+                                           TransmissionType type);
+
+// Simple random number generator used to compute random numbers suitable
+// for pseudo-randomly dropping packets in tests.
+class SimpleRandom : public QuicRandom {
+ public:
+  SimpleRandom() { set_seed(0); }
+  SimpleRandom(const SimpleRandom&) = delete;
+  SimpleRandom& operator=(const SimpleRandom&) = delete;
+  ~SimpleRandom() override {}
+
+  // Generates |len| random bytes in the |data| buffer.
+  void RandBytes(void* data, size_t len) override;
+  // Returns a random number in the range [0, kuint64max].
+  uint64_t RandUint64() override;
+
+  // InsecureRandBytes behaves equivalently to RandBytes.
+  void InsecureRandBytes(void* data, size_t len) override;
+  // InsecureRandUint64 behaves equivalently to RandUint64.
+  uint64_t InsecureRandUint64() override;
+
+  void set_seed(uint64_t seed);
+
+ private:
+  uint8_t buffer_[4096];
+  size_t buffer_offset_ = 0;
+  uint8_t key_[32];
+
+  void FillBuffer();
+};
+
+class MockFramerVisitor : public QuicFramerVisitorInterface {
+ public:
+  MockFramerVisitor();
+  MockFramerVisitor(const MockFramerVisitor&) = delete;
+  MockFramerVisitor& operator=(const MockFramerVisitor&) = delete;
+  ~MockFramerVisitor() override;
+
+  MOCK_METHOD(void, OnError, (QuicFramer*), (override));
+  // The constructor sets this up to return false by default.
+  MOCK_METHOD(bool, OnProtocolVersionMismatch, (ParsedQuicVersion version),
+              (override));
+  MOCK_METHOD(void, OnPacket, (), (override));
+  MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket& header),
+              (override));
+  MOCK_METHOD(void, OnVersionNegotiationPacket,
+              (const QuicVersionNegotiationPacket& packet), (override));
+  MOCK_METHOD(void, OnRetryPacket,
+              (QuicConnectionId original_connection_id,
+               QuicConnectionId new_connection_id,
+               absl::string_view retry_token,
+               absl::string_view retry_integrity_tag,
+               absl::string_view retry_without_tag),
+              (override));
+  // The constructor sets this up to return true by default.
+  MOCK_METHOD(bool, OnUnauthenticatedHeader, (const QuicPacketHeader& header),
+              (override));
+  // The constructor sets this up to return true by default.
+  MOCK_METHOD(bool, OnUnauthenticatedPublicHeader,
+              (const QuicPacketHeader& header), (override));
+  MOCK_METHOD(void, OnDecryptedPacket, (size_t length, EncryptionLevel level),
+              (override));
+  MOCK_METHOD(bool, OnPacketHeader, (const QuicPacketHeader& header),
+              (override));
+  MOCK_METHOD(void, OnCoalescedPacket, (const QuicEncryptedPacket& packet),
+              (override));
+  MOCK_METHOD(void, OnUndecryptablePacket,
+              (const QuicEncryptedPacket& packet,
+               EncryptionLevel decryption_level, bool has_decryption_key),
+              (override));
+  MOCK_METHOD(bool, OnStreamFrame, (const QuicStreamFrame& frame), (override));
+  MOCK_METHOD(bool, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
+  MOCK_METHOD(bool, OnAckFrameStart, (QuicPacketNumber, QuicTime::Delta),
+              (override));
+  MOCK_METHOD(bool, OnAckRange, (QuicPacketNumber, QuicPacketNumber),
+              (override));
+  MOCK_METHOD(bool, OnAckTimestamp, (QuicPacketNumber, QuicTime), (override));
+  MOCK_METHOD(bool, OnAckFrameEnd, (QuicPacketNumber), (override));
+  MOCK_METHOD(bool, OnStopWaitingFrame, (const QuicStopWaitingFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnPaddingFrame, (const QuicPaddingFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnPingFrame, (const QuicPingFrame& frame), (override));
+  MOCK_METHOD(bool, OnRstStreamFrame, (const QuicRstStreamFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnConnectionCloseFrame,
+              (const QuicConnectionCloseFrame& frame), (override));
+  MOCK_METHOD(bool, OnNewConnectionIdFrame,
+              (const QuicNewConnectionIdFrame& frame), (override));
+  MOCK_METHOD(bool, OnRetireConnectionIdFrame,
+              (const QuicRetireConnectionIdFrame& frame), (override));
+  MOCK_METHOD(bool, OnNewTokenFrame, (const QuicNewTokenFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnPathChallengeFrame, (const QuicPathChallengeFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnGoAwayFrame, (const QuicGoAwayFrame& frame), (override));
+  MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnStreamsBlockedFrame,
+              (const QuicStreamsBlockedFrame& frame), (override));
+  MOCK_METHOD(bool, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnBlockedFrame, (const QuicBlockedFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnMessageFrame, (const QuicMessageFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnHandshakeDoneFrame, (const QuicHandshakeDoneFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnAckFrequencyFrame, (const QuicAckFrequencyFrame& frame),
+              (override));
+  MOCK_METHOD(void, OnPacketComplete, (), (override));
+  MOCK_METHOD(bool, IsValidStatelessResetToken, (const StatelessResetToken&),
+              (const, override));
+  MOCK_METHOD(void, OnAuthenticatedIetfStatelessResetPacket,
+              (const QuicIetfStatelessResetPacket&), (override));
+  MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
+  MOCK_METHOD(void, OnDecryptedFirstPacketInKeyPhase, (), (override));
+  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
+  MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
+              (override));
+};
+
+class NoOpFramerVisitor : public QuicFramerVisitorInterface {
+ public:
+  NoOpFramerVisitor() {}
+  NoOpFramerVisitor(const NoOpFramerVisitor&) = delete;
+  NoOpFramerVisitor& operator=(const NoOpFramerVisitor&) = delete;
+
+  void OnError(QuicFramer* /*framer*/) override {}
+  void OnPacket() override {}
+  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {}
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {}
+  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
+  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
+  void OnDecryptedPacket(size_t /*length*/,
+                         EncryptionLevel /*level*/) override {}
+  bool OnPacketHeader(const QuicPacketHeader& header) override;
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
+  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
+                             EncryptionLevel decryption_level,
+                             bool has_decryption_key) override;
+  bool OnStreamFrame(const QuicStreamFrame& frame) override;
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override;
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override;
+  bool OnAckFrameEnd(QuicPacketNumber start) override;
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
+  bool OnPingFrame(const QuicPingFrame& frame) override;
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override;
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
+  bool OnMessageFrame(const QuicMessageFrame& frame) override;
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
+  void OnPacketComplete() override {}
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& token) const override;
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& /*packet*/) override {}
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  void OnDecryptedFirstPacketInKeyPhase() override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+};
+
+class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
+ public:
+  MockQuicConnectionVisitor();
+  MockQuicConnectionVisitor(const MockQuicConnectionVisitor&) = delete;
+  MockQuicConnectionVisitor& operator=(const MockQuicConnectionVisitor&) =
+      delete;
+  ~MockQuicConnectionVisitor() override;
+
+  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
+  MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
+  MOCK_METHOD(void, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
+              (override));
+  MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame& frame),
+              (override));
+  MOCK_METHOD(void, OnRstStream, (const QuicRstStreamFrame& frame), (override));
+  MOCK_METHOD(void, OnGoAway, (const QuicGoAwayFrame& frame), (override));
+  MOCK_METHOD(void, OnMessageReceived, (absl::string_view message), (override));
+  MOCK_METHOD(void, OnHandshakeDoneReceived, (), (override));
+  MOCK_METHOD(void, OnNewTokenReceived, (absl::string_view token), (override));
+  MOCK_METHOD(void, OnConnectionClosed,
+              (const QuicConnectionCloseFrame& frame,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(void, OnWriteBlocked, (), (override));
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool, SendProbingData, (), (override));
+  MOCK_METHOD(bool, ValidateStatelessReset,
+              (const quic::QuicSocketAddress&, const quic::QuicSocketAddress&),
+              (override));
+  MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
+  MOCK_METHOD(void, OnConnectionMigration, (AddressChangeType type),
+              (override));
+  MOCK_METHOD(void, OnPathDegrading, (), (override));
+  MOCK_METHOD(void, OnForwardProgressMadeAfterPathDegrading, (), (override));
+  MOCK_METHOD(bool, WillingAndAbleToWrite, (), (const, override));
+  MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
+  MOCK_METHOD(std::string, GetStreamsInfoForLogging, (), (const, override));
+  MOCK_METHOD(void, OnSuccessfulVersionNegotiation,
+              (const ParsedQuicVersion& version), (override));
+  MOCK_METHOD(void, OnPacketReceived,
+              (const QuicSocketAddress& self_address,
+               const QuicSocketAddress& peer_address,
+               bool is_connectivity_probe),
+              (override));
+  MOCK_METHOD(void, OnAckNeedsRetransmittableFrame, (), (override));
+  MOCK_METHOD(void, SendAckFrequency, (const QuicAckFrequencyFrame& frame),
+              (override));
+  MOCK_METHOD(void, SendNewConnectionId,
+              (const QuicNewConnectionIdFrame& frame), (override));
+  MOCK_METHOD(void, SendRetireConnectionId, (uint64_t sequence_number),
+              (override));
+  MOCK_METHOD(void, OnServerConnectionIdIssued,
+              (const QuicConnectionId& server_connection_id), (override));
+  MOCK_METHOD(void, OnServerConnectionIdRetired,
+              (const QuicConnectionId& server_connection_id), (override));
+  MOCK_METHOD(bool, AllowSelfAddressChange, (), (const, override));
+  MOCK_METHOD(HandshakeState, GetHandshakeState, (), (const, override));
+  MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
+              (override));
+  MOCK_METHOD(bool, OnStreamsBlockedFrame,
+              (const QuicStreamsBlockedFrame& frame), (override));
+  MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
+              (override));
+  MOCK_METHOD(void, OnPacketDecrypted, (EncryptionLevel), (override));
+  MOCK_METHOD(void, OnOneRttPacketAcknowledged, (), (override));
+  MOCK_METHOD(void, OnHandshakePacketSent, (), (override));
+  MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
+  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
+              AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
+  MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
+              (override));
+  MOCK_METHOD(void, BeforeConnectionCloseSent, (), (override));
+  MOCK_METHOD(bool, ValidateToken, (absl::string_view), (override));
+  MOCK_METHOD(bool, MaybeSendAddressToken, (), (override));
+
+  bool IsKnownServerAddress(
+      const QuicSocketAddress& /*address*/) const override {
+    return false;
+  }
+};
+
+class MockQuicConnectionHelper : public QuicConnectionHelperInterface {
+ public:
+  MockQuicConnectionHelper();
+  MockQuicConnectionHelper(const MockQuicConnectionHelper&) = delete;
+  MockQuicConnectionHelper& operator=(const MockQuicConnectionHelper&) = delete;
+  ~MockQuicConnectionHelper() override;
+  const QuicClock* GetClock() const override;
+  QuicRandom* GetRandomGenerator() override;
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
+  void AdvanceTime(QuicTime::Delta delta);
+
+ private:
+  MockClock clock_;
+  MockRandom random_generator_;
+  quiche::SimpleBufferAllocator buffer_allocator_;
+};
+
+class MockAlarmFactory : public QuicAlarmFactory {
+ public:
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override;
+
+  // No-op alarm implementation
+  class TestAlarm : public QuicAlarm {
+   public:
+    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+        : QuicAlarm(std::move(delegate)) {}
+
+    void SetImpl() override {}
+    void CancelImpl() override {}
+
+    using QuicAlarm::Fire;
+  };
+
+  void FireAlarm(QuicAlarm* alarm) {
+    reinterpret_cast<TestAlarm*>(alarm)->Fire();
+  }
+};
+
+class TestAlarmFactory : public QuicAlarmFactory {
+ public:
+  class TestAlarm : public QuicAlarm {
+   public:
+    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+        : QuicAlarm(std::move(delegate)) {}
+
+    void SetImpl() override {}
+    void CancelImpl() override {}
+    using QuicAlarm::Fire;
+  };
+
+  TestAlarmFactory() {}
+  TestAlarmFactory(const TestAlarmFactory&) = delete;
+  TestAlarmFactory& operator=(const TestAlarmFactory&) = delete;
+
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
+    return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+  }
+
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override {
+    return arena->New<TestAlarm>(std::move(delegate));
+  }
+};
+
+class MockQuicConnection : public QuicConnection {
+ public:
+  // Uses a ConnectionId of 42 and 127.0.0.1:123.
+  MockQuicConnection(MockQuicConnectionHelper* helper,
+                     MockAlarmFactory* alarm_factory, Perspective perspective);
+
+  // Uses a ConnectionId of 42.
+  MockQuicConnection(QuicSocketAddress address,
+                     MockQuicConnectionHelper* helper,
+                     MockAlarmFactory* alarm_factory, Perspective perspective);
+
+  // Uses 127.0.0.1:123.
+  MockQuicConnection(QuicConnectionId connection_id,
+                     MockQuicConnectionHelper* helper,
+                     MockAlarmFactory* alarm_factory, Perspective perspective);
+
+  // Uses a ConnectionId of 42, and 127.0.0.1:123.
+  MockQuicConnection(MockQuicConnectionHelper* helper,
+                     MockAlarmFactory* alarm_factory, Perspective perspective,
+                     const ParsedQuicVersionVector& supported_versions);
+
+  MockQuicConnection(QuicConnectionId connection_id, QuicSocketAddress address,
+                     MockQuicConnectionHelper* helper,
+                     MockAlarmFactory* alarm_factory, Perspective perspective,
+                     const ParsedQuicVersionVector& supported_versions);
+  MockQuicConnection(const MockQuicConnection&) = delete;
+  MockQuicConnection& operator=(const MockQuicConnection&) = delete;
+
+  ~MockQuicConnection() override;
+
+  // If the constructor that uses a MockQuicConnectionHelper has been used then
+  // this method
+  // will advance the time of the MockClock.
+  void AdvanceTime(QuicTime::Delta delta);
+
+  MOCK_METHOD(void, ProcessUdpPacket,
+              (const QuicSocketAddress& self_address,
+               const QuicSocketAddress& peer_address,
+               const QuicReceivedPacket& packet),
+              (override));
+  MOCK_METHOD(void, CloseConnection,
+              (QuicErrorCode error, const std::string& details,
+               ConnectionCloseBehavior connection_close_behavior),
+              (override));
+  MOCK_METHOD(void, CloseConnection,
+              (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
+               const std::string& details,
+               ConnectionCloseBehavior connection_close_behavior),
+              (override));
+  MOCK_METHOD(void, SendConnectionClosePacket,
+              (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
+               const std::string& details),
+              (override));
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool, SendConnectivityProbingPacket,
+              (QuicPacketWriter*, const QuicSocketAddress& peer_address),
+              (override));
+
+  MOCK_METHOD(void, OnSendConnectionState, (const CachedNetworkParameters&),
+              (override));
+  MOCK_METHOD(void, ResumeConnectionState,
+              (const CachedNetworkParameters&, bool), (override));
+  MOCK_METHOD(void, SetMaxPacingRate, (QuicBandwidth), (override));
+
+  MOCK_METHOD(void, OnStreamReset, (QuicStreamId, QuicRstStreamErrorCode),
+              (override));
+  MOCK_METHOD(bool, SendControlFrame, (const QuicFrame& frame), (override));
+  MOCK_METHOD(MessageStatus, SendMessage,
+              (QuicMessageId, absl::Span<quiche::QuicheMemSlice>, bool),
+              (override));
+  MOCK_METHOD(bool, SendPathChallenge,
+              (const QuicPathFrameBuffer&, const QuicSocketAddress&,
+               const QuicSocketAddress&, const QuicSocketAddress&,
+               QuicPacketWriter*),
+              (override));
+
+  MOCK_METHOD(void, OnError, (QuicFramer*), (override));
+  void QuicConnection_OnError(QuicFramer* framer) {
+    QuicConnection::OnError(framer);
+  }
+
+  void ReallyOnCanWrite() { QuicConnection::OnCanWrite(); }
+
+  void ReallyCloseConnection(
+      QuicErrorCode error, const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior) {
+    // Call the 4-param method directly instead of the 3-param method, so that
+    // it doesn't invoke the virtual 4-param method causing the mock 4-param
+    // method to trigger.
+    QuicConnection::CloseConnection(error, NO_IETF_QUIC_ERROR, details,
+                                    connection_close_behavior);
+  }
+
+  void ReallyCloseConnection4(
+      QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
+      const std::string& details,
+      ConnectionCloseBehavior connection_close_behavior) {
+    QuicConnection::CloseConnection(error, ietf_error, details,
+                                    connection_close_behavior);
+  }
+
+  void ReallySendConnectionClosePacket(QuicErrorCode error,
+                                       QuicIetfTransportErrorCodes ietf_error,
+                                       const std::string& details) {
+    QuicConnection::SendConnectionClosePacket(error, ietf_error, details);
+  }
+
+  void ReallyProcessUdpPacket(const QuicSocketAddress& self_address,
+                              const QuicSocketAddress& peer_address,
+                              const QuicReceivedPacket& packet) {
+    QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
+  }
+
+  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
+
+  bool ReallySendControlFrame(const QuicFrame& frame) {
+    return QuicConnection::SendControlFrame(frame);
+  }
+
+  bool ReallySendConnectivityProbingPacket(
+      QuicPacketWriter* probing_writer, const QuicSocketAddress& peer_address) {
+    return QuicConnection::SendConnectivityProbingPacket(probing_writer,
+                                                         peer_address);
+  }
+
+  bool ReallyOnPathResponseFrame(const QuicPathResponseFrame& frame) {
+    return QuicConnection::OnPathResponseFrame(frame);
+  }
+
+  MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame&),
+              (override));
+  MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
+              (override));
+  MOCK_METHOD(size_t, SendCryptoData,
+              (EncryptionLevel, size_t, QuicStreamOffset), (override));
+  size_t QuicConnection_SendCryptoData(EncryptionLevel level,
+                                       size_t write_length,
+                                       QuicStreamOffset offset) {
+    return QuicConnection::SendCryptoData(level, write_length, offset);
+  }
+};
+
+class PacketSavingConnection : public MockQuicConnection {
+ public:
+  PacketSavingConnection(MockQuicConnectionHelper* helper,
+                         MockAlarmFactory* alarm_factory,
+                         Perspective perspective);
+
+  PacketSavingConnection(MockQuicConnectionHelper* helper,
+                         MockAlarmFactory* alarm_factory,
+                         Perspective perspective,
+                         const ParsedQuicVersionVector& supported_versions);
+  PacketSavingConnection(const PacketSavingConnection&) = delete;
+  PacketSavingConnection& operator=(const PacketSavingConnection&) = delete;
+
+  ~PacketSavingConnection() override;
+
+  void SendOrQueuePacket(SerializedPacket packet) override;
+
+  MOCK_METHOD(void, OnPacketSent, (EncryptionLevel, TransmissionType));
+
+  std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_;
+  // Number of packets in encrypted_packets that has been delivered to the peer
+  // connection.
+  size_t number_of_packets_delivered_ = 0;
+  MockClock clock_;
+};
+
+class MockQuicSession : public QuicSession {
+ public:
+  // Takes ownership of |connection|.
+  MockQuicSession(QuicConnection* connection, bool create_mock_crypto_stream);
+
+  // Takes ownership of |connection|.
+  explicit MockQuicSession(QuicConnection* connection);
+  MockQuicSession(const MockQuicSession&) = delete;
+  MockQuicSession& operator=(const MockQuicSession&) = delete;
+  ~MockQuicSession() override;
+
+  QuicCryptoStream* GetMutableCryptoStream() override;
+  const QuicCryptoStream* GetCryptoStream() const override;
+  void SetCryptoStream(QuicCryptoStream* crypto_stream);
+
+  MOCK_METHOD(void, OnConnectionClosed,
+              (const QuicConnectionCloseFrame& frame,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(QuicStream*, CreateIncomingStream, (QuicStreamId id), (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
+              (override));
+  MOCK_METHOD(QuicConsumedData, WritevData,
+              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
+               StreamSendingState state, TransmissionType type,
+               EncryptionLevel level),
+              (override));
+  MOCK_METHOD(bool, WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type), (override));
+  MOCK_METHOD(void, MaybeSendRstStreamFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error,
+               QuicStreamOffset bytes_written),
+              (override));
+  MOCK_METHOD(void, MaybeSendStopSendingFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error), (override));
+
+  MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
+  MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
+  MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
+              (const std::vector<absl::string_view>&), (const, override));
+  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
+
+  using QuicSession::ActivateStream;
+
+  // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
+  // if set) has been consumed.
+  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
+                               QuicStreamOffset offset,
+                               StreamSendingState state, TransmissionType type,
+                               absl::optional<EncryptionLevel> level);
+
+  void ReallyMaybeSendRstStreamFrame(QuicStreamId id,
+                                     QuicRstStreamErrorCode error,
+                                     QuicStreamOffset bytes_written) {
+    QuicSession::MaybeSendRstStreamFrame(
+        id, QuicResetStreamError::FromInternal(error), bytes_written);
+  }
+
+ private:
+  std::unique_ptr<QuicCryptoStream> crypto_stream_;
+};
+
+class MockQuicCryptoStream : public QuicCryptoStream {
+ public:
+  explicit MockQuicCryptoStream(QuicSession* session);
+
+  ~MockQuicCryptoStream() override;
+
+  ssl_early_data_reason_t EarlyDataReason() const override;
+  bool encryption_established() const override;
+  bool one_rtt_keys_available() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+  CryptoMessageParser* crypto_message_parser() override;
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  std::string GetAddressToken(
+      const CachedNetworkParameters* /*cached_network_parameters*/)
+      const override {
+    return "";
+  }
+  bool ValidateAddressToken(absl::string_view /*token*/) const override {
+    return true;
+  }
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
+    return nullptr;
+  }
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters /*cached_network_params*/) override {}
+  void OnConnectionClosed(QuicErrorCode /*error*/,
+                          ConnectionCloseSource /*source*/) override {}
+  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
+  void SetServerApplicationStateForResumption(
+      std::unique_ptr<ApplicationState> /*application_state*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  bool ExportKeyingMaterial(absl::string_view /*label*/,
+                            absl::string_view /*context*/,
+                            size_t /*result_len*/,
+                            std::string* /*result*/) override {
+    return false;
+  }
+  SSL* GetSsl() const override { return nullptr; }
+
+ private:
+  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  CryptoFramer crypto_framer_;
+};
+
+class MockQuicSpdySession : public QuicSpdySession {
+ public:
+  // Takes ownership of |connection|.
+  explicit MockQuicSpdySession(QuicConnection* connection);
+  // Takes ownership of |connection|.
+  MockQuicSpdySession(QuicConnection* connection,
+                      bool create_mock_crypto_stream);
+  MockQuicSpdySession(const MockQuicSpdySession&) = delete;
+  MockQuicSpdySession& operator=(const MockQuicSpdySession&) = delete;
+  ~MockQuicSpdySession() override;
+
+  QuicCryptoStream* GetMutableCryptoStream() override;
+  const QuicCryptoStream* GetCryptoStream() const override;
+  void SetCryptoStream(QuicCryptoStream* crypto_stream);
+
+  void ReallyOnConnectionClosed(const QuicConnectionCloseFrame& frame,
+                                ConnectionCloseSource source) {
+    QuicSession::OnConnectionClosed(frame, source);
+  }
+
+  // From QuicSession.
+  MOCK_METHOD(void, OnConnectionClosed,
+              (const QuicConnectionCloseFrame& frame,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
+              (override));
+  MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
+  MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
+  MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
+  MOCK_METHOD(QuicConsumedData, WritevData,
+              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
+               StreamSendingState state, TransmissionType type,
+               EncryptionLevel level),
+              (override));
+  MOCK_METHOD(void, MaybeSendRstStreamFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error,
+               QuicStreamOffset bytes_written),
+              (override));
+  MOCK_METHOD(void, MaybeSendStopSendingFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error), (override));
+  MOCK_METHOD(void, SendWindowUpdate,
+              (QuicStreamId id, QuicStreamOffset byte_offset), (override));
+  MOCK_METHOD(void, SendBlocked, (QuicStreamId id), (override));
+  MOCK_METHOD(void, OnStreamHeadersPriority,
+              (QuicStreamId stream_id,
+               const spdy::SpdyStreamPrecedence& precedence),
+              (override));
+  MOCK_METHOD(void, OnStreamHeaderList,
+              (QuicStreamId stream_id, bool fin, size_t frame_len,
+               const QuicHeaderList& header_list),
+              (override));
+  MOCK_METHOD(void, OnPromiseHeaderList,
+              (QuicStreamId stream_id, QuicStreamId promised_stream_id,
+               size_t frame_len, const QuicHeaderList& header_list),
+              (override));
+  MOCK_METHOD(void, OnPriorityFrame,
+              (QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence),
+              (override));
+  MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
+
+  // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
+  // if set) has been consumed.
+  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
+                               QuicStreamOffset offset,
+                               StreamSendingState state, TransmissionType type,
+                               absl::optional<EncryptionLevel> level);
+
+  using QuicSession::ActivateStream;
+
+ private:
+  std::unique_ptr<QuicCryptoStream> crypto_stream_;
+};
+
+class MockHttp3DebugVisitor : public Http3DebugVisitor {
+ public:
+  MOCK_METHOD(void, OnControlStreamCreated, (QuicStreamId), (override));
+  MOCK_METHOD(void, OnQpackEncoderStreamCreated, (QuicStreamId), (override));
+  MOCK_METHOD(void, OnQpackDecoderStreamCreated, (QuicStreamId), (override));
+  MOCK_METHOD(void, OnPeerControlStreamCreated, (QuicStreamId), (override));
+  MOCK_METHOD(void, OnPeerQpackEncoderStreamCreated, (QuicStreamId),
+              (override));
+  MOCK_METHOD(void, OnPeerQpackDecoderStreamCreated, (QuicStreamId),
+              (override));
+
+  MOCK_METHOD(void, OnSettingsFrameReceivedViaAlps, (const SettingsFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnAcceptChFrameReceivedViaAlps, (const AcceptChFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnSettingsFrameReceived, (const SettingsFrame&),
+              (override));
+  MOCK_METHOD(void, OnGoAwayFrameReceived, (const GoAwayFrame&), (override));
+  MOCK_METHOD(void, OnMaxPushIdFrameReceived, (const MaxPushIdFrame&),
+              (override));
+  MOCK_METHOD(void, OnPriorityUpdateFrameReceived, (const PriorityUpdateFrame&),
+              (override));
+  MOCK_METHOD(void, OnAcceptChFrameReceived, (const AcceptChFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnDataFrameReceived, (QuicStreamId, QuicByteCount),
+              (override));
+  MOCK_METHOD(void, OnHeadersFrameReceived, (QuicStreamId, QuicByteCount),
+              (override));
+  MOCK_METHOD(void, OnHeadersDecoded, (QuicStreamId, QuicHeaderList),
+              (override));
+  MOCK_METHOD(void, OnUnknownFrameReceived,
+              (QuicStreamId, uint64_t, QuicByteCount), (override));
+
+  MOCK_METHOD(void, OnSettingsFrameSent, (const SettingsFrame&), (override));
+  MOCK_METHOD(void, OnGoAwayFrameSent, (QuicStreamId), (override));
+  MOCK_METHOD(void, OnPriorityUpdateFrameSent, (const PriorityUpdateFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnDataFrameSent, (QuicStreamId, QuicByteCount), (override));
+  MOCK_METHOD(void, OnHeadersFrameSent,
+              (QuicStreamId, const spdy::SpdyHeaderBlock&), (override));
+};
+
+class TestQuicSpdyServerSession : public QuicServerSessionBase {
+ public:
+  // Takes ownership of |connection|.
+  TestQuicSpdyServerSession(QuicConnection* connection,
+                            const QuicConfig& config,
+                            const ParsedQuicVersionVector& supported_versions,
+                            const QuicCryptoServerConfig* crypto_config,
+                            QuicCompressedCertsCache* compressed_certs_cache);
+  TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
+  TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
+      delete;
+  ~TestQuicSpdyServerSession() override;
+
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
+              (override));
+  MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
+              (const std::vector<absl::string_view>&), (const, override));
+  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override;
+
+  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
+
+  const QuicCryptoServerStreamBase* GetCryptoStream() const override;
+
+  MockQuicCryptoServerStreamHelper* helper() { return &helper_; }
+
+  QuicSSLConfig GetSSLConfig() const override {
+    QuicSSLConfig ssl_config = QuicServerSessionBase::GetSSLConfig();
+    if (early_data_enabled_.has_value()) {
+      ssl_config.early_data_enabled = *early_data_enabled_;
+    }
+    if (client_cert_mode_.has_value()) {
+      ssl_config.client_cert_mode = *client_cert_mode_;
+    }
+
+    return ssl_config;
+  }
+
+  void set_early_data_enabled(bool enabled) { early_data_enabled_ = enabled; }
+
+  void set_client_cert_mode(ClientCertMode mode) {
+    if (support_client_cert()) {
+      client_cert_mode_ = mode;
+    }
+  }
+
+ private:
+  MockQuicSessionVisitor visitor_;
+  MockQuicCryptoServerStreamHelper helper_;
+  // If not nullopt, override the early_data_enabled value from base class'
+  // ssl_config.
+  absl::optional<bool> early_data_enabled_;
+  // If not nullopt, override the client_cert_mode value from base class'
+  // ssl_config.
+  absl::optional<ClientCertMode> client_cert_mode_;
+};
+
+// A test implementation of QuicClientPushPromiseIndex::Delegate.
+class TestPushPromiseDelegate : public QuicClientPushPromiseIndex::Delegate {
+ public:
+  // |match| sets the validation result for checking whether designated header
+  // fields match for promise request and client request.
+  explicit TestPushPromiseDelegate(bool match);
+
+  bool CheckVary(const spdy::SpdyHeaderBlock& client_request,
+                 const spdy::SpdyHeaderBlock& promise_request,
+                 const spdy::SpdyHeaderBlock& promise_response) override;
+
+  void OnRendezvousResult(QuicSpdyStream* stream) override;
+
+  QuicSpdyStream* rendezvous_stream() { return rendezvous_stream_; }
+  bool rendezvous_fired() { return rendezvous_fired_; }
+
+ private:
+  bool match_;
+  bool rendezvous_fired_;
+  QuicSpdyStream* rendezvous_stream_;
+};
+
+class TestQuicSpdyClientSession : public QuicSpdyClientSessionBase {
+ public:
+  TestQuicSpdyClientSession(QuicConnection* connection,
+                            const QuicConfig& config,
+                            const ParsedQuicVersionVector& supported_versions,
+                            const QuicServerId& server_id,
+                            QuicCryptoClientConfig* crypto_config);
+  TestQuicSpdyClientSession(const TestQuicSpdyClientSession&) = delete;
+  TestQuicSpdyClientSession& operator=(const TestQuicSpdyClientSession&) =
+      delete;
+  ~TestQuicSpdyClientSession() override;
+
+  bool IsAuthorized(const std::string& authority) override;
+
+  // QuicSpdyClientSessionBase
+  MOCK_METHOD(void, OnProofValid,
+              (const QuicCryptoClientConfig::CachedState& cached), (override));
+  MOCK_METHOD(void, OnProofVerifyDetailsAvailable,
+              (const ProofVerifyDetails& verify_details), (override));
+
+  // TestQuicSpdyClientSession
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
+              (override));
+  MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
+  MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
+  MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
+  MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
+  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
+  MOCK_METHOD(void, OnConfigNegotiated, (), (override));
+
+  QuicCryptoClientStream* GetMutableCryptoStream() override;
+  const QuicCryptoClientStream* GetCryptoStream() const override;
+
+  // Override to save sent crypto handshake messages.
+  void OnCryptoHandshakeMessageSent(
+      const CryptoHandshakeMessage& message) override {
+    sent_crypto_handshake_messages_.push_back(message);
+  }
+
+  const std::vector<CryptoHandshakeMessage>& sent_crypto_handshake_messages()
+      const {
+    return sent_crypto_handshake_messages_;
+  }
+
+ private:
+  // Calls the parent class's OnConfigNegotiated method. Used to set the default
+  // mock behavior for OnConfigNegotiated.
+  void RealOnConfigNegotiated();
+
+  std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
+  QuicClientPushPromiseIndex push_promise_index_;
+  std::vector<CryptoHandshakeMessage> sent_crypto_handshake_messages_;
+};
+
+class MockPacketWriter : public QuicPacketWriter {
+ public:
+  MockPacketWriter();
+  MockPacketWriter(const MockPacketWriter&) = delete;
+  MockPacketWriter& operator=(const MockPacketWriter&) = delete;
+  ~MockPacketWriter() override;
+
+  MOCK_METHOD(WriteResult, WritePacket,
+              (const char*, size_t buf_len, const QuicIpAddress& self_address,
+               const QuicSocketAddress& peer_address, PerPacketOptions*),
+              (override));
+  MOCK_METHOD(bool, IsWriteBlocked, (), (const, override));
+  MOCK_METHOD(void, SetWritable, (), (override));
+  MOCK_METHOD(absl::optional<int>, MessageTooBigErrorCode, (),
+              (const, override));
+  MOCK_METHOD(QuicByteCount, GetMaxPacketSize,
+              (const QuicSocketAddress& peer_address), (const, override));
+  MOCK_METHOD(bool, SupportsReleaseTime, (), (const, override));
+  MOCK_METHOD(bool, IsBatchMode, (), (const, override));
+  MOCK_METHOD(QuicPacketBuffer, GetNextWriteLocation,
+              (const QuicIpAddress& self_address,
+               const QuicSocketAddress& peer_address),
+              (override));
+  MOCK_METHOD(WriteResult, Flush, (), (override));
+};
+
+class MockSendAlgorithm : public SendAlgorithmInterface {
+ public:
+  MockSendAlgorithm();
+  MockSendAlgorithm(const MockSendAlgorithm&) = delete;
+  MockSendAlgorithm& operator=(const MockSendAlgorithm&) = delete;
+  ~MockSendAlgorithm() override;
+
+  MOCK_METHOD(void, SetFromConfig,
+              (const QuicConfig& config, Perspective perspective), (override));
+  MOCK_METHOD(void, ApplyConnectionOptions,
+              (const QuicTagVector& connection_options), (override));
+  MOCK_METHOD(void, SetInitialCongestionWindowInPackets,
+              (QuicPacketCount packets), (override));
+  MOCK_METHOD(void, OnCongestionEvent,
+              (bool rtt_updated, QuicByteCount bytes_in_flight,
+               QuicTime event_time, const AckedPacketVector& acked_packets,
+               const LostPacketVector& lost_packets),
+              (override));
+  MOCK_METHOD(void, OnPacketSent,
+              (QuicTime, QuicByteCount, QuicPacketNumber, QuicByteCount,
+               HasRetransmittableData),
+              (override));
+  MOCK_METHOD(void, OnPacketNeutered, (QuicPacketNumber), (override));
+  MOCK_METHOD(void, OnRetransmissionTimeout, (bool), (override));
+  MOCK_METHOD(void, OnConnectionMigration, (), (override));
+  MOCK_METHOD(bool, CanSend, (QuicByteCount), (override));
+  MOCK_METHOD(QuicBandwidth, PacingRate, (QuicByteCount), (const, override));
+  MOCK_METHOD(QuicBandwidth, BandwidthEstimate, (), (const, override));
+  MOCK_METHOD(bool, HasGoodBandwidthEstimateForResumption, (),
+              (const, override));
+  MOCK_METHOD(QuicByteCount, GetCongestionWindow, (), (const, override));
+  MOCK_METHOD(std::string, GetDebugState, (), (const, override));
+  MOCK_METHOD(bool, InSlowStart, (), (const, override));
+  MOCK_METHOD(bool, InRecovery, (), (const, override));
+  MOCK_METHOD(bool, ShouldSendProbingPacket, (), (const, override));
+  MOCK_METHOD(QuicByteCount, GetSlowStartThreshold, (), (const, override));
+  MOCK_METHOD(CongestionControlType, GetCongestionControlType, (),
+              (const, override));
+  MOCK_METHOD(void, AdjustNetworkParameters, (const NetworkParams&),
+              (override));
+  MOCK_METHOD(void, OnApplicationLimited, (QuicByteCount), (override));
+  MOCK_METHOD(void, PopulateConnectionStats, (QuicConnectionStats*),
+              (const, override));
+};
+
+class MockLossAlgorithm : public LossDetectionInterface {
+ public:
+  MockLossAlgorithm();
+  MockLossAlgorithm(const MockLossAlgorithm&) = delete;
+  MockLossAlgorithm& operator=(const MockLossAlgorithm&) = delete;
+  ~MockLossAlgorithm() override;
+
+  MOCK_METHOD(void, SetFromConfig,
+              (const QuicConfig& config, Perspective perspective), (override));
+
+  MOCK_METHOD(DetectionStats, DetectLosses,
+              (const QuicUnackedPacketMap& unacked_packets, QuicTime time,
+               const RttStats& rtt_stats,
+               QuicPacketNumber largest_recently_acked,
+               const AckedPacketVector& packets_acked, LostPacketVector*),
+              (override));
+  MOCK_METHOD(QuicTime, GetLossTimeout, (), (const, override));
+  MOCK_METHOD(void, SpuriousLossDetected,
+              (const QuicUnackedPacketMap&, const RttStats&, QuicTime,
+               QuicPacketNumber, QuicPacketNumber),
+              (override));
+
+  MOCK_METHOD(void, OnConfigNegotiated, (), (override));
+  MOCK_METHOD(void, OnMinRttAvailable, (), (override));
+  MOCK_METHOD(void, OnUserAgentIdKnown, (), (override));
+  MOCK_METHOD(void, OnConnectionClosed, (), (override));
+  MOCK_METHOD(void, OnReorderingDetected, (), (override));
+};
+
+class MockAckListener : public QuicAckListenerInterface {
+ public:
+  MockAckListener();
+  MockAckListener(const MockAckListener&) = delete;
+  MockAckListener& operator=(const MockAckListener&) = delete;
+
+  MOCK_METHOD(void, OnPacketAcked,
+              (int acked_bytes, QuicTime::Delta ack_delay_time), (override));
+
+  MOCK_METHOD(void, OnPacketRetransmitted, (int retransmitted_bytes),
+              (override));
+
+ protected:
+  // Object is ref counted.
+  ~MockAckListener() override;
+};
+
+class MockNetworkChangeVisitor
+    : public QuicSentPacketManager::NetworkChangeVisitor {
+ public:
+  MockNetworkChangeVisitor();
+  MockNetworkChangeVisitor(const MockNetworkChangeVisitor&) = delete;
+  MockNetworkChangeVisitor& operator=(const MockNetworkChangeVisitor&) = delete;
+  ~MockNetworkChangeVisitor() override;
+
+  MOCK_METHOD(void, OnCongestionChange, (), (override));
+  MOCK_METHOD(void, OnPathMtuIncreased, (QuicPacketLength), (override));
+};
+
+class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
+ public:
+  MockQuicConnectionDebugVisitor();
+  ~MockQuicConnectionDebugVisitor() override;
+
+  MOCK_METHOD(void, OnPacketSent,
+              (QuicPacketNumber, QuicPacketLength, bool, TransmissionType,
+               EncryptionLevel, const QuicFrames&, const QuicFrames&, QuicTime),
+              (override));
+
+  MOCK_METHOD(void, OnCoalescedPacketSent, (const QuicCoalescedPacket&, size_t),
+              (override));
+
+  MOCK_METHOD(void, OnPingSent, (), (override));
+
+  MOCK_METHOD(void, OnPacketReceived,
+              (const QuicSocketAddress&, const QuicSocketAddress&,
+               const QuicEncryptedPacket&),
+              (override));
+
+  MOCK_METHOD(void, OnIncorrectConnectionId, (QuicConnectionId), (override));
+
+  MOCK_METHOD(void, OnProtocolVersionMismatch, (ParsedQuicVersion), (override));
+
+  MOCK_METHOD(void, OnPacketHeader,
+              (const QuicPacketHeader& header, QuicTime receive_time,
+               EncryptionLevel level),
+              (override));
+
+  MOCK_METHOD(void, OnSuccessfulVersionNegotiation, (const ParsedQuicVersion&),
+              (override));
+
+  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame&), (override));
+
+  MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame&), (override));
+
+  MOCK_METHOD(void, OnStopWaitingFrame, (const QuicStopWaitingFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnRstStreamFrame, (const QuicRstStreamFrame&), (override));
+
+  MOCK_METHOD(void, OnConnectionCloseFrame, (const QuicConnectionCloseFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame&), (override));
+
+  MOCK_METHOD(void, OnNewConnectionIdFrame, (const QuicNewConnectionIdFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnRetireConnectionIdFrame,
+              (const QuicRetireConnectionIdFrame&), (override));
+
+  MOCK_METHOD(void, OnNewTokenFrame, (const QuicNewTokenFrame&), (override));
+
+  MOCK_METHOD(void, OnMessageFrame, (const QuicMessageFrame&), (override));
+
+  MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnPathChallengeFrame, (const QuicPathChallengeFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnPathResponseFrame, (const QuicPathResponseFrame&),
+              (override));
+
+  MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket&),
+              (override));
+
+  MOCK_METHOD(void, OnVersionNegotiationPacket,
+              (const QuicVersionNegotiationPacket&), (override));
+
+  MOCK_METHOD(void, OnTransportParametersSent, (const TransportParameters&),
+              (override));
+
+  MOCK_METHOD(void, OnTransportParametersReceived, (const TransportParameters&),
+              (override));
+
+  MOCK_METHOD(void, OnZeroRttRejected, (int), (override));
+  MOCK_METHOD(void, OnZeroRttPacketAcked, (), (override));
+};
+
+class MockReceivedPacketManager : public QuicReceivedPacketManager {
+ public:
+  explicit MockReceivedPacketManager(QuicConnectionStats* stats);
+  ~MockReceivedPacketManager() override;
+
+  MOCK_METHOD(void, RecordPacketReceived,
+              (const QuicPacketHeader& header, QuicTime receipt_time),
+              (override));
+  MOCK_METHOD(bool, IsMissing, (QuicPacketNumber packet_number), (override));
+  MOCK_METHOD(bool, IsAwaitingPacket, (QuicPacketNumber packet_number),
+              (const, override));
+  MOCK_METHOD(bool, HasNewMissingPackets, (), (const, override));
+  MOCK_METHOD(bool, ack_frame_updated, (), (const, override));
+};
+
+class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
+ public:
+  MockPacketCreatorDelegate();
+  MockPacketCreatorDelegate(const MockPacketCreatorDelegate&) = delete;
+  MockPacketCreatorDelegate& operator=(const MockPacketCreatorDelegate&) =
+      delete;
+  ~MockPacketCreatorDelegate() override;
+
+  MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
+  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
+  MOCK_METHOD(void, OnUnrecoverableError, (QuicErrorCode, const std::string&),
+              (override));
+  MOCK_METHOD(bool, ShouldGeneratePacket,
+              (HasRetransmittableData retransmittable, IsHandshake handshake),
+              (override));
+  MOCK_METHOD(const QuicFrames, MaybeBundleAckOpportunistically, (),
+              (override));
+  MOCK_METHOD(SerializedPacketFate, GetSerializedPacketFate,
+              (bool, EncryptionLevel), (override));
+};
+
+class MockSessionNotifier : public SessionNotifierInterface {
+ public:
+  MockSessionNotifier();
+  ~MockSessionNotifier() override;
+
+  MOCK_METHOD(bool, OnFrameAcked, (const QuicFrame&, QuicTime::Delta, QuicTime),
+              (override));
+  MOCK_METHOD(void, OnStreamFrameRetransmitted, (const QuicStreamFrame&),
+              (override));
+  MOCK_METHOD(void, OnFrameLost, (const QuicFrame&), (override));
+  MOCK_METHOD(bool, RetransmitFrames,
+              (const QuicFrames&, TransmissionType type), (override));
+  MOCK_METHOD(bool, IsFrameOutstanding, (const QuicFrame&), (const, override));
+  MOCK_METHOD(bool, HasUnackedCryptoData, (), (const, override));
+  MOCK_METHOD(bool, HasUnackedStreamData, (), (const, override));
+};
+
+class MockQuicPathValidationContext : public QuicPathValidationContext {
+ public:
+  MockQuicPathValidationContext(const QuicSocketAddress& self_address,
+                                const QuicSocketAddress& peer_address,
+                                const QuicSocketAddress& effective_peer_address,
+                                QuicPacketWriter* writer)
+      : QuicPathValidationContext(self_address, peer_address,
+                                  effective_peer_address),
+        writer_(writer) {}
+  QuicPacketWriter* WriterToUse() override { return writer_; }
+
+ private:
+  QuicPacketWriter* writer_;
+};
+
+class MockQuicPathValidationResultDelegate
+    : public QuicPathValidator::ResultDelegate {
+ public:
+  MOCK_METHOD(void, OnPathValidationSuccess,
+              (std::unique_ptr<QuicPathValidationContext>), (override));
+
+  MOCK_METHOD(void, OnPathValidationFailure,
+              (std::unique_ptr<QuicPathValidationContext>), (override));
+};
+
+class QuicCryptoClientStreamPeer {
+ public:
+  QuicCryptoClientStreamPeer() = delete;
+
+  static QuicCryptoClientStream::HandshakerInterface* GetHandshaker(
+      QuicCryptoClientStream* stream);
+};
+
+// Creates a client session for testing.
+//
+// server_id: The server id associated with this stream.
+// connection_start_time: The time to set for the connection clock.
+//   Needed for strike-register nonce verification.  The client
+//   connection_start_time should be synchronized witht the server
+//   start time, otherwise nonce verification will fail.
+// supported_versions: Set of QUIC versions this client supports.
+// helper: Pointer to the MockQuicConnectionHelper to use for the session.
+// crypto_client_config: Pointer to the crypto client config.
+// client_connection: Pointer reference for newly created
+//   connection.  This object will be owned by the
+//   client_session.
+// client_session: Pointer reference for the newly created client
+//   session.  The new object will be owned by the caller.
+void CreateClientSessionForTest(
+    QuicServerId server_id, QuicTime::Delta connection_start_time,
+    const ParsedQuicVersionVector& supported_versions,
+    MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
+    QuicCryptoClientConfig* crypto_client_config,
+    PacketSavingConnection** client_connection,
+    TestQuicSpdyClientSession** client_session);
+
+// Creates a server session for testing.
+//
+// server_id: The server id associated with this stream.
+// connection_start_time: The time to set for the connection clock.
+//   Needed for strike-register nonce verification.  The server
+//   connection_start_time should be synchronized witht the client
+//   start time, otherwise nonce verification will fail.
+// supported_versions: Set of QUIC versions this server supports.
+// helper: Pointer to the MockQuicConnectionHelper to use for the session.
+// server_crypto_config: Pointer to the crypto server config.
+// server_connection: Pointer reference for newly created
+//   connection.  This object will be owned by the
+//   server_session.
+// server_session: Pointer reference for the newly created server
+//   session.  The new object will be owned by the caller.
+void CreateServerSessionForTest(
+    QuicServerId server_id, QuicTime::Delta connection_start_time,
+    ParsedQuicVersionVector supported_versions,
+    MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
+    QuicCryptoServerConfig* server_crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    PacketSavingConnection** server_connection,
+    TestQuicSpdyServerSession** server_session);
+
+// Verifies that the relative error of |actual| with respect to |expected| is
+// no more than |margin|.
+// Please use EXPECT_APPROX_EQ, a wrapper around this function, for better error
+// report.
+template <typename T>
+void ExpectApproxEq(T expected, T actual, float relative_margin) {
+  // If |relative_margin| > 1 and T is an unsigned type, the comparison will
+  // underflow.
+  ASSERT_LE(relative_margin, 1);
+  ASSERT_GE(relative_margin, 0);
+
+  T absolute_margin = expected * relative_margin;
+
+  EXPECT_GE(expected + absolute_margin, actual) << "actual value too big";
+  EXPECT_LE(expected - absolute_margin, actual) << "actual value too small";
+}
+
+#define EXPECT_APPROX_EQ(expected, actual, relative_margin)                    \
+  do {                                                                         \
+    SCOPED_TRACE(testing::Message() << "relative_margin:" << relative_margin); \
+    quic::test::ExpectApproxEq(expected, actual, relative_margin);             \
+  } while (0)
+
+template <typename T>
+QuicHeaderList AsHeaderList(const T& container) {
+  QuicHeaderList l;
+  l.OnHeaderBlockStart();
+  size_t total_size = 0;
+  for (auto p : container) {
+    total_size += p.first.size() + p.second.size();
+    l.OnHeader(p.first, p.second);
+  }
+  l.OnHeaderBlockEnd(total_size, total_size);
+  return l;
+}
+
+// Helper functions for stream ids, to allow test logic to abstract over the
+// HTTP stream numbering scheme (i.e. whether one or two QUIC streams are used
+// per HTTP transaction).
+QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
+    QuicTransportVersion version, int n);
+QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
+    QuicTransportVersion version, int n);
+QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
+    QuicTransportVersion version, int n);
+QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
+    QuicTransportVersion version, int n);
+
+StreamType DetermineStreamType(QuicStreamId id, ParsedQuicVersion version,
+                               Perspective perspective, bool is_incoming,
+                               StreamType default_type);
+
+// Creates a MemSlice using a singleton trivial buffer allocator.  Performs a
+// copy.
+quiche::QuicheMemSlice MemSliceFromString(absl::string_view data);
+
+// Used to compare ReceivedPacketInfo.
+MATCHER_P(ReceivedPacketInfoEquals, info, "") {
+  return info.ToString() == arg.ToString();
+}
+
+MATCHER_P(ReceivedPacketInfoConnectionIdEquals, destination_connection_id, "") {
+  return arg.destination_connection_id == destination_connection_id;
+}
+
+MATCHER_P2(InRange, min, max, "") { return arg >= min && arg <= max; }
+
+// A GMock matcher that prints expected and actual QuicErrorCode strings
+// upon failure.  Example usage:
+// EXPECT_THAT(stream_->connection_error(), IsError(QUIC_INTERNAL_ERROR));
+MATCHER_P(IsError, expected,
+          absl::StrCat(negation ? "isn't equal to " : "is equal to ",
+                       QuicErrorCodeToString(expected))) {
+  *result_listener << QuicErrorCodeToString(static_cast<QuicErrorCode>(arg));
+  return arg == expected;
+}
+
+// Shorthand for IsError(QUIC_NO_ERROR).
+// Example usage: EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
+MATCHER(IsQuicNoError,
+        absl::StrCat(negation ? "isn't equal to " : "is equal to ",
+                     QuicErrorCodeToString(QUIC_NO_ERROR))) {
+  *result_listener << QuicErrorCodeToString(arg);
+  return arg == QUIC_NO_ERROR;
+}
+
+// A GMock matcher that prints expected and actual QuicRstStreamErrorCode
+// strings upon failure.  Example usage:
+// EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_INTERNAL_ERROR));
+MATCHER_P(IsStreamError, expected,
+          absl::StrCat(negation ? "isn't equal to " : "is equal to ",
+                       QuicRstStreamErrorCodeToString(expected))) {
+  *result_listener << QuicRstStreamErrorCodeToString(arg);
+  return arg == expected;
+}
+
+// Shorthand for IsStreamError(QUIC_STREAM_NO_ERROR).  Example usage:
+// EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
+MATCHER(IsQuicStreamNoError,
+        absl::StrCat(negation ? "isn't equal to " : "is equal to ",
+                     QuicRstStreamErrorCodeToString(QUIC_STREAM_NO_ERROR))) {
+  *result_listener << QuicRstStreamErrorCodeToString(arg);
+  return arg == QUIC_STREAM_NO_ERROR;
+}
+
+// TaggingEncrypter appends kTagSize bytes of |tag| to the end of each message.
+class TaggingEncrypter : public QuicEncrypter {
+ public:
+  explicit TaggingEncrypter(uint8_t tag) : tag_(tag) {}
+  TaggingEncrypter(const TaggingEncrypter&) = delete;
+  TaggingEncrypter& operator=(const TaggingEncrypter&) = delete;
+
+  ~TaggingEncrypter() override {}
+
+  // QuicEncrypter interface.
+  bool SetKey(absl::string_view /*key*/) override { return true; }
+
+  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
+    return true;
+  }
+
+  bool SetIV(absl::string_view /*iv*/) override { return true; }
+
+  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
+    return true;
+  }
+
+  bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
+                     absl::string_view plaintext, char* output,
+                     size_t* output_length, size_t max_output_length) override;
+
+  std::string GenerateHeaderProtectionMask(
+      absl::string_view /*sample*/) override {
+    return std::string(5, 0);
+  }
+
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetIVSize() const override { return 0; }
+
+  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
+    return ciphertext_size - kTagSize;
+  }
+
+  size_t GetCiphertextSize(size_t plaintext_size) const override {
+    return plaintext_size + kTagSize;
+  }
+
+  QuicPacketCount GetConfidentialityLimit() const override {
+    return std::numeric_limits<QuicPacketCount>::max();
+  }
+
+  absl::string_view GetKey() const override { return absl::string_view(); }
+
+  absl::string_view GetNoncePrefix() const override {
+    return absl::string_view();
+  }
+
+ private:
+  enum {
+    kTagSize = 12,
+  };
+
+  const uint8_t tag_;
+};
+
+// TaggingDecrypter ensures that the final kTagSize bytes of the message all
+// have the same value and then removes them.
+class TaggingDecrypter : public QuicDecrypter {
+ public:
+  ~TaggingDecrypter() override {}
+
+  // QuicDecrypter interface
+  bool SetKey(absl::string_view /*key*/) override { return true; }
+
+  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
+    return true;
+  }
+
+  bool SetIV(absl::string_view /*iv*/) override { return true; }
+
+  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
+    return true;
+  }
+
+  bool SetPreliminaryKey(absl::string_view /*key*/) override {
+    QUIC_BUG(quic_bug_10230_1) << "should not be called";
+    return false;
+  }
+
+  bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
+    return true;
+  }
+
+  bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
+                     absl::string_view ciphertext, char* output,
+                     size_t* output_length, size_t max_output_length) override;
+
+  std::string GenerateHeaderProtectionMask(
+      QuicDataReader* /*sample_reader*/) override {
+    return std::string(5, 0);
+  }
+
+  size_t GetKeySize() const override { return 0; }
+  size_t GetNoncePrefixSize() const override { return 0; }
+  size_t GetIVSize() const override { return 0; }
+  absl::string_view GetKey() const override { return absl::string_view(); }
+  absl::string_view GetNoncePrefix() const override {
+    return absl::string_view();
+  }
+  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
+  uint32_t cipher_id() const override { return 0xFFFFFFF0; }
+  QuicPacketCount GetIntegrityLimit() const override {
+    return std::numeric_limits<QuicPacketCount>::max();
+  }
+
+ protected:
+  virtual uint8_t GetTag(absl::string_view ciphertext) {
+    return ciphertext.data()[ciphertext.size() - 1];
+  }
+
+ private:
+  enum {
+    kTagSize = 12,
+  };
+
+  bool CheckTag(absl::string_view ciphertext, uint8_t tag);
+};
+
+// StringTaggingDecrypter ensures that the final kTagSize bytes of the message
+// match the expected value.
+class StrictTaggingDecrypter : public TaggingDecrypter {
+ public:
+  explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {}
+  ~StrictTaggingDecrypter() override {}
+
+  // TaggingQuicDecrypter
+  uint8_t GetTag(absl::string_view /*ciphertext*/) override { return tag_; }
+
+  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
+  uint32_t cipher_id() const override { return 0xFFFFFFF1; }
+
+ private:
+  const uint8_t tag_;
+};
+
+class TestPacketWriter : public QuicPacketWriter {
+  struct PacketBuffer {
+    ABSL_CACHELINE_ALIGNED char buffer[1500];
+    bool in_use = false;
+  };
+
+ public:
+  TestPacketWriter(ParsedQuicVersion version, MockClock* clock,
+                   Perspective perspective);
+
+  TestPacketWriter(const TestPacketWriter&) = delete;
+  TestPacketWriter& operator=(const TestPacketWriter&) = delete;
+
+  ~TestPacketWriter() override;
+
+  // QuicPacketWriter interface
+  WriteResult WritePacket(const char* buffer, size_t buf_len,
+                          const QuicIpAddress& self_address,
+                          const QuicSocketAddress& peer_address,
+                          PerPacketOptions* options) override;
+
+  bool ShouldWriteFail() { return write_should_fail_; }
+
+  bool IsWriteBlocked() const override { return write_blocked_; }
+
+  absl::optional<int> MessageTooBigErrorCode() const override { return 0x1234; }
+
+  void SetWriteBlocked() { write_blocked_ = true; }
+
+  void SetWritable() override { write_blocked_ = false; }
+
+  void SetShouldWriteFail() { write_should_fail_ = true; }
+
+  void SetWriteError(int error_code) { write_error_code_ = error_code; }
+
+  QuicByteCount GetMaxPacketSize(
+      const QuicSocketAddress& /*peer_address*/) const override {
+    return max_packet_size_;
+  }
+
+  bool SupportsReleaseTime() const override { return supports_release_time_; }
+
+  bool IsBatchMode() const override { return is_batch_mode_; }
+
+  QuicPacketBuffer GetNextWriteLocation(
+      const QuicIpAddress& /*self_address*/,
+      const QuicSocketAddress& /*peer_address*/) override;
+
+  WriteResult Flush() override;
+
+  void BlockOnNextFlush() { block_on_next_flush_ = true; }
+
+  void BlockOnNextWrite() { block_on_next_write_ = true; }
+
+  void SimulateNextPacketTooLarge() { next_packet_too_large_ = true; }
+
+  void AlwaysGetPacketTooLarge() { always_get_packet_too_large_ = true; }
+
+  // Sets the amount of time that the writer should before the actual write.
+  void SetWritePauseTimeDelta(QuicTime::Delta delta) {
+    write_pause_time_delta_ = delta;
+  }
+
+  void SetBatchMode(bool new_value) { is_batch_mode_ = new_value; }
+
+  const QuicPacketHeader& header() { return framer_.header(); }
+
+  size_t frame_count() const { return framer_.num_frames(); }
+
+  const std::vector<QuicAckFrame>& ack_frames() const {
+    return framer_.ack_frames();
+  }
+
+  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
+    return framer_.stop_waiting_frames();
+  }
+
+  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
+    return framer_.connection_close_frames();
+  }
+
+  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
+    return framer_.rst_stream_frames();
+  }
+
+  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
+    return framer_.stream_frames();
+  }
+
+  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
+    return framer_.crypto_frames();
+  }
+
+  const std::vector<QuicPingFrame>& ping_frames() const {
+    return framer_.ping_frames();
+  }
+
+  const std::vector<QuicMessageFrame>& message_frames() const {
+    return framer_.message_frames();
+  }
+
+  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
+    return framer_.window_update_frames();
+  }
+
+  const std::vector<QuicPaddingFrame>& padding_frames() const {
+    return framer_.padding_frames();
+  }
+
+  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
+    return framer_.path_challenge_frames();
+  }
+
+  const std::vector<QuicPathResponseFrame>& path_response_frames() const {
+    return framer_.path_response_frames();
+  }
+
+  const QuicEncryptedPacket* coalesced_packet() const {
+    return framer_.coalesced_packet();
+  }
+
+  size_t last_packet_size() { return last_packet_size_; }
+
+  const QuicPacketHeader& last_packet_header() const {
+    return last_packet_header_;
+  }
+
+  const QuicVersionNegotiationPacket* version_negotiation_packet() {
+    return framer_.version_negotiation_packet();
+  }
+
+  void set_is_write_blocked_data_buffered(bool buffered) {
+    is_write_blocked_data_buffered_ = buffered;
+  }
+
+  void set_perspective(Perspective perspective) {
+    // We invert perspective here, because the framer needs to parse packets
+    // we send.
+    QuicFramerPeer::SetPerspective(framer_.framer(),
+                                   QuicUtils::InvertPerspective(perspective));
+    framer_.framer()->SetInitialObfuscators(TestConnectionId());
+  }
+
+  // final_bytes_of_last_packet_ returns the last four bytes of the previous
+  // packet as a little-endian, uint32_t. This is intended to be used with a
+  // TaggingEncrypter so that tests can determine which encrypter was used for
+  // a given packet.
+  uint32_t final_bytes_of_last_packet() { return final_bytes_of_last_packet_; }
+
+  // Returns the final bytes of the second to last packet.
+  uint32_t final_bytes_of_previous_packet() {
+    return final_bytes_of_previous_packet_;
+  }
+
+  void use_tagging_decrypter() { use_tagging_decrypter_ = true; }
+
+  uint32_t packets_write_attempts() const { return packets_write_attempts_; }
+
+  uint32_t flush_attempts() const { return flush_attempts_; }
+
+  uint32_t connection_close_packets() const {
+    return connection_close_packets_;
+  }
+
+  void Reset() { framer_.Reset(); }
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    framer_.SetSupportedVersions(versions);
+  }
+
+  void set_max_packet_size(QuicByteCount max_packet_size) {
+    max_packet_size_ = max_packet_size;
+  }
+
+  void set_supports_release_time(bool supports_release_time) {
+    supports_release_time_ = supports_release_time;
+  }
+
+  SimpleQuicFramer* framer() { return &framer_; }
+
+  const QuicIpAddress& last_write_source_address() const {
+    return last_write_source_address_;
+  }
+
+  const QuicSocketAddress& last_write_peer_address() const {
+    return last_write_peer_address_;
+  }
+
+ private:
+  char* AllocPacketBuffer();
+
+  void FreePacketBuffer(const char* buffer);
+
+  ParsedQuicVersion version_;
+  SimpleQuicFramer framer_;
+  size_t last_packet_size_ = 0;
+  QuicPacketHeader last_packet_header_;
+  bool write_blocked_ = false;
+  bool write_should_fail_ = false;
+  bool block_on_next_flush_ = false;
+  bool block_on_next_write_ = false;
+  bool next_packet_too_large_ = false;
+  bool always_get_packet_too_large_ = false;
+  bool is_write_blocked_data_buffered_ = false;
+  bool is_batch_mode_ = false;
+  // Number of times Flush() was called.
+  uint32_t flush_attempts_ = 0;
+  // (Batch mode only) Number of bytes buffered in writer. It is used as the
+  // return value of a successful Flush().
+  uint32_t bytes_buffered_ = 0;
+  uint32_t final_bytes_of_last_packet_ = 0;
+  uint32_t final_bytes_of_previous_packet_ = 0;
+  bool use_tagging_decrypter_ = false;
+  uint32_t packets_write_attempts_ = 0;
+  uint32_t connection_close_packets_ = 0;
+  MockClock* clock_ = nullptr;
+  // If non-zero, the clock will pause during WritePacket for this amount of
+  // time.
+  QuicTime::Delta write_pause_time_delta_ = QuicTime::Delta::Zero();
+  QuicByteCount max_packet_size_ = kMaxOutgoingPacketSize;
+  bool supports_release_time_ = false;
+  // Used to verify writer-allocated packet buffers are properly released.
+  std::vector<PacketBuffer*> packet_buffer_pool_;
+  // Buffer address => Address of the owning PacketBuffer.
+  absl::flat_hash_map<char*, PacketBuffer*, absl::Hash<char*>>
+      packet_buffer_pool_index_;
+  // Indices in packet_buffer_pool_ that are not allocated.
+  std::list<PacketBuffer*> packet_buffer_free_list_;
+  // The soruce/peer address passed into WritePacket().
+  QuicIpAddress last_write_source_address_;
+  QuicSocketAddress last_write_peer_address_;
+  int write_error_code_{0};
+};
+
+// Parses a packet generated by
+// QuicFramer::WriteClientVersionNegotiationProbePacket.
+// |packet_bytes| must point to |packet_length| bytes in memory which represent
+// the packet. This method will fill in |destination_connection_id_bytes|
+// which must point to at least |*destination_connection_id_length_out| bytes in
+// memory. |*destination_connection_id_length_out| will contain the length of
+// the received destination connection ID, which on success will match the
+// contents of the destination connection ID passed in to
+// WriteClientVersionNegotiationProbePacket.
+bool ParseClientVersionNegotiationProbePacket(
+    const char* packet_bytes, size_t packet_length,
+    char* destination_connection_id_bytes,
+    uint8_t* destination_connection_id_length_out);
+
+// Writes an array of bytes that correspond to a QUIC version negotiation packet
+// that a QUIC server would send in response to a probe created by
+// QuicFramer::WriteClientVersionNegotiationProbePacket.
+// The bytes will be written to |packet_bytes|, which must point to
+// |*packet_length_out| bytes of memory. |*packet_length_out| will contain the
+// length of the created packet. |source_connection_id_bytes| will be sent as
+// the source connection ID, and must point to |source_connection_id_length|
+// bytes of memory.
+bool WriteServerVersionNegotiationProbeResponse(
+    char* packet_bytes, size_t* packet_length_out,
+    const char* source_connection_id_bytes,
+    uint8_t source_connection_id_length);
+
+// Implementation of Http3DatagramVisitor which saves all received datagrams.
+class SavingHttp3DatagramVisitor : public QuicSpdyStream::Http3DatagramVisitor {
+ public:
+  struct SavedHttp3Datagram {
+    QuicStreamId stream_id;
+    absl::optional<QuicDatagramContextId> context_id;
+    std::string payload;
+    bool operator==(const SavedHttp3Datagram& o) const {
+      return stream_id == o.stream_id && context_id == o.context_id &&
+             payload == o.payload;
+    }
+  };
+  const std::vector<SavedHttp3Datagram>& received_h3_datagrams() const {
+    return received_h3_datagrams_;
+  }
+
+  // Override from QuicSpdyStream::Http3DatagramVisitor.
+  void OnHttp3Datagram(QuicStreamId stream_id,
+                       absl::optional<QuicDatagramContextId> context_id,
+                       absl::string_view payload) override {
+    received_h3_datagrams_.push_back(
+        SavedHttp3Datagram{stream_id, context_id, std::string(payload)});
+  }
+
+ private:
+  std::vector<SavedHttp3Datagram> received_h3_datagrams_;
+};
+
+class MockHttp3DatagramRegistrationVisitor
+    : public QuicSpdyStream::Http3DatagramRegistrationVisitor {
+ public:
+  MOCK_METHOD(void, OnContextReceived,
+              (QuicStreamId stream_id,
+               absl::optional<QuicDatagramContextId> context_id,
+               DatagramFormatType format_type,
+               absl::string_view format_additional_data),
+              (override));
+
+  MOCK_METHOD(void, OnContextClosed,
+              (QuicStreamId stream_id,
+               absl::optional<QuicDatagramContextId> context_id,
+               ContextCloseCode close_code, absl::string_view close_details),
+              (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
diff --git a/quiche/quic/test_tools/quic_test_utils_test.cc b/quiche/quic/test_tools/quic_test_utils_test.cc
new file mode 100644
index 0000000..16ca977
--- /dev/null
+++ b/quiche/quic/test_tools/quic_test_utils_test.cc
@@ -0,0 +1,79 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicTestUtilsTest : public QuicTest {};
+
+TEST_F(QuicTestUtilsTest, ConnectionId) {
+  EXPECT_NE(EmptyQuicConnectionId(), TestConnectionId());
+  EXPECT_NE(EmptyQuicConnectionId(), TestConnectionId(1));
+  EXPECT_EQ(TestConnectionId(), TestConnectionId());
+  EXPECT_EQ(TestConnectionId(33), TestConnectionId(33));
+  EXPECT_NE(TestConnectionId(0xdead), TestConnectionId(0xbeef));
+  EXPECT_EQ(0x1337u, TestConnectionIdToUInt64(TestConnectionId(0x1337)));
+  EXPECT_NE(0xdeadu, TestConnectionIdToUInt64(TestConnectionId(0xbeef)));
+}
+
+TEST_F(QuicTestUtilsTest, BasicApproxEq) {
+  EXPECT_APPROX_EQ(10, 10, 1e-6f);
+  EXPECT_APPROX_EQ(1000, 1001, 0.01f);
+  EXPECT_NONFATAL_FAILURE(EXPECT_APPROX_EQ(1000, 1100, 0.01f), "");
+
+  EXPECT_APPROX_EQ(64, 31, 0.55f);
+  EXPECT_NONFATAL_FAILURE(EXPECT_APPROX_EQ(31, 64, 0.55f), "");
+}
+
+TEST_F(QuicTestUtilsTest, QuicTimeDelta) {
+  EXPECT_APPROX_EQ(QuicTime::Delta::FromMicroseconds(1000),
+                   QuicTime::Delta::FromMicroseconds(1003), 0.01f);
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_APPROX_EQ(QuicTime::Delta::FromMicroseconds(1000),
+                       QuicTime::Delta::FromMicroseconds(1200), 0.01f),
+      "");
+}
+
+TEST_F(QuicTestUtilsTest, QuicBandwidth) {
+  EXPECT_APPROX_EQ(QuicBandwidth::FromBytesPerSecond(1000),
+                   QuicBandwidth::FromBitsPerSecond(8005), 0.01f);
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_APPROX_EQ(QuicBandwidth::FromBytesPerSecond(1000),
+                       QuicBandwidth::FromBitsPerSecond(9005), 0.01f),
+      "");
+}
+
+// Ensure that SimpleRandom does not change its output for a fixed seed.
+TEST_F(QuicTestUtilsTest, SimpleRandomStability) {
+  SimpleRandom rng;
+  rng.set_seed(UINT64_C(0x1234567800010001));
+  EXPECT_EQ(UINT64_C(12589383305231984671), rng.RandUint64());
+  EXPECT_EQ(UINT64_C(17775425089941798664), rng.RandUint64());
+}
+
+// Ensure that the output of SimpleRandom does not depend on the size of the
+// read calls.
+TEST_F(QuicTestUtilsTest, SimpleRandomChunks) {
+  SimpleRandom rng;
+  std::string reference(16 * 1024, '\0');
+  rng.RandBytes(&reference[0], reference.size());
+
+  for (size_t chunk_size : {3, 4, 7, 4096}) {
+    rng.set_seed(0);
+    size_t chunks = reference.size() / chunk_size;
+    std::string buffer(chunks * chunk_size, '\0');
+    for (size_t i = 0; i < chunks; i++) {
+      rng.RandBytes(&buffer[i * chunk_size], chunk_size);
+    }
+    EXPECT_EQ(reference.substr(0, buffer.size()), buffer)
+        << "Failed for chunk_size = " << chunk_size;
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_time_wait_list_manager_peer.cc b/quiche/quic/test_tools/quic_time_wait_list_manager_peer.cc
new file mode 100644
index 0000000..5199282
--- /dev/null
+++ b/quiche/quic/test_tools/quic_time_wait_list_manager_peer.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_time_wait_list_manager_peer.h"
+
+namespace quic {
+namespace test {
+
+bool QuicTimeWaitListManagerPeer::ShouldSendResponse(
+    QuicTimeWaitListManager* manager,
+    int received_packet_count) {
+  return manager->ShouldSendResponse(received_packet_count);
+}
+
+QuicTime::Delta QuicTimeWaitListManagerPeer::time_wait_period(
+    QuicTimeWaitListManager* manager) {
+  return manager->time_wait_period_;
+}
+
+QuicAlarm* QuicTimeWaitListManagerPeer::expiration_alarm(
+    QuicTimeWaitListManager* manager) {
+  return manager->connection_id_clean_up_alarm_.get();
+}
+
+void QuicTimeWaitListManagerPeer::set_clock(QuicTimeWaitListManager* manager,
+                                            const QuicClock* clock) {
+  manager->clock_ = clock;
+}
+
+// static
+bool QuicTimeWaitListManagerPeer::SendOrQueuePacket(
+    QuicTimeWaitListManager* manager,
+    std::unique_ptr<QuicTimeWaitListManager::QueuedPacket> packet,
+    const QuicPerPacketContext* packet_context) {
+  return manager->SendOrQueuePacket(std::move(packet), packet_context);
+}
+
+// static
+size_t QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
+    QuicTimeWaitListManager* manager) {
+  return manager->pending_packets_queue_.size();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_time_wait_list_manager_peer.h b/quiche/quic/test_tools/quic_time_wait_list_manager_peer.h
new file mode 100644
index 0000000..a7aed47
--- /dev/null
+++ b/quiche/quic/test_tools/quic_time_wait_list_manager_peer.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
+
+#include "quiche/quic/core/quic_time_wait_list_manager.h"
+
+namespace quic {
+namespace test {
+
+class QuicTimeWaitListManagerPeer {
+ public:
+  static bool ShouldSendResponse(QuicTimeWaitListManager* manager,
+                                 int received_packet_count);
+
+  static QuicTime::Delta time_wait_period(QuicTimeWaitListManager* manager);
+
+  static QuicAlarm* expiration_alarm(QuicTimeWaitListManager* manager);
+
+  static void set_clock(QuicTimeWaitListManager* manager,
+                        const QuicClock* clock);
+
+  static bool SendOrQueuePacket(
+      QuicTimeWaitListManager* manager,
+      std::unique_ptr<QuicTimeWaitListManager::QueuedPacket> packet,
+      const QuicPerPacketContext* packet_context);
+
+  static size_t PendingPacketsQueueSize(QuicTimeWaitListManager* manager);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TIME_WAIT_LIST_MANAGER_PEER_H_
diff --git a/quiche/quic/test_tools/quic_transport_test_tools.h b/quiche/quic/test_tools/quic_transport_test_tools.h
new file mode 100644
index 0000000..08d87ef
--- /dev/null
+++ b/quiche/quic/test_tools/quic_transport_test_tools.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
+
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/quic_transport/quic_transport_server_session.h"
+
+namespace quic {
+namespace test {
+
+class MockClientVisitor : public WebTransportVisitor {
+ public:
+  MOCK_METHOD(void, OnSessionReady, (const spdy::SpdyHeaderBlock&), (override));
+  MOCK_METHOD(void, OnSessionClosed,
+              (WebTransportSessionError, const std::string&), (override));
+  MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override));
+  MOCK_METHOD(void, OnIncomingUnidirectionalStreamAvailable, (), (override));
+  MOCK_METHOD(void, OnDatagramReceived, (absl::string_view), (override));
+  MOCK_METHOD(void, OnCanCreateNewOutgoingBidirectionalStream, (), (override));
+  MOCK_METHOD(void, OnCanCreateNewOutgoingUnidirectionalStream, (), (override));
+};
+
+class MockServerVisitor : public QuicTransportServerSession::ServerVisitor {
+ public:
+  MOCK_METHOD(bool, CheckOrigin, (url::Origin), (override));
+  MOCK_METHOD(bool, ProcessPath, (const GURL&), (override));
+};
+
+class MockStreamVisitor : public WebTransportStreamVisitor {
+ public:
+  MOCK_METHOD(void, OnCanRead, (), (override));
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+
+  MOCK_METHOD(void, OnResetStreamReceived, (WebTransportStreamError error),
+              (override));
+  MOCK_METHOD(void, OnStopSendingReceived, (WebTransportStreamError error),
+              (override));
+  MOCK_METHOD(void, OnWriteSideInDataRecvdState, (), (override));
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
diff --git a/quiche/quic/test_tools/quic_unacked_packet_map_peer.cc b/quiche/quic/test_tools/quic_unacked_packet_map_peer.cc
new file mode 100644
index 0000000..d253cc2
--- /dev/null
+++ b/quiche/quic/test_tools/quic_unacked_packet_map_peer.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/quic_unacked_packet_map_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+const QuicStreamFrame& QuicUnackedPacketMapPeer::GetAggregatedStreamFrame(
+    const QuicUnackedPacketMap& unacked_packets) {
+  return unacked_packets.aggregated_stream_frame_;
+}
+
+// static
+void QuicUnackedPacketMapPeer::SetPerspective(
+    QuicUnackedPacketMap* unacked_packets,
+    Perspective perspective) {
+  *const_cast<Perspective*>(&unacked_packets->perspective_) = perspective;
+}
+
+// static
+size_t QuicUnackedPacketMapPeer::GetCapacity(
+    const QuicUnackedPacketMap& unacked_packets) {
+  return unacked_packets.unacked_packets_.capacity();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/quic_unacked_packet_map_peer.h b/quiche/quic/test_tools/quic_unacked_packet_map_peer.h
new file mode 100644
index 0000000..5525506
--- /dev/null
+++ b/quiche/quic/test_tools/quic_unacked_packet_map_peer.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
+
+#include "quiche/quic/core/quic_unacked_packet_map.h"
+
+namespace quic {
+namespace test {
+
+class QuicUnackedPacketMapPeer {
+ public:
+  static const QuicStreamFrame& GetAggregatedStreamFrame(
+      const QuicUnackedPacketMap& unacked_packets);
+
+  static void SetPerspective(QuicUnackedPacketMap* unacked_packets,
+                             Perspective perspective);
+
+  static size_t GetCapacity(const QuicUnackedPacketMap& unacked_packets);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_UNACKED_PACKET_MAP_PEER_H_
diff --git a/quiche/quic/test_tools/rtt_stats_peer.cc b/quiche/quic/test_tools/rtt_stats_peer.cc
new file mode 100644
index 0000000..8bf1f99
--- /dev/null
+++ b/quiche/quic/test_tools/rtt_stats_peer.cc
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/rtt_stats_peer.h"
+
+namespace quic {
+namespace test {
+
+// static
+void RttStatsPeer::SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms) {
+  rtt_stats->smoothed_rtt_ = rtt_ms;
+}
+
+// static
+void RttStatsPeer::SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms) {
+  rtt_stats->min_rtt_ = rtt_ms;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/rtt_stats_peer.h b/quiche/quic/test_tools/rtt_stats_peer.h
new file mode 100644
index 0000000..5e7f473
--- /dev/null
+++ b/quiche/quic/test_tools/rtt_stats_peer.h
@@ -0,0 +1,26 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
+#define QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
+
+#include "quiche/quic/core/congestion_control/rtt_stats.h"
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+namespace test {
+
+class RttStatsPeer {
+ public:
+  RttStatsPeer() = delete;
+
+  static void SetSmoothedRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms);
+
+  static void SetMinRtt(RttStats* rtt_stats, QuicTime::Delta rtt_ms);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_RTT_STATS_PEER_H_
diff --git a/quic/test_tools/send_algorithm_test_result.proto b/quiche/quic/test_tools/send_algorithm_test_result.proto
similarity index 100%
rename from quic/test_tools/send_algorithm_test_result.proto
rename to quiche/quic/test_tools/send_algorithm_test_result.proto
diff --git a/quiche/quic/test_tools/send_algorithm_test_utils.cc b/quiche/quic/test_tools/send_algorithm_test_utils.cc
new file mode 100644
index 0000000..2ca1791
--- /dev/null
+++ b/quiche/quic/test_tools/send_algorithm_test_utils.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/send_algorithm_test_utils.h"
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_output.h"
+
+namespace quic {
+namespace test {
+
+bool LoadSendAlgorithmTestResult(SendAlgorithmTestResult* result) {
+  std::string test_result_file_content;
+  if (!QuicLoadTestOutput(GetSendAlgorithmTestResultFilename(),
+                          &test_result_file_content)) {
+    return false;
+  }
+  return result->ParseFromString(test_result_file_content);
+}
+
+void RecordSendAlgorithmTestResult(uint64_t random_seed,
+                                   int64_t simulated_duration_micros) {
+  SendAlgorithmTestResult result;
+  result.set_test_name(GetFullSendAlgorithmTestName());
+  result.set_random_seed(random_seed);
+  result.set_simulated_duration_micros(simulated_duration_micros);
+
+  QuicSaveTestOutput(GetSendAlgorithmTestResultFilename(),
+                     result.SerializeAsString());
+}
+
+void CompareSendAlgorithmTestResult(int64_t actual_simulated_duration_micros) {
+  SendAlgorithmTestResult expected;
+  ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
+  QUIC_LOG(INFO) << "Loaded expected test result: "
+                 << expected.ShortDebugString();
+
+  EXPECT_GE(expected.simulated_duration_micros(),
+            actual_simulated_duration_micros);
+}
+
+std::string GetFullSendAlgorithmTestName() {
+  const auto* test_info =
+      ::testing::UnitTest::GetInstance()->current_test_info();
+  const std::string type_param =
+      test_info->type_param() ? test_info->type_param() : "";
+  const std::string value_param =
+      test_info->value_param() ? test_info->value_param() : "";
+  return absl::StrCat(test_info->test_suite_name(), ".", test_info->name(), "_",
+                      type_param, "_", value_param);
+}
+
+std::string GetSendAlgorithmTestResultFilename() {
+  return GetFullSendAlgorithmTestName() + ".test_result";
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/send_algorithm_test_utils.h b/quiche/quic/test_tools/send_algorithm_test_utils.h
new file mode 100644
index 0000000..9516b9a
--- /dev/null
+++ b/quiche/quic/test_tools/send_algorithm_test_utils.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
+#define QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
+
+#include "quiche/quic/test_tools/send_algorithm_test_result.pb.h"
+
+namespace quic {
+namespace test {
+
+bool LoadSendAlgorithmTestResult(SendAlgorithmTestResult* result);
+
+void RecordSendAlgorithmTestResult(uint64_t random_seed,
+                                   int64_t simulated_duration_micros);
+
+// Load the expected test result with LoadSendAlgorithmTestResult(), and compare
+// it with the actual results provided in the arguments.
+void CompareSendAlgorithmTestResult(int64_t actual_simulated_duration_micros);
+
+std::string GetFullSendAlgorithmTestName();
+
+std::string GetSendAlgorithmTestResultFilename();
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SEND_ALGORITHM_TEST_UTILS_H_
diff --git a/quiche/quic/test_tools/server_thread.cc b/quiche/quic/test_tools/server_thread.cc
new file mode 100644
index 0000000..12d2fc2
--- /dev/null
+++ b/quiche/quic/test_tools/server_thread.cc
@@ -0,0 +1,141 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/server_thread.h"
+
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
+#include "quiche/quic/test_tools/quic_server_peer.h"
+
+namespace quic {
+namespace test {
+
+ServerThread::ServerThread(QuicServer* server, const QuicSocketAddress& address)
+    : QuicThread("server_thread"),
+      server_(server),
+      clock_(server->epoll_server()),
+      address_(address),
+      port_(0),
+      initialized_(false) {}
+
+ServerThread::~ServerThread() = default;
+
+void ServerThread::Initialize() {
+  if (initialized_) {
+    return;
+  }
+
+  server_->CreateUDPSocketAndListen(address_);
+
+  QuicWriterMutexLock lock(&port_lock_);
+  port_ = server_->port();
+
+  initialized_ = true;
+}
+
+void ServerThread::Run() {
+  if (!initialized_) {
+    Initialize();
+  }
+
+  while (!quit_.HasBeenNotified()) {
+    if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
+      paused_.Notify();
+      resume_.WaitForNotification();
+    }
+    server_->WaitForEvents();
+    ExecuteScheduledActions();
+    MaybeNotifyOfHandshakeConfirmation();
+  }
+
+  server_->Shutdown();
+}
+
+int ServerThread::GetPort() {
+  QuicReaderMutexLock lock(&port_lock_);
+  int rc = port_;
+  return rc;
+}
+
+void ServerThread::Schedule(std::function<void()> action) {
+  QUICHE_DCHECK(!quit_.HasBeenNotified());
+  QuicWriterMutexLock lock(&scheduled_actions_lock_);
+  scheduled_actions_.push_back(std::move(action));
+}
+
+void ServerThread::WaitForCryptoHandshakeConfirmed() {
+  confirmed_.WaitForNotification();
+}
+
+bool ServerThread::WaitUntil(std::function<bool()> termination_predicate,
+                             QuicTime::Delta timeout) {
+  const QuicTime deadline = clock_.Now() + timeout;
+  while (clock_.Now() < deadline) {
+    QuicNotification done_checking;
+    bool should_terminate = false;
+    Schedule([&] {
+      should_terminate = termination_predicate();
+      done_checking.Notify();
+    });
+    done_checking.WaitForNotification();
+    if (should_terminate) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void ServerThread::Pause() {
+  QUICHE_DCHECK(!pause_.HasBeenNotified());
+  pause_.Notify();
+  paused_.WaitForNotification();
+}
+
+void ServerThread::Resume() {
+  QUICHE_DCHECK(!resume_.HasBeenNotified());
+  QUICHE_DCHECK(pause_.HasBeenNotified());
+  resume_.Notify();
+}
+
+void ServerThread::Quit() {
+  if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
+    resume_.Notify();
+  }
+  if (!quit_.HasBeenNotified()) {
+    quit_.Notify();
+  }
+}
+
+void ServerThread::MaybeNotifyOfHandshakeConfirmation() {
+  if (confirmed_.HasBeenNotified()) {
+    // Only notify once.
+    return;
+  }
+  QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server());
+  if (dispatcher->NumSessions() == 0) {
+    // Wait for a session to be created.
+    return;
+  }
+  QuicSession* session = QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher);
+  if (session->OneRttKeysAvailable()) {
+    confirmed_.Notify();
+  }
+}
+
+void ServerThread::ExecuteScheduledActions() {
+  quiche::QuicheCircularDeque<std::function<void()>> actions;
+  {
+    QuicWriterMutexLock lock(&scheduled_actions_lock_);
+    actions.swap(scheduled_actions_);
+  }
+  while (!actions.empty()) {
+    actions.front()();
+    actions.pop_front();
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/server_thread.h b/quiche/quic/test_tools/server_thread.h
new file mode 100644
index 0000000..7f5d45a
--- /dev/null
+++ b/quiche/quic/test_tools/server_thread.h
@@ -0,0 +1,97 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
+#define QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
+
+#include <memory>
+
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_thread.h"
+#include "quiche/quic/tools/quic_server.h"
+
+namespace quic {
+namespace test {
+
+// Simple wrapper class to run QuicServer in a dedicated thread.
+class ServerThread : public QuicThread {
+ public:
+  ServerThread(QuicServer* server, const QuicSocketAddress& address);
+  ServerThread(const ServerThread&) = delete;
+  ServerThread& operator=(const ServerThread&) = delete;
+
+  ~ServerThread() override;
+
+  // Prepares the server, but does not start accepting connections. Useful for
+  // injecting mocks.
+  void Initialize();
+
+  // Runs the event loop. Will initialize if necessary.
+  void Run() override;
+
+  // Schedules the given action for execution in the event loop.
+  void Schedule(std::function<void()> action);
+
+  // Waits for the handshake to be confirmed for the first session created.
+  void WaitForCryptoHandshakeConfirmed();
+
+  // Wait until |termination_predicate| returns true in server thread, or
+  // reached |timeout|. Must be called from an external thread.
+  // Return whether the function returned after |termination_predicate| become
+  // true.
+  bool WaitUntil(std::function<bool()> termination_predicate,
+                 QuicTime::Delta timeout);
+
+  // Pauses execution of the server until Resume() is called.  May only be
+  // called once.
+  void Pause();
+
+  // Resumes execution of the server after Pause() has been called.  May only
+  // be called once.
+  void Resume();
+
+  // Stops the server from executing and shuts it down, destroying all
+  // server objects.
+  void Quit();
+
+  // Returns the underlying server.  Care must be taken to avoid data races
+  // when accessing the server.  It is always safe to access the server
+  // after calling Pause() and before calling Resume().
+  QuicServer* server() { return server_.get(); }
+
+  // Returns the port that the server is listening on.
+  int GetPort();
+
+ private:
+  void MaybeNotifyOfHandshakeConfirmation();
+  void ExecuteScheduledActions();
+
+  QuicNotification
+      confirmed_;            // Notified when the first handshake is confirmed.
+  QuicNotification pause_;   // Notified when the server should pause.
+  QuicNotification paused_;  // Notitied when the server has paused
+  QuicNotification resume_;  // Notified when the server should resume.
+  QuicNotification quit_;    // Notified when the server should quit.
+
+  std::unique_ptr<QuicServer> server_;
+  QuicEpollClock clock_;
+  QuicSocketAddress address_;
+  mutable QuicMutex port_lock_;
+  int port_ QUIC_GUARDED_BY(port_lock_);
+
+  bool initialized_;
+
+  QuicMutex scheduled_actions_lock_;
+  quiche::QuicheCircularDeque<std::function<void()>> scheduled_actions_
+      QUIC_GUARDED_BY(scheduled_actions_lock_);
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
diff --git a/quiche/quic/test_tools/simple_data_producer.cc b/quiche/quic/test_tools/simple_data_producer.cc
new file mode 100644
index 0000000..cf899c5
--- /dev/null
+++ b/quiche/quic/test_tools/simple_data_producer.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simple_data_producer.h"
+
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+
+namespace quic {
+
+namespace test {
+
+SimpleDataProducer::SimpleDataProducer() {}
+
+SimpleDataProducer::~SimpleDataProducer() {}
+
+void SimpleDataProducer::SaveStreamData(QuicStreamId id,
+                                        absl::string_view data) {
+  if (data.empty()) {
+    return;
+  }
+  if (!send_buffer_map_.contains(id)) {
+    send_buffer_map_[id] = std::make_unique<QuicStreamSendBuffer>(&allocator_);
+  }
+  send_buffer_map_[id]->SaveStreamData(data);
+}
+
+void SimpleDataProducer::SaveCryptoData(EncryptionLevel level,
+                                        QuicStreamOffset offset,
+                                        absl::string_view data) {
+  auto key = std::make_pair(level, offset);
+  crypto_buffer_map_[key] = std::string(data);
+}
+
+WriteStreamDataResult SimpleDataProducer::WriteStreamData(
+    QuicStreamId id,
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    QuicDataWriter* writer) {
+  auto iter = send_buffer_map_.find(id);
+  if (iter == send_buffer_map_.end()) {
+    return STREAM_MISSING;
+  }
+  if (iter->second->WriteStreamData(offset, data_length, writer)) {
+    return WRITE_SUCCESS;
+  }
+  return WRITE_FAILED;
+}
+
+bool SimpleDataProducer::WriteCryptoData(EncryptionLevel level,
+                                         QuicStreamOffset offset,
+                                         QuicByteCount data_length,
+                                         QuicDataWriter* writer) {
+  auto it = crypto_buffer_map_.find(std::make_pair(level, offset));
+  if (it == crypto_buffer_map_.end() || it->second.length() < data_length) {
+    return false;
+  }
+  return writer->WriteStringPiece(
+      absl::string_view(it->second.data(), data_length));
+}
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simple_data_producer.h b/quiche/quic/test_tools/simple_data_producer.h
new file mode 100644
index 0000000..938c87e
--- /dev/null
+++ b/quiche/quic/test_tools/simple_data_producer.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_stream_send_buffer.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+namespace test {
+
+// A simple data producer which copies stream data into a map from stream
+// id to send buffer.
+class SimpleDataProducer : public QuicStreamFrameDataProducer {
+ public:
+  SimpleDataProducer();
+  ~SimpleDataProducer() override;
+
+  // Saves `data` to be provided when WriteStreamData() is called. Multiple
+  // calls to SaveStreamData() for the same stream ID append to the buffer for
+  // that stream.
+  void SaveStreamData(QuicStreamId id, absl::string_view data);
+
+  void SaveCryptoData(EncryptionLevel level,
+                      QuicStreamOffset offset,
+                      absl::string_view data);
+
+  // QuicStreamFrameDataProducer
+  WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                        QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        QuicDataWriter* writer) override;
+  bool WriteCryptoData(EncryptionLevel level,
+                       QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer) override;
+
+ private:
+  using SendBufferMap =
+      absl::flat_hash_map<QuicStreamId, std::unique_ptr<QuicStreamSendBuffer>>;
+
+  using CryptoBufferMap =
+      absl::flat_hash_map<std::pair<EncryptionLevel, QuicStreamOffset>,
+                          std::string>;
+
+  quiche::SimpleBufferAllocator allocator_;
+
+  SendBufferMap send_buffer_map_;
+
+  // |crypto_buffer_map_| stores data provided by SaveCryptoData to later write
+  // in WriteCryptoData. The level and data passed into SaveCryptoData are used
+  // as the key to identify the data when WriteCryptoData is called.
+  // WriteCryptoData will only succeed if there is data in the map for the
+  // provided level and offset, and the data in the map matches the data_length
+  // passed into WriteCryptoData.
+  //
+  // Unlike SaveStreamData/WriteStreamData which uses a map of
+  // QuicStreamSendBuffers (for each stream ID), this map provides data for
+  // specific offsets. Using a QuicStreamSendBuffer requires that all data
+  // before an offset exist, whereas this allows providing data that exists at
+  // arbitrary offsets for testing.
+  CryptoBufferMap crypto_buffer_map_;
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_DATA_PRODUCER_H_
diff --git a/quiche/quic/test_tools/simple_quic_framer.cc b/quiche/quic/test_tools/simple_quic_framer.cc
new file mode 100644
index 0000000..9f1910f
--- /dev/null
+++ b/quiche/quic/test_tools/simple_quic_framer.cc
@@ -0,0 +1,444 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simple_quic_framer.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_decrypter.h"
+#include "quiche/quic/core/crypto/quic_encrypter.h"
+#include "quiche/quic/core/quic_types.h"
+
+namespace quic {
+namespace test {
+
+class SimpleFramerVisitor : public QuicFramerVisitorInterface {
+ public:
+  SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {}
+  SimpleFramerVisitor(const SimpleFramerVisitor&) = delete;
+  SimpleFramerVisitor& operator=(const SimpleFramerVisitor&) = delete;
+
+  ~SimpleFramerVisitor() override {}
+
+  void OnError(QuicFramer* framer) override { error_ = framer->error(); }
+
+  bool OnProtocolVersionMismatch(ParsedQuicVersion /*version*/) override {
+    return false;
+  }
+
+  void OnPacket() override {}
+  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
+    public_reset_packet_ = std::make_unique<QuicPublicResetPacket>((packet));
+  }
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& packet) override {
+    version_negotiation_packet_ =
+        std::make_unique<QuicVersionNegotiationPacket>((packet));
+  }
+
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {}
+
+  bool OnUnauthenticatedPublicHeader(
+      const QuicPacketHeader& /*header*/) override {
+    return true;
+  }
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
+    return true;
+  }
+  void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
+    last_decrypted_level_ = level;
+  }
+  bool OnPacketHeader(const QuicPacketHeader& header) override {
+    has_header_ = true;
+    header_ = header;
+    return true;
+  }
+
+  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
+    coalesced_packet_ = packet.Clone();
+  }
+
+  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
+                             EncryptionLevel /*decryption_level*/,
+                             bool /*has_decryption_key*/) override {}
+
+  bool OnStreamFrame(const QuicStreamFrame& frame) override {
+    // Save a copy of the data so it is valid after the packet is processed.
+    std::string* string_data =
+        new std::string(frame.data_buffer, frame.data_length);
+    stream_data_.push_back(absl::WrapUnique(string_data));
+    // TODO(ianswett): A pointer isn't necessary with emplace_back.
+    stream_frames_.push_back(std::make_unique<QuicStreamFrame>(
+        frame.stream_id, frame.fin, frame.offset,
+        absl::string_view(*string_data)));
+    return true;
+  }
+
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
+    // Save a copy of the data so it is valid after the packet is processed.
+    std::string* string_data =
+        new std::string(frame.data_buffer, frame.data_length);
+    crypto_data_.push_back(absl::WrapUnique(string_data));
+    crypto_frames_.push_back(std::make_unique<QuicCryptoFrame>(
+        frame.level, frame.offset, absl::string_view(*string_data)));
+    return true;
+  }
+
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta ack_delay_time) override {
+    QuicAckFrame ack_frame;
+    ack_frame.largest_acked = largest_acked;
+    ack_frame.ack_delay_time = ack_delay_time;
+    ack_frames_.push_back(ack_frame);
+    return true;
+  }
+
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
+    QUICHE_DCHECK(!ack_frames_.empty());
+    ack_frames_[ack_frames_.size() - 1].packets.AddRange(start, end);
+    return true;
+  }
+
+  bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
+                      QuicTime /*timestamp*/) override {
+    return true;
+  }
+
+  bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
+
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
+    stop_waiting_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
+    padding_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnPingFrame(const QuicPingFrame& frame) override {
+    ping_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
+    rst_stream_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
+    connection_close_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
+    new_connection_id_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override {
+    retire_connection_id_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
+    new_token_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
+    stop_sending_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
+    path_challenge_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
+    path_response_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
+    goaway_frames_.push_back(frame);
+    return true;
+  }
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
+    max_streams_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
+    streams_blocked_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
+    window_update_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
+    blocked_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnMessageFrame(const QuicMessageFrame& frame) override {
+    message_frames_.emplace_back(frame.data, frame.message_length);
+    return true;
+  }
+
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
+    handshake_done_frames_.push_back(frame);
+    return true;
+  }
+
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+    ack_frequency_frames_.push_back(frame);
+    return true;
+  }
+
+  void OnPacketComplete() override {}
+
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& /*token*/) const override {
+    return false;
+  }
+
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& packet) override {
+    stateless_reset_packet_ =
+        std::make_unique<QuicIetfStatelessResetPacket>(packet);
+  }
+
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  void OnDecryptedFirstPacketInKeyPhase() override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+
+  const QuicPacketHeader& header() const { return header_; }
+  const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; }
+  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
+    return connection_close_frames_;
+  }
+
+  const std::vector<QuicGoAwayFrame>& goaway_frames() const {
+    return goaway_frames_;
+  }
+  const std::vector<QuicMaxStreamsFrame>& max_streams_frames() const {
+    return max_streams_frames_;
+  }
+  const std::vector<QuicStreamsBlockedFrame>& streams_blocked_frames() const {
+    return streams_blocked_frames_;
+  }
+  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
+    return rst_stream_frames_;
+  }
+  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
+    return stream_frames_;
+  }
+  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
+    return crypto_frames_;
+  }
+  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
+    return stop_waiting_frames_;
+  }
+  const std::vector<QuicPingFrame>& ping_frames() const { return ping_frames_; }
+  const std::vector<QuicMessageFrame>& message_frames() const {
+    return message_frames_;
+  }
+  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
+    return window_update_frames_;
+  }
+  const std::vector<QuicPaddingFrame>& padding_frames() const {
+    return padding_frames_;
+  }
+  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
+    return path_challenge_frames_;
+  }
+  const std::vector<QuicPathResponseFrame>& path_response_frames() const {
+    return path_response_frames_;
+  }
+  const QuicVersionNegotiationPacket* version_negotiation_packet() const {
+    return version_negotiation_packet_.get();
+  }
+  EncryptionLevel last_decrypted_level() const { return last_decrypted_level_; }
+  const QuicEncryptedPacket* coalesced_packet() const {
+    return coalesced_packet_.get();
+  }
+
+ private:
+  QuicErrorCode error_;
+  bool has_header_;
+  QuicPacketHeader header_;
+  std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
+  std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
+  std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
+  std::vector<QuicAckFrame> ack_frames_;
+  std::vector<QuicStopWaitingFrame> stop_waiting_frames_;
+  std::vector<QuicPaddingFrame> padding_frames_;
+  std::vector<QuicPingFrame> ping_frames_;
+  std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
+  std::vector<std::unique_ptr<QuicCryptoFrame>> crypto_frames_;
+  std::vector<QuicRstStreamFrame> rst_stream_frames_;
+  std::vector<QuicGoAwayFrame> goaway_frames_;
+  std::vector<QuicStreamsBlockedFrame> streams_blocked_frames_;
+  std::vector<QuicMaxStreamsFrame> max_streams_frames_;
+  std::vector<QuicConnectionCloseFrame> connection_close_frames_;
+  std::vector<QuicStopSendingFrame> stop_sending_frames_;
+  std::vector<QuicPathChallengeFrame> path_challenge_frames_;
+  std::vector<QuicPathResponseFrame> path_response_frames_;
+  std::vector<QuicWindowUpdateFrame> window_update_frames_;
+  std::vector<QuicBlockedFrame> blocked_frames_;
+  std::vector<QuicNewConnectionIdFrame> new_connection_id_frames_;
+  std::vector<QuicRetireConnectionIdFrame> retire_connection_id_frames_;
+  std::vector<QuicNewTokenFrame> new_token_frames_;
+  std::vector<QuicMessageFrame> message_frames_;
+  std::vector<QuicHandshakeDoneFrame> handshake_done_frames_;
+  std::vector<QuicAckFrequencyFrame> ack_frequency_frames_;
+  std::vector<std::unique_ptr<std::string>> stream_data_;
+  std::vector<std::unique_ptr<std::string>> crypto_data_;
+  EncryptionLevel last_decrypted_level_;
+  std::unique_ptr<QuicEncryptedPacket> coalesced_packet_;
+};
+
+SimpleQuicFramer::SimpleQuicFramer()
+    : framer_(AllSupportedVersions(),
+              QuicTime::Zero(),
+              Perspective::IS_SERVER,
+              kQuicDefaultConnectionIdLength) {}
+
+SimpleQuicFramer::SimpleQuicFramer(
+    const ParsedQuicVersionVector& supported_versions)
+    : framer_(supported_versions,
+              QuicTime::Zero(),
+              Perspective::IS_SERVER,
+              kQuicDefaultConnectionIdLength) {}
+
+SimpleQuicFramer::SimpleQuicFramer(
+    const ParsedQuicVersionVector& supported_versions,
+    Perspective perspective)
+    : framer_(supported_versions,
+              QuicTime::Zero(),
+              perspective,
+              kQuicDefaultConnectionIdLength) {}
+
+SimpleQuicFramer::~SimpleQuicFramer() {}
+
+bool SimpleQuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
+  visitor_ = std::make_unique<SimpleFramerVisitor>();
+  framer_.set_visitor(visitor_.get());
+  return framer_.ProcessPacket(packet);
+}
+
+void SimpleQuicFramer::Reset() {
+  visitor_ = std::make_unique<SimpleFramerVisitor>();
+}
+
+const QuicPacketHeader& SimpleQuicFramer::header() const {
+  return visitor_->header();
+}
+
+const QuicVersionNegotiationPacket*
+SimpleQuicFramer::version_negotiation_packet() const {
+  return visitor_->version_negotiation_packet();
+}
+
+EncryptionLevel SimpleQuicFramer::last_decrypted_level() const {
+  return visitor_->last_decrypted_level();
+}
+
+QuicFramer* SimpleQuicFramer::framer() {
+  return &framer_;
+}
+
+size_t SimpleQuicFramer::num_frames() const {
+  return ack_frames().size() + goaway_frames().size() +
+         rst_stream_frames().size() + stop_waiting_frames().size() +
+         path_challenge_frames().size() + path_response_frames().size() +
+         stream_frames().size() + ping_frames().size() +
+         connection_close_frames().size() + padding_frames().size() +
+         crypto_frames().size();
+}
+
+const std::vector<QuicAckFrame>& SimpleQuicFramer::ack_frames() const {
+  return visitor_->ack_frames();
+}
+
+const std::vector<QuicStopWaitingFrame>& SimpleQuicFramer::stop_waiting_frames()
+    const {
+  return visitor_->stop_waiting_frames();
+}
+
+const std::vector<QuicPathChallengeFrame>&
+SimpleQuicFramer::path_challenge_frames() const {
+  return visitor_->path_challenge_frames();
+}
+const std::vector<QuicPathResponseFrame>&
+SimpleQuicFramer::path_response_frames() const {
+  return visitor_->path_response_frames();
+}
+
+const std::vector<QuicPingFrame>& SimpleQuicFramer::ping_frames() const {
+  return visitor_->ping_frames();
+}
+
+const std::vector<QuicMessageFrame>& SimpleQuicFramer::message_frames() const {
+  return visitor_->message_frames();
+}
+
+const std::vector<QuicWindowUpdateFrame>&
+SimpleQuicFramer::window_update_frames() const {
+  return visitor_->window_update_frames();
+}
+
+const std::vector<std::unique_ptr<QuicStreamFrame>>&
+SimpleQuicFramer::stream_frames() const {
+  return visitor_->stream_frames();
+}
+
+const std::vector<std::unique_ptr<QuicCryptoFrame>>&
+SimpleQuicFramer::crypto_frames() const {
+  return visitor_->crypto_frames();
+}
+
+const std::vector<QuicRstStreamFrame>& SimpleQuicFramer::rst_stream_frames()
+    const {
+  return visitor_->rst_stream_frames();
+}
+
+const std::vector<QuicGoAwayFrame>& SimpleQuicFramer::goaway_frames() const {
+  return visitor_->goaway_frames();
+}
+
+const std::vector<QuicConnectionCloseFrame>&
+SimpleQuicFramer::connection_close_frames() const {
+  return visitor_->connection_close_frames();
+}
+
+const std::vector<QuicPaddingFrame>& SimpleQuicFramer::padding_frames() const {
+  return visitor_->padding_frames();
+}
+
+const QuicEncryptedPacket* SimpleQuicFramer::coalesced_packet() const {
+  return visitor_->coalesced_packet();
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simple_quic_framer.h b/quiche/quic/test_tools/simple_quic_framer.h
new file mode 100644
index 0000000..a748f4c
--- /dev/null
+++ b/quiche/quic/test_tools/simple_quic_framer.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
+
+#include <memory>
+#include <vector>
+
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packets.h"
+
+namespace quic {
+
+struct QuicAckFrame;
+
+namespace test {
+
+class SimpleFramerVisitor;
+
+// Peer to make public a number of otherwise private QuicFramer methods.
+class SimpleQuicFramer {
+ public:
+  SimpleQuicFramer();
+  explicit SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions);
+  SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions,
+                   Perspective perspective);
+  SimpleQuicFramer(const SimpleQuicFramer&) = delete;
+  SimpleQuicFramer& operator=(const SimpleQuicFramer&) = delete;
+  ~SimpleQuicFramer();
+
+  bool ProcessPacket(const QuicEncryptedPacket& packet);
+  void Reset();
+
+  const QuicPacketHeader& header() const;
+  size_t num_frames() const;
+  const std::vector<QuicAckFrame>& ack_frames() const;
+  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const;
+  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const;
+  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const;
+  const std::vector<QuicPathResponseFrame>& path_response_frames() const;
+  const std::vector<QuicPingFrame>& ping_frames() const;
+  const std::vector<QuicMessageFrame>& message_frames() const;
+  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const;
+  const std::vector<QuicGoAwayFrame>& goaway_frames() const;
+  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const;
+  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const;
+  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const;
+  const std::vector<QuicPaddingFrame>& padding_frames() const;
+  const QuicVersionNegotiationPacket* version_negotiation_packet() const;
+  EncryptionLevel last_decrypted_level() const;
+  const QuicEncryptedPacket* coalesced_packet() const;
+
+  QuicFramer* framer();
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    framer_.SetSupportedVersions(versions);
+  }
+
+ private:
+  QuicFramer framer_;
+  std::unique_ptr<SimpleFramerVisitor> visitor_;
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_QUIC_FRAMER_H_
diff --git a/quiche/quic/test_tools/simple_session_cache.cc b/quiche/quic/test_tools/simple_session_cache.cc
new file mode 100644
index 0000000..eafead3
--- /dev/null
+++ b/quiche/quic/test_tools/simple_session_cache.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simple_session_cache.h"
+#include <memory>
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+
+namespace quic {
+namespace test {
+
+void SimpleSessionCache::Insert(const QuicServerId& server_id,
+                                bssl::UniquePtr<SSL_SESSION> session,
+                                const TransportParameters& params,
+                                const ApplicationState* application_state) {
+  auto it = cache_entries_.find(server_id);
+  if (it == cache_entries_.end()) {
+    it = cache_entries_.insert(std::make_pair(server_id, Entry())).first;
+  }
+  if (session != nullptr) {
+    it->second.session = std::move(session);
+  }
+  if (application_state != nullptr) {
+    it->second.application_state =
+        std::make_unique<ApplicationState>(*application_state);
+  }
+  it->second.params = std::make_unique<TransportParameters>(params);
+}
+
+std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup(
+    const QuicServerId& server_id, QuicWallTime /*now*/,
+    const SSL_CTX* /*ctx*/) {
+  auto it = cache_entries_.find(server_id);
+  if (it == cache_entries_.end()) {
+    return nullptr;
+  }
+
+  if (!it->second.session) {
+    cache_entries_.erase(it);
+    return nullptr;
+  }
+
+  auto state = std::make_unique<QuicResumptionState>();
+  state->tls_session = std::move(it->second.session);
+  if (it->second.application_state != nullptr) {
+    state->application_state =
+        std::make_unique<ApplicationState>(*it->second.application_state);
+  }
+  state->transport_params =
+      std::make_unique<TransportParameters>(*it->second.params);
+  state->token = it->second.token;
+  return state;
+}
+
+void SimpleSessionCache::ClearEarlyData(const QuicServerId& /*server_id*/) {
+  // The simple session cache only stores 1 SSL ticket per entry, so no need to
+  // do anything here.
+}
+
+void SimpleSessionCache::OnNewTokenReceived(const QuicServerId& server_id,
+                                            absl::string_view token) {
+  auto it = cache_entries_.find(server_id);
+  if (it == cache_entries_.end()) {
+    return;
+  }
+  it->second.token = std::string(token);
+}
+
+void SimpleSessionCache::RemoveExpiredEntries(QuicWallTime /*now*/) {
+  // The simple session cache does not support removing expired entries.
+}
+
+void SimpleSessionCache::Clear() { cache_entries_.clear(); }
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simple_session_cache.h b/quiche/quic/test_tools/simple_session_cache.h
new file mode 100644
index 0000000..343303a
--- /dev/null
+++ b/quiche/quic/test_tools/simple_session_cache.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
+
+#include <memory>
+#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
+#include "quiche/quic/core/crypto/transport_parameters.h"
+
+namespace quic {
+namespace test {
+
+// SimpleSessionCache provides a simple implementation of SessionCache that
+// stores only one QuicResumptionState per QuicServerId. No limit is placed on
+// the total number of entries in the cache. When Lookup is called, if a cache
+// entry exists for the provided QuicServerId, the entry will be removed from
+// the cached when it is returned.
+// TODO(fayang): Remove SimpleSessionCache by using QuicClientSessionCache.
+class SimpleSessionCache : public SessionCache {
+ public:
+  SimpleSessionCache() = default;
+  ~SimpleSessionCache() override = default;
+
+  void Insert(const QuicServerId& server_id,
+              bssl::UniquePtr<SSL_SESSION> session,
+              const TransportParameters& params,
+              const ApplicationState* application_state) override;
+  std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
+                                              QuicWallTime now,
+                                              const SSL_CTX* ctx) override;
+  void ClearEarlyData(const QuicServerId& server_id) override;
+  void OnNewTokenReceived(const QuicServerId& server_id,
+                          absl::string_view token) override;
+  void RemoveExpiredEntries(QuicWallTime now) override;
+  void Clear() override;
+
+ private:
+  struct Entry {
+    bssl::UniquePtr<SSL_SESSION> session;
+    std::unique_ptr<TransportParameters> params;
+    std::unique_ptr<ApplicationState> application_state;
+    std::string token;
+  };
+  std::map<QuicServerId, Entry> cache_entries_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_CACHE_H_
diff --git a/quiche/quic/test_tools/simple_session_notifier.cc b/quiche/quic/test_tools/simple_session_notifier.cc
new file mode 100644
index 0000000..acd249e
--- /dev/null
+++ b/quiche/quic/test_tools/simple_session_notifier.cc
@@ -0,0 +1,766 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simple_session_notifier.h"
+
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+
+namespace test {
+
+SimpleSessionNotifier::SimpleSessionNotifier(QuicConnection* connection)
+    : last_control_frame_id_(kInvalidControlFrameId),
+      least_unacked_(1),
+      least_unsent_(1),
+      connection_(connection) {}
+
+SimpleSessionNotifier::~SimpleSessionNotifier() {
+  while (!control_frames_.empty()) {
+    DeleteFrame(&control_frames_.front());
+    control_frames_.pop_front();
+  }
+}
+
+SimpleSessionNotifier::StreamState::StreamState()
+    : bytes_total(0),
+      bytes_sent(0),
+      fin_buffered(false),
+      fin_sent(false),
+      fin_outstanding(false),
+      fin_lost(false) {}
+
+SimpleSessionNotifier::StreamState::~StreamState() {}
+
+QuicConsumedData SimpleSessionNotifier::WriteOrBufferData(
+    QuicStreamId id,
+    QuicByteCount data_length,
+    StreamSendingState state) {
+  if (!stream_map_.contains(id)) {
+    stream_map_[id] = StreamState();
+  }
+  StreamState& stream_state = stream_map_.find(id)->second;
+  const bool had_buffered_data =
+      HasBufferedStreamData() || HasBufferedControlFrames();
+  QuicStreamOffset offset = stream_state.bytes_sent;
+  QUIC_DVLOG(1) << "WriteOrBuffer stream_id: " << id << " [" << offset << ", "
+                << offset + data_length << "), fin: " << (state != NO_FIN);
+  stream_state.bytes_total += data_length;
+  stream_state.fin_buffered = state != NO_FIN;
+  if (had_buffered_data) {
+    QUIC_DLOG(WARNING) << "Connection is write blocked";
+    return {0, false};
+  }
+  const size_t length = stream_state.bytes_total - stream_state.bytes_sent;
+  connection_->SetTransmissionType(NOT_RETRANSMISSION);
+  QuicConsumedData consumed =
+      connection_->SendStreamData(id, length, stream_state.bytes_sent, state);
+  QUIC_DVLOG(1) << "consumed: " << consumed;
+  OnStreamDataConsumed(id, stream_state.bytes_sent, consumed.bytes_consumed,
+                       consumed.fin_consumed);
+  return consumed;
+}
+
+void SimpleSessionNotifier::OnStreamDataConsumed(QuicStreamId id,
+                                                 QuicStreamOffset offset,
+                                                 QuicByteCount data_length,
+                                                 bool fin) {
+  StreamState& state = stream_map_.find(id)->second;
+  if (QuicUtils::IsCryptoStreamId(connection_->transport_version(), id) &&
+      data_length > 0) {
+    crypto_bytes_transferred_[connection_->encryption_level()].Add(
+        offset, offset + data_length);
+  }
+  state.bytes_sent += data_length;
+  state.fin_sent = fin;
+  state.fin_outstanding = fin;
+}
+
+size_t SimpleSessionNotifier::WriteCryptoData(EncryptionLevel level,
+                                              QuicByteCount data_length,
+                                              QuicStreamOffset offset) {
+  crypto_state_[level].bytes_total += data_length;
+  size_t bytes_written =
+      connection_->SendCryptoData(level, data_length, offset);
+  crypto_state_[level].bytes_sent += bytes_written;
+  crypto_bytes_transferred_[level].Add(offset, offset + bytes_written);
+  return bytes_written;
+}
+
+void SimpleSessionNotifier::WriteOrBufferRstStream(
+    QuicStreamId id,
+    QuicRstStreamErrorCode error,
+    QuicStreamOffset bytes_written) {
+  QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
+  const bool had_buffered_data =
+      HasBufferedStreamData() || HasBufferedControlFrames();
+  control_frames_.emplace_back((QuicFrame(new QuicRstStreamFrame(
+      ++last_control_frame_id_, id, error, bytes_written))));
+  if (error != QUIC_STREAM_NO_ERROR) {
+    // Delete stream to avoid retransmissions.
+    stream_map_.erase(id);
+  }
+  if (had_buffered_data) {
+    QUIC_DLOG(WARNING) << "Connection is write blocked";
+    return;
+  }
+  WriteBufferedControlFrames();
+}
+
+void SimpleSessionNotifier::WriteOrBufferWindowUpate(
+    QuicStreamId id, QuicStreamOffset byte_offset) {
+  QUIC_DVLOG(1) << "Writing WINDOW_UPDATE";
+  const bool had_buffered_data =
+      HasBufferedStreamData() || HasBufferedControlFrames();
+  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
+  control_frames_.emplace_back(
+      (QuicFrame(QuicWindowUpdateFrame(control_frame_id, id, byte_offset))));
+  if (had_buffered_data) {
+    QUIC_DLOG(WARNING) << "Connection is write blocked";
+    return;
+  }
+  WriteBufferedControlFrames();
+}
+
+void SimpleSessionNotifier::WriteOrBufferPing() {
+  QUIC_DVLOG(1) << "Writing PING_FRAME";
+  const bool had_buffered_data =
+      HasBufferedStreamData() || HasBufferedControlFrames();
+  control_frames_.emplace_back(
+      (QuicFrame(QuicPingFrame(++last_control_frame_id_))));
+  if (had_buffered_data) {
+    QUIC_DLOG(WARNING) << "Connection is write blocked";
+    return;
+  }
+  WriteBufferedControlFrames();
+}
+
+void SimpleSessionNotifier::WriteOrBufferAckFrequency(
+    const QuicAckFrequencyFrame& ack_frequency_frame) {
+  QUIC_DVLOG(1) << "Writing ACK_FREQUENCY";
+  const bool had_buffered_data =
+      HasBufferedStreamData() || HasBufferedControlFrames();
+  QuicControlFrameId control_frame_id = ++last_control_frame_id_;
+  control_frames_.emplace_back((
+      QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
+                                          /*sequence_number=*/control_frame_id,
+                                          ack_frequency_frame.packet_tolerance,
+                                          ack_frequency_frame.max_ack_delay))));
+  if (had_buffered_data) {
+    QUIC_DLOG(WARNING) << "Connection is write blocked";
+    return;
+  }
+  WriteBufferedControlFrames();
+}
+
+void SimpleSessionNotifier::NeuterUnencryptedData() {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
+      QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, interval.min(),
+                                   interval.max() - interval.min());
+      OnFrameAcked(QuicFrame(&crypto_frame), QuicTime::Delta::Zero(),
+                   QuicTime::Zero());
+    }
+    return;
+  }
+  for (const auto& interval : crypto_bytes_transferred_[ENCRYPTION_INITIAL]) {
+    QuicStreamFrame stream_frame(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()), false,
+        interval.min(), interval.max() - interval.min());
+    OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
+                 QuicTime::Zero());
+  }
+}
+
+void SimpleSessionNotifier::OnCanWrite() {
+  if (connection_->framer().is_processing_packet()) {
+    // Do not write data in the middle of packet processing because rest
+    // frames in the packet may change the data to write. For example, lost
+    // data could be acknowledged. Also, connection is going to emit
+    // OnCanWrite signal post packet processing.
+    QUIC_BUG(simple_notifier_write_mid_packet_processing)
+        << "Try to write mid packet processing.";
+    return;
+  }
+  if (!RetransmitLostCryptoData() || !RetransmitLostControlFrames() ||
+      !RetransmitLostStreamData()) {
+    return;
+  }
+  if (!WriteBufferedCryptoData() || !WriteBufferedControlFrames()) {
+    return;
+  }
+  // Write new data.
+  for (const auto& pair : stream_map_) {
+    const auto& state = pair.second;
+    if (!StreamHasBufferedData(pair.first)) {
+      continue;
+    }
+
+    const size_t length = state.bytes_total - state.bytes_sent;
+    const bool can_bundle_fin =
+        state.fin_buffered && (state.bytes_sent + length == state.bytes_total);
+    connection_->SetTransmissionType(NOT_RETRANSMISSION);
+    QuicConnection::ScopedEncryptionLevelContext context(
+        connection_,
+        connection_->framer().GetEncryptionLevelToSendApplicationData());
+    QuicConsumedData consumed = connection_->SendStreamData(
+        pair.first, length, state.bytes_sent, can_bundle_fin ? FIN : NO_FIN);
+    QUIC_DVLOG(1) << "Tries to write stream_id: " << pair.first << " ["
+                  << state.bytes_sent << ", " << state.bytes_sent + length
+                  << "), fin: " << can_bundle_fin
+                  << ", and consumed: " << consumed;
+    OnStreamDataConsumed(pair.first, state.bytes_sent, consumed.bytes_consumed,
+                         consumed.fin_consumed);
+    if (length != consumed.bytes_consumed ||
+        (can_bundle_fin && !consumed.fin_consumed)) {
+      break;
+    }
+  }
+}
+
+void SimpleSessionNotifier::OnStreamReset(QuicStreamId id,
+                                          QuicRstStreamErrorCode error) {
+  if (error != QUIC_STREAM_NO_ERROR) {
+    // Delete stream to avoid retransmissions.
+    stream_map_.erase(id);
+  }
+}
+
+bool SimpleSessionNotifier::WillingToWrite() const {
+  QUIC_DVLOG(1) << "has_buffered_control_frames: " << HasBufferedControlFrames()
+                << " as_lost_control_frames: " << !lost_control_frames_.empty()
+                << " has_buffered_stream_data: " << HasBufferedStreamData()
+                << " has_lost_stream_data: " << HasLostStreamData();
+  return HasBufferedControlFrames() || !lost_control_frames_.empty() ||
+         HasBufferedStreamData() || HasLostStreamData();
+}
+
+QuicByteCount SimpleSessionNotifier::StreamBytesSent() const {
+  QuicByteCount bytes_sent = 0;
+  for (const auto& pair : stream_map_) {
+    const auto& state = pair.second;
+    bytes_sent += state.bytes_sent;
+  }
+  return bytes_sent;
+}
+
+QuicByteCount SimpleSessionNotifier::StreamBytesToSend() const {
+  QuicByteCount bytes_to_send = 0;
+  for (const auto& pair : stream_map_) {
+    const auto& state = pair.second;
+    bytes_to_send += (state.bytes_total - state.bytes_sent);
+  }
+  return bytes_to_send;
+}
+
+bool SimpleSessionNotifier::OnFrameAcked(const QuicFrame& frame,
+                                         QuicTime::Delta /*ack_delay_time*/,
+                                         QuicTime /*receive_timestamp*/) {
+  QUIC_DVLOG(1) << "Acking " << frame;
+  if (frame.type == CRYPTO_FRAME) {
+    StreamState* state = &crypto_state_[frame.crypto_frame->level];
+    QuicStreamOffset offset = frame.crypto_frame->offset;
+    QuicByteCount data_length = frame.crypto_frame->data_length;
+    QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+    newly_acked.Difference(state->bytes_acked);
+    if (newly_acked.Empty()) {
+      return false;
+    }
+    state->bytes_acked.Add(offset, offset + data_length);
+    state->pending_retransmissions.Difference(offset, offset + data_length);
+    return true;
+  }
+  if (frame.type != STREAM_FRAME) {
+    return OnControlFrameAcked(frame);
+  }
+  if (!stream_map_.contains(frame.stream_frame.stream_id)) {
+    return false;
+  }
+  auto* state = &stream_map_.find(frame.stream_frame.stream_id)->second;
+  QuicStreamOffset offset = frame.stream_frame.offset;
+  QuicByteCount data_length = frame.stream_frame.data_length;
+  QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
+  newly_acked.Difference(state->bytes_acked);
+  const bool fin_newly_acked = frame.stream_frame.fin && state->fin_outstanding;
+  if (newly_acked.Empty() && !fin_newly_acked) {
+    return false;
+  }
+  state->bytes_acked.Add(offset, offset + data_length);
+  if (fin_newly_acked) {
+    state->fin_outstanding = false;
+    state->fin_lost = false;
+  }
+  state->pending_retransmissions.Difference(offset, offset + data_length);
+  return true;
+}
+
+void SimpleSessionNotifier::OnFrameLost(const QuicFrame& frame) {
+  QUIC_DVLOG(1) << "Losting " << frame;
+  if (frame.type == CRYPTO_FRAME) {
+    StreamState* state = &crypto_state_[frame.crypto_frame->level];
+    QuicStreamOffset offset = frame.crypto_frame->offset;
+    QuicByteCount data_length = frame.crypto_frame->data_length;
+    QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
+    bytes_lost.Difference(state->bytes_acked);
+    if (bytes_lost.Empty()) {
+      return;
+    }
+    for (const auto& lost : bytes_lost) {
+      state->pending_retransmissions.Add(lost.min(), lost.max());
+    }
+    return;
+  }
+  if (frame.type != STREAM_FRAME) {
+    OnControlFrameLost(frame);
+    return;
+  }
+  if (!stream_map_.contains(frame.stream_frame.stream_id)) {
+    return;
+  }
+  auto* state = &stream_map_.find(frame.stream_frame.stream_id)->second;
+  QuicStreamOffset offset = frame.stream_frame.offset;
+  QuicByteCount data_length = frame.stream_frame.data_length;
+  QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
+  bytes_lost.Difference(state->bytes_acked);
+  const bool fin_lost = state->fin_outstanding && frame.stream_frame.fin;
+  if (bytes_lost.Empty() && !fin_lost) {
+    return;
+  }
+  for (const auto& lost : bytes_lost) {
+    state->pending_retransmissions.Add(lost.min(), lost.max());
+  }
+  state->fin_lost = fin_lost;
+}
+
+bool SimpleSessionNotifier::RetransmitFrames(const QuicFrames& frames,
+                                             TransmissionType type) {
+  QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
+  connection_->SetTransmissionType(type);
+  for (const QuicFrame& frame : frames) {
+    if (frame.type == CRYPTO_FRAME) {
+      const StreamState& state = crypto_state_[frame.crypto_frame->level];
+      const EncryptionLevel current_encryption_level =
+          connection_->encryption_level();
+      QuicIntervalSet<QuicStreamOffset> retransmission(
+          frame.crypto_frame->offset,
+          frame.crypto_frame->offset + frame.crypto_frame->data_length);
+      retransmission.Difference(state.bytes_acked);
+      for (const auto& interval : retransmission) {
+        QuicStreamOffset offset = interval.min();
+        QuicByteCount length = interval.max() - interval.min();
+        connection_->SetDefaultEncryptionLevel(frame.crypto_frame->level);
+        size_t consumed = connection_->SendCryptoData(frame.crypto_frame->level,
+                                                      length, offset);
+        if (consumed < length) {
+          return false;
+        }
+      }
+      connection_->SetDefaultEncryptionLevel(current_encryption_level);
+    }
+    if (frame.type != STREAM_FRAME) {
+      if (GetControlFrameId(frame) == kInvalidControlFrameId) {
+        continue;
+      }
+      QuicFrame copy = CopyRetransmittableControlFrame(frame);
+      if (!connection_->SendControlFrame(copy)) {
+        // Connection is write blocked.
+        DeleteFrame(&copy);
+        return false;
+      }
+      continue;
+    }
+    if (!stream_map_.contains(frame.stream_frame.stream_id)) {
+      continue;
+    }
+    const auto& state = stream_map_.find(frame.stream_frame.stream_id)->second;
+    QuicIntervalSet<QuicStreamOffset> retransmission(
+        frame.stream_frame.offset,
+        frame.stream_frame.offset + frame.stream_frame.data_length);
+    EncryptionLevel retransmission_encryption_level =
+        connection_->encryption_level();
+    if (QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+                                    frame.stream_frame.stream_id)) {
+      for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+        if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
+          retransmission_encryption_level = static_cast<EncryptionLevel>(i);
+          retransmission.Intersection(crypto_bytes_transferred_[i]);
+          break;
+        }
+      }
+    }
+    retransmission.Difference(state.bytes_acked);
+    bool retransmit_fin = frame.stream_frame.fin && state.fin_outstanding;
+    QuicConsumedData consumed(0, false);
+    for (const auto& interval : retransmission) {
+      QuicStreamOffset retransmission_offset = interval.min();
+      QuicByteCount retransmission_length = interval.max() - interval.min();
+      const bool can_bundle_fin =
+          retransmit_fin &&
+          (retransmission_offset + retransmission_length == state.bytes_sent);
+      QuicConnection::ScopedEncryptionLevelContext context(
+          connection_,
+          QuicUtils::IsCryptoStreamId(connection_->transport_version(),
+                                      frame.stream_frame.stream_id)
+              ? retransmission_encryption_level
+              : connection_->framer()
+                    .GetEncryptionLevelToSendApplicationData());
+      consumed = connection_->SendStreamData(
+          frame.stream_frame.stream_id, retransmission_length,
+          retransmission_offset, can_bundle_fin ? FIN : NO_FIN);
+      QUIC_DVLOG(1) << "stream " << frame.stream_frame.stream_id
+                    << " is forced to retransmit stream data ["
+                    << retransmission_offset << ", "
+                    << retransmission_offset + retransmission_length
+                    << ") and fin: " << can_bundle_fin
+                    << ", consumed: " << consumed;
+      if (can_bundle_fin) {
+        retransmit_fin = !consumed.fin_consumed;
+      }
+      if (consumed.bytes_consumed < retransmission_length ||
+          (can_bundle_fin && !consumed.fin_consumed)) {
+        // Connection is write blocked.
+        return false;
+      }
+    }
+    if (retransmit_fin) {
+      QUIC_DVLOG(1) << "stream " << frame.stream_frame.stream_id
+                    << " retransmits fin only frame.";
+      consumed = connection_->SendStreamData(frame.stream_frame.stream_id, 0,
+                                             state.bytes_sent, FIN);
+      if (!consumed.fin_consumed) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool SimpleSessionNotifier::IsFrameOutstanding(const QuicFrame& frame) const {
+  if (frame.type == CRYPTO_FRAME) {
+    QuicStreamOffset offset = frame.crypto_frame->offset;
+    QuicByteCount data_length = frame.crypto_frame->data_length;
+    bool ret = data_length > 0 &&
+               !crypto_state_[frame.crypto_frame->level].bytes_acked.Contains(
+                   offset, offset + data_length);
+    return ret;
+  }
+  if (frame.type != STREAM_FRAME) {
+    return IsControlFrameOutstanding(frame);
+  }
+  if (!stream_map_.contains(frame.stream_frame.stream_id)) {
+    return false;
+  }
+  const auto& state = stream_map_.find(frame.stream_frame.stream_id)->second;
+  QuicStreamOffset offset = frame.stream_frame.offset;
+  QuicByteCount data_length = frame.stream_frame.data_length;
+  return (data_length > 0 &&
+          !state.bytes_acked.Contains(offset, offset + data_length)) ||
+         (frame.stream_frame.fin && state.fin_outstanding);
+}
+
+bool SimpleSessionNotifier::HasUnackedCryptoData() const {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+      const StreamState& state = crypto_state_[i];
+      if (state.bytes_total > state.bytes_sent) {
+        return true;
+      }
+      QuicIntervalSet<QuicStreamOffset> bytes_to_ack(0, state.bytes_total);
+      bytes_to_ack.Difference(state.bytes_acked);
+      if (!bytes_to_ack.Empty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+  if (!stream_map_.contains(
+          QuicUtils::GetCryptoStreamId(connection_->transport_version()))) {
+    return false;
+  }
+  const auto& state =
+      stream_map_
+          .find(QuicUtils::GetCryptoStreamId(connection_->transport_version()))
+          ->second;
+  if (state.bytes_total > state.bytes_sent) {
+    return true;
+  }
+  QuicIntervalSet<QuicStreamOffset> bytes_to_ack(0, state.bytes_total);
+  bytes_to_ack.Difference(state.bytes_acked);
+  return !bytes_to_ack.Empty();
+}
+
+bool SimpleSessionNotifier::HasUnackedStreamData() const {
+  for (const auto& it : stream_map_) {
+    if (StreamIsWaitingForAcks(it.first))
+      return true;
+  }
+  return false;
+}
+
+bool SimpleSessionNotifier::OnControlFrameAcked(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    return false;
+  }
+  QUICHE_DCHECK(id < least_unacked_ + control_frames_.size());
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    return false;
+  }
+  SetControlFrameId(kInvalidControlFrameId,
+                    &control_frames_.at(id - least_unacked_));
+  lost_control_frames_.erase(id);
+  while (!control_frames_.empty() &&
+         GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
+    DeleteFrame(&control_frames_.front());
+    control_frames_.pop_front();
+    ++least_unacked_;
+  }
+  return true;
+}
+
+void SimpleSessionNotifier::OnControlFrameLost(const QuicFrame& frame) {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    return;
+  }
+  QUICHE_DCHECK(id < least_unacked_ + control_frames_.size());
+  if (id < least_unacked_ ||
+      GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
+          kInvalidControlFrameId) {
+    return;
+  }
+  if (!lost_control_frames_.contains(id)) {
+    lost_control_frames_[id] = true;
+  }
+}
+
+bool SimpleSessionNotifier::IsControlFrameOutstanding(
+    const QuicFrame& frame) const {
+  QuicControlFrameId id = GetControlFrameId(frame);
+  if (id == kInvalidControlFrameId) {
+    return false;
+  }
+  return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
+         GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
+             kInvalidControlFrameId;
+}
+
+bool SimpleSessionNotifier::RetransmitLostControlFrames() {
+  while (!lost_control_frames_.empty()) {
+    QuicFrame pending = control_frames_.at(lost_control_frames_.begin()->first -
+                                           least_unacked_);
+    QuicFrame copy = CopyRetransmittableControlFrame(pending);
+    connection_->SetTransmissionType(LOSS_RETRANSMISSION);
+    if (!connection_->SendControlFrame(copy)) {
+      // Connection is write blocked.
+      DeleteFrame(&copy);
+      break;
+    }
+    lost_control_frames_.pop_front();
+  }
+  return lost_control_frames_.empty();
+}
+
+bool SimpleSessionNotifier::RetransmitLostCryptoData() {
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    for (EncryptionLevel level :
+         {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
+          ENCRYPTION_FORWARD_SECURE}) {
+      auto& state = crypto_state_[level];
+      while (!state.pending_retransmissions.Empty()) {
+        connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
+        EncryptionLevel current_encryption_level =
+            connection_->encryption_level();
+        connection_->SetDefaultEncryptionLevel(level);
+        QuicIntervalSet<QuicStreamOffset> retransmission(
+            state.pending_retransmissions.begin()->min(),
+            state.pending_retransmissions.begin()->max());
+        retransmission.Intersection(crypto_bytes_transferred_[level]);
+        QuicStreamOffset retransmission_offset = retransmission.begin()->min();
+        QuicByteCount retransmission_length =
+            retransmission.begin()->max() - retransmission.begin()->min();
+        size_t bytes_consumed = connection_->SendCryptoData(
+            level, retransmission_length, retransmission_offset);
+        // Restore encryption level.
+        connection_->SetDefaultEncryptionLevel(current_encryption_level);
+        state.pending_retransmissions.Difference(
+            retransmission_offset, retransmission_offset + bytes_consumed);
+        if (bytes_consumed < retransmission_length) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+  if (!stream_map_.contains(
+          QuicUtils::GetCryptoStreamId(connection_->transport_version()))) {
+    return true;
+  }
+  auto& state =
+      stream_map_
+          .find(QuicUtils::GetCryptoStreamId(connection_->transport_version()))
+          ->second;
+  while (!state.pending_retransmissions.Empty()) {
+    connection_->SetTransmissionType(HANDSHAKE_RETRANSMISSION);
+    QuicIntervalSet<QuicStreamOffset> retransmission(
+        state.pending_retransmissions.begin()->min(),
+        state.pending_retransmissions.begin()->max());
+    EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
+    for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+      if (retransmission.Intersects(crypto_bytes_transferred_[i])) {
+        retransmission_encryption_level = static_cast<EncryptionLevel>(i);
+        retransmission.Intersection(crypto_bytes_transferred_[i]);
+        break;
+      }
+    }
+    QuicStreamOffset retransmission_offset = retransmission.begin()->min();
+    QuicByteCount retransmission_length =
+        retransmission.begin()->max() - retransmission.begin()->min();
+    EncryptionLevel current_encryption_level = connection_->encryption_level();
+    // Set appropriate encryption level.
+    connection_->SetDefaultEncryptionLevel(retransmission_encryption_level);
+    QuicConsumedData consumed = connection_->SendStreamData(
+        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
+        retransmission_length, retransmission_offset, NO_FIN);
+    // Restore encryption level.
+    connection_->SetDefaultEncryptionLevel(current_encryption_level);
+    state.pending_retransmissions.Difference(
+        retransmission_offset, retransmission_offset + consumed.bytes_consumed);
+    if (consumed.bytes_consumed < retransmission_length) {
+      break;
+    }
+  }
+  return state.pending_retransmissions.Empty();
+}
+
+bool SimpleSessionNotifier::RetransmitLostStreamData() {
+  for (auto& pair : stream_map_) {
+    StreamState& state = pair.second;
+    QuicConsumedData consumed(0, false);
+    while (!state.pending_retransmissions.Empty() || state.fin_lost) {
+      connection_->SetTransmissionType(LOSS_RETRANSMISSION);
+      if (state.pending_retransmissions.Empty()) {
+        QUIC_DVLOG(1) << "stream " << pair.first
+                      << " retransmits fin only frame.";
+        consumed =
+            connection_->SendStreamData(pair.first, 0, state.bytes_sent, FIN);
+        state.fin_lost = !consumed.fin_consumed;
+        if (state.fin_lost) {
+          QUIC_DLOG(INFO) << "Connection is write blocked";
+          return false;
+        }
+      } else {
+        QuicStreamOffset offset = state.pending_retransmissions.begin()->min();
+        QuicByteCount length = state.pending_retransmissions.begin()->max() -
+                               state.pending_retransmissions.begin()->min();
+        const bool can_bundle_fin =
+            state.fin_lost && (offset + length == state.bytes_sent);
+        consumed = connection_->SendStreamData(pair.first, length, offset,
+                                               can_bundle_fin ? FIN : NO_FIN);
+        QUIC_DVLOG(1) << "stream " << pair.first
+                      << " tries to retransmit stream data [" << offset << ", "
+                      << offset + length << ") and fin: " << can_bundle_fin
+                      << ", consumed: " << consumed;
+        state.pending_retransmissions.Difference(
+            offset, offset + consumed.bytes_consumed);
+        if (consumed.fin_consumed) {
+          state.fin_lost = false;
+        }
+        if (length > consumed.bytes_consumed ||
+            (can_bundle_fin && !consumed.fin_consumed)) {
+          QUIC_DVLOG(1) << "Connection is write blocked";
+          break;
+        }
+      }
+    }
+  }
+  return !HasLostStreamData();
+}
+
+bool SimpleSessionNotifier::WriteBufferedCryptoData() {
+  for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+    const StreamState& state = crypto_state_[i];
+    QuicIntervalSet<QuicStreamOffset> buffered_crypto_data(0,
+                                                           state.bytes_total);
+    buffered_crypto_data.Difference(crypto_bytes_transferred_[i]);
+    for (const auto& interval : buffered_crypto_data) {
+      size_t bytes_written = connection_->SendCryptoData(
+          static_cast<EncryptionLevel>(i), interval.Length(), interval.min());
+      crypto_state_[i].bytes_sent += bytes_written;
+      crypto_bytes_transferred_[i].Add(interval.min(),
+                                       interval.min() + bytes_written);
+      if (bytes_written < interval.Length()) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool SimpleSessionNotifier::WriteBufferedControlFrames() {
+  while (HasBufferedControlFrames()) {
+    QuicFrame frame_to_send =
+        control_frames_.at(least_unsent_ - least_unacked_);
+    QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
+    connection_->SetTransmissionType(NOT_RETRANSMISSION);
+    if (!connection_->SendControlFrame(copy)) {
+      // Connection is write blocked.
+      DeleteFrame(&copy);
+      break;
+    }
+    ++least_unsent_;
+  }
+  return !HasBufferedControlFrames();
+}
+
+bool SimpleSessionNotifier::HasBufferedControlFrames() const {
+  return least_unsent_ < least_unacked_ + control_frames_.size();
+}
+
+bool SimpleSessionNotifier::HasBufferedStreamData() const {
+  for (const auto& pair : stream_map_) {
+    const auto& state = pair.second;
+    if (state.bytes_total > state.bytes_sent ||
+        (state.fin_buffered && !state.fin_sent)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool SimpleSessionNotifier::StreamIsWaitingForAcks(QuicStreamId id) const {
+  if (!stream_map_.contains(id)) {
+    return false;
+  }
+  const StreamState& state = stream_map_.find(id)->second;
+  return !state.bytes_acked.Contains(0, state.bytes_sent) ||
+         state.fin_outstanding;
+}
+
+bool SimpleSessionNotifier::StreamHasBufferedData(QuicStreamId id) const {
+  if (!stream_map_.contains(id)) {
+    return false;
+  }
+  const StreamState& state = stream_map_.find(id)->second;
+  return state.bytes_total > state.bytes_sent ||
+         (state.fin_buffered && !state.fin_sent);
+}
+
+bool SimpleSessionNotifier::HasLostStreamData() const {
+  for (const auto& pair : stream_map_) {
+    const auto& state = pair.second;
+    if (!state.pending_retransmissions.Empty() || state.fin_lost) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simple_session_notifier.h b/quiche/quic/test_tools/simple_session_notifier.h
new file mode 100644
index 0000000..a78fe1c
--- /dev/null
+++ b/quiche/quic/test_tools/simple_session_notifier.h
@@ -0,0 +1,170 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/session_notifier_interface.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+class QuicConnection;
+
+namespace test {
+
+// SimpleSessionNotifier implements the basic functionalities of a session, and
+// it manages stream data and control frames.
+class SimpleSessionNotifier : public SessionNotifierInterface {
+ public:
+  explicit SimpleSessionNotifier(QuicConnection* connection);
+  ~SimpleSessionNotifier() override;
+
+  // Tries to write stream data and returns data consumed.
+  QuicConsumedData WriteOrBufferData(QuicStreamId id,
+                                     QuicByteCount data_length,
+                                     StreamSendingState state);
+
+  // Tries to write RST_STREAM_FRAME.
+  void WriteOrBufferRstStream(QuicStreamId id,
+                              QuicRstStreamErrorCode error,
+                              QuicStreamOffset bytes_written);
+
+  // Tries to write WINDOW_UPDATE.
+  void WriteOrBufferWindowUpate(QuicStreamId id, QuicStreamOffset byte_offset);
+
+  // Tries to write PING.
+  void WriteOrBufferPing();
+
+  // Tries to write ACK_FREQUENCY.
+  void WriteOrBufferAckFrequency(
+      const QuicAckFrequencyFrame& ack_frequency_frame);
+
+  // Tries to write CRYPTO data and returns the number of bytes written.
+  size_t WriteCryptoData(EncryptionLevel level,
+                         QuicByteCount data_length,
+                         QuicStreamOffset offset);
+
+  // Neuters unencrypted data of crypto stream.
+  void NeuterUnencryptedData();
+
+  // Called when connection_ becomes writable.
+  void OnCanWrite();
+
+  // Called to reset stream.
+  void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
+
+  // Returns true if there are 1) unsent control frames and stream data, or 2)
+  // lost control frames and stream data.
+  bool WillingToWrite() const;
+
+  // Number of sent stream bytes. Please note, this does not count
+  // retransmissions.
+  QuicByteCount StreamBytesSent() const;
+
+  // Number of stream bytes waiting to be sent for the first time.
+  QuicByteCount StreamBytesToSend() const;
+
+  // Returns true if there is any stream data waiting to be sent for the first
+  // time.
+  bool HasBufferedStreamData() const;
+
+  // Returns true if stream |id| has any outstanding data.
+  bool StreamIsWaitingForAcks(QuicStreamId id) const;
+
+  // SessionNotifierInterface methods:
+  bool OnFrameAcked(const QuicFrame& frame,
+                    QuicTime::Delta ack_delay_time,
+                    QuicTime receive_timestamp) override;
+  void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
+  void OnFrameLost(const QuicFrame& frame) override;
+  bool RetransmitFrames(const QuicFrames& frames,
+                        TransmissionType type) override;
+  bool IsFrameOutstanding(const QuicFrame& frame) const override;
+  bool HasUnackedCryptoData() const override;
+  bool HasUnackedStreamData() const override;
+  bool HasLostStreamData() const;
+
+ private:
+  struct StreamState {
+    StreamState();
+    ~StreamState();
+
+    // Total number of bytes.
+    QuicByteCount bytes_total;
+    // Number of sent bytes.
+    QuicByteCount bytes_sent;
+    // Record of acked offsets.
+    QuicIntervalSet<QuicStreamOffset> bytes_acked;
+    // Data considered as lost and needs to be retransmitted.
+    QuicIntervalSet<QuicStreamOffset> pending_retransmissions;
+
+    bool fin_buffered;
+    bool fin_sent;
+    bool fin_outstanding;
+    bool fin_lost;
+  };
+
+  friend std::ostream& operator<<(std::ostream& os, const StreamState& s);
+
+  using StreamMap = absl::flat_hash_map<QuicStreamId, StreamState>;
+
+  void OnStreamDataConsumed(QuicStreamId id,
+                            QuicStreamOffset offset,
+                            QuicByteCount data_length,
+                            bool fin);
+
+  bool OnControlFrameAcked(const QuicFrame& frame);
+
+  void OnControlFrameLost(const QuicFrame& frame);
+
+  bool RetransmitLostControlFrames();
+
+  bool RetransmitLostCryptoData();
+
+  bool RetransmitLostStreamData();
+
+  bool WriteBufferedControlFrames();
+
+  bool WriteBufferedCryptoData();
+
+  bool IsControlFrameOutstanding(const QuicFrame& frame) const;
+
+  bool HasBufferedControlFrames() const;
+
+  bool StreamHasBufferedData(QuicStreamId id) const;
+
+  quiche::QuicheCircularDeque<QuicFrame> control_frames_;
+
+  quiche::QuicheLinkedHashMap<QuicControlFrameId, bool> lost_control_frames_;
+
+  // Id of latest saved control frame. 0 if no control frame has been saved.
+  QuicControlFrameId last_control_frame_id_;
+
+  // The control frame at the 0th index of control_frames_.
+  QuicControlFrameId least_unacked_;
+
+  // ID of the least unsent control frame.
+  QuicControlFrameId least_unsent_;
+
+  StreamMap stream_map_;
+
+  // Transferred crypto bytes according to encryption levels.
+  QuicIntervalSet<QuicStreamOffset>
+      crypto_bytes_transferred_[NUM_ENCRYPTION_LEVELS];
+
+  StreamState crypto_state_[NUM_ENCRYPTION_LEVELS];
+
+  QuicConnection* connection_;
+};
+
+}  // namespace test
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
diff --git a/quiche/quic/test_tools/simple_session_notifier_test.cc b/quiche/quic/test_tools/simple_session_notifier_test.cc
new file mode 100644
index 0000000..77e3bf7
--- /dev/null
+++ b/quiche/quic/test_tools/simple_session_notifier_test.cc
@@ -0,0 +1,370 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simple_session_notifier.h"
+
+#include <utility>
+
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simple_data_producer.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
+ public:
+  MockQuicConnectionWithSendStreamData(MockQuicConnectionHelper* helper,
+                                       MockAlarmFactory* alarm_factory,
+                                       Perspective perspective)
+      : MockQuicConnection(helper, alarm_factory, perspective) {}
+
+  MOCK_METHOD(QuicConsumedData,
+              SendStreamData,
+              (QuicStreamId id,
+               size_t write_length,
+               QuicStreamOffset offset,
+               StreamSendingState state),
+              (override));
+};
+
+class SimpleSessionNotifierTest : public QuicTest {
+ public:
+  SimpleSessionNotifierTest()
+      : connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT),
+        notifier_(&connection_) {
+    connection_.set_visitor(&visitor_);
+    connection_.SetSessionNotifier(&notifier_);
+    EXPECT_FALSE(notifier_.WillingToWrite());
+    EXPECT_EQ(0u, notifier_.StreamBytesSent());
+    EXPECT_FALSE(notifier_.HasBufferedStreamData());
+  }
+
+  bool ControlFrameConsumed(const QuicFrame& frame) {
+    DeleteFrame(&const_cast<QuicFrame&>(frame));
+    return true;
+  }
+
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnectionVisitor visitor_;
+  StrictMock<MockQuicConnectionWithSendStreamData> connection_;
+  SimpleSessionNotifier notifier_;
+};
+
+TEST_F(SimpleSessionNotifierTest, WriteOrBufferData) {
+  InSequence s;
+  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(1024, false)));
+  notifier_.WriteOrBufferData(3, 1024, NO_FIN);
+  EXPECT_EQ(0u, notifier_.StreamBytesToSend());
+  EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  notifier_.WriteOrBufferData(5, 512, NO_FIN);
+  EXPECT_FALSE(notifier_.WillingToWrite());
+  // Connection is blocked.
+  EXPECT_CALL(connection_, SendStreamData(5, 512, 512, FIN))
+      .WillOnce(Return(QuicConsumedData(256, false)));
+  notifier_.WriteOrBufferData(5, 512, FIN);
+  EXPECT_TRUE(notifier_.WillingToWrite());
+  EXPECT_EQ(1792u, notifier_.StreamBytesSent());
+  EXPECT_EQ(256u, notifier_.StreamBytesToSend());
+  EXPECT_TRUE(notifier_.HasBufferedStreamData());
+
+  // New data cannot be sent as connection is blocked.
+  EXPECT_CALL(connection_, SendStreamData(7, 1024, 0, FIN)).Times(0);
+  notifier_.WriteOrBufferData(7, 1024, FIN);
+  EXPECT_EQ(1792u, notifier_.StreamBytesSent());
+}
+
+TEST_F(SimpleSessionNotifierTest, WriteOrBufferRstStream) {
+  InSequence s;
+  EXPECT_CALL(connection_, SendStreamData(5, 1024, 0, FIN))
+      .WillOnce(Return(QuicConsumedData(1024, true)));
+  notifier_.WriteOrBufferData(5, 1024, FIN);
+  EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
+  EXPECT_TRUE(notifier_.HasUnackedStreamData());
+
+  // Reset stream 5 with no error.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillRepeatedly(
+          Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 1024);
+  // Verify stream 5 is waiting for acks.
+  EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
+  EXPECT_TRUE(notifier_.HasUnackedStreamData());
+
+  // Reset stream 5 with error.
+  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
+  EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(5));
+  EXPECT_FALSE(notifier_.HasUnackedStreamData());
+}
+
+TEST_F(SimpleSessionNotifierTest, WriteOrBufferPing) {
+  InSequence s;
+  // Write ping when connection is not write blocked.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillRepeatedly(
+          Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  notifier_.WriteOrBufferPing();
+  EXPECT_EQ(0u, notifier_.StreamBytesToSend());
+  EXPECT_FALSE(notifier_.WillingToWrite());
+
+  // Write stream data and cause the connection to be write blocked.
+  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(1024, false)));
+  notifier_.WriteOrBufferData(3, 1024, NO_FIN);
+  EXPECT_EQ(0u, notifier_.StreamBytesToSend());
+  EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(256, false)));
+  notifier_.WriteOrBufferData(5, 512, NO_FIN);
+  EXPECT_TRUE(notifier_.WillingToWrite());
+
+  // Connection is blocked.
+  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
+  notifier_.WriteOrBufferPing();
+}
+
+TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    // This test writes crypto data through crypto streams. It won't work when
+    // crypto frames are used instead.
+    return;
+  }
+  InSequence s;
+  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
+                                              connection_.transport_version()),
+                                          1024, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(1024, false)));
+  notifier_.WriteOrBufferData(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
+      NO_FIN);
+  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
+                                              connection_.transport_version()),
+                                          1024, 1024, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(1024, false)));
+  notifier_.WriteOrBufferData(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
+      NO_FIN);
+  // Ack [1024, 2048).
+  QuicStreamFrame stream_frame(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
+      1024, 1024);
+  notifier_.OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
+                         QuicTime::Zero());
+  EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version())));
+  EXPECT_TRUE(notifier_.HasUnackedStreamData());
+
+  // Neuters unencrypted data.
+  notifier_.NeuterUnencryptedData();
+  EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version())));
+  EXPECT_FALSE(notifier_.HasUnackedStreamData());
+}
+
+TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    // This test writes crypto data through crypto streams. It won't work when
+    // crypto frames are used instead.
+    return;
+  }
+  InSequence s;
+  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
+                                              connection_.transport_version()),
+                                          1024, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(1024, false)));
+  notifier_.WriteOrBufferData(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
+      NO_FIN);
+
+  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
+                                              connection_.transport_version()),
+                                          1024, 1024, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(1024, false)));
+  notifier_.WriteOrBufferData(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
+      NO_FIN);
+  // Send stream 3 [0, 1024) and connection is blocked.
+  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  notifier_.WriteOrBufferData(3, 1024, FIN);
+  // Send stream 5 [0, 1024).
+  EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
+  notifier_.WriteOrBufferData(5, 1024, NO_FIN);
+  // Reset stream 5 with error.
+  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
+  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
+
+  // Lost crypto data [500, 1500) and stream 3 [0, 512).
+  QuicStreamFrame frame1(
+      QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 500,
+      1000);
+  QuicStreamFrame frame2(3, false, 0, 512);
+  notifier_.OnFrameLost(QuicFrame(frame1));
+  notifier_.OnFrameLost(QuicFrame(frame2));
+
+  // Connection becomes writable.
+  // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
+  // they are in different encryption levels.
+  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
+                                              connection_.transport_version()),
+                                          524, 500, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(524, false)));
+  EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
+                                              connection_.transport_version()),
+                                          476, 1024, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(476, false)));
+  // Lost stream 3 data gets retransmitted.
+  EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  // Buffered control frames get sent.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  // Buffered stream 3 data [512, 1024) gets sent.
+  EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
+      .WillOnce(Return(QuicConsumedData(512, true)));
+  notifier_.OnCanWrite();
+  EXPECT_FALSE(notifier_.WillingToWrite());
+}
+
+TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    return;
+  }
+  SimpleDataProducer producer;
+  connection_.SetDataProducer(&producer);
+  InSequence s;
+  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(connection_, CloseConnection(QUIC_PACKET_WRITE_ERROR, _, _));
+  std::string crypto_data1(1024, 'a');
+  producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, crypto_data1);
+  std::string crypto_data2(524, 'a');
+  producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, crypto_data2);
+  notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
+  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
+                                                    Perspective::IS_CLIENT));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  std::string crypto_data3(1024, 'a');
+  producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, crypto_data3);
+  notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
+  // Send stream 3 [0, 1024) and connection is blocked.
+  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  notifier_.WriteOrBufferData(3, 1024, FIN);
+  // Send stream 5 [0, 1024).
+  EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
+  notifier_.WriteOrBufferData(5, 1024, NO_FIN);
+  // Reset stream 5 with error.
+  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
+  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
+
+  // Lost crypto data [500, 1500) and stream 3 [0, 512).
+  QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
+  QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
+  QuicStreamFrame stream3_frame(3, false, 0, 512);
+  notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
+  notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
+  notifier_.OnFrameLost(QuicFrame(stream3_frame));
+
+  // Connection becomes writable.
+  // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
+  // they are in different encryption levels.
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  // Lost stream 3 data gets retransmitted.
+  EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  // Buffered control frames get sent.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  // Buffered stream 3 data [512, 1024) gets sent.
+  EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
+      .WillOnce(Return(QuicConsumedData(512, true)));
+  notifier_.OnCanWrite();
+  EXPECT_FALSE(notifier_.WillingToWrite());
+}
+
+TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
+  InSequence s;
+  connection_.SetEncrypter(
+      ENCRYPTION_FORWARD_SECURE,
+      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+  // Send stream 3 data [0, 10) and fin.
+  EXPECT_CALL(connection_, SendStreamData(3, 10, 0, FIN))
+      .WillOnce(Return(QuicConsumedData(10, true)));
+  notifier_.WriteOrBufferData(3, 10, FIN);
+  QuicStreamFrame frame1(3, true, 0, 10);
+  // Send stream 5 [0, 10) and fin.
+  EXPECT_CALL(connection_, SendStreamData(5, 10, 0, FIN))
+      .WillOnce(Return(QuicConsumedData(10, true)));
+  notifier_.WriteOrBufferData(5, 10, FIN);
+  QuicStreamFrame frame2(5, true, 0, 10);
+  // Reset stream 5 with no error.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 10);
+
+  // Ack stream 3 [3, 7), and stream 5 [8, 10).
+  QuicStreamFrame ack_frame1(3, false, 3, 4);
+  QuicStreamFrame ack_frame2(5, false, 8, 2);
+  notifier_.OnFrameAcked(QuicFrame(ack_frame1), QuicTime::Delta::Zero(),
+                         QuicTime::Zero());
+  notifier_.OnFrameAcked(QuicFrame(ack_frame2), QuicTime::Delta::Zero(),
+                         QuicTime::Zero());
+  EXPECT_FALSE(notifier_.WillingToWrite());
+
+  // Force to send.
+  QuicRstStreamFrame rst_stream(1, 5, QUIC_STREAM_NO_ERROR, 10);
+  QuicFrames frames;
+  frames.push_back(QuicFrame(frame2));
+  frames.push_back(QuicFrame(&rst_stream));
+  frames.push_back(QuicFrame(frame1));
+  // stream 5 data [0, 8), fin only are retransmitted.
+  EXPECT_CALL(connection_, SendStreamData(5, 8, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(8, false)));
+  EXPECT_CALL(connection_, SendStreamData(5, 0, 10, FIN))
+      .WillOnce(Return(QuicConsumedData(0, true)));
+  // rst_stream is retransmitted.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  // stream 3 data [0, 3) is retransmitted and connection is blocked.
+  EXPECT_CALL(connection_, SendStreamData(3, 3, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(2, false)));
+  notifier_.RetransmitFrames(frames, RTO_RETRANSMISSION);
+  EXPECT_FALSE(notifier_.WillingToWrite());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/test_tools/simulator/README.md b/quiche/quic/test_tools/simulator/README.md
similarity index 100%
rename from quic/test_tools/simulator/README.md
rename to quiche/quic/test_tools/simulator/README.md
diff --git a/quiche/quic/test_tools/simulator/actor.cc b/quiche/quic/test_tools/simulator/actor.cc
new file mode 100644
index 0000000..5d28cab
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/actor.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/actor.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+namespace quic {
+namespace simulator {
+
+Actor::Actor(Simulator* simulator, std::string name)
+    : simulator_(simulator),
+      clock_(simulator->GetClock()),
+      name_(std::move(name)) {
+  simulator_->AddActor(this);
+}
+
+Actor::~Actor() {
+  simulator_->RemoveActor(this);
+}
+
+void Actor::Schedule(QuicTime next_tick) {
+  simulator_->Schedule(this, next_tick);
+}
+
+void Actor::Unschedule() {
+  simulator_->Unschedule(this);
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/actor.h b/quiche/quic/test_tools/simulator/actor.h
new file mode 100644
index 0000000..3747322
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/actor.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
+
+#include <string>
+
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+namespace simulator {
+
+class Simulator;
+
+// Actor is the base class for all participants of the simulation which can
+// schedule events to be triggered at the specified time.  Every actor has a
+// name assigned to it, which can be used for debugging and addressing purposes.
+//
+// The Actor object is scheduled as follows:
+// 1. Every Actor object appears at most once in the event queue, for one
+//    specific time.
+// 2. Actor is scheduled by calling Schedule() method.
+// 3. If Schedule() method is called with multiple different times specified,
+//    Act() method will be called at the earliest time specified.
+// 4. Before Act() is called, the Actor is removed from the event queue.  Act()
+//    will not be called again unless Schedule() is called.
+class Actor {
+ public:
+  Actor(Simulator* simulator, std::string name);
+  virtual ~Actor();
+
+  // Trigger all the events the actor can potentially handle at this point.
+  // Before Act() is called, the actor is removed from the event queue, and has
+  // to schedule the next call manually.
+  virtual void Act() = 0;
+
+  std::string name() const { return name_; }
+  Simulator* simulator() const { return simulator_; }
+
+ protected:
+  // Calls Schedule() on the associated simulator.
+  void Schedule(QuicTime next_tick);
+
+  // Calls Unschedule() on the associated simulator.
+  void Unschedule();
+
+  Simulator* simulator_;
+  const QuicClock* clock_;
+  std::string name_;
+
+ private:
+  // Since the Actor object registers itself with a simulator using a pointer to
+  // itself, do not allow it to be moved.
+  Actor(Actor&&) = delete;
+  Actor(const Actor&) = delete;
+  Actor& operator=(const Actor&) = delete;
+  Actor& operator=(Actor&&) = delete;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ACTOR_H_
diff --git a/quiche/quic/test_tools/simulator/alarm_factory.cc b/quiche/quic/test_tools/simulator/alarm_factory.cc
new file mode 100644
index 0000000..4c9f811
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/alarm_factory.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/alarm_factory.h"
+
+#include "absl/strings/str_format.h"
+#include "quiche/quic/core/quic_alarm.h"
+
+namespace quic {
+namespace simulator {
+
+// Alarm is an implementation of QuicAlarm which can schedule alarms in the
+// simulation timeline.
+class Alarm : public QuicAlarm {
+ public:
+  Alarm(Simulator* simulator,
+        std::string name,
+        QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+      : QuicAlarm(std::move(delegate)), adapter_(simulator, name, this) {}
+  ~Alarm() override {}
+
+  void SetImpl() override {
+    QUICHE_DCHECK(deadline().IsInitialized());
+    adapter_.Set(deadline());
+  }
+
+  void CancelImpl() override { adapter_.Cancel(); }
+
+ private:
+  // An adapter class triggering a QuicAlarm using a simulation time system.
+  // An adapter is required here because neither Actor nor QuicAlarm are pure
+  // interfaces.
+  class Adapter : public Actor {
+   public:
+    Adapter(Simulator* simulator, std::string name, Alarm* parent)
+        : Actor(simulator, name), parent_(parent) {}
+    ~Adapter() override {}
+
+    void Set(QuicTime time) { Schedule(std::max(time, clock_->Now())); }
+    void Cancel() { Unschedule(); }
+
+    void Act() override {
+      QUICHE_DCHECK(clock_->Now() >= parent_->deadline());
+      parent_->Fire();
+    }
+
+   private:
+    Alarm* parent_;
+  };
+  Adapter adapter_;
+};
+
+AlarmFactory::AlarmFactory(Simulator* simulator, std::string name)
+    : simulator_(simulator), name_(std::move(name)), counter_(0) {}
+
+AlarmFactory::~AlarmFactory() {}
+
+std::string AlarmFactory::GetNewAlarmName() {
+  ++counter_;
+  return absl::StrFormat("%s (alarm %i)", name_, counter_);
+}
+
+QuicAlarm* AlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
+  return new Alarm(simulator_, GetNewAlarmName(),
+                   QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+}
+
+QuicArenaScopedPtr<QuicAlarm> AlarmFactory::CreateAlarm(
+    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+    QuicConnectionArena* arena) {
+  if (arena != nullptr) {
+    return arena->New<Alarm>(simulator_, GetNewAlarmName(),
+                             std::move(delegate));
+  }
+  return QuicArenaScopedPtr<QuicAlarm>(
+      new Alarm(simulator_, GetNewAlarmName(), std::move(delegate)));
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/alarm_factory.h b/quiche/quic/test_tools/simulator/alarm_factory.h
new file mode 100644
index 0000000..2d6f183
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/alarm_factory.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
+
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/test_tools/simulator/actor.h"
+
+namespace quic {
+namespace simulator {
+
+// AlarmFactory allows to schedule QuicAlarms using the simulation event queue.
+class AlarmFactory : public QuicAlarmFactory {
+ public:
+  AlarmFactory(Simulator* simulator, std::string name);
+  AlarmFactory(const AlarmFactory&) = delete;
+  AlarmFactory& operator=(const AlarmFactory&) = delete;
+  ~AlarmFactory() override;
+
+  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+      QuicConnectionArena* arena) override;
+
+ private:
+  // Automatically generate a name for a new alarm.
+  std::string GetNewAlarmName();
+
+  Simulator* simulator_;
+  std::string name_;
+  int counter_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_ALARM_FACTORY_H_
diff --git a/quiche/quic/test_tools/simulator/link.cc b/quiche/quic/test_tools/simulator/link.cc
new file mode 100644
index 0000000..ac2f56c
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/link.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/link.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+namespace quic {
+namespace simulator {
+
+// Parameters for random noise delay.
+const uint64_t kMaxRandomDelayUs = 10;
+
+OneWayLink::OneWayLink(Simulator* simulator,
+                       std::string name,
+                       UnconstrainedPortInterface* sink,
+                       QuicBandwidth bandwidth,
+                       QuicTime::Delta propagation_delay)
+    : Actor(simulator, name),
+      sink_(sink),
+      bandwidth_(bandwidth),
+      propagation_delay_(propagation_delay),
+      next_write_at_(QuicTime::Zero()) {}
+
+OneWayLink::~OneWayLink() {}
+
+OneWayLink::QueuedPacket::QueuedPacket(std::unique_ptr<Packet> packet,
+                                       QuicTime dequeue_time)
+    : packet(std::move(packet)), dequeue_time(dequeue_time) {}
+
+OneWayLink::QueuedPacket::QueuedPacket(QueuedPacket&& other) = default;
+
+OneWayLink::QueuedPacket::~QueuedPacket() {}
+
+void OneWayLink::AcceptPacket(std::unique_ptr<Packet> packet) {
+  QUICHE_DCHECK(TimeUntilAvailable().IsZero());
+  QuicTime::Delta transfer_time = bandwidth_.TransferTime(packet->size);
+  next_write_at_ = clock_->Now() + transfer_time;
+
+  packets_in_transit_.emplace_back(
+      std::move(packet),
+      // Ensure that packets are delivered in order.
+      std::max(
+          next_write_at_ + propagation_delay_ + GetRandomDelay(transfer_time),
+          packets_in_transit_.empty()
+              ? QuicTime::Zero()
+              : packets_in_transit_.back().dequeue_time));
+  ScheduleNextPacketDeparture();
+}
+
+QuicTime::Delta OneWayLink::TimeUntilAvailable() {
+  const QuicTime now = clock_->Now();
+  if (next_write_at_ <= now) {
+    return QuicTime::Delta::Zero();
+  }
+
+  return next_write_at_ - now;
+}
+
+void OneWayLink::Act() {
+  QUICHE_DCHECK(!packets_in_transit_.empty());
+  QUICHE_DCHECK(packets_in_transit_.front().dequeue_time >= clock_->Now());
+
+  sink_->AcceptPacket(std::move(packets_in_transit_.front().packet));
+  packets_in_transit_.pop_front();
+
+  ScheduleNextPacketDeparture();
+}
+
+void OneWayLink::ScheduleNextPacketDeparture() {
+  if (packets_in_transit_.empty()) {
+    return;
+  }
+
+  Schedule(packets_in_transit_.front().dequeue_time);
+}
+
+QuicTime::Delta OneWayLink::GetRandomDelay(QuicTime::Delta transfer_time) {
+  if (!simulator_->enable_random_delays()) {
+    return QuicTime::Delta::Zero();
+  }
+
+  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(
+      simulator_->GetRandomGenerator()->RandUint64() % (kMaxRandomDelayUs + 1));
+  // Have an upper bound on the delay to ensure packets do not go out of order.
+  delta = std::min(delta, transfer_time * 0.5);
+  return delta;
+}
+
+SymmetricLink::SymmetricLink(Simulator* simulator,
+                             std::string name,
+                             UnconstrainedPortInterface* sink_a,
+                             UnconstrainedPortInterface* sink_b,
+                             QuicBandwidth bandwidth,
+                             QuicTime::Delta propagation_delay)
+    : a_to_b_link_(simulator,
+                   absl::StrCat(name, " (A-to-B)"),
+                   sink_b,
+                   bandwidth,
+                   propagation_delay),
+      b_to_a_link_(simulator,
+                   absl::StrCat(name, " (B-to-A)"),
+                   sink_a,
+                   bandwidth,
+                   propagation_delay) {}
+
+SymmetricLink::SymmetricLink(Endpoint* endpoint_a,
+                             Endpoint* endpoint_b,
+                             QuicBandwidth bandwidth,
+                             QuicTime::Delta propagation_delay)
+    : SymmetricLink(endpoint_a->simulator(),
+                    absl::StrFormat("Link [%s]<->[%s]",
+                                    endpoint_a->name(),
+                                    endpoint_b->name()),
+                    endpoint_a->GetRxPort(),
+                    endpoint_b->GetRxPort(),
+                    bandwidth,
+                    propagation_delay) {
+  endpoint_a->SetTxPort(&a_to_b_link_);
+  endpoint_b->SetTxPort(&b_to_a_link_);
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/link.h b/quiche/quic/test_tools/simulator/link.h
new file mode 100644
index 0000000..a534876
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/link.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
+
+#include <utility>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_bandwidth.h"
+#include "quiche/quic/test_tools/simulator/actor.h"
+#include "quiche/quic/test_tools/simulator/port.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+namespace simulator {
+
+// A reliable simplex link between two endpoints with constrained bandwidth.  A
+// few microseconds of random delay are added for every packet to avoid
+// synchronization issues.
+class OneWayLink : public Actor, public ConstrainedPortInterface {
+ public:
+  OneWayLink(Simulator* simulator,
+             std::string name,
+             UnconstrainedPortInterface* sink,
+             QuicBandwidth bandwidth,
+             QuicTime::Delta propagation_delay);
+  OneWayLink(const OneWayLink&) = delete;
+  OneWayLink& operator=(const OneWayLink&) = delete;
+  ~OneWayLink() override;
+
+  void AcceptPacket(std::unique_ptr<Packet> packet) override;
+  QuicTime::Delta TimeUntilAvailable() override;
+  void Act() override;
+
+  QuicBandwidth bandwidth() const { return bandwidth_; }
+  void set_bandwidth(QuicBandwidth new_bandwidth) {
+    bandwidth_ = new_bandwidth;
+  }
+
+ protected:
+  // Get the value of a random delay imposed on each packet.  By default, this
+  // is a short random delay in order to avoid artifical synchronization
+  // artifacts during the simulation.  Subclasses may override this behavior
+  // (for example, to provide a random component of delay).
+  virtual QuicTime::Delta GetRandomDelay(QuicTime::Delta transfer_time);
+
+ private:
+  struct QueuedPacket {
+    std::unique_ptr<Packet> packet;
+    QuicTime dequeue_time;
+
+    QueuedPacket(std::unique_ptr<Packet> packet, QuicTime dequeue_time);
+    QueuedPacket(QueuedPacket&& other);
+    ~QueuedPacket();
+  };
+
+  // Schedule the next packet to be egressed out of the link if there are
+  // packets on the link.
+  void ScheduleNextPacketDeparture();
+
+  UnconstrainedPortInterface* sink_;
+  quiche::QuicheCircularDeque<QueuedPacket> packets_in_transit_;
+
+  QuicBandwidth bandwidth_;
+  const QuicTime::Delta propagation_delay_;
+
+  QuicTime next_write_at_;
+};
+
+// A full-duplex link between two endpoints, functionally equivalent to two
+// OneWayLink objects tied together.
+class SymmetricLink {
+ public:
+  SymmetricLink(Simulator* simulator,
+                std::string name,
+                UnconstrainedPortInterface* sink_a,
+                UnconstrainedPortInterface* sink_b,
+                QuicBandwidth bandwidth,
+                QuicTime::Delta propagation_delay);
+  SymmetricLink(Endpoint* endpoint_a,
+                Endpoint* endpoint_b,
+                QuicBandwidth bandwidth,
+                QuicTime::Delta propagation_delay);
+  SymmetricLink(const SymmetricLink&) = delete;
+  SymmetricLink& operator=(const SymmetricLink&) = delete;
+
+  QuicBandwidth bandwidth() { return a_to_b_link_.bandwidth(); }
+  void set_bandwidth(QuicBandwidth new_bandwidth) {
+    a_to_b_link_.set_bandwidth(new_bandwidth);
+    b_to_a_link_.set_bandwidth(new_bandwidth);
+  }
+
+ private:
+  OneWayLink a_to_b_link_;
+  OneWayLink b_to_a_link_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_LINK_H_
diff --git a/quiche/quic/test_tools/simulator/packet_filter.cc b/quiche/quic/test_tools/simulator/packet_filter.cc
new file mode 100644
index 0000000..68f90b0
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/packet_filter.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/packet_filter.h"
+
+namespace quic {
+namespace simulator {
+
+PacketFilter::PacketFilter(Simulator* simulator,
+                           std::string name,
+                           Endpoint* input)
+    : Endpoint(simulator, name), input_(input) {
+  input_->SetTxPort(this);
+}
+
+PacketFilter::~PacketFilter() {}
+
+void PacketFilter::AcceptPacket(std::unique_ptr<Packet> packet) {
+  if (FilterPacket(*packet)) {
+    output_tx_port_->AcceptPacket(std::move(packet));
+  }
+}
+
+QuicTime::Delta PacketFilter::TimeUntilAvailable() {
+  return output_tx_port_->TimeUntilAvailable();
+}
+
+void PacketFilter::Act() {}
+
+UnconstrainedPortInterface* PacketFilter::GetRxPort() {
+  return input_->GetRxPort();
+}
+
+void PacketFilter::SetTxPort(ConstrainedPortInterface* port) {
+  output_tx_port_ = port;
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/packet_filter.h b/quiche/quic/test_tools/simulator/packet_filter.h
new file mode 100644
index 0000000..cf57bb0
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/packet_filter.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
+
+#include "quiche/quic/test_tools/simulator/port.h"
+
+namespace quic {
+namespace simulator {
+
+// Packet filter allows subclasses to filter out the packets that enter the
+// input port and exit the output port.  Packets in the other direction are
+// always passed through.
+//
+// The filter wraps around the input endpoint, and exposes the resulting
+// filtered endpoint via the output() method.  For example, if initially there
+// are two endpoints, A and B, connected via a symmetric link:
+//
+//   QuicEndpoint endpoint_a;
+//   QuicEndpoint endpoint_b;
+//
+//   [...]
+//
+//   SymmetricLink a_b_link(&endpoint_a, &endpoint_b, ...);
+//
+// and the goal is to filter the traffic from A to B, then the new invocation
+// would be as follows:
+//
+//   PacketFilter filter(&simulator, "A-to-B packet filter", endpoint_a);
+//   SymmetricLink a_b_link(&filter, &endpoint_b, ...);
+//
+// Note that the filter drops the packet instanteneously, without it ever
+// reaching the output wire.  This means that in a direct endpoint-to-endpoint
+// scenario, whenever the packet is dropped, the link would become immediately
+// available for the next packet.
+class PacketFilter : public Endpoint, public ConstrainedPortInterface {
+ public:
+  // Initialize the filter by wrapping around |input|.  Does not take the
+  // ownership of |input|.
+  PacketFilter(Simulator* simulator, std::string name, Endpoint* input);
+  PacketFilter(const PacketFilter&) = delete;
+  PacketFilter& operator=(const PacketFilter&) = delete;
+  ~PacketFilter() override;
+
+  // Implementation of ConstrainedPortInterface.
+  void AcceptPacket(std::unique_ptr<Packet> packet) override;
+  QuicTime::Delta TimeUntilAvailable() override;
+
+  // Implementation of Endpoint interface methods.
+  UnconstrainedPortInterface* GetRxPort() override;
+  void SetTxPort(ConstrainedPortInterface* port) override;
+
+  // Implementation of Actor interface methods.
+  void Act() override;
+
+ protected:
+  // Returns true if the packet should be passed through, and false if it should
+  // be dropped.  The function is called once per packet, in the order that the
+  // packets arrive, so it is safe for the function to alter the internal state
+  // of the filter.
+  virtual bool FilterPacket(const Packet& packet) = 0;
+
+ private:
+  // The port onto which the filtered packets are egressed.
+  ConstrainedPortInterface* output_tx_port_;
+
+  // The original network endpoint wrapped by the class.
+  Endpoint* input_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PACKET_FILTER_H_
diff --git a/quiche/quic/test_tools/simulator/port.cc b/quiche/quic/test_tools/simulator/port.cc
new file mode 100644
index 0000000..bffc086
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/port.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/port.h"
+
+namespace quic {
+namespace simulator {
+
+Packet::Packet()
+    : source(), destination(), tx_timestamp(QuicTime::Zero()), size(0) {}
+
+Packet::~Packet() {}
+
+Packet::Packet(const Packet& packet) = default;
+
+Endpoint::Endpoint(Simulator* simulator, std::string name)
+    : Actor(simulator, name) {}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/port.h b/quiche/quic/test_tools/simulator/port.h
new file mode 100644
index 0000000..27bac95
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/port.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
+
+#include <string>
+#include <utility>
+
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/test_tools/simulator/actor.h"
+
+namespace quic {
+namespace simulator {
+
+struct Packet {
+  Packet();
+  ~Packet();
+  Packet(const Packet& packet);
+
+  std::string source;
+  std::string destination;
+  QuicTime tx_timestamp;
+
+  std::string contents;
+  QuicByteCount size;
+};
+
+// An interface for anything that accepts packets at arbitrary rate.
+class UnconstrainedPortInterface {
+ public:
+  virtual ~UnconstrainedPortInterface() {}
+  virtual void AcceptPacket(std::unique_ptr<Packet> packet) = 0;
+};
+
+// An interface for any device that accepts packets at a specific rate.
+// Typically one would use a Queue object in order to write into a constrained
+// port.
+class ConstrainedPortInterface {
+ public:
+  virtual ~ConstrainedPortInterface() {}
+
+  // Accept a packet for a port.  TimeUntilAvailable() must be zero before this
+  // method is called.
+  virtual void AcceptPacket(std::unique_ptr<Packet> packet) = 0;
+
+  // Time until write for the next port is available.  Cannot be infinite.
+  virtual QuicTime::Delta TimeUntilAvailable() = 0;
+};
+
+// A convenience class for any network endpoints, i.e. the objects which can
+// both accept and send packets.
+class Endpoint : public Actor {
+ public:
+  virtual UnconstrainedPortInterface* GetRxPort() = 0;
+  virtual void SetTxPort(ConstrainedPortInterface* port) = 0;
+
+ protected:
+  Endpoint(Simulator* simulator, std::string name);
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_PORT_H_
diff --git a/quiche/quic/test_tools/simulator/queue.cc b/quiche/quic/test_tools/simulator/queue.cc
new file mode 100644
index 0000000..2af1ec1
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/queue.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/queue.h"
+
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+namespace quic {
+namespace simulator {
+
+Queue::ListenerInterface::~ListenerInterface() {}
+
+Queue::Queue(Simulator* simulator, std::string name, QuicByteCount capacity)
+    : Actor(simulator, name),
+      capacity_(capacity),
+      bytes_queued_(0),
+      aggregation_threshold_(0),
+      aggregation_timeout_(QuicTime::Delta::Infinite()),
+      current_bundle_(0),
+      current_bundle_bytes_(0),
+      tx_port_(nullptr),
+      listener_(nullptr) {
+  aggregation_timeout_alarm_.reset(simulator_->GetAlarmFactory()->CreateAlarm(
+      new AggregationAlarmDelegate(this)));
+}
+
+Queue::~Queue() { aggregation_timeout_alarm_->PermanentCancel(); }
+
+void Queue::set_tx_port(ConstrainedPortInterface* port) {
+  tx_port_ = port;
+}
+
+void Queue::AcceptPacket(std::unique_ptr<Packet> packet) {
+  if (packet->size + bytes_queued_ > capacity_) {
+    QUIC_DVLOG(1) << "Queue [" << name() << "] has received a packet from ["
+                  << packet->source << "] to [" << packet->destination
+                  << "] which is over capacity.  Dropping it.";
+    QUIC_DVLOG(1) << "Queue size: " << bytes_queued_ << " out of " << capacity_
+                  << ".  Packet size: " << packet->size;
+    return;
+  }
+
+  bytes_queued_ += packet->size;
+  queue_.emplace_back(std::move(packet), current_bundle_);
+
+  if (IsAggregationEnabled()) {
+    current_bundle_bytes_ += queue_.front().packet->size;
+    if (!aggregation_timeout_alarm_->IsSet()) {
+      aggregation_timeout_alarm_->Set(clock_->Now() + aggregation_timeout_);
+    }
+    if (current_bundle_bytes_ >= aggregation_threshold_) {
+      NextBundle();
+    }
+  }
+
+  ScheduleNextPacketDequeue();
+}
+
+void Queue::Act() {
+  QUICHE_DCHECK(!queue_.empty());
+  if (tx_port_->TimeUntilAvailable().IsZero()) {
+    QUICHE_DCHECK(bytes_queued_ >= queue_.front().packet->size);
+    bytes_queued_ -= queue_.front().packet->size;
+
+    tx_port_->AcceptPacket(std::move(queue_.front().packet));
+    queue_.pop_front();
+    if (listener_ != nullptr) {
+      listener_->OnPacketDequeued();
+    }
+  }
+
+  ScheduleNextPacketDequeue();
+}
+
+void Queue::EnableAggregation(QuicByteCount aggregation_threshold,
+                              QuicTime::Delta aggregation_timeout) {
+  QUICHE_DCHECK_EQ(bytes_queued_, 0u);
+  QUICHE_DCHECK_GT(aggregation_threshold, 0u);
+  QUICHE_DCHECK(!aggregation_timeout.IsZero());
+  QUICHE_DCHECK(!aggregation_timeout.IsInfinite());
+
+  aggregation_threshold_ = aggregation_threshold;
+  aggregation_timeout_ = aggregation_timeout;
+}
+
+Queue::AggregationAlarmDelegate::AggregationAlarmDelegate(Queue* queue)
+    : queue_(queue) {}
+
+void Queue::AggregationAlarmDelegate::OnAlarm() {
+  queue_->NextBundle();
+  queue_->ScheduleNextPacketDequeue();
+}
+
+Queue::EnqueuedPacket::EnqueuedPacket(std::unique_ptr<Packet> packet,
+                                      AggregationBundleNumber bundle)
+    : packet(std::move(packet)), bundle(bundle) {}
+
+Queue::EnqueuedPacket::EnqueuedPacket(EnqueuedPacket&& other) = default;
+
+Queue::EnqueuedPacket::~EnqueuedPacket() = default;
+
+void Queue::NextBundle() {
+  current_bundle_++;
+  current_bundle_bytes_ = 0;
+  aggregation_timeout_alarm_->Cancel();
+}
+
+void Queue::ScheduleNextPacketDequeue() {
+  if (queue_.empty()) {
+    QUICHE_DCHECK_EQ(bytes_queued_, 0u);
+    return;
+  }
+
+  if (IsAggregationEnabled() && queue_.front().bundle == current_bundle_) {
+    return;
+  }
+
+  QuicTime::Delta time_until_available = QuicTime::Delta::Zero();
+  if (tx_port_) {
+    time_until_available = tx_port_->TimeUntilAvailable();
+  }
+
+  Schedule(clock_->Now() + time_until_available);
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/queue.h b/quiche/quic/test_tools/simulator/queue.h
new file mode 100644
index 0000000..b81db56
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/queue.h
@@ -0,0 +1,119 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+namespace simulator {
+
+// A finitely sized queue which egresses packets onto a constrained link.  The
+// capacity of the queue is measured in bytes as opposed to packets.
+class Queue : public Actor, public UnconstrainedPortInterface {
+ public:
+  class ListenerInterface {
+   public:
+    virtual ~ListenerInterface();
+
+    // Called whenever a packet is removed from the queue.
+    virtual void OnPacketDequeued() = 0;
+  };
+
+  Queue(Simulator* simulator, std::string name, QuicByteCount capacity);
+  Queue(const Queue&) = delete;
+  Queue& operator=(const Queue&) = delete;
+  ~Queue() override;
+
+  void set_tx_port(ConstrainedPortInterface* port);
+
+  void AcceptPacket(std::unique_ptr<Packet> packet) override;
+
+  void Act() override;
+
+  QuicByteCount capacity() const { return capacity_; }
+  QuicByteCount bytes_queued() const { return bytes_queued_; }
+  QuicPacketCount packets_queued() const { return queue_.size(); }
+
+  void set_listener_interface(ListenerInterface* listener) {
+    listener_ = listener;
+  }
+
+  // Enables packet aggregation on the queue.  Packet aggregation makes the
+  // queue bundle packets up until they reach certain size.  When the
+  // aggregation is enabled, the packets are not dequeued until the total size
+  // of packets in the queue reaches |aggregation_threshold|.  The packets are
+  // automatically flushed from the queue if the oldest packet has been in it
+  // for |aggregation_timeout|.
+  //
+  // This method may only be called when the queue is empty.  Once enabled,
+  // aggregation cannot be disabled.
+  void EnableAggregation(QuicByteCount aggregation_threshold,
+                         QuicTime::Delta aggregation_timeout);
+
+ private:
+  using AggregationBundleNumber = uint64_t;
+
+  // In order to implement packet aggregation, each packet is tagged with a
+  // bundle number.  The queue keeps a bundle counter, and whenever a bundle is
+  // ready, it increments the number of the current bundle.  Only the packets
+  // outside of the current bundle are allowed to leave the queue.
+  struct EnqueuedPacket {
+    EnqueuedPacket(std::unique_ptr<Packet> packet,
+                   AggregationBundleNumber bundle);
+    EnqueuedPacket(EnqueuedPacket&& other);
+    ~EnqueuedPacket();
+
+    std::unique_ptr<Packet> packet;
+    AggregationBundleNumber bundle;
+  };
+
+  // Alarm handler for aggregation timeout.
+  class AggregationAlarmDelegate : public QuicAlarm::DelegateWithoutContext {
+   public:
+    explicit AggregationAlarmDelegate(Queue* queue);
+
+    void OnAlarm() override;
+
+   private:
+    Queue* queue_;
+  };
+
+  bool IsAggregationEnabled() const { return aggregation_threshold_ > 0; }
+
+  // Increment the bundle counter and reset the bundle state.  This causes all
+  // packets currently in the bundle to be flushed onto the link.
+  void NextBundle();
+
+  void ScheduleNextPacketDequeue();
+
+  const QuicByteCount capacity_;
+  QuicByteCount bytes_queued_;
+
+  QuicByteCount aggregation_threshold_;
+  QuicTime::Delta aggregation_timeout_;
+  // The number of the current aggregation bundle.  Monotonically increasing.
+  // All packets in the previous bundles are allowed to leave the queue, and
+  // none of the packets in the current one are.
+  AggregationBundleNumber current_bundle_;
+  // Size of the current bundle.  Whenever it exceeds |aggregation_threshold_|,
+  // the next bundle is created.
+  QuicByteCount current_bundle_bytes_;
+  // Alarm responsible for flushing the current bundle upon timeout.  Set when
+  // the first packet in the bundle is enqueued.
+  std::unique_ptr<QuicAlarm> aggregation_timeout_alarm_;
+
+  ConstrainedPortInterface* tx_port_;
+  quiche::QuicheCircularDeque<EnqueuedPacket> queue_;
+
+  ListenerInterface* listener_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUEUE_H_
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint.cc b/quiche/quic/test_tools/simulator/quic_endpoint.cc
new file mode 100644
index 0000000..75194aa
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/quic_endpoint.cc
@@ -0,0 +1,258 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/platform/api/quic_test_output.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+namespace quic {
+namespace simulator {
+
+const QuicStreamId kDataStream = 3;
+const QuicByteCount kWriteChunkSize = 128 * 1024;
+const char kStreamDataContents = 'Q';
+
+QuicEndpoint::QuicEndpoint(Simulator* simulator,
+                           std::string name,
+                           std::string peer_name,
+                           Perspective perspective,
+                           QuicConnectionId connection_id)
+    : QuicEndpointBase(simulator, name, peer_name),
+      bytes_to_transfer_(0),
+      bytes_transferred_(0),
+      wrong_data_received_(false),
+      notifier_(nullptr) {
+  connection_ = std::make_unique<QuicConnection>(
+      connection_id, GetAddressFromName(name), GetAddressFromName(peer_name),
+      simulator, simulator->GetAlarmFactory(), &writer_, false, perspective,
+      ParsedVersionOfIndex(CurrentSupportedVersions(), 0));
+  connection_->set_visitor(this);
+  connection_->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+                            std::make_unique<NullEncrypter>(perspective));
+  connection_->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
+  if (connection_->version().KnowsWhichDecrypterToUse()) {
+    connection_->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+                                  std::make_unique<NullDecrypter>(perspective));
+    connection_->RemoveDecrypter(ENCRYPTION_INITIAL);
+  } else {
+    connection_->SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+                              std::make_unique<NullDecrypter>(perspective));
+  }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+  connection_->OnHandshakeComplete();
+  if (perspective == Perspective::IS_SERVER) {
+    // Skip version negotiation.
+    test::QuicConnectionPeer::SetNegotiatedVersion(connection_.get());
+  }
+  test::QuicConnectionPeer::SetAddressValidated(connection_.get());
+  connection_->SetDataProducer(&producer_);
+  connection_->SetSessionNotifier(this);
+  notifier_ = std::make_unique<test::SimpleSessionNotifier>(connection_.get());
+
+  // Configure the connection as if it received a handshake.  This is important
+  // primarily because
+  //  - this enables pacing, and
+  //  - this sets the non-handshake timeouts.
+  std::string error;
+  CryptoHandshakeMessage peer_hello;
+  peer_hello.SetValue(kICSL,
+                      static_cast<uint32_t>(kMaximumIdleTimeoutSecs - 1));
+  peer_hello.SetValue(kMIBS,
+                      static_cast<uint32_t>(kDefaultMaxStreamsPerConnection));
+  QuicConfig config;
+  QuicErrorCode error_code = config.ProcessPeerHello(
+      peer_hello, perspective == Perspective::IS_CLIENT ? SERVER : CLIENT,
+      &error);
+  QUICHE_DCHECK_EQ(error_code, QUIC_NO_ERROR)
+      << "Configuration failed: " << error;
+  if (connection_->version().UsesTls()) {
+    if (connection_->perspective() == Perspective::IS_CLIENT) {
+      test::QuicConfigPeer::SetReceivedOriginalConnectionId(
+          &config, connection_->connection_id());
+      test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+          &config, connection_->connection_id());
+    } else {
+      test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+          &config, connection_->client_connection_id());
+    }
+  }
+  connection_->SetFromConfig(config);
+  connection_->DisableMtuDiscovery();
+}
+
+QuicByteCount QuicEndpoint::bytes_received() const {
+  QuicByteCount total = 0;
+  for (auto& interval : offsets_received_) {
+    total += interval.max() - interval.min();
+  }
+  return total;
+}
+
+QuicByteCount QuicEndpoint::bytes_to_transfer() const {
+  if (notifier_ != nullptr) {
+    return notifier_->StreamBytesToSend();
+  }
+  return bytes_to_transfer_;
+}
+
+QuicByteCount QuicEndpoint::bytes_transferred() const {
+  if (notifier_ != nullptr) {
+    return notifier_->StreamBytesSent();
+  }
+  return bytes_transferred_;
+}
+
+void QuicEndpoint::AddBytesToTransfer(QuicByteCount bytes) {
+  if (notifier_ != nullptr) {
+    if (notifier_->HasBufferedStreamData()) {
+      Schedule(clock_->Now());
+    }
+    notifier_->WriteOrBufferData(kDataStream, bytes, NO_FIN);
+    return;
+  }
+
+  if (bytes_to_transfer_ > 0) {
+    Schedule(clock_->Now());
+  }
+
+  bytes_to_transfer_ += bytes;
+  WriteStreamData();
+}
+
+void QuicEndpoint::OnStreamFrame(const QuicStreamFrame& frame) {
+  // Verify that the data received always matches the expected.
+  QUICHE_DCHECK(frame.stream_id == kDataStream);
+  for (size_t i = 0; i < frame.data_length; i++) {
+    if (frame.data_buffer[i] != kStreamDataContents) {
+      wrong_data_received_ = true;
+    }
+  }
+  offsets_received_.Add(frame.offset, frame.offset + frame.data_length);
+  // Sanity check against very pathological connections.
+  QUICHE_DCHECK_LE(offsets_received_.Size(), 1000u);
+}
+
+void QuicEndpoint::OnCryptoFrame(const QuicCryptoFrame& /*frame*/) {}
+
+void QuicEndpoint::OnCanWrite() {
+  if (notifier_ != nullptr) {
+    notifier_->OnCanWrite();
+    return;
+  }
+  WriteStreamData();
+}
+
+bool QuicEndpoint::SendProbingData() {
+  if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
+          PROBING_RETRANSMISSION)) {
+    return true;
+  }
+  return false;
+}
+
+bool QuicEndpoint::WillingAndAbleToWrite() const {
+  if (notifier_ != nullptr) {
+    return notifier_->WillingToWrite();
+  }
+  return bytes_to_transfer_ != 0;
+}
+bool QuicEndpoint::ShouldKeepConnectionAlive() const {
+  return true;
+}
+
+bool QuicEndpoint::AllowSelfAddressChange() const {
+  return false;
+}
+
+bool QuicEndpoint::OnFrameAcked(const QuicFrame& frame,
+                                QuicTime::Delta ack_delay_time,
+                                QuicTime receive_timestamp) {
+  if (notifier_ != nullptr) {
+    return notifier_->OnFrameAcked(frame, ack_delay_time, receive_timestamp);
+  }
+  return false;
+}
+
+void QuicEndpoint::OnFrameLost(const QuicFrame& frame) {
+  QUICHE_DCHECK(notifier_);
+  notifier_->OnFrameLost(frame);
+}
+
+bool QuicEndpoint::RetransmitFrames(const QuicFrames& frames,
+                                    TransmissionType type) {
+  QUICHE_DCHECK(notifier_);
+  return notifier_->RetransmitFrames(frames, type);
+}
+
+bool QuicEndpoint::IsFrameOutstanding(const QuicFrame& frame) const {
+  QUICHE_DCHECK(notifier_);
+  return notifier_->IsFrameOutstanding(frame);
+}
+
+bool QuicEndpoint::HasUnackedCryptoData() const {
+  return false;
+}
+
+bool QuicEndpoint::HasUnackedStreamData() const {
+  if (notifier_ != nullptr) {
+    return notifier_->HasUnackedStreamData();
+  }
+  return false;
+}
+
+HandshakeState QuicEndpoint::GetHandshakeState() const {
+  return HANDSHAKE_COMPLETE;
+}
+
+WriteStreamDataResult QuicEndpoint::DataProducer::WriteStreamData(
+    QuicStreamId /*id*/,
+    QuicStreamOffset /*offset*/,
+    QuicByteCount data_length,
+    QuicDataWriter* writer) {
+  writer->WriteRepeatedByte(kStreamDataContents, data_length);
+  return WRITE_SUCCESS;
+}
+
+bool QuicEndpoint::DataProducer::WriteCryptoData(EncryptionLevel /*level*/,
+                                                 QuicStreamOffset /*offset*/,
+                                                 QuicByteCount /*data_length*/,
+                                                 QuicDataWriter* /*writer*/) {
+  QUIC_BUG(quic_bug_10157_1)
+      << "QuicEndpoint::DataProducer::WriteCryptoData is unimplemented";
+  return false;
+}
+
+void QuicEndpoint::WriteStreamData() {
+  // Instantiate a flusher which would normally be here due to QuicSession.
+  QuicConnection::ScopedPacketFlusher flusher(connection_.get());
+
+  while (bytes_to_transfer_ > 0) {
+    // Transfer data in chunks of size at most |kWriteChunkSize|.
+    const size_t transmission_size =
+        std::min(kWriteChunkSize, bytes_to_transfer_);
+
+    QuicConsumedData consumed_data = connection_->SendStreamData(
+        kDataStream, transmission_size, bytes_transferred_, NO_FIN);
+
+    QUICHE_DCHECK(consumed_data.bytes_consumed <= transmission_size);
+    bytes_transferred_ += consumed_data.bytes_consumed;
+    bytes_to_transfer_ -= consumed_data.bytes_consumed;
+    if (consumed_data.bytes_consumed != transmission_size) {
+      return;
+    }
+  }
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint.h b/quiche/quic/test_tools/simulator/quic_endpoint.h
new file mode 100644
index 0000000..e29d594
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/quic_endpoint.h
@@ -0,0 +1,179 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_default_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_trace_visitor.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/test_tools/simple_session_notifier.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/quic/test_tools/simulator/queue.h"
+#include "quiche/quic/test_tools/simulator/quic_endpoint_base.h"
+
+namespace quic {
+namespace simulator {
+
+// A QUIC connection endpoint.  Wraps around QuicConnection.  In order to
+// initiate a transfer, the caller has to call AddBytesToTransfer().  The data
+// transferred is always the same and is always transferred on a single stream.
+// The endpoint receives all packets addressed to it, and verifies that the data
+// received is what it's supposed to be.
+class QuicEndpoint : public QuicEndpointBase,
+                     public QuicConnectionVisitorInterface,
+                     public SessionNotifierInterface {
+ public:
+  QuicEndpoint(Simulator* simulator,
+               std::string name,
+               std::string peer_name,
+               Perspective perspective,
+               QuicConnectionId connection_id);
+
+  QuicByteCount bytes_to_transfer() const;
+  QuicByteCount bytes_transferred() const;
+  QuicByteCount bytes_received() const;
+  bool wrong_data_received() const { return wrong_data_received_; }
+
+  // Send |bytes| bytes.  Initiates the transfer if one is not already in
+  // progress.
+  void AddBytesToTransfer(QuicByteCount bytes);
+
+  // Begin QuicConnectionVisitorInterface implementation.
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  void OnCryptoFrame(const QuicCryptoFrame& frame) override;
+  void OnCanWrite() override;
+  bool SendProbingData() override;
+  bool ValidateStatelessReset(
+      const quic::QuicSocketAddress& /*self_address*/,
+      const quic::QuicSocketAddress& /*peer_address*/) override {
+    return true;
+  }
+  bool WillingAndAbleToWrite() const override;
+  bool ShouldKeepConnectionAlive() const override;
+
+  std::string GetStreamsInfoForLogging() const override { return ""; }
+  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {}
+  void OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {}
+  void OnRstStream(const QuicRstStreamFrame& /*frame*/) override {}
+  void OnGoAway(const QuicGoAwayFrame& /*frame*/) override {}
+  void OnMessageReceived(absl::string_view /*message*/) override {}
+  void OnHandshakeDoneReceived() override {}
+  void OnNewTokenReceived(absl::string_view /*token*/) override {}
+  void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
+                          ConnectionCloseSource /*source*/) override {}
+  void OnWriteBlocked() override {}
+  void OnSuccessfulVersionNegotiation(
+      const ParsedQuicVersion& /*version*/) override {}
+  void OnPacketReceived(const QuicSocketAddress& /*self_address*/,
+                        const QuicSocketAddress& /*peer_address*/,
+                        bool /*is_connectivity_probe*/) override {}
+  void OnCongestionWindowChange(QuicTime /*now*/) override {}
+  void OnConnectionMigration(AddressChangeType /*type*/) override {}
+  void OnPathDegrading() override {}
+  void OnForwardProgressMadeAfterPathDegrading() override {}
+  void OnAckNeedsRetransmittableFrame() override {}
+  void SendAckFrequency(const QuicAckFrequencyFrame& /*frame*/) override {}
+  void SendNewConnectionId(const QuicNewConnectionIdFrame& /*frame*/) override {
+  }
+  void SendRetireConnectionId(uint64_t /*sequence_number*/) override {}
+  void OnServerConnectionIdIssued(
+      const QuicConnectionId& /*server_connection_id*/) override {}
+  void OnServerConnectionIdRetired(
+      const QuicConnectionId& /*server_connection_id*/) override {}
+  bool AllowSelfAddressChange() const override;
+  HandshakeState GetHandshakeState() const override;
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
+    return true;
+  }
+  bool OnStreamsBlockedFrame(
+      const QuicStreamsBlockedFrame& /*frame*/) override {
+    return true;
+  }
+  void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {}
+  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
+  void OnOneRttPacketAcknowledged() override {}
+  void OnHandshakePacketSent() override {}
+  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    return nullptr;
+  }
+  void BeforeConnectionCloseSent() override {}
+  bool ValidateToken(absl::string_view /*token*/) override { return true; }
+  bool MaybeSendAddressToken() override { return false; }
+  bool IsKnownServerAddress(
+      const QuicSocketAddress& /*address*/) const override {
+    return false;
+  }
+
+  // End QuicConnectionVisitorInterface implementation.
+
+  // Begin SessionNotifierInterface methods:
+  bool OnFrameAcked(const QuicFrame& frame,
+                    QuicTime::Delta ack_delay_time,
+                    QuicTime receive_timestamp) override;
+  void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
+  void OnFrameLost(const QuicFrame& frame) override;
+  bool RetransmitFrames(const QuicFrames& frames,
+                        TransmissionType type) override;
+  bool IsFrameOutstanding(const QuicFrame& frame) const override;
+  bool HasUnackedCryptoData() const override;
+  bool HasUnackedStreamData() const override;
+  // End SessionNotifierInterface implementation.
+
+ private:
+  // The producer outputs the repetition of the same byte.  That sequence is
+  // verified by the receiver.
+  class DataProducer : public QuicStreamFrameDataProducer {
+   public:
+    WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                          QuicStreamOffset offset,
+                                          QuicByteCount data_length,
+                                          QuicDataWriter* writer) override;
+    bool WriteCryptoData(EncryptionLevel level,
+                         QuicStreamOffset offset,
+                         QuicByteCount data_length,
+                         QuicDataWriter* writer) override;
+  };
+
+  std::unique_ptr<QuicConnection> CreateConnection(
+      Simulator* simulator,
+      std::string name,
+      std::string peer_name,
+      Perspective perspective,
+      QuicConnectionId connection_id);
+
+  // Write stream data until |bytes_to_transfer_| is zero or the connection is
+  // write-blocked.
+  void WriteStreamData();
+
+  DataProducer producer_;
+
+  QuicByteCount bytes_to_transfer_;
+  QuicByteCount bytes_transferred_;
+
+  // Set to true if the endpoint receives stream data different from what it
+  // expects.
+  bool wrong_data_received_;
+
+  // Record of received offsets in the data stream.
+  QuicIntervalSet<QuicStreamOffset> offsets_received_;
+
+  std::unique_ptr<test::SimpleSessionNotifier> notifier_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_H_
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint_base.cc b/quiche/quic/test_tools/simulator/quic_endpoint_base.cc
new file mode 100644
index 0000000..ad8c662
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/quic_endpoint_base.cc
@@ -0,0 +1,224 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/quic_endpoint_base.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/crypto_handshake_message.h"
+#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_data_writer.h"
+#include "quiche/quic/platform/api/quic_test_output.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+namespace quic {
+namespace simulator {
+
+// Takes a SHA-1 hash of the name and converts it into five 32-bit integers.
+static std::vector<uint32_t> HashNameIntoFive32BitIntegers(std::string name) {
+  const std::string hash = test::Sha1Hash(name);
+
+  std::vector<uint32_t> output;
+  uint32_t current_number = 0;
+  for (size_t i = 0; i < hash.size(); i++) {
+    current_number = (current_number << 8) + hash[i];
+    if (i % 4 == 3) {
+      output.push_back(i);
+      current_number = 0;
+    }
+  }
+
+  return output;
+}
+
+QuicSocketAddress GetAddressFromName(std::string name) {
+  const std::vector<uint32_t> hash = HashNameIntoFive32BitIntegers(name);
+
+  // Generate a random port between 1025 and 65535.
+  const uint16_t port = 1025 + hash[0] % (65535 - 1025 + 1);
+
+  // Generate a random 10.x.x.x address, where x is between 1 and 254.
+  std::string ip_address{"\xa\0\0\0", 4};
+  for (size_t i = 1; i < 4; i++) {
+    ip_address[i] = 1 + hash[i] % 254;
+  }
+  QuicIpAddress host;
+  host.FromPackedString(ip_address.c_str(), ip_address.length());
+  return QuicSocketAddress(host, port);
+}
+
+QuicEndpointBase::QuicEndpointBase(Simulator* simulator,
+                                   std::string name,
+                                   std::string peer_name)
+    : Endpoint(simulator, name),
+      peer_name_(peer_name),
+      writer_(this),
+      nic_tx_queue_(simulator,
+                    absl::StrCat(name, " (TX Queue)"),
+                    kMaxOutgoingPacketSize * kTxQueueSize),
+      connection_(nullptr),
+      write_blocked_count_(0),
+      drop_next_packet_(false) {
+  nic_tx_queue_.set_listener_interface(this);
+}
+
+QuicEndpointBase::~QuicEndpointBase() {
+  if (trace_visitor_ != nullptr) {
+    const char* perspective_prefix =
+        connection_->perspective() == Perspective::IS_CLIENT ? "C" : "S";
+
+    std::string identifier = absl::StrCat(
+        perspective_prefix, connection_->connection_id().ToString());
+    QuicRecordTrace(identifier, trace_visitor_->trace()->SerializeAsString());
+  }
+}
+
+void QuicEndpointBase::DropNextIncomingPacket() {
+  drop_next_packet_ = true;
+}
+
+void QuicEndpointBase::RecordTrace() {
+  trace_visitor_ = std::make_unique<QuicTraceVisitor>(connection_.get());
+  connection_->set_debug_visitor(trace_visitor_.get());
+}
+
+void QuicEndpointBase::AcceptPacket(std::unique_ptr<Packet> packet) {
+  if (packet->destination != name_) {
+    return;
+  }
+  if (drop_next_packet_) {
+    drop_next_packet_ = false;
+    return;
+  }
+
+  QuicReceivedPacket received_packet(packet->contents.data(),
+                                     packet->contents.size(), clock_->Now());
+  connection_->ProcessUdpPacket(connection_->self_address(),
+                                connection_->peer_address(), received_packet);
+}
+
+UnconstrainedPortInterface* QuicEndpointBase::GetRxPort() {
+  return this;
+}
+
+void QuicEndpointBase::SetTxPort(ConstrainedPortInterface* port) {
+  // Any egress done by the endpoint is actually handled by a queue on an NIC.
+  nic_tx_queue_.set_tx_port(port);
+}
+
+void QuicEndpointBase::OnPacketDequeued() {
+  if (writer_.IsWriteBlocked() &&
+      (nic_tx_queue_.capacity() - nic_tx_queue_.bytes_queued()) >=
+          kMaxOutgoingPacketSize) {
+    writer_.SetWritable();
+    connection_->OnCanWrite();
+  }
+}
+
+QuicEndpointBase::Writer::Writer(QuicEndpointBase* endpoint)
+    : endpoint_(endpoint), is_blocked_(false) {}
+
+QuicEndpointBase::Writer::~Writer() {}
+
+WriteResult QuicEndpointBase::Writer::WritePacket(
+    const char* buffer,
+    size_t buf_len,
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/,
+    PerPacketOptions* options) {
+  QUICHE_DCHECK(!IsWriteBlocked());
+  QUICHE_DCHECK(options == nullptr);
+  QUICHE_DCHECK(buf_len <= kMaxOutgoingPacketSize);
+
+  // Instead of losing a packet, become write-blocked when the egress queue is
+  // full.
+  if (endpoint_->nic_tx_queue_.packets_queued() > kTxQueueSize) {
+    is_blocked_ = true;
+    endpoint_->write_blocked_count_++;
+    return WriteResult(WRITE_STATUS_BLOCKED, 0);
+  }
+
+  auto packet = std::make_unique<Packet>();
+  packet->source = endpoint_->name();
+  packet->destination = endpoint_->peer_name_;
+  packet->tx_timestamp = endpoint_->clock_->Now();
+
+  packet->contents = std::string(buffer, buf_len);
+  packet->size = buf_len;
+
+  endpoint_->nic_tx_queue_.AcceptPacket(std::move(packet));
+
+  return WriteResult(WRITE_STATUS_OK, buf_len);
+}
+
+bool QuicEndpointBase::Writer::IsWriteBlocked() const {
+  return is_blocked_;
+}
+
+void QuicEndpointBase::Writer::SetWritable() {
+  is_blocked_ = false;
+}
+
+absl::optional<int> QuicEndpointBase::Writer::MessageTooBigErrorCode() const {
+  return absl::nullopt;
+}
+
+QuicByteCount QuicEndpointBase::Writer::GetMaxPacketSize(
+    const QuicSocketAddress& /*peer_address*/) const {
+  return kMaxOutgoingPacketSize;
+}
+
+bool QuicEndpointBase::Writer::SupportsReleaseTime() const {
+  return false;
+}
+
+bool QuicEndpointBase::Writer::IsBatchMode() const {
+  return false;
+}
+
+QuicPacketBuffer QuicEndpointBase::Writer::GetNextWriteLocation(
+    const QuicIpAddress& /*self_address*/,
+    const QuicSocketAddress& /*peer_address*/) {
+  return {nullptr, nullptr};
+}
+
+WriteResult QuicEndpointBase::Writer::Flush() {
+  return WriteResult(WRITE_STATUS_OK, 0);
+}
+
+QuicEndpointMultiplexer::QuicEndpointMultiplexer(
+    std::string name,
+    const std::vector<QuicEndpointBase*>& endpoints)
+    : Endpoint((*endpoints.begin())->simulator(), name) {
+  for (QuicEndpointBase* endpoint : endpoints) {
+    mapping_.insert(std::make_pair(endpoint->name(), endpoint));
+  }
+}
+
+QuicEndpointMultiplexer::~QuicEndpointMultiplexer() {}
+
+void QuicEndpointMultiplexer::AcceptPacket(std::unique_ptr<Packet> packet) {
+  auto key_value_pair_it = mapping_.find(packet->destination);
+  if (key_value_pair_it == mapping_.end()) {
+    return;
+  }
+
+  key_value_pair_it->second->GetRxPort()->AcceptPacket(std::move(packet));
+}
+UnconstrainedPortInterface* QuicEndpointMultiplexer::GetRxPort() {
+  return this;
+}
+void QuicEndpointMultiplexer::SetTxPort(ConstrainedPortInterface* port) {
+  for (auto& key_value_pair : mapping_) {
+    key_value_pair.second->SetTxPort(port);
+  }
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint_base.h b/quiche/quic/test_tools/simulator/quic_endpoint_base.h
new file mode 100644
index 0000000..24a3c47
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/quic_endpoint_base.h
@@ -0,0 +1,161 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
+
+#include <memory>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/crypto/null_decrypter.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_default_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_stream_frame_data_producer.h"
+#include "quiche/quic/core/quic_trace_visitor.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/test_tools/simple_session_notifier.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/quic/test_tools/simulator/queue.h"
+
+namespace quic {
+namespace simulator {
+
+// Size of the TX queue used by the kernel/NIC.  1000 is the Linux
+// kernel default.
+const QuicByteCount kTxQueueSize = 1000;
+
+// Generate a random local network host-port tuple based on the name of the
+// endpoint.
+QuicSocketAddress GetAddressFromName(std::string name);
+
+// A QUIC connection endpoint.  If the specific data transmitted does not matter
+// (e.g. for congestion control purposes), QuicEndpoint is the subclass that
+// transmits dummy data.  If the actual semantics of the connection matter,
+// subclassing QuicEndpointBase is required.
+class QuicEndpointBase : public Endpoint,
+                         public UnconstrainedPortInterface,
+                         public Queue::ListenerInterface {
+ public:
+  // Does not create the connection; the subclass has to create connection by
+  // itself.
+  QuicEndpointBase(Simulator* simulator,
+                   std::string name,
+                   std::string peer_name);
+  ~QuicEndpointBase() override;
+
+  QuicConnection* connection() { return connection_.get(); }
+  size_t write_blocked_count() { return write_blocked_count_; }
+
+  // Drop the next packet upon receipt.
+  void DropNextIncomingPacket();
+
+  // UnconstrainedPortInterface method.  Called whenever the endpoint receives a
+  // packet.
+  void AcceptPacket(std::unique_ptr<Packet> packet) override;
+
+  // Enables logging of the connection trace at the end of the unit test.
+  void RecordTrace();
+
+  // Begin Endpoint implementation.
+  UnconstrainedPortInterface* GetRxPort() override;
+  void SetTxPort(ConstrainedPortInterface* port) override;
+  // End Endpoint implementation.
+
+  // Actor method.
+  void Act() override {}
+
+  // Queue::ListenerInterface method.
+  void OnPacketDequeued() override;
+
+ protected:
+  // A Writer object that writes into the |nic_tx_queue_|.
+  class Writer : public QuicPacketWriter {
+   public:
+    explicit Writer(QuicEndpointBase* endpoint);
+    ~Writer() override;
+
+    WriteResult WritePacket(const char* buffer,
+                            size_t buf_len,
+                            const QuicIpAddress& self_address,
+                            const QuicSocketAddress& peer_address,
+                            PerPacketOptions* options) override;
+    bool IsWriteBlocked() const override;
+    void SetWritable() override;
+    absl::optional<int> MessageTooBigErrorCode() const override;
+    QuicByteCount GetMaxPacketSize(
+        const QuicSocketAddress& peer_address) const override;
+    bool SupportsReleaseTime() const override;
+    bool IsBatchMode() const override;
+    QuicPacketBuffer GetNextWriteLocation(
+        const QuicIpAddress& self_address,
+        const QuicSocketAddress& peer_address) override;
+    WriteResult Flush() override;
+
+   private:
+    QuicEndpointBase* endpoint_;
+
+    bool is_blocked_;
+  };
+
+  // The producer outputs the repetition of the same byte.  That sequence is
+  // verified by the receiver.
+  class DataProducer : public QuicStreamFrameDataProducer {
+   public:
+    WriteStreamDataResult WriteStreamData(QuicStreamId id,
+                                          QuicStreamOffset offset,
+                                          QuicByteCount data_length,
+                                          QuicDataWriter* writer) override;
+    bool WriteCryptoData(EncryptionLevel level,
+                         QuicStreamOffset offset,
+                         QuicByteCount data_length,
+                         QuicDataWriter* writer) override;
+  };
+
+  std::string peer_name_;
+
+  Writer writer_;
+  // The queue for the outgoing packets.  In reality, this might be either on
+  // the network card, or in the kernel, but for concreteness we assume it's on
+  // the network card.
+  Queue nic_tx_queue_;
+  // Created by the subclass.
+  std::unique_ptr<QuicConnection> connection_;
+
+  // Counts the number of times the writer became write-blocked.
+  size_t write_blocked_count_;
+
+  // If true, drop the next packet when receiving it.
+  bool drop_next_packet_;
+
+  std::unique_ptr<QuicTraceVisitor> trace_visitor_;
+};
+
+// Multiplexes multiple connections at the same host on the network.
+class QuicEndpointMultiplexer : public Endpoint,
+                                public UnconstrainedPortInterface {
+ public:
+  QuicEndpointMultiplexer(std::string name,
+                          const std::vector<QuicEndpointBase*>& endpoints);
+  ~QuicEndpointMultiplexer() override;
+
+  // Receives a packet and passes it to the specified endpoint if that endpoint
+  // is one of the endpoints being multiplexed, otherwise ignores the packet.
+  void AcceptPacket(std::unique_ptr<Packet> packet) override;
+  UnconstrainedPortInterface* GetRxPort() override;
+
+  // Sets the egress port for all the endpoints being multiplexed.
+  void SetTxPort(ConstrainedPortInterface* port) override;
+
+  void Act() override {}
+
+ private:
+  absl::flat_hash_map<std::string, QuicEndpointBase*> mapping_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_QUIC_ENDPOINT_BASE_H_
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint_test.cc b/quiche/quic/test_tools/simulator/quic_endpoint_test.cc
new file mode 100644
index 0000000..6952684
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/quic_endpoint_test.cc
@@ -0,0 +1,208 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/quic_endpoint.h"
+
+#include <utility>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/simulator.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+
+using ::testing::_;
+using ::testing::NiceMock;
+using ::testing::Return;
+
+namespace quic {
+namespace simulator {
+
+const QuicBandwidth kDefaultBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10 * 1000);
+const QuicTime::Delta kDefaultPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(20);
+const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
+
+// A simple test harness where all hosts are connected to a switch with
+// identical links.
+class QuicEndpointTest : public QuicTest {
+ public:
+  QuicEndpointTest()
+      : simulator_(), switch_(&simulator_, "Switch", 8, kDefaultBdp * 2) {}
+
+ protected:
+  Simulator simulator_;
+  Switch switch_;
+
+  std::unique_ptr<SymmetricLink> Link(Endpoint* a, Endpoint* b) {
+    return std::make_unique<SymmetricLink>(a, b, kDefaultBandwidth,
+                                           kDefaultPropagationDelay);
+  }
+
+  std::unique_ptr<SymmetricLink> CustomLink(Endpoint* a,
+                                            Endpoint* b,
+                                            uint64_t extra_rtt_ms) {
+    return std::make_unique<SymmetricLink>(
+        a, b, kDefaultBandwidth,
+        kDefaultPropagationDelay +
+            QuicTime::Delta::FromMilliseconds(extra_rtt_ms));
+  }
+};
+
+// Test transmission from one host to another.
+TEST_F(QuicEndpointTest, OneWayTransmission) {
+  QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
+                          Perspective::IS_CLIENT, test::TestConnectionId(42));
+  QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
+                          Perspective::IS_SERVER, test::TestConnectionId(42));
+  auto link_a = Link(&endpoint_a, switch_.port(1));
+  auto link_b = Link(&endpoint_b, switch_.port(2));
+
+  // First transmit a small, packet-size chunk of data.
+  endpoint_a.AddBytesToTransfer(600);
+  QuicTime end_time =
+      simulator_.GetClock()->Now() + QuicTime::Delta::FromMilliseconds(1000);
+  simulator_.RunUntil(
+      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
+
+  EXPECT_EQ(600u, endpoint_a.bytes_transferred());
+  ASSERT_EQ(600u, endpoint_b.bytes_received());
+  EXPECT_FALSE(endpoint_a.wrong_data_received());
+  EXPECT_FALSE(endpoint_b.wrong_data_received());
+
+  // After a small chunk succeeds, try to transfer 2 MiB.
+  endpoint_a.AddBytesToTransfer(2 * 1024 * 1024);
+  end_time = simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(5);
+  simulator_.RunUntil(
+      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
+
+  const QuicByteCount total_bytes_transferred = 600 + 2 * 1024 * 1024;
+  EXPECT_EQ(total_bytes_transferred, endpoint_a.bytes_transferred());
+  EXPECT_EQ(total_bytes_transferred, endpoint_b.bytes_received());
+  EXPECT_EQ(0u, endpoint_a.write_blocked_count());
+  EXPECT_FALSE(endpoint_a.wrong_data_received());
+  EXPECT_FALSE(endpoint_b.wrong_data_received());
+}
+
+// Test the situation in which the writer becomes write-blocked.
+TEST_F(QuicEndpointTest, WriteBlocked) {
+  QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
+                          Perspective::IS_CLIENT, test::TestConnectionId(42));
+  QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
+                          Perspective::IS_SERVER, test::TestConnectionId(42));
+  auto link_a = Link(&endpoint_a, switch_.port(1));
+  auto link_b = Link(&endpoint_b, switch_.port(2));
+
+  // Will be owned by the sent packet manager.
+  auto* sender = new NiceMock<test::MockSendAlgorithm>();
+  EXPECT_CALL(*sender, CanSend(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(*sender, PacingRate(_))
+      .WillRepeatedly(Return(10 * kDefaultBandwidth));
+  EXPECT_CALL(*sender, BandwidthEstimate())
+      .WillRepeatedly(Return(10 * kDefaultBandwidth));
+  EXPECT_CALL(*sender, GetCongestionWindow())
+      .WillRepeatedly(Return(kMaxOutgoingPacketSize *
+                             GetQuicFlag(FLAGS_quic_max_congestion_window)));
+  test::QuicConnectionPeer::SetSendAlgorithm(endpoint_a.connection(), sender);
+
+  // First transmit a small, packet-size chunk of data.
+  QuicByteCount bytes_to_transfer = 3 * 1024 * 1024;
+  endpoint_a.AddBytesToTransfer(bytes_to_transfer);
+  QuicTime end_time =
+      simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(30);
+  simulator_.RunUntil([this, &endpoint_b, bytes_to_transfer, end_time]() {
+    return endpoint_b.bytes_received() == bytes_to_transfer ||
+           simulator_.GetClock()->Now() >= end_time;
+  });
+
+  EXPECT_EQ(bytes_to_transfer, endpoint_a.bytes_transferred());
+  EXPECT_EQ(bytes_to_transfer, endpoint_b.bytes_received());
+  EXPECT_GT(endpoint_a.write_blocked_count(), 0u);
+  EXPECT_FALSE(endpoint_a.wrong_data_received());
+  EXPECT_FALSE(endpoint_b.wrong_data_received());
+}
+
+// Test transmission of 1 MiB of data between two hosts simultaneously in both
+// directions.
+TEST_F(QuicEndpointTest, TwoWayTransmission) {
+  QuicEndpoint endpoint_a(&simulator_, "Endpoint A", "Endpoint B",
+                          Perspective::IS_CLIENT, test::TestConnectionId(42));
+  QuicEndpoint endpoint_b(&simulator_, "Endpoint B", "Endpoint A",
+                          Perspective::IS_SERVER, test::TestConnectionId(42));
+  auto link_a = Link(&endpoint_a, switch_.port(1));
+  auto link_b = Link(&endpoint_b, switch_.port(2));
+
+  endpoint_a.RecordTrace();
+  endpoint_b.RecordTrace();
+
+  endpoint_a.AddBytesToTransfer(1024 * 1024);
+  endpoint_b.AddBytesToTransfer(1024 * 1024);
+  QuicTime end_time =
+      simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(5);
+  simulator_.RunUntil(
+      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
+
+  EXPECT_EQ(1024u * 1024u, endpoint_a.bytes_transferred());
+  EXPECT_EQ(1024u * 1024u, endpoint_b.bytes_transferred());
+  EXPECT_EQ(1024u * 1024u, endpoint_a.bytes_received());
+  EXPECT_EQ(1024u * 1024u, endpoint_b.bytes_received());
+  EXPECT_FALSE(endpoint_a.wrong_data_received());
+  EXPECT_FALSE(endpoint_b.wrong_data_received());
+}
+
+// Simulate three hosts trying to send data to a fourth one simultaneously.
+TEST_F(QuicEndpointTest, Competition) {
+  auto endpoint_a = std::make_unique<QuicEndpoint>(
+      &simulator_, "Endpoint A", "Endpoint D (A)", Perspective::IS_CLIENT,
+      test::TestConnectionId(42));
+  auto endpoint_b = std::make_unique<QuicEndpoint>(
+      &simulator_, "Endpoint B", "Endpoint D (B)", Perspective::IS_CLIENT,
+      test::TestConnectionId(43));
+  auto endpoint_c = std::make_unique<QuicEndpoint>(
+      &simulator_, "Endpoint C", "Endpoint D (C)", Perspective::IS_CLIENT,
+      test::TestConnectionId(44));
+  auto endpoint_d_a = std::make_unique<QuicEndpoint>(
+      &simulator_, "Endpoint D (A)", "Endpoint A", Perspective::IS_SERVER,
+      test::TestConnectionId(42));
+  auto endpoint_d_b = std::make_unique<QuicEndpoint>(
+      &simulator_, "Endpoint D (B)", "Endpoint B", Perspective::IS_SERVER,
+      test::TestConnectionId(43));
+  auto endpoint_d_c = std::make_unique<QuicEndpoint>(
+      &simulator_, "Endpoint D (C)", "Endpoint C", Perspective::IS_SERVER,
+      test::TestConnectionId(44));
+  QuicEndpointMultiplexer endpoint_d(
+      "Endpoint D",
+      {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()});
+
+  // Create links with slightly different RTTs in order to avoid pathological
+  // side-effects of packets entering the queue at the exactly same time.
+  auto link_a = CustomLink(endpoint_a.get(), switch_.port(1), 0);
+  auto link_b = CustomLink(endpoint_b.get(), switch_.port(2), 1);
+  auto link_c = CustomLink(endpoint_c.get(), switch_.port(3), 2);
+  auto link_d = Link(&endpoint_d, switch_.port(4));
+
+  endpoint_a->AddBytesToTransfer(2 * 1024 * 1024);
+  endpoint_b->AddBytesToTransfer(2 * 1024 * 1024);
+  endpoint_c->AddBytesToTransfer(2 * 1024 * 1024);
+  QuicTime end_time =
+      simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(12);
+  simulator_.RunUntil(
+      [this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
+
+  for (QuicEndpoint* endpoint :
+       {endpoint_a.get(), endpoint_b.get(), endpoint_c.get()}) {
+    EXPECT_EQ(2u * 1024u * 1024u, endpoint->bytes_transferred());
+    EXPECT_GE(endpoint->connection()->GetStats().packets_lost, 0u);
+  }
+  for (QuicEndpoint* endpoint :
+       {endpoint_d_a.get(), endpoint_d_b.get(), endpoint_d_c.get()}) {
+    EXPECT_EQ(2u * 1024u * 1024u, endpoint->bytes_received());
+    EXPECT_FALSE(endpoint->wrong_data_received());
+  }
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/simulator.cc b/quiche/quic/test_tools/simulator/simulator.cc
new file mode 100644
index 0000000..2b3c5d5
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/simulator.cc
@@ -0,0 +1,170 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+namespace simulator {
+
+Simulator::Simulator() : Simulator(nullptr) {}
+
+Simulator::Simulator(QuicRandom* random_generator)
+    : random_generator_(random_generator),
+      alarm_factory_(this, "Default Alarm Manager"),
+      run_for_should_stop_(false),
+      enable_random_delays_(false) {
+  run_for_alarm_.reset(
+      alarm_factory_.CreateAlarm(new RunForDelegate(&run_for_should_stop_)));
+}
+
+Simulator::~Simulator() {
+  // Ensure that Actor under run_for_alarm_ is removed before Simulator data
+  // structures are destructed.
+  run_for_alarm_.reset();
+}
+
+Simulator::Clock::Clock() : now_(kStartTime) {}
+
+QuicTime Simulator::Clock::ApproximateNow() const {
+  return now_;
+}
+
+QuicTime Simulator::Clock::Now() const {
+  return now_;
+}
+
+QuicWallTime Simulator::Clock::WallNow() const {
+  return QuicWallTime::FromUNIXMicroseconds(
+      (now_ - QuicTime::Zero()).ToMicroseconds());
+}
+
+void Simulator::AddActor(Actor* actor) {
+  auto emplace_times_result =
+      scheduled_times_.insert(std::make_pair(actor, QuicTime::Infinite()));
+  auto emplace_names_result = actor_names_.insert(actor->name());
+
+  // Ensure that the object was actually placed into the map.
+  QUICHE_DCHECK(emplace_times_result.second);
+  QUICHE_DCHECK(emplace_names_result.second);
+}
+
+void Simulator::RemoveActor(Actor* actor) {
+  auto scheduled_time_it = scheduled_times_.find(actor);
+  auto actor_names_it = actor_names_.find(actor->name());
+  QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
+  QUICHE_DCHECK(actor_names_it != actor_names_.end());
+
+  QuicTime scheduled_time = scheduled_time_it->second;
+  if (scheduled_time != QuicTime::Infinite()) {
+    Unschedule(actor);
+  }
+
+  scheduled_times_.erase(scheduled_time_it);
+  actor_names_.erase(actor_names_it);
+}
+
+void Simulator::Schedule(Actor* actor, QuicTime new_time) {
+  auto scheduled_time_it = scheduled_times_.find(actor);
+  QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
+  QuicTime scheduled_time = scheduled_time_it->second;
+
+  if (scheduled_time <= new_time) {
+    return;
+  }
+
+  if (scheduled_time != QuicTime::Infinite()) {
+    Unschedule(actor);
+  }
+
+  scheduled_time_it->second = new_time;
+  schedule_.insert(std::make_pair(new_time, actor));
+}
+
+void Simulator::Unschedule(Actor* actor) {
+  auto scheduled_time_it = scheduled_times_.find(actor);
+  QUICHE_DCHECK(scheduled_time_it != scheduled_times_.end());
+  QuicTime scheduled_time = scheduled_time_it->second;
+
+  QUICHE_DCHECK(scheduled_time != QuicTime::Infinite());
+  auto range = schedule_.equal_range(scheduled_time);
+  for (auto it = range.first; it != range.second; ++it) {
+    if (it->second == actor) {
+      schedule_.erase(it);
+      scheduled_time_it->second = QuicTime::Infinite();
+      return;
+    }
+  }
+  QUICHE_DCHECK(false);
+}
+
+const QuicClock* Simulator::GetClock() const {
+  return &clock_;
+}
+
+QuicRandom* Simulator::GetRandomGenerator() {
+  if (random_generator_ == nullptr) {
+    random_generator_ = QuicRandom::GetInstance();
+  }
+
+  return random_generator_;
+}
+
+quiche::QuicheBufferAllocator* Simulator::GetStreamSendBufferAllocator() {
+  return &buffer_allocator_;
+}
+
+QuicAlarmFactory* Simulator::GetAlarmFactory() {
+  return &alarm_factory_;
+}
+
+Simulator::RunForDelegate::RunForDelegate(bool* run_for_should_stop)
+    : run_for_should_stop_(run_for_should_stop) {}
+
+void Simulator::RunForDelegate::OnAlarm() {
+  *run_for_should_stop_ = true;
+}
+
+void Simulator::RunFor(QuicTime::Delta time_span) {
+  QUICHE_DCHECK(!run_for_alarm_->IsSet());
+
+  // RunFor() ensures that the simulation stops at the exact time specified by
+  // scheduling an alarm at that point and using that alarm to abort the
+  // simulation.  An alarm is necessary because otherwise it is possible that
+  // nothing is scheduled at |end_time|, so the simulation will either go
+  // further than requested or stop before reaching |end_time|.
+  const QuicTime end_time = clock_.Now() + time_span;
+  run_for_alarm_->Set(end_time);
+  run_for_should_stop_ = false;
+  bool simulation_result = RunUntil([this]() { return run_for_should_stop_; });
+
+  QUICHE_DCHECK(simulation_result);
+  QUICHE_DCHECK(clock_.Now() == end_time);
+}
+
+void Simulator::HandleNextScheduledActor() {
+  const auto current_event_it = schedule_.begin();
+  QuicTime event_time = current_event_it->first;
+  Actor* actor = current_event_it->second;
+  QUIC_DVLOG(3) << "At t = " << event_time.ToDebuggingValue() << ", calling "
+                << actor->name();
+
+  Unschedule(actor);
+
+  if (clock_.Now() > event_time) {
+    QUIC_BUG(quic_bug_10150_1)
+        << "Error: event registered by [" << actor->name()
+        << "] requires travelling back in time.  Current time: "
+        << clock_.Now().ToDebuggingValue()
+        << ", scheduled time: " << event_time.ToDebuggingValue();
+  }
+  clock_.now_ = event_time;
+
+  actor->Act();
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/simulator.h b/quiche/quic/test_tools/simulator/simulator.h
new file mode 100644
index 0000000..0dabe4a
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/simulator.h
@@ -0,0 +1,167 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
+
+#include <map>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/test_tools/simulator/actor.h"
+#include "quiche/quic/test_tools/simulator/alarm_factory.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+namespace simulator {
+
+// Simulator is responsible for scheduling actors in the simulation and
+// providing basic utility interfaces (clock, alarms, RNG and others).
+class Simulator : public QuicConnectionHelperInterface {
+ public:
+  Simulator();
+  explicit Simulator(QuicRandom* random_generator);
+  Simulator(const Simulator&) = delete;
+  Simulator& operator=(const Simulator&) = delete;
+  ~Simulator() override;
+
+  // Schedule the specified actor.  This method will ensure that |actor| is
+  // called at |new_time| at latest.  If Schedule() is called multiple times
+  // before the Actor is called, Act() is called exactly once, at the earliest
+  // time requested, and the Actor has to reschedule itself manually for the
+  // subsequent times if they are still necessary.
+  void Schedule(Actor* actor, QuicTime new_time);
+
+  // Remove the specified actor from the schedule.
+  void Unschedule(Actor* actor);
+
+  // Begin QuicConnectionHelperInterface implementation.
+  const QuicClock* GetClock() const override;
+  QuicRandom* GetRandomGenerator() override;
+  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
+  // End QuicConnectionHelperInterface implementation.
+
+  QuicAlarmFactory* GetAlarmFactory();
+
+  void set_random_generator(QuicRandom* random) { random_generator_ = random; }
+
+  bool enable_random_delays() const { return enable_random_delays_; }
+
+  // Run the simulation until either no actors are scheduled or
+  // |termination_predicate| returns true.  Returns true if terminated due to
+  // predicate, and false otherwise.
+  template <class TerminationPredicate>
+  bool RunUntil(TerminationPredicate termination_predicate);
+
+  // Same as RunUntil, except this function also accepts a |deadline|, and will
+  // return false if the deadline is exceeded.
+  template <class TerminationPredicate>
+  bool RunUntilOrTimeout(TerminationPredicate termination_predicate,
+                         QuicTime::Delta deadline);
+
+  // Runs the simulation for exactly the specified |time_span|.
+  void RunFor(QuicTime::Delta time_span);
+
+ private:
+  friend class Actor;
+
+  class Clock : public QuicClock {
+   public:
+    // Do not start at zero as certain code can treat zero as an invalid
+    // timestamp.
+    const QuicTime kStartTime =
+        QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(1);
+
+    Clock();
+
+    QuicTime ApproximateNow() const override;
+    QuicTime Now() const override;
+    QuicWallTime WallNow() const override;
+
+    QuicTime now_;
+  };
+
+  // The delegate used for RunFor().
+  class RunForDelegate : public QuicAlarm::DelegateWithoutContext {
+   public:
+    explicit RunForDelegate(bool* run_for_should_stop);
+    void OnAlarm() override;
+
+   private:
+    // Pointer to |run_for_should_stop_| in the parent simulator.
+    bool* run_for_should_stop_;
+  };
+
+  // Register an actor with the simulator. Invoked by Actor constructor.
+  void AddActor(Actor* actor);
+
+  // Unregister an actor with the simulator. Invoked by Actor destructor.
+  void RemoveActor(Actor* actor);
+
+  // Finds the next scheduled actor, advances time to the schedule time and
+  // notifies the actor.
+  void HandleNextScheduledActor();
+
+  Clock clock_;
+  QuicRandom* random_generator_;
+  quiche::SimpleBufferAllocator buffer_allocator_;
+  AlarmFactory alarm_factory_;
+
+  // Alarm for RunFor() method.
+  std::unique_ptr<QuicAlarm> run_for_alarm_;
+  // Flag used to stop simulations ran via RunFor().
+  bool run_for_should_stop_;
+
+  // Indicates whether the simulator should add random delays on the links in
+  // order to avoid synchronization issues.
+  bool enable_random_delays_;
+
+  // Schedule of when the actors will be executed via an Act() call.  The
+  // schedule is subject to the following invariants:
+  // - An actor cannot be scheduled for a later time than it's currently in the
+  //   schedule.
+  // - An actor is removed from schedule either immediately before Act() is
+  //   called or by explicitly calling Unschedule().
+  // - Each Actor appears in the map at most once.
+  std::multimap<QuicTime, Actor*> schedule_;
+  // For each actor, maintain the time it is scheduled at.  The value for
+  // unscheduled actors is QuicTime::Infinite().
+  absl::flat_hash_map<Actor*, QuicTime> scheduled_times_;
+  absl::flat_hash_set<std::string> actor_names_;
+};
+
+template <class TerminationPredicate>
+bool Simulator::RunUntil(TerminationPredicate termination_predicate) {
+  bool predicate_value = false;
+  while (true) {
+    predicate_value = termination_predicate();
+    if (predicate_value || schedule_.empty()) {
+      break;
+    }
+    HandleNextScheduledActor();
+  }
+  return predicate_value;
+}
+
+template <class TerminationPredicate>
+bool Simulator::RunUntilOrTimeout(TerminationPredicate termination_predicate,
+                                  QuicTime::Delta timeout) {
+  QuicTime end_time = clock_.Now() + timeout;
+  bool return_value = RunUntil([end_time, &termination_predicate, this]() {
+    return termination_predicate() || clock_.Now() >= end_time;
+  });
+
+  if (clock_.Now() >= end_time) {
+    return false;
+  }
+  return return_value;
+}
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SIMULATOR_H_
diff --git a/quiche/quic/test_tools/simulator/simulator_test.cc b/quiche/quic/test_tools/simulator/simulator_test.cc
new file mode 100644
index 0000000..76ce046
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/simulator_test.cc
@@ -0,0 +1,832 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/simulator.h"
+
+#include <utility>
+
+#include "absl/container/node_hash_map.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/test_tools/simulator/alarm_factory.h"
+#include "quiche/quic/test_tools/simulator/link.h"
+#include "quiche/quic/test_tools/simulator/packet_filter.h"
+#include "quiche/quic/test_tools/simulator/queue.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+#include "quiche/quic/test_tools/simulator/traffic_policer.h"
+
+using testing::_;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace simulator {
+
+// A simple counter that increments its value by 1 every specified period.
+class Counter : public Actor {
+ public:
+  Counter(Simulator* simulator, std::string name, QuicTime::Delta period)
+      : Actor(simulator, name), value_(-1), period_(period) {
+    Schedule(clock_->Now());
+  }
+  ~Counter() override {}
+
+  inline int get_value() const { return value_; }
+
+  void Act() override {
+    ++value_;
+    QUIC_DVLOG(1) << name_ << " has value " << value_ << " at time "
+                  << clock_->Now().ToDebuggingValue();
+    Schedule(clock_->Now() + period_);
+  }
+
+ private:
+  int value_;
+  QuicTime::Delta period_;
+};
+
+class SimulatorTest : public QuicTest {};
+
+// Test that the basic event handling works, and that Actors can be created and
+// destroyed mid-simulation.
+TEST_F(SimulatorTest, Counters) {
+  Simulator simulator;
+  for (int i = 0; i < 2; ++i) {
+    Counter fast_counter(&simulator, "fast_counter",
+                         QuicTime::Delta::FromSeconds(3));
+    Counter slow_counter(&simulator, "slow_counter",
+                         QuicTime::Delta::FromSeconds(10));
+
+    simulator.RunUntil(
+        [&slow_counter]() { return slow_counter.get_value() >= 10; });
+
+    EXPECT_EQ(10, slow_counter.get_value());
+    EXPECT_EQ(10 * 10 / 3, fast_counter.get_value());
+  }
+}
+
+// A port which counts the number of packets received on it, both total and
+// per-destination.
+class CounterPort : public UnconstrainedPortInterface {
+ public:
+  CounterPort() { Reset(); }
+  ~CounterPort() override {}
+
+  inline QuicByteCount bytes() const { return bytes_; }
+  inline QuicPacketCount packets() const { return packets_; }
+
+  void AcceptPacket(std::unique_ptr<Packet> packet) override {
+    bytes_ += packet->size;
+    packets_ += 1;
+
+    per_destination_packet_counter_[packet->destination] += 1;
+  }
+
+  void Reset() {
+    bytes_ = 0;
+    packets_ = 0;
+    per_destination_packet_counter_.clear();
+  }
+
+  QuicPacketCount CountPacketsForDestination(std::string destination) const {
+    auto result_it = per_destination_packet_counter_.find(destination);
+    if (result_it == per_destination_packet_counter_.cend()) {
+      return 0;
+    }
+    return result_it->second;
+  }
+
+ private:
+  QuicByteCount bytes_;
+  QuicPacketCount packets_;
+
+  absl::node_hash_map<std::string, QuicPacketCount>
+      per_destination_packet_counter_;
+};
+
+// Sends the packet to the specified destination at the uplink rate.  Provides a
+// CounterPort as an Rx interface.
+class LinkSaturator : public Endpoint {
+ public:
+  LinkSaturator(Simulator* simulator,
+                std::string name,
+                QuicByteCount packet_size,
+                std::string destination)
+      : Endpoint(simulator, name),
+        packet_size_(packet_size),
+        destination_(std::move(destination)),
+        bytes_transmitted_(0),
+        packets_transmitted_(0) {
+    Schedule(clock_->Now());
+  }
+
+  void Act() override {
+    if (tx_port_->TimeUntilAvailable().IsZero()) {
+      auto packet = std::make_unique<Packet>();
+      packet->source = name_;
+      packet->destination = destination_;
+      packet->tx_timestamp = clock_->Now();
+      packet->size = packet_size_;
+
+      tx_port_->AcceptPacket(std::move(packet));
+
+      bytes_transmitted_ += packet_size_;
+      packets_transmitted_ += 1;
+    }
+
+    Schedule(clock_->Now() + tx_port_->TimeUntilAvailable());
+  }
+
+  UnconstrainedPortInterface* GetRxPort() override {
+    return static_cast<UnconstrainedPortInterface*>(&rx_port_);
+  }
+
+  void SetTxPort(ConstrainedPortInterface* port) override { tx_port_ = port; }
+
+  CounterPort* counter() { return &rx_port_; }
+
+  inline QuicByteCount bytes_transmitted() const { return bytes_transmitted_; }
+  inline QuicPacketCount packets_transmitted() const {
+    return packets_transmitted_;
+  }
+
+  void Pause() { Unschedule(); }
+  void Resume() { Schedule(clock_->Now()); }
+
+ private:
+  QuicByteCount packet_size_;
+  std::string destination_;
+
+  ConstrainedPortInterface* tx_port_;
+  CounterPort rx_port_;
+
+  QuicByteCount bytes_transmitted_;
+  QuicPacketCount packets_transmitted_;
+};
+
+// Saturate a symmetric link and verify that the number of packets sent and
+// received is correct.
+TEST_F(SimulatorTest, DirectLinkSaturation) {
+  Simulator simulator;
+  LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
+  LinkSaturator saturator_b(&simulator, "Saturator B", 100, "Saturator A");
+  SymmetricLink link(&saturator_a, &saturator_b,
+                     QuicBandwidth::FromKBytesPerSecond(1000),
+                     QuicTime::Delta::FromMilliseconds(100) +
+                         QuicTime::Delta::FromMicroseconds(1));
+
+  const QuicTime start_time = simulator.GetClock()->Now();
+  const QuicTime after_first_50_ms =
+      start_time + QuicTime::Delta::FromMilliseconds(50);
+  simulator.RunUntil([&simulator, after_first_50_ms]() {
+    return simulator.GetClock()->Now() >= after_first_50_ms;
+  });
+  EXPECT_LE(1000u * 50u, saturator_a.bytes_transmitted());
+  EXPECT_GE(1000u * 51u, saturator_a.bytes_transmitted());
+  EXPECT_LE(1000u * 50u, saturator_b.bytes_transmitted());
+  EXPECT_GE(1000u * 51u, saturator_b.bytes_transmitted());
+  EXPECT_LE(50u, saturator_a.packets_transmitted());
+  EXPECT_GE(51u, saturator_a.packets_transmitted());
+  EXPECT_LE(500u, saturator_b.packets_transmitted());
+  EXPECT_GE(501u, saturator_b.packets_transmitted());
+  EXPECT_EQ(0u, saturator_a.counter()->bytes());
+  EXPECT_EQ(0u, saturator_b.counter()->bytes());
+
+  simulator.RunUntil([&saturator_a, &saturator_b]() {
+    if (saturator_a.counter()->packets() > 1000 ||
+        saturator_b.counter()->packets() > 100) {
+      ADD_FAILURE() << "The simulation did not arrive at the expected "
+                       "termination contidition. Saturator A counter: "
+                    << saturator_a.counter()->packets()
+                    << ", saturator B counter: "
+                    << saturator_b.counter()->packets();
+      return true;
+    }
+
+    return saturator_a.counter()->packets() == 1000 &&
+           saturator_b.counter()->packets() == 100;
+  });
+  EXPECT_EQ(201u, saturator_a.packets_transmitted());
+  EXPECT_EQ(2001u, saturator_b.packets_transmitted());
+  EXPECT_EQ(201u * 1000, saturator_a.bytes_transmitted());
+  EXPECT_EQ(2001u * 100, saturator_b.bytes_transmitted());
+
+  EXPECT_EQ(1000u,
+            saturator_a.counter()->CountPacketsForDestination("Saturator A"));
+  EXPECT_EQ(100u,
+            saturator_b.counter()->CountPacketsForDestination("Saturator B"));
+  EXPECT_EQ(0u,
+            saturator_a.counter()->CountPacketsForDestination("Saturator B"));
+  EXPECT_EQ(0u,
+            saturator_b.counter()->CountPacketsForDestination("Saturator A"));
+
+  const QuicTime end_time = simulator.GetClock()->Now();
+  const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
+      saturator_a.bytes_transmitted(), end_time - start_time);
+  EXPECT_APPROX_EQ(link.bandwidth(), observed_bandwidth, 0.01f);
+}
+
+// Accepts packets and stores them internally.
+class PacketAcceptor : public ConstrainedPortInterface {
+ public:
+  void AcceptPacket(std::unique_ptr<Packet> packet) override {
+    packets_.emplace_back(std::move(packet));
+  }
+
+  QuicTime::Delta TimeUntilAvailable() override {
+    return QuicTime::Delta::Zero();
+  }
+
+  std::vector<std::unique_ptr<Packet>>* packets() { return &packets_; }
+
+ private:
+  std::vector<std::unique_ptr<Packet>> packets_;
+};
+
+// Ensure the queue behaves correctly with accepting packets.
+TEST_F(SimulatorTest, Queue) {
+  Simulator simulator;
+  Queue queue(&simulator, "Queue", 1000);
+  PacketAcceptor acceptor;
+  queue.set_tx_port(&acceptor);
+
+  EXPECT_EQ(0u, queue.bytes_queued());
+  EXPECT_EQ(0u, queue.packets_queued());
+  EXPECT_EQ(0u, acceptor.packets()->size());
+
+  auto first_packet = std::make_unique<Packet>();
+  first_packet->size = 600;
+  queue.AcceptPacket(std::move(first_packet));
+  EXPECT_EQ(600u, queue.bytes_queued());
+  EXPECT_EQ(1u, queue.packets_queued());
+  EXPECT_EQ(0u, acceptor.packets()->size());
+
+  // The second packet does not fit and is dropped.
+  auto second_packet = std::make_unique<Packet>();
+  second_packet->size = 500;
+  queue.AcceptPacket(std::move(second_packet));
+  EXPECT_EQ(600u, queue.bytes_queued());
+  EXPECT_EQ(1u, queue.packets_queued());
+  EXPECT_EQ(0u, acceptor.packets()->size());
+
+  auto third_packet = std::make_unique<Packet>();
+  third_packet->size = 400;
+  queue.AcceptPacket(std::move(third_packet));
+  EXPECT_EQ(1000u, queue.bytes_queued());
+  EXPECT_EQ(2u, queue.packets_queued());
+  EXPECT_EQ(0u, acceptor.packets()->size());
+
+  // Run until there is nothing scheduled, so that the queue can deplete.
+  simulator.RunUntil([]() { return false; });
+  EXPECT_EQ(0u, queue.bytes_queued());
+  EXPECT_EQ(0u, queue.packets_queued());
+  ASSERT_EQ(2u, acceptor.packets()->size());
+  EXPECT_EQ(600u, acceptor.packets()->at(0)->size);
+  EXPECT_EQ(400u, acceptor.packets()->at(1)->size);
+}
+
+// Simulate a situation where the bottleneck link is 10 times slower than the
+// uplink, and they are separated by a queue.
+TEST_F(SimulatorTest, QueueBottleneck) {
+  const QuicBandwidth local_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(1000);
+  const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
+  const QuicTime::Delta local_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(1);
+  const QuicTime::Delta bottleneck_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(20);
+  const QuicByteCount bdp =
+      bottleneck_bandwidth *
+      (local_propagation_delay + bottleneck_propagation_delay);
+
+  Simulator simulator;
+  LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
+  ASSERT_GE(bdp, 1000u);
+  Queue queue(&simulator, "Queue", bdp);
+  CounterPort counter;
+
+  OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
+                        local_propagation_delay);
+  OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
+                             bottleneck_bandwidth,
+                             bottleneck_propagation_delay);
+  saturator.SetTxPort(&local_link);
+  queue.set_tx_port(&bottleneck_link);
+
+  static const QuicPacketCount packets_received = 1000;
+  simulator.RunUntil(
+      [&counter]() { return counter.packets() == packets_received; });
+  const double loss_ratio = 1 - static_cast<double>(packets_received) /
+                                    saturator.packets_transmitted();
+  EXPECT_NEAR(loss_ratio, 0.9, 0.001);
+}
+
+// Verify that the queue of exactly one packet allows the transmission to
+// actually go through.
+TEST_F(SimulatorTest, OnePacketQueue) {
+  const QuicBandwidth local_bandwidth =
+      QuicBandwidth::FromKBytesPerSecond(1000);
+  const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
+  const QuicTime::Delta local_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(1);
+  const QuicTime::Delta bottleneck_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(20);
+
+  Simulator simulator;
+  LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
+  Queue queue(&simulator, "Queue", 1000);
+  CounterPort counter;
+
+  OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
+                        local_propagation_delay);
+  OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
+                             bottleneck_bandwidth,
+                             bottleneck_propagation_delay);
+  saturator.SetTxPort(&local_link);
+  queue.set_tx_port(&bottleneck_link);
+
+  static const QuicPacketCount packets_received = 10;
+  // The deadline here is to prevent this tests from looping infinitely in case
+  // the packets never reach the receiver.
+  const QuicTime deadline =
+      simulator.GetClock()->Now() + QuicTime::Delta::FromSeconds(10);
+  simulator.RunUntil([&simulator, &counter, deadline]() {
+    return counter.packets() == packets_received ||
+           simulator.GetClock()->Now() > deadline;
+  });
+  ASSERT_EQ(packets_received, counter.packets());
+}
+
+// Simulate a network where three endpoints are connected to a switch and they
+// are sending traffic in circle (1 -> 2, 2 -> 3, 3 -> 1).
+TEST_F(SimulatorTest, SwitchedNetwork) {
+  const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(10000);
+  const QuicTime::Delta base_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(50);
+
+  Simulator simulator;
+  LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
+  LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 3");
+  LinkSaturator saturator3(&simulator, "Saturator 3", 1000, "Saturator 1");
+  Switch network_switch(&simulator, "Switch", 8,
+                        bandwidth * base_propagation_delay * 10);
+
+  // For determinicity, make it so that the first packet will arrive from
+  // Saturator 1, then from Saturator 2, and then from Saturator 3.
+  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
+                      base_propagation_delay);
+  SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
+                      base_propagation_delay * 2);
+  SymmetricLink link3(&saturator3, network_switch.port(3), bandwidth,
+                      base_propagation_delay * 3);
+
+  const QuicTime start_time = simulator.GetClock()->Now();
+  static const QuicPacketCount bytes_received = 64 * 1000;
+  simulator.RunUntil([&saturator1]() {
+    return saturator1.counter()->bytes() >= bytes_received;
+  });
+  const QuicTime end_time = simulator.GetClock()->Now();
+
+  const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
+      bytes_received, end_time - start_time);
+  const double bandwidth_ratio =
+      static_cast<double>(observed_bandwidth.ToBitsPerSecond()) /
+      bandwidth.ToBitsPerSecond();
+  EXPECT_NEAR(1, bandwidth_ratio, 0.1);
+
+  const double normalized_received_packets_for_saturator_2 =
+      static_cast<double>(saturator2.counter()->packets()) /
+      saturator1.counter()->packets();
+  const double normalized_received_packets_for_saturator_3 =
+      static_cast<double>(saturator3.counter()->packets()) /
+      saturator1.counter()->packets();
+  EXPECT_NEAR(1, normalized_received_packets_for_saturator_2, 0.1);
+  EXPECT_NEAR(1, normalized_received_packets_for_saturator_3, 0.1);
+
+  // Since Saturator 1 has its packet arrive first into the switch, switch will
+  // always know how to route traffic to it.
+  EXPECT_EQ(0u,
+            saturator2.counter()->CountPacketsForDestination("Saturator 1"));
+  EXPECT_EQ(0u,
+            saturator3.counter()->CountPacketsForDestination("Saturator 1"));
+
+  // Packets from the other saturators will be broadcast at least once.
+  EXPECT_EQ(1u,
+            saturator1.counter()->CountPacketsForDestination("Saturator 2"));
+  EXPECT_EQ(1u,
+            saturator3.counter()->CountPacketsForDestination("Saturator 2"));
+  EXPECT_EQ(1u,
+            saturator1.counter()->CountPacketsForDestination("Saturator 3"));
+  EXPECT_EQ(1u,
+            saturator2.counter()->CountPacketsForDestination("Saturator 3"));
+}
+
+// Toggle an alarm on and off at the specified interval.  Assumes that alarm is
+// initially set and unsets it almost immediately after the object is
+// instantiated.
+class AlarmToggler : public Actor {
+ public:
+  AlarmToggler(Simulator* simulator,
+               std::string name,
+               QuicAlarm* alarm,
+               QuicTime::Delta interval)
+      : Actor(simulator, name),
+        alarm_(alarm),
+        interval_(interval),
+        deadline_(alarm->deadline()),
+        times_set_(0),
+        times_cancelled_(0) {
+    EXPECT_TRUE(alarm->IsSet());
+    EXPECT_GE(alarm->deadline(), clock_->Now());
+    Schedule(clock_->Now());
+  }
+
+  void Act() override {
+    if (deadline_ <= clock_->Now()) {
+      return;
+    }
+
+    if (alarm_->IsSet()) {
+      alarm_->Cancel();
+      times_cancelled_++;
+    } else {
+      alarm_->Set(deadline_);
+      times_set_++;
+    }
+
+    Schedule(clock_->Now() + interval_);
+  }
+
+  inline int times_set() { return times_set_; }
+  inline int times_cancelled() { return times_cancelled_; }
+
+ private:
+  QuicAlarm* alarm_;
+  QuicTime::Delta interval_;
+  QuicTime deadline_;
+
+  // Counts the number of times the alarm was set.
+  int times_set_;
+  // Counts the number of times the alarm was cancelled.
+  int times_cancelled_;
+};
+
+// Counts the number of times an alarm has fired.
+class CounterDelegate : public QuicAlarm::DelegateWithoutContext {
+ public:
+  explicit CounterDelegate(size_t* counter) : counter_(counter) {}
+
+  void OnAlarm() override { *counter_ += 1; }
+
+ private:
+  size_t* counter_;
+};
+
+// Verifies that the alarms work correctly, even when they are repeatedly
+// toggled.
+TEST_F(SimulatorTest, Alarms) {
+  Simulator simulator;
+  QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
+
+  size_t fast_alarm_counter = 0;
+  size_t slow_alarm_counter = 0;
+  std::unique_ptr<QuicAlarm> alarm_fast(
+      alarm_factory->CreateAlarm(new CounterDelegate(&fast_alarm_counter)));
+  std::unique_ptr<QuicAlarm> alarm_slow(
+      alarm_factory->CreateAlarm(new CounterDelegate(&slow_alarm_counter)));
+
+  const QuicTime start_time = simulator.GetClock()->Now();
+  alarm_fast->Set(start_time + QuicTime::Delta::FromMilliseconds(100));
+  alarm_slow->Set(start_time + QuicTime::Delta::FromMilliseconds(750));
+  AlarmToggler toggler(&simulator, "Toggler", alarm_slow.get(),
+                       QuicTime::Delta::FromMilliseconds(100));
+
+  const QuicTime end_time =
+      start_time + QuicTime::Delta::FromMilliseconds(1000);
+  EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
+    return simulator.GetClock()->Now() >= end_time;
+  }));
+  EXPECT_EQ(1u, slow_alarm_counter);
+  EXPECT_EQ(1u, fast_alarm_counter);
+
+  EXPECT_EQ(4, toggler.times_set());
+  EXPECT_EQ(4, toggler.times_cancelled());
+}
+
+// Verifies that a cancelled alarm is never fired.
+TEST_F(SimulatorTest, AlarmCancelling) {
+  Simulator simulator;
+  QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
+
+  size_t alarm_counter = 0;
+  std::unique_ptr<QuicAlarm> alarm(
+      alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
+
+  const QuicTime start_time = simulator.GetClock()->Now();
+  const QuicTime alarm_at = start_time + QuicTime::Delta::FromMilliseconds(300);
+  const QuicTime end_time = start_time + QuicTime::Delta::FromMilliseconds(400);
+
+  alarm->Set(alarm_at);
+  alarm->Cancel();
+  EXPECT_FALSE(alarm->IsSet());
+
+  EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
+    return simulator.GetClock()->Now() >= end_time;
+  }));
+
+  EXPECT_FALSE(alarm->IsSet());
+  EXPECT_EQ(0u, alarm_counter);
+}
+
+// Verifies that alarms can be scheduled into the past.
+TEST_F(SimulatorTest, AlarmInPast) {
+  Simulator simulator;
+  QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
+
+  size_t alarm_counter = 0;
+  std::unique_ptr<QuicAlarm> alarm(
+      alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
+
+  const QuicTime start_time = simulator.GetClock()->Now();
+  simulator.RunFor(QuicTime::Delta::FromMilliseconds(400));
+
+  alarm->Set(start_time);
+  simulator.RunFor(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_FALSE(alarm->IsSet());
+  EXPECT_EQ(1u, alarm_counter);
+}
+
+// Tests Simulator::RunUntilOrTimeout() interface.
+TEST_F(SimulatorTest, RunUntilOrTimeout) {
+  Simulator simulator;
+  bool simulation_result;
+
+  // Count the number of seconds since the beginning of the simulation.
+  Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(1));
+
+  // Ensure that the counter reaches the value of 10 given a 20 second deadline.
+  simulation_result = simulator.RunUntilOrTimeout(
+      [&counter]() { return counter.get_value() == 10; },
+      QuicTime::Delta::FromSeconds(20));
+  ASSERT_TRUE(simulation_result);
+
+  // Ensure that the counter will not reach the value of 100 given that the
+  // starting value is 10 and the deadline is 20 seconds.
+  simulation_result = simulator.RunUntilOrTimeout(
+      [&counter]() { return counter.get_value() == 100; },
+      QuicTime::Delta::FromSeconds(20));
+  ASSERT_FALSE(simulation_result);
+}
+
+// Tests Simulator::RunFor() interface.
+TEST_F(SimulatorTest, RunFor) {
+  Simulator simulator;
+
+  Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(3));
+
+  simulator.RunFor(QuicTime::Delta::FromSeconds(100));
+
+  EXPECT_EQ(33, counter.get_value());
+}
+
+class MockPacketFilter : public PacketFilter {
+ public:
+  MockPacketFilter(Simulator* simulator, std::string name, Endpoint* endpoint)
+      : PacketFilter(simulator, name, endpoint) {}
+  MOCK_METHOD(bool, FilterPacket, (const Packet&), (override));
+};
+
+// Set up two trivial packet filters, one allowing any packets, and one dropping
+// all of them.
+TEST_F(SimulatorTest, PacketFilter) {
+  const QuicBandwidth bandwidth =
+      QuicBandwidth::FromBytesPerSecond(1024 * 1024);
+  const QuicTime::Delta base_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(5);
+
+  Simulator simulator;
+  LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
+  LinkSaturator saturator_b(&simulator, "Saturator B", 1000, "Saturator A");
+
+  // Attach packets to the switch to create a delay between the point at which
+  // the packet is generated and the point at which it is filtered.  Note that
+  // if the saturators were connected directly, the link would be always
+  // available for the endpoint which has all of its packets dropped, resulting
+  // in saturator looping infinitely.
+  Switch network_switch(&simulator, "Switch", 8,
+                        bandwidth * base_propagation_delay * 10);
+  StrictMock<MockPacketFilter> a_to_b_filter(&simulator, "A -> B filter",
+                                             network_switch.port(1));
+  StrictMock<MockPacketFilter> b_to_a_filter(&simulator, "B -> A filter",
+                                             network_switch.port(2));
+  SymmetricLink link_a(&a_to_b_filter, &saturator_b, bandwidth,
+                       base_propagation_delay);
+  SymmetricLink link_b(&b_to_a_filter, &saturator_a, bandwidth,
+                       base_propagation_delay);
+
+  // Allow packets from A to B, but not from B to A.
+  EXPECT_CALL(a_to_b_filter, FilterPacket(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(b_to_a_filter, FilterPacket(_)).WillRepeatedly(Return(false));
+
+  // Run the simulation for a while, and expect that only B will receive any
+  // packets.
+  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_GE(saturator_b.counter()->packets(), 1u);
+  EXPECT_EQ(saturator_a.counter()->packets(), 0u);
+}
+
+// Set up a traffic policer in one direction that throttles at 25% of link
+// bandwidth, and put two link saturators at each endpoint.
+TEST_F(SimulatorTest, TrafficPolicer) {
+  const QuicBandwidth bandwidth =
+      QuicBandwidth::FromBytesPerSecond(1024 * 1024);
+  const QuicTime::Delta base_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(5);
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+
+  Simulator simulator;
+  LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
+  LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
+  Switch network_switch(&simulator, "Switch", 8,
+                        bandwidth * base_propagation_delay * 10);
+
+  static const QuicByteCount initial_burst = 1000 * 10;
+  static const QuicByteCount max_bucket_size = 1000 * 100;
+  static const QuicBandwidth target_bandwidth = bandwidth * 0.25;
+  TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
+                         target_bandwidth, network_switch.port(2));
+
+  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
+                      base_propagation_delay);
+  SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
+
+  // Ensure the initial burst passes without being dropped at all.
+  bool simulator_result = simulator.RunUntilOrTimeout(
+      [&saturator1]() {
+        return saturator1.bytes_transmitted() == initial_burst;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  saturator1.Pause();
+  simulator_result = simulator.RunUntilOrTimeout(
+      [&saturator2]() {
+        return saturator2.counter()->bytes() == initial_burst;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  saturator1.Resume();
+
+  // Run for some time so that the initial burst is not visible.
+  const QuicTime::Delta simulation_time = QuicTime::Delta::FromSeconds(10);
+  simulator.RunFor(simulation_time);
+
+  // Ensure we've transmitted the amount of data we expected.
+  for (auto* saturator : {&saturator1, &saturator2}) {
+    EXPECT_APPROX_EQ(bandwidth * simulation_time,
+                     saturator->bytes_transmitted(), 0.01f);
+  }
+
+  // Check that only one direction is throttled.
+  EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
+                   saturator2.counter()->bytes(), 0.1f);
+  EXPECT_APPROX_EQ(saturator2.bytes_transmitted(),
+                   saturator1.counter()->bytes(), 0.1f);
+}
+
+// Ensure that a larger burst is allowed when the policed saturator exits
+// quiescence.
+TEST_F(SimulatorTest, TrafficPolicerBurst) {
+  const QuicBandwidth bandwidth =
+      QuicBandwidth::FromBytesPerSecond(1024 * 1024);
+  const QuicTime::Delta base_propagation_delay =
+      QuicTime::Delta::FromMilliseconds(5);
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+
+  Simulator simulator;
+  LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
+  LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
+  Switch network_switch(&simulator, "Switch", 8,
+                        bandwidth * base_propagation_delay * 10);
+
+  const QuicByteCount initial_burst = 1000 * 10;
+  const QuicByteCount max_bucket_size = 1000 * 100;
+  const QuicBandwidth target_bandwidth = bandwidth * 0.25;
+  TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
+                         target_bandwidth, network_switch.port(2));
+
+  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
+                      base_propagation_delay);
+  SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
+
+  // Ensure at least one packet is sent on each side.
+  bool simulator_result = simulator.RunUntilOrTimeout(
+      [&saturator1, &saturator2]() {
+        return saturator1.packets_transmitted() > 0 &&
+               saturator2.packets_transmitted() > 0;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Wait until the bucket fills up.
+  saturator1.Pause();
+  saturator2.Pause();
+  simulator.RunFor(1.5f * target_bandwidth.TransferTime(max_bucket_size));
+
+  // Send a burst.
+  saturator1.Resume();
+  simulator.RunFor(bandwidth.TransferTime(max_bucket_size));
+  saturator1.Pause();
+  simulator.RunFor(2 * base_propagation_delay);
+
+  // Expect the burst to pass without losses.
+  EXPECT_APPROX_EQ(saturator1.bytes_transmitted(),
+                   saturator2.counter()->bytes(), 0.1f);
+
+  // Expect subsequent traffic to be policed.
+  saturator1.Resume();
+  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
+                   saturator2.counter()->bytes(), 0.1f);
+}
+
+// Test that the packet aggregation support in queues work.
+TEST_F(SimulatorTest, PacketAggregation) {
+  // Model network where the delays are dominated by transfer delay.
+  const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000);
+  const QuicTime::Delta base_propagation_delay =
+      QuicTime::Delta::FromMicroseconds(1);
+  const QuicByteCount aggregation_threshold = 1000;
+  const QuicTime::Delta aggregation_timeout = QuicTime::Delta::FromSeconds(30);
+
+  Simulator simulator;
+  LinkSaturator saturator1(&simulator, "Saturator 1", 10, "Saturator 2");
+  LinkSaturator saturator2(&simulator, "Saturator 2", 10, "Saturator 1");
+  Switch network_switch(&simulator, "Switch", 8, 10 * aggregation_threshold);
+
+  // Make links with asymmetric propagation delay so that Saturator 2 only
+  // receives packets addressed to it.
+  SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
+                      base_propagation_delay);
+  SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
+                      2 * base_propagation_delay);
+
+  // Enable aggregation in 1 -> 2 direction.
+  Queue* queue = network_switch.port_queue(2);
+  queue->EnableAggregation(aggregation_threshold, aggregation_timeout);
+
+  // Enable aggregation in 2 -> 1 direction in a way that all packets are larger
+  // than the threshold, so that aggregation is effectively a no-op.
+  network_switch.port_queue(1)->EnableAggregation(5, aggregation_timeout);
+
+  // Fill up the aggregation buffer up to 90% (900 bytes).
+  simulator.RunFor(0.9 * bandwidth.TransferTime(aggregation_threshold));
+  EXPECT_EQ(0u, saturator2.counter()->bytes());
+
+  // Stop sending, ensure that given a timespan much shorter than timeout, the
+  // packets remain in the queue.
+  saturator1.Pause();
+  saturator2.Pause();
+  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_EQ(0u, saturator2.counter()->bytes());
+  EXPECT_EQ(900u, queue->bytes_queued());
+
+  // Ensure that all packets have reached the saturator not affected by
+  // aggregation.  Here, 10 extra bytes account for a misrouted packet in the
+  // beginning.
+  EXPECT_EQ(910u, saturator1.counter()->bytes());
+
+  // Send 500 more bytes.  Since the aggregation threshold is 1000 bytes, and
+  // queue already has 900 bytes, 1000 bytes will be send and 400 will be in the
+  // queue.
+  saturator1.Resume();
+  simulator.RunFor(0.5 * bandwidth.TransferTime(aggregation_threshold));
+  saturator1.Pause();
+  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_EQ(1000u, saturator2.counter()->bytes());
+  EXPECT_EQ(400u, queue->bytes_queued());
+
+  // Actually time out, and cause all of the data to be received.
+  simulator.RunFor(aggregation_timeout);
+  EXPECT_EQ(1400u, saturator2.counter()->bytes());
+  EXPECT_EQ(0u, queue->bytes_queued());
+
+  // Run saturator for a longer time, to ensure that the logic to cancel and
+  // reset alarms works correctly.
+  saturator1.Resume();
+  simulator.RunFor(5.5 * bandwidth.TransferTime(aggregation_threshold));
+  saturator1.Pause();
+  simulator.RunFor(QuicTime::Delta::FromSeconds(10));
+  EXPECT_EQ(6400u, saturator2.counter()->bytes());
+  EXPECT_EQ(500u, queue->bytes_queued());
+
+  // Time out again.
+  simulator.RunFor(aggregation_timeout);
+  EXPECT_EQ(6900u, saturator2.counter()->bytes());
+  EXPECT_EQ(0u, queue->bytes_queued());
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/switch.cc b/quiche/quic/test_tools/simulator/switch.cc
new file mode 100644
index 0000000..f897ccb
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/switch.cc
@@ -0,0 +1,83 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cinttypes>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace simulator {
+
+Switch::Switch(Simulator* simulator,
+               std::string name,
+               SwitchPortNumber port_count,
+               QuicByteCount queue_capacity) {
+  for (size_t port_number = 1; port_number <= port_count; port_number++) {
+    ports_.emplace_back(simulator,
+                        absl::StrCat(name, " (port ", port_number, ")"), this,
+                        port_number, queue_capacity);
+  }
+}
+
+Switch::~Switch() {}
+
+Switch::Port::Port(Simulator* simulator,
+                   std::string name,
+                   Switch* parent,
+                   SwitchPortNumber port_number,
+                   QuicByteCount queue_capacity)
+    : Endpoint(simulator, name),
+      parent_(parent),
+      port_number_(port_number),
+      connected_(false),
+      queue_(simulator, absl::StrCat(name, " (queue)"), queue_capacity) {}
+
+void Switch::Port::AcceptPacket(std::unique_ptr<Packet> packet) {
+  parent_->DispatchPacket(port_number_, std::move(packet));
+}
+
+void Switch::Port::EnqueuePacket(std::unique_ptr<Packet> packet) {
+  queue_.AcceptPacket(std::move(packet));
+}
+
+UnconstrainedPortInterface* Switch::Port::GetRxPort() {
+  return this;
+}
+
+void Switch::Port::SetTxPort(ConstrainedPortInterface* port) {
+  queue_.set_tx_port(port);
+  connected_ = true;
+}
+
+void Switch::Port::Act() {}
+
+void Switch::DispatchPacket(SwitchPortNumber port_number,
+                            std::unique_ptr<Packet> packet) {
+  Port* source_port = &ports_[port_number - 1];
+  const auto source_mapping_it = switching_table_.find(packet->source);
+  if (source_mapping_it == switching_table_.end()) {
+    switching_table_.insert(std::make_pair(packet->source, source_port));
+  }
+
+  const auto destination_mapping_it =
+      switching_table_.find(packet->destination);
+  if (destination_mapping_it != switching_table_.end()) {
+    destination_mapping_it->second->EnqueuePacket(std::move(packet));
+    return;
+  }
+
+  // If no mapping is available yet, broadcast the packet to all ports
+  // different from the source.
+  for (Port& egress_port : ports_) {
+    if (!egress_port.connected()) {
+      continue;
+    }
+    egress_port.EnqueuePacket(std::make_unique<Packet>(*packet));
+  }
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/switch.h b/quiche/quic/test_tools/simulator/switch.h
new file mode 100644
index 0000000..df25367
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/switch.h
@@ -0,0 +1,90 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
+
+#include <deque>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/test_tools/simulator/queue.h"
+
+namespace quic {
+namespace simulator {
+
+using SwitchPortNumber = size_t;
+
+// Simulates a network switch with simple persistent learning scheme and queues
+// on every output port.
+class Switch {
+ public:
+  Switch(Simulator* simulator,
+         std::string name,
+         SwitchPortNumber port_count,
+         QuicByteCount queue_capacity);
+  Switch(const Switch&) = delete;
+  Switch& operator=(const Switch&) = delete;
+  ~Switch();
+
+  // Returns Endpoint associated with the port under number |port_number|.  Just
+  // like on most real switches, port numbering starts with 1.
+  Endpoint* port(SwitchPortNumber port_number) {
+    QUICHE_DCHECK_NE(port_number, 0u);
+    return &ports_[port_number - 1];
+  }
+
+  Queue* port_queue(SwitchPortNumber port_number) {
+    return ports_[port_number - 1].queue();
+  }
+
+ private:
+  class Port : public Endpoint, public UnconstrainedPortInterface {
+   public:
+    Port(Simulator* simulator,
+         std::string name,
+         Switch* parent,
+         SwitchPortNumber port_number,
+         QuicByteCount queue_capacity);
+    Port(Port&&) = delete;
+    Port(const Port&) = delete;
+    Port& operator=(const Port&) = delete;
+    ~Port() override {}
+
+    // Accepts packet to be routed into the switch.
+    void AcceptPacket(std::unique_ptr<Packet> packet) override;
+    // Enqueue packet to be routed out of the switch.
+    void EnqueuePacket(std::unique_ptr<Packet> packet);
+
+    UnconstrainedPortInterface* GetRxPort() override;
+    void SetTxPort(ConstrainedPortInterface* port) override;
+
+    void Act() override;
+
+    bool connected() const { return connected_; }
+    Queue* queue() { return &queue_; }
+
+   private:
+    Switch* parent_;
+    SwitchPortNumber port_number_;
+    bool connected_;
+
+    Queue queue_;
+  };
+
+  // Sends the packet to the appropriate port, or to all ports if the
+  // appropriate port is not known.
+  void DispatchPacket(SwitchPortNumber port_number,
+                      std::unique_ptr<Packet> packet);
+
+  // This cannot be a quiche::QuicheCircularDeque since pointers into this are
+  // assumed to be stable.
+  std::deque<Port> ports_;
+  absl::flat_hash_map<std::string, Port*> switching_table_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_SWITCH_H_
diff --git a/quiche/quic/test_tools/simulator/traffic_policer.cc b/quiche/quic/test_tools/simulator/traffic_policer.cc
new file mode 100644
index 0000000..8bd3a24
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/traffic_policer.cc
@@ -0,0 +1,60 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/simulator/traffic_policer.h"
+
+#include <algorithm>
+
+namespace quic {
+namespace simulator {
+
+TrafficPolicer::TrafficPolicer(Simulator* simulator,
+                               std::string name,
+                               QuicByteCount initial_bucket_size,
+                               QuicByteCount max_bucket_size,
+                               QuicBandwidth target_bandwidth,
+                               Endpoint* input)
+    : PacketFilter(simulator, name, input),
+      initial_bucket_size_(initial_bucket_size),
+      max_bucket_size_(max_bucket_size),
+      target_bandwidth_(target_bandwidth),
+      last_refill_time_(clock_->Now()) {}
+
+TrafficPolicer::~TrafficPolicer() {}
+
+void TrafficPolicer::Refill() {
+  QuicTime::Delta time_passed = clock_->Now() - last_refill_time_;
+  QuicByteCount refill_size = time_passed * target_bandwidth_;
+
+  for (auto& bucket : token_buckets_) {
+    bucket.second = std::min(bucket.second + refill_size, max_bucket_size_);
+  }
+
+  last_refill_time_ = clock_->Now();
+}
+
+bool TrafficPolicer::FilterPacket(const Packet& packet) {
+  // Refill existing buckets.
+  Refill();
+
+  // Create a new bucket if one does not exist.
+  if (token_buckets_.count(packet.destination) == 0) {
+    token_buckets_.insert(
+        std::make_pair(packet.destination, initial_bucket_size_));
+  }
+
+  auto bucket = token_buckets_.find(packet.destination);
+  QUICHE_DCHECK(bucket != token_buckets_.end());
+
+  // Silently drop the packet on the floor if out of tokens
+  if (bucket->second < packet.size) {
+    return false;
+  }
+
+  bucket->second -= packet.size;
+  return true;
+}
+
+}  // namespace simulator
+}  // namespace quic
diff --git a/quiche/quic/test_tools/simulator/traffic_policer.h b/quiche/quic/test_tools/simulator/traffic_policer.h
new file mode 100644
index 0000000..f8b889e
--- /dev/null
+++ b/quiche/quic/test_tools/simulator/traffic_policer.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
+#define QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/test_tools/simulator/packet_filter.h"
+#include "quiche/quic/test_tools/simulator/port.h"
+
+namespace quic {
+namespace simulator {
+
+// Traffic policer uses a token bucket to limit the bandwidth of the traffic
+// passing through.  It wraps around an input port and exposes an output port.
+// Only the traffic from input to the output is policed, so in case when
+// bidirectional policing is desired, two policers have to be used.  The flows
+// are hashed by the destination only.
+class TrafficPolicer : public PacketFilter {
+ public:
+  TrafficPolicer(Simulator* simulator,
+                 std::string name,
+                 QuicByteCount initial_bucket_size,
+                 QuicByteCount max_bucket_size,
+                 QuicBandwidth target_bandwidth,
+                 Endpoint* input);
+  TrafficPolicer(const TrafficPolicer&) = delete;
+  TrafficPolicer& operator=(const TrafficPolicer&) = delete;
+  ~TrafficPolicer() override;
+
+ protected:
+  bool FilterPacket(const Packet& packet) override;
+
+ private:
+  // Refill the token buckets with all the tokens that have been granted since
+  // |last_refill_time_|.
+  void Refill();
+
+  QuicByteCount initial_bucket_size_;
+  QuicByteCount max_bucket_size_;
+  QuicBandwidth target_bandwidth_;
+
+  // The time at which the token buckets were last refilled.
+  QuicTime last_refill_time_;
+
+  // Maps each destination to the number of tokens it has left.
+  absl::flat_hash_map<std::string, QuicByteCount> token_buckets_;
+};
+
+}  // namespace simulator
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_SIMULATOR_TRAFFIC_POLICER_H_
diff --git a/quiche/quic/test_tools/test_certificates.cc b/quiche/quic/test_tools/test_certificates.cc
new file mode 100644
index 0000000..67ef981
--- /dev/null
+++ b/quiche/quic/test_tools/test_certificates.cc
@@ -0,0 +1,734 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/test_certificates.h"
+
+namespace quic {
+namespace test {
+
+// A test certificate generated by //net/tools/quic/certs/generate-certs.sh.
+ABSL_CONST_INIT const char kTestCertificateRaw[] = {
+    '\x30', '\x82', '\x03', '\xb4', '\x30', '\x82', '\x02', '\x9c', '\xa0',
+    '\x03', '\x02', '\x01', '\x02', '\x02', '\x01', '\x01', '\x30', '\x0d',
+    '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
+    '\x01', '\x0b', '\x05', '\x00', '\x30', '\x1e', '\x31', '\x1c', '\x30',
+    '\x1a', '\x06', '\x03', '\x55', '\x04', '\x03', '\x0c', '\x13', '\x51',
+    '\x55', '\x49', '\x43', '\x20', '\x53', '\x65', '\x72', '\x76', '\x65',
+    '\x72', '\x20', '\x52', '\x6f', '\x6f', '\x74', '\x20', '\x43', '\x41',
+    '\x30', '\x1e', '\x17', '\x0d', '\x32', '\x30', '\x30', '\x31', '\x33',
+    '\x30', '\x31', '\x38', '\x31', '\x33', '\x35', '\x39', '\x5a', '\x17',
+    '\x0d', '\x32', '\x30', '\x30', '\x32', '\x30', '\x32', '\x31', '\x38',
+    '\x31', '\x33', '\x35', '\x39', '\x5a', '\x30', '\x64', '\x31', '\x0b',
+    '\x30', '\x09', '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02',
+    '\x55', '\x53', '\x31', '\x13', '\x30', '\x11', '\x06', '\x03', '\x55',
+    '\x04', '\x08', '\x0c', '\x0a', '\x43', '\x61', '\x6c', '\x69', '\x66',
+    '\x6f', '\x72', '\x6e', '\x69', '\x61', '\x31', '\x16', '\x30', '\x14',
+    '\x06', '\x03', '\x55', '\x04', '\x07', '\x0c', '\x0d', '\x4d', '\x6f',
+    '\x75', '\x6e', '\x74', '\x61', '\x69', '\x6e', '\x20', '\x56', '\x69',
+    '\x65', '\x77', '\x31', '\x14', '\x30', '\x12', '\x06', '\x03', '\x55',
+    '\x04', '\x0a', '\x0c', '\x0b', '\x51', '\x55', '\x49', '\x43', '\x20',
+    '\x53', '\x65', '\x72', '\x76', '\x65', '\x72', '\x31', '\x12', '\x30',
+    '\x10', '\x06', '\x03', '\x55', '\x04', '\x03', '\x0c', '\x09', '\x31',
+    '\x32', '\x37', '\x2e', '\x30', '\x2e', '\x30', '\x2e', '\x31', '\x30',
+    '\x82', '\x01', '\x22', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86',
+    '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00',
+    '\x03', '\x82', '\x01', '\x0f', '\x00', '\x30', '\x82', '\x01', '\x0a',
+    '\x02', '\x82', '\x01', '\x01', '\x00', '\xc5', '\xe2', '\x51', '\x6d',
+    '\x3f', '\xd6', '\x28', '\xf2', '\xad', '\x34', '\x73', '\x87', '\x64',
+    '\xca', '\x33', '\x19', '\x33', '\xb7', '\x75', '\x91', '\xab', '\x31',
+    '\x19', '\x2b', '\xe3', '\xa4', '\x26', '\x09', '\x29', '\x8b', '\x2d',
+    '\xf7', '\x52', '\x75', '\xa7', '\x55', '\x15', '\xf0', '\x11', '\xc7',
+    '\xc2', '\xc4', '\xed', '\x18', '\x1b', '\x33', '\x0b', '\x71', '\x32',
+    '\xe6', '\x35', '\x89', '\xcd', '\x2d', '\x5a', '\x05', '\x57', '\x4e',
+    '\xc2', '\x78', '\x75', '\x65', '\x72', '\x2d', '\x8a', '\x17', '\x83',
+    '\xd6', '\x32', '\x90', '\x85', '\xf8', '\x22', '\xe2', '\x65', '\xa9',
+    '\xe0', '\xa0', '\xfe', '\x19', '\xb2', '\x39', '\x2d', '\x14', '\x03',
+    '\x10', '\x2f', '\xcc', '\x8b', '\x5e', '\xaa', '\x25', '\x27', '\x0d',
+    '\xa3', '\x37', '\x10', '\x0c', '\x17', '\xec', '\xf0', '\x8b', '\xc5',
+    '\x6b', '\xed', '\x6b', '\x5e', '\xb2', '\xe2', '\x35', '\x3e', '\x46',
+    '\x3b', '\xf7', '\xf6', '\x59', '\xb1', '\xe0', '\x16', '\xa6', '\xfb',
+    '\x03', '\xbf', '\x84', '\x4f', '\xce', '\x64', '\x15', '\x0d', '\x59',
+    '\x99', '\xa6', '\xf0', '\x7f', '\x8a', '\x33', '\x4b', '\xbb', '\x0b',
+    '\xb8', '\xf2', '\xd1', '\x27', '\x90', '\x8f', '\x38', '\xf8', '\x5a',
+    '\x41', '\x82', '\x07', '\x9b', '\x0d', '\xd9', '\x52', '\xe0', '\x70',
+    '\xff', '\xde', '\xda', '\xd8', '\x25', '\x4e', '\x2f', '\x2d', '\x9f',
+    '\xaf', '\x92', '\x63', '\xc7', '\x42', '\xb4', '\xdc', '\x16', '\x95',
+    '\x23', '\x05', '\x02', '\x6b', '\xb0', '\xe8', '\xc5', '\xfe', '\x15',
+    '\x9a', '\xe8', '\x7d', '\x2f', '\xdc', '\x43', '\xf4', '\x70', '\x91',
+    '\x1a', '\x93', '\xbe', '\x71', '\xaf', '\x85', '\x84', '\xdb', '\xcf',
+    '\x6b', '\x5c', '\x80', '\xb2', '\xd3', '\xf3', '\x42', '\x6e', '\x24',
+    '\xec', '\x2a', '\x62', '\x99', '\xc6', '\x3c', '\xe5', '\x32', '\xe5',
+    '\x72', '\x37', '\x30', '\x9b', '\x0b', '\xe4', '\x06', '\xb4', '\x64',
+    '\x26', '\x95', '\x59', '\xba', '\xf1', '\x53', '\x83', '\x3d', '\x99',
+    '\x6d', '\xf0', '\x80', '\xe2', '\xdb', '\x6b', '\x34', '\x52', '\x06',
+    '\x77', '\x3c', '\x73', '\xbe', '\xc6', '\xe3', '\xce', '\xb2', '\x11',
+    '\x02', '\x03', '\x01', '\x00', '\x01', '\xa3', '\x81', '\xb6', '\x30',
+    '\x81', '\xb3', '\x30', '\x0c', '\x06', '\x03', '\x55', '\x1d', '\x13',
+    '\x01', '\x01', '\xff', '\x04', '\x02', '\x30', '\x00', '\x30', '\x1d',
+    '\x06', '\x03', '\x55', '\x1d', '\x0e', '\x04', '\x16', '\x04', '\x14',
+    '\xc8', '\x54', '\x28', '\xf6', '\xd2', '\xd5', '\x12', '\x35', '\x89',
+    '\x15', '\x75', '\xb8', '\xbf', '\xdd', '\xfb', '\x4a', '\xfc', '\x6c',
+    '\x89', '\xde', '\x30', '\x1f', '\x06', '\x03', '\x55', '\x1d', '\x23',
+    '\x04', '\x18', '\x30', '\x16', '\x80', '\x14', '\x50', '\xe4', '\x1d',
+    '\xc3', '\x1a', '\xfb', '\xfd', '\x38', '\xdd', '\xa2', '\x05', '\xfd',
+    '\xc8', '\xfa', '\x57', '\x0a', '\xc1', '\x06', '\x0f', '\xae', '\x30',
+    '\x1d', '\x06', '\x03', '\x55', '\x1d', '\x25', '\x04', '\x16', '\x30',
+    '\x14', '\x06', '\x08', '\x2b', '\x06', '\x01', '\x05', '\x05', '\x07',
+    '\x03', '\x01', '\x06', '\x08', '\x2b', '\x06', '\x01', '\x05', '\x05',
+    '\x07', '\x03', '\x02', '\x30', '\x44', '\x06', '\x03', '\x55', '\x1d',
+    '\x11', '\x04', '\x3d', '\x30', '\x3b', '\x82', '\x0f', '\x77', '\x77',
+    '\x77', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
+    '\x2e', '\x6f', '\x72', '\x67', '\x82', '\x10', '\x6d', '\x61', '\x69',
+    '\x6c', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
+    '\x2e', '\x6f', '\x72', '\x67', '\x82', '\x10', '\x6d', '\x61', '\x69',
+    '\x6c', '\x2e', '\x65', '\x78', '\x61', '\x6d', '\x70', '\x6c', '\x65',
+    '\x2e', '\x63', '\x6f', '\x6d', '\x87', '\x04', '\x7f', '\x00', '\x00',
+    '\x01', '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86',
+    '\xf7', '\x0d', '\x01', '\x01', '\x0b', '\x05', '\x00', '\x03', '\x82',
+    '\x01', '\x01', '\x00', '\x45', '\x41', '\x7a', '\x68', '\xe0', '\xa7',
+    '\x59', '\xa1', '\x62', '\x54', '\x73', '\x74', '\x14', '\x4f', '\xde',
+    '\x9c', '\x51', '\xac', '\x25', '\x97', '\x70', '\xf7', '\x09', '\x51',
+    '\x39', '\x72', '\x39', '\x3c', '\xd0', '\x31', '\xe1', '\xc3', '\x02',
+    '\x91', '\x14', '\x4d', '\x8f', '\x1d', '\x31', '\xab', '\x98', '\x7e',
+    '\xe6', '\xbb', '\xab', '\x6a', '\xd9', '\xc5', '\x86', '\xaa', '\x4e',
+    '\x6a', '\x48', '\xe9', '\xf8', '\xd7', '\xb3', '\x1d', '\xa0', '\xc5',
+    '\xe6', '\xbf', '\x4c', '\x5a', '\x9b', '\xb5', '\x78', '\x01', '\xa3',
+    '\x39', '\x7b', '\x5f', '\xbc', '\xb8', '\xa7', '\xc2', '\x71', '\xb0',
+    '\x7b', '\xdd', '\xa1', '\x87', '\xa6', '\x54', '\x9c', '\xf6', '\x59',
+    '\x81', '\xb1', '\x2c', '\xde', '\xc5', '\x8a', '\xa2', '\x06', '\x89',
+    '\xb5', '\xc1', '\x7a', '\xbe', '\x0c', '\x9f', '\x3d', '\xde', '\x81',
+    '\x48', '\x53', '\x71', '\x7b', '\x8d', '\xc7', '\xea', '\x87', '\xd7',
+    '\xd1', '\xda', '\x94', '\xb4', '\xc5', '\xac', '\x1e', '\x83', '\xa3',
+    '\x42', '\x7d', '\xe6', '\xab', '\x3f', '\xd6', '\x1c', '\xd6', '\x65',
+    '\xc3', '\x60', '\xe9', '\x76', '\x54', '\x79', '\x3f', '\xeb', '\x65',
+    '\x85', '\x4f', '\x60', '\x7d', '\xbb', '\x96', '\x03', '\x54', '\x2e',
+    '\xd0', '\x1b', '\xe2', '\x6c', '\x2d', '\x91', '\xae', '\x33', '\x9c',
+    '\x04', '\xc4', '\x44', '\x0a', '\x7d', '\x5f', '\xbb', '\x80', '\xa2',
+    '\x01', '\xbc', '\x90', '\x81', '\xa5', '\xdc', '\x4a', '\xc8', '\x77',
+    '\xc9', '\x8d', '\x34', '\x17', '\xe6', '\x2a', '\x7d', '\x02', '\x1e',
+    '\x32', '\x3f', '\x7d', '\xd7', '\x0c', '\x80', '\x5b', '\xc6', '\x94',
+    '\x6a', '\x42', '\x36', '\x05', '\x9f', '\x9e', '\xc5', '\x85', '\x9f',
+    '\x60', '\xe3', '\x72', '\x73', '\x34', '\x39', '\x44', '\x75', '\x55',
+    '\x60', '\x24', '\x7a', '\x8b', '\x09', '\x74', '\x84', '\x72', '\xfd',
+    '\x91', '\x68', '\x93', '\x57', '\x9e', '\x70', '\x46', '\x4d', '\xe4',
+    '\x30', '\x84', '\x5f', '\x20', '\x07', '\xad', '\xfd', '\x86', '\x32',
+    '\xd3', '\xfb', '\xba', '\xaf', '\xd9', '\x61', '\x14', '\x3c', '\xe0',
+    '\xa1', '\xa9', '\x51', '\x51', '\x0f', '\xad', '\x60'};
+
+ABSL_CONST_INIT const absl::string_view kTestCertificate(
+    kTestCertificateRaw,
+    sizeof(kTestCertificateRaw));
+
+ABSL_CONST_INIT const char kTestCertificatePem[] =
+    R"(Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=QUIC Server Root CA
+        Validity
+            Not Before: Jan 30 18:13:59 2020 GMT
+            Not After : Feb  2 18:13:59 2020 GMT
+        Subject: C=US, ST=California, L=Mountain View, O=QUIC Server, CN=127.0.0.1
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                RSA Public-Key: (2048 bit)
+                Modulus:
+                    00:c5:e2:51:6d:3f:d6:28:f2:ad:34:73:87:64:ca:
+                    33:19:33:b7:75:91:ab:31:19:2b:e3:a4:26:09:29:
+                    8b:2d:f7:52:75:a7:55:15:f0:11:c7:c2:c4:ed:18:
+                    1b:33:0b:71:32:e6:35:89:cd:2d:5a:05:57:4e:c2:
+                    78:75:65:72:2d:8a:17:83:d6:32:90:85:f8:22:e2:
+                    65:a9:e0:a0:fe:19:b2:39:2d:14:03:10:2f:cc:8b:
+                    5e:aa:25:27:0d:a3:37:10:0c:17:ec:f0:8b:c5:6b:
+                    ed:6b:5e:b2:e2:35:3e:46:3b:f7:f6:59:b1:e0:16:
+                    a6:fb:03:bf:84:4f:ce:64:15:0d:59:99:a6:f0:7f:
+                    8a:33:4b:bb:0b:b8:f2:d1:27:90:8f:38:f8:5a:41:
+                    82:07:9b:0d:d9:52:e0:70:ff:de:da:d8:25:4e:2f:
+                    2d:9f:af:92:63:c7:42:b4:dc:16:95:23:05:02:6b:
+                    b0:e8:c5:fe:15:9a:e8:7d:2f:dc:43:f4:70:91:1a:
+                    93:be:71:af:85:84:db:cf:6b:5c:80:b2:d3:f3:42:
+                    6e:24:ec:2a:62:99:c6:3c:e5:32:e5:72:37:30:9b:
+                    0b:e4:06:b4:64:26:95:59:ba:f1:53:83:3d:99:6d:
+                    f0:80:e2:db:6b:34:52:06:77:3c:73:be:c6:e3:ce:
+                    b2:11
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Subject Key Identifier:
+                C8:54:28:F6:D2:D5:12:35:89:15:75:B8:BF:DD:FB:4A:FC:6C:89:DE
+            X509v3 Authority Key Identifier:
+                keyid:50:E4:1D:C3:1A:FB:FD:38:DD:A2:05:FD:C8:FA:57:0A:C1:06:0F:AE
+
+            X509v3 Extended Key Usage:
+                TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name:
+                DNS:www.example.org, DNS:mail.example.org, DNS:mail.example.com, IP Address:127.0.0.1
+    Signature Algorithm: sha256WithRSAEncryption
+         45:41:7a:68:e0:a7:59:a1:62:54:73:74:14:4f:de:9c:51:ac:
+         25:97:70:f7:09:51:39:72:39:3c:d0:31:e1:c3:02:91:14:4d:
+         8f:1d:31:ab:98:7e:e6:bb:ab:6a:d9:c5:86:aa:4e:6a:48:e9:
+         f8:d7:b3:1d:a0:c5:e6:bf:4c:5a:9b:b5:78:01:a3:39:7b:5f:
+         bc:b8:a7:c2:71:b0:7b:dd:a1:87:a6:54:9c:f6:59:81:b1:2c:
+         de:c5:8a:a2:06:89:b5:c1:7a:be:0c:9f:3d:de:81:48:53:71:
+         7b:8d:c7:ea:87:d7:d1:da:94:b4:c5:ac:1e:83:a3:42:7d:e6:
+         ab:3f:d6:1c:d6:65:c3:60:e9:76:54:79:3f:eb:65:85:4f:60:
+         7d:bb:96:03:54:2e:d0:1b:e2:6c:2d:91:ae:33:9c:04:c4:44:
+         0a:7d:5f:bb:80:a2:01:bc:90:81:a5:dc:4a:c8:77:c9:8d:34:
+         17:e6:2a:7d:02:1e:32:3f:7d:d7:0c:80:5b:c6:94:6a:42:36:
+         05:9f:9e:c5:85:9f:60:e3:72:73:34:39:44:75:55:60:24:7a:
+         8b:09:74:84:72:fd:91:68:93:57:9e:70:46:4d:e4:30:84:5f:
+         20:07:ad:fd:86:32:d3:fb:ba:af:d9:61:14:3c:e0:a1:a9:51:
+         51:0f:ad:60
+-----BEGIN CERTIFICATE-----
+MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD
+IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow
+ZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
+dW50YWluIFZpZXcxFDASBgNVBAoMC1FVSUMgU2VydmVyMRIwEAYDVQQDDAkxMjcu
+MC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF4lFtP9Yo8q00
+c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
+wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
+XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
+UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
+a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
+vsbjzrIRAgMBAAGjgbYwgbMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyFQo9tLV
+EjWJFXW4v937Svxsid4wHwYDVR0jBBgwFoAUUOQdwxr7/TjdogX9yPpXCsEGD64w
+HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEQGA1UdEQQ9MDuCD3d3dy5l
+eGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLmNvbYcE
+fwAAATANBgkqhkiG9w0BAQsFAAOCAQEARUF6aOCnWaFiVHN0FE/enFGsJZdw9wlR
+OXI5PNAx4cMCkRRNjx0xq5h+5ruratnFhqpOakjp+NezHaDF5r9MWpu1eAGjOXtf
+vLinwnGwe92hh6ZUnPZZgbEs3sWKogaJtcF6vgyfPd6BSFNxe43H6ofX0dqUtMWs
+HoOjQn3mqz/WHNZlw2DpdlR5P+tlhU9gfbuWA1Qu0BvibC2RrjOcBMRECn1fu4Ci
+AbyQgaXcSsh3yY00F+YqfQIeMj991wyAW8aUakI2BZ+exYWfYONyczQ5RHVVYCR6
+iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA==
+-----END CERTIFICATE-----)";
+
+// Same leaf as above, but with an intermediary attached.
+ABSL_CONST_INIT const char kTestCertificateChainPem[] =
+    R"(-----BEGIN CERTIFICATE-----
+MIIDtDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNRVUlD
+IFNlcnZlciBSb290IENBMB4XDTIwMDEzMDE4MTM1OVoXDTIwMDIwMjE4MTM1OVow
+ZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
+dW50YWluIFZpZXcxFDASBgNVBAoMC1FVSUMgU2VydmVyMRIwEAYDVQQDDAkxMjcu
+MC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDF4lFtP9Yo8q00
+c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
+wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
+XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
+UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
+a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
+vsbjzrIRAgMBAAGjgbYwgbMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyFQo9tLV
+EjWJFXW4v937Svxsid4wHwYDVR0jBBgwFoAUUOQdwxr7/TjdogX9yPpXCsEGD64w
+HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEQGA1UdEQQ9MDuCD3d3dy5l
+eGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLm9yZ4IQbWFpbC5leGFtcGxlLmNvbYcE
+fwAAATANBgkqhkiG9w0BAQsFAAOCAQEARUF6aOCnWaFiVHN0FE/enFGsJZdw9wlR
+OXI5PNAx4cMCkRRNjx0xq5h+5ruratnFhqpOakjp+NezHaDF5r9MWpu1eAGjOXtf
+vLinwnGwe92hh6ZUnPZZgbEs3sWKogaJtcF6vgyfPd6BSFNxe43H6ofX0dqUtMWs
+HoOjQn3mqz/WHNZlw2DpdlR5P+tlhU9gfbuWA1Qu0BvibC2RrjOcBMRECn1fu4Ci
+AbyQgaXcSsh3yY00F+YqfQIeMj991wyAW8aUakI2BZ+exYWfYONyczQ5RHVVYCR6
+iwl0hHL9kWiTV55wRk3kMIRfIAet/YYy0/u6r9lhFDzgoalRUQ+tYA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIUfVS7RH+aVGqZhrjyuyD4qCnTS+MwDQYJKoZIhvcNAQEL
+BQAwHjEcMBoGA1UEAwwTUVVJQyBTZXJ2ZXIgUm9vdCBDQTAeFw0yMDAxMzAxODEz
+NTlaFw0yMDAyMDIxODEzNTlaMB4xHDAaBgNVBAMME1FVSUMgU2VydmVyIFJvb3Qg
+Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc3k0GGpCBf6jXHxia
+QM4ntB6pWkT+NbaZUNHb1SkG2Cp9dN5dEKOXiqOi9306j4WNWTq/q0Ku9lCPPPFs
+JTIVC3tKY8Nbiczw+mohgW4rwLgpAP5rjjVzTxSFpDWZlgkH54HpqLjJFVl4Fklg
+vzSj+rYfqP+ueesi7z7KwPwzd30jjsJlpr2rlkZkidWT5vRTD3uYhNOW7IIT0lRP
+MDTwdxTEU5unyxESAsZyckNuJDeNF0y1Aw5Xiw/Bww+CyRH+tX6OUcWNtA+ZSDU8
+oVH5m4rxYK/DaHAZrA672/ywvUcPQaNaRxsAWRVjhktgyGPT3pjqiHDCN8+42uhH
+SgrbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFDkHcMa+/04
+3aIF/cj6VwrBBg+uMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
+iX+tn1Zfxx4M5YqZlPgXFB219agrJP2vM0fzW0E4zqDvA2ALaQN+lwdnFueN3tDk
+3IJvxd2W5k1Qh7LqWFUbBghDAP43XffW/yNy0+nuR2n3nRYdNStSMrGQm7oywhBd
+5jQl0GQUyYf1jcbD76HA5JraBjEXnQyJe6gJYHiRiMaMURWyzcngOPv5w3XBzIe3
+sRM0Rk/TTZP1Qx7fDY3ikFe1w9LzAMGbKDTKfc1+F0GZByJ3pdWakUNXZvtGFhIF
+hTXMooR/wD7an6gtnXD8ixCh7bP0TyPiBhNsUb12WrvSEAm/UyciQbQlR7P+K0Z7
+Cmn1Mj4hQ+pT0t+pw/DMOw==
+-----END CERTIFICATE-----)";
+
+ABSL_CONST_INIT const char kTestCertWithUnknownSanTypePem[] =
+    R"(-----BEGIN CERTIFICATE-----
+MIIEYTCCA0mgAwIBAgIJAILStmLgUUcVMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp
+c2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRAw
+DgYDVQQDDAdUZXN0IENBMB4XDTE4MTIxNzIwMTgwMFoXDTIwMTIxNjIwMTgwMFow
+gaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T
+YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu
+ZWVyaW5nMRowGAYDVQQDDBFUZXN0IEJhY2tlbmQgVGVhbTEkMCIGCSqGSIb3DQEJ
+ARYVYmFja2VuZC10ZWFtQGx5ZnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAuvPdQdmwZongPAgQho/Vipd3PZWrQ6BKxIb4l/RvqtVP321IUTLs
+4vVwpXoYJ+12L+XOO3jCInszs53tHjFpTI1GE8/sasmgR6LRr2krwSoVRHPqUoc9
+tzkDG1SzKP2TRTi1MTI3FO+TnLFahntO9Zstxhv1Epz5GZ/xQLE0/LLoRYzcynL/
+iflk18iL1KM8i0Hy4cKjclOaUdnh2nh753iJfxCSb5wJfx4FH1qverYHHT6FopYR
+V40Cg0yYXcYo8yNwrg+EBY8QAT2JOMDokXNKbZpmVKiBlh0QYMX6BBiW249v3sYl
+3Ve+fZvCkle3W0xP0xJw8PdX0NRbvGOrBQIDAQABo4HAMIG9MAwGA1UdEwEB/wQC
+MAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBB
+BgNVHREEOjA4hh5zcGlmZmU6Ly9seWZ0LmNvbS9iYWNrZW5kLXRlYW2CCGx5ZnQu
+Y29tggx3d3cubHlmdC5jb20wHQYDVR0OBBYEFLHmMm0DV9jCHJSWVRwyPYpBw62r
+MB8GA1UdIwQYMBaAFBQz1vaSbPuePL++7GTMqLAMtk3kMA0GCSqGSIb3DQEBCwUA
+A4IBAQAwx3/M2o00W8GlQ3OT4y/hQGb5K2aytxx8QeSmJaaZTJbvaHhe0x3/fLgq
+uWrW3WEWFtwasilySjOrFOtB9UNmJmNOHSJD3Bslbv5htRaWnoFPCXdwZtVMdoTq
+IHIQqLoos/xj3kVD5sJSYySrveMeKaeUILTkb5ZubSivye1X2yiJLR7AtuwuiMio
+CdIOqhn6xJqYhT7z0IhdKpLNPk4w1tBZSKOXqzrXS4uoJgTC67hWslWWZ2VC6IvZ
+FmKuuGZamCCj6F1QF2IjMVM8evl84hEnN0ajdkA/QWnil9kcWvBm15Ho+oTvvJ7s
+M8MD3RDSq/90FSiME4vbyNEyTmj0
+-----END CERTIFICATE-----)";
+
+ABSL_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = {
+    '\x30', '\x82', '\x04', '\xbc', '\x02', '\x01', '\x00', '\x30', '\x0d',
+    '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
+    '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa6', '\x30',
+    '\x82', '\x04', '\xa2', '\x02', '\x01', '\x00', '\x02', '\x82', '\x01',
+    '\x01', '\x00', '\xc5', '\xe2', '\x51', '\x6d', '\x3f', '\xd6', '\x28',
+    '\xf2', '\xad', '\x34', '\x73', '\x87', '\x64', '\xca', '\x33', '\x19',
+    '\x33', '\xb7', '\x75', '\x91', '\xab', '\x31', '\x19', '\x2b', '\xe3',
+    '\xa4', '\x26', '\x09', '\x29', '\x8b', '\x2d', '\xf7', '\x52', '\x75',
+    '\xa7', '\x55', '\x15', '\xf0', '\x11', '\xc7', '\xc2', '\xc4', '\xed',
+    '\x18', '\x1b', '\x33', '\x0b', '\x71', '\x32', '\xe6', '\x35', '\x89',
+    '\xcd', '\x2d', '\x5a', '\x05', '\x57', '\x4e', '\xc2', '\x78', '\x75',
+    '\x65', '\x72', '\x2d', '\x8a', '\x17', '\x83', '\xd6', '\x32', '\x90',
+    '\x85', '\xf8', '\x22', '\xe2', '\x65', '\xa9', '\xe0', '\xa0', '\xfe',
+    '\x19', '\xb2', '\x39', '\x2d', '\x14', '\x03', '\x10', '\x2f', '\xcc',
+    '\x8b', '\x5e', '\xaa', '\x25', '\x27', '\x0d', '\xa3', '\x37', '\x10',
+    '\x0c', '\x17', '\xec', '\xf0', '\x8b', '\xc5', '\x6b', '\xed', '\x6b',
+    '\x5e', '\xb2', '\xe2', '\x35', '\x3e', '\x46', '\x3b', '\xf7', '\xf6',
+    '\x59', '\xb1', '\xe0', '\x16', '\xa6', '\xfb', '\x03', '\xbf', '\x84',
+    '\x4f', '\xce', '\x64', '\x15', '\x0d', '\x59', '\x99', '\xa6', '\xf0',
+    '\x7f', '\x8a', '\x33', '\x4b', '\xbb', '\x0b', '\xb8', '\xf2', '\xd1',
+    '\x27', '\x90', '\x8f', '\x38', '\xf8', '\x5a', '\x41', '\x82', '\x07',
+    '\x9b', '\x0d', '\xd9', '\x52', '\xe0', '\x70', '\xff', '\xde', '\xda',
+    '\xd8', '\x25', '\x4e', '\x2f', '\x2d', '\x9f', '\xaf', '\x92', '\x63',
+    '\xc7', '\x42', '\xb4', '\xdc', '\x16', '\x95', '\x23', '\x05', '\x02',
+    '\x6b', '\xb0', '\xe8', '\xc5', '\xfe', '\x15', '\x9a', '\xe8', '\x7d',
+    '\x2f', '\xdc', '\x43', '\xf4', '\x70', '\x91', '\x1a', '\x93', '\xbe',
+    '\x71', '\xaf', '\x85', '\x84', '\xdb', '\xcf', '\x6b', '\x5c', '\x80',
+    '\xb2', '\xd3', '\xf3', '\x42', '\x6e', '\x24', '\xec', '\x2a', '\x62',
+    '\x99', '\xc6', '\x3c', '\xe5', '\x32', '\xe5', '\x72', '\x37', '\x30',
+    '\x9b', '\x0b', '\xe4', '\x06', '\xb4', '\x64', '\x26', '\x95', '\x59',
+    '\xba', '\xf1', '\x53', '\x83', '\x3d', '\x99', '\x6d', '\xf0', '\x80',
+    '\xe2', '\xdb', '\x6b', '\x34', '\x52', '\x06', '\x77', '\x3c', '\x73',
+    '\xbe', '\xc6', '\xe3', '\xce', '\xb2', '\x11', '\x02', '\x03', '\x01',
+    '\x00', '\x01', '\x02', '\x82', '\x01', '\x00', '\x39', '\x75', '\xac',
+    '\x1b', '\x43', '\x0c', '\x16', '\xbb', '\xd0', '\xdb', '\x88', '\x28',
+    '\x6a', '\x75', '\xe4', '\x3c', '\x8f', '\x2d', '\xd8', '\x6f', '\xc1',
+    '\xfb', '\xf1', '\xc9', '\x32', '\xc2', '\xb9', '\x60', '\xb3', '\xb5',
+    '\x7c', '\x55', '\x72', '\x96', '\x43', '\x4e', '\x8b', '\x9e', '\x38',
+    '\x2b', '\x7f', '\x3c', '\xdb', '\x73', '\xc2', '\x82', '\x21', '\xf2',
+    '\x6e', '\xcb', '\x36', '\x04', '\x9b', '\x95', '\x6d', '\xac', '\x5b',
+    '\x5b', '\xbd', '\x50', '\x69', '\x16', '\x59', '\xff', '\x2b', '\x38',
+    '\x04', '\xca', '\x2f', '\xc8', '\x93', '\x7e', '\x27', '\xf3', '\x01',
+    '\x7e', '\x40', '\x81', '\xbf', '\x07', '\x0b', '\x1f', '\x5b', '\x1d',
+    '\x92', '\x7e', '\x22', '\xc3', '\x0c', '\x3d', '\x22', '\xbe', '\xc3',
+    '\x06', '\x4c', '\xbc', '\x72', '\x66', '\x70', '\x94', '\x16', '\x8d',
+    '\x1f', '\x78', '\x65', '\x6a', '\x66', '\x07', '\x1f', '\x74', '\x42',
+    '\x6e', '\xf6', '\x7e', '\xdc', '\x03', '\xd3', '\x88', '\xb4', '\x4b',
+    '\x2c', '\x5c', '\x3c', '\x42', '\x59', '\x42', '\x1f', '\x01', '\x13',
+    '\x31', '\xc5', '\x22', '\xe7', '\x6a', '\x96', '\xf2', '\xfb', '\x66',
+    '\xfe', '\xc8', '\xa1', '\x7e', '\x24', '\x96', '\x5f', '\x02', '\xee',
+    '\x38', '\x21', '\xa5', '\x14', '\xd2', '\xa6', '\x35', '\x70', '\x6c',
+    '\x8d', '\xa6', '\xd8', '\x2a', '\xd2', '\x45', '\x31', '\x5f', '\x67',
+    '\x9e', '\x35', '\x57', '\x6a', '\xc4', '\x15', '\xe7', '\xba', '\x60',
+    '\x2f', '\x8e', '\x52', '\x4e', '\xfc', '\x6f', '\xa0', '\x08', '\x91',
+    '\x31', '\x71', '\x06', '\x68', '\x19', '\x48', '\xc7', '\x81', '\x0d',
+    '\x5e', '\x52', '\x93', '\x57', '\xcc', '\xfe', '\x46', '\xac', '\xa9',
+    '\x4f', '\xe2', '\x96', '\x4f', '\xaf', '\x12', '\xfb', '\xc2', '\x4b',
+    '\xc4', '\x8d', '\x3b', '\xb0', '\x38', '\xe4', '\xbb', '\x8d', '\x19',
+    '\x81', '\xe4', '\x74', '\x63', '\x9c', '\x8d', '\xaa', '\x84', '\x82',
+    '\x91', '\xdf', '\xdc', '\x45', '\xf0', '\x39', '\xb2', '\xb4', '\xac',
+    '\x45', '\xda', '\x3f', '\x30', '\x4d', '\x46', '\xb1', '\xe1', '\xb2',
+    '\x9d', '\xdf', '\xd8', '\xc4', '\xa2', '\xef', '\xe9', '\x1a', '\x97',
+    '\x79', '\x02', '\x81', '\x81', '\x00', '\xe5', '\x23', '\xb8', '\xd7',
+    '\x09', '\x54', '\x54', '\x3b', '\xb6', '\x78', '\x78', '\x67', '\x57',
+    '\x65', '\xc5', '\xd4', '\x74', '\xaf', '\x05', '\x4f', '\xb5', '\xc8',
+    '\x8c', '\x1b', '\xd1', '\x9a', '\x2c', '\xd6', '\xe4', '\x68', '\xd1',
+    '\xaf', '\x3d', '\x72', '\x42', '\x50', '\xc8', '\xdd', '\xb1', '\xee',
+    '\x77', '\x52', '\xb8', '\xb1', '\x31', '\xbe', '\xf0', '\x74', '\x78',
+    '\x42', '\x59', '\xea', '\x13', '\x8b', '\x82', '\x00', '\x54', '\x22',
+    '\xd2', '\x0a', '\x24', '\xb0', '\x1f', '\x1e', '\x76', '\x27', '\xae',
+    '\x63', '\xc6', '\x6b', '\x59', '\x28', '\x1d', '\xa0', '\x9f', '\x42',
+    '\x30', '\xf1', '\xe3', '\x59', '\x1c', '\x4f', '\x31', '\x49', '\xff',
+    '\x45', '\x7e', '\x6b', '\xef', '\xe9', '\x6f', '\xde', '\xaf', '\x1e',
+    '\x04', '\x96', '\x61', '\x4e', '\x9f', '\x58', '\xf5', '\x0d', '\x64',
+    '\x08', '\x48', '\x0a', '\xae', '\xac', '\xe4', '\x76', '\x91', '\xdd',
+    '\x6e', '\x33', '\x97', '\xc5', '\x96', '\xda', '\xff', '\xbc', '\x42',
+    '\x5b', '\x71', '\xb5', '\x76', '\xae', '\x01', '\xb3', '\x02', '\x81',
+    '\x81', '\x00', '\xdd', '\x14', '\xa5', '\x6c', '\x89', '\x2b', '\x80',
+    '\x78', '\xf6', '\xc3', '\x80', '\x4d', '\x53', '\x54', '\xb3', '\x2b',
+    '\x40', '\xce', '\x98', '\x16', '\xa0', '\xbf', '\x72', '\xf1', '\xe3',
+    '\xdc', '\xe9', '\x0b', '\x45', '\x23', '\x86', '\x38', '\x4c', '\x29',
+    '\xf1', '\xa0', '\xe0', '\x2c', '\xfa', '\x86', '\x3f', '\x01', '\x90',
+    '\xc5', '\x1b', '\x96', '\x10', '\x44', '\x84', '\xfb', '\xec', '\x3c',
+    '\x74', '\x6c', '\x0d', '\xcc', '\xc3', '\xcd', '\x1b', '\x28', '\x12',
+    '\xaa', '\xb4', '\x67', '\x80', '\xc8', '\xd9', '\x1b', '\x7d', '\xe7',
+    '\x54', '\x39', '\x03', '\x6d', '\xba', '\xaa', '\x6f', '\xf7', '\x93',
+    '\x1f', '\x94', '\x76', '\xd6', '\xab', '\x9b', '\xda', '\x3d', '\x89',
+    '\x37', '\x83', '\xfe', '\x72', '\x2a', '\xbb', '\x6f', '\x36', '\xc5',
+    '\xe0', '\xae', '\x65', '\xf9', '\xbb', '\xc6', '\xe2', '\x98', '\x0f',
+    '\xbd', '\xf6', '\x22', '\xf8', '\x35', '\x5b', '\x99', '\xe6', '\xff',
+    '\x6d', '\x6e', '\xb2', '\x92', '\x93', '\x64', '\x25', '\xc1', '\xe8',
+    '\x9c', '\x6b', '\x73', '\x2b', '\x02', '\x81', '\x80', '\x13', '\x30',
+    '\x1a', '\x9a', '\x67', '\x3d', '\x98', '\x90', '\x27', '\x87', '\x8f',
+    '\x0d', '\x98', '\x53', '\xfd', '\x6c', '\xfd', '\x18', '\x6a', '\xe9',
+    '\x71', '\xdf', '\x89', '\x5c', '\x0b', '\x01', '\x4e', '\x1f', '\xf0',
+    '\xa0', '\x96', '\x6e', '\x86', '\x46', '\xbb', '\x26', '\xe8', '\xab',
+    '\x27', '\xeb', '\x40', '\x32', '\xbd', '\x24', '\x99', '\x75', '\xd3',
+    '\xcc', '\xed', '\x05', '\x21', '\x62', '\x68', '\xa0', '\x96', '\x12',
+    '\x50', '\xf9', '\x59', '\x7d', '\x5f', '\xf5', '\x1f', '\xa5', '\xfd',
+    '\x5e', '\xf5', '\x4b', '\x85', '\xa2', '\x17', '\xa5', '\x34', '\x55',
+    '\xef', '\x00', '\x2b', '\xf9', '\x15', '\x80', '\xb0', '\xce', '\x30',
+    '\xe2', '\x71', '\x6d', '\xf0', '\x58', '\x39', '\x8e', '\xe2', '\xbf',
+    '\x53', '\x0a', '\xc0', '\x77', '\x97', '\x4e', '\x6e', '\x29', '\x94',
+    '\xdb', '\xba', '\x34', '\xb7', '\x53', '\xad', '\xac', '\xec', '\xb4',
+    '\xc1', '\x22', '\x39', '\xc8', '\x38', '\x3d', '\x63', '\x94', '\x93',
+    '\x35', '\xc0', '\x98', '\xc7', '\xbc', '\xda', '\x63', '\x57', '\xe1',
+    '\x02', '\x81', '\x80', '\x51', '\x71', '\x7c', '\xab', '\x6a', '\x30',
+    '\xe3', '\x68', '\x2c', '\x87', '\xc2', '\xe9', '\x39', '\x8c', '\x97',
+    '\x60', '\x94', '\xc4', '\x46', '\xd4', '\xf7', '\x2c', '\xf0', '\x1c',
+    '\x5a', '\x34', '\x14', '\x89', '\xf9', '\x53', '\x67', '\xeb', '\xaf',
+    '\x6b', '\x38', '\x3f', '\x6a', '\xb6', '\x47', '\x28', '\x53', '\x67',
+    '\xb1', '\x3c', '\x5b', '\xb8', '\x41', '\x8f', '\xec', '\x69', '\x9e',
+    '\x12', '\x7b', '\x55', '\x1f', '\x14', '\x53', '\x01', '\x69', '\x42',
+    '\xae', '\xf5', '\xc1', '\xf5', '\xeb', '\x44', '\x92', '\x6e', '\x85',
+    '\x48', '\x46', '\x07', '\xa6', '\xd2', '\xb2', '\x94', '\x7d', '\x20',
+    '\xf8', '\x4b', '\x06', '\xf7', '\x6c', '\x87', '\xd5', '\xa7', '\x65',
+    '\x49', '\xfa', '\x70', '\x9e', '\xb8', '\xd2', '\x33', '\x30', '\x7a',
+    '\x3e', '\x15', '\x52', '\x49', '\xf0', '\xe1', '\x13', '\x18', '\x80',
+    '\xaa', '\x33', '\xf1', '\xcb', '\xda', '\x22', '\x55', '\xf7', '\x71',
+    '\x58', '\xa1', '\xa8', '\xc9', '\x12', '\x24', '\x48', '\x1d', '\x7c',
+    '\xbc', '\xc3', '\x7a', '\xf5', '\xf7', '\x02', '\x81', '\x80', '\x41',
+    '\x7c', '\xae', '\x6e', '\x48', '\x3f', '\xb5', '\x0b', '\x99', '\xaa',
+    '\xc5', '\xea', '\x81', '\xad', '\x84', '\x6b', '\x29', '\x78', '\x4b',
+    '\x18', '\xdb', '\x0e', '\xd3', '\x3e', '\x60', '\x8b', '\xef', '\x65',
+    '\x4d', '\x58', '\x25', '\x3a', '\x08', '\xb5', '\x21', '\xb6', '\x61',
+    '\x0c', '\xfa', '\xf0', '\x69', '\x78', '\x4e', '\x68', '\x36', '\xdb',
+    '\x41', '\x4b', '\x50', '\xd8', '\xd3', '\x8e', '\x3d', '\x74', '\x80',
+    '\x8e', '\xa0', '\xe6', '\xda', '\xec', '\x70', '\x89', '\x77', '\xb2',
+    '\x9d', '\xd6', '\x6e', '\x0a', '\xc4', '\xbd', '\xf6', '\x9a', '\x07',
+    '\x15', '\xba', '\x55', '\x9f', '\xd4', '\x4d', '\x3a', '\x0f', '\x51',
+    '\x12', '\xa4', '\xd9', '\xc2', '\x98', '\x76', '\xc5', '\xb7', '\x29',
+    '\x40', '\xca', '\xf4', '\xbb', '\x74', '\x2d', '\x71', '\x03', '\x4d',
+    '\xe7', '\x05', '\x75', '\xc0', '\x8d', '\x96', '\x7e', '\x59', '\xa1',
+    '\x8b', '\x3b', '\xa3', '\x2b', '\xa5', '\xa3', '\xc8', '\xf7', '\xd3',
+    '\x3e', '\x6b', '\x2e', '\xfa', '\x4f', '\x4d', '\xe6', '\xbe', '\xd3',
+    '\x59'};
+
+ABSL_CONST_INIT const absl::string_view kTestCertificatePrivateKey(
+    kTestCertificatePrivateKeyRaw,
+    sizeof(kTestCertificatePrivateKeyRaw));
+
+ABSL_CONST_INIT const char kTestCertificatePrivateKeyPem[] =
+    R"(-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDF4lFtP9Yo8q00
+c4dkyjMZM7d1kasxGSvjpCYJKYst91J1p1UV8BHHwsTtGBszC3Ey5jWJzS1aBVdO
+wnh1ZXItiheD1jKQhfgi4mWp4KD+GbI5LRQDEC/Mi16qJScNozcQDBfs8IvFa+1r
+XrLiNT5GO/f2WbHgFqb7A7+ET85kFQ1Zmabwf4ozS7sLuPLRJ5CPOPhaQYIHmw3Z
+UuBw/97a2CVOLy2fr5Jjx0K03BaVIwUCa7Doxf4Vmuh9L9xD9HCRGpO+ca+FhNvP
+a1yAstPzQm4k7CpimcY85TLlcjcwmwvkBrRkJpVZuvFTgz2ZbfCA4ttrNFIGdzxz
+vsbjzrIRAgMBAAECggEAOXWsG0MMFrvQ24goanXkPI8t2G/B+/HJMsK5YLO1fFVy
+lkNOi544K38823PCgiHybss2BJuVbaxbW71QaRZZ/ys4BMovyJN+J/MBfkCBvwcL
+H1sdkn4iwww9Ir7DBky8cmZwlBaNH3hlamYHH3RCbvZ+3APTiLRLLFw8QllCHwET
+McUi52qW8vtm/sihfiSWXwLuOCGlFNKmNXBsjabYKtJFMV9nnjVXasQV57pgL45S
+TvxvoAiRMXEGaBlIx4ENXlKTV8z+RqypT+KWT68S+8JLxI07sDjku40ZgeR0Y5yN
+qoSCkd/cRfA5srSsRdo/ME1GseGynd/YxKLv6RqXeQKBgQDlI7jXCVRUO7Z4eGdX
+ZcXUdK8FT7XIjBvRmizW5GjRrz1yQlDI3bHud1K4sTG+8HR4QlnqE4uCAFQi0gok
+sB8edieuY8ZrWSgdoJ9CMPHjWRxPMUn/RX5r7+lv3q8eBJZhTp9Y9Q1kCEgKrqzk
+dpHdbjOXxZba/7xCW3G1dq4BswKBgQDdFKVsiSuAePbDgE1TVLMrQM6YFqC/cvHj
+3OkLRSOGOEwp8aDgLPqGPwGQxRuWEESE++w8dGwNzMPNGygSqrRngMjZG33nVDkD
+bbqqb/eTH5R21qub2j2JN4P+ciq7bzbF4K5l+bvG4pgPvfYi+DVbmeb/bW6ykpNk
+JcHonGtzKwKBgBMwGppnPZiQJ4ePDZhT/Wz9GGrpcd+JXAsBTh/woJZuhka7Juir
+J+tAMr0kmXXTzO0FIWJooJYSUPlZfV/1H6X9XvVLhaIXpTRV7wAr+RWAsM4w4nFt
+8Fg5juK/UwrAd5dObimU27o0t1OtrOy0wSI5yDg9Y5STNcCYx7zaY1fhAoGAUXF8
+q2ow42gsh8LpOYyXYJTERtT3LPAcWjQUiflTZ+uvazg/arZHKFNnsTxbuEGP7Gme
+EntVHxRTAWlCrvXB9etEkm6FSEYHptKylH0g+EsG92yH1adlSfpwnrjSMzB6PhVS
+SfDhExiAqjPxy9oiVfdxWKGoyRIkSB18vMN69fcCgYBBfK5uSD+1C5mqxeqBrYRr
+KXhLGNsO0z5gi+9lTVglOgi1IbZhDPrwaXhOaDbbQUtQ2NOOPXSAjqDm2uxwiXey
+ndZuCsS99poHFbpVn9RNOg9REqTZwph2xbcpQMr0u3QtcQNN5wV1wI2Wflmhizuj
+K6WjyPfTPmsu+k9N5r7TWQ==
+-----END PRIVATE KEY-----)";
+
+// The legacy version was manually generated from the one above using der2ascii.
+ABSL_CONST_INIT const char kTestCertificatePrivateKeyLegacyPem[] =
+    R"(-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAxeJRbT/WKPKtNHOHZMozGTO3dZGrMRkr46QmCSmLLfdSdadVFfARx8LE7Rgb
+MwtxMuY1ic0tWgVXTsJ4dWVyLYoXg9YykIX4IuJlqeCg/hmyOS0UAxAvzIteqiUnDaM3EAwX7PCL
+xWvta16y4jU+Rjv39lmx4Bam+wO/hE/OZBUNWZmm8H+KM0u7C7jy0SeQjzj4WkGCB5sN2VLgcP/e
+2tglTi8tn6+SY8dCtNwWlSMFAmuw6MX+FZrofS/cQ/RwkRqTvnGvhYTbz2tcgLLT80JuJOwqYpnG
+POUy5XI3MJsL5Aa0ZCaVWbrxU4M9mW3wgOLbazRSBnc8c77G486yEQIDAQABAoIBADl1rBtDDBa7
+0NuIKGp15DyPLdhvwfvxyTLCuWCztXxVcpZDToueOCt/PNtzwoIh8m7LNgSblW2sW1u9UGkWWf8r
+OATKL8iTfifzAX5Agb8HCx9bHZJ+IsMMPSK+wwZMvHJmcJQWjR94ZWpmBx90Qm72ftwD04i0Syxc
+PEJZQh8BEzHFIudqlvL7Zv7IoX4kll8C7jghpRTSpjVwbI2m2CrSRTFfZ541V2rEFee6YC+OUk78
+b6AIkTFxBmgZSMeBDV5Sk1fM/kasqU/ilk+vEvvCS8SNO7A45LuNGYHkdGOcjaqEgpHf3EXwObK0
+rEXaPzBNRrHhsp3f2MSi7+kal3kCgYEA5SO41wlUVDu2eHhnV2XF1HSvBU+1yIwb0Zos1uRo0a89
+ckJQyN2x7ndSuLExvvB0eEJZ6hOLggBUItIKJLAfHnYnrmPGa1koHaCfQjDx41kcTzFJ/0V+a+/p
+b96vHgSWYU6fWPUNZAhICq6s5HaR3W4zl8WW2v+8QltxtXauAbMCgYEA3RSlbIkrgHj2w4BNU1Sz
+K0DOmBagv3Lx49zpC0UjhjhMKfGg4Cz6hj8BkMUblhBEhPvsPHRsDczDzRsoEqq0Z4DI2Rt951Q5
+A226qm/3kx+Udtarm9o9iTeD/nIqu282xeCuZfm7xuKYD732Ivg1W5nm/21uspKTZCXB6JxrcysC
+gYATMBqaZz2YkCeHjw2YU/1s/Rhq6XHfiVwLAU4f8KCWboZGuyboqyfrQDK9JJl108ztBSFiaKCW
+ElD5WX1f9R+l/V71S4WiF6U0Ve8AK/kVgLDOMOJxbfBYOY7iv1MKwHeXTm4plNu6NLdTrazstMEi
+Ocg4PWOUkzXAmMe82mNX4QKBgFFxfKtqMONoLIfC6TmMl2CUxEbU9yzwHFo0FIn5U2frr2s4P2q2
+RyhTZ7E8W7hBj+xpnhJ7VR8UUwFpQq71wfXrRJJuhUhGB6bSspR9IPhLBvdsh9WnZUn6cJ640jMw
+ej4VUknw4RMYgKoz8cvaIlX3cVihqMkSJEgdfLzDevX3AoGAQXyubkg/tQuZqsXqga2Eayl4Sxjb
+DtM+YIvvZU1YJToItSG2YQz68Gl4Tmg220FLUNjTjj10gI6g5trscIl3sp3WbgrEvfaaBxW6VZ/U
+TToPURKk2cKYdsW3KUDK9Lt0LXEDTecFdcCNln5ZoYs7oyulo8j30z5rLvpPTea+01k=
+-----END RSA PRIVATE KEY-----)";
+
+ABSL_CONST_INIT const char kWildcardCertificateRaw[] = {
+    '\x30', '\x82', '\x03', '\x5f', '\x30', '\x82', '\x02', '\x47', '\xa0',
+    '\x03', '\x02', '\x01', '\x02', '\x02', '\x14', '\x36', '\x1d', '\xe3',
+    '\xd2', '\x39', '\x35', '\x20', '\xb1', '\xae', '\x18', '\xdd', '\x71',
+    '\xc9', '\x5b', '\x4a', '\x17', '\xbe', '\x00', '\xb4', '\x15', '\x30',
+    '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d',
+    '\x01', '\x01', '\x0b', '\x05', '\x00', '\x30', '\x24', '\x31', '\x0b',
+    '\x30', '\x09', '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02',
+    '\x55', '\x53', '\x31', '\x15', '\x30', '\x13', '\x06', '\x03', '\x55',
+    '\x04', '\x03', '\x0c', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66',
+    '\x6f', '\x6f', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x1e',
+    '\x17', '\x0d', '\x32', '\x30', '\x30', '\x34', '\x32', '\x31', '\x30',
+    '\x32', '\x31', '\x38', '\x34', '\x35', '\x5a', '\x17', '\x0d', '\x32',
+    '\x31', '\x30', '\x34', '\x32', '\x31', '\x30', '\x32', '\x31', '\x38',
+    '\x34', '\x35', '\x5a', '\x30', '\x24', '\x31', '\x0b', '\x30', '\x09',
+    '\x06', '\x03', '\x55', '\x04', '\x06', '\x13', '\x02', '\x55', '\x53',
+    '\x31', '\x15', '\x30', '\x13', '\x06', '\x03', '\x55', '\x04', '\x03',
+    '\x0c', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66', '\x6f', '\x6f',
+    '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x82', '\x01', '\x22',
+    '\x30', '\x0d', '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7',
+    '\x0d', '\x01', '\x01', '\x01', '\x05', '\x00', '\x03', '\x82', '\x01',
+    '\x0f', '\x00', '\x30', '\x82', '\x01', '\x0a', '\x02', '\x82', '\x01',
+    '\x01', '\x00', '\xcc', '\xd5', '\x5d', '\xa0', '\x4a', '\x03', '\x9d',
+    '\x89', '\xa2', '\xae', '\x7a', '\x59', '\x15', '\xf7', '\x27', '\x67',
+    '\x49', '\xa4', '\xc1', '\x87', '\xcd', '\x9c', '\x02', '\x9e', '\xb9',
+    '\x2f', '\xd1', '\xa1', '\x0d', '\x57', '\xff', '\xd6', '\xc0', '\x6a',
+    '\x7b', '\xaa', '\x52', '\xb2', '\x6e', '\xa6', '\x12', '\x34', '\xcf',
+    '\xdc', '\xd3', '\x1e', '\x32', '\xc1', '\x8d', '\x42', '\xa3', '\x0b',
+    '\xd6', '\xaf', '\xe9', '\x37', '\x42', '\xf8', '\x78', '\xdc', '\xcb',
+    '\x2d', '\x0e', '\x42', '\x5a', '\xe2', '\xbf', '\xd2', '\xe4', '\x9c',
+    '\xb4', '\x34', '\x38', '\x97', '\x5e', '\x4d', '\x5e', '\x8a', '\x0b',
+    '\xd8', '\x42', '\x11', '\x88', '\x19', '\xa2', '\x23', '\x4b', '\xec',
+    '\x3b', '\x0a', '\xc9', '\x67', '\x49', '\x2c', '\x8e', '\x1c', '\x5e',
+    '\x7f', '\x42', '\xe7', '\x73', '\x0b', '\x86', '\x68', '\xf0', '\xaa',
+    '\x3f', '\x1e', '\x17', '\x3e', '\x29', '\xc4', '\x57', '\x6e', '\x34',
+    '\x78', '\xaf', '\x15', '\x03', '\x39', '\x32', '\x27', '\x80', '\x76',
+    '\xb1', '\xda', '\x08', '\xe5', '\x4d', '\x3f', '\x4c', '\xfc', '\x1e',
+    '\x23', '\x5a', '\xb3', '\xd4', '\x99', '\xdc', '\x5c', '\x2b', '\xf1',
+    '\xa8', '\xe3', '\x02', '\x0a', '\xc8', '\x4d', '\x63', '\x27', '\xb9',
+    '\x0d', '\x6c', '\xc2', '\x34', '\x82', '\x82', '\x5d', '\x56', '\xa8',
+    '\x93', '\x44', '\x8b', '\xf4', '\x8b', '\xf0', '\x63', '\xe5', '\x23',
+    '\x7f', '\x8d', '\x5f', '\x3a', '\x4a', '\xa5', '\x50', '\xb9', '\xc6',
+    '\x5c', '\xe6', '\x33', '\xe3', '\xfc', '\xc8', '\x96', '\x88', '\x88',
+    '\xe9', '\x53', '\xaf', '\x0d', '\xbb', '\x80', '\x9c', '\xbb', '\xed',
+    '\x4d', '\x06', '\xfa', '\xe9', '\x7c', '\x25', '\x1c', '\x59', '\xee',
+    '\x19', '\xcc', '\xa9', '\x7c', '\x1d', '\x86', '\xd9', '\x95', '\x78',
+    '\x2d', '\x3a', '\x95', '\x49', '\x11', '\x45', '\xfa', '\xd6', '\xef',
+    '\xd5', '\x07', '\x1c', '\x23', '\xeb', '\xad', '\xd3', '\x3b', '\x95',
+    '\xcf', '\x53', '\xa3', '\x47', '\xa9', '\xa7', '\x90', '\xde', '\x34',
+    '\xa4', '\xbb', '\x05', '\xdc', '\x54', '\x87', '\x97', '\x30', '\xea',
+    '\x25', '\xf0', '\xfd', '\xba', '\xa1', '\x1b', '\x02', '\x03', '\x01',
+    '\x00', '\x01', '\xa3', '\x81', '\x88', '\x30', '\x81', '\x85', '\x30',
+    '\x1d', '\x06', '\x03', '\x55', '\x1d', '\x0e', '\x04', '\x16', '\x04',
+    '\x14', '\x09', '\xfb', '\x77', '\xbb', '\xc8', '\x8f', '\xd6', '\xa4',
+    '\xf0', '\x74', '\xb2', '\x90', '\x46', '\x0a', '\x8d', '\x09', '\x4b',
+    '\x89', '\x2e', '\x41', '\x30', '\x1f', '\x06', '\x03', '\x55', '\x1d',
+    '\x23', '\x04', '\x18', '\x30', '\x16', '\x80', '\x14', '\x09', '\xfb',
+    '\x77', '\xbb', '\xc8', '\x8f', '\xd6', '\xa4', '\xf0', '\x74', '\xb2',
+    '\x90', '\x46', '\x0a', '\x8d', '\x09', '\x4b', '\x89', '\x2e', '\x41',
+    '\x30', '\x0f', '\x06', '\x03', '\x55', '\x1d', '\x13', '\x01', '\x01',
+    '\xff', '\x04', '\x05', '\x30', '\x03', '\x01', '\x01', '\xff', '\x30',
+    '\x32', '\x06', '\x03', '\x55', '\x1d', '\x11', '\x04', '\x2b', '\x30',
+    '\x29', '\x82', '\x08', '\x66', '\x6f', '\x6f', '\x2e', '\x74', '\x65',
+    '\x73', '\x74', '\x82', '\x0c', '\x77', '\x77', '\x77', '\x2e', '\x66',
+    '\x6f', '\x6f', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x82', '\x0f',
+    '\x2a', '\x2e', '\x77', '\x69', '\x6c', '\x64', '\x63', '\x61', '\x72',
+    '\x64', '\x2e', '\x74', '\x65', '\x73', '\x74', '\x30', '\x0d', '\x06',
+    '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01', '\x01',
+    '\x0b', '\x05', '\x00', '\x03', '\x82', '\x01', '\x01', '\x00', '\x93',
+    '\xbc', '\x33', '\x4c', '\xa4', '\xdf', '\xdc', '\xed', '\x4b', '\x4d',
+    '\x5e', '\xdb', '\xdd', '\x4a', '\xb7', '\xbc', '\x50', '\x1f', '\xca',
+    '\x66', '\x4d', '\x28', '\x96', '\x42', '\x4e', '\x84', '\x44', '\x80',
+    '\x25', '\x17', '\x2c', '\x05', '\x93', '\xe0', '\x2a', '\x29', '\xef',
+    '\xe4', '\x26', '\x19', '\x63', '\xdf', '\xb2', '\x72', '\xb1', '\x82',
+    '\x7e', '\x5f', '\xce', '\x82', '\x41', '\xad', '\x96', '\x78', '\x94',
+    '\xa8', '\x21', '\xee', '\xf2', '\x4a', '\xf5', '\x41', '\xa8', '\xfb',
+    '\xe0', '\xe1', '\x22', '\x89', '\xf1', '\x40', '\x85', '\x86', '\x53',
+    '\x61', '\x57', '\x0f', '\x31', '\xae', '\x0c', '\xc3', '\x8d', '\xe8',
+    '\x29', '\xac', '\xe0', '\x03', '\x2d', '\x69', '\x44', '\x3d', '\xd6',
+    '\x3b', '\x2b', '\x0f', '\xb3', '\xf5', '\x83', '\x1b', '\x4e', '\x65',
+    '\x60', '\x6b', '\xa2', '\x01', '\x03', '\x1e', '\x98', '\xca', '\xca',
+    '\x32', '\xd4', '\x5b', '\xde', '\x45', '\xe2', '\x35', '\xd2', '\x54',
+    '\x1a', '\x2a', '\x38', '\xa7', '\x42', '\xa0', '\xf3', '\xef', '\x28',
+    '\xe3', '\x6e', '\x23', '\x77', '\x07', '\xd5', '\xef', '\xfd', '\x30',
+    '\xd6', '\x31', '\xfa', '\xf2', '\x94', '\x95', '\x2f', '\x03', '\x7a',
+    '\x43', '\xe0', '\xb3', '\x82', '\xca', '\x7e', '\xb4', '\x00', '\xc9',
+    '\x08', '\x15', '\x7b', '\x2e', '\x51', '\xec', '\xab', '\x68', '\xca',
+    '\xc2', '\xca', '\x44', '\xe1', '\xbe', '\xe4', '\x06', '\x98', '\x87',
+    '\x9b', '\x58', '\xbc', '\xf1', '\xea', '\x55', '\xf6', '\x64', '\x92',
+    '\xe6', '\x73', '\xc9', '\xf6', '\xc5', '\x7a', '\x90', '\x42', '\x83',
+    '\x39', '\x9e', '\xd0', '\xca', '\x85', '\x6c', '\x53', '\x99', '\x64',
+    '\xbb', '\x49', '\xdc', '\xae', '\x1c', '\xe5', '\x00', '\x65', '\x13',
+    '\xdd', '\xdc', '\xde', '\x3f', '\xf9', '\x14', '\x91', '\x0d', '\xe6',
+    '\xba', '\xc1', '\x7d', '\x5f', '\xd5', '\x6d', '\xe8', '\x65', '\x9c',
+    '\xfb', '\xda', '\x82', '\xf7', '\x4d', '\x45', '\x81', '\x8c', '\x54',
+    '\xec', '\x50', '\xbb', '\x14', '\xe9', '\x06', '\xda', '\x76', '\xb3',
+    '\xf0', '\xb7', '\xbb', '\x58', '\x4c', '\x8f', '\x6a', '\x5d', '\x8e',
+    '\x93', '\x5f', '\x35'};
+
+ABSL_CONST_INIT const absl::string_view kWildcardCertificate(
+    kWildcardCertificateRaw,
+    sizeof(kWildcardCertificateRaw));
+
+ABSL_CONST_INIT const char kWildcardCertificatePrivateKeyRaw[] = {
+    '\x30', '\x82', '\x04', '\xbe', '\x02', '\x01', '\x00', '\x30', '\x0d',
+    '\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
+    '\x01', '\x01', '\x05', '\x00', '\x04', '\x82', '\x04', '\xa8', '\x30',
+    '\x82', '\x04', '\xa4', '\x02', '\x01', '\x00', '\x02', '\x82', '\x01',
+    '\x01', '\x00', '\xcc', '\xd5', '\x5d', '\xa0', '\x4a', '\x03', '\x9d',
+    '\x89', '\xa2', '\xae', '\x7a', '\x59', '\x15', '\xf7', '\x27', '\x67',
+    '\x49', '\xa4', '\xc1', '\x87', '\xcd', '\x9c', '\x02', '\x9e', '\xb9',
+    '\x2f', '\xd1', '\xa1', '\x0d', '\x57', '\xff', '\xd6', '\xc0', '\x6a',
+    '\x7b', '\xaa', '\x52', '\xb2', '\x6e', '\xa6', '\x12', '\x34', '\xcf',
+    '\xdc', '\xd3', '\x1e', '\x32', '\xc1', '\x8d', '\x42', '\xa3', '\x0b',
+    '\xd6', '\xaf', '\xe9', '\x37', '\x42', '\xf8', '\x78', '\xdc', '\xcb',
+    '\x2d', '\x0e', '\x42', '\x5a', '\xe2', '\xbf', '\xd2', '\xe4', '\x9c',
+    '\xb4', '\x34', '\x38', '\x97', '\x5e', '\x4d', '\x5e', '\x8a', '\x0b',
+    '\xd8', '\x42', '\x11', '\x88', '\x19', '\xa2', '\x23', '\x4b', '\xec',
+    '\x3b', '\x0a', '\xc9', '\x67', '\x49', '\x2c', '\x8e', '\x1c', '\x5e',
+    '\x7f', '\x42', '\xe7', '\x73', '\x0b', '\x86', '\x68', '\xf0', '\xaa',
+    '\x3f', '\x1e', '\x17', '\x3e', '\x29', '\xc4', '\x57', '\x6e', '\x34',
+    '\x78', '\xaf', '\x15', '\x03', '\x39', '\x32', '\x27', '\x80', '\x76',
+    '\xb1', '\xda', '\x08', '\xe5', '\x4d', '\x3f', '\x4c', '\xfc', '\x1e',
+    '\x23', '\x5a', '\xb3', '\xd4', '\x99', '\xdc', '\x5c', '\x2b', '\xf1',
+    '\xa8', '\xe3', '\x02', '\x0a', '\xc8', '\x4d', '\x63', '\x27', '\xb9',
+    '\x0d', '\x6c', '\xc2', '\x34', '\x82', '\x82', '\x5d', '\x56', '\xa8',
+    '\x93', '\x44', '\x8b', '\xf4', '\x8b', '\xf0', '\x63', '\xe5', '\x23',
+    '\x7f', '\x8d', '\x5f', '\x3a', '\x4a', '\xa5', '\x50', '\xb9', '\xc6',
+    '\x5c', '\xe6', '\x33', '\xe3', '\xfc', '\xc8', '\x96', '\x88', '\x88',
+    '\xe9', '\x53', '\xaf', '\x0d', '\xbb', '\x80', '\x9c', '\xbb', '\xed',
+    '\x4d', '\x06', '\xfa', '\xe9', '\x7c', '\x25', '\x1c', '\x59', '\xee',
+    '\x19', '\xcc', '\xa9', '\x7c', '\x1d', '\x86', '\xd9', '\x95', '\x78',
+    '\x2d', '\x3a', '\x95', '\x49', '\x11', '\x45', '\xfa', '\xd6', '\xef',
+    '\xd5', '\x07', '\x1c', '\x23', '\xeb', '\xad', '\xd3', '\x3b', '\x95',
+    '\xcf', '\x53', '\xa3', '\x47', '\xa9', '\xa7', '\x90', '\xde', '\x34',
+    '\xa4', '\xbb', '\x05', '\xdc', '\x54', '\x87', '\x97', '\x30', '\xea',
+    '\x25', '\xf0', '\xfd', '\xba', '\xa1', '\x1b', '\x02', '\x03', '\x01',
+    '\x00', '\x01', '\x02', '\x82', '\x01', '\x01', '\x00', '\xa3', '\xb3',
+    '\x01', '\x98', '\x50', '\x8e', '\x83', '\x20', '\xb4', '\x3a', '\xec',
+    '\xdc', '\xb5', '\x89', '\x48', '\x9c', '\x6b', '\x66', '\x98', '\xa4',
+    '\x87', '\xd5', '\xde', '\xe2', '\x2a', '\xed', '\xe4', '\x82', '\xe9',
+    '\xbf', '\x22', '\x5f', '\xe6', '\x77', '\x33', '\x4d', '\xf3', '\xb9',
+    '\x56', '\x64', '\xb2', '\xb8', '\x32', '\x47', '\x31', '\x12', '\x39',
+    '\x4e', '\x26', '\x2e', '\xd3', '\x4f', '\x6a', '\xcc', '\x3b', '\x7e',
+    '\x46', '\xaf', '\x7d', '\x28', '\x37', '\xd8', '\x52', '\x45', '\x05',
+    '\x8d', '\xa1', '\xf0', '\x51', '\x74', '\x4b', '\x30', '\x50', '\xe9',
+    '\xe8', '\x1b', '\xbd', '\x2a', '\x66', '\x3c', '\xf6', '\xd0', '\x3c',
+    '\x0d', '\x00', '\x5f', '\x65', '\x15', '\xee', '\x39', '\xb8', '\xac',
+    '\x2a', '\xf6', '\xc8', '\xbc', '\x33', '\x69', '\x51', '\x76', '\xd7',
+    '\xa2', '\xa6', '\x50', '\xc7', '\xc5', '\xc7', '\x9b', '\xac', '\xc7',
+    '\xa9', '\x69', '\x98', '\xd6', '\x22', '\x69', '\x30', '\xc3', '\x82',
+    '\x47', '\xfb', '\xa5', '\x46', '\x2d', '\x96', '\x05', '\xc2', '\x84',
+    '\xd1', '\x1d', '\xd5', '\xa7', '\x5c', '\xdb', '\x6d', '\x35', '\x7b',
+    '\x1b', '\x80', '\xe4', '\x42', '\x1f', '\x4d', '\x68', '\x2e', '\xbc',
+    '\x58', '\xb6', '\x7c', '\x7e', '\xc5', '\x07', '\xe1', '\xf5', '\x30',
+    '\xa9', '\x8f', '\x14', '\x76', '\xad', '\xe2', '\xdf', '\xaf', '\xd3',
+    '\xf1', '\xba', '\xd5', '\x98', '\xf3', '\x5e', '\x30', '\x79', '\xcb',
+    '\xe7', '\x7a', '\x83', '\xba', '\xf7', '\x71', '\xb0', '\xb2', '\xd1',
+    '\xf4', '\x34', '\x5b', '\xe1', '\xe8', '\x60', '\x39', '\x96', '\x12',
+    '\xdc', '\xb4', '\x0d', '\xf9', '\x8d', '\x8c', '\xd8', '\xbb', '\xb7',
+    '\xd2', '\x1b', '\x83', '\x10', '\xbd', '\x86', '\xef', '\x5c', '\x6c',
+    '\xe3', '\xb1', '\x96', '\x7f', '\xab', '\x58', '\xce', '\x87', '\xc9',
+    '\x48', '\x69', '\xbb', '\xb1', '\xec', '\xa4', '\x3a', '\x06', '\xa3',
+    '\x33', '\xad', '\x7a', '\xe5', '\x88', '\x6d', '\x32', '\x67', '\x1c',
+    '\x03', '\xda', '\x9d', '\x3c', '\x73', '\xe0', '\xd7', '\x6c', '\x00',
+    '\xe4', '\x8d', '\x7d', '\xf2', '\xac', '\xa5', '\xb8', '\x35', '\xb9',
+    '\xac', '\x81', '\x02', '\x81', '\x81', '\x00', '\xe8', '\xd5', '\x5b',
+    '\xd0', '\x4f', '\x7c', '\xfc', '\x4b', '\xe6', '\xe8', '\x3c', '\x4c',
+    '\x24', '\xce', '\x68', '\x73', '\x3b', '\x4b', '\xa0', '\xfb', '\x79',
+    '\xa5', '\x72', '\x1d', '\x77', '\xb2', '\xdf', '\x2b', '\x0a', '\x11',
+    '\x28', '\xe8', '\x02', '\x7f', '\x26', '\x40', '\x34', '\x8f', '\x78',
+    '\x18', '\xad', '\xf4', '\x11', '\x78', '\x45', '\x9f', '\x66', '\x4e',
+    '\x78', '\x71', '\x60', '\x40', '\xeb', '\x64', '\x28', '\x06', '\xae',
+    '\x9b', '\x32', '\x73', '\xb5', '\xe1', '\x7e', '\x3c', '\x07', '\x31',
+    '\x8d', '\x82', '\xed', '\x6a', '\xe6', '\x1e', '\x65', '\x9e', '\x81',
+    '\x29', '\x08', '\x56', '\x17', '\x4b', '\x31', '\xc3', '\xf5', '\x27',
+    '\xef', '\xb8', '\xda', '\x58', '\xff', '\x36', '\x47', '\x12', '\xb0',
+    '\xef', '\x14', '\x20', '\x5c', '\x48', '\xb3', '\x84', '\x0d', '\x64',
+    '\x22', '\x3e', '\xfe', '\x94', '\x17', '\x6c', '\x45', '\xe7', '\x3f',
+    '\x4c', '\x90', '\x67', '\x13', '\x1a', '\xa8', '\xbc', '\x5b', '\xd0',
+    '\xc1', '\x8a', '\xa9', '\x42', '\xbe', '\xe4', '\x0e', '\x59', '\x02',
+    '\x81', '\x81', '\x00', '\xe1', '\x36', '\xcd', '\x86', '\x1e', '\xcb',
+    '\x8b', '\x68', '\x65', '\x6b', '\x42', '\xec', '\x50', '\x29', '\xa0',
+    '\xab', '\x3a', '\xe5', '\x6f', '\xe1', '\x13', '\xe8', '\xa3', '\x6b',
+    '\x7c', '\x2b', '\xd3', '\x69', '\x89', '\x47', '\x07', '\x39', '\xb2',
+    '\x0f', '\x03', '\x4e', '\x6f', '\x28', '\x94', '\x1d', '\x1f', '\x22',
+    '\x47', '\xf9', '\x95', '\xff', '\x3e', '\xa4', '\x26', '\x38', '\x07',
+    '\x5b', '\xdd', '\xef', '\x0a', '\xa5', '\xe8', '\x99', '\xad', '\x91',
+    '\x68', '\x83', '\xf2', '\xf5', '\xa5', '\x3d', '\x21', '\x88', '\xa5',
+    '\x6a', '\x39', '\x3b', '\xca', '\x4c', '\xc9', '\xd1', '\x9a', '\x74',
+    '\xb2', '\xe3', '\x73', '\x5d', '\xfe', '\xbd', '\x05', '\x1b', '\x9a',
+    '\x13', '\x98', '\x39', '\x93', '\xf3', '\x88', '\x55', '\x61', '\x85',
+    '\x7a', '\x53', '\x5a', '\xd9', '\x2c', '\xdb', '\x15', '\x69', '\xa6',
+    '\x31', '\x09', '\xbb', '\xd1', '\xe8', '\x6e', '\x8c', '\x47', '\x77',
+    '\x1e', '\x9b', '\xbe', '\xb7', '\x57', '\xd4', '\xaa', '\xd5', '\x92',
+    '\xa1', '\xd5', '\x55', '\x04', '\x93', '\x02', '\x81', '\x80', '\x06',
+    '\x84', '\x01', '\xff', '\xc0', '\x59', '\xb5', '\x0d', '\xc2', '\xb6',
+    '\x79', '\x09', '\x80', '\x76', '\x2e', '\x42', '\x1b', '\x44', '\xb0',
+    '\x8a', '\x99', '\x0a', '\xe2', '\x38', '\xa4', '\xe2', '\xe2', '\x8f',
+    '\xe7', '\xc6', '\x37', '\x28', '\xd6', '\xf9', '\x0b', '\xee', '\xfc',
+    '\x09', '\x8f', '\xc8', '\xd1', '\x05', '\x65', '\x7f', '\xc2', '\x23',
+    '\x05', '\xcf', '\xe8', '\x5a', '\xf3', '\xe0', '\x9d', '\x35', '\xbe',
+    '\x51', '\x01', '\x8d', '\xe2', '\x49', '\x8e', '\xab', '\x72', '\xc6',
+    '\xe7', '\x44', '\xa1', '\xbb', '\x2a', '\x3d', '\xb5', '\x96', '\xe0',
+    '\x2d', '\x21', '\x5c', '\x2e', '\x99', '\x8a', '\x29', '\x56', '\x89',
+    '\x2f', '\x51', '\x20', '\xca', '\x41', '\x82', '\x00', '\x12', '\x5a',
+    '\xc6', '\xd1', '\x20', '\xbf', '\xa5', '\x70', '\x2f', '\xb0', '\xa6',
+    '\x5f', '\x61', '\x8f', '\xfb', '\xc7', '\x50', '\x09', '\x9f', '\xc4',
+    '\x0d', '\x06', '\x9e', '\x73', '\xe4', '\x0e', '\x8a', '\xce', '\x72',
+    '\x06', '\xf7', '\xbe', '\x92', '\xcc', '\xcd', '\xcb', '\x5d', '\xc2',
+    '\x71', '\x02', '\x81', '\x80', '\x26', '\xf3', '\xba', '\x92', '\x52',
+    '\xeb', '\x33', '\x7e', '\x67', '\xe4', '\x28', '\x5c', '\x04', '\xf5',
+    '\x5e', '\x33', '\x9f', '\x69', '\x25', '\x73', '\x91', '\x64', '\xf0',
+    '\x36', '\xdb', '\xf0', '\x1c', '\x8d', '\xa9', '\x4f', '\x9e', '\xa1',
+    '\x4c', '\xf9', '\xa9', '\xc1', '\xbc', '\x1a', '\x11', '\x9c', '\x03',
+    '\xd1', '\x83', '\x0f', '\x58', '\xf1', '\x1f', '\x9d', '\x76', '\x7a',
+    '\xc4', '\x53', '\x10', '\x4c', '\x92', '\xd3', '\xe5', '\x2a', '\x07',
+    '\x4a', '\x1a', '\x00', '\x90', '\x5a', '\x0a', '\x2d', '\x4b', '\x8a',
+    '\x7d', '\xc9', '\xa4', '\x82', '\x81', '\xd7', '\xcc', '\x24', '\x33',
+    '\x89', '\xb1', '\x93', '\x03', '\x56', '\x23', '\x83', '\xff', '\xc9',
+    '\x29', '\x59', '\xf0', '\x3f', '\x2d', '\x26', '\xb6', '\xd2', '\xc5',
+    '\x9e', '\x37', '\x6d', '\x09', '\x4e', '\x7c', '\xa2', '\x9b', '\xce',
+    '\x7d', '\x0f', '\x08', '\x36', '\xf2', '\xf4', '\x37', '\x82', '\x8d',
+    '\xad', '\xbd', '\x9e', '\x84', '\x5a', '\xe3', '\x97', '\x05', '\xc1',
+    '\x10', '\xae', '\x6a', '\xde', '\x5c', '\x7f', '\x02', '\x81', '\x81',
+    '\x00', '\x9b', '\x8e', '\xa4', '\x2b', '\xcf', '\xb6', '\x30', '\x1c',
+    '\xb5', '\x82', '\x50', '\x08', '\xc0', '\x0b', '\x57', '\xf4', '\x2d',
+    '\x82', '\x39', '\x11', '\x1b', '\x02', '\xe6', '\xbe', '\x14', '\x26',
+    '\x77', '\xd7', '\x26', '\x1f', '\x0d', '\x92', '\xc6', '\x67', '\xa0',
+    '\x01', '\x6c', '\xd9', '\x7a', '\xdf', '\xc3', '\x3d', '\x50', '\x8d',
+    '\x43', '\xef', '\x95', '\x50', '\x72', '\x25', '\x06', '\x28', '\x7a',
+    '\x7e', '\x99', '\xea', '\x4d', '\xe8', '\x87', '\xe5', '\xca', '\x71',
+    '\x36', '\x8a', '\xce', '\x18', '\x55', '\xe4', '\x87', '\x39', '\x3d',
+    '\xea', '\x9a', '\x22', '\x99', '\x1a', '\xab', '\xe3', '\x6f', '\x48',
+    '\x78', '\x49', '\x8f', '\xf6', '\xfa', '\xb1', '\xb8', '\x68', '\xae',
+    '\xc3', '\x47', '\x1d', '\x8f', '\x1d', '\x11', '\xa1', '\x06', '\xf5',
+    '\xc0', '\x0d', '\xcf', '\x7b', '\x33', '\xfe', '\x0c', '\x69', '\xca',
+    '\x46', '\xfe', '\x2c', '\xac', '\xd8', '\x4d', '\x02', '\x79', '\xfe',
+    '\x47', '\xca', '\x21', '\x30', '\x65', '\xa4', '\xe5', '\xaa', '\x4e',
+    '\x9c', '\xbc', '\xa5'};
+
+ABSL_CONST_INIT const absl::string_view kWildcardCertificatePrivateKey(
+    kWildcardCertificatePrivateKeyRaw,
+    sizeof(kWildcardCertificatePrivateKeyRaw));
+
+ABSL_CONST_INIT const char kTestEcPrivateKeyLegacyPem[] =
+    R"(-----BEGIN EC PARAMETERS-----
+BggqhkjOPQMBBw==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMdjXX0hg399DlccZuYFXPKq+dMGduXWmQYClDYJNDGroAoGCCqGSM49
+AwEHoUQDQgAENCuPQTywFI8hbsGo68AeN1KVWmd09buzlu/2CAtsJcNoECUmpVXH
+4dwvWMv6zWn9RJ5EzI72R/5FVcO485s5MQ==
+-----END EC PRIVATE KEY-----)";
+
+}  // namespace test
+}  // namespace quic
diff --git a/quic/test_tools/test_certificates.h b/quiche/quic/test_tools/test_certificates.h
similarity index 100%
rename from quic/test_tools/test_certificates.h
rename to quiche/quic/test_tools/test_certificates.h
diff --git a/quiche/quic/test_tools/test_ticket_crypter.cc b/quiche/quic/test_tools/test_ticket_crypter.cc
new file mode 100644
index 0000000..7c4a54e
--- /dev/null
+++ b/quiche/quic/test_tools/test_ticket_crypter.cc
@@ -0,0 +1,83 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/test_ticket_crypter.h"
+
+#include <cstring>
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+// A TicketCrypter implementation is supposed to encrypt and decrypt session
+// tickets. However, the only requirement that is needed of a test
+// implementation is that calling Decrypt(Encrypt(input), callback) results in
+// callback being called with input. (The output of Encrypt must also not exceed
+// the overhead specified by MaxOverhead.) This test implementation encrypts
+// tickets by prepending kTicketPrefix to generate the ciphertext. The decrypt
+// function checks that the prefix is present and strips it; otherwise it
+// returns an empty vector to signal failure.
+constexpr char kTicketPrefix[] = "TEST TICKET";
+
+}  // namespace
+
+TestTicketCrypter::TestTicketCrypter()
+    : ticket_prefix_(ABSL_ARRAYSIZE(kTicketPrefix) + 16) {
+  memcpy(ticket_prefix_.data(), kTicketPrefix, ABSL_ARRAYSIZE(kTicketPrefix));
+  QuicRandom::GetInstance()->RandBytes(
+      ticket_prefix_.data() + ABSL_ARRAYSIZE(kTicketPrefix), 16);
+}
+
+size_t TestTicketCrypter::MaxOverhead() {
+  return ticket_prefix_.size();
+}
+
+std::vector<uint8_t> TestTicketCrypter::Encrypt(
+    absl::string_view in, absl::string_view /* encryption_key */) {
+  size_t prefix_len = ticket_prefix_.size();
+  std::vector<uint8_t> out(prefix_len + in.size());
+  memcpy(out.data(), ticket_prefix_.data(), prefix_len);
+  memcpy(out.data() + prefix_len, in.data(), in.size());
+  return out;
+}
+
+std::vector<uint8_t> TestTicketCrypter::Decrypt(absl::string_view in) {
+  size_t prefix_len = ticket_prefix_.size();
+  if (fail_decrypt_ || in.size() < prefix_len ||
+      memcmp(ticket_prefix_.data(), in.data(), prefix_len) != 0) {
+    return std::vector<uint8_t>();
+  }
+  return std::vector<uint8_t>(in.begin() + prefix_len, in.end());
+}
+
+void TestTicketCrypter::Decrypt(
+    absl::string_view in,
+    std::unique_ptr<ProofSource::DecryptCallback> callback) {
+  auto decrypted_ticket = Decrypt(in);
+  if (run_async_) {
+    pending_callbacks_.push_back({std::move(callback), decrypted_ticket});
+  } else {
+    callback->Run(decrypted_ticket);
+  }
+}
+
+void TestTicketCrypter::SetRunCallbacksAsync(bool run_async) {
+  run_async_ = run_async;
+}
+
+size_t TestTicketCrypter::NumPendingCallbacks() {
+  return pending_callbacks_.size();
+}
+
+void TestTicketCrypter::RunPendingCallback(size_t n) {
+  const PendingCallback& callback = pending_callbacks_[n];
+  callback.callback->Run(callback.decrypted_ticket);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/test_ticket_crypter.h b/quiche/quic/test_tools/test_ticket_crypter.h
new file mode 100644
index 0000000..8443099
--- /dev/null
+++ b/quiche/quic/test_tools/test_ticket_crypter.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
+#define QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
+
+#include "quiche/quic/core/crypto/proof_source.h"
+
+namespace quic {
+namespace test {
+
+// Provides a simple implementation of ProofSource::TicketCrypter for testing.
+// THIS IMPLEMENTATION IS NOT SECURE. It is only intended for testing purposes.
+class TestTicketCrypter : public ProofSource::TicketCrypter {
+ public:
+  TestTicketCrypter();
+  ~TestTicketCrypter() override = default;
+
+  // TicketCrypter interface
+  size_t MaxOverhead() override;
+  std::vector<uint8_t> Encrypt(absl::string_view in,
+                               absl::string_view encryption_key) override;
+  void Decrypt(absl::string_view in,
+               std::unique_ptr<ProofSource::DecryptCallback> callback) override;
+
+  void SetRunCallbacksAsync(bool run_async);
+  size_t NumPendingCallbacks();
+  void RunPendingCallback(size_t n);
+
+  // Allows configuring this TestTicketCrypter to fail decryption.
+  void set_fail_decrypt(bool fail_decrypt) { fail_decrypt_ = fail_decrypt; }
+
+ private:
+  // Performs the Decrypt operation synchronously.
+  std::vector<uint8_t> Decrypt(absl::string_view in);
+
+  struct PendingCallback {
+    std::unique_ptr<ProofSource::DecryptCallback> callback;
+    std::vector<uint8_t> decrypted_ticket;
+  };
+
+  bool fail_decrypt_ = false;
+  bool run_async_ = false;
+  std::vector<PendingCallback> pending_callbacks_;
+  std::vector<uint8_t> ticket_prefix_;
+};
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_TEST_TICKET_CRYPTER_H_
diff --git a/quiche/quic/test_tools/web_transport_resets_backend.cc b/quiche/quic/test_tools/web_transport_resets_backend.cc
new file mode 100644
index 0000000..aa48dd6
--- /dev/null
+++ b/quiche/quic/test_tools/web_transport_resets_backend.cc
@@ -0,0 +1,113 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/test_tools/web_transport_resets_backend.h"
+
+#include <memory>
+
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/tools/web_transport_test_visitors.h"
+#include "quiche/common/quiche_circular_deque.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+class ResetsVisitor;
+
+class BidirectionalEchoVisitorWithLogging
+    : public WebTransportBidirectionalEchoVisitor {
+ public:
+  BidirectionalEchoVisitorWithLogging(WebTransportStream* stream,
+                                      ResetsVisitor* session_visitor)
+      : WebTransportBidirectionalEchoVisitor(stream),
+        session_visitor_(session_visitor) {}
+
+  void OnResetStreamReceived(WebTransportStreamError error) override;
+  void OnStopSendingReceived(WebTransportStreamError error) override;
+
+ private:
+  ResetsVisitor* session_visitor_;  // Not owned.
+};
+
+class ResetsVisitor : public WebTransportVisitor {
+ public:
+  ResetsVisitor(WebTransportSession* session) : session_(session) {}
+
+  void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
+  void OnSessionClosed(WebTransportSessionError /*error_code*/,
+                       const std::string& /*error_message*/) override {}
+
+  void OnIncomingBidirectionalStreamAvailable() override {
+    while (true) {
+      WebTransportStream* stream =
+          session_->AcceptIncomingBidirectionalStream();
+      if (stream == nullptr) {
+        return;
+      }
+      stream->SetVisitor(
+          std::make_unique<BidirectionalEchoVisitorWithLogging>(stream, this));
+      stream->visitor()->OnCanRead();
+    }
+  }
+  void OnIncomingUnidirectionalStreamAvailable() override {}
+
+  void OnDatagramReceived(absl::string_view /*datagram*/) override {}
+
+  void OnCanCreateNewOutgoingBidirectionalStream() override {}
+  void OnCanCreateNewOutgoingUnidirectionalStream() override {
+    MaybeSendLogsBack();
+  }
+
+  void Log(std::string line) {
+    log_.push_back(std::move(line));
+    MaybeSendLogsBack();
+  }
+
+ private:
+  void MaybeSendLogsBack() {
+    while (!log_.empty() &&
+           session_->CanOpenNextOutgoingUnidirectionalStream()) {
+      WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
+      stream->SetVisitor(
+          std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
+              stream, log_.front()));
+      log_.pop_front();
+      stream->visitor()->OnCanWrite();
+    }
+  }
+
+  WebTransportSession* session_;  // Not owned.
+  quiche::QuicheCircularDeque<std::string> log_;
+};
+
+void BidirectionalEchoVisitorWithLogging::OnResetStreamReceived(
+    WebTransportStreamError error) {
+  session_visitor_->Log(absl::StrCat("Received reset for stream ",
+                                     stream()->GetStreamId(),
+                                     " with error code ", error));
+  WebTransportBidirectionalEchoVisitor::OnResetStreamReceived(error);
+}
+void BidirectionalEchoVisitorWithLogging::OnStopSendingReceived(
+    WebTransportStreamError error) {
+  session_visitor_->Log(absl::StrCat("Received stop sending for stream ",
+                                     stream()->GetStreamId(),
+                                     " with error code ", error));
+  WebTransportBidirectionalEchoVisitor::OnStopSendingReceived(error);
+}
+
+}  // namespace
+
+QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
+    const spdy::Http2HeaderBlock& /*request_headers*/,
+    WebTransportSession* session) {
+  QuicSimpleServerBackend::WebTransportResponse response;
+  response.response_headers[":status"] = "200";
+  response.visitor = std::make_unique<ResetsVisitor>(session);
+  return response;
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/test_tools/web_transport_resets_backend.h b/quiche/quic/test_tools/web_transport_resets_backend.h
new file mode 100644
index 0000000..d3b490c
--- /dev/null
+++ b/quiche/quic/test_tools/web_transport_resets_backend.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
+#define QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
+
+#include "quiche/quic/test_tools/quic_test_backend.h"
+
+namespace quic {
+namespace test {
+
+// A backend for testing RESET_STREAM/STOP_SENDING behavior.  Provides
+// bidirectional echo streams; whenever one of those receives RESET_STREAM or
+// STOP_SENDING, a log message is sent as a unidirectional stream.
+QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
+    const spdy::Http2HeaderBlock& request_headers,
+    WebTransportSession* session);
+
+}  // namespace test
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TEST_TOOLS_WEB_TRANSPORT_RESETS_BACKEND_H_
diff --git a/quiche/quic/tools/fake_proof_verifier.h b/quiche/quic/tools/fake_proof_verifier.h
new file mode 100644
index 0000000..62ab87a
--- /dev/null
+++ b/quiche/quic/tools/fake_proof_verifier.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
+#define QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/proof_verifier.h"
+
+namespace quic {
+
+// ProofVerifier implementation which always returns success.
+class FakeProofVerifier : public ProofVerifier {
+ public:
+  ~FakeProofVerifier() override {}
+  QuicAsyncStatus VerifyProof(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::string& /*server_config*/,
+      QuicTransportVersion /*quic_version*/,
+      absl::string_view /*chlo_hash*/,
+      const std::vector<std::string>& /*certs*/,
+      const std::string& /*cert_sct*/,
+      const std::string& /*signature*/,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*details*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return QUIC_SUCCESS;
+  }
+  QuicAsyncStatus VerifyCertChain(
+      const std::string& /*hostname*/,
+      const uint16_t /*port*/,
+      const std::vector<std::string>& /*certs*/,
+      const std::string& /*ocsp_response*/,
+      const std::string& /*cert_sct*/,
+      const ProofVerifyContext* /*context*/,
+      std::string* /*error_details*/,
+      std::unique_ptr<ProofVerifyDetails>* /*details*/,
+      uint8_t* /*out_alert*/,
+      std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+    return QUIC_SUCCESS;
+  }
+  std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+    return nullptr;
+  }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_FAKE_PROOF_VERIFIER_H_
diff --git a/quiche/quic/tools/quic_backend_response.cc b/quiche/quic/tools/quic_backend_response.cc
new file mode 100644
index 0000000..d079d63
--- /dev/null
+++ b/quiche/quic/tools/quic_backend_response.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_backend_response.h"
+
+namespace quic {
+
+QuicBackendResponse::ServerPushInfo::ServerPushInfo(
+    QuicUrl request_url,
+    spdy::Http2HeaderBlock headers,
+    spdy::SpdyPriority priority,
+    std::string body)
+    : request_url(request_url),
+      headers(std::move(headers)),
+      priority(priority),
+      body(body) {}
+
+QuicBackendResponse::ServerPushInfo::ServerPushInfo(const ServerPushInfo& other)
+    : request_url(other.request_url),
+      headers(other.headers.Clone()),
+      priority(other.priority),
+      body(other.body) {}
+
+QuicBackendResponse::QuicBackendResponse() : response_type_(REGULAR_RESPONSE) {}
+
+QuicBackendResponse::~QuicBackendResponse() = default;
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_backend_response.h b/quiche/quic/tools/quic_backend_response.h
new file mode 100644
index 0000000..e67e186
--- /dev/null
+++ b/quiche/quic/tools/quic_backend_response.h
@@ -0,0 +1,92 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
+#define QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+// Container for HTTP response header/body pairs
+// fetched by the QuicSimpleServerBackend
+class QuicBackendResponse {
+ public:
+  // A ServerPushInfo contains path of the push request and everything needed in
+  // comprising a response for the push request.
+  // TODO(b/171463363): Remove.
+  struct ServerPushInfo {
+    ServerPushInfo(QuicUrl request_url,
+                   spdy::Http2HeaderBlock headers,
+                   spdy::SpdyPriority priority,
+                   std::string body);
+    ServerPushInfo(const ServerPushInfo& other);
+
+    QuicUrl request_url;
+    spdy::Http2HeaderBlock headers;
+    spdy::SpdyPriority priority;
+    std::string body;
+  };
+
+  enum SpecialResponseType {
+    REGULAR_RESPONSE,      // Send the headers and body like a server should.
+    CLOSE_CONNECTION,      // Close the connection (sending the close packet).
+    IGNORE_REQUEST,        // Do nothing, expect the client to time out.
+    BACKEND_ERR_RESPONSE,  // There was an error fetching the response from
+                           // the backend, for example as a TCP connection
+                           // error.
+    INCOMPLETE_RESPONSE,   // The server will act as if there is a non-empty
+                           // trailer but it will not be sent, as a result, FIN
+                           // will not be sent too.
+    GENERATE_BYTES         // Sends a response with a length equal to the number
+                           // of bytes in the URL path.
+  };
+  QuicBackendResponse();
+
+  QuicBackendResponse(const QuicBackendResponse& other) = delete;
+  QuicBackendResponse& operator=(const QuicBackendResponse& other) = delete;
+
+  ~QuicBackendResponse();
+
+  const std::vector<spdy::Http2HeaderBlock>& early_hints() const {
+    return early_hints_;
+  }
+  SpecialResponseType response_type() const { return response_type_; }
+  const spdy::Http2HeaderBlock& headers() const { return headers_; }
+  const spdy::Http2HeaderBlock& trailers() const { return trailers_; }
+  const absl::string_view body() const { return absl::string_view(body_); }
+
+  void AddEarlyHints(const spdy::Http2HeaderBlock& headers) {
+    spdy::Http2HeaderBlock hints = headers.Clone();
+    hints[":status"] = "103";
+    early_hints_.push_back(std::move(hints));
+  }
+
+  void set_response_type(SpecialResponseType response_type) {
+    response_type_ = response_type;
+  }
+
+  void set_headers(spdy::Http2HeaderBlock headers) {
+    headers_ = std::move(headers);
+  }
+  void set_trailers(spdy::Http2HeaderBlock trailers) {
+    trailers_ = std::move(trailers);
+  }
+  void set_body(absl::string_view body) {
+    body_.assign(body.data(), body.size());
+  }
+
+ private:
+  std::vector<spdy::Http2HeaderBlock> early_hints_;
+  SpecialResponseType response_type_;
+  spdy::Http2HeaderBlock headers_;
+  spdy::Http2HeaderBlock trailers_;
+  std::string body_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_
diff --git a/quiche/quic/tools/quic_client.cc b/quiche/quic/tools/quic_client.cc
new file mode 100644
index 0000000..a493e9c
--- /dev/null
+++ b/quiche/quic/tools/quic_client.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_client.h"
+
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <utility>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_simple_client_session.h"
+
+namespace quic {
+
+namespace tools {
+
+QuicSocketAddress LookupAddress(int address_family_for_lookup,
+                                std::string host,
+                                std::string port) {
+  addrinfo hint;
+  memset(&hint, 0, sizeof(hint));
+  hint.ai_family = address_family_for_lookup;
+  hint.ai_protocol = IPPROTO_UDP;
+
+  addrinfo* info_list = nullptr;
+  int result = getaddrinfo(host.c_str(), port.c_str(), &hint, &info_list);
+  if (result != 0) {
+    QUIC_LOG(ERROR) << "Failed to look up " << host << ": "
+                    << gai_strerror(result);
+    return QuicSocketAddress();
+  }
+
+  QUICHE_CHECK(info_list != nullptr);
+  std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(info_list,
+                                                                 freeaddrinfo);
+  return QuicSocketAddress(info_list->ai_addr, info_list->ai_addrlen);
+}
+
+}  // namespace tools
+
+QuicClient::QuicClient(QuicSocketAddress server_address,
+                       const QuicServerId& server_id,
+                       const ParsedQuicVersionVector& supported_versions,
+                       QuicEpollServer* epoll_server,
+                       std::unique_ptr<ProofVerifier> proof_verifier)
+    : QuicClient(
+          server_address,
+          server_id,
+          supported_versions,
+          QuicConfig(),
+          epoll_server,
+          std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
+          std::move(proof_verifier),
+          nullptr) {}
+
+QuicClient::QuicClient(QuicSocketAddress server_address,
+                       const QuicServerId& server_id,
+                       const ParsedQuicVersionVector& supported_versions,
+                       QuicEpollServer* epoll_server,
+                       std::unique_ptr<ProofVerifier> proof_verifier,
+                       std::unique_ptr<SessionCache> session_cache)
+    : QuicClient(
+          server_address,
+          server_id,
+          supported_versions,
+          QuicConfig(),
+          epoll_server,
+          std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
+          std::move(proof_verifier),
+          std::move(session_cache)) {}
+
+QuicClient::QuicClient(QuicSocketAddress server_address,
+                       const QuicServerId& server_id,
+                       const ParsedQuicVersionVector& supported_versions,
+                       const QuicConfig& config,
+                       QuicEpollServer* epoll_server,
+                       std::unique_ptr<ProofVerifier> proof_verifier,
+                       std::unique_ptr<SessionCache> session_cache)
+    : QuicClient(
+          server_address,
+          server_id,
+          supported_versions,
+          config,
+          epoll_server,
+          std::make_unique<QuicClientEpollNetworkHelper>(epoll_server, this),
+          std::move(proof_verifier),
+          std::move(session_cache)) {}
+
+QuicClient::QuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+    std::unique_ptr<ProofVerifier> proof_verifier)
+    : QuicClient(server_address,
+                 server_id,
+                 supported_versions,
+                 QuicConfig(),
+                 epoll_server,
+                 std::move(network_helper),
+                 std::move(proof_verifier),
+                 nullptr) {}
+
+QuicClient::QuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicConfig& config,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+    std::unique_ptr<ProofVerifier> proof_verifier)
+    : QuicClient(server_address,
+                 server_id,
+                 supported_versions,
+                 config,
+                 epoll_server,
+                 std::move(network_helper),
+                 std::move(proof_verifier),
+                 nullptr) {}
+
+QuicClient::QuicClient(
+    QuicSocketAddress server_address,
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicConfig& config,
+    QuicEpollServer* epoll_server,
+    std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : QuicSpdyClientBase(
+          server_id,
+          supported_versions,
+          config,
+          new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
+          new QuicEpollAlarmFactory(epoll_server),
+          std::move(network_helper),
+          std::move(proof_verifier),
+          std::move(session_cache)) {
+  set_server_address(server_address);
+}
+
+QuicClient::~QuicClient() = default;
+
+std::unique_ptr<QuicSession> QuicClient::CreateQuicClientSession(
+    const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection) {
+  return std::make_unique<QuicSimpleClientSession>(
+      *config(), supported_versions, connection, server_id(), crypto_config(),
+      push_promise_index(), drop_response_body(), enable_web_transport(),
+      use_datagram_contexts());
+}
+
+QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() {
+  return static_cast<QuicClientEpollNetworkHelper*>(network_helper());
+}
+
+const QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() const {
+  return static_cast<const QuicClientEpollNetworkHelper*>(network_helper());
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_client.h b/quiche/quic/tools/quic_client.h
new file mode 100644
index 0000000..446e9c6
--- /dev/null
+++ b/quiche/quic/tools/quic_client.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A toy client, which connects to a specified port and sends QUIC
+// request to that endpoint.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
+#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packet_reader.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/tools/quic_client_epoll_network_helper.h"
+#include "quiche/quic/tools/quic_spdy_client_base.h"
+
+namespace quic {
+
+class QuicServerId;
+
+namespace test {
+class QuicClientPeer;
+}  // namespace test
+
+namespace tools {
+
+QuicSocketAddress LookupAddress(int address_family_for_lookup,
+                                std::string host,
+                                std::string port);
+
+inline QuicSocketAddress LookupAddress(std::string host, std::string port) {
+  return LookupAddress(0, host, port);
+}
+
+}  // namespace tools
+
+class QuicClient : public QuicSpdyClientBase {
+ public:
+  // These will create their own QuicClientEpollNetworkHelper.
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<ProofVerifier> proof_verifier,
+             std::unique_ptr<SessionCache> session_cache);
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             const QuicConfig& config,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<ProofVerifier> proof_verifier,
+             std::unique_ptr<SessionCache> session_cache);
+  // This will take ownership of a passed in network primitive.
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+             std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             const QuicConfig& config,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+             std::unique_ptr<ProofVerifier> proof_verifier);
+  QuicClient(QuicSocketAddress server_address,
+             const QuicServerId& server_id,
+             const ParsedQuicVersionVector& supported_versions,
+             const QuicConfig& config,
+             QuicEpollServer* epoll_server,
+             std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
+             std::unique_ptr<ProofVerifier> proof_verifier,
+             std::unique_ptr<SessionCache> session_cache);
+  QuicClient(const QuicClient&) = delete;
+  QuicClient& operator=(const QuicClient&) = delete;
+
+  ~QuicClient() override;
+
+  std::unique_ptr<QuicSession> CreateQuicClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection) override;
+
+  // Exposed for the quic client test.
+  int GetLatestFD() const { return epoll_network_helper()->GetLatestFD(); }
+
+  QuicClientEpollNetworkHelper* epoll_network_helper();
+  const QuicClientEpollNetworkHelper* epoll_network_helper() const;
+
+ private:
+  friend class test::QuicClientPeer;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_H_
diff --git a/quiche/quic/tools/quic_client_base.cc b/quiche/quic/tools/quic_client_base.cc
new file mode 100644
index 0000000..8cabb60
--- /dev/null
+++ b/quiche/quic/tools/quic_client_base.cc
@@ -0,0 +1,514 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_client_base.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+// A path context which owns the writer.
+class QUIC_EXPORT_PRIVATE PathMigrationContext
+    : public QuicPathValidationContext {
+ public:
+  PathMigrationContext(std::unique_ptr<QuicPacketWriter> writer,
+                       const QuicSocketAddress& self_address,
+                       const QuicSocketAddress& peer_address)
+      : QuicPathValidationContext(self_address, peer_address),
+        alternative_writer_(std::move(writer)) {}
+
+  QuicPacketWriter* WriterToUse() override { return alternative_writer_.get(); }
+
+  QuicPacketWriter* ReleaseWriter() { return alternative_writer_.release(); }
+
+ private:
+  std::unique_ptr<QuicPacketWriter> alternative_writer_;
+};
+
+// Implements the basic feature of a result delegate for path validation for
+// connection migration. If the validation succeeds, migrate to the alternative
+// path. Otherwise, stay on the current path.
+class QuicClientSocketMigrationValidationResultDelegate
+    : public QuicPathValidator::ResultDelegate {
+ public:
+  QuicClientSocketMigrationValidationResultDelegate(QuicClientBase* client)
+      : QuicPathValidator::ResultDelegate(), client_(client) {}
+
+  // QuicPathValidator::ResultDelegate
+  // Overridden to start migration and takes the ownership of the writer in the
+  // context.
+  void OnPathValidationSuccess(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    QUIC_DLOG(INFO) << "Successfully validated path from " << *context
+                    << ". Migrate to it now.";
+    auto migration_context = std::unique_ptr<PathMigrationContext>(
+        static_cast<PathMigrationContext*>(context.release()));
+    client_->session()->MigratePath(
+        migration_context->self_address(), migration_context->peer_address(),
+        migration_context->WriterToUse(), /*owns_writer=*/false);
+    QUICHE_DCHECK(migration_context->WriterToUse() != nullptr);
+    // Hand the ownership of the alternative writer to the client.
+    client_->set_writer(migration_context->ReleaseWriter());
+  }
+
+  void OnPathValidationFailure(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    QUIC_LOG(WARNING) << "Fail to validate path " << *context
+                      << ", stop migrating.";
+    client_->session()->connection()->OnPathValidationFailureAtClient();
+  }
+
+ private:
+  QuicClientBase* client_;
+};
+
+QuicClientBase::NetworkHelper::~NetworkHelper() = default;
+
+QuicClientBase::QuicClientBase(
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicConfig& config,
+    QuicConnectionHelperInterface* helper,
+    QuicAlarmFactory* alarm_factory,
+    std::unique_ptr<NetworkHelper> network_helper,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : server_id_(server_id),
+      initialized_(false),
+      local_port_(0),
+      config_(config),
+      crypto_config_(std::move(proof_verifier), std::move(session_cache)),
+      helper_(helper),
+      alarm_factory_(alarm_factory),
+      supported_versions_(supported_versions),
+      initial_max_packet_length_(0),
+      num_sent_client_hellos_(0),
+      connection_error_(QUIC_NO_ERROR),
+      connected_or_attempting_connect_(false),
+      network_helper_(std::move(network_helper)),
+      connection_debug_visitor_(nullptr),
+      server_connection_id_length_(kQuicDefaultConnectionIdLength),
+      client_connection_id_length_(0) {}
+
+QuicClientBase::~QuicClientBase() = default;
+
+bool QuicClientBase::Initialize() {
+  num_sent_client_hellos_ = 0;
+  connection_error_ = QUIC_NO_ERROR;
+  connected_or_attempting_connect_ = false;
+
+  // If an initial flow control window has not explicitly been set, then use the
+  // same values that Chrome uses.
+  const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024;  // 15 MB
+  const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024;    //  6 MB
+  if (config()->GetInitialStreamFlowControlWindowToSend() ==
+      kDefaultFlowControlSendWindow) {
+    config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize);
+  }
+  if (config()->GetInitialSessionFlowControlWindowToSend() ==
+      kDefaultFlowControlSendWindow) {
+    config()->SetInitialSessionFlowControlWindowToSend(
+        kSessionMaxRecvWindowSize);
+  }
+
+  if (!network_helper_->CreateUDPSocketAndBind(server_address_,
+                                               bind_to_address_, local_port_)) {
+    return false;
+  }
+
+  initialized_ = true;
+  return true;
+}
+
+bool QuicClientBase::Connect() {
+  // Attempt multiple connects until the maximum number of client hellos have
+  // been sent.
+  int num_attempts = 0;
+  while (!connected() &&
+         num_attempts <= QuicCryptoClientStream::kMaxClientHellos) {
+    StartConnect();
+    while (EncryptionBeingEstablished()) {
+      WaitForEvents();
+    }
+    ParsedQuicVersion version = UnsupportedQuicVersion();
+    if (session() != nullptr && !CanReconnectWithDifferentVersion(&version)) {
+      // We've successfully created a session but we're not connected, and we
+      // cannot reconnect with a different version.  Give up trying.
+      break;
+    }
+    num_attempts++;
+  }
+  if (session() == nullptr) {
+    QUIC_BUG(quic_bug_10906_1) << "Missing session after Connect";
+    return false;
+  }
+  return session()->connection()->connected();
+}
+
+void QuicClientBase::StartConnect() {
+  QUICHE_DCHECK(initialized_);
+  QUICHE_DCHECK(!connected());
+  QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
+  ParsedQuicVersion mutual_version = UnsupportedQuicVersion();
+  const bool can_reconnect_with_different_version =
+      CanReconnectWithDifferentVersion(&mutual_version);
+  if (connected_or_attempting_connect()) {
+    // Clear queued up data if client can not try to connect with a different
+    // version.
+    if (!can_reconnect_with_different_version) {
+      ClearDataToResend();
+    }
+    // Before we destroy the last session and create a new one, gather its stats
+    // and update the stats for the overall connection.
+    UpdateStats();
+  }
+
+  const quic::ParsedQuicVersionVector client_supported_versions =
+      can_reconnect_with_different_version
+          ? ParsedQuicVersionVector{mutual_version}
+          : supported_versions();
+
+  session_ = CreateQuicClientSession(
+      client_supported_versions,
+      new QuicConnection(GetNextConnectionId(), QuicSocketAddress(),
+                         server_address(), helper(), alarm_factory(), writer,
+                         /* owns_writer= */ false, Perspective::IS_CLIENT,
+                         client_supported_versions));
+  if (can_reconnect_with_different_version) {
+    session()->set_client_original_supported_versions(supported_versions());
+  }
+  if (connection_debug_visitor_ != nullptr) {
+    session()->connection()->set_debug_visitor(connection_debug_visitor_);
+  }
+  session()->connection()->set_client_connection_id(GetClientConnectionId());
+  if (initial_max_packet_length_ != 0) {
+    session()->connection()->SetMaxPacketLength(initial_max_packet_length_);
+  }
+  // Reset |writer()| after |session()| so that the old writer outlives the old
+  // session.
+  set_writer(writer);
+  InitializeSession();
+  if (can_reconnect_with_different_version) {
+    // This is a reconnect using server supported |mutual_version|.
+    session()->connection()->SetVersionNegotiated();
+  }
+  set_connected_or_attempting_connect(true);
+}
+
+void QuicClientBase::InitializeSession() {
+  session()->Initialize();
+}
+
+void QuicClientBase::Disconnect() {
+  QUICHE_DCHECK(initialized_);
+
+  initialized_ = false;
+  if (connected()) {
+    session()->connection()->CloseConnection(
+        QUIC_PEER_GOING_AWAY, "Client disconnecting",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+
+  ClearDataToResend();
+
+  network_helper_->CleanUpAllUDPSockets();
+}
+
+ProofVerifier* QuicClientBase::proof_verifier() const {
+  return crypto_config_.proof_verifier();
+}
+
+bool QuicClientBase::EncryptionBeingEstablished() {
+  return !session_->IsEncryptionEstablished() &&
+         session_->connection()->connected();
+}
+
+bool QuicClientBase::WaitForEvents() {
+  if (!connected()) {
+    QUIC_BUG(quic_bug_10906_2)
+        << "Cannot call WaitForEvents on non-connected client";
+    return false;
+  }
+
+  network_helper_->RunEventLoop();
+
+  QUICHE_DCHECK(session() != nullptr);
+  ParsedQuicVersion version = UnsupportedQuicVersion();
+  if (!connected() && CanReconnectWithDifferentVersion(&version)) {
+    QUIC_DLOG(INFO) << "Can reconnect with version: " << version
+                    << ", attempting to reconnect.";
+
+    Connect();
+  }
+
+  return HasActiveRequests();
+}
+
+bool QuicClientBase::MigrateSocket(const QuicIpAddress& new_host) {
+  return MigrateSocketWithSpecifiedPort(new_host, local_port_);
+}
+
+bool QuicClientBase::MigrateSocketWithSpecifiedPort(
+    const QuicIpAddress& new_host,
+    int port) {
+  if (!connected()) {
+    QUICHE_DVLOG(1)
+        << "MigrateSocketWithSpecifiedPort failed as connection has closed";
+    return false;
+  }
+
+  network_helper_->CleanUpAllUDPSockets();
+  std::unique_ptr<QuicPacketWriter> writer =
+      CreateWriterForNewNetwork(new_host, port);
+  if (writer == nullptr) {
+    QUICHE_DVLOG(1)
+        << "MigrateSocketWithSpecifiedPort failed from writer creation";
+    return false;
+  }
+  if (!session()->MigratePath(network_helper_->GetLatestClientAddress(),
+                              session()->connection()->peer_address(),
+                              writer.get(), false)) {
+    QUICHE_DVLOG(1)
+        << "MigrateSocketWithSpecifiedPort failed from session()->MigratePath";
+    return false;
+  }
+  set_writer(writer.release());
+  return true;
+}
+
+bool QuicClientBase::ValidateAndMigrateSocket(const QuicIpAddress& new_host) {
+  QUICHE_DCHECK(VersionHasIetfQuicFrames(
+                    session_->connection()->version().transport_version) &&
+                session_->connection()->use_path_validator());
+  if (!connected()) {
+    return false;
+  }
+
+  std::unique_ptr<QuicPacketWriter> writer =
+      CreateWriterForNewNetwork(new_host, local_port_);
+  if (writer == nullptr) {
+    return false;
+  }
+  // Asynchronously start migration.
+  session_->ValidatePath(
+      std::make_unique<PathMigrationContext>(
+          std::move(writer), network_helper_->GetLatestClientAddress(),
+          session_->peer_address()),
+      std::make_unique<QuicClientSocketMigrationValidationResultDelegate>(
+          this));
+  return true;
+}
+
+std::unique_ptr<QuicPacketWriter> QuicClientBase::CreateWriterForNewNetwork(
+    const QuicIpAddress& new_host,
+    int port) {
+  set_bind_to_address(new_host);
+  set_local_port(port);
+  if (!network_helper_->CreateUDPSocketAndBind(server_address_,
+                                               bind_to_address_, port)) {
+    return nullptr;
+  }
+
+  QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
+  QUIC_LOG_IF(WARNING, writer == writer_.get())
+      << "The new writer is wrapped in the same wrapper as the old one, thus "
+         "appearing to have the same address as the old one.";
+  return std::unique_ptr<QuicPacketWriter>(writer);
+}
+
+bool QuicClientBase::ChangeEphemeralPort() {
+  auto current_host = network_helper_->GetLatestClientAddress().host();
+  return MigrateSocketWithSpecifiedPort(current_host, 0 /*any ephemeral port*/);
+}
+
+QuicSession* QuicClientBase::session() {
+  return session_.get();
+}
+
+const QuicSession* QuicClientBase::session() const {
+  return session_.get();
+}
+
+QuicClientBase::NetworkHelper* QuicClientBase::network_helper() {
+  return network_helper_.get();
+}
+
+const QuicClientBase::NetworkHelper* QuicClientBase::network_helper() const {
+  return network_helper_.get();
+}
+
+void QuicClientBase::WaitForStreamToClose(QuicStreamId id) {
+  if (!connected()) {
+    QUIC_BUG(quic_bug_10906_3)
+        << "Cannot WaitForStreamToClose on non-connected client";
+    return;
+  }
+
+  while (connected() && !session_->IsClosedStream(id)) {
+    WaitForEvents();
+  }
+}
+
+bool QuicClientBase::WaitForOneRttKeysAvailable() {
+  if (!connected()) {
+    QUIC_BUG(quic_bug_10906_4)
+        << "Cannot WaitForOneRttKeysAvailable on non-connected client";
+    return false;
+  }
+
+  while (connected() && !session_->OneRttKeysAvailable()) {
+    WaitForEvents();
+  }
+
+  // If the handshake fails due to a timeout, the connection will be closed.
+  QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
+  return connected();
+}
+
+bool QuicClientBase::WaitForHandshakeConfirmed() {
+  if (!session_->connection()->version().UsesTls()) {
+    return WaitForOneRttKeysAvailable();
+  }
+  // Otherwise, wait for receipt of HANDSHAKE_DONE frame.
+  while (connected() && session_->GetHandshakeState() < HANDSHAKE_CONFIRMED) {
+    WaitForEvents();
+  }
+
+  // If the handshake fails due to a timeout, the connection will be closed.
+  QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
+  return connected();
+}
+
+bool QuicClientBase::connected() const {
+  return session_.get() && session_->connection() &&
+         session_->connection()->connected();
+}
+
+bool QuicClientBase::goaway_received() const {
+  return session_ != nullptr && session_->transport_goaway_received();
+}
+
+int QuicClientBase::GetNumSentClientHellos() {
+  // If we are not actively attempting to connect, the session object
+  // corresponds to the previous connection and should not be used.
+  const int current_session_hellos = !connected_or_attempting_connect_
+                                         ? 0
+                                         : GetNumSentClientHellosFromSession();
+  return num_sent_client_hellos_ + current_session_hellos;
+}
+
+void QuicClientBase::UpdateStats() {
+  num_sent_client_hellos_ += GetNumSentClientHellosFromSession();
+}
+
+int QuicClientBase::GetNumReceivedServerConfigUpdates() {
+  // If we are not actively attempting to connect, the session object
+  // corresponds to the previous connection and should not be used.
+  return !connected_or_attempting_connect_
+             ? 0
+             : GetNumReceivedServerConfigUpdatesFromSession();
+}
+
+QuicErrorCode QuicClientBase::connection_error() const {
+  // Return the high-level error if there was one.  Otherwise, return the
+  // connection error from the last session.
+  if (connection_error_ != QUIC_NO_ERROR) {
+    return connection_error_;
+  }
+  if (session_ == nullptr) {
+    return QUIC_NO_ERROR;
+  }
+  return session_->error();
+}
+
+QuicConnectionId QuicClientBase::GetNextConnectionId() {
+  return GenerateNewConnectionId();
+}
+
+QuicConnectionId QuicClientBase::GenerateNewConnectionId() {
+  return QuicUtils::CreateRandomConnectionId(server_connection_id_length_);
+}
+
+QuicConnectionId QuicClientBase::GetClientConnectionId() {
+  return QuicUtils::CreateRandomConnectionId(client_connection_id_length_);
+}
+
+bool QuicClientBase::CanReconnectWithDifferentVersion(
+    ParsedQuicVersion* version) const {
+  if (session_ == nullptr || session_->connection() == nullptr ||
+      session_->error() != QUIC_INVALID_VERSION) {
+    return false;
+  }
+
+  const auto& server_supported_versions =
+      session_->connection()->server_supported_versions();
+  if (server_supported_versions.empty()) {
+    return false;
+  }
+
+  for (const auto& client_version : supported_versions_) {
+    if (std::find(server_supported_versions.begin(),
+                  server_supported_versions.end(),
+                  client_version) != server_supported_versions.end()) {
+      *version = client_version;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicClientBase::HasPendingPathValidation() {
+  return session()->HasPendingPathValidation();
+}
+
+class ValidationResultDelegate : public QuicPathValidator::ResultDelegate {
+ public:
+  ValidationResultDelegate(QuicClientBase* client)
+      : QuicPathValidator::ResultDelegate(), client_(client) {}
+
+  void OnPathValidationSuccess(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    QUIC_DLOG(INFO) << "Successfully validated path from " << *context;
+    client_->AddValidatedPath(std::move(context));
+  }
+  void OnPathValidationFailure(
+      std::unique_ptr<QuicPathValidationContext> context) override {
+    QUIC_LOG(WARNING) << "Fail to validate path " << *context
+                      << ", stop migrating.";
+    client_->session()->connection()->OnPathValidationFailureAtClient();
+  }
+
+ private:
+  QuicClientBase* client_;
+};
+
+void QuicClientBase::ValidateNewNetwork(const QuicIpAddress& host) {
+  std::unique_ptr<QuicPacketWriter> writer =
+      CreateWriterForNewNetwork(host, local_port_);
+  auto result_delegate = std::make_unique<ValidationResultDelegate>(this);
+  if (writer == nullptr) {
+    result_delegate->OnPathValidationFailure(
+        std::make_unique<PathMigrationContext>(
+            nullptr, network_helper_->GetLatestClientAddress(),
+            session_->peer_address()));
+    return;
+  }
+  session()->ValidatePath(
+      std::make_unique<PathMigrationContext>(
+          std::move(writer), network_helper_->GetLatestClientAddress(),
+          session_->peer_address()),
+      std::move(result_delegate));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_client_base.h b/quiche/quic/tools/quic_client_base.h
new file mode 100644
index 0000000..9b568eb
--- /dev/null
+++ b/quiche/quic/tools/quic_client_base.h
@@ -0,0 +1,408 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A base class for the toy client, which connects to a specified port and sends
+// QUIC request to that endpoint.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
+#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+class ProofVerifier;
+class QuicServerId;
+class SessionCache;
+
+// QuicClientBase handles establishing a connection to the passed in
+// server id, including ensuring that it supports the passed in versions
+// and config.
+// Subclasses derived from this class are responsible for creating the
+// actual QuicSession instance, as well as defining functions that
+// create and run the underlying network transport.
+class QuicClientBase {
+ public:
+  // An interface to various network events that the QuicClient will need to
+  // interact with.
+  class NetworkHelper {
+   public:
+    virtual ~NetworkHelper();
+
+    // Runs one iteration of the event loop.
+    virtual void RunEventLoop() = 0;
+
+    // Used during initialization: creates the UDP socket FD, sets socket
+    // options, and binds the socket to our address.
+    virtual bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
+                                        QuicIpAddress bind_to_address,
+                                        int bind_to_port) = 0;
+
+    // Unregister and close all open UDP sockets.
+    virtual void CleanUpAllUDPSockets() = 0;
+
+    // If the client has at least one UDP socket, return address of the latest
+    // created one. Otherwise, return an empty socket address.
+    virtual QuicSocketAddress GetLatestClientAddress() const = 0;
+
+    // Creates a packet writer to be used for the next connection.
+    virtual QuicPacketWriter* CreateQuicPacketWriter() = 0;
+  };
+
+  QuicClientBase(const QuicServerId& server_id,
+                 const ParsedQuicVersionVector& supported_versions,
+                 const QuicConfig& config,
+                 QuicConnectionHelperInterface* helper,
+                 QuicAlarmFactory* alarm_factory,
+                 std::unique_ptr<NetworkHelper> network_helper,
+                 std::unique_ptr<ProofVerifier> proof_verifier,
+                 std::unique_ptr<SessionCache> session_cache);
+  QuicClientBase(const QuicClientBase&) = delete;
+  QuicClientBase& operator=(const QuicClientBase&) = delete;
+
+  virtual ~QuicClientBase();
+
+  // Initializes the client to create a connection. Should be called exactly
+  // once before calling StartConnect or Connect. Returns true if the
+  // initialization succeeds, false otherwise.
+  virtual bool Initialize();
+
+  // "Connect" to the QUIC server, including performing synchronous crypto
+  // handshake.
+  bool Connect();
+
+  // Start the crypto handshake.  This can be done in place of the synchronous
+  // Connect(), but callers are responsible for making sure the crypto handshake
+  // completes.
+  void StartConnect();
+
+  // Calls session()->Initialize(). Subclasses may override this if any extra
+  // initialization needs to be done. Subclasses should expect that session()
+  // is non-null and valid.
+  virtual void InitializeSession();
+
+  // Disconnects from the QUIC server.
+  void Disconnect();
+
+  // Returns true if the crypto handshake has yet to establish encryption.
+  // Returns false if encryption is active (even if the server hasn't confirmed
+  // the handshake) or if the connection has been closed.
+  bool EncryptionBeingEstablished();
+
+  // Wait for events until the stream with the given ID is closed.
+  void WaitForStreamToClose(QuicStreamId id);
+
+  // Wait for 1-RTT keys become available.
+  // Returns true once 1-RTT keys are available, false otherwise.
+  ABSL_MUST_USE_RESULT bool WaitForOneRttKeysAvailable();
+
+  // Wait for handshake state proceeds to HANDSHAKE_CONFIRMED.
+  // In QUIC crypto, this does the same as WaitForOneRttKeysAvailable, while in
+  // TLS, this waits for HANDSHAKE_DONE frame is received.
+  ABSL_MUST_USE_RESULT bool WaitForHandshakeConfirmed();
+
+  // Wait up to 50ms, and handle any events which occur.
+  // Returns true if there are any outstanding requests.
+  bool WaitForEvents();
+
+  // Migrate to a new socket (new_host) during an active connection.
+  bool MigrateSocket(const QuicIpAddress& new_host);
+
+  // Migrate to a new socket (new_host, port) during an active connection.
+  bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
+
+  // Validate the new socket and migrate to it if the validation succeeds.
+  // Otherwise stay on the current socket. Return true if the validation has
+  // started.
+  bool ValidateAndMigrateSocket(const QuicIpAddress& new_host);
+
+  // Open a new socket to change to a new ephemeral port.
+  bool ChangeEphemeralPort();
+
+  QuicSession* session();
+  const QuicSession* session() const;
+
+  bool connected() const;
+  virtual bool goaway_received() const;
+
+  const QuicServerId& server_id() const { return server_id_; }
+
+  // This should only be set before the initial Connect()
+  void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; }
+
+  void SetUserAgentID(const std::string& user_agent_id) {
+    crypto_config_.set_user_agent_id(user_agent_id);
+  }
+
+  void SetTlsSignatureAlgorithms(std::string signature_algorithms) {
+    crypto_config_.set_tls_signature_algorithms(
+        std::move(signature_algorithms));
+  }
+
+  const ParsedQuicVersionVector& supported_versions() const {
+    return supported_versions_;
+  }
+
+  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+    supported_versions_ = versions;
+  }
+
+  QuicConfig* config() { return &config_; }
+
+  QuicCryptoClientConfig* crypto_config() { return &crypto_config_; }
+
+  // Change the initial maximum packet size of the connection.  Has to be called
+  // before Connect()/StartConnect() in order to have any effect.
+  void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) {
+    initial_max_packet_length_ = initial_max_packet_length;
+  }
+
+  // The number of client hellos sent.
+  int GetNumSentClientHellos();
+
+  // Returns true if early data (0-RTT data) was sent and the server accepted
+  // it.
+  virtual bool EarlyDataAccepted() = 0;
+
+  // Returns true if the handshake was delayed one round trip by the server
+  // because the server wanted proof the client controls its source address
+  // before progressing further. In Google QUIC, this would be due to an
+  // inchoate REJ in the QUIC Crypto handshake; in IETF QUIC this would be due
+  // to a Retry packet.
+  // TODO(nharper): Consider a better name for this method.
+  virtual bool ReceivedInchoateReject() = 0;
+
+  // Gather the stats for the last session and update the stats for the overall
+  // connection.
+  void UpdateStats();
+
+  // The number of server config updates received.
+  int GetNumReceivedServerConfigUpdates();
+
+  // Returns any errors that occurred at the connection-level.
+  QuicErrorCode connection_error() const;
+  void set_connection_error(QuicErrorCode connection_error) {
+    connection_error_ = connection_error;
+  }
+
+  bool connected_or_attempting_connect() const {
+    return connected_or_attempting_connect_;
+  }
+  void set_connected_or_attempting_connect(
+      bool connected_or_attempting_connect) {
+    connected_or_attempting_connect_ = connected_or_attempting_connect;
+  }
+
+  QuicPacketWriter* writer() { return writer_.get(); }
+  void set_writer(QuicPacketWriter* writer) {
+    if (writer_.get() != writer) {
+      writer_.reset(writer);
+    }
+  }
+
+  void reset_writer() { writer_.reset(); }
+
+  ProofVerifier* proof_verifier() const;
+
+  void set_bind_to_address(QuicIpAddress address) {
+    bind_to_address_ = address;
+  }
+
+  QuicIpAddress bind_to_address() const { return bind_to_address_; }
+
+  void set_local_port(int local_port) { local_port_ = local_port; }
+
+  int local_port() const { return local_port_; }
+
+  const QuicSocketAddress& server_address() const { return server_address_; }
+
+  void set_server_address(const QuicSocketAddress& server_address) {
+    server_address_ = server_address;
+  }
+
+  QuicConnectionHelperInterface* helper() { return helper_.get(); }
+
+  NetworkHelper* network_helper();
+  const NetworkHelper* network_helper() const;
+
+  bool initialized() const { return initialized_; }
+
+  void SetPreSharedKey(absl::string_view key) {
+    crypto_config_.set_pre_shared_key(key);
+  }
+
+  void set_connection_debug_visitor(
+      QuicConnectionDebugVisitor* connection_debug_visitor) {
+    connection_debug_visitor_ = connection_debug_visitor;
+  }
+
+  void set_server_connection_id_length(uint8_t server_connection_id_length) {
+    server_connection_id_length_ = server_connection_id_length;
+  }
+
+  void set_client_connection_id_length(uint8_t client_connection_id_length) {
+    client_connection_id_length_ = client_connection_id_length;
+  }
+
+  bool HasPendingPathValidation();
+
+  void ValidateNewNetwork(const QuicIpAddress& host);
+
+  void AddValidatedPath(std::unique_ptr<QuicPathValidationContext> context) {
+    validated_paths_.push_back(std::move(context));
+  }
+
+  const std::vector<std::unique_ptr<QuicPathValidationContext>>&
+  validated_paths() const {
+    return validated_paths_;
+  }
+
+ protected:
+  // TODO(rch): Move GetNumSentClientHellosFromSession and
+  // GetNumReceivedServerConfigUpdatesFromSession into a new/better
+  // QuicSpdyClientSession class. The current inherits dependencies from
+  // Spdy. When that happens this class and all its subclasses should
+  // work with QuicSpdyClientSession instead of QuicSession.
+  // That will obviate the need for the pure virtual functions below.
+
+  // Extract the number of sent client hellos from the session.
+  virtual int GetNumSentClientHellosFromSession() = 0;
+
+  // The number of server config updates received.
+  virtual int GetNumReceivedServerConfigUpdatesFromSession() = 0;
+
+  // If this client supports buffering data, resend it.
+  virtual void ResendSavedData() = 0;
+
+  // If this client supports buffering data, clear it.
+  virtual void ClearDataToResend() = 0;
+
+  // Takes ownership of |connection|. If you override this function,
+  // you probably want to call ResetSession() in your destructor.
+  // TODO(rch): Change the connection parameter to take in a
+  // std::unique_ptr<QuicConnection> instead.
+  virtual std::unique_ptr<QuicSession> CreateQuicClientSession(
+      const ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection) = 0;
+
+  // Generates the next ConnectionId for |server_id_|.  By default, if the
+  // cached server config contains a server-designated ID, that ID will be
+  // returned.  Otherwise, the next random ID will be returned.
+  QuicConnectionId GetNextConnectionId();
+
+  // Generates a new, random connection ID (as opposed to a server-designated
+  // connection ID).
+  virtual QuicConnectionId GenerateNewConnectionId();
+
+  // Returns the client connection ID to use.
+  virtual QuicConnectionId GetClientConnectionId();
+
+  QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
+
+  // Subclasses may need to explicitly clear the session on destruction
+  // if they create it with objects that will be destroyed before this is.
+  // You probably want to call this if you override CreateQuicSpdyClientSession.
+  void ResetSession() { session_.reset(); }
+
+  // Returns true if the corresponding of this client has active requests.
+  virtual bool HasActiveRequests() = 0;
+
+ private:
+  // Returns true and set |version| if client can reconnect with a different
+  // version.
+  bool CanReconnectWithDifferentVersion(ParsedQuicVersion* version) const;
+
+  std::unique_ptr<QuicPacketWriter> CreateWriterForNewNetwork(
+      const QuicIpAddress& new_host,
+      int port);
+
+  // |server_id_| is a tuple (hostname, port, is_https) of the server.
+  QuicServerId server_id_;
+
+  // Tracks if the client is initialized to connect.
+  bool initialized_;
+
+  // Address of the server.
+  QuicSocketAddress server_address_;
+
+  // If initialized, the address to bind to.
+  QuicIpAddress bind_to_address_;
+
+  // Local port to bind to. Initialize to 0.
+  int local_port_;
+
+  // config_ and crypto_config_ contain configuration and cached state about
+  // servers.
+  QuicConfig config_;
+  QuicCryptoClientConfig crypto_config_;
+
+  // Helper to be used by created connections. Must outlive |session_|.
+  std::unique_ptr<QuicConnectionHelperInterface> helper_;
+
+  // Alarm factory to be used by created connections. Must outlive |session_|.
+  std::unique_ptr<QuicAlarmFactory> alarm_factory_;
+
+  // Writer used to actually send packets to the wire. Must outlive |session_|.
+  std::unique_ptr<QuicPacketWriter> writer_;
+
+  // Session which manages streams.
+  std::unique_ptr<QuicSession> session_;
+
+  // This vector contains QUIC versions which we currently support.
+  // This should be ordered such that the highest supported version is the first
+  // element, with subsequent elements in descending order (versions can be
+  // skipped as necessary). We will always pick supported_versions_[0] as the
+  // initial version to use.
+  ParsedQuicVersionVector supported_versions_;
+
+  // The initial value of maximum packet size of the connection.  If set to
+  // zero, the default is used.
+  QuicByteCount initial_max_packet_length_;
+
+  // The number of hellos sent during the current/latest connection.
+  int num_sent_client_hellos_;
+
+  // Used to store any errors that occurred with the overall connection (as
+  // opposed to that associated with the last session object).
+  QuicErrorCode connection_error_;
+
+  // True when the client is attempting to connect.  Set to false between a call
+  // to Disconnect() and the subsequent call to StartConnect().  When
+  // connected_or_attempting_connect_ is false, the session object corresponds
+  // to the previous client-level connection.
+  bool connected_or_attempting_connect_;
+
+  // The network helper used to create sockets and manage the event loop.
+  // Not owned by this class.
+  std::unique_ptr<NetworkHelper> network_helper_;
+
+  // The debug visitor set on the connection right after it is constructed.
+  // Not owned, must be valid for the lifetime of the QuicClientBase instance.
+  QuicConnectionDebugVisitor* connection_debug_visitor_;
+
+  // GenerateNewConnectionId creates a random connection ID of this length.
+  // Defaults to 8.
+  uint8_t server_connection_id_length_;
+
+  // GetClientConnectionId creates a random connection ID of this length.
+  // Defaults to 0.
+  uint8_t client_connection_id_length_;
+
+  // Stores validated paths.
+  std::vector<std::unique_ptr<QuicPathValidationContext>> validated_paths_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_BASE_H_
diff --git a/quiche/quic/tools/quic_client_bin.cc b/quiche/quic/tools/quic_client_bin.cc
new file mode 100644
index 0000000..ad2acf9
--- /dev/null
+++ b/quiche/quic/tools/quic_client_bin.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A binary wrapper for QuicClient.
+// Connects to a host using QUIC, sends a request to the provided URL, and
+// displays the response.
+//
+// Some usage examples:
+//
+// Standard request/response:
+//   quic_client www.google.com
+//   quic_client www.google.com --quiet
+//   quic_client www.google.com --port=443
+//
+// Use a specific version:
+//   quic_client www.google.com --quic_version=23
+//
+// Send a POST instead of a GET:
+//   quic_client www.google.com --body="this is a POST body"
+//
+// Append additional headers to the request:
+//   quic_client www.google.com --headers="header-a: 1234; header-b: 5678"
+//
+// Connect to a host different to the URL being requested:
+//   quic_client mail.google.com --host=www.google.com
+//
+// Connect to a specific IP:
+//   IP=`dig www.google.com +short | head -1`
+//   quic_client www.google.com --host=${IP}
+//
+// Send repeated requests and change ephemeral port between requests
+//   quic_client www.google.com --num_requests=10
+//
+// Try to connect to a host which does not speak QUIC:
+//   quic_client www.example.com
+//
+// This tool is available as a built binary at:
+// /google/data/ro/teams/quic/tools/quic_client
+// After submitting changes to this file, you will need to follow the
+// instructions at go/quic_client_binary_update
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/tools/quic_epoll_client_factory.h"
+#include "quiche/quic/tools/quic_toy_client.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_system_event_loop.h"
+
+int main(int argc, char* argv[]) {
+  quiche::QuicheSystemEventLoop event_loop("quic_client");
+  const char* usage = "Usage: quic_client [options] <url>";
+
+  // All non-flag arguments should be interpreted as URLs to fetch.
+  std::vector<std::string> urls =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (urls.size() != 1) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    exit(0);
+  }
+
+  quic::QuicEpollClientFactory factory;
+  quic::QuicToyClient client(&factory);
+  return client.SendRequestsAndPrintResponses(urls);
+}
diff --git a/quiche/quic/tools/quic_client_epoll_network_helper.cc b/quiche/quic/tools/quic_client_epoll_network_helper.cc
new file mode 100644
index 0000000..f42c4ed
--- /dev/null
+++ b/quiche/quic/tools/quic_client_epoll_network_helper.cc
@@ -0,0 +1,227 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_client_epoll_network_helper.h"
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_system_event_loop.h"
+
+namespace quic {
+
+namespace {
+const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
+}  // namespace
+
+QuicClientEpollNetworkHelper::QuicClientEpollNetworkHelper(
+    QuicEpollServer* epoll_server,
+    QuicClientBase* client)
+    : epoll_server_(epoll_server),
+      packets_dropped_(0),
+      overflow_supported_(false),
+      packet_reader_(new QuicPacketReader()),
+      client_(client),
+      max_reads_per_epoll_loop_(std::numeric_limits<int>::max()) {}
+
+QuicClientEpollNetworkHelper::~QuicClientEpollNetworkHelper() {
+  if (client_->connected()) {
+    client_->session()->connection()->CloseConnection(
+        QUIC_PEER_GOING_AWAY, "Client being torn down",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+  }
+
+  CleanUpAllUDPSockets();
+}
+
+std::string QuicClientEpollNetworkHelper::Name() const {
+  return "QuicClientEpollNetworkHelper";
+}
+
+bool QuicClientEpollNetworkHelper::CreateUDPSocketAndBind(
+    QuicSocketAddress server_address,
+    QuicIpAddress bind_to_address,
+    int bind_to_port) {
+  epoll_server_->set_timeout_in_us(50 * 1000);
+
+  int fd = CreateUDPSocket(server_address, &overflow_supported_);
+  if (fd < 0) {
+    return false;
+  }
+
+  QuicSocketAddress client_address;
+  if (bind_to_address.IsInitialized()) {
+    client_address = QuicSocketAddress(bind_to_address, client_->local_port());
+  } else if (server_address.host().address_family() == IpAddressFamily::IP_V4) {
+    client_address = QuicSocketAddress(QuicIpAddress::Any4(), bind_to_port);
+  } else {
+    client_address = QuicSocketAddress(QuicIpAddress::Any6(), bind_to_port);
+  }
+
+  // Some platforms expect that the addrlen given to bind() exactly matches the
+  // size of the associated protocol family's sockaddr struct.
+  // TODO(b/179430548): Revert this when affected platforms are updated to
+  // to support binding with an addrelen of sizeof(sockaddr_storage)
+  socklen_t addrlen;
+  switch (client_address.host().address_family()) {
+    case IpAddressFamily::IP_V4:
+      addrlen = sizeof(sockaddr_in);
+      break;
+    case IpAddressFamily::IP_V6:
+      addrlen = sizeof(sockaddr_in6);
+      break;
+    case IpAddressFamily::IP_UNSPEC:
+      addrlen = 0;
+      break;
+  }
+
+  sockaddr_storage addr = client_address.generic_address();
+  int rc = bind(fd, reinterpret_cast<sockaddr*>(&addr), addrlen);
+  if (rc < 0) {
+    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno)
+                    << " bind_to_address:" << bind_to_address
+                    << ", bind_to_port:" << bind_to_port
+                    << ", client_address:" << client_address;
+    return false;
+  }
+
+  if (client_address.FromSocket(fd) != 0) {
+    QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
+                    << strerror(errno);
+  }
+
+  fd_address_map_[fd] = client_address;
+  epoll_server_->RegisterFD(fd, this, kEpollFlags);
+  return true;
+}
+
+void QuicClientEpollNetworkHelper::CleanUpUDPSocket(int fd) {
+  CleanUpUDPSocketImpl(fd);
+  fd_address_map_.erase(fd);
+}
+
+void QuicClientEpollNetworkHelper::CleanUpAllUDPSockets() {
+  for (std::pair<int, QuicSocketAddress> fd_address : fd_address_map_) {
+    CleanUpUDPSocketImpl(fd_address.first);
+  }
+  fd_address_map_.clear();
+}
+
+void QuicClientEpollNetworkHelper::CleanUpUDPSocketImpl(int fd) {
+  if (fd > -1) {
+    epoll_server_->UnregisterFD(fd);
+    int rc = close(fd);
+    QUICHE_DCHECK_EQ(0, rc);
+  }
+}
+
+void QuicClientEpollNetworkHelper::RunEventLoop() {
+  quiche::QuicheRunSystemEventLoopIteration();
+  epoll_server_->WaitForEventsAndExecuteCallbacks();
+}
+
+void QuicClientEpollNetworkHelper::OnRegistration(QuicEpollServer* /*eps*/,
+                                                  int /*fd*/,
+                                                  int /*event_mask*/) {}
+void QuicClientEpollNetworkHelper::OnModification(int /*fd*/,
+                                                  int /*event_mask*/) {}
+void QuicClientEpollNetworkHelper::OnUnregistration(int /*fd*/,
+                                                    bool /*replaced*/) {}
+void QuicClientEpollNetworkHelper::OnShutdown(QuicEpollServer* /*eps*/,
+                                              int /*fd*/) {}
+
+void QuicClientEpollNetworkHelper::OnEvent(int fd, QuicEpollEvent* event) {
+  if (event->in_events & EPOLLIN) {
+    QUIC_DVLOG(1) << "Read packets on EPOLLIN";
+    int times_to_read = max_reads_per_epoll_loop_;
+    bool more_to_read = true;
+    QuicPacketCount packets_dropped = 0;
+    while (client_->connected() && more_to_read && times_to_read > 0) {
+      more_to_read = packet_reader_->ReadAndDispatchPackets(
+          fd, GetLatestClientAddress().port(), *client_->helper()->GetClock(),
+          this, overflow_supported_ ? &packets_dropped : nullptr);
+      --times_to_read;
+    }
+    if (packets_dropped_ < packets_dropped) {
+      QUIC_LOG(ERROR)
+          << packets_dropped - packets_dropped_
+          << " more packets are dropped in the socket receive buffer.";
+      packets_dropped_ = packets_dropped;
+    }
+    if (client_->connected() && more_to_read) {
+      event->out_ready_mask |= EPOLLIN;
+    }
+  }
+  if (client_->connected() && (event->in_events & EPOLLOUT)) {
+    client_->writer()->SetWritable();
+    client_->session()->connection()->OnCanWrite();
+  }
+  if (event->in_events & EPOLLERR) {
+    QUIC_DLOG(INFO) << "Epollerr";
+  }
+}
+
+QuicPacketWriter* QuicClientEpollNetworkHelper::CreateQuicPacketWriter() {
+  return new QuicDefaultPacketWriter(GetLatestFD());
+}
+
+void QuicClientEpollNetworkHelper::SetClientPort(int port) {
+  fd_address_map_.back().second =
+      QuicSocketAddress(GetLatestClientAddress().host(), port);
+}
+
+QuicSocketAddress QuicClientEpollNetworkHelper::GetLatestClientAddress() const {
+  if (fd_address_map_.empty()) {
+    return QuicSocketAddress();
+  }
+
+  return fd_address_map_.back().second;
+}
+
+int QuicClientEpollNetworkHelper::GetLatestFD() const {
+  if (fd_address_map_.empty()) {
+    return -1;
+  }
+
+  return fd_address_map_.back().first;
+}
+
+void QuicClientEpollNetworkHelper::ProcessPacket(
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address,
+    const QuicReceivedPacket& packet) {
+  client_->session()->ProcessUdpPacket(self_address, peer_address, packet);
+}
+
+int QuicClientEpollNetworkHelper::CreateUDPSocket(
+    QuicSocketAddress server_address,
+    bool* overflow_supported) {
+  QuicUdpSocketApi api;
+  int fd = api.Create(server_address.host().AddressFamilyToInt(),
+                      /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
+                      /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
+  if (fd < 0) {
+    return fd;
+  }
+
+  *overflow_supported = api.EnableDroppedPacketCount(fd);
+  api.EnableReceiveTimestamp(fd);
+  return fd;
+}
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_client_epoll_network_helper.h b/quiche/quic/tools/quic_client_epoll_network_helper.h
new file mode 100644
index 0000000..637af45
--- /dev/null
+++ b/quiche/quic/tools/quic_client_epoll_network_helper.h
@@ -0,0 +1,135 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// An implementation of the QuicClientBase::NetworkHelper
+// that is based off the epoll server.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_packet_reader.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/tools/quic_client_base.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+
+namespace quic {
+
+namespace test {
+class QuicClientPeer;
+}  // namespace test
+
+// An implementation of the QuicClientBase::NetworkHelper based off
+// the epoll server.
+class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
+                                     public QuicEpollCallbackInterface,
+                                     public ProcessPacketInterface {
+ public:
+  // Create a quic client, which will have events managed by an externally owned
+  // EpollServer.
+  QuicClientEpollNetworkHelper(QuicEpollServer* epoll_server,
+                               QuicClientBase* client);
+  QuicClientEpollNetworkHelper(const QuicClientEpollNetworkHelper&) = delete;
+  QuicClientEpollNetworkHelper& operator=(const QuicClientEpollNetworkHelper&) =
+      delete;
+
+  ~QuicClientEpollNetworkHelper() override;
+
+  // Return a name describing the class for use in debug/error reporting.
+  std::string Name() const override;
+
+  // From EpollCallbackInterface
+  void OnRegistration(QuicEpollServer* eps, int fd, int event_mask) override;
+  void OnModification(int fd, int event_mask) override;
+  void OnEvent(int fd, QuicEpollEvent* event) override;
+  // |fd_| can be unregistered without the client being disconnected. This
+  // happens in b3m QuicProber where we unregister |fd_| to feed in events to
+  // the client from the SelectServer.
+  void OnUnregistration(int fd, bool replaced) override;
+  void OnShutdown(QuicEpollServer* eps, int fd) override;
+
+  // From ProcessPacketInterface. This will be called for each received
+  // packet.
+  void ProcessPacket(const QuicSocketAddress& self_address,
+                     const QuicSocketAddress& peer_address,
+                     const QuicReceivedPacket& packet) override;
+
+  // From NetworkHelper.
+  void RunEventLoop() override;
+  bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
+                              QuicIpAddress bind_to_address,
+                              int bind_to_port) override;
+  void CleanUpAllUDPSockets() override;
+  QuicSocketAddress GetLatestClientAddress() const override;
+  QuicPacketWriter* CreateQuicPacketWriter() override;
+
+  // Accessors provided for convenience, not part of any interface.
+
+  QuicEpollServer* epoll_server() { return epoll_server_; }
+
+  const quiche::QuicheLinkedHashMap<int, QuicSocketAddress>& fd_address_map()
+      const {
+    return fd_address_map_;
+  }
+
+  // If the client has at least one UDP socket, return the latest created one.
+  // Otherwise, return -1.
+  int GetLatestFD() const;
+
+  // Create socket for connection to |server_address| with default socket
+  // options.
+  // Return fd index.
+  virtual int CreateUDPSocket(QuicSocketAddress server_address,
+                              bool* overflow_supported);
+
+  QuicClientBase* client() { return client_; }
+
+  void set_max_reads_per_epoll_loop(int num_reads) {
+    max_reads_per_epoll_loop_ = num_reads;
+  }
+  // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
+  // nothing.
+  void CleanUpUDPSocket(int fd);
+
+ private:
+  friend class test::QuicClientPeer;
+
+  // Used for testing.
+  void SetClientPort(int port);
+
+  // Actually clean up |fd|.
+  void CleanUpUDPSocketImpl(int fd);
+
+  // Listens for events on the client socket.
+  QuicEpollServer* epoll_server_;
+
+  // Map mapping created UDP sockets to their addresses. By using linked hash
+  // map, the order of socket creation can be recorded.
+  quiche::QuicheLinkedHashMap<int, QuicSocketAddress> fd_address_map_;
+
+  // If overflow_supported_ is true, this will be the number of packets dropped
+  // during the lifetime of the server.
+  QuicPacketCount packets_dropped_;
+
+  // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
+  // because the socket would otherwise overflow.
+  bool overflow_supported_;
+
+  // Point to a QuicPacketReader object on the heap. The reader allocates more
+  // space than allowed on the stack.
+  std::unique_ptr<QuicPacketReader> packet_reader_;
+
+  QuicClientBase* client_;
+
+  int max_reads_per_epoll_loop_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
diff --git a/quiche/quic/tools/quic_client_interop_test_bin.cc b/quiche/quic/tools/quic_client_interop_test_bin.cc
new file mode 100644
index 0000000..ece457f
--- /dev/null
+++ b/quiche/quic/tools/quic_client_interop_test_bin.cc
@@ -0,0 +1,467 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/tools/fake_proof_verifier.h"
+#include "quiche/quic/tools/quic_client.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_system_event_loop.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, host, "",
+                                "The IP or hostname to connect to.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_version, "",
+    "The QUIC version to use. Defaults to most recent IETF QUIC version.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
+
+namespace quic {
+
+enum class Feature {
+  // First row of features ("table stakes")
+  // A version negotiation response is elicited and acted on.
+  kVersionNegotiation,
+  // The handshake completes successfully.
+  kHandshake,
+  // Stream data is being exchanged and ACK'ed.
+  kStreamData,
+  // The connection close procedcure completes with a zero error code.
+  kConnectionClose,
+  // The connection was established using TLS resumption.
+  kResumption,
+  // 0-RTT data is being sent and acted on.
+  kZeroRtt,
+  // A RETRY packet was successfully processed.
+  kRetry,
+  // A handshake using a ClientHello that spans multiple packets completed
+  // successfully.
+  kQuantum,
+
+  // Second row of features (anything else protocol-related)
+  // We switched to a different port and the server migrated to it.
+  kRebinding,
+  // One endpoint can update keys and its peer responds correctly.
+  kKeyUpdate,
+
+  // Third row of features (H3 tests)
+  // An H3 transaction succeeded.
+  kHttp3,
+  // One or both endpoints insert entries into dynamic table and subsequenly
+  // reference them from header blocks.
+  kDynamicEntryReferenced,
+};
+
+char MatrixLetter(Feature f) {
+  switch (f) {
+    case Feature::kVersionNegotiation:
+      return 'V';
+    case Feature::kHandshake:
+      return 'H';
+    case Feature::kStreamData:
+      return 'D';
+    case Feature::kConnectionClose:
+      return 'C';
+    case Feature::kResumption:
+      return 'R';
+    case Feature::kZeroRtt:
+      return 'Z';
+    case Feature::kRetry:
+      return 'S';
+    case Feature::kQuantum:
+      return 'Q';
+    case Feature::kRebinding:
+      return 'B';
+    case Feature::kKeyUpdate:
+      return 'U';
+    case Feature::kHttp3:
+      return '3';
+    case Feature::kDynamicEntryReferenced:
+      return 'd';
+  }
+}
+
+class QuicClientInteropRunner : QuicConnectionDebugVisitor {
+ public:
+  QuicClientInteropRunner() {}
+
+  void InsertFeature(Feature feature) { features_.insert(feature); }
+
+  std::set<Feature> features() const { return features_; }
+
+  // Attempts a resumption using |client| by disconnecting and reconnecting. If
+  // resumption is successful, |features_| is modified to add
+  // Feature::kResumption to it, otherwise it is left unmodified.
+  void AttemptResumption(QuicClient* client, const std::string& authority);
+
+  void AttemptRequest(QuicSocketAddress addr,
+                      std::string authority,
+                      QuicServerId server_id,
+                      ParsedQuicVersion version,
+                      bool test_version_negotiation,
+                      bool attempt_rebind,
+                      bool attempt_multi_packet_chlo,
+                      bool attempt_key_update);
+
+  // Constructs a SpdyHeaderBlock containing the pseudo-headers needed to make a
+  // GET request to "/" on the hostname |authority|.
+  spdy::Http2HeaderBlock ConstructHeaderBlock(const std::string& authority);
+
+  // Sends an HTTP request represented by |header_block| using |client|.
+  void SendRequest(QuicClient* client,
+                   const spdy::Http2HeaderBlock& header_block);
+
+  void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
+    switch (frame.close_type) {
+      case GOOGLE_QUIC_CONNECTION_CLOSE:
+        QUIC_LOG(ERROR) << "Received unexpected GoogleQUIC connection close";
+        break;
+      case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+        if (frame.wire_error_code == NO_IETF_QUIC_ERROR) {
+          InsertFeature(Feature::kConnectionClose);
+        } else {
+          QUIC_LOG(ERROR) << "Received transport connection close "
+                          << QuicIetfTransportErrorCodeString(
+                                 static_cast<QuicIetfTransportErrorCodes>(
+                                     frame.wire_error_code));
+        }
+        break;
+      case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+        if (frame.wire_error_code == 0) {
+          InsertFeature(Feature::kConnectionClose);
+        } else {
+          QUIC_LOG(ERROR) << "Received application connection close "
+                          << frame.wire_error_code;
+        }
+        break;
+    }
+  }
+
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {
+    InsertFeature(Feature::kVersionNegotiation);
+  }
+
+ private:
+  std::set<Feature> features_;
+};
+
+void QuicClientInteropRunner::AttemptResumption(QuicClient* client,
+                                                const std::string& authority) {
+  client->Disconnect();
+  if (!client->Initialize()) {
+    QUIC_LOG(ERROR) << "Failed to reinitialize client";
+    return;
+  }
+  if (!client->Connect()) {
+    return;
+  }
+
+  bool zero_rtt_attempt = !client->session()->OneRttKeysAvailable();
+
+  spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority);
+  SendRequest(client, header_block);
+
+  if (!client->session()->OneRttKeysAvailable()) {
+    return;
+  }
+
+  if (static_cast<QuicCryptoClientStream*>(
+          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
+          ->IsResumption()) {
+    InsertFeature(Feature::kResumption);
+  }
+  if (static_cast<QuicCryptoClientStream*>(
+          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
+          ->EarlyDataAccepted() &&
+      zero_rtt_attempt && client->latest_response_code() != -1) {
+    InsertFeature(Feature::kZeroRtt);
+  }
+}
+
+void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
+                                             std::string authority,
+                                             QuicServerId server_id,
+                                             ParsedQuicVersion version,
+                                             bool test_version_negotiation,
+                                             bool attempt_rebind,
+                                             bool attempt_multi_packet_chlo,
+                                             bool attempt_key_update) {
+  ParsedQuicVersionVector versions = {version};
+  if (test_version_negotiation) {
+    versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
+  }
+
+  auto proof_verifier = std::make_unique<FakeProofVerifier>();
+  auto session_cache = std::make_unique<QuicClientSessionCache>();
+  QuicEpollServer epoll_server;
+  QuicEpollClock epoll_clock(&epoll_server);
+  QuicConfig config;
+  QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(20);
+  config.SetIdleNetworkTimeout(timeout);
+  if (attempt_multi_packet_chlo) {
+    // Make the ClientHello span multiple packets by adding a custom transport
+    // parameter.
+    constexpr auto kCustomParameter =
+        static_cast<TransportParameters::TransportParameterId>(0x173E);
+    std::string custom_value(2000, '?');
+    config.custom_transport_parameters_to_send()[kCustomParameter] =
+        custom_value;
+  }
+  auto client = std::make_unique<QuicClient>(
+      addr, server_id, versions, config, &epoll_server,
+      std::move(proof_verifier), std::move(session_cache));
+  client->set_connection_debug_visitor(this);
+  if (!client->Initialize()) {
+    QUIC_LOG(ERROR) << "Failed to initialize client";
+    return;
+  }
+  const bool connect_result = client->Connect();
+  QuicConnection* connection = client->session()->connection();
+  if (connection == nullptr) {
+    QUIC_LOG(ERROR) << "No QuicConnection object";
+    return;
+  }
+  QuicConnectionStats client_stats = connection->GetStats();
+  if (client_stats.retry_packet_processed) {
+    InsertFeature(Feature::kRetry);
+  }
+  if (test_version_negotiation && connection->version() == version) {
+    InsertFeature(Feature::kVersionNegotiation);
+  }
+  if (test_version_negotiation && !connect_result) {
+    // Failed to negotiate version, retry without version negotiation.
+    AttemptRequest(addr, authority, server_id, version,
+                   /*test_version_negotiation=*/false, attempt_rebind,
+                   attempt_multi_packet_chlo, attempt_key_update);
+    return;
+  }
+  if (!client->session()->OneRttKeysAvailable()) {
+    if (attempt_multi_packet_chlo) {
+      // Failed to handshake with multi-packet client hello, retry without it.
+      AttemptRequest(addr, authority, server_id, version,
+                     test_version_negotiation, attempt_rebind,
+                     /*attempt_multi_packet_chlo=*/false, attempt_key_update);
+      return;
+    }
+    return;
+  }
+  InsertFeature(Feature::kHandshake);
+  if (attempt_multi_packet_chlo) {
+    InsertFeature(Feature::kQuantum);
+  }
+
+  spdy::Http2HeaderBlock header_block = ConstructHeaderBlock(authority);
+  SendRequest(client.get(), header_block);
+
+  if (!client->connected()) {
+    return;
+  }
+
+  if (client->latest_response_code() != -1) {
+    InsertFeature(Feature::kHttp3);
+
+    if (client->client_session()->dynamic_table_entry_referenced()) {
+      InsertFeature(Feature::kDynamicEntryReferenced);
+    }
+
+    if (attempt_rebind) {
+      // Now make a second request after switching to a different client port.
+      if (client->ChangeEphemeralPort()) {
+        client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
+        if (!client->connected()) {
+          // Rebinding does not work, retry without attempting it.
+          AttemptRequest(addr, authority, server_id, version,
+                         test_version_negotiation, /*attempt_rebind=*/false,
+                         attempt_multi_packet_chlo, attempt_key_update);
+          return;
+        }
+        InsertFeature(Feature::kRebinding);
+
+        if (client->client_session()->dynamic_table_entry_referenced()) {
+          InsertFeature(Feature::kDynamicEntryReferenced);
+        }
+      } else {
+        QUIC_LOG(ERROR) << "Failed to change ephemeral port";
+      }
+    }
+
+    if (attempt_key_update) {
+      if (connection->IsKeyUpdateAllowed()) {
+        if (connection->InitiateKeyUpdate(
+                KeyUpdateReason::kLocalForInteropRunner)) {
+          client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
+          if (!client->connected()) {
+            // Key update does not work, retry without attempting it.
+            AttemptRequest(addr, authority, server_id, version,
+                           test_version_negotiation, attempt_rebind,
+                           attempt_multi_packet_chlo,
+                           /*attempt_key_update=*/false);
+            return;
+          }
+          InsertFeature(Feature::kKeyUpdate);
+        } else {
+          QUIC_LOG(ERROR) << "Failed to initiate key update";
+        }
+      } else {
+        QUIC_LOG(ERROR) << "Key update not allowed";
+      }
+    }
+  }
+
+  if (connection->connected()) {
+    connection->CloseConnection(
+        QUIC_NO_ERROR, "Graceful close",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    InsertFeature(Feature::kConnectionClose);
+  }
+
+  AttemptResumption(client.get(), authority);
+}
+
+spdy::Http2HeaderBlock QuicClientInteropRunner::ConstructHeaderBlock(
+    const std::string& authority) {
+  // Construct and send a request.
+  spdy::Http2HeaderBlock header_block;
+  header_block[":method"] = "GET";
+  header_block[":scheme"] = "https";
+  header_block[":authority"] = authority;
+  header_block[":path"] = "/";
+  return header_block;
+}
+
+void QuicClientInteropRunner::SendRequest(
+    QuicClient* client,
+    const spdy::Http2HeaderBlock& header_block) {
+  client->set_store_response(true);
+  client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
+
+  QuicConnection* connection = client->session()->connection();
+  if (connection == nullptr) {
+    QUIC_LOG(ERROR) << "No QuicConnection object";
+    return;
+  }
+  QuicConnectionStats client_stats = connection->GetStats();
+  QuicSentPacketManager* sent_packet_manager =
+      test::QuicConnectionPeer::GetSentPacketManager(connection);
+  const bool received_forward_secure_ack =
+      sent_packet_manager != nullptr &&
+      sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
+          .IsInitialized();
+  if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
+    InsertFeature(Feature::kStreamData);
+  }
+}
+
+std::set<Feature> ServerSupport(std::string dns_host,
+                                std::string url_host,
+                                int port,
+                                ParsedQuicVersion version) {
+  std::cout << "Attempting interop with version " << version << std::endl;
+
+  // Build the client, and try to connect.
+  QuicSocketAddress addr = tools::LookupAddress(dns_host, absl::StrCat(port));
+  if (!addr.IsInitialized()) {
+    QUIC_LOG(ERROR) << "Failed to resolve " << dns_host;
+    return std::set<Feature>();
+  }
+  QuicServerId server_id(url_host, port, false);
+  std::string authority = absl::StrCat(url_host, ":", port);
+
+  QuicClientInteropRunner runner;
+
+  runner.AttemptRequest(addr, authority, server_id, version,
+                        /*test_version_negotiation=*/true,
+                        /*attempt_rebind=*/true,
+                        /*attempt_multi_packet_chlo=*/true,
+                        /*attempt_key_update=*/true);
+
+  return runner.features();
+}
+
+}  // namespace quic
+
+int main(int argc, char* argv[]) {
+  quiche::QuicheSystemEventLoop event_loop("quic_client");
+  const char* usage = "Usage: quic_client_interop_test [options] [url]";
+
+  std::vector<std::string> args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (args.size() > 1) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    exit(1);
+  }
+  std::string dns_host = GetQuicFlag(FLAGS_host);
+  std::string url_host = "";
+  int port = GetQuicFlag(FLAGS_port);
+
+  if (!args.empty()) {
+    quic::QuicUrl url(args[0], "https");
+    url_host = url.host();
+    if (dns_host.empty()) {
+      dns_host = url_host;
+    }
+    if (port == 0) {
+      port = url.port();
+    }
+  }
+  if (port == 0) {
+    port = 443;
+  }
+  if (dns_host.empty()) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    exit(1);
+  }
+  if (url_host.empty()) {
+    url_host = dns_host;
+  }
+
+  // Pick QUIC version to use.
+  quic::QuicVersionInitializeSupportForIetfDraft();
+  quic::ParsedQuicVersion version = quic::UnsupportedQuicVersion();
+  std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
+  if (!quic_version_string.empty()) {
+    version = quic::ParseQuicVersionString(quic_version_string);
+  } else {
+    for (const quic::ParsedQuicVersion& vers : quic::AllSupportedVersions()) {
+      // Use the most recent IETF QUIC version.
+      if (vers.HasIetfQuicFrames() && vers.UsesHttp3() && vers.UsesTls()) {
+        version = vers;
+        break;
+      }
+    }
+  }
+  QUICHE_CHECK(version.IsKnown());
+  QuicEnableVersion(version);
+
+  auto supported_features =
+      quic::ServerSupport(dns_host, url_host, port, version);
+  std::cout << "Results for " << url_host << ":" << port << std::endl;
+  int current_row = 1;
+  for (auto feature : supported_features) {
+    if (current_row < 2 && feature >= quic::Feature::kRebinding) {
+      std::cout << std::endl;
+      current_row = 2;
+    }
+    if (current_row < 3 && feature >= quic::Feature::kHttp3) {
+      std::cout << std::endl;
+      current_row = 3;
+    }
+    std::cout << MatrixLetter(feature);
+  }
+  std::cout << std::endl;
+}
diff --git a/quiche/quic/tools/quic_client_test.cc b/quiche/quic/tools/quic_client_test.cc
new file mode 100644
index 0000000..5c3aec6
--- /dev/null
+++ b/quiche/quic/tools/quic_client_test.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_client.h"
+
+#include <dirent.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_client_peer.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+const char* kPathToFds = "/proc/self/fd";
+
+// Return the value of a symbolic link in |path|, if |path| is not found, return
+// an empty string.
+std::string ReadLink(const std::string& path) {
+  std::string result(PATH_MAX, '\0');
+  ssize_t result_size = readlink(path.c_str(), &result[0], result.size());
+  if (result_size < 0 && errno == ENOENT) {
+    return "";
+  }
+  QUICHE_CHECK(result_size > 0 &&
+               static_cast<size_t>(result_size) < result.size())
+      << "result_size:" << result_size << ", errno:" << errno
+      << ", path:" << path;
+  result.resize(result_size);
+  return result;
+}
+
+// Counts the number of open sockets for the current process.
+size_t NumOpenSocketFDs() {
+  size_t socket_count = 0;
+  dirent* file;
+  std::unique_ptr<DIR, int (*)(DIR*)> fd_directory(opendir(kPathToFds),
+                                                   closedir);
+  while ((file = readdir(fd_directory.get())) != nullptr) {
+    absl::string_view name(file->d_name);
+    if (name == "." || name == "..") {
+      continue;
+    }
+
+    std::string fd_path = ReadLink(absl::StrCat(kPathToFds, "/", name));
+    if (absl::StartsWith(fd_path, "socket:")) {
+      socket_count++;
+    }
+  }
+  return socket_count;
+}
+
+class QuicClientTest : public QuicTest {
+ public:
+  QuicClientTest() {
+    // Creates and destroys a single client first which may open persistent
+    // sockets when initializing platform dependencies like certificate
+    // verifier. Future creation of addtional clients will deterministically
+    // open one socket per client.
+    CreateAndInitializeQuicClient();
+  }
+
+  // Creates a new QuicClient and Initializes it on an unused port.
+  // Caller is responsible for deletion.
+  std::unique_ptr<QuicClient> CreateAndInitializeQuicClient() {
+    QuicSocketAddress server_address(QuicSocketAddress(TestLoopback(), 0));
+    QuicServerId server_id("hostname", server_address.port(), false);
+    ParsedQuicVersionVector versions = AllSupportedVersions();
+    auto client = std::make_unique<QuicClient>(
+        server_address, server_id, versions, &epoll_server_,
+        crypto_test_utils::ProofVerifierForTesting());
+    EXPECT_TRUE(client->Initialize());
+    return client;
+  }
+
+ private:
+  QuicEpollServer epoll_server_;
+};
+
+TEST_F(QuicClientTest, DoNotLeakSocketFDs) {
+  // Make sure that the QuicClient doesn't leak socket FDs. Doing so could cause
+  // port exhaustion in long running processes which repeatedly create clients.
+
+  // Record the initial number of FDs.
+  size_t number_of_open_fds = NumOpenSocketFDs();
+
+  // Create a number of clients, initialize them, and verify this has resulted
+  // in additional FDs being opened.
+  const int kNumClients = 50;
+  for (int i = 0; i < kNumClients; ++i) {
+    EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
+    std::unique_ptr<QuicClient> client(CreateAndInitializeQuicClient());
+    // Initializing the client will create a new FD.
+    EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
+  }
+
+  // The FDs created by the QuicClients should now be closed.
+  EXPECT_EQ(number_of_open_fds, NumOpenSocketFDs());
+}
+
+TEST_F(QuicClientTest, CreateAndCleanUpUDPSockets) {
+  size_t number_of_open_fds = NumOpenSocketFDs();
+
+  std::unique_ptr<QuicClient> client(CreateAndInitializeQuicClient());
+  // Creating and initializing a client will result in one socket being opened.
+  EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
+
+  // Create more UDP sockets.
+  EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
+  EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
+  EXPECT_TRUE(QuicClientPeer::CreateUDPSocketAndBind(client.get()));
+  EXPECT_EQ(number_of_open_fds + 3, NumOpenSocketFDs());
+
+  // Clean up UDP sockets.
+  QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
+  EXPECT_EQ(number_of_open_fds + 2, NumOpenSocketFDs());
+  QuicClientPeer::CleanUpUDPSocket(client.get(), client->GetLatestFD());
+  EXPECT_EQ(number_of_open_fds + 1, NumOpenSocketFDs());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_epoll_client_factory.cc b/quiche/quic/tools/quic_epoll_client_factory.cc
new file mode 100644
index 0000000..2719057
--- /dev/null
+++ b/quiche/quic/tools/quic_epoll_client_factory.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_epoll_client_factory.h"
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_client.h"
+
+namespace quic {
+
+std::unique_ptr<QuicSpdyClientBase> QuicEpollClientFactory::CreateClient(
+    std::string host_for_handshake,
+    std::string host_for_lookup,
+    int address_family_for_lookup,
+    uint16_t port,
+    ParsedQuicVersionVector versions,
+    const QuicConfig& config,
+    std::unique_ptr<ProofVerifier> verifier,
+    std::unique_ptr<SessionCache> session_cache) {
+  QuicSocketAddress addr = tools::LookupAddress(
+      address_family_for_lookup, host_for_lookup, absl::StrCat(port));
+  if (!addr.IsInitialized()) {
+    QUIC_LOG(ERROR) << "Unable to resolve address: " << host_for_lookup;
+    return nullptr;
+  }
+  QuicServerId server_id(host_for_handshake, port, false);
+  return std::make_unique<QuicClient>(addr, server_id, versions, config,
+                                      &epoll_server_, std::move(verifier),
+                                      std::move(session_cache));
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_epoll_client_factory.h b/quiche/quic/tools/quic_epoll_client_factory.h
new file mode 100644
index 0000000..1e5708f
--- /dev/null
+++ b/quiche/quic/tools/quic_epoll_client_factory.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
+#define QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
+
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/tools/quic_toy_client.h"
+
+namespace quic {
+
+// Factory creating QuicClient instances.
+class QuicEpollClientFactory : public QuicToyClient::ClientFactory {
+ public:
+  std::unique_ptr<QuicSpdyClientBase> CreateClient(
+      std::string host_for_handshake,
+      std::string host_for_lookup,
+      int address_family_for_lookup,
+      uint16_t port,
+      ParsedQuicVersionVector versions,
+      const QuicConfig& config,
+      std::unique_ptr<ProofVerifier> verifier,
+      std::unique_ptr<SessionCache> session_cache) override;
+
+ private:
+  QuicEpollServer epoll_server_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_EPOLL_CLIENT_FACTORY_H_
diff --git a/quiche/quic/tools/quic_epoll_server_factory.cc b/quiche/quic/tools/quic_epoll_server_factory.cc
new file mode 100644
index 0000000..a81b973
--- /dev/null
+++ b/quiche/quic/tools/quic_epoll_server_factory.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_epoll_server_factory.h"
+
+#include <utility>
+
+#include "quiche/quic/tools/quic_server.h"
+
+namespace quic {
+
+std::unique_ptr<quic::QuicSpdyServerBase> QuicEpollServerFactory::CreateServer(
+    quic::QuicSimpleServerBackend* backend,
+    std::unique_ptr<quic::ProofSource> proof_source,
+    const quic::ParsedQuicVersionVector& supported_versions) {
+  return std::make_unique<quic::QuicServer>(std::move(proof_source), backend,
+                                            supported_versions);
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_epoll_server_factory.h b/quiche/quic/tools/quic_epoll_server_factory.h
new file mode 100644
index 0000000..6d6876a
--- /dev/null
+++ b/quiche/quic/tools/quic_epoll_server_factory.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
+#define QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
+
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/tools/quic_toy_server.h"
+
+namespace quic {
+
+// Factory creating QuicServer instances.
+class QuicEpollServerFactory : public QuicToyServer::ServerFactory {
+ public:
+  std::unique_ptr<QuicSpdyServerBase> CreateServer(
+      QuicSimpleServerBackend* backend,
+      std::unique_ptr<ProofSource> proof_source,
+      const quic::ParsedQuicVersionVector& supported_versions) override;
+
+ private:
+  QuicEpollServer epoll_server_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_EPOLL_SERVER_FACTORY_H_
diff --git a/quiche/quic/tools/quic_memory_cache_backend.cc b/quiche/quic/tools/quic_memory_cache_backend.cc
new file mode 100644
index 0000000..0e50139
--- /dev/null
+++ b/quiche/quic/tools/quic_memory_cache_backend.cc
@@ -0,0 +1,496 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+
+#include <utility>
+
+#include "absl/strings/match.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/tools/web_transport_test_visitors.h"
+#include "quiche/common/platform/api/quiche_file_utils.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using spdy::Http2HeaderBlock;
+using spdy::kV3LowestPriority;
+
+namespace quic {
+
+QuicMemoryCacheBackend::ResourceFile::ResourceFile(const std::string& file_name)
+    : file_name_(file_name) {}
+
+QuicMemoryCacheBackend::ResourceFile::~ResourceFile() = default;
+
+void QuicMemoryCacheBackend::ResourceFile::Read() {
+  absl::optional<std::string> maybe_file_contents =
+      quiche::ReadFileContents(file_name_);
+  if (!maybe_file_contents) {
+    QUIC_LOG(DFATAL) << "Failed to read file for the memory cache backend: "
+                     << file_name_;
+    return;
+  }
+  file_contents_ = *maybe_file_contents;
+
+  // First read the headers.
+  size_t start = 0;
+  while (start < file_contents_.length()) {
+    size_t pos = file_contents_.find('\n', start);
+    if (pos == std::string::npos) {
+      QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file_name_;
+      return;
+    }
+    size_t len = pos - start;
+    // Support both dos and unix line endings for convenience.
+    if (file_contents_[pos - 1] == '\r') {
+      len -= 1;
+    }
+    absl::string_view line(file_contents_.data() + start, len);
+    start = pos + 1;
+    // Headers end with an empty line.
+    if (line.empty()) {
+      break;
+    }
+    // Extract the status from the HTTP first line.
+    if (line.substr(0, 4) == "HTTP") {
+      pos = line.find(' ');
+      if (pos == std::string::npos) {
+        QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
+                         << file_name_;
+        return;
+      }
+      spdy_headers_[":status"] = line.substr(pos + 1, 3);
+      continue;
+    }
+    // Headers are "key: value".
+    pos = line.find(": ");
+    if (pos == std::string::npos) {
+      QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file_name_;
+      return;
+    }
+    spdy_headers_.AppendValueOrAddHeader(
+        quiche::QuicheTextUtils::ToLower(line.substr(0, pos)),
+        line.substr(pos + 2));
+  }
+
+  // The connection header is prohibited in HTTP/2.
+  spdy_headers_.erase("connection");
+
+  // Override the URL with the X-Original-Url header, if present.
+  auto it = spdy_headers_.find("x-original-url");
+  if (it != spdy_headers_.end()) {
+    x_original_url_ = it->second;
+    HandleXOriginalUrl();
+  }
+
+  // X-Push-URL header is a relatively quick way to support sever push
+  // in the toy server.  A production server should use link=preload
+  // stuff as described in https://w3c.github.io/preload/.
+  it = spdy_headers_.find("x-push-url");
+  if (it != spdy_headers_.end()) {
+    absl::string_view push_urls = it->second;
+    size_t start = 0;
+    while (start < push_urls.length()) {
+      size_t pos = push_urls.find('\0', start);
+      if (pos == std::string::npos) {
+        push_urls_.push_back(absl::string_view(push_urls.data() + start,
+                                               push_urls.length() - start));
+        break;
+      }
+      push_urls_.push_back(absl::string_view(push_urls.data() + start, pos));
+      start += pos + 1;
+    }
+  }
+
+  body_ = absl::string_view(file_contents_.data() + start,
+                            file_contents_.size() - start);
+}
+
+void QuicMemoryCacheBackend::ResourceFile::SetHostPathFromBase(
+    absl::string_view base) {
+  QUICHE_DCHECK(base[0] != '/') << base;
+  size_t path_start = base.find_first_of('/');
+  if (path_start == absl::string_view::npos) {
+    host_ = std::string(base);
+    path_ = "";
+    return;
+  }
+
+  host_ = std::string(base.substr(0, path_start));
+  size_t query_start = base.find_first_of(',');
+  if (query_start > 0) {
+    path_ = std::string(base.substr(path_start, query_start - 1));
+  } else {
+    path_ = std::string(base.substr(path_start));
+  }
+}
+
+absl::string_view QuicMemoryCacheBackend::ResourceFile::RemoveScheme(
+    absl::string_view url) {
+  if (absl::StartsWith(url, "https://")) {
+    url.remove_prefix(8);
+  } else if (absl::StartsWith(url, "http://")) {
+    url.remove_prefix(7);
+  }
+  return url;
+}
+
+void QuicMemoryCacheBackend::ResourceFile::HandleXOriginalUrl() {
+  absl::string_view url(x_original_url_);
+  SetHostPathFromBase(RemoveScheme(url));
+}
+
+const QuicBackendResponse* QuicMemoryCacheBackend::GetResponse(
+    absl::string_view host, absl::string_view path) const {
+  QuicWriterMutexLock lock(&response_mutex_);
+
+  auto it = responses_.find(GetKey(host, path));
+  if (it == responses_.end()) {
+    uint64_t ignored = 0;
+    if (generate_bytes_response_) {
+      if (absl::SimpleAtoi(absl::string_view(path.data() + 1, path.size() - 1),
+                           &ignored)) {
+        // The actual parsed length is ignored here and will be recomputed
+        // by the caller.
+        return generate_bytes_response_.get();
+      }
+    }
+    QUIC_DVLOG(1) << "Get response for resource failed: host " << host
+                  << " path " << path;
+    if (default_response_) {
+      return default_response_.get();
+    }
+    return nullptr;
+  }
+  return it->second.get();
+}
+
+using ServerPushInfo = QuicBackendResponse::ServerPushInfo;
+using SpecialResponseType = QuicBackendResponse::SpecialResponseType;
+
+void QuicMemoryCacheBackend::AddSimpleResponse(absl::string_view host,
+                                               absl::string_view path,
+                                               int response_code,
+                                               absl::string_view body) {
+  Http2HeaderBlock response_headers;
+  response_headers[":status"] = absl::StrCat(response_code);
+  response_headers["content-length"] = absl::StrCat(body.length());
+  AddResponse(host, path, std::move(response_headers), body);
+}
+
+void QuicMemoryCacheBackend::AddSimpleResponseWithServerPushResources(
+    absl::string_view host, absl::string_view path, int response_code,
+    absl::string_view body, std::list<ServerPushInfo> push_resources) {
+  AddSimpleResponse(host, path, response_code, body);
+  MaybeAddServerPushResources(host, path, push_resources);
+}
+
+void QuicMemoryCacheBackend::AddDefaultResponse(QuicBackendResponse* response) {
+  QuicWriterMutexLock lock(&response_mutex_);
+  default_response_.reset(response);
+}
+
+void QuicMemoryCacheBackend::AddResponse(absl::string_view host,
+                                         absl::string_view path,
+                                         Http2HeaderBlock response_headers,
+                                         absl::string_view response_body) {
+  AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
+                  std::move(response_headers), response_body,
+                  Http2HeaderBlock(), std::vector<spdy::Http2HeaderBlock>());
+}
+
+void QuicMemoryCacheBackend::AddResponse(absl::string_view host,
+                                         absl::string_view path,
+                                         Http2HeaderBlock response_headers,
+                                         absl::string_view response_body,
+                                         Http2HeaderBlock response_trailers) {
+  AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
+                  std::move(response_headers), response_body,
+                  std::move(response_trailers),
+                  std::vector<spdy::Http2HeaderBlock>());
+}
+
+void QuicMemoryCacheBackend::AddResponseWithEarlyHints(
+    absl::string_view host, absl::string_view path,
+    spdy::Http2HeaderBlock response_headers, absl::string_view response_body,
+    const std::vector<spdy::Http2HeaderBlock>& early_hints) {
+  AddResponseImpl(host, path, QuicBackendResponse::REGULAR_RESPONSE,
+                  std::move(response_headers), response_body,
+                  Http2HeaderBlock(), early_hints);
+}
+
+void QuicMemoryCacheBackend::AddSpecialResponse(
+    absl::string_view host, absl::string_view path,
+    SpecialResponseType response_type) {
+  AddResponseImpl(host, path, response_type, Http2HeaderBlock(), "",
+                  Http2HeaderBlock(), std::vector<spdy::Http2HeaderBlock>());
+}
+
+void QuicMemoryCacheBackend::AddSpecialResponse(
+    absl::string_view host, absl::string_view path,
+    spdy::Http2HeaderBlock response_headers, absl::string_view response_body,
+    SpecialResponseType response_type) {
+  AddResponseImpl(host, path, response_type, std::move(response_headers),
+                  response_body, Http2HeaderBlock(),
+                  std::vector<spdy::Http2HeaderBlock>());
+}
+
+QuicMemoryCacheBackend::QuicMemoryCacheBackend() : cache_initialized_(false) {}
+
+bool QuicMemoryCacheBackend::InitializeBackend(
+    const std::string& cache_directory) {
+  if (cache_directory.empty()) {
+    QUIC_BUG(quic_bug_10932_1) << "cache_directory must not be empty.";
+    return false;
+  }
+  QUIC_LOG(INFO)
+      << "Attempting to initialize QuicMemoryCacheBackend from directory: "
+      << cache_directory;
+  std::vector<std::string> files;
+  if (!quiche::EnumerateDirectoryRecursively(cache_directory, files)) {
+    QUIC_BUG(QuicMemoryCacheBackend unreadable directory)
+        << "Can't read QuicMemoryCacheBackend directory: " << cache_directory;
+    return false;
+  }
+  std::list<std::unique_ptr<ResourceFile>> resource_files;
+  for (const auto& filename : files) {
+    std::unique_ptr<ResourceFile> resource_file(new ResourceFile(filename));
+
+    // Tease apart filename into host and path.
+    std::string base(resource_file->file_name());
+    // Transform windows path separators to URL path separators.
+    for (size_t i = 0; i < base.length(); ++i) {
+      if (base[i] == '\\') {
+        base[i] = '/';
+      }
+    }
+    base.erase(0, cache_directory.length());
+    if (base[0] == '/') {
+      base.erase(0, 1);
+    }
+
+    resource_file->SetHostPathFromBase(base);
+    resource_file->Read();
+
+    AddResponse(resource_file->host(), resource_file->path(),
+                resource_file->spdy_headers().Clone(), resource_file->body());
+
+    resource_files.push_back(std::move(resource_file));
+  }
+
+  for (const auto& resource_file : resource_files) {
+    std::list<ServerPushInfo> push_resources;
+    for (const auto& push_url : resource_file->push_urls()) {
+      QuicUrl url(push_url);
+      const QuicBackendResponse* response = GetResponse(url.host(), url.path());
+      if (!response) {
+        QUIC_BUG(quic_bug_10932_2)
+            << "Push URL '" << push_url << "' not found.";
+        return false;
+      }
+      push_resources.push_back(ServerPushInfo(url, response->headers().Clone(),
+                                              kV3LowestPriority,
+                                              (std::string(response->body()))));
+    }
+    MaybeAddServerPushResources(resource_file->host(), resource_file->path(),
+                                push_resources);
+  }
+
+  cache_initialized_ = true;
+  return true;
+}
+
+void QuicMemoryCacheBackend::GenerateDynamicResponses() {
+  QuicWriterMutexLock lock(&response_mutex_);
+  // Add a generate bytes response.
+  spdy::Http2HeaderBlock response_headers;
+  response_headers[":status"] = "200";
+  generate_bytes_response_ = std::make_unique<QuicBackendResponse>();
+  generate_bytes_response_->set_headers(std::move(response_headers));
+  generate_bytes_response_->set_response_type(
+      QuicBackendResponse::GENERATE_BYTES);
+}
+
+void QuicMemoryCacheBackend::EnableWebTransport() {
+  enable_webtransport_ = true;
+}
+
+bool QuicMemoryCacheBackend::IsBackendInitialized() const {
+  return cache_initialized_;
+}
+
+void QuicMemoryCacheBackend::FetchResponseFromBackend(
+    const Http2HeaderBlock& request_headers,
+    const std::string& /*request_body*/,
+    QuicSimpleServerBackend::RequestHandler* quic_stream) {
+  const QuicBackendResponse* quic_response = nullptr;
+  // Find response in cache. If not found, send error response.
+  auto authority = request_headers.find(":authority");
+  auto path = request_headers.find(":path");
+  if (authority != request_headers.end() && path != request_headers.end()) {
+    quic_response = GetResponse(authority->second, path->second);
+  }
+
+  std::string request_url;
+  if (authority != request_headers.end()) {
+    request_url = std::string(authority->second);
+  }
+  if (path != request_headers.end()) {
+    request_url += std::string(path->second);
+  }
+  QUIC_DVLOG(1)
+      << "Fetching QUIC response from backend in-memory cache for url "
+      << request_url;
+  quic_stream->OnResponseBackendComplete(quic_response);
+}
+
+// The memory cache does not have a per-stream handler
+void QuicMemoryCacheBackend::CloseBackendResponseStream(
+    QuicSimpleServerBackend::RequestHandler* /*quic_stream*/) {}
+
+std::list<ServerPushInfo> QuicMemoryCacheBackend::GetServerPushResources(
+    std::string request_url) {
+  QuicWriterMutexLock lock(&response_mutex_);
+
+  std::list<ServerPushInfo> resources;
+  auto resource_range = server_push_resources_.equal_range(request_url);
+  for (auto it = resource_range.first; it != resource_range.second; ++it) {
+    resources.push_back(it->second);
+  }
+  QUIC_DVLOG(1) << "Found " << resources.size() << " push resources for "
+                << request_url;
+  return resources;
+}
+
+QuicMemoryCacheBackend::WebTransportResponse
+QuicMemoryCacheBackend::ProcessWebTransportRequest(
+    const spdy::Http2HeaderBlock& request_headers,
+    WebTransportSession* session) {
+  if (!SupportsWebTransport()) {
+    return QuicSimpleServerBackend::ProcessWebTransportRequest(request_headers,
+                                                               session);
+  }
+
+  auto path_it = request_headers.find(":path");
+  if (path_it == request_headers.end()) {
+    WebTransportResponse response;
+    response.response_headers[":status"] = "400";
+    return response;
+  }
+  absl::string_view path = path_it->second;
+  if (path == "/echo") {
+    WebTransportResponse response;
+    response.response_headers[":status"] = "200";
+    response.visitor =
+        std::make_unique<EchoWebTransportSessionVisitor>(session);
+    return response;
+  }
+
+  WebTransportResponse response;
+  response.response_headers[":status"] = "404";
+  return response;
+}
+
+QuicMemoryCacheBackend::~QuicMemoryCacheBackend() {
+  {
+    QuicWriterMutexLock lock(&response_mutex_);
+    responses_.clear();
+  }
+}
+
+void QuicMemoryCacheBackend::AddResponseImpl(
+    absl::string_view host, absl::string_view path,
+    SpecialResponseType response_type, Http2HeaderBlock response_headers,
+    absl::string_view response_body, Http2HeaderBlock response_trailers,
+    const std::vector<spdy::Http2HeaderBlock>& early_hints) {
+  QuicWriterMutexLock lock(&response_mutex_);
+
+  QUICHE_DCHECK(!host.empty())
+      << "Host must be populated, e.g. \"www.google.com\"";
+  std::string key = GetKey(host, path);
+  if (responses_.contains(key)) {
+    QUIC_BUG(quic_bug_10932_3)
+        << "Response for '" << key << "' already exists!";
+    return;
+  }
+  auto new_response = std::make_unique<QuicBackendResponse>();
+  new_response->set_response_type(response_type);
+  new_response->set_headers(std::move(response_headers));
+  new_response->set_body(response_body);
+  new_response->set_trailers(std::move(response_trailers));
+  for (auto& headers : early_hints) {
+    new_response->AddEarlyHints(headers);
+  }
+  QUIC_DVLOG(1) << "Add response with key " << key;
+  responses_[key] = std::move(new_response);
+}
+
+std::string QuicMemoryCacheBackend::GetKey(absl::string_view host,
+                                           absl::string_view path) const {
+  std::string host_string = std::string(host);
+  size_t port = host_string.find(':');
+  if (port != std::string::npos)
+    host_string = std::string(host_string.c_str(), port);
+  return host_string + std::string(path);
+}
+
+void QuicMemoryCacheBackend::MaybeAddServerPushResources(
+    absl::string_view request_host, absl::string_view request_path,
+    std::list<ServerPushInfo> push_resources) {
+  std::string request_url = GetKey(request_host, request_path);
+
+  for (const auto& push_resource : push_resources) {
+    if (PushResourceExistsInCache(request_url, push_resource)) {
+      continue;
+    }
+
+    QUIC_DVLOG(1) << "Add request-resource association: request url "
+                  << request_url << " push url "
+                  << push_resource.request_url.ToString()
+                  << " response headers "
+                  << push_resource.headers.DebugString();
+    {
+      QuicWriterMutexLock lock(&response_mutex_);
+      server_push_resources_.insert(std::make_pair(request_url, push_resource));
+    }
+    std::string host = push_resource.request_url.host();
+    if (host.empty()) {
+      host = std::string(request_host);
+    }
+    std::string path = push_resource.request_url.path();
+    bool found_existing_response = false;
+    {
+      QuicWriterMutexLock lock(&response_mutex_);
+      found_existing_response = responses_.contains(GetKey(host, path));
+    }
+    if (!found_existing_response) {
+      // Add a server push response to responses map, if it is not in the map.
+      absl::string_view body = push_resource.body;
+      QUIC_DVLOG(1) << "Add response for push resource: host " << host
+                    << " path " << path;
+      AddResponse(host, path, push_resource.headers.Clone(), body);
+    }
+  }
+}
+
+bool QuicMemoryCacheBackend::PushResourceExistsInCache(
+    std::string original_request_url, ServerPushInfo resource) {
+  QuicWriterMutexLock lock(&response_mutex_);
+  auto resource_range =
+      server_push_resources_.equal_range(original_request_url);
+  for (auto it = resource_range.first; it != resource_range.second; ++it) {
+    ServerPushInfo push_resource = it->second;
+    if (push_resource.request_url.ToString() ==
+        resource.request_url.ToString()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_memory_cache_backend.h b/quiche/quic/tools/quic_memory_cache_backend.h
new file mode 100644
index 0000000..986badb
--- /dev/null
+++ b/quiche/quic/tools/quic_memory_cache_backend.h
@@ -0,0 +1,217 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
+#define QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+// In-memory cache for HTTP responses.
+// Reads from disk cache generated by:
+// `wget -p --save_headers <url>`
+class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
+ public:
+  // Class to manage loading a resource file into memory.  There are
+  // two uses: called by InitializeBackend to load resources
+  // from files, and recursively called when said resources specify
+  // server push associations.
+  class ResourceFile {
+   public:
+    explicit ResourceFile(const std::string& file_name);
+    ResourceFile(const ResourceFile&) = delete;
+    ResourceFile& operator=(const ResourceFile&) = delete;
+    virtual ~ResourceFile();
+
+    void Read();
+
+    // |base| is |file_name_| with |cache_directory| prefix stripped.
+    void SetHostPathFromBase(absl::string_view base);
+
+    const std::string& file_name() { return file_name_; }
+
+    absl::string_view host() { return host_; }
+
+    absl::string_view path() { return path_; }
+
+    const spdy::Http2HeaderBlock& spdy_headers() { return spdy_headers_; }
+
+    absl::string_view body() { return body_; }
+
+    const std::vector<absl::string_view>& push_urls() { return push_urls_; }
+
+   private:
+    void HandleXOriginalUrl();
+    absl::string_view RemoveScheme(absl::string_view url);
+
+    std::string file_name_;
+    std::string file_contents_;
+    absl::string_view body_;
+    spdy::Http2HeaderBlock spdy_headers_;
+    absl::string_view x_original_url_;
+    std::vector<absl::string_view> push_urls_;
+    std::string host_;
+    std::string path_;
+  };
+
+  QuicMemoryCacheBackend();
+  QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete;
+  QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete;
+  ~QuicMemoryCacheBackend() override;
+
+  // Retrieve a response from this cache for a given host and path..
+  // If no appropriate response exists, nullptr is returned.
+  const QuicBackendResponse* GetResponse(absl::string_view host,
+                                         absl::string_view path) const;
+
+  // Adds a simple response to the cache.  The response headers will
+  // only contain the "content-length" header with the length of |body|.
+  void AddSimpleResponse(absl::string_view host,
+                         absl::string_view path,
+                         int response_code,
+                         absl::string_view body);
+
+  // Add a simple response to the cache as AddSimpleResponse() does, and add
+  // some server push resources(resource path, corresponding response status and
+  // path) associated with it.
+  // Push resource implicitly come from the same host.
+  // TODO(b/171463363): Remove.
+  void AddSimpleResponseWithServerPushResources(
+      absl::string_view host,
+      absl::string_view path,
+      int response_code,
+      absl::string_view body,
+      std::list<QuicBackendResponse::ServerPushInfo> push_resources);
+
+  // Add a response to the cache.
+  void AddResponse(absl::string_view host,
+                   absl::string_view path,
+                   spdy::Http2HeaderBlock response_headers,
+                   absl::string_view response_body);
+
+  // Add a response, with trailers, to the cache.
+  void AddResponse(absl::string_view host,
+                   absl::string_view path,
+                   spdy::Http2HeaderBlock response_headers,
+                   absl::string_view response_body,
+                   spdy::Http2HeaderBlock response_trailers);
+
+  // Add a response, with 103 Early Hints, to the cache.
+  void AddResponseWithEarlyHints(
+      absl::string_view host,
+      absl::string_view path,
+      spdy::Http2HeaderBlock response_headers,
+      absl::string_view response_body,
+      const std::vector<spdy::Http2HeaderBlock>& early_hints);
+
+  // Simulate a special behavior at a particular path.
+  void AddSpecialResponse(
+      absl::string_view host,
+      absl::string_view path,
+      QuicBackendResponse::SpecialResponseType response_type);
+
+  void AddSpecialResponse(
+      absl::string_view host,
+      absl::string_view path,
+      spdy::Http2HeaderBlock response_headers,
+      absl::string_view response_body,
+      QuicBackendResponse::SpecialResponseType response_type);
+
+  // Sets a default response in case of cache misses.  Takes ownership of
+  // 'response'.
+  void AddDefaultResponse(QuicBackendResponse* response);
+
+  // Once called, URLs which have a numeric path will send a dynamically
+  // generated response of that many bytes.
+  void GenerateDynamicResponses();
+
+  void EnableWebTransport();
+
+  // Find all the server push resources associated with |request_url|.
+  // TODO(b/171463363): Remove.
+  std::list<QuicBackendResponse::ServerPushInfo> GetServerPushResources(
+      std::string request_url);
+
+  // Implements the functions for interface QuicSimpleServerBackend
+  // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
+  bool InitializeBackend(const std::string& cache_directory) override;
+  bool IsBackendInitialized() const override;
+  void FetchResponseFromBackend(
+      const spdy::Http2HeaderBlock& request_headers,
+      const std::string& request_body,
+      QuicSimpleServerBackend::RequestHandler* quic_stream) override;
+  void CloseBackendResponseStream(
+      QuicSimpleServerBackend::RequestHandler* quic_stream) override;
+  WebTransportResponse ProcessWebTransportRequest(
+      const spdy::Http2HeaderBlock& request_headers,
+      WebTransportSession* session) override;
+  bool SupportsWebTransport() override { return enable_webtransport_; }
+
+ private:
+  void AddResponseImpl(absl::string_view host,
+                       absl::string_view path,
+                       QuicBackendResponse::SpecialResponseType response_type,
+                       spdy::Http2HeaderBlock response_headers,
+                       absl::string_view response_body,
+                       spdy::Http2HeaderBlock response_trailers,
+                       const std::vector<spdy::Http2HeaderBlock>& early_hints);
+
+  std::string GetKey(absl::string_view host, absl::string_view path) const;
+
+  // Add some server push urls with given responses for specified
+  // request if these push resources are not associated with this request yet.
+  // TODO(b/171463363): Remove.
+  void MaybeAddServerPushResources(
+      absl::string_view request_host,
+      absl::string_view request_path,
+      std::list<QuicBackendResponse::ServerPushInfo> push_resources);
+
+  // Check if push resource(push_host/push_path) associated with given request
+  // url already exists in server push map.
+  // TODO(b/171463363): Remove.
+  bool PushResourceExistsInCache(std::string original_request_url,
+                                 QuicBackendResponse::ServerPushInfo resource);
+
+  // Cached responses.
+  absl::flat_hash_map<std::string, std::unique_ptr<QuicBackendResponse>>
+      responses_ QUIC_GUARDED_BY(response_mutex_);
+
+  // The default response for cache misses, if set.
+  std::unique_ptr<QuicBackendResponse> default_response_
+      QUIC_GUARDED_BY(response_mutex_);
+
+  // The generate bytes response, if set.
+  std::unique_ptr<QuicBackendResponse> generate_bytes_response_
+      QUIC_GUARDED_BY(response_mutex_);
+
+  // A map from request URL to associated server push responses (if any).
+  // TODO(b/171463363): Remove.
+  std::multimap<std::string, QuicBackendResponse::ServerPushInfo>
+      server_push_resources_ QUIC_GUARDED_BY(response_mutex_);
+
+  // Protects against concurrent access from test threads setting responses, and
+  // server threads accessing those responses.
+  mutable QuicMutex response_mutex_;
+  bool cache_initialized_;
+
+  bool enable_webtransport_ = false;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
diff --git a/quiche/quic/tools/quic_memory_cache_backend_test.cc b/quiche/quic/tools/quic_memory_cache_backend_test.cc
new file mode 100644
index 0000000..bb5e675
--- /dev/null
+++ b/quiche/quic/tools/quic_memory_cache_backend_test.cc
@@ -0,0 +1,291 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/common/platform/api/quiche_file_utils.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+using Response = QuicBackendResponse;
+using ServerPushInfo = QuicBackendResponse::ServerPushInfo;
+}  // namespace
+
+class QuicMemoryCacheBackendTest : public QuicTest {
+ protected:
+  void CreateRequest(std::string host, std::string path,
+                     spdy::Http2HeaderBlock* headers) {
+    (*headers)[":method"] = "GET";
+    (*headers)[":path"] = path;
+    (*headers)[":authority"] = host;
+    (*headers)[":scheme"] = "https";
+  }
+
+  std::string CacheDirectory() { return QuicGetTestMemoryCachePath(); }
+
+  QuicMemoryCacheBackend cache_;
+};
+
+TEST_F(QuicMemoryCacheBackendTest, GetResponseNoMatch) {
+  const Response* response =
+      cache_.GetResponse("mail.google.com", "/index.html");
+  ASSERT_FALSE(response);
+}
+
+TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseGetResponse) {
+  std::string response_body("hello response");
+  cache_.AddSimpleResponse("www.google.com", "/", 200, response_body);
+
+  spdy::Http2HeaderBlock request_headers;
+  CreateRequest("www.google.com", "/", &request_headers);
+  const Response* response = cache_.GetResponse("www.google.com", "/");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("200", response->headers().find(":status")->second);
+  EXPECT_EQ(response_body.size(), response->body().length());
+}
+
+TEST_F(QuicMemoryCacheBackendTest, AddResponse) {
+  const std::string kRequestHost = "www.foo.com";
+  const std::string kRequestPath = "/";
+  const std::string kResponseBody("hello response");
+
+  spdy::Http2HeaderBlock response_headers;
+  response_headers[":status"] = "200";
+  response_headers["content-length"] = absl::StrCat(kResponseBody.size());
+
+  spdy::Http2HeaderBlock response_trailers;
+  response_trailers["key-1"] = "value-1";
+  response_trailers["key-2"] = "value-2";
+  response_trailers["key-3"] = "value-3";
+
+  cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody,
+                     response_trailers.Clone());
+
+  const Response* response = cache_.GetResponse(kRequestHost, kRequestPath);
+  EXPECT_EQ(response->headers(), response_headers);
+  EXPECT_EQ(response->body(), kResponseBody);
+  EXPECT_EQ(response->trailers(), response_trailers);
+}
+
+// TODO(crbug.com/1249712) This test is failing on iOS.
+#if defined(OS_IOS)
+#define MAYBE_ReadsCacheDir DISABLED_ReadsCacheDir
+#else
+#define MAYBE_ReadsCacheDir ReadsCacheDir
+#endif
+TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDir) {
+  cache_.InitializeBackend(CacheDirectory());
+  const Response* response =
+      cache_.GetResponse("test.example.com", "/index.html");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("200", response->headers().find(":status")->second);
+  // Connection headers are not valid in HTTP/2.
+  EXPECT_FALSE(response->headers().contains("connection"));
+  EXPECT_LT(0U, response->body().length());
+}
+
+// TODO(crbug.com/1249712) This test is failing on iOS.
+#if defined(OS_IOS)
+#define MAYBE_ReadsCacheDirWithServerPushResource \
+  DISABLED_ReadsCacheDirWithServerPushResource
+#else
+#define MAYBE_ReadsCacheDirWithServerPushResource \
+  ReadsCacheDirWithServerPushResource
+#endif
+TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDirWithServerPushResource) {
+  cache_.InitializeBackend(CacheDirectory() + "_with_push");
+  std::list<ServerPushInfo> resources =
+      cache_.GetServerPushResources("test.example.com/");
+  ASSERT_EQ(1UL, resources.size());
+}
+
+// TODO(crbug.com/1249712) This test is failing on iOS.
+#if defined(OS_IOS)
+#define MAYBE_ReadsCacheDirWithServerPushResources \
+  DISABLED_ReadsCacheDirWithServerPushResources
+#else
+#define MAYBE_ReadsCacheDirWithServerPushResources \
+  ReadsCacheDirWithServerPushResources
+#endif
+TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDirWithServerPushResources) {
+  cache_.InitializeBackend(CacheDirectory() + "_with_push");
+  std::list<ServerPushInfo> resources =
+      cache_.GetServerPushResources("test.example.com/index2.html");
+  ASSERT_EQ(2UL, resources.size());
+}
+
+// TODO(crbug.com/1249712) This test is failing on iOS.
+#if defined(OS_IOS)
+#define MAYBE_UsesOriginalUrl DISABLED_UsesOriginalUrl
+#else
+#define MAYBE_UsesOriginalUrl UsesOriginalUrl
+#endif
+TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrl) {
+  cache_.InitializeBackend(CacheDirectory());
+  const Response* response =
+      cache_.GetResponse("test.example.com", "/site_map.html");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("200", response->headers().find(":status")->second);
+  // Connection headers are not valid in HTTP/2.
+  EXPECT_FALSE(response->headers().contains("connection"));
+  EXPECT_LT(0U, response->body().length());
+}
+
+// TODO(crbug.com/1249712) This test is failing on iOS.
+#if defined(OS_IOS)
+#define MAYBE_UsesOriginalUrlOnly DISABLED_UsesOriginalUrlOnly
+#else
+#define MAYBE_UsesOriginalUrlOnly UsesOriginalUrlOnly
+#endif
+TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrlOnly) {
+  // Tests that if the URL cannot be inferred correctly from the path
+  // because the directory does not include the hostname, that the
+  // X-Original-Url header's value will be used.
+  std::string dir;
+  std::string path = "map.html";
+  std::vector<std::string> files;
+  ASSERT_TRUE(quiche::EnumerateDirectoryRecursively(CacheDirectory(), files));
+  for (const std::string& file : files) {
+    if (absl::EndsWithIgnoreCase(file, "map.html")) {
+      dir = file;
+      dir.erase(dir.length() - path.length() - 1);
+      break;
+    }
+  }
+  ASSERT_NE("", dir);
+
+  cache_.InitializeBackend(dir);
+  const Response* response =
+      cache_.GetResponse("test.example.com", "/site_map.html");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("200", response->headers().find(":status")->second);
+  // Connection headers are not valid in HTTP/2.
+  EXPECT_FALSE(response->headers().contains("connection"));
+  EXPECT_LT(0U, response->body().length());
+}
+
+TEST_F(QuicMemoryCacheBackendTest, DefaultResponse) {
+  // Verify GetResponse returns nullptr when no default is set.
+  const Response* response = cache_.GetResponse("www.google.com", "/");
+  ASSERT_FALSE(response);
+
+  // Add a default response.
+  spdy::Http2HeaderBlock response_headers;
+  response_headers[":status"] = "200";
+  response_headers["content-length"] = "0";
+  Response* default_response = new Response;
+  default_response->set_headers(std::move(response_headers));
+  cache_.AddDefaultResponse(default_response);
+
+  // Now we should get the default response for the original request.
+  response = cache_.GetResponse("www.google.com", "/");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("200", response->headers().find(":status")->second);
+
+  // Now add a set response for / and make sure it is returned
+  cache_.AddSimpleResponse("www.google.com", "/", 302, "");
+  response = cache_.GetResponse("www.google.com", "/");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("302", response->headers().find(":status")->second);
+
+  // We should get the default response for other requests.
+  response = cache_.GetResponse("www.google.com", "/asd");
+  ASSERT_TRUE(response);
+  ASSERT_TRUE(response->headers().contains(":status"));
+  EXPECT_EQ("200", response->headers().find(":status")->second);
+}
+
+TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseWithServerPushResources) {
+  std::string request_host = "www.foo.com";
+  std::string response_body("hello response");
+  const size_t kNumResources = 5;
+  int NumResources = 5;
+  std::list<ServerPushInfo> push_resources;
+  std::string scheme = "http";
+  for (int i = 0; i < NumResources; ++i) {
+    std::string path = absl::StrCat("/server_push_src", i);
+    std::string url = scheme + "://" + request_host + path;
+    QuicUrl resource_url(url);
+    std::string body =
+        absl::StrCat("This is server push response body for ", path);
+    spdy::Http2HeaderBlock response_headers;
+    response_headers[":status"] = "200";
+    response_headers["content-length"] = absl::StrCat(body.size());
+    push_resources.push_back(
+        ServerPushInfo(resource_url, response_headers.Clone(), i, body));
+  }
+
+  cache_.AddSimpleResponseWithServerPushResources(
+      request_host, "/", 200, response_body, push_resources);
+
+  std::string request_url = request_host + "/";
+  std::list<ServerPushInfo> resources =
+      cache_.GetServerPushResources(request_url);
+  ASSERT_EQ(kNumResources, resources.size());
+  for (const auto& push_resource : push_resources) {
+    ServerPushInfo resource = resources.front();
+    EXPECT_EQ(resource.request_url.ToString(),
+              push_resource.request_url.ToString());
+    EXPECT_EQ(resource.priority, push_resource.priority);
+    resources.pop_front();
+  }
+}
+
+TEST_F(QuicMemoryCacheBackendTest, GetServerPushResourcesAndPushResponses) {
+  std::string request_host = "www.foo.com";
+  std::string response_body("hello response");
+  const size_t kNumResources = 4;
+  int NumResources = 4;
+  std::string scheme = "http";
+  std::string push_response_status[kNumResources] = {"200", "200", "301",
+                                                     "404"};
+  std::list<ServerPushInfo> push_resources;
+  for (int i = 0; i < NumResources; ++i) {
+    std::string path = absl::StrCat("/server_push_src", i);
+    std::string url = scheme + "://" + request_host + path;
+    QuicUrl resource_url(url);
+    std::string body = "This is server push response body for " + path;
+    spdy::Http2HeaderBlock response_headers;
+    response_headers[":status"] = push_response_status[i];
+    response_headers["content-length"] = absl::StrCat(body.size());
+    push_resources.push_back(
+        ServerPushInfo(resource_url, response_headers.Clone(), i, body));
+  }
+  cache_.AddSimpleResponseWithServerPushResources(
+      request_host, "/", 200, response_body, push_resources);
+  std::string request_url = request_host + "/";
+  std::list<ServerPushInfo> resources =
+      cache_.GetServerPushResources(request_url);
+  ASSERT_EQ(kNumResources, resources.size());
+  int i = 0;
+  for (const auto& push_resource : push_resources) {
+    QuicUrl url = resources.front().request_url;
+    std::string host = url.host();
+    std::string path = url.path();
+    const Response* response = cache_.GetResponse(host, path);
+    ASSERT_TRUE(response);
+    ASSERT_TRUE(response->headers().contains(":status"));
+    EXPECT_EQ(push_response_status[i++],
+              response->headers().find(":status")->second);
+    EXPECT_EQ(push_resource.body, response->body());
+    resources.pop_front();
+  }
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_packet_printer_bin.cc b/quiche/quic/tools/quic_packet_printer_bin.cc
new file mode 100644
index 0000000..8867e44
--- /dev/null
+++ b/quiche/quic/tools/quic_packet_printer_bin.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// clang-format off
+
+// Dumps out the decryptable contents of a QUIC packet in a human-readable way.
+// If the packet is null encrypted, this will dump full packet contents.
+// Otherwise it will dump the header, and fail with an error that the
+// packet is undecryptable.
+//
+// Usage: quic_packet_printer server|client <hex dump of packet>
+//
+// Example input:
+// quic_packet_printer server 0c6b810308320f24c004a939a38a2e3fd6ca589917f200400201b80b0100501c0700060003023d0000001c00556e656e637279707465642073747265616d2064617461207365656e
+//
+// Example output:
+// OnPacket
+// OnUnauthenticatedPublicHeader
+// OnUnauthenticatedHeader: { connection_id: 13845207862000976235, connection_id_length:8, packet_number_length:1, multipath_flag: 0, reset_flag: 0, version_flag: 0, path_id: , packet_number: 4 }
+// OnDecryptedPacket
+// OnPacketHeader
+// OnAckFrame:  largest_observed: 1 ack_delay_time: 3000 missing_packets: [  ] is_truncated: 0 received_packets: [ 1 at 466016  ]
+// OnStopWaitingFrame
+// OnConnectionCloseFrame: error_code { 61 } error_details { Unencrypted stream data seen }
+
+// clang-format on
+
+#include <iostream>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, quic_version, "",
+                                "If set, specify the QUIC version to use.");
+
+namespace quic {
+
+class QuicPacketPrinter : public QuicFramerVisitorInterface {
+ public:
+  explicit QuicPacketPrinter(QuicFramer* framer) : framer_(framer) {}
+
+  void OnError(QuicFramer* framer) override {
+    std::cerr << "OnError: " << QuicErrorCodeToString(framer->error())
+              << " detail: " << framer->detailed_error() << "\n";
+  }
+  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
+    framer_->set_version(received_version);
+    std::cerr << "OnProtocolVersionMismatch: "
+              << ParsedQuicVersionToString(received_version) << "\n";
+    return true;
+  }
+  void OnPacket() override { std::cerr << "OnPacket\n"; }
+  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {
+    std::cerr << "OnPublicResetPacket\n";
+  }
+  void OnVersionNegotiationPacket(
+      const QuicVersionNegotiationPacket& /*packet*/) override {
+    std::cerr << "OnVersionNegotiationPacket\n";
+  }
+  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
+                     QuicConnectionId /*new_connection_id*/,
+                     absl::string_view /*retry_token*/,
+                     absl::string_view /*retry_integrity_tag*/,
+                     absl::string_view /*retry_without_tag*/) override {
+    std::cerr << "OnRetryPacket\n";
+  }
+  bool OnUnauthenticatedPublicHeader(
+      const QuicPacketHeader& /*header*/) override {
+    std::cerr << "OnUnauthenticatedPublicHeader\n";
+    return true;
+  }
+  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
+    std::cerr << "OnUnauthenticatedHeader: " << header;
+    return true;
+  }
+  void OnDecryptedPacket(size_t /*length*/, EncryptionLevel level) override {
+    // This only currently supports "decrypting" null encrypted packets.
+    QUICHE_DCHECK_EQ(ENCRYPTION_INITIAL, level);
+    std::cerr << "OnDecryptedPacket\n";
+  }
+  bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
+    std::cerr << "OnPacketHeader\n";
+    return true;
+  }
+  void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {
+    std::cerr << "OnCoalescedPacket\n";
+  }
+  void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
+                             EncryptionLevel /*decryption_level*/,
+                             bool /*has_decryption_key*/) override {
+    std::cerr << "OnUndecryptablePacket\n";
+  }
+  bool OnStreamFrame(const QuicStreamFrame& frame) override {
+    std::cerr << "OnStreamFrame: " << frame;
+    std::cerr << "         data: { "
+              << absl::BytesToHexString(
+                     absl::string_view(frame.data_buffer, frame.data_length))
+              << " }\n";
+    return true;
+  }
+  bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
+    std::cerr << "OnCryptoFrame: " << frame;
+    std::cerr << "         data: { "
+              << absl::BytesToHexString(
+                     absl::string_view(frame.data_buffer, frame.data_length))
+              << " }\n";
+    return true;
+  }
+  bool OnAckFrameStart(QuicPacketNumber largest_acked,
+                       QuicTime::Delta /*ack_delay_time*/) override {
+    std::cerr << "OnAckFrameStart, largest_acked: " << largest_acked;
+    return true;
+  }
+  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
+    std::cerr << "OnAckRange: [" << start << ", " << end << ")";
+    return true;
+  }
+  bool OnAckTimestamp(QuicPacketNumber packet_number,
+                      QuicTime timestamp) override {
+    std::cerr << "OnAckTimestamp: [" << packet_number << ", "
+              << timestamp.ToDebuggingValue() << ")";
+    return true;
+  }
+  bool OnAckFrameEnd(QuicPacketNumber start) override {
+    std::cerr << "OnAckFrameEnd, start: " << start;
+    return true;
+  }
+  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
+    std::cerr << "OnStopWaitingFrame: " << frame;
+    return true;
+  }
+  bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
+    std::cerr << "OnPaddingFrame: " << frame;
+    return true;
+  }
+  bool OnPingFrame(const QuicPingFrame& frame) override {
+    std::cerr << "OnPingFrame: " << frame;
+    return true;
+  }
+  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
+    std::cerr << "OnRstStreamFrame: " << frame;
+    return true;
+  }
+  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
+    // The frame printout will indicate whether it's a Google QUIC
+    // CONNECTION_CLOSE, IETF QUIC CONNECTION_CLOSE/Transport, or IETF QUIC
+    // CONNECTION_CLOSE/Application frame.
+    std::cerr << "OnConnectionCloseFrame: " << frame;
+    return true;
+  }
+  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
+    std::cerr << "OnNewConnectionIdFrame: " << frame;
+    return true;
+  }
+  bool OnRetireConnectionIdFrame(
+      const QuicRetireConnectionIdFrame& frame) override {
+    std::cerr << "OnRetireConnectionIdFrame: " << frame;
+    return true;
+  }
+  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
+    std::cerr << "OnNewTokenFrame: " << frame;
+    return true;
+  }
+  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
+    std::cerr << "OnStopSendingFrame: " << frame;
+    return true;
+  }
+  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
+    std::cerr << "OnPathChallengeFrame: " << frame;
+    return true;
+  }
+  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
+    std::cerr << "OnPathResponseFrame: " << frame;
+    return true;
+  }
+  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
+    std::cerr << "OnGoAwayFrame: " << frame;
+    return true;
+  }
+  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
+    std::cerr << "OnMaxStreamsFrame: " << frame;
+    return true;
+  }
+  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
+    std::cerr << "OnStreamsBlockedFrame: " << frame;
+    return true;
+  }
+  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
+    std::cerr << "OnWindowUpdateFrame: " << frame;
+    return true;
+  }
+  bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
+    std::cerr << "OnBlockedFrame: " << frame;
+    return true;
+  }
+  bool OnMessageFrame(const QuicMessageFrame& frame) override {
+    std::cerr << "OnMessageFrame: " << frame;
+    return true;
+  }
+  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
+    std::cerr << "OnHandshakeDoneFrame: " << frame;
+    return true;
+  }
+  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+    std::cerr << "OnAckFrequencyFrame: " << frame;
+    return true;
+  }
+  void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
+  bool IsValidStatelessResetToken(
+      const StatelessResetToken& /*token*/) const override {
+    std::cerr << "IsValidStatelessResetToken\n";
+    return false;
+  }
+  void OnAuthenticatedIetfStatelessResetPacket(
+      const QuicIetfStatelessResetPacket& /*packet*/) override {
+    std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n";
+  }
+  void OnKeyUpdate(KeyUpdateReason reason) override {
+    std::cerr << "OnKeyUpdate: " << reason << "\n";
+  }
+  void OnDecryptedFirstPacketInKeyPhase() override {
+    std::cerr << "OnDecryptedFirstPacketInKeyPhase\n";
+  }
+  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
+      override {
+    std::cerr << "AdvanceKeysAndCreateCurrentOneRttDecrypter\n";
+    return nullptr;
+  }
+  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
+    std::cerr << "CreateCurrentOneRttEncrypter\n";
+    return nullptr;
+  }
+
+ private:
+  QuicFramer* framer_;  // Unowned.
+};
+
+}  // namespace quic
+
+int main(int argc, char* argv[]) {
+  const char* usage = "Usage: quic_packet_printer client|server <hex>";
+  std::vector<std::string> args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+
+  if (args.size() < 2) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    return 1;
+  }
+
+  std::string perspective_string = args[0];
+  quic::Perspective perspective;
+  if (perspective_string == "client") {
+    perspective = quic::Perspective::IS_CLIENT;
+  } else if (perspective_string == "server") {
+    perspective = quic::Perspective::IS_SERVER;
+  } else {
+    std::cerr << "Invalid perspective" << std::endl;
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    return 1;
+  }
+  std::string hex = absl::HexStringToBytes(args[1]);
+  quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
+  // Fake a time since we're not actually generating acks.
+  quic::QuicTime start(quic::QuicTime::Zero());
+  quic::QuicFramer framer(versions, start, perspective,
+                          quic::kQuicDefaultConnectionIdLength);
+  const quic::ParsedQuicVersion& version =
+      quic::ParseQuicVersionString(GetQuicFlag(FLAGS_quic_version));
+  if (version != quic::ParsedQuicVersion::Unsupported()) {
+    framer.set_version(version);
+  }
+  quic::QuicPacketPrinter visitor(&framer);
+  framer.set_visitor(&visitor);
+  quic::QuicEncryptedPacket encrypted(hex.c_str(), hex.length());
+  return framer.ProcessPacket(encrypted);
+}
diff --git a/quiche/quic/tools/quic_reject_reason_decoder_bin.cc b/quiche/quic/tools/quic_reject_reason_decoder_bin.cc
new file mode 100644
index 0000000..661e3d9
--- /dev/null
+++ b/quiche/quic/tools/quic_reject_reason_decoder_bin.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Decodes the packet HandshakeFailureReason from the chromium histogram
+// Net.QuicClientHelloRejectReasons
+
+#include <iostream>
+
+#include "absl/strings/numbers.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using quic::CryptoUtils;
+using quic::HandshakeFailureReason;
+using quic::MAX_FAILURE_REASON;
+
+int main(int argc, char* argv[]) {
+  const char* usage = "Usage: quic_reject_reason_decoder <packed_reason>";
+  std::vector<std::string> args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+
+  if (args.size() != 1) {
+    std::cerr << usage << std::endl;
+    return 1;
+  }
+
+  uint32_t packed_error = 0;
+  if (!absl::SimpleAtoi(args[0], &packed_error)) {
+    std::cerr << "Unable to parse: " << args[0] << "\n";
+    return 2;
+  }
+
+  for (int i = 1; i < MAX_FAILURE_REASON; ++i) {
+    if ((packed_error & (1 << (i - 1))) == 0) {
+      continue;
+    }
+    HandshakeFailureReason reason = static_cast<HandshakeFailureReason>(i);
+    std::cout << CryptoUtils::HandshakeFailureReasonToString(reason) << "\n";
+  }
+  return 0;
+}
diff --git a/quiche/quic/tools/quic_server.cc b/quiche/quic/tools/quic_server.cc
new file mode 100644
index 0000000..aa521ef
--- /dev/null
+++ b/quiche/quic/tools/quic_server.cc
@@ -0,0 +1,221 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_server.h"
+
+#include <errno.h>
+#include <features.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+
+#include <cstdint>
+#include <memory>
+
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_crypto_stream.h"
+#include "quiche/quic/core/quic_data_reader.h"
+#include "quiche/quic/core/quic_default_packet_writer.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_clock.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_packet_reader.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+#include "quiche/quic/tools/quic_simple_dispatcher.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+
+namespace quic {
+
+namespace {
+
+const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
+const char kSourceAddressTokenSecret[] = "secret";
+
+}  // namespace
+
+const size_t kNumSessionsToCreatePerSocketEvent = 16;
+
+QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
+                       QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicServer(std::move(proof_source),
+                 quic_simple_server_backend,
+                 AllSupportedVersions()) {}
+
+QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
+                       QuicSimpleServerBackend* quic_simple_server_backend,
+                       const ParsedQuicVersionVector& supported_versions)
+    : QuicServer(std::move(proof_source),
+                 QuicConfig(),
+                 QuicCryptoServerConfig::ConfigOptions(),
+                 supported_versions,
+                 quic_simple_server_backend,
+                 kQuicDefaultConnectionIdLength) {}
+
+QuicServer::QuicServer(
+    std::unique_ptr<ProofSource> proof_source,
+    const QuicConfig& config,
+    const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
+    const ParsedQuicVersionVector& supported_versions,
+    QuicSimpleServerBackend* quic_simple_server_backend,
+    uint8_t expected_server_connection_id_length)
+    : port_(0),
+      fd_(-1),
+      packets_dropped_(0),
+      overflow_supported_(false),
+      silent_close_(false),
+      config_(config),
+      crypto_config_(kSourceAddressTokenSecret,
+                     QuicRandom::GetInstance(),
+                     std::move(proof_source),
+                     KeyExchangeSource::Default()),
+      crypto_config_options_(crypto_config_options),
+      version_manager_(supported_versions),
+      packet_reader_(new QuicPacketReader()),
+      quic_simple_server_backend_(quic_simple_server_backend),
+      expected_server_connection_id_length_(
+          expected_server_connection_id_length) {
+  QUICHE_DCHECK(quic_simple_server_backend_);
+  Initialize();
+}
+
+void QuicServer::Initialize() {
+  // If an initial flow control window has not explicitly been set, then use a
+  // sensible value for a server: 1 MB for session, 64 KB for each stream.
+  const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024;  // 1 MB
+  const uint32_t kInitialStreamFlowControlWindow = 64 * 1024;         // 64 KB
+  if (config_.GetInitialStreamFlowControlWindowToSend() ==
+      kDefaultFlowControlSendWindow) {
+    config_.SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindow);
+  }
+  if (config_.GetInitialSessionFlowControlWindowToSend() ==
+      kDefaultFlowControlSendWindow) {
+    config_.SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindow);
+  }
+
+  epoll_server_.set_timeout_in_us(50 * 1000);
+
+  QuicEpollClock clock(&epoll_server_);
+
+  std::unique_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
+      QuicRandom::GetInstance(), &clock, crypto_config_options_));
+}
+
+QuicServer::~QuicServer() = default;
+
+bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
+  QuicUdpSocketApi socket_api;
+  fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
+                          /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
+                          /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
+  if (fd_ == kQuicInvalidSocketFd) {
+    QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+    return false;
+  }
+
+  overflow_supported_ = socket_api.EnableDroppedPacketCount(fd_);
+  socket_api.EnableReceiveTimestamp(fd_);
+
+  sockaddr_storage addr = address.generic_address();
+  int rc = bind(fd_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
+  if (rc < 0) {
+    QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
+    return false;
+  }
+  QUIC_LOG(INFO) << "Listening on " << address.ToString();
+  port_ = address.port();
+  if (port_ == 0) {
+    QuicSocketAddress address;
+    if (address.FromSocket(fd_) != 0) {
+      QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
+                      << strerror(errno);
+    }
+    port_ = address.port();
+  }
+
+  epoll_server_.RegisterFD(fd_, this, kEpollFlags);
+  dispatcher_.reset(CreateQuicDispatcher());
+  dispatcher_->InitializeWithWriter(CreateWriter(fd_));
+
+  return true;
+}
+
+QuicPacketWriter* QuicServer::CreateWriter(int fd) {
+  return new QuicDefaultPacketWriter(fd);
+}
+
+QuicDispatcher* QuicServer::CreateQuicDispatcher() {
+  QuicEpollAlarmFactory alarm_factory(&epoll_server_);
+  return new QuicSimpleDispatcher(
+      &config_, &crypto_config_, &version_manager_,
+      std::unique_ptr<QuicEpollConnectionHelper>(new QuicEpollConnectionHelper(
+          &epoll_server_, QuicAllocator::BUFFER_POOL)),
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+          new QuicSimpleCryptoServerStreamHelper()),
+      std::unique_ptr<QuicEpollAlarmFactory>(
+          new QuicEpollAlarmFactory(&epoll_server_)),
+      quic_simple_server_backend_, expected_server_connection_id_length_);
+}
+
+void QuicServer::HandleEventsForever() {
+  while (true) {
+    WaitForEvents();
+  }
+}
+
+void QuicServer::WaitForEvents() {
+  epoll_server_.WaitForEventsAndExecuteCallbacks();
+}
+
+void QuicServer::Shutdown() {
+  if (!silent_close_) {
+    // Before we shut down the epoll server, give all active sessions a chance
+    // to notify clients that they're closing.
+    dispatcher_->Shutdown();
+  }
+
+  epoll_server_.Shutdown();
+
+  close(fd_);
+  fd_ = -1;
+}
+
+void QuicServer::OnEvent(int fd, QuicEpollEvent* event) {
+  QUICHE_DCHECK_EQ(fd, fd_);
+  event->out_ready_mask = 0;
+
+  if (event->in_events & EPOLLIN) {
+    QUIC_DVLOG(1) << "EPOLLIN";
+
+    dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
+
+    bool more_to_read = true;
+    while (more_to_read) {
+      more_to_read = packet_reader_->ReadAndDispatchPackets(
+          fd_, port_, QuicEpollClock(&epoll_server_), dispatcher_.get(),
+          overflow_supported_ ? &packets_dropped_ : nullptr);
+    }
+
+    if (dispatcher_->HasChlosBuffered()) {
+      // Register EPOLLIN event to consume buffered CHLO(s).
+      event->out_ready_mask |= EPOLLIN;
+    }
+  }
+  if (event->in_events & EPOLLOUT) {
+    dispatcher_->OnCanWrite();
+    if (dispatcher_->HasPendingWrites()) {
+      event->out_ready_mask |= EPOLLOUT;
+    }
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_server.h b/quiche/quic/tools/quic_server.h
new file mode 100644
index 0000000..9024289
--- /dev/null
+++ b/quiche/quic/tools/quic_server.h
@@ -0,0 +1,171 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A toy server, which listens on a specified address for QUIC traffic and
+// handles incoming responses.
+//
+// Note that this server is intended to verify correctness of the client and is
+// in no way expected to be performant.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_framer.h"
+#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_udp_socket.h"
+#include "quiche/quic/core/quic_version_manager.h"
+#include "quiche/quic/platform/api/quic_epoll.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+#include "quiche/quic/tools/quic_spdy_server_base.h"
+
+namespace quic {
+
+namespace test {
+class QuicServerPeer;
+}  // namespace test
+
+class QuicDispatcher;
+class QuicPacketReader;
+
+class QuicServer : public QuicSpdyServerBase,
+                   public QuicEpollCallbackInterface {
+ public:
+  QuicServer(std::unique_ptr<ProofSource> proof_source,
+             QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicServer(std::unique_ptr<ProofSource> proof_source,
+             QuicSimpleServerBackend* quic_simple_server_backend,
+             const ParsedQuicVersionVector& supported_versions);
+  QuicServer(std::unique_ptr<ProofSource> proof_source,
+             const QuicConfig& config,
+             const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
+             const ParsedQuicVersionVector& supported_versions,
+             QuicSimpleServerBackend* quic_simple_server_backend,
+             uint8_t expected_server_connection_id_length);
+  QuicServer(const QuicServer&) = delete;
+  QuicServer& operator=(const QuicServer&) = delete;
+
+  ~QuicServer() override;
+
+  std::string Name() const override { return "QuicServer"; }
+
+  // Start listening on the specified address.
+  bool CreateUDPSocketAndListen(const QuicSocketAddress& address) override;
+  // Handles all events. Does not return.
+  void HandleEventsForever() override;
+
+  // Wait up to 50ms, and handle any events which occur.
+  void WaitForEvents();
+
+  // Server deletion is imminent.  Start cleaning up the epoll server.
+  virtual void Shutdown();
+
+  // From EpollCallbackInterface
+  void OnRegistration(QuicEpollServer* /*eps*/,
+                      int /*fd*/,
+                      int /*event_mask*/) override {}
+  void OnModification(int /*fd*/, int /*event_mask*/) override {}
+  void OnEvent(int /*fd*/, QuicEpollEvent* /*event*/) override;
+  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
+
+  void OnShutdown(QuicEpollServer* /*eps*/, int /*fd*/) override {}
+
+  void SetChloMultiplier(size_t multiplier) {
+    crypto_config_.set_chlo_multiplier(multiplier);
+  }
+
+  void SetPreSharedKey(absl::string_view key) {
+    crypto_config_.set_pre_shared_key(key);
+  }
+
+  bool overflow_supported() { return overflow_supported_; }
+
+  QuicPacketCount packets_dropped() { return packets_dropped_; }
+
+  int port() { return port_; }
+
+  QuicEpollServer* epoll_server() { return &epoll_server_; }
+
+ protected:
+  virtual QuicPacketWriter* CreateWriter(int fd);
+
+  virtual QuicDispatcher* CreateQuicDispatcher();
+
+  const QuicConfig& config() const { return config_; }
+  const QuicCryptoServerConfig& crypto_config() const { return crypto_config_; }
+
+  QuicDispatcher* dispatcher() { return dispatcher_.get(); }
+
+  QuicVersionManager* version_manager() { return &version_manager_; }
+
+  QuicSimpleServerBackend* server_backend() {
+    return quic_simple_server_backend_;
+  }
+
+  void set_silent_close(bool value) { silent_close_ = value; }
+
+  uint8_t expected_server_connection_id_length() {
+    return expected_server_connection_id_length_;
+  }
+
+ private:
+  friend class quic::test::QuicServerPeer;
+
+  // Initialize the internal state of the server.
+  void Initialize();
+
+  // Accepts data from the framer and demuxes clients to sessions.
+  std::unique_ptr<QuicDispatcher> dispatcher_;
+  // Frames incoming packets and hands them to the dispatcher.
+  QuicEpollServer epoll_server_;
+
+  // The port the server is listening on.
+  int port_;
+
+  // Listening connection.  Also used for outbound client communication.
+  QuicUdpSocketFd fd_;
+
+  // If overflow_supported_ is true this will be the number of packets dropped
+  // during the lifetime of the server.  This may overflow if enough packets
+  // are dropped.
+  QuicPacketCount packets_dropped_;
+
+  // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
+  // because the socket would otherwise overflow.
+  bool overflow_supported_;
+
+  // If true, do not call Shutdown on the dispatcher.  Connections will close
+  // without sending a final connection close.
+  bool silent_close_;
+
+  // config_ contains non-crypto parameters that are negotiated in the crypto
+  // handshake.
+  QuicConfig config_;
+  // crypto_config_ contains crypto parameters for the handshake.
+  QuicCryptoServerConfig crypto_config_;
+  // crypto_config_options_ contains crypto parameters for the handshake.
+  QuicCryptoServerConfig::ConfigOptions crypto_config_options_;
+
+  // Used to generate current supported versions.
+  QuicVersionManager version_manager_;
+
+  // Point to a QuicPacketReader object on the heap. The reader allocates more
+  // space than allowed on the stack.
+  std::unique_ptr<QuicPacketReader> packet_reader_;
+
+  QuicSimpleServerBackend* quic_simple_server_backend_;  // unowned.
+
+  // Connection ID length expected to be read on incoming IETF short headers.
+  uint8_t expected_server_connection_id_length_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SERVER_H_
diff --git a/quiche/quic/tools/quic_server_bin.cc b/quiche/quic/tools/quic_server_bin.cc
new file mode 100644
index 0000000..b7e587b
--- /dev/null
+++ b/quiche/quic/tools/quic_server_bin.cc
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A binary wrapper for QuicServer.  It listens forever on --port
+// (default 6121) until it's killed or ctrl-cd to death.
+
+#include <vector>
+
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/tools/quic_epoll_server_factory.h"
+#include "quiche/quic/tools/quic_toy_server.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_system_event_loop.h"
+
+int main(int argc, char* argv[]) {
+  quiche::QuicheSystemEventLoop event_loop("quic_server");
+  const char* usage = "Usage: quic_server [options]";
+  std::vector<std::string> non_option_args =
+      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
+  if (!non_option_args.empty()) {
+    quiche::QuichePrintCommandLineFlagHelp(usage);
+    exit(0);
+  }
+
+  quic::QuicToyServer::MemoryCacheBackendFactory backend_factory;
+  quic::QuicEpollServerFactory server_factory;
+  quic::QuicToyServer server(&backend_factory, &server_factory);
+  return server.Start();
+}
diff --git a/quiche/quic/tools/quic_server_test.cc b/quiche/quic/tools/quic_server_test.cc
new file mode 100644
index 0000000..5994689
--- /dev/null
+++ b/quiche/quic/tools/quic_server_test.cc
@@ -0,0 +1,210 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_server.h"
+
+#include "absl/base/macros.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_epoll_alarm_factory.h"
+#include "quiche/quic/core/quic_epoll_connection_helper.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/platform/api/quic_test_loopback.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_quic_dispatcher.h"
+#include "quiche/quic/test_tools/quic_server_peer.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+
+namespace quic {
+namespace test {
+
+using ::testing::_;
+
+namespace {
+
+class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
+ public:
+  MockQuicSimpleDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleDispatcher(config,
+                             crypto_config,
+                             version_manager,
+                             std::move(helper),
+                             std::move(session_helper),
+                             std::move(alarm_factory),
+                             quic_simple_server_backend,
+                             kQuicDefaultConnectionIdLength) {}
+  ~MockQuicSimpleDispatcher() override = default;
+
+  MOCK_METHOD(void, OnCanWrite, (), (override));
+  MOCK_METHOD(bool, HasPendingWrites, (), (const, override));
+  MOCK_METHOD(bool, HasChlosBuffered, (), (const, override));
+  MOCK_METHOD(void, ProcessBufferedChlos, (size_t), (override));
+};
+
+class TestQuicServer : public QuicServer {
+ public:
+  TestQuicServer()
+      : QuicServer(crypto_test_utils::ProofSourceForTesting(),
+                   &quic_simple_server_backend_) {}
+
+  ~TestQuicServer() override = default;
+
+  MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
+
+ protected:
+  QuicDispatcher* CreateQuicDispatcher() override {
+    mock_dispatcher_ = new MockQuicSimpleDispatcher(
+        &config(), &crypto_config(), version_manager(),
+        std::unique_ptr<QuicEpollConnectionHelper>(
+            new QuicEpollConnectionHelper(epoll_server(),
+                                          QuicAllocator::BUFFER_POOL)),
+        std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+            new QuicSimpleCryptoServerStreamHelper()),
+        std::unique_ptr<QuicEpollAlarmFactory>(
+            new QuicEpollAlarmFactory(epoll_server())),
+        &quic_simple_server_backend_);
+    return mock_dispatcher_;
+  }
+
+  MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
+  QuicMemoryCacheBackend quic_simple_server_backend_;
+};
+
+class QuicServerEpollInTest : public QuicTest {
+ public:
+  QuicServerEpollInTest() : server_address_(TestLoopback(), 0) {}
+
+  void StartListening() {
+    server_.CreateUDPSocketAndListen(server_address_);
+    server_address_ = QuicSocketAddress(server_address_.host(), server_.port());
+
+    ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
+
+    if (!server_.overflow_supported()) {
+      QUIC_LOG(WARNING) << "Overflow not supported.  Not testing.";
+      return;
+    }
+  }
+
+ protected:
+  QuicSocketAddress server_address_;
+  TestQuicServer server_;
+};
+
+// Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
+// event should try to create connections for them. And set epoll mask with
+// EPOLLIN if there are still CHLOs remaining at the end of epoll event.
+TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
+  // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
+  // event, dispatcher can't create session for all of CHLOs. So listener should
+  // register another EPOLLIN event by itself. Even without new packet arrival,
+  // the rest CHLOs should be process in next epoll event.
+  StartListening();
+  bool more_chlos = true;
+  MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
+  QUICHE_DCHECK(dispatcher_ != nullptr);
+  EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
+  EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
+  EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
+  // Expect there are still CHLOs buffered after 1st event. But not any more
+  // after 2nd event.
+  EXPECT_CALL(*dispatcher_, HasChlosBuffered())
+      .WillOnce(testing::Return(true))
+      .WillOnce(
+          DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
+
+  // Send a packet to trigger epoll event.
+  int fd = socket(
+      AddressFamilyUnderTest() == IpAddressFamily::IP_V4 ? AF_INET : AF_INET6,
+      SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
+  ASSERT_LT(0, fd);
+
+  char buf[1024];
+  memset(buf, 0, ABSL_ARRAYSIZE(buf));
+  sockaddr_storage storage = server_address_.generic_address();
+  int rc = sendto(fd, buf, ABSL_ARRAYSIZE(buf), 0,
+                  reinterpret_cast<sockaddr*>(&storage), sizeof(storage));
+  if (rc < 0) {
+    QUIC_DLOG(INFO) << errno << " " << strerror(errno);
+  }
+
+  while (more_chlos) {
+    server_.WaitForEvents();
+  }
+}
+
+class QuicServerDispatchPacketTest : public QuicTest {
+ public:
+  QuicServerDispatchPacketTest()
+      : crypto_config_("blah",
+                       QuicRandom::GetInstance(),
+                       crypto_test_utils::ProofSourceForTesting(),
+                       KeyExchangeSource::Default()),
+        version_manager_(AllSupportedVersions()),
+        dispatcher_(
+            &config_,
+            &crypto_config_,
+            &version_manager_,
+            std::unique_ptr<QuicEpollConnectionHelper>(
+                new QuicEpollConnectionHelper(&eps_,
+                                              QuicAllocator::BUFFER_POOL)),
+            std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
+                new QuicSimpleCryptoServerStreamHelper()),
+            std::unique_ptr<QuicEpollAlarmFactory>(
+                new QuicEpollAlarmFactory(&eps_)),
+            &quic_simple_server_backend_) {
+    dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
+  }
+
+  void DispatchPacket(const QuicReceivedPacket& packet) {
+    QuicSocketAddress client_addr, server_addr;
+    dispatcher_.ProcessPacket(server_addr, client_addr, packet);
+  }
+
+ protected:
+  QuicConfig config_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicVersionManager version_manager_;
+  QuicEpollServer eps_;
+  QuicMemoryCacheBackend quic_simple_server_backend_;
+  MockQuicDispatcher dispatcher_;
+};
+
+TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
+  // clang-format off
+  unsigned char valid_packet[] = {
+    // public flags (8 byte connection_id)
+    0x3C,
+    // connection_id
+    0x10, 0x32, 0x54, 0x76,
+    0x98, 0xBA, 0xDC, 0xFE,
+    // packet number
+    0xBC, 0x9A, 0x78, 0x56,
+    0x34, 0x12,
+    // private flags
+    0x00
+  };
+  // clang-format on
+  QuicReceivedPacket encrypted_valid_packet(
+      reinterpret_cast<char*>(valid_packet), ABSL_ARRAYSIZE(valid_packet),
+      QuicTime::Zero(), false);
+
+  EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
+  DispatchPacket(encrypted_valid_packet);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_client_session.cc b/quiche/quic/tools/quic_simple_client_session.cc
new file mode 100644
index 0000000..fa211ac
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_client_session.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_client_session.h"
+
+#include <utility>
+
+namespace quic {
+
+QuicSimpleClientSession::QuicSimpleClientSession(
+    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection, const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body)
+    : QuicSimpleClientSession(config, supported_versions, connection, server_id,
+                              crypto_config, push_promise_index,
+                              drop_response_body,
+                              /*enable_web_transport=*/false,
+                              /*use_datagram_contexts=*/false) {}
+
+QuicSimpleClientSession::QuicSimpleClientSession(
+    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection, const QuicServerId& server_id,
+    QuicCryptoClientConfig* crypto_config,
+    QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body,
+    bool enable_web_transport, bool use_datagram_contexts)
+    : QuicSpdyClientSession(config, supported_versions, connection, server_id,
+                            crypto_config, push_promise_index),
+      drop_response_body_(drop_response_body),
+      enable_web_transport_(enable_web_transport),
+      use_datagram_contexts_(use_datagram_contexts) {}
+
+std::unique_ptr<QuicSpdyClientStream>
+QuicSimpleClientSession::CreateClientStream() {
+  return std::make_unique<QuicSimpleClientStream>(
+      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
+      drop_response_body_);
+}
+
+bool QuicSimpleClientSession::ShouldNegotiateWebTransport() {
+  return enable_web_transport_;
+}
+
+bool QuicSimpleClientSession::ShouldNegotiateDatagramContexts() {
+  return use_datagram_contexts_;
+}
+
+HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() {
+  return enable_web_transport_ ? HttpDatagramSupport::kDraft04
+                               : HttpDatagramSupport::kNone;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_client_session.h b/quiche/quic/tools/quic_simple_client_session.h
new file mode 100644
index 0000000..75ed195
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_client_session.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
+
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/tools/quic_simple_client_stream.h"
+
+namespace quic {
+
+class QuicSimpleClientSession : public QuicSpdyClientSession {
+ public:
+  QuicSimpleClientSession(const QuicConfig& config,
+                          const ParsedQuicVersionVector& supported_versions,
+                          QuicConnection* connection,
+                          const QuicServerId& server_id,
+                          QuicCryptoClientConfig* crypto_config,
+                          QuicClientPushPromiseIndex* push_promise_index,
+                          bool drop_response_body);
+  QuicSimpleClientSession(const QuicConfig& config,
+                          const ParsedQuicVersionVector& supported_versions,
+                          QuicConnection* connection,
+                          const QuicServerId& server_id,
+                          QuicCryptoClientConfig* crypto_config,
+                          QuicClientPushPromiseIndex* push_promise_index,
+                          bool drop_response_body, bool enable_web_transport,
+                          bool use_datagram_contexts);
+
+  std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override;
+  bool ShouldNegotiateWebTransport() override;
+  bool ShouldNegotiateDatagramContexts() override;
+  HttpDatagramSupport LocalHttpDatagramSupport() override;
+
+ private:
+  const bool drop_response_body_;
+  const bool enable_web_transport_;
+  const bool use_datagram_contexts_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
diff --git a/quiche/quic/tools/quic_simple_client_stream.cc b/quiche/quic/tools/quic_simple_client_stream.cc
new file mode 100644
index 0000000..14de9f0
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_client_stream.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_client_stream.h"
+
+namespace quic {
+
+void QuicSimpleClientStream::OnBodyAvailable() {
+  if (!drop_response_body_) {
+    QuicSpdyClientStream::OnBodyAvailable();
+    return;
+  }
+
+  while (HasBytesToRead()) {
+    struct iovec iov;
+    if (GetReadableRegions(&iov, 1) == 0) {
+      break;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  if (sequencer()->IsClosed()) {
+    OnFinRead();
+  } else {
+    sequencer()->SetUnblocked();
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_client_stream.h b/quiche/quic/tools/quic_simple_client_stream.h
new file mode 100644
index 0000000..a68b7cb
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_client_stream.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
+
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+
+namespace quic {
+
+class QuicSimpleClientStream : public QuicSpdyClientStream {
+ public:
+  QuicSimpleClientStream(QuicStreamId id,
+                         QuicSpdyClientSession* session,
+                         StreamType type,
+                         bool drop_response_body)
+      : QuicSpdyClientStream(id, session, type),
+        drop_response_body_(drop_response_body) {}
+  void OnBodyAvailable() override;
+
+ private:
+  const bool drop_response_body_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_STREAM_H_
diff --git a/quiche/quic/tools/quic_simple_crypto_server_stream_helper.cc b/quiche/quic/tools/quic_simple_crypto_server_stream_helper.cc
new file mode 100644
index 0000000..08d63b7
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_crypto_server_stream_helper.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+
+#include "quiche/quic/core/quic_utils.h"
+
+namespace quic {
+
+QuicSimpleCryptoServerStreamHelper::QuicSimpleCryptoServerStreamHelper() =
+    default;
+
+QuicSimpleCryptoServerStreamHelper::~QuicSimpleCryptoServerStreamHelper() =
+    default;
+
+bool QuicSimpleCryptoServerStreamHelper::CanAcceptClientHello(
+    const CryptoHandshakeMessage& /*message*/,
+    const QuicSocketAddress& /*client_address*/,
+    const QuicSocketAddress& /*peer_address*/,
+    const QuicSocketAddress& /*self_address*/,
+    std::string* /*error_details*/) const {
+  return true;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_crypto_server_stream_helper.h b/quiche/quic/tools/quic_simple_crypto_server_stream_helper.h
new file mode 100644
index 0000000..ba64226
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_crypto_server_stream_helper.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+
+namespace quic {
+
+// Simple helper for server crypto streams which generates a new random
+// connection ID for rejects.
+class QuicSimpleCryptoServerStreamHelper
+    : public QuicCryptoServerStreamBase::Helper {
+ public:
+  QuicSimpleCryptoServerStreamHelper();
+
+  ~QuicSimpleCryptoServerStreamHelper() override;
+
+  bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
+                            const QuicSocketAddress& client_address,
+                            const QuicSocketAddress& peer_address,
+                            const QuicSocketAddress& self_address,
+                            std::string* error_details) const override;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CRYPTO_SERVER_STREAM_HELPER_H_
diff --git a/quiche/quic/tools/quic_simple_dispatcher.cc b/quiche/quic/tools/quic_simple_dispatcher.cc
new file mode 100644
index 0000000..b820864
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_dispatcher.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_dispatcher.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/tools/quic_simple_server_session.h"
+
+namespace quic {
+
+QuicSimpleDispatcher::QuicSimpleDispatcher(
+    const QuicConfig* config,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicVersionManager* version_manager,
+    std::unique_ptr<QuicConnectionHelperInterface> helper,
+    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+    std::unique_ptr<QuicAlarmFactory> alarm_factory,
+    QuicSimpleServerBackend* quic_simple_server_backend,
+    uint8_t expected_server_connection_id_length)
+    : QuicDispatcher(config,
+                     crypto_config,
+                     version_manager,
+                     std::move(helper),
+                     std::move(session_helper),
+                     std::move(alarm_factory),
+                     expected_server_connection_id_length),
+      quic_simple_server_backend_(quic_simple_server_backend) {}
+
+QuicSimpleDispatcher::~QuicSimpleDispatcher() = default;
+
+int QuicSimpleDispatcher::GetRstErrorCount(
+    QuicRstStreamErrorCode error_code) const {
+  auto it = rst_error_map_.find(error_code);
+  if (it == rst_error_map_.end()) {
+    return 0;
+  }
+  return it->second;
+}
+
+void QuicSimpleDispatcher::OnRstStreamReceived(
+    const QuicRstStreamFrame& frame) {
+  auto it = rst_error_map_.find(frame.error_code);
+  if (it == rst_error_map_.end()) {
+    rst_error_map_.insert(std::make_pair(frame.error_code, 1));
+  } else {
+    it->second++;
+  }
+}
+
+std::unique_ptr<QuicSession> QuicSimpleDispatcher::CreateQuicSession(
+    QuicConnectionId connection_id, const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
+    const ParsedQuicVersion& version,
+    const ParsedClientHello& /*parsed_chlo*/) {
+  // The QuicServerSessionBase takes ownership of |connection| below.
+  QuicConnection* connection =
+      new QuicConnection(connection_id, self_address, peer_address, helper(),
+                         alarm_factory(), writer(),
+                         /* owns_writer= */ false, Perspective::IS_SERVER,
+                         ParsedQuicVersionVector{version});
+
+  auto session = std::make_unique<QuicSimpleServerSession>(
+      config(), GetSupportedVersions(), connection, this, session_helper(),
+      crypto_config(), compressed_certs_cache(), quic_simple_server_backend_);
+  session->Initialize();
+  return session;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_dispatcher.h b/quiche/quic/tools/quic_simple_dispatcher.h
new file mode 100644
index 0000000..ee80955
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_dispatcher.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_server_session_base.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+
+namespace quic {
+
+class QuicSimpleDispatcher : public QuicDispatcher {
+ public:
+  QuicSimpleDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      QuicSimpleServerBackend* quic_simple_server_backend,
+      uint8_t expected_server_connection_id_length);
+
+  ~QuicSimpleDispatcher() override;
+
+  int GetRstErrorCount(QuicRstStreamErrorCode rst_error_code) const;
+
+  void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
+
+ protected:
+  std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId connection_id, const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version,
+      const ParsedClientHello& parsed_chlo) override;
+
+  QuicSimpleServerBackend* server_backend() {
+    return quic_simple_server_backend_;
+  }
+
+ private:
+  QuicSimpleServerBackend* quic_simple_server_backend_;  // Unowned.
+
+  // The map of the reset error code with its counter.
+  std::map<QuicRstStreamErrorCode, int> rst_error_map_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_DISPATCHER_H_
diff --git a/quiche/quic/tools/quic_simple_server_backend.h b/quiche/quic/tools/quic_simple_server_backend.h
new file mode 100644
index 0000000..b0e1d8f
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_backend.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
+
+#include <memory>
+
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace quic {
+
+// This interface implements the functionality to fetch a response
+// from the backend (such as cache, http-proxy etc) to serve
+// requests received by a Quic Server
+class QuicSimpleServerBackend {
+ public:
+  // This interface implements the methods
+  // called by the QuicSimpleServerBackend implementation
+  // to process the request in the backend
+  class RequestHandler {
+   public:
+    virtual ~RequestHandler() {}
+
+    virtual QuicConnectionId connection_id() const = 0;
+    virtual QuicStreamId stream_id() const = 0;
+    virtual std::string peer_host() const = 0;
+    // Called when the response is ready at the backend and can be send back to
+    // the QUIC client.
+    virtual void OnResponseBackendComplete(
+        const QuicBackendResponse* response) = 0;
+  };
+
+  struct WebTransportResponse {
+    spdy::Http2HeaderBlock response_headers;
+    std::unique_ptr<WebTransportVisitor> visitor;
+  };
+
+  virtual ~QuicSimpleServerBackend() = default;
+  // This method initializes the backend instance to fetch responses
+  // from a backend server, in-memory cache etc.
+  virtual bool InitializeBackend(const std::string& backend_url) = 0;
+  // Returns true if the backend has been successfully initialized
+  // and could be used to fetch HTTP requests
+  virtual bool IsBackendInitialized() const = 0;
+  // Triggers a HTTP request to be sent to the backend server or cache
+  // If response is immediately available, the function synchronously calls
+  // the |request_handler| with the HTTP response.
+  // If the response has to be fetched over the network, the function
+  // asynchronously calls |request_handler| with the HTTP response.
+  virtual void FetchResponseFromBackend(
+      const spdy::Http2HeaderBlock& request_headers,
+      const std::string& request_body,
+      RequestHandler* request_handler) = 0;
+  // Clears the state of the backend  instance
+  virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0;
+
+  virtual WebTransportResponse ProcessWebTransportRequest(
+      const spdy::Http2HeaderBlock& /*request_headers*/,
+      WebTransportSession* /*session*/) {
+    WebTransportResponse response;
+    response.response_headers[":status"] = "400";
+    return response;
+  }
+  virtual bool SupportsWebTransport() { return false; }
+  virtual bool UsesDatagramContexts() { return false; }
+  virtual bool SupportsExtendedConnect() { return true; }
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
diff --git a/quiche/quic/tools/quic_simple_server_session.cc b/quiche/quic/tools/quic_simple_server_session.cc
new file mode 100644
index 0000000..15e43b9
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_session.cc
@@ -0,0 +1,225 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_server_session.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "quiche/quic/core/http/quic_server_initiated_spdy_stream.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+namespace quic {
+
+QuicSimpleServerSession::QuicSimpleServerSession(
+    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection, QuicSession::Visitor* visitor,
+    QuicCryptoServerStreamBase::Helper* helper,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicServerSessionBase(config, supported_versions, connection, visitor,
+                            helper, crypto_config, compressed_certs_cache),
+      highest_promised_stream_id_(
+          QuicUtils::GetInvalidStreamId(connection->transport_version())),
+      quic_simple_server_backend_(quic_simple_server_backend) {
+  QUICHE_DCHECK(quic_simple_server_backend_);
+}
+
+QuicSimpleServerSession::~QuicSimpleServerSession() { DeleteConnection(); }
+
+std::unique_ptr<QuicCryptoServerStreamBase>
+QuicSimpleServerSession::CreateQuicCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache) {
+  return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
+                                  stream_helper());
+}
+
+void QuicSimpleServerSession::OnStreamFrame(const QuicStreamFrame& frame) {
+  if (!IsIncomingStream(frame.stream_id) && !WillNegotiateWebTransport()) {
+    QUIC_LOG(WARNING) << "Client shouldn't send data on server push stream";
+    connection()->CloseConnection(
+        QUIC_INVALID_STREAM_ID, "Client sent data on server push stream",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+  QuicSpdySession::OnStreamFrame(frame);
+}
+
+QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(QuicStreamId id) {
+  if (!ShouldCreateIncomingStream(id)) {
+    return nullptr;
+  }
+
+  QuicSpdyStream* stream = new QuicSimpleServerStream(
+      id, this, BIDIRECTIONAL, quic_simple_server_backend_);
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(
+    PendingStream* pending) {
+  QuicSpdyStream* stream =
+      new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+QuicSpdyStream* QuicSimpleServerSession::CreateOutgoingBidirectionalStream() {
+  if (!WillNegotiateWebTransport()) {
+    QUIC_BUG(QuicSimpleServerSession CreateOutgoingBidirectionalStream without
+                 WebTransport support)
+        << "QuicSimpleServerSession::CreateOutgoingBidirectionalStream called "
+           "in a session without WebTransport support.";
+    return nullptr;
+  }
+  if (!ShouldCreateOutgoingBidirectionalStream()) {
+    return nullptr;
+  }
+
+  QuicServerInitiatedSpdyStream* stream = new QuicServerInitiatedSpdyStream(
+      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+QuicSimpleServerStream*
+QuicSimpleServerSession::CreateOutgoingUnidirectionalStream() {
+  if (!ShouldCreateOutgoingUnidirectionalStream()) {
+    return nullptr;
+  }
+
+  QuicSimpleServerStream* stream = new QuicSimpleServerStream(
+      GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
+      quic_simple_server_backend_);
+  ActivateStream(absl::WrapUnique(stream));
+  return stream;
+}
+
+void QuicSimpleServerSession::HandleFrameOnNonexistentOutgoingStream(
+    QuicStreamId stream_id) {
+  // If this stream is a promised but not created stream (stream_id within the
+  // range of next_outgoing_stream_id_ and highes_promised_stream_id_),
+  // connection shouldn't be closed.
+  // Otherwise behave in the same way as base class.
+  if (highest_promised_stream_id_ ==
+          QuicUtils::GetInvalidStreamId(transport_version()) ||
+      stream_id > highest_promised_stream_id_) {
+    QuicSession::HandleFrameOnNonexistentOutgoingStream(stream_id);
+  }
+}
+
+void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
+    const QuicRstStreamFrame& frame) {
+  QuicSession::HandleRstOnValidNonexistentStream(frame);
+  if (!IsClosedStream(frame.stream_id)) {
+    // If a nonexistent stream is not a closed stream and still valid, it must
+    // be a locally preserved stream. Resetting this kind of stream means
+    // cancelling the promised server push.
+    // Since PromisedStreamInfo are queued in sequence, the corresponding
+    // index for it in promised_streams_ can be calculated.
+    QuicStreamId next_stream_id = next_outgoing_unidirectional_stream_id();
+    if ((!version().HasIetfQuicFrames() ||
+         !QuicUtils::IsBidirectionalStreamId(frame.stream_id, version())) &&
+        frame.stream_id >= next_stream_id) {
+      size_t index = (frame.stream_id - next_stream_id) /
+                     QuicUtils::StreamIdDelta(transport_version());
+      if (index < promised_streams_.size()) {
+        promised_streams_[index].is_cancelled = true;
+      }
+    }
+    control_frame_manager().WriteOrBufferRstStream(
+        frame.stream_id,
+        QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 0);
+    connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
+  }
+}
+
+spdy::Http2HeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders(
+    std::string request_url, QuicBackendResponse::ServerPushInfo resource,
+    const spdy::Http2HeaderBlock& original_request_headers) {
+  QuicUrl push_request_url = resource.request_url;
+
+  spdy::Http2HeaderBlock spdy_headers = original_request_headers.Clone();
+  // :authority could be different from original request.
+  spdy_headers[":authority"] = push_request_url.host();
+  spdy_headers[":path"] = push_request_url.path();
+  // Push request always use GET.
+  spdy_headers[":method"] = "GET";
+  spdy_headers["referer"] = request_url;
+  spdy_headers[":scheme"] = push_request_url.scheme();
+  // It is not possible to push a response to a request that includes a request
+  // body.
+  spdy_headers["content-length"] = "0";
+  // Remove "host" field as push request is a directly generated HTTP2 request
+  // which should use ":authority" instead of "host".
+  spdy_headers.erase("host");
+  return spdy_headers;
+}
+
+void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id,
+                                              QuicStreamId promised_stream_id,
+                                              spdy::Http2HeaderBlock headers) {
+  QUIC_DLOG(INFO) << "stream " << original_stream_id
+                  << " send PUSH_PROMISE for promised stream "
+                  << promised_stream_id;
+  WritePushPromise(original_stream_id, promised_stream_id, std::move(headers));
+}
+
+void QuicSimpleServerSession::HandlePromisedPushRequests() {
+  while (!promised_streams_.empty() &&
+         ShouldCreateOutgoingUnidirectionalStream()) {
+    PromisedStreamInfo& promised_info = promised_streams_.front();
+    QUICHE_DCHECK_EQ(next_outgoing_unidirectional_stream_id(),
+                     promised_info.stream_id);
+
+    if (promised_info.is_cancelled) {
+      // This stream has been reset by client. Skip this stream id.
+      promised_streams_.pop_front();
+      GetNextOutgoingUnidirectionalStreamId();
+      return;
+    }
+
+    QuicSimpleServerStream* promised_stream =
+        static_cast<QuicSimpleServerStream*>(
+            CreateOutgoingUnidirectionalStream());
+    QUICHE_DCHECK_NE(promised_stream, nullptr);
+    QUICHE_DCHECK_EQ(promised_info.stream_id, promised_stream->id());
+    QUIC_DLOG(INFO) << "created server push stream " << promised_stream->id();
+
+    promised_stream->SetPriority(promised_info.precedence);
+
+    spdy::Http2HeaderBlock request_headers(
+        std::move(promised_info.request_headers));
+
+    promised_streams_.pop_front();
+    promised_stream->PushResponse(std::move(request_headers));
+  }
+}
+
+void QuicSimpleServerSession::OnCanCreateNewOutgoingStream(
+    bool unidirectional) {
+  QuicSpdySession::OnCanCreateNewOutgoingStream(unidirectional);
+  if (unidirectional) {
+    HandlePromisedPushRequests();
+  }
+}
+
+void QuicSimpleServerSession::MaybeInitializeHttp3UnidirectionalStreams() {
+  size_t previous_static_stream_count = num_static_streams();
+  QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams();
+  size_t current_static_stream_count = num_static_streams();
+  QUICHE_DCHECK_GE(current_static_stream_count, previous_static_stream_count);
+  highest_promised_stream_id_ +=
+      QuicUtils::StreamIdDelta(transport_version()) *
+      (current_static_stream_count - previous_static_stream_count);
+}
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_server_session.h b/quiche/quic/tools/quic_simple_server_session.h
new file mode 100644
index 0000000..950da18
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_session.h
@@ -0,0 +1,160 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A toy server specific QuicSession subclass.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
+
+#include <stdint.h>
+
+#include <list>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/core/http/quic_server_session_base.h"
+#include "quiche/quic/core/http/quic_spdy_session.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+namespace quic {
+
+namespace test {
+class QuicSimpleServerSessionPeer;
+}  // namespace test
+
+class QuicSimpleServerSession : public QuicServerSessionBase {
+ public:
+  // A PromisedStreamInfo is an element of the queue to store promised
+  // stream which hasn't been created yet. It keeps a mapping between promised
+  // stream id with its priority and the headers sent out in PUSH_PROMISE.
+  struct PromisedStreamInfo {
+   public:
+    PromisedStreamInfo(spdy::Http2HeaderBlock request_headers,
+                       QuicStreamId stream_id,
+                       const spdy::SpdyStreamPrecedence& precedence)
+        : request_headers(std::move(request_headers)),
+          stream_id(stream_id),
+          precedence(precedence),
+          is_cancelled(false) {}
+    spdy::Http2HeaderBlock request_headers;
+    QuicStreamId stream_id;
+    spdy::SpdyStreamPrecedence precedence;
+    bool is_cancelled;
+  };
+
+  // Takes ownership of |connection|.
+  QuicSimpleServerSession(const QuicConfig& config,
+                          const ParsedQuicVersionVector& supported_versions,
+                          QuicConnection* connection,
+                          QuicSession::Visitor* visitor,
+                          QuicCryptoServerStreamBase::Helper* helper,
+                          const QuicCryptoServerConfig* crypto_config,
+                          QuicCompressedCertsCache* compressed_certs_cache,
+                          QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicSimpleServerSession(const QuicSimpleServerSession&) = delete;
+  QuicSimpleServerSession& operator=(const QuicSimpleServerSession&) = delete;
+
+  ~QuicSimpleServerSession() override;
+
+  // Override base class to detact client sending data on server push stream.
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+
+  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
+
+  bool ShouldNegotiateDatagramContexts() override {
+    return quic_simple_server_backend_->UsesDatagramContexts();
+  }
+
+ protected:
+  // QuicSession methods:
+  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
+  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override;
+  QuicSpdyStream* CreateOutgoingBidirectionalStream() override;
+  QuicSimpleServerStream* CreateOutgoingUnidirectionalStream() override;
+  // Override to return true for locally preserved server push stream.
+  void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
+  // Override to handle reseting locally preserved streams.
+  void HandleRstOnValidNonexistentStream(
+      const QuicRstStreamFrame& frame) override;
+
+  // QuicServerSessionBaseMethod:
+  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache) override;
+
+  QuicSimpleServerBackend* server_backend() {
+    return quic_simple_server_backend_;
+  }
+
+  void MaybeInitializeHttp3UnidirectionalStreams() override;
+
+  bool ShouldNegotiateWebTransport() override {
+    return quic_simple_server_backend_->SupportsWebTransport();
+  }
+  HttpDatagramSupport LocalHttpDatagramSupport() override {
+    if (ShouldNegotiateWebTransport()) {
+      return HttpDatagramSupport::kDraft00And04;
+    }
+    return QuicServerSessionBase::LocalHttpDatagramSupport();
+  }
+
+ private:
+  friend class test::QuicSimpleServerSessionPeer;
+
+  // Create a server push headers block by copying request's headers block.
+  // But replace or add these pseudo-headers as they are specific to each
+  // request:
+  // :authority, :path, :method, :scheme, referer.
+  // Copying the rest headers ensures they are the same as the original
+  // request, especially cookies.
+  spdy::Http2HeaderBlock SynthesizePushRequestHeaders(
+      std::string request_url,
+      QuicBackendResponse::ServerPushInfo resource,
+      const spdy::Http2HeaderBlock& original_request_headers);
+
+  // Send PUSH_PROMISE frame on headers stream.
+  void SendPushPromise(QuicStreamId original_stream_id,
+                       QuicStreamId promised_stream_id,
+                       spdy::Http2HeaderBlock headers);
+
+  // Fetch response from cache for request headers enqueued into
+  // promised_headers_and_streams_ and send them on dedicated stream until
+  // reaches max_open_stream_ limit.
+  // Called when return value of GetNumOpenOutgoingStreams() changes:
+  //    CloseStreamInner();
+  //    StreamDraining();
+  // Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
+  // return value becasue all push streams are impossible to become locally
+  // closed. Since a locally preserved stream becomes remotely closed after
+  // HandlePromisedPushRequests() starts to process it, and if it is reset
+  // locally afterwards, it will be immediately become closed and never get into
+  // locally_closed_stream_highest_offset_. So all the streams in this map
+  // are not outgoing streams.
+  void HandlePromisedPushRequests();
+
+  // Keep track of the highest stream id which has been sent in PUSH_PROMISE.
+  QuicStreamId highest_promised_stream_id_;
+
+  // Promised streams which hasn't been created yet because of max_open_stream_
+  // limit. New element is added to the end of the queue.
+  // Since outgoing stream is created in sequence, stream_id of each element in
+  // the queue also increases by 2 from previous one's. The front element's
+  // stream_id is always next_outgoing_stream_id_, and the last one is always
+  // highest_promised_stream_id_.
+  quiche::QuicheCircularDeque<PromisedStreamInfo> promised_streams_;
+
+  QuicSimpleServerBackend* quic_simple_server_backend_;  // Not owned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_SESSION_H_
diff --git a/quiche/quic/tools/quic_simple_server_session_test.cc b/quiche/quic/tools/quic_simple_server_session_test.cc
new file mode 100644
index 0000000..2cff502
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_session_test.cc
@@ -0,0 +1,595 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_server_session.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/proto/cached_network_parameters_proto.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_crypto_server_stream.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/core/tls_server_handshaker.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+using testing::_;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+// Data to be sent on a request stream.  In Google QUIC, this is interpreted as
+// DATA payload (there is no framing on request streams).  In IETF QUIC, this is
+// interpreted as HEADERS frame (type 0x1) with payload length 122 ('z').  Since
+// no payload is included, QPACK decoder will not be invoked.
+const char* const kStreamData = "\1z";
+
+}  // namespace
+
+class QuicSimpleServerSessionPeer {
+ public:
+  static void SetCryptoStream(QuicSimpleServerSession* s,
+                              QuicCryptoServerStreamBase* crypto_stream) {
+    s->crypto_stream_.reset(crypto_stream);
+  }
+
+  static QuicSpdyStream* CreateIncomingStream(QuicSimpleServerSession* s,
+                                              QuicStreamId id) {
+    return s->CreateIncomingStream(id);
+  }
+
+  static QuicSimpleServerStream* CreateOutgoingUnidirectionalStream(
+      QuicSimpleServerSession* s) {
+    return s->CreateOutgoingUnidirectionalStream();
+  }
+};
+
+namespace {
+
+const size_t kMaxStreamsForTest = 10;
+
+class MockQuicCryptoServerStream : public QuicCryptoServerStream {
+ public:
+  explicit MockQuicCryptoServerStream(
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicSession* session,
+      QuicCryptoServerStreamBase::Helper* helper)
+      : QuicCryptoServerStream(crypto_config,
+                               compressed_certs_cache,
+                               session,
+                               helper) {}
+  MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
+  MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
+      delete;
+  ~MockQuicCryptoServerStream() override {}
+
+  MOCK_METHOD(void,
+              SendServerConfigUpdate,
+              (const CachedNetworkParameters*),
+              (override));
+
+  bool encryption_established() const override { return true; }
+};
+
+class MockTlsServerHandshaker : public TlsServerHandshaker {
+ public:
+  explicit MockTlsServerHandshaker(QuicSession* session,
+                                   const QuicCryptoServerConfig* crypto_config)
+      : TlsServerHandshaker(session, crypto_config) {}
+  MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
+  MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
+  ~MockTlsServerHandshaker() override {}
+
+  MOCK_METHOD(void,
+              SendServerConfigUpdate,
+              (const CachedNetworkParameters*),
+              (override));
+
+  bool encryption_established() const override { return true; }
+};
+
+QuicCryptoServerStreamBase* CreateMockCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSession* session,
+    QuicCryptoServerStreamBase::Helper* helper) {
+  switch (session->connection()->version().handshake_protocol) {
+    case PROTOCOL_QUIC_CRYPTO:
+      return new MockQuicCryptoServerStream(
+          crypto_config, compressed_certs_cache, session, helper);
+    case PROTOCOL_TLS1_3:
+      return new MockTlsServerHandshaker(session, crypto_config);
+    case PROTOCOL_UNSUPPORTED:
+      break;
+  }
+  QUIC_BUG(quic_bug_10933_1)
+      << "Unknown handshake protocol: "
+      << static_cast<int>(session->connection()->version().handshake_protocol);
+  return nullptr;
+}
+
+class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
+ public:
+  MockQuicConnectionWithSendStreamData(
+      MockQuicConnectionHelper* helper,
+      MockAlarmFactory* alarm_factory,
+      Perspective perspective,
+      const ParsedQuicVersionVector& supported_versions)
+      : MockQuicConnection(helper,
+                           alarm_factory,
+                           perspective,
+                           supported_versions) {
+    auto consume_all_data = [](QuicStreamId /*id*/, size_t write_length,
+                               QuicStreamOffset /*offset*/,
+                               StreamSendingState state) {
+      return QuicConsumedData(write_length, state != NO_FIN);
+    };
+    ON_CALL(*this, SendStreamData(_, _, _, _))
+        .WillByDefault(Invoke(consume_all_data));
+  }
+
+  MOCK_METHOD(QuicConsumedData,
+              SendStreamData,
+              (QuicStreamId id,
+               size_t write_length,
+               QuicStreamOffset offset,
+               StreamSendingState state),
+              (override));
+};
+
+class MockQuicSimpleServerSession : public QuicSimpleServerSession {
+ public:
+  MockQuicSimpleServerSession(
+      const QuicConfig& config,
+      QuicConnection* connection,
+      QuicSession::Visitor* visitor,
+      QuicCryptoServerStreamBase::Helper* helper,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerSession(config,
+                                CurrentSupportedVersions(),
+                                connection,
+                                visitor,
+                                helper,
+                                crypto_config,
+                                compressed_certs_cache,
+                                quic_simple_server_backend) {}
+  // Methods taking non-copyable types like Http2HeaderBlock by value cannot be
+  // mocked directly.
+  void WritePushPromise(QuicStreamId original_stream_id,
+                        QuicStreamId promised_stream_id,
+                        spdy::Http2HeaderBlock headers) override {
+    return WritePushPromiseMock(original_stream_id, promised_stream_id,
+                                headers);
+  }
+  MOCK_METHOD(void,
+              WritePushPromiseMock,
+              (QuicStreamId original_stream_id,
+               QuicStreamId promised_stream_id,
+               const spdy::Http2HeaderBlock& headers),
+              ());
+
+  MOCK_METHOD(void, SendBlocked, (QuicStreamId), (override));
+  MOCK_METHOD(bool,
+              WriteControlFrame,
+              (const QuicFrame& frame, TransmissionType type),
+              (override));
+};
+
+class QuicSimpleServerSessionTest
+    : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  // The function ensures that A) the MAX_STREAMS frames get properly deleted
+  // (since the test uses a 'did we leak memory' check ... if we just lose the
+  // frame, the test fails) and B) returns true (instead of the default, false)
+  // which ensures that the rest of the system thinks that the frame actually
+  // was transmitted.
+  bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
+    if (frame.type == MAX_STREAMS_FRAME) {
+      DeleteFrame(&const_cast<QuicFrame&>(frame));
+      return true;
+    }
+    return false;
+  }
+
+ protected:
+  QuicSimpleServerSessionTest()
+      : crypto_config_(QuicCryptoServerConfig::TESTING,
+                       QuicRandom::GetInstance(),
+                       crypto_test_utils::ProofSourceForTesting(),
+                       KeyExchangeSource::Default()),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
+    config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
+    QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
+                                                       kMaxStreamsForTest);
+    config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
+
+    config_.SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialMaxStreamDataBytesUnidirectionalToSend(
+        kInitialStreamFlowControlWindowForTest);
+    config_.SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    if (VersionUsesHttp3(transport_version())) {
+      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
+          &config_, kMaxStreamsForTest + 3);
+    } else {
+      QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
+                                                          kMaxStreamsForTest);
+    }
+
+    ParsedQuicVersionVector supported_versions = SupportedVersions(version());
+    connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
+        &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+    connection_->SetEncrypter(
+        ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<NullEncrypter>(connection_->perspective()));
+    session_ = std::make_unique<MockQuicSimpleServerSession>(
+        config_, connection_, &owner_, &stream_helper_, &crypto_config_,
+        &compressed_certs_cache_, &memory_cache_backend_);
+    MockClock clock;
+    handshake_message_ = crypto_config_.AddDefaultConfig(
+        QuicRandom::GetInstance(), &clock,
+        QuicCryptoServerConfig::ConfigOptions());
+    session_->Initialize();
+
+    if (VersionHasIetfQuicFrames(transport_version())) {
+      EXPECT_CALL(*session_, WriteControlFrame(_, _))
+          .WillRepeatedly(Invoke(&ClearControlFrameWithTransmissionType));
+    }
+    session_->OnConfigNegotiated();
+  }
+
+  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
+    return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
+  }
+
+  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
+    return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
+        transport_version(), n);
+  }
+
+  ParsedQuicVersion version() const { return GetParam(); }
+
+  QuicTransportVersion transport_version() const {
+    return version().transport_version;
+  }
+
+  void InjectStopSending(QuicStreamId stream_id,
+                         QuicRstStreamErrorCode rst_stream_code) {
+    // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+    // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
+    // a one-way close.
+    if (!VersionHasIetfQuicFrames(transport_version())) {
+      // Only needed for version 99/IETF QUIC.
+      return;
+    }
+    EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
+                                      rst_stream_code);
+    // Expect the RESET_STREAM that is generated in response to receiving a
+    // STOP_SENDING.
+    EXPECT_CALL(*connection_, OnStreamReset(stream_id, rst_stream_code));
+    session_->OnStopSendingFrame(stop_sending);
+  }
+
+  StrictMock<MockQuicSessionVisitor> owner_;
+  StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnectionWithSendStreamData>* connection_;
+  QuicConfig config_;
+  QuicCryptoServerConfig crypto_config_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicMemoryCacheBackend memory_cache_backend_;
+  std::unique_ptr<MockQuicSimpleServerSession> session_;
+  std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         QuicSimpleServerSessionTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
+  // Send some data open a stream, then reset it.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Receive a reset (and send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  EXPECT_CALL(*session_, WriteControlFrame(_, _));
+
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    // For version 99, this is covered in InjectStopSending()
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst1);
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
+  // a one-way close.
+  InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
+                    QUIC_ERROR_PROCESSING_STREAM);
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Send the same two bytes of payload in a new packet.
+  session_->OnStreamFrame(data1);
+
+  // The stream should not be re-opened.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) {
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst1(kInvalidControlFrameId,
+                          GetNthClientInitiatedBidirectionalId(0),
+                          QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    // For version 99, this is covered in InjectStopSending()
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst1);
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
+  // a one-way close.
+  InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
+                    QUIC_ERROR_PROCESSING_STREAM);
+
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) {
+  // Send some data to open two streams.
+  QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                         kStreamData);
+  QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                         kStreamData);
+  session_->OnStreamFrame(frame1);
+  session_->OnStreamFrame(frame2);
+  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+
+  // Send a reset (and expect the peer to send a RST in response).
+  QuicRstStreamFrame rst(kInvalidControlFrameId,
+                         GetNthClientInitiatedBidirectionalId(0),
+                         QUIC_ERROR_PROCESSING_STREAM, 0);
+  EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
+  if (!VersionHasIetfQuicFrames(transport_version())) {
+    EXPECT_CALL(*session_, WriteControlFrame(_, _));
+    // For version 99, this is covered in InjectStopSending()
+    EXPECT_CALL(*connection_,
+                OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
+                              QUIC_RST_ACKNOWLEDGEMENT));
+  }
+  session_->OnRstStream(rst);
+  // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
+  // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes
+  // a one-way close.
+  InjectStopSending(GetNthClientInitiatedBidirectionalId(0),
+                    QUIC_ERROR_PROCESSING_STREAM);
+
+  // If we were tracking, we'd probably want to reject this because it's data
+  // past the reset point of stream 3.  As it's a closed stream we just drop the
+  // data on the floor, but accept the packet because it has data for stream 5.
+  QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
+                         kStreamData);
+  QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
+                         kStreamData);
+  session_->OnStreamFrame(frame3);
+  session_->OnStreamFrame(frame4);
+  // The stream should never be opened, now that the reset is received.
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_TRUE(connection_->connected());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateIncomingStreamDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (version() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Tests that incoming stream creation fails when connection is not connected.
+  size_t initial_num_open_stream =
+      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
+  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  EXPECT_QUIC_BUG(QuicSimpleServerSessionPeer::CreateIncomingStream(
+                      session_.get(), GetNthClientInitiatedBidirectionalId(0)),
+                  "ShouldCreateIncomingStream called when disconnected");
+  EXPECT_EQ(initial_num_open_stream,
+            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateIncomingStream) {
+  QuicSpdyStream* stream = QuicSimpleServerSessionPeer::CreateIncomingStream(
+      session_.get(), GetNthClientInitiatedBidirectionalId(0));
+  EXPECT_NE(nullptr, stream);
+  EXPECT_EQ(GetNthClientInitiatedBidirectionalId(0), stream->id());
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamDisconnected) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (version() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Tests that outgoing stream creation fails when connection is not connected.
+  size_t initial_num_open_stream =
+      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
+  QuicConnectionPeer::TearDownLocalConnectionState(connection_);
+  EXPECT_QUIC_BUG(
+      QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
+          session_.get()),
+      "ShouldCreateOutgoingUnidirectionalStream called when disconnected");
+
+  EXPECT_EQ(initial_num_open_stream,
+            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUnencrypted) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (version() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Tests that outgoing stream creation fails when encryption has not yet been
+  // established.
+  size_t initial_num_open_stream =
+      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
+  EXPECT_QUIC_BUG(
+      QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
+          session_.get()),
+      "Encryption not established so no outgoing stream created.");
+  EXPECT_EQ(initial_num_open_stream,
+            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
+  // Tests that outgoing stream creation should not be affected by existing
+  // incoming stream and vice-versa. But when reaching the limit of max outgoing
+  // stream allowed, creation should fail.
+
+  // Receive some data to initiate a incoming stream which should not effect
+  // creating outgoing streams.
+  QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data1);
+  EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+  EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
+                    /*incoming=*/1);
+
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->UnregisterStreamPriority(
+        QuicUtils::GetHeadersStreamId(transport_version()),
+        /*is_static=*/true);
+  }
+  // Assume encryption already established.
+  QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
+  QuicCryptoServerStreamBase* crypto_stream =
+      CreateMockCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
+                                   session_.get(), &stream_helper_);
+  QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
+  if (!VersionUsesHttp3(transport_version())) {
+    session_->RegisterStreamPriority(
+        QuicUtils::GetHeadersStreamId(transport_version()),
+        /*is_static=*/true,
+        spdy::SpdyStreamPrecedence(QuicStream::kDefaultPriority));
+  }
+
+  // Create push streams till reaching the upper limit of allowed open streams.
+  for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
+    QuicSpdyStream* created_stream =
+        QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
+            session_.get());
+    if (VersionUsesHttp3(transport_version())) {
+      EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i + 3),
+                created_stream->id());
+    } else {
+      EXPECT_EQ(GetNthServerInitiatedUnidirectionalId(i), created_stream->id());
+    }
+    EXPECT_EQ(i + 1, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
+                         /*incoming=*/1);
+  }
+
+  // Continuing creating push stream would fail.
+  EXPECT_EQ(nullptr,
+            QuicSimpleServerSessionPeer::CreateOutgoingUnidirectionalStream(
+                session_.get()));
+  EXPECT_EQ(kMaxStreamsForTest,
+            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
+                /*incoming=*/1);
+
+  // Create peer initiated stream should have no problem.
+  QuicStreamFrame data2(GetNthClientInitiatedBidirectionalId(1), false, 0,
+                        kStreamData);
+  session_->OnStreamFrame(data2);
+  EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()) -
+                    /*outcoming=*/kMaxStreamsForTest);
+}
+
+TEST_P(QuicSimpleServerSessionTest, OnStreamFrameWithEvenStreamId) {
+  QuicStreamFrame frame(GetNthServerInitiatedUnidirectionalId(0), false, 0,
+                        kStreamData);
+  EXPECT_CALL(*connection_,
+              CloseConnection(QUIC_INVALID_STREAM_ID,
+                              "Client sent data on server push stream", _));
+  session_->OnStreamFrame(frame);
+}
+
+// Tests that calling GetOrCreateStream() on an outgoing stream not promised yet
+// should result close connection.
+TEST_P(QuicSimpleServerSessionTest, GetEvenIncomingError) {
+  const size_t initial_num_open_stream =
+      QuicSessionPeer::GetNumOpenDynamicStreams(session_.get());
+  const QuicErrorCode expected_error = VersionUsesHttp3(transport_version())
+                                           ? QUIC_HTTP_STREAM_WRONG_DIRECTION
+                                           : QUIC_INVALID_STREAM_ID;
+  EXPECT_CALL(*connection_, CloseConnection(expected_error,
+                                            "Data for nonexistent stream", _));
+  EXPECT_EQ(nullptr,
+            QuicSessionPeer::GetOrCreateStream(
+                session_.get(), GetNthServerInitiatedUnidirectionalId(3)));
+  EXPECT_EQ(initial_num_open_stream,
+            QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_server_stream.cc b/quiche/quic/tools/quic_simple_server_stream.cc
new file mode 100644
index 0000000..ab9622e
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_stream.cc
@@ -0,0 +1,429 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+#include <list>
+#include <utility>
+
+#include "absl/strings/match.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_stream.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/tools/quic_simple_server_session.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using spdy::Http2HeaderBlock;
+
+namespace quic {
+
+QuicSimpleServerStream::QuicSimpleServerStream(
+    QuicStreamId id,
+    QuicSpdySession* session,
+    StreamType type,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicSpdyServerStreamBase(id, session, type),
+      content_length_(-1),
+      generate_bytes_length_(0),
+      quic_simple_server_backend_(quic_simple_server_backend) {
+  QUICHE_DCHECK(quic_simple_server_backend_);
+}
+
+QuicSimpleServerStream::QuicSimpleServerStream(
+    PendingStream* pending, QuicSpdySession* session,
+    QuicSimpleServerBackend* quic_simple_server_backend)
+    : QuicSpdyServerStreamBase(pending, session),
+      content_length_(-1),
+      generate_bytes_length_(0),
+      quic_simple_server_backend_(quic_simple_server_backend) {
+  QUICHE_DCHECK(quic_simple_server_backend_);
+}
+
+QuicSimpleServerStream::~QuicSimpleServerStream() {
+  quic_simple_server_backend_->CloseBackendResponseStream(this);
+}
+
+void QuicSimpleServerStream::OnInitialHeadersComplete(
+    bool fin,
+    size_t frame_len,
+    const QuicHeaderList& header_list) {
+  QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
+  // QuicSpdyStream::OnInitialHeadersComplete() may have already sent error
+  // response.
+  if (!response_sent_ &&
+      !SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
+                                         &request_headers_)) {
+    QUIC_DVLOG(1) << "Invalid headers";
+      SendErrorResponse();
+  }
+  ConsumeHeaderList();
+  if (!fin && !response_sent_) {
+    // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) require
+    // sending the response right after parsing the headers even though the FIN
+    // bit has not been received on the request stream.
+    auto it = request_headers_.find(":method");
+    if (it != request_headers_.end() &&
+        absl::StartsWith(it->second, "CONNECT")) {
+      SendResponse();
+    }
+  }
+}
+
+void QuicSimpleServerStream::OnTrailingHeadersComplete(
+    bool /*fin*/,
+    size_t /*frame_len*/,
+    const QuicHeaderList& /*header_list*/) {
+  QUIC_BUG(quic_bug_10962_1) << "Server does not support receiving Trailers.";
+  SendErrorResponse();
+}
+
+void QuicSimpleServerStream::OnBodyAvailable() {
+  while (HasBytesToRead()) {
+    struct iovec iov;
+    if (GetReadableRegions(&iov, 1) == 0) {
+      // No more data to read.
+      break;
+    }
+    QUIC_DVLOG(1) << "Stream " << id() << " processed " << iov.iov_len
+                  << " bytes.";
+    body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
+
+    if (content_length_ >= 0 &&
+        body_.size() > static_cast<uint64_t>(content_length_)) {
+      QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
+                    << content_length_ << ").";
+      SendErrorResponse();
+      return;
+    }
+    MarkConsumed(iov.iov_len);
+  }
+  if (!sequencer()->IsClosed()) {
+    sequencer()->SetUnblocked();
+    return;
+  }
+
+  // If the sequencer is closed, then all the body, including the fin, has been
+  // consumed.
+  OnFinRead();
+
+  if (write_side_closed() || fin_buffered()) {
+    return;
+  }
+
+  SendResponse();
+}
+
+void QuicSimpleServerStream::PushResponse(
+    Http2HeaderBlock push_request_headers) {
+  if (QuicUtils::IsClientInitiatedStreamId(session()->transport_version(),
+                                           id())) {
+    QUIC_BUG(quic_bug_10962_2)
+        << "Client initiated stream shouldn't be used as promised stream.";
+    return;
+  }
+  // Change the stream state to emulate a client request.
+  request_headers_ = std::move(push_request_headers);
+  content_length_ = 0;
+  QUIC_DVLOG(1) << "Stream " << id()
+                << " ready to receive server push response.";
+  QUICHE_DCHECK(reading_stopped());
+
+  // Directly send response based on the emulated request_headers_.
+  SendResponse();
+}
+
+void QuicSimpleServerStream::SendResponse() {
+  if (request_headers_.empty()) {
+    QUIC_DVLOG(1) << "Request headers empty.";
+    SendErrorResponse();
+    return;
+  }
+
+  if (content_length_ > 0 &&
+      static_cast<uint64_t>(content_length_) != body_.size()) {
+    QUIC_DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
+                  << body_.size() << ").";
+    SendErrorResponse();
+    return;
+  }
+
+  if (!request_headers_.contains(":authority")) {
+    QUIC_DVLOG(1) << "Request headers do not contain :authority.";
+    SendErrorResponse();
+    return;
+  }
+
+  if (!request_headers_.contains(":path")) {
+    // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) do not all
+    // require :path to be present.
+    auto it = request_headers_.find(":method");
+    if (it == request_headers_.end() ||
+        !absl::StartsWith(it->second, "CONNECT")) {
+      QUIC_DVLOG(1) << "Request headers do not contain :path.";
+      SendErrorResponse();
+      return;
+    }
+  }
+
+  if (quic_simple_server_backend_ == nullptr) {
+    QUIC_DVLOG(1) << "Backend is missing.";
+    SendErrorResponse();
+    return;
+  }
+
+  if (web_transport() != nullptr) {
+    QuicSimpleServerBackend::WebTransportResponse response =
+        quic_simple_server_backend_->ProcessWebTransportRequest(
+            request_headers_, web_transport());
+    if (response.response_headers[":status"] == "200") {
+      WriteHeaders(std::move(response.response_headers), false, nullptr);
+      if (response.visitor != nullptr) {
+        web_transport()->SetVisitor(std::move(response.visitor));
+      }
+      web_transport()->HeadersReceived(request_headers_);
+    } else {
+      WriteHeaders(std::move(response.response_headers), true, nullptr);
+    }
+    return;
+  }
+
+  // Fetch the response from the backend interface and wait for callback once
+  // response is ready
+  quic_simple_server_backend_->FetchResponseFromBackend(request_headers_, body_,
+                                                        this);
+}
+
+QuicConnectionId QuicSimpleServerStream::connection_id() const {
+  return spdy_session()->connection_id();
+}
+
+QuicStreamId QuicSimpleServerStream::stream_id() const {
+  return id();
+}
+
+std::string QuicSimpleServerStream::peer_host() const {
+  return spdy_session()->peer_address().host().ToString();
+}
+
+void QuicSimpleServerStream::OnResponseBackendComplete(
+    const QuicBackendResponse* response) {
+  if (response == nullptr) {
+    QUIC_DVLOG(1) << "Response not found in cache.";
+    SendNotFoundResponse();
+    return;
+  }
+
+  // Send Early Hints first.
+  for (const auto& headers : response->early_hints()) {
+    QUIC_DVLOG(1) << "Stream " << id() << " sending an Early Hints response: "
+                  << headers.DebugString();
+    WriteHeaders(headers.Clone(), false, nullptr);
+  }
+
+  if (response->response_type() == QuicBackendResponse::CLOSE_CONNECTION) {
+    QUIC_DVLOG(1) << "Special response: closing connection.";
+    OnUnrecoverableError(QUIC_NO_ERROR, "Toy server forcing close");
+    return;
+  }
+
+  if (response->response_type() == QuicBackendResponse::IGNORE_REQUEST) {
+    QUIC_DVLOG(1) << "Special response: ignoring request.";
+    return;
+  }
+
+  if (response->response_type() == QuicBackendResponse::BACKEND_ERR_RESPONSE) {
+    QUIC_DVLOG(1) << "Quic Proxy: Backend connection error.";
+    /*502 Bad Gateway
+      The server was acting as a gateway or proxy and received an
+      invalid response from the upstream server.*/
+    SendErrorResponse(502);
+    return;
+  }
+
+  // Examing response status, if it was not pure integer as typical h2
+  // response status, send error response. Notice that
+  // QuicHttpResponseCache push urls are strictly authority + path only,
+  // scheme is not included (see |QuicHttpResponseCache::GetKey()|).
+  std::string request_url = request_headers_[":authority"].as_string() +
+                            request_headers_[":path"].as_string();
+  int response_code;
+  const Http2HeaderBlock& response_headers = response->headers();
+  if (!ParseHeaderStatusCode(response_headers, &response_code)) {
+    auto status = response_headers.find(":status");
+    if (status == response_headers.end()) {
+      QUIC_LOG(WARNING)
+          << ":status not present in response from cache for request "
+          << request_url;
+    } else {
+      QUIC_LOG(WARNING) << "Illegal (non-integer) response :status from cache: "
+                        << status->second << " for request " << request_url;
+    }
+    SendErrorResponse();
+    return;
+  }
+
+  if (QuicUtils::IsServerInitiatedStreamId(session()->transport_version(),
+                                           id())) {
+    // A server initiated stream is only used for a server push response,
+    // and only 200 and 30X response codes are supported for server push.
+    // This behavior mirrors the HTTP/2 implementation.
+    bool is_redirection = response_code / 100 == 3;
+    if (response_code != 200 && !is_redirection) {
+      QUIC_LOG(WARNING) << "Response to server push request " << request_url
+                        << " result in response code " << response_code;
+      Reset(QUIC_STREAM_CANCELLED);
+      return;
+    }
+  }
+
+  if (response->response_type() == QuicBackendResponse::INCOMPLETE_RESPONSE) {
+    QUIC_DVLOG(1)
+        << "Stream " << id()
+        << " sending an incomplete response, i.e. no trailer, no fin.";
+    SendIncompleteResponse(response->headers().Clone(), response->body());
+    return;
+  }
+
+  if (response->response_type() == QuicBackendResponse::GENERATE_BYTES) {
+    QUIC_DVLOG(1) << "Stream " << id() << " sending a generate bytes response.";
+    std::string path = request_headers_[":path"].as_string().substr(1);
+    if (!absl::SimpleAtoi(path, &generate_bytes_length_)) {
+      QUIC_LOG(ERROR) << "Path is not a number.";
+      SendNotFoundResponse();
+      return;
+    }
+    Http2HeaderBlock headers = response->headers().Clone();
+    headers["content-length"] = absl::StrCat(generate_bytes_length_);
+
+    WriteHeaders(std::move(headers), false, nullptr);
+    QUICHE_DCHECK(!response_sent_);
+    response_sent_ = true;
+
+    WriteGeneratedBytes();
+
+    return;
+  }
+
+  QUIC_DVLOG(1) << "Stream " << id() << " sending response.";
+  SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(),
+                                response->trailers().Clone());
+}
+
+void QuicSimpleServerStream::OnCanWrite() {
+  QuicSpdyStream::OnCanWrite();
+  WriteGeneratedBytes();
+}
+
+void QuicSimpleServerStream::WriteGeneratedBytes() {
+  static size_t kChunkSize = 1024;
+  while (!HasBufferedData() && generate_bytes_length_ > 0) {
+    size_t len = std::min<size_t>(kChunkSize, generate_bytes_length_);
+    std::string data(len, 'a');
+    generate_bytes_length_ -= len;
+    bool fin = generate_bytes_length_ == 0;
+    WriteOrBufferBody(data, fin);
+  }
+}
+
+void QuicSimpleServerStream::SendNotFoundResponse() {
+  QUIC_DVLOG(1) << "Stream " << id() << " sending not found response.";
+  Http2HeaderBlock headers;
+  headers[":status"] = "404";
+  headers["content-length"] = absl::StrCat(strlen(kNotFoundResponseBody));
+  SendHeadersAndBody(std::move(headers), kNotFoundResponseBody);
+}
+
+void QuicSimpleServerStream::SendErrorResponse() {
+  SendErrorResponse(0);
+}
+
+void QuicSimpleServerStream::SendErrorResponse(int resp_code) {
+  QUIC_DVLOG(1) << "Stream " << id() << " sending error response.";
+  if (!reading_stopped()) {
+    StopReading();
+  }
+  Http2HeaderBlock headers;
+  if (resp_code <= 0) {
+    headers[":status"] = "500";
+  } else {
+    headers[":status"] = absl::StrCat(resp_code);
+  }
+  headers["content-length"] = absl::StrCat(strlen(kErrorResponseBody));
+  SendHeadersAndBody(std::move(headers), kErrorResponseBody);
+}
+
+void QuicSimpleServerStream::SendIncompleteResponse(
+    Http2HeaderBlock response_headers,
+    absl::string_view body) {
+  QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = false) : "
+                  << response_headers.DebugString();
+  WriteHeaders(std::move(response_headers), /*fin=*/false, nullptr);
+  QUICHE_DCHECK(!response_sent_);
+  response_sent_ = true;
+
+  QUIC_DLOG(INFO) << "Stream " << id()
+                  << " writing body (fin = false) with size: " << body.size();
+  if (!body.empty()) {
+    WriteOrBufferBody(body, /*fin=*/false);
+  }
+}
+
+void QuicSimpleServerStream::SendHeadersAndBody(
+    Http2HeaderBlock response_headers,
+    absl::string_view body) {
+  SendHeadersAndBodyAndTrailers(std::move(response_headers), body,
+                                Http2HeaderBlock());
+}
+
+void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
+    Http2HeaderBlock response_headers,
+    absl::string_view body,
+    Http2HeaderBlock response_trailers) {
+  // Send the headers, with a FIN if there's nothing else to send.
+  bool send_fin = (body.empty() && response_trailers.empty());
+  QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = " << send_fin
+                  << ") : " << response_headers.DebugString();
+  WriteHeaders(std::move(response_headers), send_fin, nullptr);
+  QUICHE_DCHECK(!response_sent_);
+  response_sent_ = true;
+  if (send_fin) {
+    // Nothing else to send.
+    return;
+  }
+
+  // Send the body, with a FIN if there's no trailers to send.
+  send_fin = response_trailers.empty();
+  QUIC_DLOG(INFO) << "Stream " << id() << " writing body (fin = " << send_fin
+                  << ") with size: " << body.size();
+  if (!body.empty() || send_fin) {
+    WriteOrBufferBody(body, send_fin);
+  }
+  if (send_fin) {
+    // Nothing else to send.
+    return;
+  }
+
+  // Send the trailers. A FIN is always sent with trailers.
+  QUIC_DLOG(INFO) << "Stream " << id() << " writing trailers (fin = true): "
+                  << response_trailers.DebugString();
+  WriteTrailers(std::move(response_trailers), nullptr);
+}
+
+void QuicSimpleServerStream::OnInvalidHeaders() {
+  QUIC_DVLOG(1) << "Invalid headers";
+  SendErrorResponse(400);
+}
+
+const char* const QuicSimpleServerStream::kErrorResponseBody = "bad";
+const char* const QuicSimpleServerStream::kNotFoundResponseBody =
+    "file not found";
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_simple_server_stream.h b/quiche/quic/tools/quic_simple_server_stream.h
new file mode 100644
index 0000000..841437d
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_stream.h
@@ -0,0 +1,109 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/http/quic_spdy_server_stream_base.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+#include "quiche/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+// All this does right now is aggregate data, and on fin, send an HTTP
+// response.
+class QuicSimpleServerStream : public QuicSpdyServerStreamBase,
+                               public QuicSimpleServerBackend::RequestHandler {
+ public:
+  QuicSimpleServerStream(QuicStreamId id,
+                         QuicSpdySession* session,
+                         StreamType type,
+                         QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicSimpleServerStream(PendingStream* pending,
+                         QuicSpdySession* session,
+                         QuicSimpleServerBackend* quic_simple_server_backend);
+  QuicSimpleServerStream(const QuicSimpleServerStream&) = delete;
+  QuicSimpleServerStream& operator=(const QuicSimpleServerStream&) = delete;
+  ~QuicSimpleServerStream() override;
+
+  // QuicSpdyStream
+  void OnInitialHeadersComplete(bool fin,
+                                size_t frame_len,
+                                const QuicHeaderList& header_list) override;
+  void OnTrailingHeadersComplete(bool fin,
+                                 size_t frame_len,
+                                 const QuicHeaderList& header_list) override;
+  void OnCanWrite() override;
+
+  // QuicStream implementation called by the sequencer when there is
+  // data (or a FIN) to be read.
+  void OnBodyAvailable() override;
+
+  void OnInvalidHeaders() override;
+
+  // Make this stream start from as if it just finished parsing an incoming
+  // request whose headers are equivalent to |push_request_headers|.
+  // Doing so will trigger this toy stream to fetch response and send it back.
+  virtual void PushResponse(spdy::Http2HeaderBlock push_request_headers);
+
+  // The response body of error responses.
+  static const char* const kErrorResponseBody;
+  static const char* const kNotFoundResponseBody;
+
+  // Implements QuicSimpleServerBackend::RequestHandler callbacks
+  QuicConnectionId connection_id() const override;
+  QuicStreamId stream_id() const override;
+  std::string peer_host() const override;
+  void OnResponseBackendComplete(const QuicBackendResponse* response) override;
+
+ protected:
+  // Sends a basic 200 response using SendHeaders for the headers and WriteData
+  // for the body.
+  virtual void SendResponse();
+
+  // Sends a basic 500 response using SendHeaders for the headers and WriteData
+  // for the body.
+  virtual void SendErrorResponse();
+  virtual void SendErrorResponse(int resp_code);
+
+  // Sends a basic 404 response using SendHeaders for the headers and WriteData
+  // for the body.
+  void SendNotFoundResponse();
+
+  // Sends the response header and body, but not the fin.
+  void SendIncompleteResponse(spdy::Http2HeaderBlock response_headers,
+                              absl::string_view body);
+
+  void SendHeadersAndBody(spdy::Http2HeaderBlock response_headers,
+                          absl::string_view body);
+  void SendHeadersAndBodyAndTrailers(spdy::Http2HeaderBlock response_headers,
+                                     absl::string_view body,
+                                     spdy::Http2HeaderBlock response_trailers);
+
+  spdy::Http2HeaderBlock* request_headers() { return &request_headers_; }
+
+  const std::string& body() { return body_; }
+
+  // Writes the body bytes for the GENERATE_BYTES response type.
+  void WriteGeneratedBytes();
+
+  // The parsed headers received from the client.
+  spdy::Http2HeaderBlock request_headers_;
+  int64_t content_length_;
+  std::string body_;
+
+ private:
+  uint64_t generate_bytes_length_;
+  // Whether response headers have already been sent.
+  bool response_sent_ = false;
+
+  QuicSimpleServerBackend* quic_simple_server_backend_;  // Not owned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
diff --git a/quiche/quic/tools/quic_simple_server_stream_test.cc b/quiche/quic/tools/quic_simple_server_stream_test.cc
new file mode 100644
index 0000000..c2aa58e
--- /dev/null
+++ b/quiche/quic/tools/quic_simple_server_stream_test.cc
@@ -0,0 +1,790 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_simple_server_stream.h"
+
+#include <list>
+#include <memory>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/http/http_encoder.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_config_peer.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
+#include "quiche/quic/test_tools/quic_session_peer.h"
+#include "quiche/quic/test_tools/quic_spdy_session_peer.h"
+#include "quiche/quic/test_tools/quic_stream_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/quic/tools/quic_backend_response.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_simple_server_session.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::InSequence;
+using testing::Invoke;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+
+const size_t kFakeFrameLen = 60;
+const size_t kErrorLength = strlen(QuicSimpleServerStream::kErrorResponseBody);
+const size_t kDataFrameHeaderLength = 2;
+
+class TestStream : public QuicSimpleServerStream {
+ public:
+  TestStream(QuicStreamId stream_id, QuicSpdySession* session, StreamType type,
+             QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerStream(stream_id, session, type,
+                               quic_simple_server_backend) {}
+
+  ~TestStream() override = default;
+
+  MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
+  MOCK_METHOD(void, WriteEarlyHintsHeadersMock, (bool fin), ());
+
+  size_t WriteHeaders(
+      spdy::Http2HeaderBlock header_block, bool fin,
+      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
+      /*ack_listener*/) override {
+    if (header_block[":status"] == "103") {
+      WriteEarlyHintsHeadersMock(fin);
+    } else {
+      WriteHeadersMock(fin);
+    }
+    return 0;
+  }
+
+  // Expose protected QuicSimpleServerStream methods.
+  void DoSendResponse() { SendResponse(); }
+  void DoSendErrorResponse() { QuicSimpleServerStream::SendErrorResponse(); }
+
+  spdy::Http2HeaderBlock* mutable_headers() { return &request_headers_; }
+  void set_body(std::string body) { body_ = std::move(body); }
+  const std::string& body() const { return body_; }
+  int content_length() const { return content_length_; }
+  bool send_response_was_called() const { return send_response_was_called_; }
+  bool send_error_response_was_called() const {
+    return send_error_response_was_called_;
+  }
+
+  absl::string_view GetHeader(absl::string_view key) const {
+    auto it = request_headers_.find(key);
+    QUICHE_DCHECK(it != request_headers_.end());
+    return it->second;
+  }
+
+ protected:
+  void SendResponse() override {
+    send_response_was_called_ = true;
+    QuicSimpleServerStream::SendResponse();
+  }
+
+  void SendErrorResponse(int resp_code) override {
+    send_error_response_was_called_ = true;
+    QuicSimpleServerStream::SendErrorResponse(resp_code);
+  }
+
+ private:
+  bool send_response_was_called_ = false;
+  bool send_error_response_was_called_ = false;
+};
+
+namespace {
+
+class MockQuicSimpleServerSession : public QuicSimpleServerSession {
+ public:
+  const size_t kMaxStreamsForTest = 100;
+
+  MockQuicSimpleServerSession(
+      QuicConnection* connection, MockQuicSessionVisitor* owner,
+      MockQuicCryptoServerStreamHelper* helper,
+      QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      QuicSimpleServerBackend* quic_simple_server_backend)
+      : QuicSimpleServerSession(DefaultQuicConfig(), CurrentSupportedVersions(),
+                                connection, owner, helper, crypto_config,
+                                compressed_certs_cache,
+                                quic_simple_server_backend) {
+    if (VersionHasIetfQuicFrames(connection->transport_version())) {
+      QuicSessionPeer::SetMaxOpenIncomingUnidirectionalStreams(
+          this, kMaxStreamsForTest);
+      QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
+          this, kMaxStreamsForTest);
+    } else {
+      QuicSessionPeer::SetMaxOpenIncomingStreams(this, kMaxStreamsForTest);
+      QuicSessionPeer::SetMaxOpenOutgoingStreams(this, kMaxStreamsForTest);
+    }
+    ON_CALL(*this, WritevData(_, _, _, _, _, _))
+        .WillByDefault(Invoke(this, &MockQuicSimpleServerSession::ConsumeData));
+  }
+
+  MockQuicSimpleServerSession(const MockQuicSimpleServerSession&) = delete;
+  MockQuicSimpleServerSession& operator=(const MockQuicSimpleServerSession&) =
+      delete;
+  ~MockQuicSimpleServerSession() override = default;
+
+  MOCK_METHOD(void, OnConnectionClosed,
+              (const QuicConnectionCloseFrame& frame,
+               ConnectionCloseSource source),
+              (override));
+  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
+              (override));
+  MOCK_METHOD(QuicConsumedData, WritevData,
+              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
+               StreamSendingState state, TransmissionType type,
+               EncryptionLevel level),
+              (override));
+  MOCK_METHOD(void, OnStreamHeaderList,
+              (QuicStreamId stream_id, bool fin, size_t frame_len,
+               const QuicHeaderList& header_list),
+              (override));
+  MOCK_METHOD(void, OnStreamHeadersPriority,
+              (QuicStreamId stream_id,
+               const spdy::SpdyStreamPrecedence& precedence),
+              (override));
+  MOCK_METHOD(void, MaybeSendRstStreamFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error,
+               QuicStreamOffset bytes_written),
+              (override));
+  MOCK_METHOD(void, MaybeSendStopSendingFrame,
+              (QuicStreamId stream_id, QuicResetStreamError error), (override));
+
+  using QuicSession::ActivateStream;
+
+  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
+                               QuicStreamOffset offset,
+                               StreamSendingState state,
+                               TransmissionType /*type*/,
+                               absl::optional<EncryptionLevel> /*level*/) {
+    if (write_length > 0) {
+      auto buf = std::make_unique<char[]>(write_length);
+      QuicStream* stream = GetOrCreateStream(id);
+      QUICHE_DCHECK(stream);
+      QuicDataWriter writer(write_length, buf.get(), quiche::HOST_BYTE_ORDER);
+      stream->WriteStreamData(offset, write_length, &writer);
+    } else {
+      QUICHE_DCHECK(state != NO_FIN);
+    }
+    return QuicConsumedData(write_length, state != NO_FIN);
+  }
+
+  spdy::Http2HeaderBlock original_request_headers_;
+};
+
+class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
+ public:
+  QuicSimpleServerStreamTest()
+      : connection_(new StrictMock<MockQuicConnection>(
+            &helper_, &alarm_factory_, Perspective::IS_SERVER,
+            SupportedVersions(GetParam()))),
+        crypto_config_(new QuicCryptoServerConfig(
+            QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+            crypto_test_utils::ProofSourceForTesting(),
+            KeyExchangeSource::Default())),
+        compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        session_(connection_, &session_owner_, &session_helper_,
+                 crypto_config_.get(), &compressed_certs_cache_,
+                 &memory_cache_backend_),
+        quic_response_(new QuicBackendResponse),
+        body_("hello world") {
+    connection_->set_visitor(&session_);
+    header_list_.OnHeaderBlockStart();
+    header_list_.OnHeader(":authority", "www.google.com");
+    header_list_.OnHeader(":path", "/");
+    header_list_.OnHeader(":method", "POST");
+    header_list_.OnHeader(":scheme", "https");
+    header_list_.OnHeader("content-length", "11");
+
+    header_list_.OnHeaderBlockEnd(128, 128);
+
+    // New streams rely on having the peer's flow control receive window
+    // negotiated in the config.
+    session_.config()->SetInitialStreamFlowControlWindowToSend(
+        kInitialStreamFlowControlWindowForTest);
+    session_.config()->SetInitialSessionFlowControlWindowToSend(
+        kInitialSessionFlowControlWindowForTest);
+    session_.Initialize();
+    connection_->SetEncrypter(
+        quic::ENCRYPTION_FORWARD_SECURE,
+        std::make_unique<quic::NullEncrypter>(connection_->perspective()));
+    if (connection_->version().SupportsAntiAmplificationLimit()) {
+      QuicConnectionPeer::SetAddressValidated(connection_);
+    }
+    stream_ = new StrictMock<TestStream>(
+        GetNthClientInitiatedBidirectionalStreamId(
+            connection_->transport_version(), 0),
+        &session_, BIDIRECTIONAL, &memory_cache_backend_);
+    // Register stream_ in dynamic_stream_map_ and pass ownership to session_.
+    session_.ActivateStream(absl::WrapUnique(stream_));
+    QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
+        session_.config(), kMinimumFlowControlSendWindow);
+    QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 10);
+    session_.OnConfigNegotiated();
+    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+  }
+
+  const std::string& StreamBody() { return stream_->body(); }
+
+  std::string StreamHeadersValue(const std::string& key) {
+    return (*stream_->mutable_headers())[key].as_string();
+  }
+
+  bool UsesHttp3() const {
+    return VersionUsesHttp3(connection_->transport_version());
+  }
+
+  spdy::Http2HeaderBlock response_headers_;
+  MockQuicConnectionHelper helper_;
+  MockAlarmFactory alarm_factory_;
+  StrictMock<MockQuicConnection>* connection_;
+  StrictMock<MockQuicSessionVisitor> session_owner_;
+  StrictMock<MockQuicCryptoServerStreamHelper> session_helper_;
+  std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
+  QuicCompressedCertsCache compressed_certs_cache_;
+  QuicMemoryCacheBackend memory_cache_backend_;
+  StrictMock<MockQuicSimpleServerSession> session_;
+  StrictMock<TestStream>* stream_;  // Owned by session_.
+  std::unique_ptr<QuicBackendResponse> quic_response_;
+  std::string body_;
+  QuicHeaderList header_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSimpleServerStreamTest,
+                         ::testing::ValuesIn(AllSupportedVersions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(QuicSimpleServerStreamTest, TestFraming) {
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data =
+      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("11", StreamHeadersValue("content-length"));
+  EXPECT_EQ("/", StreamHeadersValue(":path"));
+  EXPECT_EQ("POST", StreamHeadersValue(":method"));
+  EXPECT_EQ(body_, StreamBody());
+}
+
+TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+
+  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data =
+      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("11", StreamHeadersValue("content-length"));
+  EXPECT_EQ("/", StreamHeadersValue(":path"));
+  EXPECT_EQ("POST", StreamHeadersValue(":method"));
+  EXPECT_EQ(body_, StreamBody());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+
+  EXPECT_FALSE(stream_->fin_received());
+  EXPECT_FALSE(stream_->rst_received());
+
+  QuicStreamPeer::SetFinSent(stream_);
+  stream_->CloseWriteSide();
+
+  if (session_.version().UsesHttp3()) {
+    EXPECT_CALL(session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_NO_ERROR)))
+        .Times(1);
+  } else {
+    EXPECT_CALL(
+        session_,
+        MaybeSendRstStreamFrame(
+            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
+        .Times(1);
+  }
+  stream_->StopReading();
+}
+
+TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
+  InSequence seq;
+  std::string large_body = "hello world!!!!!!";
+
+  // We'll automatically write out an error (headers + body)
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_,
+                WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
+
+  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data =
+      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
+
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  // Content length is still 11.  This will register as an error and we won't
+  // accept the bytes.
+  header = HttpEncoder::SerializeDataFrameHeader(
+      large_body.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data2 = UsesHttp3()
+                          ? absl::StrCat(header.AsStringView(), large_body)
+                          : large_body;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/true, data.size(), data2));
+  EXPECT_EQ("11", StreamHeadersValue("content-length"));
+  EXPECT_EQ("/", StreamHeadersValue(":path"));
+  EXPECT_EQ("POST", StreamHeadersValue(":method"));
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus) {
+  // Send an illegal response with response status not supported by HTTP/2.
+  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
+  (*request_headers)[":path"] = "/bar";
+  (*request_headers)[":authority"] = "www.google.com";
+  (*request_headers)[":method"] = "GET";
+
+  // HTTP/2 only supports integer responsecode, so "200 OK" is illegal.
+  response_headers_[":status"] = "200 OK";
+  response_headers_["content-length"] = "5";
+  std::string body = "Yummm";
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body.length(), quiche::SimpleBufferAllocator::Get());
+
+  memory_cache_backend_.AddResponse("www.google.com", "/bar",
+                                    std::move(response_headers_), body);
+
+  QuicStreamPeer::SetFinReceived(stream_);
+
+  InSequence s;
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
+
+  stream_->DoSendResponse();
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendResponseWithIllegalResponseStatus2) {
+  // Send an illegal response with response status not supported by HTTP/2.
+  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
+  (*request_headers)[":path"] = "/bar";
+  (*request_headers)[":authority"] = "www.google.com";
+  (*request_headers)[":method"] = "GET";
+
+  // HTTP/2 only supports 3-digit-integer, so "+200" is illegal.
+  response_headers_[":status"] = "+200";
+  response_headers_["content-length"] = "5";
+  std::string body = "Yummm";
+
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body.length(), quiche::SimpleBufferAllocator::Get());
+
+  memory_cache_backend_.AddResponse("www.google.com", "/bar",
+                                    std::move(response_headers_), body);
+
+  QuicStreamPeer::SetFinReceived(stream_);
+
+  InSequence s;
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
+
+  stream_->DoSendResponse();
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendPushResponseWith404Response) {
+  // Create a new promised stream with even id().
+  auto promised_stream = new StrictMock<TestStream>(
+      GetNthServerInitiatedUnidirectionalStreamId(
+          connection_->transport_version(), 3),
+      &session_, WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
+  session_.ActivateStream(absl::WrapUnique(promised_stream));
+
+  // Send a push response with response status 404, which will be regarded as
+  // invalid server push response.
+  spdy::Http2HeaderBlock* request_headers = promised_stream->mutable_headers();
+  (*request_headers)[":path"] = "/bar";
+  (*request_headers)[":authority"] = "www.google.com";
+  (*request_headers)[":method"] = "GET";
+
+  response_headers_[":status"] = "404";
+  response_headers_["content-length"] = "8";
+  std::string body = "NotFound";
+
+  memory_cache_backend_.AddResponse("www.google.com", "/bar",
+                                    std::move(response_headers_), body);
+
+  InSequence s;
+  if (session_.version().UsesHttp3()) {
+    EXPECT_CALL(session_,
+                MaybeSendStopSendingFrame(
+                    promised_stream->id(),
+                    QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)));
+  }
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          promised_stream->id(),
+          QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), 0));
+
+  promised_stream->DoSendResponse();
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendResponseWithValidHeaders) {
+  // Add a request and response with valid headers.
+  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
+  (*request_headers)[":path"] = "/bar";
+  (*request_headers)[":authority"] = "www.google.com";
+  (*request_headers)[":method"] = "GET";
+
+  response_headers_[":status"] = "200";
+  response_headers_["content-length"] = "5";
+  std::string body = "Yummm";
+
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body.length(), quiche::SimpleBufferAllocator::Get());
+
+  memory_cache_backend_.AddResponse("www.google.com", "/bar",
+                                    std::move(response_headers_), body);
+  QuicStreamPeer::SetFinReceived(stream_);
+
+  InSequence s;
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
+
+  stream_->DoSendResponse();
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, SendResponseWithEarlyHints) {
+  std::string host = "www.google.com";
+  std::string request_path = "/foo";
+  std::string body = "Yummm";
+
+  // Add a request and response with early hints.
+  spdy::Http2HeaderBlock* request_headers = stream_->mutable_headers();
+  (*request_headers)[":path"] = request_path;
+  (*request_headers)[":authority"] = host;
+  (*request_headers)[":method"] = "GET";
+
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body.length(), quiche::SimpleBufferAllocator::Get());
+  std::vector<spdy::Http2HeaderBlock> early_hints;
+  // Add two Early Hints.
+  const size_t kNumEarlyHintsResponses = 2;
+  for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
+    spdy::Http2HeaderBlock hints;
+    hints["link"] = "</image.png>; rel=preload; as=image";
+    early_hints.push_back(std::move(hints));
+  }
+
+  response_headers_[":status"] = "200";
+  response_headers_["content-length"] = "5";
+  memory_cache_backend_.AddResponseWithEarlyHints(
+      host, request_path, std::move(response_headers_), body, early_hints);
+  QuicStreamPeer::SetFinReceived(stream_);
+
+  InSequence s;
+  for (size_t i = 0; i < kNumEarlyHintsResponses; ++i) {
+    EXPECT_CALL(*stream_, WriteEarlyHintsHeadersMock(false));
+  }
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_, WritevData(_, header.size(), _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_, WritevData(_, body.length(), _, FIN, _, _));
+
+  stream_->DoSendResponse();
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, PushResponseOnClientInitiatedStream) {
+  // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
+  if (GetParam() != AllSupportedVersions()[0]) {
+    return;
+  }
+
+  // Calling PushResponse() on a client initialted stream is never supposed to
+  // happen.
+  EXPECT_QUIC_BUG(stream_->PushResponse(spdy::Http2HeaderBlock()),
+                  "Client initiated stream"
+                  " shouldn't be used as promised stream.");
+}
+
+TEST_P(QuicSimpleServerStreamTest, PushResponseOnServerInitiatedStream) {
+  // Tests that PushResponse() should take the given headers as request headers
+  // and fetch response from cache, and send it out.
+
+  // Create a stream with even stream id and test against this stream.
+  const QuicStreamId kServerInitiatedStreamId =
+      GetNthServerInitiatedUnidirectionalStreamId(
+          connection_->transport_version(), 3);
+  // Create a server initiated stream and pass it to session_.
+  auto server_initiated_stream =
+      new StrictMock<TestStream>(kServerInitiatedStreamId, &session_,
+                                 WRITE_UNIDIRECTIONAL, &memory_cache_backend_);
+  session_.ActivateStream(absl::WrapUnique(server_initiated_stream));
+
+  const std::string kHost = "www.foo.com";
+  const std::string kPath = "/bar";
+  spdy::Http2HeaderBlock headers;
+  headers[":path"] = kPath;
+  headers[":authority"] = kHost;
+  headers[":method"] = "GET";
+
+  response_headers_[":status"] = "200";
+  response_headers_["content-length"] = "5";
+  const std::string kBody = "Hello";
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  memory_cache_backend_.AddResponse(kHost, kPath, std::move(response_headers_),
+                                    kBody);
+
+  // Call PushResponse() should trigger stream to fetch response from cache
+  // and send it back.
+  InSequence s;
+  EXPECT_CALL(*server_initiated_stream, WriteHeadersMock(false));
+
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_, WritevData(kServerInitiatedStreamId, header.size(), _,
+                                     NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_,
+              WritevData(kServerInitiatedStreamId, kBody.size(), _, FIN, _, _));
+  server_initiated_stream->PushResponse(std::move(headers));
+  EXPECT_EQ(kPath, server_initiated_stream->GetHeader(":path"));
+  EXPECT_EQ("GET", server_initiated_stream->GetHeader(":method"));
+}
+
+TEST_P(QuicSimpleServerStreamTest, TestSendErrorResponse) {
+  QuicStreamPeer::SetFinReceived(stream_);
+
+  InSequence s;
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_,
+                WritevData(_, kDataFrameHeaderLength, _, NO_FIN, _, _));
+  }
+  EXPECT_CALL(session_, WritevData(_, kErrorLength, _, FIN, _, _));
+
+  stream_->DoSendErrorResponse();
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
+  spdy::Http2HeaderBlock request_headers;
+  // \000 is a way to write the null byte when followed by a literal digit.
+  header_list_.OnHeader("content-length", absl::string_view("11\00012", 5));
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+  stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
+
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->reading_stopped());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
+  spdy::Http2HeaderBlock request_headers;
+  // \000 is a way to write the null byte when followed by a literal digit.
+  header_list_.OnHeader("content-length", absl::string_view("\00012", 3));
+
+  EXPECT_CALL(*stream_, WriteHeadersMock(false));
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+  stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
+
+  EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_TRUE(stream_->reading_stopped());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, ValidMultipleContentLength) {
+  spdy::Http2HeaderBlock request_headers;
+  // \000 is a way to write the null byte when followed by a literal digit.
+  header_list_.OnHeader("content-length", absl::string_view("11\00011", 5));
+
+  stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
+
+  EXPECT_EQ(11, stream_->content_length());
+  EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
+  EXPECT_FALSE(stream_->reading_stopped());
+  EXPECT_FALSE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest,
+       DoNotSendQuicRstStreamNoErrorWithRstReceived) {
+  EXPECT_FALSE(stream_->reading_stopped());
+
+  if (VersionUsesHttp3(connection_->transport_version())) {
+    // Unidirectional stream type and then a Stream Cancellation instruction is
+    // sent on the QPACK decoder stream.  Ignore these writes without any
+    // assumption on their number or size.
+    auto* qpack_decoder_stream =
+        QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
+    EXPECT_CALL(session_, WritevData(qpack_decoder_stream->id(), _, _, _, _, _))
+        .Times(AnyNumber());
+  }
+
+  EXPECT_CALL(
+      session_,
+      MaybeSendRstStreamFrame(
+          _,
+          session_.version().UsesHttp3()
+              ? QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)
+              : QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT),
+          _))
+      .Times(1);
+  QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+                               QUIC_STREAM_CANCELLED, 1234);
+  stream_->OnStreamReset(rst_frame);
+  if (VersionHasIetfQuicFrames(connection_->transport_version())) {
+    EXPECT_CALL(session_owner_, OnStopSendingReceived(_));
+    // Create and inject a STOP SENDING frame to complete the close
+    // of the stream. This is only needed for version 99/IETF QUIC.
+    QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_->id(),
+                                      QUIC_STREAM_CANCELLED);
+    session_.OnStopSendingFrame(stop_sending);
+  }
+  EXPECT_TRUE(stream_->reading_stopped());
+  EXPECT_TRUE(stream_->write_side_closed());
+}
+
+TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
+  char arr[] = {
+      0x3a,   0x68, 0x6f, 0x73,  // :hos
+      0x74,   0x00, 0x00, 0x00,  // t...
+      0x00,   0x00, 0x00, 0x00,  // ....
+      0x07,   0x3a, 0x6d, 0x65,  // .:me
+      0x74,   0x68, 0x6f, 0x64,  // thod
+      0x00,   0x00, 0x00, 0x03,  // ....
+      0x47,   0x45, 0x54, 0x00,  // GET.
+      0x00,   0x00, 0x05, 0x3a,  // ...:
+      0x70,   0x61, 0x74, 0x68,  // path
+      0x00,   0x00, 0x00, 0x04,  // ....
+      0x2f,   0x66, 0x6f, 0x6f,  // /foo
+      0x00,   0x00, 0x00, 0x07,  // ....
+      0x3a,   0x73, 0x63, 0x68,  // :sch
+      0x65,   0x6d, 0x65, 0x00,  // eme.
+      0x00,   0x00, 0x00, 0x00,  // ....
+      0x00,   0x00, 0x08, 0x3a,  // ...:
+      0x76,   0x65, 0x72, 0x73,  // vers
+      '\x96', 0x6f, 0x6e, 0x00,  // <i(69)>on.
+      0x00,   0x00, 0x08, 0x48,  // ...H
+      0x54,   0x54, 0x50, 0x2f,  // TTP/
+      0x31,   0x2e, 0x31,        // 1.1
+  };
+  absl::string_view data(arr, ABSL_ARRAYSIZE(arr));
+  QuicStreamFrame frame(stream_->id(), true, 0, data);
+  // Verify that we don't crash when we get a invalid headers in stream frame.
+  stream_->OnStreamFrame(frame);
+}
+
+TEST_P(QuicSimpleServerStreamTest, ConnectSendsResponseBeforeFinReceived) {
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  header_list.OnHeaderBlockEnd(128, 128);
+  EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
+  stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
+  quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+      body_.length(), quiche::SimpleBufferAllocator::Get());
+  std::string data =
+      UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
+  stream_->OnStreamFrame(
+      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+  EXPECT_EQ("CONNECT", StreamHeadersValue(":method"));
+  EXPECT_EQ(body_, StreamBody());
+  EXPECT_TRUE(stream_->send_response_was_called());
+  EXPECT_FALSE(stream_->send_error_response_was_called());
+}
+
+TEST_P(QuicSimpleServerStreamTest, ConnectWithInvalidHeader) {
+  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+      .WillRepeatedly(
+          Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+  QuicHeaderList header_list;
+  header_list.OnHeaderBlockStart();
+  header_list.OnHeader(":authority", "www.google.com:4433");
+  header_list.OnHeader(":method", "CONNECT");
+  // QUIC requires lower-case header names.
+  header_list.OnHeader("InVaLiD-HeAdEr", "Well that's just wrong!");
+  header_list.OnHeaderBlockEnd(128, 128);
+
+  if (UsesHttp3()) {
+    EXPECT_CALL(session_,
+                MaybeSendStopSendingFrame(_, QuicResetStreamError::FromInternal(
+                                                 QUIC_STREAM_NO_ERROR)))
+        .Times(1);
+  } else {
+    EXPECT_CALL(
+        session_,
+        MaybeSendRstStreamFrame(
+            _, QuicResetStreamError::FromInternal(QUIC_STREAM_NO_ERROR), _))
+        .Times(1);
+  }
+  EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
+  stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
+  EXPECT_FALSE(stream_->send_response_was_called());
+  EXPECT_TRUE(stream_->send_error_response_was_called());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_spdy_client_base.cc b/quiche/quic/tools/quic_spdy_client_base.cc
new file mode 100644
index 0000000..f61a26d
--- /dev/null
+++ b/quiche/quic/tools/quic_spdy_client_base.cc
@@ -0,0 +1,296 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_spdy_client_base.h"
+
+#include <utility>
+
+#include "absl/strings/numbers.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/http/spdy_utils.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/quiche_text_utils.h"
+
+using spdy::Http2HeaderBlock;
+
+namespace quic {
+
+void QuicSpdyClientBase::ClientQuicDataToResend::Resend() {
+  client_->SendRequest(*headers_, body_, fin_);
+  headers_ = nullptr;
+}
+
+QuicSpdyClientBase::QuicDataToResend::QuicDataToResend(
+    std::unique_ptr<Http2HeaderBlock> headers,
+    absl::string_view body,
+    bool fin)
+    : headers_(std::move(headers)), body_(body), fin_(fin) {}
+
+QuicSpdyClientBase::QuicDataToResend::~QuicDataToResend() = default;
+
+QuicSpdyClientBase::QuicSpdyClientBase(
+    const QuicServerId& server_id,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicConfig& config,
+    QuicConnectionHelperInterface* helper,
+    QuicAlarmFactory* alarm_factory,
+    std::unique_ptr<NetworkHelper> network_helper,
+    std::unique_ptr<ProofVerifier> proof_verifier,
+    std::unique_ptr<SessionCache> session_cache)
+    : QuicClientBase(server_id,
+                     supported_versions,
+                     config,
+                     helper,
+                     alarm_factory,
+                     std::move(network_helper),
+                     std::move(proof_verifier),
+                     std::move(session_cache)),
+      store_response_(false),
+      latest_response_code_(-1) {}
+
+QuicSpdyClientBase::~QuicSpdyClientBase() {
+  // We own the push promise index. We need to explicitly kill
+  // the session before the push promise index goes out of scope.
+  ResetSession();
+}
+
+QuicSpdyClientSession* QuicSpdyClientBase::client_session() {
+  return static_cast<QuicSpdyClientSession*>(QuicClientBase::session());
+}
+
+const QuicSpdyClientSession* QuicSpdyClientBase::client_session() const {
+  return static_cast<const QuicSpdyClientSession*>(QuicClientBase::session());
+}
+
+void QuicSpdyClientBase::InitializeSession() {
+  if (max_inbound_header_list_size_ > 0) {
+    client_session()->set_max_inbound_header_list_size(
+        max_inbound_header_list_size_);
+  }
+  client_session()->Initialize();
+  client_session()->CryptoConnect();
+}
+
+void QuicSpdyClientBase::OnClose(QuicSpdyStream* stream) {
+  QUICHE_DCHECK(stream != nullptr);
+  QuicSpdyClientStream* client_stream =
+      static_cast<QuicSpdyClientStream*>(stream);
+
+  const Http2HeaderBlock& response_headers = client_stream->response_headers();
+  if (response_listener_ != nullptr) {
+    response_listener_->OnCompleteResponse(stream->id(), response_headers,
+                                           client_stream->data());
+  }
+
+  // Store response headers and body.
+  if (store_response_) {
+    auto status = response_headers.find(":status");
+    if (status == response_headers.end()) {
+      QUIC_LOG(ERROR) << "Missing :status response header";
+    } else if (!absl::SimpleAtoi(status->second, &latest_response_code_)) {
+      QUIC_LOG(ERROR) << "Invalid :status response header: " << status->second;
+    }
+    latest_response_headers_ = response_headers.DebugString();
+    preliminary_response_headers_ =
+        client_stream->preliminary_headers().DebugString();
+    latest_response_header_block_ = response_headers.Clone();
+    latest_response_body_ = client_stream->data();
+    latest_response_trailers_ =
+        client_stream->received_trailers().DebugString();
+  }
+}
+
+std::unique_ptr<QuicSession> QuicSpdyClientBase::CreateQuicClientSession(
+    const quic::ParsedQuicVersionVector& supported_versions,
+    QuicConnection* connection) {
+  return std::make_unique<QuicSpdyClientSession>(
+      *config(), supported_versions, connection, server_id(), crypto_config(),
+      &push_promise_index_);
+}
+
+void QuicSpdyClientBase::SendRequest(const Http2HeaderBlock& headers,
+                                     absl::string_view body,
+                                     bool fin) {
+  if (GetQuicFlag(FLAGS_quic_client_convert_http_header_name_to_lowercase)) {
+    QUIC_CODE_COUNT(quic_client_convert_http_header_name_to_lowercase);
+    Http2HeaderBlock sanitized_headers;
+    for (const auto& p : headers) {
+      sanitized_headers[quiche::QuicheTextUtils::ToLower(p.first)] = p.second;
+    }
+
+    SendRequestInternal(std::move(sanitized_headers), body, fin);
+  } else {
+    SendRequestInternal(headers.Clone(), body, fin);
+  }
+}
+
+void QuicSpdyClientBase::SendRequestInternal(Http2HeaderBlock sanitized_headers,
+                                             absl::string_view body,
+                                             bool fin) {
+  QuicClientPushPromiseIndex::TryHandle* handle;
+  QuicAsyncStatus rv =
+      push_promise_index()->Try(sanitized_headers, this, &handle);
+  if (rv == QUIC_SUCCESS)
+    return;
+
+  if (rv == QUIC_PENDING) {
+    // May need to retry request if asynchronous rendezvous fails.
+    AddPromiseDataToResend(sanitized_headers, body, fin);
+    return;
+  }
+
+  QuicSpdyClientStream* stream = CreateClientStream();
+  if (stream == nullptr) {
+    QUIC_BUG(quic_bug_10949_1) << "stream creation failed!";
+    return;
+  }
+  stream->SendRequest(std::move(sanitized_headers), body, fin);
+}
+
+void QuicSpdyClientBase::SendRequestAndWaitForResponse(
+    const Http2HeaderBlock& headers,
+    absl::string_view body,
+    bool fin) {
+  SendRequest(headers, body, fin);
+  while (WaitForEvents()) {
+  }
+}
+
+void QuicSpdyClientBase::SendRequestsAndWaitForResponse(
+    const std::vector<std::string>& url_list) {
+  for (size_t i = 0; i < url_list.size(); ++i) {
+    Http2HeaderBlock headers;
+    if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) {
+      QUIC_BUG(quic_bug_10949_2) << "Unable to create request";
+      continue;
+    }
+    SendRequest(headers, "", true);
+  }
+  while (WaitForEvents()) {
+  }
+}
+
+QuicSpdyClientStream* QuicSpdyClientBase::CreateClientStream() {
+  if (!connected()) {
+    return nullptr;
+  }
+  if (VersionHasIetfQuicFrames(client_session()->transport_version())) {
+    // Process MAX_STREAMS from peer or wait for liveness testing succeeds.
+    while (!client_session()->CanOpenNextOutgoingBidirectionalStream()) {
+      network_helper()->RunEventLoop();
+    }
+  }
+  auto* stream = static_cast<QuicSpdyClientStream*>(
+      client_session()->CreateOutgoingBidirectionalStream());
+  if (stream) {
+    stream->set_visitor(this);
+  }
+  return stream;
+}
+
+bool QuicSpdyClientBase::goaway_received() const {
+  return client_session() && client_session()->goaway_received();
+}
+
+bool QuicSpdyClientBase::EarlyDataAccepted() {
+  return client_session()->EarlyDataAccepted();
+}
+
+bool QuicSpdyClientBase::ReceivedInchoateReject() {
+  return client_session()->ReceivedInchoateReject();
+}
+
+int QuicSpdyClientBase::GetNumSentClientHellosFromSession() {
+  return client_session()->GetNumSentClientHellos();
+}
+
+int QuicSpdyClientBase::GetNumReceivedServerConfigUpdatesFromSession() {
+  return client_session()->GetNumReceivedServerConfigUpdates();
+}
+
+void QuicSpdyClientBase::MaybeAddQuicDataToResend(
+    std::unique_ptr<QuicDataToResend> data_to_resend) {
+  data_to_resend_on_connect_.push_back(std::move(data_to_resend));
+}
+
+void QuicSpdyClientBase::ClearDataToResend() {
+  data_to_resend_on_connect_.clear();
+}
+
+void QuicSpdyClientBase::ResendSavedData() {
+  // Calling Resend will re-enqueue the data, so swap out
+  //  data_to_resend_on_connect_ before iterating.
+  std::vector<std::unique_ptr<QuicDataToResend>> old_data;
+  old_data.swap(data_to_resend_on_connect_);
+  for (const auto& data : old_data) {
+    data->Resend();
+  }
+}
+
+void QuicSpdyClientBase::AddPromiseDataToResend(const Http2HeaderBlock& headers,
+                                                absl::string_view body,
+                                                bool fin) {
+  std::unique_ptr<Http2HeaderBlock> new_headers(
+      new Http2HeaderBlock(headers.Clone()));
+  push_promise_data_to_resend_.reset(
+      new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
+}
+
+bool QuicSpdyClientBase::CheckVary(
+    const Http2HeaderBlock& /*client_request*/,
+    const Http2HeaderBlock& /*promise_request*/,
+    const Http2HeaderBlock& /*promise_response*/) {
+  return true;
+}
+
+void QuicSpdyClientBase::OnRendezvousResult(QuicSpdyStream* stream) {
+  std::unique_ptr<ClientQuicDataToResend> data_to_resend =
+      std::move(push_promise_data_to_resend_);
+  if (stream) {
+    stream->set_visitor(this);
+    stream->OnBodyAvailable();
+  } else if (data_to_resend) {
+    data_to_resend->Resend();
+  }
+}
+
+int QuicSpdyClientBase::latest_response_code() const {
+  QUIC_BUG_IF(quic_bug_10949_3, !store_response_) << "Response not stored!";
+  return latest_response_code_;
+}
+
+const std::string& QuicSpdyClientBase::latest_response_headers() const {
+  QUIC_BUG_IF(quic_bug_10949_4, !store_response_) << "Response not stored!";
+  return latest_response_headers_;
+}
+
+const std::string& QuicSpdyClientBase::preliminary_response_headers() const {
+  QUIC_BUG_IF(quic_bug_10949_5, !store_response_) << "Response not stored!";
+  return preliminary_response_headers_;
+}
+
+const Http2HeaderBlock& QuicSpdyClientBase::latest_response_header_block()
+    const {
+  QUIC_BUG_IF(quic_bug_10949_6, !store_response_) << "Response not stored!";
+  return latest_response_header_block_;
+}
+
+const std::string& QuicSpdyClientBase::latest_response_body() const {
+  QUIC_BUG_IF(quic_bug_10949_7, !store_response_) << "Response not stored!";
+  return latest_response_body_;
+}
+
+const std::string& QuicSpdyClientBase::latest_response_trailers() const {
+  QUIC_BUG_IF(quic_bug_10949_8, !store_response_) << "Response not stored!";
+  return latest_response_trailers_;
+}
+
+bool QuicSpdyClientBase::HasActiveRequests() {
+  return client_session()->HasActiveRequestStreams();
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_spdy_client_base.h b/quiche/quic/tools/quic_spdy_client_base.h
new file mode 100644
index 0000000..921718a
--- /dev/null
+++ b/quiche/quic/tools/quic_spdy_client_base.h
@@ -0,0 +1,243 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A base class for the toy client, which connects to a specified port and sends
+// QUIC request to that endpoint.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/http/quic_client_push_promise_index.h"
+#include "quiche/quic/core/http/quic_spdy_client_session.h"
+#include "quiche/quic/core/http/quic_spdy_client_stream.h"
+#include "quiche/quic/core/quic_config.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_client_base.h"
+
+namespace quic {
+
+class ProofVerifier;
+class QuicServerId;
+class SessionCache;
+
+class QuicSpdyClientBase : public QuicClientBase,
+                           public QuicClientPushPromiseIndex::Delegate,
+                           public QuicSpdyStream::Visitor {
+ public:
+  // A ResponseListener is notified when a complete response is received.
+  class ResponseListener {
+   public:
+    ResponseListener() {}
+    virtual ~ResponseListener() {}
+    virtual void OnCompleteResponse(
+        QuicStreamId id,
+        const spdy::Http2HeaderBlock& response_headers,
+        const std::string& response_body) = 0;
+  };
+
+  // A piece of data that can be sent multiple times. For example, it can be a
+  // HTTP request that is resent after a connect=>version negotiation=>reconnect
+  // sequence.
+  class QuicDataToResend {
+   public:
+    // |headers| may be null, since it's possible to send data without headers.
+    QuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers,
+                     absl::string_view body,
+                     bool fin);
+    QuicDataToResend(const QuicDataToResend&) = delete;
+    QuicDataToResend& operator=(const QuicDataToResend&) = delete;
+
+    virtual ~QuicDataToResend();
+
+    // Must be overridden by specific classes with the actual method for
+    // re-sending data.
+    virtual void Resend() = 0;
+
+   protected:
+    std::unique_ptr<spdy::Http2HeaderBlock> headers_;
+    absl::string_view body_;
+    bool fin_;
+  };
+
+  QuicSpdyClientBase(const QuicServerId& server_id,
+                     const ParsedQuicVersionVector& supported_versions,
+                     const QuicConfig& config,
+                     QuicConnectionHelperInterface* helper,
+                     QuicAlarmFactory* alarm_factory,
+                     std::unique_ptr<NetworkHelper> network_helper,
+                     std::unique_ptr<ProofVerifier> proof_verifier,
+                     std::unique_ptr<SessionCache> session_cache);
+  QuicSpdyClientBase(const QuicSpdyClientBase&) = delete;
+  QuicSpdyClientBase& operator=(const QuicSpdyClientBase&) = delete;
+
+  ~QuicSpdyClientBase() override;
+
+  // QuicSpdyStream::Visitor
+  void OnClose(QuicSpdyStream* stream) override;
+
+  // A spdy session has to call CryptoConnect on top of the regular
+  // initialization.
+  void InitializeSession() override;
+
+  // Sends an HTTP request and does not wait for response before returning.
+  void SendRequest(const spdy::Http2HeaderBlock& headers,
+                   absl::string_view body,
+                   bool fin);
+
+  // Sends an HTTP request and waits for response before returning.
+  void SendRequestAndWaitForResponse(const spdy::Http2HeaderBlock& headers,
+                                     absl::string_view body,
+                                     bool fin);
+
+  // Sends a request simple GET for each URL in |url_list|, and then waits for
+  // each to complete.
+  void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list);
+
+  // Returns a newly created QuicSpdyClientStream.
+  QuicSpdyClientStream* CreateClientStream();
+
+  // Returns a the session used for this client downcasted to a
+  // QuicSpdyClientSession.
+  QuicSpdyClientSession* client_session();
+  const QuicSpdyClientSession* client_session() const;
+
+  QuicClientPushPromiseIndex* push_promise_index() {
+    return &push_promise_index_;
+  }
+
+  bool CheckVary(const spdy::Http2HeaderBlock& client_request,
+                 const spdy::Http2HeaderBlock& promise_request,
+                 const spdy::Http2HeaderBlock& promise_response) override;
+  void OnRendezvousResult(QuicSpdyStream*) override;
+
+  // If the crypto handshake has not yet been confirmed, adds the data to the
+  // queue of data to resend if the client receives a stateless reject.
+  // Otherwise, deletes the data.
+  void MaybeAddQuicDataToResend(
+      std::unique_ptr<QuicDataToResend> data_to_resend);
+
+  void set_store_response(bool val) { store_response_ = val; }
+
+  int latest_response_code() const;
+  const std::string& latest_response_headers() const;
+  const std::string& preliminary_response_headers() const;
+  const spdy::Http2HeaderBlock& latest_response_header_block() const;
+  const std::string& latest_response_body() const;
+  const std::string& latest_response_trailers() const;
+
+  void set_response_listener(std::unique_ptr<ResponseListener> listener) {
+    response_listener_ = std::move(listener);
+  }
+
+  void set_drop_response_body(bool drop_response_body) {
+    drop_response_body_ = drop_response_body;
+  }
+  bool drop_response_body() const { return drop_response_body_; }
+
+  void set_enable_web_transport(bool enable_web_transport) {
+    enable_web_transport_ = enable_web_transport;
+  }
+  bool enable_web_transport() const { return enable_web_transport_; }
+
+  void set_use_datagram_contexts(bool use_datagram_contexts) {
+    use_datagram_contexts_ = use_datagram_contexts;
+  }
+  bool use_datagram_contexts() const { return use_datagram_contexts_; }
+
+  // QuicClientBase methods.
+  bool goaway_received() const override;
+  bool EarlyDataAccepted() override;
+  bool ReceivedInchoateReject() override;
+
+  void set_max_inbound_header_list_size(size_t size) {
+    max_inbound_header_list_size_ = size;
+  }
+
+ protected:
+  int GetNumSentClientHellosFromSession() override;
+  int GetNumReceivedServerConfigUpdatesFromSession() override;
+
+  // Takes ownership of |connection|.
+  std::unique_ptr<QuicSession> CreateQuicClientSession(
+      const quic::ParsedQuicVersionVector& supported_versions,
+      QuicConnection* connection) override;
+
+  void ClearDataToResend() override;
+
+  void ResendSavedData() override;
+
+  void AddPromiseDataToResend(const spdy::Http2HeaderBlock& headers,
+                              absl::string_view body,
+                              bool fin);
+  bool HasActiveRequests() override;
+
+ private:
+  // Specific QuicClient class for storing data to resend.
+  class ClientQuicDataToResend : public QuicDataToResend {
+   public:
+    ClientQuicDataToResend(std::unique_ptr<spdy::Http2HeaderBlock> headers,
+                           absl::string_view body,
+                           bool fin,
+                           QuicSpdyClientBase* client)
+        : QuicDataToResend(std::move(headers), body, fin), client_(client) {
+      QUICHE_DCHECK(headers_);
+      QUICHE_DCHECK(client);
+    }
+
+    ClientQuicDataToResend(const ClientQuicDataToResend&) = delete;
+    ClientQuicDataToResend& operator=(const ClientQuicDataToResend&) = delete;
+    ~ClientQuicDataToResend() override {}
+
+    void Resend() override;
+
+   private:
+    QuicSpdyClientBase* client_;
+  };
+
+  void SendRequestInternal(spdy::Http2HeaderBlock sanitized_headers,
+                           absl::string_view body,
+                           bool fin);
+
+  // Index of pending promised streams. Must outlive |session_|.
+  QuicClientPushPromiseIndex push_promise_index_;
+
+  // If true, store the latest response code, headers, and body.
+  bool store_response_;
+  // HTTP response code from most recent response.
+  int latest_response_code_;
+  // HTTP/2 headers from most recent response.
+  std::string latest_response_headers_;
+  // preliminary 100 Continue HTTP/2 headers from most recent response, if any.
+  std::string preliminary_response_headers_;
+  // HTTP/2 headers from most recent response.
+  spdy::Http2HeaderBlock latest_response_header_block_;
+  // Body of most recent response.
+  std::string latest_response_body_;
+  // HTTP/2 trailers from most recent response.
+  std::string latest_response_trailers_;
+
+  // Listens for full responses.
+  std::unique_ptr<ResponseListener> response_listener_;
+
+  // Keeps track of any data that must be resent upon a subsequent successful
+  // connection, in case the client receives a stateless reject.
+  std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_;
+
+  std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_;
+
+  bool drop_response_body_ = false;
+  bool enable_web_transport_ = false;
+  bool use_datagram_contexts_ = false;
+  // If not zero, used to set client's max inbound header size before session
+  // initialize.
+  size_t max_inbound_header_list_size_ = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_
diff --git a/quiche/quic/tools/quic_spdy_server_base.h b/quiche/quic/tools/quic_spdy_server_base.h
new file mode 100644
index 0000000..39bde90
--- /dev/null
+++ b/quiche/quic/tools/quic_spdy_server_base.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A toy server, which connects to a specified port and sends QUIC
+// requests to that endpoint.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
+
+#include "quiche/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Base class for service instances to be used with QuicToyServer.
+class QuicSpdyServerBase {
+ public:
+  virtual ~QuicSpdyServerBase() = default;
+
+  // Creates a UDP socket and listens on |address|. Returns true on success
+  // and false otherwise.
+  virtual bool CreateUDPSocketAndListen(const QuicSocketAddress& address) = 0;
+
+  // Handles incoming requests. Does not return.
+  virtual void HandleEventsForever() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
diff --git a/quiche/quic/tools/quic_tcp_like_trace_converter.cc b/quiche/quic/tools/quic_tcp_like_trace_converter.cc
new file mode 100644
index 0000000..f1ae0c1
--- /dev/null
+++ b/quiche/quic/tools/quic_tcp_like_trace_converter.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_tcp_like_trace_converter.h"
+
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/platform/api/quic_bug_tracker.h"
+
+namespace quic {
+
+QuicTcpLikeTraceConverter::QuicTcpLikeTraceConverter()
+    : largest_observed_control_frame_id_(kInvalidControlFrameId),
+      connection_offset_(0) {}
+
+QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment()
+    : connection_offset(0) {}
+
+QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment(
+    QuicStreamOffset stream_offset,
+    uint64_t connection_offset,
+    QuicByteCount data_length)
+    : stream_data(stream_offset, stream_offset + data_length),
+      connection_offset(connection_offset) {}
+
+QuicTcpLikeTraceConverter::StreamInfo::StreamInfo() : fin(false) {}
+
+QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnCryptoFrameSent(
+    EncryptionLevel level,
+    QuicStreamOffset offset,
+    QuicByteCount data_length) {
+  if (level >= NUM_ENCRYPTION_LEVELS) {
+    QUIC_BUG(quic_bug_10907_1) << "Invalid encryption level";
+    return {};
+  }
+  return OnFrameSent(offset, data_length, /*fin=*/false,
+                     &crypto_frames_info_[level]);
+}
+
+QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnStreamFrameSent(
+    QuicStreamId stream_id,
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    bool fin) {
+  return OnFrameSent(
+      offset, data_length, fin,
+      &streams_info_.emplace(stream_id, StreamInfo()).first->second);
+}
+
+QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnFrameSent(
+    QuicStreamOffset offset,
+    QuicByteCount data_length,
+    bool fin,
+    StreamInfo* info) {
+  QuicIntervalSet<uint64_t> connection_offsets;
+  if (fin) {
+    // Stream fin consumes a connection offset.
+    ++data_length;
+  }
+  // Get connection offsets of retransmission data in this frame.
+  for (const auto& segment : info->segments) {
+    QuicInterval<QuicStreamOffset> retransmission(offset, offset + data_length);
+    retransmission.IntersectWith(segment.stream_data);
+    if (retransmission.Empty()) {
+      continue;
+    }
+    const uint64_t connection_offset = segment.connection_offset +
+                                       retransmission.min() -
+                                       segment.stream_data.min();
+    connection_offsets.Add(connection_offset,
+                           connection_offset + retransmission.Length());
+  }
+
+  if (info->fin) {
+    return connection_offsets;
+  }
+
+  // Get connection offsets of new data in this frame.
+  QuicStreamOffset least_unsent_offset =
+      info->segments.empty() ? 0 : info->segments.back().stream_data.max();
+  if (least_unsent_offset >= offset + data_length) {
+    return connection_offsets;
+  }
+  // Ignore out-of-order stream data so that as connection offset increases,
+  // stream offset increases.
+  QuicStreamOffset new_data_offset = std::max(least_unsent_offset, offset);
+  QuicByteCount new_data_length = offset + data_length - new_data_offset;
+  connection_offsets.Add(connection_offset_,
+                         connection_offset_ + new_data_length);
+  if (!info->segments.empty() && new_data_offset == least_unsent_offset &&
+      connection_offset_ == info->segments.back().connection_offset +
+                                info->segments.back().stream_data.Length()) {
+    // Extend the last segment if both stream and connection offsets are
+    // contiguous.
+    info->segments.back().stream_data.SetMax(new_data_offset + new_data_length);
+  } else {
+    info->segments.emplace_back(new_data_offset, connection_offset_,
+                                new_data_length);
+  }
+  info->fin = fin;
+  connection_offset_ += new_data_length;
+
+  return connection_offsets;
+}
+
+QuicInterval<uint64_t> QuicTcpLikeTraceConverter::OnControlFrameSent(
+    QuicControlFrameId control_frame_id,
+    QuicByteCount control_frame_length) {
+  if (control_frame_id > largest_observed_control_frame_id_) {
+    // New control frame.
+    QuicInterval<uint64_t> connection_offset = QuicInterval<uint64_t>(
+        connection_offset_, connection_offset_ + control_frame_length);
+    connection_offset_ += control_frame_length;
+    control_frames_info_[control_frame_id] = connection_offset;
+    largest_observed_control_frame_id_ = control_frame_id;
+    return connection_offset;
+  }
+  const auto iter = control_frames_info_.find(control_frame_id);
+  if (iter == control_frames_info_.end()) {
+    // Ignore out of order control frames.
+    return {};
+  }
+  return iter->second;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_tcp_like_trace_converter.h b/quiche/quic/tools/quic_tcp_like_trace_converter.h
new file mode 100644
index 0000000..78cbaf9
--- /dev/null
+++ b/quiche/quic/tools/quic_tcp_like_trace_converter.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
+
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/quic/core/frames/quic_stream_frame.h"
+#include "quiche/quic/core/quic_interval.h"
+#include "quiche/quic/core/quic_interval_set.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+
+namespace quic {
+
+// This converter converts sent QUIC frames to connection byte offset (just like
+// TCP byte sequence number).
+class QuicTcpLikeTraceConverter {
+ public:
+  // StreamOffsetSegment stores a stream offset range which has contiguous
+  // connection offset.
+  struct StreamOffsetSegment {
+    StreamOffsetSegment();
+    StreamOffsetSegment(QuicStreamOffset stream_offset,
+                        uint64_t connection_offset,
+                        QuicByteCount data_length);
+
+    QuicInterval<QuicStreamOffset> stream_data;
+    uint64_t connection_offset;
+  };
+
+  QuicTcpLikeTraceConverter();
+  QuicTcpLikeTraceConverter(const QuicTcpLikeTraceConverter& other) = delete;
+  QuicTcpLikeTraceConverter(QuicTcpLikeTraceConverter&& other) = delete;
+
+  ~QuicTcpLikeTraceConverter() {}
+
+  // Called when a crypto frame is sent. Returns the corresponding connection
+  // offsets.
+  QuicIntervalSet<uint64_t> OnCryptoFrameSent(EncryptionLevel level,
+                                              QuicStreamOffset offset,
+                                              QuicByteCount data_length);
+
+  // Called when a stream frame is sent. Returns the corresponding connection
+  // offsets.
+  QuicIntervalSet<uint64_t> OnStreamFrameSent(QuicStreamId stream_id,
+                                              QuicStreamOffset offset,
+                                              QuicByteCount data_length,
+                                              bool fin);
+
+  // Called when a control frame is sent. Returns the corresponding connection
+  // offsets.
+  QuicInterval<uint64_t> OnControlFrameSent(QuicControlFrameId control_frame_id,
+                                            QuicByteCount control_frame_length);
+
+ private:
+  struct StreamInfo {
+    StreamInfo();
+
+    // Stores contiguous connection offset pieces.
+    std::vector<StreamOffsetSegment> segments;
+    // Indicates whether fin has been sent.
+    bool fin;
+  };
+
+  // Called when frame with |offset|, |data_length| and |fin| has been sent.
+  // Update |info| and returns connection offsets.
+  QuicIntervalSet<uint64_t> OnFrameSent(QuicStreamOffset offset,
+                                        QuicByteCount data_length,
+                                        bool fin,
+                                        StreamInfo* info);
+
+  StreamInfo crypto_frames_info_[NUM_ENCRYPTION_LEVELS];
+  absl::flat_hash_map<QuicStreamId, StreamInfo> streams_info_;
+  absl::flat_hash_map<QuicControlFrameId, QuicInterval<uint64_t>>
+      control_frames_info_;
+
+  QuicControlFrameId largest_observed_control_frame_id_;
+
+  uint64_t connection_offset_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_TCP_LIKE_TRACE_CONVERTER_H_
diff --git a/quiche/quic/tools/quic_tcp_like_trace_converter_test.cc b/quiche/quic/tools/quic_tcp_like_trace_converter_test.cc
new file mode 100644
index 0000000..287a319
--- /dev/null
+++ b/quiche/quic/tools/quic_tcp_like_trace_converter_test.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_tcp_like_trace_converter.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+TEST(QuicTcpLikeTraceConverterTest, BasicTest) {
+  QuicTcpLikeTraceConverter converter;
+
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
+            converter.OnStreamFrameSent(1, 0, 100, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
+            converter.OnStreamFrameSent(3, 0, 100, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
+            converter.OnStreamFrameSent(3, 100, 100, false));
+  EXPECT_EQ(QuicInterval<uint64_t>(300, 450),
+            converter.OnControlFrameSent(2, 150));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(450, 550),
+            converter.OnStreamFrameSent(1, 100, 100, false));
+  EXPECT_EQ(QuicInterval<uint64_t>(550, 650),
+            converter.OnControlFrameSent(3, 100));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(650, 850),
+            converter.OnStreamFrameSent(3, 200, 200, false));
+  EXPECT_EQ(QuicInterval<uint64_t>(850, 1050),
+            converter.OnControlFrameSent(4, 200));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(1050, 1100),
+            converter.OnStreamFrameSent(1, 200, 50, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(1100, 1150),
+            converter.OnStreamFrameSent(1, 250, 50, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(1150, 1350),
+            converter.OnStreamFrameSent(3, 400, 200, false));
+
+  // Stream 1 retransmits [50, 300) and sends new data [300, 350) in the same
+  // frame.
+  QuicIntervalSet<uint64_t> expected;
+  expected.Add(50, 100);
+  expected.Add(450, 550);
+  expected.Add(1050, 1150);
+  expected.Add(1350, 1401);
+  EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 300, true));
+
+  expected.Clear();
+  // Stream 3 retransmits [150, 500).
+  expected.Add(250, 300);
+  expected.Add(650, 850);
+  expected.Add(1150, 1250);
+  EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 150, 350, false));
+
+  // Stream 3 retransmits [300, 600) and sends new data [600, 800) in the same
+  // frame.
+  expected.Clear();
+  expected.Add(750, 850);
+  expected.Add(1150, 1350);
+  expected.Add(1401, 1602);
+  EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 300, 500, true));
+
+  // Stream 3 retransmits fin only frame.
+  expected.Clear();
+  expected.Add(1601, 1602);
+  EXPECT_EQ(expected, converter.OnStreamFrameSent(3, 800, 0, true));
+
+  QuicInterval<uint64_t> expected2;
+  // Ignore out of order control frames.
+  EXPECT_EQ(expected2, converter.OnControlFrameSent(1, 100));
+
+  // Ignore passed in length for retransmitted frame.
+  expected2 = {300, 450};
+  EXPECT_EQ(expected2, converter.OnControlFrameSent(2, 200));
+
+  expected2 = {1602, 1702};
+  EXPECT_EQ(expected2, converter.OnControlFrameSent(10, 100));
+}
+
+TEST(QuicTcpLikeTraceConverterTest, FuzzerTest) {
+  QuicTcpLikeTraceConverter converter;
+  // Stream does not start from offset 0.
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
+            converter.OnStreamFrameSent(1, 100, 100, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 300),
+            converter.OnStreamFrameSent(3, 200, 200, false));
+  // Stream does not send data contiguously.
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
+            converter.OnStreamFrameSent(1, 300, 100, false));
+
+  // Stream fills existing holes.
+  QuicIntervalSet<uint64_t> expected;
+  expected.Add(0, 100);
+  expected.Add(300, 501);
+  EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 0, 500, true));
+
+  // Stream sends frame after fin.
+  EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 600, false));
+}
+
+TEST(QuicTcpLikeTraceConverterTest, OnCryptoFrameSent) {
+  QuicTcpLikeTraceConverter converter;
+
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
+            converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
+            converter.OnStreamFrameSent(1, 0, 100, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
+            converter.OnStreamFrameSent(1, 100, 100, false));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
+            converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 0, 100));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
+            converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
+
+  // Verify crypto frame retransmission works as intended.
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
+            converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
+  EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
+            converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_toy_client.cc b/quiche/quic/tools/quic_toy_client.cc
new file mode 100644
index 0000000..9baccbf
--- /dev/null
+++ b/quiche/quic/tools/quic_toy_client.cc
@@ -0,0 +1,501 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A binary wrapper for QuicClient.
+// Connects to a host using QUIC, sends a request to the provided URL, and
+// displays the response.
+//
+// Some usage examples:
+//
+// Standard request/response:
+//   quic_client www.google.com
+//   quic_client www.google.com --quiet
+//   quic_client www.google.com --port=443
+//
+// Use a specific version:
+//   quic_client www.google.com --quic_version=23
+//
+// Send a POST instead of a GET:
+//   quic_client www.google.com --body="this is a POST body"
+//
+// Append additional headers to the request:
+//   quic_client www.google.com --headers="Header-A: 1234; Header-B: 5678"
+//
+// Connect to a host different to the URL being requested:
+//   quic_client mail.google.com --host=www.google.com
+//
+// Connect to a specific IP:
+//   IP=`dig www.google.com +short | head -1`
+//   quic_client www.google.com --host=${IP}
+//
+// Send repeated requests and change ephemeral port between requests
+//   quic_client www.google.com --num_requests=10
+//
+// Try to connect to a host which does not speak QUIC:
+//   quic_client www.example.com
+//
+// This tool is available as a built binary at:
+// /google/data/ro/teams/quic/tools/quic_client
+// After submitting changes to this file, you will need to follow the
+// instructions at go/quic_client_binary_update
+
+#include "quiche/quic/tools/quic_toy_client.h"
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+#include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_default_proof_providers.h"
+#include "quiche/quic/platform/api/quic_ip_address.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/fake_proof_verifier.h"
+#include "quiche/quic/tools/quic_url.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace {
+
+using quiche::QuicheTextUtils;
+
+}  // namespace
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, host, "",
+    "The IP or hostname to connect to. If not provided, the host "
+    "will be derived from the provided URL.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, ip_version_for_host_lookup, "",
+                                "Only used if host address lookup is needed. "
+                                "4=ipv4; 6=ipv6; otherwise=don't care.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, body, "",
+                                "If set, send a POST with this body.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, body_hex, "",
+    "If set, contents are converted from hex to ascii, before "
+    "sending as body of a POST. e.g. --body_hex=\"68656c6c6f\"");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, headers, "",
+    "A semicolon separated list of key:value pairs to "
+    "add to request headers.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quiet, false,
+                                "Set to true for a quieter output experience.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_version, "",
+    "QUIC version to speak, e.g. 21. If not set, then all available "
+    "versions are offered in the handshake. Also supports wire versions "
+    "such as Q043 or T099.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, connection_options, "",
+    "Connection options as ASCII tags separated by commas, "
+    "e.g. \"ABCD,EFGH\"");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, client_connection_options, "",
+    "Client connection options as ASCII tags separated by commas, "
+    "e.g. \"ABCD,EFGH\"");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
+                                "Use the IETF draft version. This also enables "
+                                "required internal QUIC flags.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, version_mismatch_ok, false,
+    "If true, a version mismatch in the handshake is not considered a "
+    "failure. Useful for probing a server to determine if it speaks "
+    "any version of QUIC.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, force_version_negotiation, false,
+    "If true, start by proposing a version that is reserved for version "
+    "negotiation.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, multi_packet_chlo, false,
+    "If true, add a transport parameter to make the ClientHello span two "
+    "packets. Only works with QUIC+TLS.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, redirect_is_success, true,
+    "If true, an HTTP response code of 3xx is considered to be a "
+    "successful response, otherwise a failure.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, initial_mtu, 0,
+                                "Initial MTU of the connection.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    int32_t, num_requests, 1,
+    "How many sequential requests to make on a single connection.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, disable_certificate_verification, false,
+    "If true, don't verify the server certificate.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, default_client_cert, "",
+    "The path to the file containing PEM-encoded client default certificate to "
+    "be sent to the server, if server requested client certs.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, default_client_cert_key, "",
+    "The path to the file containing PEM-encoded private key of the client's "
+    "default certificate for signing, if server requested client certs.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, drop_response_body, false,
+    "If true, drop response body immediately after it is received.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, disable_port_changes, false,
+    "If true, do not change local port after each request.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, one_connection_per_request, false,
+                                "If true, close the connection after each "
+                                "request. This allows testing 0-RTT.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, server_connection_id_length, -1,
+                                "Length of the server connection ID used.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, client_connection_id_length, -1,
+                                "Length of the client connection ID used.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, max_time_before_crypto_handshake_ms,
+                                10000,
+                                "Max time to wait before handshake completes.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    int32_t, max_inbound_header_list_size, 128 * 1024,
+    "Max inbound header list size. 0 means default.");
+
+namespace quic {
+namespace {
+
+// Creates a ClientProofSource which only contains a default client certificate.
+// Return nullptr for failure.
+std::unique_ptr<ClientProofSource> CreateTestClientProofSource(
+    absl::string_view default_client_cert_file,
+    absl::string_view default_client_cert_key_file) {
+  std::ifstream cert_stream(std::string{default_client_cert_file},
+                            std::ios::binary);
+  std::vector<std::string> certs =
+      CertificateView::LoadPemFromStream(&cert_stream);
+  if (certs.empty()) {
+    std::cerr << "Failed to load client certs." << std::endl;
+    return nullptr;
+  }
+
+  std::ifstream key_stream(std::string{default_client_cert_key_file},
+                           std::ios::binary);
+  std::unique_ptr<CertificatePrivateKey> private_key =
+      CertificatePrivateKey::LoadPemFromStream(&key_stream);
+  if (private_key == nullptr) {
+    std::cerr << "Failed to load client cert key." << std::endl;
+    return nullptr;
+  }
+
+  auto proof_source = std::make_unique<DefaultClientProofSource>();
+  proof_source->AddCertAndKey(
+      {"*"},
+      quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+          new ClientProofSource::Chain(certs)),
+      std::move(*private_key));
+
+  return proof_source;
+}
+
+}  // namespace
+
+QuicToyClient::QuicToyClient(ClientFactory* client_factory)
+    : client_factory_(client_factory) {}
+
+int QuicToyClient::SendRequestsAndPrintResponses(
+    std::vector<std::string> urls) {
+  QuicUrl url(urls[0], "https");
+  std::string host = GetQuicFlag(FLAGS_host);
+  if (host.empty()) {
+    host = url.host();
+  }
+  int port = GetQuicFlag(FLAGS_port);
+  if (port == 0) {
+    port = url.port();
+  }
+
+  quic::ParsedQuicVersionVector versions = quic::CurrentSupportedVersions();
+
+  if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
+    quic::QuicVersionInitializeSupportForIetfDraft();
+    versions = {};
+    for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+      if (version.HasIetfQuicFrames() &&
+          version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+        versions.push_back(version);
+      }
+    }
+  }
+
+  std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
+  if (!quic_version_string.empty()) {
+    versions = quic::ParseQuicVersionVectorString(quic_version_string);
+  }
+
+  if (versions.empty()) {
+    std::cerr << "No known version selected." << std::endl;
+    return 1;
+  }
+
+  for (const quic::ParsedQuicVersion& version : versions) {
+    quic::QuicEnableVersion(version);
+  }
+
+  if (GetQuicFlag(FLAGS_force_version_negotiation)) {
+    versions.insert(versions.begin(),
+                    quic::QuicVersionReservedForNegotiation());
+  }
+
+  const int32_t num_requests(GetQuicFlag(FLAGS_num_requests));
+  std::unique_ptr<quic::ProofVerifier> proof_verifier;
+  if (GetQuicFlag(FLAGS_disable_certificate_verification)) {
+    proof_verifier = std::make_unique<FakeProofVerifier>();
+  } else {
+    proof_verifier = quic::CreateDefaultProofVerifier(url.host());
+  }
+  std::unique_ptr<quic::SessionCache> session_cache;
+  if (num_requests > 1 && GetQuicFlag(FLAGS_one_connection_per_request)) {
+    session_cache = std::make_unique<QuicClientSessionCache>();
+  }
+
+  QuicConfig config;
+  std::string connection_options_string = GetQuicFlag(FLAGS_connection_options);
+  if (!connection_options_string.empty()) {
+    config.SetConnectionOptionsToSend(
+        ParseQuicTagVector(connection_options_string));
+  }
+  std::string client_connection_options_string =
+      GetQuicFlag(FLAGS_client_connection_options);
+  if (!client_connection_options_string.empty()) {
+    config.SetClientConnectionOptions(
+        ParseQuicTagVector(client_connection_options_string));
+  }
+  if (GetQuicFlag(FLAGS_multi_packet_chlo)) {
+    // Make the ClientHello span multiple packets by adding a custom transport
+    // parameter.
+    constexpr auto kCustomParameter =
+        static_cast<TransportParameters::TransportParameterId>(0x173E);
+    std::string custom_value(2000, '?');
+    config.custom_transport_parameters_to_send()[kCustomParameter] =
+        custom_value;
+  }
+  config.set_max_time_before_crypto_handshake(QuicTime::Delta::FromMilliseconds(
+      GetQuicFlag(FLAGS_max_time_before_crypto_handshake_ms)));
+
+  int address_family_for_lookup = AF_UNSPEC;
+  if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "4") {
+    address_family_for_lookup = AF_INET;
+  } else if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "6") {
+    address_family_for_lookup = AF_INET6;
+  }
+
+  // Build the client, and try to connect.
+  std::unique_ptr<QuicSpdyClientBase> client = client_factory_->CreateClient(
+      url.host(), host, address_family_for_lookup, port, versions, config,
+      std::move(proof_verifier), std::move(session_cache));
+
+  if (client == nullptr) {
+    std::cerr << "Failed to create client." << std::endl;
+    return 1;
+  }
+
+  if (!GetQuicFlag(FLAGS_default_client_cert).empty() &&
+      !GetQuicFlag(FLAGS_default_client_cert_key).empty()) {
+    std::unique_ptr<ClientProofSource> proof_source =
+        CreateTestClientProofSource(GetQuicFlag(FLAGS_default_client_cert),
+                                    GetQuicFlag(FLAGS_default_client_cert_key));
+    if (proof_source == nullptr) {
+      std::cerr << "Failed to create client proof source." << std::endl;
+      return 1;
+    }
+    client->crypto_config()->set_proof_source(std::move(proof_source));
+  }
+
+  int32_t initial_mtu = GetQuicFlag(FLAGS_initial_mtu);
+  client->set_initial_max_packet_length(
+      initial_mtu != 0 ? initial_mtu : quic::kDefaultMaxPacketSize);
+  client->set_drop_response_body(GetQuicFlag(FLAGS_drop_response_body));
+  const int32_t server_connection_id_length =
+      GetQuicFlag(FLAGS_server_connection_id_length);
+  if (server_connection_id_length >= 0) {
+    client->set_server_connection_id_length(server_connection_id_length);
+  }
+  const int32_t client_connection_id_length =
+      GetQuicFlag(FLAGS_client_connection_id_length);
+  if (client_connection_id_length >= 0) {
+    client->set_client_connection_id_length(client_connection_id_length);
+  }
+  const size_t max_inbound_header_list_size =
+      GetQuicFlag(FLAGS_max_inbound_header_list_size);
+  if (max_inbound_header_list_size > 0) {
+    client->set_max_inbound_header_list_size(max_inbound_header_list_size);
+  }
+  if (!client->Initialize()) {
+    std::cerr << "Failed to initialize client." << std::endl;
+    return 1;
+  }
+  if (!client->Connect()) {
+    quic::QuicErrorCode error = client->session()->error();
+    if (error == quic::QUIC_INVALID_VERSION) {
+      std::cerr << "Failed to negotiate version with " << host << ":" << port
+                << ". " << client->session()->error_details() << std::endl;
+      // 0: No error.
+      // 20: Failed to connect due to QUIC_INVALID_VERSION.
+      return GetQuicFlag(FLAGS_version_mismatch_ok) ? 0 : 20;
+    }
+    std::cerr << "Failed to connect to " << host << ":" << port << ". "
+              << quic::QuicErrorCodeToString(error) << " "
+              << client->session()->error_details() << std::endl;
+    return 1;
+  }
+  std::cerr << "Connected to " << host << ":" << port << std::endl;
+
+  // Construct the string body from flags, if provided.
+  std::string body = GetQuicFlag(FLAGS_body);
+  if (!GetQuicFlag(FLAGS_body_hex).empty()) {
+    QUICHE_DCHECK(GetQuicFlag(FLAGS_body).empty())
+        << "Only set one of --body and --body_hex.";
+    body = absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex));
+  }
+
+  // Construct a GET or POST request for supplied URL.
+  spdy::Http2HeaderBlock header_block;
+  header_block[":method"] = body.empty() ? "GET" : "POST";
+  header_block[":scheme"] = url.scheme();
+  header_block[":authority"] = url.HostPort();
+  header_block[":path"] = url.PathParamsQuery();
+
+  // Append any additional headers supplied on the command line.
+  const std::string headers = GetQuicFlag(FLAGS_headers);
+  for (absl::string_view sp : absl::StrSplit(headers, ';')) {
+    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp);
+    if (sp.empty()) {
+      continue;
+    }
+    std::vector<absl::string_view> kv =
+        absl::StrSplit(sp, absl::MaxSplits(':', 1));
+    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[0]);
+    QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&kv[1]);
+    header_block[kv[0]] = kv[1];
+  }
+
+  // Make sure to store the response, for later output.
+  client->set_store_response(true);
+
+  for (int i = 0; i < num_requests; ++i) {
+    // Send the request.
+    client->SendRequestAndWaitForResponse(header_block, body, /*fin=*/true);
+
+    // Print request and response details.
+    if (!GetQuicFlag(FLAGS_quiet)) {
+      std::cout << "Request:" << std::endl;
+      std::cout << "headers:" << header_block.DebugString();
+      if (!GetQuicFlag(FLAGS_body_hex).empty()) {
+        // Print the user provided hex, rather than binary body.
+        std::cout << "body:\n"
+                  << QuicheTextUtils::HexDump(
+                         absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex)))
+                  << std::endl;
+      } else {
+        std::cout << "body: " << body << std::endl;
+      }
+      std::cout << std::endl;
+
+      if (!client->preliminary_response_headers().empty()) {
+        std::cout << "Preliminary response headers: "
+                  << client->preliminary_response_headers() << std::endl;
+        std::cout << std::endl;
+      }
+
+      std::cout << "Response:" << std::endl;
+      std::cout << "headers: " << client->latest_response_headers()
+                << std::endl;
+      std::string response_body = client->latest_response_body();
+      if (!GetQuicFlag(FLAGS_body_hex).empty()) {
+        // Assume response is binary data.
+        std::cout << "body:\n"
+                  << QuicheTextUtils::HexDump(response_body) << std::endl;
+      } else {
+        std::cout << "body: " << response_body << std::endl;
+      }
+      std::cout << "trailers: " << client->latest_response_trailers()
+                << std::endl;
+    }
+
+    if (!client->connected()) {
+      std::cerr << "Request caused connection failure. Error: "
+                << quic::QuicErrorCodeToString(client->session()->error())
+                << std::endl;
+      return 1;
+    }
+
+    int response_code = client->latest_response_code();
+    if (response_code >= 200 && response_code < 300) {
+      std::cout << "Request succeeded (" << response_code << ")." << std::endl;
+    } else if (response_code >= 300 && response_code < 400) {
+      if (GetQuicFlag(FLAGS_redirect_is_success)) {
+        std::cout << "Request succeeded (redirect " << response_code << ")."
+                  << std::endl;
+      } else {
+        std::cout << "Request failed (redirect " << response_code << ")."
+                  << std::endl;
+        return 1;
+      }
+    } else {
+      std::cout << "Request failed (" << response_code << ")." << std::endl;
+      return 1;
+    }
+
+    if (i + 1 < num_requests) {  // There are more requests to perform.
+      if (GetQuicFlag(FLAGS_one_connection_per_request)) {
+        std::cout << "Disconnecting client between requests." << std::endl;
+        client->Disconnect();
+        if (!client->Initialize()) {
+          std::cerr << "Failed to reinitialize client between requests."
+                    << std::endl;
+          return 1;
+        }
+        if (!client->Connect()) {
+          std::cerr << "Failed to reconnect client between requests."
+                    << std::endl;
+          return 1;
+        }
+      } else if (!GetQuicFlag(FLAGS_disable_port_changes)) {
+        // Change the ephemeral port.
+        if (!client->ChangeEphemeralPort()) {
+          std::cerr << "Failed to change ephemeral port." << std::endl;
+          return 1;
+        }
+      }
+    }
+  }
+
+  return 0;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_toy_client.h b/quiche/quic/tools/quic_toy_client.h
new file mode 100644
index 0000000..5f884f0
--- /dev/null
+++ b/quiche/quic/tools/quic_toy_client.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A toy client, which connects to a specified port and sends QUIC
+// requests to that endpoint.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
+#define QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
+
+#include "quiche/quic/tools/quic_spdy_client_base.h"
+
+namespace quic {
+
+class QuicToyClient {
+ public:
+  class ClientFactory {
+   public:
+    virtual ~ClientFactory() = default;
+
+    // Creates a new client configured to connect to |host_for_lookup:port|
+    // supporting |versions|, using |host_for_handshake| for handshake and
+    // |verifier| to verify proofs.
+    virtual std::unique_ptr<QuicSpdyClientBase> CreateClient(
+        std::string host_for_handshake,
+        std::string host_for_lookup,
+        // AF_INET, AF_INET6, or AF_UNSPEC(=don't care).
+        int address_family_for_lookup,
+        uint16_t port,
+        ParsedQuicVersionVector versions,
+        const QuicConfig& config,
+        std::unique_ptr<ProofVerifier> verifier,
+        std::unique_ptr<SessionCache> session_cache) = 0;
+  };
+
+  // Constructs a new toy client that will use |client_factory| to create the
+  // actual QuicSpdyClientBase instance.
+  QuicToyClient(ClientFactory* client_factory);
+
+  // Connects to the QUIC server based on the various flags defined in the
+  // .cc file, sends requests and prints the responses. Returns 0 on success
+  // and non-zero otherwise.
+  int SendRequestsAndPrintResponses(std::vector<std::string> urls);
+
+ private:
+  ClientFactory* client_factory_;  // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_TOY_CLIENT_H_
diff --git a/quiche/quic/tools/quic_toy_server.cc b/quiche/quic/tools/quic_toy_server.cc
new file mode 100644
index 0000000..03f910c
--- /dev/null
+++ b/quiche/quic/tools/quic_toy_server.cc
@@ -0,0 +1,103 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_toy_server.h"
+
+#include <utility>
+#include <vector>
+
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_default_proof_providers.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/common/platform/api/quiche_command_line_flags.h"
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 6121,
+                                "The port the quic server will listen on.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_response_cache_dir, "",
+    "Specifies the directory used during QuicHttpResponseCache "
+    "construction to seed the cache. Cache directory can be "
+    "generated using `wget -p --save-headers <url>`");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    bool, generate_dynamic_responses, false,
+    "If true, then URLs which have a numeric path will send a dynamically "
+    "generated response of that many bytes.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, quic_ietf_draft, false,
+                                "Only enable IETF draft versions. This also "
+                                "enables required internal QUIC flags.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    std::string, quic_versions, "",
+    "QUIC versions to enable, e.g. \"h3-25,h3-27\". If not set, then all "
+    "available versions are enabled.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, enable_webtransport, false,
+                                "If true, WebTransport support is enabled.");
+
+namespace quic {
+
+std::unique_ptr<quic::QuicSimpleServerBackend>
+QuicToyServer::MemoryCacheBackendFactory::CreateBackend() {
+  auto memory_cache_backend = std::make_unique<QuicMemoryCacheBackend>();
+  if (GetQuicFlag(FLAGS_generate_dynamic_responses)) {
+    memory_cache_backend->GenerateDynamicResponses();
+  }
+  if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
+    memory_cache_backend->InitializeBackend(
+        GetQuicFlag(FLAGS_quic_response_cache_dir));
+  }
+  if (GetQuicFlag(FLAGS_enable_webtransport)) {
+    memory_cache_backend->EnableWebTransport();
+  }
+  return memory_cache_backend;
+}
+
+QuicToyServer::QuicToyServer(BackendFactory* backend_factory,
+                             ServerFactory* server_factory)
+    : backend_factory_(backend_factory), server_factory_(server_factory) {}
+
+int QuicToyServer::Start() {
+  ParsedQuicVersionVector supported_versions;
+  if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
+    QuicVersionInitializeSupportForIetfDraft();
+    for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+      // Add all versions that supports IETF QUIC.
+      if (version.HasIetfQuicFrames() &&
+          version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+        supported_versions.push_back(version);
+      }
+    }
+  } else {
+    supported_versions = AllSupportedVersions();
+  }
+  std::string versions_string = GetQuicFlag(FLAGS_quic_versions);
+  if (!versions_string.empty()) {
+    supported_versions = ParseQuicVersionVectorString(versions_string);
+  }
+  if (supported_versions.empty()) {
+    return 1;
+  }
+  for (const auto& version : supported_versions) {
+    QuicEnableVersion(version);
+  }
+  auto proof_source = quic::CreateDefaultProofSource();
+  auto backend = backend_factory_->CreateBackend();
+  auto server = server_factory_->CreateServer(
+      backend.get(), std::move(proof_source), supported_versions);
+
+  if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
+          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
+    return 1;
+  }
+
+  server->HandleEventsForever();
+  return 0;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_toy_server.h b/quiche/quic/tools/quic_toy_server.h
new file mode 100644
index 0000000..fc82ff7
--- /dev/null
+++ b/quiche/quic/tools/quic_toy_server.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
+
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
+#include "quiche/quic/tools/quic_spdy_server_base.h"
+
+namespace quic {
+
+// A binary wrapper for QuicServer.  It listens forever on --port
+// (default 6121) until it's killed or ctrl-cd to death.
+class QuicToyServer {
+ public:
+  // A factory for creating QuicSpdyServerBase instances.
+  class ServerFactory {
+   public:
+    virtual ~ServerFactory() = default;
+
+    // Creates a QuicSpdyServerBase instance using |backend| for generating
+    // responses, and |proof_source| for certificates.
+    virtual std::unique_ptr<QuicSpdyServerBase> CreateServer(
+        QuicSimpleServerBackend* backend,
+        std::unique_ptr<ProofSource> proof_source,
+        const ParsedQuicVersionVector& supported_versions) = 0;
+  };
+
+  // A facotry for creating QuicSimpleServerBackend instances.
+  class BackendFactory {
+   public:
+    virtual ~BackendFactory() = default;
+
+    // Creates a new backend.
+    virtual std::unique_ptr<QuicSimpleServerBackend> CreateBackend() = 0;
+  };
+
+  // A factory for creating QuicMemoryCacheBackend instances, configured
+  // to load files from disk, if necessary.
+  class MemoryCacheBackendFactory : public BackendFactory {
+   public:
+    std::unique_ptr<quic::QuicSimpleServerBackend> CreateBackend() override;
+  };
+
+  // Constructs a new toy server that will use |server_factory| to create the
+  // actual QuicSpdyServerBase instance.
+  QuicToyServer(BackendFactory* backend_factory, ServerFactory* server_factory);
+
+  // Connects to the QUIC server based on the various flags defined in the
+  // .cc file, listends for requests and sends the responses. Returns 1 on
+  // failure and does not return otherwise.
+  int Start();
+
+ private:
+  BackendFactory* backend_factory_;  // Unowned.
+  ServerFactory* server_factory_;    // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
diff --git a/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc b/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc
new file mode 100644
index 0000000..91c7816
--- /dev/null
+++ b/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_transport_simple_server_dispatcher.h"
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/tools/quic_transport_simple_server_session.h"
+
+namespace quic {
+
+QuicTransportSimpleServerDispatcher::QuicTransportSimpleServerDispatcher(
+    const QuicConfig* config,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicVersionManager* version_manager,
+    std::unique_ptr<QuicConnectionHelperInterface> helper,
+    std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+    std::unique_ptr<QuicAlarmFactory> alarm_factory,
+    uint8_t expected_server_connection_id_length,
+    std::vector<url::Origin> accepted_origins)
+    : QuicDispatcher(config,
+                     crypto_config,
+                     version_manager,
+                     std::move(helper),
+                     std::move(session_helper),
+                     std::move(alarm_factory),
+                     expected_server_connection_id_length),
+      accepted_origins_(accepted_origins) {}
+
+std::unique_ptr<QuicSession>
+QuicTransportSimpleServerDispatcher::CreateQuicSession(
+    QuicConnectionId server_connection_id,
+    const QuicSocketAddress& self_address,
+    const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
+    const ParsedQuicVersion& version,
+    const ParsedClientHello& /*parsed_chlo*/) {
+  auto connection = std::make_unique<QuicConnection>(
+      server_connection_id, self_address, peer_address, helper(),
+      alarm_factory(), writer(),
+      /*owns_writer=*/false, Perspective::IS_SERVER,
+      ParsedQuicVersionVector{version});
+  auto session = std::make_unique<QuicTransportSimpleServerSession>(
+      connection.release(), /*owns_connection=*/true, this, config(),
+      GetSupportedVersions(), crypto_config(), compressed_certs_cache(),
+      accepted_origins_);
+  session->Initialize();
+  return session;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_transport_simple_server_dispatcher.h b/quiche/quic/tools/quic_transport_simple_server_dispatcher.h
new file mode 100644
index 0000000..a70aae1
--- /dev/null
+++ b/quiche/quic/tools/quic_transport_simple_server_dispatcher.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
+
+#include "absl/strings/string_view.h"
+#include "url/origin.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/tools/quic_transport_simple_server_session.h"
+
+namespace quic {
+
+// Dispatcher that creates a QuicTransportSimpleServerSession for every incoming
+// connection.
+class QuicTransportSimpleServerDispatcher : public QuicDispatcher {
+ public:
+  QuicTransportSimpleServerDispatcher(
+      const QuicConfig* config,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicVersionManager* version_manager,
+      std::unique_ptr<QuicConnectionHelperInterface> helper,
+      std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      uint8_t expected_server_connection_id_length,
+      std::vector<url::Origin> accepted_origins);
+
+ protected:
+  std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId server_connection_id,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version,
+      const ParsedClientHello& parsed_chlo) override;
+
+  std::vector<url::Origin> accepted_origins_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
diff --git a/quiche/quic/tools/quic_transport_simple_server_session.cc b/quiche/quic/tools/quic_transport_simple_server_session.cc
new file mode 100644
index 0000000..722e131
--- /dev/null
+++ b/quiche/quic/tools/quic_transport_simple_server_session.cc
@@ -0,0 +1,176 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_transport_simple_server_session.h"
+
+#include <memory>
+
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/quic/quic_transport/quic_transport_protocol.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+#include "quiche/quic/tools/web_transport_test_visitors.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_buffer_allocator.h"
+
+namespace quic {
+
+QuicTransportSimpleServerSession::QuicTransportSimpleServerSession(
+    QuicConnection* connection,
+    bool owns_connection,
+    Visitor* owner,
+    const QuicConfig& config,
+    const ParsedQuicVersionVector& supported_versions,
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    std::vector<url::Origin> accepted_origins)
+    : QuicTransportServerSession(connection,
+                                 owner,
+                                 config,
+                                 supported_versions,
+                                 crypto_config,
+                                 compressed_certs_cache,
+                                 this),
+      owns_connection_(owns_connection),
+      mode_(DISCARD),
+      accepted_origins_(accepted_origins) {}
+
+QuicTransportSimpleServerSession::~QuicTransportSimpleServerSession() {
+  if (owns_connection_) {
+    DeleteConnection();
+  }
+}
+
+void QuicTransportSimpleServerSession::OnIncomingDataStream(
+    QuicTransportStream* stream) {
+  switch (mode_) {
+    case DISCARD:
+      stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
+      break;
+
+    case ECHO:
+      switch (stream->type()) {
+        case BIDIRECTIONAL:
+          QUIC_DVLOG(1) << "Opening bidirectional echo stream " << stream->id();
+          stream->SetVisitor(
+              std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
+          break;
+        case READ_UNIDIRECTIONAL:
+          QUIC_DVLOG(1)
+              << "Started receiving data on unidirectional echo stream "
+              << stream->id();
+          stream->SetVisitor(
+              std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
+                  stream,
+                  [this](const std::string& s) { this->EchoStreamBack(s); }));
+          break;
+        default:
+          QUIC_NOTREACHED();
+          break;
+      }
+      break;
+
+    case OUTGOING_BIDIRECTIONAL:
+      stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
+      ++pending_outgoing_bidirectional_streams_;
+      MaybeCreateOutgoingBidirectionalStream();
+      break;
+  }
+}
+
+void QuicTransportSimpleServerSession::OnCanCreateNewOutgoingStream(
+    bool unidirectional) {
+  if (mode_ == ECHO && unidirectional) {
+    MaybeEchoStreamsBack();
+  } else if (mode_ == OUTGOING_BIDIRECTIONAL && !unidirectional) {
+    MaybeCreateOutgoingBidirectionalStream();
+  }
+}
+
+bool QuicTransportSimpleServerSession::CheckOrigin(url::Origin origin) {
+  if (accepted_origins_.empty()) {
+    return true;
+  }
+
+  for (const url::Origin& accepted_origin : accepted_origins_) {
+    if (origin.IsSameOriginWith(accepted_origin)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool QuicTransportSimpleServerSession::ProcessPath(const GURL& url) {
+  if (url.path() == "/discard") {
+    mode_ = DISCARD;
+    return true;
+  }
+  if (url.path() == "/echo") {
+    mode_ = ECHO;
+    return true;
+  }
+  if (url.path() == "/receive-bidirectional") {
+    mode_ = OUTGOING_BIDIRECTIONAL;
+    return true;
+  }
+
+  QUIC_DLOG(WARNING) << "Unknown path requested: " << url.path();
+  return false;
+}
+
+void QuicTransportSimpleServerSession::OnMessageReceived(
+    absl::string_view message) {
+  if (mode_ != ECHO) {
+    return;
+  }
+  datagram_queue()->SendOrQueueDatagram(
+      quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
+          connection()->helper()->GetStreamSendBufferAllocator(), message)));
+}
+
+void QuicTransportSimpleServerSession::MaybeEchoStreamsBack() {
+  while (!streams_to_echo_back_.empty() &&
+         CanOpenNextOutgoingUnidirectionalStream()) {
+    // Remove the stream from the queue first, in order to avoid accidentally
+    // entering an infinite loop in case any of the following code calls
+    // OnCanCreateNewOutgoingStream().
+    std::string data = std::move(streams_to_echo_back_.front());
+    streams_to_echo_back_.pop_front();
+
+    auto stream_owned = std::make_unique<QuicTransportStream>(
+        GetNextOutgoingUnidirectionalStreamId(), this, this);
+    QuicTransportStream* stream = stream_owned.get();
+    ActivateStream(std::move(stream_owned));
+    QUIC_DVLOG(1) << "Opened echo response stream " << stream->id();
+
+    stream->SetVisitor(
+        std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(stream,
+                                                                     data));
+    stream->visitor()->OnCanWrite();
+  }
+}
+
+void QuicTransportSimpleServerSession::
+    MaybeCreateOutgoingBidirectionalStream() {
+  while (pending_outgoing_bidirectional_streams_ > 0 &&
+         CanOpenNextOutgoingBidirectionalStream()) {
+    auto stream_owned = std::make_unique<QuicTransportStream>(
+        GetNextOutgoingBidirectionalStreamId(), this, this);
+    QuicTransportStream* stream = stream_owned.get();
+    ActivateStream(std::move(stream_owned));
+    QUIC_DVLOG(1) << "Opened outgoing bidirectional stream " << stream->id();
+    stream->SetVisitor(
+        std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
+    if (!stream->Write("hello")) {
+      QUIC_DVLOG(1) << "Write failed.";
+    }
+    --pending_outgoing_bidirectional_streams_;
+  }
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_transport_simple_server_session.h b/quiche/quic/tools/quic_transport_simple_server_session.h
new file mode 100644
index 0000000..f5c3934
--- /dev/null
+++ b/quiche/quic/tools/quic_transport_simple_server_session.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
+#define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
+
+#include <memory>
+#include <vector>
+
+#include "url/origin.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/quic/quic_transport/quic_transport_server_session.h"
+#include "quiche/quic/quic_transport/quic_transport_stream.h"
+
+namespace quic {
+
+// QuicTransport simple server is a non-production server that can be used for
+// testing QuicTransport.  It has two modes that can be changed using the
+// command line flags, "echo" and "discard".
+class QuicTransportSimpleServerSession
+    : public QuicTransportServerSession,
+      QuicTransportServerSession::ServerVisitor {
+ public:
+  enum Mode {
+    // In DISCARD mode, any data on incoming streams is discarded and no
+    // outgoing streams are initiated.
+    DISCARD,
+    // In ECHO mode, any data sent on a bidirectional stream is echoed back.
+    // Any data sent on a unidirectional stream is buffered, and echoed back on
+    // a server-initiated unidirectional stream that is sent as soon as a FIN is
+    // received on the incoming stream.
+    ECHO,
+    // In OUTGOING_BIDIRECTIONAL mode, a server-originated bidirectional stream
+    // is created on receipt of a unidirectional stream. The contents of the
+    // unidirectional stream are disregarded. The bidirectional stream initially
+    // sends "hello", then any received data is echoed back.
+    // TODO(ricea): Maybe this should be replaced by a more general mechanism
+    // where commands on the unidirectional stream trigger different behaviour?
+    OUTGOING_BIDIRECTIONAL,
+  };
+
+  QuicTransportSimpleServerSession(
+      QuicConnection* connection,
+      bool owns_connection,
+      Visitor* owner,
+      const QuicConfig& config,
+      const ParsedQuicVersionVector& supported_versions,
+      const QuicCryptoServerConfig* crypto_config,
+      QuicCompressedCertsCache* compressed_certs_cache,
+      std::vector<url::Origin> accepted_origins);
+  ~QuicTransportSimpleServerSession();
+
+  void OnIncomingDataStream(QuicTransportStream* stream) override;
+  void OnCanCreateNewOutgoingStream(bool unidirectional) override;
+  bool CheckOrigin(url::Origin origin) override;
+  bool ProcessPath(const GURL& url) override;
+  void OnMessageReceived(absl::string_view message) override;
+
+  void EchoStreamBack(const std::string& data) {
+    streams_to_echo_back_.push_back(data);
+    MaybeEchoStreamsBack();
+  }
+
+ private:
+  void MaybeEchoStreamsBack();
+  void MaybeCreateOutgoingBidirectionalStream();
+
+  const bool owns_connection_;
+  size_t pending_outgoing_bidirectional_streams_ = 0u;
+  Mode mode_;
+  std::vector<url::Origin> accepted_origins_;
+  quiche::QuicheCircularDeque<std::string> streams_to_echo_back_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
diff --git a/quiche/quic/tools/quic_url.cc b/quiche/quic/tools/quic_url.cc
new file mode 100644
index 0000000..db52720
--- /dev/null
+++ b/quiche/quic/tools/quic_url.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_url.h"
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+
+namespace quic {
+
+static constexpr size_t kMaxHostNameLength = 256;
+
+QuicUrl::QuicUrl(absl::string_view url) : url_(static_cast<std::string>(url)) {}
+
+QuicUrl::QuicUrl(absl::string_view url, absl::string_view default_scheme)
+    : QuicUrl(url) {
+  if (url_.has_scheme()) {
+    return;
+  }
+
+  url_ = GURL(absl::StrCat(default_scheme, "://", url));
+}
+
+std::string QuicUrl::ToString() const {
+  if (IsValid()) {
+    return url_.spec();
+  }
+  return "";
+}
+
+bool QuicUrl::IsValid() const {
+  if (!url_.is_valid() || !url_.has_scheme()) {
+    return false;
+  }
+
+  if (url_.has_host() && url_.host().length() > kMaxHostNameLength) {
+    return false;
+  }
+
+  return true;
+}
+
+std::string QuicUrl::HostPort() const {
+  if (!IsValid() || !url_.has_host()) {
+    return "";
+  }
+
+  std::string host = url_.host();
+  int port = url_.IntPort();
+  if (port == url::PORT_UNSPECIFIED) {
+    return host;
+  }
+  return absl::StrCat(host, ":", port);
+}
+
+std::string QuicUrl::PathParamsQuery() const {
+  if (!IsValid() || !url_.has_path()) {
+    return "/";
+  }
+
+  return url_.PathForRequest();
+}
+
+std::string QuicUrl::scheme() const {
+  if (!IsValid()) {
+    return "";
+  }
+
+  return url_.scheme();
+}
+
+std::string QuicUrl::host() const {
+  if (!IsValid()) {
+    return "";
+  }
+
+  return url_.HostNoBrackets();
+}
+
+std::string QuicUrl::path() const {
+  if (!IsValid()) {
+    return "";
+  }
+
+  return url_.path();
+}
+
+uint16_t QuicUrl::port() const {
+  if (!IsValid()) {
+    return 0;
+  }
+
+  int port = url_.EffectiveIntPort();
+  if (port == url::PORT_UNSPECIFIED) {
+    return 0;
+  }
+  return port;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/quic_url.h b/quiche/quic/tools/quic_url.h
new file mode 100644
index 0000000..78b21ec
--- /dev/null
+++ b/quiche/quic/tools/quic_url.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_URL_H_
+#define QUICHE_QUIC_TOOLS_QUIC_URL_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "url/gurl.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// A utility class that wraps GURL.
+class QuicUrl {
+ public:
+  // Constructs an empty QuicUrl.
+  QuicUrl() = default;
+
+  // Constructs a QuicUrl from the url string |url|.
+  //
+  // NOTE: If |url| doesn't have a scheme, it will have an empty scheme
+  // field. If that's not what you want, use the QuicUrlImpl(url,
+  // default_scheme) form below.
+  explicit QuicUrl(absl::string_view url);
+
+  // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL
+  // is |default_scheme| if there is no scheme specified in |url|.
+  QuicUrl(absl::string_view url, absl::string_view default_scheme);
+
+  // Returns false if the URL is not valid.
+  bool IsValid() const;
+
+  // Returns full text of the QuicUrl if it is valid. Return empty string
+  // otherwise.
+  std::string ToString() const;
+
+  // Returns host:port.
+  // If the host is empty, it will return an empty string.
+  // If the host is an IPv6 address, it will be bracketed.
+  // If port is not present or is equal to default_port of scheme (e.g., port
+  // 80 for HTTP), it won't be returned.
+  std::string HostPort() const;
+
+  // Returns a string assembles path, parameters and query.
+  std::string PathParamsQuery() const;
+
+  std::string scheme() const;
+  std::string host() const;
+  std::string path() const;
+  uint16_t port() const;
+
+ private:
+  GURL url_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_URL_H_
diff --git a/quiche/quic/tools/quic_url_test.cc b/quiche/quic/tools/quic_url_test.cc
new file mode 100644
index 0000000..8f26e01
--- /dev/null
+++ b/quiche/quic/tools/quic_url_test.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/quic_url.h"
+
+#include <string>
+
+#include "quiche/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicUrlTest : public QuicTest {};
+
+TEST_F(QuicUrlTest, Basic) {
+  // No scheme specified.
+  std::string url_str = "www.example.com";
+  QuicUrl url(url_str);
+  EXPECT_FALSE(url.IsValid());
+
+  // scheme is HTTP.
+  url_str = "http://www.example.com";
+  url = QuicUrl(url_str);
+  EXPECT_TRUE(url.IsValid());
+  EXPECT_EQ("http://www.example.com/", url.ToString());
+  EXPECT_EQ("http", url.scheme());
+  EXPECT_EQ("www.example.com", url.HostPort());
+  EXPECT_EQ("/", url.PathParamsQuery());
+  EXPECT_EQ(80u, url.port());
+
+  // scheme is HTTPS.
+  url_str = "https://www.example.com:12345/path/to/resource?a=1&campaign=2";
+  url = QuicUrl(url_str);
+  EXPECT_TRUE(url.IsValid());
+  EXPECT_EQ("https://www.example.com:12345/path/to/resource?a=1&campaign=2",
+            url.ToString());
+  EXPECT_EQ("https", url.scheme());
+  EXPECT_EQ("www.example.com:12345", url.HostPort());
+  EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery());
+  EXPECT_EQ(12345u, url.port());
+
+  // scheme is FTP.
+  url_str = "ftp://www.example.com";
+  url = QuicUrl(url_str);
+  EXPECT_TRUE(url.IsValid());
+  EXPECT_EQ("ftp://www.example.com/", url.ToString());
+  EXPECT_EQ("ftp", url.scheme());
+  EXPECT_EQ("www.example.com", url.HostPort());
+  EXPECT_EQ("/", url.PathParamsQuery());
+  EXPECT_EQ(21u, url.port());
+}
+
+TEST_F(QuicUrlTest, DefaultScheme) {
+  // Default scheme to HTTP.
+  std::string url_str = "www.example.com";
+  QuicUrl url(url_str, "http");
+  EXPECT_EQ("http://www.example.com/", url.ToString());
+  EXPECT_EQ("http", url.scheme());
+
+  // URL already has a scheme specified.
+  url_str = "http://www.example.com";
+  url = QuicUrl(url_str, "https");
+  EXPECT_EQ("http://www.example.com/", url.ToString());
+  EXPECT_EQ("http", url.scheme());
+
+  // Default scheme to FTP.
+  url_str = "www.example.com";
+  url = QuicUrl(url_str, "ftp");
+  EXPECT_EQ("ftp://www.example.com/", url.ToString());
+  EXPECT_EQ("ftp", url.scheme());
+}
+
+TEST_F(QuicUrlTest, IsValid) {
+  std::string url_str =
+      "ftp://www.example.com:12345/path/to/resource?a=1&campaign=2";
+  EXPECT_TRUE(QuicUrl(url_str).IsValid());
+
+  // Invalid characters in host name.
+  url_str = "https://www%.example.com:12345/path/to/resource?a=1&campaign=2";
+  EXPECT_FALSE(QuicUrl(url_str).IsValid());
+
+  // Invalid characters in scheme.
+  url_str = "%http://www.example.com:12345/path/to/resource?a=1&campaign=2";
+  EXPECT_FALSE(QuicUrl(url_str).IsValid());
+
+  // Host name too long.
+  std::string host(1024, 'a');
+  url_str = "https://" + host;
+  EXPECT_FALSE(QuicUrl(url_str).IsValid());
+
+  // Invalid port number.
+  url_str = "https://www..example.com:123456/path/to/resource?a=1&campaign=2";
+  EXPECT_FALSE(QuicUrl(url_str).IsValid());
+}
+
+TEST_F(QuicUrlTest, HostPort) {
+  std::string url_str = "http://www.example.com/";
+  QuicUrl url(url_str);
+  EXPECT_EQ("www.example.com", url.HostPort());
+  EXPECT_EQ("www.example.com", url.host());
+  EXPECT_EQ(80u, url.port());
+
+  url_str = "http://www.example.com:80/";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("www.example.com", url.HostPort());
+  EXPECT_EQ("www.example.com", url.host());
+  EXPECT_EQ(80u, url.port());
+
+  url_str = "http://www.example.com:81/";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("www.example.com:81", url.HostPort());
+  EXPECT_EQ("www.example.com", url.host());
+  EXPECT_EQ(81u, url.port());
+
+  url_str = "https://192.168.1.1:443/";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("192.168.1.1", url.HostPort());
+  EXPECT_EQ("192.168.1.1", url.host());
+  EXPECT_EQ(443u, url.port());
+
+  url_str = "http://[2001::1]:80/";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("[2001::1]", url.HostPort());
+  EXPECT_EQ("2001::1", url.host());
+  EXPECT_EQ(80u, url.port());
+
+  url_str = "http://[2001::1]:81/";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("[2001::1]:81", url.HostPort());
+  EXPECT_EQ("2001::1", url.host());
+  EXPECT_EQ(81u, url.port());
+}
+
+TEST_F(QuicUrlTest, PathParamsQuery) {
+  std::string url_str =
+      "https://www.example.com:12345/path/to/resource?a=1&campaign=2";
+  QuicUrl url(url_str);
+  EXPECT_EQ("/path/to/resource?a=1&campaign=2", url.PathParamsQuery());
+  EXPECT_EQ("/path/to/resource", url.path());
+
+  url_str = "https://www.example.com/?";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("/?", url.PathParamsQuery());
+  EXPECT_EQ("/", url.path());
+
+  url_str = "https://www.example.com/";
+  url = QuicUrl(url_str);
+  EXPECT_EQ("/", url.PathParamsQuery());
+  EXPECT_EQ("/", url.path());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/simple_ticket_crypter.cc b/quiche/quic/tools/simple_ticket_crypter.cc
new file mode 100644
index 0000000..ef788d6
--- /dev/null
+++ b/quiche/quic/tools/simple_ticket_crypter.cc
@@ -0,0 +1,112 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/simple_ticket_crypter.h"
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "third_party/boringssl/src/include/openssl/rand.h"
+
+namespace quic {
+
+namespace {
+
+constexpr QuicTime::Delta kTicketKeyLifetime =
+    QuicTime::Delta::FromSeconds(60 * 60 * 24 * 7);
+
+// The format of an encrypted ticket is 1 byte for the key epoch, followed by
+// 16 bytes of IV, followed by the output from the AES-GCM Seal operation. The
+// seal operation has an overhead of 16 bytes for its auth tag.
+constexpr size_t kEpochSize = 1;
+constexpr size_t kIVSize = 16;
+constexpr size_t kAuthTagSize = 16;
+
+// Offsets into the ciphertext to make message parsing easier.
+constexpr size_t kIVOffset = kEpochSize;
+constexpr size_t kMessageOffset = kIVOffset + kIVSize;
+
+}  // namespace
+
+SimpleTicketCrypter::SimpleTicketCrypter(QuicClock* clock) : clock_(clock) {
+  RAND_bytes(&key_epoch_, 1);
+  current_key_ = NewKey();
+}
+
+SimpleTicketCrypter::~SimpleTicketCrypter() = default;
+
+size_t SimpleTicketCrypter::MaxOverhead() {
+  return kEpochSize + kIVSize + kAuthTagSize;
+}
+
+std::vector<uint8_t> SimpleTicketCrypter::Encrypt(
+    absl::string_view in, absl::string_view encryption_key) {
+  // This class is only used in Chromium, in which the |encryption_key| argument
+  // will never be populated and an internally-cached key should be used for
+  // encrypting tickets.
+  QUICHE_DCHECK(encryption_key.empty());
+  MaybeRotateKeys();
+  std::vector<uint8_t> out(in.size() + MaxOverhead());
+  out[0] = key_epoch_;
+  RAND_bytes(out.data() + kIVOffset, kIVSize);
+  size_t out_len;
+  const EVP_AEAD_CTX* ctx = current_key_->aead_ctx.get();
+  if (!EVP_AEAD_CTX_seal(ctx, out.data() + kMessageOffset, &out_len,
+                         out.size() - kMessageOffset, out.data() + kIVOffset,
+                         kIVSize, reinterpret_cast<const uint8_t*>(in.data()),
+                         in.size(), nullptr, 0)) {
+    return std::vector<uint8_t>();
+  }
+  out.resize(out_len + kMessageOffset);
+  return out;
+}
+
+std::vector<uint8_t> SimpleTicketCrypter::Decrypt(absl::string_view in) {
+  MaybeRotateKeys();
+  if (in.size() < kMessageOffset) {
+    return std::vector<uint8_t>();
+  }
+  const uint8_t* input = reinterpret_cast<const uint8_t*>(in.data());
+  std::vector<uint8_t> out(in.size() - kMessageOffset);
+  size_t out_len;
+  const EVP_AEAD_CTX* ctx = current_key_->aead_ctx.get();
+  if (input[0] != key_epoch_) {
+    if (input[0] == static_cast<uint8_t>(key_epoch_ - 1) && previous_key_) {
+      ctx = previous_key_->aead_ctx.get();
+    } else {
+      return std::vector<uint8_t>();
+    }
+  }
+  if (!EVP_AEAD_CTX_open(ctx, out.data(), &out_len, out.size(),
+                         input + kIVOffset, kIVSize, input + kMessageOffset,
+                         in.size() - kMessageOffset, nullptr, 0)) {
+    return std::vector<uint8_t>();
+  }
+  out.resize(out_len);
+  return out;
+}
+
+void SimpleTicketCrypter::Decrypt(
+    absl::string_view in,
+    std::unique_ptr<quic::ProofSource::DecryptCallback> callback) {
+  callback->Run(Decrypt(in));
+}
+
+void SimpleTicketCrypter::MaybeRotateKeys() {
+  QuicTime now = clock_->ApproximateNow();
+  if (current_key_->expiration < now) {
+    previous_key_ = std::move(current_key_);
+    current_key_ = NewKey();
+    key_epoch_++;
+  }
+}
+
+std::unique_ptr<SimpleTicketCrypter::Key> SimpleTicketCrypter::NewKey() {
+  auto key = std::make_unique<SimpleTicketCrypter::Key>();
+  RAND_bytes(key->key, kKeySize);
+  EVP_AEAD_CTX_init(key->aead_ctx.get(), EVP_aead_aes_128_gcm(), key->key,
+                    kKeySize, EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr);
+  key->expiration = clock_->ApproximateNow() + kTicketKeyLifetime;
+  return key;
+}
+
+}  // namespace quic
diff --git a/quiche/quic/tools/simple_ticket_crypter.h b/quiche/quic/tools/simple_ticket_crypter.h
new file mode 100644
index 0000000..518ea9b
--- /dev/null
+++ b/quiche/quic/tools/simple_ticket_crypter.h
@@ -0,0 +1,56 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
+#define QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
+
+#include "third_party/boringssl/src/include/openssl/aead.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_time.h"
+
+namespace quic {
+
+// SimpleTicketCrypter implements the QUIC ProofSource::TicketCrypter interface.
+// It generates a random key at startup and every 7 days it rotates the key,
+// keeping track of the previous key used to facilitate decrypting older
+// tickets. This implementation is not suitable for server setups where multiple
+// servers need to share keys.
+class QUIC_NO_EXPORT SimpleTicketCrypter
+    : public quic::ProofSource::TicketCrypter {
+ public:
+  explicit SimpleTicketCrypter(QuicClock* clock);
+  ~SimpleTicketCrypter() override;
+
+  size_t MaxOverhead() override;
+  std::vector<uint8_t> Encrypt(absl::string_view in,
+                               absl::string_view encryption_key) override;
+  void Decrypt(
+      absl::string_view in,
+      std::unique_ptr<quic::ProofSource::DecryptCallback> callback) override;
+
+ private:
+  std::vector<uint8_t> Decrypt(absl::string_view in);
+
+  void MaybeRotateKeys();
+
+  static constexpr size_t kKeySize = 16;
+
+  struct Key {
+    uint8_t key[kKeySize];
+    bssl::ScopedEVP_AEAD_CTX aead_ctx;
+    QuicTime expiration = QuicTime::Zero();
+  };
+
+  std::unique_ptr<Key> NewKey();
+
+  std::unique_ptr<Key> current_key_;
+  std::unique_ptr<Key> previous_key_;
+  uint8_t key_epoch_ = 0;
+  QuicClock* clock_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_SIMPLE_TICKET_CRYPTER_H_
diff --git a/quiche/quic/tools/simple_ticket_crypter_test.cc b/quiche/quic/tools/simple_ticket_crypter_test.cc
new file mode 100644
index 0000000..0399047
--- /dev/null
+++ b/quiche/quic/tools/simple_ticket_crypter_test.cc
@@ -0,0 +1,111 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/tools/simple_ticket_crypter.h"
+
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+namespace {
+
+constexpr QuicTime::Delta kOneDay = QuicTime::Delta::FromSeconds(60 * 60 * 24);
+
+}  // namespace
+
+class DecryptCallback : public quic::ProofSource::DecryptCallback {
+ public:
+  explicit DecryptCallback(std::vector<uint8_t>* out) : out_(out) {}
+
+  void Run(std::vector<uint8_t> plaintext) override { *out_ = plaintext; }
+
+ private:
+  std::vector<uint8_t>* out_;
+};
+
+absl::string_view StringPiece(const std::vector<uint8_t>& in) {
+  return absl::string_view(reinterpret_cast<const char*>(in.data()), in.size());
+}
+
+class SimpleTicketCrypterTest : public QuicTest {
+ public:
+  SimpleTicketCrypterTest() : ticket_crypter_(&mock_clock_) {}
+
+ protected:
+  MockClock mock_clock_;
+  SimpleTicketCrypter ticket_crypter_;
+};
+
+TEST_F(SimpleTicketCrypterTest, EncryptDecrypt) {
+  std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
+  std::vector<uint8_t> ciphertext =
+      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
+  EXPECT_NE(plaintext, ciphertext);
+
+  std::vector<uint8_t> out_plaintext;
+  ticket_crypter_.Decrypt(StringPiece(ciphertext),
+                          std::make_unique<DecryptCallback>(&out_plaintext));
+  EXPECT_EQ(out_plaintext, plaintext);
+}
+
+TEST_F(SimpleTicketCrypterTest, CiphertextsDiffer) {
+  std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
+  std::vector<uint8_t> ciphertext1 =
+      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
+  std::vector<uint8_t> ciphertext2 =
+      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
+  EXPECT_NE(ciphertext1, ciphertext2);
+}
+
+TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithModifiedCiphertext) {
+  std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
+  std::vector<uint8_t> ciphertext =
+      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
+  EXPECT_NE(plaintext, ciphertext);
+
+  // Check that a bit flip in any byte will cause a decryption failure.
+  for (size_t i = 0; i < ciphertext.size(); i++) {
+    SCOPED_TRACE(i);
+    std::vector<uint8_t> munged_ciphertext = ciphertext;
+    munged_ciphertext[i] ^= 1;
+    std::vector<uint8_t> out_plaintext;
+    ticket_crypter_.Decrypt(StringPiece(munged_ciphertext),
+                            std::make_unique<DecryptCallback>(&out_plaintext));
+    EXPECT_TRUE(out_plaintext.empty());
+  }
+}
+
+TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithEmptyCiphertext) {
+  std::vector<uint8_t> out_plaintext;
+  ticket_crypter_.Decrypt(absl::string_view(),
+                          std::make_unique<DecryptCallback>(&out_plaintext));
+  EXPECT_TRUE(out_plaintext.empty());
+}
+
+TEST_F(SimpleTicketCrypterTest, KeyRotation) {
+  std::vector<uint8_t> plaintext = {1, 2, 3};
+  std::vector<uint8_t> ciphertext =
+      ticket_crypter_.Encrypt(StringPiece(plaintext), {});
+  EXPECT_FALSE(ciphertext.empty());
+
+  // Advance the clock 8 days, so the key used for |ciphertext| is now the
+  // previous key. Check that decryption still works.
+  mock_clock_.AdvanceTime(kOneDay * 8);
+  std::vector<uint8_t> out_plaintext;
+  ticket_crypter_.Decrypt(StringPiece(ciphertext),
+                          std::make_unique<DecryptCallback>(&out_plaintext));
+  EXPECT_EQ(out_plaintext, plaintext);
+
+  // Advance the clock 8 more days. Now the original key should be expired and
+  // decryption should fail.
+  mock_clock_.AdvanceTime(kOneDay * 8);
+  ticket_crypter_.Decrypt(StringPiece(ciphertext),
+                          std::make_unique<DecryptCallback>(&out_plaintext));
+  EXPECT_TRUE(out_plaintext.empty());
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quiche/quic/tools/web_transport_test_visitors.h b/quiche/quic/tools/web_transport_test_visitors.h
new file mode 100644
index 0000000..07d3161
--- /dev/null
+++ b/quiche/quic/tools/web_transport_test_visitors.h
@@ -0,0 +1,263 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
+#define QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
+
+#include <string>
+
+#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+#include "quiche/common/quiche_circular_deque.h"
+#include "quiche/common/simple_buffer_allocator.h"
+
+namespace quic {
+
+// Discards any incoming data.
+class WebTransportDiscardVisitor : public WebTransportStreamVisitor {
+ public:
+  WebTransportDiscardVisitor(WebTransportStream* stream) : stream_(stream) {}
+
+  void OnCanRead() override {
+    std::string buffer;
+    WebTransportStream::ReadResult result = stream_->Read(&buffer);
+    QUIC_DVLOG(2) << "Read " << result.bytes_read
+                  << " bytes from WebTransport stream "
+                  << stream_->GetStreamId() << ", fin: " << result.fin;
+  }
+
+  void OnCanWrite() override {}
+
+  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
+  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
+  void OnWriteSideInDataRecvdState() override {}
+
+ private:
+  WebTransportStream* stream_;
+};
+
+// Echoes any incoming data back on the same stream.
+class WebTransportBidirectionalEchoVisitor : public WebTransportStreamVisitor {
+ public:
+  WebTransportBidirectionalEchoVisitor(WebTransportStream* stream)
+      : stream_(stream) {}
+
+  void OnCanRead() override {
+    WebTransportStream::ReadResult result = stream_->Read(&buffer_);
+    QUIC_DVLOG(1) << "Attempted reading on WebTransport bidirectional stream "
+                  << stream_->GetStreamId()
+                  << ", bytes read: " << result.bytes_read;
+    if (result.fin) {
+      send_fin_ = true;
+    }
+    OnCanWrite();
+  }
+
+  void OnCanWrite() override {
+    if (stop_sending_received_) {
+      return;
+    }
+
+    if (!buffer_.empty()) {
+      bool success = stream_->Write(buffer_);
+      QUIC_DVLOG(1) << "Attempted writing on WebTransport bidirectional stream "
+                    << stream_->GetStreamId()
+                    << ", success: " << (success ? "yes" : "no");
+      if (!success) {
+        return;
+      }
+
+      buffer_ = "";
+    }
+
+    if (send_fin_) {
+      bool success = stream_->SendFin();
+      QUICHE_DCHECK(success);
+    }
+  }
+
+  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {
+    // Send FIN in response to a stream reset.  We want to test that we can
+    // operate one side of the stream cleanly while the other is reset, thus
+    // replying with a FIN rather than a RESET_STREAM is more appropriate here.
+    send_fin_ = true;
+    OnCanWrite();
+  }
+  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {
+    stop_sending_received_ = true;
+  }
+  void OnWriteSideInDataRecvdState() override {}
+
+ protected:
+  WebTransportStream* stream() { return stream_; }
+
+ private:
+  WebTransportStream* stream_;
+  std::string buffer_;
+  bool send_fin_ = false;
+  bool stop_sending_received_ = false;
+};
+
+// Buffers all of the data and calls |callback| with the entirety of the stream
+// data.
+class WebTransportUnidirectionalEchoReadVisitor
+    : public WebTransportStreamVisitor {
+ public:
+  using Callback = std::function<void(const std::string&)>;
+
+  WebTransportUnidirectionalEchoReadVisitor(WebTransportStream* stream,
+                                            Callback callback)
+      : stream_(stream), callback_(std::move(callback)) {}
+
+  void OnCanRead() override {
+    WebTransportStream::ReadResult result = stream_->Read(&buffer_);
+    QUIC_DVLOG(1) << "Attempted reading on WebTransport unidirectional stream "
+                  << stream_->GetStreamId()
+                  << ", bytes read: " << result.bytes_read;
+    if (result.fin) {
+      QUIC_DVLOG(1) << "Finished receiving data on a WebTransport stream "
+                    << stream_->GetStreamId() << ", queueing up the echo";
+      callback_(buffer_);
+    }
+  }
+
+  void OnCanWrite() override { QUIC_NOTREACHED(); }
+
+  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
+  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
+  void OnWriteSideInDataRecvdState() override {}
+
+ private:
+  WebTransportStream* stream_;
+  std::string buffer_;
+  Callback callback_;
+};
+
+// Sends supplied data.
+class WebTransportUnidirectionalEchoWriteVisitor
+    : public WebTransportStreamVisitor {
+ public:
+  WebTransportUnidirectionalEchoWriteVisitor(WebTransportStream* stream,
+                                             const std::string& data)
+      : stream_(stream), data_(data) {}
+
+  void OnCanRead() override { QUIC_NOTREACHED(); }
+  void OnCanWrite() override {
+    if (data_.empty()) {
+      return;
+    }
+    if (!stream_->Write(data_)) {
+      return;
+    }
+    data_ = "";
+    bool fin_sent = stream_->SendFin();
+    QUICHE_DVLOG(1)
+        << "WebTransportUnidirectionalEchoWriteVisitor finished sending data.";
+    QUICHE_DCHECK(fin_sent);
+  }
+
+  void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
+  void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
+  void OnWriteSideInDataRecvdState() override {}
+
+ private:
+  WebTransportStream* stream_;
+  std::string data_;
+};
+
+// A session visitor which sets unidirectional or bidirectional stream visitors
+// to echo.
+class EchoWebTransportSessionVisitor : public WebTransportVisitor {
+ public:
+  EchoWebTransportSessionVisitor(WebTransportSession* session)
+      : session_(session) {}
+
+  void OnSessionReady(const spdy::SpdyHeaderBlock&) override {
+    if (session_->CanOpenNextOutgoingBidirectionalStream()) {
+      OnCanCreateNewOutgoingBidirectionalStream();
+    }
+  }
+
+  void OnSessionClosed(WebTransportSessionError /*error_code*/,
+                       const std::string& /*error_message*/) override {}
+
+  void OnIncomingBidirectionalStreamAvailable() override {
+    while (true) {
+      WebTransportStream* stream =
+          session_->AcceptIncomingBidirectionalStream();
+      if (stream == nullptr) {
+        return;
+      }
+      QUIC_DVLOG(1)
+          << "EchoWebTransportSessionVisitor received a bidirectional stream "
+          << stream->GetStreamId();
+      stream->SetVisitor(
+          std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
+      stream->visitor()->OnCanRead();
+    }
+  }
+
+  void OnIncomingUnidirectionalStreamAvailable() override {
+    while (true) {
+      WebTransportStream* stream =
+          session_->AcceptIncomingUnidirectionalStream();
+      if (stream == nullptr) {
+        return;
+      }
+      QUIC_DVLOG(1)
+          << "EchoWebTransportSessionVisitor received a unidirectional stream";
+      stream->SetVisitor(
+          std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
+              stream, [this](const std::string& data) {
+                streams_to_echo_back_.push_back(data);
+                TrySendingUnidirectionalStreams();
+              }));
+      stream->visitor()->OnCanRead();
+    }
+  }
+
+  void OnDatagramReceived(absl::string_view datagram) override {
+    quiche::QuicheMemSlice slice(
+        quiche::QuicheBuffer::Copy(&allocator_, datagram));
+    session_->SendOrQueueDatagram(std::move(slice));
+  }
+
+  void OnCanCreateNewOutgoingBidirectionalStream() override {
+    if (!echo_stream_opened_) {
+      WebTransportStream* stream = session_->OpenOutgoingBidirectionalStream();
+      stream->SetVisitor(
+          std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
+      echo_stream_opened_ = true;
+    }
+  }
+  void OnCanCreateNewOutgoingUnidirectionalStream() override {
+    TrySendingUnidirectionalStreams();
+  }
+
+  void TrySendingUnidirectionalStreams() {
+    while (!streams_to_echo_back_.empty() &&
+           session_->CanOpenNextOutgoingUnidirectionalStream()) {
+      QUIC_DVLOG(1)
+          << "EchoWebTransportServer echoed a unidirectional stream back";
+      WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
+      stream->SetVisitor(
+          std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
+              stream, streams_to_echo_back_.front()));
+      streams_to_echo_back_.pop_front();
+      stream->visitor()->OnCanWrite();
+    }
+  }
+
+ private:
+  WebTransportSession* session_;
+  quiche::SimpleBufferAllocator allocator_;
+  bool echo_stream_opened_ = false;
+
+  quiche::QuicheCircularDeque<std::string> streams_to_echo_back_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_WEB_TRANSPORT_TEST_VISITORS_H_
diff --git a/quiche/spdy/core/array_output_buffer.cc b/quiche/spdy/core/array_output_buffer.cc
new file mode 100644
index 0000000..8cebea7
--- /dev/null
+++ b/quiche/spdy/core/array_output_buffer.cc
@@ -0,0 +1,23 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/array_output_buffer.h"
+
+namespace spdy {
+
+void ArrayOutputBuffer::Next(char** data, int* size) {
+  *data = current_;
+  *size = capacity_ > 0 ? capacity_ : 0;
+}
+
+void ArrayOutputBuffer::AdvanceWritePtr(int64_t count) {
+  current_ += count;
+  capacity_ -= count;
+}
+
+uint64_t ArrayOutputBuffer::BytesFree() const {
+  return capacity_;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/array_output_buffer.h b/quiche/spdy/core/array_output_buffer.h
new file mode 100644
index 0000000..6387c81
--- /dev/null
+++ b/quiche/spdy/core/array_output_buffer.h
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
+#define QUICHE_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
+
+#include <cstddef>
+#include "quiche/spdy/core/zero_copy_output_buffer.h"
+
+namespace spdy {
+
+class ArrayOutputBuffer : public ZeroCopyOutputBuffer {
+ public:
+  // |buffer| is pointed to the output to write to, and |size| is the capacity
+  // of the output.
+  ArrayOutputBuffer(char* buffer, int64_t size)
+      : current_(buffer), begin_(buffer), capacity_(size) {}
+  ~ArrayOutputBuffer() override {}
+
+  ArrayOutputBuffer(const ArrayOutputBuffer&) = delete;
+  ArrayOutputBuffer& operator=(const ArrayOutputBuffer&) = delete;
+
+  void Next(char** data, int* size) override;
+  void AdvanceWritePtr(int64_t count) override;
+  uint64_t BytesFree() const override;
+
+  size_t Size() const { return current_ - begin_; }
+  char* Begin() const { return begin_; }
+
+  // Resets the buffer to its original state.
+  void Reset() {
+    capacity_ += Size();
+    current_ = begin_;
+  }
+
+ private:
+  char* current_ = nullptr;
+  char* begin_ = nullptr;
+  uint64_t capacity_ = 0;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
diff --git a/quiche/spdy/core/array_output_buffer_test.cc b/quiche/spdy/core/array_output_buffer_test.cc
new file mode 100644
index 0000000..0054a72
--- /dev/null
+++ b/quiche/spdy/core/array_output_buffer_test.cc
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/array_output_buffer.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+namespace test {
+
+// This test verifies that ArrayOutputBuffer is initialized properly.
+TEST(ArrayOutputBufferTest, InitializedFromArray) {
+  char array[100];
+  ArrayOutputBuffer buffer(array, sizeof(array));
+  EXPECT_EQ(sizeof(array), buffer.BytesFree());
+  EXPECT_EQ(0u, buffer.Size());
+  EXPECT_EQ(array, buffer.Begin());
+}
+
+// This test verifies that Reset() causes an ArrayOutputBuffer's capacity and
+// size to be reset to the initial state.
+TEST(ArrayOutputBufferTest, WriteAndReset) {
+  char array[100];
+  ArrayOutputBuffer buffer(array, sizeof(array));
+
+  // Let's write some bytes.
+  char* dst;
+  int size;
+  buffer.Next(&dst, &size);
+  ASSERT_GT(size, 1);
+  ASSERT_NE(nullptr, dst);
+  const int64_t written = size / 2;
+  memset(dst, 'x', written);
+  buffer.AdvanceWritePtr(written);
+
+  // The buffer should be partially used.
+  EXPECT_EQ(static_cast<uint64_t>(size) - written, buffer.BytesFree());
+  EXPECT_EQ(static_cast<uint64_t>(written), buffer.Size());
+
+  buffer.Reset();
+
+  // After a reset, the buffer should regain its full capacity.
+  EXPECT_EQ(sizeof(array), buffer.BytesFree());
+  EXPECT_EQ(0u, buffer.Size());
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/header_byte_listener_interface.h b/quiche/spdy/core/header_byte_listener_interface.h
new file mode 100644
index 0000000..7b738af
--- /dev/null
+++ b/quiche/spdy/core/header_byte_listener_interface.h
@@ -0,0 +1,22 @@
+#ifndef QUICHE_SPDY_CORE_HEADER_BYTE_LISTENER_INTERFACE_H_
+#define QUICHE_SPDY_CORE_HEADER_BYTE_LISTENER_INTERFACE_H_
+
+#include <stddef.h>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace spdy {
+
+// Listens for the receipt of uncompressed header bytes.
+class QUICHE_EXPORT_PRIVATE HeaderByteListenerInterface {
+ public:
+  virtual ~HeaderByteListenerInterface() {}
+
+  // Called when a header block has been parsed, with the number of uncompressed
+  // header bytes parsed from the header block.
+  virtual void OnHeaderBytesReceived(size_t uncompressed_header_bytes) = 0;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HEADER_BYTE_LISTENER_INTERFACE_H_
diff --git a/quiche/spdy/core/hpack/hpack_constants.cc b/quiche/spdy/core/hpack/hpack_constants.cc
new file mode 100644
index 0000000..817216e
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_constants.cc
@@ -0,0 +1,374 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+
+#include <cstddef>
+#include <memory>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+namespace spdy {
+
+// Produced by applying the python program [1] with tables provided by [2]
+// (inserted into the source of the python program) and copy-paste them into
+// this file.
+//
+// [1] net/tools/build_hpack_constants.py in Chromium
+// [2] http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
+
+// HpackHuffmanSymbol entries are initialized as {code, length, id}.
+// Codes are specified in the |length| most-significant bits of |code|.
+const std::vector<HpackHuffmanSymbol>& HpackHuffmanCodeVector() {
+  static const auto* kHpackHuffmanCode = new std::vector<HpackHuffmanSymbol>{
+      {0xffc00000ul, 13, 0},    //     11111111|11000
+      {0xffffb000ul, 23, 1},    //     11111111|11111111|1011000
+      {0xfffffe20ul, 28, 2},    //     11111111|11111111|11111110|0010
+      {0xfffffe30ul, 28, 3},    //     11111111|11111111|11111110|0011
+      {0xfffffe40ul, 28, 4},    //     11111111|11111111|11111110|0100
+      {0xfffffe50ul, 28, 5},    //     11111111|11111111|11111110|0101
+      {0xfffffe60ul, 28, 6},    //     11111111|11111111|11111110|0110
+      {0xfffffe70ul, 28, 7},    //     11111111|11111111|11111110|0111
+      {0xfffffe80ul, 28, 8},    //     11111111|11111111|11111110|1000
+      {0xffffea00ul, 24, 9},    //     11111111|11111111|11101010
+      {0xfffffff0ul, 30, 10},   //     11111111|11111111|11111111|111100
+      {0xfffffe90ul, 28, 11},   //     11111111|11111111|11111110|1001
+      {0xfffffea0ul, 28, 12},   //     11111111|11111111|11111110|1010
+      {0xfffffff4ul, 30, 13},   //     11111111|11111111|11111111|111101
+      {0xfffffeb0ul, 28, 14},   //     11111111|11111111|11111110|1011
+      {0xfffffec0ul, 28, 15},   //     11111111|11111111|11111110|1100
+      {0xfffffed0ul, 28, 16},   //     11111111|11111111|11111110|1101
+      {0xfffffee0ul, 28, 17},   //     11111111|11111111|11111110|1110
+      {0xfffffef0ul, 28, 18},   //     11111111|11111111|11111110|1111
+      {0xffffff00ul, 28, 19},   //     11111111|11111111|11111111|0000
+      {0xffffff10ul, 28, 20},   //     11111111|11111111|11111111|0001
+      {0xffffff20ul, 28, 21},   //     11111111|11111111|11111111|0010
+      {0xfffffff8ul, 30, 22},   //     11111111|11111111|11111111|111110
+      {0xffffff30ul, 28, 23},   //     11111111|11111111|11111111|0011
+      {0xffffff40ul, 28, 24},   //     11111111|11111111|11111111|0100
+      {0xffffff50ul, 28, 25},   //     11111111|11111111|11111111|0101
+      {0xffffff60ul, 28, 26},   //     11111111|11111111|11111111|0110
+      {0xffffff70ul, 28, 27},   //     11111111|11111111|11111111|0111
+      {0xffffff80ul, 28, 28},   //     11111111|11111111|11111111|1000
+      {0xffffff90ul, 28, 29},   //     11111111|11111111|11111111|1001
+      {0xffffffa0ul, 28, 30},   //     11111111|11111111|11111111|1010
+      {0xffffffb0ul, 28, 31},   //     11111111|11111111|11111111|1011
+      {0x50000000ul, 6, 32},    // ' ' 010100
+      {0xfe000000ul, 10, 33},   // '!' 11111110|00
+      {0xfe400000ul, 10, 34},   // '"' 11111110|01
+      {0xffa00000ul, 12, 35},   // '#' 11111111|1010
+      {0xffc80000ul, 13, 36},   // '$' 11111111|11001
+      {0x54000000ul, 6, 37},    // '%' 010101
+      {0xf8000000ul, 8, 38},    // '&' 11111000
+      {0xff400000ul, 11, 39},   // ''' 11111111|010
+      {0xfe800000ul, 10, 40},   // '(' 11111110|10
+      {0xfec00000ul, 10, 41},   // ')' 11111110|11
+      {0xf9000000ul, 8, 42},    // '*' 11111001
+      {0xff600000ul, 11, 43},   // '+' 11111111|011
+      {0xfa000000ul, 8, 44},    // ',' 11111010
+      {0x58000000ul, 6, 45},    // '-' 010110
+      {0x5c000000ul, 6, 46},    // '.' 010111
+      {0x60000000ul, 6, 47},    // '/' 011000
+      {0x00000000ul, 5, 48},    // '0' 00000
+      {0x08000000ul, 5, 49},    // '1' 00001
+      {0x10000000ul, 5, 50},    // '2' 00010
+      {0x64000000ul, 6, 51},    // '3' 011001
+      {0x68000000ul, 6, 52},    // '4' 011010
+      {0x6c000000ul, 6, 53},    // '5' 011011
+      {0x70000000ul, 6, 54},    // '6' 011100
+      {0x74000000ul, 6, 55},    // '7' 011101
+      {0x78000000ul, 6, 56},    // '8' 011110
+      {0x7c000000ul, 6, 57},    // '9' 011111
+      {0xb8000000ul, 7, 58},    // ':' 1011100
+      {0xfb000000ul, 8, 59},    // ';' 11111011
+      {0xfff80000ul, 15, 60},   // '<' 11111111|1111100
+      {0x80000000ul, 6, 61},    // '=' 100000
+      {0xffb00000ul, 12, 62},   // '>' 11111111|1011
+      {0xff000000ul, 10, 63},   // '?' 11111111|00
+      {0xffd00000ul, 13, 64},   // '@' 11111111|11010
+      {0x84000000ul, 6, 65},    // 'A' 100001
+      {0xba000000ul, 7, 66},    // 'B' 1011101
+      {0xbc000000ul, 7, 67},    // 'C' 1011110
+      {0xbe000000ul, 7, 68},    // 'D' 1011111
+      {0xc0000000ul, 7, 69},    // 'E' 1100000
+      {0xc2000000ul, 7, 70},    // 'F' 1100001
+      {0xc4000000ul, 7, 71},    // 'G' 1100010
+      {0xc6000000ul, 7, 72},    // 'H' 1100011
+      {0xc8000000ul, 7, 73},    // 'I' 1100100
+      {0xca000000ul, 7, 74},    // 'J' 1100101
+      {0xcc000000ul, 7, 75},    // 'K' 1100110
+      {0xce000000ul, 7, 76},    // 'L' 1100111
+      {0xd0000000ul, 7, 77},    // 'M' 1101000
+      {0xd2000000ul, 7, 78},    // 'N' 1101001
+      {0xd4000000ul, 7, 79},    // 'O' 1101010
+      {0xd6000000ul, 7, 80},    // 'P' 1101011
+      {0xd8000000ul, 7, 81},    // 'Q' 1101100
+      {0xda000000ul, 7, 82},    // 'R' 1101101
+      {0xdc000000ul, 7, 83},    // 'S' 1101110
+      {0xde000000ul, 7, 84},    // 'T' 1101111
+      {0xe0000000ul, 7, 85},    // 'U' 1110000
+      {0xe2000000ul, 7, 86},    // 'V' 1110001
+      {0xe4000000ul, 7, 87},    // 'W' 1110010
+      {0xfc000000ul, 8, 88},    // 'X' 11111100
+      {0xe6000000ul, 7, 89},    // 'Y' 1110011
+      {0xfd000000ul, 8, 90},    // 'Z' 11111101
+      {0xffd80000ul, 13, 91},   // '[' 11111111|11011
+      {0xfffe0000ul, 19, 92},   // '\' 11111111|11111110|000
+      {0xffe00000ul, 13, 93},   // ']' 11111111|11100
+      {0xfff00000ul, 14, 94},   // '^' 11111111|111100
+      {0x88000000ul, 6, 95},    // '_' 100010
+      {0xfffa0000ul, 15, 96},   // '`' 11111111|1111101
+      {0x18000000ul, 5, 97},    // 'a' 00011
+      {0x8c000000ul, 6, 98},    // 'b' 100011
+      {0x20000000ul, 5, 99},    // 'c' 00100
+      {0x90000000ul, 6, 100},   // 'd' 100100
+      {0x28000000ul, 5, 101},   // 'e' 00101
+      {0x94000000ul, 6, 102},   // 'f' 100101
+      {0x98000000ul, 6, 103},   // 'g' 100110
+      {0x9c000000ul, 6, 104},   // 'h' 100111
+      {0x30000000ul, 5, 105},   // 'i' 00110
+      {0xe8000000ul, 7, 106},   // 'j' 1110100
+      {0xea000000ul, 7, 107},   // 'k' 1110101
+      {0xa0000000ul, 6, 108},   // 'l' 101000
+      {0xa4000000ul, 6, 109},   // 'm' 101001
+      {0xa8000000ul, 6, 110},   // 'n' 101010
+      {0x38000000ul, 5, 111},   // 'o' 00111
+      {0xac000000ul, 6, 112},   // 'p' 101011
+      {0xec000000ul, 7, 113},   // 'q' 1110110
+      {0xb0000000ul, 6, 114},   // 'r' 101100
+      {0x40000000ul, 5, 115},   // 's' 01000
+      {0x48000000ul, 5, 116},   // 't' 01001
+      {0xb4000000ul, 6, 117},   // 'u' 101101
+      {0xee000000ul, 7, 118},   // 'v' 1110111
+      {0xf0000000ul, 7, 119},   // 'w' 1111000
+      {0xf2000000ul, 7, 120},   // 'x' 1111001
+      {0xf4000000ul, 7, 121},   // 'y' 1111010
+      {0xf6000000ul, 7, 122},   // 'z' 1111011
+      {0xfffc0000ul, 15, 123},  // '{' 11111111|1111110
+      {0xff800000ul, 11, 124},  // '|' 11111111|100
+      {0xfff40000ul, 14, 125},  // '}' 11111111|111101
+      {0xffe80000ul, 13, 126},  // '~' 11111111|11101
+      {0xffffffc0ul, 28, 127},  //     11111111|11111111|11111111|1100
+      {0xfffe6000ul, 20, 128},  //     11111111|11111110|0110
+      {0xffff4800ul, 22, 129},  //     11111111|11111111|010010
+      {0xfffe7000ul, 20, 130},  //     11111111|11111110|0111
+      {0xfffe8000ul, 20, 131},  //     11111111|11111110|1000
+      {0xffff4c00ul, 22, 132},  //     11111111|11111111|010011
+      {0xffff5000ul, 22, 133},  //     11111111|11111111|010100
+      {0xffff5400ul, 22, 134},  //     11111111|11111111|010101
+      {0xffffb200ul, 23, 135},  //     11111111|11111111|1011001
+      {0xffff5800ul, 22, 136},  //     11111111|11111111|010110
+      {0xffffb400ul, 23, 137},  //     11111111|11111111|1011010
+      {0xffffb600ul, 23, 138},  //     11111111|11111111|1011011
+      {0xffffb800ul, 23, 139},  //     11111111|11111111|1011100
+      {0xffffba00ul, 23, 140},  //     11111111|11111111|1011101
+      {0xffffbc00ul, 23, 141},  //     11111111|11111111|1011110
+      {0xffffeb00ul, 24, 142},  //     11111111|11111111|11101011
+      {0xffffbe00ul, 23, 143},  //     11111111|11111111|1011111
+      {0xffffec00ul, 24, 144},  //     11111111|11111111|11101100
+      {0xffffed00ul, 24, 145},  //     11111111|11111111|11101101
+      {0xffff5c00ul, 22, 146},  //     11111111|11111111|010111
+      {0xffffc000ul, 23, 147},  //     11111111|11111111|1100000
+      {0xffffee00ul, 24, 148},  //     11111111|11111111|11101110
+      {0xffffc200ul, 23, 149},  //     11111111|11111111|1100001
+      {0xffffc400ul, 23, 150},  //     11111111|11111111|1100010
+      {0xffffc600ul, 23, 151},  //     11111111|11111111|1100011
+      {0xffffc800ul, 23, 152},  //     11111111|11111111|1100100
+      {0xfffee000ul, 21, 153},  //     11111111|11111110|11100
+      {0xffff6000ul, 22, 154},  //     11111111|11111111|011000
+      {0xffffca00ul, 23, 155},  //     11111111|11111111|1100101
+      {0xffff6400ul, 22, 156},  //     11111111|11111111|011001
+      {0xffffcc00ul, 23, 157},  //     11111111|11111111|1100110
+      {0xffffce00ul, 23, 158},  //     11111111|11111111|1100111
+      {0xffffef00ul, 24, 159},  //     11111111|11111111|11101111
+      {0xffff6800ul, 22, 160},  //     11111111|11111111|011010
+      {0xfffee800ul, 21, 161},  //     11111111|11111110|11101
+      {0xfffe9000ul, 20, 162},  //     11111111|11111110|1001
+      {0xffff6c00ul, 22, 163},  //     11111111|11111111|011011
+      {0xffff7000ul, 22, 164},  //     11111111|11111111|011100
+      {0xffffd000ul, 23, 165},  //     11111111|11111111|1101000
+      {0xffffd200ul, 23, 166},  //     11111111|11111111|1101001
+      {0xfffef000ul, 21, 167},  //     11111111|11111110|11110
+      {0xffffd400ul, 23, 168},  //     11111111|11111111|1101010
+      {0xffff7400ul, 22, 169},  //     11111111|11111111|011101
+      {0xffff7800ul, 22, 170},  //     11111111|11111111|011110
+      {0xfffff000ul, 24, 171},  //     11111111|11111111|11110000
+      {0xfffef800ul, 21, 172},  //     11111111|11111110|11111
+      {0xffff7c00ul, 22, 173},  //     11111111|11111111|011111
+      {0xffffd600ul, 23, 174},  //     11111111|11111111|1101011
+      {0xffffd800ul, 23, 175},  //     11111111|11111111|1101100
+      {0xffff0000ul, 21, 176},  //     11111111|11111111|00000
+      {0xffff0800ul, 21, 177},  //     11111111|11111111|00001
+      {0xffff8000ul, 22, 178},  //     11111111|11111111|100000
+      {0xffff1000ul, 21, 179},  //     11111111|11111111|00010
+      {0xffffda00ul, 23, 180},  //     11111111|11111111|1101101
+      {0xffff8400ul, 22, 181},  //     11111111|11111111|100001
+      {0xffffdc00ul, 23, 182},  //     11111111|11111111|1101110
+      {0xffffde00ul, 23, 183},  //     11111111|11111111|1101111
+      {0xfffea000ul, 20, 184},  //     11111111|11111110|1010
+      {0xffff8800ul, 22, 185},  //     11111111|11111111|100010
+      {0xffff8c00ul, 22, 186},  //     11111111|11111111|100011
+      {0xffff9000ul, 22, 187},  //     11111111|11111111|100100
+      {0xffffe000ul, 23, 188},  //     11111111|11111111|1110000
+      {0xffff9400ul, 22, 189},  //     11111111|11111111|100101
+      {0xffff9800ul, 22, 190},  //     11111111|11111111|100110
+      {0xffffe200ul, 23, 191},  //     11111111|11111111|1110001
+      {0xfffff800ul, 26, 192},  //     11111111|11111111|11111000|00
+      {0xfffff840ul, 26, 193},  //     11111111|11111111|11111000|01
+      {0xfffeb000ul, 20, 194},  //     11111111|11111110|1011
+      {0xfffe2000ul, 19, 195},  //     11111111|11111110|001
+      {0xffff9c00ul, 22, 196},  //     11111111|11111111|100111
+      {0xffffe400ul, 23, 197},  //     11111111|11111111|1110010
+      {0xffffa000ul, 22, 198},  //     11111111|11111111|101000
+      {0xfffff600ul, 25, 199},  //     11111111|11111111|11110110|0
+      {0xfffff880ul, 26, 200},  //     11111111|11111111|11111000|10
+      {0xfffff8c0ul, 26, 201},  //     11111111|11111111|11111000|11
+      {0xfffff900ul, 26, 202},  //     11111111|11111111|11111001|00
+      {0xfffffbc0ul, 27, 203},  //     11111111|11111111|11111011|110
+      {0xfffffbe0ul, 27, 204},  //     11111111|11111111|11111011|111
+      {0xfffff940ul, 26, 205},  //     11111111|11111111|11111001|01
+      {0xfffff100ul, 24, 206},  //     11111111|11111111|11110001
+      {0xfffff680ul, 25, 207},  //     11111111|11111111|11110110|1
+      {0xfffe4000ul, 19, 208},  //     11111111|11111110|010
+      {0xffff1800ul, 21, 209},  //     11111111|11111111|00011
+      {0xfffff980ul, 26, 210},  //     11111111|11111111|11111001|10
+      {0xfffffc00ul, 27, 211},  //     11111111|11111111|11111100|000
+      {0xfffffc20ul, 27, 212},  //     11111111|11111111|11111100|001
+      {0xfffff9c0ul, 26, 213},  //     11111111|11111111|11111001|11
+      {0xfffffc40ul, 27, 214},  //     11111111|11111111|11111100|010
+      {0xfffff200ul, 24, 215},  //     11111111|11111111|11110010
+      {0xffff2000ul, 21, 216},  //     11111111|11111111|00100
+      {0xffff2800ul, 21, 217},  //     11111111|11111111|00101
+      {0xfffffa00ul, 26, 218},  //     11111111|11111111|11111010|00
+      {0xfffffa40ul, 26, 219},  //     11111111|11111111|11111010|01
+      {0xffffffd0ul, 28, 220},  //     11111111|11111111|11111111|1101
+      {0xfffffc60ul, 27, 221},  //     11111111|11111111|11111100|011
+      {0xfffffc80ul, 27, 222},  //     11111111|11111111|11111100|100
+      {0xfffffca0ul, 27, 223},  //     11111111|11111111|11111100|101
+      {0xfffec000ul, 20, 224},  //     11111111|11111110|1100
+      {0xfffff300ul, 24, 225},  //     11111111|11111111|11110011
+      {0xfffed000ul, 20, 226},  //     11111111|11111110|1101
+      {0xffff3000ul, 21, 227},  //     11111111|11111111|00110
+      {0xffffa400ul, 22, 228},  //     11111111|11111111|101001
+      {0xffff3800ul, 21, 229},  //     11111111|11111111|00111
+      {0xffff4000ul, 21, 230},  //     11111111|11111111|01000
+      {0xffffe600ul, 23, 231},  //     11111111|11111111|1110011
+      {0xffffa800ul, 22, 232},  //     11111111|11111111|101010
+      {0xffffac00ul, 22, 233},  //     11111111|11111111|101011
+      {0xfffff700ul, 25, 234},  //     11111111|11111111|11110111|0
+      {0xfffff780ul, 25, 235},  //     11111111|11111111|11110111|1
+      {0xfffff400ul, 24, 236},  //     11111111|11111111|11110100
+      {0xfffff500ul, 24, 237},  //     11111111|11111111|11110101
+      {0xfffffa80ul, 26, 238},  //     11111111|11111111|11111010|10
+      {0xffffe800ul, 23, 239},  //     11111111|11111111|1110100
+      {0xfffffac0ul, 26, 240},  //     11111111|11111111|11111010|11
+      {0xfffffcc0ul, 27, 241},  //     11111111|11111111|11111100|110
+      {0xfffffb00ul, 26, 242},  //     11111111|11111111|11111011|00
+      {0xfffffb40ul, 26, 243},  //     11111111|11111111|11111011|01
+      {0xfffffce0ul, 27, 244},  //     11111111|11111111|11111100|111
+      {0xfffffd00ul, 27, 245},  //     11111111|11111111|11111101|000
+      {0xfffffd20ul, 27, 246},  //     11111111|11111111|11111101|001
+      {0xfffffd40ul, 27, 247},  //     11111111|11111111|11111101|010
+      {0xfffffd60ul, 27, 248},  //     11111111|11111111|11111101|011
+      {0xffffffe0ul, 28, 249},  //     11111111|11111111|11111111|1110
+      {0xfffffd80ul, 27, 250},  //     11111111|11111111|11111101|100
+      {0xfffffda0ul, 27, 251},  //     11111111|11111111|11111101|101
+      {0xfffffdc0ul, 27, 252},  //     11111111|11111111|11111101|110
+      {0xfffffde0ul, 27, 253},  //     11111111|11111111|11111101|111
+      {0xfffffe00ul, 27, 254},  //     11111111|11111111|11111110|000
+      {0xfffffb80ul, 26, 255},  //     11111111|11111111|11111011|10
+      {0xfffffffcul, 30, 256},  // EOS 11111111|11111111|11111111|111111
+  };
+  return *kHpackHuffmanCode;
+}
+
+// The "constructor" for a HpackStaticEntry that computes the lengths at
+// compile time.
+#define STATIC_ENTRY(name, value) \
+  { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 }
+
+const std::vector<HpackStaticEntry>& HpackStaticTableVector() {
+  static const auto* kHpackStaticTable = new std::vector<HpackStaticEntry>{
+      STATIC_ENTRY(":authority", ""),                    // 1
+      STATIC_ENTRY(":method", "GET"),                    // 2
+      STATIC_ENTRY(":method", "POST"),                   // 3
+      STATIC_ENTRY(":path", "/"),                        // 4
+      STATIC_ENTRY(":path", "/index.html"),              // 5
+      STATIC_ENTRY(":scheme", "http"),                   // 6
+      STATIC_ENTRY(":scheme", "https"),                  // 7
+      STATIC_ENTRY(":status", "200"),                    // 8
+      STATIC_ENTRY(":status", "204"),                    // 9
+      STATIC_ENTRY(":status", "206"),                    // 10
+      STATIC_ENTRY(":status", "304"),                    // 11
+      STATIC_ENTRY(":status", "400"),                    // 12
+      STATIC_ENTRY(":status", "404"),                    // 13
+      STATIC_ENTRY(":status", "500"),                    // 14
+      STATIC_ENTRY("accept-charset", ""),                // 15
+      STATIC_ENTRY("accept-encoding", "gzip, deflate"),  // 16
+      STATIC_ENTRY("accept-language", ""),               // 17
+      STATIC_ENTRY("accept-ranges", ""),                 // 18
+      STATIC_ENTRY("accept", ""),                        // 19
+      STATIC_ENTRY("access-control-allow-origin", ""),   // 20
+      STATIC_ENTRY("age", ""),                           // 21
+      STATIC_ENTRY("allow", ""),                         // 22
+      STATIC_ENTRY("authorization", ""),                 // 23
+      STATIC_ENTRY("cache-control", ""),                 // 24
+      STATIC_ENTRY("content-disposition", ""),           // 25
+      STATIC_ENTRY("content-encoding", ""),              // 26
+      STATIC_ENTRY("content-language", ""),              // 27
+      STATIC_ENTRY("content-length", ""),                // 28
+      STATIC_ENTRY("content-location", ""),              // 29
+      STATIC_ENTRY("content-range", ""),                 // 30
+      STATIC_ENTRY("content-type", ""),                  // 31
+      STATIC_ENTRY("cookie", ""),                        // 32
+      STATIC_ENTRY("date", ""),                          // 33
+      STATIC_ENTRY("etag", ""),                          // 34
+      STATIC_ENTRY("expect", ""),                        // 35
+      STATIC_ENTRY("expires", ""),                       // 36
+      STATIC_ENTRY("from", ""),                          // 37
+      STATIC_ENTRY("host", ""),                          // 38
+      STATIC_ENTRY("if-match", ""),                      // 39
+      STATIC_ENTRY("if-modified-since", ""),             // 40
+      STATIC_ENTRY("if-none-match", ""),                 // 41
+      STATIC_ENTRY("if-range", ""),                      // 42
+      STATIC_ENTRY("if-unmodified-since", ""),           // 43
+      STATIC_ENTRY("last-modified", ""),                 // 44
+      STATIC_ENTRY("link", ""),                          // 45
+      STATIC_ENTRY("location", ""),                      // 46
+      STATIC_ENTRY("max-forwards", ""),                  // 47
+      STATIC_ENTRY("proxy-authenticate", ""),            // 48
+      STATIC_ENTRY("proxy-authorization", ""),           // 49
+      STATIC_ENTRY("range", ""),                         // 50
+      STATIC_ENTRY("referer", ""),                       // 51
+      STATIC_ENTRY("refresh", ""),                       // 52
+      STATIC_ENTRY("retry-after", ""),                   // 53
+      STATIC_ENTRY("server", ""),                        // 54
+      STATIC_ENTRY("set-cookie", ""),                    // 55
+      STATIC_ENTRY("strict-transport-security", ""),     // 56
+      STATIC_ENTRY("transfer-encoding", ""),             // 57
+      STATIC_ENTRY("user-agent", ""),                    // 58
+      STATIC_ENTRY("vary", ""),                          // 59
+      STATIC_ENTRY("via", ""),                           // 60
+      STATIC_ENTRY("www-authenticate", ""),              // 61
+  };
+  return *kHpackStaticTable;
+}
+
+#undef STATIC_ENTRY
+
+const HpackStaticTable& ObtainHpackStaticTable() {
+  static const HpackStaticTable* const shared_static_table = []() {
+    auto* table = new HpackStaticTable();
+    table->Initialize(HpackStaticTableVector().data(),
+                      HpackStaticTableVector().size());
+    QUICHE_CHECK(table->IsInitialized());
+    return table;
+  }();
+  return *shared_static_table;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_constants.h b/quiche/spdy/core/hpack/hpack_constants.h
new file mode 100644
index 0000000..6c91a47
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_constants.h
@@ -0,0 +1,90 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+// All section references below are to
+// https://httpwg.org/specs/rfc7540.html and
+// https://httpwg.org/specs/rfc7541.html.
+
+namespace spdy {
+
+// An HpackPrefix signifies |bits| stored in the top |bit_size| bits
+// of an octet.
+struct HpackPrefix {
+  uint8_t bits;
+  size_t bit_size;
+};
+
+// Represents a symbol and its Huffman code (stored in most-significant bits).
+struct HpackHuffmanSymbol {
+  uint32_t code;
+  uint8_t length;
+  uint16_t id;
+};
+
+// An entry in the static table. Must be a POD in order to avoid static
+// initializers, i.e. no user-defined constructors or destructors.
+struct HpackStaticEntry {
+  const char* const name;
+  const size_t name_len;
+  const char* const value;
+  const size_t value_len;
+};
+
+class HpackStaticTable;
+
+// RFC 7540, 6.5.2: Initial value for SETTINGS_HEADER_TABLE_SIZE.
+const uint32_t kDefaultHeaderTableSizeSetting = 4096;
+
+// RFC 7541, 5.2: Flag for a string literal that is stored unmodified (i.e.,
+// without Huffman encoding).
+const HpackPrefix kStringLiteralIdentityEncoded = {0x0, 1};
+
+// RFC 7541, 5.2: Flag for a Huffman-coded string literal.
+const HpackPrefix kStringLiteralHuffmanEncoded = {0x1, 1};
+
+// RFC 7541, 6.1: Opcode for an indexed header field.
+const HpackPrefix kIndexedOpcode = {0b1, 1};
+
+// RFC 7541, 6.2.1: Opcode for a literal header field with incremental indexing.
+const HpackPrefix kLiteralIncrementalIndexOpcode = {0b01, 2};
+
+// RFC 7541, 6.2.2: Opcode for a literal header field without indexing.
+const HpackPrefix kLiteralNoIndexOpcode = {0b0000, 4};
+
+// RFC 7541, 6.2.3: Opcode for a literal header field which is never indexed.
+// Currently unused.
+// const HpackPrefix kLiteralNeverIndexOpcode = {0b0001, 4};
+
+// RFC 7541, 6.3: Opcode for maximum header table size update. Begins a
+// varint-encoded table size with a 5-bit prefix.
+const HpackPrefix kHeaderTableSizeUpdateOpcode = {0b001, 3};
+
+// RFC 7541, Appendix B: Huffman Code.
+QUICHE_EXPORT_PRIVATE const std::vector<HpackHuffmanSymbol>&
+HpackHuffmanCodeVector();
+
+// RFC 7541, Appendix A: Static Table Definition.
+QUICHE_EXPORT_PRIVATE const std::vector<HpackStaticEntry>&
+HpackStaticTableVector();
+
+// Returns a HpackStaticTable instance initialized with |kHpackStaticTable|.
+// The instance is read-only, has static lifetime, and is safe to share amoung
+// threads. This function is thread-safe.
+QUICHE_EXPORT_PRIVATE const HpackStaticTable& ObtainHpackStaticTable();
+
+// RFC 7541, 8.1.2.1: Pseudo-headers start with a colon.
+const char kPseudoHeaderPrefix = ':';
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
diff --git a/quiche/spdy/core/hpack/hpack_decoder_adapter.cc b/quiche/spdy/core/hpack/hpack_decoder_adapter.cc
new file mode 100644
index 0000000..447f258
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_decoder_adapter.cc
@@ -0,0 +1,165 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_decoder_adapter.h"
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+namespace {
+const size_t kMaxDecodeBufferSizeBytes = 32 * 1024;  // 32 KB
+}  // namespace
+
+HpackDecoderAdapter::HpackDecoderAdapter()
+    : hpack_decoder_(&listener_adapter_, kMaxDecodeBufferSizeBytes),
+      max_decode_buffer_size_bytes_(kMaxDecodeBufferSizeBytes),
+      max_header_block_bytes_(0),
+      header_block_started_(false),
+      error_(http2::HpackDecodingError::kOk) {}
+
+HpackDecoderAdapter::~HpackDecoderAdapter() = default;
+
+void HpackDecoderAdapter::ApplyHeaderTableSizeSetting(size_t size_setting) {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ApplyHeaderTableSizeSetting";
+  hpack_decoder_.ApplyHeaderTableSizeSetting(size_setting);
+}
+
+size_t HpackDecoderAdapter::GetCurrentHeaderTableSizeSetting() const {
+  return hpack_decoder_.GetCurrentHeaderTableSizeSetting();
+}
+
+void HpackDecoderAdapter::HandleControlFrameHeadersStart(
+    SpdyHeadersHandlerInterface* handler) {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::HandleControlFrameHeadersStart";
+  QUICHE_DCHECK(!header_block_started_);
+  listener_adapter_.set_handler(handler);
+}
+
+bool HpackDecoderAdapter::HandleControlFrameHeadersData(
+    const char* headers_data,
+    size_t headers_data_length) {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::HandleControlFrameHeadersData: len="
+                  << headers_data_length;
+  if (!header_block_started_) {
+    // Initialize the decoding process here rather than in
+    // HandleControlFrameHeadersStart because that method is not always called.
+    header_block_started_ = true;
+    if (!hpack_decoder_.StartDecodingBlock()) {
+      header_block_started_ = false;
+      error_ = hpack_decoder_.error();
+      detailed_error_ = hpack_decoder_.detailed_error();
+      return false;
+    }
+  }
+
+  // Sometimes we get a call with headers_data==nullptr and
+  // headers_data_length==0, in which case we need to avoid creating
+  // a DecodeBuffer, which would otherwise complain.
+  if (headers_data_length > 0) {
+    QUICHE_DCHECK_NE(headers_data, nullptr);
+    if (headers_data_length > max_decode_buffer_size_bytes_) {
+      QUICHE_DVLOG(1) << "max_decode_buffer_size_bytes_ < headers_data_length: "
+                      << max_decode_buffer_size_bytes_ << " < "
+                      << headers_data_length;
+      error_ = http2::HpackDecodingError::kFragmentTooLong;
+      detailed_error_ = "";
+      return false;
+    }
+    listener_adapter_.AddToTotalHpackBytes(headers_data_length);
+    if (max_header_block_bytes_ != 0 &&
+        listener_adapter_.total_hpack_bytes() > max_header_block_bytes_) {
+      error_ = http2::HpackDecodingError::kCompressedHeaderSizeExceedsLimit;
+      detailed_error_ = "";
+      return false;
+    }
+    http2::DecodeBuffer db(headers_data, headers_data_length);
+    bool ok = hpack_decoder_.DecodeFragment(&db);
+    QUICHE_DCHECK(!ok || db.Empty()) << "Remaining=" << db.Remaining();
+    if (!ok) {
+      error_ = hpack_decoder_.error();
+      detailed_error_ = hpack_decoder_.detailed_error();
+    }
+    return ok;
+  }
+  return true;
+}
+
+bool HpackDecoderAdapter::HandleControlFrameHeadersComplete() {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::HandleControlFrameHeadersComplete";
+  if (!hpack_decoder_.EndDecodingBlock()) {
+    QUICHE_DVLOG(3) << "EndDecodingBlock returned false";
+    error_ = hpack_decoder_.error();
+    detailed_error_ = hpack_decoder_.detailed_error();
+    return false;
+  }
+  header_block_started_ = false;
+  return true;
+}
+
+const SpdyHeaderBlock& HpackDecoderAdapter::decoded_block() const {
+  return listener_adapter_.decoded_block();
+}
+
+void HpackDecoderAdapter::set_max_decode_buffer_size_bytes(
+    size_t max_decode_buffer_size_bytes) {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::set_max_decode_buffer_size_bytes";
+  max_decode_buffer_size_bytes_ = max_decode_buffer_size_bytes;
+  hpack_decoder_.set_max_string_size_bytes(max_decode_buffer_size_bytes);
+}
+
+void HpackDecoderAdapter::set_max_header_block_bytes(
+    size_t max_header_block_bytes) {
+  max_header_block_bytes_ = max_header_block_bytes;
+}
+
+HpackDecoderAdapter::ListenerAdapter::ListenerAdapter() : handler_(nullptr) {}
+HpackDecoderAdapter::ListenerAdapter::~ListenerAdapter() = default;
+
+void HpackDecoderAdapter::ListenerAdapter::set_handler(
+    SpdyHeadersHandlerInterface* handler) {
+  handler_ = handler;
+}
+
+void HpackDecoderAdapter::ListenerAdapter::OnHeaderListStart() {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ListenerAdapter::OnHeaderListStart";
+  total_hpack_bytes_ = 0;
+  total_uncompressed_bytes_ = 0;
+  decoded_block_.clear();
+  if (handler_ != nullptr) {
+    handler_->OnHeaderBlockStart();
+  }
+}
+
+void HpackDecoderAdapter::ListenerAdapter::OnHeader(const std::string& name,
+                                                    const std::string& value) {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ListenerAdapter::OnHeader:\n name: "
+                  << name << "\n value: " << value;
+  total_uncompressed_bytes_ += name.size() + value.size();
+  if (handler_ == nullptr) {
+    QUICHE_DVLOG(3) << "Adding to decoded_block";
+    decoded_block_.AppendValueOrAddHeader(name, value);
+  } else {
+    QUICHE_DVLOG(3) << "Passing to handler";
+    handler_->OnHeader(name, value);
+  }
+}
+
+void HpackDecoderAdapter::ListenerAdapter::OnHeaderListEnd() {
+  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ListenerAdapter::OnHeaderListEnd";
+  // We don't clear the SpdyHeaderBlock here to allow access to it until the
+  // next HPACK block is decoded.
+  if (handler_ != nullptr) {
+    handler_->OnHeaderBlockEnd(total_uncompressed_bytes_, total_hpack_bytes_);
+    handler_ = nullptr;
+  }
+}
+
+void HpackDecoderAdapter::ListenerAdapter::OnHeaderErrorDetected(
+    absl::string_view error_message) {
+  QUICHE_VLOG(1) << error_message;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_decoder_adapter.h b/quiche/spdy/core/hpack/hpack_decoder_adapter.h
new file mode 100644
index 0000000..d1eefbd
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_decoder_adapter.h
@@ -0,0 +1,157 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_DECODER_ADAPTER_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_DECODER_ADAPTER_H_
+
+// HpackDecoderAdapter uses http2::HpackDecoder to decode HPACK blocks into
+// HTTP/2 header lists as outlined in http://tools.ietf.org/html/rfc7541.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_listener.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+#include "quiche/http2/hpack/http2_hpack_constants.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+
+namespace spdy {
+namespace test {
+class HpackDecoderAdapterPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE HpackDecoderAdapter {
+ public:
+  friend test::HpackDecoderAdapterPeer;
+  HpackDecoderAdapter();
+  HpackDecoderAdapter(const HpackDecoderAdapter&) = delete;
+  HpackDecoderAdapter& operator=(const HpackDecoderAdapter&) = delete;
+  ~HpackDecoderAdapter();
+
+  // Called upon acknowledgement of SETTINGS_HEADER_TABLE_SIZE.
+  void ApplyHeaderTableSizeSetting(size_t size_setting);
+
+  // Returns the most recently applied value of SETTINGS_HEADER_TABLE_SIZE.
+  size_t GetCurrentHeaderTableSizeSetting() const;
+
+  // If a SpdyHeadersHandlerInterface is provided, the decoder will emit
+  // headers to it rather than accumulating them in a SpdyHeaderBlock.
+  // Does not take ownership of the handler, but does use the pointer until
+  // the current HPACK block is completely decoded.
+  void HandleControlFrameHeadersStart(SpdyHeadersHandlerInterface* handler);
+
+  // Called as HPACK block fragments arrive. Returns false if an error occurred
+  // while decoding the block. Does not take ownership of headers_data.
+  bool HandleControlFrameHeadersData(const char* headers_data,
+                                     size_t headers_data_length);
+
+  // Called after a HPACK block has been completely delivered via
+  // HandleControlFrameHeadersData(). Returns false if an error occurred.
+  // |compressed_len| if non-null will be set to the size of the encoded
+  // buffered block that was accumulated in HandleControlFrameHeadersData(),
+  // to support subsequent calculation of compression percentage.
+  // Discards the handler supplied at the start of decoding the block.
+  bool HandleControlFrameHeadersComplete();
+
+  // Accessor for the most recently decoded headers block. Valid until the next
+  // call to HandleControlFrameHeadersData().
+  // TODO(birenroy): Remove this method when all users of HpackDecoder specify
+  // a SpdyHeadersHandlerInterface.
+  const SpdyHeaderBlock& decoded_block() const;
+
+  // Returns the current dynamic table size, including the 32 bytes per entry
+  // overhead mentioned in RFC 7541 section 4.1.
+  size_t GetDynamicTableSize() const {
+    return hpack_decoder_.GetDynamicTableSize();
+  }
+
+  // Set how much encoded data this decoder is willing to buffer.
+  // TODO(jamessynge): Resolve definition of this value, as it is currently
+  // too tied to a single implementation. We probably want to limit one or more
+  // of these: individual name or value strings, header entries, the entire
+  // header list, or the HPACK block; we probably shouldn't care about the size
+  // of individual transport buffers.
+  void set_max_decode_buffer_size_bytes(size_t max_decode_buffer_size_bytes);
+
+  // Specifies the maximum size of an on-the-wire header block that will be
+  // accepted.
+  void set_max_header_block_bytes(size_t max_header_block_bytes);
+
+  // Error code if an error has occurred, Error::kOk otherwise.
+  http2::HpackDecodingError error() const { return error_; }
+
+  std::string detailed_error() const { return detailed_error_; }
+
+ private:
+  class QUICHE_EXPORT_PRIVATE ListenerAdapter
+      : public http2::HpackDecoderListener {
+   public:
+    ListenerAdapter();
+    ~ListenerAdapter() override;
+
+    // If a SpdyHeadersHandlerInterface is provided, the decoder will emit
+    // headers to it rather than accumulating them in a SpdyHeaderBlock.
+    // Does not take ownership of the handler, but does use the pointer until
+    // the current HPACK block is completely decoded.
+    void set_handler(SpdyHeadersHandlerInterface* handler);
+    const SpdyHeaderBlock& decoded_block() const { return decoded_block_; }
+
+    // Override the HpackDecoderListener methods:
+    void OnHeaderListStart() override;
+    void OnHeader(const std::string& name, const std::string& value) override;
+    void OnHeaderListEnd() override;
+    void OnHeaderErrorDetected(absl::string_view error_message) override;
+
+    void AddToTotalHpackBytes(size_t delta) { total_hpack_bytes_ += delta; }
+    size_t total_hpack_bytes() const { return total_hpack_bytes_; }
+
+   private:
+    // If the caller doesn't provide a handler, the header list is stored in
+    // this SpdyHeaderBlock.
+    SpdyHeaderBlock decoded_block_;
+
+    // If non-NULL, handles decoded headers. Not owned.
+    SpdyHeadersHandlerInterface* handler_;
+
+    // Total bytes that have been received as input (i.e. HPACK encoded)
+    // in the current HPACK block.
+    size_t total_hpack_bytes_;
+
+    // Total bytes of the name and value strings in the current HPACK block.
+    size_t total_uncompressed_bytes_;
+  };
+
+  // Converts calls to HpackDecoderListener into calls to
+  // SpdyHeadersHandlerInterface.
+  ListenerAdapter listener_adapter_;
+
+  // The actual decoder.
+  http2::HpackDecoder hpack_decoder_;
+
+  // How much encoded data this decoder is willing to buffer.
+  size_t max_decode_buffer_size_bytes_;
+
+  // How much encoded data this decoder is willing to process.
+  size_t max_header_block_bytes_;
+
+  // Flag to keep track of having seen the header block start. Needed at the
+  // moment because HandleControlFrameHeadersStart won't be called if a handler
+  // is not being provided by the caller.
+  bool header_block_started_;
+
+  // Error code if an error has occurred, Error::kOk otherwise.
+  http2::HpackDecodingError error_;
+  std::string detailed_error_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_DECODER_ADAPTER_H_
diff --git a/quiche/spdy/core/hpack/hpack_decoder_adapter_test.cc b/quiche/spdy/core/hpack/hpack_decoder_adapter_test.cc
new file mode 100644
index 0000000..f51e2a9
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_decoder_adapter_test.cc
@@ -0,0 +1,1123 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_decoder_adapter.h"
+
+// Tests of HpackDecoderAdapter.
+
+#include <stdint.h>
+
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_state.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_tables.h"
+#include "quiche/http2/hpack/tools/hpack_block_builder.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+#include "quiche/spdy/core/hpack/hpack_output_stream.h"
+#include "quiche/spdy/core/recording_headers_handler.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+using ::http2::HpackEntryType;
+using ::http2::HpackStringPair;
+using ::http2::test::HpackBlockBuilder;
+using ::http2::test::HpackDecoderPeer;
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
+namespace http2 {
+namespace test {
+
+class HpackDecoderStatePeer {
+ public:
+  static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) {
+    return &state->decoder_tables_;
+  }
+};
+
+class HpackDecoderPeer {
+ public:
+  static HpackDecoderState* GetDecoderState(HpackDecoder* decoder) {
+    return &decoder->decoder_state_;
+  }
+  static HpackDecoderTables* GetDecoderTables(HpackDecoder* decoder) {
+    return HpackDecoderStatePeer::GetDecoderTables(GetDecoderState(decoder));
+  }
+};
+
+}  // namespace test
+}  // namespace http2
+
+namespace spdy {
+namespace test {
+
+class HpackDecoderAdapterPeer {
+ public:
+  explicit HpackDecoderAdapterPeer(HpackDecoderAdapter* decoder)
+      : decoder_(decoder) {}
+
+  void HandleHeaderRepresentation(const std::string& name,
+                                  const std::string& value) {
+    decoder_->listener_adapter_.OnHeader(name, value);
+  }
+
+  http2::HpackDecoderTables* GetDecoderTables() {
+    return HpackDecoderPeer::GetDecoderTables(&decoder_->hpack_decoder_);
+  }
+
+  const HpackStringPair* GetTableEntry(uint32_t index) {
+    return GetDecoderTables()->Lookup(index);
+  }
+
+  size_t current_header_table_size() {
+    return GetDecoderTables()->current_header_table_size();
+  }
+
+  size_t header_table_size_limit() {
+    return GetDecoderTables()->header_table_size_limit();
+  }
+
+  void set_header_table_size_limit(size_t size) {
+    return GetDecoderTables()->DynamicTableSizeUpdate(size);
+  }
+
+ private:
+  HpackDecoderAdapter* decoder_;
+};
+
+class HpackEncoderPeer {
+ public:
+  static void CookieToCrumbs(const HpackEncoder::Representation& cookie,
+                             HpackEncoder::Representations* crumbs_out) {
+    HpackEncoder::CookieToCrumbs(cookie, crumbs_out);
+  }
+};
+
+namespace {
+
+const bool kNoCheckDecodedSize = false;
+const char* kCookieKey = "cookie";
+
+// Is HandleControlFrameHeadersStart to be called, and with what value?
+enum StartChoice { START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START };
+
+class HpackDecoderAdapterTest
+    : public QuicheTestWithParam<std::tuple<StartChoice, bool>> {
+ protected:
+  HpackDecoderAdapterTest() : decoder_(), decoder_peer_(&decoder_) {}
+
+  void SetUp() override {
+    std::tie(start_choice_, randomly_split_input_buffer_) = GetParam();
+  }
+
+  void HandleControlFrameHeadersStart() {
+    bytes_passed_in_ = 0;
+    switch (start_choice_) {
+      case START_WITH_HANDLER:
+        decoder_.HandleControlFrameHeadersStart(&handler_);
+        break;
+      case START_WITHOUT_HANDLER:
+        decoder_.HandleControlFrameHeadersStart(nullptr);
+        break;
+      case NO_START:
+        break;
+    }
+  }
+
+  bool HandleControlFrameHeadersData(absl::string_view str) {
+    QUICHE_VLOG(3) << "HandleControlFrameHeadersData:\n"
+                   << quiche::QuicheTextUtils::HexDump(str);
+    bytes_passed_in_ += str.size();
+    return decoder_.HandleControlFrameHeadersData(str.data(), str.size());
+  }
+
+  bool HandleControlFrameHeadersComplete() {
+    bool rc = decoder_.HandleControlFrameHeadersComplete();
+    return rc;
+  }
+
+  bool DecodeHeaderBlock(absl::string_view str,
+                         bool check_decoded_size = true) {
+    // Don't call this again if HandleControlFrameHeadersData failed previously.
+    EXPECT_FALSE(decode_has_failed_);
+    HandleControlFrameHeadersStart();
+    if (randomly_split_input_buffer_) {
+      do {
+        // Decode some fragment of the remaining bytes.
+        size_t bytes = str.size();
+        if (!str.empty()) {
+          bytes = random_.Uniform(str.size()) + 1;
+        }
+        EXPECT_LE(bytes, str.size());
+        if (!HandleControlFrameHeadersData(str.substr(0, bytes))) {
+          decode_has_failed_ = true;
+          return false;
+        }
+        str.remove_prefix(bytes);
+      } while (!str.empty());
+    } else if (!HandleControlFrameHeadersData(str)) {
+      decode_has_failed_ = true;
+      return false;
+    }
+    if (start_choice_ == START_WITH_HANDLER) {
+      if (!HandleControlFrameHeadersComplete()) {
+        decode_has_failed_ = true;
+        return false;
+      }
+      EXPECT_EQ(handler_.compressed_header_bytes(), bytes_passed_in_);
+    } else {
+      if (!HandleControlFrameHeadersComplete()) {
+        decode_has_failed_ = true;
+        return false;
+      }
+    }
+    if (check_decoded_size && start_choice_ == START_WITH_HANDLER) {
+      EXPECT_EQ(handler_.uncompressed_header_bytes(),
+                SizeOfHeaders(decoded_block()));
+    }
+    return true;
+  }
+
+  bool EncodeAndDecodeDynamicTableSizeUpdates(size_t first, size_t second) {
+    HpackBlockBuilder hbb;
+    hbb.AppendDynamicTableSizeUpdate(first);
+    if (second != first) {
+      hbb.AppendDynamicTableSizeUpdate(second);
+    }
+    return DecodeHeaderBlock(hbb.buffer());
+  }
+
+  const SpdyHeaderBlock& decoded_block() const {
+    if (start_choice_ == START_WITH_HANDLER) {
+      return handler_.decoded_block();
+    } else {
+      return decoder_.decoded_block();
+    }
+  }
+
+  static size_t SizeOfHeaders(const SpdyHeaderBlock& headers) {
+    size_t size = 0;
+    for (const auto& kv : headers) {
+      if (kv.first == kCookieKey) {
+        HpackEncoder::Representations crumbs;
+        HpackEncoderPeer::CookieToCrumbs(kv, &crumbs);
+        for (const auto& crumb : crumbs) {
+          size += crumb.first.size() + crumb.second.size();
+        }
+      } else {
+        size += kv.first.size() + kv.second.size();
+      }
+    }
+    return size;
+  }
+
+  const SpdyHeaderBlock& DecodeBlockExpectingSuccess(absl::string_view str) {
+    EXPECT_TRUE(DecodeHeaderBlock(str));
+    return decoded_block();
+  }
+
+  void expectEntry(size_t index,
+                   size_t size,
+                   const std::string& name,
+                   const std::string& value) {
+    const HpackStringPair* entry = decoder_peer_.GetTableEntry(index);
+    EXPECT_EQ(name, entry->name) << "index " << index;
+    EXPECT_EQ(value, entry->value);
+    EXPECT_EQ(size, entry->size());
+  }
+
+  SpdyHeaderBlock MakeHeaderBlock(
+      const std::vector<std::pair<std::string, std::string>>& headers) {
+    SpdyHeaderBlock result;
+    for (const auto& kv : headers) {
+      result.AppendValueOrAddHeader(kv.first, kv.second);
+    }
+    return result;
+  }
+
+  http2::test::Http2Random random_;
+  HpackDecoderAdapter decoder_;
+  test::HpackDecoderAdapterPeer decoder_peer_;
+  RecordingHeadersHandler handler_;
+  StartChoice start_choice_;
+  bool randomly_split_input_buffer_;
+  bool decode_has_failed_ = false;
+  size_t bytes_passed_in_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    NoHandler,
+    HpackDecoderAdapterTest,
+    ::testing::Combine(::testing::Values(START_WITHOUT_HANDLER, NO_START),
+                       ::testing::Bool()));
+
+INSTANTIATE_TEST_SUITE_P(
+    WithHandler,
+    HpackDecoderAdapterTest,
+    ::testing::Combine(::testing::Values(START_WITH_HANDLER),
+                       ::testing::Bool()));
+
+TEST_P(HpackDecoderAdapterTest, ApplyHeaderTableSizeSetting) {
+  EXPECT_EQ(4096u, decoder_.GetCurrentHeaderTableSizeSetting());
+  decoder_.ApplyHeaderTableSizeSetting(12 * 1024);
+  EXPECT_EQ(12288u, decoder_.GetCurrentHeaderTableSizeSetting());
+}
+
+TEST_P(HpackDecoderAdapterTest,
+       AddHeaderDataWithHandleControlFrameHeadersData) {
+  // The hpack decode buffer size is limited in size. This test verifies that
+  // adding encoded data under that limit is accepted, and data that exceeds the
+  // limit is rejected.
+  HandleControlFrameHeadersStart();
+  const size_t kMaxBufferSizeBytes = 50;
+  const std::string a_value = std::string(49, 'x');
+  decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes);
+  HpackBlockBuilder hbb;
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
+                                false, "a", false, a_value);
+  const std::string& s = hbb.buffer();
+  EXPECT_GT(s.size(), kMaxBufferSizeBytes);
+
+  // Any one in input buffer must not exceed kMaxBufferSizeBytes.
+  EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(0, s.size() / 2)));
+  EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(s.size() / 2)));
+
+  EXPECT_FALSE(HandleControlFrameHeadersData(s));
+  SpdyHeaderBlock expected_block = MakeHeaderBlock({{"a", a_value}});
+  EXPECT_EQ(expected_block, decoded_block());
+}
+
+TEST_P(HpackDecoderAdapterTest, NameTooLong) {
+  // Verify that a name longer than the allowed size generates an error.
+  const size_t kMaxBufferSizeBytes = 50;
+  const std::string name = std::string(2 * kMaxBufferSizeBytes, 'x');
+  const std::string value = "abc";
+
+  decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes);
+
+  HpackBlockBuilder hbb;
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
+                                false, name, false, value);
+
+  const size_t fragment_size = (3 * kMaxBufferSizeBytes) / 2;
+  const std::string fragment = hbb.buffer().substr(0, fragment_size);
+
+  HandleControlFrameHeadersStart();
+  EXPECT_FALSE(HandleControlFrameHeadersData(fragment));
+}
+
+TEST_P(HpackDecoderAdapterTest, HeaderTooLongToBuffer) {
+  // Verify that a header longer than the allowed size generates an error if
+  // it isn't all in one input buffer.
+  const std::string name = "some-key";
+  const std::string value = "some-value";
+  const size_t kMaxBufferSizeBytes = name.size() + value.size() - 2;
+  decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes);
+
+  HpackBlockBuilder hbb;
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
+                                false, name, false, value);
+  const size_t fragment_size = hbb.size() - 1;
+  const std::string fragment = hbb.buffer().substr(0, fragment_size);
+
+  HandleControlFrameHeadersStart();
+  EXPECT_FALSE(HandleControlFrameHeadersData(fragment));
+}
+
+// Verify that a header block that exceeds the maximum length is rejected.
+TEST_P(HpackDecoderAdapterTest, HeaderBlockTooLong) {
+  const std::string name = "some-key";
+  const std::string value = "some-value";
+  const size_t kMaxBufferSizeBytes = 1024;
+
+  HpackBlockBuilder hbb;
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false,
+                                name, false, value);
+  while (hbb.size() < kMaxBufferSizeBytes) {
+    hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false,
+                                  "", false, "");
+  }
+  // With no limit on the maximum header block size, the decoder handles the
+  // entire block successfully.
+  HandleControlFrameHeadersStart();
+  EXPECT_TRUE(HandleControlFrameHeadersData(hbb.buffer()));
+  EXPECT_TRUE(HandleControlFrameHeadersComplete());
+
+  // When a total byte limit is imposed, the decoder bails before the end of the
+  // block.
+  decoder_.set_max_header_block_bytes(kMaxBufferSizeBytes);
+  HandleControlFrameHeadersStart();
+  EXPECT_FALSE(HandleControlFrameHeadersData(hbb.buffer()));
+}
+
+// Decode with incomplete data in buffer.
+TEST_P(HpackDecoderAdapterTest, DecodeWithIncompleteData) {
+  HandleControlFrameHeadersStart();
+
+  // No need to wait for more data.
+  EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82"));
+  std::vector<std::pair<std::string, std::string>> expected_headers = {
+      {":method", "GET"}, {":path", "/index.html"}, {":method", "GET"}};
+
+  SpdyHeaderBlock expected_block1 = MakeHeaderBlock(expected_headers);
+  EXPECT_EQ(expected_block1, decoded_block());
+
+  // Full and partial headers, won't add partial to the headers.
+  EXPECT_TRUE(
+      HandleControlFrameHeadersData("\x40\x03goo"
+                                    "\x03gar\xbe\x40\x04spam"));
+  expected_headers.push_back({"goo", "gar"});
+  expected_headers.push_back({"goo", "gar"});
+
+  SpdyHeaderBlock expected_block2 = MakeHeaderBlock(expected_headers);
+  EXPECT_EQ(expected_block2, decoded_block());
+
+  // Add the needed data.
+  EXPECT_TRUE(HandleControlFrameHeadersData("\x04gggs"));
+
+  EXPECT_TRUE(HandleControlFrameHeadersComplete());
+
+  expected_headers.push_back({"spam", "gggs"});
+
+  SpdyHeaderBlock expected_block3 = MakeHeaderBlock(expected_headers);
+  EXPECT_EQ(expected_block3, decoded_block());
+}
+
+TEST_P(HpackDecoderAdapterTest, HandleHeaderRepresentation) {
+  // Make sure the decoder is properly initialized.
+  HandleControlFrameHeadersStart();
+  HandleControlFrameHeadersData("");
+
+  // All cookie crumbs are joined.
+  decoder_peer_.HandleHeaderRepresentation("cookie", " part 1");
+  decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 ");
+  decoder_peer_.HandleHeaderRepresentation("cookie", "part3");
+
+  // Already-delimited headers are passed through.
+  decoder_peer_.HandleHeaderRepresentation("passed-through",
+                                           std::string("foo\0baz", 7));
+
+  // Other headers are joined on \0. Case matters.
+  decoder_peer_.HandleHeaderRepresentation("joined", "joined");
+  decoder_peer_.HandleHeaderRepresentation("joineD", "value 1");
+  decoder_peer_.HandleHeaderRepresentation("joineD", "value 2");
+
+  // Empty headers remain empty.
+  decoder_peer_.HandleHeaderRepresentation("empty", "");
+
+  // Joined empty headers work as expected.
+  decoder_peer_.HandleHeaderRepresentation("empty-joined", "");
+  decoder_peer_.HandleHeaderRepresentation("empty-joined", "foo");
+  decoder_peer_.HandleHeaderRepresentation("empty-joined", "");
+  decoder_peer_.HandleHeaderRepresentation("empty-joined", "");
+
+  // Non-contiguous cookie crumb.
+  decoder_peer_.HandleHeaderRepresentation("cookie", " fin!");
+
+  // Finish and emit all headers.
+  decoder_.HandleControlFrameHeadersComplete();
+
+  // Resulting decoded headers are in the same order as the inputs.
+  EXPECT_THAT(
+      decoded_block(),
+      ElementsAre(
+          Pair("cookie", " part 1; part 2 ; part3;  fin!"),
+          Pair("passed-through", absl::string_view("foo\0baz", 7)),
+          Pair("joined", absl::string_view("joined\0value 1\0value 2", 22)),
+          Pair("empty", ""),
+          Pair("empty-joined", absl::string_view("\0foo\0\0", 6))));
+}
+
+// Decoding indexed static table field should work.
+TEST_P(HpackDecoderAdapterTest, IndexedHeaderStatic) {
+  // Reference static table entries #2 and #5.
+  const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess("\x82\x85");
+  SpdyHeaderBlock expected_header_set1;
+  expected_header_set1[":method"] = "GET";
+  expected_header_set1[":path"] = "/index.html";
+  EXPECT_EQ(expected_header_set1, header_set1);
+
+  // Reference static table entry #2.
+  const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess("\x82");
+  SpdyHeaderBlock expected_header_set2;
+  expected_header_set2[":method"] = "GET";
+  EXPECT_EQ(expected_header_set2, header_set2);
+}
+
+TEST_P(HpackDecoderAdapterTest, IndexedHeaderDynamic) {
+  // First header block: add an entry to header table.
+  const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess(
+      "\x40\x03"
+      "foo"
+      "\x03"
+      "bar");
+  SpdyHeaderBlock expected_header_set1;
+  expected_header_set1["foo"] = "bar";
+  EXPECT_EQ(expected_header_set1, header_set1);
+
+  // Second header block: add another entry to header table.
+  const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess(
+      "\xbe\x40\x04"
+      "spam"
+      "\x04"
+      "eggs");
+  SpdyHeaderBlock expected_header_set2;
+  expected_header_set2["foo"] = "bar";
+  expected_header_set2["spam"] = "eggs";
+  EXPECT_EQ(expected_header_set2, header_set2);
+
+  // Third header block: refer to most recently added entry.
+  const SpdyHeaderBlock& header_set3 = DecodeBlockExpectingSuccess("\xbe");
+  SpdyHeaderBlock expected_header_set3;
+  expected_header_set3["spam"] = "eggs";
+  EXPECT_EQ(expected_header_set3, header_set3);
+}
+
+// Test a too-large indexed header.
+TEST_P(HpackDecoderAdapterTest, InvalidIndexedHeader) {
+  // High-bit set, and a prefix of one more than the number of static entries.
+  EXPECT_FALSE(DecodeHeaderBlock("\xbe"));
+}
+
+TEST_P(HpackDecoderAdapterTest, ContextUpdateMaximumSize) {
+  EXPECT_EQ(kDefaultHeaderTableSizeSetting,
+            decoder_peer_.header_table_size_limit());
+  std::string input;
+  {
+    // Maximum-size update with size 126. Succeeds.
+    HpackOutputStream output_stream;
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(126);
+
+    input = output_stream.TakeString();
+    EXPECT_TRUE(DecodeHeaderBlock(input));
+    EXPECT_EQ(126u, decoder_peer_.header_table_size_limit());
+  }
+  {
+    // Maximum-size update with kDefaultHeaderTableSizeSetting. Succeeds.
+    HpackOutputStream output_stream;
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(kDefaultHeaderTableSizeSetting);
+
+    input = output_stream.TakeString();
+    EXPECT_TRUE(DecodeHeaderBlock(input));
+    EXPECT_EQ(kDefaultHeaderTableSizeSetting,
+              decoder_peer_.header_table_size_limit());
+  }
+  {
+    // Maximum-size update with kDefaultHeaderTableSizeSetting + 1. Fails.
+    HpackOutputStream output_stream;
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1);
+
+    input = output_stream.TakeString();
+    EXPECT_FALSE(DecodeHeaderBlock(input));
+    EXPECT_EQ(kDefaultHeaderTableSizeSetting,
+              decoder_peer_.header_table_size_limit());
+  }
+}
+
+// Two HeaderTableSizeUpdates may appear at the beginning of the block
+TEST_P(HpackDecoderAdapterTest, TwoTableSizeUpdates) {
+  std::string input;
+  {
+    // Should accept two table size updates, update to second one
+    HpackOutputStream output_stream;
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(0);
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(122);
+
+    input = output_stream.TakeString();
+    EXPECT_TRUE(DecodeHeaderBlock(input));
+    EXPECT_EQ(122u, decoder_peer_.header_table_size_limit());
+  }
+}
+
+// Three HeaderTableSizeUpdates should result in an error
+TEST_P(HpackDecoderAdapterTest, ThreeTableSizeUpdatesError) {
+  std::string input;
+  {
+    // Should reject three table size updates, update to second one
+    HpackOutputStream output_stream;
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(5);
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(10);
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(15);
+
+    input = output_stream.TakeString();
+
+    EXPECT_FALSE(DecodeHeaderBlock(input));
+    EXPECT_EQ(10u, decoder_peer_.header_table_size_limit());
+  }
+}
+
+// HeaderTableSizeUpdates may only appear at the beginning of the block
+// Any other updates should result in an error
+TEST_P(HpackDecoderAdapterTest, TableSizeUpdateSecondError) {
+  std::string input;
+  {
+    // Should reject a table size update appearing after a different entry
+    // The table size should remain as the default
+    HpackOutputStream output_stream;
+    output_stream.AppendBytes("\x82\x85");
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(123);
+
+    input = output_stream.TakeString();
+
+    EXPECT_FALSE(DecodeHeaderBlock(input));
+    EXPECT_EQ(kDefaultHeaderTableSizeSetting,
+              decoder_peer_.header_table_size_limit());
+  }
+}
+
+// HeaderTableSizeUpdates may only appear at the beginning of the block
+// Any other updates should result in an error
+TEST_P(HpackDecoderAdapterTest, TableSizeUpdateFirstThirdError) {
+  std::string input;
+  {
+    // Should reject the second table size update
+    // if a different entry appears after the first update
+    // The table size should update to the first but not the second
+    HpackOutputStream output_stream;
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(60);
+    output_stream.AppendBytes("\x82\x85");
+    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream.AppendUint32(125);
+
+    input = output_stream.TakeString();
+
+    EXPECT_FALSE(DecodeHeaderBlock(input));
+    EXPECT_EQ(60u, decoder_peer_.header_table_size_limit());
+  }
+}
+
+// Decoding two valid encoded literal headers with no indexing should
+// work.
+TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexing) {
+  // First header with indexed name, second header with string literal
+  // name.
+  const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2";
+  const SpdyHeaderBlock& header_set = DecodeBlockExpectingSuccess(
+      absl::string_view(input, ABSL_ARRAYSIZE(input) - 1));
+
+  SpdyHeaderBlock expected_header_set;
+  expected_header_set[":path"] = "/sample/path";
+  expected_header_set[":path2"] = "/sample/path/2";
+  EXPECT_EQ(expected_header_set, header_set);
+}
+
+// Decoding two valid encoded literal headers with incremental
+// indexing and string literal names should work.
+TEST_P(HpackDecoderAdapterTest, LiteralHeaderIncrementalIndexing) {
+  const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2";
+  const SpdyHeaderBlock& header_set = DecodeBlockExpectingSuccess(
+      absl::string_view(input, ABSL_ARRAYSIZE(input) - 1));
+
+  SpdyHeaderBlock expected_header_set;
+  expected_header_set[":path"] = "/sample/path";
+  expected_header_set[":path2"] = "/sample/path/2";
+  EXPECT_EQ(expected_header_set, header_set);
+}
+
+TEST_P(HpackDecoderAdapterTest, LiteralHeaderWithIndexingInvalidNameIndex) {
+  decoder_.ApplyHeaderTableSizeSetting(0);
+  EXPECT_TRUE(EncodeAndDecodeDynamicTableSizeUpdates(0, 0));
+
+  // Name is the last static index. Works.
+  EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x7d\x03ooo")));
+  // Name is one beyond the last static index. Fails.
+  EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x7e\x03ooo")));
+}
+
+TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexingInvalidNameIndex) {
+  // Name is the last static index. Works.
+  EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x0f\x2e\x03ooo")));
+  // Name is one beyond the last static index. Fails.
+  EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x0f\x2f\x03ooo")));
+}
+
+TEST_P(HpackDecoderAdapterTest, LiteralHeaderNeverIndexedInvalidNameIndex) {
+  // Name is the last static index. Works.
+  EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x1f\x2e\x03ooo")));
+  // Name is one beyond the last static index. Fails.
+  EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x1f\x2f\x03ooo")));
+}
+
+TEST_P(HpackDecoderAdapterTest, TruncatedIndex) {
+  // Indexed Header, varint for index requires multiple bytes,
+  // but only one provided.
+  EXPECT_FALSE(DecodeHeaderBlock("\xff"));
+}
+
+TEST_P(HpackDecoderAdapterTest, TruncatedHuffmanLiteral) {
+  // Literal value, Huffman encoded, but with the last byte missing (i.e.
+  // drop the final ff shown below).
+  //
+  // 41                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 1)
+  //                                         |     :authority
+  // 8c                                      |   Literal value (len = 12)
+  //                                         |     Huffman encoded:
+  // f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
+  //                                         |     Decoded:
+  //                                         | www.example.com
+  //                                         | -> :authority: www.example.com
+
+  std::string first = absl::HexStringToBytes("418cf1e3c2e5f23a6ba0ab90f4ff");
+  EXPECT_TRUE(DecodeHeaderBlock(first));
+  first.pop_back();
+  EXPECT_FALSE(DecodeHeaderBlock(first));
+}
+
+TEST_P(HpackDecoderAdapterTest, HuffmanEOSError) {
+  // Literal value, Huffman encoded, but with an additional ff byte at the end
+  // of the string, i.e. an EOS that is longer than permitted.
+  //
+  // 41                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 1)
+  //                                         |     :authority
+  // 8d                                      |   Literal value (len = 13)
+  //                                         |     Huffman encoded:
+  // f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
+  //                                         |     Decoded:
+  //                                         | www.example.com
+  //                                         | -> :authority: www.example.com
+
+  std::string first = absl::HexStringToBytes("418cf1e3c2e5f23a6ba0ab90f4ff");
+  EXPECT_TRUE(DecodeHeaderBlock(first));
+  first = absl::HexStringToBytes("418df1e3c2e5f23a6ba0ab90f4ffff");
+  EXPECT_FALSE(DecodeHeaderBlock(first));
+}
+
+// Round-tripping the header set from RFC 7541 C.3.1 should work.
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1
+TEST_P(HpackDecoderAdapterTest, BasicC31) {
+  HpackEncoder encoder;
+
+  SpdyHeaderBlock expected_header_set;
+  expected_header_set[":method"] = "GET";
+  expected_header_set[":scheme"] = "http";
+  expected_header_set[":path"] = "/";
+  expected_header_set[":authority"] = "www.example.com";
+
+  std::string encoded_header_set =
+      encoder.EncodeHeaderBlock(expected_header_set);
+
+  EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set));
+  EXPECT_EQ(expected_header_set, decoded_block());
+}
+
+// RFC 7541, Section C.4: Request Examples with Huffman Coding
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4
+TEST_P(HpackDecoderAdapterTest, SectionC4RequestHuffmanExamples) {
+  // TODO(jamessynge): Use http2/hpack/tools/hpack_example.h to parse the
+  // example directly, instead of having it as a comment.
+  //
+  // 82                                      | == Indexed - Add ==
+  //                                         |   idx = 2
+  //                                         | -> :method: GET
+  // 86                                      | == Indexed - Add ==
+  //                                         |   idx = 6
+  //                                         | -> :scheme: http
+  // 84                                      | == Indexed - Add ==
+  //                                         |   idx = 4
+  //                                         | -> :path: /
+  // 41                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 1)
+  //                                         |     :authority
+  // 8c                                      |   Literal value (len = 12)
+  //                                         |     Huffman encoded:
+  // f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
+  //                                         |     Decoded:
+  //                                         | www.example.com
+  //                                         | -> :authority: www.example.com
+  std::string first =
+      absl::HexStringToBytes("828684418cf1e3c2e5f23a6ba0ab90f4ff");
+  const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first);
+
+  EXPECT_THAT(first_header_set,
+              ElementsAre(
+                  // clang-format off
+      Pair(":method", "GET"),
+      Pair(":scheme", "http"),
+      Pair(":path", "/"),
+      Pair(":authority", "www.example.com")));
+  // clang-format on
+
+  expectEntry(62, 57, ":authority", "www.example.com");
+  EXPECT_EQ(57u, decoder_peer_.current_header_table_size());
+
+  // 82                                      | == Indexed - Add ==
+  //                                         |   idx = 2
+  //                                         | -> :method: GET
+  // 86                                      | == Indexed - Add ==
+  //                                         |   idx = 6
+  //                                         | -> :scheme: http
+  // 84                                      | == Indexed - Add ==
+  //                                         |   idx = 4
+  //                                         | -> :path: /
+  // be                                      | == Indexed - Add ==
+  //                                         |   idx = 62
+  //                                         | -> :authority: www.example.com
+  // 58                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 24)
+  //                                         |     cache-control
+  // 86                                      |   Literal value (len = 8)
+  //                                         |     Huffman encoded:
+  // a8eb 1064 9cbf                          | ...d..
+  //                                         |     Decoded:
+  //                                         | no-cache
+  //                                         | -> cache-control: no-cache
+
+  std::string second = absl::HexStringToBytes("828684be5886a8eb10649cbf");
+  const SpdyHeaderBlock& second_header_set =
+      DecodeBlockExpectingSuccess(second);
+
+  EXPECT_THAT(second_header_set,
+              ElementsAre(
+                  // clang-format off
+      Pair(":method", "GET"),
+      Pair(":scheme", "http"),
+      Pair(":path", "/"),
+      Pair(":authority", "www.example.com"),
+      Pair("cache-control", "no-cache")));
+  // clang-format on
+
+  expectEntry(62, 53, "cache-control", "no-cache");
+  expectEntry(63, 57, ":authority", "www.example.com");
+  EXPECT_EQ(110u, decoder_peer_.current_header_table_size());
+
+  // 82                                      | == Indexed - Add ==
+  //                                         |   idx = 2
+  //                                         | -> :method: GET
+  // 87                                      | == Indexed - Add ==
+  //                                         |   idx = 7
+  //                                         | -> :scheme: https
+  // 85                                      | == Indexed - Add ==
+  //                                         |   idx = 5
+  //                                         | -> :path: /index.html
+  // bf                                      | == Indexed - Add ==
+  //                                         |   idx = 63
+  //                                         | -> :authority: www.example.com
+  // 40                                      | == Literal indexed ==
+  // 88                                      |   Literal name (len = 10)
+  //                                         |     Huffman encoded:
+  // 25a8 49e9 5ba9 7d7f                     | %.I.[.}.
+  //                                         |     Decoded:
+  //                                         | custom-key
+  // 89                                      |   Literal value (len = 12)
+  //                                         |     Huffman encoded:
+  // 25a8 49e9 5bb8 e8b4 bf                  | %.I.[....
+  //                                         |     Decoded:
+  //                                         | custom-value
+  //                                         | -> custom-key: custom-value
+  std::string third = absl::HexStringToBytes(
+      "828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf");
+  const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third);
+
+  EXPECT_THAT(
+      third_header_set,
+      ElementsAre(
+          // clang-format off
+      Pair(":method", "GET"),
+      Pair(":scheme", "https"),
+      Pair(":path", "/index.html"),
+      Pair(":authority", "www.example.com"),
+      Pair("custom-key", "custom-value")));
+  // clang-format on
+
+  expectEntry(62, 54, "custom-key", "custom-value");
+  expectEntry(63, 53, "cache-control", "no-cache");
+  expectEntry(64, 57, ":authority", "www.example.com");
+  EXPECT_EQ(164u, decoder_peer_.current_header_table_size());
+}
+
+// RFC 7541, Section C.6: Response Examples with Huffman Coding
+// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6
+TEST_P(HpackDecoderAdapterTest, SectionC6ResponseHuffmanExamples) {
+  // The example is based on a maximum dynamic table size of 256,
+  // which allows for testing dynamic table evictions.
+  decoder_peer_.set_header_table_size_limit(256);
+
+  // 48                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 8)
+  //                                         |     :status
+  // 82                                      |   Literal value (len = 3)
+  //                                         |     Huffman encoded:
+  // 6402                                    | d.
+  //                                         |     Decoded:
+  //                                         | 302
+  //                                         | -> :status: 302
+  // 58                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 24)
+  //                                         |     cache-control
+  // 85                                      |   Literal value (len = 7)
+  //                                         |     Huffman encoded:
+  // aec3 771a 4b                            | ..w.K
+  //                                         |     Decoded:
+  //                                         | private
+  //                                         | -> cache-control: private
+  // 61                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 33)
+  //                                         |     date
+  // 96                                      |   Literal value (len = 29)
+  //                                         |     Huffman encoded:
+  // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
+  // e082 a62d 1bff                          | ...-..
+  //                                         |     Decoded:
+  //                                         | Mon, 21 Oct 2013 20:13:21
+  //                                         | GMT
+  //                                         | -> date: Mon, 21 Oct 2013
+  //                                         |   20:13:21 GMT
+  // 6e                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 46)
+  //                                         |     location
+  // 91                                      |   Literal value (len = 23)
+  //                                         |     Huffman encoded:
+  // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C
+  // d3                                      | .
+  //                                         |     Decoded:
+  //                                         | https://www.example.com
+  //                                         | -> location: https://www.e
+  //                                         |    xample.com
+
+  std::string first = absl::HexStringToBytes(
+      "488264025885aec3771a4b6196d07abe"
+      "941054d444a8200595040b8166e082a6"
+      "2d1bff6e919d29ad171863c78f0b97c8"
+      "e9ae82ae43d3");
+  const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first);
+
+  EXPECT_THAT(first_header_set,
+              ElementsAre(
+                  // clang-format off
+      Pair(":status", "302"),
+      Pair("cache-control", "private"),
+      Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+      Pair("location", "https://www.example.com")));
+  // clang-format on
+
+  expectEntry(62, 63, "location", "https://www.example.com");
+  expectEntry(63, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT");
+  expectEntry(64, 52, "cache-control", "private");
+  expectEntry(65, 42, ":status", "302");
+  EXPECT_EQ(222u, decoder_peer_.current_header_table_size());
+
+  // 48                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 8)
+  //                                         |     :status
+  // 83                                      |   Literal value (len = 3)
+  //                                         |     Huffman encoded:
+  // 640e ff                                 | d..
+  //                                         |     Decoded:
+  //                                         | 307
+  //                                         | - evict: :status: 302
+  //                                         | -> :status: 307
+  // c1                                      | == Indexed - Add ==
+  //                                         |   idx = 65
+  //                                         | -> cache-control: private
+  // c0                                      | == Indexed - Add ==
+  //                                         |   idx = 64
+  //                                         | -> date: Mon, 21 Oct 2013
+  //                                         |   20:13:21 GMT
+  // bf                                      | == Indexed - Add ==
+  //                                         |   idx = 63
+  //                                         | -> location:
+  //                                         |   https://www.example.com
+  std::string second = absl::HexStringToBytes("4883640effc1c0bf");
+  const SpdyHeaderBlock& second_header_set =
+      DecodeBlockExpectingSuccess(second);
+
+  EXPECT_THAT(second_header_set,
+              ElementsAre(
+                  // clang-format off
+      Pair(":status", "307"),
+      Pair("cache-control", "private"),
+      Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
+      Pair("location", "https://www.example.com")));
+  // clang-format on
+
+  expectEntry(62, 42, ":status", "307");
+  expectEntry(63, 63, "location", "https://www.example.com");
+  expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT");
+  expectEntry(65, 52, "cache-control", "private");
+  EXPECT_EQ(222u, decoder_peer_.current_header_table_size());
+
+  // 88                                      | == Indexed - Add ==
+  //                                         |   idx = 8
+  //                                         | -> :status: 200
+  // c1                                      | == Indexed - Add ==
+  //                                         |   idx = 65
+  //                                         | -> cache-control: private
+  // 61                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 33)
+  //                                         |     date
+  // 96                                      |   Literal value (len = 22)
+  //                                         |     Huffman encoded:
+  // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
+  // e084 a62d 1bff                          | ...-..
+  //                                         |     Decoded:
+  //                                         | Mon, 21 Oct 2013 20:13:22
+  //                                         | GMT
+  //                                         | - evict: cache-control:
+  //                                         |   private
+  //                                         | -> date: Mon, 21 Oct 2013
+  //                                         |   20:13:22 GMT
+  // c0                                      | == Indexed - Add ==
+  //                                         |   idx = 64
+  //                                         | -> location:
+  //                                         |    https://www.example.com
+  // 5a                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 26)
+  //                                         |     content-encoding
+  // 83                                      |   Literal value (len = 3)
+  //                                         |     Huffman encoded:
+  // 9bd9 ab                                 | ...
+  //                                         |     Decoded:
+  //                                         | gzip
+  //                                         | - evict: date: Mon, 21 Oct
+  //                                         |    2013 20:13:21 GMT
+  //                                         | -> content-encoding: gzip
+  // 77                                      | == Literal indexed ==
+  //                                         |   Indexed name (idx = 55)
+  //                                         |     set-cookie
+  // ad                                      |   Literal value (len = 45)
+  //                                         |     Huffman encoded:
+  // 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9`
+  // d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)...
+  // 3160 65c0 03ed 4ee5 b106 3d50 07        | 1`e...N...=P.
+  //                                         |     Decoded:
+  //                                         | foo=ASDJKHQKBZXOQWEOPIUAXQ
+  //                                         | WEOIU; max-age=3600; versi
+  //                                         | on=1
+  //                                         | - evict: location:
+  //                                         |   https://www.example.com
+  //                                         | - evict: :status: 307
+  //                                         | -> set-cookie: foo=ASDJKHQ
+  //                                         |   KBZXOQWEOPIUAXQWEOIU;
+  //                                         |   max-age=3600; version=1
+  std::string third = absl::HexStringToBytes(
+      "88c16196d07abe941054d444a8200595"
+      "040b8166e084a62d1bffc05a839bd9ab"
+      "77ad94e7821dd7f2e6c7b335dfdfcd5b"
+      "3960d5af27087f3672c1ab270fb5291f"
+      "9587316065c003ed4ee5b1063d5007");
+  const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third);
+
+  EXPECT_THAT(third_header_set,
+              ElementsAre(
+                  // clang-format off
+      Pair(":status", "200"),
+      Pair("cache-control", "private"),
+      Pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
+      Pair("location", "https://www.example.com"),
+      Pair("content-encoding", "gzip"),
+      Pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;"
+           " max-age=3600; version=1")));
+  // clang-format on
+
+  expectEntry(62, 98, "set-cookie",
+              "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;"
+              " max-age=3600; version=1");
+  expectEntry(63, 52, "content-encoding", "gzip");
+  expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT");
+  EXPECT_EQ(215u, decoder_peer_.current_header_table_size());
+}
+
+// Regression test: Found that entries with dynamic indexed names and literal
+// values caused "use after free" MSAN failures if the name was evicted as it
+// was being re-used.
+TEST_P(HpackDecoderAdapterTest, ReuseNameOfEvictedEntry) {
+  // Each entry is measured as 32 bytes plus the sum of the lengths of the name
+  // and the value. Set the size big enough for at most one entry, and a fairly
+  // small one at that (31 ASCII characters).
+  decoder_.ApplyHeaderTableSizeSetting(63);
+
+  HpackBlockBuilder hbb;
+  hbb.AppendDynamicTableSizeUpdate(0);
+  hbb.AppendDynamicTableSizeUpdate(63);
+
+  const absl::string_view name("some-name");
+  const absl::string_view value1("some-value");
+  const absl::string_view value2("another-value");
+  const absl::string_view value3("yet-another-value");
+
+  // Add an entry that will become the first in the dynamic table, entry 62.
+  hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false,
+                                name, false, value1);
+
+  // Confirm that entry has been added by re-using it.
+  hbb.AppendIndexedHeader(62);
+
+  // Add another entry referring to the name of the first. This will evict the
+  // first.
+  hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62,
+                                     false, value2);
+
+  // Confirm that entry has been added by re-using it.
+  hbb.AppendIndexedHeader(62);
+
+  // Add another entry referring to the name of the second. This will evict the
+  // second.
+  hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62,
+                                     false, value3);
+
+  // Confirm that entry has been added by re-using it.
+  hbb.AppendIndexedHeader(62);
+
+  // Can't have DecodeHeaderBlock do the default check for size of the decoded
+  // data because SpdyHeaderBlock will join multiple headers with the same
+  // name into a single entry, thus we won't see repeated occurrences of the
+  // name, instead seeing separators between values.
+  EXPECT_TRUE(DecodeHeaderBlock(hbb.buffer(), kNoCheckDecodedSize));
+
+  SpdyHeaderBlock expected_header_set;
+  expected_header_set.AppendValueOrAddHeader(name, value1);
+  expected_header_set.AppendValueOrAddHeader(name, value1);
+  expected_header_set.AppendValueOrAddHeader(name, value2);
+  expected_header_set.AppendValueOrAddHeader(name, value2);
+  expected_header_set.AppendValueOrAddHeader(name, value3);
+  expected_header_set.AppendValueOrAddHeader(name, value3);
+
+  // SpdyHeaderBlock stores these 6 strings as '\0' separated values.
+  // Make sure that is what happened.
+  std::string joined_values = expected_header_set[name].as_string();
+  EXPECT_EQ(joined_values.size(),
+            2 * value1.size() + 2 * value2.size() + 2 * value3.size() + 5);
+
+  EXPECT_EQ(expected_header_set, decoded_block());
+
+  if (start_choice_ == START_WITH_HANDLER) {
+    EXPECT_EQ(handler_.uncompressed_header_bytes(),
+              6 * name.size() + 2 * value1.size() + 2 * value2.size() +
+                  2 * value3.size());
+  }
+}
+
+// Regression test for https://crbug.com/747395.
+TEST_P(HpackDecoderAdapterTest, Cookies) {
+  SpdyHeaderBlock expected_header_set;
+  expected_header_set["cookie"] = "foo; bar";
+
+  EXPECT_TRUE(DecodeHeaderBlock(absl::HexStringToBytes("608294e76003626172")));
+  EXPECT_EQ(expected_header_set, decoded_block());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_encoder.cc b/quiche/spdy/core/hpack/hpack_encoder.cc
new file mode 100644
index 0000000..7bfb8a4
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_encoder.cc
@@ -0,0 +1,374 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+#include "quiche/spdy/core/hpack/hpack_output_stream.h"
+
+namespace spdy {
+
+class HpackEncoder::RepresentationIterator {
+ public:
+  // |pseudo_headers| and |regular_headers| must outlive the iterator.
+  RepresentationIterator(const Representations& pseudo_headers,
+                         const Representations& regular_headers)
+      : pseudo_begin_(pseudo_headers.begin()),
+        pseudo_end_(pseudo_headers.end()),
+        regular_begin_(regular_headers.begin()),
+        regular_end_(regular_headers.end()) {}
+
+  // |headers| must outlive the iterator.
+  explicit RepresentationIterator(const Representations& headers)
+      : pseudo_begin_(headers.begin()),
+        pseudo_end_(headers.end()),
+        regular_begin_(headers.end()),
+        regular_end_(headers.end()) {}
+
+  bool HasNext() {
+    return pseudo_begin_ != pseudo_end_ || regular_begin_ != regular_end_;
+  }
+
+  const Representation Next() {
+    if (pseudo_begin_ != pseudo_end_) {
+      return *pseudo_begin_++;
+    } else {
+      return *regular_begin_++;
+    }
+  }
+
+ private:
+  Representations::const_iterator pseudo_begin_;
+  Representations::const_iterator pseudo_end_;
+  Representations::const_iterator regular_begin_;
+  Representations::const_iterator regular_end_;
+};
+
+namespace {
+
+// The default header listener.
+void NoOpListener(absl::string_view /*name*/, absl::string_view /*value*/) {}
+
+// The default HPACK indexing policy.
+bool DefaultPolicy(absl::string_view name, absl::string_view /* value */) {
+  if (name.empty()) {
+    return false;
+  }
+  // :authority is always present and rarely changes, and has moderate
+  // length, therefore it makes a lot of sense to index (insert in the
+  // dynamic table).
+  if (name[0] == kPseudoHeaderPrefix) {
+    return name == ":authority";
+  }
+  return true;
+}
+
+}  // namespace
+
+HpackEncoder::HpackEncoder()
+    : output_stream_(),
+      min_table_size_setting_received_(std::numeric_limits<size_t>::max()),
+      listener_(NoOpListener),
+      should_index_(DefaultPolicy),
+      enable_compression_(true),
+      should_emit_table_size_(false) {}
+
+HpackEncoder::~HpackEncoder() = default;
+
+std::string HpackEncoder::EncodeHeaderBlock(const SpdyHeaderBlock& header_set) {
+  // Separate header set into pseudo-headers and regular headers.
+  Representations pseudo_headers;
+  Representations regular_headers;
+  bool found_cookie = false;
+  for (const auto& header : header_set) {
+    if (!found_cookie && header.first == "cookie") {
+      // Note that there can only be one "cookie" header, because header_set is
+      // a map.
+      found_cookie = true;
+      CookieToCrumbs(header, &regular_headers);
+    } else if (!header.first.empty() &&
+               header.first[0] == kPseudoHeaderPrefix) {
+      DecomposeRepresentation(header, &pseudo_headers);
+    } else {
+      DecomposeRepresentation(header, &regular_headers);
+    }
+  }
+
+  RepresentationIterator iter(pseudo_headers, regular_headers);
+  return EncodeRepresentations(&iter);
+}
+
+void HpackEncoder::ApplyHeaderTableSizeSetting(size_t size_setting) {
+  if (size_setting == header_table_.settings_size_bound()) {
+    return;
+  }
+  if (size_setting < header_table_.settings_size_bound()) {
+    min_table_size_setting_received_ =
+        std::min(size_setting, min_table_size_setting_received_);
+  }
+  header_table_.SetSettingsHeaderTableSize(size_setting);
+  should_emit_table_size_ = true;
+}
+
+std::string HpackEncoder::EncodeRepresentations(RepresentationIterator* iter) {
+  MaybeEmitTableSize();
+  while (iter->HasNext()) {
+    const auto header = iter->Next();
+    listener_(header.first, header.second);
+    if (enable_compression_) {
+      size_t index =
+          header_table_.GetByNameAndValue(header.first, header.second);
+      if (index != kHpackEntryNotFound) {
+        EmitIndex(index);
+      } else if (should_index_(header.first, header.second)) {
+        EmitIndexedLiteral(header);
+      } else {
+        EmitNonIndexedLiteral(header, enable_compression_);
+      }
+    } else {
+      EmitNonIndexedLiteral(header, enable_compression_);
+    }
+  }
+
+  return output_stream_.TakeString();
+}
+
+void HpackEncoder::EmitIndex(size_t index) {
+  QUICHE_DVLOG(2) << "Emitting index " << index;
+  output_stream_.AppendPrefix(kIndexedOpcode);
+  output_stream_.AppendUint32(index);
+}
+
+void HpackEncoder::EmitIndexedLiteral(const Representation& representation) {
+  QUICHE_DVLOG(2) << "Emitting indexed literal: (" << representation.first
+                  << ", " << representation.second << ")";
+  output_stream_.AppendPrefix(kLiteralIncrementalIndexOpcode);
+  EmitLiteral(representation);
+  header_table_.TryAddEntry(representation.first, representation.second);
+}
+
+void HpackEncoder::EmitNonIndexedLiteral(const Representation& representation,
+                                         bool enable_compression) {
+  QUICHE_DVLOG(2) << "Emitting nonindexed literal: (" << representation.first
+                  << ", " << representation.second << ")";
+  output_stream_.AppendPrefix(kLiteralNoIndexOpcode);
+  size_t name_index = header_table_.GetByName(representation.first);
+  if (enable_compression && name_index != kHpackEntryNotFound) {
+    output_stream_.AppendUint32(name_index);
+  } else {
+    output_stream_.AppendUint32(0);
+    EmitString(representation.first);
+  }
+  EmitString(representation.second);
+}
+
+void HpackEncoder::EmitLiteral(const Representation& representation) {
+  size_t name_index = header_table_.GetByName(representation.first);
+  if (name_index != kHpackEntryNotFound) {
+    output_stream_.AppendUint32(name_index);
+  } else {
+    output_stream_.AppendUint32(0);
+    EmitString(representation.first);
+  }
+  EmitString(representation.second);
+}
+
+void HpackEncoder::EmitString(absl::string_view str) {
+  size_t encoded_size =
+      enable_compression_ ? http2::HuffmanSize(str) : str.size();
+  if (encoded_size < str.size()) {
+    QUICHE_DVLOG(2) << "Emitted Huffman-encoded string of length "
+                    << encoded_size;
+    output_stream_.AppendPrefix(kStringLiteralHuffmanEncoded);
+    output_stream_.AppendUint32(encoded_size);
+    http2::HuffmanEncodeFast(str, encoded_size, output_stream_.MutableString());
+  } else {
+    QUICHE_DVLOG(2) << "Emitted literal string of length " << str.size();
+    output_stream_.AppendPrefix(kStringLiteralIdentityEncoded);
+    output_stream_.AppendUint32(str.size());
+    output_stream_.AppendBytes(str);
+  }
+}
+
+void HpackEncoder::MaybeEmitTableSize() {
+  if (!should_emit_table_size_) {
+    return;
+  }
+  const size_t current_size = CurrentHeaderTableSizeSetting();
+  QUICHE_DVLOG(1) << "MaybeEmitTableSize current_size=" << current_size;
+  QUICHE_DVLOG(1) << "MaybeEmitTableSize min_table_size_setting_received_="
+                  << min_table_size_setting_received_;
+  if (min_table_size_setting_received_ < current_size) {
+    output_stream_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    output_stream_.AppendUint32(min_table_size_setting_received_);
+  }
+  output_stream_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+  output_stream_.AppendUint32(current_size);
+  min_table_size_setting_received_ = std::numeric_limits<size_t>::max();
+  should_emit_table_size_ = false;
+}
+
+// static
+void HpackEncoder::CookieToCrumbs(const Representation& cookie,
+                                  Representations* out) {
+  // See Section 8.1.2.5. "Compressing the Cookie Header Field" in the HTTP/2
+  // specification at https://tools.ietf.org/html/draft-ietf-httpbis-http2-14.
+  // Cookie values are split into individually-encoded HPACK representations.
+  absl::string_view cookie_value = cookie.second;
+  // Consume leading and trailing whitespace if present.
+  absl::string_view::size_type first = cookie_value.find_first_not_of(" \t");
+  absl::string_view::size_type last = cookie_value.find_last_not_of(" \t");
+  if (first == absl::string_view::npos) {
+    cookie_value = absl::string_view();
+  } else {
+    cookie_value = cookie_value.substr(first, (last - first) + 1);
+  }
+  for (size_t pos = 0;;) {
+    size_t end = cookie_value.find(';', pos);
+
+    if (end == absl::string_view::npos) {
+      out->push_back(std::make_pair(cookie.first, cookie_value.substr(pos)));
+      break;
+    }
+    out->push_back(
+        std::make_pair(cookie.first, cookie_value.substr(pos, end - pos)));
+
+    // Consume next space if present.
+    pos = end + 1;
+    if (pos != cookie_value.size() && cookie_value[pos] == ' ') {
+      pos++;
+    }
+  }
+}
+
+// static
+void HpackEncoder::DecomposeRepresentation(const Representation& header_field,
+                                           Representations* out) {
+  size_t pos = 0;
+  size_t end = 0;
+  while (end != absl::string_view::npos) {
+    end = header_field.second.find('\0', pos);
+    out->push_back(std::make_pair(
+        header_field.first,
+        header_field.second.substr(
+            pos, end == absl::string_view::npos ? end : end - pos)));
+    pos = end + 1;
+  }
+}
+
+// Iteratively encodes a SpdyHeaderBlock.
+class HpackEncoder::Encoderator : public ProgressiveEncoder {
+ public:
+  Encoderator(const SpdyHeaderBlock& header_set, HpackEncoder* encoder);
+  Encoderator(const Representations& representations, HpackEncoder* encoder);
+
+  // Encoderator is neither copyable nor movable.
+  Encoderator(const Encoderator&) = delete;
+  Encoderator& operator=(const Encoderator&) = delete;
+
+  // Returns true iff more remains to encode.
+  bool HasNext() const override { return has_next_; }
+
+  // Encodes and returns up to max_encoded_bytes of the current header block.
+  std::string Next(size_t max_encoded_bytes) override;
+
+ private:
+  HpackEncoder* encoder_;
+  std::unique_ptr<RepresentationIterator> header_it_;
+  Representations pseudo_headers_;
+  Representations regular_headers_;
+  bool has_next_;
+};
+
+HpackEncoder::Encoderator::Encoderator(const SpdyHeaderBlock& header_set,
+                                       HpackEncoder* encoder)
+    : encoder_(encoder), has_next_(true) {
+  // Separate header set into pseudo-headers and regular headers.
+  bool found_cookie = false;
+  for (const auto& header : header_set) {
+    if (!found_cookie && header.first == "cookie") {
+      // Note that there can only be one "cookie" header, because header_set
+      // is a map.
+      found_cookie = true;
+      CookieToCrumbs(header, &regular_headers_);
+    } else if (!header.first.empty() &&
+               header.first[0] == kPseudoHeaderPrefix) {
+      DecomposeRepresentation(header, &pseudo_headers_);
+    } else {
+      DecomposeRepresentation(header, &regular_headers_);
+    }
+  }
+  header_it_ = std::make_unique<RepresentationIterator>(pseudo_headers_,
+                                                        regular_headers_);
+
+  encoder_->MaybeEmitTableSize();
+}
+
+HpackEncoder::Encoderator::Encoderator(const Representations& representations,
+                                       HpackEncoder* encoder)
+    : encoder_(encoder), has_next_(true) {
+  for (const auto& header : representations) {
+    if (header.first == "cookie") {
+      CookieToCrumbs(header, &regular_headers_);
+    } else if (!header.first.empty() &&
+               header.first[0] == kPseudoHeaderPrefix) {
+      pseudo_headers_.push_back(header);
+    } else {
+      regular_headers_.push_back(header);
+    }
+  }
+  header_it_ = std::make_unique<RepresentationIterator>(pseudo_headers_,
+                                                        regular_headers_);
+
+  encoder_->MaybeEmitTableSize();
+}
+
+std::string HpackEncoder::Encoderator::Next(size_t max_encoded_bytes) {
+  QUICHE_BUG_IF(spdy_bug_61_1, !has_next_)
+      << "Encoderator::Next called with nothing left to encode.";
+  const bool enable_compression = encoder_->enable_compression_;
+
+  // Encode up to max_encoded_bytes of headers.
+  while (header_it_->HasNext() &&
+         encoder_->output_stream_.size() <= max_encoded_bytes) {
+    const Representation header = header_it_->Next();
+    encoder_->listener_(header.first, header.second);
+    if (enable_compression) {
+      size_t index = encoder_->header_table_.GetByNameAndValue(header.first,
+                                                               header.second);
+      if (index != kHpackEntryNotFound) {
+        encoder_->EmitIndex(index);
+      } else if (encoder_->should_index_(header.first, header.second)) {
+        encoder_->EmitIndexedLiteral(header);
+      } else {
+        encoder_->EmitNonIndexedLiteral(header, enable_compression);
+      }
+    } else {
+      encoder_->EmitNonIndexedLiteral(header, enable_compression);
+    }
+  }
+
+  has_next_ = encoder_->output_stream_.size() > max_encoded_bytes;
+  return encoder_->output_stream_.BoundedTakeString(max_encoded_bytes);
+}
+
+std::unique_ptr<HpackEncoder::ProgressiveEncoder> HpackEncoder::EncodeHeaderSet(
+    const SpdyHeaderBlock& header_set) {
+  return std::make_unique<Encoderator>(header_set, this);
+}
+
+std::unique_ptr<HpackEncoder::ProgressiveEncoder>
+HpackEncoder::EncodeRepresentations(const Representations& representations) {
+  return std::make_unique<Encoderator>(representations, this);
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_encoder.h b/quiche/spdy/core/hpack/hpack_encoder.h
new file mode 100644
index 0000000..4974e19
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_encoder.h
@@ -0,0 +1,146 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_ENCODER_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_ENCODER_H_
+
+#include <stddef.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+#include "quiche/spdy/core/hpack/hpack_output_stream.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+// An HpackEncoder encodes header sets as outlined in
+// http://tools.ietf.org/html/rfc7541.
+
+namespace spdy {
+
+namespace test {
+class HpackEncoderPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE HpackEncoder {
+ public:
+  using Representation = std::pair<absl::string_view, absl::string_view>;
+  using Representations = std::vector<Representation>;
+
+  // Callers may provide a HeaderListener to be informed of header name-value
+  // pairs processed by this encoder.
+  using HeaderListener =
+      std::function<void(absl::string_view, absl::string_view)>;
+
+  // An indexing policy should return true if the provided header name-value
+  // pair should be inserted into the HPACK dynamic table.
+  using IndexingPolicy =
+      std::function<bool(absl::string_view, absl::string_view)>;
+
+  HpackEncoder();
+  HpackEncoder(const HpackEncoder&) = delete;
+  HpackEncoder& operator=(const HpackEncoder&) = delete;
+  ~HpackEncoder();
+
+  // Encodes and returns the given header set as a string.
+  std::string EncodeHeaderBlock(const SpdyHeaderBlock& header_set);
+
+  class QUICHE_EXPORT_PRIVATE ProgressiveEncoder {
+   public:
+    virtual ~ProgressiveEncoder() {}
+
+    // Returns true iff more remains to encode.
+    virtual bool HasNext() const = 0;
+
+    // Encodes and returns up to max_encoded_bytes of the current header block.
+    virtual std::string Next(size_t max_encoded_bytes) = 0;
+  };
+
+  // Returns a ProgressiveEncoder which must be outlived by both the given
+  // SpdyHeaderBlock and this object.
+  std::unique_ptr<ProgressiveEncoder> EncodeHeaderSet(
+      const SpdyHeaderBlock& header_set);
+  // Returns a ProgressiveEncoder which must be outlived by this HpackEncoder.
+  // The encoder will not attempt to split any \0-delimited values in
+  // |representations|. If such splitting is desired, it must be performed by
+  // the caller when constructing the list of representations.
+  std::unique_ptr<ProgressiveEncoder> EncodeRepresentations(
+      const Representations& representations);
+
+  // Called upon a change to SETTINGS_HEADER_TABLE_SIZE. Specifically, this
+  // is to be called after receiving (and sending an acknowledgement for) a
+  // SETTINGS_HEADER_TABLE_SIZE update from the remote decoding endpoint.
+  void ApplyHeaderTableSizeSetting(size_t size_setting);
+
+  // TODO(birenroy): Rename this GetDynamicTableCapacity().
+  size_t CurrentHeaderTableSizeSetting() const {
+    return header_table_.settings_size_bound();
+  }
+
+  // This HpackEncoder will use |policy| to determine whether to insert header
+  // name-value pairs into the dynamic table.
+  void SetIndexingPolicy(IndexingPolicy policy) { should_index_ = policy; }
+
+  // |listener| will be invoked for each header name-value pair processed by
+  // this encoder.
+  void SetHeaderListener(HeaderListener listener) { listener_ = listener; }
+
+  void DisableCompression() { enable_compression_ = false; }
+
+  // Returns the current dynamic table size, including the 32 bytes per entry
+  // overhead mentioned in RFC 7541 section 4.1.
+  size_t GetDynamicTableSize() const { return header_table_.size(); }
+
+ private:
+  friend class test::HpackEncoderPeer;
+
+  class RepresentationIterator;
+  class Encoderator;
+
+  // Encodes a sequence of header name-value pairs as a single header block.
+  std::string EncodeRepresentations(RepresentationIterator* iter);
+
+  // Emits a static/dynamic indexed representation (Section 7.1).
+  void EmitIndex(size_t index);
+
+  // Emits a literal representation (Section 7.2).
+  void EmitIndexedLiteral(const Representation& representation);
+  void EmitNonIndexedLiteral(const Representation& representation,
+                             bool enable_compression);
+  void EmitLiteral(const Representation& representation);
+
+  // Emits a Huffman or identity string (whichever is smaller).
+  void EmitString(absl::string_view str);
+
+  // Emits the current dynamic table size if the table size was recently
+  // updated and we have not yet emitted it (Section 6.3).
+  void MaybeEmitTableSize();
+
+  // Crumbles a cookie header into ";" delimited crumbs.
+  static void CookieToCrumbs(const Representation& cookie,
+                             Representations* crumbs_out);
+
+  // Crumbles other header field values at \0 delimiters.
+  static void DecomposeRepresentation(const Representation& header_field,
+                                      Representations* out);
+
+  HpackHeaderTable header_table_;
+  HpackOutputStream output_stream_;
+
+  size_t min_table_size_setting_received_;
+  HeaderListener listener_;
+  IndexingPolicy should_index_;
+  bool enable_compression_;
+  bool should_emit_table_size_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_ENCODER_H_
diff --git a/quiche/spdy/core/hpack/hpack_encoder_test.cc b/quiche/spdy/core/hpack/hpack_encoder_test.cc
new file mode 100644
index 0000000..c0b9339
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_encoder_test.cc
@@ -0,0 +1,756 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+
+#include <cstdint>
+#include <utility>
+
+#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+#include "quiche/spdy/core/spdy_simple_arena.h"
+
+namespace spdy {
+
+namespace test {
+
+class HpackHeaderTablePeer {
+ public:
+  explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {}
+
+  const HpackEntry* GetFirstStaticEntry() const {
+    return &table_->static_entries_.front();
+  }
+
+  HpackHeaderTable::DynamicEntryTable* dynamic_entries() {
+    return &table_->dynamic_entries_;
+  }
+
+ private:
+  HpackHeaderTable* table_;
+};
+
+class HpackEncoderPeer {
+ public:
+  typedef HpackEncoder::Representation Representation;
+  typedef HpackEncoder::Representations Representations;
+
+  explicit HpackEncoderPeer(HpackEncoder* encoder) : encoder_(encoder) {}
+
+  bool compression_enabled() const { return encoder_->enable_compression_; }
+  HpackHeaderTable* table() { return &encoder_->header_table_; }
+  HpackHeaderTablePeer table_peer() { return HpackHeaderTablePeer(table()); }
+  void EmitString(absl::string_view str) { encoder_->EmitString(str); }
+  void TakeString(std::string* out) {
+    *out = encoder_->output_stream_.TakeString();
+  }
+  static void CookieToCrumbs(absl::string_view cookie,
+                             std::vector<absl::string_view>* out) {
+    Representations tmp;
+    HpackEncoder::CookieToCrumbs(std::make_pair("", cookie), &tmp);
+
+    out->clear();
+    for (size_t i = 0; i != tmp.size(); ++i) {
+      out->push_back(tmp[i].second);
+    }
+  }
+  static void DecomposeRepresentation(absl::string_view value,
+                                      std::vector<absl::string_view>* out) {
+    Representations tmp;
+    HpackEncoder::DecomposeRepresentation(std::make_pair("foobar", value),
+                                          &tmp);
+
+    out->clear();
+    for (size_t i = 0; i != tmp.size(); ++i) {
+      out->push_back(tmp[i].second);
+    }
+  }
+
+  // TODO(dahollings): Remove or clean up these methods when deprecating
+  // non-incremental encoding path.
+  static std::string EncodeHeaderBlock(HpackEncoder* encoder,
+                                       const SpdyHeaderBlock& header_set) {
+    return encoder->EncodeHeaderBlock(header_set);
+  }
+
+  static bool EncodeIncremental(HpackEncoder* encoder,
+                                const SpdyHeaderBlock& header_set,
+                                std::string* output) {
+    std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator =
+        encoder->EncodeHeaderSet(header_set);
+    http2::test::Http2Random random;
+    std::string output_buffer = encoderator->Next(random.UniformInRange(0, 16));
+    while (encoderator->HasNext()) {
+      std::string second_buffer =
+          encoderator->Next(random.UniformInRange(0, 16));
+      output_buffer.append(second_buffer);
+    }
+    *output = std::move(output_buffer);
+    return true;
+  }
+
+  static bool EncodeRepresentations(HpackEncoder* encoder,
+                                    const Representations& representations,
+                                    std::string* output) {
+    std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator =
+        encoder->EncodeRepresentations(representations);
+    http2::test::Http2Random random;
+    std::string output_buffer = encoderator->Next(random.UniformInRange(0, 16));
+    while (encoderator->HasNext()) {
+      std::string second_buffer =
+          encoderator->Next(random.UniformInRange(0, 16));
+      output_buffer.append(second_buffer);
+    }
+    *output = std::move(output_buffer);
+    return true;
+  }
+
+ private:
+  HpackEncoder* encoder_;
+};
+
+}  // namespace test
+
+namespace {
+
+using testing::ElementsAre;
+using testing::Pair;
+
+const size_t kStaticEntryIndex = 1;
+
+enum EncodeStrategy {
+  kDefault,
+  kIncremental,
+  kRepresentations,
+};
+
+class HpackEncoderTest : public QuicheTestWithParam<EncodeStrategy> {
+ protected:
+  typedef test::HpackEncoderPeer::Representations Representations;
+
+  HpackEncoderTest()
+      : peer_(&encoder_),
+        static_(peer_.table_peer().GetFirstStaticEntry()),
+        dynamic_table_insertions_(0),
+        headers_storage_(1024 /* block size */),
+        strategy_(GetParam()) {}
+
+  void SetUp() override {
+    // Populate dynamic entries into the table fixture. For simplicity each
+    // entry has name.size() + value.size() == 10.
+    key_1_ = peer_.table()->TryAddEntry("key1", "value1");
+    key_1_index_ = dynamic_table_insertions_++;
+    key_2_ = peer_.table()->TryAddEntry("key2", "value2");
+    key_2_index_ = dynamic_table_insertions_++;
+    cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb");
+    cookie_a_index_ = dynamic_table_insertions_++;
+    cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd");
+    cookie_c_index_ = dynamic_table_insertions_++;
+
+    // No further insertions may occur without evictions.
+    peer_.table()->SetMaxSize(peer_.table()->size());
+    QUICHE_CHECK_EQ(kInitialDynamicTableSize, peer_.table()->size());
+  }
+
+  void SaveHeaders(absl::string_view name, absl::string_view value) {
+    absl::string_view n(headers_storage_.Memdup(name.data(), name.size()),
+                        name.size());
+    absl::string_view v(headers_storage_.Memdup(value.data(), value.size()),
+                        value.size());
+    headers_observed_.push_back(std::make_pair(n, v));
+  }
+
+  void ExpectIndex(size_t index) {
+    expected_.AppendPrefix(kIndexedOpcode);
+    expected_.AppendUint32(index);
+  }
+  void ExpectIndexedLiteral(size_t key_index, absl::string_view value) {
+    expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
+    expected_.AppendUint32(key_index);
+    ExpectString(&expected_, value);
+  }
+  void ExpectIndexedLiteral(absl::string_view name, absl::string_view value) {
+    expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
+    expected_.AppendUint32(0);
+    ExpectString(&expected_, name);
+    ExpectString(&expected_, value);
+  }
+  void ExpectNonIndexedLiteral(absl::string_view name,
+                               absl::string_view value) {
+    expected_.AppendPrefix(kLiteralNoIndexOpcode);
+    expected_.AppendUint32(0);
+    ExpectString(&expected_, name);
+    ExpectString(&expected_, value);
+  }
+  void ExpectNonIndexedLiteralWithNameIndex(size_t key_index,
+                                            absl::string_view value) {
+    expected_.AppendPrefix(kLiteralNoIndexOpcode);
+    expected_.AppendUint32(key_index);
+    ExpectString(&expected_, value);
+  }
+  void ExpectString(HpackOutputStream* stream, absl::string_view str) {
+    size_t encoded_size =
+        peer_.compression_enabled() ? http2::HuffmanSize(str) : str.size();
+    if (encoded_size < str.size()) {
+      expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
+      expected_.AppendUint32(encoded_size);
+      http2::HuffmanEncodeFast(str, encoded_size, stream->MutableString());
+    } else {
+      expected_.AppendPrefix(kStringLiteralIdentityEncoded);
+      expected_.AppendUint32(str.size());
+      expected_.AppendBytes(str);
+    }
+  }
+  void ExpectHeaderTableSizeUpdate(uint32_t size) {
+    expected_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
+    expected_.AppendUint32(size);
+  }
+  Representations MakeRepresentations(const SpdyHeaderBlock& header_set) {
+    Representations r;
+    for (const auto& header : header_set) {
+      r.push_back(header);
+    }
+    return r;
+  }
+  void CompareWithExpectedEncoding(const SpdyHeaderBlock& header_set) {
+    std::string actual_out;
+    std::string expected_out = expected_.TakeString();
+    switch (strategy_) {
+      case kDefault:
+        actual_out =
+            test::HpackEncoderPeer::EncodeHeaderBlock(&encoder_, header_set);
+        break;
+      case kIncremental:
+        EXPECT_TRUE(test::HpackEncoderPeer::EncodeIncremental(
+            &encoder_, header_set, &actual_out));
+        break;
+      case kRepresentations:
+        EXPECT_TRUE(test::HpackEncoderPeer::EncodeRepresentations(
+            &encoder_, MakeRepresentations(header_set), &actual_out));
+        break;
+    }
+    EXPECT_EQ(expected_out, actual_out);
+  }
+  void CompareWithExpectedEncoding(const Representations& representations) {
+    std::string actual_out;
+    std::string expected_out = expected_.TakeString();
+    EXPECT_TRUE(test::HpackEncoderPeer::EncodeRepresentations(
+        &encoder_, representations, &actual_out));
+    EXPECT_EQ(expected_out, actual_out);
+  }
+  // Converts the index of a dynamic table entry to the HPACK index.
+  // In these test, dynamic table entries are indexed sequentially, starting
+  // with 0.  The HPACK indexing scheme is defined at
+  // https://httpwg.org/specs/rfc7541.html#index.address.space.
+  size_t DynamicIndexToWireIndex(size_t index) {
+    return dynamic_table_insertions_ - index + kStaticTableSize;
+  }
+
+  HpackEncoder encoder_;
+  test::HpackEncoderPeer peer_;
+
+  // Calculated based on the names and values inserted in SetUp(), above.
+  const size_t kInitialDynamicTableSize = 4 * (10 + 32);
+
+  const HpackEntry* static_;
+  const HpackEntry* key_1_;
+  const HpackEntry* key_2_;
+  const HpackEntry* cookie_a_;
+  const HpackEntry* cookie_c_;
+  size_t key_1_index_;
+  size_t key_2_index_;
+  size_t cookie_a_index_;
+  size_t cookie_c_index_;
+  size_t dynamic_table_insertions_;
+
+  SpdySimpleArena headers_storage_;
+  std::vector<std::pair<absl::string_view, absl::string_view>>
+      headers_observed_;
+
+  HpackOutputStream expected_;
+  const EncodeStrategy strategy_;
+};
+
+using HpackEncoderTestWithDefaultStrategy = HpackEncoderTest;
+
+INSTANTIATE_TEST_SUITE_P(HpackEncoderTests,
+                         HpackEncoderTestWithDefaultStrategy,
+                         ::testing::Values(kDefault));
+
+TEST_P(HpackEncoderTestWithDefaultStrategy, EncodeRepresentations) {
+  EXPECT_EQ(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
+  encoder_.SetHeaderListener(
+      [this](absl::string_view name, absl::string_view value) {
+        this->SaveHeaders(name, value);
+      });
+  const std::vector<std::pair<absl::string_view, absl::string_view>>
+      header_list = {{"cookie", "val1; val2;val3"},
+                     {":path", "/home"},
+                     {"accept", "text/html, text/plain,application/xml"},
+                     {"cookie", "val4"},
+                     {"withnul", absl::string_view("one\0two", 7)}};
+  ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
+                                       "/home");
+  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val1");
+  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val2");
+  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val3");
+  ExpectIndexedLiteral(peer_.table()->GetByName("accept"),
+                       "text/html, text/plain,application/xml");
+  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val4");
+  ExpectIndexedLiteral("withnul", absl::string_view("one\0two", 7));
+
+  CompareWithExpectedEncoding(header_list);
+  EXPECT_THAT(
+      headers_observed_,
+      ElementsAre(Pair(":path", "/home"), Pair("cookie", "val1"),
+                  Pair("cookie", "val2"), Pair("cookie", "val3"),
+                  Pair("accept", "text/html, text/plain,application/xml"),
+                  Pair("cookie", "val4"),
+                  Pair("withnul", absl::string_view("one\0two", 7))));
+  // Insertions and evictions have happened over the course of the test.
+  EXPECT_GE(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
+}
+
+TEST_P(HpackEncoderTestWithDefaultStrategy, DynamicTableGrows) {
+  EXPECT_EQ(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
+  peer_.table()->SetMaxSize(4096);
+  encoder_.SetHeaderListener(
+      [this](absl::string_view name, absl::string_view value) {
+        this->SaveHeaders(name, value);
+      });
+  const std::vector<std::pair<absl::string_view, absl::string_view>>
+      header_list = {{"cookie", "val1; val2;val3"},
+                     {":path", "/home"},
+                     {"accept", "text/html, text/plain,application/xml"},
+                     {"cookie", "val4"},
+                     {"withnul", absl::string_view("one\0two", 7)}};
+  std::string out;
+  EXPECT_TRUE(test::HpackEncoderPeer::EncodeRepresentations(&encoder_,
+                                                            header_list, &out));
+
+  EXPECT_FALSE(out.empty());
+  // Insertions have happened over the course of the test.
+  EXPECT_GT(encoder_.GetDynamicTableSize(), kInitialDynamicTableSize);
+}
+
+INSTANTIATE_TEST_SUITE_P(HpackEncoderTests,
+                         HpackEncoderTest,
+                         ::testing::Values(kDefault,
+                                           kIncremental,
+                                           kRepresentations));
+
+TEST_P(HpackEncoderTest, SingleDynamicIndex) {
+  encoder_.SetHeaderListener(
+      [this](absl::string_view name, absl::string_view value) {
+        this->SaveHeaders(name, value);
+      });
+
+  ExpectIndex(DynamicIndexToWireIndex(key_2_index_));
+
+  SpdyHeaderBlock headers;
+  headers[key_2_->name()] = key_2_->value();
+  CompareWithExpectedEncoding(headers);
+  EXPECT_THAT(headers_observed_,
+              ElementsAre(Pair(key_2_->name(), key_2_->value())));
+}
+
+TEST_P(HpackEncoderTest, SingleStaticIndex) {
+  ExpectIndex(kStaticEntryIndex);
+
+  SpdyHeaderBlock headers;
+  headers[static_->name()] = static_->value();
+  CompareWithExpectedEncoding(headers);
+}
+
+TEST_P(HpackEncoderTest, SingleStaticIndexTooLarge) {
+  peer_.table()->SetMaxSize(1);  // Also evicts all fixtures.
+  ExpectIndex(kStaticEntryIndex);
+
+  SpdyHeaderBlock headers;
+  headers[static_->name()] = static_->value();
+  CompareWithExpectedEncoding(headers);
+
+  EXPECT_EQ(0u, peer_.table_peer().dynamic_entries()->size());
+}
+
+TEST_P(HpackEncoderTest, SingleLiteralWithIndexName) {
+  ExpectIndexedLiteral(DynamicIndexToWireIndex(key_2_index_), "value3");
+
+  SpdyHeaderBlock headers;
+  headers[key_2_->name()] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  // A new entry was inserted and added to the reference set.
+  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+  EXPECT_EQ(new_entry->name(), key_2_->name());
+  EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_P(HpackEncoderTest, SingleLiteralWithLiteralName) {
+  ExpectIndexedLiteral("key3", "value3");
+
+  SpdyHeaderBlock headers;
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+  EXPECT_EQ(new_entry->name(), "key3");
+  EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_P(HpackEncoderTest, SingleLiteralTooLarge) {
+  peer_.table()->SetMaxSize(1);  // Also evicts all fixtures.
+
+  ExpectIndexedLiteral("key3", "value3");
+
+  // A header overflowing the header table is still emitted.
+  // The header table is empty.
+  SpdyHeaderBlock headers;
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  EXPECT_EQ(0u, peer_.table_peer().dynamic_entries()->size());
+}
+
+TEST_P(HpackEncoderTest, EmitThanEvict) {
+  // |key_1_| is toggled and placed into the reference set,
+  // and then immediately evicted by "key3".
+  ExpectIndex(DynamicIndexToWireIndex(key_1_index_));
+  ExpectIndexedLiteral("key3", "value3");
+
+  SpdyHeaderBlock headers;
+  headers[key_1_->name()] = key_1_->value();
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+}
+
+TEST_P(HpackEncoderTest, CookieHeaderIsCrumbled) {
+  ExpectIndex(DynamicIndexToWireIndex(cookie_a_index_));
+  ExpectIndex(DynamicIndexToWireIndex(cookie_c_index_));
+  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");
+
+  SpdyHeaderBlock headers;
+  headers["cookie"] = "a=bb; c=dd; e=ff";
+  CompareWithExpectedEncoding(headers);
+}
+
+TEST_P(HpackEncoderTest, MultiValuedHeadersNotCrumbled) {
+  ExpectIndexedLiteral("foo", "bar, baz");
+  SpdyHeaderBlock headers;
+  headers["foo"] = "bar, baz";
+  CompareWithExpectedEncoding(headers);
+}
+
+TEST_P(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) {
+  // Compactable string. Uses Huffman coding.
+  peer_.EmitString("feedbeef");
+  expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
+  expected_.AppendUint32(6);
+  expected_.AppendBytes("\x94\xA5\x92\x32\x96_");
+
+  // Non-compactable. Uses identity coding.
+  peer_.EmitString("@@@@@@");
+  expected_.AppendPrefix(kStringLiteralIdentityEncoded);
+  expected_.AppendUint32(6);
+  expected_.AppendBytes("@@@@@@");
+
+  std::string actual_out;
+  std::string expected_out = expected_.TakeString();
+  peer_.TakeString(&actual_out);
+  EXPECT_EQ(expected_out, actual_out);
+}
+
+TEST_P(HpackEncoderTest, EncodingWithoutCompression) {
+  encoder_.SetHeaderListener(
+      [this](absl::string_view name, absl::string_view value) {
+        this->SaveHeaders(name, value);
+      });
+  encoder_.DisableCompression();
+
+  ExpectNonIndexedLiteral(":path", "/index.html");
+  ExpectNonIndexedLiteral("cookie", "foo=bar");
+  ExpectNonIndexedLiteral("cookie", "baz=bing");
+  if (strategy_ == kRepresentations) {
+    ExpectNonIndexedLiteral("hello", std::string("goodbye\0aloha", 13));
+  } else {
+    ExpectNonIndexedLiteral("hello", "goodbye");
+    ExpectNonIndexedLiteral("hello", "aloha");
+  }
+  ExpectNonIndexedLiteral("multivalue", "value1, value2");
+
+  SpdyHeaderBlock headers;
+  headers[":path"] = "/index.html";
+  headers["cookie"] = "foo=bar; baz=bing";
+  headers["hello"] = "goodbye";
+  headers.AppendValueOrAddHeader("hello", "aloha");
+  headers["multivalue"] = "value1, value2";
+
+  CompareWithExpectedEncoding(headers);
+
+  if (strategy_ == kRepresentations) {
+    EXPECT_THAT(
+        headers_observed_,
+        ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"),
+                    Pair("cookie", "baz=bing"),
+                    Pair("hello", absl::string_view("goodbye\0aloha", 13)),
+                    Pair("multivalue", "value1, value2")));
+  } else {
+    EXPECT_THAT(
+        headers_observed_,
+        ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"),
+                    Pair("cookie", "baz=bing"), Pair("hello", "goodbye"),
+                    Pair("hello", "aloha"),
+                    Pair("multivalue", "value1, value2")));
+  }
+  EXPECT_EQ(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
+}
+
+TEST_P(HpackEncoderTest, MultipleEncodingPasses) {
+  encoder_.SetHeaderListener(
+      [this](absl::string_view name, absl::string_view value) {
+        this->SaveHeaders(name, value);
+      });
+
+  // Pass 1.
+  {
+    SpdyHeaderBlock headers;
+    headers["key1"] = "value1";
+    headers["cookie"] = "a=bb";
+
+    ExpectIndex(DynamicIndexToWireIndex(key_1_index_));
+    ExpectIndex(DynamicIndexToWireIndex(cookie_a_index_));
+    CompareWithExpectedEncoding(headers);
+  }
+  // Header table is:
+  // 65: key1: value1
+  // 64: key2: value2
+  // 63: cookie: a=bb
+  // 62: cookie: c=dd
+  // Pass 2.
+  {
+    SpdyHeaderBlock headers;
+    headers["key2"] = "value2";
+    headers["cookie"] = "c=dd; e=ff";
+
+    // "key2: value2"
+    ExpectIndex(DynamicIndexToWireIndex(key_2_index_));
+    // "cookie: c=dd"
+    ExpectIndex(DynamicIndexToWireIndex(cookie_c_index_));
+    // This cookie evicts |key1| from the dynamic table.
+    ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");
+    dynamic_table_insertions_++;
+
+    CompareWithExpectedEncoding(headers);
+  }
+  // Header table is:
+  // 65: key2: value2
+  // 64: cookie: a=bb
+  // 63: cookie: c=dd
+  // 62: cookie: e=ff
+  // Pass 3.
+  {
+    SpdyHeaderBlock headers;
+    headers["key2"] = "value2";
+    headers["cookie"] = "a=bb; b=cc; c=dd";
+
+    // "key2: value2"
+    EXPECT_EQ(65u, DynamicIndexToWireIndex(key_2_index_));
+    ExpectIndex(DynamicIndexToWireIndex(key_2_index_));
+    // "cookie: a=bb"
+    EXPECT_EQ(64u, DynamicIndexToWireIndex(cookie_a_index_));
+    ExpectIndex(DynamicIndexToWireIndex(cookie_a_index_));
+    // This cookie evicts |key2| from the dynamic table.
+    ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "b=cc");
+    dynamic_table_insertions_++;
+    // "cookie: c=dd"
+    ExpectIndex(DynamicIndexToWireIndex(cookie_c_index_));
+
+    CompareWithExpectedEncoding(headers);
+  }
+
+  // clang-format off
+  EXPECT_THAT(headers_observed_,
+              ElementsAre(Pair("key1", "value1"),
+                          Pair("cookie", "a=bb"),
+                          Pair("key2", "value2"),
+                          Pair("cookie", "c=dd"),
+                          Pair("cookie", "e=ff"),
+                          Pair("key2", "value2"),
+                          Pair("cookie", "a=bb"),
+                          Pair("cookie", "b=cc"),
+                          Pair("cookie", "c=dd")));
+  // clang-format on
+}
+
+TEST_P(HpackEncoderTest, PseudoHeadersFirst) {
+  SpdyHeaderBlock headers;
+  // A pseudo-header that should not be indexed.
+  headers[":path"] = "/spam/eggs.html";
+  // A pseudo-header to be indexed.
+  headers[":authority"] = "www.example.com";
+  // A regular header which precedes ":" alphabetically, should still be encoded
+  // after pseudo-headers.
+  headers["-foo"] = "bar";
+  headers["foo"] = "bar";
+  headers["cookie"] = "c=dd";
+
+  // Headers are indexed in the order in which they were added.
+  // This entry pushes "cookie: a=bb" back to 63.
+  ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
+                                       "/spam/eggs.html");
+  ExpectIndexedLiteral(peer_.table()->GetByName(":authority"),
+                       "www.example.com");
+  ExpectIndexedLiteral("-foo", "bar");
+  ExpectIndexedLiteral("foo", "bar");
+  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "c=dd");
+  CompareWithExpectedEncoding(headers);
+}
+
+TEST_P(HpackEncoderTest, CookieToCrumbs) {
+  test::HpackEncoderPeer peer(nullptr);
+  std::vector<absl::string_view> out;
+
+  // Leading and trailing whitespace is consumed. A space after ';' is consumed.
+  // All other spaces remain. ';' at beginning and end of string produce empty
+  // crumbs.
+  // See section 8.1.3.4 "Compressing the Cookie Header Field" in the HTTP/2
+  // specification at http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
+  peer.CookieToCrumbs(" foo=1;bar=2 ; bar=3;  bing=4; ", &out);
+  EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3", " bing=4", ""));
+
+  peer.CookieToCrumbs(";;foo = bar ;; ;baz =bing", &out);
+  EXPECT_THAT(out, ElementsAre("", "", "foo = bar ", "", "", "baz =bing"));
+
+  peer.CookieToCrumbs("baz=bing; foo=bar; baz=bing", &out);
+  EXPECT_THAT(out, ElementsAre("baz=bing", "foo=bar", "baz=bing"));
+
+  peer.CookieToCrumbs("baz=bing", &out);
+  EXPECT_THAT(out, ElementsAre("baz=bing"));
+
+  peer.CookieToCrumbs("", &out);
+  EXPECT_THAT(out, ElementsAre(""));
+
+  peer.CookieToCrumbs("foo;bar; baz;baz;bing;", &out);
+  EXPECT_THAT(out, ElementsAre("foo", "bar", "baz", "baz", "bing", ""));
+
+  peer.CookieToCrumbs(" \t foo=1;bar=2 ; bar=3;\t  ", &out);
+  EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3", ""));
+
+  peer.CookieToCrumbs(" \t foo=1;bar=2 ; bar=3 \t  ", &out);
+  EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3"));
+}
+
+TEST_P(HpackEncoderTest, DecomposeRepresentation) {
+  test::HpackEncoderPeer peer(nullptr);
+  std::vector<absl::string_view> out;
+
+  peer.DecomposeRepresentation("", &out);
+  EXPECT_THAT(out, ElementsAre(""));
+
+  peer.DecomposeRepresentation("foobar", &out);
+  EXPECT_THAT(out, ElementsAre("foobar"));
+
+  peer.DecomposeRepresentation(absl::string_view("foo\0bar", 7), &out);
+  EXPECT_THAT(out, ElementsAre("foo", "bar"));
+
+  peer.DecomposeRepresentation(absl::string_view("\0foo\0bar", 8), &out);
+  EXPECT_THAT(out, ElementsAre("", "foo", "bar"));
+
+  peer.DecomposeRepresentation(absl::string_view("foo\0bar\0", 8), &out);
+  EXPECT_THAT(out, ElementsAre("foo", "bar", ""));
+
+  peer.DecomposeRepresentation(absl::string_view("\0foo\0bar\0", 9), &out);
+  EXPECT_THAT(out, ElementsAre("", "foo", "bar", ""));
+}
+
+// Test that encoded headers do not have \0-delimited multiple values, as this
+// became disallowed in HTTP/2 draft-14.
+TEST_P(HpackEncoderTest, CrumbleNullByteDelimitedValue) {
+  if (strategy_ == kRepresentations) {
+    // When HpackEncoder is asked to encode a list of Representations, the
+    // caller must crumble null-delimited values.
+    return;
+  }
+  SpdyHeaderBlock headers;
+  // A header field to be crumbled: "spam: foo\0bar".
+  headers["spam"] = std::string("foo\0bar", 7);
+
+  ExpectIndexedLiteral("spam", "foo");
+  expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
+  expected_.AppendUint32(62);
+  expected_.AppendPrefix(kStringLiteralIdentityEncoded);
+  expected_.AppendUint32(3);
+  expected_.AppendBytes("bar");
+  CompareWithExpectedEncoding(headers);
+}
+
+TEST_P(HpackEncoderTest, HeaderTableSizeUpdate) {
+  encoder_.ApplyHeaderTableSizeSetting(1024);
+  ExpectHeaderTableSizeUpdate(1024);
+  ExpectIndexedLiteral("key3", "value3");
+
+  SpdyHeaderBlock headers;
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+  EXPECT_EQ(new_entry->name(), "key3");
+  EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_P(HpackEncoderTest, HeaderTableSizeUpdateWithMin) {
+  const size_t starting_size = peer_.table()->settings_size_bound();
+  encoder_.ApplyHeaderTableSizeSetting(starting_size - 2);
+  encoder_.ApplyHeaderTableSizeSetting(starting_size - 1);
+  // We must encode the low watermark, so the peer knows to evict entries
+  // if necessary.
+  ExpectHeaderTableSizeUpdate(starting_size - 2);
+  ExpectHeaderTableSizeUpdate(starting_size - 1);
+  ExpectIndexedLiteral("key3", "value3");
+
+  SpdyHeaderBlock headers;
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+  EXPECT_EQ(new_entry->name(), "key3");
+  EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_P(HpackEncoderTest, HeaderTableSizeUpdateWithExistingSize) {
+  encoder_.ApplyHeaderTableSizeSetting(peer_.table()->settings_size_bound());
+  // No encoded size update.
+  ExpectIndexedLiteral("key3", "value3");
+
+  SpdyHeaderBlock headers;
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+  EXPECT_EQ(new_entry->name(), "key3");
+  EXPECT_EQ(new_entry->value(), "value3");
+}
+
+TEST_P(HpackEncoderTest, HeaderTableSizeUpdatesWithGreaterSize) {
+  const size_t starting_size = peer_.table()->settings_size_bound();
+  encoder_.ApplyHeaderTableSizeSetting(starting_size + 1);
+  encoder_.ApplyHeaderTableSizeSetting(starting_size + 2);
+  // Only a single size update to the final size.
+  ExpectHeaderTableSizeUpdate(starting_size + 2);
+  ExpectIndexedLiteral("key3", "value3");
+
+  SpdyHeaderBlock headers;
+  headers["key3"] = "value3";
+  CompareWithExpectedEncoding(headers);
+
+  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
+  EXPECT_EQ(new_entry->name(), "key3");
+  EXPECT_EQ(new_entry->value(), "value3");
+}
+
+}  // namespace
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_entry.cc b/quiche/spdy/core/hpack/hpack_entry.cc
new file mode 100644
index 0000000..e8f911e
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_entry.cc
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+
+#include "absl/strings/str_cat.h"
+
+namespace spdy {
+
+HpackEntry::HpackEntry(std::string name, std::string value)
+    : name_(std::move(name)), value_(std::move(value)) {}
+
+// static
+size_t HpackEntry::Size(absl::string_view name, absl::string_view value) {
+  return name.size() + value.size() + kHpackEntrySizeOverhead;
+}
+size_t HpackEntry::Size() const {
+  return Size(name(), value());
+}
+
+std::string HpackEntry::GetDebugString() const {
+  return absl::StrCat("{ name: \"", name_, "\", value: \"", value_, "\" }");
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_entry.h b/quiche/spdy/core/hpack/hpack_entry.h
new file mode 100644
index 0000000..26eeb6a
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_entry.h
@@ -0,0 +1,81 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_ENTRY_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_ENTRY_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+// All section references below are to
+// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
+
+namespace spdy {
+
+// The constant amount added to name().size() and value().size() to
+// get the size of an HpackEntry as defined in 5.1.
+constexpr size_t kHpackEntrySizeOverhead = 32;
+
+// A structure for looking up entries in the static and dynamic tables.
+struct QUICHE_EXPORT_PRIVATE HpackLookupEntry {
+  absl::string_view name;
+  absl::string_view value;
+
+  bool operator==(const HpackLookupEntry& other) const {
+    return name == other.name && value == other.value;
+  }
+
+  // Abseil hashing framework extension according to absl/hash/hash.h:
+  template <typename H>
+  friend H AbslHashValue(H h, const HpackLookupEntry& entry) {
+    return H::combine(std::move(h), entry.name, entry.value);
+  }
+};
+
+// A structure for an entry in the static table (3.3.1)
+// and the header table (3.3.2).
+class QUICHE_EXPORT_PRIVATE HpackEntry {
+ public:
+  HpackEntry(std::string name, std::string value);
+
+  // Make HpackEntry non-copyable to make sure it is always moved.
+  HpackEntry(const HpackEntry&) = delete;
+  HpackEntry& operator=(const HpackEntry&) = delete;
+
+  HpackEntry(HpackEntry&&) = default;
+  HpackEntry& operator=(HpackEntry&&) = default;
+
+  // Getters for std::string members traditionally return const std::string&.
+  // However, HpackHeaderTable uses string_view as keys in the maps
+  // static_name_index_ and dynamic_name_index_.  If HpackEntry::name() returned
+  // const std::string&, then
+  //   dynamic_name_index_.insert(std::make_pair(entry.name(), index));
+  // would silently create a dangling reference: make_pair infers type from the
+  // return type of entry.name() and silently creates a temporary string copy.
+  // Insert creates a string_view that points to this copy, which then
+  // immediately goes out of scope and gets destroyed.  While this is quite easy
+  // to avoid, for example, by explicitly specifying type as a template
+  // parameter to make_pair, returning string_view here is less error-prone.
+  absl::string_view name() const { return name_; }
+  absl::string_view value() const { return value_; }
+
+  // Returns the size of an entry as defined in 5.1.
+  static size_t Size(absl::string_view name, absl::string_view value);
+  size_t Size() const;
+
+  std::string GetDebugString() const;
+
+ private:
+  std::string name_;
+  std::string value_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_ENTRY_H_
diff --git a/quiche/spdy/core/hpack/hpack_entry_test.cc b/quiche/spdy/core/hpack/hpack_entry_test.cc
new file mode 100644
index 0000000..faf7786
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_entry_test.cc
@@ -0,0 +1,53 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+
+#include "absl/hash/hash.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+
+namespace {
+
+TEST(HpackLookupEntryTest, EntryNamesDiffer) {
+  HpackLookupEntry entry1{"header", "value"};
+  HpackLookupEntry entry2{"HEADER", "value"};
+
+  EXPECT_FALSE(entry1 == entry2);
+  EXPECT_NE(absl::Hash<HpackLookupEntry>()(entry1),
+            absl::Hash<HpackLookupEntry>()(entry2));
+}
+
+TEST(HpackLookupEntryTest, EntryValuesDiffer) {
+  HpackLookupEntry entry1{"header", "value"};
+  HpackLookupEntry entry2{"header", "VALUE"};
+
+  EXPECT_FALSE(entry1 == entry2);
+  EXPECT_NE(absl::Hash<HpackLookupEntry>()(entry1),
+            absl::Hash<HpackLookupEntry>()(entry2));
+}
+
+TEST(HpackLookupEntryTest, EntriesEqual) {
+  HpackLookupEntry entry1{"name", "value"};
+  HpackLookupEntry entry2{"name", "value"};
+
+  EXPECT_TRUE(entry1 == entry2);
+  EXPECT_EQ(absl::Hash<HpackLookupEntry>()(entry1),
+            absl::Hash<HpackLookupEntry>()(entry2));
+}
+
+TEST(HpackEntryTest, BasicEntry) {
+  HpackEntry entry("header-name", "header value");
+
+  EXPECT_EQ("header-name", entry.name());
+  EXPECT_EQ("header value", entry.value());
+
+  EXPECT_EQ(55u, entry.Size());
+  EXPECT_EQ(55u, HpackEntry::Size("header-name", "header value"));
+}
+
+}  // namespace
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_header_table.cc b/quiche/spdy/core/hpack/hpack_header_table.cc
new file mode 100644
index 0000000..102d2b4
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_header_table.cc
@@ -0,0 +1,188 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+
+#include <algorithm>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+namespace spdy {
+
+HpackHeaderTable::HpackHeaderTable()
+    : static_entries_(ObtainHpackStaticTable().GetStaticEntries()),
+      static_index_(ObtainHpackStaticTable().GetStaticIndex()),
+      static_name_index_(ObtainHpackStaticTable().GetStaticNameIndex()),
+      settings_size_bound_(kDefaultHeaderTableSizeSetting),
+      size_(0),
+      max_size_(kDefaultHeaderTableSizeSetting),
+      dynamic_table_insertions_(0) {}
+
+HpackHeaderTable::~HpackHeaderTable() = default;
+
+size_t HpackHeaderTable::GetByName(absl::string_view name) {
+  {
+    auto it = static_name_index_.find(name);
+    if (it != static_name_index_.end()) {
+      return 1 + it->second;
+    }
+  }
+  {
+    NameToEntryMap::const_iterator it = dynamic_name_index_.find(name);
+    if (it != dynamic_name_index_.end()) {
+      return dynamic_table_insertions_ - it->second + kStaticTableSize;
+    }
+  }
+  return kHpackEntryNotFound;
+}
+
+size_t HpackHeaderTable::GetByNameAndValue(absl::string_view name,
+                                           absl::string_view value) {
+  HpackLookupEntry query{name, value};
+  {
+    auto it = static_index_.find(query);
+    if (it != static_index_.end()) {
+      return 1 + it->second;
+    }
+  }
+  {
+    auto it = dynamic_index_.find(query);
+    if (it != dynamic_index_.end()) {
+      return dynamic_table_insertions_ - it->second + kStaticTableSize;
+    }
+  }
+  return kHpackEntryNotFound;
+}
+
+void HpackHeaderTable::SetMaxSize(size_t max_size) {
+  QUICHE_CHECK_LE(max_size, settings_size_bound_);
+
+  max_size_ = max_size;
+  if (size_ > max_size_) {
+    Evict(EvictionCountToReclaim(size_ - max_size_));
+    QUICHE_CHECK_LE(size_, max_size_);
+  }
+}
+
+void HpackHeaderTable::SetSettingsHeaderTableSize(size_t settings_size) {
+  settings_size_bound_ = settings_size;
+  SetMaxSize(settings_size_bound_);
+}
+
+void HpackHeaderTable::EvictionSet(absl::string_view name,
+                                   absl::string_view value,
+                                   DynamicEntryTable::iterator* begin_out,
+                                   DynamicEntryTable::iterator* end_out) {
+  size_t eviction_count = EvictionCountForEntry(name, value);
+  *begin_out = dynamic_entries_.end() - eviction_count;
+  *end_out = dynamic_entries_.end();
+}
+
+size_t HpackHeaderTable::EvictionCountForEntry(absl::string_view name,
+                                               absl::string_view value) const {
+  size_t available_size = max_size_ - size_;
+  size_t entry_size = HpackEntry::Size(name, value);
+
+  if (entry_size <= available_size) {
+    // No evictions are required.
+    return 0;
+  }
+  return EvictionCountToReclaim(entry_size - available_size);
+}
+
+size_t HpackHeaderTable::EvictionCountToReclaim(size_t reclaim_size) const {
+  size_t count = 0;
+  for (auto it = dynamic_entries_.rbegin();
+       it != dynamic_entries_.rend() && reclaim_size != 0; ++it, ++count) {
+    reclaim_size -= std::min(reclaim_size, it->Size());
+  }
+  return count;
+}
+
+void HpackHeaderTable::Evict(size_t count) {
+  for (size_t i = 0; i != count; ++i) {
+    QUICHE_CHECK(!dynamic_entries_.empty());
+
+    HpackEntry* entry = &dynamic_entries_.back();
+    const size_t index = dynamic_table_insertions_ - dynamic_entries_.size();
+
+    size_ -= entry->Size();
+    auto it = dynamic_index_.find({entry->name(), entry->value()});
+    QUICHE_DCHECK(it != dynamic_index_.end());
+    // Only remove an entry from the index if its insertion index matches;
+    // otherwise, the index refers to another entry with the same name and
+    // value.
+    if (it->second == index) {
+      dynamic_index_.erase(it);
+    }
+    auto name_it = dynamic_name_index_.find(entry->name());
+    QUICHE_DCHECK(name_it != dynamic_name_index_.end());
+    // Only remove an entry from the literal index if its insertion index
+    /// matches; otherwise, the index refers to another entry with the same
+    // name.
+    if (name_it->second == index) {
+      dynamic_name_index_.erase(name_it);
+    }
+    dynamic_entries_.pop_back();
+  }
+}
+
+const HpackEntry* HpackHeaderTable::TryAddEntry(absl::string_view name,
+                                                absl::string_view value) {
+  // Since |dynamic_entries_| has iterator stability, |name| and |value| are
+  // valid even after evicting other entries and push_front() making room for
+  // the new one.
+  Evict(EvictionCountForEntry(name, value));
+
+  size_t entry_size = HpackEntry::Size(name, value);
+  if (entry_size > (max_size_ - size_)) {
+    // Entire table has been emptied, but there's still insufficient room.
+    QUICHE_DCHECK(dynamic_entries_.empty());
+    QUICHE_DCHECK_EQ(0u, size_);
+    return nullptr;
+  }
+
+  const size_t index = dynamic_table_insertions_;
+  dynamic_entries_.push_front(
+      HpackEntry(std::string(name), std::string(value)));
+  HpackEntry* new_entry = &dynamic_entries_.front();
+  auto index_result = dynamic_index_.insert(std::make_pair(
+      HpackLookupEntry{new_entry->name(), new_entry->value()}, index));
+  if (!index_result.second) {
+    // An entry with the same name and value already exists in the dynamic
+    // index. We should replace it with the newly added entry.
+    QUICHE_DVLOG(1) << "Found existing entry at: " << index_result.first->second
+                    << " replacing with: " << new_entry->GetDebugString()
+                    << " at: " << index;
+    QUICHE_DCHECK_GT(index, index_result.first->second);
+    dynamic_index_.erase(index_result.first);
+    auto insert_result = dynamic_index_.insert(std::make_pair(
+        HpackLookupEntry{new_entry->name(), new_entry->value()}, index));
+    QUICHE_CHECK(insert_result.second);
+  }
+
+  auto name_result =
+      dynamic_name_index_.insert(std::make_pair(new_entry->name(), index));
+  if (!name_result.second) {
+    // An entry with the same name already exists in the dynamic index. We
+    // should replace it with the newly added entry.
+    QUICHE_DVLOG(1) << "Found existing entry at: " << name_result.first->second
+                    << " replacing with: " << new_entry->GetDebugString()
+                    << " at: " << index;
+    QUICHE_DCHECK_GT(index, name_result.first->second);
+    dynamic_name_index_.erase(name_result.first);
+    auto insert_result =
+        dynamic_name_index_.insert(std::make_pair(new_entry->name(), index));
+    QUICHE_CHECK(insert_result.second);
+  }
+
+  size_ += entry_size;
+  ++dynamic_table_insertions_;
+
+  return &dynamic_entries_.front();
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_header_table.h b/quiche/spdy/core/hpack/hpack_header_table.h
new file mode 100644
index 0000000..4d6b6ec
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_header_table.h
@@ -0,0 +1,154 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <deque>
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/hash/hash.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+
+// All section references below are to http://tools.ietf.org/html/rfc7541.
+
+namespace spdy {
+
+namespace test {
+class HpackHeaderTablePeer;
+}  // namespace test
+
+// Return value of GetByName() and GetByNameAndValue() if matching entry is not
+// found.  This value is never used in HPACK for indexing entries, see
+// https://httpwg.org/specs/rfc7541.html#index.address.space.
+constexpr size_t kHpackEntryNotFound = 0;
+
+// A data structure for the static table (2.3.1) and the dynamic table (2.3.2).
+class QUICHE_EXPORT_PRIVATE HpackHeaderTable {
+ public:
+  friend class test::HpackHeaderTablePeer;
+
+  // Use a lightweight, memory efficient container for the static table, which
+  // is initialized once and never changed after.
+  using StaticEntryTable = std::vector<HpackEntry>;
+
+  // HpackHeaderTable takes advantage of the deque property that references
+  // remain valid, so long as insertions & deletions are at the head & tail.
+  // This precludes the use of base::circular_deque.
+  // TODO(b/182349990): Change to a more memory efficient container.
+  using DynamicEntryTable = std::deque<HpackEntry>;
+
+  using NameValueToEntryMap = absl::flat_hash_map<HpackLookupEntry, size_t>;
+  using NameToEntryMap = absl::flat_hash_map<absl::string_view, size_t>;
+
+  HpackHeaderTable();
+  HpackHeaderTable(const HpackHeaderTable&) = delete;
+  HpackHeaderTable& operator=(const HpackHeaderTable&) = delete;
+
+  ~HpackHeaderTable();
+
+  // Last-acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
+  size_t settings_size_bound() const { return settings_size_bound_; }
+
+  // Current and maximum estimated byte size of the table, as described in
+  // 4.1. Notably, this is /not/ the number of entries in the table.
+  size_t size() const { return size_; }
+  size_t max_size() const { return max_size_; }
+
+  // The HPACK indexing scheme used by GetByName() and GetByNameAndValue() is
+  // defined at https://httpwg.org/specs/rfc7541.html#index.address.space.
+
+  // Returns the index of the lowest-index entry matching |name|,
+  // or kHpackEntryNotFound if no matching entry is found.
+  size_t GetByName(absl::string_view name);
+
+  // Returns the index of the lowest-index entry matching |name| and |value|,
+  // or kHpackEntryNotFound if no matching entry is found.
+  size_t GetByNameAndValue(absl::string_view name, absl::string_view value);
+
+  // Sets the maximum size of the header table, evicting entries if
+  // necessary as described in 5.2.
+  void SetMaxSize(size_t max_size);
+
+  // Sets the SETTINGS_HEADER_TABLE_SIZE bound of the table. Will call
+  // SetMaxSize() as needed to preserve max_size() <= settings_size_bound().
+  void SetSettingsHeaderTableSize(size_t settings_size);
+
+  // Determine the set of entries which would be evicted by the insertion
+  // of |name| & |value| into the table, as per section 4.4. No eviction
+  // actually occurs. The set is returned via range [begin_out, end_out).
+  void EvictionSet(absl::string_view name,
+                   absl::string_view value,
+                   DynamicEntryTable::iterator* begin_out,
+                   DynamicEntryTable::iterator* end_out);
+
+  // Adds an entry for the representation, evicting entries as needed. |name|
+  // and |value| must not point to an entry in |dynamic_entries_| which is about
+  // to be evicted, but they may point to an entry which is not.
+  // The added HpackEntry is returned, or NULL is returned if all entries were
+  // evicted and the empty table is of insufficent size for the representation.
+  const HpackEntry* TryAddEntry(absl::string_view name,
+                                absl::string_view value);
+
+ private:
+  // Returns number of evictions required to enter |name| & |value|.
+  size_t EvictionCountForEntry(absl::string_view name,
+                               absl::string_view value) const;
+
+  // Returns number of evictions required to reclaim |reclaim_size| table size.
+  size_t EvictionCountToReclaim(size_t reclaim_size) const;
+
+  // Evicts |count| oldest entries from the table.
+  void Evict(size_t count);
+
+  // |static_entries_|, |static_index_|, and |static_name_index_| are owned by
+  // HpackStaticTable singleton.
+
+  // Stores HpackEntries.
+  const StaticEntryTable& static_entries_;
+  DynamicEntryTable dynamic_entries_;
+
+  // Tracks the index of the unique HpackEntry for a given header name and
+  // value.  Keys consist of string_views that point to strings stored in
+  // |static_entries_|.
+  const NameValueToEntryMap& static_index_;
+
+  // Tracks the index of the first static entry for each name in the static
+  // table.  Each key is a string_view that points to a name string stored in
+  // |static_entries_|.
+  const NameToEntryMap& static_name_index_;
+
+  // Tracks the index of the most recently inserted HpackEntry for a given
+  // header name and value.  Keys consist of string_views that point to strings
+  // stored in |dynamic_entries_|.
+  NameValueToEntryMap dynamic_index_;
+
+  // Tracks the index of the most recently inserted HpackEntry for a given
+  // header name.  Each key is a string_view that points to a name string stored
+  // in |dynamic_entries_|.
+  NameToEntryMap dynamic_name_index_;
+
+  // Last acknowledged value for SETTINGS_HEADER_TABLE_SIZE.
+  size_t settings_size_bound_;
+
+  // Estimated current and maximum byte size of the table.
+  // |max_size_| <= |settings_size_bound_|
+  size_t size_;
+  size_t max_size_;
+
+  // Total number of dynamic table insertions so far
+  // (including entries that have been evicted).
+  size_t dynamic_table_insertions_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
diff --git a/quiche/spdy/core/hpack/hpack_header_table_test.cc b/quiche/spdy/core/hpack/hpack_header_table_test.cc
new file mode 100644
index 0000000..0d1acef
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_header_table_test.cc
@@ -0,0 +1,392 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+namespace spdy {
+
+using std::distance;
+
+namespace test {
+
+class HpackHeaderTablePeer {
+ public:
+  explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {}
+
+  const HpackHeaderTable::DynamicEntryTable& dynamic_entries() {
+    return table_->dynamic_entries_;
+  }
+  const HpackHeaderTable::StaticEntryTable& static_entries() {
+    return table_->static_entries_;
+  }
+  const HpackEntry* GetFirstStaticEntry() {
+    return &table_->static_entries_.front();
+  }
+  const HpackEntry* GetLastStaticEntry() {
+    return &table_->static_entries_.back();
+  }
+  std::vector<HpackEntry*> EvictionSet(absl::string_view name,
+                                       absl::string_view value) {
+    HpackHeaderTable::DynamicEntryTable::iterator begin, end;
+    table_->EvictionSet(name, value, &begin, &end);
+    std::vector<HpackEntry*> result;
+    for (; begin != end; ++begin) {
+      result.push_back(&(*begin));
+    }
+    return result;
+  }
+  size_t dynamic_table_insertions() {
+    return table_->dynamic_table_insertions_;
+  }
+  size_t EvictionCountForEntry(absl::string_view name,
+                               absl::string_view value) {
+    return table_->EvictionCountForEntry(name, value);
+  }
+  size_t EvictionCountToReclaim(size_t reclaim_size) {
+    return table_->EvictionCountToReclaim(reclaim_size);
+  }
+  void Evict(size_t count) { return table_->Evict(count); }
+
+ private:
+  HpackHeaderTable* table_;
+};
+
+}  // namespace test
+
+namespace {
+
+class HpackHeaderTableTest : public QuicheTest {
+ protected:
+  typedef std::vector<HpackEntry> HpackEntryVector;
+
+  HpackHeaderTableTest() : table_(), peer_(&table_) {}
+
+  // Returns an entry whose Size() is equal to the given one.
+  static HpackEntry MakeEntryOfSize(uint32_t size) {
+    EXPECT_GE(size, kHpackEntrySizeOverhead);
+    std::string name((size - kHpackEntrySizeOverhead) / 2, 'n');
+    std::string value(size - kHpackEntrySizeOverhead - name.size(), 'v');
+    HpackEntry entry(name, value);
+    EXPECT_EQ(size, entry.Size());
+    return entry;
+  }
+
+  // Returns a vector of entries whose total size is equal to the given
+  // one.
+  static HpackEntryVector MakeEntriesOfTotalSize(uint32_t total_size) {
+    EXPECT_GE(total_size, kHpackEntrySizeOverhead);
+    uint32_t entry_size = kHpackEntrySizeOverhead;
+    uint32_t remaining_size = total_size;
+    HpackEntryVector entries;
+    while (remaining_size > 0) {
+      EXPECT_LE(entry_size, remaining_size);
+      entries.push_back(MakeEntryOfSize(entry_size));
+      remaining_size -= entry_size;
+      entry_size = std::min(remaining_size, entry_size + 32);
+    }
+    return entries;
+  }
+
+  // Adds the given vector of entries to the given header table,
+  // expecting no eviction to happen.
+  void AddEntriesExpectNoEviction(const HpackEntryVector& entries) {
+    for (auto it = entries.begin(); it != entries.end(); ++it) {
+      HpackHeaderTable::DynamicEntryTable::iterator begin, end;
+
+      table_.EvictionSet(it->name(), it->value(), &begin, &end);
+      EXPECT_EQ(0, distance(begin, end));
+
+      const HpackEntry* entry = table_.TryAddEntry(it->name(), it->value());
+      EXPECT_NE(entry, static_cast<HpackEntry*>(nullptr));
+    }
+  }
+
+  HpackHeaderTable table_;
+  test::HpackHeaderTablePeer peer_;
+};
+
+TEST_F(HpackHeaderTableTest, StaticTableInitialization) {
+  EXPECT_EQ(0u, table_.size());
+  EXPECT_EQ(kDefaultHeaderTableSizeSetting, table_.max_size());
+  EXPECT_EQ(kDefaultHeaderTableSizeSetting, table_.settings_size_bound());
+
+  EXPECT_EQ(0u, peer_.dynamic_entries().size());
+  EXPECT_EQ(0u, peer_.dynamic_table_insertions());
+
+  // Static entries have been populated and inserted into the table & index.
+  const HpackHeaderTable::StaticEntryTable& static_entries =
+      peer_.static_entries();
+  EXPECT_EQ(kStaticTableSize, static_entries.size());
+  // HPACK indexing scheme is 1-based.
+  size_t index = 1;
+  for (const HpackEntry& entry : static_entries) {
+    EXPECT_EQ(index, table_.GetByNameAndValue(entry.name(), entry.value()));
+    index++;
+  }
+}
+
+TEST_F(HpackHeaderTableTest, BasicDynamicEntryInsertionAndEviction) {
+  EXPECT_EQ(kStaticTableSize, peer_.static_entries().size());
+
+  const HpackEntry* first_static_entry = peer_.GetFirstStaticEntry();
+  const HpackEntry* last_static_entry = peer_.GetLastStaticEntry();
+
+  const HpackEntry* entry = table_.TryAddEntry("header-key", "Header Value");
+  EXPECT_EQ("header-key", entry->name());
+  EXPECT_EQ("Header Value", entry->value());
+
+  // Table counts were updated appropriately.
+  EXPECT_EQ(entry->Size(), table_.size());
+  EXPECT_EQ(1u, peer_.dynamic_entries().size());
+  EXPECT_EQ(kStaticTableSize, peer_.static_entries().size());
+
+  EXPECT_EQ(62u, table_.GetByNameAndValue("header-key", "Header Value"));
+
+  // Index of static entries does not change.
+  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
+  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
+
+  // Evict |entry|. Table counts are again updated appropriately.
+  peer_.Evict(1);
+  EXPECT_EQ(0u, table_.size());
+  EXPECT_EQ(0u, peer_.dynamic_entries().size());
+  EXPECT_EQ(kStaticTableSize, peer_.static_entries().size());
+
+  // Index of static entries does not change.
+  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
+  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
+}
+
+TEST_F(HpackHeaderTableTest, EntryIndexing) {
+  const HpackEntry* first_static_entry = peer_.GetFirstStaticEntry();
+  const HpackEntry* last_static_entry = peer_.GetLastStaticEntry();
+
+  // Static entries are queryable by name & value.
+  EXPECT_EQ(1u, table_.GetByName(first_static_entry->name()));
+  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
+                                         first_static_entry->value()));
+
+  // Create a mix of entries which duplicate names, and names & values of both
+  // dynamic and static entries.
+  table_.TryAddEntry(first_static_entry->name(), first_static_entry->value());
+  table_.TryAddEntry(first_static_entry->name(), "Value Four");
+  table_.TryAddEntry("key-1", "Value One");
+  table_.TryAddEntry("key-2", "Value Three");
+  table_.TryAddEntry("key-1", "Value Two");
+  table_.TryAddEntry("key-2", "Value Three");
+  table_.TryAddEntry("key-2", "Value Four");
+
+  // The following entry is identical to the one at index 68.  The smaller index
+  // is returned by GetByNameAndValue().
+  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
+                                         first_static_entry->value()));
+  EXPECT_EQ(67u,
+            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
+  EXPECT_EQ(66u, table_.GetByNameAndValue("key-1", "Value One"));
+  EXPECT_EQ(64u, table_.GetByNameAndValue("key-1", "Value Two"));
+  // The following entry is identical to the one at index 65.  The smaller index
+  // is returned by GetByNameAndValue().
+  EXPECT_EQ(63u, table_.GetByNameAndValue("key-2", "Value Three"));
+  EXPECT_EQ(62u, table_.GetByNameAndValue("key-2", "Value Four"));
+
+  // Index of static entries does not change.
+  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
+  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
+
+  // Querying by name returns the most recently added matching entry.
+  EXPECT_EQ(64u, table_.GetByName("key-1"));
+  EXPECT_EQ(62u, table_.GetByName("key-2"));
+  EXPECT_EQ(1u, table_.GetByName(first_static_entry->name()));
+  EXPECT_EQ(kHpackEntryNotFound, table_.GetByName("not-present"));
+
+  // Querying by name & value returns the lowest-index matching entry among
+  // static entries, and the highest-index one among dynamic entries.
+  EXPECT_EQ(66u, table_.GetByNameAndValue("key-1", "Value One"));
+  EXPECT_EQ(64u, table_.GetByNameAndValue("key-1", "Value Two"));
+  EXPECT_EQ(63u, table_.GetByNameAndValue("key-2", "Value Three"));
+  EXPECT_EQ(62u, table_.GetByNameAndValue("key-2", "Value Four"));
+  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
+                                         first_static_entry->value()));
+  EXPECT_EQ(67u,
+            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
+  EXPECT_EQ(kHpackEntryNotFound,
+            table_.GetByNameAndValue("key-1", "Not Present"));
+  EXPECT_EQ(kHpackEntryNotFound,
+            table_.GetByNameAndValue("not-present", "Value One"));
+
+  // Evict |entry1|. Queries for its name & value now return the static entry.
+  // |entry2| remains queryable.
+  peer_.Evict(1);
+  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
+                                         first_static_entry->value()));
+  EXPECT_EQ(67u,
+            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
+
+  // Evict |entry2|. Queries by its name & value are not found.
+  peer_.Evict(1);
+  EXPECT_EQ(kHpackEntryNotFound,
+            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
+
+  // Index of static entries does not change.
+  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
+  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
+}
+
+TEST_F(HpackHeaderTableTest, SetSizes) {
+  std::string key = "key", value = "value";
+  const HpackEntry* entry1 = table_.TryAddEntry(key, value);
+  const HpackEntry* entry2 = table_.TryAddEntry(key, value);
+  const HpackEntry* entry3 = table_.TryAddEntry(key, value);
+
+  // Set exactly large enough. No Evictions.
+  size_t max_size = entry1->Size() + entry2->Size() + entry3->Size();
+  table_.SetMaxSize(max_size);
+  EXPECT_EQ(3u, peer_.dynamic_entries().size());
+
+  // Set just too small. One eviction.
+  max_size = entry1->Size() + entry2->Size() + entry3->Size() - 1;
+  table_.SetMaxSize(max_size);
+  EXPECT_EQ(2u, peer_.dynamic_entries().size());
+
+  // Changing SETTINGS_HEADER_TABLE_SIZE.
+  EXPECT_EQ(kDefaultHeaderTableSizeSetting, table_.settings_size_bound());
+  // In production, the size passed to SetSettingsHeaderTableSize is never
+  // larger than table_.settings_size_bound().
+  table_.SetSettingsHeaderTableSize(kDefaultHeaderTableSizeSetting * 3 + 1);
+  EXPECT_EQ(kDefaultHeaderTableSizeSetting * 3 + 1, table_.max_size());
+
+  // SETTINGS_HEADER_TABLE_SIZE upper-bounds |table_.max_size()|,
+  // and will force evictions.
+  max_size = entry3->Size() - 1;
+  table_.SetSettingsHeaderTableSize(max_size);
+  EXPECT_EQ(max_size, table_.max_size());
+  EXPECT_EQ(max_size, table_.settings_size_bound());
+  EXPECT_EQ(0u, peer_.dynamic_entries().size());
+}
+
+TEST_F(HpackHeaderTableTest, EvictionCountForEntry) {
+  std::string key = "key", value = "value";
+  const HpackEntry* entry1 = table_.TryAddEntry(key, value);
+  const HpackEntry* entry2 = table_.TryAddEntry(key, value);
+  size_t entry3_size = HpackEntry::Size(key, value);
+
+  // Just enough capacity for third entry.
+  table_.SetMaxSize(entry1->Size() + entry2->Size() + entry3_size);
+  EXPECT_EQ(0u, peer_.EvictionCountForEntry(key, value));
+  EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value + "x"));
+
+  // No extra capacity. Third entry would force evictions.
+  table_.SetMaxSize(entry1->Size() + entry2->Size());
+  EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value));
+  EXPECT_EQ(2u, peer_.EvictionCountForEntry(key, value + "x"));
+}
+
+TEST_F(HpackHeaderTableTest, EvictionCountToReclaim) {
+  std::string key = "key", value = "value";
+  const HpackEntry* entry1 = table_.TryAddEntry(key, value);
+  const HpackEntry* entry2 = table_.TryAddEntry(key, value);
+
+  EXPECT_EQ(1u, peer_.EvictionCountToReclaim(1));
+  EXPECT_EQ(1u, peer_.EvictionCountToReclaim(entry1->Size()));
+  EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + 1));
+  EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + entry2->Size()));
+}
+
+// Fill a header table with entries. Make sure the entries are in
+// reverse order in the header table.
+TEST_F(HpackHeaderTableTest, TryAddEntryBasic) {
+  EXPECT_EQ(0u, table_.size());
+  EXPECT_EQ(table_.settings_size_bound(), table_.max_size());
+
+  HpackEntryVector entries = MakeEntriesOfTotalSize(table_.max_size());
+
+  // Most of the checks are in AddEntriesExpectNoEviction().
+  AddEntriesExpectNoEviction(entries);
+  EXPECT_EQ(table_.max_size(), table_.size());
+  EXPECT_EQ(table_.settings_size_bound(), table_.size());
+}
+
+// Fill a header table with entries, and then ramp the table's max
+// size down to evict an entry one at a time. Make sure the eviction
+// happens as expected.
+TEST_F(HpackHeaderTableTest, SetMaxSize) {
+  HpackEntryVector entries =
+      MakeEntriesOfTotalSize(kDefaultHeaderTableSizeSetting / 2);
+  AddEntriesExpectNoEviction(entries);
+
+  for (auto it = entries.begin(); it != entries.end(); ++it) {
+    size_t expected_count = distance(it, entries.end());
+    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
+
+    table_.SetMaxSize(table_.size() + 1);
+    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
+
+    table_.SetMaxSize(table_.size());
+    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
+
+    --expected_count;
+    table_.SetMaxSize(table_.size() - 1);
+    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
+  }
+  EXPECT_EQ(0u, table_.size());
+}
+
+// Fill a header table with entries, and then add an entry just big
+// enough to cause eviction of all but one entry. Make sure the
+// eviction happens as expected and the long entry is inserted into
+// the table.
+TEST_F(HpackHeaderTableTest, TryAddEntryEviction) {
+  HpackEntryVector entries = MakeEntriesOfTotalSize(table_.max_size());
+  AddEntriesExpectNoEviction(entries);
+
+  // The first entry in the dynamic table.
+  const HpackEntry* survivor_entry = &peer_.dynamic_entries().front();
+
+  HpackEntry long_entry =
+      MakeEntryOfSize(table_.max_size() - survivor_entry->Size());
+
+  // All dynamic entries but the first are to be evicted.
+  EXPECT_EQ(peer_.dynamic_entries().size() - 1,
+            peer_.EvictionSet(long_entry.name(), long_entry.value()).size());
+
+  table_.TryAddEntry(long_entry.name(), long_entry.value());
+  EXPECT_EQ(2u, peer_.dynamic_entries().size());
+  EXPECT_EQ(63u, table_.GetByNameAndValue(survivor_entry->name(),
+                                          survivor_entry->value()));
+  EXPECT_EQ(62u,
+            table_.GetByNameAndValue(long_entry.name(), long_entry.value()));
+}
+
+// Fill a header table with entries, and then add an entry bigger than
+// the entire table. Make sure no entry remains in the table.
+TEST_F(HpackHeaderTableTest, TryAddTooLargeEntry) {
+  HpackEntryVector entries = MakeEntriesOfTotalSize(table_.max_size());
+  AddEntriesExpectNoEviction(entries);
+
+  const HpackEntry long_entry = MakeEntryOfSize(table_.max_size() + 1);
+
+  // All entries are to be evicted.
+  EXPECT_EQ(peer_.dynamic_entries().size(),
+            peer_.EvictionSet(long_entry.name(), long_entry.value()).size());
+
+  const HpackEntry* new_entry =
+      table_.TryAddEntry(long_entry.name(), long_entry.value());
+  EXPECT_EQ(new_entry, static_cast<HpackEntry*>(nullptr));
+  EXPECT_EQ(0u, peer_.dynamic_entries().size());
+}
+
+}  // namespace
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_output_stream.cc b/quiche/spdy/core/hpack/hpack_output_stream.cc
new file mode 100644
index 0000000..8a0c8d6
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_output_stream.cc
@@ -0,0 +1,100 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_output_stream.h"
+
+#include <utility>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+
+HpackOutputStream::HpackOutputStream() : bit_offset_(0) {}
+
+HpackOutputStream::~HpackOutputStream() = default;
+
+void HpackOutputStream::AppendBits(uint8_t bits, size_t bit_size) {
+  QUICHE_DCHECK_GT(bit_size, 0u);
+  QUICHE_DCHECK_LE(bit_size, 8u);
+  QUICHE_DCHECK_EQ(bits >> bit_size, 0);
+  size_t new_bit_offset = bit_offset_ + bit_size;
+  if (bit_offset_ == 0) {
+    // Buffer ends on a byte boundary.
+    QUICHE_DCHECK_LE(bit_size, 8u);
+    buffer_.append(1, bits << (8 - bit_size));
+  } else if (new_bit_offset <= 8) {
+    // Buffer does not end on a byte boundary but the given bits fit
+    // in the remainder of the last byte.
+    buffer_.back() |= bits << (8 - new_bit_offset);
+  } else {
+    // Buffer does not end on a byte boundary and the given bits do
+    // not fit in the remainder of the last byte.
+    buffer_.back() |= bits >> (new_bit_offset - 8);
+    buffer_.append(1, bits << (16 - new_bit_offset));
+  }
+  bit_offset_ = new_bit_offset % 8;
+}
+
+void HpackOutputStream::AppendPrefix(HpackPrefix prefix) {
+  AppendBits(prefix.bits, prefix.bit_size);
+}
+
+void HpackOutputStream::AppendBytes(absl::string_view buffer) {
+  QUICHE_DCHECK_EQ(bit_offset_, 0u);
+  buffer_.append(buffer.data(), buffer.size());
+}
+
+void HpackOutputStream::AppendUint32(uint32_t I) {
+  // The algorithm below is adapted from the pseudocode in 6.1.
+  size_t N = 8 - bit_offset_;
+  uint8_t max_first_byte = static_cast<uint8_t>((1 << N) - 1);
+  if (I < max_first_byte) {
+    AppendBits(static_cast<uint8_t>(I), N);
+  } else {
+    AppendBits(max_first_byte, N);
+    I -= max_first_byte;
+    while ((I & ~0x7f) != 0) {
+      buffer_.append(1, (I & 0x7f) | 0x80);
+      I >>= 7;
+    }
+    AppendBits(static_cast<uint8_t>(I), 8);
+  }
+  QUICHE_DCHECK_EQ(bit_offset_, 0u);
+}
+
+std::string* HpackOutputStream::MutableString() {
+  QUICHE_DCHECK_EQ(bit_offset_, 0u);
+  return &buffer_;
+}
+
+std::string HpackOutputStream::TakeString() {
+  // This must hold, since all public functions cause the buffer to
+  // end on a byte boundary.
+  QUICHE_DCHECK_EQ(bit_offset_, 0u);
+  std::string out = std::move(buffer_);
+  buffer_ = {};
+  bit_offset_ = 0;
+  return out;
+}
+
+std::string HpackOutputStream::BoundedTakeString(size_t max_size) {
+  if (buffer_.size() > max_size) {
+    // Save off overflow bytes to temporary string (causes a copy).
+    std::string overflow = buffer_.substr(max_size);
+
+    // Resize buffer down to the given limit.
+    buffer_.resize(max_size);
+
+    // Give buffer to output string.
+    std::string out = std::move(buffer_);
+
+    // Reset to contain overflow.
+    buffer_ = std::move(overflow);
+    return out;
+  } else {
+    return TakeString();
+  }
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_output_stream.h b/quiche/spdy/core/hpack/hpack_output_stream.h
new file mode 100644
index 0000000..cd8ce46
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_output_stream.h
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
+
+#include <cstdint>
+#include <map>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+
+// All section references below are to
+// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
+
+namespace spdy {
+
+// An HpackOutputStream handles all the low-level details of encoding
+// header fields.
+class QUICHE_EXPORT_PRIVATE HpackOutputStream {
+ public:
+  HpackOutputStream();
+  HpackOutputStream(const HpackOutputStream&) = delete;
+  HpackOutputStream& operator=(const HpackOutputStream&) = delete;
+  ~HpackOutputStream();
+
+  // Appends the lower |bit_size| bits of |bits| to the internal buffer.
+  //
+  // |bit_size| must be > 0 and <= 8. |bits| must not have any bits
+  // set other than the lower |bit_size| bits.
+  void AppendBits(uint8_t bits, size_t bit_size);
+
+  // Simply forwards to AppendBits(prefix.bits, prefix.bit-size).
+  void AppendPrefix(HpackPrefix prefix);
+
+  // Directly appends |buffer|.
+  void AppendBytes(absl::string_view buffer);
+
+  // Appends the given integer using the representation described in
+  // 6.1. If the internal buffer ends on a byte boundary, the prefix
+  // length N is taken to be 8; otherwise, it is taken to be the
+  // number of bits to the next byte boundary.
+  //
+  // It is guaranteed that the internal buffer will end on a byte
+  // boundary after this function is called.
+  void AppendUint32(uint32_t I);
+
+  // Return pointer to internal buffer.  |bit_offset_| needs to be zero.
+  std::string* MutableString();
+
+  // Returns the internal buffer as a string, then resets state.
+  std::string TakeString();
+
+  // Returns up to |max_size| bytes of the internal buffer. Resets
+  // internal state with the overflow.
+  std::string BoundedTakeString(size_t max_size);
+
+  // Size in bytes of stream's internal buffer.
+  size_t size() const { return buffer_.size(); }
+
+ private:
+  // The internal bit buffer.
+  std::string buffer_;
+
+  // If 0, the buffer ends on a byte boundary. If non-zero, the buffer
+  // ends on the nth most significant bit. Guaranteed to be < 8.
+  size_t bit_offset_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
diff --git a/quiche/spdy/core/hpack/hpack_output_stream_test.cc b/quiche/spdy/core/hpack/hpack_output_stream_test.cc
new file mode 100644
index 0000000..ea1c265
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_output_stream_test.cc
@@ -0,0 +1,284 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_output_stream.h"
+
+#include <cstddef>
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+
+namespace {
+
+// Make sure that AppendBits() appends bits starting from the most
+// significant bit, and that it can handle crossing a byte boundary.
+TEST(HpackOutputStreamTest, AppendBits) {
+  HpackOutputStream output_stream;
+  std::string expected_str;
+
+  output_stream.AppendBits(0x1, 1);
+  expected_str.append(1, 0x00);
+  expected_str.back() |= (0x1 << 7);
+
+  output_stream.AppendBits(0x0, 1);
+
+  output_stream.AppendBits(0x3, 2);
+  *expected_str.rbegin() |= (0x3 << 4);
+
+  output_stream.AppendBits(0x0, 2);
+
+  // Byte-crossing append.
+  output_stream.AppendBits(0x7, 3);
+  *expected_str.rbegin() |= (0x7 >> 1);
+  expected_str.append(1, 0x00);
+  expected_str.back() |= (0x7 << 7);
+
+  output_stream.AppendBits(0x0, 7);
+
+  std::string str = output_stream.TakeString();
+  EXPECT_EQ(expected_str, str);
+}
+
+// Utility function to return I as a string encoded with an N-bit
+// prefix.
+std::string EncodeUint32(uint8_t N, uint32_t I) {
+  HpackOutputStream output_stream;
+  if (N < 8) {
+    output_stream.AppendBits(0x00, 8 - N);
+  }
+  output_stream.AppendUint32(I);
+  std::string str = output_stream.TakeString();
+  return str;
+}
+
+// The {Number}ByteIntegersEightBitPrefix tests below test that
+// certain integers are encoded correctly with an 8-bit prefix in
+// exactly {Number} bytes.
+
+TEST(HpackOutputStreamTest, OneByteIntegersEightBitPrefix) {
+  // Minimum.
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(8, 0x00));
+  EXPECT_EQ("\x7f", EncodeUint32(8, 0x7f));
+  // Maximum.
+  EXPECT_EQ("\xfe", EncodeUint32(8, 0xfe));
+}
+
+TEST(HpackOutputStreamTest, TwoByteIntegersEightBitPrefix) {
+  // Minimum.
+  EXPECT_EQ(std::string("\xff\x00", 2), EncodeUint32(8, 0xff));
+  EXPECT_EQ("\xff\x01", EncodeUint32(8, 0x0100));
+  // Maximum.
+  EXPECT_EQ("\xff\x7f", EncodeUint32(8, 0x017e));
+}
+
+TEST(HpackOutputStreamTest, ThreeByteIntegersEightBitPrefix) {
+  // Minimum.
+  EXPECT_EQ("\xff\x80\x01", EncodeUint32(8, 0x017f));
+  EXPECT_EQ("\xff\x80\x1e", EncodeUint32(8, 0x0fff));
+  // Maximum.
+  EXPECT_EQ("\xff\xff\x7f", EncodeUint32(8, 0x40fe));
+}
+
+TEST(HpackOutputStreamTest, FourByteIntegersEightBitPrefix) {
+  // Minimum.
+  EXPECT_EQ("\xff\x80\x80\x01", EncodeUint32(8, 0x40ff));
+  EXPECT_EQ("\xff\x80\xfe\x03", EncodeUint32(8, 0xffff));
+  // Maximum.
+  EXPECT_EQ("\xff\xff\xff\x7f", EncodeUint32(8, 0x002000fe));
+}
+
+TEST(HpackOutputStreamTest, FiveByteIntegersEightBitPrefix) {
+  // Minimum.
+  EXPECT_EQ("\xff\x80\x80\x80\x01", EncodeUint32(8, 0x002000ff));
+  EXPECT_EQ("\xff\x80\xfe\xff\x07", EncodeUint32(8, 0x00ffffff));
+  // Maximum.
+  EXPECT_EQ("\xff\xff\xff\xff\x7f", EncodeUint32(8, 0x100000fe));
+}
+
+TEST(HpackOutputStreamTest, SixByteIntegersEightBitPrefix) {
+  // Minimum.
+  EXPECT_EQ("\xff\x80\x80\x80\x80\x01", EncodeUint32(8, 0x100000ff));
+  // Maximum.
+  EXPECT_EQ("\xff\x80\xfe\xff\xff\x0f", EncodeUint32(8, 0xffffffff));
+}
+
+// The {Number}ByteIntegersOneToSevenBitPrefix tests below test that
+// certain integers are encoded correctly with an N-bit prefix in
+// exactly {Number} bytes for N in {1, 2, ..., 7}.
+
+TEST(HpackOutputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
+  // Minimums.
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(7, 0x00));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(6, 0x00));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(5, 0x00));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(4, 0x00));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(3, 0x00));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(2, 0x00));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(1, 0x00));
+
+  // Maximums.
+  EXPECT_EQ("\x7e", EncodeUint32(7, 0x7e));
+  EXPECT_EQ("\x3e", EncodeUint32(6, 0x3e));
+  EXPECT_EQ("\x1e", EncodeUint32(5, 0x1e));
+  EXPECT_EQ("\x0e", EncodeUint32(4, 0x0e));
+  EXPECT_EQ("\x06", EncodeUint32(3, 0x06));
+  EXPECT_EQ("\x02", EncodeUint32(2, 0x02));
+  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(1, 0x00));
+}
+
+TEST(HpackOutputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
+  // Minimums.
+  EXPECT_EQ(std::string("\x7f\x00", 2), EncodeUint32(7, 0x7f));
+  EXPECT_EQ(std::string("\x3f\x00", 2), EncodeUint32(6, 0x3f));
+  EXPECT_EQ(std::string("\x1f\x00", 2), EncodeUint32(5, 0x1f));
+  EXPECT_EQ(std::string("\x0f\x00", 2), EncodeUint32(4, 0x0f));
+  EXPECT_EQ(std::string("\x07\x00", 2), EncodeUint32(3, 0x07));
+  EXPECT_EQ(std::string("\x03\x00", 2), EncodeUint32(2, 0x03));
+  EXPECT_EQ(std::string("\x01\x00", 2), EncodeUint32(1, 0x01));
+
+  // Maximums.
+  EXPECT_EQ("\x7f\x7f", EncodeUint32(7, 0xfe));
+  EXPECT_EQ("\x3f\x7f", EncodeUint32(6, 0xbe));
+  EXPECT_EQ("\x1f\x7f", EncodeUint32(5, 0x9e));
+  EXPECT_EQ("\x0f\x7f", EncodeUint32(4, 0x8e));
+  EXPECT_EQ("\x07\x7f", EncodeUint32(3, 0x86));
+  EXPECT_EQ("\x03\x7f", EncodeUint32(2, 0x82));
+  EXPECT_EQ("\x01\x7f", EncodeUint32(1, 0x80));
+}
+
+TEST(HpackOutputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
+  // Minimums.
+  EXPECT_EQ("\x7f\x80\x01", EncodeUint32(7, 0xff));
+  EXPECT_EQ("\x3f\x80\x01", EncodeUint32(6, 0xbf));
+  EXPECT_EQ("\x1f\x80\x01", EncodeUint32(5, 0x9f));
+  EXPECT_EQ("\x0f\x80\x01", EncodeUint32(4, 0x8f));
+  EXPECT_EQ("\x07\x80\x01", EncodeUint32(3, 0x87));
+  EXPECT_EQ("\x03\x80\x01", EncodeUint32(2, 0x83));
+  EXPECT_EQ("\x01\x80\x01", EncodeUint32(1, 0x81));
+
+  // Maximums.
+  EXPECT_EQ("\x7f\xff\x7f", EncodeUint32(7, 0x407e));
+  EXPECT_EQ("\x3f\xff\x7f", EncodeUint32(6, 0x403e));
+  EXPECT_EQ("\x1f\xff\x7f", EncodeUint32(5, 0x401e));
+  EXPECT_EQ("\x0f\xff\x7f", EncodeUint32(4, 0x400e));
+  EXPECT_EQ("\x07\xff\x7f", EncodeUint32(3, 0x4006));
+  EXPECT_EQ("\x03\xff\x7f", EncodeUint32(2, 0x4002));
+  EXPECT_EQ("\x01\xff\x7f", EncodeUint32(1, 0x4000));
+}
+
+TEST(HpackOutputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
+  // Minimums.
+  EXPECT_EQ("\x7f\x80\x80\x01", EncodeUint32(7, 0x407f));
+  EXPECT_EQ("\x3f\x80\x80\x01", EncodeUint32(6, 0x403f));
+  EXPECT_EQ("\x1f\x80\x80\x01", EncodeUint32(5, 0x401f));
+  EXPECT_EQ("\x0f\x80\x80\x01", EncodeUint32(4, 0x400f));
+  EXPECT_EQ("\x07\x80\x80\x01", EncodeUint32(3, 0x4007));
+  EXPECT_EQ("\x03\x80\x80\x01", EncodeUint32(2, 0x4003));
+  EXPECT_EQ("\x01\x80\x80\x01", EncodeUint32(1, 0x4001));
+
+  // Maximums.
+  EXPECT_EQ("\x7f\xff\xff\x7f", EncodeUint32(7, 0x20007e));
+  EXPECT_EQ("\x3f\xff\xff\x7f", EncodeUint32(6, 0x20003e));
+  EXPECT_EQ("\x1f\xff\xff\x7f", EncodeUint32(5, 0x20001e));
+  EXPECT_EQ("\x0f\xff\xff\x7f", EncodeUint32(4, 0x20000e));
+  EXPECT_EQ("\x07\xff\xff\x7f", EncodeUint32(3, 0x200006));
+  EXPECT_EQ("\x03\xff\xff\x7f", EncodeUint32(2, 0x200002));
+  EXPECT_EQ("\x01\xff\xff\x7f", EncodeUint32(1, 0x200000));
+}
+
+TEST(HpackOutputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
+  // Minimums.
+  EXPECT_EQ("\x7f\x80\x80\x80\x01", EncodeUint32(7, 0x20007f));
+  EXPECT_EQ("\x3f\x80\x80\x80\x01", EncodeUint32(6, 0x20003f));
+  EXPECT_EQ("\x1f\x80\x80\x80\x01", EncodeUint32(5, 0x20001f));
+  EXPECT_EQ("\x0f\x80\x80\x80\x01", EncodeUint32(4, 0x20000f));
+  EXPECT_EQ("\x07\x80\x80\x80\x01", EncodeUint32(3, 0x200007));
+  EXPECT_EQ("\x03\x80\x80\x80\x01", EncodeUint32(2, 0x200003));
+  EXPECT_EQ("\x01\x80\x80\x80\x01", EncodeUint32(1, 0x200001));
+
+  // Maximums.
+  EXPECT_EQ("\x7f\xff\xff\xff\x7f", EncodeUint32(7, 0x1000007e));
+  EXPECT_EQ("\x3f\xff\xff\xff\x7f", EncodeUint32(6, 0x1000003e));
+  EXPECT_EQ("\x1f\xff\xff\xff\x7f", EncodeUint32(5, 0x1000001e));
+  EXPECT_EQ("\x0f\xff\xff\xff\x7f", EncodeUint32(4, 0x1000000e));
+  EXPECT_EQ("\x07\xff\xff\xff\x7f", EncodeUint32(3, 0x10000006));
+  EXPECT_EQ("\x03\xff\xff\xff\x7f", EncodeUint32(2, 0x10000002));
+  EXPECT_EQ("\x01\xff\xff\xff\x7f", EncodeUint32(1, 0x10000000));
+}
+
+TEST(HpackOutputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
+  // Minimums.
+  EXPECT_EQ("\x7f\x80\x80\x80\x80\x01", EncodeUint32(7, 0x1000007f));
+  EXPECT_EQ("\x3f\x80\x80\x80\x80\x01", EncodeUint32(6, 0x1000003f));
+  EXPECT_EQ("\x1f\x80\x80\x80\x80\x01", EncodeUint32(5, 0x1000001f));
+  EXPECT_EQ("\x0f\x80\x80\x80\x80\x01", EncodeUint32(4, 0x1000000f));
+  EXPECT_EQ("\x07\x80\x80\x80\x80\x01", EncodeUint32(3, 0x10000007));
+  EXPECT_EQ("\x03\x80\x80\x80\x80\x01", EncodeUint32(2, 0x10000003));
+  EXPECT_EQ("\x01\x80\x80\x80\x80\x01", EncodeUint32(1, 0x10000001));
+
+  // Maximums.
+  EXPECT_EQ("\x7f\x80\xff\xff\xff\x0f", EncodeUint32(7, 0xffffffff));
+  EXPECT_EQ("\x3f\xc0\xff\xff\xff\x0f", EncodeUint32(6, 0xffffffff));
+  EXPECT_EQ("\x1f\xe0\xff\xff\xff\x0f", EncodeUint32(5, 0xffffffff));
+  EXPECT_EQ("\x0f\xf0\xff\xff\xff\x0f", EncodeUint32(4, 0xffffffff));
+  EXPECT_EQ("\x07\xf8\xff\xff\xff\x0f", EncodeUint32(3, 0xffffffff));
+  EXPECT_EQ("\x03\xfc\xff\xff\xff\x0f", EncodeUint32(2, 0xffffffff));
+  EXPECT_EQ("\x01\xfe\xff\xff\xff\x0f", EncodeUint32(1, 0xffffffff));
+}
+
+// Test that encoding an integer with an N-bit prefix preserves the
+// upper (8-N) bits of the first byte.
+TEST(HpackOutputStreamTest, AppendUint32PreservesUpperBits) {
+  HpackOutputStream output_stream;
+  output_stream.AppendBits(0x7f, 7);
+  output_stream.AppendUint32(0x01);
+  std::string str = output_stream.TakeString();
+  EXPECT_EQ(std::string("\xff\x00", 2), str);
+}
+
+TEST(HpackOutputStreamTest, AppendBytes) {
+  HpackOutputStream output_stream;
+
+  output_stream.AppendBytes("buffer1");
+  output_stream.AppendBytes("buffer2");
+
+  std::string str = output_stream.TakeString();
+  EXPECT_EQ("buffer1buffer2", str);
+}
+
+TEST(HpackOutputStreamTest, BoundedTakeString) {
+  HpackOutputStream output_stream;
+
+  output_stream.AppendBytes("buffer12");
+  output_stream.AppendBytes("buffer456");
+
+  std::string str = output_stream.BoundedTakeString(9);
+  EXPECT_EQ("buffer12b", str);
+
+  output_stream.AppendBits(0x7f, 7);
+  output_stream.AppendUint32(0x11);
+  str = output_stream.BoundedTakeString(9);
+  EXPECT_EQ("uffer456\xff", str);
+
+  str = output_stream.BoundedTakeString(9);
+  EXPECT_EQ("\x10", str);
+}
+
+TEST(HpackOutputStreamTest, MutableString) {
+  HpackOutputStream output_stream;
+
+  output_stream.AppendBytes("1");
+  output_stream.MutableString()->append("2");
+
+  output_stream.AppendBytes("foo");
+  output_stream.MutableString()->append("bar");
+
+  std::string str = output_stream.TakeString();
+  EXPECT_EQ("12foobar", str);
+}
+
+}  // namespace
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_round_trip_test.cc b/quiche/spdy/core/hpack/hpack_round_trip_test.cc
new file mode 100644
index 0000000..7a9a262
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_round_trip_test.cc
@@ -0,0 +1,224 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cmath>
+#include <cstdint>
+#include <ctime>
+#include <vector>
+
+#include "quiche/http2/test_tools/http2_random.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_decoder_adapter.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+namespace spdy {
+namespace test {
+
+namespace {
+
+// Supports testing with the input split at every byte boundary.
+enum InputSizeParam { ALL_INPUT, ONE_BYTE, ZERO_THEN_ONE_BYTE };
+
+class HpackRoundTripTest : public QuicheTestWithParam<InputSizeParam> {
+ protected:
+  void SetUp() override {
+    // Use a small table size to tickle eviction handling.
+    encoder_.ApplyHeaderTableSizeSetting(256);
+    decoder_.ApplyHeaderTableSizeSetting(256);
+  }
+
+  bool RoundTrip(const SpdyHeaderBlock& header_set) {
+    std::string encoded = encoder_.EncodeHeaderBlock(header_set);
+
+    bool success = true;
+    if (GetParam() == ALL_INPUT) {
+      // Pass all the input to the decoder at once.
+      success = decoder_.HandleControlFrameHeadersData(encoded.data(),
+                                                       encoded.size());
+    } else if (GetParam() == ONE_BYTE) {
+      // Pass the input to the decoder one byte at a time.
+      const char* data = encoded.data();
+      for (size_t ndx = 0; ndx < encoded.size() && success; ++ndx) {
+        success = decoder_.HandleControlFrameHeadersData(data + ndx, 1);
+      }
+    } else if (GetParam() == ZERO_THEN_ONE_BYTE) {
+      // Pass the input to the decoder one byte at a time, but before each
+      // byte pass an empty buffer.
+      const char* data = encoded.data();
+      for (size_t ndx = 0; ndx < encoded.size() && success; ++ndx) {
+        success = (decoder_.HandleControlFrameHeadersData(data + ndx, 0) &&
+                   decoder_.HandleControlFrameHeadersData(data + ndx, 1));
+      }
+    } else {
+      ADD_FAILURE() << "Unknown param: " << GetParam();
+    }
+
+    if (success) {
+      success = decoder_.HandleControlFrameHeadersComplete();
+    }
+
+    EXPECT_EQ(header_set, decoder_.decoded_block());
+    return success;
+  }
+
+  size_t SampleExponential(size_t mean, size_t sanity_bound) {
+    return std::min<size_t>(-std::log(random_.RandDouble()) * mean,
+                            sanity_bound);
+  }
+
+  http2::test::Http2Random random_;
+  HpackEncoder encoder_;
+  HpackDecoderAdapter decoder_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests,
+                         HpackRoundTripTest,
+                         ::testing::Values(ALL_INPUT,
+                                           ONE_BYTE,
+                                           ZERO_THEN_ONE_BYTE));
+
+TEST_P(HpackRoundTripTest, ResponseFixtures) {
+  {
+    SpdyHeaderBlock headers;
+    headers[":status"] = "302";
+    headers["cache-control"] = "private";
+    headers["date"] = "Mon, 21 Oct 2013 20:13:21 GMT";
+    headers["location"] = "https://www.example.com";
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+  {
+    SpdyHeaderBlock headers;
+    headers[":status"] = "200";
+    headers["cache-control"] = "private";
+    headers["date"] = "Mon, 21 Oct 2013 20:13:21 GMT";
+    headers["location"] = "https://www.example.com";
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+  {
+    SpdyHeaderBlock headers;
+    headers[":status"] = "200";
+    headers["cache-control"] = "private";
+    headers["content-encoding"] = "gzip";
+    headers["date"] = "Mon, 21 Oct 2013 20:13:22 GMT";
+    headers["location"] = "https://www.example.com";
+    headers["set-cookie"] =
+        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;"
+        " max-age=3600; version=1";
+    headers["multivalue"] = std::string("foo\0bar", 7);
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+}
+
+TEST_P(HpackRoundTripTest, RequestFixtures) {
+  {
+    SpdyHeaderBlock headers;
+    headers[":authority"] = "www.example.com";
+    headers[":method"] = "GET";
+    headers[":path"] = "/";
+    headers[":scheme"] = "http";
+    headers["cookie"] = "baz=bing; foo=bar";
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+  {
+    SpdyHeaderBlock headers;
+    headers[":authority"] = "www.example.com";
+    headers[":method"] = "GET";
+    headers[":path"] = "/";
+    headers[":scheme"] = "http";
+    headers["cache-control"] = "no-cache";
+    headers["cookie"] = "foo=bar; spam=eggs";
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+  {
+    SpdyHeaderBlock headers;
+    headers[":authority"] = "www.example.com";
+    headers[":method"] = "GET";
+    headers[":path"] = "/index.html";
+    headers[":scheme"] = "https";
+    headers["custom-key"] = "custom-value";
+    headers["cookie"] = "baz=bing; fizzle=fazzle; garbage";
+    headers["multivalue"] = std::string("foo\0bar", 7);
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+}
+
+TEST_P(HpackRoundTripTest, RandomizedExamples) {
+  // Grow vectors of names & values, which are seeded with fixtures and then
+  // expanded with dynamically generated data. Samples are taken using the
+  // exponential distribution.
+  std::vector<std::string> pseudo_header_names, random_header_names;
+  pseudo_header_names.push_back(":authority");
+  pseudo_header_names.push_back(":path");
+  pseudo_header_names.push_back(":status");
+
+  // TODO(jgraettinger): Enable "cookie" as a name fixture. Crumbs may be
+  // reconstructed in any order, which breaks the simple validation used here.
+
+  std::vector<std::string> values;
+  values.push_back("/");
+  values.push_back("/index.html");
+  values.push_back("200");
+  values.push_back("404");
+  values.push_back("");
+  values.push_back("baz=bing; foo=bar; garbage");
+  values.push_back("baz=bing; fizzle=fazzle; garbage");
+
+  for (size_t i = 0; i != 2000; ++i) {
+    SpdyHeaderBlock headers;
+
+    // Choose a random number of headers to add, and of these a random subset
+    // will be HTTP/2 pseudo headers.
+    size_t header_count = 1 + SampleExponential(7, 50);
+    size_t pseudo_header_count =
+        std::min(header_count, 1 + SampleExponential(7, 50));
+    EXPECT_LE(pseudo_header_count, header_count);
+    for (size_t j = 0; j != header_count; ++j) {
+      std::string name, value;
+      // Pseudo headers must be added before regular headers.
+      if (j < pseudo_header_count) {
+        // Choose one of the defined pseudo headers at random.
+        size_t name_index = random_.Uniform(pseudo_header_names.size());
+        name = pseudo_header_names[name_index];
+      } else {
+        // Randomly reuse an existing header name, or generate a new one.
+        size_t name_index = SampleExponential(20, 200);
+        if (name_index >= random_header_names.size()) {
+          name = random_.RandString(1 + SampleExponential(5, 30));
+          // A regular header cannot begin with the pseudo header prefix ":".
+          if (name[0] == ':') {
+            name[0] = 'x';
+          }
+          random_header_names.push_back(name);
+        } else {
+          name = random_header_names[name_index];
+        }
+      }
+
+      // Randomly reuse an existing value, or generate a new one.
+      size_t value_index = SampleExponential(20, 200);
+      if (value_index >= values.size()) {
+        std::string newvalue =
+            random_.RandString(1 + SampleExponential(15, 75));
+        // Currently order is not preserved in the encoder.  In particular,
+        // when a value is decomposed at \0 delimiters, its parts might get
+        // encoded out of order if some but not all of them already exist in
+        // the header table.  For now, avoid \0 bytes in values.
+        std::replace(newvalue.begin(), newvalue.end(), '\x00', '\x01');
+        values.push_back(newvalue);
+        value = values.back();
+      } else {
+        value = values[value_index];
+      }
+      headers[name] = value;
+    }
+    EXPECT_TRUE(RoundTrip(headers));
+  }
+}
+
+}  // namespace
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_static_table.cc b/quiche/spdy/core/hpack/hpack_static_table.cc
new file mode 100644
index 0000000..a443283
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_static_table.cc
@@ -0,0 +1,50 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+#include "quiche/spdy/core/hpack/hpack_entry.h"
+
+namespace spdy {
+
+HpackStaticTable::HpackStaticTable() = default;
+
+HpackStaticTable::~HpackStaticTable() = default;
+
+void HpackStaticTable::Initialize(const HpackStaticEntry* static_entry_table,
+                                  size_t static_entry_count) {
+  QUICHE_CHECK(!IsInitialized());
+
+  static_entries_.reserve(static_entry_count);
+
+  for (const HpackStaticEntry* it = static_entry_table;
+       it != static_entry_table + static_entry_count; ++it) {
+    std::string name(it->name, it->name_len);
+    std::string value(it->value, it->value_len);
+    static_entries_.push_back(HpackEntry(std::move(name), std::move(value)));
+  }
+
+  // |static_entries_| will not be mutated any more.  Therefore its entries will
+  // remain stable even if the container does not have iterator stability.
+  int insertion_count = 0;
+  for (const auto& entry : static_entries_) {
+    auto result = static_index_.insert(std::make_pair(
+        HpackLookupEntry{entry.name(), entry.value()}, insertion_count));
+    QUICHE_CHECK(result.second);
+
+    // Multiple static entries may have the same name, so inserts may fail.
+    static_name_index_.insert(std::make_pair(entry.name(), insertion_count));
+
+    ++insertion_count;
+  }
+}
+
+bool HpackStaticTable::IsInitialized() const {
+  return !static_entries_.empty();
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/hpack/hpack_static_table.h b/quiche/spdy/core/hpack/hpack_static_table.h
new file mode 100644
index 0000000..fda34d1
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_static_table.h
@@ -0,0 +1,56 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
+#define QUICHE_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+
+namespace spdy {
+
+struct HpackStaticEntry;
+
+// Number of entries in the HPACK static table.
+constexpr size_t kStaticTableSize = 61;
+
+// HpackStaticTable provides |static_entries_| and |static_index_| for HPACK
+// encoding and decoding contexts.  Once initialized, an instance is read only
+// and may be accessed only through its const interface.  Such an instance may
+// be shared accross multiple HPACK contexts.
+class QUICHE_EXPORT_PRIVATE HpackStaticTable {
+ public:
+  HpackStaticTable();
+  ~HpackStaticTable();
+
+  // Prepares HpackStaticTable by filling up static_entries_ and static_index_
+  // from an array of struct HpackStaticEntry.  Must be called exactly once.
+  void Initialize(const HpackStaticEntry* static_entry_table,
+                  size_t static_entry_count);
+
+  // Returns whether Initialize() has been called.
+  bool IsInitialized() const;
+
+  // Accessors.
+  const HpackHeaderTable::StaticEntryTable& GetStaticEntries() const {
+    return static_entries_;
+  }
+  const HpackHeaderTable::NameValueToEntryMap& GetStaticIndex() const {
+    return static_index_;
+  }
+  const HpackHeaderTable::NameToEntryMap& GetStaticNameIndex() const {
+    return static_name_index_;
+  }
+
+ private:
+  HpackHeaderTable::StaticEntryTable static_entries_;
+  // The following two members have string_views that point to strings stored in
+  // |static_entries_|.
+  HpackHeaderTable::NameValueToEntryMap static_index_;
+  HpackHeaderTable::NameToEntryMap static_name_index_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
diff --git a/quiche/spdy/core/hpack/hpack_static_table_test.cc b/quiche/spdy/core/hpack/hpack_static_table_test.cc
new file mode 100644
index 0000000..e0577a0
--- /dev/null
+++ b/quiche/spdy/core/hpack/hpack_static_table_test.cc
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/hpack/hpack_static_table.h"
+
+#include <set>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/hpack/hpack_constants.h"
+
+namespace spdy {
+
+namespace test {
+
+namespace {
+
+class HpackStaticTableTest : public QuicheTest {
+ protected:
+  HpackStaticTableTest() : table_() {}
+
+  HpackStaticTable table_;
+};
+
+// Check that an initialized instance has the right number of entries.
+TEST_F(HpackStaticTableTest, Initialize) {
+  EXPECT_FALSE(table_.IsInitialized());
+  table_.Initialize(HpackStaticTableVector().data(),
+                    HpackStaticTableVector().size());
+  EXPECT_TRUE(table_.IsInitialized());
+
+  const HpackHeaderTable::StaticEntryTable& static_entries =
+      table_.GetStaticEntries();
+  EXPECT_EQ(kStaticTableSize, static_entries.size());
+
+  const HpackHeaderTable::NameValueToEntryMap& static_index =
+      table_.GetStaticIndex();
+  EXPECT_EQ(kStaticTableSize, static_index.size());
+
+  const HpackHeaderTable::NameToEntryMap& static_name_index =
+      table_.GetStaticNameIndex();
+  // Count distinct names in static table.
+  std::set<absl::string_view> names;
+  for (const auto& entry : static_entries) {
+    names.insert(entry.name());
+  }
+  EXPECT_EQ(names.size(), static_name_index.size());
+}
+
+// Test that ObtainHpackStaticTable returns the same instance every time.
+TEST_F(HpackStaticTableTest, IsSingleton) {
+  const HpackStaticTable* static_table_one = &ObtainHpackStaticTable();
+  const HpackStaticTable* static_table_two = &ObtainHpackStaticTable();
+  EXPECT_EQ(static_table_one, static_table_two);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/http2_frame_decoder_adapter.cc b/quiche/spdy/core/http2_frame_decoder_adapter.cc
new file mode 100644
index 0000000..d5ebcab
--- /dev/null
+++ b/quiche/spdy/core/http2_frame_decoder_adapter.cc
@@ -0,0 +1,1107 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+
+// Logging policy: If an error in the input is detected, QUICHE_VLOG(n) is used
+// so that the option exists to debug the situation. Otherwise, this code mostly
+// uses QUICHE_DVLOG so that the logging does not slow down production code when
+// things are working OK.
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <cstring>
+#include <utility>
+
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/decoder/decode_status.h"
+#include "quiche/http2/decoder/http2_frame_decoder.h"
+#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
+#include "quiche/http2/http2_constants.h"
+#include "quiche/http2/http2_structures.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/spdy/core/hpack/hpack_decoder_adapter.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+using ::spdy::ExtensionVisitorInterface;
+using ::spdy::HpackDecoderAdapter;
+using ::spdy::HpackHeaderTable;
+using ::spdy::ParseErrorCode;
+using ::spdy::ParseFrameType;
+using ::spdy::SpdyAltSvcWireFormat;
+using ::spdy::SpdyErrorCode;
+using ::spdy::SpdyFramerDebugVisitorInterface;
+using ::spdy::SpdyFramerVisitorInterface;
+using ::spdy::SpdyFrameType;
+using ::spdy::SpdyHeadersHandlerInterface;
+using ::spdy::SpdyKnownSettingsId;
+using ::spdy::SpdySettingsId;
+
+namespace http2 {
+namespace {
+
+const bool kHasPriorityFields = true;
+const bool kNotHasPriorityFields = false;
+
+bool IsPaddable(Http2FrameType type) {
+  return type == Http2FrameType::DATA || type == Http2FrameType::HEADERS ||
+         type == Http2FrameType::PUSH_PROMISE;
+}
+
+SpdyFrameType ToSpdyFrameType(Http2FrameType type) {
+  return ParseFrameType(static_cast<uint8_t>(type));
+}
+
+uint64_t ToSpdyPingId(const Http2PingFields& ping) {
+  uint64_t v;
+  std::memcpy(&v, ping.opaque_bytes, Http2PingFields::EncodedSize());
+  return quiche::QuicheEndian::NetToHost64(v);
+}
+
+// Overwrites the fields of the header with invalid values, for the purpose
+// of identifying reading of unset fields. Only takes effect for debug builds.
+// In Address Sanatizer builds, it also marks the fields as un-readable.
+#ifndef NDEBUG
+void CorruptFrameHeader(Http2FrameHeader* header) {
+  // Beyond a valid payload length, which is 2^24 - 1.
+  header->payload_length = 0x1010dead;
+  // An unsupported frame type.
+  header->type = Http2FrameType(0x80);
+  QUICHE_DCHECK(!IsSupportedHttp2FrameType(header->type));
+  // Frame flag bits that aren't used by any supported frame type.
+  header->flags = Http2FrameFlag(0xd2);
+  // A stream id with the reserved high-bit (R in the RFC) set.
+  // 2129510127 when the high-bit is cleared.
+  header->stream_id = 0xfeedbeef;
+}
+#else
+void CorruptFrameHeader(Http2FrameHeader* /*header*/) {}
+#endif
+
+Http2DecoderAdapter::SpdyFramerError HpackDecodingErrorToSpdyFramerError(
+    HpackDecodingError error) {
+  switch (error) {
+    case HpackDecodingError::kOk:
+      return Http2DecoderAdapter::SpdyFramerError::SPDY_NO_ERROR;
+    case HpackDecodingError::kIndexVarintError:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_INDEX_VARINT_ERROR;
+    case HpackDecodingError::kNameLengthVarintError:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_NAME_LENGTH_VARINT_ERROR;
+    case HpackDecodingError::kValueLengthVarintError:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR;
+    case HpackDecodingError::kNameTooLong:
+      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG;
+    case HpackDecodingError::kValueTooLong:
+      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG;
+    case HpackDecodingError::kNameHuffmanError:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_NAME_HUFFMAN_ERROR;
+    case HpackDecodingError::kValueHuffmanError:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_VALUE_HUFFMAN_ERROR;
+    case HpackDecodingError::kMissingDynamicTableSizeUpdate:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
+    case HpackDecodingError::kInvalidIndex:
+      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX;
+    case HpackDecodingError::kInvalidNameIndex:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_INVALID_NAME_INDEX;
+    case HpackDecodingError::kDynamicTableSizeUpdateNotAllowed:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
+    case HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
+    case HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
+    case HpackDecodingError::kTruncatedBlock:
+      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK;
+    case HpackDecodingError::kFragmentTooLong:
+      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG;
+    case HpackDecodingError::kCompressedHeaderSizeExceedsLimit:
+      return Http2DecoderAdapter::SpdyFramerError::
+          SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
+  }
+
+  return Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE;
+}
+
+}  // namespace
+
+const char* Http2DecoderAdapter::StateToString(int state) {
+  switch (state) {
+    case SPDY_ERROR:
+      return "ERROR";
+    case SPDY_FRAME_COMPLETE:
+      return "FRAME_COMPLETE";
+    case SPDY_READY_FOR_FRAME:
+      return "READY_FOR_FRAME";
+    case SPDY_READING_COMMON_HEADER:
+      return "READING_COMMON_HEADER";
+    case SPDY_CONTROL_FRAME_PAYLOAD:
+      return "CONTROL_FRAME_PAYLOAD";
+    case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
+      return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
+    case SPDY_CONSUME_PADDING:
+      return "SPDY_CONSUME_PADDING";
+    case SPDY_IGNORE_REMAINING_PAYLOAD:
+      return "IGNORE_REMAINING_PAYLOAD";
+    case SPDY_FORWARD_STREAM_FRAME:
+      return "FORWARD_STREAM_FRAME";
+    case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
+      return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
+    case SPDY_CONTROL_FRAME_HEADER_BLOCK:
+      return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
+    case SPDY_GOAWAY_FRAME_PAYLOAD:
+      return "SPDY_GOAWAY_FRAME_PAYLOAD";
+    case SPDY_SETTINGS_FRAME_HEADER:
+      return "SPDY_SETTINGS_FRAME_HEADER";
+    case SPDY_SETTINGS_FRAME_PAYLOAD:
+      return "SPDY_SETTINGS_FRAME_PAYLOAD";
+    case SPDY_ALTSVC_FRAME_PAYLOAD:
+      return "SPDY_ALTSVC_FRAME_PAYLOAD";
+  }
+  return "UNKNOWN_STATE";
+}
+
+const char* Http2DecoderAdapter::SpdyFramerErrorToString(
+    SpdyFramerError spdy_framer_error) {
+  switch (spdy_framer_error) {
+    case SPDY_NO_ERROR:
+      return "NO_ERROR";
+    case SPDY_INVALID_STREAM_ID:
+      return "INVALID_STREAM_ID";
+    case SPDY_INVALID_CONTROL_FRAME:
+      return "INVALID_CONTROL_FRAME";
+    case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
+      return "CONTROL_PAYLOAD_TOO_LARGE";
+    case SPDY_DECOMPRESS_FAILURE:
+      return "DECOMPRESS_FAILURE";
+    case SPDY_INVALID_PADDING:
+      return "INVALID_PADDING";
+    case SPDY_INVALID_DATA_FRAME_FLAGS:
+      return "INVALID_DATA_FRAME_FLAGS";
+    case SPDY_UNEXPECTED_FRAME:
+      return "UNEXPECTED_FRAME";
+    case SPDY_INTERNAL_FRAMER_ERROR:
+      return "INTERNAL_FRAMER_ERROR";
+    case SPDY_INVALID_CONTROL_FRAME_SIZE:
+      return "INVALID_CONTROL_FRAME_SIZE";
+    case SPDY_OVERSIZED_PAYLOAD:
+      return "OVERSIZED_PAYLOAD";
+    case SPDY_HPACK_INDEX_VARINT_ERROR:
+      return "HPACK_INDEX_VARINT_ERROR";
+    case SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
+      return "HPACK_NAME_LENGTH_VARINT_ERROR";
+    case SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
+      return "HPACK_VALUE_LENGTH_VARINT_ERROR";
+    case SPDY_HPACK_NAME_TOO_LONG:
+      return "HPACK_NAME_TOO_LONG";
+    case SPDY_HPACK_VALUE_TOO_LONG:
+      return "HPACK_VALUE_TOO_LONG";
+    case SPDY_HPACK_NAME_HUFFMAN_ERROR:
+      return "HPACK_NAME_HUFFMAN_ERROR";
+    case SPDY_HPACK_VALUE_HUFFMAN_ERROR:
+      return "HPACK_VALUE_HUFFMAN_ERROR";
+    case SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
+      return "HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE";
+    case SPDY_HPACK_INVALID_INDEX:
+      return "HPACK_INVALID_INDEX";
+    case SPDY_HPACK_INVALID_NAME_INDEX:
+      return "HPACK_INVALID_NAME_INDEX";
+    case SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
+      return "HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED";
+    case SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
+      return "HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK";
+    case SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
+      return "HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING";
+    case SPDY_HPACK_TRUNCATED_BLOCK:
+      return "HPACK_TRUNCATED_BLOCK";
+    case SPDY_HPACK_FRAGMENT_TOO_LONG:
+      return "HPACK_FRAGMENT_TOO_LONG";
+    case SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
+      return "HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT";
+    case SPDY_STOP_PROCESSING:
+      return "STOP_PROCESSING";
+    case LAST_ERROR:
+      return "UNKNOWN_ERROR";
+  }
+  return "UNKNOWN_ERROR";
+}
+
+Http2DecoderAdapter::Http2DecoderAdapter() : frame_decoder_(this) {
+  QUICHE_DVLOG(1) << "Http2DecoderAdapter ctor";
+
+  CorruptFrameHeader(&frame_header_);
+  CorruptFrameHeader(&hpack_first_frame_header_);
+}
+
+Http2DecoderAdapter::~Http2DecoderAdapter() = default;
+
+void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) {
+  visitor_ = visitor;
+}
+
+void Http2DecoderAdapter::set_debug_visitor(
+    SpdyFramerDebugVisitorInterface* debug_visitor) {
+  debug_visitor_ = debug_visitor;
+}
+
+void Http2DecoderAdapter::set_extension_visitor(
+    ExtensionVisitorInterface* visitor) {
+  extension_ = visitor;
+}
+
+size_t Http2DecoderAdapter::ProcessInput(const char* data, size_t len) {
+  size_t total_processed = 0;
+  while (len > 0 && spdy_state_ != SPDY_ERROR) {
+    // Process one at a time so that we update the adapter's internal
+    // state appropriately.
+    const size_t processed = ProcessInputFrame(data, len);
+
+    // We had some data, and weren't in an error state, so should have
+    // processed/consumed at least one byte of it, even if we then ended up
+    // in an error state.
+    QUICHE_DCHECK(processed > 0)
+        << "processed=" << processed << "   spdy_state_=" << spdy_state_
+        << "   spdy_framer_error_=" << spdy_framer_error_;
+
+    data += processed;
+    len -= processed;
+    total_processed += processed;
+    if (processed == 0) {
+      break;
+    }
+  }
+  return total_processed;
+}
+
+Http2DecoderAdapter::SpdyState Http2DecoderAdapter::state() const {
+  return spdy_state_;
+}
+
+Http2DecoderAdapter::SpdyFramerError Http2DecoderAdapter::spdy_framer_error()
+    const {
+  return spdy_framer_error_;
+}
+
+bool Http2DecoderAdapter::probable_http_response() const {
+  return latched_probable_http_response_;
+}
+
+void Http2DecoderAdapter::StopProcessing() {
+  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_STOP_PROCESSING,
+                        "Ignoring further events on this connection.");
+}
+
+void Http2DecoderAdapter::SetMaxFrameSize(size_t max_frame_size) {
+  max_frame_size_ = max_frame_size;
+  frame_decoder_.set_maximum_payload_size(max_frame_size);
+}
+
+// ===========================================================================
+// Implementations of the methods declared by Http2FrameDecoderListener.
+
+// Called once the common frame header has been decoded for any frame.
+// This function is largely based on Http2DecoderAdapter::ValidateFrameHeader
+// and some parts of Http2DecoderAdapter::ProcessCommonHeader.
+bool Http2DecoderAdapter::OnFrameHeader(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnFrameHeader: " << header;
+  decoded_frame_header_ = true;
+  if (!latched_probable_http_response_) {
+    latched_probable_http_response_ = header.IsProbableHttpResponse();
+  }
+  const uint8_t raw_frame_type = static_cast<uint8_t>(header.type);
+  visitor()->OnCommonHeader(header.stream_id, header.payload_length,
+                            raw_frame_type, header.flags);
+  if (has_expected_frame_type_ && header.type != expected_frame_type_) {
+    // Report an unexpected frame error and close the connection if we
+    // expect a known frame type (probably CONTINUATION) and receive an
+    // unknown frame.
+    QUICHE_VLOG(1) << "The framer was expecting to receive a "
+                   << expected_frame_type_
+                   << " frame, but instead received an unknown frame of type "
+                   << header.type;
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
+    return false;
+  }
+  if (!IsSupportedHttp2FrameType(header.type)) {
+    if (extension_ != nullptr) {
+      // Unknown frames will be passed to the registered extension.
+      return true;
+    }
+    // In HTTP2 we ignore unknown frame types for extensibility, as long as
+    // the rest of the control frame header is valid.
+    // We rely on the visitor to check validity of stream_id.
+    bool valid_stream =
+        visitor()->OnUnknownFrame(header.stream_id, raw_frame_type);
+    if (!valid_stream) {
+      // Report an invalid frame error if the stream_id is not valid.
+      QUICHE_VLOG(1) << "Unknown control frame type " << header.type
+                     << " received on invalid stream " << header.stream_id;
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
+      return false;
+    } else {
+      QUICHE_DVLOG(1) << "Ignoring unknown frame type " << header.type;
+      return true;
+    }
+  }
+
+  SpdyFrameType frame_type = ToSpdyFrameType(header.type);
+  if (!IsValidHTTP2FrameStreamId(header.stream_id, frame_type)) {
+    QUICHE_VLOG(1) << "The framer received an invalid streamID of "
+                   << header.stream_id << " for a frame of type "
+                   << header.type;
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
+    return false;
+  }
+
+  if (has_expected_frame_type_ && header.type != expected_frame_type_) {
+    QUICHE_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
+                   << header.type;
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
+    return false;
+  }
+
+  if (!has_expected_frame_type_ &&
+      header.type == Http2FrameType::CONTINUATION) {
+    QUICHE_VLOG(1) << "Got CONTINUATION frame when not expected.";
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
+    return false;
+  }
+
+  if (header.type == Http2FrameType::DATA) {
+    // For some reason SpdyFramer still rejects invalid DATA frame flags.
+    uint8_t valid_flags = Http2FrameFlag::PADDED | Http2FrameFlag::END_STREAM;
+    if (header.HasAnyFlags(~valid_flags)) {
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS, "");
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void Http2DecoderAdapter::OnDataStart(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnDataStart: " << header;
+
+  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
+    frame_header_ = header;
+    has_frame_header_ = true;
+    visitor()->OnDataFrameHeader(header.stream_id, header.payload_length,
+                                 header.IsEndStream());
+  }
+}
+
+void Http2DecoderAdapter::OnDataPayload(const char* data, size_t len) {
+  QUICHE_DVLOG(1) << "OnDataPayload: len=" << len;
+  QUICHE_DCHECK(has_frame_header_);
+  QUICHE_DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
+  visitor()->OnStreamFrameData(frame_header().stream_id, data, len);
+}
+
+void Http2DecoderAdapter::OnDataEnd() {
+  QUICHE_DVLOG(1) << "OnDataEnd";
+  QUICHE_DCHECK(has_frame_header_);
+  QUICHE_DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
+  if (frame_header().IsEndStream()) {
+    visitor()->OnStreamEnd(frame_header().stream_id);
+  }
+  opt_pad_length_.reset();
+}
+
+void Http2DecoderAdapter::OnHeadersStart(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnHeadersStart: " << header;
+  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
+    frame_header_ = header;
+    has_frame_header_ = true;
+    if (header.HasPriority()) {
+      // Once we've got the priority fields, then we can report the arrival
+      // of this HEADERS frame.
+      on_headers_called_ = false;
+      return;
+    }
+    on_headers_called_ = true;
+    ReportReceiveCompressedFrame(header);
+    visitor()->OnHeaders(header.stream_id, kNotHasPriorityFields,
+                         0,      // priority
+                         0,      // parent_stream_id
+                         false,  // exclusive
+                         header.IsEndStream(), header.IsEndHeaders());
+    CommonStartHpackBlock();
+  }
+}
+
+void Http2DecoderAdapter::OnHeadersPriority(
+    const Http2PriorityFields& priority) {
+  QUICHE_DVLOG(1) << "OnHeadersPriority: " << priority;
+  QUICHE_DCHECK(has_frame_header_);
+  QUICHE_DCHECK_EQ(frame_type(), Http2FrameType::HEADERS) << frame_header_;
+  QUICHE_DCHECK(frame_header_.HasPriority());
+  QUICHE_DCHECK(!on_headers_called_);
+  on_headers_called_ = true;
+  ReportReceiveCompressedFrame(frame_header_);
+  if (!visitor()) {
+    QUICHE_BUG(spdy_bug_1_1)
+        << "Visitor is nullptr, handling priority in headers failed."
+        << " priority:" << priority << " frame_header:" << frame_header_;
+    return;
+  }
+  visitor()->OnHeaders(frame_header_.stream_id, kHasPriorityFields,
+                       priority.weight, priority.stream_dependency,
+                       priority.is_exclusive, frame_header_.IsEndStream(),
+                       frame_header_.IsEndHeaders());
+  CommonStartHpackBlock();
+}
+
+void Http2DecoderAdapter::OnHpackFragment(const char* data, size_t len) {
+  QUICHE_DVLOG(1) << "OnHpackFragment: len=" << len;
+  on_hpack_fragment_called_ = true;
+  auto* decoder = GetHpackDecoder();
+  if (!decoder->HandleControlFrameHeadersData(data, len)) {
+    SetSpdyErrorAndNotify(HpackDecodingErrorToSpdyFramerError(decoder->error()),
+                          decoder->detailed_error());
+    return;
+  }
+}
+
+void Http2DecoderAdapter::OnHeadersEnd() {
+  QUICHE_DVLOG(1) << "OnHeadersEnd";
+  CommonHpackFragmentEnd();
+  opt_pad_length_.reset();
+}
+
+void Http2DecoderAdapter::OnPriorityFrame(const Http2FrameHeader& header,
+                                          const Http2PriorityFields& priority) {
+  QUICHE_DVLOG(1) << "OnPriorityFrame: " << header
+                  << "; priority: " << priority;
+  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
+    visitor()->OnPriority(header.stream_id, priority.stream_dependency,
+                          priority.weight, priority.is_exclusive);
+  }
+}
+
+void Http2DecoderAdapter::OnContinuationStart(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnContinuationStart: " << header;
+  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
+    QUICHE_DCHECK(has_hpack_first_frame_header_);
+    if (header.stream_id != hpack_first_frame_header_.stream_id) {
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
+      return;
+    }
+    frame_header_ = header;
+    has_frame_header_ = true;
+    ReportReceiveCompressedFrame(header);
+    visitor()->OnContinuation(header.stream_id, header.IsEndHeaders());
+  }
+}
+
+void Http2DecoderAdapter::OnContinuationEnd() {
+  QUICHE_DVLOG(1) << "OnContinuationEnd";
+  CommonHpackFragmentEnd();
+}
+
+void Http2DecoderAdapter::OnPadLength(size_t trailing_length) {
+  QUICHE_DVLOG(1) << "OnPadLength: " << trailing_length;
+  opt_pad_length_ = trailing_length;
+  QUICHE_DCHECK_LT(trailing_length, 256u);
+  if (frame_header_.type == Http2FrameType::DATA) {
+    visitor()->OnStreamPadLength(stream_id(), trailing_length);
+  }
+}
+
+void Http2DecoderAdapter::OnPadding(const char* /*padding*/,
+                                    size_t skipped_length) {
+  QUICHE_DVLOG(1) << "OnPadding: " << skipped_length;
+  if (frame_header_.type == Http2FrameType::DATA) {
+    visitor()->OnStreamPadding(stream_id(), skipped_length);
+  } else {
+    MaybeAnnounceEmptyFirstHpackFragment();
+  }
+}
+
+void Http2DecoderAdapter::OnRstStream(const Http2FrameHeader& header,
+                                      Http2ErrorCode http2_error_code) {
+  QUICHE_DVLOG(1) << "OnRstStream: " << header << "; code=" << http2_error_code;
+  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
+    SpdyErrorCode error_code =
+        ParseErrorCode(static_cast<uint32_t>(http2_error_code));
+    visitor()->OnRstStream(header.stream_id, error_code);
+  }
+}
+
+void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnSettingsStart: " << header;
+  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
+    frame_header_ = header;
+    has_frame_header_ = true;
+    visitor()->OnSettings();
+  }
+}
+
+void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) {
+  QUICHE_DVLOG(1) << "OnSetting: " << setting_fields;
+  const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter);
+  visitor()->OnSetting(parameter, setting_fields.value);
+  SpdyKnownSettingsId known_id;
+  if (extension_ != nullptr && !spdy::ParseSettingsId(parameter, &known_id)) {
+    extension_->OnSetting(parameter, setting_fields.value);
+  }
+}
+
+void Http2DecoderAdapter::OnSettingsEnd() {
+  QUICHE_DVLOG(1) << "OnSettingsEnd";
+  visitor()->OnSettingsEnd();
+}
+
+void Http2DecoderAdapter::OnSettingsAck(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnSettingsAck: " << header;
+  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
+    visitor()->OnSettingsAck();
+  }
+}
+
+void Http2DecoderAdapter::OnPushPromiseStart(
+    const Http2FrameHeader& header,
+    const Http2PushPromiseFields& promise,
+    size_t total_padding_length) {
+  QUICHE_DVLOG(1) << "OnPushPromiseStart: " << header
+                  << "; promise: " << promise
+                  << "; total_padding_length: " << total_padding_length;
+  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
+    if (promise.promised_stream_id == 0) {
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
+      return;
+    }
+    frame_header_ = header;
+    has_frame_header_ = true;
+    ReportReceiveCompressedFrame(header);
+    visitor()->OnPushPromise(header.stream_id, promise.promised_stream_id,
+                             header.IsEndHeaders());
+    CommonStartHpackBlock();
+  }
+}
+
+void Http2DecoderAdapter::OnPushPromiseEnd() {
+  QUICHE_DVLOG(1) << "OnPushPromiseEnd";
+  CommonHpackFragmentEnd();
+  opt_pad_length_.reset();
+}
+
+void Http2DecoderAdapter::OnPing(const Http2FrameHeader& header,
+                                 const Http2PingFields& ping) {
+  QUICHE_DVLOG(1) << "OnPing: " << header << "; ping: " << ping;
+  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
+    visitor()->OnPing(ToSpdyPingId(ping), false);
+  }
+}
+
+void Http2DecoderAdapter::OnPingAck(const Http2FrameHeader& header,
+                                    const Http2PingFields& ping) {
+  QUICHE_DVLOG(1) << "OnPingAck: " << header << "; ping: " << ping;
+  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
+    visitor()->OnPing(ToSpdyPingId(ping), true);
+  }
+}
+
+void Http2DecoderAdapter::OnGoAwayStart(const Http2FrameHeader& header,
+                                        const Http2GoAwayFields& goaway) {
+  QUICHE_DVLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway;
+  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
+    frame_header_ = header;
+    has_frame_header_ = true;
+    SpdyErrorCode error_code =
+        ParseErrorCode(static_cast<uint32_t>(goaway.error_code));
+    visitor()->OnGoAway(goaway.last_stream_id, error_code);
+  }
+}
+
+void Http2DecoderAdapter::OnGoAwayOpaqueData(const char* data, size_t len) {
+  QUICHE_DVLOG(1) << "OnGoAwayOpaqueData: len=" << len;
+  visitor()->OnGoAwayFrameData(data, len);
+}
+
+void Http2DecoderAdapter::OnGoAwayEnd() {
+  QUICHE_DVLOG(1) << "OnGoAwayEnd";
+  visitor()->OnGoAwayFrameData(nullptr, 0);
+}
+
+void Http2DecoderAdapter::OnWindowUpdate(const Http2FrameHeader& header,
+                                         uint32_t increment) {
+  QUICHE_DVLOG(1) << "OnWindowUpdate: " << header
+                  << "; increment=" << increment;
+  if (IsOkToStartFrame(header)) {
+    visitor()->OnWindowUpdate(header.stream_id, increment);
+  }
+}
+
+// Per RFC7838, an ALTSVC frame on stream 0 with origin_length == 0, or one on
+// a stream other than stream 0 with origin_length != 0 MUST be ignored.  All
+// frames are decoded by Http2DecoderAdapter, and it is left to the consumer
+// (listener) to implement this behavior.
+void Http2DecoderAdapter::OnAltSvcStart(const Http2FrameHeader& header,
+                                        size_t origin_length,
+                                        size_t value_length) {
+  QUICHE_DVLOG(1) << "OnAltSvcStart: " << header
+                  << "; origin_length: " << origin_length
+                  << "; value_length: " << value_length;
+  if (!IsOkToStartFrame(header)) {
+    return;
+  }
+  frame_header_ = header;
+  has_frame_header_ = true;
+  alt_svc_origin_.clear();
+  alt_svc_value_.clear();
+}
+
+void Http2DecoderAdapter::OnAltSvcOriginData(const char* data, size_t len) {
+  QUICHE_DVLOG(1) << "OnAltSvcOriginData: len=" << len;
+  alt_svc_origin_.append(data, len);
+}
+
+// Called when decoding the Alt-Svc-Field-Value of an ALTSVC;
+// the field is uninterpreted.
+void Http2DecoderAdapter::OnAltSvcValueData(const char* data, size_t len) {
+  QUICHE_DVLOG(1) << "OnAltSvcValueData: len=" << len;
+  alt_svc_value_.append(data, len);
+}
+
+void Http2DecoderAdapter::OnAltSvcEnd() {
+  QUICHE_DVLOG(1) << "OnAltSvcEnd: origin.size(): " << alt_svc_origin_.size()
+                  << "; value.size(): " << alt_svc_value_.size();
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(alt_svc_value_,
+                                                   &altsvc_vector)) {
+    QUICHE_DLOG(ERROR) << "SpdyAltSvcWireFormat::ParseHeaderFieldValue failed.";
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
+    return;
+  }
+  visitor()->OnAltSvc(frame_header_.stream_id, alt_svc_origin_, altsvc_vector);
+  // We assume that ALTSVC frames are rare, so get rid of the storage.
+  alt_svc_origin_.clear();
+  alt_svc_origin_.shrink_to_fit();
+  alt_svc_value_.clear();
+  alt_svc_value_.shrink_to_fit();
+}
+
+void Http2DecoderAdapter::OnPriorityUpdateStart(
+    const Http2FrameHeader& header,
+    const Http2PriorityUpdateFields& priority_update) {
+  QUICHE_DVLOG(1) << "OnPriorityUpdateStart: " << header
+                  << "; prioritized_stream_id: "
+                  << priority_update.prioritized_stream_id;
+  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header) &&
+      HasRequiredStreamId(priority_update.prioritized_stream_id)) {
+    frame_header_ = header;
+    has_frame_header_ = true;
+    prioritized_stream_id_ = priority_update.prioritized_stream_id;
+  }
+}
+
+void Http2DecoderAdapter::OnPriorityUpdatePayload(const char* data,
+                                                  size_t len) {
+  QUICHE_DVLOG(1) << "OnPriorityUpdatePayload: len=" << len;
+  priority_field_value_.append(data, len);
+}
+
+void Http2DecoderAdapter::OnPriorityUpdateEnd() {
+  QUICHE_DVLOG(1) << "OnPriorityUpdateEnd: priority_field_value.size(): "
+                  << priority_field_value_.size();
+  visitor()->OnPriorityUpdate(prioritized_stream_id_, priority_field_value_);
+  priority_field_value_.clear();
+}
+
+// Except for BLOCKED frames, all other unknown frames are either dropped or
+// passed to a registered extension.
+void Http2DecoderAdapter::OnUnknownStart(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnUnknownStart: " << header;
+  if (IsOkToStartFrame(header)) {
+    if (extension_ != nullptr) {
+      const uint8_t type = static_cast<uint8_t>(header.type);
+      const uint8_t flags = static_cast<uint8_t>(header.flags);
+      handling_extension_payload_ = extension_->OnFrameHeader(
+          header.stream_id, header.payload_length, type, flags);
+    }
+  }
+}
+
+void Http2DecoderAdapter::OnUnknownPayload(const char* data, size_t len) {
+  if (handling_extension_payload_) {
+    extension_->OnFramePayload(data, len);
+  } else {
+    QUICHE_DVLOG(1) << "OnUnknownPayload: len=" << len;
+  }
+}
+
+void Http2DecoderAdapter::OnUnknownEnd() {
+  QUICHE_DVLOG(1) << "OnUnknownEnd";
+  handling_extension_payload_ = false;
+}
+
+void Http2DecoderAdapter::OnPaddingTooLong(const Http2FrameHeader& header,
+                                           size_t missing_length) {
+  QUICHE_DVLOG(1) << "OnPaddingTooLong: " << header
+                  << "; missing_length: " << missing_length;
+  if (header.type == Http2FrameType::DATA) {
+    if (header.payload_length == 0) {
+      QUICHE_DCHECK_EQ(1u, missing_length);
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS, "");
+      return;
+    }
+    visitor()->OnStreamPadding(header.stream_id, 1);
+  }
+  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_PADDING, "");
+}
+
+void Http2DecoderAdapter::OnFrameSizeError(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(1) << "OnFrameSizeError: " << header;
+  if (header.payload_length > max_frame_size_) {
+    if (header.type == Http2FrameType::DATA) {
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_OVERSIZED_PAYLOAD, "");
+    } else {
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
+                            "");
+    }
+    return;
+  }
+  switch (header.type) {
+    case Http2FrameType::GOAWAY:
+    case Http2FrameType::ALTSVC:
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
+      break;
+    default:
+      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE,
+                            "");
+  }
+}
+
+// Decodes the input up to the next frame boundary (i.e. at most one frame),
+// stopping early if an error is detected.
+size_t Http2DecoderAdapter::ProcessInputFrame(const char* data, size_t len) {
+  QUICHE_DCHECK_NE(spdy_state_, SpdyState::SPDY_ERROR);
+  DecodeBuffer db(data, len);
+  DecodeStatus status = frame_decoder_.DecodeFrame(&db);
+  if (spdy_state_ != SpdyState::SPDY_ERROR) {
+    DetermineSpdyState(status);
+  } else {
+    QUICHE_VLOG(1) << "ProcessInputFrame spdy_framer_error_="
+                   << SpdyFramerErrorToString(spdy_framer_error_);
+    if (spdy_framer_error_ == SpdyFramerError::SPDY_INVALID_PADDING &&
+        has_frame_header_ && frame_type() != Http2FrameType::DATA) {
+      // spdy_framer_test checks that all of the available frame payload
+      // has been consumed, so do that.
+      size_t total = remaining_total_payload();
+      if (total <= frame_header().payload_length) {
+        size_t avail = db.MinLengthRemaining(total);
+        QUICHE_VLOG(1) << "Skipping past " << avail << " bytes, of " << total
+                       << " total remaining in the frame's payload.";
+        db.AdvanceCursor(avail);
+      } else {
+        QUICHE_BUG(spdy_bug_1_2)
+            << "Total remaining (" << total
+            << ") should not be greater than the payload length; "
+            << frame_header();
+      }
+    }
+  }
+  return db.Offset();
+}
+
+// After decoding, determine the next SpdyState. Only called if the current
+// state is NOT SpdyState::SPDY_ERROR (i.e. if none of the callback methods
+// detected an error condition), because otherwise we assume that the callback
+// method has set spdy_framer_error_ appropriately.
+void Http2DecoderAdapter::DetermineSpdyState(DecodeStatus status) {
+  QUICHE_DCHECK_EQ(spdy_framer_error_, SPDY_NO_ERROR);
+  QUICHE_DCHECK(!HasError()) << spdy_framer_error_;
+  switch (status) {
+    case DecodeStatus::kDecodeDone:
+      QUICHE_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeDone";
+      ResetBetweenFrames();
+      break;
+    case DecodeStatus::kDecodeInProgress:
+      QUICHE_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeInProgress";
+      if (decoded_frame_header_) {
+        if (IsDiscardingPayload()) {
+          set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
+        } else if (has_frame_header_ && frame_type() == Http2FrameType::DATA) {
+          if (IsReadingPaddingLength()) {
+            set_spdy_state(SpdyState::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
+          } else if (IsSkippingPadding()) {
+            set_spdy_state(SpdyState::SPDY_CONSUME_PADDING);
+          } else {
+            set_spdy_state(SpdyState::SPDY_FORWARD_STREAM_FRAME);
+          }
+        } else {
+          set_spdy_state(SpdyState::SPDY_CONTROL_FRAME_PAYLOAD);
+        }
+      } else {
+        set_spdy_state(SpdyState::SPDY_READING_COMMON_HEADER);
+      }
+      break;
+    case DecodeStatus::kDecodeError:
+      QUICHE_VLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeError";
+      if (IsDiscardingPayload()) {
+        if (remaining_total_payload() == 0) {
+          // Push the Http2FrameDecoder out of state kDiscardPayload now
+          // since doing so requires no input.
+          DecodeBuffer tmp("", 0);
+          DecodeStatus decode_status = frame_decoder_.DecodeFrame(&tmp);
+          if (decode_status != DecodeStatus::kDecodeDone) {
+            QUICHE_BUG(spdy_bug_1_3)
+                << "Expected to be done decoding the frame, not "
+                << decode_status;
+            SetSpdyErrorAndNotify(SPDY_INTERNAL_FRAMER_ERROR, "");
+          } else if (spdy_framer_error_ != SPDY_NO_ERROR) {
+            QUICHE_BUG(spdy_bug_1_4)
+                << "Expected to have no error, not "
+                << SpdyFramerErrorToString(spdy_framer_error_);
+          } else {
+            ResetBetweenFrames();
+          }
+        } else {
+          set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
+        }
+      } else {
+        SetSpdyErrorAndNotify(SPDY_INVALID_CONTROL_FRAME, "");
+      }
+      break;
+  }
+}
+
+void Http2DecoderAdapter::ResetBetweenFrames() {
+  CorruptFrameHeader(&frame_header_);
+  decoded_frame_header_ = false;
+  has_frame_header_ = false;
+  set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME);
+}
+
+void Http2DecoderAdapter::set_spdy_state(SpdyState v) {
+  QUICHE_DVLOG(2) << "set_spdy_state(" << StateToString(v) << ")";
+  spdy_state_ = v;
+}
+
+void Http2DecoderAdapter::SetSpdyErrorAndNotify(SpdyFramerError error,
+                                                std::string detailed_error) {
+  if (HasError()) {
+    QUICHE_DCHECK_EQ(spdy_state_, SpdyState::SPDY_ERROR);
+  } else {
+    QUICHE_VLOG(2) << "SetSpdyErrorAndNotify(" << SpdyFramerErrorToString(error)
+                   << ")";
+    QUICHE_DCHECK_NE(error, SpdyFramerError::SPDY_NO_ERROR);
+    spdy_framer_error_ = error;
+    set_spdy_state(SpdyState::SPDY_ERROR);
+    frame_decoder_.set_listener(&no_op_listener_);
+    visitor()->OnError(error, detailed_error);
+  }
+}
+
+bool Http2DecoderAdapter::HasError() const {
+  if (spdy_state_ == SpdyState::SPDY_ERROR) {
+    QUICHE_DCHECK_NE(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
+    return true;
+  } else {
+    QUICHE_DCHECK_EQ(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
+    return false;
+  }
+}
+
+const Http2FrameHeader& Http2DecoderAdapter::frame_header() const {
+  QUICHE_DCHECK(has_frame_header_);
+  return frame_header_;
+}
+
+uint32_t Http2DecoderAdapter::stream_id() const {
+  return frame_header().stream_id;
+}
+
+Http2FrameType Http2DecoderAdapter::frame_type() const {
+  return frame_header().type;
+}
+
+size_t Http2DecoderAdapter::remaining_total_payload() const {
+  QUICHE_DCHECK(has_frame_header_);
+  size_t remaining = frame_decoder_.remaining_payload();
+  if (IsPaddable(frame_type()) && frame_header_.IsPadded()) {
+    remaining += frame_decoder_.remaining_padding();
+  }
+  return remaining;
+}
+
+bool Http2DecoderAdapter::IsReadingPaddingLength() {
+  bool result = frame_header_.IsPadded() && !opt_pad_length_;
+  QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsReadingPaddingLength: " << result;
+  return result;
+}
+bool Http2DecoderAdapter::IsSkippingPadding() {
+  bool result = frame_header_.IsPadded() && opt_pad_length_ &&
+                frame_decoder_.remaining_payload() == 0 &&
+                frame_decoder_.remaining_padding() > 0;
+  QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsSkippingPadding: " << result;
+  return result;
+}
+bool Http2DecoderAdapter::IsDiscardingPayload() {
+  bool result = decoded_frame_header_ && frame_decoder_.IsDiscardingPayload();
+  QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsDiscardingPayload: " << result;
+  return result;
+}
+// Called from OnXyz or OnXyzStart methods to decide whether it is OK to
+// handle the callback.
+bool Http2DecoderAdapter::IsOkToStartFrame(const Http2FrameHeader& header) {
+  QUICHE_DVLOG(3) << "IsOkToStartFrame";
+  if (HasError()) {
+    QUICHE_VLOG(2) << "HasError()";
+    return false;
+  }
+  QUICHE_DCHECK(!has_frame_header_);
+  if (has_expected_frame_type_ && header.type != expected_frame_type_) {
+    QUICHE_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
+                   << header.type;
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
+    return false;
+  }
+
+  return true;
+}
+
+bool Http2DecoderAdapter::HasRequiredStreamId(uint32_t stream_id) {
+  QUICHE_DVLOG(3) << "HasRequiredStreamId: " << stream_id;
+  if (HasError()) {
+    QUICHE_VLOG(2) << "HasError()";
+    return false;
+  }
+  if (stream_id != 0) {
+    return true;
+  }
+  QUICHE_VLOG(1) << "Stream Id is required, but zero provided";
+  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
+  return false;
+}
+
+bool Http2DecoderAdapter::HasRequiredStreamId(const Http2FrameHeader& header) {
+  return HasRequiredStreamId(header.stream_id);
+}
+
+bool Http2DecoderAdapter::HasRequiredStreamIdZero(uint32_t stream_id) {
+  QUICHE_DVLOG(3) << "HasRequiredStreamIdZero: " << stream_id;
+  if (HasError()) {
+    QUICHE_VLOG(2) << "HasError()";
+    return false;
+  }
+  if (stream_id == 0) {
+    return true;
+  }
+  QUICHE_VLOG(1) << "Stream Id was not zero, as required: " << stream_id;
+  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
+  return false;
+}
+
+bool Http2DecoderAdapter::HasRequiredStreamIdZero(
+    const Http2FrameHeader& header) {
+  return HasRequiredStreamIdZero(header.stream_id);
+}
+
+void Http2DecoderAdapter::ReportReceiveCompressedFrame(
+    const Http2FrameHeader& header) {
+  if (debug_visitor() != nullptr) {
+    size_t total = header.payload_length + Http2FrameHeader::EncodedSize();
+    debug_visitor()->OnReceiveCompressedFrame(
+        header.stream_id, ToSpdyFrameType(header.type), total);
+  }
+}
+
+HpackDecoderAdapter* Http2DecoderAdapter::GetHpackDecoder() {
+  if (hpack_decoder_ == nullptr) {
+    hpack_decoder_ = std::make_unique<HpackDecoderAdapter>();
+  }
+  return hpack_decoder_.get();
+}
+
+void Http2DecoderAdapter::CommonStartHpackBlock() {
+  QUICHE_DVLOG(1) << "CommonStartHpackBlock";
+  QUICHE_DCHECK(!has_hpack_first_frame_header_);
+  if (!frame_header_.IsEndHeaders()) {
+    hpack_first_frame_header_ = frame_header_;
+    has_hpack_first_frame_header_ = true;
+  } else {
+    CorruptFrameHeader(&hpack_first_frame_header_);
+  }
+  on_hpack_fragment_called_ = false;
+  SpdyHeadersHandlerInterface* handler =
+      visitor()->OnHeaderFrameStart(stream_id());
+  if (handler == nullptr) {
+    QUICHE_BUG(spdy_bug_1_5) << "visitor_->OnHeaderFrameStart returned nullptr";
+    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR, "");
+    return;
+  }
+  GetHpackDecoder()->HandleControlFrameHeadersStart(handler);
+}
+
+// SpdyFramer calls HandleControlFrameHeadersData even if there are zero
+// fragment bytes in the first frame, so do the same.
+void Http2DecoderAdapter::MaybeAnnounceEmptyFirstHpackFragment() {
+  if (!on_hpack_fragment_called_) {
+    OnHpackFragment(nullptr, 0);
+    QUICHE_DCHECK(on_hpack_fragment_called_);
+  }
+}
+
+void Http2DecoderAdapter::CommonHpackFragmentEnd() {
+  QUICHE_DVLOG(1) << "CommonHpackFragmentEnd: stream_id=" << stream_id();
+  if (HasError()) {
+    QUICHE_VLOG(1) << "HasError(), returning";
+    return;
+  }
+  QUICHE_DCHECK(has_frame_header_);
+  MaybeAnnounceEmptyFirstHpackFragment();
+  if (frame_header_.IsEndHeaders()) {
+    QUICHE_DCHECK_EQ(has_hpack_first_frame_header_,
+                     frame_type() == Http2FrameType::CONTINUATION)
+        << frame_header();
+    has_expected_frame_type_ = false;
+    auto* decoder = GetHpackDecoder();
+    if (decoder->HandleControlFrameHeadersComplete()) {
+      visitor()->OnHeaderFrameEnd(stream_id());
+    } else {
+      SetSpdyErrorAndNotify(
+          HpackDecodingErrorToSpdyFramerError(decoder->error()), "");
+      return;
+    }
+    const Http2FrameHeader& first = frame_type() == Http2FrameType::CONTINUATION
+                                        ? hpack_first_frame_header_
+                                        : frame_header_;
+    if (first.type == Http2FrameType::HEADERS && first.IsEndStream()) {
+      visitor()->OnStreamEnd(first.stream_id);
+    }
+    has_hpack_first_frame_header_ = false;
+    CorruptFrameHeader(&hpack_first_frame_header_);
+  } else {
+    QUICHE_DCHECK(has_hpack_first_frame_header_);
+    has_expected_frame_type_ = true;
+    expected_frame_type_ = Http2FrameType::CONTINUATION;
+  }
+}
+
+}  // namespace http2
+
+namespace spdy {
+
+bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* /*goaway_data*/,
+                                                   size_t /*len*/) {
+  return true;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/http2_frame_decoder_adapter.h b/quiche/spdy/core/http2_frame_decoder_adapter.h
new file mode 100644
index 0000000..1798ae0
--- /dev/null
+++ b/quiche/spdy/core/http2_frame_decoder_adapter.h
@@ -0,0 +1,547 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
+#define QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "quiche/http2/decoder/http2_frame_decoder.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_decoder_adapter.h"
+#include "quiche/spdy/core/hpack/hpack_header_table.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace spdy {
+
+class SpdyFramerVisitorInterface;
+class ExtensionVisitorInterface;
+
+}  // namespace spdy
+
+// TODO(dahollings): Perform various renames/moves suggested in cl/164660364.
+
+namespace http2 {
+
+// Adapts SpdyFramer interface to use Http2FrameDecoder.
+class QUICHE_EXPORT_PRIVATE Http2DecoderAdapter
+    : public http2::Http2FrameDecoderListener {
+ public:
+  // HTTP2 states.
+  enum SpdyState {
+    SPDY_ERROR,
+    SPDY_READY_FOR_FRAME,  // Framer is ready for reading the next frame.
+    SPDY_FRAME_COMPLETE,  // Framer has finished reading a frame, need to reset.
+    SPDY_READING_COMMON_HEADER,
+    SPDY_CONTROL_FRAME_PAYLOAD,
+    SPDY_READ_DATA_FRAME_PADDING_LENGTH,
+    SPDY_CONSUME_PADDING,
+    SPDY_IGNORE_REMAINING_PAYLOAD,
+    SPDY_FORWARD_STREAM_FRAME,
+    SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK,
+    SPDY_CONTROL_FRAME_HEADER_BLOCK,
+    SPDY_GOAWAY_FRAME_PAYLOAD,
+    SPDY_SETTINGS_FRAME_HEADER,
+    SPDY_SETTINGS_FRAME_PAYLOAD,
+    SPDY_ALTSVC_FRAME_PAYLOAD,
+    SPDY_EXTENSION_FRAME_PAYLOAD,
+  };
+
+  // Framer error codes.
+  enum SpdyFramerError {
+    SPDY_NO_ERROR,
+    SPDY_INVALID_STREAM_ID,            // Stream ID is invalid
+    SPDY_INVALID_CONTROL_FRAME,        // Control frame is mal-formatted.
+    SPDY_CONTROL_PAYLOAD_TOO_LARGE,    // Control frame payload was too large.
+    SPDY_DECOMPRESS_FAILURE,           // There was an error decompressing.
+    SPDY_INVALID_PADDING,              // HEADERS or DATA frame padding invalid
+    SPDY_INVALID_DATA_FRAME_FLAGS,     // Data frame has invalid flags.
+    SPDY_UNEXPECTED_FRAME,             // Frame received out of order.
+    SPDY_INTERNAL_FRAMER_ERROR,        // SpdyFramer was used incorrectly.
+    SPDY_INVALID_CONTROL_FRAME_SIZE,   // Control frame not sized to spec
+    SPDY_OVERSIZED_PAYLOAD,            // Payload size was too large
+
+    // HttpDecoder or HttpDecoderAdapter error.
+    // See HpackDecodingError for description of each error code.
+    SPDY_HPACK_INDEX_VARINT_ERROR,
+    SPDY_HPACK_NAME_LENGTH_VARINT_ERROR,
+    SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR,
+    SPDY_HPACK_NAME_TOO_LONG,
+    SPDY_HPACK_VALUE_TOO_LONG,
+    SPDY_HPACK_NAME_HUFFMAN_ERROR,
+    SPDY_HPACK_VALUE_HUFFMAN_ERROR,
+    SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE,
+    SPDY_HPACK_INVALID_INDEX,
+    SPDY_HPACK_INVALID_NAME_INDEX,
+    SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED,
+    SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK,
+    SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING,
+    SPDY_HPACK_TRUNCATED_BLOCK,
+    SPDY_HPACK_FRAGMENT_TOO_LONG,
+    SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT,
+
+    // Set if the visitor no longer wishes to receive events for this
+    // connection.
+    SPDY_STOP_PROCESSING,
+
+    LAST_ERROR,  // Must be the last entry in the enum.
+  };
+
+  // For debugging.
+  static const char* StateToString(int state);
+  static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error);
+
+  Http2DecoderAdapter();
+  ~Http2DecoderAdapter() override;
+
+  Http2DecoderAdapter(const Http2DecoderAdapter&) = delete;
+  Http2DecoderAdapter& operator=(const Http2DecoderAdapter&) = delete;
+
+  // Set callbacks to be called from the framer.  A visitor must be set, or
+  // else the framer will likely crash.  It is acceptable for the visitor
+  // to do nothing.  If this is called multiple times, only the last visitor
+  // will be used.
+  void set_visitor(spdy::SpdyFramerVisitorInterface* visitor);
+  spdy::SpdyFramerVisitorInterface* visitor() const { return visitor_; }
+
+  // Set extension callbacks to be called from the framer or decoder. Optional.
+  // If called multiple times, only the last visitor will be used.
+  void set_extension_visitor(spdy::ExtensionVisitorInterface* visitor);
+  spdy::ExtensionVisitorInterface* extension_visitor() const {
+    return extension_;
+  }
+
+  // Set debug callbacks to be called from the framer. The debug visitor is
+  // completely optional and need not be set in order for normal operation.
+  // If this is called multiple times, only the last visitor will be used.
+  void set_debug_visitor(spdy::SpdyFramerDebugVisitorInterface* debug_visitor);
+  spdy::SpdyFramerDebugVisitorInterface* debug_visitor() const {
+    return debug_visitor_;
+  }
+
+  // Decode the |len| bytes of encoded HTTP/2 starting at |*data|. Returns
+  // the number of bytes consumed. It is safe to pass more bytes in than
+  // may be consumed. Should process (or otherwise buffer) as much as
+  // available.
+  //
+  // If the input contains the entirety of a DATA frame payload, GOAWAY frame
+  // Additional Debug Data field, or unknown frame payload, then the
+  // corresponding SpdyFramerVisitorInterface::OnStreamFrameData(),
+  // OnGoAwayFrameData(), or ExtensionVisitorInterface::OnFramePayload() method
+  // is guaranteed to be called exactly once, with the entire payload or field.
+  size_t ProcessInput(const char* data, size_t len);
+
+  // Current state of the decoder.
+  SpdyState state() const;
+
+  // Current error code (NO_ERROR if state != ERROR).
+  SpdyFramerError spdy_framer_error() const;
+
+  // Has any frame header looked like the start of an HTTP/1.1 (or earlier)
+  // response? Used to detect if a backend/server that we sent a request to
+  // has responded with an HTTP/1.1 (or earlier) response.
+  bool probable_http_response() const;
+
+  spdy::HpackDecoderAdapter* GetHpackDecoder();
+  const spdy::HpackDecoderAdapter* GetHpackDecoder() const {
+    return hpack_decoder_.get();
+  }
+
+  bool HasError() const;
+
+  // A visitor may call this method to indicate it no longer wishes to receive
+  // events for this connection.
+  void StopProcessing();
+
+  // Sets the limit on the size of received HTTP/2 frame payloads. Corresponds
+  // to SETTINGS_MAX_FRAME_SIZE as advertised to the peer.
+  void SetMaxFrameSize(size_t max_frame_size);
+
+ private:
+  bool OnFrameHeader(const Http2FrameHeader& header) override;
+  void OnDataStart(const Http2FrameHeader& header) override;
+  void OnDataPayload(const char* data, size_t len) override;
+  void OnDataEnd() override;
+  void OnHeadersStart(const Http2FrameHeader& header) override;
+  void OnHeadersPriority(const Http2PriorityFields& priority) override;
+  void OnHpackFragment(const char* data, size_t len) override;
+  void OnHeadersEnd() override;
+  void OnPriorityFrame(const Http2FrameHeader& header,
+                       const Http2PriorityFields& priority) override;
+  void OnContinuationStart(const Http2FrameHeader& header) override;
+  void OnContinuationEnd() override;
+  void OnPadLength(size_t trailing_length) override;
+  void OnPadding(const char* padding, size_t skipped_length) override;
+  void OnRstStream(const Http2FrameHeader& header,
+                   Http2ErrorCode http2_error_code) override;
+  void OnSettingsStart(const Http2FrameHeader& header) override;
+  void OnSetting(const Http2SettingFields& setting_fields) override;
+  void OnSettingsEnd() override;
+  void OnSettingsAck(const Http2FrameHeader& header) override;
+  void OnPushPromiseStart(const Http2FrameHeader& header,
+                          const Http2PushPromiseFields& promise,
+                          size_t total_padding_length) override;
+  void OnPushPromiseEnd() override;
+  void OnPing(const Http2FrameHeader& header,
+              const Http2PingFields& ping) override;
+  void OnPingAck(const Http2FrameHeader& header,
+                 const Http2PingFields& ping) override;
+  void OnGoAwayStart(const Http2FrameHeader& header,
+                     const Http2GoAwayFields& goaway) override;
+  void OnGoAwayOpaqueData(const char* data, size_t len) override;
+  void OnGoAwayEnd() override;
+  void OnWindowUpdate(const Http2FrameHeader& header,
+                      uint32_t increment) override;
+  void OnAltSvcStart(const Http2FrameHeader& header,
+                     size_t origin_length,
+                     size_t value_length) override;
+  void OnAltSvcOriginData(const char* data, size_t len) override;
+  void OnAltSvcValueData(const char* data, size_t len) override;
+  void OnAltSvcEnd() override;
+  void OnPriorityUpdateStart(
+      const Http2FrameHeader& header,
+      const Http2PriorityUpdateFields& priority_update) override;
+  void OnPriorityUpdatePayload(const char* data, size_t len) override;
+  void OnPriorityUpdateEnd() override;
+  void OnUnknownStart(const Http2FrameHeader& header) override;
+  void OnUnknownPayload(const char* data, size_t len) override;
+  void OnUnknownEnd() override;
+  void OnPaddingTooLong(const Http2FrameHeader& header,
+                        size_t missing_length) override;
+  void OnFrameSizeError(const Http2FrameHeader& header) override;
+
+  size_t ProcessInputFrame(const char* data, size_t len);
+
+  void DetermineSpdyState(DecodeStatus status);
+  void ResetBetweenFrames();
+
+  void set_spdy_state(SpdyState v);
+
+  void SetSpdyErrorAndNotify(SpdyFramerError error, std::string detailed_error);
+
+  const Http2FrameHeader& frame_header() const;
+
+  uint32_t stream_id() const;
+  Http2FrameType frame_type() const;
+
+  size_t remaining_total_payload() const;
+
+  bool IsReadingPaddingLength();
+  bool IsSkippingPadding();
+  bool IsDiscardingPayload();
+  // Called from OnXyz or OnXyzStart methods to decide whether it is OK to
+  // handle the callback.
+  bool IsOkToStartFrame(const Http2FrameHeader& header);
+  bool HasRequiredStreamId(uint32_t stream_id);
+
+  bool HasRequiredStreamId(const Http2FrameHeader& header);
+
+  bool HasRequiredStreamIdZero(uint32_t stream_id);
+
+  bool HasRequiredStreamIdZero(const Http2FrameHeader& header);
+
+  void ReportReceiveCompressedFrame(const Http2FrameHeader& header);
+
+  void CommonStartHpackBlock();
+
+  // SpdyFramer calls HandleControlFrameHeadersData even if there are zero
+  // fragment bytes in the first frame, so do the same.
+  void MaybeAnnounceEmptyFirstHpackFragment();
+  void CommonHpackFragmentEnd();
+
+  // The most recently decoded frame header; invalid after we reached the end
+  // of that frame.
+  Http2FrameHeader frame_header_;
+
+  // If decoding an HPACK block that is split across multiple frames, this holds
+  // the frame header of the HEADERS or PUSH_PROMISE that started the block.
+  Http2FrameHeader hpack_first_frame_header_;
+
+  // Amount of trailing padding. Currently used just as an indicator of whether
+  // OnPadLength has been called.
+  absl::optional<size_t> opt_pad_length_;
+
+  // Temporary buffers for the AltSvc fields.
+  std::string alt_svc_origin_;
+  std::string alt_svc_value_;
+
+  // Temporary buffers for PRIORITY_UPDATE fields.
+  uint32_t prioritized_stream_id_ = 0;
+  std::string priority_field_value_;
+
+  // Listener used if we transition to an error state; the listener ignores all
+  // the callbacks.
+  Http2FrameDecoderNoOpListener no_op_listener_;
+
+  spdy::SpdyFramerVisitorInterface* visitor_ = nullptr;
+  spdy::SpdyFramerDebugVisitorInterface* debug_visitor_ = nullptr;
+
+  // If non-null, unknown frames and settings are passed to the extension.
+  spdy::ExtensionVisitorInterface* extension_ = nullptr;
+
+  // The HPACK decoder to be used for this adapter. User is responsible for
+  // clearing if the adapter is to be used for another connection.
+  std::unique_ptr<spdy::HpackDecoderAdapter> hpack_decoder_;
+
+  // The HTTP/2 frame decoder.
+  Http2FrameDecoder frame_decoder_;
+
+  // Next frame type expected. Currently only used for CONTINUATION frames,
+  // but could be used for detecting whether the first frame is a SETTINGS
+  // frame.
+  // TODO(jamessynge): Provide means to indicate that decoder should require
+  // SETTINGS frame as the first frame.
+  Http2FrameType expected_frame_type_;
+
+  // Attempt to duplicate the SpdyState and SpdyFramerError values that
+  // SpdyFramer sets. Values determined by getting tests to pass.
+  SpdyState spdy_state_ = SpdyState::SPDY_READY_FOR_FRAME;
+  SpdyFramerError spdy_framer_error_ = SpdyFramerError::SPDY_NO_ERROR;
+
+  // The limit on the size of received HTTP/2 payloads as specified in the
+  // SETTINGS_MAX_FRAME_SIZE advertised to peer.
+  size_t max_frame_size_ = spdy::kHttp2DefaultFramePayloadLimit;
+
+  // Has OnFrameHeader been called?
+  bool decoded_frame_header_ = false;
+
+  // Have we recorded an Http2FrameHeader for the current frame?
+  // We only do so if the decoder will make multiple callbacks for
+  // the frame; for example, for PING frames we don't make record
+  // the frame header, but for ALTSVC we do.
+  bool has_frame_header_ = false;
+
+  // Have we recorded an Http2FrameHeader for the current HPACK block?
+  // True only for multi-frame HPACK blocks.
+  bool has_hpack_first_frame_header_ = false;
+
+  // Has OnHeaders() already been called for current HEADERS block? Only
+  // meaningful between OnHeadersStart and OnHeadersPriority.
+  bool on_headers_called_ = false;
+
+  // Has OnHpackFragment() already been called for current HPACK block?
+  // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS
+  // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only
+  // padding). Detect that condition and replicate the behavior using this
+  // field.
+  bool on_hpack_fragment_called_ = false;
+
+  // Have we seen a frame header that appears to be an HTTP/1 response?
+  bool latched_probable_http_response_ = false;
+
+  // Is expected_frame_type_ set?
+  bool has_expected_frame_type_ = false;
+
+  // Is the current frame payload destined for |extension_|?
+  bool handling_extension_payload_ = false;
+};
+
+}  // namespace http2
+
+namespace spdy {
+
+// Http2DecoderAdapter will use the given visitor implementing this
+// interface to deliver event callbacks as frames are decoded.
+//
+// Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE)
+// are processed in fashion that allows the decompressed header block to be
+// delivered in chunks to the visitor.
+// The following steps are followed:
+//   1. OnHeaders, or OnPushPromise is called.
+//   2. OnHeaderFrameStart is called; visitor is expected to return an instance
+//      of SpdyHeadersHandlerInterface that will receive the header key-value
+//      pairs.
+//   3. OnHeaderFrameEnd is called, indicating that the full header block has
+//      been delivered for the control frame.
+// During step 2, if the visitor is not interested in accepting the header data,
+// it should return a no-op implementation of SpdyHeadersHandlerInterface.
+class QUICHE_EXPORT_PRIVATE SpdyFramerVisitorInterface {
+ public:
+  virtual ~SpdyFramerVisitorInterface() {}
+
+  // Called if an error is detected in the SpdyFrame protocol.
+  virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
+                       std::string detailed_error) = 0;
+
+  // Called when the common header for a frame is received. Validating the
+  // common header occurs in later processing.
+  virtual void OnCommonHeader(SpdyStreamId /*stream_id*/,
+                              size_t /*length*/,
+                              uint8_t /*type*/,
+                              uint8_t /*flags*/) {}
+
+  // Called when a data frame header is received. The frame's data
+  // payload will be provided via subsequent calls to
+  // OnStreamFrameData().
+  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
+                                 size_t length,
+                                 bool fin) = 0;
+
+  // Called when data is received.
+  // |stream_id| The stream receiving data.
+  // |data| A buffer containing the data received.
+  // |len| The length of the data buffer.
+  virtual void OnStreamFrameData(SpdyStreamId stream_id,
+                                 const char* data,
+                                 size_t len) = 0;
+
+  // Called when the other side has finished sending data on this stream.
+  // |stream_id| The stream that was receiving data.
+  virtual void OnStreamEnd(SpdyStreamId stream_id) = 0;
+
+  // Called when padding length field is received on a DATA frame.
+  // |stream_id| The stream receiving data.
+  // |value| The value of the padding length field.
+  virtual void OnStreamPadLength(SpdyStreamId /*stream_id*/, size_t /*value*/) {
+  }
+
+  // Called when padding is received (the trailing octets, not pad_len field) on
+  // a DATA frame.
+  // |stream_id| The stream receiving data.
+  // |len| The number of padding octets.
+  virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;
+
+  // Called just before processing the payload of a frame containing header
+  // data. Should return an implementation of SpdyHeadersHandlerInterface that
+  // will receive headers for stream |stream_id|. The caller will not take
+  // ownership of the headers handler. The same instance should remain live
+  // and be returned for all header frames comprising a logical header block
+  // (i.e. until OnHeaderFrameEnd() is called).
+  virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId stream_id) = 0;
+
+  // Called after processing the payload of a frame containing header data.
+  virtual void OnHeaderFrameEnd(SpdyStreamId stream_id) = 0;
+
+  // Called when a RST_STREAM frame has been parsed.
+  virtual void OnRstStream(SpdyStreamId stream_id,
+                           SpdyErrorCode error_code) = 0;
+
+  // Called when a SETTINGS frame is received.
+  virtual void OnSettings() {}
+
+  // Called when a complete setting within a SETTINGS frame has been parsed.
+  // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
+  virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
+
+  // Called when a SETTINGS frame is received with the ACK flag set.
+  virtual void OnSettingsAck() {}
+
+  // Called before and after parsing SETTINGS id and value tuples.
+  virtual void OnSettingsEnd() = 0;
+
+  // Called when a PING frame has been parsed.
+  virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
+
+  // Called when a GOAWAY frame has been parsed.
+  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                        SpdyErrorCode error_code) = 0;
+
+  // Called when a HEADERS frame is received.
+  // Note that header block data is not included. See OnHeaderFrameStart().
+  // |stream_id| The stream receiving the header.
+  // |has_priority| Whether or not the headers frame included a priority value,
+  //     and stream dependency info.
+  // |weight| If |has_priority| is true, then weight (in the range [1, 256])
+  //     for the receiving stream, otherwise 0.
+  // |parent_stream_id| If |has_priority| is true the parent stream of the
+  //     receiving stream, else 0.
+  // |exclusive| If |has_priority| is true the exclusivity of dependence on the
+  //     parent stream, else false.
+  // |fin| Whether FIN flag is set in frame headers.
+  // |end| False if HEADERs frame is to be followed by a CONTINUATION frame,
+  //     or true if not.
+  virtual void OnHeaders(SpdyStreamId stream_id,
+                         bool has_priority,
+                         int weight,
+                         SpdyStreamId parent_stream_id,
+                         bool exclusive,
+                         bool fin,
+                         bool end) = 0;
+
+  // Called when a WINDOW_UPDATE frame has been parsed.
+  virtual void OnWindowUpdate(SpdyStreamId stream_id,
+                              int delta_window_size) = 0;
+
+  // Called when a goaway frame opaque data is available.
+  // |goaway_data| A buffer containing the opaque GOAWAY data chunk received.
+  // |len| The length of the header data buffer. A length of zero indicates
+  //       that the header data block has been completely sent.
+  // When this function returns true the visitor indicates that it accepted
+  // all of the data. Returning false indicates that that an error has
+  // occurred while processing the data. Default implementation returns true.
+  virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len);
+
+  // Called when a PUSH_PROMISE frame is received.
+  // Note that header block data is not included. See OnHeaderFrameStart().
+  virtual void OnPushPromise(SpdyStreamId stream_id,
+                             SpdyStreamId promised_stream_id,
+                             bool end) = 0;
+
+  // Called when a CONTINUATION frame is received.
+  // Note that header block data is not included. See OnHeaderFrameStart().
+  virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0;
+
+  // Called when an ALTSVC frame has been parsed.
+  virtual void OnAltSvc(
+      SpdyStreamId /*stream_id*/,
+      absl::string_view /*origin*/,
+      const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) {
+  }
+
+  // Called when a PRIORITY frame is received.
+  // |stream_id| The stream to update the priority of.
+  // |parent_stream_id| The parent stream of |stream_id|.
+  // |weight| Stream weight, in the range [1, 256].
+  // |exclusive| Whether |stream_id| should be an only child of
+  //     |parent_stream_id|.
+  virtual void OnPriority(SpdyStreamId stream_id,
+                          SpdyStreamId parent_stream_id,
+                          int weight,
+                          bool exclusive) = 0;
+
+  // Called when a PRIORITY_UPDATE frame is received on stream 0.
+  // |prioritized_stream_id| is the Prioritized Stream ID and
+  // |priority_field_value| is the Priority Field Value
+  // parsed from the frame payload.
+  virtual void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
+                                absl::string_view priority_field_value) = 0;
+
+  // Called when a frame type we don't recognize is received.
+  // Return true if this appears to be a valid extension frame, false otherwise.
+  // We distinguish between extension frames and nonsense by checking
+  // whether the stream id is valid.
+  virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0;
+};
+
+class QUICHE_EXPORT_PRIVATE ExtensionVisitorInterface {
+ public:
+  virtual ~ExtensionVisitorInterface() {}
+
+  // Called when non-standard SETTINGS are received.
+  virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
+
+  // Called when non-standard frames are received.
+  virtual bool OnFrameHeader(SpdyStreamId stream_id,
+                             size_t length,
+                             uint8_t type,
+                             uint8_t flags) = 0;
+
+  // The payload for a single frame may be delivered as multiple calls to
+  // OnFramePayload. Since the length field is passed in OnFrameHeader, there is
+  // no explicit indication of the end of the frame payload.
+  virtual void OnFramePayload(const char* data, size_t len) = 0;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
diff --git a/quiche/spdy/core/http2_header_block_hpack_listener.h b/quiche/spdy/core/http2_header_block_hpack_listener.h
new file mode 100644
index 0000000..795543a
--- /dev/null
+++ b/quiche/spdy/core/http2_header_block_hpack_listener.h
@@ -0,0 +1,47 @@
+#ifndef QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_HPACK_LISTENER_H_
+#define QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_HPACK_LISTENER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder_listener.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace spdy {
+
+// This class simply gathers the key-value pairs emitted by an HpackDecoder in
+// a SpdyHeaderBlock.
+class Http2HeaderBlockHpackListener : public http2::HpackDecoderListener {
+ public:
+  Http2HeaderBlockHpackListener() {}
+
+  void OnHeaderListStart() override {
+    header_block_.clear();
+    hpack_error_ = false;
+  }
+
+  void OnHeader(const std::string& name, const std::string& value) override {
+    header_block_.AppendValueOrAddHeader(name, value);
+  }
+
+  void OnHeaderListEnd() override {}
+
+  void OnHeaderErrorDetected(absl::string_view error_message) override {
+    QUICHE_VLOG(1) << error_message;
+    hpack_error_ = true;
+  }
+
+  SpdyHeaderBlock release_header_block() {
+    SpdyHeaderBlock block = std::move(header_block_);
+    header_block_ = {};
+    return block;
+  }
+  bool hpack_error() const { return hpack_error_; }
+
+ private:
+  SpdyHeaderBlock header_block_;
+  bool hpack_error_ = false;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_HPACK_LISTENER_H_
diff --git a/quiche/spdy/core/metadata_extension.cc b/quiche/spdy/core/metadata_extension.cc
new file mode 100644
index 0000000..6eb10af
--- /dev/null
+++ b/quiche/spdy/core/metadata_extension.cc
@@ -0,0 +1,195 @@
+#include "quiche/spdy/core/metadata_extension.h"
+
+#include <list>
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "quiche/http2/decoder/decode_buffer.h"
+#include "quiche/http2/hpack/decoder/hpack_decoder.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+#include "quiche/spdy/core/http2_header_block_hpack_listener.h"
+
+namespace spdy {
+
+// Non-standard constants related to METADATA frames.
+const SpdySettingsId MetadataVisitor::kMetadataExtensionId = 0x4d44;
+const uint8_t MetadataVisitor::kMetadataFrameType = 0x4d;
+const uint8_t MetadataVisitor::kEndMetadataFlag = 0x4;
+
+namespace {
+
+const size_t kMaxMetadataBlockSize = 1 << 20;  // 1 MB
+
+// This class uses an HpackEncoder to serialize a METADATA block as a series of
+// METADATA frames.
+class MetadataFrameSequence : public MetadataSerializer::FrameSequence {
+ public:
+  MetadataFrameSequence(SpdyStreamId stream_id, spdy::SpdyHeaderBlock payload)
+      : stream_id_(stream_id), payload_(std::move(payload)) {
+    // Metadata should not use HPACK compression.
+    encoder_.DisableCompression();
+    HpackEncoder::Representations r;
+    for (const auto& kv_pair : payload_) {
+      r.push_back(kv_pair);
+    }
+    progressive_encoder_ = encoder_.EncodeRepresentations(r);
+  }
+
+  // Copies are not allowed.
+  MetadataFrameSequence(const MetadataFrameSequence& other) = delete;
+  MetadataFrameSequence& operator=(const MetadataFrameSequence& other) = delete;
+
+  std::unique_ptr<spdy::SpdyFrameIR> Next() override;
+
+ private:
+  SpdyStreamId stream_id_;
+  SpdyHeaderBlock payload_;
+  HpackEncoder encoder_;
+  std::unique_ptr<HpackEncoder::ProgressiveEncoder> progressive_encoder_;
+};
+
+std::unique_ptr<spdy::SpdyFrameIR> MetadataFrameSequence::Next() {
+  if (!progressive_encoder_->HasNext()) {
+    return nullptr;
+  }
+  // METADATA frames obey the HTTP/2 maximum frame size.
+  std::string payload =
+      progressive_encoder_->Next(spdy::kHttp2DefaultFramePayloadLimit);
+  const bool end_metadata = (!progressive_encoder_->HasNext());
+  const uint8_t flags = end_metadata ? MetadataVisitor::kEndMetadataFlag : 0;
+  return absl::make_unique<spdy::SpdyUnknownIR>(
+      stream_id_, MetadataVisitor::kMetadataFrameType, flags,
+      std::move(payload));
+}
+
+}  // anonymous namespace
+
+struct MetadataVisitor::MetadataPayloadState {
+  MetadataPayloadState(size_t remaining, bool end)
+      : bytes_remaining(remaining), end_metadata(end) {}
+  std::list<std::string> buffer;
+  size_t bytes_remaining;
+  bool end_metadata;
+};
+
+MetadataVisitor::MetadataVisitor(OnCompletePayload on_payload,
+                                 OnMetadataSupport on_support)
+    : on_payload_(std::move(on_payload)),
+      on_support_(std::move(on_support)),
+      peer_supports_metadata_(MetadataSupportState::UNSPECIFIED) {}
+
+MetadataVisitor::~MetadataVisitor() {}
+
+void MetadataVisitor::OnSetting(SpdySettingsId id, uint32_t value) {
+  QUICHE_VLOG(1) << "MetadataVisitor::OnSetting(" << id << ", " << value << ")";
+  if (id == kMetadataExtensionId) {
+    if (value == 0) {
+      const MetadataSupportState previous_state = peer_supports_metadata_;
+      peer_supports_metadata_ = MetadataSupportState::NOT_SUPPORTED;
+      if (previous_state == MetadataSupportState::UNSPECIFIED ||
+          previous_state == MetadataSupportState::SUPPORTED) {
+        on_support_(false);
+      }
+    } else if (value == 1) {
+      const MetadataSupportState previous_state = peer_supports_metadata_;
+      peer_supports_metadata_ = MetadataSupportState::SUPPORTED;
+      if (previous_state == MetadataSupportState::UNSPECIFIED ||
+          previous_state == MetadataSupportState::NOT_SUPPORTED) {
+        on_support_(true);
+      }
+    } else {
+      LOG_EVERY_N_SEC(WARNING, 1)
+          << "Unrecognized value for setting " << id << ": " << value;
+    }
+  }
+}
+
+bool MetadataVisitor::OnFrameHeader(SpdyStreamId stream_id, size_t length,
+                                    uint8_t type, uint8_t flags) {
+  QUICHE_VLOG(1) << "OnFrameHeader(stream_id=" << stream_id
+                 << ", length=" << length << ", type=" << static_cast<int>(type)
+                 << ", flags=" << static_cast<int>(flags);
+  // TODO(birenroy): Consider disabling METADATA handling until our setting
+  // advertising METADATA support has been acked.
+  if (type != kMetadataFrameType) {
+    return false;
+  }
+  auto it = metadata_map_.find(stream_id);
+  if (it == metadata_map_.end()) {
+    auto state = absl::make_unique<MetadataPayloadState>(
+        length, flags & kEndMetadataFlag);
+    auto result = metadata_map_.insert(std::make_pair(stream_id,
+                                                      std::move(state)));
+    QUICHE_BUG_IF(bug_if_2781_1, !result.second) << "Map insertion failed.";
+    it = result.first;
+  } else {
+    QUICHE_BUG_IF(bug_22051_1, it->second->end_metadata)
+        << "Inconsistent metadata payload state!";
+    QUICHE_BUG_IF(bug_if_2781_2, it->second->bytes_remaining > 0)
+        << "Incomplete metadata block!";
+  }
+
+  if (it->second == nullptr) {
+    QUICHE_BUG(bug_2781_3) << "Null metadata payload state!";
+    return false;
+  }
+  current_stream_ = stream_id;
+  it->second->bytes_remaining = length;
+  it->second->end_metadata = (flags & kEndMetadataFlag);
+  return true;
+}
+
+void MetadataVisitor::OnFramePayload(const char* data, size_t len) {
+  QUICHE_VLOG(1) << "OnFramePayload(stream_id=" << current_stream_
+                 << ", len=" << len << ")";
+  auto it = metadata_map_.find(current_stream_);
+  if (it == metadata_map_.end() || it->second == nullptr) {
+    QUICHE_BUG(bug_2781_4) << "Invalid order of operations on MetadataVisitor.";
+  } else {
+    MetadataPayloadState* state = it->second.get();  // For readability.
+    state->buffer.push_back(std::string(data, len));
+    if (len < state->bytes_remaining) {
+      state->bytes_remaining -= len;
+    } else {
+      QUICHE_BUG_IF(bug_22051_2, len > state->bytes_remaining)
+          << "Metadata payload overflow! len: " << len
+          << " bytes_remaining: " << state->bytes_remaining;
+      state->bytes_remaining = 0;
+      if (state->end_metadata) {
+        // The whole process of decoding the HPACK-encoded metadata block,
+        // below, is more cumbersome than it ought to be.
+        spdy::Http2HeaderBlockHpackListener listener;
+        http2::HpackDecoder decoder(&listener, kMaxMetadataBlockSize);
+
+        // If any operations fail, the decode process should be aborted.
+        bool success = decoder.StartDecodingBlock();
+        for (const std::string& slice : state->buffer) {
+          if (!success) {
+            break;
+          }
+          http2::DecodeBuffer buffer(slice.data(), slice.size());
+          success = success && decoder.DecodeFragment(&buffer);
+        }
+        success =
+            success && decoder.EndDecodingBlock() && !listener.hpack_error();
+        if (success) {
+          on_payload_(current_stream_, listener.release_header_block());
+        }
+        // TODO(birenroy): add varz counting metadata decode successes/failures.
+        metadata_map_.erase(it);
+      }
+    }
+  }
+}
+
+std::unique_ptr<MetadataSerializer::FrameSequence>
+MetadataSerializer::FrameSequenceForPayload(SpdyStreamId stream_id,
+                                            MetadataPayload payload) {
+  return absl::make_unique<MetadataFrameSequence>(stream_id,
+                                                  std::move(payload));
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/metadata_extension.h b/quiche/spdy/core/metadata_extension.h
new file mode 100644
index 0000000..a27ad16
--- /dev/null
+++ b/quiche/spdy/core/metadata_extension.h
@@ -0,0 +1,116 @@
+#ifndef QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
+#define QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/zero_copy_output_buffer.h"
+
+namespace spdy {
+
+// An implementation of the ExtensionVisitorInterface that can parse
+// METADATA frames. METADATA is a non-standard HTTP/2 extension developed and
+// used internally at Google. A peer advertises support for METADATA by sending
+// a setting with a setting ID of kMetadataExtensionId and a value of 1.
+//
+// Metadata is represented as a HPACK header block with literal encoding.
+class MetadataVisitor : public spdy::ExtensionVisitorInterface {
+ public:
+  using MetadataPayload = spdy::SpdyHeaderBlock;
+
+  static_assert(!std::is_copy_constructible<MetadataPayload>::value,
+                "MetadataPayload should be a move-only type!");
+
+  using OnMetadataSupport = std::function<void(bool)>;
+  using OnCompletePayload =
+      std::function<void(spdy::SpdyStreamId, MetadataPayload)>;
+
+  // The HTTP/2 SETTINGS ID that is used to indicate support for METADATA
+  // frames.
+  static const spdy::SpdySettingsId kMetadataExtensionId;
+
+  // The 8-bit frame type code for a METADATA frame.
+  static const uint8_t kMetadataFrameType;
+
+  // The flag that indicates the end of a logical metadata block. Due to frame
+  // size limits, a single metadata block may be emitted as several HTTP/2
+  // frames.
+  static const uint8_t kEndMetadataFlag;
+
+  // |on_payload| is invoked whenever a complete metadata payload is received.
+  // |on_support| is invoked whenever the peer's advertised support for metadata
+  // changes.
+  MetadataVisitor(OnCompletePayload on_payload, OnMetadataSupport on_support);
+  ~MetadataVisitor() override;
+
+  MetadataVisitor(const MetadataVisitor&) = delete;
+  MetadataVisitor& operator=(const MetadataVisitor&) = delete;
+
+  // Interprets the non-standard setting indicating support for METADATA.
+  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
+
+  // Returns true iff |type| indicates a METADATA frame.
+  bool OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
+                     uint8_t flags) override;
+
+  // Consumes a METADATA frame payload. Invokes the registered callback when a
+  // complete payload has been received.
+  void OnFramePayload(const char* data, size_t len) override;
+
+  // Returns true if the peer has advertised support for METADATA via the
+  // appropriate setting.
+  bool PeerSupportsMetadata() const {
+    return peer_supports_metadata_ == MetadataSupportState::SUPPORTED;
+  }
+
+ private:
+  enum class MetadataSupportState : uint8_t {
+    UNSPECIFIED,
+    SUPPORTED,
+    NOT_SUPPORTED,
+  };
+
+  struct MetadataPayloadState;
+
+  using StreamMetadataMap =
+      absl::flat_hash_map<spdy::SpdyStreamId,
+                          std::unique_ptr<MetadataPayloadState>>;
+
+  OnCompletePayload on_payload_;
+  OnMetadataSupport on_support_;
+  StreamMetadataMap metadata_map_;
+  spdy::SpdyStreamId current_stream_;
+  MetadataSupportState peer_supports_metadata_;
+};
+
+// A class that serializes metadata blocks as sequences of frames.
+class MetadataSerializer {
+ public:
+  using MetadataPayload = spdy::SpdyHeaderBlock;
+
+  class FrameSequence {
+   public:
+    virtual ~FrameSequence() {}
+
+    // Returns nullptr once the sequence has been exhausted.
+    virtual std::unique_ptr<spdy::SpdyFrameIR> Next() = 0;
+  };
+
+  MetadataSerializer() {}
+
+  MetadataSerializer(const MetadataSerializer&) = delete;
+  MetadataSerializer& operator=(const MetadataSerializer&) = delete;
+
+  // Returns nullptr on failure.
+  std::unique_ptr<FrameSequence> FrameSequenceForPayload(
+      spdy::SpdyStreamId stream_id, MetadataPayload payload);
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
diff --git a/quiche/spdy/core/metadata_extension_test.cc b/quiche/spdy/core/metadata_extension_test.cc
new file mode 100644
index 0000000..baf4a88
--- /dev/null
+++ b/quiche/spdy/core/metadata_extension_test.cc
@@ -0,0 +1,229 @@
+#include "quiche/spdy/core/metadata_extension.h"
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/functional/bind_front.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/array_output_buffer.h"
+#include "quiche/spdy/core/mock_spdy_framer_visitor.h"
+#include "quiche/spdy/core/spdy_framer.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_no_op_visitor.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace spdy {
+namespace test {
+namespace {
+
+using ::absl::bind_front;
+using ::spdy::SpdyFramer;
+using ::spdy::SpdyHeaderBlock;
+using ::spdy::test::MockSpdyFramerVisitor;
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
+const size_t kBufferSize = 64 * 1024;
+char kBuffer[kBufferSize];
+
+class MetadataExtensionTest : public QuicheTest {
+ protected:
+  MetadataExtensionTest() : test_buffer_(kBuffer, kBufferSize) {}
+
+  void SetUp() override {
+    extension_ = absl::make_unique<MetadataVisitor>(
+        bind_front(&MetadataExtensionTest::OnCompletePayload, this),
+        bind_front(&MetadataExtensionTest::OnMetadataSupport, this));
+  }
+
+  void OnCompletePayload(spdy::SpdyStreamId stream_id,
+                         MetadataVisitor::MetadataPayload payload) {
+    ++received_count_;
+    received_payload_map_.insert(std::make_pair(stream_id, std::move(payload)));
+  }
+
+  void OnMetadataSupport(bool peer_supports_metadata) {
+    EXPECT_EQ(peer_supports_metadata, extension_->PeerSupportsMetadata());
+    received_metadata_support_.push_back(peer_supports_metadata);
+  }
+
+  MetadataSerializer::MetadataPayload PayloadForData(absl::string_view data) {
+    SpdyHeaderBlock block;
+    block["example-payload"] = data;
+    return block;
+  }
+
+  std::unique_ptr<MetadataVisitor> extension_;
+  absl::flat_hash_map<spdy::SpdyStreamId, SpdyHeaderBlock>
+      received_payload_map_;
+  std::vector<bool> received_metadata_support_;
+  size_t received_count_ = 0;
+  spdy::ArrayOutputBuffer test_buffer_;
+};
+
+// This test verifies that the MetadataVisitor is initialized to a state where
+// it believes the peer does not support metadata.
+TEST_F(MetadataExtensionTest, MetadataNotSupported) {
+  EXPECT_FALSE(extension_->PeerSupportsMetadata());
+  EXPECT_THAT(received_metadata_support_, IsEmpty());
+}
+
+// This test verifies that upon receiving a specific setting, the extension
+// realizes that the peer supports metadata.
+TEST_F(MetadataExtensionTest, MetadataSupported) {
+  EXPECT_FALSE(extension_->PeerSupportsMetadata());
+  // 3 is not an appropriate value for the metadata extension key.
+  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 3);
+  EXPECT_FALSE(extension_->PeerSupportsMetadata());
+  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
+  ASSERT_TRUE(extension_->PeerSupportsMetadata());
+  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 0);
+  EXPECT_FALSE(extension_->PeerSupportsMetadata());
+  EXPECT_THAT(received_metadata_support_, ElementsAre(true, false));
+}
+
+TEST_F(MetadataExtensionTest, MetadataIgnoredWithoutExtension) {
+  const char kData[] = "some payload";
+  SpdyHeaderBlock payload = PayloadForData(kData);
+
+  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
+  ASSERT_TRUE(extension_->PeerSupportsMetadata());
+
+  MetadataSerializer serializer;
+  auto sequence = serializer.FrameSequenceForPayload(3, std::move(payload));
+  ASSERT_TRUE(sequence != nullptr);
+
+  http2::Http2DecoderAdapter deframer;
+  ::testing::StrictMock<MockSpdyFramerVisitor> visitor;
+  deframer.set_visitor(&visitor);
+
+  EXPECT_CALL(visitor,
+              OnCommonHeader(3, _, MetadataVisitor::kMetadataFrameType, _));
+  // The Return(true) should not be necessary. http://b/36023792
+  EXPECT_CALL(visitor, OnUnknownFrame(3, MetadataVisitor::kMetadataFrameType))
+      .WillOnce(::testing::Return(true));
+
+  SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+  auto frame = sequence->Next();
+  ASSERT_TRUE(frame != nullptr);
+  while (frame != nullptr) {
+    const size_t frame_size = framer.SerializeFrame(*frame, &test_buffer_);
+    ASSERT_GT(frame_size, 0u);
+    ASSERT_FALSE(deframer.HasError());
+    ASSERT_EQ(frame_size, test_buffer_.Size());
+    EXPECT_EQ(frame_size, deframer.ProcessInput(kBuffer, frame_size));
+    test_buffer_.Reset();
+    frame = sequence->Next();
+  }
+  EXPECT_FALSE(deframer.HasError());
+  EXPECT_THAT(received_metadata_support_, ElementsAre(true));
+}
+
+// This test verifies that the METADATA frame emitted by a MetadataExtension
+// can be parsed by another SpdyFramer with a MetadataVisitor.
+TEST_F(MetadataExtensionTest, MetadataPayloadEndToEnd) {
+  SpdyHeaderBlock block1;
+  block1["foo"] = "Some metadata value.";
+  SpdyHeaderBlock block2;
+  block2["bar"] =
+      "The color taupe truly represents a triumph of the human spirit over "
+      "adversity.";
+  block2["baz"] =
+      "Or perhaps it represents abject surrender to the implacable and "
+      "incomprehensible forces of the universe.";
+  const absl::string_view binary_payload{"binary\0payload", 14};
+  block2["qux"] = binary_payload;
+  EXPECT_EQ(binary_payload, block2["qux"]);
+  for (const SpdyHeaderBlock& payload_block :
+       {std::move(block1), std::move(block2)}) {
+    extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
+    ASSERT_TRUE(extension_->PeerSupportsMetadata());
+
+    MetadataSerializer serializer;
+    auto sequence =
+        serializer.FrameSequenceForPayload(3, payload_block.Clone());
+    ASSERT_TRUE(sequence != nullptr);
+
+    http2::Http2DecoderAdapter deframer;
+    ::spdy::SpdyNoOpVisitor visitor;
+    deframer.set_visitor(&visitor);
+    deframer.set_extension_visitor(extension_.get());
+    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+    auto frame = sequence->Next();
+    ASSERT_TRUE(frame != nullptr);
+    while (frame != nullptr) {
+      const size_t frame_size = framer.SerializeFrame(*frame, &test_buffer_);
+      ASSERT_GT(frame_size, 0u);
+      ASSERT_FALSE(deframer.HasError());
+      ASSERT_EQ(frame_size, test_buffer_.Size());
+      EXPECT_EQ(frame_size, deframer.ProcessInput(kBuffer, frame_size));
+      test_buffer_.Reset();
+      frame = sequence->Next();
+    }
+    EXPECT_EQ(1u, received_count_);
+    auto it = received_payload_map_.find(3);
+    ASSERT_TRUE(it != received_payload_map_.end());
+    EXPECT_EQ(payload_block, it->second);
+
+    received_count_ = 0;
+    received_payload_map_.clear();
+  }
+}
+
+// This test verifies that METADATA frames for two different streams can be
+// interleaved and still successfully parsed by another SpdyFramer with a
+// MetadataVisitor.
+TEST_F(MetadataExtensionTest, MetadataPayloadInterleaved) {
+  const std::string kData1 = std::string(65 * 1024, 'a');
+  const std::string kData2 = std::string(65 * 1024, 'b');
+  const SpdyHeaderBlock payload1 = PayloadForData(kData1);
+  const SpdyHeaderBlock payload2 = PayloadForData(kData2);
+
+  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
+  ASSERT_TRUE(extension_->PeerSupportsMetadata());
+
+  MetadataSerializer serializer;
+  auto sequence1 = serializer.FrameSequenceForPayload(3, payload1.Clone());
+  ASSERT_TRUE(sequence1 != nullptr);
+
+  auto sequence2 = serializer.FrameSequenceForPayload(5, payload2.Clone());
+  ASSERT_TRUE(sequence2 != nullptr);
+
+  http2::Http2DecoderAdapter deframer;
+  ::spdy::SpdyNoOpVisitor visitor;
+  deframer.set_visitor(&visitor);
+  deframer.set_extension_visitor(extension_.get());
+
+  SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+  auto frame1 = sequence1->Next();
+  ASSERT_TRUE(frame1 != nullptr);
+  auto frame2 = sequence2->Next();
+  ASSERT_TRUE(frame2 != nullptr);
+  while (frame1 != nullptr || frame2 != nullptr) {
+    for (auto frame : {frame1.get(), frame2.get()}) {
+      if (frame != nullptr) {
+        const size_t frame_size = framer.SerializeFrame(*frame, &test_buffer_);
+        ASSERT_GT(frame_size, 0u);
+        ASSERT_FALSE(deframer.HasError());
+        ASSERT_EQ(frame_size, test_buffer_.Size());
+        EXPECT_EQ(frame_size, deframer.ProcessInput(kBuffer, frame_size));
+        test_buffer_.Reset();
+      }
+    }
+    frame1 = sequence1->Next();
+    frame2 = sequence2->Next();
+  }
+  EXPECT_EQ(2u, received_count_);
+  auto it = received_payload_map_.find(3);
+  ASSERT_TRUE(it != received_payload_map_.end());
+  EXPECT_EQ(payload1, it->second);
+
+  it = received_payload_map_.find(5);
+  ASSERT_TRUE(it != received_payload_map_.end());
+  EXPECT_EQ(payload2, it->second);
+}
+
+}  // anonymous namespace
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/mock_spdy_framer_visitor.cc b/quiche/spdy/core/mock_spdy_framer_visitor.cc
new file mode 100644
index 0000000..cdc8906
--- /dev/null
+++ b/quiche/spdy/core/mock_spdy_framer_visitor.cc
@@ -0,0 +1,19 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/mock_spdy_framer_visitor.h"
+
+namespace spdy {
+
+namespace test {
+
+MockSpdyFramerVisitor::MockSpdyFramerVisitor() {
+  DelegateHeaderHandling();
+}
+
+MockSpdyFramerVisitor::~MockSpdyFramerVisitor() = default;
+
+}  // namespace test
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/mock_spdy_framer_visitor.h b/quiche/spdy/core/mock_spdy_framer_visitor.h
new file mode 100644
index 0000000..8aa79fd
--- /dev/null
+++ b/quiche/spdy/core/mock_spdy_framer_visitor.h
@@ -0,0 +1,150 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
+#define QUICHE_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
+
+#include <cstdint>
+#include <memory>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/recording_headers_handler.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+namespace spdy {
+
+namespace test {
+
+class QUICHE_NO_EXPORT MockSpdyFramerVisitor
+    : public SpdyFramerVisitorInterface {
+ public:
+  MockSpdyFramerVisitor();
+  ~MockSpdyFramerVisitor() override;
+
+  MOCK_METHOD(void,
+              OnError,
+              (http2::Http2DecoderAdapter::SpdyFramerError error,
+               std::string detailed_error),
+              (override));
+  MOCK_METHOD(void, OnCommonHeader,
+              (SpdyStreamId stream_id, size_t length, uint8_t type,
+               uint8_t flags),
+              (override));
+  MOCK_METHOD(void,
+              OnDataFrameHeader,
+              (SpdyStreamId stream_id, size_t length, bool fin),
+              (override));
+  MOCK_METHOD(void,
+              OnStreamFrameData,
+              (SpdyStreamId stream_id, const char* data, size_t len),
+              (override));
+  MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnStreamPadLength,
+              (SpdyStreamId stream_id, size_t value),
+              (override));
+  MOCK_METHOD(void,
+              OnStreamPadding,
+              (SpdyStreamId stream_id, size_t len),
+              (override));
+  MOCK_METHOD(SpdyHeadersHandlerInterface*,
+              OnHeaderFrameStart,
+              (SpdyStreamId stream_id),
+              (override));
+  MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
+  MOCK_METHOD(void,
+              OnRstStream,
+              (SpdyStreamId stream_id, SpdyErrorCode error_code),
+              (override));
+  MOCK_METHOD(void, OnSettings, (), (override));
+  MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
+  MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
+  MOCK_METHOD(void, OnSettingsEnd, (), (override));
+  MOCK_METHOD(void, OnSettingsAck, (), (override));
+  MOCK_METHOD(void,
+              OnGoAway,
+              (SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
+              (override));
+  MOCK_METHOD(bool, OnGoAwayFrameData, (const char* goaway_data, size_t len),
+              (override));
+  MOCK_METHOD(void,
+              OnHeaders,
+              (SpdyStreamId stream_id,
+               bool has_priority,
+               int weight,
+               SpdyStreamId parent_stream_id,
+               bool exclusive,
+               bool fin,
+               bool end),
+              (override));
+  MOCK_METHOD(void,
+              OnWindowUpdate,
+              (SpdyStreamId stream_id, int delta_window_size),
+              (override));
+  MOCK_METHOD(void,
+              OnPushPromise,
+              (SpdyStreamId stream_id,
+               SpdyStreamId promised_stream_id,
+               bool end),
+              (override));
+  MOCK_METHOD(void,
+              OnContinuation,
+              (SpdyStreamId stream_id, bool end),
+              (override));
+  MOCK_METHOD(
+      void,
+      OnAltSvc,
+      (SpdyStreamId stream_id,
+       absl::string_view origin,
+       const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
+      (override));
+  MOCK_METHOD(void,
+              OnPriority,
+              (SpdyStreamId stream_id,
+               SpdyStreamId parent_stream_id,
+               int weight,
+               bool exclusive),
+              (override));
+  MOCK_METHOD(void,
+              OnPriorityUpdate,
+              (SpdyStreamId prioritized_stream_id,
+               absl::string_view priority_field_value),
+              (override));
+  MOCK_METHOD(bool,
+              OnUnknownFrame,
+              (SpdyStreamId stream_id, uint8_t frame_type),
+              (override));
+
+  void DelegateHeaderHandling() {
+    ON_CALL(*this, OnHeaderFrameStart(testing::_))
+        .WillByDefault(testing::Invoke(
+            this, &MockSpdyFramerVisitor::ReturnTestHeadersHandler));
+    ON_CALL(*this, OnHeaderFrameEnd(testing::_))
+        .WillByDefault(testing::Invoke(
+            this, &MockSpdyFramerVisitor::ResetTestHeadersHandler));
+  }
+
+  SpdyHeadersHandlerInterface* ReturnTestHeadersHandler(
+      SpdyStreamId /* stream_id */) {
+    if (headers_handler_ == nullptr) {
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+    }
+    return headers_handler_.get();
+  }
+
+  void ResetTestHeadersHandler(SpdyStreamId /* stream_id */) {
+    headers_handler_.reset();
+  }
+
+  std::unique_ptr<SpdyHeadersHandlerInterface> headers_handler_;
+};
+
+}  // namespace test
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
diff --git a/quiche/spdy/core/no_op_headers_handler.h b/quiche/spdy/core/no_op_headers_handler.h
new file mode 100644
index 0000000..9db36d2
--- /dev/null
+++ b/quiche/spdy/core/no_op_headers_handler.h
@@ -0,0 +1,39 @@
+#ifndef QUICHE_SPDY_CORE_NO_OP_HEADERS_HANDLER_H_
+#define QUICHE_SPDY_CORE_NO_OP_HEADERS_HANDLER_H_
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/header_byte_listener_interface.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+
+namespace spdy {
+
+// Drops all header data, but passes information about header bytes parsed to
+// a listener.
+class QUICHE_EXPORT_PRIVATE NoOpHeadersHandler
+    : public SpdyHeadersHandlerInterface {
+ public:
+  // Does not take ownership of listener.
+  explicit NoOpHeadersHandler(HeaderByteListenerInterface* listener)
+      : listener_(listener) {}
+  NoOpHeadersHandler(const NoOpHeadersHandler&) = delete;
+  NoOpHeadersHandler& operator=(const NoOpHeadersHandler&) = delete;
+  ~NoOpHeadersHandler() override {}
+
+  // From SpdyHeadersHandlerInterface
+  void OnHeaderBlockStart() override {}
+  void OnHeader(absl::string_view /*key*/,
+                absl::string_view /*value*/) override {}
+  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                        size_t /* compressed_header_bytes */) override {
+    if (listener_ != nullptr) {
+      listener_->OnHeaderBytesReceived(uncompressed_header_bytes);
+    }
+  }
+
+ private:
+  HeaderByteListenerInterface* listener_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_NO_OP_HEADERS_HANDLER_H_
diff --git a/quiche/spdy/core/recording_headers_handler.cc b/quiche/spdy/core/recording_headers_handler.cc
new file mode 100644
index 0000000..7808e7f
--- /dev/null
+++ b/quiche/spdy/core/recording_headers_handler.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/recording_headers_handler.h"
+
+namespace spdy {
+
+RecordingHeadersHandler::RecordingHeadersHandler(
+    SpdyHeadersHandlerInterface* wrapped)
+    : wrapped_(wrapped) {}
+
+void RecordingHeadersHandler::OnHeaderBlockStart() {
+  block_.clear();
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeaderBlockStart();
+  }
+}
+
+void RecordingHeadersHandler::OnHeader(absl::string_view key,
+                                       absl::string_view value) {
+  block_.AppendValueOrAddHeader(key, value);
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeader(key, value);
+  }
+}
+
+void RecordingHeadersHandler::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                                               size_t compressed_header_bytes) {
+  uncompressed_header_bytes_ = uncompressed_header_bytes;
+  compressed_header_bytes_ = compressed_header_bytes;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeaderBlockEnd(uncompressed_header_bytes,
+                               compressed_header_bytes);
+  }
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/recording_headers_handler.h b/quiche/spdy/core/recording_headers_handler.h
new file mode 100644
index 0000000..a2c06ec
--- /dev/null
+++ b/quiche/spdy/core/recording_headers_handler.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
+#define QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+
+namespace spdy {
+
+// RecordingHeadersHandler copies the headers emitted from the deframer, and
+// when needed can forward events to another wrapped handler.
+class QUICHE_EXPORT_PRIVATE RecordingHeadersHandler
+    : public SpdyHeadersHandlerInterface {
+ public:
+  explicit RecordingHeadersHandler(
+      SpdyHeadersHandlerInterface* wrapped = nullptr);
+  RecordingHeadersHandler(const RecordingHeadersHandler&) = delete;
+  RecordingHeadersHandler& operator=(const RecordingHeadersHandler&) = delete;
+
+  void OnHeaderBlockStart() override;
+
+  void OnHeader(absl::string_view key, absl::string_view value) override;
+
+  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                        size_t compressed_header_bytes) override;
+
+  const Http2HeaderBlock& decoded_block() const { return block_; }
+  size_t uncompressed_header_bytes() const {
+    return uncompressed_header_bytes_;
+  }
+  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
+
+ private:
+  SpdyHeadersHandlerInterface* wrapped_ = nullptr;
+  Http2HeaderBlock block_;
+  size_t uncompressed_header_bytes_ = 0;
+  size_t compressed_header_bytes_ = 0;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
diff --git a/quiche/spdy/core/spdy_alt_svc_wire_format.cc b/quiche/spdy/core/spdy_alt_svc_wire_format.cc
new file mode 100644
index 0000000..08c301e
--- /dev/null
+++ b/quiche/spdy/core/spdy_alt_svc_wire_format.cc
@@ -0,0 +1,427 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+
+#include <algorithm>
+#include <cctype>
+#include <limits>
+
+#include "absl/strings/str_cat.h"
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+
+namespace {
+
+template <class T>
+bool ParsePositiveIntegerImpl(absl::string_view::const_iterator c,
+                              absl::string_view::const_iterator end,
+                              T* value) {
+  *value = 0;
+  for (; c != end && std::isdigit(*c); ++c) {
+    if (*value > std::numeric_limits<T>::max() / 10) {
+      return false;
+    }
+    *value *= 10;
+    if (*value > std::numeric_limits<T>::max() - (*c - '0')) {
+      return false;
+    }
+    *value += *c - '0';
+  }
+  return (c == end && *value > 0);
+}
+
+}  // namespace
+
+SpdyAltSvcWireFormat::AlternativeService::AlternativeService() = default;
+
+SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
+    const std::string& protocol_id, const std::string& host, uint16_t port,
+    uint32_t max_age_seconds, VersionVector version)
+    : protocol_id(protocol_id),
+      host(host),
+      port(port),
+      max_age_seconds(max_age_seconds),
+      version(std::move(version)) {}
+
+SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() = default;
+
+SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
+    const AlternativeService& other) = default;
+
+// static
+bool SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+    absl::string_view value,
+    AlternativeServiceVector* altsvc_vector) {
+  // Empty value is invalid according to the specification.
+  if (value.empty()) {
+    return false;
+  }
+  altsvc_vector->clear();
+  if (value == absl::string_view("clear")) {
+    return true;
+  }
+  absl::string_view::const_iterator c = value.begin();
+  while (c != value.end()) {
+    // Parse protocol-id.
+    absl::string_view::const_iterator percent_encoded_protocol_id_end =
+        std::find(c, value.end(), '=');
+    std::string protocol_id;
+    if (percent_encoded_protocol_id_end == c ||
+        !PercentDecode(c, percent_encoded_protocol_id_end, &protocol_id)) {
+      return false;
+    }
+    // Check for IETF format for advertising QUIC:
+    // hq=":443";quic=51303338;quic=51303334
+    const bool is_ietf_format_quic = (protocol_id == "hq");
+    c = percent_encoded_protocol_id_end;
+    if (c == value.end()) {
+      return false;
+    }
+    // Parse alt-authority.
+    QUICHE_DCHECK_EQ('=', *c);
+    ++c;
+    if (c == value.end() || *c != '"') {
+      return false;
+    }
+    ++c;
+    absl::string_view::const_iterator alt_authority_begin = c;
+    for (; c != value.end() && *c != '"'; ++c) {
+      // Decode backslash encoding.
+      if (*c != '\\') {
+        continue;
+      }
+      ++c;
+      if (c == value.end()) {
+        return false;
+      }
+    }
+    if (c == alt_authority_begin || c == value.end()) {
+      return false;
+    }
+    QUICHE_DCHECK_EQ('"', *c);
+    std::string host;
+    uint16_t port;
+    if (!ParseAltAuthority(alt_authority_begin, c, &host, &port)) {
+      return false;
+    }
+    ++c;
+    // Parse parameters.
+    uint32_t max_age_seconds = 86400;
+    VersionVector version;
+    absl::string_view::const_iterator parameters_end =
+        std::find(c, value.end(), ',');
+    while (c != parameters_end) {
+      SkipWhiteSpace(&c, parameters_end);
+      if (c == parameters_end) {
+        break;
+      }
+      if (*c != ';') {
+        return false;
+      }
+      ++c;
+      SkipWhiteSpace(&c, parameters_end);
+      if (c == parameters_end) {
+        break;
+      }
+      std::string parameter_name;
+      for (; c != parameters_end && *c != '=' && *c != ' ' && *c != '\t'; ++c) {
+        parameter_name.push_back(tolower(*c));
+      }
+      SkipWhiteSpace(&c, parameters_end);
+      if (c == parameters_end || *c != '=') {
+        return false;
+      }
+      ++c;
+      SkipWhiteSpace(&c, parameters_end);
+      absl::string_view::const_iterator parameter_value_begin = c;
+      for (; c != parameters_end && *c != ';' && *c != ' ' && *c != '\t'; ++c) {
+      }
+      if (c == parameter_value_begin) {
+        return false;
+      }
+      if (parameter_name == "ma") {
+        if (!ParsePositiveInteger32(parameter_value_begin, c,
+                                    &max_age_seconds)) {
+          return false;
+        }
+      } else if (!is_ietf_format_quic && parameter_name == "v") {
+        // Version is a comma separated list of positive integers enclosed in
+        // quotation marks.  Since it can contain commas, which are not
+        // delineating alternative service entries, |parameters_end| and |c| can
+        // be invalid.
+        if (*parameter_value_begin != '"') {
+          return false;
+        }
+        c = std::find(parameter_value_begin + 1, value.end(), '"');
+        if (c == value.end()) {
+          return false;
+        }
+        ++c;
+        parameters_end = std::find(c, value.end(), ',');
+        absl::string_view::const_iterator v_begin = parameter_value_begin + 1;
+        while (v_begin < c) {
+          absl::string_view::const_iterator v_end = v_begin;
+          while (v_end < c - 1 && *v_end != ',') {
+            ++v_end;
+          }
+          uint16_t v;
+          if (!ParsePositiveInteger16(v_begin, v_end, &v)) {
+            return false;
+          }
+          version.push_back(v);
+          v_begin = v_end + 1;
+          if (v_begin == c - 1) {
+            // List ends in comma.
+            return false;
+          }
+        }
+      } else if (is_ietf_format_quic && parameter_name == "quic") {
+        // IETF format for advertising QUIC. Version is hex encoding of QUIC
+        // version tag. Hex-encoded string should not include leading "0x" or
+        // leading zeros.
+        // Example for advertising QUIC versions "Q038" and "Q034":
+        // hq=":443";quic=51303338;quic=51303334
+        if (*parameter_value_begin == '0') {
+          return false;
+        }
+        // Versions will be stored as the uint32_t hex decoding of the param
+        // value string. Example: QUIC version "Q038", which is advertised as:
+        // hq=":443";quic=51303338
+        // ... will be stored in |versions| as 0x51303338.
+        uint32_t quic_version;
+        if (!HexDecodeToUInt32(absl::string_view(&*parameter_value_begin,
+                                                 c - parameter_value_begin),
+                               &quic_version) ||
+            quic_version == 0) {
+          return false;
+        }
+        version.push_back(quic_version);
+      }
+    }
+    altsvc_vector->emplace_back(protocol_id, host, port, max_age_seconds,
+                                version);
+    for (; c != value.end() && (*c == ' ' || *c == '\t' || *c == ','); ++c) {
+    }
+  }
+  return true;
+}
+
+// static
+std::string SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
+    const AlternativeServiceVector& altsvc_vector) {
+  if (altsvc_vector.empty()) {
+    return std::string("clear");
+  }
+  const char kNibbleToHex[] = "0123456789ABCDEF";
+  std::string value;
+  for (const AlternativeService& altsvc : altsvc_vector) {
+    if (!value.empty()) {
+      value.push_back(',');
+    }
+    // Check for IETF format for advertising QUIC.
+    const bool is_ietf_format_quic = (altsvc.protocol_id == "hq");
+    // Percent escape protocol id according to
+    // http://tools.ietf.org/html/rfc7230#section-3.2.6.
+    for (char c : altsvc.protocol_id) {
+      if (isalnum(c)) {
+        value.push_back(c);
+        continue;
+      }
+      switch (c) {
+        case '!':
+        case '#':
+        case '$':
+        case '&':
+        case '\'':
+        case '*':
+        case '+':
+        case '-':
+        case '.':
+        case '^':
+        case '_':
+        case '`':
+        case '|':
+        case '~':
+          value.push_back(c);
+          break;
+        default:
+          value.push_back('%');
+          // Network byte order is big-endian.
+          value.push_back(kNibbleToHex[c >> 4]);
+          value.push_back(kNibbleToHex[c & 0x0f]);
+          break;
+      }
+    }
+    value.push_back('=');
+    value.push_back('"');
+    for (char c : altsvc.host) {
+      if (c == '"' || c == '\\') {
+        value.push_back('\\');
+      }
+      value.push_back(c);
+    }
+    absl::StrAppend(&value, ":", altsvc.port, "\"");
+    if (altsvc.max_age_seconds != 86400) {
+      absl::StrAppend(&value, "; ma=", altsvc.max_age_seconds);
+    }
+    if (!altsvc.version.empty()) {
+      if (is_ietf_format_quic) {
+        for (uint32_t quic_version : altsvc.version) {
+          absl::StrAppend(&value, "; quic=", absl::Hex(quic_version));
+        }
+      } else {
+        value.append("; v=\"");
+        for (auto it = altsvc.version.begin(); it != altsvc.version.end();
+             ++it) {
+          if (it != altsvc.version.begin()) {
+            value.append(",");
+          }
+          absl::StrAppend(&value, *it);
+        }
+        value.append("\"");
+      }
+    }
+  }
+  return value;
+}
+
+// static
+void SpdyAltSvcWireFormat::SkipWhiteSpace(
+    absl::string_view::const_iterator* c,
+    absl::string_view::const_iterator end) {
+  for (; *c != end && (**c == ' ' || **c == '\t'); ++*c) {
+  }
+}
+
+// static
+bool SpdyAltSvcWireFormat::PercentDecode(absl::string_view::const_iterator c,
+                                         absl::string_view::const_iterator end,
+                                         std::string* output) {
+  output->clear();
+  for (; c != end; ++c) {
+    if (*c != '%') {
+      output->push_back(*c);
+      continue;
+    }
+    QUICHE_DCHECK_EQ('%', *c);
+    ++c;
+    if (c == end || !std::isxdigit(*c)) {
+      return false;
+    }
+    // Network byte order is big-endian.
+    char decoded = HexDigitToInt(*c) << 4;
+    ++c;
+    if (c == end || !std::isxdigit(*c)) {
+      return false;
+    }
+    decoded += HexDigitToInt(*c);
+    output->push_back(decoded);
+  }
+  return true;
+}
+
+// static
+bool SpdyAltSvcWireFormat::ParseAltAuthority(
+    absl::string_view::const_iterator c,
+    absl::string_view::const_iterator end,
+    std::string* host,
+    uint16_t* port) {
+  host->clear();
+  if (c == end) {
+    return false;
+  }
+  if (*c == '[') {
+    for (; c != end && *c != ']'; ++c) {
+      if (*c == '"') {
+        // Port is mandatory.
+        return false;
+      }
+      host->push_back(*c);
+    }
+    if (c == end) {
+      return false;
+    }
+    QUICHE_DCHECK_EQ(']', *c);
+    host->push_back(*c);
+    ++c;
+  } else {
+    for (; c != end && *c != ':'; ++c) {
+      if (*c == '"') {
+        // Port is mandatory.
+        return false;
+      }
+      if (*c == '\\') {
+        ++c;
+        if (c == end) {
+          return false;
+        }
+      }
+      host->push_back(*c);
+    }
+  }
+  if (c == end || *c != ':') {
+    return false;
+  }
+  QUICHE_DCHECK_EQ(':', *c);
+  ++c;
+  return ParsePositiveInteger16(c, end, port);
+}
+
+// static
+bool SpdyAltSvcWireFormat::ParsePositiveInteger16(
+    absl::string_view::const_iterator c,
+    absl::string_view::const_iterator end,
+    uint16_t* value) {
+  return ParsePositiveIntegerImpl<uint16_t>(c, end, value);
+}
+
+// static
+bool SpdyAltSvcWireFormat::ParsePositiveInteger32(
+    absl::string_view::const_iterator c,
+    absl::string_view::const_iterator end,
+    uint32_t* value) {
+  return ParsePositiveIntegerImpl<uint32_t>(c, end, value);
+}
+
+// static
+char SpdyAltSvcWireFormat::HexDigitToInt(char c) {
+  QUICHE_DCHECK(std::isxdigit(c));
+
+  if (std::isdigit(c)) {
+    return c - '0';
+  }
+  if (c >= 'A' && c <= 'F') {
+    return c - 'A' + 10;
+  }
+  if (c >= 'a' && c <= 'f') {
+    return c - 'a' + 10;
+  }
+
+  return 0;
+}
+
+// static
+bool SpdyAltSvcWireFormat::HexDecodeToUInt32(absl::string_view data,
+                                             uint32_t* value) {
+  if (data.empty() || data.length() > 8u) {
+    return false;
+  }
+
+  *value = 0;
+  for (char c : data) {
+    if (!std::isxdigit(c)) {
+      return false;
+    }
+
+    *value <<= 4;
+    *value += HexDigitToInt(c);
+  }
+
+  return true;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_alt_svc_wire_format.h b/quiche/spdy/core/spdy_alt_svc_wire_format.h
new file mode 100644
index 0000000..b81a979
--- /dev/null
+++ b/quiche/spdy/core/spdy_alt_svc_wire_format.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains data structures and utility functions used for serializing
+// and parsing alternative service header values, common to HTTP/1.1 header
+// fields and HTTP/2 and QUIC ALTSVC frames.  See specification at
+// https://httpwg.github.io/http-extensions/alt-svc.html.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
+#define QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace spdy {
+
+namespace test {
+class SpdyAltSvcWireFormatPeer;
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE SpdyAltSvcWireFormat {
+ public:
+  using VersionVector = absl::InlinedVector<uint32_t, 8>;
+
+  struct QUICHE_EXPORT_PRIVATE AlternativeService {
+    std::string protocol_id;
+    std::string host;
+
+    // Default is 0: invalid port.
+    uint16_t port = 0;
+    // Default is one day.
+    uint32_t max_age_seconds = 86400;
+    // Default is empty: unspecified version.
+    VersionVector version;
+
+    AlternativeService();
+    AlternativeService(const std::string& protocol_id, const std::string& host,
+                       uint16_t port, uint32_t max_age_seconds,
+                       VersionVector version);
+    AlternativeService(const AlternativeService& other);
+    ~AlternativeService();
+
+    bool operator==(const AlternativeService& other) const {
+      return protocol_id == other.protocol_id && host == other.host &&
+             port == other.port && version == other.version &&
+             max_age_seconds == other.max_age_seconds;
+    }
+  };
+  // An empty vector means alternative services should be cleared for given
+  // origin.  Note that the wire format for this is the string "clear", not an
+  // empty value (which is invalid).
+  typedef std::vector<AlternativeService> AlternativeServiceVector;
+
+  friend class test::SpdyAltSvcWireFormatPeer;
+  static bool ParseHeaderFieldValue(absl::string_view value,
+                                    AlternativeServiceVector* altsvc_vector);
+  static std::string SerializeHeaderFieldValue(
+      const AlternativeServiceVector& altsvc_vector);
+
+ private:
+  // Forward |*c| over space and tab or until |end| is reached.
+  static void SkipWhiteSpace(absl::string_view::const_iterator* c,
+                             absl::string_view::const_iterator end);
+  // Decode percent-decoded string between |c| and |end| into |*output|.
+  // Return true on success, false if input is invalid.
+  static bool PercentDecode(absl::string_view::const_iterator c,
+                            absl::string_view::const_iterator end,
+                            std::string* output);
+  // Parse the authority part of Alt-Svc between |c| and |end| into |*host| and
+  // |*port|.  Return true on success, false if input is invalid.
+  static bool ParseAltAuthority(absl::string_view::const_iterator c,
+                                absl::string_view::const_iterator end,
+                                std::string* host,
+                                uint16_t* port);
+  // Parse a positive integer between |c| and |end| into |*value|.
+  // Return true on success, false if input is not a positive integer or it
+  // cannot be represented on uint16_t.
+  static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
+                                     absl::string_view::const_iterator end,
+                                     uint16_t* value);
+  // Parse a positive integer between |c| and |end| into |*value|.
+  // Return true on success, false if input is not a positive integer or it
+  // cannot be represented on uint32_t.
+  static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
+                                     absl::string_view::const_iterator end,
+                                     uint32_t* value);
+  // Parse |c| as hexadecimal digit, case insensitive.  |c| must be [0-9a-fA-F].
+  // Output is between 0 and 15.
+  static char HexDigitToInt(char c);
+  // Parse |data| as hexadecimal number into |*value|.  |data| must only contain
+  // hexadecimal digits, no "0x" prefix.
+  // Return true on success, false if input is empty, not valid hexadecimal
+  // number, or cannot be represented on uint32_t.
+  static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value);
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
diff --git a/quiche/spdy/core/spdy_alt_svc_wire_format_test.cc b/quiche/spdy/core/spdy_alt_svc_wire_format_test.cc
new file mode 100644
index 0000000..e9cbc67
--- /dev/null
+++ b/quiche/spdy/core/spdy_alt_svc_wire_format_test.cc
@@ -0,0 +1,638 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+
+namespace test {
+
+// Expose all private methods of class SpdyAltSvcWireFormat.
+class SpdyAltSvcWireFormatPeer {
+ public:
+  static void SkipWhiteSpace(absl::string_view::const_iterator* c,
+                             absl::string_view::const_iterator end) {
+    SpdyAltSvcWireFormat::SkipWhiteSpace(c, end);
+  }
+  static bool PercentDecode(absl::string_view::const_iterator c,
+                            absl::string_view::const_iterator end,
+                            std::string* output) {
+    return SpdyAltSvcWireFormat::PercentDecode(c, end, output);
+  }
+  static bool ParseAltAuthority(absl::string_view::const_iterator c,
+                                absl::string_view::const_iterator end,
+                                std::string* host,
+                                uint16_t* port) {
+    return SpdyAltSvcWireFormat::ParseAltAuthority(c, end, host, port);
+  }
+  static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
+                                     absl::string_view::const_iterator end,
+                                     uint16_t* max_age_seconds) {
+    return SpdyAltSvcWireFormat::ParsePositiveInteger16(c, end,
+                                                        max_age_seconds);
+  }
+  static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
+                                     absl::string_view::const_iterator end,
+                                     uint32_t* max_age_seconds) {
+    return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end,
+                                                        max_age_seconds);
+  }
+  static char HexDigitToInt(char c) {
+    return SpdyAltSvcWireFormat::HexDigitToInt(c);
+  }
+  static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value) {
+    return SpdyAltSvcWireFormat::HexDecodeToUInt32(data, value);
+  }
+};
+
+namespace {
+
+// Generate header field values, possibly with multiply defined parameters and
+// random case, and corresponding AlternativeService entries.
+void FuzzHeaderFieldValue(
+    int i,
+    std::string* header_field_value,
+    SpdyAltSvcWireFormat::AlternativeService* expected_altsvc) {
+  if (!header_field_value->empty()) {
+    header_field_value->push_back(',');
+  }
+  // TODO(b/77515496): use struct of bools instead of int |i| to generate the
+  // header field value.
+  bool is_ietf_format_quic = (i & 1 << 0) != 0;
+  if (i & 1 << 0) {
+    expected_altsvc->protocol_id = "hq";
+    header_field_value->append("hq=\"");
+  } else {
+    expected_altsvc->protocol_id = "a=b%c";
+    header_field_value->append("a%3Db%25c=\"");
+  }
+  if (i & 1 << 1) {
+    expected_altsvc->host = "foo\"bar\\baz";
+    header_field_value->append("foo\\\"bar\\\\baz");
+  } else {
+    expected_altsvc->host = "";
+  }
+  expected_altsvc->port = 42;
+  header_field_value->append(":42\"");
+  if (i & 1 << 2) {
+    header_field_value->append(" ");
+  }
+  if (i & 3 << 3) {
+    expected_altsvc->max_age_seconds = 1111;
+    header_field_value->append(";");
+    if (i & 1 << 3) {
+      header_field_value->append(" ");
+    }
+    header_field_value->append("mA=1111");
+    if (i & 2 << 3) {
+      header_field_value->append(" ");
+    }
+  }
+  if (i & 1 << 5) {
+    header_field_value->append("; J=s");
+  }
+  if (i & 1 << 6) {
+    if (is_ietf_format_quic) {
+      if (i & 1 << 7) {
+        expected_altsvc->version.push_back(0x923457e);
+        header_field_value->append("; quic=923457E");
+      } else {
+        expected_altsvc->version.push_back(1);
+        expected_altsvc->version.push_back(0xFFFFFFFF);
+        header_field_value->append("; quic=1; quic=fFfFffFf");
+      }
+    } else {
+      if (i & i << 7) {
+        expected_altsvc->version.push_back(24);
+        header_field_value->append("; v=\"24\"");
+      } else {
+        expected_altsvc->version.push_back(1);
+        expected_altsvc->version.push_back(65535);
+        header_field_value->append("; v=\"1,65535\"");
+      }
+    }
+  }
+  if (i & 1 << 8) {
+    expected_altsvc->max_age_seconds = 999999999;
+    header_field_value->append("; Ma=999999999");
+  }
+  if (i & 1 << 9) {
+    header_field_value->append(";");
+  }
+  if (i & 1 << 10) {
+    header_field_value->append(" ");
+  }
+  if (i & 1 << 11) {
+    header_field_value->append(",");
+  }
+  if (i & 1 << 12) {
+    header_field_value->append(" ");
+  }
+}
+
+// Generate AlternativeService entries and corresponding header field values in
+// canonical form, that is, what SerializeHeaderFieldValue() should output.
+void FuzzAlternativeService(int i,
+                            SpdyAltSvcWireFormat::AlternativeService* altsvc,
+                            std::string* expected_header_field_value) {
+  if (!expected_header_field_value->empty()) {
+    expected_header_field_value->push_back(',');
+  }
+  altsvc->protocol_id = "a=b%c";
+  altsvc->port = 42;
+  expected_header_field_value->append("a%3Db%25c=\"");
+  if (i & 1 << 0) {
+    altsvc->host = "foo\"bar\\baz";
+    expected_header_field_value->append("foo\\\"bar\\\\baz");
+  }
+  expected_header_field_value->append(":42\"");
+  if (i & 1 << 1) {
+    altsvc->max_age_seconds = 1111;
+    expected_header_field_value->append("; ma=1111");
+  }
+  if (i & 1 << 2) {
+    altsvc->version.push_back(24);
+    altsvc->version.push_back(25);
+    expected_header_field_value->append("; v=\"24,25\"");
+  }
+}
+
+// Tests of public API.
+
+TEST(SpdyAltSvcWireFormatTest, DefaultValues) {
+  SpdyAltSvcWireFormat::AlternativeService altsvc;
+  EXPECT_EQ("", altsvc.protocol_id);
+  EXPECT_EQ("", altsvc.host);
+  EXPECT_EQ(0u, altsvc.port);
+  EXPECT_EQ(86400u, altsvc.max_age_seconds);
+  EXPECT_TRUE(altsvc.version.empty());
+}
+
+TEST(SpdyAltSvcWireFormatTest, ParseInvalidEmptyHeaderFieldValue) {
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  ASSERT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue("", &altsvc_vector));
+}
+
+TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueClear) {
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  ASSERT_TRUE(
+      SpdyAltSvcWireFormat::ParseHeaderFieldValue("clear", &altsvc_vector));
+  EXPECT_EQ(0u, altsvc_vector.size());
+}
+
+// Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
+// parameters, duplicate parameters, trailing space, trailing alternate service
+// separator, etc.  Single alternative service at a time.
+TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) {
+  for (int i = 0; i < 1 << 13; ++i) {
+    std::string header_field_value;
+    SpdyAltSvcWireFormat::AlternativeService expected_altsvc;
+    FuzzHeaderFieldValue(i, &header_field_value, &expected_altsvc);
+    SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(header_field_value,
+                                                            &altsvc_vector));
+    ASSERT_EQ(1u, altsvc_vector.size());
+    EXPECT_EQ(expected_altsvc.protocol_id, altsvc_vector[0].protocol_id);
+    EXPECT_EQ(expected_altsvc.host, altsvc_vector[0].host);
+    EXPECT_EQ(expected_altsvc.port, altsvc_vector[0].port);
+    EXPECT_EQ(expected_altsvc.max_age_seconds,
+              altsvc_vector[0].max_age_seconds);
+    EXPECT_EQ(expected_altsvc.version, altsvc_vector[0].version);
+
+    // Roundtrip test starting with |altsvc_vector|.
+    std::string reserialized_header_field_value =
+        SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector);
+    SpdyAltSvcWireFormat::AlternativeServiceVector roundtrip_altsvc_vector;
+    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+        reserialized_header_field_value, &roundtrip_altsvc_vector));
+    ASSERT_EQ(1u, roundtrip_altsvc_vector.size());
+    EXPECT_EQ(expected_altsvc.protocol_id,
+              roundtrip_altsvc_vector[0].protocol_id);
+    EXPECT_EQ(expected_altsvc.host, roundtrip_altsvc_vector[0].host);
+    EXPECT_EQ(expected_altsvc.port, roundtrip_altsvc_vector[0].port);
+    EXPECT_EQ(expected_altsvc.max_age_seconds,
+              roundtrip_altsvc_vector[0].max_age_seconds);
+    EXPECT_EQ(expected_altsvc.version, roundtrip_altsvc_vector[0].version);
+  }
+}
+
+// Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
+// parameters, duplicate parameters, trailing space, trailing alternate service
+// separator, etc.  Possibly multiple alternative service at a time.
+TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueMultiple) {
+  for (int i = 0; i < 1 << 13;) {
+    std::string header_field_value;
+    SpdyAltSvcWireFormat::AlternativeServiceVector expected_altsvc_vector;
+    // This will generate almost two hundred header field values with two,
+    // three, four, five, six, and seven alternative services each, and
+    // thousands with a single one.
+    do {
+      SpdyAltSvcWireFormat::AlternativeService expected_altsvc;
+      FuzzHeaderFieldValue(i, &header_field_value, &expected_altsvc);
+      expected_altsvc_vector.push_back(expected_altsvc);
+      ++i;
+    } while (i % 6 < i % 7);
+    SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(header_field_value,
+                                                            &altsvc_vector));
+    ASSERT_EQ(expected_altsvc_vector.size(), altsvc_vector.size());
+    for (unsigned int j = 0; j < altsvc_vector.size(); ++j) {
+      EXPECT_EQ(expected_altsvc_vector[j].protocol_id,
+                altsvc_vector[j].protocol_id);
+      EXPECT_EQ(expected_altsvc_vector[j].host, altsvc_vector[j].host);
+      EXPECT_EQ(expected_altsvc_vector[j].port, altsvc_vector[j].port);
+      EXPECT_EQ(expected_altsvc_vector[j].max_age_seconds,
+                altsvc_vector[j].max_age_seconds);
+      EXPECT_EQ(expected_altsvc_vector[j].version, altsvc_vector[j].version);
+    }
+
+    // Roundtrip test starting with |altsvc_vector|.
+    std::string reserialized_header_field_value =
+        SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector);
+    SpdyAltSvcWireFormat::AlternativeServiceVector roundtrip_altsvc_vector;
+    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+        reserialized_header_field_value, &roundtrip_altsvc_vector));
+    ASSERT_EQ(expected_altsvc_vector.size(), roundtrip_altsvc_vector.size());
+    for (unsigned int j = 0; j < roundtrip_altsvc_vector.size(); ++j) {
+      EXPECT_EQ(expected_altsvc_vector[j].protocol_id,
+                roundtrip_altsvc_vector[j].protocol_id);
+      EXPECT_EQ(expected_altsvc_vector[j].host,
+                roundtrip_altsvc_vector[j].host);
+      EXPECT_EQ(expected_altsvc_vector[j].port,
+                roundtrip_altsvc_vector[j].port);
+      EXPECT_EQ(expected_altsvc_vector[j].max_age_seconds,
+                roundtrip_altsvc_vector[j].max_age_seconds);
+      EXPECT_EQ(expected_altsvc_vector[j].version,
+                roundtrip_altsvc_vector[j].version);
+    }
+  }
+}
+
+TEST(SpdyAltSvcWireFormatTest, SerializeEmptyHeaderFieldValue) {
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  EXPECT_EQ("clear",
+            SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
+}
+
+// Test ParseHeaderFieldValue() and SerializeHeaderFieldValue() on the same pair
+// of |expected_header_field_value| and |altsvc|, with and without hostname and
+// each
+// parameter.  Single alternative service at a time.
+TEST(SpdyAltSvcWireFormatTest, RoundTrip) {
+  for (int i = 0; i < 1 << 3; ++i) {
+    SpdyAltSvcWireFormat::AlternativeService altsvc;
+    std::string expected_header_field_value;
+    FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
+
+    // Test ParseHeaderFieldValue().
+    SpdyAltSvcWireFormat::AlternativeServiceVector parsed_altsvc_vector;
+    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+        expected_header_field_value, &parsed_altsvc_vector));
+    ASSERT_EQ(1u, parsed_altsvc_vector.size());
+    EXPECT_EQ(altsvc.protocol_id, parsed_altsvc_vector[0].protocol_id);
+    EXPECT_EQ(altsvc.host, parsed_altsvc_vector[0].host);
+    EXPECT_EQ(altsvc.port, parsed_altsvc_vector[0].port);
+    EXPECT_EQ(altsvc.max_age_seconds, parsed_altsvc_vector[0].max_age_seconds);
+    EXPECT_EQ(altsvc.version, parsed_altsvc_vector[0].version);
+
+    // Test SerializeHeaderFieldValue().
+    SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+    altsvc_vector.push_back(altsvc);
+    EXPECT_EQ(expected_header_field_value,
+              SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
+  }
+}
+
+// Test ParseHeaderFieldValue() and SerializeHeaderFieldValue() on the same pair
+// of |expected_header_field_value| and |altsvc|, with and without hostname and
+// each
+// parameter.  Multiple alternative services at a time.
+TEST(SpdyAltSvcWireFormatTest, RoundTripMultiple) {
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  std::string expected_header_field_value;
+  for (int i = 0; i < 1 << 3; ++i) {
+    SpdyAltSvcWireFormat::AlternativeService altsvc;
+    FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
+    altsvc_vector.push_back(altsvc);
+  }
+
+  // Test ParseHeaderFieldValue().
+  SpdyAltSvcWireFormat::AlternativeServiceVector parsed_altsvc_vector;
+  ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+      expected_header_field_value, &parsed_altsvc_vector));
+  ASSERT_EQ(altsvc_vector.size(), parsed_altsvc_vector.size());
+  auto expected_it = altsvc_vector.begin();
+  auto parsed_it = parsed_altsvc_vector.begin();
+  for (; expected_it != altsvc_vector.end(); ++expected_it, ++parsed_it) {
+    EXPECT_EQ(expected_it->protocol_id, parsed_it->protocol_id);
+    EXPECT_EQ(expected_it->host, parsed_it->host);
+    EXPECT_EQ(expected_it->port, parsed_it->port);
+    EXPECT_EQ(expected_it->max_age_seconds, parsed_it->max_age_seconds);
+    EXPECT_EQ(expected_it->version, parsed_it->version);
+  }
+
+  // Test SerializeHeaderFieldValue().
+  EXPECT_EQ(expected_header_field_value,
+            SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
+}
+
+// ParseHeaderFieldValue() should return false on malformed field values:
+// invalid percent encoding, unmatched quotation mark, empty port, non-numeric
+// characters in numeric fields.
+TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) {
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  const char* invalid_field_value_array[] = {"a%",
+                                             "a%x",
+                                             "a%b",
+                                             "a%9z",
+                                             "a=",
+                                             "a=\"",
+                                             "a=\"b\"",
+                                             "a=\":\"",
+                                             "a=\"c:\"",
+                                             "a=\"c:foo\"",
+                                             "a=\"c:42foo\"",
+                                             "a=\"b:42\"bar",
+                                             "a=\"b:42\" ; m",
+                                             "a=\"b:42\" ; min-age",
+                                             "a=\"b:42\" ; ma",
+                                             "a=\"b:42\" ; ma=",
+                                             "a=\"b:42\" ; v=\"..\"",
+                                             "a=\"b:42\" ; ma=ma",
+                                             "a=\"b:42\" ; ma=123bar",
+                                             "a=\"b:42\" ; v=24",
+                                             "a=\"b:42\" ; v=24,25",
+                                             "a=\"b:42\" ; v=\"-3\"",
+                                             "a=\"b:42\" ; v=\"1.2\"",
+                                             "a=\"b:42\" ; v=\"24,\""};
+  for (const char* invalid_field_value : invalid_field_value_array) {
+    EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+        invalid_field_value, &altsvc_vector))
+        << invalid_field_value;
+  }
+}
+
+// ParseHeaderFieldValue() should return false on a field values truncated
+// before closing quotation mark, without trying to access memory beyond the end
+// of the input.
+TEST(SpdyAltSvcWireFormatTest, ParseTruncatedHeaderFieldValue) {
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  const char* field_value_array[] = {"a=\":137\"", "a=\"foo:137\"",
+                                     "a%25=\"foo\\\"bar\\\\baz:137\""};
+  for (const std::string& field_value : field_value_array) {
+    for (size_t len = 1; len < field_value.size(); ++len) {
+      EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+          field_value.substr(0, len), &altsvc_vector))
+          << len;
+    }
+  }
+}
+
+// Tests of private methods.
+
+// Test SkipWhiteSpace().
+TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) {
+  absl::string_view input("a \tb  ");
+  absl::string_view::const_iterator c = input.begin();
+  SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+  ASSERT_EQ(input.begin(), c);
+  ++c;
+  SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+  ASSERT_EQ(input.begin() + 3, c);
+  ++c;
+  SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+  ASSERT_EQ(input.end(), c);
+}
+
+// Test PercentDecode() on valid input.
+TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) {
+  absl::string_view input("");
+  std::string output;
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+                                                      input.end(), &output));
+  EXPECT_EQ("", output);
+
+  input = absl::string_view("foo");
+  output.clear();
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+                                                      input.end(), &output));
+  EXPECT_EQ("foo", output);
+
+  input = absl::string_view("%2ca%5Cb");
+  output.clear();
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+                                                      input.end(), &output));
+  EXPECT_EQ(",a\\b", output);
+}
+
+// Test PercentDecode() on invalid input.
+TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) {
+  const char* invalid_input_array[] = {"a%", "a%x", "a%b", "%J22", "%9z"};
+  for (const char* invalid_input : invalid_input_array) {
+    absl::string_view input(invalid_input);
+    std::string output;
+    EXPECT_FALSE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+                                                         input.end(), &output))
+        << input;
+  }
+}
+
+// Test ParseAltAuthority() on valid input.
+TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) {
+  absl::string_view input(":42");
+  std::string host;
+  uint16_t port;
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+      input.begin(), input.end(), &host, &port));
+  EXPECT_TRUE(host.empty());
+  EXPECT_EQ(42, port);
+
+  input = absl::string_view("foo:137");
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+      input.begin(), input.end(), &host, &port));
+  EXPECT_EQ("foo", host);
+  EXPECT_EQ(137, port);
+
+  input = absl::string_view("[2003:8:0:16::509d:9615]:443");
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+      input.begin(), input.end(), &host, &port));
+  EXPECT_EQ("[2003:8:0:16::509d:9615]", host);
+  EXPECT_EQ(443, port);
+}
+
+// Test ParseAltAuthority() on invalid input: empty string, no port, zero port,
+// non-digit characters following port.
+TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) {
+  const char* invalid_input_array[] = {"",
+                                       ":",
+                                       "foo:",
+                                       ":bar",
+                                       ":0",
+                                       "foo:0",
+                                       ":12bar",
+                                       "foo:23bar",
+                                       " ",
+                                       ":12 ",
+                                       "foo:12 ",
+                                       "[2003:8:0:16::509d:9615]",
+                                       "[2003:8:0:16::509d:9615]:",
+                                       "[2003:8:0:16::509d:9615]foo:443",
+                                       "[2003:8:0:16::509d:9615:443",
+                                       "2003:8:0:16::509d:9615]:443"};
+  for (const char* invalid_input : invalid_input_array) {
+    absl::string_view input(invalid_input);
+    std::string host;
+    uint16_t port;
+    EXPECT_FALSE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+        input.begin(), input.end(), &host, &port))
+        << input;
+  }
+}
+
+// Test ParseInteger() on valid input.
+TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) {
+  absl::string_view input("3");
+  uint16_t value;
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+      input.begin(), input.end(), &value));
+  EXPECT_EQ(3, value);
+
+  input = absl::string_view("1337");
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+      input.begin(), input.end(), &value));
+  EXPECT_EQ(1337, value);
+}
+
+// Test ParseIntegerValid() on invalid input: empty, zero, non-numeric, trailing
+// non-numeric characters.
+TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) {
+  const char* invalid_input_array[] = {"", " ", "a", "0", "00", "1 ", "12b"};
+  for (const char* invalid_input : invalid_input_array) {
+    absl::string_view input(invalid_input);
+    uint16_t value;
+    EXPECT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+        input.begin(), input.end(), &value))
+        << input;
+  }
+}
+
+// Test ParseIntegerValid() around overflow limit.
+TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) {
+  // Largest possible uint16_t value.
+  absl::string_view input("65535");
+  uint16_t value16;
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+      input.begin(), input.end(), &value16));
+  EXPECT_EQ(65535, value16);
+
+  // Overflow uint16_t, ParsePositiveInteger16() should return false.
+  input = absl::string_view("65536");
+  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+      input.begin(), input.end(), &value16));
+
+  // However, even if overflow is not checked for, 65536 overflows to 0, which
+  // returns false anyway.  Check for a larger number which overflows to 1.
+  input = absl::string_view("65537");
+  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+      input.begin(), input.end(), &value16));
+
+  // Largest possible uint32_t value.
+  input = absl::string_view("4294967295");
+  uint32_t value32;
+  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+      input.begin(), input.end(), &value32));
+  EXPECT_EQ(4294967295, value32);
+
+  // Overflow uint32_t, ParsePositiveInteger32() should return false.
+  input = absl::string_view("4294967296");
+  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+      input.begin(), input.end(), &value32));
+
+  // However, even if overflow is not checked for, 4294967296 overflows to 0,
+  // which returns false anyway.  Check for a larger number which overflows to
+  // 1.
+  input = absl::string_view("4294967297");
+  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+      input.begin(), input.end(), &value32));
+}
+
+// Test parsing an Alt-Svc entry with IP literal hostname.
+// Regression test for https://crbug.com/664173.
+TEST(SpdyAltSvcWireFormatTest, ParseIPLiteral) {
+  const char* input =
+      "quic=\"[2003:8:0:16::509d:9615]:443\"; v=\"36,35\"; ma=60";
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  ASSERT_TRUE(
+      SpdyAltSvcWireFormat::ParseHeaderFieldValue(input, &altsvc_vector));
+  EXPECT_EQ(1u, altsvc_vector.size());
+  EXPECT_EQ("quic", altsvc_vector[0].protocol_id);
+  EXPECT_EQ("[2003:8:0:16::509d:9615]", altsvc_vector[0].host);
+  EXPECT_EQ(443u, altsvc_vector[0].port);
+  EXPECT_EQ(60u, altsvc_vector[0].max_age_seconds);
+  EXPECT_THAT(altsvc_vector[0].version, ::testing::ElementsAre(36, 35));
+}
+
+TEST(SpdyAltSvcWireFormatTest, HexDigitToInt) {
+  EXPECT_EQ(0, SpdyAltSvcWireFormatPeer::HexDigitToInt('0'));
+  EXPECT_EQ(1, SpdyAltSvcWireFormatPeer::HexDigitToInt('1'));
+  EXPECT_EQ(2, SpdyAltSvcWireFormatPeer::HexDigitToInt('2'));
+  EXPECT_EQ(3, SpdyAltSvcWireFormatPeer::HexDigitToInt('3'));
+  EXPECT_EQ(4, SpdyAltSvcWireFormatPeer::HexDigitToInt('4'));
+  EXPECT_EQ(5, SpdyAltSvcWireFormatPeer::HexDigitToInt('5'));
+  EXPECT_EQ(6, SpdyAltSvcWireFormatPeer::HexDigitToInt('6'));
+  EXPECT_EQ(7, SpdyAltSvcWireFormatPeer::HexDigitToInt('7'));
+  EXPECT_EQ(8, SpdyAltSvcWireFormatPeer::HexDigitToInt('8'));
+  EXPECT_EQ(9, SpdyAltSvcWireFormatPeer::HexDigitToInt('9'));
+
+  EXPECT_EQ(10, SpdyAltSvcWireFormatPeer::HexDigitToInt('a'));
+  EXPECT_EQ(11, SpdyAltSvcWireFormatPeer::HexDigitToInt('b'));
+  EXPECT_EQ(12, SpdyAltSvcWireFormatPeer::HexDigitToInt('c'));
+  EXPECT_EQ(13, SpdyAltSvcWireFormatPeer::HexDigitToInt('d'));
+  EXPECT_EQ(14, SpdyAltSvcWireFormatPeer::HexDigitToInt('e'));
+  EXPECT_EQ(15, SpdyAltSvcWireFormatPeer::HexDigitToInt('f'));
+
+  EXPECT_EQ(10, SpdyAltSvcWireFormatPeer::HexDigitToInt('A'));
+  EXPECT_EQ(11, SpdyAltSvcWireFormatPeer::HexDigitToInt('B'));
+  EXPECT_EQ(12, SpdyAltSvcWireFormatPeer::HexDigitToInt('C'));
+  EXPECT_EQ(13, SpdyAltSvcWireFormatPeer::HexDigitToInt('D'));
+  EXPECT_EQ(14, SpdyAltSvcWireFormatPeer::HexDigitToInt('E'));
+  EXPECT_EQ(15, SpdyAltSvcWireFormatPeer::HexDigitToInt('F'));
+}
+
+TEST(SpdyAltSvcWireFormatTest, HexDecodeToUInt32) {
+  uint32_t out;
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("00", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0000000", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("00000000", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1", &out));
+  EXPECT_EQ(1u, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("ffffFFF", &out));
+  EXPECT_EQ(0xFFFFFFFu, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("fFfFffFf", &out));
+  EXPECT_EQ(0xFFFFFFFFu, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("01AEF", &out));
+  EXPECT_EQ(0x1AEFu, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("abcde", &out));
+  EXPECT_EQ(0xABCDEu, out);
+  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1234abcd", &out));
+  EXPECT_EQ(0x1234ABCDu, out);
+
+  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("", &out));
+  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("111111111", &out));
+  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1111111111", &out));
+  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0x1111", &out));
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace spdy
diff --git a/spdy/core/spdy_bitmasks.h b/quiche/spdy/core/spdy_bitmasks.h
similarity index 100%
rename from spdy/core/spdy_bitmasks.h
rename to quiche/spdy/core/spdy_bitmasks.h
diff --git a/quiche/spdy/core/spdy_frame_builder.cc b/quiche/spdy/core/spdy_frame_builder.cc
new file mode 100644
index 0000000..a9a8923
--- /dev/null
+++ b/quiche/spdy/core/spdy_frame_builder.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_frame_builder.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <new>
+
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/zero_copy_output_buffer.h"
+
+namespace spdy {
+
+SpdyFrameBuilder::SpdyFrameBuilder(size_t size)
+    : buffer_(new char[size]), capacity_(size), length_(0), offset_(0) {}
+
+SpdyFrameBuilder::SpdyFrameBuilder(size_t size, ZeroCopyOutputBuffer* output)
+    : buffer_(output == nullptr ? new char[size] : nullptr),
+      output_(output),
+      capacity_(size),
+      length_(0),
+      offset_(0) {}
+
+SpdyFrameBuilder::~SpdyFrameBuilder() = default;
+
+char* SpdyFrameBuilder::GetWritableBuffer(size_t length) {
+  if (!CanWrite(length)) {
+    return nullptr;
+  }
+  return buffer_.get() + offset_ + length_;
+}
+
+char* SpdyFrameBuilder::GetWritableOutput(size_t length,
+                                          size_t* actual_length) {
+  char* dest = nullptr;
+  int size = 0;
+
+  if (!CanWrite(length)) {
+    return nullptr;
+  }
+  output_->Next(&dest, &size);
+  *actual_length = std::min<size_t>(length, size);
+  return dest;
+}
+
+bool SpdyFrameBuilder::Seek(size_t length) {
+  if (!CanWrite(length)) {
+    return false;
+  }
+  if (output_ == nullptr) {
+    length_ += length;
+  } else {
+    output_->AdvanceWritePtr(length);
+    length_ += length;
+  }
+  return true;
+}
+
+bool SpdyFrameBuilder::BeginNewFrame(SpdyFrameType type,
+                                     uint8_t flags,
+                                     SpdyStreamId stream_id) {
+  uint8_t raw_frame_type = SerializeFrameType(type);
+  QUICHE_DCHECK(IsDefinedFrameType(raw_frame_type));
+  QUICHE_DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  bool success = true;
+  if (length_ > 0) {
+    QUICHE_BUG(spdy_bug_73_1)
+        << "SpdyFrameBuilder doesn't have a clean state when BeginNewFrame"
+        << "is called. Leftover length_ is " << length_;
+    offset_ += length_;
+    length_ = 0;
+  }
+
+  success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize);
+  success &= WriteUInt8(raw_frame_type);
+  success &= WriteUInt8(flags);
+  success &= WriteUInt32(stream_id);
+  QUICHE_DCHECK_EQ(kDataFrameMinimumSize, length_);
+  return success;
+}
+
+bool SpdyFrameBuilder::BeginNewFrame(SpdyFrameType type,
+                                     uint8_t flags,
+                                     SpdyStreamId stream_id,
+                                     size_t length) {
+  uint8_t raw_frame_type = SerializeFrameType(type);
+  QUICHE_DCHECK(IsDefinedFrameType(raw_frame_type));
+  QUICHE_DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+  QUICHE_BUG_IF(spdy_bug_73_2, length > kHttp2DefaultFramePayloadLimit)
+      << "Frame length  " << length_ << " is longer than frame size limit.";
+  return BeginNewFrameInternal(raw_frame_type, flags, stream_id, length);
+}
+
+bool SpdyFrameBuilder::BeginNewUncheckedFrame(uint8_t raw_frame_type,
+                                              uint8_t flags,
+                                              SpdyStreamId stream_id,
+                                              size_t length) {
+  return BeginNewFrameInternal(raw_frame_type, flags, stream_id, length);
+}
+
+bool SpdyFrameBuilder::BeginNewFrameInternal(uint8_t raw_frame_type,
+                                             uint8_t flags,
+                                             SpdyStreamId stream_id,
+                                             size_t length) {
+  QUICHE_DCHECK_EQ(length, length & kLengthMask);
+  bool success = true;
+
+  offset_ += length_;
+  length_ = 0;
+
+  success &= WriteUInt24(length);
+  success &= WriteUInt8(raw_frame_type);
+  success &= WriteUInt8(flags);
+  success &= WriteUInt32(stream_id);
+  QUICHE_DCHECK_EQ(kDataFrameMinimumSize, length_);
+  return success;
+}
+
+bool SpdyFrameBuilder::WriteStringPiece32(const absl::string_view value) {
+  if (!WriteUInt32(value.size())) {
+    return false;
+  }
+
+  return WriteBytes(value.data(), value.size());
+}
+
+bool SpdyFrameBuilder::WriteBytes(const void* data, uint32_t data_len) {
+  if (!CanWrite(data_len)) {
+    return false;
+  }
+
+  if (output_ == nullptr) {
+    char* dest = GetWritableBuffer(data_len);
+    memcpy(dest, data, data_len);
+    Seek(data_len);
+  } else {
+    char* dest = nullptr;
+    size_t size = 0;
+    size_t total_written = 0;
+    const char* data_ptr = reinterpret_cast<const char*>(data);
+    while (data_len > 0) {
+      dest = GetWritableOutput(data_len, &size);
+      if (dest == nullptr || size == 0) {
+        // Unable to make progress.
+        return false;
+      }
+      uint32_t to_copy = std::min<uint32_t>(data_len, size);
+      const char* src = data_ptr + total_written;
+      memcpy(dest, src, to_copy);
+      Seek(to_copy);
+      data_len -= to_copy;
+      total_written += to_copy;
+    }
+  }
+  return true;
+}
+
+bool SpdyFrameBuilder::CanWrite(size_t length) const {
+  if (length > kLengthMask) {
+    QUICHE_DCHECK(false);
+    return false;
+  }
+
+  if (output_ == nullptr) {
+    if (offset_ + length_ + length > capacity_) {
+      QUICHE_DLOG(FATAL) << "Requested: " << length
+                         << " capacity: " << capacity_
+                         << " used: " << offset_ + length_;
+      return false;
+    }
+  } else {
+    if (length > output_->BytesFree()) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_frame_builder.h b/quiche/spdy/core/spdy_frame_builder.h
new file mode 100644
index 0000000..129a784
--- /dev/null
+++ b/quiche/spdy/core/spdy_frame_builder.h
@@ -0,0 +1,146 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_FRAME_BUILDER_H_
+#define QUICHE_SPDY_CORE_SPDY_FRAME_BUILDER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_endian.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/zero_copy_output_buffer.h"
+
+namespace spdy {
+
+namespace test {
+class SpdyFrameBuilderPeer;
+}  // namespace test
+
+// This class provides facilities for basic binary value packing
+// into Spdy frames.
+//
+// The SpdyFrameBuilder supports appending primitive values (int, string, etc)
+// to a frame instance.  The SpdyFrameBuilder grows its internal memory buffer
+// dynamically to hold the sequence of primitive values.   The internal memory
+// buffer is exposed as the "data" of the SpdyFrameBuilder.
+class QUICHE_EXPORT_PRIVATE SpdyFrameBuilder {
+ public:
+  // Initializes a SpdyFrameBuilder with a buffer of given size
+  explicit SpdyFrameBuilder(size_t size);
+  // Doesn't take ownership of output.
+  SpdyFrameBuilder(size_t size, ZeroCopyOutputBuffer* output);
+
+  ~SpdyFrameBuilder();
+
+  // Returns the total size of the SpdyFrameBuilder's data, which may include
+  // multiple frames.
+  size_t length() const { return offset_ + length_; }
+
+  // Seeks forward by the given number of bytes. Useful in conjunction with
+  // GetWriteableBuffer() above.
+  bool Seek(size_t length);
+
+  // Populates this frame with a HTTP2 frame prefix using length information
+  // from |capacity_|. The given type must be a control frame type.
+  bool BeginNewFrame(SpdyFrameType type, uint8_t flags, SpdyStreamId stream_id);
+
+  // Populates this frame with a HTTP2 frame prefix with type and length
+  // information.  |type| must be a defined frame type.
+  bool BeginNewFrame(SpdyFrameType type,
+                     uint8_t flags,
+                     SpdyStreamId stream_id,
+                     size_t length);
+
+  // Populates this frame with a HTTP2 frame prefix with type and length
+  // information.  |raw_frame_type| may be a defined or undefined frame type.
+  bool BeginNewUncheckedFrame(uint8_t raw_frame_type,
+                              uint8_t flags,
+                              SpdyStreamId stream_id,
+                              size_t length);
+
+  // Takes the buffer from the SpdyFrameBuilder.
+  SpdySerializedFrame take() {
+    QUICHE_BUG_IF(spdy_bug_39_1, output_ != nullptr)
+        << "ZeroCopyOutputBuffer is used to build "
+        << "frames. take() shouldn't be called";
+    QUICHE_BUG_IF(spdy_bug_39_2, kMaxFrameSizeLimit < length_)
+        << "Frame length " << length_
+        << " is longer than the maximum possible allowed length.";
+    SpdySerializedFrame rv(buffer_.release(), length(), true);
+    capacity_ = 0;
+    length_ = 0;
+    offset_ = 0;
+    return rv;
+  }
+
+  // Methods for adding to the payload.  These values are appended to the end
+  // of the SpdyFrameBuilder payload. Note - binary integers are converted from
+  // host to network form.
+  bool WriteUInt8(uint8_t value) { return WriteBytes(&value, sizeof(value)); }
+  bool WriteUInt16(uint16_t value) {
+    value = quiche::QuicheEndian::HostToNet16(value);
+    return WriteBytes(&value, sizeof(value));
+  }
+  bool WriteUInt24(uint32_t value) {
+    value = quiche::QuicheEndian::HostToNet32(value);
+    return WriteBytes(reinterpret_cast<char*>(&value) + 1, sizeof(value) - 1);
+  }
+  bool WriteUInt32(uint32_t value) {
+    value = quiche::QuicheEndian::HostToNet32(value);
+    return WriteBytes(&value, sizeof(value));
+  }
+  bool WriteUInt64(uint64_t value) {
+    uint32_t upper =
+        quiche::QuicheEndian::HostToNet32(static_cast<uint32_t>(value >> 32));
+    uint32_t lower =
+        quiche::QuicheEndian::HostToNet32(static_cast<uint32_t>(value));
+    return (WriteBytes(&upper, sizeof(upper)) &&
+            WriteBytes(&lower, sizeof(lower)));
+  }
+  bool WriteStringPiece32(const absl::string_view value);
+  bool WriteBytes(const void* data, uint32_t data_len);
+
+ private:
+  friend class test::SpdyFrameBuilderPeer;
+
+  // Populates this frame with a HTTP2 frame prefix with type and length
+  // information.
+  bool BeginNewFrameInternal(uint8_t raw_frame_type,
+                             uint8_t flags,
+                             SpdyStreamId stream_id,
+                             size_t length);
+
+  // Returns a writeable buffer of given size in bytes, to be appended to the
+  // currently written frame. Does bounds checking on length but does not
+  // increment the underlying iterator. To do so, consumers should subsequently
+  // call Seek().
+  // In general, consumers should use Write*() calls instead of this.
+  // Returns NULL on failure.
+  char* GetWritableBuffer(size_t length);
+  char* GetWritableOutput(size_t desired_length, size_t* actual_length);
+
+  // Checks to make sure that there is an appropriate amount of space for a
+  // write of given size, in bytes.
+  bool CanWrite(size_t length) const;
+
+  // A buffer to be created whenever a new frame needs to be written. Used only
+  // if |output_| is nullptr.
+  std::unique_ptr<char[]> buffer_;
+  // A pre-allocated buffer. If not-null, serialized frame data is written to
+  // this buffer.
+  ZeroCopyOutputBuffer* output_ = nullptr;  // Does not own.
+
+  size_t capacity_;  // Allocation size of payload, set by constructor.
+  size_t length_;    // Length of the latest frame in the buffer.
+  size_t offset_;    // Position at which the latest frame begins.
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_FRAME_BUILDER_H_
diff --git a/quiche/spdy/core/spdy_frame_builder_test.cc b/quiche/spdy/core/spdy_frame_builder_test.cc
new file mode 100644
index 0000000..66656e3
--- /dev/null
+++ b/quiche/spdy/core/spdy_frame_builder_test.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_frame_builder.h"
+
+#include <memory>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/array_output_buffer.h"
+#include "quiche/spdy/core/spdy_framer.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace spdy {
+
+namespace test {
+
+class QUICHE_EXPORT_PRIVATE SpdyFrameBuilderPeer {
+ public:
+  static char* GetWritableBuffer(SpdyFrameBuilder* builder, size_t length) {
+    return builder->GetWritableBuffer(length);
+  }
+
+  static char* GetWritableOutput(SpdyFrameBuilder* builder,
+                                 size_t desired_length,
+                                 size_t* actual_length) {
+    return builder->GetWritableOutput(desired_length, actual_length);
+  }
+};
+
+namespace {
+
+const int64_t kSize = 64 * 1024;
+char output_buffer[kSize] = "";
+
+}  // namespace
+
+// Verifies that SpdyFrameBuilder::GetWritableBuffer() can be used to build a
+// SpdySerializedFrame.
+TEST(SpdyFrameBuilderTest, GetWritableBuffer) {
+  const size_t kBuilderSize = 10;
+  SpdyFrameBuilder builder(kBuilderSize);
+  char* writable_buffer =
+      SpdyFrameBuilderPeer::GetWritableBuffer(&builder, kBuilderSize);
+  memset(writable_buffer, ~1, kBuilderSize);
+  EXPECT_TRUE(builder.Seek(kBuilderSize));
+  SpdySerializedFrame frame(builder.take());
+  char expected[kBuilderSize];
+  memset(expected, ~1, kBuilderSize);
+  EXPECT_EQ(absl::string_view(expected, kBuilderSize),
+            absl::string_view(frame.data(), kBuilderSize));
+}
+
+// Verifies that SpdyFrameBuilder::GetWritableBuffer() can be used to build a
+// SpdySerializedFrame to the output buffer.
+TEST(SpdyFrameBuilderTest, GetWritableOutput) {
+  ArrayOutputBuffer output(output_buffer, kSize);
+  const size_t kBuilderSize = 10;
+  SpdyFrameBuilder builder(kBuilderSize, &output);
+  size_t actual_size = 0;
+  char* writable_buffer = SpdyFrameBuilderPeer::GetWritableOutput(
+      &builder, kBuilderSize, &actual_size);
+  memset(writable_buffer, ~1, kBuilderSize);
+  EXPECT_TRUE(builder.Seek(kBuilderSize));
+  SpdySerializedFrame frame(output.Begin(), kBuilderSize, false);
+  char expected[kBuilderSize];
+  memset(expected, ~1, kBuilderSize);
+  EXPECT_EQ(absl::string_view(expected, kBuilderSize),
+            absl::string_view(frame.data(), kBuilderSize));
+}
+
+// Verifies the case that the buffer's capacity is too small.
+TEST(SpdyFrameBuilderTest, GetWritableOutputNegative) {
+  size_t small_cap = 1;
+  ArrayOutputBuffer output(output_buffer, small_cap);
+  const size_t kBuilderSize = 10;
+  SpdyFrameBuilder builder(kBuilderSize, &output);
+  size_t actual_size = 0;
+  char* writable_buffer = SpdyFrameBuilderPeer::GetWritableOutput(
+      &builder, kBuilderSize, &actual_size);
+  EXPECT_EQ(0u, actual_size);
+  EXPECT_EQ(nullptr, writable_buffer);
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_framer.cc b/quiche/spdy/core/spdy_framer.cc
new file mode 100644
index 0000000..f568a05
--- /dev/null
+++ b/quiche/spdy/core/spdy_framer.cc
@@ -0,0 +1,1380 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_framer.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <iterator>
+#include <list>
+#include <new>
+#include <utility>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/spdy_bitmasks.h"
+#include "quiche/spdy/core/spdy_frame_builder.h"
+
+namespace spdy {
+
+namespace {
+
+// Pack parent stream ID and exclusive flag into the format used by HTTP/2
+// headers and priority frames.
+uint32_t PackStreamDependencyValues(bool exclusive,
+                                    SpdyStreamId parent_stream_id) {
+  // Make sure the highest-order bit in the parent stream id is zeroed out.
+  uint32_t parent = parent_stream_id & 0x7fffffff;
+  // Set the one-bit exclusivity flag.
+  uint32_t e_bit = exclusive ? 0x80000000 : 0;
+  return parent | e_bit;
+}
+
+// Used to indicate no flags in a HTTP2 flags field.
+const uint8_t kNoFlags = 0;
+
+// Wire size of pad length field.
+const size_t kPadLengthFieldSize = 1;
+
+// The size of one parameter in SETTINGS frame.
+const size_t kOneSettingParameterSize = 6;
+
+size_t GetUncompressedSerializedLength(const Http2HeaderBlock& headers) {
+  const size_t num_name_value_pairs_size = sizeof(uint32_t);
+  const size_t length_of_name_size = num_name_value_pairs_size;
+  const size_t length_of_value_size = num_name_value_pairs_size;
+
+  size_t total_length = num_name_value_pairs_size;
+  for (const auto& header : headers) {
+    // We add space for the length of the name and the length of the value as
+    // well as the length of the name and the length of the value.
+    total_length += length_of_name_size + header.first.size() +
+                    length_of_value_size + header.second.size();
+  }
+  return total_length;
+}
+
+// Serializes the flags octet for a given SpdyHeadersIR.
+uint8_t SerializeHeaderFrameFlags(const SpdyHeadersIR& header_ir,
+                                  const bool end_headers) {
+  uint8_t flags = 0;
+  if (header_ir.fin()) {
+    flags |= CONTROL_FLAG_FIN;
+  }
+  if (end_headers) {
+    flags |= HEADERS_FLAG_END_HEADERS;
+  }
+  if (header_ir.padded()) {
+    flags |= HEADERS_FLAG_PADDED;
+  }
+  if (header_ir.has_priority()) {
+    flags |= HEADERS_FLAG_PRIORITY;
+  }
+  return flags;
+}
+
+// Serializes the flags octet for a given SpdyPushPromiseIR.
+uint8_t SerializePushPromiseFrameFlags(const SpdyPushPromiseIR& push_promise_ir,
+                                       const bool end_headers) {
+  uint8_t flags = 0;
+  if (push_promise_ir.padded()) {
+    flags = flags | PUSH_PROMISE_FLAG_PADDED;
+  }
+  if (end_headers) {
+    flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
+  }
+  return flags;
+}
+
+// Serializes a HEADERS frame from the given SpdyHeadersIR and encoded header
+// block. Does not need or use the SpdyHeaderBlock inside SpdyHeadersIR.
+// Return false if the serialization fails. |encoding| should not be empty.
+bool SerializeHeadersGivenEncoding(const SpdyHeadersIR& headers,
+                                   const std::string& encoding,
+                                   const bool end_headers,
+                                   ZeroCopyOutputBuffer* output) {
+  const size_t frame_size =
+      GetHeaderFrameSizeSansBlock(headers) + encoding.size();
+  SpdyFrameBuilder builder(frame_size, output);
+  bool ret = builder.BeginNewFrame(
+      SpdyFrameType::HEADERS, SerializeHeaderFrameFlags(headers, end_headers),
+      headers.stream_id(), frame_size - kFrameHeaderSize);
+  QUICHE_DCHECK_EQ(kFrameHeaderSize, builder.length());
+
+  if (ret && headers.padded()) {
+    ret &= builder.WriteUInt8(headers.padding_payload_len());
+  }
+
+  if (ret && headers.has_priority()) {
+    int weight = ClampHttp2Weight(headers.weight());
+    ret &= builder.WriteUInt32(PackStreamDependencyValues(
+        headers.exclusive(), headers.parent_stream_id()));
+    // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
+    ret &= builder.WriteUInt8(weight - 1);
+  }
+
+  if (ret) {
+    ret &= builder.WriteBytes(encoding.data(), encoding.size());
+  }
+
+  if (ret && headers.padding_payload_len() > 0) {
+    std::string padding(headers.padding_payload_len(), 0);
+    ret &= builder.WriteBytes(padding.data(), padding.length());
+  }
+
+  if (!ret) {
+    QUICHE_DLOG(WARNING)
+        << "Failed to build HEADERS. Not enough space in output";
+  }
+  return ret;
+}
+
+// Serializes a PUSH_PROMISE frame from the given SpdyPushPromiseIR and
+// encoded header block. Does not need or use the SpdyHeaderBlock inside
+// SpdyPushPromiseIR.
+bool SerializePushPromiseGivenEncoding(const SpdyPushPromiseIR& push_promise,
+                                       const std::string& encoding,
+                                       const bool end_headers,
+                                       ZeroCopyOutputBuffer* output) {
+  const size_t frame_size =
+      GetPushPromiseFrameSizeSansBlock(push_promise) + encoding.size();
+  SpdyFrameBuilder builder(frame_size, output);
+  bool ok = builder.BeginNewFrame(
+      SpdyFrameType::PUSH_PROMISE,
+      SerializePushPromiseFrameFlags(push_promise, end_headers),
+      push_promise.stream_id(), frame_size - kFrameHeaderSize);
+
+  if (push_promise.padded()) {
+    ok = ok && builder.WriteUInt8(push_promise.padding_payload_len());
+  }
+  ok = ok && builder.WriteUInt32(push_promise.promised_stream_id()) &&
+       builder.WriteBytes(encoding.data(), encoding.size());
+  if (ok && push_promise.padding_payload_len() > 0) {
+    std::string padding(push_promise.padding_payload_len(), 0);
+    ok = builder.WriteBytes(padding.data(), padding.length());
+  }
+
+  QUICHE_DLOG_IF(ERROR, !ok)
+      << "Failed to write PUSH_PROMISE encoding, not enough "
+      << "space in output";
+  return ok;
+}
+
+bool WritePayloadWithContinuation(SpdyFrameBuilder* builder,
+                                  const std::string& hpack_encoding,
+                                  SpdyStreamId stream_id,
+                                  SpdyFrameType type,
+                                  int padding_payload_len) {
+  uint8_t end_flag = 0;
+  uint8_t flags = 0;
+  if (type == SpdyFrameType::HEADERS) {
+    end_flag = HEADERS_FLAG_END_HEADERS;
+  } else if (type == SpdyFrameType::PUSH_PROMISE) {
+    end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
+  } else {
+    QUICHE_DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
+                       << FrameTypeToString(type);
+  }
+
+  // Write all the padding payload and as much of the data payload as possible
+  // into the initial frame.
+  size_t bytes_remaining = 0;
+  bytes_remaining = hpack_encoding.size() -
+                    std::min(hpack_encoding.size(),
+                             kHttp2MaxControlFrameSendSize - builder->length() -
+                                 padding_payload_len);
+  bool ret = builder->WriteBytes(&hpack_encoding[0],
+                                 hpack_encoding.size() - bytes_remaining);
+  if (padding_payload_len > 0) {
+    std::string padding = std::string(padding_payload_len, 0);
+    ret &= builder->WriteBytes(padding.data(), padding.length());
+  }
+
+  // Tack on CONTINUATION frames for the overflow.
+  while (bytes_remaining > 0 && ret) {
+    size_t bytes_to_write =
+        std::min(bytes_remaining,
+                 kHttp2MaxControlFrameSendSize - kContinuationFrameMinimumSize);
+    // Write CONTINUATION frame prefix.
+    if (bytes_remaining == bytes_to_write) {
+      flags |= end_flag;
+    }
+    ret &= builder->BeginNewFrame(SpdyFrameType::CONTINUATION, flags, stream_id,
+                                  bytes_to_write);
+    // Write payload fragment.
+    ret &= builder->WriteBytes(
+        &hpack_encoding[hpack_encoding.size() - bytes_remaining],
+        bytes_to_write);
+    bytes_remaining -= bytes_to_write;
+  }
+  return ret;
+}
+
+void SerializeDataBuilderHelper(const SpdyDataIR& data_ir,
+                                uint8_t* flags,
+                                int* num_padding_fields,
+                                size_t* size_with_padding) {
+  if (data_ir.fin()) {
+    *flags = DATA_FLAG_FIN;
+  }
+
+  if (data_ir.padded()) {
+    *flags = *flags | DATA_FLAG_PADDED;
+    ++*num_padding_fields;
+  }
+
+  *size_with_padding = *num_padding_fields + data_ir.data_len() +
+                       data_ir.padding_payload_len() + kDataFrameMinimumSize;
+}
+
+void SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
+    const SpdyDataIR& data_ir,
+    uint8_t* flags,
+    size_t* frame_size,
+    size_t* num_padding_fields) {
+  *flags = DATA_FLAG_NONE;
+  if (data_ir.fin()) {
+    *flags = DATA_FLAG_FIN;
+  }
+
+  *frame_size = kDataFrameMinimumSize;
+  if (data_ir.padded()) {
+    *flags = *flags | DATA_FLAG_PADDED;
+    ++(*num_padding_fields);
+    *frame_size = *frame_size + *num_padding_fields;
+  }
+}
+
+void SerializeSettingsBuilderHelper(const SpdySettingsIR& settings,
+                                    uint8_t* flags,
+                                    const SettingsMap* values,
+                                    size_t* size) {
+  if (settings.is_ack()) {
+    *flags = *flags | SETTINGS_FLAG_ACK;
+  }
+  *size =
+      kSettingsFrameMinimumSize + (values->size() * kOneSettingParameterSize);
+}
+
+void SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir,
+                                  std::string* value,
+                                  size_t* size) {
+  *size = kGetAltSvcFrameMinimumSize;
+  *size = *size + altsvc_ir.origin().length();
+  *value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
+      altsvc_ir.altsvc_vector());
+  *size = *size + value->length();
+}
+
+}  // namespace
+
+SpdyFramer::SpdyFramer(CompressionOption option)
+    : debug_visitor_(nullptr), compression_option_(option) {
+  static_assert(kHttp2MaxControlFrameSendSize <= kHttp2DefaultFrameSizeLimit,
+                "Our send limit should be at most our receive limit.");
+}
+
+SpdyFramer::~SpdyFramer() = default;
+
+void SpdyFramer::set_debug_visitor(
+    SpdyFramerDebugVisitorInterface* debug_visitor) {
+  debug_visitor_ = debug_visitor;
+}
+
+SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer)
+    : framer_(framer), is_first_frame_(true), has_next_frame_(true) {}
+
+SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() = default;
+
+size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) {
+  const SpdyFrameIR& frame_ir = GetIR();
+  if (!has_next_frame_) {
+    QUICHE_BUG(spdy_bug_75_1)
+        << "SpdyFramer::SpdyFrameIterator::NextFrame called without "
+        << "a next frame.";
+    return false;
+  }
+
+  const size_t size_without_block =
+      is_first_frame_ ? GetFrameSizeSansBlock() : kContinuationFrameMinimumSize;
+  std::string encoding =
+      encoder_->Next(kHttp2MaxControlFrameSendSize - size_without_block);
+  has_next_frame_ = encoder_->HasNext();
+
+  if (framer_->debug_visitor_ != nullptr) {
+    const auto& header_block_frame_ir =
+        static_cast<const SpdyFrameWithHeaderBlockIR&>(frame_ir);
+    const size_t header_list_size =
+        GetUncompressedSerializedLength(header_block_frame_ir.header_block());
+    framer_->debug_visitor_->OnSendCompressedFrame(
+        frame_ir.stream_id(),
+        is_first_frame_ ? frame_ir.frame_type() : SpdyFrameType::CONTINUATION,
+        header_list_size, size_without_block + encoding.size());
+  }
+
+  const size_t free_bytes_before = output->BytesFree();
+  bool ok = false;
+  if (is_first_frame_) {
+    is_first_frame_ = false;
+    ok = SerializeGivenEncoding(encoding, output);
+  } else {
+    SpdyContinuationIR continuation_ir(frame_ir.stream_id());
+    continuation_ir.take_encoding(std::move(encoding));
+    continuation_ir.set_end_headers(!has_next_frame_);
+    ok = framer_->SerializeContinuation(continuation_ir, output);
+  }
+  return ok ? free_bytes_before - output->BytesFree() : 0;
+}
+
+bool SpdyFramer::SpdyFrameIterator::HasNextFrame() const {
+  return has_next_frame_;
+}
+
+SpdyFramer::SpdyHeaderFrameIterator::SpdyHeaderFrameIterator(
+    SpdyFramer* framer,
+    std::unique_ptr<const SpdyHeadersIR> headers_ir)
+    : SpdyFrameIterator(framer), headers_ir_(std::move(headers_ir)) {
+  SetEncoder(headers_ir_.get());
+}
+
+SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() = default;
+
+const SpdyFrameIR& SpdyFramer::SpdyHeaderFrameIterator::GetIR() const {
+  return *headers_ir_;
+}
+
+size_t SpdyFramer::SpdyHeaderFrameIterator::GetFrameSizeSansBlock() const {
+  return GetHeaderFrameSizeSansBlock(*headers_ir_);
+}
+
+bool SpdyFramer::SpdyHeaderFrameIterator::SerializeGivenEncoding(
+    const std::string& encoding,
+    ZeroCopyOutputBuffer* output) const {
+  return SerializeHeadersGivenEncoding(*headers_ir_, encoding,
+                                       !has_next_frame(), output);
+}
+
+SpdyFramer::SpdyPushPromiseFrameIterator::SpdyPushPromiseFrameIterator(
+    SpdyFramer* framer,
+    std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir)
+    : SpdyFrameIterator(framer), push_promise_ir_(std::move(push_promise_ir)) {
+  SetEncoder(push_promise_ir_.get());
+}
+
+SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() =
+    default;
+
+const SpdyFrameIR& SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() const {
+  return *push_promise_ir_;
+}
+
+size_t SpdyFramer::SpdyPushPromiseFrameIterator::GetFrameSizeSansBlock() const {
+  return GetPushPromiseFrameSizeSansBlock(*push_promise_ir_);
+}
+
+bool SpdyFramer::SpdyPushPromiseFrameIterator::SerializeGivenEncoding(
+    const std::string& encoding,
+    ZeroCopyOutputBuffer* output) const {
+  return SerializePushPromiseGivenEncoding(*push_promise_ir_, encoding,
+                                           !has_next_frame(), output);
+}
+
+SpdyFramer::SpdyControlFrameIterator::SpdyControlFrameIterator(
+    SpdyFramer* framer,
+    std::unique_ptr<const SpdyFrameIR> frame_ir)
+    : framer_(framer), frame_ir_(std::move(frame_ir)) {}
+
+SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() = default;
+
+size_t SpdyFramer::SpdyControlFrameIterator::NextFrame(
+    ZeroCopyOutputBuffer* output) {
+  size_t size_written = framer_->SerializeFrame(*frame_ir_, output);
+  has_next_frame_ = false;
+  return size_written;
+}
+
+bool SpdyFramer::SpdyControlFrameIterator::HasNextFrame() const {
+  return has_next_frame_;
+}
+
+const SpdyFrameIR& SpdyFramer::SpdyControlFrameIterator::GetIR() const {
+  return *frame_ir_;
+}
+
+std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator(
+    SpdyFramer* framer,
+    std::unique_ptr<const SpdyFrameIR> frame_ir) {
+  switch (frame_ir->frame_type()) {
+    case SpdyFrameType::HEADERS: {
+      return std::make_unique<SpdyHeaderFrameIterator>(
+          framer, absl::WrapUnique(
+                      static_cast<const SpdyHeadersIR*>(frame_ir.release())));
+    }
+    case SpdyFrameType::PUSH_PROMISE: {
+      return std::make_unique<SpdyPushPromiseFrameIterator>(
+          framer, absl::WrapUnique(static_cast<const SpdyPushPromiseIR*>(
+                      frame_ir.release())));
+    }
+    case SpdyFrameType::DATA: {
+      QUICHE_DVLOG(1) << "Serialize a stream end DATA frame for VTL";
+      ABSL_FALLTHROUGH_INTENDED;
+    }
+    default: {
+      return std::make_unique<SpdyControlFrameIterator>(framer,
+                                                        std::move(frame_ir));
+    }
+  }
+}
+
+SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) {
+  uint8_t flags = DATA_FLAG_NONE;
+  int num_padding_fields = 0;
+  size_t size_with_padding = 0;
+  SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields,
+                             &size_with_padding);
+
+  SpdyFrameBuilder builder(size_with_padding);
+  builder.BeginNewFrame(SpdyFrameType::DATA, flags, data_ir.stream_id());
+  if (data_ir.padded()) {
+    builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
+  }
+  builder.WriteBytes(data_ir.data(), data_ir.data_len());
+  if (data_ir.padding_payload_len() > 0) {
+    std::string padding(data_ir.padding_payload_len(), 0);
+    builder.WriteBytes(padding.data(), padding.length());
+  }
+  QUICHE_DCHECK_EQ(size_with_padding, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
+    const SpdyDataIR& data_ir) {
+  uint8_t flags = DATA_FLAG_NONE;
+  size_t frame_size = 0;
+  size_t num_padding_fields = 0;
+  SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
+      data_ir, &flags, &frame_size, &num_padding_fields);
+
+  SpdyFrameBuilder builder(frame_size);
+  builder.BeginNewFrame(
+      SpdyFrameType::DATA, flags, data_ir.stream_id(),
+      num_padding_fields + data_ir.data_len() + data_ir.padding_payload_len());
+  if (data_ir.padded()) {
+    builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
+  }
+  QUICHE_DCHECK_EQ(frame_size, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeRstStream(
+    const SpdyRstStreamIR& rst_stream) const {
+  size_t expected_length = kRstStreamFrameSize;
+  SpdyFrameBuilder builder(expected_length);
+
+  builder.BeginNewFrame(SpdyFrameType::RST_STREAM, 0, rst_stream.stream_id());
+
+  builder.WriteUInt32(rst_stream.error_code());
+
+  QUICHE_DCHECK_EQ(expected_length, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeSettings(
+    const SpdySettingsIR& settings) const {
+  uint8_t flags = 0;
+  // Size, in bytes, of this SETTINGS frame.
+  size_t size = 0;
+  const SettingsMap* values = &(settings.values());
+  SerializeSettingsBuilderHelper(settings, &flags, values, &size);
+  SpdyFrameBuilder builder(size);
+  builder.BeginNewFrame(SpdyFrameType::SETTINGS, flags, 0);
+
+  // If this is an ACK, payload should be empty.
+  if (settings.is_ack()) {
+    return builder.take();
+  }
+
+  QUICHE_DCHECK_EQ(kSettingsFrameMinimumSize, builder.length());
+  for (auto it = values->begin(); it != values->end(); ++it) {
+    int setting_id = it->first;
+    QUICHE_DCHECK_GE(setting_id, 0);
+    builder.WriteUInt16(static_cast<SpdySettingsId>(setting_id));
+    builder.WriteUInt32(it->second);
+  }
+  QUICHE_DCHECK_EQ(size, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
+  SpdyFrameBuilder builder(kPingFrameSize);
+  uint8_t flags = 0;
+  if (ping.is_ack()) {
+    flags |= PING_FLAG_ACK;
+  }
+  builder.BeginNewFrame(SpdyFrameType::PING, flags, 0);
+  builder.WriteUInt64(ping.id());
+  QUICHE_DCHECK_EQ(kPingFrameSize, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeGoAway(
+    const SpdyGoAwayIR& goaway) const {
+  // Compute the output buffer size, take opaque data into account.
+  size_t expected_length = kGoawayFrameMinimumSize;
+  expected_length += goaway.description().size();
+  SpdyFrameBuilder builder(expected_length);
+
+  // Serialize the GOAWAY frame.
+  builder.BeginNewFrame(SpdyFrameType::GOAWAY, 0, 0);
+
+  // GOAWAY frames specify the last good stream id.
+  builder.WriteUInt32(goaway.last_good_stream_id());
+
+  // GOAWAY frames also specify the error code.
+  builder.WriteUInt32(goaway.error_code());
+
+  // GOAWAY frames may also specify opaque data.
+  if (!goaway.description().empty()) {
+    builder.WriteBytes(goaway.description().data(),
+                       goaway.description().size());
+  }
+
+  QUICHE_DCHECK_EQ(expected_length, builder.length());
+  return builder.take();
+}
+
+void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
+                                               uint8_t* flags,
+                                               size_t* size,
+                                               std::string* hpack_encoding,
+                                               int* weight,
+                                               size_t* length_field) {
+  if (headers.fin()) {
+    *flags = *flags | CONTROL_FLAG_FIN;
+  }
+  // This will get overwritten if we overflow into a CONTINUATION frame.
+  *flags = *flags | HEADERS_FLAG_END_HEADERS;
+  if (headers.has_priority()) {
+    *flags = *flags | HEADERS_FLAG_PRIORITY;
+  }
+  if (headers.padded()) {
+    *flags = *flags | HEADERS_FLAG_PADDED;
+  }
+
+  *size = kHeadersFrameMinimumSize;
+
+  if (headers.padded()) {
+    *size = *size + kPadLengthFieldSize;
+    *size = *size + headers.padding_payload_len();
+  }
+
+  if (headers.has_priority()) {
+    *weight = ClampHttp2Weight(headers.weight());
+    *size = *size + 5;
+  }
+
+  *hpack_encoding =
+      GetHpackEncoder()->EncodeHeaderBlock(headers.header_block());
+  *size = *size + hpack_encoding->size();
+  if (*size > kHttp2MaxControlFrameSendSize) {
+    *size = *size + GetNumberRequiredContinuationFrames(*size) *
+                        kContinuationFrameMinimumSize;
+    *flags = *flags & ~HEADERS_FLAG_END_HEADERS;
+  }
+  // Compute frame length field.
+  if (headers.padded()) {
+    *length_field = *length_field + kPadLengthFieldSize;
+  }
+  if (headers.has_priority()) {
+    *length_field = *length_field + 4;  // Dependency field.
+    *length_field = *length_field + 1;  // Weight field.
+  }
+  *length_field = *length_field + headers.padding_payload_len();
+  *length_field = *length_field + hpack_encoding->size();
+  // If the HEADERS frame with payload would exceed the max frame size, then
+  // WritePayloadWithContinuation() will serialize CONTINUATION frames as
+  // necessary.
+  *length_field =
+      std::min(*length_field, kHttp2MaxControlFrameSendSize - kFrameHeaderSize);
+}
+
+SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) {
+  uint8_t flags = 0;
+  // The size of this frame, including padding (if there is any) and
+  // variable-length header block.
+  size_t size = 0;
+  std::string hpack_encoding;
+  int weight = 0;
+  size_t length_field = 0;
+  SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding,
+                                &weight, &length_field);
+
+  SpdyFrameBuilder builder(size);
+  builder.BeginNewFrame(SpdyFrameType::HEADERS, flags, headers.stream_id(),
+                        length_field);
+
+  QUICHE_DCHECK_EQ(kHeadersFrameMinimumSize, builder.length());
+
+  int padding_payload_len = 0;
+  if (headers.padded()) {
+    builder.WriteUInt8(headers.padding_payload_len());
+    padding_payload_len = headers.padding_payload_len();
+  }
+  if (headers.has_priority()) {
+    builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(),
+                                                   headers.parent_stream_id()));
+    // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
+    builder.WriteUInt8(weight - 1);
+  }
+  WritePayloadWithContinuation(&builder, hpack_encoding, headers.stream_id(),
+                               SpdyFrameType::HEADERS, padding_payload_len);
+
+  if (debug_visitor_) {
+    const size_t header_list_size =
+        GetUncompressedSerializedLength(headers.header_block());
+    debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
+                                          SpdyFrameType::HEADERS,
+                                          header_list_size, builder.length());
+  }
+
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeWindowUpdate(
+    const SpdyWindowUpdateIR& window_update) {
+  SpdyFrameBuilder builder(kWindowUpdateFrameSize);
+  builder.BeginNewFrame(SpdyFrameType::WINDOW_UPDATE, kNoFlags,
+                        window_update.stream_id());
+  builder.WriteUInt32(window_update.delta());
+  QUICHE_DCHECK_EQ(kWindowUpdateFrameSize, builder.length());
+  return builder.take();
+}
+
+void SpdyFramer::SerializePushPromiseBuilderHelper(
+    const SpdyPushPromiseIR& push_promise,
+    uint8_t* flags,
+    std::string* hpack_encoding,
+    size_t* size) {
+  *flags = 0;
+  // This will get overwritten if we overflow into a CONTINUATION frame.
+  *flags = *flags | PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
+  // The size of this frame, including variable-length name-value block.
+  *size = kPushPromiseFrameMinimumSize;
+
+  if (push_promise.padded()) {
+    *flags = *flags | PUSH_PROMISE_FLAG_PADDED;
+    *size = *size + kPadLengthFieldSize;
+    *size = *size + push_promise.padding_payload_len();
+  }
+
+  *hpack_encoding =
+      GetHpackEncoder()->EncodeHeaderBlock(push_promise.header_block());
+  *size = *size + hpack_encoding->size();
+  if (*size > kHttp2MaxControlFrameSendSize) {
+    *size = *size + GetNumberRequiredContinuationFrames(*size) *
+                        kContinuationFrameMinimumSize;
+    *flags = *flags & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
+  }
+}
+
+SpdySerializedFrame SpdyFramer::SerializePushPromise(
+    const SpdyPushPromiseIR& push_promise) {
+  uint8_t flags = 0;
+  size_t size = 0;
+  std::string hpack_encoding;
+  SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding,
+                                    &size);
+
+  SpdyFrameBuilder builder(size);
+  size_t length =
+      std::min(size, kHttp2MaxControlFrameSendSize) - kFrameHeaderSize;
+  builder.BeginNewFrame(SpdyFrameType::PUSH_PROMISE, flags,
+                        push_promise.stream_id(), length);
+  int padding_payload_len = 0;
+  if (push_promise.padded()) {
+    builder.WriteUInt8(push_promise.padding_payload_len());
+    builder.WriteUInt32(push_promise.promised_stream_id());
+    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize + kPadLengthFieldSize,
+                     builder.length());
+
+    padding_payload_len = push_promise.padding_payload_len();
+  } else {
+    builder.WriteUInt32(push_promise.promised_stream_id());
+    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize, builder.length());
+  }
+
+  WritePayloadWithContinuation(
+      &builder, hpack_encoding, push_promise.stream_id(),
+      SpdyFrameType::PUSH_PROMISE, padding_payload_len);
+
+  if (debug_visitor_) {
+    const size_t header_list_size =
+        GetUncompressedSerializedLength(push_promise.header_block());
+    debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
+                                          SpdyFrameType::PUSH_PROMISE,
+                                          header_list_size, builder.length());
+  }
+
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeContinuation(
+    const SpdyContinuationIR& continuation) const {
+  const std::string& encoding = continuation.encoding();
+  size_t frame_size = kContinuationFrameMinimumSize + encoding.size();
+  SpdyFrameBuilder builder(frame_size);
+  uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0;
+  builder.BeginNewFrame(SpdyFrameType::CONTINUATION, flags,
+                        continuation.stream_id());
+  QUICHE_DCHECK_EQ(kFrameHeaderSize, builder.length());
+
+  builder.WriteBytes(encoding.data(), encoding.size());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) {
+  std::string value;
+  size_t size = 0;
+  SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size);
+  SpdyFrameBuilder builder(size);
+  builder.BeginNewFrame(SpdyFrameType::ALTSVC, kNoFlags, altsvc_ir.stream_id());
+
+  builder.WriteUInt16(altsvc_ir.origin().length());
+  builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length());
+  builder.WriteBytes(value.data(), value.length());
+  QUICHE_DCHECK_LT(kGetAltSvcFrameMinimumSize, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializePriority(
+    const SpdyPriorityIR& priority) const {
+  SpdyFrameBuilder builder(kPriorityFrameSize);
+  builder.BeginNewFrame(SpdyFrameType::PRIORITY, kNoFlags,
+                        priority.stream_id());
+
+  builder.WriteUInt32(PackStreamDependencyValues(priority.exclusive(),
+                                                 priority.parent_stream_id()));
+  // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
+  builder.WriteUInt8(priority.weight() - 1);
+  QUICHE_DCHECK_EQ(kPriorityFrameSize, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializePriorityUpdate(
+    const SpdyPriorityUpdateIR& priority_update) const {
+  const size_t total_size = kPriorityUpdateFrameMinimumSize +
+                            priority_update.priority_field_value().size();
+  SpdyFrameBuilder builder(total_size);
+  builder.BeginNewFrame(SpdyFrameType::PRIORITY_UPDATE, kNoFlags,
+                        priority_update.stream_id());
+
+  builder.WriteUInt32(priority_update.prioritized_stream_id());
+  builder.WriteBytes(priority_update.priority_field_value().data(),
+                     priority_update.priority_field_value().size());
+  QUICHE_DCHECK_EQ(total_size, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeAcceptCh(
+    const SpdyAcceptChIR& accept_ch) const {
+  const size_t total_size = accept_ch.size();
+  SpdyFrameBuilder builder(total_size);
+  builder.BeginNewFrame(SpdyFrameType::ACCEPT_CH, kNoFlags,
+                        accept_ch.stream_id());
+
+  for (const AcceptChOriginValuePair& entry : accept_ch.entries()) {
+    builder.WriteUInt16(entry.origin.size());
+    builder.WriteBytes(entry.origin.data(), entry.origin.size());
+    builder.WriteUInt16(entry.value.size());
+    builder.WriteBytes(entry.value.data(), entry.value.size());
+  }
+
+  QUICHE_DCHECK_EQ(total_size, builder.length());
+  return builder.take();
+}
+
+SpdySerializedFrame SpdyFramer::SerializeUnknown(
+    const SpdyUnknownIR& unknown) const {
+  const size_t total_size = kFrameHeaderSize + unknown.payload().size();
+  SpdyFrameBuilder builder(total_size);
+  builder.BeginNewUncheckedFrame(unknown.type(), unknown.flags(),
+                                 unknown.stream_id(), unknown.length());
+  builder.WriteBytes(unknown.payload().data(), unknown.payload().size());
+  return builder.take();
+}
+
+namespace {
+
+class FrameSerializationVisitor : public SpdyFrameVisitor {
+ public:
+  explicit FrameSerializationVisitor(SpdyFramer* framer)
+      : framer_(framer), frame_() {}
+  ~FrameSerializationVisitor() override = default;
+
+  SpdySerializedFrame ReleaseSerializedFrame() { return std::move(frame_); }
+
+  void VisitData(const SpdyDataIR& data) override {
+    frame_ = framer_->SerializeData(data);
+  }
+  void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
+    frame_ = framer_->SerializeRstStream(rst_stream);
+  }
+  void VisitSettings(const SpdySettingsIR& settings) override {
+    frame_ = framer_->SerializeSettings(settings);
+  }
+  void VisitPing(const SpdyPingIR& ping) override {
+    frame_ = framer_->SerializePing(ping);
+  }
+  void VisitGoAway(const SpdyGoAwayIR& goaway) override {
+    frame_ = framer_->SerializeGoAway(goaway);
+  }
+  void VisitHeaders(const SpdyHeadersIR& headers) override {
+    frame_ = framer_->SerializeHeaders(headers);
+  }
+  void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
+    frame_ = framer_->SerializeWindowUpdate(window_update);
+  }
+  void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
+    frame_ = framer_->SerializePushPromise(push_promise);
+  }
+  void VisitContinuation(const SpdyContinuationIR& continuation) override {
+    frame_ = framer_->SerializeContinuation(continuation);
+  }
+  void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
+    frame_ = framer_->SerializeAltSvc(altsvc);
+  }
+  void VisitPriority(const SpdyPriorityIR& priority) override {
+    frame_ = framer_->SerializePriority(priority);
+  }
+  void VisitPriorityUpdate(
+      const SpdyPriorityUpdateIR& priority_update) override {
+    frame_ = framer_->SerializePriorityUpdate(priority_update);
+  }
+  void VisitAcceptCh(const SpdyAcceptChIR& accept_ch) override {
+    frame_ = framer_->SerializeAcceptCh(accept_ch);
+  }
+  void VisitUnknown(const SpdyUnknownIR& unknown) override {
+    frame_ = framer_->SerializeUnknown(unknown);
+  }
+
+ private:
+  SpdyFramer* framer_;
+  SpdySerializedFrame frame_;
+};
+
+// TODO(diannahu): Use also in frame serialization.
+class FlagsSerializationVisitor : public SpdyFrameVisitor {
+ public:
+  void VisitData(const SpdyDataIR& data) override {
+    flags_ = DATA_FLAG_NONE;
+    if (data.fin()) {
+      flags_ |= DATA_FLAG_FIN;
+    }
+    if (data.padded()) {
+      flags_ |= DATA_FLAG_PADDED;
+    }
+  }
+
+  void VisitRstStream(const SpdyRstStreamIR& /*rst_stream*/) override {
+    flags_ = kNoFlags;
+  }
+
+  void VisitSettings(const SpdySettingsIR& settings) override {
+    flags_ = kNoFlags;
+    if (settings.is_ack()) {
+      flags_ |= SETTINGS_FLAG_ACK;
+    }
+  }
+
+  void VisitPing(const SpdyPingIR& ping) override {
+    flags_ = kNoFlags;
+    if (ping.is_ack()) {
+      flags_ |= PING_FLAG_ACK;
+    }
+  }
+
+  void VisitGoAway(const SpdyGoAwayIR& /*goaway*/) override {
+    flags_ = kNoFlags;
+  }
+
+  // TODO(diannahu): The END_HEADERS flag is incorrect for HEADERS that require
+  //     CONTINUATION frames.
+  void VisitHeaders(const SpdyHeadersIR& headers) override {
+    flags_ = HEADERS_FLAG_END_HEADERS;
+    if (headers.fin()) {
+      flags_ |= CONTROL_FLAG_FIN;
+    }
+    if (headers.padded()) {
+      flags_ |= HEADERS_FLAG_PADDED;
+    }
+    if (headers.has_priority()) {
+      flags_ |= HEADERS_FLAG_PRIORITY;
+    }
+  }
+
+  void VisitWindowUpdate(const SpdyWindowUpdateIR& /*window_update*/) override {
+    flags_ = kNoFlags;
+  }
+
+  // TODO(diannahu): The END_PUSH_PROMISE flag is incorrect for PUSH_PROMISEs
+  //     that require CONTINUATION frames.
+  void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
+    flags_ = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
+    if (push_promise.padded()) {
+      flags_ |= PUSH_PROMISE_FLAG_PADDED;
+    }
+  }
+
+  // TODO(diannahu): The END_HEADERS flag is incorrect for CONTINUATIONs that
+  //     require CONTINUATION frames.
+  void VisitContinuation(const SpdyContinuationIR& /*continuation*/) override {
+    flags_ = HEADERS_FLAG_END_HEADERS;
+  }
+
+  void VisitAltSvc(const SpdyAltSvcIR& /*altsvc*/) override {
+    flags_ = kNoFlags;
+  }
+
+  void VisitPriority(const SpdyPriorityIR& /*priority*/) override {
+    flags_ = kNoFlags;
+  }
+
+  void VisitPriorityUpdate(
+      const SpdyPriorityUpdateIR& /*priority_update*/) override {
+    flags_ = kNoFlags;
+  }
+
+  void VisitAcceptCh(const SpdyAcceptChIR& /*accept_ch*/) override {
+    flags_ = kNoFlags;
+  }
+
+  uint8_t flags() const { return flags_; }
+
+ private:
+  uint8_t flags_ = kNoFlags;
+};
+
+}  // namespace
+
+SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
+  FrameSerializationVisitor visitor(this);
+  frame.Visit(&visitor);
+  return visitor.ReleaseSerializedFrame();
+}
+
+uint8_t SpdyFramer::GetSerializedFlags(const SpdyFrameIR& frame) {
+  FlagsSerializationVisitor visitor;
+  frame.Visit(&visitor);
+  return visitor.flags();
+}
+
+bool SpdyFramer::SerializeData(const SpdyDataIR& data_ir,
+                               ZeroCopyOutputBuffer* output) const {
+  uint8_t flags = DATA_FLAG_NONE;
+  int num_padding_fields = 0;
+  size_t size_with_padding = 0;
+  SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields,
+                             &size_with_padding);
+  SpdyFrameBuilder builder(size_with_padding, output);
+
+  bool ok =
+      builder.BeginNewFrame(SpdyFrameType::DATA, flags, data_ir.stream_id());
+
+  if (data_ir.padded()) {
+    ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
+  }
+
+  ok = ok && builder.WriteBytes(data_ir.data(), data_ir.data_len());
+  if (data_ir.padding_payload_len() > 0) {
+    std::string padding;
+    padding = std::string(data_ir.padding_payload_len(), 0);
+    ok = ok && builder.WriteBytes(padding.data(), padding.length());
+  }
+  QUICHE_DCHECK_EQ(size_with_padding, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
+    const SpdyDataIR& data_ir,
+    ZeroCopyOutputBuffer* output) const {
+  uint8_t flags = DATA_FLAG_NONE;
+  size_t frame_size = 0;
+  size_t num_padding_fields = 0;
+  SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
+      data_ir, &flags, &frame_size, &num_padding_fields);
+
+  SpdyFrameBuilder builder(frame_size, output);
+  bool ok = true;
+  ok = ok &&
+       builder.BeginNewFrame(SpdyFrameType::DATA, flags, data_ir.stream_id(),
+                             num_padding_fields + data_ir.data_len() +
+                                 data_ir.padding_payload_len());
+  if (data_ir.padded()) {
+    ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
+  }
+  QUICHE_DCHECK_EQ(frame_size, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeRstStream(const SpdyRstStreamIR& rst_stream,
+                                    ZeroCopyOutputBuffer* output) const {
+  size_t expected_length = kRstStreamFrameSize;
+  SpdyFrameBuilder builder(expected_length, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::RST_STREAM, 0,
+                                  rst_stream.stream_id());
+  ok = ok && builder.WriteUInt32(rst_stream.error_code());
+
+  QUICHE_DCHECK_EQ(expected_length, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeSettings(const SpdySettingsIR& settings,
+                                   ZeroCopyOutputBuffer* output) const {
+  uint8_t flags = 0;
+  // Size, in bytes, of this SETTINGS frame.
+  size_t size = 0;
+  const SettingsMap* values = &(settings.values());
+  SerializeSettingsBuilderHelper(settings, &flags, values, &size);
+  SpdyFrameBuilder builder(size, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::SETTINGS, flags, 0);
+
+  // If this is an ACK, payload should be empty.
+  if (settings.is_ack()) {
+    return ok;
+  }
+
+  QUICHE_DCHECK_EQ(kSettingsFrameMinimumSize, builder.length());
+  for (auto it = values->begin(); it != values->end(); ++it) {
+    int setting_id = it->first;
+    QUICHE_DCHECK_GE(setting_id, 0);
+    ok = ok && builder.WriteUInt16(static_cast<SpdySettingsId>(setting_id)) &&
+         builder.WriteUInt32(it->second);
+  }
+  QUICHE_DCHECK_EQ(size, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializePing(const SpdyPingIR& ping,
+                               ZeroCopyOutputBuffer* output) const {
+  SpdyFrameBuilder builder(kPingFrameSize, output);
+  uint8_t flags = 0;
+  if (ping.is_ack()) {
+    flags |= PING_FLAG_ACK;
+  }
+  bool ok = builder.BeginNewFrame(SpdyFrameType::PING, flags, 0);
+  ok = ok && builder.WriteUInt64(ping.id());
+  QUICHE_DCHECK_EQ(kPingFrameSize, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeGoAway(const SpdyGoAwayIR& goaway,
+                                 ZeroCopyOutputBuffer* output) const {
+  // Compute the output buffer size, take opaque data into account.
+  size_t expected_length = kGoawayFrameMinimumSize;
+  expected_length += goaway.description().size();
+  SpdyFrameBuilder builder(expected_length, output);
+
+  // Serialize the GOAWAY frame.
+  bool ok = builder.BeginNewFrame(SpdyFrameType::GOAWAY, 0, 0);
+
+  // GOAWAY frames specify the last good stream id.
+  ok = ok && builder.WriteUInt32(goaway.last_good_stream_id()) &&
+       // GOAWAY frames also specify the error status code.
+       builder.WriteUInt32(goaway.error_code());
+
+  // GOAWAY frames may also specify opaque data.
+  if (!goaway.description().empty()) {
+    ok = ok && builder.WriteBytes(goaway.description().data(),
+                                  goaway.description().size());
+  }
+
+  QUICHE_DCHECK_EQ(expected_length, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers,
+                                  ZeroCopyOutputBuffer* output) {
+  uint8_t flags = 0;
+  // The size of this frame, including padding (if there is any) and
+  // variable-length header block.
+  size_t size = 0;
+  std::string hpack_encoding;
+  int weight = 0;
+  size_t length_field = 0;
+  SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding,
+                                &weight, &length_field);
+
+  bool ok = true;
+  SpdyFrameBuilder builder(size, output);
+  ok = ok && builder.BeginNewFrame(SpdyFrameType::HEADERS, flags,
+                                   headers.stream_id(), length_field);
+  QUICHE_DCHECK_EQ(kHeadersFrameMinimumSize, builder.length());
+
+  int padding_payload_len = 0;
+  if (headers.padded()) {
+    ok = ok && builder.WriteUInt8(headers.padding_payload_len());
+    padding_payload_len = headers.padding_payload_len();
+  }
+  if (headers.has_priority()) {
+    ok = ok &&
+         builder.WriteUInt32(PackStreamDependencyValues(
+             headers.exclusive(), headers.parent_stream_id())) &&
+         // Per RFC 7540 section 6.3, serialized weight value is weight - 1.
+         builder.WriteUInt8(weight - 1);
+  }
+  ok = ok && WritePayloadWithContinuation(
+                 &builder, hpack_encoding, headers.stream_id(),
+                 SpdyFrameType::HEADERS, padding_payload_len);
+
+  if (debug_visitor_) {
+    const size_t header_list_size =
+        GetUncompressedSerializedLength(headers.header_block());
+    debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
+                                          SpdyFrameType::HEADERS,
+                                          header_list_size, builder.length());
+  }
+
+  return ok;
+}
+
+bool SpdyFramer::SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
+                                       ZeroCopyOutputBuffer* output) const {
+  SpdyFrameBuilder builder(kWindowUpdateFrameSize, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::WINDOW_UPDATE, kNoFlags,
+                                  window_update.stream_id());
+  ok = ok && builder.WriteUInt32(window_update.delta());
+  QUICHE_DCHECK_EQ(kWindowUpdateFrameSize, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise,
+                                      ZeroCopyOutputBuffer* output) {
+  uint8_t flags = 0;
+  size_t size = 0;
+  std::string hpack_encoding;
+  SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding,
+                                    &size);
+
+  bool ok = true;
+  SpdyFrameBuilder builder(size, output);
+  size_t length =
+      std::min(size, kHttp2MaxControlFrameSendSize) - kFrameHeaderSize;
+  ok = builder.BeginNewFrame(SpdyFrameType::PUSH_PROMISE, flags,
+                             push_promise.stream_id(), length);
+
+  int padding_payload_len = 0;
+  if (push_promise.padded()) {
+    ok = ok && builder.WriteUInt8(push_promise.padding_payload_len()) &&
+         builder.WriteUInt32(push_promise.promised_stream_id());
+    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize + kPadLengthFieldSize,
+                     builder.length());
+
+    padding_payload_len = push_promise.padding_payload_len();
+  } else {
+    ok = ok && builder.WriteUInt32(push_promise.promised_stream_id());
+    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize, builder.length());
+  }
+
+  ok = ok && WritePayloadWithContinuation(
+                 &builder, hpack_encoding, push_promise.stream_id(),
+                 SpdyFrameType::PUSH_PROMISE, padding_payload_len);
+
+  if (debug_visitor_) {
+    const size_t header_list_size =
+        GetUncompressedSerializedLength(push_promise.header_block());
+    debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
+                                          SpdyFrameType::PUSH_PROMISE,
+                                          header_list_size, builder.length());
+  }
+
+  return ok;
+}
+
+bool SpdyFramer::SerializeContinuation(const SpdyContinuationIR& continuation,
+                                       ZeroCopyOutputBuffer* output) const {
+  const std::string& encoding = continuation.encoding();
+  size_t frame_size = kContinuationFrameMinimumSize + encoding.size();
+  SpdyFrameBuilder builder(frame_size, output);
+  uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0;
+  bool ok = builder.BeginNewFrame(SpdyFrameType::CONTINUATION, flags,
+                                  continuation.stream_id(),
+                                  frame_size - kFrameHeaderSize);
+  QUICHE_DCHECK_EQ(kFrameHeaderSize, builder.length());
+
+  ok = ok && builder.WriteBytes(encoding.data(), encoding.size());
+  return ok;
+}
+
+bool SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir,
+                                 ZeroCopyOutputBuffer* output) {
+  std::string value;
+  size_t size = 0;
+  SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size);
+  SpdyFrameBuilder builder(size, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::ALTSVC, kNoFlags,
+                                  altsvc_ir.stream_id()) &&
+            builder.WriteUInt16(altsvc_ir.origin().length()) &&
+            builder.WriteBytes(altsvc_ir.origin().data(),
+                               altsvc_ir.origin().length()) &&
+            builder.WriteBytes(value.data(), value.length());
+  QUICHE_DCHECK_LT(kGetAltSvcFrameMinimumSize, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializePriority(const SpdyPriorityIR& priority,
+                                   ZeroCopyOutputBuffer* output) const {
+  SpdyFrameBuilder builder(kPriorityFrameSize, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::PRIORITY, kNoFlags,
+                                  priority.stream_id());
+  ok = ok &&
+       builder.WriteUInt32(PackStreamDependencyValues(
+           priority.exclusive(), priority.parent_stream_id())) &&
+       // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
+       builder.WriteUInt8(priority.weight() - 1);
+  QUICHE_DCHECK_EQ(kPriorityFrameSize, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializePriorityUpdate(
+    const SpdyPriorityUpdateIR& priority_update,
+    ZeroCopyOutputBuffer* output) const {
+  const size_t total_size = kPriorityUpdateFrameMinimumSize +
+                            priority_update.priority_field_value().size();
+  SpdyFrameBuilder builder(total_size, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::PRIORITY_UPDATE, kNoFlags,
+                                  priority_update.stream_id());
+
+  ok = ok && builder.WriteUInt32(priority_update.prioritized_stream_id());
+  ok = ok && builder.WriteBytes(priority_update.priority_field_value().data(),
+                                priority_update.priority_field_value().size());
+  QUICHE_DCHECK_EQ(total_size, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeAcceptCh(const SpdyAcceptChIR& accept_ch,
+                                   ZeroCopyOutputBuffer* output) const {
+  const size_t total_size = accept_ch.size();
+  SpdyFrameBuilder builder(total_size, output);
+  bool ok = builder.BeginNewFrame(SpdyFrameType::ACCEPT_CH, kNoFlags,
+                                  accept_ch.stream_id());
+
+  for (const AcceptChOriginValuePair& entry : accept_ch.entries()) {
+    ok = ok && builder.WriteUInt16(entry.origin.size());
+    ok = ok && builder.WriteBytes(entry.origin.data(), entry.origin.size());
+    ok = ok && builder.WriteUInt16(entry.value.size());
+    ok = ok && builder.WriteBytes(entry.value.data(), entry.value.size());
+  }
+
+  QUICHE_DCHECK_EQ(total_size, builder.length());
+  return ok;
+}
+
+bool SpdyFramer::SerializeUnknown(const SpdyUnknownIR& unknown,
+                                  ZeroCopyOutputBuffer* output) const {
+  const size_t total_size = kFrameHeaderSize + unknown.payload().size();
+  SpdyFrameBuilder builder(total_size, output);
+  bool ok = builder.BeginNewUncheckedFrame(
+      unknown.type(), unknown.flags(), unknown.stream_id(), unknown.length());
+  ok = ok &&
+       builder.WriteBytes(unknown.payload().data(), unknown.payload().size());
+  return ok;
+}
+
+namespace {
+
+class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor {
+ public:
+  explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer,
+                                               ZeroCopyOutputBuffer* output)
+      : framer_(framer), output_(output), result_(false) {}
+  ~FrameSerializationVisitorWithOutput() override = default;
+
+  size_t Result() { return result_; }
+
+  void VisitData(const SpdyDataIR& data) override {
+    result_ = framer_->SerializeData(data, output_);
+  }
+  void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
+    result_ = framer_->SerializeRstStream(rst_stream, output_);
+  }
+  void VisitSettings(const SpdySettingsIR& settings) override {
+    result_ = framer_->SerializeSettings(settings, output_);
+  }
+  void VisitPing(const SpdyPingIR& ping) override {
+    result_ = framer_->SerializePing(ping, output_);
+  }
+  void VisitGoAway(const SpdyGoAwayIR& goaway) override {
+    result_ = framer_->SerializeGoAway(goaway, output_);
+  }
+  void VisitHeaders(const SpdyHeadersIR& headers) override {
+    result_ = framer_->SerializeHeaders(headers, output_);
+  }
+  void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
+    result_ = framer_->SerializeWindowUpdate(window_update, output_);
+  }
+  void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
+    result_ = framer_->SerializePushPromise(push_promise, output_);
+  }
+  void VisitContinuation(const SpdyContinuationIR& continuation) override {
+    result_ = framer_->SerializeContinuation(continuation, output_);
+  }
+  void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
+    result_ = framer_->SerializeAltSvc(altsvc, output_);
+  }
+  void VisitPriority(const SpdyPriorityIR& priority) override {
+    result_ = framer_->SerializePriority(priority, output_);
+  }
+  void VisitPriorityUpdate(
+      const SpdyPriorityUpdateIR& priority_update) override {
+    result_ = framer_->SerializePriorityUpdate(priority_update, output_);
+  }
+  void VisitAcceptCh(const SpdyAcceptChIR& accept_ch) override {
+    result_ = framer_->SerializeAcceptCh(accept_ch, output_);
+  }
+
+  void VisitUnknown(const SpdyUnknownIR& unknown) override {
+    result_ = framer_->SerializeUnknown(unknown, output_);
+  }
+
+ private:
+  SpdyFramer* framer_;
+  ZeroCopyOutputBuffer* output_;
+  bool result_;
+};
+
+}  // namespace
+
+size_t SpdyFramer::SerializeFrame(const SpdyFrameIR& frame,
+                                  ZeroCopyOutputBuffer* output) {
+  FrameSerializationVisitorWithOutput visitor(this, output);
+  size_t free_bytes_before = output->BytesFree();
+  frame.Visit(&visitor);
+  return visitor.Result() ? free_bytes_before - output->BytesFree() : 0;
+}
+
+HpackEncoder* SpdyFramer::GetHpackEncoder() {
+  if (hpack_encoder_ == nullptr) {
+    hpack_encoder_ = std::make_unique<HpackEncoder>();
+    if (!compression_enabled()) {
+      hpack_encoder_->DisableCompression();
+    }
+  }
+  return hpack_encoder_.get();
+}
+
+void SpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) {
+  GetHpackEncoder()->ApplyHeaderTableSizeSetting(value);
+}
+
+size_t SpdyFramer::header_encoder_table_size() const {
+  if (hpack_encoder_ == nullptr) {
+    return kDefaultHeaderTableSizeSetting;
+  } else {
+    return hpack_encoder_->CurrentHeaderTableSizeSetting();
+  }
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_framer.h b/quiche/spdy/core/spdy_framer.h
new file mode 100644
index 0000000..dcf2e1d
--- /dev/null
+++ b/quiche/spdy/core/spdy_framer.h
@@ -0,0 +1,383 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_FRAMER_H_
+#define QUICHE_SPDY_CORE_SPDY_FRAMER_H_
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/hpack/hpack_encoder.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_headers_handler_interface.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/zero_copy_output_buffer.h"
+
+namespace spdy {
+
+namespace test {
+
+class SpdyFramerPeer;
+class SpdyFramerTest_MultipleContinuationFramesWithIterator_Test;
+class SpdyFramerTest_PushPromiseFramesWithIterator_Test;
+
+}  // namespace test
+
+class QUICHE_EXPORT_PRIVATE SpdyFrameSequence {
+ public:
+  virtual ~SpdyFrameSequence() {}
+
+  // Serializes the next frame in the sequence to |output|. Returns the number
+  // of bytes written to |output|.
+  virtual size_t NextFrame(ZeroCopyOutputBuffer* output) = 0;
+
+  // Returns true iff there is at least one more frame in the sequence.
+  virtual bool HasNextFrame() const = 0;
+
+  // Get SpdyFrameIR of the frame to be serialized.
+  virtual const SpdyFrameIR& GetIR() const = 0;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyFramer {
+ public:
+  enum CompressionOption {
+    ENABLE_COMPRESSION,
+    DISABLE_COMPRESSION,
+  };
+
+  // Create a SpdyFrameSequence to serialize |frame_ir|.
+  static std::unique_ptr<SpdyFrameSequence> CreateIterator(
+      SpdyFramer* framer,
+      std::unique_ptr<const SpdyFrameIR> frame_ir);
+
+  // Gets the serialized flags for the given |frame|.
+  static uint8_t GetSerializedFlags(const SpdyFrameIR& frame);
+
+  // Serialize a data frame.
+  static SpdySerializedFrame SerializeData(const SpdyDataIR& data_ir);
+  // Serializes the data frame header and optionally padding length fields,
+  // excluding actual data payload and padding.
+  static SpdySerializedFrame SerializeDataFrameHeaderWithPaddingLengthField(
+      const SpdyDataIR& data_ir);
+
+  // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
+  // frame is used to implement per stream flow control.
+  static SpdySerializedFrame SerializeWindowUpdate(
+      const SpdyWindowUpdateIR& window_update);
+
+  explicit SpdyFramer(CompressionOption option);
+
+  virtual ~SpdyFramer();
+
+  // Set debug callbacks to be called from the framer. The debug visitor is
+  // completely optional and need not be set in order for normal operation.
+  // If this is called multiple times, only the last visitor will be used.
+  void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
+
+  SpdySerializedFrame SerializeRstStream(
+      const SpdyRstStreamIR& rst_stream) const;
+
+  // Serializes a SETTINGS frame. The SETTINGS frame is
+  // used to communicate name/value pairs relevant to the communication channel.
+  SpdySerializedFrame SerializeSettings(const SpdySettingsIR& settings) const;
+
+  // Serializes a PING frame. The unique_id is used to
+  // identify the ping request/response.
+  SpdySerializedFrame SerializePing(const SpdyPingIR& ping) const;
+
+  // Serializes a GOAWAY frame. The GOAWAY frame is used
+  // prior to the shutting down of the TCP connection, and includes the
+  // stream_id of the last stream the sender of the frame is willing to process
+  // to completion.
+  SpdySerializedFrame SerializeGoAway(const SpdyGoAwayIR& goaway) const;
+
+  // Serializes a HEADERS frame. The HEADERS frame is used
+  // for sending headers.
+  SpdySerializedFrame SerializeHeaders(const SpdyHeadersIR& headers);
+
+  // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
+  // to inform the client that it will be receiving an additional stream
+  // in response to the original request. The frame includes synthesized
+  // headers to explain the upcoming data.
+  SpdySerializedFrame SerializePushPromise(
+      const SpdyPushPromiseIR& push_promise);
+
+  // Serializes a CONTINUATION frame. The CONTINUATION frame is used
+  // to continue a sequence of header block fragments.
+  SpdySerializedFrame SerializeContinuation(
+      const SpdyContinuationIR& continuation) const;
+
+  // Serializes an ALTSVC frame. The ALTSVC frame advertises the
+  // availability of an alternative service to the client.
+  SpdySerializedFrame SerializeAltSvc(const SpdyAltSvcIR& altsvc);
+
+  // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
+  // the relative priority of the given stream.
+  SpdySerializedFrame SerializePriority(const SpdyPriorityIR& priority) const;
+
+  // Serializes a PRIORITY_UPDATE frame.
+  // See https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html.
+  SpdySerializedFrame SerializePriorityUpdate(
+      const SpdyPriorityUpdateIR& priority_update) const;
+
+  // Serializes an ACCEPT_CH frame.  See
+  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02.
+  SpdySerializedFrame SerializeAcceptCh(const SpdyAcceptChIR& accept_ch) const;
+
+  // Serializes an unknown frame given a frame header and payload.
+  SpdySerializedFrame SerializeUnknown(const SpdyUnknownIR& unknown) const;
+
+  // Serialize a frame of unknown type.
+  SpdySerializedFrame SerializeFrame(const SpdyFrameIR& frame);
+
+  // Serialize a data frame.
+  bool SerializeData(const SpdyDataIR& data,
+                     ZeroCopyOutputBuffer* output) const;
+
+  // Serializes the data frame header and optionally padding length fields,
+  // excluding actual data payload and padding.
+  bool SerializeDataFrameHeaderWithPaddingLengthField(
+      const SpdyDataIR& data,
+      ZeroCopyOutputBuffer* output) const;
+
+  bool SerializeRstStream(const SpdyRstStreamIR& rst_stream,
+                          ZeroCopyOutputBuffer* output) const;
+
+  // Serializes a SETTINGS frame. The SETTINGS frame is
+  // used to communicate name/value pairs relevant to the communication channel.
+  bool SerializeSettings(const SpdySettingsIR& settings,
+                         ZeroCopyOutputBuffer* output) const;
+
+  // Serializes a PING frame. The unique_id is used to
+  // identify the ping request/response.
+  bool SerializePing(const SpdyPingIR& ping,
+                     ZeroCopyOutputBuffer* output) const;
+
+  // Serializes a GOAWAY frame. The GOAWAY frame is used
+  // prior to the shutting down of the TCP connection, and includes the
+  // stream_id of the last stream the sender of the frame is willing to process
+  // to completion.
+  bool SerializeGoAway(const SpdyGoAwayIR& goaway,
+                       ZeroCopyOutputBuffer* output) const;
+
+  // Serializes a HEADERS frame. The HEADERS frame is used
+  // for sending headers.
+  bool SerializeHeaders(const SpdyHeadersIR& headers,
+                        ZeroCopyOutputBuffer* output);
+
+  // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
+  // frame is used to implement per stream flow control.
+  bool SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
+                             ZeroCopyOutputBuffer* output) const;
+
+  // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
+  // to inform the client that it will be receiving an additional stream
+  // in response to the original request. The frame includes synthesized
+  // headers to explain the upcoming data.
+  bool SerializePushPromise(const SpdyPushPromiseIR& push_promise,
+                            ZeroCopyOutputBuffer* output);
+
+  // Serializes a CONTINUATION frame. The CONTINUATION frame is used
+  // to continue a sequence of header block fragments.
+  bool SerializeContinuation(const SpdyContinuationIR& continuation,
+                             ZeroCopyOutputBuffer* output) const;
+
+  // Serializes an ALTSVC frame. The ALTSVC frame advertises the
+  // availability of an alternative service to the client.
+  bool SerializeAltSvc(const SpdyAltSvcIR& altsvc,
+                       ZeroCopyOutputBuffer* output);
+
+  // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
+  // the relative priority of the given stream.
+  bool SerializePriority(const SpdyPriorityIR& priority,
+                         ZeroCopyOutputBuffer* output) const;
+
+  // Serializes a PRIORITY_UPDATE frame.
+  // See https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html.
+  bool SerializePriorityUpdate(const SpdyPriorityUpdateIR& priority_update,
+                               ZeroCopyOutputBuffer* output) const;
+
+  // Serializes an ACCEPT_CH frame.  See
+  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02.
+  bool SerializeAcceptCh(const SpdyAcceptChIR& accept_ch,
+                         ZeroCopyOutputBuffer* output) const;
+
+  // Serializes an unknown frame given a frame header and payload.
+  bool SerializeUnknown(const SpdyUnknownIR& unknown,
+                        ZeroCopyOutputBuffer* output) const;
+
+  // Serialize a frame of unknown type.
+  size_t SerializeFrame(const SpdyFrameIR& frame, ZeroCopyOutputBuffer* output);
+
+  // Returns whether this SpdyFramer will compress header blocks using HPACK.
+  bool compression_enabled() const {
+    return compression_option_ == ENABLE_COMPRESSION;
+  }
+
+  void SetHpackIndexingPolicy(HpackEncoder::IndexingPolicy policy) {
+    GetHpackEncoder()->SetIndexingPolicy(std::move(policy));
+  }
+
+  // Updates the maximum size of the header encoder compression table.
+  void UpdateHeaderEncoderTableSize(uint32_t value);
+
+  // Returns the maximum size of the header encoder compression table.
+  size_t header_encoder_table_size() const;
+
+  // Get (and lazily initialize) the HPACK encoder state.
+  HpackEncoder* GetHpackEncoder();
+
+  // Gets the HPACK encoder state. Returns nullptr if the encoder has not been
+  // initialized.
+  const HpackEncoder* GetHpackEncoder() const { return hpack_encoder_.get(); }
+
+ protected:
+  friend class test::SpdyFramerPeer;
+  friend class test::SpdyFramerTest_MultipleContinuationFramesWithIterator_Test;
+  friend class test::SpdyFramerTest_PushPromiseFramesWithIterator_Test;
+
+  // Iteratively converts a SpdyFrameIR into an appropriate sequence of Spdy
+  // frames.
+  // Example usage:
+  // std::unique_ptr<SpdyFrameSequence> it = CreateIterator(framer, frame_ir);
+  // while (it->HasNextFrame()) {
+  //   if(it->NextFrame(output) == 0) {
+  //     // Write failed;
+  //   }
+  // }
+  class QUICHE_EXPORT_PRIVATE SpdyFrameIterator : public SpdyFrameSequence {
+   public:
+    // Creates an iterator with the provided framer.
+    // Does not take ownership of |framer|.
+    // |framer| must outlive this instance.
+    explicit SpdyFrameIterator(SpdyFramer* framer);
+    ~SpdyFrameIterator() override;
+
+    // Serializes the next frame in the sequence to |output|. Returns the number
+    // of bytes written to |output|.
+    size_t NextFrame(ZeroCopyOutputBuffer* output) override;
+
+    // Returns true iff there is at least one more frame in the sequence.
+    bool HasNextFrame() const override;
+
+    // SpdyFrameIterator is neither copyable nor movable.
+    SpdyFrameIterator(const SpdyFrameIterator&) = delete;
+    SpdyFrameIterator& operator=(const SpdyFrameIterator&) = delete;
+
+   protected:
+    virtual size_t GetFrameSizeSansBlock() const = 0;
+    virtual bool SerializeGivenEncoding(const std::string& encoding,
+                                        ZeroCopyOutputBuffer* output) const = 0;
+
+    SpdyFramer* GetFramer() const { return framer_; }
+
+    void SetEncoder(const SpdyFrameWithHeaderBlockIR* ir) {
+      encoder_ =
+          framer_->GetHpackEncoder()->EncodeHeaderSet(ir->header_block());
+    }
+
+    bool has_next_frame() const { return has_next_frame_; }
+
+   private:
+    SpdyFramer* const framer_;
+    std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoder_;
+    bool is_first_frame_;
+    bool has_next_frame_;
+  };
+
+  // Iteratively converts a SpdyHeadersIR (with a possibly huge
+  // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and
+  // write to the output.
+  class QUICHE_EXPORT_PRIVATE SpdyHeaderFrameIterator
+      : public SpdyFrameIterator {
+   public:
+    // Does not take ownership of |framer|. Take ownership of |headers_ir|.
+    SpdyHeaderFrameIterator(SpdyFramer* framer,
+                            std::unique_ptr<const SpdyHeadersIR> headers_ir);
+
+    ~SpdyHeaderFrameIterator() override;
+
+   private:
+    const SpdyFrameIR& GetIR() const override;
+    size_t GetFrameSizeSansBlock() const override;
+    bool SerializeGivenEncoding(const std::string& encoding,
+                                ZeroCopyOutputBuffer* output) const override;
+
+    const std::unique_ptr<const SpdyHeadersIR> headers_ir_;
+  };
+
+  // Iteratively converts a SpdyPushPromiseIR (with a possibly huge
+  // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and
+  // write to the output.
+  class QUICHE_EXPORT_PRIVATE SpdyPushPromiseFrameIterator
+      : public SpdyFrameIterator {
+   public:
+    // Does not take ownership of |framer|. Take ownership of |push_promise_ir|.
+    SpdyPushPromiseFrameIterator(
+        SpdyFramer* framer,
+        std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir);
+
+    ~SpdyPushPromiseFrameIterator() override;
+
+   private:
+    const SpdyFrameIR& GetIR() const override;
+    size_t GetFrameSizeSansBlock() const override;
+    bool SerializeGivenEncoding(const std::string& encoding,
+                                ZeroCopyOutputBuffer* output) const override;
+
+    const std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir_;
+  };
+
+  // Converts a SpdyFrameIR into one Spdy frame (a sequence of length 1), and
+  // write it to the output.
+  class QUICHE_EXPORT_PRIVATE SpdyControlFrameIterator
+      : public SpdyFrameSequence {
+   public:
+    SpdyControlFrameIterator(SpdyFramer* framer,
+                             std::unique_ptr<const SpdyFrameIR> frame_ir);
+    ~SpdyControlFrameIterator() override;
+
+    size_t NextFrame(ZeroCopyOutputBuffer* output) override;
+
+    bool HasNextFrame() const override;
+
+    const SpdyFrameIR& GetIR() const override;
+
+   private:
+    SpdyFramer* const framer_;
+    std::unique_ptr<const SpdyFrameIR> frame_ir_;
+    bool has_next_frame_ = true;
+  };
+
+ private:
+  void SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
+                                     uint8_t* flags,
+                                     size_t* size,
+                                     std::string* hpack_encoding,
+                                     int* weight,
+                                     size_t* length_field);
+  void SerializePushPromiseBuilderHelper(const SpdyPushPromiseIR& push_promise,
+                                         uint8_t* flags,
+                                         std::string* hpack_encoding,
+                                         size_t* size);
+
+  std::unique_ptr<HpackEncoder> hpack_encoder_;
+
+  SpdyFramerDebugVisitorInterface* debug_visitor_;
+
+  // Determines whether HPACK compression is used.
+  const CompressionOption compression_option_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_FRAMER_H_
diff --git a/quiche/spdy/core/spdy_framer_test.cc b/quiche/spdy/core/spdy_framer_test.cc
new file mode 100644
index 0000000..a99a08d
--- /dev/null
+++ b/quiche/spdy/core/spdy_framer_test.cc
@@ -0,0 +1,5085 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_framer.h"
+
+#include <stdlib.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/array_output_buffer.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/mock_spdy_framer_visitor.h"
+#include "quiche/spdy/core/recording_headers_handler.h"
+#include "quiche/spdy/core/spdy_bitmasks.h"
+#include "quiche/spdy/core/spdy_frame_builder.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+using ::http2::Http2DecoderAdapter;
+using ::testing::_;
+
+namespace spdy {
+
+namespace test {
+
+namespace {
+
+const int64_t kSize = 1024 * 1024;
+char output_buffer[kSize] = "";
+
+// frame_list_char is used to hold frames to be compared with output_buffer.
+const int64_t buffer_size = 64 * 1024;
+char frame_list_char[buffer_size] = "";
+}  // namespace
+
+class MockDebugVisitor : public SpdyFramerDebugVisitorInterface {
+ public:
+  MOCK_METHOD4(OnSendCompressedFrame,
+               void(SpdyStreamId stream_id,
+                    SpdyFrameType type,
+                    size_t payload_len,
+                    size_t frame_len));
+
+  MOCK_METHOD3(OnReceiveCompressedFrame,
+               void(SpdyStreamId stream_id,
+                    SpdyFrameType type,
+                    size_t frame_len));
+};
+
+MATCHER_P(IsFrameUnionOf, frame_list, "") {
+  size_t size_verified = 0;
+  for (const auto& frame : *frame_list) {
+    if (arg.size() < size_verified + frame.size()) {
+      QUICHE_LOG(FATAL)
+          << "Incremental header serialization should not lead to a "
+          << "higher total frame length than non-incremental method.";
+      return false;
+    }
+    if (memcmp(arg.data() + size_verified, frame.data(), frame.size())) {
+      CompareCharArraysWithHexError(
+          "Header serialization methods should be equivalent: ",
+          reinterpret_cast<unsigned char*>(arg.data() + size_verified),
+          frame.size(), reinterpret_cast<unsigned char*>(frame.data()),
+          frame.size());
+      return false;
+    }
+    size_verified += frame.size();
+  }
+  return size_verified == arg.size();
+}
+
+class SpdyFramerPeer {
+ public:
+  // TODO(dahollings): Remove these methods when deprecating non-incremental
+  // header serialization path.
+  static std::unique_ptr<SpdyHeadersIR> CloneSpdyHeadersIR(
+      const SpdyHeadersIR& headers) {
+    auto new_headers = std::make_unique<SpdyHeadersIR>(
+        headers.stream_id(), headers.header_block().Clone());
+    new_headers->set_fin(headers.fin());
+    new_headers->set_has_priority(headers.has_priority());
+    new_headers->set_weight(headers.weight());
+    new_headers->set_parent_stream_id(headers.parent_stream_id());
+    new_headers->set_exclusive(headers.exclusive());
+    if (headers.padded()) {
+      new_headers->set_padding_len(headers.padding_payload_len() + 1);
+    }
+    return new_headers;
+  }
+
+  static SpdySerializedFrame SerializeHeaders(SpdyFramer* framer,
+                                              const SpdyHeadersIR& headers) {
+    SpdySerializedFrame serialized_headers_old_version(
+        framer->SerializeHeaders(headers));
+    framer->hpack_encoder_.reset(nullptr);
+    auto* saved_debug_visitor = framer->debug_visitor_;
+    framer->debug_visitor_ = nullptr;
+
+    std::vector<SpdySerializedFrame> frame_list;
+    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
+    SpdyFramer::SpdyHeaderFrameIterator it(framer, CloneSpdyHeadersIR(headers));
+    while (it.HasNextFrame()) {
+      size_t size_before = frame_list_buffer.Size();
+      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
+      frame_list.emplace_back(
+          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
+                              frame_list_buffer.Size() - size_before, false));
+    }
+    framer->debug_visitor_ = saved_debug_visitor;
+
+    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
+    return serialized_headers_old_version;
+  }
+
+  static SpdySerializedFrame SerializeHeaders(SpdyFramer* framer,
+                                              const SpdyHeadersIR& headers,
+                                              ArrayOutputBuffer* output) {
+    if (output == nullptr) {
+      return SerializeHeaders(framer, headers);
+    }
+    output->Reset();
+    EXPECT_TRUE(framer->SerializeHeaders(headers, output));
+    SpdySerializedFrame serialized_headers_old_version(output->Begin(),
+                                                       output->Size(), false);
+    framer->hpack_encoder_.reset(nullptr);
+    auto* saved_debug_visitor = framer->debug_visitor_;
+    framer->debug_visitor_ = nullptr;
+
+    std::vector<SpdySerializedFrame> frame_list;
+    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
+    SpdyFramer::SpdyHeaderFrameIterator it(framer, CloneSpdyHeadersIR(headers));
+    while (it.HasNextFrame()) {
+      size_t size_before = frame_list_buffer.Size();
+      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
+      frame_list.emplace_back(
+          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
+                              frame_list_buffer.Size() - size_before, false));
+    }
+    framer->debug_visitor_ = saved_debug_visitor;
+
+    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
+    return serialized_headers_old_version;
+  }
+
+  static std::unique_ptr<SpdyPushPromiseIR> CloneSpdyPushPromiseIR(
+      const SpdyPushPromiseIR& push_promise) {
+    auto new_push_promise = std::make_unique<SpdyPushPromiseIR>(
+        push_promise.stream_id(), push_promise.promised_stream_id(),
+        push_promise.header_block().Clone());
+    new_push_promise->set_fin(push_promise.fin());
+    if (push_promise.padded()) {
+      new_push_promise->set_padding_len(push_promise.padding_payload_len() + 1);
+    }
+    return new_push_promise;
+  }
+
+  static SpdySerializedFrame SerializePushPromise(
+      SpdyFramer* framer,
+      const SpdyPushPromiseIR& push_promise) {
+    SpdySerializedFrame serialized_headers_old_version =
+        framer->SerializePushPromise(push_promise);
+    framer->hpack_encoder_.reset(nullptr);
+    auto* saved_debug_visitor = framer->debug_visitor_;
+    framer->debug_visitor_ = nullptr;
+
+    std::vector<SpdySerializedFrame> frame_list;
+    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
+    frame_list_buffer.Reset();
+    SpdyFramer::SpdyPushPromiseFrameIterator it(
+        framer, CloneSpdyPushPromiseIR(push_promise));
+    while (it.HasNextFrame()) {
+      size_t size_before = frame_list_buffer.Size();
+      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
+      frame_list.emplace_back(
+          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
+                              frame_list_buffer.Size() - size_before, false));
+    }
+    framer->debug_visitor_ = saved_debug_visitor;
+
+    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
+    return serialized_headers_old_version;
+  }
+
+  static SpdySerializedFrame SerializePushPromise(
+      SpdyFramer* framer,
+      const SpdyPushPromiseIR& push_promise,
+      ArrayOutputBuffer* output) {
+    if (output == nullptr) {
+      return SerializePushPromise(framer, push_promise);
+    }
+    output->Reset();
+    EXPECT_TRUE(framer->SerializePushPromise(push_promise, output));
+    SpdySerializedFrame serialized_headers_old_version(output->Begin(),
+                                                       output->Size(), false);
+    framer->hpack_encoder_.reset(nullptr);
+    auto* saved_debug_visitor = framer->debug_visitor_;
+    framer->debug_visitor_ = nullptr;
+
+    std::vector<SpdySerializedFrame> frame_list;
+    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
+    frame_list_buffer.Reset();
+    SpdyFramer::SpdyPushPromiseFrameIterator it(
+        framer, CloneSpdyPushPromiseIR(push_promise));
+    while (it.HasNextFrame()) {
+      size_t size_before = frame_list_buffer.Size();
+      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
+      frame_list.emplace_back(
+          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
+                              frame_list_buffer.Size() - size_before, false));
+    }
+    framer->debug_visitor_ = saved_debug_visitor;
+
+    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
+    return serialized_headers_old_version;
+  }
+};
+
+class TestSpdyVisitor : public SpdyFramerVisitorInterface,
+                        public SpdyFramerDebugVisitorInterface {
+ public:
+  // This is larger than our max frame size because header blocks that
+  // are too long can spill over into CONTINUATION frames.
+  static constexpr size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024;
+
+  explicit TestSpdyVisitor(SpdyFramer::CompressionOption option)
+      : framer_(option),
+        error_count_(0),
+        headers_frame_count_(0),
+        push_promise_frame_count_(0),
+        goaway_count_(0),
+        setting_count_(0),
+        settings_ack_sent_(0),
+        settings_ack_received_(0),
+        continuation_count_(0),
+        altsvc_count_(0),
+        priority_count_(0),
+        on_unknown_frame_result_(false),
+        last_window_update_stream_(0),
+        last_window_update_delta_(0),
+        last_push_promise_stream_(0),
+        last_push_promise_promised_stream_(0),
+        data_bytes_(0),
+        fin_frame_count_(0),
+        fin_flag_count_(0),
+        end_of_stream_count_(0),
+        control_frame_header_data_count_(0),
+        zero_length_control_frame_header_data_count_(0),
+        data_frame_count_(0),
+        last_payload_len_(0),
+        last_frame_len_(0),
+        header_buffer_(new char[kDefaultHeaderBufferSize]),
+        header_buffer_length_(0),
+        header_buffer_size_(kDefaultHeaderBufferSize),
+        header_stream_id_(static_cast<SpdyStreamId>(-1)),
+        header_control_type_(SpdyFrameType::DATA),
+        header_buffer_valid_(false) {}
+
+  void OnError(Http2DecoderAdapter::SpdyFramerError error,
+               std::string /*detailed_error*/) override {
+    QUICHE_VLOG(1) << "SpdyFramer Error: "
+                   << Http2DecoderAdapter::SpdyFramerErrorToString(error);
+    ++error_count_;
+  }
+
+  void OnDataFrameHeader(SpdyStreamId stream_id,
+                         size_t length,
+                         bool fin) override {
+    QUICHE_VLOG(1) << "OnDataFrameHeader(" << stream_id << ", " << length
+                   << ", " << fin << ")";
+    ++data_frame_count_;
+    header_stream_id_ = stream_id;
+  }
+
+  void OnStreamFrameData(SpdyStreamId stream_id,
+                         const char* data,
+                         size_t len) override {
+    QUICHE_VLOG(1) << "OnStreamFrameData(" << stream_id << ", data, " << len
+                   << ", "
+                   << ")   data:\n"
+                   << quiche::QuicheTextUtils::HexDump(
+                          absl::string_view(data, len));
+    EXPECT_EQ(header_stream_id_, stream_id);
+
+    data_bytes_ += len;
+  }
+
+  void OnStreamEnd(SpdyStreamId stream_id) override {
+    QUICHE_VLOG(1) << "OnStreamEnd(" << stream_id << ")";
+    EXPECT_EQ(header_stream_id_, stream_id);
+    ++end_of_stream_count_;
+  }
+
+  void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override {
+    QUICHE_VLOG(1) << "OnStreamPadding(" << stream_id << ", " << value << ")\n";
+    EXPECT_EQ(header_stream_id_, stream_id);
+    // Count the padding length field byte against total data bytes.
+    data_bytes_ += 1;
+  }
+
+  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
+    QUICHE_VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n";
+    EXPECT_EQ(header_stream_id_, stream_id);
+    data_bytes_ += len;
+  }
+
+  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId /*stream_id*/) override {
+    if (headers_handler_ == nullptr) {
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
+    }
+    return headers_handler_.get();
+  }
+
+  void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override {
+    QUICHE_CHECK(headers_handler_ != nullptr);
+    headers_ = headers_handler_->decoded_block().Clone();
+    header_bytes_received_ = headers_handler_->uncompressed_header_bytes();
+    headers_handler_.reset();
+  }
+
+  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {
+    QUICHE_VLOG(1) << "OnRstStream(" << stream_id << ", " << error_code << ")";
+    ++fin_frame_count_;
+  }
+
+  void OnSetting(SpdySettingsId id, uint32_t value) override {
+    QUICHE_VLOG(1) << "OnSetting(" << id << ", " << std::hex << value << ")";
+    ++setting_count_;
+  }
+
+  void OnSettingsAck() override {
+    QUICHE_VLOG(1) << "OnSettingsAck";
+    ++settings_ack_received_;
+  }
+
+  void OnSettingsEnd() override {
+    QUICHE_VLOG(1) << "OnSettingsEnd";
+    ++settings_ack_sent_;
+  }
+
+  void OnPing(SpdyPingId unique_id, bool is_ack) override {
+    QUICHE_LOG(DFATAL) << "OnPing(" << unique_id << ", " << (is_ack ? 1 : 0)
+                       << ")";
+  }
+
+  void OnGoAway(SpdyStreamId last_accepted_stream_id,
+                SpdyErrorCode error_code) override {
+    QUICHE_VLOG(1) << "OnGoAway(" << last_accepted_stream_id << ", "
+                   << error_code << ")";
+    ++goaway_count_;
+  }
+
+  void OnHeaders(SpdyStreamId stream_id,
+                 bool has_priority,
+                 int weight,
+                 SpdyStreamId parent_stream_id,
+                 bool exclusive,
+                 bool fin,
+                 bool end) override {
+    QUICHE_VLOG(1) << "OnHeaders(" << stream_id << ", " << has_priority << ", "
+                   << weight << ", " << parent_stream_id << ", " << exclusive
+                   << ", " << fin << ", " << end << ")";
+    ++headers_frame_count_;
+    InitHeaderStreaming(SpdyFrameType::HEADERS, stream_id);
+    if (fin) {
+      ++fin_flag_count_;
+    }
+    header_has_priority_ = has_priority;
+    header_parent_stream_id_ = parent_stream_id;
+    header_exclusive_ = exclusive;
+  }
+
+  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {
+    QUICHE_VLOG(1) << "OnWindowUpdate(" << stream_id << ", "
+                   << delta_window_size << ")";
+    last_window_update_stream_ = stream_id;
+    last_window_update_delta_ = delta_window_size;
+  }
+
+  void OnPushPromise(SpdyStreamId stream_id,
+                     SpdyStreamId promised_stream_id,
+                     bool end) override {
+    QUICHE_VLOG(1) << "OnPushPromise(" << stream_id << ", "
+                   << promised_stream_id << ", " << end << ")";
+    ++push_promise_frame_count_;
+    InitHeaderStreaming(SpdyFrameType::PUSH_PROMISE, stream_id);
+    last_push_promise_stream_ = stream_id;
+    last_push_promise_promised_stream_ = promised_stream_id;
+  }
+
+  void OnContinuation(SpdyStreamId stream_id, bool end) override {
+    QUICHE_VLOG(1) << "OnContinuation(" << stream_id << ", " << end << ")";
+    ++continuation_count_;
+  }
+
+  void OnAltSvc(SpdyStreamId stream_id,
+                absl::string_view origin,
+                const SpdyAltSvcWireFormat::AlternativeServiceVector&
+                    altsvc_vector) override {
+    QUICHE_VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin
+                   << "\", altsvc_vector)";
+    test_altsvc_ir_ = std::make_unique<SpdyAltSvcIR>(stream_id);
+    if (origin.length() > 0) {
+      test_altsvc_ir_->set_origin(std::string(origin));
+    }
+    for (const auto& altsvc : altsvc_vector) {
+      test_altsvc_ir_->add_altsvc(altsvc);
+    }
+    ++altsvc_count_;
+  }
+
+  void OnPriority(SpdyStreamId stream_id,
+                  SpdyStreamId parent_stream_id,
+                  int weight,
+                  bool exclusive) override {
+    QUICHE_VLOG(1) << "OnPriority(" << stream_id << ", " << parent_stream_id
+                   << ", " << weight << ", " << (exclusive ? 1 : 0) << ")";
+    ++priority_count_;
+  }
+
+  void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
+                        absl::string_view priority_field_value) override {
+    QUICHE_VLOG(1) << "OnPriorityUpdate(" << prioritized_stream_id << ", "
+                   << priority_field_value << ")";
+  }
+
+  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override {
+    QUICHE_VLOG(1) << "OnUnknownFrame(" << stream_id << ", " << frame_type
+                   << ")";
+    return on_unknown_frame_result_;
+  }
+
+  void OnSendCompressedFrame(SpdyStreamId stream_id,
+                             SpdyFrameType type,
+                             size_t payload_len,
+                             size_t frame_len) override {
+    QUICHE_VLOG(1) << "OnSendCompressedFrame(" << stream_id << ", " << type
+                   << ", " << payload_len << ", " << frame_len << ")";
+    last_payload_len_ = payload_len;
+    last_frame_len_ = frame_len;
+  }
+
+  void OnReceiveCompressedFrame(SpdyStreamId stream_id,
+                                SpdyFrameType type,
+                                size_t frame_len) override {
+    QUICHE_VLOG(1) << "OnReceiveCompressedFrame(" << stream_id << ", " << type
+                   << ", " << frame_len << ")";
+    last_frame_len_ = frame_len;
+  }
+
+  // Convenience function which runs a framer simulation with particular input.
+  void SimulateInFramer(const unsigned char* input, size_t size) {
+    deframer_.set_visitor(this);
+    size_t input_remaining = size;
+    const char* input_ptr = reinterpret_cast<const char*>(input);
+    while (input_remaining > 0 && deframer_.spdy_framer_error() ==
+                                      Http2DecoderAdapter::SPDY_NO_ERROR) {
+      // To make the tests more interesting, we feed random (and small) chunks
+      // into the framer.  This simulates getting strange-sized reads from
+      // the socket.
+      const size_t kMaxReadSize = 32;
+      size_t bytes_read =
+          (rand() % std::min(input_remaining, kMaxReadSize)) + 1;  // NOLINT
+      size_t bytes_processed = deframer_.ProcessInput(input_ptr, bytes_read);
+      input_remaining -= bytes_processed;
+      input_ptr += bytes_processed;
+    }
+  }
+
+  void InitHeaderStreaming(SpdyFrameType header_control_type,
+                           SpdyStreamId stream_id) {
+    if (!IsDefinedFrameType(SerializeFrameType(header_control_type))) {
+      QUICHE_DLOG(FATAL) << "Attempted to init header streaming with "
+                         << "invalid control frame type: "
+                         << header_control_type;
+    }
+    memset(header_buffer_.get(), 0, header_buffer_size_);
+    header_buffer_length_ = 0;
+    header_stream_id_ = stream_id;
+    header_control_type_ = header_control_type;
+    header_buffer_valid_ = true;
+  }
+
+  void set_extension_visitor(ExtensionVisitorInterface* extension) {
+    deframer_.set_extension_visitor(extension);
+  }
+
+  // Override the default buffer size (16K). Call before using the framer!
+  void set_header_buffer_size(size_t header_buffer_size) {
+    header_buffer_size_ = header_buffer_size;
+    header_buffer_.reset(new char[header_buffer_size]);
+  }
+
+  SpdyFramer framer_;
+  Http2DecoderAdapter deframer_;
+
+  // Counters from the visitor callbacks.
+  int error_count_;
+  int headers_frame_count_;
+  int push_promise_frame_count_;
+  int goaway_count_;
+  int setting_count_;
+  int settings_ack_sent_;
+  int settings_ack_received_;
+  int continuation_count_;
+  int altsvc_count_;
+  int priority_count_;
+  std::unique_ptr<SpdyAltSvcIR> test_altsvc_ir_;
+  bool on_unknown_frame_result_;
+  SpdyStreamId last_window_update_stream_;
+  int last_window_update_delta_;
+  SpdyStreamId last_push_promise_stream_;
+  SpdyStreamId last_push_promise_promised_stream_;
+  int data_bytes_;
+  int fin_frame_count_;      // The count of RST_STREAM type frames received.
+  int fin_flag_count_;       // The count of frames with the FIN flag set.
+  int end_of_stream_count_;  // The count of zero-length data frames.
+  int control_frame_header_data_count_;  // The count of chunks received.
+  // The count of zero-length control frame header data chunks received.
+  int zero_length_control_frame_header_data_count_;
+  int data_frame_count_;
+  size_t last_payload_len_;
+  size_t last_frame_len_;
+
+  // Header block streaming state:
+  std::unique_ptr<char[]> header_buffer_;
+  size_t header_buffer_length_;
+  size_t header_buffer_size_;
+  size_t header_bytes_received_;
+  SpdyStreamId header_stream_id_;
+  SpdyFrameType header_control_type_;
+  bool header_buffer_valid_;
+  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
+  Http2HeaderBlock headers_;
+  bool header_has_priority_;
+  SpdyStreamId header_parent_stream_id_;
+  bool header_exclusive_;
+};
+
+class TestExtension : public ExtensionVisitorInterface {
+ public:
+  void OnSetting(SpdySettingsId id, uint32_t value) override {
+    settings_received_.push_back({id, value});
+  }
+
+  // Called when non-standard frames are received.
+  bool OnFrameHeader(SpdyStreamId stream_id,
+                     size_t length,
+                     uint8_t type,
+                     uint8_t flags) override {
+    stream_id_ = stream_id;
+    length_ = length;
+    type_ = type;
+    flags_ = flags;
+    return true;
+  }
+
+  // The payload for a single frame may be delivered as multiple calls to
+  // OnFramePayload.
+  void OnFramePayload(const char* data, size_t len) override {
+    payload_.append(data, len);
+  }
+
+  std::vector<std::pair<SpdySettingsId, uint32_t>> settings_received_;
+  SpdyStreamId stream_id_ = 0;
+  size_t length_ = 0;
+  uint8_t type_ = 0;
+  uint8_t flags_ = 0;
+  std::string payload_;
+};
+
+// Exposes SpdyUnknownIR::set_length() for testing purposes.
+class TestSpdyUnknownIR : public SpdyUnknownIR {
+ public:
+  using SpdyUnknownIR::set_length;
+  using SpdyUnknownIR::SpdyUnknownIR;
+};
+
+enum Output { USE, NOT_USE };
+
+class SpdyFramerTest : public QuicheTestWithParam<Output> {
+ public:
+  SpdyFramerTest()
+      : output_(output_buffer, kSize),
+        framer_(SpdyFramer::ENABLE_COMPRESSION),
+        deframer_(absl::make_unique<Http2DecoderAdapter>()) {}
+
+ protected:
+  void SetUp() override {
+    switch (GetParam()) {
+      case USE:
+        use_output_ = true;
+        break;
+      case NOT_USE:
+        // TODO(yasong): remove this case after
+        // gfe2_reloadable_flag_write_queue_zero_copy_buffer deprecates.
+        use_output_ = false;
+        break;
+    }
+  }
+
+  void CompareFrame(const std::string& description,
+                    const SpdySerializedFrame& actual_frame,
+                    const unsigned char* expected,
+                    const int expected_len) {
+    const unsigned char* actual =
+        reinterpret_cast<const unsigned char*>(actual_frame.data());
+    CompareCharArraysWithHexError(description, actual, actual_frame.size(),
+                                  expected, expected_len);
+  }
+
+  bool use_output_ = false;
+  ArrayOutputBuffer output_;
+  SpdyFramer framer_;
+  std::unique_ptr<Http2DecoderAdapter> deframer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(SpdyFramerTests,
+                         SpdyFramerTest,
+                         ::testing::Values(USE, NOT_USE));
+
+// Test that we can encode and decode a SpdyHeaderBlock in serialized form.
+TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+
+  // Encode the header block into a Headers frame.
+  SpdyHeadersIR headers(/* stream_id = */ 1);
+  headers.SetHeader("alpha", "beta");
+  headers.SetHeader("gamma", "charlie");
+  headers.SetHeader("cookie", "key1=value1; key2=value2");
+  SpdySerializedFrame frame(
+      SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size());
+
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(headers.header_block(), visitor.headers_);
+}
+
+// Test that if there's not a full frame, we fail to parse it.
+TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+
+  // Encode the header block into a Headers frame.
+  SpdyHeadersIR headers(/* stream_id = */ 1);
+  headers.SetHeader("alpha", "beta");
+  headers.SetHeader("gamma", "charlie");
+  SpdySerializedFrame frame(
+      SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size() - 2);
+
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_THAT(visitor.headers_, testing::IsEmpty());
+}
+
+// Test that we can encode and decode stream dependency values in a header
+// frame.
+TEST_P(SpdyFramerTest, HeaderStreamDependencyValues) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+
+  const SpdyStreamId parent_stream_id_test_array[] = {0, 3};
+  for (SpdyStreamId parent_stream_id : parent_stream_id_test_array) {
+    const bool exclusive_test_array[] = {true, false};
+    for (bool exclusive : exclusive_test_array) {
+      SpdyHeadersIR headers(1);
+      headers.set_has_priority(true);
+      headers.set_parent_stream_id(parent_stream_id);
+      headers.set_exclusive(exclusive);
+      SpdySerializedFrame frame(
+          SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
+
+      TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+      visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                               frame.size());
+
+      EXPECT_TRUE(visitor.header_has_priority_);
+      EXPECT_EQ(parent_stream_id, visitor.header_parent_stream_id_);
+      EXPECT_EQ(exclusive, visitor.header_exclusive_);
+    }
+  }
+}
+
+// Test that if we receive a frame with a payload length field at the default
+// max size, we do not set an error in ProcessInput.
+TEST_P(SpdyFramerTest, AcceptMaxFrameSizeSetting) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  // DATA frame with maximum allowed payload length.
+  unsigned char kH2FrameData[] = {
+      0x00, 0x40, 0x00,        // Length: 2^14
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: None
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  // Junk payload
+  };
+
+  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
+                            sizeof(kH2FrameData), false);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 16384, 0x0, 0x0));
+  EXPECT_CALL(visitor, OnDataFrameHeader(1, 1 << 14, false));
+  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4));
+  deframer_->ProcessInput(frame.data(), frame.size());
+  EXPECT_FALSE(deframer_->HasError());
+}
+
+// Test that if we receive a frame with a payload length larger than the default
+// max size, we set an error of SPDY_INVALID_CONTROL_FRAME_SIZE.
+TEST_P(SpdyFramerTest, ExceedMaxFrameSizeSetting) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  // DATA frame with too large payload length.
+  unsigned char kH2FrameData[] = {
+      0x00, 0x40, 0x01,        // Length: 2^14 + 1
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: None
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  // Junk payload
+  };
+
+  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
+                            sizeof(kH2FrameData), false);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 16385, 0x0, 0x0));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD, _));
+  deframer_->ProcessInput(frame.data(), frame.size());
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we set a larger max frame size and then receive a frame with a
+// payload length at that larger size, we do not set an error in ProcessInput.
+TEST_P(SpdyFramerTest, AcceptLargerMaxFrameSizeSetting) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  const size_t big_frame_size = (1 << 14) + 1;
+  deframer_->SetMaxFrameSize(big_frame_size);
+
+  // DATA frame with larger-than-default but acceptable payload length.
+  unsigned char kH2FrameData[] = {
+      0x00, 0x40, 0x01,        // Length: 2^14 + 1
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: None
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  // Junk payload
+  };
+
+  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
+                            sizeof(kH2FrameData), false);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, big_frame_size, 0x0, 0x0));
+  EXPECT_CALL(visitor, OnDataFrameHeader(1, big_frame_size, false));
+  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4));
+  deframer_->ProcessInput(frame.data(), frame.size());
+  EXPECT_FALSE(deframer_->HasError());
+}
+
+// Test that if we receive a DATA frame with padding length larger than the
+// payload length, we set an error of SPDY_INVALID_PADDING
+TEST_P(SpdyFramerTest, OversizedDataPaddingError) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  // DATA frame with invalid padding length.
+  // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses
+  // MSVC, where |char| is signed by default, which would not compile because of
+  // the element exceeding 127.
+  unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x00,                    //   Type: DATA
+      0x09,                    //  Flags: END_STREAM|PADDED
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xff,                    // PadLen: 255 trailing bytes (Too Long)
+      0x00, 0x00, 0x00, 0x00,  // Padding
+  };
+
+  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
+                            sizeof(kH2FrameData), false);
+
+  {
+    testing::InSequence seq;
+    EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, 0x9));
+    EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, 1));
+    EXPECT_CALL(visitor, OnStreamPadding(1, 1));
+    EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_PADDING, _));
+  }
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a DATA frame with padding length not larger than the
+// payload length, we do not set an error of SPDY_INVALID_PADDING
+TEST_P(SpdyFramerTest, CorrectlySizedDataPaddingNoError) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  // DATA frame with valid Padding length
+  char kH2FrameData[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x00,                    //   Type: DATA
+      0x08,                    //  Flags: PADDED
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x04,                    // PadLen: 4 trailing bytes
+      0x00, 0x00, 0x00, 0x00,  // Padding
+  };
+
+  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
+
+  {
+    testing::InSequence seq;
+    EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, 0x8));
+    EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, false));
+    EXPECT_CALL(visitor, OnStreamPadLength(1, 4));
+    EXPECT_CALL(visitor, OnError(_, _)).Times(0);
+    // Note that OnStreamFrameData(1, _, 1)) is never called
+    // since there is no data, only padding
+    EXPECT_CALL(visitor, OnStreamPadding(1, 4));
+  }
+
+  EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_FALSE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a HEADERS frame with padding length larger than the
+// payload length, we set an error of SPDY_INVALID_PADDING
+TEST_P(SpdyFramerTest, OversizedHeadersPaddingError) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  // HEADERS frame with invalid padding length.
+  // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses
+  // MSVC, where |char| is signed by default, which would not compile because of
+  // the element exceeding 127.
+  unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x01,                    //   Type: HEADERS
+      0x08,                    //  Flags: PADDED
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xff,                    // PadLen: 255 trailing bytes (Too Long)
+      0x00, 0x00, 0x00, 0x00,  // Padding
+  };
+
+  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
+                            sizeof(kH2FrameData), false);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x1, 0x8));
+  EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false));
+  EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1);
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_PADDING, _));
+  EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a HEADERS frame with padding length not larger
+// than the payload length, we do not set an error of SPDY_INVALID_PADDING
+TEST_P(SpdyFramerTest, CorrectlySizedHeadersPaddingNoError) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  // HEADERS frame with invalid Padding length
+  char kH2FrameData[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x01,                    //   Type: HEADERS
+      0x08,                    //  Flags: PADDED
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x04,                    // PadLen: 4 trailing bytes
+      0x00, 0x00, 0x00, 0x00,  // Padding
+  };
+
+  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x1, 0x8));
+  EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false));
+  EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1);
+
+  EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_FALSE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a DATA with stream ID zero, we signal an error
+// (but don't crash).
+TEST_P(SpdyFramerTest, DataWithStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  const char bytes[] = "hello";
+  SpdyDataIR data_ir(/* stream_id = */ 0, bytes);
+  SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x0, _));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a HEADERS with stream ID zero, we signal an error
+// (but don't crash).
+TEST_P(SpdyFramerTest, HeadersWithStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyHeadersIR headers(/* stream_id = */ 0);
+  headers.SetHeader("alpha", "beta");
+  SpdySerializedFrame frame(
+      SpdyFramerPeer::SerializeHeaders(&framer_, headers, &output_));
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x1, _));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a PRIORITY with stream ID zero, we signal an error
+// (but don't crash).
+TEST_P(SpdyFramerTest, PriorityWithStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyPriorityIR priority_ir(/* stream_id = */ 0,
+                             /* parent_stream_id = */ 1,
+                             /* weight = */ 16,
+                             /* exclusive = */ true);
+  SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x2, _));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a RST_STREAM with stream ID zero, we signal an error
+// (but don't crash).
+TEST_P(SpdyFramerTest, RstStreamWithStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyRstStreamIR rst_stream_ir(/* stream_id = */ 0, ERROR_CODE_PROTOCOL_ERROR);
+  SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream_ir));
+  if (use_output_) {
+    EXPECT_TRUE(framer_.SerializeRstStream(rst_stream_ir, &output_));
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x3, _));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a SETTINGS with stream ID other than zero,
+// we signal an error (but don't crash).
+TEST_P(SpdyFramerTest, SettingsWithStreamIdNotZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  // Settings frame with invalid StreamID of 0x01
+  char kH2FrameData[] = {
+      0x00, 0x00, 0x06,        // Length: 6
+      0x04,                    //   Type: SETTINGS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
+      0x0a, 0x0b, 0x0c, 0x0d,  //  Value: 168496141
+  };
+
+  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(1, 6, 0x4, 0x0));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a GOAWAY with stream ID other than zero,
+// we signal an error (but don't crash).
+TEST_P(SpdyFramerTest, GoawayWithStreamIdNotZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  // GOAWAY frame with invalid StreamID of 0x01
+  char kH2FrameData[] = {
+      0x00, 0x00, 0x0a,        // Length: 10
+      0x07,                    //   Type: GOAWAY
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  //   Last: 0
+      0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
+      0x47, 0x41,              // Description
+  };
+
+  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(1, 10, 0x7, 0x0));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a CONTINUATION with stream ID zero, we signal
+// SPDY_INVALID_STREAM_ID.
+TEST_P(SpdyFramerTest, ContinuationWithStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyContinuationIR continuation(/* stream_id = */ 0);
+  std::string some_nonsense_encoding = "some nonsense encoding";
+  continuation.take_encoding(std::move(some_nonsense_encoding));
+  continuation.set_end_headers(true);
+  SpdySerializedFrame frame(framer_.SerializeContinuation(continuation));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeContinuation(continuation, &output_));
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x9, _));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a PUSH_PROMISE with stream ID zero, we signal
+// SPDY_INVALID_STREAM_ID.
+TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyPushPromiseIR push_promise(/* stream_id = */ 0,
+                                 /* promised_stream_id = */ 4);
+  push_promise.SetHeader("alpha", "beta");
+  SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+      &framer_, push_promise, use_output_ ? &output_ : nullptr));
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x5, _));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test that if we receive a PUSH_PROMISE with promised stream ID zero, we
+// signal SPDY_INVALID_CONTROL_FRAME.
+TEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyPushPromiseIR push_promise(/* stream_id = */ 3,
+                                 /* promised_stream_id = */ 0);
+  push_promise.SetHeader("alpha", "beta");
+  SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+      &framer_, push_promise, use_output_ ? &output_ : nullptr));
+
+  EXPECT_CALL(visitor, OnCommonHeader(3, _, 0x5, _));
+  EXPECT_CALL(visitor,
+              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME, _));
+  deframer_->ProcessInput(frame.data(), frame.size());
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, MultiValueHeader) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+  std::string value("value1\0value2", 13);
+  // TODO(jgraettinger): If this pattern appears again, move to test class.
+  Http2HeaderBlock header_set;
+  header_set["name"] = value;
+  HpackEncoder encoder;
+  encoder.DisableCompression();
+  std::string buffer = encoder.EncodeHeaderBlock(header_set);
+  // Frame builder with plentiful buffer size.
+  SpdyFrameBuilder frame(1024);
+  frame.BeginNewFrame(SpdyFrameType::HEADERS,
+                      HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, 3,
+                      buffer.size() + 5 /* priority */);
+  frame.WriteUInt32(0);   // Priority exclusivity and dependent stream.
+  frame.WriteUInt8(255);  // Priority weight.
+  frame.WriteBytes(&buffer[0], buffer.size());
+
+  SpdySerializedFrame control_frame(frame.take());
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+
+  EXPECT_THAT(visitor.headers_, testing::ElementsAre(testing::Pair(
+                                    "name", absl::string_view(value))));
+}
+
+TEST_P(SpdyFramerTest, CompressEmptyHeaders) {
+  // See https://crbug.com/172383/
+  SpdyHeadersIR headers(1);
+  headers.SetHeader("server", "SpdyServer 1.0");
+  headers.SetHeader("date", "Mon 12 Jan 2009 12:12:12 PST");
+  headers.SetHeader("status", "200");
+  headers.SetHeader("version", "HTTP/1.1");
+  headers.SetHeader("content-type", "text/html");
+  headers.SetHeader("content-length", "12");
+  headers.SetHeader("x-empty-header", "");
+
+  SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+  SpdySerializedFrame frame1(
+      SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
+}
+
+TEST_P(SpdyFramerTest, Basic) {
+  // Send HEADERS frames with PRIORITY and END_HEADERS set.
+  // frame-format off
+  const unsigned char kH2Input[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x01,                    //   Type: HEADERS
+      0x24,                    //  Flags: END_HEADERS|PRIORITY
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  // Parent: 0
+      0x82,                    // Weight: 131
+
+      0x00, 0x00, 0x01,        // Length: 1
+      0x01,                    //   Type: HEADERS
+      0x04,                    //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x8c,                    // :status: 200
+
+      0x00, 0x00, 0x0c,        // Length: 12
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+      0xde, 0xad, 0xbe, 0xef,  //
+      0xde, 0xad, 0xbe, 0xef,  //
+
+      0x00, 0x00, 0x05,        // Length: 5
+      0x01,                    //   Type: HEADERS
+      0x24,                    //  Flags: END_HEADERS|PRIORITY
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x00, 0x00,  // Parent: 0
+      0x82,                    // Weight: 131
+
+      0x00, 0x00, 0x08,        // Length: 8
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+      0xde, 0xad, 0xbe, 0xef,  //
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
+
+      0x00, 0x00, 0x00,        // Length: 0
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
+  };
+  // frame-format on
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
+
+  EXPECT_EQ(24, visitor.data_bytes_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.fin_frame_count_);
+
+  EXPECT_EQ(3, visitor.headers_frame_count_);
+
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(0, visitor.end_of_stream_count_);
+  EXPECT_EQ(4, visitor.data_frame_count_);
+}
+
+// Verifies that the decoder stops delivering events after a user error.
+TEST_P(SpdyFramerTest, BasicWithError) {
+  // Send HEADERS frames with PRIORITY and END_HEADERS set.
+  // frame-format off
+  const unsigned char kH2Input[] = {
+      0x00, 0x00, 0x01,        // Length: 1
+      0x01,                    //   Type: HEADERS
+      0x04,                    //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x8c,                    // :status: 200
+
+      0x00, 0x00, 0x0c,        // Length: 12
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+      0xde, 0xad, 0xbe, 0xef,  //
+      0xde, 0xad, 0xbe, 0xef,  //
+
+      0x00, 0x00, 0x06,        // Length: 6
+      0x01,                    //   Type: HEADERS
+      0x24,                    //  Flags: END_HEADERS|PRIORITY
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x00, 0x00,  // Parent: 0
+      0x82,                    // Weight: 131
+      0x8c,                    // :status: 200
+
+      0x00, 0x00, 0x08,        // Length: 8
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+      0xde, 0xad, 0xbe, 0xef,  //
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
+
+      0x00, 0x00, 0x00,        // Length: 0
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
+  };
+  // frame-format on
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  testing::InSequence s;
+  EXPECT_CALL(visitor, OnCommonHeader(1, 1, 0x1, 0x4));
+  EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, true));
+  EXPECT_CALL(visitor, OnHeaderFrameStart(1));
+  EXPECT_CALL(visitor, OnHeaderFrameEnd(1));
+  EXPECT_CALL(visitor, OnCommonHeader(1, 12, 0x0, 0x0));
+  EXPECT_CALL(visitor, OnDataFrameHeader(1, 12, false));
+  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 12));
+  EXPECT_CALL(visitor, OnCommonHeader(3, 6, 0x1, 0x24));
+  EXPECT_CALL(visitor, OnHeaders(3, true, 131, 0, false, false, true));
+  EXPECT_CALL(visitor, OnHeaderFrameStart(3));
+  EXPECT_CALL(visitor, OnHeaderFrameEnd(3));
+  EXPECT_CALL(visitor, OnCommonHeader(3, 8, 0x0, 0x0));
+  EXPECT_CALL(visitor, OnDataFrameHeader(3, 8, false))
+      .WillOnce(testing::InvokeWithoutArgs(
+          [this]() { deframer_->StopProcessing(); }));
+  // Remaining frames are not processed due to the error.
+  EXPECT_CALL(
+      visitor,
+      OnError(http2::Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
+              "Ignoring further events on this connection."));
+
+  size_t processed = deframer_->ProcessInput(
+      reinterpret_cast<const char*>(kH2Input), sizeof(kH2Input));
+  EXPECT_LT(processed, sizeof(kH2Input));
+}
+
+// Test that the FIN flag on a data frame signifies EOF.
+TEST_P(SpdyFramerTest, FinOnDataFrame) {
+  // Send HEADERS frames with END_HEADERS set.
+  // frame-format off
+  const unsigned char kH2Input[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x01,                    //   Type: HEADERS
+      0x24,                    //  Flags: END_HEADERS|PRIORITY
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  // Parent: 0
+      0x82,                    // Weight: 131
+
+      0x00, 0x00, 0x01,        // Length: 1
+      0x01,                    //   Type: HEADERS
+      0x04,                    //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x8c,                    // :status: 200
+
+      0x00, 0x00, 0x0c,        // Length: 12
+      0x00,                    //   Type: DATA
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+      0xde, 0xad, 0xbe, 0xef,  //
+      0xde, 0xad, 0xbe, 0xef,  //
+
+      0x00, 0x00, 0x04,        // Length: 4
+      0x00,                    //   Type: DATA
+      0x01,                    //  Flags: END_STREAM
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0xde, 0xad, 0xbe, 0xef,  // Payload
+  };
+  // frame-format on
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.headers_frame_count_);
+  EXPECT_EQ(16, visitor.data_bytes_);
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.end_of_stream_count_);
+  EXPECT_EQ(2, visitor.data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, FinOnHeadersFrame) {
+  // Send HEADERS frames with END_HEADERS set.
+  // frame-format off
+  const unsigned char kH2Input[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x01,                    //   Type: HEADERS
+      0x24,                    //  Flags: END_HEADERS|PRIORITY
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  // Parent: 0
+      0x82,                    // Weight: 131
+
+      0x00, 0x00, 0x01,        // Length: 1
+      0x01,                    //   Type: HEADERS
+      0x05,                    //  Flags: END_STREAM|END_HEADERS
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x8c,                    // :status: 200
+  };
+  // frame-format on
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.data_bytes_);
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(1, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.end_of_stream_count_);
+  EXPECT_EQ(0, visitor.data_frame_count_);
+}
+
+// Verify we can decompress the stream even if handed over to the
+// framer 1 byte at a time.
+TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
+  const char kHeader1[] = "header1";
+  const char kHeader2[] = "header2";
+  const char kValue1[] = "value1";
+  const char kValue2[] = "value2";
+
+  SpdyHeadersIR headers(/* stream_id = */ 1);
+  headers.SetHeader(kHeader1, kValue1);
+  headers.SetHeader(kHeader2, kValue2);
+  SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders(
+      &framer_, headers, use_output_ ? &output_ : nullptr));
+
+  const char bytes[] = "this is a test test test test test!";
+  SpdyDataIR data_ir(/* stream_id = */ 1,
+                     absl::string_view(bytes, ABSL_ARRAYSIZE(bytes)));
+  data_ir.set_fin(true);
+  SpdySerializedFrame send_frame(framer_.SerializeData(data_ir));
+
+  // Run the inputs through the framer.
+  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+  const unsigned char* data;
+  data = reinterpret_cast<const unsigned char*>(headers_frame.data());
+  for (size_t idx = 0; idx < headers_frame.size(); ++idx) {
+    visitor.SimulateInFramer(data + idx, 1);
+    ASSERT_EQ(0, visitor.error_count_);
+  }
+  data = reinterpret_cast<const unsigned char*>(send_frame.data());
+  for (size_t idx = 0; idx < send_frame.size(); ++idx) {
+    visitor.SimulateInFramer(data + idx, 1);
+    ASSERT_EQ(0, visitor.error_count_);
+  }
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(ABSL_ARRAYSIZE(bytes), static_cast<unsigned>(visitor.data_bytes_));
+  EXPECT_EQ(0, visitor.fin_frame_count_);
+  EXPECT_EQ(0, visitor.fin_flag_count_);
+  EXPECT_EQ(1, visitor.end_of_stream_count_);
+  EXPECT_EQ(1, visitor.data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, WindowUpdateFrame) {
+  SpdyWindowUpdateIR window_update(/* stream_id = */ 1,
+                                   /* delta = */ 0x12345678);
+  SpdySerializedFrame frame(framer_.SerializeWindowUpdate(window_update));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeWindowUpdate(window_update, &output_));
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+
+  const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x04,        // Length: 4
+      0x08,                    //   Type: WINDOW_UPDATE
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x12, 0x34, 0x56, 0x78,  // Increment: 305419896
+  };
+
+  CompareFrame(kDescription, frame, kH2FrameData, ABSL_ARRAYSIZE(kH2FrameData));
+}
+
+TEST_P(SpdyFramerTest, CreateDataFrame) {
+  {
+    const char kDescription[] = "'hello' data frame, no FIN";
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x05,        // Length: 5
+        0x00,                    //   Type: DATA
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        'h',  'e',  'l',  'l',   // Payload
+        'o',                     //
+    };
+    // frame-format on
+    const char bytes[] = "hello";
+
+    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+
+    SpdyDataIR data_header_ir(/* stream_id = */ 1);
+    data_header_ir.SetDataShallow(bytes);
+    frame =
+        framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_header_ir);
+    CompareCharArraysWithHexError(
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
+        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
+  }
+
+  {
+    const char kDescription[] = "'hello' data frame with more padding, no FIN";
+    // clang-format off
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0xfd,        // Length: 253
+        0x00,                    //   Type: DATA
+        0x08,                    //  Flags: PADDED
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0xf7,                    // PadLen: 247 trailing bytes
+        'h', 'e', 'l', 'l',      // Payload
+        'o',                     //
+        // Padding of 247 0x00(s).
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    };
+    // frame-format on
+    // clang-format on
+    const char bytes[] = "hello";
+
+    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
+    // 247 zeros and the pad length field make the overall padding to be 248
+    // bytes.
+    data_ir.set_padding_len(248);
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+
+    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
+    CompareCharArraysWithHexError(
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
+        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
+  }
+
+  {
+    const char kDescription[] = "'hello' data frame with few padding, no FIN";
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x0d,        // Length: 13
+        0x00,                    //   Type: DATA
+        0x08,                    //  Flags: PADDED
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0x07,                    // PadLen: 7 trailing bytes
+        'h',  'e',  'l',  'l',   // Payload
+        'o',                     //
+        0x00, 0x00, 0x00, 0x00,  // Padding
+        0x00, 0x00, 0x00,        // Padding
+    };
+    // frame-format on
+    const char bytes[] = "hello";
+
+    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
+    // 7 zeros and the pad length field make the overall padding to be 8 bytes.
+    data_ir.set_padding_len(8);
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+
+    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
+    CompareCharArraysWithHexError(
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
+        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
+  }
+
+  {
+    const char kDescription[] =
+        "'hello' data frame with 1 byte padding, no FIN";
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x06,        // Length: 6
+        0x00,                    //   Type: DATA
+        0x08,                    //  Flags: PADDED
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0x00,                    // PadLen: 0 trailing bytes
+        'h',  'e',  'l',  'l',   // Payload
+        'o',                     //
+    };
+    // frame-format on
+    const char bytes[] = "hello";
+
+    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
+    // The pad length field itself is used for the 1-byte padding and no padding
+    // payload is needed.
+    data_ir.set_padding_len(1);
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+
+    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
+    CompareCharArraysWithHexError(
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
+        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
+  }
+
+  {
+    const char kDescription[] = "Data frame with negative data byte, no FIN";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x01,        // Length: 1
+        0x00,                    //   Type: DATA
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0xff,                    // Payload
+    };
+    SpdyDataIR data_ir(/* stream_id = */ 1, "\xff");
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "'hello' data frame, with FIN";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x05,        // Length: 5
+        0x00,                    //   Type: DATA
+        0x01,                    //  Flags: END_STREAM
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0x68, 0x65, 0x6c, 0x6c,  // Payload
+        0x6f,                    //
+    };
+    SpdyDataIR data_ir(/* stream_id = */ 1, "hello");
+    data_ir.set_fin(true);
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "Empty data frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x00,        // Length: 0
+        0x00,                    //   Type: DATA
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+    };
+    SpdyDataIR data_ir(/* stream_id = */ 1, "");
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+
+    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
+    CompareCharArraysWithHexError(
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
+        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
+  }
+
+  {
+    const char kDescription[] = "Data frame with max stream ID";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x05,        // Length: 5
+        0x00,                    //   Type: DATA
+        0x01,                    //  Flags: END_STREAM
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
+        0x68, 0x65, 0x6c, 0x6c,  // Payload
+        0x6f,                    //
+    };
+    SpdyDataIR data_ir(/* stream_id = */ 0x7fffffff, "hello");
+    data_ir.set_fin(true);
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateRstStream) {
+  {
+    const char kDescription[] = "RST_STREAM frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x04,        // Length: 4
+        0x03,                    //   Type: RST_STREAM
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0x00, 0x00, 0x00, 0x01,  //  Error: PROTOCOL_ERROR
+    };
+    SpdyRstStreamIR rst_stream(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
+    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
+    if (use_output_) {
+      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "RST_STREAM frame with max stream ID";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x04,        // Length: 4
+        0x03,                    //   Type: RST_STREAM
+        0x00,                    //  Flags: none
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
+        0x00, 0x00, 0x00, 0x01,  //  Error: PROTOCOL_ERROR
+    };
+    SpdyRstStreamIR rst_stream(/* stream_id = */ 0x7FFFFFFF,
+                               ERROR_CODE_PROTOCOL_ERROR);
+    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "RST_STREAM frame with max status code";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x04,        // Length: 4
+        0x03,                    //   Type: RST_STREAM
+        0x00,                    //  Flags: none
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
+        0x00, 0x00, 0x00, 0x02,  //  Error: INTERNAL_ERROR
+    };
+    SpdyRstStreamIR rst_stream(/* stream_id = */ 0x7FFFFFFF,
+                               ERROR_CODE_INTERNAL_ERROR);
+    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateSettings) {
+  {
+    const char kDescription[] = "Network byte order SETTINGS frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x06,        // Length: 6
+        0x04,                    //   Type: SETTINGS
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+        0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
+        0x0a, 0x0b, 0x0c, 0x0d,  //  Value: 168496141
+    };
+
+    uint32_t kValue = 0x0a0b0c0d;
+    SpdySettingsIR settings_ir;
+
+    SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE;
+    settings_ir.AddSetting(kId, kValue);
+
+    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
+    if (use_output_) {
+      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "Basic SETTINGS frame";
+    // These end up seemingly out of order because of the way that our internal
+    // ordering for settings_ir works. HTTP2 has no requirement on ordering on
+    // the wire.
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x18,        // Length: 24
+        0x04,                    //   Type: SETTINGS
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+        0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
+        0x00, 0x00, 0x00, 0x05,  //  Value: 5
+        0x00, 0x02,              //  Param: ENABLE_PUSH
+        0x00, 0x00, 0x00, 0x06,  //  Value: 6
+        0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
+        0x00, 0x00, 0x00, 0x07,  //  Value: 7
+        0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
+        0x00, 0x00, 0x00, 0x08,  //  Value: 8
+    };
+
+    SpdySettingsIR settings_ir;
+    settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
+    settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
+    settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
+    settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 8);
+    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "Empty SETTINGS frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x00,        // Length: 0
+        0x04,                    //   Type: SETTINGS
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+    };
+    SpdySettingsIR settings_ir;
+    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreatePingFrame) {
+  {
+    const char kDescription[] = "PING frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x08,        // Length: 8
+        0x06,                    //   Type: PING
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+        0x12, 0x34, 0x56, 0x78,  // Opaque
+        0x9a, 0xbc, 0xde, 0xff,  //     Data
+    };
+    const unsigned char kH2FrameDataWithAck[] = {
+        0x00, 0x00, 0x08,        // Length: 8
+        0x06,                    //   Type: PING
+        0x01,                    //  Flags: ACK
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+        0x12, 0x34, 0x56, 0x78,  // Opaque
+        0x9a, 0xbc, 0xde, 0xff,  //     Data
+    };
+    const SpdyPingId kPingId = 0x123456789abcdeffULL;
+    SpdyPingIR ping_ir(kPingId);
+    // Tests SpdyPingIR when the ping is not an ack.
+    ASSERT_FALSE(ping_ir.is_ack());
+    SpdySerializedFrame frame(framer_.SerializePing(ping_ir));
+    if (use_output_) {
+      ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+
+    // Tests SpdyPingIR when the ping is an ack.
+    ping_ir.set_is_ack(true);
+    frame = framer_.SerializePing(ping_ir);
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameDataWithAck,
+                 ABSL_ARRAYSIZE(kH2FrameDataWithAck));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateGoAway) {
+  {
+    const char kDescription[] = "GOAWAY frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x0a,        // Length: 10
+        0x07,                    //   Type: GOAWAY
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+        0x00, 0x00, 0x00, 0x00,  //   Last: 0
+        0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
+        0x47, 0x41,              // Description
+    };
+    SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 0, ERROR_CODE_NO_ERROR,
+                           "GA");
+    SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
+    if (use_output_) {
+      ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "GOAWAY frame with max stream ID, status";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x0a,        // Length: 10
+        0x07,                    //   Type: GOAWAY
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x00,  // Stream: 0
+        0x7f, 0xff, 0xff, 0xff,  //   Last: 0x7fffffff
+        0x00, 0x00, 0x00, 0x02,  //  Error: INTERNAL_ERROR
+        0x47, 0x41,              // Description
+    };
+    SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 0x7FFFFFFF,
+                           ERROR_CODE_INTERNAL_ERROR, "GA");
+    SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+
+  {
+    const char kDescription[] = "HEADERS frame, no FIN";
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x12,        // Length: 18
+        0x01,                    //   Type: HEADERS
+        0x04,                    //  Flags: END_HEADERS
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x03,              // Value Len: 3
+        0x62, 0x61, 0x72,  // bar
+    };
+    // frame-format on
+    SpdyHeadersIR headers(/* stream_id = */ 1);
+    headers.SetHeader("bar", "foo");
+    headers.SetHeader("foo", "bar");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header name, FIN, max stream ID";
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x0f,        // Length: 15
+        0x01,                    //   Type: HEADERS
+        0x05,                    //  Flags: END_STREAM|END_HEADERS
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
+
+        0x00,              // Unindexed Entry
+        0x00,              // Name Len: 0
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x03,              // Value Len: 3
+        0x62, 0x61, 0x72,  // bar
+    };
+    // frame-format on
+    SpdyHeadersIR headers(/* stream_id = */ 0x7fffffff);
+    headers.set_fin(true);
+    headers.SetHeader("", "foo");
+    headers.SetHeader("foo", "bar");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header val, FIN, max stream ID";
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x0f,        // Length: 15
+        0x01,                    //   Type: HEADERS
+        0x05,                    //  Flags: END_STREAM|END_HEADERS
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x00,              // Value Len: 0
+    };
+    // frame-format on
+    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
+    headers_ir.set_fin(true);
+    headers_ir.SetHeader("bar", "foo");
+    headers_ir.SetHeader("foo", "");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers_ir, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header val, FIN, max stream ID, pri";
+
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x14,        // Length: 20
+        0x01,                    //   Type: HEADERS
+        0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
+        0x00, 0x00, 0x00, 0x00,  // Parent: 0
+        0xdb,                    // Weight: 220
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x00,              // Value Len: 0
+    };
+    // frame-format on
+    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
+    headers_ir.set_fin(true);
+    headers_ir.set_has_priority(true);
+    headers_ir.set_weight(220);
+    headers_ir.SetHeader("bar", "foo");
+    headers_ir.SetHeader("foo", "");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers_ir, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header val, FIN, max stream ID, pri, "
+        "exclusive=true, parent_stream=0";
+
+    // frame-format off
+    const unsigned char kV4FrameData[] = {
+        0x00, 0x00, 0x14,        // Length: 20
+        0x01,                    //   Type: HEADERS
+        0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
+        0x80, 0x00, 0x00, 0x00,  // Parent: 0 (Exclusive)
+        0xdb,                    // Weight: 220
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x00,              // Value Len: 0
+    };
+    // frame-format on
+    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
+    headers_ir.set_fin(true);
+    headers_ir.set_has_priority(true);
+    headers_ir.set_weight(220);
+    headers_ir.set_exclusive(true);
+    headers_ir.set_parent_stream_id(0);
+    headers_ir.SetHeader("bar", "foo");
+    headers_ir.SetHeader("foo", "");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers_ir, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kV4FrameData,
+                 ABSL_ARRAYSIZE(kV4FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header val, FIN, max stream ID, pri, "
+        "exclusive=false, parent_stream=max stream ID";
+
+    // frame-format off
+    const unsigned char kV4FrameData[] = {
+        0x00, 0x00, 0x14,        // Length: 20
+        0x01,                    //   Type: HEADERS
+        0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
+        0x7f, 0xff, 0xff, 0xff,  // Parent: 2147483647
+        0xdb,                    // Weight: 220
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x00,              // Value Len: 0
+    };
+    // frame-format on
+    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
+    headers_ir.set_fin(true);
+    headers_ir.set_has_priority(true);
+    headers_ir.set_weight(220);
+    headers_ir.set_exclusive(false);
+    headers_ir.set_parent_stream_id(0x7fffffff);
+    headers_ir.SetHeader("bar", "foo");
+    headers_ir.SetHeader("foo", "");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers_ir, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kV4FrameData,
+                 ABSL_ARRAYSIZE(kV4FrameData));
+  }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header name, FIN, max stream ID, padded";
+
+    // frame-format off
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x15,        // Length: 21
+        0x01,                    //   Type: HEADERS
+        0x0d,                    //  Flags: END_STREAM|END_HEADERS|PADDED
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
+        0x05,                    // PadLen: 5 trailing bytes
+
+        0x00,              // Unindexed Entry
+        0x00,              // Name Len: 0
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x03,              // Value Len: 3
+        0x62, 0x61, 0x72,  // bar
+
+        0x00, 0x00, 0x00, 0x00,  // Padding
+        0x00,                    // Padding
+    };
+    // frame-format on
+    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
+    headers_ir.set_fin(true);
+    headers_ir.SetHeader("", "foo");
+    headers_ir.SetHeader("foo", "bar");
+    headers_ir.set_padding_len(6);
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers_ir, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateWindowUpdate) {
+  {
+    const char kDescription[] = "WINDOW_UPDATE frame";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x04,        // Length: 4
+        0x08,                    //   Type: WINDOW_UPDATE
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0x00, 0x00, 0x00, 0x01,  // Increment: 1
+    };
+    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
+        SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1)));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeWindowUpdate(
+          SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1), &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x04,        // Length: 4
+        0x08,                    //   Type: WINDOW_UPDATE
+        0x00,                    //  Flags: none
+        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
+        0x00, 0x00, 0x00, 0x01,  // Increment: 1
+    };
+    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
+        SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1)));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeWindowUpdate(
+          SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1),
+          &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+
+  {
+    const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
+    const unsigned char kH2FrameData[] = {
+        0x00, 0x00, 0x04,        // Length: 4
+        0x08,                    //   Type: WINDOW_UPDATE
+        0x00,                    //  Flags: none
+        0x00, 0x00, 0x00, 0x01,  // Stream: 1
+        0x7f, 0xff, 0xff, 0xff,  // Increment: 0x7fffffff
+    };
+    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
+        SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF)));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeWindowUpdate(
+          SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF),
+          &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    CompareFrame(kDescription, frame, kH2FrameData,
+                 ABSL_ARRAYSIZE(kH2FrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
+  {
+    // Test framing PUSH_PROMISE without padding.
+    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+    const char kDescription[] = "PUSH_PROMISE frame without padding";
+
+    // frame-format off
+    const unsigned char kFrameData[] = {
+        0x00, 0x00, 0x16,        // Length: 22
+        0x05,                    //   Type: PUSH_PROMISE
+        0x04,                    //  Flags: END_HEADERS
+        0x00, 0x00, 0x00, 0x29,  // Stream: 41
+        0x00, 0x00, 0x00, 0x3a,  // Promise: 58
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x03,              // Value Len: 3
+        0x62, 0x61, 0x72,  // bar
+    };
+    // frame-format on
+
+    SpdyPushPromiseIR push_promise(/* stream_id = */ 41,
+                                   /* promised_stream_id = */ 58);
+    push_promise.SetHeader("bar", "foo");
+    push_promise.SetHeader("foo", "bar");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+        &framer, push_promise, use_output_ ? &output_ : nullptr));
+    CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+  }
+
+  {
+    // Test framing PUSH_PROMISE with one byte of padding.
+    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+    const char kDescription[] = "PUSH_PROMISE frame with one byte of padding";
+
+    // frame-format off
+    const unsigned char kFrameData[] = {
+        0x00, 0x00, 0x17,        // Length: 23
+        0x05,                    //   Type: PUSH_PROMISE
+        0x0c,                    //  Flags: END_HEADERS|PADDED
+        0x00, 0x00, 0x00, 0x29,  // Stream: 41
+        0x00,                    // PadLen: 0 trailing bytes
+        0x00, 0x00, 0x00, 0x3a,  // Promise: 58
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x62, 0x61, 0x72,  // bar
+        0x03,              // Value Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+
+        0x00,              // Unindexed Entry
+        0x03,              // Name Len: 3
+        0x66, 0x6f, 0x6f,  // foo
+        0x03,              // Value Len: 3
+        0x62, 0x61, 0x72,  // bar
+    };
+    // frame-format on
+
+    SpdyPushPromiseIR push_promise(/* stream_id = */ 41,
+                                   /* promised_stream_id = */ 58);
+    push_promise.set_padding_len(1);
+    push_promise.SetHeader("bar", "foo");
+    push_promise.SetHeader("foo", "bar");
+    output_.Reset();
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+        &framer, push_promise, use_output_ ? &output_ : nullptr));
+
+    CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+  }
+
+  {
+    // Test framing PUSH_PROMISE with 177 bytes of padding.
+    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+    const char kDescription[] = "PUSH_PROMISE frame with 177 bytes of padding";
+
+    // frame-format off
+    // clang-format off
+    const unsigned char kFrameData[] = {
+        0x00, 0x00, 0xc7,        // Length: 199
+        0x05,                    //   Type: PUSH_PROMISE
+        0x0c,                    //  Flags: END_HEADERS|PADDED
+        0x00, 0x00, 0x00, 0x2a,  // Stream: 42
+        0xb0,                    // PadLen: 176 trailing bytes
+        0x00, 0x00, 0x00, 0x39,  // Promise: 57
+
+        0x00,                    // Unindexed Entry
+        0x03,                    // Name Len: 3
+        0x62, 0x61, 0x72,        // bar
+        0x03,                    // Value Len: 3
+        0x66, 0x6f, 0x6f,        // foo
+
+        0x00,                    // Unindexed Entry
+        0x03,                    // Name Len: 3
+        0x66, 0x6f, 0x6f,        // foo
+        0x03,                    // Value Len: 3
+        0x62, 0x61, 0x72,        // bar
+
+      // Padding of 176 0x00(s).
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
+    };
+    // clang-format on
+    // frame-format on
+
+    SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
+                                   /* promised_stream_id = */ 57);
+    push_promise.set_padding_len(177);
+    push_promise.SetHeader("bar", "foo");
+    push_promise.SetHeader("foo", "bar");
+    output_.Reset();
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+        &framer, push_promise, use_output_ ? &output_ : nullptr));
+
+    CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+  }
+}
+
+// Regression test for https://crbug.com/464748.
+TEST_P(SpdyFramerTest, GetNumberRequiredContinuationFrames) {
+  EXPECT_EQ(1u, GetNumberRequiredContinuationFrames(16383 + 16374));
+  EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 16374 + 1));
+  EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374));
+  EXPECT_EQ(3u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374 + 1));
+}
+
+TEST_P(SpdyFramerTest, CreateContinuationUncompressed) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+  const char kDescription[] = "CONTINUATION frame";
+
+  // frame-format off
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x12,        // Length: 18
+      0x09,                    //   Type: CONTINUATION
+      0x04,                    //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x2a,  // Stream: 42
+
+      0x00,              // Unindexed Entry
+      0x03,              // Name Len: 3
+      0x62, 0x61, 0x72,  // bar
+      0x03,              // Value Len: 3
+      0x66, 0x6f, 0x6f,  // foo
+
+      0x00,              // Unindexed Entry
+      0x03,              // Name Len: 3
+      0x66, 0x6f, 0x6f,  // foo
+      0x03,              // Value Len: 3
+      0x62, 0x61, 0x72,  // bar
+  };
+  // frame-format on
+
+  Http2HeaderBlock header_block;
+  header_block["bar"] = "foo";
+  header_block["foo"] = "bar";
+  HpackEncoder encoder;
+  encoder.DisableCompression();
+  std::string buffer = encoder.EncodeHeaderBlock(header_block);
+
+  SpdyContinuationIR continuation(/* stream_id = */ 42);
+  continuation.take_encoding(std::move(buffer));
+  continuation.set_end_headers(true);
+
+  SpdySerializedFrame frame(framer.SerializeContinuation(continuation));
+  if (use_output_) {
+    ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+// Test that if we send an unexpected CONTINUATION
+// we signal an error (but don't crash).
+TEST_P(SpdyFramerTest, SendUnexpectedContinuation) {
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  // frame-format off
+  char kH2FrameData[] = {
+      0x00, 0x00, 0x12,        // Length: 18
+      0x09,                    //   Type: CONTINUATION
+      0x04,                    //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x2a,  // Stream: 42
+
+      0x00,              // Unindexed Entry
+      0x03,              // Name Len: 3
+      0x62, 0x61, 0x72,  // bar
+      0x03,              // Value Len: 3
+      0x66, 0x6f, 0x6f,  // foo
+
+      0x00,              // Unindexed Entry
+      0x03,              // Name Len: 3
+      0x66, 0x6f, 0x6f,  // foo
+      0x03,              // Value Len: 3
+      0x62, 0x61, 0x72,  // bar
+  };
+  // frame-format on
+
+  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
+
+  // We shouldn't have to read the whole frame before we signal an error.
+  EXPECT_CALL(visitor, OnCommonHeader(42, 18, 0x9, 0x4));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME, _));
+  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
+  EXPECT_TRUE(deframer_->HasError());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
+  {
+    // Test framing in a case such that a PUSH_PROMISE frame, with one byte of
+    // padding, cannot hold all the data payload, which is overflowed to the
+    // consecutive CONTINUATION frame.
+    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+    const char kDescription[] =
+        "PUSH_PROMISE and CONTINUATION frames with one byte of padding";
+
+    // frame-format off
+    const unsigned char kPartialPushPromiseFrameData[] = {
+        0x00, 0x3f, 0xf6,        // Length: 16374
+        0x05,                    //   Type: PUSH_PROMISE
+        0x08,                    //  Flags: PADDED
+        0x00, 0x00, 0x00, 0x2a,  // Stream: 42
+        0x00,                    // PadLen: 0 trailing bytes
+        0x00, 0x00, 0x00, 0x39,  // Promise: 57
+
+        0x00,                    // Unindexed Entry
+        0x03,                    // Name Len: 3
+        0x78, 0x78, 0x78,        // xxx
+        0x7f, 0x80, 0x7f,        // Value Len: 16361
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+    };
+    const unsigned char kContinuationFrameData[] = {
+        0x00, 0x00, 0x16,        // Length: 22
+        0x09,                    //   Type: CONTINUATION
+        0x04,                    //  Flags: END_HEADERS
+        0x00, 0x00, 0x00, 0x2a,  // Stream: 42
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78,                    // x
+    };
+    // frame-format on
+
+    SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
+                                   /* promised_stream_id = */ 57);
+    push_promise.set_padding_len(1);
+    std::string big_value(kHttp2MaxControlFrameSendSize, 'x');
+    push_promise.SetHeader("xxx", big_value);
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+        &framer, push_promise, use_output_ ? &output_ : nullptr));
+
+    // The entire frame should look like below:
+    // Name                     Length in Byte
+    // ------------------------------------------- Begin of PUSH_PROMISE frame
+    // PUSH_PROMISE header      9
+    // Pad length field         1
+    // Promised stream          4
+    // Length field of key      2
+    // Content of key           3
+    // Length field of value    3
+    // Part of big_value        16361
+    // ------------------------------------------- Begin of CONTINUATION frame
+    // CONTINUATION header      9
+    // Remaining of big_value   22
+    // ------------------------------------------- End
+
+    // Length of everything listed above except big_value.
+    int len_non_data_payload = 31;
+    EXPECT_EQ(kHttp2MaxControlFrameSendSize + len_non_data_payload,
+              frame.size());
+
+    // Partially compare the PUSH_PROMISE frame against the template.
+    const unsigned char* frame_data =
+        reinterpret_cast<const unsigned char*>(frame.data());
+    CompareCharArraysWithHexError(kDescription, frame_data,
+                                  ABSL_ARRAYSIZE(kPartialPushPromiseFrameData),
+                                  kPartialPushPromiseFrameData,
+                                  ABSL_ARRAYSIZE(kPartialPushPromiseFrameData));
+
+    // Compare the CONTINUATION frame against the template.
+    frame_data += kHttp2MaxControlFrameSendSize;
+    CompareCharArraysWithHexError(
+        kDescription, frame_data, ABSL_ARRAYSIZE(kContinuationFrameData),
+        kContinuationFrameData, ABSL_ARRAYSIZE(kContinuationFrameData));
+  }
+}
+
+TEST_P(SpdyFramerTest, CreateAltSvc) {
+  const char kDescription[] = "ALTSVC frame";
+  const unsigned char kType = SerializeFrameType(SpdyFrameType::ALTSVC);
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x49, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o',
+      'r',  'i',  'g',  'i',   'n',  'p',  'i',  'd',  '1',  '=',  '"',  'h',
+      'o',  's',  't',  ':',   '4',  '4',  '3',  '"',  ';',  ' ',  'm',  'a',
+      '=',  '5',  ',',  'p',   '%',  '2',  '2',  '%',  '3',  'D',  'i',  '%',
+      '3',  'A',  'd',  '=',   '"',  'h',  '_',  '\\', '\\', 'o',  '\\', '"',
+      's',  't',  ':',  '1',   '2',  '3',  '"',  ';',  ' ',  'm',  'a',  '=',
+      '4',  '2',  ';',  ' ',   'v',  '=',  '"',  '2',  '4',  '"'};
+  SpdyAltSvcIR altsvc_ir(/* stream_id = */ 3);
+  altsvc_ir.set_origin("origin");
+  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
+  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+      "p\"=i:d", "h_\\o\"st", 123, 42,
+      SpdyAltSvcWireFormat::VersionVector{24}));
+  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+TEST_P(SpdyFramerTest, CreatePriority) {
+  const char kDescription[] = "PRIORITY frame";
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x05,        // Length: 5
+      0x02,                    //   Type: PRIORITY
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x02,  // Stream: 2
+      0x80, 0x00, 0x00, 0x01,  // Parent: 1 (Exclusive)
+      0x10,                    // Weight: 17
+  };
+  SpdyPriorityIR priority_ir(/* stream_id = */ 2,
+                             /* parent_stream_id = */ 1,
+                             /* weight = */ 17,
+                             /* exclusive = */ true);
+  SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+TEST_P(SpdyFramerTest, CreatePriorityUpdate) {
+  const char kDescription[] = "PRIORITY_UPDATE frame";
+  const unsigned char kType =
+      SerializeFrameType(SpdyFrameType::PRIORITY_UPDATE);
+  const unsigned char kFrameData[] = {
+      0x00,  0x00, 0x07,        // frame length
+      kType,                    // frame type
+      0x00,                     // flags
+      0x00,  0x00, 0x00, 0x00,  // stream ID, must be 0 for PRIORITY_UPDATE
+      0x00,  0x00, 0x00, 0x03,  // prioritized stream ID
+      'u',   '=',  '0'};        // priority field value
+  SpdyPriorityUpdateIR priority_update_ir(/* stream_id = */ 0,
+                                          /* prioritized_stream_id = */ 3,
+                                          /* priority_field_value = */ "u=0");
+  SpdySerializedFrame frame(framer_.SerializeFrame(priority_update_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(priority_update_ir, &output_),
+              frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+TEST_P(SpdyFramerTest, CreateAcceptCh) {
+  const char kDescription[] = "ACCEPT_CH frame";
+  const unsigned char kType = SerializeFrameType(SpdyFrameType::ACCEPT_CH);
+  const unsigned char kFrameData[] = {
+      0x00,  0x00, 0x2d,                  // frame length
+      kType,                              // frame type
+      0x00,                               // flags
+      0x00,  0x00, 0x00, 0x00,            // stream ID, must be 0 for ACCEPT_CH
+      0x00,  0x0f,                        // origin length
+      'w',   'w',  'w',  '.',  'e', 'x',  // origin
+      'a',   'm',  'p',  'l',  'e', '.',  //
+      'c',   'o',  'm',                   //
+      0x00,  0x03,                        // value length
+      'f',   'o',  'o',                   // value
+      0x00,  0x10,                        // origin length
+      'm',   'a',  'i',  'l',  '.', 'e',  //
+      'x',   'a',  'm',  'p',  'l', 'e',  //
+      '.',   'c',  'o',  'm',             //
+      0x00,  0x03,                        // value length
+      'b',   'a',  'r'};                  // value
+  SpdyAcceptChIR accept_ch_ir(
+      {{"www.example.com", "foo"}, {"mail.example.com", "bar"}});
+  SpdySerializedFrame frame(framer_.SerializeFrame(accept_ch_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(accept_ch_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+TEST_P(SpdyFramerTest, CreateUnknown) {
+  const char kDescription[] = "Unknown frame";
+  const uint8_t kType = 0xaf;
+  const uint8_t kFlags = 0x11;
+  const uint8_t kLength = strlen(kDescription);
+  const unsigned char kFrameData[] = {
+      0x00,   0x00, kLength,        // Length: 13
+      kType,                        //   Type: undefined
+      kFlags,                       //  Flags: arbitrary, undefined
+      0x00,   0x00, 0x00,    0x02,  // Stream: 2
+      0x55,   0x6e, 0x6b,    0x6e,  // "Unkn"
+      0x6f,   0x77, 0x6e,    0x20,  // "own "
+      0x66,   0x72, 0x61,    0x6d,  // "fram"
+      0x65,                         // "e"
+  };
+  SpdyUnknownIR unknown_ir(/* stream_id = */ 2,
+                           /* type = */ kType,
+                           /* flags = */ kFlags,
+                           /* payload = */ kDescription);
+  SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+// Test serialization of a SpdyUnknownIR with a defined type, a length field
+// that does not match the payload size and in fact exceeds framer limits, and a
+// stream ID that effectively flips the reserved bit.
+TEST_P(SpdyFramerTest, CreateUnknownUnchecked) {
+  const char kDescription[] = "Unknown frame";
+  const uint8_t kType = 0x00;
+  const uint8_t kFlags = 0x11;
+  const uint8_t kLength = std::numeric_limits<uint8_t>::max();
+  const unsigned int kStreamId = kStreamIdMask + 42;
+  const unsigned char kFrameData[] = {
+      0x00,   0x00, kLength,        // Length: 16426
+      kType,                        //   Type: DATA, defined
+      kFlags,                       //  Flags: arbitrary, undefined
+      0x80,   0x00, 0x00,    0x29,  // Stream: 2147483689
+      0x55,   0x6e, 0x6b,    0x6e,  // "Unkn"
+      0x6f,   0x77, 0x6e,    0x20,  // "own "
+      0x66,   0x72, 0x61,    0x6d,  // "fram"
+      0x65,                         // "e"
+  };
+  TestSpdyUnknownIR unknown_ir(/* stream_id = */ kStreamId,
+                               /* type = */ kType,
+                               /* flags = */ kFlags,
+                               /* payload = */ kDescription);
+  unknown_ir.set_length(kLength);
+  SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
+  if (use_output_) {
+    EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
+  SpdyHeadersIR headers_ir(/* stream_id = */ 1);
+  headers_ir.SetHeader("alpha", "beta");
+  headers_ir.SetHeader("gamma", "delta");
+  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
+      &framer_, headers_ir, use_output_ ? &output_ : nullptr));
+  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.end_of_stream_count_);
+  EXPECT_EQ(headers_ir.header_block(), visitor.headers_);
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
+  SpdyHeadersIR headers_ir(/* stream_id = */ 1);
+  headers_ir.set_fin(true);
+  headers_ir.SetHeader("alpha", "beta");
+  headers_ir.SetHeader("gamma", "delta");
+  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
+      &framer_, headers_ir, use_output_ ? &output_ : nullptr));
+  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(1, visitor.end_of_stream_count_);
+  EXPECT_EQ(headers_ir.header_block(), visitor.headers_);
+}
+
+TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+  SpdyHeadersIR headers(/* stream_id = */ 1);
+  headers.set_padding_len(256);
+
+  // Exact payload length will change with HPACK, but this should be long
+  // enough to cause an overflow.
+  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
+  std::string big_value(kBigValueSize, 'x');
+  headers.SetHeader("aa", big_value);
+  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
+      &framer, headers, use_output_ ? &output_ : nullptr));
+  EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(1, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+}
+
+TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+  auto headers = std::make_unique<SpdyHeadersIR>(/* stream_id = */ 1);
+  headers->set_padding_len(256);
+
+  // Exact payload length will change with HPACK, but this should be long
+  // enough to cause an overflow.
+  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
+  std::string big_valuex(kBigValueSize, 'x');
+  headers->SetHeader("aa", big_valuex);
+  std::string big_valuez(kBigValueSize, 'z');
+  headers->SetHeader("bb", big_valuez);
+
+  SpdyFramer::SpdyHeaderFrameIterator frame_it(&framer, std::move(headers));
+
+  EXPECT_TRUE(frame_it.HasNextFrame());
+  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
+  SpdySerializedFrame headers_frame(output_.Begin(), output_.Size(), false);
+  EXPECT_EQ(headers_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(headers_frame.data()),
+      headers_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  output_.Reset();
+  EXPECT_TRUE(frame_it.HasNextFrame());
+  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
+  SpdySerializedFrame first_cont_frame(output_.Begin(), output_.Size(), false);
+  EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(first_cont_frame.data()),
+      first_cont_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(1, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  output_.Reset();
+  EXPECT_TRUE(frame_it.HasNextFrame());
+  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
+  SpdySerializedFrame second_cont_frame(output_.Begin(), output_.Size(), false);
+  EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(second_cont_frame.data()),
+      second_cont_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(2, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  EXPECT_FALSE(frame_it.HasNextFrame());
+}
+
+TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+  auto push_promise =
+      std::make_unique<SpdyPushPromiseIR>(/* stream_id = */ 1,
+                                          /* promised_stream_id = */ 2);
+  push_promise->set_padding_len(256);
+
+  // Exact payload length will change with HPACK, but this should be long
+  // enough to cause an overflow.
+  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
+  std::string big_valuex(kBigValueSize, 'x');
+  push_promise->SetHeader("aa", big_valuex);
+  std::string big_valuez(kBigValueSize, 'z');
+  push_promise->SetHeader("bb", big_valuez);
+
+  SpdyFramer::SpdyPushPromiseFrameIterator frame_it(&framer,
+                                                    std::move(push_promise));
+
+  EXPECT_TRUE(frame_it.HasNextFrame());
+  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
+  SpdySerializedFrame push_promise_frame(output_.Begin(), output_.Size(),
+                                         false);
+  EXPECT_EQ(push_promise_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(push_promise_frame.data()),
+      push_promise_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.push_promise_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  EXPECT_TRUE(frame_it.HasNextFrame());
+  output_.Reset();
+  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
+  SpdySerializedFrame first_cont_frame(output_.Begin(), output_.Size(), false);
+
+  EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(first_cont_frame.data()),
+      first_cont_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.push_promise_frame_count_);
+  EXPECT_EQ(1, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  EXPECT_TRUE(frame_it.HasNextFrame());
+  output_.Reset();
+  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
+  SpdySerializedFrame second_cont_frame(output_.Begin(), output_.Size(), false);
+  EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(second_cont_frame.data()),
+      second_cont_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.push_promise_frame_count_);
+  EXPECT_EQ(2, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+
+  EXPECT_FALSE(frame_it.HasNextFrame());
+}
+
+class SpdyControlFrameIteratorTest : public quiche::test::QuicheTest {
+ public:
+  SpdyControlFrameIteratorTest() : output_(output_buffer, kSize) {}
+
+  void RunTest(std::unique_ptr<SpdyFrameIR> ir) {
+    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+    SpdySerializedFrame frame(framer.SerializeFrame(*ir));
+    std::unique_ptr<SpdyFrameSequence> it =
+        SpdyFramer::CreateIterator(&framer, std::move(ir));
+    EXPECT_TRUE(it->HasNextFrame());
+    EXPECT_EQ(it->NextFrame(&output_), frame.size());
+    EXPECT_FALSE(it->HasNextFrame());
+  }
+
+ private:
+  ArrayOutputBuffer output_;
+};
+
+TEST_F(SpdyControlFrameIteratorTest, RstStreamFrameWithIterator) {
+  auto ir = std::make_unique<SpdyRstStreamIR>(0, ERROR_CODE_PROTOCOL_ERROR);
+  RunTest(std::move(ir));
+}
+
+TEST_F(SpdyControlFrameIteratorTest, SettingsFrameWithIterator) {
+  auto ir = std::make_unique<SpdySettingsIR>();
+  uint32_t kValue = 0x0a0b0c0d;
+  SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE;
+  ir->AddSetting(kId, kValue);
+  RunTest(std::move(ir));
+}
+
+TEST_F(SpdyControlFrameIteratorTest, PingFrameWithIterator) {
+  const SpdyPingId kPingId = 0x123456789abcdeffULL;
+  auto ir = std::make_unique<SpdyPingIR>(kPingId);
+  RunTest(std::move(ir));
+}
+
+TEST_F(SpdyControlFrameIteratorTest, GoAwayFrameWithIterator) {
+  auto ir = std::make_unique<SpdyGoAwayIR>(0, ERROR_CODE_NO_ERROR, "GA");
+  RunTest(std::move(ir));
+}
+
+TEST_F(SpdyControlFrameIteratorTest, WindowUpdateFrameWithIterator) {
+  auto ir = std::make_unique<SpdyWindowUpdateIR>(1, 1);
+  RunTest(std::move(ir));
+}
+
+TEST_F(SpdyControlFrameIteratorTest, AtlSvcFrameWithIterator) {
+  auto ir = std::make_unique<SpdyAltSvcIR>(3);
+  ir->set_origin("origin");
+  ir->add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
+  ir->add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+      "p\"=i:d", "h_\\o\"st", 123, 42,
+      SpdyAltSvcWireFormat::VersionVector{24}));
+  RunTest(std::move(ir));
+}
+
+TEST_F(SpdyControlFrameIteratorTest, PriorityFrameWithIterator) {
+  auto ir = std::make_unique<SpdyPriorityIR>(2, 1, 17, true);
+  RunTest(std::move(ir));
+}
+
+TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+  SpdyPushPromiseIR push_promise(/* stream_id = */ 1,
+                                 /* promised_stream_id = */ 2);
+  push_promise.set_padding_len(256);
+
+  // Exact payload length will change with HPACK, but this should be long
+  // enough to cause an overflow.
+  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
+  std::string big_value(kBigValueSize, 'x');
+  push_promise.SetHeader("aa", big_value);
+  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializePushPromise(
+      &framer, push_promise, use_output_ ? &output_ : nullptr));
+  EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_TRUE(visitor.header_buffer_valid_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.push_promise_frame_count_);
+  EXPECT_EQ(1, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+}
+
+// Check that the framer stops delivering header data chunks once the visitor
+// declares it doesn't want any more. This is important to guard against
+// "zip bomb" types of attacks.
+TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
+  const size_t kHeaderBufferChunks = 4;
+  const size_t kHeaderBufferSize =
+      kHttp2DefaultFramePayloadLimit / kHeaderBufferChunks;
+  const size_t kBigValueSize = kHeaderBufferSize * 2;
+  std::string big_value(kBigValueSize, 'x');
+  SpdyHeadersIR headers(/* stream_id = */ 1);
+  headers.set_fin(true);
+  headers.SetHeader("aa", big_value);
+  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
+      &framer_, headers, use_output_ ? &output_ : nullptr));
+  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+  visitor.set_header_buffer_size(kHeaderBufferSize);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  // It's up to the visitor to ignore extraneous header data; the framer
+  // won't throw an error.
+  EXPECT_GT(visitor.header_bytes_received_, visitor.header_buffer_size_);
+  EXPECT_EQ(1, visitor.end_of_stream_count_);
+}
+
+TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
+  // Create a GoAway frame that has a few extra bytes at the end.
+  const size_t length = 20;
+
+  // HTTP/2 GOAWAY frames are only bound by a minimal length, since they may
+  // carry opaque data. Verify that minimal length is tested.
+  ASSERT_GT(kGoawayFrameMinimumSize, kFrameHeaderSize);
+  const size_t less_than_min_length =
+      kGoawayFrameMinimumSize - kFrameHeaderSize - 1;
+  ASSERT_LE(less_than_min_length, std::numeric_limits<unsigned char>::max());
+  const unsigned char kH2Len = static_cast<unsigned char>(less_than_min_length);
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, kH2Len,        // Length: min length - 1
+      0x07,                      //   Type: GOAWAY
+      0x00,                      //  Flags: none
+      0x00, 0x00, 0x00,   0x00,  // Stream: 0
+      0x00, 0x00, 0x00,   0x00,  //   Last: 0
+      0x00, 0x00, 0x00,          // Truncated Status Field
+  };
+  const size_t pad_length = length + kFrameHeaderSize - sizeof(kH2FrameData);
+  std::string pad(pad_length, 'A');
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+
+  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
+  visitor.SimulateInFramer(reinterpret_cast<const unsigned char*>(pad.c_str()),
+                           pad.length());
+
+  EXPECT_EQ(1, visitor.error_count_);  // This generated an error.
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(0, visitor.goaway_count_);  // Frame not parsed.
+}
+
+TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
+  SpdySettingsIR settings_ir;
+  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  SetFrameLength(&control_frame, 0);
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()), kFrameHeaderSize);
+  // Zero-len settings frames are permitted as of HTTP/2.
+  EXPECT_EQ(0, visitor.error_count_);
+}
+
+// Tests handling of SETTINGS frames with invalid length.
+TEST_P(SpdyFramerTest, ReadBogusLenSettingsFrame) {
+  SpdySettingsIR settings_ir;
+
+  // Add settings to more than fill the frame so that we don't get a buffer
+  // overflow when calling SimulateInFramer() below. These settings must be
+  // distinct parameters because SpdySettingsIR has a map for settings, and
+  // will collapse multiple copies of the same parameter.
+  settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 0x00000002);
+  settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 0x00000002);
+  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  const size_t kNewLength = 8;
+  SetFrameLength(&control_frame, kNewLength);
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      kFrameHeaderSize + kNewLength);
+  // Should generate an error, since its not possible to have a
+  // settings frame of length kNewLength.
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+}
+
+// Tests handling of larger SETTINGS frames.
+TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
+  SpdySettingsIR settings_ir;
+  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
+  settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
+  settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
+
+  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+
+  // Read all at once.
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(3, visitor.setting_count_);
+  EXPECT_EQ(1, visitor.settings_ack_sent_);
+
+  // Read data in small chunks.
+  size_t framed_data = 0;
+  size_t unframed_data = control_frame.size();
+  size_t kReadChunkSize = 5;  // Read five bytes at a time.
+  while (unframed_data > 0) {
+    size_t to_read = std::min(kReadChunkSize, unframed_data);
+    visitor.SimulateInFramer(
+        reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
+        to_read);
+    unframed_data -= to_read;
+    framed_data += to_read;
+  }
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(3 * 2, visitor.setting_count_);
+  EXPECT_EQ(2, visitor.settings_ack_sent_);
+}
+
+// Tests handling of SETTINGS frame with duplicate entries.
+TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x12,        // Length: 18
+      0x04,                    //   Type: SETTINGS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
+      0x00, 0x00, 0x00, 0x02,  //  Value: 2
+      0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
+      0x00, 0x00, 0x00, 0x03,  //  Value: 3
+      0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
+      0x00, 0x00, 0x00, 0x03,  //  Value: 3
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
+
+  // In HTTP/2, duplicate settings are allowed;
+  // each setting replaces the previous value for that setting.
+  EXPECT_EQ(3, visitor.setting_count_);
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.settings_ack_sent_);
+}
+
+// Tests handling of SETTINGS frame with a setting we don't recognize.
+TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x06,        // Length: 6
+      0x04,                    //   Type: SETTINGS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0x00, 0x10,              //  Param: 16
+      0x00, 0x00, 0x00, 0x02,  //  Value: 2
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
+
+  // In HTTP/2, we ignore unknown settings because of extensions. However, we
+  // pass the SETTINGS to the visitor, which can decide how to handle them.
+  EXPECT_EQ(1, visitor.setting_count_);
+  EXPECT_EQ(0, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadKnownAndUnknownSettingsWithExtension) {
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x18,        // Length: 24
+      0x04,                    //   Type: SETTINGS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0x00, 0x10,              //  Param: 16
+      0x00, 0x00, 0x00, 0x02,  //  Value: 2
+      0x00, 0x5f,              //  Param: 95
+      0x00, 0x01, 0x00, 0x02,  //  Value: 65538
+      0x00, 0x02,              //  Param: ENABLE_PUSH
+      0x00, 0x00, 0x00, 0x01,  //  Value: 1
+      0x00, 0x08,              //  Param: ENABLE_CONNECT_PROTOCOL
+      0x00, 0x00, 0x00, 0x01,  //  Value: 1
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  TestExtension extension;
+  visitor.set_extension_visitor(&extension);
+  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
+
+  // In HTTP/2, we ignore unknown settings because of extensions. However, we
+  // pass the SETTINGS to the visitor, which can decide how to handle them.
+  EXPECT_EQ(4, visitor.setting_count_);
+  EXPECT_EQ(0, visitor.error_count_);
+
+  // The extension receives only the non-standard SETTINGS.
+  EXPECT_THAT(
+      extension.settings_received_,
+      testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538)));
+}
+
+// Tests handling of SETTINGS frame with entries out of order.
+TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x12,        // Length: 18
+      0x04,                    //   Type: SETTINGS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0x00, 0x02,              //  Param: ENABLE_PUSH
+      0x00, 0x00, 0x00, 0x02,  //  Value: 2
+      0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
+      0x00, 0x00, 0x00, 0x03,  //  Value: 3
+      0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
+      0x00, 0x00, 0x00, 0x03,  //  Value: 3
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
+
+  // In HTTP/2, settings are allowed in any order.
+  EXPECT_EQ(3, visitor.setting_count_);
+  EXPECT_EQ(0, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ProcessSettingsAckFrame) {
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x00,        // Length: 0
+      0x04,                    //   Type: SETTINGS
+      0x01,                    //  Flags: ACK
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(0, visitor.setting_count_);
+  EXPECT_EQ(1, visitor.settings_ack_received_);
+}
+
+TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
+  const int kPaddingLen = 119;
+  const char data_payload[] = "hello";
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  SpdyDataIR data_ir(/* stream_id = */ 1, data_payload);
+  data_ir.set_padding_len(kPaddingLen);
+  SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+
+  int bytes_consumed = 0;
+
+  // Send the frame header.
+  EXPECT_CALL(visitor,
+              OnCommonHeader(1, kPaddingLen + strlen(data_payload), 0x0, 0x8));
+  EXPECT_CALL(visitor,
+              OnDataFrameHeader(1, kPaddingLen + strlen(data_payload), false));
+  QUICHE_CHECK_EQ(kDataFrameMinimumSize,
+                  deframer_->ProcessInput(frame.data(), kDataFrameMinimumSize));
+  QUICHE_CHECK_EQ(deframer_->state(),
+                  Http2DecoderAdapter::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
+  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
+                  Http2DecoderAdapter::SPDY_NO_ERROR);
+  bytes_consumed += kDataFrameMinimumSize;
+
+  // Send the padding length field.
+  EXPECT_CALL(visitor, OnStreamPadLength(1, kPaddingLen - 1));
+  QUICHE_CHECK_EQ(1u,
+                  deframer_->ProcessInput(frame.data() + bytes_consumed, 1));
+  QUICHE_CHECK_EQ(deframer_->state(),
+                  Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
+  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
+                  Http2DecoderAdapter::SPDY_NO_ERROR);
+  bytes_consumed += 1;
+
+  // Send the first two bytes of the data payload, i.e., "he".
+  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2));
+  QUICHE_CHECK_EQ(2u,
+                  deframer_->ProcessInput(frame.data() + bytes_consumed, 2));
+  QUICHE_CHECK_EQ(deframer_->state(),
+                  Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
+  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
+                  Http2DecoderAdapter::SPDY_NO_ERROR);
+  bytes_consumed += 2;
+
+  // Send the rest three bytes of the data payload, i.e., "llo".
+  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3));
+  QUICHE_CHECK_EQ(3u,
+                  deframer_->ProcessInput(frame.data() + bytes_consumed, 3));
+  QUICHE_CHECK_EQ(deframer_->state(),
+                  Http2DecoderAdapter::SPDY_CONSUME_PADDING);
+  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
+                  Http2DecoderAdapter::SPDY_NO_ERROR);
+  bytes_consumed += 3;
+
+  // Send the first 100 bytes of the padding payload.
+  EXPECT_CALL(visitor, OnStreamPadding(1, 100));
+  QUICHE_CHECK_EQ(100u,
+                  deframer_->ProcessInput(frame.data() + bytes_consumed, 100));
+  QUICHE_CHECK_EQ(deframer_->state(),
+                  Http2DecoderAdapter::SPDY_CONSUME_PADDING);
+  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
+                  Http2DecoderAdapter::SPDY_NO_ERROR);
+  bytes_consumed += 100;
+
+  // Send rest of the padding payload.
+  EXPECT_CALL(visitor, OnStreamPadding(1, 18));
+  QUICHE_CHECK_EQ(18u,
+                  deframer_->ProcessInput(frame.data() + bytes_consumed, 18));
+  QUICHE_CHECK_EQ(deframer_->state(),
+                  Http2DecoderAdapter::SPDY_READY_FOR_FRAME);
+  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
+                  Http2DecoderAdapter::SPDY_NO_ERROR);
+}
+
+TEST_P(SpdyFramerTest, ReadWindowUpdate) {
+  SpdySerializedFrame control_frame(framer_.SerializeWindowUpdate(
+      SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2)));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeWindowUpdate(
+        SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2), &output_));
+    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_EQ(1u, visitor.last_window_update_stream_);
+  EXPECT_EQ(2, visitor.last_window_update_delta_);
+}
+
+TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
+  SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
+                                 /* promised_stream_id = */ 57);
+  push_promise.SetHeader("foo", "bar");
+  push_promise.SetHeader("bar", "foofoo");
+  SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+      &framer_, push_promise, use_output_ ? &output_ : nullptr));
+  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size());
+  EXPECT_EQ(42u, visitor.last_push_promise_stream_);
+  EXPECT_EQ(57u, visitor.last_push_promise_promised_stream_);
+  EXPECT_EQ(push_promise.header_block(), visitor.headers_);
+}
+
+TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
+  // frame-format off
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x14,                       // Length: 20
+      0x01,                                   //   Type: HEADERS
+      0x08,                                   //  Flags: PADDED
+      0x00, 0x00, 0x00, 0x01,                 // Stream: 1
+      0x03,                                   // PadLen: 3 trailing bytes
+      0x00,                                   // Unindexed Entry
+      0x06,                                   // Name Len: 6
+      'c',  'o',  'o',  'k',  'i', 'e',       // Name
+      0x07,                                   // Value Len: 7
+      'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
+      0x00, 0x00, 0x00,                       // Padding
+
+      0x00, 0x00, 0x14,                            // Length: 20
+      0x09,                                        //   Type: CONTINUATION
+      0x00,                                        //  Flags: none
+      0x00, 0x00, 0x00, 0x01,                      // Stream: 1
+      0x00,                                        // Unindexed Entry
+      0x06,                                        // Name Len: 6
+      'c',  'o',  'o',  'k',  'i', 'e',            // Name
+      0x08,                                        // Value Len: 7
+      'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
+      0x00,                                        // Unindexed Entry
+      0x06,                                        // Name Len: 6
+      'c',                                         // Name (split)
+
+      0x00, 0x00, 0x12,             // Length: 18
+      0x09,                         //   Type: CONTINUATION
+      0x04,                         //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x01,       // Stream: 1
+      'o',  'o',  'k',  'i',  'e',  // Name (continued)
+      0x00,                         // Value Len: 0
+      0x00,                         // Unindexed Entry
+      0x04,                         // Name Len: 4
+      'n',  'a',  'm',  'e',        // Name
+      0x05,                         // Value Len: 5
+      'v',  'a',  'l',  'u',  'e',  // Value
+  };
+  // frame-format on
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(2, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.end_of_stream_count_);
+
+  EXPECT_THAT(
+      visitor.headers_,
+      testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
+                           testing::Pair("name", "value")));
+}
+
+TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) {
+  // frame-format off
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x10,                       // Length: 20
+      0x01,                                   //   Type: HEADERS
+      0x01,                                   //  Flags: END_STREAM
+      0x00, 0x00, 0x00, 0x01,                 // Stream: 1
+      0x00,                                   // Unindexed Entry
+      0x06,                                   // Name Len: 6
+      'c',  'o',  'o',  'k',  'i', 'e',       // Name
+      0x07,                                   // Value Len: 7
+      'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
+
+      0x00, 0x00, 0x14,                            // Length: 20
+      0x09,                                        //   Type: CONTINUATION
+      0x00,                                        //  Flags: none
+      0x00, 0x00, 0x00, 0x01,                      // Stream: 1
+      0x00,                                        // Unindexed Entry
+      0x06,                                        // Name Len: 6
+      'c',  'o',  'o',  'k',  'i', 'e',            // Name
+      0x08,                                        // Value Len: 7
+      'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
+      0x00,                                        // Unindexed Entry
+      0x06,                                        // Name Len: 6
+      'c',                                         // Name (split)
+
+      0x00, 0x00, 0x12,             // Length: 18
+      0x09,                         //   Type: CONTINUATION
+      0x04,                         //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x01,       // Stream: 1
+      'o',  'o',  'k',  'i',  'e',  // Name (continued)
+      0x00,                         // Value Len: 0
+      0x00,                         // Unindexed Entry
+      0x04,                         // Name Len: 4
+      'n',  'a',  'm',  'e',        // Name
+      0x05,                         // Value Len: 5
+      'v',  'a',  'l',  'u',  'e',  // Value
+  };
+  // frame-format on
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(2, visitor.continuation_count_);
+  EXPECT_EQ(1, visitor.fin_flag_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(1, visitor.end_of_stream_count_);
+
+  EXPECT_THAT(
+      visitor.headers_,
+      testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
+                           testing::Pair("name", "value")));
+}
+
+TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) {
+  // frame-format off
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x17,                       // Length: 23
+      0x05,                                   //   Type: PUSH_PROMISE
+      0x08,                                   //  Flags: PADDED
+      0x00, 0x00, 0x00, 0x01,                 // Stream: 1
+      0x02,                                   // PadLen: 2 trailing bytes
+      0x00, 0x00, 0x00, 0x2a,                 // Promise: 42
+      0x00,                                   // Unindexed Entry
+      0x06,                                   // Name Len: 6
+      'c',  'o',  'o',  'k',  'i', 'e',       // Name
+      0x07,                                   // Value Len: 7
+      'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
+      0x00, 0x00,                             // Padding
+
+      0x00, 0x00, 0x14,                            // Length: 20
+      0x09,                                        //   Type: CONTINUATION
+      0x00,                                        //  Flags: none
+      0x00, 0x00, 0x00, 0x01,                      // Stream: 1
+      0x00,                                        // Unindexed Entry
+      0x06,                                        // Name Len: 6
+      'c',  'o',  'o',  'k',  'i', 'e',            // Name
+      0x08,                                        // Value Len: 7
+      'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
+      0x00,                                        // Unindexed Entry
+      0x06,                                        // Name Len: 6
+      'c',                                         // Name (split)
+
+      0x00, 0x00, 0x12,             // Length: 18
+      0x09,                         //   Type: CONTINUATION
+      0x04,                         //  Flags: END_HEADERS
+      0x00, 0x00, 0x00, 0x01,       // Stream: 1
+      'o',  'o',  'k',  'i',  'e',  // Name (continued)
+      0x00,                         // Value Len: 0
+      0x00,                         // Unindexed Entry
+      0x04,                         // Name Len: 4
+      'n',  'a',  'm',  'e',        // Name
+      0x05,                         // Value Len: 5
+      'v',  'a',  'l',  'u',  'e',  // Value
+  };
+  // frame-format on
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1u, visitor.last_push_promise_stream_);
+  EXPECT_EQ(42u, visitor.last_push_promise_promised_stream_);
+  EXPECT_EQ(2, visitor.continuation_count_);
+  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
+  EXPECT_EQ(0, visitor.end_of_stream_count_);
+
+  EXPECT_THAT(
+      visitor.headers_,
+      testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
+                           testing::Pair("name", "value")));
+}
+
+// Receiving an unknown frame when a continuation is expected should
+// result in a SPDY_UNEXPECTED_FRAME error
+TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuation) {
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x10,        // Length: 16
+      0x01,                    //   Type: HEADERS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+
+      0x00, 0x00, 0x14,        // Length: 20
+      0xa9,                    //   Type: UnknownFrameType(169)
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // Payload
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x08, 0x62, 0x61, 0x7a,  //
+      0x3d, 0x62, 0x69, 0x6e,  //
+      0x67, 0x00, 0x06, 0x63,  //
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  // Assume the unknown frame is allowed
+  visitor.on_unknown_frame_result_ = true;
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+}
+
+// Receiving an unknown frame when a continuation is expected should
+// result in a SPDY_UNEXPECTED_FRAME error
+TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuationWithExtension) {
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x10,        // Length: 16
+      0x01,                    //   Type: HEADERS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+
+      0x00, 0x00, 0x14,        // Length: 20
+      0xa9,                    //   Type: UnknownFrameType(169)
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // Payload
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x08, 0x62, 0x61, 0x7a,  //
+      0x3d, 0x62, 0x69, 0x6e,  //
+      0x67, 0x00, 0x06, 0x63,  //
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  TestExtension extension;
+  visitor.set_extension_visitor(&extension);
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+}
+
+TEST_P(SpdyFramerTest, ReceiveContinuationOnWrongStream) {
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x10,        // Length: 16
+      0x01,                    //   Type: HEADERS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+
+      0x00, 0x00, 0x14,        // Length: 20
+      0x09,                    //   Type: CONTINUATION
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x02,  // Stream: 2
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x08, 0x62, 0x61, 0x7a,  //
+      0x3d, 0x62, 0x69, 0x6e,  //
+      0x67, 0x00, 0x06, 0x63,  //
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+}
+
+TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) {
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x18,        // Length: 24
+      0x09,                    //   Type: CONTINUATION
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+}
+
+TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) {
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x10,        // Length: 16
+      0x01,                    //   Type: HEADERS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+
+      0x00, 0x00, 0x00,        // Length: 0
+      0x00,                    //   Type: DATA
+      0x01,                    //  Flags: END_STREAM
+      0x00, 0x00, 0x00, 0x04,  // Stream: 4
+
+      0xde, 0xad, 0xbe, 0xef,  // Truncated Frame Header
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+  EXPECT_EQ(0, visitor.data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) {
+  const unsigned char kInput[] = {
+      0x00, 0x00, 0x10,        // Length: 16
+      0x01,                    //   Type: HEADERS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+
+      0x00, 0x00, 0x10,        // Length: 16
+      0x01,                    //   Type: HEADERS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x06, 0x63, 0x6f,  // HPACK
+      0x6f, 0x6b, 0x69, 0x65,  //
+      0x07, 0x66, 0x6f, 0x6f,  //
+      0x3d, 0x62, 0x61, 0x72,  //
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kInput, sizeof(kInput));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+  EXPECT_EQ(1, visitor.headers_frame_count_);
+  EXPECT_EQ(0, visitor.continuation_count_);
+  EXPECT_EQ(0u, visitor.header_buffer_length_);
+  EXPECT_EQ(0, visitor.data_frame_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadGarbage) {
+  unsigned char garbage_frame[256];
+  memset(garbage_frame, ~0, sizeof(garbage_frame));
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadUnknownExtensionFrame) {
+  // The unrecognized frame type should still have a valid length.
+  const unsigned char unknown_frame[] = {
+      0x00, 0x00, 0x08,        // Length: 8
+      0xff,                    //   Type: UnknownFrameType(255)
+      0xff,                    //  Flags: 0xff
+      0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
+      0xff, 0xff, 0xff, 0xff,  // Payload
+      0xff, 0xff, 0xff, 0xff,  //
+  };
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+
+  // Simulate the case where the stream id validation checks out.
+  visitor.on_unknown_frame_result_ = true;
+  visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame));
+  EXPECT_EQ(0, visitor.error_count_);
+
+  // Follow it up with a valid control frame to make sure we handle
+  // subsequent frames correctly.
+  SpdySettingsIR settings_ir;
+  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10);
+  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
+  if (use_output_) {
+    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.setting_count_);
+  EXPECT_EQ(1, visitor.settings_ack_sent_);
+}
+
+TEST_P(SpdyFramerTest, ReadUnknownExtensionFrameWithExtension) {
+  // The unrecognized frame type should still have a valid length.
+  const unsigned char unknown_frame[] = {
+      0x00, 0x00, 0x14,        // Length: 20
+      0xff,                    //   Type: UnknownFrameType(255)
+      0xff,                    //  Flags: 0xff
+      0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
+      0xff, 0xff, 0xff, 0xff,  // Payload
+      0xff, 0xff, 0xff, 0xff,  //
+      0xff, 0xff, 0xff, 0xff,  //
+      0xff, 0xff, 0xff, 0xff,  //
+      0xff, 0xff, 0xff, 0xff,  //
+  };
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  TestExtension extension;
+  visitor.set_extension_visitor(&extension);
+  visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame));
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(0x7fffffffu, extension.stream_id_);
+  EXPECT_EQ(20u, extension.length_);
+  EXPECT_EQ(255, extension.type_);
+  EXPECT_EQ(0xff, extension.flags_);
+  EXPECT_EQ(std::string(20, '\xff'), extension.payload_);
+
+  // Follow it up with a valid control frame to make sure we handle
+  // subsequent frames correctly.
+  SpdySettingsIR settings_ir;
+  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10);
+  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
+  visitor.SimulateInFramer(
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.setting_count_);
+  EXPECT_EQ(1, visitor.settings_ack_sent_);
+}
+
+TEST_P(SpdyFramerTest, ReadGarbageWithValidLength) {
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x08,        // Length: 8
+      0xff,                    //   Type: UnknownFrameType(255)
+      0xff,                    //  Flags: 0xff
+      0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
+      0xff, 0xff, 0xff, 0xff,  // Payload
+      0xff, 0xff, 0xff, 0xff,  //
+  };
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, ABSL_ARRAYSIZE(kFrameData));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, ReadGarbageHPACKEncoding) {
+  const unsigned char kInput[] = {
+      0x00, 0x12, 0x01,        // Length: 4609
+      0x04,                    //   Type: SETTINGS
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x01, 0xef,  // Stream: 495
+      0xef, 0xff,              //  Param: 61439
+      0xff, 0xff, 0xff, 0xff,  //  Value: 4294967295
+      0xff, 0xff,              //  Param: 0xffff
+      0xff, 0xff, 0xff, 0xff,  //  Value: 4294967295
+      0xff, 0xff, 0xff, 0xff,  // Settings (Truncated)
+      0xff,                    //
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kInput, ABSL_ARRAYSIZE(kInput));
+  EXPECT_EQ(1, visitor.error_count_);
+}
+
+TEST_P(SpdyFramerTest, SizesTest) {
+  EXPECT_EQ(9u, kFrameHeaderSize);
+  EXPECT_EQ(9u, kDataFrameMinimumSize);
+  EXPECT_EQ(9u, kHeadersFrameMinimumSize);
+  EXPECT_EQ(14u, kPriorityFrameSize);
+  EXPECT_EQ(13u, kRstStreamFrameSize);
+  EXPECT_EQ(9u, kSettingsFrameMinimumSize);
+  EXPECT_EQ(13u, kPushPromiseFrameMinimumSize);
+  EXPECT_EQ(17u, kPingFrameSize);
+  EXPECT_EQ(17u, kGoawayFrameMinimumSize);
+  EXPECT_EQ(13u, kWindowUpdateFrameSize);
+  EXPECT_EQ(9u, kContinuationFrameMinimumSize);
+  EXPECT_EQ(11u, kGetAltSvcFrameMinimumSize);
+  EXPECT_EQ(9u, kFrameMinimumSize);
+
+  EXPECT_EQ(16384u, kHttp2DefaultFramePayloadLimit);
+  EXPECT_EQ(16393u, kHttp2DefaultFrameSizeLimit);
+}
+
+TEST_P(SpdyFramerTest, StateToStringTest) {
+  EXPECT_STREQ("ERROR", Http2DecoderAdapter::StateToString(
+                            Http2DecoderAdapter::SPDY_ERROR));
+  EXPECT_STREQ("FRAME_COMPLETE", Http2DecoderAdapter::StateToString(
+                                     Http2DecoderAdapter::SPDY_FRAME_COMPLETE));
+  EXPECT_STREQ("READY_FOR_FRAME",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_READY_FOR_FRAME));
+  EXPECT_STREQ("READING_COMMON_HEADER",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_READING_COMMON_HEADER));
+  EXPECT_STREQ("CONTROL_FRAME_PAYLOAD",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_CONTROL_FRAME_PAYLOAD));
+  EXPECT_STREQ("IGNORE_REMAINING_PAYLOAD",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_IGNORE_REMAINING_PAYLOAD));
+  EXPECT_STREQ("FORWARD_STREAM_FRAME",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME));
+  EXPECT_STREQ(
+      "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK",
+      Http2DecoderAdapter::StateToString(
+          Http2DecoderAdapter::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK));
+  EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_CONTROL_FRAME_HEADER_BLOCK));
+  EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_SETTINGS_FRAME_PAYLOAD));
+  EXPECT_STREQ("SPDY_ALTSVC_FRAME_PAYLOAD",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_ALTSVC_FRAME_PAYLOAD));
+  EXPECT_STREQ("UNKNOWN_STATE",
+               Http2DecoderAdapter::StateToString(
+                   Http2DecoderAdapter::SPDY_ALTSVC_FRAME_PAYLOAD + 1));
+}
+
+TEST_P(SpdyFramerTest, SpdyFramerErrorToStringTest) {
+  EXPECT_STREQ("NO_ERROR", Http2DecoderAdapter::SpdyFramerErrorToString(
+                               Http2DecoderAdapter::SPDY_NO_ERROR));
+  EXPECT_STREQ("INVALID_STREAM_ID",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_INVALID_STREAM_ID));
+  EXPECT_STREQ("INVALID_CONTROL_FRAME",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
+  EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
+  EXPECT_STREQ("DECOMPRESS_FAILURE",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_DECOMPRESS_FAILURE));
+  EXPECT_STREQ("INVALID_PADDING",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_INVALID_PADDING));
+  EXPECT_STREQ("INVALID_DATA_FRAME_FLAGS",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS));
+  EXPECT_STREQ("UNEXPECTED_FRAME",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME));
+  EXPECT_STREQ("INTERNAL_FRAMER_ERROR",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_INTERNAL_FRAMER_ERROR));
+  EXPECT_STREQ("INVALID_CONTROL_FRAME_SIZE",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE));
+  EXPECT_STREQ("OVERSIZED_PAYLOAD",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD));
+  EXPECT_STREQ("UNKNOWN_ERROR", Http2DecoderAdapter::SpdyFramerErrorToString(
+                                    Http2DecoderAdapter::LAST_ERROR));
+  EXPECT_STREQ("UNKNOWN_ERROR",
+               Http2DecoderAdapter::SpdyFramerErrorToString(
+                   static_cast<Http2DecoderAdapter::SpdyFramerError>(
+                       Http2DecoderAdapter::LAST_ERROR + 1)));
+}
+
+TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
+  uint8_t valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED;
+
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+    deframer_->set_visitor(&visitor);
+
+    SpdyDataIR data_ir(/* stream_id = */ 1, "hello");
+    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
+    SetFrameFlags(&frame, flags);
+
+    EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, flags));
+    if (flags & ~valid_data_flags) {
+      EXPECT_CALL(visitor, OnError(_, _));
+    } else {
+      EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
+      if (flags & DATA_FLAG_PADDED) {
+        // The first byte of payload is parsed as padding length, but 'h'
+        // (0x68) is too large a padding length for a 5 byte payload.
+        EXPECT_CALL(visitor, OnStreamPadding(_, 1));
+        // Expect Error since the frame ends prematurely.
+        EXPECT_CALL(visitor, OnError(_, _));
+      } else {
+        EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5));
+        if (flags & DATA_FLAG_FIN) {
+          EXPECT_CALL(visitor, OnStreamEnd(_));
+        }
+      }
+    }
+
+    deframer_->ProcessInput(frame.data(), frame.size());
+    if (flags & ~valid_data_flags) {
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS,
+                deframer_->spdy_framer_error())
+          << Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+    } else if (flags & DATA_FLAG_PADDED) {
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
+                deframer_->spdy_framer_error())
+          << Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+    } else {
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+                deframer_->spdy_framer_error())
+          << Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+    }
+    deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+    deframer_->set_visitor(&visitor);
+
+    SpdyRstStreamIR rst_stream(/* stream_id = */ 13, ERROR_CODE_CANCEL);
+    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    SetFrameFlags(&frame, flags);
+
+    EXPECT_CALL(visitor, OnCommonHeader(13, 4, 0x3, flags));
+    EXPECT_CALL(visitor, OnRstStream(13, ERROR_CODE_CANCEL));
+
+    deframer_->ProcessInput(frame.data(), frame.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+              deframer_->spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+    deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, SettingsFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+    deframer_->set_visitor(&visitor);
+
+    SpdySettingsIR settings_ir;
+    settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16);
+    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    SetFrameFlags(&frame, flags);
+
+    EXPECT_CALL(visitor, OnCommonHeader(0, 6, 0x4, flags));
+    if (flags & SETTINGS_FLAG_ACK) {
+      EXPECT_CALL(visitor, OnError(_, _));
+    } else {
+      EXPECT_CALL(visitor, OnSettings());
+      EXPECT_CALL(visitor, OnSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16));
+      EXPECT_CALL(visitor, OnSettingsEnd());
+    }
+
+    deframer_->ProcessInput(frame.data(), frame.size());
+    if (flags & SETTINGS_FLAG_ACK) {
+      // The frame is invalid because ACK frames should have no payload.
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+                deframer_->spdy_framer_error())
+          << Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+    } else {
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+      EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+                deframer_->spdy_framer_error())
+          << Http2DecoderAdapter::SpdyFramerErrorToString(
+                 deframer_->spdy_framer_error());
+    }
+    deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, GoawayFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+    deframer_->set_visitor(&visitor);
+
+    SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 97, ERROR_CODE_NO_ERROR,
+                           "test");
+    SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
+    if (use_output_) {
+      output_.Reset();
+      ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
+      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    }
+    SetFrameFlags(&frame, flags);
+
+    EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x7, flags));
+    EXPECT_CALL(visitor, OnGoAway(97, ERROR_CODE_NO_ERROR));
+    EXPECT_CALL(visitor, OnGoAwayFrameData)
+        .WillRepeatedly(testing::Return(true));
+
+    deframer_->ProcessInput(frame.data(), frame.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+              deframer_->spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+    deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, HeadersFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+    Http2DecoderAdapter deframer;
+    deframer.set_visitor(&visitor);
+
+    SpdyHeadersIR headers_ir(/* stream_id = */ 57);
+    if (flags & HEADERS_FLAG_PRIORITY) {
+      headers_ir.set_weight(3);
+      headers_ir.set_has_priority(true);
+      headers_ir.set_parent_stream_id(5);
+      headers_ir.set_exclusive(true);
+    }
+    headers_ir.SetHeader("foo", "bar");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
+        &framer, headers_ir, use_output_ ? &output_ : nullptr));
+    uint8_t set_flags = flags & ~HEADERS_FLAG_PADDED;
+    SetFrameFlags(&frame, set_flags);
+
+    // Expected callback values
+    SpdyStreamId stream_id = 57;
+    bool has_priority = false;
+    int weight = 0;
+    SpdyStreamId parent_stream_id = 0;
+    bool exclusive = false;
+    bool fin = flags & CONTROL_FLAG_FIN;
+    bool end = flags & HEADERS_FLAG_END_HEADERS;
+    if (flags & HEADERS_FLAG_PRIORITY) {
+      has_priority = true;
+      weight = 3;
+      parent_stream_id = 5;
+      exclusive = true;
+    }
+    EXPECT_CALL(visitor, OnCommonHeader(stream_id, _, 0x1, set_flags));
+    EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, weight,
+                                   parent_stream_id, exclusive, fin, end));
+    EXPECT_CALL(visitor, OnHeaderFrameStart(57)).Times(1);
+    if (end) {
+      EXPECT_CALL(visitor, OnHeaderFrameEnd(57)).Times(1);
+    }
+    if (flags & DATA_FLAG_FIN && end) {
+      EXPECT_CALL(visitor, OnStreamEnd(_));
+    } else {
+      // Do not close the stream if we are expecting a CONTINUATION frame.
+      EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0);
+    }
+
+    deframer.ProcessInput(frame.data(), frame.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer.spdy_framer_error());
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, PingFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+    deframer_->set_visitor(&visitor);
+
+    SpdySerializedFrame frame(framer_.SerializePing(SpdyPingIR(42)));
+    SetFrameFlags(&frame, flags);
+
+    EXPECT_CALL(visitor, OnCommonHeader(0, 8, 0x6, flags));
+    EXPECT_CALL(visitor, OnPing(42, flags & PING_FLAG_ACK));
+
+    deframer_->ProcessInput(frame.data(), frame.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+              deframer_->spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+    deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+    deframer_->set_visitor(&visitor);
+
+    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
+        SpdyWindowUpdateIR(/* stream_id = */ 4, /* delta = */ 1024)));
+    SetFrameFlags(&frame, flags);
+
+    EXPECT_CALL(visitor, OnCommonHeader(4, 4, 0x8, flags));
+    EXPECT_CALL(visitor, OnWindowUpdate(4, 1024));
+
+    deframer_->ProcessInput(frame.data(), frame.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+              deframer_->spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+    deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, PushPromiseFrameFlags) {
+  const SpdyStreamId client_id = 123;   // Must be odd.
+  const SpdyStreamId promised_id = 22;  // Must be even.
+  uint8_t flags = 0;
+  do {
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+    testing::StrictMock<test::MockDebugVisitor> debug_visitor;
+    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+    Http2DecoderAdapter deframer;
+    deframer.set_visitor(&visitor);
+    deframer.set_debug_visitor(&debug_visitor);
+    framer.set_debug_visitor(&debug_visitor);
+
+    EXPECT_CALL(
+        debug_visitor,
+        OnSendCompressedFrame(client_id, SpdyFrameType::PUSH_PROMISE, _, _));
+
+    SpdyPushPromiseIR push_promise(client_id, promised_id);
+    push_promise.SetHeader("foo", "bar");
+    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
+        &framer, push_promise, use_output_ ? &output_ : nullptr));
+    // TODO(jgraettinger): Add padding to SpdyPushPromiseIR,
+    // and implement framing.
+    SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED);
+
+    bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
+    EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(
+                                   client_id, SpdyFrameType::PUSH_PROMISE, _));
+    EXPECT_CALL(visitor, OnCommonHeader(client_id, _, 0x5,
+                                        flags & ~HEADERS_FLAG_PADDED));
+    EXPECT_CALL(visitor, OnPushPromise(client_id, promised_id, end));
+    EXPECT_CALL(visitor, OnHeaderFrameStart(client_id)).Times(1);
+    if (end) {
+      EXPECT_CALL(visitor, OnHeaderFrameEnd(client_id)).Times(1);
+    }
+
+    deframer.ProcessInput(frame.data(), frame.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer.spdy_framer_error());
+  } while (++flags != 0);
+}
+
+TEST_P(SpdyFramerTest, ContinuationFrameFlags) {
+  uint8_t flags = 0;
+  do {
+    if (use_output_) {
+      output_.Reset();
+    }
+    SCOPED_TRACE(testing::Message()
+                 << "Flags " << std::hex << static_cast<int>(flags));
+
+    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+    testing::StrictMock<test::MockDebugVisitor> debug_visitor;
+    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
+    Http2DecoderAdapter deframer;
+    deframer.set_visitor(&visitor);
+    deframer.set_debug_visitor(&debug_visitor);
+    framer.set_debug_visitor(&debug_visitor);
+
+    EXPECT_CALL(debug_visitor,
+                OnSendCompressedFrame(42, SpdyFrameType::HEADERS, _, _));
+    EXPECT_CALL(debug_visitor,
+                OnReceiveCompressedFrame(42, SpdyFrameType::HEADERS, _));
+    EXPECT_CALL(visitor, OnCommonHeader(42, _, 0x1, 0));
+    EXPECT_CALL(visitor, OnHeaders(42, false, 0, 0, false, false, false));
+    EXPECT_CALL(visitor, OnHeaderFrameStart(42)).Times(1);
+
+    SpdyHeadersIR headers_ir(/* stream_id = */ 42);
+    headers_ir.SetHeader("foo", "bar");
+    SpdySerializedFrame frame0;
+    if (use_output_) {
+      EXPECT_TRUE(framer.SerializeHeaders(headers_ir, &output_));
+      frame0 = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+    } else {
+      frame0 = framer.SerializeHeaders(headers_ir);
+    }
+    SetFrameFlags(&frame0, 0);
+
+    SpdyContinuationIR continuation(/* stream_id = */ 42);
+    SpdySerializedFrame frame1;
+    if (use_output_) {
+      char* begin = output_.Begin() + output_.Size();
+      ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
+      frame1 =
+          SpdySerializedFrame(begin, output_.Size() - frame0.size(), false);
+    } else {
+      frame1 = framer.SerializeContinuation(continuation);
+    }
+    SetFrameFlags(&frame1, flags);
+
+    EXPECT_CALL(debug_visitor,
+                OnReceiveCompressedFrame(42, SpdyFrameType::CONTINUATION, _));
+    EXPECT_CALL(visitor, OnCommonHeader(42, _, 0x9, flags));
+    EXPECT_CALL(visitor, OnContinuation(42, flags & HEADERS_FLAG_END_HEADERS));
+    bool end = flags & HEADERS_FLAG_END_HEADERS;
+    if (end) {
+      EXPECT_CALL(visitor, OnHeaderFrameEnd(42)).Times(1);
+    }
+
+    deframer.ProcessInput(frame0.data(), frame0.size());
+    deframer.ProcessInput(frame1.data(), frame1.size());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer.spdy_framer_error());
+  } while (++flags != 0);
+}
+
+// TODO(mlavan): Add TEST_P(SpdyFramerTest, AltSvcFrameFlags)
+
+// Test handling of a RST_STREAM with out-of-bounds status codes.
+TEST_P(SpdyFramerTest, RstStreamStatusBounds) {
+  const unsigned char kH2RstStreamInvalid[] = {
+      0x00, 0x00, 0x04,        // Length: 4
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
+  };
+  const unsigned char kH2RstStreamNumStatusCodes[] = {
+      0x00, 0x00, 0x04,        // Length: 4
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x01,  // Stream: 1
+      0x00, 0x00, 0x00, 0xff,  //  Error: 255
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x3, 0x0));
+  EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_NO_ERROR));
+  deframer_->ProcessInput(reinterpret_cast<const char*>(kH2RstStreamInvalid),
+                          ABSL_ARRAYSIZE(kH2RstStreamInvalid));
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+  deframer_ = absl::make_unique<Http2DecoderAdapter>();
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x3, 0x0));
+  EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_INTERNAL_ERROR));
+  deframer_->ProcessInput(
+      reinterpret_cast<const char*>(kH2RstStreamNumStatusCodes),
+      ABSL_ARRAYSIZE(kH2RstStreamNumStatusCodes));
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Test handling of GOAWAY frames with out-of-bounds status code.
+TEST_P(SpdyFramerTest, GoAwayStatusBounds) {
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x0a,        // Length: 10
+      0x07,                    //   Type: GOAWAY
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0x00, 0x00, 0x00, 0x01,  //   Last: 1
+      0xff, 0xff, 0xff, 0xff,  //  Error: 0xffffffff
+      0x47, 0x41,              // Description
+  };
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 10, 0x7, 0x0));
+  EXPECT_CALL(visitor, OnGoAway(1, ERROR_CODE_INTERNAL_ERROR));
+  EXPECT_CALL(visitor, OnGoAwayFrameData).WillRepeatedly(testing::Return(true));
+  deframer_->ProcessInput(reinterpret_cast<const char*>(kH2FrameData),
+                          ABSL_ARRAYSIZE(kH2FrameData));
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Tests handling of a GOAWAY frame with out-of-bounds stream ID.
+TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
+  const unsigned char kH2FrameData[] = {
+      0x00, 0x00, 0x08,        // Length: 8
+      0x07,                    //   Type: GOAWAY
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0xff, 0xff, 0xff, 0xff,  //   Last: 0x7fffffff (R-bit set)
+      0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 8, 0x7, 0x0));
+  EXPECT_CALL(visitor, OnGoAway(0x7fffffff, ERROR_CODE_NO_ERROR));
+  EXPECT_CALL(visitor, OnGoAwayFrameData).WillRepeatedly(testing::Return(true));
+  deframer_->ProcessInput(reinterpret_cast<const char*>(kH2FrameData),
+                          ABSL_ARRAYSIZE(kH2FrameData));
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, OnAltSvcWithOrigin) {
+  const SpdyStreamId kStreamId = 0;  // Stream id must be zero if origin given.
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyAltSvcWireFormat::AlternativeService altsvc1(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
+  SpdyAltSvcWireFormat::AlternativeService altsvc2(
+      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  altsvc_vector.push_back(altsvc1);
+  altsvc_vector.push_back(altsvc2);
+  EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
+  EXPECT_CALL(visitor,
+              OnAltSvc(kStreamId, absl::string_view("o_r|g!n"), altsvc_vector));
+
+  SpdyAltSvcIR altsvc_ir(kStreamId);
+  altsvc_ir.set_origin("o_r|g!n");
+  altsvc_ir.add_altsvc(altsvc1);
+  altsvc_ir.add_altsvc(altsvc2);
+  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
+  if (use_output_) {
+    output_.Reset();
+    EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  deframer_->ProcessInput(frame.data(), frame.size());
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) {
+  const SpdyStreamId kStreamId = 1;
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  SpdyAltSvcWireFormat::AlternativeService altsvc1(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
+  SpdyAltSvcWireFormat::AlternativeService altsvc2(
+      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  altsvc_vector.push_back(altsvc1);
+  altsvc_vector.push_back(altsvc2);
+  EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
+  EXPECT_CALL(visitor,
+              OnAltSvc(kStreamId, absl::string_view(""), altsvc_vector));
+
+  SpdyAltSvcIR altsvc_ir(kStreamId);
+  altsvc_ir.add_altsvc(altsvc1);
+  altsvc_ir.add_altsvc(altsvc2);
+  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
+  deframer_->ProcessInput(frame.data(), frame.size());
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, OnAltSvcEmptyProtocolId) {
+  const SpdyStreamId kStreamId = 0;  // Stream id must be zero if origin given.
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
+  EXPECT_CALL(visitor,
+              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME, _));
+
+  SpdyAltSvcIR altsvc_ir(kStreamId);
+  altsvc_ir.set_origin("o1");
+  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
+  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
+      "", "h1", 443, 10, SpdyAltSvcWireFormat::VersionVector()));
+  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
+  if (use_output_) {
+    output_.Reset();
+    EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  deframer_->ProcessInput(frame.data(), frame.size());
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, OnAltSvcBadLengths) {
+  const unsigned char kType = SerializeFrameType(SpdyFrameType::ALTSVC);
+  const unsigned char kFrameDataOriginLenLargerThanFrame[] = {
+      0x00, 0x00, 0x05, kType, 0x00, 0x00, 0x00,
+      0x00, 0x03, 0x42, 0x42,  'f',  'o',  'o',
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+
+  deframer_->set_visitor(&visitor);
+  visitor.SimulateInFramer(kFrameDataOriginLenLargerThanFrame,
+                           sizeof(kFrameDataOriginLenLargerThanFrame));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
+            visitor.deframer_.spdy_framer_error());
+}
+
+// Tests handling of ALTSVC frames delivered in small chunks.
+TEST_P(SpdyFramerTest, ReadChunkedAltSvcFrame) {
+  SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
+  SpdyAltSvcWireFormat::AlternativeService altsvc1(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
+  SpdyAltSvcWireFormat::AlternativeService altsvc2(
+      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
+  altsvc_ir.add_altsvc(altsvc1);
+  altsvc_ir.add_altsvc(altsvc2);
+
+  SpdySerializedFrame control_frame(framer_.SerializeAltSvc(altsvc_ir));
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+
+  // Read data in small chunks.
+  size_t framed_data = 0;
+  size_t unframed_data = control_frame.size();
+  size_t kReadChunkSize = 5;  // Read five bytes at a time.
+  while (unframed_data > 0) {
+    size_t to_read = std::min(kReadChunkSize, unframed_data);
+    visitor.SimulateInFramer(
+        reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
+        to_read);
+    unframed_data -= to_read;
+    framed_data += to_read;
+  }
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(1, visitor.altsvc_count_);
+  ASSERT_NE(nullptr, visitor.test_altsvc_ir_);
+  ASSERT_EQ(2u, visitor.test_altsvc_ir_->altsvc_vector().size());
+  EXPECT_TRUE(visitor.test_altsvc_ir_->altsvc_vector()[0] == altsvc1);
+  EXPECT_TRUE(visitor.test_altsvc_ir_->altsvc_vector()[1] == altsvc2);
+}
+
+// While RFC7838 Section 4 says that an ALTSVC frame on stream 0 with empty
+// origin MUST be ignored, it is not implemented at the framer level: instead,
+// such frames are passed on to the consumer.
+TEST_P(SpdyFramerTest, ReadAltSvcFrame) {
+  constexpr struct {
+    uint32_t stream_id;
+    const char* origin;
+  } test_cases[] = {{0, ""},
+                    {1, ""},
+                    {0, "https://www.example.com"},
+                    {1, "https://www.example.com"}};
+  for (const auto& test_case : test_cases) {
+    SpdyAltSvcIR altsvc_ir(test_case.stream_id);
+    SpdyAltSvcWireFormat::AlternativeService altsvc(
+        "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
+    altsvc_ir.add_altsvc(altsvc);
+    altsvc_ir.set_origin(test_case.origin);
+    SpdySerializedFrame frame(framer_.SerializeAltSvc(altsvc_ir));
+
+    TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+    deframer_->set_visitor(&visitor);
+    deframer_->ProcessInput(frame.data(), frame.size());
+
+    EXPECT_EQ(0, visitor.error_count_);
+    EXPECT_EQ(1, visitor.altsvc_count_);
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
+              deframer_->spdy_framer_error())
+        << Http2DecoderAdapter::SpdyFramerErrorToString(
+               deframer_->spdy_framer_error());
+  }
+}
+
+// An ALTSVC frame with invalid Alt-Svc-Field-Value results in an error.
+TEST_P(SpdyFramerTest, ErrorOnAltSvcFrameWithInvalidValue) {
+  // Alt-Svc-Field-Value must be "clear" or must contain an "=" character
+  // per RFC7838 Section 3.
+  const char kFrameData[] = {
+      0x00, 0x00, 0x16,        //     Length: 22
+      0x0a,                    //       Type: ALTSVC
+      0x00,                    //      Flags: none
+      0x00, 0x00, 0x00, 0x01,  //     Stream: 1
+      0x00, 0x00,              // Origin-Len: 0
+      0x74, 0x68, 0x69, 0x73,  // thisisnotavalidvalue
+      0x69, 0x73, 0x6e, 0x6f, 0x74, 0x61, 0x76, 0x61,
+      0x6c, 0x69, 0x64, 0x76, 0x61, 0x6c, 0x75, 0x65,
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
+  deframer_->set_visitor(&visitor);
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(1, visitor.error_count_);
+  EXPECT_EQ(0, visitor.altsvc_count_);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
+            deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+TEST_P(SpdyFramerTest, ReadPriorityUpdateFrame) {
+  const char kFrameData[] = {
+      0x00, 0x00, 0x07,        // payload length
+      0x10,                    // frame type PRIORITY_UPDATE
+      0x00,                    // flags
+      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
+      0x00, 0x00, 0x00, 0x03,  // prioritized stream ID, must not be zero
+      'f',  'o',  'o'          // priority field value
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 7, 0x10, 0x0));
+  EXPECT_CALL(visitor, OnPriorityUpdate(3, "foo"));
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+  EXPECT_FALSE(deframer_->HasError());
+}
+
+TEST_P(SpdyFramerTest, ReadPriorityUpdateFrameWithEmptyPriorityFieldValue) {
+  const char kFrameData[] = {
+      0x00, 0x00, 0x04,        // payload length
+      0x10,                    // frame type PRIORITY_UPDATE
+      0x00,                    // flags
+      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
+      0x00, 0x00, 0x00, 0x03   // prioritized stream ID, must not be zero
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 4, 0x10, 0x0));
+  EXPECT_CALL(visitor, OnPriorityUpdate(3, ""));
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+  EXPECT_FALSE(deframer_->HasError());
+}
+
+TEST_P(SpdyFramerTest, PriorityUpdateFrameWithEmptyPayload) {
+  const char kFrameData[] = {
+      0x00, 0x00, 0x00,        // payload length
+      0x10,                    // frame type PRIORITY_UPDATE
+      0x00,                    // flags
+      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 0, 0x10, 0x0));
+  EXPECT_CALL(visitor,
+              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE, _));
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+  EXPECT_TRUE(deframer_->HasError());
+}
+
+TEST_P(SpdyFramerTest, PriorityUpdateFrameWithShortPayload) {
+  const char kFrameData[] = {
+      0x00, 0x00, 0x02,        // payload length
+      0x10,                    // frame type PRIORITY_UPDATE
+      0x00,                    // flags
+      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
+      0x00, 0x01  // payload not long enough to hold 32 bits of prioritized
+                  // stream ID
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 2, 0x10, 0x0));
+  EXPECT_CALL(visitor,
+              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE, _));
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+  EXPECT_TRUE(deframer_->HasError());
+}
+
+TEST_P(SpdyFramerTest, PriorityUpdateFrameOnIncorrectStream) {
+  const char kFrameData[] = {
+      0x00, 0x00, 0x04,        // payload length
+      0x10,                    // frame type PRIORITY_UPDATE
+      0x00,                    // flags
+      0x00, 0x00, 0x00, 0x01,  // invalid stream ID, must be 0
+      0x00, 0x00, 0x00, 0x01,  // prioritized stream ID, must not be zero
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x10, 0x0));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+  EXPECT_TRUE(deframer_->HasError());
+}
+
+TEST_P(SpdyFramerTest, PriorityUpdateFramePrioritizingIncorrectStream) {
+  const char kFrameData[] = {
+      0x00, 0x00, 0x04,        // payload length
+      0x10,                    // frame type PRIORITY_UPDATE
+      0x00,                    // flags
+      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
+      0x00, 0x00, 0x00, 0x00,  // prioritized stream ID, must not be zero
+  };
+
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+
+  EXPECT_CALL(visitor, OnCommonHeader(0, 4, 0x10, 0x0));
+  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
+  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
+  EXPECT_TRUE(deframer_->HasError());
+}
+
+// Tests handling of PRIORITY frames.
+TEST_P(SpdyFramerTest, ReadPriority) {
+  SpdyPriorityIR priority(/* stream_id = */ 3,
+                          /* parent_stream_id = */ 1,
+                          /* weight = */ 256,
+                          /* exclusive = */ false);
+  SpdySerializedFrame frame(framer_.SerializePriority(priority));
+  if (use_output_) {
+    output_.Reset();
+    ASSERT_TRUE(framer_.SerializePriority(priority, &output_));
+    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+  }
+  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
+  deframer_->set_visitor(&visitor);
+  EXPECT_CALL(visitor, OnCommonHeader(3, 5, 0x2, 0x0));
+  EXPECT_CALL(visitor, OnPriority(3, 1, 256, false));
+  deframer_->ProcessInput(frame.data(), frame.size());
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             deframer_->spdy_framer_error());
+}
+
+// Tests handling of PRIORITY frame with incorrect size.
+TEST_P(SpdyFramerTest, ReadIncorrectlySizedPriority) {
+  // PRIORITY frame of size 4, which isn't correct.
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x04,        // Length: 4
+      0x02,                    //   Type: PRIORITY
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x00, 0x01,  // Priority (Truncated)
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+}
+
+// Tests handling of PING frame with incorrect size.
+TEST_P(SpdyFramerTest, ReadIncorrectlySizedPing) {
+  // PING frame of size 4, which isn't correct.
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x04,        // Length: 4
+      0x06,                    //   Type: PING
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x00,  // Stream: 0
+      0x00, 0x00, 0x00, 0x01,  // Ping (Truncated)
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+}
+
+// Tests handling of WINDOW_UPDATE frame with incorrect size.
+TEST_P(SpdyFramerTest, ReadIncorrectlySizedWindowUpdate) {
+  // WINDOW_UPDATE frame of size 3, which isn't correct.
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x03,        // Length: 3
+      0x08,                    //   Type: WINDOW_UPDATE
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x01,        // WindowUpdate (Truncated)
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+}
+
+// Tests handling of RST_STREAM frame with incorrect size.
+TEST_P(SpdyFramerTest, ReadIncorrectlySizedRstStream) {
+  // RST_STREAM frame of size 3, which isn't correct.
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x03,        // Length: 3
+      0x03,                    //   Type: RST_STREAM
+      0x00,                    //  Flags: none
+      0x00, 0x00, 0x00, 0x03,  // Stream: 3
+      0x00, 0x00, 0x01,        // RstStream (Truncated)
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+}
+
+// Regression test for https://crbug.com/548674:
+// RST_STREAM with payload must not be accepted.
+TEST_P(SpdyFramerTest, ReadInvalidRstStreamWithPayload) {
+  const unsigned char kFrameData[] = {
+      0x00, 0x00, 0x07,        //  Length: 7
+      0x03,                    //    Type: RST_STREAM
+      0x00,                    //   Flags: none
+      0x00, 0x00, 0x00, 0x01,  //  Stream: 1
+      0x00, 0x00, 0x00, 0x00,  //   Error: NO_ERROR
+      'f',  'o',  'o'          // Payload: "foo"
+  };
+
+  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
+  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
+
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
+            visitor.deframer_.spdy_framer_error())
+      << Http2DecoderAdapter::SpdyFramerErrorToString(
+             visitor.deframer_.spdy_framer_error());
+}
+
+// Test that SpdyFramer processes all passed input in one call to ProcessInput.
+TEST_P(SpdyFramerTest, ProcessAllInput) {
+  auto visitor =
+      std::make_unique<TestSpdyVisitor>(SpdyFramer::DISABLE_COMPRESSION);
+  deframer_->set_visitor(visitor.get());
+
+  // Create two input frames.
+  SpdyHeadersIR headers(/* stream_id = */ 1);
+  headers.SetHeader("alpha", "beta");
+  headers.SetHeader("gamma", "charlie");
+  headers.SetHeader("cookie", "key1=value1; key2=value2");
+  SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders(
+      &framer_, headers, use_output_ ? &output_ : nullptr));
+
+  const char four_score[] = "Four score and seven years ago";
+  SpdyDataIR four_score_ir(/* stream_id = */ 1, four_score);
+  SpdySerializedFrame four_score_frame(framer_.SerializeData(four_score_ir));
+
+  // Put them in a single buffer (new variables here to make it easy to
+  // change the order and type of frames).
+  SpdySerializedFrame frame1 = std::move(headers_frame);
+  SpdySerializedFrame frame2 = std::move(four_score_frame);
+
+  const size_t frame1_size = frame1.size();
+  const size_t frame2_size = frame2.size();
+
+  QUICHE_VLOG(1) << "frame1_size = " << frame1_size;
+  QUICHE_VLOG(1) << "frame2_size = " << frame2_size;
+
+  std::string input_buffer;
+  input_buffer.append(frame1.data(), frame1_size);
+  input_buffer.append(frame2.data(), frame2_size);
+
+  const char* buf = input_buffer.data();
+  const size_t buf_size = input_buffer.size();
+
+  QUICHE_VLOG(1) << "buf_size = " << buf_size;
+
+  size_t processed = deframer_->ProcessInput(buf, buf_size);
+  EXPECT_EQ(buf_size, processed);
+  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
+  EXPECT_EQ(1, visitor->headers_frame_count_);
+  EXPECT_EQ(1, visitor->data_frame_count_);
+  EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_));
+}
+
+namespace {
+void CheckFrameAndIRSize(SpdyFrameIR* ir,
+                         SpdyFramer* framer,
+                         ArrayOutputBuffer* output_buffer) {
+  output_buffer->Reset();
+  SpdyFrameType type = ir->frame_type();
+  size_t ir_size = ir->size();
+  framer->SerializeFrame(*ir, output_buffer);
+  if (type == SpdyFrameType::HEADERS || type == SpdyFrameType::PUSH_PROMISE) {
+    // For HEADERS and PUSH_PROMISE, the size is an estimate.
+    EXPECT_GE(ir_size, output_buffer->Size() * 9 / 10);
+    EXPECT_LT(ir_size, output_buffer->Size() * 11 / 10);
+  } else {
+    EXPECT_EQ(ir_size, output_buffer->Size());
+  }
+}
+}  // namespace
+
+TEST_P(SpdyFramerTest, SpdyFrameIRSize) {
+  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+
+  const char bytes[] = "this is a very short data frame";
+  SpdyDataIR data_ir(1, absl::string_view(bytes, ABSL_ARRAYSIZE(bytes)));
+  CheckFrameAndIRSize(&data_ir, &framer, &output_);
+
+  SpdyRstStreamIR rst_ir(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
+  CheckFrameAndIRSize(&rst_ir, &framer, &output_);
+
+  SpdySettingsIR settings_ir;
+  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
+  settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
+  settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
+  CheckFrameAndIRSize(&settings_ir, &framer, &output_);
+
+  SpdyPingIR ping_ir(42);
+  CheckFrameAndIRSize(&ping_ir, &framer, &output_);
+
+  SpdyGoAwayIR goaway_ir(97, ERROR_CODE_NO_ERROR, "Goaway description");
+  CheckFrameAndIRSize(&goaway_ir, &framer, &output_);
+
+  SpdyHeadersIR headers_ir(1);
+  headers_ir.SetHeader("alpha", "beta");
+  headers_ir.SetHeader("gamma", "charlie");
+  headers_ir.SetHeader("cookie", "key1=value1; key2=value2");
+  CheckFrameAndIRSize(&headers_ir, &framer, &output_);
+
+  SpdyHeadersIR headers_ir_with_continuation(1);
+  headers_ir_with_continuation.SetHeader("alpha", std::string(100000, 'x'));
+  headers_ir_with_continuation.SetHeader("beta", std::string(100000, 'x'));
+  headers_ir_with_continuation.SetHeader("cookie", "key1=value1; key2=value2");
+  CheckFrameAndIRSize(&headers_ir_with_continuation, &framer, &output_);
+
+  SpdyWindowUpdateIR window_update_ir(4, 1024);
+  CheckFrameAndIRSize(&window_update_ir, &framer, &output_);
+
+  SpdyPushPromiseIR push_promise_ir(3, 8);
+  push_promise_ir.SetHeader("alpha", std::string(100000, 'x'));
+  push_promise_ir.SetHeader("beta", std::string(100000, 'x'));
+  push_promise_ir.SetHeader("cookie", "key1=value1; key2=value2");
+  CheckFrameAndIRSize(&push_promise_ir, &framer, &output_);
+
+  SpdyAltSvcWireFormat::AlternativeService altsvc1(
+      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
+  SpdyAltSvcWireFormat::AlternativeService altsvc2(
+      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+  altsvc_vector.push_back(altsvc1);
+  altsvc_vector.push_back(altsvc2);
+  SpdyAltSvcIR altsvc_ir(0);
+  altsvc_ir.set_origin("o_r|g!n");
+  altsvc_ir.add_altsvc(altsvc1);
+  altsvc_ir.add_altsvc(altsvc2);
+  CheckFrameAndIRSize(&altsvc_ir, &framer, &output_);
+
+  SpdyPriorityIR priority_ir(3, 1, 256, false);
+  CheckFrameAndIRSize(&priority_ir, &framer, &output_);
+
+  const char kDescription[] = "Unknown frame";
+  const uint8_t kType = 0xaf;
+  const uint8_t kFlags = 0x11;
+  SpdyUnknownIR unknown_ir(2, kType, kFlags, kDescription);
+  CheckFrameAndIRSize(&unknown_ir, &framer, &output_);
+}
+
+}  // namespace test
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_header_block.cc b/quiche/spdy/core/spdy_header_block.cc
new file mode 100644
index 0000000..3a59c33
--- /dev/null
+++ b/quiche/spdy/core/spdy_header_block.cc
@@ -0,0 +1,317 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_header_block.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+namespace {
+
+// By default, linked_hash_map's internal map allocates space for 100 map
+// buckets on construction, which is larger than necessary.  Standard library
+// unordered map implementations use a list of prime numbers to set the bucket
+// count for a particular capacity.  |kInitialMapBuckets| is chosen to reduce
+// memory usage for small header blocks, at the cost of having to rehash for
+// large header blocks.
+const size_t kInitialMapBuckets = 11;
+
+const char kCookieKey[] = "cookie";
+const char kNullSeparator = 0;
+
+absl::string_view SeparatorForKey(absl::string_view key) {
+  if (key == kCookieKey) {
+    static absl::string_view cookie_separator = "; ";
+    return cookie_separator;
+  } else {
+    return absl::string_view(&kNullSeparator, 1);
+  }
+}
+
+}  // namespace
+
+Http2HeaderBlock::HeaderValue::HeaderValue(SpdyHeaderStorage* storage,
+                                           absl::string_view key,
+                                           absl::string_view initial_value)
+    : storage_(storage),
+      fragments_({initial_value}),
+      pair_({key, {}}),
+      size_(initial_value.size()),
+      separator_size_(SeparatorForKey(key).size()) {}
+
+Http2HeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other)
+    : storage_(other.storage_),
+      fragments_(std::move(other.fragments_)),
+      pair_(std::move(other.pair_)),
+      size_(other.size_),
+      separator_size_(other.separator_size_) {}
+
+Http2HeaderBlock::HeaderValue& Http2HeaderBlock::HeaderValue::operator=(
+    HeaderValue&& other) {
+  storage_ = other.storage_;
+  fragments_ = std::move(other.fragments_);
+  pair_ = std::move(other.pair_);
+  size_ = other.size_;
+  separator_size_ = other.separator_size_;
+  return *this;
+}
+
+void Http2HeaderBlock::HeaderValue::set_storage(SpdyHeaderStorage* storage) {
+  storage_ = storage;
+}
+
+Http2HeaderBlock::HeaderValue::~HeaderValue() = default;
+
+absl::string_view Http2HeaderBlock::HeaderValue::ConsolidatedValue() const {
+  if (fragments_.empty()) {
+    return absl::string_view();
+  }
+  if (fragments_.size() > 1) {
+    fragments_ = {
+        storage_->WriteFragments(fragments_, SeparatorForKey(pair_.first))};
+  }
+  return fragments_[0];
+}
+
+void Http2HeaderBlock::HeaderValue::Append(absl::string_view fragment) {
+  size_ += (fragment.size() + separator_size_);
+  fragments_.push_back(fragment);
+}
+
+const std::pair<absl::string_view, absl::string_view>&
+Http2HeaderBlock::HeaderValue::as_pair() const {
+  pair_.second = ConsolidatedValue();
+  return pair_;
+}
+
+Http2HeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {}
+
+Http2HeaderBlock::iterator::iterator(const iterator& other) = default;
+
+Http2HeaderBlock::iterator::~iterator() = default;
+
+Http2HeaderBlock::ValueProxy::ValueProxy(
+    Http2HeaderBlock* block,
+    Http2HeaderBlock::MapType::iterator lookup_result,
+    const absl::string_view key,
+    size_t* spdy_header_block_value_size)
+    : block_(block),
+      lookup_result_(lookup_result),
+      key_(key),
+      spdy_header_block_value_size_(spdy_header_block_value_size),
+      valid_(true) {}
+
+Http2HeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other)
+    : block_(other.block_),
+      lookup_result_(other.lookup_result_),
+      key_(other.key_),
+      spdy_header_block_value_size_(other.spdy_header_block_value_size_),
+      valid_(true) {
+  other.valid_ = false;
+}
+
+Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=(
+    Http2HeaderBlock::ValueProxy&& other) {
+  block_ = other.block_;
+  lookup_result_ = other.lookup_result_;
+  key_ = other.key_;
+  valid_ = true;
+  other.valid_ = false;
+  spdy_header_block_value_size_ = other.spdy_header_block_value_size_;
+  return *this;
+}
+
+Http2HeaderBlock::ValueProxy::~ValueProxy() {
+  // If the ValueProxy is destroyed while lookup_result_ == block_->end(),
+  // the assignment operator was never used, and the block's SpdyHeaderStorage
+  // can reclaim the memory used by the key. This makes lookup-only access to
+  // Http2HeaderBlock through operator[] memory-neutral.
+  if (valid_ && lookup_result_ == block_->map_.end()) {
+    block_->storage_.Rewind(key_);
+  }
+}
+
+Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=(
+    absl::string_view value) {
+  *spdy_header_block_value_size_ += value.size();
+  SpdyHeaderStorage* storage = &block_->storage_;
+  if (lookup_result_ == block_->map_.end()) {
+    QUICHE_DVLOG(1) << "Inserting: (" << key_ << ", " << value << ")";
+    lookup_result_ =
+        block_->map_
+            .emplace(std::make_pair(
+                key_, HeaderValue(storage, key_, storage->Write(value))))
+            .first;
+  } else {
+    QUICHE_DVLOG(1) << "Updating key: " << key_ << " with value: " << value;
+    *spdy_header_block_value_size_ -= lookup_result_->second.SizeEstimate();
+    lookup_result_->second = HeaderValue(storage, key_, storage->Write(value));
+  }
+  return *this;
+}
+
+bool Http2HeaderBlock::ValueProxy::operator==(absl::string_view value) const {
+  if (lookup_result_ == block_->map_.end()) {
+    return false;
+  } else {
+    return value == lookup_result_->second.value();
+  }
+}
+
+std::string Http2HeaderBlock::ValueProxy::as_string() const {
+  if (lookup_result_ == block_->map_.end()) {
+    return "";
+  } else {
+    return std::string(lookup_result_->second.value());
+  }
+}
+
+Http2HeaderBlock::Http2HeaderBlock() : map_(kInitialMapBuckets) {}
+
+Http2HeaderBlock::Http2HeaderBlock(Http2HeaderBlock&& other)
+    : map_(kInitialMapBuckets) {
+  map_.swap(other.map_);
+  storage_ = std::move(other.storage_);
+  for (auto& p : map_) {
+    p.second.set_storage(&storage_);
+  }
+  key_size_ = other.key_size_;
+  value_size_ = other.value_size_;
+}
+
+Http2HeaderBlock::~Http2HeaderBlock() = default;
+
+Http2HeaderBlock& Http2HeaderBlock::operator=(Http2HeaderBlock&& other) {
+  map_.swap(other.map_);
+  storage_ = std::move(other.storage_);
+  for (auto& p : map_) {
+    p.second.set_storage(&storage_);
+  }
+  key_size_ = other.key_size_;
+  value_size_ = other.value_size_;
+  return *this;
+}
+
+Http2HeaderBlock Http2HeaderBlock::Clone() const {
+  Http2HeaderBlock copy;
+  for (const auto& p : *this) {
+    copy.AppendHeader(p.first, p.second);
+  }
+  return copy;
+}
+
+bool Http2HeaderBlock::operator==(const Http2HeaderBlock& other) const {
+  return size() == other.size() && std::equal(begin(), end(), other.begin());
+}
+
+bool Http2HeaderBlock::operator!=(const Http2HeaderBlock& other) const {
+  return !(operator==(other));
+}
+
+std::string Http2HeaderBlock::DebugString() const {
+  if (empty()) {
+    return "{}";
+  }
+
+  std::string output = "\n{\n";
+  for (auto it = begin(); it != end(); ++it) {
+    absl::StrAppend(&output, "  ", it->first, " ", it->second, "\n");
+  }
+  absl::StrAppend(&output, "}\n");
+  return output;
+}
+
+void Http2HeaderBlock::erase(absl::string_view key) {
+  auto iter = map_.find(key);
+  if (iter != map_.end()) {
+    QUICHE_DVLOG(1) << "Erasing header with name: " << key;
+    key_size_ -= key.size();
+    value_size_ -= iter->second.SizeEstimate();
+    map_.erase(iter);
+  }
+}
+
+void Http2HeaderBlock::clear() {
+  key_size_ = 0;
+  value_size_ = 0;
+  map_.clear();
+  storage_.Clear();
+}
+
+void Http2HeaderBlock::insert(const Http2HeaderBlock::value_type& value) {
+  // TODO(birenroy): Write new value in place of old value, if it fits.
+  value_size_ += value.second.size();
+
+  auto iter = map_.find(value.first);
+  if (iter == map_.end()) {
+    QUICHE_DVLOG(1) << "Inserting: (" << value.first << ", " << value.second
+                    << ")";
+    AppendHeader(value.first, value.second);
+  } else {
+    QUICHE_DVLOG(1) << "Updating key: " << iter->first
+                    << " with value: " << value.second;
+    value_size_ -= iter->second.SizeEstimate();
+    iter->second =
+        HeaderValue(&storage_, iter->first, storage_.Write(value.second));
+  }
+}
+
+Http2HeaderBlock::ValueProxy Http2HeaderBlock::operator[](
+    const absl::string_view key) {
+  QUICHE_DVLOG(2) << "Operator[] saw key: " << key;
+  absl::string_view out_key;
+  auto iter = map_.find(key);
+  if (iter == map_.end()) {
+    // We write the key first, to assure that the ValueProxy has a
+    // reference to a valid absl::string_view in its operator=.
+    out_key = WriteKey(key);
+    QUICHE_DVLOG(2) << "Key written as: " << std::hex
+                    << static_cast<const void*>(key.data()) << ", " << std::dec
+                    << key.size();
+  } else {
+    out_key = iter->first;
+  }
+  return ValueProxy(this, iter, out_key, &value_size_);
+}
+
+void Http2HeaderBlock::AppendValueOrAddHeader(const absl::string_view key,
+                                              const absl::string_view value) {
+  value_size_ += value.size();
+
+  auto iter = map_.find(key);
+  if (iter == map_.end()) {
+    QUICHE_DVLOG(1) << "Inserting: (" << key << ", " << value << ")";
+
+    AppendHeader(key, value);
+    return;
+  }
+  QUICHE_DVLOG(1) << "Updating key: " << iter->first
+                  << "; appending value: " << value;
+  value_size_ += SeparatorForKey(key).size();
+  iter->second.Append(storage_.Write(value));
+}
+
+void Http2HeaderBlock::AppendHeader(const absl::string_view key,
+                                    const absl::string_view value) {
+  auto backed_key = WriteKey(key);
+  map_.emplace(std::make_pair(
+      backed_key, HeaderValue(&storage_, backed_key, storage_.Write(value))));
+}
+
+absl::string_view Http2HeaderBlock::WriteKey(const absl::string_view key) {
+  key_size_ += key.size();
+  return storage_.Write(key);
+}
+
+size_t Http2HeaderBlock::bytes_allocated() const {
+  return storage_.bytes_allocated();
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_header_block.h b/quiche/spdy/core/spdy_header_block.h
new file mode 100644
index 0000000..795d350
--- /dev/null
+++ b/quiche/spdy/core/spdy_header_block.h
@@ -0,0 +1,295 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
+#define QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
+
+#include <stddef.h>
+
+#include <functional>
+#include <list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_header_storage.h"
+
+namespace spdy {
+
+namespace test {
+class Http2HeaderBlockPeer;
+class ValueProxyPeer;
+}  // namespace test
+
+#ifndef SPDY_HEADER_DEBUG
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define SPDY_HEADER_DEBUG 1
+#else  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define SPDY_HEADER_DEBUG 0
+#endif  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#endif  // SPDY_HEADER_DEBUG
+
+// This class provides a key-value map that can be used to store SPDY header
+// names and values. This data structure preserves insertion order.
+//
+// Under the hood, this data structure uses large, contiguous blocks of memory
+// to store names and values. Lookups may be performed with absl::string_view
+// keys, and values are returned as absl::string_views (via ValueProxy, below).
+// Value absl::string_views are valid as long as the Http2HeaderBlock exists;
+// allocated memory is never freed until Http2HeaderBlock's destruction.
+//
+// This implementation does not make much of an effort to minimize wasted space.
+// It's expected that keys are rarely deleted from a Http2HeaderBlock.
+class QUICHE_EXPORT_PRIVATE Http2HeaderBlock {
+ private:
+  // Stores a list of value fragments that can be joined later with a
+  // key-dependent separator.
+  class QUICHE_EXPORT_PRIVATE HeaderValue {
+   public:
+    HeaderValue(SpdyHeaderStorage* storage,
+                absl::string_view key,
+                absl::string_view initial_value);
+
+    // Moves are allowed.
+    HeaderValue(HeaderValue&& other);
+    HeaderValue& operator=(HeaderValue&& other);
+
+    void set_storage(SpdyHeaderStorage* storage);
+
+    // Copies are not.
+    HeaderValue(const HeaderValue& other) = delete;
+    HeaderValue& operator=(const HeaderValue& other) = delete;
+
+    ~HeaderValue();
+
+    // Consumes at most |fragment.size()| bytes of memory.
+    void Append(absl::string_view fragment);
+
+    absl::string_view value() const { return as_pair().second; }
+    const std::pair<absl::string_view, absl::string_view>& as_pair() const;
+
+    // Size estimate including separators. Used when keys are erased from
+    // Http2HeaderBlock.
+    size_t SizeEstimate() const { return size_; }
+
+   private:
+    // May allocate a large contiguous region of memory to hold the concatenated
+    // fragments and separators.
+    absl::string_view ConsolidatedValue() const;
+
+    mutable SpdyHeaderStorage* storage_;
+    mutable std::vector<absl::string_view> fragments_;
+    // The first element is the key; the second is the consolidated value.
+    mutable std::pair<absl::string_view, absl::string_view> pair_;
+    size_t size_ = 0;
+    size_t separator_size_ = 0;
+  };
+
+  typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
+                                      quiche::StringPieceCaseHash,
+                                      quiche::StringPieceCaseEqual>
+      MapType;
+
+ public:
+  typedef std::pair<absl::string_view, absl::string_view> value_type;
+
+  // Provides iteration over a sequence of std::pair<absl::string_view,
+  // absl::string_view>, even though the underlying MapType::value_type is
+  // different. Dereferencing the iterator will result in memory allocation for
+  // multi-value headers.
+  class QUICHE_EXPORT_PRIVATE iterator {
+   public:
+    // The following type definitions fulfill the requirements for iterator
+    // implementations.
+    typedef std::pair<absl::string_view, absl::string_view> value_type;
+    typedef value_type& reference;
+    typedef value_type* pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef MapType::iterator::difference_type difference_type;
+
+    // In practice, this iterator only offers access to const value_type.
+    typedef const value_type& const_reference;
+    typedef const value_type* const_pointer;
+
+    explicit iterator(MapType::const_iterator it);
+    iterator(const iterator& other);
+    ~iterator();
+
+    // This will result in memory allocation if the value consists of multiple
+    // fragments.
+    const_reference operator*() const {
+#if SPDY_HEADER_DEBUG
+      QUICHE_CHECK(!dereference_forbidden_);
+#endif  // SPDY_HEADER_DEBUG
+      return it_->second.as_pair();
+    }
+
+    const_pointer operator->() const { return &(this->operator*()); }
+    bool operator==(const iterator& it) const { return it_ == it.it_; }
+    bool operator!=(const iterator& it) const { return !(*this == it); }
+
+    iterator& operator++() {
+      it_++;
+      return *this;
+    }
+
+    iterator operator++(int) {
+      auto ret = *this;
+      this->operator++();
+      return ret;
+    }
+
+#if SPDY_HEADER_DEBUG
+    void forbid_dereference() { dereference_forbidden_ = true; }
+#endif  // SPDY_HEADER_DEBUG
+
+   private:
+    MapType::const_iterator it_;
+#if SPDY_HEADER_DEBUG
+    bool dereference_forbidden_ = false;
+#endif  // SPDY_HEADER_DEBUG
+  };
+  typedef iterator const_iterator;
+
+  Http2HeaderBlock();
+  Http2HeaderBlock(const Http2HeaderBlock& other) = delete;
+  Http2HeaderBlock(Http2HeaderBlock&& other);
+  ~Http2HeaderBlock();
+
+  Http2HeaderBlock& operator=(const Http2HeaderBlock& other) = delete;
+  Http2HeaderBlock& operator=(Http2HeaderBlock&& other);
+  Http2HeaderBlock Clone() const;
+
+  bool operator==(const Http2HeaderBlock& other) const;
+  bool operator!=(const Http2HeaderBlock& other) const;
+
+  // Provides a human readable multi-line representation of the stored header
+  // keys and values.
+  std::string DebugString() const;
+
+  iterator begin() { return wrap_iterator(map_.begin()); }
+  iterator end() { return wrap_iterator(map_.end()); }
+  const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
+  const_iterator end() const { return wrap_const_iterator(map_.end()); }
+  bool empty() const { return map_.empty(); }
+  size_t size() const { return map_.size(); }
+  iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
+  const_iterator find(absl::string_view key) const {
+    return wrap_const_iterator(map_.find(key));
+  }
+  bool contains(absl::string_view key) const { return find(key) != end(); }
+  void erase(absl::string_view key);
+
+  // Clears both our MapType member and the memory used to hold headers.
+  void clear();
+
+  // The next few methods copy data into our backing storage.
+
+  // If key already exists in the block, replaces the value of that key. Else
+  // adds a new header to the end of the block.
+  void insert(const value_type& value);
+
+  // If a header with the key is already present, then append the value to the
+  // existing header value, NUL ("\0") separated unless the key is cookie, in
+  // which case the separator is "; ".
+  // If there is no such key, a new header with the key and value is added.
+  void AppendValueOrAddHeader(const absl::string_view key,
+                              const absl::string_view value);
+
+  // This object provides automatic conversions that allow Http2HeaderBlock to
+  // be nearly a drop-in replacement for
+  // SpdyLinkedHashMap<std::string, std::string>.
+  // It reads data from or writes data to a SpdyHeaderStorage.
+  class QUICHE_EXPORT_PRIVATE ValueProxy {
+   public:
+    ~ValueProxy();
+
+    // Moves are allowed.
+    ValueProxy(ValueProxy&& other);
+    ValueProxy& operator=(ValueProxy&& other);
+
+    // Copies are not.
+    ValueProxy(const ValueProxy& other) = delete;
+    ValueProxy& operator=(const ValueProxy& other) = delete;
+
+    // Assignment modifies the underlying Http2HeaderBlock.
+    ValueProxy& operator=(absl::string_view value);
+
+    // Provides easy comparison against absl::string_view.
+    bool operator==(absl::string_view value) const;
+
+    std::string as_string() const;
+
+   private:
+    friend class Http2HeaderBlock;
+    friend class test::ValueProxyPeer;
+
+    ValueProxy(Http2HeaderBlock* block,
+               Http2HeaderBlock::MapType::iterator lookup_result,
+               const absl::string_view key,
+               size_t* spdy_header_block_value_size);
+
+    Http2HeaderBlock* block_;
+    Http2HeaderBlock::MapType::iterator lookup_result_;
+    absl::string_view key_;
+    size_t* spdy_header_block_value_size_;
+    bool valid_;
+  };
+
+  // Allows either lookup or mutation of the value associated with a key.
+  ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);
+
+  size_t TotalBytesUsed() const { return key_size_ + value_size_; }
+
+ private:
+  friend class test::Http2HeaderBlockPeer;
+
+  inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
+#if SPDY_HEADER_DEBUG
+    iterator outer_iterator(inner_iterator);
+    if (inner_iterator == map_.end()) {
+      outer_iterator.forbid_dereference();
+    }
+    return outer_iterator;
+#else  // SPDY_HEADER_DEBUG
+    return iterator(inner_iterator);
+#endif  // SPDY_HEADER_DEBUG
+  }
+
+  inline const_iterator wrap_const_iterator(
+      MapType::const_iterator inner_iterator) const {
+#if SPDY_HEADER_DEBUG
+    const_iterator outer_iterator(inner_iterator);
+    if (inner_iterator == map_.end()) {
+      outer_iterator.forbid_dereference();
+    }
+    return outer_iterator;
+#else  // SPDY_HEADER_DEBUG
+    return iterator(inner_iterator);
+#endif  // SPDY_HEADER_DEBUG
+  }
+
+  void AppendHeader(const absl::string_view key, const absl::string_view value);
+  absl::string_view WriteKey(const absl::string_view key);
+  size_t bytes_allocated() const;
+
+  // absl::string_views held by |map_| point to memory owned by |storage_|.
+  MapType map_;
+  SpdyHeaderStorage storage_;
+
+  size_t key_size_ = 0;
+  size_t value_size_ = 0;
+};
+
+// TODO(b/156770486): Remove this alias when the rename is complete.
+using SpdyHeaderBlock = Http2HeaderBlock;
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
diff --git a/quiche/spdy/core/spdy_header_block_test.cc b/quiche/spdy/core/spdy_header_block_test.cc
new file mode 100644
index 0000000..7b266c6
--- /dev/null
+++ b/quiche/spdy/core/spdy_header_block_test.cc
@@ -0,0 +1,279 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_header_block.h"
+
+#include <memory>
+#include <utility>
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+using ::testing::ElementsAre;
+
+namespace spdy {
+namespace test {
+
+class ValueProxyPeer {
+ public:
+  static absl::string_view key(Http2HeaderBlock::ValueProxy* p) {
+    return p->key_;
+  }
+};
+
+std::pair<absl::string_view, absl::string_view> Pair(absl::string_view k,
+                                                     absl::string_view v) {
+  return std::make_pair(k, v);
+}
+
+// This test verifies that Http2HeaderBlock behaves correctly when empty.
+TEST(Http2HeaderBlockTest, EmptyBlock) {
+  Http2HeaderBlock block;
+  EXPECT_TRUE(block.empty());
+  EXPECT_EQ(0u, block.size());
+  EXPECT_EQ(block.end(), block.find("foo"));
+  EXPECT_FALSE(block.contains("foo"));
+  EXPECT_TRUE(block.end() == block.begin());
+
+  // Should have no effect.
+  block.erase("bar");
+}
+
+TEST(Http2HeaderBlockTest, KeyMemoryReclaimedOnLookup) {
+  Http2HeaderBlock block;
+  absl::string_view copied_key1;
+  {
+    auto proxy1 = block["some key name"];
+    copied_key1 = ValueProxyPeer::key(&proxy1);
+  }
+  absl::string_view copied_key2;
+  {
+    auto proxy2 = block["some other key name"];
+    copied_key2 = ValueProxyPeer::key(&proxy2);
+  }
+  // Because proxy1 was never used to modify the block, the memory used for the
+  // key could be reclaimed and used for the second call to operator[].
+  // Therefore, we expect the pointers of the two absl::string_views to be
+  // equal.
+  EXPECT_EQ(copied_key1.data(), copied_key2.data());
+
+  {
+    auto proxy1 = block["some key name"];
+    block["some other key name"] = "some value";
+  }
+  // Nothing should blow up when proxy1 is destructed, and we should be able to
+  // modify and access the Http2HeaderBlock.
+  block["key"] = "value";
+  EXPECT_EQ("value", block["key"]);
+  EXPECT_EQ("some value", block["some other key name"]);
+  EXPECT_TRUE(block.find("some key name") == block.end());
+}
+
+// This test verifies that headers can be set in a variety of ways.
+TEST(Http2HeaderBlockTest, AddHeaders) {
+  Http2HeaderBlock block;
+  block["foo"] = std::string(300, 'x');
+  block["bar"] = "baz";
+  block["qux"] = "qux1";
+  block["qux"] = "qux2";
+  block.insert(std::make_pair("key", "value"));
+
+  EXPECT_EQ(Pair("foo", std::string(300, 'x')), *block.find("foo"));
+  EXPECT_EQ("baz", block["bar"]);
+  std::string qux("qux");
+  EXPECT_EQ("qux2", block[qux]);
+  ASSERT_NE(block.end(), block.find("key"));
+  ASSERT_TRUE(block.contains("key"));
+  EXPECT_EQ(Pair("key", "value"), *block.find("key"));
+
+  block.erase("key");
+  EXPECT_EQ(block.end(), block.find("key"));
+}
+
+// This test verifies that Http2HeaderBlock can be copied using Clone().
+TEST(Http2HeaderBlockTest, CopyBlocks) {
+  Http2HeaderBlock block1;
+  block1["foo"] = std::string(300, 'x');
+  block1["bar"] = "baz";
+  block1.insert(std::make_pair("qux", "qux1"));
+
+  Http2HeaderBlock block2 = block1.Clone();
+  Http2HeaderBlock block3(block1.Clone());
+
+  EXPECT_EQ(block1, block2);
+  EXPECT_EQ(block1, block3);
+}
+
+TEST(Http2HeaderBlockTest, Equality) {
+  // Test equality and inequality operators.
+  Http2HeaderBlock block1;
+  block1["foo"] = "bar";
+
+  Http2HeaderBlock block2;
+  block2["foo"] = "bar";
+
+  Http2HeaderBlock block3;
+  block3["baz"] = "qux";
+
+  EXPECT_EQ(block1, block2);
+  EXPECT_NE(block1, block3);
+
+  block2["baz"] = "qux";
+  EXPECT_NE(block1, block2);
+}
+
+Http2HeaderBlock ReturnTestHeaderBlock() {
+  Http2HeaderBlock block;
+  block["foo"] = "bar";
+  block.insert(std::make_pair("foo2", "baz"));
+  return block;
+}
+
+// Test that certain methods do not crash on moved-from instances.
+TEST(Http2HeaderBlockTest, MovedFromIsValid) {
+  Http2HeaderBlock block1;
+  block1["foo"] = "bar";
+
+  Http2HeaderBlock block2(std::move(block1));
+  EXPECT_THAT(block2, ElementsAre(Pair("foo", "bar")));
+
+  block1["baz"] = "qux";  // NOLINT  testing post-move behavior
+
+  Http2HeaderBlock block3(std::move(block1));
+
+  block1["foo"] = "bar";  // NOLINT  testing post-move behavior
+
+  Http2HeaderBlock block4(std::move(block1));
+
+  block1.clear();  // NOLINT  testing post-move behavior
+  EXPECT_TRUE(block1.empty());
+
+  block1["foo"] = "bar";
+  EXPECT_THAT(block1, ElementsAre(Pair("foo", "bar")));
+
+  Http2HeaderBlock block5 = ReturnTestHeaderBlock();
+  block5.AppendValueOrAddHeader("foo", "bar2");
+  EXPECT_THAT(block5, ElementsAre(Pair("foo", std::string("bar\0bar2", 8)),
+                                  Pair("foo2", "baz")));
+}
+
+// This test verifies that headers can be appended to no matter how they were
+// added originally.
+TEST(Http2HeaderBlockTest, AppendHeaders) {
+  Http2HeaderBlock block;
+  block["foo"] = "foo";
+  block.AppendValueOrAddHeader("foo", "bar");
+  EXPECT_EQ(Pair("foo", std::string("foo\0bar", 7)), *block.find("foo"));
+
+  block.insert(std::make_pair("foo", "baz"));
+  EXPECT_EQ("baz", block["foo"]);
+  EXPECT_EQ(Pair("foo", "baz"), *block.find("foo"));
+
+  // Try all four methods of adding an entry.
+  block["cookie"] = "key1=value1";
+  block.AppendValueOrAddHeader("h1", "h1v1");
+  block.insert(std::make_pair("h2", "h2v1"));
+
+  block.AppendValueOrAddHeader("h3", "h3v2");
+  block.AppendValueOrAddHeader("h2", "h2v2");
+  block.AppendValueOrAddHeader("h1", "h1v2");
+  block.AppendValueOrAddHeader("cookie", "key2=value2");
+
+  block.AppendValueOrAddHeader("cookie", "key3=value3");
+  block.AppendValueOrAddHeader("h1", "h1v3");
+  block.AppendValueOrAddHeader("h2", "h2v3");
+  block.AppendValueOrAddHeader("h3", "h3v3");
+  block.AppendValueOrAddHeader("h4", "singleton");
+
+  EXPECT_EQ("key1=value1; key2=value2; key3=value3", block["cookie"]);
+  EXPECT_EQ("baz", block["foo"]);
+  EXPECT_EQ(std::string("h1v1\0h1v2\0h1v3", 14), block["h1"]);
+  EXPECT_EQ(std::string("h2v1\0h2v2\0h2v3", 14), block["h2"]);
+  EXPECT_EQ(std::string("h3v2\0h3v3", 9), block["h3"]);
+  EXPECT_EQ("singleton", block["h4"]);
+}
+
+TEST(Http2HeaderBlockTest, CompareValueToStringPiece) {
+  Http2HeaderBlock block;
+  block["foo"] = "foo";
+  block.AppendValueOrAddHeader("foo", "bar");
+  const auto& val = block["foo"];
+  const char expected[] = "foo\0bar";
+  EXPECT_TRUE(absl::string_view(expected, 7) == val);
+  EXPECT_TRUE(val == absl::string_view(expected, 7));
+  EXPECT_FALSE(absl::string_view(expected, 3) == val);
+  EXPECT_FALSE(val == absl::string_view(expected, 3));
+  const char not_expected[] = "foo\0barextra";
+  EXPECT_FALSE(absl::string_view(not_expected, 12) == val);
+  EXPECT_FALSE(val == absl::string_view(not_expected, 12));
+
+  const auto& val2 = block["foo2"];
+  EXPECT_FALSE(absl::string_view(expected, 7) == val2);
+  EXPECT_FALSE(val2 == absl::string_view(expected, 7));
+  EXPECT_FALSE(absl::string_view("") == val2);
+  EXPECT_FALSE(val2 == absl::string_view(""));
+}
+
+// This test demonstrates that the Http2HeaderBlock data structure does not
+// place any limitations on the characters present in the header names.
+TEST(Http2HeaderBlockTest, UpperCaseNames) {
+  Http2HeaderBlock block;
+  block["Foo"] = "foo";
+  block.AppendValueOrAddHeader("Foo", "bar");
+  EXPECT_NE(block.end(), block.find("foo"));
+  EXPECT_EQ(Pair("Foo", std::string("foo\0bar", 7)), *block.find("Foo"));
+
+  // The map is case insensitive, so updating "foo" modifies the entry
+  // previously added.
+  block.AppendValueOrAddHeader("foo", "baz");
+  EXPECT_THAT(block,
+              ElementsAre(Pair("Foo", std::string("foo\0bar\0baz", 11))));
+}
+
+namespace {
+size_t Http2HeaderBlockSize(const Http2HeaderBlock& block) {
+  size_t size = 0;
+  for (const auto& pair : block) {
+    size += pair.first.size() + pair.second.size();
+  }
+  return size;
+}
+}  // namespace
+
+// Tests Http2HeaderBlock SizeEstimate().
+TEST(Http2HeaderBlockTest, TotalBytesUsed) {
+  Http2HeaderBlock block;
+  const size_t value_size = 300;
+  block["foo"] = std::string(value_size, 'x');
+  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+  block.insert(std::make_pair("key", std::string(value_size, 'x')));
+  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+  block.AppendValueOrAddHeader("abc", std::string(value_size, 'x'));
+  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+
+  // Replace value for existing key.
+  block["foo"] = std::string(value_size, 'x');
+  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+  block.insert(std::make_pair("key", std::string(value_size, 'x')));
+  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+  // Add value for existing key.
+  block.AppendValueOrAddHeader("abc", std::string(value_size, 'x'));
+  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+
+  // Copies/clones Http2HeaderBlock.
+  size_t block_size = block.TotalBytesUsed();
+  Http2HeaderBlock block_copy = std::move(block);
+  EXPECT_EQ(block_size, block_copy.TotalBytesUsed());
+
+  // Erases key.
+  block_copy.erase("foo");
+  EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
+  block_copy.erase("key");
+  EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
+  block_copy.erase("abc");
+  EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_header_storage.cc b/quiche/spdy/core/spdy_header_storage.cc
new file mode 100644
index 0000000..8fab19d
--- /dev/null
+++ b/quiche/spdy/core/spdy_header_storage.cc
@@ -0,0 +1,60 @@
+#include "quiche/spdy/core/spdy_header_storage.h"
+
+#include <cstring>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+namespace {
+
+// SpdyHeaderStorage allocates blocks of this size by default.
+const size_t kDefaultStorageBlockSize = 2048;
+
+}  // namespace
+
+SpdyHeaderStorage::SpdyHeaderStorage() : arena_(kDefaultStorageBlockSize) {}
+
+absl::string_view SpdyHeaderStorage::Write(const absl::string_view s) {
+  return absl::string_view(arena_.Memdup(s.data(), s.size()), s.size());
+}
+
+void SpdyHeaderStorage::Rewind(const absl::string_view s) {
+  arena_.Free(const_cast<char*>(s.data()), s.size());
+}
+
+absl::string_view SpdyHeaderStorage::WriteFragments(
+    const std::vector<absl::string_view>& fragments,
+    absl::string_view separator) {
+  if (fragments.empty()) {
+    return absl::string_view();
+  }
+  size_t total_size = separator.size() * (fragments.size() - 1);
+  for (const absl::string_view& fragment : fragments) {
+    total_size += fragment.size();
+  }
+  char* dst = arena_.Alloc(total_size);
+  size_t written = Join(dst, fragments, separator);
+  QUICHE_DCHECK_EQ(written, total_size);
+  return absl::string_view(dst, total_size);
+}
+
+size_t Join(char* dst,
+            const std::vector<absl::string_view>& fragments,
+            absl::string_view separator) {
+  if (fragments.empty()) {
+    return 0;
+  }
+  auto* original_dst = dst;
+  auto it = fragments.begin();
+  memcpy(dst, it->data(), it->size());
+  dst += it->size();
+  for (++it; it != fragments.end(); ++it) {
+    memcpy(dst, separator.data(), separator.size());
+    dst += separator.size();
+    memcpy(dst, it->data(), it->size());
+    dst += it->size();
+  }
+  return dst - original_dst;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_header_storage.h b/quiche/spdy/core/spdy_header_storage.h
new file mode 100644
index 0000000..42b1b9f
--- /dev/null
+++ b/quiche/spdy/core/spdy_header_storage.h
@@ -0,0 +1,59 @@
+#ifndef QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_
+#define QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_simple_arena.h"
+
+namespace spdy {
+
+// This class provides a backing store for absl::string_views. It previously
+// used custom allocation logic, but now uses an UnsafeArena instead. It has the
+// property that absl::string_views that refer to data in SpdyHeaderStorage are
+// never invalidated until the SpdyHeaderStorage is deleted or Clear() is
+// called.
+//
+// Write operations always append to the last block. If there is not enough
+// space to perform the write, a new block is allocated, and any unused space
+// is wasted.
+class QUICHE_EXPORT_PRIVATE SpdyHeaderStorage {
+ public:
+  SpdyHeaderStorage();
+
+  SpdyHeaderStorage(const SpdyHeaderStorage&) = delete;
+  SpdyHeaderStorage& operator=(const SpdyHeaderStorage&) = delete;
+
+  SpdyHeaderStorage(SpdyHeaderStorage&& other) = default;
+  SpdyHeaderStorage& operator=(SpdyHeaderStorage&& other) = default;
+
+  absl::string_view Write(absl::string_view s);
+
+  // If |s| points to the most recent allocation from arena_, the arena will
+  // reclaim the memory. Otherwise, this method is a no-op.
+  void Rewind(absl::string_view s);
+
+  void Clear() { arena_.Reset(); }
+
+  // Given a list of fragments and a separator, writes the fragments joined by
+  // the separator to a contiguous region of memory. Returns a absl::string_view
+  // pointing to the region of memory.
+  absl::string_view WriteFragments(
+      const std::vector<absl::string_view>& fragments,
+      absl::string_view separator);
+
+  size_t bytes_allocated() const { return arena_.status().bytes_allocated(); }
+
+ private:
+  SpdySimpleArena arena_;
+};
+
+// Writes |fragments| to |dst|, joined by |separator|. |dst| must be large
+// enough to hold the result. Returns the number of bytes written.
+QUICHE_EXPORT_PRIVATE size_t
+Join(char* dst,
+     const std::vector<absl::string_view>& fragments,
+     absl::string_view separator);
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_
diff --git a/quiche/spdy/core/spdy_header_storage_test.cc b/quiche/spdy/core/spdy_header_storage_test.cc
new file mode 100644
index 0000000..474b01e
--- /dev/null
+++ b/quiche/spdy/core/spdy_header_storage_test.cc
@@ -0,0 +1,35 @@
+#include "quiche/spdy/core/spdy_header_storage.h"
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+namespace test {
+
+TEST(JoinTest, JoinEmpty) {
+  std::vector<absl::string_view> empty;
+  absl::string_view separator = ", ";
+  char buf[10] = "";
+  size_t written = Join(buf, empty, separator);
+  EXPECT_EQ(0u, written);
+}
+
+TEST(JoinTest, JoinOne) {
+  std::vector<absl::string_view> v = {"one"};
+  absl::string_view separator = ", ";
+  char buf[15];
+  size_t written = Join(buf, v, separator);
+  EXPECT_EQ(3u, written);
+  EXPECT_EQ("one", absl::string_view(buf, written));
+}
+
+TEST(JoinTest, JoinMultiple) {
+  std::vector<absl::string_view> v = {"one", "two", "three"};
+  absl::string_view separator = ", ";
+  char buf[15];
+  size_t written = Join(buf, v, separator);
+  EXPECT_EQ(15u, written);
+  EXPECT_EQ("one, two, three", absl::string_view(buf, written));
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_headers_handler_interface.h b/quiche/spdy/core/spdy_headers_handler_interface.h
new file mode 100644
index 0000000..00f95da
--- /dev/null
+++ b/quiche/spdy/core/spdy_headers_handler_interface.h
@@ -0,0 +1,39 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
+#define QUICHE_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
+
+#include <stddef.h>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace spdy {
+
+// This interface defines how an object that accepts header data should behave.
+// It is used by both SpdyHeadersBlockParser and HpackDecoder.
+class QUICHE_EXPORT_PRIVATE SpdyHeadersHandlerInterface {
+ public:
+  virtual ~SpdyHeadersHandlerInterface() {}
+
+  // A callback method which notifies when the parser starts handling a new
+  // header block. Will only be called once per block, even if it extends into
+  // CONTINUATION frames.
+  virtual void OnHeaderBlockStart() = 0;
+
+  // A callback method which notifies on a header key value pair. Multiple
+  // values for a given key will be emitted as multiple calls to OnHeader.
+  virtual void OnHeader(absl::string_view key, absl::string_view value) = 0;
+
+  // A callback method which notifies when the parser finishes handling a
+  // header block (i.e. the containing frame has the END_HEADERS flag set).
+  // Also indicates the total number of bytes in this block.
+  virtual void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                                size_t compressed_header_bytes) = 0;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
diff --git a/spdy/core/spdy_intrusive_list.h b/quiche/spdy/core/spdy_intrusive_list.h
similarity index 100%
rename from spdy/core/spdy_intrusive_list.h
rename to quiche/spdy/core/spdy_intrusive_list.h
diff --git a/quiche/spdy/core/spdy_intrusive_list_test.cc b/quiche/spdy/core/spdy_intrusive_list_test.cc
new file mode 100644
index 0000000..f52313f
--- /dev/null
+++ b/quiche/spdy/core/spdy_intrusive_list_test.cc
@@ -0,0 +1,427 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_intrusive_list.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <list>
+#include <string>
+#include <utility>
+
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+namespace test {
+
+struct ListId2 {};
+
+struct TestItem : public SpdyIntrusiveLink<TestItem>,
+                  public SpdyIntrusiveLink<TestItem, ListId2> {
+  int n;
+};
+typedef SpdyIntrusiveList<TestItem> TestList;
+typedef std::list<TestItem*> CanonicalList;
+
+void swap(TestItem &a, TestItem &b) {
+  using std::swap;
+  swap(a.n, b.n);
+}
+
+class IntrusiveListTest : public QuicheTest {
+ protected:
+  void CheckLists() {
+    CheckLists(l1, ll1);
+    if (QuicheTest::HasFailure())
+      return;
+    CheckLists(l2, ll2);
+  }
+
+  void CheckLists(const TestList &list_a, const CanonicalList &list_b) {
+    ASSERT_EQ(list_a.size(), list_b.size());
+    TestList::const_iterator it_a = list_a.begin();
+    CanonicalList::const_iterator it_b = list_b.begin();
+    while (it_a != list_a.end()) {
+      EXPECT_EQ(&*it_a++, *it_b++);
+    }
+    EXPECT_EQ(list_a.end(), it_a);
+    EXPECT_EQ(list_b.end(), it_b);
+  }
+
+  void PrepareLists(int num_elems_1, int num_elems_2 = 0) {
+    FillLists(&l1, &ll1, e, num_elems_1);
+    FillLists(&l2, &ll2, e + num_elems_1, num_elems_2);
+  }
+
+  void FillLists(TestList *list_a, CanonicalList *list_b, TestItem *elems,
+                 int num_elems) {
+    list_a->clear();
+    list_b->clear();
+    for (int i = 0; i < num_elems; ++i) {
+      list_a->push_back(elems + i);
+      list_b->push_back(elems + i);
+    }
+    CheckLists(*list_a, *list_b);
+  }
+
+  TestItem e[10];
+  TestList l1, l2;
+  CanonicalList ll1, ll2;
+};
+
+TEST(NewIntrusiveListTest, Basic) {
+  TestList list1;
+
+  EXPECT_EQ(sizeof(SpdyIntrusiveLink<TestItem>), sizeof(void*) * 2);
+
+  for (int i = 0; i < 10; ++i) {
+    TestItem *e = new TestItem;
+    e->n = i;
+    list1.push_front(e);
+  }
+  EXPECT_EQ(list1.size(), 10u);
+
+  // Verify we can reverse a list because we defined swap for TestItem.
+  std::reverse(list1.begin(), list1.end());
+  EXPECT_EQ(list1.size(), 10u);
+
+  // Check both const and non-const forward iteration.
+  const TestList& clist1 = list1;
+  int i = 0;
+  TestList::iterator iter = list1.begin();
+  for (;
+       iter != list1.end();
+       ++iter, ++i) {
+    EXPECT_EQ(iter->n, i);
+  }
+  EXPECT_EQ(iter, clist1.end());
+  EXPECT_NE(iter, clist1.begin());
+  i = 0;
+  iter = list1.begin();
+  for (;
+       iter != list1.end();
+       ++iter, ++i) {
+    EXPECT_EQ(iter->n, i);
+  }
+  EXPECT_EQ(iter, clist1.end());
+  EXPECT_NE(iter, clist1.begin());
+
+  EXPECT_EQ(list1.front().n, 0);
+  EXPECT_EQ(list1.back().n, 9);
+
+  // Verify we can swap 2 lists.
+  TestList list2;
+  list2.swap(list1);
+  EXPECT_EQ(list1.size(), 0u);
+  EXPECT_EQ(list2.size(), 10u);
+
+  // Check both const and non-const reverse iteration.
+  const TestList& clist2 = list2;
+  TestList::reverse_iterator riter = list2.rbegin();
+  i = 9;
+  for (;
+       riter != list2.rend();
+       ++riter, --i) {
+    EXPECT_EQ(riter->n, i);
+  }
+  EXPECT_EQ(riter, clist2.rend());
+  EXPECT_NE(riter, clist2.rbegin());
+
+  riter = list2.rbegin();
+  i = 9;
+  for (;
+       riter != list2.rend();
+       ++riter, --i) {
+    EXPECT_EQ(riter->n, i);
+  }
+  EXPECT_EQ(riter, clist2.rend());
+  EXPECT_NE(riter, clist2.rbegin());
+
+  while (!list2.empty()) {
+    TestItem *e = &list2.front();
+    list2.pop_front();
+    delete e;
+  }
+}
+
+TEST(NewIntrusiveListTest, Erase) {
+  TestList l;
+  TestItem *e[10];
+
+  // Create a list with 10 items.
+  for (int i = 0; i < 10; ++i) {
+    e[i] = new TestItem;
+    l.push_front(e[i]);
+  }
+
+  // Test that erase works.
+  for (int i = 0; i < 10; ++i) {
+    EXPECT_EQ(l.size(), (10u - i));
+
+    TestList::iterator iter = l.erase(e[i]);
+    EXPECT_NE(iter, TestList::iterator(e[i]));
+
+    EXPECT_EQ(l.size(), (10u - i - 1));
+    delete e[i];
+  }
+}
+
+TEST(NewIntrusiveListTest, Insert) {
+  TestList l;
+  TestList::iterator iter = l.end();
+  TestItem *e[10];
+
+  // Create a list with 10 items.
+  for (int i = 9; i >= 0; --i) {
+    e[i] = new TestItem;
+    iter = l.insert(iter, e[i]);
+    EXPECT_EQ(&(*iter), e[i]);
+  }
+
+  EXPECT_EQ(l.size(), 10u);
+
+  // Verify insertion order.
+  iter = l.begin();
+  for (TestItem *item : e) {
+    EXPECT_EQ(&(*iter), item);
+    iter = l.erase(item);
+    delete item;
+  }
+}
+
+TEST(NewIntrusiveListTest, Move) {
+  // Move contructible.
+
+  {  // Move-construct from an empty list.
+    TestList src;
+    TestList dest(std::move(src));
+    EXPECT_TRUE(dest.empty());
+  }
+
+  {  // Move-construct from a single item list.
+    TestItem e;
+    TestList src;
+    src.push_front(&e);
+
+    TestList dest(std::move(src));
+    EXPECT_TRUE(src.empty());  // NOLINT bugprone-use-after-move
+    ASSERT_THAT(dest.size(), 1);
+    EXPECT_THAT(&dest.front(), &e);
+    EXPECT_THAT(&dest.back(), &e);
+  }
+
+  {  // Move-construct from a list with multiple items.
+    TestItem items[10];
+    TestList src;
+    for (TestItem &e : items) src.push_back(&e);
+
+    TestList dest(std::move(src));
+    EXPECT_TRUE(src.empty());  // NOLINT bugprone-use-after-move
+    // Verify the items on the destination list.
+    ASSERT_THAT(dest.size(), 10);
+    int i = 0;
+    for (TestItem &e : dest) {
+      EXPECT_THAT(&e, &items[i++]) << " for index " << i;
+    }
+  }
+}
+
+TEST(NewIntrusiveListTest, StaticInsertErase) {
+  TestList l;
+  TestItem e[2];
+  TestList::iterator i = l.begin();
+  TestList::insert(i, &e[0]);
+  TestList::insert(&e[0], &e[1]);
+  TestList::erase(&e[0]);
+  TestList::erase(TestList::iterator(&e[1]));
+  EXPECT_TRUE(l.empty());
+}
+
+TEST_F(IntrusiveListTest, Splice) {
+  // We verify that the contents of this secondary list aren't affected by any
+  // of the splices.
+  SpdyIntrusiveList<TestItem, ListId2> secondary_list;
+  for (int i  = 0; i < 3; ++i) {
+    secondary_list.push_back(&e[i]);
+  }
+
+  // Test the basic cases:
+  // - The lists range from 0 to 2 elements.
+  // - The insertion point ranges from begin() to end()
+  // - The transfered range has multiple sizes and locations in the source.
+  for (int l1_count = 0; l1_count < 3; ++l1_count) {
+    for (int l2_count = 0; l2_count < 3; ++l2_count) {
+      for (int pos = 0; pos <= l1_count; ++pos) {
+        for (int first = 0; first <= l2_count; ++first) {
+          for (int last = first; last <= l2_count; ++last) {
+            PrepareLists(l1_count, l2_count);
+
+            l1.splice(std::next(l1.begin(), pos), std::next(l2.begin(), first),
+                      std::next(l2.begin(), last));
+            ll1.splice(std::next(ll1.begin(), pos), ll2,
+                       std::next(ll2.begin(), first),
+                       std::next(ll2.begin(), last));
+
+            CheckLists();
+
+            ASSERT_EQ(3u, secondary_list.size());
+            for (int i = 0; i < 3; ++i) {
+              EXPECT_EQ(&e[i], &*std::next(secondary_list.begin(), i));
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+// Build up a set of classes which form "challenging" type hierarchies to use
+// with an SpdyIntrusiveList.
+struct BaseLinkId {};
+struct DerivedLinkId {};
+
+struct AbstractBase : public SpdyIntrusiveLink<AbstractBase, BaseLinkId> {
+  virtual ~AbstractBase() = 0;
+  virtual std::string name() { return "AbstractBase"; }
+};
+AbstractBase::~AbstractBase() {}
+struct DerivedClass : public SpdyIntrusiveLink<DerivedClass, DerivedLinkId>,
+                      public AbstractBase {
+  ~DerivedClass() override {}
+  std::string name() override { return "DerivedClass"; }
+};
+struct VirtuallyDerivedBaseClass : public virtual AbstractBase {
+  ~VirtuallyDerivedBaseClass() override = 0;
+  std::string name() override { return "VirtuallyDerivedBaseClass"; }
+};
+VirtuallyDerivedBaseClass::~VirtuallyDerivedBaseClass() {}
+struct VirtuallyDerivedClassA
+    : public SpdyIntrusiveLink<VirtuallyDerivedClassA, DerivedLinkId>,
+      public virtual VirtuallyDerivedBaseClass {
+  ~VirtuallyDerivedClassA() override {}
+  std::string name() override { return "VirtuallyDerivedClassA"; }
+};
+struct NonceClass {
+  virtual ~NonceClass() {}
+  int data_;
+};
+struct VirtuallyDerivedClassB
+    : public SpdyIntrusiveLink<VirtuallyDerivedClassB, DerivedLinkId>,
+      public virtual NonceClass,
+      public virtual VirtuallyDerivedBaseClass {
+  ~VirtuallyDerivedClassB() override {}
+  std::string name() override { return "VirtuallyDerivedClassB"; }
+};
+struct VirtuallyDerivedClassC
+    : public SpdyIntrusiveLink<VirtuallyDerivedClassC, DerivedLinkId>,
+      public virtual AbstractBase,
+      public virtual NonceClass,
+      public virtual VirtuallyDerivedBaseClass {
+  ~VirtuallyDerivedClassC() override {}
+  std::string name() override { return "VirtuallyDerivedClassC"; }
+};
+
+// Test for multiple layers between the element type and the link.
+namespace templated_base_link {
+template <typename T> struct AbstractBase : public SpdyIntrusiveLink<T> {
+  virtual ~AbstractBase() = 0;
+};
+template <typename T> AbstractBase<T>::~AbstractBase() {}
+struct DerivedClass : public AbstractBase<DerivedClass> {
+  int n;
+};
+}
+
+TEST(NewIntrusiveListTest, HandleInheritanceHierarchies) {
+  {
+    SpdyIntrusiveList<DerivedClass, DerivedLinkId> list;
+    DerivedClass elements[2];
+    EXPECT_TRUE(list.empty());
+    list.push_back(&elements[0]);
+    EXPECT_EQ(1u, list.size());
+    list.push_back(&elements[1]);
+    EXPECT_EQ(2u, list.size());
+    list.pop_back();
+    EXPECT_EQ(1u, list.size());
+    list.pop_back();
+    EXPECT_TRUE(list.empty());
+  }
+  {
+    SpdyIntrusiveList<VirtuallyDerivedClassA, DerivedLinkId> list;
+    VirtuallyDerivedClassA elements[2];
+    EXPECT_TRUE(list.empty());
+    list.push_back(&elements[0]);
+    EXPECT_EQ(1u, list.size());
+    list.push_back(&elements[1]);
+    EXPECT_EQ(2u, list.size());
+    list.pop_back();
+    EXPECT_EQ(1u, list.size());
+    list.pop_back();
+    EXPECT_TRUE(list.empty());
+  }
+  {
+    SpdyIntrusiveList<VirtuallyDerivedClassC, DerivedLinkId> list;
+    VirtuallyDerivedClassC elements[2];
+    EXPECT_TRUE(list.empty());
+    list.push_back(&elements[0]);
+    EXPECT_EQ(1u, list.size());
+    list.push_back(&elements[1]);
+    EXPECT_EQ(2u, list.size());
+    list.pop_back();
+    EXPECT_EQ(1u, list.size());
+    list.pop_back();
+    EXPECT_TRUE(list.empty());
+  }
+  {
+    SpdyIntrusiveList<AbstractBase, BaseLinkId> list;
+    DerivedClass d1;
+    VirtuallyDerivedClassA d2;
+    VirtuallyDerivedClassB d3;
+    VirtuallyDerivedClassC d4;
+    EXPECT_TRUE(list.empty());
+    list.push_back(&d1);
+    EXPECT_EQ(1u, list.size());
+    list.push_back(&d2);
+    EXPECT_EQ(2u, list.size());
+    list.push_back(&d3);
+    EXPECT_EQ(3u, list.size());
+    list.push_back(&d4);
+    EXPECT_EQ(4u, list.size());
+    SpdyIntrusiveList<AbstractBase, BaseLinkId>::iterator it = list.begin();
+    EXPECT_EQ("DerivedClass",           (it++)->name());
+    EXPECT_EQ("VirtuallyDerivedClassA", (it++)->name());
+    EXPECT_EQ("VirtuallyDerivedClassB", (it++)->name());
+    EXPECT_EQ("VirtuallyDerivedClassC", (it++)->name());
+  }
+  {
+    SpdyIntrusiveList<templated_base_link::DerivedClass> list;
+    templated_base_link::DerivedClass elements[2];
+    EXPECT_TRUE(list.empty());
+    list.push_back(&elements[0]);
+    EXPECT_EQ(1u, list.size());
+    list.push_back(&elements[1]);
+    EXPECT_EQ(2u, list.size());
+    list.pop_back();
+    EXPECT_EQ(1u, list.size());
+    list.pop_back();
+    EXPECT_TRUE(list.empty());
+  }
+}
+
+class IntrusiveListTagTypeTest : public QuicheTest {
+ protected:
+  struct Tag {};
+  class Element : public SpdyIntrusiveLink<Element, Tag> {};
+};
+
+TEST_F(IntrusiveListTagTypeTest, TagTypeListID) {
+  SpdyIntrusiveList<Element, Tag> list;
+  {
+    Element e;
+    list.push_back(&e);
+  }
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_no_op_visitor.cc b/quiche/spdy/core/spdy_no_op_visitor.cc
new file mode 100644
index 0000000..d1ab89b
--- /dev/null
+++ b/quiche/spdy/core/spdy_no_op_visitor.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_no_op_visitor.h"
+
+#include <type_traits>
+
+namespace spdy {
+
+SpdyNoOpVisitor::SpdyNoOpVisitor() {
+  static_assert(std::is_abstract<SpdyNoOpVisitor>::value == false,
+                "Need to update SpdyNoOpVisitor.");
+}
+SpdyNoOpVisitor::~SpdyNoOpVisitor() = default;
+
+SpdyHeadersHandlerInterface* SpdyNoOpVisitor::OnHeaderFrameStart(
+    SpdyStreamId /*stream_id*/) {
+  return this;
+}
+
+bool SpdyNoOpVisitor::OnUnknownFrame(SpdyStreamId /*stream_id*/,
+                                     uint8_t /*frame_type*/) {
+  return true;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_no_op_visitor.h b/quiche/spdy/core/spdy_no_op_visitor.h
new file mode 100644
index 0000000..3adc02b
--- /dev/null
+++ b/quiche/spdy/core/spdy_no_op_visitor.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// SpdyNoOpVisitor implements several of the visitor and handler interfaces
+// to make it easier to write tests that need to provide instances. Other
+// interfaces can be added as needed.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
+#define QUICHE_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace spdy {
+
+class SpdyNoOpVisitor : public SpdyFramerVisitorInterface,
+                        public SpdyFramerDebugVisitorInterface,
+                        public SpdyHeadersHandlerInterface {
+ public:
+  SpdyNoOpVisitor();
+  ~SpdyNoOpVisitor() override;
+
+  // SpdyFramerVisitorInterface methods:
+  void OnError(http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
+               std::string /*detailed_error*/) override {}
+  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
+      SpdyStreamId stream_id) override;
+  void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override {}
+  void OnDataFrameHeader(SpdyStreamId /*stream_id*/,
+                         size_t /*length*/,
+                         bool /*fin*/) override {}
+  void OnStreamFrameData(SpdyStreamId /*stream_id*/,
+                         const char* /*data*/,
+                         size_t /*len*/) override {}
+  void OnStreamEnd(SpdyStreamId /*stream_id*/) override {}
+  void OnStreamPadding(SpdyStreamId /*stream_id*/, size_t /*len*/) override {}
+  void OnRstStream(SpdyStreamId /*stream_id*/,
+                   SpdyErrorCode /*error_code*/) override {}
+  void OnSetting(SpdySettingsId /*id*/, uint32_t /*value*/) override {}
+  void OnPing(SpdyPingId /*unique_id*/, bool /*is_ack*/) override {}
+  void OnSettingsEnd() override {}
+  void OnSettingsAck() override {}
+  void OnGoAway(SpdyStreamId /*last_accepted_stream_id*/,
+                SpdyErrorCode /*error_code*/) override {}
+  void OnHeaders(SpdyStreamId /*stream_id*/,
+                 bool /*has_priority*/,
+                 int /*weight*/,
+                 SpdyStreamId /*parent_stream_id*/,
+                 bool /*exclusive*/,
+                 bool /*fin*/,
+                 bool /*end*/) override {}
+  void OnWindowUpdate(SpdyStreamId /*stream_id*/,
+                      int /*delta_window_size*/) override {}
+  void OnPushPromise(SpdyStreamId /*stream_id*/,
+                     SpdyStreamId /*promised_stream_id*/,
+                     bool /*end*/) override {}
+  void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
+  void OnAltSvc(SpdyStreamId /*stream_id*/,
+                absl::string_view /*origin*/,
+                const SpdyAltSvcWireFormat::AlternativeServiceVector&
+                /*altsvc_vector*/) override {}
+  void OnPriority(SpdyStreamId /*stream_id*/,
+                  SpdyStreamId /*parent_stream_id*/,
+                  int /*weight*/,
+                  bool /*exclusive*/) override {}
+  void OnPriorityUpdate(SpdyStreamId /*prioritized_stream_id*/,
+                        absl::string_view /*priority_field_value*/) override {}
+  bool OnUnknownFrame(SpdyStreamId /*stream_id*/,
+                      uint8_t /*frame_type*/) override;
+
+  // SpdyFramerDebugVisitorInterface methods:
+  void OnSendCompressedFrame(SpdyStreamId /*stream_id*/,
+                             SpdyFrameType /*type*/,
+                             size_t /*payload_len*/,
+                             size_t /*frame_len*/) override {}
+  void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
+                                SpdyFrameType /*type*/,
+                                size_t /*frame_len*/) override {}
+
+  // SpdyHeadersHandlerInterface methods:
+  void OnHeaderBlockStart() override {}
+  void OnHeader(absl::string_view /*key*/,
+                absl::string_view /*value*/) override {}
+  void OnHeaderBlockEnd(size_t /* uncompressed_header_bytes */,
+                        size_t /* compressed_header_bytes */) override {}
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
diff --git a/quiche/spdy/core/spdy_pinnable_buffer_piece.cc b/quiche/spdy/core/spdy_pinnable_buffer_piece.cc
new file mode 100644
index 0000000..4448d90
--- /dev/null
+++ b/quiche/spdy/core/spdy_pinnable_buffer_piece.cc
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_pinnable_buffer_piece.h"
+
+#include <new>
+
+namespace spdy {
+
+SpdyPinnableBufferPiece::SpdyPinnableBufferPiece()
+    : buffer_(nullptr), length_(0) {}
+
+SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() = default;
+
+void SpdyPinnableBufferPiece::Pin() {
+  if (!storage_ && buffer_ != nullptr && length_ != 0) {
+    storage_.reset(new char[length_]);
+    std::copy(buffer_, buffer_ + length_, storage_.get());
+    buffer_ = storage_.get();
+  }
+}
+
+void SpdyPinnableBufferPiece::Swap(SpdyPinnableBufferPiece* other) {
+  size_t length = length_;
+  length_ = other->length_;
+  other->length_ = length;
+
+  const char* buffer = buffer_;
+  buffer_ = other->buffer_;
+  other->buffer_ = buffer;
+
+  storage_.swap(other->storage_);
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_pinnable_buffer_piece.h b/quiche/spdy/core/spdy_pinnable_buffer_piece.h
new file mode 100644
index 0000000..1b1bd32
--- /dev/null
+++ b/quiche/spdy/core/spdy_pinnable_buffer_piece.h
@@ -0,0 +1,53 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
+#define QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace spdy {
+
+class SpdyPrefixedBufferReader;
+
+// Helper class of SpdyPrefixedBufferReader.
+// Represents a piece of consumed buffer which may (or may not) own its
+// underlying storage. Users may "pin" the buffer at a later time to ensure
+// a SpdyPinnableBufferPiece owns and retains storage of the buffer.
+struct QUICHE_EXPORT_PRIVATE SpdyPinnableBufferPiece {
+ public:
+  SpdyPinnableBufferPiece();
+  ~SpdyPinnableBufferPiece();
+
+  const char* buffer() const { return buffer_; }
+
+  explicit operator absl::string_view() const {
+    return absl::string_view(buffer_, length_);
+  }
+
+  // Allocates and copies the buffer to internal storage.
+  void Pin();
+
+  bool IsPinned() const { return storage_ != nullptr; }
+
+  // Swaps buffers, including internal storage, with |other|.
+  void Swap(SpdyPinnableBufferPiece* other);
+
+ private:
+  friend class SpdyPrefixedBufferReader;
+
+  const char* buffer_;
+  size_t length_;
+  // Null iff |buffer_| isn't pinned.
+  std::unique_ptr<char[]> storage_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
diff --git a/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc b/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc
new file mode 100644
index 0000000..f35f9b0
--- /dev/null
+++ b/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc
@@ -0,0 +1,80 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_pinnable_buffer_piece.h"
+
+#include <string>
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/spdy_prefixed_buffer_reader.h"
+
+namespace spdy {
+
+namespace test {
+
+class SpdyPinnableBufferPieceTest : public QuicheTest {
+ protected:
+  SpdyPrefixedBufferReader Build(const std::string& prefix,
+                                 const std::string& suffix) {
+    prefix_ = prefix;
+    suffix_ = suffix;
+    return SpdyPrefixedBufferReader(prefix_.data(), prefix_.length(),
+                                    suffix_.data(), suffix_.length());
+  }
+  std::string prefix_, suffix_;
+};
+
+TEST_F(SpdyPinnableBufferPieceTest, Pin) {
+  SpdyPrefixedBufferReader reader = Build("foobar", "");
+  SpdyPinnableBufferPiece piece;
+  EXPECT_TRUE(reader.ReadN(6, &piece));
+
+  // Piece points to underlying prefix storage.
+  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
+  EXPECT_FALSE(piece.IsPinned());
+  EXPECT_EQ(prefix_.data(), piece.buffer());
+
+  piece.Pin();
+
+  // Piece now points to allocated storage.
+  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
+  EXPECT_TRUE(piece.IsPinned());
+  EXPECT_NE(prefix_.data(), piece.buffer());
+
+  // Pinning again has no effect.
+  const char* buffer = piece.buffer();
+  piece.Pin();
+  EXPECT_EQ(buffer, piece.buffer());
+}
+
+TEST_F(SpdyPinnableBufferPieceTest, Swap) {
+  SpdyPrefixedBufferReader reader = Build("foobar", "");
+  SpdyPinnableBufferPiece piece1, piece2;
+  EXPECT_TRUE(reader.ReadN(4, &piece1));
+  EXPECT_TRUE(reader.ReadN(2, &piece2));
+
+  piece1.Pin();
+
+  EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece1));
+  EXPECT_TRUE(piece1.IsPinned());
+  EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece2));
+  EXPECT_FALSE(piece2.IsPinned());
+
+  piece1.Swap(&piece2);
+
+  EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece1));
+  EXPECT_FALSE(piece1.IsPinned());
+  EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece2));
+  EXPECT_TRUE(piece2.IsPinned());
+
+  SpdyPinnableBufferPiece empty;
+  piece2.Swap(&empty);
+
+  EXPECT_EQ(absl::string_view(""), absl::string_view(piece2));
+  EXPECT_FALSE(piece2.IsPinned());
+}
+
+}  // namespace test
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_prefixed_buffer_reader.cc b/quiche/spdy/core/spdy_prefixed_buffer_reader.cc
new file mode 100644
index 0000000..8b5a252
--- /dev/null
+++ b/quiche/spdy/core/spdy_prefixed_buffer_reader.cc
@@ -0,0 +1,84 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_prefixed_buffer_reader.h"
+
+#include <new>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+
+SpdyPrefixedBufferReader::SpdyPrefixedBufferReader(const char* prefix,
+                                                   size_t prefix_length,
+                                                   const char* suffix,
+                                                   size_t suffix_length)
+    : prefix_(prefix),
+      suffix_(suffix),
+      prefix_length_(prefix_length),
+      suffix_length_(suffix_length) {}
+
+size_t SpdyPrefixedBufferReader::Available() {
+  return prefix_length_ + suffix_length_;
+}
+
+bool SpdyPrefixedBufferReader::ReadN(size_t count, char* out) {
+  if (Available() < count) {
+    return false;
+  }
+
+  if (prefix_length_ >= count) {
+    // Read is fully satisfied by the prefix.
+    std::copy(prefix_, prefix_ + count, out);
+    prefix_ += count;
+    prefix_length_ -= count;
+    return true;
+  } else if (prefix_length_ != 0) {
+    // Read is partially satisfied by the prefix.
+    out = std::copy(prefix_, prefix_ + prefix_length_, out);
+    count -= prefix_length_;
+    prefix_length_ = 0;
+    // Fallthrough to suffix read.
+  }
+  QUICHE_DCHECK(suffix_length_ >= count);
+  // Read is satisfied by the suffix.
+  std::copy(suffix_, suffix_ + count, out);
+  suffix_ += count;
+  suffix_length_ -= count;
+  return true;
+}
+
+bool SpdyPrefixedBufferReader::ReadN(size_t count,
+                                     SpdyPinnableBufferPiece* out) {
+  if (Available() < count) {
+    return false;
+  }
+
+  out->storage_.reset();
+  out->length_ = count;
+
+  if (prefix_length_ >= count) {
+    // Read is fully satisfied by the prefix.
+    out->buffer_ = prefix_;
+    prefix_ += count;
+    prefix_length_ -= count;
+    return true;
+  } else if (prefix_length_ != 0) {
+    // Read is only partially satisfied by the prefix. We need to allocate
+    // contiguous storage as the read spans the prefix & suffix.
+    out->storage_.reset(new char[count]);
+    out->buffer_ = out->storage_.get();
+    ReadN(count, out->storage_.get());
+    return true;
+  } else {
+    QUICHE_DCHECK(suffix_length_ >= count);
+    // Read is fully satisfied by the suffix.
+    out->buffer_ = suffix_;
+    suffix_ += count;
+    suffix_length_ -= count;
+    return true;
+  }
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_prefixed_buffer_reader.h b/quiche/spdy/core/spdy_prefixed_buffer_reader.h
new file mode 100644
index 0000000..8f51f86
--- /dev/null
+++ b/quiche/spdy/core/spdy_prefixed_buffer_reader.h
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
+#define QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
+
+#include <stddef.h>
+
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/spdy/core/spdy_pinnable_buffer_piece.h"
+
+namespace spdy {
+
+// Reader class which simplifies reading contiguously from
+// from a disjoint buffer prefix & suffix.
+class QUICHE_EXPORT_PRIVATE SpdyPrefixedBufferReader {
+ public:
+  SpdyPrefixedBufferReader(const char* prefix,
+                           size_t prefix_length,
+                           const char* suffix,
+                           size_t suffix_length);
+
+  // Returns number of bytes available to be read.
+  size_t Available();
+
+  // Reads |count| bytes, copying into |*out|. Returns true on success,
+  // false if not enough bytes were available.
+  bool ReadN(size_t count, char* out);
+
+  // Reads |count| bytes, returned in |*out|. Returns true on success,
+  // false if not enough bytes were available.
+  bool ReadN(size_t count, SpdyPinnableBufferPiece* out);
+
+ private:
+  const char* prefix_;
+  const char* suffix_;
+
+  size_t prefix_length_;
+  size_t suffix_length_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
diff --git a/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc b/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc
new file mode 100644
index 0000000..c2bf25c
--- /dev/null
+++ b/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc
@@ -0,0 +1,131 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_prefixed_buffer_reader.h"
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+
+namespace test {
+
+using testing::ElementsAreArray;
+
+class SpdyPrefixedBufferReaderTest : public QuicheTest {
+ protected:
+  SpdyPrefixedBufferReader Build(const std::string& prefix,
+                                 const std::string& suffix) {
+    prefix_ = prefix;
+    suffix_ = suffix;
+    return SpdyPrefixedBufferReader(prefix_.data(), prefix_.length(),
+                                    suffix_.data(), suffix_.length());
+  }
+  std::string prefix_, suffix_;
+};
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadRawFromPrefix) {
+  SpdyPrefixedBufferReader reader = Build("foobar", "");
+  EXPECT_EQ(6u, reader.Available());
+
+  char buffer[] = "123456";
+  EXPECT_FALSE(reader.ReadN(10, buffer));  // Not enough buffer.
+  EXPECT_TRUE(reader.ReadN(6, buffer));
+  EXPECT_THAT(buffer, ElementsAreArray("foobar"));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromPrefix) {
+  SpdyPrefixedBufferReader reader = Build("foobar", "");
+  EXPECT_EQ(6u, reader.Available());
+
+  SpdyPinnableBufferPiece piece;
+  EXPECT_FALSE(reader.ReadN(10, &piece));  // Not enough buffer.
+  EXPECT_TRUE(reader.ReadN(6, &piece));
+  EXPECT_FALSE(piece.IsPinned());
+  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadRawFromSuffix) {
+  SpdyPrefixedBufferReader reader = Build("", "foobar");
+  EXPECT_EQ(6u, reader.Available());
+
+  char buffer[] = "123456";
+  EXPECT_FALSE(reader.ReadN(10, buffer));  // Not enough buffer.
+  EXPECT_TRUE(reader.ReadN(6, buffer));
+  EXPECT_THAT(buffer, ElementsAreArray("foobar"));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromSuffix) {
+  SpdyPrefixedBufferReader reader = Build("", "foobar");
+  EXPECT_EQ(6u, reader.Available());
+
+  SpdyPinnableBufferPiece piece;
+  EXPECT_FALSE(reader.ReadN(10, &piece));  // Not enough buffer.
+  EXPECT_TRUE(reader.ReadN(6, &piece));
+  EXPECT_FALSE(piece.IsPinned());
+  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadRawSpanning) {
+  SpdyPrefixedBufferReader reader = Build("foob", "ar");
+  EXPECT_EQ(6u, reader.Available());
+
+  char buffer[] = "123456";
+  EXPECT_FALSE(reader.ReadN(10, buffer));  // Not enough buffer.
+  EXPECT_TRUE(reader.ReadN(6, buffer));
+  EXPECT_THAT(buffer, ElementsAreArray("foobar"));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceSpanning) {
+  SpdyPrefixedBufferReader reader = Build("foob", "ar");
+  EXPECT_EQ(6u, reader.Available());
+
+  SpdyPinnableBufferPiece piece;
+  EXPECT_FALSE(reader.ReadN(10, &piece));  // Not enough buffer.
+  EXPECT_TRUE(reader.ReadN(6, &piece));
+  EXPECT_TRUE(piece.IsPinned());
+  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+TEST_F(SpdyPrefixedBufferReaderTest, ReadMixed) {
+  SpdyPrefixedBufferReader reader = Build("abcdef", "hijkl");
+  EXPECT_EQ(11u, reader.Available());
+
+  char buffer[] = "1234";
+  SpdyPinnableBufferPiece piece;
+
+  EXPECT_TRUE(reader.ReadN(3, buffer));
+  EXPECT_THAT(buffer, ElementsAreArray("abc4"));
+  EXPECT_EQ(8u, reader.Available());
+
+  EXPECT_TRUE(reader.ReadN(2, buffer));
+  EXPECT_THAT(buffer, ElementsAreArray("dec4"));
+  EXPECT_EQ(6u, reader.Available());
+
+  EXPECT_TRUE(reader.ReadN(3, &piece));
+  EXPECT_EQ(absl::string_view("fhi"), absl::string_view(piece));
+  EXPECT_TRUE(piece.IsPinned());
+  EXPECT_EQ(3u, reader.Available());
+
+  EXPECT_TRUE(reader.ReadN(2, &piece));
+  EXPECT_EQ(absl::string_view("jk"), absl::string_view(piece));
+  EXPECT_FALSE(piece.IsPinned());
+  EXPECT_EQ(1u, reader.Available());
+
+  EXPECT_TRUE(reader.ReadN(1, buffer));
+  EXPECT_THAT(buffer, ElementsAreArray("lec4"));
+  EXPECT_EQ(0u, reader.Available());
+}
+
+}  // namespace test
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_protocol.cc b/quiche/spdy/core/spdy_protocol.cc
new file mode 100644
index 0000000..7588806
--- /dev/null
+++ b/quiche/spdy/core/spdy_protocol.cc
@@ -0,0 +1,643 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_protocol.h"
+
+#include <limits>
+#include <ostream>
+
+#include "absl/strings/str_cat.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
+
+namespace spdy {
+
+const char* const kHttp2ConnectionHeaderPrefix =
+    "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
+
+std::ostream& operator<<(std::ostream& out, SpdyKnownSettingsId id) {
+  return out << static_cast<SpdySettingsId>(id);
+}
+
+std::ostream& operator<<(std::ostream& out, SpdyFrameType frame_type) {
+  return out << SerializeFrameType(frame_type);
+}
+
+SpdyPriority ClampSpdy3Priority(SpdyPriority priority) {
+  static_assert(std::numeric_limits<SpdyPriority>::min() == kV3HighestPriority,
+                "The value of given priority shouldn't be smaller than highest "
+                "priority. Check this invariant explicitly.");
+  if (priority > kV3LowestPriority) {
+    QUICHE_BUG(spdy_bug_22_1)
+        << "Invalid priority: " << static_cast<int>(priority);
+    return kV3LowestPriority;
+  }
+  return priority;
+}
+
+int ClampHttp2Weight(int weight) {
+  if (weight < kHttp2MinStreamWeight) {
+    QUICHE_BUG(spdy_bug_22_2) << "Invalid weight: " << weight;
+    return kHttp2MinStreamWeight;
+  }
+  if (weight > kHttp2MaxStreamWeight) {
+    QUICHE_BUG(spdy_bug_22_3) << "Invalid weight: " << weight;
+    return kHttp2MaxStreamWeight;
+  }
+  return weight;
+}
+
+int Spdy3PriorityToHttp2Weight(SpdyPriority priority) {
+  priority = ClampSpdy3Priority(priority);
+  const float kSteps = 255.9f / 7.f;
+  return static_cast<int>(kSteps * (7.f - priority)) + 1;
+}
+
+SpdyPriority Http2WeightToSpdy3Priority(int weight) {
+  weight = ClampHttp2Weight(weight);
+  const float kSteps = 255.9f / 7.f;
+  return static_cast<SpdyPriority>(7.f - (weight - 1) / kSteps);
+}
+
+bool IsDefinedFrameType(uint8_t frame_type_field) {
+  switch (static_cast<SpdyFrameType>(frame_type_field)) {
+    case SpdyFrameType::DATA:
+      return true;
+    case SpdyFrameType::HEADERS:
+      return true;
+    case SpdyFrameType::PRIORITY:
+      return true;
+    case SpdyFrameType::RST_STREAM:
+      return true;
+    case SpdyFrameType::SETTINGS:
+      return true;
+    case SpdyFrameType::PUSH_PROMISE:
+      return true;
+    case SpdyFrameType::PING:
+      return true;
+    case SpdyFrameType::GOAWAY:
+      return true;
+    case SpdyFrameType::WINDOW_UPDATE:
+      return true;
+    case SpdyFrameType::CONTINUATION:
+      return true;
+    case SpdyFrameType::ALTSVC:
+      return true;
+    case SpdyFrameType::PRIORITY_UPDATE:
+      return true;
+    case SpdyFrameType::ACCEPT_CH:
+      return true;
+  }
+  return false;
+}
+
+SpdyFrameType ParseFrameType(uint8_t frame_type_field) {
+  QUICHE_BUG_IF(spdy_bug_22_4, !IsDefinedFrameType(frame_type_field))
+      << "Frame type not defined: " << static_cast<int>(frame_type_field);
+  return static_cast<SpdyFrameType>(frame_type_field);
+}
+
+uint8_t SerializeFrameType(SpdyFrameType frame_type) {
+  return static_cast<uint8_t>(frame_type);
+}
+
+bool IsValidHTTP2FrameStreamId(SpdyStreamId current_frame_stream_id,
+                               SpdyFrameType frame_type_field) {
+  if (current_frame_stream_id == 0) {
+    switch (frame_type_field) {
+      case SpdyFrameType::DATA:
+      case SpdyFrameType::HEADERS:
+      case SpdyFrameType::PRIORITY:
+      case SpdyFrameType::RST_STREAM:
+      case SpdyFrameType::CONTINUATION:
+      case SpdyFrameType::PUSH_PROMISE:
+        // These frame types must specify a stream
+        return false;
+      default:
+        return true;
+    }
+  } else {
+    switch (frame_type_field) {
+      case SpdyFrameType::GOAWAY:
+      case SpdyFrameType::SETTINGS:
+      case SpdyFrameType::PING:
+        // These frame types must not specify a stream
+        return false;
+      default:
+        return true;
+    }
+  }
+}
+
+const char* FrameTypeToString(SpdyFrameType frame_type) {
+  switch (frame_type) {
+    case SpdyFrameType::DATA:
+      return "DATA";
+    case SpdyFrameType::RST_STREAM:
+      return "RST_STREAM";
+    case SpdyFrameType::SETTINGS:
+      return "SETTINGS";
+    case SpdyFrameType::PING:
+      return "PING";
+    case SpdyFrameType::GOAWAY:
+      return "GOAWAY";
+    case SpdyFrameType::HEADERS:
+      return "HEADERS";
+    case SpdyFrameType::WINDOW_UPDATE:
+      return "WINDOW_UPDATE";
+    case SpdyFrameType::PUSH_PROMISE:
+      return "PUSH_PROMISE";
+    case SpdyFrameType::CONTINUATION:
+      return "CONTINUATION";
+    case SpdyFrameType::PRIORITY:
+      return "PRIORITY";
+    case SpdyFrameType::ALTSVC:
+      return "ALTSVC";
+    case SpdyFrameType::PRIORITY_UPDATE:
+      return "PRIORITY_UPDATE";
+    case SpdyFrameType::ACCEPT_CH:
+      return "ACCEPT_CH";
+  }
+  return "UNKNOWN_FRAME_TYPE";
+}
+
+bool ParseSettingsId(SpdySettingsId wire_setting_id,
+                     SpdyKnownSettingsId* setting_id) {
+  if (wire_setting_id != SETTINGS_EXPERIMENT_SCHEDULER &&
+      (wire_setting_id < SETTINGS_MIN || wire_setting_id > SETTINGS_MAX)) {
+    return false;
+  }
+
+  *setting_id = static_cast<SpdyKnownSettingsId>(wire_setting_id);
+  // This switch ensures that the casted value is valid. The default case is
+  // explicitly omitted to have compile-time guarantees that new additions to
+  // |SpdyKnownSettingsId| must also be handled here.
+  switch (*setting_id) {
+    case SETTINGS_HEADER_TABLE_SIZE:
+    case SETTINGS_ENABLE_PUSH:
+    case SETTINGS_MAX_CONCURRENT_STREAMS:
+    case SETTINGS_INITIAL_WINDOW_SIZE:
+    case SETTINGS_MAX_FRAME_SIZE:
+    case SETTINGS_MAX_HEADER_LIST_SIZE:
+    case SETTINGS_ENABLE_CONNECT_PROTOCOL:
+    case SETTINGS_DEPRECATE_HTTP2_PRIORITIES:
+    case SETTINGS_EXPERIMENT_SCHEDULER:
+      return true;
+  }
+  return false;
+}
+
+std::string SettingsIdToString(SpdySettingsId id) {
+  SpdyKnownSettingsId known_id;
+  if (!ParseSettingsId(id, &known_id)) {
+    return absl::StrCat("SETTINGS_UNKNOWN_", absl::Hex(uint32_t{id}));
+  }
+
+  switch (known_id) {
+    case SETTINGS_HEADER_TABLE_SIZE:
+      return "SETTINGS_HEADER_TABLE_SIZE";
+    case SETTINGS_ENABLE_PUSH:
+      return "SETTINGS_ENABLE_PUSH";
+    case SETTINGS_MAX_CONCURRENT_STREAMS:
+      return "SETTINGS_MAX_CONCURRENT_STREAMS";
+    case SETTINGS_INITIAL_WINDOW_SIZE:
+      return "SETTINGS_INITIAL_WINDOW_SIZE";
+    case SETTINGS_MAX_FRAME_SIZE:
+      return "SETTINGS_MAX_FRAME_SIZE";
+    case SETTINGS_MAX_HEADER_LIST_SIZE:
+      return "SETTINGS_MAX_HEADER_LIST_SIZE";
+    case SETTINGS_ENABLE_CONNECT_PROTOCOL:
+      return "SETTINGS_ENABLE_CONNECT_PROTOCOL";
+    case SETTINGS_DEPRECATE_HTTP2_PRIORITIES:
+      return "SETTINGS_DEPRECATE_HTTP2_PRIORITIES";
+    case SETTINGS_EXPERIMENT_SCHEDULER:
+      return "SETTINGS_EXPERIMENT_SCHEDULER";
+  }
+
+  return absl::StrCat("SETTINGS_UNKNOWN_", absl::Hex(uint32_t{id}));
+}
+
+SpdyErrorCode ParseErrorCode(uint32_t wire_error_code) {
+  if (wire_error_code > ERROR_CODE_MAX) {
+    return ERROR_CODE_INTERNAL_ERROR;
+  }
+
+  return static_cast<SpdyErrorCode>(wire_error_code);
+}
+
+const char* ErrorCodeToString(SpdyErrorCode error_code) {
+  switch (error_code) {
+    case ERROR_CODE_NO_ERROR:
+      return "NO_ERROR";
+    case ERROR_CODE_PROTOCOL_ERROR:
+      return "PROTOCOL_ERROR";
+    case ERROR_CODE_INTERNAL_ERROR:
+      return "INTERNAL_ERROR";
+    case ERROR_CODE_FLOW_CONTROL_ERROR:
+      return "FLOW_CONTROL_ERROR";
+    case ERROR_CODE_SETTINGS_TIMEOUT:
+      return "SETTINGS_TIMEOUT";
+    case ERROR_CODE_STREAM_CLOSED:
+      return "STREAM_CLOSED";
+    case ERROR_CODE_FRAME_SIZE_ERROR:
+      return "FRAME_SIZE_ERROR";
+    case ERROR_CODE_REFUSED_STREAM:
+      return "REFUSED_STREAM";
+    case ERROR_CODE_CANCEL:
+      return "CANCEL";
+    case ERROR_CODE_COMPRESSION_ERROR:
+      return "COMPRESSION_ERROR";
+    case ERROR_CODE_CONNECT_ERROR:
+      return "CONNECT_ERROR";
+    case ERROR_CODE_ENHANCE_YOUR_CALM:
+      return "ENHANCE_YOUR_CALM";
+    case ERROR_CODE_INADEQUATE_SECURITY:
+      return "INADEQUATE_SECURITY";
+    case ERROR_CODE_HTTP_1_1_REQUIRED:
+      return "HTTP_1_1_REQUIRED";
+  }
+  return "UNKNOWN_ERROR_CODE";
+}
+
+const char* WriteSchedulerTypeToString(WriteSchedulerType type) {
+  switch (type) {
+    case WriteSchedulerType::LIFO:
+      return "LIFO";
+    case WriteSchedulerType::SPDY:
+      return "SPDY";
+    case WriteSchedulerType::HTTP2:
+      return "HTTP2";
+    case WriteSchedulerType::FIFO:
+      return "FIFO";
+  }
+  return "UNKNOWN";
+}
+
+size_t GetNumberRequiredContinuationFrames(size_t size) {
+  QUICHE_DCHECK_GT(size, kHttp2MaxControlFrameSendSize);
+  size_t overflow = size - kHttp2MaxControlFrameSendSize;
+  int payload_size =
+      kHttp2MaxControlFrameSendSize - kContinuationFrameMinimumSize;
+  // This is ceiling(overflow/payload_size) using integer arithmetics.
+  return (overflow - 1) / payload_size + 1;
+}
+
+const char* const kHttp2Npn = "h2";
+
+const char* const kHttp2AuthorityHeader = ":authority";
+const char* const kHttp2MethodHeader = ":method";
+const char* const kHttp2PathHeader = ":path";
+const char* const kHttp2SchemeHeader = ":scheme";
+const char* const kHttp2ProtocolHeader = ":protocol";
+
+const char* const kHttp2StatusHeader = ":status";
+
+bool SpdyFrameIR::fin() const {
+  return false;
+}
+
+int SpdyFrameIR::flow_control_window_consumed() const {
+  return 0;
+}
+
+bool SpdyFrameWithFinIR::fin() const {
+  return fin_;
+}
+
+SpdyFrameWithHeaderBlockIR::SpdyFrameWithHeaderBlockIR(
+    SpdyStreamId stream_id,
+    Http2HeaderBlock header_block)
+    : SpdyFrameWithFinIR(stream_id), header_block_(std::move(header_block)) {}
+
+SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() = default;
+
+SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, absl::string_view data)
+    : SpdyFrameWithFinIR(stream_id),
+      data_(nullptr),
+      data_len_(0),
+      padded_(false),
+      padding_payload_len_(0) {
+  SetDataDeep(data);
+}
+
+SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, const char* data)
+    : SpdyDataIR(stream_id, absl::string_view(data)) {}
+
+SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, std::string data)
+    : SpdyFrameWithFinIR(stream_id),
+      data_store_(std::make_unique<std::string>(std::move(data))),
+      data_(data_store_->data()),
+      data_len_(data_store_->size()),
+      padded_(false),
+      padding_payload_len_(0) {}
+
+SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
+    : SpdyFrameWithFinIR(stream_id),
+      data_(nullptr),
+      data_len_(0),
+      padded_(false),
+      padding_payload_len_(0) {}
+
+SpdyDataIR::~SpdyDataIR() = default;
+
+void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitData(*this);
+}
+
+SpdyFrameType SpdyDataIR::frame_type() const {
+  return SpdyFrameType::DATA;
+}
+
+int SpdyDataIR::flow_control_window_consumed() const {
+  return padded_ ? 1 + padding_payload_len_ + data_len_ : data_len_;
+}
+
+size_t SpdyDataIR::size() const {
+  return kFrameHeaderSize +
+         (padded() ? 1 + padding_payload_len() + data_len() : data_len());
+}
+
+SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
+                                 SpdyErrorCode error_code)
+    : SpdyFrameIR(stream_id) {
+  set_error_code(error_code);
+}
+
+SpdyRstStreamIR::~SpdyRstStreamIR() = default;
+
+void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitRstStream(*this);
+}
+
+SpdyFrameType SpdyRstStreamIR::frame_type() const {
+  return SpdyFrameType::RST_STREAM;
+}
+
+size_t SpdyRstStreamIR::size() const {
+  return kRstStreamFrameSize;
+}
+
+SpdySettingsIR::SpdySettingsIR() : is_ack_(false) {}
+
+SpdySettingsIR::~SpdySettingsIR() = default;
+
+void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitSettings(*this);
+}
+
+SpdyFrameType SpdySettingsIR::frame_type() const {
+  return SpdyFrameType::SETTINGS;
+}
+
+size_t SpdySettingsIR::size() const {
+  return kFrameHeaderSize + values_.size() * kSettingsOneSettingSize;
+}
+
+void SpdyPingIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitPing(*this);
+}
+
+SpdyFrameType SpdyPingIR::frame_type() const {
+  return SpdyFrameType::PING;
+}
+
+size_t SpdyPingIR::size() const {
+  return kPingFrameSize;
+}
+
+SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
+                           SpdyErrorCode error_code,
+                           absl::string_view description)
+    : description_(description) {
+  set_last_good_stream_id(last_good_stream_id);
+  set_error_code(error_code);
+}
+
+SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
+                           SpdyErrorCode error_code,
+                           const char* description)
+    : SpdyGoAwayIR(last_good_stream_id,
+                   error_code,
+                   absl::string_view(description)) {}
+
+SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
+                           SpdyErrorCode error_code,
+                           std::string description)
+    : description_store_(std::move(description)),
+      description_(description_store_) {
+  set_last_good_stream_id(last_good_stream_id);
+  set_error_code(error_code);
+}
+
+SpdyGoAwayIR::~SpdyGoAwayIR() = default;
+
+void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitGoAway(*this);
+}
+
+SpdyFrameType SpdyGoAwayIR::frame_type() const {
+  return SpdyFrameType::GOAWAY;
+}
+
+size_t SpdyGoAwayIR::size() const {
+  return kGoawayFrameMinimumSize + description_.size();
+}
+
+SpdyContinuationIR::SpdyContinuationIR(SpdyStreamId stream_id)
+    : SpdyFrameIR(stream_id), end_headers_(false) {
+}
+
+SpdyContinuationIR::~SpdyContinuationIR() = default;
+
+void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitContinuation(*this);
+}
+
+SpdyFrameType SpdyContinuationIR::frame_type() const {
+  return SpdyFrameType::CONTINUATION;
+}
+
+size_t SpdyContinuationIR::size() const {
+  // We don't need to get the size of CONTINUATION frame directly. It is
+  // calculated in HEADERS or PUSH_PROMISE frame.
+  QUICHE_DLOG(WARNING) << "Shouldn't not call size() for CONTINUATION frame.";
+  return 0;
+}
+
+void SpdyHeadersIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitHeaders(*this);
+}
+
+SpdyFrameType SpdyHeadersIR::frame_type() const {
+  return SpdyFrameType::HEADERS;
+}
+
+size_t SpdyHeadersIR::size() const {
+  size_t size = kHeadersFrameMinimumSize;
+
+  if (padded_) {
+    // Padding field length.
+    size += 1;
+    size += padding_payload_len_;
+  }
+
+  if (has_priority_) {
+    size += 5;
+  }
+
+  // Assume no hpack encoding is applied.
+  size += header_block().TotalBytesUsed() +
+          header_block().size() * kPerHeaderHpackOverhead;
+  if (size > kHttp2MaxControlFrameSendSize) {
+    size += GetNumberRequiredContinuationFrames(size) *
+            kContinuationFrameMinimumSize;
+  }
+  return size;
+}
+
+void SpdyWindowUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitWindowUpdate(*this);
+}
+
+SpdyFrameType SpdyWindowUpdateIR::frame_type() const {
+  return SpdyFrameType::WINDOW_UPDATE;
+}
+
+size_t SpdyWindowUpdateIR::size() const {
+  return kWindowUpdateFrameSize;
+}
+
+void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitPushPromise(*this);
+}
+
+SpdyFrameType SpdyPushPromiseIR::frame_type() const {
+  return SpdyFrameType::PUSH_PROMISE;
+}
+
+size_t SpdyPushPromiseIR::size() const {
+  size_t size = kPushPromiseFrameMinimumSize;
+
+  if (padded_) {
+    // Padding length field.
+    size += 1;
+    size += padding_payload_len_;
+  }
+
+  size += header_block().TotalBytesUsed();
+  if (size > kHttp2MaxControlFrameSendSize) {
+    size += GetNumberRequiredContinuationFrames(size) *
+            kContinuationFrameMinimumSize;
+  }
+  return size;
+}
+
+SpdyAltSvcIR::SpdyAltSvcIR(SpdyStreamId stream_id) : SpdyFrameIR(stream_id) {}
+
+SpdyAltSvcIR::~SpdyAltSvcIR() = default;
+
+void SpdyAltSvcIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitAltSvc(*this);
+}
+
+SpdyFrameType SpdyAltSvcIR::frame_type() const {
+  return SpdyFrameType::ALTSVC;
+}
+
+size_t SpdyAltSvcIR::size() const {
+  size_t size = kGetAltSvcFrameMinimumSize;
+  size += origin_.length();
+  // TODO(yasong): estimates the size without serializing the vector.
+  std::string str =
+      SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector_);
+  size += str.size();
+  return size;
+}
+
+void SpdyPriorityIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitPriority(*this);
+}
+
+SpdyFrameType SpdyPriorityIR::frame_type() const {
+  return SpdyFrameType::PRIORITY;
+}
+
+size_t SpdyPriorityIR::size() const {
+  return kPriorityFrameSize;
+}
+
+void SpdyPriorityUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitPriorityUpdate(*this);
+}
+
+SpdyFrameType SpdyPriorityUpdateIR::frame_type() const {
+  return SpdyFrameType::PRIORITY_UPDATE;
+}
+
+size_t SpdyPriorityUpdateIR::size() const {
+  return kPriorityUpdateFrameMinimumSize + priority_field_value_.size();
+}
+
+void SpdyAcceptChIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitAcceptCh(*this);
+}
+
+SpdyFrameType SpdyAcceptChIR::frame_type() const {
+  return SpdyFrameType::ACCEPT_CH;
+}
+
+size_t SpdyAcceptChIR::size() const {
+  size_t total_size = kAcceptChFrameMinimumSize;
+  for (const AcceptChOriginValuePair& entry : entries_) {
+    total_size += entry.origin.size() + entry.value.size() +
+                  kAcceptChFramePerEntryOverhead;
+  }
+  return total_size;
+}
+
+void SpdyUnknownIR::Visit(SpdyFrameVisitor* visitor) const {
+  return visitor->VisitUnknown(*this);
+}
+
+SpdyFrameType SpdyUnknownIR::frame_type() const {
+  return static_cast<SpdyFrameType>(type());
+}
+
+size_t SpdyUnknownIR::size() const {
+  return kFrameHeaderSize + payload_.size();
+}
+
+int SpdyUnknownIR::flow_control_window_consumed() const {
+  if (frame_type() == SpdyFrameType::DATA) {
+    return payload_.size();
+  } else {
+    return 0;
+  }
+}
+
+// Wire size of pad length field.
+const size_t kPadLengthFieldSize = 1;
+
+size_t GetHeaderFrameSizeSansBlock(const SpdyHeadersIR& header_ir) {
+  size_t min_size = kFrameHeaderSize;
+  if (header_ir.padded()) {
+    min_size += kPadLengthFieldSize;
+    min_size += header_ir.padding_payload_len();
+  }
+  if (header_ir.has_priority()) {
+    min_size += 5;
+  }
+  return min_size;
+}
+
+size_t GetPushPromiseFrameSizeSansBlock(
+    const SpdyPushPromiseIR& push_promise_ir) {
+  size_t min_size = kPushPromiseFrameMinimumSize;
+  if (push_promise_ir.padded()) {
+    min_size += kPadLengthFieldSize;
+    min_size += push_promise_ir.padding_payload_len();
+  }
+  return min_size;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_protocol.h b/quiche/spdy/core/spdy_protocol.h
new file mode 100644
index 0000000..7f462a5
--- /dev/null
+++ b/quiche/spdy/core/spdy_protocol.h
@@ -0,0 +1,1138 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains some protocol structures for use with SPDY 3 and HTTP 2
+// The SPDY 3 spec can be found at:
+// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3
+
+#ifndef QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
+#define QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <iosfwd>
+#include <limits>
+#include <map>
+#include <memory>
+#include <new>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
+#include "quiche/spdy/core/spdy_bitmasks.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+
+namespace spdy {
+
+// A stream ID is a 31-bit entity.
+using SpdyStreamId = uint32_t;
+
+// A SETTINGS ID is a 16-bit entity.
+using SpdySettingsId = uint16_t;
+
+// Specifies the stream ID used to denote the current session (for
+// flow control).
+const SpdyStreamId kSessionFlowControlStreamId = 0;
+
+// 0 is not a valid stream ID for any other purpose than flow control.
+const SpdyStreamId kInvalidStreamId = 0;
+
+// Max stream id.
+const SpdyStreamId kMaxStreamId = 0x7fffffff;
+
+// The maximum possible frame payload size allowed by the spec.
+const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1;
+
+// The initial value for the maximum frame payload size as per the spec. This is
+// the maximum control frame size we accept.
+const uint32_t kHttp2DefaultFramePayloadLimit = 1 << 14;
+
+// The maximum size of the control frames that we send, including the size of
+// the header. This limit is arbitrary. We can enforce it here or at the
+// application layer. We chose the framing layer, but this can be changed (or
+// removed) if necessary later down the line.
+const size_t kHttp2MaxControlFrameSendSize = kHttp2DefaultFramePayloadLimit - 1;
+
+// Number of octets in the frame header.
+const size_t kFrameHeaderSize = 9;
+
+// The initial value for the maximum frame payload size as per the spec. This is
+// the maximum control frame size we accept.
+const uint32_t kHttp2DefaultFrameSizeLimit =
+    kHttp2DefaultFramePayloadLimit + kFrameHeaderSize;
+
+// The initial value for the maximum size of the header list, "unlimited" (max
+// unsigned 32-bit int) as per the spec.
+const uint32_t kSpdyInitialHeaderListSizeLimit = 0xFFFFFFFF;
+
+// Maximum window size for a Spdy stream or session.
+const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF;  // Max signed 32bit int
+
+// Maximum padding size in octets for one DATA or HEADERS or PUSH_PROMISE frame.
+const int32_t kPaddingSizePerFrame = 256;
+
+// The HTTP/2 connection preface, which must be the first bytes sent by the
+// client upon starting an HTTP/2 connection, and which must be followed by a
+// SETTINGS frame.  Note that even though |kHttp2ConnectionHeaderPrefix| is
+// defined as a string literal with a null terminator, the actual connection
+// preface is only the first |kHttp2ConnectionHeaderPrefixSize| bytes, which
+// excludes the null terminator.
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2ConnectionHeaderPrefix;
+const int kHttp2ConnectionHeaderPrefixSize = 24;
+
+// Wire values for HTTP2 frame types.
+enum class SpdyFrameType : uint8_t {
+  DATA = 0x00,
+  HEADERS = 0x01,
+  PRIORITY = 0x02,
+  RST_STREAM = 0x03,
+  SETTINGS = 0x04,
+  PUSH_PROMISE = 0x05,
+  PING = 0x06,
+  GOAWAY = 0x07,
+  WINDOW_UPDATE = 0x08,
+  CONTINUATION = 0x09,
+  // ALTSVC is a public extension.
+  ALTSVC = 0x0a,
+  PRIORITY_UPDATE = 0x10,
+  ACCEPT_CH = 0x89,
+};
+
+// Flags on data packets.
+enum SpdyDataFlags {
+  DATA_FLAG_NONE = 0x00,
+  DATA_FLAG_FIN = 0x01,
+  DATA_FLAG_PADDED = 0x08,
+};
+
+// Flags on control packets
+enum SpdyControlFlags {
+  CONTROL_FLAG_NONE = 0x00,
+  CONTROL_FLAG_FIN = 0x01,
+};
+
+enum SpdyPingFlags {
+  PING_FLAG_ACK = 0x01,
+};
+
+// Used by HEADERS, PUSH_PROMISE, and CONTINUATION.
+enum SpdyHeadersFlags {
+  HEADERS_FLAG_END_HEADERS = 0x04,
+  HEADERS_FLAG_PADDED = 0x08,
+  HEADERS_FLAG_PRIORITY = 0x20,
+};
+
+enum SpdyPushPromiseFlags {
+  PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x04,
+  PUSH_PROMISE_FLAG_PADDED = 0x08,
+};
+
+enum Http2SettingsControlFlags {
+  SETTINGS_FLAG_ACK = 0x01,
+};
+
+// Wire values of HTTP/2 setting identifiers.
+enum SpdyKnownSettingsId : SpdySettingsId {
+  // HPACK header table maximum size.
+  SETTINGS_HEADER_TABLE_SIZE = 0x1,
+  SETTINGS_MIN = SETTINGS_HEADER_TABLE_SIZE,
+  // Whether or not server push (PUSH_PROMISE) is enabled.
+  SETTINGS_ENABLE_PUSH = 0x2,
+  // The maximum number of simultaneous live streams in each direction.
+  SETTINGS_MAX_CONCURRENT_STREAMS = 0x3,
+  // Initial window size in bytes
+  SETTINGS_INITIAL_WINDOW_SIZE = 0x4,
+  // The size of the largest frame payload that a receiver is willing to accept.
+  SETTINGS_MAX_FRAME_SIZE = 0x5,
+  // The maximum size of header list that the sender is prepared to accept.
+  SETTINGS_MAX_HEADER_LIST_SIZE = 0x6,
+  // Enable Websockets over HTTP/2, see
+  // https://httpwg.org/specs/rfc8441.html
+  SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x8,
+  // Disable HTTP/2 priorities, see
+  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-02.
+  SETTINGS_DEPRECATE_HTTP2_PRIORITIES = 0x9,
+  SETTINGS_MAX = SETTINGS_DEPRECATE_HTTP2_PRIORITIES,
+  // Experimental setting used to configure an alternative write scheduler.
+  SETTINGS_EXPERIMENT_SCHEDULER = 0xFF45,
+};
+
+// This explicit operator is needed, otherwise compiler finds
+// overloaded operator to be ambiguous.
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               SpdyKnownSettingsId id);
+
+// This operator is needed, because SpdyFrameType is an enum class,
+// therefore implicit conversion to underlying integer type is not allowed.
+QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
+                                               SpdyFrameType frame_type);
+
+using SettingsMap = std::map<SpdySettingsId, uint32_t>;
+
+// HTTP/2 error codes, RFC 7540 Section 7.
+enum SpdyErrorCode : uint32_t {
+  ERROR_CODE_NO_ERROR = 0x0,
+  ERROR_CODE_PROTOCOL_ERROR = 0x1,
+  ERROR_CODE_INTERNAL_ERROR = 0x2,
+  ERROR_CODE_FLOW_CONTROL_ERROR = 0x3,
+  ERROR_CODE_SETTINGS_TIMEOUT = 0x4,
+  ERROR_CODE_STREAM_CLOSED = 0x5,
+  ERROR_CODE_FRAME_SIZE_ERROR = 0x6,
+  ERROR_CODE_REFUSED_STREAM = 0x7,
+  ERROR_CODE_CANCEL = 0x8,
+  ERROR_CODE_COMPRESSION_ERROR = 0x9,
+  ERROR_CODE_CONNECT_ERROR = 0xa,
+  ERROR_CODE_ENHANCE_YOUR_CALM = 0xb,
+  ERROR_CODE_INADEQUATE_SECURITY = 0xc,
+  ERROR_CODE_HTTP_1_1_REQUIRED = 0xd,
+  ERROR_CODE_MAX = ERROR_CODE_HTTP_1_1_REQUIRED
+};
+
+// Type of priority write scheduler.
+enum class WriteSchedulerType {
+  LIFO,  // Last added stream has the highest priority.
+  SPDY,  // Uses SPDY priorities described in
+         // https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority.
+  HTTP2,  // Uses HTTP2 (tree-style) priority described in
+          // https://tools.ietf.org/html/rfc7540#section-5.3.
+  FIFO,   // Stream with the smallest stream ID has the highest priority.
+};
+
+// A SPDY priority is a number between 0 and 7 (inclusive).
+typedef uint8_t SpdyPriority;
+
+// Lowest and Highest here refer to SPDY priorities as described in
+// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
+const SpdyPriority kV3HighestPriority = 0;
+const SpdyPriority kV3LowestPriority = 7;
+
+// Returns SPDY 3.x priority value clamped to the valid range of [0, 7].
+QUICHE_EXPORT_PRIVATE SpdyPriority ClampSpdy3Priority(SpdyPriority priority);
+
+// HTTP/2 stream weights are integers in range [1, 256], as specified in RFC
+// 7540 section 5.3.2. Default stream weight is defined in section 5.3.5.
+const int kHttp2MinStreamWeight = 1;
+const int kHttp2MaxStreamWeight = 256;
+const int kHttp2DefaultStreamWeight = 16;
+
+// Returns HTTP/2 weight clamped to the valid range of [1, 256].
+QUICHE_EXPORT_PRIVATE int ClampHttp2Weight(int weight);
+
+// Maps SPDY 3.x priority value in range [0, 7] to HTTP/2 weight value in range
+// [1, 256], where priority 0 (i.e. highest precedence) corresponds to maximum
+// weight 256 and priority 7 (lowest precedence) corresponds to minimum weight
+// 1.
+QUICHE_EXPORT_PRIVATE int Spdy3PriorityToHttp2Weight(SpdyPriority priority);
+
+// Maps HTTP/2 weight value in range [1, 256] to SPDY 3.x priority value in
+// range [0, 7], where minimum weight 1 corresponds to priority 7 (lowest
+// precedence) and maximum weight 256 corresponds to priority 0 (highest
+// precedence).
+QUICHE_EXPORT_PRIVATE SpdyPriority Http2WeightToSpdy3Priority(int weight);
+
+// Reserved ID for root stream of HTTP/2 stream dependency tree, as specified
+// in RFC 7540 section 5.3.1.
+const unsigned int kHttp2RootStreamId = 0;
+
+typedef uint64_t SpdyPingId;
+
+// Returns true if a given on-the-wire enumeration of a frame type is defined
+// in a standardized HTTP/2 specification, false otherwise.
+QUICHE_EXPORT_PRIVATE bool IsDefinedFrameType(uint8_t frame_type_field);
+
+// Parses a frame type from an on-the-wire enumeration.
+// Behavior is undefined for invalid frame type fields; consumers should first
+// use IsValidFrameType() to verify validity of frame type fields.
+QUICHE_EXPORT_PRIVATE SpdyFrameType ParseFrameType(uint8_t frame_type_field);
+
+// Serializes a frame type to the on-the-wire value.
+QUICHE_EXPORT_PRIVATE uint8_t SerializeFrameType(SpdyFrameType frame_type);
+
+// (HTTP/2) All standard frame types except WINDOW_UPDATE are
+// (stream-specific xor connection-level). Returns false iff we know
+// the given frame type does not align with the given streamID.
+QUICHE_EXPORT_PRIVATE bool IsValidHTTP2FrameStreamId(
+    SpdyStreamId current_frame_stream_id,
+    SpdyFrameType frame_type_field);
+
+// Serialize |frame_type| to string for logging/debugging.
+QUICHE_EXPORT_PRIVATE const char* FrameTypeToString(SpdyFrameType frame_type);
+
+// If |wire_setting_id| is the on-the-wire representation of a defined SETTINGS
+// parameter, parse it to |*setting_id| and return true.
+QUICHE_EXPORT_PRIVATE bool ParseSettingsId(SpdySettingsId wire_setting_id,
+                                           SpdyKnownSettingsId* setting_id);
+
+// Returns a string representation of the |id| for logging/debugging. Returns
+// the |id| prefixed with "SETTINGS_UNKNOWN_" for unknown SETTINGS IDs. To parse
+// the |id| into a SpdyKnownSettingsId (if applicable), use ParseSettingsId().
+QUICHE_EXPORT_PRIVATE std::string SettingsIdToString(SpdySettingsId id);
+
+// Parse |wire_error_code| to a SpdyErrorCode.
+// Treat unrecognized error codes as INTERNAL_ERROR
+// as recommended by the HTTP/2 specification.
+QUICHE_EXPORT_PRIVATE SpdyErrorCode ParseErrorCode(uint32_t wire_error_code);
+
+// Serialize RST_STREAM or GOAWAY frame error code to string
+// for logging/debugging.
+const char* ErrorCodeToString(SpdyErrorCode error_code);
+
+// Serialize |type| to string for logging/debugging.
+QUICHE_EXPORT_PRIVATE const char* WriteSchedulerTypeToString(
+    WriteSchedulerType type);
+
+// Minimum size of a frame, in octets.
+const size_t kFrameMinimumSize = kFrameHeaderSize;
+
+// Minimum frame size for variable size frame types (includes mandatory fields),
+// frame size for fixed size frames, in octets.
+
+const size_t kDataFrameMinimumSize = kFrameHeaderSize;
+const size_t kHeadersFrameMinimumSize = kFrameHeaderSize;
+// PRIORITY frame has stream_dependency (4 octets) and weight (1 octet) fields.
+const size_t kPriorityFrameSize = kFrameHeaderSize + 5;
+// RST_STREAM frame has error_code (4 octets) field.
+const size_t kRstStreamFrameSize = kFrameHeaderSize + 4;
+const size_t kSettingsFrameMinimumSize = kFrameHeaderSize;
+const size_t kSettingsOneSettingSize =
+    sizeof(uint32_t) + sizeof(SpdySettingsId);
+// PUSH_PROMISE frame has promised_stream_id (4 octet) field.
+const size_t kPushPromiseFrameMinimumSize = kFrameHeaderSize + 4;
+// PING frame has opaque_bytes (8 octet) field.
+const size_t kPingFrameSize = kFrameHeaderSize + 8;
+// GOAWAY frame has last_stream_id (4 octet) and error_code (4 octet) fields.
+const size_t kGoawayFrameMinimumSize = kFrameHeaderSize + 8;
+// WINDOW_UPDATE frame has window_size_increment (4 octet) field.
+const size_t kWindowUpdateFrameSize = kFrameHeaderSize + 4;
+const size_t kContinuationFrameMinimumSize = kFrameHeaderSize;
+// ALTSVC frame has origin_len (2 octets) field.
+const size_t kGetAltSvcFrameMinimumSize = kFrameHeaderSize + 2;
+// PRIORITY_UPDATE frame has prioritized_stream_id (4 octets) field.
+const size_t kPriorityUpdateFrameMinimumSize = kFrameHeaderSize + 4;
+// ACCEPT_CH frame may have empty payload.
+const size_t kAcceptChFrameMinimumSize = kFrameHeaderSize;
+// Each ACCEPT_CH frame entry has a 16-bit origin length and a 16-bit value
+// length.
+const size_t kAcceptChFramePerEntryOverhead = 4;
+
+// Maximum possible configurable size of a frame in octets.
+const size_t kMaxFrameSizeLimit = kSpdyMaxFrameSizeLimit + kFrameHeaderSize;
+// Size of a header block size field.
+const size_t kSizeOfSizeField = sizeof(uint32_t);
+// Initial window size for a stream in bytes.
+const int32_t kInitialStreamWindowSize = 64 * 1024 - 1;
+// Initial window size for a session in bytes.
+const int32_t kInitialSessionWindowSize = 64 * 1024 - 1;
+// The NPN string for HTTP2, "h2".
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2Npn;
+// An estimate size of the HPACK overhead for each header field. 1 bytes for
+// indexed literal, 1 bytes for key literal and length encoding, and 2 bytes for
+// value literal and length encoding.
+const size_t kPerHeaderHpackOverhead = 4;
+
+// Names of pseudo-headers defined for HTTP/2 requests.
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2AuthorityHeader;
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2MethodHeader;
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2PathHeader;
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2SchemeHeader;
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2ProtocolHeader;
+
+// Name of pseudo-header defined for HTTP/2 responses.
+QUICHE_EXPORT_PRIVATE extern const char* const kHttp2StatusHeader;
+
+QUICHE_EXPORT_PRIVATE size_t GetNumberRequiredContinuationFrames(size_t size);
+
+// Variant type (i.e. tagged union) that is either a SPDY 3.x priority value,
+// or else an HTTP/2 stream dependency tuple {parent stream ID, weight,
+// exclusive bit}. Templated to allow for use by QUIC code; SPDY and HTTP/2
+// code should use the concrete type instantiation SpdyStreamPrecedence.
+template <typename StreamIdType>
+class QUICHE_EXPORT_PRIVATE StreamPrecedence {
+ public:
+  // Constructs instance that is a SPDY 3.x priority. Clamps priority value to
+  // the valid range [0, 7].
+  explicit StreamPrecedence(SpdyPriority priority)
+      : is_spdy3_priority_(true),
+        spdy3_priority_(ClampSpdy3Priority(priority)) {}
+
+  // Constructs instance that is an HTTP/2 stream weight, parent stream ID, and
+  // exclusive bit. Clamps stream weight to the valid range [1, 256].
+  StreamPrecedence(StreamIdType parent_id, int weight, bool is_exclusive)
+      : is_spdy3_priority_(false),
+        http2_stream_dependency_{parent_id, ClampHttp2Weight(weight),
+                                 is_exclusive} {}
+
+  // Intentionally copyable, to support pass by value.
+  StreamPrecedence(const StreamPrecedence& other) = default;
+  StreamPrecedence& operator=(const StreamPrecedence& other) = default;
+
+  // Returns true if this instance is a SPDY 3.x priority, or false if this
+  // instance is an HTTP/2 stream dependency.
+  bool is_spdy3_priority() const { return is_spdy3_priority_; }
+
+  // Returns SPDY 3.x priority value. If |is_spdy3_priority()| is true, this is
+  // the value provided at construction, clamped to the legal priority
+  // range. Otherwise, it is the HTTP/2 stream weight mapped to a SPDY 3.x
+  // priority value, where minimum weight 1 corresponds to priority 7 (lowest
+  // precedence) and maximum weight 256 corresponds to priority 0 (highest
+  // precedence).
+  SpdyPriority spdy3_priority() const {
+    return is_spdy3_priority_
+               ? spdy3_priority_
+               : Http2WeightToSpdy3Priority(http2_stream_dependency_.weight);
+  }
+
+  // Returns HTTP/2 parent stream ID. If |is_spdy3_priority()| is false, this is
+  // the value provided at construction, otherwise it is |kHttp2RootStreamId|.
+  StreamIdType parent_id() const {
+    return is_spdy3_priority_ ? kHttp2RootStreamId
+                              : http2_stream_dependency_.parent_id;
+  }
+
+  // Returns HTTP/2 stream weight. If |is_spdy3_priority()| is false, this is
+  // the value provided at construction, clamped to the legal weight
+  // range. Otherwise, it is the SPDY 3.x priority value mapped to an HTTP/2
+  // stream weight, where priority 0 (i.e. highest precedence) corresponds to
+  // maximum weight 256 and priority 7 (lowest precedence) corresponds to
+  // minimum weight 1.
+  int weight() const {
+    return is_spdy3_priority_ ? Spdy3PriorityToHttp2Weight(spdy3_priority_)
+                              : http2_stream_dependency_.weight;
+  }
+
+  // Returns HTTP/2 parent stream exclusivity. If |is_spdy3_priority()| is
+  // false, this is the value provided at construction, otherwise it is false.
+  bool is_exclusive() const {
+    return !is_spdy3_priority_ && http2_stream_dependency_.is_exclusive;
+  }
+
+  // Facilitates test assertions.
+  bool operator==(const StreamPrecedence& other) const {
+    if (is_spdy3_priority()) {
+      return other.is_spdy3_priority() &&
+             (spdy3_priority() == other.spdy3_priority());
+    } else {
+      return !other.is_spdy3_priority() && (parent_id() == other.parent_id()) &&
+             (weight() == other.weight()) &&
+             (is_exclusive() == other.is_exclusive());
+    }
+  }
+
+  bool operator!=(const StreamPrecedence& other) const {
+    return !(*this == other);
+  }
+
+ private:
+  struct QUICHE_EXPORT_PRIVATE Http2StreamDependency {
+    StreamIdType parent_id;
+    int weight;
+    bool is_exclusive;
+  };
+
+  bool is_spdy3_priority_;
+  union {
+    SpdyPriority spdy3_priority_;
+    Http2StreamDependency http2_stream_dependency_;
+  };
+};
+
+typedef StreamPrecedence<SpdyStreamId> SpdyStreamPrecedence;
+
+class SpdyFrameVisitor;
+
+// Intermediate representation for HTTP2 frames.
+class QUICHE_EXPORT_PRIVATE SpdyFrameIR {
+ public:
+  virtual ~SpdyFrameIR() {}
+
+  virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
+  virtual SpdyFrameType frame_type() const = 0;
+  SpdyStreamId stream_id() const { return stream_id_; }
+  virtual bool fin() const;
+  // Returns an estimate of the size of the serialized frame, without applying
+  // compression. May not be exact.
+  virtual size_t size() const = 0;
+
+  // Returns the number of bytes of flow control window that would be consumed
+  // by this frame if written to the wire.
+  virtual int flow_control_window_consumed() const;
+
+ protected:
+  SpdyFrameIR() : stream_id_(0) {}
+  explicit SpdyFrameIR(SpdyStreamId stream_id) : stream_id_(stream_id) {}
+  SpdyFrameIR(const SpdyFrameIR&) = delete;
+  SpdyFrameIR& operator=(const SpdyFrameIR&) = delete;
+
+ private:
+  SpdyStreamId stream_id_;
+};
+
+// Abstract class intended to be inherited by IRs that have the option of a FIN
+// flag.
+class QUICHE_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameIR {
+ public:
+  ~SpdyFrameWithFinIR() override {}
+  bool fin() const override;
+  void set_fin(bool fin) { fin_ = fin; }
+
+ protected:
+  explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
+      : SpdyFrameIR(stream_id), fin_(false) {}
+  SpdyFrameWithFinIR(const SpdyFrameWithFinIR&) = delete;
+  SpdyFrameWithFinIR& operator=(const SpdyFrameWithFinIR&) = delete;
+
+ private:
+  bool fin_;
+};
+
+// Abstract class intended to be inherited by IRs that contain a header
+// block. Implies SpdyFrameWithFinIR.
+class QUICHE_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR
+    : public SpdyFrameWithFinIR {
+ public:
+  ~SpdyFrameWithHeaderBlockIR() override;
+
+  const Http2HeaderBlock& header_block() const { return header_block_; }
+  void set_header_block(Http2HeaderBlock header_block) {
+    // Deep copy.
+    header_block_ = std::move(header_block);
+  }
+  void SetHeader(absl::string_view name, absl::string_view value) {
+    header_block_[name] = value;
+  }
+
+ protected:
+  SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id,
+                             Http2HeaderBlock header_block);
+  SpdyFrameWithHeaderBlockIR(const SpdyFrameWithHeaderBlockIR&) = delete;
+  SpdyFrameWithHeaderBlockIR& operator=(const SpdyFrameWithHeaderBlockIR&) =
+      delete;
+
+ private:
+  Http2HeaderBlock header_block_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR {
+ public:
+  // Performs a deep copy on data.
+  SpdyDataIR(SpdyStreamId stream_id, absl::string_view data);
+
+  // Performs a deep copy on data.
+  SpdyDataIR(SpdyStreamId stream_id, const char* data);
+
+  // Moves data into data_store_. Makes a copy if passed a non-movable string.
+  SpdyDataIR(SpdyStreamId stream_id, std::string data);
+
+  // Use in conjunction with SetDataShallow() for shallow-copy on data.
+  explicit SpdyDataIR(SpdyStreamId stream_id);
+  SpdyDataIR(const SpdyDataIR&) = delete;
+  SpdyDataIR& operator=(const SpdyDataIR&) = delete;
+
+  ~SpdyDataIR() override;
+
+  const char* data() const { return data_; }
+  size_t data_len() const { return data_len_; }
+
+  bool padded() const { return padded_; }
+
+  int padding_payload_len() const { return padding_payload_len_; }
+
+  void set_padding_len(int padding_len) {
+    QUICHE_DCHECK_GT(padding_len, 0);
+    QUICHE_DCHECK_LE(padding_len, kPaddingSizePerFrame);
+    padded_ = true;
+    // The pad field takes one octet on the wire.
+    padding_payload_len_ = padding_len - 1;
+  }
+
+  // Deep-copy of data (keep private copy).
+  void SetDataDeep(absl::string_view data) {
+    data_store_ = std::make_unique<std::string>(data.data(), data.size());
+    data_ = data_store_->data();
+    data_len_ = data.size();
+  }
+
+  // Shallow-copy of data (do not keep private copy).
+  void SetDataShallow(absl::string_view data) {
+    data_store_.reset();
+    data_ = data.data();
+    data_len_ = data.size();
+  }
+
+  // Use this method if we don't have a contiguous buffer and only
+  // need a length.
+  void SetDataShallow(size_t len) {
+    data_store_.reset();
+    data_ = nullptr;
+    data_len_ = len;
+  }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  int flow_control_window_consumed() const override;
+
+  size_t size() const override;
+
+ private:
+  // Used to store data that this SpdyDataIR should own.
+  std::unique_ptr<std::string> data_store_;
+  const char* data_;
+  size_t data_len_;
+
+  bool padded_;
+  // padding_payload_len_ = desired padding length - len(padding length field).
+  int padding_payload_len_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameIR {
+ public:
+  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyErrorCode error_code);
+  SpdyRstStreamIR(const SpdyRstStreamIR&) = delete;
+  SpdyRstStreamIR& operator=(const SpdyRstStreamIR&) = delete;
+
+  ~SpdyRstStreamIR() override;
+
+  SpdyErrorCode error_code() const { return error_code_; }
+  void set_error_code(SpdyErrorCode error_code) { error_code_ = error_code; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  SpdyErrorCode error_code_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
+ public:
+  SpdySettingsIR();
+  SpdySettingsIR(const SpdySettingsIR&) = delete;
+  SpdySettingsIR& operator=(const SpdySettingsIR&) = delete;
+  ~SpdySettingsIR() override;
+
+  // Overwrites as appropriate.
+  const SettingsMap& values() const { return values_; }
+  void AddSetting(SpdySettingsId id, int32_t value) { values_[id] = value; }
+
+  bool is_ack() const { return is_ack_; }
+  void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  SettingsMap values_;
+  bool is_ack_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
+ public:
+  explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
+  SpdyPingIR(const SpdyPingIR&) = delete;
+  SpdyPingIR& operator=(const SpdyPingIR&) = delete;
+  SpdyPingId id() const { return id_; }
+
+  bool is_ack() const { return is_ack_; }
+  void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  SpdyPingId id_;
+  bool is_ack_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
+ public:
+  // References description, doesn't copy it, so description must outlast
+  // this SpdyGoAwayIR.
+  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
+               SpdyErrorCode error_code,
+               absl::string_view description);
+
+  // References description, doesn't copy it, so description must outlast
+  // this SpdyGoAwayIR.
+  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
+               SpdyErrorCode error_code,
+               const char* description);
+
+  // Moves description into description_store_, so caller doesn't need to
+  // keep description live after constructing this SpdyGoAwayIR.
+  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
+               SpdyErrorCode error_code,
+               std::string description);
+  SpdyGoAwayIR(const SpdyGoAwayIR&) = delete;
+  SpdyGoAwayIR& operator=(const SpdyGoAwayIR&) = delete;
+
+  ~SpdyGoAwayIR() override;
+
+  SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
+  void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
+    QUICHE_DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
+    last_good_stream_id_ = last_good_stream_id;
+  }
+  SpdyErrorCode error_code() const { return error_code_; }
+  void set_error_code(SpdyErrorCode error_code) {
+    // TODO(hkhalil): Check valid ranges of error_code?
+    error_code_ = error_code;
+  }
+
+  const absl::string_view& description() const { return description_; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  SpdyStreamId last_good_stream_id_;
+  SpdyErrorCode error_code_;
+  const std::string description_store_;
+  const absl::string_view description_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
+ public:
+  explicit SpdyHeadersIR(SpdyStreamId stream_id)
+      : SpdyHeadersIR(stream_id, Http2HeaderBlock()) {}
+  SpdyHeadersIR(SpdyStreamId stream_id, Http2HeaderBlock header_block)
+      : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)) {}
+  SpdyHeadersIR(const SpdyHeadersIR&) = delete;
+  SpdyHeadersIR& operator=(const SpdyHeadersIR&) = delete;
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+  bool has_priority() const { return has_priority_; }
+  void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
+  int weight() const { return weight_; }
+  void set_weight(int weight) { weight_ = weight; }
+  SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
+  void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
+  bool exclusive() const { return exclusive_; }
+  void set_exclusive(bool exclusive) { exclusive_ = exclusive; }
+  bool padded() const { return padded_; }
+  int padding_payload_len() const { return padding_payload_len_; }
+  void set_padding_len(int padding_len) {
+    QUICHE_DCHECK_GT(padding_len, 0);
+    QUICHE_DCHECK_LE(padding_len, kPaddingSizePerFrame);
+    padded_ = true;
+    // The pad field takes one octet on the wire.
+    padding_payload_len_ = padding_len - 1;
+  }
+
+ private:
+  bool has_priority_ = false;
+  int weight_ = kHttp2DefaultStreamWeight;
+  SpdyStreamId parent_stream_id_ = 0;
+  bool exclusive_ = false;
+  bool padded_ = false;
+  int padding_payload_len_ = 0;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameIR {
+ public:
+  SpdyWindowUpdateIR(SpdyStreamId stream_id, int32_t delta)
+      : SpdyFrameIR(stream_id) {
+    set_delta(delta);
+  }
+  SpdyWindowUpdateIR(const SpdyWindowUpdateIR&) = delete;
+  SpdyWindowUpdateIR& operator=(const SpdyWindowUpdateIR&) = delete;
+
+  int32_t delta() const { return delta_; }
+  void set_delta(int32_t delta) {
+    QUICHE_DCHECK_LE(0, delta);
+    QUICHE_DCHECK_LE(delta, kSpdyMaximumWindowSize);
+    delta_ = delta;
+  }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  int32_t delta_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyPushPromiseIR
+    : public SpdyFrameWithHeaderBlockIR {
+ public:
+  SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
+      : SpdyPushPromiseIR(stream_id, promised_stream_id, Http2HeaderBlock()) {}
+  SpdyPushPromiseIR(SpdyStreamId stream_id,
+                    SpdyStreamId promised_stream_id,
+                    Http2HeaderBlock header_block)
+      : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)),
+        promised_stream_id_(promised_stream_id),
+        padded_(false),
+        padding_payload_len_(0) {}
+  SpdyPushPromiseIR(const SpdyPushPromiseIR&) = delete;
+  SpdyPushPromiseIR& operator=(const SpdyPushPromiseIR&) = delete;
+  SpdyStreamId promised_stream_id() const { return promised_stream_id_; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+  bool padded() const { return padded_; }
+  int padding_payload_len() const { return padding_payload_len_; }
+  void set_padding_len(int padding_len) {
+    QUICHE_DCHECK_GT(padding_len, 0);
+    QUICHE_DCHECK_LE(padding_len, kPaddingSizePerFrame);
+    padded_ = true;
+    // The pad field takes one octet on the wire.
+    padding_payload_len_ = padding_len - 1;
+  }
+
+ private:
+  SpdyStreamId promised_stream_id_;
+
+  bool padded_;
+  int padding_payload_len_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyContinuationIR : public SpdyFrameIR {
+ public:
+  explicit SpdyContinuationIR(SpdyStreamId stream_id);
+  SpdyContinuationIR(const SpdyContinuationIR&) = delete;
+  SpdyContinuationIR& operator=(const SpdyContinuationIR&) = delete;
+  ~SpdyContinuationIR() override;
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  bool end_headers() const { return end_headers_; }
+  void set_end_headers(bool end_headers) { end_headers_ = end_headers; }
+  const std::string& encoding() const { return encoding_; }
+  void take_encoding(std::string encoding) { encoding_ = std::move(encoding); }
+  size_t size() const override;
+
+ private:
+  std::string encoding_;
+  bool end_headers_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameIR {
+ public:
+  explicit SpdyAltSvcIR(SpdyStreamId stream_id);
+  SpdyAltSvcIR(const SpdyAltSvcIR&) = delete;
+  SpdyAltSvcIR& operator=(const SpdyAltSvcIR&) = delete;
+  ~SpdyAltSvcIR() override;
+
+  std::string origin() const { return origin_; }
+  const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector() const {
+    return altsvc_vector_;
+  }
+
+  void set_origin(std::string origin) { origin_ = std::move(origin); }
+  void add_altsvc(const SpdyAltSvcWireFormat::AlternativeService& altsvc) {
+    altsvc_vector_.push_back(altsvc);
+  }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  std::string origin_;
+  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameIR {
+ public:
+  SpdyPriorityIR(SpdyStreamId stream_id,
+                 SpdyStreamId parent_stream_id,
+                 int weight,
+                 bool exclusive)
+      : SpdyFrameIR(stream_id),
+        parent_stream_id_(parent_stream_id),
+        weight_(weight),
+        exclusive_(exclusive) {}
+  SpdyPriorityIR(const SpdyPriorityIR&) = delete;
+  SpdyPriorityIR& operator=(const SpdyPriorityIR&) = delete;
+  SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
+  int weight() const { return weight_; }
+  bool exclusive() const { return exclusive_; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  SpdyStreamId parent_stream_id_;
+  int weight_;
+  bool exclusive_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyPriorityUpdateIR : public SpdyFrameIR {
+ public:
+  SpdyPriorityUpdateIR(SpdyStreamId stream_id,
+                       SpdyStreamId prioritized_stream_id,
+                       std::string priority_field_value)
+      : SpdyFrameIR(stream_id),
+        prioritized_stream_id_(prioritized_stream_id),
+        priority_field_value_(std::move(priority_field_value)) {}
+  SpdyPriorityUpdateIR(const SpdyPriorityUpdateIR&) = delete;
+  SpdyPriorityUpdateIR& operator=(const SpdyPriorityUpdateIR&) = delete;
+  SpdyStreamId prioritized_stream_id() const { return prioritized_stream_id_; }
+  const std::string& priority_field_value() const {
+    return priority_field_value_;
+  }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+ private:
+  SpdyStreamId prioritized_stream_id_;
+  std::string priority_field_value_;
+};
+
+struct QUICHE_EXPORT_PRIVATE AcceptChOriginValuePair {
+  std::string origin;
+  std::string value;
+  bool operator==(const AcceptChOriginValuePair& rhs) const {
+    return origin == rhs.origin && value == rhs.value;
+  }
+};
+
+class QUICHE_EXPORT_PRIVATE SpdyAcceptChIR : public SpdyFrameIR {
+ public:
+  SpdyAcceptChIR(std::vector<AcceptChOriginValuePair> entries)
+      : entries_(std::move(entries)) {}
+  SpdyAcceptChIR(const SpdyAcceptChIR&) = delete;
+  SpdyAcceptChIR& operator=(const SpdyAcceptChIR&) = delete;
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  size_t size() const override;
+
+  const std::vector<AcceptChOriginValuePair>& entries() const {
+    return entries_;
+  }
+
+ private:
+  std::vector<AcceptChOriginValuePair> entries_;
+};
+
+// Represents a frame of unrecognized type.
+class QUICHE_EXPORT_PRIVATE SpdyUnknownIR : public SpdyFrameIR {
+ public:
+  SpdyUnknownIR(SpdyStreamId stream_id,
+                uint8_t type,
+                uint8_t flags,
+                std::string payload)
+      : SpdyFrameIR(stream_id),
+        type_(type),
+        flags_(flags),
+        length_(payload.size()),
+        payload_(std::move(payload)) {}
+  SpdyUnknownIR(const SpdyUnknownIR&) = delete;
+  SpdyUnknownIR& operator=(const SpdyUnknownIR&) = delete;
+  uint8_t type() const { return type_; }
+  uint8_t flags() const { return flags_; }
+  size_t length() const { return length_; }
+  const std::string& payload() const { return payload_; }
+
+  void Visit(SpdyFrameVisitor* visitor) const override;
+
+  SpdyFrameType frame_type() const override;
+
+  int flow_control_window_consumed() const override;
+
+  size_t size() const override;
+
+ protected:
+  // Allows subclasses to overwrite the default payload length.
+  void set_length(size_t length) { length_ = length; }
+
+ private:
+  uint8_t type_;
+  uint8_t flags_;
+  size_t length_;
+  const std::string payload_;
+};
+
+class QUICHE_EXPORT_PRIVATE SpdySerializedFrame {
+ public:
+  SpdySerializedFrame()
+      : frame_(const_cast<char*>("")), size_(0), owns_buffer_(false) {}
+
+  // Create a valid SpdySerializedFrame using a pre-created buffer.
+  // If |owns_buffer| is true, this class takes ownership of the buffer and will
+  // delete it on cleanup.  The buffer must have been created using new char[].
+  // If |owns_buffer| is false, the caller retains ownership of the buffer and
+  // is responsible for making sure the buffer outlives this frame.  In other
+  // words, this class does NOT create a copy of the buffer.
+  SpdySerializedFrame(char* data, size_t size, bool owns_buffer)
+      : frame_(data), size_(size), owns_buffer_(owns_buffer) {}
+
+  SpdySerializedFrame(SpdySerializedFrame&& other)
+      : frame_(other.frame_),
+        size_(other.size_),
+        owns_buffer_(other.owns_buffer_) {
+    // |other| is no longer responsible for the buffer.
+    other.owns_buffer_ = false;
+  }
+  SpdySerializedFrame(const SpdySerializedFrame&) = delete;
+  SpdySerializedFrame& operator=(const SpdySerializedFrame&) = delete;
+
+  SpdySerializedFrame& operator=(SpdySerializedFrame&& other) {
+    // Free buffer if necessary.
+    if (owns_buffer_) {
+      delete[] frame_;
+    }
+    // Take over |other|.
+    frame_ = other.frame_;
+    size_ = other.size_;
+    owns_buffer_ = other.owns_buffer_;
+    // |other| is no longer responsible for the buffer.
+    other.owns_buffer_ = false;
+    return *this;
+  }
+
+  ~SpdySerializedFrame() {
+    if (owns_buffer_) {
+      delete[] frame_;
+    }
+  }
+
+  // Provides access to the frame bytes, which is a buffer containing the frame
+  // packed as expected for sending over the wire.
+  char* data() const { return frame_; }
+
+  // Returns the actual size of the underlying buffer.
+  size_t size() const { return size_; }
+
+  operator absl::string_view() const {
+    return absl::string_view{frame_, size_};
+  }
+
+  operator std::string() const { return std::string{frame_, size_}; }
+
+  // Returns a buffer containing the contents of the frame, of which the caller
+  // takes ownership, and clears this SpdySerializedFrame.
+  char* ReleaseBuffer() {
+    char* buffer;
+    if (owns_buffer_) {
+      // If the buffer is owned, relinquish ownership to the caller.
+      buffer = frame_;
+      owns_buffer_ = false;
+    } else {
+      // Otherwise, we need to make a copy to give to the caller.
+      buffer = new char[size_];
+      memcpy(buffer, frame_, size_);
+    }
+    *this = SpdySerializedFrame();
+    return buffer;
+  }
+
+ protected:
+  char* frame_;
+
+ private:
+  size_t size_;
+  bool owns_buffer_;
+};
+
+// This interface is for classes that want to process SpdyFrameIRs without
+// having to know what type they are.  An instance of this interface can be
+// passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
+// method of this class will be called.
+class QUICHE_EXPORT_PRIVATE SpdyFrameVisitor {
+ public:
+  SpdyFrameVisitor() {}
+  SpdyFrameVisitor(const SpdyFrameVisitor&) = delete;
+  SpdyFrameVisitor& operator=(const SpdyFrameVisitor&) = delete;
+  virtual ~SpdyFrameVisitor() {}
+
+  virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
+  virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
+  virtual void VisitPing(const SpdyPingIR& ping) = 0;
+  virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
+  virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
+  virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
+  virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0;
+  virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0;
+  virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) = 0;
+  virtual void VisitPriority(const SpdyPriorityIR& priority) = 0;
+  virtual void VisitData(const SpdyDataIR& data) = 0;
+  virtual void VisitPriorityUpdate(
+      const SpdyPriorityUpdateIR& priority_update) = 0;
+  virtual void VisitAcceptCh(const SpdyAcceptChIR& accept_ch) = 0;
+  virtual void VisitUnknown(const SpdyUnknownIR& /*unknown*/) {
+    // TODO(birenroy): make abstract.
+  }
+};
+
+// Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting
+// SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in
+// order to extract debug/internal information about the SpdyFramer as it
+// operates.
+//
+// Most HTTP2 implementations need not bother with this interface at all.
+class QUICHE_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface {
+ public:
+  virtual ~SpdyFramerDebugVisitorInterface() {}
+
+  // Called after compressing a frame with a payload of
+  // a list of name-value pairs.
+  // |payload_len| is the uncompressed payload size.
+  // |frame_len| is the compressed frame size.
+  virtual void OnSendCompressedFrame(SpdyStreamId /*stream_id*/,
+                                     SpdyFrameType /*type*/,
+                                     size_t /*payload_len*/,
+                                     size_t /*frame_len*/) {}
+
+  // Called when a frame containing a compressed payload of
+  // name-value pairs is received.
+  // |frame_len| is the compressed frame size.
+  virtual void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
+                                        SpdyFrameType /*type*/,
+                                        size_t /*frame_len*/) {}
+};
+
+// Calculates the number of bytes required to serialize a SpdyHeadersIR, not
+// including the bytes to be used for the encoded header set.
+size_t GetHeaderFrameSizeSansBlock(const SpdyHeadersIR& header_ir);
+
+// Calculates the number of bytes required to serialize a SpdyPushPromiseIR,
+// not including the bytes to be used for the encoded header set.
+size_t GetPushPromiseFrameSizeSansBlock(
+    const SpdyPushPromiseIR& push_promise_ir);
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
diff --git a/quiche/spdy/core/spdy_protocol_test.cc b/quiche/spdy/core/spdy_protocol_test.cc
new file mode 100644
index 0000000..3084907
--- /dev/null
+++ b/quiche/spdy/core/spdy_protocol_test.cc
@@ -0,0 +1,275 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_protocol.h"
+
+#include <iostream>
+#include <limits>
+#include <memory>
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_test_helpers.h"
+#include "quiche/spdy/core/spdy_bitmasks.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+namespace spdy {
+
+std::ostream& operator<<(std::ostream& os,
+                         const SpdyStreamPrecedence precedence) {
+  if (precedence.is_spdy3_priority()) {
+    os << "SpdyStreamPrecedence[spdy3_priority=" << precedence.spdy3_priority()
+       << "]";
+  } else {
+    os << "SpdyStreamPrecedence[parent_id=" << precedence.parent_id()
+       << ", weight=" << precedence.weight()
+       << ", is_exclusive=" << precedence.is_exclusive() << "]";
+  }
+  return os;
+}
+
+namespace test {
+
+TEST(SpdyProtocolTest, ClampSpdy3Priority) {
+  EXPECT_QUICHE_BUG(EXPECT_EQ(7, ClampSpdy3Priority(8)), "Invalid priority: 8");
+  EXPECT_EQ(kV3LowestPriority, ClampSpdy3Priority(kV3LowestPriority));
+  EXPECT_EQ(kV3HighestPriority, ClampSpdy3Priority(kV3HighestPriority));
+}
+
+TEST(SpdyProtocolTest, ClampHttp2Weight) {
+  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MinStreamWeight, ClampHttp2Weight(0)),
+                    "Invalid weight: 0");
+  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MaxStreamWeight, ClampHttp2Weight(300)),
+                    "Invalid weight: 300");
+  EXPECT_EQ(kHttp2MinStreamWeight, ClampHttp2Weight(kHttp2MinStreamWeight));
+  EXPECT_EQ(kHttp2MaxStreamWeight, ClampHttp2Weight(kHttp2MaxStreamWeight));
+}
+
+TEST(SpdyProtocolTest, Spdy3PriorityToHttp2Weight) {
+  EXPECT_EQ(256, Spdy3PriorityToHttp2Weight(0));
+  EXPECT_EQ(220, Spdy3PriorityToHttp2Weight(1));
+  EXPECT_EQ(183, Spdy3PriorityToHttp2Weight(2));
+  EXPECT_EQ(147, Spdy3PriorityToHttp2Weight(3));
+  EXPECT_EQ(110, Spdy3PriorityToHttp2Weight(4));
+  EXPECT_EQ(74, Spdy3PriorityToHttp2Weight(5));
+  EXPECT_EQ(37, Spdy3PriorityToHttp2Weight(6));
+  EXPECT_EQ(1, Spdy3PriorityToHttp2Weight(7));
+}
+
+TEST(SpdyProtocolTest, Http2WeightToSpdy3Priority) {
+  EXPECT_EQ(0u, Http2WeightToSpdy3Priority(256));
+  EXPECT_EQ(0u, Http2WeightToSpdy3Priority(221));
+  EXPECT_EQ(1u, Http2WeightToSpdy3Priority(220));
+  EXPECT_EQ(1u, Http2WeightToSpdy3Priority(184));
+  EXPECT_EQ(2u, Http2WeightToSpdy3Priority(183));
+  EXPECT_EQ(2u, Http2WeightToSpdy3Priority(148));
+  EXPECT_EQ(3u, Http2WeightToSpdy3Priority(147));
+  EXPECT_EQ(3u, Http2WeightToSpdy3Priority(111));
+  EXPECT_EQ(4u, Http2WeightToSpdy3Priority(110));
+  EXPECT_EQ(4u, Http2WeightToSpdy3Priority(75));
+  EXPECT_EQ(5u, Http2WeightToSpdy3Priority(74));
+  EXPECT_EQ(5u, Http2WeightToSpdy3Priority(38));
+  EXPECT_EQ(6u, Http2WeightToSpdy3Priority(37));
+  EXPECT_EQ(6u, Http2WeightToSpdy3Priority(2));
+  EXPECT_EQ(7u, Http2WeightToSpdy3Priority(1));
+}
+
+TEST(SpdyProtocolTest, IsValidHTTP2FrameStreamId) {
+  // Stream-specific frames must have non-zero stream ids
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::DATA));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::DATA));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::HEADERS));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::HEADERS));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::PRIORITY));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::PRIORITY));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::RST_STREAM));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::RST_STREAM));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::CONTINUATION));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::CONTINUATION));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::PUSH_PROMISE));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::PUSH_PROMISE));
+
+  // Connection-level frames must have zero stream ids
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::GOAWAY));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::GOAWAY));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::SETTINGS));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::SETTINGS));
+  EXPECT_FALSE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::PING));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::PING));
+
+  // Frames that are neither stream-specific nor connection-level
+  // should not have their stream id declared invalid
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::WINDOW_UPDATE));
+  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::WINDOW_UPDATE));
+}
+
+TEST(SpdyProtocolTest, ParseSettingsId) {
+  SpdyKnownSettingsId setting_id;
+  EXPECT_FALSE(ParseSettingsId(0, &setting_id));
+  EXPECT_TRUE(ParseSettingsId(1, &setting_id));
+  EXPECT_EQ(SETTINGS_HEADER_TABLE_SIZE, setting_id);
+  EXPECT_TRUE(ParseSettingsId(2, &setting_id));
+  EXPECT_EQ(SETTINGS_ENABLE_PUSH, setting_id);
+  EXPECT_TRUE(ParseSettingsId(3, &setting_id));
+  EXPECT_EQ(SETTINGS_MAX_CONCURRENT_STREAMS, setting_id);
+  EXPECT_TRUE(ParseSettingsId(4, &setting_id));
+  EXPECT_EQ(SETTINGS_INITIAL_WINDOW_SIZE, setting_id);
+  EXPECT_TRUE(ParseSettingsId(5, &setting_id));
+  EXPECT_EQ(SETTINGS_MAX_FRAME_SIZE, setting_id);
+  EXPECT_TRUE(ParseSettingsId(6, &setting_id));
+  EXPECT_EQ(SETTINGS_MAX_HEADER_LIST_SIZE, setting_id);
+  EXPECT_FALSE(ParseSettingsId(7, &setting_id));
+  EXPECT_TRUE(ParseSettingsId(8, &setting_id));
+  EXPECT_EQ(SETTINGS_ENABLE_CONNECT_PROTOCOL, setting_id);
+  EXPECT_TRUE(ParseSettingsId(9, &setting_id));
+  EXPECT_EQ(SETTINGS_DEPRECATE_HTTP2_PRIORITIES, setting_id);
+  EXPECT_FALSE(ParseSettingsId(10, &setting_id));
+  EXPECT_FALSE(ParseSettingsId(0xFF44, &setting_id));
+  EXPECT_TRUE(ParseSettingsId(0xFF45, &setting_id));
+  EXPECT_EQ(SETTINGS_EXPERIMENT_SCHEDULER, setting_id);
+  EXPECT_FALSE(ParseSettingsId(0xFF46, &setting_id));
+}
+
+TEST(SpdyProtocolTest, SettingsIdToString) {
+  struct {
+    SpdySettingsId setting_id;
+    const std::string expected_string;
+  } test_cases[] = {
+      {0, "SETTINGS_UNKNOWN_0"},
+      {SETTINGS_HEADER_TABLE_SIZE, "SETTINGS_HEADER_TABLE_SIZE"},
+      {SETTINGS_ENABLE_PUSH, "SETTINGS_ENABLE_PUSH"},
+      {SETTINGS_MAX_CONCURRENT_STREAMS, "SETTINGS_MAX_CONCURRENT_STREAMS"},
+      {SETTINGS_INITIAL_WINDOW_SIZE, "SETTINGS_INITIAL_WINDOW_SIZE"},
+      {SETTINGS_MAX_FRAME_SIZE, "SETTINGS_MAX_FRAME_SIZE"},
+      {SETTINGS_MAX_HEADER_LIST_SIZE, "SETTINGS_MAX_HEADER_LIST_SIZE"},
+      {7, "SETTINGS_UNKNOWN_7"},
+      {SETTINGS_ENABLE_CONNECT_PROTOCOL, "SETTINGS_ENABLE_CONNECT_PROTOCOL"},
+      {SETTINGS_DEPRECATE_HTTP2_PRIORITIES,
+       "SETTINGS_DEPRECATE_HTTP2_PRIORITIES"},
+      {0xa, "SETTINGS_UNKNOWN_a"},
+      {0xFF44, "SETTINGS_UNKNOWN_ff44"},
+      {0xFF45, "SETTINGS_EXPERIMENT_SCHEDULER"},
+      {0xFF46, "SETTINGS_UNKNOWN_ff46"}};
+  for (auto test_case : test_cases) {
+    EXPECT_EQ(test_case.expected_string,
+              SettingsIdToString(test_case.setting_id));
+  }
+}
+
+TEST(SpdyStreamPrecedenceTest, Basic) {
+  SpdyStreamPrecedence spdy3_prec(2);
+  EXPECT_TRUE(spdy3_prec.is_spdy3_priority());
+  EXPECT_EQ(2, spdy3_prec.spdy3_priority());
+  EXPECT_EQ(kHttp2RootStreamId, spdy3_prec.parent_id());
+  EXPECT_EQ(Spdy3PriorityToHttp2Weight(2), spdy3_prec.weight());
+  EXPECT_FALSE(spdy3_prec.is_exclusive());
+
+  for (bool is_exclusive : {true, false}) {
+    SpdyStreamPrecedence h2_prec(7, 123, is_exclusive);
+    EXPECT_FALSE(h2_prec.is_spdy3_priority());
+    EXPECT_EQ(Http2WeightToSpdy3Priority(123), h2_prec.spdy3_priority());
+    EXPECT_EQ(7u, h2_prec.parent_id());
+    EXPECT_EQ(123, h2_prec.weight());
+    EXPECT_EQ(is_exclusive, h2_prec.is_exclusive());
+  }
+}
+
+TEST(SpdyStreamPrecedenceTest, Clamping) {
+  EXPECT_QUICHE_BUG(EXPECT_EQ(7, SpdyStreamPrecedence(8).spdy3_priority()),
+                    "Invalid priority: 8");
+  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MinStreamWeight,
+                              SpdyStreamPrecedence(3, 0, false).weight()),
+                    "Invalid weight: 0");
+  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MaxStreamWeight,
+                              SpdyStreamPrecedence(3, 300, false).weight()),
+                    "Invalid weight: 300");
+}
+
+TEST(SpdyStreamPrecedenceTest, Copying) {
+  SpdyStreamPrecedence prec1(3);
+  SpdyStreamPrecedence copy1(prec1);
+  EXPECT_TRUE(copy1.is_spdy3_priority());
+  EXPECT_EQ(3, copy1.spdy3_priority());
+
+  SpdyStreamPrecedence prec2(4, 5, true);
+  SpdyStreamPrecedence copy2(prec2);
+  EXPECT_FALSE(copy2.is_spdy3_priority());
+  EXPECT_EQ(4u, copy2.parent_id());
+  EXPECT_EQ(5, copy2.weight());
+  EXPECT_TRUE(copy2.is_exclusive());
+
+  copy1 = prec2;
+  EXPECT_FALSE(copy1.is_spdy3_priority());
+  EXPECT_EQ(4u, copy1.parent_id());
+  EXPECT_EQ(5, copy1.weight());
+  EXPECT_TRUE(copy1.is_exclusive());
+
+  copy2 = prec1;
+  EXPECT_TRUE(copy2.is_spdy3_priority());
+  EXPECT_EQ(3, copy2.spdy3_priority());
+}
+
+TEST(SpdyStreamPrecedenceTest, Equals) {
+  EXPECT_EQ(SpdyStreamPrecedence(3), SpdyStreamPrecedence(3));
+  EXPECT_NE(SpdyStreamPrecedence(3), SpdyStreamPrecedence(4));
+
+  EXPECT_EQ(SpdyStreamPrecedence(1, 2, false),
+            SpdyStreamPrecedence(1, 2, false));
+  EXPECT_NE(SpdyStreamPrecedence(1, 2, false),
+            SpdyStreamPrecedence(2, 2, false));
+  EXPECT_NE(SpdyStreamPrecedence(1, 2, false),
+            SpdyStreamPrecedence(1, 3, false));
+  EXPECT_NE(SpdyStreamPrecedence(1, 2, false),
+            SpdyStreamPrecedence(1, 2, true));
+
+  SpdyStreamPrecedence spdy3_prec(3);
+  SpdyStreamPrecedence h2_prec(spdy3_prec.parent_id(), spdy3_prec.weight(),
+                               spdy3_prec.is_exclusive());
+  EXPECT_NE(spdy3_prec, h2_prec);
+}
+
+TEST(SpdyDataIRTest, Construct) {
+  // Confirm that it makes a string of zero length from a
+  // absl::string_view(nullptr).
+  absl::string_view s1;
+  SpdyDataIR d1(/* stream_id = */ 1, s1);
+  EXPECT_EQ(0u, d1.data_len());
+  EXPECT_NE(nullptr, d1.data());
+
+  // Confirms makes a copy of char array.
+  const char s2[] = "something";
+  SpdyDataIR d2(/* stream_id = */ 2, s2);
+  EXPECT_EQ(absl::string_view(d2.data(), d2.data_len()), s2);
+  EXPECT_NE(absl::string_view(d1.data(), d1.data_len()), s2);
+  EXPECT_EQ((int)d1.data_len(), d1.flow_control_window_consumed());
+
+  // Confirm copies a const string.
+  const std::string foo = "foo";
+  SpdyDataIR d3(/* stream_id = */ 3, foo);
+  EXPECT_EQ(foo, d3.data());
+  EXPECT_EQ((int)d3.data_len(), d3.flow_control_window_consumed());
+
+  // Confirm copies a non-const string.
+  std::string bar = "bar";
+  SpdyDataIR d4(/* stream_id = */ 4, bar);
+  EXPECT_EQ("bar", bar);
+  EXPECT_EQ("bar", absl::string_view(d4.data(), d4.data_len()));
+
+  // Confirm moves an rvalue reference. Note that the test string "baz" is too
+  // short to trigger the move optimization, and instead a copy occurs.
+  std::string baz = "the quick brown fox";
+  SpdyDataIR d5(/* stream_id = */ 5, std::move(baz));
+  EXPECT_EQ("", baz);
+  EXPECT_EQ(absl::string_view(d5.data(), d5.data_len()), "the quick brown fox");
+
+  // Confirms makes a copy of string literal.
+  SpdyDataIR d7(/* stream_id = */ 7, "something else");
+  EXPECT_EQ(absl::string_view(d7.data(), d7.data_len()), "something else");
+
+  SpdyDataIR d8(/* stream_id = */ 8, "shawarma");
+  d8.set_padding_len(20);
+  EXPECT_EQ(28, d8.flow_control_window_consumed());
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_protocol_test_utils.cc b/quiche/spdy/core/spdy_protocol_test_utils.cc
new file mode 100644
index 0000000..9bd3a06
--- /dev/null
+++ b/quiche/spdy/core/spdy_protocol_test_utils.cc
@@ -0,0 +1,155 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_protocol_test_utils.h"
+
+#include <cstdint>
+
+#include "absl/strings/string_view.h"
+
+namespace spdy {
+namespace test {
+
+// TODO(jamessynge): Where it makes sense in these functions, it would be nice
+// to make use of the existing gMock matchers here, instead of rolling our own.
+
+::testing::AssertionResult VerifySpdyFrameWithHeaderBlockIREquals(
+    const SpdyFrameWithHeaderBlockIR& expected,
+    const SpdyFrameWithHeaderBlockIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameWithHeaderBlockIREquals";
+  VERIFY_TRUE(actual.header_block() == expected.header_block());
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyAltSvcIR& expected,
+                                                   const SpdyAltSvcIR& actual) {
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_EQ(expected.origin(), actual.origin());
+  VERIFY_THAT(actual.altsvc_vector(),
+              ::testing::ContainerEq(expected.altsvc_vector()));
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyContinuationIR& /*expected*/,
+    const SpdyContinuationIR& /*actual*/) {
+  return ::testing::AssertionFailure()
+         << "VerifySpdyFrameIREquals SpdyContinuationIR not yet implemented";
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyDataIR& expected,
+                                                   const SpdyDataIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyDataIR";
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_EQ(expected.fin(), actual.fin());
+  VERIFY_EQ(expected.data_len(), actual.data_len());
+  if (expected.data() == nullptr) {
+    VERIFY_EQ(nullptr, actual.data());
+  } else {
+    VERIFY_EQ(absl::string_view(expected.data(), expected.data_len()),
+              absl::string_view(actual.data(), actual.data_len()));
+  }
+  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyGoAwayIR& expected,
+                                                   const SpdyGoAwayIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyGoAwayIR";
+  VERIFY_EQ(expected.last_good_stream_id(), actual.last_good_stream_id());
+  VERIFY_EQ(expected.error_code(), actual.error_code());
+  VERIFY_EQ(expected.description(), actual.description());
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyHeadersIR& expected,
+    const SpdyHeadersIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyHeadersIR";
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_EQ(expected.fin(), actual.fin());
+  VERIFY_SUCCESS(VerifySpdyFrameWithHeaderBlockIREquals(expected, actual));
+  VERIFY_EQ(expected.has_priority(), actual.has_priority());
+  if (expected.has_priority()) {
+    VERIFY_SUCCESS(VerifySpdyFrameWithPriorityIREquals(expected, actual));
+  }
+  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyPingIR& expected,
+                                                   const SpdyPingIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyPingIR";
+  VERIFY_EQ(expected.id(), actual.id());
+  VERIFY_EQ(expected.is_ack(), actual.is_ack());
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyPriorityIR& expected,
+    const SpdyPriorityIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyPriorityIR";
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_SUCCESS(VerifySpdyFrameWithPriorityIREquals(expected, actual));
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyPushPromiseIR& expected,
+    const SpdyPushPromiseIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyPushPromiseIR";
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
+  VERIFY_EQ(expected.promised_stream_id(), actual.promised_stream_id());
+  VERIFY_SUCCESS(VerifySpdyFrameWithHeaderBlockIREquals(expected, actual));
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyRstStreamIR& expected,
+    const SpdyRstStreamIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyRstStreamIR";
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_EQ(expected.error_code(), actual.error_code());
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdySettingsIR& expected,
+    const SpdySettingsIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdySettingsIR";
+  // Note, ignoring non-HTTP/2 fields such as clear_settings.
+  VERIFY_EQ(expected.is_ack(), actual.is_ack());
+
+  // Note, the following doesn't work because there isn't a comparator and
+  // formatter for SpdySettingsIR::Value. Fixable if we cared.
+  //
+  //   VERIFY_THAT(actual.values(), ::testing::ContainerEq(actual.values()));
+
+  VERIFY_EQ(expected.values().size(), actual.values().size());
+  for (const auto& entry : expected.values()) {
+    const auto& param = entry.first;
+    auto actual_itr = actual.values().find(param);
+    VERIFY_TRUE(!(actual_itr == actual.values().end()))
+        << "actual doesn't contain param: " << param;
+    uint32_t expected_value = entry.second;
+    uint32_t actual_value = actual_itr->second;
+    VERIFY_EQ(expected_value, actual_value)
+        << "Values don't match for parameter: " << param;
+  }
+
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyWindowUpdateIR& expected,
+    const SpdyWindowUpdateIR& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyWindowUpdateIR";
+  VERIFY_EQ(expected.stream_id(), actual.stream_id());
+  VERIFY_EQ(expected.delta(), actual.delta());
+  return ::testing::AssertionSuccess();
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_protocol_test_utils.h b/quiche/spdy/core/spdy_protocol_test_utils.h
new file mode 100644
index 0000000..1f147a6
--- /dev/null
+++ b/quiche/spdy/core/spdy_protocol_test_utils.h
@@ -0,0 +1,149 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
+#define QUICHE_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
+
+// These functions support tests that need to compare two concrete SpdyFrameIR
+// instances for equality. They return AssertionResult, so they may be used as
+// follows:
+//
+//    SomeSpdyFrameIRSubClass expected_ir(...);
+//    std::unique_ptr<SpdyFrameIR> collected_frame;
+//    ... some test code that may fill in collected_frame ...
+//    ASSERT_TRUE(VerifySpdyFrameIREquals(expected_ir, collected_frame.get()));
+//
+// TODO(jamessynge): Where it makes sense in these functions, it would be nice
+// to make use of the existing gMock matchers here, instead of rolling our own.
+
+#include <typeinfo>
+
+#include "quiche/http2/platform/api/http2_test_helpers.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+namespace spdy {
+namespace test {
+
+// Verify the header entries in two SpdyFrameWithHeaderBlockIR instances
+// are the same.
+::testing::AssertionResult VerifySpdyFrameWithHeaderBlockIREquals(
+    const SpdyFrameWithHeaderBlockIR& expected,
+    const SpdyFrameWithHeaderBlockIR& actual);
+
+// Verify that the padding in two frames of type T is the same.
+template <class T>
+::testing::AssertionResult VerifySpdyFrameWithPaddingIREquals(const T& expected,
+                                                              const T& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameWithPaddingIREquals";
+  VERIFY_EQ(expected.padded(), actual.padded());
+  if (expected.padded()) {
+    VERIFY_EQ(expected.padding_payload_len(), actual.padding_payload_len());
+  }
+
+  return ::testing::AssertionSuccess();
+}
+
+// Verify the priority fields in two frames of type T are the same.
+template <class T>
+::testing::AssertionResult VerifySpdyFrameWithPriorityIREquals(
+    const T& expected,
+    const T& actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameWithPriorityIREquals";
+  VERIFY_EQ(expected.parent_stream_id(), actual.parent_stream_id());
+  VERIFY_EQ(expected.weight(), actual.weight());
+  VERIFY_EQ(expected.exclusive(), actual.exclusive());
+  return ::testing::AssertionSuccess();
+}
+
+// Verify that two SpdyAltSvcIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyAltSvcIR& expected,
+                                                   const SpdyAltSvcIR& actual);
+
+// VerifySpdyFrameIREquals for SpdyContinuationIR frames isn't really needed
+// because we don't really make use of SpdyContinuationIR, instead creating
+// SpdyHeadersIR or SpdyPushPromiseIR with the pre-encoding form of the HPACK
+// block (i.e. we don't yet have a CONTINUATION frame).
+//
+// ::testing::AssertionResult VerifySpdyFrameIREquals(
+//     const SpdyContinuationIR& expected,
+//     const SpdyContinuationIR& actual) {
+//   return ::testing::AssertionFailure()
+//          << "VerifySpdyFrameIREquals SpdyContinuationIR NYI";
+// }
+
+// Verify that two SpdyDataIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyDataIR& expected,
+                                                   const SpdyDataIR& actual);
+
+// Verify that two SpdyGoAwayIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyGoAwayIR& expected,
+                                                   const SpdyGoAwayIR& actual);
+
+// Verify that two SpdyHeadersIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyHeadersIR& expected,
+    const SpdyHeadersIR& actual);
+
+// Verify that two SpdyPingIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyPingIR& expected,
+                                                   const SpdyPingIR& actual);
+
+// Verify that two SpdyPriorityIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyPriorityIR& expected,
+    const SpdyPriorityIR& actual);
+
+// Verify that two SpdyPushPromiseIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyPushPromiseIR& expected,
+    const SpdyPushPromiseIR& actual);
+
+// Verify that two SpdyRstStreamIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyRstStreamIR& expected,
+    const SpdyRstStreamIR& actual);
+
+// Verify that two SpdySettingsIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdySettingsIR& expected,
+    const SpdySettingsIR& actual);
+
+// Verify that two SpdyWindowUpdateIR frames are the same.
+::testing::AssertionResult VerifySpdyFrameIREquals(
+    const SpdyWindowUpdateIR& expected,
+    const SpdyWindowUpdateIR& actual);
+
+// Verify that either expected and actual are both nullptr, or that both are not
+// nullptr, and that actual is of type E, and that it matches expected.
+template <class E>
+::testing::AssertionResult VerifySpdyFrameIREquals(const E* expected,
+                                                   const SpdyFrameIR* actual) {
+  if (expected == nullptr || actual == nullptr) {
+    QUICHE_VLOG(1) << "VerifySpdyFrameIREquals one null";
+    VERIFY_EQ(expected, nullptr);
+    VERIFY_EQ(actual, nullptr);
+    return ::testing::AssertionSuccess();
+  }
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals not null";
+  VERIFY_EQ(actual->frame_type(), expected->frame_type());
+  const E* actual2 = static_cast<const E*>(actual);
+  return VerifySpdyFrameIREquals(*expected, *actual2);
+}
+
+// Verify that actual is not nullptr, that it is of type E and that it
+// matches expected.
+template <class E>
+::testing::AssertionResult VerifySpdyFrameIREquals(const E& expected,
+                                                   const SpdyFrameIR* actual) {
+  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals";
+  return VerifySpdyFrameIREquals(&expected, actual);
+}
+
+}  // namespace test
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
diff --git a/quiche/spdy/core/spdy_simple_arena.cc b/quiche/spdy/core/spdy_simple_arena.cc
new file mode 100644
index 0000000..0b3b798
--- /dev/null
+++ b/quiche/spdy/core/spdy_simple_arena.cc
@@ -0,0 +1,106 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_simple_arena.h"
+
+#include <algorithm>
+#include <cstring>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+
+namespace spdy {
+
+SpdySimpleArena::SpdySimpleArena(size_t block_size) : block_size_(block_size) {}
+
+SpdySimpleArena::~SpdySimpleArena() = default;
+
+SpdySimpleArena::SpdySimpleArena(SpdySimpleArena&& other) = default;
+SpdySimpleArena& SpdySimpleArena::operator=(SpdySimpleArena&& other) = default;
+
+char* SpdySimpleArena::Alloc(size_t size) {
+  Reserve(size);
+  Block& b = blocks_.back();
+  QUICHE_DCHECK_GE(b.size, b.used + size);
+  char* out = b.data.get() + b.used;
+  b.used += size;
+  return out;
+}
+
+char* SpdySimpleArena::Realloc(char* original, size_t oldsize, size_t newsize) {
+  QUICHE_DCHECK(!blocks_.empty());
+  Block& last = blocks_.back();
+  if (last.data.get() <= original && original < last.data.get() + last.size) {
+    // (original, oldsize) is in the last Block.
+    QUICHE_DCHECK_GE(last.data.get() + last.used, original + oldsize);
+    if (original + oldsize == last.data.get() + last.used) {
+      // (original, oldsize) was the most recent allocation,
+      if (original + newsize < last.data.get() + last.size) {
+        // (original, newsize) fits in the same Block.
+        last.used += newsize - oldsize;
+        return original;
+      }
+    }
+  }
+  char* out = Alloc(newsize);
+  memcpy(out, original, oldsize);
+  return out;
+}
+
+char* SpdySimpleArena::Memdup(const char* data, size_t size) {
+  char* out = Alloc(size);
+  memcpy(out, data, size);
+  return out;
+}
+
+void SpdySimpleArena::Free(char* data, size_t size) {
+  if (blocks_.empty()) {
+    return;
+  }
+  Block& b = blocks_.back();
+  if (size <= b.used && data + size == b.data.get() + b.used) {
+    // The memory region passed by the caller was the most recent allocation
+    // from the final block in this arena.
+    b.used -= size;
+  }
+}
+
+void SpdySimpleArena::Reset() {
+  blocks_.clear();
+  status_.bytes_allocated_ = 0;
+}
+
+void SpdySimpleArena::Reserve(size_t additional_space) {
+  if (blocks_.empty()) {
+    AllocBlock(std::max(additional_space, block_size_));
+  } else {
+    const Block& last = blocks_.back();
+    if (last.size < last.used + additional_space) {
+      AllocBlock(std::max(additional_space, block_size_));
+    }
+  }
+}
+
+void SpdySimpleArena::AllocBlock(size_t size) {
+  blocks_.push_back(Block(size));
+  status_.bytes_allocated_ += size;
+}
+
+SpdySimpleArena::Block::Block(size_t s) : data(new char[s]), size(s), used(0) {}
+
+SpdySimpleArena::Block::~Block() = default;
+
+SpdySimpleArena::Block::Block(SpdySimpleArena::Block&& other)
+    : size(other.size), used(other.used) {
+  data = std::move(other.data);
+}
+
+SpdySimpleArena::Block& SpdySimpleArena::Block::operator=(
+    SpdySimpleArena::Block&& other) {
+  size = other.size;
+  used = other.used;
+  data = std::move(other.data);
+  return *this;
+}
+
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_simple_arena.h b/quiche/spdy/core/spdy_simple_arena.h
new file mode 100644
index 0000000..99a6f74
--- /dev/null
+++ b/quiche/spdy/core/spdy_simple_arena.h
@@ -0,0 +1,77 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
+#define QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
+
+#include <memory>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_export.h"
+
+namespace spdy {
+
+// Allocates large blocks of memory, and doles them out in smaller chunks.
+// Not thread-safe.
+class QUICHE_EXPORT_PRIVATE SpdySimpleArena {
+ public:
+  class Status {
+   private:
+    friend class SpdySimpleArena;
+    size_t bytes_allocated_;
+
+   public:
+    Status() : bytes_allocated_(0) {}
+    size_t bytes_allocated() const { return bytes_allocated_; }
+  };
+
+  // Blocks allocated by this arena will be at least |block_size| bytes.
+  explicit SpdySimpleArena(size_t block_size);
+  ~SpdySimpleArena();
+
+  // Copy and assign are not allowed.
+  SpdySimpleArena() = delete;
+  SpdySimpleArena(const SpdySimpleArena&) = delete;
+  SpdySimpleArena& operator=(const SpdySimpleArena&) = delete;
+
+  // Move is allowed.
+  SpdySimpleArena(SpdySimpleArena&& other);
+  SpdySimpleArena& operator=(SpdySimpleArena&& other);
+
+  char* Alloc(size_t size);
+  char* Realloc(char* original, size_t oldsize, size_t newsize);
+  char* Memdup(const char* data, size_t size);
+
+  // If |data| and |size| describe the most recent allocation made from this
+  // arena, the memory is reclaimed. Otherwise, this method is a no-op.
+  void Free(char* data, size_t size);
+
+  void Reset();
+
+  Status status() const { return status_; }
+
+ private:
+  struct Block {
+    std::unique_ptr<char[]> data;
+    size_t size = 0;
+    size_t used = 0;
+
+    explicit Block(size_t s);
+    ~Block();
+
+    Block(Block&& other);
+    Block& operator=(Block&& other);
+  };
+
+  void Reserve(size_t additional_space);
+  void AllocBlock(size_t size);
+
+  size_t block_size_;
+  std::vector<Block> blocks_;
+  Status status_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
diff --git a/quiche/spdy/core/spdy_simple_arena_test.cc b/quiche/spdy/core/spdy_simple_arena_test.cc
new file mode 100644
index 0000000..9708375
--- /dev/null
+++ b/quiche/spdy/core/spdy_simple_arena_test.cc
@@ -0,0 +1,141 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_simple_arena.h"
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+
+namespace spdy {
+namespace {
+
+size_t kDefaultBlockSize = 2048;
+const char kTestString[] = "This is a decently long test string.";
+
+TEST(SpdySimpleArenaTest, NoAllocationOnConstruction) {
+  SpdySimpleArena arena(kDefaultBlockSize);
+  EXPECT_EQ(0u, arena.status().bytes_allocated());
+}
+
+TEST(SpdySimpleArenaTest, Memdup) {
+  SpdySimpleArena arena(kDefaultBlockSize);
+  const size_t length = strlen(kTestString);
+  char* c = arena.Memdup(kTestString, length);
+  EXPECT_NE(nullptr, c);
+  EXPECT_NE(c, kTestString);
+  EXPECT_EQ(absl::string_view(c, length), kTestString);
+}
+
+TEST(SpdySimpleArenaTest, MemdupLargeString) {
+  SpdySimpleArena arena(10 /* block size */);
+  const size_t length = strlen(kTestString);
+  char* c = arena.Memdup(kTestString, length);
+  EXPECT_NE(nullptr, c);
+  EXPECT_NE(c, kTestString);
+  EXPECT_EQ(absl::string_view(c, length), kTestString);
+}
+
+TEST(SpdySimpleArenaTest, MultipleBlocks) {
+  SpdySimpleArena arena(40 /* block size */);
+  std::vector<std::string> strings = {
+      "One decently long string.", "Another string.",
+      "A third string that will surely go in a different block."};
+  std::vector<absl::string_view> copies;
+  for (const std::string& s : strings) {
+    absl::string_view sp(arena.Memdup(s.data(), s.size()), s.size());
+    copies.push_back(sp);
+  }
+  EXPECT_EQ(strings.size(), copies.size());
+  for (size_t i = 0; i < strings.size(); ++i) {
+    EXPECT_EQ(copies[i], strings[i]);
+  }
+}
+
+TEST(SpdySimpleArenaTest, UseAfterReset) {
+  SpdySimpleArena arena(kDefaultBlockSize);
+  const size_t length = strlen(kTestString);
+  char* c = arena.Memdup(kTestString, length);
+  arena.Reset();
+  c = arena.Memdup(kTestString, length);
+  EXPECT_NE(nullptr, c);
+  EXPECT_NE(c, kTestString);
+  EXPECT_EQ(absl::string_view(c, length), kTestString);
+}
+
+TEST(SpdySimpleArenaTest, Free) {
+  SpdySimpleArena arena(kDefaultBlockSize);
+  const size_t length = strlen(kTestString);
+  // Freeing memory not owned by the arena should be a no-op, and freeing
+  // before any allocations from the arena should be a no-op.
+  arena.Free(const_cast<char*>(kTestString), length);
+  char* c1 = arena.Memdup("Foo", 3);
+  char* c2 = arena.Memdup(kTestString, length);
+  arena.Free(const_cast<char*>(kTestString), length);
+  char* c3 = arena.Memdup("Bar", 3);
+  char* c4 = arena.Memdup(kTestString, length);
+  EXPECT_NE(c1, c2);
+  EXPECT_NE(c1, c3);
+  EXPECT_NE(c1, c4);
+  EXPECT_NE(c2, c3);
+  EXPECT_NE(c2, c4);
+  EXPECT_NE(c3, c4);
+  // Freeing c4 should succeed, since it was the most recent allocation.
+  arena.Free(c4, length);
+  // Freeing c2 should be a no-op.
+  arena.Free(c2, length);
+  // c5 should reuse memory that was previously used by c4.
+  char* c5 = arena.Memdup("Baz", 3);
+  EXPECT_EQ(c4, c5);
+}
+
+TEST(SpdySimpleArenaTest, Alloc) {
+  SpdySimpleArena arena(kDefaultBlockSize);
+  const size_t length = strlen(kTestString);
+  char* c1 = arena.Alloc(length);
+  char* c2 = arena.Alloc(2 * length);
+  char* c3 = arena.Alloc(3 * length);
+  char* c4 = arena.Memdup(kTestString, length);
+  EXPECT_EQ(c1 + length, c2);
+  EXPECT_EQ(c2 + 2 * length, c3);
+  EXPECT_EQ(c3 + 3 * length, c4);
+  EXPECT_EQ(absl::string_view(c4, length), kTestString);
+}
+
+TEST(SpdySimpleArenaTest, Realloc) {
+  SpdySimpleArena arena(kDefaultBlockSize);
+  const size_t length = strlen(kTestString);
+  // Simple realloc that fits in the block.
+  char* c1 = arena.Memdup(kTestString, length);
+  char* c2 = arena.Realloc(c1, length, 2 * length);
+  EXPECT_TRUE(c1);
+  EXPECT_EQ(c1, c2);
+  EXPECT_EQ(absl::string_view(c1, length), kTestString);
+  // Multiple reallocs.
+  char* c3 = arena.Memdup(kTestString, length);
+  EXPECT_EQ(c2 + 2 * length, c3);
+  EXPECT_EQ(absl::string_view(c3, length), kTestString);
+  char* c4 = arena.Realloc(c3, length, 2 * length);
+  EXPECT_EQ(c3, c4);
+  EXPECT_EQ(absl::string_view(c4, length), kTestString);
+  char* c5 = arena.Realloc(c4, 2 * length, 3 * length);
+  EXPECT_EQ(c4, c5);
+  EXPECT_EQ(absl::string_view(c5, length), kTestString);
+  char* c6 = arena.Memdup(kTestString, length);
+  EXPECT_EQ(c5 + 3 * length, c6);
+  EXPECT_EQ(absl::string_view(c6, length), kTestString);
+  // Realloc that does not fit in the remainder of the first block.
+  char* c7 = arena.Realloc(c6, length, kDefaultBlockSize);
+  EXPECT_EQ(absl::string_view(c7, length), kTestString);
+  arena.Free(c7, kDefaultBlockSize);
+  char* c8 = arena.Memdup(kTestString, length);
+  EXPECT_NE(c6, c7);
+  EXPECT_EQ(c7, c8);
+  EXPECT_EQ(absl::string_view(c8, length), kTestString);
+}
+
+}  // namespace
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_test_utils.cc b/quiche/spdy/core/spdy_test_utils.cc
new file mode 100644
index 0000000..b896d93
--- /dev/null
+++ b/quiche/spdy/core/spdy_test_utils.cc
@@ -0,0 +1,104 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/spdy/core/spdy_test_utils.h"
+
+#include <algorithm>
+#include <cstring>
+#include <memory>
+#include <new>
+#include <utility>
+#include <vector>
+
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace spdy {
+namespace test {
+
+std::string HexDumpWithMarks(const unsigned char* data,
+                             int length,
+                             const bool* marks,
+                             int mark_length) {
+  static const char kHexChars[] = "0123456789abcdef";
+  static const int kColumns = 4;
+
+  const int kSizeLimit = 1024;
+  if (length > kSizeLimit || mark_length > kSizeLimit) {
+    QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
+    length = std::min(length, kSizeLimit);
+    mark_length = std::min(mark_length, kSizeLimit);
+  }
+
+  std::string hex;
+  for (const unsigned char* row = data; length > 0;
+       row += kColumns, length -= kColumns) {
+    for (const unsigned char* p = row; p < row + 4; ++p) {
+      if (p < row + length) {
+        const bool mark =
+            (marks && (p - data) < mark_length && marks[p - data]);
+        hex += mark ? '*' : ' ';
+        hex += kHexChars[(*p & 0xf0) >> 4];
+        hex += kHexChars[*p & 0x0f];
+        hex += mark ? '*' : ' ';
+      } else {
+        hex += "    ";
+      }
+    }
+    hex = hex + "  ";
+
+    for (const unsigned char* p = row; p < row + 4 && p < row + length; ++p) {
+      hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
+    }
+
+    hex = hex + '\n';
+  }
+  return hex;
+}
+
+void CompareCharArraysWithHexError(const std::string& description,
+                                   const unsigned char* actual,
+                                   const int actual_len,
+                                   const unsigned char* expected,
+                                   const int expected_len) {
+  const int min_len = std::min(actual_len, expected_len);
+  const int max_len = std::max(actual_len, expected_len);
+  std::unique_ptr<bool[]> marks(new bool[max_len]);
+  bool identical = (actual_len == expected_len);
+  for (int i = 0; i < min_len; ++i) {
+    if (actual[i] != expected[i]) {
+      marks[i] = true;
+      identical = false;
+    } else {
+      marks[i] = false;
+    }
+  }
+  for (int i = min_len; i < max_len; ++i) {
+    marks[i] = true;
+  }
+  if (identical)
+    return;
+  ADD_FAILURE() << "Description:\n"
+                << description << "\n\nExpected:\n"
+                << HexDumpWithMarks(expected, expected_len, marks.get(),
+                                    max_len)
+                << "\nActual:\n"
+                << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
+}
+
+void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags) {
+  frame->data()[4] = flags;
+}
+
+void SetFrameLength(SpdySerializedFrame* frame, size_t length) {
+  QUICHE_CHECK_GT(1u << 14, length);
+  {
+    int32_t wire_length = quiche::QuicheEndian::HostToNet32(length);
+    memcpy(frame->data(), reinterpret_cast<char*>(&wire_length) + 1, 3);
+  }
+}
+
+}  // namespace test
+}  // namespace spdy
diff --git a/quiche/spdy/core/spdy_test_utils.h b/quiche/spdy/core/spdy_test_utils.h
new file mode 100644
index 0000000..27f42e9
--- /dev/null
+++ b/quiche/spdy/core/spdy_test_utils.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_SPDY_TEST_UTILS_H_
+#define QUICHE_SPDY_CORE_SPDY_TEST_UTILS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/spdy_protocol.h"
+
+namespace spdy {
+
+inline bool operator==(absl::string_view x,
+                       const Http2HeaderBlock::ValueProxy& y) {
+  return y.operator==(x);
+}
+
+namespace test {
+
+std::string HexDumpWithMarks(const unsigned char* data,
+                             int length,
+                             const bool* marks,
+                             int mark_length);
+
+void CompareCharArraysWithHexError(const std::string& description,
+                                   const unsigned char* actual,
+                                   const int actual_len,
+                                   const unsigned char* expected,
+                                   const int expected_len);
+
+void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags);
+
+void SetFrameLength(SpdySerializedFrame* frame, size_t length);
+
+}  // namespace test
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_SPDY_TEST_UTILS_H_
diff --git a/spdy/core/zero_copy_output_buffer.h b/quiche/spdy/core/zero_copy_output_buffer.h
similarity index 100%
rename from spdy/core/zero_copy_output_buffer.h
rename to quiche/spdy/core/zero_copy_output_buffer.h
diff --git a/spdy/core/array_output_buffer.cc b/spdy/core/array_output_buffer.cc
deleted file mode 100644
index 39e2fa0..0000000
--- a/spdy/core/array_output_buffer.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/array_output_buffer.h"
-
-namespace spdy {
-
-void ArrayOutputBuffer::Next(char** data, int* size) {
-  *data = current_;
-  *size = capacity_ > 0 ? capacity_ : 0;
-}
-
-void ArrayOutputBuffer::AdvanceWritePtr(int64_t count) {
-  current_ += count;
-  capacity_ -= count;
-}
-
-uint64_t ArrayOutputBuffer::BytesFree() const {
-  return capacity_;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/array_output_buffer.h b/spdy/core/array_output_buffer.h
deleted file mode 100644
index 80367c5..0000000
--- a/spdy/core/array_output_buffer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
-#define QUICHE_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
-
-#include <cstddef>
-#include "spdy/core/zero_copy_output_buffer.h"
-
-namespace spdy {
-
-class ArrayOutputBuffer : public ZeroCopyOutputBuffer {
- public:
-  // |buffer| is pointed to the output to write to, and |size| is the capacity
-  // of the output.
-  ArrayOutputBuffer(char* buffer, int64_t size)
-      : current_(buffer), begin_(buffer), capacity_(size) {}
-  ~ArrayOutputBuffer() override {}
-
-  ArrayOutputBuffer(const ArrayOutputBuffer&) = delete;
-  ArrayOutputBuffer& operator=(const ArrayOutputBuffer&) = delete;
-
-  void Next(char** data, int* size) override;
-  void AdvanceWritePtr(int64_t count) override;
-  uint64_t BytesFree() const override;
-
-  size_t Size() const { return current_ - begin_; }
-  char* Begin() const { return begin_; }
-
-  // Resets the buffer to its original state.
-  void Reset() {
-    capacity_ += Size();
-    current_ = begin_;
-  }
-
- private:
-  char* current_ = nullptr;
-  char* begin_ = nullptr;
-  uint64_t capacity_ = 0;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
diff --git a/spdy/core/array_output_buffer_test.cc b/spdy/core/array_output_buffer_test.cc
deleted file mode 100644
index 9d2baf8..0000000
--- a/spdy/core/array_output_buffer_test.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/array_output_buffer.h"
-
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-namespace test {
-
-// This test verifies that ArrayOutputBuffer is initialized properly.
-TEST(ArrayOutputBufferTest, InitializedFromArray) {
-  char array[100];
-  ArrayOutputBuffer buffer(array, sizeof(array));
-  EXPECT_EQ(sizeof(array), buffer.BytesFree());
-  EXPECT_EQ(0u, buffer.Size());
-  EXPECT_EQ(array, buffer.Begin());
-}
-
-// This test verifies that Reset() causes an ArrayOutputBuffer's capacity and
-// size to be reset to the initial state.
-TEST(ArrayOutputBufferTest, WriteAndReset) {
-  char array[100];
-  ArrayOutputBuffer buffer(array, sizeof(array));
-
-  // Let's write some bytes.
-  char* dst;
-  int size;
-  buffer.Next(&dst, &size);
-  ASSERT_GT(size, 1);
-  ASSERT_NE(nullptr, dst);
-  const int64_t written = size / 2;
-  memset(dst, 'x', written);
-  buffer.AdvanceWritePtr(written);
-
-  // The buffer should be partially used.
-  EXPECT_EQ(static_cast<uint64_t>(size) - written, buffer.BytesFree());
-  EXPECT_EQ(static_cast<uint64_t>(written), buffer.Size());
-
-  buffer.Reset();
-
-  // After a reset, the buffer should regain its full capacity.
-  EXPECT_EQ(sizeof(array), buffer.BytesFree());
-  EXPECT_EQ(0u, buffer.Size());
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/header_byte_listener_interface.h b/spdy/core/header_byte_listener_interface.h
deleted file mode 100644
index e2ae4f9..0000000
--- a/spdy/core/header_byte_listener_interface.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef QUICHE_SPDY_CORE_HEADER_BYTE_LISTENER_INTERFACE_H_
-#define QUICHE_SPDY_CORE_HEADER_BYTE_LISTENER_INTERFACE_H_
-
-#include <stddef.h>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace spdy {
-
-// Listens for the receipt of uncompressed header bytes.
-class QUICHE_EXPORT_PRIVATE HeaderByteListenerInterface {
- public:
-  virtual ~HeaderByteListenerInterface() {}
-
-  // Called when a header block has been parsed, with the number of uncompressed
-  // header bytes parsed from the header block.
-  virtual void OnHeaderBytesReceived(size_t uncompressed_header_bytes) = 0;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HEADER_BYTE_LISTENER_INTERFACE_H_
diff --git a/spdy/core/hpack/hpack_constants.cc b/spdy/core/hpack/hpack_constants.cc
deleted file mode 100644
index a8e48a2..0000000
--- a/spdy/core/hpack/hpack_constants.cc
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_constants.h"
-
-#include <cstddef>
-#include <memory>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/hpack/hpack_static_table.h"
-
-namespace spdy {
-
-// Produced by applying the python program [1] with tables provided by [2]
-// (inserted into the source of the python program) and copy-paste them into
-// this file.
-//
-// [1] net/tools/build_hpack_constants.py in Chromium
-// [2] http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
-
-// HpackHuffmanSymbol entries are initialized as {code, length, id}.
-// Codes are specified in the |length| most-significant bits of |code|.
-const std::vector<HpackHuffmanSymbol>& HpackHuffmanCodeVector() {
-  static const auto* kHpackHuffmanCode = new std::vector<HpackHuffmanSymbol>{
-      {0xffc00000ul, 13, 0},    //     11111111|11000
-      {0xffffb000ul, 23, 1},    //     11111111|11111111|1011000
-      {0xfffffe20ul, 28, 2},    //     11111111|11111111|11111110|0010
-      {0xfffffe30ul, 28, 3},    //     11111111|11111111|11111110|0011
-      {0xfffffe40ul, 28, 4},    //     11111111|11111111|11111110|0100
-      {0xfffffe50ul, 28, 5},    //     11111111|11111111|11111110|0101
-      {0xfffffe60ul, 28, 6},    //     11111111|11111111|11111110|0110
-      {0xfffffe70ul, 28, 7},    //     11111111|11111111|11111110|0111
-      {0xfffffe80ul, 28, 8},    //     11111111|11111111|11111110|1000
-      {0xffffea00ul, 24, 9},    //     11111111|11111111|11101010
-      {0xfffffff0ul, 30, 10},   //     11111111|11111111|11111111|111100
-      {0xfffffe90ul, 28, 11},   //     11111111|11111111|11111110|1001
-      {0xfffffea0ul, 28, 12},   //     11111111|11111111|11111110|1010
-      {0xfffffff4ul, 30, 13},   //     11111111|11111111|11111111|111101
-      {0xfffffeb0ul, 28, 14},   //     11111111|11111111|11111110|1011
-      {0xfffffec0ul, 28, 15},   //     11111111|11111111|11111110|1100
-      {0xfffffed0ul, 28, 16},   //     11111111|11111111|11111110|1101
-      {0xfffffee0ul, 28, 17},   //     11111111|11111111|11111110|1110
-      {0xfffffef0ul, 28, 18},   //     11111111|11111111|11111110|1111
-      {0xffffff00ul, 28, 19},   //     11111111|11111111|11111111|0000
-      {0xffffff10ul, 28, 20},   //     11111111|11111111|11111111|0001
-      {0xffffff20ul, 28, 21},   //     11111111|11111111|11111111|0010
-      {0xfffffff8ul, 30, 22},   //     11111111|11111111|11111111|111110
-      {0xffffff30ul, 28, 23},   //     11111111|11111111|11111111|0011
-      {0xffffff40ul, 28, 24},   //     11111111|11111111|11111111|0100
-      {0xffffff50ul, 28, 25},   //     11111111|11111111|11111111|0101
-      {0xffffff60ul, 28, 26},   //     11111111|11111111|11111111|0110
-      {0xffffff70ul, 28, 27},   //     11111111|11111111|11111111|0111
-      {0xffffff80ul, 28, 28},   //     11111111|11111111|11111111|1000
-      {0xffffff90ul, 28, 29},   //     11111111|11111111|11111111|1001
-      {0xffffffa0ul, 28, 30},   //     11111111|11111111|11111111|1010
-      {0xffffffb0ul, 28, 31},   //     11111111|11111111|11111111|1011
-      {0x50000000ul, 6, 32},    // ' ' 010100
-      {0xfe000000ul, 10, 33},   // '!' 11111110|00
-      {0xfe400000ul, 10, 34},   // '"' 11111110|01
-      {0xffa00000ul, 12, 35},   // '#' 11111111|1010
-      {0xffc80000ul, 13, 36},   // '$' 11111111|11001
-      {0x54000000ul, 6, 37},    // '%' 010101
-      {0xf8000000ul, 8, 38},    // '&' 11111000
-      {0xff400000ul, 11, 39},   // ''' 11111111|010
-      {0xfe800000ul, 10, 40},   // '(' 11111110|10
-      {0xfec00000ul, 10, 41},   // ')' 11111110|11
-      {0xf9000000ul, 8, 42},    // '*' 11111001
-      {0xff600000ul, 11, 43},   // '+' 11111111|011
-      {0xfa000000ul, 8, 44},    // ',' 11111010
-      {0x58000000ul, 6, 45},    // '-' 010110
-      {0x5c000000ul, 6, 46},    // '.' 010111
-      {0x60000000ul, 6, 47},    // '/' 011000
-      {0x00000000ul, 5, 48},    // '0' 00000
-      {0x08000000ul, 5, 49},    // '1' 00001
-      {0x10000000ul, 5, 50},    // '2' 00010
-      {0x64000000ul, 6, 51},    // '3' 011001
-      {0x68000000ul, 6, 52},    // '4' 011010
-      {0x6c000000ul, 6, 53},    // '5' 011011
-      {0x70000000ul, 6, 54},    // '6' 011100
-      {0x74000000ul, 6, 55},    // '7' 011101
-      {0x78000000ul, 6, 56},    // '8' 011110
-      {0x7c000000ul, 6, 57},    // '9' 011111
-      {0xb8000000ul, 7, 58},    // ':' 1011100
-      {0xfb000000ul, 8, 59},    // ';' 11111011
-      {0xfff80000ul, 15, 60},   // '<' 11111111|1111100
-      {0x80000000ul, 6, 61},    // '=' 100000
-      {0xffb00000ul, 12, 62},   // '>' 11111111|1011
-      {0xff000000ul, 10, 63},   // '?' 11111111|00
-      {0xffd00000ul, 13, 64},   // '@' 11111111|11010
-      {0x84000000ul, 6, 65},    // 'A' 100001
-      {0xba000000ul, 7, 66},    // 'B' 1011101
-      {0xbc000000ul, 7, 67},    // 'C' 1011110
-      {0xbe000000ul, 7, 68},    // 'D' 1011111
-      {0xc0000000ul, 7, 69},    // 'E' 1100000
-      {0xc2000000ul, 7, 70},    // 'F' 1100001
-      {0xc4000000ul, 7, 71},    // 'G' 1100010
-      {0xc6000000ul, 7, 72},    // 'H' 1100011
-      {0xc8000000ul, 7, 73},    // 'I' 1100100
-      {0xca000000ul, 7, 74},    // 'J' 1100101
-      {0xcc000000ul, 7, 75},    // 'K' 1100110
-      {0xce000000ul, 7, 76},    // 'L' 1100111
-      {0xd0000000ul, 7, 77},    // 'M' 1101000
-      {0xd2000000ul, 7, 78},    // 'N' 1101001
-      {0xd4000000ul, 7, 79},    // 'O' 1101010
-      {0xd6000000ul, 7, 80},    // 'P' 1101011
-      {0xd8000000ul, 7, 81},    // 'Q' 1101100
-      {0xda000000ul, 7, 82},    // 'R' 1101101
-      {0xdc000000ul, 7, 83},    // 'S' 1101110
-      {0xde000000ul, 7, 84},    // 'T' 1101111
-      {0xe0000000ul, 7, 85},    // 'U' 1110000
-      {0xe2000000ul, 7, 86},    // 'V' 1110001
-      {0xe4000000ul, 7, 87},    // 'W' 1110010
-      {0xfc000000ul, 8, 88},    // 'X' 11111100
-      {0xe6000000ul, 7, 89},    // 'Y' 1110011
-      {0xfd000000ul, 8, 90},    // 'Z' 11111101
-      {0xffd80000ul, 13, 91},   // '[' 11111111|11011
-      {0xfffe0000ul, 19, 92},   // '\' 11111111|11111110|000
-      {0xffe00000ul, 13, 93},   // ']' 11111111|11100
-      {0xfff00000ul, 14, 94},   // '^' 11111111|111100
-      {0x88000000ul, 6, 95},    // '_' 100010
-      {0xfffa0000ul, 15, 96},   // '`' 11111111|1111101
-      {0x18000000ul, 5, 97},    // 'a' 00011
-      {0x8c000000ul, 6, 98},    // 'b' 100011
-      {0x20000000ul, 5, 99},    // 'c' 00100
-      {0x90000000ul, 6, 100},   // 'd' 100100
-      {0x28000000ul, 5, 101},   // 'e' 00101
-      {0x94000000ul, 6, 102},   // 'f' 100101
-      {0x98000000ul, 6, 103},   // 'g' 100110
-      {0x9c000000ul, 6, 104},   // 'h' 100111
-      {0x30000000ul, 5, 105},   // 'i' 00110
-      {0xe8000000ul, 7, 106},   // 'j' 1110100
-      {0xea000000ul, 7, 107},   // 'k' 1110101
-      {0xa0000000ul, 6, 108},   // 'l' 101000
-      {0xa4000000ul, 6, 109},   // 'm' 101001
-      {0xa8000000ul, 6, 110},   // 'n' 101010
-      {0x38000000ul, 5, 111},   // 'o' 00111
-      {0xac000000ul, 6, 112},   // 'p' 101011
-      {0xec000000ul, 7, 113},   // 'q' 1110110
-      {0xb0000000ul, 6, 114},   // 'r' 101100
-      {0x40000000ul, 5, 115},   // 's' 01000
-      {0x48000000ul, 5, 116},   // 't' 01001
-      {0xb4000000ul, 6, 117},   // 'u' 101101
-      {0xee000000ul, 7, 118},   // 'v' 1110111
-      {0xf0000000ul, 7, 119},   // 'w' 1111000
-      {0xf2000000ul, 7, 120},   // 'x' 1111001
-      {0xf4000000ul, 7, 121},   // 'y' 1111010
-      {0xf6000000ul, 7, 122},   // 'z' 1111011
-      {0xfffc0000ul, 15, 123},  // '{' 11111111|1111110
-      {0xff800000ul, 11, 124},  // '|' 11111111|100
-      {0xfff40000ul, 14, 125},  // '}' 11111111|111101
-      {0xffe80000ul, 13, 126},  // '~' 11111111|11101
-      {0xffffffc0ul, 28, 127},  //     11111111|11111111|11111111|1100
-      {0xfffe6000ul, 20, 128},  //     11111111|11111110|0110
-      {0xffff4800ul, 22, 129},  //     11111111|11111111|010010
-      {0xfffe7000ul, 20, 130},  //     11111111|11111110|0111
-      {0xfffe8000ul, 20, 131},  //     11111111|11111110|1000
-      {0xffff4c00ul, 22, 132},  //     11111111|11111111|010011
-      {0xffff5000ul, 22, 133},  //     11111111|11111111|010100
-      {0xffff5400ul, 22, 134},  //     11111111|11111111|010101
-      {0xffffb200ul, 23, 135},  //     11111111|11111111|1011001
-      {0xffff5800ul, 22, 136},  //     11111111|11111111|010110
-      {0xffffb400ul, 23, 137},  //     11111111|11111111|1011010
-      {0xffffb600ul, 23, 138},  //     11111111|11111111|1011011
-      {0xffffb800ul, 23, 139},  //     11111111|11111111|1011100
-      {0xffffba00ul, 23, 140},  //     11111111|11111111|1011101
-      {0xffffbc00ul, 23, 141},  //     11111111|11111111|1011110
-      {0xffffeb00ul, 24, 142},  //     11111111|11111111|11101011
-      {0xffffbe00ul, 23, 143},  //     11111111|11111111|1011111
-      {0xffffec00ul, 24, 144},  //     11111111|11111111|11101100
-      {0xffffed00ul, 24, 145},  //     11111111|11111111|11101101
-      {0xffff5c00ul, 22, 146},  //     11111111|11111111|010111
-      {0xffffc000ul, 23, 147},  //     11111111|11111111|1100000
-      {0xffffee00ul, 24, 148},  //     11111111|11111111|11101110
-      {0xffffc200ul, 23, 149},  //     11111111|11111111|1100001
-      {0xffffc400ul, 23, 150},  //     11111111|11111111|1100010
-      {0xffffc600ul, 23, 151},  //     11111111|11111111|1100011
-      {0xffffc800ul, 23, 152},  //     11111111|11111111|1100100
-      {0xfffee000ul, 21, 153},  //     11111111|11111110|11100
-      {0xffff6000ul, 22, 154},  //     11111111|11111111|011000
-      {0xffffca00ul, 23, 155},  //     11111111|11111111|1100101
-      {0xffff6400ul, 22, 156},  //     11111111|11111111|011001
-      {0xffffcc00ul, 23, 157},  //     11111111|11111111|1100110
-      {0xffffce00ul, 23, 158},  //     11111111|11111111|1100111
-      {0xffffef00ul, 24, 159},  //     11111111|11111111|11101111
-      {0xffff6800ul, 22, 160},  //     11111111|11111111|011010
-      {0xfffee800ul, 21, 161},  //     11111111|11111110|11101
-      {0xfffe9000ul, 20, 162},  //     11111111|11111110|1001
-      {0xffff6c00ul, 22, 163},  //     11111111|11111111|011011
-      {0xffff7000ul, 22, 164},  //     11111111|11111111|011100
-      {0xffffd000ul, 23, 165},  //     11111111|11111111|1101000
-      {0xffffd200ul, 23, 166},  //     11111111|11111111|1101001
-      {0xfffef000ul, 21, 167},  //     11111111|11111110|11110
-      {0xffffd400ul, 23, 168},  //     11111111|11111111|1101010
-      {0xffff7400ul, 22, 169},  //     11111111|11111111|011101
-      {0xffff7800ul, 22, 170},  //     11111111|11111111|011110
-      {0xfffff000ul, 24, 171},  //     11111111|11111111|11110000
-      {0xfffef800ul, 21, 172},  //     11111111|11111110|11111
-      {0xffff7c00ul, 22, 173},  //     11111111|11111111|011111
-      {0xffffd600ul, 23, 174},  //     11111111|11111111|1101011
-      {0xffffd800ul, 23, 175},  //     11111111|11111111|1101100
-      {0xffff0000ul, 21, 176},  //     11111111|11111111|00000
-      {0xffff0800ul, 21, 177},  //     11111111|11111111|00001
-      {0xffff8000ul, 22, 178},  //     11111111|11111111|100000
-      {0xffff1000ul, 21, 179},  //     11111111|11111111|00010
-      {0xffffda00ul, 23, 180},  //     11111111|11111111|1101101
-      {0xffff8400ul, 22, 181},  //     11111111|11111111|100001
-      {0xffffdc00ul, 23, 182},  //     11111111|11111111|1101110
-      {0xffffde00ul, 23, 183},  //     11111111|11111111|1101111
-      {0xfffea000ul, 20, 184},  //     11111111|11111110|1010
-      {0xffff8800ul, 22, 185},  //     11111111|11111111|100010
-      {0xffff8c00ul, 22, 186},  //     11111111|11111111|100011
-      {0xffff9000ul, 22, 187},  //     11111111|11111111|100100
-      {0xffffe000ul, 23, 188},  //     11111111|11111111|1110000
-      {0xffff9400ul, 22, 189},  //     11111111|11111111|100101
-      {0xffff9800ul, 22, 190},  //     11111111|11111111|100110
-      {0xffffe200ul, 23, 191},  //     11111111|11111111|1110001
-      {0xfffff800ul, 26, 192},  //     11111111|11111111|11111000|00
-      {0xfffff840ul, 26, 193},  //     11111111|11111111|11111000|01
-      {0xfffeb000ul, 20, 194},  //     11111111|11111110|1011
-      {0xfffe2000ul, 19, 195},  //     11111111|11111110|001
-      {0xffff9c00ul, 22, 196},  //     11111111|11111111|100111
-      {0xffffe400ul, 23, 197},  //     11111111|11111111|1110010
-      {0xffffa000ul, 22, 198},  //     11111111|11111111|101000
-      {0xfffff600ul, 25, 199},  //     11111111|11111111|11110110|0
-      {0xfffff880ul, 26, 200},  //     11111111|11111111|11111000|10
-      {0xfffff8c0ul, 26, 201},  //     11111111|11111111|11111000|11
-      {0xfffff900ul, 26, 202},  //     11111111|11111111|11111001|00
-      {0xfffffbc0ul, 27, 203},  //     11111111|11111111|11111011|110
-      {0xfffffbe0ul, 27, 204},  //     11111111|11111111|11111011|111
-      {0xfffff940ul, 26, 205},  //     11111111|11111111|11111001|01
-      {0xfffff100ul, 24, 206},  //     11111111|11111111|11110001
-      {0xfffff680ul, 25, 207},  //     11111111|11111111|11110110|1
-      {0xfffe4000ul, 19, 208},  //     11111111|11111110|010
-      {0xffff1800ul, 21, 209},  //     11111111|11111111|00011
-      {0xfffff980ul, 26, 210},  //     11111111|11111111|11111001|10
-      {0xfffffc00ul, 27, 211},  //     11111111|11111111|11111100|000
-      {0xfffffc20ul, 27, 212},  //     11111111|11111111|11111100|001
-      {0xfffff9c0ul, 26, 213},  //     11111111|11111111|11111001|11
-      {0xfffffc40ul, 27, 214},  //     11111111|11111111|11111100|010
-      {0xfffff200ul, 24, 215},  //     11111111|11111111|11110010
-      {0xffff2000ul, 21, 216},  //     11111111|11111111|00100
-      {0xffff2800ul, 21, 217},  //     11111111|11111111|00101
-      {0xfffffa00ul, 26, 218},  //     11111111|11111111|11111010|00
-      {0xfffffa40ul, 26, 219},  //     11111111|11111111|11111010|01
-      {0xffffffd0ul, 28, 220},  //     11111111|11111111|11111111|1101
-      {0xfffffc60ul, 27, 221},  //     11111111|11111111|11111100|011
-      {0xfffffc80ul, 27, 222},  //     11111111|11111111|11111100|100
-      {0xfffffca0ul, 27, 223},  //     11111111|11111111|11111100|101
-      {0xfffec000ul, 20, 224},  //     11111111|11111110|1100
-      {0xfffff300ul, 24, 225},  //     11111111|11111111|11110011
-      {0xfffed000ul, 20, 226},  //     11111111|11111110|1101
-      {0xffff3000ul, 21, 227},  //     11111111|11111111|00110
-      {0xffffa400ul, 22, 228},  //     11111111|11111111|101001
-      {0xffff3800ul, 21, 229},  //     11111111|11111111|00111
-      {0xffff4000ul, 21, 230},  //     11111111|11111111|01000
-      {0xffffe600ul, 23, 231},  //     11111111|11111111|1110011
-      {0xffffa800ul, 22, 232},  //     11111111|11111111|101010
-      {0xffffac00ul, 22, 233},  //     11111111|11111111|101011
-      {0xfffff700ul, 25, 234},  //     11111111|11111111|11110111|0
-      {0xfffff780ul, 25, 235},  //     11111111|11111111|11110111|1
-      {0xfffff400ul, 24, 236},  //     11111111|11111111|11110100
-      {0xfffff500ul, 24, 237},  //     11111111|11111111|11110101
-      {0xfffffa80ul, 26, 238},  //     11111111|11111111|11111010|10
-      {0xffffe800ul, 23, 239},  //     11111111|11111111|1110100
-      {0xfffffac0ul, 26, 240},  //     11111111|11111111|11111010|11
-      {0xfffffcc0ul, 27, 241},  //     11111111|11111111|11111100|110
-      {0xfffffb00ul, 26, 242},  //     11111111|11111111|11111011|00
-      {0xfffffb40ul, 26, 243},  //     11111111|11111111|11111011|01
-      {0xfffffce0ul, 27, 244},  //     11111111|11111111|11111100|111
-      {0xfffffd00ul, 27, 245},  //     11111111|11111111|11111101|000
-      {0xfffffd20ul, 27, 246},  //     11111111|11111111|11111101|001
-      {0xfffffd40ul, 27, 247},  //     11111111|11111111|11111101|010
-      {0xfffffd60ul, 27, 248},  //     11111111|11111111|11111101|011
-      {0xffffffe0ul, 28, 249},  //     11111111|11111111|11111111|1110
-      {0xfffffd80ul, 27, 250},  //     11111111|11111111|11111101|100
-      {0xfffffda0ul, 27, 251},  //     11111111|11111111|11111101|101
-      {0xfffffdc0ul, 27, 252},  //     11111111|11111111|11111101|110
-      {0xfffffde0ul, 27, 253},  //     11111111|11111111|11111101|111
-      {0xfffffe00ul, 27, 254},  //     11111111|11111111|11111110|000
-      {0xfffffb80ul, 26, 255},  //     11111111|11111111|11111011|10
-      {0xfffffffcul, 30, 256},  // EOS 11111111|11111111|11111111|111111
-  };
-  return *kHpackHuffmanCode;
-}
-
-// The "constructor" for a HpackStaticEntry that computes the lengths at
-// compile time.
-#define STATIC_ENTRY(name, value) \
-  { name, ABSL_ARRAYSIZE(name) - 1, value, ABSL_ARRAYSIZE(value) - 1 }
-
-const std::vector<HpackStaticEntry>& HpackStaticTableVector() {
-  static const auto* kHpackStaticTable = new std::vector<HpackStaticEntry>{
-      STATIC_ENTRY(":authority", ""),                    // 1
-      STATIC_ENTRY(":method", "GET"),                    // 2
-      STATIC_ENTRY(":method", "POST"),                   // 3
-      STATIC_ENTRY(":path", "/"),                        // 4
-      STATIC_ENTRY(":path", "/index.html"),              // 5
-      STATIC_ENTRY(":scheme", "http"),                   // 6
-      STATIC_ENTRY(":scheme", "https"),                  // 7
-      STATIC_ENTRY(":status", "200"),                    // 8
-      STATIC_ENTRY(":status", "204"),                    // 9
-      STATIC_ENTRY(":status", "206"),                    // 10
-      STATIC_ENTRY(":status", "304"),                    // 11
-      STATIC_ENTRY(":status", "400"),                    // 12
-      STATIC_ENTRY(":status", "404"),                    // 13
-      STATIC_ENTRY(":status", "500"),                    // 14
-      STATIC_ENTRY("accept-charset", ""),                // 15
-      STATIC_ENTRY("accept-encoding", "gzip, deflate"),  // 16
-      STATIC_ENTRY("accept-language", ""),               // 17
-      STATIC_ENTRY("accept-ranges", ""),                 // 18
-      STATIC_ENTRY("accept", ""),                        // 19
-      STATIC_ENTRY("access-control-allow-origin", ""),   // 20
-      STATIC_ENTRY("age", ""),                           // 21
-      STATIC_ENTRY("allow", ""),                         // 22
-      STATIC_ENTRY("authorization", ""),                 // 23
-      STATIC_ENTRY("cache-control", ""),                 // 24
-      STATIC_ENTRY("content-disposition", ""),           // 25
-      STATIC_ENTRY("content-encoding", ""),              // 26
-      STATIC_ENTRY("content-language", ""),              // 27
-      STATIC_ENTRY("content-length", ""),                // 28
-      STATIC_ENTRY("content-location", ""),              // 29
-      STATIC_ENTRY("content-range", ""),                 // 30
-      STATIC_ENTRY("content-type", ""),                  // 31
-      STATIC_ENTRY("cookie", ""),                        // 32
-      STATIC_ENTRY("date", ""),                          // 33
-      STATIC_ENTRY("etag", ""),                          // 34
-      STATIC_ENTRY("expect", ""),                        // 35
-      STATIC_ENTRY("expires", ""),                       // 36
-      STATIC_ENTRY("from", ""),                          // 37
-      STATIC_ENTRY("host", ""),                          // 38
-      STATIC_ENTRY("if-match", ""),                      // 39
-      STATIC_ENTRY("if-modified-since", ""),             // 40
-      STATIC_ENTRY("if-none-match", ""),                 // 41
-      STATIC_ENTRY("if-range", ""),                      // 42
-      STATIC_ENTRY("if-unmodified-since", ""),           // 43
-      STATIC_ENTRY("last-modified", ""),                 // 44
-      STATIC_ENTRY("link", ""),                          // 45
-      STATIC_ENTRY("location", ""),                      // 46
-      STATIC_ENTRY("max-forwards", ""),                  // 47
-      STATIC_ENTRY("proxy-authenticate", ""),            // 48
-      STATIC_ENTRY("proxy-authorization", ""),           // 49
-      STATIC_ENTRY("range", ""),                         // 50
-      STATIC_ENTRY("referer", ""),                       // 51
-      STATIC_ENTRY("refresh", ""),                       // 52
-      STATIC_ENTRY("retry-after", ""),                   // 53
-      STATIC_ENTRY("server", ""),                        // 54
-      STATIC_ENTRY("set-cookie", ""),                    // 55
-      STATIC_ENTRY("strict-transport-security", ""),     // 56
-      STATIC_ENTRY("transfer-encoding", ""),             // 57
-      STATIC_ENTRY("user-agent", ""),                    // 58
-      STATIC_ENTRY("vary", ""),                          // 59
-      STATIC_ENTRY("via", ""),                           // 60
-      STATIC_ENTRY("www-authenticate", ""),              // 61
-  };
-  return *kHpackStaticTable;
-}
-
-#undef STATIC_ENTRY
-
-const HpackStaticTable& ObtainHpackStaticTable() {
-  static const HpackStaticTable* const shared_static_table = []() {
-    auto* table = new HpackStaticTable();
-    table->Initialize(HpackStaticTableVector().data(),
-                      HpackStaticTableVector().size());
-    QUICHE_CHECK(table->IsInitialized());
-    return table;
-  }();
-  return *shared_static_table;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_constants.h b/spdy/core/hpack/hpack_constants.h
deleted file mode 100644
index b0ffef1..0000000
--- a/spdy/core/hpack/hpack_constants.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <vector>
-
-#include "common/platform/api/quiche_export.h"
-
-// All section references below are to
-// https://httpwg.org/specs/rfc7540.html and
-// https://httpwg.org/specs/rfc7541.html.
-
-namespace spdy {
-
-// An HpackPrefix signifies |bits| stored in the top |bit_size| bits
-// of an octet.
-struct HpackPrefix {
-  uint8_t bits;
-  size_t bit_size;
-};
-
-// Represents a symbol and its Huffman code (stored in most-significant bits).
-struct HpackHuffmanSymbol {
-  uint32_t code;
-  uint8_t length;
-  uint16_t id;
-};
-
-// An entry in the static table. Must be a POD in order to avoid static
-// initializers, i.e. no user-defined constructors or destructors.
-struct HpackStaticEntry {
-  const char* const name;
-  const size_t name_len;
-  const char* const value;
-  const size_t value_len;
-};
-
-class HpackStaticTable;
-
-// RFC 7540, 6.5.2: Initial value for SETTINGS_HEADER_TABLE_SIZE.
-const uint32_t kDefaultHeaderTableSizeSetting = 4096;
-
-// RFC 7541, 5.2: Flag for a string literal that is stored unmodified (i.e.,
-// without Huffman encoding).
-const HpackPrefix kStringLiteralIdentityEncoded = {0x0, 1};
-
-// RFC 7541, 5.2: Flag for a Huffman-coded string literal.
-const HpackPrefix kStringLiteralHuffmanEncoded = {0x1, 1};
-
-// RFC 7541, 6.1: Opcode for an indexed header field.
-const HpackPrefix kIndexedOpcode = {0b1, 1};
-
-// RFC 7541, 6.2.1: Opcode for a literal header field with incremental indexing.
-const HpackPrefix kLiteralIncrementalIndexOpcode = {0b01, 2};
-
-// RFC 7541, 6.2.2: Opcode for a literal header field without indexing.
-const HpackPrefix kLiteralNoIndexOpcode = {0b0000, 4};
-
-// RFC 7541, 6.2.3: Opcode for a literal header field which is never indexed.
-// Currently unused.
-// const HpackPrefix kLiteralNeverIndexOpcode = {0b0001, 4};
-
-// RFC 7541, 6.3: Opcode for maximum header table size update. Begins a
-// varint-encoded table size with a 5-bit prefix.
-const HpackPrefix kHeaderTableSizeUpdateOpcode = {0b001, 3};
-
-// RFC 7541, Appendix B: Huffman Code.
-QUICHE_EXPORT_PRIVATE const std::vector<HpackHuffmanSymbol>&
-HpackHuffmanCodeVector();
-
-// RFC 7541, Appendix A: Static Table Definition.
-QUICHE_EXPORT_PRIVATE const std::vector<HpackStaticEntry>&
-HpackStaticTableVector();
-
-// Returns a HpackStaticTable instance initialized with |kHpackStaticTable|.
-// The instance is read-only, has static lifetime, and is safe to share amoung
-// threads. This function is thread-safe.
-QUICHE_EXPORT_PRIVATE const HpackStaticTable& ObtainHpackStaticTable();
-
-// RFC 7541, 8.1.2.1: Pseudo-headers start with a colon.
-const char kPseudoHeaderPrefix = ':';
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
diff --git a/spdy/core/hpack/hpack_decoder_adapter.cc b/spdy/core/hpack/hpack_decoder_adapter.cc
deleted file mode 100644
index 3e7c21a..0000000
--- a/spdy/core/hpack/hpack_decoder_adapter.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_decoder_adapter.h"
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-namespace {
-const size_t kMaxDecodeBufferSizeBytes = 32 * 1024;  // 32 KB
-}  // namespace
-
-HpackDecoderAdapter::HpackDecoderAdapter()
-    : hpack_decoder_(&listener_adapter_, kMaxDecodeBufferSizeBytes),
-      max_decode_buffer_size_bytes_(kMaxDecodeBufferSizeBytes),
-      max_header_block_bytes_(0),
-      header_block_started_(false),
-      error_(http2::HpackDecodingError::kOk) {}
-
-HpackDecoderAdapter::~HpackDecoderAdapter() = default;
-
-void HpackDecoderAdapter::ApplyHeaderTableSizeSetting(size_t size_setting) {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ApplyHeaderTableSizeSetting";
-  hpack_decoder_.ApplyHeaderTableSizeSetting(size_setting);
-}
-
-size_t HpackDecoderAdapter::GetCurrentHeaderTableSizeSetting() const {
-  return hpack_decoder_.GetCurrentHeaderTableSizeSetting();
-}
-
-void HpackDecoderAdapter::HandleControlFrameHeadersStart(
-    SpdyHeadersHandlerInterface* handler) {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::HandleControlFrameHeadersStart";
-  QUICHE_DCHECK(!header_block_started_);
-  listener_adapter_.set_handler(handler);
-}
-
-bool HpackDecoderAdapter::HandleControlFrameHeadersData(
-    const char* headers_data,
-    size_t headers_data_length) {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::HandleControlFrameHeadersData: len="
-                  << headers_data_length;
-  if (!header_block_started_) {
-    // Initialize the decoding process here rather than in
-    // HandleControlFrameHeadersStart because that method is not always called.
-    header_block_started_ = true;
-    if (!hpack_decoder_.StartDecodingBlock()) {
-      header_block_started_ = false;
-      error_ = hpack_decoder_.error();
-      detailed_error_ = hpack_decoder_.detailed_error();
-      return false;
-    }
-  }
-
-  // Sometimes we get a call with headers_data==nullptr and
-  // headers_data_length==0, in which case we need to avoid creating
-  // a DecodeBuffer, which would otherwise complain.
-  if (headers_data_length > 0) {
-    QUICHE_DCHECK_NE(headers_data, nullptr);
-    if (headers_data_length > max_decode_buffer_size_bytes_) {
-      QUICHE_DVLOG(1) << "max_decode_buffer_size_bytes_ < headers_data_length: "
-                      << max_decode_buffer_size_bytes_ << " < "
-                      << headers_data_length;
-      error_ = http2::HpackDecodingError::kFragmentTooLong;
-      detailed_error_ = "";
-      return false;
-    }
-    listener_adapter_.AddToTotalHpackBytes(headers_data_length);
-    if (max_header_block_bytes_ != 0 &&
-        listener_adapter_.total_hpack_bytes() > max_header_block_bytes_) {
-      error_ = http2::HpackDecodingError::kCompressedHeaderSizeExceedsLimit;
-      detailed_error_ = "";
-      return false;
-    }
-    http2::DecodeBuffer db(headers_data, headers_data_length);
-    bool ok = hpack_decoder_.DecodeFragment(&db);
-    QUICHE_DCHECK(!ok || db.Empty()) << "Remaining=" << db.Remaining();
-    if (!ok) {
-      error_ = hpack_decoder_.error();
-      detailed_error_ = hpack_decoder_.detailed_error();
-    }
-    return ok;
-  }
-  return true;
-}
-
-bool HpackDecoderAdapter::HandleControlFrameHeadersComplete() {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::HandleControlFrameHeadersComplete";
-  if (!hpack_decoder_.EndDecodingBlock()) {
-    QUICHE_DVLOG(3) << "EndDecodingBlock returned false";
-    error_ = hpack_decoder_.error();
-    detailed_error_ = hpack_decoder_.detailed_error();
-    return false;
-  }
-  header_block_started_ = false;
-  return true;
-}
-
-const SpdyHeaderBlock& HpackDecoderAdapter::decoded_block() const {
-  return listener_adapter_.decoded_block();
-}
-
-void HpackDecoderAdapter::set_max_decode_buffer_size_bytes(
-    size_t max_decode_buffer_size_bytes) {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::set_max_decode_buffer_size_bytes";
-  max_decode_buffer_size_bytes_ = max_decode_buffer_size_bytes;
-  hpack_decoder_.set_max_string_size_bytes(max_decode_buffer_size_bytes);
-}
-
-void HpackDecoderAdapter::set_max_header_block_bytes(
-    size_t max_header_block_bytes) {
-  max_header_block_bytes_ = max_header_block_bytes;
-}
-
-HpackDecoderAdapter::ListenerAdapter::ListenerAdapter() : handler_(nullptr) {}
-HpackDecoderAdapter::ListenerAdapter::~ListenerAdapter() = default;
-
-void HpackDecoderAdapter::ListenerAdapter::set_handler(
-    SpdyHeadersHandlerInterface* handler) {
-  handler_ = handler;
-}
-
-void HpackDecoderAdapter::ListenerAdapter::OnHeaderListStart() {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ListenerAdapter::OnHeaderListStart";
-  total_hpack_bytes_ = 0;
-  total_uncompressed_bytes_ = 0;
-  decoded_block_.clear();
-  if (handler_ != nullptr) {
-    handler_->OnHeaderBlockStart();
-  }
-}
-
-void HpackDecoderAdapter::ListenerAdapter::OnHeader(const std::string& name,
-                                                    const std::string& value) {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ListenerAdapter::OnHeader:\n name: "
-                  << name << "\n value: " << value;
-  total_uncompressed_bytes_ += name.size() + value.size();
-  if (handler_ == nullptr) {
-    QUICHE_DVLOG(3) << "Adding to decoded_block";
-    decoded_block_.AppendValueOrAddHeader(name, value);
-  } else {
-    QUICHE_DVLOG(3) << "Passing to handler";
-    handler_->OnHeader(name, value);
-  }
-}
-
-void HpackDecoderAdapter::ListenerAdapter::OnHeaderListEnd() {
-  QUICHE_DVLOG(2) << "HpackDecoderAdapter::ListenerAdapter::OnHeaderListEnd";
-  // We don't clear the SpdyHeaderBlock here to allow access to it until the
-  // next HPACK block is decoded.
-  if (handler_ != nullptr) {
-    handler_->OnHeaderBlockEnd(total_uncompressed_bytes_, total_hpack_bytes_);
-    handler_ = nullptr;
-  }
-}
-
-void HpackDecoderAdapter::ListenerAdapter::OnHeaderErrorDetected(
-    absl::string_view error_message) {
-  QUICHE_VLOG(1) << error_message;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_decoder_adapter.h b/spdy/core/hpack/hpack_decoder_adapter.h
deleted file mode 100644
index c4bc991..0000000
--- a/spdy/core/hpack/hpack_decoder_adapter.h
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_DECODER_ADAPTER_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_DECODER_ADAPTER_H_
-
-// HpackDecoderAdapter uses http2::HpackDecoder to decode HPACK blocks into
-// HTTP/2 header lists as outlined in http://tools.ietf.org/html/rfc7541.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_decoder.h"
-#include "http2/hpack/decoder/hpack_decoder_listener.h"
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-#include "http2/hpack/http2_hpack_constants.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-
-namespace spdy {
-namespace test {
-class HpackDecoderAdapterPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE HpackDecoderAdapter {
- public:
-  friend test::HpackDecoderAdapterPeer;
-  HpackDecoderAdapter();
-  HpackDecoderAdapter(const HpackDecoderAdapter&) = delete;
-  HpackDecoderAdapter& operator=(const HpackDecoderAdapter&) = delete;
-  ~HpackDecoderAdapter();
-
-  // Called upon acknowledgement of SETTINGS_HEADER_TABLE_SIZE.
-  void ApplyHeaderTableSizeSetting(size_t size_setting);
-
-  // Returns the most recently applied value of SETTINGS_HEADER_TABLE_SIZE.
-  size_t GetCurrentHeaderTableSizeSetting() const;
-
-  // If a SpdyHeadersHandlerInterface is provided, the decoder will emit
-  // headers to it rather than accumulating them in a SpdyHeaderBlock.
-  // Does not take ownership of the handler, but does use the pointer until
-  // the current HPACK block is completely decoded.
-  void HandleControlFrameHeadersStart(SpdyHeadersHandlerInterface* handler);
-
-  // Called as HPACK block fragments arrive. Returns false if an error occurred
-  // while decoding the block. Does not take ownership of headers_data.
-  bool HandleControlFrameHeadersData(const char* headers_data,
-                                     size_t headers_data_length);
-
-  // Called after a HPACK block has been completely delivered via
-  // HandleControlFrameHeadersData(). Returns false if an error occurred.
-  // |compressed_len| if non-null will be set to the size of the encoded
-  // buffered block that was accumulated in HandleControlFrameHeadersData(),
-  // to support subsequent calculation of compression percentage.
-  // Discards the handler supplied at the start of decoding the block.
-  bool HandleControlFrameHeadersComplete();
-
-  // Accessor for the most recently decoded headers block. Valid until the next
-  // call to HandleControlFrameHeadersData().
-  // TODO(birenroy): Remove this method when all users of HpackDecoder specify
-  // a SpdyHeadersHandlerInterface.
-  const SpdyHeaderBlock& decoded_block() const;
-
-  // Returns the current dynamic table size, including the 32 bytes per entry
-  // overhead mentioned in RFC 7541 section 4.1.
-  size_t GetDynamicTableSize() const {
-    return hpack_decoder_.GetDynamicTableSize();
-  }
-
-  // Set how much encoded data this decoder is willing to buffer.
-  // TODO(jamessynge): Resolve definition of this value, as it is currently
-  // too tied to a single implementation. We probably want to limit one or more
-  // of these: individual name or value strings, header entries, the entire
-  // header list, or the HPACK block; we probably shouldn't care about the size
-  // of individual transport buffers.
-  void set_max_decode_buffer_size_bytes(size_t max_decode_buffer_size_bytes);
-
-  // Specifies the maximum size of an on-the-wire header block that will be
-  // accepted.
-  void set_max_header_block_bytes(size_t max_header_block_bytes);
-
-  // Error code if an error has occurred, Error::kOk otherwise.
-  http2::HpackDecodingError error() const { return error_; }
-
-  std::string detailed_error() const { return detailed_error_; }
-
- private:
-  class QUICHE_EXPORT_PRIVATE ListenerAdapter
-      : public http2::HpackDecoderListener {
-   public:
-    ListenerAdapter();
-    ~ListenerAdapter() override;
-
-    // If a SpdyHeadersHandlerInterface is provided, the decoder will emit
-    // headers to it rather than accumulating them in a SpdyHeaderBlock.
-    // Does not take ownership of the handler, but does use the pointer until
-    // the current HPACK block is completely decoded.
-    void set_handler(SpdyHeadersHandlerInterface* handler);
-    const SpdyHeaderBlock& decoded_block() const { return decoded_block_; }
-
-    // Override the HpackDecoderListener methods:
-    void OnHeaderListStart() override;
-    void OnHeader(const std::string& name, const std::string& value) override;
-    void OnHeaderListEnd() override;
-    void OnHeaderErrorDetected(absl::string_view error_message) override;
-
-    void AddToTotalHpackBytes(size_t delta) { total_hpack_bytes_ += delta; }
-    size_t total_hpack_bytes() const { return total_hpack_bytes_; }
-
-   private:
-    // If the caller doesn't provide a handler, the header list is stored in
-    // this SpdyHeaderBlock.
-    SpdyHeaderBlock decoded_block_;
-
-    // If non-NULL, handles decoded headers. Not owned.
-    SpdyHeadersHandlerInterface* handler_;
-
-    // Total bytes that have been received as input (i.e. HPACK encoded)
-    // in the current HPACK block.
-    size_t total_hpack_bytes_;
-
-    // Total bytes of the name and value strings in the current HPACK block.
-    size_t total_uncompressed_bytes_;
-  };
-
-  // Converts calls to HpackDecoderListener into calls to
-  // SpdyHeadersHandlerInterface.
-  ListenerAdapter listener_adapter_;
-
-  // The actual decoder.
-  http2::HpackDecoder hpack_decoder_;
-
-  // How much encoded data this decoder is willing to buffer.
-  size_t max_decode_buffer_size_bytes_;
-
-  // How much encoded data this decoder is willing to process.
-  size_t max_header_block_bytes_;
-
-  // Flag to keep track of having seen the header block start. Needed at the
-  // moment because HandleControlFrameHeadersStart won't be called if a handler
-  // is not being provided by the caller.
-  bool header_block_started_;
-
-  // Error code if an error has occurred, Error::kOk otherwise.
-  http2::HpackDecodingError error_;
-  std::string detailed_error_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_DECODER_ADAPTER_H_
diff --git a/spdy/core/hpack/hpack_decoder_adapter_test.cc b/spdy/core/hpack/hpack_decoder_adapter_test.cc
deleted file mode 100644
index f1f64e6..0000000
--- a/spdy/core/hpack/hpack_decoder_adapter_test.cc
+++ /dev/null
@@ -1,1123 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_decoder_adapter.h"
-
-// Tests of HpackDecoderAdapter.
-
-#include <stdint.h>
-
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/strings/escaping.h"
-#include "http2/hpack/decoder/hpack_decoder_state.h"
-#include "http2/hpack/decoder/hpack_decoder_tables.h"
-#include "http2/hpack/tools/hpack_block_builder.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-#include "spdy/core/hpack/hpack_output_stream.h"
-#include "spdy/core/recording_headers_handler.h"
-#include "spdy/core/spdy_test_utils.h"
-
-using ::http2::HpackEntryType;
-using ::http2::HpackStringPair;
-using ::http2::test::HpackBlockBuilder;
-using ::http2::test::HpackDecoderPeer;
-using ::testing::ElementsAre;
-using ::testing::Pair;
-
-namespace http2 {
-namespace test {
-
-class HpackDecoderStatePeer {
- public:
-  static HpackDecoderTables* GetDecoderTables(HpackDecoderState* state) {
-    return &state->decoder_tables_;
-  }
-};
-
-class HpackDecoderPeer {
- public:
-  static HpackDecoderState* GetDecoderState(HpackDecoder* decoder) {
-    return &decoder->decoder_state_;
-  }
-  static HpackDecoderTables* GetDecoderTables(HpackDecoder* decoder) {
-    return HpackDecoderStatePeer::GetDecoderTables(GetDecoderState(decoder));
-  }
-};
-
-}  // namespace test
-}  // namespace http2
-
-namespace spdy {
-namespace test {
-
-class HpackDecoderAdapterPeer {
- public:
-  explicit HpackDecoderAdapterPeer(HpackDecoderAdapter* decoder)
-      : decoder_(decoder) {}
-
-  void HandleHeaderRepresentation(const std::string& name,
-                                  const std::string& value) {
-    decoder_->listener_adapter_.OnHeader(name, value);
-  }
-
-  http2::HpackDecoderTables* GetDecoderTables() {
-    return HpackDecoderPeer::GetDecoderTables(&decoder_->hpack_decoder_);
-  }
-
-  const HpackStringPair* GetTableEntry(uint32_t index) {
-    return GetDecoderTables()->Lookup(index);
-  }
-
-  size_t current_header_table_size() {
-    return GetDecoderTables()->current_header_table_size();
-  }
-
-  size_t header_table_size_limit() {
-    return GetDecoderTables()->header_table_size_limit();
-  }
-
-  void set_header_table_size_limit(size_t size) {
-    return GetDecoderTables()->DynamicTableSizeUpdate(size);
-  }
-
- private:
-  HpackDecoderAdapter* decoder_;
-};
-
-class HpackEncoderPeer {
- public:
-  static void CookieToCrumbs(const HpackEncoder::Representation& cookie,
-                             HpackEncoder::Representations* crumbs_out) {
-    HpackEncoder::CookieToCrumbs(cookie, crumbs_out);
-  }
-};
-
-namespace {
-
-const bool kNoCheckDecodedSize = false;
-const char* kCookieKey = "cookie";
-
-// Is HandleControlFrameHeadersStart to be called, and with what value?
-enum StartChoice { START_WITH_HANDLER, START_WITHOUT_HANDLER, NO_START };
-
-class HpackDecoderAdapterTest
-    : public QuicheTestWithParam<std::tuple<StartChoice, bool>> {
- protected:
-  HpackDecoderAdapterTest() : decoder_(), decoder_peer_(&decoder_) {}
-
-  void SetUp() override {
-    std::tie(start_choice_, randomly_split_input_buffer_) = GetParam();
-  }
-
-  void HandleControlFrameHeadersStart() {
-    bytes_passed_in_ = 0;
-    switch (start_choice_) {
-      case START_WITH_HANDLER:
-        decoder_.HandleControlFrameHeadersStart(&handler_);
-        break;
-      case START_WITHOUT_HANDLER:
-        decoder_.HandleControlFrameHeadersStart(nullptr);
-        break;
-      case NO_START:
-        break;
-    }
-  }
-
-  bool HandleControlFrameHeadersData(absl::string_view str) {
-    QUICHE_VLOG(3) << "HandleControlFrameHeadersData:\n"
-                   << quiche::QuicheTextUtils::HexDump(str);
-    bytes_passed_in_ += str.size();
-    return decoder_.HandleControlFrameHeadersData(str.data(), str.size());
-  }
-
-  bool HandleControlFrameHeadersComplete() {
-    bool rc = decoder_.HandleControlFrameHeadersComplete();
-    return rc;
-  }
-
-  bool DecodeHeaderBlock(absl::string_view str,
-                         bool check_decoded_size = true) {
-    // Don't call this again if HandleControlFrameHeadersData failed previously.
-    EXPECT_FALSE(decode_has_failed_);
-    HandleControlFrameHeadersStart();
-    if (randomly_split_input_buffer_) {
-      do {
-        // Decode some fragment of the remaining bytes.
-        size_t bytes = str.size();
-        if (!str.empty()) {
-          bytes = random_.Uniform(str.size()) + 1;
-        }
-        EXPECT_LE(bytes, str.size());
-        if (!HandleControlFrameHeadersData(str.substr(0, bytes))) {
-          decode_has_failed_ = true;
-          return false;
-        }
-        str.remove_prefix(bytes);
-      } while (!str.empty());
-    } else if (!HandleControlFrameHeadersData(str)) {
-      decode_has_failed_ = true;
-      return false;
-    }
-    if (start_choice_ == START_WITH_HANDLER) {
-      if (!HandleControlFrameHeadersComplete()) {
-        decode_has_failed_ = true;
-        return false;
-      }
-      EXPECT_EQ(handler_.compressed_header_bytes(), bytes_passed_in_);
-    } else {
-      if (!HandleControlFrameHeadersComplete()) {
-        decode_has_failed_ = true;
-        return false;
-      }
-    }
-    if (check_decoded_size && start_choice_ == START_WITH_HANDLER) {
-      EXPECT_EQ(handler_.uncompressed_header_bytes(),
-                SizeOfHeaders(decoded_block()));
-    }
-    return true;
-  }
-
-  bool EncodeAndDecodeDynamicTableSizeUpdates(size_t first, size_t second) {
-    HpackBlockBuilder hbb;
-    hbb.AppendDynamicTableSizeUpdate(first);
-    if (second != first) {
-      hbb.AppendDynamicTableSizeUpdate(second);
-    }
-    return DecodeHeaderBlock(hbb.buffer());
-  }
-
-  const SpdyHeaderBlock& decoded_block() const {
-    if (start_choice_ == START_WITH_HANDLER) {
-      return handler_.decoded_block();
-    } else {
-      return decoder_.decoded_block();
-    }
-  }
-
-  static size_t SizeOfHeaders(const SpdyHeaderBlock& headers) {
-    size_t size = 0;
-    for (const auto& kv : headers) {
-      if (kv.first == kCookieKey) {
-        HpackEncoder::Representations crumbs;
-        HpackEncoderPeer::CookieToCrumbs(kv, &crumbs);
-        for (const auto& crumb : crumbs) {
-          size += crumb.first.size() + crumb.second.size();
-        }
-      } else {
-        size += kv.first.size() + kv.second.size();
-      }
-    }
-    return size;
-  }
-
-  const SpdyHeaderBlock& DecodeBlockExpectingSuccess(absl::string_view str) {
-    EXPECT_TRUE(DecodeHeaderBlock(str));
-    return decoded_block();
-  }
-
-  void expectEntry(size_t index,
-                   size_t size,
-                   const std::string& name,
-                   const std::string& value) {
-    const HpackStringPair* entry = decoder_peer_.GetTableEntry(index);
-    EXPECT_EQ(name, entry->name) << "index " << index;
-    EXPECT_EQ(value, entry->value);
-    EXPECT_EQ(size, entry->size());
-  }
-
-  SpdyHeaderBlock MakeHeaderBlock(
-      const std::vector<std::pair<std::string, std::string>>& headers) {
-    SpdyHeaderBlock result;
-    for (const auto& kv : headers) {
-      result.AppendValueOrAddHeader(kv.first, kv.second);
-    }
-    return result;
-  }
-
-  http2::test::Http2Random random_;
-  HpackDecoderAdapter decoder_;
-  test::HpackDecoderAdapterPeer decoder_peer_;
-  RecordingHeadersHandler handler_;
-  StartChoice start_choice_;
-  bool randomly_split_input_buffer_;
-  bool decode_has_failed_ = false;
-  size_t bytes_passed_in_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    NoHandler,
-    HpackDecoderAdapterTest,
-    ::testing::Combine(::testing::Values(START_WITHOUT_HANDLER, NO_START),
-                       ::testing::Bool()));
-
-INSTANTIATE_TEST_SUITE_P(
-    WithHandler,
-    HpackDecoderAdapterTest,
-    ::testing::Combine(::testing::Values(START_WITH_HANDLER),
-                       ::testing::Bool()));
-
-TEST_P(HpackDecoderAdapterTest, ApplyHeaderTableSizeSetting) {
-  EXPECT_EQ(4096u, decoder_.GetCurrentHeaderTableSizeSetting());
-  decoder_.ApplyHeaderTableSizeSetting(12 * 1024);
-  EXPECT_EQ(12288u, decoder_.GetCurrentHeaderTableSizeSetting());
-}
-
-TEST_P(HpackDecoderAdapterTest,
-       AddHeaderDataWithHandleControlFrameHeadersData) {
-  // The hpack decode buffer size is limited in size. This test verifies that
-  // adding encoded data under that limit is accepted, and data that exceeds the
-  // limit is rejected.
-  HandleControlFrameHeadersStart();
-  const size_t kMaxBufferSizeBytes = 50;
-  const std::string a_value = std::string(49, 'x');
-  decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes);
-  HpackBlockBuilder hbb;
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
-                                false, "a", false, a_value);
-  const std::string& s = hbb.buffer();
-  EXPECT_GT(s.size(), kMaxBufferSizeBytes);
-
-  // Any one in input buffer must not exceed kMaxBufferSizeBytes.
-  EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(0, s.size() / 2)));
-  EXPECT_TRUE(HandleControlFrameHeadersData(s.substr(s.size() / 2)));
-
-  EXPECT_FALSE(HandleControlFrameHeadersData(s));
-  SpdyHeaderBlock expected_block = MakeHeaderBlock({{"a", a_value}});
-  EXPECT_EQ(expected_block, decoded_block());
-}
-
-TEST_P(HpackDecoderAdapterTest, NameTooLong) {
-  // Verify that a name longer than the allowed size generates an error.
-  const size_t kMaxBufferSizeBytes = 50;
-  const std::string name = std::string(2 * kMaxBufferSizeBytes, 'x');
-  const std::string value = "abc";
-
-  decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes);
-
-  HpackBlockBuilder hbb;
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
-                                false, name, false, value);
-
-  const size_t fragment_size = (3 * kMaxBufferSizeBytes) / 2;
-  const std::string fragment = hbb.buffer().substr(0, fragment_size);
-
-  HandleControlFrameHeadersStart();
-  EXPECT_FALSE(HandleControlFrameHeadersData(fragment));
-}
-
-TEST_P(HpackDecoderAdapterTest, HeaderTooLongToBuffer) {
-  // Verify that a header longer than the allowed size generates an error if
-  // it isn't all in one input buffer.
-  const std::string name = "some-key";
-  const std::string value = "some-value";
-  const size_t kMaxBufferSizeBytes = name.size() + value.size() - 2;
-  decoder_.set_max_decode_buffer_size_bytes(kMaxBufferSizeBytes);
-
-  HpackBlockBuilder hbb;
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kNeverIndexedLiteralHeader,
-                                false, name, false, value);
-  const size_t fragment_size = hbb.size() - 1;
-  const std::string fragment = hbb.buffer().substr(0, fragment_size);
-
-  HandleControlFrameHeadersStart();
-  EXPECT_FALSE(HandleControlFrameHeadersData(fragment));
-}
-
-// Verify that a header block that exceeds the maximum length is rejected.
-TEST_P(HpackDecoderAdapterTest, HeaderBlockTooLong) {
-  const std::string name = "some-key";
-  const std::string value = "some-value";
-  const size_t kMaxBufferSizeBytes = 1024;
-
-  HpackBlockBuilder hbb;
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false,
-                                name, false, value);
-  while (hbb.size() < kMaxBufferSizeBytes) {
-    hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false,
-                                  "", false, "");
-  }
-  // With no limit on the maximum header block size, the decoder handles the
-  // entire block successfully.
-  HandleControlFrameHeadersStart();
-  EXPECT_TRUE(HandleControlFrameHeadersData(hbb.buffer()));
-  EXPECT_TRUE(HandleControlFrameHeadersComplete());
-
-  // When a total byte limit is imposed, the decoder bails before the end of the
-  // block.
-  decoder_.set_max_header_block_bytes(kMaxBufferSizeBytes);
-  HandleControlFrameHeadersStart();
-  EXPECT_FALSE(HandleControlFrameHeadersData(hbb.buffer()));
-}
-
-// Decode with incomplete data in buffer.
-TEST_P(HpackDecoderAdapterTest, DecodeWithIncompleteData) {
-  HandleControlFrameHeadersStart();
-
-  // No need to wait for more data.
-  EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82"));
-  std::vector<std::pair<std::string, std::string>> expected_headers = {
-      {":method", "GET"}, {":path", "/index.html"}, {":method", "GET"}};
-
-  SpdyHeaderBlock expected_block1 = MakeHeaderBlock(expected_headers);
-  EXPECT_EQ(expected_block1, decoded_block());
-
-  // Full and partial headers, won't add partial to the headers.
-  EXPECT_TRUE(
-      HandleControlFrameHeadersData("\x40\x03goo"
-                                    "\x03gar\xbe\x40\x04spam"));
-  expected_headers.push_back({"goo", "gar"});
-  expected_headers.push_back({"goo", "gar"});
-
-  SpdyHeaderBlock expected_block2 = MakeHeaderBlock(expected_headers);
-  EXPECT_EQ(expected_block2, decoded_block());
-
-  // Add the needed data.
-  EXPECT_TRUE(HandleControlFrameHeadersData("\x04gggs"));
-
-  EXPECT_TRUE(HandleControlFrameHeadersComplete());
-
-  expected_headers.push_back({"spam", "gggs"});
-
-  SpdyHeaderBlock expected_block3 = MakeHeaderBlock(expected_headers);
-  EXPECT_EQ(expected_block3, decoded_block());
-}
-
-TEST_P(HpackDecoderAdapterTest, HandleHeaderRepresentation) {
-  // Make sure the decoder is properly initialized.
-  HandleControlFrameHeadersStart();
-  HandleControlFrameHeadersData("");
-
-  // All cookie crumbs are joined.
-  decoder_peer_.HandleHeaderRepresentation("cookie", " part 1");
-  decoder_peer_.HandleHeaderRepresentation("cookie", "part 2 ");
-  decoder_peer_.HandleHeaderRepresentation("cookie", "part3");
-
-  // Already-delimited headers are passed through.
-  decoder_peer_.HandleHeaderRepresentation("passed-through",
-                                           std::string("foo\0baz", 7));
-
-  // Other headers are joined on \0. Case matters.
-  decoder_peer_.HandleHeaderRepresentation("joined", "joined");
-  decoder_peer_.HandleHeaderRepresentation("joineD", "value 1");
-  decoder_peer_.HandleHeaderRepresentation("joineD", "value 2");
-
-  // Empty headers remain empty.
-  decoder_peer_.HandleHeaderRepresentation("empty", "");
-
-  // Joined empty headers work as expected.
-  decoder_peer_.HandleHeaderRepresentation("empty-joined", "");
-  decoder_peer_.HandleHeaderRepresentation("empty-joined", "foo");
-  decoder_peer_.HandleHeaderRepresentation("empty-joined", "");
-  decoder_peer_.HandleHeaderRepresentation("empty-joined", "");
-
-  // Non-contiguous cookie crumb.
-  decoder_peer_.HandleHeaderRepresentation("cookie", " fin!");
-
-  // Finish and emit all headers.
-  decoder_.HandleControlFrameHeadersComplete();
-
-  // Resulting decoded headers are in the same order as the inputs.
-  EXPECT_THAT(
-      decoded_block(),
-      ElementsAre(
-          Pair("cookie", " part 1; part 2 ; part3;  fin!"),
-          Pair("passed-through", absl::string_view("foo\0baz", 7)),
-          Pair("joined", absl::string_view("joined\0value 1\0value 2", 22)),
-          Pair("empty", ""),
-          Pair("empty-joined", absl::string_view("\0foo\0\0", 6))));
-}
-
-// Decoding indexed static table field should work.
-TEST_P(HpackDecoderAdapterTest, IndexedHeaderStatic) {
-  // Reference static table entries #2 and #5.
-  const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess("\x82\x85");
-  SpdyHeaderBlock expected_header_set1;
-  expected_header_set1[":method"] = "GET";
-  expected_header_set1[":path"] = "/index.html";
-  EXPECT_EQ(expected_header_set1, header_set1);
-
-  // Reference static table entry #2.
-  const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess("\x82");
-  SpdyHeaderBlock expected_header_set2;
-  expected_header_set2[":method"] = "GET";
-  EXPECT_EQ(expected_header_set2, header_set2);
-}
-
-TEST_P(HpackDecoderAdapterTest, IndexedHeaderDynamic) {
-  // First header block: add an entry to header table.
-  const SpdyHeaderBlock& header_set1 = DecodeBlockExpectingSuccess(
-      "\x40\x03"
-      "foo"
-      "\x03"
-      "bar");
-  SpdyHeaderBlock expected_header_set1;
-  expected_header_set1["foo"] = "bar";
-  EXPECT_EQ(expected_header_set1, header_set1);
-
-  // Second header block: add another entry to header table.
-  const SpdyHeaderBlock& header_set2 = DecodeBlockExpectingSuccess(
-      "\xbe\x40\x04"
-      "spam"
-      "\x04"
-      "eggs");
-  SpdyHeaderBlock expected_header_set2;
-  expected_header_set2["foo"] = "bar";
-  expected_header_set2["spam"] = "eggs";
-  EXPECT_EQ(expected_header_set2, header_set2);
-
-  // Third header block: refer to most recently added entry.
-  const SpdyHeaderBlock& header_set3 = DecodeBlockExpectingSuccess("\xbe");
-  SpdyHeaderBlock expected_header_set3;
-  expected_header_set3["spam"] = "eggs";
-  EXPECT_EQ(expected_header_set3, header_set3);
-}
-
-// Test a too-large indexed header.
-TEST_P(HpackDecoderAdapterTest, InvalidIndexedHeader) {
-  // High-bit set, and a prefix of one more than the number of static entries.
-  EXPECT_FALSE(DecodeHeaderBlock("\xbe"));
-}
-
-TEST_P(HpackDecoderAdapterTest, ContextUpdateMaximumSize) {
-  EXPECT_EQ(kDefaultHeaderTableSizeSetting,
-            decoder_peer_.header_table_size_limit());
-  std::string input;
-  {
-    // Maximum-size update with size 126. Succeeds.
-    HpackOutputStream output_stream;
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(126);
-
-    input = output_stream.TakeString();
-    EXPECT_TRUE(DecodeHeaderBlock(input));
-    EXPECT_EQ(126u, decoder_peer_.header_table_size_limit());
-  }
-  {
-    // Maximum-size update with kDefaultHeaderTableSizeSetting. Succeeds.
-    HpackOutputStream output_stream;
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(kDefaultHeaderTableSizeSetting);
-
-    input = output_stream.TakeString();
-    EXPECT_TRUE(DecodeHeaderBlock(input));
-    EXPECT_EQ(kDefaultHeaderTableSizeSetting,
-              decoder_peer_.header_table_size_limit());
-  }
-  {
-    // Maximum-size update with kDefaultHeaderTableSizeSetting + 1. Fails.
-    HpackOutputStream output_stream;
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(kDefaultHeaderTableSizeSetting + 1);
-
-    input = output_stream.TakeString();
-    EXPECT_FALSE(DecodeHeaderBlock(input));
-    EXPECT_EQ(kDefaultHeaderTableSizeSetting,
-              decoder_peer_.header_table_size_limit());
-  }
-}
-
-// Two HeaderTableSizeUpdates may appear at the beginning of the block
-TEST_P(HpackDecoderAdapterTest, TwoTableSizeUpdates) {
-  std::string input;
-  {
-    // Should accept two table size updates, update to second one
-    HpackOutputStream output_stream;
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(0);
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(122);
-
-    input = output_stream.TakeString();
-    EXPECT_TRUE(DecodeHeaderBlock(input));
-    EXPECT_EQ(122u, decoder_peer_.header_table_size_limit());
-  }
-}
-
-// Three HeaderTableSizeUpdates should result in an error
-TEST_P(HpackDecoderAdapterTest, ThreeTableSizeUpdatesError) {
-  std::string input;
-  {
-    // Should reject three table size updates, update to second one
-    HpackOutputStream output_stream;
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(5);
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(10);
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(15);
-
-    input = output_stream.TakeString();
-
-    EXPECT_FALSE(DecodeHeaderBlock(input));
-    EXPECT_EQ(10u, decoder_peer_.header_table_size_limit());
-  }
-}
-
-// HeaderTableSizeUpdates may only appear at the beginning of the block
-// Any other updates should result in an error
-TEST_P(HpackDecoderAdapterTest, TableSizeUpdateSecondError) {
-  std::string input;
-  {
-    // Should reject a table size update appearing after a different entry
-    // The table size should remain as the default
-    HpackOutputStream output_stream;
-    output_stream.AppendBytes("\x82\x85");
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(123);
-
-    input = output_stream.TakeString();
-
-    EXPECT_FALSE(DecodeHeaderBlock(input));
-    EXPECT_EQ(kDefaultHeaderTableSizeSetting,
-              decoder_peer_.header_table_size_limit());
-  }
-}
-
-// HeaderTableSizeUpdates may only appear at the beginning of the block
-// Any other updates should result in an error
-TEST_P(HpackDecoderAdapterTest, TableSizeUpdateFirstThirdError) {
-  std::string input;
-  {
-    // Should reject the second table size update
-    // if a different entry appears after the first update
-    // The table size should update to the first but not the second
-    HpackOutputStream output_stream;
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(60);
-    output_stream.AppendBytes("\x82\x85");
-    output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream.AppendUint32(125);
-
-    input = output_stream.TakeString();
-
-    EXPECT_FALSE(DecodeHeaderBlock(input));
-    EXPECT_EQ(60u, decoder_peer_.header_table_size_limit());
-  }
-}
-
-// Decoding two valid encoded literal headers with no indexing should
-// work.
-TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexing) {
-  // First header with indexed name, second header with string literal
-  // name.
-  const char input[] = "\x04\x0c/sample/path\x00\x06:path2\x0e/sample/path/2";
-  const SpdyHeaderBlock& header_set = DecodeBlockExpectingSuccess(
-      absl::string_view(input, ABSL_ARRAYSIZE(input) - 1));
-
-  SpdyHeaderBlock expected_header_set;
-  expected_header_set[":path"] = "/sample/path";
-  expected_header_set[":path2"] = "/sample/path/2";
-  EXPECT_EQ(expected_header_set, header_set);
-}
-
-// Decoding two valid encoded literal headers with incremental
-// indexing and string literal names should work.
-TEST_P(HpackDecoderAdapterTest, LiteralHeaderIncrementalIndexing) {
-  const char input[] = "\x44\x0c/sample/path\x40\x06:path2\x0e/sample/path/2";
-  const SpdyHeaderBlock& header_set = DecodeBlockExpectingSuccess(
-      absl::string_view(input, ABSL_ARRAYSIZE(input) - 1));
-
-  SpdyHeaderBlock expected_header_set;
-  expected_header_set[":path"] = "/sample/path";
-  expected_header_set[":path2"] = "/sample/path/2";
-  EXPECT_EQ(expected_header_set, header_set);
-}
-
-TEST_P(HpackDecoderAdapterTest, LiteralHeaderWithIndexingInvalidNameIndex) {
-  decoder_.ApplyHeaderTableSizeSetting(0);
-  EXPECT_TRUE(EncodeAndDecodeDynamicTableSizeUpdates(0, 0));
-
-  // Name is the last static index. Works.
-  EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x7d\x03ooo")));
-  // Name is one beyond the last static index. Fails.
-  EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x7e\x03ooo")));
-}
-
-TEST_P(HpackDecoderAdapterTest, LiteralHeaderNoIndexingInvalidNameIndex) {
-  // Name is the last static index. Works.
-  EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x0f\x2e\x03ooo")));
-  // Name is one beyond the last static index. Fails.
-  EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x0f\x2f\x03ooo")));
-}
-
-TEST_P(HpackDecoderAdapterTest, LiteralHeaderNeverIndexedInvalidNameIndex) {
-  // Name is the last static index. Works.
-  EXPECT_TRUE(DecodeHeaderBlock(absl::string_view("\x1f\x2e\x03ooo")));
-  // Name is one beyond the last static index. Fails.
-  EXPECT_FALSE(DecodeHeaderBlock(absl::string_view("\x1f\x2f\x03ooo")));
-}
-
-TEST_P(HpackDecoderAdapterTest, TruncatedIndex) {
-  // Indexed Header, varint for index requires multiple bytes,
-  // but only one provided.
-  EXPECT_FALSE(DecodeHeaderBlock("\xff"));
-}
-
-TEST_P(HpackDecoderAdapterTest, TruncatedHuffmanLiteral) {
-  // Literal value, Huffman encoded, but with the last byte missing (i.e.
-  // drop the final ff shown below).
-  //
-  // 41                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 1)
-  //                                         |     :authority
-  // 8c                                      |   Literal value (len = 12)
-  //                                         |     Huffman encoded:
-  // f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
-  //                                         |     Decoded:
-  //                                         | www.example.com
-  //                                         | -> :authority: www.example.com
-
-  std::string first = absl::HexStringToBytes("418cf1e3c2e5f23a6ba0ab90f4ff");
-  EXPECT_TRUE(DecodeHeaderBlock(first));
-  first.pop_back();
-  EXPECT_FALSE(DecodeHeaderBlock(first));
-}
-
-TEST_P(HpackDecoderAdapterTest, HuffmanEOSError) {
-  // Literal value, Huffman encoded, but with an additional ff byte at the end
-  // of the string, i.e. an EOS that is longer than permitted.
-  //
-  // 41                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 1)
-  //                                         |     :authority
-  // 8d                                      |   Literal value (len = 13)
-  //                                         |     Huffman encoded:
-  // f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
-  //                                         |     Decoded:
-  //                                         | www.example.com
-  //                                         | -> :authority: www.example.com
-
-  std::string first = absl::HexStringToBytes("418cf1e3c2e5f23a6ba0ab90f4ff");
-  EXPECT_TRUE(DecodeHeaderBlock(first));
-  first = absl::HexStringToBytes("418df1e3c2e5f23a6ba0ab90f4ffff");
-  EXPECT_FALSE(DecodeHeaderBlock(first));
-}
-
-// Round-tripping the header set from RFC 7541 C.3.1 should work.
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1
-TEST_P(HpackDecoderAdapterTest, BasicC31) {
-  HpackEncoder encoder;
-
-  SpdyHeaderBlock expected_header_set;
-  expected_header_set[":method"] = "GET";
-  expected_header_set[":scheme"] = "http";
-  expected_header_set[":path"] = "/";
-  expected_header_set[":authority"] = "www.example.com";
-
-  std::string encoded_header_set =
-      encoder.EncodeHeaderBlock(expected_header_set);
-
-  EXPECT_TRUE(DecodeHeaderBlock(encoded_header_set));
-  EXPECT_EQ(expected_header_set, decoded_block());
-}
-
-// RFC 7541, Section C.4: Request Examples with Huffman Coding
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.4
-TEST_P(HpackDecoderAdapterTest, SectionC4RequestHuffmanExamples) {
-  // TODO(jamessynge): Use http2/hpack/tools/hpack_example.h to parse the
-  // example directly, instead of having it as a comment.
-  //
-  // 82                                      | == Indexed - Add ==
-  //                                         |   idx = 2
-  //                                         | -> :method: GET
-  // 86                                      | == Indexed - Add ==
-  //                                         |   idx = 6
-  //                                         | -> :scheme: http
-  // 84                                      | == Indexed - Add ==
-  //                                         |   idx = 4
-  //                                         | -> :path: /
-  // 41                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 1)
-  //                                         |     :authority
-  // 8c                                      |   Literal value (len = 12)
-  //                                         |     Huffman encoded:
-  // f1e3 c2e5 f23a 6ba0 ab90 f4ff           | .....:k.....
-  //                                         |     Decoded:
-  //                                         | www.example.com
-  //                                         | -> :authority: www.example.com
-  std::string first =
-      absl::HexStringToBytes("828684418cf1e3c2e5f23a6ba0ab90f4ff");
-  const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first);
-
-  EXPECT_THAT(first_header_set,
-              ElementsAre(
-                  // clang-format off
-      Pair(":method", "GET"),
-      Pair(":scheme", "http"),
-      Pair(":path", "/"),
-      Pair(":authority", "www.example.com")));
-  // clang-format on
-
-  expectEntry(62, 57, ":authority", "www.example.com");
-  EXPECT_EQ(57u, decoder_peer_.current_header_table_size());
-
-  // 82                                      | == Indexed - Add ==
-  //                                         |   idx = 2
-  //                                         | -> :method: GET
-  // 86                                      | == Indexed - Add ==
-  //                                         |   idx = 6
-  //                                         | -> :scheme: http
-  // 84                                      | == Indexed - Add ==
-  //                                         |   idx = 4
-  //                                         | -> :path: /
-  // be                                      | == Indexed - Add ==
-  //                                         |   idx = 62
-  //                                         | -> :authority: www.example.com
-  // 58                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 24)
-  //                                         |     cache-control
-  // 86                                      |   Literal value (len = 8)
-  //                                         |     Huffman encoded:
-  // a8eb 1064 9cbf                          | ...d..
-  //                                         |     Decoded:
-  //                                         | no-cache
-  //                                         | -> cache-control: no-cache
-
-  std::string second = absl::HexStringToBytes("828684be5886a8eb10649cbf");
-  const SpdyHeaderBlock& second_header_set =
-      DecodeBlockExpectingSuccess(second);
-
-  EXPECT_THAT(second_header_set,
-              ElementsAre(
-                  // clang-format off
-      Pair(":method", "GET"),
-      Pair(":scheme", "http"),
-      Pair(":path", "/"),
-      Pair(":authority", "www.example.com"),
-      Pair("cache-control", "no-cache")));
-  // clang-format on
-
-  expectEntry(62, 53, "cache-control", "no-cache");
-  expectEntry(63, 57, ":authority", "www.example.com");
-  EXPECT_EQ(110u, decoder_peer_.current_header_table_size());
-
-  // 82                                      | == Indexed - Add ==
-  //                                         |   idx = 2
-  //                                         | -> :method: GET
-  // 87                                      | == Indexed - Add ==
-  //                                         |   idx = 7
-  //                                         | -> :scheme: https
-  // 85                                      | == Indexed - Add ==
-  //                                         |   idx = 5
-  //                                         | -> :path: /index.html
-  // bf                                      | == Indexed - Add ==
-  //                                         |   idx = 63
-  //                                         | -> :authority: www.example.com
-  // 40                                      | == Literal indexed ==
-  // 88                                      |   Literal name (len = 10)
-  //                                         |     Huffman encoded:
-  // 25a8 49e9 5ba9 7d7f                     | %.I.[.}.
-  //                                         |     Decoded:
-  //                                         | custom-key
-  // 89                                      |   Literal value (len = 12)
-  //                                         |     Huffman encoded:
-  // 25a8 49e9 5bb8 e8b4 bf                  | %.I.[....
-  //                                         |     Decoded:
-  //                                         | custom-value
-  //                                         | -> custom-key: custom-value
-  std::string third = absl::HexStringToBytes(
-      "828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf");
-  const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third);
-
-  EXPECT_THAT(
-      third_header_set,
-      ElementsAre(
-          // clang-format off
-      Pair(":method", "GET"),
-      Pair(":scheme", "https"),
-      Pair(":path", "/index.html"),
-      Pair(":authority", "www.example.com"),
-      Pair("custom-key", "custom-value")));
-  // clang-format on
-
-  expectEntry(62, 54, "custom-key", "custom-value");
-  expectEntry(63, 53, "cache-control", "no-cache");
-  expectEntry(64, 57, ":authority", "www.example.com");
-  EXPECT_EQ(164u, decoder_peer_.current_header_table_size());
-}
-
-// RFC 7541, Section C.6: Response Examples with Huffman Coding
-// http://httpwg.org/specs/rfc7541.html#rfc.section.C.6
-TEST_P(HpackDecoderAdapterTest, SectionC6ResponseHuffmanExamples) {
-  // The example is based on a maximum dynamic table size of 256,
-  // which allows for testing dynamic table evictions.
-  decoder_peer_.set_header_table_size_limit(256);
-
-  // 48                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 8)
-  //                                         |     :status
-  // 82                                      |   Literal value (len = 3)
-  //                                         |     Huffman encoded:
-  // 6402                                    | d.
-  //                                         |     Decoded:
-  //                                         | 302
-  //                                         | -> :status: 302
-  // 58                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 24)
-  //                                         |     cache-control
-  // 85                                      |   Literal value (len = 7)
-  //                                         |     Huffman encoded:
-  // aec3 771a 4b                            | ..w.K
-  //                                         |     Decoded:
-  //                                         | private
-  //                                         | -> cache-control: private
-  // 61                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 33)
-  //                                         |     date
-  // 96                                      |   Literal value (len = 29)
-  //                                         |     Huffman encoded:
-  // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
-  // e082 a62d 1bff                          | ...-..
-  //                                         |     Decoded:
-  //                                         | Mon, 21 Oct 2013 20:13:21
-  //                                         | GMT
-  //                                         | -> date: Mon, 21 Oct 2013
-  //                                         |   20:13:21 GMT
-  // 6e                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 46)
-  //                                         |     location
-  // 91                                      |   Literal value (len = 23)
-  //                                         |     Huffman encoded:
-  // 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C
-  // d3                                      | .
-  //                                         |     Decoded:
-  //                                         | https://www.example.com
-  //                                         | -> location: https://www.e
-  //                                         |    xample.com
-
-  std::string first = absl::HexStringToBytes(
-      "488264025885aec3771a4b6196d07abe"
-      "941054d444a8200595040b8166e082a6"
-      "2d1bff6e919d29ad171863c78f0b97c8"
-      "e9ae82ae43d3");
-  const SpdyHeaderBlock& first_header_set = DecodeBlockExpectingSuccess(first);
-
-  EXPECT_THAT(first_header_set,
-              ElementsAre(
-                  // clang-format off
-      Pair(":status", "302"),
-      Pair("cache-control", "private"),
-      Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
-      Pair("location", "https://www.example.com")));
-  // clang-format on
-
-  expectEntry(62, 63, "location", "https://www.example.com");
-  expectEntry(63, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT");
-  expectEntry(64, 52, "cache-control", "private");
-  expectEntry(65, 42, ":status", "302");
-  EXPECT_EQ(222u, decoder_peer_.current_header_table_size());
-
-  // 48                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 8)
-  //                                         |     :status
-  // 83                                      |   Literal value (len = 3)
-  //                                         |     Huffman encoded:
-  // 640e ff                                 | d..
-  //                                         |     Decoded:
-  //                                         | 307
-  //                                         | - evict: :status: 302
-  //                                         | -> :status: 307
-  // c1                                      | == Indexed - Add ==
-  //                                         |   idx = 65
-  //                                         | -> cache-control: private
-  // c0                                      | == Indexed - Add ==
-  //                                         |   idx = 64
-  //                                         | -> date: Mon, 21 Oct 2013
-  //                                         |   20:13:21 GMT
-  // bf                                      | == Indexed - Add ==
-  //                                         |   idx = 63
-  //                                         | -> location:
-  //                                         |   https://www.example.com
-  std::string second = absl::HexStringToBytes("4883640effc1c0bf");
-  const SpdyHeaderBlock& second_header_set =
-      DecodeBlockExpectingSuccess(second);
-
-  EXPECT_THAT(second_header_set,
-              ElementsAre(
-                  // clang-format off
-      Pair(":status", "307"),
-      Pair("cache-control", "private"),
-      Pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
-      Pair("location", "https://www.example.com")));
-  // clang-format on
-
-  expectEntry(62, 42, ":status", "307");
-  expectEntry(63, 63, "location", "https://www.example.com");
-  expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:21 GMT");
-  expectEntry(65, 52, "cache-control", "private");
-  EXPECT_EQ(222u, decoder_peer_.current_header_table_size());
-
-  // 88                                      | == Indexed - Add ==
-  //                                         |   idx = 8
-  //                                         | -> :status: 200
-  // c1                                      | == Indexed - Add ==
-  //                                         |   idx = 65
-  //                                         | -> cache-control: private
-  // 61                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 33)
-  //                                         |     date
-  // 96                                      |   Literal value (len = 22)
-  //                                         |     Huffman encoded:
-  // d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f
-  // e084 a62d 1bff                          | ...-..
-  //                                         |     Decoded:
-  //                                         | Mon, 21 Oct 2013 20:13:22
-  //                                         | GMT
-  //                                         | - evict: cache-control:
-  //                                         |   private
-  //                                         | -> date: Mon, 21 Oct 2013
-  //                                         |   20:13:22 GMT
-  // c0                                      | == Indexed - Add ==
-  //                                         |   idx = 64
-  //                                         | -> location:
-  //                                         |    https://www.example.com
-  // 5a                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 26)
-  //                                         |     content-encoding
-  // 83                                      |   Literal value (len = 3)
-  //                                         |     Huffman encoded:
-  // 9bd9 ab                                 | ...
-  //                                         |     Decoded:
-  //                                         | gzip
-  //                                         | - evict: date: Mon, 21 Oct
-  //                                         |    2013 20:13:21 GMT
-  //                                         | -> content-encoding: gzip
-  // 77                                      | == Literal indexed ==
-  //                                         |   Indexed name (idx = 55)
-  //                                         |     set-cookie
-  // ad                                      |   Literal value (len = 45)
-  //                                         |     Huffman encoded:
-  // 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9`
-  // d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)...
-  // 3160 65c0 03ed 4ee5 b106 3d50 07        | 1`e...N...=P.
-  //                                         |     Decoded:
-  //                                         | foo=ASDJKHQKBZXOQWEOPIUAXQ
-  //                                         | WEOIU; max-age=3600; versi
-  //                                         | on=1
-  //                                         | - evict: location:
-  //                                         |   https://www.example.com
-  //                                         | - evict: :status: 307
-  //                                         | -> set-cookie: foo=ASDJKHQ
-  //                                         |   KBZXOQWEOPIUAXQWEOIU;
-  //                                         |   max-age=3600; version=1
-  std::string third = absl::HexStringToBytes(
-      "88c16196d07abe941054d444a8200595"
-      "040b8166e084a62d1bffc05a839bd9ab"
-      "77ad94e7821dd7f2e6c7b335dfdfcd5b"
-      "3960d5af27087f3672c1ab270fb5291f"
-      "9587316065c003ed4ee5b1063d5007");
-  const SpdyHeaderBlock& third_header_set = DecodeBlockExpectingSuccess(third);
-
-  EXPECT_THAT(third_header_set,
-              ElementsAre(
-                  // clang-format off
-      Pair(":status", "200"),
-      Pair("cache-control", "private"),
-      Pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
-      Pair("location", "https://www.example.com"),
-      Pair("content-encoding", "gzip"),
-      Pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;"
-           " max-age=3600; version=1")));
-  // clang-format on
-
-  expectEntry(62, 98, "set-cookie",
-              "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;"
-              " max-age=3600; version=1");
-  expectEntry(63, 52, "content-encoding", "gzip");
-  expectEntry(64, 65, "date", "Mon, 21 Oct 2013 20:13:22 GMT");
-  EXPECT_EQ(215u, decoder_peer_.current_header_table_size());
-}
-
-// Regression test: Found that entries with dynamic indexed names and literal
-// values caused "use after free" MSAN failures if the name was evicted as it
-// was being re-used.
-TEST_P(HpackDecoderAdapterTest, ReuseNameOfEvictedEntry) {
-  // Each entry is measured as 32 bytes plus the sum of the lengths of the name
-  // and the value. Set the size big enough for at most one entry, and a fairly
-  // small one at that (31 ASCII characters).
-  decoder_.ApplyHeaderTableSizeSetting(63);
-
-  HpackBlockBuilder hbb;
-  hbb.AppendDynamicTableSizeUpdate(0);
-  hbb.AppendDynamicTableSizeUpdate(63);
-
-  const absl::string_view name("some-name");
-  const absl::string_view value1("some-value");
-  const absl::string_view value2("another-value");
-  const absl::string_view value3("yet-another-value");
-
-  // Add an entry that will become the first in the dynamic table, entry 62.
-  hbb.AppendLiteralNameAndValue(HpackEntryType::kIndexedLiteralHeader, false,
-                                name, false, value1);
-
-  // Confirm that entry has been added by re-using it.
-  hbb.AppendIndexedHeader(62);
-
-  // Add another entry referring to the name of the first. This will evict the
-  // first.
-  hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62,
-                                     false, value2);
-
-  // Confirm that entry has been added by re-using it.
-  hbb.AppendIndexedHeader(62);
-
-  // Add another entry referring to the name of the second. This will evict the
-  // second.
-  hbb.AppendNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, 62,
-                                     false, value3);
-
-  // Confirm that entry has been added by re-using it.
-  hbb.AppendIndexedHeader(62);
-
-  // Can't have DecodeHeaderBlock do the default check for size of the decoded
-  // data because SpdyHeaderBlock will join multiple headers with the same
-  // name into a single entry, thus we won't see repeated occurrences of the
-  // name, instead seeing separators between values.
-  EXPECT_TRUE(DecodeHeaderBlock(hbb.buffer(), kNoCheckDecodedSize));
-
-  SpdyHeaderBlock expected_header_set;
-  expected_header_set.AppendValueOrAddHeader(name, value1);
-  expected_header_set.AppendValueOrAddHeader(name, value1);
-  expected_header_set.AppendValueOrAddHeader(name, value2);
-  expected_header_set.AppendValueOrAddHeader(name, value2);
-  expected_header_set.AppendValueOrAddHeader(name, value3);
-  expected_header_set.AppendValueOrAddHeader(name, value3);
-
-  // SpdyHeaderBlock stores these 6 strings as '\0' separated values.
-  // Make sure that is what happened.
-  std::string joined_values = expected_header_set[name].as_string();
-  EXPECT_EQ(joined_values.size(),
-            2 * value1.size() + 2 * value2.size() + 2 * value3.size() + 5);
-
-  EXPECT_EQ(expected_header_set, decoded_block());
-
-  if (start_choice_ == START_WITH_HANDLER) {
-    EXPECT_EQ(handler_.uncompressed_header_bytes(),
-              6 * name.size() + 2 * value1.size() + 2 * value2.size() +
-                  2 * value3.size());
-  }
-}
-
-// Regression test for https://crbug.com/747395.
-TEST_P(HpackDecoderAdapterTest, Cookies) {
-  SpdyHeaderBlock expected_header_set;
-  expected_header_set["cookie"] = "foo; bar";
-
-  EXPECT_TRUE(DecodeHeaderBlock(absl::HexStringToBytes("608294e76003626172")));
-  EXPECT_EQ(expected_header_set, decoded_block());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_encoder.cc b/spdy/core/hpack/hpack_encoder.cc
deleted file mode 100644
index cc7746f..0000000
--- a/spdy/core/hpack/hpack_encoder.cc
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_encoder.h"
-
-#include <algorithm>
-#include <limits>
-#include <utility>
-
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-#include "spdy/core/hpack/hpack_output_stream.h"
-
-namespace spdy {
-
-class HpackEncoder::RepresentationIterator {
- public:
-  // |pseudo_headers| and |regular_headers| must outlive the iterator.
-  RepresentationIterator(const Representations& pseudo_headers,
-                         const Representations& regular_headers)
-      : pseudo_begin_(pseudo_headers.begin()),
-        pseudo_end_(pseudo_headers.end()),
-        regular_begin_(regular_headers.begin()),
-        regular_end_(regular_headers.end()) {}
-
-  // |headers| must outlive the iterator.
-  explicit RepresentationIterator(const Representations& headers)
-      : pseudo_begin_(headers.begin()),
-        pseudo_end_(headers.end()),
-        regular_begin_(headers.end()),
-        regular_end_(headers.end()) {}
-
-  bool HasNext() {
-    return pseudo_begin_ != pseudo_end_ || regular_begin_ != regular_end_;
-  }
-
-  const Representation Next() {
-    if (pseudo_begin_ != pseudo_end_) {
-      return *pseudo_begin_++;
-    } else {
-      return *regular_begin_++;
-    }
-  }
-
- private:
-  Representations::const_iterator pseudo_begin_;
-  Representations::const_iterator pseudo_end_;
-  Representations::const_iterator regular_begin_;
-  Representations::const_iterator regular_end_;
-};
-
-namespace {
-
-// The default header listener.
-void NoOpListener(absl::string_view /*name*/, absl::string_view /*value*/) {}
-
-// The default HPACK indexing policy.
-bool DefaultPolicy(absl::string_view name, absl::string_view /* value */) {
-  if (name.empty()) {
-    return false;
-  }
-  // :authority is always present and rarely changes, and has moderate
-  // length, therefore it makes a lot of sense to index (insert in the
-  // dynamic table).
-  if (name[0] == kPseudoHeaderPrefix) {
-    return name == ":authority";
-  }
-  return true;
-}
-
-}  // namespace
-
-HpackEncoder::HpackEncoder()
-    : output_stream_(),
-      min_table_size_setting_received_(std::numeric_limits<size_t>::max()),
-      listener_(NoOpListener),
-      should_index_(DefaultPolicy),
-      enable_compression_(true),
-      should_emit_table_size_(false) {}
-
-HpackEncoder::~HpackEncoder() = default;
-
-std::string HpackEncoder::EncodeHeaderBlock(const SpdyHeaderBlock& header_set) {
-  // Separate header set into pseudo-headers and regular headers.
-  Representations pseudo_headers;
-  Representations regular_headers;
-  bool found_cookie = false;
-  for (const auto& header : header_set) {
-    if (!found_cookie && header.first == "cookie") {
-      // Note that there can only be one "cookie" header, because header_set is
-      // a map.
-      found_cookie = true;
-      CookieToCrumbs(header, &regular_headers);
-    } else if (!header.first.empty() &&
-               header.first[0] == kPseudoHeaderPrefix) {
-      DecomposeRepresentation(header, &pseudo_headers);
-    } else {
-      DecomposeRepresentation(header, &regular_headers);
-    }
-  }
-
-  RepresentationIterator iter(pseudo_headers, regular_headers);
-  return EncodeRepresentations(&iter);
-}
-
-void HpackEncoder::ApplyHeaderTableSizeSetting(size_t size_setting) {
-  if (size_setting == header_table_.settings_size_bound()) {
-    return;
-  }
-  if (size_setting < header_table_.settings_size_bound()) {
-    min_table_size_setting_received_ =
-        std::min(size_setting, min_table_size_setting_received_);
-  }
-  header_table_.SetSettingsHeaderTableSize(size_setting);
-  should_emit_table_size_ = true;
-}
-
-std::string HpackEncoder::EncodeRepresentations(RepresentationIterator* iter) {
-  MaybeEmitTableSize();
-  while (iter->HasNext()) {
-    const auto header = iter->Next();
-    listener_(header.first, header.second);
-    if (enable_compression_) {
-      size_t index =
-          header_table_.GetByNameAndValue(header.first, header.second);
-      if (index != kHpackEntryNotFound) {
-        EmitIndex(index);
-      } else if (should_index_(header.first, header.second)) {
-        EmitIndexedLiteral(header);
-      } else {
-        EmitNonIndexedLiteral(header, enable_compression_);
-      }
-    } else {
-      EmitNonIndexedLiteral(header, enable_compression_);
-    }
-  }
-
-  return output_stream_.TakeString();
-}
-
-void HpackEncoder::EmitIndex(size_t index) {
-  QUICHE_DVLOG(2) << "Emitting index " << index;
-  output_stream_.AppendPrefix(kIndexedOpcode);
-  output_stream_.AppendUint32(index);
-}
-
-void HpackEncoder::EmitIndexedLiteral(const Representation& representation) {
-  QUICHE_DVLOG(2) << "Emitting indexed literal: (" << representation.first
-                  << ", " << representation.second << ")";
-  output_stream_.AppendPrefix(kLiteralIncrementalIndexOpcode);
-  EmitLiteral(representation);
-  header_table_.TryAddEntry(representation.first, representation.second);
-}
-
-void HpackEncoder::EmitNonIndexedLiteral(const Representation& representation,
-                                         bool enable_compression) {
-  QUICHE_DVLOG(2) << "Emitting nonindexed literal: (" << representation.first
-                  << ", " << representation.second << ")";
-  output_stream_.AppendPrefix(kLiteralNoIndexOpcode);
-  size_t name_index = header_table_.GetByName(representation.first);
-  if (enable_compression && name_index != kHpackEntryNotFound) {
-    output_stream_.AppendUint32(name_index);
-  } else {
-    output_stream_.AppendUint32(0);
-    EmitString(representation.first);
-  }
-  EmitString(representation.second);
-}
-
-void HpackEncoder::EmitLiteral(const Representation& representation) {
-  size_t name_index = header_table_.GetByName(representation.first);
-  if (name_index != kHpackEntryNotFound) {
-    output_stream_.AppendUint32(name_index);
-  } else {
-    output_stream_.AppendUint32(0);
-    EmitString(representation.first);
-  }
-  EmitString(representation.second);
-}
-
-void HpackEncoder::EmitString(absl::string_view str) {
-  size_t encoded_size =
-      enable_compression_ ? http2::HuffmanSize(str) : str.size();
-  if (encoded_size < str.size()) {
-    QUICHE_DVLOG(2) << "Emitted Huffman-encoded string of length "
-                    << encoded_size;
-    output_stream_.AppendPrefix(kStringLiteralHuffmanEncoded);
-    output_stream_.AppendUint32(encoded_size);
-    http2::HuffmanEncodeFast(str, encoded_size, output_stream_.MutableString());
-  } else {
-    QUICHE_DVLOG(2) << "Emitted literal string of length " << str.size();
-    output_stream_.AppendPrefix(kStringLiteralIdentityEncoded);
-    output_stream_.AppendUint32(str.size());
-    output_stream_.AppendBytes(str);
-  }
-}
-
-void HpackEncoder::MaybeEmitTableSize() {
-  if (!should_emit_table_size_) {
-    return;
-  }
-  const size_t current_size = CurrentHeaderTableSizeSetting();
-  QUICHE_DVLOG(1) << "MaybeEmitTableSize current_size=" << current_size;
-  QUICHE_DVLOG(1) << "MaybeEmitTableSize min_table_size_setting_received_="
-                  << min_table_size_setting_received_;
-  if (min_table_size_setting_received_ < current_size) {
-    output_stream_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    output_stream_.AppendUint32(min_table_size_setting_received_);
-  }
-  output_stream_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-  output_stream_.AppendUint32(current_size);
-  min_table_size_setting_received_ = std::numeric_limits<size_t>::max();
-  should_emit_table_size_ = false;
-}
-
-// static
-void HpackEncoder::CookieToCrumbs(const Representation& cookie,
-                                  Representations* out) {
-  // See Section 8.1.2.5. "Compressing the Cookie Header Field" in the HTTP/2
-  // specification at https://tools.ietf.org/html/draft-ietf-httpbis-http2-14.
-  // Cookie values are split into individually-encoded HPACK representations.
-  absl::string_view cookie_value = cookie.second;
-  // Consume leading and trailing whitespace if present.
-  absl::string_view::size_type first = cookie_value.find_first_not_of(" \t");
-  absl::string_view::size_type last = cookie_value.find_last_not_of(" \t");
-  if (first == absl::string_view::npos) {
-    cookie_value = absl::string_view();
-  } else {
-    cookie_value = cookie_value.substr(first, (last - first) + 1);
-  }
-  for (size_t pos = 0;;) {
-    size_t end = cookie_value.find(';', pos);
-
-    if (end == absl::string_view::npos) {
-      out->push_back(std::make_pair(cookie.first, cookie_value.substr(pos)));
-      break;
-    }
-    out->push_back(
-        std::make_pair(cookie.first, cookie_value.substr(pos, end - pos)));
-
-    // Consume next space if present.
-    pos = end + 1;
-    if (pos != cookie_value.size() && cookie_value[pos] == ' ') {
-      pos++;
-    }
-  }
-}
-
-// static
-void HpackEncoder::DecomposeRepresentation(const Representation& header_field,
-                                           Representations* out) {
-  size_t pos = 0;
-  size_t end = 0;
-  while (end != absl::string_view::npos) {
-    end = header_field.second.find('\0', pos);
-    out->push_back(std::make_pair(
-        header_field.first,
-        header_field.second.substr(
-            pos, end == absl::string_view::npos ? end : end - pos)));
-    pos = end + 1;
-  }
-}
-
-// Iteratively encodes a SpdyHeaderBlock.
-class HpackEncoder::Encoderator : public ProgressiveEncoder {
- public:
-  Encoderator(const SpdyHeaderBlock& header_set, HpackEncoder* encoder);
-  Encoderator(const Representations& representations, HpackEncoder* encoder);
-
-  // Encoderator is neither copyable nor movable.
-  Encoderator(const Encoderator&) = delete;
-  Encoderator& operator=(const Encoderator&) = delete;
-
-  // Returns true iff more remains to encode.
-  bool HasNext() const override { return has_next_; }
-
-  // Encodes and returns up to max_encoded_bytes of the current header block.
-  std::string Next(size_t max_encoded_bytes) override;
-
- private:
-  HpackEncoder* encoder_;
-  std::unique_ptr<RepresentationIterator> header_it_;
-  Representations pseudo_headers_;
-  Representations regular_headers_;
-  bool has_next_;
-};
-
-HpackEncoder::Encoderator::Encoderator(const SpdyHeaderBlock& header_set,
-                                       HpackEncoder* encoder)
-    : encoder_(encoder), has_next_(true) {
-  // Separate header set into pseudo-headers and regular headers.
-  bool found_cookie = false;
-  for (const auto& header : header_set) {
-    if (!found_cookie && header.first == "cookie") {
-      // Note that there can only be one "cookie" header, because header_set
-      // is a map.
-      found_cookie = true;
-      CookieToCrumbs(header, &regular_headers_);
-    } else if (!header.first.empty() &&
-               header.first[0] == kPseudoHeaderPrefix) {
-      DecomposeRepresentation(header, &pseudo_headers_);
-    } else {
-      DecomposeRepresentation(header, &regular_headers_);
-    }
-  }
-  header_it_ = std::make_unique<RepresentationIterator>(pseudo_headers_,
-                                                        regular_headers_);
-
-  encoder_->MaybeEmitTableSize();
-}
-
-HpackEncoder::Encoderator::Encoderator(const Representations& representations,
-                                       HpackEncoder* encoder)
-    : encoder_(encoder), has_next_(true) {
-  for (const auto& header : representations) {
-    if (header.first == "cookie") {
-      CookieToCrumbs(header, &regular_headers_);
-    } else if (!header.first.empty() &&
-               header.first[0] == kPseudoHeaderPrefix) {
-      pseudo_headers_.push_back(header);
-    } else {
-      regular_headers_.push_back(header);
-    }
-  }
-  header_it_ = std::make_unique<RepresentationIterator>(pseudo_headers_,
-                                                        regular_headers_);
-
-  encoder_->MaybeEmitTableSize();
-}
-
-std::string HpackEncoder::Encoderator::Next(size_t max_encoded_bytes) {
-  QUICHE_BUG_IF(spdy_bug_61_1, !has_next_)
-      << "Encoderator::Next called with nothing left to encode.";
-  const bool enable_compression = encoder_->enable_compression_;
-
-  // Encode up to max_encoded_bytes of headers.
-  while (header_it_->HasNext() &&
-         encoder_->output_stream_.size() <= max_encoded_bytes) {
-    const Representation header = header_it_->Next();
-    encoder_->listener_(header.first, header.second);
-    if (enable_compression) {
-      size_t index = encoder_->header_table_.GetByNameAndValue(header.first,
-                                                               header.second);
-      if (index != kHpackEntryNotFound) {
-        encoder_->EmitIndex(index);
-      } else if (encoder_->should_index_(header.first, header.second)) {
-        encoder_->EmitIndexedLiteral(header);
-      } else {
-        encoder_->EmitNonIndexedLiteral(header, enable_compression);
-      }
-    } else {
-      encoder_->EmitNonIndexedLiteral(header, enable_compression);
-    }
-  }
-
-  has_next_ = encoder_->output_stream_.size() > max_encoded_bytes;
-  return encoder_->output_stream_.BoundedTakeString(max_encoded_bytes);
-}
-
-std::unique_ptr<HpackEncoder::ProgressiveEncoder> HpackEncoder::EncodeHeaderSet(
-    const SpdyHeaderBlock& header_set) {
-  return std::make_unique<Encoderator>(header_set, this);
-}
-
-std::unique_ptr<HpackEncoder::ProgressiveEncoder>
-HpackEncoder::EncodeRepresentations(const Representations& representations) {
-  return std::make_unique<Encoderator>(representations, this);
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_encoder.h b/spdy/core/hpack/hpack_encoder.h
deleted file mode 100644
index dbdbb6b..0000000
--- a/spdy/core/hpack/hpack_encoder.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_ENCODER_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_ENCODER_H_
-
-#include <stddef.h>
-
-#include <functional>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-#include "spdy/core/hpack/hpack_output_stream.h"
-#include "spdy/core/spdy_protocol.h"
-
-// An HpackEncoder encodes header sets as outlined in
-// http://tools.ietf.org/html/rfc7541.
-
-namespace spdy {
-
-namespace test {
-class HpackEncoderPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE HpackEncoder {
- public:
-  using Representation = std::pair<absl::string_view, absl::string_view>;
-  using Representations = std::vector<Representation>;
-
-  // Callers may provide a HeaderListener to be informed of header name-value
-  // pairs processed by this encoder.
-  using HeaderListener =
-      std::function<void(absl::string_view, absl::string_view)>;
-
-  // An indexing policy should return true if the provided header name-value
-  // pair should be inserted into the HPACK dynamic table.
-  using IndexingPolicy =
-      std::function<bool(absl::string_view, absl::string_view)>;
-
-  HpackEncoder();
-  HpackEncoder(const HpackEncoder&) = delete;
-  HpackEncoder& operator=(const HpackEncoder&) = delete;
-  ~HpackEncoder();
-
-  // Encodes and returns the given header set as a string.
-  std::string EncodeHeaderBlock(const SpdyHeaderBlock& header_set);
-
-  class QUICHE_EXPORT_PRIVATE ProgressiveEncoder {
-   public:
-    virtual ~ProgressiveEncoder() {}
-
-    // Returns true iff more remains to encode.
-    virtual bool HasNext() const = 0;
-
-    // Encodes and returns up to max_encoded_bytes of the current header block.
-    virtual std::string Next(size_t max_encoded_bytes) = 0;
-  };
-
-  // Returns a ProgressiveEncoder which must be outlived by both the given
-  // SpdyHeaderBlock and this object.
-  std::unique_ptr<ProgressiveEncoder> EncodeHeaderSet(
-      const SpdyHeaderBlock& header_set);
-  // Returns a ProgressiveEncoder which must be outlived by this HpackEncoder.
-  // The encoder will not attempt to split any \0-delimited values in
-  // |representations|. If such splitting is desired, it must be performed by
-  // the caller when constructing the list of representations.
-  std::unique_ptr<ProgressiveEncoder> EncodeRepresentations(
-      const Representations& representations);
-
-  // Called upon a change to SETTINGS_HEADER_TABLE_SIZE. Specifically, this
-  // is to be called after receiving (and sending an acknowledgement for) a
-  // SETTINGS_HEADER_TABLE_SIZE update from the remote decoding endpoint.
-  void ApplyHeaderTableSizeSetting(size_t size_setting);
-
-  // TODO(birenroy): Rename this GetDynamicTableCapacity().
-  size_t CurrentHeaderTableSizeSetting() const {
-    return header_table_.settings_size_bound();
-  }
-
-  // This HpackEncoder will use |policy| to determine whether to insert header
-  // name-value pairs into the dynamic table.
-  void SetIndexingPolicy(IndexingPolicy policy) { should_index_ = policy; }
-
-  // |listener| will be invoked for each header name-value pair processed by
-  // this encoder.
-  void SetHeaderListener(HeaderListener listener) { listener_ = listener; }
-
-  void DisableCompression() { enable_compression_ = false; }
-
-  // Returns the current dynamic table size, including the 32 bytes per entry
-  // overhead mentioned in RFC 7541 section 4.1.
-  size_t GetDynamicTableSize() const { return header_table_.size(); }
-
- private:
-  friend class test::HpackEncoderPeer;
-
-  class RepresentationIterator;
-  class Encoderator;
-
-  // Encodes a sequence of header name-value pairs as a single header block.
-  std::string EncodeRepresentations(RepresentationIterator* iter);
-
-  // Emits a static/dynamic indexed representation (Section 7.1).
-  void EmitIndex(size_t index);
-
-  // Emits a literal representation (Section 7.2).
-  void EmitIndexedLiteral(const Representation& representation);
-  void EmitNonIndexedLiteral(const Representation& representation,
-                             bool enable_compression);
-  void EmitLiteral(const Representation& representation);
-
-  // Emits a Huffman or identity string (whichever is smaller).
-  void EmitString(absl::string_view str);
-
-  // Emits the current dynamic table size if the table size was recently
-  // updated and we have not yet emitted it (Section 6.3).
-  void MaybeEmitTableSize();
-
-  // Crumbles a cookie header into ";" delimited crumbs.
-  static void CookieToCrumbs(const Representation& cookie,
-                             Representations* crumbs_out);
-
-  // Crumbles other header field values at \0 delimiters.
-  static void DecomposeRepresentation(const Representation& header_field,
-                                      Representations* out);
-
-  HpackHeaderTable header_table_;
-  HpackOutputStream output_stream_;
-
-  size_t min_table_size_setting_received_;
-  HeaderListener listener_;
-  IndexingPolicy should_index_;
-  bool enable_compression_;
-  bool should_emit_table_size_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_ENCODER_H_
diff --git a/spdy/core/hpack/hpack_encoder_test.cc b/spdy/core/hpack/hpack_encoder_test.cc
deleted file mode 100644
index c47bf97..0000000
--- a/spdy/core/hpack/hpack_encoder_test.cc
+++ /dev/null
@@ -1,756 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_encoder.h"
-
-#include <cstdint>
-#include <utility>
-
-#include "http2/hpack/huffman/hpack_huffman_encoder.h"
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/hpack/hpack_static_table.h"
-#include "spdy/core/spdy_simple_arena.h"
-
-namespace spdy {
-
-namespace test {
-
-class HpackHeaderTablePeer {
- public:
-  explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {}
-
-  const HpackEntry* GetFirstStaticEntry() const {
-    return &table_->static_entries_.front();
-  }
-
-  HpackHeaderTable::DynamicEntryTable* dynamic_entries() {
-    return &table_->dynamic_entries_;
-  }
-
- private:
-  HpackHeaderTable* table_;
-};
-
-class HpackEncoderPeer {
- public:
-  typedef HpackEncoder::Representation Representation;
-  typedef HpackEncoder::Representations Representations;
-
-  explicit HpackEncoderPeer(HpackEncoder* encoder) : encoder_(encoder) {}
-
-  bool compression_enabled() const { return encoder_->enable_compression_; }
-  HpackHeaderTable* table() { return &encoder_->header_table_; }
-  HpackHeaderTablePeer table_peer() { return HpackHeaderTablePeer(table()); }
-  void EmitString(absl::string_view str) { encoder_->EmitString(str); }
-  void TakeString(std::string* out) {
-    *out = encoder_->output_stream_.TakeString();
-  }
-  static void CookieToCrumbs(absl::string_view cookie,
-                             std::vector<absl::string_view>* out) {
-    Representations tmp;
-    HpackEncoder::CookieToCrumbs(std::make_pair("", cookie), &tmp);
-
-    out->clear();
-    for (size_t i = 0; i != tmp.size(); ++i) {
-      out->push_back(tmp[i].second);
-    }
-  }
-  static void DecomposeRepresentation(absl::string_view value,
-                                      std::vector<absl::string_view>* out) {
-    Representations tmp;
-    HpackEncoder::DecomposeRepresentation(std::make_pair("foobar", value),
-                                          &tmp);
-
-    out->clear();
-    for (size_t i = 0; i != tmp.size(); ++i) {
-      out->push_back(tmp[i].second);
-    }
-  }
-
-  // TODO(dahollings): Remove or clean up these methods when deprecating
-  // non-incremental encoding path.
-  static std::string EncodeHeaderBlock(HpackEncoder* encoder,
-                                       const SpdyHeaderBlock& header_set) {
-    return encoder->EncodeHeaderBlock(header_set);
-  }
-
-  static bool EncodeIncremental(HpackEncoder* encoder,
-                                const SpdyHeaderBlock& header_set,
-                                std::string* output) {
-    std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator =
-        encoder->EncodeHeaderSet(header_set);
-    http2::test::Http2Random random;
-    std::string output_buffer = encoderator->Next(random.UniformInRange(0, 16));
-    while (encoderator->HasNext()) {
-      std::string second_buffer =
-          encoderator->Next(random.UniformInRange(0, 16));
-      output_buffer.append(second_buffer);
-    }
-    *output = std::move(output_buffer);
-    return true;
-  }
-
-  static bool EncodeRepresentations(HpackEncoder* encoder,
-                                    const Representations& representations,
-                                    std::string* output) {
-    std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator =
-        encoder->EncodeRepresentations(representations);
-    http2::test::Http2Random random;
-    std::string output_buffer = encoderator->Next(random.UniformInRange(0, 16));
-    while (encoderator->HasNext()) {
-      std::string second_buffer =
-          encoderator->Next(random.UniformInRange(0, 16));
-      output_buffer.append(second_buffer);
-    }
-    *output = std::move(output_buffer);
-    return true;
-  }
-
- private:
-  HpackEncoder* encoder_;
-};
-
-}  // namespace test
-
-namespace {
-
-using testing::ElementsAre;
-using testing::Pair;
-
-const size_t kStaticEntryIndex = 1;
-
-enum EncodeStrategy {
-  kDefault,
-  kIncremental,
-  kRepresentations,
-};
-
-class HpackEncoderTest : public QuicheTestWithParam<EncodeStrategy> {
- protected:
-  typedef test::HpackEncoderPeer::Representations Representations;
-
-  HpackEncoderTest()
-      : peer_(&encoder_),
-        static_(peer_.table_peer().GetFirstStaticEntry()),
-        dynamic_table_insertions_(0),
-        headers_storage_(1024 /* block size */),
-        strategy_(GetParam()) {}
-
-  void SetUp() override {
-    // Populate dynamic entries into the table fixture. For simplicity each
-    // entry has name.size() + value.size() == 10.
-    key_1_ = peer_.table()->TryAddEntry("key1", "value1");
-    key_1_index_ = dynamic_table_insertions_++;
-    key_2_ = peer_.table()->TryAddEntry("key2", "value2");
-    key_2_index_ = dynamic_table_insertions_++;
-    cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb");
-    cookie_a_index_ = dynamic_table_insertions_++;
-    cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd");
-    cookie_c_index_ = dynamic_table_insertions_++;
-
-    // No further insertions may occur without evictions.
-    peer_.table()->SetMaxSize(peer_.table()->size());
-    QUICHE_CHECK_EQ(kInitialDynamicTableSize, peer_.table()->size());
-  }
-
-  void SaveHeaders(absl::string_view name, absl::string_view value) {
-    absl::string_view n(headers_storage_.Memdup(name.data(), name.size()),
-                        name.size());
-    absl::string_view v(headers_storage_.Memdup(value.data(), value.size()),
-                        value.size());
-    headers_observed_.push_back(std::make_pair(n, v));
-  }
-
-  void ExpectIndex(size_t index) {
-    expected_.AppendPrefix(kIndexedOpcode);
-    expected_.AppendUint32(index);
-  }
-  void ExpectIndexedLiteral(size_t key_index, absl::string_view value) {
-    expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
-    expected_.AppendUint32(key_index);
-    ExpectString(&expected_, value);
-  }
-  void ExpectIndexedLiteral(absl::string_view name, absl::string_view value) {
-    expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
-    expected_.AppendUint32(0);
-    ExpectString(&expected_, name);
-    ExpectString(&expected_, value);
-  }
-  void ExpectNonIndexedLiteral(absl::string_view name,
-                               absl::string_view value) {
-    expected_.AppendPrefix(kLiteralNoIndexOpcode);
-    expected_.AppendUint32(0);
-    ExpectString(&expected_, name);
-    ExpectString(&expected_, value);
-  }
-  void ExpectNonIndexedLiteralWithNameIndex(size_t key_index,
-                                            absl::string_view value) {
-    expected_.AppendPrefix(kLiteralNoIndexOpcode);
-    expected_.AppendUint32(key_index);
-    ExpectString(&expected_, value);
-  }
-  void ExpectString(HpackOutputStream* stream, absl::string_view str) {
-    size_t encoded_size =
-        peer_.compression_enabled() ? http2::HuffmanSize(str) : str.size();
-    if (encoded_size < str.size()) {
-      expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
-      expected_.AppendUint32(encoded_size);
-      http2::HuffmanEncodeFast(str, encoded_size, stream->MutableString());
-    } else {
-      expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-      expected_.AppendUint32(str.size());
-      expected_.AppendBytes(str);
-    }
-  }
-  void ExpectHeaderTableSizeUpdate(uint32_t size) {
-    expected_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
-    expected_.AppendUint32(size);
-  }
-  Representations MakeRepresentations(const SpdyHeaderBlock& header_set) {
-    Representations r;
-    for (const auto& header : header_set) {
-      r.push_back(header);
-    }
-    return r;
-  }
-  void CompareWithExpectedEncoding(const SpdyHeaderBlock& header_set) {
-    std::string actual_out;
-    std::string expected_out = expected_.TakeString();
-    switch (strategy_) {
-      case kDefault:
-        actual_out =
-            test::HpackEncoderPeer::EncodeHeaderBlock(&encoder_, header_set);
-        break;
-      case kIncremental:
-        EXPECT_TRUE(test::HpackEncoderPeer::EncodeIncremental(
-            &encoder_, header_set, &actual_out));
-        break;
-      case kRepresentations:
-        EXPECT_TRUE(test::HpackEncoderPeer::EncodeRepresentations(
-            &encoder_, MakeRepresentations(header_set), &actual_out));
-        break;
-    }
-    EXPECT_EQ(expected_out, actual_out);
-  }
-  void CompareWithExpectedEncoding(const Representations& representations) {
-    std::string actual_out;
-    std::string expected_out = expected_.TakeString();
-    EXPECT_TRUE(test::HpackEncoderPeer::EncodeRepresentations(
-        &encoder_, representations, &actual_out));
-    EXPECT_EQ(expected_out, actual_out);
-  }
-  // Converts the index of a dynamic table entry to the HPACK index.
-  // In these test, dynamic table entries are indexed sequentially, starting
-  // with 0.  The HPACK indexing scheme is defined at
-  // https://httpwg.org/specs/rfc7541.html#index.address.space.
-  size_t DynamicIndexToWireIndex(size_t index) {
-    return dynamic_table_insertions_ - index + kStaticTableSize;
-  }
-
-  HpackEncoder encoder_;
-  test::HpackEncoderPeer peer_;
-
-  // Calculated based on the names and values inserted in SetUp(), above.
-  const size_t kInitialDynamicTableSize = 4 * (10 + 32);
-
-  const HpackEntry* static_;
-  const HpackEntry* key_1_;
-  const HpackEntry* key_2_;
-  const HpackEntry* cookie_a_;
-  const HpackEntry* cookie_c_;
-  size_t key_1_index_;
-  size_t key_2_index_;
-  size_t cookie_a_index_;
-  size_t cookie_c_index_;
-  size_t dynamic_table_insertions_;
-
-  SpdySimpleArena headers_storage_;
-  std::vector<std::pair<absl::string_view, absl::string_view>>
-      headers_observed_;
-
-  HpackOutputStream expected_;
-  const EncodeStrategy strategy_;
-};
-
-using HpackEncoderTestWithDefaultStrategy = HpackEncoderTest;
-
-INSTANTIATE_TEST_SUITE_P(HpackEncoderTests,
-                         HpackEncoderTestWithDefaultStrategy,
-                         ::testing::Values(kDefault));
-
-TEST_P(HpackEncoderTestWithDefaultStrategy, EncodeRepresentations) {
-  EXPECT_EQ(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
-  encoder_.SetHeaderListener(
-      [this](absl::string_view name, absl::string_view value) {
-        this->SaveHeaders(name, value);
-      });
-  const std::vector<std::pair<absl::string_view, absl::string_view>>
-      header_list = {{"cookie", "val1; val2;val3"},
-                     {":path", "/home"},
-                     {"accept", "text/html, text/plain,application/xml"},
-                     {"cookie", "val4"},
-                     {"withnul", absl::string_view("one\0two", 7)}};
-  ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
-                                       "/home");
-  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val1");
-  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val2");
-  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val3");
-  ExpectIndexedLiteral(peer_.table()->GetByName("accept"),
-                       "text/html, text/plain,application/xml");
-  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val4");
-  ExpectIndexedLiteral("withnul", absl::string_view("one\0two", 7));
-
-  CompareWithExpectedEncoding(header_list);
-  EXPECT_THAT(
-      headers_observed_,
-      ElementsAre(Pair(":path", "/home"), Pair("cookie", "val1"),
-                  Pair("cookie", "val2"), Pair("cookie", "val3"),
-                  Pair("accept", "text/html, text/plain,application/xml"),
-                  Pair("cookie", "val4"),
-                  Pair("withnul", absl::string_view("one\0two", 7))));
-  // Insertions and evictions have happened over the course of the test.
-  EXPECT_GE(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
-}
-
-TEST_P(HpackEncoderTestWithDefaultStrategy, DynamicTableGrows) {
-  EXPECT_EQ(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
-  peer_.table()->SetMaxSize(4096);
-  encoder_.SetHeaderListener(
-      [this](absl::string_view name, absl::string_view value) {
-        this->SaveHeaders(name, value);
-      });
-  const std::vector<std::pair<absl::string_view, absl::string_view>>
-      header_list = {{"cookie", "val1; val2;val3"},
-                     {":path", "/home"},
-                     {"accept", "text/html, text/plain,application/xml"},
-                     {"cookie", "val4"},
-                     {"withnul", absl::string_view("one\0two", 7)}};
-  std::string out;
-  EXPECT_TRUE(test::HpackEncoderPeer::EncodeRepresentations(&encoder_,
-                                                            header_list, &out));
-
-  EXPECT_FALSE(out.empty());
-  // Insertions have happened over the course of the test.
-  EXPECT_GT(encoder_.GetDynamicTableSize(), kInitialDynamicTableSize);
-}
-
-INSTANTIATE_TEST_SUITE_P(HpackEncoderTests,
-                         HpackEncoderTest,
-                         ::testing::Values(kDefault,
-                                           kIncremental,
-                                           kRepresentations));
-
-TEST_P(HpackEncoderTest, SingleDynamicIndex) {
-  encoder_.SetHeaderListener(
-      [this](absl::string_view name, absl::string_view value) {
-        this->SaveHeaders(name, value);
-      });
-
-  ExpectIndex(DynamicIndexToWireIndex(key_2_index_));
-
-  SpdyHeaderBlock headers;
-  headers[key_2_->name()] = key_2_->value();
-  CompareWithExpectedEncoding(headers);
-  EXPECT_THAT(headers_observed_,
-              ElementsAre(Pair(key_2_->name(), key_2_->value())));
-}
-
-TEST_P(HpackEncoderTest, SingleStaticIndex) {
-  ExpectIndex(kStaticEntryIndex);
-
-  SpdyHeaderBlock headers;
-  headers[static_->name()] = static_->value();
-  CompareWithExpectedEncoding(headers);
-}
-
-TEST_P(HpackEncoderTest, SingleStaticIndexTooLarge) {
-  peer_.table()->SetMaxSize(1);  // Also evicts all fixtures.
-  ExpectIndex(kStaticEntryIndex);
-
-  SpdyHeaderBlock headers;
-  headers[static_->name()] = static_->value();
-  CompareWithExpectedEncoding(headers);
-
-  EXPECT_EQ(0u, peer_.table_peer().dynamic_entries()->size());
-}
-
-TEST_P(HpackEncoderTest, SingleLiteralWithIndexName) {
-  ExpectIndexedLiteral(DynamicIndexToWireIndex(key_2_index_), "value3");
-
-  SpdyHeaderBlock headers;
-  headers[key_2_->name()] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  // A new entry was inserted and added to the reference set.
-  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
-  EXPECT_EQ(new_entry->name(), key_2_->name());
-  EXPECT_EQ(new_entry->value(), "value3");
-}
-
-TEST_P(HpackEncoderTest, SingleLiteralWithLiteralName) {
-  ExpectIndexedLiteral("key3", "value3");
-
-  SpdyHeaderBlock headers;
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
-  EXPECT_EQ(new_entry->name(), "key3");
-  EXPECT_EQ(new_entry->value(), "value3");
-}
-
-TEST_P(HpackEncoderTest, SingleLiteralTooLarge) {
-  peer_.table()->SetMaxSize(1);  // Also evicts all fixtures.
-
-  ExpectIndexedLiteral("key3", "value3");
-
-  // A header overflowing the header table is still emitted.
-  // The header table is empty.
-  SpdyHeaderBlock headers;
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  EXPECT_EQ(0u, peer_.table_peer().dynamic_entries()->size());
-}
-
-TEST_P(HpackEncoderTest, EmitThanEvict) {
-  // |key_1_| is toggled and placed into the reference set,
-  // and then immediately evicted by "key3".
-  ExpectIndex(DynamicIndexToWireIndex(key_1_index_));
-  ExpectIndexedLiteral("key3", "value3");
-
-  SpdyHeaderBlock headers;
-  headers[key_1_->name()] = key_1_->value();
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-}
-
-TEST_P(HpackEncoderTest, CookieHeaderIsCrumbled) {
-  ExpectIndex(DynamicIndexToWireIndex(cookie_a_index_));
-  ExpectIndex(DynamicIndexToWireIndex(cookie_c_index_));
-  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");
-
-  SpdyHeaderBlock headers;
-  headers["cookie"] = "a=bb; c=dd; e=ff";
-  CompareWithExpectedEncoding(headers);
-}
-
-TEST_P(HpackEncoderTest, MultiValuedHeadersNotCrumbled) {
-  ExpectIndexedLiteral("foo", "bar, baz");
-  SpdyHeaderBlock headers;
-  headers["foo"] = "bar, baz";
-  CompareWithExpectedEncoding(headers);
-}
-
-TEST_P(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) {
-  // Compactable string. Uses Huffman coding.
-  peer_.EmitString("feedbeef");
-  expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
-  expected_.AppendUint32(6);
-  expected_.AppendBytes("\x94\xA5\x92\x32\x96_");
-
-  // Non-compactable. Uses identity coding.
-  peer_.EmitString("@@@@@@");
-  expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-  expected_.AppendUint32(6);
-  expected_.AppendBytes("@@@@@@");
-
-  std::string actual_out;
-  std::string expected_out = expected_.TakeString();
-  peer_.TakeString(&actual_out);
-  EXPECT_EQ(expected_out, actual_out);
-}
-
-TEST_P(HpackEncoderTest, EncodingWithoutCompression) {
-  encoder_.SetHeaderListener(
-      [this](absl::string_view name, absl::string_view value) {
-        this->SaveHeaders(name, value);
-      });
-  encoder_.DisableCompression();
-
-  ExpectNonIndexedLiteral(":path", "/index.html");
-  ExpectNonIndexedLiteral("cookie", "foo=bar");
-  ExpectNonIndexedLiteral("cookie", "baz=bing");
-  if (strategy_ == kRepresentations) {
-    ExpectNonIndexedLiteral("hello", std::string("goodbye\0aloha", 13));
-  } else {
-    ExpectNonIndexedLiteral("hello", "goodbye");
-    ExpectNonIndexedLiteral("hello", "aloha");
-  }
-  ExpectNonIndexedLiteral("multivalue", "value1, value2");
-
-  SpdyHeaderBlock headers;
-  headers[":path"] = "/index.html";
-  headers["cookie"] = "foo=bar; baz=bing";
-  headers["hello"] = "goodbye";
-  headers.AppendValueOrAddHeader("hello", "aloha");
-  headers["multivalue"] = "value1, value2";
-
-  CompareWithExpectedEncoding(headers);
-
-  if (strategy_ == kRepresentations) {
-    EXPECT_THAT(
-        headers_observed_,
-        ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"),
-                    Pair("cookie", "baz=bing"),
-                    Pair("hello", absl::string_view("goodbye\0aloha", 13)),
-                    Pair("multivalue", "value1, value2")));
-  } else {
-    EXPECT_THAT(
-        headers_observed_,
-        ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"),
-                    Pair("cookie", "baz=bing"), Pair("hello", "goodbye"),
-                    Pair("hello", "aloha"),
-                    Pair("multivalue", "value1, value2")));
-  }
-  EXPECT_EQ(kInitialDynamicTableSize, encoder_.GetDynamicTableSize());
-}
-
-TEST_P(HpackEncoderTest, MultipleEncodingPasses) {
-  encoder_.SetHeaderListener(
-      [this](absl::string_view name, absl::string_view value) {
-        this->SaveHeaders(name, value);
-      });
-
-  // Pass 1.
-  {
-    SpdyHeaderBlock headers;
-    headers["key1"] = "value1";
-    headers["cookie"] = "a=bb";
-
-    ExpectIndex(DynamicIndexToWireIndex(key_1_index_));
-    ExpectIndex(DynamicIndexToWireIndex(cookie_a_index_));
-    CompareWithExpectedEncoding(headers);
-  }
-  // Header table is:
-  // 65: key1: value1
-  // 64: key2: value2
-  // 63: cookie: a=bb
-  // 62: cookie: c=dd
-  // Pass 2.
-  {
-    SpdyHeaderBlock headers;
-    headers["key2"] = "value2";
-    headers["cookie"] = "c=dd; e=ff";
-
-    // "key2: value2"
-    ExpectIndex(DynamicIndexToWireIndex(key_2_index_));
-    // "cookie: c=dd"
-    ExpectIndex(DynamicIndexToWireIndex(cookie_c_index_));
-    // This cookie evicts |key1| from the dynamic table.
-    ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "e=ff");
-    dynamic_table_insertions_++;
-
-    CompareWithExpectedEncoding(headers);
-  }
-  // Header table is:
-  // 65: key2: value2
-  // 64: cookie: a=bb
-  // 63: cookie: c=dd
-  // 62: cookie: e=ff
-  // Pass 3.
-  {
-    SpdyHeaderBlock headers;
-    headers["key2"] = "value2";
-    headers["cookie"] = "a=bb; b=cc; c=dd";
-
-    // "key2: value2"
-    EXPECT_EQ(65u, DynamicIndexToWireIndex(key_2_index_));
-    ExpectIndex(DynamicIndexToWireIndex(key_2_index_));
-    // "cookie: a=bb"
-    EXPECT_EQ(64u, DynamicIndexToWireIndex(cookie_a_index_));
-    ExpectIndex(DynamicIndexToWireIndex(cookie_a_index_));
-    // This cookie evicts |key2| from the dynamic table.
-    ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "b=cc");
-    dynamic_table_insertions_++;
-    // "cookie: c=dd"
-    ExpectIndex(DynamicIndexToWireIndex(cookie_c_index_));
-
-    CompareWithExpectedEncoding(headers);
-  }
-
-  // clang-format off
-  EXPECT_THAT(headers_observed_,
-              ElementsAre(Pair("key1", "value1"),
-                          Pair("cookie", "a=bb"),
-                          Pair("key2", "value2"),
-                          Pair("cookie", "c=dd"),
-                          Pair("cookie", "e=ff"),
-                          Pair("key2", "value2"),
-                          Pair("cookie", "a=bb"),
-                          Pair("cookie", "b=cc"),
-                          Pair("cookie", "c=dd")));
-  // clang-format on
-}
-
-TEST_P(HpackEncoderTest, PseudoHeadersFirst) {
-  SpdyHeaderBlock headers;
-  // A pseudo-header that should not be indexed.
-  headers[":path"] = "/spam/eggs.html";
-  // A pseudo-header to be indexed.
-  headers[":authority"] = "www.example.com";
-  // A regular header which precedes ":" alphabetically, should still be encoded
-  // after pseudo-headers.
-  headers["-foo"] = "bar";
-  headers["foo"] = "bar";
-  headers["cookie"] = "c=dd";
-
-  // Headers are indexed in the order in which they were added.
-  // This entry pushes "cookie: a=bb" back to 63.
-  ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
-                                       "/spam/eggs.html");
-  ExpectIndexedLiteral(peer_.table()->GetByName(":authority"),
-                       "www.example.com");
-  ExpectIndexedLiteral("-foo", "bar");
-  ExpectIndexedLiteral("foo", "bar");
-  ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "c=dd");
-  CompareWithExpectedEncoding(headers);
-}
-
-TEST_P(HpackEncoderTest, CookieToCrumbs) {
-  test::HpackEncoderPeer peer(nullptr);
-  std::vector<absl::string_view> out;
-
-  // Leading and trailing whitespace is consumed. A space after ';' is consumed.
-  // All other spaces remain. ';' at beginning and end of string produce empty
-  // crumbs.
-  // See section 8.1.3.4 "Compressing the Cookie Header Field" in the HTTP/2
-  // specification at http://tools.ietf.org/html/draft-ietf-httpbis-http2-11
-  peer.CookieToCrumbs(" foo=1;bar=2 ; bar=3;  bing=4; ", &out);
-  EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3", " bing=4", ""));
-
-  peer.CookieToCrumbs(";;foo = bar ;; ;baz =bing", &out);
-  EXPECT_THAT(out, ElementsAre("", "", "foo = bar ", "", "", "baz =bing"));
-
-  peer.CookieToCrumbs("baz=bing; foo=bar; baz=bing", &out);
-  EXPECT_THAT(out, ElementsAre("baz=bing", "foo=bar", "baz=bing"));
-
-  peer.CookieToCrumbs("baz=bing", &out);
-  EXPECT_THAT(out, ElementsAre("baz=bing"));
-
-  peer.CookieToCrumbs("", &out);
-  EXPECT_THAT(out, ElementsAre(""));
-
-  peer.CookieToCrumbs("foo;bar; baz;baz;bing;", &out);
-  EXPECT_THAT(out, ElementsAre("foo", "bar", "baz", "baz", "bing", ""));
-
-  peer.CookieToCrumbs(" \t foo=1;bar=2 ; bar=3;\t  ", &out);
-  EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3", ""));
-
-  peer.CookieToCrumbs(" \t foo=1;bar=2 ; bar=3 \t  ", &out);
-  EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3"));
-}
-
-TEST_P(HpackEncoderTest, DecomposeRepresentation) {
-  test::HpackEncoderPeer peer(nullptr);
-  std::vector<absl::string_view> out;
-
-  peer.DecomposeRepresentation("", &out);
-  EXPECT_THAT(out, ElementsAre(""));
-
-  peer.DecomposeRepresentation("foobar", &out);
-  EXPECT_THAT(out, ElementsAre("foobar"));
-
-  peer.DecomposeRepresentation(absl::string_view("foo\0bar", 7), &out);
-  EXPECT_THAT(out, ElementsAre("foo", "bar"));
-
-  peer.DecomposeRepresentation(absl::string_view("\0foo\0bar", 8), &out);
-  EXPECT_THAT(out, ElementsAre("", "foo", "bar"));
-
-  peer.DecomposeRepresentation(absl::string_view("foo\0bar\0", 8), &out);
-  EXPECT_THAT(out, ElementsAre("foo", "bar", ""));
-
-  peer.DecomposeRepresentation(absl::string_view("\0foo\0bar\0", 9), &out);
-  EXPECT_THAT(out, ElementsAre("", "foo", "bar", ""));
-}
-
-// Test that encoded headers do not have \0-delimited multiple values, as this
-// became disallowed in HTTP/2 draft-14.
-TEST_P(HpackEncoderTest, CrumbleNullByteDelimitedValue) {
-  if (strategy_ == kRepresentations) {
-    // When HpackEncoder is asked to encode a list of Representations, the
-    // caller must crumble null-delimited values.
-    return;
-  }
-  SpdyHeaderBlock headers;
-  // A header field to be crumbled: "spam: foo\0bar".
-  headers["spam"] = std::string("foo\0bar", 7);
-
-  ExpectIndexedLiteral("spam", "foo");
-  expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
-  expected_.AppendUint32(62);
-  expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-  expected_.AppendUint32(3);
-  expected_.AppendBytes("bar");
-  CompareWithExpectedEncoding(headers);
-}
-
-TEST_P(HpackEncoderTest, HeaderTableSizeUpdate) {
-  encoder_.ApplyHeaderTableSizeSetting(1024);
-  ExpectHeaderTableSizeUpdate(1024);
-  ExpectIndexedLiteral("key3", "value3");
-
-  SpdyHeaderBlock headers;
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
-  EXPECT_EQ(new_entry->name(), "key3");
-  EXPECT_EQ(new_entry->value(), "value3");
-}
-
-TEST_P(HpackEncoderTest, HeaderTableSizeUpdateWithMin) {
-  const size_t starting_size = peer_.table()->settings_size_bound();
-  encoder_.ApplyHeaderTableSizeSetting(starting_size - 2);
-  encoder_.ApplyHeaderTableSizeSetting(starting_size - 1);
-  // We must encode the low watermark, so the peer knows to evict entries
-  // if necessary.
-  ExpectHeaderTableSizeUpdate(starting_size - 2);
-  ExpectHeaderTableSizeUpdate(starting_size - 1);
-  ExpectIndexedLiteral("key3", "value3");
-
-  SpdyHeaderBlock headers;
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
-  EXPECT_EQ(new_entry->name(), "key3");
-  EXPECT_EQ(new_entry->value(), "value3");
-}
-
-TEST_P(HpackEncoderTest, HeaderTableSizeUpdateWithExistingSize) {
-  encoder_.ApplyHeaderTableSizeSetting(peer_.table()->settings_size_bound());
-  // No encoded size update.
-  ExpectIndexedLiteral("key3", "value3");
-
-  SpdyHeaderBlock headers;
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
-  EXPECT_EQ(new_entry->name(), "key3");
-  EXPECT_EQ(new_entry->value(), "value3");
-}
-
-TEST_P(HpackEncoderTest, HeaderTableSizeUpdatesWithGreaterSize) {
-  const size_t starting_size = peer_.table()->settings_size_bound();
-  encoder_.ApplyHeaderTableSizeSetting(starting_size + 1);
-  encoder_.ApplyHeaderTableSizeSetting(starting_size + 2);
-  // Only a single size update to the final size.
-  ExpectHeaderTableSizeUpdate(starting_size + 2);
-  ExpectIndexedLiteral("key3", "value3");
-
-  SpdyHeaderBlock headers;
-  headers["key3"] = "value3";
-  CompareWithExpectedEncoding(headers);
-
-  HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
-  EXPECT_EQ(new_entry->name(), "key3");
-  EXPECT_EQ(new_entry->value(), "value3");
-}
-
-}  // namespace
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_entry.cc b/spdy/core/hpack/hpack_entry.cc
deleted file mode 100644
index d755214..0000000
--- a/spdy/core/hpack/hpack_entry.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_entry.h"
-
-#include "absl/strings/str_cat.h"
-
-namespace spdy {
-
-HpackEntry::HpackEntry(std::string name, std::string value)
-    : name_(std::move(name)), value_(std::move(value)) {}
-
-// static
-size_t HpackEntry::Size(absl::string_view name, absl::string_view value) {
-  return name.size() + value.size() + kHpackEntrySizeOverhead;
-}
-size_t HpackEntry::Size() const {
-  return Size(name(), value());
-}
-
-std::string HpackEntry::GetDebugString() const {
-  return absl::StrCat("{ name: \"", name_, "\", value: \"", value_, "\" }");
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_entry.h b/spdy/core/hpack/hpack_entry.h
deleted file mode 100644
index 86e3977..0000000
--- a/spdy/core/hpack/hpack_entry.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_ENTRY_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_ENTRY_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-// All section references below are to
-// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
-
-namespace spdy {
-
-// The constant amount added to name().size() and value().size() to
-// get the size of an HpackEntry as defined in 5.1.
-constexpr size_t kHpackEntrySizeOverhead = 32;
-
-// A structure for looking up entries in the static and dynamic tables.
-struct QUICHE_EXPORT_PRIVATE HpackLookupEntry {
-  absl::string_view name;
-  absl::string_view value;
-
-  bool operator==(const HpackLookupEntry& other) const {
-    return name == other.name && value == other.value;
-  }
-
-  // Abseil hashing framework extension according to absl/hash/hash.h:
-  template <typename H>
-  friend H AbslHashValue(H h, const HpackLookupEntry& entry) {
-    return H::combine(std::move(h), entry.name, entry.value);
-  }
-};
-
-// A structure for an entry in the static table (3.3.1)
-// and the header table (3.3.2).
-class QUICHE_EXPORT_PRIVATE HpackEntry {
- public:
-  HpackEntry(std::string name, std::string value);
-
-  // Make HpackEntry non-copyable to make sure it is always moved.
-  HpackEntry(const HpackEntry&) = delete;
-  HpackEntry& operator=(const HpackEntry&) = delete;
-
-  HpackEntry(HpackEntry&&) = default;
-  HpackEntry& operator=(HpackEntry&&) = default;
-
-  // Getters for std::string members traditionally return const std::string&.
-  // However, HpackHeaderTable uses string_view as keys in the maps
-  // static_name_index_ and dynamic_name_index_.  If HpackEntry::name() returned
-  // const std::string&, then
-  //   dynamic_name_index_.insert(std::make_pair(entry.name(), index));
-  // would silently create a dangling reference: make_pair infers type from the
-  // return type of entry.name() and silently creates a temporary string copy.
-  // Insert creates a string_view that points to this copy, which then
-  // immediately goes out of scope and gets destroyed.  While this is quite easy
-  // to avoid, for example, by explicitly specifying type as a template
-  // parameter to make_pair, returning string_view here is less error-prone.
-  absl::string_view name() const { return name_; }
-  absl::string_view value() const { return value_; }
-
-  // Returns the size of an entry as defined in 5.1.
-  static size_t Size(absl::string_view name, absl::string_view value);
-  size_t Size() const;
-
-  std::string GetDebugString() const;
-
- private:
-  std::string name_;
-  std::string value_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_ENTRY_H_
diff --git a/spdy/core/hpack/hpack_entry_test.cc b/spdy/core/hpack/hpack_entry_test.cc
deleted file mode 100644
index 81acd9a..0000000
--- a/spdy/core/hpack/hpack_entry_test.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_entry.h"
-
-#include "absl/hash/hash.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-
-namespace {
-
-TEST(HpackLookupEntryTest, EntryNamesDiffer) {
-  HpackLookupEntry entry1{"header", "value"};
-  HpackLookupEntry entry2{"HEADER", "value"};
-
-  EXPECT_FALSE(entry1 == entry2);
-  EXPECT_NE(absl::Hash<HpackLookupEntry>()(entry1),
-            absl::Hash<HpackLookupEntry>()(entry2));
-}
-
-TEST(HpackLookupEntryTest, EntryValuesDiffer) {
-  HpackLookupEntry entry1{"header", "value"};
-  HpackLookupEntry entry2{"header", "VALUE"};
-
-  EXPECT_FALSE(entry1 == entry2);
-  EXPECT_NE(absl::Hash<HpackLookupEntry>()(entry1),
-            absl::Hash<HpackLookupEntry>()(entry2));
-}
-
-TEST(HpackLookupEntryTest, EntriesEqual) {
-  HpackLookupEntry entry1{"name", "value"};
-  HpackLookupEntry entry2{"name", "value"};
-
-  EXPECT_TRUE(entry1 == entry2);
-  EXPECT_EQ(absl::Hash<HpackLookupEntry>()(entry1),
-            absl::Hash<HpackLookupEntry>()(entry2));
-}
-
-TEST(HpackEntryTest, BasicEntry) {
-  HpackEntry entry("header-name", "header value");
-
-  EXPECT_EQ("header-name", entry.name());
-  EXPECT_EQ("header value", entry.value());
-
-  EXPECT_EQ(55u, entry.Size());
-  EXPECT_EQ(55u, HpackEntry::Size("header-name", "header value"));
-}
-
-}  // namespace
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_header_table.cc b/spdy/core/hpack/hpack_header_table.cc
deleted file mode 100644
index 6358003..0000000
--- a/spdy/core/hpack/hpack_header_table.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_header_table.h"
-
-#include <algorithm>
-
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_static_table.h"
-
-namespace spdy {
-
-HpackHeaderTable::HpackHeaderTable()
-    : static_entries_(ObtainHpackStaticTable().GetStaticEntries()),
-      static_index_(ObtainHpackStaticTable().GetStaticIndex()),
-      static_name_index_(ObtainHpackStaticTable().GetStaticNameIndex()),
-      settings_size_bound_(kDefaultHeaderTableSizeSetting),
-      size_(0),
-      max_size_(kDefaultHeaderTableSizeSetting),
-      dynamic_table_insertions_(0) {}
-
-HpackHeaderTable::~HpackHeaderTable() = default;
-
-size_t HpackHeaderTable::GetByName(absl::string_view name) {
-  {
-    auto it = static_name_index_.find(name);
-    if (it != static_name_index_.end()) {
-      return 1 + it->second;
-    }
-  }
-  {
-    NameToEntryMap::const_iterator it = dynamic_name_index_.find(name);
-    if (it != dynamic_name_index_.end()) {
-      return dynamic_table_insertions_ - it->second + kStaticTableSize;
-    }
-  }
-  return kHpackEntryNotFound;
-}
-
-size_t HpackHeaderTable::GetByNameAndValue(absl::string_view name,
-                                           absl::string_view value) {
-  HpackLookupEntry query{name, value};
-  {
-    auto it = static_index_.find(query);
-    if (it != static_index_.end()) {
-      return 1 + it->second;
-    }
-  }
-  {
-    auto it = dynamic_index_.find(query);
-    if (it != dynamic_index_.end()) {
-      return dynamic_table_insertions_ - it->second + kStaticTableSize;
-    }
-  }
-  return kHpackEntryNotFound;
-}
-
-void HpackHeaderTable::SetMaxSize(size_t max_size) {
-  QUICHE_CHECK_LE(max_size, settings_size_bound_);
-
-  max_size_ = max_size;
-  if (size_ > max_size_) {
-    Evict(EvictionCountToReclaim(size_ - max_size_));
-    QUICHE_CHECK_LE(size_, max_size_);
-  }
-}
-
-void HpackHeaderTable::SetSettingsHeaderTableSize(size_t settings_size) {
-  settings_size_bound_ = settings_size;
-  SetMaxSize(settings_size_bound_);
-}
-
-void HpackHeaderTable::EvictionSet(absl::string_view name,
-                                   absl::string_view value,
-                                   DynamicEntryTable::iterator* begin_out,
-                                   DynamicEntryTable::iterator* end_out) {
-  size_t eviction_count = EvictionCountForEntry(name, value);
-  *begin_out = dynamic_entries_.end() - eviction_count;
-  *end_out = dynamic_entries_.end();
-}
-
-size_t HpackHeaderTable::EvictionCountForEntry(absl::string_view name,
-                                               absl::string_view value) const {
-  size_t available_size = max_size_ - size_;
-  size_t entry_size = HpackEntry::Size(name, value);
-
-  if (entry_size <= available_size) {
-    // No evictions are required.
-    return 0;
-  }
-  return EvictionCountToReclaim(entry_size - available_size);
-}
-
-size_t HpackHeaderTable::EvictionCountToReclaim(size_t reclaim_size) const {
-  size_t count = 0;
-  for (auto it = dynamic_entries_.rbegin();
-       it != dynamic_entries_.rend() && reclaim_size != 0; ++it, ++count) {
-    reclaim_size -= std::min(reclaim_size, it->Size());
-  }
-  return count;
-}
-
-void HpackHeaderTable::Evict(size_t count) {
-  for (size_t i = 0; i != count; ++i) {
-    QUICHE_CHECK(!dynamic_entries_.empty());
-
-    HpackEntry* entry = &dynamic_entries_.back();
-    const size_t index = dynamic_table_insertions_ - dynamic_entries_.size();
-
-    size_ -= entry->Size();
-    auto it = dynamic_index_.find({entry->name(), entry->value()});
-    QUICHE_DCHECK(it != dynamic_index_.end());
-    // Only remove an entry from the index if its insertion index matches;
-    // otherwise, the index refers to another entry with the same name and
-    // value.
-    if (it->second == index) {
-      dynamic_index_.erase(it);
-    }
-    auto name_it = dynamic_name_index_.find(entry->name());
-    QUICHE_DCHECK(name_it != dynamic_name_index_.end());
-    // Only remove an entry from the literal index if its insertion index
-    /// matches; otherwise, the index refers to another entry with the same
-    // name.
-    if (name_it->second == index) {
-      dynamic_name_index_.erase(name_it);
-    }
-    dynamic_entries_.pop_back();
-  }
-}
-
-const HpackEntry* HpackHeaderTable::TryAddEntry(absl::string_view name,
-                                                absl::string_view value) {
-  // Since |dynamic_entries_| has iterator stability, |name| and |value| are
-  // valid even after evicting other entries and push_front() making room for
-  // the new one.
-  Evict(EvictionCountForEntry(name, value));
-
-  size_t entry_size = HpackEntry::Size(name, value);
-  if (entry_size > (max_size_ - size_)) {
-    // Entire table has been emptied, but there's still insufficient room.
-    QUICHE_DCHECK(dynamic_entries_.empty());
-    QUICHE_DCHECK_EQ(0u, size_);
-    return nullptr;
-  }
-
-  const size_t index = dynamic_table_insertions_;
-  dynamic_entries_.push_front(
-      HpackEntry(std::string(name), std::string(value)));
-  HpackEntry* new_entry = &dynamic_entries_.front();
-  auto index_result = dynamic_index_.insert(std::make_pair(
-      HpackLookupEntry{new_entry->name(), new_entry->value()}, index));
-  if (!index_result.second) {
-    // An entry with the same name and value already exists in the dynamic
-    // index. We should replace it with the newly added entry.
-    QUICHE_DVLOG(1) << "Found existing entry at: " << index_result.first->second
-                    << " replacing with: " << new_entry->GetDebugString()
-                    << " at: " << index;
-    QUICHE_DCHECK_GT(index, index_result.first->second);
-    dynamic_index_.erase(index_result.first);
-    auto insert_result = dynamic_index_.insert(std::make_pair(
-        HpackLookupEntry{new_entry->name(), new_entry->value()}, index));
-    QUICHE_CHECK(insert_result.second);
-  }
-
-  auto name_result =
-      dynamic_name_index_.insert(std::make_pair(new_entry->name(), index));
-  if (!name_result.second) {
-    // An entry with the same name already exists in the dynamic index. We
-    // should replace it with the newly added entry.
-    QUICHE_DVLOG(1) << "Found existing entry at: " << name_result.first->second
-                    << " replacing with: " << new_entry->GetDebugString()
-                    << " at: " << index;
-    QUICHE_DCHECK_GT(index, name_result.first->second);
-    dynamic_name_index_.erase(name_result.first);
-    auto insert_result =
-        dynamic_name_index_.insert(std::make_pair(new_entry->name(), index));
-    QUICHE_CHECK(insert_result.second);
-  }
-
-  size_ += entry_size;
-  ++dynamic_table_insertions_;
-
-  return &dynamic_entries_.front();
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_header_table.h b/spdy/core/hpack/hpack_header_table.h
deleted file mode 100644
index 427fc85..0000000
--- a/spdy/core/hpack/hpack_header_table.h
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <deque>
-#include <memory>
-
-#include "absl/base/attributes.h"
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "absl/hash/hash.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_entry.h"
-
-// All section references below are to http://tools.ietf.org/html/rfc7541.
-
-namespace spdy {
-
-namespace test {
-class HpackHeaderTablePeer;
-}  // namespace test
-
-// Return value of GetByName() and GetByNameAndValue() if matching entry is not
-// found.  This value is never used in HPACK for indexing entries, see
-// https://httpwg.org/specs/rfc7541.html#index.address.space.
-constexpr size_t kHpackEntryNotFound = 0;
-
-// A data structure for the static table (2.3.1) and the dynamic table (2.3.2).
-class QUICHE_EXPORT_PRIVATE HpackHeaderTable {
- public:
-  friend class test::HpackHeaderTablePeer;
-
-  // Use a lightweight, memory efficient container for the static table, which
-  // is initialized once and never changed after.
-  using StaticEntryTable = std::vector<HpackEntry>;
-
-  // HpackHeaderTable takes advantage of the deque property that references
-  // remain valid, so long as insertions & deletions are at the head & tail.
-  // This precludes the use of base::circular_deque.
-  // TODO(b/182349990): Change to a more memory efficient container.
-  using DynamicEntryTable = std::deque<HpackEntry>;
-
-  using NameValueToEntryMap = absl::flat_hash_map<HpackLookupEntry, size_t>;
-  using NameToEntryMap = absl::flat_hash_map<absl::string_view, size_t>;
-
-  HpackHeaderTable();
-  HpackHeaderTable(const HpackHeaderTable&) = delete;
-  HpackHeaderTable& operator=(const HpackHeaderTable&) = delete;
-
-  ~HpackHeaderTable();
-
-  // Last-acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
-  size_t settings_size_bound() const { return settings_size_bound_; }
-
-  // Current and maximum estimated byte size of the table, as described in
-  // 4.1. Notably, this is /not/ the number of entries in the table.
-  size_t size() const { return size_; }
-  size_t max_size() const { return max_size_; }
-
-  // The HPACK indexing scheme used by GetByName() and GetByNameAndValue() is
-  // defined at https://httpwg.org/specs/rfc7541.html#index.address.space.
-
-  // Returns the index of the lowest-index entry matching |name|,
-  // or kHpackEntryNotFound if no matching entry is found.
-  size_t GetByName(absl::string_view name);
-
-  // Returns the index of the lowest-index entry matching |name| and |value|,
-  // or kHpackEntryNotFound if no matching entry is found.
-  size_t GetByNameAndValue(absl::string_view name, absl::string_view value);
-
-  // Sets the maximum size of the header table, evicting entries if
-  // necessary as described in 5.2.
-  void SetMaxSize(size_t max_size);
-
-  // Sets the SETTINGS_HEADER_TABLE_SIZE bound of the table. Will call
-  // SetMaxSize() as needed to preserve max_size() <= settings_size_bound().
-  void SetSettingsHeaderTableSize(size_t settings_size);
-
-  // Determine the set of entries which would be evicted by the insertion
-  // of |name| & |value| into the table, as per section 4.4. No eviction
-  // actually occurs. The set is returned via range [begin_out, end_out).
-  void EvictionSet(absl::string_view name,
-                   absl::string_view value,
-                   DynamicEntryTable::iterator* begin_out,
-                   DynamicEntryTable::iterator* end_out);
-
-  // Adds an entry for the representation, evicting entries as needed. |name|
-  // and |value| must not point to an entry in |dynamic_entries_| which is about
-  // to be evicted, but they may point to an entry which is not.
-  // The added HpackEntry is returned, or NULL is returned if all entries were
-  // evicted and the empty table is of insufficent size for the representation.
-  const HpackEntry* TryAddEntry(absl::string_view name,
-                                absl::string_view value);
-
- private:
-  // Returns number of evictions required to enter |name| & |value|.
-  size_t EvictionCountForEntry(absl::string_view name,
-                               absl::string_view value) const;
-
-  // Returns number of evictions required to reclaim |reclaim_size| table size.
-  size_t EvictionCountToReclaim(size_t reclaim_size) const;
-
-  // Evicts |count| oldest entries from the table.
-  void Evict(size_t count);
-
-  // |static_entries_|, |static_index_|, and |static_name_index_| are owned by
-  // HpackStaticTable singleton.
-
-  // Stores HpackEntries.
-  const StaticEntryTable& static_entries_;
-  DynamicEntryTable dynamic_entries_;
-
-  // Tracks the index of the unique HpackEntry for a given header name and
-  // value.  Keys consist of string_views that point to strings stored in
-  // |static_entries_|.
-  const NameValueToEntryMap& static_index_;
-
-  // Tracks the index of the first static entry for each name in the static
-  // table.  Each key is a string_view that points to a name string stored in
-  // |static_entries_|.
-  const NameToEntryMap& static_name_index_;
-
-  // Tracks the index of the most recently inserted HpackEntry for a given
-  // header name and value.  Keys consist of string_views that point to strings
-  // stored in |dynamic_entries_|.
-  NameValueToEntryMap dynamic_index_;
-
-  // Tracks the index of the most recently inserted HpackEntry for a given
-  // header name.  Each key is a string_view that points to a name string stored
-  // in |dynamic_entries_|.
-  NameToEntryMap dynamic_name_index_;
-
-  // Last acknowledged value for SETTINGS_HEADER_TABLE_SIZE.
-  size_t settings_size_bound_;
-
-  // Estimated current and maximum byte size of the table.
-  // |max_size_| <= |settings_size_bound_|
-  size_t size_;
-  size_t max_size_;
-
-  // Total number of dynamic table insertions so far
-  // (including entries that have been evicted).
-  size_t dynamic_table_insertions_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
diff --git a/spdy/core/hpack/hpack_header_table_test.cc b/spdy/core/hpack/hpack_header_table_test.cc
deleted file mode 100644
index 23b5516..0000000
--- a/spdy/core/hpack/hpack_header_table_test.cc
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_header_table.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_entry.h"
-#include "spdy/core/hpack/hpack_static_table.h"
-
-namespace spdy {
-
-using std::distance;
-
-namespace test {
-
-class HpackHeaderTablePeer {
- public:
-  explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {}
-
-  const HpackHeaderTable::DynamicEntryTable& dynamic_entries() {
-    return table_->dynamic_entries_;
-  }
-  const HpackHeaderTable::StaticEntryTable& static_entries() {
-    return table_->static_entries_;
-  }
-  const HpackEntry* GetFirstStaticEntry() {
-    return &table_->static_entries_.front();
-  }
-  const HpackEntry* GetLastStaticEntry() {
-    return &table_->static_entries_.back();
-  }
-  std::vector<HpackEntry*> EvictionSet(absl::string_view name,
-                                       absl::string_view value) {
-    HpackHeaderTable::DynamicEntryTable::iterator begin, end;
-    table_->EvictionSet(name, value, &begin, &end);
-    std::vector<HpackEntry*> result;
-    for (; begin != end; ++begin) {
-      result.push_back(&(*begin));
-    }
-    return result;
-  }
-  size_t dynamic_table_insertions() {
-    return table_->dynamic_table_insertions_;
-  }
-  size_t EvictionCountForEntry(absl::string_view name,
-                               absl::string_view value) {
-    return table_->EvictionCountForEntry(name, value);
-  }
-  size_t EvictionCountToReclaim(size_t reclaim_size) {
-    return table_->EvictionCountToReclaim(reclaim_size);
-  }
-  void Evict(size_t count) { return table_->Evict(count); }
-
- private:
-  HpackHeaderTable* table_;
-};
-
-}  // namespace test
-
-namespace {
-
-class HpackHeaderTableTest : public QuicheTest {
- protected:
-  typedef std::vector<HpackEntry> HpackEntryVector;
-
-  HpackHeaderTableTest() : table_(), peer_(&table_) {}
-
-  // Returns an entry whose Size() is equal to the given one.
-  static HpackEntry MakeEntryOfSize(uint32_t size) {
-    EXPECT_GE(size, kHpackEntrySizeOverhead);
-    std::string name((size - kHpackEntrySizeOverhead) / 2, 'n');
-    std::string value(size - kHpackEntrySizeOverhead - name.size(), 'v');
-    HpackEntry entry(name, value);
-    EXPECT_EQ(size, entry.Size());
-    return entry;
-  }
-
-  // Returns a vector of entries whose total size is equal to the given
-  // one.
-  static HpackEntryVector MakeEntriesOfTotalSize(uint32_t total_size) {
-    EXPECT_GE(total_size, kHpackEntrySizeOverhead);
-    uint32_t entry_size = kHpackEntrySizeOverhead;
-    uint32_t remaining_size = total_size;
-    HpackEntryVector entries;
-    while (remaining_size > 0) {
-      EXPECT_LE(entry_size, remaining_size);
-      entries.push_back(MakeEntryOfSize(entry_size));
-      remaining_size -= entry_size;
-      entry_size = std::min(remaining_size, entry_size + 32);
-    }
-    return entries;
-  }
-
-  // Adds the given vector of entries to the given header table,
-  // expecting no eviction to happen.
-  void AddEntriesExpectNoEviction(const HpackEntryVector& entries) {
-    for (auto it = entries.begin(); it != entries.end(); ++it) {
-      HpackHeaderTable::DynamicEntryTable::iterator begin, end;
-
-      table_.EvictionSet(it->name(), it->value(), &begin, &end);
-      EXPECT_EQ(0, distance(begin, end));
-
-      const HpackEntry* entry = table_.TryAddEntry(it->name(), it->value());
-      EXPECT_NE(entry, static_cast<HpackEntry*>(nullptr));
-    }
-  }
-
-  HpackHeaderTable table_;
-  test::HpackHeaderTablePeer peer_;
-};
-
-TEST_F(HpackHeaderTableTest, StaticTableInitialization) {
-  EXPECT_EQ(0u, table_.size());
-  EXPECT_EQ(kDefaultHeaderTableSizeSetting, table_.max_size());
-  EXPECT_EQ(kDefaultHeaderTableSizeSetting, table_.settings_size_bound());
-
-  EXPECT_EQ(0u, peer_.dynamic_entries().size());
-  EXPECT_EQ(0u, peer_.dynamic_table_insertions());
-
-  // Static entries have been populated and inserted into the table & index.
-  const HpackHeaderTable::StaticEntryTable& static_entries =
-      peer_.static_entries();
-  EXPECT_EQ(kStaticTableSize, static_entries.size());
-  // HPACK indexing scheme is 1-based.
-  size_t index = 1;
-  for (const HpackEntry& entry : static_entries) {
-    EXPECT_EQ(index, table_.GetByNameAndValue(entry.name(), entry.value()));
-    index++;
-  }
-}
-
-TEST_F(HpackHeaderTableTest, BasicDynamicEntryInsertionAndEviction) {
-  EXPECT_EQ(kStaticTableSize, peer_.static_entries().size());
-
-  const HpackEntry* first_static_entry = peer_.GetFirstStaticEntry();
-  const HpackEntry* last_static_entry = peer_.GetLastStaticEntry();
-
-  const HpackEntry* entry = table_.TryAddEntry("header-key", "Header Value");
-  EXPECT_EQ("header-key", entry->name());
-  EXPECT_EQ("Header Value", entry->value());
-
-  // Table counts were updated appropriately.
-  EXPECT_EQ(entry->Size(), table_.size());
-  EXPECT_EQ(1u, peer_.dynamic_entries().size());
-  EXPECT_EQ(kStaticTableSize, peer_.static_entries().size());
-
-  EXPECT_EQ(62u, table_.GetByNameAndValue("header-key", "Header Value"));
-
-  // Index of static entries does not change.
-  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
-  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
-
-  // Evict |entry|. Table counts are again updated appropriately.
-  peer_.Evict(1);
-  EXPECT_EQ(0u, table_.size());
-  EXPECT_EQ(0u, peer_.dynamic_entries().size());
-  EXPECT_EQ(kStaticTableSize, peer_.static_entries().size());
-
-  // Index of static entries does not change.
-  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
-  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
-}
-
-TEST_F(HpackHeaderTableTest, EntryIndexing) {
-  const HpackEntry* first_static_entry = peer_.GetFirstStaticEntry();
-  const HpackEntry* last_static_entry = peer_.GetLastStaticEntry();
-
-  // Static entries are queryable by name & value.
-  EXPECT_EQ(1u, table_.GetByName(first_static_entry->name()));
-  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
-                                         first_static_entry->value()));
-
-  // Create a mix of entries which duplicate names, and names & values of both
-  // dynamic and static entries.
-  table_.TryAddEntry(first_static_entry->name(), first_static_entry->value());
-  table_.TryAddEntry(first_static_entry->name(), "Value Four");
-  table_.TryAddEntry("key-1", "Value One");
-  table_.TryAddEntry("key-2", "Value Three");
-  table_.TryAddEntry("key-1", "Value Two");
-  table_.TryAddEntry("key-2", "Value Three");
-  table_.TryAddEntry("key-2", "Value Four");
-
-  // The following entry is identical to the one at index 68.  The smaller index
-  // is returned by GetByNameAndValue().
-  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
-                                         first_static_entry->value()));
-  EXPECT_EQ(67u,
-            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
-  EXPECT_EQ(66u, table_.GetByNameAndValue("key-1", "Value One"));
-  EXPECT_EQ(64u, table_.GetByNameAndValue("key-1", "Value Two"));
-  // The following entry is identical to the one at index 65.  The smaller index
-  // is returned by GetByNameAndValue().
-  EXPECT_EQ(63u, table_.GetByNameAndValue("key-2", "Value Three"));
-  EXPECT_EQ(62u, table_.GetByNameAndValue("key-2", "Value Four"));
-
-  // Index of static entries does not change.
-  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
-  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
-
-  // Querying by name returns the most recently added matching entry.
-  EXPECT_EQ(64u, table_.GetByName("key-1"));
-  EXPECT_EQ(62u, table_.GetByName("key-2"));
-  EXPECT_EQ(1u, table_.GetByName(first_static_entry->name()));
-  EXPECT_EQ(kHpackEntryNotFound, table_.GetByName("not-present"));
-
-  // Querying by name & value returns the lowest-index matching entry among
-  // static entries, and the highest-index one among dynamic entries.
-  EXPECT_EQ(66u, table_.GetByNameAndValue("key-1", "Value One"));
-  EXPECT_EQ(64u, table_.GetByNameAndValue("key-1", "Value Two"));
-  EXPECT_EQ(63u, table_.GetByNameAndValue("key-2", "Value Three"));
-  EXPECT_EQ(62u, table_.GetByNameAndValue("key-2", "Value Four"));
-  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
-                                         first_static_entry->value()));
-  EXPECT_EQ(67u,
-            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
-  EXPECT_EQ(kHpackEntryNotFound,
-            table_.GetByNameAndValue("key-1", "Not Present"));
-  EXPECT_EQ(kHpackEntryNotFound,
-            table_.GetByNameAndValue("not-present", "Value One"));
-
-  // Evict |entry1|. Queries for its name & value now return the static entry.
-  // |entry2| remains queryable.
-  peer_.Evict(1);
-  EXPECT_EQ(1u, table_.GetByNameAndValue(first_static_entry->name(),
-                                         first_static_entry->value()));
-  EXPECT_EQ(67u,
-            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
-
-  // Evict |entry2|. Queries by its name & value are not found.
-  peer_.Evict(1);
-  EXPECT_EQ(kHpackEntryNotFound,
-            table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
-
-  // Index of static entries does not change.
-  EXPECT_EQ(first_static_entry, peer_.GetFirstStaticEntry());
-  EXPECT_EQ(last_static_entry, peer_.GetLastStaticEntry());
-}
-
-TEST_F(HpackHeaderTableTest, SetSizes) {
-  std::string key = "key", value = "value";
-  const HpackEntry* entry1 = table_.TryAddEntry(key, value);
-  const HpackEntry* entry2 = table_.TryAddEntry(key, value);
-  const HpackEntry* entry3 = table_.TryAddEntry(key, value);
-
-  // Set exactly large enough. No Evictions.
-  size_t max_size = entry1->Size() + entry2->Size() + entry3->Size();
-  table_.SetMaxSize(max_size);
-  EXPECT_EQ(3u, peer_.dynamic_entries().size());
-
-  // Set just too small. One eviction.
-  max_size = entry1->Size() + entry2->Size() + entry3->Size() - 1;
-  table_.SetMaxSize(max_size);
-  EXPECT_EQ(2u, peer_.dynamic_entries().size());
-
-  // Changing SETTINGS_HEADER_TABLE_SIZE.
-  EXPECT_EQ(kDefaultHeaderTableSizeSetting, table_.settings_size_bound());
-  // In production, the size passed to SetSettingsHeaderTableSize is never
-  // larger than table_.settings_size_bound().
-  table_.SetSettingsHeaderTableSize(kDefaultHeaderTableSizeSetting * 3 + 1);
-  EXPECT_EQ(kDefaultHeaderTableSizeSetting * 3 + 1, table_.max_size());
-
-  // SETTINGS_HEADER_TABLE_SIZE upper-bounds |table_.max_size()|,
-  // and will force evictions.
-  max_size = entry3->Size() - 1;
-  table_.SetSettingsHeaderTableSize(max_size);
-  EXPECT_EQ(max_size, table_.max_size());
-  EXPECT_EQ(max_size, table_.settings_size_bound());
-  EXPECT_EQ(0u, peer_.dynamic_entries().size());
-}
-
-TEST_F(HpackHeaderTableTest, EvictionCountForEntry) {
-  std::string key = "key", value = "value";
-  const HpackEntry* entry1 = table_.TryAddEntry(key, value);
-  const HpackEntry* entry2 = table_.TryAddEntry(key, value);
-  size_t entry3_size = HpackEntry::Size(key, value);
-
-  // Just enough capacity for third entry.
-  table_.SetMaxSize(entry1->Size() + entry2->Size() + entry3_size);
-  EXPECT_EQ(0u, peer_.EvictionCountForEntry(key, value));
-  EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value + "x"));
-
-  // No extra capacity. Third entry would force evictions.
-  table_.SetMaxSize(entry1->Size() + entry2->Size());
-  EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value));
-  EXPECT_EQ(2u, peer_.EvictionCountForEntry(key, value + "x"));
-}
-
-TEST_F(HpackHeaderTableTest, EvictionCountToReclaim) {
-  std::string key = "key", value = "value";
-  const HpackEntry* entry1 = table_.TryAddEntry(key, value);
-  const HpackEntry* entry2 = table_.TryAddEntry(key, value);
-
-  EXPECT_EQ(1u, peer_.EvictionCountToReclaim(1));
-  EXPECT_EQ(1u, peer_.EvictionCountToReclaim(entry1->Size()));
-  EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + 1));
-  EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + entry2->Size()));
-}
-
-// Fill a header table with entries. Make sure the entries are in
-// reverse order in the header table.
-TEST_F(HpackHeaderTableTest, TryAddEntryBasic) {
-  EXPECT_EQ(0u, table_.size());
-  EXPECT_EQ(table_.settings_size_bound(), table_.max_size());
-
-  HpackEntryVector entries = MakeEntriesOfTotalSize(table_.max_size());
-
-  // Most of the checks are in AddEntriesExpectNoEviction().
-  AddEntriesExpectNoEviction(entries);
-  EXPECT_EQ(table_.max_size(), table_.size());
-  EXPECT_EQ(table_.settings_size_bound(), table_.size());
-}
-
-// Fill a header table with entries, and then ramp the table's max
-// size down to evict an entry one at a time. Make sure the eviction
-// happens as expected.
-TEST_F(HpackHeaderTableTest, SetMaxSize) {
-  HpackEntryVector entries =
-      MakeEntriesOfTotalSize(kDefaultHeaderTableSizeSetting / 2);
-  AddEntriesExpectNoEviction(entries);
-
-  for (auto it = entries.begin(); it != entries.end(); ++it) {
-    size_t expected_count = distance(it, entries.end());
-    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
-
-    table_.SetMaxSize(table_.size() + 1);
-    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
-
-    table_.SetMaxSize(table_.size());
-    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
-
-    --expected_count;
-    table_.SetMaxSize(table_.size() - 1);
-    EXPECT_EQ(expected_count, peer_.dynamic_entries().size());
-  }
-  EXPECT_EQ(0u, table_.size());
-}
-
-// Fill a header table with entries, and then add an entry just big
-// enough to cause eviction of all but one entry. Make sure the
-// eviction happens as expected and the long entry is inserted into
-// the table.
-TEST_F(HpackHeaderTableTest, TryAddEntryEviction) {
-  HpackEntryVector entries = MakeEntriesOfTotalSize(table_.max_size());
-  AddEntriesExpectNoEviction(entries);
-
-  // The first entry in the dynamic table.
-  const HpackEntry* survivor_entry = &peer_.dynamic_entries().front();
-
-  HpackEntry long_entry =
-      MakeEntryOfSize(table_.max_size() - survivor_entry->Size());
-
-  // All dynamic entries but the first are to be evicted.
-  EXPECT_EQ(peer_.dynamic_entries().size() - 1,
-            peer_.EvictionSet(long_entry.name(), long_entry.value()).size());
-
-  table_.TryAddEntry(long_entry.name(), long_entry.value());
-  EXPECT_EQ(2u, peer_.dynamic_entries().size());
-  EXPECT_EQ(63u, table_.GetByNameAndValue(survivor_entry->name(),
-                                          survivor_entry->value()));
-  EXPECT_EQ(62u,
-            table_.GetByNameAndValue(long_entry.name(), long_entry.value()));
-}
-
-// Fill a header table with entries, and then add an entry bigger than
-// the entire table. Make sure no entry remains in the table.
-TEST_F(HpackHeaderTableTest, TryAddTooLargeEntry) {
-  HpackEntryVector entries = MakeEntriesOfTotalSize(table_.max_size());
-  AddEntriesExpectNoEviction(entries);
-
-  const HpackEntry long_entry = MakeEntryOfSize(table_.max_size() + 1);
-
-  // All entries are to be evicted.
-  EXPECT_EQ(peer_.dynamic_entries().size(),
-            peer_.EvictionSet(long_entry.name(), long_entry.value()).size());
-
-  const HpackEntry* new_entry =
-      table_.TryAddEntry(long_entry.name(), long_entry.value());
-  EXPECT_EQ(new_entry, static_cast<HpackEntry*>(nullptr));
-  EXPECT_EQ(0u, peer_.dynamic_entries().size());
-}
-
-}  // namespace
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_output_stream.cc b/spdy/core/hpack/hpack_output_stream.cc
deleted file mode 100644
index 291ad3d..0000000
--- a/spdy/core/hpack/hpack_output_stream.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_output_stream.h"
-
-#include <utility>
-
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-
-HpackOutputStream::HpackOutputStream() : bit_offset_(0) {}
-
-HpackOutputStream::~HpackOutputStream() = default;
-
-void HpackOutputStream::AppendBits(uint8_t bits, size_t bit_size) {
-  QUICHE_DCHECK_GT(bit_size, 0u);
-  QUICHE_DCHECK_LE(bit_size, 8u);
-  QUICHE_DCHECK_EQ(bits >> bit_size, 0);
-  size_t new_bit_offset = bit_offset_ + bit_size;
-  if (bit_offset_ == 0) {
-    // Buffer ends on a byte boundary.
-    QUICHE_DCHECK_LE(bit_size, 8u);
-    buffer_.append(1, bits << (8 - bit_size));
-  } else if (new_bit_offset <= 8) {
-    // Buffer does not end on a byte boundary but the given bits fit
-    // in the remainder of the last byte.
-    buffer_.back() |= bits << (8 - new_bit_offset);
-  } else {
-    // Buffer does not end on a byte boundary and the given bits do
-    // not fit in the remainder of the last byte.
-    buffer_.back() |= bits >> (new_bit_offset - 8);
-    buffer_.append(1, bits << (16 - new_bit_offset));
-  }
-  bit_offset_ = new_bit_offset % 8;
-}
-
-void HpackOutputStream::AppendPrefix(HpackPrefix prefix) {
-  AppendBits(prefix.bits, prefix.bit_size);
-}
-
-void HpackOutputStream::AppendBytes(absl::string_view buffer) {
-  QUICHE_DCHECK_EQ(bit_offset_, 0u);
-  buffer_.append(buffer.data(), buffer.size());
-}
-
-void HpackOutputStream::AppendUint32(uint32_t I) {
-  // The algorithm below is adapted from the pseudocode in 6.1.
-  size_t N = 8 - bit_offset_;
-  uint8_t max_first_byte = static_cast<uint8_t>((1 << N) - 1);
-  if (I < max_first_byte) {
-    AppendBits(static_cast<uint8_t>(I), N);
-  } else {
-    AppendBits(max_first_byte, N);
-    I -= max_first_byte;
-    while ((I & ~0x7f) != 0) {
-      buffer_.append(1, (I & 0x7f) | 0x80);
-      I >>= 7;
-    }
-    AppendBits(static_cast<uint8_t>(I), 8);
-  }
-  QUICHE_DCHECK_EQ(bit_offset_, 0u);
-}
-
-std::string* HpackOutputStream::MutableString() {
-  QUICHE_DCHECK_EQ(bit_offset_, 0u);
-  return &buffer_;
-}
-
-std::string HpackOutputStream::TakeString() {
-  // This must hold, since all public functions cause the buffer to
-  // end on a byte boundary.
-  QUICHE_DCHECK_EQ(bit_offset_, 0u);
-  std::string out = std::move(buffer_);
-  buffer_ = {};
-  bit_offset_ = 0;
-  return out;
-}
-
-std::string HpackOutputStream::BoundedTakeString(size_t max_size) {
-  if (buffer_.size() > max_size) {
-    // Save off overflow bytes to temporary string (causes a copy).
-    std::string overflow = buffer_.substr(max_size);
-
-    // Resize buffer down to the given limit.
-    buffer_.resize(max_size);
-
-    // Give buffer to output string.
-    std::string out = std::move(buffer_);
-
-    // Reset to contain overflow.
-    buffer_ = std::move(overflow);
-    return out;
-  } else {
-    return TakeString();
-  }
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_output_stream.h b/spdy/core/hpack/hpack_output_stream.h
deleted file mode 100644
index ade1cd1..0000000
--- a/spdy/core/hpack/hpack_output_stream.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
-
-#include <cstdint>
-#include <map>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_constants.h"
-
-// All section references below are to
-// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08
-
-namespace spdy {
-
-// An HpackOutputStream handles all the low-level details of encoding
-// header fields.
-class QUICHE_EXPORT_PRIVATE HpackOutputStream {
- public:
-  HpackOutputStream();
-  HpackOutputStream(const HpackOutputStream&) = delete;
-  HpackOutputStream& operator=(const HpackOutputStream&) = delete;
-  ~HpackOutputStream();
-
-  // Appends the lower |bit_size| bits of |bits| to the internal buffer.
-  //
-  // |bit_size| must be > 0 and <= 8. |bits| must not have any bits
-  // set other than the lower |bit_size| bits.
-  void AppendBits(uint8_t bits, size_t bit_size);
-
-  // Simply forwards to AppendBits(prefix.bits, prefix.bit-size).
-  void AppendPrefix(HpackPrefix prefix);
-
-  // Directly appends |buffer|.
-  void AppendBytes(absl::string_view buffer);
-
-  // Appends the given integer using the representation described in
-  // 6.1. If the internal buffer ends on a byte boundary, the prefix
-  // length N is taken to be 8; otherwise, it is taken to be the
-  // number of bits to the next byte boundary.
-  //
-  // It is guaranteed that the internal buffer will end on a byte
-  // boundary after this function is called.
-  void AppendUint32(uint32_t I);
-
-  // Return pointer to internal buffer.  |bit_offset_| needs to be zero.
-  std::string* MutableString();
-
-  // Returns the internal buffer as a string, then resets state.
-  std::string TakeString();
-
-  // Returns up to |max_size| bytes of the internal buffer. Resets
-  // internal state with the overflow.
-  std::string BoundedTakeString(size_t max_size);
-
-  // Size in bytes of stream's internal buffer.
-  size_t size() const { return buffer_.size(); }
-
- private:
-  // The internal bit buffer.
-  std::string buffer_;
-
-  // If 0, the buffer ends on a byte boundary. If non-zero, the buffer
-  // ends on the nth most significant bit. Guaranteed to be < 8.
-  size_t bit_offset_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
diff --git a/spdy/core/hpack/hpack_output_stream_test.cc b/spdy/core/hpack/hpack_output_stream_test.cc
deleted file mode 100644
index 3d8c35d..0000000
--- a/spdy/core/hpack/hpack_output_stream_test.cc
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_output_stream.h"
-
-#include <cstddef>
-
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-
-namespace {
-
-// Make sure that AppendBits() appends bits starting from the most
-// significant bit, and that it can handle crossing a byte boundary.
-TEST(HpackOutputStreamTest, AppendBits) {
-  HpackOutputStream output_stream;
-  std::string expected_str;
-
-  output_stream.AppendBits(0x1, 1);
-  expected_str.append(1, 0x00);
-  expected_str.back() |= (0x1 << 7);
-
-  output_stream.AppendBits(0x0, 1);
-
-  output_stream.AppendBits(0x3, 2);
-  *expected_str.rbegin() |= (0x3 << 4);
-
-  output_stream.AppendBits(0x0, 2);
-
-  // Byte-crossing append.
-  output_stream.AppendBits(0x7, 3);
-  *expected_str.rbegin() |= (0x7 >> 1);
-  expected_str.append(1, 0x00);
-  expected_str.back() |= (0x7 << 7);
-
-  output_stream.AppendBits(0x0, 7);
-
-  std::string str = output_stream.TakeString();
-  EXPECT_EQ(expected_str, str);
-}
-
-// Utility function to return I as a string encoded with an N-bit
-// prefix.
-std::string EncodeUint32(uint8_t N, uint32_t I) {
-  HpackOutputStream output_stream;
-  if (N < 8) {
-    output_stream.AppendBits(0x00, 8 - N);
-  }
-  output_stream.AppendUint32(I);
-  std::string str = output_stream.TakeString();
-  return str;
-}
-
-// The {Number}ByteIntegersEightBitPrefix tests below test that
-// certain integers are encoded correctly with an 8-bit prefix in
-// exactly {Number} bytes.
-
-TEST(HpackOutputStreamTest, OneByteIntegersEightBitPrefix) {
-  // Minimum.
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(8, 0x00));
-  EXPECT_EQ("\x7f", EncodeUint32(8, 0x7f));
-  // Maximum.
-  EXPECT_EQ("\xfe", EncodeUint32(8, 0xfe));
-}
-
-TEST(HpackOutputStreamTest, TwoByteIntegersEightBitPrefix) {
-  // Minimum.
-  EXPECT_EQ(std::string("\xff\x00", 2), EncodeUint32(8, 0xff));
-  EXPECT_EQ("\xff\x01", EncodeUint32(8, 0x0100));
-  // Maximum.
-  EXPECT_EQ("\xff\x7f", EncodeUint32(8, 0x017e));
-}
-
-TEST(HpackOutputStreamTest, ThreeByteIntegersEightBitPrefix) {
-  // Minimum.
-  EXPECT_EQ("\xff\x80\x01", EncodeUint32(8, 0x017f));
-  EXPECT_EQ("\xff\x80\x1e", EncodeUint32(8, 0x0fff));
-  // Maximum.
-  EXPECT_EQ("\xff\xff\x7f", EncodeUint32(8, 0x40fe));
-}
-
-TEST(HpackOutputStreamTest, FourByteIntegersEightBitPrefix) {
-  // Minimum.
-  EXPECT_EQ("\xff\x80\x80\x01", EncodeUint32(8, 0x40ff));
-  EXPECT_EQ("\xff\x80\xfe\x03", EncodeUint32(8, 0xffff));
-  // Maximum.
-  EXPECT_EQ("\xff\xff\xff\x7f", EncodeUint32(8, 0x002000fe));
-}
-
-TEST(HpackOutputStreamTest, FiveByteIntegersEightBitPrefix) {
-  // Minimum.
-  EXPECT_EQ("\xff\x80\x80\x80\x01", EncodeUint32(8, 0x002000ff));
-  EXPECT_EQ("\xff\x80\xfe\xff\x07", EncodeUint32(8, 0x00ffffff));
-  // Maximum.
-  EXPECT_EQ("\xff\xff\xff\xff\x7f", EncodeUint32(8, 0x100000fe));
-}
-
-TEST(HpackOutputStreamTest, SixByteIntegersEightBitPrefix) {
-  // Minimum.
-  EXPECT_EQ("\xff\x80\x80\x80\x80\x01", EncodeUint32(8, 0x100000ff));
-  // Maximum.
-  EXPECT_EQ("\xff\x80\xfe\xff\xff\x0f", EncodeUint32(8, 0xffffffff));
-}
-
-// The {Number}ByteIntegersOneToSevenBitPrefix tests below test that
-// certain integers are encoded correctly with an N-bit prefix in
-// exactly {Number} bytes for N in {1, 2, ..., 7}.
-
-TEST(HpackOutputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
-  // Minimums.
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(7, 0x00));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(6, 0x00));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(5, 0x00));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(4, 0x00));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(3, 0x00));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(2, 0x00));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(1, 0x00));
-
-  // Maximums.
-  EXPECT_EQ("\x7e", EncodeUint32(7, 0x7e));
-  EXPECT_EQ("\x3e", EncodeUint32(6, 0x3e));
-  EXPECT_EQ("\x1e", EncodeUint32(5, 0x1e));
-  EXPECT_EQ("\x0e", EncodeUint32(4, 0x0e));
-  EXPECT_EQ("\x06", EncodeUint32(3, 0x06));
-  EXPECT_EQ("\x02", EncodeUint32(2, 0x02));
-  EXPECT_EQ(std::string("\x00", 1), EncodeUint32(1, 0x00));
-}
-
-TEST(HpackOutputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
-  // Minimums.
-  EXPECT_EQ(std::string("\x7f\x00", 2), EncodeUint32(7, 0x7f));
-  EXPECT_EQ(std::string("\x3f\x00", 2), EncodeUint32(6, 0x3f));
-  EXPECT_EQ(std::string("\x1f\x00", 2), EncodeUint32(5, 0x1f));
-  EXPECT_EQ(std::string("\x0f\x00", 2), EncodeUint32(4, 0x0f));
-  EXPECT_EQ(std::string("\x07\x00", 2), EncodeUint32(3, 0x07));
-  EXPECT_EQ(std::string("\x03\x00", 2), EncodeUint32(2, 0x03));
-  EXPECT_EQ(std::string("\x01\x00", 2), EncodeUint32(1, 0x01));
-
-  // Maximums.
-  EXPECT_EQ("\x7f\x7f", EncodeUint32(7, 0xfe));
-  EXPECT_EQ("\x3f\x7f", EncodeUint32(6, 0xbe));
-  EXPECT_EQ("\x1f\x7f", EncodeUint32(5, 0x9e));
-  EXPECT_EQ("\x0f\x7f", EncodeUint32(4, 0x8e));
-  EXPECT_EQ("\x07\x7f", EncodeUint32(3, 0x86));
-  EXPECT_EQ("\x03\x7f", EncodeUint32(2, 0x82));
-  EXPECT_EQ("\x01\x7f", EncodeUint32(1, 0x80));
-}
-
-TEST(HpackOutputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
-  // Minimums.
-  EXPECT_EQ("\x7f\x80\x01", EncodeUint32(7, 0xff));
-  EXPECT_EQ("\x3f\x80\x01", EncodeUint32(6, 0xbf));
-  EXPECT_EQ("\x1f\x80\x01", EncodeUint32(5, 0x9f));
-  EXPECT_EQ("\x0f\x80\x01", EncodeUint32(4, 0x8f));
-  EXPECT_EQ("\x07\x80\x01", EncodeUint32(3, 0x87));
-  EXPECT_EQ("\x03\x80\x01", EncodeUint32(2, 0x83));
-  EXPECT_EQ("\x01\x80\x01", EncodeUint32(1, 0x81));
-
-  // Maximums.
-  EXPECT_EQ("\x7f\xff\x7f", EncodeUint32(7, 0x407e));
-  EXPECT_EQ("\x3f\xff\x7f", EncodeUint32(6, 0x403e));
-  EXPECT_EQ("\x1f\xff\x7f", EncodeUint32(5, 0x401e));
-  EXPECT_EQ("\x0f\xff\x7f", EncodeUint32(4, 0x400e));
-  EXPECT_EQ("\x07\xff\x7f", EncodeUint32(3, 0x4006));
-  EXPECT_EQ("\x03\xff\x7f", EncodeUint32(2, 0x4002));
-  EXPECT_EQ("\x01\xff\x7f", EncodeUint32(1, 0x4000));
-}
-
-TEST(HpackOutputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
-  // Minimums.
-  EXPECT_EQ("\x7f\x80\x80\x01", EncodeUint32(7, 0x407f));
-  EXPECT_EQ("\x3f\x80\x80\x01", EncodeUint32(6, 0x403f));
-  EXPECT_EQ("\x1f\x80\x80\x01", EncodeUint32(5, 0x401f));
-  EXPECT_EQ("\x0f\x80\x80\x01", EncodeUint32(4, 0x400f));
-  EXPECT_EQ("\x07\x80\x80\x01", EncodeUint32(3, 0x4007));
-  EXPECT_EQ("\x03\x80\x80\x01", EncodeUint32(2, 0x4003));
-  EXPECT_EQ("\x01\x80\x80\x01", EncodeUint32(1, 0x4001));
-
-  // Maximums.
-  EXPECT_EQ("\x7f\xff\xff\x7f", EncodeUint32(7, 0x20007e));
-  EXPECT_EQ("\x3f\xff\xff\x7f", EncodeUint32(6, 0x20003e));
-  EXPECT_EQ("\x1f\xff\xff\x7f", EncodeUint32(5, 0x20001e));
-  EXPECT_EQ("\x0f\xff\xff\x7f", EncodeUint32(4, 0x20000e));
-  EXPECT_EQ("\x07\xff\xff\x7f", EncodeUint32(3, 0x200006));
-  EXPECT_EQ("\x03\xff\xff\x7f", EncodeUint32(2, 0x200002));
-  EXPECT_EQ("\x01\xff\xff\x7f", EncodeUint32(1, 0x200000));
-}
-
-TEST(HpackOutputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
-  // Minimums.
-  EXPECT_EQ("\x7f\x80\x80\x80\x01", EncodeUint32(7, 0x20007f));
-  EXPECT_EQ("\x3f\x80\x80\x80\x01", EncodeUint32(6, 0x20003f));
-  EXPECT_EQ("\x1f\x80\x80\x80\x01", EncodeUint32(5, 0x20001f));
-  EXPECT_EQ("\x0f\x80\x80\x80\x01", EncodeUint32(4, 0x20000f));
-  EXPECT_EQ("\x07\x80\x80\x80\x01", EncodeUint32(3, 0x200007));
-  EXPECT_EQ("\x03\x80\x80\x80\x01", EncodeUint32(2, 0x200003));
-  EXPECT_EQ("\x01\x80\x80\x80\x01", EncodeUint32(1, 0x200001));
-
-  // Maximums.
-  EXPECT_EQ("\x7f\xff\xff\xff\x7f", EncodeUint32(7, 0x1000007e));
-  EXPECT_EQ("\x3f\xff\xff\xff\x7f", EncodeUint32(6, 0x1000003e));
-  EXPECT_EQ("\x1f\xff\xff\xff\x7f", EncodeUint32(5, 0x1000001e));
-  EXPECT_EQ("\x0f\xff\xff\xff\x7f", EncodeUint32(4, 0x1000000e));
-  EXPECT_EQ("\x07\xff\xff\xff\x7f", EncodeUint32(3, 0x10000006));
-  EXPECT_EQ("\x03\xff\xff\xff\x7f", EncodeUint32(2, 0x10000002));
-  EXPECT_EQ("\x01\xff\xff\xff\x7f", EncodeUint32(1, 0x10000000));
-}
-
-TEST(HpackOutputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
-  // Minimums.
-  EXPECT_EQ("\x7f\x80\x80\x80\x80\x01", EncodeUint32(7, 0x1000007f));
-  EXPECT_EQ("\x3f\x80\x80\x80\x80\x01", EncodeUint32(6, 0x1000003f));
-  EXPECT_EQ("\x1f\x80\x80\x80\x80\x01", EncodeUint32(5, 0x1000001f));
-  EXPECT_EQ("\x0f\x80\x80\x80\x80\x01", EncodeUint32(4, 0x1000000f));
-  EXPECT_EQ("\x07\x80\x80\x80\x80\x01", EncodeUint32(3, 0x10000007));
-  EXPECT_EQ("\x03\x80\x80\x80\x80\x01", EncodeUint32(2, 0x10000003));
-  EXPECT_EQ("\x01\x80\x80\x80\x80\x01", EncodeUint32(1, 0x10000001));
-
-  // Maximums.
-  EXPECT_EQ("\x7f\x80\xff\xff\xff\x0f", EncodeUint32(7, 0xffffffff));
-  EXPECT_EQ("\x3f\xc0\xff\xff\xff\x0f", EncodeUint32(6, 0xffffffff));
-  EXPECT_EQ("\x1f\xe0\xff\xff\xff\x0f", EncodeUint32(5, 0xffffffff));
-  EXPECT_EQ("\x0f\xf0\xff\xff\xff\x0f", EncodeUint32(4, 0xffffffff));
-  EXPECT_EQ("\x07\xf8\xff\xff\xff\x0f", EncodeUint32(3, 0xffffffff));
-  EXPECT_EQ("\x03\xfc\xff\xff\xff\x0f", EncodeUint32(2, 0xffffffff));
-  EXPECT_EQ("\x01\xfe\xff\xff\xff\x0f", EncodeUint32(1, 0xffffffff));
-}
-
-// Test that encoding an integer with an N-bit prefix preserves the
-// upper (8-N) bits of the first byte.
-TEST(HpackOutputStreamTest, AppendUint32PreservesUpperBits) {
-  HpackOutputStream output_stream;
-  output_stream.AppendBits(0x7f, 7);
-  output_stream.AppendUint32(0x01);
-  std::string str = output_stream.TakeString();
-  EXPECT_EQ(std::string("\xff\x00", 2), str);
-}
-
-TEST(HpackOutputStreamTest, AppendBytes) {
-  HpackOutputStream output_stream;
-
-  output_stream.AppendBytes("buffer1");
-  output_stream.AppendBytes("buffer2");
-
-  std::string str = output_stream.TakeString();
-  EXPECT_EQ("buffer1buffer2", str);
-}
-
-TEST(HpackOutputStreamTest, BoundedTakeString) {
-  HpackOutputStream output_stream;
-
-  output_stream.AppendBytes("buffer12");
-  output_stream.AppendBytes("buffer456");
-
-  std::string str = output_stream.BoundedTakeString(9);
-  EXPECT_EQ("buffer12b", str);
-
-  output_stream.AppendBits(0x7f, 7);
-  output_stream.AppendUint32(0x11);
-  str = output_stream.BoundedTakeString(9);
-  EXPECT_EQ("uffer456\xff", str);
-
-  str = output_stream.BoundedTakeString(9);
-  EXPECT_EQ("\x10", str);
-}
-
-TEST(HpackOutputStreamTest, MutableString) {
-  HpackOutputStream output_stream;
-
-  output_stream.AppendBytes("1");
-  output_stream.MutableString()->append("2");
-
-  output_stream.AppendBytes("foo");
-  output_stream.MutableString()->append("bar");
-
-  std::string str = output_stream.TakeString();
-  EXPECT_EQ("12foobar", str);
-}
-
-}  // namespace
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_round_trip_test.cc b/spdy/core/hpack/hpack_round_trip_test.cc
deleted file mode 100644
index 42a4f2e..0000000
--- a/spdy/core/hpack/hpack_round_trip_test.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cmath>
-#include <cstdint>
-#include <ctime>
-#include <vector>
-
-#include "http2/test_tools/http2_random.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_decoder_adapter.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-#include "spdy/core/spdy_test_utils.h"
-
-namespace spdy {
-namespace test {
-
-namespace {
-
-// Supports testing with the input split at every byte boundary.
-enum InputSizeParam { ALL_INPUT, ONE_BYTE, ZERO_THEN_ONE_BYTE };
-
-class HpackRoundTripTest : public QuicheTestWithParam<InputSizeParam> {
- protected:
-  void SetUp() override {
-    // Use a small table size to tickle eviction handling.
-    encoder_.ApplyHeaderTableSizeSetting(256);
-    decoder_.ApplyHeaderTableSizeSetting(256);
-  }
-
-  bool RoundTrip(const SpdyHeaderBlock& header_set) {
-    std::string encoded = encoder_.EncodeHeaderBlock(header_set);
-
-    bool success = true;
-    if (GetParam() == ALL_INPUT) {
-      // Pass all the input to the decoder at once.
-      success = decoder_.HandleControlFrameHeadersData(encoded.data(),
-                                                       encoded.size());
-    } else if (GetParam() == ONE_BYTE) {
-      // Pass the input to the decoder one byte at a time.
-      const char* data = encoded.data();
-      for (size_t ndx = 0; ndx < encoded.size() && success; ++ndx) {
-        success = decoder_.HandleControlFrameHeadersData(data + ndx, 1);
-      }
-    } else if (GetParam() == ZERO_THEN_ONE_BYTE) {
-      // Pass the input to the decoder one byte at a time, but before each
-      // byte pass an empty buffer.
-      const char* data = encoded.data();
-      for (size_t ndx = 0; ndx < encoded.size() && success; ++ndx) {
-        success = (decoder_.HandleControlFrameHeadersData(data + ndx, 0) &&
-                   decoder_.HandleControlFrameHeadersData(data + ndx, 1));
-      }
-    } else {
-      ADD_FAILURE() << "Unknown param: " << GetParam();
-    }
-
-    if (success) {
-      success = decoder_.HandleControlFrameHeadersComplete();
-    }
-
-    EXPECT_EQ(header_set, decoder_.decoded_block());
-    return success;
-  }
-
-  size_t SampleExponential(size_t mean, size_t sanity_bound) {
-    return std::min<size_t>(-std::log(random_.RandDouble()) * mean,
-                            sanity_bound);
-  }
-
-  http2::test::Http2Random random_;
-  HpackEncoder encoder_;
-  HpackDecoderAdapter decoder_;
-};
-
-INSTANTIATE_TEST_SUITE_P(Tests,
-                         HpackRoundTripTest,
-                         ::testing::Values(ALL_INPUT,
-                                           ONE_BYTE,
-                                           ZERO_THEN_ONE_BYTE));
-
-TEST_P(HpackRoundTripTest, ResponseFixtures) {
-  {
-    SpdyHeaderBlock headers;
-    headers[":status"] = "302";
-    headers["cache-control"] = "private";
-    headers["date"] = "Mon, 21 Oct 2013 20:13:21 GMT";
-    headers["location"] = "https://www.example.com";
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-  {
-    SpdyHeaderBlock headers;
-    headers[":status"] = "200";
-    headers["cache-control"] = "private";
-    headers["date"] = "Mon, 21 Oct 2013 20:13:21 GMT";
-    headers["location"] = "https://www.example.com";
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-  {
-    SpdyHeaderBlock headers;
-    headers[":status"] = "200";
-    headers["cache-control"] = "private";
-    headers["content-encoding"] = "gzip";
-    headers["date"] = "Mon, 21 Oct 2013 20:13:22 GMT";
-    headers["location"] = "https://www.example.com";
-    headers["set-cookie"] =
-        "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU;"
-        " max-age=3600; version=1";
-    headers["multivalue"] = std::string("foo\0bar", 7);
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-}
-
-TEST_P(HpackRoundTripTest, RequestFixtures) {
-  {
-    SpdyHeaderBlock headers;
-    headers[":authority"] = "www.example.com";
-    headers[":method"] = "GET";
-    headers[":path"] = "/";
-    headers[":scheme"] = "http";
-    headers["cookie"] = "baz=bing; foo=bar";
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-  {
-    SpdyHeaderBlock headers;
-    headers[":authority"] = "www.example.com";
-    headers[":method"] = "GET";
-    headers[":path"] = "/";
-    headers[":scheme"] = "http";
-    headers["cache-control"] = "no-cache";
-    headers["cookie"] = "foo=bar; spam=eggs";
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-  {
-    SpdyHeaderBlock headers;
-    headers[":authority"] = "www.example.com";
-    headers[":method"] = "GET";
-    headers[":path"] = "/index.html";
-    headers[":scheme"] = "https";
-    headers["custom-key"] = "custom-value";
-    headers["cookie"] = "baz=bing; fizzle=fazzle; garbage";
-    headers["multivalue"] = std::string("foo\0bar", 7);
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-}
-
-TEST_P(HpackRoundTripTest, RandomizedExamples) {
-  // Grow vectors of names & values, which are seeded with fixtures and then
-  // expanded with dynamically generated data. Samples are taken using the
-  // exponential distribution.
-  std::vector<std::string> pseudo_header_names, random_header_names;
-  pseudo_header_names.push_back(":authority");
-  pseudo_header_names.push_back(":path");
-  pseudo_header_names.push_back(":status");
-
-  // TODO(jgraettinger): Enable "cookie" as a name fixture. Crumbs may be
-  // reconstructed in any order, which breaks the simple validation used here.
-
-  std::vector<std::string> values;
-  values.push_back("/");
-  values.push_back("/index.html");
-  values.push_back("200");
-  values.push_back("404");
-  values.push_back("");
-  values.push_back("baz=bing; foo=bar; garbage");
-  values.push_back("baz=bing; fizzle=fazzle; garbage");
-
-  for (size_t i = 0; i != 2000; ++i) {
-    SpdyHeaderBlock headers;
-
-    // Choose a random number of headers to add, and of these a random subset
-    // will be HTTP/2 pseudo headers.
-    size_t header_count = 1 + SampleExponential(7, 50);
-    size_t pseudo_header_count =
-        std::min(header_count, 1 + SampleExponential(7, 50));
-    EXPECT_LE(pseudo_header_count, header_count);
-    for (size_t j = 0; j != header_count; ++j) {
-      std::string name, value;
-      // Pseudo headers must be added before regular headers.
-      if (j < pseudo_header_count) {
-        // Choose one of the defined pseudo headers at random.
-        size_t name_index = random_.Uniform(pseudo_header_names.size());
-        name = pseudo_header_names[name_index];
-      } else {
-        // Randomly reuse an existing header name, or generate a new one.
-        size_t name_index = SampleExponential(20, 200);
-        if (name_index >= random_header_names.size()) {
-          name = random_.RandString(1 + SampleExponential(5, 30));
-          // A regular header cannot begin with the pseudo header prefix ":".
-          if (name[0] == ':') {
-            name[0] = 'x';
-          }
-          random_header_names.push_back(name);
-        } else {
-          name = random_header_names[name_index];
-        }
-      }
-
-      // Randomly reuse an existing value, or generate a new one.
-      size_t value_index = SampleExponential(20, 200);
-      if (value_index >= values.size()) {
-        std::string newvalue =
-            random_.RandString(1 + SampleExponential(15, 75));
-        // Currently order is not preserved in the encoder.  In particular,
-        // when a value is decomposed at \0 delimiters, its parts might get
-        // encoded out of order if some but not all of them already exist in
-        // the header table.  For now, avoid \0 bytes in values.
-        std::replace(newvalue.begin(), newvalue.end(), '\x00', '\x01');
-        values.push_back(newvalue);
-        value = values.back();
-      } else {
-        value = values[value_index];
-      }
-      headers[name] = value;
-    }
-    EXPECT_TRUE(RoundTrip(headers));
-  }
-}
-
-}  // namespace
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_static_table.cc b/spdy/core/hpack/hpack_static_table.cc
deleted file mode 100644
index e5a403d..0000000
--- a/spdy/core/hpack/hpack_static_table.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_static_table.h"
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/hpack/hpack_constants.h"
-#include "spdy/core/hpack/hpack_entry.h"
-
-namespace spdy {
-
-HpackStaticTable::HpackStaticTable() = default;
-
-HpackStaticTable::~HpackStaticTable() = default;
-
-void HpackStaticTable::Initialize(const HpackStaticEntry* static_entry_table,
-                                  size_t static_entry_count) {
-  QUICHE_CHECK(!IsInitialized());
-
-  static_entries_.reserve(static_entry_count);
-
-  for (const HpackStaticEntry* it = static_entry_table;
-       it != static_entry_table + static_entry_count; ++it) {
-    std::string name(it->name, it->name_len);
-    std::string value(it->value, it->value_len);
-    static_entries_.push_back(HpackEntry(std::move(name), std::move(value)));
-  }
-
-  // |static_entries_| will not be mutated any more.  Therefore its entries will
-  // remain stable even if the container does not have iterator stability.
-  int insertion_count = 0;
-  for (const auto& entry : static_entries_) {
-    auto result = static_index_.insert(std::make_pair(
-        HpackLookupEntry{entry.name(), entry.value()}, insertion_count));
-    QUICHE_CHECK(result.second);
-
-    // Multiple static entries may have the same name, so inserts may fail.
-    static_name_index_.insert(std::make_pair(entry.name(), insertion_count));
-
-    ++insertion_count;
-  }
-}
-
-bool HpackStaticTable::IsInitialized() const {
-  return !static_entries_.empty();
-}
-
-}  // namespace spdy
diff --git a/spdy/core/hpack/hpack_static_table.h b/spdy/core/hpack/hpack_static_table.h
deleted file mode 100644
index 307fc1c..0000000
--- a/spdy/core/hpack/hpack_static_table.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
-#define QUICHE_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
-
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-
-namespace spdy {
-
-struct HpackStaticEntry;
-
-// Number of entries in the HPACK static table.
-constexpr size_t kStaticTableSize = 61;
-
-// HpackStaticTable provides |static_entries_| and |static_index_| for HPACK
-// encoding and decoding contexts.  Once initialized, an instance is read only
-// and may be accessed only through its const interface.  Such an instance may
-// be shared accross multiple HPACK contexts.
-class QUICHE_EXPORT_PRIVATE HpackStaticTable {
- public:
-  HpackStaticTable();
-  ~HpackStaticTable();
-
-  // Prepares HpackStaticTable by filling up static_entries_ and static_index_
-  // from an array of struct HpackStaticEntry.  Must be called exactly once.
-  void Initialize(const HpackStaticEntry* static_entry_table,
-                  size_t static_entry_count);
-
-  // Returns whether Initialize() has been called.
-  bool IsInitialized() const;
-
-  // Accessors.
-  const HpackHeaderTable::StaticEntryTable& GetStaticEntries() const {
-    return static_entries_;
-  }
-  const HpackHeaderTable::NameValueToEntryMap& GetStaticIndex() const {
-    return static_index_;
-  }
-  const HpackHeaderTable::NameToEntryMap& GetStaticNameIndex() const {
-    return static_name_index_;
-  }
-
- private:
-  HpackHeaderTable::StaticEntryTable static_entries_;
-  // The following two members have string_views that point to strings stored in
-  // |static_entries_|.
-  HpackHeaderTable::NameValueToEntryMap static_index_;
-  HpackHeaderTable::NameToEntryMap static_name_index_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
diff --git a/spdy/core/hpack/hpack_static_table_test.cc b/spdy/core/hpack/hpack_static_table_test.cc
deleted file mode 100644
index f7506da..0000000
--- a/spdy/core/hpack/hpack_static_table_test.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/hpack/hpack_static_table.h"
-
-#include <set>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/hpack/hpack_constants.h"
-
-namespace spdy {
-
-namespace test {
-
-namespace {
-
-class HpackStaticTableTest : public QuicheTest {
- protected:
-  HpackStaticTableTest() : table_() {}
-
-  HpackStaticTable table_;
-};
-
-// Check that an initialized instance has the right number of entries.
-TEST_F(HpackStaticTableTest, Initialize) {
-  EXPECT_FALSE(table_.IsInitialized());
-  table_.Initialize(HpackStaticTableVector().data(),
-                    HpackStaticTableVector().size());
-  EXPECT_TRUE(table_.IsInitialized());
-
-  const HpackHeaderTable::StaticEntryTable& static_entries =
-      table_.GetStaticEntries();
-  EXPECT_EQ(kStaticTableSize, static_entries.size());
-
-  const HpackHeaderTable::NameValueToEntryMap& static_index =
-      table_.GetStaticIndex();
-  EXPECT_EQ(kStaticTableSize, static_index.size());
-
-  const HpackHeaderTable::NameToEntryMap& static_name_index =
-      table_.GetStaticNameIndex();
-  // Count distinct names in static table.
-  std::set<absl::string_view> names;
-  for (const auto& entry : static_entries) {
-    names.insert(entry.name());
-  }
-  EXPECT_EQ(names.size(), static_name_index.size());
-}
-
-// Test that ObtainHpackStaticTable returns the same instance every time.
-TEST_F(HpackStaticTableTest, IsSingleton) {
-  const HpackStaticTable* static_table_one = &ObtainHpackStaticTable();
-  const HpackStaticTable* static_table_two = &ObtainHpackStaticTable();
-  EXPECT_EQ(static_table_one, static_table_two);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace spdy
diff --git a/spdy/core/http2_frame_decoder_adapter.cc b/spdy/core/http2_frame_decoder_adapter.cc
deleted file mode 100644
index 0f6da60..0000000
--- a/spdy/core/http2_frame_decoder_adapter.cc
+++ /dev/null
@@ -1,1107 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/http2_frame_decoder_adapter.h"
-
-// Logging policy: If an error in the input is detected, QUICHE_VLOG(n) is used
-// so that the option exists to debug the situation. Otherwise, this code mostly
-// uses QUICHE_DVLOG so that the logging does not slow down production code when
-// things are working OK.
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <cstring>
-#include <utility>
-
-#include "http2/decoder/decode_buffer.h"
-#include "http2/decoder/decode_status.h"
-#include "http2/decoder/http2_frame_decoder.h"
-#include "http2/decoder/http2_frame_decoder_listener.h"
-#include "http2/http2_constants.h"
-#include "http2/http2_structures.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_endian.h"
-#include "spdy/core/hpack/hpack_decoder_adapter.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-#include "spdy/core/spdy_protocol.h"
-
-using ::spdy::ExtensionVisitorInterface;
-using ::spdy::HpackDecoderAdapter;
-using ::spdy::HpackHeaderTable;
-using ::spdy::ParseErrorCode;
-using ::spdy::ParseFrameType;
-using ::spdy::SpdyAltSvcWireFormat;
-using ::spdy::SpdyErrorCode;
-using ::spdy::SpdyFramerDebugVisitorInterface;
-using ::spdy::SpdyFramerVisitorInterface;
-using ::spdy::SpdyFrameType;
-using ::spdy::SpdyHeadersHandlerInterface;
-using ::spdy::SpdyKnownSettingsId;
-using ::spdy::SpdySettingsId;
-
-namespace http2 {
-namespace {
-
-const bool kHasPriorityFields = true;
-const bool kNotHasPriorityFields = false;
-
-bool IsPaddable(Http2FrameType type) {
-  return type == Http2FrameType::DATA || type == Http2FrameType::HEADERS ||
-         type == Http2FrameType::PUSH_PROMISE;
-}
-
-SpdyFrameType ToSpdyFrameType(Http2FrameType type) {
-  return ParseFrameType(static_cast<uint8_t>(type));
-}
-
-uint64_t ToSpdyPingId(const Http2PingFields& ping) {
-  uint64_t v;
-  std::memcpy(&v, ping.opaque_bytes, Http2PingFields::EncodedSize());
-  return quiche::QuicheEndian::NetToHost64(v);
-}
-
-// Overwrites the fields of the header with invalid values, for the purpose
-// of identifying reading of unset fields. Only takes effect for debug builds.
-// In Address Sanatizer builds, it also marks the fields as un-readable.
-#ifndef NDEBUG
-void CorruptFrameHeader(Http2FrameHeader* header) {
-  // Beyond a valid payload length, which is 2^24 - 1.
-  header->payload_length = 0x1010dead;
-  // An unsupported frame type.
-  header->type = Http2FrameType(0x80);
-  QUICHE_DCHECK(!IsSupportedHttp2FrameType(header->type));
-  // Frame flag bits that aren't used by any supported frame type.
-  header->flags = Http2FrameFlag(0xd2);
-  // A stream id with the reserved high-bit (R in the RFC) set.
-  // 2129510127 when the high-bit is cleared.
-  header->stream_id = 0xfeedbeef;
-}
-#else
-void CorruptFrameHeader(Http2FrameHeader* /*header*/) {}
-#endif
-
-Http2DecoderAdapter::SpdyFramerError HpackDecodingErrorToSpdyFramerError(
-    HpackDecodingError error) {
-  switch (error) {
-    case HpackDecodingError::kOk:
-      return Http2DecoderAdapter::SpdyFramerError::SPDY_NO_ERROR;
-    case HpackDecodingError::kIndexVarintError:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_INDEX_VARINT_ERROR;
-    case HpackDecodingError::kNameLengthVarintError:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_NAME_LENGTH_VARINT_ERROR;
-    case HpackDecodingError::kValueLengthVarintError:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR;
-    case HpackDecodingError::kNameTooLong:
-      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG;
-    case HpackDecodingError::kValueTooLong:
-      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG;
-    case HpackDecodingError::kNameHuffmanError:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_NAME_HUFFMAN_ERROR;
-    case HpackDecodingError::kValueHuffmanError:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_VALUE_HUFFMAN_ERROR;
-    case HpackDecodingError::kMissingDynamicTableSizeUpdate:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
-    case HpackDecodingError::kInvalidIndex:
-      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX;
-    case HpackDecodingError::kInvalidNameIndex:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_INVALID_NAME_INDEX;
-    case HpackDecodingError::kDynamicTableSizeUpdateNotAllowed:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
-    case HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
-    case HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
-    case HpackDecodingError::kTruncatedBlock:
-      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK;
-    case HpackDecodingError::kFragmentTooLong:
-      return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG;
-    case HpackDecodingError::kCompressedHeaderSizeExceedsLimit:
-      return Http2DecoderAdapter::SpdyFramerError::
-          SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
-  }
-
-  return Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE;
-}
-
-}  // namespace
-
-const char* Http2DecoderAdapter::StateToString(int state) {
-  switch (state) {
-    case SPDY_ERROR:
-      return "ERROR";
-    case SPDY_FRAME_COMPLETE:
-      return "FRAME_COMPLETE";
-    case SPDY_READY_FOR_FRAME:
-      return "READY_FOR_FRAME";
-    case SPDY_READING_COMMON_HEADER:
-      return "READING_COMMON_HEADER";
-    case SPDY_CONTROL_FRAME_PAYLOAD:
-      return "CONTROL_FRAME_PAYLOAD";
-    case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
-      return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
-    case SPDY_CONSUME_PADDING:
-      return "SPDY_CONSUME_PADDING";
-    case SPDY_IGNORE_REMAINING_PAYLOAD:
-      return "IGNORE_REMAINING_PAYLOAD";
-    case SPDY_FORWARD_STREAM_FRAME:
-      return "FORWARD_STREAM_FRAME";
-    case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
-      return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
-    case SPDY_CONTROL_FRAME_HEADER_BLOCK:
-      return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
-    case SPDY_GOAWAY_FRAME_PAYLOAD:
-      return "SPDY_GOAWAY_FRAME_PAYLOAD";
-    case SPDY_SETTINGS_FRAME_HEADER:
-      return "SPDY_SETTINGS_FRAME_HEADER";
-    case SPDY_SETTINGS_FRAME_PAYLOAD:
-      return "SPDY_SETTINGS_FRAME_PAYLOAD";
-    case SPDY_ALTSVC_FRAME_PAYLOAD:
-      return "SPDY_ALTSVC_FRAME_PAYLOAD";
-  }
-  return "UNKNOWN_STATE";
-}
-
-const char* Http2DecoderAdapter::SpdyFramerErrorToString(
-    SpdyFramerError spdy_framer_error) {
-  switch (spdy_framer_error) {
-    case SPDY_NO_ERROR:
-      return "NO_ERROR";
-    case SPDY_INVALID_STREAM_ID:
-      return "INVALID_STREAM_ID";
-    case SPDY_INVALID_CONTROL_FRAME:
-      return "INVALID_CONTROL_FRAME";
-    case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
-      return "CONTROL_PAYLOAD_TOO_LARGE";
-    case SPDY_DECOMPRESS_FAILURE:
-      return "DECOMPRESS_FAILURE";
-    case SPDY_INVALID_PADDING:
-      return "INVALID_PADDING";
-    case SPDY_INVALID_DATA_FRAME_FLAGS:
-      return "INVALID_DATA_FRAME_FLAGS";
-    case SPDY_UNEXPECTED_FRAME:
-      return "UNEXPECTED_FRAME";
-    case SPDY_INTERNAL_FRAMER_ERROR:
-      return "INTERNAL_FRAMER_ERROR";
-    case SPDY_INVALID_CONTROL_FRAME_SIZE:
-      return "INVALID_CONTROL_FRAME_SIZE";
-    case SPDY_OVERSIZED_PAYLOAD:
-      return "OVERSIZED_PAYLOAD";
-    case SPDY_HPACK_INDEX_VARINT_ERROR:
-      return "HPACK_INDEX_VARINT_ERROR";
-    case SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
-      return "HPACK_NAME_LENGTH_VARINT_ERROR";
-    case SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
-      return "HPACK_VALUE_LENGTH_VARINT_ERROR";
-    case SPDY_HPACK_NAME_TOO_LONG:
-      return "HPACK_NAME_TOO_LONG";
-    case SPDY_HPACK_VALUE_TOO_LONG:
-      return "HPACK_VALUE_TOO_LONG";
-    case SPDY_HPACK_NAME_HUFFMAN_ERROR:
-      return "HPACK_NAME_HUFFMAN_ERROR";
-    case SPDY_HPACK_VALUE_HUFFMAN_ERROR:
-      return "HPACK_VALUE_HUFFMAN_ERROR";
-    case SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
-      return "HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE";
-    case SPDY_HPACK_INVALID_INDEX:
-      return "HPACK_INVALID_INDEX";
-    case SPDY_HPACK_INVALID_NAME_INDEX:
-      return "HPACK_INVALID_NAME_INDEX";
-    case SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
-      return "HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED";
-    case SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
-      return "HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK";
-    case SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
-      return "HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING";
-    case SPDY_HPACK_TRUNCATED_BLOCK:
-      return "HPACK_TRUNCATED_BLOCK";
-    case SPDY_HPACK_FRAGMENT_TOO_LONG:
-      return "HPACK_FRAGMENT_TOO_LONG";
-    case SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
-      return "HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT";
-    case SPDY_STOP_PROCESSING:
-      return "STOP_PROCESSING";
-    case LAST_ERROR:
-      return "UNKNOWN_ERROR";
-  }
-  return "UNKNOWN_ERROR";
-}
-
-Http2DecoderAdapter::Http2DecoderAdapter() : frame_decoder_(this) {
-  QUICHE_DVLOG(1) << "Http2DecoderAdapter ctor";
-
-  CorruptFrameHeader(&frame_header_);
-  CorruptFrameHeader(&hpack_first_frame_header_);
-}
-
-Http2DecoderAdapter::~Http2DecoderAdapter() = default;
-
-void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) {
-  visitor_ = visitor;
-}
-
-void Http2DecoderAdapter::set_debug_visitor(
-    SpdyFramerDebugVisitorInterface* debug_visitor) {
-  debug_visitor_ = debug_visitor;
-}
-
-void Http2DecoderAdapter::set_extension_visitor(
-    ExtensionVisitorInterface* visitor) {
-  extension_ = visitor;
-}
-
-size_t Http2DecoderAdapter::ProcessInput(const char* data, size_t len) {
-  size_t total_processed = 0;
-  while (len > 0 && spdy_state_ != SPDY_ERROR) {
-    // Process one at a time so that we update the adapter's internal
-    // state appropriately.
-    const size_t processed = ProcessInputFrame(data, len);
-
-    // We had some data, and weren't in an error state, so should have
-    // processed/consumed at least one byte of it, even if we then ended up
-    // in an error state.
-    QUICHE_DCHECK(processed > 0)
-        << "processed=" << processed << "   spdy_state_=" << spdy_state_
-        << "   spdy_framer_error_=" << spdy_framer_error_;
-
-    data += processed;
-    len -= processed;
-    total_processed += processed;
-    if (processed == 0) {
-      break;
-    }
-  }
-  return total_processed;
-}
-
-Http2DecoderAdapter::SpdyState Http2DecoderAdapter::state() const {
-  return spdy_state_;
-}
-
-Http2DecoderAdapter::SpdyFramerError Http2DecoderAdapter::spdy_framer_error()
-    const {
-  return spdy_framer_error_;
-}
-
-bool Http2DecoderAdapter::probable_http_response() const {
-  return latched_probable_http_response_;
-}
-
-void Http2DecoderAdapter::StopProcessing() {
-  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_STOP_PROCESSING,
-                        "Ignoring further events on this connection.");
-}
-
-void Http2DecoderAdapter::SetMaxFrameSize(size_t max_frame_size) {
-  max_frame_size_ = max_frame_size;
-  frame_decoder_.set_maximum_payload_size(max_frame_size);
-}
-
-// ===========================================================================
-// Implementations of the methods declared by Http2FrameDecoderListener.
-
-// Called once the common frame header has been decoded for any frame.
-// This function is largely based on Http2DecoderAdapter::ValidateFrameHeader
-// and some parts of Http2DecoderAdapter::ProcessCommonHeader.
-bool Http2DecoderAdapter::OnFrameHeader(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnFrameHeader: " << header;
-  decoded_frame_header_ = true;
-  if (!latched_probable_http_response_) {
-    latched_probable_http_response_ = header.IsProbableHttpResponse();
-  }
-  const uint8_t raw_frame_type = static_cast<uint8_t>(header.type);
-  visitor()->OnCommonHeader(header.stream_id, header.payload_length,
-                            raw_frame_type, header.flags);
-  if (has_expected_frame_type_ && header.type != expected_frame_type_) {
-    // Report an unexpected frame error and close the connection if we
-    // expect a known frame type (probably CONTINUATION) and receive an
-    // unknown frame.
-    QUICHE_VLOG(1) << "The framer was expecting to receive a "
-                   << expected_frame_type_
-                   << " frame, but instead received an unknown frame of type "
-                   << header.type;
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
-    return false;
-  }
-  if (!IsSupportedHttp2FrameType(header.type)) {
-    if (extension_ != nullptr) {
-      // Unknown frames will be passed to the registered extension.
-      return true;
-    }
-    // In HTTP2 we ignore unknown frame types for extensibility, as long as
-    // the rest of the control frame header is valid.
-    // We rely on the visitor to check validity of stream_id.
-    bool valid_stream =
-        visitor()->OnUnknownFrame(header.stream_id, raw_frame_type);
-    if (!valid_stream) {
-      // Report an invalid frame error if the stream_id is not valid.
-      QUICHE_VLOG(1) << "Unknown control frame type " << header.type
-                     << " received on invalid stream " << header.stream_id;
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
-      return false;
-    } else {
-      QUICHE_DVLOG(1) << "Ignoring unknown frame type " << header.type;
-      return true;
-    }
-  }
-
-  SpdyFrameType frame_type = ToSpdyFrameType(header.type);
-  if (!IsValidHTTP2FrameStreamId(header.stream_id, frame_type)) {
-    QUICHE_VLOG(1) << "The framer received an invalid streamID of "
-                   << header.stream_id << " for a frame of type "
-                   << header.type;
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
-    return false;
-  }
-
-  if (has_expected_frame_type_ && header.type != expected_frame_type_) {
-    QUICHE_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
-                   << header.type;
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
-    return false;
-  }
-
-  if (!has_expected_frame_type_ &&
-      header.type == Http2FrameType::CONTINUATION) {
-    QUICHE_VLOG(1) << "Got CONTINUATION frame when not expected.";
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
-    return false;
-  }
-
-  if (header.type == Http2FrameType::DATA) {
-    // For some reason SpdyFramer still rejects invalid DATA frame flags.
-    uint8_t valid_flags = Http2FrameFlag::PADDED | Http2FrameFlag::END_STREAM;
-    if (header.HasAnyFlags(~valid_flags)) {
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS, "");
-      return false;
-    }
-  }
-
-  return true;
-}
-
-void Http2DecoderAdapter::OnDataStart(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnDataStart: " << header;
-
-  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
-    frame_header_ = header;
-    has_frame_header_ = true;
-    visitor()->OnDataFrameHeader(header.stream_id, header.payload_length,
-                                 header.IsEndStream());
-  }
-}
-
-void Http2DecoderAdapter::OnDataPayload(const char* data, size_t len) {
-  QUICHE_DVLOG(1) << "OnDataPayload: len=" << len;
-  QUICHE_DCHECK(has_frame_header_);
-  QUICHE_DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
-  visitor()->OnStreamFrameData(frame_header().stream_id, data, len);
-}
-
-void Http2DecoderAdapter::OnDataEnd() {
-  QUICHE_DVLOG(1) << "OnDataEnd";
-  QUICHE_DCHECK(has_frame_header_);
-  QUICHE_DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
-  if (frame_header().IsEndStream()) {
-    visitor()->OnStreamEnd(frame_header().stream_id);
-  }
-  opt_pad_length_.reset();
-}
-
-void Http2DecoderAdapter::OnHeadersStart(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnHeadersStart: " << header;
-  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
-    frame_header_ = header;
-    has_frame_header_ = true;
-    if (header.HasPriority()) {
-      // Once we've got the priority fields, then we can report the arrival
-      // of this HEADERS frame.
-      on_headers_called_ = false;
-      return;
-    }
-    on_headers_called_ = true;
-    ReportReceiveCompressedFrame(header);
-    visitor()->OnHeaders(header.stream_id, kNotHasPriorityFields,
-                         0,      // priority
-                         0,      // parent_stream_id
-                         false,  // exclusive
-                         header.IsEndStream(), header.IsEndHeaders());
-    CommonStartHpackBlock();
-  }
-}
-
-void Http2DecoderAdapter::OnHeadersPriority(
-    const Http2PriorityFields& priority) {
-  QUICHE_DVLOG(1) << "OnHeadersPriority: " << priority;
-  QUICHE_DCHECK(has_frame_header_);
-  QUICHE_DCHECK_EQ(frame_type(), Http2FrameType::HEADERS) << frame_header_;
-  QUICHE_DCHECK(frame_header_.HasPriority());
-  QUICHE_DCHECK(!on_headers_called_);
-  on_headers_called_ = true;
-  ReportReceiveCompressedFrame(frame_header_);
-  if (!visitor()) {
-    QUICHE_BUG(spdy_bug_1_1)
-        << "Visitor is nullptr, handling priority in headers failed."
-        << " priority:" << priority << " frame_header:" << frame_header_;
-    return;
-  }
-  visitor()->OnHeaders(frame_header_.stream_id, kHasPriorityFields,
-                       priority.weight, priority.stream_dependency,
-                       priority.is_exclusive, frame_header_.IsEndStream(),
-                       frame_header_.IsEndHeaders());
-  CommonStartHpackBlock();
-}
-
-void Http2DecoderAdapter::OnHpackFragment(const char* data, size_t len) {
-  QUICHE_DVLOG(1) << "OnHpackFragment: len=" << len;
-  on_hpack_fragment_called_ = true;
-  auto* decoder = GetHpackDecoder();
-  if (!decoder->HandleControlFrameHeadersData(data, len)) {
-    SetSpdyErrorAndNotify(HpackDecodingErrorToSpdyFramerError(decoder->error()),
-                          decoder->detailed_error());
-    return;
-  }
-}
-
-void Http2DecoderAdapter::OnHeadersEnd() {
-  QUICHE_DVLOG(1) << "OnHeadersEnd";
-  CommonHpackFragmentEnd();
-  opt_pad_length_.reset();
-}
-
-void Http2DecoderAdapter::OnPriorityFrame(const Http2FrameHeader& header,
-                                          const Http2PriorityFields& priority) {
-  QUICHE_DVLOG(1) << "OnPriorityFrame: " << header
-                  << "; priority: " << priority;
-  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
-    visitor()->OnPriority(header.stream_id, priority.stream_dependency,
-                          priority.weight, priority.is_exclusive);
-  }
-}
-
-void Http2DecoderAdapter::OnContinuationStart(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnContinuationStart: " << header;
-  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
-    QUICHE_DCHECK(has_hpack_first_frame_header_);
-    if (header.stream_id != hpack_first_frame_header_.stream_id) {
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
-      return;
-    }
-    frame_header_ = header;
-    has_frame_header_ = true;
-    ReportReceiveCompressedFrame(header);
-    visitor()->OnContinuation(header.stream_id, header.IsEndHeaders());
-  }
-}
-
-void Http2DecoderAdapter::OnContinuationEnd() {
-  QUICHE_DVLOG(1) << "OnContinuationEnd";
-  CommonHpackFragmentEnd();
-}
-
-void Http2DecoderAdapter::OnPadLength(size_t trailing_length) {
-  QUICHE_DVLOG(1) << "OnPadLength: " << trailing_length;
-  opt_pad_length_ = trailing_length;
-  QUICHE_DCHECK_LT(trailing_length, 256u);
-  if (frame_header_.type == Http2FrameType::DATA) {
-    visitor()->OnStreamPadLength(stream_id(), trailing_length);
-  }
-}
-
-void Http2DecoderAdapter::OnPadding(const char* /*padding*/,
-                                    size_t skipped_length) {
-  QUICHE_DVLOG(1) << "OnPadding: " << skipped_length;
-  if (frame_header_.type == Http2FrameType::DATA) {
-    visitor()->OnStreamPadding(stream_id(), skipped_length);
-  } else {
-    MaybeAnnounceEmptyFirstHpackFragment();
-  }
-}
-
-void Http2DecoderAdapter::OnRstStream(const Http2FrameHeader& header,
-                                      Http2ErrorCode http2_error_code) {
-  QUICHE_DVLOG(1) << "OnRstStream: " << header << "; code=" << http2_error_code;
-  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
-    SpdyErrorCode error_code =
-        ParseErrorCode(static_cast<uint32_t>(http2_error_code));
-    visitor()->OnRstStream(header.stream_id, error_code);
-  }
-}
-
-void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnSettingsStart: " << header;
-  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
-    frame_header_ = header;
-    has_frame_header_ = true;
-    visitor()->OnSettings();
-  }
-}
-
-void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) {
-  QUICHE_DVLOG(1) << "OnSetting: " << setting_fields;
-  const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter);
-  visitor()->OnSetting(parameter, setting_fields.value);
-  SpdyKnownSettingsId known_id;
-  if (extension_ != nullptr && !spdy::ParseSettingsId(parameter, &known_id)) {
-    extension_->OnSetting(parameter, setting_fields.value);
-  }
-}
-
-void Http2DecoderAdapter::OnSettingsEnd() {
-  QUICHE_DVLOG(1) << "OnSettingsEnd";
-  visitor()->OnSettingsEnd();
-}
-
-void Http2DecoderAdapter::OnSettingsAck(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnSettingsAck: " << header;
-  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
-    visitor()->OnSettingsAck();
-  }
-}
-
-void Http2DecoderAdapter::OnPushPromiseStart(
-    const Http2FrameHeader& header,
-    const Http2PushPromiseFields& promise,
-    size_t total_padding_length) {
-  QUICHE_DVLOG(1) << "OnPushPromiseStart: " << header
-                  << "; promise: " << promise
-                  << "; total_padding_length: " << total_padding_length;
-  if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
-    if (promise.promised_stream_id == 0) {
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
-      return;
-    }
-    frame_header_ = header;
-    has_frame_header_ = true;
-    ReportReceiveCompressedFrame(header);
-    visitor()->OnPushPromise(header.stream_id, promise.promised_stream_id,
-                             header.IsEndHeaders());
-    CommonStartHpackBlock();
-  }
-}
-
-void Http2DecoderAdapter::OnPushPromiseEnd() {
-  QUICHE_DVLOG(1) << "OnPushPromiseEnd";
-  CommonHpackFragmentEnd();
-  opt_pad_length_.reset();
-}
-
-void Http2DecoderAdapter::OnPing(const Http2FrameHeader& header,
-                                 const Http2PingFields& ping) {
-  QUICHE_DVLOG(1) << "OnPing: " << header << "; ping: " << ping;
-  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
-    visitor()->OnPing(ToSpdyPingId(ping), false);
-  }
-}
-
-void Http2DecoderAdapter::OnPingAck(const Http2FrameHeader& header,
-                                    const Http2PingFields& ping) {
-  QUICHE_DVLOG(1) << "OnPingAck: " << header << "; ping: " << ping;
-  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
-    visitor()->OnPing(ToSpdyPingId(ping), true);
-  }
-}
-
-void Http2DecoderAdapter::OnGoAwayStart(const Http2FrameHeader& header,
-                                        const Http2GoAwayFields& goaway) {
-  QUICHE_DVLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway;
-  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
-    frame_header_ = header;
-    has_frame_header_ = true;
-    SpdyErrorCode error_code =
-        ParseErrorCode(static_cast<uint32_t>(goaway.error_code));
-    visitor()->OnGoAway(goaway.last_stream_id, error_code);
-  }
-}
-
-void Http2DecoderAdapter::OnGoAwayOpaqueData(const char* data, size_t len) {
-  QUICHE_DVLOG(1) << "OnGoAwayOpaqueData: len=" << len;
-  visitor()->OnGoAwayFrameData(data, len);
-}
-
-void Http2DecoderAdapter::OnGoAwayEnd() {
-  QUICHE_DVLOG(1) << "OnGoAwayEnd";
-  visitor()->OnGoAwayFrameData(nullptr, 0);
-}
-
-void Http2DecoderAdapter::OnWindowUpdate(const Http2FrameHeader& header,
-                                         uint32_t increment) {
-  QUICHE_DVLOG(1) << "OnWindowUpdate: " << header
-                  << "; increment=" << increment;
-  if (IsOkToStartFrame(header)) {
-    visitor()->OnWindowUpdate(header.stream_id, increment);
-  }
-}
-
-// Per RFC7838, an ALTSVC frame on stream 0 with origin_length == 0, or one on
-// a stream other than stream 0 with origin_length != 0 MUST be ignored.  All
-// frames are decoded by Http2DecoderAdapter, and it is left to the consumer
-// (listener) to implement this behavior.
-void Http2DecoderAdapter::OnAltSvcStart(const Http2FrameHeader& header,
-                                        size_t origin_length,
-                                        size_t value_length) {
-  QUICHE_DVLOG(1) << "OnAltSvcStart: " << header
-                  << "; origin_length: " << origin_length
-                  << "; value_length: " << value_length;
-  if (!IsOkToStartFrame(header)) {
-    return;
-  }
-  frame_header_ = header;
-  has_frame_header_ = true;
-  alt_svc_origin_.clear();
-  alt_svc_value_.clear();
-}
-
-void Http2DecoderAdapter::OnAltSvcOriginData(const char* data, size_t len) {
-  QUICHE_DVLOG(1) << "OnAltSvcOriginData: len=" << len;
-  alt_svc_origin_.append(data, len);
-}
-
-// Called when decoding the Alt-Svc-Field-Value of an ALTSVC;
-// the field is uninterpreted.
-void Http2DecoderAdapter::OnAltSvcValueData(const char* data, size_t len) {
-  QUICHE_DVLOG(1) << "OnAltSvcValueData: len=" << len;
-  alt_svc_value_.append(data, len);
-}
-
-void Http2DecoderAdapter::OnAltSvcEnd() {
-  QUICHE_DVLOG(1) << "OnAltSvcEnd: origin.size(): " << alt_svc_origin_.size()
-                  << "; value.size(): " << alt_svc_value_.size();
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(alt_svc_value_,
-                                                   &altsvc_vector)) {
-    QUICHE_DLOG(ERROR) << "SpdyAltSvcWireFormat::ParseHeaderFieldValue failed.";
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
-    return;
-  }
-  visitor()->OnAltSvc(frame_header_.stream_id, alt_svc_origin_, altsvc_vector);
-  // We assume that ALTSVC frames are rare, so get rid of the storage.
-  alt_svc_origin_.clear();
-  alt_svc_origin_.shrink_to_fit();
-  alt_svc_value_.clear();
-  alt_svc_value_.shrink_to_fit();
-}
-
-void Http2DecoderAdapter::OnPriorityUpdateStart(
-    const Http2FrameHeader& header,
-    const Http2PriorityUpdateFields& priority_update) {
-  QUICHE_DVLOG(1) << "OnPriorityUpdateStart: " << header
-                  << "; prioritized_stream_id: "
-                  << priority_update.prioritized_stream_id;
-  if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header) &&
-      HasRequiredStreamId(priority_update.prioritized_stream_id)) {
-    frame_header_ = header;
-    has_frame_header_ = true;
-    prioritized_stream_id_ = priority_update.prioritized_stream_id;
-  }
-}
-
-void Http2DecoderAdapter::OnPriorityUpdatePayload(const char* data,
-                                                  size_t len) {
-  QUICHE_DVLOG(1) << "OnPriorityUpdatePayload: len=" << len;
-  priority_field_value_.append(data, len);
-}
-
-void Http2DecoderAdapter::OnPriorityUpdateEnd() {
-  QUICHE_DVLOG(1) << "OnPriorityUpdateEnd: priority_field_value.size(): "
-                  << priority_field_value_.size();
-  visitor()->OnPriorityUpdate(prioritized_stream_id_, priority_field_value_);
-  priority_field_value_.clear();
-}
-
-// Except for BLOCKED frames, all other unknown frames are either dropped or
-// passed to a registered extension.
-void Http2DecoderAdapter::OnUnknownStart(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnUnknownStart: " << header;
-  if (IsOkToStartFrame(header)) {
-    if (extension_ != nullptr) {
-      const uint8_t type = static_cast<uint8_t>(header.type);
-      const uint8_t flags = static_cast<uint8_t>(header.flags);
-      handling_extension_payload_ = extension_->OnFrameHeader(
-          header.stream_id, header.payload_length, type, flags);
-    }
-  }
-}
-
-void Http2DecoderAdapter::OnUnknownPayload(const char* data, size_t len) {
-  if (handling_extension_payload_) {
-    extension_->OnFramePayload(data, len);
-  } else {
-    QUICHE_DVLOG(1) << "OnUnknownPayload: len=" << len;
-  }
-}
-
-void Http2DecoderAdapter::OnUnknownEnd() {
-  QUICHE_DVLOG(1) << "OnUnknownEnd";
-  handling_extension_payload_ = false;
-}
-
-void Http2DecoderAdapter::OnPaddingTooLong(const Http2FrameHeader& header,
-                                           size_t missing_length) {
-  QUICHE_DVLOG(1) << "OnPaddingTooLong: " << header
-                  << "; missing_length: " << missing_length;
-  if (header.type == Http2FrameType::DATA) {
-    if (header.payload_length == 0) {
-      QUICHE_DCHECK_EQ(1u, missing_length);
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS, "");
-      return;
-    }
-    visitor()->OnStreamPadding(header.stream_id, 1);
-  }
-  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_PADDING, "");
-}
-
-void Http2DecoderAdapter::OnFrameSizeError(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(1) << "OnFrameSizeError: " << header;
-  if (header.payload_length > max_frame_size_) {
-    if (header.type == Http2FrameType::DATA) {
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_OVERSIZED_PAYLOAD, "");
-    } else {
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
-                            "");
-    }
-    return;
-  }
-  switch (header.type) {
-    case Http2FrameType::GOAWAY:
-    case Http2FrameType::ALTSVC:
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
-      break;
-    default:
-      SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE,
-                            "");
-  }
-}
-
-// Decodes the input up to the next frame boundary (i.e. at most one frame),
-// stopping early if an error is detected.
-size_t Http2DecoderAdapter::ProcessInputFrame(const char* data, size_t len) {
-  QUICHE_DCHECK_NE(spdy_state_, SpdyState::SPDY_ERROR);
-  DecodeBuffer db(data, len);
-  DecodeStatus status = frame_decoder_.DecodeFrame(&db);
-  if (spdy_state_ != SpdyState::SPDY_ERROR) {
-    DetermineSpdyState(status);
-  } else {
-    QUICHE_VLOG(1) << "ProcessInputFrame spdy_framer_error_="
-                   << SpdyFramerErrorToString(spdy_framer_error_);
-    if (spdy_framer_error_ == SpdyFramerError::SPDY_INVALID_PADDING &&
-        has_frame_header_ && frame_type() != Http2FrameType::DATA) {
-      // spdy_framer_test checks that all of the available frame payload
-      // has been consumed, so do that.
-      size_t total = remaining_total_payload();
-      if (total <= frame_header().payload_length) {
-        size_t avail = db.MinLengthRemaining(total);
-        QUICHE_VLOG(1) << "Skipping past " << avail << " bytes, of " << total
-                       << " total remaining in the frame's payload.";
-        db.AdvanceCursor(avail);
-      } else {
-        QUICHE_BUG(spdy_bug_1_2)
-            << "Total remaining (" << total
-            << ") should not be greater than the payload length; "
-            << frame_header();
-      }
-    }
-  }
-  return db.Offset();
-}
-
-// After decoding, determine the next SpdyState. Only called if the current
-// state is NOT SpdyState::SPDY_ERROR (i.e. if none of the callback methods
-// detected an error condition), because otherwise we assume that the callback
-// method has set spdy_framer_error_ appropriately.
-void Http2DecoderAdapter::DetermineSpdyState(DecodeStatus status) {
-  QUICHE_DCHECK_EQ(spdy_framer_error_, SPDY_NO_ERROR);
-  QUICHE_DCHECK(!HasError()) << spdy_framer_error_;
-  switch (status) {
-    case DecodeStatus::kDecodeDone:
-      QUICHE_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeDone";
-      ResetBetweenFrames();
-      break;
-    case DecodeStatus::kDecodeInProgress:
-      QUICHE_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeInProgress";
-      if (decoded_frame_header_) {
-        if (IsDiscardingPayload()) {
-          set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
-        } else if (has_frame_header_ && frame_type() == Http2FrameType::DATA) {
-          if (IsReadingPaddingLength()) {
-            set_spdy_state(SpdyState::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
-          } else if (IsSkippingPadding()) {
-            set_spdy_state(SpdyState::SPDY_CONSUME_PADDING);
-          } else {
-            set_spdy_state(SpdyState::SPDY_FORWARD_STREAM_FRAME);
-          }
-        } else {
-          set_spdy_state(SpdyState::SPDY_CONTROL_FRAME_PAYLOAD);
-        }
-      } else {
-        set_spdy_state(SpdyState::SPDY_READING_COMMON_HEADER);
-      }
-      break;
-    case DecodeStatus::kDecodeError:
-      QUICHE_VLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeError";
-      if (IsDiscardingPayload()) {
-        if (remaining_total_payload() == 0) {
-          // Push the Http2FrameDecoder out of state kDiscardPayload now
-          // since doing so requires no input.
-          DecodeBuffer tmp("", 0);
-          DecodeStatus decode_status = frame_decoder_.DecodeFrame(&tmp);
-          if (decode_status != DecodeStatus::kDecodeDone) {
-            QUICHE_BUG(spdy_bug_1_3)
-                << "Expected to be done decoding the frame, not "
-                << decode_status;
-            SetSpdyErrorAndNotify(SPDY_INTERNAL_FRAMER_ERROR, "");
-          } else if (spdy_framer_error_ != SPDY_NO_ERROR) {
-            QUICHE_BUG(spdy_bug_1_4)
-                << "Expected to have no error, not "
-                << SpdyFramerErrorToString(spdy_framer_error_);
-          } else {
-            ResetBetweenFrames();
-          }
-        } else {
-          set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
-        }
-      } else {
-        SetSpdyErrorAndNotify(SPDY_INVALID_CONTROL_FRAME, "");
-      }
-      break;
-  }
-}
-
-void Http2DecoderAdapter::ResetBetweenFrames() {
-  CorruptFrameHeader(&frame_header_);
-  decoded_frame_header_ = false;
-  has_frame_header_ = false;
-  set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME);
-}
-
-void Http2DecoderAdapter::set_spdy_state(SpdyState v) {
-  QUICHE_DVLOG(2) << "set_spdy_state(" << StateToString(v) << ")";
-  spdy_state_ = v;
-}
-
-void Http2DecoderAdapter::SetSpdyErrorAndNotify(SpdyFramerError error,
-                                                std::string detailed_error) {
-  if (HasError()) {
-    QUICHE_DCHECK_EQ(spdy_state_, SpdyState::SPDY_ERROR);
-  } else {
-    QUICHE_VLOG(2) << "SetSpdyErrorAndNotify(" << SpdyFramerErrorToString(error)
-                   << ")";
-    QUICHE_DCHECK_NE(error, SpdyFramerError::SPDY_NO_ERROR);
-    spdy_framer_error_ = error;
-    set_spdy_state(SpdyState::SPDY_ERROR);
-    frame_decoder_.set_listener(&no_op_listener_);
-    visitor()->OnError(error, detailed_error);
-  }
-}
-
-bool Http2DecoderAdapter::HasError() const {
-  if (spdy_state_ == SpdyState::SPDY_ERROR) {
-    QUICHE_DCHECK_NE(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
-    return true;
-  } else {
-    QUICHE_DCHECK_EQ(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
-    return false;
-  }
-}
-
-const Http2FrameHeader& Http2DecoderAdapter::frame_header() const {
-  QUICHE_DCHECK(has_frame_header_);
-  return frame_header_;
-}
-
-uint32_t Http2DecoderAdapter::stream_id() const {
-  return frame_header().stream_id;
-}
-
-Http2FrameType Http2DecoderAdapter::frame_type() const {
-  return frame_header().type;
-}
-
-size_t Http2DecoderAdapter::remaining_total_payload() const {
-  QUICHE_DCHECK(has_frame_header_);
-  size_t remaining = frame_decoder_.remaining_payload();
-  if (IsPaddable(frame_type()) && frame_header_.IsPadded()) {
-    remaining += frame_decoder_.remaining_padding();
-  }
-  return remaining;
-}
-
-bool Http2DecoderAdapter::IsReadingPaddingLength() {
-  bool result = frame_header_.IsPadded() && !opt_pad_length_;
-  QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsReadingPaddingLength: " << result;
-  return result;
-}
-bool Http2DecoderAdapter::IsSkippingPadding() {
-  bool result = frame_header_.IsPadded() && opt_pad_length_ &&
-                frame_decoder_.remaining_payload() == 0 &&
-                frame_decoder_.remaining_padding() > 0;
-  QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsSkippingPadding: " << result;
-  return result;
-}
-bool Http2DecoderAdapter::IsDiscardingPayload() {
-  bool result = decoded_frame_header_ && frame_decoder_.IsDiscardingPayload();
-  QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsDiscardingPayload: " << result;
-  return result;
-}
-// Called from OnXyz or OnXyzStart methods to decide whether it is OK to
-// handle the callback.
-bool Http2DecoderAdapter::IsOkToStartFrame(const Http2FrameHeader& header) {
-  QUICHE_DVLOG(3) << "IsOkToStartFrame";
-  if (HasError()) {
-    QUICHE_VLOG(2) << "HasError()";
-    return false;
-  }
-  QUICHE_DCHECK(!has_frame_header_);
-  if (has_expected_frame_type_ && header.type != expected_frame_type_) {
-    QUICHE_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
-                   << header.type;
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
-    return false;
-  }
-
-  return true;
-}
-
-bool Http2DecoderAdapter::HasRequiredStreamId(uint32_t stream_id) {
-  QUICHE_DVLOG(3) << "HasRequiredStreamId: " << stream_id;
-  if (HasError()) {
-    QUICHE_VLOG(2) << "HasError()";
-    return false;
-  }
-  if (stream_id != 0) {
-    return true;
-  }
-  QUICHE_VLOG(1) << "Stream Id is required, but zero provided";
-  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
-  return false;
-}
-
-bool Http2DecoderAdapter::HasRequiredStreamId(const Http2FrameHeader& header) {
-  return HasRequiredStreamId(header.stream_id);
-}
-
-bool Http2DecoderAdapter::HasRequiredStreamIdZero(uint32_t stream_id) {
-  QUICHE_DVLOG(3) << "HasRequiredStreamIdZero: " << stream_id;
-  if (HasError()) {
-    QUICHE_VLOG(2) << "HasError()";
-    return false;
-  }
-  if (stream_id == 0) {
-    return true;
-  }
-  QUICHE_VLOG(1) << "Stream Id was not zero, as required: " << stream_id;
-  SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
-  return false;
-}
-
-bool Http2DecoderAdapter::HasRequiredStreamIdZero(
-    const Http2FrameHeader& header) {
-  return HasRequiredStreamIdZero(header.stream_id);
-}
-
-void Http2DecoderAdapter::ReportReceiveCompressedFrame(
-    const Http2FrameHeader& header) {
-  if (debug_visitor() != nullptr) {
-    size_t total = header.payload_length + Http2FrameHeader::EncodedSize();
-    debug_visitor()->OnReceiveCompressedFrame(
-        header.stream_id, ToSpdyFrameType(header.type), total);
-  }
-}
-
-HpackDecoderAdapter* Http2DecoderAdapter::GetHpackDecoder() {
-  if (hpack_decoder_ == nullptr) {
-    hpack_decoder_ = std::make_unique<HpackDecoderAdapter>();
-  }
-  return hpack_decoder_.get();
-}
-
-void Http2DecoderAdapter::CommonStartHpackBlock() {
-  QUICHE_DVLOG(1) << "CommonStartHpackBlock";
-  QUICHE_DCHECK(!has_hpack_first_frame_header_);
-  if (!frame_header_.IsEndHeaders()) {
-    hpack_first_frame_header_ = frame_header_;
-    has_hpack_first_frame_header_ = true;
-  } else {
-    CorruptFrameHeader(&hpack_first_frame_header_);
-  }
-  on_hpack_fragment_called_ = false;
-  SpdyHeadersHandlerInterface* handler =
-      visitor()->OnHeaderFrameStart(stream_id());
-  if (handler == nullptr) {
-    QUICHE_BUG(spdy_bug_1_5) << "visitor_->OnHeaderFrameStart returned nullptr";
-    SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR, "");
-    return;
-  }
-  GetHpackDecoder()->HandleControlFrameHeadersStart(handler);
-}
-
-// SpdyFramer calls HandleControlFrameHeadersData even if there are zero
-// fragment bytes in the first frame, so do the same.
-void Http2DecoderAdapter::MaybeAnnounceEmptyFirstHpackFragment() {
-  if (!on_hpack_fragment_called_) {
-    OnHpackFragment(nullptr, 0);
-    QUICHE_DCHECK(on_hpack_fragment_called_);
-  }
-}
-
-void Http2DecoderAdapter::CommonHpackFragmentEnd() {
-  QUICHE_DVLOG(1) << "CommonHpackFragmentEnd: stream_id=" << stream_id();
-  if (HasError()) {
-    QUICHE_VLOG(1) << "HasError(), returning";
-    return;
-  }
-  QUICHE_DCHECK(has_frame_header_);
-  MaybeAnnounceEmptyFirstHpackFragment();
-  if (frame_header_.IsEndHeaders()) {
-    QUICHE_DCHECK_EQ(has_hpack_first_frame_header_,
-                     frame_type() == Http2FrameType::CONTINUATION)
-        << frame_header();
-    has_expected_frame_type_ = false;
-    auto* decoder = GetHpackDecoder();
-    if (decoder->HandleControlFrameHeadersComplete()) {
-      visitor()->OnHeaderFrameEnd(stream_id());
-    } else {
-      SetSpdyErrorAndNotify(
-          HpackDecodingErrorToSpdyFramerError(decoder->error()), "");
-      return;
-    }
-    const Http2FrameHeader& first = frame_type() == Http2FrameType::CONTINUATION
-                                        ? hpack_first_frame_header_
-                                        : frame_header_;
-    if (first.type == Http2FrameType::HEADERS && first.IsEndStream()) {
-      visitor()->OnStreamEnd(first.stream_id);
-    }
-    has_hpack_first_frame_header_ = false;
-    CorruptFrameHeader(&hpack_first_frame_header_);
-  } else {
-    QUICHE_DCHECK(has_hpack_first_frame_header_);
-    has_expected_frame_type_ = true;
-    expected_frame_type_ = Http2FrameType::CONTINUATION;
-  }
-}
-
-}  // namespace http2
-
-namespace spdy {
-
-bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* /*goaway_data*/,
-                                                   size_t /*len*/) {
-  return true;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/http2_frame_decoder_adapter.h b/spdy/core/http2_frame_decoder_adapter.h
deleted file mode 100644
index 5664470..0000000
--- a/spdy/core/http2_frame_decoder_adapter.h
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
-#define QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/optional.h"
-#include "http2/decoder/http2_frame_decoder.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_decoder_adapter.h"
-#include "spdy/core/hpack/hpack_header_table.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace spdy {
-
-class SpdyFramerVisitorInterface;
-class ExtensionVisitorInterface;
-
-}  // namespace spdy
-
-// TODO(dahollings): Perform various renames/moves suggested in cl/164660364.
-
-namespace http2 {
-
-// Adapts SpdyFramer interface to use Http2FrameDecoder.
-class QUICHE_EXPORT_PRIVATE Http2DecoderAdapter
-    : public http2::Http2FrameDecoderListener {
- public:
-  // HTTP2 states.
-  enum SpdyState {
-    SPDY_ERROR,
-    SPDY_READY_FOR_FRAME,  // Framer is ready for reading the next frame.
-    SPDY_FRAME_COMPLETE,  // Framer has finished reading a frame, need to reset.
-    SPDY_READING_COMMON_HEADER,
-    SPDY_CONTROL_FRAME_PAYLOAD,
-    SPDY_READ_DATA_FRAME_PADDING_LENGTH,
-    SPDY_CONSUME_PADDING,
-    SPDY_IGNORE_REMAINING_PAYLOAD,
-    SPDY_FORWARD_STREAM_FRAME,
-    SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK,
-    SPDY_CONTROL_FRAME_HEADER_BLOCK,
-    SPDY_GOAWAY_FRAME_PAYLOAD,
-    SPDY_SETTINGS_FRAME_HEADER,
-    SPDY_SETTINGS_FRAME_PAYLOAD,
-    SPDY_ALTSVC_FRAME_PAYLOAD,
-    SPDY_EXTENSION_FRAME_PAYLOAD,
-  };
-
-  // Framer error codes.
-  enum SpdyFramerError {
-    SPDY_NO_ERROR,
-    SPDY_INVALID_STREAM_ID,            // Stream ID is invalid
-    SPDY_INVALID_CONTROL_FRAME,        // Control frame is mal-formatted.
-    SPDY_CONTROL_PAYLOAD_TOO_LARGE,    // Control frame payload was too large.
-    SPDY_DECOMPRESS_FAILURE,           // There was an error decompressing.
-    SPDY_INVALID_PADDING,              // HEADERS or DATA frame padding invalid
-    SPDY_INVALID_DATA_FRAME_FLAGS,     // Data frame has invalid flags.
-    SPDY_UNEXPECTED_FRAME,             // Frame received out of order.
-    SPDY_INTERNAL_FRAMER_ERROR,        // SpdyFramer was used incorrectly.
-    SPDY_INVALID_CONTROL_FRAME_SIZE,   // Control frame not sized to spec
-    SPDY_OVERSIZED_PAYLOAD,            // Payload size was too large
-
-    // HttpDecoder or HttpDecoderAdapter error.
-    // See HpackDecodingError for description of each error code.
-    SPDY_HPACK_INDEX_VARINT_ERROR,
-    SPDY_HPACK_NAME_LENGTH_VARINT_ERROR,
-    SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR,
-    SPDY_HPACK_NAME_TOO_LONG,
-    SPDY_HPACK_VALUE_TOO_LONG,
-    SPDY_HPACK_NAME_HUFFMAN_ERROR,
-    SPDY_HPACK_VALUE_HUFFMAN_ERROR,
-    SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE,
-    SPDY_HPACK_INVALID_INDEX,
-    SPDY_HPACK_INVALID_NAME_INDEX,
-    SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED,
-    SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK,
-    SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING,
-    SPDY_HPACK_TRUNCATED_BLOCK,
-    SPDY_HPACK_FRAGMENT_TOO_LONG,
-    SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT,
-
-    // Set if the visitor no longer wishes to receive events for this
-    // connection.
-    SPDY_STOP_PROCESSING,
-
-    LAST_ERROR,  // Must be the last entry in the enum.
-  };
-
-  // For debugging.
-  static const char* StateToString(int state);
-  static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error);
-
-  Http2DecoderAdapter();
-  ~Http2DecoderAdapter() override;
-
-  Http2DecoderAdapter(const Http2DecoderAdapter&) = delete;
-  Http2DecoderAdapter& operator=(const Http2DecoderAdapter&) = delete;
-
-  // Set callbacks to be called from the framer.  A visitor must be set, or
-  // else the framer will likely crash.  It is acceptable for the visitor
-  // to do nothing.  If this is called multiple times, only the last visitor
-  // will be used.
-  void set_visitor(spdy::SpdyFramerVisitorInterface* visitor);
-  spdy::SpdyFramerVisitorInterface* visitor() const { return visitor_; }
-
-  // Set extension callbacks to be called from the framer or decoder. Optional.
-  // If called multiple times, only the last visitor will be used.
-  void set_extension_visitor(spdy::ExtensionVisitorInterface* visitor);
-  spdy::ExtensionVisitorInterface* extension_visitor() const {
-    return extension_;
-  }
-
-  // Set debug callbacks to be called from the framer. The debug visitor is
-  // completely optional and need not be set in order for normal operation.
-  // If this is called multiple times, only the last visitor will be used.
-  void set_debug_visitor(spdy::SpdyFramerDebugVisitorInterface* debug_visitor);
-  spdy::SpdyFramerDebugVisitorInterface* debug_visitor() const {
-    return debug_visitor_;
-  }
-
-  // Decode the |len| bytes of encoded HTTP/2 starting at |*data|. Returns
-  // the number of bytes consumed. It is safe to pass more bytes in than
-  // may be consumed. Should process (or otherwise buffer) as much as
-  // available.
-  //
-  // If the input contains the entirety of a DATA frame payload, GOAWAY frame
-  // Additional Debug Data field, or unknown frame payload, then the
-  // corresponding SpdyFramerVisitorInterface::OnStreamFrameData(),
-  // OnGoAwayFrameData(), or ExtensionVisitorInterface::OnFramePayload() method
-  // is guaranteed to be called exactly once, with the entire payload or field.
-  size_t ProcessInput(const char* data, size_t len);
-
-  // Current state of the decoder.
-  SpdyState state() const;
-
-  // Current error code (NO_ERROR if state != ERROR).
-  SpdyFramerError spdy_framer_error() const;
-
-  // Has any frame header looked like the start of an HTTP/1.1 (or earlier)
-  // response? Used to detect if a backend/server that we sent a request to
-  // has responded with an HTTP/1.1 (or earlier) response.
-  bool probable_http_response() const;
-
-  spdy::HpackDecoderAdapter* GetHpackDecoder();
-  const spdy::HpackDecoderAdapter* GetHpackDecoder() const {
-    return hpack_decoder_.get();
-  }
-
-  bool HasError() const;
-
-  // A visitor may call this method to indicate it no longer wishes to receive
-  // events for this connection.
-  void StopProcessing();
-
-  // Sets the limit on the size of received HTTP/2 frame payloads. Corresponds
-  // to SETTINGS_MAX_FRAME_SIZE as advertised to the peer.
-  void SetMaxFrameSize(size_t max_frame_size);
-
- private:
-  bool OnFrameHeader(const Http2FrameHeader& header) override;
-  void OnDataStart(const Http2FrameHeader& header) override;
-  void OnDataPayload(const char* data, size_t len) override;
-  void OnDataEnd() override;
-  void OnHeadersStart(const Http2FrameHeader& header) override;
-  void OnHeadersPriority(const Http2PriorityFields& priority) override;
-  void OnHpackFragment(const char* data, size_t len) override;
-  void OnHeadersEnd() override;
-  void OnPriorityFrame(const Http2FrameHeader& header,
-                       const Http2PriorityFields& priority) override;
-  void OnContinuationStart(const Http2FrameHeader& header) override;
-  void OnContinuationEnd() override;
-  void OnPadLength(size_t trailing_length) override;
-  void OnPadding(const char* padding, size_t skipped_length) override;
-  void OnRstStream(const Http2FrameHeader& header,
-                   Http2ErrorCode http2_error_code) override;
-  void OnSettingsStart(const Http2FrameHeader& header) override;
-  void OnSetting(const Http2SettingFields& setting_fields) override;
-  void OnSettingsEnd() override;
-  void OnSettingsAck(const Http2FrameHeader& header) override;
-  void OnPushPromiseStart(const Http2FrameHeader& header,
-                          const Http2PushPromiseFields& promise,
-                          size_t total_padding_length) override;
-  void OnPushPromiseEnd() override;
-  void OnPing(const Http2FrameHeader& header,
-              const Http2PingFields& ping) override;
-  void OnPingAck(const Http2FrameHeader& header,
-                 const Http2PingFields& ping) override;
-  void OnGoAwayStart(const Http2FrameHeader& header,
-                     const Http2GoAwayFields& goaway) override;
-  void OnGoAwayOpaqueData(const char* data, size_t len) override;
-  void OnGoAwayEnd() override;
-  void OnWindowUpdate(const Http2FrameHeader& header,
-                      uint32_t increment) override;
-  void OnAltSvcStart(const Http2FrameHeader& header,
-                     size_t origin_length,
-                     size_t value_length) override;
-  void OnAltSvcOriginData(const char* data, size_t len) override;
-  void OnAltSvcValueData(const char* data, size_t len) override;
-  void OnAltSvcEnd() override;
-  void OnPriorityUpdateStart(
-      const Http2FrameHeader& header,
-      const Http2PriorityUpdateFields& priority_update) override;
-  void OnPriorityUpdatePayload(const char* data, size_t len) override;
-  void OnPriorityUpdateEnd() override;
-  void OnUnknownStart(const Http2FrameHeader& header) override;
-  void OnUnknownPayload(const char* data, size_t len) override;
-  void OnUnknownEnd() override;
-  void OnPaddingTooLong(const Http2FrameHeader& header,
-                        size_t missing_length) override;
-  void OnFrameSizeError(const Http2FrameHeader& header) override;
-
-  size_t ProcessInputFrame(const char* data, size_t len);
-
-  void DetermineSpdyState(DecodeStatus status);
-  void ResetBetweenFrames();
-
-  void set_spdy_state(SpdyState v);
-
-  void SetSpdyErrorAndNotify(SpdyFramerError error, std::string detailed_error);
-
-  const Http2FrameHeader& frame_header() const;
-
-  uint32_t stream_id() const;
-  Http2FrameType frame_type() const;
-
-  size_t remaining_total_payload() const;
-
-  bool IsReadingPaddingLength();
-  bool IsSkippingPadding();
-  bool IsDiscardingPayload();
-  // Called from OnXyz or OnXyzStart methods to decide whether it is OK to
-  // handle the callback.
-  bool IsOkToStartFrame(const Http2FrameHeader& header);
-  bool HasRequiredStreamId(uint32_t stream_id);
-
-  bool HasRequiredStreamId(const Http2FrameHeader& header);
-
-  bool HasRequiredStreamIdZero(uint32_t stream_id);
-
-  bool HasRequiredStreamIdZero(const Http2FrameHeader& header);
-
-  void ReportReceiveCompressedFrame(const Http2FrameHeader& header);
-
-  void CommonStartHpackBlock();
-
-  // SpdyFramer calls HandleControlFrameHeadersData even if there are zero
-  // fragment bytes in the first frame, so do the same.
-  void MaybeAnnounceEmptyFirstHpackFragment();
-  void CommonHpackFragmentEnd();
-
-  // The most recently decoded frame header; invalid after we reached the end
-  // of that frame.
-  Http2FrameHeader frame_header_;
-
-  // If decoding an HPACK block that is split across multiple frames, this holds
-  // the frame header of the HEADERS or PUSH_PROMISE that started the block.
-  Http2FrameHeader hpack_first_frame_header_;
-
-  // Amount of trailing padding. Currently used just as an indicator of whether
-  // OnPadLength has been called.
-  absl::optional<size_t> opt_pad_length_;
-
-  // Temporary buffers for the AltSvc fields.
-  std::string alt_svc_origin_;
-  std::string alt_svc_value_;
-
-  // Temporary buffers for PRIORITY_UPDATE fields.
-  uint32_t prioritized_stream_id_ = 0;
-  std::string priority_field_value_;
-
-  // Listener used if we transition to an error state; the listener ignores all
-  // the callbacks.
-  Http2FrameDecoderNoOpListener no_op_listener_;
-
-  spdy::SpdyFramerVisitorInterface* visitor_ = nullptr;
-  spdy::SpdyFramerDebugVisitorInterface* debug_visitor_ = nullptr;
-
-  // If non-null, unknown frames and settings are passed to the extension.
-  spdy::ExtensionVisitorInterface* extension_ = nullptr;
-
-  // The HPACK decoder to be used for this adapter. User is responsible for
-  // clearing if the adapter is to be used for another connection.
-  std::unique_ptr<spdy::HpackDecoderAdapter> hpack_decoder_;
-
-  // The HTTP/2 frame decoder.
-  Http2FrameDecoder frame_decoder_;
-
-  // Next frame type expected. Currently only used for CONTINUATION frames,
-  // but could be used for detecting whether the first frame is a SETTINGS
-  // frame.
-  // TODO(jamessynge): Provide means to indicate that decoder should require
-  // SETTINGS frame as the first frame.
-  Http2FrameType expected_frame_type_;
-
-  // Attempt to duplicate the SpdyState and SpdyFramerError values that
-  // SpdyFramer sets. Values determined by getting tests to pass.
-  SpdyState spdy_state_ = SpdyState::SPDY_READY_FOR_FRAME;
-  SpdyFramerError spdy_framer_error_ = SpdyFramerError::SPDY_NO_ERROR;
-
-  // The limit on the size of received HTTP/2 payloads as specified in the
-  // SETTINGS_MAX_FRAME_SIZE advertised to peer.
-  size_t max_frame_size_ = spdy::kHttp2DefaultFramePayloadLimit;
-
-  // Has OnFrameHeader been called?
-  bool decoded_frame_header_ = false;
-
-  // Have we recorded an Http2FrameHeader for the current frame?
-  // We only do so if the decoder will make multiple callbacks for
-  // the frame; for example, for PING frames we don't make record
-  // the frame header, but for ALTSVC we do.
-  bool has_frame_header_ = false;
-
-  // Have we recorded an Http2FrameHeader for the current HPACK block?
-  // True only for multi-frame HPACK blocks.
-  bool has_hpack_first_frame_header_ = false;
-
-  // Has OnHeaders() already been called for current HEADERS block? Only
-  // meaningful between OnHeadersStart and OnHeadersPriority.
-  bool on_headers_called_ = false;
-
-  // Has OnHpackFragment() already been called for current HPACK block?
-  // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS
-  // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only
-  // padding). Detect that condition and replicate the behavior using this
-  // field.
-  bool on_hpack_fragment_called_ = false;
-
-  // Have we seen a frame header that appears to be an HTTP/1 response?
-  bool latched_probable_http_response_ = false;
-
-  // Is expected_frame_type_ set?
-  bool has_expected_frame_type_ = false;
-
-  // Is the current frame payload destined for |extension_|?
-  bool handling_extension_payload_ = false;
-};
-
-}  // namespace http2
-
-namespace spdy {
-
-// Http2DecoderAdapter will use the given visitor implementing this
-// interface to deliver event callbacks as frames are decoded.
-//
-// Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE)
-// are processed in fashion that allows the decompressed header block to be
-// delivered in chunks to the visitor.
-// The following steps are followed:
-//   1. OnHeaders, or OnPushPromise is called.
-//   2. OnHeaderFrameStart is called; visitor is expected to return an instance
-//      of SpdyHeadersHandlerInterface that will receive the header key-value
-//      pairs.
-//   3. OnHeaderFrameEnd is called, indicating that the full header block has
-//      been delivered for the control frame.
-// During step 2, if the visitor is not interested in accepting the header data,
-// it should return a no-op implementation of SpdyHeadersHandlerInterface.
-class QUICHE_EXPORT_PRIVATE SpdyFramerVisitorInterface {
- public:
-  virtual ~SpdyFramerVisitorInterface() {}
-
-  // Called if an error is detected in the SpdyFrame protocol.
-  virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
-                       std::string detailed_error) = 0;
-
-  // Called when the common header for a frame is received. Validating the
-  // common header occurs in later processing.
-  virtual void OnCommonHeader(SpdyStreamId /*stream_id*/,
-                              size_t /*length*/,
-                              uint8_t /*type*/,
-                              uint8_t /*flags*/) {}
-
-  // Called when a data frame header is received. The frame's data
-  // payload will be provided via subsequent calls to
-  // OnStreamFrameData().
-  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
-                                 size_t length,
-                                 bool fin) = 0;
-
-  // Called when data is received.
-  // |stream_id| The stream receiving data.
-  // |data| A buffer containing the data received.
-  // |len| The length of the data buffer.
-  virtual void OnStreamFrameData(SpdyStreamId stream_id,
-                                 const char* data,
-                                 size_t len) = 0;
-
-  // Called when the other side has finished sending data on this stream.
-  // |stream_id| The stream that was receiving data.
-  virtual void OnStreamEnd(SpdyStreamId stream_id) = 0;
-
-  // Called when padding length field is received on a DATA frame.
-  // |stream_id| The stream receiving data.
-  // |value| The value of the padding length field.
-  virtual void OnStreamPadLength(SpdyStreamId /*stream_id*/, size_t /*value*/) {
-  }
-
-  // Called when padding is received (the trailing octets, not pad_len field) on
-  // a DATA frame.
-  // |stream_id| The stream receiving data.
-  // |len| The number of padding octets.
-  virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;
-
-  // Called just before processing the payload of a frame containing header
-  // data. Should return an implementation of SpdyHeadersHandlerInterface that
-  // will receive headers for stream |stream_id|. The caller will not take
-  // ownership of the headers handler. The same instance should remain live
-  // and be returned for all header frames comprising a logical header block
-  // (i.e. until OnHeaderFrameEnd() is called).
-  virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      SpdyStreamId stream_id) = 0;
-
-  // Called after processing the payload of a frame containing header data.
-  virtual void OnHeaderFrameEnd(SpdyStreamId stream_id) = 0;
-
-  // Called when a RST_STREAM frame has been parsed.
-  virtual void OnRstStream(SpdyStreamId stream_id,
-                           SpdyErrorCode error_code) = 0;
-
-  // Called when a SETTINGS frame is received.
-  virtual void OnSettings() {}
-
-  // Called when a complete setting within a SETTINGS frame has been parsed.
-  // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
-  virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
-
-  // Called when a SETTINGS frame is received with the ACK flag set.
-  virtual void OnSettingsAck() {}
-
-  // Called before and after parsing SETTINGS id and value tuples.
-  virtual void OnSettingsEnd() = 0;
-
-  // Called when a PING frame has been parsed.
-  virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
-
-  // Called when a GOAWAY frame has been parsed.
-  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
-                        SpdyErrorCode error_code) = 0;
-
-  // Called when a HEADERS frame is received.
-  // Note that header block data is not included. See OnHeaderFrameStart().
-  // |stream_id| The stream receiving the header.
-  // |has_priority| Whether or not the headers frame included a priority value,
-  //     and stream dependency info.
-  // |weight| If |has_priority| is true, then weight (in the range [1, 256])
-  //     for the receiving stream, otherwise 0.
-  // |parent_stream_id| If |has_priority| is true the parent stream of the
-  //     receiving stream, else 0.
-  // |exclusive| If |has_priority| is true the exclusivity of dependence on the
-  //     parent stream, else false.
-  // |fin| Whether FIN flag is set in frame headers.
-  // |end| False if HEADERs frame is to be followed by a CONTINUATION frame,
-  //     or true if not.
-  virtual void OnHeaders(SpdyStreamId stream_id,
-                         bool has_priority,
-                         int weight,
-                         SpdyStreamId parent_stream_id,
-                         bool exclusive,
-                         bool fin,
-                         bool end) = 0;
-
-  // Called when a WINDOW_UPDATE frame has been parsed.
-  virtual void OnWindowUpdate(SpdyStreamId stream_id,
-                              int delta_window_size) = 0;
-
-  // Called when a goaway frame opaque data is available.
-  // |goaway_data| A buffer containing the opaque GOAWAY data chunk received.
-  // |len| The length of the header data buffer. A length of zero indicates
-  //       that the header data block has been completely sent.
-  // When this function returns true the visitor indicates that it accepted
-  // all of the data. Returning false indicates that that an error has
-  // occurred while processing the data. Default implementation returns true.
-  virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len);
-
-  // Called when a PUSH_PROMISE frame is received.
-  // Note that header block data is not included. See OnHeaderFrameStart().
-  virtual void OnPushPromise(SpdyStreamId stream_id,
-                             SpdyStreamId promised_stream_id,
-                             bool end) = 0;
-
-  // Called when a CONTINUATION frame is received.
-  // Note that header block data is not included. See OnHeaderFrameStart().
-  virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0;
-
-  // Called when an ALTSVC frame has been parsed.
-  virtual void OnAltSvc(
-      SpdyStreamId /*stream_id*/,
-      absl::string_view /*origin*/,
-      const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) {
-  }
-
-  // Called when a PRIORITY frame is received.
-  // |stream_id| The stream to update the priority of.
-  // |parent_stream_id| The parent stream of |stream_id|.
-  // |weight| Stream weight, in the range [1, 256].
-  // |exclusive| Whether |stream_id| should be an only child of
-  //     |parent_stream_id|.
-  virtual void OnPriority(SpdyStreamId stream_id,
-                          SpdyStreamId parent_stream_id,
-                          int weight,
-                          bool exclusive) = 0;
-
-  // Called when a PRIORITY_UPDATE frame is received on stream 0.
-  // |prioritized_stream_id| is the Prioritized Stream ID and
-  // |priority_field_value| is the Priority Field Value
-  // parsed from the frame payload.
-  virtual void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
-                                absl::string_view priority_field_value) = 0;
-
-  // Called when a frame type we don't recognize is received.
-  // Return true if this appears to be a valid extension frame, false otherwise.
-  // We distinguish between extension frames and nonsense by checking
-  // whether the stream id is valid.
-  virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0;
-};
-
-class QUICHE_EXPORT_PRIVATE ExtensionVisitorInterface {
- public:
-  virtual ~ExtensionVisitorInterface() {}
-
-  // Called when non-standard SETTINGS are received.
-  virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
-
-  // Called when non-standard frames are received.
-  virtual bool OnFrameHeader(SpdyStreamId stream_id,
-                             size_t length,
-                             uint8_t type,
-                             uint8_t flags) = 0;
-
-  // The payload for a single frame may be delivered as multiple calls to
-  // OnFramePayload. Since the length field is passed in OnFrameHeader, there is
-  // no explicit indication of the end of the frame payload.
-  virtual void OnFramePayload(const char* data, size_t len) = 0;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
diff --git a/spdy/core/http2_header_block_hpack_listener.h b/spdy/core/http2_header_block_hpack_listener.h
deleted file mode 100644
index 19352e5..0000000
--- a/spdy/core/http2_header_block_hpack_listener.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_HPACK_LISTENER_H_
-#define QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_HPACK_LISTENER_H_
-
-#include "absl/strings/string_view.h"
-#include "http2/hpack/decoder/hpack_decoder_listener.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace spdy {
-
-// This class simply gathers the key-value pairs emitted by an HpackDecoder in
-// a SpdyHeaderBlock.
-class Http2HeaderBlockHpackListener : public http2::HpackDecoderListener {
- public:
-  Http2HeaderBlockHpackListener() {}
-
-  void OnHeaderListStart() override {
-    header_block_.clear();
-    hpack_error_ = false;
-  }
-
-  void OnHeader(const std::string& name, const std::string& value) override {
-    header_block_.AppendValueOrAddHeader(name, value);
-  }
-
-  void OnHeaderListEnd() override {}
-
-  void OnHeaderErrorDetected(absl::string_view error_message) override {
-    QUICHE_VLOG(1) << error_message;
-    hpack_error_ = true;
-  }
-
-  SpdyHeaderBlock release_header_block() {
-    SpdyHeaderBlock block = std::move(header_block_);
-    header_block_ = {};
-    return block;
-  }
-  bool hpack_error() const { return hpack_error_; }
-
- private:
-  SpdyHeaderBlock header_block_;
-  bool hpack_error_ = false;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_HPACK_LISTENER_H_
diff --git a/spdy/core/metadata_extension.cc b/spdy/core/metadata_extension.cc
deleted file mode 100644
index 1683dcc..0000000
--- a/spdy/core/metadata_extension.cc
+++ /dev/null
@@ -1,195 +0,0 @@
-#include "spdy/core/metadata_extension.h"
-
-#include <list>
-#include <string>
-
-#include "absl/memory/memory.h"
-#include "absl/strings/str_cat.h"
-#include "http2/decoder/decode_buffer.h"
-#include "http2/hpack/decoder/hpack_decoder.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-#include "spdy/core/http2_header_block_hpack_listener.h"
-
-namespace spdy {
-
-// Non-standard constants related to METADATA frames.
-const SpdySettingsId MetadataVisitor::kMetadataExtensionId = 0x4d44;
-const uint8_t MetadataVisitor::kMetadataFrameType = 0x4d;
-const uint8_t MetadataVisitor::kEndMetadataFlag = 0x4;
-
-namespace {
-
-const size_t kMaxMetadataBlockSize = 1 << 20;  // 1 MB
-
-// This class uses an HpackEncoder to serialize a METADATA block as a series of
-// METADATA frames.
-class MetadataFrameSequence : public MetadataSerializer::FrameSequence {
- public:
-  MetadataFrameSequence(SpdyStreamId stream_id, spdy::SpdyHeaderBlock payload)
-      : stream_id_(stream_id), payload_(std::move(payload)) {
-    // Metadata should not use HPACK compression.
-    encoder_.DisableCompression();
-    HpackEncoder::Representations r;
-    for (const auto& kv_pair : payload_) {
-      r.push_back(kv_pair);
-    }
-    progressive_encoder_ = encoder_.EncodeRepresentations(r);
-  }
-
-  // Copies are not allowed.
-  MetadataFrameSequence(const MetadataFrameSequence& other) = delete;
-  MetadataFrameSequence& operator=(const MetadataFrameSequence& other) = delete;
-
-  std::unique_ptr<spdy::SpdyFrameIR> Next() override;
-
- private:
-  SpdyStreamId stream_id_;
-  SpdyHeaderBlock payload_;
-  HpackEncoder encoder_;
-  std::unique_ptr<HpackEncoder::ProgressiveEncoder> progressive_encoder_;
-};
-
-std::unique_ptr<spdy::SpdyFrameIR> MetadataFrameSequence::Next() {
-  if (!progressive_encoder_->HasNext()) {
-    return nullptr;
-  }
-  // METADATA frames obey the HTTP/2 maximum frame size.
-  std::string payload =
-      progressive_encoder_->Next(spdy::kHttp2DefaultFramePayloadLimit);
-  const bool end_metadata = (!progressive_encoder_->HasNext());
-  const uint8_t flags = end_metadata ? MetadataVisitor::kEndMetadataFlag : 0;
-  return absl::make_unique<spdy::SpdyUnknownIR>(
-      stream_id_, MetadataVisitor::kMetadataFrameType, flags,
-      std::move(payload));
-}
-
-}  // anonymous namespace
-
-struct MetadataVisitor::MetadataPayloadState {
-  MetadataPayloadState(size_t remaining, bool end)
-      : bytes_remaining(remaining), end_metadata(end) {}
-  std::list<std::string> buffer;
-  size_t bytes_remaining;
-  bool end_metadata;
-};
-
-MetadataVisitor::MetadataVisitor(OnCompletePayload on_payload,
-                                 OnMetadataSupport on_support)
-    : on_payload_(std::move(on_payload)),
-      on_support_(std::move(on_support)),
-      peer_supports_metadata_(MetadataSupportState::UNSPECIFIED) {}
-
-MetadataVisitor::~MetadataVisitor() {}
-
-void MetadataVisitor::OnSetting(SpdySettingsId id, uint32_t value) {
-  QUICHE_VLOG(1) << "MetadataVisitor::OnSetting(" << id << ", " << value << ")";
-  if (id == kMetadataExtensionId) {
-    if (value == 0) {
-      const MetadataSupportState previous_state = peer_supports_metadata_;
-      peer_supports_metadata_ = MetadataSupportState::NOT_SUPPORTED;
-      if (previous_state == MetadataSupportState::UNSPECIFIED ||
-          previous_state == MetadataSupportState::SUPPORTED) {
-        on_support_(false);
-      }
-    } else if (value == 1) {
-      const MetadataSupportState previous_state = peer_supports_metadata_;
-      peer_supports_metadata_ = MetadataSupportState::SUPPORTED;
-      if (previous_state == MetadataSupportState::UNSPECIFIED ||
-          previous_state == MetadataSupportState::NOT_SUPPORTED) {
-        on_support_(true);
-      }
-    } else {
-      LOG_EVERY_N_SEC(WARNING, 1)
-          << "Unrecognized value for setting " << id << ": " << value;
-    }
-  }
-}
-
-bool MetadataVisitor::OnFrameHeader(SpdyStreamId stream_id, size_t length,
-                                    uint8_t type, uint8_t flags) {
-  QUICHE_VLOG(1) << "OnFrameHeader(stream_id=" << stream_id
-                 << ", length=" << length << ", type=" << static_cast<int>(type)
-                 << ", flags=" << static_cast<int>(flags);
-  // TODO(birenroy): Consider disabling METADATA handling until our setting
-  // advertising METADATA support has been acked.
-  if (type != kMetadataFrameType) {
-    return false;
-  }
-  auto it = metadata_map_.find(stream_id);
-  if (it == metadata_map_.end()) {
-    auto state = absl::make_unique<MetadataPayloadState>(
-        length, flags & kEndMetadataFlag);
-    auto result = metadata_map_.insert(std::make_pair(stream_id,
-                                                      std::move(state)));
-    QUICHE_BUG_IF(bug_if_2781_1, !result.second) << "Map insertion failed.";
-    it = result.first;
-  } else {
-    QUICHE_BUG_IF(bug_22051_1, it->second->end_metadata)
-        << "Inconsistent metadata payload state!";
-    QUICHE_BUG_IF(bug_if_2781_2, it->second->bytes_remaining > 0)
-        << "Incomplete metadata block!";
-  }
-
-  if (it->second == nullptr) {
-    QUICHE_BUG(bug_2781_3) << "Null metadata payload state!";
-    return false;
-  }
-  current_stream_ = stream_id;
-  it->second->bytes_remaining = length;
-  it->second->end_metadata = (flags & kEndMetadataFlag);
-  return true;
-}
-
-void MetadataVisitor::OnFramePayload(const char* data, size_t len) {
-  QUICHE_VLOG(1) << "OnFramePayload(stream_id=" << current_stream_
-                 << ", len=" << len << ")";
-  auto it = metadata_map_.find(current_stream_);
-  if (it == metadata_map_.end() || it->second == nullptr) {
-    QUICHE_BUG(bug_2781_4) << "Invalid order of operations on MetadataVisitor.";
-  } else {
-    MetadataPayloadState* state = it->second.get();  // For readability.
-    state->buffer.push_back(std::string(data, len));
-    if (len < state->bytes_remaining) {
-      state->bytes_remaining -= len;
-    } else {
-      QUICHE_BUG_IF(bug_22051_2, len > state->bytes_remaining)
-          << "Metadata payload overflow! len: " << len
-          << " bytes_remaining: " << state->bytes_remaining;
-      state->bytes_remaining = 0;
-      if (state->end_metadata) {
-        // The whole process of decoding the HPACK-encoded metadata block,
-        // below, is more cumbersome than it ought to be.
-        spdy::Http2HeaderBlockHpackListener listener;
-        http2::HpackDecoder decoder(&listener, kMaxMetadataBlockSize);
-
-        // If any operations fail, the decode process should be aborted.
-        bool success = decoder.StartDecodingBlock();
-        for (const std::string& slice : state->buffer) {
-          if (!success) {
-            break;
-          }
-          http2::DecodeBuffer buffer(slice.data(), slice.size());
-          success = success && decoder.DecodeFragment(&buffer);
-        }
-        success =
-            success && decoder.EndDecodingBlock() && !listener.hpack_error();
-        if (success) {
-          on_payload_(current_stream_, listener.release_header_block());
-        }
-        // TODO(birenroy): add varz counting metadata decode successes/failures.
-        metadata_map_.erase(it);
-      }
-    }
-  }
-}
-
-std::unique_ptr<MetadataSerializer::FrameSequence>
-MetadataSerializer::FrameSequenceForPayload(SpdyStreamId stream_id,
-                                            MetadataPayload payload) {
-  return absl::make_unique<MetadataFrameSequence>(stream_id,
-                                                  std::move(payload));
-}
-
-}  // namespace spdy
diff --git a/spdy/core/metadata_extension.h b/spdy/core/metadata_extension.h
deleted file mode 100644
index 043d6f0..0000000
--- a/spdy/core/metadata_extension.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
-#define QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/zero_copy_output_buffer.h"
-
-namespace spdy {
-
-// An implementation of the ExtensionVisitorInterface that can parse
-// METADATA frames. METADATA is a non-standard HTTP/2 extension developed and
-// used internally at Google. A peer advertises support for METADATA by sending
-// a setting with a setting ID of kMetadataExtensionId and a value of 1.
-//
-// Metadata is represented as a HPACK header block with literal encoding.
-class MetadataVisitor : public spdy::ExtensionVisitorInterface {
- public:
-  using MetadataPayload = spdy::SpdyHeaderBlock;
-
-  static_assert(!std::is_copy_constructible<MetadataPayload>::value,
-                "MetadataPayload should be a move-only type!");
-
-  using OnMetadataSupport = std::function<void(bool)>;
-  using OnCompletePayload =
-      std::function<void(spdy::SpdyStreamId, MetadataPayload)>;
-
-  // The HTTP/2 SETTINGS ID that is used to indicate support for METADATA
-  // frames.
-  static const spdy::SpdySettingsId kMetadataExtensionId;
-
-  // The 8-bit frame type code for a METADATA frame.
-  static const uint8_t kMetadataFrameType;
-
-  // The flag that indicates the end of a logical metadata block. Due to frame
-  // size limits, a single metadata block may be emitted as several HTTP/2
-  // frames.
-  static const uint8_t kEndMetadataFlag;
-
-  // |on_payload| is invoked whenever a complete metadata payload is received.
-  // |on_support| is invoked whenever the peer's advertised support for metadata
-  // changes.
-  MetadataVisitor(OnCompletePayload on_payload, OnMetadataSupport on_support);
-  ~MetadataVisitor() override;
-
-  MetadataVisitor(const MetadataVisitor&) = delete;
-  MetadataVisitor& operator=(const MetadataVisitor&) = delete;
-
-  // Interprets the non-standard setting indicating support for METADATA.
-  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
-
-  // Returns true iff |type| indicates a METADATA frame.
-  bool OnFrameHeader(spdy::SpdyStreamId stream_id, size_t length, uint8_t type,
-                     uint8_t flags) override;
-
-  // Consumes a METADATA frame payload. Invokes the registered callback when a
-  // complete payload has been received.
-  void OnFramePayload(const char* data, size_t len) override;
-
-  // Returns true if the peer has advertised support for METADATA via the
-  // appropriate setting.
-  bool PeerSupportsMetadata() const {
-    return peer_supports_metadata_ == MetadataSupportState::SUPPORTED;
-  }
-
- private:
-  enum class MetadataSupportState : uint8_t {
-    UNSPECIFIED,
-    SUPPORTED,
-    NOT_SUPPORTED,
-  };
-
-  struct MetadataPayloadState;
-
-  using StreamMetadataMap =
-      absl::flat_hash_map<spdy::SpdyStreamId,
-                          std::unique_ptr<MetadataPayloadState>>;
-
-  OnCompletePayload on_payload_;
-  OnMetadataSupport on_support_;
-  StreamMetadataMap metadata_map_;
-  spdy::SpdyStreamId current_stream_;
-  MetadataSupportState peer_supports_metadata_;
-};
-
-// A class that serializes metadata blocks as sequences of frames.
-class MetadataSerializer {
- public:
-  using MetadataPayload = spdy::SpdyHeaderBlock;
-
-  class FrameSequence {
-   public:
-    virtual ~FrameSequence() {}
-
-    // Returns nullptr once the sequence has been exhausted.
-    virtual std::unique_ptr<spdy::SpdyFrameIR> Next() = 0;
-  };
-
-  MetadataSerializer() {}
-
-  MetadataSerializer(const MetadataSerializer&) = delete;
-  MetadataSerializer& operator=(const MetadataSerializer&) = delete;
-
-  // Returns nullptr on failure.
-  std::unique_ptr<FrameSequence> FrameSequenceForPayload(
-      spdy::SpdyStreamId stream_id, MetadataPayload payload);
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_METADATA_EXTENSION_H_
diff --git a/spdy/core/metadata_extension_test.cc b/spdy/core/metadata_extension_test.cc
deleted file mode 100644
index 9c0ea73..0000000
--- a/spdy/core/metadata_extension_test.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-#include "spdy/core/metadata_extension.h"
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/functional/bind_front.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/array_output_buffer.h"
-#include "spdy/core/mock_spdy_framer_visitor.h"
-#include "spdy/core/spdy_framer.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_no_op_visitor.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace spdy {
-namespace test {
-namespace {
-
-using ::absl::bind_front;
-using ::spdy::SpdyFramer;
-using ::spdy::SpdyHeaderBlock;
-using ::spdy::test::MockSpdyFramerVisitor;
-using ::testing::_;
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-const size_t kBufferSize = 64 * 1024;
-char kBuffer[kBufferSize];
-
-class MetadataExtensionTest : public QuicheTest {
- protected:
-  MetadataExtensionTest() : test_buffer_(kBuffer, kBufferSize) {}
-
-  void SetUp() override {
-    extension_ = absl::make_unique<MetadataVisitor>(
-        bind_front(&MetadataExtensionTest::OnCompletePayload, this),
-        bind_front(&MetadataExtensionTest::OnMetadataSupport, this));
-  }
-
-  void OnCompletePayload(spdy::SpdyStreamId stream_id,
-                         MetadataVisitor::MetadataPayload payload) {
-    ++received_count_;
-    received_payload_map_.insert(std::make_pair(stream_id, std::move(payload)));
-  }
-
-  void OnMetadataSupport(bool peer_supports_metadata) {
-    EXPECT_EQ(peer_supports_metadata, extension_->PeerSupportsMetadata());
-    received_metadata_support_.push_back(peer_supports_metadata);
-  }
-
-  MetadataSerializer::MetadataPayload PayloadForData(absl::string_view data) {
-    SpdyHeaderBlock block;
-    block["example-payload"] = data;
-    return block;
-  }
-
-  std::unique_ptr<MetadataVisitor> extension_;
-  absl::flat_hash_map<spdy::SpdyStreamId, SpdyHeaderBlock>
-      received_payload_map_;
-  std::vector<bool> received_metadata_support_;
-  size_t received_count_ = 0;
-  spdy::ArrayOutputBuffer test_buffer_;
-};
-
-// This test verifies that the MetadataVisitor is initialized to a state where
-// it believes the peer does not support metadata.
-TEST_F(MetadataExtensionTest, MetadataNotSupported) {
-  EXPECT_FALSE(extension_->PeerSupportsMetadata());
-  EXPECT_THAT(received_metadata_support_, IsEmpty());
-}
-
-// This test verifies that upon receiving a specific setting, the extension
-// realizes that the peer supports metadata.
-TEST_F(MetadataExtensionTest, MetadataSupported) {
-  EXPECT_FALSE(extension_->PeerSupportsMetadata());
-  // 3 is not an appropriate value for the metadata extension key.
-  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 3);
-  EXPECT_FALSE(extension_->PeerSupportsMetadata());
-  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
-  ASSERT_TRUE(extension_->PeerSupportsMetadata());
-  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 0);
-  EXPECT_FALSE(extension_->PeerSupportsMetadata());
-  EXPECT_THAT(received_metadata_support_, ElementsAre(true, false));
-}
-
-TEST_F(MetadataExtensionTest, MetadataIgnoredWithoutExtension) {
-  const char kData[] = "some payload";
-  SpdyHeaderBlock payload = PayloadForData(kData);
-
-  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
-  ASSERT_TRUE(extension_->PeerSupportsMetadata());
-
-  MetadataSerializer serializer;
-  auto sequence = serializer.FrameSequenceForPayload(3, std::move(payload));
-  ASSERT_TRUE(sequence != nullptr);
-
-  http2::Http2DecoderAdapter deframer;
-  ::testing::StrictMock<MockSpdyFramerVisitor> visitor;
-  deframer.set_visitor(&visitor);
-
-  EXPECT_CALL(visitor,
-              OnCommonHeader(3, _, MetadataVisitor::kMetadataFrameType, _));
-  // The Return(true) should not be necessary. http://b/36023792
-  EXPECT_CALL(visitor, OnUnknownFrame(3, MetadataVisitor::kMetadataFrameType))
-      .WillOnce(::testing::Return(true));
-
-  SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-  auto frame = sequence->Next();
-  ASSERT_TRUE(frame != nullptr);
-  while (frame != nullptr) {
-    const size_t frame_size = framer.SerializeFrame(*frame, &test_buffer_);
-    ASSERT_GT(frame_size, 0u);
-    ASSERT_FALSE(deframer.HasError());
-    ASSERT_EQ(frame_size, test_buffer_.Size());
-    EXPECT_EQ(frame_size, deframer.ProcessInput(kBuffer, frame_size));
-    test_buffer_.Reset();
-    frame = sequence->Next();
-  }
-  EXPECT_FALSE(deframer.HasError());
-  EXPECT_THAT(received_metadata_support_, ElementsAre(true));
-}
-
-// This test verifies that the METADATA frame emitted by a MetadataExtension
-// can be parsed by another SpdyFramer with a MetadataVisitor.
-TEST_F(MetadataExtensionTest, MetadataPayloadEndToEnd) {
-  SpdyHeaderBlock block1;
-  block1["foo"] = "Some metadata value.";
-  SpdyHeaderBlock block2;
-  block2["bar"] =
-      "The color taupe truly represents a triumph of the human spirit over "
-      "adversity.";
-  block2["baz"] =
-      "Or perhaps it represents abject surrender to the implacable and "
-      "incomprehensible forces of the universe.";
-  const absl::string_view binary_payload{"binary\0payload", 14};
-  block2["qux"] = binary_payload;
-  EXPECT_EQ(binary_payload, block2["qux"]);
-  for (const SpdyHeaderBlock& payload_block :
-       {std::move(block1), std::move(block2)}) {
-    extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
-    ASSERT_TRUE(extension_->PeerSupportsMetadata());
-
-    MetadataSerializer serializer;
-    auto sequence =
-        serializer.FrameSequenceForPayload(3, payload_block.Clone());
-    ASSERT_TRUE(sequence != nullptr);
-
-    http2::Http2DecoderAdapter deframer;
-    ::spdy::SpdyNoOpVisitor visitor;
-    deframer.set_visitor(&visitor);
-    deframer.set_extension_visitor(extension_.get());
-    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-    auto frame = sequence->Next();
-    ASSERT_TRUE(frame != nullptr);
-    while (frame != nullptr) {
-      const size_t frame_size = framer.SerializeFrame(*frame, &test_buffer_);
-      ASSERT_GT(frame_size, 0u);
-      ASSERT_FALSE(deframer.HasError());
-      ASSERT_EQ(frame_size, test_buffer_.Size());
-      EXPECT_EQ(frame_size, deframer.ProcessInput(kBuffer, frame_size));
-      test_buffer_.Reset();
-      frame = sequence->Next();
-    }
-    EXPECT_EQ(1u, received_count_);
-    auto it = received_payload_map_.find(3);
-    ASSERT_TRUE(it != received_payload_map_.end());
-    EXPECT_EQ(payload_block, it->second);
-
-    received_count_ = 0;
-    received_payload_map_.clear();
-  }
-}
-
-// This test verifies that METADATA frames for two different streams can be
-// interleaved and still successfully parsed by another SpdyFramer with a
-// MetadataVisitor.
-TEST_F(MetadataExtensionTest, MetadataPayloadInterleaved) {
-  const std::string kData1 = std::string(65 * 1024, 'a');
-  const std::string kData2 = std::string(65 * 1024, 'b');
-  const SpdyHeaderBlock payload1 = PayloadForData(kData1);
-  const SpdyHeaderBlock payload2 = PayloadForData(kData2);
-
-  extension_->OnSetting(MetadataVisitor::kMetadataExtensionId, 1);
-  ASSERT_TRUE(extension_->PeerSupportsMetadata());
-
-  MetadataSerializer serializer;
-  auto sequence1 = serializer.FrameSequenceForPayload(3, payload1.Clone());
-  ASSERT_TRUE(sequence1 != nullptr);
-
-  auto sequence2 = serializer.FrameSequenceForPayload(5, payload2.Clone());
-  ASSERT_TRUE(sequence2 != nullptr);
-
-  http2::Http2DecoderAdapter deframer;
-  ::spdy::SpdyNoOpVisitor visitor;
-  deframer.set_visitor(&visitor);
-  deframer.set_extension_visitor(extension_.get());
-
-  SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-  auto frame1 = sequence1->Next();
-  ASSERT_TRUE(frame1 != nullptr);
-  auto frame2 = sequence2->Next();
-  ASSERT_TRUE(frame2 != nullptr);
-  while (frame1 != nullptr || frame2 != nullptr) {
-    for (auto frame : {frame1.get(), frame2.get()}) {
-      if (frame != nullptr) {
-        const size_t frame_size = framer.SerializeFrame(*frame, &test_buffer_);
-        ASSERT_GT(frame_size, 0u);
-        ASSERT_FALSE(deframer.HasError());
-        ASSERT_EQ(frame_size, test_buffer_.Size());
-        EXPECT_EQ(frame_size, deframer.ProcessInput(kBuffer, frame_size));
-        test_buffer_.Reset();
-      }
-    }
-    frame1 = sequence1->Next();
-    frame2 = sequence2->Next();
-  }
-  EXPECT_EQ(2u, received_count_);
-  auto it = received_payload_map_.find(3);
-  ASSERT_TRUE(it != received_payload_map_.end());
-  EXPECT_EQ(payload1, it->second);
-
-  it = received_payload_map_.find(5);
-  ASSERT_TRUE(it != received_payload_map_.end());
-  EXPECT_EQ(payload2, it->second);
-}
-
-}  // anonymous namespace
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/mock_spdy_framer_visitor.cc b/spdy/core/mock_spdy_framer_visitor.cc
deleted file mode 100644
index df1de42..0000000
--- a/spdy/core/mock_spdy_framer_visitor.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/mock_spdy_framer_visitor.h"
-
-namespace spdy {
-
-namespace test {
-
-MockSpdyFramerVisitor::MockSpdyFramerVisitor() {
-  DelegateHeaderHandling();
-}
-
-MockSpdyFramerVisitor::~MockSpdyFramerVisitor() = default;
-
-}  // namespace test
-
-}  // namespace spdy
diff --git a/spdy/core/mock_spdy_framer_visitor.h b/spdy/core/mock_spdy_framer_visitor.h
deleted file mode 100644
index 744072f..0000000
--- a/spdy/core/mock_spdy_framer_visitor.h
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
-#define QUICHE_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
-
-#include <cstdint>
-#include <memory>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/recording_headers_handler.h"
-#include "spdy/core/spdy_test_utils.h"
-
-namespace spdy {
-
-namespace test {
-
-class QUICHE_NO_EXPORT MockSpdyFramerVisitor
-    : public SpdyFramerVisitorInterface {
- public:
-  MockSpdyFramerVisitor();
-  ~MockSpdyFramerVisitor() override;
-
-  MOCK_METHOD(void,
-              OnError,
-              (http2::Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error),
-              (override));
-  MOCK_METHOD(void, OnCommonHeader,
-              (SpdyStreamId stream_id, size_t length, uint8_t type,
-               uint8_t flags),
-              (override));
-  MOCK_METHOD(void,
-              OnDataFrameHeader,
-              (SpdyStreamId stream_id, size_t length, bool fin),
-              (override));
-  MOCK_METHOD(void,
-              OnStreamFrameData,
-              (SpdyStreamId stream_id, const char* data, size_t len),
-              (override));
-  MOCK_METHOD(void, OnStreamEnd, (SpdyStreamId stream_id), (override));
-  MOCK_METHOD(void,
-              OnStreamPadLength,
-              (SpdyStreamId stream_id, size_t value),
-              (override));
-  MOCK_METHOD(void,
-              OnStreamPadding,
-              (SpdyStreamId stream_id, size_t len),
-              (override));
-  MOCK_METHOD(SpdyHeadersHandlerInterface*,
-              OnHeaderFrameStart,
-              (SpdyStreamId stream_id),
-              (override));
-  MOCK_METHOD(void, OnHeaderFrameEnd, (SpdyStreamId stream_id), (override));
-  MOCK_METHOD(void,
-              OnRstStream,
-              (SpdyStreamId stream_id, SpdyErrorCode error_code),
-              (override));
-  MOCK_METHOD(void, OnSettings, (), (override));
-  MOCK_METHOD(void, OnSetting, (SpdySettingsId id, uint32_t value), (override));
-  MOCK_METHOD(void, OnPing, (SpdyPingId unique_id, bool is_ack), (override));
-  MOCK_METHOD(void, OnSettingsEnd, (), (override));
-  MOCK_METHOD(void, OnSettingsAck, (), (override));
-  MOCK_METHOD(void,
-              OnGoAway,
-              (SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
-              (override));
-  MOCK_METHOD(bool, OnGoAwayFrameData, (const char* goaway_data, size_t len),
-              (override));
-  MOCK_METHOD(void,
-              OnHeaders,
-              (SpdyStreamId stream_id,
-               bool has_priority,
-               int weight,
-               SpdyStreamId parent_stream_id,
-               bool exclusive,
-               bool fin,
-               bool end),
-              (override));
-  MOCK_METHOD(void,
-              OnWindowUpdate,
-              (SpdyStreamId stream_id, int delta_window_size),
-              (override));
-  MOCK_METHOD(void,
-              OnPushPromise,
-              (SpdyStreamId stream_id,
-               SpdyStreamId promised_stream_id,
-               bool end),
-              (override));
-  MOCK_METHOD(void,
-              OnContinuation,
-              (SpdyStreamId stream_id, bool end),
-              (override));
-  MOCK_METHOD(
-      void,
-      OnAltSvc,
-      (SpdyStreamId stream_id,
-       absl::string_view origin,
-       const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector),
-      (override));
-  MOCK_METHOD(void,
-              OnPriority,
-              (SpdyStreamId stream_id,
-               SpdyStreamId parent_stream_id,
-               int weight,
-               bool exclusive),
-              (override));
-  MOCK_METHOD(void,
-              OnPriorityUpdate,
-              (SpdyStreamId prioritized_stream_id,
-               absl::string_view priority_field_value),
-              (override));
-  MOCK_METHOD(bool,
-              OnUnknownFrame,
-              (SpdyStreamId stream_id, uint8_t frame_type),
-              (override));
-
-  void DelegateHeaderHandling() {
-    ON_CALL(*this, OnHeaderFrameStart(testing::_))
-        .WillByDefault(testing::Invoke(
-            this, &MockSpdyFramerVisitor::ReturnTestHeadersHandler));
-    ON_CALL(*this, OnHeaderFrameEnd(testing::_))
-        .WillByDefault(testing::Invoke(
-            this, &MockSpdyFramerVisitor::ResetTestHeadersHandler));
-  }
-
-  SpdyHeadersHandlerInterface* ReturnTestHeadersHandler(
-      SpdyStreamId /* stream_id */) {
-    if (headers_handler_ == nullptr) {
-      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-    }
-    return headers_handler_.get();
-  }
-
-  void ResetTestHeadersHandler(SpdyStreamId /* stream_id */) {
-    headers_handler_.reset();
-  }
-
-  std::unique_ptr<SpdyHeadersHandlerInterface> headers_handler_;
-};
-
-}  // namespace test
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
diff --git a/spdy/core/no_op_headers_handler.h b/spdy/core/no_op_headers_handler.h
deleted file mode 100644
index 8c99459..0000000
--- a/spdy/core/no_op_headers_handler.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef QUICHE_SPDY_CORE_NO_OP_HEADERS_HANDLER_H_
-#define QUICHE_SPDY_CORE_NO_OP_HEADERS_HANDLER_H_
-
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/header_byte_listener_interface.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-
-namespace spdy {
-
-// Drops all header data, but passes information about header bytes parsed to
-// a listener.
-class QUICHE_EXPORT_PRIVATE NoOpHeadersHandler
-    : public SpdyHeadersHandlerInterface {
- public:
-  // Does not take ownership of listener.
-  explicit NoOpHeadersHandler(HeaderByteListenerInterface* listener)
-      : listener_(listener) {}
-  NoOpHeadersHandler(const NoOpHeadersHandler&) = delete;
-  NoOpHeadersHandler& operator=(const NoOpHeadersHandler&) = delete;
-  ~NoOpHeadersHandler() override {}
-
-  // From SpdyHeadersHandlerInterface
-  void OnHeaderBlockStart() override {}
-  void OnHeader(absl::string_view /*key*/,
-                absl::string_view /*value*/) override {}
-  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
-                        size_t /* compressed_header_bytes */) override {
-    if (listener_ != nullptr) {
-      listener_->OnHeaderBytesReceived(uncompressed_header_bytes);
-    }
-  }
-
- private:
-  HeaderByteListenerInterface* listener_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_NO_OP_HEADERS_HANDLER_H_
diff --git a/spdy/core/recording_headers_handler.cc b/spdy/core/recording_headers_handler.cc
deleted file mode 100644
index 9136dba..0000000
--- a/spdy/core/recording_headers_handler.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/recording_headers_handler.h"
-
-namespace spdy {
-
-RecordingHeadersHandler::RecordingHeadersHandler(
-    SpdyHeadersHandlerInterface* wrapped)
-    : wrapped_(wrapped) {}
-
-void RecordingHeadersHandler::OnHeaderBlockStart() {
-  block_.clear();
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHeaderBlockStart();
-  }
-}
-
-void RecordingHeadersHandler::OnHeader(absl::string_view key,
-                                       absl::string_view value) {
-  block_.AppendValueOrAddHeader(key, value);
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHeader(key, value);
-  }
-}
-
-void RecordingHeadersHandler::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
-                                               size_t compressed_header_bytes) {
-  uncompressed_header_bytes_ = uncompressed_header_bytes;
-  compressed_header_bytes_ = compressed_header_bytes;
-  if (wrapped_ != nullptr) {
-    wrapped_->OnHeaderBlockEnd(uncompressed_header_bytes,
-                               compressed_header_bytes);
-  }
-}
-
-}  // namespace spdy
diff --git a/spdy/core/recording_headers_handler.h b/spdy/core/recording_headers_handler.h
deleted file mode 100644
index eafa1c7..0000000
--- a/spdy/core/recording_headers_handler.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
-#define QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-
-namespace spdy {
-
-// RecordingHeadersHandler copies the headers emitted from the deframer, and
-// when needed can forward events to another wrapped handler.
-class QUICHE_EXPORT_PRIVATE RecordingHeadersHandler
-    : public SpdyHeadersHandlerInterface {
- public:
-  explicit RecordingHeadersHandler(
-      SpdyHeadersHandlerInterface* wrapped = nullptr);
-  RecordingHeadersHandler(const RecordingHeadersHandler&) = delete;
-  RecordingHeadersHandler& operator=(const RecordingHeadersHandler&) = delete;
-
-  void OnHeaderBlockStart() override;
-
-  void OnHeader(absl::string_view key, absl::string_view value) override;
-
-  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
-                        size_t compressed_header_bytes) override;
-
-  const Http2HeaderBlock& decoded_block() const { return block_; }
-  size_t uncompressed_header_bytes() const {
-    return uncompressed_header_bytes_;
-  }
-  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
-
- private:
-  SpdyHeadersHandlerInterface* wrapped_ = nullptr;
-  Http2HeaderBlock block_;
-  size_t uncompressed_header_bytes_ = 0;
-  size_t compressed_header_bytes_ = 0;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
diff --git a/spdy/core/spdy_alt_svc_wire_format.cc b/spdy/core/spdy_alt_svc_wire_format.cc
deleted file mode 100644
index de37a12..0000000
--- a/spdy/core/spdy_alt_svc_wire_format.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-
-#include <algorithm>
-#include <cctype>
-#include <limits>
-
-#include "absl/strings/str_cat.h"
-
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-
-namespace {
-
-template <class T>
-bool ParsePositiveIntegerImpl(absl::string_view::const_iterator c,
-                              absl::string_view::const_iterator end,
-                              T* value) {
-  *value = 0;
-  for (; c != end && std::isdigit(*c); ++c) {
-    if (*value > std::numeric_limits<T>::max() / 10) {
-      return false;
-    }
-    *value *= 10;
-    if (*value > std::numeric_limits<T>::max() - (*c - '0')) {
-      return false;
-    }
-    *value += *c - '0';
-  }
-  return (c == end && *value > 0);
-}
-
-}  // namespace
-
-SpdyAltSvcWireFormat::AlternativeService::AlternativeService() = default;
-
-SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
-    const std::string& protocol_id, const std::string& host, uint16_t port,
-    uint32_t max_age_seconds, VersionVector version)
-    : protocol_id(protocol_id),
-      host(host),
-      port(port),
-      max_age_seconds(max_age_seconds),
-      version(std::move(version)) {}
-
-SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() = default;
-
-SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
-    const AlternativeService& other) = default;
-
-// static
-bool SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-    absl::string_view value,
-    AlternativeServiceVector* altsvc_vector) {
-  // Empty value is invalid according to the specification.
-  if (value.empty()) {
-    return false;
-  }
-  altsvc_vector->clear();
-  if (value == absl::string_view("clear")) {
-    return true;
-  }
-  absl::string_view::const_iterator c = value.begin();
-  while (c != value.end()) {
-    // Parse protocol-id.
-    absl::string_view::const_iterator percent_encoded_protocol_id_end =
-        std::find(c, value.end(), '=');
-    std::string protocol_id;
-    if (percent_encoded_protocol_id_end == c ||
-        !PercentDecode(c, percent_encoded_protocol_id_end, &protocol_id)) {
-      return false;
-    }
-    // Check for IETF format for advertising QUIC:
-    // hq=":443";quic=51303338;quic=51303334
-    const bool is_ietf_format_quic = (protocol_id == "hq");
-    c = percent_encoded_protocol_id_end;
-    if (c == value.end()) {
-      return false;
-    }
-    // Parse alt-authority.
-    QUICHE_DCHECK_EQ('=', *c);
-    ++c;
-    if (c == value.end() || *c != '"') {
-      return false;
-    }
-    ++c;
-    absl::string_view::const_iterator alt_authority_begin = c;
-    for (; c != value.end() && *c != '"'; ++c) {
-      // Decode backslash encoding.
-      if (*c != '\\') {
-        continue;
-      }
-      ++c;
-      if (c == value.end()) {
-        return false;
-      }
-    }
-    if (c == alt_authority_begin || c == value.end()) {
-      return false;
-    }
-    QUICHE_DCHECK_EQ('"', *c);
-    std::string host;
-    uint16_t port;
-    if (!ParseAltAuthority(alt_authority_begin, c, &host, &port)) {
-      return false;
-    }
-    ++c;
-    // Parse parameters.
-    uint32_t max_age_seconds = 86400;
-    VersionVector version;
-    absl::string_view::const_iterator parameters_end =
-        std::find(c, value.end(), ',');
-    while (c != parameters_end) {
-      SkipWhiteSpace(&c, parameters_end);
-      if (c == parameters_end) {
-        break;
-      }
-      if (*c != ';') {
-        return false;
-      }
-      ++c;
-      SkipWhiteSpace(&c, parameters_end);
-      if (c == parameters_end) {
-        break;
-      }
-      std::string parameter_name;
-      for (; c != parameters_end && *c != '=' && *c != ' ' && *c != '\t'; ++c) {
-        parameter_name.push_back(tolower(*c));
-      }
-      SkipWhiteSpace(&c, parameters_end);
-      if (c == parameters_end || *c != '=') {
-        return false;
-      }
-      ++c;
-      SkipWhiteSpace(&c, parameters_end);
-      absl::string_view::const_iterator parameter_value_begin = c;
-      for (; c != parameters_end && *c != ';' && *c != ' ' && *c != '\t'; ++c) {
-      }
-      if (c == parameter_value_begin) {
-        return false;
-      }
-      if (parameter_name == "ma") {
-        if (!ParsePositiveInteger32(parameter_value_begin, c,
-                                    &max_age_seconds)) {
-          return false;
-        }
-      } else if (!is_ietf_format_quic && parameter_name == "v") {
-        // Version is a comma separated list of positive integers enclosed in
-        // quotation marks.  Since it can contain commas, which are not
-        // delineating alternative service entries, |parameters_end| and |c| can
-        // be invalid.
-        if (*parameter_value_begin != '"') {
-          return false;
-        }
-        c = std::find(parameter_value_begin + 1, value.end(), '"');
-        if (c == value.end()) {
-          return false;
-        }
-        ++c;
-        parameters_end = std::find(c, value.end(), ',');
-        absl::string_view::const_iterator v_begin = parameter_value_begin + 1;
-        while (v_begin < c) {
-          absl::string_view::const_iterator v_end = v_begin;
-          while (v_end < c - 1 && *v_end != ',') {
-            ++v_end;
-          }
-          uint16_t v;
-          if (!ParsePositiveInteger16(v_begin, v_end, &v)) {
-            return false;
-          }
-          version.push_back(v);
-          v_begin = v_end + 1;
-          if (v_begin == c - 1) {
-            // List ends in comma.
-            return false;
-          }
-        }
-      } else if (is_ietf_format_quic && parameter_name == "quic") {
-        // IETF format for advertising QUIC. Version is hex encoding of QUIC
-        // version tag. Hex-encoded string should not include leading "0x" or
-        // leading zeros.
-        // Example for advertising QUIC versions "Q038" and "Q034":
-        // hq=":443";quic=51303338;quic=51303334
-        if (*parameter_value_begin == '0') {
-          return false;
-        }
-        // Versions will be stored as the uint32_t hex decoding of the param
-        // value string. Example: QUIC version "Q038", which is advertised as:
-        // hq=":443";quic=51303338
-        // ... will be stored in |versions| as 0x51303338.
-        uint32_t quic_version;
-        if (!HexDecodeToUInt32(absl::string_view(&*parameter_value_begin,
-                                                 c - parameter_value_begin),
-                               &quic_version) ||
-            quic_version == 0) {
-          return false;
-        }
-        version.push_back(quic_version);
-      }
-    }
-    altsvc_vector->emplace_back(protocol_id, host, port, max_age_seconds,
-                                version);
-    for (; c != value.end() && (*c == ' ' || *c == '\t' || *c == ','); ++c) {
-    }
-  }
-  return true;
-}
-
-// static
-std::string SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
-    const AlternativeServiceVector& altsvc_vector) {
-  if (altsvc_vector.empty()) {
-    return std::string("clear");
-  }
-  const char kNibbleToHex[] = "0123456789ABCDEF";
-  std::string value;
-  for (const AlternativeService& altsvc : altsvc_vector) {
-    if (!value.empty()) {
-      value.push_back(',');
-    }
-    // Check for IETF format for advertising QUIC.
-    const bool is_ietf_format_quic = (altsvc.protocol_id == "hq");
-    // Percent escape protocol id according to
-    // http://tools.ietf.org/html/rfc7230#section-3.2.6.
-    for (char c : altsvc.protocol_id) {
-      if (isalnum(c)) {
-        value.push_back(c);
-        continue;
-      }
-      switch (c) {
-        case '!':
-        case '#':
-        case '$':
-        case '&':
-        case '\'':
-        case '*':
-        case '+':
-        case '-':
-        case '.':
-        case '^':
-        case '_':
-        case '`':
-        case '|':
-        case '~':
-          value.push_back(c);
-          break;
-        default:
-          value.push_back('%');
-          // Network byte order is big-endian.
-          value.push_back(kNibbleToHex[c >> 4]);
-          value.push_back(kNibbleToHex[c & 0x0f]);
-          break;
-      }
-    }
-    value.push_back('=');
-    value.push_back('"');
-    for (char c : altsvc.host) {
-      if (c == '"' || c == '\\') {
-        value.push_back('\\');
-      }
-      value.push_back(c);
-    }
-    absl::StrAppend(&value, ":", altsvc.port, "\"");
-    if (altsvc.max_age_seconds != 86400) {
-      absl::StrAppend(&value, "; ma=", altsvc.max_age_seconds);
-    }
-    if (!altsvc.version.empty()) {
-      if (is_ietf_format_quic) {
-        for (uint32_t quic_version : altsvc.version) {
-          absl::StrAppend(&value, "; quic=", absl::Hex(quic_version));
-        }
-      } else {
-        value.append("; v=\"");
-        for (auto it = altsvc.version.begin(); it != altsvc.version.end();
-             ++it) {
-          if (it != altsvc.version.begin()) {
-            value.append(",");
-          }
-          absl::StrAppend(&value, *it);
-        }
-        value.append("\"");
-      }
-    }
-  }
-  return value;
-}
-
-// static
-void SpdyAltSvcWireFormat::SkipWhiteSpace(
-    absl::string_view::const_iterator* c,
-    absl::string_view::const_iterator end) {
-  for (; *c != end && (**c == ' ' || **c == '\t'); ++*c) {
-  }
-}
-
-// static
-bool SpdyAltSvcWireFormat::PercentDecode(absl::string_view::const_iterator c,
-                                         absl::string_view::const_iterator end,
-                                         std::string* output) {
-  output->clear();
-  for (; c != end; ++c) {
-    if (*c != '%') {
-      output->push_back(*c);
-      continue;
-    }
-    QUICHE_DCHECK_EQ('%', *c);
-    ++c;
-    if (c == end || !std::isxdigit(*c)) {
-      return false;
-    }
-    // Network byte order is big-endian.
-    char decoded = HexDigitToInt(*c) << 4;
-    ++c;
-    if (c == end || !std::isxdigit(*c)) {
-      return false;
-    }
-    decoded += HexDigitToInt(*c);
-    output->push_back(decoded);
-  }
-  return true;
-}
-
-// static
-bool SpdyAltSvcWireFormat::ParseAltAuthority(
-    absl::string_view::const_iterator c,
-    absl::string_view::const_iterator end,
-    std::string* host,
-    uint16_t* port) {
-  host->clear();
-  if (c == end) {
-    return false;
-  }
-  if (*c == '[') {
-    for (; c != end && *c != ']'; ++c) {
-      if (*c == '"') {
-        // Port is mandatory.
-        return false;
-      }
-      host->push_back(*c);
-    }
-    if (c == end) {
-      return false;
-    }
-    QUICHE_DCHECK_EQ(']', *c);
-    host->push_back(*c);
-    ++c;
-  } else {
-    for (; c != end && *c != ':'; ++c) {
-      if (*c == '"') {
-        // Port is mandatory.
-        return false;
-      }
-      if (*c == '\\') {
-        ++c;
-        if (c == end) {
-          return false;
-        }
-      }
-      host->push_back(*c);
-    }
-  }
-  if (c == end || *c != ':') {
-    return false;
-  }
-  QUICHE_DCHECK_EQ(':', *c);
-  ++c;
-  return ParsePositiveInteger16(c, end, port);
-}
-
-// static
-bool SpdyAltSvcWireFormat::ParsePositiveInteger16(
-    absl::string_view::const_iterator c,
-    absl::string_view::const_iterator end,
-    uint16_t* value) {
-  return ParsePositiveIntegerImpl<uint16_t>(c, end, value);
-}
-
-// static
-bool SpdyAltSvcWireFormat::ParsePositiveInteger32(
-    absl::string_view::const_iterator c,
-    absl::string_view::const_iterator end,
-    uint32_t* value) {
-  return ParsePositiveIntegerImpl<uint32_t>(c, end, value);
-}
-
-// static
-char SpdyAltSvcWireFormat::HexDigitToInt(char c) {
-  QUICHE_DCHECK(std::isxdigit(c));
-
-  if (std::isdigit(c)) {
-    return c - '0';
-  }
-  if (c >= 'A' && c <= 'F') {
-    return c - 'A' + 10;
-  }
-  if (c >= 'a' && c <= 'f') {
-    return c - 'a' + 10;
-  }
-
-  return 0;
-}
-
-// static
-bool SpdyAltSvcWireFormat::HexDecodeToUInt32(absl::string_view data,
-                                             uint32_t* value) {
-  if (data.empty() || data.length() > 8u) {
-    return false;
-  }
-
-  *value = 0;
-  for (char c : data) {
-    if (!std::isxdigit(c)) {
-      return false;
-    }
-
-    *value <<= 4;
-    *value += HexDigitToInt(c);
-  }
-
-  return true;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_alt_svc_wire_format.h b/spdy/core/spdy_alt_svc_wire_format.h
deleted file mode 100644
index 664dc1c..0000000
--- a/spdy/core/spdy_alt_svc_wire_format.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains data structures and utility functions used for serializing
-// and parsing alternative service header values, common to HTTP/1.1 header
-// fields and HTTP/2 and QUIC ALTSVC frames.  See specification at
-// https://httpwg.github.io/http-extensions/alt-svc.html.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
-#define QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace spdy {
-
-namespace test {
-class SpdyAltSvcWireFormatPeer;
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE SpdyAltSvcWireFormat {
- public:
-  using VersionVector = absl::InlinedVector<uint32_t, 8>;
-
-  struct QUICHE_EXPORT_PRIVATE AlternativeService {
-    std::string protocol_id;
-    std::string host;
-
-    // Default is 0: invalid port.
-    uint16_t port = 0;
-    // Default is one day.
-    uint32_t max_age_seconds = 86400;
-    // Default is empty: unspecified version.
-    VersionVector version;
-
-    AlternativeService();
-    AlternativeService(const std::string& protocol_id, const std::string& host,
-                       uint16_t port, uint32_t max_age_seconds,
-                       VersionVector version);
-    AlternativeService(const AlternativeService& other);
-    ~AlternativeService();
-
-    bool operator==(const AlternativeService& other) const {
-      return protocol_id == other.protocol_id && host == other.host &&
-             port == other.port && version == other.version &&
-             max_age_seconds == other.max_age_seconds;
-    }
-  };
-  // An empty vector means alternative services should be cleared for given
-  // origin.  Note that the wire format for this is the string "clear", not an
-  // empty value (which is invalid).
-  typedef std::vector<AlternativeService> AlternativeServiceVector;
-
-  friend class test::SpdyAltSvcWireFormatPeer;
-  static bool ParseHeaderFieldValue(absl::string_view value,
-                                    AlternativeServiceVector* altsvc_vector);
-  static std::string SerializeHeaderFieldValue(
-      const AlternativeServiceVector& altsvc_vector);
-
- private:
-  // Forward |*c| over space and tab or until |end| is reached.
-  static void SkipWhiteSpace(absl::string_view::const_iterator* c,
-                             absl::string_view::const_iterator end);
-  // Decode percent-decoded string between |c| and |end| into |*output|.
-  // Return true on success, false if input is invalid.
-  static bool PercentDecode(absl::string_view::const_iterator c,
-                            absl::string_view::const_iterator end,
-                            std::string* output);
-  // Parse the authority part of Alt-Svc between |c| and |end| into |*host| and
-  // |*port|.  Return true on success, false if input is invalid.
-  static bool ParseAltAuthority(absl::string_view::const_iterator c,
-                                absl::string_view::const_iterator end,
-                                std::string* host,
-                                uint16_t* port);
-  // Parse a positive integer between |c| and |end| into |*value|.
-  // Return true on success, false if input is not a positive integer or it
-  // cannot be represented on uint16_t.
-  static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
-                                     absl::string_view::const_iterator end,
-                                     uint16_t* value);
-  // Parse a positive integer between |c| and |end| into |*value|.
-  // Return true on success, false if input is not a positive integer or it
-  // cannot be represented on uint32_t.
-  static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
-                                     absl::string_view::const_iterator end,
-                                     uint32_t* value);
-  // Parse |c| as hexadecimal digit, case insensitive.  |c| must be [0-9a-fA-F].
-  // Output is between 0 and 15.
-  static char HexDigitToInt(char c);
-  // Parse |data| as hexadecimal number into |*value|.  |data| must only contain
-  // hexadecimal digits, no "0x" prefix.
-  // Return true on success, false if input is empty, not valid hexadecimal
-  // number, or cannot be represented on uint32_t.
-  static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value);
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
diff --git a/spdy/core/spdy_alt_svc_wire_format_test.cc b/spdy/core/spdy_alt_svc_wire_format_test.cc
deleted file mode 100644
index 70e708b..0000000
--- a/spdy/core/spdy_alt_svc_wire_format_test.cc
+++ /dev/null
@@ -1,638 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-
-namespace test {
-
-// Expose all private methods of class SpdyAltSvcWireFormat.
-class SpdyAltSvcWireFormatPeer {
- public:
-  static void SkipWhiteSpace(absl::string_view::const_iterator* c,
-                             absl::string_view::const_iterator end) {
-    SpdyAltSvcWireFormat::SkipWhiteSpace(c, end);
-  }
-  static bool PercentDecode(absl::string_view::const_iterator c,
-                            absl::string_view::const_iterator end,
-                            std::string* output) {
-    return SpdyAltSvcWireFormat::PercentDecode(c, end, output);
-  }
-  static bool ParseAltAuthority(absl::string_view::const_iterator c,
-                                absl::string_view::const_iterator end,
-                                std::string* host,
-                                uint16_t* port) {
-    return SpdyAltSvcWireFormat::ParseAltAuthority(c, end, host, port);
-  }
-  static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
-                                     absl::string_view::const_iterator end,
-                                     uint16_t* max_age_seconds) {
-    return SpdyAltSvcWireFormat::ParsePositiveInteger16(c, end,
-                                                        max_age_seconds);
-  }
-  static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
-                                     absl::string_view::const_iterator end,
-                                     uint32_t* max_age_seconds) {
-    return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end,
-                                                        max_age_seconds);
-  }
-  static char HexDigitToInt(char c) {
-    return SpdyAltSvcWireFormat::HexDigitToInt(c);
-  }
-  static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value) {
-    return SpdyAltSvcWireFormat::HexDecodeToUInt32(data, value);
-  }
-};
-
-namespace {
-
-// Generate header field values, possibly with multiply defined parameters and
-// random case, and corresponding AlternativeService entries.
-void FuzzHeaderFieldValue(
-    int i,
-    std::string* header_field_value,
-    SpdyAltSvcWireFormat::AlternativeService* expected_altsvc) {
-  if (!header_field_value->empty()) {
-    header_field_value->push_back(',');
-  }
-  // TODO(b/77515496): use struct of bools instead of int |i| to generate the
-  // header field value.
-  bool is_ietf_format_quic = (i & 1 << 0) != 0;
-  if (i & 1 << 0) {
-    expected_altsvc->protocol_id = "hq";
-    header_field_value->append("hq=\"");
-  } else {
-    expected_altsvc->protocol_id = "a=b%c";
-    header_field_value->append("a%3Db%25c=\"");
-  }
-  if (i & 1 << 1) {
-    expected_altsvc->host = "foo\"bar\\baz";
-    header_field_value->append("foo\\\"bar\\\\baz");
-  } else {
-    expected_altsvc->host = "";
-  }
-  expected_altsvc->port = 42;
-  header_field_value->append(":42\"");
-  if (i & 1 << 2) {
-    header_field_value->append(" ");
-  }
-  if (i & 3 << 3) {
-    expected_altsvc->max_age_seconds = 1111;
-    header_field_value->append(";");
-    if (i & 1 << 3) {
-      header_field_value->append(" ");
-    }
-    header_field_value->append("mA=1111");
-    if (i & 2 << 3) {
-      header_field_value->append(" ");
-    }
-  }
-  if (i & 1 << 5) {
-    header_field_value->append("; J=s");
-  }
-  if (i & 1 << 6) {
-    if (is_ietf_format_quic) {
-      if (i & 1 << 7) {
-        expected_altsvc->version.push_back(0x923457e);
-        header_field_value->append("; quic=923457E");
-      } else {
-        expected_altsvc->version.push_back(1);
-        expected_altsvc->version.push_back(0xFFFFFFFF);
-        header_field_value->append("; quic=1; quic=fFfFffFf");
-      }
-    } else {
-      if (i & i << 7) {
-        expected_altsvc->version.push_back(24);
-        header_field_value->append("; v=\"24\"");
-      } else {
-        expected_altsvc->version.push_back(1);
-        expected_altsvc->version.push_back(65535);
-        header_field_value->append("; v=\"1,65535\"");
-      }
-    }
-  }
-  if (i & 1 << 8) {
-    expected_altsvc->max_age_seconds = 999999999;
-    header_field_value->append("; Ma=999999999");
-  }
-  if (i & 1 << 9) {
-    header_field_value->append(";");
-  }
-  if (i & 1 << 10) {
-    header_field_value->append(" ");
-  }
-  if (i & 1 << 11) {
-    header_field_value->append(",");
-  }
-  if (i & 1 << 12) {
-    header_field_value->append(" ");
-  }
-}
-
-// Generate AlternativeService entries and corresponding header field values in
-// canonical form, that is, what SerializeHeaderFieldValue() should output.
-void FuzzAlternativeService(int i,
-                            SpdyAltSvcWireFormat::AlternativeService* altsvc,
-                            std::string* expected_header_field_value) {
-  if (!expected_header_field_value->empty()) {
-    expected_header_field_value->push_back(',');
-  }
-  altsvc->protocol_id = "a=b%c";
-  altsvc->port = 42;
-  expected_header_field_value->append("a%3Db%25c=\"");
-  if (i & 1 << 0) {
-    altsvc->host = "foo\"bar\\baz";
-    expected_header_field_value->append("foo\\\"bar\\\\baz");
-  }
-  expected_header_field_value->append(":42\"");
-  if (i & 1 << 1) {
-    altsvc->max_age_seconds = 1111;
-    expected_header_field_value->append("; ma=1111");
-  }
-  if (i & 1 << 2) {
-    altsvc->version.push_back(24);
-    altsvc->version.push_back(25);
-    expected_header_field_value->append("; v=\"24,25\"");
-  }
-}
-
-// Tests of public API.
-
-TEST(SpdyAltSvcWireFormatTest, DefaultValues) {
-  SpdyAltSvcWireFormat::AlternativeService altsvc;
-  EXPECT_EQ("", altsvc.protocol_id);
-  EXPECT_EQ("", altsvc.host);
-  EXPECT_EQ(0u, altsvc.port);
-  EXPECT_EQ(86400u, altsvc.max_age_seconds);
-  EXPECT_TRUE(altsvc.version.empty());
-}
-
-TEST(SpdyAltSvcWireFormatTest, ParseInvalidEmptyHeaderFieldValue) {
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  ASSERT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue("", &altsvc_vector));
-}
-
-TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueClear) {
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  ASSERT_TRUE(
-      SpdyAltSvcWireFormat::ParseHeaderFieldValue("clear", &altsvc_vector));
-  EXPECT_EQ(0u, altsvc_vector.size());
-}
-
-// Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
-// parameters, duplicate parameters, trailing space, trailing alternate service
-// separator, etc.  Single alternative service at a time.
-TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) {
-  for (int i = 0; i < 1 << 13; ++i) {
-    std::string header_field_value;
-    SpdyAltSvcWireFormat::AlternativeService expected_altsvc;
-    FuzzHeaderFieldValue(i, &header_field_value, &expected_altsvc);
-    SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(header_field_value,
-                                                            &altsvc_vector));
-    ASSERT_EQ(1u, altsvc_vector.size());
-    EXPECT_EQ(expected_altsvc.protocol_id, altsvc_vector[0].protocol_id);
-    EXPECT_EQ(expected_altsvc.host, altsvc_vector[0].host);
-    EXPECT_EQ(expected_altsvc.port, altsvc_vector[0].port);
-    EXPECT_EQ(expected_altsvc.max_age_seconds,
-              altsvc_vector[0].max_age_seconds);
-    EXPECT_EQ(expected_altsvc.version, altsvc_vector[0].version);
-
-    // Roundtrip test starting with |altsvc_vector|.
-    std::string reserialized_header_field_value =
-        SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector);
-    SpdyAltSvcWireFormat::AlternativeServiceVector roundtrip_altsvc_vector;
-    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-        reserialized_header_field_value, &roundtrip_altsvc_vector));
-    ASSERT_EQ(1u, roundtrip_altsvc_vector.size());
-    EXPECT_EQ(expected_altsvc.protocol_id,
-              roundtrip_altsvc_vector[0].protocol_id);
-    EXPECT_EQ(expected_altsvc.host, roundtrip_altsvc_vector[0].host);
-    EXPECT_EQ(expected_altsvc.port, roundtrip_altsvc_vector[0].port);
-    EXPECT_EQ(expected_altsvc.max_age_seconds,
-              roundtrip_altsvc_vector[0].max_age_seconds);
-    EXPECT_EQ(expected_altsvc.version, roundtrip_altsvc_vector[0].version);
-  }
-}
-
-// Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
-// parameters, duplicate parameters, trailing space, trailing alternate service
-// separator, etc.  Possibly multiple alternative service at a time.
-TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueMultiple) {
-  for (int i = 0; i < 1 << 13;) {
-    std::string header_field_value;
-    SpdyAltSvcWireFormat::AlternativeServiceVector expected_altsvc_vector;
-    // This will generate almost two hundred header field values with two,
-    // three, four, five, six, and seven alternative services each, and
-    // thousands with a single one.
-    do {
-      SpdyAltSvcWireFormat::AlternativeService expected_altsvc;
-      FuzzHeaderFieldValue(i, &header_field_value, &expected_altsvc);
-      expected_altsvc_vector.push_back(expected_altsvc);
-      ++i;
-    } while (i % 6 < i % 7);
-    SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(header_field_value,
-                                                            &altsvc_vector));
-    ASSERT_EQ(expected_altsvc_vector.size(), altsvc_vector.size());
-    for (unsigned int j = 0; j < altsvc_vector.size(); ++j) {
-      EXPECT_EQ(expected_altsvc_vector[j].protocol_id,
-                altsvc_vector[j].protocol_id);
-      EXPECT_EQ(expected_altsvc_vector[j].host, altsvc_vector[j].host);
-      EXPECT_EQ(expected_altsvc_vector[j].port, altsvc_vector[j].port);
-      EXPECT_EQ(expected_altsvc_vector[j].max_age_seconds,
-                altsvc_vector[j].max_age_seconds);
-      EXPECT_EQ(expected_altsvc_vector[j].version, altsvc_vector[j].version);
-    }
-
-    // Roundtrip test starting with |altsvc_vector|.
-    std::string reserialized_header_field_value =
-        SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector);
-    SpdyAltSvcWireFormat::AlternativeServiceVector roundtrip_altsvc_vector;
-    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-        reserialized_header_field_value, &roundtrip_altsvc_vector));
-    ASSERT_EQ(expected_altsvc_vector.size(), roundtrip_altsvc_vector.size());
-    for (unsigned int j = 0; j < roundtrip_altsvc_vector.size(); ++j) {
-      EXPECT_EQ(expected_altsvc_vector[j].protocol_id,
-                roundtrip_altsvc_vector[j].protocol_id);
-      EXPECT_EQ(expected_altsvc_vector[j].host,
-                roundtrip_altsvc_vector[j].host);
-      EXPECT_EQ(expected_altsvc_vector[j].port,
-                roundtrip_altsvc_vector[j].port);
-      EXPECT_EQ(expected_altsvc_vector[j].max_age_seconds,
-                roundtrip_altsvc_vector[j].max_age_seconds);
-      EXPECT_EQ(expected_altsvc_vector[j].version,
-                roundtrip_altsvc_vector[j].version);
-    }
-  }
-}
-
-TEST(SpdyAltSvcWireFormatTest, SerializeEmptyHeaderFieldValue) {
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  EXPECT_EQ("clear",
-            SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
-}
-
-// Test ParseHeaderFieldValue() and SerializeHeaderFieldValue() on the same pair
-// of |expected_header_field_value| and |altsvc|, with and without hostname and
-// each
-// parameter.  Single alternative service at a time.
-TEST(SpdyAltSvcWireFormatTest, RoundTrip) {
-  for (int i = 0; i < 1 << 3; ++i) {
-    SpdyAltSvcWireFormat::AlternativeService altsvc;
-    std::string expected_header_field_value;
-    FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
-
-    // Test ParseHeaderFieldValue().
-    SpdyAltSvcWireFormat::AlternativeServiceVector parsed_altsvc_vector;
-    ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-        expected_header_field_value, &parsed_altsvc_vector));
-    ASSERT_EQ(1u, parsed_altsvc_vector.size());
-    EXPECT_EQ(altsvc.protocol_id, parsed_altsvc_vector[0].protocol_id);
-    EXPECT_EQ(altsvc.host, parsed_altsvc_vector[0].host);
-    EXPECT_EQ(altsvc.port, parsed_altsvc_vector[0].port);
-    EXPECT_EQ(altsvc.max_age_seconds, parsed_altsvc_vector[0].max_age_seconds);
-    EXPECT_EQ(altsvc.version, parsed_altsvc_vector[0].version);
-
-    // Test SerializeHeaderFieldValue().
-    SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-    altsvc_vector.push_back(altsvc);
-    EXPECT_EQ(expected_header_field_value,
-              SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
-  }
-}
-
-// Test ParseHeaderFieldValue() and SerializeHeaderFieldValue() on the same pair
-// of |expected_header_field_value| and |altsvc|, with and without hostname and
-// each
-// parameter.  Multiple alternative services at a time.
-TEST(SpdyAltSvcWireFormatTest, RoundTripMultiple) {
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  std::string expected_header_field_value;
-  for (int i = 0; i < 1 << 3; ++i) {
-    SpdyAltSvcWireFormat::AlternativeService altsvc;
-    FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
-    altsvc_vector.push_back(altsvc);
-  }
-
-  // Test ParseHeaderFieldValue().
-  SpdyAltSvcWireFormat::AlternativeServiceVector parsed_altsvc_vector;
-  ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-      expected_header_field_value, &parsed_altsvc_vector));
-  ASSERT_EQ(altsvc_vector.size(), parsed_altsvc_vector.size());
-  auto expected_it = altsvc_vector.begin();
-  auto parsed_it = parsed_altsvc_vector.begin();
-  for (; expected_it != altsvc_vector.end(); ++expected_it, ++parsed_it) {
-    EXPECT_EQ(expected_it->protocol_id, parsed_it->protocol_id);
-    EXPECT_EQ(expected_it->host, parsed_it->host);
-    EXPECT_EQ(expected_it->port, parsed_it->port);
-    EXPECT_EQ(expected_it->max_age_seconds, parsed_it->max_age_seconds);
-    EXPECT_EQ(expected_it->version, parsed_it->version);
-  }
-
-  // Test SerializeHeaderFieldValue().
-  EXPECT_EQ(expected_header_field_value,
-            SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
-}
-
-// ParseHeaderFieldValue() should return false on malformed field values:
-// invalid percent encoding, unmatched quotation mark, empty port, non-numeric
-// characters in numeric fields.
-TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) {
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  const char* invalid_field_value_array[] = {"a%",
-                                             "a%x",
-                                             "a%b",
-                                             "a%9z",
-                                             "a=",
-                                             "a=\"",
-                                             "a=\"b\"",
-                                             "a=\":\"",
-                                             "a=\"c:\"",
-                                             "a=\"c:foo\"",
-                                             "a=\"c:42foo\"",
-                                             "a=\"b:42\"bar",
-                                             "a=\"b:42\" ; m",
-                                             "a=\"b:42\" ; min-age",
-                                             "a=\"b:42\" ; ma",
-                                             "a=\"b:42\" ; ma=",
-                                             "a=\"b:42\" ; v=\"..\"",
-                                             "a=\"b:42\" ; ma=ma",
-                                             "a=\"b:42\" ; ma=123bar",
-                                             "a=\"b:42\" ; v=24",
-                                             "a=\"b:42\" ; v=24,25",
-                                             "a=\"b:42\" ; v=\"-3\"",
-                                             "a=\"b:42\" ; v=\"1.2\"",
-                                             "a=\"b:42\" ; v=\"24,\""};
-  for (const char* invalid_field_value : invalid_field_value_array) {
-    EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-        invalid_field_value, &altsvc_vector))
-        << invalid_field_value;
-  }
-}
-
-// ParseHeaderFieldValue() should return false on a field values truncated
-// before closing quotation mark, without trying to access memory beyond the end
-// of the input.
-TEST(SpdyAltSvcWireFormatTest, ParseTruncatedHeaderFieldValue) {
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  const char* field_value_array[] = {"a=\":137\"", "a=\"foo:137\"",
-                                     "a%25=\"foo\\\"bar\\\\baz:137\""};
-  for (const std::string& field_value : field_value_array) {
-    for (size_t len = 1; len < field_value.size(); ++len) {
-      EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
-          field_value.substr(0, len), &altsvc_vector))
-          << len;
-    }
-  }
-}
-
-// Tests of private methods.
-
-// Test SkipWhiteSpace().
-TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) {
-  absl::string_view input("a \tb  ");
-  absl::string_view::const_iterator c = input.begin();
-  SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
-  ASSERT_EQ(input.begin(), c);
-  ++c;
-  SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
-  ASSERT_EQ(input.begin() + 3, c);
-  ++c;
-  SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
-  ASSERT_EQ(input.end(), c);
-}
-
-// Test PercentDecode() on valid input.
-TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) {
-  absl::string_view input("");
-  std::string output;
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
-                                                      input.end(), &output));
-  EXPECT_EQ("", output);
-
-  input = absl::string_view("foo");
-  output.clear();
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
-                                                      input.end(), &output));
-  EXPECT_EQ("foo", output);
-
-  input = absl::string_view("%2ca%5Cb");
-  output.clear();
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
-                                                      input.end(), &output));
-  EXPECT_EQ(",a\\b", output);
-}
-
-// Test PercentDecode() on invalid input.
-TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) {
-  const char* invalid_input_array[] = {"a%", "a%x", "a%b", "%J22", "%9z"};
-  for (const char* invalid_input : invalid_input_array) {
-    absl::string_view input(invalid_input);
-    std::string output;
-    EXPECT_FALSE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
-                                                         input.end(), &output))
-        << input;
-  }
-}
-
-// Test ParseAltAuthority() on valid input.
-TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) {
-  absl::string_view input(":42");
-  std::string host;
-  uint16_t port;
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
-      input.begin(), input.end(), &host, &port));
-  EXPECT_TRUE(host.empty());
-  EXPECT_EQ(42, port);
-
-  input = absl::string_view("foo:137");
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
-      input.begin(), input.end(), &host, &port));
-  EXPECT_EQ("foo", host);
-  EXPECT_EQ(137, port);
-
-  input = absl::string_view("[2003:8:0:16::509d:9615]:443");
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
-      input.begin(), input.end(), &host, &port));
-  EXPECT_EQ("[2003:8:0:16::509d:9615]", host);
-  EXPECT_EQ(443, port);
-}
-
-// Test ParseAltAuthority() on invalid input: empty string, no port, zero port,
-// non-digit characters following port.
-TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) {
-  const char* invalid_input_array[] = {"",
-                                       ":",
-                                       "foo:",
-                                       ":bar",
-                                       ":0",
-                                       "foo:0",
-                                       ":12bar",
-                                       "foo:23bar",
-                                       " ",
-                                       ":12 ",
-                                       "foo:12 ",
-                                       "[2003:8:0:16::509d:9615]",
-                                       "[2003:8:0:16::509d:9615]:",
-                                       "[2003:8:0:16::509d:9615]foo:443",
-                                       "[2003:8:0:16::509d:9615:443",
-                                       "2003:8:0:16::509d:9615]:443"};
-  for (const char* invalid_input : invalid_input_array) {
-    absl::string_view input(invalid_input);
-    std::string host;
-    uint16_t port;
-    EXPECT_FALSE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
-        input.begin(), input.end(), &host, &port))
-        << input;
-  }
-}
-
-// Test ParseInteger() on valid input.
-TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) {
-  absl::string_view input("3");
-  uint16_t value;
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
-      input.begin(), input.end(), &value));
-  EXPECT_EQ(3, value);
-
-  input = absl::string_view("1337");
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
-      input.begin(), input.end(), &value));
-  EXPECT_EQ(1337, value);
-}
-
-// Test ParseIntegerValid() on invalid input: empty, zero, non-numeric, trailing
-// non-numeric characters.
-TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) {
-  const char* invalid_input_array[] = {"", " ", "a", "0", "00", "1 ", "12b"};
-  for (const char* invalid_input : invalid_input_array) {
-    absl::string_view input(invalid_input);
-    uint16_t value;
-    EXPECT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
-        input.begin(), input.end(), &value))
-        << input;
-  }
-}
-
-// Test ParseIntegerValid() around overflow limit.
-TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) {
-  // Largest possible uint16_t value.
-  absl::string_view input("65535");
-  uint16_t value16;
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
-      input.begin(), input.end(), &value16));
-  EXPECT_EQ(65535, value16);
-
-  // Overflow uint16_t, ParsePositiveInteger16() should return false.
-  input = absl::string_view("65536");
-  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
-      input.begin(), input.end(), &value16));
-
-  // However, even if overflow is not checked for, 65536 overflows to 0, which
-  // returns false anyway.  Check for a larger number which overflows to 1.
-  input = absl::string_view("65537");
-  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
-      input.begin(), input.end(), &value16));
-
-  // Largest possible uint32_t value.
-  input = absl::string_view("4294967295");
-  uint32_t value32;
-  ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
-      input.begin(), input.end(), &value32));
-  EXPECT_EQ(4294967295, value32);
-
-  // Overflow uint32_t, ParsePositiveInteger32() should return false.
-  input = absl::string_view("4294967296");
-  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
-      input.begin(), input.end(), &value32));
-
-  // However, even if overflow is not checked for, 4294967296 overflows to 0,
-  // which returns false anyway.  Check for a larger number which overflows to
-  // 1.
-  input = absl::string_view("4294967297");
-  ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
-      input.begin(), input.end(), &value32));
-}
-
-// Test parsing an Alt-Svc entry with IP literal hostname.
-// Regression test for https://crbug.com/664173.
-TEST(SpdyAltSvcWireFormatTest, ParseIPLiteral) {
-  const char* input =
-      "quic=\"[2003:8:0:16::509d:9615]:443\"; v=\"36,35\"; ma=60";
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  ASSERT_TRUE(
-      SpdyAltSvcWireFormat::ParseHeaderFieldValue(input, &altsvc_vector));
-  EXPECT_EQ(1u, altsvc_vector.size());
-  EXPECT_EQ("quic", altsvc_vector[0].protocol_id);
-  EXPECT_EQ("[2003:8:0:16::509d:9615]", altsvc_vector[0].host);
-  EXPECT_EQ(443u, altsvc_vector[0].port);
-  EXPECT_EQ(60u, altsvc_vector[0].max_age_seconds);
-  EXPECT_THAT(altsvc_vector[0].version, ::testing::ElementsAre(36, 35));
-}
-
-TEST(SpdyAltSvcWireFormatTest, HexDigitToInt) {
-  EXPECT_EQ(0, SpdyAltSvcWireFormatPeer::HexDigitToInt('0'));
-  EXPECT_EQ(1, SpdyAltSvcWireFormatPeer::HexDigitToInt('1'));
-  EXPECT_EQ(2, SpdyAltSvcWireFormatPeer::HexDigitToInt('2'));
-  EXPECT_EQ(3, SpdyAltSvcWireFormatPeer::HexDigitToInt('3'));
-  EXPECT_EQ(4, SpdyAltSvcWireFormatPeer::HexDigitToInt('4'));
-  EXPECT_EQ(5, SpdyAltSvcWireFormatPeer::HexDigitToInt('5'));
-  EXPECT_EQ(6, SpdyAltSvcWireFormatPeer::HexDigitToInt('6'));
-  EXPECT_EQ(7, SpdyAltSvcWireFormatPeer::HexDigitToInt('7'));
-  EXPECT_EQ(8, SpdyAltSvcWireFormatPeer::HexDigitToInt('8'));
-  EXPECT_EQ(9, SpdyAltSvcWireFormatPeer::HexDigitToInt('9'));
-
-  EXPECT_EQ(10, SpdyAltSvcWireFormatPeer::HexDigitToInt('a'));
-  EXPECT_EQ(11, SpdyAltSvcWireFormatPeer::HexDigitToInt('b'));
-  EXPECT_EQ(12, SpdyAltSvcWireFormatPeer::HexDigitToInt('c'));
-  EXPECT_EQ(13, SpdyAltSvcWireFormatPeer::HexDigitToInt('d'));
-  EXPECT_EQ(14, SpdyAltSvcWireFormatPeer::HexDigitToInt('e'));
-  EXPECT_EQ(15, SpdyAltSvcWireFormatPeer::HexDigitToInt('f'));
-
-  EXPECT_EQ(10, SpdyAltSvcWireFormatPeer::HexDigitToInt('A'));
-  EXPECT_EQ(11, SpdyAltSvcWireFormatPeer::HexDigitToInt('B'));
-  EXPECT_EQ(12, SpdyAltSvcWireFormatPeer::HexDigitToInt('C'));
-  EXPECT_EQ(13, SpdyAltSvcWireFormatPeer::HexDigitToInt('D'));
-  EXPECT_EQ(14, SpdyAltSvcWireFormatPeer::HexDigitToInt('E'));
-  EXPECT_EQ(15, SpdyAltSvcWireFormatPeer::HexDigitToInt('F'));
-}
-
-TEST(SpdyAltSvcWireFormatTest, HexDecodeToUInt32) {
-  uint32_t out;
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0", &out));
-  EXPECT_EQ(0u, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("00", &out));
-  EXPECT_EQ(0u, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0000000", &out));
-  EXPECT_EQ(0u, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("00000000", &out));
-  EXPECT_EQ(0u, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1", &out));
-  EXPECT_EQ(1u, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("ffffFFF", &out));
-  EXPECT_EQ(0xFFFFFFFu, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("fFfFffFf", &out));
-  EXPECT_EQ(0xFFFFFFFFu, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("01AEF", &out));
-  EXPECT_EQ(0x1AEFu, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("abcde", &out));
-  EXPECT_EQ(0xABCDEu, out);
-  EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1234abcd", &out));
-  EXPECT_EQ(0x1234ABCDu, out);
-
-  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("", &out));
-  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("111111111", &out));
-  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1111111111", &out));
-  EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0x1111", &out));
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_frame_builder.cc b/spdy/core/spdy_frame_builder.cc
deleted file mode 100644
index 0b75271..0000000
--- a/spdy/core/spdy_frame_builder.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_frame_builder.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <new>
-
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/zero_copy_output_buffer.h"
-
-namespace spdy {
-
-SpdyFrameBuilder::SpdyFrameBuilder(size_t size)
-    : buffer_(new char[size]), capacity_(size), length_(0), offset_(0) {}
-
-SpdyFrameBuilder::SpdyFrameBuilder(size_t size, ZeroCopyOutputBuffer* output)
-    : buffer_(output == nullptr ? new char[size] : nullptr),
-      output_(output),
-      capacity_(size),
-      length_(0),
-      offset_(0) {}
-
-SpdyFrameBuilder::~SpdyFrameBuilder() = default;
-
-char* SpdyFrameBuilder::GetWritableBuffer(size_t length) {
-  if (!CanWrite(length)) {
-    return nullptr;
-  }
-  return buffer_.get() + offset_ + length_;
-}
-
-char* SpdyFrameBuilder::GetWritableOutput(size_t length,
-                                          size_t* actual_length) {
-  char* dest = nullptr;
-  int size = 0;
-
-  if (!CanWrite(length)) {
-    return nullptr;
-  }
-  output_->Next(&dest, &size);
-  *actual_length = std::min<size_t>(length, size);
-  return dest;
-}
-
-bool SpdyFrameBuilder::Seek(size_t length) {
-  if (!CanWrite(length)) {
-    return false;
-  }
-  if (output_ == nullptr) {
-    length_ += length;
-  } else {
-    output_->AdvanceWritePtr(length);
-    length_ += length;
-  }
-  return true;
-}
-
-bool SpdyFrameBuilder::BeginNewFrame(SpdyFrameType type,
-                                     uint8_t flags,
-                                     SpdyStreamId stream_id) {
-  uint8_t raw_frame_type = SerializeFrameType(type);
-  QUICHE_DCHECK(IsDefinedFrameType(raw_frame_type));
-  QUICHE_DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
-  bool success = true;
-  if (length_ > 0) {
-    QUICHE_BUG(spdy_bug_73_1)
-        << "SpdyFrameBuilder doesn't have a clean state when BeginNewFrame"
-        << "is called. Leftover length_ is " << length_;
-    offset_ += length_;
-    length_ = 0;
-  }
-
-  success &= WriteUInt24(capacity_ - offset_ - kFrameHeaderSize);
-  success &= WriteUInt8(raw_frame_type);
-  success &= WriteUInt8(flags);
-  success &= WriteUInt32(stream_id);
-  QUICHE_DCHECK_EQ(kDataFrameMinimumSize, length_);
-  return success;
-}
-
-bool SpdyFrameBuilder::BeginNewFrame(SpdyFrameType type,
-                                     uint8_t flags,
-                                     SpdyStreamId stream_id,
-                                     size_t length) {
-  uint8_t raw_frame_type = SerializeFrameType(type);
-  QUICHE_DCHECK(IsDefinedFrameType(raw_frame_type));
-  QUICHE_DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
-  QUICHE_BUG_IF(spdy_bug_73_2, length > kHttp2DefaultFramePayloadLimit)
-      << "Frame length  " << length_ << " is longer than frame size limit.";
-  return BeginNewFrameInternal(raw_frame_type, flags, stream_id, length);
-}
-
-bool SpdyFrameBuilder::BeginNewUncheckedFrame(uint8_t raw_frame_type,
-                                              uint8_t flags,
-                                              SpdyStreamId stream_id,
-                                              size_t length) {
-  return BeginNewFrameInternal(raw_frame_type, flags, stream_id, length);
-}
-
-bool SpdyFrameBuilder::BeginNewFrameInternal(uint8_t raw_frame_type,
-                                             uint8_t flags,
-                                             SpdyStreamId stream_id,
-                                             size_t length) {
-  QUICHE_DCHECK_EQ(length, length & kLengthMask);
-  bool success = true;
-
-  offset_ += length_;
-  length_ = 0;
-
-  success &= WriteUInt24(length);
-  success &= WriteUInt8(raw_frame_type);
-  success &= WriteUInt8(flags);
-  success &= WriteUInt32(stream_id);
-  QUICHE_DCHECK_EQ(kDataFrameMinimumSize, length_);
-  return success;
-}
-
-bool SpdyFrameBuilder::WriteStringPiece32(const absl::string_view value) {
-  if (!WriteUInt32(value.size())) {
-    return false;
-  }
-
-  return WriteBytes(value.data(), value.size());
-}
-
-bool SpdyFrameBuilder::WriteBytes(const void* data, uint32_t data_len) {
-  if (!CanWrite(data_len)) {
-    return false;
-  }
-
-  if (output_ == nullptr) {
-    char* dest = GetWritableBuffer(data_len);
-    memcpy(dest, data, data_len);
-    Seek(data_len);
-  } else {
-    char* dest = nullptr;
-    size_t size = 0;
-    size_t total_written = 0;
-    const char* data_ptr = reinterpret_cast<const char*>(data);
-    while (data_len > 0) {
-      dest = GetWritableOutput(data_len, &size);
-      if (dest == nullptr || size == 0) {
-        // Unable to make progress.
-        return false;
-      }
-      uint32_t to_copy = std::min<uint32_t>(data_len, size);
-      const char* src = data_ptr + total_written;
-      memcpy(dest, src, to_copy);
-      Seek(to_copy);
-      data_len -= to_copy;
-      total_written += to_copy;
-    }
-  }
-  return true;
-}
-
-bool SpdyFrameBuilder::CanWrite(size_t length) const {
-  if (length > kLengthMask) {
-    QUICHE_DCHECK(false);
-    return false;
-  }
-
-  if (output_ == nullptr) {
-    if (offset_ + length_ + length > capacity_) {
-      QUICHE_DLOG(FATAL) << "Requested: " << length
-                         << " capacity: " << capacity_
-                         << " used: " << offset_ + length_;
-      return false;
-    }
-  } else {
-    if (length > output_->BytesFree()) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_frame_builder.h b/spdy/core/spdy_frame_builder.h
deleted file mode 100644
index 4625aa1..0000000
--- a/spdy/core/spdy_frame_builder.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_FRAME_BUILDER_H_
-#define QUICHE_SPDY_CORE_SPDY_FRAME_BUILDER_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/quiche_endian.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/zero_copy_output_buffer.h"
-
-namespace spdy {
-
-namespace test {
-class SpdyFrameBuilderPeer;
-}  // namespace test
-
-// This class provides facilities for basic binary value packing
-// into Spdy frames.
-//
-// The SpdyFrameBuilder supports appending primitive values (int, string, etc)
-// to a frame instance.  The SpdyFrameBuilder grows its internal memory buffer
-// dynamically to hold the sequence of primitive values.   The internal memory
-// buffer is exposed as the "data" of the SpdyFrameBuilder.
-class QUICHE_EXPORT_PRIVATE SpdyFrameBuilder {
- public:
-  // Initializes a SpdyFrameBuilder with a buffer of given size
-  explicit SpdyFrameBuilder(size_t size);
-  // Doesn't take ownership of output.
-  SpdyFrameBuilder(size_t size, ZeroCopyOutputBuffer* output);
-
-  ~SpdyFrameBuilder();
-
-  // Returns the total size of the SpdyFrameBuilder's data, which may include
-  // multiple frames.
-  size_t length() const { return offset_ + length_; }
-
-  // Seeks forward by the given number of bytes. Useful in conjunction with
-  // GetWriteableBuffer() above.
-  bool Seek(size_t length);
-
-  // Populates this frame with a HTTP2 frame prefix using length information
-  // from |capacity_|. The given type must be a control frame type.
-  bool BeginNewFrame(SpdyFrameType type, uint8_t flags, SpdyStreamId stream_id);
-
-  // Populates this frame with a HTTP2 frame prefix with type and length
-  // information.  |type| must be a defined frame type.
-  bool BeginNewFrame(SpdyFrameType type,
-                     uint8_t flags,
-                     SpdyStreamId stream_id,
-                     size_t length);
-
-  // Populates this frame with a HTTP2 frame prefix with type and length
-  // information.  |raw_frame_type| may be a defined or undefined frame type.
-  bool BeginNewUncheckedFrame(uint8_t raw_frame_type,
-                              uint8_t flags,
-                              SpdyStreamId stream_id,
-                              size_t length);
-
-  // Takes the buffer from the SpdyFrameBuilder.
-  SpdySerializedFrame take() {
-    QUICHE_BUG_IF(spdy_bug_39_1, output_ != nullptr)
-        << "ZeroCopyOutputBuffer is used to build "
-        << "frames. take() shouldn't be called";
-    QUICHE_BUG_IF(spdy_bug_39_2, kMaxFrameSizeLimit < length_)
-        << "Frame length " << length_
-        << " is longer than the maximum possible allowed length.";
-    SpdySerializedFrame rv(buffer_.release(), length(), true);
-    capacity_ = 0;
-    length_ = 0;
-    offset_ = 0;
-    return rv;
-  }
-
-  // Methods for adding to the payload.  These values are appended to the end
-  // of the SpdyFrameBuilder payload. Note - binary integers are converted from
-  // host to network form.
-  bool WriteUInt8(uint8_t value) { return WriteBytes(&value, sizeof(value)); }
-  bool WriteUInt16(uint16_t value) {
-    value = quiche::QuicheEndian::HostToNet16(value);
-    return WriteBytes(&value, sizeof(value));
-  }
-  bool WriteUInt24(uint32_t value) {
-    value = quiche::QuicheEndian::HostToNet32(value);
-    return WriteBytes(reinterpret_cast<char*>(&value) + 1, sizeof(value) - 1);
-  }
-  bool WriteUInt32(uint32_t value) {
-    value = quiche::QuicheEndian::HostToNet32(value);
-    return WriteBytes(&value, sizeof(value));
-  }
-  bool WriteUInt64(uint64_t value) {
-    uint32_t upper =
-        quiche::QuicheEndian::HostToNet32(static_cast<uint32_t>(value >> 32));
-    uint32_t lower =
-        quiche::QuicheEndian::HostToNet32(static_cast<uint32_t>(value));
-    return (WriteBytes(&upper, sizeof(upper)) &&
-            WriteBytes(&lower, sizeof(lower)));
-  }
-  bool WriteStringPiece32(const absl::string_view value);
-  bool WriteBytes(const void* data, uint32_t data_len);
-
- private:
-  friend class test::SpdyFrameBuilderPeer;
-
-  // Populates this frame with a HTTP2 frame prefix with type and length
-  // information.
-  bool BeginNewFrameInternal(uint8_t raw_frame_type,
-                             uint8_t flags,
-                             SpdyStreamId stream_id,
-                             size_t length);
-
-  // Returns a writeable buffer of given size in bytes, to be appended to the
-  // currently written frame. Does bounds checking on length but does not
-  // increment the underlying iterator. To do so, consumers should subsequently
-  // call Seek().
-  // In general, consumers should use Write*() calls instead of this.
-  // Returns NULL on failure.
-  char* GetWritableBuffer(size_t length);
-  char* GetWritableOutput(size_t desired_length, size_t* actual_length);
-
-  // Checks to make sure that there is an appropriate amount of space for a
-  // write of given size, in bytes.
-  bool CanWrite(size_t length) const;
-
-  // A buffer to be created whenever a new frame needs to be written. Used only
-  // if |output_| is nullptr.
-  std::unique_ptr<char[]> buffer_;
-  // A pre-allocated buffer. If not-null, serialized frame data is written to
-  // this buffer.
-  ZeroCopyOutputBuffer* output_ = nullptr;  // Does not own.
-
-  size_t capacity_;  // Allocation size of payload, set by constructor.
-  size_t length_;    // Length of the latest frame in the buffer.
-  size_t offset_;    // Position at which the latest frame begins.
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_FRAME_BUILDER_H_
diff --git a/spdy/core/spdy_frame_builder_test.cc b/spdy/core/spdy_frame_builder_test.cc
deleted file mode 100644
index dd5d3d6..0000000
--- a/spdy/core/spdy_frame_builder_test.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_frame_builder.h"
-
-#include <memory>
-
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/array_output_buffer.h"
-#include "spdy/core/spdy_framer.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace spdy {
-
-namespace test {
-
-class QUICHE_EXPORT_PRIVATE SpdyFrameBuilderPeer {
- public:
-  static char* GetWritableBuffer(SpdyFrameBuilder* builder, size_t length) {
-    return builder->GetWritableBuffer(length);
-  }
-
-  static char* GetWritableOutput(SpdyFrameBuilder* builder,
-                                 size_t desired_length,
-                                 size_t* actual_length) {
-    return builder->GetWritableOutput(desired_length, actual_length);
-  }
-};
-
-namespace {
-
-const int64_t kSize = 64 * 1024;
-char output_buffer[kSize] = "";
-
-}  // namespace
-
-// Verifies that SpdyFrameBuilder::GetWritableBuffer() can be used to build a
-// SpdySerializedFrame.
-TEST(SpdyFrameBuilderTest, GetWritableBuffer) {
-  const size_t kBuilderSize = 10;
-  SpdyFrameBuilder builder(kBuilderSize);
-  char* writable_buffer =
-      SpdyFrameBuilderPeer::GetWritableBuffer(&builder, kBuilderSize);
-  memset(writable_buffer, ~1, kBuilderSize);
-  EXPECT_TRUE(builder.Seek(kBuilderSize));
-  SpdySerializedFrame frame(builder.take());
-  char expected[kBuilderSize];
-  memset(expected, ~1, kBuilderSize);
-  EXPECT_EQ(absl::string_view(expected, kBuilderSize),
-            absl::string_view(frame.data(), kBuilderSize));
-}
-
-// Verifies that SpdyFrameBuilder::GetWritableBuffer() can be used to build a
-// SpdySerializedFrame to the output buffer.
-TEST(SpdyFrameBuilderTest, GetWritableOutput) {
-  ArrayOutputBuffer output(output_buffer, kSize);
-  const size_t kBuilderSize = 10;
-  SpdyFrameBuilder builder(kBuilderSize, &output);
-  size_t actual_size = 0;
-  char* writable_buffer = SpdyFrameBuilderPeer::GetWritableOutput(
-      &builder, kBuilderSize, &actual_size);
-  memset(writable_buffer, ~1, kBuilderSize);
-  EXPECT_TRUE(builder.Seek(kBuilderSize));
-  SpdySerializedFrame frame(output.Begin(), kBuilderSize, false);
-  char expected[kBuilderSize];
-  memset(expected, ~1, kBuilderSize);
-  EXPECT_EQ(absl::string_view(expected, kBuilderSize),
-            absl::string_view(frame.data(), kBuilderSize));
-}
-
-// Verifies the case that the buffer's capacity is too small.
-TEST(SpdyFrameBuilderTest, GetWritableOutputNegative) {
-  size_t small_cap = 1;
-  ArrayOutputBuffer output(output_buffer, small_cap);
-  const size_t kBuilderSize = 10;
-  SpdyFrameBuilder builder(kBuilderSize, &output);
-  size_t actual_size = 0;
-  char* writable_buffer = SpdyFrameBuilderPeer::GetWritableOutput(
-      &builder, kBuilderSize, &actual_size);
-  EXPECT_EQ(0u, actual_size);
-  EXPECT_EQ(nullptr, writable_buffer);
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_framer.cc b/spdy/core/spdy_framer.cc
deleted file mode 100644
index e97d45c..0000000
--- a/spdy/core/spdy_framer.cc
+++ /dev/null
@@ -1,1380 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_framer.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <iterator>
-#include <list>
-#include <new>
-#include <utility>
-
-#include "absl/base/macros.h"
-#include "absl/memory/memory.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/spdy_bitmasks.h"
-#include "spdy/core/spdy_frame_builder.h"
-
-namespace spdy {
-
-namespace {
-
-// Pack parent stream ID and exclusive flag into the format used by HTTP/2
-// headers and priority frames.
-uint32_t PackStreamDependencyValues(bool exclusive,
-                                    SpdyStreamId parent_stream_id) {
-  // Make sure the highest-order bit in the parent stream id is zeroed out.
-  uint32_t parent = parent_stream_id & 0x7fffffff;
-  // Set the one-bit exclusivity flag.
-  uint32_t e_bit = exclusive ? 0x80000000 : 0;
-  return parent | e_bit;
-}
-
-// Used to indicate no flags in a HTTP2 flags field.
-const uint8_t kNoFlags = 0;
-
-// Wire size of pad length field.
-const size_t kPadLengthFieldSize = 1;
-
-// The size of one parameter in SETTINGS frame.
-const size_t kOneSettingParameterSize = 6;
-
-size_t GetUncompressedSerializedLength(const Http2HeaderBlock& headers) {
-  const size_t num_name_value_pairs_size = sizeof(uint32_t);
-  const size_t length_of_name_size = num_name_value_pairs_size;
-  const size_t length_of_value_size = num_name_value_pairs_size;
-
-  size_t total_length = num_name_value_pairs_size;
-  for (const auto& header : headers) {
-    // We add space for the length of the name and the length of the value as
-    // well as the length of the name and the length of the value.
-    total_length += length_of_name_size + header.first.size() +
-                    length_of_value_size + header.second.size();
-  }
-  return total_length;
-}
-
-// Serializes the flags octet for a given SpdyHeadersIR.
-uint8_t SerializeHeaderFrameFlags(const SpdyHeadersIR& header_ir,
-                                  const bool end_headers) {
-  uint8_t flags = 0;
-  if (header_ir.fin()) {
-    flags |= CONTROL_FLAG_FIN;
-  }
-  if (end_headers) {
-    flags |= HEADERS_FLAG_END_HEADERS;
-  }
-  if (header_ir.padded()) {
-    flags |= HEADERS_FLAG_PADDED;
-  }
-  if (header_ir.has_priority()) {
-    flags |= HEADERS_FLAG_PRIORITY;
-  }
-  return flags;
-}
-
-// Serializes the flags octet for a given SpdyPushPromiseIR.
-uint8_t SerializePushPromiseFrameFlags(const SpdyPushPromiseIR& push_promise_ir,
-                                       const bool end_headers) {
-  uint8_t flags = 0;
-  if (push_promise_ir.padded()) {
-    flags = flags | PUSH_PROMISE_FLAG_PADDED;
-  }
-  if (end_headers) {
-    flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
-  }
-  return flags;
-}
-
-// Serializes a HEADERS frame from the given SpdyHeadersIR and encoded header
-// block. Does not need or use the SpdyHeaderBlock inside SpdyHeadersIR.
-// Return false if the serialization fails. |encoding| should not be empty.
-bool SerializeHeadersGivenEncoding(const SpdyHeadersIR& headers,
-                                   const std::string& encoding,
-                                   const bool end_headers,
-                                   ZeroCopyOutputBuffer* output) {
-  const size_t frame_size =
-      GetHeaderFrameSizeSansBlock(headers) + encoding.size();
-  SpdyFrameBuilder builder(frame_size, output);
-  bool ret = builder.BeginNewFrame(
-      SpdyFrameType::HEADERS, SerializeHeaderFrameFlags(headers, end_headers),
-      headers.stream_id(), frame_size - kFrameHeaderSize);
-  QUICHE_DCHECK_EQ(kFrameHeaderSize, builder.length());
-
-  if (ret && headers.padded()) {
-    ret &= builder.WriteUInt8(headers.padding_payload_len());
-  }
-
-  if (ret && headers.has_priority()) {
-    int weight = ClampHttp2Weight(headers.weight());
-    ret &= builder.WriteUInt32(PackStreamDependencyValues(
-        headers.exclusive(), headers.parent_stream_id()));
-    // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
-    ret &= builder.WriteUInt8(weight - 1);
-  }
-
-  if (ret) {
-    ret &= builder.WriteBytes(encoding.data(), encoding.size());
-  }
-
-  if (ret && headers.padding_payload_len() > 0) {
-    std::string padding(headers.padding_payload_len(), 0);
-    ret &= builder.WriteBytes(padding.data(), padding.length());
-  }
-
-  if (!ret) {
-    QUICHE_DLOG(WARNING)
-        << "Failed to build HEADERS. Not enough space in output";
-  }
-  return ret;
-}
-
-// Serializes a PUSH_PROMISE frame from the given SpdyPushPromiseIR and
-// encoded header block. Does not need or use the SpdyHeaderBlock inside
-// SpdyPushPromiseIR.
-bool SerializePushPromiseGivenEncoding(const SpdyPushPromiseIR& push_promise,
-                                       const std::string& encoding,
-                                       const bool end_headers,
-                                       ZeroCopyOutputBuffer* output) {
-  const size_t frame_size =
-      GetPushPromiseFrameSizeSansBlock(push_promise) + encoding.size();
-  SpdyFrameBuilder builder(frame_size, output);
-  bool ok = builder.BeginNewFrame(
-      SpdyFrameType::PUSH_PROMISE,
-      SerializePushPromiseFrameFlags(push_promise, end_headers),
-      push_promise.stream_id(), frame_size - kFrameHeaderSize);
-
-  if (push_promise.padded()) {
-    ok = ok && builder.WriteUInt8(push_promise.padding_payload_len());
-  }
-  ok = ok && builder.WriteUInt32(push_promise.promised_stream_id()) &&
-       builder.WriteBytes(encoding.data(), encoding.size());
-  if (ok && push_promise.padding_payload_len() > 0) {
-    std::string padding(push_promise.padding_payload_len(), 0);
-    ok = builder.WriteBytes(padding.data(), padding.length());
-  }
-
-  QUICHE_DLOG_IF(ERROR, !ok)
-      << "Failed to write PUSH_PROMISE encoding, not enough "
-      << "space in output";
-  return ok;
-}
-
-bool WritePayloadWithContinuation(SpdyFrameBuilder* builder,
-                                  const std::string& hpack_encoding,
-                                  SpdyStreamId stream_id,
-                                  SpdyFrameType type,
-                                  int padding_payload_len) {
-  uint8_t end_flag = 0;
-  uint8_t flags = 0;
-  if (type == SpdyFrameType::HEADERS) {
-    end_flag = HEADERS_FLAG_END_HEADERS;
-  } else if (type == SpdyFrameType::PUSH_PROMISE) {
-    end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
-  } else {
-    QUICHE_DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
-                       << FrameTypeToString(type);
-  }
-
-  // Write all the padding payload and as much of the data payload as possible
-  // into the initial frame.
-  size_t bytes_remaining = 0;
-  bytes_remaining = hpack_encoding.size() -
-                    std::min(hpack_encoding.size(),
-                             kHttp2MaxControlFrameSendSize - builder->length() -
-                                 padding_payload_len);
-  bool ret = builder->WriteBytes(&hpack_encoding[0],
-                                 hpack_encoding.size() - bytes_remaining);
-  if (padding_payload_len > 0) {
-    std::string padding = std::string(padding_payload_len, 0);
-    ret &= builder->WriteBytes(padding.data(), padding.length());
-  }
-
-  // Tack on CONTINUATION frames for the overflow.
-  while (bytes_remaining > 0 && ret) {
-    size_t bytes_to_write =
-        std::min(bytes_remaining,
-                 kHttp2MaxControlFrameSendSize - kContinuationFrameMinimumSize);
-    // Write CONTINUATION frame prefix.
-    if (bytes_remaining == bytes_to_write) {
-      flags |= end_flag;
-    }
-    ret &= builder->BeginNewFrame(SpdyFrameType::CONTINUATION, flags, stream_id,
-                                  bytes_to_write);
-    // Write payload fragment.
-    ret &= builder->WriteBytes(
-        &hpack_encoding[hpack_encoding.size() - bytes_remaining],
-        bytes_to_write);
-    bytes_remaining -= bytes_to_write;
-  }
-  return ret;
-}
-
-void SerializeDataBuilderHelper(const SpdyDataIR& data_ir,
-                                uint8_t* flags,
-                                int* num_padding_fields,
-                                size_t* size_with_padding) {
-  if (data_ir.fin()) {
-    *flags = DATA_FLAG_FIN;
-  }
-
-  if (data_ir.padded()) {
-    *flags = *flags | DATA_FLAG_PADDED;
-    ++*num_padding_fields;
-  }
-
-  *size_with_padding = *num_padding_fields + data_ir.data_len() +
-                       data_ir.padding_payload_len() + kDataFrameMinimumSize;
-}
-
-void SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
-    const SpdyDataIR& data_ir,
-    uint8_t* flags,
-    size_t* frame_size,
-    size_t* num_padding_fields) {
-  *flags = DATA_FLAG_NONE;
-  if (data_ir.fin()) {
-    *flags = DATA_FLAG_FIN;
-  }
-
-  *frame_size = kDataFrameMinimumSize;
-  if (data_ir.padded()) {
-    *flags = *flags | DATA_FLAG_PADDED;
-    ++(*num_padding_fields);
-    *frame_size = *frame_size + *num_padding_fields;
-  }
-}
-
-void SerializeSettingsBuilderHelper(const SpdySettingsIR& settings,
-                                    uint8_t* flags,
-                                    const SettingsMap* values,
-                                    size_t* size) {
-  if (settings.is_ack()) {
-    *flags = *flags | SETTINGS_FLAG_ACK;
-  }
-  *size =
-      kSettingsFrameMinimumSize + (values->size() * kOneSettingParameterSize);
-}
-
-void SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir,
-                                  std::string* value,
-                                  size_t* size) {
-  *size = kGetAltSvcFrameMinimumSize;
-  *size = *size + altsvc_ir.origin().length();
-  *value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
-      altsvc_ir.altsvc_vector());
-  *size = *size + value->length();
-}
-
-}  // namespace
-
-SpdyFramer::SpdyFramer(CompressionOption option)
-    : debug_visitor_(nullptr), compression_option_(option) {
-  static_assert(kHttp2MaxControlFrameSendSize <= kHttp2DefaultFrameSizeLimit,
-                "Our send limit should be at most our receive limit.");
-}
-
-SpdyFramer::~SpdyFramer() = default;
-
-void SpdyFramer::set_debug_visitor(
-    SpdyFramerDebugVisitorInterface* debug_visitor) {
-  debug_visitor_ = debug_visitor;
-}
-
-SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer)
-    : framer_(framer), is_first_frame_(true), has_next_frame_(true) {}
-
-SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() = default;
-
-size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) {
-  const SpdyFrameIR& frame_ir = GetIR();
-  if (!has_next_frame_) {
-    QUICHE_BUG(spdy_bug_75_1)
-        << "SpdyFramer::SpdyFrameIterator::NextFrame called without "
-        << "a next frame.";
-    return false;
-  }
-
-  const size_t size_without_block =
-      is_first_frame_ ? GetFrameSizeSansBlock() : kContinuationFrameMinimumSize;
-  std::string encoding =
-      encoder_->Next(kHttp2MaxControlFrameSendSize - size_without_block);
-  has_next_frame_ = encoder_->HasNext();
-
-  if (framer_->debug_visitor_ != nullptr) {
-    const auto& header_block_frame_ir =
-        static_cast<const SpdyFrameWithHeaderBlockIR&>(frame_ir);
-    const size_t header_list_size =
-        GetUncompressedSerializedLength(header_block_frame_ir.header_block());
-    framer_->debug_visitor_->OnSendCompressedFrame(
-        frame_ir.stream_id(),
-        is_first_frame_ ? frame_ir.frame_type() : SpdyFrameType::CONTINUATION,
-        header_list_size, size_without_block + encoding.size());
-  }
-
-  const size_t free_bytes_before = output->BytesFree();
-  bool ok = false;
-  if (is_first_frame_) {
-    is_first_frame_ = false;
-    ok = SerializeGivenEncoding(encoding, output);
-  } else {
-    SpdyContinuationIR continuation_ir(frame_ir.stream_id());
-    continuation_ir.take_encoding(std::move(encoding));
-    continuation_ir.set_end_headers(!has_next_frame_);
-    ok = framer_->SerializeContinuation(continuation_ir, output);
-  }
-  return ok ? free_bytes_before - output->BytesFree() : 0;
-}
-
-bool SpdyFramer::SpdyFrameIterator::HasNextFrame() const {
-  return has_next_frame_;
-}
-
-SpdyFramer::SpdyHeaderFrameIterator::SpdyHeaderFrameIterator(
-    SpdyFramer* framer,
-    std::unique_ptr<const SpdyHeadersIR> headers_ir)
-    : SpdyFrameIterator(framer), headers_ir_(std::move(headers_ir)) {
-  SetEncoder(headers_ir_.get());
-}
-
-SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() = default;
-
-const SpdyFrameIR& SpdyFramer::SpdyHeaderFrameIterator::GetIR() const {
-  return *headers_ir_;
-}
-
-size_t SpdyFramer::SpdyHeaderFrameIterator::GetFrameSizeSansBlock() const {
-  return GetHeaderFrameSizeSansBlock(*headers_ir_);
-}
-
-bool SpdyFramer::SpdyHeaderFrameIterator::SerializeGivenEncoding(
-    const std::string& encoding,
-    ZeroCopyOutputBuffer* output) const {
-  return SerializeHeadersGivenEncoding(*headers_ir_, encoding,
-                                       !has_next_frame(), output);
-}
-
-SpdyFramer::SpdyPushPromiseFrameIterator::SpdyPushPromiseFrameIterator(
-    SpdyFramer* framer,
-    std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir)
-    : SpdyFrameIterator(framer), push_promise_ir_(std::move(push_promise_ir)) {
-  SetEncoder(push_promise_ir_.get());
-}
-
-SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() =
-    default;
-
-const SpdyFrameIR& SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() const {
-  return *push_promise_ir_;
-}
-
-size_t SpdyFramer::SpdyPushPromiseFrameIterator::GetFrameSizeSansBlock() const {
-  return GetPushPromiseFrameSizeSansBlock(*push_promise_ir_);
-}
-
-bool SpdyFramer::SpdyPushPromiseFrameIterator::SerializeGivenEncoding(
-    const std::string& encoding,
-    ZeroCopyOutputBuffer* output) const {
-  return SerializePushPromiseGivenEncoding(*push_promise_ir_, encoding,
-                                           !has_next_frame(), output);
-}
-
-SpdyFramer::SpdyControlFrameIterator::SpdyControlFrameIterator(
-    SpdyFramer* framer,
-    std::unique_ptr<const SpdyFrameIR> frame_ir)
-    : framer_(framer), frame_ir_(std::move(frame_ir)) {}
-
-SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() = default;
-
-size_t SpdyFramer::SpdyControlFrameIterator::NextFrame(
-    ZeroCopyOutputBuffer* output) {
-  size_t size_written = framer_->SerializeFrame(*frame_ir_, output);
-  has_next_frame_ = false;
-  return size_written;
-}
-
-bool SpdyFramer::SpdyControlFrameIterator::HasNextFrame() const {
-  return has_next_frame_;
-}
-
-const SpdyFrameIR& SpdyFramer::SpdyControlFrameIterator::GetIR() const {
-  return *frame_ir_;
-}
-
-std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator(
-    SpdyFramer* framer,
-    std::unique_ptr<const SpdyFrameIR> frame_ir) {
-  switch (frame_ir->frame_type()) {
-    case SpdyFrameType::HEADERS: {
-      return std::make_unique<SpdyHeaderFrameIterator>(
-          framer, absl::WrapUnique(
-                      static_cast<const SpdyHeadersIR*>(frame_ir.release())));
-    }
-    case SpdyFrameType::PUSH_PROMISE: {
-      return std::make_unique<SpdyPushPromiseFrameIterator>(
-          framer, absl::WrapUnique(static_cast<const SpdyPushPromiseIR*>(
-                      frame_ir.release())));
-    }
-    case SpdyFrameType::DATA: {
-      QUICHE_DVLOG(1) << "Serialize a stream end DATA frame for VTL";
-      ABSL_FALLTHROUGH_INTENDED;
-    }
-    default: {
-      return std::make_unique<SpdyControlFrameIterator>(framer,
-                                                        std::move(frame_ir));
-    }
-  }
-}
-
-SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) {
-  uint8_t flags = DATA_FLAG_NONE;
-  int num_padding_fields = 0;
-  size_t size_with_padding = 0;
-  SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields,
-                             &size_with_padding);
-
-  SpdyFrameBuilder builder(size_with_padding);
-  builder.BeginNewFrame(SpdyFrameType::DATA, flags, data_ir.stream_id());
-  if (data_ir.padded()) {
-    builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
-  }
-  builder.WriteBytes(data_ir.data(), data_ir.data_len());
-  if (data_ir.padding_payload_len() > 0) {
-    std::string padding(data_ir.padding_payload_len(), 0);
-    builder.WriteBytes(padding.data(), padding.length());
-  }
-  QUICHE_DCHECK_EQ(size_with_padding, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
-    const SpdyDataIR& data_ir) {
-  uint8_t flags = DATA_FLAG_NONE;
-  size_t frame_size = 0;
-  size_t num_padding_fields = 0;
-  SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
-      data_ir, &flags, &frame_size, &num_padding_fields);
-
-  SpdyFrameBuilder builder(frame_size);
-  builder.BeginNewFrame(
-      SpdyFrameType::DATA, flags, data_ir.stream_id(),
-      num_padding_fields + data_ir.data_len() + data_ir.padding_payload_len());
-  if (data_ir.padded()) {
-    builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
-  }
-  QUICHE_DCHECK_EQ(frame_size, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeRstStream(
-    const SpdyRstStreamIR& rst_stream) const {
-  size_t expected_length = kRstStreamFrameSize;
-  SpdyFrameBuilder builder(expected_length);
-
-  builder.BeginNewFrame(SpdyFrameType::RST_STREAM, 0, rst_stream.stream_id());
-
-  builder.WriteUInt32(rst_stream.error_code());
-
-  QUICHE_DCHECK_EQ(expected_length, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeSettings(
-    const SpdySettingsIR& settings) const {
-  uint8_t flags = 0;
-  // Size, in bytes, of this SETTINGS frame.
-  size_t size = 0;
-  const SettingsMap* values = &(settings.values());
-  SerializeSettingsBuilderHelper(settings, &flags, values, &size);
-  SpdyFrameBuilder builder(size);
-  builder.BeginNewFrame(SpdyFrameType::SETTINGS, flags, 0);
-
-  // If this is an ACK, payload should be empty.
-  if (settings.is_ack()) {
-    return builder.take();
-  }
-
-  QUICHE_DCHECK_EQ(kSettingsFrameMinimumSize, builder.length());
-  for (auto it = values->begin(); it != values->end(); ++it) {
-    int setting_id = it->first;
-    QUICHE_DCHECK_GE(setting_id, 0);
-    builder.WriteUInt16(static_cast<SpdySettingsId>(setting_id));
-    builder.WriteUInt32(it->second);
-  }
-  QUICHE_DCHECK_EQ(size, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
-  SpdyFrameBuilder builder(kPingFrameSize);
-  uint8_t flags = 0;
-  if (ping.is_ack()) {
-    flags |= PING_FLAG_ACK;
-  }
-  builder.BeginNewFrame(SpdyFrameType::PING, flags, 0);
-  builder.WriteUInt64(ping.id());
-  QUICHE_DCHECK_EQ(kPingFrameSize, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeGoAway(
-    const SpdyGoAwayIR& goaway) const {
-  // Compute the output buffer size, take opaque data into account.
-  size_t expected_length = kGoawayFrameMinimumSize;
-  expected_length += goaway.description().size();
-  SpdyFrameBuilder builder(expected_length);
-
-  // Serialize the GOAWAY frame.
-  builder.BeginNewFrame(SpdyFrameType::GOAWAY, 0, 0);
-
-  // GOAWAY frames specify the last good stream id.
-  builder.WriteUInt32(goaway.last_good_stream_id());
-
-  // GOAWAY frames also specify the error code.
-  builder.WriteUInt32(goaway.error_code());
-
-  // GOAWAY frames may also specify opaque data.
-  if (!goaway.description().empty()) {
-    builder.WriteBytes(goaway.description().data(),
-                       goaway.description().size());
-  }
-
-  QUICHE_DCHECK_EQ(expected_length, builder.length());
-  return builder.take();
-}
-
-void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
-                                               uint8_t* flags,
-                                               size_t* size,
-                                               std::string* hpack_encoding,
-                                               int* weight,
-                                               size_t* length_field) {
-  if (headers.fin()) {
-    *flags = *flags | CONTROL_FLAG_FIN;
-  }
-  // This will get overwritten if we overflow into a CONTINUATION frame.
-  *flags = *flags | HEADERS_FLAG_END_HEADERS;
-  if (headers.has_priority()) {
-    *flags = *flags | HEADERS_FLAG_PRIORITY;
-  }
-  if (headers.padded()) {
-    *flags = *flags | HEADERS_FLAG_PADDED;
-  }
-
-  *size = kHeadersFrameMinimumSize;
-
-  if (headers.padded()) {
-    *size = *size + kPadLengthFieldSize;
-    *size = *size + headers.padding_payload_len();
-  }
-
-  if (headers.has_priority()) {
-    *weight = ClampHttp2Weight(headers.weight());
-    *size = *size + 5;
-  }
-
-  *hpack_encoding =
-      GetHpackEncoder()->EncodeHeaderBlock(headers.header_block());
-  *size = *size + hpack_encoding->size();
-  if (*size > kHttp2MaxControlFrameSendSize) {
-    *size = *size + GetNumberRequiredContinuationFrames(*size) *
-                        kContinuationFrameMinimumSize;
-    *flags = *flags & ~HEADERS_FLAG_END_HEADERS;
-  }
-  // Compute frame length field.
-  if (headers.padded()) {
-    *length_field = *length_field + kPadLengthFieldSize;
-  }
-  if (headers.has_priority()) {
-    *length_field = *length_field + 4;  // Dependency field.
-    *length_field = *length_field + 1;  // Weight field.
-  }
-  *length_field = *length_field + headers.padding_payload_len();
-  *length_field = *length_field + hpack_encoding->size();
-  // If the HEADERS frame with payload would exceed the max frame size, then
-  // WritePayloadWithContinuation() will serialize CONTINUATION frames as
-  // necessary.
-  *length_field =
-      std::min(*length_field, kHttp2MaxControlFrameSendSize - kFrameHeaderSize);
-}
-
-SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) {
-  uint8_t flags = 0;
-  // The size of this frame, including padding (if there is any) and
-  // variable-length header block.
-  size_t size = 0;
-  std::string hpack_encoding;
-  int weight = 0;
-  size_t length_field = 0;
-  SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding,
-                                &weight, &length_field);
-
-  SpdyFrameBuilder builder(size);
-  builder.BeginNewFrame(SpdyFrameType::HEADERS, flags, headers.stream_id(),
-                        length_field);
-
-  QUICHE_DCHECK_EQ(kHeadersFrameMinimumSize, builder.length());
-
-  int padding_payload_len = 0;
-  if (headers.padded()) {
-    builder.WriteUInt8(headers.padding_payload_len());
-    padding_payload_len = headers.padding_payload_len();
-  }
-  if (headers.has_priority()) {
-    builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(),
-                                                   headers.parent_stream_id()));
-    // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
-    builder.WriteUInt8(weight - 1);
-  }
-  WritePayloadWithContinuation(&builder, hpack_encoding, headers.stream_id(),
-                               SpdyFrameType::HEADERS, padding_payload_len);
-
-  if (debug_visitor_) {
-    const size_t header_list_size =
-        GetUncompressedSerializedLength(headers.header_block());
-    debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
-                                          SpdyFrameType::HEADERS,
-                                          header_list_size, builder.length());
-  }
-
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeWindowUpdate(
-    const SpdyWindowUpdateIR& window_update) {
-  SpdyFrameBuilder builder(kWindowUpdateFrameSize);
-  builder.BeginNewFrame(SpdyFrameType::WINDOW_UPDATE, kNoFlags,
-                        window_update.stream_id());
-  builder.WriteUInt32(window_update.delta());
-  QUICHE_DCHECK_EQ(kWindowUpdateFrameSize, builder.length());
-  return builder.take();
-}
-
-void SpdyFramer::SerializePushPromiseBuilderHelper(
-    const SpdyPushPromiseIR& push_promise,
-    uint8_t* flags,
-    std::string* hpack_encoding,
-    size_t* size) {
-  *flags = 0;
-  // This will get overwritten if we overflow into a CONTINUATION frame.
-  *flags = *flags | PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
-  // The size of this frame, including variable-length name-value block.
-  *size = kPushPromiseFrameMinimumSize;
-
-  if (push_promise.padded()) {
-    *flags = *flags | PUSH_PROMISE_FLAG_PADDED;
-    *size = *size + kPadLengthFieldSize;
-    *size = *size + push_promise.padding_payload_len();
-  }
-
-  *hpack_encoding =
-      GetHpackEncoder()->EncodeHeaderBlock(push_promise.header_block());
-  *size = *size + hpack_encoding->size();
-  if (*size > kHttp2MaxControlFrameSendSize) {
-    *size = *size + GetNumberRequiredContinuationFrames(*size) *
-                        kContinuationFrameMinimumSize;
-    *flags = *flags & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
-  }
-}
-
-SpdySerializedFrame SpdyFramer::SerializePushPromise(
-    const SpdyPushPromiseIR& push_promise) {
-  uint8_t flags = 0;
-  size_t size = 0;
-  std::string hpack_encoding;
-  SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding,
-                                    &size);
-
-  SpdyFrameBuilder builder(size);
-  size_t length =
-      std::min(size, kHttp2MaxControlFrameSendSize) - kFrameHeaderSize;
-  builder.BeginNewFrame(SpdyFrameType::PUSH_PROMISE, flags,
-                        push_promise.stream_id(), length);
-  int padding_payload_len = 0;
-  if (push_promise.padded()) {
-    builder.WriteUInt8(push_promise.padding_payload_len());
-    builder.WriteUInt32(push_promise.promised_stream_id());
-    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize + kPadLengthFieldSize,
-                     builder.length());
-
-    padding_payload_len = push_promise.padding_payload_len();
-  } else {
-    builder.WriteUInt32(push_promise.promised_stream_id());
-    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize, builder.length());
-  }
-
-  WritePayloadWithContinuation(
-      &builder, hpack_encoding, push_promise.stream_id(),
-      SpdyFrameType::PUSH_PROMISE, padding_payload_len);
-
-  if (debug_visitor_) {
-    const size_t header_list_size =
-        GetUncompressedSerializedLength(push_promise.header_block());
-    debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
-                                          SpdyFrameType::PUSH_PROMISE,
-                                          header_list_size, builder.length());
-  }
-
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeContinuation(
-    const SpdyContinuationIR& continuation) const {
-  const std::string& encoding = continuation.encoding();
-  size_t frame_size = kContinuationFrameMinimumSize + encoding.size();
-  SpdyFrameBuilder builder(frame_size);
-  uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0;
-  builder.BeginNewFrame(SpdyFrameType::CONTINUATION, flags,
-                        continuation.stream_id());
-  QUICHE_DCHECK_EQ(kFrameHeaderSize, builder.length());
-
-  builder.WriteBytes(encoding.data(), encoding.size());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) {
-  std::string value;
-  size_t size = 0;
-  SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size);
-  SpdyFrameBuilder builder(size);
-  builder.BeginNewFrame(SpdyFrameType::ALTSVC, kNoFlags, altsvc_ir.stream_id());
-
-  builder.WriteUInt16(altsvc_ir.origin().length());
-  builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length());
-  builder.WriteBytes(value.data(), value.length());
-  QUICHE_DCHECK_LT(kGetAltSvcFrameMinimumSize, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializePriority(
-    const SpdyPriorityIR& priority) const {
-  SpdyFrameBuilder builder(kPriorityFrameSize);
-  builder.BeginNewFrame(SpdyFrameType::PRIORITY, kNoFlags,
-                        priority.stream_id());
-
-  builder.WriteUInt32(PackStreamDependencyValues(priority.exclusive(),
-                                                 priority.parent_stream_id()));
-  // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
-  builder.WriteUInt8(priority.weight() - 1);
-  QUICHE_DCHECK_EQ(kPriorityFrameSize, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializePriorityUpdate(
-    const SpdyPriorityUpdateIR& priority_update) const {
-  const size_t total_size = kPriorityUpdateFrameMinimumSize +
-                            priority_update.priority_field_value().size();
-  SpdyFrameBuilder builder(total_size);
-  builder.BeginNewFrame(SpdyFrameType::PRIORITY_UPDATE, kNoFlags,
-                        priority_update.stream_id());
-
-  builder.WriteUInt32(priority_update.prioritized_stream_id());
-  builder.WriteBytes(priority_update.priority_field_value().data(),
-                     priority_update.priority_field_value().size());
-  QUICHE_DCHECK_EQ(total_size, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeAcceptCh(
-    const SpdyAcceptChIR& accept_ch) const {
-  const size_t total_size = accept_ch.size();
-  SpdyFrameBuilder builder(total_size);
-  builder.BeginNewFrame(SpdyFrameType::ACCEPT_CH, kNoFlags,
-                        accept_ch.stream_id());
-
-  for (const AcceptChOriginValuePair& entry : accept_ch.entries()) {
-    builder.WriteUInt16(entry.origin.size());
-    builder.WriteBytes(entry.origin.data(), entry.origin.size());
-    builder.WriteUInt16(entry.value.size());
-    builder.WriteBytes(entry.value.data(), entry.value.size());
-  }
-
-  QUICHE_DCHECK_EQ(total_size, builder.length());
-  return builder.take();
-}
-
-SpdySerializedFrame SpdyFramer::SerializeUnknown(
-    const SpdyUnknownIR& unknown) const {
-  const size_t total_size = kFrameHeaderSize + unknown.payload().size();
-  SpdyFrameBuilder builder(total_size);
-  builder.BeginNewUncheckedFrame(unknown.type(), unknown.flags(),
-                                 unknown.stream_id(), unknown.length());
-  builder.WriteBytes(unknown.payload().data(), unknown.payload().size());
-  return builder.take();
-}
-
-namespace {
-
-class FrameSerializationVisitor : public SpdyFrameVisitor {
- public:
-  explicit FrameSerializationVisitor(SpdyFramer* framer)
-      : framer_(framer), frame_() {}
-  ~FrameSerializationVisitor() override = default;
-
-  SpdySerializedFrame ReleaseSerializedFrame() { return std::move(frame_); }
-
-  void VisitData(const SpdyDataIR& data) override {
-    frame_ = framer_->SerializeData(data);
-  }
-  void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
-    frame_ = framer_->SerializeRstStream(rst_stream);
-  }
-  void VisitSettings(const SpdySettingsIR& settings) override {
-    frame_ = framer_->SerializeSettings(settings);
-  }
-  void VisitPing(const SpdyPingIR& ping) override {
-    frame_ = framer_->SerializePing(ping);
-  }
-  void VisitGoAway(const SpdyGoAwayIR& goaway) override {
-    frame_ = framer_->SerializeGoAway(goaway);
-  }
-  void VisitHeaders(const SpdyHeadersIR& headers) override {
-    frame_ = framer_->SerializeHeaders(headers);
-  }
-  void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
-    frame_ = framer_->SerializeWindowUpdate(window_update);
-  }
-  void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
-    frame_ = framer_->SerializePushPromise(push_promise);
-  }
-  void VisitContinuation(const SpdyContinuationIR& continuation) override {
-    frame_ = framer_->SerializeContinuation(continuation);
-  }
-  void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
-    frame_ = framer_->SerializeAltSvc(altsvc);
-  }
-  void VisitPriority(const SpdyPriorityIR& priority) override {
-    frame_ = framer_->SerializePriority(priority);
-  }
-  void VisitPriorityUpdate(
-      const SpdyPriorityUpdateIR& priority_update) override {
-    frame_ = framer_->SerializePriorityUpdate(priority_update);
-  }
-  void VisitAcceptCh(const SpdyAcceptChIR& accept_ch) override {
-    frame_ = framer_->SerializeAcceptCh(accept_ch);
-  }
-  void VisitUnknown(const SpdyUnknownIR& unknown) override {
-    frame_ = framer_->SerializeUnknown(unknown);
-  }
-
- private:
-  SpdyFramer* framer_;
-  SpdySerializedFrame frame_;
-};
-
-// TODO(diannahu): Use also in frame serialization.
-class FlagsSerializationVisitor : public SpdyFrameVisitor {
- public:
-  void VisitData(const SpdyDataIR& data) override {
-    flags_ = DATA_FLAG_NONE;
-    if (data.fin()) {
-      flags_ |= DATA_FLAG_FIN;
-    }
-    if (data.padded()) {
-      flags_ |= DATA_FLAG_PADDED;
-    }
-  }
-
-  void VisitRstStream(const SpdyRstStreamIR& /*rst_stream*/) override {
-    flags_ = kNoFlags;
-  }
-
-  void VisitSettings(const SpdySettingsIR& settings) override {
-    flags_ = kNoFlags;
-    if (settings.is_ack()) {
-      flags_ |= SETTINGS_FLAG_ACK;
-    }
-  }
-
-  void VisitPing(const SpdyPingIR& ping) override {
-    flags_ = kNoFlags;
-    if (ping.is_ack()) {
-      flags_ |= PING_FLAG_ACK;
-    }
-  }
-
-  void VisitGoAway(const SpdyGoAwayIR& /*goaway*/) override {
-    flags_ = kNoFlags;
-  }
-
-  // TODO(diannahu): The END_HEADERS flag is incorrect for HEADERS that require
-  //     CONTINUATION frames.
-  void VisitHeaders(const SpdyHeadersIR& headers) override {
-    flags_ = HEADERS_FLAG_END_HEADERS;
-    if (headers.fin()) {
-      flags_ |= CONTROL_FLAG_FIN;
-    }
-    if (headers.padded()) {
-      flags_ |= HEADERS_FLAG_PADDED;
-    }
-    if (headers.has_priority()) {
-      flags_ |= HEADERS_FLAG_PRIORITY;
-    }
-  }
-
-  void VisitWindowUpdate(const SpdyWindowUpdateIR& /*window_update*/) override {
-    flags_ = kNoFlags;
-  }
-
-  // TODO(diannahu): The END_PUSH_PROMISE flag is incorrect for PUSH_PROMISEs
-  //     that require CONTINUATION frames.
-  void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
-    flags_ = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
-    if (push_promise.padded()) {
-      flags_ |= PUSH_PROMISE_FLAG_PADDED;
-    }
-  }
-
-  // TODO(diannahu): The END_HEADERS flag is incorrect for CONTINUATIONs that
-  //     require CONTINUATION frames.
-  void VisitContinuation(const SpdyContinuationIR& /*continuation*/) override {
-    flags_ = HEADERS_FLAG_END_HEADERS;
-  }
-
-  void VisitAltSvc(const SpdyAltSvcIR& /*altsvc*/) override {
-    flags_ = kNoFlags;
-  }
-
-  void VisitPriority(const SpdyPriorityIR& /*priority*/) override {
-    flags_ = kNoFlags;
-  }
-
-  void VisitPriorityUpdate(
-      const SpdyPriorityUpdateIR& /*priority_update*/) override {
-    flags_ = kNoFlags;
-  }
-
-  void VisitAcceptCh(const SpdyAcceptChIR& /*accept_ch*/) override {
-    flags_ = kNoFlags;
-  }
-
-  uint8_t flags() const { return flags_; }
-
- private:
-  uint8_t flags_ = kNoFlags;
-};
-
-}  // namespace
-
-SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
-  FrameSerializationVisitor visitor(this);
-  frame.Visit(&visitor);
-  return visitor.ReleaseSerializedFrame();
-}
-
-uint8_t SpdyFramer::GetSerializedFlags(const SpdyFrameIR& frame) {
-  FlagsSerializationVisitor visitor;
-  frame.Visit(&visitor);
-  return visitor.flags();
-}
-
-bool SpdyFramer::SerializeData(const SpdyDataIR& data_ir,
-                               ZeroCopyOutputBuffer* output) const {
-  uint8_t flags = DATA_FLAG_NONE;
-  int num_padding_fields = 0;
-  size_t size_with_padding = 0;
-  SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields,
-                             &size_with_padding);
-  SpdyFrameBuilder builder(size_with_padding, output);
-
-  bool ok =
-      builder.BeginNewFrame(SpdyFrameType::DATA, flags, data_ir.stream_id());
-
-  if (data_ir.padded()) {
-    ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
-  }
-
-  ok = ok && builder.WriteBytes(data_ir.data(), data_ir.data_len());
-  if (data_ir.padding_payload_len() > 0) {
-    std::string padding;
-    padding = std::string(data_ir.padding_payload_len(), 0);
-    ok = ok && builder.WriteBytes(padding.data(), padding.length());
-  }
-  QUICHE_DCHECK_EQ(size_with_padding, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
-    const SpdyDataIR& data_ir,
-    ZeroCopyOutputBuffer* output) const {
-  uint8_t flags = DATA_FLAG_NONE;
-  size_t frame_size = 0;
-  size_t num_padding_fields = 0;
-  SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
-      data_ir, &flags, &frame_size, &num_padding_fields);
-
-  SpdyFrameBuilder builder(frame_size, output);
-  bool ok = true;
-  ok = ok &&
-       builder.BeginNewFrame(SpdyFrameType::DATA, flags, data_ir.stream_id(),
-                             num_padding_fields + data_ir.data_len() +
-                                 data_ir.padding_payload_len());
-  if (data_ir.padded()) {
-    ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
-  }
-  QUICHE_DCHECK_EQ(frame_size, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeRstStream(const SpdyRstStreamIR& rst_stream,
-                                    ZeroCopyOutputBuffer* output) const {
-  size_t expected_length = kRstStreamFrameSize;
-  SpdyFrameBuilder builder(expected_length, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::RST_STREAM, 0,
-                                  rst_stream.stream_id());
-  ok = ok && builder.WriteUInt32(rst_stream.error_code());
-
-  QUICHE_DCHECK_EQ(expected_length, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeSettings(const SpdySettingsIR& settings,
-                                   ZeroCopyOutputBuffer* output) const {
-  uint8_t flags = 0;
-  // Size, in bytes, of this SETTINGS frame.
-  size_t size = 0;
-  const SettingsMap* values = &(settings.values());
-  SerializeSettingsBuilderHelper(settings, &flags, values, &size);
-  SpdyFrameBuilder builder(size, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::SETTINGS, flags, 0);
-
-  // If this is an ACK, payload should be empty.
-  if (settings.is_ack()) {
-    return ok;
-  }
-
-  QUICHE_DCHECK_EQ(kSettingsFrameMinimumSize, builder.length());
-  for (auto it = values->begin(); it != values->end(); ++it) {
-    int setting_id = it->first;
-    QUICHE_DCHECK_GE(setting_id, 0);
-    ok = ok && builder.WriteUInt16(static_cast<SpdySettingsId>(setting_id)) &&
-         builder.WriteUInt32(it->second);
-  }
-  QUICHE_DCHECK_EQ(size, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializePing(const SpdyPingIR& ping,
-                               ZeroCopyOutputBuffer* output) const {
-  SpdyFrameBuilder builder(kPingFrameSize, output);
-  uint8_t flags = 0;
-  if (ping.is_ack()) {
-    flags |= PING_FLAG_ACK;
-  }
-  bool ok = builder.BeginNewFrame(SpdyFrameType::PING, flags, 0);
-  ok = ok && builder.WriteUInt64(ping.id());
-  QUICHE_DCHECK_EQ(kPingFrameSize, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeGoAway(const SpdyGoAwayIR& goaway,
-                                 ZeroCopyOutputBuffer* output) const {
-  // Compute the output buffer size, take opaque data into account.
-  size_t expected_length = kGoawayFrameMinimumSize;
-  expected_length += goaway.description().size();
-  SpdyFrameBuilder builder(expected_length, output);
-
-  // Serialize the GOAWAY frame.
-  bool ok = builder.BeginNewFrame(SpdyFrameType::GOAWAY, 0, 0);
-
-  // GOAWAY frames specify the last good stream id.
-  ok = ok && builder.WriteUInt32(goaway.last_good_stream_id()) &&
-       // GOAWAY frames also specify the error status code.
-       builder.WriteUInt32(goaway.error_code());
-
-  // GOAWAY frames may also specify opaque data.
-  if (!goaway.description().empty()) {
-    ok = ok && builder.WriteBytes(goaway.description().data(),
-                                  goaway.description().size());
-  }
-
-  QUICHE_DCHECK_EQ(expected_length, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers,
-                                  ZeroCopyOutputBuffer* output) {
-  uint8_t flags = 0;
-  // The size of this frame, including padding (if there is any) and
-  // variable-length header block.
-  size_t size = 0;
-  std::string hpack_encoding;
-  int weight = 0;
-  size_t length_field = 0;
-  SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding,
-                                &weight, &length_field);
-
-  bool ok = true;
-  SpdyFrameBuilder builder(size, output);
-  ok = ok && builder.BeginNewFrame(SpdyFrameType::HEADERS, flags,
-                                   headers.stream_id(), length_field);
-  QUICHE_DCHECK_EQ(kHeadersFrameMinimumSize, builder.length());
-
-  int padding_payload_len = 0;
-  if (headers.padded()) {
-    ok = ok && builder.WriteUInt8(headers.padding_payload_len());
-    padding_payload_len = headers.padding_payload_len();
-  }
-  if (headers.has_priority()) {
-    ok = ok &&
-         builder.WriteUInt32(PackStreamDependencyValues(
-             headers.exclusive(), headers.parent_stream_id())) &&
-         // Per RFC 7540 section 6.3, serialized weight value is weight - 1.
-         builder.WriteUInt8(weight - 1);
-  }
-  ok = ok && WritePayloadWithContinuation(
-                 &builder, hpack_encoding, headers.stream_id(),
-                 SpdyFrameType::HEADERS, padding_payload_len);
-
-  if (debug_visitor_) {
-    const size_t header_list_size =
-        GetUncompressedSerializedLength(headers.header_block());
-    debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
-                                          SpdyFrameType::HEADERS,
-                                          header_list_size, builder.length());
-  }
-
-  return ok;
-}
-
-bool SpdyFramer::SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
-                                       ZeroCopyOutputBuffer* output) const {
-  SpdyFrameBuilder builder(kWindowUpdateFrameSize, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::WINDOW_UPDATE, kNoFlags,
-                                  window_update.stream_id());
-  ok = ok && builder.WriteUInt32(window_update.delta());
-  QUICHE_DCHECK_EQ(kWindowUpdateFrameSize, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise,
-                                      ZeroCopyOutputBuffer* output) {
-  uint8_t flags = 0;
-  size_t size = 0;
-  std::string hpack_encoding;
-  SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding,
-                                    &size);
-
-  bool ok = true;
-  SpdyFrameBuilder builder(size, output);
-  size_t length =
-      std::min(size, kHttp2MaxControlFrameSendSize) - kFrameHeaderSize;
-  ok = builder.BeginNewFrame(SpdyFrameType::PUSH_PROMISE, flags,
-                             push_promise.stream_id(), length);
-
-  int padding_payload_len = 0;
-  if (push_promise.padded()) {
-    ok = ok && builder.WriteUInt8(push_promise.padding_payload_len()) &&
-         builder.WriteUInt32(push_promise.promised_stream_id());
-    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize + kPadLengthFieldSize,
-                     builder.length());
-
-    padding_payload_len = push_promise.padding_payload_len();
-  } else {
-    ok = ok && builder.WriteUInt32(push_promise.promised_stream_id());
-    QUICHE_DCHECK_EQ(kPushPromiseFrameMinimumSize, builder.length());
-  }
-
-  ok = ok && WritePayloadWithContinuation(
-                 &builder, hpack_encoding, push_promise.stream_id(),
-                 SpdyFrameType::PUSH_PROMISE, padding_payload_len);
-
-  if (debug_visitor_) {
-    const size_t header_list_size =
-        GetUncompressedSerializedLength(push_promise.header_block());
-    debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
-                                          SpdyFrameType::PUSH_PROMISE,
-                                          header_list_size, builder.length());
-  }
-
-  return ok;
-}
-
-bool SpdyFramer::SerializeContinuation(const SpdyContinuationIR& continuation,
-                                       ZeroCopyOutputBuffer* output) const {
-  const std::string& encoding = continuation.encoding();
-  size_t frame_size = kContinuationFrameMinimumSize + encoding.size();
-  SpdyFrameBuilder builder(frame_size, output);
-  uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0;
-  bool ok = builder.BeginNewFrame(SpdyFrameType::CONTINUATION, flags,
-                                  continuation.stream_id(),
-                                  frame_size - kFrameHeaderSize);
-  QUICHE_DCHECK_EQ(kFrameHeaderSize, builder.length());
-
-  ok = ok && builder.WriteBytes(encoding.data(), encoding.size());
-  return ok;
-}
-
-bool SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir,
-                                 ZeroCopyOutputBuffer* output) {
-  std::string value;
-  size_t size = 0;
-  SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size);
-  SpdyFrameBuilder builder(size, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::ALTSVC, kNoFlags,
-                                  altsvc_ir.stream_id()) &&
-            builder.WriteUInt16(altsvc_ir.origin().length()) &&
-            builder.WriteBytes(altsvc_ir.origin().data(),
-                               altsvc_ir.origin().length()) &&
-            builder.WriteBytes(value.data(), value.length());
-  QUICHE_DCHECK_LT(kGetAltSvcFrameMinimumSize, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializePriority(const SpdyPriorityIR& priority,
-                                   ZeroCopyOutputBuffer* output) const {
-  SpdyFrameBuilder builder(kPriorityFrameSize, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::PRIORITY, kNoFlags,
-                                  priority.stream_id());
-  ok = ok &&
-       builder.WriteUInt32(PackStreamDependencyValues(
-           priority.exclusive(), priority.parent_stream_id())) &&
-       // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
-       builder.WriteUInt8(priority.weight() - 1);
-  QUICHE_DCHECK_EQ(kPriorityFrameSize, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializePriorityUpdate(
-    const SpdyPriorityUpdateIR& priority_update,
-    ZeroCopyOutputBuffer* output) const {
-  const size_t total_size = kPriorityUpdateFrameMinimumSize +
-                            priority_update.priority_field_value().size();
-  SpdyFrameBuilder builder(total_size, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::PRIORITY_UPDATE, kNoFlags,
-                                  priority_update.stream_id());
-
-  ok = ok && builder.WriteUInt32(priority_update.prioritized_stream_id());
-  ok = ok && builder.WriteBytes(priority_update.priority_field_value().data(),
-                                priority_update.priority_field_value().size());
-  QUICHE_DCHECK_EQ(total_size, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeAcceptCh(const SpdyAcceptChIR& accept_ch,
-                                   ZeroCopyOutputBuffer* output) const {
-  const size_t total_size = accept_ch.size();
-  SpdyFrameBuilder builder(total_size, output);
-  bool ok = builder.BeginNewFrame(SpdyFrameType::ACCEPT_CH, kNoFlags,
-                                  accept_ch.stream_id());
-
-  for (const AcceptChOriginValuePair& entry : accept_ch.entries()) {
-    ok = ok && builder.WriteUInt16(entry.origin.size());
-    ok = ok && builder.WriteBytes(entry.origin.data(), entry.origin.size());
-    ok = ok && builder.WriteUInt16(entry.value.size());
-    ok = ok && builder.WriteBytes(entry.value.data(), entry.value.size());
-  }
-
-  QUICHE_DCHECK_EQ(total_size, builder.length());
-  return ok;
-}
-
-bool SpdyFramer::SerializeUnknown(const SpdyUnknownIR& unknown,
-                                  ZeroCopyOutputBuffer* output) const {
-  const size_t total_size = kFrameHeaderSize + unknown.payload().size();
-  SpdyFrameBuilder builder(total_size, output);
-  bool ok = builder.BeginNewUncheckedFrame(
-      unknown.type(), unknown.flags(), unknown.stream_id(), unknown.length());
-  ok = ok &&
-       builder.WriteBytes(unknown.payload().data(), unknown.payload().size());
-  return ok;
-}
-
-namespace {
-
-class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor {
- public:
-  explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer,
-                                               ZeroCopyOutputBuffer* output)
-      : framer_(framer), output_(output), result_(false) {}
-  ~FrameSerializationVisitorWithOutput() override = default;
-
-  size_t Result() { return result_; }
-
-  void VisitData(const SpdyDataIR& data) override {
-    result_ = framer_->SerializeData(data, output_);
-  }
-  void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
-    result_ = framer_->SerializeRstStream(rst_stream, output_);
-  }
-  void VisitSettings(const SpdySettingsIR& settings) override {
-    result_ = framer_->SerializeSettings(settings, output_);
-  }
-  void VisitPing(const SpdyPingIR& ping) override {
-    result_ = framer_->SerializePing(ping, output_);
-  }
-  void VisitGoAway(const SpdyGoAwayIR& goaway) override {
-    result_ = framer_->SerializeGoAway(goaway, output_);
-  }
-  void VisitHeaders(const SpdyHeadersIR& headers) override {
-    result_ = framer_->SerializeHeaders(headers, output_);
-  }
-  void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
-    result_ = framer_->SerializeWindowUpdate(window_update, output_);
-  }
-  void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
-    result_ = framer_->SerializePushPromise(push_promise, output_);
-  }
-  void VisitContinuation(const SpdyContinuationIR& continuation) override {
-    result_ = framer_->SerializeContinuation(continuation, output_);
-  }
-  void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
-    result_ = framer_->SerializeAltSvc(altsvc, output_);
-  }
-  void VisitPriority(const SpdyPriorityIR& priority) override {
-    result_ = framer_->SerializePriority(priority, output_);
-  }
-  void VisitPriorityUpdate(
-      const SpdyPriorityUpdateIR& priority_update) override {
-    result_ = framer_->SerializePriorityUpdate(priority_update, output_);
-  }
-  void VisitAcceptCh(const SpdyAcceptChIR& accept_ch) override {
-    result_ = framer_->SerializeAcceptCh(accept_ch, output_);
-  }
-
-  void VisitUnknown(const SpdyUnknownIR& unknown) override {
-    result_ = framer_->SerializeUnknown(unknown, output_);
-  }
-
- private:
-  SpdyFramer* framer_;
-  ZeroCopyOutputBuffer* output_;
-  bool result_;
-};
-
-}  // namespace
-
-size_t SpdyFramer::SerializeFrame(const SpdyFrameIR& frame,
-                                  ZeroCopyOutputBuffer* output) {
-  FrameSerializationVisitorWithOutput visitor(this, output);
-  size_t free_bytes_before = output->BytesFree();
-  frame.Visit(&visitor);
-  return visitor.Result() ? free_bytes_before - output->BytesFree() : 0;
-}
-
-HpackEncoder* SpdyFramer::GetHpackEncoder() {
-  if (hpack_encoder_ == nullptr) {
-    hpack_encoder_ = std::make_unique<HpackEncoder>();
-    if (!compression_enabled()) {
-      hpack_encoder_->DisableCompression();
-    }
-  }
-  return hpack_encoder_.get();
-}
-
-void SpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) {
-  GetHpackEncoder()->ApplyHeaderTableSizeSetting(value);
-}
-
-size_t SpdyFramer::header_encoder_table_size() const {
-  if (hpack_encoder_ == nullptr) {
-    return kDefaultHeaderTableSizeSetting;
-  } else {
-    return hpack_encoder_->CurrentHeaderTableSizeSetting();
-  }
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_framer.h b/spdy/core/spdy_framer.h
deleted file mode 100644
index 6f7a5dc..0000000
--- a/spdy/core/spdy_framer.h
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_FRAMER_H_
-#define QUICHE_SPDY_CORE_SPDY_FRAMER_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/hpack/hpack_encoder.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_headers_handler_interface.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/zero_copy_output_buffer.h"
-
-namespace spdy {
-
-namespace test {
-
-class SpdyFramerPeer;
-class SpdyFramerTest_MultipleContinuationFramesWithIterator_Test;
-class SpdyFramerTest_PushPromiseFramesWithIterator_Test;
-
-}  // namespace test
-
-class QUICHE_EXPORT_PRIVATE SpdyFrameSequence {
- public:
-  virtual ~SpdyFrameSequence() {}
-
-  // Serializes the next frame in the sequence to |output|. Returns the number
-  // of bytes written to |output|.
-  virtual size_t NextFrame(ZeroCopyOutputBuffer* output) = 0;
-
-  // Returns true iff there is at least one more frame in the sequence.
-  virtual bool HasNextFrame() const = 0;
-
-  // Get SpdyFrameIR of the frame to be serialized.
-  virtual const SpdyFrameIR& GetIR() const = 0;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyFramer {
- public:
-  enum CompressionOption {
-    ENABLE_COMPRESSION,
-    DISABLE_COMPRESSION,
-  };
-
-  // Create a SpdyFrameSequence to serialize |frame_ir|.
-  static std::unique_ptr<SpdyFrameSequence> CreateIterator(
-      SpdyFramer* framer,
-      std::unique_ptr<const SpdyFrameIR> frame_ir);
-
-  // Gets the serialized flags for the given |frame|.
-  static uint8_t GetSerializedFlags(const SpdyFrameIR& frame);
-
-  // Serialize a data frame.
-  static SpdySerializedFrame SerializeData(const SpdyDataIR& data_ir);
-  // Serializes the data frame header and optionally padding length fields,
-  // excluding actual data payload and padding.
-  static SpdySerializedFrame SerializeDataFrameHeaderWithPaddingLengthField(
-      const SpdyDataIR& data_ir);
-
-  // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
-  // frame is used to implement per stream flow control.
-  static SpdySerializedFrame SerializeWindowUpdate(
-      const SpdyWindowUpdateIR& window_update);
-
-  explicit SpdyFramer(CompressionOption option);
-
-  virtual ~SpdyFramer();
-
-  // Set debug callbacks to be called from the framer. The debug visitor is
-  // completely optional and need not be set in order for normal operation.
-  // If this is called multiple times, only the last visitor will be used.
-  void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
-
-  SpdySerializedFrame SerializeRstStream(
-      const SpdyRstStreamIR& rst_stream) const;
-
-  // Serializes a SETTINGS frame. The SETTINGS frame is
-  // used to communicate name/value pairs relevant to the communication channel.
-  SpdySerializedFrame SerializeSettings(const SpdySettingsIR& settings) const;
-
-  // Serializes a PING frame. The unique_id is used to
-  // identify the ping request/response.
-  SpdySerializedFrame SerializePing(const SpdyPingIR& ping) const;
-
-  // Serializes a GOAWAY frame. The GOAWAY frame is used
-  // prior to the shutting down of the TCP connection, and includes the
-  // stream_id of the last stream the sender of the frame is willing to process
-  // to completion.
-  SpdySerializedFrame SerializeGoAway(const SpdyGoAwayIR& goaway) const;
-
-  // Serializes a HEADERS frame. The HEADERS frame is used
-  // for sending headers.
-  SpdySerializedFrame SerializeHeaders(const SpdyHeadersIR& headers);
-
-  // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
-  // to inform the client that it will be receiving an additional stream
-  // in response to the original request. The frame includes synthesized
-  // headers to explain the upcoming data.
-  SpdySerializedFrame SerializePushPromise(
-      const SpdyPushPromiseIR& push_promise);
-
-  // Serializes a CONTINUATION frame. The CONTINUATION frame is used
-  // to continue a sequence of header block fragments.
-  SpdySerializedFrame SerializeContinuation(
-      const SpdyContinuationIR& continuation) const;
-
-  // Serializes an ALTSVC frame. The ALTSVC frame advertises the
-  // availability of an alternative service to the client.
-  SpdySerializedFrame SerializeAltSvc(const SpdyAltSvcIR& altsvc);
-
-  // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
-  // the relative priority of the given stream.
-  SpdySerializedFrame SerializePriority(const SpdyPriorityIR& priority) const;
-
-  // Serializes a PRIORITY_UPDATE frame.
-  // See https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html.
-  SpdySerializedFrame SerializePriorityUpdate(
-      const SpdyPriorityUpdateIR& priority_update) const;
-
-  // Serializes an ACCEPT_CH frame.  See
-  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02.
-  SpdySerializedFrame SerializeAcceptCh(const SpdyAcceptChIR& accept_ch) const;
-
-  // Serializes an unknown frame given a frame header and payload.
-  SpdySerializedFrame SerializeUnknown(const SpdyUnknownIR& unknown) const;
-
-  // Serialize a frame of unknown type.
-  SpdySerializedFrame SerializeFrame(const SpdyFrameIR& frame);
-
-  // Serialize a data frame.
-  bool SerializeData(const SpdyDataIR& data,
-                     ZeroCopyOutputBuffer* output) const;
-
-  // Serializes the data frame header and optionally padding length fields,
-  // excluding actual data payload and padding.
-  bool SerializeDataFrameHeaderWithPaddingLengthField(
-      const SpdyDataIR& data,
-      ZeroCopyOutputBuffer* output) const;
-
-  bool SerializeRstStream(const SpdyRstStreamIR& rst_stream,
-                          ZeroCopyOutputBuffer* output) const;
-
-  // Serializes a SETTINGS frame. The SETTINGS frame is
-  // used to communicate name/value pairs relevant to the communication channel.
-  bool SerializeSettings(const SpdySettingsIR& settings,
-                         ZeroCopyOutputBuffer* output) const;
-
-  // Serializes a PING frame. The unique_id is used to
-  // identify the ping request/response.
-  bool SerializePing(const SpdyPingIR& ping,
-                     ZeroCopyOutputBuffer* output) const;
-
-  // Serializes a GOAWAY frame. The GOAWAY frame is used
-  // prior to the shutting down of the TCP connection, and includes the
-  // stream_id of the last stream the sender of the frame is willing to process
-  // to completion.
-  bool SerializeGoAway(const SpdyGoAwayIR& goaway,
-                       ZeroCopyOutputBuffer* output) const;
-
-  // Serializes a HEADERS frame. The HEADERS frame is used
-  // for sending headers.
-  bool SerializeHeaders(const SpdyHeadersIR& headers,
-                        ZeroCopyOutputBuffer* output);
-
-  // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
-  // frame is used to implement per stream flow control.
-  bool SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
-                             ZeroCopyOutputBuffer* output) const;
-
-  // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
-  // to inform the client that it will be receiving an additional stream
-  // in response to the original request. The frame includes synthesized
-  // headers to explain the upcoming data.
-  bool SerializePushPromise(const SpdyPushPromiseIR& push_promise,
-                            ZeroCopyOutputBuffer* output);
-
-  // Serializes a CONTINUATION frame. The CONTINUATION frame is used
-  // to continue a sequence of header block fragments.
-  bool SerializeContinuation(const SpdyContinuationIR& continuation,
-                             ZeroCopyOutputBuffer* output) const;
-
-  // Serializes an ALTSVC frame. The ALTSVC frame advertises the
-  // availability of an alternative service to the client.
-  bool SerializeAltSvc(const SpdyAltSvcIR& altsvc,
-                       ZeroCopyOutputBuffer* output);
-
-  // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
-  // the relative priority of the given stream.
-  bool SerializePriority(const SpdyPriorityIR& priority,
-                         ZeroCopyOutputBuffer* output) const;
-
-  // Serializes a PRIORITY_UPDATE frame.
-  // See https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html.
-  bool SerializePriorityUpdate(const SpdyPriorityUpdateIR& priority_update,
-                               ZeroCopyOutputBuffer* output) const;
-
-  // Serializes an ACCEPT_CH frame.  See
-  // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02.
-  bool SerializeAcceptCh(const SpdyAcceptChIR& accept_ch,
-                         ZeroCopyOutputBuffer* output) const;
-
-  // Serializes an unknown frame given a frame header and payload.
-  bool SerializeUnknown(const SpdyUnknownIR& unknown,
-                        ZeroCopyOutputBuffer* output) const;
-
-  // Serialize a frame of unknown type.
-  size_t SerializeFrame(const SpdyFrameIR& frame, ZeroCopyOutputBuffer* output);
-
-  // Returns whether this SpdyFramer will compress header blocks using HPACK.
-  bool compression_enabled() const {
-    return compression_option_ == ENABLE_COMPRESSION;
-  }
-
-  void SetHpackIndexingPolicy(HpackEncoder::IndexingPolicy policy) {
-    GetHpackEncoder()->SetIndexingPolicy(std::move(policy));
-  }
-
-  // Updates the maximum size of the header encoder compression table.
-  void UpdateHeaderEncoderTableSize(uint32_t value);
-
-  // Returns the maximum size of the header encoder compression table.
-  size_t header_encoder_table_size() const;
-
-  // Get (and lazily initialize) the HPACK encoder state.
-  HpackEncoder* GetHpackEncoder();
-
-  // Gets the HPACK encoder state. Returns nullptr if the encoder has not been
-  // initialized.
-  const HpackEncoder* GetHpackEncoder() const { return hpack_encoder_.get(); }
-
- protected:
-  friend class test::SpdyFramerPeer;
-  friend class test::SpdyFramerTest_MultipleContinuationFramesWithIterator_Test;
-  friend class test::SpdyFramerTest_PushPromiseFramesWithIterator_Test;
-
-  // Iteratively converts a SpdyFrameIR into an appropriate sequence of Spdy
-  // frames.
-  // Example usage:
-  // std::unique_ptr<SpdyFrameSequence> it = CreateIterator(framer, frame_ir);
-  // while (it->HasNextFrame()) {
-  //   if(it->NextFrame(output) == 0) {
-  //     // Write failed;
-  //   }
-  // }
-  class QUICHE_EXPORT_PRIVATE SpdyFrameIterator : public SpdyFrameSequence {
-   public:
-    // Creates an iterator with the provided framer.
-    // Does not take ownership of |framer|.
-    // |framer| must outlive this instance.
-    explicit SpdyFrameIterator(SpdyFramer* framer);
-    ~SpdyFrameIterator() override;
-
-    // Serializes the next frame in the sequence to |output|. Returns the number
-    // of bytes written to |output|.
-    size_t NextFrame(ZeroCopyOutputBuffer* output) override;
-
-    // Returns true iff there is at least one more frame in the sequence.
-    bool HasNextFrame() const override;
-
-    // SpdyFrameIterator is neither copyable nor movable.
-    SpdyFrameIterator(const SpdyFrameIterator&) = delete;
-    SpdyFrameIterator& operator=(const SpdyFrameIterator&) = delete;
-
-   protected:
-    virtual size_t GetFrameSizeSansBlock() const = 0;
-    virtual bool SerializeGivenEncoding(const std::string& encoding,
-                                        ZeroCopyOutputBuffer* output) const = 0;
-
-    SpdyFramer* GetFramer() const { return framer_; }
-
-    void SetEncoder(const SpdyFrameWithHeaderBlockIR* ir) {
-      encoder_ =
-          framer_->GetHpackEncoder()->EncodeHeaderSet(ir->header_block());
-    }
-
-    bool has_next_frame() const { return has_next_frame_; }
-
-   private:
-    SpdyFramer* const framer_;
-    std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoder_;
-    bool is_first_frame_;
-    bool has_next_frame_;
-  };
-
-  // Iteratively converts a SpdyHeadersIR (with a possibly huge
-  // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and
-  // write to the output.
-  class QUICHE_EXPORT_PRIVATE SpdyHeaderFrameIterator
-      : public SpdyFrameIterator {
-   public:
-    // Does not take ownership of |framer|. Take ownership of |headers_ir|.
-    SpdyHeaderFrameIterator(SpdyFramer* framer,
-                            std::unique_ptr<const SpdyHeadersIR> headers_ir);
-
-    ~SpdyHeaderFrameIterator() override;
-
-   private:
-    const SpdyFrameIR& GetIR() const override;
-    size_t GetFrameSizeSansBlock() const override;
-    bool SerializeGivenEncoding(const std::string& encoding,
-                                ZeroCopyOutputBuffer* output) const override;
-
-    const std::unique_ptr<const SpdyHeadersIR> headers_ir_;
-  };
-
-  // Iteratively converts a SpdyPushPromiseIR (with a possibly huge
-  // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and
-  // write to the output.
-  class QUICHE_EXPORT_PRIVATE SpdyPushPromiseFrameIterator
-      : public SpdyFrameIterator {
-   public:
-    // Does not take ownership of |framer|. Take ownership of |push_promise_ir|.
-    SpdyPushPromiseFrameIterator(
-        SpdyFramer* framer,
-        std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir);
-
-    ~SpdyPushPromiseFrameIterator() override;
-
-   private:
-    const SpdyFrameIR& GetIR() const override;
-    size_t GetFrameSizeSansBlock() const override;
-    bool SerializeGivenEncoding(const std::string& encoding,
-                                ZeroCopyOutputBuffer* output) const override;
-
-    const std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir_;
-  };
-
-  // Converts a SpdyFrameIR into one Spdy frame (a sequence of length 1), and
-  // write it to the output.
-  class QUICHE_EXPORT_PRIVATE SpdyControlFrameIterator
-      : public SpdyFrameSequence {
-   public:
-    SpdyControlFrameIterator(SpdyFramer* framer,
-                             std::unique_ptr<const SpdyFrameIR> frame_ir);
-    ~SpdyControlFrameIterator() override;
-
-    size_t NextFrame(ZeroCopyOutputBuffer* output) override;
-
-    bool HasNextFrame() const override;
-
-    const SpdyFrameIR& GetIR() const override;
-
-   private:
-    SpdyFramer* const framer_;
-    std::unique_ptr<const SpdyFrameIR> frame_ir_;
-    bool has_next_frame_ = true;
-  };
-
- private:
-  void SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
-                                     uint8_t* flags,
-                                     size_t* size,
-                                     std::string* hpack_encoding,
-                                     int* weight,
-                                     size_t* length_field);
-  void SerializePushPromiseBuilderHelper(const SpdyPushPromiseIR& push_promise,
-                                         uint8_t* flags,
-                                         std::string* hpack_encoding,
-                                         size_t* size);
-
-  std::unique_ptr<HpackEncoder> hpack_encoder_;
-
-  SpdyFramerDebugVisitorInterface* debug_visitor_;
-
-  // Determines whether HPACK compression is used.
-  const CompressionOption compression_option_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_FRAMER_H_
diff --git a/spdy/core/spdy_framer_test.cc b/spdy/core/spdy_framer_test.cc
deleted file mode 100644
index 236a02f..0000000
--- a/spdy/core/spdy_framer_test.cc
+++ /dev/null
@@ -1,5085 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_framer.h"
-
-#include <stdlib.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/array_output_buffer.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/mock_spdy_framer_visitor.h"
-#include "spdy/core/recording_headers_handler.h"
-#include "spdy/core/spdy_bitmasks.h"
-#include "spdy/core/spdy_frame_builder.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/spdy_test_utils.h"
-
-using ::http2::Http2DecoderAdapter;
-using ::testing::_;
-
-namespace spdy {
-
-namespace test {
-
-namespace {
-
-const int64_t kSize = 1024 * 1024;
-char output_buffer[kSize] = "";
-
-// frame_list_char is used to hold frames to be compared with output_buffer.
-const int64_t buffer_size = 64 * 1024;
-char frame_list_char[buffer_size] = "";
-}  // namespace
-
-class MockDebugVisitor : public SpdyFramerDebugVisitorInterface {
- public:
-  MOCK_METHOD4(OnSendCompressedFrame,
-               void(SpdyStreamId stream_id,
-                    SpdyFrameType type,
-                    size_t payload_len,
-                    size_t frame_len));
-
-  MOCK_METHOD3(OnReceiveCompressedFrame,
-               void(SpdyStreamId stream_id,
-                    SpdyFrameType type,
-                    size_t frame_len));
-};
-
-MATCHER_P(IsFrameUnionOf, frame_list, "") {
-  size_t size_verified = 0;
-  for (const auto& frame : *frame_list) {
-    if (arg.size() < size_verified + frame.size()) {
-      QUICHE_LOG(FATAL)
-          << "Incremental header serialization should not lead to a "
-          << "higher total frame length than non-incremental method.";
-      return false;
-    }
-    if (memcmp(arg.data() + size_verified, frame.data(), frame.size())) {
-      CompareCharArraysWithHexError(
-          "Header serialization methods should be equivalent: ",
-          reinterpret_cast<unsigned char*>(arg.data() + size_verified),
-          frame.size(), reinterpret_cast<unsigned char*>(frame.data()),
-          frame.size());
-      return false;
-    }
-    size_verified += frame.size();
-  }
-  return size_verified == arg.size();
-}
-
-class SpdyFramerPeer {
- public:
-  // TODO(dahollings): Remove these methods when deprecating non-incremental
-  // header serialization path.
-  static std::unique_ptr<SpdyHeadersIR> CloneSpdyHeadersIR(
-      const SpdyHeadersIR& headers) {
-    auto new_headers = std::make_unique<SpdyHeadersIR>(
-        headers.stream_id(), headers.header_block().Clone());
-    new_headers->set_fin(headers.fin());
-    new_headers->set_has_priority(headers.has_priority());
-    new_headers->set_weight(headers.weight());
-    new_headers->set_parent_stream_id(headers.parent_stream_id());
-    new_headers->set_exclusive(headers.exclusive());
-    if (headers.padded()) {
-      new_headers->set_padding_len(headers.padding_payload_len() + 1);
-    }
-    return new_headers;
-  }
-
-  static SpdySerializedFrame SerializeHeaders(SpdyFramer* framer,
-                                              const SpdyHeadersIR& headers) {
-    SpdySerializedFrame serialized_headers_old_version(
-        framer->SerializeHeaders(headers));
-    framer->hpack_encoder_.reset(nullptr);
-    auto* saved_debug_visitor = framer->debug_visitor_;
-    framer->debug_visitor_ = nullptr;
-
-    std::vector<SpdySerializedFrame> frame_list;
-    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
-    SpdyFramer::SpdyHeaderFrameIterator it(framer, CloneSpdyHeadersIR(headers));
-    while (it.HasNextFrame()) {
-      size_t size_before = frame_list_buffer.Size();
-      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
-      frame_list.emplace_back(
-          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
-                              frame_list_buffer.Size() - size_before, false));
-    }
-    framer->debug_visitor_ = saved_debug_visitor;
-
-    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
-    return serialized_headers_old_version;
-  }
-
-  static SpdySerializedFrame SerializeHeaders(SpdyFramer* framer,
-                                              const SpdyHeadersIR& headers,
-                                              ArrayOutputBuffer* output) {
-    if (output == nullptr) {
-      return SerializeHeaders(framer, headers);
-    }
-    output->Reset();
-    EXPECT_TRUE(framer->SerializeHeaders(headers, output));
-    SpdySerializedFrame serialized_headers_old_version(output->Begin(),
-                                                       output->Size(), false);
-    framer->hpack_encoder_.reset(nullptr);
-    auto* saved_debug_visitor = framer->debug_visitor_;
-    framer->debug_visitor_ = nullptr;
-
-    std::vector<SpdySerializedFrame> frame_list;
-    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
-    SpdyFramer::SpdyHeaderFrameIterator it(framer, CloneSpdyHeadersIR(headers));
-    while (it.HasNextFrame()) {
-      size_t size_before = frame_list_buffer.Size();
-      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
-      frame_list.emplace_back(
-          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
-                              frame_list_buffer.Size() - size_before, false));
-    }
-    framer->debug_visitor_ = saved_debug_visitor;
-
-    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
-    return serialized_headers_old_version;
-  }
-
-  static std::unique_ptr<SpdyPushPromiseIR> CloneSpdyPushPromiseIR(
-      const SpdyPushPromiseIR& push_promise) {
-    auto new_push_promise = std::make_unique<SpdyPushPromiseIR>(
-        push_promise.stream_id(), push_promise.promised_stream_id(),
-        push_promise.header_block().Clone());
-    new_push_promise->set_fin(push_promise.fin());
-    if (push_promise.padded()) {
-      new_push_promise->set_padding_len(push_promise.padding_payload_len() + 1);
-    }
-    return new_push_promise;
-  }
-
-  static SpdySerializedFrame SerializePushPromise(
-      SpdyFramer* framer,
-      const SpdyPushPromiseIR& push_promise) {
-    SpdySerializedFrame serialized_headers_old_version =
-        framer->SerializePushPromise(push_promise);
-    framer->hpack_encoder_.reset(nullptr);
-    auto* saved_debug_visitor = framer->debug_visitor_;
-    framer->debug_visitor_ = nullptr;
-
-    std::vector<SpdySerializedFrame> frame_list;
-    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
-    frame_list_buffer.Reset();
-    SpdyFramer::SpdyPushPromiseFrameIterator it(
-        framer, CloneSpdyPushPromiseIR(push_promise));
-    while (it.HasNextFrame()) {
-      size_t size_before = frame_list_buffer.Size();
-      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
-      frame_list.emplace_back(
-          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
-                              frame_list_buffer.Size() - size_before, false));
-    }
-    framer->debug_visitor_ = saved_debug_visitor;
-
-    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
-    return serialized_headers_old_version;
-  }
-
-  static SpdySerializedFrame SerializePushPromise(
-      SpdyFramer* framer,
-      const SpdyPushPromiseIR& push_promise,
-      ArrayOutputBuffer* output) {
-    if (output == nullptr) {
-      return SerializePushPromise(framer, push_promise);
-    }
-    output->Reset();
-    EXPECT_TRUE(framer->SerializePushPromise(push_promise, output));
-    SpdySerializedFrame serialized_headers_old_version(output->Begin(),
-                                                       output->Size(), false);
-    framer->hpack_encoder_.reset(nullptr);
-    auto* saved_debug_visitor = framer->debug_visitor_;
-    framer->debug_visitor_ = nullptr;
-
-    std::vector<SpdySerializedFrame> frame_list;
-    ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
-    frame_list_buffer.Reset();
-    SpdyFramer::SpdyPushPromiseFrameIterator it(
-        framer, CloneSpdyPushPromiseIR(push_promise));
-    while (it.HasNextFrame()) {
-      size_t size_before = frame_list_buffer.Size();
-      EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
-      frame_list.emplace_back(
-          SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
-                              frame_list_buffer.Size() - size_before, false));
-    }
-    framer->debug_visitor_ = saved_debug_visitor;
-
-    EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
-    return serialized_headers_old_version;
-  }
-};
-
-class TestSpdyVisitor : public SpdyFramerVisitorInterface,
-                        public SpdyFramerDebugVisitorInterface {
- public:
-  // This is larger than our max frame size because header blocks that
-  // are too long can spill over into CONTINUATION frames.
-  static constexpr size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024;
-
-  explicit TestSpdyVisitor(SpdyFramer::CompressionOption option)
-      : framer_(option),
-        error_count_(0),
-        headers_frame_count_(0),
-        push_promise_frame_count_(0),
-        goaway_count_(0),
-        setting_count_(0),
-        settings_ack_sent_(0),
-        settings_ack_received_(0),
-        continuation_count_(0),
-        altsvc_count_(0),
-        priority_count_(0),
-        on_unknown_frame_result_(false),
-        last_window_update_stream_(0),
-        last_window_update_delta_(0),
-        last_push_promise_stream_(0),
-        last_push_promise_promised_stream_(0),
-        data_bytes_(0),
-        fin_frame_count_(0),
-        fin_flag_count_(0),
-        end_of_stream_count_(0),
-        control_frame_header_data_count_(0),
-        zero_length_control_frame_header_data_count_(0),
-        data_frame_count_(0),
-        last_payload_len_(0),
-        last_frame_len_(0),
-        header_buffer_(new char[kDefaultHeaderBufferSize]),
-        header_buffer_length_(0),
-        header_buffer_size_(kDefaultHeaderBufferSize),
-        header_stream_id_(static_cast<SpdyStreamId>(-1)),
-        header_control_type_(SpdyFrameType::DATA),
-        header_buffer_valid_(false) {}
-
-  void OnError(Http2DecoderAdapter::SpdyFramerError error,
-               std::string /*detailed_error*/) override {
-    QUICHE_VLOG(1) << "SpdyFramer Error: "
-                   << Http2DecoderAdapter::SpdyFramerErrorToString(error);
-    ++error_count_;
-  }
-
-  void OnDataFrameHeader(SpdyStreamId stream_id,
-                         size_t length,
-                         bool fin) override {
-    QUICHE_VLOG(1) << "OnDataFrameHeader(" << stream_id << ", " << length
-                   << ", " << fin << ")";
-    ++data_frame_count_;
-    header_stream_id_ = stream_id;
-  }
-
-  void OnStreamFrameData(SpdyStreamId stream_id,
-                         const char* data,
-                         size_t len) override {
-    QUICHE_VLOG(1) << "OnStreamFrameData(" << stream_id << ", data, " << len
-                   << ", "
-                   << ")   data:\n"
-                   << quiche::QuicheTextUtils::HexDump(
-                          absl::string_view(data, len));
-    EXPECT_EQ(header_stream_id_, stream_id);
-
-    data_bytes_ += len;
-  }
-
-  void OnStreamEnd(SpdyStreamId stream_id) override {
-    QUICHE_VLOG(1) << "OnStreamEnd(" << stream_id << ")";
-    EXPECT_EQ(header_stream_id_, stream_id);
-    ++end_of_stream_count_;
-  }
-
-  void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override {
-    QUICHE_VLOG(1) << "OnStreamPadding(" << stream_id << ", " << value << ")\n";
-    EXPECT_EQ(header_stream_id_, stream_id);
-    // Count the padding length field byte against total data bytes.
-    data_bytes_ += 1;
-  }
-
-  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
-    QUICHE_VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n";
-    EXPECT_EQ(header_stream_id_, stream_id);
-    data_bytes_ += len;
-  }
-
-  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      SpdyStreamId /*stream_id*/) override {
-    if (headers_handler_ == nullptr) {
-      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-    }
-    return headers_handler_.get();
-  }
-
-  void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override {
-    QUICHE_CHECK(headers_handler_ != nullptr);
-    headers_ = headers_handler_->decoded_block().Clone();
-    header_bytes_received_ = headers_handler_->uncompressed_header_bytes();
-    headers_handler_.reset();
-  }
-
-  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {
-    QUICHE_VLOG(1) << "OnRstStream(" << stream_id << ", " << error_code << ")";
-    ++fin_frame_count_;
-  }
-
-  void OnSetting(SpdySettingsId id, uint32_t value) override {
-    QUICHE_VLOG(1) << "OnSetting(" << id << ", " << std::hex << value << ")";
-    ++setting_count_;
-  }
-
-  void OnSettingsAck() override {
-    QUICHE_VLOG(1) << "OnSettingsAck";
-    ++settings_ack_received_;
-  }
-
-  void OnSettingsEnd() override {
-    QUICHE_VLOG(1) << "OnSettingsEnd";
-    ++settings_ack_sent_;
-  }
-
-  void OnPing(SpdyPingId unique_id, bool is_ack) override {
-    QUICHE_LOG(DFATAL) << "OnPing(" << unique_id << ", " << (is_ack ? 1 : 0)
-                       << ")";
-  }
-
-  void OnGoAway(SpdyStreamId last_accepted_stream_id,
-                SpdyErrorCode error_code) override {
-    QUICHE_VLOG(1) << "OnGoAway(" << last_accepted_stream_id << ", "
-                   << error_code << ")";
-    ++goaway_count_;
-  }
-
-  void OnHeaders(SpdyStreamId stream_id,
-                 bool has_priority,
-                 int weight,
-                 SpdyStreamId parent_stream_id,
-                 bool exclusive,
-                 bool fin,
-                 bool end) override {
-    QUICHE_VLOG(1) << "OnHeaders(" << stream_id << ", " << has_priority << ", "
-                   << weight << ", " << parent_stream_id << ", " << exclusive
-                   << ", " << fin << ", " << end << ")";
-    ++headers_frame_count_;
-    InitHeaderStreaming(SpdyFrameType::HEADERS, stream_id);
-    if (fin) {
-      ++fin_flag_count_;
-    }
-    header_has_priority_ = has_priority;
-    header_parent_stream_id_ = parent_stream_id;
-    header_exclusive_ = exclusive;
-  }
-
-  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {
-    QUICHE_VLOG(1) << "OnWindowUpdate(" << stream_id << ", "
-                   << delta_window_size << ")";
-    last_window_update_stream_ = stream_id;
-    last_window_update_delta_ = delta_window_size;
-  }
-
-  void OnPushPromise(SpdyStreamId stream_id,
-                     SpdyStreamId promised_stream_id,
-                     bool end) override {
-    QUICHE_VLOG(1) << "OnPushPromise(" << stream_id << ", "
-                   << promised_stream_id << ", " << end << ")";
-    ++push_promise_frame_count_;
-    InitHeaderStreaming(SpdyFrameType::PUSH_PROMISE, stream_id);
-    last_push_promise_stream_ = stream_id;
-    last_push_promise_promised_stream_ = promised_stream_id;
-  }
-
-  void OnContinuation(SpdyStreamId stream_id, bool end) override {
-    QUICHE_VLOG(1) << "OnContinuation(" << stream_id << ", " << end << ")";
-    ++continuation_count_;
-  }
-
-  void OnAltSvc(SpdyStreamId stream_id,
-                absl::string_view origin,
-                const SpdyAltSvcWireFormat::AlternativeServiceVector&
-                    altsvc_vector) override {
-    QUICHE_VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin
-                   << "\", altsvc_vector)";
-    test_altsvc_ir_ = std::make_unique<SpdyAltSvcIR>(stream_id);
-    if (origin.length() > 0) {
-      test_altsvc_ir_->set_origin(std::string(origin));
-    }
-    for (const auto& altsvc : altsvc_vector) {
-      test_altsvc_ir_->add_altsvc(altsvc);
-    }
-    ++altsvc_count_;
-  }
-
-  void OnPriority(SpdyStreamId stream_id,
-                  SpdyStreamId parent_stream_id,
-                  int weight,
-                  bool exclusive) override {
-    QUICHE_VLOG(1) << "OnPriority(" << stream_id << ", " << parent_stream_id
-                   << ", " << weight << ", " << (exclusive ? 1 : 0) << ")";
-    ++priority_count_;
-  }
-
-  void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
-                        absl::string_view priority_field_value) override {
-    QUICHE_VLOG(1) << "OnPriorityUpdate(" << prioritized_stream_id << ", "
-                   << priority_field_value << ")";
-  }
-
-  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override {
-    QUICHE_VLOG(1) << "OnUnknownFrame(" << stream_id << ", " << frame_type
-                   << ")";
-    return on_unknown_frame_result_;
-  }
-
-  void OnSendCompressedFrame(SpdyStreamId stream_id,
-                             SpdyFrameType type,
-                             size_t payload_len,
-                             size_t frame_len) override {
-    QUICHE_VLOG(1) << "OnSendCompressedFrame(" << stream_id << ", " << type
-                   << ", " << payload_len << ", " << frame_len << ")";
-    last_payload_len_ = payload_len;
-    last_frame_len_ = frame_len;
-  }
-
-  void OnReceiveCompressedFrame(SpdyStreamId stream_id,
-                                SpdyFrameType type,
-                                size_t frame_len) override {
-    QUICHE_VLOG(1) << "OnReceiveCompressedFrame(" << stream_id << ", " << type
-                   << ", " << frame_len << ")";
-    last_frame_len_ = frame_len;
-  }
-
-  // Convenience function which runs a framer simulation with particular input.
-  void SimulateInFramer(const unsigned char* input, size_t size) {
-    deframer_.set_visitor(this);
-    size_t input_remaining = size;
-    const char* input_ptr = reinterpret_cast<const char*>(input);
-    while (input_remaining > 0 && deframer_.spdy_framer_error() ==
-                                      Http2DecoderAdapter::SPDY_NO_ERROR) {
-      // To make the tests more interesting, we feed random (and small) chunks
-      // into the framer.  This simulates getting strange-sized reads from
-      // the socket.
-      const size_t kMaxReadSize = 32;
-      size_t bytes_read =
-          (rand() % std::min(input_remaining, kMaxReadSize)) + 1;  // NOLINT
-      size_t bytes_processed = deframer_.ProcessInput(input_ptr, bytes_read);
-      input_remaining -= bytes_processed;
-      input_ptr += bytes_processed;
-    }
-  }
-
-  void InitHeaderStreaming(SpdyFrameType header_control_type,
-                           SpdyStreamId stream_id) {
-    if (!IsDefinedFrameType(SerializeFrameType(header_control_type))) {
-      QUICHE_DLOG(FATAL) << "Attempted to init header streaming with "
-                         << "invalid control frame type: "
-                         << header_control_type;
-    }
-    memset(header_buffer_.get(), 0, header_buffer_size_);
-    header_buffer_length_ = 0;
-    header_stream_id_ = stream_id;
-    header_control_type_ = header_control_type;
-    header_buffer_valid_ = true;
-  }
-
-  void set_extension_visitor(ExtensionVisitorInterface* extension) {
-    deframer_.set_extension_visitor(extension);
-  }
-
-  // Override the default buffer size (16K). Call before using the framer!
-  void set_header_buffer_size(size_t header_buffer_size) {
-    header_buffer_size_ = header_buffer_size;
-    header_buffer_.reset(new char[header_buffer_size]);
-  }
-
-  SpdyFramer framer_;
-  Http2DecoderAdapter deframer_;
-
-  // Counters from the visitor callbacks.
-  int error_count_;
-  int headers_frame_count_;
-  int push_promise_frame_count_;
-  int goaway_count_;
-  int setting_count_;
-  int settings_ack_sent_;
-  int settings_ack_received_;
-  int continuation_count_;
-  int altsvc_count_;
-  int priority_count_;
-  std::unique_ptr<SpdyAltSvcIR> test_altsvc_ir_;
-  bool on_unknown_frame_result_;
-  SpdyStreamId last_window_update_stream_;
-  int last_window_update_delta_;
-  SpdyStreamId last_push_promise_stream_;
-  SpdyStreamId last_push_promise_promised_stream_;
-  int data_bytes_;
-  int fin_frame_count_;      // The count of RST_STREAM type frames received.
-  int fin_flag_count_;       // The count of frames with the FIN flag set.
-  int end_of_stream_count_;  // The count of zero-length data frames.
-  int control_frame_header_data_count_;  // The count of chunks received.
-  // The count of zero-length control frame header data chunks received.
-  int zero_length_control_frame_header_data_count_;
-  int data_frame_count_;
-  size_t last_payload_len_;
-  size_t last_frame_len_;
-
-  // Header block streaming state:
-  std::unique_ptr<char[]> header_buffer_;
-  size_t header_buffer_length_;
-  size_t header_buffer_size_;
-  size_t header_bytes_received_;
-  SpdyStreamId header_stream_id_;
-  SpdyFrameType header_control_type_;
-  bool header_buffer_valid_;
-  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
-  Http2HeaderBlock headers_;
-  bool header_has_priority_;
-  SpdyStreamId header_parent_stream_id_;
-  bool header_exclusive_;
-};
-
-class TestExtension : public ExtensionVisitorInterface {
- public:
-  void OnSetting(SpdySettingsId id, uint32_t value) override {
-    settings_received_.push_back({id, value});
-  }
-
-  // Called when non-standard frames are received.
-  bool OnFrameHeader(SpdyStreamId stream_id,
-                     size_t length,
-                     uint8_t type,
-                     uint8_t flags) override {
-    stream_id_ = stream_id;
-    length_ = length;
-    type_ = type;
-    flags_ = flags;
-    return true;
-  }
-
-  // The payload for a single frame may be delivered as multiple calls to
-  // OnFramePayload.
-  void OnFramePayload(const char* data, size_t len) override {
-    payload_.append(data, len);
-  }
-
-  std::vector<std::pair<SpdySettingsId, uint32_t>> settings_received_;
-  SpdyStreamId stream_id_ = 0;
-  size_t length_ = 0;
-  uint8_t type_ = 0;
-  uint8_t flags_ = 0;
-  std::string payload_;
-};
-
-// Exposes SpdyUnknownIR::set_length() for testing purposes.
-class TestSpdyUnknownIR : public SpdyUnknownIR {
- public:
-  using SpdyUnknownIR::set_length;
-  using SpdyUnknownIR::SpdyUnknownIR;
-};
-
-enum Output { USE, NOT_USE };
-
-class SpdyFramerTest : public QuicheTestWithParam<Output> {
- public:
-  SpdyFramerTest()
-      : output_(output_buffer, kSize),
-        framer_(SpdyFramer::ENABLE_COMPRESSION),
-        deframer_(absl::make_unique<Http2DecoderAdapter>()) {}
-
- protected:
-  void SetUp() override {
-    switch (GetParam()) {
-      case USE:
-        use_output_ = true;
-        break;
-      case NOT_USE:
-        // TODO(yasong): remove this case after
-        // gfe2_reloadable_flag_write_queue_zero_copy_buffer deprecates.
-        use_output_ = false;
-        break;
-    }
-  }
-
-  void CompareFrame(const std::string& description,
-                    const SpdySerializedFrame& actual_frame,
-                    const unsigned char* expected,
-                    const int expected_len) {
-    const unsigned char* actual =
-        reinterpret_cast<const unsigned char*>(actual_frame.data());
-    CompareCharArraysWithHexError(description, actual, actual_frame.size(),
-                                  expected, expected_len);
-  }
-
-  bool use_output_ = false;
-  ArrayOutputBuffer output_;
-  SpdyFramer framer_;
-  std::unique_ptr<Http2DecoderAdapter> deframer_;
-};
-
-INSTANTIATE_TEST_SUITE_P(SpdyFramerTests,
-                         SpdyFramerTest,
-                         ::testing::Values(USE, NOT_USE));
-
-// Test that we can encode and decode a SpdyHeaderBlock in serialized form.
-TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-
-  // Encode the header block into a Headers frame.
-  SpdyHeadersIR headers(/* stream_id = */ 1);
-  headers.SetHeader("alpha", "beta");
-  headers.SetHeader("gamma", "charlie");
-  headers.SetHeader("cookie", "key1=value1; key2=value2");
-  SpdySerializedFrame frame(
-      SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
-                           frame.size());
-
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_EQ(headers.header_block(), visitor.headers_);
-}
-
-// Test that if there's not a full frame, we fail to parse it.
-TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-
-  // Encode the header block into a Headers frame.
-  SpdyHeadersIR headers(/* stream_id = */ 1);
-  headers.SetHeader("alpha", "beta");
-  headers.SetHeader("gamma", "charlie");
-  SpdySerializedFrame frame(
-      SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
-                           frame.size() - 2);
-
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_THAT(visitor.headers_, testing::IsEmpty());
-}
-
-// Test that we can encode and decode stream dependency values in a header
-// frame.
-TEST_P(SpdyFramerTest, HeaderStreamDependencyValues) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-
-  const SpdyStreamId parent_stream_id_test_array[] = {0, 3};
-  for (SpdyStreamId parent_stream_id : parent_stream_id_test_array) {
-    const bool exclusive_test_array[] = {true, false};
-    for (bool exclusive : exclusive_test_array) {
-      SpdyHeadersIR headers(1);
-      headers.set_has_priority(true);
-      headers.set_parent_stream_id(parent_stream_id);
-      headers.set_exclusive(exclusive);
-      SpdySerializedFrame frame(
-          SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
-
-      TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-      visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
-                               frame.size());
-
-      EXPECT_TRUE(visitor.header_has_priority_);
-      EXPECT_EQ(parent_stream_id, visitor.header_parent_stream_id_);
-      EXPECT_EQ(exclusive, visitor.header_exclusive_);
-    }
-  }
-}
-
-// Test that if we receive a frame with a payload length field at the default
-// max size, we do not set an error in ProcessInput.
-TEST_P(SpdyFramerTest, AcceptMaxFrameSizeSetting) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  // DATA frame with maximum allowed payload length.
-  unsigned char kH2FrameData[] = {
-      0x00, 0x40, 0x00,        // Length: 2^14
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: None
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  // Junk payload
-  };
-
-  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
-                            sizeof(kH2FrameData), false);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 16384, 0x0, 0x0));
-  EXPECT_CALL(visitor, OnDataFrameHeader(1, 1 << 14, false));
-  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4));
-  deframer_->ProcessInput(frame.data(), frame.size());
-  EXPECT_FALSE(deframer_->HasError());
-}
-
-// Test that if we receive a frame with a payload length larger than the default
-// max size, we set an error of SPDY_INVALID_CONTROL_FRAME_SIZE.
-TEST_P(SpdyFramerTest, ExceedMaxFrameSizeSetting) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  // DATA frame with too large payload length.
-  unsigned char kH2FrameData[] = {
-      0x00, 0x40, 0x01,        // Length: 2^14 + 1
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: None
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  // Junk payload
-  };
-
-  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
-                            sizeof(kH2FrameData), false);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 16385, 0x0, 0x0));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD, _));
-  deframer_->ProcessInput(frame.data(), frame.size());
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we set a larger max frame size and then receive a frame with a
-// payload length at that larger size, we do not set an error in ProcessInput.
-TEST_P(SpdyFramerTest, AcceptLargerMaxFrameSizeSetting) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  const size_t big_frame_size = (1 << 14) + 1;
-  deframer_->SetMaxFrameSize(big_frame_size);
-
-  // DATA frame with larger-than-default but acceptable payload length.
-  unsigned char kH2FrameData[] = {
-      0x00, 0x40, 0x01,        // Length: 2^14 + 1
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: None
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  // Junk payload
-  };
-
-  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
-                            sizeof(kH2FrameData), false);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, big_frame_size, 0x0, 0x0));
-  EXPECT_CALL(visitor, OnDataFrameHeader(1, big_frame_size, false));
-  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4));
-  deframer_->ProcessInput(frame.data(), frame.size());
-  EXPECT_FALSE(deframer_->HasError());
-}
-
-// Test that if we receive a DATA frame with padding length larger than the
-// payload length, we set an error of SPDY_INVALID_PADDING
-TEST_P(SpdyFramerTest, OversizedDataPaddingError) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  // DATA frame with invalid padding length.
-  // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses
-  // MSVC, where |char| is signed by default, which would not compile because of
-  // the element exceeding 127.
-  unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x00,                    //   Type: DATA
-      0x09,                    //  Flags: END_STREAM|PADDED
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xff,                    // PadLen: 255 trailing bytes (Too Long)
-      0x00, 0x00, 0x00, 0x00,  // Padding
-  };
-
-  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
-                            sizeof(kH2FrameData), false);
-
-  {
-    testing::InSequence seq;
-    EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, 0x9));
-    EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, 1));
-    EXPECT_CALL(visitor, OnStreamPadding(1, 1));
-    EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_PADDING, _));
-  }
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a DATA frame with padding length not larger than the
-// payload length, we do not set an error of SPDY_INVALID_PADDING
-TEST_P(SpdyFramerTest, CorrectlySizedDataPaddingNoError) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  // DATA frame with valid Padding length
-  char kH2FrameData[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x00,                    //   Type: DATA
-      0x08,                    //  Flags: PADDED
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x04,                    // PadLen: 4 trailing bytes
-      0x00, 0x00, 0x00, 0x00,  // Padding
-  };
-
-  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
-
-  {
-    testing::InSequence seq;
-    EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, 0x8));
-    EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, false));
-    EXPECT_CALL(visitor, OnStreamPadLength(1, 4));
-    EXPECT_CALL(visitor, OnError(_, _)).Times(0);
-    // Note that OnStreamFrameData(1, _, 1)) is never called
-    // since there is no data, only padding
-    EXPECT_CALL(visitor, OnStreamPadding(1, 4));
-  }
-
-  EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_FALSE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a HEADERS frame with padding length larger than the
-// payload length, we set an error of SPDY_INVALID_PADDING
-TEST_P(SpdyFramerTest, OversizedHeadersPaddingError) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  // HEADERS frame with invalid padding length.
-  // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses
-  // MSVC, where |char| is signed by default, which would not compile because of
-  // the element exceeding 127.
-  unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x01,                    //   Type: HEADERS
-      0x08,                    //  Flags: PADDED
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xff,                    // PadLen: 255 trailing bytes (Too Long)
-      0x00, 0x00, 0x00, 0x00,  // Padding
-  };
-
-  SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData),
-                            sizeof(kH2FrameData), false);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x1, 0x8));
-  EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false));
-  EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1);
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_PADDING, _));
-  EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a HEADERS frame with padding length not larger
-// than the payload length, we do not set an error of SPDY_INVALID_PADDING
-TEST_P(SpdyFramerTest, CorrectlySizedHeadersPaddingNoError) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  // HEADERS frame with invalid Padding length
-  char kH2FrameData[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x01,                    //   Type: HEADERS
-      0x08,                    //  Flags: PADDED
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x04,                    // PadLen: 4 trailing bytes
-      0x00, 0x00, 0x00, 0x00,  // Padding
-  };
-
-  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x1, 0x8));
-  EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false));
-  EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1);
-
-  EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_FALSE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a DATA with stream ID zero, we signal an error
-// (but don't crash).
-TEST_P(SpdyFramerTest, DataWithStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  const char bytes[] = "hello";
-  SpdyDataIR data_ir(/* stream_id = */ 0, bytes);
-  SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x0, _));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a HEADERS with stream ID zero, we signal an error
-// (but don't crash).
-TEST_P(SpdyFramerTest, HeadersWithStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyHeadersIR headers(/* stream_id = */ 0);
-  headers.SetHeader("alpha", "beta");
-  SpdySerializedFrame frame(
-      SpdyFramerPeer::SerializeHeaders(&framer_, headers, &output_));
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x1, _));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a PRIORITY with stream ID zero, we signal an error
-// (but don't crash).
-TEST_P(SpdyFramerTest, PriorityWithStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyPriorityIR priority_ir(/* stream_id = */ 0,
-                             /* parent_stream_id = */ 1,
-                             /* weight = */ 16,
-                             /* exclusive = */ true);
-  SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x2, _));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a RST_STREAM with stream ID zero, we signal an error
-// (but don't crash).
-TEST_P(SpdyFramerTest, RstStreamWithStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyRstStreamIR rst_stream_ir(/* stream_id = */ 0, ERROR_CODE_PROTOCOL_ERROR);
-  SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream_ir));
-  if (use_output_) {
-    EXPECT_TRUE(framer_.SerializeRstStream(rst_stream_ir, &output_));
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x3, _));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a SETTINGS with stream ID other than zero,
-// we signal an error (but don't crash).
-TEST_P(SpdyFramerTest, SettingsWithStreamIdNotZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  // Settings frame with invalid StreamID of 0x01
-  char kH2FrameData[] = {
-      0x00, 0x00, 0x06,        // Length: 6
-      0x04,                    //   Type: SETTINGS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
-      0x0a, 0x0b, 0x0c, 0x0d,  //  Value: 168496141
-  };
-
-  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(1, 6, 0x4, 0x0));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a GOAWAY with stream ID other than zero,
-// we signal an error (but don't crash).
-TEST_P(SpdyFramerTest, GoawayWithStreamIdNotZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  // GOAWAY frame with invalid StreamID of 0x01
-  char kH2FrameData[] = {
-      0x00, 0x00, 0x0a,        // Length: 10
-      0x07,                    //   Type: GOAWAY
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  //   Last: 0
-      0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
-      0x47, 0x41,              // Description
-  };
-
-  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(1, 10, 0x7, 0x0));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a CONTINUATION with stream ID zero, we signal
-// SPDY_INVALID_STREAM_ID.
-TEST_P(SpdyFramerTest, ContinuationWithStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyContinuationIR continuation(/* stream_id = */ 0);
-  std::string some_nonsense_encoding = "some nonsense encoding";
-  continuation.take_encoding(std::move(some_nonsense_encoding));
-  continuation.set_end_headers(true);
-  SpdySerializedFrame frame(framer_.SerializeContinuation(continuation));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeContinuation(continuation, &output_));
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x9, _));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a PUSH_PROMISE with stream ID zero, we signal
-// SPDY_INVALID_STREAM_ID.
-TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyPushPromiseIR push_promise(/* stream_id = */ 0,
-                                 /* promised_stream_id = */ 4);
-  push_promise.SetHeader("alpha", "beta");
-  SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-      &framer_, push_promise, use_output_ ? &output_ : nullptr));
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x5, _));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test that if we receive a PUSH_PROMISE with promised stream ID zero, we
-// signal SPDY_INVALID_CONTROL_FRAME.
-TEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyPushPromiseIR push_promise(/* stream_id = */ 3,
-                                 /* promised_stream_id = */ 0);
-  push_promise.SetHeader("alpha", "beta");
-  SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-      &framer_, push_promise, use_output_ ? &output_ : nullptr));
-
-  EXPECT_CALL(visitor, OnCommonHeader(3, _, 0x5, _));
-  EXPECT_CALL(visitor,
-              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME, _));
-  deframer_->ProcessInput(frame.data(), frame.size());
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, MultiValueHeader) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-  std::string value("value1\0value2", 13);
-  // TODO(jgraettinger): If this pattern appears again, move to test class.
-  Http2HeaderBlock header_set;
-  header_set["name"] = value;
-  HpackEncoder encoder;
-  encoder.DisableCompression();
-  std::string buffer = encoder.EncodeHeaderBlock(header_set);
-  // Frame builder with plentiful buffer size.
-  SpdyFrameBuilder frame(1024);
-  frame.BeginNewFrame(SpdyFrameType::HEADERS,
-                      HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, 3,
-                      buffer.size() + 5 /* priority */);
-  frame.WriteUInt32(0);   // Priority exclusivity and dependent stream.
-  frame.WriteUInt8(255);  // Priority weight.
-  frame.WriteBytes(&buffer[0], buffer.size());
-
-  SpdySerializedFrame control_frame(frame.take());
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-
-  EXPECT_THAT(visitor.headers_, testing::ElementsAre(testing::Pair(
-                                    "name", absl::string_view(value))));
-}
-
-TEST_P(SpdyFramerTest, CompressEmptyHeaders) {
-  // See https://crbug.com/172383/
-  SpdyHeadersIR headers(1);
-  headers.SetHeader("server", "SpdyServer 1.0");
-  headers.SetHeader("date", "Mon 12 Jan 2009 12:12:12 PST");
-  headers.SetHeader("status", "200");
-  headers.SetHeader("version", "HTTP/1.1");
-  headers.SetHeader("content-type", "text/html");
-  headers.SetHeader("content-length", "12");
-  headers.SetHeader("x-empty-header", "");
-
-  SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-  SpdySerializedFrame frame1(
-      SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
-}
-
-TEST_P(SpdyFramerTest, Basic) {
-  // Send HEADERS frames with PRIORITY and END_HEADERS set.
-  // frame-format off
-  const unsigned char kH2Input[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x01,                    //   Type: HEADERS
-      0x24,                    //  Flags: END_HEADERS|PRIORITY
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  // Parent: 0
-      0x82,                    // Weight: 131
-
-      0x00, 0x00, 0x01,        // Length: 1
-      0x01,                    //   Type: HEADERS
-      0x04,                    //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x8c,                    // :status: 200
-
-      0x00, 0x00, 0x0c,        // Length: 12
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-      0xde, 0xad, 0xbe, 0xef,  //
-      0xde, 0xad, 0xbe, 0xef,  //
-
-      0x00, 0x00, 0x05,        // Length: 5
-      0x01,                    //   Type: HEADERS
-      0x24,                    //  Flags: END_HEADERS|PRIORITY
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x00, 0x00,  // Parent: 0
-      0x82,                    // Weight: 131
-
-      0x00, 0x00, 0x08,        // Length: 8
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-      0xde, 0xad, 0xbe, 0xef,  //
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
-
-      0x00, 0x00, 0x00,        // Length: 0
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
-  };
-  // frame-format on
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
-
-  EXPECT_EQ(24, visitor.data_bytes_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(2, visitor.fin_frame_count_);
-
-  EXPECT_EQ(3, visitor.headers_frame_count_);
-
-  EXPECT_EQ(0, visitor.fin_flag_count_);
-  EXPECT_EQ(0, visitor.end_of_stream_count_);
-  EXPECT_EQ(4, visitor.data_frame_count_);
-}
-
-// Verifies that the decoder stops delivering events after a user error.
-TEST_P(SpdyFramerTest, BasicWithError) {
-  // Send HEADERS frames with PRIORITY and END_HEADERS set.
-  // frame-format off
-  const unsigned char kH2Input[] = {
-      0x00, 0x00, 0x01,        // Length: 1
-      0x01,                    //   Type: HEADERS
-      0x04,                    //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x8c,                    // :status: 200
-
-      0x00, 0x00, 0x0c,        // Length: 12
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-      0xde, 0xad, 0xbe, 0xef,  //
-      0xde, 0xad, 0xbe, 0xef,  //
-
-      0x00, 0x00, 0x06,        // Length: 6
-      0x01,                    //   Type: HEADERS
-      0x24,                    //  Flags: END_HEADERS|PRIORITY
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x00, 0x00,  // Parent: 0
-      0x82,                    // Weight: 131
-      0x8c,                    // :status: 200
-
-      0x00, 0x00, 0x08,        // Length: 8
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-      0xde, 0xad, 0xbe, 0xef,  //
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
-
-      0x00, 0x00, 0x00,        // Length: 0
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
-  };
-  // frame-format on
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  testing::InSequence s;
-  EXPECT_CALL(visitor, OnCommonHeader(1, 1, 0x1, 0x4));
-  EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, true));
-  EXPECT_CALL(visitor, OnHeaderFrameStart(1));
-  EXPECT_CALL(visitor, OnHeaderFrameEnd(1));
-  EXPECT_CALL(visitor, OnCommonHeader(1, 12, 0x0, 0x0));
-  EXPECT_CALL(visitor, OnDataFrameHeader(1, 12, false));
-  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 12));
-  EXPECT_CALL(visitor, OnCommonHeader(3, 6, 0x1, 0x24));
-  EXPECT_CALL(visitor, OnHeaders(3, true, 131, 0, false, false, true));
-  EXPECT_CALL(visitor, OnHeaderFrameStart(3));
-  EXPECT_CALL(visitor, OnHeaderFrameEnd(3));
-  EXPECT_CALL(visitor, OnCommonHeader(3, 8, 0x0, 0x0));
-  EXPECT_CALL(visitor, OnDataFrameHeader(3, 8, false))
-      .WillOnce(testing::InvokeWithoutArgs(
-          [this]() { deframer_->StopProcessing(); }));
-  // Remaining frames are not processed due to the error.
-  EXPECT_CALL(
-      visitor,
-      OnError(http2::Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
-              "Ignoring further events on this connection."));
-
-  size_t processed = deframer_->ProcessInput(
-      reinterpret_cast<const char*>(kH2Input), sizeof(kH2Input));
-  EXPECT_LT(processed, sizeof(kH2Input));
-}
-
-// Test that the FIN flag on a data frame signifies EOF.
-TEST_P(SpdyFramerTest, FinOnDataFrame) {
-  // Send HEADERS frames with END_HEADERS set.
-  // frame-format off
-  const unsigned char kH2Input[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x01,                    //   Type: HEADERS
-      0x24,                    //  Flags: END_HEADERS|PRIORITY
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  // Parent: 0
-      0x82,                    // Weight: 131
-
-      0x00, 0x00, 0x01,        // Length: 1
-      0x01,                    //   Type: HEADERS
-      0x04,                    //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x8c,                    // :status: 200
-
-      0x00, 0x00, 0x0c,        // Length: 12
-      0x00,                    //   Type: DATA
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-      0xde, 0xad, 0xbe, 0xef,  //
-      0xde, 0xad, 0xbe, 0xef,  //
-
-      0x00, 0x00, 0x04,        // Length: 4
-      0x00,                    //   Type: DATA
-      0x01,                    //  Flags: END_STREAM
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0xde, 0xad, 0xbe, 0xef,  // Payload
-  };
-  // frame-format on
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(2, visitor.headers_frame_count_);
-  EXPECT_EQ(16, visitor.data_bytes_);
-  EXPECT_EQ(0, visitor.fin_frame_count_);
-  EXPECT_EQ(0, visitor.fin_flag_count_);
-  EXPECT_EQ(1, visitor.end_of_stream_count_);
-  EXPECT_EQ(2, visitor.data_frame_count_);
-}
-
-TEST_P(SpdyFramerTest, FinOnHeadersFrame) {
-  // Send HEADERS frames with END_HEADERS set.
-  // frame-format off
-  const unsigned char kH2Input[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x01,                    //   Type: HEADERS
-      0x24,                    //  Flags: END_HEADERS|PRIORITY
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  // Parent: 0
-      0x82,                    // Weight: 131
-
-      0x00, 0x00, 0x01,        // Length: 1
-      0x01,                    //   Type: HEADERS
-      0x05,                    //  Flags: END_STREAM|END_HEADERS
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x8c,                    // :status: 200
-  };
-  // frame-format on
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(2, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.data_bytes_);
-  EXPECT_EQ(0, visitor.fin_frame_count_);
-  EXPECT_EQ(1, visitor.fin_flag_count_);
-  EXPECT_EQ(1, visitor.end_of_stream_count_);
-  EXPECT_EQ(0, visitor.data_frame_count_);
-}
-
-// Verify we can decompress the stream even if handed over to the
-// framer 1 byte at a time.
-TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
-  const char kHeader1[] = "header1";
-  const char kHeader2[] = "header2";
-  const char kValue1[] = "value1";
-  const char kValue2[] = "value2";
-
-  SpdyHeadersIR headers(/* stream_id = */ 1);
-  headers.SetHeader(kHeader1, kValue1);
-  headers.SetHeader(kHeader2, kValue2);
-  SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders(
-      &framer_, headers, use_output_ ? &output_ : nullptr));
-
-  const char bytes[] = "this is a test test test test test!";
-  SpdyDataIR data_ir(/* stream_id = */ 1,
-                     absl::string_view(bytes, ABSL_ARRAYSIZE(bytes)));
-  data_ir.set_fin(true);
-  SpdySerializedFrame send_frame(framer_.SerializeData(data_ir));
-
-  // Run the inputs through the framer.
-  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-  const unsigned char* data;
-  data = reinterpret_cast<const unsigned char*>(headers_frame.data());
-  for (size_t idx = 0; idx < headers_frame.size(); ++idx) {
-    visitor.SimulateInFramer(data + idx, 1);
-    ASSERT_EQ(0, visitor.error_count_);
-  }
-  data = reinterpret_cast<const unsigned char*>(send_frame.data());
-  for (size_t idx = 0; idx < send_frame.size(); ++idx) {
-    visitor.SimulateInFramer(data + idx, 1);
-    ASSERT_EQ(0, visitor.error_count_);
-  }
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(ABSL_ARRAYSIZE(bytes), static_cast<unsigned>(visitor.data_bytes_));
-  EXPECT_EQ(0, visitor.fin_frame_count_);
-  EXPECT_EQ(0, visitor.fin_flag_count_);
-  EXPECT_EQ(1, visitor.end_of_stream_count_);
-  EXPECT_EQ(1, visitor.data_frame_count_);
-}
-
-TEST_P(SpdyFramerTest, WindowUpdateFrame) {
-  SpdyWindowUpdateIR window_update(/* stream_id = */ 1,
-                                   /* delta = */ 0x12345678);
-  SpdySerializedFrame frame(framer_.SerializeWindowUpdate(window_update));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeWindowUpdate(window_update, &output_));
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-
-  const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x04,        // Length: 4
-      0x08,                    //   Type: WINDOW_UPDATE
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x12, 0x34, 0x56, 0x78,  // Increment: 305419896
-  };
-
-  CompareFrame(kDescription, frame, kH2FrameData, ABSL_ARRAYSIZE(kH2FrameData));
-}
-
-TEST_P(SpdyFramerTest, CreateDataFrame) {
-  {
-    const char kDescription[] = "'hello' data frame, no FIN";
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x05,        // Length: 5
-        0x00,                    //   Type: DATA
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        'h',  'e',  'l',  'l',   // Payload
-        'o',                     //
-    };
-    // frame-format on
-    const char bytes[] = "hello";
-
-    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-
-    SpdyDataIR data_header_ir(/* stream_id = */ 1);
-    data_header_ir.SetDataShallow(bytes);
-    frame =
-        framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_header_ir);
-    CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
-        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
-  }
-
-  {
-    const char kDescription[] = "'hello' data frame with more padding, no FIN";
-    // clang-format off
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0xfd,        // Length: 253
-        0x00,                    //   Type: DATA
-        0x08,                    //  Flags: PADDED
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0xf7,                    // PadLen: 247 trailing bytes
-        'h', 'e', 'l', 'l',      // Payload
-        'o',                     //
-        // Padding of 247 0x00(s).
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    };
-    // frame-format on
-    // clang-format on
-    const char bytes[] = "hello";
-
-    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
-    // 247 zeros and the pad length field make the overall padding to be 248
-    // bytes.
-    data_ir.set_padding_len(248);
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-
-    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
-    CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
-        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
-  }
-
-  {
-    const char kDescription[] = "'hello' data frame with few padding, no FIN";
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x0d,        // Length: 13
-        0x00,                    //   Type: DATA
-        0x08,                    //  Flags: PADDED
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0x07,                    // PadLen: 7 trailing bytes
-        'h',  'e',  'l',  'l',   // Payload
-        'o',                     //
-        0x00, 0x00, 0x00, 0x00,  // Padding
-        0x00, 0x00, 0x00,        // Padding
-    };
-    // frame-format on
-    const char bytes[] = "hello";
-
-    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
-    // 7 zeros and the pad length field make the overall padding to be 8 bytes.
-    data_ir.set_padding_len(8);
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-
-    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
-    CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
-        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
-  }
-
-  {
-    const char kDescription[] =
-        "'hello' data frame with 1 byte padding, no FIN";
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x06,        // Length: 6
-        0x00,                    //   Type: DATA
-        0x08,                    //  Flags: PADDED
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0x00,                    // PadLen: 0 trailing bytes
-        'h',  'e',  'l',  'l',   // Payload
-        'o',                     //
-    };
-    // frame-format on
-    const char bytes[] = "hello";
-
-    SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
-    // The pad length field itself is used for the 1-byte padding and no padding
-    // payload is needed.
-    data_ir.set_padding_len(1);
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-
-    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
-    CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
-        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
-  }
-
-  {
-    const char kDescription[] = "Data frame with negative data byte, no FIN";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x01,        // Length: 1
-        0x00,                    //   Type: DATA
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0xff,                    // Payload
-    };
-    SpdyDataIR data_ir(/* stream_id = */ 1, "\xff");
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "'hello' data frame, with FIN";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x05,        // Length: 5
-        0x00,                    //   Type: DATA
-        0x01,                    //  Flags: END_STREAM
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0x68, 0x65, 0x6c, 0x6c,  // Payload
-        0x6f,                    //
-    };
-    SpdyDataIR data_ir(/* stream_id = */ 1, "hello");
-    data_ir.set_fin(true);
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "Empty data frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x00,        // Length: 0
-        0x00,                    //   Type: DATA
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-    };
-    SpdyDataIR data_ir(/* stream_id = */ 1, "");
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-
-    frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
-    CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
-        kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
-  }
-
-  {
-    const char kDescription[] = "Data frame with max stream ID";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x05,        // Length: 5
-        0x00,                    //   Type: DATA
-        0x01,                    //  Flags: END_STREAM
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
-        0x68, 0x65, 0x6c, 0x6c,  // Payload
-        0x6f,                    //
-    };
-    SpdyDataIR data_ir(/* stream_id = */ 0x7fffffff, "hello");
-    data_ir.set_fin(true);
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreateRstStream) {
-  {
-    const char kDescription[] = "RST_STREAM frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x04,        // Length: 4
-        0x03,                    //   Type: RST_STREAM
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0x00, 0x00, 0x00, 0x01,  //  Error: PROTOCOL_ERROR
-    };
-    SpdyRstStreamIR rst_stream(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
-    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
-    if (use_output_) {
-      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "RST_STREAM frame with max stream ID";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x04,        // Length: 4
-        0x03,                    //   Type: RST_STREAM
-        0x00,                    //  Flags: none
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
-        0x00, 0x00, 0x00, 0x01,  //  Error: PROTOCOL_ERROR
-    };
-    SpdyRstStreamIR rst_stream(/* stream_id = */ 0x7FFFFFFF,
-                               ERROR_CODE_PROTOCOL_ERROR);
-    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "RST_STREAM frame with max status code";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x04,        // Length: 4
-        0x03,                    //   Type: RST_STREAM
-        0x00,                    //  Flags: none
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
-        0x00, 0x00, 0x00, 0x02,  //  Error: INTERNAL_ERROR
-    };
-    SpdyRstStreamIR rst_stream(/* stream_id = */ 0x7FFFFFFF,
-                               ERROR_CODE_INTERNAL_ERROR);
-    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreateSettings) {
-  {
-    const char kDescription[] = "Network byte order SETTINGS frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x06,        // Length: 6
-        0x04,                    //   Type: SETTINGS
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-        0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
-        0x0a, 0x0b, 0x0c, 0x0d,  //  Value: 168496141
-    };
-
-    uint32_t kValue = 0x0a0b0c0d;
-    SpdySettingsIR settings_ir;
-
-    SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE;
-    settings_ir.AddSetting(kId, kValue);
-
-    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
-    if (use_output_) {
-      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "Basic SETTINGS frame";
-    // These end up seemingly out of order because of the way that our internal
-    // ordering for settings_ir works. HTTP2 has no requirement on ordering on
-    // the wire.
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x18,        // Length: 24
-        0x04,                    //   Type: SETTINGS
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-        0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
-        0x00, 0x00, 0x00, 0x05,  //  Value: 5
-        0x00, 0x02,              //  Param: ENABLE_PUSH
-        0x00, 0x00, 0x00, 0x06,  //  Value: 6
-        0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
-        0x00, 0x00, 0x00, 0x07,  //  Value: 7
-        0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
-        0x00, 0x00, 0x00, 0x08,  //  Value: 8
-    };
-
-    SpdySettingsIR settings_ir;
-    settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
-    settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
-    settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
-    settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 8);
-    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "Empty SETTINGS frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x00,        // Length: 0
-        0x04,                    //   Type: SETTINGS
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-    };
-    SpdySettingsIR settings_ir;
-    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreatePingFrame) {
-  {
-    const char kDescription[] = "PING frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x08,        // Length: 8
-        0x06,                    //   Type: PING
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-        0x12, 0x34, 0x56, 0x78,  // Opaque
-        0x9a, 0xbc, 0xde, 0xff,  //     Data
-    };
-    const unsigned char kH2FrameDataWithAck[] = {
-        0x00, 0x00, 0x08,        // Length: 8
-        0x06,                    //   Type: PING
-        0x01,                    //  Flags: ACK
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-        0x12, 0x34, 0x56, 0x78,  // Opaque
-        0x9a, 0xbc, 0xde, 0xff,  //     Data
-    };
-    const SpdyPingId kPingId = 0x123456789abcdeffULL;
-    SpdyPingIR ping_ir(kPingId);
-    // Tests SpdyPingIR when the ping is not an ack.
-    ASSERT_FALSE(ping_ir.is_ack());
-    SpdySerializedFrame frame(framer_.SerializePing(ping_ir));
-    if (use_output_) {
-      ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-
-    // Tests SpdyPingIR when the ping is an ack.
-    ping_ir.set_is_ack(true);
-    frame = framer_.SerializePing(ping_ir);
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameDataWithAck,
-                 ABSL_ARRAYSIZE(kH2FrameDataWithAck));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreateGoAway) {
-  {
-    const char kDescription[] = "GOAWAY frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x0a,        // Length: 10
-        0x07,                    //   Type: GOAWAY
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-        0x00, 0x00, 0x00, 0x00,  //   Last: 0
-        0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
-        0x47, 0x41,              // Description
-    };
-    SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 0, ERROR_CODE_NO_ERROR,
-                           "GA");
-    SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
-    if (use_output_) {
-      ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "GOAWAY frame with max stream ID, status";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x0a,        // Length: 10
-        0x07,                    //   Type: GOAWAY
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x00,  // Stream: 0
-        0x7f, 0xff, 0xff, 0xff,  //   Last: 0x7fffffff
-        0x00, 0x00, 0x00, 0x02,  //  Error: INTERNAL_ERROR
-        0x47, 0x41,              // Description
-    };
-    SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 0x7FFFFFFF,
-                           ERROR_CODE_INTERNAL_ERROR, "GA");
-    SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-
-  {
-    const char kDescription[] = "HEADERS frame, no FIN";
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x12,        // Length: 18
-        0x01,                    //   Type: HEADERS
-        0x04,                    //  Flags: END_HEADERS
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x03,              // Value Len: 3
-        0x62, 0x61, 0x72,  // bar
-    };
-    // frame-format on
-    SpdyHeadersIR headers(/* stream_id = */ 1);
-    headers.SetHeader("bar", "foo");
-    headers.SetHeader("foo", "bar");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] =
-        "HEADERS frame with a 0-length header name, FIN, max stream ID";
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x0f,        // Length: 15
-        0x01,                    //   Type: HEADERS
-        0x05,                    //  Flags: END_STREAM|END_HEADERS
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
-
-        0x00,              // Unindexed Entry
-        0x00,              // Name Len: 0
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x03,              // Value Len: 3
-        0x62, 0x61, 0x72,  // bar
-    };
-    // frame-format on
-    SpdyHeadersIR headers(/* stream_id = */ 0x7fffffff);
-    headers.set_fin(true);
-    headers.SetHeader("", "foo");
-    headers.SetHeader("foo", "bar");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] =
-        "HEADERS frame with a 0-length header val, FIN, max stream ID";
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x0f,        // Length: 15
-        0x01,                    //   Type: HEADERS
-        0x05,                    //  Flags: END_STREAM|END_HEADERS
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x00,              // Value Len: 0
-    };
-    // frame-format on
-    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
-    headers_ir.set_fin(true);
-    headers_ir.SetHeader("bar", "foo");
-    headers_ir.SetHeader("foo", "");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers_ir, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] =
-        "HEADERS frame with a 0-length header val, FIN, max stream ID, pri";
-
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x14,        // Length: 20
-        0x01,                    //   Type: HEADERS
-        0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
-        0x00, 0x00, 0x00, 0x00,  // Parent: 0
-        0xdb,                    // Weight: 220
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x00,              // Value Len: 0
-    };
-    // frame-format on
-    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
-    headers_ir.set_fin(true);
-    headers_ir.set_has_priority(true);
-    headers_ir.set_weight(220);
-    headers_ir.SetHeader("bar", "foo");
-    headers_ir.SetHeader("foo", "");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers_ir, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] =
-        "HEADERS frame with a 0-length header val, FIN, max stream ID, pri, "
-        "exclusive=true, parent_stream=0";
-
-    // frame-format off
-    const unsigned char kV4FrameData[] = {
-        0x00, 0x00, 0x14,        // Length: 20
-        0x01,                    //   Type: HEADERS
-        0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
-        0x80, 0x00, 0x00, 0x00,  // Parent: 0 (Exclusive)
-        0xdb,                    // Weight: 220
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x00,              // Value Len: 0
-    };
-    // frame-format on
-    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
-    headers_ir.set_fin(true);
-    headers_ir.set_has_priority(true);
-    headers_ir.set_weight(220);
-    headers_ir.set_exclusive(true);
-    headers_ir.set_parent_stream_id(0);
-    headers_ir.SetHeader("bar", "foo");
-    headers_ir.SetHeader("foo", "");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers_ir, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kV4FrameData,
-                 ABSL_ARRAYSIZE(kV4FrameData));
-  }
-
-  {
-    const char kDescription[] =
-        "HEADERS frame with a 0-length header val, FIN, max stream ID, pri, "
-        "exclusive=false, parent_stream=max stream ID";
-
-    // frame-format off
-    const unsigned char kV4FrameData[] = {
-        0x00, 0x00, 0x14,        // Length: 20
-        0x01,                    //   Type: HEADERS
-        0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
-        0x7f, 0xff, 0xff, 0xff,  // Parent: 2147483647
-        0xdb,                    // Weight: 220
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x00,              // Value Len: 0
-    };
-    // frame-format on
-    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
-    headers_ir.set_fin(true);
-    headers_ir.set_has_priority(true);
-    headers_ir.set_weight(220);
-    headers_ir.set_exclusive(false);
-    headers_ir.set_parent_stream_id(0x7fffffff);
-    headers_ir.SetHeader("bar", "foo");
-    headers_ir.SetHeader("foo", "");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers_ir, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kV4FrameData,
-                 ABSL_ARRAYSIZE(kV4FrameData));
-  }
-
-  {
-    const char kDescription[] =
-        "HEADERS frame with a 0-length header name, FIN, max stream ID, padded";
-
-    // frame-format off
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x15,        // Length: 21
-        0x01,                    //   Type: HEADERS
-        0x0d,                    //  Flags: END_STREAM|END_HEADERS|PADDED
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
-        0x05,                    // PadLen: 5 trailing bytes
-
-        0x00,              // Unindexed Entry
-        0x00,              // Name Len: 0
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x03,              // Value Len: 3
-        0x62, 0x61, 0x72,  // bar
-
-        0x00, 0x00, 0x00, 0x00,  // Padding
-        0x00,                    // Padding
-    };
-    // frame-format on
-    SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
-    headers_ir.set_fin(true);
-    headers_ir.SetHeader("", "foo");
-    headers_ir.SetHeader("foo", "bar");
-    headers_ir.set_padding_len(6);
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers_ir, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreateWindowUpdate) {
-  {
-    const char kDescription[] = "WINDOW_UPDATE frame";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x04,        // Length: 4
-        0x08,                    //   Type: WINDOW_UPDATE
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0x00, 0x00, 0x00, 0x01,  // Increment: 1
-    };
-    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1)));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeWindowUpdate(
-          SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1), &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x04,        // Length: 4
-        0x08,                    //   Type: WINDOW_UPDATE
-        0x00,                    //  Flags: none
-        0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
-        0x00, 0x00, 0x00, 0x01,  // Increment: 1
-    };
-    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1)));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeWindowUpdate(
-          SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1),
-          &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-
-  {
-    const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
-    const unsigned char kH2FrameData[] = {
-        0x00, 0x00, 0x04,        // Length: 4
-        0x08,                    //   Type: WINDOW_UPDATE
-        0x00,                    //  Flags: none
-        0x00, 0x00, 0x00, 0x01,  // Stream: 1
-        0x7f, 0xff, 0xff, 0xff,  // Increment: 0x7fffffff
-    };
-    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF)));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeWindowUpdate(
-          SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF),
-          &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    CompareFrame(kDescription, frame, kH2FrameData,
-                 ABSL_ARRAYSIZE(kH2FrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
-  {
-    // Test framing PUSH_PROMISE without padding.
-    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-    const char kDescription[] = "PUSH_PROMISE frame without padding";
-
-    // frame-format off
-    const unsigned char kFrameData[] = {
-        0x00, 0x00, 0x16,        // Length: 22
-        0x05,                    //   Type: PUSH_PROMISE
-        0x04,                    //  Flags: END_HEADERS
-        0x00, 0x00, 0x00, 0x29,  // Stream: 41
-        0x00, 0x00, 0x00, 0x3a,  // Promise: 58
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x03,              // Value Len: 3
-        0x62, 0x61, 0x72,  // bar
-    };
-    // frame-format on
-
-    SpdyPushPromiseIR push_promise(/* stream_id = */ 41,
-                                   /* promised_stream_id = */ 58);
-    push_promise.SetHeader("bar", "foo");
-    push_promise.SetHeader("foo", "bar");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-        &framer, push_promise, use_output_ ? &output_ : nullptr));
-    CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-  }
-
-  {
-    // Test framing PUSH_PROMISE with one byte of padding.
-    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-    const char kDescription[] = "PUSH_PROMISE frame with one byte of padding";
-
-    // frame-format off
-    const unsigned char kFrameData[] = {
-        0x00, 0x00, 0x17,        // Length: 23
-        0x05,                    //   Type: PUSH_PROMISE
-        0x0c,                    //  Flags: END_HEADERS|PADDED
-        0x00, 0x00, 0x00, 0x29,  // Stream: 41
-        0x00,                    // PadLen: 0 trailing bytes
-        0x00, 0x00, 0x00, 0x3a,  // Promise: 58
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x62, 0x61, 0x72,  // bar
-        0x03,              // Value Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-
-        0x00,              // Unindexed Entry
-        0x03,              // Name Len: 3
-        0x66, 0x6f, 0x6f,  // foo
-        0x03,              // Value Len: 3
-        0x62, 0x61, 0x72,  // bar
-    };
-    // frame-format on
-
-    SpdyPushPromiseIR push_promise(/* stream_id = */ 41,
-                                   /* promised_stream_id = */ 58);
-    push_promise.set_padding_len(1);
-    push_promise.SetHeader("bar", "foo");
-    push_promise.SetHeader("foo", "bar");
-    output_.Reset();
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-        &framer, push_promise, use_output_ ? &output_ : nullptr));
-
-    CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-  }
-
-  {
-    // Test framing PUSH_PROMISE with 177 bytes of padding.
-    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-    const char kDescription[] = "PUSH_PROMISE frame with 177 bytes of padding";
-
-    // frame-format off
-    // clang-format off
-    const unsigned char kFrameData[] = {
-        0x00, 0x00, 0xc7,        // Length: 199
-        0x05,                    //   Type: PUSH_PROMISE
-        0x0c,                    //  Flags: END_HEADERS|PADDED
-        0x00, 0x00, 0x00, 0x2a,  // Stream: 42
-        0xb0,                    // PadLen: 176 trailing bytes
-        0x00, 0x00, 0x00, 0x39,  // Promise: 57
-
-        0x00,                    // Unindexed Entry
-        0x03,                    // Name Len: 3
-        0x62, 0x61, 0x72,        // bar
-        0x03,                    // Value Len: 3
-        0x66, 0x6f, 0x6f,        // foo
-
-        0x00,                    // Unindexed Entry
-        0x03,                    // Name Len: 3
-        0x66, 0x6f, 0x6f,        // foo
-        0x03,                    // Value Len: 3
-        0x62, 0x61, 0x72,        // bar
-
-      // Padding of 176 0x00(s).
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-      0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
-    };
-    // clang-format on
-    // frame-format on
-
-    SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
-                                   /* promised_stream_id = */ 57);
-    push_promise.set_padding_len(177);
-    push_promise.SetHeader("bar", "foo");
-    push_promise.SetHeader("foo", "bar");
-    output_.Reset();
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-        &framer, push_promise, use_output_ ? &output_ : nullptr));
-
-    CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-  }
-}
-
-// Regression test for https://crbug.com/464748.
-TEST_P(SpdyFramerTest, GetNumberRequiredContinuationFrames) {
-  EXPECT_EQ(1u, GetNumberRequiredContinuationFrames(16383 + 16374));
-  EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 16374 + 1));
-  EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374));
-  EXPECT_EQ(3u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374 + 1));
-}
-
-TEST_P(SpdyFramerTest, CreateContinuationUncompressed) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-  const char kDescription[] = "CONTINUATION frame";
-
-  // frame-format off
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x12,        // Length: 18
-      0x09,                    //   Type: CONTINUATION
-      0x04,                    //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x2a,  // Stream: 42
-
-      0x00,              // Unindexed Entry
-      0x03,              // Name Len: 3
-      0x62, 0x61, 0x72,  // bar
-      0x03,              // Value Len: 3
-      0x66, 0x6f, 0x6f,  // foo
-
-      0x00,              // Unindexed Entry
-      0x03,              // Name Len: 3
-      0x66, 0x6f, 0x6f,  // foo
-      0x03,              // Value Len: 3
-      0x62, 0x61, 0x72,  // bar
-  };
-  // frame-format on
-
-  Http2HeaderBlock header_block;
-  header_block["bar"] = "foo";
-  header_block["foo"] = "bar";
-  HpackEncoder encoder;
-  encoder.DisableCompression();
-  std::string buffer = encoder.EncodeHeaderBlock(header_block);
-
-  SpdyContinuationIR continuation(/* stream_id = */ 42);
-  continuation.take_encoding(std::move(buffer));
-  continuation.set_end_headers(true);
-
-  SpdySerializedFrame frame(framer.SerializeContinuation(continuation));
-  if (use_output_) {
-    ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-// Test that if we send an unexpected CONTINUATION
-// we signal an error (but don't crash).
-TEST_P(SpdyFramerTest, SendUnexpectedContinuation) {
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  // frame-format off
-  char kH2FrameData[] = {
-      0x00, 0x00, 0x12,        // Length: 18
-      0x09,                    //   Type: CONTINUATION
-      0x04,                    //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x2a,  // Stream: 42
-
-      0x00,              // Unindexed Entry
-      0x03,              // Name Len: 3
-      0x62, 0x61, 0x72,  // bar
-      0x03,              // Value Len: 3
-      0x66, 0x6f, 0x6f,  // foo
-
-      0x00,              // Unindexed Entry
-      0x03,              // Name Len: 3
-      0x66, 0x6f, 0x6f,  // foo
-      0x03,              // Value Len: 3
-      0x62, 0x61, 0x72,  // bar
-  };
-  // frame-format on
-
-  SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false);
-
-  // We shouldn't have to read the whole frame before we signal an error.
-  EXPECT_CALL(visitor, OnCommonHeader(42, 18, 0x9, 0x4));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME, _));
-  EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
-  EXPECT_TRUE(deframer_->HasError());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
-  {
-    // Test framing in a case such that a PUSH_PROMISE frame, with one byte of
-    // padding, cannot hold all the data payload, which is overflowed to the
-    // consecutive CONTINUATION frame.
-    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-    const char kDescription[] =
-        "PUSH_PROMISE and CONTINUATION frames with one byte of padding";
-
-    // frame-format off
-    const unsigned char kPartialPushPromiseFrameData[] = {
-        0x00, 0x3f, 0xf6,        // Length: 16374
-        0x05,                    //   Type: PUSH_PROMISE
-        0x08,                    //  Flags: PADDED
-        0x00, 0x00, 0x00, 0x2a,  // Stream: 42
-        0x00,                    // PadLen: 0 trailing bytes
-        0x00, 0x00, 0x00, 0x39,  // Promise: 57
-
-        0x00,                    // Unindexed Entry
-        0x03,                    // Name Len: 3
-        0x78, 0x78, 0x78,        // xxx
-        0x7f, 0x80, 0x7f,        // Value Len: 16361
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-    };
-    const unsigned char kContinuationFrameData[] = {
-        0x00, 0x00, 0x16,        // Length: 22
-        0x09,                    //   Type: CONTINUATION
-        0x04,                    //  Flags: END_HEADERS
-        0x00, 0x00, 0x00, 0x2a,  // Stream: 42
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78, 0x78, 0x78, 0x78,  // xxxx
-        0x78,                    // x
-    };
-    // frame-format on
-
-    SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
-                                   /* promised_stream_id = */ 57);
-    push_promise.set_padding_len(1);
-    std::string big_value(kHttp2MaxControlFrameSendSize, 'x');
-    push_promise.SetHeader("xxx", big_value);
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-        &framer, push_promise, use_output_ ? &output_ : nullptr));
-
-    // The entire frame should look like below:
-    // Name                     Length in Byte
-    // ------------------------------------------- Begin of PUSH_PROMISE frame
-    // PUSH_PROMISE header      9
-    // Pad length field         1
-    // Promised stream          4
-    // Length field of key      2
-    // Content of key           3
-    // Length field of value    3
-    // Part of big_value        16361
-    // ------------------------------------------- Begin of CONTINUATION frame
-    // CONTINUATION header      9
-    // Remaining of big_value   22
-    // ------------------------------------------- End
-
-    // Length of everything listed above except big_value.
-    int len_non_data_payload = 31;
-    EXPECT_EQ(kHttp2MaxControlFrameSendSize + len_non_data_payload,
-              frame.size());
-
-    // Partially compare the PUSH_PROMISE frame against the template.
-    const unsigned char* frame_data =
-        reinterpret_cast<const unsigned char*>(frame.data());
-    CompareCharArraysWithHexError(kDescription, frame_data,
-                                  ABSL_ARRAYSIZE(kPartialPushPromiseFrameData),
-                                  kPartialPushPromiseFrameData,
-                                  ABSL_ARRAYSIZE(kPartialPushPromiseFrameData));
-
-    // Compare the CONTINUATION frame against the template.
-    frame_data += kHttp2MaxControlFrameSendSize;
-    CompareCharArraysWithHexError(
-        kDescription, frame_data, ABSL_ARRAYSIZE(kContinuationFrameData),
-        kContinuationFrameData, ABSL_ARRAYSIZE(kContinuationFrameData));
-  }
-}
-
-TEST_P(SpdyFramerTest, CreateAltSvc) {
-  const char kDescription[] = "ALTSVC frame";
-  const unsigned char kType = SerializeFrameType(SpdyFrameType::ALTSVC);
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x49, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o',
-      'r',  'i',  'g',  'i',   'n',  'p',  'i',  'd',  '1',  '=',  '"',  'h',
-      'o',  's',  't',  ':',   '4',  '4',  '3',  '"',  ';',  ' ',  'm',  'a',
-      '=',  '5',  ',',  'p',   '%',  '2',  '2',  '%',  '3',  'D',  'i',  '%',
-      '3',  'A',  'd',  '=',   '"',  'h',  '_',  '\\', '\\', 'o',  '\\', '"',
-      's',  't',  ':',  '1',   '2',  '3',  '"',  ';',  ' ',  'm',  'a',  '=',
-      '4',  '2',  ';',  ' ',   'v',  '=',  '"',  '2',  '4',  '"'};
-  SpdyAltSvcIR altsvc_ir(/* stream_id = */ 3);
-  altsvc_ir.set_origin("origin");
-  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
-  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
-      "p\"=i:d", "h_\\o\"st", 123, 42,
-      SpdyAltSvcWireFormat::VersionVector{24}));
-  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-TEST_P(SpdyFramerTest, CreatePriority) {
-  const char kDescription[] = "PRIORITY frame";
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x05,        // Length: 5
-      0x02,                    //   Type: PRIORITY
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x02,  // Stream: 2
-      0x80, 0x00, 0x00, 0x01,  // Parent: 1 (Exclusive)
-      0x10,                    // Weight: 17
-  };
-  SpdyPriorityIR priority_ir(/* stream_id = */ 2,
-                             /* parent_stream_id = */ 1,
-                             /* weight = */ 17,
-                             /* exclusive = */ true);
-  SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-TEST_P(SpdyFramerTest, CreatePriorityUpdate) {
-  const char kDescription[] = "PRIORITY_UPDATE frame";
-  const unsigned char kType =
-      SerializeFrameType(SpdyFrameType::PRIORITY_UPDATE);
-  const unsigned char kFrameData[] = {
-      0x00,  0x00, 0x07,        // frame length
-      kType,                    // frame type
-      0x00,                     // flags
-      0x00,  0x00, 0x00, 0x00,  // stream ID, must be 0 for PRIORITY_UPDATE
-      0x00,  0x00, 0x00, 0x03,  // prioritized stream ID
-      'u',   '=',  '0'};        // priority field value
-  SpdyPriorityUpdateIR priority_update_ir(/* stream_id = */ 0,
-                                          /* prioritized_stream_id = */ 3,
-                                          /* priority_field_value = */ "u=0");
-  SpdySerializedFrame frame(framer_.SerializeFrame(priority_update_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(priority_update_ir, &output_),
-              frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-TEST_P(SpdyFramerTest, CreateAcceptCh) {
-  const char kDescription[] = "ACCEPT_CH frame";
-  const unsigned char kType = SerializeFrameType(SpdyFrameType::ACCEPT_CH);
-  const unsigned char kFrameData[] = {
-      0x00,  0x00, 0x2d,                  // frame length
-      kType,                              // frame type
-      0x00,                               // flags
-      0x00,  0x00, 0x00, 0x00,            // stream ID, must be 0 for ACCEPT_CH
-      0x00,  0x0f,                        // origin length
-      'w',   'w',  'w',  '.',  'e', 'x',  // origin
-      'a',   'm',  'p',  'l',  'e', '.',  //
-      'c',   'o',  'm',                   //
-      0x00,  0x03,                        // value length
-      'f',   'o',  'o',                   // value
-      0x00,  0x10,                        // origin length
-      'm',   'a',  'i',  'l',  '.', 'e',  //
-      'x',   'a',  'm',  'p',  'l', 'e',  //
-      '.',   'c',  'o',  'm',             //
-      0x00,  0x03,                        // value length
-      'b',   'a',  'r'};                  // value
-  SpdyAcceptChIR accept_ch_ir(
-      {{"www.example.com", "foo"}, {"mail.example.com", "bar"}});
-  SpdySerializedFrame frame(framer_.SerializeFrame(accept_ch_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(accept_ch_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-TEST_P(SpdyFramerTest, CreateUnknown) {
-  const char kDescription[] = "Unknown frame";
-  const uint8_t kType = 0xaf;
-  const uint8_t kFlags = 0x11;
-  const uint8_t kLength = strlen(kDescription);
-  const unsigned char kFrameData[] = {
-      0x00,   0x00, kLength,        // Length: 13
-      kType,                        //   Type: undefined
-      kFlags,                       //  Flags: arbitrary, undefined
-      0x00,   0x00, 0x00,    0x02,  // Stream: 2
-      0x55,   0x6e, 0x6b,    0x6e,  // "Unkn"
-      0x6f,   0x77, 0x6e,    0x20,  // "own "
-      0x66,   0x72, 0x61,    0x6d,  // "fram"
-      0x65,                         // "e"
-  };
-  SpdyUnknownIR unknown_ir(/* stream_id = */ 2,
-                           /* type = */ kType,
-                           /* flags = */ kFlags,
-                           /* payload = */ kDescription);
-  SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-// Test serialization of a SpdyUnknownIR with a defined type, a length field
-// that does not match the payload size and in fact exceeds framer limits, and a
-// stream ID that effectively flips the reserved bit.
-TEST_P(SpdyFramerTest, CreateUnknownUnchecked) {
-  const char kDescription[] = "Unknown frame";
-  const uint8_t kType = 0x00;
-  const uint8_t kFlags = 0x11;
-  const uint8_t kLength = std::numeric_limits<uint8_t>::max();
-  const unsigned int kStreamId = kStreamIdMask + 42;
-  const unsigned char kFrameData[] = {
-      0x00,   0x00, kLength,        // Length: 16426
-      kType,                        //   Type: DATA, defined
-      kFlags,                       //  Flags: arbitrary, undefined
-      0x80,   0x00, 0x00,    0x29,  // Stream: 2147483689
-      0x55,   0x6e, 0x6b,    0x6e,  // "Unkn"
-      0x6f,   0x77, 0x6e,    0x20,  // "own "
-      0x66,   0x72, 0x61,    0x6d,  // "fram"
-      0x65,                         // "e"
-  };
-  TestSpdyUnknownIR unknown_ir(/* stream_id = */ kStreamId,
-                               /* type = */ kType,
-                               /* flags = */ kFlags,
-                               /* payload = */ kDescription);
-  unknown_ir.set_length(kLength);
-  SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
-  if (use_output_) {
-    EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
-}
-
-TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
-  SpdyHeadersIR headers_ir(/* stream_id = */ 1);
-  headers_ir.SetHeader("alpha", "beta");
-  headers_ir.SetHeader("gamma", "delta");
-  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
-      &framer_, headers_ir, use_output_ ? &output_ : nullptr));
-  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.control_frame_header_data_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_EQ(0, visitor.end_of_stream_count_);
-  EXPECT_EQ(headers_ir.header_block(), visitor.headers_);
-}
-
-TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
-  SpdyHeadersIR headers_ir(/* stream_id = */ 1);
-  headers_ir.set_fin(true);
-  headers_ir.SetHeader("alpha", "beta");
-  headers_ir.SetHeader("gamma", "delta");
-  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
-      &framer_, headers_ir, use_output_ ? &output_ : nullptr));
-  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.control_frame_header_data_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_EQ(1, visitor.end_of_stream_count_);
-  EXPECT_EQ(headers_ir.header_block(), visitor.headers_);
-}
-
-TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-  SpdyHeadersIR headers(/* stream_id = */ 1);
-  headers.set_padding_len(256);
-
-  // Exact payload length will change with HPACK, but this should be long
-  // enough to cause an overflow.
-  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
-  std::string big_value(kBigValueSize, 'x');
-  headers.SetHeader("aa", big_value);
-  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
-      &framer, headers, use_output_ ? &output_ : nullptr));
-  EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(1, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-}
-
-TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-  auto headers = std::make_unique<SpdyHeadersIR>(/* stream_id = */ 1);
-  headers->set_padding_len(256);
-
-  // Exact payload length will change with HPACK, but this should be long
-  // enough to cause an overflow.
-  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
-  std::string big_valuex(kBigValueSize, 'x');
-  headers->SetHeader("aa", big_valuex);
-  std::string big_valuez(kBigValueSize, 'z');
-  headers->SetHeader("bb", big_valuez);
-
-  SpdyFramer::SpdyHeaderFrameIterator frame_it(&framer, std::move(headers));
-
-  EXPECT_TRUE(frame_it.HasNextFrame());
-  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
-  SpdySerializedFrame headers_frame(output_.Begin(), output_.Size(), false);
-  EXPECT_EQ(headers_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(headers_frame.data()),
-      headers_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-
-  output_.Reset();
-  EXPECT_TRUE(frame_it.HasNextFrame());
-  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
-  SpdySerializedFrame first_cont_frame(output_.Begin(), output_.Size(), false);
-  EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(first_cont_frame.data()),
-      first_cont_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(1, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-
-  output_.Reset();
-  EXPECT_TRUE(frame_it.HasNextFrame());
-  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
-  SpdySerializedFrame second_cont_frame(output_.Begin(), output_.Size(), false);
-  EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(second_cont_frame.data()),
-      second_cont_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(2, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-
-  EXPECT_FALSE(frame_it.HasNextFrame());
-}
-
-TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-  auto push_promise =
-      std::make_unique<SpdyPushPromiseIR>(/* stream_id = */ 1,
-                                          /* promised_stream_id = */ 2);
-  push_promise->set_padding_len(256);
-
-  // Exact payload length will change with HPACK, but this should be long
-  // enough to cause an overflow.
-  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
-  std::string big_valuex(kBigValueSize, 'x');
-  push_promise->SetHeader("aa", big_valuex);
-  std::string big_valuez(kBigValueSize, 'z');
-  push_promise->SetHeader("bb", big_valuez);
-
-  SpdyFramer::SpdyPushPromiseFrameIterator frame_it(&framer,
-                                                    std::move(push_promise));
-
-  EXPECT_TRUE(frame_it.HasNextFrame());
-  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
-  SpdySerializedFrame push_promise_frame(output_.Begin(), output_.Size(),
-                                         false);
-  EXPECT_EQ(push_promise_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(push_promise_frame.data()),
-      push_promise_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.push_promise_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-
-  EXPECT_TRUE(frame_it.HasNextFrame());
-  output_.Reset();
-  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
-  SpdySerializedFrame first_cont_frame(output_.Begin(), output_.Size(), false);
-
-  EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(first_cont_frame.data()),
-      first_cont_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.push_promise_frame_count_);
-  EXPECT_EQ(1, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-
-  EXPECT_TRUE(frame_it.HasNextFrame());
-  output_.Reset();
-  EXPECT_GT(frame_it.NextFrame(&output_), 0u);
-  SpdySerializedFrame second_cont_frame(output_.Begin(), output_.Size(), false);
-  EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(second_cont_frame.data()),
-      second_cont_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.push_promise_frame_count_);
-  EXPECT_EQ(2, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-
-  EXPECT_FALSE(frame_it.HasNextFrame());
-}
-
-class SpdyControlFrameIteratorTest : public quiche::test::QuicheTest {
- public:
-  SpdyControlFrameIteratorTest() : output_(output_buffer, kSize) {}
-
-  void RunTest(std::unique_ptr<SpdyFrameIR> ir) {
-    SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-    SpdySerializedFrame frame(framer.SerializeFrame(*ir));
-    std::unique_ptr<SpdyFrameSequence> it =
-        SpdyFramer::CreateIterator(&framer, std::move(ir));
-    EXPECT_TRUE(it->HasNextFrame());
-    EXPECT_EQ(it->NextFrame(&output_), frame.size());
-    EXPECT_FALSE(it->HasNextFrame());
-  }
-
- private:
-  ArrayOutputBuffer output_;
-};
-
-TEST_F(SpdyControlFrameIteratorTest, RstStreamFrameWithIterator) {
-  auto ir = std::make_unique<SpdyRstStreamIR>(0, ERROR_CODE_PROTOCOL_ERROR);
-  RunTest(std::move(ir));
-}
-
-TEST_F(SpdyControlFrameIteratorTest, SettingsFrameWithIterator) {
-  auto ir = std::make_unique<SpdySettingsIR>();
-  uint32_t kValue = 0x0a0b0c0d;
-  SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE;
-  ir->AddSetting(kId, kValue);
-  RunTest(std::move(ir));
-}
-
-TEST_F(SpdyControlFrameIteratorTest, PingFrameWithIterator) {
-  const SpdyPingId kPingId = 0x123456789abcdeffULL;
-  auto ir = std::make_unique<SpdyPingIR>(kPingId);
-  RunTest(std::move(ir));
-}
-
-TEST_F(SpdyControlFrameIteratorTest, GoAwayFrameWithIterator) {
-  auto ir = std::make_unique<SpdyGoAwayIR>(0, ERROR_CODE_NO_ERROR, "GA");
-  RunTest(std::move(ir));
-}
-
-TEST_F(SpdyControlFrameIteratorTest, WindowUpdateFrameWithIterator) {
-  auto ir = std::make_unique<SpdyWindowUpdateIR>(1, 1);
-  RunTest(std::move(ir));
-}
-
-TEST_F(SpdyControlFrameIteratorTest, AtlSvcFrameWithIterator) {
-  auto ir = std::make_unique<SpdyAltSvcIR>(3);
-  ir->set_origin("origin");
-  ir->add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
-  ir->add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
-      "p\"=i:d", "h_\\o\"st", 123, 42,
-      SpdyAltSvcWireFormat::VersionVector{24}));
-  RunTest(std::move(ir));
-}
-
-TEST_F(SpdyControlFrameIteratorTest, PriorityFrameWithIterator) {
-  auto ir = std::make_unique<SpdyPriorityIR>(2, 1, 17, true);
-  RunTest(std::move(ir));
-}
-
-TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-  SpdyPushPromiseIR push_promise(/* stream_id = */ 1,
-                                 /* promised_stream_id = */ 2);
-  push_promise.set_padding_len(256);
-
-  // Exact payload length will change with HPACK, but this should be long
-  // enough to cause an overflow.
-  const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
-  std::string big_value(kBigValueSize, 'x');
-  push_promise.SetHeader("aa", big_value);
-  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializePushPromise(
-      &framer, push_promise, use_output_ ? &output_ : nullptr));
-  EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_TRUE(visitor.header_buffer_valid_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.push_promise_frame_count_);
-  EXPECT_EQ(1, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-}
-
-// Check that the framer stops delivering header data chunks once the visitor
-// declares it doesn't want any more. This is important to guard against
-// "zip bomb" types of attacks.
-TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
-  const size_t kHeaderBufferChunks = 4;
-  const size_t kHeaderBufferSize =
-      kHttp2DefaultFramePayloadLimit / kHeaderBufferChunks;
-  const size_t kBigValueSize = kHeaderBufferSize * 2;
-  std::string big_value(kBigValueSize, 'x');
-  SpdyHeadersIR headers(/* stream_id = */ 1);
-  headers.set_fin(true);
-  headers.SetHeader("aa", big_value);
-  SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
-      &framer_, headers, use_output_ ? &output_ : nullptr));
-  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-  visitor.set_header_buffer_size(kHeaderBufferSize);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  // It's up to the visitor to ignore extraneous header data; the framer
-  // won't throw an error.
-  EXPECT_GT(visitor.header_bytes_received_, visitor.header_buffer_size_);
-  EXPECT_EQ(1, visitor.end_of_stream_count_);
-}
-
-TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
-  // Create a GoAway frame that has a few extra bytes at the end.
-  const size_t length = 20;
-
-  // HTTP/2 GOAWAY frames are only bound by a minimal length, since they may
-  // carry opaque data. Verify that minimal length is tested.
-  ASSERT_GT(kGoawayFrameMinimumSize, kFrameHeaderSize);
-  const size_t less_than_min_length =
-      kGoawayFrameMinimumSize - kFrameHeaderSize - 1;
-  ASSERT_LE(less_than_min_length, std::numeric_limits<unsigned char>::max());
-  const unsigned char kH2Len = static_cast<unsigned char>(less_than_min_length);
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, kH2Len,        // Length: min length - 1
-      0x07,                      //   Type: GOAWAY
-      0x00,                      //  Flags: none
-      0x00, 0x00, 0x00,   0x00,  // Stream: 0
-      0x00, 0x00, 0x00,   0x00,  //   Last: 0
-      0x00, 0x00, 0x00,          // Truncated Status Field
-  };
-  const size_t pad_length = length + kFrameHeaderSize - sizeof(kH2FrameData);
-  std::string pad(pad_length, 'A');
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-
-  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
-  visitor.SimulateInFramer(reinterpret_cast<const unsigned char*>(pad.c_str()),
-                           pad.length());
-
-  EXPECT_EQ(1, visitor.error_count_);  // This generated an error.
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(0, visitor.goaway_count_);  // Frame not parsed.
-}
-
-TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
-  SpdySettingsIR settings_ir;
-  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  SetFrameLength(&control_frame, 0);
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()), kFrameHeaderSize);
-  // Zero-len settings frames are permitted as of HTTP/2.
-  EXPECT_EQ(0, visitor.error_count_);
-}
-
-// Tests handling of SETTINGS frames with invalid length.
-TEST_P(SpdyFramerTest, ReadBogusLenSettingsFrame) {
-  SpdySettingsIR settings_ir;
-
-  // Add settings to more than fill the frame so that we don't get a buffer
-  // overflow when calling SimulateInFramer() below. These settings must be
-  // distinct parameters because SpdySettingsIR has a map for settings, and
-  // will collapse multiple copies of the same parameter.
-  settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 0x00000002);
-  settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 0x00000002);
-  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  const size_t kNewLength = 8;
-  SetFrameLength(&control_frame, kNewLength);
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      kFrameHeaderSize + kNewLength);
-  // Should generate an error, since its not possible to have a
-  // settings frame of length kNewLength.
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-}
-
-// Tests handling of larger SETTINGS frames.
-TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
-  SpdySettingsIR settings_ir;
-  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
-  settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
-  settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
-
-  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-
-  // Read all at once.
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(3, visitor.setting_count_);
-  EXPECT_EQ(1, visitor.settings_ack_sent_);
-
-  // Read data in small chunks.
-  size_t framed_data = 0;
-  size_t unframed_data = control_frame.size();
-  size_t kReadChunkSize = 5;  // Read five bytes at a time.
-  while (unframed_data > 0) {
-    size_t to_read = std::min(kReadChunkSize, unframed_data);
-    visitor.SimulateInFramer(
-        reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
-        to_read);
-    unframed_data -= to_read;
-    framed_data += to_read;
-  }
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(3 * 2, visitor.setting_count_);
-  EXPECT_EQ(2, visitor.settings_ack_sent_);
-}
-
-// Tests handling of SETTINGS frame with duplicate entries.
-TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x12,        // Length: 18
-      0x04,                    //   Type: SETTINGS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
-      0x00, 0x00, 0x00, 0x02,  //  Value: 2
-      0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
-      0x00, 0x00, 0x00, 0x03,  //  Value: 3
-      0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
-      0x00, 0x00, 0x00, 0x03,  //  Value: 3
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
-
-  // In HTTP/2, duplicate settings are allowed;
-  // each setting replaces the previous value for that setting.
-  EXPECT_EQ(3, visitor.setting_count_);
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.settings_ack_sent_);
-}
-
-// Tests handling of SETTINGS frame with a setting we don't recognize.
-TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x06,        // Length: 6
-      0x04,                    //   Type: SETTINGS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0x00, 0x10,              //  Param: 16
-      0x00, 0x00, 0x00, 0x02,  //  Value: 2
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
-
-  // In HTTP/2, we ignore unknown settings because of extensions. However, we
-  // pass the SETTINGS to the visitor, which can decide how to handle them.
-  EXPECT_EQ(1, visitor.setting_count_);
-  EXPECT_EQ(0, visitor.error_count_);
-}
-
-TEST_P(SpdyFramerTest, ReadKnownAndUnknownSettingsWithExtension) {
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x18,        // Length: 24
-      0x04,                    //   Type: SETTINGS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0x00, 0x10,              //  Param: 16
-      0x00, 0x00, 0x00, 0x02,  //  Value: 2
-      0x00, 0x5f,              //  Param: 95
-      0x00, 0x01, 0x00, 0x02,  //  Value: 65538
-      0x00, 0x02,              //  Param: ENABLE_PUSH
-      0x00, 0x00, 0x00, 0x01,  //  Value: 1
-      0x00, 0x08,              //  Param: ENABLE_CONNECT_PROTOCOL
-      0x00, 0x00, 0x00, 0x01,  //  Value: 1
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  TestExtension extension;
-  visitor.set_extension_visitor(&extension);
-  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
-
-  // In HTTP/2, we ignore unknown settings because of extensions. However, we
-  // pass the SETTINGS to the visitor, which can decide how to handle them.
-  EXPECT_EQ(4, visitor.setting_count_);
-  EXPECT_EQ(0, visitor.error_count_);
-
-  // The extension receives only the non-standard SETTINGS.
-  EXPECT_THAT(
-      extension.settings_received_,
-      testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538)));
-}
-
-// Tests handling of SETTINGS frame with entries out of order.
-TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x12,        // Length: 18
-      0x04,                    //   Type: SETTINGS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0x00, 0x02,              //  Param: ENABLE_PUSH
-      0x00, 0x00, 0x00, 0x02,  //  Value: 2
-      0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
-      0x00, 0x00, 0x00, 0x03,  //  Value: 3
-      0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
-      0x00, 0x00, 0x00, 0x03,  //  Value: 3
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
-
-  // In HTTP/2, settings are allowed in any order.
-  EXPECT_EQ(3, visitor.setting_count_);
-  EXPECT_EQ(0, visitor.error_count_);
-}
-
-TEST_P(SpdyFramerTest, ProcessSettingsAckFrame) {
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x00,        // Length: 0
-      0x04,                    //   Type: SETTINGS
-      0x01,                    //  Flags: ACK
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(0, visitor.setting_count_);
-  EXPECT_EQ(1, visitor.settings_ack_received_);
-}
-
-TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
-  const int kPaddingLen = 119;
-  const char data_payload[] = "hello";
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  SpdyDataIR data_ir(/* stream_id = */ 1, data_payload);
-  data_ir.set_padding_len(kPaddingLen);
-  SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-
-  int bytes_consumed = 0;
-
-  // Send the frame header.
-  EXPECT_CALL(visitor,
-              OnCommonHeader(1, kPaddingLen + strlen(data_payload), 0x0, 0x8));
-  EXPECT_CALL(visitor,
-              OnDataFrameHeader(1, kPaddingLen + strlen(data_payload), false));
-  QUICHE_CHECK_EQ(kDataFrameMinimumSize,
-                  deframer_->ProcessInput(frame.data(), kDataFrameMinimumSize));
-  QUICHE_CHECK_EQ(deframer_->state(),
-                  Http2DecoderAdapter::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
-  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
-                  Http2DecoderAdapter::SPDY_NO_ERROR);
-  bytes_consumed += kDataFrameMinimumSize;
-
-  // Send the padding length field.
-  EXPECT_CALL(visitor, OnStreamPadLength(1, kPaddingLen - 1));
-  QUICHE_CHECK_EQ(1u,
-                  deframer_->ProcessInput(frame.data() + bytes_consumed, 1));
-  QUICHE_CHECK_EQ(deframer_->state(),
-                  Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
-  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
-                  Http2DecoderAdapter::SPDY_NO_ERROR);
-  bytes_consumed += 1;
-
-  // Send the first two bytes of the data payload, i.e., "he".
-  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2));
-  QUICHE_CHECK_EQ(2u,
-                  deframer_->ProcessInput(frame.data() + bytes_consumed, 2));
-  QUICHE_CHECK_EQ(deframer_->state(),
-                  Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
-  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
-                  Http2DecoderAdapter::SPDY_NO_ERROR);
-  bytes_consumed += 2;
-
-  // Send the rest three bytes of the data payload, i.e., "llo".
-  EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3));
-  QUICHE_CHECK_EQ(3u,
-                  deframer_->ProcessInput(frame.data() + bytes_consumed, 3));
-  QUICHE_CHECK_EQ(deframer_->state(),
-                  Http2DecoderAdapter::SPDY_CONSUME_PADDING);
-  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
-                  Http2DecoderAdapter::SPDY_NO_ERROR);
-  bytes_consumed += 3;
-
-  // Send the first 100 bytes of the padding payload.
-  EXPECT_CALL(visitor, OnStreamPadding(1, 100));
-  QUICHE_CHECK_EQ(100u,
-                  deframer_->ProcessInput(frame.data() + bytes_consumed, 100));
-  QUICHE_CHECK_EQ(deframer_->state(),
-                  Http2DecoderAdapter::SPDY_CONSUME_PADDING);
-  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
-                  Http2DecoderAdapter::SPDY_NO_ERROR);
-  bytes_consumed += 100;
-
-  // Send rest of the padding payload.
-  EXPECT_CALL(visitor, OnStreamPadding(1, 18));
-  QUICHE_CHECK_EQ(18u,
-                  deframer_->ProcessInput(frame.data() + bytes_consumed, 18));
-  QUICHE_CHECK_EQ(deframer_->state(),
-                  Http2DecoderAdapter::SPDY_READY_FOR_FRAME);
-  QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
-                  Http2DecoderAdapter::SPDY_NO_ERROR);
-}
-
-TEST_P(SpdyFramerTest, ReadWindowUpdate) {
-  SpdySerializedFrame control_frame(framer_.SerializeWindowUpdate(
-      SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2)));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2), &output_));
-    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_EQ(1u, visitor.last_window_update_stream_);
-  EXPECT_EQ(2, visitor.last_window_update_delta_);
-}
-
-TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
-  SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
-                                 /* promised_stream_id = */ 57);
-  push_promise.SetHeader("foo", "bar");
-  push_promise.SetHeader("bar", "foofoo");
-  SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-      &framer_, push_promise, use_output_ ? &output_ : nullptr));
-  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
-                           frame.size());
-  EXPECT_EQ(42u, visitor.last_push_promise_stream_);
-  EXPECT_EQ(57u, visitor.last_push_promise_promised_stream_);
-  EXPECT_EQ(push_promise.header_block(), visitor.headers_);
-}
-
-TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
-  // frame-format off
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x14,                       // Length: 20
-      0x01,                                   //   Type: HEADERS
-      0x08,                                   //  Flags: PADDED
-      0x00, 0x00, 0x00, 0x01,                 // Stream: 1
-      0x03,                                   // PadLen: 3 trailing bytes
-      0x00,                                   // Unindexed Entry
-      0x06,                                   // Name Len: 6
-      'c',  'o',  'o',  'k',  'i', 'e',       // Name
-      0x07,                                   // Value Len: 7
-      'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
-      0x00, 0x00, 0x00,                       // Padding
-
-      0x00, 0x00, 0x14,                            // Length: 20
-      0x09,                                        //   Type: CONTINUATION
-      0x00,                                        //  Flags: none
-      0x00, 0x00, 0x00, 0x01,                      // Stream: 1
-      0x00,                                        // Unindexed Entry
-      0x06,                                        // Name Len: 6
-      'c',  'o',  'o',  'k',  'i', 'e',            // Name
-      0x08,                                        // Value Len: 7
-      'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
-      0x00,                                        // Unindexed Entry
-      0x06,                                        // Name Len: 6
-      'c',                                         // Name (split)
-
-      0x00, 0x00, 0x12,             // Length: 18
-      0x09,                         //   Type: CONTINUATION
-      0x04,                         //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,       // Stream: 1
-      'o',  'o',  'k',  'i',  'e',  // Name (continued)
-      0x00,                         // Value Len: 0
-      0x00,                         // Unindexed Entry
-      0x04,                         // Name Len: 4
-      'n',  'a',  'm',  'e',        // Name
-      0x05,                         // Value Len: 5
-      'v',  'a',  'l',  'u',  'e',  // Value
-  };
-  // frame-format on
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(2, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_EQ(0, visitor.end_of_stream_count_);
-
-  EXPECT_THAT(
-      visitor.headers_,
-      testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
-                           testing::Pair("name", "value")));
-}
-
-TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) {
-  // frame-format off
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x10,                       // Length: 20
-      0x01,                                   //   Type: HEADERS
-      0x01,                                   //  Flags: END_STREAM
-      0x00, 0x00, 0x00, 0x01,                 // Stream: 1
-      0x00,                                   // Unindexed Entry
-      0x06,                                   // Name Len: 6
-      'c',  'o',  'o',  'k',  'i', 'e',       // Name
-      0x07,                                   // Value Len: 7
-      'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
-
-      0x00, 0x00, 0x14,                            // Length: 20
-      0x09,                                        //   Type: CONTINUATION
-      0x00,                                        //  Flags: none
-      0x00, 0x00, 0x00, 0x01,                      // Stream: 1
-      0x00,                                        // Unindexed Entry
-      0x06,                                        // Name Len: 6
-      'c',  'o',  'o',  'k',  'i', 'e',            // Name
-      0x08,                                        // Value Len: 7
-      'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
-      0x00,                                        // Unindexed Entry
-      0x06,                                        // Name Len: 6
-      'c',                                         // Name (split)
-
-      0x00, 0x00, 0x12,             // Length: 18
-      0x09,                         //   Type: CONTINUATION
-      0x04,                         //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,       // Stream: 1
-      'o',  'o',  'k',  'i',  'e',  // Name (continued)
-      0x00,                         // Value Len: 0
-      0x00,                         // Unindexed Entry
-      0x04,                         // Name Len: 4
-      'n',  'a',  'm',  'e',        // Name
-      0x05,                         // Value Len: 5
-      'v',  'a',  'l',  'u',  'e',  // Value
-  };
-  // frame-format on
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(2, visitor.continuation_count_);
-  EXPECT_EQ(1, visitor.fin_flag_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_EQ(1, visitor.end_of_stream_count_);
-
-  EXPECT_THAT(
-      visitor.headers_,
-      testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
-                           testing::Pair("name", "value")));
-}
-
-TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) {
-  // frame-format off
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x17,                       // Length: 23
-      0x05,                                   //   Type: PUSH_PROMISE
-      0x08,                                   //  Flags: PADDED
-      0x00, 0x00, 0x00, 0x01,                 // Stream: 1
-      0x02,                                   // PadLen: 2 trailing bytes
-      0x00, 0x00, 0x00, 0x2a,                 // Promise: 42
-      0x00,                                   // Unindexed Entry
-      0x06,                                   // Name Len: 6
-      'c',  'o',  'o',  'k',  'i', 'e',       // Name
-      0x07,                                   // Value Len: 7
-      'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
-      0x00, 0x00,                             // Padding
-
-      0x00, 0x00, 0x14,                            // Length: 20
-      0x09,                                        //   Type: CONTINUATION
-      0x00,                                        //  Flags: none
-      0x00, 0x00, 0x00, 0x01,                      // Stream: 1
-      0x00,                                        // Unindexed Entry
-      0x06,                                        // Name Len: 6
-      'c',  'o',  'o',  'k',  'i', 'e',            // Name
-      0x08,                                        // Value Len: 7
-      'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
-      0x00,                                        // Unindexed Entry
-      0x06,                                        // Name Len: 6
-      'c',                                         // Name (split)
-
-      0x00, 0x00, 0x12,             // Length: 18
-      0x09,                         //   Type: CONTINUATION
-      0x04,                         //  Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,       // Stream: 1
-      'o',  'o',  'k',  'i',  'e',  // Name (continued)
-      0x00,                         // Value Len: 0
-      0x00,                         // Unindexed Entry
-      0x04,                         // Name Len: 4
-      'n',  'a',  'm',  'e',        // Name
-      0x05,                         // Value Len: 5
-      'v',  'a',  'l',  'u',  'e',  // Value
-  };
-  // frame-format on
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1u, visitor.last_push_promise_stream_);
-  EXPECT_EQ(42u, visitor.last_push_promise_promised_stream_);
-  EXPECT_EQ(2, visitor.continuation_count_);
-  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
-  EXPECT_EQ(0, visitor.end_of_stream_count_);
-
-  EXPECT_THAT(
-      visitor.headers_,
-      testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
-                           testing::Pair("name", "value")));
-}
-
-// Receiving an unknown frame when a continuation is expected should
-// result in a SPDY_UNEXPECTED_FRAME error
-TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuation) {
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x10,        // Length: 16
-      0x01,                    //   Type: HEADERS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-
-      0x00, 0x00, 0x14,        // Length: 20
-      0xa9,                    //   Type: UnknownFrameType(169)
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // Payload
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x08, 0x62, 0x61, 0x7a,  //
-      0x3d, 0x62, 0x69, 0x6e,  //
-      0x67, 0x00, 0x06, 0x63,  //
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  // Assume the unknown frame is allowed
-  visitor.on_unknown_frame_result_ = true;
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0u, visitor.header_buffer_length_);
-}
-
-// Receiving an unknown frame when a continuation is expected should
-// result in a SPDY_UNEXPECTED_FRAME error
-TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuationWithExtension) {
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x10,        // Length: 16
-      0x01,                    //   Type: HEADERS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-
-      0x00, 0x00, 0x14,        // Length: 20
-      0xa9,                    //   Type: UnknownFrameType(169)
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // Payload
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x08, 0x62, 0x61, 0x7a,  //
-      0x3d, 0x62, 0x69, 0x6e,  //
-      0x67, 0x00, 0x06, 0x63,  //
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  TestExtension extension;
-  visitor.set_extension_visitor(&extension);
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0u, visitor.header_buffer_length_);
-}
-
-TEST_P(SpdyFramerTest, ReceiveContinuationOnWrongStream) {
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x10,        // Length: 16
-      0x01,                    //   Type: HEADERS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-
-      0x00, 0x00, 0x14,        // Length: 20
-      0x09,                    //   Type: CONTINUATION
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x02,  // Stream: 2
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x08, 0x62, 0x61, 0x7a,  //
-      0x3d, 0x62, 0x69, 0x6e,  //
-      0x67, 0x00, 0x06, 0x63,  //
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0u, visitor.header_buffer_length_);
-}
-
-TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) {
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x18,        // Length: 24
-      0x09,                    //   Type: CONTINUATION
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0u, visitor.header_buffer_length_);
-}
-
-TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) {
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x10,        // Length: 16
-      0x01,                    //   Type: HEADERS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-
-      0x00, 0x00, 0x00,        // Length: 0
-      0x00,                    //   Type: DATA
-      0x01,                    //  Flags: END_STREAM
-      0x00, 0x00, 0x00, 0x04,  // Stream: 4
-
-      0xde, 0xad, 0xbe, 0xef,  // Truncated Frame Header
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0u, visitor.header_buffer_length_);
-  EXPECT_EQ(0, visitor.data_frame_count_);
-}
-
-TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) {
-  const unsigned char kInput[] = {
-      0x00, 0x00, 0x10,        // Length: 16
-      0x01,                    //   Type: HEADERS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-
-      0x00, 0x00, 0x10,        // Length: 16
-      0x01,                    //   Type: HEADERS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x06, 0x63, 0x6f,  // HPACK
-      0x6f, 0x6b, 0x69, 0x65,  //
-      0x07, 0x66, 0x6f, 0x6f,  //
-      0x3d, 0x62, 0x61, 0x72,  //
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kInput, sizeof(kInput));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-  EXPECT_EQ(1, visitor.headers_frame_count_);
-  EXPECT_EQ(0, visitor.continuation_count_);
-  EXPECT_EQ(0u, visitor.header_buffer_length_);
-  EXPECT_EQ(0, visitor.data_frame_count_);
-}
-
-TEST_P(SpdyFramerTest, ReadGarbage) {
-  unsigned char garbage_frame[256];
-  memset(garbage_frame, ~0, sizeof(garbage_frame));
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame));
-  EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST_P(SpdyFramerTest, ReadUnknownExtensionFrame) {
-  // The unrecognized frame type should still have a valid length.
-  const unsigned char unknown_frame[] = {
-      0x00, 0x00, 0x08,        // Length: 8
-      0xff,                    //   Type: UnknownFrameType(255)
-      0xff,                    //  Flags: 0xff
-      0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
-      0xff, 0xff, 0xff, 0xff,  // Payload
-      0xff, 0xff, 0xff, 0xff,  //
-  };
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-
-  // Simulate the case where the stream id validation checks out.
-  visitor.on_unknown_frame_result_ = true;
-  visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame));
-  EXPECT_EQ(0, visitor.error_count_);
-
-  // Follow it up with a valid control frame to make sure we handle
-  // subsequent frames correctly.
-  SpdySettingsIR settings_ir;
-  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10);
-  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
-  if (use_output_) {
-    ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-    control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.setting_count_);
-  EXPECT_EQ(1, visitor.settings_ack_sent_);
-}
-
-TEST_P(SpdyFramerTest, ReadUnknownExtensionFrameWithExtension) {
-  // The unrecognized frame type should still have a valid length.
-  const unsigned char unknown_frame[] = {
-      0x00, 0x00, 0x14,        // Length: 20
-      0xff,                    //   Type: UnknownFrameType(255)
-      0xff,                    //  Flags: 0xff
-      0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
-      0xff, 0xff, 0xff, 0xff,  // Payload
-      0xff, 0xff, 0xff, 0xff,  //
-      0xff, 0xff, 0xff, 0xff,  //
-      0xff, 0xff, 0xff, 0xff,  //
-      0xff, 0xff, 0xff, 0xff,  //
-  };
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  TestExtension extension;
-  visitor.set_extension_visitor(&extension);
-  visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame));
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(0x7fffffffu, extension.stream_id_);
-  EXPECT_EQ(20u, extension.length_);
-  EXPECT_EQ(255, extension.type_);
-  EXPECT_EQ(0xff, extension.flags_);
-  EXPECT_EQ(std::string(20, '\xff'), extension.payload_);
-
-  // Follow it up with a valid control frame to make sure we handle
-  // subsequent frames correctly.
-  SpdySettingsIR settings_ir;
-  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10);
-  SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame.data()),
-      control_frame.size());
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.setting_count_);
-  EXPECT_EQ(1, visitor.settings_ack_sent_);
-}
-
-TEST_P(SpdyFramerTest, ReadGarbageWithValidLength) {
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x08,        // Length: 8
-      0xff,                    //   Type: UnknownFrameType(255)
-      0xff,                    //  Flags: 0xff
-      0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
-      0xff, 0xff, 0xff, 0xff,  // Payload
-      0xff, 0xff, 0xff, 0xff,  //
-  };
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, ABSL_ARRAYSIZE(kFrameData));
-  EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST_P(SpdyFramerTest, ReadGarbageHPACKEncoding) {
-  const unsigned char kInput[] = {
-      0x00, 0x12, 0x01,        // Length: 4609
-      0x04,                    //   Type: SETTINGS
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x01, 0xef,  // Stream: 495
-      0xef, 0xff,              //  Param: 61439
-      0xff, 0xff, 0xff, 0xff,  //  Value: 4294967295
-      0xff, 0xff,              //  Param: 0xffff
-      0xff, 0xff, 0xff, 0xff,  //  Value: 4294967295
-      0xff, 0xff, 0xff, 0xff,  // Settings (Truncated)
-      0xff,                    //
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kInput, ABSL_ARRAYSIZE(kInput));
-  EXPECT_EQ(1, visitor.error_count_);
-}
-
-TEST_P(SpdyFramerTest, SizesTest) {
-  EXPECT_EQ(9u, kFrameHeaderSize);
-  EXPECT_EQ(9u, kDataFrameMinimumSize);
-  EXPECT_EQ(9u, kHeadersFrameMinimumSize);
-  EXPECT_EQ(14u, kPriorityFrameSize);
-  EXPECT_EQ(13u, kRstStreamFrameSize);
-  EXPECT_EQ(9u, kSettingsFrameMinimumSize);
-  EXPECT_EQ(13u, kPushPromiseFrameMinimumSize);
-  EXPECT_EQ(17u, kPingFrameSize);
-  EXPECT_EQ(17u, kGoawayFrameMinimumSize);
-  EXPECT_EQ(13u, kWindowUpdateFrameSize);
-  EXPECT_EQ(9u, kContinuationFrameMinimumSize);
-  EXPECT_EQ(11u, kGetAltSvcFrameMinimumSize);
-  EXPECT_EQ(9u, kFrameMinimumSize);
-
-  EXPECT_EQ(16384u, kHttp2DefaultFramePayloadLimit);
-  EXPECT_EQ(16393u, kHttp2DefaultFrameSizeLimit);
-}
-
-TEST_P(SpdyFramerTest, StateToStringTest) {
-  EXPECT_STREQ("ERROR", Http2DecoderAdapter::StateToString(
-                            Http2DecoderAdapter::SPDY_ERROR));
-  EXPECT_STREQ("FRAME_COMPLETE", Http2DecoderAdapter::StateToString(
-                                     Http2DecoderAdapter::SPDY_FRAME_COMPLETE));
-  EXPECT_STREQ("READY_FOR_FRAME",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_READY_FOR_FRAME));
-  EXPECT_STREQ("READING_COMMON_HEADER",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_READING_COMMON_HEADER));
-  EXPECT_STREQ("CONTROL_FRAME_PAYLOAD",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_CONTROL_FRAME_PAYLOAD));
-  EXPECT_STREQ("IGNORE_REMAINING_PAYLOAD",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_IGNORE_REMAINING_PAYLOAD));
-  EXPECT_STREQ("FORWARD_STREAM_FRAME",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME));
-  EXPECT_STREQ(
-      "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK",
-      Http2DecoderAdapter::StateToString(
-          Http2DecoderAdapter::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK));
-  EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_CONTROL_FRAME_HEADER_BLOCK));
-  EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_SETTINGS_FRAME_PAYLOAD));
-  EXPECT_STREQ("SPDY_ALTSVC_FRAME_PAYLOAD",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_ALTSVC_FRAME_PAYLOAD));
-  EXPECT_STREQ("UNKNOWN_STATE",
-               Http2DecoderAdapter::StateToString(
-                   Http2DecoderAdapter::SPDY_ALTSVC_FRAME_PAYLOAD + 1));
-}
-
-TEST_P(SpdyFramerTest, SpdyFramerErrorToStringTest) {
-  EXPECT_STREQ("NO_ERROR", Http2DecoderAdapter::SpdyFramerErrorToString(
-                               Http2DecoderAdapter::SPDY_NO_ERROR));
-  EXPECT_STREQ("INVALID_STREAM_ID",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_INVALID_STREAM_ID));
-  EXPECT_STREQ("INVALID_CONTROL_FRAME",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
-  EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
-  EXPECT_STREQ("DECOMPRESS_FAILURE",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_DECOMPRESS_FAILURE));
-  EXPECT_STREQ("INVALID_PADDING",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_INVALID_PADDING));
-  EXPECT_STREQ("INVALID_DATA_FRAME_FLAGS",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS));
-  EXPECT_STREQ("UNEXPECTED_FRAME",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME));
-  EXPECT_STREQ("INTERNAL_FRAMER_ERROR",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_INTERNAL_FRAMER_ERROR));
-  EXPECT_STREQ("INVALID_CONTROL_FRAME_SIZE",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE));
-  EXPECT_STREQ("OVERSIZED_PAYLOAD",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD));
-  EXPECT_STREQ("UNKNOWN_ERROR", Http2DecoderAdapter::SpdyFramerErrorToString(
-                                    Http2DecoderAdapter::LAST_ERROR));
-  EXPECT_STREQ("UNKNOWN_ERROR",
-               Http2DecoderAdapter::SpdyFramerErrorToString(
-                   static_cast<Http2DecoderAdapter::SpdyFramerError>(
-                       Http2DecoderAdapter::LAST_ERROR + 1)));
-}
-
-TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
-  uint8_t valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED;
-
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-    deframer_->set_visitor(&visitor);
-
-    SpdyDataIR data_ir(/* stream_id = */ 1, "hello");
-    SpdySerializedFrame frame(framer_.SerializeData(data_ir));
-    SetFrameFlags(&frame, flags);
-
-    EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, flags));
-    if (flags & ~valid_data_flags) {
-      EXPECT_CALL(visitor, OnError(_, _));
-    } else {
-      EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
-      if (flags & DATA_FLAG_PADDED) {
-        // The first byte of payload is parsed as padding length, but 'h'
-        // (0x68) is too large a padding length for a 5 byte payload.
-        EXPECT_CALL(visitor, OnStreamPadding(_, 1));
-        // Expect Error since the frame ends prematurely.
-        EXPECT_CALL(visitor, OnError(_, _));
-      } else {
-        EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5));
-        if (flags & DATA_FLAG_FIN) {
-          EXPECT_CALL(visitor, OnStreamEnd(_));
-        }
-      }
-    }
-
-    deframer_->ProcessInput(frame.data(), frame.size());
-    if (flags & ~valid_data_flags) {
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS,
-                deframer_->spdy_framer_error())
-          << Http2DecoderAdapter::SpdyFramerErrorToString(
-                 deframer_->spdy_framer_error());
-    } else if (flags & DATA_FLAG_PADDED) {
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
-                deframer_->spdy_framer_error())
-          << Http2DecoderAdapter::SpdyFramerErrorToString(
-                 deframer_->spdy_framer_error());
-    } else {
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-                deframer_->spdy_framer_error())
-          << Http2DecoderAdapter::SpdyFramerErrorToString(
-                 deframer_->spdy_framer_error());
-    }
-    deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-    deframer_->set_visitor(&visitor);
-
-    SpdyRstStreamIR rst_stream(/* stream_id = */ 13, ERROR_CODE_CANCEL);
-    SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    SetFrameFlags(&frame, flags);
-
-    EXPECT_CALL(visitor, OnCommonHeader(13, 4, 0x3, flags));
-    EXPECT_CALL(visitor, OnRstStream(13, ERROR_CODE_CANCEL));
-
-    deframer_->ProcessInput(frame.data(), frame.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-              deframer_->spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer_->spdy_framer_error());
-    deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, SettingsFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-    deframer_->set_visitor(&visitor);
-
-    SpdySettingsIR settings_ir;
-    settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16);
-    SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    SetFrameFlags(&frame, flags);
-
-    EXPECT_CALL(visitor, OnCommonHeader(0, 6, 0x4, flags));
-    if (flags & SETTINGS_FLAG_ACK) {
-      EXPECT_CALL(visitor, OnError(_, _));
-    } else {
-      EXPECT_CALL(visitor, OnSettings());
-      EXPECT_CALL(visitor, OnSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16));
-      EXPECT_CALL(visitor, OnSettingsEnd());
-    }
-
-    deframer_->ProcessInput(frame.data(), frame.size());
-    if (flags & SETTINGS_FLAG_ACK) {
-      // The frame is invalid because ACK frames should have no payload.
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-                deframer_->spdy_framer_error())
-          << Http2DecoderAdapter::SpdyFramerErrorToString(
-                 deframer_->spdy_framer_error());
-    } else {
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-      EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-                deframer_->spdy_framer_error())
-          << Http2DecoderAdapter::SpdyFramerErrorToString(
-                 deframer_->spdy_framer_error());
-    }
-    deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, GoawayFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-    deframer_->set_visitor(&visitor);
-
-    SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 97, ERROR_CODE_NO_ERROR,
-                           "test");
-    SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
-    if (use_output_) {
-      output_.Reset();
-      ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
-      frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    }
-    SetFrameFlags(&frame, flags);
-
-    EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x7, flags));
-    EXPECT_CALL(visitor, OnGoAway(97, ERROR_CODE_NO_ERROR));
-    EXPECT_CALL(visitor, OnGoAwayFrameData)
-        .WillRepeatedly(testing::Return(true));
-
-    deframer_->ProcessInput(frame.data(), frame.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-              deframer_->spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer_->spdy_framer_error());
-    deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, HeadersFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-    Http2DecoderAdapter deframer;
-    deframer.set_visitor(&visitor);
-
-    SpdyHeadersIR headers_ir(/* stream_id = */ 57);
-    if (flags & HEADERS_FLAG_PRIORITY) {
-      headers_ir.set_weight(3);
-      headers_ir.set_has_priority(true);
-      headers_ir.set_parent_stream_id(5);
-      headers_ir.set_exclusive(true);
-    }
-    headers_ir.SetHeader("foo", "bar");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
-        &framer, headers_ir, use_output_ ? &output_ : nullptr));
-    uint8_t set_flags = flags & ~HEADERS_FLAG_PADDED;
-    SetFrameFlags(&frame, set_flags);
-
-    // Expected callback values
-    SpdyStreamId stream_id = 57;
-    bool has_priority = false;
-    int weight = 0;
-    SpdyStreamId parent_stream_id = 0;
-    bool exclusive = false;
-    bool fin = flags & CONTROL_FLAG_FIN;
-    bool end = flags & HEADERS_FLAG_END_HEADERS;
-    if (flags & HEADERS_FLAG_PRIORITY) {
-      has_priority = true;
-      weight = 3;
-      parent_stream_id = 5;
-      exclusive = true;
-    }
-    EXPECT_CALL(visitor, OnCommonHeader(stream_id, _, 0x1, set_flags));
-    EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, weight,
-                                   parent_stream_id, exclusive, fin, end));
-    EXPECT_CALL(visitor, OnHeaderFrameStart(57)).Times(1);
-    if (end) {
-      EXPECT_CALL(visitor, OnHeaderFrameEnd(57)).Times(1);
-    }
-    if (flags & DATA_FLAG_FIN && end) {
-      EXPECT_CALL(visitor, OnStreamEnd(_));
-    } else {
-      // Do not close the stream if we are expecting a CONTINUATION frame.
-      EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0);
-    }
-
-    deframer.ProcessInput(frame.data(), frame.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer.spdy_framer_error());
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, PingFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-    deframer_->set_visitor(&visitor);
-
-    SpdySerializedFrame frame(framer_.SerializePing(SpdyPingIR(42)));
-    SetFrameFlags(&frame, flags);
-
-    EXPECT_CALL(visitor, OnCommonHeader(0, 8, 0x6, flags));
-    EXPECT_CALL(visitor, OnPing(42, flags & PING_FLAG_ACK));
-
-    deframer_->ProcessInput(frame.data(), frame.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-              deframer_->spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer_->spdy_framer_error());
-    deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-    deframer_->set_visitor(&visitor);
-
-    SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(/* stream_id = */ 4, /* delta = */ 1024)));
-    SetFrameFlags(&frame, flags);
-
-    EXPECT_CALL(visitor, OnCommonHeader(4, 4, 0x8, flags));
-    EXPECT_CALL(visitor, OnWindowUpdate(4, 1024));
-
-    deframer_->ProcessInput(frame.data(), frame.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-              deframer_->spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer_->spdy_framer_error());
-    deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, PushPromiseFrameFlags) {
-  const SpdyStreamId client_id = 123;   // Must be odd.
-  const SpdyStreamId promised_id = 22;  // Must be even.
-  uint8_t flags = 0;
-  do {
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-    testing::StrictMock<test::MockDebugVisitor> debug_visitor;
-    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-    Http2DecoderAdapter deframer;
-    deframer.set_visitor(&visitor);
-    deframer.set_debug_visitor(&debug_visitor);
-    framer.set_debug_visitor(&debug_visitor);
-
-    EXPECT_CALL(
-        debug_visitor,
-        OnSendCompressedFrame(client_id, SpdyFrameType::PUSH_PROMISE, _, _));
-
-    SpdyPushPromiseIR push_promise(client_id, promised_id);
-    push_promise.SetHeader("foo", "bar");
-    SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
-        &framer, push_promise, use_output_ ? &output_ : nullptr));
-    // TODO(jgraettinger): Add padding to SpdyPushPromiseIR,
-    // and implement framing.
-    SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED);
-
-    bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
-    EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(
-                                   client_id, SpdyFrameType::PUSH_PROMISE, _));
-    EXPECT_CALL(visitor, OnCommonHeader(client_id, _, 0x5,
-                                        flags & ~HEADERS_FLAG_PADDED));
-    EXPECT_CALL(visitor, OnPushPromise(client_id, promised_id, end));
-    EXPECT_CALL(visitor, OnHeaderFrameStart(client_id)).Times(1);
-    if (end) {
-      EXPECT_CALL(visitor, OnHeaderFrameEnd(client_id)).Times(1);
-    }
-
-    deframer.ProcessInput(frame.data(), frame.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer.spdy_framer_error());
-  } while (++flags != 0);
-}
-
-TEST_P(SpdyFramerTest, ContinuationFrameFlags) {
-  uint8_t flags = 0;
-  do {
-    if (use_output_) {
-      output_.Reset();
-    }
-    SCOPED_TRACE(testing::Message()
-                 << "Flags " << std::hex << static_cast<int>(flags));
-
-    testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-    testing::StrictMock<test::MockDebugVisitor> debug_visitor;
-    SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
-    Http2DecoderAdapter deframer;
-    deframer.set_visitor(&visitor);
-    deframer.set_debug_visitor(&debug_visitor);
-    framer.set_debug_visitor(&debug_visitor);
-
-    EXPECT_CALL(debug_visitor,
-                OnSendCompressedFrame(42, SpdyFrameType::HEADERS, _, _));
-    EXPECT_CALL(debug_visitor,
-                OnReceiveCompressedFrame(42, SpdyFrameType::HEADERS, _));
-    EXPECT_CALL(visitor, OnCommonHeader(42, _, 0x1, 0));
-    EXPECT_CALL(visitor, OnHeaders(42, false, 0, 0, false, false, false));
-    EXPECT_CALL(visitor, OnHeaderFrameStart(42)).Times(1);
-
-    SpdyHeadersIR headers_ir(/* stream_id = */ 42);
-    headers_ir.SetHeader("foo", "bar");
-    SpdySerializedFrame frame0;
-    if (use_output_) {
-      EXPECT_TRUE(framer.SerializeHeaders(headers_ir, &output_));
-      frame0 = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-    } else {
-      frame0 = framer.SerializeHeaders(headers_ir);
-    }
-    SetFrameFlags(&frame0, 0);
-
-    SpdyContinuationIR continuation(/* stream_id = */ 42);
-    SpdySerializedFrame frame1;
-    if (use_output_) {
-      char* begin = output_.Begin() + output_.Size();
-      ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
-      frame1 =
-          SpdySerializedFrame(begin, output_.Size() - frame0.size(), false);
-    } else {
-      frame1 = framer.SerializeContinuation(continuation);
-    }
-    SetFrameFlags(&frame1, flags);
-
-    EXPECT_CALL(debug_visitor,
-                OnReceiveCompressedFrame(42, SpdyFrameType::CONTINUATION, _));
-    EXPECT_CALL(visitor, OnCommonHeader(42, _, 0x9, flags));
-    EXPECT_CALL(visitor, OnContinuation(42, flags & HEADERS_FLAG_END_HEADERS));
-    bool end = flags & HEADERS_FLAG_END_HEADERS;
-    if (end) {
-      EXPECT_CALL(visitor, OnHeaderFrameEnd(42)).Times(1);
-    }
-
-    deframer.ProcessInput(frame0.data(), frame0.size());
-    deframer.ProcessInput(frame1.data(), frame1.size());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer.spdy_framer_error());
-  } while (++flags != 0);
-}
-
-// TODO(mlavan): Add TEST_P(SpdyFramerTest, AltSvcFrameFlags)
-
-// Test handling of a RST_STREAM with out-of-bounds status codes.
-TEST_P(SpdyFramerTest, RstStreamStatusBounds) {
-  const unsigned char kH2RstStreamInvalid[] = {
-      0x00, 0x00, 0x04,        // Length: 4
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
-  };
-  const unsigned char kH2RstStreamNumStatusCodes[] = {
-      0x00, 0x00, 0x04,        // Length: 4
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00, 0x00, 0x00, 0xff,  //  Error: 255
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x3, 0x0));
-  EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_NO_ERROR));
-  deframer_->ProcessInput(reinterpret_cast<const char*>(kH2RstStreamInvalid),
-                          ABSL_ARRAYSIZE(kH2RstStreamInvalid));
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-  deframer_ = absl::make_unique<Http2DecoderAdapter>();
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x3, 0x0));
-  EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_INTERNAL_ERROR));
-  deframer_->ProcessInput(
-      reinterpret_cast<const char*>(kH2RstStreamNumStatusCodes),
-      ABSL_ARRAYSIZE(kH2RstStreamNumStatusCodes));
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Test handling of GOAWAY frames with out-of-bounds status code.
-TEST_P(SpdyFramerTest, GoAwayStatusBounds) {
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x0a,        // Length: 10
-      0x07,                    //   Type: GOAWAY
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0x00, 0x00, 0x00, 0x01,  //   Last: 1
-      0xff, 0xff, 0xff, 0xff,  //  Error: 0xffffffff
-      0x47, 0x41,              // Description
-  };
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 10, 0x7, 0x0));
-  EXPECT_CALL(visitor, OnGoAway(1, ERROR_CODE_INTERNAL_ERROR));
-  EXPECT_CALL(visitor, OnGoAwayFrameData).WillRepeatedly(testing::Return(true));
-  deframer_->ProcessInput(reinterpret_cast<const char*>(kH2FrameData),
-                          ABSL_ARRAYSIZE(kH2FrameData));
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Tests handling of a GOAWAY frame with out-of-bounds stream ID.
-TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
-  const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x08,        // Length: 8
-      0x07,                    //   Type: GOAWAY
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0xff, 0xff, 0xff, 0xff,  //   Last: 0x7fffffff (R-bit set)
-      0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 8, 0x7, 0x0));
-  EXPECT_CALL(visitor, OnGoAway(0x7fffffff, ERROR_CODE_NO_ERROR));
-  EXPECT_CALL(visitor, OnGoAwayFrameData).WillRepeatedly(testing::Return(true));
-  deframer_->ProcessInput(reinterpret_cast<const char*>(kH2FrameData),
-                          ABSL_ARRAYSIZE(kH2FrameData));
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, OnAltSvcWithOrigin) {
-  const SpdyStreamId kStreamId = 0;  // Stream id must be zero if origin given.
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyAltSvcWireFormat::AlternativeService altsvc1(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
-  SpdyAltSvcWireFormat::AlternativeService altsvc2(
-      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  altsvc_vector.push_back(altsvc1);
-  altsvc_vector.push_back(altsvc2);
-  EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
-  EXPECT_CALL(visitor,
-              OnAltSvc(kStreamId, absl::string_view("o_r|g!n"), altsvc_vector));
-
-  SpdyAltSvcIR altsvc_ir(kStreamId);
-  altsvc_ir.set_origin("o_r|g!n");
-  altsvc_ir.add_altsvc(altsvc1);
-  altsvc_ir.add_altsvc(altsvc2);
-  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
-  if (use_output_) {
-    output_.Reset();
-    EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  deframer_->ProcessInput(frame.data(), frame.size());
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) {
-  const SpdyStreamId kStreamId = 1;
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  SpdyAltSvcWireFormat::AlternativeService altsvc1(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
-  SpdyAltSvcWireFormat::AlternativeService altsvc2(
-      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  altsvc_vector.push_back(altsvc1);
-  altsvc_vector.push_back(altsvc2);
-  EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
-  EXPECT_CALL(visitor,
-              OnAltSvc(kStreamId, absl::string_view(""), altsvc_vector));
-
-  SpdyAltSvcIR altsvc_ir(kStreamId);
-  altsvc_ir.add_altsvc(altsvc1);
-  altsvc_ir.add_altsvc(altsvc2);
-  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
-  deframer_->ProcessInput(frame.data(), frame.size());
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, OnAltSvcEmptyProtocolId) {
-  const SpdyStreamId kStreamId = 0;  // Stream id must be zero if origin given.
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
-  EXPECT_CALL(visitor,
-              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME, _));
-
-  SpdyAltSvcIR altsvc_ir(kStreamId);
-  altsvc_ir.set_origin("o1");
-  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
-  altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
-      "", "h1", 443, 10, SpdyAltSvcWireFormat::VersionVector()));
-  SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
-  if (use_output_) {
-    output_.Reset();
-    EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  deframer_->ProcessInput(frame.data(), frame.size());
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, OnAltSvcBadLengths) {
-  const unsigned char kType = SerializeFrameType(SpdyFrameType::ALTSVC);
-  const unsigned char kFrameDataOriginLenLargerThanFrame[] = {
-      0x00, 0x00, 0x05, kType, 0x00, 0x00, 0x00,
-      0x00, 0x03, 0x42, 0x42,  'f',  'o',  'o',
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-
-  deframer_->set_visitor(&visitor);
-  visitor.SimulateInFramer(kFrameDataOriginLenLargerThanFrame,
-                           sizeof(kFrameDataOriginLenLargerThanFrame));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
-            visitor.deframer_.spdy_framer_error());
-}
-
-// Tests handling of ALTSVC frames delivered in small chunks.
-TEST_P(SpdyFramerTest, ReadChunkedAltSvcFrame) {
-  SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
-  SpdyAltSvcWireFormat::AlternativeService altsvc1(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
-  SpdyAltSvcWireFormat::AlternativeService altsvc2(
-      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
-  altsvc_ir.add_altsvc(altsvc1);
-  altsvc_ir.add_altsvc(altsvc2);
-
-  SpdySerializedFrame control_frame(framer_.SerializeAltSvc(altsvc_ir));
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-
-  // Read data in small chunks.
-  size_t framed_data = 0;
-  size_t unframed_data = control_frame.size();
-  size_t kReadChunkSize = 5;  // Read five bytes at a time.
-  while (unframed_data > 0) {
-    size_t to_read = std::min(kReadChunkSize, unframed_data);
-    visitor.SimulateInFramer(
-        reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
-        to_read);
-    unframed_data -= to_read;
-    framed_data += to_read;
-  }
-  EXPECT_EQ(0, visitor.error_count_);
-  EXPECT_EQ(1, visitor.altsvc_count_);
-  ASSERT_NE(nullptr, visitor.test_altsvc_ir_);
-  ASSERT_EQ(2u, visitor.test_altsvc_ir_->altsvc_vector().size());
-  EXPECT_TRUE(visitor.test_altsvc_ir_->altsvc_vector()[0] == altsvc1);
-  EXPECT_TRUE(visitor.test_altsvc_ir_->altsvc_vector()[1] == altsvc2);
-}
-
-// While RFC7838 Section 4 says that an ALTSVC frame on stream 0 with empty
-// origin MUST be ignored, it is not implemented at the framer level: instead,
-// such frames are passed on to the consumer.
-TEST_P(SpdyFramerTest, ReadAltSvcFrame) {
-  constexpr struct {
-    uint32_t stream_id;
-    const char* origin;
-  } test_cases[] = {{0, ""},
-                    {1, ""},
-                    {0, "https://www.example.com"},
-                    {1, "https://www.example.com"}};
-  for (const auto& test_case : test_cases) {
-    SpdyAltSvcIR altsvc_ir(test_case.stream_id);
-    SpdyAltSvcWireFormat::AlternativeService altsvc(
-        "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
-    altsvc_ir.add_altsvc(altsvc);
-    altsvc_ir.set_origin(test_case.origin);
-    SpdySerializedFrame frame(framer_.SerializeAltSvc(altsvc_ir));
-
-    TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-    deframer_->set_visitor(&visitor);
-    deframer_->ProcessInput(frame.data(), frame.size());
-
-    EXPECT_EQ(0, visitor.error_count_);
-    EXPECT_EQ(1, visitor.altsvc_count_);
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-    EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
-              deframer_->spdy_framer_error())
-        << Http2DecoderAdapter::SpdyFramerErrorToString(
-               deframer_->spdy_framer_error());
-  }
-}
-
-// An ALTSVC frame with invalid Alt-Svc-Field-Value results in an error.
-TEST_P(SpdyFramerTest, ErrorOnAltSvcFrameWithInvalidValue) {
-  // Alt-Svc-Field-Value must be "clear" or must contain an "=" character
-  // per RFC7838 Section 3.
-  const char kFrameData[] = {
-      0x00, 0x00, 0x16,        //     Length: 22
-      0x0a,                    //       Type: ALTSVC
-      0x00,                    //      Flags: none
-      0x00, 0x00, 0x00, 0x01,  //     Stream: 1
-      0x00, 0x00,              // Origin-Len: 0
-      0x74, 0x68, 0x69, 0x73,  // thisisnotavalidvalue
-      0x69, 0x73, 0x6e, 0x6f, 0x74, 0x61, 0x76, 0x61,
-      0x6c, 0x69, 0x64, 0x76, 0x61, 0x6c, 0x75, 0x65,
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
-  deframer_->set_visitor(&visitor);
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(1, visitor.error_count_);
-  EXPECT_EQ(0, visitor.altsvc_count_);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
-            deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-TEST_P(SpdyFramerTest, ReadPriorityUpdateFrame) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x07,        // payload length
-      0x10,                    // frame type PRIORITY_UPDATE
-      0x00,                    // flags
-      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
-      0x00, 0x00, 0x00, 0x03,  // prioritized stream ID, must not be zero
-      'f',  'o',  'o'          // priority field value
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 7, 0x10, 0x0));
-  EXPECT_CALL(visitor, OnPriorityUpdate(3, "foo"));
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-  EXPECT_FALSE(deframer_->HasError());
-}
-
-TEST_P(SpdyFramerTest, ReadPriorityUpdateFrameWithEmptyPriorityFieldValue) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x04,        // payload length
-      0x10,                    // frame type PRIORITY_UPDATE
-      0x00,                    // flags
-      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
-      0x00, 0x00, 0x00, 0x03   // prioritized stream ID, must not be zero
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 4, 0x10, 0x0));
-  EXPECT_CALL(visitor, OnPriorityUpdate(3, ""));
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-  EXPECT_FALSE(deframer_->HasError());
-}
-
-TEST_P(SpdyFramerTest, PriorityUpdateFrameWithEmptyPayload) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x00,        // payload length
-      0x10,                    // frame type PRIORITY_UPDATE
-      0x00,                    // flags
-      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 0, 0x10, 0x0));
-  EXPECT_CALL(visitor,
-              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE, _));
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-  EXPECT_TRUE(deframer_->HasError());
-}
-
-TEST_P(SpdyFramerTest, PriorityUpdateFrameWithShortPayload) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x02,        // payload length
-      0x10,                    // frame type PRIORITY_UPDATE
-      0x00,                    // flags
-      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
-      0x00, 0x01  // payload not long enough to hold 32 bits of prioritized
-                  // stream ID
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 2, 0x10, 0x0));
-  EXPECT_CALL(visitor,
-              OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE, _));
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-  EXPECT_TRUE(deframer_->HasError());
-}
-
-TEST_P(SpdyFramerTest, PriorityUpdateFrameOnIncorrectStream) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x04,        // payload length
-      0x10,                    // frame type PRIORITY_UPDATE
-      0x00,                    // flags
-      0x00, 0x00, 0x00, 0x01,  // invalid stream ID, must be 0
-      0x00, 0x00, 0x00, 0x01,  // prioritized stream ID, must not be zero
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x10, 0x0));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-  EXPECT_TRUE(deframer_->HasError());
-}
-
-TEST_P(SpdyFramerTest, PriorityUpdateFramePrioritizingIncorrectStream) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x04,        // payload length
-      0x10,                    // frame type PRIORITY_UPDATE
-      0x00,                    // flags
-      0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
-      0x00, 0x00, 0x00, 0x00,  // prioritized stream ID, must not be zero
-  };
-
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-
-  EXPECT_CALL(visitor, OnCommonHeader(0, 4, 0x10, 0x0));
-  EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
-  deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
-  EXPECT_TRUE(deframer_->HasError());
-}
-
-// Tests handling of PRIORITY frames.
-TEST_P(SpdyFramerTest, ReadPriority) {
-  SpdyPriorityIR priority(/* stream_id = */ 3,
-                          /* parent_stream_id = */ 1,
-                          /* weight = */ 256,
-                          /* exclusive = */ false);
-  SpdySerializedFrame frame(framer_.SerializePriority(priority));
-  if (use_output_) {
-    output_.Reset();
-    ASSERT_TRUE(framer_.SerializePriority(priority, &output_));
-    frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
-  }
-  testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
-  deframer_->set_visitor(&visitor);
-  EXPECT_CALL(visitor, OnCommonHeader(3, 5, 0x2, 0x0));
-  EXPECT_CALL(visitor, OnPriority(3, 1, 256, false));
-  deframer_->ProcessInput(frame.data(), frame.size());
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             deframer_->spdy_framer_error());
-}
-
-// Tests handling of PRIORITY frame with incorrect size.
-TEST_P(SpdyFramerTest, ReadIncorrectlySizedPriority) {
-  // PRIORITY frame of size 4, which isn't correct.
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x04,        // Length: 4
-      0x02,                    //   Type: PRIORITY
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x00, 0x01,  // Priority (Truncated)
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-}
-
-// Tests handling of PING frame with incorrect size.
-TEST_P(SpdyFramerTest, ReadIncorrectlySizedPing) {
-  // PING frame of size 4, which isn't correct.
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x04,        // Length: 4
-      0x06,                    //   Type: PING
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x00,  // Stream: 0
-      0x00, 0x00, 0x00, 0x01,  // Ping (Truncated)
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-}
-
-// Tests handling of WINDOW_UPDATE frame with incorrect size.
-TEST_P(SpdyFramerTest, ReadIncorrectlySizedWindowUpdate) {
-  // WINDOW_UPDATE frame of size 3, which isn't correct.
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x03,        // Length: 3
-      0x08,                    //   Type: WINDOW_UPDATE
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x01,        // WindowUpdate (Truncated)
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-}
-
-// Tests handling of RST_STREAM frame with incorrect size.
-TEST_P(SpdyFramerTest, ReadIncorrectlySizedRstStream) {
-  // RST_STREAM frame of size 3, which isn't correct.
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x03,        // Length: 3
-      0x03,                    //   Type: RST_STREAM
-      0x00,                    //  Flags: none
-      0x00, 0x00, 0x00, 0x03,  // Stream: 3
-      0x00, 0x00, 0x01,        // RstStream (Truncated)
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-}
-
-// Regression test for https://crbug.com/548674:
-// RST_STREAM with payload must not be accepted.
-TEST_P(SpdyFramerTest, ReadInvalidRstStreamWithPayload) {
-  const unsigned char kFrameData[] = {
-      0x00, 0x00, 0x07,        //  Length: 7
-      0x03,                    //    Type: RST_STREAM
-      0x00,                    //   Flags: none
-      0x00, 0x00, 0x00, 0x01,  //  Stream: 1
-      0x00, 0x00, 0x00, 0x00,  //   Error: NO_ERROR
-      'f',  'o',  'o'          // Payload: "foo"
-  };
-
-  TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
-  visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
-
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
-            visitor.deframer_.spdy_framer_error())
-      << Http2DecoderAdapter::SpdyFramerErrorToString(
-             visitor.deframer_.spdy_framer_error());
-}
-
-// Test that SpdyFramer processes all passed input in one call to ProcessInput.
-TEST_P(SpdyFramerTest, ProcessAllInput) {
-  auto visitor =
-      std::make_unique<TestSpdyVisitor>(SpdyFramer::DISABLE_COMPRESSION);
-  deframer_->set_visitor(visitor.get());
-
-  // Create two input frames.
-  SpdyHeadersIR headers(/* stream_id = */ 1);
-  headers.SetHeader("alpha", "beta");
-  headers.SetHeader("gamma", "charlie");
-  headers.SetHeader("cookie", "key1=value1; key2=value2");
-  SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders(
-      &framer_, headers, use_output_ ? &output_ : nullptr));
-
-  const char four_score[] = "Four score and seven years ago";
-  SpdyDataIR four_score_ir(/* stream_id = */ 1, four_score);
-  SpdySerializedFrame four_score_frame(framer_.SerializeData(four_score_ir));
-
-  // Put them in a single buffer (new variables here to make it easy to
-  // change the order and type of frames).
-  SpdySerializedFrame frame1 = std::move(headers_frame);
-  SpdySerializedFrame frame2 = std::move(four_score_frame);
-
-  const size_t frame1_size = frame1.size();
-  const size_t frame2_size = frame2.size();
-
-  QUICHE_VLOG(1) << "frame1_size = " << frame1_size;
-  QUICHE_VLOG(1) << "frame2_size = " << frame2_size;
-
-  std::string input_buffer;
-  input_buffer.append(frame1.data(), frame1_size);
-  input_buffer.append(frame2.data(), frame2_size);
-
-  const char* buf = input_buffer.data();
-  const size_t buf_size = input_buffer.size();
-
-  QUICHE_VLOG(1) << "buf_size = " << buf_size;
-
-  size_t processed = deframer_->ProcessInput(buf, buf_size);
-  EXPECT_EQ(buf_size, processed);
-  EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
-  EXPECT_EQ(1, visitor->headers_frame_count_);
-  EXPECT_EQ(1, visitor->data_frame_count_);
-  EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_));
-}
-
-namespace {
-void CheckFrameAndIRSize(SpdyFrameIR* ir,
-                         SpdyFramer* framer,
-                         ArrayOutputBuffer* output_buffer) {
-  output_buffer->Reset();
-  SpdyFrameType type = ir->frame_type();
-  size_t ir_size = ir->size();
-  framer->SerializeFrame(*ir, output_buffer);
-  if (type == SpdyFrameType::HEADERS || type == SpdyFrameType::PUSH_PROMISE) {
-    // For HEADERS and PUSH_PROMISE, the size is an estimate.
-    EXPECT_GE(ir_size, output_buffer->Size() * 9 / 10);
-    EXPECT_LT(ir_size, output_buffer->Size() * 11 / 10);
-  } else {
-    EXPECT_EQ(ir_size, output_buffer->Size());
-  }
-}
-}  // namespace
-
-TEST_P(SpdyFramerTest, SpdyFrameIRSize) {
-  SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
-
-  const char bytes[] = "this is a very short data frame";
-  SpdyDataIR data_ir(1, absl::string_view(bytes, ABSL_ARRAYSIZE(bytes)));
-  CheckFrameAndIRSize(&data_ir, &framer, &output_);
-
-  SpdyRstStreamIR rst_ir(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
-  CheckFrameAndIRSize(&rst_ir, &framer, &output_);
-
-  SpdySettingsIR settings_ir;
-  settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
-  settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
-  settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
-  CheckFrameAndIRSize(&settings_ir, &framer, &output_);
-
-  SpdyPingIR ping_ir(42);
-  CheckFrameAndIRSize(&ping_ir, &framer, &output_);
-
-  SpdyGoAwayIR goaway_ir(97, ERROR_CODE_NO_ERROR, "Goaway description");
-  CheckFrameAndIRSize(&goaway_ir, &framer, &output_);
-
-  SpdyHeadersIR headers_ir(1);
-  headers_ir.SetHeader("alpha", "beta");
-  headers_ir.SetHeader("gamma", "charlie");
-  headers_ir.SetHeader("cookie", "key1=value1; key2=value2");
-  CheckFrameAndIRSize(&headers_ir, &framer, &output_);
-
-  SpdyHeadersIR headers_ir_with_continuation(1);
-  headers_ir_with_continuation.SetHeader("alpha", std::string(100000, 'x'));
-  headers_ir_with_continuation.SetHeader("beta", std::string(100000, 'x'));
-  headers_ir_with_continuation.SetHeader("cookie", "key1=value1; key2=value2");
-  CheckFrameAndIRSize(&headers_ir_with_continuation, &framer, &output_);
-
-  SpdyWindowUpdateIR window_update_ir(4, 1024);
-  CheckFrameAndIRSize(&window_update_ir, &framer, &output_);
-
-  SpdyPushPromiseIR push_promise_ir(3, 8);
-  push_promise_ir.SetHeader("alpha", std::string(100000, 'x'));
-  push_promise_ir.SetHeader("beta", std::string(100000, 'x'));
-  push_promise_ir.SetHeader("cookie", "key1=value1; key2=value2");
-  CheckFrameAndIRSize(&push_promise_ir, &framer, &output_);
-
-  SpdyAltSvcWireFormat::AlternativeService altsvc1(
-      "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
-  SpdyAltSvcWireFormat::AlternativeService altsvc2(
-      "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
-  altsvc_vector.push_back(altsvc1);
-  altsvc_vector.push_back(altsvc2);
-  SpdyAltSvcIR altsvc_ir(0);
-  altsvc_ir.set_origin("o_r|g!n");
-  altsvc_ir.add_altsvc(altsvc1);
-  altsvc_ir.add_altsvc(altsvc2);
-  CheckFrameAndIRSize(&altsvc_ir, &framer, &output_);
-
-  SpdyPriorityIR priority_ir(3, 1, 256, false);
-  CheckFrameAndIRSize(&priority_ir, &framer, &output_);
-
-  const char kDescription[] = "Unknown frame";
-  const uint8_t kType = 0xaf;
-  const uint8_t kFlags = 0x11;
-  SpdyUnknownIR unknown_ir(2, kType, kFlags, kDescription);
-  CheckFrameAndIRSize(&unknown_ir, &framer, &output_);
-}
-
-}  // namespace test
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_header_block.cc b/spdy/core/spdy_header_block.cc
deleted file mode 100644
index 2190c6b..0000000
--- a/spdy/core/spdy_header_block.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_header_block.h"
-
-#include <string.h>
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/strings/str_cat.h"
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-namespace {
-
-// By default, linked_hash_map's internal map allocates space for 100 map
-// buckets on construction, which is larger than necessary.  Standard library
-// unordered map implementations use a list of prime numbers to set the bucket
-// count for a particular capacity.  |kInitialMapBuckets| is chosen to reduce
-// memory usage for small header blocks, at the cost of having to rehash for
-// large header blocks.
-const size_t kInitialMapBuckets = 11;
-
-const char kCookieKey[] = "cookie";
-const char kNullSeparator = 0;
-
-absl::string_view SeparatorForKey(absl::string_view key) {
-  if (key == kCookieKey) {
-    static absl::string_view cookie_separator = "; ";
-    return cookie_separator;
-  } else {
-    return absl::string_view(&kNullSeparator, 1);
-  }
-}
-
-}  // namespace
-
-Http2HeaderBlock::HeaderValue::HeaderValue(SpdyHeaderStorage* storage,
-                                           absl::string_view key,
-                                           absl::string_view initial_value)
-    : storage_(storage),
-      fragments_({initial_value}),
-      pair_({key, {}}),
-      size_(initial_value.size()),
-      separator_size_(SeparatorForKey(key).size()) {}
-
-Http2HeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other)
-    : storage_(other.storage_),
-      fragments_(std::move(other.fragments_)),
-      pair_(std::move(other.pair_)),
-      size_(other.size_),
-      separator_size_(other.separator_size_) {}
-
-Http2HeaderBlock::HeaderValue& Http2HeaderBlock::HeaderValue::operator=(
-    HeaderValue&& other) {
-  storage_ = other.storage_;
-  fragments_ = std::move(other.fragments_);
-  pair_ = std::move(other.pair_);
-  size_ = other.size_;
-  separator_size_ = other.separator_size_;
-  return *this;
-}
-
-void Http2HeaderBlock::HeaderValue::set_storage(SpdyHeaderStorage* storage) {
-  storage_ = storage;
-}
-
-Http2HeaderBlock::HeaderValue::~HeaderValue() = default;
-
-absl::string_view Http2HeaderBlock::HeaderValue::ConsolidatedValue() const {
-  if (fragments_.empty()) {
-    return absl::string_view();
-  }
-  if (fragments_.size() > 1) {
-    fragments_ = {
-        storage_->WriteFragments(fragments_, SeparatorForKey(pair_.first))};
-  }
-  return fragments_[0];
-}
-
-void Http2HeaderBlock::HeaderValue::Append(absl::string_view fragment) {
-  size_ += (fragment.size() + separator_size_);
-  fragments_.push_back(fragment);
-}
-
-const std::pair<absl::string_view, absl::string_view>&
-Http2HeaderBlock::HeaderValue::as_pair() const {
-  pair_.second = ConsolidatedValue();
-  return pair_;
-}
-
-Http2HeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {}
-
-Http2HeaderBlock::iterator::iterator(const iterator& other) = default;
-
-Http2HeaderBlock::iterator::~iterator() = default;
-
-Http2HeaderBlock::ValueProxy::ValueProxy(
-    Http2HeaderBlock* block,
-    Http2HeaderBlock::MapType::iterator lookup_result,
-    const absl::string_view key,
-    size_t* spdy_header_block_value_size)
-    : block_(block),
-      lookup_result_(lookup_result),
-      key_(key),
-      spdy_header_block_value_size_(spdy_header_block_value_size),
-      valid_(true) {}
-
-Http2HeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other)
-    : block_(other.block_),
-      lookup_result_(other.lookup_result_),
-      key_(other.key_),
-      spdy_header_block_value_size_(other.spdy_header_block_value_size_),
-      valid_(true) {
-  other.valid_ = false;
-}
-
-Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=(
-    Http2HeaderBlock::ValueProxy&& other) {
-  block_ = other.block_;
-  lookup_result_ = other.lookup_result_;
-  key_ = other.key_;
-  valid_ = true;
-  other.valid_ = false;
-  spdy_header_block_value_size_ = other.spdy_header_block_value_size_;
-  return *this;
-}
-
-Http2HeaderBlock::ValueProxy::~ValueProxy() {
-  // If the ValueProxy is destroyed while lookup_result_ == block_->end(),
-  // the assignment operator was never used, and the block's SpdyHeaderStorage
-  // can reclaim the memory used by the key. This makes lookup-only access to
-  // Http2HeaderBlock through operator[] memory-neutral.
-  if (valid_ && lookup_result_ == block_->map_.end()) {
-    block_->storage_.Rewind(key_);
-  }
-}
-
-Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=(
-    absl::string_view value) {
-  *spdy_header_block_value_size_ += value.size();
-  SpdyHeaderStorage* storage = &block_->storage_;
-  if (lookup_result_ == block_->map_.end()) {
-    QUICHE_DVLOG(1) << "Inserting: (" << key_ << ", " << value << ")";
-    lookup_result_ =
-        block_->map_
-            .emplace(std::make_pair(
-                key_, HeaderValue(storage, key_, storage->Write(value))))
-            .first;
-  } else {
-    QUICHE_DVLOG(1) << "Updating key: " << key_ << " with value: " << value;
-    *spdy_header_block_value_size_ -= lookup_result_->second.SizeEstimate();
-    lookup_result_->second = HeaderValue(storage, key_, storage->Write(value));
-  }
-  return *this;
-}
-
-bool Http2HeaderBlock::ValueProxy::operator==(absl::string_view value) const {
-  if (lookup_result_ == block_->map_.end()) {
-    return false;
-  } else {
-    return value == lookup_result_->second.value();
-  }
-}
-
-std::string Http2HeaderBlock::ValueProxy::as_string() const {
-  if (lookup_result_ == block_->map_.end()) {
-    return "";
-  } else {
-    return std::string(lookup_result_->second.value());
-  }
-}
-
-Http2HeaderBlock::Http2HeaderBlock() : map_(kInitialMapBuckets) {}
-
-Http2HeaderBlock::Http2HeaderBlock(Http2HeaderBlock&& other)
-    : map_(kInitialMapBuckets) {
-  map_.swap(other.map_);
-  storage_ = std::move(other.storage_);
-  for (auto& p : map_) {
-    p.second.set_storage(&storage_);
-  }
-  key_size_ = other.key_size_;
-  value_size_ = other.value_size_;
-}
-
-Http2HeaderBlock::~Http2HeaderBlock() = default;
-
-Http2HeaderBlock& Http2HeaderBlock::operator=(Http2HeaderBlock&& other) {
-  map_.swap(other.map_);
-  storage_ = std::move(other.storage_);
-  for (auto& p : map_) {
-    p.second.set_storage(&storage_);
-  }
-  key_size_ = other.key_size_;
-  value_size_ = other.value_size_;
-  return *this;
-}
-
-Http2HeaderBlock Http2HeaderBlock::Clone() const {
-  Http2HeaderBlock copy;
-  for (const auto& p : *this) {
-    copy.AppendHeader(p.first, p.second);
-  }
-  return copy;
-}
-
-bool Http2HeaderBlock::operator==(const Http2HeaderBlock& other) const {
-  return size() == other.size() && std::equal(begin(), end(), other.begin());
-}
-
-bool Http2HeaderBlock::operator!=(const Http2HeaderBlock& other) const {
-  return !(operator==(other));
-}
-
-std::string Http2HeaderBlock::DebugString() const {
-  if (empty()) {
-    return "{}";
-  }
-
-  std::string output = "\n{\n";
-  for (auto it = begin(); it != end(); ++it) {
-    absl::StrAppend(&output, "  ", it->first, " ", it->second, "\n");
-  }
-  absl::StrAppend(&output, "}\n");
-  return output;
-}
-
-void Http2HeaderBlock::erase(absl::string_view key) {
-  auto iter = map_.find(key);
-  if (iter != map_.end()) {
-    QUICHE_DVLOG(1) << "Erasing header with name: " << key;
-    key_size_ -= key.size();
-    value_size_ -= iter->second.SizeEstimate();
-    map_.erase(iter);
-  }
-}
-
-void Http2HeaderBlock::clear() {
-  key_size_ = 0;
-  value_size_ = 0;
-  map_.clear();
-  storage_.Clear();
-}
-
-void Http2HeaderBlock::insert(const Http2HeaderBlock::value_type& value) {
-  // TODO(birenroy): Write new value in place of old value, if it fits.
-  value_size_ += value.second.size();
-
-  auto iter = map_.find(value.first);
-  if (iter == map_.end()) {
-    QUICHE_DVLOG(1) << "Inserting: (" << value.first << ", " << value.second
-                    << ")";
-    AppendHeader(value.first, value.second);
-  } else {
-    QUICHE_DVLOG(1) << "Updating key: " << iter->first
-                    << " with value: " << value.second;
-    value_size_ -= iter->second.SizeEstimate();
-    iter->second =
-        HeaderValue(&storage_, iter->first, storage_.Write(value.second));
-  }
-}
-
-Http2HeaderBlock::ValueProxy Http2HeaderBlock::operator[](
-    const absl::string_view key) {
-  QUICHE_DVLOG(2) << "Operator[] saw key: " << key;
-  absl::string_view out_key;
-  auto iter = map_.find(key);
-  if (iter == map_.end()) {
-    // We write the key first, to assure that the ValueProxy has a
-    // reference to a valid absl::string_view in its operator=.
-    out_key = WriteKey(key);
-    QUICHE_DVLOG(2) << "Key written as: " << std::hex
-                    << static_cast<const void*>(key.data()) << ", " << std::dec
-                    << key.size();
-  } else {
-    out_key = iter->first;
-  }
-  return ValueProxy(this, iter, out_key, &value_size_);
-}
-
-void Http2HeaderBlock::AppendValueOrAddHeader(const absl::string_view key,
-                                              const absl::string_view value) {
-  value_size_ += value.size();
-
-  auto iter = map_.find(key);
-  if (iter == map_.end()) {
-    QUICHE_DVLOG(1) << "Inserting: (" << key << ", " << value << ")";
-
-    AppendHeader(key, value);
-    return;
-  }
-  QUICHE_DVLOG(1) << "Updating key: " << iter->first
-                  << "; appending value: " << value;
-  value_size_ += SeparatorForKey(key).size();
-  iter->second.Append(storage_.Write(value));
-}
-
-void Http2HeaderBlock::AppendHeader(const absl::string_view key,
-                                    const absl::string_view value) {
-  auto backed_key = WriteKey(key);
-  map_.emplace(std::make_pair(
-      backed_key, HeaderValue(&storage_, backed_key, storage_.Write(value))));
-}
-
-absl::string_view Http2HeaderBlock::WriteKey(const absl::string_view key) {
-  key_size_ += key.size();
-  return storage_.Write(key);
-}
-
-size_t Http2HeaderBlock::bytes_allocated() const {
-  return storage_.bytes_allocated();
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_header_block.h b/spdy/core/spdy_header_block.h
deleted file mode 100644
index d409427..0000000
--- a/spdy/core/spdy_header_block.h
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
-#define QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
-
-#include <stddef.h>
-
-#include <functional>
-#include <list>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/attributes.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/quiche_linked_hash_map.h"
-#include "common/quiche_text_utils.h"
-#include "spdy/core/spdy_header_storage.h"
-
-namespace spdy {
-
-namespace test {
-class Http2HeaderBlockPeer;
-class ValueProxyPeer;
-}  // namespace test
-
-#ifndef SPDY_HEADER_DEBUG
-#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define SPDY_HEADER_DEBUG 1
-#else  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define SPDY_HEADER_DEBUG 0
-#endif  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#endif  // SPDY_HEADER_DEBUG
-
-// This class provides a key-value map that can be used to store SPDY header
-// names and values. This data structure preserves insertion order.
-//
-// Under the hood, this data structure uses large, contiguous blocks of memory
-// to store names and values. Lookups may be performed with absl::string_view
-// keys, and values are returned as absl::string_views (via ValueProxy, below).
-// Value absl::string_views are valid as long as the Http2HeaderBlock exists;
-// allocated memory is never freed until Http2HeaderBlock's destruction.
-//
-// This implementation does not make much of an effort to minimize wasted space.
-// It's expected that keys are rarely deleted from a Http2HeaderBlock.
-class QUICHE_EXPORT_PRIVATE Http2HeaderBlock {
- private:
-  // Stores a list of value fragments that can be joined later with a
-  // key-dependent separator.
-  class QUICHE_EXPORT_PRIVATE HeaderValue {
-   public:
-    HeaderValue(SpdyHeaderStorage* storage,
-                absl::string_view key,
-                absl::string_view initial_value);
-
-    // Moves are allowed.
-    HeaderValue(HeaderValue&& other);
-    HeaderValue& operator=(HeaderValue&& other);
-
-    void set_storage(SpdyHeaderStorage* storage);
-
-    // Copies are not.
-    HeaderValue(const HeaderValue& other) = delete;
-    HeaderValue& operator=(const HeaderValue& other) = delete;
-
-    ~HeaderValue();
-
-    // Consumes at most |fragment.size()| bytes of memory.
-    void Append(absl::string_view fragment);
-
-    absl::string_view value() const { return as_pair().second; }
-    const std::pair<absl::string_view, absl::string_view>& as_pair() const;
-
-    // Size estimate including separators. Used when keys are erased from
-    // Http2HeaderBlock.
-    size_t SizeEstimate() const { return size_; }
-
-   private:
-    // May allocate a large contiguous region of memory to hold the concatenated
-    // fragments and separators.
-    absl::string_view ConsolidatedValue() const;
-
-    mutable SpdyHeaderStorage* storage_;
-    mutable std::vector<absl::string_view> fragments_;
-    // The first element is the key; the second is the consolidated value.
-    mutable std::pair<absl::string_view, absl::string_view> pair_;
-    size_t size_ = 0;
-    size_t separator_size_ = 0;
-  };
-
-  typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
-                                      quiche::StringPieceCaseHash,
-                                      quiche::StringPieceCaseEqual>
-      MapType;
-
- public:
-  typedef std::pair<absl::string_view, absl::string_view> value_type;
-
-  // Provides iteration over a sequence of std::pair<absl::string_view,
-  // absl::string_view>, even though the underlying MapType::value_type is
-  // different. Dereferencing the iterator will result in memory allocation for
-  // multi-value headers.
-  class QUICHE_EXPORT_PRIVATE iterator {
-   public:
-    // The following type definitions fulfill the requirements for iterator
-    // implementations.
-    typedef std::pair<absl::string_view, absl::string_view> value_type;
-    typedef value_type& reference;
-    typedef value_type* pointer;
-    typedef std::forward_iterator_tag iterator_category;
-    typedef MapType::iterator::difference_type difference_type;
-
-    // In practice, this iterator only offers access to const value_type.
-    typedef const value_type& const_reference;
-    typedef const value_type* const_pointer;
-
-    explicit iterator(MapType::const_iterator it);
-    iterator(const iterator& other);
-    ~iterator();
-
-    // This will result in memory allocation if the value consists of multiple
-    // fragments.
-    const_reference operator*() const {
-#if SPDY_HEADER_DEBUG
-      QUICHE_CHECK(!dereference_forbidden_);
-#endif  // SPDY_HEADER_DEBUG
-      return it_->second.as_pair();
-    }
-
-    const_pointer operator->() const { return &(this->operator*()); }
-    bool operator==(const iterator& it) const { return it_ == it.it_; }
-    bool operator!=(const iterator& it) const { return !(*this == it); }
-
-    iterator& operator++() {
-      it_++;
-      return *this;
-    }
-
-    iterator operator++(int) {
-      auto ret = *this;
-      this->operator++();
-      return ret;
-    }
-
-#if SPDY_HEADER_DEBUG
-    void forbid_dereference() { dereference_forbidden_ = true; }
-#endif  // SPDY_HEADER_DEBUG
-
-   private:
-    MapType::const_iterator it_;
-#if SPDY_HEADER_DEBUG
-    bool dereference_forbidden_ = false;
-#endif  // SPDY_HEADER_DEBUG
-  };
-  typedef iterator const_iterator;
-
-  Http2HeaderBlock();
-  Http2HeaderBlock(const Http2HeaderBlock& other) = delete;
-  Http2HeaderBlock(Http2HeaderBlock&& other);
-  ~Http2HeaderBlock();
-
-  Http2HeaderBlock& operator=(const Http2HeaderBlock& other) = delete;
-  Http2HeaderBlock& operator=(Http2HeaderBlock&& other);
-  Http2HeaderBlock Clone() const;
-
-  bool operator==(const Http2HeaderBlock& other) const;
-  bool operator!=(const Http2HeaderBlock& other) const;
-
-  // Provides a human readable multi-line representation of the stored header
-  // keys and values.
-  std::string DebugString() const;
-
-  iterator begin() { return wrap_iterator(map_.begin()); }
-  iterator end() { return wrap_iterator(map_.end()); }
-  const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
-  const_iterator end() const { return wrap_const_iterator(map_.end()); }
-  bool empty() const { return map_.empty(); }
-  size_t size() const { return map_.size(); }
-  iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
-  const_iterator find(absl::string_view key) const {
-    return wrap_const_iterator(map_.find(key));
-  }
-  bool contains(absl::string_view key) const { return find(key) != end(); }
-  void erase(absl::string_view key);
-
-  // Clears both our MapType member and the memory used to hold headers.
-  void clear();
-
-  // The next few methods copy data into our backing storage.
-
-  // If key already exists in the block, replaces the value of that key. Else
-  // adds a new header to the end of the block.
-  void insert(const value_type& value);
-
-  // If a header with the key is already present, then append the value to the
-  // existing header value, NUL ("\0") separated unless the key is cookie, in
-  // which case the separator is "; ".
-  // If there is no such key, a new header with the key and value is added.
-  void AppendValueOrAddHeader(const absl::string_view key,
-                              const absl::string_view value);
-
-  // This object provides automatic conversions that allow Http2HeaderBlock to
-  // be nearly a drop-in replacement for
-  // SpdyLinkedHashMap<std::string, std::string>.
-  // It reads data from or writes data to a SpdyHeaderStorage.
-  class QUICHE_EXPORT_PRIVATE ValueProxy {
-   public:
-    ~ValueProxy();
-
-    // Moves are allowed.
-    ValueProxy(ValueProxy&& other);
-    ValueProxy& operator=(ValueProxy&& other);
-
-    // Copies are not.
-    ValueProxy(const ValueProxy& other) = delete;
-    ValueProxy& operator=(const ValueProxy& other) = delete;
-
-    // Assignment modifies the underlying Http2HeaderBlock.
-    ValueProxy& operator=(absl::string_view value);
-
-    // Provides easy comparison against absl::string_view.
-    bool operator==(absl::string_view value) const;
-
-    std::string as_string() const;
-
-   private:
-    friend class Http2HeaderBlock;
-    friend class test::ValueProxyPeer;
-
-    ValueProxy(Http2HeaderBlock* block,
-               Http2HeaderBlock::MapType::iterator lookup_result,
-               const absl::string_view key,
-               size_t* spdy_header_block_value_size);
-
-    Http2HeaderBlock* block_;
-    Http2HeaderBlock::MapType::iterator lookup_result_;
-    absl::string_view key_;
-    size_t* spdy_header_block_value_size_;
-    bool valid_;
-  };
-
-  // Allows either lookup or mutation of the value associated with a key.
-  ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);
-
-  size_t TotalBytesUsed() const { return key_size_ + value_size_; }
-
- private:
-  friend class test::Http2HeaderBlockPeer;
-
-  inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
-#if SPDY_HEADER_DEBUG
-    iterator outer_iterator(inner_iterator);
-    if (inner_iterator == map_.end()) {
-      outer_iterator.forbid_dereference();
-    }
-    return outer_iterator;
-#else  // SPDY_HEADER_DEBUG
-    return iterator(inner_iterator);
-#endif  // SPDY_HEADER_DEBUG
-  }
-
-  inline const_iterator wrap_const_iterator(
-      MapType::const_iterator inner_iterator) const {
-#if SPDY_HEADER_DEBUG
-    const_iterator outer_iterator(inner_iterator);
-    if (inner_iterator == map_.end()) {
-      outer_iterator.forbid_dereference();
-    }
-    return outer_iterator;
-#else  // SPDY_HEADER_DEBUG
-    return iterator(inner_iterator);
-#endif  // SPDY_HEADER_DEBUG
-  }
-
-  void AppendHeader(const absl::string_view key, const absl::string_view value);
-  absl::string_view WriteKey(const absl::string_view key);
-  size_t bytes_allocated() const;
-
-  // absl::string_views held by |map_| point to memory owned by |storage_|.
-  MapType map_;
-  SpdyHeaderStorage storage_;
-
-  size_t key_size_ = 0;
-  size_t value_size_ = 0;
-};
-
-// TODO(b/156770486): Remove this alias when the rename is complete.
-using SpdyHeaderBlock = Http2HeaderBlock;
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
diff --git a/spdy/core/spdy_header_block_test.cc b/spdy/core/spdy_header_block_test.cc
deleted file mode 100644
index 0767dc9..0000000
--- a/spdy/core/spdy_header_block_test.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_header_block.h"
-
-#include <memory>
-#include <utility>
-
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/spdy_test_utils.h"
-
-using ::testing::ElementsAre;
-
-namespace spdy {
-namespace test {
-
-class ValueProxyPeer {
- public:
-  static absl::string_view key(Http2HeaderBlock::ValueProxy* p) {
-    return p->key_;
-  }
-};
-
-std::pair<absl::string_view, absl::string_view> Pair(absl::string_view k,
-                                                     absl::string_view v) {
-  return std::make_pair(k, v);
-}
-
-// This test verifies that Http2HeaderBlock behaves correctly when empty.
-TEST(Http2HeaderBlockTest, EmptyBlock) {
-  Http2HeaderBlock block;
-  EXPECT_TRUE(block.empty());
-  EXPECT_EQ(0u, block.size());
-  EXPECT_EQ(block.end(), block.find("foo"));
-  EXPECT_FALSE(block.contains("foo"));
-  EXPECT_TRUE(block.end() == block.begin());
-
-  // Should have no effect.
-  block.erase("bar");
-}
-
-TEST(Http2HeaderBlockTest, KeyMemoryReclaimedOnLookup) {
-  Http2HeaderBlock block;
-  absl::string_view copied_key1;
-  {
-    auto proxy1 = block["some key name"];
-    copied_key1 = ValueProxyPeer::key(&proxy1);
-  }
-  absl::string_view copied_key2;
-  {
-    auto proxy2 = block["some other key name"];
-    copied_key2 = ValueProxyPeer::key(&proxy2);
-  }
-  // Because proxy1 was never used to modify the block, the memory used for the
-  // key could be reclaimed and used for the second call to operator[].
-  // Therefore, we expect the pointers of the two absl::string_views to be
-  // equal.
-  EXPECT_EQ(copied_key1.data(), copied_key2.data());
-
-  {
-    auto proxy1 = block["some key name"];
-    block["some other key name"] = "some value";
-  }
-  // Nothing should blow up when proxy1 is destructed, and we should be able to
-  // modify and access the Http2HeaderBlock.
-  block["key"] = "value";
-  EXPECT_EQ("value", block["key"]);
-  EXPECT_EQ("some value", block["some other key name"]);
-  EXPECT_TRUE(block.find("some key name") == block.end());
-}
-
-// This test verifies that headers can be set in a variety of ways.
-TEST(Http2HeaderBlockTest, AddHeaders) {
-  Http2HeaderBlock block;
-  block["foo"] = std::string(300, 'x');
-  block["bar"] = "baz";
-  block["qux"] = "qux1";
-  block["qux"] = "qux2";
-  block.insert(std::make_pair("key", "value"));
-
-  EXPECT_EQ(Pair("foo", std::string(300, 'x')), *block.find("foo"));
-  EXPECT_EQ("baz", block["bar"]);
-  std::string qux("qux");
-  EXPECT_EQ("qux2", block[qux]);
-  ASSERT_NE(block.end(), block.find("key"));
-  ASSERT_TRUE(block.contains("key"));
-  EXPECT_EQ(Pair("key", "value"), *block.find("key"));
-
-  block.erase("key");
-  EXPECT_EQ(block.end(), block.find("key"));
-}
-
-// This test verifies that Http2HeaderBlock can be copied using Clone().
-TEST(Http2HeaderBlockTest, CopyBlocks) {
-  Http2HeaderBlock block1;
-  block1["foo"] = std::string(300, 'x');
-  block1["bar"] = "baz";
-  block1.insert(std::make_pair("qux", "qux1"));
-
-  Http2HeaderBlock block2 = block1.Clone();
-  Http2HeaderBlock block3(block1.Clone());
-
-  EXPECT_EQ(block1, block2);
-  EXPECT_EQ(block1, block3);
-}
-
-TEST(Http2HeaderBlockTest, Equality) {
-  // Test equality and inequality operators.
-  Http2HeaderBlock block1;
-  block1["foo"] = "bar";
-
-  Http2HeaderBlock block2;
-  block2["foo"] = "bar";
-
-  Http2HeaderBlock block3;
-  block3["baz"] = "qux";
-
-  EXPECT_EQ(block1, block2);
-  EXPECT_NE(block1, block3);
-
-  block2["baz"] = "qux";
-  EXPECT_NE(block1, block2);
-}
-
-Http2HeaderBlock ReturnTestHeaderBlock() {
-  Http2HeaderBlock block;
-  block["foo"] = "bar";
-  block.insert(std::make_pair("foo2", "baz"));
-  return block;
-}
-
-// Test that certain methods do not crash on moved-from instances.
-TEST(Http2HeaderBlockTest, MovedFromIsValid) {
-  Http2HeaderBlock block1;
-  block1["foo"] = "bar";
-
-  Http2HeaderBlock block2(std::move(block1));
-  EXPECT_THAT(block2, ElementsAre(Pair("foo", "bar")));
-
-  block1["baz"] = "qux";  // NOLINT  testing post-move behavior
-
-  Http2HeaderBlock block3(std::move(block1));
-
-  block1["foo"] = "bar";  // NOLINT  testing post-move behavior
-
-  Http2HeaderBlock block4(std::move(block1));
-
-  block1.clear();  // NOLINT  testing post-move behavior
-  EXPECT_TRUE(block1.empty());
-
-  block1["foo"] = "bar";
-  EXPECT_THAT(block1, ElementsAre(Pair("foo", "bar")));
-
-  Http2HeaderBlock block5 = ReturnTestHeaderBlock();
-  block5.AppendValueOrAddHeader("foo", "bar2");
-  EXPECT_THAT(block5, ElementsAre(Pair("foo", std::string("bar\0bar2", 8)),
-                                  Pair("foo2", "baz")));
-}
-
-// This test verifies that headers can be appended to no matter how they were
-// added originally.
-TEST(Http2HeaderBlockTest, AppendHeaders) {
-  Http2HeaderBlock block;
-  block["foo"] = "foo";
-  block.AppendValueOrAddHeader("foo", "bar");
-  EXPECT_EQ(Pair("foo", std::string("foo\0bar", 7)), *block.find("foo"));
-
-  block.insert(std::make_pair("foo", "baz"));
-  EXPECT_EQ("baz", block["foo"]);
-  EXPECT_EQ(Pair("foo", "baz"), *block.find("foo"));
-
-  // Try all four methods of adding an entry.
-  block["cookie"] = "key1=value1";
-  block.AppendValueOrAddHeader("h1", "h1v1");
-  block.insert(std::make_pair("h2", "h2v1"));
-
-  block.AppendValueOrAddHeader("h3", "h3v2");
-  block.AppendValueOrAddHeader("h2", "h2v2");
-  block.AppendValueOrAddHeader("h1", "h1v2");
-  block.AppendValueOrAddHeader("cookie", "key2=value2");
-
-  block.AppendValueOrAddHeader("cookie", "key3=value3");
-  block.AppendValueOrAddHeader("h1", "h1v3");
-  block.AppendValueOrAddHeader("h2", "h2v3");
-  block.AppendValueOrAddHeader("h3", "h3v3");
-  block.AppendValueOrAddHeader("h4", "singleton");
-
-  EXPECT_EQ("key1=value1; key2=value2; key3=value3", block["cookie"]);
-  EXPECT_EQ("baz", block["foo"]);
-  EXPECT_EQ(std::string("h1v1\0h1v2\0h1v3", 14), block["h1"]);
-  EXPECT_EQ(std::string("h2v1\0h2v2\0h2v3", 14), block["h2"]);
-  EXPECT_EQ(std::string("h3v2\0h3v3", 9), block["h3"]);
-  EXPECT_EQ("singleton", block["h4"]);
-}
-
-TEST(Http2HeaderBlockTest, CompareValueToStringPiece) {
-  Http2HeaderBlock block;
-  block["foo"] = "foo";
-  block.AppendValueOrAddHeader("foo", "bar");
-  const auto& val = block["foo"];
-  const char expected[] = "foo\0bar";
-  EXPECT_TRUE(absl::string_view(expected, 7) == val);
-  EXPECT_TRUE(val == absl::string_view(expected, 7));
-  EXPECT_FALSE(absl::string_view(expected, 3) == val);
-  EXPECT_FALSE(val == absl::string_view(expected, 3));
-  const char not_expected[] = "foo\0barextra";
-  EXPECT_FALSE(absl::string_view(not_expected, 12) == val);
-  EXPECT_FALSE(val == absl::string_view(not_expected, 12));
-
-  const auto& val2 = block["foo2"];
-  EXPECT_FALSE(absl::string_view(expected, 7) == val2);
-  EXPECT_FALSE(val2 == absl::string_view(expected, 7));
-  EXPECT_FALSE(absl::string_view("") == val2);
-  EXPECT_FALSE(val2 == absl::string_view(""));
-}
-
-// This test demonstrates that the Http2HeaderBlock data structure does not
-// place any limitations on the characters present in the header names.
-TEST(Http2HeaderBlockTest, UpperCaseNames) {
-  Http2HeaderBlock block;
-  block["Foo"] = "foo";
-  block.AppendValueOrAddHeader("Foo", "bar");
-  EXPECT_NE(block.end(), block.find("foo"));
-  EXPECT_EQ(Pair("Foo", std::string("foo\0bar", 7)), *block.find("Foo"));
-
-  // The map is case insensitive, so updating "foo" modifies the entry
-  // previously added.
-  block.AppendValueOrAddHeader("foo", "baz");
-  EXPECT_THAT(block,
-              ElementsAre(Pair("Foo", std::string("foo\0bar\0baz", 11))));
-}
-
-namespace {
-size_t Http2HeaderBlockSize(const Http2HeaderBlock& block) {
-  size_t size = 0;
-  for (const auto& pair : block) {
-    size += pair.first.size() + pair.second.size();
-  }
-  return size;
-}
-}  // namespace
-
-// Tests Http2HeaderBlock SizeEstimate().
-TEST(Http2HeaderBlockTest, TotalBytesUsed) {
-  Http2HeaderBlock block;
-  const size_t value_size = 300;
-  block["foo"] = std::string(value_size, 'x');
-  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
-  block.insert(std::make_pair("key", std::string(value_size, 'x')));
-  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
-  block.AppendValueOrAddHeader("abc", std::string(value_size, 'x'));
-  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
-
-  // Replace value for existing key.
-  block["foo"] = std::string(value_size, 'x');
-  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
-  block.insert(std::make_pair("key", std::string(value_size, 'x')));
-  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
-  // Add value for existing key.
-  block.AppendValueOrAddHeader("abc", std::string(value_size, 'x'));
-  EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
-
-  // Copies/clones Http2HeaderBlock.
-  size_t block_size = block.TotalBytesUsed();
-  Http2HeaderBlock block_copy = std::move(block);
-  EXPECT_EQ(block_size, block_copy.TotalBytesUsed());
-
-  // Erases key.
-  block_copy.erase("foo");
-  EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
-  block_copy.erase("key");
-  EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
-  block_copy.erase("abc");
-  EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_header_storage.cc b/spdy/core/spdy_header_storage.cc
deleted file mode 100644
index e995905..0000000
--- a/spdy/core/spdy_header_storage.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "spdy/core/spdy_header_storage.h"
-
-#include <cstring>
-
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-namespace {
-
-// SpdyHeaderStorage allocates blocks of this size by default.
-const size_t kDefaultStorageBlockSize = 2048;
-
-}  // namespace
-
-SpdyHeaderStorage::SpdyHeaderStorage() : arena_(kDefaultStorageBlockSize) {}
-
-absl::string_view SpdyHeaderStorage::Write(const absl::string_view s) {
-  return absl::string_view(arena_.Memdup(s.data(), s.size()), s.size());
-}
-
-void SpdyHeaderStorage::Rewind(const absl::string_view s) {
-  arena_.Free(const_cast<char*>(s.data()), s.size());
-}
-
-absl::string_view SpdyHeaderStorage::WriteFragments(
-    const std::vector<absl::string_view>& fragments,
-    absl::string_view separator) {
-  if (fragments.empty()) {
-    return absl::string_view();
-  }
-  size_t total_size = separator.size() * (fragments.size() - 1);
-  for (const absl::string_view& fragment : fragments) {
-    total_size += fragment.size();
-  }
-  char* dst = arena_.Alloc(total_size);
-  size_t written = Join(dst, fragments, separator);
-  QUICHE_DCHECK_EQ(written, total_size);
-  return absl::string_view(dst, total_size);
-}
-
-size_t Join(char* dst,
-            const std::vector<absl::string_view>& fragments,
-            absl::string_view separator) {
-  if (fragments.empty()) {
-    return 0;
-  }
-  auto* original_dst = dst;
-  auto it = fragments.begin();
-  memcpy(dst, it->data(), it->size());
-  dst += it->size();
-  for (++it; it != fragments.end(); ++it) {
-    memcpy(dst, separator.data(), separator.size());
-    dst += separator.size();
-    memcpy(dst, it->data(), it->size());
-    dst += it->size();
-  }
-  return dst - original_dst;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_header_storage.h b/spdy/core/spdy_header_storage.h
deleted file mode 100644
index 54267db..0000000
--- a/spdy/core/spdy_header_storage.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_
-#define QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_simple_arena.h"
-
-namespace spdy {
-
-// This class provides a backing store for absl::string_views. It previously
-// used custom allocation logic, but now uses an UnsafeArena instead. It has the
-// property that absl::string_views that refer to data in SpdyHeaderStorage are
-// never invalidated until the SpdyHeaderStorage is deleted or Clear() is
-// called.
-//
-// Write operations always append to the last block. If there is not enough
-// space to perform the write, a new block is allocated, and any unused space
-// is wasted.
-class QUICHE_EXPORT_PRIVATE SpdyHeaderStorage {
- public:
-  SpdyHeaderStorage();
-
-  SpdyHeaderStorage(const SpdyHeaderStorage&) = delete;
-  SpdyHeaderStorage& operator=(const SpdyHeaderStorage&) = delete;
-
-  SpdyHeaderStorage(SpdyHeaderStorage&& other) = default;
-  SpdyHeaderStorage& operator=(SpdyHeaderStorage&& other) = default;
-
-  absl::string_view Write(absl::string_view s);
-
-  // If |s| points to the most recent allocation from arena_, the arena will
-  // reclaim the memory. Otherwise, this method is a no-op.
-  void Rewind(absl::string_view s);
-
-  void Clear() { arena_.Reset(); }
-
-  // Given a list of fragments and a separator, writes the fragments joined by
-  // the separator to a contiguous region of memory. Returns a absl::string_view
-  // pointing to the region of memory.
-  absl::string_view WriteFragments(
-      const std::vector<absl::string_view>& fragments,
-      absl::string_view separator);
-
-  size_t bytes_allocated() const { return arena_.status().bytes_allocated(); }
-
- private:
-  SpdySimpleArena arena_;
-};
-
-// Writes |fragments| to |dst|, joined by |separator|. |dst| must be large
-// enough to hold the result. Returns the number of bytes written.
-QUICHE_EXPORT_PRIVATE size_t
-Join(char* dst,
-     const std::vector<absl::string_view>& fragments,
-     absl::string_view separator);
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_HEADER_STORAGE_H_
diff --git a/spdy/core/spdy_header_storage_test.cc b/spdy/core/spdy_header_storage_test.cc
deleted file mode 100644
index 698a1ed..0000000
--- a/spdy/core/spdy_header_storage_test.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "spdy/core/spdy_header_storage.h"
-
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-namespace test {
-
-TEST(JoinTest, JoinEmpty) {
-  std::vector<absl::string_view> empty;
-  absl::string_view separator = ", ";
-  char buf[10] = "";
-  size_t written = Join(buf, empty, separator);
-  EXPECT_EQ(0u, written);
-}
-
-TEST(JoinTest, JoinOne) {
-  std::vector<absl::string_view> v = {"one"};
-  absl::string_view separator = ", ";
-  char buf[15];
-  size_t written = Join(buf, v, separator);
-  EXPECT_EQ(3u, written);
-  EXPECT_EQ("one", absl::string_view(buf, written));
-}
-
-TEST(JoinTest, JoinMultiple) {
-  std::vector<absl::string_view> v = {"one", "two", "three"};
-  absl::string_view separator = ", ";
-  char buf[15];
-  size_t written = Join(buf, v, separator);
-  EXPECT_EQ(15u, written);
-  EXPECT_EQ("one, two, three", absl::string_view(buf, written));
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_headers_handler_interface.h b/spdy/core/spdy_headers_handler_interface.h
deleted file mode 100644
index ea2614b..0000000
--- a/spdy/core/spdy_headers_handler_interface.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
-#define QUICHE_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
-
-#include <stddef.h>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace spdy {
-
-// This interface defines how an object that accepts header data should behave.
-// It is used by both SpdyHeadersBlockParser and HpackDecoder.
-class QUICHE_EXPORT_PRIVATE SpdyHeadersHandlerInterface {
- public:
-  virtual ~SpdyHeadersHandlerInterface() {}
-
-  // A callback method which notifies when the parser starts handling a new
-  // header block. Will only be called once per block, even if it extends into
-  // CONTINUATION frames.
-  virtual void OnHeaderBlockStart() = 0;
-
-  // A callback method which notifies on a header key value pair. Multiple
-  // values for a given key will be emitted as multiple calls to OnHeader.
-  virtual void OnHeader(absl::string_view key, absl::string_view value) = 0;
-
-  // A callback method which notifies when the parser finishes handling a
-  // header block (i.e. the containing frame has the END_HEADERS flag set).
-  // Also indicates the total number of bytes in this block.
-  virtual void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
-                                size_t compressed_header_bytes) = 0;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
diff --git a/spdy/core/spdy_intrusive_list_test.cc b/spdy/core/spdy_intrusive_list_test.cc
deleted file mode 100644
index c09e178..0000000
--- a/spdy/core/spdy_intrusive_list_test.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_intrusive_list.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <list>
-#include <string>
-#include <utility>
-
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-namespace test {
-
-struct ListId2 {};
-
-struct TestItem : public SpdyIntrusiveLink<TestItem>,
-                  public SpdyIntrusiveLink<TestItem, ListId2> {
-  int n;
-};
-typedef SpdyIntrusiveList<TestItem> TestList;
-typedef std::list<TestItem*> CanonicalList;
-
-void swap(TestItem &a, TestItem &b) {
-  using std::swap;
-  swap(a.n, b.n);
-}
-
-class IntrusiveListTest : public QuicheTest {
- protected:
-  void CheckLists() {
-    CheckLists(l1, ll1);
-    if (QuicheTest::HasFailure())
-      return;
-    CheckLists(l2, ll2);
-  }
-
-  void CheckLists(const TestList &list_a, const CanonicalList &list_b) {
-    ASSERT_EQ(list_a.size(), list_b.size());
-    TestList::const_iterator it_a = list_a.begin();
-    CanonicalList::const_iterator it_b = list_b.begin();
-    while (it_a != list_a.end()) {
-      EXPECT_EQ(&*it_a++, *it_b++);
-    }
-    EXPECT_EQ(list_a.end(), it_a);
-    EXPECT_EQ(list_b.end(), it_b);
-  }
-
-  void PrepareLists(int num_elems_1, int num_elems_2 = 0) {
-    FillLists(&l1, &ll1, e, num_elems_1);
-    FillLists(&l2, &ll2, e + num_elems_1, num_elems_2);
-  }
-
-  void FillLists(TestList *list_a, CanonicalList *list_b, TestItem *elems,
-                 int num_elems) {
-    list_a->clear();
-    list_b->clear();
-    for (int i = 0; i < num_elems; ++i) {
-      list_a->push_back(elems + i);
-      list_b->push_back(elems + i);
-    }
-    CheckLists(*list_a, *list_b);
-  }
-
-  TestItem e[10];
-  TestList l1, l2;
-  CanonicalList ll1, ll2;
-};
-
-TEST(NewIntrusiveListTest, Basic) {
-  TestList list1;
-
-  EXPECT_EQ(sizeof(SpdyIntrusiveLink<TestItem>), sizeof(void*) * 2);
-
-  for (int i = 0; i < 10; ++i) {
-    TestItem *e = new TestItem;
-    e->n = i;
-    list1.push_front(e);
-  }
-  EXPECT_EQ(list1.size(), 10u);
-
-  // Verify we can reverse a list because we defined swap for TestItem.
-  std::reverse(list1.begin(), list1.end());
-  EXPECT_EQ(list1.size(), 10u);
-
-  // Check both const and non-const forward iteration.
-  const TestList& clist1 = list1;
-  int i = 0;
-  TestList::iterator iter = list1.begin();
-  for (;
-       iter != list1.end();
-       ++iter, ++i) {
-    EXPECT_EQ(iter->n, i);
-  }
-  EXPECT_EQ(iter, clist1.end());
-  EXPECT_NE(iter, clist1.begin());
-  i = 0;
-  iter = list1.begin();
-  for (;
-       iter != list1.end();
-       ++iter, ++i) {
-    EXPECT_EQ(iter->n, i);
-  }
-  EXPECT_EQ(iter, clist1.end());
-  EXPECT_NE(iter, clist1.begin());
-
-  EXPECT_EQ(list1.front().n, 0);
-  EXPECT_EQ(list1.back().n, 9);
-
-  // Verify we can swap 2 lists.
-  TestList list2;
-  list2.swap(list1);
-  EXPECT_EQ(list1.size(), 0u);
-  EXPECT_EQ(list2.size(), 10u);
-
-  // Check both const and non-const reverse iteration.
-  const TestList& clist2 = list2;
-  TestList::reverse_iterator riter = list2.rbegin();
-  i = 9;
-  for (;
-       riter != list2.rend();
-       ++riter, --i) {
-    EXPECT_EQ(riter->n, i);
-  }
-  EXPECT_EQ(riter, clist2.rend());
-  EXPECT_NE(riter, clist2.rbegin());
-
-  riter = list2.rbegin();
-  i = 9;
-  for (;
-       riter != list2.rend();
-       ++riter, --i) {
-    EXPECT_EQ(riter->n, i);
-  }
-  EXPECT_EQ(riter, clist2.rend());
-  EXPECT_NE(riter, clist2.rbegin());
-
-  while (!list2.empty()) {
-    TestItem *e = &list2.front();
-    list2.pop_front();
-    delete e;
-  }
-}
-
-TEST(NewIntrusiveListTest, Erase) {
-  TestList l;
-  TestItem *e[10];
-
-  // Create a list with 10 items.
-  for (int i = 0; i < 10; ++i) {
-    e[i] = new TestItem;
-    l.push_front(e[i]);
-  }
-
-  // Test that erase works.
-  for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(l.size(), (10u - i));
-
-    TestList::iterator iter = l.erase(e[i]);
-    EXPECT_NE(iter, TestList::iterator(e[i]));
-
-    EXPECT_EQ(l.size(), (10u - i - 1));
-    delete e[i];
-  }
-}
-
-TEST(NewIntrusiveListTest, Insert) {
-  TestList l;
-  TestList::iterator iter = l.end();
-  TestItem *e[10];
-
-  // Create a list with 10 items.
-  for (int i = 9; i >= 0; --i) {
-    e[i] = new TestItem;
-    iter = l.insert(iter, e[i]);
-    EXPECT_EQ(&(*iter), e[i]);
-  }
-
-  EXPECT_EQ(l.size(), 10u);
-
-  // Verify insertion order.
-  iter = l.begin();
-  for (TestItem *item : e) {
-    EXPECT_EQ(&(*iter), item);
-    iter = l.erase(item);
-    delete item;
-  }
-}
-
-TEST(NewIntrusiveListTest, Move) {
-  // Move contructible.
-
-  {  // Move-construct from an empty list.
-    TestList src;
-    TestList dest(std::move(src));
-    EXPECT_TRUE(dest.empty());
-  }
-
-  {  // Move-construct from a single item list.
-    TestItem e;
-    TestList src;
-    src.push_front(&e);
-
-    TestList dest(std::move(src));
-    EXPECT_TRUE(src.empty());  // NOLINT bugprone-use-after-move
-    ASSERT_THAT(dest.size(), 1);
-    EXPECT_THAT(&dest.front(), &e);
-    EXPECT_THAT(&dest.back(), &e);
-  }
-
-  {  // Move-construct from a list with multiple items.
-    TestItem items[10];
-    TestList src;
-    for (TestItem &e : items) src.push_back(&e);
-
-    TestList dest(std::move(src));
-    EXPECT_TRUE(src.empty());  // NOLINT bugprone-use-after-move
-    // Verify the items on the destination list.
-    ASSERT_THAT(dest.size(), 10);
-    int i = 0;
-    for (TestItem &e : dest) {
-      EXPECT_THAT(&e, &items[i++]) << " for index " << i;
-    }
-  }
-}
-
-TEST(NewIntrusiveListTest, StaticInsertErase) {
-  TestList l;
-  TestItem e[2];
-  TestList::iterator i = l.begin();
-  TestList::insert(i, &e[0]);
-  TestList::insert(&e[0], &e[1]);
-  TestList::erase(&e[0]);
-  TestList::erase(TestList::iterator(&e[1]));
-  EXPECT_TRUE(l.empty());
-}
-
-TEST_F(IntrusiveListTest, Splice) {
-  // We verify that the contents of this secondary list aren't affected by any
-  // of the splices.
-  SpdyIntrusiveList<TestItem, ListId2> secondary_list;
-  for (int i  = 0; i < 3; ++i) {
-    secondary_list.push_back(&e[i]);
-  }
-
-  // Test the basic cases:
-  // - The lists range from 0 to 2 elements.
-  // - The insertion point ranges from begin() to end()
-  // - The transfered range has multiple sizes and locations in the source.
-  for (int l1_count = 0; l1_count < 3; ++l1_count) {
-    for (int l2_count = 0; l2_count < 3; ++l2_count) {
-      for (int pos = 0; pos <= l1_count; ++pos) {
-        for (int first = 0; first <= l2_count; ++first) {
-          for (int last = first; last <= l2_count; ++last) {
-            PrepareLists(l1_count, l2_count);
-
-            l1.splice(std::next(l1.begin(), pos), std::next(l2.begin(), first),
-                      std::next(l2.begin(), last));
-            ll1.splice(std::next(ll1.begin(), pos), ll2,
-                       std::next(ll2.begin(), first),
-                       std::next(ll2.begin(), last));
-
-            CheckLists();
-
-            ASSERT_EQ(3u, secondary_list.size());
-            for (int i = 0; i < 3; ++i) {
-              EXPECT_EQ(&e[i], &*std::next(secondary_list.begin(), i));
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-// Build up a set of classes which form "challenging" type hierarchies to use
-// with an SpdyIntrusiveList.
-struct BaseLinkId {};
-struct DerivedLinkId {};
-
-struct AbstractBase : public SpdyIntrusiveLink<AbstractBase, BaseLinkId> {
-  virtual ~AbstractBase() = 0;
-  virtual std::string name() { return "AbstractBase"; }
-};
-AbstractBase::~AbstractBase() {}
-struct DerivedClass : public SpdyIntrusiveLink<DerivedClass, DerivedLinkId>,
-                      public AbstractBase {
-  ~DerivedClass() override {}
-  std::string name() override { return "DerivedClass"; }
-};
-struct VirtuallyDerivedBaseClass : public virtual AbstractBase {
-  ~VirtuallyDerivedBaseClass() override = 0;
-  std::string name() override { return "VirtuallyDerivedBaseClass"; }
-};
-VirtuallyDerivedBaseClass::~VirtuallyDerivedBaseClass() {}
-struct VirtuallyDerivedClassA
-    : public SpdyIntrusiveLink<VirtuallyDerivedClassA, DerivedLinkId>,
-      public virtual VirtuallyDerivedBaseClass {
-  ~VirtuallyDerivedClassA() override {}
-  std::string name() override { return "VirtuallyDerivedClassA"; }
-};
-struct NonceClass {
-  virtual ~NonceClass() {}
-  int data_;
-};
-struct VirtuallyDerivedClassB
-    : public SpdyIntrusiveLink<VirtuallyDerivedClassB, DerivedLinkId>,
-      public virtual NonceClass,
-      public virtual VirtuallyDerivedBaseClass {
-  ~VirtuallyDerivedClassB() override {}
-  std::string name() override { return "VirtuallyDerivedClassB"; }
-};
-struct VirtuallyDerivedClassC
-    : public SpdyIntrusiveLink<VirtuallyDerivedClassC, DerivedLinkId>,
-      public virtual AbstractBase,
-      public virtual NonceClass,
-      public virtual VirtuallyDerivedBaseClass {
-  ~VirtuallyDerivedClassC() override {}
-  std::string name() override { return "VirtuallyDerivedClassC"; }
-};
-
-// Test for multiple layers between the element type and the link.
-namespace templated_base_link {
-template <typename T> struct AbstractBase : public SpdyIntrusiveLink<T> {
-  virtual ~AbstractBase() = 0;
-};
-template <typename T> AbstractBase<T>::~AbstractBase() {}
-struct DerivedClass : public AbstractBase<DerivedClass> {
-  int n;
-};
-}
-
-TEST(NewIntrusiveListTest, HandleInheritanceHierarchies) {
-  {
-    SpdyIntrusiveList<DerivedClass, DerivedLinkId> list;
-    DerivedClass elements[2];
-    EXPECT_TRUE(list.empty());
-    list.push_back(&elements[0]);
-    EXPECT_EQ(1u, list.size());
-    list.push_back(&elements[1]);
-    EXPECT_EQ(2u, list.size());
-    list.pop_back();
-    EXPECT_EQ(1u, list.size());
-    list.pop_back();
-    EXPECT_TRUE(list.empty());
-  }
-  {
-    SpdyIntrusiveList<VirtuallyDerivedClassA, DerivedLinkId> list;
-    VirtuallyDerivedClassA elements[2];
-    EXPECT_TRUE(list.empty());
-    list.push_back(&elements[0]);
-    EXPECT_EQ(1u, list.size());
-    list.push_back(&elements[1]);
-    EXPECT_EQ(2u, list.size());
-    list.pop_back();
-    EXPECT_EQ(1u, list.size());
-    list.pop_back();
-    EXPECT_TRUE(list.empty());
-  }
-  {
-    SpdyIntrusiveList<VirtuallyDerivedClassC, DerivedLinkId> list;
-    VirtuallyDerivedClassC elements[2];
-    EXPECT_TRUE(list.empty());
-    list.push_back(&elements[0]);
-    EXPECT_EQ(1u, list.size());
-    list.push_back(&elements[1]);
-    EXPECT_EQ(2u, list.size());
-    list.pop_back();
-    EXPECT_EQ(1u, list.size());
-    list.pop_back();
-    EXPECT_TRUE(list.empty());
-  }
-  {
-    SpdyIntrusiveList<AbstractBase, BaseLinkId> list;
-    DerivedClass d1;
-    VirtuallyDerivedClassA d2;
-    VirtuallyDerivedClassB d3;
-    VirtuallyDerivedClassC d4;
-    EXPECT_TRUE(list.empty());
-    list.push_back(&d1);
-    EXPECT_EQ(1u, list.size());
-    list.push_back(&d2);
-    EXPECT_EQ(2u, list.size());
-    list.push_back(&d3);
-    EXPECT_EQ(3u, list.size());
-    list.push_back(&d4);
-    EXPECT_EQ(4u, list.size());
-    SpdyIntrusiveList<AbstractBase, BaseLinkId>::iterator it = list.begin();
-    EXPECT_EQ("DerivedClass",           (it++)->name());
-    EXPECT_EQ("VirtuallyDerivedClassA", (it++)->name());
-    EXPECT_EQ("VirtuallyDerivedClassB", (it++)->name());
-    EXPECT_EQ("VirtuallyDerivedClassC", (it++)->name());
-  }
-  {
-    SpdyIntrusiveList<templated_base_link::DerivedClass> list;
-    templated_base_link::DerivedClass elements[2];
-    EXPECT_TRUE(list.empty());
-    list.push_back(&elements[0]);
-    EXPECT_EQ(1u, list.size());
-    list.push_back(&elements[1]);
-    EXPECT_EQ(2u, list.size());
-    list.pop_back();
-    EXPECT_EQ(1u, list.size());
-    list.pop_back();
-    EXPECT_TRUE(list.empty());
-  }
-}
-
-class IntrusiveListTagTypeTest : public QuicheTest {
- protected:
-  struct Tag {};
-  class Element : public SpdyIntrusiveLink<Element, Tag> {};
-};
-
-TEST_F(IntrusiveListTagTypeTest, TagTypeListID) {
-  SpdyIntrusiveList<Element, Tag> list;
-  {
-    Element e;
-    list.push_back(&e);
-  }
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_no_op_visitor.cc b/spdy/core/spdy_no_op_visitor.cc
deleted file mode 100644
index f27da89..0000000
--- a/spdy/core/spdy_no_op_visitor.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_no_op_visitor.h"
-
-#include <type_traits>
-
-namespace spdy {
-
-SpdyNoOpVisitor::SpdyNoOpVisitor() {
-  static_assert(std::is_abstract<SpdyNoOpVisitor>::value == false,
-                "Need to update SpdyNoOpVisitor.");
-}
-SpdyNoOpVisitor::~SpdyNoOpVisitor() = default;
-
-SpdyHeadersHandlerInterface* SpdyNoOpVisitor::OnHeaderFrameStart(
-    SpdyStreamId /*stream_id*/) {
-  return this;
-}
-
-bool SpdyNoOpVisitor::OnUnknownFrame(SpdyStreamId /*stream_id*/,
-                                     uint8_t /*frame_type*/) {
-  return true;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_no_op_visitor.h b/spdy/core/spdy_no_op_visitor.h
deleted file mode 100644
index 04dd0d4..0000000
--- a/spdy/core/spdy_no_op_visitor.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// SpdyNoOpVisitor implements several of the visitor and handler interfaces
-// to make it easier to write tests that need to provide instances. Other
-// interfaces can be added as needed.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
-#define QUICHE_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "spdy/core/http2_frame_decoder_adapter.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace spdy {
-
-class SpdyNoOpVisitor : public SpdyFramerVisitorInterface,
-                        public SpdyFramerDebugVisitorInterface,
-                        public SpdyHeadersHandlerInterface {
- public:
-  SpdyNoOpVisitor();
-  ~SpdyNoOpVisitor() override;
-
-  // SpdyFramerVisitorInterface methods:
-  void OnError(http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
-               std::string /*detailed_error*/) override {}
-  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      SpdyStreamId stream_id) override;
-  void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override {}
-  void OnDataFrameHeader(SpdyStreamId /*stream_id*/,
-                         size_t /*length*/,
-                         bool /*fin*/) override {}
-  void OnStreamFrameData(SpdyStreamId /*stream_id*/,
-                         const char* /*data*/,
-                         size_t /*len*/) override {}
-  void OnStreamEnd(SpdyStreamId /*stream_id*/) override {}
-  void OnStreamPadding(SpdyStreamId /*stream_id*/, size_t /*len*/) override {}
-  void OnRstStream(SpdyStreamId /*stream_id*/,
-                   SpdyErrorCode /*error_code*/) override {}
-  void OnSetting(SpdySettingsId /*id*/, uint32_t /*value*/) override {}
-  void OnPing(SpdyPingId /*unique_id*/, bool /*is_ack*/) override {}
-  void OnSettingsEnd() override {}
-  void OnSettingsAck() override {}
-  void OnGoAway(SpdyStreamId /*last_accepted_stream_id*/,
-                SpdyErrorCode /*error_code*/) override {}
-  void OnHeaders(SpdyStreamId /*stream_id*/,
-                 bool /*has_priority*/,
-                 int /*weight*/,
-                 SpdyStreamId /*parent_stream_id*/,
-                 bool /*exclusive*/,
-                 bool /*fin*/,
-                 bool /*end*/) override {}
-  void OnWindowUpdate(SpdyStreamId /*stream_id*/,
-                      int /*delta_window_size*/) override {}
-  void OnPushPromise(SpdyStreamId /*stream_id*/,
-                     SpdyStreamId /*promised_stream_id*/,
-                     bool /*end*/) override {}
-  void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
-  void OnAltSvc(SpdyStreamId /*stream_id*/,
-                absl::string_view /*origin*/,
-                const SpdyAltSvcWireFormat::AlternativeServiceVector&
-                /*altsvc_vector*/) override {}
-  void OnPriority(SpdyStreamId /*stream_id*/,
-                  SpdyStreamId /*parent_stream_id*/,
-                  int /*weight*/,
-                  bool /*exclusive*/) override {}
-  void OnPriorityUpdate(SpdyStreamId /*prioritized_stream_id*/,
-                        absl::string_view /*priority_field_value*/) override {}
-  bool OnUnknownFrame(SpdyStreamId /*stream_id*/,
-                      uint8_t /*frame_type*/) override;
-
-  // SpdyFramerDebugVisitorInterface methods:
-  void OnSendCompressedFrame(SpdyStreamId /*stream_id*/,
-                             SpdyFrameType /*type*/,
-                             size_t /*payload_len*/,
-                             size_t /*frame_len*/) override {}
-  void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
-                                SpdyFrameType /*type*/,
-                                size_t /*frame_len*/) override {}
-
-  // SpdyHeadersHandlerInterface methods:
-  void OnHeaderBlockStart() override {}
-  void OnHeader(absl::string_view /*key*/,
-                absl::string_view /*value*/) override {}
-  void OnHeaderBlockEnd(size_t /* uncompressed_header_bytes */,
-                        size_t /* compressed_header_bytes */) override {}
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
diff --git a/spdy/core/spdy_pinnable_buffer_piece.cc b/spdy/core/spdy_pinnable_buffer_piece.cc
deleted file mode 100644
index 1e8fd7a..0000000
--- a/spdy/core/spdy_pinnable_buffer_piece.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_pinnable_buffer_piece.h"
-
-#include <new>
-
-namespace spdy {
-
-SpdyPinnableBufferPiece::SpdyPinnableBufferPiece()
-    : buffer_(nullptr), length_(0) {}
-
-SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() = default;
-
-void SpdyPinnableBufferPiece::Pin() {
-  if (!storage_ && buffer_ != nullptr && length_ != 0) {
-    storage_.reset(new char[length_]);
-    std::copy(buffer_, buffer_ + length_, storage_.get());
-    buffer_ = storage_.get();
-  }
-}
-
-void SpdyPinnableBufferPiece::Swap(SpdyPinnableBufferPiece* other) {
-  size_t length = length_;
-  length_ = other->length_;
-  other->length_ = length;
-
-  const char* buffer = buffer_;
-  buffer_ = other->buffer_;
-  other->buffer_ = buffer;
-
-  storage_.swap(other->storage_);
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_pinnable_buffer_piece.h b/spdy/core/spdy_pinnable_buffer_piece.h
deleted file mode 100644
index 3386645..0000000
--- a/spdy/core/spdy_pinnable_buffer_piece.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
-#define QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-
-namespace spdy {
-
-class SpdyPrefixedBufferReader;
-
-// Helper class of SpdyPrefixedBufferReader.
-// Represents a piece of consumed buffer which may (or may not) own its
-// underlying storage. Users may "pin" the buffer at a later time to ensure
-// a SpdyPinnableBufferPiece owns and retains storage of the buffer.
-struct QUICHE_EXPORT_PRIVATE SpdyPinnableBufferPiece {
- public:
-  SpdyPinnableBufferPiece();
-  ~SpdyPinnableBufferPiece();
-
-  const char* buffer() const { return buffer_; }
-
-  explicit operator absl::string_view() const {
-    return absl::string_view(buffer_, length_);
-  }
-
-  // Allocates and copies the buffer to internal storage.
-  void Pin();
-
-  bool IsPinned() const { return storage_ != nullptr; }
-
-  // Swaps buffers, including internal storage, with |other|.
-  void Swap(SpdyPinnableBufferPiece* other);
-
- private:
-  friend class SpdyPrefixedBufferReader;
-
-  const char* buffer_;
-  size_t length_;
-  // Null iff |buffer_| isn't pinned.
-  std::unique_ptr<char[]> storage_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
diff --git a/spdy/core/spdy_pinnable_buffer_piece_test.cc b/spdy/core/spdy_pinnable_buffer_piece_test.cc
deleted file mode 100644
index 0ee17ca..0000000
--- a/spdy/core/spdy_pinnable_buffer_piece_test.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_pinnable_buffer_piece.h"
-
-#include <string>
-
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/spdy_prefixed_buffer_reader.h"
-
-namespace spdy {
-
-namespace test {
-
-class SpdyPinnableBufferPieceTest : public QuicheTest {
- protected:
-  SpdyPrefixedBufferReader Build(const std::string& prefix,
-                                 const std::string& suffix) {
-    prefix_ = prefix;
-    suffix_ = suffix;
-    return SpdyPrefixedBufferReader(prefix_.data(), prefix_.length(),
-                                    suffix_.data(), suffix_.length());
-  }
-  std::string prefix_, suffix_;
-};
-
-TEST_F(SpdyPinnableBufferPieceTest, Pin) {
-  SpdyPrefixedBufferReader reader = Build("foobar", "");
-  SpdyPinnableBufferPiece piece;
-  EXPECT_TRUE(reader.ReadN(6, &piece));
-
-  // Piece points to underlying prefix storage.
-  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
-  EXPECT_FALSE(piece.IsPinned());
-  EXPECT_EQ(prefix_.data(), piece.buffer());
-
-  piece.Pin();
-
-  // Piece now points to allocated storage.
-  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
-  EXPECT_TRUE(piece.IsPinned());
-  EXPECT_NE(prefix_.data(), piece.buffer());
-
-  // Pinning again has no effect.
-  const char* buffer = piece.buffer();
-  piece.Pin();
-  EXPECT_EQ(buffer, piece.buffer());
-}
-
-TEST_F(SpdyPinnableBufferPieceTest, Swap) {
-  SpdyPrefixedBufferReader reader = Build("foobar", "");
-  SpdyPinnableBufferPiece piece1, piece2;
-  EXPECT_TRUE(reader.ReadN(4, &piece1));
-  EXPECT_TRUE(reader.ReadN(2, &piece2));
-
-  piece1.Pin();
-
-  EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece1));
-  EXPECT_TRUE(piece1.IsPinned());
-  EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece2));
-  EXPECT_FALSE(piece2.IsPinned());
-
-  piece1.Swap(&piece2);
-
-  EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece1));
-  EXPECT_FALSE(piece1.IsPinned());
-  EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece2));
-  EXPECT_TRUE(piece2.IsPinned());
-
-  SpdyPinnableBufferPiece empty;
-  piece2.Swap(&empty);
-
-  EXPECT_EQ(absl::string_view(""), absl::string_view(piece2));
-  EXPECT_FALSE(piece2.IsPinned());
-}
-
-}  // namespace test
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_prefixed_buffer_reader.cc b/spdy/core/spdy_prefixed_buffer_reader.cc
deleted file mode 100644
index 767dea3..0000000
--- a/spdy/core/spdy_prefixed_buffer_reader.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_prefixed_buffer_reader.h"
-
-#include <new>
-
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-
-SpdyPrefixedBufferReader::SpdyPrefixedBufferReader(const char* prefix,
-                                                   size_t prefix_length,
-                                                   const char* suffix,
-                                                   size_t suffix_length)
-    : prefix_(prefix),
-      suffix_(suffix),
-      prefix_length_(prefix_length),
-      suffix_length_(suffix_length) {}
-
-size_t SpdyPrefixedBufferReader::Available() {
-  return prefix_length_ + suffix_length_;
-}
-
-bool SpdyPrefixedBufferReader::ReadN(size_t count, char* out) {
-  if (Available() < count) {
-    return false;
-  }
-
-  if (prefix_length_ >= count) {
-    // Read is fully satisfied by the prefix.
-    std::copy(prefix_, prefix_ + count, out);
-    prefix_ += count;
-    prefix_length_ -= count;
-    return true;
-  } else if (prefix_length_ != 0) {
-    // Read is partially satisfied by the prefix.
-    out = std::copy(prefix_, prefix_ + prefix_length_, out);
-    count -= prefix_length_;
-    prefix_length_ = 0;
-    // Fallthrough to suffix read.
-  }
-  QUICHE_DCHECK(suffix_length_ >= count);
-  // Read is satisfied by the suffix.
-  std::copy(suffix_, suffix_ + count, out);
-  suffix_ += count;
-  suffix_length_ -= count;
-  return true;
-}
-
-bool SpdyPrefixedBufferReader::ReadN(size_t count,
-                                     SpdyPinnableBufferPiece* out) {
-  if (Available() < count) {
-    return false;
-  }
-
-  out->storage_.reset();
-  out->length_ = count;
-
-  if (prefix_length_ >= count) {
-    // Read is fully satisfied by the prefix.
-    out->buffer_ = prefix_;
-    prefix_ += count;
-    prefix_length_ -= count;
-    return true;
-  } else if (prefix_length_ != 0) {
-    // Read is only partially satisfied by the prefix. We need to allocate
-    // contiguous storage as the read spans the prefix & suffix.
-    out->storage_.reset(new char[count]);
-    out->buffer_ = out->storage_.get();
-    ReadN(count, out->storage_.get());
-    return true;
-  } else {
-    QUICHE_DCHECK(suffix_length_ >= count);
-    // Read is fully satisfied by the suffix.
-    out->buffer_ = suffix_;
-    suffix_ += count;
-    suffix_length_ -= count;
-    return true;
-  }
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_prefixed_buffer_reader.h b/spdy/core/spdy_prefixed_buffer_reader.h
deleted file mode 100644
index 7665b87..0000000
--- a/spdy/core/spdy_prefixed_buffer_reader.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
-#define QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
-
-#include <stddef.h>
-
-#include "common/platform/api/quiche_export.h"
-#include "spdy/core/spdy_pinnable_buffer_piece.h"
-
-namespace spdy {
-
-// Reader class which simplifies reading contiguously from
-// from a disjoint buffer prefix & suffix.
-class QUICHE_EXPORT_PRIVATE SpdyPrefixedBufferReader {
- public:
-  SpdyPrefixedBufferReader(const char* prefix,
-                           size_t prefix_length,
-                           const char* suffix,
-                           size_t suffix_length);
-
-  // Returns number of bytes available to be read.
-  size_t Available();
-
-  // Reads |count| bytes, copying into |*out|. Returns true on success,
-  // false if not enough bytes were available.
-  bool ReadN(size_t count, char* out);
-
-  // Reads |count| bytes, returned in |*out|. Returns true on success,
-  // false if not enough bytes were available.
-  bool ReadN(size_t count, SpdyPinnableBufferPiece* out);
-
- private:
-  const char* prefix_;
-  const char* suffix_;
-
-  size_t prefix_length_;
-  size_t suffix_length_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
diff --git a/spdy/core/spdy_prefixed_buffer_reader_test.cc b/spdy/core/spdy_prefixed_buffer_reader_test.cc
deleted file mode 100644
index cd6d15e..0000000
--- a/spdy/core/spdy_prefixed_buffer_reader_test.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_prefixed_buffer_reader.h"
-
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-
-namespace test {
-
-using testing::ElementsAreArray;
-
-class SpdyPrefixedBufferReaderTest : public QuicheTest {
- protected:
-  SpdyPrefixedBufferReader Build(const std::string& prefix,
-                                 const std::string& suffix) {
-    prefix_ = prefix;
-    suffix_ = suffix;
-    return SpdyPrefixedBufferReader(prefix_.data(), prefix_.length(),
-                                    suffix_.data(), suffix_.length());
-  }
-  std::string prefix_, suffix_;
-};
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadRawFromPrefix) {
-  SpdyPrefixedBufferReader reader = Build("foobar", "");
-  EXPECT_EQ(6u, reader.Available());
-
-  char buffer[] = "123456";
-  EXPECT_FALSE(reader.ReadN(10, buffer));  // Not enough buffer.
-  EXPECT_TRUE(reader.ReadN(6, buffer));
-  EXPECT_THAT(buffer, ElementsAreArray("foobar"));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromPrefix) {
-  SpdyPrefixedBufferReader reader = Build("foobar", "");
-  EXPECT_EQ(6u, reader.Available());
-
-  SpdyPinnableBufferPiece piece;
-  EXPECT_FALSE(reader.ReadN(10, &piece));  // Not enough buffer.
-  EXPECT_TRUE(reader.ReadN(6, &piece));
-  EXPECT_FALSE(piece.IsPinned());
-  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadRawFromSuffix) {
-  SpdyPrefixedBufferReader reader = Build("", "foobar");
-  EXPECT_EQ(6u, reader.Available());
-
-  char buffer[] = "123456";
-  EXPECT_FALSE(reader.ReadN(10, buffer));  // Not enough buffer.
-  EXPECT_TRUE(reader.ReadN(6, buffer));
-  EXPECT_THAT(buffer, ElementsAreArray("foobar"));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromSuffix) {
-  SpdyPrefixedBufferReader reader = Build("", "foobar");
-  EXPECT_EQ(6u, reader.Available());
-
-  SpdyPinnableBufferPiece piece;
-  EXPECT_FALSE(reader.ReadN(10, &piece));  // Not enough buffer.
-  EXPECT_TRUE(reader.ReadN(6, &piece));
-  EXPECT_FALSE(piece.IsPinned());
-  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadRawSpanning) {
-  SpdyPrefixedBufferReader reader = Build("foob", "ar");
-  EXPECT_EQ(6u, reader.Available());
-
-  char buffer[] = "123456";
-  EXPECT_FALSE(reader.ReadN(10, buffer));  // Not enough buffer.
-  EXPECT_TRUE(reader.ReadN(6, buffer));
-  EXPECT_THAT(buffer, ElementsAreArray("foobar"));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceSpanning) {
-  SpdyPrefixedBufferReader reader = Build("foob", "ar");
-  EXPECT_EQ(6u, reader.Available());
-
-  SpdyPinnableBufferPiece piece;
-  EXPECT_FALSE(reader.ReadN(10, &piece));  // Not enough buffer.
-  EXPECT_TRUE(reader.ReadN(6, &piece));
-  EXPECT_TRUE(piece.IsPinned());
-  EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-TEST_F(SpdyPrefixedBufferReaderTest, ReadMixed) {
-  SpdyPrefixedBufferReader reader = Build("abcdef", "hijkl");
-  EXPECT_EQ(11u, reader.Available());
-
-  char buffer[] = "1234";
-  SpdyPinnableBufferPiece piece;
-
-  EXPECT_TRUE(reader.ReadN(3, buffer));
-  EXPECT_THAT(buffer, ElementsAreArray("abc4"));
-  EXPECT_EQ(8u, reader.Available());
-
-  EXPECT_TRUE(reader.ReadN(2, buffer));
-  EXPECT_THAT(buffer, ElementsAreArray("dec4"));
-  EXPECT_EQ(6u, reader.Available());
-
-  EXPECT_TRUE(reader.ReadN(3, &piece));
-  EXPECT_EQ(absl::string_view("fhi"), absl::string_view(piece));
-  EXPECT_TRUE(piece.IsPinned());
-  EXPECT_EQ(3u, reader.Available());
-
-  EXPECT_TRUE(reader.ReadN(2, &piece));
-  EXPECT_EQ(absl::string_view("jk"), absl::string_view(piece));
-  EXPECT_FALSE(piece.IsPinned());
-  EXPECT_EQ(1u, reader.Available());
-
-  EXPECT_TRUE(reader.ReadN(1, buffer));
-  EXPECT_THAT(buffer, ElementsAreArray("lec4"));
-  EXPECT_EQ(0u, reader.Available());
-}
-
-}  // namespace test
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_protocol.cc b/spdy/core/spdy_protocol.cc
deleted file mode 100644
index 3fcdcc3..0000000
--- a/spdy/core/spdy_protocol.cc
+++ /dev/null
@@ -1,643 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_protocol.h"
-
-#include <limits>
-#include <ostream>
-
-#include "absl/strings/str_cat.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-
-namespace spdy {
-
-const char* const kHttp2ConnectionHeaderPrefix =
-    "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
-
-std::ostream& operator<<(std::ostream& out, SpdyKnownSettingsId id) {
-  return out << static_cast<SpdySettingsId>(id);
-}
-
-std::ostream& operator<<(std::ostream& out, SpdyFrameType frame_type) {
-  return out << SerializeFrameType(frame_type);
-}
-
-SpdyPriority ClampSpdy3Priority(SpdyPriority priority) {
-  static_assert(std::numeric_limits<SpdyPriority>::min() == kV3HighestPriority,
-                "The value of given priority shouldn't be smaller than highest "
-                "priority. Check this invariant explicitly.");
-  if (priority > kV3LowestPriority) {
-    QUICHE_BUG(spdy_bug_22_1)
-        << "Invalid priority: " << static_cast<int>(priority);
-    return kV3LowestPriority;
-  }
-  return priority;
-}
-
-int ClampHttp2Weight(int weight) {
-  if (weight < kHttp2MinStreamWeight) {
-    QUICHE_BUG(spdy_bug_22_2) << "Invalid weight: " << weight;
-    return kHttp2MinStreamWeight;
-  }
-  if (weight > kHttp2MaxStreamWeight) {
-    QUICHE_BUG(spdy_bug_22_3) << "Invalid weight: " << weight;
-    return kHttp2MaxStreamWeight;
-  }
-  return weight;
-}
-
-int Spdy3PriorityToHttp2Weight(SpdyPriority priority) {
-  priority = ClampSpdy3Priority(priority);
-  const float kSteps = 255.9f / 7.f;
-  return static_cast<int>(kSteps * (7.f - priority)) + 1;
-}
-
-SpdyPriority Http2WeightToSpdy3Priority(int weight) {
-  weight = ClampHttp2Weight(weight);
-  const float kSteps = 255.9f / 7.f;
-  return static_cast<SpdyPriority>(7.f - (weight - 1) / kSteps);
-}
-
-bool IsDefinedFrameType(uint8_t frame_type_field) {
-  switch (static_cast<SpdyFrameType>(frame_type_field)) {
-    case SpdyFrameType::DATA:
-      return true;
-    case SpdyFrameType::HEADERS:
-      return true;
-    case SpdyFrameType::PRIORITY:
-      return true;
-    case SpdyFrameType::RST_STREAM:
-      return true;
-    case SpdyFrameType::SETTINGS:
-      return true;
-    case SpdyFrameType::PUSH_PROMISE:
-      return true;
-    case SpdyFrameType::PING:
-      return true;
-    case SpdyFrameType::GOAWAY:
-      return true;
-    case SpdyFrameType::WINDOW_UPDATE:
-      return true;
-    case SpdyFrameType::CONTINUATION:
-      return true;
-    case SpdyFrameType::ALTSVC:
-      return true;
-    case SpdyFrameType::PRIORITY_UPDATE:
-      return true;
-    case SpdyFrameType::ACCEPT_CH:
-      return true;
-  }
-  return false;
-}
-
-SpdyFrameType ParseFrameType(uint8_t frame_type_field) {
-  QUICHE_BUG_IF(spdy_bug_22_4, !IsDefinedFrameType(frame_type_field))
-      << "Frame type not defined: " << static_cast<int>(frame_type_field);
-  return static_cast<SpdyFrameType>(frame_type_field);
-}
-
-uint8_t SerializeFrameType(SpdyFrameType frame_type) {
-  return static_cast<uint8_t>(frame_type);
-}
-
-bool IsValidHTTP2FrameStreamId(SpdyStreamId current_frame_stream_id,
-                               SpdyFrameType frame_type_field) {
-  if (current_frame_stream_id == 0) {
-    switch (frame_type_field) {
-      case SpdyFrameType::DATA:
-      case SpdyFrameType::HEADERS:
-      case SpdyFrameType::PRIORITY:
-      case SpdyFrameType::RST_STREAM:
-      case SpdyFrameType::CONTINUATION:
-      case SpdyFrameType::PUSH_PROMISE:
-        // These frame types must specify a stream
-        return false;
-      default:
-        return true;
-    }
-  } else {
-    switch (frame_type_field) {
-      case SpdyFrameType::GOAWAY:
-      case SpdyFrameType::SETTINGS:
-      case SpdyFrameType::PING:
-        // These frame types must not specify a stream
-        return false;
-      default:
-        return true;
-    }
-  }
-}
-
-const char* FrameTypeToString(SpdyFrameType frame_type) {
-  switch (frame_type) {
-    case SpdyFrameType::DATA:
-      return "DATA";
-    case SpdyFrameType::RST_STREAM:
-      return "RST_STREAM";
-    case SpdyFrameType::SETTINGS:
-      return "SETTINGS";
-    case SpdyFrameType::PING:
-      return "PING";
-    case SpdyFrameType::GOAWAY:
-      return "GOAWAY";
-    case SpdyFrameType::HEADERS:
-      return "HEADERS";
-    case SpdyFrameType::WINDOW_UPDATE:
-      return "WINDOW_UPDATE";
-    case SpdyFrameType::PUSH_PROMISE:
-      return "PUSH_PROMISE";
-    case SpdyFrameType::CONTINUATION:
-      return "CONTINUATION";
-    case SpdyFrameType::PRIORITY:
-      return "PRIORITY";
-    case SpdyFrameType::ALTSVC:
-      return "ALTSVC";
-    case SpdyFrameType::PRIORITY_UPDATE:
-      return "PRIORITY_UPDATE";
-    case SpdyFrameType::ACCEPT_CH:
-      return "ACCEPT_CH";
-  }
-  return "UNKNOWN_FRAME_TYPE";
-}
-
-bool ParseSettingsId(SpdySettingsId wire_setting_id,
-                     SpdyKnownSettingsId* setting_id) {
-  if (wire_setting_id != SETTINGS_EXPERIMENT_SCHEDULER &&
-      (wire_setting_id < SETTINGS_MIN || wire_setting_id > SETTINGS_MAX)) {
-    return false;
-  }
-
-  *setting_id = static_cast<SpdyKnownSettingsId>(wire_setting_id);
-  // This switch ensures that the casted value is valid. The default case is
-  // explicitly omitted to have compile-time guarantees that new additions to
-  // |SpdyKnownSettingsId| must also be handled here.
-  switch (*setting_id) {
-    case SETTINGS_HEADER_TABLE_SIZE:
-    case SETTINGS_ENABLE_PUSH:
-    case SETTINGS_MAX_CONCURRENT_STREAMS:
-    case SETTINGS_INITIAL_WINDOW_SIZE:
-    case SETTINGS_MAX_FRAME_SIZE:
-    case SETTINGS_MAX_HEADER_LIST_SIZE:
-    case SETTINGS_ENABLE_CONNECT_PROTOCOL:
-    case SETTINGS_DEPRECATE_HTTP2_PRIORITIES:
-    case SETTINGS_EXPERIMENT_SCHEDULER:
-      return true;
-  }
-  return false;
-}
-
-std::string SettingsIdToString(SpdySettingsId id) {
-  SpdyKnownSettingsId known_id;
-  if (!ParseSettingsId(id, &known_id)) {
-    return absl::StrCat("SETTINGS_UNKNOWN_", absl::Hex(uint32_t{id}));
-  }
-
-  switch (known_id) {
-    case SETTINGS_HEADER_TABLE_SIZE:
-      return "SETTINGS_HEADER_TABLE_SIZE";
-    case SETTINGS_ENABLE_PUSH:
-      return "SETTINGS_ENABLE_PUSH";
-    case SETTINGS_MAX_CONCURRENT_STREAMS:
-      return "SETTINGS_MAX_CONCURRENT_STREAMS";
-    case SETTINGS_INITIAL_WINDOW_SIZE:
-      return "SETTINGS_INITIAL_WINDOW_SIZE";
-    case SETTINGS_MAX_FRAME_SIZE:
-      return "SETTINGS_MAX_FRAME_SIZE";
-    case SETTINGS_MAX_HEADER_LIST_SIZE:
-      return "SETTINGS_MAX_HEADER_LIST_SIZE";
-    case SETTINGS_ENABLE_CONNECT_PROTOCOL:
-      return "SETTINGS_ENABLE_CONNECT_PROTOCOL";
-    case SETTINGS_DEPRECATE_HTTP2_PRIORITIES:
-      return "SETTINGS_DEPRECATE_HTTP2_PRIORITIES";
-    case SETTINGS_EXPERIMENT_SCHEDULER:
-      return "SETTINGS_EXPERIMENT_SCHEDULER";
-  }
-
-  return absl::StrCat("SETTINGS_UNKNOWN_", absl::Hex(uint32_t{id}));
-}
-
-SpdyErrorCode ParseErrorCode(uint32_t wire_error_code) {
-  if (wire_error_code > ERROR_CODE_MAX) {
-    return ERROR_CODE_INTERNAL_ERROR;
-  }
-
-  return static_cast<SpdyErrorCode>(wire_error_code);
-}
-
-const char* ErrorCodeToString(SpdyErrorCode error_code) {
-  switch (error_code) {
-    case ERROR_CODE_NO_ERROR:
-      return "NO_ERROR";
-    case ERROR_CODE_PROTOCOL_ERROR:
-      return "PROTOCOL_ERROR";
-    case ERROR_CODE_INTERNAL_ERROR:
-      return "INTERNAL_ERROR";
-    case ERROR_CODE_FLOW_CONTROL_ERROR:
-      return "FLOW_CONTROL_ERROR";
-    case ERROR_CODE_SETTINGS_TIMEOUT:
-      return "SETTINGS_TIMEOUT";
-    case ERROR_CODE_STREAM_CLOSED:
-      return "STREAM_CLOSED";
-    case ERROR_CODE_FRAME_SIZE_ERROR:
-      return "FRAME_SIZE_ERROR";
-    case ERROR_CODE_REFUSED_STREAM:
-      return "REFUSED_STREAM";
-    case ERROR_CODE_CANCEL:
-      return "CANCEL";
-    case ERROR_CODE_COMPRESSION_ERROR:
-      return "COMPRESSION_ERROR";
-    case ERROR_CODE_CONNECT_ERROR:
-      return "CONNECT_ERROR";
-    case ERROR_CODE_ENHANCE_YOUR_CALM:
-      return "ENHANCE_YOUR_CALM";
-    case ERROR_CODE_INADEQUATE_SECURITY:
-      return "INADEQUATE_SECURITY";
-    case ERROR_CODE_HTTP_1_1_REQUIRED:
-      return "HTTP_1_1_REQUIRED";
-  }
-  return "UNKNOWN_ERROR_CODE";
-}
-
-const char* WriteSchedulerTypeToString(WriteSchedulerType type) {
-  switch (type) {
-    case WriteSchedulerType::LIFO:
-      return "LIFO";
-    case WriteSchedulerType::SPDY:
-      return "SPDY";
-    case WriteSchedulerType::HTTP2:
-      return "HTTP2";
-    case WriteSchedulerType::FIFO:
-      return "FIFO";
-  }
-  return "UNKNOWN";
-}
-
-size_t GetNumberRequiredContinuationFrames(size_t size) {
-  QUICHE_DCHECK_GT(size, kHttp2MaxControlFrameSendSize);
-  size_t overflow = size - kHttp2MaxControlFrameSendSize;
-  int payload_size =
-      kHttp2MaxControlFrameSendSize - kContinuationFrameMinimumSize;
-  // This is ceiling(overflow/payload_size) using integer arithmetics.
-  return (overflow - 1) / payload_size + 1;
-}
-
-const char* const kHttp2Npn = "h2";
-
-const char* const kHttp2AuthorityHeader = ":authority";
-const char* const kHttp2MethodHeader = ":method";
-const char* const kHttp2PathHeader = ":path";
-const char* const kHttp2SchemeHeader = ":scheme";
-const char* const kHttp2ProtocolHeader = ":protocol";
-
-const char* const kHttp2StatusHeader = ":status";
-
-bool SpdyFrameIR::fin() const {
-  return false;
-}
-
-int SpdyFrameIR::flow_control_window_consumed() const {
-  return 0;
-}
-
-bool SpdyFrameWithFinIR::fin() const {
-  return fin_;
-}
-
-SpdyFrameWithHeaderBlockIR::SpdyFrameWithHeaderBlockIR(
-    SpdyStreamId stream_id,
-    Http2HeaderBlock header_block)
-    : SpdyFrameWithFinIR(stream_id), header_block_(std::move(header_block)) {}
-
-SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() = default;
-
-SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, absl::string_view data)
-    : SpdyFrameWithFinIR(stream_id),
-      data_(nullptr),
-      data_len_(0),
-      padded_(false),
-      padding_payload_len_(0) {
-  SetDataDeep(data);
-}
-
-SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, const char* data)
-    : SpdyDataIR(stream_id, absl::string_view(data)) {}
-
-SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, std::string data)
-    : SpdyFrameWithFinIR(stream_id),
-      data_store_(std::make_unique<std::string>(std::move(data))),
-      data_(data_store_->data()),
-      data_len_(data_store_->size()),
-      padded_(false),
-      padding_payload_len_(0) {}
-
-SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
-    : SpdyFrameWithFinIR(stream_id),
-      data_(nullptr),
-      data_len_(0),
-      padded_(false),
-      padding_payload_len_(0) {}
-
-SpdyDataIR::~SpdyDataIR() = default;
-
-void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitData(*this);
-}
-
-SpdyFrameType SpdyDataIR::frame_type() const {
-  return SpdyFrameType::DATA;
-}
-
-int SpdyDataIR::flow_control_window_consumed() const {
-  return padded_ ? 1 + padding_payload_len_ + data_len_ : data_len_;
-}
-
-size_t SpdyDataIR::size() const {
-  return kFrameHeaderSize +
-         (padded() ? 1 + padding_payload_len() + data_len() : data_len());
-}
-
-SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
-                                 SpdyErrorCode error_code)
-    : SpdyFrameIR(stream_id) {
-  set_error_code(error_code);
-}
-
-SpdyRstStreamIR::~SpdyRstStreamIR() = default;
-
-void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitRstStream(*this);
-}
-
-SpdyFrameType SpdyRstStreamIR::frame_type() const {
-  return SpdyFrameType::RST_STREAM;
-}
-
-size_t SpdyRstStreamIR::size() const {
-  return kRstStreamFrameSize;
-}
-
-SpdySettingsIR::SpdySettingsIR() : is_ack_(false) {}
-
-SpdySettingsIR::~SpdySettingsIR() = default;
-
-void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitSettings(*this);
-}
-
-SpdyFrameType SpdySettingsIR::frame_type() const {
-  return SpdyFrameType::SETTINGS;
-}
-
-size_t SpdySettingsIR::size() const {
-  return kFrameHeaderSize + values_.size() * kSettingsOneSettingSize;
-}
-
-void SpdyPingIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitPing(*this);
-}
-
-SpdyFrameType SpdyPingIR::frame_type() const {
-  return SpdyFrameType::PING;
-}
-
-size_t SpdyPingIR::size() const {
-  return kPingFrameSize;
-}
-
-SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
-                           SpdyErrorCode error_code,
-                           absl::string_view description)
-    : description_(description) {
-  set_last_good_stream_id(last_good_stream_id);
-  set_error_code(error_code);
-}
-
-SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
-                           SpdyErrorCode error_code,
-                           const char* description)
-    : SpdyGoAwayIR(last_good_stream_id,
-                   error_code,
-                   absl::string_view(description)) {}
-
-SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
-                           SpdyErrorCode error_code,
-                           std::string description)
-    : description_store_(std::move(description)),
-      description_(description_store_) {
-  set_last_good_stream_id(last_good_stream_id);
-  set_error_code(error_code);
-}
-
-SpdyGoAwayIR::~SpdyGoAwayIR() = default;
-
-void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitGoAway(*this);
-}
-
-SpdyFrameType SpdyGoAwayIR::frame_type() const {
-  return SpdyFrameType::GOAWAY;
-}
-
-size_t SpdyGoAwayIR::size() const {
-  return kGoawayFrameMinimumSize + description_.size();
-}
-
-SpdyContinuationIR::SpdyContinuationIR(SpdyStreamId stream_id)
-    : SpdyFrameIR(stream_id), end_headers_(false) {
-}
-
-SpdyContinuationIR::~SpdyContinuationIR() = default;
-
-void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitContinuation(*this);
-}
-
-SpdyFrameType SpdyContinuationIR::frame_type() const {
-  return SpdyFrameType::CONTINUATION;
-}
-
-size_t SpdyContinuationIR::size() const {
-  // We don't need to get the size of CONTINUATION frame directly. It is
-  // calculated in HEADERS or PUSH_PROMISE frame.
-  QUICHE_DLOG(WARNING) << "Shouldn't not call size() for CONTINUATION frame.";
-  return 0;
-}
-
-void SpdyHeadersIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitHeaders(*this);
-}
-
-SpdyFrameType SpdyHeadersIR::frame_type() const {
-  return SpdyFrameType::HEADERS;
-}
-
-size_t SpdyHeadersIR::size() const {
-  size_t size = kHeadersFrameMinimumSize;
-
-  if (padded_) {
-    // Padding field length.
-    size += 1;
-    size += padding_payload_len_;
-  }
-
-  if (has_priority_) {
-    size += 5;
-  }
-
-  // Assume no hpack encoding is applied.
-  size += header_block().TotalBytesUsed() +
-          header_block().size() * kPerHeaderHpackOverhead;
-  if (size > kHttp2MaxControlFrameSendSize) {
-    size += GetNumberRequiredContinuationFrames(size) *
-            kContinuationFrameMinimumSize;
-  }
-  return size;
-}
-
-void SpdyWindowUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitWindowUpdate(*this);
-}
-
-SpdyFrameType SpdyWindowUpdateIR::frame_type() const {
-  return SpdyFrameType::WINDOW_UPDATE;
-}
-
-size_t SpdyWindowUpdateIR::size() const {
-  return kWindowUpdateFrameSize;
-}
-
-void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitPushPromise(*this);
-}
-
-SpdyFrameType SpdyPushPromiseIR::frame_type() const {
-  return SpdyFrameType::PUSH_PROMISE;
-}
-
-size_t SpdyPushPromiseIR::size() const {
-  size_t size = kPushPromiseFrameMinimumSize;
-
-  if (padded_) {
-    // Padding length field.
-    size += 1;
-    size += padding_payload_len_;
-  }
-
-  size += header_block().TotalBytesUsed();
-  if (size > kHttp2MaxControlFrameSendSize) {
-    size += GetNumberRequiredContinuationFrames(size) *
-            kContinuationFrameMinimumSize;
-  }
-  return size;
-}
-
-SpdyAltSvcIR::SpdyAltSvcIR(SpdyStreamId stream_id) : SpdyFrameIR(stream_id) {}
-
-SpdyAltSvcIR::~SpdyAltSvcIR() = default;
-
-void SpdyAltSvcIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitAltSvc(*this);
-}
-
-SpdyFrameType SpdyAltSvcIR::frame_type() const {
-  return SpdyFrameType::ALTSVC;
-}
-
-size_t SpdyAltSvcIR::size() const {
-  size_t size = kGetAltSvcFrameMinimumSize;
-  size += origin_.length();
-  // TODO(yasong): estimates the size without serializing the vector.
-  std::string str =
-      SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector_);
-  size += str.size();
-  return size;
-}
-
-void SpdyPriorityIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitPriority(*this);
-}
-
-SpdyFrameType SpdyPriorityIR::frame_type() const {
-  return SpdyFrameType::PRIORITY;
-}
-
-size_t SpdyPriorityIR::size() const {
-  return kPriorityFrameSize;
-}
-
-void SpdyPriorityUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitPriorityUpdate(*this);
-}
-
-SpdyFrameType SpdyPriorityUpdateIR::frame_type() const {
-  return SpdyFrameType::PRIORITY_UPDATE;
-}
-
-size_t SpdyPriorityUpdateIR::size() const {
-  return kPriorityUpdateFrameMinimumSize + priority_field_value_.size();
-}
-
-void SpdyAcceptChIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitAcceptCh(*this);
-}
-
-SpdyFrameType SpdyAcceptChIR::frame_type() const {
-  return SpdyFrameType::ACCEPT_CH;
-}
-
-size_t SpdyAcceptChIR::size() const {
-  size_t total_size = kAcceptChFrameMinimumSize;
-  for (const AcceptChOriginValuePair& entry : entries_) {
-    total_size += entry.origin.size() + entry.value.size() +
-                  kAcceptChFramePerEntryOverhead;
-  }
-  return total_size;
-}
-
-void SpdyUnknownIR::Visit(SpdyFrameVisitor* visitor) const {
-  return visitor->VisitUnknown(*this);
-}
-
-SpdyFrameType SpdyUnknownIR::frame_type() const {
-  return static_cast<SpdyFrameType>(type());
-}
-
-size_t SpdyUnknownIR::size() const {
-  return kFrameHeaderSize + payload_.size();
-}
-
-int SpdyUnknownIR::flow_control_window_consumed() const {
-  if (frame_type() == SpdyFrameType::DATA) {
-    return payload_.size();
-  } else {
-    return 0;
-  }
-}
-
-// Wire size of pad length field.
-const size_t kPadLengthFieldSize = 1;
-
-size_t GetHeaderFrameSizeSansBlock(const SpdyHeadersIR& header_ir) {
-  size_t min_size = kFrameHeaderSize;
-  if (header_ir.padded()) {
-    min_size += kPadLengthFieldSize;
-    min_size += header_ir.padding_payload_len();
-  }
-  if (header_ir.has_priority()) {
-    min_size += 5;
-  }
-  return min_size;
-}
-
-size_t GetPushPromiseFrameSizeSansBlock(
-    const SpdyPushPromiseIR& push_promise_ir) {
-  size_t min_size = kPushPromiseFrameMinimumSize;
-  if (push_promise_ir.padded()) {
-    min_size += kPadLengthFieldSize;
-    min_size += push_promise_ir.padding_payload_len();
-  }
-  return min_size;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_protocol.h b/spdy/core/spdy_protocol.h
deleted file mode 100644
index eafb845..0000000
--- a/spdy/core/spdy_protocol.h
+++ /dev/null
@@ -1,1138 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains some protocol structures for use with SPDY 3 and HTTP 2
-// The SPDY 3 spec can be found at:
-// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3
-
-#ifndef QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
-#define QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <iosfwd>
-#include <limits>
-#include <map>
-#include <memory>
-#include <new>
-#include <string>
-#include <utility>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_export.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/spdy_alt_svc_wire_format.h"
-#include "spdy/core/spdy_bitmasks.h"
-#include "spdy/core/spdy_header_block.h"
-
-namespace spdy {
-
-// A stream ID is a 31-bit entity.
-using SpdyStreamId = uint32_t;
-
-// A SETTINGS ID is a 16-bit entity.
-using SpdySettingsId = uint16_t;
-
-// Specifies the stream ID used to denote the current session (for
-// flow control).
-const SpdyStreamId kSessionFlowControlStreamId = 0;
-
-// 0 is not a valid stream ID for any other purpose than flow control.
-const SpdyStreamId kInvalidStreamId = 0;
-
-// Max stream id.
-const SpdyStreamId kMaxStreamId = 0x7fffffff;
-
-// The maximum possible frame payload size allowed by the spec.
-const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1;
-
-// The initial value for the maximum frame payload size as per the spec. This is
-// the maximum control frame size we accept.
-const uint32_t kHttp2DefaultFramePayloadLimit = 1 << 14;
-
-// The maximum size of the control frames that we send, including the size of
-// the header. This limit is arbitrary. We can enforce it here or at the
-// application layer. We chose the framing layer, but this can be changed (or
-// removed) if necessary later down the line.
-const size_t kHttp2MaxControlFrameSendSize = kHttp2DefaultFramePayloadLimit - 1;
-
-// Number of octets in the frame header.
-const size_t kFrameHeaderSize = 9;
-
-// The initial value for the maximum frame payload size as per the spec. This is
-// the maximum control frame size we accept.
-const uint32_t kHttp2DefaultFrameSizeLimit =
-    kHttp2DefaultFramePayloadLimit + kFrameHeaderSize;
-
-// The initial value for the maximum size of the header list, "unlimited" (max
-// unsigned 32-bit int) as per the spec.
-const uint32_t kSpdyInitialHeaderListSizeLimit = 0xFFFFFFFF;
-
-// Maximum window size for a Spdy stream or session.
-const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF;  // Max signed 32bit int
-
-// Maximum padding size in octets for one DATA or HEADERS or PUSH_PROMISE frame.
-const int32_t kPaddingSizePerFrame = 256;
-
-// The HTTP/2 connection preface, which must be the first bytes sent by the
-// client upon starting an HTTP/2 connection, and which must be followed by a
-// SETTINGS frame.  Note that even though |kHttp2ConnectionHeaderPrefix| is
-// defined as a string literal with a null terminator, the actual connection
-// preface is only the first |kHttp2ConnectionHeaderPrefixSize| bytes, which
-// excludes the null terminator.
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2ConnectionHeaderPrefix;
-const int kHttp2ConnectionHeaderPrefixSize = 24;
-
-// Wire values for HTTP2 frame types.
-enum class SpdyFrameType : uint8_t {
-  DATA = 0x00,
-  HEADERS = 0x01,
-  PRIORITY = 0x02,
-  RST_STREAM = 0x03,
-  SETTINGS = 0x04,
-  PUSH_PROMISE = 0x05,
-  PING = 0x06,
-  GOAWAY = 0x07,
-  WINDOW_UPDATE = 0x08,
-  CONTINUATION = 0x09,
-  // ALTSVC is a public extension.
-  ALTSVC = 0x0a,
-  PRIORITY_UPDATE = 0x10,
-  ACCEPT_CH = 0x89,
-};
-
-// Flags on data packets.
-enum SpdyDataFlags {
-  DATA_FLAG_NONE = 0x00,
-  DATA_FLAG_FIN = 0x01,
-  DATA_FLAG_PADDED = 0x08,
-};
-
-// Flags on control packets
-enum SpdyControlFlags {
-  CONTROL_FLAG_NONE = 0x00,
-  CONTROL_FLAG_FIN = 0x01,
-};
-
-enum SpdyPingFlags {
-  PING_FLAG_ACK = 0x01,
-};
-
-// Used by HEADERS, PUSH_PROMISE, and CONTINUATION.
-enum SpdyHeadersFlags {
-  HEADERS_FLAG_END_HEADERS = 0x04,
-  HEADERS_FLAG_PADDED = 0x08,
-  HEADERS_FLAG_PRIORITY = 0x20,
-};
-
-enum SpdyPushPromiseFlags {
-  PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x04,
-  PUSH_PROMISE_FLAG_PADDED = 0x08,
-};
-
-enum Http2SettingsControlFlags {
-  SETTINGS_FLAG_ACK = 0x01,
-};
-
-// Wire values of HTTP/2 setting identifiers.
-enum SpdyKnownSettingsId : SpdySettingsId {
-  // HPACK header table maximum size.
-  SETTINGS_HEADER_TABLE_SIZE = 0x1,
-  SETTINGS_MIN = SETTINGS_HEADER_TABLE_SIZE,
-  // Whether or not server push (PUSH_PROMISE) is enabled.
-  SETTINGS_ENABLE_PUSH = 0x2,
-  // The maximum number of simultaneous live streams in each direction.
-  SETTINGS_MAX_CONCURRENT_STREAMS = 0x3,
-  // Initial window size in bytes
-  SETTINGS_INITIAL_WINDOW_SIZE = 0x4,
-  // The size of the largest frame payload that a receiver is willing to accept.
-  SETTINGS_MAX_FRAME_SIZE = 0x5,
-  // The maximum size of header list that the sender is prepared to accept.
-  SETTINGS_MAX_HEADER_LIST_SIZE = 0x6,
-  // Enable Websockets over HTTP/2, see
-  // https://httpwg.org/specs/rfc8441.html
-  SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x8,
-  // Disable HTTP/2 priorities, see
-  // https://tools.ietf.org/html/draft-ietf-httpbis-priority-02.
-  SETTINGS_DEPRECATE_HTTP2_PRIORITIES = 0x9,
-  SETTINGS_MAX = SETTINGS_DEPRECATE_HTTP2_PRIORITIES,
-  // Experimental setting used to configure an alternative write scheduler.
-  SETTINGS_EXPERIMENT_SCHEDULER = 0xFF45,
-};
-
-// This explicit operator is needed, otherwise compiler finds
-// overloaded operator to be ambiguous.
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               SpdyKnownSettingsId id);
-
-// This operator is needed, because SpdyFrameType is an enum class,
-// therefore implicit conversion to underlying integer type is not allowed.
-QUICHE_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
-                                               SpdyFrameType frame_type);
-
-using SettingsMap = std::map<SpdySettingsId, uint32_t>;
-
-// HTTP/2 error codes, RFC 7540 Section 7.
-enum SpdyErrorCode : uint32_t {
-  ERROR_CODE_NO_ERROR = 0x0,
-  ERROR_CODE_PROTOCOL_ERROR = 0x1,
-  ERROR_CODE_INTERNAL_ERROR = 0x2,
-  ERROR_CODE_FLOW_CONTROL_ERROR = 0x3,
-  ERROR_CODE_SETTINGS_TIMEOUT = 0x4,
-  ERROR_CODE_STREAM_CLOSED = 0x5,
-  ERROR_CODE_FRAME_SIZE_ERROR = 0x6,
-  ERROR_CODE_REFUSED_STREAM = 0x7,
-  ERROR_CODE_CANCEL = 0x8,
-  ERROR_CODE_COMPRESSION_ERROR = 0x9,
-  ERROR_CODE_CONNECT_ERROR = 0xa,
-  ERROR_CODE_ENHANCE_YOUR_CALM = 0xb,
-  ERROR_CODE_INADEQUATE_SECURITY = 0xc,
-  ERROR_CODE_HTTP_1_1_REQUIRED = 0xd,
-  ERROR_CODE_MAX = ERROR_CODE_HTTP_1_1_REQUIRED
-};
-
-// Type of priority write scheduler.
-enum class WriteSchedulerType {
-  LIFO,  // Last added stream has the highest priority.
-  SPDY,  // Uses SPDY priorities described in
-         // https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority.
-  HTTP2,  // Uses HTTP2 (tree-style) priority described in
-          // https://tools.ietf.org/html/rfc7540#section-5.3.
-  FIFO,   // Stream with the smallest stream ID has the highest priority.
-};
-
-// A SPDY priority is a number between 0 and 7 (inclusive).
-typedef uint8_t SpdyPriority;
-
-// Lowest and Highest here refer to SPDY priorities as described in
-// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
-const SpdyPriority kV3HighestPriority = 0;
-const SpdyPriority kV3LowestPriority = 7;
-
-// Returns SPDY 3.x priority value clamped to the valid range of [0, 7].
-QUICHE_EXPORT_PRIVATE SpdyPriority ClampSpdy3Priority(SpdyPriority priority);
-
-// HTTP/2 stream weights are integers in range [1, 256], as specified in RFC
-// 7540 section 5.3.2. Default stream weight is defined in section 5.3.5.
-const int kHttp2MinStreamWeight = 1;
-const int kHttp2MaxStreamWeight = 256;
-const int kHttp2DefaultStreamWeight = 16;
-
-// Returns HTTP/2 weight clamped to the valid range of [1, 256].
-QUICHE_EXPORT_PRIVATE int ClampHttp2Weight(int weight);
-
-// Maps SPDY 3.x priority value in range [0, 7] to HTTP/2 weight value in range
-// [1, 256], where priority 0 (i.e. highest precedence) corresponds to maximum
-// weight 256 and priority 7 (lowest precedence) corresponds to minimum weight
-// 1.
-QUICHE_EXPORT_PRIVATE int Spdy3PriorityToHttp2Weight(SpdyPriority priority);
-
-// Maps HTTP/2 weight value in range [1, 256] to SPDY 3.x priority value in
-// range [0, 7], where minimum weight 1 corresponds to priority 7 (lowest
-// precedence) and maximum weight 256 corresponds to priority 0 (highest
-// precedence).
-QUICHE_EXPORT_PRIVATE SpdyPriority Http2WeightToSpdy3Priority(int weight);
-
-// Reserved ID for root stream of HTTP/2 stream dependency tree, as specified
-// in RFC 7540 section 5.3.1.
-const unsigned int kHttp2RootStreamId = 0;
-
-typedef uint64_t SpdyPingId;
-
-// Returns true if a given on-the-wire enumeration of a frame type is defined
-// in a standardized HTTP/2 specification, false otherwise.
-QUICHE_EXPORT_PRIVATE bool IsDefinedFrameType(uint8_t frame_type_field);
-
-// Parses a frame type from an on-the-wire enumeration.
-// Behavior is undefined for invalid frame type fields; consumers should first
-// use IsValidFrameType() to verify validity of frame type fields.
-QUICHE_EXPORT_PRIVATE SpdyFrameType ParseFrameType(uint8_t frame_type_field);
-
-// Serializes a frame type to the on-the-wire value.
-QUICHE_EXPORT_PRIVATE uint8_t SerializeFrameType(SpdyFrameType frame_type);
-
-// (HTTP/2) All standard frame types except WINDOW_UPDATE are
-// (stream-specific xor connection-level). Returns false iff we know
-// the given frame type does not align with the given streamID.
-QUICHE_EXPORT_PRIVATE bool IsValidHTTP2FrameStreamId(
-    SpdyStreamId current_frame_stream_id,
-    SpdyFrameType frame_type_field);
-
-// Serialize |frame_type| to string for logging/debugging.
-QUICHE_EXPORT_PRIVATE const char* FrameTypeToString(SpdyFrameType frame_type);
-
-// If |wire_setting_id| is the on-the-wire representation of a defined SETTINGS
-// parameter, parse it to |*setting_id| and return true.
-QUICHE_EXPORT_PRIVATE bool ParseSettingsId(SpdySettingsId wire_setting_id,
-                                           SpdyKnownSettingsId* setting_id);
-
-// Returns a string representation of the |id| for logging/debugging. Returns
-// the |id| prefixed with "SETTINGS_UNKNOWN_" for unknown SETTINGS IDs. To parse
-// the |id| into a SpdyKnownSettingsId (if applicable), use ParseSettingsId().
-QUICHE_EXPORT_PRIVATE std::string SettingsIdToString(SpdySettingsId id);
-
-// Parse |wire_error_code| to a SpdyErrorCode.
-// Treat unrecognized error codes as INTERNAL_ERROR
-// as recommended by the HTTP/2 specification.
-QUICHE_EXPORT_PRIVATE SpdyErrorCode ParseErrorCode(uint32_t wire_error_code);
-
-// Serialize RST_STREAM or GOAWAY frame error code to string
-// for logging/debugging.
-const char* ErrorCodeToString(SpdyErrorCode error_code);
-
-// Serialize |type| to string for logging/debugging.
-QUICHE_EXPORT_PRIVATE const char* WriteSchedulerTypeToString(
-    WriteSchedulerType type);
-
-// Minimum size of a frame, in octets.
-const size_t kFrameMinimumSize = kFrameHeaderSize;
-
-// Minimum frame size for variable size frame types (includes mandatory fields),
-// frame size for fixed size frames, in octets.
-
-const size_t kDataFrameMinimumSize = kFrameHeaderSize;
-const size_t kHeadersFrameMinimumSize = kFrameHeaderSize;
-// PRIORITY frame has stream_dependency (4 octets) and weight (1 octet) fields.
-const size_t kPriorityFrameSize = kFrameHeaderSize + 5;
-// RST_STREAM frame has error_code (4 octets) field.
-const size_t kRstStreamFrameSize = kFrameHeaderSize + 4;
-const size_t kSettingsFrameMinimumSize = kFrameHeaderSize;
-const size_t kSettingsOneSettingSize =
-    sizeof(uint32_t) + sizeof(SpdySettingsId);
-// PUSH_PROMISE frame has promised_stream_id (4 octet) field.
-const size_t kPushPromiseFrameMinimumSize = kFrameHeaderSize + 4;
-// PING frame has opaque_bytes (8 octet) field.
-const size_t kPingFrameSize = kFrameHeaderSize + 8;
-// GOAWAY frame has last_stream_id (4 octet) and error_code (4 octet) fields.
-const size_t kGoawayFrameMinimumSize = kFrameHeaderSize + 8;
-// WINDOW_UPDATE frame has window_size_increment (4 octet) field.
-const size_t kWindowUpdateFrameSize = kFrameHeaderSize + 4;
-const size_t kContinuationFrameMinimumSize = kFrameHeaderSize;
-// ALTSVC frame has origin_len (2 octets) field.
-const size_t kGetAltSvcFrameMinimumSize = kFrameHeaderSize + 2;
-// PRIORITY_UPDATE frame has prioritized_stream_id (4 octets) field.
-const size_t kPriorityUpdateFrameMinimumSize = kFrameHeaderSize + 4;
-// ACCEPT_CH frame may have empty payload.
-const size_t kAcceptChFrameMinimumSize = kFrameHeaderSize;
-// Each ACCEPT_CH frame entry has a 16-bit origin length and a 16-bit value
-// length.
-const size_t kAcceptChFramePerEntryOverhead = 4;
-
-// Maximum possible configurable size of a frame in octets.
-const size_t kMaxFrameSizeLimit = kSpdyMaxFrameSizeLimit + kFrameHeaderSize;
-// Size of a header block size field.
-const size_t kSizeOfSizeField = sizeof(uint32_t);
-// Initial window size for a stream in bytes.
-const int32_t kInitialStreamWindowSize = 64 * 1024 - 1;
-// Initial window size for a session in bytes.
-const int32_t kInitialSessionWindowSize = 64 * 1024 - 1;
-// The NPN string for HTTP2, "h2".
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2Npn;
-// An estimate size of the HPACK overhead for each header field. 1 bytes for
-// indexed literal, 1 bytes for key literal and length encoding, and 2 bytes for
-// value literal and length encoding.
-const size_t kPerHeaderHpackOverhead = 4;
-
-// Names of pseudo-headers defined for HTTP/2 requests.
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2AuthorityHeader;
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2MethodHeader;
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2PathHeader;
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2SchemeHeader;
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2ProtocolHeader;
-
-// Name of pseudo-header defined for HTTP/2 responses.
-QUICHE_EXPORT_PRIVATE extern const char* const kHttp2StatusHeader;
-
-QUICHE_EXPORT_PRIVATE size_t GetNumberRequiredContinuationFrames(size_t size);
-
-// Variant type (i.e. tagged union) that is either a SPDY 3.x priority value,
-// or else an HTTP/2 stream dependency tuple {parent stream ID, weight,
-// exclusive bit}. Templated to allow for use by QUIC code; SPDY and HTTP/2
-// code should use the concrete type instantiation SpdyStreamPrecedence.
-template <typename StreamIdType>
-class QUICHE_EXPORT_PRIVATE StreamPrecedence {
- public:
-  // Constructs instance that is a SPDY 3.x priority. Clamps priority value to
-  // the valid range [0, 7].
-  explicit StreamPrecedence(SpdyPriority priority)
-      : is_spdy3_priority_(true),
-        spdy3_priority_(ClampSpdy3Priority(priority)) {}
-
-  // Constructs instance that is an HTTP/2 stream weight, parent stream ID, and
-  // exclusive bit. Clamps stream weight to the valid range [1, 256].
-  StreamPrecedence(StreamIdType parent_id, int weight, bool is_exclusive)
-      : is_spdy3_priority_(false),
-        http2_stream_dependency_{parent_id, ClampHttp2Weight(weight),
-                                 is_exclusive} {}
-
-  // Intentionally copyable, to support pass by value.
-  StreamPrecedence(const StreamPrecedence& other) = default;
-  StreamPrecedence& operator=(const StreamPrecedence& other) = default;
-
-  // Returns true if this instance is a SPDY 3.x priority, or false if this
-  // instance is an HTTP/2 stream dependency.
-  bool is_spdy3_priority() const { return is_spdy3_priority_; }
-
-  // Returns SPDY 3.x priority value. If |is_spdy3_priority()| is true, this is
-  // the value provided at construction, clamped to the legal priority
-  // range. Otherwise, it is the HTTP/2 stream weight mapped to a SPDY 3.x
-  // priority value, where minimum weight 1 corresponds to priority 7 (lowest
-  // precedence) and maximum weight 256 corresponds to priority 0 (highest
-  // precedence).
-  SpdyPriority spdy3_priority() const {
-    return is_spdy3_priority_
-               ? spdy3_priority_
-               : Http2WeightToSpdy3Priority(http2_stream_dependency_.weight);
-  }
-
-  // Returns HTTP/2 parent stream ID. If |is_spdy3_priority()| is false, this is
-  // the value provided at construction, otherwise it is |kHttp2RootStreamId|.
-  StreamIdType parent_id() const {
-    return is_spdy3_priority_ ? kHttp2RootStreamId
-                              : http2_stream_dependency_.parent_id;
-  }
-
-  // Returns HTTP/2 stream weight. If |is_spdy3_priority()| is false, this is
-  // the value provided at construction, clamped to the legal weight
-  // range. Otherwise, it is the SPDY 3.x priority value mapped to an HTTP/2
-  // stream weight, where priority 0 (i.e. highest precedence) corresponds to
-  // maximum weight 256 and priority 7 (lowest precedence) corresponds to
-  // minimum weight 1.
-  int weight() const {
-    return is_spdy3_priority_ ? Spdy3PriorityToHttp2Weight(spdy3_priority_)
-                              : http2_stream_dependency_.weight;
-  }
-
-  // Returns HTTP/2 parent stream exclusivity. If |is_spdy3_priority()| is
-  // false, this is the value provided at construction, otherwise it is false.
-  bool is_exclusive() const {
-    return !is_spdy3_priority_ && http2_stream_dependency_.is_exclusive;
-  }
-
-  // Facilitates test assertions.
-  bool operator==(const StreamPrecedence& other) const {
-    if (is_spdy3_priority()) {
-      return other.is_spdy3_priority() &&
-             (spdy3_priority() == other.spdy3_priority());
-    } else {
-      return !other.is_spdy3_priority() && (parent_id() == other.parent_id()) &&
-             (weight() == other.weight()) &&
-             (is_exclusive() == other.is_exclusive());
-    }
-  }
-
-  bool operator!=(const StreamPrecedence& other) const {
-    return !(*this == other);
-  }
-
- private:
-  struct QUICHE_EXPORT_PRIVATE Http2StreamDependency {
-    StreamIdType parent_id;
-    int weight;
-    bool is_exclusive;
-  };
-
-  bool is_spdy3_priority_;
-  union {
-    SpdyPriority spdy3_priority_;
-    Http2StreamDependency http2_stream_dependency_;
-  };
-};
-
-typedef StreamPrecedence<SpdyStreamId> SpdyStreamPrecedence;
-
-class SpdyFrameVisitor;
-
-// Intermediate representation for HTTP2 frames.
-class QUICHE_EXPORT_PRIVATE SpdyFrameIR {
- public:
-  virtual ~SpdyFrameIR() {}
-
-  virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
-  virtual SpdyFrameType frame_type() const = 0;
-  SpdyStreamId stream_id() const { return stream_id_; }
-  virtual bool fin() const;
-  // Returns an estimate of the size of the serialized frame, without applying
-  // compression. May not be exact.
-  virtual size_t size() const = 0;
-
-  // Returns the number of bytes of flow control window that would be consumed
-  // by this frame if written to the wire.
-  virtual int flow_control_window_consumed() const;
-
- protected:
-  SpdyFrameIR() : stream_id_(0) {}
-  explicit SpdyFrameIR(SpdyStreamId stream_id) : stream_id_(stream_id) {}
-  SpdyFrameIR(const SpdyFrameIR&) = delete;
-  SpdyFrameIR& operator=(const SpdyFrameIR&) = delete;
-
- private:
-  SpdyStreamId stream_id_;
-};
-
-// Abstract class intended to be inherited by IRs that have the option of a FIN
-// flag.
-class QUICHE_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameIR {
- public:
-  ~SpdyFrameWithFinIR() override {}
-  bool fin() const override;
-  void set_fin(bool fin) { fin_ = fin; }
-
- protected:
-  explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
-      : SpdyFrameIR(stream_id), fin_(false) {}
-  SpdyFrameWithFinIR(const SpdyFrameWithFinIR&) = delete;
-  SpdyFrameWithFinIR& operator=(const SpdyFrameWithFinIR&) = delete;
-
- private:
-  bool fin_;
-};
-
-// Abstract class intended to be inherited by IRs that contain a header
-// block. Implies SpdyFrameWithFinIR.
-class QUICHE_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR
-    : public SpdyFrameWithFinIR {
- public:
-  ~SpdyFrameWithHeaderBlockIR() override;
-
-  const Http2HeaderBlock& header_block() const { return header_block_; }
-  void set_header_block(Http2HeaderBlock header_block) {
-    // Deep copy.
-    header_block_ = std::move(header_block);
-  }
-  void SetHeader(absl::string_view name, absl::string_view value) {
-    header_block_[name] = value;
-  }
-
- protected:
-  SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id,
-                             Http2HeaderBlock header_block);
-  SpdyFrameWithHeaderBlockIR(const SpdyFrameWithHeaderBlockIR&) = delete;
-  SpdyFrameWithHeaderBlockIR& operator=(const SpdyFrameWithHeaderBlockIR&) =
-      delete;
-
- private:
-  Http2HeaderBlock header_block_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR {
- public:
-  // Performs a deep copy on data.
-  SpdyDataIR(SpdyStreamId stream_id, absl::string_view data);
-
-  // Performs a deep copy on data.
-  SpdyDataIR(SpdyStreamId stream_id, const char* data);
-
-  // Moves data into data_store_. Makes a copy if passed a non-movable string.
-  SpdyDataIR(SpdyStreamId stream_id, std::string data);
-
-  // Use in conjunction with SetDataShallow() for shallow-copy on data.
-  explicit SpdyDataIR(SpdyStreamId stream_id);
-  SpdyDataIR(const SpdyDataIR&) = delete;
-  SpdyDataIR& operator=(const SpdyDataIR&) = delete;
-
-  ~SpdyDataIR() override;
-
-  const char* data() const { return data_; }
-  size_t data_len() const { return data_len_; }
-
-  bool padded() const { return padded_; }
-
-  int padding_payload_len() const { return padding_payload_len_; }
-
-  void set_padding_len(int padding_len) {
-    QUICHE_DCHECK_GT(padding_len, 0);
-    QUICHE_DCHECK_LE(padding_len, kPaddingSizePerFrame);
-    padded_ = true;
-    // The pad field takes one octet on the wire.
-    padding_payload_len_ = padding_len - 1;
-  }
-
-  // Deep-copy of data (keep private copy).
-  void SetDataDeep(absl::string_view data) {
-    data_store_ = std::make_unique<std::string>(data.data(), data.size());
-    data_ = data_store_->data();
-    data_len_ = data.size();
-  }
-
-  // Shallow-copy of data (do not keep private copy).
-  void SetDataShallow(absl::string_view data) {
-    data_store_.reset();
-    data_ = data.data();
-    data_len_ = data.size();
-  }
-
-  // Use this method if we don't have a contiguous buffer and only
-  // need a length.
-  void SetDataShallow(size_t len) {
-    data_store_.reset();
-    data_ = nullptr;
-    data_len_ = len;
-  }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  int flow_control_window_consumed() const override;
-
-  size_t size() const override;
-
- private:
-  // Used to store data that this SpdyDataIR should own.
-  std::unique_ptr<std::string> data_store_;
-  const char* data_;
-  size_t data_len_;
-
-  bool padded_;
-  // padding_payload_len_ = desired padding length - len(padding length field).
-  int padding_payload_len_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameIR {
- public:
-  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyErrorCode error_code);
-  SpdyRstStreamIR(const SpdyRstStreamIR&) = delete;
-  SpdyRstStreamIR& operator=(const SpdyRstStreamIR&) = delete;
-
-  ~SpdyRstStreamIR() override;
-
-  SpdyErrorCode error_code() const { return error_code_; }
-  void set_error_code(SpdyErrorCode error_code) { error_code_ = error_code; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  SpdyErrorCode error_code_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
- public:
-  SpdySettingsIR();
-  SpdySettingsIR(const SpdySettingsIR&) = delete;
-  SpdySettingsIR& operator=(const SpdySettingsIR&) = delete;
-  ~SpdySettingsIR() override;
-
-  // Overwrites as appropriate.
-  const SettingsMap& values() const { return values_; }
-  void AddSetting(SpdySettingsId id, int32_t value) { values_[id] = value; }
-
-  bool is_ack() const { return is_ack_; }
-  void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  SettingsMap values_;
-  bool is_ack_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
- public:
-  explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
-  SpdyPingIR(const SpdyPingIR&) = delete;
-  SpdyPingIR& operator=(const SpdyPingIR&) = delete;
-  SpdyPingId id() const { return id_; }
-
-  bool is_ack() const { return is_ack_; }
-  void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  SpdyPingId id_;
-  bool is_ack_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
- public:
-  // References description, doesn't copy it, so description must outlast
-  // this SpdyGoAwayIR.
-  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
-               SpdyErrorCode error_code,
-               absl::string_view description);
-
-  // References description, doesn't copy it, so description must outlast
-  // this SpdyGoAwayIR.
-  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
-               SpdyErrorCode error_code,
-               const char* description);
-
-  // Moves description into description_store_, so caller doesn't need to
-  // keep description live after constructing this SpdyGoAwayIR.
-  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
-               SpdyErrorCode error_code,
-               std::string description);
-  SpdyGoAwayIR(const SpdyGoAwayIR&) = delete;
-  SpdyGoAwayIR& operator=(const SpdyGoAwayIR&) = delete;
-
-  ~SpdyGoAwayIR() override;
-
-  SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
-  void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
-    QUICHE_DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
-    last_good_stream_id_ = last_good_stream_id;
-  }
-  SpdyErrorCode error_code() const { return error_code_; }
-  void set_error_code(SpdyErrorCode error_code) {
-    // TODO(hkhalil): Check valid ranges of error_code?
-    error_code_ = error_code;
-  }
-
-  const absl::string_view& description() const { return description_; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  SpdyStreamId last_good_stream_id_;
-  SpdyErrorCode error_code_;
-  const std::string description_store_;
-  const absl::string_view description_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
- public:
-  explicit SpdyHeadersIR(SpdyStreamId stream_id)
-      : SpdyHeadersIR(stream_id, Http2HeaderBlock()) {}
-  SpdyHeadersIR(SpdyStreamId stream_id, Http2HeaderBlock header_block)
-      : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)) {}
-  SpdyHeadersIR(const SpdyHeadersIR&) = delete;
-  SpdyHeadersIR& operator=(const SpdyHeadersIR&) = delete;
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
-  bool has_priority() const { return has_priority_; }
-  void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
-  int weight() const { return weight_; }
-  void set_weight(int weight) { weight_ = weight; }
-  SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
-  void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
-  bool exclusive() const { return exclusive_; }
-  void set_exclusive(bool exclusive) { exclusive_ = exclusive; }
-  bool padded() const { return padded_; }
-  int padding_payload_len() const { return padding_payload_len_; }
-  void set_padding_len(int padding_len) {
-    QUICHE_DCHECK_GT(padding_len, 0);
-    QUICHE_DCHECK_LE(padding_len, kPaddingSizePerFrame);
-    padded_ = true;
-    // The pad field takes one octet on the wire.
-    padding_payload_len_ = padding_len - 1;
-  }
-
- private:
-  bool has_priority_ = false;
-  int weight_ = kHttp2DefaultStreamWeight;
-  SpdyStreamId parent_stream_id_ = 0;
-  bool exclusive_ = false;
-  bool padded_ = false;
-  int padding_payload_len_ = 0;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameIR {
- public:
-  SpdyWindowUpdateIR(SpdyStreamId stream_id, int32_t delta)
-      : SpdyFrameIR(stream_id) {
-    set_delta(delta);
-  }
-  SpdyWindowUpdateIR(const SpdyWindowUpdateIR&) = delete;
-  SpdyWindowUpdateIR& operator=(const SpdyWindowUpdateIR&) = delete;
-
-  int32_t delta() const { return delta_; }
-  void set_delta(int32_t delta) {
-    QUICHE_DCHECK_LE(0, delta);
-    QUICHE_DCHECK_LE(delta, kSpdyMaximumWindowSize);
-    delta_ = delta;
-  }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  int32_t delta_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyPushPromiseIR
-    : public SpdyFrameWithHeaderBlockIR {
- public:
-  SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
-      : SpdyPushPromiseIR(stream_id, promised_stream_id, Http2HeaderBlock()) {}
-  SpdyPushPromiseIR(SpdyStreamId stream_id,
-                    SpdyStreamId promised_stream_id,
-                    Http2HeaderBlock header_block)
-      : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)),
-        promised_stream_id_(promised_stream_id),
-        padded_(false),
-        padding_payload_len_(0) {}
-  SpdyPushPromiseIR(const SpdyPushPromiseIR&) = delete;
-  SpdyPushPromiseIR& operator=(const SpdyPushPromiseIR&) = delete;
-  SpdyStreamId promised_stream_id() const { return promised_stream_id_; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
-  bool padded() const { return padded_; }
-  int padding_payload_len() const { return padding_payload_len_; }
-  void set_padding_len(int padding_len) {
-    QUICHE_DCHECK_GT(padding_len, 0);
-    QUICHE_DCHECK_LE(padding_len, kPaddingSizePerFrame);
-    padded_ = true;
-    // The pad field takes one octet on the wire.
-    padding_payload_len_ = padding_len - 1;
-  }
-
- private:
-  SpdyStreamId promised_stream_id_;
-
-  bool padded_;
-  int padding_payload_len_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyContinuationIR : public SpdyFrameIR {
- public:
-  explicit SpdyContinuationIR(SpdyStreamId stream_id);
-  SpdyContinuationIR(const SpdyContinuationIR&) = delete;
-  SpdyContinuationIR& operator=(const SpdyContinuationIR&) = delete;
-  ~SpdyContinuationIR() override;
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  bool end_headers() const { return end_headers_; }
-  void set_end_headers(bool end_headers) { end_headers_ = end_headers; }
-  const std::string& encoding() const { return encoding_; }
-  void take_encoding(std::string encoding) { encoding_ = std::move(encoding); }
-  size_t size() const override;
-
- private:
-  std::string encoding_;
-  bool end_headers_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameIR {
- public:
-  explicit SpdyAltSvcIR(SpdyStreamId stream_id);
-  SpdyAltSvcIR(const SpdyAltSvcIR&) = delete;
-  SpdyAltSvcIR& operator=(const SpdyAltSvcIR&) = delete;
-  ~SpdyAltSvcIR() override;
-
-  std::string origin() const { return origin_; }
-  const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector() const {
-    return altsvc_vector_;
-  }
-
-  void set_origin(std::string origin) { origin_ = std::move(origin); }
-  void add_altsvc(const SpdyAltSvcWireFormat::AlternativeService& altsvc) {
-    altsvc_vector_.push_back(altsvc);
-  }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  std::string origin_;
-  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameIR {
- public:
-  SpdyPriorityIR(SpdyStreamId stream_id,
-                 SpdyStreamId parent_stream_id,
-                 int weight,
-                 bool exclusive)
-      : SpdyFrameIR(stream_id),
-        parent_stream_id_(parent_stream_id),
-        weight_(weight),
-        exclusive_(exclusive) {}
-  SpdyPriorityIR(const SpdyPriorityIR&) = delete;
-  SpdyPriorityIR& operator=(const SpdyPriorityIR&) = delete;
-  SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
-  int weight() const { return weight_; }
-  bool exclusive() const { return exclusive_; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  SpdyStreamId parent_stream_id_;
-  int weight_;
-  bool exclusive_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyPriorityUpdateIR : public SpdyFrameIR {
- public:
-  SpdyPriorityUpdateIR(SpdyStreamId stream_id,
-                       SpdyStreamId prioritized_stream_id,
-                       std::string priority_field_value)
-      : SpdyFrameIR(stream_id),
-        prioritized_stream_id_(prioritized_stream_id),
-        priority_field_value_(std::move(priority_field_value)) {}
-  SpdyPriorityUpdateIR(const SpdyPriorityUpdateIR&) = delete;
-  SpdyPriorityUpdateIR& operator=(const SpdyPriorityUpdateIR&) = delete;
-  SpdyStreamId prioritized_stream_id() const { return prioritized_stream_id_; }
-  const std::string& priority_field_value() const {
-    return priority_field_value_;
-  }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
- private:
-  SpdyStreamId prioritized_stream_id_;
-  std::string priority_field_value_;
-};
-
-struct QUICHE_EXPORT_PRIVATE AcceptChOriginValuePair {
-  std::string origin;
-  std::string value;
-  bool operator==(const AcceptChOriginValuePair& rhs) const {
-    return origin == rhs.origin && value == rhs.value;
-  }
-};
-
-class QUICHE_EXPORT_PRIVATE SpdyAcceptChIR : public SpdyFrameIR {
- public:
-  SpdyAcceptChIR(std::vector<AcceptChOriginValuePair> entries)
-      : entries_(std::move(entries)) {}
-  SpdyAcceptChIR(const SpdyAcceptChIR&) = delete;
-  SpdyAcceptChIR& operator=(const SpdyAcceptChIR&) = delete;
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  size_t size() const override;
-
-  const std::vector<AcceptChOriginValuePair>& entries() const {
-    return entries_;
-  }
-
- private:
-  std::vector<AcceptChOriginValuePair> entries_;
-};
-
-// Represents a frame of unrecognized type.
-class QUICHE_EXPORT_PRIVATE SpdyUnknownIR : public SpdyFrameIR {
- public:
-  SpdyUnknownIR(SpdyStreamId stream_id,
-                uint8_t type,
-                uint8_t flags,
-                std::string payload)
-      : SpdyFrameIR(stream_id),
-        type_(type),
-        flags_(flags),
-        length_(payload.size()),
-        payload_(std::move(payload)) {}
-  SpdyUnknownIR(const SpdyUnknownIR&) = delete;
-  SpdyUnknownIR& operator=(const SpdyUnknownIR&) = delete;
-  uint8_t type() const { return type_; }
-  uint8_t flags() const { return flags_; }
-  size_t length() const { return length_; }
-  const std::string& payload() const { return payload_; }
-
-  void Visit(SpdyFrameVisitor* visitor) const override;
-
-  SpdyFrameType frame_type() const override;
-
-  int flow_control_window_consumed() const override;
-
-  size_t size() const override;
-
- protected:
-  // Allows subclasses to overwrite the default payload length.
-  void set_length(size_t length) { length_ = length; }
-
- private:
-  uint8_t type_;
-  uint8_t flags_;
-  size_t length_;
-  const std::string payload_;
-};
-
-class QUICHE_EXPORT_PRIVATE SpdySerializedFrame {
- public:
-  SpdySerializedFrame()
-      : frame_(const_cast<char*>("")), size_(0), owns_buffer_(false) {}
-
-  // Create a valid SpdySerializedFrame using a pre-created buffer.
-  // If |owns_buffer| is true, this class takes ownership of the buffer and will
-  // delete it on cleanup.  The buffer must have been created using new char[].
-  // If |owns_buffer| is false, the caller retains ownership of the buffer and
-  // is responsible for making sure the buffer outlives this frame.  In other
-  // words, this class does NOT create a copy of the buffer.
-  SpdySerializedFrame(char* data, size_t size, bool owns_buffer)
-      : frame_(data), size_(size), owns_buffer_(owns_buffer) {}
-
-  SpdySerializedFrame(SpdySerializedFrame&& other)
-      : frame_(other.frame_),
-        size_(other.size_),
-        owns_buffer_(other.owns_buffer_) {
-    // |other| is no longer responsible for the buffer.
-    other.owns_buffer_ = false;
-  }
-  SpdySerializedFrame(const SpdySerializedFrame&) = delete;
-  SpdySerializedFrame& operator=(const SpdySerializedFrame&) = delete;
-
-  SpdySerializedFrame& operator=(SpdySerializedFrame&& other) {
-    // Free buffer if necessary.
-    if (owns_buffer_) {
-      delete[] frame_;
-    }
-    // Take over |other|.
-    frame_ = other.frame_;
-    size_ = other.size_;
-    owns_buffer_ = other.owns_buffer_;
-    // |other| is no longer responsible for the buffer.
-    other.owns_buffer_ = false;
-    return *this;
-  }
-
-  ~SpdySerializedFrame() {
-    if (owns_buffer_) {
-      delete[] frame_;
-    }
-  }
-
-  // Provides access to the frame bytes, which is a buffer containing the frame
-  // packed as expected for sending over the wire.
-  char* data() const { return frame_; }
-
-  // Returns the actual size of the underlying buffer.
-  size_t size() const { return size_; }
-
-  operator absl::string_view() const {
-    return absl::string_view{frame_, size_};
-  }
-
-  operator std::string() const { return std::string{frame_, size_}; }
-
-  // Returns a buffer containing the contents of the frame, of which the caller
-  // takes ownership, and clears this SpdySerializedFrame.
-  char* ReleaseBuffer() {
-    char* buffer;
-    if (owns_buffer_) {
-      // If the buffer is owned, relinquish ownership to the caller.
-      buffer = frame_;
-      owns_buffer_ = false;
-    } else {
-      // Otherwise, we need to make a copy to give to the caller.
-      buffer = new char[size_];
-      memcpy(buffer, frame_, size_);
-    }
-    *this = SpdySerializedFrame();
-    return buffer;
-  }
-
- protected:
-  char* frame_;
-
- private:
-  size_t size_;
-  bool owns_buffer_;
-};
-
-// This interface is for classes that want to process SpdyFrameIRs without
-// having to know what type they are.  An instance of this interface can be
-// passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
-// method of this class will be called.
-class QUICHE_EXPORT_PRIVATE SpdyFrameVisitor {
- public:
-  SpdyFrameVisitor() {}
-  SpdyFrameVisitor(const SpdyFrameVisitor&) = delete;
-  SpdyFrameVisitor& operator=(const SpdyFrameVisitor&) = delete;
-  virtual ~SpdyFrameVisitor() {}
-
-  virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
-  virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
-  virtual void VisitPing(const SpdyPingIR& ping) = 0;
-  virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
-  virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
-  virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
-  virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0;
-  virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0;
-  virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) = 0;
-  virtual void VisitPriority(const SpdyPriorityIR& priority) = 0;
-  virtual void VisitData(const SpdyDataIR& data) = 0;
-  virtual void VisitPriorityUpdate(
-      const SpdyPriorityUpdateIR& priority_update) = 0;
-  virtual void VisitAcceptCh(const SpdyAcceptChIR& accept_ch) = 0;
-  virtual void VisitUnknown(const SpdyUnknownIR& /*unknown*/) {
-    // TODO(birenroy): make abstract.
-  }
-};
-
-// Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting
-// SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in
-// order to extract debug/internal information about the SpdyFramer as it
-// operates.
-//
-// Most HTTP2 implementations need not bother with this interface at all.
-class QUICHE_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface {
- public:
-  virtual ~SpdyFramerDebugVisitorInterface() {}
-
-  // Called after compressing a frame with a payload of
-  // a list of name-value pairs.
-  // |payload_len| is the uncompressed payload size.
-  // |frame_len| is the compressed frame size.
-  virtual void OnSendCompressedFrame(SpdyStreamId /*stream_id*/,
-                                     SpdyFrameType /*type*/,
-                                     size_t /*payload_len*/,
-                                     size_t /*frame_len*/) {}
-
-  // Called when a frame containing a compressed payload of
-  // name-value pairs is received.
-  // |frame_len| is the compressed frame size.
-  virtual void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
-                                        SpdyFrameType /*type*/,
-                                        size_t /*frame_len*/) {}
-};
-
-// Calculates the number of bytes required to serialize a SpdyHeadersIR, not
-// including the bytes to be used for the encoded header set.
-size_t GetHeaderFrameSizeSansBlock(const SpdyHeadersIR& header_ir);
-
-// Calculates the number of bytes required to serialize a SpdyPushPromiseIR,
-// not including the bytes to be used for the encoded header set.
-size_t GetPushPromiseFrameSizeSansBlock(
-    const SpdyPushPromiseIR& push_promise_ir);
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
diff --git a/spdy/core/spdy_protocol_test.cc b/spdy/core/spdy_protocol_test.cc
deleted file mode 100644
index dbea0e3..0000000
--- a/spdy/core/spdy_protocol_test.cc
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_protocol.h"
-
-#include <iostream>
-#include <limits>
-#include <memory>
-
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-#include "spdy/core/spdy_bitmasks.h"
-#include "spdy/core/spdy_test_utils.h"
-
-namespace spdy {
-
-std::ostream& operator<<(std::ostream& os,
-                         const SpdyStreamPrecedence precedence) {
-  if (precedence.is_spdy3_priority()) {
-    os << "SpdyStreamPrecedence[spdy3_priority=" << precedence.spdy3_priority()
-       << "]";
-  } else {
-    os << "SpdyStreamPrecedence[parent_id=" << precedence.parent_id()
-       << ", weight=" << precedence.weight()
-       << ", is_exclusive=" << precedence.is_exclusive() << "]";
-  }
-  return os;
-}
-
-namespace test {
-
-TEST(SpdyProtocolTest, ClampSpdy3Priority) {
-  EXPECT_QUICHE_BUG(EXPECT_EQ(7, ClampSpdy3Priority(8)), "Invalid priority: 8");
-  EXPECT_EQ(kV3LowestPriority, ClampSpdy3Priority(kV3LowestPriority));
-  EXPECT_EQ(kV3HighestPriority, ClampSpdy3Priority(kV3HighestPriority));
-}
-
-TEST(SpdyProtocolTest, ClampHttp2Weight) {
-  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MinStreamWeight, ClampHttp2Weight(0)),
-                    "Invalid weight: 0");
-  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MaxStreamWeight, ClampHttp2Weight(300)),
-                    "Invalid weight: 300");
-  EXPECT_EQ(kHttp2MinStreamWeight, ClampHttp2Weight(kHttp2MinStreamWeight));
-  EXPECT_EQ(kHttp2MaxStreamWeight, ClampHttp2Weight(kHttp2MaxStreamWeight));
-}
-
-TEST(SpdyProtocolTest, Spdy3PriorityToHttp2Weight) {
-  EXPECT_EQ(256, Spdy3PriorityToHttp2Weight(0));
-  EXPECT_EQ(220, Spdy3PriorityToHttp2Weight(1));
-  EXPECT_EQ(183, Spdy3PriorityToHttp2Weight(2));
-  EXPECT_EQ(147, Spdy3PriorityToHttp2Weight(3));
-  EXPECT_EQ(110, Spdy3PriorityToHttp2Weight(4));
-  EXPECT_EQ(74, Spdy3PriorityToHttp2Weight(5));
-  EXPECT_EQ(37, Spdy3PriorityToHttp2Weight(6));
-  EXPECT_EQ(1, Spdy3PriorityToHttp2Weight(7));
-}
-
-TEST(SpdyProtocolTest, Http2WeightToSpdy3Priority) {
-  EXPECT_EQ(0u, Http2WeightToSpdy3Priority(256));
-  EXPECT_EQ(0u, Http2WeightToSpdy3Priority(221));
-  EXPECT_EQ(1u, Http2WeightToSpdy3Priority(220));
-  EXPECT_EQ(1u, Http2WeightToSpdy3Priority(184));
-  EXPECT_EQ(2u, Http2WeightToSpdy3Priority(183));
-  EXPECT_EQ(2u, Http2WeightToSpdy3Priority(148));
-  EXPECT_EQ(3u, Http2WeightToSpdy3Priority(147));
-  EXPECT_EQ(3u, Http2WeightToSpdy3Priority(111));
-  EXPECT_EQ(4u, Http2WeightToSpdy3Priority(110));
-  EXPECT_EQ(4u, Http2WeightToSpdy3Priority(75));
-  EXPECT_EQ(5u, Http2WeightToSpdy3Priority(74));
-  EXPECT_EQ(5u, Http2WeightToSpdy3Priority(38));
-  EXPECT_EQ(6u, Http2WeightToSpdy3Priority(37));
-  EXPECT_EQ(6u, Http2WeightToSpdy3Priority(2));
-  EXPECT_EQ(7u, Http2WeightToSpdy3Priority(1));
-}
-
-TEST(SpdyProtocolTest, IsValidHTTP2FrameStreamId) {
-  // Stream-specific frames must have non-zero stream ids
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::DATA));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::DATA));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::HEADERS));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::HEADERS));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::PRIORITY));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::PRIORITY));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::RST_STREAM));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::RST_STREAM));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::CONTINUATION));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::CONTINUATION));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::PUSH_PROMISE));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::PUSH_PROMISE));
-
-  // Connection-level frames must have zero stream ids
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::GOAWAY));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::GOAWAY));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::SETTINGS));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::SETTINGS));
-  EXPECT_FALSE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::PING));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::PING));
-
-  // Frames that are neither stream-specific nor connection-level
-  // should not have their stream id declared invalid
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(1, SpdyFrameType::WINDOW_UPDATE));
-  EXPECT_TRUE(IsValidHTTP2FrameStreamId(0, SpdyFrameType::WINDOW_UPDATE));
-}
-
-TEST(SpdyProtocolTest, ParseSettingsId) {
-  SpdyKnownSettingsId setting_id;
-  EXPECT_FALSE(ParseSettingsId(0, &setting_id));
-  EXPECT_TRUE(ParseSettingsId(1, &setting_id));
-  EXPECT_EQ(SETTINGS_HEADER_TABLE_SIZE, setting_id);
-  EXPECT_TRUE(ParseSettingsId(2, &setting_id));
-  EXPECT_EQ(SETTINGS_ENABLE_PUSH, setting_id);
-  EXPECT_TRUE(ParseSettingsId(3, &setting_id));
-  EXPECT_EQ(SETTINGS_MAX_CONCURRENT_STREAMS, setting_id);
-  EXPECT_TRUE(ParseSettingsId(4, &setting_id));
-  EXPECT_EQ(SETTINGS_INITIAL_WINDOW_SIZE, setting_id);
-  EXPECT_TRUE(ParseSettingsId(5, &setting_id));
-  EXPECT_EQ(SETTINGS_MAX_FRAME_SIZE, setting_id);
-  EXPECT_TRUE(ParseSettingsId(6, &setting_id));
-  EXPECT_EQ(SETTINGS_MAX_HEADER_LIST_SIZE, setting_id);
-  EXPECT_FALSE(ParseSettingsId(7, &setting_id));
-  EXPECT_TRUE(ParseSettingsId(8, &setting_id));
-  EXPECT_EQ(SETTINGS_ENABLE_CONNECT_PROTOCOL, setting_id);
-  EXPECT_TRUE(ParseSettingsId(9, &setting_id));
-  EXPECT_EQ(SETTINGS_DEPRECATE_HTTP2_PRIORITIES, setting_id);
-  EXPECT_FALSE(ParseSettingsId(10, &setting_id));
-  EXPECT_FALSE(ParseSettingsId(0xFF44, &setting_id));
-  EXPECT_TRUE(ParseSettingsId(0xFF45, &setting_id));
-  EXPECT_EQ(SETTINGS_EXPERIMENT_SCHEDULER, setting_id);
-  EXPECT_FALSE(ParseSettingsId(0xFF46, &setting_id));
-}
-
-TEST(SpdyProtocolTest, SettingsIdToString) {
-  struct {
-    SpdySettingsId setting_id;
-    const std::string expected_string;
-  } test_cases[] = {
-      {0, "SETTINGS_UNKNOWN_0"},
-      {SETTINGS_HEADER_TABLE_SIZE, "SETTINGS_HEADER_TABLE_SIZE"},
-      {SETTINGS_ENABLE_PUSH, "SETTINGS_ENABLE_PUSH"},
-      {SETTINGS_MAX_CONCURRENT_STREAMS, "SETTINGS_MAX_CONCURRENT_STREAMS"},
-      {SETTINGS_INITIAL_WINDOW_SIZE, "SETTINGS_INITIAL_WINDOW_SIZE"},
-      {SETTINGS_MAX_FRAME_SIZE, "SETTINGS_MAX_FRAME_SIZE"},
-      {SETTINGS_MAX_HEADER_LIST_SIZE, "SETTINGS_MAX_HEADER_LIST_SIZE"},
-      {7, "SETTINGS_UNKNOWN_7"},
-      {SETTINGS_ENABLE_CONNECT_PROTOCOL, "SETTINGS_ENABLE_CONNECT_PROTOCOL"},
-      {SETTINGS_DEPRECATE_HTTP2_PRIORITIES,
-       "SETTINGS_DEPRECATE_HTTP2_PRIORITIES"},
-      {0xa, "SETTINGS_UNKNOWN_a"},
-      {0xFF44, "SETTINGS_UNKNOWN_ff44"},
-      {0xFF45, "SETTINGS_EXPERIMENT_SCHEDULER"},
-      {0xFF46, "SETTINGS_UNKNOWN_ff46"}};
-  for (auto test_case : test_cases) {
-    EXPECT_EQ(test_case.expected_string,
-              SettingsIdToString(test_case.setting_id));
-  }
-}
-
-TEST(SpdyStreamPrecedenceTest, Basic) {
-  SpdyStreamPrecedence spdy3_prec(2);
-  EXPECT_TRUE(spdy3_prec.is_spdy3_priority());
-  EXPECT_EQ(2, spdy3_prec.spdy3_priority());
-  EXPECT_EQ(kHttp2RootStreamId, spdy3_prec.parent_id());
-  EXPECT_EQ(Spdy3PriorityToHttp2Weight(2), spdy3_prec.weight());
-  EXPECT_FALSE(spdy3_prec.is_exclusive());
-
-  for (bool is_exclusive : {true, false}) {
-    SpdyStreamPrecedence h2_prec(7, 123, is_exclusive);
-    EXPECT_FALSE(h2_prec.is_spdy3_priority());
-    EXPECT_EQ(Http2WeightToSpdy3Priority(123), h2_prec.spdy3_priority());
-    EXPECT_EQ(7u, h2_prec.parent_id());
-    EXPECT_EQ(123, h2_prec.weight());
-    EXPECT_EQ(is_exclusive, h2_prec.is_exclusive());
-  }
-}
-
-TEST(SpdyStreamPrecedenceTest, Clamping) {
-  EXPECT_QUICHE_BUG(EXPECT_EQ(7, SpdyStreamPrecedence(8).spdy3_priority()),
-                    "Invalid priority: 8");
-  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MinStreamWeight,
-                              SpdyStreamPrecedence(3, 0, false).weight()),
-                    "Invalid weight: 0");
-  EXPECT_QUICHE_BUG(EXPECT_EQ(kHttp2MaxStreamWeight,
-                              SpdyStreamPrecedence(3, 300, false).weight()),
-                    "Invalid weight: 300");
-}
-
-TEST(SpdyStreamPrecedenceTest, Copying) {
-  SpdyStreamPrecedence prec1(3);
-  SpdyStreamPrecedence copy1(prec1);
-  EXPECT_TRUE(copy1.is_spdy3_priority());
-  EXPECT_EQ(3, copy1.spdy3_priority());
-
-  SpdyStreamPrecedence prec2(4, 5, true);
-  SpdyStreamPrecedence copy2(prec2);
-  EXPECT_FALSE(copy2.is_spdy3_priority());
-  EXPECT_EQ(4u, copy2.parent_id());
-  EXPECT_EQ(5, copy2.weight());
-  EXPECT_TRUE(copy2.is_exclusive());
-
-  copy1 = prec2;
-  EXPECT_FALSE(copy1.is_spdy3_priority());
-  EXPECT_EQ(4u, copy1.parent_id());
-  EXPECT_EQ(5, copy1.weight());
-  EXPECT_TRUE(copy1.is_exclusive());
-
-  copy2 = prec1;
-  EXPECT_TRUE(copy2.is_spdy3_priority());
-  EXPECT_EQ(3, copy2.spdy3_priority());
-}
-
-TEST(SpdyStreamPrecedenceTest, Equals) {
-  EXPECT_EQ(SpdyStreamPrecedence(3), SpdyStreamPrecedence(3));
-  EXPECT_NE(SpdyStreamPrecedence(3), SpdyStreamPrecedence(4));
-
-  EXPECT_EQ(SpdyStreamPrecedence(1, 2, false),
-            SpdyStreamPrecedence(1, 2, false));
-  EXPECT_NE(SpdyStreamPrecedence(1, 2, false),
-            SpdyStreamPrecedence(2, 2, false));
-  EXPECT_NE(SpdyStreamPrecedence(1, 2, false),
-            SpdyStreamPrecedence(1, 3, false));
-  EXPECT_NE(SpdyStreamPrecedence(1, 2, false),
-            SpdyStreamPrecedence(1, 2, true));
-
-  SpdyStreamPrecedence spdy3_prec(3);
-  SpdyStreamPrecedence h2_prec(spdy3_prec.parent_id(), spdy3_prec.weight(),
-                               spdy3_prec.is_exclusive());
-  EXPECT_NE(spdy3_prec, h2_prec);
-}
-
-TEST(SpdyDataIRTest, Construct) {
-  // Confirm that it makes a string of zero length from a
-  // absl::string_view(nullptr).
-  absl::string_view s1;
-  SpdyDataIR d1(/* stream_id = */ 1, s1);
-  EXPECT_EQ(0u, d1.data_len());
-  EXPECT_NE(nullptr, d1.data());
-
-  // Confirms makes a copy of char array.
-  const char s2[] = "something";
-  SpdyDataIR d2(/* stream_id = */ 2, s2);
-  EXPECT_EQ(absl::string_view(d2.data(), d2.data_len()), s2);
-  EXPECT_NE(absl::string_view(d1.data(), d1.data_len()), s2);
-  EXPECT_EQ((int)d1.data_len(), d1.flow_control_window_consumed());
-
-  // Confirm copies a const string.
-  const std::string foo = "foo";
-  SpdyDataIR d3(/* stream_id = */ 3, foo);
-  EXPECT_EQ(foo, d3.data());
-  EXPECT_EQ((int)d3.data_len(), d3.flow_control_window_consumed());
-
-  // Confirm copies a non-const string.
-  std::string bar = "bar";
-  SpdyDataIR d4(/* stream_id = */ 4, bar);
-  EXPECT_EQ("bar", bar);
-  EXPECT_EQ("bar", absl::string_view(d4.data(), d4.data_len()));
-
-  // Confirm moves an rvalue reference. Note that the test string "baz" is too
-  // short to trigger the move optimization, and instead a copy occurs.
-  std::string baz = "the quick brown fox";
-  SpdyDataIR d5(/* stream_id = */ 5, std::move(baz));
-  EXPECT_EQ("", baz);
-  EXPECT_EQ(absl::string_view(d5.data(), d5.data_len()), "the quick brown fox");
-
-  // Confirms makes a copy of string literal.
-  SpdyDataIR d7(/* stream_id = */ 7, "something else");
-  EXPECT_EQ(absl::string_view(d7.data(), d7.data_len()), "something else");
-
-  SpdyDataIR d8(/* stream_id = */ 8, "shawarma");
-  d8.set_padding_len(20);
-  EXPECT_EQ(28, d8.flow_control_window_consumed());
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_protocol_test_utils.cc b/spdy/core/spdy_protocol_test_utils.cc
deleted file mode 100644
index 1888176..0000000
--- a/spdy/core/spdy_protocol_test_utils.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_protocol_test_utils.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-
-namespace spdy {
-namespace test {
-
-// TODO(jamessynge): Where it makes sense in these functions, it would be nice
-// to make use of the existing gMock matchers here, instead of rolling our own.
-
-::testing::AssertionResult VerifySpdyFrameWithHeaderBlockIREquals(
-    const SpdyFrameWithHeaderBlockIR& expected,
-    const SpdyFrameWithHeaderBlockIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameWithHeaderBlockIREquals";
-  VERIFY_TRUE(actual.header_block() == expected.header_block());
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyAltSvcIR& expected,
-                                                   const SpdyAltSvcIR& actual) {
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_EQ(expected.origin(), actual.origin());
-  VERIFY_THAT(actual.altsvc_vector(),
-              ::testing::ContainerEq(expected.altsvc_vector()));
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyContinuationIR& /*expected*/,
-    const SpdyContinuationIR& /*actual*/) {
-  return ::testing::AssertionFailure()
-         << "VerifySpdyFrameIREquals SpdyContinuationIR not yet implemented";
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyDataIR& expected,
-                                                   const SpdyDataIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyDataIR";
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_EQ(expected.fin(), actual.fin());
-  VERIFY_EQ(expected.data_len(), actual.data_len());
-  if (expected.data() == nullptr) {
-    VERIFY_EQ(nullptr, actual.data());
-  } else {
-    VERIFY_EQ(absl::string_view(expected.data(), expected.data_len()),
-              absl::string_view(actual.data(), actual.data_len()));
-  }
-  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyGoAwayIR& expected,
-                                                   const SpdyGoAwayIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyGoAwayIR";
-  VERIFY_EQ(expected.last_good_stream_id(), actual.last_good_stream_id());
-  VERIFY_EQ(expected.error_code(), actual.error_code());
-  VERIFY_EQ(expected.description(), actual.description());
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyHeadersIR& expected,
-    const SpdyHeadersIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyHeadersIR";
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_EQ(expected.fin(), actual.fin());
-  VERIFY_SUCCESS(VerifySpdyFrameWithHeaderBlockIREquals(expected, actual));
-  VERIFY_EQ(expected.has_priority(), actual.has_priority());
-  if (expected.has_priority()) {
-    VERIFY_SUCCESS(VerifySpdyFrameWithPriorityIREquals(expected, actual));
-  }
-  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyPingIR& expected,
-                                                   const SpdyPingIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyPingIR";
-  VERIFY_EQ(expected.id(), actual.id());
-  VERIFY_EQ(expected.is_ack(), actual.is_ack());
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyPriorityIR& expected,
-    const SpdyPriorityIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyPriorityIR";
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_SUCCESS(VerifySpdyFrameWithPriorityIREquals(expected, actual));
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyPushPromiseIR& expected,
-    const SpdyPushPromiseIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyPushPromiseIR";
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
-  VERIFY_EQ(expected.promised_stream_id(), actual.promised_stream_id());
-  VERIFY_SUCCESS(VerifySpdyFrameWithHeaderBlockIREquals(expected, actual));
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyRstStreamIR& expected,
-    const SpdyRstStreamIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyRstStreamIR";
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_EQ(expected.error_code(), actual.error_code());
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdySettingsIR& expected,
-    const SpdySettingsIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdySettingsIR";
-  // Note, ignoring non-HTTP/2 fields such as clear_settings.
-  VERIFY_EQ(expected.is_ack(), actual.is_ack());
-
-  // Note, the following doesn't work because there isn't a comparator and
-  // formatter for SpdySettingsIR::Value. Fixable if we cared.
-  //
-  //   VERIFY_THAT(actual.values(), ::testing::ContainerEq(actual.values()));
-
-  VERIFY_EQ(expected.values().size(), actual.values().size());
-  for (const auto& entry : expected.values()) {
-    const auto& param = entry.first;
-    auto actual_itr = actual.values().find(param);
-    VERIFY_TRUE(!(actual_itr == actual.values().end()))
-        << "actual doesn't contain param: " << param;
-    uint32_t expected_value = entry.second;
-    uint32_t actual_value = actual_itr->second;
-    VERIFY_EQ(expected_value, actual_value)
-        << "Values don't match for parameter: " << param;
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyWindowUpdateIR& expected,
-    const SpdyWindowUpdateIR& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals SpdyWindowUpdateIR";
-  VERIFY_EQ(expected.stream_id(), actual.stream_id());
-  VERIFY_EQ(expected.delta(), actual.delta());
-  return ::testing::AssertionSuccess();
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_protocol_test_utils.h b/spdy/core/spdy_protocol_test_utils.h
deleted file mode 100644
index de716d5..0000000
--- a/spdy/core/spdy_protocol_test_utils.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
-#define QUICHE_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
-
-// These functions support tests that need to compare two concrete SpdyFrameIR
-// instances for equality. They return AssertionResult, so they may be used as
-// follows:
-//
-//    SomeSpdyFrameIRSubClass expected_ir(...);
-//    std::unique_ptr<SpdyFrameIR> collected_frame;
-//    ... some test code that may fill in collected_frame ...
-//    ASSERT_TRUE(VerifySpdyFrameIREquals(expected_ir, collected_frame.get()));
-//
-// TODO(jamessynge): Where it makes sense in these functions, it would be nice
-// to make use of the existing gMock matchers here, instead of rolling our own.
-
-#include <typeinfo>
-
-#include "http2/platform/api/http2_test_helpers.h"
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_test.h"
-#include "spdy/core/spdy_protocol.h"
-#include "spdy/core/spdy_test_utils.h"
-
-namespace spdy {
-namespace test {
-
-// Verify the header entries in two SpdyFrameWithHeaderBlockIR instances
-// are the same.
-::testing::AssertionResult VerifySpdyFrameWithHeaderBlockIREquals(
-    const SpdyFrameWithHeaderBlockIR& expected,
-    const SpdyFrameWithHeaderBlockIR& actual);
-
-// Verify that the padding in two frames of type T is the same.
-template <class T>
-::testing::AssertionResult VerifySpdyFrameWithPaddingIREquals(const T& expected,
-                                                              const T& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameWithPaddingIREquals";
-  VERIFY_EQ(expected.padded(), actual.padded());
-  if (expected.padded()) {
-    VERIFY_EQ(expected.padding_payload_len(), actual.padding_payload_len());
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-// Verify the priority fields in two frames of type T are the same.
-template <class T>
-::testing::AssertionResult VerifySpdyFrameWithPriorityIREquals(
-    const T& expected,
-    const T& actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameWithPriorityIREquals";
-  VERIFY_EQ(expected.parent_stream_id(), actual.parent_stream_id());
-  VERIFY_EQ(expected.weight(), actual.weight());
-  VERIFY_EQ(expected.exclusive(), actual.exclusive());
-  return ::testing::AssertionSuccess();
-}
-
-// Verify that two SpdyAltSvcIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyAltSvcIR& expected,
-                                                   const SpdyAltSvcIR& actual);
-
-// VerifySpdyFrameIREquals for SpdyContinuationIR frames isn't really needed
-// because we don't really make use of SpdyContinuationIR, instead creating
-// SpdyHeadersIR or SpdyPushPromiseIR with the pre-encoding form of the HPACK
-// block (i.e. we don't yet have a CONTINUATION frame).
-//
-// ::testing::AssertionResult VerifySpdyFrameIREquals(
-//     const SpdyContinuationIR& expected,
-//     const SpdyContinuationIR& actual) {
-//   return ::testing::AssertionFailure()
-//          << "VerifySpdyFrameIREquals SpdyContinuationIR NYI";
-// }
-
-// Verify that two SpdyDataIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyDataIR& expected,
-                                                   const SpdyDataIR& actual);
-
-// Verify that two SpdyGoAwayIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyGoAwayIR& expected,
-                                                   const SpdyGoAwayIR& actual);
-
-// Verify that two SpdyHeadersIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyHeadersIR& expected,
-    const SpdyHeadersIR& actual);
-
-// Verify that two SpdyPingIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyPingIR& expected,
-                                                   const SpdyPingIR& actual);
-
-// Verify that two SpdyPriorityIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyPriorityIR& expected,
-    const SpdyPriorityIR& actual);
-
-// Verify that two SpdyPushPromiseIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyPushPromiseIR& expected,
-    const SpdyPushPromiseIR& actual);
-
-// Verify that two SpdyRstStreamIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyRstStreamIR& expected,
-    const SpdyRstStreamIR& actual);
-
-// Verify that two SpdySettingsIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdySettingsIR& expected,
-    const SpdySettingsIR& actual);
-
-// Verify that two SpdyWindowUpdateIR frames are the same.
-::testing::AssertionResult VerifySpdyFrameIREquals(
-    const SpdyWindowUpdateIR& expected,
-    const SpdyWindowUpdateIR& actual);
-
-// Verify that either expected and actual are both nullptr, or that both are not
-// nullptr, and that actual is of type E, and that it matches expected.
-template <class E>
-::testing::AssertionResult VerifySpdyFrameIREquals(const E* expected,
-                                                   const SpdyFrameIR* actual) {
-  if (expected == nullptr || actual == nullptr) {
-    QUICHE_VLOG(1) << "VerifySpdyFrameIREquals one null";
-    VERIFY_EQ(expected, nullptr);
-    VERIFY_EQ(actual, nullptr);
-    return ::testing::AssertionSuccess();
-  }
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals not null";
-  VERIFY_EQ(actual->frame_type(), expected->frame_type());
-  const E* actual2 = static_cast<const E*>(actual);
-  return VerifySpdyFrameIREquals(*expected, *actual2);
-}
-
-// Verify that actual is not nullptr, that it is of type E and that it
-// matches expected.
-template <class E>
-::testing::AssertionResult VerifySpdyFrameIREquals(const E& expected,
-                                                   const SpdyFrameIR* actual) {
-  QUICHE_VLOG(1) << "VerifySpdyFrameIREquals";
-  return VerifySpdyFrameIREquals(&expected, actual);
-}
-
-}  // namespace test
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
diff --git a/spdy/core/spdy_simple_arena.cc b/spdy/core/spdy_simple_arena.cc
deleted file mode 100644
index 4df2246..0000000
--- a/spdy/core/spdy_simple_arena.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_simple_arena.h"
-
-#include <algorithm>
-#include <cstring>
-
-#include "common/platform/api/quiche_logging.h"
-
-namespace spdy {
-
-SpdySimpleArena::SpdySimpleArena(size_t block_size) : block_size_(block_size) {}
-
-SpdySimpleArena::~SpdySimpleArena() = default;
-
-SpdySimpleArena::SpdySimpleArena(SpdySimpleArena&& other) = default;
-SpdySimpleArena& SpdySimpleArena::operator=(SpdySimpleArena&& other) = default;
-
-char* SpdySimpleArena::Alloc(size_t size) {
-  Reserve(size);
-  Block& b = blocks_.back();
-  QUICHE_DCHECK_GE(b.size, b.used + size);
-  char* out = b.data.get() + b.used;
-  b.used += size;
-  return out;
-}
-
-char* SpdySimpleArena::Realloc(char* original, size_t oldsize, size_t newsize) {
-  QUICHE_DCHECK(!blocks_.empty());
-  Block& last = blocks_.back();
-  if (last.data.get() <= original && original < last.data.get() + last.size) {
-    // (original, oldsize) is in the last Block.
-    QUICHE_DCHECK_GE(last.data.get() + last.used, original + oldsize);
-    if (original + oldsize == last.data.get() + last.used) {
-      // (original, oldsize) was the most recent allocation,
-      if (original + newsize < last.data.get() + last.size) {
-        // (original, newsize) fits in the same Block.
-        last.used += newsize - oldsize;
-        return original;
-      }
-    }
-  }
-  char* out = Alloc(newsize);
-  memcpy(out, original, oldsize);
-  return out;
-}
-
-char* SpdySimpleArena::Memdup(const char* data, size_t size) {
-  char* out = Alloc(size);
-  memcpy(out, data, size);
-  return out;
-}
-
-void SpdySimpleArena::Free(char* data, size_t size) {
-  if (blocks_.empty()) {
-    return;
-  }
-  Block& b = blocks_.back();
-  if (size <= b.used && data + size == b.data.get() + b.used) {
-    // The memory region passed by the caller was the most recent allocation
-    // from the final block in this arena.
-    b.used -= size;
-  }
-}
-
-void SpdySimpleArena::Reset() {
-  blocks_.clear();
-  status_.bytes_allocated_ = 0;
-}
-
-void SpdySimpleArena::Reserve(size_t additional_space) {
-  if (blocks_.empty()) {
-    AllocBlock(std::max(additional_space, block_size_));
-  } else {
-    const Block& last = blocks_.back();
-    if (last.size < last.used + additional_space) {
-      AllocBlock(std::max(additional_space, block_size_));
-    }
-  }
-}
-
-void SpdySimpleArena::AllocBlock(size_t size) {
-  blocks_.push_back(Block(size));
-  status_.bytes_allocated_ += size;
-}
-
-SpdySimpleArena::Block::Block(size_t s) : data(new char[s]), size(s), used(0) {}
-
-SpdySimpleArena::Block::~Block() = default;
-
-SpdySimpleArena::Block::Block(SpdySimpleArena::Block&& other)
-    : size(other.size), used(other.used) {
-  data = std::move(other.data);
-}
-
-SpdySimpleArena::Block& SpdySimpleArena::Block::operator=(
-    SpdySimpleArena::Block&& other) {
-  size = other.size;
-  used = other.used;
-  data = std::move(other.data);
-  return *this;
-}
-
-}  // namespace spdy
diff --git a/spdy/core/spdy_simple_arena.h b/spdy/core/spdy_simple_arena.h
deleted file mode 100644
index 823d5af..0000000
--- a/spdy/core/spdy_simple_arena.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
-#define QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
-
-#include <memory>
-#include <vector>
-
-#include "common/platform/api/quiche_export.h"
-
-namespace spdy {
-
-// Allocates large blocks of memory, and doles them out in smaller chunks.
-// Not thread-safe.
-class QUICHE_EXPORT_PRIVATE SpdySimpleArena {
- public:
-  class Status {
-   private:
-    friend class SpdySimpleArena;
-    size_t bytes_allocated_;
-
-   public:
-    Status() : bytes_allocated_(0) {}
-    size_t bytes_allocated() const { return bytes_allocated_; }
-  };
-
-  // Blocks allocated by this arena will be at least |block_size| bytes.
-  explicit SpdySimpleArena(size_t block_size);
-  ~SpdySimpleArena();
-
-  // Copy and assign are not allowed.
-  SpdySimpleArena() = delete;
-  SpdySimpleArena(const SpdySimpleArena&) = delete;
-  SpdySimpleArena& operator=(const SpdySimpleArena&) = delete;
-
-  // Move is allowed.
-  SpdySimpleArena(SpdySimpleArena&& other);
-  SpdySimpleArena& operator=(SpdySimpleArena&& other);
-
-  char* Alloc(size_t size);
-  char* Realloc(char* original, size_t oldsize, size_t newsize);
-  char* Memdup(const char* data, size_t size);
-
-  // If |data| and |size| describe the most recent allocation made from this
-  // arena, the memory is reclaimed. Otherwise, this method is a no-op.
-  void Free(char* data, size_t size);
-
-  void Reset();
-
-  Status status() const { return status_; }
-
- private:
-  struct Block {
-    std::unique_ptr<char[]> data;
-    size_t size = 0;
-    size_t used = 0;
-
-    explicit Block(size_t s);
-    ~Block();
-
-    Block(Block&& other);
-    Block& operator=(Block&& other);
-  };
-
-  void Reserve(size_t additional_space);
-  void AllocBlock(size_t size);
-
-  size_t block_size_;
-  std::vector<Block> blocks_;
-  Status status_;
-};
-
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
diff --git a/spdy/core/spdy_simple_arena_test.cc b/spdy/core/spdy_simple_arena_test.cc
deleted file mode 100644
index 3657341..0000000
--- a/spdy/core/spdy_simple_arena_test.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_simple_arena.h"
-
-#include <string>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-namespace {
-
-size_t kDefaultBlockSize = 2048;
-const char kTestString[] = "This is a decently long test string.";
-
-TEST(SpdySimpleArenaTest, NoAllocationOnConstruction) {
-  SpdySimpleArena arena(kDefaultBlockSize);
-  EXPECT_EQ(0u, arena.status().bytes_allocated());
-}
-
-TEST(SpdySimpleArenaTest, Memdup) {
-  SpdySimpleArena arena(kDefaultBlockSize);
-  const size_t length = strlen(kTestString);
-  char* c = arena.Memdup(kTestString, length);
-  EXPECT_NE(nullptr, c);
-  EXPECT_NE(c, kTestString);
-  EXPECT_EQ(absl::string_view(c, length), kTestString);
-}
-
-TEST(SpdySimpleArenaTest, MemdupLargeString) {
-  SpdySimpleArena arena(10 /* block size */);
-  const size_t length = strlen(kTestString);
-  char* c = arena.Memdup(kTestString, length);
-  EXPECT_NE(nullptr, c);
-  EXPECT_NE(c, kTestString);
-  EXPECT_EQ(absl::string_view(c, length), kTestString);
-}
-
-TEST(SpdySimpleArenaTest, MultipleBlocks) {
-  SpdySimpleArena arena(40 /* block size */);
-  std::vector<std::string> strings = {
-      "One decently long string.", "Another string.",
-      "A third string that will surely go in a different block."};
-  std::vector<absl::string_view> copies;
-  for (const std::string& s : strings) {
-    absl::string_view sp(arena.Memdup(s.data(), s.size()), s.size());
-    copies.push_back(sp);
-  }
-  EXPECT_EQ(strings.size(), copies.size());
-  for (size_t i = 0; i < strings.size(); ++i) {
-    EXPECT_EQ(copies[i], strings[i]);
-  }
-}
-
-TEST(SpdySimpleArenaTest, UseAfterReset) {
-  SpdySimpleArena arena(kDefaultBlockSize);
-  const size_t length = strlen(kTestString);
-  char* c = arena.Memdup(kTestString, length);
-  arena.Reset();
-  c = arena.Memdup(kTestString, length);
-  EXPECT_NE(nullptr, c);
-  EXPECT_NE(c, kTestString);
-  EXPECT_EQ(absl::string_view(c, length), kTestString);
-}
-
-TEST(SpdySimpleArenaTest, Free) {
-  SpdySimpleArena arena(kDefaultBlockSize);
-  const size_t length = strlen(kTestString);
-  // Freeing memory not owned by the arena should be a no-op, and freeing
-  // before any allocations from the arena should be a no-op.
-  arena.Free(const_cast<char*>(kTestString), length);
-  char* c1 = arena.Memdup("Foo", 3);
-  char* c2 = arena.Memdup(kTestString, length);
-  arena.Free(const_cast<char*>(kTestString), length);
-  char* c3 = arena.Memdup("Bar", 3);
-  char* c4 = arena.Memdup(kTestString, length);
-  EXPECT_NE(c1, c2);
-  EXPECT_NE(c1, c3);
-  EXPECT_NE(c1, c4);
-  EXPECT_NE(c2, c3);
-  EXPECT_NE(c2, c4);
-  EXPECT_NE(c3, c4);
-  // Freeing c4 should succeed, since it was the most recent allocation.
-  arena.Free(c4, length);
-  // Freeing c2 should be a no-op.
-  arena.Free(c2, length);
-  // c5 should reuse memory that was previously used by c4.
-  char* c5 = arena.Memdup("Baz", 3);
-  EXPECT_EQ(c4, c5);
-}
-
-TEST(SpdySimpleArenaTest, Alloc) {
-  SpdySimpleArena arena(kDefaultBlockSize);
-  const size_t length = strlen(kTestString);
-  char* c1 = arena.Alloc(length);
-  char* c2 = arena.Alloc(2 * length);
-  char* c3 = arena.Alloc(3 * length);
-  char* c4 = arena.Memdup(kTestString, length);
-  EXPECT_EQ(c1 + length, c2);
-  EXPECT_EQ(c2 + 2 * length, c3);
-  EXPECT_EQ(c3 + 3 * length, c4);
-  EXPECT_EQ(absl::string_view(c4, length), kTestString);
-}
-
-TEST(SpdySimpleArenaTest, Realloc) {
-  SpdySimpleArena arena(kDefaultBlockSize);
-  const size_t length = strlen(kTestString);
-  // Simple realloc that fits in the block.
-  char* c1 = arena.Memdup(kTestString, length);
-  char* c2 = arena.Realloc(c1, length, 2 * length);
-  EXPECT_TRUE(c1);
-  EXPECT_EQ(c1, c2);
-  EXPECT_EQ(absl::string_view(c1, length), kTestString);
-  // Multiple reallocs.
-  char* c3 = arena.Memdup(kTestString, length);
-  EXPECT_EQ(c2 + 2 * length, c3);
-  EXPECT_EQ(absl::string_view(c3, length), kTestString);
-  char* c4 = arena.Realloc(c3, length, 2 * length);
-  EXPECT_EQ(c3, c4);
-  EXPECT_EQ(absl::string_view(c4, length), kTestString);
-  char* c5 = arena.Realloc(c4, 2 * length, 3 * length);
-  EXPECT_EQ(c4, c5);
-  EXPECT_EQ(absl::string_view(c5, length), kTestString);
-  char* c6 = arena.Memdup(kTestString, length);
-  EXPECT_EQ(c5 + 3 * length, c6);
-  EXPECT_EQ(absl::string_view(c6, length), kTestString);
-  // Realloc that does not fit in the remainder of the first block.
-  char* c7 = arena.Realloc(c6, length, kDefaultBlockSize);
-  EXPECT_EQ(absl::string_view(c7, length), kTestString);
-  arena.Free(c7, kDefaultBlockSize);
-  char* c8 = arena.Memdup(kTestString, length);
-  EXPECT_NE(c6, c7);
-  EXPECT_EQ(c7, c8);
-  EXPECT_EQ(absl::string_view(c8, length), kTestString);
-}
-
-}  // namespace
-}  // namespace spdy
diff --git a/spdy/core/spdy_test_utils.cc b/spdy/core/spdy_test_utils.cc
deleted file mode 100644
index 4ea1ce8..0000000
--- a/spdy/core/spdy_test_utils.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "spdy/core/spdy_test_utils.h"
-
-#include <algorithm>
-#include <cstring>
-#include <memory>
-#include <new>
-#include <utility>
-#include <vector>
-
-#include "common/platform/api/quiche_logging.h"
-#include "common/platform/api/quiche_test.h"
-#include "common/quiche_endian.h"
-
-namespace spdy {
-namespace test {
-
-std::string HexDumpWithMarks(const unsigned char* data,
-                             int length,
-                             const bool* marks,
-                             int mark_length) {
-  static const char kHexChars[] = "0123456789abcdef";
-  static const int kColumns = 4;
-
-  const int kSizeLimit = 1024;
-  if (length > kSizeLimit || mark_length > kSizeLimit) {
-    QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
-    length = std::min(length, kSizeLimit);
-    mark_length = std::min(mark_length, kSizeLimit);
-  }
-
-  std::string hex;
-  for (const unsigned char* row = data; length > 0;
-       row += kColumns, length -= kColumns) {
-    for (const unsigned char* p = row; p < row + 4; ++p) {
-      if (p < row + length) {
-        const bool mark =
-            (marks && (p - data) < mark_length && marks[p - data]);
-        hex += mark ? '*' : ' ';
-        hex += kHexChars[(*p & 0xf0) >> 4];
-        hex += kHexChars[*p & 0x0f];
-        hex += mark ? '*' : ' ';
-      } else {
-        hex += "    ";
-      }
-    }
-    hex = hex + "  ";
-
-    for (const unsigned char* p = row; p < row + 4 && p < row + length; ++p) {
-      hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
-    }
-
-    hex = hex + '\n';
-  }
-  return hex;
-}
-
-void CompareCharArraysWithHexError(const std::string& description,
-                                   const unsigned char* actual,
-                                   const int actual_len,
-                                   const unsigned char* expected,
-                                   const int expected_len) {
-  const int min_len = std::min(actual_len, expected_len);
-  const int max_len = std::max(actual_len, expected_len);
-  std::unique_ptr<bool[]> marks(new bool[max_len]);
-  bool identical = (actual_len == expected_len);
-  for (int i = 0; i < min_len; ++i) {
-    if (actual[i] != expected[i]) {
-      marks[i] = true;
-      identical = false;
-    } else {
-      marks[i] = false;
-    }
-  }
-  for (int i = min_len; i < max_len; ++i) {
-    marks[i] = true;
-  }
-  if (identical)
-    return;
-  ADD_FAILURE() << "Description:\n"
-                << description << "\n\nExpected:\n"
-                << HexDumpWithMarks(expected, expected_len, marks.get(),
-                                    max_len)
-                << "\nActual:\n"
-                << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
-}
-
-void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags) {
-  frame->data()[4] = flags;
-}
-
-void SetFrameLength(SpdySerializedFrame* frame, size_t length) {
-  QUICHE_CHECK_GT(1u << 14, length);
-  {
-    int32_t wire_length = quiche::QuicheEndian::HostToNet32(length);
-    memcpy(frame->data(), reinterpret_cast<char*>(&wire_length) + 1, 3);
-  }
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_test_utils.h b/spdy/core/spdy_test_utils.h
deleted file mode 100644
index d00f3b0..0000000
--- a/spdy/core/spdy_test_utils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_TEST_UTILS_H_
-#define QUICHE_SPDY_CORE_SPDY_TEST_UTILS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <string>
-
-#include "absl/strings/string_view.h"
-#include "spdy/core/spdy_header_block.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace spdy {
-
-inline bool operator==(absl::string_view x,
-                       const Http2HeaderBlock::ValueProxy& y) {
-  return y.operator==(x);
-}
-
-namespace test {
-
-std::string HexDumpWithMarks(const unsigned char* data,
-                             int length,
-                             const bool* marks,
-                             int mark_length);
-
-void CompareCharArraysWithHexError(const std::string& description,
-                                   const unsigned char* actual,
-                                   const int actual_len,
-                                   const unsigned char* expected,
-                                   const int expected_len);
-
-void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags);
-
-void SetFrameLength(SpdySerializedFrame* frame, size_t length);
-
-}  // namespace test
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_TEST_UTILS_H_
